summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bard_music.c1
-rw-r--r--src/battle_ai_script_commands.c519
-rw-r--r--src/battle_ai_switch_items.c5
-rw-r--r--src/battle_anim.c246
-rw-r--r--src/battle_anim_sound_tasks.c438
-rw-r--r--src/battle_bg.c1
-rw-r--r--src/battle_controller_link_opponent.c85
-rw-r--r--src/battle_controller_link_partner.c58
-rw-r--r--src/battle_controller_opponent.c60
-rw-r--r--src/battle_controller_player.c150
-rw-r--r--src/battle_controller_player_partner.c100
-rw-r--r--src/battle_controller_recorded_opponent.c53
-rw-r--r--src/battle_controller_recorded_player.c50
-rw-r--r--src/battle_controller_safari.c5
-rw-r--r--src/battle_controller_wally.c53
-rw-r--r--src/battle_controllers.c629
-rw-r--r--src/battle_gfx_sfx_util.c10
-rw-r--r--src/battle_interface.c196
-rw-r--r--src/battle_main.c286
-rw-r--r--src/battle_message.c1948
-rw-r--r--src/battle_records.c510
-rw-r--r--src/battle_script_commands.c998
-rw-r--r--src/battle_setup.c190
-rw-r--r--src/battle_transition.c2
-rw-r--r--src/battle_tv.c1576
-rw-r--r--src/battle_util.c60
-rw-r--r--src/battle_util2.c18
-rw-r--r--src/berry.c2
-rw-r--r--src/berry_blender.c48
-rw-r--r--src/berry_tag_screen.c12
-rw-r--r--src/bg.c10
-rw-r--r--src/bike.c4
-rw-r--r--src/birch_pc.c89
-rw-r--r--src/blit.c209
-rw-r--r--src/braille_puzzles.c212
-rw-r--r--src/calculate_base_damage.c275
-rw-r--r--src/clear_save_data_screen.c2
-rw-r--r--src/clock.c2
-rw-r--r--src/credits.c2355
-rw-r--r--src/daycare.c31
-rw-r--r--src/decompress.c2
-rw-r--r--src/decoration.c159
-rw-r--r--src/dewford_trend.c340
-rw-r--r--src/egg_hatch.c24
-rw-r--r--src/evolution_scene.c16
-rw-r--r--src/field_camera.c497
-rw-r--r--src/field_effect.c3884
-rw-r--r--src/field_map_obj.c8
-rwxr-xr-xsrc/field_map_obj_helpers.c201
-rw-r--r--src/fieldmap.c1034
-rw-r--r--src/fldeff_flash.c367
-rw-r--r--src/fldeff_groundshake.c299
-rw-r--r--src/fldeff_softboiled.c109
-rw-r--r--src/fldeff_strength.c46
-rw-r--r--src/fldeff_sweetscent.c98
-rw-r--r--src/fldeff_teleport.c9
-rw-r--r--src/fossil_specials.c770
-rw-r--r--src/gym_leader_rematch.c106
-rw-r--r--src/hall_of_fame.c6
-rw-r--r--src/hof_pc.c3
-rw-r--r--src/international_string_util.c2
-rw-r--r--src/intro.c3020
-rw-r--r--src/intro_credits_graphics.c740
-rw-r--r--src/item.c1026
-rw-r--r--src/item_icon.c2
-rwxr-xr-xsrc/item_menu.c2245
-rw-r--r--src/item_menu_icons.c684
-rwxr-xr-xsrc/item_use.c30
-rw-r--r--src/librfu_rfu.c32
-rw-r--r--src/lilycove_lady.c90
-rw-r--r--src/link.c2430
-rw-r--r--src/link_rfu.c4942
-rw-r--r--src/list_menu.c633
-rw-r--r--src/load_save.c87
-rw-r--r--src/mail.c8
-rw-r--r--src/main.c94
-rw-r--r--src/main_menu.c1962
-rw-r--r--src/map_name_popup.c474
-rw-r--r--src/map_obj_lock.c187
-rw-r--r--src/match_call.c1275
-rw-r--r--src/mauville_old_man.c1247
-rw-r--r--src/menu.c128
-rw-r--r--src/menu_helpers.c455
-rw-r--r--src/mon_markings.c611
-rw-r--r--src/mystery_event_menu.c4
-rw-r--r--src/naming_screen.c132
-rw-r--r--src/new_game.c12
-rw-r--r--src/option_menu.c19
-rw-r--r--src/overworld.c3188
-rw-r--r--src/player_pc.c1364
-rw-r--r--src/pokeball.c190
-rw-r--r--src/pokeblock.c48
-rw-r--r--src/pokeblock_feed.c3
-rw-r--r--src/pokemon.c6096
-rw-r--r--src/pokemon_1.c457
-rw-r--r--src/pokemon_2.c1365
-rw-r--r--src/pokemon_3.c1749
-rw-r--r--src/pokemon_animation.c2
-rw-r--r--src/pokemon_icon.c304
-rw-r--r--src/pokemon_summary_screen.c136
-rw-r--r--src/random.c4
-rw-r--r--src/record_mixing.c15
-rw-r--r--src/recorded_battle.c3
-rw-r--r--src/region_map.c14
-rw-r--r--src/reset_save_heap.c6
-rw-r--r--src/reshow_battle_screen.c26
-rw-r--r--src/rom6.c209
-rw-r--r--src/rom_8011DC0.c18
-rw-r--r--src/rotating_gate.c1188
-rw-r--r--src/safari_zone.c12
-rw-r--r--src/save.c50
-rw-r--r--src/scrcmd.c191
-rw-r--r--src/script.c2
-rw-r--r--src/script_movement.c233
-rw-r--r--src/secret_base.c33
-rw-r--r--src/smokescreen.c71
-rw-r--r--src/start_menu.c1331
-rw-r--r--src/starter_choose.c6
-rw-r--r--src/text.c21
-rw-r--r--src/text_window.c40
-rw-r--r--src/time_events.c2
-rw-r--r--src/title_screen.c3
-rw-r--r--src/trader.c209
-rw-r--r--src/tv.c679
-rw-r--r--src/util.c2
-rw-r--r--src/walda_phrase.c7
-rw-r--r--src/window.c32
127 files changed, 52310 insertions, 9046 deletions
diff --git a/src/bard_music.c b/src/bard_music.c
index 6fb1496e5..6c2578071 100644
--- a/src/bard_music.c
+++ b/src/bard_music.c
@@ -2,6 +2,7 @@
// Includes
#include "global.h"
#include "bard_music.h"
+#include "constants/easy_chat.h"
#include "easy_chat.h"
#include "data/bard_music/bard_sounds.h"
diff --git a/src/battle_ai_script_commands.c b/src/battle_ai_script_commands.c
index d6ccf9305..e1a9168a9 100644
--- a/src/battle_ai_script_commands.c
+++ b/src/battle_ai_script_commands.c
@@ -12,10 +12,6 @@
#include "util.h"
#include "constants/battle_ai.h"
-#define AIScriptRead32(ptr) ((ptr)[0] | (ptr)[1] << 8 | (ptr)[2] << 16 | (ptr)[3] << 24)
-#define AIScriptRead16(ptr) ((ptr)[0] | (ptr)[1] << 8)
-#define AIScriptReadPtr(ptr) (const u8*) AIScriptRead32(ptr)
-
#define AI_ACTION_DONE 0x0001
#define AI_ACTION_FLEE 0x0002
#define AI_ACTION_WATCH 0x0004
@@ -45,7 +41,6 @@ in order to read the next command correctly. refer to battle_ai_scripts.s for th
AI scripts.
*/
-extern const struct BattleMove gBattleMoves[];
extern const u8 * const gBattleAI_ScriptsTable[];
extern u32 GetAiScriptsInRecordedBattle();
@@ -346,7 +341,7 @@ void BattleAI_SetupAIData(u8 defaultScoreMoves)
}
gBattleResources->AI_ScriptsStack->size = 0;
sBattler_AI = gActiveBattler;
- // decide a random target bank in doubles
+ // decide a random target battlerId in doubles
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
gBattlerTarget = (Random() & BIT_FLANK) + (GetBattlerSide(gActiveBattler) ^ BIT_SIDE);
@@ -620,32 +615,32 @@ static void RecordLastUsedMoveByTarget(void)
}
}
-void ClearBattlerMoveHistory(u8 bank)
+void ClearBattlerMoveHistory(u8 battlerId)
{
s32 i;
for (i = 0; i < 4; i++)
- gBattleResources->battleHistory->usedMoves[bank].moves[i] = 0;
+ gBattleResources->battleHistory->usedMoves[battlerId].moves[i] = 0;
}
-void RecordAbilityBattle(u8 bank, u8 abilityId)
+void RecordAbilityBattle(u8 battlerId, u8 abilityId)
{
- gBattleResources->battleHistory->abilities[bank] = abilityId;
+ gBattleResources->battleHistory->abilities[battlerId] = abilityId;
}
-void ClearBattlerAbilityHistory(u8 bank)
+void ClearBattlerAbilityHistory(u8 battlerId)
{
- gBattleResources->battleHistory->abilities[bank] = 0;
+ gBattleResources->battleHistory->abilities[battlerId] = 0;
}
-void RecordItemEffectBattle(u8 bank, u8 itemEffect)
+void RecordItemEffectBattle(u8 battlerId, u8 itemEffect)
{
- gBattleResources->battleHistory->itemEffects[bank] = itemEffect;
+ gBattleResources->battleHistory->itemEffects[battlerId] = itemEffect;
}
-void ClearBankItemEffectHistory(u8 bank)
+void ClearBankItemEffectHistory(u8 battlerId)
{
- gBattleResources->battleHistory->itemEffects[bank] = 0;
+ gBattleResources->battleHistory->itemEffects[battlerId] = 0;
}
static void BattleAICmd_if_random_less_than(void)
@@ -653,7 +648,7 @@ static void BattleAICmd_if_random_less_than(void)
u16 random = Random();
if (random % 256 < gAIScriptPtr[1])
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
else
gAIScriptPtr += 6;
}
@@ -663,7 +658,7 @@ static void BattleAICmd_if_random_greater_than(void)
u16 random = Random();
if (random % 256 > gAIScriptPtr[1])
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
else
gAIScriptPtr += 6;
}
@@ -673,7 +668,7 @@ static void BattleAICmd_if_random_equal(void)
u16 random = Random();
if (random % 256 == gAIScriptPtr[1])
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
else
gAIScriptPtr += 6;
}
@@ -683,7 +678,7 @@ static void BattleAICmd_if_random_not_equal(void)
u16 random = Random();
if (random % 256 != gAIScriptPtr[1])
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
else
gAIScriptPtr += 6;
}
@@ -700,206 +695,206 @@ static void BattleAICmd_score(void)
static void BattleAICmd_if_hp_less_than(void)
{
- u16 bank;
+ u16 battlerId;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
- if ((u32)(100 * gBattleMons[bank].hp / gBattleMons[bank].maxHP) < gAIScriptPtr[2])
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3);
+ if ((u32)(100 * gBattleMons[battlerId].hp / gBattleMons[battlerId].maxHP) < gAIScriptPtr[2])
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3);
else
gAIScriptPtr += 7;
}
static void BattleAICmd_if_hp_more_than(void)
{
- u16 bank;
+ u16 battlerId;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
- if ((u32)(100 * gBattleMons[bank].hp / gBattleMons[bank].maxHP) > gAIScriptPtr[2])
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3);
+ if ((u32)(100 * gBattleMons[battlerId].hp / gBattleMons[battlerId].maxHP) > gAIScriptPtr[2])
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3);
else
gAIScriptPtr += 7;
}
static void BattleAICmd_if_hp_equal(void)
{
- u16 bank;
+ u16 battlerId;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
- if ((u32)(100 * gBattleMons[bank].hp / gBattleMons[bank].maxHP) == gAIScriptPtr[2])
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3);
+ if ((u32)(100 * gBattleMons[battlerId].hp / gBattleMons[battlerId].maxHP) == gAIScriptPtr[2])
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3);
else
gAIScriptPtr += 7;
}
static void BattleAICmd_if_hp_not_equal(void)
{
- u16 bank;
+ u16 battlerId;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
- if ((u32)(100 * gBattleMons[bank].hp / gBattleMons[bank].maxHP) != gAIScriptPtr[2])
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3);
+ if ((u32)(100 * gBattleMons[battlerId].hp / gBattleMons[battlerId].maxHP) != gAIScriptPtr[2])
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3);
else
gAIScriptPtr += 7;
}
static void BattleAICmd_if_status(void)
{
- u16 bank;
+ u16 battlerId;
u32 status;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
- status = AIScriptRead32(gAIScriptPtr + 2);
+ status = T1_READ_32(gAIScriptPtr + 2);
- if ((gBattleMons[bank].status1 & status) != 0)
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6);
+ if ((gBattleMons[battlerId].status1 & status) != 0)
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6);
else
gAIScriptPtr += 10;
}
static void BattleAICmd_if_not_status(void)
{
- u16 bank;
+ u16 battlerId;
u32 status;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
- status = AIScriptRead32(gAIScriptPtr + 2);
+ status = T1_READ_32(gAIScriptPtr + 2);
- if ((gBattleMons[bank].status1 & status) == 0)
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6);
+ if ((gBattleMons[battlerId].status1 & status) == 0)
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6);
else
gAIScriptPtr += 10;
}
static void BattleAICmd_if_status2(void)
{
- u16 bank;
+ u16 battlerId;
u32 status;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
- status = AIScriptRead32(gAIScriptPtr + 2);
+ status = T1_READ_32(gAIScriptPtr + 2);
- if ((gBattleMons[bank].status2 & status) != 0)
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6);
+ if ((gBattleMons[battlerId].status2 & status) != 0)
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6);
else
gAIScriptPtr += 10;
}
static void BattleAICmd_if_not_status2(void)
{
- u16 bank;
+ u16 battlerId;
u32 status;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
- status = AIScriptRead32(gAIScriptPtr + 2);
+ status = T1_READ_32(gAIScriptPtr + 2);
- if ((gBattleMons[bank].status2 & status) == 0)
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6);
+ if ((gBattleMons[battlerId].status2 & status) == 0)
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6);
else
gAIScriptPtr += 10;
}
static void BattleAICmd_if_status3(void)
{
- u16 bank;
+ u16 battlerId;
u32 status;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
- status = AIScriptRead32(gAIScriptPtr + 2);
+ status = T1_READ_32(gAIScriptPtr + 2);
- if ((gStatuses3[bank] & status) != 0)
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6);
+ if ((gStatuses3[battlerId] & status) != 0)
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6);
else
gAIScriptPtr += 10;
}
static void BattleAICmd_if_not_status3(void)
{
- u16 bank;
+ u16 battlerId;
u32 status;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
- status = AIScriptRead32(gAIScriptPtr + 2);
+ status = T1_READ_32(gAIScriptPtr + 2);
- if ((gStatuses3[bank] & status) == 0)
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6);
+ if ((gStatuses3[battlerId] & status) == 0)
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6);
else
gAIScriptPtr += 10;
}
static void BattleAICmd_if_side_affecting(void)
{
- u16 bank;
+ u16 battlerId;
u32 side, status;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
- side = GET_BATTLER_SIDE(bank);
- status = AIScriptRead32(gAIScriptPtr + 2);
+ side = GET_BATTLER_SIDE(battlerId);
+ status = T1_READ_32(gAIScriptPtr + 2);
if ((gSideStatuses[side] & status) != 0)
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6);
else
gAIScriptPtr += 10;
}
static void BattleAICmd_if_not_side_affecting(void)
{
- u16 bank;
+ u16 battlerId;
u32 side, status;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
- side = GET_BATTLER_SIDE(bank);
- status = AIScriptRead32(gAIScriptPtr + 2);
+ side = GET_BATTLER_SIDE(battlerId);
+ status = T1_READ_32(gAIScriptPtr + 2);
if ((gSideStatuses[side] & status) == 0)
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6);
else
gAIScriptPtr += 10;
}
@@ -907,7 +902,7 @@ static void BattleAICmd_if_not_side_affecting(void)
static void BattleAICmd_if_less_than(void)
{
if (AI_THINKING_STRUCT->funcResult < gAIScriptPtr[1])
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
else
gAIScriptPtr += 6;
}
@@ -915,7 +910,7 @@ static void BattleAICmd_if_less_than(void)
static void BattleAICmd_if_more_than(void)
{
if (AI_THINKING_STRUCT->funcResult > gAIScriptPtr[1])
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
else
gAIScriptPtr += 6;
}
@@ -923,7 +918,7 @@ static void BattleAICmd_if_more_than(void)
static void BattleAICmd_if_equal(void)
{
if (AI_THINKING_STRUCT->funcResult == gAIScriptPtr[1])
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
else
gAIScriptPtr += 6;
}
@@ -931,80 +926,80 @@ static void BattleAICmd_if_equal(void)
static void BattleAICmd_if_not_equal(void)
{
if (AI_THINKING_STRUCT->funcResult != gAIScriptPtr[1])
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
else
gAIScriptPtr += 6;
}
static void BattleAICmd_if_less_than_ptr(void)
{
- const u8 *value = AIScriptReadPtr(gAIScriptPtr + 1);
+ const u8 *value = T1_READ_PTR(gAIScriptPtr + 1);
if (AI_THINKING_STRUCT->funcResult < *value)
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5);
else
gAIScriptPtr += 9;
}
static void BattleAICmd_if_more_than_ptr(void)
{
- const u8 *value = AIScriptReadPtr(gAIScriptPtr + 1);
+ const u8 *value = T1_READ_PTR(gAIScriptPtr + 1);
if (AI_THINKING_STRUCT->funcResult > *value)
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5);
else
gAIScriptPtr += 9;
}
static void BattleAICmd_if_equal_ptr(void)
{
- const u8 *value = AIScriptReadPtr(gAIScriptPtr + 1);
+ const u8 *value = T1_READ_PTR(gAIScriptPtr + 1);
if (AI_THINKING_STRUCT->funcResult == *value)
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5);
else
gAIScriptPtr += 9;
}
static void BattleAICmd_if_not_equal_ptr(void)
{
- const u8 *value = AIScriptReadPtr(gAIScriptPtr + 1);
+ const u8 *value = T1_READ_PTR(gAIScriptPtr + 1);
if (AI_THINKING_STRUCT->funcResult != *value)
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5);
else
gAIScriptPtr += 9;
}
static void BattleAICmd_if_move(void)
{
- u16 move = AIScriptRead16(gAIScriptPtr + 1);
+ u16 move = T1_READ_16(gAIScriptPtr + 1);
if (AI_THINKING_STRUCT->moveConsidered == move)
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3);
else
gAIScriptPtr += 7;
}
static void BattleAICmd_if_not_move(void)
{
- u16 move = AIScriptRead16(gAIScriptPtr + 1);
+ u16 move = T1_READ_16(gAIScriptPtr + 1);
if (AI_THINKING_STRUCT->moveConsidered != move)
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3);
else
gAIScriptPtr += 7;
}
static void BattleAICmd_if_in_bytes(void)
{
- const u8 *ptr = AIScriptReadPtr(gAIScriptPtr + 1);
+ const u8 *ptr = T1_READ_PTR(gAIScriptPtr + 1);
while (*ptr != 0xFF)
{
if (AI_THINKING_STRUCT->funcResult == *ptr)
{
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5);
return;
}
ptr++;
@@ -1014,7 +1009,7 @@ static void BattleAICmd_if_in_bytes(void)
static void BattleAICmd_if_not_in_bytes(void)
{
- const u8 *ptr = AIScriptReadPtr(gAIScriptPtr + 1);
+ const u8 *ptr = T1_READ_PTR(gAIScriptPtr + 1);
while (*ptr != 0xFF)
{
@@ -1025,18 +1020,18 @@ static void BattleAICmd_if_not_in_bytes(void)
}
ptr++;
}
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5);
}
static void BattleAICmd_if_in_hwords(void)
{
- const u16 *ptr = (const u16 *)AIScriptReadPtr(gAIScriptPtr + 1);
+ const u16 *ptr = (const u16 *)T1_READ_PTR(gAIScriptPtr + 1);
while (*ptr != 0xFFFF)
{
if (AI_THINKING_STRUCT->funcResult == *ptr)
{
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5);
return;
}
ptr++;
@@ -1046,7 +1041,7 @@ static void BattleAICmd_if_in_hwords(void)
static void BattleAICmd_if_not_in_hwords(void)
{
- const u16 *ptr = (u16 *)AIScriptReadPtr(gAIScriptPtr + 1);
+ const u16 *ptr = (u16 *)T1_READ_PTR(gAIScriptPtr + 1);
while (*ptr != 0xFFFF)
{
@@ -1057,7 +1052,7 @@ static void BattleAICmd_if_not_in_hwords(void)
}
ptr++;
}
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 5);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5);
}
static void BattleAICmd_if_user_has_attacking_move(void)
@@ -1073,7 +1068,7 @@ static void BattleAICmd_if_user_has_attacking_move(void)
if (i == 4)
gAIScriptPtr += 5;
else
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1);
}
static void BattleAICmd_if_user_has_no_attacking_moves(void)
@@ -1089,7 +1084,7 @@ static void BattleAICmd_if_user_has_no_attacking_moves(void)
if (i != 4)
gAIScriptPtr += 5;
else
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1);
}
static void BattleAICmd_get_turn_count(void)
@@ -1123,9 +1118,9 @@ static void BattleAICmd_get_type(void)
gAIScriptPtr += 2;
}
-static u8 BattleAI_GetWantedBank(u8 bank)
+static u8 BattleAI_GetWantedBank(u8 battlerId)
{
- switch (bank)
+ switch (battlerId)
{
case AI_USER:
return sBattler_AI;
@@ -1141,9 +1136,9 @@ static u8 BattleAI_GetWantedBank(u8 bank)
static void BattleAICmd_is_of_type(void)
{
- u8 bank = BattleAI_GetWantedBank(gAIScriptPtr[1]);
+ u8 battlerId = BattleAI_GetWantedBank(gAIScriptPtr[1]);
- if(gBattleMons[bank].type1 == gAIScriptPtr[2] || gBattleMons[bank].type2 == gAIScriptPtr[2])
+ if(gBattleMons[battlerId].type1 == gAIScriptPtr[2] || gBattleMons[battlerId].type2 == gAIScriptPtr[2])
{
AI_THINKING_STRUCT->funcResult = TRUE;
}
@@ -1238,7 +1233,7 @@ static void BattleAICmd_get_last_used_bank_move(void)
static void BattleAICmd_if_equal_(void) // same as if_equal
{
if (gAIScriptPtr[1] == AI_THINKING_STRUCT->funcResult)
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
else
gAIScriptPtr += 6;
}
@@ -1246,7 +1241,7 @@ static void BattleAICmd_if_equal_(void) // same as if_equal
static void BattleAICmd_if_not_equal_(void) // same as if_not_equal
{
if (gAIScriptPtr[1] != AI_THINKING_STRUCT->funcResult)
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
else
gAIScriptPtr += 6;
}
@@ -1254,7 +1249,7 @@ static void BattleAICmd_if_not_equal_(void) // same as if_not_equal
static void BattleAICmd_if_user_goes(void)
{
if (GetWhoStrikesFirst(sBattler_AI, gBattlerTarget, TRUE) == gAIScriptPtr[1])
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
else
gAIScriptPtr += 6;
}
@@ -1262,7 +1257,7 @@ static void BattleAICmd_if_user_goes(void)
static void BattleAICmd_if_user_doesnt_go(void)
{
if (GetWhoStrikesFirst(sBattler_AI, gBattlerTarget, TRUE) != gAIScriptPtr[1])
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
else
gAIScriptPtr += 6;
}
@@ -1277,7 +1272,7 @@ static void BattleAICmd_nullsub_2B(void)
static void BattleAICmd_count_usable_party_mons(void)
{
- u8 bank;
+ u8 battlerId;
u8 bankOnField1, bankOnField2;
struct Pokemon *party;
int i;
@@ -1285,11 +1280,11 @@ static void BattleAICmd_count_usable_party_mons(void)
AI_THINKING_STRUCT->funcResult = 0;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
- if (GetBattlerSide(bank) == B_SIDE_PLAYER)
+ if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
party = gPlayerParty;
else
party = gEnemyParty;
@@ -1297,14 +1292,14 @@ static void BattleAICmd_count_usable_party_mons(void)
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
u32 position;
- bankOnField1 = gBattlerPartyIndexes[bank];
- position = GetBattlerPosition(bank) ^ BIT_FLANK;
+ bankOnField1 = gBattlerPartyIndexes[battlerId];
+ position = GetBattlerPosition(battlerId) ^ BIT_FLANK;
bankOnField2 = gBattlerPartyIndexes[GetBattlerAtPosition(position)];
}
- else // in singles there's only one bank by side
+ else // in singles there's only one battlerId by side
{
- bankOnField1 = gBattlerPartyIndexes[bank];
- bankOnField2 = gBattlerPartyIndexes[bank];
+ bankOnField1 = gBattlerPartyIndexes[battlerId];
+ bankOnField2 = gBattlerPartyIndexes[battlerId];
}
for (i = 0; i < PARTY_SIZE; i++)
@@ -1335,110 +1330,110 @@ static void BattleAICmd_get_considered_move_effect(void)
static void BattleAICmd_get_ability(void)
{
- u8 bank;
+ u8 battlerId;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
- if (gActiveBattler != bank)
+ if (gActiveBattler != battlerId)
{
- if (BATTLE_HISTORY->abilities[bank] != 0)
+ if (BATTLE_HISTORY->abilities[battlerId] != 0)
{
- AI_THINKING_STRUCT->funcResult = BATTLE_HISTORY->abilities[bank];
+ AI_THINKING_STRUCT->funcResult = BATTLE_HISTORY->abilities[battlerId];
gAIScriptPtr += 2;
return;
}
// abilities that prevent fleeing.
- if (gBattleMons[bank].ability == ABILITY_SHADOW_TAG
- || gBattleMons[bank].ability == ABILITY_MAGNET_PULL
- || gBattleMons[bank].ability == ABILITY_ARENA_TRAP)
+ if (gBattleMons[battlerId].ability == ABILITY_SHADOW_TAG
+ || gBattleMons[battlerId].ability == ABILITY_MAGNET_PULL
+ || gBattleMons[battlerId].ability == ABILITY_ARENA_TRAP)
{
- AI_THINKING_STRUCT->funcResult = gBattleMons[bank].ability;
+ AI_THINKING_STRUCT->funcResult = gBattleMons[battlerId].ability;
gAIScriptPtr += 2;
return;
}
- if (gBaseStats[gBattleMons[bank].species].ability1 != ABILITY_NONE)
+ if (gBaseStats[gBattleMons[battlerId].species].ability1 != ABILITY_NONE)
{
- if (gBaseStats[gBattleMons[bank].species].ability2 != ABILITY_NONE)
+ if (gBaseStats[gBattleMons[battlerId].species].ability2 != ABILITY_NONE)
{
// AI has no knowledge of opponent, so it guesses which ability.
if (Random() & 1)
{
- AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[bank].species].ability1;
+ AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[battlerId].species].ability1;
}
else
{
- AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[bank].species].ability2;
+ AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[battlerId].species].ability2;
}
}
else
{
- AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[bank].species].ability1; // it's definitely ability 1.
+ AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[battlerId].species].ability1; // it's definitely ability 1.
}
}
else
{
- AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[bank].species].ability2; // AI cant actually reach this part since every mon has at least 1 ability.
+ AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[battlerId].species].ability2; // AI cant actually reach this part since every mon has at least 1 ability.
}
}
else
{
// The AI knows its own ability.
- AI_THINKING_STRUCT->funcResult = gBattleMons[bank].ability;
+ AI_THINKING_STRUCT->funcResult = gBattleMons[battlerId].ability;
}
gAIScriptPtr += 2;
}
static void BattleAICmd_check_ability(void)
{
- u32 bank = BattleAI_GetWantedBank(gAIScriptPtr[1]);
+ u32 battlerId = BattleAI_GetWantedBank(gAIScriptPtr[1]);
u32 ability = gAIScriptPtr[2];
if (gAIScriptPtr[1] == AI_TARGET || gAIScriptPtr[1] == AI_TARGET_PARTNER)
{
- if (BATTLE_HISTORY->abilities[bank] != 0)
+ if (BATTLE_HISTORY->abilities[battlerId] != 0)
{
- ability = BATTLE_HISTORY->abilities[bank];
+ ability = BATTLE_HISTORY->abilities[battlerId];
AI_THINKING_STRUCT->funcResult = ability;
}
// abilities that prevent fleeing.
- else if (gBattleMons[bank].ability == ABILITY_SHADOW_TAG
- || gBattleMons[bank].ability == ABILITY_MAGNET_PULL
- || gBattleMons[bank].ability == ABILITY_ARENA_TRAP)
+ else if (gBattleMons[battlerId].ability == ABILITY_SHADOW_TAG
+ || gBattleMons[battlerId].ability == ABILITY_MAGNET_PULL
+ || gBattleMons[battlerId].ability == ABILITY_ARENA_TRAP)
{
- ability = gBattleMons[bank].ability;
+ ability = gBattleMons[battlerId].ability;
}
- else if (gBaseStats[gBattleMons[bank].species].ability1 != ABILITY_NONE)
+ else if (gBaseStats[gBattleMons[battlerId].species].ability1 != ABILITY_NONE)
{
- if (gBaseStats[gBattleMons[bank].species].ability2 != ABILITY_NONE)
+ if (gBaseStats[gBattleMons[battlerId].species].ability2 != ABILITY_NONE)
{
u8 abilityDummyVariable = ability; // needed to match
- if (gBaseStats[gBattleMons[bank].species].ability1 != abilityDummyVariable
- && gBaseStats[gBattleMons[bank].species].ability2 != abilityDummyVariable)
+ if (gBaseStats[gBattleMons[battlerId].species].ability1 != abilityDummyVariable
+ && gBaseStats[gBattleMons[battlerId].species].ability2 != abilityDummyVariable)
{
- ability = gBaseStats[gBattleMons[bank].species].ability1;
+ ability = gBaseStats[gBattleMons[battlerId].species].ability1;
}
else
ability = 0;
}
else
{
- ability = gBaseStats[gBattleMons[bank].species].ability1;
+ ability = gBaseStats[gBattleMons[battlerId].species].ability1;
}
}
else
{
- ability = gBaseStats[gBattleMons[bank].species].ability2; // AI cant actually reach this part since every mon has at least 1 ability.
+ ability = gBaseStats[gBattleMons[battlerId].species].ability2; // AI cant actually reach this part since every mon has at least 1 ability.
}
}
else
{
// The AI knows its own or partner's ability.
- ability = gBattleMons[bank].ability;
+ ability = gBattleMons[battlerId].ability;
}
if (ability == 0)
{
@@ -1528,7 +1523,7 @@ static void BattleAICmd_if_type_effectiveness(void)
damageVar = gBattleMoveDamage;
if (damageVar == gAIScriptPtr[1])
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
else
gAIScriptPtr += 6;
}
@@ -1546,21 +1541,21 @@ static void BattleAICmd_if_status_in_party(void)
struct Pokemon *party;
int i;
u32 statusToCompareTo;
- u8 bank;
+ u8 battlerId;
switch(gAIScriptPtr[1])
{
case AI_USER:
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
break;
default:
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
break;
}
- party = (GetBattlerSide(bank) == B_SIDE_PLAYER) ? gPlayerParty : gEnemyParty;
+ party = (GetBattlerSide(battlerId) == B_SIDE_PLAYER) ? gPlayerParty : gEnemyParty;
- statusToCompareTo = AIScriptRead32(gAIScriptPtr + 2);
+ statusToCompareTo = T1_READ_32(gAIScriptPtr + 2);
for (i = 0; i < PARTY_SIZE; i++)
{
@@ -1570,7 +1565,7 @@ static void BattleAICmd_if_status_in_party(void)
if (species != SPECIES_NONE && species != SPECIES_EGG && hp != 0 && status == statusToCompareTo)
{
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6);
return;
}
}
@@ -1583,21 +1578,21 @@ static void BattleAICmd_if_status_not_in_party(void)
struct Pokemon *party;
int i;
u32 statusToCompareTo;
- u8 bank;
+ u8 battlerId;
switch(gAIScriptPtr[1])
{
case 1:
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
break;
default:
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
break;
}
- party = (GetBattlerSide(bank) == B_SIDE_PLAYER) ? gPlayerParty : gEnemyParty;
+ party = (GetBattlerSide(battlerId) == B_SIDE_PLAYER) ? gPlayerParty : gEnemyParty;
- statusToCompareTo = AIScriptRead32(gAIScriptPtr + 2);
+ statusToCompareTo = T1_READ_32(gAIScriptPtr + 2);
for (i = 0; i < PARTY_SIZE; i++)
{
@@ -1611,7 +1606,7 @@ static void BattleAICmd_if_status_not_in_party(void)
}
}
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 6);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6);
}
static void BattleAICmd_get_weather(void)
@@ -1631,7 +1626,7 @@ static void BattleAICmd_get_weather(void)
static void BattleAICmd_if_effect(void)
{
if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect == gAIScriptPtr[1])
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
else
gAIScriptPtr += 6;
}
@@ -1639,67 +1634,67 @@ static void BattleAICmd_if_effect(void)
static void BattleAICmd_if_not_effect(void)
{
if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect != gAIScriptPtr[1])
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
else
gAIScriptPtr += 6;
}
static void BattleAICmd_if_stat_level_less_than(void)
{
- u32 bank;
+ u32 battlerId;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
- if (gBattleMons[bank].statStages[gAIScriptPtr[2]] < gAIScriptPtr[3])
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4);
+ if (gBattleMons[battlerId].statStages[gAIScriptPtr[2]] < gAIScriptPtr[3])
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4);
else
gAIScriptPtr += 8;
}
static void BattleAICmd_if_stat_level_more_than(void)
{
- u32 bank;
+ u32 battlerId;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
- if (gBattleMons[bank].statStages[gAIScriptPtr[2]] > gAIScriptPtr[3])
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4);
+ if (gBattleMons[battlerId].statStages[gAIScriptPtr[2]] > gAIScriptPtr[3])
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4);
else
gAIScriptPtr += 8;
}
static void BattleAICmd_if_stat_level_equal(void)
{
- u32 bank;
+ u32 battlerId;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
- if (gBattleMons[bank].statStages[gAIScriptPtr[2]] == gAIScriptPtr[3])
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4);
+ if (gBattleMons[battlerId].statStages[gAIScriptPtr[2]] == gAIScriptPtr[3])
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4);
else
gAIScriptPtr += 8;
}
static void BattleAICmd_if_stat_level_not_equal(void)
{
- u32 bank;
+ u32 battlerId;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
- if (gBattleMons[bank].statStages[gAIScriptPtr[2]] != gAIScriptPtr[3])
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4);
+ if (gBattleMons[battlerId].statStages[gAIScriptPtr[2]] != gAIScriptPtr[3])
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4);
else
gAIScriptPtr += 8;
}
@@ -1728,7 +1723,7 @@ static void BattleAICmd_if_can_faint(void)
gBattleMoveDamage = 1;
if (gBattleMons[gBattlerTarget].hp <= gBattleMoveDamage)
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1);
else
gAIScriptPtr += 5;
}
@@ -1755,7 +1750,7 @@ static void BattleAICmd_if_cant_faint(void)
// this macro is missing the damage 0 = 1 assumption.
if (gBattleMons[gBattlerTarget].hp > gBattleMoveDamage)
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1);
else
gAIScriptPtr += 5;
}
@@ -1780,7 +1775,7 @@ static void BattleAICmd_if_has_move(void)
}
else
{
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4);
return;
}
case AI_USER_PARTNER:
@@ -1804,7 +1799,7 @@ static void BattleAICmd_if_has_move(void)
}
else
{
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4);
return;
}
case AI_TARGET:
@@ -1821,7 +1816,7 @@ static void BattleAICmd_if_has_move(void)
}
else
{
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4);
return;
}
}
@@ -1848,7 +1843,7 @@ static void BattleAICmd_if_doesnt_have_move(void)
}
else
{
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4);
return;
}
case AI_TARGET:
@@ -1865,7 +1860,7 @@ static void BattleAICmd_if_doesnt_have_move(void)
}
else
{
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4);
return;
}
}
@@ -1887,7 +1882,7 @@ static void BattleAICmd_if_has_move_with_effect(void)
if (i == 4)
gAIScriptPtr += 7;
else
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3);
break;
case AI_TARGET:
case AI_TARGET_PARTNER:
@@ -1900,7 +1895,7 @@ static void BattleAICmd_if_has_move_with_effect(void)
if (i == 4)
gAIScriptPtr += 7;
else
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3);
break;
}
}
@@ -1921,7 +1916,7 @@ static void BattleAICmd_if_doesnt_have_move_with_effect(void)
if (i != 4)
gAIScriptPtr += 7;
else
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3);
break;
case AI_TARGET:
case AI_TARGET_PARTNER:
@@ -1933,28 +1928,28 @@ static void BattleAICmd_if_doesnt_have_move_with_effect(void)
if (i != 4)
gAIScriptPtr += 7;
else
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3);
break;
}
}
static void BattleAICmd_if_any_move_disabled_or_encored(void)
{
- u8 bank;
+ u8 battlerId;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
if (gAIScriptPtr[2] == 0)
{
- if (gDisableStructs[bank].disabledMove == 0)
+ if (gDisableStructs[battlerId].disabledMove == 0)
{
gAIScriptPtr += 7;
return;
}
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3);
return;
}
else if (gAIScriptPtr[2] != 1) // ignore the macro if its not 0 or 1.
@@ -1962,9 +1957,9 @@ static void BattleAICmd_if_any_move_disabled_or_encored(void)
gAIScriptPtr += 7;
return;
}
- else if (gDisableStructs[bank].encoredMove != 0)
+ else if (gDisableStructs[battlerId].encoredMove != 0)
{
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 3);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3);
return;
}
gAIScriptPtr += 7;
@@ -1977,7 +1972,7 @@ static void BattleAICmd_if_curr_move_disabled_or_encored(void)
case 0:
if (gDisableStructs[gActiveBattler].disabledMove == AI_THINKING_STRUCT->moveConsidered)
{
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
return;
}
gAIScriptPtr += 6;
@@ -1985,7 +1980,7 @@ static void BattleAICmd_if_curr_move_disabled_or_encored(void)
case 1:
if (gDisableStructs[gActiveBattler].encoredMove == AI_THINKING_STRUCT->moveConsidered)
{
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
return;
}
gAIScriptPtr += 6;
@@ -2006,7 +2001,7 @@ static void BattleAICmd_if_random_safari_flee(void)
u8 safariFleeRate = gBattleStruct->field_7B * 5; // safari flee rate, from 0-20
if ((u8)(Random() % 100) < safariFleeRate)
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1);
else
gAIScriptPtr += 5;
}
@@ -2018,80 +2013,80 @@ static void BattleAICmd_watch(void)
static void BattleAICmd_get_hold_effect(void)
{
- u8 bank;
+ u8 battlerId;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
- if (gActiveBattler != bank)
- AI_THINKING_STRUCT->funcResult = ItemId_GetHoldEffect(BATTLE_HISTORY->itemEffects[bank]);
+ if (gActiveBattler != battlerId)
+ AI_THINKING_STRUCT->funcResult = ItemId_GetHoldEffect(BATTLE_HISTORY->itemEffects[battlerId]);
else
- AI_THINKING_STRUCT->funcResult = ItemId_GetHoldEffect(gBattleMons[bank].item);
+ AI_THINKING_STRUCT->funcResult = ItemId_GetHoldEffect(gBattleMons[battlerId].item);
gAIScriptPtr += 2;
}
static void BattleAICmd_if_holds_item(void)
{
- u8 bank = BattleAI_GetWantedBank(gAIScriptPtr[1]);
+ u8 battlerId = BattleAI_GetWantedBank(gAIScriptPtr[1]);
u16 item;
u8 var1, var2;
- if ((bank & BIT_SIDE) == (sBattler_AI & BIT_SIDE))
- item = gBattleMons[bank].item;
+ if ((battlerId & BIT_SIDE) == (sBattler_AI & BIT_SIDE))
+ item = gBattleMons[battlerId].item;
else
- item = BATTLE_HISTORY->itemEffects[bank];
+ item = BATTLE_HISTORY->itemEffects[battlerId];
// UB: doesn't properly read an unaligned u16
var2 = gAIScriptPtr[2];
var1 = gAIScriptPtr[3];
if ((var1 | var2) == item)
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 4);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4);
else
gAIScriptPtr += 8;
}
static void BattleAICmd_get_gender(void)
{
- u8 bank;
+ u8 battlerId;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
- AI_THINKING_STRUCT->funcResult = GetGenderFromSpeciesAndPersonality(gBattleMons[bank].species, gBattleMons[bank].personality);
+ AI_THINKING_STRUCT->funcResult = GetGenderFromSpeciesAndPersonality(gBattleMons[battlerId].species, gBattleMons[battlerId].personality);
gAIScriptPtr += 2;
}
static void BattleAICmd_is_first_turn_for(void)
{
- u8 bank;
+ u8 battlerId;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
- AI_THINKING_STRUCT->funcResult = gDisableStructs[bank].isFirstTurn;
+ AI_THINKING_STRUCT->funcResult = gDisableStructs[battlerId].isFirstTurn;
gAIScriptPtr += 2;
}
static void BattleAICmd_get_stockpile_count(void)
{
- u8 bank;
+ u8 battlerId;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
- AI_THINKING_STRUCT->funcResult = gDisableStructs[bank].stockpileCounter;
+ AI_THINKING_STRUCT->funcResult = gDisableStructs[battlerId].stockpileCounter;
gAIScriptPtr += 2;
}
@@ -2105,18 +2100,18 @@ static void BattleAICmd_is_double_battle(void)
static void BattleAICmd_get_used_held_item(void)
{
- u8 bank;
+ u8 battlerId;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
// This is likely a leftover from Ruby's code and its ugly ewram access
#ifdef NONMATCHING
- AI_THINKING_STRUCT->funcResult = gBattleStruct->usedHeldItems[bank];
+ AI_THINKING_STRUCT->funcResult = gBattleStruct->usedHeldItems[battlerId];
#else
- AI_THINKING_STRUCT->funcResult = *(u8*)((u8*)(gBattleStruct) + offsetof(struct BattleStruct, usedHeldItems) + (bank * 2));
+ AI_THINKING_STRUCT->funcResult = *(u8*)((u8*)(gBattleStruct) + offsetof(struct BattleStruct, usedHeldItems) + (battlerId * 2));
#endif // NONMATCHING
gAIScriptPtr += 2;
@@ -2145,14 +2140,14 @@ static void BattleAICmd_get_move_effect_from_result(void)
static void BattleAICmd_get_protect_count(void)
{
- u8 bank;
+ u8 battlerId;
if (gAIScriptPtr[1] == AI_USER)
- bank = sBattler_AI;
+ battlerId = sBattler_AI;
else
- bank = gBattlerTarget;
+ battlerId = gBattlerTarget;
- AI_THINKING_STRUCT->funcResult = gDisableStructs[bank].protectUses;
+ AI_THINKING_STRUCT->funcResult = gDisableStructs[battlerId].protectUses;
gAIScriptPtr += 2;
}
@@ -2184,12 +2179,12 @@ static void BattleAICmd_nullsub_57(void)
static void BattleAICmd_call(void)
{
AIStackPushVar(gAIScriptPtr + 5);
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1);
}
static void BattleAICmd_goto(void)
{
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1);
}
static void BattleAICmd_end(void)
@@ -2205,7 +2200,7 @@ static void BattleAICmd_if_level_cond(void)
case 0: // greater than
if (gBattleMons[sBattler_AI].level > gBattleMons[gBattlerTarget].level)
{
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
return;
}
gAIScriptPtr += 6;
@@ -2213,7 +2208,7 @@ static void BattleAICmd_if_level_cond(void)
case 1: // less than
if (gBattleMons[sBattler_AI].level < gBattleMons[gBattlerTarget].level)
{
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
return;
}
gAIScriptPtr += 6;
@@ -2221,7 +2216,7 @@ static void BattleAICmd_if_level_cond(void)
case 2: // equal
if (gBattleMons[sBattler_AI].level == gBattleMons[gBattlerTarget].level)
{
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
return;
}
gAIScriptPtr += 6;
@@ -2232,7 +2227,7 @@ static void BattleAICmd_if_level_cond(void)
static void BattleAICmd_if_target_taunted(void)
{
if (gDisableStructs[gBattlerTarget].tauntTimer1 != 0)
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1);
else
gAIScriptPtr += 5;
}
@@ -2240,7 +2235,7 @@ static void BattleAICmd_if_target_taunted(void)
static void BattleAICmd_if_target_not_taunted(void)
{
if (gDisableStructs[gBattlerTarget].tauntTimer1 == 0)
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1);
else
gAIScriptPtr += 5;
}
@@ -2248,17 +2243,17 @@ static void BattleAICmd_if_target_not_taunted(void)
static void BattleAICmd_if_target_is_ally(void)
{
if ((sBattler_AI & BIT_SIDE) == (gBattlerTarget & BIT_SIDE))
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 1);
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1);
else
gAIScriptPtr += 5;
}
static void BattleAICmd_if_flash_fired(void)
{
- u8 bank = BattleAI_GetWantedBank(gAIScriptPtr[1]);
+ u8 battlerId = BattleAI_GetWantedBank(gAIScriptPtr[1]);
- if (gBattleResources->flags->flags[bank] & UNKNOWN_FLAG_FLASH_FIRE)
- gAIScriptPtr = AIScriptReadPtr(gAIScriptPtr + 2);
+ if (gBattleResources->flags->flags[battlerId] & UNKNOWN_FLAG_FLASH_FIRE)
+ gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2);
else
gAIScriptPtr += 6;
}
diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c
index b0fcc2e29..83ad2b4fd 100644
--- a/src/battle_ai_switch_items.c
+++ b/src/battle_ai_switch_items.c
@@ -8,11 +8,6 @@
#include "random.h"
#include "util.h"
#include "constants/items.h"
-#include "pokemon_item_effects.h"
-
-extern const struct BattleMove gBattleMoves[];
-extern const u8 gTypeEffectiveness[];
-extern const u8 * const gItemEffectTable[]; // todo: fix once struct is declared
// this file's functions
static bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng);
diff --git a/src/battle_anim.c b/src/battle_anim.c
index 7606f701d..8071736e6 100644
--- a/src/battle_anim.c
+++ b/src/battle_anim.c
@@ -19,10 +19,6 @@
// sprites start at 10000 and thus must be subtracted of 10000 to account for the true index.
#define GET_TRUE_SPRITE_INDEX(i) ((i - 10000))
-#define SCRIPT_READ_16(ptr) ((ptr)[0] | ((ptr)[1] << 8))
-#define SCRIPT_READ_32(ptr) (((ptr)[0]) + ((ptr)[1] << 8) + ((ptr)[2] << 16) + ((ptr)[3] << 24))
-#define SCRIPT_READ_PTR(ptr) ((const u8*)(SCRIPT_READ_32(ptr)))
-
#define ANIM_SPRITE_INDEX_COUNT 8
extern u16 gBattle_WIN0H;
@@ -127,7 +123,7 @@ EWRAM_DATA static u8 sAnimBackgroundFadeState = 0;
EWRAM_DATA static u16 sAnimMoveIndex = 0; // set but unused.
EWRAM_DATA u8 gBattleAnimAttacker = 0;
EWRAM_DATA u8 gBattleAnimTarget = 0;
-EWRAM_DATA u16 gAnimSpeciesByBanks[MAX_BATTLERS_COUNT] = {0};
+EWRAM_DATA u16 gAnimBattlerSpecies[MAX_BATTLERS_COUNT] = {0};
EWRAM_DATA u8 gUnknown_02038440 = 0;
// const rom data
@@ -232,15 +228,15 @@ void LaunchBattleAnimation(const u8 *const animsTable[], u16 tableId, bool8 isMo
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
{
if (GetBattlerSide(i) != 0)
- gAnimSpeciesByBanks[i] = GetMonData(&gEnemyParty[gBattlerPartyIndexes[i]], MON_DATA_SPECIES);
+ gAnimBattlerSpecies[i] = GetMonData(&gEnemyParty[gBattlerPartyIndexes[i]], MON_DATA_SPECIES);
else
- gAnimSpeciesByBanks[i] = GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_SPECIES);
+ gAnimBattlerSpecies[i] = GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_SPECIES);
}
}
else
{
for (i = 0; i < 4; i++)
- gAnimSpeciesByBanks[i] = gContestResources->field_18->field_0;
+ gAnimBattlerSpecies[i] = gContestResources->field_18->field_0;
}
if (!isMoveAnim)
@@ -352,7 +348,7 @@ static void ScriptCmd_loadspritegfx(void)
u16 index;
sBattleAnimScriptPtr++;
- index = SCRIPT_READ_16(sBattleAnimScriptPtr);
+ index = T1_READ_16(sBattleAnimScriptPtr);
LoadCompressedObjectPicUsingHeap(&gBattleAnimPicTable[GET_TRUE_SPRITE_INDEX(index)]);
LoadCompressedObjectPaletteUsingHeap(&gBattleAnimPaletteTable[GET_TRUE_SPRITE_INDEX(index)]);
sBattleAnimScriptPtr += 2;
@@ -366,7 +362,7 @@ static void ScriptCmd_unloadspritegfx(void)
u16 index;
sBattleAnimScriptPtr++;
- index = SCRIPT_READ_16(sBattleAnimScriptPtr);
+ index = T1_READ_16(sBattleAnimScriptPtr);
FreeSpriteTilesByTag(gBattleAnimPicTable[GET_TRUE_SPRITE_INDEX(index)].tag);
FreeSpritePaletteByTag(gBattleAnimPicTable[GET_TRUE_SPRITE_INDEX(index)].tag);
sBattleAnimScriptPtr += 2;
@@ -382,7 +378,7 @@ static void ScriptCmd_createsprite(void)
s16 subpriority;
sBattleAnimScriptPtr++;
- template = (const struct SpriteTemplate *)(SCRIPT_READ_32(sBattleAnimScriptPtr));
+ template = (const struct SpriteTemplate *)(T2_READ_32(sBattleAnimScriptPtr));
sBattleAnimScriptPtr += 4;
argVar = sBattleAnimScriptPtr[0];
@@ -392,7 +388,7 @@ static void ScriptCmd_createsprite(void)
sBattleAnimScriptPtr++;
for (i = 0; i < argsCount; i++)
{
- gBattleAnimArgs[i] = SCRIPT_READ_16(sBattleAnimScriptPtr);
+ gBattleAnimArgs[i] = T1_READ_16(sBattleAnimScriptPtr);
sBattleAnimScriptPtr += 2;
}
@@ -433,7 +429,7 @@ static void ScriptCmd_createvisualtask(void)
sBattleAnimScriptPtr++;
- taskFunc = (TaskFunc)SCRIPT_READ_32(sBattleAnimScriptPtr);
+ taskFunc = (TaskFunc)T2_READ_32(sBattleAnimScriptPtr);
sBattleAnimScriptPtr += 4;
taskPriority = sBattleAnimScriptPtr[0];
@@ -444,7 +440,7 @@ static void ScriptCmd_createvisualtask(void)
for (i = 0; i < numArgs; i++)
{
- gBattleAnimArgs[i] = SCRIPT_READ_16(sBattleAnimScriptPtr);
+ gBattleAnimArgs[i] = T1_READ_16(sBattleAnimScriptPtr);
sBattleAnimScriptPtr += 2;
}
@@ -542,26 +538,26 @@ static void ScriptCmd_end(void)
static void ScriptCmd_playse(void)
{
sBattleAnimScriptPtr++;
- PlaySE(SCRIPT_READ_16(sBattleAnimScriptPtr));
+ PlaySE(T1_READ_16(sBattleAnimScriptPtr));
sBattleAnimScriptPtr += 2;
}
-#define t1_MONBG_BANK 0
+#define t1_MONBG_BATTLER 0
#define t1_MON_IN_BG2 1
#define t1_CREATE_ANOTHER_TASK 2
#define t1_IS_SECONDMON_BG 3
-#define t2_BANK_SPRITE_ID 0
+#define t2_BATTLER_SPRITE_ID 0
#define t2_MON_IN_BG2 5
-#define t2_MONBG_BANK 6
+#define t2_MONBG_BATTLER 6
static void sub_80A40F4(u8 taskId)
{
u8 newTaskId;
s16 *selfData = gTasks[taskId].data;
- u8 bankSpriteId = gBattlerSpriteIds[selfData[t1_MONBG_BANK]];
- gSprites[bankSpriteId].invisible = 1;
+ u8 battlerSpriteId = gBattlerSpriteIds[selfData[t1_MONBG_BATTLER]];
+ gSprites[battlerSpriteId].invisible = 1;
if (!selfData[t1_CREATE_ANOTHER_TASK])
{
@@ -570,9 +566,9 @@ static void sub_80A40F4(u8 taskId)
}
newTaskId = CreateTask(task_pA_ma0A_obj_to_bg_pal, 10);
- gTasks[newTaskId].data[t2_BANK_SPRITE_ID] = bankSpriteId;
- gTasks[newTaskId].data[1] = gSprites[bankSpriteId].pos1.x + gSprites[bankSpriteId].pos2.x;
- gTasks[newTaskId].data[2] = gSprites[bankSpriteId].pos1.y + gSprites[bankSpriteId].pos2.y;
+ gTasks[newTaskId].data[t2_BATTLER_SPRITE_ID] = battlerSpriteId;
+ gTasks[newTaskId].data[1] = gSprites[battlerSpriteId].pos1.x + gSprites[battlerSpriteId].pos2.x;
+ gTasks[newTaskId].data[2] = gSprites[battlerSpriteId].pos1.y + gSprites[battlerSpriteId].pos2.y;
if (!selfData[t1_MON_IN_BG2])
{
@@ -586,7 +582,7 @@ static void sub_80A40F4(u8 taskId)
}
gTasks[newTaskId].data[t2_MON_IN_BG2] = selfData[t1_MON_IN_BG2];
- gTasks[newTaskId].data[t2_MONBG_BANK] = selfData[t1_MONBG_BANK];
+ gTasks[newTaskId].data[t2_MONBG_BATTLER] = selfData[t1_MONBG_BATTLER];
sMonAnimTaskIdArray[selfData[t1_IS_SECONDMON_BG]] = newTaskId;
DestroyAnimVisualTask(taskId);
}
@@ -595,48 +591,48 @@ static void ScriptCmd_monbg(void)
{
bool8 toBG_2;
u8 taskId;
- u8 bank;
+ u8 battlerId;
u8 animBank;
sBattleAnimScriptPtr++;
animBank = sBattleAnimScriptPtr[0];
if (animBank & ANIM_TARGET)
- bank = gBattleAnimTarget;
+ battlerId = gBattleAnimTarget;
else
- bank = gBattleAnimAttacker;
+ battlerId = gBattleAnimAttacker;
- if (IsBattlerSpriteVisible(bank))
+ if (IsBattlerSpriteVisible(battlerId))
{
- u8 position = GetBattlerPosition(bank);
+ u8 position = GetBattlerPosition(battlerId);
if (position == B_POSITION_OPPONENT_LEFT || position == B_POSITION_PLAYER_RIGHT || IsContest())
toBG_2 = FALSE;
else
toBG_2 = TRUE;
- sub_80A438C(bank, toBG_2, FALSE);
+ sub_80A438C(battlerId, toBG_2, FALSE);
taskId = CreateTask(sub_80A40F4, 10);
gAnimVisualTaskCount++;
- gTasks[taskId].data[t1_MONBG_BANK] = bank;
+ gTasks[taskId].data[t1_MONBG_BATTLER] = battlerId;
gTasks[taskId].data[t1_MON_IN_BG2] = toBG_2;
gTasks[taskId].data[t1_CREATE_ANOTHER_TASK] = TRUE;
gTasks[taskId].data[t1_IS_SECONDMON_BG] = 0;
}
- bank ^= BIT_FLANK;
- if (IsBattlerSpriteVisible(bank))
+ battlerId ^= BIT_FLANK;
+ if (IsBattlerSpriteVisible(battlerId))
{
- u8 position = GetBattlerPosition(bank);
+ u8 position = GetBattlerPosition(battlerId);
if (position == B_POSITION_OPPONENT_LEFT || position == B_POSITION_PLAYER_RIGHT || IsContest())
toBG_2 = FALSE;
else
toBG_2 = TRUE;
- sub_80A438C(bank, toBG_2, FALSE);
+ sub_80A438C(battlerId, toBG_2, FALSE);
taskId = CreateTask(sub_80A40F4, 10);
gAnimVisualTaskCount++;
- gTasks[taskId].data[0] = bank;
+ gTasks[taskId].data[0] = battlerId;
gTasks[taskId].data[1] = toBG_2;
gTasks[taskId].data[t1_CREATE_ANOTHER_TASK] = TRUE;
gTasks[taskId].data[t1_IS_SECONDMON_BG] = 1;
@@ -647,33 +643,33 @@ static void ScriptCmd_monbg(void)
gAnimScriptCallback = WaitAnimFrameCount;
}
-bool8 IsBattlerSpriteVisible(u8 bank)
+bool8 IsBattlerSpriteVisible(u8 battlerId)
{
if (IsContest())
{
- if (bank == gBattleAnimAttacker)
+ if (battlerId == gBattleAnimAttacker)
return TRUE;
else
return FALSE;
}
- if (!IsBattlerSpritePresent(bank))
+ if (!IsBattlerSpritePresent(battlerId))
return FALSE;
if (IsContest())
return TRUE; // this line wont ever be reached.
- if (!gBattleSpritesDataPtr->battlerData[bank].invisible || !gSprites[gBattlerSpriteIds[bank]].invisible)
+ if (!gBattleSpritesDataPtr->battlerData[battlerId].invisible || !gSprites[gBattlerSpriteIds[battlerId]].invisible)
return TRUE;
return FALSE;
}
-void sub_80A438C(u8 bank, bool8 toBG_2, bool8 setSpriteInvisible)
+void sub_80A438C(u8 battlerId, bool8 toBG_2, bool8 setSpriteInvisible)
{
struct UnknownAnimStruct2 unknownStruct;
- u8 bankSpriteId;
+ u8 battlerSpriteId;
if (!toBG_2)
{
- u8 bankIdentity;
+ u8 battlerPosition;
if (IsContest() == TRUE)
{
@@ -694,28 +690,28 @@ void sub_80A438C(u8 bank, bool8 toBG_2, bool8 setSpriteInvisible)
SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 1);
SetAnimBgAttribute(1, BG_ANIM_AREA_OVERFLOW_MODE, 0);
- bankSpriteId = gBattlerSpriteIds[bank];
+ battlerSpriteId = gBattlerSpriteIds[battlerId];
- gBattle_BG1_X = -(gSprites[bankSpriteId].pos1.x + gSprites[bankSpriteId].pos2.x) + 0x20;
+ gBattle_BG1_X = -(gSprites[battlerSpriteId].pos1.x + gSprites[battlerSpriteId].pos2.x) + 0x20;
if (IsContest() && IsSpeciesNotUnown(gContestResources->field_18->field_0))
gBattle_BG1_X--;
- gBattle_BG1_Y = -(gSprites[bankSpriteId].pos1.y + gSprites[bankSpriteId].pos2.y) + 0x20;
+ gBattle_BG1_Y = -(gSprites[battlerSpriteId].pos1.y + gSprites[battlerSpriteId].pos2.y) + 0x20;
if (setSpriteInvisible)
- gSprites[gBattlerSpriteIds[bank]].invisible = 1;
+ gSprites[gBattlerSpriteIds[battlerId]].invisible = 1;
SetGpuReg(REG_OFFSET_BG1HOFS, gBattle_BG1_X);
SetGpuReg(REG_OFFSET_BG1VOFS, gBattle_BG1_Y);
- LoadPalette(&gPlttBufferUnfaded[0x100 + bank * 16], unknownStruct.unk8 * 16, 0x20);
- CpuCopy32(&gPlttBufferUnfaded[0x100 + bank * 16], (void*)(BG_PLTT + unknownStruct.unk8 * 32), 0x20);
+ LoadPalette(&gPlttBufferUnfaded[0x100 + battlerId * 16], unknownStruct.unk8 * 16, 0x20);
+ CpuCopy32(&gPlttBufferUnfaded[0x100 + battlerId * 16], (void*)(BG_PLTT + unknownStruct.unk8 * 32), 0x20);
if (IsContest())
- bankIdentity = 0;
+ battlerPosition = 0;
else
- bankIdentity = GetBattlerPosition(bank);
+ battlerPosition = GetBattlerPosition(battlerId);
- sub_8118FBC(1, 0, 0, bankIdentity, unknownStruct.unk8, unknownStruct.unk0, unknownStruct.unk4, unknownStruct.unkA);
+ sub_8118FBC(1, 0, 0, battlerPosition, unknownStruct.unk8, unknownStruct.unk0, unknownStruct.unk4, unknownStruct.unkA);
if (IsContest())
sub_80A46A0();
@@ -731,21 +727,21 @@ void sub_80A438C(u8 bank, bool8 toBG_2, bool8 setSpriteInvisible)
SetAnimBgAttribute(2, BG_ANIM_SCREEN_SIZE, 1);
SetAnimBgAttribute(2, BG_ANIM_AREA_OVERFLOW_MODE, 0);
- bankSpriteId = gBattlerSpriteIds[bank];
+ battlerSpriteId = gBattlerSpriteIds[battlerId];
- gBattle_BG2_X = -(gSprites[bankSpriteId].pos1.x + gSprites[bankSpriteId].pos2.x) + 0x20;
- gBattle_BG2_Y = -(gSprites[bankSpriteId].pos1.y + gSprites[bankSpriteId].pos2.y) + 0x20;
+ gBattle_BG2_X = -(gSprites[battlerSpriteId].pos1.x + gSprites[battlerSpriteId].pos2.x) + 0x20;
+ gBattle_BG2_Y = -(gSprites[battlerSpriteId].pos1.y + gSprites[battlerSpriteId].pos2.y) + 0x20;
if (setSpriteInvisible)
- gSprites[gBattlerSpriteIds[bank]].invisible = 1;
+ gSprites[gBattlerSpriteIds[battlerId]].invisible = 1;
SetGpuReg(REG_OFFSET_BG2HOFS, gBattle_BG2_X);
SetGpuReg(REG_OFFSET_BG2VOFS, gBattle_BG2_Y);
- LoadPalette(&gPlttBufferUnfaded[0x100 + bank * 16], 0x90, 0x20);
- CpuCopy32(&gPlttBufferUnfaded[0x100 + bank * 16], (void*)(BG_PLTT + 0x120), 0x20);
+ LoadPalette(&gPlttBufferUnfaded[0x100 + battlerId * 16], 0x90, 0x20);
+ CpuCopy32(&gPlttBufferUnfaded[0x100 + battlerId * 16], (void*)(BG_PLTT + 0x120), 0x20);
- sub_8118FBC(2, 0, 0, GetBattlerPosition(bank), unknownStruct.unk8, unknownStruct.unk0 + 0x1000, unknownStruct.unk4 + 0x400, unknownStruct.unkA);
+ sub_8118FBC(2, 0, 0, GetBattlerPosition(battlerId), unknownStruct.unk8, unknownStruct.unk0 + 0x1000, unknownStruct.unk4 + 0x400, unknownStruct.unkA);
}
}
@@ -852,7 +848,7 @@ static void task_pA_ma0A_obj_to_bg_pal(u8 taskId)
static void ScriptCmd_clearmonbg(void)
{
u8 animBankId;
- u8 bank;
+ u8 battlerId;
u8 taskId;
sBattleAnimScriptPtr++;
@@ -864,20 +860,20 @@ static void ScriptCmd_clearmonbg(void)
animBankId = ANIM_DEF_PARTNER;
if (animBankId == ANIM_ATTACKER || animBankId == ANIM_ATK_PARTNER)
- bank = gBattleAnimAttacker;
+ battlerId = gBattleAnimAttacker;
else
- bank = gBattleAnimTarget;
+ battlerId = gBattleAnimTarget;
if (sMonAnimTaskIdArray[0] != 0xFF)
- gSprites[gBattlerSpriteIds[bank]].invisible = 0;
+ gSprites[gBattlerSpriteIds[battlerId]].invisible = 0;
if (animBankId > 1 && sMonAnimTaskIdArray[1] != 0xFF)
- gSprites[gBattlerSpriteIds[bank ^ BIT_FLANK]].invisible = 0;
+ gSprites[gBattlerSpriteIds[battlerId ^ BIT_FLANK]].invisible = 0;
else
animBankId = 0;
taskId = CreateTask(sub_80A4980, 5);
gTasks[taskId].data[0] = animBankId;
- gTasks[taskId].data[2] = bank;
+ gTasks[taskId].data[2] = battlerId;
sBattleAnimScriptPtr++;
}
@@ -913,7 +909,7 @@ static void sub_80A4980(u8 taskId)
static void ScriptCmd_monbg_22(void)
{
bool8 toBG_2;
- u8 bank;
+ u8 battlerId;
u8 animBankId;
sBattleAnimScriptPtr++;
@@ -926,31 +922,31 @@ static void ScriptCmd_monbg_22(void)
animBankId = ANIM_DEF_PARTNER;
if (animBankId == ANIM_ATTACKER || animBankId == ANIM_ATK_PARTNER)
- bank = gBattleAnimAttacker;
+ battlerId = gBattleAnimAttacker;
else
- bank = gBattleAnimTarget;
+ battlerId = gBattleAnimTarget;
- if (IsBattlerSpriteVisible(bank))
+ if (IsBattlerSpriteVisible(battlerId))
{
- u8 position = GetBattlerPosition(bank);
+ u8 position = GetBattlerPosition(battlerId);
if (position == B_POSITION_OPPONENT_LEFT || position == B_POSITION_PLAYER_RIGHT || IsContest())
toBG_2 = FALSE;
else
toBG_2 = TRUE;
- sub_80A438C(bank, toBG_2, FALSE);
+ sub_80A438C(battlerId, toBG_2, FALSE);
}
- bank ^= BIT_FLANK;
- if (animBankId > 1 && IsBattlerSpriteVisible(bank))
+ battlerId ^= BIT_FLANK;
+ if (animBankId > 1 && IsBattlerSpriteVisible(battlerId))
{
- u8 position = GetBattlerPosition(bank);
+ u8 position = GetBattlerPosition(battlerId);
if (position == B_POSITION_OPPONENT_LEFT || position == B_POSITION_PLAYER_RIGHT || IsContest())
toBG_2 = FALSE;
else
toBG_2 = TRUE;
- sub_80A438C(bank, toBG_2, FALSE);
+ sub_80A438C(battlerId, toBG_2, FALSE);
}
sBattleAnimScriptPtr++;
@@ -959,7 +955,7 @@ static void ScriptCmd_monbg_22(void)
static void ScriptCmd_clearmonbg_23(void)
{
u8 animBankId;
- u8 bank;
+ u8 battlerId;
u8 taskId;
sBattleAnimScriptPtr++;
@@ -971,20 +967,20 @@ static void ScriptCmd_clearmonbg_23(void)
animBankId = ANIM_DEF_PARTNER;
if (animBankId == ANIM_ATTACKER || animBankId == ANIM_ATK_PARTNER)
- bank = gBattleAnimAttacker;
+ battlerId = gBattleAnimAttacker;
else
- bank = gBattleAnimTarget;
+ battlerId = gBattleAnimTarget;
- if (IsBattlerSpriteVisible(bank))
- gSprites[gBattlerSpriteIds[bank]].invisible = 0;
- if (animBankId > 1 && IsBattlerSpriteVisible(bank ^ BIT_FLANK))
- gSprites[gBattlerSpriteIds[bank ^ BIT_FLANK]].invisible = 0;
+ if (IsBattlerSpriteVisible(battlerId))
+ gSprites[gBattlerSpriteIds[battlerId]].invisible = 0;
+ if (animBankId > 1 && IsBattlerSpriteVisible(battlerId ^ BIT_FLANK))
+ gSprites[gBattlerSpriteIds[battlerId ^ BIT_FLANK]].invisible = 0;
else
animBankId = 0;
taskId = CreateTask(sub_80A4BB0, 5);
gTasks[taskId].data[0] = animBankId;
- gTasks[taskId].data[2] = bank;
+ gTasks[taskId].data[2] = battlerId;
sBattleAnimScriptPtr++;
}
@@ -995,30 +991,30 @@ static void sub_80A4BB0(u8 taskId)
if (gTasks[taskId].data[1] != 1)
{
bool8 toBG_2;
- u8 bank = gTasks[taskId].data[2];
- u8 position = GetBattlerPosition(bank);
+ u8 battlerId = gTasks[taskId].data[2];
+ u8 position = GetBattlerPosition(battlerId);
if (position == B_POSITION_OPPONENT_LEFT || position == B_POSITION_PLAYER_RIGHT || IsContest())
toBG_2 = FALSE;
else
toBG_2 = TRUE;
- if (IsBattlerSpriteVisible(bank))
+ if (IsBattlerSpriteVisible(battlerId))
sub_80A477C(toBG_2);
- if (gTasks[taskId].data[0] > 1 && IsBattlerSpriteVisible(bank ^ BIT_FLANK))
+ if (gTasks[taskId].data[0] > 1 && IsBattlerSpriteVisible(battlerId ^ BIT_FLANK))
sub_80A477C(toBG_2 ^ 1);
DestroyTask(taskId);
}
}
-#undef t1_MONBG_BANK
+#undef t1_MONBG_BATTLER
#undef t1_MON_IN_BG2
#undef t1_CREATE_ANOTHER_TASK
#undef t1_IS_SECONDMON_BG
-#undef t2_BANK_SPRITE_ID
+#undef t2_BATTLER_SPRITE_ID
#undef t2_MON_IN_BG2
-#undef t2_MONBG_BANK
+#undef t2_MONBG_BATTLER
static void ScriptCmd_setalpha(void)
{
@@ -1052,7 +1048,7 @@ static void ScriptCmd_call(void)
{
sBattleAnimScriptPtr++;
sBattleAnimScriptRetAddr = sBattleAnimScriptPtr + 4;
- sBattleAnimScriptPtr = SCRIPT_READ_PTR(sBattleAnimScriptPtr);
+ sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr);
}
static void ScriptCmd_return(void)
@@ -1069,7 +1065,7 @@ static void ScriptCmd_setarg(void)
sBattleAnimScriptPtr++;
argId = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
- value = SCRIPT_READ_16(sBattleAnimScriptPtr);
+ value = T1_READ_16(sBattleAnimScriptPtr);
sBattleAnimScriptPtr = addr + 4;
gBattleAnimArgs[argId] = value;
}
@@ -1079,7 +1075,7 @@ static void ScriptCmd_choosetwoturnanim(void)
sBattleAnimScriptPtr++;
if (gAnimMoveTurn & 1)
sBattleAnimScriptPtr += 4;
- sBattleAnimScriptPtr = SCRIPT_READ_PTR(sBattleAnimScriptPtr);
+ sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr);
}
static void ScriptCmd_jumpifmoveturn(void)
@@ -1090,7 +1086,7 @@ static void ScriptCmd_jumpifmoveturn(void)
sBattleAnimScriptPtr++;
if (toCheck == gAnimMoveTurn)
- sBattleAnimScriptPtr = SCRIPT_READ_PTR(sBattleAnimScriptPtr);
+ sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr);
else
sBattleAnimScriptPtr += 4;
}
@@ -1098,7 +1094,7 @@ static void ScriptCmd_jumpifmoveturn(void)
static void ScriptCmd_goto(void)
{
sBattleAnimScriptPtr++;
- sBattleAnimScriptPtr = SCRIPT_READ_PTR(sBattleAnimScriptPtr);
+ sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr);
}
// Uses of this function that rely on a TRUE return are expecting inBattle to not be ticked as defined in contest behavior. As a result, if misused, this function cannot reliably discern between field and contest status and could result in undefined behavior.
@@ -1322,16 +1318,16 @@ s8 BattleAnimAdjustPanning2(s8 pan)
return pan;
}
-s16 sub_80A52EC(s16 a)
+s16 KeepPanInRange(s16 panArg)
{
- s16 var = a;
+ s16 pan = panArg;
- if (var > 63)
- var = 63;
- else if (var < -64)
- var = -64;
+ if (pan > PAN_SIDE_OPPONENT)
+ pan = PAN_SIDE_OPPONENT;
+ else if (pan < PAN_SIDE_PLAYER)
+ pan = PAN_SIDE_PLAYER;
- return var;
+ return pan;
}
s16 CalculatePanIncrement(s16 sourcePan, s16 targetPan, s16 incrementPan)
@@ -1354,7 +1350,7 @@ static void ScriptCmd_playsewithpan(void)
s8 pan;
sBattleAnimScriptPtr++;
- songId = SCRIPT_READ_16(sBattleAnimScriptPtr);
+ songId = T1_READ_16(sBattleAnimScriptPtr);
pan = sBattleAnimScriptPtr[2];
PlaySE12WithPanning(songId, BattleAnimAdjustPanning(pan));
sBattleAnimScriptPtr += 3;
@@ -1385,7 +1381,7 @@ static void ScriptCmd_panse_1B(void)
u8 taskId;
sBattleAnimScriptPtr++;
- songNum = SCRIPT_READ_16(sBattleAnimScriptPtr);
+ songNum = T1_READ_16(sBattleAnimScriptPtr);
currentPanArg = sBattleAnimScriptPtr[2];
incrementPan = sBattleAnimScriptPtr[3];
incrementPanArg = sBattleAnimScriptPtr[4];
@@ -1457,7 +1453,7 @@ static void ScriptCmd_panse_26(void)
u8 taskId;
sBattleAnimScriptPtr++;
- songId = SCRIPT_READ_16(sBattleAnimScriptPtr);
+ songId = T1_READ_16(sBattleAnimScriptPtr);
currentPan = sBattleAnimScriptPtr[2];
targetPan = sBattleAnimScriptPtr[3];
incrementPan = sBattleAnimScriptPtr[4];
@@ -1484,7 +1480,7 @@ static void ScriptCmd_panse_27(void)
u8 taskId;
sBattleAnimScriptPtr++;
- songId = SCRIPT_READ_16(sBattleAnimScriptPtr);
+ songId = T1_READ_16(sBattleAnimScriptPtr);
currentPanArg = sBattleAnimScriptPtr[2];
targetPanArg = sBattleAnimScriptPtr[3];
incrementPanArg = sBattleAnimScriptPtr[4];
@@ -1528,7 +1524,7 @@ static void ScriptCmd_loopsewithpan(void)
u8 taskId;
sBattleAnimScriptPtr++;
- songId = SCRIPT_READ_16(sBattleAnimScriptPtr);
+ songId = T1_READ_16(sBattleAnimScriptPtr);
panningArg = sBattleAnimScriptPtr[2];
framesToWait = sBattleAnimScriptPtr[3];
numberOfPlays = sBattleAnimScriptPtr[4];
@@ -1585,7 +1581,7 @@ static void ScriptCmd_waitplaysewithpan(void)
u8 taskId;
sBattleAnimScriptPtr++;
- songId = SCRIPT_READ_16(sBattleAnimScriptPtr);
+ songId = T1_READ_16(sBattleAnimScriptPtr);
panningArg = sBattleAnimScriptPtr[2];
framesToWait = sBattleAnimScriptPtr[3];
panning = BattleAnimAdjustPanning(panningArg);
@@ -1620,13 +1616,13 @@ static void ScriptCmd_createsoundtask(void)
s32 i;
sBattleAnimScriptPtr++;
- func = (TaskFunc)SCRIPT_READ_32(sBattleAnimScriptPtr);
+ func = (TaskFunc)T2_READ_32(sBattleAnimScriptPtr);
sBattleAnimScriptPtr += 4;
numArgs = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
for (i = 0; i < numArgs; i++)
{
- gBattleAnimArgs[i] = SCRIPT_READ_16(sBattleAnimScriptPtr);
+ gBattleAnimArgs[i] = T1_READ_16(sBattleAnimScriptPtr);
sBattleAnimScriptPtr += 2;
}
taskId = CreateTask(func, 1);
@@ -1669,10 +1665,10 @@ static void ScriptCmd_jumpargeq(void)
sBattleAnimScriptPtr++;
argId = sBattleAnimScriptPtr[0];
- valueToCheck = SCRIPT_READ_16(sBattleAnimScriptPtr + 1);
+ valueToCheck = T1_READ_16(sBattleAnimScriptPtr + 1);
if (valueToCheck == gBattleAnimArgs[argId])
- sBattleAnimScriptPtr = SCRIPT_READ_PTR(sBattleAnimScriptPtr + 3);
+ sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr + 3);
else
sBattleAnimScriptPtr += 7;
}
@@ -1681,7 +1677,7 @@ static void ScriptCmd_jumpifcontest(void)
{
sBattleAnimScriptPtr++;
if (IsContest())
- sBattleAnimScriptPtr = SCRIPT_READ_PTR(sBattleAnimScriptPtr);
+ sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr);
else
sBattleAnimScriptPtr += 4;
}
@@ -1689,19 +1685,19 @@ static void ScriptCmd_jumpifcontest(void)
static void ScriptCmd_monbgprio_28(void)
{
u8 wantedBank;
- u8 bank;
- u8 bankIdentity;
+ u8 battlerId;
+ u8 battlerPosition;
wantedBank = sBattleAnimScriptPtr[1];
sBattleAnimScriptPtr += 2;
if (wantedBank != ANIM_ATTACKER)
- bank = gBattleAnimTarget;
+ battlerId = gBattleAnimTarget;
else
- bank = gBattleAnimAttacker;
+ battlerId = gBattleAnimAttacker;
- bankIdentity = GetBattlerPosition(bank);
- if (!IsContest() && (bankIdentity == B_POSITION_PLAYER_LEFT || bankIdentity == B_POSITION_OPPONENT_RIGHT))
+ battlerPosition = GetBattlerPosition(battlerId);
+ if (!IsContest() && (battlerPosition == B_POSITION_PLAYER_LEFT || battlerPosition == B_POSITION_OPPONENT_RIGHT))
{
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
SetAnimBgAttribute(2, BG_ANIM_PRIORITY, 2);
@@ -1721,20 +1717,20 @@ static void ScriptCmd_monbgprio_29(void)
static void ScriptCmd_monbgprio_2A(void)
{
u8 wantedBank;
- u8 bankIdentity;
- u8 bank;
+ u8 battlerPosition;
+ u8 battlerId;
wantedBank = sBattleAnimScriptPtr[1];
sBattleAnimScriptPtr += 2;
if (GetBattlerSide(gBattleAnimAttacker) != GetBattlerSide(gBattleAnimTarget))
{
if (wantedBank != ANIM_ATTACKER)
- bank = gBattleAnimTarget;
+ battlerId = gBattleAnimTarget;
else
- bank = gBattleAnimAttacker;
+ battlerId = gBattleAnimAttacker;
- bankIdentity = GetBattlerPosition(bank);
- if (!IsContest() && (bankIdentity == B_POSITION_PLAYER_LEFT || bankIdentity == B_POSITION_OPPONENT_RIGHT))
+ battlerPosition = GetBattlerPosition(battlerId);
+ if (!IsContest() && (battlerPosition == B_POSITION_PLAYER_LEFT || battlerPosition == B_POSITION_OPPONENT_RIGHT))
{
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
SetAnimBgAttribute(2, BG_ANIM_PRIORITY, 2);
diff --git a/src/battle_anim_sound_tasks.c b/src/battle_anim_sound_tasks.c
new file mode 100644
index 000000000..2316b9759
--- /dev/null
+++ b/src/battle_anim_sound_tasks.c
@@ -0,0 +1,438 @@
+#include "global.h"
+#include "battle.h"
+#include "constants/battle_anim.h"
+#include "constants/species.h"
+#include "battle_anim.h"
+#include "task.h"
+#include "sound.h"
+#include "contest.h"
+
+// this file's functions
+static void sub_8158B98(u8 taskId);
+static void sub_8158C04(u8 taskId);
+static void sub_8158D08(u8 taskId);
+static void sub_8158FF4(u8 taskId);
+static void sub_815913C(u8 taskId);
+static void sub_8159308(u8 taskId);
+
+// task start
+void sub_8158B30(u8 taskId)
+{
+ s8 pan1, pan2, panIncrement;
+
+ gTasks[taskId].data[0] = gBattleAnimArgs[0];
+ gTasks[taskId].data[1] = gBattleAnimArgs[1];
+
+ pan1 = BattleAnimAdjustPanning(PAN_SIDE_PLAYER);
+ pan2 = BattleAnimAdjustPanning(PAN_SIDE_OPPONENT);
+ panIncrement = CalculatePanIncrement(pan1, pan2, 2);
+
+ gTasks[taskId].data[2] = pan1;
+ gTasks[taskId].data[3] = pan2;
+ gTasks[taskId].data[4] = panIncrement;
+ gTasks[taskId].data[10] = 10;
+
+ gTasks[taskId].func = sub_8158B98;
+}
+
+static void sub_8158B98(u8 taskId)
+{
+ s16 pan = gTasks[taskId].data[2];
+ s8 panIncrement = gTasks[taskId].data[4];
+ if (++gTasks[taskId].data[11] == 111)
+ {
+ gTasks[taskId].data[10] = 5;
+ gTasks[taskId].data[11] = 0;
+ gTasks[taskId].func = sub_8158C04;
+ }
+ else
+ {
+ if (++gTasks[taskId].data[10] == 11)
+ {
+ gTasks[taskId].data[10] = 0;
+ PlaySE12WithPanning(gTasks[taskId].data[0], pan);
+ }
+ pan += panIncrement;
+ gTasks[taskId].data[2] = KeepPanInRange(pan);
+ }
+}
+
+static void sub_8158C04(u8 taskId)
+{
+ if (++gTasks[taskId].data[10] == 6)
+ {
+ s8 pan;
+
+ gTasks[taskId].data[10] = 0;
+ pan = BattleAnimAdjustPanning(PAN_SIDE_OPPONENT);
+ PlaySE12WithPanning(gTasks[taskId].data[1], pan);
+ if (++gTasks[taskId].data[11] == 2)
+ DestroyAnimSoundTask(taskId);
+ }
+}
+// task end
+
+// task start
+void sub_8158C58(u8 taskId)
+{
+ u16 songId = gBattleAnimArgs[0];
+ s8 targetPan = gBattleAnimArgs[2];
+ s8 panIncrement = gBattleAnimArgs[3];
+ u8 r10 = gBattleAnimArgs[4];
+ u8 r7 = gBattleAnimArgs[5];
+ u8 r9 = gBattleAnimArgs[6];
+ s8 sourcePan = BattleAnimAdjustPanning(gBattleAnimArgs[1]);
+
+ targetPan = BattleAnimAdjustPanning(targetPan);
+ panIncrement = CalculatePanIncrement(sourcePan, targetPan, panIncrement);
+
+ gTasks[taskId].data[0] = songId;
+ gTasks[taskId].data[1] = sourcePan;
+ gTasks[taskId].data[2] = targetPan;
+ gTasks[taskId].data[3] = panIncrement;
+ gTasks[taskId].data[4] = r10;
+ gTasks[taskId].data[5] = r7;
+ gTasks[taskId].data[6] = r9;
+ gTasks[taskId].data[10] = 0;
+ gTasks[taskId].data[11] = sourcePan;
+ gTasks[taskId].data[12] = r9;
+
+ gTasks[taskId].func = sub_8158D08;
+ sub_8158D08(taskId);
+}
+
+static void sub_8158D08(u8 taskId)
+{
+ if (gTasks[taskId].data[12]++ == gTasks[taskId].data[6])
+ {
+ gTasks[taskId].data[12] = 0;
+ PlaySE12WithPanning(gTasks[taskId].data[0], gTasks[taskId].data[11]);
+ if (--gTasks[taskId].data[4] == 0)
+ {
+ DestroyAnimSoundTask(taskId);
+ return;
+ }
+ }
+
+ if (gTasks[taskId].data[10]++ == gTasks[taskId].data[5])
+ {
+ gTasks[taskId].data[10] = 0;
+ gTasks[taskId].data[11] += gTasks[taskId].data[3];
+ gTasks[taskId].data[11] = KeepPanInRange(gTasks[taskId].data[11]);
+ }
+}
+// task end
+
+// task start
+void sub_8158D8C(u8 taskId)
+{
+ u16 species = 0;
+ s8 pan = BattleAnimAdjustPanning(PAN_SIDE_PLAYER);
+ if (IsContest())
+ {
+ if (gBattleAnimArgs[0] == ANIM_ATTACKER)
+ species = gContestResources->field_18->field_0;
+ else
+ DestroyAnimVisualTask(taskId); // UB: function should return upon destroying task
+ }
+ else
+ {
+ u8 battlerId;
+
+ // get wanted battler
+ if (gBattleAnimArgs[0] == ANIM_ATTACKER)
+ battlerId = gBattleAnimAttacker;
+ else if (gBattleAnimArgs[0] == ANIM_TARGET)
+ battlerId = gBattleAnimTarget;
+ else if (gBattleAnimArgs[0] == ANIM_ATK_PARTNER)
+ battlerId = BATTLE_PARTNER(gBattleAnimAttacker);
+ else
+ battlerId = BATTLE_PARTNER(gBattleAnimTarget);
+
+ // check if battler is visible
+ if ((gBattleAnimArgs[0] == ANIM_TARGET || gBattleAnimArgs[0] == ANIM_DEF_PARTNER) && !IsBattlerSpriteVisible(battlerId))
+ {
+ DestroyAnimVisualTask(taskId);
+ return;
+ }
+
+ if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
+ species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
+ else
+ species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
+ }
+
+ if (species != SPECIES_NONE)
+ PlayCry3(species, pan, 3);
+
+ DestroyAnimVisualTask(taskId);
+}
+// task end
+
+// task start
+void sub_8158E9C(u8 taskId)
+{
+ u16 species = 0;
+ s8 pan = BattleAnimAdjustPanning(PAN_SIDE_PLAYER);
+ if (IsContest())
+ {
+ if (gBattleAnimArgs[0] == ANIM_ATTACKER)
+ species = gContestResources->field_18->field_0;
+ else
+ DestroyAnimVisualTask(taskId); // UB: function should return upon destroying task
+ }
+ else
+ {
+ u8 battlerId;
+
+ // get wanted battler
+ if (gBattleAnimArgs[0] == ANIM_ATTACKER)
+ battlerId = gBattleAnimAttacker;
+ else if (gBattleAnimArgs[0] == ANIM_TARGET)
+ battlerId = gBattleAnimTarget;
+ else if (gBattleAnimArgs[0] == ANIM_ATK_PARTNER)
+ battlerId = BATTLE_PARTNER(gBattleAnimAttacker);
+ else
+ battlerId = BATTLE_PARTNER(gBattleAnimTarget);
+
+ // check if battler is visible
+ if ((gBattleAnimArgs[0] == ANIM_TARGET || gBattleAnimArgs[0] == ANIM_DEF_PARTNER) && !IsBattlerSpriteVisible(battlerId))
+ {
+ DestroyAnimVisualTask(taskId);
+ return;
+ }
+
+ if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
+ species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
+ else
+ species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
+ }
+
+ gTasks[taskId].data[0] = gBattleAnimArgs[1];
+ gTasks[taskId].data[1] = species;
+ gTasks[taskId].data[2] = pan;
+
+ if (species != SPECIES_NONE)
+ {
+ if (gBattleAnimArgs[1] == 0xFF)
+ PlayCry3(species, pan, 9);
+ else
+ PlayCry3(species, pan, 7);
+
+ gTasks[taskId].func = sub_8158FF4;
+ }
+ else
+ {
+ DestroyAnimVisualTask(taskId);
+ }
+}
+
+static void sub_8158FF4(u8 taskId)
+{
+ u16 species = gTasks[taskId].data[1];
+ s8 pan = gTasks[taskId].data[2];
+
+ if (gTasks[taskId].data[9] < 2)
+ {
+ gTasks[taskId].data[9]++;
+ }
+ else
+ {
+ if (gTasks[taskId].data[0] == 0xFF)
+ {
+ if (!IsCryPlaying())
+ {
+ PlayCry3(species, pan, 10);
+ DestroyAnimVisualTask(taskId);
+ }
+ }
+ else
+ {
+ if (!IsCryPlaying())
+ {
+ PlayCry3(species, pan, 8);
+ DestroyAnimVisualTask(taskId);
+ }
+ }
+ }
+}
+// task end
+
+void sub_8159078(u8 taskId)
+{
+ if (gTasks[taskId].data[9] < 2)
+ {
+ gTasks[taskId].data[9]++;
+ }
+ else
+ {
+ if (!IsCryPlaying())
+ DestroyAnimVisualTask(taskId);
+ }
+}
+
+// task start
+void sub_81590B8(u8 taskId)
+{
+ u16 species;
+ s8 pan;
+
+ gTasks[taskId].data[10] = gBattleAnimArgs[0];
+ pan = BattleAnimAdjustPanning(PAN_SIDE_PLAYER);
+
+ if (IsContest())
+ species = gContestResources->field_18->field_0;
+ else
+ species = gAnimBattlerSpecies[gBattleAnimAttacker];
+
+ gTasks[taskId].data[1] = species;
+ gTasks[taskId].data[2] = pan;
+
+ if (species != SPECIES_NONE)
+ gTasks[taskId].func = sub_815913C;
+ else
+ DestroyAnimVisualTask(taskId);
+}
+
+static void sub_815913C(u8 taskId)
+{
+ u16 species = gTasks[taskId].data[1];
+ s8 pan = gTasks[taskId].data[2];
+
+ switch (gTasks[taskId].data[9])
+ {
+ case 2:
+ PlayCry6(species, pan, 4);
+ gTasks[taskId].data[9]++;
+ break;
+ case 1:
+ case 3:
+ case 4:
+ gTasks[taskId].data[9]++;
+ break;
+ case 5:
+ if (IsCryPlaying())
+ break;
+ case 0:
+ StopCryAndClearCrySongs();
+ gTasks[taskId].data[9]++;
+ break;
+ default:
+ if (gTasks[taskId].data[10] == 0)
+ PlayCry6(species, pan, 6);
+ else
+ PlayCry3(species, pan, 6);
+
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+// task end
+
+void sub_8159210(u8 taskId)
+{
+ u16 songId = gBattleAnimArgs[0];
+ s8 pan = BattleAnimAdjustPanning(gBattleAnimArgs[1]);
+
+ PlaySE1WithPanning(songId, pan);
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_8159244(u8 taskId)
+{
+ u16 songId = gBattleAnimArgs[0];
+ s8 pan = BattleAnimAdjustPanning(gBattleAnimArgs[1]);
+
+ PlaySE2WithPanning(songId, pan);
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_8159278(u8 taskId)
+{
+ s8 targetPan = gBattleAnimArgs[1];
+ s8 panIncrement = gBattleAnimArgs[2];
+ u16 r9 = gBattleAnimArgs[3];
+ s8 sourcePan = BattleAnimAdjustPanning(gBattleAnimArgs[0]);
+
+ targetPan = BattleAnimAdjustPanning(targetPan);
+ panIncrement = CalculatePanIncrement(sourcePan, targetPan, panIncrement);
+
+ gTasks[taskId].data[1] = sourcePan;
+ gTasks[taskId].data[2] = targetPan;
+ gTasks[taskId].data[3] = panIncrement;
+ gTasks[taskId].data[5] = r9;
+ gTasks[taskId].data[10] = 0;
+ gTasks[taskId].data[11] = sourcePan;
+
+ gTasks[taskId].func = sub_8159308;
+ sub_8159308(taskId);
+}
+
+#ifdef NONMATCHING
+void sub_8159308(u8 taskId)
+{
+ s16 panIncrement = gTasks[taskId].data[3];
+
+ if (gTasks[taskId].data[10]++ == gTasks[taskId].data[5])
+ {
+ gTasks[taskId].data[10] = 0;
+
+ gTasks[taskId].data[11] += panIncrement;
+ gTasks[taskId].data[11] = KeepPanInRange(gTasks[taskId].data[11]);
+ }
+
+ gUnknown_02038440 = gTasks[taskId].data[11];
+ if (gTasks[taskId].data[11] == gTasks[taskId].data[2])
+ DestroyAnimVisualTask(taskId);
+}
+#else
+NAKED
+void sub_8159308(u8 taskId)
+{
+ asm_unified(" push {r4,r5,lr}\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ adds r5, r0, 0\n\
+ ldr r1, =gTasks\n\
+ lsls r0, r5, 2\n\
+ adds r0, r5\n\
+ lsls r0, 3\n\
+ adds r4, r0, r1\n\
+ ldrh r2, [r4, 0xE]\n\
+ ldrh r0, [r4, 0x1C]\n\
+ adds r1, r0, 0x1\n\
+ strh r1, [r4, 0x1C]\n\
+ lsls r0, 16\n\
+ asrs r0, 16\n\
+ movs r3, 0x12\n\
+ ldrsh r1, [r4, r3]\n\
+ cmp r0, r1\n\
+ bne _08159342\n\
+ movs r0, 0\n\
+ strh r0, [r4, 0x1C]\n\
+ ldrh r1, [r4, 0x1E]\n\
+ adds r0, r2, r1\n\
+ strh r0, [r4, 0x1E]\n\
+ movs r2, 0x1E\n\
+ ldrsh r0, [r4, r2]\n\
+ bl KeepPanInRange\n\
+ strh r0, [r4, 0x1E]\n\
+_08159342:\n\
+ ldr r1, =gUnknown_02038440\n\
+ ldrh r0, [r4, 0x1E]\n\
+ strb r0, [r1]\n\
+ movs r3, 0x1E\n\
+ ldrsh r1, [r4, r3]\n\
+ movs r2, 0xC\n\
+ ldrsh r0, [r4, r2]\n\
+ cmp r1, r0\n\
+ bne _0815935A\n\
+ adds r0, r5, 0\n\
+ bl DestroyAnimVisualTask\n\
+_0815935A:\n\
+ pop {r4,r5}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .pool");
+}
+#endif
diff --git a/src/battle_bg.c b/src/battle_bg.c
index f493bafea..d4bfd297a 100644
--- a/src/battle_bg.c
+++ b/src/battle_bg.c
@@ -14,7 +14,6 @@
#include "trig.h"
#include "sound.h"
#include "constants/songs.h"
-#include "strings.h"
#include "window.h"
#include "text_window.h"
#include "menu.h"
diff --git a/src/battle_controller_link_opponent.c b/src/battle_controller_link_opponent.c
index 290236f4a..a4aac55e2 100644
--- a/src/battle_controller_link_opponent.c
+++ b/src/battle_controller_link_opponent.c
@@ -6,7 +6,7 @@
#include "battle_anim.h"
#include "constants/battle_anim.h"
#include "battle_ai_script_commands.h"
-#include "battle_link_817C95C.h"
+#include "battle_tv.h"
#include "pokemon.h"
#include "link.h"
#include "util.h"
@@ -26,17 +26,14 @@
#include "data2.h"
#include "battle_setup.h"
-extern struct SpriteTemplate gUnknown_0202499C;
extern u16 gBattle_BG0_X;
extern u16 gBattle_BG0_Y;
extern struct MusicPlayerInfo gMPlayInfo_BGM;
extern struct UnusedControllerStruct gUnknown_02022D0C;
extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[];
-extern const struct BattleMove gBattleMoves[];
-extern const u8 gFacilityClassToPicIndex[];
-extern void sub_8172EF0(u8 bank, struct Pokemon *mon);
+extern void sub_8172EF0(u8 battlerId, struct Pokemon *mon);
extern void sub_806A068(u16, u8);
extern void sub_81851A8(u8 *);
extern u16 sub_8068B48(void);
@@ -106,7 +103,7 @@ static void LinkOpponentBufferExecCompleted(void);
static void sub_8064DD0(void);
static u32 CopyLinkOpponentMonData(u8 monId, u8 *dst);
static void SetLinkOpponentMonData(u8 monId);
-static void sub_8066494(u8 bank, bool8 dontClearSubstituteBit);
+static void sub_8066494(u8 battlerId, bool8 dontClearSubstituteBit);
static void DoSwitchOutAnimation(void);
static void LinkOpponentDoMoveAnimation(void);
static void sub_8067618(u8 taskId);
@@ -1162,36 +1159,36 @@ static void LinkOpponentHandleSwitchInAnim(void)
gBattlerControllerFuncs[gActiveBattler] = sub_8064F40;
}
-static void sub_8066494(u8 bank, bool8 dontClearSubstituteBit)
+static void sub_8066494(u8 battlerId, bool8 dontClearSubstituteBit)
{
u16 species;
- ClearTemporarySpeciesSpriteData(bank, dontClearSubstituteBit);
- gBattlerPartyIndexes[bank] = gBattleBufferA[bank][1];
- species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[bank]], MON_DATA_SPECIES);
- gUnknown_03005D7C[bank] = CreateInvisibleSpriteWithCallback(sub_805D714);
- BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[bank]], bank);
- sub_806A068(species, GetBattlerPosition(bank));
+ ClearTemporarySpeciesSpriteData(battlerId, dontClearSubstituteBit);
+ gBattlerPartyIndexes[battlerId] = gBattleBufferA[battlerId][1];
+ species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
+ gUnknown_03005D7C[battlerId] = CreateInvisibleSpriteWithCallback(sub_805D714);
+ BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[battlerId]], battlerId);
+ sub_806A068(species, GetBattlerPosition(battlerId));
- gBattlerSpriteIds[bank] = CreateSprite(
+ gBattlerSpriteIds[battlerId] = CreateSprite(
&gUnknown_0202499C,
- GetBattlerSpriteCoord(bank, 2),
- GetBattlerSpriteDefault_Y(bank),
- sub_80A82E4(bank));
+ GetBattlerSpriteCoord(battlerId, 2),
+ GetBattlerSpriteDefault_Y(battlerId),
+ sub_80A82E4(battlerId));
- gSprites[gUnknown_03005D7C[bank]].data[1] = gBattlerSpriteIds[bank];
- gSprites[gUnknown_03005D7C[bank]].data[2] = bank;
+ gSprites[gUnknown_03005D7C[battlerId]].data[1] = gBattlerSpriteIds[battlerId];
+ gSprites[gUnknown_03005D7C[battlerId]].data[2] = battlerId;
- gSprites[gBattlerSpriteIds[bank]].data[0] = bank;
- gSprites[gBattlerSpriteIds[bank]].data[2] = species;
- gSprites[gBattlerSpriteIds[bank]].oam.paletteNum = bank;
+ gSprites[gBattlerSpriteIds[battlerId]].data[0] = battlerId;
+ gSprites[gBattlerSpriteIds[battlerId]].data[2] = species;
+ gSprites[gBattlerSpriteIds[battlerId]].oam.paletteNum = battlerId;
- StartSpriteAnim(&gSprites[gBattlerSpriteIds[bank]], gBattleMonForms[bank]);
+ StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerId]], gBattleMonForms[battlerId]);
- gSprites[gBattlerSpriteIds[bank]].invisible = TRUE;
- gSprites[gBattlerSpriteIds[bank]].callback = SpriteCallbackDummy;
+ gSprites[gBattlerSpriteIds[battlerId]].invisible = TRUE;
+ gSprites[gBattlerSpriteIds[battlerId]].callback = SpriteCallbackDummy;
- gSprites[gUnknown_03005D7C[bank]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_OPPONENT_SENDOUT);
+ gSprites[gUnknown_03005D7C[battlerId]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_OPPONENT_SENDOUT);
}
static void LinkOpponentHandleReturnMonToBall(void)
@@ -1246,7 +1243,7 @@ static void LinkOpponentHandleDrawTrainerPic(void)
if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER)
{
- if (gActiveBattler == 1)
+ if (gActiveBattler == B_POSITION_OPPONENT_LEFT)
trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_A);
else
trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_B);
@@ -1256,18 +1253,18 @@ static void LinkOpponentHandleDrawTrainerPic(void)
if ((gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_FIRE_RED
|| (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_LEAF_GREEN)
{
- if (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].gender != 0)
- trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_10];
+ if (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].gender != MALE)
+ trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_LEAF];
else
- trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_9];
+ trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_RED];
}
else if ((gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_RUBY
|| (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_SAPPHIRE)
{
- if (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].gender != 0)
- trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_12];
+ if (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].gender != MALE)
+ trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_RS_MAY];
else
- trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_11];
+ trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_RS_BRENDAN];
}
else
{
@@ -1286,17 +1283,17 @@ static void LinkOpponentHandleDrawTrainerPic(void)
|| (gLinkPlayers[GetMultiplayerId() ^ BIT_SIDE].version & 0xFF) == VERSION_LEAF_GREEN)
{
if (gLinkPlayers[GetMultiplayerId() ^ BIT_SIDE].gender != 0)
- trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_10];
+ trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_LEAF];
else
- trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_9];
+ trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_RED];
}
else if ((gLinkPlayers[GetMultiplayerId() ^ BIT_SIDE].version & 0xFF) == VERSION_RUBY
|| (gLinkPlayers[GetMultiplayerId() ^ BIT_SIDE].version & 0xFF) == VERSION_SAPPHIRE)
{
if (gLinkPlayers[GetMultiplayerId() ^ BIT_SIDE].gender != 0)
- trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_12];
+ trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_RS_MAY];
else
- trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_11];
+ trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_RS_BRENDAN];
}
else
{
@@ -1340,7 +1337,7 @@ static void LinkOpponentHandleTrainerSlide(void)
gSprites[gBattlerSpriteIds[gActiveBattler]].oam.affineParam = trainerPicId;
gSprites[gBattlerSpriteIds[gActiveBattler]].callback = sub_805D7AC;
- gBattlerControllerFuncs[gActiveBattler] = CompleteOnBankSpriteCallbackDummy2; // this line is redundant, because LinkOpponentBufferExecCompleted changes the battle bank function
+ gBattlerControllerFuncs[gActiveBattler] = CompleteOnBankSpriteCallbackDummy2; // this line is redundant, because LinkOpponentBufferExecCompleted changes the battle battlerId function
LinkOpponentBufferExecCompleted();
}
@@ -1416,7 +1413,7 @@ static void LinkOpponentHandleMoveAnimation(void)
{
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0;
gBattlerControllerFuncs[gActiveBattler] = LinkOpponentDoMoveAnimation;
- sub_817E0FC(move, gWeatherMoveAnim, gAnimDisableStructPtr);
+ BattleTv_SetDataBasedOnMove(move, gWeatherMoveAnim, gAnimDisableStructPtr);
}
}
}
@@ -1480,7 +1477,7 @@ static void LinkOpponentHandlePrintString(void)
BufferStringBattle(*stringId);
BattleHandleAddTextPrinter(gDisplayedStringBattle, 0);
gBattlerControllerFuncs[gActiveBattler] = CompleteOnInactiveTextPrinter;
- sub_817C95C(*stringId);
+ BattleTv_SetDataBasedOnString(*stringId);
}
static void LinkOpponentHandlePrintSelectionString(void)
@@ -1551,11 +1548,11 @@ static void LinkOpponentHandleStatusIconUpdate(void)
{
if (!mplay_80342A4(gActiveBattler))
{
- u8 bank;
+ u8 battlerId;
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_STATUS_ICON);
- bank = gActiveBattler;
- gBattleSpritesDataPtr->healthBoxesData[bank].statusAnimActive = 0;
+ battlerId = gActiveBattler;
+ gBattleSpritesDataPtr->healthBoxesData[battlerId].statusAnimActive = 0;
gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation;
}
}
@@ -1833,7 +1830,7 @@ static void LinkOpponentHandleBattleAnimation(void)
else
gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedBattleAnimation;
- sub_817E32C(animationId);
+ BattleTv_SetDataBasedOnAnimation(animationId);
}
}
diff --git a/src/battle_controller_link_partner.c b/src/battle_controller_link_partner.c
index 9d2c79922..d742d5df2 100644
--- a/src/battle_controller_link_partner.c
+++ b/src/battle_controller_link_partner.c
@@ -6,7 +6,7 @@
#include "battle_anim.h"
#include "constants/battle_anim.h"
#include "battle_ai_script_commands.h"
-#include "battle_link_817C95C.h"
+#include "battle_tv.h"
#include "pokemon.h"
#include "link.h"
#include "util.h"
@@ -25,16 +25,14 @@
#include "data2.h"
#include "battle_setup.h"
-extern struct SpriteTemplate gUnknown_0202499C;
extern u16 gBattle_BG0_X;
extern u16 gBattle_BG0_Y;
extern struct UnusedControllerStruct gUnknown_02022D0C;
extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[];
extern const struct CompressedSpritePalette gTrainerBackPicPaletteTable[];
-extern const struct BattleMove gBattleMoves[];
-extern void sub_8172EF0(u8 bank, struct Pokemon *mon);
+extern void sub_8172EF0(u8 battlerId, struct Pokemon *mon);
extern void sub_806A068(u16, u8);
extern void sub_81851A8(u8 *);
extern u8 GetFrontierTrainerFrontSpriteId(u16 trainerId);
@@ -103,7 +101,7 @@ static void LinkPartnerBufferExecCompleted(void);
static void sub_814B554(void);
static u32 CopyLinkPartnerMonData(u8 monId, u8 *dst);
static void SetLinkPartnerMonData(u8 monId);
-static void sub_814CC98(u8 bank, bool8 dontClearSubstituteBit);
+static void sub_814CC98(u8 battlerId, bool8 dontClearSubstituteBit);
static void DoSwitchOutAnimation(void);
static void LinkPartnerDoMoveAnimation(void);
static void sub_814DCCC(u8 taskId);
@@ -1047,35 +1045,35 @@ static void LinkPartnerHandleSwitchInAnim(void)
gBattlerControllerFuncs[gActiveBattler] = sub_814B69C;
}
-static void sub_814CC98(u8 bank, bool8 dontClearSubstituteBit)
+static void sub_814CC98(u8 battlerId, bool8 dontClearSubstituteBit)
{
u16 species;
- ClearTemporarySpeciesSpriteData(bank, dontClearSubstituteBit);
- gBattlerPartyIndexes[bank] = gBattleBufferA[bank][1];
- species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_SPECIES);
- gUnknown_03005D7C[bank] = CreateInvisibleSpriteWithCallback(sub_805D714);
- sub_806A068(species, GetBattlerPosition(bank));
+ ClearTemporarySpeciesSpriteData(battlerId, dontClearSubstituteBit);
+ gBattlerPartyIndexes[battlerId] = gBattleBufferA[battlerId][1];
+ species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
+ gUnknown_03005D7C[battlerId] = CreateInvisibleSpriteWithCallback(sub_805D714);
+ sub_806A068(species, GetBattlerPosition(battlerId));
- gBattlerSpriteIds[bank] = CreateSprite(
+ gBattlerSpriteIds[battlerId] = CreateSprite(
&gUnknown_0202499C,
- GetBattlerSpriteCoord(bank, 2),
- GetBattlerSpriteDefault_Y(bank),
- sub_80A82E4(bank));
+ GetBattlerSpriteCoord(battlerId, 2),
+ GetBattlerSpriteDefault_Y(battlerId),
+ sub_80A82E4(battlerId));
- gSprites[gUnknown_03005D7C[bank]].data[1] = gBattlerSpriteIds[bank];
- gSprites[gUnknown_03005D7C[bank]].data[2] = bank;
+ gSprites[gUnknown_03005D7C[battlerId]].data[1] = gBattlerSpriteIds[battlerId];
+ gSprites[gUnknown_03005D7C[battlerId]].data[2] = battlerId;
- gSprites[gBattlerSpriteIds[bank]].data[0] = bank;
- gSprites[gBattlerSpriteIds[bank]].data[2] = species;
- gSprites[gBattlerSpriteIds[bank]].oam.paletteNum = bank;
+ gSprites[gBattlerSpriteIds[battlerId]].data[0] = battlerId;
+ gSprites[gBattlerSpriteIds[battlerId]].data[2] = species;
+ gSprites[gBattlerSpriteIds[battlerId]].oam.paletteNum = battlerId;
- StartSpriteAnim(&gSprites[gBattlerSpriteIds[bank]], gBattleMonForms[bank]);
+ StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerId]], gBattleMonForms[battlerId]);
- gSprites[gBattlerSpriteIds[bank]].invisible = TRUE;
- gSprites[gBattlerSpriteIds[bank]].callback = SpriteCallbackDummy;
+ gSprites[gBattlerSpriteIds[battlerId]].invisible = TRUE;
+ gSprites[gBattlerSpriteIds[battlerId]].callback = SpriteCallbackDummy;
- gSprites[gUnknown_03005D7C[bank]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_PLAYER_SENDOUT);
+ gSprites[gUnknown_03005D7C[battlerId]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_PLAYER_SENDOUT);
}
static void LinkPartnerHandleReturnMonToBall(void)
@@ -1239,7 +1237,7 @@ static void LinkPartnerHandleMoveAnimation(void)
{
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0;
gBattlerControllerFuncs[gActiveBattler] = LinkPartnerDoMoveAnimation;
- sub_817E0FC(move, gWeatherMoveAnim, gAnimDisableStructPtr);
+ BattleTv_SetDataBasedOnMove(move, gWeatherMoveAnim, gAnimDisableStructPtr);
}
}
}
@@ -1303,7 +1301,7 @@ static void LinkPartnerHandlePrintString(void)
BufferStringBattle(*stringId);
BattleHandleAddTextPrinter(gDisplayedStringBattle, 0);
gBattlerControllerFuncs[gActiveBattler] = CompleteOnInactiveTextPrinter;
- sub_817C95C(*stringId);
+ BattleTv_SetDataBasedOnString(*stringId);
}
static void LinkPartnerHandlePrintSelectionString(void)
@@ -1374,11 +1372,11 @@ static void LinkPartnerHandleStatusIconUpdate(void)
{
if (!mplay_80342A4(gActiveBattler))
{
- u8 bank;
+ u8 battlerId;
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_STATUS_ICON);
- bank = gActiveBattler;
- gBattleSpritesDataPtr->healthBoxesData[bank].statusAnimActive = 0;
+ battlerId = gActiveBattler;
+ gBattleSpritesDataPtr->healthBoxesData[battlerId].statusAnimActive = 0;
gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation;
}
}
@@ -1667,7 +1665,7 @@ static void LinkPartnerHandleBattleAnimation(void)
else
gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedBattleAnimation;
- sub_817E32C(animationId);
+ BattleTv_SetDataBasedOnAnimation(animationId);
}
}
diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c
index 5a3732f8b..64cf16b86 100644
--- a/src/battle_controller_opponent.c
+++ b/src/battle_controller_opponent.c
@@ -5,7 +5,7 @@
#include "battle_interface.h"
#include "battle_anim.h"
#include "constants/battle_anim.h"
-#include "battle_link_817C95C.h"
+#include "battle_tv.h"
#include "battle_ai_script_commands.h"
#include "pokemon.h"
#include "link.h"
@@ -29,18 +29,16 @@
#include "data2.h"
#include "battle_setup.h"
-extern struct SpriteTemplate gUnknown_0202499C;
extern u16 gBattle_BG0_X;
extern u16 gBattle_BG0_Y;
extern struct MusicPlayerInfo gMPlayInfo_BGM;
extern struct UnusedControllerStruct gUnknown_02022D0C;
extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[];
-extern const struct BattleMove gBattleMoves[];
-extern void sub_8172EF0(u8 bank, struct Pokemon *mon);
+extern void sub_8172EF0(u8 battlerId, struct Pokemon *mon);
extern void sub_806A068(u16, u8);
-extern void sub_81A57E4(u8 bank, u16 stringId);
+extern void sub_81A57E4(u8 battlerId, u16 stringId);
extern u8 sub_81A4CB0(void);
extern u8 sub_81D5588(u16 trainerId);
extern u8 GetFrontierTrainerFrontSpriteId(u16 trainerId);
@@ -110,7 +108,7 @@ static void OpponentBufferExecCompleted(void);
static void sub_805FC80(void);
static u32 GetOpponentMonData(u8 monId, u8 *dst);
static void SetOpponentMonData(u8 monId);
-static void sub_80613DC(u8 bank, bool8 dontClearSubstituteBit);
+static void sub_80613DC(u8 battlerId, bool8 dontClearSubstituteBit);
static void DoSwitchOutAnimation(void);
static void OpponentDoMoveAnimation(void);
static void sub_806280C(struct Sprite *sprite);
@@ -1155,36 +1153,36 @@ static void OpponentHandleSwitchInAnim(void)
gBattlerControllerFuncs[gActiveBattler] = sub_805FDF0;
}
-static void sub_80613DC(u8 bank, bool8 dontClearSubstituteBit)
+static void sub_80613DC(u8 battlerId, bool8 dontClearSubstituteBit)
{
u16 species;
- ClearTemporarySpeciesSpriteData(bank, dontClearSubstituteBit);
- gBattlerPartyIndexes[bank] = gBattleBufferA[bank][1];
- species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[bank]], MON_DATA_SPECIES);
- gUnknown_03005D7C[bank] = CreateInvisibleSpriteWithCallback(sub_805D714);
- BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[bank]], bank);
- sub_806A068(species, GetBattlerPosition(bank));
+ ClearTemporarySpeciesSpriteData(battlerId, dontClearSubstituteBit);
+ gBattlerPartyIndexes[battlerId] = gBattleBufferA[battlerId][1];
+ species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
+ gUnknown_03005D7C[battlerId] = CreateInvisibleSpriteWithCallback(sub_805D714);
+ BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[battlerId]], battlerId);
+ sub_806A068(species, GetBattlerPosition(battlerId));
- gBattlerSpriteIds[bank] = CreateSprite(&gUnknown_0202499C,
- GetBattlerSpriteCoord(bank, 2),
- GetBattlerSpriteDefault_Y(bank),
- sub_80A82E4(bank));
+ gBattlerSpriteIds[battlerId] = CreateSprite(&gUnknown_0202499C,
+ GetBattlerSpriteCoord(battlerId, 2),
+ GetBattlerSpriteDefault_Y(battlerId),
+ sub_80A82E4(battlerId));
- gSprites[gBattlerSpriteIds[bank]].data[0] = bank;
- gSprites[gBattlerSpriteIds[bank]].data[2] = species;
+ gSprites[gBattlerSpriteIds[battlerId]].data[0] = battlerId;
+ gSprites[gBattlerSpriteIds[battlerId]].data[2] = species;
- gSprites[gUnknown_03005D7C[bank]].data[1] = gBattlerSpriteIds[bank];
- gSprites[gUnknown_03005D7C[bank]].data[2] = bank;
+ gSprites[gUnknown_03005D7C[battlerId]].data[1] = gBattlerSpriteIds[battlerId];
+ gSprites[gUnknown_03005D7C[battlerId]].data[2] = battlerId;
- gSprites[gBattlerSpriteIds[bank]].oam.paletteNum = bank;
+ gSprites[gBattlerSpriteIds[battlerId]].oam.paletteNum = battlerId;
- StartSpriteAnim(&gSprites[gBattlerSpriteIds[bank]], gBattleMonForms[bank]);
+ StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerId]], gBattleMonForms[battlerId]);
- gSprites[gBattlerSpriteIds[bank]].invisible = TRUE;
- gSprites[gBattlerSpriteIds[bank]].callback = SpriteCallbackDummy;
+ gSprites[gBattlerSpriteIds[battlerId]].invisible = TRUE;
+ gSprites[gBattlerSpriteIds[battlerId]].callback = SpriteCallbackDummy;
- gSprites[gUnknown_03005D7C[bank]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_OPPONENT_SENDOUT);
+ gSprites[gUnknown_03005D7C[battlerId]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_OPPONENT_SENDOUT);
}
static void OpponentHandleReturnMonToBall(void)
@@ -1564,7 +1562,7 @@ static void OpponentHandleChooseMove(void)
BtlController_EmitTwoReturnValues(1, 15, gBattlerTarget);
break;
default:
- if (gBattleMoves[moveInfo->moves[chosenMoveId]].target & (MOVE_TARGET_USER | MOVE_TARGET_x10))
+ if (gBattleMoves[moveInfo->moves[chosenMoveId]].target & (MOVE_TARGET_USER_OR_SELECTED | MOVE_TARGET_USER))
gBattlerTarget = gActiveBattler;
if (gBattleMoves[moveInfo->moves[chosenMoveId]].target & MOVE_TARGET_BOTH)
{
@@ -1586,7 +1584,7 @@ static void OpponentHandleChooseMove(void)
move = moveInfo->moves[chosenMoveId];
} while (move == MOVE_NONE);
- if (gBattleMoves[move].target & (MOVE_TARGET_USER | MOVE_TARGET_x10))
+ if (gBattleMoves[move].target & (MOVE_TARGET_USER_OR_SELECTED | MOVE_TARGET_USER))
BtlController_EmitTwoReturnValues(1, 10, (chosenMoveId) | (gActiveBattler << 8));
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
BtlController_EmitTwoReturnValues(1, 10, (chosenMoveId) | (GetBattlerAtPosition(Random() & 2) << 8));
@@ -1699,11 +1697,11 @@ static void OpponentHandleStatusIconUpdate(void)
{
if (!mplay_80342A4(gActiveBattler))
{
- u8 bank;
+ u8 battlerId;
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_STATUS_ICON);
- bank = gActiveBattler;
- gBattleSpritesDataPtr->healthBoxesData[bank].statusAnimActive = 0;
+ battlerId = gActiveBattler;
+ gBattleSpritesDataPtr->healthBoxesData[battlerId].statusAnimActive = 0;
gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation;
}
}
diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c
index 897122ddd..e0694029a 100644
--- a/src/battle_controller_player.c
+++ b/src/battle_controller_player.c
@@ -5,7 +5,7 @@
#include "battle_interface.h"
#include "battle_anim.h"
#include "constants/battle_anim.h"
-#include "battle_link_817C95C.h"
+#include "battle_tv.h"
#include "pokemon.h"
#include "link.h"
#include "util.h"
@@ -42,22 +42,12 @@ extern struct SpriteTemplate gUnknown_0202499C;
extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[];
extern const struct CompressedSpritePalette gTrainerBackPicPaletteTable[];
-extern const u8 gTypeNames[][7];
-extern const struct BattleMove gBattleMoves[];
-
-extern const u8 gText_BattleSwitchWhich[];
-extern const u8 gText_MoveInterfacePP[];
-extern const u8 gText_MoveInterfaceType[];
-extern const u8 gText_LinkStandby[];
-extern const u8 gText_BattleMenu[];
-extern const u8 gText_WhatWillPkmnDo[];
-extern const u8 gText_BattleYesNoChoice[];
-
-extern void sub_8172EF0(u8 bank, struct Pokemon *mon);
+
+extern void sub_8172EF0(u8 battlerId, struct Pokemon *mon);
extern void sub_81B89AC(u8 arg0);
extern void sub_81AABB0(void);
extern void sub_806A068(u16, u8);
-extern void sub_81A57E4(u8 bank, u16 stringId);
+extern void sub_81A57E4(u8 battlerId, u16 stringId);
extern void sub_81851A8(u8 *);
// this file's functions
@@ -140,7 +130,7 @@ static void sub_80595A4(u8 taskId);
static void PrintLinkStandbyMsg(void);
static u32 CopyPlayerMonData(u8 monId, u8 *dst);
static void SetPlayerMonData(u8 monId);
-static void sub_805B258(u8 bank, bool8 dontClearSubstituteBit);
+static void sub_805B258(u8 battlerId, bool8 dontClearSubstituteBit);
static void DoSwitchOutAnimation(void);
static void PlayerDoMoveAnimation(void);
static void task05_08033660(u8 taskId);
@@ -432,7 +422,7 @@ static void HandleInputChooseTarget(void)
case B_POSITION_PLAYER_RIGHT:
if (gActiveBattler != gMultiUsePlayerCursor)
i++;
- else if (gBattleMoves[GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1 + gMoveSelectionCursor[gActiveBattler])].target & MOVE_TARGET_USER)
+ else if (gBattleMoves[GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1 + gMoveSelectionCursor[gActiveBattler])].target & MOVE_TARGET_USER_OR_SELECTED)
i++;
break;
case B_POSITION_OPPONENT_LEFT:
@@ -474,7 +464,7 @@ static void HandleInputChooseTarget(void)
case B_POSITION_PLAYER_RIGHT:
if (gActiveBattler != gMultiUsePlayerCursor)
i++;
- else if (gBattleMoves[GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1 + gMoveSelectionCursor[gActiveBattler])].target & MOVE_TARGET_USER)
+ else if (gBattleMoves[GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1 + gMoveSelectionCursor[gActiveBattler])].target & MOVE_TARGET_USER_OR_SELECTED)
i++;
break;
case B_POSITION_OPPONENT_LEFT:
@@ -508,7 +498,7 @@ static void HandleInputChooseMove(void)
if (moveInfo->moves[gMoveSelectionCursor[gActiveBattler]] == MOVE_CURSE)
{
if (moveInfo->monType1 != TYPE_GHOST && moveInfo->monType2 != TYPE_GHOST)
- moveTarget = MOVE_TARGET_x10;
+ moveTarget = MOVE_TARGET_USER;
else
moveTarget = MOVE_TARGET_SELECTED;
}
@@ -517,26 +507,26 @@ static void HandleInputChooseMove(void)
moveTarget = gBattleMoves[moveInfo->moves[gMoveSelectionCursor[gActiveBattler]]].target;
}
- if (moveTarget & MOVE_TARGET_x10)
+ if (moveTarget & MOVE_TARGET_USER)
gMultiUsePlayerCursor = gActiveBattler;
else
gMultiUsePlayerCursor = GetBattlerAtPosition((GetBattlerPosition(gActiveBattler) & BIT_SIDE) ^ BIT_SIDE);
if (!gBattleBufferA[gActiveBattler][1]) // not a double battle
{
- if (moveTarget & MOVE_TARGET_USER && !gBattleBufferA[gActiveBattler][2])
+ if (moveTarget & MOVE_TARGET_USER_OR_SELECTED && !gBattleBufferA[gActiveBattler][2])
canSelectTarget++;
}
else // double battle
{
- if (!(moveTarget & (MOVE_TARGET_RANDOM | MOVE_TARGET_BOTH | MOVE_TARGET_DEPENDS | MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_x10)))
+ if (!(moveTarget & (MOVE_TARGET_RANDOM | MOVE_TARGET_BOTH | MOVE_TARGET_DEPENDS | MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_USER)))
canSelectTarget++; // either selected or user
if (moveInfo->currentPp[gMoveSelectionCursor[gActiveBattler]] == 0)
{
canSelectTarget = FALSE;
}
- else if (!(moveTarget & (MOVE_TARGET_x10 | MOVE_TARGET_USER)) && CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_ACTIVE) <= 1)
+ else if (!(moveTarget & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED)) && CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_ACTIVE) <= 1)
{
gMultiUsePlayerCursor = GetDefaultMoveTarget(gActiveBattler);
canSelectTarget = FALSE;
@@ -552,7 +542,7 @@ static void HandleInputChooseMove(void)
{
gBattlerControllerFuncs[gActiveBattler] = HandleInputChooseTarget;
- if (moveTarget & (MOVE_TARGET_x10 | MOVE_TARGET_USER))
+ if (moveTarget & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED))
gMultiUsePlayerCursor = gActiveBattler;
else if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT)])
gMultiUsePlayerCursor = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
@@ -872,7 +862,7 @@ static void HandleMoveSwitchting(void)
static void sub_80586F8(void)
{
- if (gLinkVSyncDisabled == 0)
+ if (gWirelessCommType == 0)
{
if (gReceivedRemoteLinkPlayers == 0)
{
@@ -881,7 +871,7 @@ static void sub_80586F8(void)
gMain.callback1 = gPreBattleCallback1;
SetMainCallback2(sub_8038D64);
if (gBattleOutcome == B_OUTCOME_WON)
- sub_817E3F4();
+ TryPutLinkBattleTvShowOnAir();
FreeAllWindowBuffers();
}
}
@@ -894,7 +884,7 @@ static void sub_80586F8(void)
gMain.callback1 = gPreBattleCallback1;
SetMainCallback2(sub_8038D64);
if (gBattleOutcome == B_OUTCOME_WON)
- sub_817E3F4();
+ TryPutLinkBattleTvShowOnAir();
FreeAllWindowBuffers();
}
}
@@ -908,7 +898,7 @@ void sub_80587B0(void)
{
if (sub_800A520())
{
- if (gLinkVSyncDisabled == 0)
+ if (gWirelessCommType == 0)
sub_800AC34();
else
sub_800ADF8();
@@ -1159,10 +1149,10 @@ static void CompleteOnInactiveTextPrinter(void)
static void Task_GiveExpToMon(u8 taskId)
{
u32 monId = (u8)(gTasks[taskId].tExpTask_monId);
- u8 bank = gTasks[taskId].tExpTask_bank;
+ u8 battlerId = gTasks[taskId].tExpTask_bank;
s16 gainedExp = gTasks[taskId].tExpTask_gainedExp;
- if (IsDoubleBattle() == TRUE || monId != gBattlerPartyIndexes[bank]) // give exp without the expbar
+ if (IsDoubleBattle() == TRUE || monId != gBattlerPartyIndexes[battlerId]) // give exp without the expbar
{
struct Pokemon *mon = &gPlayerParty[monId];
u16 species = GetMonData(mon, MON_DATA_SPECIES);
@@ -1178,12 +1168,12 @@ static void Task_GiveExpToMon(u8 taskId)
CalculateMonStats(mon);
gainedExp -= nextLvlExp - currExp;
savedActiveBank = gActiveBattler;
- gActiveBattler = bank;
+ gActiveBattler = battlerId;
BtlController_EmitTwoReturnValues(1, RET_VALUE_LEVELLED_UP, gainedExp);
gActiveBattler = savedActiveBank;
if (IsDoubleBattle() == TRUE
- && ((u16)(monId) == gBattlerPartyIndexes[bank] || (u16)(monId) == gBattlerPartyIndexes[bank ^ BIT_FLANK]))
+ && ((u16)(monId) == gBattlerPartyIndexes[battlerId] || (u16)(monId) == gBattlerPartyIndexes[battlerId ^ BIT_FLANK]))
gTasks[taskId].func = sub_8059544;
else
gTasks[taskId].func = DestroyExpTaskAndCompleteOnInactiveTextPrinter;
@@ -1192,7 +1182,7 @@ static void Task_GiveExpToMon(u8 taskId)
{
currExp += gainedExp;
SetMonData(mon, MON_DATA_EXP, &currExp);
- gBattlerControllerFuncs[bank] = CompleteOnInactiveTextPrinter;
+ gBattlerControllerFuncs[battlerId] = CompleteOnInactiveTextPrinter;
DestroyTask(taskId);
}
}
@@ -1206,7 +1196,7 @@ static void Task_PrepareToGiveExpWithExpBar(u8 taskId)
{
u8 monIndex = gTasks[taskId].tExpTask_monId;
s32 gainedExp = gTasks[taskId].tExpTask_gainedExp;
- u8 bank = gTasks[taskId].tExpTask_bank;
+ u8 battlerId = gTasks[taskId].tExpTask_bank;
struct Pokemon *mon = &gPlayerParty[monIndex];
u8 level = GetMonData(mon, MON_DATA_LEVEL);
u16 species = GetMonData(mon, MON_DATA_SPECIES);
@@ -1216,7 +1206,7 @@ static void Task_PrepareToGiveExpWithExpBar(u8 taskId)
exp -= currLvlExp;
expToNextLvl = gExperienceTables[gBaseStats[species].growthRate][level + 1] - currLvlExp;
- SetBattleBarStruct(bank, gHealthboxSpriteIds[bank], expToNextLvl, exp, -gainedExp);
+ SetBattleBarStruct(battlerId, gHealthboxSpriteIds[battlerId], expToNextLvl, exp, -gainedExp);
PlaySE(SE_EXP);
gTasks[taskId].func = sub_8059400;
}
@@ -1231,11 +1221,11 @@ static void sub_8059400(u8 taskId)
{
u8 monId = gTasks[taskId].tExpTask_monId;
s16 gainedExp = gTasks[taskId].tExpTask_gainedExp;
- u8 bank = gTasks[taskId].tExpTask_bank;
+ u8 battlerId = gTasks[taskId].tExpTask_bank;
s16 r4;
- r4 = sub_8074AA0(bank, gHealthboxSpriteIds[bank], EXP_BAR, 0);
- SetHealthboxSpriteVisible(gHealthboxSpriteIds[bank]);
+ r4 = sub_8074AA0(battlerId, gHealthboxSpriteIds[battlerId], EXP_BAR, 0);
+ SetHealthboxSpriteVisible(gHealthboxSpriteIds[battlerId]);
if (r4 == -1)
{
u8 level;
@@ -1257,7 +1247,7 @@ static void sub_8059400(u8 taskId)
CalculateMonStats(&gPlayerParty[monId]);
gainedExp -= expOnNextLvl - currExp;
savedActiveBank = gActiveBattler;
- gActiveBattler = bank;
+ gActiveBattler = battlerId;
BtlController_EmitTwoReturnValues(1, RET_VALUE_LEVELLED_UP, gainedExp);
gActiveBattler = savedActiveBank;
gTasks[taskId].func = sub_8059544;
@@ -1266,7 +1256,7 @@ static void sub_8059400(u8 taskId)
{
currExp += gainedExp;
SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &currExp);
- gBattlerControllerFuncs[bank] = CompleteOnInactiveTextPrinter;
+ gBattlerControllerFuncs[battlerId] = CompleteOnInactiveTextPrinter;
DestroyTask(taskId);
}
}
@@ -1275,30 +1265,30 @@ static void sub_8059400(u8 taskId)
static void sub_8059544(u8 taskId)
{
- u8 bank = gTasks[taskId].tExpTask_bank;
+ u8 battlerId = gTasks[taskId].tExpTask_bank;
u8 monIndex = gTasks[taskId].tExpTask_monId;
- if (IsDoubleBattle() == TRUE && monIndex == gBattlerPartyIndexes[bank ^ BIT_FLANK])
- bank ^= BIT_FLANK;
+ if (IsDoubleBattle() == TRUE && monIndex == gBattlerPartyIndexes[battlerId ^ BIT_FLANK])
+ battlerId ^= BIT_FLANK;
- InitAndLaunchSpecialAnimation(bank, bank, bank, B_ANIM_LVL_UP);
+ InitAndLaunchSpecialAnimation(battlerId, battlerId, battlerId, B_ANIM_LVL_UP);
gTasks[taskId].func = sub_80595A4;
}
static void sub_80595A4(u8 taskId)
{
- u8 bank = gTasks[taskId].tExpTask_bank;
+ u8 battlerId = gTasks[taskId].tExpTask_bank;
- if (!gBattleSpritesDataPtr->healthBoxesData[bank].specialAnimActive)
+ if (!gBattleSpritesDataPtr->healthBoxesData[battlerId].specialAnimActive)
{
u8 monIndex = gTasks[taskId].tExpTask_monId;
GetMonData(&gPlayerParty[monIndex], MON_DATA_LEVEL); // Unused return value
- if (IsDoubleBattle() == TRUE && monIndex == gBattlerPartyIndexes[bank ^ BIT_FLANK])
- UpdateHealthboxAttribute(gHealthboxSpriteIds[bank ^ BIT_FLANK], &gPlayerParty[monIndex], HEALTHBOX_ALL);
+ if (IsDoubleBattle() == TRUE && monIndex == gBattlerPartyIndexes[battlerId ^ BIT_FLANK])
+ UpdateHealthboxAttribute(gHealthboxSpriteIds[battlerId ^ BIT_FLANK], &gPlayerParty[monIndex], HEALTHBOX_ALL);
else
- UpdateHealthboxAttribute(gHealthboxSpriteIds[bank], &gPlayerParty[monIndex], HEALTHBOX_ALL);
+ UpdateHealthboxAttribute(gHealthboxSpriteIds[battlerId], &gPlayerParty[monIndex], HEALTHBOX_ALL);
gTasks[taskId].func = DestroyExpTaskAndCompleteOnInactiveTextPrinter;
}
@@ -1307,12 +1297,12 @@ static void sub_80595A4(u8 taskId)
static void DestroyExpTaskAndCompleteOnInactiveTextPrinter(u8 taskId)
{
u8 monIndex;
- u8 bank;
+ u8 battlerId;
monIndex = gTasks[taskId].tExpTask_monId;
GetMonData(&gPlayerParty[monIndex], MON_DATA_LEVEL); // Unused return value
- bank = gTasks[taskId].tExpTask_bank;
- gBattlerControllerFuncs[bank] = CompleteOnInactiveTextPrinter;
+ battlerId = gTasks[taskId].tExpTask_bank;
+ gBattlerControllerFuncs[battlerId] = CompleteOnInactiveTextPrinter;
DestroyTask(taskId);
}
@@ -2201,35 +2191,35 @@ static void PlayerHandleSwitchInAnim(void)
gBattlerControllerFuncs[gActiveBattler] = sub_805902C;
}
-static void sub_805B258(u8 bank, bool8 dontClearSubstituteBit)
+static void sub_805B258(u8 battlerId, bool8 dontClearSubstituteBit)
{
u16 species;
- ClearTemporarySpeciesSpriteData(bank, dontClearSubstituteBit);
- gBattlerPartyIndexes[bank] = gBattleBufferA[bank][1];
- species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_SPECIES);
- gUnknown_03005D7C[bank] = CreateInvisibleSpriteWithCallback(sub_805D714);
- sub_806A068(species, GetBattlerPosition(bank));
+ ClearTemporarySpeciesSpriteData(battlerId, dontClearSubstituteBit);
+ gBattlerPartyIndexes[battlerId] = gBattleBufferA[battlerId][1];
+ species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
+ gUnknown_03005D7C[battlerId] = CreateInvisibleSpriteWithCallback(sub_805D714);
+ sub_806A068(species, GetBattlerPosition(battlerId));
- gBattlerSpriteIds[bank] = CreateSprite(
+ gBattlerSpriteIds[battlerId] = CreateSprite(
&gUnknown_0202499C,
- GetBattlerSpriteCoord(bank, 2),
- GetBattlerSpriteDefault_Y(bank),
- sub_80A82E4(bank));
+ GetBattlerSpriteCoord(battlerId, 2),
+ GetBattlerSpriteDefault_Y(battlerId),
+ sub_80A82E4(battlerId));
- gSprites[gUnknown_03005D7C[bank]].data[1] = gBattlerSpriteIds[bank];
- gSprites[gUnknown_03005D7C[bank]].data[2] = bank;
+ gSprites[gUnknown_03005D7C[battlerId]].data[1] = gBattlerSpriteIds[battlerId];
+ gSprites[gUnknown_03005D7C[battlerId]].data[2] = battlerId;
- gSprites[gBattlerSpriteIds[bank]].data[0] = bank;
- gSprites[gBattlerSpriteIds[bank]].data[2] = species;
- gSprites[gBattlerSpriteIds[bank]].oam.paletteNum = bank;
+ gSprites[gBattlerSpriteIds[battlerId]].data[0] = battlerId;
+ gSprites[gBattlerSpriteIds[battlerId]].data[2] = species;
+ gSprites[gBattlerSpriteIds[battlerId]].oam.paletteNum = battlerId;
- StartSpriteAnim(&gSprites[gBattlerSpriteIds[bank]], gBattleMonForms[bank]);
+ StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerId]], gBattleMonForms[battlerId]);
- gSprites[gBattlerSpriteIds[bank]].invisible = TRUE;
- gSprites[gBattlerSpriteIds[bank]].callback = SpriteCallbackDummy;
+ gSprites[gBattlerSpriteIds[battlerId]].invisible = TRUE;
+ gSprites[gBattlerSpriteIds[battlerId]].callback = SpriteCallbackDummy;
- gSprites[gUnknown_03005D7C[bank]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_PLAYER_SENDOUT);
+ gSprites[gUnknown_03005D7C[battlerId]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_PLAYER_SENDOUT);
}
static void PlayerHandleReturnMonToBall(void)
@@ -2484,7 +2474,7 @@ static void PlayerHandleMoveAnimation(void)
{
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0;
gBattlerControllerFuncs[gActiveBattler] = PlayerDoMoveAnimation;
- sub_817E0FC(move, gWeatherMoveAnim, gAnimDisableStructPtr);
+ BattleTv_SetDataBasedOnMove(move, gWeatherMoveAnim, gAnimDisableStructPtr);
}
}
}
@@ -2548,7 +2538,7 @@ static void PlayerHandlePrintString(void)
BufferStringBattle(*stringId);
BattleHandleAddTextPrinter(gDisplayedStringBattle, 0);
gBattlerControllerFuncs[gActiveBattler] = CompleteOnInactiveTextPrinter2;
- sub_817C95C(*stringId);
+ BattleTv_SetDataBasedOnString(*stringId);
sub_81A57E4(gActiveBattler, *stringId);
}
@@ -2575,7 +2565,7 @@ static void PlayerHandleChooseAction(void)
s32 i;
gBattlerControllerFuncs[gActiveBattler] = HandleChooseActionAfterDma3;
- sub_817F2A8();
+ BattleTv_ClearExplosionFaintCause();
BattleHandleAddTextPrinter(gText_BattleMenu, 2);
for (i = 0; i < 4; i++)
@@ -2751,11 +2741,11 @@ static void PlayerHandleStatusIconUpdate(void)
{
if (!mplay_80342A4(gActiveBattler))
{
- u8 bank;
+ u8 battlerId;
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_STATUS_ICON);
- bank = gActiveBattler;
- gBattleSpritesDataPtr->healthBoxesData[bank].statusAnimActive = 0;
+ battlerId = gActiveBattler;
+ gBattleSpritesDataPtr->healthBoxesData[battlerId].statusAnimActive = 0;
gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation;
}
}
@@ -2964,13 +2954,13 @@ static void PlayerHandleIntroTrainerBallThrow(void)
void sub_805CC00(struct Sprite *sprite)
{
- u8 bank = sprite->data[5];
+ u8 battlerId = sprite->data[5];
FreeSpriteOamMatrix(sprite);
FreeSpritePaletteByTag(GetSpritePaletteTagByPaletteNum(sprite->oam.paletteNum));
DestroySprite(sprite);
- BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[bank]], bank);
- StartSpriteAnim(&gSprites[gBattlerSpriteIds[bank]], 0);
+ BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[battlerId]], battlerId);
+ StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerId]], 0);
}
static void task05_08033660(u8 taskId)
@@ -3069,7 +3059,7 @@ static void PlayerHandleBattleAnimation(void)
else
gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedBattleAnimation;
- sub_817E32C(animationId);
+ BattleTv_SetDataBasedOnAnimation(animationId);
}
}
diff --git a/src/battle_controller_player_partner.c b/src/battle_controller_player_partner.c
index 159fdb2ff..f18f582f7 100644
--- a/src/battle_controller_player_partner.c
+++ b/src/battle_controller_player_partner.c
@@ -25,17 +25,15 @@
#include "battle_setup.h"
#include "item_use.h"
-extern struct SpriteTemplate gUnknown_0202499C;
extern u16 gBattle_BG0_X;
extern u16 gBattle_BG0_Y;
extern struct UnusedControllerStruct gUnknown_02022D0C;
extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[];
extern const struct CompressedSpritePalette gTrainerBackPicPaletteTable[];
-extern const struct BattleMove gBattleMoves[];
extern void sub_81358F4(void);
-extern void sub_8172EF0(u8 bank, struct Pokemon *mon);
+extern void sub_8172EF0(u8 battlerId, struct Pokemon *mon);
extern void sub_806A068(u16, u8);
extern u8 GetFrontierTrainerFrontSpriteId(u16 trainerId);
@@ -109,7 +107,7 @@ static void sub_81BB688(u8 taskId);
static void sub_81BB9A0(void);
static u32 CopyPlayerPartnerMonData(u8 monId, u8 *dst);
static void SetPlayerPartnerMonData(u8 monId);
-static void sub_81BD0E4(u8 bank, bool8 dontClearSubstituteBit);
+static void sub_81BD0E4(u8 battlerId, bool8 dontClearSubstituteBit);
static void DoSwitchOutAnimation(void);
static void PlayerPartnerDoMoveAnimation(void);
static void sub_81BE2C8(u8 taskId);
@@ -326,10 +324,10 @@ static void CompleteOnInactiveTextPrinter(void)
static void Task_GiveExpToMon(u8 taskId)
{
u32 monId = (u8)(gTasks[taskId].tExpTask_monId);
- u8 bank = gTasks[taskId].tExpTask_bank;
+ u8 battlerId = gTasks[taskId].tExpTask_bank;
s16 gainedExp = gTasks[taskId].tExpTask_gainedExp;
- if (IsDoubleBattle() == TRUE || monId != gBattlerPartyIndexes[bank]) // give exp without the expbar
+ if (IsDoubleBattle() == TRUE || monId != gBattlerPartyIndexes[battlerId]) // give exp without the expbar
{
struct Pokemon *mon = &gPlayerParty[monId];
u16 species = GetMonData(mon, MON_DATA_SPECIES);
@@ -345,12 +343,12 @@ static void Task_GiveExpToMon(u8 taskId)
CalculateMonStats(mon);
gainedExp -= nextLvlExp - currExp;
savedActiveBank = gActiveBattler;
- gActiveBattler = bank;
+ gActiveBattler = battlerId;
BtlController_EmitTwoReturnValues(1, RET_VALUE_LEVELLED_UP, gainedExp);
gActiveBattler = savedActiveBank;
if (IsDoubleBattle() == TRUE
- && ((u16)(monId) == gBattlerPartyIndexes[bank] || (u16)(monId) == gBattlerPartyIndexes[bank ^ BIT_FLANK]))
+ && ((u16)(monId) == gBattlerPartyIndexes[battlerId] || (u16)(monId) == gBattlerPartyIndexes[battlerId ^ BIT_FLANK]))
gTasks[taskId].func = sub_81BB628;
else
gTasks[taskId].func = DestroyExpTaskAndCompleteOnInactiveTextPrinter;
@@ -359,7 +357,7 @@ static void Task_GiveExpToMon(u8 taskId)
{
currExp += gainedExp;
SetMonData(mon, MON_DATA_EXP, &currExp);
- gBattlerControllerFuncs[bank] = CompleteOnInactiveTextPrinter;
+ gBattlerControllerFuncs[battlerId] = CompleteOnInactiveTextPrinter;
DestroyTask(taskId);
}
}
@@ -373,7 +371,7 @@ static void Task_PrepareToGiveExpWithExpBar(u8 taskId)
{
u8 monIndex = gTasks[taskId].tExpTask_monId;
s32 gainedExp = gTasks[taskId].tExpTask_gainedExp;
- u8 bank = gTasks[taskId].tExpTask_bank;
+ u8 battlerId = gTasks[taskId].tExpTask_bank;
struct Pokemon *mon = &gPlayerParty[monIndex];
u8 level = GetMonData(mon, MON_DATA_LEVEL);
u16 species = GetMonData(mon, MON_DATA_SPECIES);
@@ -383,7 +381,7 @@ static void Task_PrepareToGiveExpWithExpBar(u8 taskId)
exp -= currLvlExp;
expToNextLvl = gExperienceTables[gBaseStats[species].growthRate][level + 1] - currLvlExp;
- SetBattleBarStruct(bank, gHealthboxSpriteIds[bank], expToNextLvl, exp, -gainedExp);
+ SetBattleBarStruct(battlerId, gHealthboxSpriteIds[battlerId], expToNextLvl, exp, -gainedExp);
PlaySE(SE_EXP);
gTasks[taskId].func = sub_81BB4E4;
}
@@ -398,11 +396,11 @@ static void sub_81BB4E4(u8 taskId)
{
u8 monId = gTasks[taskId].tExpTask_monId;
s16 gainedExp = gTasks[taskId].tExpTask_gainedExp;
- u8 bank = gTasks[taskId].tExpTask_bank;
+ u8 battlerId = gTasks[taskId].tExpTask_bank;
s16 r4;
- r4 = sub_8074AA0(bank, gHealthboxSpriteIds[bank], EXP_BAR, 0);
- SetHealthboxSpriteVisible(gHealthboxSpriteIds[bank]);
+ r4 = sub_8074AA0(battlerId, gHealthboxSpriteIds[battlerId], EXP_BAR, 0);
+ SetHealthboxSpriteVisible(gHealthboxSpriteIds[battlerId]);
if (r4 == -1)
{
u8 level;
@@ -424,7 +422,7 @@ static void sub_81BB4E4(u8 taskId)
CalculateMonStats(&gPlayerParty[monId]);
gainedExp -= expOnNextLvl - currExp;
savedActiveBank = gActiveBattler;
- gActiveBattler = bank;
+ gActiveBattler = battlerId;
BtlController_EmitTwoReturnValues(1, RET_VALUE_LEVELLED_UP, gainedExp);
gActiveBattler = savedActiveBank;
gTasks[taskId].func = sub_81BB628;
@@ -433,7 +431,7 @@ static void sub_81BB4E4(u8 taskId)
{
currExp += gainedExp;
SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &currExp);
- gBattlerControllerFuncs[bank] = CompleteOnInactiveTextPrinter;
+ gBattlerControllerFuncs[battlerId] = CompleteOnInactiveTextPrinter;
DestroyTask(taskId);
}
}
@@ -442,30 +440,30 @@ static void sub_81BB4E4(u8 taskId)
static void sub_81BB628(u8 taskId)
{
- u8 bank = gTasks[taskId].tExpTask_bank;
+ u8 battlerId = gTasks[taskId].tExpTask_bank;
u8 monIndex = gTasks[taskId].tExpTask_monId;
- if (IsDoubleBattle() == TRUE && monIndex == gBattlerPartyIndexes[bank ^ BIT_FLANK])
- bank ^= BIT_FLANK;
+ if (IsDoubleBattle() == TRUE && monIndex == gBattlerPartyIndexes[battlerId ^ BIT_FLANK])
+ battlerId ^= BIT_FLANK;
- InitAndLaunchSpecialAnimation(bank, bank, bank, B_ANIM_LVL_UP);
+ InitAndLaunchSpecialAnimation(battlerId, battlerId, battlerId, B_ANIM_LVL_UP);
gTasks[taskId].func = sub_81BB688;
}
static void sub_81BB688(u8 taskId)
{
- u8 bank = gTasks[taskId].tExpTask_bank;
+ u8 battlerId = gTasks[taskId].tExpTask_bank;
- if (!gBattleSpritesDataPtr->healthBoxesData[bank].specialAnimActive)
+ if (!gBattleSpritesDataPtr->healthBoxesData[battlerId].specialAnimActive)
{
u8 monIndex = gTasks[taskId].tExpTask_monId;
GetMonData(&gPlayerParty[monIndex], MON_DATA_LEVEL); // Unused return value
- if (IsDoubleBattle() == TRUE && monIndex == gBattlerPartyIndexes[bank ^ BIT_FLANK])
- UpdateHealthboxAttribute(gHealthboxSpriteIds[bank ^ BIT_FLANK], &gPlayerParty[monIndex], HEALTHBOX_ALL);
+ if (IsDoubleBattle() == TRUE && monIndex == gBattlerPartyIndexes[battlerId ^ BIT_FLANK])
+ UpdateHealthboxAttribute(gHealthboxSpriteIds[battlerId ^ BIT_FLANK], &gPlayerParty[monIndex], HEALTHBOX_ALL);
else
- UpdateHealthboxAttribute(gHealthboxSpriteIds[bank], &gPlayerParty[monIndex], HEALTHBOX_ALL);
+ UpdateHealthboxAttribute(gHealthboxSpriteIds[battlerId], &gPlayerParty[monIndex], HEALTHBOX_ALL);
gTasks[taskId].func = DestroyExpTaskAndCompleteOnInactiveTextPrinter;
}
@@ -474,12 +472,12 @@ static void sub_81BB688(u8 taskId)
static void DestroyExpTaskAndCompleteOnInactiveTextPrinter(u8 taskId)
{
u8 monIndex;
- u8 bank;
+ u8 battlerId;
monIndex = gTasks[taskId].tExpTask_monId;
GetMonData(&gPlayerParty[monIndex], MON_DATA_LEVEL); // Unused return value
- bank = gTasks[taskId].tExpTask_bank;
- gBattlerControllerFuncs[bank] = CompleteOnInactiveTextPrinter;
+ battlerId = gTasks[taskId].tExpTask_bank;
+ gBattlerControllerFuncs[battlerId] = CompleteOnInactiveTextPrinter;
DestroyTask(taskId);
}
@@ -1234,35 +1232,35 @@ static void PlayerPartnerHandleSwitchInAnim(void)
gBattlerControllerFuncs[gActiveBattler] = sub_81BBAE8;
}
-static void sub_81BD0E4(u8 bank, bool8 dontClearSubstituteBit)
+static void sub_81BD0E4(u8 battlerId, bool8 dontClearSubstituteBit)
{
u16 species;
- ClearTemporarySpeciesSpriteData(bank, dontClearSubstituteBit);
- gBattlerPartyIndexes[bank] = gBattleBufferA[bank][1];
- species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_SPECIES);
- gUnknown_03005D7C[bank] = CreateInvisibleSpriteWithCallback(sub_805D714);
- sub_806A068(species, GetBattlerPosition(bank));
+ ClearTemporarySpeciesSpriteData(battlerId, dontClearSubstituteBit);
+ gBattlerPartyIndexes[battlerId] = gBattleBufferA[battlerId][1];
+ species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
+ gUnknown_03005D7C[battlerId] = CreateInvisibleSpriteWithCallback(sub_805D714);
+ sub_806A068(species, GetBattlerPosition(battlerId));
- gBattlerSpriteIds[bank] = CreateSprite(
+ gBattlerSpriteIds[battlerId] = CreateSprite(
&gUnknown_0202499C,
- GetBattlerSpriteCoord(bank, 2),
- GetBattlerSpriteDefault_Y(bank),
- sub_80A82E4(bank));
+ GetBattlerSpriteCoord(battlerId, 2),
+ GetBattlerSpriteDefault_Y(battlerId),
+ sub_80A82E4(battlerId));
- gSprites[gUnknown_03005D7C[bank]].data[1] = gBattlerSpriteIds[bank];
- gSprites[gUnknown_03005D7C[bank]].data[2] = bank;
+ gSprites[gUnknown_03005D7C[battlerId]].data[1] = gBattlerSpriteIds[battlerId];
+ gSprites[gUnknown_03005D7C[battlerId]].data[2] = battlerId;
- gSprites[gBattlerSpriteIds[bank]].data[0] = bank;
- gSprites[gBattlerSpriteIds[bank]].data[2] = species;
- gSprites[gBattlerSpriteIds[bank]].oam.paletteNum = bank;
+ gSprites[gBattlerSpriteIds[battlerId]].data[0] = battlerId;
+ gSprites[gBattlerSpriteIds[battlerId]].data[2] = species;
+ gSprites[gBattlerSpriteIds[battlerId]].oam.paletteNum = battlerId;
- StartSpriteAnim(&gSprites[gBattlerSpriteIds[bank]], gBattleMonForms[bank]);
+ StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerId]], gBattleMonForms[battlerId]);
- gSprites[gBattlerSpriteIds[bank]].invisible = TRUE;
- gSprites[gBattlerSpriteIds[bank]].callback = SpriteCallbackDummy;
+ gSprites[gBattlerSpriteIds[battlerId]].invisible = TRUE;
+ gSprites[gBattlerSpriteIds[battlerId]].callback = SpriteCallbackDummy;
- gSprites[gUnknown_03005D7C[bank]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_PLAYER_SENDOUT);
+ gSprites[gUnknown_03005D7C[battlerId]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_PLAYER_SENDOUT);
}
static void PlayerPartnerHandleReturnMonToBall(void)
@@ -1522,7 +1520,7 @@ static void PlayerPartnerHandleChooseMove(void)
BattleAI_SetupAIData(0xF);
chosenMoveId = BattleAI_ChooseMoveOrAction();
- if (gBattleMoves[moveInfo->moves[chosenMoveId]].target & (MOVE_TARGET_x10 | MOVE_TARGET_USER))
+ if (gBattleMoves[moveInfo->moves[chosenMoveId]].target & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED))
gBattlerTarget = gActiveBattler;
if (gBattleMoves[moveInfo->moves[chosenMoveId]].target & MOVE_TARGET_BOTH)
{
@@ -1627,11 +1625,11 @@ static void PlayerPartnerHandleStatusIconUpdate(void)
{
if (!mplay_80342A4(gActiveBattler))
{
- u8 bank;
+ u8 battlerId;
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_STATUS_ICON);
- bank = gActiveBattler;
- gBattleSpritesDataPtr->healthBoxesData[bank].statusAnimActive = 0;
+ battlerId = gActiveBattler;
+ gBattleSpritesDataPtr->healthBoxesData[battlerId].statusAnimActive = 0;
gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation;
}
}
diff --git a/src/battle_controller_recorded_opponent.c b/src/battle_controller_recorded_opponent.c
index 855dfc554..4d1ccbaca 100644
--- a/src/battle_controller_recorded_opponent.c
+++ b/src/battle_controller_recorded_opponent.c
@@ -6,7 +6,7 @@
#include "battle_anim.h"
#include "constants/battle_anim.h"
#include "battle_ai_script_commands.h"
-#include "battle_link_817C95C.h"
+#include "battle_tv.h"
#include "recorded_battle.h"
#include "pokemon.h"
#include "link.h"
@@ -27,7 +27,6 @@
#include "item_use.h"
#include "battle_setup.h"
-extern struct SpriteTemplate gUnknown_0202499C;
extern u16 gBattle_BG0_X;
extern u16 gBattle_BG0_Y;
extern struct MusicPlayerInfo gMPlayInfo_BGM;
@@ -36,7 +35,7 @@ extern u8 gUnknown_0203C7B4;
extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[];
-extern void sub_8172EF0(u8 bank, struct Pokemon *mon);
+extern void sub_8172EF0(u8 battlerId, struct Pokemon *mon);
extern void sub_806A068(u16, u8);
extern u16 sub_8068B48(void);
extern u8 GetFrontierTrainerFrontSpriteId(u16 trainerId);
@@ -105,7 +104,7 @@ static void RecordedOpponentBufferExecCompleted(void);
static void sub_8186F14(void);
static u32 CopyRecordedOpponentMonData(u8 monId, u8 *dst);
static void SetRecordedOpponentMonData(u8 monId);
-static void sub_81885D8(u8 bank, bool8 dontClearSubstituteBit);
+static void sub_81885D8(u8 battlerId, bool8 dontClearSubstituteBit);
static void DoSwitchOutAnimation(void);
static void RecordedOpponentDoMoveAnimation(void);
static void sub_8189548(u8 taskId);
@@ -1145,35 +1144,35 @@ static void RecordedOpponentHandleSwitchInAnim(void)
gBattlerControllerFuncs[gActiveBattler] = sub_8187084;
}
-static void sub_81885D8(u8 bank, bool8 dontClearSubstituteBit)
+static void sub_81885D8(u8 battlerId, bool8 dontClearSubstituteBit)
{
u16 species;
- ClearTemporarySpeciesSpriteData(bank, dontClearSubstituteBit);
- gBattlerPartyIndexes[bank] = gBattleBufferA[bank][1];
- species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[bank]], MON_DATA_SPECIES);
- gUnknown_03005D7C[bank] = CreateInvisibleSpriteWithCallback(sub_805D714);
- BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[bank]], bank);
- sub_806A068(species, GetBattlerPosition(bank));
+ ClearTemporarySpeciesSpriteData(battlerId, dontClearSubstituteBit);
+ gBattlerPartyIndexes[battlerId] = gBattleBufferA[battlerId][1];
+ species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
+ gUnknown_03005D7C[battlerId] = CreateInvisibleSpriteWithCallback(sub_805D714);
+ BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[battlerId]], battlerId);
+ sub_806A068(species, GetBattlerPosition(battlerId));
- gBattlerSpriteIds[bank] = CreateSprite(&gUnknown_0202499C,
- GetBattlerSpriteCoord(bank, 2),
- GetBattlerSpriteDefault_Y(bank),
- sub_80A82E4(bank));
+ gBattlerSpriteIds[battlerId] = CreateSprite(&gUnknown_0202499C,
+ GetBattlerSpriteCoord(battlerId, 2),
+ GetBattlerSpriteDefault_Y(battlerId),
+ sub_80A82E4(battlerId));
- gSprites[gUnknown_03005D7C[bank]].data[1] = gBattlerSpriteIds[bank];
- gSprites[gUnknown_03005D7C[bank]].data[2] = bank;
+ gSprites[gUnknown_03005D7C[battlerId]].data[1] = gBattlerSpriteIds[battlerId];
+ gSprites[gUnknown_03005D7C[battlerId]].data[2] = battlerId;
- gSprites[gBattlerSpriteIds[bank]].data[0] = bank;
- gSprites[gBattlerSpriteIds[bank]].data[2] = species;
- gSprites[gBattlerSpriteIds[bank]].oam.paletteNum = bank;
+ gSprites[gBattlerSpriteIds[battlerId]].data[0] = battlerId;
+ gSprites[gBattlerSpriteIds[battlerId]].data[2] = species;
+ gSprites[gBattlerSpriteIds[battlerId]].oam.paletteNum = battlerId;
- StartSpriteAnim(&gSprites[gBattlerSpriteIds[bank]], gBattleMonForms[bank]);
+ StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerId]], gBattleMonForms[battlerId]);
- gSprites[gBattlerSpriteIds[bank]].invisible = TRUE;
- gSprites[gBattlerSpriteIds[bank]].callback = SpriteCallbackDummy;
+ gSprites[gBattlerSpriteIds[battlerId]].invisible = TRUE;
+ gSprites[gBattlerSpriteIds[battlerId]].callback = SpriteCallbackDummy;
- gSprites[gUnknown_03005D7C[bank]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_OPPONENT_SENDOUT);
+ gSprites[gUnknown_03005D7C[battlerId]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_OPPONENT_SENDOUT);
}
static void RecordedOpponentHandleReturnMonToBall(void)
@@ -1491,11 +1490,11 @@ static void RecordedOpponentHandleStatusIconUpdate(void)
{
if (!mplay_80342A4(gActiveBattler))
{
- u8 bank;
+ u8 battlerId;
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_STATUS_ICON);
- bank = gActiveBattler;
- gBattleSpritesDataPtr->healthBoxesData[bank].statusAnimActive = 0;
+ battlerId = gActiveBattler;
+ gBattleSpritesDataPtr->healthBoxesData[battlerId].statusAnimActive = 0;
gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation;
}
}
diff --git a/src/battle_controller_recorded_player.c b/src/battle_controller_recorded_player.c
index 4efe5babf..b16c3f307 100644
--- a/src/battle_controller_recorded_player.c
+++ b/src/battle_controller_recorded_player.c
@@ -25,7 +25,6 @@
#include "data2.h"
#include "item_use.h"
-extern struct SpriteTemplate gUnknown_0202499C;
extern u16 gBattle_BG0_X;
extern u16 gBattle_BG0_Y;
extern u32 gTransformedPersonalities[MAX_BATTLERS_COUNT];
@@ -35,9 +34,8 @@ extern struct UnusedControllerStruct gUnknown_02022D0C;
extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[];
extern const struct CompressedSpritePalette gTrainerBackPicPaletteTable[];
-extern const struct BattleMove gBattleMoves[];
-extern void sub_8172EF0(u8 bank, struct Pokemon *mon);
+extern void sub_8172EF0(u8 battlerId, struct Pokemon *mon);
extern void sub_806A068(u16, u8);
extern u8 GetFrontierTrainerFrontSpriteId(u16 trainerId);
@@ -105,7 +103,7 @@ static void RecordedPlayerBufferExecCompleted(void);
static void sub_818A328(void);
static u32 CopyRecordedPlayerMonData(u8 monId, u8 *dst);
static void SetRecordedPlayerMonData(u8 monId);
-static void sub_818BA6C(u8 bank, bool8 dontClearSubstituteBit);
+static void sub_818BA6C(u8 battlerId, bool8 dontClearSubstituteBit);
static void DoSwitchOutAnimation(void);
static void RecordedPlayerDoMoveAnimation(void);
static void sub_818CC24(u8 taskId);
@@ -1131,35 +1129,35 @@ static void RecordedPlayerHandleSwitchInAnim(void)
gBattlerControllerFuncs[gActiveBattler] = sub_818A470;
}
-static void sub_818BA6C(u8 bank, bool8 dontClearSubstituteBit)
+static void sub_818BA6C(u8 battlerId, bool8 dontClearSubstituteBit)
{
u16 species;
- ClearTemporarySpeciesSpriteData(bank, dontClearSubstituteBit);
- gBattlerPartyIndexes[bank] = gBattleBufferA[bank][1];
- species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_SPECIES);
- gUnknown_03005D7C[bank] = CreateInvisibleSpriteWithCallback(sub_805D714);
- sub_806A068(species, GetBattlerPosition(bank));
+ ClearTemporarySpeciesSpriteData(battlerId, dontClearSubstituteBit);
+ gBattlerPartyIndexes[battlerId] = gBattleBufferA[battlerId][1];
+ species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
+ gUnknown_03005D7C[battlerId] = CreateInvisibleSpriteWithCallback(sub_805D714);
+ sub_806A068(species, GetBattlerPosition(battlerId));
- gBattlerSpriteIds[bank] = CreateSprite(
+ gBattlerSpriteIds[battlerId] = CreateSprite(
&gUnknown_0202499C,
- GetBattlerSpriteCoord(bank, 2),
- GetBattlerSpriteDefault_Y(bank),
- sub_80A82E4(bank));
+ GetBattlerSpriteCoord(battlerId, 2),
+ GetBattlerSpriteDefault_Y(battlerId),
+ sub_80A82E4(battlerId));
- gSprites[gUnknown_03005D7C[bank]].data[1] = gBattlerSpriteIds[bank];
- gSprites[gUnknown_03005D7C[bank]].data[2] = bank;
+ gSprites[gUnknown_03005D7C[battlerId]].data[1] = gBattlerSpriteIds[battlerId];
+ gSprites[gUnknown_03005D7C[battlerId]].data[2] = battlerId;
- gSprites[gBattlerSpriteIds[bank]].data[0] = bank;
- gSprites[gBattlerSpriteIds[bank]].data[2] = species;
- gSprites[gBattlerSpriteIds[bank]].oam.paletteNum = bank;
+ gSprites[gBattlerSpriteIds[battlerId]].data[0] = battlerId;
+ gSprites[gBattlerSpriteIds[battlerId]].data[2] = species;
+ gSprites[gBattlerSpriteIds[battlerId]].oam.paletteNum = battlerId;
- StartSpriteAnim(&gSprites[gBattlerSpriteIds[bank]], gBattleMonForms[bank]);
+ StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerId]], gBattleMonForms[battlerId]);
- gSprites[gBattlerSpriteIds[bank]].invisible = TRUE;
- gSprites[gBattlerSpriteIds[bank]].callback = SpriteCallbackDummy;
+ gSprites[gBattlerSpriteIds[battlerId]].invisible = TRUE;
+ gSprites[gBattlerSpriteIds[battlerId]].callback = SpriteCallbackDummy;
- gSprites[gUnknown_03005D7C[bank]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_PLAYER_SENDOUT);
+ gSprites[gUnknown_03005D7C[battlerId]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_PLAYER_SENDOUT);
}
static void RecordedPlayerHandleReturnMonToBall(void)
@@ -1514,11 +1512,11 @@ static void RecordedPlayerHandleStatusIconUpdate(void)
{
if (!mplay_80342A4(gActiveBattler))
{
- u8 bank;
+ u8 battlerId;
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_STATUS_ICON);
- bank = gActiveBattler;
- gBattleSpritesDataPtr->healthBoxesData[bank].statusAnimActive = 0;
+ battlerId = gActiveBattler;
+ gBattleSpritesDataPtr->healthBoxesData[battlerId].statusAnimActive = 0;
gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation;
}
}
diff --git a/src/battle_controller_safari.c b/src/battle_controller_safari.c
index f65d11a84..09776f150 100644
--- a/src/battle_controller_safari.c
+++ b/src/battle_controller_safari.c
@@ -23,16 +23,11 @@
#include "pokeblock.h"
#include "item_use.h"
-extern struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT];
-extern struct SpriteTemplate gUnknown_0202499C;
extern u16 gBattle_BG0_X;
extern u16 gBattle_BG0_Y;
extern const struct CompressedSpritePalette gTrainerBackPicPaletteTable[];
-extern const u8 gText_SafariZoneMenu[];
-extern const u8 gText_WhatWillPkmnDo2[];
-
extern void sub_81358F4(void);
// this file's functions
diff --git a/src/battle_controller_wally.c b/src/battle_controller_wally.c
index ad028b719..ca7b2fd44 100644
--- a/src/battle_controller_wally.c
+++ b/src/battle_controller_wally.c
@@ -5,7 +5,7 @@
#include "battle_interface.h"
#include "battle_anim.h"
#include "constants/battle_anim.h"
-#include "battle_link_817C95C.h"
+#include "battle_tv.h"
#include "pokemon.h"
#include "link.h"
#include "util.h"
@@ -30,8 +30,6 @@
#include "battle_setup.h"
#include "item_use.h"
-extern struct MusicPlayerInfo gMPlayInfo_BGM;
-extern struct SpriteTemplate gUnknown_0202499C;
extern u16 gBattle_BG0_X;
extern u16 gBattle_BG0_Y;
extern s32 gUnknown_0203CD70;
@@ -39,10 +37,7 @@ extern struct UnusedControllerStruct gUnknown_02022D0C;
extern const struct CompressedSpritePalette gTrainerBackPicPaletteTable[];
-extern const u8 gText_WhatWillWallyDo[];
-extern const u8 gText_BattleMenu[];
-
-extern void sub_8172EF0(u8 bank, struct Pokemon *mon);
+extern void sub_8172EF0(u8 battlerId, struct Pokemon *mon);
extern void sub_806A068(u16, u8);
// this file's functions
@@ -1462,31 +1457,31 @@ static void WallyHandleIntroTrainerBallThrow(void)
gBattlerControllerFuncs[gActiveBattler] = nullsub_21;
}
-static void sub_816AA80(u8 bank)
+static void sub_816AA80(u8 battlerId)
{
u16 species;
- gBattleSpritesDataPtr->battlerData[bank].transformSpecies = 0;
- gBattlerPartyIndexes[bank] = gBattleBufferA[bank][1];
- species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_SPECIES);
- gUnknown_03005D7C[bank] = CreateInvisibleSpriteWithCallback(sub_805D714);
- sub_806A068(species, GetBattlerPosition(bank));
- gBattlerSpriteIds[bank] = CreateSprite(&gUnknown_0202499C,
- GetBattlerSpriteCoord(bank, 2),
- GetBattlerSpriteDefault_Y(bank),
- sub_80A82E4(bank));
-
- gSprites[gUnknown_03005D7C[bank]].data[1] = gBattlerSpriteIds[bank];
- gSprites[gUnknown_03005D7C[bank]].data[2] = bank;
-
- gSprites[gBattlerSpriteIds[bank]].data[0] = bank;
- gSprites[gBattlerSpriteIds[bank]].data[2] = species;
- gSprites[gBattlerSpriteIds[bank]].oam.paletteNum = bank;
-
- StartSpriteAnim(&gSprites[gBattlerSpriteIds[bank]], gBattleMonForms[bank]);
- gSprites[gBattlerSpriteIds[bank]].invisible = TRUE;
- gSprites[gBattlerSpriteIds[bank]].callback = SpriteCallbackDummy;
- gSprites[gUnknown_03005D7C[bank]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_PLAYER_SENDOUT);
+ gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies = 0;
+ gBattlerPartyIndexes[battlerId] = gBattleBufferA[battlerId][1];
+ species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
+ gUnknown_03005D7C[battlerId] = CreateInvisibleSpriteWithCallback(sub_805D714);
+ sub_806A068(species, GetBattlerPosition(battlerId));
+ gBattlerSpriteIds[battlerId] = CreateSprite(&gUnknown_0202499C,
+ GetBattlerSpriteCoord(battlerId, 2),
+ GetBattlerSpriteDefault_Y(battlerId),
+ sub_80A82E4(battlerId));
+
+ gSprites[gUnknown_03005D7C[battlerId]].data[1] = gBattlerSpriteIds[battlerId];
+ gSprites[gUnknown_03005D7C[battlerId]].data[2] = battlerId;
+
+ gSprites[gBattlerSpriteIds[battlerId]].data[0] = battlerId;
+ gSprites[gBattlerSpriteIds[battlerId]].data[2] = species;
+ gSprites[gBattlerSpriteIds[battlerId]].oam.paletteNum = battlerId;
+
+ StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerId]], gBattleMonForms[battlerId]);
+ gSprites[gBattlerSpriteIds[battlerId]].invisible = TRUE;
+ gSprites[gBattlerSpriteIds[battlerId]].callback = SpriteCallbackDummy;
+ gSprites[gUnknown_03005D7C[battlerId]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_PLAYER_SENDOUT);
}
static void sub_816AC04(u8 taskId)
diff --git a/src/battle_controllers.c b/src/battle_controllers.c
index cbb4fff69..2b918d018 100644
--- a/src/battle_controllers.c
+++ b/src/battle_controllers.c
@@ -12,18 +12,14 @@
#include "constants/abilities.h"
#include "battle_message.h"
-extern u8 gBattleBuffersTransferData[0x100];
-extern u8 gUnknown_0202428C;
-extern u32 gUnknown_02022FF4;
-extern u8 gUnknown_0203C7B4;
extern u8 gUnknown_02022D08;
extern u8 gUnknown_02022D09;
extern u8 gUnknown_02022D0A;
-extern const struct BattleMove gBattleMoves[];
+static EWRAM_DATA u8 sBattleBuffersTransferData[0x100] = {};
extern void task00_08081A90(u8 taskId); // cable_club
-extern void sub_81B8D64(u8 bank, u8 arg1); // party_menu
+extern void sub_81B8D64(u8 battlerId, u8 arg1); // party_menu
// this file's funcionts
static void CreateTasksForSendRecvLinkBuffers(void);
@@ -37,7 +33,7 @@ void HandleLinkBattleSetup(void)
{
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
{
- if (gLinkVSyncDisabled)
+ if (gWirelessCommType)
sub_800B488();
if (!gReceivedRemoteLinkPlayers)
OpenLink();
@@ -81,7 +77,6 @@ void SetUpBattleVarsAndBirchZigzagoon(void)
void sub_8032768(void)
{
s32 i;
- u8 *data;
if (!(gBattleTypeFlags & BATTLE_TYPE_RECORDED))
sub_8184DA4(1);
@@ -104,11 +99,11 @@ void sub_8032768(void)
sub_81B8D64(i, 0);
}
- for (i = 0; i < sizeof(gBattleStruct->field_1A4); i++)
- *(gBattleStruct->field_1A4 + i) = 0;
+ for (i = 0; i < sizeof(gBattleStruct->tvMovePoints); i++)
+ *((u8*)(&gBattleStruct->tvMovePoints) + i) = 0;
- for (i = 0; i < sizeof(gBattleStruct->field_204); i++)
- *(gBattleStruct->field_204 + i) = 0;
+ for (i = 0; i < sizeof(gBattleStruct->tv); i++)
+ *((u8*)(&gBattleStruct->tv) + i) = 0;
}
static void InitSinglePlayerBtlControllers(void)
@@ -758,7 +753,7 @@ static void Task_HandleSendLinkBuffersData(u8 taskId)
gTasks[taskId].data[11]++;
break;
case 2:
- if (gLinkVSyncDisabled)
+ if (gWirelessCommType)
{
gTasks[taskId].data[11]++;
}
@@ -871,7 +866,7 @@ void sub_8033648(void)
static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId)
{
u16 blockSize;
- u8 bank;
+ u8 battlerId;
u8 var;
if (gTasks[taskId].data[15] != gTasks[taskId].data[14])
@@ -882,17 +877,17 @@ static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId)
gTasks[taskId].data[12] = 0;
gTasks[taskId].data[15] = 0;
}
- bank = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_ACTIVE_BANK];
+ battlerId = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_ACTIVE_BANK];
blockSize = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_SIZE_LO] | (gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_SIZE_HI] << 8);
switch (gLinkBattleRecvBuffer[gTasks[taskId].data[15] + 0])
{
case 0:
- if (gBattleControllerExecFlags & gBitTable[bank])
+ if (gBattleControllerExecFlags & gBitTable[battlerId])
return;
- memcpy(gBattleBufferA[bank], &gLinkBattleRecvBuffer[gTasks[taskId].data[15] + 8], blockSize);
- sub_803F850(bank);
+ memcpy(gBattleBufferA[battlerId], &gLinkBattleRecvBuffer[gTasks[taskId].data[15] + 8], blockSize);
+ sub_803F850(battlerId);
if (!(gBattleTypeFlags & BATTLE_TYPE_WILD))
{
@@ -903,11 +898,11 @@ static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId)
}
break;
case 1:
- memcpy(gBattleBufferB[bank], &gLinkBattleRecvBuffer[gTasks[taskId].data[15] + 8], blockSize);
+ memcpy(gBattleBufferB[battlerId], &gLinkBattleRecvBuffer[gTasks[taskId].data[15] + 8], blockSize);
break;
case 2:
var = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_DATA];
- gBattleControllerExecFlags &= ~(gBitTable[bank] << (var * 4));
+ gBattleControllerExecFlags &= ~(gBitTable[battlerId] << (var * 4));
break;
}
@@ -917,171 +912,171 @@ static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId)
void BtlController_EmitGetMonData(u8 bufferId, u8 requestId, u8 monToCheck)
{
- gBattleBuffersTransferData[0] = CONTROLLER_GETMONDATA;
- gBattleBuffersTransferData[1] = requestId;
- gBattleBuffersTransferData[2] = monToCheck;
- gBattleBuffersTransferData[3] = 0;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_GETMONDATA;
+ sBattleBuffersTransferData[1] = requestId;
+ sBattleBuffersTransferData[2] = monToCheck;
+ sBattleBuffersTransferData[3] = 0;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitGetRawMonData(u8 bufferId, u8 monId, u8 bytes)
{
- gBattleBuffersTransferData[0] = CONTROLLER_GETRAWMONDATA;
- gBattleBuffersTransferData[1] = monId;
- gBattleBuffersTransferData[2] = bytes;
- gBattleBuffersTransferData[3] = 0;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_GETRAWMONDATA;
+ sBattleBuffersTransferData[1] = monId;
+ sBattleBuffersTransferData[2] = bytes;
+ sBattleBuffersTransferData[3] = 0;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitSetMonData(u8 bufferId, u8 requestId, u8 monToCheck, u8 bytes, void *data)
{
s32 i;
- gBattleBuffersTransferData[0] = CONTROLLER_SETMONDATA;
- gBattleBuffersTransferData[1] = requestId;
- gBattleBuffersTransferData[2] = monToCheck;
+ sBattleBuffersTransferData[0] = CONTROLLER_SETMONDATA;
+ sBattleBuffersTransferData[1] = requestId;
+ sBattleBuffersTransferData[2] = monToCheck;
for (i = 0; i < bytes; i++)
- gBattleBuffersTransferData[3 + i] = *(u8*)(data++);
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 3 + bytes);
+ sBattleBuffersTransferData[3 + i] = *(u8*)(data++);
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 3 + bytes);
}
void BtlController_EmitSetRawMonData(u8 bufferId, u8 monId, u8 bytes, void *data)
{
s32 i;
- gBattleBuffersTransferData[0] = CONTROLLER_SETRAWMONDATA;
- gBattleBuffersTransferData[1] = monId;
- gBattleBuffersTransferData[2] = bytes;
+ sBattleBuffersTransferData[0] = CONTROLLER_SETRAWMONDATA;
+ sBattleBuffersTransferData[1] = monId;
+ sBattleBuffersTransferData[2] = bytes;
for (i = 0; i < bytes; i++)
- gBattleBuffersTransferData[3 + i] = *(u8*)(data++);
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, bytes + 3);
+ sBattleBuffersTransferData[3 + i] = *(u8*)(data++);
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, bytes + 3);
}
void BtlController_EmitLoadMonSprite(u8 bufferId)
{
- gBattleBuffersTransferData[0] = CONTROLLER_LOADMONSPRITE;
- gBattleBuffersTransferData[1] = CONTROLLER_LOADMONSPRITE;
- gBattleBuffersTransferData[2] = CONTROLLER_LOADMONSPRITE;
- gBattleBuffersTransferData[3] = CONTROLLER_LOADMONSPRITE;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_LOADMONSPRITE;
+ sBattleBuffersTransferData[1] = CONTROLLER_LOADMONSPRITE;
+ sBattleBuffersTransferData[2] = CONTROLLER_LOADMONSPRITE;
+ sBattleBuffersTransferData[3] = CONTROLLER_LOADMONSPRITE;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitSwitchInAnim(u8 bufferId, u8 partyId, bool8 dontClearSubstituteBit)
{
- gBattleBuffersTransferData[0] = CONTROLLER_SWITCHINANIM;
- gBattleBuffersTransferData[1] = partyId;
- gBattleBuffersTransferData[2] = dontClearSubstituteBit;
- gBattleBuffersTransferData[3] = 5;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_SWITCHINANIM;
+ sBattleBuffersTransferData[1] = partyId;
+ sBattleBuffersTransferData[2] = dontClearSubstituteBit;
+ sBattleBuffersTransferData[3] = 5;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitReturnMonToBall(u8 bufferId, u8 arg1)
{
- gBattleBuffersTransferData[0] = CONTROLLER_RETURNMONTOBALL;
- gBattleBuffersTransferData[1] = arg1;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 2);
+ sBattleBuffersTransferData[0] = CONTROLLER_RETURNMONTOBALL;
+ sBattleBuffersTransferData[1] = arg1;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 2);
}
void BtlController_EmitDrawTrainerPic(u8 bufferId)
{
- gBattleBuffersTransferData[0] = CONTROLLER_DRAWTRAINERPIC;
- gBattleBuffersTransferData[1] = CONTROLLER_DRAWTRAINERPIC;
- gBattleBuffersTransferData[2] = CONTROLLER_DRAWTRAINERPIC;
- gBattleBuffersTransferData[3] = CONTROLLER_DRAWTRAINERPIC;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_DRAWTRAINERPIC;
+ sBattleBuffersTransferData[1] = CONTROLLER_DRAWTRAINERPIC;
+ sBattleBuffersTransferData[2] = CONTROLLER_DRAWTRAINERPIC;
+ sBattleBuffersTransferData[3] = CONTROLLER_DRAWTRAINERPIC;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitTrainerSlide(u8 bufferId)
{
- gBattleBuffersTransferData[0] = CONTROLLER_TRAINERSLIDE;
- gBattleBuffersTransferData[1] = CONTROLLER_TRAINERSLIDE;
- gBattleBuffersTransferData[2] = CONTROLLER_TRAINERSLIDE;
- gBattleBuffersTransferData[3] = CONTROLLER_TRAINERSLIDE;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_TRAINERSLIDE;
+ sBattleBuffersTransferData[1] = CONTROLLER_TRAINERSLIDE;
+ sBattleBuffersTransferData[2] = CONTROLLER_TRAINERSLIDE;
+ sBattleBuffersTransferData[3] = CONTROLLER_TRAINERSLIDE;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitTrainerSlideBack(u8 bufferId)
{
- gBattleBuffersTransferData[0] = CONTROLLER_TRAINERSLIDEBACK;
- gBattleBuffersTransferData[1] = CONTROLLER_TRAINERSLIDEBACK;
- gBattleBuffersTransferData[2] = CONTROLLER_TRAINERSLIDEBACK;
- gBattleBuffersTransferData[3] = CONTROLLER_TRAINERSLIDEBACK;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_TRAINERSLIDEBACK;
+ sBattleBuffersTransferData[1] = CONTROLLER_TRAINERSLIDEBACK;
+ sBattleBuffersTransferData[2] = CONTROLLER_TRAINERSLIDEBACK;
+ sBattleBuffersTransferData[3] = CONTROLLER_TRAINERSLIDEBACK;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitFaintAnimation(u8 bufferId)
{
- gBattleBuffersTransferData[0] = CONTROLLER_FAINTANIMATION;
- gBattleBuffersTransferData[1] = CONTROLLER_FAINTANIMATION;
- gBattleBuffersTransferData[2] = CONTROLLER_FAINTANIMATION;
- gBattleBuffersTransferData[3] = CONTROLLER_FAINTANIMATION;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_FAINTANIMATION;
+ sBattleBuffersTransferData[1] = CONTROLLER_FAINTANIMATION;
+ sBattleBuffersTransferData[2] = CONTROLLER_FAINTANIMATION;
+ sBattleBuffersTransferData[3] = CONTROLLER_FAINTANIMATION;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitPaletteFade(u8 bufferId)
{
- gBattleBuffersTransferData[0] = CONTROLLER_PALETTEFADE;
- gBattleBuffersTransferData[1] = CONTROLLER_PALETTEFADE;
- gBattleBuffersTransferData[2] = CONTROLLER_PALETTEFADE;
- gBattleBuffersTransferData[3] = CONTROLLER_PALETTEFADE;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_PALETTEFADE;
+ sBattleBuffersTransferData[1] = CONTROLLER_PALETTEFADE;
+ sBattleBuffersTransferData[2] = CONTROLLER_PALETTEFADE;
+ sBattleBuffersTransferData[3] = CONTROLLER_PALETTEFADE;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitSuccessBallThrowAnim(u8 bufferId)
{
- gBattleBuffersTransferData[0] = CONTROLLER_SUCCESSBALLTHROWANIM;
- gBattleBuffersTransferData[1] = CONTROLLER_SUCCESSBALLTHROWANIM;
- gBattleBuffersTransferData[2] = CONTROLLER_SUCCESSBALLTHROWANIM;
- gBattleBuffersTransferData[3] = CONTROLLER_SUCCESSBALLTHROWANIM;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_SUCCESSBALLTHROWANIM;
+ sBattleBuffersTransferData[1] = CONTROLLER_SUCCESSBALLTHROWANIM;
+ sBattleBuffersTransferData[2] = CONTROLLER_SUCCESSBALLTHROWANIM;
+ sBattleBuffersTransferData[3] = CONTROLLER_SUCCESSBALLTHROWANIM;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitBallThrowAnim(u8 bufferId, u8 caseId)
{
- gBattleBuffersTransferData[0] = CONTROLLER_BALLTHROWANIM;
- gBattleBuffersTransferData[1] = caseId;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 2);
+ sBattleBuffersTransferData[0] = CONTROLLER_BALLTHROWANIM;
+ sBattleBuffersTransferData[1] = caseId;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 2);
}
void BtlController_EmitPause(u8 bufferId, u8 toWait, void *data)
{
s32 i;
- gBattleBuffersTransferData[0] = CONTROLLER_PAUSE;
- gBattleBuffersTransferData[1] = toWait;
+ sBattleBuffersTransferData[0] = CONTROLLER_PAUSE;
+ sBattleBuffersTransferData[1] = toWait;
for (i = 0; i < toWait * 3; i++)
- gBattleBuffersTransferData[2 + i] = *(u8*)(data++);
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, toWait * 3 + 2);
+ sBattleBuffersTransferData[2 + i] = *(u8*)(data++);
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, toWait * 3 + 2);
}
void BtlController_EmitMoveAnimation(u8 bufferId, u16 move, u8 turnOfMove, u16 movePower, s32 dmg, u8 friendship, struct DisableStruct *disableStructPtr, u8 multihit)
{
- gBattleBuffersTransferData[0] = CONTROLLER_MOVEANIMATION;
- gBattleBuffersTransferData[1] = move;
- gBattleBuffersTransferData[2] = (move & 0xFF00) >> 8;
- gBattleBuffersTransferData[3] = turnOfMove;
- gBattleBuffersTransferData[4] = movePower;
- gBattleBuffersTransferData[5] = (movePower & 0xFF00) >> 8;
- gBattleBuffersTransferData[6] = dmg;
- gBattleBuffersTransferData[7] = (dmg & 0x0000FF00) >> 8;
- gBattleBuffersTransferData[8] = (dmg & 0x00FF0000) >> 16;
- gBattleBuffersTransferData[9] = (dmg & 0xFF000000) >> 24;
- gBattleBuffersTransferData[10] = friendship;
- gBattleBuffersTransferData[11] = multihit;
+ sBattleBuffersTransferData[0] = CONTROLLER_MOVEANIMATION;
+ sBattleBuffersTransferData[1] = move;
+ sBattleBuffersTransferData[2] = (move & 0xFF00) >> 8;
+ sBattleBuffersTransferData[3] = turnOfMove;
+ sBattleBuffersTransferData[4] = movePower;
+ sBattleBuffersTransferData[5] = (movePower & 0xFF00) >> 8;
+ sBattleBuffersTransferData[6] = dmg;
+ sBattleBuffersTransferData[7] = (dmg & 0x0000FF00) >> 8;
+ sBattleBuffersTransferData[8] = (dmg & 0x00FF0000) >> 16;
+ sBattleBuffersTransferData[9] = (dmg & 0xFF000000) >> 24;
+ sBattleBuffersTransferData[10] = friendship;
+ sBattleBuffersTransferData[11] = multihit;
if (WEATHER_HAS_EFFECT2)
{
- gBattleBuffersTransferData[12] = gBattleWeather;
- gBattleBuffersTransferData[13] = (gBattleWeather & 0xFF00) >> 8;
+ sBattleBuffersTransferData[12] = gBattleWeather;
+ sBattleBuffersTransferData[13] = (gBattleWeather & 0xFF00) >> 8;
}
else
{
- gBattleBuffersTransferData[12] = 0;
- gBattleBuffersTransferData[13] = 0;
+ sBattleBuffersTransferData[12] = 0;
+ sBattleBuffersTransferData[13] = 0;
}
- gBattleBuffersTransferData[14] = 0;
- gBattleBuffersTransferData[15] = 0;
- memcpy(&gBattleBuffersTransferData[16], disableStructPtr, sizeof(struct DisableStruct));
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 16 + sizeof(struct DisableStruct));
+ sBattleBuffersTransferData[14] = 0;
+ sBattleBuffersTransferData[15] = 0;
+ memcpy(&sBattleBuffersTransferData[16], disableStructPtr, sizeof(struct DisableStruct));
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 16 + sizeof(struct DisableStruct));
}
void BtlController_EmitPrintString(u8 bufferId, u16 stringID)
@@ -1089,12 +1084,12 @@ void BtlController_EmitPrintString(u8 bufferId, u16 stringID)
s32 i;
struct StringInfoBattle* stringInfo;
- gBattleBuffersTransferData[0] = CONTROLLER_PRINTSTRING;
- gBattleBuffersTransferData[1] = gBattleOutcome;
- gBattleBuffersTransferData[2] = stringID;
- gBattleBuffersTransferData[3] = (stringID & 0xFF00) >> 8;
+ sBattleBuffersTransferData[0] = CONTROLLER_PRINTSTRING;
+ sBattleBuffersTransferData[1] = gBattleOutcome;
+ sBattleBuffersTransferData[2] = stringID;
+ sBattleBuffersTransferData[3] = (stringID & 0xFF00) >> 8;
- stringInfo = (struct StringInfoBattle*)(&gBattleBuffersTransferData[4]);
+ stringInfo = (struct StringInfoBattle*)(&sBattleBuffersTransferData[4]);
stringInfo->currentMove = gCurrentMove;
stringInfo->originallyUsedMove = gChosenMove;
stringInfo->lastItem = gLastUsedItem;
@@ -1113,7 +1108,7 @@ void BtlController_EmitPrintString(u8 bufferId, u16 stringID)
stringInfo->textBuffs[1][i] = gBattleTextBuff2[i];
stringInfo->textBuffs[2][i] = gBattleTextBuff3[i];
}
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, sizeof(struct StringInfoBattle) + 4);
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, sizeof(struct StringInfoBattle) + 4);
}
void BtlController_EmitPrintSelectionString(u8 bufferId, u16 stringID)
@@ -1121,12 +1116,12 @@ void BtlController_EmitPrintSelectionString(u8 bufferId, u16 stringID)
s32 i;
struct StringInfoBattle *stringInfo;
- gBattleBuffersTransferData[0] = CONTROLLER_PRINTSTRINGPLAYERONLY;
- gBattleBuffersTransferData[1] = CONTROLLER_PRINTSTRINGPLAYERONLY;
- gBattleBuffersTransferData[2] = stringID;
- gBattleBuffersTransferData[3] = (stringID & 0xFF00) >> 8;
+ sBattleBuffersTransferData[0] = CONTROLLER_PRINTSTRINGPLAYERONLY;
+ sBattleBuffersTransferData[1] = CONTROLLER_PRINTSTRINGPLAYERONLY;
+ sBattleBuffersTransferData[2] = stringID;
+ sBattleBuffersTransferData[3] = (stringID & 0xFF00) >> 8;
- stringInfo = (struct StringInfoBattle*)(&gBattleBuffersTransferData[4]);
+ stringInfo = (struct StringInfoBattle*)(&sBattleBuffersTransferData[4]);
stringInfo->currentMove = gCurrentMove;
stringInfo->originallyUsedMove = gChosenMove;
stringInfo->lastItem = gLastUsedItem;
@@ -1142,386 +1137,386 @@ void BtlController_EmitPrintSelectionString(u8 bufferId, u16 stringID)
stringInfo->textBuffs[1][i] = gBattleTextBuff2[i];
stringInfo->textBuffs[2][i] = gBattleTextBuff3[i];
}
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, sizeof(struct StringInfoBattle) + 4);
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, sizeof(struct StringInfoBattle) + 4);
}
void BtlController_EmitChooseAction(u8 bufferId, u8 arg1, u16 arg2)
{
- gBattleBuffersTransferData[0] = CONTROLLER_CHOOSEACTION;
- gBattleBuffersTransferData[1] = arg1;
- gBattleBuffersTransferData[2] = arg2;
- gBattleBuffersTransferData[3] = (arg2 & 0xFF00) >> 8;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_CHOOSEACTION;
+ sBattleBuffersTransferData[1] = arg1;
+ sBattleBuffersTransferData[2] = arg2;
+ sBattleBuffersTransferData[3] = (arg2 & 0xFF00) >> 8;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitUnknownYesNoBox(u8 bufferId)
{
- gBattleBuffersTransferData[0] = CONTROLLER_UNKNOWNYESNOBOX;
- gBattleBuffersTransferData[1] = CONTROLLER_UNKNOWNYESNOBOX;
- gBattleBuffersTransferData[2] = CONTROLLER_UNKNOWNYESNOBOX;
- gBattleBuffersTransferData[3] = CONTROLLER_UNKNOWNYESNOBOX;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_UNKNOWNYESNOBOX;
+ sBattleBuffersTransferData[1] = CONTROLLER_UNKNOWNYESNOBOX;
+ sBattleBuffersTransferData[2] = CONTROLLER_UNKNOWNYESNOBOX;
+ sBattleBuffersTransferData[3] = CONTROLLER_UNKNOWNYESNOBOX;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitChooseMove(u8 bufferId, bool8 isDoubleBattle, bool8 NoPpNumber, struct ChooseMoveStruct *movePpData)
{
s32 i;
- gBattleBuffersTransferData[0] = CONTROLLER_CHOOSEMOVE;
- gBattleBuffersTransferData[1] = isDoubleBattle;
- gBattleBuffersTransferData[2] = NoPpNumber;
- gBattleBuffersTransferData[3] = 0;
+ sBattleBuffersTransferData[0] = CONTROLLER_CHOOSEMOVE;
+ sBattleBuffersTransferData[1] = isDoubleBattle;
+ sBattleBuffersTransferData[2] = NoPpNumber;
+ sBattleBuffersTransferData[3] = 0;
for (i = 0; i < sizeof(*movePpData); i++)
- gBattleBuffersTransferData[4 + i] = *((u8*)(movePpData) + i);
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, sizeof(*movePpData) + 4);
+ sBattleBuffersTransferData[4 + i] = *((u8*)(movePpData) + i);
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, sizeof(*movePpData) + 4);
}
void BtlController_EmitChooseItem(u8 bufferId, u8 *arg1)
{
s32 i;
- gBattleBuffersTransferData[0] = CONTROLLER_OPENBAG;
+ sBattleBuffersTransferData[0] = CONTROLLER_OPENBAG;
for (i = 0; i < 3; i++)
- gBattleBuffersTransferData[1 + i] = arg1[i];
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[1 + i] = arg1[i];
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitChoosePokemon(u8 bufferId, u8 caseId, u8 arg2, u8 abilityId, u8* arg4)
{
s32 i;
- gBattleBuffersTransferData[0] = CONTROLLER_CHOOSEPOKEMON;
- gBattleBuffersTransferData[1] = caseId;
- gBattleBuffersTransferData[2] = arg2;
- gBattleBuffersTransferData[3] = abilityId;
+ sBattleBuffersTransferData[0] = CONTROLLER_CHOOSEPOKEMON;
+ sBattleBuffersTransferData[1] = caseId;
+ sBattleBuffersTransferData[2] = arg2;
+ sBattleBuffersTransferData[3] = abilityId;
for (i = 0; i < 3; i++)
- gBattleBuffersTransferData[4 + i] = arg4[i];
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 8); // but only 7 bytes were written
+ sBattleBuffersTransferData[4 + i] = arg4[i];
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 8); // but only 7 bytes were written
}
void BtlController_EmitCmd23(u8 bufferId)
{
- gBattleBuffersTransferData[0] = CONTROLLER_23;
- gBattleBuffersTransferData[1] = CONTROLLER_23;
- gBattleBuffersTransferData[2] = CONTROLLER_23;
- gBattleBuffersTransferData[3] = CONTROLLER_23;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_23;
+ sBattleBuffersTransferData[1] = CONTROLLER_23;
+ sBattleBuffersTransferData[2] = CONTROLLER_23;
+ sBattleBuffersTransferData[3] = CONTROLLER_23;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
// why is the argument u16 if it's being cast to s16 anyway?
void BtlController_EmitHealthBarUpdate(u8 bufferId, u16 hpValue)
{
- gBattleBuffersTransferData[0] = CONTROLLER_HEALTHBARUPDATE;
- gBattleBuffersTransferData[1] = 0;
- gBattleBuffersTransferData[2] = (s16)hpValue;
- gBattleBuffersTransferData[3] = ((s16)hpValue & 0xFF00) >> 8;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_HEALTHBARUPDATE;
+ sBattleBuffersTransferData[1] = 0;
+ sBattleBuffersTransferData[2] = (s16)hpValue;
+ sBattleBuffersTransferData[3] = ((s16)hpValue & 0xFF00) >> 8;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
// why is the argument u16 if it's being cast to s16 anyway?
void BtlController_EmitExpUpdate(u8 bufferId, u8 partyId, u16 expPoints)
{
- gBattleBuffersTransferData[0] = CONTROLLER_EXPUPDATE;
- gBattleBuffersTransferData[1] = partyId;
- gBattleBuffersTransferData[2] = (s16)expPoints;
- gBattleBuffersTransferData[3] = ((s16)expPoints & 0xFF00) >> 8;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_EXPUPDATE;
+ sBattleBuffersTransferData[1] = partyId;
+ sBattleBuffersTransferData[2] = (s16)expPoints;
+ sBattleBuffersTransferData[3] = ((s16)expPoints & 0xFF00) >> 8;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitStatusIconUpdate(u8 bufferId, u32 status1, u32 status2)
{
- gBattleBuffersTransferData[0] = CONTROLLER_STATUSICONUPDATE;
- gBattleBuffersTransferData[1] = status1;
- gBattleBuffersTransferData[2] = (status1 & 0x0000FF00) >> 8;
- gBattleBuffersTransferData[3] = (status1 & 0x00FF0000) >> 16;
- gBattleBuffersTransferData[4] = (status1 & 0xFF000000) >> 24;
- gBattleBuffersTransferData[5] = status2;
- gBattleBuffersTransferData[6] = (status2 & 0x0000FF00) >> 8;
- gBattleBuffersTransferData[7] = (status2 & 0x00FF0000) >> 16;
- gBattleBuffersTransferData[8] = (status2 & 0xFF000000) >> 24;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 9);
+ sBattleBuffersTransferData[0] = CONTROLLER_STATUSICONUPDATE;
+ sBattleBuffersTransferData[1] = status1;
+ sBattleBuffersTransferData[2] = (status1 & 0x0000FF00) >> 8;
+ sBattleBuffersTransferData[3] = (status1 & 0x00FF0000) >> 16;
+ sBattleBuffersTransferData[4] = (status1 & 0xFF000000) >> 24;
+ sBattleBuffersTransferData[5] = status2;
+ sBattleBuffersTransferData[6] = (status2 & 0x0000FF00) >> 8;
+ sBattleBuffersTransferData[7] = (status2 & 0x00FF0000) >> 16;
+ sBattleBuffersTransferData[8] = (status2 & 0xFF000000) >> 24;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 9);
}
void BtlController_EmitStatusAnimation(u8 bufferId, bool8 status2, u32 status)
{
- gBattleBuffersTransferData[0] = CONTROLLER_STATUSANIMATION;
- gBattleBuffersTransferData[1] = status2;
- gBattleBuffersTransferData[2] = status;
- gBattleBuffersTransferData[3] = (status & 0x0000FF00) >> 8;
- gBattleBuffersTransferData[4] = (status & 0x00FF0000) >> 16;
- gBattleBuffersTransferData[5] = (status & 0xFF000000) >> 24;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 6);
+ sBattleBuffersTransferData[0] = CONTROLLER_STATUSANIMATION;
+ sBattleBuffersTransferData[1] = status2;
+ sBattleBuffersTransferData[2] = status;
+ sBattleBuffersTransferData[3] = (status & 0x0000FF00) >> 8;
+ sBattleBuffersTransferData[4] = (status & 0x00FF0000) >> 16;
+ sBattleBuffersTransferData[5] = (status & 0xFF000000) >> 24;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 6);
}
void BtlController_EmitStatusXor(u8 bufferId, u8 b)
{
- gBattleBuffersTransferData[0] = CONTROLLER_STATUSXOR;
- gBattleBuffersTransferData[1] = b;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 2);
+ sBattleBuffersTransferData[0] = CONTROLLER_STATUSXOR;
+ sBattleBuffersTransferData[1] = b;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 2);
}
void BtlController_EmitDataTransfer(u8 bufferId, u16 size, void *data)
{
s32 i;
- gBattleBuffersTransferData[0] = CONTROLLER_DATATRANSFER;
- gBattleBuffersTransferData[1] = CONTROLLER_DATATRANSFER;
- gBattleBuffersTransferData[2] = size;
- gBattleBuffersTransferData[3] = (size & 0xFF00) >> 8;
+ sBattleBuffersTransferData[0] = CONTROLLER_DATATRANSFER;
+ sBattleBuffersTransferData[1] = CONTROLLER_DATATRANSFER;
+ sBattleBuffersTransferData[2] = size;
+ sBattleBuffersTransferData[3] = (size & 0xFF00) >> 8;
for (i = 0; i < size; i++)
- gBattleBuffersTransferData[4 + i] = *(u8*)(data++);
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, size + 4);
+ sBattleBuffersTransferData[4 + i] = *(u8*)(data++);
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, size + 4);
}
void BtlController_EmitDMA3Transfer(u8 bufferId, void *dst, u16 size, void *data)
{
s32 i;
- gBattleBuffersTransferData[0] = CONTROLLER_DMA3TRANSFER;
- gBattleBuffersTransferData[1] = (u32)(dst);
- gBattleBuffersTransferData[2] = ((u32)(dst) & 0x0000FF00) >> 8;
- gBattleBuffersTransferData[3] = ((u32)(dst) & 0x00FF0000) >> 16;
- gBattleBuffersTransferData[4] = ((u32)(dst) & 0xFF000000) >> 24;
- gBattleBuffersTransferData[5] = size;
- gBattleBuffersTransferData[6] = (size & 0xFF00) >> 8;
+ sBattleBuffersTransferData[0] = CONTROLLER_DMA3TRANSFER;
+ sBattleBuffersTransferData[1] = (u32)(dst);
+ sBattleBuffersTransferData[2] = ((u32)(dst) & 0x0000FF00) >> 8;
+ sBattleBuffersTransferData[3] = ((u32)(dst) & 0x00FF0000) >> 16;
+ sBattleBuffersTransferData[4] = ((u32)(dst) & 0xFF000000) >> 24;
+ sBattleBuffersTransferData[5] = size;
+ sBattleBuffersTransferData[6] = (size & 0xFF00) >> 8;
for (i = 0; i < size; i++)
- gBattleBuffersTransferData[7 + i] = *(u8*)(data++);
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, size + 7);
+ sBattleBuffersTransferData[7 + i] = *(u8*)(data++);
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, size + 7);
}
void BtlController_EmitPlayBGM(u8 bufferId, u16 songId, void *unusedDumbDataParameter)
{
s32 i;
- gBattleBuffersTransferData[0] = CONTROLLER_31;
- gBattleBuffersTransferData[1] = songId;
- gBattleBuffersTransferData[2] = (songId & 0xFF00) >> 8;
+ sBattleBuffersTransferData[0] = CONTROLLER_31;
+ sBattleBuffersTransferData[1] = songId;
+ sBattleBuffersTransferData[2] = (songId & 0xFF00) >> 8;
for (i = 0; i < songId; i++) // ????
- gBattleBuffersTransferData[3 + i] = *(u8*)(unusedDumbDataParameter++);
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, songId + 3);
+ sBattleBuffersTransferData[3 + i] = *(u8*)(unusedDumbDataParameter++);
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, songId + 3);
}
void BtlController_EmitCmd32(u8 bufferId, u16 size, void *data)
{
s32 i;
- gBattleBuffersTransferData[0] = CONTROLLER_32;
- gBattleBuffersTransferData[1] = size;
- gBattleBuffersTransferData[2] = (size & 0xFF00) >> 8;
+ sBattleBuffersTransferData[0] = CONTROLLER_32;
+ sBattleBuffersTransferData[1] = size;
+ sBattleBuffersTransferData[2] = (size & 0xFF00) >> 8;
for (i = 0; i < size; i++)
- gBattleBuffersTransferData[3 + i] = *(u8*)(data++);
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, size + 3);
+ sBattleBuffersTransferData[3 + i] = *(u8*)(data++);
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, size + 3);
}
void BtlController_EmitTwoReturnValues(u8 bufferId, u8 arg1, u16 arg2)
{
- gBattleBuffersTransferData[0] = CONTROLLER_TWORETURNVALUES;
- gBattleBuffersTransferData[1] = arg1;
- gBattleBuffersTransferData[2] = arg2;
- gBattleBuffersTransferData[3] = (arg2 & 0xFF00) >> 8;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_TWORETURNVALUES;
+ sBattleBuffersTransferData[1] = arg1;
+ sBattleBuffersTransferData[2] = arg2;
+ sBattleBuffersTransferData[3] = (arg2 & 0xFF00) >> 8;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitChosenMonReturnValue(u8 bufferId, u8 b, u8 *c)
{
s32 i;
- gBattleBuffersTransferData[0] = CONTROLLER_CHOSENMONRETURNVALUE;
- gBattleBuffersTransferData[1] = b;
+ sBattleBuffersTransferData[0] = CONTROLLER_CHOSENMONRETURNVALUE;
+ sBattleBuffersTransferData[1] = b;
for (i = 0; i < 3; i++)
- gBattleBuffersTransferData[2 + i] = c[i];
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 5);
+ sBattleBuffersTransferData[2 + i] = c[i];
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 5);
}
void BtlController_EmitOneReturnValue(u8 bufferId, u16 arg1)
{
- gBattleBuffersTransferData[0] = CONTROLLER_ONERETURNVALUE;
- gBattleBuffersTransferData[1] = arg1;
- gBattleBuffersTransferData[2] = (arg1 & 0xFF00) >> 8;
- gBattleBuffersTransferData[3] = 0;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_ONERETURNVALUE;
+ sBattleBuffersTransferData[1] = arg1;
+ sBattleBuffersTransferData[2] = (arg1 & 0xFF00) >> 8;
+ sBattleBuffersTransferData[3] = 0;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitOneReturnValue_Duplicate(u8 bufferId, u16 b)
{
- gBattleBuffersTransferData[0] = CONTROLLER_ONERETURNVALUE_DUPLICATE;
- gBattleBuffersTransferData[1] = b;
- gBattleBuffersTransferData[2] = (b & 0xFF00) >> 8;
- gBattleBuffersTransferData[3] = 0;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_ONERETURNVALUE_DUPLICATE;
+ sBattleBuffersTransferData[1] = b;
+ sBattleBuffersTransferData[2] = (b & 0xFF00) >> 8;
+ sBattleBuffersTransferData[3] = 0;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitCmd37(u8 bufferId)
{
- gBattleBuffersTransferData[0] = CONTROLLER_37;
- gBattleBuffersTransferData[1] = CONTROLLER_37;
- gBattleBuffersTransferData[2] = CONTROLLER_37;
- gBattleBuffersTransferData[3] = CONTROLLER_37;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_37;
+ sBattleBuffersTransferData[1] = CONTROLLER_37;
+ sBattleBuffersTransferData[2] = CONTROLLER_37;
+ sBattleBuffersTransferData[3] = CONTROLLER_37;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitCmd38(u8 bufferId, u8 b)
{
- gBattleBuffersTransferData[0] = CONTROLLER_38;
- gBattleBuffersTransferData[1] = b;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 2);
+ sBattleBuffersTransferData[0] = CONTROLLER_38;
+ sBattleBuffersTransferData[1] = b;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 2);
}
void BtlController_EmitCmd39(u8 bufferId)
{
- gBattleBuffersTransferData[0] = CONTROLLER_39;
- gBattleBuffersTransferData[1] = CONTROLLER_39;
- gBattleBuffersTransferData[2] = CONTROLLER_39;
- gBattleBuffersTransferData[3] = CONTROLLER_39;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_39;
+ sBattleBuffersTransferData[1] = CONTROLLER_39;
+ sBattleBuffersTransferData[2] = CONTROLLER_39;
+ sBattleBuffersTransferData[3] = CONTROLLER_39;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitCmd40(u8 bufferId)
{
- gBattleBuffersTransferData[0] = CONTROLLER_40;
- gBattleBuffersTransferData[1] = CONTROLLER_40;
- gBattleBuffersTransferData[2] = CONTROLLER_40;
- gBattleBuffersTransferData[3] = CONTROLLER_40;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_40;
+ sBattleBuffersTransferData[1] = CONTROLLER_40;
+ sBattleBuffersTransferData[2] = CONTROLLER_40;
+ sBattleBuffersTransferData[3] = CONTROLLER_40;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitHitAnimation(u8 bufferId)
{
- gBattleBuffersTransferData[0] = CONTROLLER_HITANIMATION;
- gBattleBuffersTransferData[1] = CONTROLLER_HITANIMATION;
- gBattleBuffersTransferData[2] = CONTROLLER_HITANIMATION;
- gBattleBuffersTransferData[3] = CONTROLLER_HITANIMATION;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_HITANIMATION;
+ sBattleBuffersTransferData[1] = CONTROLLER_HITANIMATION;
+ sBattleBuffersTransferData[2] = CONTROLLER_HITANIMATION;
+ sBattleBuffersTransferData[3] = CONTROLLER_HITANIMATION;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitCmd42(u8 bufferId)
{
- gBattleBuffersTransferData[0] = CONTROLLER_42;
- gBattleBuffersTransferData[1] = CONTROLLER_42;
- gBattleBuffersTransferData[2] = CONTROLLER_42;
- gBattleBuffersTransferData[3] = CONTROLLER_42;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_42;
+ sBattleBuffersTransferData[1] = CONTROLLER_42;
+ sBattleBuffersTransferData[2] = CONTROLLER_42;
+ sBattleBuffersTransferData[3] = CONTROLLER_42;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitPlaySE(u8 bufferId, u16 songId)
{
- gBattleBuffersTransferData[0] = CONTROLLER_EFFECTIVENESSSOUND;
- gBattleBuffersTransferData[1] = songId;
- gBattleBuffersTransferData[2] = (songId & 0xFF00) >> 8;
- gBattleBuffersTransferData[3] = 0;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_EFFECTIVENESSSOUND;
+ sBattleBuffersTransferData[1] = songId;
+ sBattleBuffersTransferData[2] = (songId & 0xFF00) >> 8;
+ sBattleBuffersTransferData[3] = 0;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitPlayFanfareOrBGM(u8 bufferId, u16 songId, bool8 playBGM)
{
- gBattleBuffersTransferData[0] = CONTROLLER_PLAYFANFAREORBGM;
- gBattleBuffersTransferData[1] = songId;
- gBattleBuffersTransferData[2] = (songId & 0xFF00) >> 8;
- gBattleBuffersTransferData[3] = playBGM;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_PLAYFANFAREORBGM;
+ sBattleBuffersTransferData[1] = songId;
+ sBattleBuffersTransferData[2] = (songId & 0xFF00) >> 8;
+ sBattleBuffersTransferData[3] = playBGM;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitFaintingCry(u8 bufferId)
{
- gBattleBuffersTransferData[0] = CONTROLLER_FAINTINGCRY;
- gBattleBuffersTransferData[1] = CONTROLLER_FAINTINGCRY;
- gBattleBuffersTransferData[2] = CONTROLLER_FAINTINGCRY;
- gBattleBuffersTransferData[3] = CONTROLLER_FAINTINGCRY;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_FAINTINGCRY;
+ sBattleBuffersTransferData[1] = CONTROLLER_FAINTINGCRY;
+ sBattleBuffersTransferData[2] = CONTROLLER_FAINTINGCRY;
+ sBattleBuffersTransferData[3] = CONTROLLER_FAINTINGCRY;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitIntroSlide(u8 bufferId, u8 terrainId)
{
- gBattleBuffersTransferData[0] = CONTROLLER_INTROSLIDE;
- gBattleBuffersTransferData[1] = terrainId;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 2);
+ sBattleBuffersTransferData[0] = CONTROLLER_INTROSLIDE;
+ sBattleBuffersTransferData[1] = terrainId;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 2);
}
void BtlController_EmitIntroTrainerBallThrow(u8 bufferId)
{
- gBattleBuffersTransferData[0] = CONTROLLER_INTROTRAINERBALLTHROW;
- gBattleBuffersTransferData[1] = CONTROLLER_INTROTRAINERBALLTHROW;
- gBattleBuffersTransferData[2] = CONTROLLER_INTROTRAINERBALLTHROW;
- gBattleBuffersTransferData[3] = CONTROLLER_INTROTRAINERBALLTHROW;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_INTROTRAINERBALLTHROW;
+ sBattleBuffersTransferData[1] = CONTROLLER_INTROTRAINERBALLTHROW;
+ sBattleBuffersTransferData[2] = CONTROLLER_INTROTRAINERBALLTHROW;
+ sBattleBuffersTransferData[3] = CONTROLLER_INTROTRAINERBALLTHROW;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitDrawPartyStatusSummary(u8 bufferId, struct HpAndStatus* hpAndStatus, u8 arg2)
{
s32 i;
- gBattleBuffersTransferData[0] = CONTROLLER_DRAWPARTYSTATUSSUMMARY;
- gBattleBuffersTransferData[1] = arg2 & 0x7F;
- gBattleBuffersTransferData[2] = (arg2 & 0x80) >> 7;
- gBattleBuffersTransferData[3] = CONTROLLER_DRAWPARTYSTATUSSUMMARY;
+ sBattleBuffersTransferData[0] = CONTROLLER_DRAWPARTYSTATUSSUMMARY;
+ sBattleBuffersTransferData[1] = arg2 & 0x7F;
+ sBattleBuffersTransferData[2] = (arg2 & 0x80) >> 7;
+ sBattleBuffersTransferData[3] = CONTROLLER_DRAWPARTYSTATUSSUMMARY;
for (i = 0; i < (s32)(sizeof(struct HpAndStatus) * 6); i++)
- gBattleBuffersTransferData[4 + i] = *(i + (u8*)(hpAndStatus));
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, sizeof(struct HpAndStatus) * 6 + 4);
+ sBattleBuffersTransferData[4 + i] = *(i + (u8*)(hpAndStatus));
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, sizeof(struct HpAndStatus) * 6 + 4);
}
void BtlController_EmitCmd49(u8 bufferId)
{
- gBattleBuffersTransferData[0] = CONTROLLER_49;
- gBattleBuffersTransferData[1] = CONTROLLER_49;
- gBattleBuffersTransferData[2] = CONTROLLER_49;
- gBattleBuffersTransferData[3] = CONTROLLER_49;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_49;
+ sBattleBuffersTransferData[1] = CONTROLLER_49;
+ sBattleBuffersTransferData[2] = CONTROLLER_49;
+ sBattleBuffersTransferData[3] = CONTROLLER_49;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitCmd50(u8 bufferId)
{
- gBattleBuffersTransferData[0] = CONTROLLER_50;
- gBattleBuffersTransferData[1] = CONTROLLER_50;
- gBattleBuffersTransferData[2] = CONTROLLER_50;
- gBattleBuffersTransferData[3] = CONTROLLER_50;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_50;
+ sBattleBuffersTransferData[1] = CONTROLLER_50;
+ sBattleBuffersTransferData[2] = CONTROLLER_50;
+ sBattleBuffersTransferData[3] = CONTROLLER_50;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitSpriteInvisibility(u8 bufferId, bool8 isInvisible)
{
- gBattleBuffersTransferData[0] = CONTROLLER_SPRITEINVISIBILITY;
- gBattleBuffersTransferData[1] = isInvisible;
- gBattleBuffersTransferData[2] = CONTROLLER_SPRITEINVISIBILITY;
- gBattleBuffersTransferData[3] = CONTROLLER_SPRITEINVISIBILITY;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_SPRITEINVISIBILITY;
+ sBattleBuffersTransferData[1] = isInvisible;
+ sBattleBuffersTransferData[2] = CONTROLLER_SPRITEINVISIBILITY;
+ sBattleBuffersTransferData[3] = CONTROLLER_SPRITEINVISIBILITY;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitBattleAnimation(u8 bufferId, u8 animationId, u16 argument)
{
- gBattleBuffersTransferData[0] = CONTROLLER_BATTLEANIMATION;
- gBattleBuffersTransferData[1] = animationId;
- gBattleBuffersTransferData[2] = argument;
- gBattleBuffersTransferData[3] = (argument & 0xFF00) >> 8;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4);
+ sBattleBuffersTransferData[0] = CONTROLLER_BATTLEANIMATION;
+ sBattleBuffersTransferData[1] = animationId;
+ sBattleBuffersTransferData[2] = argument;
+ sBattleBuffersTransferData[3] = (argument & 0xFF00) >> 8;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4);
}
void BtlController_EmitLinkStandbyMsg(u8 bufferId, u8 arg1, bool32 arg2)
{
bool8 arg2_ = arg2;
- gBattleBuffersTransferData[0] = CONTROLLER_LINKSTANDBYMSG;
- gBattleBuffersTransferData[1] = arg1;
+ sBattleBuffersTransferData[0] = CONTROLLER_LINKSTANDBYMSG;
+ sBattleBuffersTransferData[1] = arg1;
if (arg2_)
- gBattleBuffersTransferData[3] = gBattleBuffersTransferData[2] = sub_81850DC(&gBattleBuffersTransferData[4]);
+ sBattleBuffersTransferData[3] = sBattleBuffersTransferData[2] = sub_81850DC(&sBattleBuffersTransferData[4]);
else
- gBattleBuffersTransferData[3] = gBattleBuffersTransferData[2] = 0;
+ sBattleBuffersTransferData[3] = sBattleBuffersTransferData[2] = 0;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, gBattleBuffersTransferData[2] + 4);
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, sBattleBuffersTransferData[2] + 4);
}
void BtlController_EmitResetActionMoveSelection(u8 bufferId, u8 caseId)
{
- gBattleBuffersTransferData[0] = CONTROLLER_RESETACTIONMOVESELECTION;
- gBattleBuffersTransferData[1] = caseId;
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 2);
+ sBattleBuffersTransferData[0] = CONTROLLER_RESETACTIONMOVESELECTION;
+ sBattleBuffersTransferData[1] = caseId;
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 2);
}
void BtlController_EmitCmd55(u8 bufferId, u8 arg1)
{
- gBattleBuffersTransferData[0] = CONTROLLER_55;
- gBattleBuffersTransferData[1] = arg1;
- gBattleBuffersTransferData[2] = gSaveBlock2Ptr->field_CA9_b;
- gBattleBuffersTransferData[3] = gSaveBlock2Ptr->field_CA9_b;
- gBattleBuffersTransferData[5] = gBattleBuffersTransferData[4] = sub_81850DC(&gBattleBuffersTransferData[6]);
- PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, gBattleBuffersTransferData[4] + 6);
+ sBattleBuffersTransferData[0] = CONTROLLER_55;
+ sBattleBuffersTransferData[1] = arg1;
+ sBattleBuffersTransferData[2] = gSaveBlock2Ptr->field_CA9_b;
+ sBattleBuffersTransferData[3] = gSaveBlock2Ptr->field_CA9_b;
+ sBattleBuffersTransferData[5] = sBattleBuffersTransferData[4] = sub_81850DC(&sBattleBuffersTransferData[6]);
+ PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, sBattleBuffersTransferData[4] + 6);
}
diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c
index 803b3eeab..d2c242553 100644
--- a/src/battle_gfx_sfx_util.c
+++ b/src/battle_gfx_sfx_util.c
@@ -28,7 +28,6 @@ extern struct MusicPlayerInfo gMPlayInfo_SE1;
extern struct MusicPlayerInfo gMPlayInfo_SE2;
extern struct MusicPlayerInfo gMPlayInfo_BGM;
-extern const struct BattleMove gBattleMoves[];
extern const u8 gUnknown_0831C604[];
extern const u8 * const gBattleAnims_VariousTable[];
extern const u8 * const gBattleAnims_Special[];
@@ -39,7 +38,6 @@ extern const struct CompressedSpriteSheet gTrainerBackPicTable[];
extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[];
extern const struct CompressedSpritePalette gTrainerBackPicPaletteTable[];
extern const union AnimCmd* const * const gMonAnimationsSpriteAnimsPtrTable[];
-extern const struct SpriteTemplate gUnknown_08329D98[4];
extern const struct CompressedSpriteSheet gSpriteSheet_EnemyShadow;
extern const struct SpriteTemplate gSpriteTemplate_EnemyShadow;
extern const u8 gEnemyMonElevation[];
@@ -238,7 +236,7 @@ u16 ChooseMoveAndTargetInBattlePalace(void)
if (moveInfo->moves[chosenMoveId] == MOVE_CURSE)
{
if (moveInfo->monType1 != TYPE_GHOST && moveInfo->monType2 != TYPE_GHOST)
- var1 = MOVE_TARGET_x10;
+ var1 = MOVE_TARGET_USER;
else
var1 = MOVE_TARGET_SELECTED;
}
@@ -247,7 +245,7 @@ u16 ChooseMoveAndTargetInBattlePalace(void)
var1 = gBattleMoves[moveInfo->moves[chosenMoveId]].target;
}
- if (var1 & MOVE_TARGET_x10)
+ if (var1 & MOVE_TARGET_USER)
chosenMoveId |= (gActiveBattler << 8);
else if (var1 == MOVE_TARGET_SELECTED)
chosenMoveId |= (BattlePalaceGetTargetRetValue());
@@ -262,7 +260,7 @@ static u8 sub_805D4A8(u16 move)
switch (gBattleMoves[move].target)
{
case MOVE_TARGET_SELECTED:
- case MOVE_TARGET_USER:
+ case MOVE_TARGET_USER_OR_SELECTED:
case MOVE_TARGET_RANDOM:
case MOVE_TARGET_BOTH:
case MOVE_TARGET_FOES_AND_ALLY:
@@ -274,7 +272,7 @@ static u8 sub_805D4A8(u16 move)
case MOVE_TARGET_DEPENDS:
case MOVE_TARGET_OPPONENTS_FIELD:
return 2;
- case MOVE_TARGET_x10:
+ case MOVE_TARGET_USER:
return 1;
default:
return 0;
diff --git a/src/battle_interface.c b/src/battle_interface.c
index bc6ff1122..9ef45020d 100644
--- a/src/battle_interface.c
+++ b/src/battle_interface.c
@@ -21,6 +21,7 @@
#include "safari_zone.h"
#include "battle_anim.h"
#include "constants/rgb.h"
+#include "data2.h"
struct TestingBar
{
@@ -154,7 +155,6 @@ enum
};
extern const u8 * const gNatureNamePointers[];
-extern const u8 gSpeciesNames[][POKEMON_NAME_LENGTH + 1];
// strings
extern const u8 gText_Slash[];
@@ -162,8 +162,6 @@ extern const u8 gText_HighlightDarkGrey[];
extern const u8 gText_DynColor2[];
extern const u8 gText_DynColor2Male[];
extern const u8 gText_DynColor1Female[];
-extern const u8 gText_SafariBalls[];
-extern const u8 gText_SafariBallLeft[];
// graphics
extern const u8 gBattleInterface_BallStatusBarGfx[];
@@ -198,10 +196,10 @@ static void SpriteCB_StatusSummaryBar(struct Sprite *sprite);
static void SpriteCB_StatusSummaryBallsOnBattleStart(struct Sprite *sprite);
static void SpriteCB_StatusSummaryBallsOnSwitchout(struct Sprite *sprite);
-static u8 GetStatusIconForBankId(u8 statusElementId, u8 bank);
+static u8 GetStatusIconForBankId(u8 statusElementId, u8 battlerId);
static s32 sub_8074DB8(s32 maxValue, s32 currValue, s32 receivedValue, s32 *arg3, u8 arg4, u16 arg5);
static u8 GetScaledExpFraction(s32 currValue, s32 receivedValue, s32 maxValue, u8 scale);
-static void sub_8074B9C(u8 bank, u8 whichBar);
+static void sub_8074B9C(u8 battlerId, u8 whichBar);
static u8 sub_8074E8C(s32 maxValue, s32 currValue, s32 receivedValue, s32 *arg3, u8 *arg4, u8 arg5);
static void sub_8074F88(struct TestingBar *barInfo, s32 *arg1, u16 *arg2);
@@ -650,7 +648,7 @@ static void sub_8072308(s16 arg0, u16 *arg1, u8 arg2)
}
#else
-__attribute__((naked))
+NAKED
static void sub_8072308(s16 arg0, u16 *arg1, u8 arg2)
{
asm(".syntax unified\n\
@@ -1034,13 +1032,13 @@ static void sub_8072924(struct Sprite *sprite)
sprite->pos2.y = gSprites[otherSpriteId].pos2.y;
}
-void SetBattleBarStruct(u8 bank, u8 healthboxSpriteId, s32 maxVal, s32 currVal, s32 receivedValue)
+void SetBattleBarStruct(u8 battlerId, u8 healthboxSpriteId, s32 maxVal, s32 currVal, s32 receivedValue)
{
- gBattleSpritesDataPtr->battleBars[bank].healthboxSpriteId = healthboxSpriteId;
- gBattleSpritesDataPtr->battleBars[bank].maxValue = maxVal;
- gBattleSpritesDataPtr->battleBars[bank].currentValue = currVal;
- gBattleSpritesDataPtr->battleBars[bank].receivedValue = receivedValue;
- gBattleSpritesDataPtr->battleBars[bank].field_10 = -32768;
+ gBattleSpritesDataPtr->battleBars[battlerId].healthboxSpriteId = healthboxSpriteId;
+ gBattleSpritesDataPtr->battleBars[battlerId].maxValue = maxVal;
+ gBattleSpritesDataPtr->battleBars[battlerId].currentValue = currVal;
+ gBattleSpritesDataPtr->battleBars[battlerId].receivedValue = receivedValue;
+ gBattleSpritesDataPtr->battleBars[battlerId].field_10 = -32768;
}
void SetHealthboxSpriteInvisible(u8 healthboxSpriteId)
@@ -1281,12 +1279,12 @@ static void UpdateHpTextInHealthboxInDoubles(u8 healthboxSpriteId, s16 value, u8
}
else
{
- u8 bank;
+ u8 battlerId;
memcpy(text, sUnknown_0832C3D8, sizeof(sUnknown_0832C3D8));
- bank = gSprites[healthboxSpriteId].data[6];
+ battlerId = gSprites[healthboxSpriteId].data[6];
- if (gBattleSpritesDataPtr->battlerData[bank].hpNumbersNoBars) // don't print text if only bars are visible
+ if (gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars) // don't print text if only bars are visible
{
u8 var = 4;
u8 r7;
@@ -1327,7 +1325,7 @@ static void UpdateHpTextInHealthboxInDoubles(u8 healthboxSpriteId, s16 value, u8
}
else
{
- if (GetBattlerSide(bank) == B_SIDE_PLAYER) // impossible to reach part, because the bank is from the opponent's side
+ if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) // impossible to reach part, because the battlerId is from the opponent's side
{
CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_116),
(void*)(OBJ_VRAM0) + ((gSprites[healthboxSpriteId].oam.tileNum + 52) * 32),
@@ -1469,7 +1467,7 @@ void SwapHpBarsWithHpText(void)
}
}
-u8 CreatePartyStatusSummarySprites(u8 bank, struct HpAndStatus *partyInfo, u8 arg2, bool8 isBattleStart)
+u8 CreatePartyStatusSummarySprites(u8 battlerId, struct HpAndStatus *partyInfo, u8 arg2, bool8 isBattleStart)
{
bool8 isOpponent;
s16 bar_X, bar_Y, bar_pos2_X, bar_data0;
@@ -1478,9 +1476,9 @@ u8 CreatePartyStatusSummarySprites(u8 bank, struct HpAndStatus *partyInfo, u8 ar
u8 ballIconSpritesIds[6];
u8 taskId;
- if (!arg2 || GetBattlerPosition(bank) != B_POSITION_OPPONENT_RIGHT)
+ if (!arg2 || GetBattlerPosition(battlerId) != B_POSITION_OPPONENT_RIGHT)
{
- if (GetBattlerSide(bank) == B_SIDE_PLAYER)
+ if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
{
isOpponent = FALSE;
bar_X = 136, bar_Y = 96;
@@ -1559,7 +1557,7 @@ u8 CreatePartyStatusSummarySprites(u8 bank, struct HpAndStatus *partyInfo, u8 ar
gSprites[ballIconSpritesIds[i]].data[2] = isOpponent;
}
- if (GetBattlerSide(bank) == B_SIDE_PLAYER)
+ if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
{
if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
{
@@ -1658,7 +1656,7 @@ u8 CreatePartyStatusSummarySprites(u8 bank, struct HpAndStatus *partyInfo, u8 ar
}
taskId = CreateTask(TaskDummy, 5);
- gTasks[taskId].data[0] = bank;
+ gTasks[taskId].data[0] = battlerId;
gTasks[taskId].data[1] = barSpriteId;
for (i = 0; i < 6; i++)
@@ -1680,12 +1678,12 @@ void sub_8073C30(u8 taskId)
u8 sp[6];
u8 r7;
u8 r10;
- u8 bank;
+ u8 battlerId;
s32 i;
r7 = gTasks[taskId].data[10];
r10 = gTasks[taskId].data[1];
- bank = gTasks[taskId].data[0];
+ battlerId = gTasks[taskId].data[0];
for (i = 0; i < 6; i++)
sp[i] = gTasks[taskId].data[3 + i];
@@ -1704,7 +1702,7 @@ void sub_8073C30(u8 taskId)
{
for (i = 0; i < 6; i++)
{
- if (GetBattlerSide(bank) != B_SIDE_PLAYER)
+ if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
{
gSprites[sp[5 - i]].data[1] = 7 * i;
gSprites[sp[5 - i]].data[3] = 0;
@@ -1752,7 +1750,7 @@ static void sub_8073E64(u8 taskId)
u8 sp[6];
s32 i;
- u8 bank = gTasks[taskId].data[0];
+ u8 battlerId = gTasks[taskId].data[0];
gTasks[taskId].data[15]--;
if (gTasks[taskId].data[15] == -1)
{
@@ -1780,7 +1778,7 @@ static void sub_8073E64(u8 taskId)
}
else if (gTasks[taskId].data[15] == -3)
{
- gBattleSpritesDataPtr->healthBoxesData[bank].flag_x1 = 0;
+ gBattleSpritesDataPtr->healthBoxesData[battlerId].flag_x1 = 0;
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
DestroyTask(taskId);
@@ -1792,7 +1790,7 @@ static void sub_8073F98(u8 taskId)
u8 sp[6];
s32 i;
- u8 bank = gTasks[taskId].data[0];
+ u8 battlerId = gTasks[taskId].data[0];
gTasks[taskId].data[15]--;
if (gTasks[taskId].data[15] >= 0)
{
@@ -1813,7 +1811,7 @@ static void sub_8073F98(u8 taskId)
}
else if (gTasks[taskId].data[15] == -3)
{
- gBattleSpritesDataPtr->healthBoxesData[bank].flag_x1 = 0;
+ gBattleSpritesDataPtr->healthBoxesData[battlerId].flag_x1 = 0;
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
DestroyTask(taskId);
@@ -1976,17 +1974,17 @@ static void UpdateNickInHealthbox(u8 healthboxSpriteId, struct Pokemon *mon)
static void TryAddPokeballIconToHealthbox(u8 healthboxSpriteId, bool8 noStatus)
{
- u8 bank, healthboxSpriteId_2;
+ u8 battlerId, healthboxSpriteId_2;
if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL)
return;
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
return;
- bank = gSprites[healthboxSpriteId].data[6];
- if (GetBattlerSide(bank) == B_SIDE_PLAYER)
+ battlerId = gSprites[healthboxSpriteId].data[6];
+ if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
return;
- if (!GetSetPokedexFlag(SpeciesToNationalPokedexNum(GetMonData(&gEnemyParty[gBattlerPartyIndexes[bank]], MON_DATA_SPECIES)), FLAG_GET_CAUGHT))
+ if (!GetSetPokedexFlag(SpeciesToNationalPokedexNum(GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES)), FLAG_GET_CAUGHT))
return;
healthboxSpriteId_2 = gSprites[healthboxSpriteId].data[5];
@@ -2000,17 +1998,17 @@ static void TryAddPokeballIconToHealthbox(u8 healthboxSpriteId, bool8 noStatus)
static void UpdateStatusIconInHealthbox(u8 healthboxSpriteId)
{
s32 i;
- u8 bank, healthboxSpriteId_2;
+ u8 battlerId, healthboxSpriteId_2;
u32 status, pltAdder;
const u8 *statusGfxPtr;
s16 tileNumAdder;
u8 statusPalId;
- bank = gSprites[healthboxSpriteId].data[6];
+ battlerId = gSprites[healthboxSpriteId].data[6];
healthboxSpriteId_2 = gSprites[healthboxSpriteId].data[5];
- if (GetBattlerSide(bank) == B_SIDE_PLAYER)
+ if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
{
- status = GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_STATUS);
+ status = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_STATUS);
if (!IsDoubleBattle())
tileNumAdder = 0x1A;
else
@@ -2018,33 +2016,33 @@ static void UpdateStatusIconInHealthbox(u8 healthboxSpriteId)
}
else
{
- status = GetMonData(&gEnemyParty[gBattlerPartyIndexes[bank]], MON_DATA_STATUS);
+ status = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_STATUS);
tileNumAdder = 0x11;
}
if (status & STATUS1_SLEEP)
{
- statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBankId(HEALTHBOX_GFX_STATUS_SLP_BANK0, bank));
+ statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBankId(HEALTHBOX_GFX_STATUS_SLP_BANK0, battlerId));
statusPalId = PAL_STATUS_SLP;
}
else if (status & STATUS1_PSN_ANY)
{
- statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBankId(HEALTHBOX_GFX_STATUS_PSN_BANK0, bank));
+ statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBankId(HEALTHBOX_GFX_STATUS_PSN_BANK0, battlerId));
statusPalId = PAL_STATUS_PSN;
}
else if (status & STATUS1_BURN)
{
- statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBankId(HEALTHBOX_GFX_STATUS_BRN_BANK0, bank));
+ statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBankId(HEALTHBOX_GFX_STATUS_BRN_BANK0, battlerId));
statusPalId = PAL_STATUS_BRN;
}
else if (status & STATUS1_FREEZE)
{
- statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBankId(HEALTHBOX_GFX_STATUS_FRZ_BANK0, bank));
+ statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBankId(HEALTHBOX_GFX_STATUS_FRZ_BANK0, battlerId));
statusPalId = PAL_STATUS_FRZ;
}
else if (status & STATUS1_PARALYSIS)
{
- statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBankId(HEALTHBOX_GFX_STATUS_PRZ_BANK0, bank));
+ statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBankId(HEALTHBOX_GFX_STATUS_PRZ_BANK0, battlerId));
statusPalId = PAL_STATUS_PAR;
}
else
@@ -2054,7 +2052,7 @@ static void UpdateStatusIconInHealthbox(u8 healthboxSpriteId)
for (i = 0; i < 3; i++)
CpuCopy32(statusGfxPtr, (void*)(OBJ_VRAM0 + (gSprites[healthboxSpriteId].oam.tileNum + tileNumAdder + i) * 32), 32);
- if (!gBattleSpritesDataPtr->battlerData[bank].hpNumbersNoBars)
+ if (!gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars)
CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_1), (void *)(OBJ_VRAM0 + gSprites[healthboxSpriteId_2].oam.tileNum * 32), 64);
TryAddPokeballIconToHealthbox(healthboxSpriteId, TRUE);
@@ -2062,14 +2060,14 @@ static void UpdateStatusIconInHealthbox(u8 healthboxSpriteId)
}
pltAdder = gSprites[healthboxSpriteId].oam.paletteNum * 16;
- pltAdder += bank + 12;
+ pltAdder += battlerId + 12;
FillPalette(sStatusIconColors[statusPalId], pltAdder + 0x100, 2);
CpuCopy16(gPlttBufferUnfaded + 0x100 + pltAdder, (void*)(OBJ_PLTT + pltAdder * 2), 2);
CpuCopy32(statusGfxPtr, (void*)(OBJ_VRAM0 + (gSprites[healthboxSpriteId].oam.tileNum + tileNumAdder) * 32), 96);
- if (IsDoubleBattle() == TRUE || GetBattlerSide(bank) == B_SIDE_OPPONENT)
+ if (IsDoubleBattle() == TRUE || GetBattlerSide(battlerId) == B_SIDE_OPPONENT)
{
- if (!gBattleSpritesDataPtr->battlerData[bank].hpNumbersNoBars)
+ if (!gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars)
{
CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_0), (void*)(OBJ_VRAM0 + gSprites[healthboxSpriteId_2].oam.tileNum * 32), 32);
CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_65), (void*)(OBJ_VRAM0 + (gSprites[healthboxSpriteId_2].oam.tileNum + 1) * 32), 32);
@@ -2078,58 +2076,58 @@ static void UpdateStatusIconInHealthbox(u8 healthboxSpriteId)
TryAddPokeballIconToHealthbox(healthboxSpriteId, FALSE);
}
-static u8 GetStatusIconForBankId(u8 statusElementId, u8 bank)
+static u8 GetStatusIconForBankId(u8 statusElementId, u8 battlerId)
{
u8 ret = statusElementId;
switch (statusElementId)
{
case HEALTHBOX_GFX_STATUS_PSN_BANK0:
- if (bank == 0)
+ if (battlerId == 0)
ret = HEALTHBOX_GFX_STATUS_PSN_BANK0;
- else if (bank == 1)
+ else if (battlerId == 1)
ret = HEALTHBOX_GFX_STATUS_PSN_BANK1;
- else if (bank == 2)
+ else if (battlerId == 2)
ret = HEALTHBOX_GFX_STATUS_PSN_BANK2;
else
ret = HEALTHBOX_GFX_STATUS_PSN_BANK3;
break;
case HEALTHBOX_GFX_STATUS_PRZ_BANK0:
- if (bank == 0)
+ if (battlerId == 0)
ret = HEALTHBOX_GFX_STATUS_PRZ_BANK0;
- else if (bank == 1)
+ else if (battlerId == 1)
ret = HEALTHBOX_GFX_STATUS_PRZ_BANK1;
- else if (bank == 2)
+ else if (battlerId == 2)
ret = HEALTHBOX_GFX_STATUS_PRZ_BANK2;
else
ret = HEALTHBOX_GFX_STATUS_PRZ_BANK3;
break;
case HEALTHBOX_GFX_STATUS_SLP_BANK0:
- if (bank == 0)
+ if (battlerId == 0)
ret = HEALTHBOX_GFX_STATUS_SLP_BANK0;
- else if (bank == 1)
+ else if (battlerId == 1)
ret = HEALTHBOX_GFX_STATUS_SLP_BANK1;
- else if (bank == 2)
+ else if (battlerId == 2)
ret = HEALTHBOX_GFX_STATUS_SLP_BANK2;
else
ret = HEALTHBOX_GFX_STATUS_SLP_BANK3;
break;
case HEALTHBOX_GFX_STATUS_FRZ_BANK0:
- if (bank == 0)
+ if (battlerId == 0)
ret = HEALTHBOX_GFX_STATUS_FRZ_BANK0;
- else if (bank == 1)
+ else if (battlerId == 1)
ret = HEALTHBOX_GFX_STATUS_FRZ_BANK1;
- else if (bank == 2)
+ else if (battlerId == 2)
ret = HEALTHBOX_GFX_STATUS_FRZ_BANK2;
else
ret = HEALTHBOX_GFX_STATUS_FRZ_BANK3;
break;
case HEALTHBOX_GFX_STATUS_BRN_BANK0:
- if (bank == 0)
+ if (battlerId == 0)
ret = HEALTHBOX_GFX_STATUS_BRN_BANK0;
- else if (bank == 1)
+ else if (battlerId == 1)
ret = HEALTHBOX_GFX_STATUS_BRN_BANK1;
- else if (bank == 2)
+ else if (battlerId == 2)
ret = HEALTHBOX_GFX_STATUS_BRN_BANK2;
else
ret = HEALTHBOX_GFX_STATUS_BRN_BANK3;
@@ -2170,10 +2168,10 @@ static void UpdateLeftNoOfBallsTextOnHealthbox(u8 healthboxSpriteId)
void UpdateHealthboxAttribute(u8 healthboxSpriteId, struct Pokemon *mon, u8 elementId)
{
s32 maxHp, currHp;
- u8 bank = gSprites[healthboxSpriteId].data[6];
+ u8 battlerId = gSprites[healthboxSpriteId].data[6];
if (elementId == HEALTHBOX_ALL && !IsDoubleBattle())
- GetBattlerSide(bank); // pointless function call
+ GetBattlerSide(battlerId); // pointless function call
if (GetBattlerSide(gSprites[healthboxSpriteId].data[6]) == B_SIDE_PLAYER)
{
@@ -2190,8 +2188,8 @@ void UpdateHealthboxAttribute(u8 healthboxSpriteId, struct Pokemon *mon, u8 elem
LoadBattleBarGfx(0);
maxHp = GetMonData(mon, MON_DATA_MAX_HP);
currHp = GetMonData(mon, MON_DATA_HP);
- SetBattleBarStruct(bank, healthboxSpriteId, maxHp, currHp, 0);
- sub_8074AA0(bank, healthboxSpriteId, HEALTH_BAR, 0);
+ SetBattleBarStruct(battlerId, healthboxSpriteId, maxHp, currHp, 0);
+ sub_8074AA0(battlerId, healthboxSpriteId, HEALTH_BAR, 0);
}
isDoubles = IsDoubleBattle();
if (!isDoubles && (elementId == HEALTHBOX_EXP_BAR || elementId == HEALTHBOX_ALL))
@@ -2208,8 +2206,8 @@ void UpdateHealthboxAttribute(u8 healthboxSpriteId, struct Pokemon *mon, u8 elem
currLevelExp = gExperienceTables[gBaseStats[species].growthRate][level];
currExpBarValue = exp - currLevelExp;
maxExpBarValue = gExperienceTables[gBaseStats[species].growthRate][level + 1] - currLevelExp;
- SetBattleBarStruct(bank, healthboxSpriteId, maxExpBarValue, currExpBarValue, isDoubles);
- sub_8074AA0(bank, healthboxSpriteId, EXP_BAR, 0);
+ SetBattleBarStruct(battlerId, healthboxSpriteId, maxExpBarValue, currExpBarValue, isDoubles);
+ sub_8074AA0(battlerId, healthboxSpriteId, EXP_BAR, 0);
}
if (elementId == HEALTHBOX_NICK || elementId == HEALTHBOX_ALL)
UpdateNickInHealthbox(healthboxSpriteId, mon);
@@ -2229,8 +2227,8 @@ void UpdateHealthboxAttribute(u8 healthboxSpriteId, struct Pokemon *mon, u8 elem
LoadBattleBarGfx(0);
maxHp = GetMonData(mon, MON_DATA_MAX_HP);
currHp = GetMonData(mon, MON_DATA_HP);
- SetBattleBarStruct(bank, healthboxSpriteId, maxHp, currHp, 0);
- sub_8074AA0(bank, healthboxSpriteId, HEALTH_BAR, 0);
+ SetBattleBarStruct(battlerId, healthboxSpriteId, maxHp, currHp, 0);
+ sub_8074AA0(battlerId, healthboxSpriteId, HEALTH_BAR, 0);
}
if (elementId == HEALTHBOX_NICK || elementId == HEALTHBOX_ALL)
UpdateNickInHealthbox(healthboxSpriteId, mon);
@@ -2239,44 +2237,44 @@ void UpdateHealthboxAttribute(u8 healthboxSpriteId, struct Pokemon *mon, u8 elem
}
}
-s32 sub_8074AA0(u8 bank, u8 healthboxSpriteId, u8 whichBar, u8 arg3)
+s32 sub_8074AA0(u8 battlerId, u8 healthboxSpriteId, u8 whichBar, u8 arg3)
{
s32 var;
if (whichBar == HEALTH_BAR) // health bar
{
- var = sub_8074DB8(gBattleSpritesDataPtr->battleBars[bank].maxValue,
- gBattleSpritesDataPtr->battleBars[bank].currentValue,
- gBattleSpritesDataPtr->battleBars[bank].receivedValue,
- &gBattleSpritesDataPtr->battleBars[bank].field_10,
+ var = sub_8074DB8(gBattleSpritesDataPtr->battleBars[battlerId].maxValue,
+ gBattleSpritesDataPtr->battleBars[battlerId].currentValue,
+ gBattleSpritesDataPtr->battleBars[battlerId].receivedValue,
+ &gBattleSpritesDataPtr->battleBars[battlerId].field_10,
6, 1);
}
else // exp bar
{
- u16 expFraction = GetScaledExpFraction(gBattleSpritesDataPtr->battleBars[bank].currentValue,
- gBattleSpritesDataPtr->battleBars[bank].receivedValue,
- gBattleSpritesDataPtr->battleBars[bank].maxValue, 8);
+ u16 expFraction = GetScaledExpFraction(gBattleSpritesDataPtr->battleBars[battlerId].currentValue,
+ gBattleSpritesDataPtr->battleBars[battlerId].receivedValue,
+ gBattleSpritesDataPtr->battleBars[battlerId].maxValue, 8);
if (expFraction == 0)
expFraction = 1;
- expFraction = abs(gBattleSpritesDataPtr->battleBars[bank].receivedValue / expFraction);
+ expFraction = abs(gBattleSpritesDataPtr->battleBars[battlerId].receivedValue / expFraction);
- var = sub_8074DB8(gBattleSpritesDataPtr->battleBars[bank].maxValue,
- gBattleSpritesDataPtr->battleBars[bank].currentValue,
- gBattleSpritesDataPtr->battleBars[bank].receivedValue,
- &gBattleSpritesDataPtr->battleBars[bank].field_10,
+ var = sub_8074DB8(gBattleSpritesDataPtr->battleBars[battlerId].maxValue,
+ gBattleSpritesDataPtr->battleBars[battlerId].currentValue,
+ gBattleSpritesDataPtr->battleBars[battlerId].receivedValue,
+ &gBattleSpritesDataPtr->battleBars[battlerId].field_10,
8, expFraction);
}
- if (whichBar == EXP_BAR || (whichBar == HEALTH_BAR && !gBattleSpritesDataPtr->battlerData[bank].hpNumbersNoBars))
- sub_8074B9C(bank, whichBar);
+ if (whichBar == EXP_BAR || (whichBar == HEALTH_BAR && !gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars))
+ sub_8074B9C(battlerId, whichBar);
if (var == -1)
- gBattleSpritesDataPtr->battleBars[bank].field_10 = 0;
+ gBattleSpritesDataPtr->battleBars[battlerId].field_10 = 0;
return var;
}
-static void sub_8074B9C(u8 bank, u8 whichBar)
+static void sub_8074B9C(u8 battlerId, u8 whichBar)
{
u8 array[8];
u8 subRet, level;
@@ -2286,10 +2284,10 @@ static void sub_8074B9C(u8 bank, u8 whichBar)
switch (whichBar)
{
case HEALTH_BAR:
- subRet = sub_8074E8C(gBattleSpritesDataPtr->battleBars[bank].maxValue,
- gBattleSpritesDataPtr->battleBars[bank].currentValue,
- gBattleSpritesDataPtr->battleBars[bank].receivedValue,
- &gBattleSpritesDataPtr->battleBars[bank].field_10,
+ subRet = sub_8074E8C(gBattleSpritesDataPtr->battleBars[battlerId].maxValue,
+ gBattleSpritesDataPtr->battleBars[battlerId].currentValue,
+ gBattleSpritesDataPtr->battleBars[battlerId].receivedValue,
+ &gBattleSpritesDataPtr->battleBars[battlerId].field_10,
array, 6);
barElementId = 3;
if (subRet <= 0x18)
@@ -2300,7 +2298,7 @@ static void sub_8074B9C(u8 bank, u8 whichBar)
}
for (i = 0; i < 6; i++)
{
- u8 healthboxSpriteId_2 = gSprites[gBattleSpritesDataPtr->battleBars[bank].healthboxSpriteId].data[5];
+ u8 healthboxSpriteId_2 = gSprites[gBattleSpritesDataPtr->battleBars[battlerId].healthboxSpriteId].data[5];
if (i < 2)
CpuCopy32(GetHealthboxElementGfxPtr(barElementId) + array[i] * 32,
(void*)(OBJ_VRAM0 + (gSprites[healthboxSpriteId_2].oam.tileNum + 2 + i) * 32), 32);
@@ -2310,12 +2308,12 @@ static void sub_8074B9C(u8 bank, u8 whichBar)
}
break;
case EXP_BAR:
- sub_8074E8C(gBattleSpritesDataPtr->battleBars[bank].maxValue,
- gBattleSpritesDataPtr->battleBars[bank].currentValue,
- gBattleSpritesDataPtr->battleBars[bank].receivedValue,
- &gBattleSpritesDataPtr->battleBars[bank].field_10,
+ sub_8074E8C(gBattleSpritesDataPtr->battleBars[battlerId].maxValue,
+ gBattleSpritesDataPtr->battleBars[battlerId].currentValue,
+ gBattleSpritesDataPtr->battleBars[battlerId].receivedValue,
+ &gBattleSpritesDataPtr->battleBars[battlerId].field_10,
array, 8);
- level = GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_LEVEL);
+ level = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_LEVEL);
if (level == MAX_MON_LEVEL)
{
for (i = 0; i < 8; i++)
@@ -2325,10 +2323,10 @@ static void sub_8074B9C(u8 bank, u8 whichBar)
{
if (i < 4)
CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_12) + array[i] * 32,
- (void*)(OBJ_VRAM0 + (gSprites[gBattleSpritesDataPtr->battleBars[bank].healthboxSpriteId].oam.tileNum + 0x24 + i) * 32), 32);
+ (void*)(OBJ_VRAM0 + (gSprites[gBattleSpritesDataPtr->battleBars[battlerId].healthboxSpriteId].oam.tileNum + 0x24 + i) * 32), 32);
else
CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_12) + array[i] * 32,
- (void*)(OBJ_VRAM0 + 0xB80 + (i + gSprites[gBattleSpritesDataPtr->battleBars[bank].healthboxSpriteId].oam.tileNum) * 32), 32);
+ (void*)(OBJ_VRAM0 + 0xB80 + (i + gSprites[gBattleSpritesDataPtr->battleBars[battlerId].healthboxSpriteId].oam.tileNum) * 32), 32);
}
break;
}
diff --git a/src/battle_main.c b/src/battle_main.c
index 3c4a61600..8649209c0 100644
--- a/src/battle_main.c
+++ b/src/battle_main.c
@@ -20,6 +20,7 @@
#include "constants/hold_effects.h"
#include "constants/trainers.h"
#include "link.h"
+#include "link_rfu.h"
#include "bg.h"
#include "dma3.h"
#include "string_util.h"
@@ -50,7 +51,7 @@
#include "international_string_util.h"
#include "pokeball.h"
-struct UnknownPokemonStruct2
+struct UnknownPokemonStruct4
{
/*0x00*/ u16 species;
/*0x02*/ u16 heldItem;
@@ -80,12 +81,10 @@ extern struct MusicPlayerInfo gMPlayInfo_SE1;
extern struct MusicPlayerInfo gMPlayInfo_SE2;
extern u8 gUnknown_0203CF00[];
-extern const struct BattleMove gBattleMoves[];
extern const u16 gBattleTextboxPalette[]; // battle textbox palette
extern const struct BgTemplate gUnknown_0831AA08[];
extern const struct WindowTemplate * const gUnknown_0831ABA0[];
extern const u8 gUnknown_0831ACE0[];
-extern const u8 gStatStageRatios[][2];
extern const u8 * const gBattleScriptsForMoveEffects[];
extern const u8 * const gBattlescriptsForBallThrow[];
extern const u8 * const gBattlescriptsForRunningByItem[];
@@ -95,12 +94,8 @@ extern const struct ScanlineEffectParams gUnknown_0831AC70;
// strings
extern const u8 gText_LinkStandby3[];
-extern const u8 gText_RecordBattleToPass[];
-extern const u8 gText_BattleYesNoChoice[];
extern const u8 gText_BattleRecordCouldntBeSaved[];
-extern const u8 gText_BattleRecordedOnPass[];
extern const u8 gText_ShedinjaJapaneseName[];
-extern const u8 gText_EmptyString3[];
extern const u8 gText_Poison[];
extern const u8 gText_Sleep[];
extern const u8 gText_Paralysis[];
@@ -198,8 +193,8 @@ EWRAM_DATA static u32 sUnusedUnknownArray[25] = {0};
EWRAM_DATA u32 gBattleTypeFlags = 0;
EWRAM_DATA u8 gBattleTerrain = 0;
EWRAM_DATA u32 gUnknown_02022FF4 = 0;
-EWRAM_DATA struct UnknownPokemonStruct2 gUnknown_02022FF8[3] = {0}; // what is it used for?
-EWRAM_DATA struct UnknownPokemonStruct2* gUnknown_02023058 = NULL; // what is it used for?
+EWRAM_DATA struct UnknownPokemonStruct4 gUnknown_02022FF8[3] = {0}; // what is it used for?
+EWRAM_DATA struct UnknownPokemonStruct4* gUnknown_02023058 = NULL; // what is it used for?
EWRAM_DATA u8 *gUnknown_0202305C = NULL;
EWRAM_DATA u8 *gUnknown_02023060 = NULL;
EWRAM_DATA u8 gBattleBufferA[MAX_BATTLERS_COUNT][0x200] = {0};
@@ -301,6 +296,214 @@ u8 gNumberOfMovesToChoose;
u8 gUnknown_03005D7C[MAX_BATTLERS_COUNT];
// rom const data
+
+// format: attacking type, defending type, damage multiplier
+// the multiplier is a (decimal) fixed-point number:
+// 20 is ×2.0 TYPE_MUL_SUPER_EFFECTIVE
+// 10 is ×1.0 TYPE_MUL_NORMAL
+// 05 is ×0.5 TYPE_MUL_NOT_EFFECTIVE
+// 00 is ×0.0 TYPE_MUL_NO_EFFECT
+const u8 gTypeEffectiveness[336] =
+{
+ TYPE_NORMAL, TYPE_ROCK, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_NORMAL, TYPE_STEEL, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_FIRE, TYPE_FIRE, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_FIRE, TYPE_WATER, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_FIRE, TYPE_GRASS, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_FIRE, TYPE_ICE, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_FIRE, TYPE_BUG, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_FIRE, TYPE_ROCK, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_FIRE, TYPE_DRAGON, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_FIRE, TYPE_STEEL, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_WATER, TYPE_FIRE, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_WATER, TYPE_WATER, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_WATER, TYPE_GRASS, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_WATER, TYPE_GROUND, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_WATER, TYPE_ROCK, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_WATER, TYPE_DRAGON, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_ELECTRIC, TYPE_WATER, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_ELECTRIC, TYPE_ELECTRIC, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_ELECTRIC, TYPE_GRASS, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_ELECTRIC, TYPE_GROUND, TYPE_MUL_NO_EFFECT,
+ TYPE_ELECTRIC, TYPE_FLYING, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_ELECTRIC, TYPE_DRAGON, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_GRASS, TYPE_FIRE, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_GRASS, TYPE_WATER, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_GRASS, TYPE_GRASS, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_GRASS, TYPE_POISON, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_GRASS, TYPE_GROUND, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_GRASS, TYPE_FLYING, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_GRASS, TYPE_BUG, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_GRASS, TYPE_ROCK, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_GRASS, TYPE_DRAGON, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_GRASS, TYPE_STEEL, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_ICE, TYPE_WATER, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_ICE, TYPE_GRASS, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_ICE, TYPE_ICE, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_ICE, TYPE_GROUND, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_ICE, TYPE_FLYING, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_ICE, TYPE_DRAGON, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_ICE, TYPE_STEEL, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_ICE, TYPE_FIRE, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_FIGHTING, TYPE_NORMAL, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_FIGHTING, TYPE_ICE, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_FIGHTING, TYPE_POISON, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_FIGHTING, TYPE_FLYING, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_FIGHTING, TYPE_PSYCHIC, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_FIGHTING, TYPE_BUG, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_FIGHTING, TYPE_ROCK, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_FIGHTING, TYPE_DARK, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_FIGHTING, TYPE_STEEL, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_POISON, TYPE_GRASS, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_POISON, TYPE_POISON, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_POISON, TYPE_GROUND, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_POISON, TYPE_ROCK, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_POISON, TYPE_GHOST, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_POISON, TYPE_STEEL, TYPE_MUL_NO_EFFECT,
+ TYPE_GROUND, TYPE_FIRE, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_GROUND, TYPE_ELECTRIC, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_GROUND, TYPE_GRASS, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_GROUND, TYPE_POISON, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_GROUND, TYPE_FLYING, TYPE_MUL_NO_EFFECT,
+ TYPE_GROUND, TYPE_BUG, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_GROUND, TYPE_ROCK, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_GROUND, TYPE_STEEL, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_FLYING, TYPE_ELECTRIC, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_FLYING, TYPE_GRASS, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_FLYING, TYPE_FIGHTING, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_FLYING, TYPE_BUG, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_FLYING, TYPE_ROCK, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_FLYING, TYPE_STEEL, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_PSYCHIC, TYPE_FIGHTING, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_PSYCHIC, TYPE_POISON, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_PSYCHIC, TYPE_PSYCHIC, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_PSYCHIC, TYPE_DARK, TYPE_MUL_NO_EFFECT,
+ TYPE_PSYCHIC, TYPE_STEEL, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_BUG, TYPE_FIRE, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_BUG, TYPE_GRASS, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_BUG, TYPE_FIGHTING, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_BUG, TYPE_POISON, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_BUG, TYPE_FLYING, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_BUG, TYPE_PSYCHIC, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_BUG, TYPE_GHOST, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_BUG, TYPE_DARK, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_BUG, TYPE_STEEL, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_ROCK, TYPE_FIRE, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_ROCK, TYPE_ICE, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_ROCK, TYPE_FIGHTING, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_ROCK, TYPE_GROUND, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_ROCK, TYPE_FLYING, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_ROCK, TYPE_BUG, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_ROCK, TYPE_STEEL, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_GHOST, TYPE_NORMAL, TYPE_MUL_NO_EFFECT,
+ TYPE_GHOST, TYPE_PSYCHIC, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_GHOST, TYPE_DARK, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_GHOST, TYPE_STEEL, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_GHOST, TYPE_GHOST, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_DRAGON, TYPE_DRAGON, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_DRAGON, TYPE_STEEL, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_DARK, TYPE_FIGHTING, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_DARK, TYPE_PSYCHIC, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_DARK, TYPE_GHOST, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_DARK, TYPE_DARK, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_DARK, TYPE_STEEL, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_STEEL, TYPE_FIRE, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_STEEL, TYPE_WATER, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_STEEL, TYPE_ELECTRIC, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_STEEL, TYPE_ICE, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_STEEL, TYPE_ROCK, TYPE_MUL_SUPER_EFFECTIVE,
+ TYPE_STEEL, TYPE_STEEL, TYPE_MUL_NOT_EFFECTIVE,
+ TYPE_FORESIGHT, TYPE_FORESIGHT, TYPE_MUL_NO_EFFECT,
+ TYPE_NORMAL, TYPE_GHOST, TYPE_MUL_NO_EFFECT,
+ TYPE_FIGHTING, TYPE_GHOST, TYPE_MUL_NO_EFFECT,
+ TYPE_ENDTABLE, TYPE_ENDTABLE, TYPE_MUL_NO_EFFECT
+};
+
+const u8 gTypeNames[][TYPE_NAME_LENGTH + 1] =
+{
+ _("NORMAL"),
+ _("FIGHT"),
+ _("FLYING"),
+ _("POISON"),
+ _("GROUND"),
+ _("ROCK"),
+ _("BUG"),
+ _("GHOST"),
+ _("STEEL"),
+ _("???"),
+ _("FIRE"),
+ _("WATER"),
+ _("GRASS"),
+ _("ELECTR"),
+ _("PSYCHC"),
+ _("ICE"),
+ _("DRAGON"),
+ _("DARK"),
+};
+
+// This is a factor in how much money you get for beating a trainer.
+const struct TrainerMoney gTrainerMoneyTable[] =
+{
+ {TRAINER_CLASS_TEAM_AQUA, 5},
+ {TRAINER_CLASS_AQUA_ADMIN, 10},
+ {TRAINER_CLASS_AQUA_LEADER, 20},
+ {TRAINER_CLASS_AROMA_LADY, 10},
+ {TRAINER_CLASS_RUIN_MANIAC, 15},
+ {TRAINER_CLASS_INTERVIEWER, 12},
+ {TRAINER_CLASS_TUBER_1, 1},
+ {TRAINER_CLASS_TUBER_2, 1},
+ {TRAINER_CLASS_SIS_AND_BRO, 3},
+ {TRAINER_CLASS_COOLTRAINER_1, 12},
+ {TRAINER_CLASS_HEX_MANIAC, 6},
+ {TRAINER_CLASS_LADY, 50},
+ {TRAINER_CLASS_BEAUTY, 20},
+ {TRAINER_CLASS_RICH_BOY, 50},
+ {TRAINER_CLASS_POKEMANIAC, 15},
+ {TRAINER_CLASS_SWIMMER_M, 2},
+ {TRAINER_CLASS_BLACK_BELT, 8},
+ {TRAINER_CLASS_GUITARIST, 8},
+ {TRAINER_CLASS_KINDLER, 8},
+ {TRAINER_CLASS_CAMPER, 4},
+ {TRAINER_CLASS_OLD_COUPLE, 10},
+ {TRAINER_CLASS_BUG_MANIAC, 15},
+ {TRAINER_CLASS_PSYCHIC, 6},
+ {TRAINER_CLASS_GENTLEMAN, 20},
+ {TRAINER_CLASS_ELITE_FOUR, 25},
+ {TRAINER_CLASS_LEADER, 25},
+ {TRAINER_CLASS_SCHOOL_KID, 5},
+ {TRAINER_CLASS_SR_AND_JR, 4},
+ {TRAINER_CLASS_POKEFAN, 20},
+ {TRAINER_CLASS_EXPERT, 10},
+ {TRAINER_CLASS_YOUNGSTER, 4},
+ {TRAINER_CLASS_CHAMPION, 50},
+ {TRAINER_CLASS_FISHERMAN, 10},
+ {TRAINER_CLASS_TRIATHLETE, 10},
+ {TRAINER_CLASS_DRAGON_TAMER, 12},
+ {TRAINER_CLASS_BIRD_KEEPER, 8},
+ {TRAINER_CLASS_NINJA_BOY, 3},
+ {TRAINER_CLASS_BATTLE_GIRL, 6},
+ {TRAINER_CLASS_PARASOL_LADY, 10},
+ {TRAINER_CLASS_SWIMMER_F, 2},
+ {TRAINER_CLASS_PICNICKER, 4},
+ {TRAINER_CLASS_TWINS, 3},
+ {TRAINER_CLASS_SAILOR, 8},
+ {TRAINER_CLASS_COLLECTOR, 15},
+ {TRAINER_CLASS_PKMN_TRAINER_3, 15},
+ {TRAINER_CLASS_PKMN_BREEDER, 10},
+ {TRAINER_CLASS_PKMN_RANGER, 12},
+ {TRAINER_CLASS_TEAM_MAGMA, 5},
+ {TRAINER_CLASS_MAGMA_ADMIN, 10},
+ {TRAINER_CLASS_MAGMA_LEADER, 20},
+ {TRAINER_CLASS_LASS, 4},
+ {TRAINER_CLASS_BUG_CATCHER, 4},
+ {TRAINER_CLASS_HIKER, 10},
+ {TRAINER_CLASS_YOUNG_COUPLE, 8},
+ {TRAINER_CLASS_WINSTRATE, 10},
+ {0xFF, 5},
+};
+
+#include "data/text/abilities.h"
+
static void (* const sTurnActionsFuncsTable[])(void) =
{
HandleAction_UseMove, // B_ACTION_USE_MOVE
@@ -738,7 +941,7 @@ static void CB2_HandleStartBattle(void)
sub_805EF14();
gBattleCommunication[MULTIUSE_STATE] = 1;
}
- if (gLinkVSyncDisabled)
+ if (gWirelessCommType)
sub_800E0E8();
break;
case 1:
@@ -762,8 +965,8 @@ static void CB2_HandleStartBattle(void)
SendBlock(bitmask_all_link_players_but_self(), &gBattleStruct->field_180, 32);
gBattleCommunication[MULTIUSE_STATE] = 2;
}
- if (gLinkVSyncDisabled)
- sub_800DFB4(0, 0);
+ if (gWirelessCommType)
+ CreateWirelessStatusIndicatorSprite(0, 0);
}
}
else
@@ -790,7 +993,7 @@ static void CB2_HandleStartBattle(void)
gTasks[taskId].data[4] = gBlockRecvBuffer[enemyMultiplayerId][1];
sub_8185F90(gBlockRecvBuffer[playerMultiplayerId][1]);
sub_8185F90(gBlockRecvBuffer[enemyMultiplayerId][1]);
- sub_8068AA4();
+ SetDeoxysStats();
gBattleCommunication[MULTIUSE_STATE]++;
}
break;
@@ -933,7 +1136,7 @@ static void CB2_HandleStartMultiPartnerBattle(void)
sub_805EF14();
gBattleCommunication[MULTIUSE_STATE] = 1;
}
- if (gLinkVSyncDisabled)
+ if (gWirelessCommType)
sub_800E0E8();
// fall through
case 1:
@@ -964,8 +1167,8 @@ static void CB2_HandleStartMultiPartnerBattle(void)
gBattleCommunication[MULTIUSE_STATE] = 2;
}
- if (gLinkVSyncDisabled)
- sub_800DFB4(0, 0);
+ if (gWirelessCommType)
+ CreateWirelessStatusIndicatorSprite(0, 0);
}
}
else
@@ -1202,9 +1405,9 @@ static void CB2_PreInitMultiBattle(void)
case 0:
if (gReceivedRemoteLinkPlayers != 0 && sub_800A520())
{
- gUnknown_02023058 = Alloc(sizeof(struct UnknownPokemonStruct2) * 3);
+ gUnknown_02023058 = Alloc(sizeof(struct UnknownPokemonStruct4) * 3);
sub_80379F8(0);
- SendBlock(bitmask_all_link_players_but_self(), gUnknown_02023058, sizeof(struct UnknownPokemonStruct2) * 3);
+ SendBlock(bitmask_all_link_players_but_self(), gUnknown_02023058, sizeof(struct UnknownPokemonStruct4) * 3);
gBattleCommunication[MULTIUSE_STATE]++;
}
break;
@@ -1222,12 +1425,12 @@ static void CB2_PreInitMultiBattle(void)
if ((!(gLinkPlayers[i].lp_field_18 & 1) && !(gLinkPlayers[playerMultiplierId].lp_field_18 & 1))
|| (gLinkPlayers[i].lp_field_18 & 1 && gLinkPlayers[playerMultiplierId].lp_field_18 & 1))
{
- memcpy(gUnknown_02022FF8, gBlockRecvBuffer[i], sizeof(struct UnknownPokemonStruct2) * 3);
+ memcpy(gUnknown_02022FF8, gBlockRecvBuffer[i], sizeof(struct UnknownPokemonStruct4) * 3);
}
}
else
{
- memcpy(gUnknown_02022FF8, gBlockRecvBuffer[i], sizeof(struct UnknownPokemonStruct2) * 3);
+ memcpy(gUnknown_02022FF8, gBlockRecvBuffer[i], sizeof(struct UnknownPokemonStruct4) * 3);
}
}
gBattleCommunication[MULTIUSE_STATE]++;
@@ -1241,14 +1444,14 @@ static void CB2_PreInitMultiBattle(void)
if (sub_800A520() && !gPaletteFade.active)
{
gBattleCommunication[MULTIUSE_STATE]++;
- if (gLinkVSyncDisabled)
+ if (gWirelessCommType)
sub_800ADF8();
else
sub_800AC34();
}
break;
case 3:
- if (gLinkVSyncDisabled)
+ if (gWirelessCommType)
{
if (sub_8010500())
{
@@ -1286,7 +1489,7 @@ static void CB2_PreInitIngamePlayerPartnerBattle(void)
switch (gBattleCommunication[MULTIUSE_STATE])
{
case 0:
- gUnknown_02023058 = Alloc(sizeof(struct UnknownPokemonStruct2) * 3);
+ gUnknown_02023058 = Alloc(sizeof(struct UnknownPokemonStruct4) * 3);
sub_80379F8(3);
gBattleCommunication[MULTIUSE_STATE]++;
*savedCallback = gMain.savedCallback;
@@ -1333,7 +1536,7 @@ static void CB2_HandleStartMultiBattle(void)
sub_805EF14();
gBattleCommunication[MULTIUSE_STATE] = 1;
}
- if (gLinkVSyncDisabled)
+ if (gWirelessCommType)
sub_800E0E8();
break;
case 1:
@@ -1351,8 +1554,8 @@ static void CB2_HandleStartMultiBattle(void)
SendBlock(bitmask_all_link_players_but_self(), &gBattleStruct->field_180, 32);
gBattleCommunication[MULTIUSE_STATE]++;
}
- if (gLinkVSyncDisabled)
- sub_800DFB4(0, 0);
+ if (gWirelessCommType)
+ CreateWirelessStatusIndicatorSprite(0, 0);
}
}
else
@@ -1369,7 +1572,7 @@ static void CB2_HandleStartMultiBattle(void)
ResetBlockReceivedFlags();
sub_8036EB8(4, playerMultiplayerId);
SetAllPlayersBerryData();
- sub_8068AA4();
+ SetDeoxysStats();
var = CreateTask(sub_8035D74, 0);
gTasks[var].data[1] = 0x10E;
gTasks[var].data[2] = 0x5A;
@@ -1627,7 +1830,7 @@ static void FreeRestoreBattleData(void)
gScanlineEffect.state = 3;
gMain.inBattle = 0;
ZeroEnemyPartyMons();
- m4aSongNumStop(0x5A);
+ m4aSongNumStop(SE_HINSI);
FreeMonSpritesGfx();
FreeBattleSpritesData();
FreeBattleResources();
@@ -2136,12 +2339,12 @@ static void sub_8038F34(void)
}
break;
case 8:
- if (!gLinkVSyncDisabled)
+ if (!gWirelessCommType)
sub_800AC34();
gBattleCommunication[MULTIUSE_STATE]++;
break;
case 9:
- if (!gMain.field_439_x4 || gLinkVSyncDisabled || gReceivedRemoteLinkPlayers != 1)
+ if (!gMain.field_439_x4 || gWirelessCommType || gReceivedRemoteLinkPlayers != 1)
{
gMain.field_439_x4 = 0;
SetMainCallback2(gMain.savedCallback);
@@ -2320,13 +2523,13 @@ static void sub_803939C(void)
case 8:
if (--gBattleCommunication[1] == 0)
{
- if (gMain.field_439_x4 && !gLinkVSyncDisabled)
+ if (gMain.field_439_x4 && !gWirelessCommType)
sub_800AC34();
gBattleCommunication[MULTIUSE_STATE]++;
}
break;
case 9:
- if (!gMain.field_439_x4 || gLinkVSyncDisabled || gReceivedRemoteLinkPlayers != 1)
+ if (!gMain.field_439_x4 || gWirelessCommType || gReceivedRemoteLinkPlayers != 1)
{
gMain.field_439_x4 = 0;
if (!gPaletteFade.active)
@@ -3387,9 +3590,8 @@ static void BattleIntroOpponent1SendsOutMonAnimation(void)
gBattleMainFunc = BattleIntroRecordMonsToDex;
}
-
#else
-__attribute__((naked))
+NAKED
static void BattleIntroOpponent1SendsOutMonAnimation(void)
{
asm(".syntax unified\n\
@@ -3474,7 +3676,6 @@ _0803B2F2:\n\
.pool\n\
.syntax divided");
}
-
#endif // NONMATCHING
static void BattleIntroRecordMonsToDex(void)
@@ -3835,8 +4036,7 @@ u8 IsRunningFromBattleImpossible(void)
}
if (side != GetBattlerSide(i)
&& gBattleMons[gActiveBattler].ability != ABILITY_LEVITATE
- && gBattleMons[gActiveBattler].type1 != TYPE_FLYING
- && gBattleMons[gActiveBattler].type2 != TYPE_FLYING
+ && !IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_FLYING)
&& gBattleMons[i].ability == ABILITY_ARENA_TRAP)
{
gBattleScripting.battler = i;
@@ -3846,7 +4046,7 @@ u8 IsRunningFromBattleImpossible(void)
}
}
i = AbilityBattleEffects(ABILITYEFFECT_CHECK_FIELD_EXCEPT_BANK, gActiveBattler, ABILITY_MAGNET_PULL, 0, 0);
- if (i != 0 && (gBattleMons[gActiveBattler].type1 == TYPE_STEEL || gBattleMons[gActiveBattler].type2 == TYPE_STEEL))
+ if (i != 0 && IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_STEEL))
{
gBattleScripting.battler = i - 1;
gLastUsedAbility = gBattleMons[i - 1].ability;
@@ -4033,12 +4233,10 @@ static void HandleTurnActionSelectionState(void)
}
else if ((i = AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, gActiveBattler, ABILITY_SHADOW_TAG, 0, 0))
|| ((i = AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, gActiveBattler, ABILITY_ARENA_TRAP, 0, 0))
- && gBattleMons[gActiveBattler].type1 != TYPE_FLYING
- && gBattleMons[gActiveBattler].type2 != TYPE_FLYING
+ && !IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_FLYING)
&& gBattleMons[gActiveBattler].ability != ABILITY_LEVITATE)
|| ((i = AbilityBattleEffects(ABILITYEFFECT_CHECK_FIELD_EXCEPT_BANK, gActiveBattler, ABILITY_MAGNET_PULL, 0, 0))
- && (gBattleMons[gActiveBattler].type1 == TYPE_STEEL
- || gBattleMons[gActiveBattler].type2 == TYPE_STEEL)))
+ && IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_STEEL)))
{
BtlController_EmitChoosePokemon(0, ((i - 1) << 4) | 4, 6, gLastUsedAbility, gBattleStruct->field_60[gActiveBattler]);
}
@@ -5026,7 +5224,7 @@ static void ReturnFromBattleToOverworld(void)
SetRoamerInactive();
}
- m4aSongNumStop(0x5A);
+ m4aSongNumStop(SE_HINSI);
SetMainCallback2(gMain.savedCallback);
}
@@ -5133,7 +5331,7 @@ static void HandleAction_UseMove(void)
else if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
&& gSideTimers[side].followmeTimer == 0
&& (gBattleMoves[gCurrentMove].power != 0
- || gBattleMoves[gCurrentMove].target != MOVE_TARGET_x10)
+ || gBattleMoves[gCurrentMove].target != MOVE_TARGET_USER)
&& gBattleMons[*(gBattleStruct->moveTarget + gBattlerAttacker)].ability != ABILITY_LIGHTNING_ROD
&& gBattleMoves[gCurrentMove].type == TYPE_ELECTRIC)
{
diff --git a/src/battle_message.c b/src/battle_message.c
index 2b9783f1a..1f338db92 100644
--- a/src/battle_message.c
+++ b/src/battle_message.c
@@ -22,9 +22,7 @@ extern u8 gUnknown_0203C7B4;
extern struct StringInfoBattle *gStringInfo;
extern const u8 gMoveNames[LAST_MOVE_INDEX + 1][13];
-extern const u8 gAbilityNames[][13];
extern const u8 gTrainerClassNames[][13];
-extern const u8 gTypeNames[][7];
extern const u16 gUnknown_08D85620[];
// strings
@@ -59,832 +57,832 @@ EWRAM_DATA u8 gBattleTextBuff3[TEXT_BUFF_ARRAY_COUNT] = {0};
// const rom data
// todo: make some of those names less vague: attacker/target vs pkmn, etc.
-const u8 gText_Trainer1LoseText[] = _("{B_TRAINER1_LOSE_TEXT}");
-const u8 gText_PkmnGainedEXP[] = _("{B_BUFF1} gained{B_BUFF2}\n{B_BUFF3} EXP. Points!\p");
-const u8 gText_EmptyString4[] = _("");
-const u8 gText_ABoosted[] = _(" a boosted");
-const u8 gText_PkmnGrewToLv[] = _("{B_BUFF1} grew to\nLV. {B_BUFF2}!{UNKNOWN_A}\p");
-const u8 gText_PkmnLearnedMove[] = _("{B_BUFF1} learned\n{B_BUFF2}!{UNKNOWN_A}\p");
-const u8 gText_TryToLearnMove1[] = _("{B_BUFF1} is trying to\nlearn {B_BUFF2}.\p");
-const u8 gText_TryToLearnMove2[] = _("But, {B_BUFF1} can’t learn\nmore than four moves.\p");
-const u8 gText_TryToLearnMove3[] = _("Delete a move to make\nroom for {B_BUFF2}?");
-const u8 gText_PkmnForgotMove[] = _("{B_BUFF1} forgot\n{B_BUFF2}.\p");
-const u8 gText_StopLearningMove[] = _("{PAUSE 32}Stop learning\n{B_BUFF2}?");
-const u8 gText_DidNotLearnMove[] = _("{B_BUFF1} did not learn\n{B_BUFF2}.\p");
-const u8 gText_UseNextPkmn[] = _("Use next POKéMON?");
-const u8 gText_AttackMissed[] = _("{B_ATK_NAME_WITH_PREFIX}’s\nattack missed!");
-const u8 gText_PkmnProtectedItself[] = _("{B_DEF_NAME_WITH_PREFIX}\nprotected itself!");
-const u8 gText_AvoidedDamage[] = _("{B_DEF_NAME_WITH_PREFIX} avoided\ndamage with {B_DEF_ABILITY}!");
-const u8 gText_PkmnMakesGroundMiss[] = _("{B_DEF_NAME_WITH_PREFIX} makes GROUND\nmoves miss with {B_DEF_ABILITY}!");
-const u8 gText_PkmnAvoidedAttack[] = _("{B_DEF_NAME_WITH_PREFIX} avoided\nthe attack!");
-const u8 gText_ItDoesntAffect[] = _("It doesn’t affect\n{B_DEF_NAME_WITH_PREFIX}…");
-const u8 gText_AttackerFainted[] = _("{B_ATK_NAME_WITH_PREFIX}\nfainted!\p");
-const u8 gText_TargetFainted[] = _("{B_DEF_NAME_WITH_PREFIX}\nfainted!\p");
-const u8 gText_PlayerGotMoney[] = _("{B_PLAYER_NAME} got ¥{B_BUFF1}\nfor winning!\p");
-const u8 gText_PlayerWhiteout[] = _("{B_PLAYER_NAME} is out of\nusable POKéMON!\p");
-const u8 gText_PlayerWhiteout2[] = _("{B_PLAYER_NAME} whited out!{PAUSE_UNTIL_PRESS}");
-const u8 gText_PreventsEscape[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} prevents\nescape with {B_SCR_ACTIVE_ABILITY}!\p");
-const u8 gText_CantEscape2[] = _("Can’t escape!\p");
-const u8 gText_AttackerCantEscape[] = _("{B_ATK_NAME_WITH_PREFIX} can’t escape!");
-const u8 gText_HitXTimes[] = _("Hit {B_BUFF1} time(s)!");
-const u8 gText_PkmnFellAsleep[] = _("{B_EFF_NAME_WITH_PREFIX}\nfell asleep!");
-const u8 gText_PkmnMadeSleep[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nmade {B_EFF_NAME_WITH_PREFIX} sleep!");
-const u8 gText_PkmnAlreadyAsleep[] = _("{B_DEF_NAME_WITH_PREFIX} is\nalready asleep!");
-const u8 gText_PkmnAlreadyAsleep2[] = _("{B_ATK_NAME_WITH_PREFIX} is\nalready asleep!");
-const u8 gText_PkmnWasntAffected[] = _("{B_DEF_NAME_WITH_PREFIX}\nwasn’t affected!");
-const u8 gText_PkmnWasPoisoned[] = _("{B_EFF_NAME_WITH_PREFIX}\nwas poisoned!");
-const u8 gText_PkmnPoisonedBy[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\npoisoned {B_EFF_NAME_WITH_PREFIX}!");
-const u8 gText_PkmnHurtByPoison[] = _("{B_ATK_NAME_WITH_PREFIX} is hurt\nby poison!");
-const u8 gText_PkmnAlreadyPoisoned[] = _("{B_DEF_NAME_WITH_PREFIX} is already\npoisoned.");
-const u8 gText_PkmnBadlyPoisoned[] = _("{B_EFF_NAME_WITH_PREFIX} is badly\npoisoned!");
-const u8 gText_PkmnEnergyDrained[] = _("{B_DEF_NAME_WITH_PREFIX} had its\nenergy drained!");
-const u8 gText_PkmnWasBurned[] = _("{B_EFF_NAME_WITH_PREFIX} was burned!");
-const u8 gText_PkmnBurnedBy[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nburned {B_EFF_NAME_WITH_PREFIX}!");
-const u8 gText_PkmnHurtByBurn[] = _("{B_ATK_NAME_WITH_PREFIX} is hurt\nby its burn!");
-const u8 gText_PkmnAlreadyHasBurn[] = _("{B_DEF_NAME_WITH_PREFIX} already\nhas a burn.");
-const u8 gText_PkmnWasFrozen[] = _("{B_EFF_NAME_WITH_PREFIX} was\nfrozen solid!");
-const u8 gText_PkmnFrozenBy[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nfroze {B_EFF_NAME_WITH_PREFIX} solid!");
-const u8 gText_PkmnIsFrozen[] = _("{B_ATK_NAME_WITH_PREFIX} is\nfrozen solid!");
-const u8 gText_PkmnWasDefrosted[] = _("{B_DEF_NAME_WITH_PREFIX} was\ndefrosted!");
-const u8 gText_PkmnWasDefrosted2[] = _("{B_ATK_NAME_WITH_PREFIX} was\ndefrosted!");
-const u8 gText_PkmnWasDefrostedBy[] = _("{B_ATK_NAME_WITH_PREFIX} was\ndefrosted by {B_CURRENT_MOVE}!");
-const u8 gText_PkmnWasParalyzed[] = _("{B_EFF_NAME_WITH_PREFIX} is paralyzed!\nIt may be unable to move!");
-const u8 gText_PkmnWasParalyzedBy[] = _("{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 gText_PkmnIsParalyzed[] = _("{B_ATK_NAME_WITH_PREFIX} is paralyzed!\nIt can’t move!");
-const u8 gText_PkmnIsAlreadyParalyzed[] = _("{B_DEF_NAME_WITH_PREFIX} is\nalready paralyzed!");
-const u8 gText_PkmnHealedParalysis[] = _("{B_DEF_NAME_WITH_PREFIX} was\nhealed of paralysis!");
-const u8 gText_PkmnDreamEaten[] = _("{B_DEF_NAME_WITH_PREFIX}’s\ndream was eaten!");
-const u8 gText_StatsWontIncrease[] = _("{B_ATK_NAME_WITH_PREFIX}’s {B_BUFF1}\nwon’t go higher!");
-const u8 gText_StatsWontDecrease[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_BUFF1}\nwon’t go lower!");
-const u8 gText_TeamStoppedWorking[] = _("Your team’s {B_BUFF1}\nstopped working!");
-const u8 gText_FoeStoppedWorking[] = _("The foe’s {B_BUFF1}\nstopped working!");
-const u8 gText_PkmnIsConfused[] = _("{B_ATK_NAME_WITH_PREFIX} is\nconfused!");
-const u8 gText_PkmnHealedConfusion[] = _("{B_ATK_NAME_WITH_PREFIX} snapped\nout of confusion!");
-const u8 gText_PkmnWasConfused[] = _("{B_EFF_NAME_WITH_PREFIX} became\nconfused!");
-const u8 gText_PkmnAlreadyConfused[] = _("{B_DEF_NAME_WITH_PREFIX} is\nalready confused!");
-const u8 gText_PkmnFellInLove[] = _("{B_DEF_NAME_WITH_PREFIX}\nfell in love!");
-const u8 gText_PkmnInLove[] = _("{B_ATK_NAME_WITH_PREFIX} is in love\nwith {B_SCR_ACTIVE_NAME_WITH_PREFIX}!");
-const u8 gText_PkmnImmobilizedByLove[] = _("{B_ATK_NAME_WITH_PREFIX} is\nimmobilized by love!");
-const u8 gText_PkmnBlownAway[] = _("{B_DEF_NAME_WITH_PREFIX} was\nblown away!");
-const u8 gText_PkmnChangedType[] = _("{B_ATK_NAME_WITH_PREFIX} transformed\ninto the {B_BUFF1} type!");
-const u8 gText_PkmnFlinched[] = _("{B_ATK_NAME_WITH_PREFIX} flinched!");
-const u8 gText_PkmnRegainedHealth[] = _("{B_DEF_NAME_WITH_PREFIX} regained\nhealth!");
-const u8 gText_PkmnHPFull[] = _("{B_DEF_NAME_WITH_PREFIX}’s\nHP is full!");
-const u8 gText_PkmnRaisedSpDef[] = _("{B_ATK_PREFIX2}’s {B_CURRENT_MOVE}\nraised SP. DEF!");
-const u8 gText_PkmnRaisedSpDefALittle[] = _("{B_ATK_PREFIX2}’s {B_CURRENT_MOVE}\nraised SP. DEF a little!");
-const u8 gText_PkmnRaisedDef[] = _("{B_ATK_PREFIX2}’s {B_CURRENT_MOVE}\nraised DEFENSE!");
-const u8 gText_PkmnRaisedDefALittle[] = _("{B_ATK_PREFIX2}’s {B_CURRENT_MOVE}\nraised DEFENSE a little!");
-const u8 gText_PkmnCoveredByVeil[] = _("{B_ATK_PREFIX2}’s party is covered\nby a veil!");
-const u8 gText_PkmnUsedSafeguard[] = _("{B_DEF_NAME_WITH_PREFIX}’s party is protected\nby SAFEGUARD!");
-const u8 gText_PkmnSafeguardExpired[] = _("{B_ATK_PREFIX3}’s party is no longer\nprotected by SAFEGUARD!");
-const u8 gText_PkmnWentToSleep[] = _("{B_ATK_NAME_WITH_PREFIX} went\nto sleep!");
-const u8 gText_PkmnSleptHealthy[] = _("{B_ATK_NAME_WITH_PREFIX} slept and\nbecame healthy!");
-const u8 gText_PkmnWhippedWhirlwind[] = _("{B_ATK_NAME_WITH_PREFIX} whipped\nup a whirlwind!");
-const u8 gText_PkmnTookSunlight[] = _("{B_ATK_NAME_WITH_PREFIX} took\nin sunlight!");
-const u8 gText_PkmnLoweredHead[] = _("{B_ATK_NAME_WITH_PREFIX} lowered\nits head!");
-const u8 gText_PkmnIsGlowing[] = _("{B_ATK_NAME_WITH_PREFIX} is glowing!");
-const u8 gText_PkmnFlewHigh[] = _("{B_ATK_NAME_WITH_PREFIX} flew\nup high!");
-const u8 gText_PkmnDugHole[] = _("{B_ATK_NAME_WITH_PREFIX} dug a hole!");
-const u8 gText_PkmnHidUnderwater[] = _("{B_ATK_NAME_WITH_PREFIX} hid\nunderwater!");
-const u8 gText_PkmnSprangUp[] = _("{B_ATK_NAME_WITH_PREFIX} sprang up!");
-const u8 gText_PkmnSqueezedByBind[] = _("{B_DEF_NAME_WITH_PREFIX} was squeezed by\n{B_ATK_NAME_WITH_PREFIX}’s BIND!");
-const u8 gText_PkmnTrappedInVortex[] = _("{B_DEF_NAME_WITH_PREFIX} was trapped\nin the vortex!");
-const u8 gText_PkmnTrappedBySandTomb[] = _("{B_DEF_NAME_WITH_PREFIX} was trapped\nby SAND TOMB!");
-const u8 gText_PkmnWrappedBy[] = _("{B_DEF_NAME_WITH_PREFIX} was WRAPPED by\n{B_ATK_NAME_WITH_PREFIX}!");
-const u8 gText_PkmnClamped[] = _("{B_ATK_NAME_WITH_PREFIX} CLAMPED\n{B_DEF_NAME_WITH_PREFIX}!");
-const u8 gText_PkmnHurtBy[] = _("{B_ATK_NAME_WITH_PREFIX} is hurt\nby {B_BUFF1}!");
-const u8 gText_PkmnFreedFrom[] = _("{B_ATK_NAME_WITH_PREFIX} was freed\nfrom {B_BUFF1}!");
-const u8 gText_PkmnCrashed[] = _("{B_ATK_NAME_WITH_PREFIX} kept going\nand crashed!");
+static const u8 sText_Trainer1LoseText[] = _("{B_TRAINER1_LOSE_TEXT}");
+static const u8 sText_PkmnGainedEXP[] = _("{B_BUFF1} gained{B_BUFF2}\n{B_BUFF3} EXP. Points!\p");
+static const u8 sText_EmptyString4[] = _("");
+static const u8 sText_ABoosted[] = _(" a boosted");
+static const u8 sText_PkmnGrewToLv[] = _("{B_BUFF1} grew to\nLV. {B_BUFF2}!{UNKNOWN_A}\p");
+static const u8 sText_PkmnLearnedMove[] = _("{B_BUFF1} learned\n{B_BUFF2}!{UNKNOWN_A}\p");
+static const u8 sText_TryToLearnMove1[] = _("{B_BUFF1} is trying to\nlearn {B_BUFF2}.\p");
+static const u8 sText_TryToLearnMove2[] = _("But, {B_BUFF1} can’t learn\nmore than four moves.\p");
+static const u8 sText_TryToLearnMove3[] = _("Delete a move to make\nroom for {B_BUFF2}?");
+static const u8 sText_PkmnForgotMove[] = _("{B_BUFF1} forgot\n{B_BUFF2}.\p");
+static const u8 sText_StopLearningMove[] = _("{PAUSE 32}Stop learning\n{B_BUFF2}?");
+static const u8 sText_DidNotLearnMove[] = _("{B_BUFF1} did not learn\n{B_BUFF2}.\p");
+static const u8 sText_UseNextPkmn[] = _("Use next POKéMON?");
+static const u8 sText_AttackMissed[] = _("{B_ATK_NAME_WITH_PREFIX}’s\nattack missed!");
+static const u8 sText_PkmnProtectedItself[] = _("{B_DEF_NAME_WITH_PREFIX}\nprotected itself!");
+static const u8 sText_AvoidedDamage[] = _("{B_DEF_NAME_WITH_PREFIX} avoided\ndamage with {B_DEF_ABILITY}!");
+static const u8 sText_PkmnMakesGroundMiss[] = _("{B_DEF_NAME_WITH_PREFIX} makes GROUND\nmoves miss with {B_DEF_ABILITY}!");
+static const u8 sText_PkmnAvoidedAttack[] = _("{B_DEF_NAME_WITH_PREFIX} avoided\nthe attack!");
+static const u8 sText_ItDoesntAffect[] = _("It doesn’t affect\n{B_DEF_NAME_WITH_PREFIX}…");
+static const u8 sText_AttackerFainted[] = _("{B_ATK_NAME_WITH_PREFIX}\nfainted!\p");
+static const u8 sText_TargetFainted[] = _("{B_DEF_NAME_WITH_PREFIX}\nfainted!\p");
+static const u8 sText_PlayerGotMoney[] = _("{B_PLAYER_NAME} got ¥{B_BUFF1}\nfor winning!\p");
+static const u8 sText_PlayerWhiteout[] = _("{B_PLAYER_NAME} is out of\nusable POKéMON!\p");
+static const u8 sText_PlayerWhiteout2[] = _("{B_PLAYER_NAME} whited out!{PAUSE_UNTIL_PRESS}");
+static const u8 sText_PreventsEscape[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} prevents\nescape with {B_SCR_ACTIVE_ABILITY}!\p");
+static const u8 sText_CantEscape2[] = _("Can’t escape!\p");
+static const u8 sText_AttackerCantEscape[] = _("{B_ATK_NAME_WITH_PREFIX} can’t escape!");
+static const u8 sText_HitXTimes[] = _("Hit {B_BUFF1} time(s)!");
+static const u8 sText_PkmnFellAsleep[] = _("{B_EFF_NAME_WITH_PREFIX}\nfell asleep!");
+static const u8 sText_PkmnMadeSleep[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nmade {B_EFF_NAME_WITH_PREFIX} sleep!");
+static const u8 sText_PkmnAlreadyAsleep[] = _("{B_DEF_NAME_WITH_PREFIX} is\nalready asleep!");
+static const u8 sText_PkmnAlreadyAsleep2[] = _("{B_ATK_NAME_WITH_PREFIX} is\nalready asleep!");
+static const u8 sText_PkmnWasntAffected[] = _("{B_DEF_NAME_WITH_PREFIX}\nwasn’t affected!");
+static const u8 sText_PkmnWasPoisoned[] = _("{B_EFF_NAME_WITH_PREFIX}\nwas poisoned!");
+static const u8 sText_PkmnPoisonedBy[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\npoisoned {B_EFF_NAME_WITH_PREFIX}!");
+static const u8 sText_PkmnHurtByPoison[] = _("{B_ATK_NAME_WITH_PREFIX} is hurt\nby poison!");
+static const u8 sText_PkmnAlreadyPoisoned[] = _("{B_DEF_NAME_WITH_PREFIX} is already\npoisoned.");
+static const u8 sText_PkmnBadlyPoisoned[] = _("{B_EFF_NAME_WITH_PREFIX} is badly\npoisoned!");
+static const u8 sText_PkmnEnergyDrained[] = _("{B_DEF_NAME_WITH_PREFIX} had its\nenergy drained!");
+static const u8 sText_PkmnWasBurned[] = _("{B_EFF_NAME_WITH_PREFIX} was burned!");
+static const u8 sText_PkmnBurnedBy[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nburned {B_EFF_NAME_WITH_PREFIX}!");
+static const u8 sText_PkmnHurtByBurn[] = _("{B_ATK_NAME_WITH_PREFIX} is hurt\nby its burn!");
+static const u8 sText_PkmnAlreadyHasBurn[] = _("{B_DEF_NAME_WITH_PREFIX} already\nhas a burn.");
+static const u8 sText_PkmnWasFrozen[] = _("{B_EFF_NAME_WITH_PREFIX} was\nfrozen solid!");
+static const u8 sText_PkmnFrozenBy[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nfroze {B_EFF_NAME_WITH_PREFIX} solid!");
+static const u8 sText_PkmnIsFrozen[] = _("{B_ATK_NAME_WITH_PREFIX} is\nfrozen solid!");
+static const u8 sText_PkmnWasDefrosted[] = _("{B_DEF_NAME_WITH_PREFIX} was\ndefrosted!");
+static const u8 sText_PkmnWasDefrosted2[] = _("{B_ATK_NAME_WITH_PREFIX} was\ndefrosted!");
+static const u8 sText_PkmnWasDefrostedBy[] = _("{B_ATK_NAME_WITH_PREFIX} was\ndefrosted by {B_CURRENT_MOVE}!");
+static const u8 sText_PkmnWasParalyzed[] = _("{B_EFF_NAME_WITH_PREFIX} is paralyzed!\nIt may be unable to move!");
+static const u8 sText_PkmnWasParalyzedBy[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nparalyzed {B_EFF_NAME_WITH_PREFIX}!\lIt may be unable to move!");
+static const u8 sText_PkmnIsParalyzed[] = _("{B_ATK_NAME_WITH_PREFIX} is paralyzed!\nIt can’t move!");
+static const u8 sText_PkmnIsAlreadyParalyzed[] = _("{B_DEF_NAME_WITH_PREFIX} is\nalready paralyzed!");
+static const u8 sText_PkmnHealedParalysis[] = _("{B_DEF_NAME_WITH_PREFIX} was\nhealed of paralysis!");
+static const u8 sText_PkmnDreamEaten[] = _("{B_DEF_NAME_WITH_PREFIX}’s\ndream was eaten!");
+static const u8 sText_StatsWontIncrease[] = _("{B_ATK_NAME_WITH_PREFIX}’s {B_BUFF1}\nwon’t go higher!");
+static const u8 sText_StatsWontDecrease[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_BUFF1}\nwon’t go lower!");
+static const u8 sText_TeamStoppedWorking[] = _("Your team’s {B_BUFF1}\nstopped working!");
+static const u8 sText_FoeStoppedWorking[] = _("The foe’s {B_BUFF1}\nstopped working!");
+static const u8 sText_PkmnIsConfused[] = _("{B_ATK_NAME_WITH_PREFIX} is\nconfused!");
+static const u8 sText_PkmnHealedConfusion[] = _("{B_ATK_NAME_WITH_PREFIX} snapped\nout of confusion!");
+static const u8 sText_PkmnWasConfused[] = _("{B_EFF_NAME_WITH_PREFIX} became\nconfused!");
+static const u8 sText_PkmnAlreadyConfused[] = _("{B_DEF_NAME_WITH_PREFIX} is\nalready confused!");
+static const u8 sText_PkmnFellInLove[] = _("{B_DEF_NAME_WITH_PREFIX}\nfell in love!");
+static const u8 sText_PkmnInLove[] = _("{B_ATK_NAME_WITH_PREFIX} is in love\nwith {B_SCR_ACTIVE_NAME_WITH_PREFIX}!");
+static const u8 sText_PkmnImmobilizedByLove[] = _("{B_ATK_NAME_WITH_PREFIX} is\nimmobilized by love!");
+static const u8 sText_PkmnBlownAway[] = _("{B_DEF_NAME_WITH_PREFIX} was\nblown away!");
+static const u8 sText_PkmnChangedType[] = _("{B_ATK_NAME_WITH_PREFIX} transformed\ninto the {B_BUFF1} type!");
+static const u8 sText_PkmnFlinched[] = _("{B_ATK_NAME_WITH_PREFIX} flinched!");
+static const u8 sText_PkmnRegainedHealth[] = _("{B_DEF_NAME_WITH_PREFIX} regained\nhealth!");
+static const u8 sText_PkmnHPFull[] = _("{B_DEF_NAME_WITH_PREFIX}’s\nHP is full!");
+static const u8 sText_PkmnRaisedSpDef[] = _("{B_ATK_PREFIX2}’s {B_CURRENT_MOVE}\nraised SP. DEF!");
+static const u8 sText_PkmnRaisedSpDefALittle[] = _("{B_ATK_PREFIX2}’s {B_CURRENT_MOVE}\nraised SP. DEF a little!");
+static const u8 sText_PkmnRaisedDef[] = _("{B_ATK_PREFIX2}’s {B_CURRENT_MOVE}\nraised DEFENSE!");
+static const u8 sText_PkmnRaisedDefALittle[] = _("{B_ATK_PREFIX2}’s {B_CURRENT_MOVE}\nraised DEFENSE a little!");
+static const u8 sText_PkmnCoveredByVeil[] = _("{B_ATK_PREFIX2}’s party is covered\nby a veil!");
+static const u8 sText_PkmnUsedSafeguard[] = _("{B_DEF_NAME_WITH_PREFIX}’s party is protected\nby SAFEGUARD!");
+static const u8 sText_PkmnSafeguardExpired[] = _("{B_ATK_PREFIX3}’s party is no longer\nprotected by SAFEGUARD!");
+static const u8 sText_PkmnWentToSleep[] = _("{B_ATK_NAME_WITH_PREFIX} went\nto sleep!");
+static const u8 sText_PkmnSleptHealthy[] = _("{B_ATK_NAME_WITH_PREFIX} slept and\nbecame healthy!");
+static const u8 sText_PkmnWhippedWhirlwind[] = _("{B_ATK_NAME_WITH_PREFIX} whipped\nup a whirlwind!");
+static const u8 sText_PkmnTookSunlight[] = _("{B_ATK_NAME_WITH_PREFIX} took\nin sunlight!");
+static const u8 sText_PkmnLoweredHead[] = _("{B_ATK_NAME_WITH_PREFIX} lowered\nits head!");
+static const u8 sText_PkmnIsGlowing[] = _("{B_ATK_NAME_WITH_PREFIX} is glowing!");
+static const u8 sText_PkmnFlewHigh[] = _("{B_ATK_NAME_WITH_PREFIX} flew\nup high!");
+static const u8 sText_PkmnDugHole[] = _("{B_ATK_NAME_WITH_PREFIX} dug a hole!");
+static const u8 sText_PkmnHidUnderwater[] = _("{B_ATK_NAME_WITH_PREFIX} hid\nunderwater!");
+static const u8 sText_PkmnSprangUp[] = _("{B_ATK_NAME_WITH_PREFIX} sprang up!");
+static const u8 sText_PkmnSqueezedByBind[] = _("{B_DEF_NAME_WITH_PREFIX} was squeezed by\n{B_ATK_NAME_WITH_PREFIX}’s BIND!");
+static const u8 sText_PkmnTrappedInVortex[] = _("{B_DEF_NAME_WITH_PREFIX} was trapped\nin the vortex!");
+static const u8 sText_PkmnTrappedBySandTomb[] = _("{B_DEF_NAME_WITH_PREFIX} was trapped\nby SAND TOMB!");
+static const u8 sText_PkmnWrappedBy[] = _("{B_DEF_NAME_WITH_PREFIX} was WRAPPED by\n{B_ATK_NAME_WITH_PREFIX}!");
+static const u8 sText_PkmnClamped[] = _("{B_ATK_NAME_WITH_PREFIX} CLAMPED\n{B_DEF_NAME_WITH_PREFIX}!");
+static const u8 sText_PkmnHurtBy[] = _("{B_ATK_NAME_WITH_PREFIX} is hurt\nby {B_BUFF1}!");
+static const u8 sText_PkmnFreedFrom[] = _("{B_ATK_NAME_WITH_PREFIX} was freed\nfrom {B_BUFF1}!");
+static const u8 sText_PkmnCrashed[] = _("{B_ATK_NAME_WITH_PREFIX} kept going\nand crashed!");
const u8 gText_PkmnShroudedInMist[] = _("{B_ATK_PREFIX2} became\nshrouded in MIST!");
-const u8 gText_PkmnProtectedByMist[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is protected\nby MIST!");
+static const u8 sText_PkmnProtectedByMist[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is protected\nby MIST!");
const u8 gText_PkmnGettingPumped[] = _("{B_ATK_NAME_WITH_PREFIX} is getting\npumped!");
-const u8 gText_PkmnHitWithRecoil[] = _("{B_ATK_NAME_WITH_PREFIX} is hit\nwith recoil!");
-const u8 gText_PkmnProtectedItself2[] = _("{B_ATK_NAME_WITH_PREFIX} protected\nitself!");
-const u8 gText_PkmnBuffetedBySandstorm[] = _("{B_ATK_NAME_WITH_PREFIX} is buffeted\nby the sandstorm!");
-const u8 gText_PkmnPeltedByHail[] = _("{B_ATK_NAME_WITH_PREFIX} is pelted\nby HAIL!");
-const u8 gText_PkmnsXWoreOff[] = _("{B_ATK_PREFIX1}’s {B_BUFF1}\nwore off!");
-const u8 gText_PkmnSeeded[] = _("{B_DEF_NAME_WITH_PREFIX} was seeded!");
-const u8 gText_PkmnEvadedAttack[] = _("{B_DEF_NAME_WITH_PREFIX} evaded\nthe attack!");
-const u8 gText_PkmnSappedByLeechSeed[] = _("{B_ATK_NAME_WITH_PREFIX}’s health is\nsapped by LEECH SEED!");
-const u8 gText_PkmnFastAsleep[] = _("{B_ATK_NAME_WITH_PREFIX} is fast\nasleep.");
-const u8 gText_PkmnWokeUp[] = _("{B_ATK_NAME_WITH_PREFIX} woke up!");
-const u8 gText_PkmnUproarKeptAwake[] = _("But {B_SCR_ACTIVE_NAME_WITH_PREFIX}’s UPROAR\nkept it awake!");
-const u8 gText_PkmnWokeUpInUproar[] = _("{B_ATK_NAME_WITH_PREFIX} woke up\nin the UPROAR!");
-const u8 gText_PkmnCausedUproar[] = _("{B_ATK_NAME_WITH_PREFIX} caused\nan UPROAR!");
-const u8 gText_PkmnMakingUproar[] = _("{B_ATK_NAME_WITH_PREFIX} is making\nan UPROAR!");
-const u8 gText_PkmnCalmedDown[] = _("{B_ATK_NAME_WITH_PREFIX} calmed down.");
-const u8 gText_PkmnCantSleepInUproar[] = _("But {B_DEF_NAME_WITH_PREFIX} can’t\nsleep in an UPROAR!");
-const u8 gText_PkmnStockpiled[] = _("{B_ATK_NAME_WITH_PREFIX} STOCKPILED\n{B_BUFF1}!");
-const u8 gText_PkmnCantStockpile[] = _("{B_ATK_NAME_WITH_PREFIX} can’t\nSTOCKPILE any more!");
-const u8 gText_PkmnCantSleepInUproar2[] = _("But {B_DEF_NAME_WITH_PREFIX} can’t\nsleep in an UPROAR!");
-const u8 gText_UproarKeptPkmnAwake[] = _("But the UPROAR kept\n{B_DEF_NAME_WITH_PREFIX} awake!");
-const u8 gText_PkmnStayedAwakeUsing[] = _("{B_DEF_NAME_WITH_PREFIX} stayed awake\nusing its {B_DEF_ABILITY}!");
-const u8 gText_PkmnStoringEnergy[] = _("{B_ATK_NAME_WITH_PREFIX} is storing\nenergy!");
-const u8 gText_PkmnUnleashedEnergy[] = _("{B_ATK_NAME_WITH_PREFIX} unleashed\nenergy!");
-const u8 gText_PkmnFatigueConfusion[] = _("{B_ATK_NAME_WITH_PREFIX} became\nconfused due to fatigue!");
-const u8 gText_PkmnPickedUpItem[] = _("{B_PLAYER_NAME} picked up\n¥{B_BUFF1}!\p");
-const u8 gText_PkmnUnaffected[] = _("{B_DEF_NAME_WITH_PREFIX} is\nunaffected!");
-const u8 gText_PkmnTransformedInto[] = _("{B_ATK_NAME_WITH_PREFIX} transformed\ninto {B_BUFF1}!");
-const u8 gText_PkmnMadeSubstitute[] = _("{B_ATK_NAME_WITH_PREFIX} made\na SUBSTITUTE!");
-const u8 gText_PkmnHasSubstitute[] = _("{B_ATK_NAME_WITH_PREFIX} already\nhas a SUBSTITUTE!");
-const u8 gText_SubstituteDamaged[] = _("The SUBSTITUTE took damage\nfor {B_DEF_NAME_WITH_PREFIX}!\p");
-const u8 gText_PkmnSubstituteFaded[] = _("{B_DEF_NAME_WITH_PREFIX}’s\nSUBSTITUTE faded!\p");
-const u8 gText_PkmnMustRecharge[] = _("{B_ATK_NAME_WITH_PREFIX} must\nrecharge!");
-const u8 gText_PkmnRageBuilding[] = _("{B_DEF_NAME_WITH_PREFIX}’s RAGE\nis building!");
-const u8 gText_PkmnMoveWasDisabled[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_BUFF1}\nwas disabled!");
-const u8 gText_PkmnMoveDisabledNoMore[] = _("{B_ATK_NAME_WITH_PREFIX} is disabled\nno more!");
-const u8 gText_PkmnGotEncore[] = _("{B_DEF_NAME_WITH_PREFIX} got\nan ENCORE!");
-const u8 gText_PkmnEncoreEnded[] = _("{B_ATK_NAME_WITH_PREFIX}’s ENCORE\nended!");
-const u8 gText_PkmnTookAim[] = _("{B_ATK_NAME_WITH_PREFIX} took aim\nat {B_DEF_NAME_WITH_PREFIX}!");
-const u8 gText_PkmnSketchedMove[] = _("{B_ATK_NAME_WITH_PREFIX} SKETCHED\n{B_BUFF1}!");
-const u8 gText_PkmnTryingToTakeFoe[] = _("{B_ATK_NAME_WITH_PREFIX} is trying\nto take its foe with it!");
-const u8 gText_PkmnTookFoe[] = _("{B_DEF_NAME_WITH_PREFIX} took\n{B_ATK_NAME_WITH_PREFIX} with it!");
-const u8 gText_PkmnReducedPP[] = _("Reduced {B_DEF_NAME_WITH_PREFIX}’s\n{B_BUFF1} by {B_BUFF2}!");
-const u8 gText_PkmnStoleItem[] = _("{B_ATK_NAME_WITH_PREFIX} stole\n{B_DEF_NAME_WITH_PREFIX}’s {B_LAST_ITEM}!");
-const u8 gText_TargetCantEscapeNow[] = _("{B_DEF_NAME_WITH_PREFIX} can’t\nescape now!");
-const u8 gText_PkmnFellIntoNightmare[] = _("{B_DEF_NAME_WITH_PREFIX} fell into\na NIGHTMARE!");
-const u8 gText_PkmnLockedInNightmare[] = _("{B_ATK_NAME_WITH_PREFIX} is locked\nin a NIGHTMARE!");
-const u8 gText_PkmnLaidCurse[] = _("{B_ATK_NAME_WITH_PREFIX} cut its own HP and\nlaid a CURSE on {B_DEF_NAME_WITH_PREFIX}!");
-const u8 gText_PkmnAfflictedByCurse[] = _("{B_ATK_NAME_WITH_PREFIX} is afflicted\nby the CURSE!");
-const u8 gText_SpikesScattered[] = _("SPIKES were scattered all around\nthe opponent’s side!");
-const u8 gText_PkmnHurtBySpikes[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is hurt\nby SPIKES!");
-const u8 gText_PkmnIdentified[] = _("{B_ATK_NAME_WITH_PREFIX} identified\n{B_DEF_NAME_WITH_PREFIX}!");
-const u8 gText_PkmnPerishCountFell[] = _("{B_ATK_NAME_WITH_PREFIX}’s PERISH count\nfell to {B_BUFF1}!");
-const u8 gText_PkmnBracedItself[] = _("{B_ATK_NAME_WITH_PREFIX} braced\nitself!");
-const u8 gText_PkmnEnduredHit[] = _("{B_DEF_NAME_WITH_PREFIX} ENDURED\nthe hit!");
-const u8 gText_MagnitudeStrength[] = _("MAGNITUDE {B_BUFF1}!");
-const u8 gText_PkmnCutHPMaxedAttack[] = _("{B_ATK_NAME_WITH_PREFIX} cut its own HP\nand maximized ATTACK!");
-const u8 gText_PkmnCopiedStatChanges[] = _("{B_ATK_NAME_WITH_PREFIX} copied\n{B_DEF_NAME_WITH_PREFIX}’s stat changes!");
-const u8 gText_PkmnGotFree[] = _("{B_ATK_NAME_WITH_PREFIX} got free of\n{B_DEF_NAME_WITH_PREFIX}’s {B_BUFF1}!");
-const u8 gText_PkmnShedLeechSeed[] = _("{B_ATK_NAME_WITH_PREFIX} shed\nLEECH SEED!");
-const u8 gText_PkmnBlewAwaySpikes[] = _("{B_ATK_NAME_WITH_PREFIX} blew away\nSPIKES!");
-const u8 gText_PkmnFledFromBattle[] = _("{B_ATK_NAME_WITH_PREFIX} fled from\nbattle!");
-const u8 gText_PkmnForesawAttack[] = _("{B_ATK_NAME_WITH_PREFIX} foresaw\nan attack!");
-const u8 gText_PkmnTookAttack[] = _("{B_DEF_NAME_WITH_PREFIX} took the\n{B_BUFF1} attack!");
-const u8 gText_PkmnChoseXAsDestiny[] = _("{B_ATK_NAME_WITH_PREFIX} chose\n{B_CURRENT_MOVE} as its destiny!");
-const u8 gText_PkmnAttack[] = _("{B_BUFF1}’s attack!");
-const u8 gText_PkmnCenterAttention[] = _("{B_ATK_NAME_WITH_PREFIX} became the\ncenter of attention!");
-const u8 gText_PkmnChargingPower[] = _("{B_ATK_NAME_WITH_PREFIX} began\ncharging power!");
-const u8 gText_NaturePowerTurnedInto[] = _("NATURE POWER turned into\n{B_CURRENT_MOVE}!");
-const u8 gText_PkmnStatusNormal[] = _("{B_ATK_NAME_WITH_PREFIX}’s status\nreturned to normal!");
-const u8 gText_PkmnSubjectedToTorment[] = _("{B_DEF_NAME_WITH_PREFIX} was subjected\nto TORMENT!");
-const u8 gText_PkmnTighteningFocus[] = _("{B_ATK_NAME_WITH_PREFIX} is tightening\nits focus!");
-const u8 gText_PkmnFellForTaunt[] = _("{B_DEF_NAME_WITH_PREFIX} fell for\nthe TAUNT!");
-const u8 gText_PkmnReadyToHelp[] = _("{B_ATK_NAME_WITH_PREFIX} is ready to\nhelp {B_DEF_NAME_WITH_PREFIX}!");
-const u8 gText_PkmnSwitchedItems[] = _("{B_ATK_NAME_WITH_PREFIX} switched\nitems with its opponent!");
-const u8 gText_PkmnObtainedX[] = _("{B_ATK_NAME_WITH_PREFIX} obtained\n{B_BUFF1}.");
-const u8 gText_PkmnObtainedX2[] = _("{B_DEF_NAME_WITH_PREFIX} obtained\n{B_BUFF2}.");
-const u8 gText_PkmnObtainedXYObtainedZ[] = _("{B_ATK_NAME_WITH_PREFIX} obtained\n{B_BUFF1}.\p{B_DEF_NAME_WITH_PREFIX} obtained\n{B_BUFF2}.");
-const u8 gText_PkmnCopiedFoe[] = _("{B_ATK_NAME_WITH_PREFIX} copied\n{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}!");
-const u8 gText_PkmnMadeWish[] = _("{B_ATK_NAME_WITH_PREFIX} made a WISH!");
-const u8 gText_PkmnWishCameTrue[] = _("{B_BUFF1}’s WISH\ncame true!");
-const u8 gText_PkmnPlantedRoots[] = _("{B_ATK_NAME_WITH_PREFIX} planted its roots!");
-const u8 gText_PkmnAbsorbedNutrients[] = _("{B_ATK_NAME_WITH_PREFIX} absorbed\nnutrients with its roots!");
-const u8 gText_PkmnAnchoredItself[] = _("{B_DEF_NAME_WITH_PREFIX} anchored\nitself with its roots!");
-const u8 gText_PkmnWasMadeDrowsy[] = _("{B_ATK_NAME_WITH_PREFIX} made\n{B_DEF_NAME_WITH_PREFIX} drowsy!");
-const u8 gText_PkmnKnockedOff[] = _("{B_ATK_NAME_WITH_PREFIX} knocked off\n{B_DEF_NAME_WITH_PREFIX}’s {B_LAST_ITEM}!");
-const u8 gText_PkmnSwappedAbilities[] = _("{B_ATK_NAME_WITH_PREFIX} swapped abilities\nwith its opponent!");
-const u8 gText_PkmnSealedOpponentMove[] = _("{B_ATK_NAME_WITH_PREFIX} sealed the\nopponent’s move(s)!");
-const u8 gText_PkmnWantsGrudge[] = _("{B_ATK_NAME_WITH_PREFIX} wants the\nopponent to bear a GRUDGE!");
-const u8 gText_PkmnLostPPGrudge[] = _("{B_ATK_NAME_WITH_PREFIX}’s {B_BUFF1} lost\nall its PP due to the GRUDGE!");
-const u8 gText_PkmnShroudedItself[] = _("{B_ATK_NAME_WITH_PREFIX} shrouded\nitself in {B_CURRENT_MOVE}!");
-const u8 gText_PkmnMoveBounced[] = _("{B_ATK_NAME_WITH_PREFIX}’s {B_CURRENT_MOVE}\nwas bounced back by MAGIC COAT!");
-const u8 gText_PkmnWaitsForTarget[] = _("{B_ATK_NAME_WITH_PREFIX} waits for a target\nto make a move!");
-const u8 gText_PkmnSnatchedMove[] = _("{B_DEF_NAME_WITH_PREFIX} SNATCHED\n{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s move!");
-const u8 gText_ElectricityWeakened[] = _("Electricity’s power was\nweakened!");
-const u8 gText_FireWeakened[] = _("Fire’s power was\nweakened!");
-const u8 gText_XFoundOneY[] = _("{B_ATK_NAME_WITH_PREFIX} found\none {B_LAST_ITEM}!");
-const u8 gText_SoothingAroma[] = _("A soothing aroma wafted\nthrough the area!");
-const u8 gText_ItemsCantBeUsedNow[] = _("Items can’t be used now.{PAUSE 64}");
-const u8 gText_ForXCommaYZ[] = _("For {B_SCR_ACTIVE_NAME_WITH_PREFIX},\n{B_LAST_ITEM} {B_BUFF1}");
-const u8 gText_PkmnUsedXToGetPumped[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} used\n{B_LAST_ITEM} to get pumped!");
-const u8 gText_PkmnLostFocus[] = _("{B_ATK_NAME_WITH_PREFIX} lost its\nfocus and couldn’t move!");
-const u8 gText_PkmnWasDraggedOut[] = _("{B_DEF_NAME_WITH_PREFIX} was\ndragged out!\p");
-const u8 gText_TheWallShattered[] = _("The wall shattered!");
-const u8 gText_ButNoEffect[] = _("But it had no effect!");
-const u8 gText_PkmnHasNoMovesLeft[] = _("{B_ACTIVE_NAME_WITH_PREFIX} has no\nmoves left!\p");
-const u8 gText_PkmnMoveIsDisabled[] = _("{B_ACTIVE_NAME_WITH_PREFIX}’s {B_CURRENT_MOVE}\nis disabled!\p");
-const u8 gText_PkmnCantUseMoveTorment[] = _("{B_ACTIVE_NAME_WITH_PREFIX} can’t use the same\nmove in a row due to the TORMENT!\p");
-const u8 gText_PkmnCantUseMoveTaunt[] = _("{B_ACTIVE_NAME_WITH_PREFIX} can’t use\n{B_CURRENT_MOVE} after the TAUNT!\p");
-const u8 gText_PkmnCantUseMoveSealed[] = _("{B_ACTIVE_NAME_WITH_PREFIX} can’t use the\nsealed {B_CURRENT_MOVE}!\p");
-const u8 gText_PkmnMadeItRain[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nmade it rain!");
-const u8 gText_PkmnRaisedSpeed[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nraised its SPEED!");
-const u8 gText_PkmnProtectedBy[] = _("{B_DEF_NAME_WITH_PREFIX} was protected\nby {B_DEF_ABILITY}!");
-const u8 gText_PkmnPreventsUsage[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nprevents {B_ATK_NAME_WITH_PREFIX}\lfrom using {B_CURRENT_MOVE}!");
-const u8 gText_PkmnRestoredHPUsing[] = _("{B_DEF_NAME_WITH_PREFIX} restored HP\nusing its {B_DEF_ABILITY}!");
-const u8 gText_PkmnsXMadeYUseless[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nmade {B_CURRENT_MOVE} useless!");
-const u8 gText_PkmnChangedTypeWith[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nmade it the {B_BUFF1} type!");
-const u8 gText_PkmnPreventsParalysisWith[] = _("{B_EFF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nprevents paralysis!");
-const u8 gText_PkmnPreventsRomanceWith[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nprevents romance!");
-const u8 gText_PkmnPreventsPoisoningWith[] = _("{B_EFF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nprevents poisoning!");
-const u8 gText_PkmnPreventsConfusionWith[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nprevents confusion!");
-const u8 gText_PkmnRaisedFirePowerWith[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nraised its FIRE power!");
-const u8 gText_PkmnAnchorsItselfWith[] = _("{B_DEF_NAME_WITH_PREFIX} anchors\nitself with {B_DEF_ABILITY}!");
-const u8 gText_PkmnCutsAttackWith[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\ncuts {B_DEF_NAME_WITH_PREFIX}’s ATTACK!");
-const u8 gText_PkmnPreventsStatLossWith[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nprevents stat loss!");
-const u8 gText_PkmnHurtsWith[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nhurt {B_ATK_NAME_WITH_PREFIX}!");
-const u8 gText_PkmnTraced[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} TRACED\n{B_BUFF1}’s {B_BUFF2}!");
-const u8 gText_PkmnsXPreventsBurns[] = _("{B_EFF_NAME_WITH_PREFIX}’s {B_EFF_ABILITY}\nprevents burns!");
-const u8 gText_PkmnsXBlocksY[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nblocks {B_CURRENT_MOVE}!");
-const u8 gText_PkmnsXBlocksY2[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nblocks {B_CURRENT_MOVE}!");
-const u8 gText_PkmnsXRestoredHPALittle2[] = _("{B_ATK_NAME_WITH_PREFIX}’s {B_ATK_ABILITY}\nrestored its HP a little!");
-const u8 gText_PkmnsXWhippedUpSandstorm[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nwhipped up a sandstorm!");
-const u8 gText_PkmnsXIntensifiedSun[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nintensified the sun’s rays!");
-const u8 gText_PkmnsXPreventsYLoss[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nprevents {B_BUFF1} loss!");
-const u8 gText_PkmnsXInfatuatedY[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\ninfatuated {B_ATK_NAME_WITH_PREFIX}!");
-const u8 gText_PkmnsXMadeYIneffective[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nmade {B_CURRENT_MOVE} ineffective!");
-const u8 gText_PkmnsXCuredYProblem[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\ncured its {B_BUFF1} problem!");
-const u8 gText_ItSuckedLiquidOoze[] = _("It sucked up the\nLIQUID OOZE!");
-const u8 gText_PkmnTransformed[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} transformed!");
-const u8 gText_PkmnsXTookAttack[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\ntook the attack!");
+static const u8 sText_PkmnHitWithRecoil[] = _("{B_ATK_NAME_WITH_PREFIX} is hit\nwith recoil!");
+static const u8 sText_PkmnProtectedItself2[] = _("{B_ATK_NAME_WITH_PREFIX} protected\nitself!");
+static const u8 sText_PkmnBuffetedBySandstorm[] = _("{B_ATK_NAME_WITH_PREFIX} is buffeted\nby the sandstorm!");
+static const u8 sText_PkmnPeltedByHail[] = _("{B_ATK_NAME_WITH_PREFIX} is pelted\nby HAIL!");
+static const u8 sText_PkmnsXWoreOff[] = _("{B_ATK_PREFIX1}’s {B_BUFF1}\nwore off!");
+static const u8 sText_PkmnSeeded[] = _("{B_DEF_NAME_WITH_PREFIX} was seeded!");
+static const u8 sText_PkmnEvadedAttack[] = _("{B_DEF_NAME_WITH_PREFIX} evaded\nthe attack!");
+static const u8 sText_PkmnSappedByLeechSeed[] = _("{B_ATK_NAME_WITH_PREFIX}’s health is\nsapped by LEECH SEED!");
+static const u8 sText_PkmnFastAsleep[] = _("{B_ATK_NAME_WITH_PREFIX} is fast\nasleep.");
+static const u8 sText_PkmnWokeUp[] = _("{B_ATK_NAME_WITH_PREFIX} woke up!");
+static const u8 sText_PkmnUproarKeptAwake[] = _("But {B_SCR_ACTIVE_NAME_WITH_PREFIX}’s UPROAR\nkept it awake!");
+static const u8 sText_PkmnWokeUpInUproar[] = _("{B_ATK_NAME_WITH_PREFIX} woke up\nin the UPROAR!");
+static const u8 sText_PkmnCausedUproar[] = _("{B_ATK_NAME_WITH_PREFIX} caused\nan UPROAR!");
+static const u8 sText_PkmnMakingUproar[] = _("{B_ATK_NAME_WITH_PREFIX} is making\nan UPROAR!");
+static const u8 sText_PkmnCalmedDown[] = _("{B_ATK_NAME_WITH_PREFIX} calmed down.");
+static const u8 sText_PkmnCantSleepInUproar[] = _("But {B_DEF_NAME_WITH_PREFIX} can’t\nsleep in an UPROAR!");
+static const u8 sText_PkmnStockpiled[] = _("{B_ATK_NAME_WITH_PREFIX} STOCKPILED\n{B_BUFF1}!");
+static const u8 sText_PkmnCantStockpile[] = _("{B_ATK_NAME_WITH_PREFIX} can’t\nSTOCKPILE any more!");
+static const u8 sText_PkmnCantSleepInUproar2[] = _("But {B_DEF_NAME_WITH_PREFIX} can’t\nsleep in an UPROAR!");
+static const u8 sText_UproarKeptPkmnAwake[] = _("But the UPROAR kept\n{B_DEF_NAME_WITH_PREFIX} awake!");
+static const u8 sText_PkmnStayedAwakeUsing[] = _("{B_DEF_NAME_WITH_PREFIX} stayed awake\nusing its {B_DEF_ABILITY}!");
+static const u8 sText_PkmnStoringEnergy[] = _("{B_ATK_NAME_WITH_PREFIX} is storing\nenergy!");
+static const u8 sText_PkmnUnleashedEnergy[] = _("{B_ATK_NAME_WITH_PREFIX} unleashed\nenergy!");
+static const u8 sText_PkmnFatigueConfusion[] = _("{B_ATK_NAME_WITH_PREFIX} became\nconfused due to fatigue!");
+static const u8 sText_PkmnPickedUpItem[] = _("{B_PLAYER_NAME} picked up\n¥{B_BUFF1}!\p");
+static const u8 sText_PkmnUnaffected[] = _("{B_DEF_NAME_WITH_PREFIX} is\nunaffected!");
+static const u8 sText_PkmnTransformedInto[] = _("{B_ATK_NAME_WITH_PREFIX} transformed\ninto {B_BUFF1}!");
+static const u8 sText_PkmnMadeSubstitute[] = _("{B_ATK_NAME_WITH_PREFIX} made\na SUBSTITUTE!");
+static const u8 sText_PkmnHasSubstitute[] = _("{B_ATK_NAME_WITH_PREFIX} already\nhas a SUBSTITUTE!");
+static const u8 sText_SubstituteDamaged[] = _("The SUBSTITUTE took damage\nfor {B_DEF_NAME_WITH_PREFIX}!\p");
+static const u8 sText_PkmnSubstituteFaded[] = _("{B_DEF_NAME_WITH_PREFIX}’s\nSUBSTITUTE faded!\p");
+static const u8 sText_PkmnMustRecharge[] = _("{B_ATK_NAME_WITH_PREFIX} must\nrecharge!");
+static const u8 sText_PkmnRageBuilding[] = _("{B_DEF_NAME_WITH_PREFIX}’s RAGE\nis building!");
+static const u8 sText_PkmnMoveWasDisabled[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_BUFF1}\nwas disabled!");
+static const u8 sText_PkmnMoveDisabledNoMore[] = _("{B_ATK_NAME_WITH_PREFIX} is disabled\nno more!");
+static const u8 sText_PkmnGotEncore[] = _("{B_DEF_NAME_WITH_PREFIX} got\nan ENCORE!");
+static const u8 sText_PkmnEncoreEnded[] = _("{B_ATK_NAME_WITH_PREFIX}’s ENCORE\nended!");
+static const u8 sText_PkmnTookAim[] = _("{B_ATK_NAME_WITH_PREFIX} took aim\nat {B_DEF_NAME_WITH_PREFIX}!");
+static const u8 sText_PkmnSketchedMove[] = _("{B_ATK_NAME_WITH_PREFIX} SKETCHED\n{B_BUFF1}!");
+static const u8 sText_PkmnTryingToTakeFoe[] = _("{B_ATK_NAME_WITH_PREFIX} is trying\nto take its foe with it!");
+static const u8 sText_PkmnTookFoe[] = _("{B_DEF_NAME_WITH_PREFIX} took\n{B_ATK_NAME_WITH_PREFIX} with it!");
+static const u8 sText_PkmnReducedPP[] = _("Reduced {B_DEF_NAME_WITH_PREFIX}’s\n{B_BUFF1} by {B_BUFF2}!");
+static const u8 sText_PkmnStoleItem[] = _("{B_ATK_NAME_WITH_PREFIX} stole\n{B_DEF_NAME_WITH_PREFIX}’s {B_LAST_ITEM}!");
+static const u8 sText_TargetCantEscapeNow[] = _("{B_DEF_NAME_WITH_PREFIX} can’t\nescape now!");
+static const u8 sText_PkmnFellIntoNightmare[] = _("{B_DEF_NAME_WITH_PREFIX} fell into\na NIGHTMARE!");
+static const u8 sText_PkmnLockedInNightmare[] = _("{B_ATK_NAME_WITH_PREFIX} is locked\nin a NIGHTMARE!");
+static const u8 sText_PkmnLaidCurse[] = _("{B_ATK_NAME_WITH_PREFIX} cut its own HP and\nlaid a CURSE on {B_DEF_NAME_WITH_PREFIX}!");
+static const u8 sText_PkmnAfflictedByCurse[] = _("{B_ATK_NAME_WITH_PREFIX} is afflicted\nby the CURSE!");
+static const u8 sText_SpikesScattered[] = _("SPIKES were scattered all around\nthe opponent’s side!");
+static const u8 sText_PkmnHurtBySpikes[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is hurt\nby SPIKES!");
+static const u8 sText_PkmnIdentified[] = _("{B_ATK_NAME_WITH_PREFIX} identified\n{B_DEF_NAME_WITH_PREFIX}!");
+static const u8 sText_PkmnPerishCountFell[] = _("{B_ATK_NAME_WITH_PREFIX}’s PERISH count\nfell to {B_BUFF1}!");
+static const u8 sText_PkmnBracedItself[] = _("{B_ATK_NAME_WITH_PREFIX} braced\nitself!");
+static const u8 sText_PkmnEnduredHit[] = _("{B_DEF_NAME_WITH_PREFIX} ENDURED\nthe hit!");
+static const u8 sText_MagnitudeStrength[] = _("MAGNITUDE {B_BUFF1}!");
+static const u8 sText_PkmnCutHPMaxedAttack[] = _("{B_ATK_NAME_WITH_PREFIX} cut its own HP\nand maximized ATTACK!");
+static const u8 sText_PkmnCopiedStatChanges[] = _("{B_ATK_NAME_WITH_PREFIX} copied\n{B_DEF_NAME_WITH_PREFIX}’s stat changes!");
+static const u8 sText_PkmnGotFree[] = _("{B_ATK_NAME_WITH_PREFIX} got free of\n{B_DEF_NAME_WITH_PREFIX}’s {B_BUFF1}!");
+static const u8 sText_PkmnShedLeechSeed[] = _("{B_ATK_NAME_WITH_PREFIX} shed\nLEECH SEED!");
+static const u8 sText_PkmnBlewAwaySpikes[] = _("{B_ATK_NAME_WITH_PREFIX} blew away\nSPIKES!");
+static const u8 sText_PkmnFledFromBattle[] = _("{B_ATK_NAME_WITH_PREFIX} fled from\nbattle!");
+static const u8 sText_PkmnForesawAttack[] = _("{B_ATK_NAME_WITH_PREFIX} foresaw\nan attack!");
+static const u8 sText_PkmnTookAttack[] = _("{B_DEF_NAME_WITH_PREFIX} took the\n{B_BUFF1} attack!");
+static const u8 sText_PkmnChoseXAsDestiny[] = _("{B_ATK_NAME_WITH_PREFIX} chose\n{B_CURRENT_MOVE} as its destiny!");
+static const u8 sText_PkmnAttack[] = _("{B_BUFF1}’s attack!");
+static const u8 sText_PkmnCenterAttention[] = _("{B_ATK_NAME_WITH_PREFIX} became the\ncenter of attention!");
+static const u8 sText_PkmnChargingPower[] = _("{B_ATK_NAME_WITH_PREFIX} began\ncharging power!");
+static const u8 sText_NaturePowerTurnedInto[] = _("NATURE POWER turned into\n{B_CURRENT_MOVE}!");
+static const u8 sText_PkmnStatusNormal[] = _("{B_ATK_NAME_WITH_PREFIX}’s status\nreturned to normal!");
+static const u8 sText_PkmnSubjectedToTorment[] = _("{B_DEF_NAME_WITH_PREFIX} was subjected\nto TORMENT!");
+static const u8 sText_PkmnTighteningFocus[] = _("{B_ATK_NAME_WITH_PREFIX} is tightening\nits focus!");
+static const u8 sText_PkmnFellForTaunt[] = _("{B_DEF_NAME_WITH_PREFIX} fell for\nthe TAUNT!");
+static const u8 sText_PkmnReadyToHelp[] = _("{B_ATK_NAME_WITH_PREFIX} is ready to\nhelp {B_DEF_NAME_WITH_PREFIX}!");
+static const u8 sText_PkmnSwitchedItems[] = _("{B_ATK_NAME_WITH_PREFIX} switched\nitems with its opponent!");
+static const u8 sText_PkmnObtainedX[] = _("{B_ATK_NAME_WITH_PREFIX} obtained\n{B_BUFF1}.");
+static const u8 sText_PkmnObtainedX2[] = _("{B_DEF_NAME_WITH_PREFIX} obtained\n{B_BUFF2}.");
+static const u8 sText_PkmnObtainedXYObtainedZ[] = _("{B_ATK_NAME_WITH_PREFIX} obtained\n{B_BUFF1}.\p{B_DEF_NAME_WITH_PREFIX} obtained\n{B_BUFF2}.");
+static const u8 sText_PkmnCopiedFoe[] = _("{B_ATK_NAME_WITH_PREFIX} copied\n{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}!");
+static const u8 sText_PkmnMadeWish[] = _("{B_ATK_NAME_WITH_PREFIX} made a WISH!");
+static const u8 sText_PkmnWishCameTrue[] = _("{B_BUFF1}’s WISH\ncame true!");
+static const u8 sText_PkmnPlantedRoots[] = _("{B_ATK_NAME_WITH_PREFIX} planted its roots!");
+static const u8 sText_PkmnAbsorbedNutrients[] = _("{B_ATK_NAME_WITH_PREFIX} absorbed\nnutrients with its roots!");
+static const u8 sText_PkmnAnchoredItself[] = _("{B_DEF_NAME_WITH_PREFIX} anchored\nitself with its roots!");
+static const u8 sText_PkmnWasMadeDrowsy[] = _("{B_ATK_NAME_WITH_PREFIX} made\n{B_DEF_NAME_WITH_PREFIX} drowsy!");
+static const u8 sText_PkmnKnockedOff[] = _("{B_ATK_NAME_WITH_PREFIX} knocked off\n{B_DEF_NAME_WITH_PREFIX}’s {B_LAST_ITEM}!");
+static const u8 sText_PkmnSwappedAbilities[] = _("{B_ATK_NAME_WITH_PREFIX} swapped abilities\nwith its opponent!");
+static const u8 sText_PkmnSealedOpponentMove[] = _("{B_ATK_NAME_WITH_PREFIX} sealed the\nopponent’s move(s)!");
+static const u8 sText_PkmnWantsGrudge[] = _("{B_ATK_NAME_WITH_PREFIX} wants the\nopponent to bear a GRUDGE!");
+static const u8 sText_PkmnLostPPGrudge[] = _("{B_ATK_NAME_WITH_PREFIX}’s {B_BUFF1} lost\nall its PP due to the GRUDGE!");
+static const u8 sText_PkmnShroudedItself[] = _("{B_ATK_NAME_WITH_PREFIX} shrouded\nitself in {B_CURRENT_MOVE}!");
+static const u8 sText_PkmnMoveBounced[] = _("{B_ATK_NAME_WITH_PREFIX}’s {B_CURRENT_MOVE}\nwas bounced back by MAGIC COAT!");
+static const u8 sText_PkmnWaitsForTarget[] = _("{B_ATK_NAME_WITH_PREFIX} waits for a target\nto make a move!");
+static const u8 sText_PkmnSnatchedMove[] = _("{B_DEF_NAME_WITH_PREFIX} SNATCHED\n{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s move!");
+static const u8 sText_ElectricityWeakened[] = _("Electricity’s power was\nweakened!");
+static const u8 sText_FireWeakened[] = _("Fire’s power was\nweakened!");
+static const u8 sText_XFoundOneY[] = _("{B_ATK_NAME_WITH_PREFIX} found\none {B_LAST_ITEM}!");
+static const u8 sText_SoothingAroma[] = _("A soothing aroma wafted\nthrough the area!");
+static const u8 sText_ItemsCantBeUsedNow[] = _("Items can’t be used now.{PAUSE 64}");
+static const u8 sText_ForXCommaYZ[] = _("For {B_SCR_ACTIVE_NAME_WITH_PREFIX},\n{B_LAST_ITEM} {B_BUFF1}");
+static const u8 sText_PkmnUsedXToGetPumped[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} used\n{B_LAST_ITEM} to get pumped!");
+static const u8 sText_PkmnLostFocus[] = _("{B_ATK_NAME_WITH_PREFIX} lost its\nfocus and couldn’t move!");
+static const u8 sText_PkmnWasDraggedOut[] = _("{B_DEF_NAME_WITH_PREFIX} was\ndragged out!\p");
+static const u8 sText_TheWallShattered[] = _("The wall shattered!");
+static const u8 sText_ButNoEffect[] = _("But it had no effect!");
+static const u8 sText_PkmnHasNoMovesLeft[] = _("{B_ACTIVE_NAME_WITH_PREFIX} has no\nmoves left!\p");
+static const u8 sText_PkmnMoveIsDisabled[] = _("{B_ACTIVE_NAME_WITH_PREFIX}’s {B_CURRENT_MOVE}\nis disabled!\p");
+static const u8 sText_PkmnCantUseMoveTorment[] = _("{B_ACTIVE_NAME_WITH_PREFIX} can’t use the same\nmove in a row due to the TORMENT!\p");
+static const u8 sText_PkmnCantUseMoveTaunt[] = _("{B_ACTIVE_NAME_WITH_PREFIX} can’t use\n{B_CURRENT_MOVE} after the TAUNT!\p");
+static const u8 sText_PkmnCantUseMoveSealed[] = _("{B_ACTIVE_NAME_WITH_PREFIX} can’t use the\nsealed {B_CURRENT_MOVE}!\p");
+static const u8 sText_PkmnMadeItRain[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nmade it rain!");
+static const u8 sText_PkmnRaisedSpeed[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nraised its SPEED!");
+static const u8 sText_PkmnProtectedBy[] = _("{B_DEF_NAME_WITH_PREFIX} was protected\nby {B_DEF_ABILITY}!");
+static const u8 sText_PkmnPreventsUsage[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nprevents {B_ATK_NAME_WITH_PREFIX}\lfrom using {B_CURRENT_MOVE}!");
+static const u8 sText_PkmnRestoredHPUsing[] = _("{B_DEF_NAME_WITH_PREFIX} restored HP\nusing its {B_DEF_ABILITY}!");
+static const u8 sText_PkmnsXMadeYUseless[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nmade {B_CURRENT_MOVE} useless!");
+static const u8 sText_PkmnChangedTypeWith[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nmade it the {B_BUFF1} type!");
+static const u8 sText_PkmnPreventsParalysisWith[] = _("{B_EFF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nprevents paralysis!");
+static const u8 sText_PkmnPreventsRomanceWith[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nprevents romance!");
+static const u8 sText_PkmnPreventsPoisoningWith[] = _("{B_EFF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nprevents poisoning!");
+static const u8 sText_PkmnPreventsConfusionWith[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nprevents confusion!");
+static const u8 sText_PkmnRaisedFirePowerWith[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nraised its FIRE power!");
+static const u8 sText_PkmnAnchorsItselfWith[] = _("{B_DEF_NAME_WITH_PREFIX} anchors\nitself with {B_DEF_ABILITY}!");
+static const u8 sText_PkmnCutsAttackWith[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\ncuts {B_DEF_NAME_WITH_PREFIX}’s ATTACK!");
+static const u8 sText_PkmnPreventsStatLossWith[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nprevents stat loss!");
+static const u8 sText_PkmnHurtsWith[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nhurt {B_ATK_NAME_WITH_PREFIX}!");
+static const u8 sText_PkmnTraced[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} TRACED\n{B_BUFF1}’s {B_BUFF2}!");
+static const u8 sText_PkmnsXPreventsBurns[] = _("{B_EFF_NAME_WITH_PREFIX}’s {B_EFF_ABILITY}\nprevents burns!");
+static const u8 sText_PkmnsXBlocksY[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nblocks {B_CURRENT_MOVE}!");
+static const u8 sText_PkmnsXBlocksY2[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nblocks {B_CURRENT_MOVE}!");
+static const u8 sText_PkmnsXRestoredHPALittle2[] = _("{B_ATK_NAME_WITH_PREFIX}’s {B_ATK_ABILITY}\nrestored its HP a little!");
+static const u8 sText_PkmnsXWhippedUpSandstorm[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nwhipped up a sandstorm!");
+static const u8 sText_PkmnsXIntensifiedSun[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nintensified the sun’s rays!");
+static const u8 sText_PkmnsXPreventsYLoss[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nprevents {B_BUFF1} loss!");
+static const u8 sText_PkmnsXInfatuatedY[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\ninfatuated {B_ATK_NAME_WITH_PREFIX}!");
+static const u8 sText_PkmnsXMadeYIneffective[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nmade {B_CURRENT_MOVE} ineffective!");
+static const u8 sText_PkmnsXCuredYProblem[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\ncured its {B_BUFF1} problem!");
+static const u8 sText_ItSuckedLiquidOoze[] = _("It sucked up the\nLIQUID OOZE!");
+static const u8 sText_PkmnTransformed[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} transformed!");
+static const u8 sText_PkmnsXTookAttack[] = _("{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 gText_PreventedFromWorking[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nprevented {B_SCR_ACTIVE_NAME_WITH_PREFIX}’s\l{B_BUFF1} from working!");
-const u8 gText_PkmnsXMadeItIneffective[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nmade it ineffective!");
-const u8 gText_PkmnsXPreventsFlinching[] = _("{B_EFF_NAME_WITH_PREFIX}’s {B_EFF_ABILITY}\nprevents flinching!");
-const u8 gText_PkmnsXPreventsYsZ[] = _("{B_ATK_NAME_WITH_PREFIX}’s {B_ATK_ABILITY}\nprevents {B_DEF_NAME_WITH_PREFIX}’s\l{B_DEF_ABILITY} from working!");
-const u8 gText_PkmnsXCuredItsYProblem[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\ncured its {B_BUFF1} problem!");
-const u8 gText_PkmnsXHadNoEffectOnY[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nhad no effect on {B_EFF_NAME_WITH_PREFIX}!");
-const u8 gText_StatSharply[] = _("sharply ");
+static const u8 sText_PreventedFromWorking[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_DEF_ABILITY}\nprevented {B_SCR_ACTIVE_NAME_WITH_PREFIX}’s\l{B_BUFF1} from working!");
+static const u8 sText_PkmnsXMadeItIneffective[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nmade it ineffective!");
+static const u8 sText_PkmnsXPreventsFlinching[] = _("{B_EFF_NAME_WITH_PREFIX}’s {B_EFF_ABILITY}\nprevents flinching!");
+static const u8 sText_PkmnsXPreventsYsZ[] = _("{B_ATK_NAME_WITH_PREFIX}’s {B_ATK_ABILITY}\nprevents {B_DEF_NAME_WITH_PREFIX}’s\l{B_DEF_ABILITY} from working!");
+static const u8 sText_PkmnsXCuredItsYProblem[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\ncured its {B_BUFF1} problem!");
+static const u8 sText_PkmnsXHadNoEffectOnY[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_SCR_ACTIVE_ABILITY}\nhad no effect on {B_EFF_NAME_WITH_PREFIX}!");
+static const u8 sText_StatSharply[] = _("sharply ");
const u8 gText_StatRose[] = _("rose!");
-const u8 gText_StatHarshly[] = _("harshly ");
-const u8 gText_StatFell[] = _("fell!");
-const u8 gText_PkmnsStatChanged[] = _("{B_ATK_NAME_WITH_PREFIX}’s {B_BUFF1}\n{B_BUFF2}");
+static const u8 sText_StatHarshly[] = _("harshly ");
+static const u8 sText_StatFell[] = _("fell!");
+static const u8 sText_PkmnsStatChanged[] = _("{B_ATK_NAME_WITH_PREFIX}’s {B_BUFF1}\n{B_BUFF2}");
const u8 gText_PkmnsStatChanged2[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_BUFF1}\n{B_BUFF2}");
-const u8 gText_UsingXTheYOfZN[] = _("Using {B_LAST_ITEM}, the {B_BUFF1}\nof {B_SCR_ACTIVE_NAME_WITH_PREFIX} {B_BUFF2}");
-const u8 gText_PkmnsStatChanged3[] = _("{B_ATK_NAME_WITH_PREFIX}’s {B_BUFF1}\n{B_BUFF2}");
-const u8 gText_PkmnsStatChanged4[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_BUFF1}\n{B_BUFF2}");
-const u8 gText_StatsWontIncrease2[] = _("{B_ATK_NAME_WITH_PREFIX}’s stats won’t\ngo any higher!");
-const u8 gText_StatsWontDecrease2[] = _("{B_DEF_NAME_WITH_PREFIX}’s stats won’t\ngo any lower!");
-const u8 gText_CriticalHit[] = _("A critical hit!");
-const u8 gText_OneHitKO[] = _("It’s a one-hit KO!");
-const u8 gText_123Poof[] = _("{PAUSE 32}1, {PAUSE 15}2, and{PAUSE 15}… {PAUSE 15}… {PAUSE 15}… {PAUSE 15}{PLAY_SE 0x0038}Poof!\p");
-const u8 gText_AndEllipsis[] = _("And…\p");
-const u8 gText_HMMovesCantBeForgotten[] = _("HM moves can’t be\nforgotten now.\p");
-const u8 gText_NotVeryEffective[] = _("It’s not very effective…");
-const u8 gText_SuperEffective[] = _("It’s super effective!");
-const u8 gText_GotAwaySafely[] = _("{PLAY_SE 0x0011}Got away safely!\p");
-const u8 gText_PkmnFledUsingIts[] = _("{PLAY_SE 0x0011}{B_ATK_NAME_WITH_PREFIX} fled\nusing its {B_LAST_ITEM}!\p");
-const u8 gText_PkmnFledUsing[] = _("{PLAY_SE 0x0011}{B_ATK_NAME_WITH_PREFIX} fled\nusing {B_ATK_ABILITY}!\p");
-const u8 gText_WildPkmnFled[] = _("{PLAY_SE 0x0011}Wild {B_BUFF1} fled!");
-const u8 gText_PlayerDefeatedLinkTrainer[] = _("Player defeated\n{B_20}!");
-const u8 gText_TwoLinkTrainersDefeated[] = _("Player beat {B_20}\nand {B_21}!");
-const u8 gText_PlayerLostAgainstLinkTrainer[] = _("Player lost against\n{B_20}!");
-const u8 gText_PlayerLostToTwo[] = _("Player lost to {B_20}\nand {B_21}!");
-const u8 gText_PlayerBattledToDrawLinkTrainer[] = _("Player battled to a draw against\n{B_20}!");
-const u8 gText_PlayerBattledToDrawVsTwo[] = _("Player battled to a draw against\n{B_20} and {B_21}!");
-const u8 gText_WildFled[] = _("{PLAY_SE 0x0011}{B_20} fled!");
-const u8 gText_TwoWildFled[] = _("{PLAY_SE 0x0011}{B_20} and\n{B_21} fled!");
-const u8 gText_NoRunningFromTrainers[] = _("No! There’s no running\nfrom a TRAINER battle!\p");
-const u8 gText_CantEscape[] = _("Can’t escape!\p");
-const u8 gText_DontLeaveBirch[] = _("PROF. BIRCH: Don’t leave me like this!\p");
-const u8 gText_ButNothingHappened[] = _("But nothing happened!");
-const u8 gText_ButItFailed[] = _("But it failed!");
-const u8 gText_ItHurtConfusion[] = _("It hurt itself in its\nconfusion!");
-const u8 gText_MirrorMoveFailed[] = _("The MIRROR MOVE failed!");
-const u8 gText_StartedToRain[] = _("It started to rain!");
-const u8 gText_DownpourStarted[] = _("A downpour started!");
-const u8 gText_RainContinues[] = _("Rain continues to fall.");
-const u8 gText_DownpourContinues[] = _("The downpour continues.");
-const u8 gText_RainStopped[] = _("The rain stopped.");
-const u8 gText_SandstormBrewed[] = _("A sandstorm brewed!");
-const u8 gText_SandstormRages[] = _("The sandstorm rages.");
-const u8 gText_SandstormSubsided[] = _("The sandstorm subsided.");
-const u8 gText_SunlightGotBright[] = _("The sunlight got bright!");
-const u8 gText_SunlightStrong[] = _("The sunlight is strong.");
-const u8 gText_SunlightFaded[] = _("The sunlight faded.");
-const u8 gText_StartedHail[] = _("It started to hail!");
-const u8 gText_HailContinues[] = _("Hail continues to fall.");
-const u8 gText_HailStopped[] = _("The hail stopped.");
-const u8 gText_FailedToSpitUp[] = _("But it failed to SPIT UP\na thing!");
-const u8 gText_FailedToSwallow[] = _("But it failed to SWALLOW\na thing!");
-const u8 gText_WindBecameHeatWave[] = _("The wind turned into a\nHEAT WAVE!");
-const u8 gText_StatChangesGone[] = _("All stat changes were\neliminated!");
-const u8 gText_CoinsScattered[] = _("Coins scattered everywhere!");
-const u8 gText_TooWeakForSubstitute[] = _("It was too weak to make\na SUBSTITUTE!");
-const u8 gText_SharedPain[] = _("The battlers shared\ntheir pain!");
-const u8 gText_BellChimed[] = _("A bell chimed!");
-const u8 gText_FaintInThree[] = _("All affected POKéMON will\nfaint in three turns!");
-const u8 gText_NoPPLeft[] = _("There’s no PP left for\nthis move!\p");
-const u8 gText_ButNoPPLeft[] = _("But there was no PP left\nfor the move!");
-const u8 gText_PkmnIgnoresAsleep[] = _("{B_ATK_NAME_WITH_PREFIX} ignored\norders while asleep!");
-const u8 gText_PkmnIgnoredOrders[] = _("{B_ATK_NAME_WITH_PREFIX} ignored\norders!");
-const u8 gText_PkmnBeganToNap[] = _("{B_ATK_NAME_WITH_PREFIX} began to nap!");
-const u8 gText_PkmnLoafing[] = _("{B_ATK_NAME_WITH_PREFIX} is\nloafing around!");
-const u8 gText_PkmnWontObey[] = _("{B_ATK_NAME_WITH_PREFIX} won’t\nobey!");
-const u8 gText_PkmnTurnedAway[] = _("{B_ATK_NAME_WITH_PREFIX} turned away!");
-const u8 gText_PkmnPretendNotNotice[] = _("{B_ATK_NAME_WITH_PREFIX} pretended\nnot to notice!");
-const u8 gText_EnemyAboutToSwitchPkmn[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME} is\nabout to use {B_BUFF2}.\pWill {B_PLAYER_NAME} change\nPOKéMON?");
-const u8 gText_PkmnLearnedMove2[] = _("{B_ATK_NAME_WITH_PREFIX} learned\n{B_BUFF1}!");
-const u8 gText_PlayerDefeatedLinkTrainerTrainer1[] = _("Player defeated\n{B_TRAINER1_CLASS} {B_TRAINER1_NAME}!\p");
-const u8 gText_CreptCloser[] = _("{B_PLAYER_NAME} crept closer to\n{B_OPPONENT_MON1_NAME}!");
-const u8 gText_CantGetCloser[] = _("{B_PLAYER_NAME} can’t get any closer!");
-const u8 gText_PkmnWatchingCarefully[] = _("{B_OPPONENT_MON1_NAME} is watching\ncarefully!");
-const u8 gText_PkmnCuriousAboutX[] = _("{B_OPPONENT_MON1_NAME} is curious about\nthe {B_BUFF1}!");
-const u8 gText_PkmnEnthralledByX[] = _("{B_OPPONENT_MON1_NAME} is enthralled by\nthe {B_BUFF1}!");
-const u8 gText_PkmnIgnoredX[] = _("{B_OPPONENT_MON1_NAME} completely ignored\nthe {B_BUFF1}!");
-const u8 gText_ThrewPokeblockAtPkmn[] = _("{B_PLAYER_NAME} threw a {POKEBLOCK}\nat the {B_OPPONENT_MON1_NAME}!");
-const u8 gText_OutOfSafariBalls[] = _("{PLAY_SE 0x0049}ANNOUNCER: You’re out of\nSAFARI BALLS! Game over!\p");
-const u8 gText_OpponentMon1Appeared[] = _("{B_OPPONENT_MON1_NAME} appeared!\p");
-const u8 gText_WildPkmnAppeared[] = _("Wild {B_OPPONENT_MON1_NAME} appeared!\p");
-const u8 gText_WildPkmnAppeared2[] = _("Wild {B_OPPONENT_MON1_NAME} appeared!\p");
-const u8 gText_WildPkmnAppearedPause[] = _("Wild {B_OPPONENT_MON1_NAME} appeared!{PAUSE 127}");
-const u8 gText_TwoWildPkmnAppeared[] = _("Wild {B_OPPONENT_MON1_NAME} and\n{B_OPPONENT_MON2_NAME} appeared!\p");
-const u8 gText_Trainer1WantsToBattle[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME}\nwould like to battle!\p");
-const u8 gText_LinkTrainerWantsToBattle[] = _("{B_20}\nwants to battle!");
-const u8 gText_TwoLinkTrainersWantToBattle[] = _("{B_20} and {B_21}\nwant to battle!");
-const u8 gText_Trainer1SentOutPkmn[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME} sent\nout {B_OPPONENT_MON1_NAME}!");
-const u8 gText_Trainer1SentOutTwoPkmn[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME} sent\nout {B_OPPONENT_MON1_NAME} and {B_OPPONENT_MON2_NAME}!");
-const u8 gText_Trainer1SentOutPkmn2[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME} sent\nout {B_BUFF1}!");
-const u8 gText_LinkTrainerSentOutPkmn[] = _("{B_20} sent out\n{B_OPPONENT_MON1_NAME}!");
-const u8 gText_LinkTrainerSentOutTwoPkmn[] = _("{B_20} sent out\n{B_OPPONENT_MON1_NAME} and {B_OPPONENT_MON2_NAME}!");
-const u8 gText_TwoLinkTrainersSentOutPkmn[] = _("{B_20} sent out {B_LINK_OPPONENT_MON1_NAME}!\n{B_21} sent out {B_LINK_OPPONENT_MON2_NAME}!");
-const u8 gText_LinkTrainerSentOutPkmn2[] = _("{B_20} sent out\n{B_BUFF1}!");
-const u8 gText_LinkTrainerMultiSentOutPkmn[] = _("{B_22} sent out\n{B_BUFF1}!");
-const u8 gText_GoPkmn[] = _("Go! {B_PLAYER_MON1_NAME}!");
-const u8 gText_GoTwoPkmn[] = _("Go! {B_PLAYER_MON1_NAME} and\n{B_PLAYER_MON2_NAME}!");
-const u8 gText_GoPkmn2[] = _("Go! {B_BUFF1}!");
-const u8 gText_DoItPkmn[] = _("Do it! {B_BUFF1}!");
-const u8 gText_GoForItPkmn[] = _("Go for it, {B_BUFF1}!");
-const u8 gText_YourFoesWeakGetEmPkmn[] = _("Your foe’s weak!\nGet ’em, {B_BUFF1}!");
-const u8 gText_LinkPartnerSentOutPkmnGoPkmn[] = _("{B_1F} sent out {B_LINK_PLAYER_MON2_NAME}!\nGo! {B_LINK_PLAYER_MON1_NAME}!");
-const u8 gText_PkmnThatsEnough[] = _("{B_BUFF1}, that’s enough!\nCome back!");
-const u8 gText_PkmnComeBack[] = _("{B_BUFF1}, come back!");
-const u8 gText_PkmnOkComeBack[] = _("{B_BUFF1}, OK!\nCome back!");
-const u8 gText_PkmnGoodComeBack[] = _("{B_BUFF1}, good!\nCome back!");
-const u8 gText_Trainer1WithdrewPkmn[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME}\nwithdrew {B_BUFF1}!");
-const u8 gText_LinkTrainer1WithdrewPkmn[] = _("{B_20} withdrew\n{B_BUFF1}!");
-const u8 gText_LinkTrainer2WithdrewPkmn[] = _("{B_22} withdrew\n{B_BUFF1}!");
-const u8 gText_WildPkmnPrefix[] = _("Wild ");
-const u8 gText_FoePkmnPrefix[] = _("Foe ");
-const u8 gText_EmptyString8[] = _( "");
-const u8 gText_FoePkmnPrefix2[] = _("Foe");
-const u8 gText_AllyPkmnPrefix[] = _("Ally");
-const u8 gText_FoePkmnPrefix3[] = _("Foe");
-const u8 gText_AllyPkmnPrefix2[] = _("Ally");
-const u8 gText_FoePkmnPrefix4[] = _("Foe");
-const u8 gText_AllyPkmnPrefix3[] = _("Ally");
-const u8 gText_AttackerUsedX[] = _("{B_ATK_NAME_WITH_PREFIX} used\n{B_BUFF2}");
-const u8 gText_ExclamationMark[] = _("!");
-const u8 gText_ExclamationMark2[] = _("!");
-const u8 gText_ExclamationMark3[] = _("!");
-const u8 gText_ExclamationMark4[] = _("!");
-const u8 gText_ExclamationMark5[] = _("!");
-const u8 gText_HP2[] = _("HP");
-const u8 gText_Attack2[] = _("ATTACK");
-const u8 gText_Defense2[] = _("DEFENSE");
-const u8 gText_Speed[] = _("SPEED");
-const u8 gText_SpAtk2[] = _("SP. ATK");
-const u8 gText_SpDef2[] = _("SP. DEF");
-const u8 gText_Accuracy[] = _("accuracy");
-const u8 gText_Evasiveness[] = _("evasiveness");
+static const u8 sText_UsingXTheYOfZN[] = _("Using {B_LAST_ITEM}, the {B_BUFF1}\nof {B_SCR_ACTIVE_NAME_WITH_PREFIX} {B_BUFF2}");
+static const u8 sText_PkmnsStatChanged3[] = _("{B_ATK_NAME_WITH_PREFIX}’s {B_BUFF1}\n{B_BUFF2}");
+static const u8 sText_PkmnsStatChanged4[] = _("{B_DEF_NAME_WITH_PREFIX}’s {B_BUFF1}\n{B_BUFF2}");
+static const u8 sText_StatsWontIncrease2[] = _("{B_ATK_NAME_WITH_PREFIX}’s stats won’t\ngo any higher!");
+static const u8 sText_StatsWontDecrease2[] = _("{B_DEF_NAME_WITH_PREFIX}’s stats won’t\ngo any lower!");
+static const u8 sText_CriticalHit[] = _("A critical hit!");
+static const u8 sText_OneHitKO[] = _("It’s a one-hit KO!");
+static const u8 sText_123Poof[] = _("{PAUSE 32}1, {PAUSE 15}2, and{PAUSE 15}… {PAUSE 15}… {PAUSE 15}… {PAUSE 15}{PLAY_SE 0x0038}Poof!\p");
+static const u8 sText_AndEllipsis[] = _("And…\p");
+static const u8 sText_HMMovesCantBeForgotten[] = _("HM moves can’t be\nforgotten now.\p");
+static const u8 sText_NotVeryEffective[] = _("It’s not very effective…");
+static const u8 sText_SuperEffective[] = _("It’s super effective!");
+static const u8 sText_GotAwaySafely[] = _("{PLAY_SE 0x0011}Got away safely!\p");
+static const u8 sText_PkmnFledUsingIts[] = _("{PLAY_SE 0x0011}{B_ATK_NAME_WITH_PREFIX} fled\nusing its {B_LAST_ITEM}!\p");
+static const u8 sText_PkmnFledUsing[] = _("{PLAY_SE 0x0011}{B_ATK_NAME_WITH_PREFIX} fled\nusing {B_ATK_ABILITY}!\p");
+static const u8 sText_WildPkmnFled[] = _("{PLAY_SE 0x0011}Wild {B_BUFF1} fled!");
+static const u8 sText_PlayerDefeatedLinkTrainer[] = _("Player defeated\n{B_20}!");
+static const u8 sText_TwoLinkTrainersDefeated[] = _("Player beat {B_20}\nand {B_21}!");
+static const u8 sText_PlayerLostAgainstLinkTrainer[] = _("Player lost against\n{B_20}!");
+static const u8 sText_PlayerLostToTwo[] = _("Player lost to {B_20}\nand {B_21}!");
+static const u8 sText_PlayerBattledToDrawLinkTrainer[] = _("Player battled to a draw against\n{B_20}!");
+static const u8 sText_PlayerBattledToDrawVsTwo[] = _("Player battled to a draw against\n{B_20} and {B_21}!");
+static const u8 sText_WildFled[] = _("{PLAY_SE 0x0011}{B_20} fled!");
+static const u8 sText_TwoWildFled[] = _("{PLAY_SE 0x0011}{B_20} and\n{B_21} fled!");
+static const u8 sText_NoRunningFromTrainers[] = _("No! There’s no running\nfrom a TRAINER battle!\p");
+static const u8 sText_CantEscape[] = _("Can’t escape!\p");
+static const u8 sText_DontLeaveBirch[] = _("PROF. BIRCH: Don’t leave me like this!\p");
+static const u8 sText_ButNothingHappened[] = _("But nothing happened!");
+static const u8 sText_ButItFailed[] = _("But it failed!");
+static const u8 sText_ItHurtConfusion[] = _("It hurt itself in its\nconfusion!");
+static const u8 sText_MirrorMoveFailed[] = _("The MIRROR MOVE failed!");
+static const u8 sText_StartedToRain[] = _("It started to rain!");
+static const u8 sText_DownpourStarted[] = _("A downpour started!");
+static const u8 sText_RainContinues[] = _("Rain continues to fall.");
+static const u8 sText_DownpourContinues[] = _("The downpour continues.");
+static const u8 sText_RainStopped[] = _("The rain stopped.");
+static const u8 sText_SandstormBrewed[] = _("A sandstorm brewed!");
+static const u8 sText_SandstormRages[] = _("The sandstorm rages.");
+static const u8 sText_SandstormSubsided[] = _("The sandstorm subsided.");
+static const u8 sText_SunlightGotBright[] = _("The sunlight got bright!");
+static const u8 sText_SunlightStrong[] = _("The sunlight is strong.");
+static const u8 sText_SunlightFaded[] = _("The sunlight faded.");
+static const u8 sText_StartedHail[] = _("It started to hail!");
+static const u8 sText_HailContinues[] = _("Hail continues to fall.");
+static const u8 sText_HailStopped[] = _("The hail stopped.");
+static const u8 sText_FailedToSpitUp[] = _("But it failed to SPIT UP\na thing!");
+static const u8 sText_FailedToSwallow[] = _("But it failed to SWALLOW\na thing!");
+static const u8 sText_WindBecameHeatWave[] = _("The wind turned into a\nHEAT WAVE!");
+static const u8 sText_StatChangesGone[] = _("All stat changes were\neliminated!");
+static const u8 sText_CoinsScattered[] = _("Coins scattered everywhere!");
+static const u8 sText_TooWeakForSubstitute[] = _("It was too weak to make\na SUBSTITUTE!");
+static const u8 sText_SharedPain[] = _("The battlers shared\ntheir pain!");
+static const u8 sText_BellChimed[] = _("A bell chimed!");
+static const u8 sText_FaintInThree[] = _("All affected POKéMON will\nfaint in three turns!");
+static const u8 sText_NoPPLeft[] = _("There’s no PP left for\nthis move!\p");
+static const u8 sText_ButNoPPLeft[] = _("But there was no PP left\nfor the move!");
+static const u8 sText_PkmnIgnoresAsleep[] = _("{B_ATK_NAME_WITH_PREFIX} ignored\norders while asleep!");
+static const u8 sText_PkmnIgnoredOrders[] = _("{B_ATK_NAME_WITH_PREFIX} ignored\norders!");
+static const u8 sText_PkmnBeganToNap[] = _("{B_ATK_NAME_WITH_PREFIX} began to nap!");
+static const u8 sText_PkmnLoafing[] = _("{B_ATK_NAME_WITH_PREFIX} is\nloafing around!");
+static const u8 sText_PkmnWontObey[] = _("{B_ATK_NAME_WITH_PREFIX} won’t\nobey!");
+static const u8 sText_PkmnTurnedAway[] = _("{B_ATK_NAME_WITH_PREFIX} turned away!");
+static const u8 sText_PkmnPretendNotNotice[] = _("{B_ATK_NAME_WITH_PREFIX} pretended\nnot to notice!");
+static const u8 sText_EnemyAboutToSwitchPkmn[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME} is\nabout to use {B_BUFF2}.\pWill {B_PLAYER_NAME} change\nPOKéMON?");
+static const u8 sText_PkmnLearnedMove2[] = _("{B_ATK_NAME_WITH_PREFIX} learned\n{B_BUFF1}!");
+static const u8 sText_PlayerDefeatedLinkTrainerTrainer1[] = _("Player defeated\n{B_TRAINER1_CLASS} {B_TRAINER1_NAME}!\p");
+static const u8 sText_CreptCloser[] = _("{B_PLAYER_NAME} crept closer to\n{B_OPPONENT_MON1_NAME}!");
+static const u8 sText_CantGetCloser[] = _("{B_PLAYER_NAME} can’t get any closer!");
+static const u8 sText_PkmnWatchingCarefully[] = _("{B_OPPONENT_MON1_NAME} is watching\ncarefully!");
+static const u8 sText_PkmnCuriousAboutX[] = _("{B_OPPONENT_MON1_NAME} is curious about\nthe {B_BUFF1}!");
+static const u8 sText_PkmnEnthralledByX[] = _("{B_OPPONENT_MON1_NAME} is enthralled by\nthe {B_BUFF1}!");
+static const u8 sText_PkmnIgnoredX[] = _("{B_OPPONENT_MON1_NAME} completely ignored\nthe {B_BUFF1}!");
+static const u8 sText_ThrewPokeblockAtPkmn[] = _("{B_PLAYER_NAME} threw a {POKEBLOCK}\nat the {B_OPPONENT_MON1_NAME}!");
+static const u8 sText_OutOfSafariBalls[] = _("{PLAY_SE 0x0049}ANNOUNCER: You’re out of\nSAFARI BALLS! Game over!\p");
+static const u8 sText_OpponentMon1Appeared[] = _("{B_OPPONENT_MON1_NAME} appeared!\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");
+static const u8 sText_Trainer1WantsToBattle[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME}\nwould like to battle!\p");
+static const u8 sText_LinkTrainerWantsToBattle[] = _("{B_20}\nwants to battle!");
+static const u8 sText_TwoLinkTrainersWantToBattle[] = _("{B_20} and {B_21}\nwant to battle!");
+static const u8 sText_Trainer1SentOutPkmn[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME} sent\nout {B_OPPONENT_MON1_NAME}!");
+static const u8 sText_Trainer1SentOutTwoPkmn[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME} sent\nout {B_OPPONENT_MON1_NAME} and {B_OPPONENT_MON2_NAME}!");
+static const u8 sText_Trainer1SentOutPkmn2[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME} sent\nout {B_BUFF1}!");
+static const u8 sText_LinkTrainerSentOutPkmn[] = _("{B_20} sent out\n{B_OPPONENT_MON1_NAME}!");
+static const u8 sText_LinkTrainerSentOutTwoPkmn[] = _("{B_20} sent out\n{B_OPPONENT_MON1_NAME} and {B_OPPONENT_MON2_NAME}!");
+static const u8 sText_TwoLinkTrainersSentOutPkmn[] = _("{B_20} sent out {B_LINK_OPPONENT_MON1_NAME}!\n{B_21} sent out {B_LINK_OPPONENT_MON2_NAME}!");
+static const u8 sText_LinkTrainerSentOutPkmn2[] = _("{B_20} sent out\n{B_BUFF1}!");
+static const u8 sText_LinkTrainerMultiSentOutPkmn[] = _("{B_22} 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_1F} 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!");
+static 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_20} withdrew\n{B_BUFF1}!");
+static const u8 sText_LinkTrainer2WithdrewPkmn[] = _("{B_22} withdrew\n{B_BUFF1}!");
+static const u8 sText_WildPkmnPrefix[] = _("Wild ");
+static const u8 sText_FoePkmnPrefix[] = _("Foe ");
+static const u8 sText_EmptyString8[] = _( "");
+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[] =
{
- gText_HP2, gText_Attack2, gText_Defense2,
- gText_Speed, gText_SpAtk2, gText_SpDef2,
- gText_Accuracy, gText_Evasiveness
+ sText_HP2, sText_Attack2, sText_Defense2,
+ sText_Speed, sText_SpAtk2, sText_SpDef2,
+ sText_Accuracy, sText_Evasiveness
};
-const u8 gText_PokeblockWasTooSpicy[] = _("was too spicy!");
-const u8 gText_PokeblockWasTooDry[] = _("was too dry!");
-const u8 gText_PokeblockWasTooSweet[] = _("was too sweet!");
-const u8 gText_PokeblockWasTooBitter[] = _("was too bitter!");
-const u8 gText_PokeblockWasTooSour[] = _("was too sour!");
+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[] =
{
- gText_PokeblockWasTooSpicy, gText_PokeblockWasTooDry,
- gText_PokeblockWasTooSweet, gText_PokeblockWasTooBitter,
- gText_PokeblockWasTooSour
+ sText_PokeblockWasTooSpicy, sText_PokeblockWasTooDry,
+ sText_PokeblockWasTooSweet, sText_PokeblockWasTooBitter,
+ sText_PokeblockWasTooSour
};
-const u8 gText_PlayerUsedItem[] = _("{B_PLAYER_NAME} used\n{B_LAST_ITEM}!");
-const u8 gText_WallyUsedItem[] = _("WALLY used\n{B_LAST_ITEM}!");
-const u8 gText_Trainer1UsedItem[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME}\nused {B_LAST_ITEM}!");
-const u8 gText_TrainerBlockedBall[] = _("The TRAINER blocked the BALL!");
-const u8 gText_DontBeAThief[] = _("Don’t be a thief!");
-const u8 gText_ItDodgedBall[] = _("It dodged the thrown BALL!\nThis POKéMON can’t be caught!");
-const u8 gText_YouMissedPkmn[] = _("You missed the POKéMON!");
-const u8 gText_PkmnBrokeFree[] = _("Oh, no!\nThe POKéMON broke free!");
-const u8 gText_ItAppearedCaught[] = _("Aww!\nIt appeared to be caught!");
-const u8 gText_AarghAlmostHadIt[] = _("Aargh!\nAlmost had it!");
-const u8 gText_ShootSoClose[] = _("Shoot!\nIt was so close, too!");
-const u8 gText_GotchaPkmnCaught[] = _("Gotcha!\n{B_OPPONENT_MON1_NAME} was caught!{UNKNOWN_A}{PLAY_BGM MUS_KACHI22}\p");
-const u8 gText_GotchaPkmnCaught2[] = _("Gotcha!\n{B_OPPONENT_MON1_NAME} was caught!{UNKNOWN_A}{PLAY_BGM MUS_KACHI22}{PAUSE 127}");
-const u8 gText_GiveNicknameCaptured[] = _("Give a nickname to the\ncaptured {B_OPPONENT_MON1_NAME}?");
-const u8 gText_PkmnSentToPC[] = _("{B_OPPONENT_MON1_NAME} was sent to\n{B_PC_CREATOR_NAME} PC.");
-const u8 gText_Someones[] = _("someone’s");
-const u8 gText_Lanettes[] = _("LANETTE’s");
-const u8 gText_PkmnDataAddedToDex[] = _("{B_OPPONENT_MON1_NAME}’s data was\nadded to the POKéDEX.\p");
-const u8 gText_ItIsRaining[] = _("It is raining.");
-const u8 gText_SandstormIsRaging[] = _("A sandstorm is raging.");
-const u8 gText_BoxIsFull[] = _("The BOX is full!\nYou can’t catch any more!\p");
-const u8 gText_EnigmaBerry[] = _("ENIGMA BERRY");
-const u8 gText_BerrySuffix[] = _(" BERRY");
-const u8 gText_PkmnsItemCuredParalysis[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\ncured paralysis!");
-const u8 gText_PkmnsItemCuredPoison[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\ncured poison!");
-const u8 gText_PkmnsItemHealedBurn[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\nhealed its burn!");
-const u8 gText_PkmnsItemDefrostedIt[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\ndefrosted it!");
-const u8 gText_PkmnsItemWokeIt[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\nwoke it from its sleep!");
-const u8 gText_PkmnsItemSnappedOut[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\nsnapped it out of confusion!");
-const u8 gText_PkmnsItemCuredProblem[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\ncured its {B_BUFF1} problem!");
-const u8 gText_PkmnsItemNormalizedStatus[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\nnormalized its status!");
-const u8 gText_PkmnsItemRestoredHealth[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\nrestored health!");
-const u8 gText_PkmnsItemRestoredPP[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\nrestored {B_BUFF1}’s PP!");
-const u8 gText_PkmnsItemRestoredStatus[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\nrestored its status!");
-const u8 gText_PkmnsItemRestoredHPALittle[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\nrestored its HP a little!");
-const u8 gText_ItemAllowsOnlyYMove[] = _("{B_LAST_ITEM} allows the\nuse of only {B_CURRENT_MOVE}!\p");
-const u8 gText_PkmnHungOnWithX[] = _("{B_DEF_NAME_WITH_PREFIX} hung on\nusing its {B_LAST_ITEM}!");
+static const u8 sText_PlayerUsedItem[] = _("{B_PLAYER_NAME} used\n{B_LAST_ITEM}!");
+static const u8 sText_WallyUsedItem[] = _("WALLY 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!");
+static const u8 sText_GotchaPkmnCaught[] = _("Gotcha!\n{B_OPPONENT_MON1_NAME} was caught!{UNKNOWN_A}{PLAY_BGM MUS_KACHI22}\p");
+static const u8 sText_GotchaPkmnCaught2[] = _("Gotcha!\n{B_OPPONENT_MON1_NAME} was caught!{UNKNOWN_A}{PLAY_BGM MUS_KACHI22}{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_Lanettes[] = _("LANETTE’s");
+static const u8 sText_PkmnDataAddedToDex[] = _("{B_OPPONENT_MON1_NAME}’s data was\nadded to the POKéDEX.\p");
+static const u8 sText_ItIsRaining[] = _("It is raining.");
+static const u8 sText_SandstormIsRaging[] = _("A sandstorm is raging.");
+static const u8 sText_BoxIsFull[] = _("The BOX is full!\nYou can’t catch any more!\p");
+static const u8 sText_EnigmaBerry[] = _("ENIGMA BERRY");
+static const u8 sText_BerrySuffix[] = _(" BERRY");
+static const u8 sText_PkmnsItemCuredParalysis[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\ncured paralysis!");
+static const u8 sText_PkmnsItemCuredPoison[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\ncured poison!");
+static const u8 sText_PkmnsItemHealedBurn[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\nhealed its burn!");
+static const u8 sText_PkmnsItemDefrostedIt[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\ndefrosted it!");
+static const u8 sText_PkmnsItemWokeIt[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\nwoke it from its sleep!");
+static const u8 sText_PkmnsItemSnappedOut[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\nsnapped it out of confusion!");
+static const u8 sText_PkmnsItemCuredProblem[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\ncured its {B_BUFF1} problem!");
+static const u8 sText_PkmnsItemNormalizedStatus[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\nnormalized its status!");
+static const u8 sText_PkmnsItemRestoredHealth[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\nrestored health!");
+static const u8 sText_PkmnsItemRestoredPP[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\nrestored {B_BUFF1}’s PP!");
+static const u8 sText_PkmnsItemRestoredStatus[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\nrestored its status!");
+static const u8 sText_PkmnsItemRestoredHPALittle[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s {B_LAST_ITEM}\nrestored its HP a little!");
+static const u8 sText_ItemAllowsOnlyYMove[] = _("{B_LAST_ITEM} allows the\nuse of only {B_CURRENT_MOVE}!\p");
+static const u8 sText_PkmnHungOnWithX[] = _("{B_DEF_NAME_WITH_PREFIX} hung on\nusing its {B_LAST_ITEM}!");
const u8 gText_EmptyString3[] = _("");
-const u8 gText_YouThrowABallNowRight[] = _("You throw a BALL now, right?\nI… I’ll do my best!");
+static const u8 sText_YouThrowABallNowRight[] = _("You throw a BALL now, right?\nI… I’ll do my best!");
// early declaration of strings
-const u8 gText_PkmnIncapableOfPower[];
-const u8 gText_GlintAppearsInEye[];
-const u8 gText_PkmnGettingIntoPosition[];
-const u8 gText_PkmnBeganGrowlingDeeply[];
-const u8 gText_PkmnEagerForMore[];
-const u8 gText_DefeatedOpponentByReferee[];
-const u8 gText_LostToOpponentByReferee[];
-const u8 gText_TiedOpponentByReferee[];
-const u8 gText_QuestionForfeitMatch[];
-const u8 gText_ForfeitedMatch[];
-const u8 gText_Trainer1WinText[];
-const u8 gText_Trainer2WinText[];
-const u8 gText_TwoInGameTrainersDefeated[];
-const u8 gText_Trainer2LoseText[];
+static const u8 sText_PkmnIncapableOfPower[];
+static const u8 sText_GlintAppearsInEye[];
+static const u8 sText_PkmnGettingIntoPosition[];
+static const u8 sText_PkmnBeganGrowlingDeeply[];
+static const u8 sText_PkmnEagerForMore[];
+static const u8 sText_DefeatedOpponentByReferee[];
+static const u8 sText_LostToOpponentByReferee[];
+static const u8 sText_TiedOpponentByReferee[];
+static const u8 sText_QuestionForfeitMatch[];
+static const u8 sText_ForfeitedMatch[];
+static const u8 sText_Trainer1WinText[];
+static const u8 sText_Trainer2WinText[];
+static const u8 sText_TwoInGameTrainersDefeated[];
+static const u8 sText_Trainer2LoseText[];
const u8 * const gBattleStringsTable[BATTLESTRINGS_COUNT] =
{
- gText_Trainer1LoseText,
- gText_PkmnGainedEXP,
- gText_PkmnGrewToLv,
- gText_PkmnLearnedMove,
- gText_TryToLearnMove1,
- gText_TryToLearnMove2,
- gText_TryToLearnMove3,
- gText_PkmnForgotMove,
- gText_StopLearningMove,
- gText_DidNotLearnMove,
- gText_PkmnLearnedMove2,
- gText_AttackMissed,
- gText_PkmnProtectedItself,
- gText_StatsWontIncrease2,
- gText_AvoidedDamage,
- gText_ItDoesntAffect,
- gText_AttackerFainted,
- gText_TargetFainted,
- gText_PlayerGotMoney,
- gText_PlayerWhiteout,
- gText_PlayerWhiteout2,
- gText_PreventsEscape,
- gText_HitXTimes,
- gText_PkmnFellAsleep,
- gText_PkmnMadeSleep,
- gText_PkmnAlreadyAsleep,
- gText_PkmnAlreadyAsleep2,
- gText_PkmnWasntAffected,
- gText_PkmnWasPoisoned,
- gText_PkmnPoisonedBy,
- gText_PkmnHurtByPoison,
- gText_PkmnAlreadyPoisoned,
- gText_PkmnBadlyPoisoned,
- gText_PkmnEnergyDrained,
- gText_PkmnWasBurned,
- gText_PkmnBurnedBy,
- gText_PkmnHurtByBurn,
- gText_PkmnWasFrozen,
- gText_PkmnFrozenBy,
- gText_PkmnIsFrozen,
- gText_PkmnWasDefrosted,
- gText_PkmnWasDefrosted2,
- gText_PkmnWasDefrostedBy,
- gText_PkmnWasParalyzed,
- gText_PkmnWasParalyzedBy,
- gText_PkmnIsParalyzed,
- gText_PkmnIsAlreadyParalyzed,
- gText_PkmnHealedParalysis,
- gText_PkmnDreamEaten,
- gText_StatsWontIncrease,
- gText_StatsWontDecrease,
- gText_TeamStoppedWorking,
- gText_FoeStoppedWorking,
- gText_PkmnIsConfused,
- gText_PkmnHealedConfusion,
- gText_PkmnWasConfused,
- gText_PkmnAlreadyConfused,
- gText_PkmnFellInLove,
- gText_PkmnInLove,
- gText_PkmnImmobilizedByLove,
- gText_PkmnBlownAway,
- gText_PkmnChangedType,
- gText_PkmnFlinched,
- gText_PkmnRegainedHealth,
- gText_PkmnHPFull,
- gText_PkmnRaisedSpDef,
- gText_PkmnRaisedDef,
- gText_PkmnCoveredByVeil,
- gText_PkmnUsedSafeguard,
- gText_PkmnSafeguardExpired,
- gText_PkmnWentToSleep,
- gText_PkmnSleptHealthy,
- gText_PkmnWhippedWhirlwind,
- gText_PkmnTookSunlight,
- gText_PkmnLoweredHead,
- gText_PkmnIsGlowing,
- gText_PkmnFlewHigh,
- gText_PkmnDugHole,
- gText_PkmnSqueezedByBind,
- gText_PkmnTrappedInVortex,
- gText_PkmnWrappedBy,
- gText_PkmnClamped,
- gText_PkmnHurtBy,
- gText_PkmnFreedFrom,
- gText_PkmnCrashed,
- gText_PkmnShroudedInMist,
- gText_PkmnProtectedByMist,
- gText_PkmnGettingPumped,
- gText_PkmnHitWithRecoil,
- gText_PkmnProtectedItself2,
- gText_PkmnBuffetedBySandstorm,
- gText_PkmnPeltedByHail,
- gText_PkmnSeeded,
- gText_PkmnEvadedAttack,
- gText_PkmnSappedByLeechSeed,
- gText_PkmnFastAsleep,
- gText_PkmnWokeUp,
- gText_PkmnUproarKeptAwake,
- gText_PkmnWokeUpInUproar,
- gText_PkmnCausedUproar,
- gText_PkmnMakingUproar,
- gText_PkmnCalmedDown,
- gText_PkmnCantSleepInUproar,
- gText_PkmnStockpiled,
- gText_PkmnCantStockpile,
- gText_PkmnCantSleepInUproar2,
- gText_UproarKeptPkmnAwake,
- gText_PkmnStayedAwakeUsing,
- gText_PkmnStoringEnergy,
- gText_PkmnUnleashedEnergy,
- gText_PkmnFatigueConfusion,
- gText_PkmnPickedUpItem,
- gText_PkmnUnaffected,
- gText_PkmnTransformedInto,
- gText_PkmnMadeSubstitute,
- gText_PkmnHasSubstitute,
- gText_SubstituteDamaged,
- gText_PkmnSubstituteFaded,
- gText_PkmnMustRecharge,
- gText_PkmnRageBuilding,
- gText_PkmnMoveWasDisabled,
- gText_PkmnMoveIsDisabled,
- gText_PkmnMoveDisabledNoMore,
- gText_PkmnGotEncore,
- gText_PkmnEncoreEnded,
- gText_PkmnTookAim,
- gText_PkmnSketchedMove,
- gText_PkmnTryingToTakeFoe,
- gText_PkmnTookFoe,
- gText_PkmnReducedPP,
- gText_PkmnStoleItem,
- gText_TargetCantEscapeNow,
- gText_PkmnFellIntoNightmare,
- gText_PkmnLockedInNightmare,
- gText_PkmnLaidCurse,
- gText_PkmnAfflictedByCurse,
- gText_SpikesScattered,
- gText_PkmnHurtBySpikes,
- gText_PkmnIdentified,
- gText_PkmnPerishCountFell,
- gText_PkmnBracedItself,
- gText_PkmnEnduredHit,
- gText_MagnitudeStrength,
- gText_PkmnCutHPMaxedAttack,
- gText_PkmnCopiedStatChanges,
- gText_PkmnGotFree,
- gText_PkmnShedLeechSeed,
- gText_PkmnBlewAwaySpikes,
- gText_PkmnFledFromBattle,
- gText_PkmnForesawAttack,
- gText_PkmnTookAttack,
- gText_PkmnAttack,
- gText_PkmnCenterAttention,
- gText_PkmnChargingPower,
- gText_NaturePowerTurnedInto,
- gText_PkmnStatusNormal,
- gText_PkmnHasNoMovesLeft,
- gText_PkmnSubjectedToTorment,
- gText_PkmnCantUseMoveTorment,
- gText_PkmnTighteningFocus,
- gText_PkmnFellForTaunt,
- gText_PkmnCantUseMoveTaunt,
- gText_PkmnReadyToHelp,
- gText_PkmnSwitchedItems,
- gText_PkmnCopiedFoe,
- gText_PkmnMadeWish,
- gText_PkmnWishCameTrue,
- gText_PkmnPlantedRoots,
- gText_PkmnAbsorbedNutrients,
- gText_PkmnAnchoredItself,
- gText_PkmnWasMadeDrowsy,
- gText_PkmnKnockedOff,
- gText_PkmnSwappedAbilities,
- gText_PkmnSealedOpponentMove,
- gText_PkmnCantUseMoveSealed,
- gText_PkmnWantsGrudge,
- gText_PkmnLostPPGrudge,
- gText_PkmnShroudedItself,
- gText_PkmnMoveBounced,
- gText_PkmnWaitsForTarget,
- gText_PkmnSnatchedMove,
- gText_PkmnMadeItRain,
- gText_PkmnRaisedSpeed,
- gText_PkmnProtectedBy,
- gText_PkmnPreventsUsage,
- gText_PkmnRestoredHPUsing,
- gText_PkmnChangedTypeWith,
- gText_PkmnPreventsParalysisWith,
- gText_PkmnPreventsRomanceWith,
- gText_PkmnPreventsPoisoningWith,
- gText_PkmnPreventsConfusionWith,
- gText_PkmnRaisedFirePowerWith,
- gText_PkmnAnchorsItselfWith,
- gText_PkmnCutsAttackWith,
- gText_PkmnPreventsStatLossWith,
- gText_PkmnHurtsWith,
- gText_PkmnTraced,
- gText_StatSharply,
- gText_StatRose,
- gText_StatHarshly,
- gText_StatFell,
- gText_PkmnsStatChanged,
- gText_PkmnsStatChanged2,
- gText_PkmnsStatChanged3,
- gText_PkmnsStatChanged4,
- gText_CriticalHit,
- gText_OneHitKO,
- gText_123Poof,
- gText_AndEllipsis,
- gText_NotVeryEffective,
- gText_SuperEffective,
- gText_GotAwaySafely,
- gText_WildPkmnFled,
- gText_NoRunningFromTrainers,
- gText_CantEscape,
- gText_DontLeaveBirch,
- gText_ButNothingHappened,
- gText_ButItFailed,
- gText_ItHurtConfusion,
- gText_MirrorMoveFailed,
- gText_StartedToRain,
- gText_DownpourStarted,
- gText_RainContinues,
- gText_DownpourContinues,
- gText_RainStopped,
- gText_SandstormBrewed,
- gText_SandstormRages,
- gText_SandstormSubsided,
- gText_SunlightGotBright,
- gText_SunlightStrong,
- gText_SunlightFaded,
- gText_StartedHail,
- gText_HailContinues,
- gText_HailStopped,
- gText_FailedToSpitUp,
- gText_FailedToSwallow,
- gText_WindBecameHeatWave,
- gText_StatChangesGone,
- gText_CoinsScattered,
- gText_TooWeakForSubstitute,
- gText_SharedPain,
- gText_BellChimed,
- gText_FaintInThree,
- gText_NoPPLeft,
- gText_ButNoPPLeft,
- gText_PlayerUsedItem,
- gText_WallyUsedItem,
- gText_TrainerBlockedBall,
- gText_DontBeAThief,
- gText_ItDodgedBall,
- gText_YouMissedPkmn,
- gText_PkmnBrokeFree,
- gText_ItAppearedCaught,
- gText_AarghAlmostHadIt,
- gText_ShootSoClose,
- gText_GotchaPkmnCaught,
- gText_GotchaPkmnCaught2,
- gText_GiveNicknameCaptured,
- gText_PkmnSentToPC,
- gText_PkmnDataAddedToDex,
- gText_ItIsRaining,
- gText_SandstormIsRaging,
- gText_CantEscape2,
- gText_PkmnIgnoresAsleep,
- gText_PkmnIgnoredOrders,
- gText_PkmnBeganToNap,
- gText_PkmnLoafing,
- gText_PkmnWontObey,
- gText_PkmnTurnedAway,
- gText_PkmnPretendNotNotice,
- gText_EnemyAboutToSwitchPkmn,
- gText_CreptCloser,
- gText_CantGetCloser,
- gText_PkmnWatchingCarefully,
- gText_PkmnCuriousAboutX,
- gText_PkmnEnthralledByX,
- gText_PkmnIgnoredX,
- gText_ThrewPokeblockAtPkmn,
- gText_OutOfSafariBalls,
- gText_PkmnsItemCuredParalysis,
- gText_PkmnsItemCuredPoison,
- gText_PkmnsItemHealedBurn,
- gText_PkmnsItemDefrostedIt,
- gText_PkmnsItemWokeIt,
- gText_PkmnsItemSnappedOut,
- gText_PkmnsItemCuredProblem,
- gText_PkmnsItemRestoredHealth,
- gText_PkmnsItemRestoredPP,
- gText_PkmnsItemRestoredStatus,
- gText_PkmnsItemRestoredHPALittle,
- gText_ItemAllowsOnlyYMove,
- gText_PkmnHungOnWithX,
- gText_EmptyString3,
- gText_PkmnsXPreventsBurns,
- gText_PkmnsXBlocksY,
- gText_PkmnsXRestoredHPALittle2,
- gText_PkmnsXWhippedUpSandstorm,
- gText_PkmnsXPreventsYLoss,
- gText_PkmnsXInfatuatedY,
- gText_PkmnsXMadeYIneffective,
- gText_PkmnsXCuredYProblem,
- gText_ItSuckedLiquidOoze,
- gText_PkmnTransformed,
- gText_ElectricityWeakened,
- gText_FireWeakened,
- gText_PkmnHidUnderwater,
- gText_PkmnSprangUp,
- gText_HMMovesCantBeForgotten,
- gText_XFoundOneY,
- gText_PlayerDefeatedLinkTrainerTrainer1,
- gText_SoothingAroma,
- gText_ItemsCantBeUsedNow,
- gText_ForXCommaYZ,
- gText_UsingXTheYOfZN,
- gText_PkmnUsedXToGetPumped,
- gText_PkmnsXMadeYUseless,
- gText_PkmnTrappedBySandTomb,
- gText_EmptyString4,
- gText_ABoosted,
- gText_PkmnsXIntensifiedSun,
- gText_PkmnMakesGroundMiss,
- gText_YouThrowABallNowRight,
- gText_PkmnsXTookAttack,
- gText_PkmnChoseXAsDestiny,
- gText_PkmnLostFocus,
- gText_UseNextPkmn,
- gText_PkmnFledUsingIts,
- gText_PkmnFledUsing,
- gText_PkmnWasDraggedOut,
- gText_PreventedFromWorking,
- gText_PkmnsItemNormalizedStatus,
- gText_Trainer1UsedItem,
- gText_BoxIsFull,
- gText_PkmnAvoidedAttack,
- gText_PkmnsXMadeItIneffective,
- gText_PkmnsXPreventsFlinching,
- gText_PkmnAlreadyHasBurn,
- gText_StatsWontDecrease2,
- gText_PkmnsXBlocksY2,
- gText_PkmnsXWoreOff,
- gText_PkmnRaisedDefALittle,
- gText_PkmnRaisedSpDefALittle,
- gText_TheWallShattered,
- gText_PkmnsXPreventsYsZ,
- gText_PkmnsXCuredItsYProblem,
- gText_AttackerCantEscape,
- gText_PkmnObtainedX,
- gText_PkmnObtainedX2,
- gText_PkmnObtainedXYObtainedZ,
- gText_ButNoEffect,
- gText_PkmnsXHadNoEffectOnY,
- gText_TwoInGameTrainersDefeated,
- gText_Trainer2LoseText,
- gText_PkmnIncapableOfPower,
- gText_GlintAppearsInEye,
- gText_PkmnGettingIntoPosition,
- gText_PkmnBeganGrowlingDeeply,
- gText_PkmnEagerForMore,
- gText_DefeatedOpponentByReferee,
- gText_LostToOpponentByReferee,
- gText_TiedOpponentByReferee,
- gText_QuestionForfeitMatch,
- gText_ForfeitedMatch,
- gText_PkmnTransferredSomeonesPC,
- gText_PkmnTransferredLanettesPC,
- gText_PkmnBoxSomeonesPCFull,
- gText_PkmnBoxLanettesPCFull,
- gText_Trainer1WinText,
- gText_Trainer2WinText,
+ sText_Trainer1LoseText, // 12
+ sText_PkmnGainedEXP, // 13
+ sText_PkmnGrewToLv, // 14
+ sText_PkmnLearnedMove, // 15
+ sText_TryToLearnMove1, // 16
+ sText_TryToLearnMove2, // 17
+ sText_TryToLearnMove3, // 18
+ sText_PkmnForgotMove, // 19
+ sText_StopLearningMove, // 20
+ sText_DidNotLearnMove, // 21
+ sText_PkmnLearnedMove2, // 22
+ sText_AttackMissed, // 23
+ sText_PkmnProtectedItself, // 24
+ sText_StatsWontIncrease2, // 25
+ sText_AvoidedDamage, // 26
+ sText_ItDoesntAffect, // 27
+ sText_AttackerFainted, // 28
+ sText_TargetFainted, // 29
+ sText_PlayerGotMoney, // 30
+ sText_PlayerWhiteout, // 31
+ sText_PlayerWhiteout2, // 32
+ sText_PreventsEscape, // 33
+ sText_HitXTimes, // 34
+ sText_PkmnFellAsleep, // 35
+ sText_PkmnMadeSleep, // 36
+ sText_PkmnAlreadyAsleep, // 37
+ sText_PkmnAlreadyAsleep2, // 38
+ sText_PkmnWasntAffected, // 39
+ sText_PkmnWasPoisoned, // 40
+ sText_PkmnPoisonedBy, // 41
+ sText_PkmnHurtByPoison, // 42
+ sText_PkmnAlreadyPoisoned, // 43
+ sText_PkmnBadlyPoisoned, // 44
+ sText_PkmnEnergyDrained, // 45
+ sText_PkmnWasBurned, // 46
+ sText_PkmnBurnedBy, // 47
+ sText_PkmnHurtByBurn, // 48
+ sText_PkmnWasFrozen, // 49
+ sText_PkmnFrozenBy, // 50
+ sText_PkmnIsFrozen, // 51
+ sText_PkmnWasDefrosted, // 52
+ sText_PkmnWasDefrosted2, // 53
+ sText_PkmnWasDefrostedBy, // 54
+ sText_PkmnWasParalyzed, // 55
+ sText_PkmnWasParalyzedBy, // 56
+ sText_PkmnIsParalyzed, // 57
+ sText_PkmnIsAlreadyParalyzed, // 58
+ sText_PkmnHealedParalysis, // 59
+ sText_PkmnDreamEaten, // 60
+ sText_StatsWontIncrease, // 61
+ sText_StatsWontDecrease, // 62
+ sText_TeamStoppedWorking, // 63
+ sText_FoeStoppedWorking, // 64
+ sText_PkmnIsConfused, // 65
+ sText_PkmnHealedConfusion, // 66
+ sText_PkmnWasConfused, // 67
+ sText_PkmnAlreadyConfused, // 68
+ sText_PkmnFellInLove, // 69
+ sText_PkmnInLove, // 70
+ sText_PkmnImmobilizedByLove, // 71
+ sText_PkmnBlownAway, // 72
+ sText_PkmnChangedType, // 73
+ sText_PkmnFlinched, // 74
+ sText_PkmnRegainedHealth, // 75
+ sText_PkmnHPFull, // 76
+ sText_PkmnRaisedSpDef, // 77
+ sText_PkmnRaisedDef, // 78
+ sText_PkmnCoveredByVeil, // 79
+ sText_PkmnUsedSafeguard, // 80
+ sText_PkmnSafeguardExpired, // 81
+ sText_PkmnWentToSleep, // 82
+ sText_PkmnSleptHealthy, // 83
+ sText_PkmnWhippedWhirlwind, // 84
+ sText_PkmnTookSunlight, // 85
+ sText_PkmnLoweredHead, // 86
+ sText_PkmnIsGlowing, // 87
+ sText_PkmnFlewHigh, // 88
+ sText_PkmnDugHole, // 89
+ sText_PkmnSqueezedByBind, // 90
+ sText_PkmnTrappedInVortex, // 91
+ sText_PkmnWrappedBy, // 92
+ sText_PkmnClamped, // 93
+ sText_PkmnHurtBy, // 94
+ sText_PkmnFreedFrom, // 95
+ sText_PkmnCrashed, // 96
+ gText_PkmnShroudedInMist, // 97
+ sText_PkmnProtectedByMist, // 98
+ gText_PkmnGettingPumped, // 99
+ sText_PkmnHitWithRecoil, // 100
+ sText_PkmnProtectedItself2, // 101
+ sText_PkmnBuffetedBySandstorm, // 102
+ sText_PkmnPeltedByHail, // 103
+ sText_PkmnSeeded, // 104
+ sText_PkmnEvadedAttack, // 105
+ sText_PkmnSappedByLeechSeed, // 106
+ sText_PkmnFastAsleep, // 107
+ sText_PkmnWokeUp, // 108
+ sText_PkmnUproarKeptAwake, // 109
+ sText_PkmnWokeUpInUproar, // 110
+ sText_PkmnCausedUproar, // 111
+ sText_PkmnMakingUproar, // 112
+ sText_PkmnCalmedDown, // 113
+ sText_PkmnCantSleepInUproar, // 114
+ sText_PkmnStockpiled, // 115
+ sText_PkmnCantStockpile, // 116
+ sText_PkmnCantSleepInUproar2, // 117
+ sText_UproarKeptPkmnAwake, // 118
+ sText_PkmnStayedAwakeUsing, // 119
+ sText_PkmnStoringEnergy, // 120
+ sText_PkmnUnleashedEnergy, // 121
+ sText_PkmnFatigueConfusion, // 122
+ sText_PkmnPickedUpItem, // 123
+ sText_PkmnUnaffected, // 124
+ sText_PkmnTransformedInto, // 125
+ sText_PkmnMadeSubstitute, // 126
+ sText_PkmnHasSubstitute, // 127
+ sText_SubstituteDamaged, // 128
+ sText_PkmnSubstituteFaded, // 129
+ sText_PkmnMustRecharge, // 130
+ sText_PkmnRageBuilding, // 131
+ sText_PkmnMoveWasDisabled, // 132
+ sText_PkmnMoveIsDisabled, // 133
+ sText_PkmnMoveDisabledNoMore, // 134
+ sText_PkmnGotEncore, // 135
+ sText_PkmnEncoreEnded, // 136
+ sText_PkmnTookAim, // 137
+ sText_PkmnSketchedMove, // 138
+ sText_PkmnTryingToTakeFoe, // 139
+ sText_PkmnTookFoe, // 140
+ sText_PkmnReducedPP, // 141
+ sText_PkmnStoleItem, // 142
+ sText_TargetCantEscapeNow, // 143
+ sText_PkmnFellIntoNightmare, // 144
+ sText_PkmnLockedInNightmare, // 145
+ sText_PkmnLaidCurse, // 146
+ sText_PkmnAfflictedByCurse, // 147
+ sText_SpikesScattered, // 148
+ sText_PkmnHurtBySpikes, // 149
+ sText_PkmnIdentified, // 150
+ sText_PkmnPerishCountFell, // 151
+ sText_PkmnBracedItself, // 152
+ sText_PkmnEnduredHit, // 153
+ sText_MagnitudeStrength, // 154
+ sText_PkmnCutHPMaxedAttack, // 155
+ sText_PkmnCopiedStatChanges, // 156
+ sText_PkmnGotFree, // 157
+ sText_PkmnShedLeechSeed, // 158
+ sText_PkmnBlewAwaySpikes, // 159
+ sText_PkmnFledFromBattle, // 160
+ sText_PkmnForesawAttack, // 161
+ sText_PkmnTookAttack, // 162
+ sText_PkmnAttack, // 163
+ sText_PkmnCenterAttention, // 164
+ sText_PkmnChargingPower, // 165
+ sText_NaturePowerTurnedInto, // 166
+ sText_PkmnStatusNormal, // 167
+ sText_PkmnHasNoMovesLeft, // 168
+ sText_PkmnSubjectedToTorment, // 169
+ sText_PkmnCantUseMoveTorment, // 170
+ sText_PkmnTighteningFocus, // 171
+ sText_PkmnFellForTaunt, // 172
+ sText_PkmnCantUseMoveTaunt, // 173
+ sText_PkmnReadyToHelp, // 174
+ sText_PkmnSwitchedItems, // 175
+ sText_PkmnCopiedFoe, // 176
+ sText_PkmnMadeWish, // 177
+ sText_PkmnWishCameTrue, // 178
+ sText_PkmnPlantedRoots, // 179
+ sText_PkmnAbsorbedNutrients, // 180
+ sText_PkmnAnchoredItself, // 181
+ sText_PkmnWasMadeDrowsy, // 182
+ sText_PkmnKnockedOff, // 183
+ sText_PkmnSwappedAbilities, // 184
+ sText_PkmnSealedOpponentMove, // 185
+ sText_PkmnCantUseMoveSealed, // 186
+ sText_PkmnWantsGrudge, // 187
+ sText_PkmnLostPPGrudge, // 188
+ sText_PkmnShroudedItself, // 189
+ sText_PkmnMoveBounced, // 190
+ sText_PkmnWaitsForTarget, // 191
+ sText_PkmnSnatchedMove, // 192
+ sText_PkmnMadeItRain, // 193
+ sText_PkmnRaisedSpeed, // 194
+ sText_PkmnProtectedBy, // 195
+ sText_PkmnPreventsUsage, // 196
+ sText_PkmnRestoredHPUsing, // 197
+ sText_PkmnChangedTypeWith, // 198
+ sText_PkmnPreventsParalysisWith, // 199
+ sText_PkmnPreventsRomanceWith, // 200
+ sText_PkmnPreventsPoisoningWith, // 201
+ sText_PkmnPreventsConfusionWith, // 202
+ sText_PkmnRaisedFirePowerWith, // 203
+ sText_PkmnAnchorsItselfWith, // 204
+ sText_PkmnCutsAttackWith, // 205
+ sText_PkmnPreventsStatLossWith, // 206
+ sText_PkmnHurtsWith, // 207
+ sText_PkmnTraced, // 208
+ sText_StatSharply, // 209
+ gText_StatRose, // 210
+ sText_StatHarshly, // 211
+ sText_StatFell, // 212
+ sText_PkmnsStatChanged, // 213
+ gText_PkmnsStatChanged2, // 214
+ sText_PkmnsStatChanged3, // 215
+ sText_PkmnsStatChanged4, // 216
+ sText_CriticalHit, // 217
+ sText_OneHitKO, // 218
+ sText_123Poof, // 219
+ sText_AndEllipsis, // 220
+ sText_NotVeryEffective, // 221
+ sText_SuperEffective, // 222
+ sText_GotAwaySafely, // 223
+ sText_WildPkmnFled, // 224
+ sText_NoRunningFromTrainers, // 225
+ sText_CantEscape, // 226
+ sText_DontLeaveBirch, // 227
+ sText_ButNothingHappened, // 228
+ sText_ButItFailed, // 229
+ sText_ItHurtConfusion, // 230
+ sText_MirrorMoveFailed, // 231
+ sText_StartedToRain, // 232
+ sText_DownpourStarted, // 233
+ sText_RainContinues, // 234
+ sText_DownpourContinues, // 235
+ sText_RainStopped, // 236
+ sText_SandstormBrewed, // 237
+ sText_SandstormRages, // 238
+ sText_SandstormSubsided, // 239
+ sText_SunlightGotBright, // 240
+ sText_SunlightStrong, // 241
+ sText_SunlightFaded, // 242
+ sText_StartedHail, // 243
+ sText_HailContinues, // 244
+ sText_HailStopped, // 245
+ sText_FailedToSpitUp, // 246
+ sText_FailedToSwallow, // 247
+ sText_WindBecameHeatWave, // 248
+ sText_StatChangesGone, // 249
+ sText_CoinsScattered, // 250
+ sText_TooWeakForSubstitute, // 251
+ sText_SharedPain, // 252
+ sText_BellChimed, // 253
+ sText_FaintInThree, // 254
+ sText_NoPPLeft, // 255
+ sText_ButNoPPLeft, // 256
+ sText_PlayerUsedItem, // 257
+ sText_WallyUsedItem, // 258
+ sText_TrainerBlockedBall, // 259
+ sText_DontBeAThief, // 260
+ sText_ItDodgedBall, // 261
+ sText_YouMissedPkmn, // 262
+ sText_PkmnBrokeFree, // 263
+ sText_ItAppearedCaught, // 264
+ sText_AarghAlmostHadIt, // 265
+ sText_ShootSoClose, // 266
+ sText_GotchaPkmnCaught, // 267
+ sText_GotchaPkmnCaught2, // 268
+ sText_GiveNicknameCaptured, // 269
+ sText_PkmnSentToPC, // 270
+ sText_PkmnDataAddedToDex, // 271
+ sText_ItIsRaining, // 272
+ sText_SandstormIsRaging, // 273
+ sText_CantEscape2, // 274
+ sText_PkmnIgnoresAsleep, // 275
+ sText_PkmnIgnoredOrders, // 276
+ sText_PkmnBeganToNap, // 277
+ sText_PkmnLoafing, // 278
+ sText_PkmnWontObey, // 279
+ sText_PkmnTurnedAway, // 280
+ sText_PkmnPretendNotNotice, // 281
+ sText_EnemyAboutToSwitchPkmn, // 282
+ sText_CreptCloser, // 283
+ sText_CantGetCloser, // 284
+ sText_PkmnWatchingCarefully, // 285
+ sText_PkmnCuriousAboutX, // 286
+ sText_PkmnEnthralledByX, // 287
+ sText_PkmnIgnoredX, // 288
+ sText_ThrewPokeblockAtPkmn, // 289
+ sText_OutOfSafariBalls, // 290
+ sText_PkmnsItemCuredParalysis, // 291
+ sText_PkmnsItemCuredPoison, // 292
+ sText_PkmnsItemHealedBurn, // 293
+ sText_PkmnsItemDefrostedIt, // 294
+ sText_PkmnsItemWokeIt, // 295
+ sText_PkmnsItemSnappedOut, // 296
+ sText_PkmnsItemCuredProblem, // 297
+ sText_PkmnsItemRestoredHealth, // 298
+ sText_PkmnsItemRestoredPP, // 299
+ sText_PkmnsItemRestoredStatus, // 300
+ sText_PkmnsItemRestoredHPALittle, // 301
+ sText_ItemAllowsOnlyYMove, // 302
+ sText_PkmnHungOnWithX, // 303
+ gText_EmptyString3, // 304
+ sText_PkmnsXPreventsBurns, // 305
+ sText_PkmnsXBlocksY, // 306
+ sText_PkmnsXRestoredHPALittle2, // 307
+ sText_PkmnsXWhippedUpSandstorm, // 308
+ sText_PkmnsXPreventsYLoss, // 309
+ sText_PkmnsXInfatuatedY, // 310
+ sText_PkmnsXMadeYIneffective, // 311
+ sText_PkmnsXCuredYProblem, // 312
+ sText_ItSuckedLiquidOoze, // 313
+ sText_PkmnTransformed, // 314
+ sText_ElectricityWeakened, // 315
+ sText_FireWeakened, // 316
+ sText_PkmnHidUnderwater, // 317
+ sText_PkmnSprangUp, // 318
+ sText_HMMovesCantBeForgotten, // 319
+ sText_XFoundOneY, // 320
+ sText_PlayerDefeatedLinkTrainerTrainer1, // 321
+ sText_SoothingAroma, // 322
+ sText_ItemsCantBeUsedNow, // 323
+ sText_ForXCommaYZ, // 324
+ sText_UsingXTheYOfZN, // 325
+ sText_PkmnUsedXToGetPumped, // 326
+ sText_PkmnsXMadeYUseless, // 327
+ sText_PkmnTrappedBySandTomb, // 328
+ sText_EmptyString4, // 329
+ sText_ABoosted, // 330
+ sText_PkmnsXIntensifiedSun, // 331
+ sText_PkmnMakesGroundMiss, // 332
+ sText_YouThrowABallNowRight, // 333
+ sText_PkmnsXTookAttack, // 334
+ sText_PkmnChoseXAsDestiny, // 335
+ sText_PkmnLostFocus, // 336
+ sText_UseNextPkmn, // 337
+ sText_PkmnFledUsingIts, // 338
+ sText_PkmnFledUsing, // 339
+ sText_PkmnWasDraggedOut, // 340
+ sText_PreventedFromWorking, // 341
+ sText_PkmnsItemNormalizedStatus, // 342
+ sText_Trainer1UsedItem, // 343
+ sText_BoxIsFull, // 344
+ sText_PkmnAvoidedAttack, // 345
+ sText_PkmnsXMadeItIneffective, // 346
+ sText_PkmnsXPreventsFlinching, // 347
+ sText_PkmnAlreadyHasBurn, // 348
+ sText_StatsWontDecrease2, // 349
+ sText_PkmnsXBlocksY2, // 350
+ sText_PkmnsXWoreOff, // 351
+ sText_PkmnRaisedDefALittle, // 352
+ sText_PkmnRaisedSpDefALittle, // 353
+ sText_TheWallShattered, // 354
+ sText_PkmnsXPreventsYsZ, // 355
+ sText_PkmnsXCuredItsYProblem, // 356
+ sText_AttackerCantEscape, // 357
+ sText_PkmnObtainedX, // 358
+ sText_PkmnObtainedX2, // 359
+ sText_PkmnObtainedXYObtainedZ, // 360
+ sText_ButNoEffect, // 361
+ sText_PkmnsXHadNoEffectOnY, // 362
+ sText_TwoInGameTrainersDefeated, // 363
+ sText_Trainer2LoseText, // 364
+ sText_PkmnIncapableOfPower, // 365
+ sText_GlintAppearsInEye, // 366
+ sText_PkmnGettingIntoPosition, // 367
+ sText_PkmnBeganGrowlingDeeply, // 368
+ sText_PkmnEagerForMore, // 369
+ sText_DefeatedOpponentByReferee, // 370
+ sText_LostToOpponentByReferee, // 371
+ sText_TiedOpponentByReferee, // 372
+ sText_QuestionForfeitMatch, // 373
+ sText_ForfeitedMatch, // 374
+ gText_PkmnTransferredSomeonesPC, // 375
+ gText_PkmnTransferredLanettesPC, // 376
+ gText_PkmnBoxSomeonesPCFull, // 377
+ gText_PkmnBoxLanettesPCFull, // 378
+ sText_Trainer1WinText, // 379
+ sText_Trainer2WinText, // 380
};
const u16 gMissStringIds[] =
@@ -1176,16 +1174,16 @@ const u8 gText_BattleSwitchWhich3[] = _("{UP_ARROW}");
const u8 gText_BattleSwitchWhich4[] = _("{ESCAPE 4}");
const u8 gText_BattleSwitchWhich5[] = _("-");
-const u8 gText_HP[] = _("HP");
-const u8 gText_Attack[] = _("ATTACK");
-const u8 gText_Defense[] = _("DEFENSE");
-const u8 gText_SpAtk[] = _("SP. ATK");
-const u8 gText_SpDef[] = _("SP. DEF");
+static const u8 sText_HP[] = _("HP");
+static const u8 sText_Attack[] = _("ATTACK");
+static const u8 sText_Defense[] = _("DEFENSE");
+static const u8 sText_SpAtk[] = _("SP. ATK");
+static const u8 sText_SpDef[] = _("SP. DEF");
const u8 * const gStatNamesTable2[] =
{
- gText_HP, gText_SpAtk, gText_Attack,
- gText_SpDef, gText_Defense, gText_Speed
+ sText_HP, sText_SpAtk, sText_Attack,
+ sText_SpDef, sText_Defense, sText_Speed
};
const u8 gText_SafariBalls[] = _("{HIGHLIGHT DARK_GREY}SAFARI BALLS");
@@ -1202,10 +1200,10 @@ const u8 gText_BattleWallyName[] = _("WALLY");
const u8 gText_Win[] = _("{HIGHLIGHT TRANSPARENT}Win");
const u8 gText_Loss[] = _("{HIGHLIGHT TRANSPARENT}Loss");
const u8 gText_Draw[] = _("{HIGHLIGHT TRANSPARENT}Draw");
-const u8 gText_SpaceIs[] = _(" is");
-const u8 gText_ApostropheS[] = _("’s");
+static const u8 sText_SpaceIs[] = _(" is");
+static const u8 sText_ApostropheS[] = _("’s");
-const u8 gText_UnknownMoveTypes[][17] =
+static const u8 sATypeMove_Table[][17] =
{
_("a NORMAL move"),
_("a FIGHTING move"),
@@ -1228,17 +1226,17 @@ const u8 gText_UnknownMoveTypes[][17] =
};
const u8 gText_BattleTourney[] = _("BATTLE TOURNEY");
-const u8 gText_Round1[] = _("Round 1");
-const u8 gText_Round2[] = _("Round 2");
-const u8 gText_Semifinal[] = _("Semifinal");
-const u8 gText_Final[] = _("Final");
+static const u8 sText_Round1[] = _("Round 1");
+static const u8 sText_Round2[] = _("Round 2");
+static const u8 sText_Semifinal[] = _("Semifinal");
+static const u8 sText_Final[] = _("Final");
const u8 * const gRoundsStringTable[] =
{
- gText_Round1,
- gText_Round2,
- gText_Semifinal,
- gText_Final
+ sText_Round1,
+ sText_Round2,
+ sText_Semifinal,
+ sText_Final
};
const u8 gText_TheGreatNewHope[] = _("The great new hope!\p");
@@ -1253,17 +1251,17 @@ const u8 gText_Mind[] = _("Mind");
const u8 gText_Skill[] = _("Skill");
const u8 gText_Body[] = _("Body");
const u8 gText_Judgement[] = _("{B_BUFF1}{CLEAR 13}Judgment{CLEAR 13}{B_BUFF2}");
-const u8 gText_TwoTrainersSentPkmn[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME} sent\nout {B_OPPONENT_MON1_NAME}!\p{B_TRAINER2_CLASS} {B_TRAINER2_NAME} sent\nout {B_OPPONENT_MON2_NAME}!");
-const u8 gText_Trainer2SentOutPkmn[] = _("{B_TRAINER2_CLASS} {B_TRAINER2_NAME} sent\nout {B_BUFF1}!");
-const u8 gText_TwoTrainersWantToBattle[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME} and\n{B_TRAINER2_CLASS} {B_TRAINER2_NAME}\lwant to battle!\p");
-const u8 gText_InGamePartnerSentOutZGoN[] = _("{B_PARTNER_CLASS} {B_PARTNER_NAME} sent\nout {B_PLAYER_MON2_NAME}!\lGo, {B_PLAYER_MON1_NAME}!");
-const u8 gText_TwoInGameTrainersDefeated[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME} and\n{B_TRAINER2_CLASS} {B_TRAINER2_NAME}\lwere defeated!\p");
-const u8 gText_Trainer2LoseText[] = _("{B_TRAINER2_LOSE_TEXT}");
-const u8 gText_PkmnIncapableOfPower[] = _("{B_ATK_NAME_WITH_PREFIX} appears incapable\nof using its power!");
-const u8 gText_GlintAppearsInEye[] = _("A glint appears in\n{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s eyes!");
-const u8 gText_PkmnGettingIntoPosition[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is getting into\nposition!");
-const u8 gText_PkmnBeganGrowlingDeeply[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} began growling deeply!");
-const u8 gText_PkmnEagerForMore[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is eager for more!");
+static const u8 sText_TwoTrainersSentPkmn[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME} sent\nout {B_OPPONENT_MON1_NAME}!\p{B_TRAINER2_CLASS} {B_TRAINER2_NAME} sent\nout {B_OPPONENT_MON2_NAME}!");
+static const u8 sText_Trainer2SentOutPkmn[] = _("{B_TRAINER2_CLASS} {B_TRAINER2_NAME} sent\nout {B_BUFF1}!");
+static const u8 sText_TwoTrainersWantToBattle[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME} and\n{B_TRAINER2_CLASS} {B_TRAINER2_NAME}\lwant to battle!\p");
+static const u8 sText_InGamePartnerSentOutZGoN[] = _("{B_PARTNER_CLASS} {B_PARTNER_NAME} sent\nout {B_PLAYER_MON2_NAME}!\lGo, {B_PLAYER_MON1_NAME}!");
+static const u8 sText_TwoInGameTrainersDefeated[] = _("{B_TRAINER1_CLASS} {B_TRAINER1_NAME} and\n{B_TRAINER2_CLASS} {B_TRAINER2_NAME}\lwere defeated!\p");
+static const u8 sText_Trainer2LoseText[] = _("{B_TRAINER2_LOSE_TEXT}");
+static const u8 sText_PkmnIncapableOfPower[] = _("{B_ATK_NAME_WITH_PREFIX} appears incapable\nof using its power!");
+static const u8 sText_GlintAppearsInEye[] = _("A glint appears in\n{B_SCR_ACTIVE_NAME_WITH_PREFIX}’s eyes!");
+static const u8 sText_PkmnGettingIntoPosition[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is getting into\nposition!");
+static const u8 sText_PkmnBeganGrowlingDeeply[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} began growling deeply!");
+static const u8 sText_PkmnEagerForMore[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is eager for more!");
const u16 gStringIds_85CCF0A[] =
{
@@ -1271,43 +1269,43 @@ const u16 gStringIds_85CCF0A[] =
STRINGID_PKMNBEGANGROWLINGDEEPLY, STRINGID_PKMNEAGERFORMORE
};
-const u8 gText_RefIfNothingIsDecided[] = _("REFEREE: If nothing is decided in\n3 turns, we will go to judging!");
-const u8 gText_RefThatsIt[] = _("REFEREE: That’s it! We will now go to\njudging to determine the winner!");
-const u8 gText_RefJudgeMind[] = _("REFEREE: Judging category 1, Mind!\nThe POKéMON showing the most guts!\p");
-const u8 gText_RefJudgeSkill[] = _("REFEREE: Judging category 2, Skill!\nThe POKéMON using moves the best!\p");
-const u8 gText_RefJudgeBody[] = _("REFEREE: Judging category 3, Body!\nThe POKéMON with the most vitality!\p");
-const u8 gText_RefJudgement1[] = _("REFEREE: Judgment: {B_BUFF1} to {B_BUFF2}!\nThe winner is {B_PLAYER_NAME}’s {B_PLAYER_MON1_NAME}!\p");
-const u8 gText_RefJudgement2[] = _("REFEREE: Judgment: {B_BUFF1} to {B_BUFF2}!\nThe winner is {B_TRAINER1_NAME}’s {B_OPPONENT_MON1_NAME}!\p");
-const u8 gText_RefJudgement3[] = _("REFEREE: Judgment: 3 to 3!\nWe have a draw!\p");
-const u8 gText_DefeatedOpponentByReferee[] = _("{B_PLAYER_MON1_NAME} defeated the opponent\n{B_OPPONENT_MON1_NAME} in a REFEREE’s decision!");
-const u8 gText_LostToOpponentByReferee[] = _("{B_PLAYER_MON1_NAME} lost to the opponent\n{B_OPPONENT_MON1_NAME} in a REFEREE’s decision!");
-const u8 gText_TiedOpponentByReferee[] = _("{B_PLAYER_MON1_NAME} tied the opponent\n{B_OPPONENT_MON1_NAME} in a REFEREE’s decision!");
-const u8 gText_RefCommenceBattle[] = _("REFEREE: {B_PLAYER_MON1_NAME} VS {B_OPPONENT_MON1_NAME}!\nCommence battling!");
+static const u8 sText_RefIfNothingIsDecided[] = _("REFEREE: If nothing is decided in\n3 turns, we will go to judging!");
+static const u8 sText_RefThatsIt[] = _("REFEREE: That’s it! We will now go to\njudging to determine the winner!");
+static const u8 sText_RefJudgeMind[] = _("REFEREE: Judging category 1, Mind!\nThe POKéMON showing the most guts!\p");
+static const u8 sText_RefJudgeSkill[] = _("REFEREE: Judging category 2, Skill!\nThe POKéMON using moves the best!\p");
+static const u8 sText_RefJudgeBody[] = _("REFEREE: Judging category 3, Body!\nThe POKéMON with the most vitality!\p");
+static const u8 sText_RefJudgement1[] = _("REFEREE: Judgment: {B_BUFF1} to {B_BUFF2}!\nThe winner is {B_PLAYER_NAME}’s {B_PLAYER_MON1_NAME}!\p");
+static const u8 sText_RefJudgement2[] = _("REFEREE: Judgment: {B_BUFF1} to {B_BUFF2}!\nThe winner is {B_TRAINER1_NAME}’s {B_OPPONENT_MON1_NAME}!\p");
+static const u8 sText_RefJudgement3[] = _("REFEREE: Judgment: 3 to 3!\nWe have a draw!\p");
+static const u8 sText_DefeatedOpponentByReferee[] = _("{B_PLAYER_MON1_NAME} defeated the opponent\n{B_OPPONENT_MON1_NAME} in a REFEREE’s decision!");
+static const u8 sText_LostToOpponentByReferee[] = _("{B_PLAYER_MON1_NAME} lost to the opponent\n{B_OPPONENT_MON1_NAME} in a REFEREE’s decision!");
+static const u8 sText_TiedOpponentByReferee[] = _("{B_PLAYER_MON1_NAME} tied the opponent\n{B_OPPONENT_MON1_NAME} in a REFEREE’s decision!");
+static const u8 sText_RefCommenceBattle[] = _("REFEREE: {B_PLAYER_MON1_NAME} VS {B_OPPONENT_MON1_NAME}!\nCommence battling!");
const u8 * const gRefereeStringsTable[] =
{
- gText_RefIfNothingIsDecided,
- gText_RefThatsIt,
- gText_RefJudgeMind,
- gText_RefJudgeSkill,
- gText_RefJudgeBody,
- gText_RefJudgement1,
- gText_RefJudgement2,
- gText_RefJudgement3,
- gText_RefCommenceBattle,
+ sText_RefIfNothingIsDecided,
+ sText_RefThatsIt,
+ sText_RefJudgeMind,
+ sText_RefJudgeSkill,
+ sText_RefJudgeBody,
+ sText_RefJudgement1,
+ sText_RefJudgement2,
+ sText_RefJudgement3,
+ sText_RefCommenceBattle,
};
-const u8 gText_QuestionForfeitMatch[] = _("Would you like to forfeit the match\nand quit now?");
-const u8 gText_ForfeitedMatch[] = _("{B_PLAYER_NAME} forfeited the match!");
-const u8 gText_Trainer1WinText[] = _("{B_TRAINER1_WIN_TEXT}");
-const u8 gText_Trainer2WinText[] = _("{B_TRAINER2_WIN_TEXT}");
-const u8 gText_Trainer1Fled[] = _( "{PLAY_SE 0x0011}{B_TRAINER1_CLASS} {B_TRAINER1_NAME} fled!");
-const u8 gText_PlayerLostAgainstTrainer1[] = _("Player lost against\n{B_TRAINER1_CLASS} {B_TRAINER1_NAME}!");
-const u8 gText_PlayerBattledToDrawTrainer1[] = _("Player battled to a draw against\n{B_TRAINER1_CLASS} {B_TRAINER1_NAME}!");
+static const u8 sText_QuestionForfeitMatch[] = _("Would you like to forfeit the match\nand quit now?");
+static const u8 sText_ForfeitedMatch[] = _("{B_PLAYER_NAME} forfeited the match!");
+static const u8 sText_Trainer1WinText[] = _("{B_TRAINER1_WIN_TEXT}");
+static const u8 sText_Trainer2WinText[] = _("{B_TRAINER2_WIN_TEXT}");
+static const u8 sText_Trainer1Fled[] = _( "{PLAY_SE 0x0011}{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}!");
const u8 gText_RecordBattleToPass[] = _("Would you like to record your battle\non your FRONTIER PASS?");
const u8 gText_BattleRecordedOnPass[] = _("{B_PLAYER_NAME}’s battle result was recorded\non the FRONTIER PASS.");
-const u8 gText_LinkTrainerWantsToBattlePause[] = _("{B_20}\nwants to battle!{PAUSE 49}");
-const u8 gText_TwoLinkTrainersWantToBattlePause[] = _("{B_20} and {B_21}\nwant to battle!{PAUSE 49}");
+static const u8 sText_LinkTrainerWantsToBattlePause[] = _("{B_20}\nwants to battle!{PAUSE 49}");
+static const u8 sText_TwoLinkTrainersWantToBattlePause[] = _("{B_20} and {B_21}\nwant to battle!{PAUSE 49}");
// This is four lists of moves which use a different attack string in Japanese
// to the default. See the documentation for sub_814F950 for more detail.
@@ -1444,45 +1442,45 @@ void BufferStringBattle(u16 stringID)
{
if (gBattleTypeFlags & BATTLE_TYPE_x800000)
{
- stringPtr = gText_TwoTrainersWantToBattle;
+ stringPtr = sText_TwoTrainersWantToBattle;
}
else if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
{
if (gBattleTypeFlags & BATTLE_TYPE_RECORDED)
- stringPtr = gText_TwoLinkTrainersWantToBattlePause;
+ stringPtr = sText_TwoLinkTrainersWantToBattlePause;
else
- stringPtr = gText_TwoLinkTrainersWantToBattle;
+ stringPtr = sText_TwoLinkTrainersWantToBattle;
}
else
{
if (gTrainerBattleOpponent_A == TRAINER_OPPONENT_C00)
- stringPtr = gText_Trainer1WantsToBattle;
+ stringPtr = sText_Trainer1WantsToBattle;
else if (gBattleTypeFlags & BATTLE_TYPE_RECORDED)
- stringPtr = gText_LinkTrainerWantsToBattlePause;
+ stringPtr = sText_LinkTrainerWantsToBattlePause;
else
- stringPtr = gText_LinkTrainerWantsToBattle;
+ stringPtr = sText_LinkTrainerWantsToBattle;
}
}
else
{
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
- stringPtr = gText_TwoTrainersWantToBattle;
+ stringPtr = sText_TwoTrainersWantToBattle;
else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
- stringPtr = gText_TwoTrainersWantToBattle;
+ stringPtr = sText_TwoTrainersWantToBattle;
else
- stringPtr = gText_Trainer1WantsToBattle;
+ stringPtr = sText_Trainer1WantsToBattle;
}
}
else
{
if (gBattleTypeFlags & BATTLE_TYPE_LEGENDARY)
- stringPtr = gText_WildPkmnAppeared2;
+ stringPtr = sText_WildPkmnAppeared2;
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) // interesting, looks like they had something planned for wild double battles
- stringPtr = gText_TwoWildPkmnAppeared;
+ stringPtr = sText_TwoWildPkmnAppeared;
else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL)
- stringPtr = gText_WildPkmnAppearedPause;
+ stringPtr = sText_WildPkmnAppearedPause;
else
- stringPtr = gText_WildPkmnAppeared;
+ stringPtr = sText_WildPkmnAppeared;
}
break;
case STRINGID_INTROSENDOUT: // poke first send-out
@@ -1491,17 +1489,17 @@ void BufferStringBattle(u16 stringID)
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
- stringPtr = gText_InGamePartnerSentOutZGoN;
+ stringPtr = sText_InGamePartnerSentOutZGoN;
else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
- stringPtr = gText_GoTwoPkmn;
+ stringPtr = sText_GoTwoPkmn;
else if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
- stringPtr = gText_LinkPartnerSentOutPkmnGoPkmn;
+ stringPtr = sText_LinkPartnerSentOutPkmnGoPkmn;
else
- stringPtr = gText_GoTwoPkmn;
+ stringPtr = sText_GoTwoPkmn;
}
else
{
- stringPtr = gText_GoPkmn;
+ stringPtr = sText_GoPkmn;
}
}
else
@@ -1509,24 +1507,24 @@ void BufferStringBattle(u16 stringID)
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
- stringPtr = gText_TwoTrainersSentPkmn;
+ stringPtr = sText_TwoTrainersSentPkmn;
else if (gBattleTypeFlags & BATTLE_TYPE_x800000)
- stringPtr = gText_TwoTrainersSentPkmn;
+ stringPtr = sText_TwoTrainersSentPkmn;
else if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
- stringPtr = gText_TwoLinkTrainersSentOutPkmn;
+ stringPtr = sText_TwoLinkTrainersSentOutPkmn;
else if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000))
- stringPtr = gText_LinkTrainerSentOutTwoPkmn;
+ stringPtr = sText_LinkTrainerSentOutTwoPkmn;
else
- stringPtr = gText_Trainer1SentOutTwoPkmn;
+ stringPtr = sText_Trainer1SentOutTwoPkmn;
}
else
{
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000)))
- stringPtr = gText_Trainer1SentOutPkmn;
+ stringPtr = sText_Trainer1SentOutPkmn;
else if (gTrainerBattleOpponent_A == TRAINER_OPPONENT_C00)
- stringPtr = gText_Trainer1SentOutPkmn;
+ stringPtr = sText_Trainer1SentOutPkmn;
else
- stringPtr = gText_LinkTrainerSentOutPkmn;
+ stringPtr = sText_LinkTrainerSentOutPkmn;
}
}
break;
@@ -1534,26 +1532,26 @@ void BufferStringBattle(u16 stringID)
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
{
if (*(&gBattleStruct->hpScale) == 0)
- stringPtr = gText_PkmnThatsEnough;
+ stringPtr = sText_PkmnThatsEnough;
else if (*(&gBattleStruct->hpScale) == 1 || gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
- stringPtr = gText_PkmnComeBack;
+ stringPtr = sText_PkmnComeBack;
else if (*(&gBattleStruct->hpScale) == 2)
- stringPtr = gText_PkmnOkComeBack;
+ stringPtr = sText_PkmnOkComeBack;
else
- stringPtr = gText_PkmnGoodComeBack;
+ stringPtr = sText_PkmnGoodComeBack;
}
else
{
if (gTrainerBattleOpponent_A == TRAINER_OPPONENT_800 || gBattleTypeFlags & BATTLE_TYPE_x2000000)
{
if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
- stringPtr = gText_LinkTrainer2WithdrewPkmn;
+ stringPtr = sText_LinkTrainer2WithdrewPkmn;
else
- stringPtr = gText_LinkTrainer1WithdrewPkmn;
+ stringPtr = sText_LinkTrainer1WithdrewPkmn;
}
else
{
- stringPtr = gText_Trainer1WithdrewPkmn;
+ stringPtr = sText_Trainer1WithdrewPkmn;
}
}
break;
@@ -1561,13 +1559,13 @@ void BufferStringBattle(u16 stringID)
if (GetBattlerSide(gBattleScripting.battler) == B_SIDE_PLAYER)
{
if (*(&gBattleStruct->hpScale) == 0 || gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
- stringPtr = gText_GoPkmn2;
+ stringPtr = sText_GoPkmn2;
else if (*(&gBattleStruct->hpScale) == 1)
- stringPtr = gText_DoItPkmn;
+ stringPtr = sText_DoItPkmn;
else if (*(&gBattleStruct->hpScale) == 2)
- stringPtr = gText_GoForItPkmn;
+ stringPtr = sText_GoForItPkmn;
else
- stringPtr = gText_YourFoesWeakGetEmPkmn;
+ stringPtr = sText_YourFoesWeakGetEmPkmn;
}
else
{
@@ -1576,18 +1574,18 @@ void BufferStringBattle(u16 stringID)
if (gBattleTypeFlags & BATTLE_TYPE_x800000)
{
if (gBattleScripting.battler == 1)
- stringPtr = gText_Trainer1SentOutPkmn2;
+ stringPtr = sText_Trainer1SentOutPkmn2;
else
- stringPtr = gText_Trainer2SentOutPkmn;
+ stringPtr = sText_Trainer2SentOutPkmn;
}
else
{
if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
- stringPtr = gText_LinkTrainerMultiSentOutPkmn;
+ stringPtr = sText_LinkTrainerMultiSentOutPkmn;
else if (gTrainerBattleOpponent_A == TRAINER_OPPONENT_C00)
- stringPtr = gText_Trainer1SentOutPkmn2;
+ stringPtr = sText_Trainer1SentOutPkmn2;
else
- stringPtr = gText_LinkTrainerSentOutPkmn2;
+ stringPtr = sText_LinkTrainerSentOutPkmn2;
}
}
else
@@ -1595,13 +1593,13 @@ void BufferStringBattle(u16 stringID)
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
{
if (gBattleScripting.battler == 1)
- stringPtr = gText_Trainer1SentOutPkmn2;
+ stringPtr = sText_Trainer1SentOutPkmn2;
else
- stringPtr = gText_Trainer2SentOutPkmn;
+ stringPtr = sText_Trainer2SentOutPkmn;
}
else
{
- stringPtr = gText_Trainer1SentOutPkmn2;
+ stringPtr = sText_Trainer1SentOutPkmn2;
}
}
}
@@ -1610,12 +1608,12 @@ void BufferStringBattle(u16 stringID)
sub_814F8F8(gBattleTextBuff1); // buff1 doesn't appear in the string, leftover from japanese move names?
if (gStringInfo->currentMove > LAST_MOVE_INDEX)
- StringCopy(gBattleTextBuff2, gText_UnknownMoveTypes[*(&gBattleStruct->stringMoveType)]);
+ StringCopy(gBattleTextBuff2, sATypeMove_Table[*(&gBattleStruct->stringMoveType)]);
else
StringCopy(gBattleTextBuff2, gMoveNames[gStringInfo->currentMove]);
sub_814F950(gBattleTextBuff2);
- stringPtr = gText_AttackerUsedX;
+ stringPtr = sText_AttackerUsedX;
break;
case STRINGID_BATTLEEND: // battle end
if (gBattleTextBuff1[0] & B_OUTCOME_LINK_BATTLE_RAN)
@@ -1625,11 +1623,11 @@ void BufferStringBattle(u16 stringID)
gBattleTextBuff1[0] ^= (B_OUTCOME_LOST | B_OUTCOME_WON);
if (gBattleTextBuff1[0] == B_OUTCOME_LOST || gBattleTextBuff1[0] == B_OUTCOME_DREW)
- stringPtr = gText_GotAwaySafely;
+ stringPtr = sText_GotAwaySafely;
else if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
- stringPtr = gText_TwoWildFled;
+ stringPtr = sText_TwoWildFled;
else
- stringPtr = gText_WildFled;
+ stringPtr = sText_WildFled;
}
else
{
@@ -1642,15 +1640,15 @@ void BufferStringBattle(u16 stringID)
{
case B_OUTCOME_WON:
if (gBattleTypeFlags & BATTLE_TYPE_x800000)
- stringPtr = gText_TwoInGameTrainersDefeated;
+ stringPtr = sText_TwoInGameTrainersDefeated;
else
- stringPtr = gText_TwoLinkTrainersDefeated;
+ stringPtr = sText_TwoLinkTrainersDefeated;
break;
case B_OUTCOME_LOST:
- stringPtr = gText_PlayerLostToTwo;
+ stringPtr = sText_PlayerLostToTwo;
break;
case B_OUTCOME_DREW:
- stringPtr = gText_PlayerBattledToDrawVsTwo;
+ stringPtr = sText_PlayerBattledToDrawVsTwo;
break;
}
}
@@ -1659,13 +1657,13 @@ void BufferStringBattle(u16 stringID)
switch (gBattleTextBuff1[0])
{
case B_OUTCOME_WON:
- stringPtr = gText_PlayerDefeatedLinkTrainerTrainer1;
+ stringPtr = sText_PlayerDefeatedLinkTrainerTrainer1;
break;
case B_OUTCOME_LOST:
- stringPtr = gText_PlayerLostAgainstTrainer1;
+ stringPtr = sText_PlayerLostAgainstTrainer1;
break;
case B_OUTCOME_DREW:
- stringPtr = gText_PlayerBattledToDrawTrainer1;
+ stringPtr = sText_PlayerBattledToDrawTrainer1;
break;
}
}
@@ -1674,13 +1672,13 @@ void BufferStringBattle(u16 stringID)
switch (gBattleTextBuff1[0])
{
case B_OUTCOME_WON:
- stringPtr = gText_PlayerDefeatedLinkTrainer;
+ stringPtr = sText_PlayerDefeatedLinkTrainer;
break;
case B_OUTCOME_LOST:
- stringPtr = gText_PlayerLostAgainstLinkTrainer;
+ stringPtr = sText_PlayerLostAgainstLinkTrainer;
break;
case B_OUTCOME_DREW:
- stringPtr = gText_PlayerBattledToDrawLinkTrainer;
+ stringPtr = sText_PlayerBattledToDrawLinkTrainer;
break;
}
}
@@ -1707,7 +1705,7 @@ u32 BattleStringExpandPlaceholdersToDisplayedString(const u8* src)
BattleStringExpandPlaceholders(src, gDisplayedStringBattle);
}
-static const u8* TryGetStatusString(u8* src)
+static const u8* TryGetStatusString(u8 *src)
{
u32 i;
u8 status[8];
@@ -1738,13 +1736,13 @@ static const u8* TryGetStatusString(u8* src)
return NULL;
}
-#define HANDLE_NICKNAME_STRING_CASE(bank, monIndex) \
- if (GetBattlerSide(bank) != B_SIDE_PLAYER) \
+#define HANDLE_NICKNAME_STRING_CASE(battlerId, monIndex) \
+ if (GetBattlerSide(battlerId) != B_SIDE_PLAYER) \
{ \
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) \
- toCpy = gText_FoePkmnPrefix; \
+ toCpy = sText_FoePkmnPrefix; \
else \
- toCpy = gText_WildPkmnPrefix; \
+ toCpy = sText_WildPkmnPrefix; \
while (*toCpy != EOS) \
{ \
dst[dstID] = *toCpy; \
@@ -1760,10 +1758,10 @@ static const u8* TryGetStatusString(u8* src)
StringGetEnd10(text); \
toCpy = text;
-u32 BattleStringExpandPlaceholders(const u8* src, u8* dst)
+u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst)
{
u32 dstID = 0; // if they used dstID, why not use srcID as well?
- const u8* toCpy = NULL;
+ const u8 *toCpy = NULL;
u8 text[30];
u8 multiplayerID;
s32 i;
@@ -1868,7 +1866,7 @@ u32 BattleStringExpandPlaceholders(const u8* src, u8* dst)
StringGetEnd10(text);
toCpy = text;
break;
- case B_TXT_ATK_NAME_WITH_PREFIX_MON1: // attacker name with prefix, only bank 0/1
+ 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;
@@ -1887,24 +1885,24 @@ u32 BattleStringExpandPlaceholders(const u8* src, u8* dst)
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 bank name with prefix
+ 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 bank name with prefix
+ 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 bank name with prefix
+ 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 (gStringInfo->currentMove > LAST_MOVE_INDEX)
- toCpy = gText_UnknownMoveTypes[gBattleStruct->stringMoveType];
+ toCpy = sATypeMove_Table[gBattleStruct->stringMoveType];
else
toCpy = gMoveNames[gStringInfo->currentMove];
break;
case B_TXT_LAST_MOVE: // originally used move name
if (gStringInfo->originallyUsedMove > LAST_MOVE_INDEX)
- toCpy = gText_UnknownMoveTypes[gBattleStruct->stringMoveType];
+ toCpy = sATypeMove_Table[gBattleStruct->stringMoveType];
else
toCpy = gMoveNames[gStringInfo->originallyUsedMove];
break;
@@ -1919,12 +1917,12 @@ u32 BattleStringExpandPlaceholders(const u8* src, u8* dst)
|| (gBattleScripting.multiplayerId == 0 && !(gPotentialItemEffectBattler & BIT_SIDE)))
{
StringCopy(text, gEnigmaBerries[gPotentialItemEffectBattler].name);
- StringAppend(text, gText_BerrySuffix);
+ StringAppend(text, sText_BerrySuffix);
toCpy = text;
}
else
{
- toCpy = gText_EnigmaBerry;
+ toCpy = sText_EnigmaBerry;
}
}
else
@@ -1932,11 +1930,11 @@ u32 BattleStringExpandPlaceholders(const u8* src, u8* dst)
if (gLinkPlayers[gBattleScripting.multiplayerId].lp_field_18 == gPotentialItemEffectBattler)
{
StringCopy(text, gEnigmaBerries[gPotentialItemEffectBattler].name);
- StringAppend(text, gText_BerrySuffix);
+ StringAppend(text, sText_BerrySuffix);
toCpy = text;
}
else
- toCpy = gText_EnigmaBerry;
+ toCpy = sText_EnigmaBerry;
}
}
else
@@ -1963,12 +1961,12 @@ u32 BattleStringExpandPlaceholders(const u8* src, u8* dst)
case B_TXT_SCR_ACTIVE_ABILITY: // scripting active ability
toCpy = gAbilityNames[gBattlerAbilities[gBattleScripting.battler]];
break;
- case B_TXT_EFF_ABILITY: // effect bank ability
+ case B_TXT_EFF_ABILITY: // effect battlerId ability
toCpy = gAbilityNames[gBattlerAbilities[gEffectBattler]];
break;
case B_TXT_TRAINER1_CLASS: // trainer class name
if (gBattleTypeFlags & BATTLE_TYPE_SECRET_BASE)
- toCpy = gTrainerClassNames[GetSecretBaseTrainerNameIndex()];
+ toCpy = gTrainerClassNames[GetSecretBaseTrainerClass()];
else if (gTrainerBattleOpponent_A == TRAINER_OPPONENT_C00)
toCpy = gTrainerClassNames[sub_8068BB0()];
else if (gTrainerBattleOpponent_A == TRAINER_OPPONENT_3FE)
@@ -2074,45 +2072,45 @@ u32 BattleStringExpandPlaceholders(const u8* src, u8* dst)
break;
case B_TXT_PC_CREATOR_NAME: // lanette pc
if (FlagGet(FLAG_SYS_PC_LANETTE))
- toCpy = gText_Lanettes;
+ toCpy = sText_Lanettes;
else
- toCpy = gText_Someones;
+ toCpy = sText_Someones;
break;
case B_TXT_ATK_PREFIX2:
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
- toCpy = gText_AllyPkmnPrefix2;
+ toCpy = sText_AllyPkmnPrefix2;
else
- toCpy = gText_FoePkmnPrefix3;
+ toCpy = sText_FoePkmnPrefix3;
break;
case B_TXT_DEF_PREFIX2:
if (GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER)
- toCpy = gText_AllyPkmnPrefix2;
+ toCpy = sText_AllyPkmnPrefix2;
else
- toCpy = gText_FoePkmnPrefix3;
+ toCpy = sText_FoePkmnPrefix3;
break;
case B_TXT_ATK_PREFIX1:
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
- toCpy = gText_AllyPkmnPrefix;
+ toCpy = sText_AllyPkmnPrefix;
else
- toCpy = gText_FoePkmnPrefix2;
+ toCpy = sText_FoePkmnPrefix2;
break;
case B_TXT_DEF_PREFIX1:
if (GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER)
- toCpy = gText_AllyPkmnPrefix;
+ toCpy = sText_AllyPkmnPrefix;
else
- toCpy = gText_FoePkmnPrefix2;
+ toCpy = sText_FoePkmnPrefix2;
break;
case B_TXT_ATK_PREFIX3:
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
- toCpy = gText_AllyPkmnPrefix3;
+ toCpy = sText_AllyPkmnPrefix3;
else
- toCpy = gText_FoePkmnPrefix4;
+ toCpy = sText_FoePkmnPrefix4;
break;
case B_TXT_DEF_PREFIX3:
if (GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER)
- toCpy = gText_AllyPkmnPrefix3;
+ toCpy = sText_AllyPkmnPrefix3;
else
- toCpy = gText_FoePkmnPrefix4;
+ toCpy = sText_FoePkmnPrefix4;
break;
case B_TXT_TRAINER2_CLASS:
if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
@@ -2258,9 +2256,9 @@ static void ExpandBattleTextBuffPlaceholders(const u8 *src, u8 *dst)
else
{
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
- StringAppend(dst, gText_FoePkmnPrefix);
+ StringAppend(dst, sText_FoePkmnPrefix);
else
- StringAppend(dst, gText_WildPkmnPrefix);
+ StringAppend(dst, sText_WildPkmnPrefix);
GetMonData(&gEnemyParty[src[srcID + 2]], MON_DATA_NICKNAME, text);
}
@@ -2301,10 +2299,10 @@ static void ExpandBattleTextBuffPlaceholders(const u8 *src, u8 *dst)
if (gLinkPlayers[gBattleScripting.multiplayerId].lp_field_18 == gPotentialItemEffectBattler)
{
StringCopy(dst, gEnigmaBerries[gPotentialItemEffectBattler].name);
- StringAppend(dst, gText_BerrySuffix);
+ StringAppend(dst, sText_BerrySuffix);
}
else
- StringAppend(dst, gText_EnigmaBerry);
+ StringAppend(dst, sText_EnigmaBerry);
}
else
CopyItemName(hword, dst);
@@ -2337,29 +2335,29 @@ static void sub_814F8F8(u8* textBuff)
if (counter >= 0)
{
if (counter <= 2)
- StringCopy(textBuff, gText_SpaceIs); // is
+ StringCopy(textBuff, sText_SpaceIs); // is
else if (counter <= 4)
- StringCopy(textBuff, gText_ApostropheS); // 's
+ StringCopy(textBuff, sText_ApostropheS); // 's
}
}
// Appends "!" to the text buffer `dst`. In the original Japanese this looked
// into the table of moves at sUnknownMoveTable and varied the line accordingly.
//
-// gText_ExclamationMark was a plain "!", used for any attack not on the list.
+// sText_ExclamationMark was a plain "!", used for any attack not on the list.
// It resulted in the translation "<NAME>'s <ATTACK>!".
//
-// gText_ExclamationMark2 was "を つかった!". This resulted in the translation
+// sText_ExclamationMark2 was "を つかった!". This resulted in the translation
// "<NAME> used <ATTACK>!", which was used for all attacks in English.
//
-// gText_ExclamationMark3 was "した!". This was used for those moves whose
+// sText_ExclamationMark3 was "した!". This was used for those moves whose
// names were verbs, such as Recover, and resulted in translations like "<NAME>
// recovered itself!".
//
-// gText_ExclamationMark4 was "を した!" This resulted in a translation of
+// sText_ExclamationMark4 was "を した!" This resulted in a translation of
// "<NAME> did an <ATTACK>!".
//
-// gText_ExclamationMark5 was " こうげき!" This resulted in a translation of
+// sText_ExclamationMark5 was " こうげき!" This resulted in a translation of
// "<NAME>'s <ATTACK> attack!".
static void sub_814F950(u8* dst)
{
@@ -2380,19 +2378,19 @@ static void sub_814F950(u8* dst)
switch (counter)
{
case 0:
- StringCopy(dst, gText_ExclamationMark);
+ StringCopy(dst, sText_ExclamationMark);
break;
case 1:
- StringCopy(dst, gText_ExclamationMark2);
+ StringCopy(dst, sText_ExclamationMark2);
break;
case 2:
- StringCopy(dst, gText_ExclamationMark3);
+ StringCopy(dst, sText_ExclamationMark3);
break;
case 3:
- StringCopy(dst, gText_ExclamationMark4);
+ StringCopy(dst, sText_ExclamationMark4);
break;
case 4:
- StringCopy(dst, gText_ExclamationMark5);
+ StringCopy(dst, sText_ExclamationMark5);
break;
}
}
diff --git a/src/battle_records.c b/src/battle_records.c
new file mode 100644
index 000000000..a148f998f
--- /dev/null
+++ b/src/battle_records.c
@@ -0,0 +1,510 @@
+#include "global.h"
+#include "battle_records.h"
+#include "bg.h"
+#include "window.h"
+#include "link.h"
+#include "battle.h"
+#include "overworld.h"
+#include "text.h"
+#include "text_window.h"
+#include "strings.h"
+#include "string_util.h"
+#include "trainer_card.h"
+#include "menu.h"
+#include "menu_helpers.h"
+#include "palette.h"
+#include "main.h"
+#include "scanline_effect.h"
+#include "international_string_util.h"
+#include "sound.h"
+#include "constants/songs.h"
+#include "malloc.h"
+#include "gpu_regs.h"
+#include "constants/game_stat.h"
+
+extern void PrintOnTrainerHillRecordsWindow(void); // pokenav.s
+
+// this file's functions
+static void Task_CloseTrainerHillRecordsOnButton(u8 taskId);
+static void Task_BeginPaletteFade(u8 taskId);
+static void Task_ExitTrainerHillRecords(u8 taskId);
+static void RemoveTrainerHillRecordsWindow(u8 windowId);
+static void CB2_ShowTrainerHillRecords(void);
+
+// EWRAM variables
+EWRAM_DATA u8 gRecordsWindowId = 0;
+EWRAM_DATA static u8 *sTilemapBuffer = NULL;
+
+// const rom data
+static const u32 sTrainerHillWindowTileset[] = INCBIN_U32("graphics/unknown/unknown_5B3484.4bpp");
+static const u16 sTrainerHillWindowPalette[] = INCBIN_U16("graphics/unknown/unknown_5B3484.gbapal");
+static const u32 sTrainerHillWindowTilemap[] = INCBIN_U32("graphics/unknown/unknown_5B3564.bin");
+
+static const struct BgTemplate sTrainerHillRecordsBgTemplates[] =
+{
+ {
+ .bg = 0,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 31,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 0,
+ .baseTile = 0
+ },
+ {
+ .bg = 3,
+ .charBaseIndex = 1,
+ .mapBaseIndex = 30,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 3,
+ .baseTile = 0
+ }
+};
+
+static const struct WindowTemplate sTrainerHillRecordsWindowTemplates[] =
+{
+ {0x0, 0x2, 0x1, 0x1A, 0x12, 0xF, 0x14},
+ DUMMY_WIN_TEMPLATE
+};
+
+static const struct WindowTemplate sLinkBattleRecordsWindow = {0x0, 0x2, 0x1, 0x1A, 0x11, 0xF, 0x1};
+
+static const u8 sText_DashesNoPlayer[] = _("-------");
+static const u8 sText_DashesNoScore[] = _("----");
+
+// code
+static void ClearLinkBattleRecord(struct LinkBattleRecord *record)
+{
+ CpuFill16(0, record, sizeof(struct LinkBattleRecord));
+ record->name[0] = EOS;
+ record->trainerId = 0;
+ record->wins = 0;
+ record->losses = 0;
+ record->draws = 0;
+}
+
+static void ClearLinkBattleRecords(struct LinkBattleRecord *records)
+{
+ s32 i;
+ for (i = 0; i < LINK_B_RECORDS_COUNT; i++)
+ {
+ ClearLinkBattleRecord(records + i);
+ }
+ SetGameStat(GAME_STAT_LINK_BATTLE_WINS, 0);
+ SetGameStat(GAME_STAT_LINK_BATTLE_LOSSES, 0);
+ SetGameStat(GAME_STAT_LINK_BATTLE_DRAWS, 0);
+}
+
+static s32 GetLinkBattleRecordTotalBattles(struct LinkBattleRecord *record)
+{
+ return record->wins + record->losses + record->draws;
+}
+
+static s32 FindLinkBattleRecord(struct LinkBattleRecord *records, const u8 *name, u16 trainerId)
+{
+ s32 i;
+
+ for (i = 0; i < LINK_B_RECORDS_COUNT; i++)
+ {
+ if (!StringCompareN(records[i].name, name, OT_NAME_LENGTH) && records[i].trainerId == trainerId)
+ return i;
+ }
+
+ return LINK_B_RECORDS_COUNT;
+}
+
+static void SortLinkBattleRecords(struct LinkBattleRecords *records)
+{
+ s32 i, j;
+
+ for (i = LINK_B_RECORDS_COUNT - 1; i > 0; i--)
+ {
+ for (j = i - 1; j >= 0; j--)
+ {
+ s32 totalBattlesI = GetLinkBattleRecordTotalBattles(&records->entries[i]);
+ s32 totalBattlesJ = GetLinkBattleRecordTotalBattles(&records->entries[j]);
+
+ if (totalBattlesI > totalBattlesJ)
+ {
+ struct LinkBattleRecord temp1;
+ u8 temp2;
+
+ temp1 = records->entries[i];
+ records->entries[i] = records->entries[j];
+ records->entries[j] = temp1;
+
+ temp2 = records->languages[i];
+ records->languages[i] = records->languages[j];
+ records->languages[j] = temp2;
+ }
+ }
+ }
+}
+
+static void UpdateLinkBattleRecord(struct LinkBattleRecord *record, s32 battleOutcome)
+{
+ switch (battleOutcome)
+ {
+ case B_OUTCOME_WON:
+ record->wins++;
+ if (record->wins > 9999)
+ record->wins = 9999;
+ break;
+ case B_OUTCOME_LOST:
+ record->losses++;
+ if (record->losses > 9999)
+ record->losses = 9999;
+ break;
+ case B_OUTCOME_DREW:
+ record->draws++;
+ if (record->draws > 9999)
+ record->draws = 9999;
+ break;
+ }
+}
+
+static void UpdateLinkBattleGameStats(s32 battleOutcome)
+{
+ u8 stat;
+
+ switch (battleOutcome)
+ {
+ case B_OUTCOME_WON:
+ stat = GAME_STAT_LINK_BATTLE_WINS;
+ break;
+ case B_OUTCOME_LOST:
+ stat = GAME_STAT_LINK_BATTLE_LOSSES;
+ break;
+ case B_OUTCOME_DREW:
+ stat = GAME_STAT_LINK_BATTLE_DRAWS;
+ break;
+ default:
+ return;
+ }
+
+ if (GetGameStat(stat) < 9999)
+ IncrementGameStat(stat);
+}
+
+static void UpdateLinkBattleRecords(struct LinkBattleRecords *records, const u8 *name, u16 trainerId, s32 battleOutcome, u8 battlerId)
+{
+ s32 index;
+
+ UpdateLinkBattleGameStats(battleOutcome);
+ SortLinkBattleRecords(records);
+ index = FindLinkBattleRecord(records->entries, name, trainerId);
+ if (index == LINK_B_RECORDS_COUNT)
+ {
+ index = LINK_B_RECORDS_COUNT - 1;
+ ClearLinkBattleRecord(&records->entries[index]);
+ StringCopyN(records->entries[index].name, name, OT_NAME_LENGTH);
+ records->entries[index].trainerId = trainerId;
+ records->languages[index] = gLinkPlayers[battlerId].language;
+ }
+ UpdateLinkBattleRecord(&records->entries[index], battleOutcome);
+ SortLinkBattleRecords(records);
+}
+
+void ClearPlayerLinkBattleRecords(void)
+{
+ ClearLinkBattleRecords(gSaveBlock1Ptr->linkBattleRecords.entries);
+}
+
+static void IncTrainerCardWins(s32 battlerId)
+{
+ u16 *wins = &gTrainerCards[battlerId].linkBattleWins;
+ (*wins)++;
+ if (*wins > 9999)
+ *wins = 9999;
+}
+
+static void IncTrainerCardLosses(s32 battlerId)
+{
+ u16 *losses = &gTrainerCards[battlerId].linkBattleLosses;
+ (*losses)++;
+ if (*losses > 9999)
+ *losses = 9999;
+}
+
+static void UpdateTrainerCardWinsLosses(s32 battlerId)
+{
+ switch (gBattleOutcome)
+ {
+ case B_OUTCOME_WON:
+ IncTrainerCardWins(BATTLE_OPPOSITE(battlerId));
+ IncTrainerCardLosses(battlerId);
+ break;
+ case B_OUTCOME_LOST:
+ IncTrainerCardLosses(BATTLE_OPPOSITE(battlerId));
+ IncTrainerCardWins(battlerId);
+ break;
+ }
+}
+
+void UpdatePlayerLinkBattleRecords(s32 battlerId)
+{
+ if (InUnionRoom() != TRUE)
+ {
+ UpdateTrainerCardWinsLosses(battlerId);
+ UpdateLinkBattleRecords(
+ &gSaveBlock1Ptr->linkBattleRecords,
+ gTrainerCards[battlerId].playerName,
+ gTrainerCards[battlerId].trainerId,
+ gBattleOutcome,
+ battlerId);
+ }
+}
+
+static void PrintLinkBattleWinsLossesDraws(struct LinkBattleRecord *records)
+{
+ s32 x;
+
+ ConvertIntToDecimalStringN(gStringVar1, GetGameStat(GAME_STAT_LINK_BATTLE_WINS), STR_CONV_MODE_LEFT_ALIGN, 4);
+ ConvertIntToDecimalStringN(gStringVar2, GetGameStat(GAME_STAT_LINK_BATTLE_LOSSES), STR_CONV_MODE_LEFT_ALIGN, 4);
+ ConvertIntToDecimalStringN(gStringVar3, GetGameStat(GAME_STAT_LINK_BATTLE_DRAWS), STR_CONV_MODE_LEFT_ALIGN, 4);
+ StringExpandPlaceholders(gStringVar4, gText_TotalRecordWLD);
+
+ x = GetStringCenterAlignXOffset(1, gStringVar4, 0xD0);
+ PrintTextOnWindow(gRecordsWindowId, 1, gStringVar4, x, 0x11, 0, NULL);
+}
+
+static void PrintLinkBattleRecord(struct LinkBattleRecord *record, u8 y, s32 language)
+{
+ if (record->wins == 0 && record->losses == 0 && record->draws == 0)
+ {
+ // empty slot
+ PrintTextOnWindow(gRecordsWindowId, 1, sText_DashesNoPlayer, 8, (y * 8) + 1, 0, NULL);
+ PrintTextOnWindow(gRecordsWindowId, 1, sText_DashesNoScore, 80, (y * 8) + 1, 0, NULL);
+ PrintTextOnWindow(gRecordsWindowId, 1, sText_DashesNoScore, 128, (y * 8) + 1, 0, NULL);
+ PrintTextOnWindow(gRecordsWindowId, 1, sText_DashesNoScore, 176, (y * 8) + 1, 0, NULL);
+ }
+ else
+ {
+ StringFillWithTerminator(gStringVar1, 8);
+ StringCopyN(gStringVar1, record->name, 7);
+ ConvertInternationalString(gStringVar1, language);
+
+ PrintTextOnWindow(gRecordsWindowId, 1, gStringVar1, 8, (y * 8) + 1, 0, NULL);
+
+ ConvertIntToDecimalStringN(gStringVar1, record->wins, STR_CONV_MODE_RIGHT_ALIGN, 4);
+ PrintTextOnWindow(gRecordsWindowId, 1, gStringVar1, 80, (y * 8) + 1, 0, NULL);
+
+ ConvertIntToDecimalStringN(gStringVar1, record->losses, STR_CONV_MODE_RIGHT_ALIGN, 4);
+ PrintTextOnWindow(gRecordsWindowId, 1, gStringVar1, 128, (y * 8) + 1, 0, NULL);
+
+ ConvertIntToDecimalStringN(gStringVar1, record->draws, STR_CONV_MODE_RIGHT_ALIGN, 4);
+ PrintTextOnWindow(gRecordsWindowId, 1, gStringVar1, 176, (y * 8) + 1, 0, NULL);
+ }
+}
+
+void ShowLinkBattleRecords(void)
+{
+ s32 i, x;
+
+ gRecordsWindowId = AddWindow(&sLinkBattleRecordsWindow);
+ NewMenuHelpers_DrawStdWindowFrame(gRecordsWindowId, FALSE);
+ FillWindowPixelBuffer(gRecordsWindowId, 0x11);
+ StringExpandPlaceholders(gStringVar4, gText_PlayersBattleResults);
+
+ x = GetStringCenterAlignXOffset(1, gStringVar4, 208);
+ PrintTextOnWindow(gRecordsWindowId, 1, gStringVar4, x, 1, 0, NULL);
+ PrintLinkBattleWinsLossesDraws(gSaveBlock1Ptr->linkBattleRecords.entries);
+
+ StringExpandPlaceholders(gStringVar4, gText_WinLoseDraw);
+ PrintTextOnWindow(gRecordsWindowId, 1, gStringVar4, 0, 41, 0, NULL);
+
+ for (i = 0; i < LINK_B_RECORDS_COUNT; i++)
+ {
+ PrintLinkBattleRecord(&gSaveBlock1Ptr->linkBattleRecords.entries[i], 7 + (i * 2), gSaveBlock1Ptr->linkBattleRecords.languages[i]);
+ }
+
+ PutWindowTilemap(gRecordsWindowId);
+ CopyWindowToVram(gRecordsWindowId, 3);
+}
+
+void RemoveRecordsWindow(void)
+{
+ sub_819746C(gRecordsWindowId, FALSE);
+ RemoveWindow(gRecordsWindowId);
+}
+
+static void Task_TrainerHillWaitForPaletteFade(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ gTasks[taskId].func = Task_CloseTrainerHillRecordsOnButton;
+}
+
+static void Task_CloseTrainerHillRecordsOnButton(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ if (gMain.newKeys & A_BUTTON || gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ task->func = Task_BeginPaletteFade;
+ }
+}
+
+static void Task_BeginPaletteFade(u8 taskId)
+{
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ gTasks[taskId].func = Task_ExitTrainerHillRecords;
+}
+
+static void Task_ExitTrainerHillRecords(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ SetMainCallback2(CB2_ReturnToFieldContinueScript);
+ Free(sTilemapBuffer);
+ RemoveTrainerHillRecordsWindow(0);
+ FreeAllWindowBuffers();
+ DestroyTask(taskId);
+ }
+}
+
+static void RemoveTrainerHillRecordsWindow(u8 windowId)
+{
+ FillWindowPixelBuffer(windowId, 0);
+ ClearWindowTilemap(windowId);
+ CopyWindowToVram(windowId, 2);
+ RemoveWindow(windowId);
+}
+
+static void ClearVramOamPlttRegs(void)
+{
+ DmaClearLarge16(3, (void*)(VRAM), VRAM_SIZE, 0x1000);
+ DmaClear32(3, OAM, OAM_SIZE);
+ DmaClear16(3, PLTT, PLTT_SIZE);
+
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ SetGpuReg(REG_OFFSET_BG0CNT, 0);
+ SetGpuReg(REG_OFFSET_BG0HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG0VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1CNT, 0);
+ SetGpuReg(REG_OFFSET_BG1HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG2CNT, 0);
+ SetGpuReg(REG_OFFSET_BG2HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG2VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG3CNT, 0);
+ SetGpuReg(REG_OFFSET_BG3HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG3VOFS, 0);
+ SetGpuReg(REG_OFFSET_WIN0H, 0);
+ SetGpuReg(REG_OFFSET_WIN0V, 0);
+ SetGpuReg(REG_OFFSET_WININ, 0);
+ SetGpuReg(REG_OFFSET_WINOUT, 0);
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+}
+
+static void ClearTasksAndGraphicalStructs(void)
+{
+ ScanlineEffect_Stop();
+ ResetTasks();
+ ResetSpriteData();
+ ResetPaletteFade();
+ FreeAllSpritePalettes();
+}
+
+static void ResetBgCoordinates(void)
+{
+ ChangeBgX(0, 0, 0);
+ ChangeBgY(0, 0, 0);
+ ChangeBgX(1, 0, 0);
+ ChangeBgY(1, 0, 0);
+ ChangeBgX(2, 0, 0);
+ ChangeBgY(2, 0, 0);
+ ChangeBgX(3, 0, 0);
+ ChangeBgY(3, 0, 0);
+}
+
+static void SetDispcntReg(void)
+{
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_BG0_ON | DISPCNT_BG3_ON | DISPCNT_OBJ_1D_MAP);
+}
+
+static void LoadTrainerHillRecordsWindowGfx(u8 bgId)
+{
+ LoadBgTiles(bgId, sTrainerHillWindowTileset, sizeof(sTrainerHillWindowTileset), 0);
+ CopyToBgTilemapBufferRect(bgId, sTrainerHillWindowTilemap, 0, 0, 0x20, 0x20);
+ LoadPalette(sTrainerHillWindowPalette, 0, 0x20);
+}
+
+static void VblankCB_TrainerHillRecords(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+static void MainCB2_TrainerHillRecords(void)
+{
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+}
+
+void ShowTrainerHillRecords(void)
+{
+ SetVBlankCallback(NULL);
+ SetMainCallback2(CB2_ShowTrainerHillRecords);
+}
+
+static void CB2_ShowTrainerHillRecords(void)
+{
+ switch (gMain.state)
+ {
+ case 0:
+ SetVBlankCallback(NULL);
+ ClearVramOamPlttRegs();
+ gMain.state++;
+ break;
+ case 1:
+ ClearTasksAndGraphicalStructs();
+ gMain.state++;
+ break;
+ case 2:
+ sTilemapBuffer = AllocZeroed(0x800);
+ ResetBgsAndClearDma3BusyFlags(0);
+ InitBgsFromTemplates(0, sTrainerHillRecordsBgTemplates, ARRAY_COUNT(sTrainerHillRecordsBgTemplates));
+ SetBgTilemapBuffer(3, sTilemapBuffer);
+ ResetBgCoordinates();
+ gMain.state++;
+ break;
+ case 3:
+ LoadTrainerHillRecordsWindowGfx(3);
+ LoadPalette(stdpal_get(0), 0xF0, 0x20);
+ gMain.state++;
+ break;
+ case 4:
+ if (IsDma3ManagerBusyWithBgCopy() != TRUE)
+ {
+ ShowBg(0);
+ ShowBg(3);
+ CopyBgTilemapBufferToVram(3);
+ gMain.state++;
+ }
+ break;
+ case 5:
+ InitWindows(sTrainerHillRecordsWindowTemplates);
+ DeactivateAllTextPrinters();
+ gMain.state++;
+ break;
+ case 6:
+ BeginNormalPaletteFade(-1, 0, 0x10, 0, 0);
+ gMain.state++;
+ break;
+ case 7:
+ SetDispcntReg();
+ SetVBlankCallback(VblankCB_TrainerHillRecords);
+ PrintOnTrainerHillRecordsWindow();
+ CreateTask(Task_TrainerHillWaitForPaletteFade, 8);
+ SetMainCallback2(MainCB2_TrainerHillRecords);
+ gMain.state = 0;
+ break;
+ }
+}
diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c
index 4d40d83a8..811aba128 100644
--- a/src/battle_script_commands.c
+++ b/src/battle_script_commands.c
@@ -12,7 +12,6 @@
#include "constants/hold_effects.h"
#include "util.h"
#include "pokemon.h"
-#include "calculate_base_damage.h"
#include "random.h"
#include "battle_controllers.h"
#include "battle_interface.h"
@@ -32,7 +31,6 @@
#include "bg.h"
#include "string_util.h"
#include "pokemon_icon.h"
-#include "pokemon_item_effects.h"
#include "m4a.h"
#include "mail.h"
#include "event_data.h"
@@ -50,15 +48,6 @@ extern u16 gBattle_BG2_Y;
extern u16 gBattle_BG3_X;
extern struct MusicPlayerInfo gMPlayInfo_BGM;
-struct TrainerMoney
-{
- u8 classId;
- u8 value;
-};
-
-extern const struct BattleMove gBattleMoves[];
-extern const u8 gTypeEffectiveness[336];
-extern const struct TrainerMoney gTrainerMoneyTable[];
extern const u8* const gBattleScriptsForMoveEffects[];
// functions
@@ -78,28 +67,12 @@ extern bool8 sub_81B1250(void); // ?
extern bool8 InBattlePike(void);
extern bool8 InBattlePyramid(void);
extern u16 GetBattlePyramidPickupItemId(void);
-extern u8 sav1_map_get_light_level(void);
+extern u8 Overworld_GetMapTypeOfSaveblockLocation(void);
extern u8 sub_813B21C(void);
extern u16 get_unknown_box_id(void);
-// strings
-extern const u8 gText_BattleYesNoChoice[];
-
-// read via orr
-#define BSScriptRead32(ptr) ((ptr)[0] | (ptr)[1] << 8 | (ptr)[2] << 16 | (ptr)[3] << 24)
-#define BSScriptRead16(ptr) ((ptr)[0] | ((ptr)[1] << 8))
-#define BSScriptReadPtr(ptr) ((void *)BSScriptRead32(ptr))
-
-// read via add
-#define BS2ScriptRead32(ptr) ((ptr)[0] + ((ptr)[1] << 8) + ((ptr)[2] << 16) + ((ptr)[3] << 24))
-#define BS2ScriptRead16(ptr) ((ptr)[0] + ((ptr)[1] << 8))
-#define BS2ScriptReadPtr(ptr) ((void *)BS2ScriptRead32(ptr))
-
#define DEFENDER_IS_PROTECTED ((gProtectStructs[gBattlerTarget].protected) && (gBattleMoves[gCurrentMove].flags & FLAG_PROTECT_AFFECTED))
-#define TARGET_TURN_DAMAGED (gSpecialStatuses[gBattlerTarget].physicalDmg != 0 \
- || gSpecialStatuses[gBattlerTarget].specialDmg != 0)
-
// this file's functions
static bool8 IsTwoTurnsMove(u16 move);
static void TrySetDestinyBondToHappen(void);
@@ -1036,7 +1009,7 @@ static void atk00_attackcanceler(void)
RecordAbilityBattle(gBattlerTarget, gLastUsedAbility);
}
else if (DEFENDER_IS_PROTECTED
- && (gCurrentMove != MOVE_CURSE || (gBattleMons[gBattlerAttacker].type1 == TYPE_GHOST || gBattleMons[gBattlerAttacker].type2 == TYPE_GHOST))
+ && (gCurrentMove != MOVE_CURSE || IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GHOST))
&& ((!IsTwoTurnsMove(gCurrentMove) || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))))
{
CancelMultiTurnMoves(gBattlerAttacker);
@@ -1059,7 +1032,7 @@ static void JumpIfMoveFailed(u8 adder, u16 move)
{
gLastLandedMoves[gBattlerTarget] = 0;
gLastHitByType[gBattlerTarget] = 0;
- BS_ptr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ BS_ptr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
@@ -1144,14 +1117,14 @@ static bool8 AccuracyCalcHelper(u16 move)
static void atk01_accuracycheck(void)
{
- u16 move = BS2ScriptRead16(gBattlescriptCurrInstr + 5);
+ u16 move = T2_READ_16(gBattlescriptCurrInstr + 5);
if (move == 0xFFFE || move == 0xFFFF)
{
if (gStatuses3[gBattlerTarget] & STATUS3_ALWAYS_HITS && move == 0xFFFF && gDisableStructs[gBattlerTarget].battlerWithSureHit == gBattlerAttacker)
gBattlescriptCurrInstr += 7;
else if (gStatuses3[gBattlerTarget] & (STATUS3_ON_AIR | STATUS3_UNDERGROUND | STATUS3_UNDERWATER))
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
else if (!JumpIfMoveAffectedByProtect(0))
gBattlescriptCurrInstr += 7;
}
@@ -1410,7 +1383,7 @@ static void atk06_typecalc(void)
GET_MOVE_TYPE(gCurrentMove, moveType);
// check stab
- if (gBattleMons[gBattlerAttacker].type1 == moveType || gBattleMons[gBattlerAttacker].type2 == moveType)
+ if (IS_BATTLER_OF_TYPE(gBattlerAttacker, moveType))
{
gBattleMoveDamage = gBattleMoveDamage * 15;
gBattleMoveDamage = gBattleMoveDamage / 10;
@@ -1588,7 +1561,7 @@ u8 TypeCalc(u16 move, u8 attacker, u8 defender)
moveType = gBattleMoves[move].type;
// check stab
- if (gBattleMons[attacker].type1 == moveType || gBattleMons[attacker].type2 == moveType)
+ if (IS_BATTLER_OF_TYPE(attacker, moveType))
{
gBattleMoveDamage = gBattleMoveDamage * 15;
gBattleMoveDamage = gBattleMoveDamage / 10;
@@ -2169,7 +2142,7 @@ static void atk10_printstring(void)
{
if (gBattleControllerExecFlags == 0)
{
- u16 var = BS2ScriptRead16(gBattlescriptCurrInstr + 1);
+ u16 var = T2_READ_16(gBattlescriptCurrInstr + 1);
PrepareStringBattle(var, gBattlerAttacker);
gBattlescriptCurrInstr += 3;
gBattleCommunication[MSG_DISPLAY] = 1;
@@ -2180,7 +2153,7 @@ static void atk11_printselectionstring(void)
{
gActiveBattler = gBattlerAttacker;
- BtlController_EmitPrintSelectionString(0, BS2ScriptRead16(gBattlescriptCurrInstr + 1));
+ BtlController_EmitPrintSelectionString(0, T2_READ_16(gBattlescriptCurrInstr + 1));
MarkBattlerForControllerExec(gActiveBattler);
gBattlescriptCurrInstr += 3;
@@ -2197,7 +2170,7 @@ static void atk12_waitmessage(void)
}
else
{
- u16 toWait = BS2ScriptRead16(gBattlescriptCurrInstr + 1);
+ u16 toWait = T2_READ_16(gBattlescriptCurrInstr + 1);
if (++gPauseCounterBattle >= toWait)
{
gPauseCounterBattle = 0;
@@ -2212,7 +2185,7 @@ static void atk13_printfromtable(void)
{
if (gBattleControllerExecFlags == 0)
{
- const u16 *ptr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ const u16 *ptr = (const u16*) T1_READ_PTR(gBattlescriptCurrInstr + 1);
ptr += gBattleCommunication[MULTISTRING_CHOOSER];
PrepareStringBattle(*ptr, gBattlerAttacker);
@@ -2226,7 +2199,7 @@ static void atk14_printselectionstringfromtable(void)
{
if (gBattleControllerExecFlags == 0)
{
- const u16 *ptr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ const u16 *ptr = (const u16*) T1_READ_PTR(gBattlescriptCurrInstr + 1);
ptr += gBattleCommunication[MULTISTRING_CHOOSER];
gActiveBattler = gBattlerAttacker;
@@ -2346,8 +2319,7 @@ void SetMoveEffect(bool8 primary, u8 certain)
}
RESET_RETURN
}
- if ((gBattleMons[gEffectBattler].type1 == TYPE_POISON || gBattleMons[gEffectBattler].type2 == TYPE_POISON
- || gBattleMons[gEffectBattler].type1 == TYPE_STEEL || gBattleMons[gEffectBattler].type2 == TYPE_STEEL)
+ if ((IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_POISON) || IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_STEEL))
&& (gHitMarker & HITMARKER_IGNORE_SAFEGUARD)
&& (primary == TRUE || certain == MOVE_EFFECT_CERTAIN))
{
@@ -2357,13 +2329,9 @@ void SetMoveEffect(bool8 primary, u8 certain)
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
RESET_RETURN
}
- if (gBattleMons[gEffectBattler].type1 == TYPE_POISON)
- break;
- if (gBattleMons[gEffectBattler].type2 == TYPE_POISON)
- break;
- if (gBattleMons[gEffectBattler].type1 == TYPE_STEEL)
+ if (IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_POISON))
break;
- if (gBattleMons[gEffectBattler].type2 == TYPE_STEEL)
+ if (IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_STEEL))
break;
if (gBattleMons[gEffectBattler].status1)
break;
@@ -2392,8 +2360,7 @@ void SetMoveEffect(bool8 primary, u8 certain)
}
RESET_RETURN
}
- if ((gBattleMons[gEffectBattler].type1 == TYPE_FIRE
- || gBattleMons[gEffectBattler].type2 == TYPE_FIRE)
+ if (IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_FIRE)
&& (gHitMarker & HITMARKER_IGNORE_SAFEGUARD)
&& (primary == TRUE || certain == MOVE_EFFECT_CERTAIN))
{
@@ -2403,9 +2370,7 @@ void SetMoveEffect(bool8 primary, u8 certain)
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
RESET_RETURN
}
- if (gBattleMons[gEffectBattler].type1 == TYPE_FIRE)
- break;
- if (gBattleMons[gEffectBattler].type2 == TYPE_FIRE)
+ if (IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_FIRE))
break;
if (gBattleMons[gEffectBattler].ability == ABILITY_WATER_VEIL)
break;
@@ -2417,9 +2382,7 @@ void SetMoveEffect(bool8 primary, u8 certain)
case STATUS1_FREEZE:
if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SUN_ANY)
noSunCanFreeze = FALSE;
- if (gBattleMons[gEffectBattler].type1 == TYPE_ICE)
- break;
- if (gBattleMons[gEffectBattler].type2 == TYPE_ICE)
+ if (IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_ICE))
break;
if (gBattleMons[gEffectBattler].status1)
break;
@@ -2481,8 +2444,7 @@ void SetMoveEffect(bool8 primary, u8 certain)
}
RESET_RETURN
}
- if ((gBattleMons[gEffectBattler].type1 == TYPE_POISON || gBattleMons[gEffectBattler].type2 == TYPE_POISON
- || gBattleMons[gEffectBattler].type1 == TYPE_STEEL || gBattleMons[gEffectBattler].type2 == TYPE_STEEL)
+ if ((IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_POISON) || IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_STEEL))
&& (gHitMarker & HITMARKER_IGNORE_SAFEGUARD)
&& (primary == TRUE || certain == MOVE_EFFECT_CERTAIN))
{
@@ -2494,10 +2456,7 @@ void SetMoveEffect(bool8 primary, u8 certain)
}
if (gBattleMons[gEffectBattler].status1)
break;
- if (gBattleMons[gEffectBattler].type1 != TYPE_POISON
- && gBattleMons[gEffectBattler].type2 != TYPE_POISON
- && gBattleMons[gEffectBattler].type1 != TYPE_STEEL
- && gBattleMons[gEffectBattler].type2 != TYPE_STEEL)
+ if (!IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_POISON) && !IS_BATTLER_OF_TYPE(gEffectBattler, TYPE_STEEL))
{
if (gBattleMons[gEffectBattler].ability == ABILITY_IMMUNITY)
break;
@@ -3014,7 +2973,7 @@ static void atk19_tryfaintmon(void)
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
if (gHitMarker & HITMARKER_FAINTED(gActiveBattler))
{
- BS_ptr = BSScriptReadPtr(gBattlescriptCurrInstr + 3);
+ BS_ptr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
BattleScriptPop();
gBattlescriptCurrInstr = BS_ptr;
@@ -3124,8 +3083,8 @@ static void atk1B_cleareffectsonfaint(void)
static void atk1C_jumpifstatus(void)
{
u8 battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
- u32 flags = BS2ScriptRead32(gBattlescriptCurrInstr + 2);
- const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 6);
+ u32 flags = T2_READ_32(gBattlescriptCurrInstr + 2);
+ const u8* jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 6);
if (gBattleMons[battlerId].status1 & flags && gBattleMons[battlerId].hp)
gBattlescriptCurrInstr = jumpPtr;
@@ -3136,8 +3095,8 @@ static void atk1C_jumpifstatus(void)
static void atk1D_jumpifstatus2(void)
{
u8 battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
- u32 flags = BS2ScriptRead32(gBattlescriptCurrInstr + 2);
- const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 6);
+ u32 flags = T2_READ_32(gBattlescriptCurrInstr + 2);
+ const u8* jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 6);
if (gBattleMons[battlerId].status2 & flags && gBattleMons[battlerId].hp)
gBattlescriptCurrInstr = jumpPtr;
@@ -3149,7 +3108,7 @@ static void atk1E_jumpifability(void)
{
u8 battlerId;
u8 ability = gBattlescriptCurrInstr[2];
- const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 3);
+ const u8* jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 3);
if (gBattlescriptCurrInstr[1] == BS_ATTACKER_SIDE)
{
@@ -3203,8 +3162,8 @@ static void atk1F_jumpifsideaffecting(void)
else
side = GET_BATTLER_SIDE(gBattlerTarget);
- flags = BS2ScriptRead16(gBattlescriptCurrInstr + 2);
- jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 4);
+ flags = T2_READ_16(gBattlescriptCurrInstr + 2);
+ jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 4);
if (gSideStatuses[side] & flags)
gBattlescriptCurrInstr = jumpPtr;
@@ -3247,7 +3206,7 @@ static void atk20_jumpifstat(void)
}
if (ret)
- gBattlescriptCurrInstr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5);
+ gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 5);
else
gBattlescriptCurrInstr += 9;
}
@@ -3258,8 +3217,8 @@ static void atk21_jumpifstatus3condition(void)
const u8 *jumpPtr;
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
- flags = BS2ScriptRead32(gBattlescriptCurrInstr + 2);
- jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 7);
+ flags = T2_READ_32(gBattlescriptCurrInstr + 2);
+ jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 7);
if (gBattlescriptCurrInstr[6])
{
@@ -3281,9 +3240,9 @@ static void atk22_jumpiftype(void)
{
u8 battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
u8 type = gBattlescriptCurrInstr[2];
- const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 3);
+ const u8* jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 3);
- if (gBattleMons[battlerId].type1 == type || gBattleMons[battlerId].type2 == type)
+ if (IS_BATTLER_OF_TYPE(battlerId, type))
gBattlescriptCurrInstr = jumpPtr;
else
gBattlescriptCurrInstr += 7;
@@ -3398,7 +3357,7 @@ static void atk23_getexp(void)
if (!(gBattleTypeFlags & BATTLE_TYPE_TRAINER) && gBattleMons[0].hp && !gBattleStruct->wildVictorySong)
{
BattleStopLowHpSound();
- PlayBGM(0x161);
+ PlayBGM(MUS_KACHI2);
gBattleStruct->wildVictorySong++;
}
@@ -3631,14 +3590,14 @@ static void atk24(void)
if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
{
if (foundOpponent + foundPlayer > 1)
- gBattlescriptCurrInstr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 1);
else
gBattlescriptCurrInstr += 5;
}
else
{
if (foundOpponent != 0 && foundPlayer != 0)
- gBattlescriptCurrInstr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 1);
else
gBattlescriptCurrInstr += 5;
}
@@ -3649,7 +3608,7 @@ static void atk24(void)
}
}
#else
-__attribute__((naked))
+NAKED
static void atk24(void)
{
asm("\n\
@@ -3972,20 +3931,20 @@ static void atk27_decrementmultihit(void)
if (--gMultiHitCounter == 0)
gBattlescriptCurrInstr += 5;
else
- gBattlescriptCurrInstr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 1);
}
static void atk28_goto(void)
{
- gBattlescriptCurrInstr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 1);
}
static void atk29_jumpifbyte(void)
{
u8 caseID = gBattlescriptCurrInstr[1];
- const u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 2);
+ const u8* memByte = T2_READ_PTR(gBattlescriptCurrInstr + 2);
u8 value = gBattlescriptCurrInstr[6];
- const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 7);
+ const u8* jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 7);
gBattlescriptCurrInstr += 11;
@@ -4021,9 +3980,9 @@ static void atk29_jumpifbyte(void)
static void atk2A_jumpifhalfword(void)
{
u8 caseID = gBattlescriptCurrInstr[1];
- const u16* memHword = BS2ScriptReadPtr(gBattlescriptCurrInstr + 2);
- u16 value = BS2ScriptRead16(gBattlescriptCurrInstr + 6);
- const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 8);
+ const u16* memHword = T2_READ_PTR(gBattlescriptCurrInstr + 2);
+ u16 value = T2_READ_16(gBattlescriptCurrInstr + 6);
+ const u8* jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 8);
gBattlescriptCurrInstr += 12;
@@ -4059,9 +4018,9 @@ static void atk2A_jumpifhalfword(void)
static void atk2B_jumpifword(void)
{
u8 caseID = gBattlescriptCurrInstr[1];
- const u32* memWord = BS2ScriptReadPtr(gBattlescriptCurrInstr + 2);
- u32 value = BSScriptRead32(gBattlescriptCurrInstr + 6);
- const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 10);
+ const u32* memWord = T2_READ_PTR(gBattlescriptCurrInstr + 2);
+ u32 value = T1_READ_32(gBattlescriptCurrInstr + 6);
+ const u8* jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 10);
gBattlescriptCurrInstr += 14;
@@ -4096,10 +4055,10 @@ static void atk2B_jumpifword(void)
static void atk2C_jumpifarrayequal(void)
{
- const u8* mem1 = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1);
- const u8* mem2 = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5);
+ const u8* mem1 = T2_READ_PTR(gBattlescriptCurrInstr + 1);
+ const u8* mem2 = T2_READ_PTR(gBattlescriptCurrInstr + 5);
u32 size = gBattlescriptCurrInstr[9];
- const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 10);
+ const u8* jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 10);
u8 i;
for (i = 0; i < size; i++)
@@ -4119,10 +4078,10 @@ static void atk2C_jumpifarrayequal(void)
static void atk2D_jumpifarraynotequal(void)
{
u8 equalBytes = 0;
- const u8* mem1 = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1);
- const u8* mem2 = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5);
+ const u8* mem1 = T2_READ_PTR(gBattlescriptCurrInstr + 1);
+ const u8* mem2 = T2_READ_PTR(gBattlescriptCurrInstr + 5);
u32 size = gBattlescriptCurrInstr[9];
- const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 10);
+ const u8* jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 10);
u8 i;
for (i = 0; i < size; i++)
@@ -4142,7 +4101,7 @@ static void atk2D_jumpifarraynotequal(void)
static void atk2E_setbyte(void)
{
- u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1);
+ u8* memByte = T2_READ_PTR(gBattlescriptCurrInstr + 1);
*memByte = gBattlescriptCurrInstr[5];
gBattlescriptCurrInstr += 6;
@@ -4150,22 +4109,22 @@ static void atk2E_setbyte(void)
static void atk2F_addbyte(void)
{
- u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1);
+ u8* memByte = T2_READ_PTR(gBattlescriptCurrInstr + 1);
*memByte += gBattlescriptCurrInstr[5];
gBattlescriptCurrInstr += 6;
}
static void atk30_subbyte(void)
{
- u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1);
+ u8* memByte = T2_READ_PTR(gBattlescriptCurrInstr + 1);
*memByte -= gBattlescriptCurrInstr[5];
gBattlescriptCurrInstr += 6;
}
static void atk31_copyarray(void)
{
- u8* dest = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1);
- const u8* src = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5);
+ u8* dest = T2_READ_PTR(gBattlescriptCurrInstr + 1);
+ const u8* src = T2_READ_PTR(gBattlescriptCurrInstr + 5);
s32 size = gBattlescriptCurrInstr[9];
s32 i;
@@ -4179,9 +4138,9 @@ static void atk31_copyarray(void)
static void atk32_copyarraywithindex(void)
{
- u8* dest = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1);
- const u8* src = BS2ScriptReadPtr(gBattlescriptCurrInstr + 5);
- const u8* index = BS2ScriptReadPtr(gBattlescriptCurrInstr + 9);
+ u8* dest = T2_READ_PTR(gBattlescriptCurrInstr + 1);
+ const u8* src = T2_READ_PTR(gBattlescriptCurrInstr + 5);
+ const u8* index = T2_READ_PTR(gBattlescriptCurrInstr + 9);
s32 size = gBattlescriptCurrInstr[13];
s32 i;
@@ -4195,15 +4154,15 @@ static void atk32_copyarraywithindex(void)
static void atk33_orbyte(void)
{
- u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1);
+ u8* memByte = T2_READ_PTR(gBattlescriptCurrInstr + 1);
*memByte |= gBattlescriptCurrInstr[5];
gBattlescriptCurrInstr += 6;
}
static void atk34_orhalfword(void)
{
- u16* memHword = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1);
- u16 val = BS2ScriptRead16(gBattlescriptCurrInstr + 5);
+ u16* memHword = T2_READ_PTR(gBattlescriptCurrInstr + 1);
+ u16 val = T2_READ_16(gBattlescriptCurrInstr + 5);
*memHword |= val;
gBattlescriptCurrInstr += 7;
@@ -4211,8 +4170,8 @@ static void atk34_orhalfword(void)
static void atk35_orword(void)
{
- u32* memWord = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1);
- u32 val = BS2ScriptRead32(gBattlescriptCurrInstr + 5);
+ u32* memWord = T2_READ_PTR(gBattlescriptCurrInstr + 1);
+ u32 val = T2_READ_32(gBattlescriptCurrInstr + 5);
*memWord |= val;
gBattlescriptCurrInstr += 9;
@@ -4220,15 +4179,15 @@ static void atk35_orword(void)
static void atk36_bicbyte(void)
{
- u8* memByte = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1);
+ u8* memByte = T2_READ_PTR(gBattlescriptCurrInstr + 1);
*memByte &= ~(gBattlescriptCurrInstr[5]);
gBattlescriptCurrInstr += 6;
}
static void atk37_bichalfword(void)
{
- u16* memHword = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1);
- u16 val = BS2ScriptRead16(gBattlescriptCurrInstr + 5);
+ u16* memHword = T2_READ_PTR(gBattlescriptCurrInstr + 1);
+ u16 val = T2_READ_16(gBattlescriptCurrInstr + 5);
*memHword &= ~val;
gBattlescriptCurrInstr += 7;
@@ -4236,8 +4195,8 @@ static void atk37_bichalfword(void)
static void atk38_bicword(void)
{
- u32* memWord = BS2ScriptReadPtr(gBattlescriptCurrInstr + 1);
- u32 val = BS2ScriptRead32(gBattlescriptCurrInstr + 5);
+ u32* memWord = T2_READ_PTR(gBattlescriptCurrInstr + 1);
+ u32 val = T2_READ_32(gBattlescriptCurrInstr + 5);
*memWord &= ~val;
gBattlescriptCurrInstr += 9;
@@ -4247,7 +4206,7 @@ static void atk39_pause(void)
{
if (gBattleControllerExecFlags == 0)
{
- u16 value = BS2ScriptRead16(gBattlescriptCurrInstr + 1);
+ u16 value = T2_READ_16(gBattlescriptCurrInstr + 1);
if (++gPauseCounterBattle >= value)
{
gPauseCounterBattle = 0;
@@ -4306,7 +4265,7 @@ static void atk3F_end3(void) // pops the main function stack
static void atk41_call(void)
{
BattleScriptPush(gBattlescriptCurrInstr + 5);
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
static void atk42_jumpiftype2(void)
@@ -4314,7 +4273,7 @@ static void atk42_jumpiftype2(void)
u8 battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
if (gBattlescriptCurrInstr[2] == gBattleMons[battlerId].type1 || gBattlescriptCurrInstr[2] == gBattleMons[battlerId].type2)
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 3);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else
gBattlescriptCurrInstr += 7;
}
@@ -4322,7 +4281,7 @@ static void atk42_jumpiftype2(void)
static void atk43_jumpifabilitypresent(void)
{
if (AbilityBattleEffects(ABILITYEFFECT_CHECK_ON_FIELD, 0, gBattlescriptCurrInstr[1], 0, 0))
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
else
gBattlescriptCurrInstr += 6;
}
@@ -4337,7 +4296,7 @@ static void atk45_playanimation(void)
const u16* argumentPtr;
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
- argumentPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 3);
+ argumentPtr = T2_READ_PTR(gBattlescriptCurrInstr + 3);
if (gBattlescriptCurrInstr[2] == B_ANIM_STATS_CHANGE
|| gBattlescriptCurrInstr[2] == B_ANIM_SNATCH_MOVE
@@ -4379,8 +4338,8 @@ static void atk46_playanimation2(void) // animation Id is stored in the first po
const u8* animationIdPtr;
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
- animationIdPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 2);
- argumentPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 6);
+ animationIdPtr = T2_READ_PTR(gBattlescriptCurrInstr + 2);
+ argumentPtr = T2_READ_PTR(gBattlescriptCurrInstr + 6);
if (*animationIdPtr == B_ANIM_STATS_CHANGE
|| *animationIdPtr == B_ANIM_SNATCH_MOVE
@@ -4438,31 +4397,34 @@ static void atk47_setgraphicalstatchangevalues(void)
gBattlescriptCurrInstr++;
}
-#ifdef NONMATCHING
static void atk48_playstatchangeanimation(void)
{
u32 currStat = 0;
- s16 statAnimId = 0;
- s16 checkingStatAnimId = 0;
- s32 changeableStats = 0;
- u32 statsToCheck = 0;
+ u16 statAnimId = 0;
+ s32 changeableStatsCount = 0;
+ u8 statsToCheck = 0;
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
statsToCheck = gBattlescriptCurrInstr[2];
if (gBattlescriptCurrInstr[3] & ATK48_STAT_NEGATIVE) // goes down
{
- checkingStatAnimId = (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO) ? 0x2D : 0x15;
+ s16 startingStatAnimId;
+ if (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO)
+ startingStatAnimId = 0x2D;
+ else
+ startingStatAnimId = 0x15;
+
while (statsToCheck != 0)
{
if (statsToCheck & 1)
{
- if (!(gBattlescriptCurrInstr[3] & ATK48_LOWER_FAIL_CHECK))
+ if (gBattlescriptCurrInstr[3] & ATK48_DONT_CHECK_LOWER)
{
if (gBattleMons[gActiveBattler].statStages[currStat] > 0)
{
- statAnimId = checkingStatAnimId;
- changeableStats++;
+ statAnimId = startingStatAnimId + currStat;
+ changeableStatsCount++;
}
}
else if (!gSideTimers[GET_BATTLER_SIDE(gActiveBattler)].mistTimer
@@ -4473,15 +4435,15 @@ static void atk48_playstatchangeanimation(void)
{
if (gBattleMons[gActiveBattler].statStages[currStat] > 0)
{
- statAnimId = checkingStatAnimId;
- changeableStats++;
+ statAnimId = startingStatAnimId + currStat;
+ changeableStatsCount++;
}
}
}
- statsToCheck >>= 1, checkingStatAnimId++, currStat++;
+ statsToCheck >>= 1, currStat++;
}
- if (changeableStats > 1) // more than one stat, so the color is gray
+ if (changeableStatsCount > 1) // more than one stat, so the color is gray
{
if (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO)
statAnimId = 0x3A;
@@ -4491,18 +4453,23 @@ static void atk48_playstatchangeanimation(void)
}
else // goes up
{
- checkingStatAnimId = (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO) ? 0x26 : 0xE;
+ s16 startingStatAnimId;
+ if (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO)
+ startingStatAnimId = 0x26;
+ else
+ startingStatAnimId = 0xE;
+
while (statsToCheck != 0)
{
if (statsToCheck & 1 && gBattleMons[gActiveBattler].statStages[currStat] < 0xC)
{
- statAnimId = checkingStatAnimId;
- changeableStats++;
+ statAnimId = startingStatAnimId + currStat;
+ changeableStatsCount++;
}
- statsToCheck >>= 1, checkingStatAnimId += 1, currStat++;
+ statsToCheck >>= 1, currStat++;
}
- if (changeableStats > 1) // more than one stat, so the color is gray
+ if (changeableStatsCount > 1) // more than one stat, so the color is gray
{
if (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO)
statAnimId = 0x38;
@@ -4511,15 +4478,15 @@ static void atk48_playstatchangeanimation(void)
}
}
- if (gBattlescriptCurrInstr[3] & ATK48_BIT_x4 && changeableStats < 2)
+ if (gBattlescriptCurrInstr[3] & ATK48_BIT_x4 && changeableStatsCount < 2)
{
gBattlescriptCurrInstr += 4;
}
- else if (changeableStats != 0 && gBattleScripting.field_1B == 0)
+ else if (changeableStatsCount != 0 && gBattleScripting.field_1B == 0)
{
BtlController_EmitBattleAnimation(0, B_ANIM_STATS_CHANGE, statAnimId);
MarkBattlerForControllerExec(gActiveBattler);
- if (gBattlescriptCurrInstr[3] & ATK48_BIT_x4 && changeableStats > 1)
+ if (gBattlescriptCurrInstr[3] & ATK48_BIT_x4 && changeableStatsCount > 1)
gBattleScripting.field_1B = 1;
gBattlescriptCurrInstr += 4;
}
@@ -4528,261 +4495,6 @@ static void atk48_playstatchangeanimation(void)
gBattlescriptCurrInstr += 4;
}
}
-#else
-__attribute__((naked))
-static void atk48_playstatchangeanimation(void)
-{
- asm("\n\
- .syntax unified\n\
- push {r4-r7,lr}\n\
- mov r7, r10\n\
- mov r6, r9\n\
- mov r5, r8\n\
- push {r5-r7}\n\
- sub sp, 0x4\n\
- movs r7, 0\n\
- movs r0, 0\n\
- mov r8, r0\n\
- movs r3, 0\n\
- ldr r5, =gBattlescriptCurrInstr\n\
- ldr r0, [r5]\n\
- ldrb r0, [r0, 0x1]\n\
- str r3, [sp]\n\
- bl GetBattlerForBattleScript\n\
- ldr r2, =gActiveBattler\n\
- strb r0, [r2]\n\
- ldr r0, [r5]\n\
- ldrb r4, [r0, 0x2]\n\
- ldrb r1, [r0, 0x3]\n\
- movs r0, 0x1\n\
- ands r0, r1\n\
- ldr r3, [sp]\n\
- cmp r0, 0\n\
- beq _0804BAEC\n\
- movs r0, 0x2\n\
- ands r0, r1\n\
- movs r1, 0x15\n\
- cmp r0, 0\n\
- beq _0804BA18\n\
- movs r1, 0x2D\n\
-_0804BA18:\n\
- cmp r4, 0\n\
- beq _0804BAC0\n\
- movs r0, 0x1\n\
- mov r10, r0\n\
- ldr r0, =gBattleMons + 0x18\n\
- mov r9, r0\n\
- lsls r5, r1, 16\n\
-_0804BA26:\n\
- adds r0, r4, 0\n\
- mov r1, r10\n\
- ands r0, r1\n\
- cmp r0, 0\n\
- beq _0804BAB2\n\
- ldr r0, =gBattlescriptCurrInstr\n\
- ldr r0, [r0]\n\
- ldrb r1, [r0, 0x3]\n\
- movs r0, 0x8\n\
- ands r0, r1\n\
- cmp r0, 0\n\
- beq _0804BA58\n\
- ldr r0, =gActiveBattler\n\
- ldrb r1, [r0]\n\
- movs r0, 0x58\n\
- muls r0, r1\n\
- adds r0, r7, r0\n\
- b _0804BAA0\n\
- .pool\n\
-_0804BA58:\n\
- ldr r6, =gActiveBattler\n\
- ldrb r0, [r6]\n\
- str r3, [sp]\n\
- bl GetBattlerPosition\n\
- mov r1, r10\n\
- ands r1, r0\n\
- lsls r0, r1, 1\n\
- adds r0, r1\n\
- lsls r0, 2\n\
- ldr r1, =gSideTimers\n\
- adds r0, r1\n\
- ldrb r0, [r0, 0x4]\n\
- ldr r3, [sp]\n\
- cmp r0, 0\n\
- bne _0804BAB2\n\
- ldr r0, =gBattleMons\n\
- ldrb r2, [r6]\n\
- movs r1, 0x58\n\
- muls r2, r1\n\
- adds r0, r2, r0\n\
- adds r0, 0x20\n\
- ldrb r0, [r0]\n\
- cmp r0, 0x1D\n\
- beq _0804BAB2\n\
- cmp r0, 0x49\n\
- beq _0804BAB2\n\
- cmp r0, 0x33\n\
- bne _0804BA96\n\
- cmp r7, 0x6\n\
- beq _0804BAB2\n\
-_0804BA96:\n\
- cmp r0, 0x34\n\
- bne _0804BA9E\n\
- cmp r7, 0x1\n\
- beq _0804BAB2\n\
-_0804BA9E:\n\
- adds r0, r7, r2\n\
-_0804BAA0:\n\
- add r0, r9\n\
- ldrb r0, [r0]\n\
- lsls r0, 24\n\
- asrs r0, 24\n\
- cmp r0, 0\n\
- ble _0804BAB2\n\
- lsrs r0, r5, 16\n\
- mov r8, r0\n\
- adds r3, 0x1\n\
-_0804BAB2:\n\
- lsrs r4, 1\n\
- movs r1, 0x80\n\
- lsls r1, 9\n\
- adds r5, r1\n\
- adds r7, 0x1\n\
- cmp r4, 0\n\
- bne _0804BA26\n\
-_0804BAC0:\n\
- ldr r0, =gBattlescriptCurrInstr\n\
- mov r9, r0\n\
- cmp r3, 0x1\n\
- ble _0804BB4E\n\
- ldr r0, [r0]\n\
- ldrb r1, [r0, 0x3]\n\
- movs r0, 0x2\n\
- ands r0, r1\n\
- movs r1, 0x39\n\
- mov r8, r1\n\
- cmp r0, 0\n\
- beq _0804BB4E\n\
- movs r0, 0x3A\n\
- b _0804BB4C\n\
- .pool\n\
-_0804BAEC:\n\
- movs r0, 0x2\n\
- ands r0, r1\n\
- movs r1, 0xE\n\
- cmp r0, 0\n\
- beq _0804BAF8\n\
- movs r1, 0x26\n\
-_0804BAF8:\n\
- mov r9, r5\n\
- cmp r4, 0\n\
- beq _0804BB34\n\
- ldr r6, =gBattleMons + 0x18\n\
- adds r5, r2, 0\n\
- lsls r2, r1, 16\n\
-_0804BB04:\n\
- movs r0, 0x1\n\
- ands r0, r4\n\
- cmp r0, 0\n\
- beq _0804BB26\n\
- ldrb r1, [r5]\n\
- movs r0, 0x58\n\
- muls r0, r1\n\
- adds r0, r7, r0\n\
- adds r0, r6\n\
- ldrb r0, [r0]\n\
- lsls r0, 24\n\
- asrs r0, 24\n\
- cmp r0, 0xB\n\
- bgt _0804BB26\n\
- lsrs r1, r2, 16\n\
- mov r8, r1\n\
- adds r3, 0x1\n\
-_0804BB26:\n\
- lsrs r4, 1\n\
- movs r0, 0x80\n\
- lsls r0, 9\n\
- adds r2, r0\n\
- adds r7, 0x1\n\
- cmp r4, 0\n\
- bne _0804BB04\n\
-_0804BB34:\n\
- cmp r3, 0x1\n\
- ble _0804BB4E\n\
- mov r1, r9\n\
- ldr r0, [r1]\n\
- ldrb r1, [r0, 0x3]\n\
- movs r0, 0x2\n\
- ands r0, r1\n\
- movs r1, 0x37\n\
- mov r8, r1\n\
- cmp r0, 0\n\
- beq _0804BB4E\n\
- movs r0, 0x38\n\
-_0804BB4C:\n\
- mov r8, r0\n\
-_0804BB4E:\n\
- mov r1, r9\n\
- ldr r2, [r1]\n\
- ldrb r1, [r2, 0x3]\n\
- movs r0, 0x4\n\
- ands r0, r1\n\
- cmp r0, 0\n\
- beq _0804BB6C\n\
- cmp r3, 0x1\n\
- bgt _0804BB6C\n\
- adds r0, r2, 0x4\n\
- mov r1, r9\n\
- b _0804BBBA\n\
- .pool\n\
-_0804BB6C:\n\
- cmp r3, 0\n\
- beq _0804BBB4\n\
- ldr r4, =gBattleScripting\n\
- ldrb r0, [r4, 0x1B]\n\
- cmp r0, 0\n\
- bne _0804BBB4\n\
- movs r0, 0\n\
- movs r1, 0x1\n\
- mov r2, r8\n\
- str r3, [sp]\n\
- bl BtlController_EmitBattleAnimation\n\
- ldr r0, =gActiveBattler\n\
- ldrb r0, [r0]\n\
- bl MarkBattlerForControllerExec\n\
- ldr r0, =gBattlescriptCurrInstr\n\
- ldr r0, [r0]\n\
- ldrb r1, [r0, 0x3]\n\
- movs r0, 0x4\n\
- ands r0, r1\n\
- ldr r3, [sp]\n\
- cmp r0, 0\n\
- beq _0804BBA4\n\
- cmp r3, 0x1\n\
- ble _0804BBA4\n\
- movs r0, 0x1\n\
- strb r0, [r4, 0x1B]\n\
-_0804BBA4:\n\
- ldr r1, =gBattlescriptCurrInstr\n\
- b _0804BBB6\n\
- .pool\n\
-_0804BBB4:\n\
- mov r1, r9\n\
-_0804BBB6:\n\
- ldr r0, [r1]\n\
- adds r0, 0x4\n\
-_0804BBBA:\n\
- str r0, [r1]\n\
- add sp, 0x4\n\
- pop {r3-r5}\n\
- mov r8, r3\n\
- mov r9, r4\n\
- mov r10, r5\n\
- pop {r4-r7}\n\
- pop {r0}\n\
- bx r0\n\
- .syntax divided");
-}
-#endif // NONMATCHING
#define ATK49_LAST_CASE 17
@@ -5273,10 +4985,9 @@ static void atk4E_switchinanim(void)
static void atk4F_jumpifcantswitch(void)
{
- s32 val = 0;
- s32 compareVar = 0;
- struct Pokemon *party = NULL;
- s32 r7 = 0;
+ s32 i;
+ s32 lastMonId;
+ struct Pokemon *party;
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1] & ~(ATK4F_DONT_CHECK_STATUSES));
@@ -5284,7 +4995,7 @@ static void atk4F_jumpifcantswitch(void)
&& ((gBattleMons[gActiveBattler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION))
|| (gStatuses3[gActiveBattler] & STATUS3_ROOTED)))
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
}
else if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
{
@@ -5296,21 +5007,21 @@ static void atk4F_jumpifcantswitch(void)
else
party = gPlayerParty;
- val = 0;
- if (2 & gActiveBattler)
- val = 3;
+ i = 0;
+ if (gActiveBattler & 2)
+ i = 3;
- for (compareVar = val + 3; val < compareVar; val++)
+ for (lastMonId = i + 3; i < lastMonId; i++)
{
- if (GetMonData(&party[val], MON_DATA_SPECIES) != SPECIES_NONE
- && !GetMonData(&party[val], MON_DATA_IS_EGG)
- && GetMonData(&party[val], MON_DATA_HP) != 0
- && gBattlerPartyIndexes[gActiveBattler] != val)
+ if (GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE
+ && !GetMonData(&party[i], MON_DATA_IS_EGG)
+ && GetMonData(&party[i], MON_DATA_HP) != 0
+ && gBattlerPartyIndexes[gActiveBattler] != i)
break;
}
- if (val == compareVar)
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2);
+ if (i == lastMonId)
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
else
gBattlescriptCurrInstr += 6;
}
@@ -5322,18 +5033,18 @@ static void atk4F_jumpifcantswitch(void)
{
party = gPlayerParty;
- val = 0;
+ i = 0;
if (sub_806D82C(GetBattlerMultiplayerId(gActiveBattler)) == TRUE)
- val = 3;
+ i = 3;
}
else
{
party = gEnemyParty;
if (gActiveBattler == 1)
- val = 0;
+ i = 0;
else
- val = 3;
+ i = 3;
}
}
else
@@ -5343,23 +5054,22 @@ static void atk4F_jumpifcantswitch(void)
else
party = gPlayerParty;
-
- val = 0;
+ i = 0;
if (sub_806D82C(GetBattlerMultiplayerId(gActiveBattler)) == TRUE)
- val = 3;
+ i = 3;
}
- for (compareVar = val + 3; val < compareVar; val++)
+ for (lastMonId = i + 3; i < lastMonId; i++)
{
- if (GetMonData(&party[val], MON_DATA_SPECIES) != SPECIES_NONE
- && !GetMonData(&party[val], MON_DATA_IS_EGG)
- && GetMonData(&party[val], MON_DATA_HP) != 0
- && gBattlerPartyIndexes[gActiveBattler] != val)
+ if (GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE
+ && !GetMonData(&party[i], MON_DATA_IS_EGG)
+ && GetMonData(&party[i], MON_DATA_HP) != 0
+ && gBattlerPartyIndexes[gActiveBattler] != i)
break;
}
- if (val == compareVar)
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2);
+ if (i == lastMonId)
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
else
gBattlescriptCurrInstr += 6;
}
@@ -5367,59 +5077,62 @@ static void atk4F_jumpifcantswitch(void)
{
party = gEnemyParty;
- val = 0;
- if (gActiveBattler == 3)
- val = 3;
+ i = 0;
+ if (gActiveBattler == B_POSITION_OPPONENT_RIGHT)
+ i = 3;
- for (compareVar = val + 3; val < compareVar; val++)
+ for (lastMonId = i + 3; i < lastMonId; i++)
{
- if (GetMonData(&party[val], MON_DATA_SPECIES) != SPECIES_NONE
- && !GetMonData(&party[val], MON_DATA_IS_EGG)
- && GetMonData(&party[val], MON_DATA_HP) != 0
- && gBattlerPartyIndexes[gActiveBattler] != val)
+ if (GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE
+ && !GetMonData(&party[i], MON_DATA_IS_EGG)
+ && GetMonData(&party[i], MON_DATA_HP) != 0
+ && gBattlerPartyIndexes[gActiveBattler] != i)
break;
}
- if (val == compareVar)
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2);
+ if (i == lastMonId)
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
else
gBattlescriptCurrInstr += 6;
}
else
{
+ u8 battlerIn1, battlerIn2;
+
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT)
{
- r7 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
+ battlerIn1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
- compareVar = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
+ battlerIn2 = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
else
- compareVar = r7;
+ battlerIn2 = battlerIn1;
party = gEnemyParty;
}
else
{
- r7 = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
+ battlerIn1 = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
- compareVar = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
+ battlerIn2 = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
else
- compareVar = r7;
+ battlerIn2 = battlerIn1;
party = gPlayerParty;
}
- for (val = 0; val < 6; val++)
+
+ for (i = 0; i < PARTY_SIZE; i++)
{
- if (GetMonData(&party[val], MON_DATA_HP) != 0
- && GetMonData(&party[val], MON_DATA_SPECIES) != SPECIES_NONE
- && !GetMonData(&party[val], MON_DATA_IS_EGG)
- && val != gBattlerPartyIndexes[r7] && val != gBattlerPartyIndexes[compareVar])
+ if (GetMonData(&party[i], MON_DATA_HP) != 0
+ && GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE
+ && !GetMonData(&party[i], MON_DATA_IS_EGG)
+ && i != gBattlerPartyIndexes[battlerIn1] && i != gBattlerPartyIndexes[battlerIn2])
break;
}
- if (val == 6)
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2);
+ if (i == 6)
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
else
gBattlescriptCurrInstr += 6;
}
@@ -5444,7 +5157,7 @@ static void atk50_openpartyscreen(void)
battlerId = 0;
flags = 0;
- jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 2);
+ jumpPtr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
if (gBattlescriptCurrInstr[1] == 5)
{
@@ -5804,8 +5517,7 @@ static void atk52_switchineffects(void)
if (!(gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES_DAMAGED)
&& (gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES)
- && gBattleMons[gActiveBattler].type1 != TYPE_FLYING
- && gBattleMons[gActiveBattler].type2 != TYPE_FLYING
+ && !IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_FLYING)
&& gBattleMons[gActiveBattler].ability != ABILITY_LEVITATE)
{
u8 spikesDmg;
@@ -5885,7 +5597,7 @@ static void atk53_trainerslidein(void)
static void atk54_playse(void)
{
gActiveBattler = gBattlerAttacker;
- BtlController_EmitPlaySE(0, BS2ScriptRead16(gBattlescriptCurrInstr + 1));
+ BtlController_EmitPlaySE(0, T2_READ_16(gBattlescriptCurrInstr + 1));
MarkBattlerForControllerExec(gActiveBattler);
gBattlescriptCurrInstr += 3;
@@ -5894,7 +5606,7 @@ static void atk54_playse(void)
static void atk55_fanfare(void)
{
gActiveBattler = gBattlerAttacker;
- BtlController_EmitPlayFanfareOrBGM(0, BS2ScriptRead16(gBattlescriptCurrInstr + 1), FALSE);
+ BtlController_EmitPlayFanfareOrBGM(0, T2_READ_16(gBattlescriptCurrInstr + 1), FALSE);
MarkBattlerForControllerExec(gActiveBattler);
gBattlescriptCurrInstr += 3;
@@ -5929,8 +5641,8 @@ static void atk58_returntoball(void)
static void atk59_handlelearnnewmove(void)
{
- const u8 *jumpPtr1 = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
- const u8 *jumpPtr2 = BSScriptReadPtr(gBattlescriptCurrInstr + 5);
+ const u8 *jumpPtr1 = T1_READ_PTR(gBattlescriptCurrInstr + 1);
+ const u8 *jumpPtr2 = T1_READ_PTR(gBattlescriptCurrInstr + 5);
u16 ret = MonTryLearningNewMove(&gPlayerParty[gBattleStruct->expGetterMonId], gBattlescriptCurrInstr[9]);
while (ret == 0xFFFE)
@@ -6047,7 +5759,7 @@ static void atk5A_yesnoboxlearnmove(void)
}
else
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
PREPARE_MOVE_BUFFER(gBattleTextBuff2, moveId)
@@ -6117,7 +5829,7 @@ static void atk5B_yesnoboxstoplearningmove(void)
PlaySE(SE_SELECT);
if (gBattleCommunication[1] != 0)
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
else
gBattlescriptCurrInstr += 5;
@@ -6126,7 +5838,7 @@ static void atk5B_yesnoboxstoplearningmove(void)
else if (gMain.newKeys & B_BUTTON)
{
PlaySE(SE_SELECT);
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
HandleBattleWindow(0x18, 0x8, 0x1D, 0xD, WINDOW_CLEAR);
}
break;
@@ -6351,7 +6063,7 @@ static void atk65_status2animation(void)
if (gBattleControllerExecFlags == 0)
{
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
- wantedToAnimate = BSScriptRead32(gBattlescriptCurrInstr + 2);
+ wantedToAnimate = T1_READ_32(gBattlescriptCurrInstr + 2);
if (!(gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE)
&& gDisableStructs[gActiveBattler].substituteHP == 0
&& !(gHitMarker & HITMARKER_NO_ANIMATIONS))
@@ -6370,7 +6082,7 @@ static void atk66_chosenstatusanimation(void)
if (gBattleControllerExecFlags == 0)
{
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
- wantedStatus = BSScriptRead32(gBattlescriptCurrInstr + 3);
+ wantedStatus = T1_READ_32(gBattlescriptCurrInstr + 3);
if (!(gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE)
&& gDisableStructs[gActiveBattler].substituteHP == 0
&& !(gHitMarker & HITMARKER_NO_ANIMATIONS))
@@ -6821,7 +6533,7 @@ static void atk71_buffermovetolearn(void)
static void atk72_jumpifplayerran(void)
{
if (TryRunFromBattle(gBattlerFainted))
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
else
gBattlescriptCurrInstr += 5;
}
@@ -6882,8 +6594,7 @@ static void atk74_hpthresholds2(void)
static void atk75_useitemonopponent(void)
{
gBattlerInMenuId = gBattlerAttacker;
- ExecuteTableBasedItemEffect(&gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker]], gLastUsedItem, gBattlerPartyIndexes[gBattlerAttacker], 0, 1);
-
+ PokemonUseItemEffects(&gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker]], gLastUsedItem, gBattlerPartyIndexes[gBattlerAttacker], 0, 1);
gBattlescriptCurrInstr += 1;
}
@@ -7151,7 +6862,7 @@ static void atk79_setatkhptozero(void)
static void atk7A_jumpifnexttargetvalid(void)
{
- const u8 *jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ const u8 *jumpPtr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
@@ -7176,7 +6887,7 @@ static void atk7A_jumpifnexttargetvalid(void)
static void atk7B_tryhealhalfhealth(void)
{
- const u8* failPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ const u8* failPtr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
if (gBattlescriptCurrInstr[5] == BS_ATTACKER)
gBattlerTarget = gBattlerAttacker;
@@ -7286,7 +6997,7 @@ static void atk7F_setseeded(void)
gMoveResultFlags |= MOVE_RESULT_MISSED;
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
}
- else if (gBattleMons[gBattlerTarget].type1 == TYPE_GRASS || gBattleMons[gBattlerTarget].type2 == TYPE_GRASS)
+ else if (IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_GRASS))
{
gMoveResultFlags |= MOVE_RESULT_MISSED;
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
@@ -7325,7 +7036,7 @@ static void atk80_manipulatedamage(void)
static void atk81_trysetrest(void)
{
- const u8 *failJump = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ const u8 *failJump = T1_READ_PTR(gBattlescriptCurrInstr + 1);
gActiveBattler = gBattlerTarget = gBattlerAttacker;
gBattleMoveDamage = gBattleMons[gBattlerTarget].maxHP * (-1);
@@ -7349,7 +7060,7 @@ static void atk81_trysetrest(void)
static void atk82_jumpifnotfirstturn(void)
{
- const u8* failJump = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ const u8* failJump = T1_READ_PTR(gBattlescriptCurrInstr + 1);
if (gDisableStructs[gBattlerAttacker].isFirstTurn)
gBattlescriptCurrInstr += 5;
@@ -7391,7 +7102,7 @@ bool8 UproarWakeUpCheck(u8 battlerId)
static void atk84_jumpifcantmakeasleep(void)
{
- const u8 *jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ const u8 *jumpPtr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
if (UproarWakeUpCheck(gBattlerTarget))
{
@@ -7431,7 +7142,7 @@ static void atk85_stockpile(void)
static void atk86_stockpiletobasedamage(void)
{
- const u8* jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ const u8* jumpPtr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
if (gDisableStructs[gBattlerAttacker].stockpileCounter == 0)
{
gBattlescriptCurrInstr = jumpPtr;
@@ -7457,7 +7168,7 @@ static void atk86_stockpiletobasedamage(void)
static void atk87_stockpiletohpheal(void)
{
- const u8* jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ const u8* jumpPtr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
if (gDisableStructs[gBattlerAttacker].stockpileCounter == 0)
{
@@ -7667,7 +7378,7 @@ static u8 ChangeStatBuffs(s8 statValue, u8 statId, u8 flags, const u8 *BS_ptr)
static void atk89_statbuffchange(void)
{
- const u8* jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 2);
+ const u8* jumpPtr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
if (ChangeStatBuffs(gBattleScripting.statChanger & 0xF0, GET_STAT_BUFF_ID(gBattleScripting.statChanger), gBattlescriptCurrInstr[1], jumpPtr) == STAT_CHANGE_WORKED)
gBattlescriptCurrInstr += 6;
}
@@ -7739,7 +7450,7 @@ static bool8 TryDoForceSwitchOut(void)
u16 random = Random() & 0xFF;
if ((u32)((random * (gBattleMons[gBattlerAttacker].level + gBattleMons[gBattlerTarget].level) >> 8) + 1) <= (gBattleMons[gBattlerTarget].level / 4))
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
return FALSE;
}
*(gBattleStruct->field_58 + gBattlerTarget) = gBattlerPartyIndexes[gBattlerTarget];
@@ -7869,7 +7580,7 @@ static void atk8F_forcerandomswitch(void)
if (validMons <= minNeeded)
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
@@ -7930,7 +7641,7 @@ static void atk90_tryconversiontypechange(void) // randomly changes user's type
if (moveType == TYPE_MYSTERY)
{
- if (gBattleMons[gBattlerAttacker].type1 == TYPE_GHOST || gBattleMons[gBattlerAttacker].type2 == TYPE_GHOST)
+ if (IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GHOST))
moveType = TYPE_GHOST;
else
moveType = TYPE_NORMAL;
@@ -7944,7 +7655,7 @@ static void atk90_tryconversiontypechange(void) // randomly changes user's type
if (moveChecked == validMoves)
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
@@ -7957,7 +7668,7 @@ static void atk90_tryconversiontypechange(void) // randomly changes user's type
if (moveType == TYPE_MYSTERY)
{
- if (gBattleMons[gBattlerAttacker].type1 == TYPE_GHOST || gBattleMons[gBattlerAttacker].type2 == TYPE_GHOST)
+ if (IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GHOST))
moveType = TYPE_GHOST;
else
moveType = TYPE_NORMAL;
@@ -7965,10 +7676,8 @@ static void atk90_tryconversiontypechange(void) // randomly changes user's type
}
while (moveType == gBattleMons[gBattlerAttacker].type1 || moveType == gBattleMons[gBattlerAttacker].type2);
- gBattleMons[gBattlerAttacker].type1 = moveType;
- gBattleMons[gBattlerAttacker].type2 = moveType;
-
- PREPARE_TYPE_BUFFER(gBattleTextBuff1, moveType)
+ SET_BATTLER_TYPE(gBattlerAttacker, moveType);
+ PREPARE_TYPE_BUFFER(gBattleTextBuff1, moveType);
gBattlescriptCurrInstr += 5;
}
@@ -8095,7 +7804,7 @@ static void atk93_tryKO(void)
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
else
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
}
@@ -8152,8 +7861,7 @@ static void atk96_weatherdamage(void)
}
if (gBattleWeather & WEATHER_HAIL)
{
- if (gBattleMons[gBattlerAttacker].type1 != TYPE_ICE
- && gBattleMons[gBattlerAttacker].type2 != TYPE_ICE
+ if (!IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_ICE)
&& !(gStatuses3[gBattlerAttacker] & STATUS3_UNDERGROUND)
&& !(gStatuses3[gBattlerAttacker] & STATUS3_UNDERWATER))
{
@@ -8213,7 +7921,7 @@ static void atk97_tryinfatuating(void)
|| GetGenderFromSpeciesAndPersonality(speciesAttacker, personalityAttacker) == MON_GENDERLESS
|| GetGenderFromSpeciesAndPersonality(speciesTarget, personalityTarget) == MON_GENDERLESS)
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
@@ -8377,7 +8085,7 @@ static void atk9D_mimicattackcopy(void)
|| gLastMoves[gBattlerTarget] == 0
|| gLastMoves[gBattlerTarget] == 0xFFFF)
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
@@ -8405,7 +8113,7 @@ static void atk9D_mimicattackcopy(void)
}
else
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
}
@@ -8480,7 +8188,7 @@ static void atkA1_counterdamagecalculator(void)
else
{
gSpecialStatuses[gBattlerAttacker].flag20 = 1;
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
@@ -8503,7 +8211,7 @@ static void atkA2_mirrorcoatdamagecalculator(void) // a copy of atkA1 with the p
else
{
gSpecialStatuses[gBattlerAttacker].flag20 = 1;
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
@@ -8528,7 +8236,7 @@ static void atkA3_disablelastusedattack(void)
}
else
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
@@ -8560,7 +8268,7 @@ static void atkA4_trysetencore(void)
}
else
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
@@ -8584,7 +8292,7 @@ static void atkA5_painsplitdmgcalc(void)
}
else
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
@@ -8593,12 +8301,12 @@ static void atkA6_settypetorandomresistance(void) // conversion 2
if (gLastLandedMoves[gBattlerAttacker] == 0
|| gLastLandedMoves[gBattlerAttacker] == 0xFFFF)
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else if (IsTwoTurnsMove(gLastLandedMoves[gBattlerAttacker])
&& gBattleMons[gLastHitBy[gBattlerAttacker]].status2 & STATUS2_MULTIPLETURNS)
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
@@ -8612,13 +8320,10 @@ static void atkA6_settypetorandomresistance(void) // conversion 2
if (TYPE_EFFECT_ATK_TYPE(i) == gLastHitByType[gBattlerAttacker]
&& TYPE_EFFECT_MULTIPLIER(i) <= TYPE_MUL_NOT_EFFECTIVE
- && gBattleMons[gBattlerAttacker].type1 != TYPE_EFFECT_DEF_TYPE(i)
- && gBattleMons[gBattlerAttacker].type2 != TYPE_EFFECT_DEF_TYPE(i))
+ && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_EFFECT_DEF_TYPE(i)))
{
- gBattleMons[gBattlerAttacker].type1 = TYPE_EFFECT_DEF_TYPE(i);
- gBattleMons[gBattlerAttacker].type2 = TYPE_EFFECT_DEF_TYPE(i);
-
- PREPARE_TYPE_BUFFER(gBattleTextBuff1, TYPE_EFFECT_DEF_TYPE(i))
+ SET_BATTLER_TYPE(gBattlerAttacker, TYPE_EFFECT_DEF_TYPE(i));
+ PREPARE_TYPE_BUFFER(gBattleTextBuff1, TYPE_EFFECT_DEF_TYPE(i));
gBattlescriptCurrInstr += 5;
return;
@@ -8635,12 +8340,9 @@ static void atkA6_settypetorandomresistance(void) // conversion 2
default:
if (TYPE_EFFECT_ATK_TYPE(j) == gLastHitByType[gBattlerAttacker]
&& TYPE_EFFECT_MULTIPLIER(j) <= 5
- && gBattleMons[gBattlerAttacker].type1 != TYPE_EFFECT_DEF_TYPE(i)
- && gBattleMons[gBattlerAttacker].type2 != TYPE_EFFECT_DEF_TYPE(i))
+ && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_EFFECT_DEF_TYPE(i)))
{
- gBattleMons[gBattlerAttacker].type1 = TYPE_EFFECT_DEF_TYPE(rands);
- gBattleMons[gBattlerAttacker].type2 = TYPE_EFFECT_DEF_TYPE(rands);
-
+ SET_BATTLER_TYPE(gBattlerAttacker, TYPE_EFFECT_DEF_TYPE(rands));
PREPARE_TYPE_BUFFER(gBattleTextBuff1, TYPE_EFFECT_DEF_TYPE(rands))
gBattlescriptCurrInstr += 5;
@@ -8650,7 +8352,7 @@ static void atkA6_settypetorandomresistance(void) // conversion 2
}
}
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
@@ -8684,7 +8386,7 @@ static void atkA8_copymovepermanently(void) // sketch
if (i != 4)
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else // sketch worked
{
@@ -8711,7 +8413,7 @@ static void atkA8_copymovepermanently(void) // sketch
}
else
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
@@ -8792,7 +8494,7 @@ static void atkA9_trychoosesleeptalkmove(void)
gCurrMovePos = movePosition;
gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED);
gBattlerTarget = GetMoveTarget(gRandomMove, 0);
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
@@ -8877,12 +8579,12 @@ static void atkAD_tryspiteppreduce(void)
}
else
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
else
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
@@ -8986,7 +8688,7 @@ static void atkAF_cursetarget(void)
{
if (gBattleMons[gBattlerTarget].status2 & STATUS2_CURSED)
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
@@ -9006,7 +8708,7 @@ static void atkB0_trysetspikes(void)
if (gSideTimers[targetSide].spikesAmount == 3)
{
gSpecialStatuses[gBattlerAttacker].flag20 = 1;
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
@@ -9045,7 +8747,7 @@ static void atkB2_trysetperishsong(void)
PressurePPLoseOnUsingPerishSong(gBattlerAttacker);
if (notAffectedCount == gBattlersCount)
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
else
gBattlescriptCurrInstr += 5;
}
@@ -9089,7 +8791,7 @@ static void atkB4_jumpifconfusedandstatmaxed(void)
{
if (gBattleMons[gBattlerTarget].status2 & STATUS2_CONFUSION
&& gBattleMons[gBattlerTarget].statStages[gBattlescriptCurrInstr[1]] == 0xC)
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
else
gBattlescriptCurrInstr += 6;
}
@@ -9267,7 +8969,7 @@ static void atkBA_jumpifnopursuitswitchdmg(void)
}
else
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
@@ -9307,7 +9009,7 @@ static void atkBC_maxattackhalvehp(void) // belly drum
}
else
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
@@ -9387,185 +9089,39 @@ static void atkC0_recoverbasedonsunlight(void)
}
else
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
-#ifdef NONMATCHING
static void atkC1_hiddenpowercalc(void)
{
- u32 powerBits = 0;
- u32 typeBits = 0;
+ u8 powerBits;
+ u8 typeBits;
- powerBits |= ((gBattleMons[gBattlerAttacker].hpIV & 2) >> 1);
- powerBits |= ((gBattleMons[gBattlerAttacker].attackIV & 2) << 0);
- powerBits |= ((gBattleMons[gBattlerAttacker].defenseIV & 2) << 1);
- powerBits |= ((gBattleMons[gBattlerAttacker].speedIV & 2) << 2);
- powerBits |= ((gBattleMons[gBattlerAttacker].spAttackIV & 2) << 3);
- powerBits |= ((gBattleMons[gBattlerAttacker].spDefenseIV & 2) << 4);
+ powerBits = ((gBattleMons[gBattlerAttacker].hpIV & 2) >> 1)
+ | ((gBattleMons[gBattlerAttacker].attackIV & 2) << 0)
+ | ((gBattleMons[gBattlerAttacker].defenseIV & 2) << 1)
+ | ((gBattleMons[gBattlerAttacker].speedIV & 2) << 2)
+ | ((gBattleMons[gBattlerAttacker].spAttackIV & 2) << 3)
+ | ((gBattleMons[gBattlerAttacker].spDefenseIV & 2) << 4);
- typeBits |= ((gBattleMons[gBattlerAttacker].hpIV & 1) << 0);
- typeBits |= ((gBattleMons[gBattlerAttacker].attackIV & 1) << 1);
- typeBits |= ((gBattleMons[gBattlerAttacker].defenseIV & 1) << 2);
- typeBits |= ((gBattleMons[gBattlerAttacker].speedIV & 1) << 3);
- typeBits |= ((gBattleMons[gBattlerAttacker].spAttackIV & 1) << 4);
- typeBits |= ((gBattleMons[gBattlerAttacker].spDefenseIV & 1) << 5);
+ typeBits = ((gBattleMons[gBattlerAttacker].hpIV & 1) << 0)
+ | ((gBattleMons[gBattlerAttacker].attackIV & 1) << 1)
+ | ((gBattleMons[gBattlerAttacker].defenseIV & 1) << 2)
+ | ((gBattleMons[gBattlerAttacker].speedIV & 1) << 3)
+ | ((gBattleMons[gBattlerAttacker].spAttackIV & 1) << 4)
+ | ((gBattleMons[gBattlerAttacker].spDefenseIV & 1) << 5);
gDynamicBasePower = (40 * powerBits) / 63 + 30;
gBattleStruct->dynamicMoveType = (15 * typeBits) / 63 + 1;
- if (gBattleStruct->dynamicMoveType > 8)
+ if (gBattleStruct->dynamicMoveType >= TYPE_MYSTERY)
gBattleStruct->dynamicMoveType++;
gBattleStruct->dynamicMoveType |= 0xC0;
gBattlescriptCurrInstr++;
}
-#else
-__attribute__((naked))
-static void atkC1_hiddenpowercalc(void)
-{
- asm(".syntax unified\n\
- push {r4-r7,lr}\n\
- mov r7, r10\n\
- mov r6, r9\n\
- mov r5, r8\n\
- push {r5-r7}\n\
- ldr r2, =gBattleMons\n\
- ldr r0, =gBattlerAttacker\n\
- ldrb r1, [r0]\n\
- movs r0, 0x58\n\
- adds r4, r1, 0\n\
- muls r4, r0\n\
- adds r4, r2\n\
- ldrb r0, [r4, 0x14]\n\
- mov r10, r0\n\
- mov r7, r10\n\
- lsls r7, 27\n\
- adds r0, r7, 0\n\
- lsrs r0, 27\n\
- mov r10, r0\n\
- movs r1, 0x2\n\
- mov r2, r10\n\
- ands r2, r1\n\
- asrs r2, 1\n\
- ldrh r7, [r4, 0x14]\n\
- mov r9, r7\n\
- mov r0, r9\n\
- lsls r0, 22\n\
- mov r9, r0\n\
- lsrs r3, r0, 27\n\
- adds r0, r1, 0\n\
- ands r0, r3\n\
- orrs r2, r0\n\
- ldrb r7, [r4, 0x15]\n\
- mov r8, r7\n\
- mov r0, r8\n\
- lsls r0, 25\n\
- mov r8, r0\n\
- lsrs r3, r0, 27\n\
- adds r0, r1, 0\n\
- ands r0, r3\n\
- lsls r0, 1\n\
- orrs r2, r0\n\
- ldr r6, [r4, 0x14]\n\
- lsls r6, 12\n\
- lsrs r3, r6, 27\n\
- adds r0, r1, 0\n\
- ands r0, r3\n\
- lsls r0, 2\n\
- orrs r2, r0\n\
- ldrh r5, [r4, 0x16]\n\
- lsls r5, 23\n\
- lsrs r3, r5, 27\n\
- adds r0, r1, 0\n\
- ands r0, r3\n\
- lsls r0, 3\n\
- orrs r2, r0\n\
- ldrb r3, [r4, 0x17]\n\
- lsls r3, 26\n\
- lsrs r0, r3, 27\n\
- ands r1, r0\n\
- lsls r1, 4\n\
- orrs r2, r1\n\
- movs r1, 0x1\n\
- adds r4, r1, 0\n\
- mov r7, r10\n\
- ands r4, r7\n\
- mov r0, r9\n\
- lsrs r0, 27\n\
- mov r9, r0\n\
- adds r0, r1, 0\n\
- mov r7, r9\n\
- ands r0, r7\n\
- lsls r0, 1\n\
- orrs r4, r0\n\
- mov r0, r8\n\
- lsrs r0, 27\n\
- mov r8, r0\n\
- adds r0, r1, 0\n\
- mov r7, r8\n\
- ands r0, r7\n\
- lsls r0, 2\n\
- orrs r4, r0\n\
- lsrs r6, 27\n\
- adds r0, r1, 0\n\
- ands r0, r6\n\
- lsls r0, 3\n\
- orrs r4, r0\n\
- lsrs r5, 27\n\
- adds r0, r1, 0\n\
- ands r0, r5\n\
- lsls r0, 4\n\
- orrs r4, r0\n\
- lsrs r3, 27\n\
- ands r1, r3\n\
- lsls r1, 5\n\
- orrs r4, r1\n\
- ldr r5, =gDynamicBasePower\n\
- lsls r0, r2, 2\n\
- adds r0, r2\n\
- lsls r0, 3\n\
- movs r1, 0x3F\n\
- bl __divsi3\n\
- adds r0, 0x1E\n\
- strh r0, [r5]\n\
- ldr r6, =gBattleStruct\n\
- ldr r5, [r6]\n\
- lsls r0, r4, 4\n\
- subs r0, r4\n\
- movs r1, 0x3F\n\
- bl __divsi3\n\
- adds r0, 0x1\n\
- strb r0, [r5, 0x13]\n\
- ldr r1, [r6]\n\
- ldrb r0, [r1, 0x13]\n\
- cmp r0, 0x8\n\
- bls _080544F0\n\
- adds r0, 0x1\n\
- strb r0, [r1, 0x13]\n\
-_080544F0:\n\
- ldr r2, [r6]\n\
- ldrb r0, [r2, 0x13]\n\
- movs r1, 0xC0\n\
- orrs r0, r1\n\
- strb r0, [r2, 0x13]\n\
- ldr r1, =gBattlescriptCurrInstr\n\
- ldr r0, [r1]\n\
- adds r0, 0x1\n\
- str r0, [r1]\n\
- pop {r3-r5}\n\
- mov r8, r3\n\
- mov r9, r4\n\
- mov r10, r5\n\
- pop {r4-r7}\n\
- pop {r0}\n\
- bx r0\n\
- .pool\n\
- .syntax divided");
-}
-#endif // NONMATCHING
-
static void atkC2_selectfirstvalidtarget(void)
{
for (gBattlerTarget = 0; gBattlerTarget < gBattlersCount; gBattlerTarget++)
@@ -9582,7 +9138,7 @@ static void atkC3_trysetfutureattack(void)
{
if (gWishFutureKnock.futureSightCounter[gBattlerTarget] != 0)
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
@@ -9617,7 +9173,7 @@ static void atkC4_trydobeatup(void)
if (gBattleMons[gBattlerTarget].hp == 0)
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
@@ -9647,9 +9203,9 @@ static void atkC4_trydobeatup(void)
gBattleCommunication[0]++;
}
else if (beforeLoop != 0)
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
else
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 5);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 5);
}
}
@@ -9722,7 +9278,7 @@ static void atkC9_jumpifattackandspecialattackcannotfall(void) // memento
&& gBattleMons[gBattlerTarget].statStages[STAT_SPATK] == 0
&& gBattleCommunication[6] != 1)
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
@@ -9770,7 +9326,7 @@ static void atkCD_cureifburnedparalysedorpoisoned(void) // refresh
}
else
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
@@ -9778,7 +9334,7 @@ static void atkCE_settorment(void)
{
if (gBattleMons[gBattlerTarget].status2 & STATUS2_TORMENT)
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
@@ -9792,7 +9348,7 @@ static void atkCF_jumpifnodamage(void)
if (gProtectStructs[gBattlerAttacker].physicalDmg || gProtectStructs[gBattlerAttacker].specialDmg)
gBattlescriptCurrInstr += 5;
else
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
static void atkD0_settaunt(void)
@@ -9805,7 +9361,7 @@ static void atkD0_settaunt(void)
}
else
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
@@ -9823,7 +9379,7 @@ static void atkD1_trysethelpinghand(void)
}
else
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
@@ -9838,7 +9394,7 @@ static void atkD2_tryswapitems(void) // trick
| BATTLE_TYPE_SECRET_BASE
| BATTLE_TYPE_x2000000))))
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
@@ -9854,7 +9410,7 @@ static void atkD2_tryswapitems(void) // trick
&& (gWishFutureKnock.knockedOffPokes[sideAttacker] & gBitTable[gBattlerPartyIndexes[gBattlerAttacker]]
|| gWishFutureKnock.knockedOffPokes[sideTarget] & gBitTable[gBattlerPartyIndexes[gBattlerTarget]]))
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
// can't swap if two pokemon don't have an item
// or if either of them is an enigma berry or a mail
@@ -9864,7 +9420,7 @@ static void atkD2_tryswapitems(void) // trick
|| IS_ITEM_MAIL(gBattleMons[gBattlerAttacker].item)
|| IS_ITEM_MAIL(gBattleMons[gBattlerTarget].item))
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
// check if ability prevents swapping
else if (gBattleMons[gBattlerTarget].ability == ABILITY_STICKY_HOLD)
@@ -9925,7 +9481,7 @@ static void atkD3_trycopyability(void) // role play
}
else
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
@@ -9942,7 +9498,7 @@ static void atkD4_trywish(void)
}
else
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
}
break;
case 1: // heal effect
@@ -9954,7 +9510,7 @@ static void atkD4_trywish(void)
gBattleMoveDamage *= -1;
if (gBattleMons[gBattlerTarget].hp == gBattleMons[gBattlerTarget].maxHP)
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
else
gBattlescriptCurrInstr += 6;
@@ -9966,7 +9522,7 @@ static void atkD5_trysetroots(void) // ingrain
{
if (gStatuses3[gBattlerAttacker] & STATUS3_ROOTED)
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
@@ -9993,7 +9549,7 @@ static void atkD7_setyawn(void)
if (gStatuses3[gBattlerTarget] & STATUS3_YAWN
|| gBattleMons[gBattlerTarget].status1 & STATUS1_ANY)
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
@@ -10006,7 +9562,7 @@ static void atkD8_setdamagetohealthdifference(void)
{
if (gBattleMons[gBattlerTarget].hp <= gBattleMons[gBattlerAttacker].hp)
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
@@ -10035,7 +9591,7 @@ static void atkDA_tryswapabilities(void) // skill swap
|| gBattleMons[gBattlerTarget].ability == ABILITY_WONDER_GUARD
|| gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
@@ -10051,7 +9607,7 @@ static void atkDB_tryimprision(void)
{
if ((gStatuses3[gBattlerAttacker] & STATUS3_IMPRISONED_OTHERS))
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
@@ -10085,7 +9641,7 @@ static void atkDB_tryimprision(void)
}
}
if (battlerId == gBattlersCount) // In Generation 3 games, Imprison fails if the user doesn't share any moves with any of the foes
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
@@ -10093,7 +9649,7 @@ static void atkDC_trysetgrudge(void)
{
if (gStatuses3[gBattlerAttacker] & STATUS3_GRUDGE)
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
@@ -10168,7 +9724,7 @@ static void atkDE_asistattackselect(void)
}
else
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
@@ -10178,7 +9734,7 @@ static void atkDF_trysetmagiccoat(void)
gSpecialStatuses[gBattlerAttacker].flag20 = 1;
if (gCurrentTurnActionNumber == gBattlersCount - 1) // moves last turn
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
@@ -10192,7 +9748,7 @@ static void atkE0_trysetsnatch(void) // snatch
gSpecialStatuses[gBattlerAttacker].flag20 = 1;
if (gCurrentTurnActionNumber == gBattlersCount - 1) // moves last turn
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
@@ -10219,7 +9775,7 @@ static void atkE1_trygetintimidatetarget(void)
}
if (gBattlerTarget >= gBattlersCount)
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
else
gBattlescriptCurrInstr += 5;
}
@@ -10245,7 +9801,7 @@ static void atkE3_jumpifhasnohp(void)
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
if (gBattleMons[gActiveBattler].hp == 0)
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
else
gBattlescriptCurrInstr += 6;
}
@@ -10413,7 +9969,7 @@ static void atkE8_settypebasedhalvers(void) // water and mud sport
if (worked)
gBattlescriptCurrInstr += 5;
else
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
static void atkE9_setweatherballtype(void)
@@ -10456,25 +10012,22 @@ static void atkEA_tryrecycleitem(void)
}
else
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
static void atkEB_settypetoterrain(void)
{
- if (gBattleMons[gBattlerAttacker].type1 != sTerrainToType[gBattleTerrain]
- && gBattleMons[gBattlerAttacker].type2 != sTerrainToType[gBattleTerrain])
+ if (!IS_BATTLER_OF_TYPE(gBattlerAttacker, sTerrainToType[gBattleTerrain]))
{
- gBattleMons[gBattlerAttacker].type1 = sTerrainToType[gBattleTerrain];
- gBattleMons[gBattlerAttacker].type2 = sTerrainToType[gBattleTerrain];
-
- PREPARE_TYPE_BUFFER(gBattleTextBuff1, sTerrainToType[gBattleTerrain])
+ SET_BATTLER_TYPE(gBattlerAttacker, sTerrainToType[gBattleTerrain]);
+ PREPARE_TYPE_BUFFER(gBattleTextBuff1, sTerrainToType[gBattleTerrain]);
gBattlescriptCurrInstr += 5;
}
else
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
@@ -10496,7 +10049,7 @@ static void atkEC_pursuitrelated(void)
}
else
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
}
@@ -10572,16 +10125,13 @@ static void atkEF_handleballthrow(void)
switch (gLastUsedItem)
{
case ITEM_NET_BALL:
- if (gBattleMons[gBattlerTarget].type1 == TYPE_WATER
- || gBattleMons[gBattlerTarget].type2 == TYPE_WATER
- || gBattleMons[gBattlerTarget].type1 == TYPE_BUG
- || gBattleMons[gBattlerTarget].type2 == TYPE_BUG)
+ if (IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_WATER) || IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_BUG))
ballMultiplier = 30;
else
ballMultiplier = 10;
break;
case ITEM_DIVE_BALL:
- if (sav1_map_get_light_level() == 5)
+ if (Overworld_GetMapTypeOfSaveblockLocation() == 5)
ballMultiplier = 35;
else
ballMultiplier = 10;
@@ -10722,7 +10272,7 @@ static void atkF1_trysetcaughtmondexflags(void)
if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_CAUGHT))
{
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
else
{
@@ -10914,14 +10464,14 @@ static void atkF3_trygivecaughtmonnick(void)
if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active )
{
SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker ^ BIT_SIDE]], MON_DATA_NICKNAME, gBattleStruct->caughtMonNick);
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
}
break;
case 4:
if (CalculatePlayerPartyCount() == 6)
gBattlescriptCurrInstr += 5;
else
- gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
break;
}
}
diff --git a/src/battle_setup.c b/src/battle_setup.c
index 52ed99b21..15af005c4 100644
--- a/src/battle_setup.c
+++ b/src/battle_setup.c
@@ -5,7 +5,6 @@
#include "battle_transition.h"
#include "main.h"
#include "task.h"
-#include "pokemon_3.h"
#include "safari_zone.h"
#include "script.h"
#include "constants/game_stat.h"
@@ -32,6 +31,8 @@
#include "string_util.h"
#include "overworld.h"
#include "field_weather.h"
+#include "gym_leader_rematch.h"
+#include "field_map_obj_helpers.h"
enum
{
@@ -54,19 +55,12 @@ extern bool8 InBattlePyramid(void);
extern bool8 InBattlePike(void);
extern bool32 InTrainerHill(void);
extern bool32 FieldPoisonEffectIsRunning(void);
-extern void overworld_free_bg_tilemaps(void);
extern void prev_quest_postbuffer_cursor_backup_reset(void);
extern void ResetPoisonStepCounter(void);
extern void sub_81BE72C(void);
-extern void FreezeMapObjects(void);
extern void sub_808BCF4(void);
extern void sub_80EECC8(void);
-extern void Overworld_ClearSavedMusic(void);
-extern void CB2_WhiteOut(void);
extern void sub_80AF6F0(void);
-extern void PlayBattleBGM(void);
-extern void sub_81DA57C(void);
-extern u8 Overworld_GetFlashLevel(void);
extern u16 sub_81A9AA8(u8 localId);
extern u16 sub_81D6180(u8 localId);
extern bool8 GetBattlePyramidTrainerFlag(u8 mapObjId);
@@ -251,84 +245,84 @@ static const struct TrainerBattleParameter sTrainerBContinueScriptBattleParams[]
const struct RematchTrainer gRematchTable[REMATCH_TABLE_ENTRIES] =
{
- {{0x0025, 0x0028, 0x0029, 0x002a, 0x002b}, 0x0000, 0x0021},
- {{0x02e1, 0x032c, 0x032d, 0x032e, 0x032f}, 0x0000, 0x0014},
- {{0x002c, 0x002f, 0x0030, 0x0031, 0x0032}, 0x0000, 0x001a},
- {{0x0039, 0x003c, 0x003d, 0x003e, 0x003f}, 0x0000, 0x0018},
- {{0x0040, 0x0043, 0x0044, 0x0045, 0x0046}, 0x0000, 0x0018},
- {{0x02af, 0x02b0, 0x02b1, 0x02b2, 0x02b3}, 0x0000, 0x0027},
- {{0x02ff, 0x033c, 0x033d, 0x033e, 0x033f}, 0x0000, 0x0024},
- {{0x005e, 0x0065, 0x0066, 0x0067, 0x0068}, 0x0000, 0x001a},
- {{0x004e, 0x0054, 0x0055, 0x0056, 0x0057}, 0x0000, 0x001a},
- {{0x006c, 0x006e, 0x006f, 0x0070, 0x0071}, 0x0018, 0x0014},
- {{0x0072, 0x0078, 0x0079, 0x007a, 0x007b}, 0x0000, 0x0013},
- {{0x0090, 0x034c, 0x034d, 0x034e, 0x034f}, 0x0018, 0x0038},
- {{0x007f, 0x0084, 0x0085, 0x0086, 0x0087}, 0x0000, 0x0024},
- {{0x0088, 0x008b, 0x008c, 0x008d, 0x008e}, 0x0000, 0x0013},
- {{0x008f, 0x0093, 0x0094, 0x0095, 0x0096}, 0x0000, 0x001d},
- {{0x009b, 0x00af, 0x00b0, 0x00b1, 0x00b2}, 0x0000, 0x0016},
- {{0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb}, 0x0000, 0x001e},
- {{0x02a0, 0x0338, 0x0339, 0x033a, 0x033b}, 0x0000, 0x002a},
- {{0x00c3, 0x0340, 0x0341, 0x0342, 0x0343}, 0x0000, 0x0026},
- {{0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8}, 0x0000, 0x0021},
- {{0x00ce, 0x00cf, 0x00d0, 0x00d1, 0x00d2}, 0x0000, 0x001d},
- {{0x00d8, 0x00db, 0x00dc, 0x00dd, 0x00de}, 0x0018, 0x000d},
- {{0x02a9, 0x02aa, 0x02ab, 0x02ac, 0x02ad}, 0x0018, 0x0001},
- {{0x00e2, 0x00e4, 0x00e5, 0x00e6, 0x00e7}, 0x0000, 0x0023},
- {{0x00ee, 0x00ef, 0x00f0, 0x00f1, 0x00f2}, 0x0000, 0x0026},
- {{0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd}, 0x0000, 0x0026},
- {{0x00fe, 0x0101, 0x0102, 0x0103, 0x0104}, 0x0000, 0x0024},
- {{0x0118, 0x011a, 0x011b, 0x011c, 0x011d}, 0x0000, 0x001f},
- {{0x0111, 0x0114, 0x0115, 0x0116, 0x0117}, 0x0000, 0x001f},
- {{0x011f, 0x0120, 0x0121, 0x0122, 0x0123}, 0x0000, 0x0020},
- {{0x012e, 0x012f, 0x0130, 0x0131, 0x0132}, 0x0000, 0x0019},
- {{0x0125, 0x0127, 0x0128, 0x0129, 0x012a}, 0x0000, 0x0012},
- {{0x0133, 0x0134, 0x0135, 0x0136, 0x0137}, 0x0000, 0x001e},
- {{0x0139, 0x013a, 0x013b, 0x013c, 0x013d}, 0x0018, 0x000c},
- {{0x013e, 0x0148, 0x0149, 0x014a, 0x014b}, 0x0000, 0x0011},
- {{0x0153, 0x015a, 0x015b, 0x015c, 0x015d}, 0x0000, 0x0015},
- {{0x0178, 0x017b, 0x017c, 0x017d, 0x017e}, 0x0000, 0x002b},
- {{0x0171, 0x0172, 0x0173, 0x0174, 0x0175}, 0x0000, 0x0020},
- {{0x0166, 0x0168, 0x0169, 0x016a, 0x016b}, 0x0000, 0x0019},
- {{0x016c, 0x016d, 0x016e, 0x016f, 0x0170}, 0x0000, 0x0020},
- {{0x0182, 0x0184, 0x0185, 0x0186, 0x0187}, 0x0000, 0x002b},
- {{0x0161, 0x0162, 0x0163, 0x0164, 0x0165}, 0x0000, 0x0019},
- {{0x0179, 0x0334, 0x0335, 0x0336, 0x0337}, 0x0000, 0x0029},
- {{0x0188, 0x0189, 0x018a, 0x018b, 0x018c}, 0x0018, 0x0001},
- {{0x0196, 0x0199, 0x019a, 0x019b, 0x019c}, 0x0000, 0x0023},
- {{0x01a3, 0x01a5, 0x01a6, 0x01a7, 0x01a8}, 0x0000, 0x001c},
- {{0x01ab, 0x01ae, 0x01af, 0x01b0, 0x01b1}, 0x0000, 0x001e},
- {{0x01b2, 0x01b5, 0x01b6, 0x01b7, 0x01b8}, 0x0000, 0x001c},
- {{0x01c1, 0x01d1, 0x01d2, 0x01d3, 0x01d4}, 0x0000, 0x0027},
- {{0x01da, 0x01dd, 0x01de, 0x01df, 0x01e0}, 0x0018, 0x000d},
- {{0x01e1, 0x01e2, 0x01e7, 0x01e8, 0x01e9}, 0x0000, 0x0012},
- {{0x01ec, 0x01f1, 0x01f2, 0x01f3, 0x01f4}, 0x0000, 0x0028},
- {{0x02e4, 0x0330, 0x0331, 0x0332, 0x0333}, 0x0000, 0x0017},
- {{0x0200, 0x0203, 0x0204, 0x0205, 0x0206}, 0x0000, 0x0019},
- {{0x0221, 0x0224, 0x0225, 0x0226, 0x0227}, 0x0000, 0x0020},
- {{0x021a, 0x021d, 0x021e, 0x021f, 0x0220}, 0x0000, 0x0020},
- {{0x0009, 0x0348, 0x0349, 0x034a, 0x034b}, 0x0018, 0x0011},
- {{0x022f, 0x0232, 0x0233, 0x0234, 0x0235}, 0x0000, 0x0022},
- {{0x0228, 0x022b, 0x022c, 0x022d, 0x022e}, 0x0000, 0x0022},
- {{0x025c, 0x025f, 0x0260, 0x0261, 0x0262}, 0x0000, 0x0013},
- {{0x026d, 0x026e, 0x026f, 0x0270, 0x0271}, 0x0018, 0x000b},
- {{0x0273, 0x027c, 0x027d, 0x027e, 0x027f}, 0x0000, 0x001b},
- {{0x0001, 0x0344, 0x0345, 0x0346, 0x0347}, 0x0018, 0x000c},
- {{0x0282, 0x0283, 0x0284, 0x0285, 0x0286}, 0x0018, 0x003e},
- {{0x0291, 0x0292, 0x0293, 0x0294, 0x0294}, 0x0018, 0x002b},
- {{0x0109, 0x0302, 0x0303, 0x0304, 0x0305}, 0x0000, 0x0003},
- {{0x010a, 0x0306, 0x0307, 0x0308, 0x0309}, 0x0000, 0x000b},
- {{0x010b, 0x030a, 0x030b, 0x030c, 0x030d}, 0x0000, 0x0002},
- {{0x010c, 0x030e, 0x030f, 0x0310, 0x0311}, 0x0000, 0x000c},
- {{0x010d, 0x0312, 0x0313, 0x0314, 0x0315}, 0x0000, 0x0000},
- {{0x010e, 0x0316, 0x0317, 0x0318, 0x0319}, 0x0000, 0x0004},
- {{0x010f, 0x031a, 0x031b, 0x031c, 0x031d}, 0x0000, 0x0006},
- {{0x0110, 0x031e, 0x031f, 0x0320, 0x0321}, 0x0000, 0x0007},
- {{0x0105, 0x0105, 0x0105, 0x0105, 0x0105}, 0x0000, 0x0008},
- {{0x0106, 0x0106, 0x0106, 0x0106, 0x0106}, 0x0000, 0x0008},
- {{0x0107, 0x0107, 0x0107, 0x0107, 0x0107}, 0x0000, 0x0008},
- {{0x0108, 0x0108, 0x0108, 0x0108, 0x0108}, 0x0000, 0x0008},
- {{0x014f, 0x014f, 0x014f, 0x014f, 0x014f}, 0x0000, 0x0008},
+ {{TRAINER_ROSE_1, TRAINER_ROSE_2, TRAINER_ROSE_3, TRAINER_ROSE_4, TRAINER_ROSE_5}, 0x0, 0x21},
+ {{TRAINER_ANDRES_1, TRAINER_ANDRES_2, TRAINER_ANDRES_3, TRAINER_ANDRES_4, TRAINER_ANDRES_5}, 0x0, 0x14},
+ {{TRAINER_DUSTY_1, TRAINER_DUSTY_2, TRAINER_DUSTY_3, TRAINER_DUSTY_4, TRAINER_DUSTY_5}, 0x0, 0x1a},
+ {{TRAINER_LOLA_1, TRAINER_LOLA_2, TRAINER_LOLA_3, TRAINER_LOLA_4, TRAINER_LOLA_5}, 0x0, 0x18},
+ {{TRAINER_RICKY_1, TRAINER_RICKY_2, TRAINER_RICKY_3, TRAINER_RICKY_4, TRAINER_RICKY_5}, 0x0, 0x18},
+ {{TRAINER_LILA_AND_ROY_1, TRAINER_LILA_AND_ROY_2, TRAINER_LILA_AND_ROY_3, TRAINER_LILA_AND_ROY_4, TRAINER_LILA_AND_ROY_5}, 0x0, 0x27},
+ {{TRAINER_CRISTIN_1, TRAINER_CRISTIN_2, TRAINER_CRISTIN_3, TRAINER_CRISTIN_4, TRAINER_CRISTIN_5}, 0x0, 0x24},
+ {{TRAINER_BROOKE_1, TRAINER_BROOKE_2, TRAINER_BROOKE_3, TRAINER_BROOKE_4, TRAINER_BROOKE_5}, 0x0, 0x1a},
+ {{TRAINER_WILTON_1, TRAINER_WILTON_2, TRAINER_WILTON_3, TRAINER_WILTON_4, TRAINER_WILTON_5}, 0x0, 0x1a},
+ {{TRAINER_VALERIE_1, TRAINER_VALERIE_2, TRAINER_VALERIE_3, TRAINER_VALERIE_4, TRAINER_VALERIE_5}, 0x18, 0x14},
+ {{TRAINER_CINDY_1, TRAINER_CINDY_3, TRAINER_CINDY_4, TRAINER_CINDY_5, TRAINER_CINDY_6}, 0x0, 0x13},
+ {{TRAINER_THALIA_1, TRAINER_THALIA_2, TRAINER_THALIA_3, TRAINER_THALIA_4, TRAINER_THALIA_5}, 0x18, 0x38},
+ {{TRAINER_JESSICA_1, TRAINER_JESSICA_2, TRAINER_JESSICA_3, TRAINER_JESSICA_4, TRAINER_JESSICA_5}, 0x0, 0x24},
+ {{TRAINER_WINSTON_1, TRAINER_WINSTON_2, TRAINER_WINSTON_3, TRAINER_WINSTON_4, TRAINER_WINSTON_5}, 0x0, 0x13},
+ {{TRAINER_STEVE_1, TRAINER_STEVE_2, TRAINER_STEVE_3, TRAINER_STEVE_4, TRAINER_STEVE_5}, 0x0, 0x1d},
+ {{TRAINER_TONY_1, TRAINER_TONY_2, TRAINER_TONY_3, TRAINER_TONY_4, TRAINER_TONY_5}, 0x0, 0x16},
+ {{TRAINER_NOB_1, TRAINER_NOB_2, TRAINER_NOB_3, TRAINER_NOB_4, TRAINER_NOB_5}, 0x0, 0x1e},
+ {{TRAINER_KOJI_1, TRAINER_KOJI_2, TRAINER_KOJI_3, TRAINER_KOJI_4, TRAINER_KOJI_5}, 0x0, 0x2a},
+ {{TRAINER_FERNANDO_1, TRAINER_FERNANDO_2, TRAINER_FERNANDO_3, TRAINER_FERNANDO_4, TRAINER_FERNANDO_5}, 0x0, 0x26},
+ {{TRAINER_DALTON_1, TRAINER_DALTON_2, TRAINER_DALTON_3, TRAINER_DALTON_4, TRAINER_DALTON_5}, 0x0, 0x21},
+ {{TRAINER_BERNIE_1, TRAINER_BERNIE_2, TRAINER_BERNIE_3, TRAINER_BERNIE_4, TRAINER_BERNIE_5}, 0x0, 0x1d},
+ {{TRAINER_ETHAN_1, TRAINER_ETHAN_2, TRAINER_ETHAN_3, TRAINER_ETHAN_4, TRAINER_ETHAN_5}, 0x18, 0xd},
+ {{TRAINER_JOHN_AND_JAY_1, TRAINER_JOHN_AND_JAY_2, TRAINER_JOHN_AND_JAY_3, TRAINER_JOHN_AND_JAY_4, TRAINER_JOHN_AND_JAY_5}, 0x18, 0x1},
+ {{TRAINER_JEFFREY_1, TRAINER_JEFFREY_2, TRAINER_JEFFREY_3, TRAINER_JEFFREY_4, TRAINER_JEFFREY_5}, 0x0, 0x23},
+ {{TRAINER_CAMERON_1, TRAINER_CAMERON_2, TRAINER_CAMERON_3, TRAINER_CAMERON_4, TRAINER_CAMERON_5}, 0x0, 0x26},
+ {{TRAINER_JACKI_1, TRAINER_JACKI_2, TRAINER_JACKI_3, TRAINER_JACKI_4, TRAINER_JACKI_5}, 0x0, 0x26},
+ {{TRAINER_WALTER_1, TRAINER_WALTER_2, TRAINER_WALTER_3, TRAINER_WALTER_4, TRAINER_WALTER_5}, 0x0, 0x24},
+ {{TRAINER_KAREN_1, TRAINER_KAREN_2, TRAINER_KAREN_3, TRAINER_KAREN_4, TRAINER_KAREN_5}, 0x0, 0x1f},
+ {{TRAINER_JERRY_1, TRAINER_JERRY_2, TRAINER_JERRY_3, TRAINER_JERRY_4, TRAINER_JERRY_5}, 0x0, 0x1f},
+ {{TRAINER_ANNA_AND_MEG_1, TRAINER_ANNA_AND_MEG_2, TRAINER_ANNA_AND_MEG_3, TRAINER_ANNA_AND_MEG_4, TRAINER_ANNA_AND_MEG_5}, 0x0, 0x20},
+ {{TRAINER_ISABEL_1, TRAINER_ISABEL_2, TRAINER_ISABEL_3, TRAINER_ISABEL_4, TRAINER_ISABEL_5}, 0x0, 0x19},
+ {{TRAINER_MIGUEL_1, TRAINER_MIGUEL_2, TRAINER_MIGUEL_3, TRAINER_MIGUEL_4, TRAINER_MIGUEL_5}, 0x0, 0x12},
+ {{TRAINER_TIMOTHY_1, TRAINER_TIMOTHY_2, TRAINER_TIMOTHY_3, TRAINER_TIMOTHY_4, TRAINER_TIMOTHY_5}, 0x0, 0x1e},
+ {{TRAINER_SHELBY_1, TRAINER_SHELBY_2, TRAINER_SHELBY_3, TRAINER_SHELBY_4, TRAINER_SHELBY_5}, 0x18, 0xc},
+ {{TRAINER_CALVIN_1, TRAINER_CALVIN_2, TRAINER_CALVIN_3, TRAINER_CALVIN_4, TRAINER_CALVIN_5}, 0x0, 0x11},
+ {{TRAINER_ELLIOT_1, TRAINER_ELLIOT_2, TRAINER_ELLIOT_3, TRAINER_ELLIOT_4, TRAINER_ELLIOT_5}, 0x0, 0x15},
+ {{TRAINER_ISAIAH_1, TRAINER_ISAIAH_2, TRAINER_ISAIAH_3, TRAINER_ISAIAH_4, TRAINER_ISAIAH_5}, 0x0, 0x2b},
+ {{TRAINER_MARIA_1, TRAINER_MARIA_2, TRAINER_MARIA_3, TRAINER_MARIA_4, TRAINER_MARIA_5}, 0x0, 0x20},
+ {{TRAINER_ABIGAIL_1, TRAINER_ABIGAIL_2, TRAINER_ABIGAIL_3, TRAINER_ABIGAIL_4, TRAINER_ABIGAIL_5}, 0x0, 0x19},
+ {{TRAINER_DYLAN_1, TRAINER_DYLAN_2, TRAINER_DYLAN_3, TRAINER_DYLAN_4, TRAINER_DYLAN_5}, 0x0, 0x20},
+ {{TRAINER_KATELYN_1, TRAINER_KATELYN_2, TRAINER_KATELYN_3, TRAINER_KATELYN_4, TRAINER_KATELYN_5}, 0x0, 0x2b},
+ {{TRAINER_BENJAMIN_1, TRAINER_BENJAMIN_2, TRAINER_BENJAMIN_3, TRAINER_BENJAMIN_4, TRAINER_BENJAMIN_5}, 0x0, 0x19},
+ {{TRAINER_PABLO_1, TRAINER_PABLO_2, TRAINER_PABLO_3, TRAINER_PABLO_4, TRAINER_PABLO_5}, 0x0, 0x29},
+ {{TRAINER_NICOLAS_1, TRAINER_NICOLAS_2, TRAINER_NICOLAS_3, TRAINER_NICOLAS_4, TRAINER_NICOLAS_5}, 0x18, 0x1},
+ {{TRAINER_ROBERT_1, TRAINER_ROBERT_2, TRAINER_ROBERT_3, TRAINER_ROBERT_4, TRAINER_ROBERT_5}, 0x0, 0x23},
+ {{TRAINER_LAO_1, TRAINER_LAO_2, TRAINER_LAO_3, TRAINER_LAO_4, TRAINER_LAO_5}, 0x0, 0x1c},
+ {{TRAINER_CYNDY_1, TRAINER_CYNDY_2, TRAINER_CYNDY_3, TRAINER_CYNDY_4, TRAINER_CYNDY_5}, 0x0, 0x1e},
+ {{TRAINER_MADELINE_1, TRAINER_MADELINE_2, TRAINER_MADELINE_3, TRAINER_MADELINE_4, TRAINER_MADELINE_5}, 0x0, 0x1c},
+ {{TRAINER_JENNY_1, TRAINER_JENNY_2, TRAINER_JENNY_3, TRAINER_JENNY_4, TRAINER_JENNY_5}, 0x0, 0x27},
+ {{TRAINER_DIANA_1, TRAINER_DIANA_2, TRAINER_DIANA_3, TRAINER_DIANA_4, TRAINER_DIANA_5}, 0x18, 0xd},
+ {{TRAINER_AMY_AND_LIV_1, TRAINER_AMY_AND_LIV_2, TRAINER_AMY_AND_LIV_4, TRAINER_AMY_AND_LIV_5, TRAINER_AMY_AND_LIV_6}, 0x0, 0x12},
+ {{TRAINER_ERNEST_1, TRAINER_ERNEST_2, TRAINER_ERNEST_3, TRAINER_ERNEST_4, TRAINER_ERNEST_5}, 0x0, 0x28},
+ {{TRAINER_CORY_1, TRAINER_CORY_2, TRAINER_CORY_3, TRAINER_CORY_4, TRAINER_CORY_5}, 0x0, 0x17},
+ {{TRAINER_EDWIN_1, TRAINER_EDWIN_2, TRAINER_EDWIN_3, TRAINER_EDWIN_4, TRAINER_EDWIN_5}, 0x0, 0x19},
+ {{TRAINER_LYDIA_1, TRAINER_LYDIA_2, TRAINER_LYDIA_3, TRAINER_LYDIA_4, TRAINER_LYDIA_5}, 0x0, 0x20},
+ {{TRAINER_ISAAC_1, TRAINER_ISAAC_2, TRAINER_ISAAC_3, TRAINER_ISAAC_4, TRAINER_ISAAC_5}, 0x0, 0x20},
+ {{TRAINER_GABRIELLE_1, TRAINER_GABRIELLE_2, TRAINER_GABRIELLE_3, TRAINER_GABRIELLE_4, TRAINER_GABRIELLE_5}, 0x18, 0x11},
+ {{TRAINER_CATHERINE_1, TRAINER_CATHERINE_2, TRAINER_CATHERINE_3, TRAINER_CATHERINE_4, TRAINER_CATHERINE_5}, 0x0, 0x22},
+ {{TRAINER_JACKSON_1, TRAINER_JACKSON_2, TRAINER_JACKSON_3, TRAINER_JACKSON_4, TRAINER_JACKSON_5}, 0x0, 0x22},
+ {{TRAINER_HALEY_1, TRAINER_HALEY_2, TRAINER_HALEY_3, TRAINER_HALEY_4, TRAINER_HALEY_5}, 0x0, 0x13},
+ {{TRAINER_JAMES_1, TRAINER_JAMES_2, TRAINER_JAMES_3, TRAINER_JAMES_4, TRAINER_JAMES_5}, 0x18, 0xb},
+ {{TRAINER_TRENT_1, TRAINER_TRENT_2, TRAINER_TRENT_3, TRAINER_TRENT_4, TRAINER_TRENT_5}, 0x0, 0x1b},
+ {{TRAINER_SAWYER_1, TRAINER_SAWYER_2, TRAINER_SAWYER_3, TRAINER_SAWYER_4, TRAINER_SAWYER_5}, 0x18, 0xc},
+ {{TRAINER_KIRA_AND_DAN_1, TRAINER_KIRA_AND_DAN_2, TRAINER_KIRA_AND_DAN_3, TRAINER_KIRA_AND_DAN_4, TRAINER_KIRA_AND_DAN_5}, 0x18, 0x3e},
+ {{TRAINER_WALLY_3, 0x292, 0x293, 0x294, 0x294}, 0x18, 0x2b},
+ {{TRAINER_ROXANNE_1, TRAINER_ROXANNE_2, TRAINER_ROXANNE_3, TRAINER_ROXANNE_4, TRAINER_ROXANNE_5}, 0x0, 0x3},
+ {{TRAINER_BRAWLY_1, TRAINER_BRAWLY_2, TRAINER_BRAWLY_3, TRAINER_BRAWLY_4, TRAINER_BRAWLY_5}, 0x0, 0xb},
+ {{TRAINER_WATTSON_1, TRAINER_WATTSON_2, TRAINER_WATTSON_3, TRAINER_WATTSON_4, TRAINER_WATTSON_5}, 0x0, 0x2},
+ {{TRAINER_FLANNERY_1, TRAINER_FLANNERY_2, TRAINER_FLANNERY_3, TRAINER_FLANNERY_4, TRAINER_FLANNERY_5}, 0x0, 0xc},
+ {{TRAINER_NORMAN_1, TRAINER_NORMAN_2, TRAINER_NORMAN_3, TRAINER_NORMAN_4, TRAINER_NORMAN_5}, 0x0, 0x0},
+ {{TRAINER_WINONA_1, TRAINER_WINONA_2, TRAINER_WINONA_3, TRAINER_WINONA_4, TRAINER_WINONA_5}, 0x0, 0x4},
+ {{TRAINER_TATE_AND_LIZA_1, TRAINER_TATE_AND_LIZA_2, TRAINER_TATE_AND_LIZA_3, TRAINER_TATE_AND_LIZA_4, TRAINER_TATE_AND_LIZA_5}, 0x0, 0x6},
+ {{TRAINER_JUAN_1, TRAINER_JUAN_2, TRAINER_JUAN_3, TRAINER_JUAN_4, TRAINER_JUAN_5}, 0x0, 0x7},
+ {{TRAINER_SIDNEY, TRAINER_SIDNEY, TRAINER_SIDNEY, TRAINER_SIDNEY, TRAINER_SIDNEY}, 0x0, 0x8},
+ {{TRAINER_PHOEBE, TRAINER_PHOEBE, TRAINER_PHOEBE, TRAINER_PHOEBE, TRAINER_PHOEBE}, 0x0, 0x8},
+ {{TRAINER_GLACIA, TRAINER_GLACIA, TRAINER_GLACIA, TRAINER_GLACIA, TRAINER_GLACIA}, 0x0, 0x8},
+ {{TRAINER_DRAKE, TRAINER_DRAKE, TRAINER_DRAKE, TRAINER_DRAKE, TRAINER_DRAKE}, 0x0, 0x8},
+ {{TRAINER_WALLACE, TRAINER_WALLACE, TRAINER_WALLACE, TRAINER_WALLACE, TRAINER_WALLACE}, 0x0, 0x8},
};
static const u16 sBadgeFlags[8] =
@@ -473,7 +467,7 @@ void StartWallyTutorialBattle(void)
{
CreateMaleMon(&gEnemyParty[0], SPECIES_RALTS, 5);
ScriptContext2_Enable();
- gMain.savedCallback = c2_exit_to_overworld_1_continue_scripts_restart_music;
+ gMain.savedCallback = CB2_ReturnToFieldContinueScript;
gBattleTypeFlags = BATTLE_TYPE_WALLY_TUTORIAL;
CreateBattleStartTask(B_TRANSITION_SLICE, 0);
}
@@ -602,7 +596,7 @@ static void CB2_EndWildBattle(void)
}
else
{
- SetMainCallback2(c2_exit_to_overworld_2_switch);
+ SetMainCallback2(CB2_ReturnToField);
gFieldCallback = sub_80AF6F0;
}
}
@@ -615,13 +609,13 @@ static void CB2_EndScriptedWildBattle(void)
if (IsPlayerDefeated(gBattleOutcome) == TRUE)
{
if (InBattlePyramid())
- SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+ SetMainCallback2(CB2_ReturnToFieldContinueScript);
else
SetMainCallback2(CB2_WhiteOut);
}
else
{
- SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+ SetMainCallback2(CB2_ReturnToFieldContinueScript);
}
}
@@ -938,19 +932,19 @@ static void CB2_StartFirstBattle(void)
static void CB2_EndFirstBattle(void)
{
Overworld_ClearSavedMusic();
- SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+ SetMainCallback2(CB2_ReturnToFieldContinueScript);
}
static void sub_80B1218(void)
{
if (GetGameStat(GAME_STAT_WILD_BATTLES) % 60 == 0)
- sub_81DA57C();
+ UpdateGymLeaderRematch();
}
static void sub_80B1234(void)
{
if (GetGameStat(GAME_STAT_TRAINER_BATTLES) % 20 == 0)
- sub_81DA57C();
+ UpdateGymLeaderRematch();
}
// why not just use the macros? maybe its because they didnt want to uncast const every time?
@@ -1314,18 +1308,18 @@ static void CB2_EndTrainerBattle(void)
{
if (gTrainerBattleOpponent_A == SECRET_BASE_OPPONENT)
{
- SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+ SetMainCallback2(CB2_ReturnToFieldContinueScript);
}
else if (IsPlayerDefeated(gBattleOutcome) == TRUE)
{
if (InBattlePyramid() || sub_81D5C18())
- SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+ SetMainCallback2(CB2_ReturnToFieldContinueScript);
else
SetMainCallback2(CB2_WhiteOut);
}
else
{
- SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+ SetMainCallback2(CB2_ReturnToFieldContinueScript);
if (!InBattlePyramid() && !sub_81D5C18())
{
RegisterTrainerInMatchCall();
@@ -1338,7 +1332,7 @@ static void CB2_EndRematchBattle(void)
{
if (gTrainerBattleOpponent_A == SECRET_BASE_OPPONENT)
{
- SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+ SetMainCallback2(CB2_ReturnToFieldContinueScript);
}
else if (IsPlayerDefeated(gBattleOutcome) == TRUE)
{
@@ -1346,7 +1340,7 @@ static void CB2_EndRematchBattle(void)
}
else
{
- SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+ SetMainCallback2(CB2_ReturnToFieldContinueScript);
RegisterTrainerInMatchCall();
SetBattledTrainersFlags();
HandleRematchVarsOnBattleEnd();
diff --git a/src/battle_transition.c b/src/battle_transition.c
index e0d208f23..8b9b50140 100644
--- a/src/battle_transition.c
+++ b/src/battle_transition.c
@@ -919,7 +919,7 @@ static void CB2_TestBattleTransition(void)
if (IsBattleTransitionDone())
{
sTestingTransitionState = 0;
- SetMainCallback2(c2_exit_to_overworld_2_switch);
+ SetMainCallback2(CB2_ReturnToField);
}
break;
}
diff --git a/src/battle_tv.c b/src/battle_tv.c
new file mode 100644
index 000000000..e5d97be30
--- /dev/null
+++ b/src/battle_tv.c
@@ -0,0 +1,1576 @@
+#include "global.h"
+#include "pokemon.h"
+#include "battle.h"
+#include "battle_tv.h"
+#include "constants/battle_string_ids.h"
+#include "constants/battle_anim.h"
+#include "constants/moves.h"
+#include "constants/species.h"
+#include "battle_message.h"
+#include "tv.h"
+
+extern struct StringInfoBattle *gStringInfo;
+
+// this file's functions
+static bool8 sub_817E0B8(u16 stringId);
+static void AddMovePoints(u8 caseId, u16 arg1, u8 arg2, u8 arg3);
+static void TrySetBattleSeminarShow(void);
+static void AddPointsOnFainting(bool8 targetFainted);
+static void AddPointsBasedOnWeather(u16 weatherFlags, u16 moveId, u8 moveSlot);
+static bool8 ShouldCalculateDamage(u16 moveId, s32 *dmg, u16 *powerOverride);
+
+// const rom data
+static const u16 sVariableDmgMoves[] =
+{
+ MOVE_COUNTER, MOVE_FISSURE, MOVE_BIDE, MOVE_MIRROR_COAT,
+ MOVE_HORN_DRILL, MOVE_FLAIL, MOVE_REVERSAL, MOVE_HIDDEN_POWER,
+ MOVE_SHEER_COLD, MOVE_FOCUS_PUNCH, MOVE_ERUPTION,
+ MOVE_WATER_SPOUT, MOVE_DREAM_EATER, MOVE_WEATHER_BALL,
+ MOVE_SNORE, MOVE_PAIN_SPLIT, MOVE_GUILLOTINE,
+ MOVE_FRUSTRATION, MOVE_RETURN, MOVE_ENDEAVOR,
+ MOVE_PRESENT, MOVE_REVENGE, 0xFFFF,
+ // those are handled by the function itself
+ MOVE_MAGNITUDE, MOVE_PSYWAVE, 0xFFFF
+};
+
+static const u16 sUnknown_0860A4E0[] =
+{
+ 0x0001, 0x0001, 0x0001, 0x0004, 0x0001, 0x0001, 0x0001, 0x0000, 0x0005, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
+ 0x0001, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0005, 0x0005, 0x0004, 0x0005, 0x0001, 0x0003, 0x0001,
+ 0x0003, 0x0005, 0x0001, 0x0007, 0x0001, 0x0007, 0x0007, 0x0001, 0x0005, 0x0002, 0x0004, 0x0001, 0x0001, 0x0001, 0x0005, 0x0001,
+ 0x0002, 0x0004, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
+ 0x0001, 0x0007, 0x0004, 0x0004, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0004, 0x0001, 0x0001, 0x0001, 0x0004,
+ 0x0005, 0x0002, 0x0004, 0x0001, 0x0004, 0x0001, 0x0007, 0x0002, 0x0001, 0x0005, 0x0007, 0x0003, 0x0003, 0x0004, 0x0003, 0x0003,
+ 0x0003, 0x0003, 0x0003, 0x0002, 0x0004, 0x0001, 0x0005, 0x0001, 0x0001, 0x0004, 0x0005, 0x0003, 0x0001, 0x0002, 0x0001, 0x0005,
+ 0x0004, 0x0003, 0x0006, 0x0004, 0x0003, 0x0003, 0x0003, 0x0002, 0x0004, 0x0001, 0x0001, 0x0001, 0x0005, 0x0001, 0x0001, 0x0007,
+ 0x0002, 0x0002, 0x0001, 0x0001, 0x0004, 0x0004, 0x0004, 0x0001, 0x0004, 0x0004, 0x0001, 0x0001, 0x0001, 0x0001, 0x0007, 0x0007,
+ 0x0006, 0x0003, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, 0x0003, 0x0001, 0x0001, 0x0004, 0x0004,
+ 0x0003, 0x0003, 0x0003, 0x0001, 0x0004, 0x0007, 0x0007, 0x0005, 0x0007, 0x0001, 0x0007, 0x0001, 0x0005, 0x0000, 0x0004, 0x0004,
+ 0x0004, 0x0004, 0x0004, 0x0002, 0x0002, 0x0006, 0x0003, 0x0006, 0x0004, 0x0004, 0x0002, 0x0005, 0x0002, 0x0001, 0x0001, 0x0006,
+ 0x0006, 0x0006, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, 0x0006, 0x0001, 0x0004, 0x0001, 0x0001, 0x0003, 0x0001, 0x0001, 0x0001,
+ 0x0001, 0x0001, 0x0004, 0x0001, 0x0001, 0x0003
+};
+static const u16 sUnknown_0860A68C[] =
+{
+ 0x0004, 0xfffd, 0xfffa
+};
+static const u16 sUnknown_0860A692[] =
+{
+ 0x0004, 0x0004, 0x0006, 0x0006, 0x0007, 0x0006, 0x0002
+};
+static const u16 sUnknown_0860A6A0[] =
+{
+ 0x0091, 0x0003, 0x00fa, 0x0003, 0x00be, 0x0003, 0x0080, 0x0003, 0x006e, 0x0003, 0x0098, 0x0003, 0x0143, 0x0003, 0x0123, 0x0003,
+ 0x007f, 0x0003, 0x014a, 0x0003, 0x0039, 0x0003, 0x0134, 0x0003, 0x0038, 0x0003, 0x003d, 0x0003, 0x015a, 0x0000, 0x0037, 0x0003,
+ 0x0160, 0x0003, 0x0137, 0x0003, 0x0057, 0x0003, 0x004c, 0xfffc, 0x013b, 0xfffc, 0x00ac, 0xfffc, 0x0035, 0xfffc, 0x00dd, 0xfffc,
+ 0x007e, 0xfffc, 0x0101, 0xfffc, 0x0034, 0xfffc, 0x0133, 0xfffc, 0x012b, 0xfffc, 0x011c, 0xfffc, 0x0053, 0xfffc, 0x0007, 0xfffc,
+ 0x004c, 0xfffc, 0xffff, 0x0000
+};
+static const u16 sUnknown_0860A728[] =
+{
+ 0x013b, 0x0003, 0x00ac, 0x0003, 0x0035, 0x0003, 0x00dd, 0x0003, 0x007e, 0x0003, 0x0101, 0x0003, 0x0034, 0x0003, 0x0133, 0x0003,
+ 0x012b, 0x0003, 0x011c, 0x0003, 0x0053, 0x0003, 0x0007, 0x0003, 0x004c, 0x0005, 0x00eb, 0x0003, 0x00ea, 0x0003, 0x00ec, 0x0003,
+ 0x0137, 0x0003, 0xffff, 0x0000
+};
+static const u16 sUnknown_0860A770[] =
+{
+ 0x0137, 0x0003, 0x004c, 0xfffd, 0xffff, 0x0000
+};
+static const u16 sUnknown_0860A77C[] =
+{
+ 0x0137, 0x0003, 0x004c, 0xfffd, 0xffff, 0x0000
+};
+static const u16 sUnknown_0860A788[] =
+{
+ 0x0055, 0x0003, 0x0009, 0x0003, 0x00d1, 0x0003, 0x0054, 0x0003, 0x00c0, 0x0003, 0x015f, 0x0003, 0x0056, 0x0000, 0x0057, 0x0003,
+ 0x0158, 0x0003, 0xffff, 0x0000
+};
+static const u16 sUnknown_0860A7B0[] =
+{
+ 0x0005, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003
+};
+static const u16 sUnknown_0860A7BE[] =
+{
+ 0x0005, 0x0005, 0x0005, 0x0005, 0x0005
+};
+static const u16 sUnknown_0860A7C8[] =
+{
+ 0x0004
+};
+static const u16 sUnknown_0860A7CA[] =
+{
+ 0x0005
+};
+static const u16 sUnknown_0860A7CC[] =
+{
+ 0x0005
+};
+static const u16 sUnknown_0860A7CE[] =
+{
+ 0x0003
+};
+static const u16 sUnknown_0860A7D0[] =
+{
+ 0x0003
+};
+static const u16 sUnknown_0860A7D2[] =
+{
+ 0x0004
+};
+static const u16 sUnknown_0860A7D4[] =
+{
+ 0x0003
+};
+static const u16 sUnknown_0860A7D6[] =
+{
+ 0x0006
+};
+static const u16 sUnknown_0860A7D8[] =
+{
+ 0x0006
+};
+static const u16 sUnknown_0860A7DA[] =
+{
+ 0x0006
+};
+static const u16 sUnknown_0860A7DC[] =
+{
+ 0x0004
+};
+static const u16 sUnknown_0860A7DE[] =
+{
+ 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002
+};
+static const u16 sUnknown_0860A7EC[] =
+{
+ 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004
+};
+static const u16 sUnknown_0860A7FA[] =
+{
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
+};
+static const u16 sUnknown_0860A808[] =
+{
+ 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002
+};
+static const u16 sUnknown_0860A816[] =
+{
+ 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004
+};
+static const u16 sUnknown_0860A824[] =
+{
+ 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xfffe
+};
+
+static const u16 *const sPointsArray[] =
+{
+ sUnknown_0860A4E0,
+ sUnknown_0860A68C,
+ sUnknown_0860A692,
+ sUnknown_0860A6A0,
+ sUnknown_0860A728,
+ sUnknown_0860A770,
+ sUnknown_0860A77C,
+ sUnknown_0860A788,
+ sUnknown_0860A7B0,
+ sUnknown_0860A7BE,
+ sUnknown_0860A7C8,
+ sUnknown_0860A7CA,
+ sUnknown_0860A7CC,
+ sUnknown_0860A7CE,
+ sUnknown_0860A7D0,
+ sUnknown_0860A7D2,
+ sUnknown_0860A7D4,
+ sUnknown_0860A7D6,
+ sUnknown_0860A7D8,
+ sUnknown_0860A7DA,
+ sUnknown_0860A7DA,
+ sUnknown_0860A7DC,
+ sUnknown_0860A7DE,
+ sUnknown_0860A7EC,
+ sUnknown_0860A7FA,
+ sUnknown_0860A808,
+ sUnknown_0860A816,
+ sUnknown_0860A824
+};
+
+static const u16 sUnknown_0860A8A4[] =
+{
+ STRINGID_PKMNPERISHCOUNTFELL, STRINGID_PKMNWISHCAMETRUE, STRINGID_PKMNLOSTPPGRUDGE,
+ STRINGID_PKMNTOOKFOE, STRINGID_PKMNABSORBEDNUTRIENTS, STRINGID_PKMNANCHOREDITSELF,
+ STRINGID_PKMNAFFLICTEDBYCURSE, STRINGID_PKMNSAPPEDBYLEECHSEED, STRINGID_PKMNLOCKEDINNIGHTMARE,
+ STRINGID_PKMNHURTBY, STRINGID_PKMNHURTBYBURN, STRINGID_PKMNHURTBYPOISON,
+ STRINGID_PKMNHURTBYSPIKES, STRINGID_ATTACKERFAINTED, STRINGID_TARGETFAINTED,
+ STRINGID_PKMNHITWITHRECOIL, STRINGID_PKMNCRASHED, 0xFFFF
+};
+
+// code
+void BattleTv_SetDataBasedOnString(u16 stringId)
+{
+ struct BattleTv *tvPtr;
+ u32 atkSide, defSide, effSide, scriptingSide;
+ struct Pokemon *atkMon, *defMon;
+ u8 moveSlot;
+ u32 atkFlank, defFlank, effFlank;
+ u8 *perishCount;
+ u16 *statStringId, *finishedMoveId;
+
+ if (!(gBattleTypeFlags & BATTLE_TYPE_LINK) && stringId != STRINGID_ITDOESNTAFFECT && stringId != STRINGID_NOTVERYEFFECTIVE)
+ return;
+
+ tvPtr = &gBattleStruct->tv;
+
+ atkSide = GetBattlerSide(gBattlerAttacker);
+ defSide = GetBattlerSide(gBattlerTarget);
+ effSide = GetBattlerSide(gEffectBattler);
+ scriptingSide = GetBattlerSide(gStringInfo->scrActive);
+
+ if (atkSide == B_SIDE_PLAYER)
+ atkMon = &gPlayerParty[gBattlerPartyIndexes[gBattlerAttacker]];
+ else
+ atkMon = &gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker]];
+
+ if (defSide == B_SIDE_PLAYER)
+ defMon = &gPlayerParty[gBattlerPartyIndexes[gBattlerTarget]];
+ else
+ defMon = &gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]];
+
+ moveSlot = GetBattlerMoveSlotId(gBattlerAttacker, gStringInfo->currentMove);
+
+ if (moveSlot >= 4 && sub_817E0B8(stringId) && stringId > BATTLESTRINGS_ID_ADDER)
+ {
+ tvPtr->side[atkSide].faintCause = 15;
+ return;
+ }
+
+ perishCount = (u8 *)(gBattleTextBuff1 + 4);
+ statStringId = (u16 *)(gBattleTextBuff2 + 2);
+ finishedMoveId = (u16 *)(gBattleTextBuff1 + 2);
+
+ atkFlank = GetBattlerPosition(gBattlerAttacker) / 2;
+ defFlank = GetBattlerPosition(gBattlerTarget) / 2;
+ effFlank = GetBattlerPosition(gEffectBattler) / 2;
+
+ switch (stringId)
+ {
+ case STRINGID_ITDOESNTAFFECT:
+ AddMovePoints(1, moveSlot, 2, 0);
+ if (!(gBattleTypeFlags & BATTLE_TYPE_LINK))
+ TrySetBattleSeminarShow();
+ break;
+ case STRINGID_NOTVERYEFFECTIVE:
+ AddMovePoints(1, moveSlot, 1, 0);
+ if (!(gBattleTypeFlags & BATTLE_TYPE_LINK) && GetMonData(defMon, MON_DATA_HP, NULL) != 0)
+ TrySetBattleSeminarShow();
+ break;
+ case STRINGID_SUPEREFFECTIVE:
+ AddMovePoints(1, moveSlot, 0, 0);
+ break;
+ case STRINGID_PKMNFORESAWATTACK:
+ tvPtr->side[atkSide].futureSightMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->side[atkSide].futureSightMoveSlot = moveSlot;
+ break;
+ case STRINGID_PKMNCHOSEXASDESTINY:
+ tvPtr->side[atkSide].doomDesireMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->side[atkSide].doomDesireMoveSlot = moveSlot;
+ break;
+ case STRINGID_FAINTINTHREE:
+ tvPtr->side[atkSide].perishSongMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->side[atkSide].perishSongMoveSlot = moveSlot;
+ tvPtr->side[atkSide].perishSong = 1;
+ break;
+ case STRINGID_PKMNPERISHCOUNTFELL:
+ if (*perishCount == 0)
+ tvPtr->side[atkSide].faintCause = 10;
+ break;
+ case STRINGID_PKMNWISHCAMETRUE:
+ if (tvPtr->side[defSide].wishMonId != 0)
+ {
+ AddMovePoints(2, 3, defSide,
+ (tvPtr->side[defSide].wishMonId - 1) * 4 + tvPtr->side[defSide].wishMoveSlot);
+ }
+ break;
+ case STRINGID_PKMNWANTSGRUDGE:
+ tvPtr->side[atkSide].grudgeMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->side[atkSide].grudgeMoveSlot = moveSlot;
+ break;
+ case STRINGID_PKMNLOSTPPGRUDGE:
+ if (tvPtr->side[defSide].grudgeMonId != 0)
+ {
+ AddMovePoints(2, 4, defSide,
+ (tvPtr->side[defSide].grudgeMonId - 1) * 4 + tvPtr->side[defSide].grudgeMoveSlot);
+ }
+ break;
+ case STRINGID_PKMNTRYINGTOTAKEFOE:
+ tvPtr->side[atkSide].destinyBondMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->side[atkSide].destinyBondMoveSlot = moveSlot;
+ break;
+ case STRINGID_PKMNTOOKFOE:
+ if (tvPtr->side[defSide].destinyBondMonId != 0)
+ tvPtr->side[atkSide].faintCause = 11;
+ break;
+ case STRINGID_PKMNPLANTEDROOTS:
+ tvPtr->pos[atkSide][atkFlank].ingrainMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->pos[atkSide][atkFlank].ingrainMoveSlot = moveSlot;
+ break;
+ case STRINGID_PKMNABSORBEDNUTRIENTS:
+ if (tvPtr->pos[atkSide][atkFlank].ingrainMonId != 0)
+ {
+ AddMovePoints(2, 6, atkSide,
+ (tvPtr->pos[atkSide][atkFlank].ingrainMonId - 1) * 4 + tvPtr->pos[atkSide][atkFlank].ingrainMoveSlot);
+ }
+ break;
+ case STRINGID_PKMNANCHOREDITSELF:
+ if (tvPtr->pos[defSide][defFlank].ingrainMonId != 0)
+ {
+ AddMovePoints(2, 6, defSide,
+ (tvPtr->pos[defSide][defFlank].ingrainMonId - 1) * 4 + tvPtr->pos[defSide][defFlank].ingrainMoveSlot);
+ }
+ break;
+ case STRINGID_PKMNTRANSFORMEDINTO:
+ gBattleStruct->anyMonHasTransformed = TRUE;
+ break;
+ case STRINGID_CRITICALHIT:
+ AddMovePoints(0x12, moveSlot, 0, 0);
+ break;
+ case STRINGID_PKMNSSTATCHANGED:
+ if (gBattleTextBuff1[2] != 0)
+ {
+ if (*statStringId == STRINGID_STATSHARPLY)
+ AddMovePoints(0x17, moveSlot, gBattleTextBuff1[2] - 1, 0);
+ else
+ AddMovePoints(0x16, moveSlot, gBattleTextBuff1[2] - 1, 0);
+ }
+ break;
+ case STRINGID_PKMNSSTATCHANGED2:
+ if (gBattleTextBuff1[2] != 0)
+ {
+ if (gBattlerAttacker == gBattlerTarget)
+ {
+ if (*statStringId == STRINGID_STATSHARPLY)
+ AddMovePoints(0x17, moveSlot, gBattleTextBuff1[2] - 1, 0);
+ else
+ AddMovePoints(0x16, moveSlot, gBattleTextBuff1[2] - 1, 0);
+ }
+ else
+ {
+ AddMovePoints(0x1B, moveSlot, gBattleTextBuff1[2] - 1, 0);
+ }
+ }
+ break;
+ case STRINGID_PKMNSSTATCHANGED3:
+ if (gBattleTextBuff1[2] != 0)
+ AddMovePoints(0x18, moveSlot, gBattleTextBuff1[2] - 1, 0);
+ break;
+ case STRINGID_PKMNSSTATCHANGED4:
+ if (gBattleTextBuff1[2] != 0)
+ {
+ if (*statStringId == STRINGID_STATHARSHLY)
+ AddMovePoints(0x1A, moveSlot, gBattleTextBuff1[2] - 1, 0);
+ else
+ AddMovePoints(0x19, moveSlot, gBattleTextBuff1[2] - 1, 0);
+ }
+ break;
+ case STRINGID_PKMNLAIDCURSE:
+ tvPtr->pos[defSide][defFlank].curseMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->pos[defSide][defFlank].curseMoveSlot = moveSlot;
+ break;
+ case STRINGID_PKMNAFFLICTEDBYCURSE:
+ if (GetMonData(atkMon, MON_DATA_HP, NULL)
+ && tvPtr->pos[atkSide][atkFlank].curseMonId != 0)
+ {
+ AddMovePoints(8, 0, tvPtr->pos[atkSide][atkFlank].curseMonId - 1, tvPtr->pos[atkSide][atkFlank].curseMoveSlot);
+ tvPtr->side[atkSide].faintCause = 1;
+ tvPtr->side[atkSide].faintCauseMonId = atkFlank;
+ }
+ break;
+ case STRINGID_PKMNSEEDED:
+ tvPtr->pos[defSide][defFlank].leechSeedMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->pos[defSide][defFlank].leechSeedMoveSlot = moveSlot;
+ break;
+ case STRINGID_PKMNSAPPEDBYLEECHSEED:
+ if (tvPtr->pos[atkSide][atkFlank].leechSeedMonId != 0)
+ {
+ AddMovePoints(8, 1, tvPtr->pos[atkSide][atkFlank].leechSeedMonId - 1, tvPtr->pos[atkSide][atkFlank].leechSeedMoveSlot);
+ tvPtr->side[atkSide].faintCause = 2;
+ tvPtr->side[atkSide].faintCauseMonId = atkFlank;
+ }
+ break;
+ case STRINGID_PKMNFELLINTONIGHTMARE:
+ tvPtr->pos[defSide][defFlank].nightmareMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->pos[defSide][defFlank].nightmareMoveSlot = moveSlot;
+ break;
+ case STRINGID_PKMNLOCKEDINNIGHTMARE:
+ if (GetMonData(atkMon, MON_DATA_HP, NULL) != 0
+ && tvPtr->pos[atkSide][atkFlank].nightmareMonId != 0)
+ {
+ AddMovePoints(8, 5, tvPtr->pos[atkSide][atkFlank].nightmareMonId - 1, tvPtr->pos[atkSide][atkFlank].nightmareMoveSlot);
+ tvPtr->side[atkSide].faintCause = 5;
+ tvPtr->side[atkSide].faintCauseMonId = atkFlank;
+ }
+ break;
+ case STRINGID_PKMNSQUEEZEDBYBIND:
+ case STRINGID_PKMNTRAPPEDINVORTEX:
+ case STRINGID_PKMNWRAPPEDBY:
+ case STRINGID_PKMNCLAMPED:
+ case STRINGID_PKMNTRAPPEDBYSANDTOMB:
+ tvPtr->pos[defSide][defFlank].wrapMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->pos[defSide][defFlank].wrapMoveSlot = moveSlot;
+ break;
+ case STRINGID_PKMNHURTBY:
+ if (GetMonData(atkMon, MON_DATA_HP, NULL) != 0
+ && tvPtr->pos[atkSide][atkFlank].wrapMonId != 0)
+ {
+ AddMovePoints(8, 6, tvPtr->pos[atkSide][atkFlank].wrapMonId - 1, tvPtr->pos[atkSide][atkFlank].wrapMoveSlot);
+ tvPtr->side[atkSide].faintCause = 6;
+ tvPtr->side[atkSide].faintCauseMonId = atkFlank;
+ }
+ break;
+ case STRINGID_PKMNWASBURNED:
+ tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].brnMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].brnMoveSlot = moveSlot;
+ break;
+ case STRINGID_PKMNHURTBYBURN:
+ if (GetMonData(atkMon, MON_DATA_HP, NULL) != 0)
+ {
+ if (tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].brnMonId != 0)
+ AddMovePoints(8, 4, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].brnMonId - 1, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].brnMoveSlot);
+ tvPtr->side[atkSide].faintCause = 4;
+ tvPtr->side[atkSide].faintCauseMonId = gBattlerPartyIndexes[gBattlerAttacker];
+ }
+ break;
+ case STRINGID_PKMNWASPOISONED:
+ tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].psnMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].psnMoveSlot = moveSlot;
+ break;
+ case STRINGID_PKMNBADLYPOISONED:
+ tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].badPsnMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].badPsnMoveSlot = moveSlot;
+ break;
+ case STRINGID_PKMNHURTBYPOISON:
+ if (GetMonData(atkMon, MON_DATA_HP, NULL) != 0)
+ {
+ if (tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].psnMonId != 0)
+ AddMovePoints(8, 2, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].psnMonId - 1, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].psnMoveSlot);
+ if (tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].badPsnMonId != 0)
+ AddMovePoints(8, 3, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].badPsnMonId - 1, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].badPsnMoveSlot);
+ tvPtr->side[atkSide].faintCause = 3;
+ tvPtr->side[atkSide].faintCauseMonId = gBattlerPartyIndexes[gBattlerAttacker];
+ }
+ break;
+ case STRINGID_PKMNFELLINLOVE:
+ tvPtr->pos[defSide][defFlank].attractMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->pos[defSide][defFlank].attractMoveSlot = moveSlot;
+ break;
+ case STRINGID_PKMNIMMOBILIZEDBYLOVE:
+ if (tvPtr->pos[atkSide][atkFlank].attractMonId != 0)
+ AddMovePoints(9, 0, tvPtr->pos[atkSide][atkFlank].attractMonId - 1, tvPtr->pos[atkSide][atkFlank].attractMoveSlot);
+ break;
+ case STRINGID_PKMNWASPARALYZED:
+ tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].prlzMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].prlzMoveSlot = moveSlot;
+ break;
+ case STRINGID_PKMNISPARALYZED:
+ if (tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].prlzMonId != 0)
+ AddMovePoints(9, 2, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].prlzMonId - 1, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].prlzMoveSlot);
+ break;
+ case STRINGID_PKMNFELLASLEEP:
+ tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].slpMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].slpMoveSlot = moveSlot;
+ break;
+ case STRINGID_PKMNFASTASLEEP:
+ if (tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].slpMonId != 0
+ && gStringInfo->currentMove != MOVE_SNORE
+ && gStringInfo->currentMove != MOVE_SLEEP_TALK)
+ AddMovePoints(9, 3, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].slpMonId - 1, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].slpMoveSlot);
+ break;
+ case STRINGID_PKMNWASFROZEN:
+ tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].frzMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->mon[effSide][gBattlerPartyIndexes[gEffectBattler]].frzMoveSlot = moveSlot;
+ break;
+ case STRINGID_PKMNISFROZEN:
+ if (tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].frzMonId != 0)
+ AddMovePoints(9, 4, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].frzMonId - 1, tvPtr->mon[atkSide][gBattlerPartyIndexes[gBattlerAttacker]].frzMoveSlot);
+ break;
+ case STRINGID_PKMNWASCONFUSED:
+ tvPtr->pos[effSide][effFlank].confusionMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->pos[effSide][effFlank].confusionMoveSlot = moveSlot;
+ break;
+ case STRINGID_ITHURTCONFUSION:
+ if (tvPtr->pos[atkSide][atkFlank].confusionMonId != 0)
+ AddMovePoints(9, 1, tvPtr->pos[atkSide][atkFlank].confusionMonId - 1, tvPtr->pos[atkSide][atkFlank].confusionMoveSlot);
+ tvPtr->side[atkSide].faintCause = 12;
+ break;
+ case STRINGID_SPIKESSCATTERED:
+ tvPtr->side[defSide].spikesMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->side[defSide].spikesMoveSlot = moveSlot;
+ break;
+ case STRINGID_PKMNHURTBYSPIKES:
+ if (tvPtr->side[scriptingSide].spikesMonId != 0)
+ {
+ AddMovePoints(10, scriptingSide ^ BIT_SIDE, tvPtr->side[scriptingSide].spikesMonId - 1, tvPtr->side[scriptingSide].spikesMoveSlot);
+ tvPtr->side[scriptingSide].faintCause = 7;
+ }
+ break;
+ case STRINGID_PKMNBLEWAWAYSPIKES:
+ tvPtr->side[atkSide].spikesMonId = 0;
+ tvPtr->side[atkSide].spikesMoveSlot = 0;
+ break;
+ case STRINGID_FIREWEAKENED:
+ tvPtr->pos[atkSide][atkFlank].waterSportMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->pos[atkSide][atkFlank].waterSportMoveSlot = moveSlot;
+ break;
+ case STRINGID_ELECTRICITYWEAKENED:
+ tvPtr->pos[atkSide][atkFlank].mudSportMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->pos[atkSide][atkFlank].mudSportMoveSlot = moveSlot;
+ break;
+ case STRINGID_ATTACKERFAINTED:
+ AddPointsOnFainting(FALSE);
+ case STRINGID_RETURNMON:
+ if (tvPtr->pos[atkSide][atkFlank].waterSportMonId != 0)
+ {
+ tvPtr->pos[atkSide][atkFlank].waterSportMonId = 0;
+ tvPtr->pos[atkSide][atkFlank].waterSportMoveSlot = 0;
+ }
+ if (tvPtr->pos[atkSide][atkFlank].mudSportMonId != 0)
+ {
+ tvPtr->pos[atkSide][atkFlank].mudSportMonId = 0;
+ tvPtr->pos[atkSide][atkFlank].mudSportMoveSlot = 0;
+ }
+ break;
+ case STRINGID_TARGETFAINTED:
+ AddPointsOnFainting(TRUE);
+ if (tvPtr->pos[atkSide][defFlank].waterSportMonId != 0)
+ {
+ tvPtr->pos[atkSide][defFlank].waterSportMonId = 0;
+ tvPtr->pos[atkSide][defFlank].waterSportMoveSlot = 0;
+ }
+ if (tvPtr->pos[atkSide][defFlank].mudSportMonId != 0)
+ {
+ tvPtr->pos[atkSide][defFlank].mudSportMonId = 0;
+ tvPtr->pos[atkSide][defFlank].mudSportMoveSlot = 0;
+ }
+ break;
+ case STRINGID_PKMNRAISEDDEF:
+ case STRINGID_PKMNRAISEDDEFALITTLE:
+ tvPtr->side[atkSide].reflectMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->side[atkSide].reflectMoveSlot = moveSlot;
+ break;
+ case STRINGID_PKMNRAISEDSPDEF:
+ case STRINGID_PKMNRAISEDSPDEFALITTLE:
+ tvPtr->side[atkSide].lightScreenMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->side[atkSide].lightScreenMoveSlot = moveSlot;
+ break;
+ case STRINGID_PKMNSXWOREOFF:
+ if (*finishedMoveId == MOVE_REFLECT)
+ {
+ tvPtr->side[atkSide].reflectMonId = 0;
+ tvPtr->side[atkSide].reflectMoveSlot = 0;
+ }
+ if (*finishedMoveId == MOVE_LIGHT_SCREEN)
+ {
+ tvPtr->side[atkSide].lightScreenMonId = 0;
+ tvPtr->side[atkSide].lightScreenMoveSlot = 0;
+ }
+ if (*finishedMoveId == MOVE_MIST)
+ {
+ tvPtr->side[atkSide].mistMonId = 0;
+ tvPtr->side[atkSide].mistMoveSlot = 0;
+ }
+ break;
+ case STRINGID_PKMNCOVEREDBYVEIL:
+ tvPtr->side[atkSide].safeguardMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->side[atkSide].safeguardMoveSlot = moveSlot;
+ break;
+ case STRINGID_PKMNUSEDSAFEGUARD:
+ if (tvPtr->side[defSide].safeguardMonId != 0)
+ AddMovePoints(15, 0, tvPtr->side[defSide].safeguardMonId - 1, tvPtr->side[defSide].safeguardMoveSlot);
+ break;
+ case STRINGID_PKMNSAFEGUARDEXPIRED:
+ tvPtr->side[atkSide].safeguardMonId = 0;
+ tvPtr->side[atkSide].safeguardMoveSlot = 0;
+ break;
+ case STRINGID_PKMNSHROUDEDINMIST:
+ tvPtr->side[atkSide].mistMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->side[atkSide].mistMoveSlot = moveSlot;
+ break;
+ case STRINGID_PKMNPROTECTEDBYMIST:
+ if (tvPtr->side[defSide].mistMonId != 0)
+ AddMovePoints(16, 0, tvPtr->side[defSide].mistMonId - 1, tvPtr->side[defSide].mistMoveSlot);
+ break;
+ case STRINGID_THEWALLSHATTERED:
+ tvPtr->side[defSide].reflectMonId = 0;
+ tvPtr->side[defSide].reflectMoveSlot = 0;
+ tvPtr->side[defSide].lightScreenMonId = 0;
+ tvPtr->side[defSide].lightScreenMoveSlot = 0;
+ AddMovePoints(17, 0, gBattlerPartyIndexes[gBattlerAttacker], moveSlot);
+ break;
+ case STRINGID_PKMNFLINCHED:
+ if (tvPtr->pos[atkSide][0].attackedByMonId != 0)
+ AddMovePoints(21, 0, tvPtr->pos[atkSide][0].attackedByMonId - 1, tvPtr->pos[atkSide][0].attackedByMoveSlot);
+ if (tvPtr->pos[atkSide][1].attackedByMonId != 0)
+ AddMovePoints(21, 0, tvPtr->pos[atkSide][1].attackedByMonId - 1, tvPtr->pos[atkSide][1].attackedByMoveSlot);
+ break;
+ case STRINGID_PKMNCRASHED:
+ case STRINGID_PKMNHITWITHRECOIL:
+ tvPtr->side[atkSide].faintCause = 14;
+ break;
+ }
+}
+
+static bool8 sub_817E0B8(u16 stringId)
+{
+ s32 i = 0;
+
+ do
+ {
+ if (sUnknown_0860A8A4[i] == stringId)
+ break;
+ i++;
+ } while (sUnknown_0860A8A4[i] != 0xFFFF);
+
+ if (sUnknown_0860A8A4[i] == 0xFFFF)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void BattleTv_SetDataBasedOnMove(u16 move, u16 weatherFlags, struct DisableStruct *disableStructPtr)
+{
+ struct BattleTv *tvPtr;
+ u32 atkSide, defSide;
+ u8 moveSlot;
+
+ if (!(gBattleTypeFlags & BATTLE_TYPE_LINK))
+ return;
+
+ tvPtr = &gBattleStruct->tv;
+
+ atkSide = GetBattlerSide(gBattlerAttacker);
+ defSide = GetBattlerSide(gBattlerTarget);
+ moveSlot = GetBattlerMoveSlotId(gBattlerAttacker, move);
+
+ if (moveSlot >= 4)
+ {
+ tvPtr->side[atkSide].faintCause = 15;
+ return;
+ }
+
+ tvPtr->pos[defSide][GetBattlerPosition(gBattlerAttacker) / 2].attackedByMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->pos[defSide][GetBattlerPosition(gBattlerAttacker) / 2].attackedByMoveSlot = moveSlot;
+ tvPtr->side[atkSide].usedMoveSlot = moveSlot;
+ AddMovePoints(0, moveSlot, gBattleMoves[move].effect, 0);
+ AddPointsBasedOnWeather(weatherFlags, move, moveSlot);
+ if (disableStructPtr->chargeTimer1 != 0)
+ AddMovePoints(7, move, moveSlot, 0);
+
+ if (move == MOVE_WISH)
+ {
+ tvPtr->side[atkSide].wishMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->side[atkSide].wishMoveSlot = moveSlot;
+ }
+ if (move == MOVE_SELF_DESTRUCT || move == MOVE_EXPLOSION)
+ {
+ tvPtr->side[atkSide ^ BIT_SIDE].explosionMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
+ tvPtr->side[atkSide ^ BIT_SIDE].explosionMoveSlot = moveSlot;
+ tvPtr->side[atkSide ^ BIT_SIDE].faintCause = 13;
+ tvPtr->side[atkSide ^ BIT_SIDE].explosion = 1;
+ }
+
+ AddMovePoints(13, gBattleMoves[move].type, gBattleMoves[move].power, 0);
+ AddMovePoints(14, gBattleMoves[move].type, gBattleMoves[move].power, 0);
+ AddMovePoints(11, gBattleMoves[move].type, 0, 0);
+ AddMovePoints(12, gBattleMoves[move].type, 0, 0);
+}
+
+void BattleTv_SetDataBasedOnAnimation(u8 animationId)
+{
+ struct BattleTv *tvPtr;
+ u32 atkSide;
+
+ if (!(gBattleTypeFlags & BATTLE_TYPE_LINK))
+ return;
+
+ tvPtr = &gBattleStruct->tv;
+ atkSide = GetBattlerSide(gBattlerAttacker);
+ switch (animationId)
+ {
+ case B_ANIM_FUTURE_SIGHT_HIT:
+ if (tvPtr->side[atkSide].futureSightMonId != 0)
+ {
+ AddMovePoints(2, 0, atkSide,
+ (tvPtr->side[atkSide].futureSightMonId - 1) * 4 + tvPtr->side[atkSide].futureSightMoveSlot);
+ tvPtr->side[atkSide].faintCause = 8;
+ }
+ break;
+ case B_ANIM_DOOM_DESIRE_HIT:
+ if (tvPtr->side[atkSide].doomDesireMonId != 0)
+ {
+ AddMovePoints(2, 1, atkSide,
+ (tvPtr->side[atkSide].doomDesireMonId - 1) * 4 + tvPtr->side[atkSide].doomDesireMoveSlot);
+ tvPtr->side[atkSide].faintCause = 9;
+ }
+ break;
+ }
+}
+
+#ifdef NONMATCHING
+// for loop has an unused stack variable
+void TryPutLinkBattleTvShowOnAir(void)
+{
+ u16 playerBestSpecies = 0, opponentBestSpecies = 0;
+ s16 playerBestSum = 0, opponentBestSum = SHRT_MAX;
+ u8 playerBestMonId = 0, opponentBestMonId = 0;
+ struct BattleTvMovePoints *movePoints = NULL;
+ u8 countPlayer = 0, countOpponent = 0;
+ s16 sum = 0;
+ u16 species = 0;
+ u16 moveId = 0;
+ s32 i, j;
+
+ if (gBattleStruct->anyMonHasTransformed)
+ return;
+
+ movePoints = &gBattleStruct->tvMovePoints;
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL) != SPECIES_NONE)
+ countPlayer++;
+ if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES, NULL) != SPECIES_NONE)
+ countOpponent++;
+ }
+
+ if (!(gBattleTypeFlags & BATTLE_TYPE_LINK) || countPlayer != countOpponent)
+ return;
+
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL);
+ if (species != SPECIES_NONE && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG, NULL))
+ {
+ for (sum = 0, j = 0; j < 4; j++)
+ sum += movePoints->points[0][i * 4 + j];
+
+ if (playerBestSum < sum)
+ {
+ playerBestMonId = i;
+ playerBestSum = sum;
+ playerBestSpecies = species;
+ }
+ }
+
+ species = GetMonData(&gEnemyParty[i], MON_DATA_SPECIES, NULL);
+ if (species != SPECIES_NONE && !GetMonData(&gEnemyParty[i], MON_DATA_IS_EGG, NULL))
+ {
+ for (sum = 0, j = 0; j < 4; j++)
+ sum += movePoints->points[1][i * 4 + j];
+
+ if (opponentBestSum == sum)
+ {
+ if (GetMonData(&gEnemyParty[i], MON_DATA_EXP, NULL) > GetMonData(&gEnemyParty[opponentBestMonId], MON_DATA_EXP, NULL))
+ {
+ opponentBestMonId = i;
+ opponentBestSum = sum;
+ opponentBestSpecies = species;
+ }
+ }
+ else if (opponentBestSum > sum)
+ {
+ opponentBestMonId = i;
+ opponentBestSum = sum;
+ opponentBestSpecies = species;
+ }
+ }
+ }
+
+ for (sum = 0, i = 0, j = 0; j < 4; j++)
+ {
+ if (sum < movePoints->points[0][playerBestMonId * 4 + j])
+ {
+ sum = movePoints->points[0][playerBestMonId * 4 + j];
+ i = j;
+ }
+ }
+
+ moveId = GetMonData(&gPlayerParty[playerBestMonId], MON_DATA_MOVE1 + i, NULL);
+ if (playerBestSum == 0 || moveId == 0)
+ return;
+
+ if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
+ {
+ if ((playerBestMonId < 3 && !sub_806D82C(gBattleScripting.multiplayerId))
+ || (playerBestMonId >= 3 && sub_806D82C(gBattleScripting.multiplayerId)))
+ {
+ j = (opponentBestMonId < 3) ? 0 : 1;
+ PutBattleUpdateOnTheAir(sub_806EF84(j, gBattleScripting.multiplayerId), moveId, playerBestSpecies, opponentBestSpecies);
+ }
+ }
+ else
+ {
+ PutBattleUpdateOnTheAir(gBattleScripting.multiplayerId ^ 1, moveId, playerBestSpecies, opponentBestSpecies);
+ }
+}
+
+#else
+NAKED
+void TryPutLinkBattleTvShowOnAir(void)
+{
+ asm_unified(
+ "push {r4-r7,lr}\n\
+ mov r7, r10\n\
+ mov r6, r9\n\
+ mov r5, r8\n\
+ push {r5-r7}\n\
+ sub sp, 0x20\n\
+ movs r0, 0\n\
+ str r0, [sp]\n\
+ movs r1, 0\n\
+ str r1, [sp, 0x4]\n\
+ movs r2, 0\n\
+ str r2, [sp, 0x8]\n\
+ ldr r3, =0x00007fff\n\
+ str r3, [sp, 0xC]\n\
+ movs r4, 0\n\
+ str r4, [sp, 0x10]\n\
+ movs r7, 0\n\
+ str r7, [sp, 0x14]\n\
+ mov r8, r0\n\
+ ldr r0, =gBattleStruct\n\
+ ldr r1, [r0]\n\
+ adds r0, r1, 0\n\
+ adds r0, 0xB3\n\
+ ldrb r0, [r0]\n\
+ cmp r0, 0\n\
+ beq _0817E42A\n\
+ b _0817E670\n\
+_0817E42A:\n\
+ movs r2, 0xD2\n\
+ lsls r2, 1\n\
+ adds r2, r1\n\
+ mov r10, r2\n\
+ movs r6, 0\n\
+_0817E434:\n\
+ movs r0, 0x64\n\
+ adds r4, r6, 0\n\
+ muls r4, r0\n\
+ ldr r0, =gPlayerParty\n\
+ adds r0, r4, r0\n\
+ movs r1, 0xB\n\
+ movs r2, 0\n\
+ bl GetMonData\n\
+ cmp r0, 0\n\
+ beq _0817E454\n\
+ mov r0, r8\n\
+ adds r0, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ mov r8, r0\n\
+_0817E454:\n\
+ ldr r5, =gEnemyParty\n\
+ adds r0, r4, r5\n\
+ movs r1, 0xB\n\
+ movs r2, 0\n\
+ bl GetMonData\n\
+ cmp r0, 0\n\
+ beq _0817E46A\n\
+ adds r0, r7, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r7, r0, 24\n\
+_0817E46A:\n\
+ adds r6, 0x1\n\
+ cmp r6, 0x5\n\
+ ble _0817E434\n\
+ ldr r0, =gBattleTypeFlags\n\
+ ldr r0, [r0]\n\
+ movs r1, 0x2\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ bne _0817E47E\n\
+ b _0817E670\n\
+_0817E47E:\n\
+ cmp r8, r7\n\
+ beq _0817E484\n\
+ b _0817E670\n\
+_0817E484:\n\
+ movs r6, 0\n\
+ lsls r3, r6, 1\n\
+ str r3, [sp, 0x18]\n\
+ movs r4, 0x64\n\
+ mov r8, r4\n\
+_0817E48E:\n\
+ mov r1, r8\n\
+ muls r1, r6\n\
+ ldr r0, =gPlayerParty\n\
+ adds r4, r1, r0\n\
+ adds r0, r4, 0\n\
+ movs r1, 0xB\n\
+ movs r2, 0\n\
+ bl GetMonData\n\
+ lsls r0, 16\n\
+ lsrs r7, r0, 16\n\
+ adds r0, r6, 0x1\n\
+ mov r9, r0\n\
+ cmp r7, 0\n\
+ beq _0817E4EE\n\
+ adds r0, r4, 0\n\
+ movs r1, 0x2D\n\
+ movs r2, 0\n\
+ bl GetMonData\n\
+ cmp r0, 0\n\
+ bne _0817E4EE\n\
+ movs r4, 0\n\
+ lsls r0, r6, 3\n\
+ mov r2, r10\n\
+ adds r1, r0, r2\n\
+ movs r3, 0x3\n\
+_0817E4C4:\n\
+ lsls r0, r4, 16\n\
+ asrs r0, 16\n\
+ ldrh r4, [r1]\n\
+ adds r0, r4\n\
+ lsls r0, 16\n\
+ lsrs r4, r0, 16\n\
+ adds r1, 0x2\n\
+ subs r3, 0x1\n\
+ cmp r3, 0\n\
+ bge _0817E4C4\n\
+ ldr r1, [sp, 0x8]\n\
+ lsls r0, r1, 16\n\
+ lsls r1, r4, 16\n\
+ cmp r0, r1\n\
+ bge _0817E4EE\n\
+ lsls r0, r6, 24\n\
+ lsrs r0, 24\n\
+ str r0, [sp, 0x10]\n\
+ lsrs r1, 16\n\
+ str r1, [sp, 0x8]\n\
+ str r7, [sp]\n\
+_0817E4EE:\n\
+ mov r0, r8\n\
+ muls r0, r6\n\
+ ldr r2, =gEnemyParty\n\
+ adds r4, r0, r2\n\
+ adds r0, r4, 0\n\
+ movs r1, 0xB\n\
+ movs r2, 0\n\
+ bl GetMonData\n\
+ lsls r0, 16\n\
+ lsrs r7, r0, 16\n\
+ ldr r3, [sp, 0x8]\n\
+ lsls r3, 16\n\
+ str r3, [sp, 0x1C]\n\
+ cmp r7, 0\n\
+ beq _0817E5A0\n\
+ adds r0, r4, 0\n\
+ movs r1, 0x2D\n\
+ movs r2, 0\n\
+ bl GetMonData\n\
+ cmp r0, 0\n\
+ bne _0817E5A0\n\
+ movs r4, 0\n\
+ ldr r0, [sp, 0xC]\n\
+ lsls r2, r0, 16\n\
+ movs r3, 0x1\n\
+ lsls r1, r3, 1\n\
+ adds r1, 0x1\n\
+ lsls r1, 4\n\
+ lsls r0, r6, 3\n\
+ adds r0, r1\n\
+ mov r3, r10\n\
+ adds r1, r0, r3\n\
+ movs r3, 0x3\n\
+_0817E534:\n\
+ lsls r0, r4, 16\n\
+ asrs r0, 16\n\
+ ldrh r4, [r1]\n\
+ adds r0, r4\n\
+ lsls r0, 16\n\
+ lsrs r4, r0, 16\n\
+ adds r1, 0x2\n\
+ subs r3, 0x1\n\
+ cmp r3, 0\n\
+ bge _0817E534\n\
+ asrs r1, r2, 16\n\
+ lsls r5, r4, 16\n\
+ asrs r0, r5, 16\n\
+ cmp r1, r0\n\
+ bne _0817E590\n\
+ mov r0, r8\n\
+ muls r0, r6\n\
+ ldr r1, =gEnemyParty\n\
+ adds r0, r1\n\
+ movs r1, 0x19\n\
+ movs r2, 0\n\
+ bl GetMonData\n\
+ adds r4, r0, 0\n\
+ ldr r2, [sp, 0x14]\n\
+ mov r0, r8\n\
+ muls r0, r2\n\
+ ldr r3, =gEnemyParty\n\
+ adds r0, r3\n\
+ movs r1, 0x19\n\
+ movs r2, 0\n\
+ bl GetMonData\n\
+ cmp r4, r0\n\
+ bls _0817E5A0\n\
+ b _0817E594\n\
+ .pool\n\
+_0817E590:\n\
+ cmp r1, r0\n\
+ ble _0817E5A0\n\
+_0817E594:\n\
+ lsls r0, r6, 24\n\
+ lsrs r0, 24\n\
+ str r0, [sp, 0x14]\n\
+ lsrs r5, 16\n\
+ str r5, [sp, 0xC]\n\
+ str r7, [sp, 0x4]\n\
+_0817E5A0:\n\
+ mov r6, r9\n\
+ cmp r6, 0x5\n\
+ bgt _0817E5A8\n\
+ b _0817E48E\n\
+_0817E5A8:\n\
+ movs r4, 0\n\
+ movs r6, 0\n\
+ movs r3, 0\n\
+ ldr r5, =gPlayerParty\n\
+ ldr r7, [sp, 0x10]\n\
+ lsls r0, r7, 3\n\
+ mov r1, r10\n\
+ adds r2, r0, r1\n\
+_0817E5B8:\n\
+ lsls r0, r4, 16\n\
+ asrs r0, 16\n\
+ movs r7, 0\n\
+ ldrsh r1, [r2, r7]\n\
+ cmp r0, r1\n\
+ bge _0817E5C8\n\
+ ldrh r4, [r2]\n\
+ adds r6, r3, 0\n\
+_0817E5C8:\n\
+ adds r2, 0x2\n\
+ adds r3, 0x1\n\
+ cmp r3, 0x3\n\
+ ble _0817E5B8\n\
+ movs r0, 0x64\n\
+ ldr r1, [sp, 0x10]\n\
+ muls r0, r1\n\
+ adds r0, r5\n\
+ adds r1, r6, 0\n\
+ adds r1, 0xD\n\
+ movs r2, 0\n\
+ bl GetMonData\n\
+ lsls r0, 16\n\
+ lsrs r4, r0, 16\n\
+ ldr r2, [sp, 0x1C]\n\
+ cmp r2, 0\n\
+ beq _0817E670\n\
+ cmp r4, 0\n\
+ beq _0817E670\n\
+ ldr r0, =gBattleTypeFlags\n\
+ ldr r0, [r0]\n\
+ movs r1, 0x40\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ beq _0817E65C\n\
+ ldr r3, [sp, 0x10]\n\
+ cmp r3, 0x2\n\
+ bhi _0817E620\n\
+ ldr r0, =gBattleScripting\n\
+ adds r0, 0x25\n\
+ ldrb r0, [r0]\n\
+ bl sub_806D82C\n\
+ lsls r0, 16\n\
+ cmp r0, 0\n\
+ beq _0817E630\n\
+ b _0817E670\n\
+ .pool\n\
+_0817E620:\n\
+ ldr r0, =gBattleScripting\n\
+ adds r0, 0x25\n\
+ ldrb r0, [r0]\n\
+ bl sub_806D82C\n\
+ lsls r0, 16\n\
+ cmp r0, 0\n\
+ beq _0817E670\n\
+_0817E630:\n\
+ movs r3, 0\n\
+ ldr r7, [sp, 0x14]\n\
+ cmp r7, 0x2\n\
+ bls _0817E63A\n\
+ movs r3, 0x1\n\
+_0817E63A:\n\
+ lsls r0, r3, 24\n\
+ lsrs r0, 24\n\
+ ldr r1, =gBattleScripting\n\
+ adds r1, 0x25\n\
+ ldrb r1, [r1]\n\
+ bl sub_806EF84\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ adds r1, r4, 0\n\
+ ldr r2, [sp]\n\
+ ldr r3, [sp, 0x4]\n\
+ bl PutBattleUpdateOnTheAir\n\
+ b _0817E670\n\
+ .pool\n\
+_0817E65C:\n\
+ ldr r0, =gBattleScripting\n\
+ adds r0, 0x25\n\
+ ldrb r1, [r0]\n\
+ movs r0, 0x1\n\
+ eors r0, r1\n\
+ adds r1, r4, 0\n\
+ ldr r2, [sp]\n\
+ ldr r3, [sp, 0x4]\n\
+ bl PutBattleUpdateOnTheAir\n\
+_0817E670:\n\
+ add sp, 0x20\n\
+ pop {r3-r5}\n\
+ mov r8, r3\n\
+ mov r9, r4\n\
+ mov r10, r5\n\
+ pop {r4-r7}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .pool");
+}
+#endif
+
+static void AddMovePoints(u8 caseId, u16 arg1, u8 arg2, u8 arg3)
+{
+ struct BattleTvMovePoints *movePoints = &gBattleStruct->tvMovePoints;
+ struct BattleTv *tvPtr = &gBattleStruct->tv;
+ u32 atkSide = GetBattlerSide(gBattlerAttacker);
+ u32 defSide = GetBattlerSide(gBattlerTarget);
+ const u16 *ptr;
+ s32 i;
+
+ switch (caseId)
+ {
+ case 0:
+ case 1:
+ case 18:
+ case 22 ... 27:
+ movePoints->points[atkSide][gBattlerPartyIndexes[gBattlerAttacker] * 4 + arg1] += sPointsArray[caseId][arg2];
+ break;
+ case 3 ... 7:
+ i = 0;
+ ptr = sPointsArray[caseId];
+ do
+ {
+ if (arg1 == ptr[i])
+ {
+ movePoints->points[atkSide][gBattlerPartyIndexes[gBattlerAttacker] * 4 + arg2] += ptr[i+1];
+ break;
+ }
+ i += 2;
+ } while (ptr[i] != 0xFFFF);
+ break;
+ case 19:
+ tvPtr->side[arg2 ^ 1].faintCause = 0;
+ movePoints->points[arg2][0 * 4 + arg3] += sPointsArray[caseId][arg1];
+ break;
+ case 20:
+ tvPtr->side[arg2].faintCause = 0;
+ case 2:
+ movePoints->points[arg2][0 * 4 + arg3] += sPointsArray[caseId][arg1];
+ break;
+ case 17:
+ movePoints->points[atkSide][arg2 * 4 + arg3] += sPointsArray[caseId][arg1];
+ break;
+ case 8:
+ case 9:
+ case 15:
+ case 16:
+ case 21:
+ movePoints->points[atkSide ^ BIT_SIDE][arg2 * 4 + arg3] += sPointsArray[caseId][arg1];
+ break;
+ case 10:
+ movePoints->points[arg1][arg2 * 4 + arg3] += sPointsArray[caseId][0];
+ break;
+ case 11:
+ if (tvPtr->pos[defSide][0].waterSportMonId != -(tvPtr->pos[defSide][1].waterSportMonId) && arg1 == 10)
+ {
+ if (tvPtr->pos[defSide][0].waterSportMonId != 0)
+ {
+ u32 id = (tvPtr->pos[defSide][0].waterSportMonId - 1) * 4;
+ movePoints->points[defSide][id + tvPtr->pos[defSide][0].waterSportMoveSlot] += sPointsArray[caseId][0];
+ }
+ if (tvPtr->pos[defSide][1].waterSportMonId != 0)
+ {
+ u32 id = (tvPtr->pos[defSide][1].waterSportMonId - 1) * 4;
+ movePoints->points[defSide][id + tvPtr->pos[defSide][1].waterSportMoveSlot] += sPointsArray[caseId][0];
+ }
+ }
+ break;
+ case 12:
+ if (tvPtr->pos[defSide][0].mudSportMonId != -(tvPtr->pos[defSide][1].mudSportMonId) && arg1 == 13)
+ {
+ if (tvPtr->pos[defSide][0].mudSportMonId != 0)
+ {
+ u32 id = (tvPtr->pos[defSide][0].mudSportMonId - 1) * 4;
+ movePoints->points[defSide][id + tvPtr->pos[defSide][0].mudSportMoveSlot] += sPointsArray[caseId][0];
+ }
+ if (tvPtr->pos[defSide][1].mudSportMonId != 0)
+ {
+ u32 id = (tvPtr->pos[defSide][1].mudSportMonId - 1) * 4;
+ movePoints->points[defSide][id + tvPtr->pos[defSide][1].mudSportMoveSlot] += sPointsArray[caseId][0];
+ }
+ }
+ break;
+ case 13:
+ if (arg1 <= 8 && arg2 != 0 && tvPtr->side[defSide].reflectMonId != 0)
+ {
+ u32 id = (tvPtr->side[defSide].reflectMonId - 1) * 4;
+ movePoints->points[defSide][id + tvPtr->side[defSide].reflectMoveSlot] += sPointsArray[caseId][0];
+ }
+ break;
+ case 14:
+ if (arg1 > 8 && arg2 != 0 && tvPtr->side[defSide].lightScreenMonId != 0)
+ {
+ u32 id = (tvPtr->side[defSide].lightScreenMonId - 1) * 4;
+ movePoints->points[defSide][id + tvPtr->side[defSide].lightScreenMoveSlot] += sPointsArray[caseId][0];
+ }
+ break;
+ }
+}
+
+static void AddPointsOnFainting(bool8 targetFainted)
+{
+ struct BattleTv *tvPtr = &gBattleStruct->tv;
+ u32 atkSide = GetBattlerSide(gBattlerAttacker);
+ u32 defSide = GetBattlerSide(gBattlerTarget);
+ u32 atkArrId = tvPtr->side[atkSide].faintCauseMonId;
+ s32 i;
+
+ if (tvPtr->side[atkSide].faintCause != 0)
+ {
+ switch (tvPtr->side[atkSide].faintCause)
+ {
+ case 1:
+ if (tvPtr->pos[atkSide][atkArrId].curseMonId != 0)
+ {
+ AddMovePoints(19, 0, atkSide ^ BIT_SIDE,
+ (tvPtr->pos[atkSide][atkArrId].curseMonId - 1) * 4 + tvPtr->pos[atkSide][atkArrId].curseMoveSlot);
+ }
+ break;
+ case 2:
+ if (tvPtr->pos[atkSide][atkArrId].leechSeedMonId != 0)
+ {
+ AddMovePoints(19, 0, atkSide ^ BIT_SIDE,
+ (tvPtr->pos[atkSide][atkArrId].leechSeedMonId - 1) * 4 + tvPtr->pos[atkSide][atkArrId].leechSeedMoveSlot);
+ }
+ break;
+ case 3:
+ if (tvPtr->mon[atkSide][atkArrId].psnMonId != 0)
+ {
+ AddMovePoints(19, 0, atkSide ^ BIT_SIDE,
+ (tvPtr->mon[atkSide][atkArrId].psnMonId - 1) * 4 + tvPtr->mon[atkSide][atkArrId].psnMoveSlot);
+ }
+ if (tvPtr->mon[atkSide][atkArrId].badPsnMonId != 0)
+ {
+ AddMovePoints(19, 0, atkSide ^ BIT_SIDE,
+ (tvPtr->mon[atkSide][atkArrId].badPsnMonId - 1) * 4 + tvPtr->mon[atkSide][atkArrId].badPsnMoveSlot);
+ }
+ break;
+ case 4:
+ if (tvPtr->mon[atkSide][atkArrId].brnMonId != 0)
+ {
+ AddMovePoints(19, 0, atkSide ^ BIT_SIDE,
+ (tvPtr->mon[atkSide][atkArrId].brnMonId - 1) * 4 + tvPtr->mon[atkSide][atkArrId].brnMoveSlot);
+ }
+ break;
+ case 5:
+ if (tvPtr->pos[atkSide][atkArrId].nightmareMonId != 0)
+ {
+ AddMovePoints(19, 0, atkSide ^ BIT_SIDE,
+ (tvPtr->pos[atkSide][atkArrId].nightmareMonId - 1) * 4 + tvPtr->pos[atkSide][atkArrId].nightmareMoveSlot);
+ }
+ break;
+ case 6:
+ if (tvPtr->pos[atkSide][atkArrId].wrapMonId != 0)
+ {
+ AddMovePoints(19, 0, atkSide ^ BIT_SIDE,
+ (tvPtr->pos[atkSide][atkArrId].wrapMonId - 1) * 4 + tvPtr->pos[atkSide][atkArrId].wrapMoveSlot);
+ }
+ break;
+ case 7:
+ if (tvPtr->side[atkSide].spikesMonId != 0)
+ {
+ AddMovePoints(19, 0, atkSide ^ BIT_SIDE,
+ (tvPtr->side[atkSide].spikesMonId - 1) * 4 + tvPtr->side[atkSide].spikesMoveSlot);
+ }
+ break;
+ case 8:
+ if (tvPtr->side[atkSide].futureSightMonId != 0)
+ {
+ AddMovePoints(20, 0, atkSide,
+ (tvPtr->side[atkSide].futureSightMonId - 1) * 4 + tvPtr->side[atkSide].futureSightMoveSlot);
+ }
+ break;
+ case 9:
+ if (tvPtr->side[atkSide].doomDesireMonId != 0)
+ {
+ AddMovePoints(20, 0, atkSide,
+ (tvPtr->side[atkSide].doomDesireMonId - 1) * 4 + tvPtr->side[atkSide].doomDesireMoveSlot);
+ }
+ break;
+ case 10:
+ if (tvPtr->side[atkSide].perishSong
+ && tvPtr->side[atkSide].perishSongMonId - 1 != gBattlerPartyIndexes[gBattlerAttacker])
+ {
+ AddMovePoints(19, 0, atkSide,
+ (tvPtr->side[atkSide].perishSongMonId - 1) * 4 + tvPtr->side[atkSide].perishSongMoveSlot);
+ }
+ if (tvPtr->side[atkSide ^ BIT_SIDE].perishSong)
+ {
+ AddMovePoints(19, 0, atkSide ^ BIT_SIDE,
+ (tvPtr->side[atkSide ^ BIT_SIDE].perishSongMonId - 1) * 4 + tvPtr->side[atkSide ^ BIT_SIDE].perishSongMoveSlot);
+ }
+ break;
+ case 11:
+ if (tvPtr->side[atkSide ^ BIT_SIDE].destinyBondMonId != 0)
+ {
+ AddMovePoints(19, 0, atkSide ^ BIT_SIDE,
+ (tvPtr->side[atkSide ^ BIT_SIDE].destinyBondMonId - 1) * 4 + tvPtr->side[atkSide ^ BIT_SIDE].destinyBondMoveSlot);
+ }
+ break;
+ case 12:
+ for (i = 0; i < 2; i++)
+ {
+ if (tvPtr->pos[atkSide][i].confusionMonId != 0)
+ {
+ AddMovePoints(19, 0, atkSide ^ BIT_SIDE,
+ (tvPtr->pos[atkSide][i].confusionMonId - 1) * 4 + tvPtr->pos[atkSide][i].confusionMoveSlot);
+ }
+ }
+ break;
+ case 13:
+ if (tvPtr->side[atkSide].explosion)
+ {
+ AddMovePoints(19, 0, atkSide,
+ (tvPtr->side[atkSide].explosionMonId - 1) * 4 + tvPtr->side[atkSide].explosionMoveSlot);
+ }
+ if (tvPtr->side[atkSide ^ BIT_SIDE].explosion)
+ {
+ AddMovePoints(19, 0, atkSide ^ BIT_SIDE,
+ (tvPtr->side[atkSide ^ BIT_SIDE].explosionMonId - 1) * 4 + tvPtr->side[atkSide ^ BIT_SIDE].explosionMoveSlot);
+ }
+ break;
+ case 14:
+ if (targetFainted == TRUE)
+ {
+ AddMovePoints(20, 0, atkSide,
+ (gBattlerPartyIndexes[gBattlerAttacker]) * 4 + tvPtr->side[atkSide].usedMoveSlot);
+ }
+ break;
+ case 15:
+ break;
+ }
+ }
+ else
+ {
+ if (tvPtr->side[defSide].faintCause == 7)
+ {
+ if (tvPtr->side[defSide].spikesMonId != 0)
+ {
+ AddMovePoints(19, 0, defSide ^ BIT_SIDE,
+ (tvPtr->side[defSide].spikesMonId - 1) * 4 + tvPtr->side[defSide].spikesMoveSlot);
+ }
+ }
+ else
+ {
+ AddMovePoints(20, 0, atkSide,
+ (gBattlerPartyIndexes[gBattlerAttacker]) * 4 + tvPtr->side[atkSide].usedMoveSlot);
+ }
+ }
+}
+
+static void TrySetBattleSeminarShow(void)
+{
+ s32 i;
+ s32 dmgByMove[4];
+ u16 powerOverride;
+ u16 currMoveSaved;
+
+ if (gBattleTypeFlags & (BATTLE_TYPE_DOUBLE | BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000))
+ return;
+ else if (GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT)
+ return;
+ else if (gBattleMons[gBattlerAttacker].statStages[STAT_ACC] <= 5)
+ return;
+ else if (gBattleMons[gBattlerTarget].statStages[STAT_EVASION] > 6)
+ return;
+ else if (gCurrentMove == MOVE_HIDDEN_POWER || gCurrentMove == MOVE_WEATHER_BALL)
+ return;
+ else if (gBattleTypeFlags & (BATTLE_TYPE_PALACE | BATTLE_TYPE_PIKE | BATTLE_TYPE_PYRAMID))
+ return;
+ else if (gBattleMoves[gBattleMons[gBattlerAttacker].moves[gMoveSelectionCursor[gBattlerAttacker]]].power == 0)
+ return;
+
+ i = 0;
+ currMoveSaved = gBattleMons[gBattlerAttacker].moves[gMoveSelectionCursor[gBattlerAttacker]];
+ do
+ {
+ if (currMoveSaved == sVariableDmgMoves[i])
+ break;
+ i++;
+ } while (sVariableDmgMoves[i] != 0xFFFF);
+
+ if (sVariableDmgMoves[i] != 0xFFFF)
+ return;
+
+ dmgByMove[gMoveSelectionCursor[gBattlerAttacker]] = gBattleMoveDamage;
+ currMoveSaved = gCurrentMove;
+ for (i = 0; i < 4; i++)
+ {
+ gCurrentMove = gBattleMons[gBattlerAttacker].moves[i];
+ powerOverride = 0;
+ if (ShouldCalculateDamage(gCurrentMove, &dmgByMove[i], &powerOverride))
+ {
+ u8 moveResultFlags;
+ u16 sideStatus = gSideStatuses[GET_BATTLER_SIDE(gBattlerTarget)];
+ gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBattlerAttacker], &gBattleMons[gBattlerTarget], gCurrentMove,
+ sideStatus, powerOverride,
+ 0, gBattlerAttacker, gBattlerTarget);
+
+ if (gStatuses3[gBattlerAttacker] & STATUS3_CHARGED_UP && gBattleMoves[gCurrentMove].type == TYPE_ELECTRIC)
+ gBattleMoveDamage *= 2;
+ if (gProtectStructs[gBattlerAttacker].helpingHand)
+ gBattleMoveDamage = gBattleMoveDamage * 15 / 10;
+
+ moveResultFlags = TypeCalc(gCurrentMove, gBattlerAttacker, gBattlerTarget);
+ dmgByMove[i] = gBattleMoveDamage;
+ if (dmgByMove[i] == 0 && !(moveResultFlags & MOVE_RESULT_NO_EFFECT))
+ dmgByMove[i] = 1;
+ }
+ }
+
+ for (i = 0; i < 4; i++)
+ {
+ if (i != gMoveSelectionCursor[gBattlerAttacker] && dmgByMove[i] > dmgByMove[gMoveSelectionCursor[gBattlerAttacker]])
+ {
+ u16 opponentSpecies, playerSpecies;
+ s32 bestMoveId;
+
+ if (gMoveSelectionCursor[gBattlerAttacker] != 0)
+ bestMoveId = 0;
+ else
+ bestMoveId = 1;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (i != gMoveSelectionCursor[gBattlerAttacker] && dmgByMove[i] > dmgByMove[bestMoveId])
+ bestMoveId = i;
+ }
+
+ opponentSpecies = GetMonData(&gEnemyParty [gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_SPECIES, NULL);
+ playerSpecies = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattlerAttacker]], MON_DATA_SPECIES, NULL);
+ sub_80EE35C(opponentSpecies, playerSpecies, gMoveSelectionCursor[gBattlerAttacker], gBattleMons[gBattlerAttacker].moves, gBattleMons[gBattlerAttacker].moves[bestMoveId]);
+ break;
+ }
+ }
+
+ gBattleMoveDamage = dmgByMove[gMoveSelectionCursor[gBattlerAttacker]];
+ gCurrentMove = currMoveSaved;
+}
+
+static bool8 ShouldCalculateDamage(u16 moveId, s32 *dmg, u16 *powerOverride)
+{
+ if (gBattleMoves[moveId].power == 0)
+ {
+ *dmg = 0;
+ return FALSE;
+ }
+ else
+ {
+ s32 i = 0;
+ do
+ {
+ if (moveId == sVariableDmgMoves[i])
+ break;
+ i++;
+ } while (sVariableDmgMoves[i] != 0xFFFF);
+
+ if (sVariableDmgMoves[i] != 0xFFFF)
+ {
+ *dmg = 0;
+ return FALSE;
+ }
+ else if (moveId == MOVE_PSYWAVE)
+ {
+ *dmg = gBattleMons[gBattlerAttacker].level;
+ *dmg /= 2;
+ return FALSE;
+ }
+ else if (moveId == MOVE_MAGNITUDE)
+ {
+ *powerOverride = 10;
+ return TRUE;
+ }
+ else
+ {
+ return TRUE;
+ }
+ }
+}
+
+void BattleTv_ClearExplosionFaintCause(void)
+{
+ if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ {
+ struct BattleTv *tvPtr = &gBattleStruct->tv;
+
+ tvPtr->side[B_SIDE_PLAYER].faintCause = 0;
+ tvPtr->side[B_SIDE_OPPONENT].faintCause = 0;
+
+ tvPtr->side[B_SIDE_PLAYER].faintCauseMonId = 0;
+ tvPtr->side[B_SIDE_OPPONENT].faintCauseMonId = 0;
+
+ tvPtr->side[B_SIDE_PLAYER].explosionMonId = 0;
+ tvPtr->side[B_SIDE_OPPONENT].explosionMonId = 0;
+
+ tvPtr->side[B_SIDE_PLAYER].explosionMoveSlot = 0;
+ tvPtr->side[B_SIDE_OPPONENT].explosionMoveSlot = 0;
+
+ tvPtr->side[B_SIDE_PLAYER].explosion = 0;
+ tvPtr->side[B_SIDE_OPPONENT].explosion = 0;
+ }
+}
+
+u8 GetBattlerMoveSlotId(u8 battlerId, u16 moveId)
+{
+ s32 i;
+ struct Pokemon *party;
+
+ if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
+ party = gPlayerParty;
+ else
+ party = gEnemyParty;
+
+ i = 0;
+ while (1)
+ {
+ if (i >= 4)
+ break;
+ if (GetMonData(&party[gBattlerPartyIndexes[battlerId]], MON_DATA_MOVE1 + i, NULL) == moveId)
+ break;
+ i++;
+ }
+
+ return i;
+}
+
+static void AddPointsBasedOnWeather(u16 weatherFlags, u16 moveId, u8 moveSlot)
+{
+ if (weatherFlags & WEATHER_RAIN_ANY)
+ AddMovePoints(3, moveId, moveSlot, 0);
+ else if (weatherFlags & WEATHER_SUN_ANY)
+ AddMovePoints(4, moveId, moveSlot, 0);
+ else if (weatherFlags & WEATHER_SANDSTORM_ANY)
+ AddMovePoints(5, moveId, moveSlot, 0);
+ else if (weatherFlags & WEATHER_HAIL_ANY)
+ AddMovePoints(6, moveId, moveSlot, 0);
+}
diff --git a/src/battle_util.c b/src/battle_util.c
index ddd61ae19..172ec6659 100644
--- a/src/battle_util.c
+++ b/src/battle_util.c
@@ -20,12 +20,9 @@
#include "battle_ai_script_commands.h"
#include "battle_controllers.h"
#include "event_data.h"
-#include "calculate_base_damage.h"
#include "link.h"
#include "berry.h"
-extern const struct BattleMove gBattleMoves[];
-
extern u8 weather_get_current(void);
// rom const data
@@ -1666,36 +1663,31 @@ u8 CastformDataTypeChange(u8 battler)
u8 formChange = 0;
if (gBattleMons[battler].species != SPECIES_CASTFORM || gBattleMons[battler].ability != ABILITY_FORECAST || gBattleMons[battler].hp == 0)
return CASTFORM_NO_CHANGE;
- if (!WEATHER_HAS_EFFECT && gBattleMons[battler].type1 != TYPE_NORMAL && gBattleMons[battler].type2 != TYPE_NORMAL)
+ if (!WEATHER_HAS_EFFECT && !IS_BATTLER_OF_TYPE(battler, TYPE_NORMAL))
{
- gBattleMons[battler].type1 = TYPE_NORMAL;
- gBattleMons[battler].type2 = TYPE_NORMAL;
+ SET_BATTLER_TYPE(battler, TYPE_NORMAL);
return CASTFORM_TO_NORMAL;
}
if (!WEATHER_HAS_EFFECT)
return CASTFORM_NO_CHANGE;
- if (!(gBattleWeather & (WEATHER_RAIN_ANY | WEATHER_SUN_ANY | WEATHER_HAIL)) && gBattleMons[battler].type1 != TYPE_NORMAL && gBattleMons[battler].type2 != TYPE_NORMAL)
+ if (!(gBattleWeather & (WEATHER_RAIN_ANY | WEATHER_SUN_ANY | WEATHER_HAIL_ANY)) && !IS_BATTLER_OF_TYPE(battler, TYPE_NORMAL))
{
- gBattleMons[battler].type1 = TYPE_NORMAL;
- gBattleMons[battler].type2 = TYPE_NORMAL;
+ SET_BATTLER_TYPE(battler, TYPE_NORMAL);
formChange = CASTFORM_TO_NORMAL;
}
- if (gBattleWeather & WEATHER_SUN_ANY && gBattleMons[battler].type1 != TYPE_FIRE && gBattleMons[battler].type2 != TYPE_FIRE)
+ if (gBattleWeather & WEATHER_SUN_ANY && !IS_BATTLER_OF_TYPE(battler, TYPE_FIRE))
{
- gBattleMons[battler].type1 = TYPE_FIRE;
- gBattleMons[battler].type2 = TYPE_FIRE;
+ SET_BATTLER_TYPE(battler, TYPE_FIRE);
formChange = CASTFORM_TO_FIRE;
}
- if (gBattleWeather & WEATHER_RAIN_ANY && gBattleMons[battler].type1 != TYPE_WATER && gBattleMons[battler].type2 != TYPE_WATER)
+ if (gBattleWeather & WEATHER_RAIN_ANY && !IS_BATTLER_OF_TYPE(battler, TYPE_WATER))
{
- gBattleMons[battler].type1 = TYPE_WATER;
- gBattleMons[battler].type2 = TYPE_WATER;
+ SET_BATTLER_TYPE(battler, TYPE_WATER);
formChange = CASTFORM_TO_WATER;
}
- if (gBattleWeather & WEATHER_HAIL && gBattleMons[battler].type1 != TYPE_ICE && gBattleMons[battler].type2 != TYPE_ICE)
+ if (gBattleWeather & WEATHER_HAIL_ANY && !IS_BATTLER_OF_TYPE(battler, TYPE_ICE))
{
- gBattleMons[battler].type1 = TYPE_ICE;
- gBattleMons[battler].type2 = TYPE_ICE;
+ SET_BATTLER_TYPE(battler, TYPE_ICE);
formChange = CASTFORM_TO_ICE;
}
return formChange;
@@ -2025,14 +2017,12 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& move != MOVE_STRUGGLE
&& gBattleMoves[move].power != 0
- && (gSpecialStatuses[gBattlerTarget].physicalDmg || gSpecialStatuses[gBattlerTarget].specialDmg)
- && gBattleMons[battler].type1 != moveType
- && gBattleMons[battler].type2 != moveType
+ && TARGET_TURN_DAMAGED
+ && !IS_BATTLER_OF_TYPE(battler, moveType)
&& gBattleMons[battler].hp != 0)
{
- gBattleMons[battler].type1 = moveType;
- gBattleMons[battler].type2 = moveType;
- PREPARE_TYPE_BUFFER(gBattleTextBuff1, moveType)
+ SET_BATTLER_TYPE(battler, moveType);
+ PREPARE_TYPE_BUFFER(gBattleTextBuff1, moveType);
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_ColorChangeActivates;
effect++;
@@ -2042,7 +2032,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& gBattleMons[gBattlerAttacker].hp != 0
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
- && (gSpecialStatuses[gBattlerTarget].physicalDmg || gSpecialStatuses[gBattlerTarget].specialDmg)
+ && TARGET_TURN_DAMAGED
&& (gBattleMoves[move].flags & FLAG_MAKES_CONTACT))
{
gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 16;
@@ -2057,7 +2047,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& gBattleMons[gBattlerAttacker].hp != 0
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
- && (gSpecialStatuses[gBattlerTarget].physicalDmg || gSpecialStatuses[gBattlerTarget].specialDmg)
+ && TARGET_TURN_DAMAGED
&& (gBattleMoves[move].flags & FLAG_MAKES_CONTACT)
&& (Random() % 10) == 0)
{
@@ -2080,7 +2070,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& gBattleMons[gBattlerAttacker].hp != 0
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
- && (gSpecialStatuses[gBattlerTarget].physicalDmg || gSpecialStatuses[gBattlerTarget].specialDmg)
+ && TARGET_TURN_DAMAGED
&& (gBattleMoves[move].flags & FLAG_MAKES_CONTACT)
&& (Random() % 3) == 0)
{
@@ -2095,7 +2085,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& gBattleMons[gBattlerAttacker].hp != 0
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
- && (gSpecialStatuses[gBattlerTarget].physicalDmg || gSpecialStatuses[gBattlerTarget].specialDmg)
+ && TARGET_TURN_DAMAGED
&& (gBattleMoves[move].flags & FLAG_MAKES_CONTACT)
&& (Random() % 3) == 0)
{
@@ -2111,7 +2101,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA
&& gBattleMons[gBattlerAttacker].hp != 0
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& (gBattleMoves[move].flags & FLAG_MAKES_CONTACT)
- && (gSpecialStatuses[gBattlerTarget].physicalDmg || gSpecialStatuses[gBattlerTarget].specialDmg)
+ && TARGET_TURN_DAMAGED
&& (Random() % 3) == 0)
{
gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_BURN;
@@ -2126,7 +2116,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA
&& gBattleMons[gBattlerAttacker].hp != 0
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& (gBattleMoves[move].flags & FLAG_MAKES_CONTACT)
- && (gSpecialStatuses[gBattlerTarget].physicalDmg || gSpecialStatuses[gBattlerTarget].specialDmg)
+ && TARGET_TURN_DAMAGED
&& gBattleMons[gBattlerTarget].hp != 0
&& (Random() % 3) == 0
&& gBattleMons[gBattlerAttacker].ability != ABILITY_OBLIVIOUS
@@ -3136,7 +3126,7 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn)
{
case HOLD_EFFECT_FLINCH:
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && (gSpecialStatuses[gBattlerTarget].physicalDmg || gSpecialStatuses[gBattlerTarget].specialDmg)
+ && TARGET_TURN_DAMAGED
&& (Random() % 100) < atkQuality
&& gBattleMoves[gCurrentMove].flags & FLAG_KINGSROCK_AFFECTED
&& gBattleMons[gBattlerTarget].hp)
@@ -3188,14 +3178,14 @@ void HandleAction_RunBattleScript(void) // identical to RunBattleScriptCommands
gBattleScriptingCommandsTable[*gBattlescriptCurrInstr]();
}
-u8 GetMoveTarget(u16 move, u8 useMoveTarget)
+u8 GetMoveTarget(u16 move, u8 setTarget)
{
u8 targetBank = 0;
u8 moveTarget;
u8 side;
- if (useMoveTarget)
- moveTarget = useMoveTarget - 1;
+ if (setTarget)
+ moveTarget = setTarget - 1;
else
moveTarget = gBattleMoves[move].target;
@@ -3256,8 +3246,8 @@ u8 GetMoveTarget(u16 move, u8 useMoveTarget)
else
targetBank = GetBattlerAtPosition((GetBattlerPosition(gBattlerAttacker) & BIT_SIDE) ^ BIT_SIDE);
break;
+ case MOVE_TARGET_USER_OR_SELECTED:
case MOVE_TARGET_USER:
- case MOVE_TARGET_x10:
targetBank = gBattlerAttacker;
break;
}
diff --git a/src/battle_util2.c b/src/battle_util2.c
index c1bbabc85..1d2f1e95b 100644
--- a/src/battle_util2.c
+++ b/src/battle_util2.c
@@ -76,26 +76,26 @@ void FreeBattleResources(void)
void AdjustFriendshipOnBattleFaint(u8 battlerId)
{
- u8 opposingBank;
+ u8 opposingBattlerId;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
- u8 opposingBank2;
+ u8 opposingBattlerId2;
- opposingBank = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
- opposingBank2 = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
+ opposingBattlerId = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
+ opposingBattlerId2 = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
- if (gBattleMons[opposingBank2].level > gBattleMons[opposingBank].level)
- opposingBank = opposingBank2;
+ if (gBattleMons[opposingBattlerId2].level > gBattleMons[opposingBattlerId].level)
+ opposingBattlerId = opposingBattlerId2;
}
else
{
- opposingBank = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
+ opposingBattlerId = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
}
- if (gBattleMons[opposingBank].level > gBattleMons[battlerId].level)
+ if (gBattleMons[opposingBattlerId].level > gBattleMons[battlerId].level)
{
- if (gBattleMons[opposingBank].level - gBattleMons[battlerId].level > 29)
+ if (gBattleMons[opposingBattlerId].level - gBattleMons[battlerId].level > 29)
AdjustFriendship(&gPlayerParty[gBattlerPartyIndexes[battlerId]], 8);
else
AdjustFriendship(&gPlayerParty[gBattlerPartyIndexes[battlerId]], 6);
diff --git a/src/berry.c b/src/berry.c
index 74b7090c0..e128eb0ec 100644
--- a/src/berry.c
+++ b/src/berry.c
@@ -1218,7 +1218,7 @@ void FieldObjectInteractionRemoveBerryTree(void)
u8 PlayerHasBerries(void)
{
- return IsBagPocketNonEmpty(BAG_BERRIES);
+ return IsBagPocketNonEmpty(POCKET_BERRIES);
}
void ResetBerryTreeSparkleFlags(void)
diff --git a/src/berry_blender.c b/src/berry_blender.c
index 848798442..48034a8c2 100644
--- a/src/berry_blender.c
+++ b/src/berry_blender.c
@@ -29,6 +29,8 @@
#include "pokeblock.h"
#include "trig.h"
#include "tv.h"
+#include "item_menu.h"
+#include "battle_records.h"
#define BLENDER_SCORE_BEST 0
#define BLENDER_SCORE_GOOD 1
@@ -128,10 +130,8 @@ struct BerryBlenderData
extern struct MusicPlayerInfo gMPlayInfo_SE2;
extern struct MusicPlayerInfo gMPlayInfo_BGM;
-extern u16 gSpecialVar_ItemId;
extern u8 gInGameOpponentsNo;
extern u8 gUnknown_020322D5;
-extern u8 gResultsWindowId;
// graphics
extern const u8 gBerryBlenderArrowTiles[];
@@ -152,10 +152,12 @@ extern const u8 gText_BlenderMaxSpeedRecord[];
extern const u8 gText_234Players[];
extern void sub_800A418(void);
+extern u8 sub_800A9D8(void);
extern void sub_809882C(u8, u16, u8);
extern void copy_textbox_border_tile_patterns_to_vram(u8, u16, u8);
extern void sub_81AABF0(void (*callback)(void));
extern void sub_800B4C0(void);
+extern void ClearLinkCallback(void);
extern void sub_8009F8C(void);
extern void sub_8153430(void);
extern bool8 sub_8153474(void);
@@ -947,10 +949,10 @@ static void sub_807FAC8(void)
sBerryBlenderData->syncArrowSpriteIds[i] = CreateSprite(&sBlenderSyncArrow_SpriteTemplate, sBlenderSyncArrowsPos[i][0], sBlenderSyncArrowsPos[i][1], 1);
StartSpriteAnim(&gSprites[sBerryBlenderData->syncArrowSpriteIds[i]], i + 8);
}
- if (gReceivedRemoteLinkPlayers != 0 && gLinkVSyncDisabled)
+ if (gReceivedRemoteLinkPlayers != 0 && gWirelessCommType)
{
sub_800E0E8();
- sub_800DFB4(0, 0);
+ CreateWirelessStatusIndicatorSprite(0, 0);
}
SetVBlankCallback(VBlankCB0_BerryBlender);
sBerryBlenderData->mainState++;
@@ -1153,10 +1155,10 @@ static void sub_8080018(void)
sBerryBlenderData->syncArrowSprite2Ids[i] = CreateSprite(&sBlenderSyncArrow_SpriteTemplate, sBlenderSyncArrowsPos[i][0], sBlenderSyncArrowsPos[i][1], 1);
StartSpriteAnim(&gSprites[sBerryBlenderData->syncArrowSprite2Ids[i]], i + 8);
}
- if (gReceivedRemoteLinkPlayers != 0 && gLinkVSyncDisabled)
+ if (gReceivedRemoteLinkPlayers != 0 && gWirelessCommType)
{
sub_800E0E8();
- sub_800DFB4(0, 0);
+ CreateWirelessStatusIndicatorSprite(0, 0);
}
sBerryBlenderData->mainState++;
break;
@@ -1869,7 +1871,7 @@ static void sub_8081370(u16 a0)
static bool32 sub_80814B0(u16 arg0, u16 arg1, u16 arg2)
{
- if (gReceivedRemoteLinkPlayers != 0 && gLinkVSyncDisabled)
+ if (gReceivedRemoteLinkPlayers != 0 && gWirelessCommType)
{
if ((arg0 & 0xFF00) == arg2)
return TRUE;
@@ -2311,7 +2313,7 @@ static void sub_8081E20(void)
static void sub_8081F94(u16 *a0)
{
- if (gReceivedRemoteLinkPlayers != 0 && gLinkVSyncDisabled)
+ if (gReceivedRemoteLinkPlayers != 0 && gWirelessCommType)
*a0 = 0x2F00;
else
*a0 = 0x2FFF;
@@ -2340,7 +2342,7 @@ static void CB2_HandleBlenderEndGame(void)
sBerryBlenderData->field_4C -= 32;
if (sBerryBlenderData->field_4C <= 0)
{
- sub_8009F8C();
+ ClearLinkCallback();
sBerryBlenderData->field_4C = 0;
if (gReceivedRemoteLinkPlayers != 0)
@@ -2360,7 +2362,7 @@ static void CB2_HandleBlenderEndGame(void)
}
else if (sub_800A520())
{
- if (gReceivedRemoteLinkPlayers != 0 && gLinkVSyncDisabled)
+ if (gReceivedRemoteLinkPlayers != 0 && gWirelessCommType)
{
sBerryBlenderData->gameBlock.timeRPM.time = sBerryBlenderData->gameFrameTime;
sBerryBlenderData->gameBlock.timeRPM.max_RPM = sBerryBlenderData->max_RPM;
@@ -2389,7 +2391,7 @@ static void CB2_HandleBlenderEndGame(void)
ResetBlockReceivedFlags();
sBerryBlenderData->gameEndState++;
- if (gReceivedRemoteLinkPlayers != 0 && gLinkVSyncDisabled)
+ if (gReceivedRemoteLinkPlayers != 0 && gWirelessCommType)
{
struct BlenderGameBlock *receivedBlock = (struct BlenderGameBlock*)(&gBlockRecvBuffer);
@@ -2469,7 +2471,7 @@ static void CB2_HandleBlenderEndGame(void)
sub_8081F94(&gSendCmd[0]);
if (sBerryBlenderData->yesNoAnswer == 0)
{
- if (IsBagPocketNonEmpty(BAG_BERRIES) == FALSE) // no berries
+ if (IsBagPocketNonEmpty(POCKET_BERRIES) == FALSE) // no berries
{
sBerryBlenderData->playAgainState = CANT_PLAY_NO_BERRIES;
gSendCmd[1] = 0x9999;
@@ -2687,7 +2689,7 @@ static void CB2_HandlePlayerLinkPlayAgainChoice(void)
if (gReceivedRemoteLinkPlayers == 0)
{
FREE_AND_SET_NULL(sBerryBlenderData);
- SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+ SetMainCallback2(CB2_ReturnToFieldContinueScript);
}
break;
}
@@ -2737,7 +2739,7 @@ static void CB2_HandlePlayerPlayAgainChoice(void)
if (sBerryBlenderData->playAgainState == PLAY_AGAIN_OK)
SetMainCallback2(DoBerryBlending);
else
- SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+ SetMainCallback2(CB2_ReturnToFieldContinueScript);
FreeAllWindowBuffers();
UnsetBgTilemapBuffer(2);
@@ -2866,7 +2868,7 @@ static void sub_8082D28(void)
if (gReceivedRemoteLinkPlayers != 0)
playerId = GetMultiplayerId();
- if (gLinkVSyncDisabled && gReceivedRemoteLinkPlayers != 0)
+ if (gWirelessCommType && gReceivedRemoteLinkPlayers != 0)
{
if (playerId == 0)
{
@@ -3482,13 +3484,13 @@ void ShowBerryBlenderRecordWindow(void)
u8 text[32];
winTemplate = sBlenderRecordWindowTemplate;
- gResultsWindowId = AddWindow(&winTemplate);
- NewMenuHelpers_DrawStdWindowFrame(gResultsWindowId, 0);
- FillWindowPixelBuffer(gResultsWindowId, 0x11);
+ gRecordsWindowId = AddWindow(&winTemplate);
+ NewMenuHelpers_DrawStdWindowFrame(gRecordsWindowId, 0);
+ FillWindowPixelBuffer(gRecordsWindowId, 0x11);
xPos = GetStringCenterAlignXOffset(1, gText_BlenderMaxSpeedRecord, 0x90);
- PrintTextOnWindow(gResultsWindowId, 1, gText_BlenderMaxSpeedRecord, xPos, 1, 0, NULL);
- PrintTextOnWindow(gResultsWindowId, 1, gText_234Players, 4, 0x29, 0, NULL);
+ PrintTextOnWindow(gRecordsWindowId, 1, gText_BlenderMaxSpeedRecord, xPos, 1, 0, NULL);
+ PrintTextOnWindow(gRecordsWindowId, 1, gText_234Players, 4, 0x29, 0, NULL);
for (i = 0, yPos = 0x29; i < BLENDER_SCORES_NO; i++)
{
@@ -3503,11 +3505,11 @@ void ShowBerryBlenderRecordWindow(void)
txtPtr = StringAppend(txtPtr, sText_RPM);
xPos = GetStringRightAlignXOffset(1, text, 0x8C);
- PrintTextOnWindow(gResultsWindowId, 1, text, xPos, yPos + (i * 16), 0, NULL);
+ PrintTextOnWindow(gRecordsWindowId, 1, text, xPos, yPos + (i * 16), 0, NULL);
}
- PutWindowTilemap(gResultsWindowId);
- CopyWindowToVram(gResultsWindowId, 3);
+ PutWindowTilemap(gRecordsWindowId);
+ CopyWindowToVram(gRecordsWindowId, 3);
}
static void sub_8083F3C(u8 taskId)
diff --git a/src/berry_tag_screen.c b/src/berry_tag_screen.c
index f86f350bf..9a6e78c81 100644
--- a/src/berry_tag_screen.c
+++ b/src/berry_tag_screen.c
@@ -515,9 +515,9 @@ static void Task_HandleInput(u8 taskId)
static void TryChangeDisplayedBerry(u8 taskId, s8 toMove)
{
s16 *data = gTasks[taskId].data;
- s16 currPocketPosition = gUnknown_0203CE58.unk12[3] + gUnknown_0203CE58.unk8[3];
+ s16 currPocketPosition = gUnknown_0203CE58.scrollPosition[3] + gUnknown_0203CE58.cursorPosition[3];
u32 newPocketPosition = currPocketPosition + toMove;
- if (newPocketPosition < 46 && BagGetItemIdByPocketPosition(BAG_BERRIES, newPocketPosition) != 0)
+ if (newPocketPosition < 46 && BagGetItemIdByPocketPosition(POCKET_BERRIES, newPocketPosition) != 0)
{
if (toMove < 0)
data[1] = 2;
@@ -533,11 +533,11 @@ static void TryChangeDisplayedBerry(u8 taskId, s8 toMove)
static void HandleBagCursorPositionChange(s8 toMove)
{
- u16 *scrollPos = &gUnknown_0203CE58.unk12[3];
- u16 *cursorPos = &gUnknown_0203CE58.unk8[3];
+ u16 *scrollPos = &gUnknown_0203CE58.scrollPosition[3];
+ u16 *cursorPos = &gUnknown_0203CE58.cursorPosition[3];
if (toMove > 0)
{
- if (*cursorPos < 4 || BagGetItemIdByPocketPosition(BAG_BERRIES, *scrollPos + 8) == 0)
+ if (*cursorPos < 4 || BagGetItemIdByPocketPosition(POCKET_BERRIES, *scrollPos + 8) == 0)
*cursorPos += toMove;
else
*scrollPos += toMove;
@@ -550,7 +550,7 @@ static void HandleBagCursorPositionChange(s8 toMove)
*scrollPos += toMove;
}
- sBerryTag->berryId = ItemIdToBerryType(BagGetItemIdByPocketPosition(BAG_BERRIES, *scrollPos + *cursorPos));
+ sBerryTag->berryId = ItemIdToBerryType(BagGetItemIdByPocketPosition(POCKET_BERRIES, *scrollPos + *cursorPos));
}
static void Task_DisplayAnotherBerry(u8 taskId)
diff --git a/src/bg.c b/src/bg.c
index b699a0b1f..2f4cdc856 100644
--- a/src/bg.c
+++ b/src/bg.c
@@ -463,7 +463,7 @@ bool8 IsDma3ManagerBusyWithBgCopy(void)
return FALSE;
}
#else
-__attribute__((naked))
+NAKED
bool8 IsDma3ManagerBusyWithBgCopy(void)
{
asm("push {r4-r7,lr}\n\
@@ -965,9 +965,9 @@ void CopyBgTilemapBufferToVram(u8 bg)
}
}
-void CopyToBgTilemapBufferRect(u8 bg, void* src, u8 destX, u8 destY, u8 width, u8 height)
+void CopyToBgTilemapBufferRect(u8 bg, const void* src, u8 destX, u8 destY, u8 width, u8 height)
{
- void* srcCopy;
+ const void* srcCopy;
u16 destX16;
u16 destY16;
u16 mode;
@@ -1048,7 +1048,7 @@ void CopyRectToBgTilemapBufferRect(u8 bg, const void* src, u8 srcX, u8 srcY, u8
}
}
}*/
-__attribute__((naked))
+NAKED
void CopyRectToBgTilemapBufferRect(u8 bg, const void* src, u8 srcX, u8 srcY, u8 srcWidth, u8 srcHeight, u8 destX, u8 destY, u8 rectWidth, u8 rectHeight, u8 palette1, u16 tileOffset, u16 palette2)
{
asm("push {r4-r7,lr}\n\
@@ -1495,7 +1495,7 @@ void CopyTileMapEntry(u16 *src, u16 *dest, s32 palette1, u32 tileOffset, u32 pal
*dest = test;
}
#else
-__attribute__((naked))
+NAKED
void CopyTileMapEntry(u16 *src, u16 *dest, s32 palette1, u32 tileOffset, u32 palette2)
{
asm("push {r4-r6,lr}\n\
diff --git a/src/bike.c b/src/bike.c
index 64af7c711..e827707cd 100644
--- a/src/bike.c
+++ b/src/bike.c
@@ -12,9 +12,7 @@
extern bool8 gBikeCyclingChallenge;
extern u8 gBikeCollisions;
-extern bool8 gUnknown_02037348;
-extern u8 sub_8093514(u8 direction);
extern u8 sub_808B980(u8 direction);
extern u8 sub_808B9BC(u8 direction);
extern u8 sub_808B9A4(u8 direction);
@@ -989,7 +987,7 @@ bool8 player_should_look_direction_be_enforced_upon_movement(void)
void GetOnOffBike(u8 transitionFlags)
{
- gUnknown_02037348 = FALSE;
+ gUnusedBikeCameraAheadPanback = FALSE;
if (gPlayerAvatar.flags & (PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE))
{
diff --git a/src/birch_pc.c b/src/birch_pc.c
new file mode 100644
index 000000000..3148832be
--- /dev/null
+++ b/src/birch_pc.c
@@ -0,0 +1,89 @@
+#include "global.h"
+#include "event_data.h"
+#include "field_message_box.h"
+#include "pokedex.h"
+#include "constants/species.h"
+#include "strings.h"
+
+bool16 ScriptGetPokedexInfo(void)
+{
+ if (gSpecialVar_0x8004 == 0) // is national dex not present?
+ {
+ gSpecialVar_0x8005 = GetHoennPokedexCount(0);
+ gSpecialVar_0x8006 = GetHoennPokedexCount(1);
+ }
+ else
+ {
+ gSpecialVar_0x8005 = GetNationalPokedexCount(0);
+ gSpecialVar_0x8006 = GetNationalPokedexCount(1);
+ }
+
+ return IsNationalPokedexEnabled();
+}
+
+// This shows your Hoenn Pokedex rating and not your National Dex.
+const u8 *GetPokedexRatingText(u16 count)
+{
+ if (count < 10)
+ return gBirchDexRatingText_LessThan10;
+ if (count < 20)
+ return gBirchDexRatingText_LessThan20;
+ if (count < 30)
+ return gBirchDexRatingText_LessThan30;
+ if (count < 40)
+ return gBirchDexRatingText_LessThan40;
+ if (count < 50)
+ return gBirchDexRatingText_LessThan50;
+ if (count < 60)
+ return gBirchDexRatingText_LessThan60;
+ if (count < 70)
+ return gBirchDexRatingText_LessThan70;
+ if (count < 80)
+ return gBirchDexRatingText_LessThan80;
+ if (count < 90)
+ return gBirchDexRatingText_LessThan90;
+ if (count < 100)
+ return gBirchDexRatingText_LessThan100;
+ if (count < 110)
+ return gBirchDexRatingText_LessThan110;
+ if (count < 120)
+ return gBirchDexRatingText_LessThan120;
+ if (count < 130)
+ return gBirchDexRatingText_LessThan130;
+ if (count < 140)
+ return gBirchDexRatingText_LessThan140;
+ if (count < 150)
+ return gBirchDexRatingText_LessThan150;
+ if (count < 160)
+ return gBirchDexRatingText_LessThan160;
+ if (count < 170)
+ return gBirchDexRatingText_LessThan170;
+ if (count < 180)
+ return gBirchDexRatingText_LessThan180;
+ if (count < 190)
+ return gBirchDexRatingText_LessThan190;
+ if (count < 200)
+ return gBirchDexRatingText_LessThan200;
+ if (count == 200)
+ {
+ if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(SPECIES_JIRACHI), 1)
+ || GetSetPokedexFlag(SpeciesToNationalPokedexNum(SPECIES_DEOXYS), 1)) // Jirachi or Deoxys is not counted towards the dex completion. If either of these flags are enabled, it means the actual count is less than 200.
+ return gBirchDexRatingText_LessThan200;
+ return gBirchDexRatingText_DexCompleted;
+ }
+ if (count == 201)
+ {
+ if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(SPECIES_JIRACHI), 1)
+ && GetSetPokedexFlag(SpeciesToNationalPokedexNum(SPECIES_DEOXYS), 1)) // If both of these flags are enabled, it means the actual count is less than 200.
+ return gBirchDexRatingText_LessThan200;
+ return gBirchDexRatingText_DexCompleted;
+ }
+ if (count == 202)
+ return gBirchDexRatingText_DexCompleted; // Hoenn dex is considered complete, even though the hoenn dex count is 210.
+ return gBirchDexRatingText_LessThan10;
+}
+
+void ShowPokedexRatingMessage(void)
+{
+ ShowFieldMessage(GetPokedexRatingText(gSpecialVar_0x8004));
+}
diff --git a/src/blit.c b/src/blit.c
new file mode 100644
index 000000000..b4d5f7de5
--- /dev/null
+++ b/src/blit.c
@@ -0,0 +1,209 @@
+#include "global.h"
+#include "blit.h"
+
+void BlitBitmapRect4BitWithoutColorKey(struct Bitmap *src, struct Bitmap *dst, u16 srcX, u16 srcY, u16 dstX, u16 dstY, u16 width, u16 height)
+{
+ BlitBitmapRect4Bit(src, dst, srcX, srcY, dstX, dstY, width, height, 0xFF);
+}
+
+void BlitBitmapRect4Bit(struct Bitmap *src, struct Bitmap *dst, u16 srcX, u16 srcY, u16 dstX, u16 dstY, u16 width, u16 height, u8 colorKey)
+{
+ s32 xEnd;
+ s32 yEnd;
+ s32 multiplierSrcY;
+ s32 multiplierDstY;
+ s32 loopSrcY, loopDstY;
+ s32 loopSrcX, loopDstX;
+ u8 *pixelsSrc;
+ u8 *pixelsDst;
+ s32 toOrr;
+ s32 toAnd;
+ s32 toShift;
+
+ if (dst->width - dstX < width)
+ xEnd = (dst->width - dstX) + srcX;
+ else
+ xEnd = srcX + width;
+
+ if (dst->height - dstY < height)
+ yEnd = (dst->height - dstY) + srcY;
+ else
+ yEnd = height + srcY;
+
+ multiplierSrcY = (src->width + (src->width & 7)) >> 3;
+ multiplierDstY = (dst->width + (dst->width & 7)) >> 3;
+
+ if (colorKey == 0xFF)
+ {
+ for (loopSrcY = srcY, loopDstY = dstY; loopSrcY < yEnd; loopSrcY++, loopDstY++)
+ {
+ for (loopSrcX = srcX, loopDstX = dstX; loopSrcX < xEnd; loopSrcX++, loopDstX++)
+ {
+ pixelsSrc = src->pixels + ((loopSrcX >> 1) & 3) + ((loopSrcX >> 3) << 5) + (((loopSrcY >> 3) * multiplierSrcY) << 5) + ((u32)(loopSrcY << 0x1d) >> 0x1B);
+ pixelsDst = dst->pixels + ((loopDstX >> 1) & 3) + ((loopDstX >> 3) << 5) + (((loopDstY >> 3) * multiplierDstY) << 5) + ((u32)(loopDstY << 0x1d) >> 0x1B);
+ toOrr = ((*pixelsSrc >> ((loopSrcX & 1) << 2)) & 0xF);
+ toShift = ((loopDstX & 1) << 2);
+ toOrr <<= toShift;
+ toAnd = 0xF0 >> (toShift);
+ *pixelsDst = toOrr | (*pixelsDst & toAnd);
+ }
+ }
+ }
+ else
+ {
+ for (loopSrcY = srcY, loopDstY = dstY; loopSrcY < yEnd; loopSrcY++, loopDstY++)
+ {
+ for (loopSrcX = srcX, loopDstX = dstX; loopSrcX < xEnd; loopSrcX++, loopDstX++)
+ {
+ pixelsSrc = src->pixels + ((loopSrcX >> 1) & 3) + ((loopSrcX >> 3) << 5) + (((loopSrcY >> 3) * multiplierSrcY) << 5) + ((u32)(loopSrcY << 0x1d) >> 0x1B);
+ pixelsDst = dst->pixels + ((loopDstX >> 1) & 3) + ((loopDstX >> 3) << 5) + (((loopDstY >> 3) * multiplierDstY) << 5) + ((u32)(loopDstY << 0x1d) >> 0x1B);
+ toOrr = ((*pixelsSrc >> ((loopSrcX & 1) << 2)) & 0xF);
+ if (toOrr != colorKey)
+ {
+ toShift = ((loopDstX & 1) << 2);
+ toOrr <<= toShift;
+ toAnd = 0xF0 >> (toShift);
+ *pixelsDst = toOrr | (*pixelsDst & toAnd);
+ }
+ }
+ }
+ }
+}
+
+void FillBitmapRect4Bit(struct Bitmap *surface, u16 x, u16 y, u16 width, u16 height, u8 fillValue)
+{
+ s32 xEnd;
+ s32 yEnd;
+ s32 multiplierY;
+ s32 loopX, loopY;
+ s32 toOrr1, toOrr2;
+
+ xEnd = x + width;
+ if (xEnd > surface->width)
+ xEnd = surface->width;
+
+ yEnd = y + height;
+ if (yEnd > surface->height)
+ yEnd = surface->height;
+
+ multiplierY = (surface->width + (surface->width & 7)) >> 3;
+ toOrr1 = (u32)(fillValue << 0x1C) >> 0x18;
+ toOrr2 = (fillValue & 0xF);
+
+ for (loopY = y; loopY < yEnd; loopY++)
+ {
+ for (loopX = x; loopX < xEnd; loopX++)
+ {
+ u8 *pixels = surface->pixels + ((loopX >> 1) & 3) + ((loopX >> 3) << 5) + (((loopY >> 3) * multiplierY) << 5) + ((u32)(loopY << 0x1d) >> 0x1B);
+ if ((loopX << 0x1F) != 0)
+ *pixels = toOrr1 | (*pixels & 0xF);
+ else
+ *pixels = toOrr2 | (*pixels & 0xF0);
+ }
+ }
+}
+
+void BlitBitmapRect4BitTo8Bit(struct Bitmap *src, struct Bitmap *dst, u16 srcX, u16 srcY, u16 dstX, u16 dstY, u16 width, u16 height, u8 colorKey, u8 paletteOffset)
+{
+ s32 palOffsetBits;
+ s32 xEnd;
+ s32 yEnd;
+ s32 multiplierSrcY;
+ s32 multiplierDstY;
+ s32 loopSrcY, loopDstY;
+ s32 loopSrcX, loopDstX;
+ u8 *pixelsSrc;
+ u8 *pixelsDst;
+ s32 colorKeyBits;
+
+ palOffsetBits = (u32)(paletteOffset << 0x1C) >> 0x18;
+ colorKeyBits = (u32)(colorKey << 0x1C) >> 0x18;
+
+ if (dst->width - dstX < width)
+ xEnd = (dst->width - dstX) + srcX;
+ else
+ xEnd = width + srcX;
+
+ if (dst->height - dstY < height)
+ yEnd = (srcY + dst->height) - dstY;
+ else
+ yEnd = srcY + height;
+
+ multiplierSrcY = (src->width + (src->width & 7)) >> 3;
+ multiplierDstY = (dst->width + (dst->width & 7)) >> 3;
+
+ if (colorKey == 0xFF)
+ {
+ for (loopSrcY = srcY, loopDstY = dstY; loopSrcY < yEnd; loopSrcY++, loopDstY++)
+ {
+ pixelsSrc = src->pixels + ((srcX >> 1) & 3) + ((srcX >> 3) << 5) + (((loopSrcY >> 3) * multiplierSrcY) << 5) + ((u32)(loopSrcY << 0x1d) >> 0x1b);
+ for (loopSrcX = srcX, loopDstX = dstX; loopSrcX < xEnd; loopSrcX++, loopDstX++)
+ {
+ pixelsDst = dst->pixels + (loopDstX & 7) + ((loopDstX >> 3) << 6) + (((loopDstY >> 3) * multiplierDstY) << 6) + ((u32)(loopDstY << 0x1d) >> 0x1a);
+ if (loopSrcX & 1)
+ {
+ *pixelsDst = palOffsetBits + (*pixelsSrc >> 4);
+ }
+ else
+ {
+ pixelsSrc = src->pixels + ((loopSrcX >> 1) & 3) + ((loopSrcX >> 3) << 5) + (((loopSrcY >> 3) * multiplierSrcY) << 5) + ((u32)(loopSrcY << 0x1d) >> 0x1b);
+ *pixelsDst = palOffsetBits + (*pixelsSrc & 0xF);
+ }
+ }
+ }
+ }
+ else
+ {
+ for (loopSrcY = srcY, loopDstY = dstY; loopSrcY < yEnd; loopSrcY++, loopDstY++)
+ {
+ pixelsSrc = src->pixels + ((srcX >> 1) & 3) + ((srcX >> 3) << 5) + (((loopSrcY >> 3) * multiplierSrcY) << 5) + ((u32)(loopSrcY << 0x1d) >> 0x1b);
+ for (loopSrcX = srcX, loopDstX = dstX; loopSrcX < xEnd; loopSrcX++, loopDstX++)
+ {
+ if (loopSrcX & 1)
+ {
+ if ((*pixelsSrc & 0xF0) != colorKeyBits)
+ {
+ pixelsDst = dst->pixels + (loopDstX & 7) + ((loopDstX >> 3) << 6) + (((loopDstY >> 3) * multiplierDstY) << 6) + ((u32)(loopDstY << 0x1d) >> 0x1a);
+ *pixelsDst = palOffsetBits + (*pixelsSrc >> 4);
+ }
+ }
+ else
+ {
+ pixelsSrc = src->pixels + ((loopSrcX >> 1) & 3) + ((loopSrcX >> 3) << 5) + (((loopSrcY >> 3) * multiplierSrcY) << 5) + ((u32)(loopSrcY << 0x1d) >> 0x1b);
+ if ((*pixelsSrc & 0xF) != colorKey)
+ {
+ pixelsDst = dst->pixels + (loopDstX & 7) + ((loopDstX >> 3) << 6) + (((loopDstY >> 3) * multiplierDstY) << 6) + ((u32)(loopDstY << 0x1d) >> 0x1a);
+ *pixelsDst = palOffsetBits + (*pixelsSrc & 0xF);
+ }
+ }
+ }
+ }
+ }
+}
+
+void FillBitmapRect8Bit(struct Bitmap *surface, u16 x, u16 y, u16 width, u16 height, u8 fillValue)
+{
+ s32 xEnd;
+ s32 yEnd;
+ s32 multiplierY;
+ s32 loopX, loopY;
+
+ xEnd = x + width;
+ if (xEnd > surface->width)
+ xEnd = surface->width;
+
+ yEnd = y + height;
+ if (yEnd > surface->height)
+ yEnd = surface->height;
+
+ multiplierY = (surface->width + (surface->width & 7)) >> 3;
+
+ for (loopY = y; loopY < yEnd; loopY++)
+ {
+ for (loopX = x; loopX < xEnd; loopX++)
+ {
+ u8 *pixels = surface->pixels + (loopX & 7) + ((loopX >> 3) << 6) + (((loopY >> 3) * multiplierY) << 6) + ((u32)(loopY << 0x1d) >> 0x1a);
+ *pixels = fillValue;
+ }
+ }
+}
diff --git a/src/braille_puzzles.c b/src/braille_puzzles.c
index d6924de9f..35277fe87 100644
--- a/src/braille_puzzles.c
+++ b/src/braille_puzzles.c
@@ -25,7 +25,7 @@ enum
};
extern u8 gBraillePuzzleCallbackFlag;
-extern u8 gUnknown_085EFE74[][2];
+extern const u8 gUnknown_085EFE74[][2];
void SealedChamberShakingEffect(u8);
void sub_8179860(void);
@@ -375,37 +375,49 @@ bool8 FldEff_UsePuzzleEffect(void)
return FALSE;
}
-// can't get this one to match due to the weird macro-like varsets with strange bitshifting.
-// to note: 0x10000 is loaded in, and its obviously supposed to be 1, but i cant get 0x80 << 9 to be loaded in without using it directly.
-// maybe there's some way of writing it that works?
-#ifdef NONMATCHING
-// ShouldDoBrailleRegicePuzzle
bool8 ShouldDoBrailleRegicePuzzle(void)
{
u8 i;
- if (gSaveBlock1Ptr->location.mapGroup == 0x18 && gSaveBlock1Ptr->location.mapNum == 0x43)
+ if (gSaveBlock1Ptr->location.mapGroup == 0x18
+ && gSaveBlock1Ptr->location.mapNum == 0x43)
{
- // _08179A1A
if (FlagGet(FLAG_SYS_BRAILLE_WAIT) != FALSE)
return FALSE;
- if (FlagGet(2) == FALSE)
+ if (FlagGet(FLAG_0x002) == FALSE)
return FALSE;
- if (FlagGet(3) == TRUE)
+ if (FlagGet(FLAG_0x003) == TRUE)
return FALSE;
for (i = 0; i < 36; i++)
{
- if (gSaveBlock1Ptr->pos.x == gUnknown_085EFE74[i][0] && gSaveBlock1Ptr->pos.y == gUnknown_085EFE74[i][1])
+ u8 xPos = gUnknown_085EFE74[i][0];
+ u8 yPos = gUnknown_085EFE74[i][1];
+ if (gSaveBlock1Ptr->pos.x == xPos && gSaveBlock1Ptr->pos.y == yPos)
{
+ u16 varValue;
+
if (i < 16)
- VarSet(0x403B, (0x10000 << i | VarGet(0x403B) << 16) >> 16); // correct
+ {
+ u16 val = VarGet(0x403B);
+ val |= 1 << i;
+ VarSet(0x403B, val);
+ }
else if (i < 32)
- VarSet(0x403C, (0x10000 << (i - 16) | VarGet(0x403C) << 16) >> 16); // hmm?
+ {
+ u16 val = VarGet(0x403C);
+ val |= 1 << (i - 16);
+ VarSet(0x403C, val);
+ }
else
- VarSet(0x403D, (0x10000 << (i - 32) | VarGet(0x403D) << 16) >> 16); // hmm?
-
- if (VarGet(0x403B) != 0xFFFF || VarGet(0x403C) != 0xFF || VarGet(0x403D) != 0xF)
+ {
+ u16 val = VarGet(0x403D);
+ val |= 1 << (i - 32);
+ VarSet(0x403D, val);
+ }
+
+ varValue = VarGet(0x403B);
+ if (varValue != 0xFFFF || VarGet(0x403C) != varValue || VarGet(0x403D) != 0xF)
return FALSE;
if (gSaveBlock1Ptr->pos.x == 8 && gSaveBlock1Ptr->pos.y == 21)
@@ -414,170 +426,10 @@ bool8 ShouldDoBrailleRegicePuzzle(void)
return FALSE;
}
}
+
+ FlagSet(FLAG_0x003);
+ FlagClear(FLAG_0x002);
}
- // TODO: Find what flags 2 and 3 are.
- FlagSet(3);
- FlagClear(2);
+
return FALSE;
}
-#else
-__attribute__((naked))
-bool8 ShouldDoBrailleRegicePuzzle(void)
-{
- asm(".syntax unified\n\
- push {r4-r7,lr}\n\
- mov r7, r9\n\
- mov r6, r8\n\
- push {r6,r7}\n\
- ldr r4, =gSaveBlock1Ptr\n\
- ldr r0, [r4]\n\
- ldrh r1, [r0, 0x4]\n\
- ldr r0, =0x00004318\n\
- cmp r1, r0\n\
- beq _08179A1A\n\
- b _08179B5A\n\
-_08179A1A:\n\
- ldr r0, =0x000008b1\n\
- bl FlagGet\n\
- lsls r0, 24\n\
- cmp r0, 0\n\
- beq _08179A28\n\
- b _08179B5A\n\
-_08179A28:\n\
- movs r0, 0x2\n\
- bl FlagGet\n\
- lsls r0, 24\n\
- cmp r0, 0\n\
- bne _08179A36\n\
- b _08179B5A\n\
-_08179A36:\n\
- movs r0, 0x3\n\
- bl FlagGet\n\
- lsls r0, 24\n\
- lsrs r0, 24\n\
- cmp r0, 0x1\n\
- bne _08179A58\n\
- b _08179B5A\n\
- .pool\n\
-_08179A54:\n\
- movs r0, 0x1\n\
- b _08179B5C\n\
-_08179A58:\n\
- movs r5, 0\n\
- mov r8, r4\n\
- ldr r4, =gUnknown_085EFE74\n\
- adds r0, r4, 0x1\n\
- mov r12, r0\n\
- ldr r6, =0x0000403b\n\
- ldr r1, =0x0000403c\n\
- mov r9, r1\n\
-_08179A68:\n\
- lsls r0, r5, 1\n\
- adds r1, r0, r4\n\
- add r0, r12\n\
- ldrb r3, [r0]\n\
- mov r7, r8\n\
- ldr r2, [r7]\n\
- movs r7, 0\n\
- ldrsh r0, [r2, r7]\n\
- ldrb r1, [r1]\n\
- cmp r0, r1\n\
- bne _08179B44\n\
- movs r1, 0x2\n\
- ldrsh r0, [r2, r1]\n\
- cmp r0, r3\n\
- bne _08179B44\n\
- cmp r5, 0xF\n\
- bhi _08179AB0\n\
- adds r0, r6, 0\n\
- bl VarGet\n\
- lsls r0, 16\n\
- movs r1, 0x80\n\
- lsls r1, 9\n\
- lsls r1, r5\n\
- orrs r1, r0\n\
- lsrs r1, 16\n\
- adds r0, r6, 0\n\
- bl VarSet\n\
- b _08179AF0\n\
- .pool\n\
-_08179AB0:\n\
- cmp r5, 0x1F\n\
- bhi _08179AD2\n\
- mov r0, r9\n\
- bl VarGet\n\
- lsls r0, 16\n\
- adds r2, r5, 0\n\
- subs r2, 0x10\n\
- movs r1, 0x80\n\
- lsls r1, 9\n\
- lsls r1, r2\n\
- orrs r1, r0\n\
- lsrs r1, 16\n\
- mov r0, r9\n\
- bl VarSet\n\
- b _08179AF0\n\
-_08179AD2:\n\
- ldr r4, =0x0000403d\n\
- adds r0, r4, 0\n\
- bl VarGet\n\
- lsls r0, 16\n\
- adds r2, r5, 0\n\
- subs r2, 0x20\n\
- movs r1, 0x80\n\
- lsls r1, 9\n\
- lsls r1, r2\n\
- orrs r1, r0\n\
- lsrs r1, 16\n\
- adds r0, r4, 0\n\
- bl VarSet\n\
-_08179AF0:\n\
- ldr r0, =0x0000403b\n\
- bl VarGet\n\
- lsls r0, 16\n\
- lsrs r4, r0, 16\n\
- ldr r0, =0x0000ffff\n\
- cmp r4, r0\n\
- bne _08179B5A\n\
- ldr r0, =0x0000403c\n\
- bl VarGet\n\
- lsls r0, 16\n\
- lsrs r0, 16\n\
- cmp r0, r4\n\
- bne _08179B5A\n\
- ldr r0, =0x0000403d\n\
- bl VarGet\n\
- lsls r0, 16\n\
- lsrs r0, 16\n\
- cmp r0, 0xF\n\
- bne _08179B5A\n\
- ldr r0, =gSaveBlock1Ptr\n\
- ldr r0, [r0]\n\
- ldr r1, [r0]\n\
- ldr r0, =0x00150008\n\
- cmp r1, r0\n\
- beq _08179A54\n\
- b _08179B5A\n\
- .pool\n\
-_08179B44:\n\
- adds r0, r5, 0x1\n\
- lsls r0, 24\n\
- lsrs r5, r0, 24\n\
- cmp r5, 0x23\n\
- bls _08179A68\n\
- movs r0, 0x3\n\
- bl FlagSet\n\
- movs r0, 0x2\n\
- bl FlagClear\n\
-_08179B5A:\n\
- movs r0, 0\n\
-_08179B5C:\n\
- pop {r3,r4}\n\
- mov r8, r3\n\
- mov r9, r4\n\
- pop {r4-r7}\n\
- pop {r1}\n\
- bx r1\n\
- .syntax divided");
-}
-#endif
diff --git a/src/calculate_base_damage.c b/src/calculate_base_damage.c
deleted file mode 100644
index 98468caa2..000000000
--- a/src/calculate_base_damage.c
+++ /dev/null
@@ -1,275 +0,0 @@
-#include "global.h"
-#include "constants/abilities.h"
-#include "battle.h"
-#include "battle_setup.h"
-#include "constants/hold_effects.h"
-#include "event_data.h"
-#include "item.h"
-#include "constants/items.h"
-#include "pokemon.h"
-#include "constants/species.h"
-#include "constants/moves.h"
-#include "constants/battle_move_effects.h"
-
-bool8 ShouldGetStatBadgeBoost(u16 flagId, u8 bank);
-
-extern const struct BattleMove gBattleMoves[];
-extern const u8 gHoldEffectToType[][2];
-extern const u8 gStatStageRatios[][2];
-
-#define APPLY_STAT_MOD(var, mon, stat, statIndex) \
-{ \
- (var) = (stat) * (gStatStageRatios)[(mon)->statStages[(statIndex)]][0]; \
- (var) /= (gStatStageRatios)[(mon)->statStages[(statIndex)]][1]; \
-}
-
-s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *defender, u32 move, u16 sideStatus, u16 powerOverride, u8 typeOverride, u8 bankAtk, u8 bankDef)
-{
- u32 i;
- s32 damage = 0;
- s32 damageHelper;
- u8 type;
- u16 attack, defense;
- u16 spAttack, spDefense;
- u8 defenderHoldEffect;
- u8 defenderHoldEffectParam;
- u8 attackerHoldEffect;
- u8 attackerHoldEffectParam;
-
- if (!powerOverride)
- gBattleMovePower = gBattleMoves[move].power;
- else
- gBattleMovePower = powerOverride;
-
- if (!typeOverride)
- type = gBattleMoves[move].type;
- else
- type = typeOverride & 0x3F;
-
- attack = attacker->attack;
- defense = defender->defense;
- spAttack = attacker->spAttack;
- spDefense = defender->spDefense;
-
- if (attacker->item == ITEM_ENIGMA_BERRY)
- {
- attackerHoldEffect = gEnigmaBerries[bankAtk].holdEffect;
- attackerHoldEffectParam = gEnigmaBerries[bankAtk].holdEffectParam;
- }
- else
- {
- attackerHoldEffect = ItemId_GetHoldEffect(attacker->item);
- attackerHoldEffectParam = ItemId_GetHoldEffectParam(attacker->item);
- }
-
- if (defender->item == ITEM_ENIGMA_BERRY)
- {
- defenderHoldEffect = gEnigmaBerries[bankDef].holdEffect;
- defenderHoldEffectParam = gEnigmaBerries[bankDef].holdEffectParam;
- }
- else
- {
- defenderHoldEffect = ItemId_GetHoldEffect(defender->item);
- defenderHoldEffectParam = ItemId_GetHoldEffectParam(defender->item);
- }
-
- if (attacker->ability == ABILITY_HUGE_POWER || attacker->ability == ABILITY_PURE_POWER)
- attack *= 2;
-
- if (ShouldGetStatBadgeBoost(FLAG_BADGE01_GET, bankAtk))
- attack = (110 * attack) / 100;
- if (ShouldGetStatBadgeBoost(FLAG_BADGE05_GET, bankDef))
- defense = (110 * defense) / 100;
- if (ShouldGetStatBadgeBoost(FLAG_BADGE07_GET, bankAtk))
- spAttack = (110 * spAttack) / 100;
- if (ShouldGetStatBadgeBoost(FLAG_BADGE07_GET, bankDef))
- spDefense = (110 * spDefense) / 100;
-
- for (i = 0; i < 17; i++)
- {
- if (attackerHoldEffect == gHoldEffectToType[i][0]
- && type == gHoldEffectToType[i][1])
- {
- if (type <= 8)
- attack = (attack * (attackerHoldEffectParam + 100)) / 100;
- else
- spAttack = (spAttack * (attackerHoldEffectParam + 100)) / 100;
- break;
- }
- }
-
- if (attackerHoldEffect == HOLD_EFFECT_CHOICE_BAND)
- attack = (150 * attack) / 100;
- if (attackerHoldEffect == HOLD_EFFECT_SOUL_DEW && !(gBattleTypeFlags & (BATTLE_TYPE_FRONTIER)) && (attacker->species == SPECIES_LATIAS || attacker->species == SPECIES_LATIOS))
- spAttack = (150 * spAttack) / 100;
- if (defenderHoldEffect == HOLD_EFFECT_SOUL_DEW && !(gBattleTypeFlags & (BATTLE_TYPE_FRONTIER)) && (defender->species == SPECIES_LATIAS || defender->species == SPECIES_LATIOS))
- spDefense = (150 * spDefense) / 100;
- if (attackerHoldEffect == HOLD_EFFECT_DEEP_SEA_TOOTH && attacker->species == SPECIES_CLAMPERL)
- spAttack *= 2;
- if (defenderHoldEffect == HOLD_EFFECT_DEEP_SEA_SCALE && defender->species == SPECIES_CLAMPERL)
- spDefense *= 2;
- if (attackerHoldEffect == HOLD_EFFECT_LIGHT_BALL && attacker->species == SPECIES_PIKACHU)
- spAttack *= 2;
- if (defenderHoldEffect == HOLD_EFFECT_METAL_POWDER && defender->species == SPECIES_DITTO)
- defense *= 2;
- if (attackerHoldEffect == HOLD_EFFECT_THICK_CLUB && (attacker->species == SPECIES_CUBONE || attacker->species == SPECIES_MAROWAK))
- attack *= 2;
- if (defender->ability == ABILITY_THICK_FAT && (type == TYPE_FIRE || type == TYPE_ICE))
- spAttack /= 2;
- if (attacker->ability == ABILITY_HUSTLE)
- attack = (150 * attack) / 100;
- if (attacker->ability == ABILITY_PLUS && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_MINUS, 0, 0))
- spAttack = (150 * spAttack) / 100;
- if (attacker->ability == ABILITY_MINUS && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_PLUS, 0, 0))
- spAttack = (150 * spAttack) / 100;
- if (attacker->ability == ABILITY_GUTS && attacker->status1)
- attack = (150 * attack) / 100;
- if (defender->ability == ABILITY_MARVEL_SCALE && defender->status1)
- defense = (150 * defense) / 100;
- if (type == TYPE_ELECTRIC && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, 0, 0xFD, 0))
- gBattleMovePower /= 2;
- if (type == TYPE_FIRE && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, 0, 0xFE, 0))
- gBattleMovePower /= 2;
- if (type == TYPE_GRASS && attacker->ability == ABILITY_OVERGROW && attacker->hp <= (attacker->maxHP / 3))
- gBattleMovePower = (150 * gBattleMovePower) / 100;
- if (type == TYPE_FIRE && attacker->ability == ABILITY_BLAZE && attacker->hp <= (attacker->maxHP / 3))
- gBattleMovePower = (150 * gBattleMovePower) / 100;
- if (type == TYPE_WATER && attacker->ability == ABILITY_TORRENT && attacker->hp <= (attacker->maxHP / 3))
- gBattleMovePower = (150 * gBattleMovePower) / 100;
- if (type == TYPE_BUG && attacker->ability == ABILITY_SWARM && attacker->hp <= (attacker->maxHP / 3))
- gBattleMovePower = (150 * gBattleMovePower) / 100;
- if (gBattleMoves[gCurrentMove].effect == EFFECT_EXPLOSION)
- defense /= 2;
-
- if (IS_MOVE_PHYSICAL(type))
- {
- if (gCritMultiplier == 2)
- {
- if (attacker->statStages[STAT_ATK] > 6)
- APPLY_STAT_MOD(damage, attacker, attack, STAT_ATK)
- else
- damage = attack;
- }
- else
- APPLY_STAT_MOD(damage, attacker, attack, STAT_ATK)
-
- damage = damage * gBattleMovePower;
- damage *= (2 * attacker->level / 5 + 2);
-
- if (gCritMultiplier == 2)
- {
- if (defender->statStages[STAT_DEF] < 6)
- APPLY_STAT_MOD(damageHelper, defender, defense, STAT_DEF)
- else
- damageHelper = defense;
- }
- else
- APPLY_STAT_MOD(damageHelper, defender, defense, STAT_DEF)
-
- damage = damage / damageHelper;
- damage /= 50;
-
- if ((attacker->status1 & STATUS1_BURN) && attacker->ability != ABILITY_GUTS)
- damage /= 2;
-
- if ((sideStatus & SIDE_STATUS_REFLECT) && gCritMultiplier == 1)
- {
- if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && CountAliveMonsInBattle(2) == 2)
- damage = 2 * (damage / 3);
- else
- damage /= 2;
- }
-
- if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gBattleMoves[move].target == 8 && CountAliveMonsInBattle(2) == 2)
- damage /= 2;
-
- // moves always do at least 1 damage.
- if (damage == 0)
- damage = 1;
- }
-
- if (type == TYPE_MYSTERY)
- damage = 0; // is ??? type. does 0 damage.
-
- if (IS_MOVE_SPECIAL(type))
- {
- if (gCritMultiplier == 2)
- {
- if (attacker->statStages[STAT_SPATK] > 6)
- APPLY_STAT_MOD(damage, attacker, spAttack, STAT_SPATK)
- else
- damage = spAttack;
- }
- else
- APPLY_STAT_MOD(damage, attacker, spAttack, STAT_SPATK)
-
- damage = damage * gBattleMovePower;
- damage *= (2 * attacker->level / 5 + 2);
-
- if (gCritMultiplier == 2)
- {
- if (defender->statStages[STAT_SPDEF] < 6)
- APPLY_STAT_MOD(damageHelper, defender, spDefense, STAT_SPDEF)
- else
- damageHelper = spDefense;
- }
- else
- APPLY_STAT_MOD(damageHelper, defender, spDefense, STAT_SPDEF)
-
- damage = (damage / damageHelper);
- damage /= 50;
-
- if ((sideStatus & SIDE_STATUS_LIGHTSCREEN) && gCritMultiplier == 1)
- {
- if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && CountAliveMonsInBattle(2) == 2)
- damage = 2 * (damage / 3);
- else
- damage /= 2;
- }
-
- if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gBattleMoves[move].target == 8 && CountAliveMonsInBattle(2) == 2)
- damage /= 2;
-
- // are effects of weather negated with cloud nine or air lock
- if (!AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_CLOUD_NINE, 0, 0)
- && !AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_AIR_LOCK, 0, 0))
- {
- if (gBattleWeather & WEATHER_RAIN_TEMPORARY)
- {
- switch (type)
- {
- case TYPE_FIRE:
- damage /= 2;
- break;
- case TYPE_WATER:
- damage = (15 * damage) / 10;
- break;
- }
- }
-
- // any weather except sun weakens solar beam
- if ((gBattleWeather & (WEATHER_RAIN_ANY | WEATHER_SANDSTORM_ANY | WEATHER_HAIL)) && gCurrentMove == MOVE_SOLAR_BEAM)
- damage /= 2;
-
- // sunny
- if (gBattleWeather & WEATHER_SUN_ANY)
- {
- switch (type)
- {
- case TYPE_FIRE:
- damage = (15 * damage) / 10;
- break;
- case TYPE_WATER:
- damage /= 2;
- break;
- }
- }
- }
-
- // flash fire triggered
- if ((gBattleResources->flags->flags[bankAtk] & UNKNOWN_FLAG_FLASH_FIRE) && type == TYPE_FIRE)
- damage = (15 * damage) / 10;
- }
-
- return damage + 2;
-}
diff --git a/src/clear_save_data_screen.c b/src/clear_save_data_screen.c
index 6d6a1545b..ca2037d2f 100644
--- a/src/clear_save_data_screen.c
+++ b/src/clear_save_data_screen.c
@@ -14,8 +14,6 @@
extern u8 gText_ClearAllSaveData[];
extern u8 gText_ClearingData[];
-extern u16 gUnknown_0860F074[];
-
static void Task_DoClearSaveDataScreenYesNo(u8);
static void Task_ClearSaveDataScreenYesNoChoice(u8);
static void Task_ClearSaveData(u8);
diff --git a/src/clock.c b/src/clock.c
index 7cea30166..71c433ed2 100644
--- a/src/clock.c
+++ b/src/clock.c
@@ -83,7 +83,7 @@ static void UpdatePerMinute(struct Time *localTime)
static void ReturnFromStartWallClock(void)
{
InitTimeBasedEvents();
- SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+ SetMainCallback2(CB2_ReturnToFieldContinueScript);
}
void StartWallClock(void)
diff --git a/src/credits.c b/src/credits.c
new file mode 100644
index 000000000..168f3e8a3
--- /dev/null
+++ b/src/credits.c
@@ -0,0 +1,2355 @@
+#include "global.h"
+#include "palette.h"
+#include "main.h"
+#include "task.h"
+#include "bg.h"
+#include "malloc.h"
+#include "window.h"
+#include "text.h"
+#include "menu.h"
+#include "international_string_util.h"
+#include "constants/songs.h"
+#include "gpu_regs.h"
+#include "m4a.h"
+#include "constants/rgb.h"
+#include "battle_dome_cards.h"
+#include "starter_choose.h"
+#include "decompress.h"
+#include "intro_credits_graphics.h"
+#include "sound.h"
+#include "trig.h"
+#include "graphics.h"
+#include "pokedex.h"
+#include "constants/vars.h"
+#include "event_data.h"
+#include "random.h"
+
+enum
+{
+ PAGE_TITLE,
+ PAGE_DIRECTOR,
+ PAGE_ART_DIRECTOR,
+ PAGE_WORLD_DIRECTOR,
+ PAGE_LEAD_PROGRAMMER,
+ PAGE_PROGRAMMERS_1,
+ PAGE_PROGRAMMERS_2,
+ PAGE_PROGRAMMERS_3,
+ PAGE_PROGRAMMERS_4,
+ PAGE_GRAPHIC_DESIGNERS_1,
+ PAGE_GRAPHIC_DESIGNERS_2,
+ PAGE_GRAPHIC_DESIGNERS_3,
+ PAGE_MUSIC_COMPOSITION,
+ PAGE_SOUND_EFFECTS,
+ PAGE_GAME_DESIGNERS_1,
+ PAGE_GAME_DESIGNERS_2,
+ PAGE_GAME_DESIGNERS_3,
+ PAGE_SCENARIO_PLOT,
+ PAGE_SCENARIO,
+ PAGE_SCRIPT_DESIGNERS,
+ PAGE_MAP_DESIGNERS,
+ PAGE_BATTLE_FRONTIER_DATA,
+ PAGE_PARAMETRIC_DESIGNERS,
+ PAGE_POKEDEX_TEXT,
+ PAGE_ENVIRONMENT_AND_TOOL_PROGRAMS_1,
+ PAGE_PKMN_DESIGNERS_1,
+ PAGE_PKMN_DESIGNERS_2,
+ PAGE_PKMN_DESIGNERS_3,
+ PAGE_PKMN_DESIGNERS_4,
+ PAGE_SUPPORT_PROGRAMMERS,
+ PAGE_NCL_PRODUCT_TESTING,
+ PAGE_PACKAGE_AND_MANUAL,
+ PAGE_SPECIAL_THANKS_1,
+ PAGE_SPECIAL_THANKS_2,
+ PAGE_SPECIAL_THANKS_3,
+ PAGE_SPECIAL_THANKS_4,
+ PAGE_INFORMATION_SUPERVISORS,
+ PAGE_ARTWORK_1,
+ PAGE_ARTWORK_2,
+ PAGE_ARTWORK_3,
+ PAGE_COORDINATORS,
+ PAGE_ENGLISH_VERSION,
+ PAGE_TRANSLATOR,
+ PAGE_TEXT_EDITOR,
+ PAGE_NCL_COORDINATOR,
+ PAGE_PROGRAMMERS_5,
+ PAGE_GRAPHIC_DESIGNER,
+ PAGE_ENVIRONMENT_AND_TOOL_PROGRAMS_2,
+ PAGE_NOA_TESTING,
+ PAGE_BRAILLE_CODE_CHECK_1,
+ PAGE_BRAILLE_CODE_CHECK_2,
+ PAGE_SPECIAL_THANKS_5,
+ PAGE_TASK_MANAGERS,
+ PAGE_PRODUCERS,
+ PAGE_EXECUTIVE_DIRECTOR,
+ PAGE_EXECUTIVE_PRODUCERS_1,
+ PAGE_EXECUTIVE_PRODUCERS_2,
+ PAGE_COUNT
+};
+
+#define COLOR_DARK_GREEN RGB(7, 11, 6)
+#define COLOR_LIGHT_GREEN RGB(13, 20, 12)
+
+enum
+{
+ TDA_0 = 0,
+ TDA_TASK_C_ID = 1,
+ TDA_TASK_E_ID = 2,
+ TDA_TASK_D_ID = 3,
+ TDA_4 = 4,
+ TDA_PLAYER_CYCLIST = 5,
+ TDA_RIVAL_CYCLIST = 6,
+ TDA_7 = 7, // Has something to do with the bike scene
+ TDA_11 = 11, // Gets set depending on whether the bike or the grass scene should be shown
+ TDA_12 = 12,
+ TDA_13 = 13,
+ TDA_14 = 14,
+ TDA_TASK_B_ID = 15,
+
+ // Appears to be responsible for text
+ TDB_0 = 0,
+ TDB_TASK_A_ID = 1,
+ TDB_CURRENT_PAGE = 2,
+ TDB_3 = 3,
+
+ TDC_0 = 0,
+ TDC_1 = 1,
+ TDC_2 = 2,
+ TDC_3 = 3,
+ TDC_4 = 4,
+ TDC_5 = 5,
+
+ TDD_STATE = 0,
+ TDD_TASK_A_ID = 1,
+ TDD_2 = 2,
+ TDD_3 = 3,
+
+ TDE_0 = 0,
+ TDE_1 = 1,
+ TDE_TASK_A_ID = 2,
+};
+
+struct Unk201C000
+{
+ u16 unk0[71];
+ u16 unk8E;
+ u16 unk90;
+ u16 unk92;
+ u16 unk94;
+ u16 unk96[386];
+ u16 unk39A;
+ u16 unk39C[7];
+};
+
+struct CreditsEntry
+{
+ u8 var_0;
+ u8 var_1;
+ const u8 *text;
+};
+
+static EWRAM_DATA s16 gUnknown_0203BCE0 = 0;
+static EWRAM_DATA u16 gUnknown_0203BCE2 = 0; // TASK A
+EWRAM_DATA bool8 gHasHallOfFameRecords = 0;
+static EWRAM_DATA u8 gUnknown_0203BCE5 = 0;
+static EWRAM_DATA struct Unk201C000 *gUnknown_0203BCE8 = {0};
+
+static const u16 gUnknown_085E56F0[][16] =
+{
+ INCBIN_U16("graphics/credits/credits_1.gbapal"),
+ INCBIN_U16("graphics/credits/credits_2.gbapal"),
+ INCBIN_U16("graphics/credits/credits_3.gbapal"),
+ INCBIN_U16("graphics/credits/credits_4.gbapal"),
+};
+
+static const u8 gCreditsCopyrightEnd_Gfx[] = INCBIN_U8("graphics/credits/the_end_copyright.4bpp.lz");
+
+static void sub_81772B8(struct Sprite *sprite);
+
+static const u8 gUnknown_085E5BAC[] =
+{
+ 0, 1, 0,
+ 0xFF, 1, 0xFF,
+ 0xFF, 1, 0xFF,
+ 0xFF, 1, 0xFF,
+ 0xFF, 1, 0xFF,
+};
+
+static const u8 gUnknown_085E5BBB[] =
+{
+ 1, 0xFF, 1,
+ 1, 0xFF, 1,
+ 1, 2, 1,
+ 1, 0xFF, 1,
+ 1, 0xFF, 1,
+};
+
+static const u8 gUnknown_085E5BCA[] =
+{
+ 1, 0, 0,
+ 1, 0xFF, 0xFF,
+ 1, 2, 2,
+ 1, 0xFF, 0xFF,
+ 1, 0x80, 0x80,
+};
+
+static const u8 gUnknown_085E5BD9[] =
+{
+ 1, 3, 1,
+ 1, 4, 1,
+ 1, 5, 1,
+ 1, 0xC4, 1,
+ 1, 0xC3, 1,
+};
+
+static const u8 gUnknown_085E5BE8[] =
+{
+ 1, 6, 7,
+ 1, 8, 9,
+ 1, 0xFF, 1,
+ 1, 0x88, 0x89,
+ 1, 0x86, 0x87,
+};
+
+static const u8 gCreditsText_EmptyString[] = _("");
+static const u8 gCreditsText_PkmnEmeraldVersion[] = _("POKéMON EMERALD VERSION");
+static const u8 gCreditsText_Credits[] = _("Credits");
+static const u8 gCreditsText_ExecutiveDirector[] = _("Executive Director");
+static const u8 gCreditsText_Director[] = _("Director");
+static const u8 gCreditsText_ArtDirector[] = _("Art Director");
+static const u8 gCreditsText_BattleDirector[] = _("Battle Director");
+static const u8 gCreditsText_MainProgrammer[] = _("Main Programmer");
+static const u8 gCreditsText_BattleSystemPgrms[] = _("Battle System Programmers");
+static const u8 gCreditsText_FieldSystemPgrms[] = _("Field System Programmer");
+static const u8 gCreditsText_Programmers[] = _("Programmers");
+static const u8 gCreditsText_MainGraphicDesigner[] = _("Main Graphic Designer");
+static const u8 gCreditsText_GraphicDesigners[] = _("Graphic Designers");
+static const u8 gCreditsText_PkmnDesigners[] = _("POKéMON Designers");
+static const u8 gCreditsText_MusicComposition[] = _("Music Composition");
+static const u8 gCreditsText_SoundEffectsAndPkmnVoices[] = _("Sound Effects & POKéMON Voices");
+static const u8 gCreditsText_GameDesigners[] = _("Game Designers");
+static const u8 gCreditsText_ScenarioPlot[] = _("Scenario Plot");
+static const u8 gCreditsText_Scenario[] = _("Scenario");
+static const u8 gCreditsText_ScriptDesigners[] = _("Script Designers");
+static const u8 gCreditsText_MapDesigners[] = _("Map Designers");
+static const u8 gCreditsText_MapDataDesigners[] = _("Map Data Designers");
+static const u8 gCreditsText_ParametricDesigners[] = _("Parametric Designers");
+static const u8 gCreditsText_PokedexText[] = _("POKéDEX Text");
+static const u8 gCreditsText_EnvAndToolPgrms[] = _("Environment & Tool Programmers");
+static const u8 gCreditsText_NCLProductTesting[] = _("NCL Product Testing");
+static const u8 gCreditsText_SpecialThanks[] = _("Special Thanks");
+static const u8 gCreditsText_Coordinators[] = _("Coordinators");
+static const u8 gCreditsText_Producers[] = _("Producers");
+static const u8 gCreditsText_ExecProducers[] = _("Executive Producers");
+static const u8 gCreditsText_InfoSupervisors[] = _("Information Supervisors");
+static const u8 gCreditsText_TaskManagers[] = _("Task Managers");
+static const u8 gCreditsText_BrailleCodeCheck[] = _("Braille Code Check");
+static const u8 gCreditsText_WorldDirector[] = _("World Director");
+static const u8 gCreditsText_BattleFrontierData[] = _("Battle Frontier Data");
+static const u8 gCreditsText_SupportProgrammers[] = _("Support Programmers");
+static const u8 gCreditsText_Artwork[] = _("Artwork");
+static const u8 gCreditsText_LeadProgrammer[] = _("Lead Programmer");
+static const u8 gCreditsText_LeadGraphicArtist[] = _("Lead Graphic Artist");
+static const u8 gCreditsText_SatoshiTajiri[] = _("Satoshi Tajiri");
+static const u8 gCreditsText_JunichiMasuda[] = _("Junichi Masuda");
+static const u8 gCreditsText_KenSugimori[] = _("Ken Sugimori");
+static const u8 gCreditsText_ShigekiMorimoto[] = _("Shigeki Morimoto");
+static const u8 gCreditsText_TetsuyaWatanabe[] = _("Tetsuya Watanabe");
+static const u8 gCreditsText_HisashiSogabe[] = _("Hisashi Sogabe");
+static const u8 gCreditsText_SosukeTamada[] = _("Sosuke Tamada");
+static const u8 gCreditsText_AkitoMori[] = _("Akito Mori");
+static const u8 gCreditsText_KeitaKagaya[] = _("Keita Kagaya");
+static const u8 gCreditsText_YoshinoriMatsuda[] = _("Yoshinori Matsuda");
+static const u8 gCreditsText_HiroyukiNakamura[] = _("Hiroyuki Nakamura");
+static const u8 gCreditsText_MasaoTaya[] = _("Masao Taya");
+static const u8 gCreditsText_SatoshiNohara[] = _("Satoshi Nohara");
+static const u8 gCreditsText_TomomichiOhta[] = _("Tomomichi Ohta");
+static const u8 gCreditsText_MiyukiIwasawa[] = _("Miyuki Iwasawa");
+static const u8 gCreditsText_TakenoriOhta[] = _("Takenori Ohta");
+static const u8 gCreditsText_HironobuYoshida[] = _("Hironobu Yoshida");
+static const u8 gCreditsText_MotofumiFujiwara[] = _("Motofumi Fujiwara");
+static const u8 gCreditsText_SatoshiOhta[] = _("Satoshi Ohta");
+static const u8 gCreditsText_AsukaIwashita[] = _("Asuka Iwashita");
+static const u8 gCreditsText_AimiTomita[] = _("Aimi Tomita");
+static const u8 gCreditsText_TakaoUnno[] = _("Takao Unno");
+static const u8 gCreditsText_KanakoEo[] = _("Kanako Eo");
+static const u8 gCreditsText_JunOkutani[] = _("Jun Okutani");
+static const u8 gCreditsText_AtsukoNishida[] = _("Atsuko Nishida");
+static const u8 gCreditsText_MuneoSaito[] = _("Muneo Saito");
+static const u8 gCreditsText_RenaYoshikawa[] = _("Rena Yoshikawa");
+static const u8 gCreditsText_GoIchinose[] = _("Go Ichinose");
+static const u8 gCreditsText_MorikazuAoki[] = _("Morikazu Aoki");
+static const u8 gCreditsText_KojiNishino[] = _("Koji Nishino");
+static const u8 gCreditsText_KenjiMatsushima[] = _("Kenji Matsushima");
+static const u8 gCreditsText_TetsujiOhta[] = _("Tetsuji Ohta");
+static const u8 gCreditsText_HitomiSato[] = _("Hitomi Sato");
+static const u8 gCreditsText_TakeshiKawachimaru[] = _("Takeshi Kawachimaru");
+static const u8 gCreditsText_TeruyukiShimoyamada[] = _("Teruyuki Shimoyamada");
+static const u8 gCreditsText_ShigeruOhmori[] = _("Shigeru Ohmori");
+static const u8 gCreditsText_TadashiTakahashi[] = _("Tadashi Takahashi");
+static const u8 gCreditsText_ToshinobuMatsumiya[] = _("Toshinobu Matsumiya");
+static const u8 gCreditsText_AkihitoTomisawa[] = _("Akihito Tomisawa");
+static const u8 gCreditsText_HirokiEnomoto[] = _("Hiroki Enomoto");
+static const u8 gCreditsText_KazuyukiTerada[] = _("Kazuyuki Terada");
+static const u8 gCreditsText_YuriSakurai[] = _("Yuri Sakurai");
+static const u8 gCreditsText_HiromiSagawa[] = _("Hiromi Sagawa");
+static const u8 gCreditsText_KenjiTominaga[] = _("Kenji Tominaga");
+static const u8 gCreditsText_YoshioTajiri[] = _("Yoshio Tajiri");
+static const u8 gCreditsText_TeikoSasaki[] = _("Teiko Sasaki");
+static const u8 gCreditsText_SachikoHamano[] = _("Sachiko Hamano");
+static const u8 gCreditsText_ChieMatsumiya[] = _("Chie Matsumiya");
+static const u8 gCreditsText_AkikoShinozaki[] = _("Akiko Shinozaki");
+static const u8 gCreditsText_AstukoFujii[] = _("Astuko Fujii");
+static const u8 gCreditsText_NozomuSaito[] = _("Nozomu Saito");
+static const u8 gCreditsText_KenkichiToyama[] = _("Kenkichi Toyama");
+static const u8 gCreditsText_SuguruNakatsui[] = _("Suguru Nakatsui");
+static const u8 gCreditsText_YumiFunasaka[] = _("Yumi Funasaka");
+static const u8 gCreditsText_NaokoYanase[] = _("Naoko Yanase");
+static const u8 gCreditsText_NCLSuperMarioClub[] = _("NCL Super Mario Club");
+static const u8 gCreditsText_AtsushiTada[] = _("Atsushi Tada");
+static const u8 gCreditsText_TakahiroOhnishi[] = _("Takahiro Ohnishi");
+static const u8 gCreditsText_NorihideOkamura[] = _("Norihide Okamura");
+static const u8 gCreditsText_HiroNakamura[] = _("Hiro Nakamura");
+static const u8 gCreditsText_HiroyukiUesugi[] = _("Hiroyuki Uesugi");
+static const u8 gCreditsText_TerukiMurakawa[] = _("Teruki Murakawa");
+static const u8 gCreditsText_AkiraKinashi[] = _("Akira Kinashi");
+static const u8 gCreditsText_MichikoTakizawa[] = _("Michiko Takizawa");
+static const u8 gCreditsText_MakikoTakada[] = _("Makiko Takada");
+static const u8 gCreditsText_TakanaoKondo[] = _("Takanao Kondo");
+static const u8 gCreditsText_AiMashima[] = _("Ai Mashima");
+static const u8 gCreditsText_GakujiNomoto[] = _("Gakuji Nomoto");
+static const u8 gCreditsText_TakehiroIzushi[] = _("Takehiro Izushi");
+static const u8 gCreditsText_HitoshiYamagami[] = _("Hitoshi Yamagami");
+static const u8 gCreditsText_KyokoWatanabe[] = _("Kyoko Watanabe");
+static const u8 gCreditsText_TakaoNakano[] = _("Takao Nakano");
+static const u8 gCreditsText_HiroyukiJinnai[] = _("Hiroyuki Jinnai");
+static const u8 gCreditsText_HiroakiTsuru[] = _("Hiroaki Tsuru");
+static const u8 gCreditsText_TsunekazIshihara[] = _("Tsunekaz Ishihara");
+static const u8 gCreditsText_SatoruIwata[] = _("Satoru Iwata");
+static const u8 gCreditsText_KazuyaSuyama[] = _("Kazuya Suyama");
+static const u8 gCreditsText_SatoshiMitsuhara[] = _("Satoshi Mitsuhara");
+static const u8 gCreditsText_JapanBrailleLibrary[] = _("Japan Braille Library");
+static const u8 gCreditsText_TomotakaKomura[] = _("Tomotaka Komura");
+static const u8 gCreditsText_MikikoOhhashi[] = _("Mikiko Ohhashi");
+static const u8 gCreditsText_DaisukeHoshino[] = _("Daisuke Hoshino");
+static const u8 gCreditsText_KenjiroIto[] = _("Kenjiro Ito");
+static const u8 gCreditsText_RuiKawaguchi[] = _("Rui Kawaguchi");
+static const u8 gCreditsText_ShunsukeKohori[] = _("Shunsuke Kohori");
+static const u8 gCreditsText_SachikoNakamichi[] = _("Sachiko Nakamichi");
+static const u8 gCreditsText_FujikoNomura[] = _("Fujiko Nomura");
+static const u8 gCreditsText_KazukiYoshihara[] = _("Kazuki Yoshihara");
+static const u8 gCreditsText_RetsujiNomoto[] = _("Retsuji Nomoto");
+static const u8 gCreditsText_AzusaTajima[] = _("Azusa Tajima");
+static const u8 gCreditsText_ShusakuEgami[] = _("Shusaku Egami");
+static const u8 gCreditsText_PackageAndManual[] = _("Package & Manual Illustration");
+static const u8 gCreditsText_EnglishVersion[] = _("English Version Coordinators");
+static const u8 gCreditsText_Translator[] = _("Translator");
+static const u8 gCreditsText_TextEditor[] = _("Text Editor");
+static const u8 gCreditsText_NCLCoordinator[] = _("NCL Coordinator");
+static const u8 gCreditsText_GraphicDesigner[] = _("Graphic Designer");
+static const u8 gCreditsText_NOAProductTesting[] = _("NOA Product Testing");
+static const u8 gCreditsText_HideyukiNakajima[] = _("Hideyuki Nakajima");
+static const u8 gCreditsText_HidenoriSaeki[] = _("Hidenori Saeki");
+static const u8 gCreditsText_YokoWatanabe[] = _("Yoko Watanabe");
+static const u8 gCreditsText_SakaeKimura[] = _("Sakae Kimura");
+static const u8 gCreditsText_ChiakiShinkai[] = _("Chiaki Shinkai");
+static const u8 gCreditsText_SethMcMahill[] = _("Seth McMahill");
+static const u8 gCreditsText_NobOgasawara[] = _("Nob Ogasawara");
+static const u8 gCreditsText_TeresaLillygren[] = _("Teresa Lillygren");
+static const u8 gCreditsText_KimikoNakamichi[] = _("Kimiko Nakamichi");
+static const u8 gCreditsText_SouichiYamamoto[] = _("Souichi Yamamoto");
+static const u8 gCreditsText_YuichiroIto[] = _("Yuichiro Ito");
+static const u8 gCreditsText_ThomasHertzog[] = _("Thomas Hertzog");
+static const u8 gCreditsText_MikaKurosawa[] = _("Mika Kurosawa");
+static const u8 gCreditsText_NationalFederationBlind[] = _("National Federation of the Blind");
+static const u8 gCreditsText_PatriciaAMaurer[] = _("Patricia A. Maurer");
+static const u8 gCreditsText_EuropeanBlindUnion[] = _("European Blind Union");
+static const u8 gCreditsText_AustralianBrailleAuthority[] = _("Australian Braille Authority");
+static const u8 gCreditsText_RoyalNewZealandFederationBlind[] = _("Royal New Zealand Federation for the Blind");
+static const u8 gCreditsText_MotoyasuTojima[] = _("Motoyasu Tojima");
+static const u8 gCreditsText_NicolaPrattBarlow[] = _("Nicola Pratt-Barlow");
+static const u8 gCreditsText_ShellieDow[] = _("Shellie Dow");
+static const u8 gCreditsText_ErikJohnson[] = _("Erik Johnson");
+static const struct CreditsEntry gCreditsEntry_EmptyString[] = {0, 0, gCreditsText_EmptyString};
+static const struct CreditsEntry gCreditsEntry_PkmnEmeraldVersion[] = {7, 1, gCreditsText_PkmnEmeraldVersion};
+static const struct CreditsEntry gCreditsEntry_Credits[] = {11, 1, gCreditsText_Credits};
+static const struct CreditsEntry gCreditsEntry_ExecutiveDirector[] = {8, 1, gCreditsText_ExecutiveDirector};
+static const struct CreditsEntry gCreditsEntry_Director[] = {12, 1, gCreditsText_Director};
+static const struct CreditsEntry gCreditsEntry_ArtDirector[] = {10, 1, gCreditsText_ArtDirector};
+static const struct CreditsEntry gCreditsEntry_BattleDirector[] = {10, 1, gCreditsText_BattleDirector};
+static const struct CreditsEntry gCreditsEntry_MainProgrammer[] = {10, 1, gCreditsText_MainProgrammer};
+static const struct CreditsEntry gCreditsEntry_BattleSystemPgrms[] = {8, 1, gCreditsText_BattleSystemPgrms};
+static const struct CreditsEntry gCreditsEntry_FieldSystemPgrms[] = {7, 1, gCreditsText_FieldSystemPgrms};
+static const struct CreditsEntry gCreditsEntry_Programmers[] = {12, 1, gCreditsText_Programmers};
+static const struct CreditsEntry gCreditsEntry_MainGraphicDesigner[] = {7, 1, gCreditsText_MainGraphicDesigner};
+static const struct CreditsEntry gCreditsEntry_GraphicDesigners[] = {9, 1, gCreditsText_GraphicDesigners};
+static const struct CreditsEntry gCreditsEntry_PkmnDesigners[] = {10, 1, gCreditsText_PkmnDesigners};
+static const struct CreditsEntry gCreditsEntry_MusicComposition[] = {13, 1, gCreditsText_MusicComposition};
+static const struct CreditsEntry gCreditsEntry_SoundEffectsAndPkmnVoices[] = {4, 1, gCreditsText_SoundEffectsAndPkmnVoices};
+static const struct CreditsEntry gCreditsEntry_GameDesigners[] = {11, 1, gCreditsText_GameDesigners};
+static const struct CreditsEntry gCreditsEntry_ScenarioPlot[] = {11, 1, gCreditsText_ScenarioPlot};
+static const struct CreditsEntry gCreditsEntry_Scenario[] = {13, 1, gCreditsText_Scenario};
+static const struct CreditsEntry gCreditsEntry_ScriptDesigners[] = {10, 1, gCreditsText_ScriptDesigners};
+static const struct CreditsEntry gCreditsEntry_MapDesigners[] = {11, 1, gCreditsText_MapDesigners};
+static const struct CreditsEntry gCreditsEntry_MapDataDesigners[] = {9, 1, gCreditsText_MapDataDesigners};
+static const struct CreditsEntry gCreditsEntry_ParametricDesigners[] = {9, 1, gCreditsText_ParametricDesigners};
+static const struct CreditsEntry gCreditsEntry_PokedexText[] = {11, 1, gCreditsText_PokedexText};
+static const struct CreditsEntry gCreditsEntry_EnvAndToolPgrms[] = {6, 1, gCreditsText_EnvAndToolPgrms};
+static const struct CreditsEntry gCreditsEntry_NCLProductTesting[] = {11, 1, gCreditsText_NCLProductTesting};
+static const struct CreditsEntry gCreditsEntry_SpecialThanks[] = {10, 1, gCreditsText_SpecialThanks};
+static const struct CreditsEntry gCreditsEntry_Coordinators[] = {11, 1, gCreditsText_Coordinators};
+static const struct CreditsEntry gCreditsEntry_Producers[] = {11, 1, gCreditsText_Producers};
+static const struct CreditsEntry gCreditsEntry_ExecProducers[] = {7, 1, gCreditsText_ExecProducers};
+static const struct CreditsEntry gCreditsEntry_InfoSupervisors[] = {10, 1, gCreditsText_InfoSupervisors};
+static const struct CreditsEntry gCreditsEntry_TaskManagers[] = {8, 1, gCreditsText_TaskManagers};
+static const struct CreditsEntry gCreditsEntry_BrailleCodeCheck[] = {10, 1, gCreditsText_BrailleCodeCheck};
+static const struct CreditsEntry gCreditsEntry_WorldDirector[] = {10, 1, gCreditsText_WorldDirector};
+static const struct CreditsEntry gCreditsEntry_BattleFrontierData[] = {8, 1, gCreditsText_BattleFrontierData};
+static const struct CreditsEntry gCreditsEntry_SupportProgrammers[] = {10, 1, gCreditsText_SupportProgrammers};
+static const struct CreditsEntry gCreditsEntry_Artwork[] = {12, 1, gCreditsText_Artwork};
+static const struct CreditsEntry gCreditsEntry_LeadProgrammer[] = {10, 1, gCreditsText_LeadProgrammer};
+static const struct CreditsEntry gCreditsEntry_LeadGraphicArtist[] = {9, 1, gCreditsText_LeadGraphicArtist};
+static const struct CreditsEntry gCreditsEntry_SatoshiTajiri[] = {11, 0, gCreditsText_SatoshiTajiri};
+static const struct CreditsEntry gCreditsEntry_JunichiMasuda[] = {11, 0, gCreditsText_JunichiMasuda};
+static const struct CreditsEntry gCreditsEntry_KenSugimori[] = {11, 0, gCreditsText_KenSugimori};
+static const struct CreditsEntry gCreditsEntry_ShigekiMorimoto[] = {11, 0, gCreditsText_ShigekiMorimoto};
+static const struct CreditsEntry gCreditsEntry_TetsuyaWatanabe[] = {11, 0, gCreditsText_TetsuyaWatanabe};
+static const struct CreditsEntry gCreditsEntry_HisashiSogabe[] = {11, 0, gCreditsText_HisashiSogabe};
+static const struct CreditsEntry gCreditsEntry_SosukeTamada[] = {11, 0, gCreditsText_SosukeTamada};
+static const struct CreditsEntry gCreditsEntry_AkitoMori[] = {11, 0, gCreditsText_AkitoMori};
+static const struct CreditsEntry gCreditsEntry_KeitaKagaya[] = {11, 0, gCreditsText_KeitaKagaya};
+static const struct CreditsEntry gCreditsEntry_YoshinoriMatsuda[] = {11, 0, gCreditsText_YoshinoriMatsuda};
+static const struct CreditsEntry gCreditsEntry_HiroyukiNakamura[] = {11, 0, gCreditsText_HiroyukiNakamura};
+static const struct CreditsEntry gCreditsEntry_MasaoTaya[] = {11, 0, gCreditsText_MasaoTaya};
+static const struct CreditsEntry gCreditsEntry_SatoshiNohara[] = {11, 0, gCreditsText_SatoshiNohara};
+static const struct CreditsEntry gCreditsEntry_TomomichiOhta[] = {11, 0, gCreditsText_TomomichiOhta};
+static const struct CreditsEntry gCreditsEntry_MiyukiIwasawa[] = {11, 0, gCreditsText_MiyukiIwasawa};
+static const struct CreditsEntry gCreditsEntry_TakenoriOhta[] = {11, 0, gCreditsText_TakenoriOhta};
+static const struct CreditsEntry gCreditsEntry_HironobuYoshida[] = {11, 0, gCreditsText_HironobuYoshida};
+static const struct CreditsEntry gCreditsEntry_MotofumiFujiwara[] = {11, 0, gCreditsText_MotofumiFujiwara};
+static const struct CreditsEntry gCreditsEntry_SatoshiOhta[] = {11, 0, gCreditsText_SatoshiOhta};
+static const struct CreditsEntry gCreditsEntry_AsukaIwashita[] = {11, 0, gCreditsText_AsukaIwashita};
+static const struct CreditsEntry gCreditsEntry_AimiTomita[] = {11, 0, gCreditsText_AimiTomita};
+static const struct CreditsEntry gCreditsEntry_TakaoUnno[] = {11, 0, gCreditsText_TakaoUnno};
+static const struct CreditsEntry gCreditsEntry_KanakoEo[] = {11, 0, gCreditsText_KanakoEo};
+static const struct CreditsEntry gCreditsEntry_JunOkutani[] = {11, 0, gCreditsText_JunOkutani};
+static const struct CreditsEntry gCreditsEntry_AtsukoNishida[] = {11, 0, gCreditsText_AtsukoNishida};
+static const struct CreditsEntry gCreditsEntry_MuneoSaito[] = {11, 0, gCreditsText_MuneoSaito};
+static const struct CreditsEntry gCreditsEntry_RenaYoshikawa[] = {11, 0, gCreditsText_RenaYoshikawa};
+static const struct CreditsEntry gCreditsEntry_GoIchinose[] = {11, 0, gCreditsText_GoIchinose};
+static const struct CreditsEntry gCreditsEntry_MorikazuAoki[] = {11, 0, gCreditsText_MorikazuAoki};
+static const struct CreditsEntry gCreditsEntry_KojiNishino[] = {11, 0, gCreditsText_KojiNishino};
+static const struct CreditsEntry gCreditsEntry_KenjiMatsushima[] = {11, 0, gCreditsText_KenjiMatsushima};
+static const struct CreditsEntry gCreditsEntry_TetsujiOhta[] = {11, 0, gCreditsText_TetsujiOhta};
+static const struct CreditsEntry gCreditsEntry_HitomiSato[] = {11, 0, gCreditsText_HitomiSato};
+static const struct CreditsEntry gCreditsEntry_TakeshiKawachimaru[] = {11, 0, gCreditsText_TakeshiKawachimaru};
+static const struct CreditsEntry gCreditsEntry_TeruyukiShimoyamada[] = {11, 0, gCreditsText_TeruyukiShimoyamada};
+static const struct CreditsEntry gCreditsEntry_ShigeruOhmori[] = {11, 0, gCreditsText_ShigeruOhmori};
+static const struct CreditsEntry gCreditsEntry_TadashiTakahashi[] = {11, 0, gCreditsText_TadashiTakahashi};
+static const struct CreditsEntry gCreditsEntry_ToshinobuMatsumiya[] = {11, 0, gCreditsText_ToshinobuMatsumiya};
+static const struct CreditsEntry gCreditsEntry_AkihitoTomisawa[] = {11, 0, gCreditsText_AkihitoTomisawa};
+static const struct CreditsEntry gCreditsEntry_HirokiEnomoto[] = {11, 0, gCreditsText_HirokiEnomoto};
+static const struct CreditsEntry gCreditsEntry_KazuyukiTerada[] = {11, 0, gCreditsText_KazuyukiTerada};
+static const struct CreditsEntry gCreditsEntry_YuriSakurai[] = {11, 0, gCreditsText_YuriSakurai};
+static const struct CreditsEntry gCreditsEntry_HiromiSagawa[] = {11, 0, gCreditsText_HiromiSagawa};
+static const struct CreditsEntry gCreditsEntry_KenjiTominaga[] = {11, 0, gCreditsText_KenjiTominaga};
+static const struct CreditsEntry gCreditsEntry_YoshioTajiri[] = {11, 0, gCreditsText_YoshioTajiri};
+static const struct CreditsEntry gCreditsEntry_TeikoSasaki[] = {11, 0, gCreditsText_TeikoSasaki};
+static const struct CreditsEntry gCreditsEntry_SachikoHamano[] = {11, 0, gCreditsText_SachikoHamano};
+static const struct CreditsEntry gCreditsEntry_ChieMatsumiya[] = {11, 0, gCreditsText_ChieMatsumiya};
+static const struct CreditsEntry gCreditsEntry_AkikoShinozaki[] = {11, 0, gCreditsText_AkikoShinozaki};
+static const struct CreditsEntry gCreditsEntry_AstukoFujii[] = {11, 0, gCreditsText_AstukoFujii};
+static const struct CreditsEntry gCreditsEntry_NozomuSaito[] = {11, 0, gCreditsText_NozomuSaito};
+static const struct CreditsEntry gCreditsEntry_KenkichiToyama[] = {11, 0, gCreditsText_KenkichiToyama};
+static const struct CreditsEntry gCreditsEntry_SuguruNakatsui[] = {11, 0, gCreditsText_SuguruNakatsui};
+static const struct CreditsEntry gCreditsEntry_YumiFunasaka[] = {11, 0, gCreditsText_YumiFunasaka};
+static const struct CreditsEntry gCreditsEntry_NaokoYanase[] = {11, 0, gCreditsText_NaokoYanase};
+static const struct CreditsEntry gCreditsEntry_NCLSuperMarioClub[] = {11, 0, gCreditsText_NCLSuperMarioClub};
+static const struct CreditsEntry gCreditsEntry_AtsushiTada[] = {11, 0, gCreditsText_AtsushiTada};
+static const struct CreditsEntry gCreditsEntry_TakahiroOhnishi[] = {11, 0, gCreditsText_TakahiroOhnishi};
+static const struct CreditsEntry gCreditsEntry_NorihideOkamura[] = {11, 0, gCreditsText_NorihideOkamura};
+static const struct CreditsEntry gCreditsEntry_HiroNakamura[] = {11, 0, gCreditsText_HiroNakamura};
+static const struct CreditsEntry gCreditsEntry_HiroyukiUesugi[] = {11, 0, gCreditsText_HiroyukiUesugi};
+static const struct CreditsEntry gCreditsEntry_TerukiMurakawa[] = {11, 0, gCreditsText_TerukiMurakawa};
+static const struct CreditsEntry gCreditsEntry_AkiraKinashi[] = {11, 0, gCreditsText_AkiraKinashi};
+static const struct CreditsEntry gCreditsEntry_MichikoTakizawa[] = {11, 0, gCreditsText_MichikoTakizawa};
+static const struct CreditsEntry gCreditsEntry_MakikoTakada[] = {11, 0, gCreditsText_MakikoTakada};
+static const struct CreditsEntry gCreditsEntry_TakanaoKondo[] = {11, 0, gCreditsText_TakanaoKondo};
+static const struct CreditsEntry gCreditsEntry_AiMashima[] = {11, 0, gCreditsText_AiMashima};
+static const struct CreditsEntry gCreditsEntry_GakujiNomoto[] = {11, 0, gCreditsText_GakujiNomoto};
+static const struct CreditsEntry gCreditsEntry_TakehiroIzushi[] = {11, 0, gCreditsText_TakehiroIzushi};
+static const struct CreditsEntry gCreditsEntry_HitoshiYamagami[] = {11, 0, gCreditsText_HitoshiYamagami};
+static const struct CreditsEntry gCreditsEntry_KyokoWatanabe[] = {11, 0, gCreditsText_KyokoWatanabe};
+static const struct CreditsEntry gCreditsEntry_TakaoNakano[] = {11, 0, gCreditsText_TakaoNakano};
+static const struct CreditsEntry gCreditsEntry_HiroyukiJinnai[] = {11, 0, gCreditsText_HiroyukiJinnai};
+static const struct CreditsEntry gCreditsEntry_HiroakiTsuru[] = {11, 0, gCreditsText_HiroakiTsuru};
+static const struct CreditsEntry gCreditsEntry_TsunekazIshihara[] = {11, 0, gCreditsText_TsunekazIshihara};
+static const struct CreditsEntry gCreditsEntry_SatoruIwata[] = {11, 0, gCreditsText_SatoruIwata};
+static const struct CreditsEntry gCreditsEntry_KazuyaSuyama[] = {11, 0, gCreditsText_KazuyaSuyama};
+static const struct CreditsEntry gCreditsEntry_SatoshiMitsuhara[] = {11, 0, gCreditsText_SatoshiMitsuhara};
+static const struct CreditsEntry gCreditsEntry_JapanBrailleLibrary[] = {9, 0, gCreditsText_JapanBrailleLibrary};
+static const struct CreditsEntry gCreditsEntry_TomotakaKomura[] = {11, 0, gCreditsText_TomotakaKomura};
+static const struct CreditsEntry gCreditsEntry_MikikoOhhashi[] = {11, 0, gCreditsText_MikikoOhhashi};
+static const struct CreditsEntry gCreditsEntry_DaisukeHoshino[] = {11, 0, gCreditsText_DaisukeHoshino};
+static const struct CreditsEntry gCreditsEntry_KenjiroIto[] = {11, 0, gCreditsText_KenjiroIto};
+static const struct CreditsEntry gCreditsEntry_RuiKawaguchi[] = {11, 0, gCreditsText_RuiKawaguchi};
+static const struct CreditsEntry gCreditsEntry_ShunsukeKohori[] = {11, 0, gCreditsText_ShunsukeKohori};
+static const struct CreditsEntry gCreditsEntry_SachikoNakamichi[] = {11, 0, gCreditsText_SachikoNakamichi};
+static const struct CreditsEntry gCreditsEntry_FujikoNomura[] = {11, 0, gCreditsText_FujikoNomura};
+static const struct CreditsEntry gCreditsEntry_KazukiYoshihara[] = {11, 0, gCreditsText_KazukiYoshihara};
+static const struct CreditsEntry gCreditsEntry_RetsujiNomoto[] = {11, 0, gCreditsText_RetsujiNomoto};
+static const struct CreditsEntry gCreditsEntry_AzusaTajima[] = {11, 0, gCreditsText_AzusaTajima};
+static const struct CreditsEntry gCreditsEntry_ShusakuEgami[] = {11, 0, gCreditsText_ShusakuEgami};
+static const struct CreditsEntry gCreditsEntry_PackageAndManual[] = {0, 1, gCreditsText_PackageAndManual};
+static const struct CreditsEntry gCreditsEntry_EnglishVersion[] = {0, 1, gCreditsText_EnglishVersion};
+static const struct CreditsEntry gCreditsEntry_Translator[] = {0, 1, gCreditsText_Translator};
+static const struct CreditsEntry gCreditsEntry_TextEditor[] = {0, 1, gCreditsText_TextEditor};
+static const struct CreditsEntry gCreditsEntry_NCLCoordinator[] = {0, 1, gCreditsText_NCLCoordinator};
+static const struct CreditsEntry gCreditsEntry_GraphicDesigner[] = {0, 1, gCreditsText_GraphicDesigner};
+static const struct CreditsEntry gCreditsEntry_NOAProductTesting[] = {0, 1, gCreditsText_NOAProductTesting};
+static const struct CreditsEntry gCreditsEntry_HideyukiNakajima[] = {0, 0, gCreditsText_HideyukiNakajima};
+static const struct CreditsEntry gCreditsEntry_HidenoriSaeki[] = {0, 0, gCreditsText_HidenoriSaeki};
+static const struct CreditsEntry gCreditsEntry_YokoWatanabe[] = {0, 0, gCreditsText_YokoWatanabe};
+static const struct CreditsEntry gCreditsEntry_SakaeKimura[] = {0, 0, gCreditsText_SakaeKimura};
+static const struct CreditsEntry gCreditsEntry_ChiakiShinkai[] = {0, 0, gCreditsText_ChiakiShinkai};
+static const struct CreditsEntry gCreditsEntry_SethMcMahill[] = {0, 0, gCreditsText_SethMcMahill};
+static const struct CreditsEntry gCreditsEntry_NobOgasawara[] = {0, 0, gCreditsText_NobOgasawara};
+static const struct CreditsEntry gCreditsEntry_TeresaLillygren[] = {0, 0, gCreditsText_TeresaLillygren};
+static const struct CreditsEntry gCreditsEntry_KimikoNakamichi[] = {0, 0, gCreditsText_KimikoNakamichi};
+static const struct CreditsEntry gCreditsEntry_SouichiYamamoto[] = {0, 0, gCreditsText_SouichiYamamoto};
+static const struct CreditsEntry gCreditsEntry_YuichiroIto[] = {0, 0, gCreditsText_YuichiroIto};
+static const struct CreditsEntry gCreditsEntry_ThomasHertzog[] = {0, 0, gCreditsText_ThomasHertzog};
+static const struct CreditsEntry gCreditsEntry_MikaKurosawa[] = {0, 0, gCreditsText_MikaKurosawa};
+static const struct CreditsEntry gCreditsEntry_NationalFederationBlind[] = {0, 0, gCreditsText_NationalFederationBlind};
+static const struct CreditsEntry gCreditsEntry_PatriciaAMaurer[] = {0, 0, gCreditsText_PatriciaAMaurer};
+static const struct CreditsEntry gCreditsEntry_EuropeanBlindUnion[] = {0, 0, gCreditsText_EuropeanBlindUnion};
+static const struct CreditsEntry gCreditsEntry_AustralianBrailleAuthority[] = {0, 0, gCreditsText_AustralianBrailleAuthority};
+static const struct CreditsEntry gCreditsEntry_RoyalNewZealandFederationBlind[] = {0, 0, gCreditsText_RoyalNewZealandFederationBlind};
+static const struct CreditsEntry gCreditsEntry_MotoyasuTojima[] = {0, 0, gCreditsText_MotoyasuTojima};
+static const struct CreditsEntry gCreditsEntry_NicolaPrattBarlow[] = {0, 0, gCreditsText_NicolaPrattBarlow};
+static const struct CreditsEntry gCreditsEntry_ShellieDow[] = {0, 0, gCreditsText_ShellieDow};
+static const struct CreditsEntry gCreditsEntry_ErikJohnson[] = {0, 0, gCreditsText_ErikJohnson};
+
+#define _ gCreditsEntry_EmptyString
+static const struct CreditsEntry *const gCreditsEntryPointerTable[][5] =
+{
+ {
+ _,
+ gCreditsEntry_PkmnEmeraldVersion,
+ gCreditsEntry_Credits,
+ _,
+ _
+ },
+ {
+ _,
+ gCreditsEntry_Director,
+ gCreditsEntry_ShigekiMorimoto,
+ _,
+ _,
+ },
+ {
+ _,
+ gCreditsEntry_ArtDirector,
+ gCreditsEntry_KenSugimori,
+ _,
+ _,
+ },
+ {
+ _,
+ gCreditsEntry_WorldDirector,
+ gCreditsEntry_JunichiMasuda,
+ _,
+ _,
+ },
+ {
+ gCreditsEntry_LeadProgrammer,
+ gCreditsEntry_HisashiSogabe,
+ gCreditsEntry_LeadGraphicArtist,
+ gCreditsEntry_MotofumiFujiwara,
+ _,
+ },
+ {
+ gCreditsEntry_Programmers,
+ gCreditsEntry_HisashiSogabe,
+ gCreditsEntry_TomomichiOhta,
+ gCreditsEntry_NozomuSaito,
+ gCreditsEntry_EmptyString,
+ },
+ {
+ gCreditsEntry_Programmers,
+ gCreditsEntry_AkitoMori,
+ gCreditsEntry_HiroyukiNakamura,
+ gCreditsEntry_MasaoTaya,
+ _,
+ },
+ {
+ gCreditsEntry_Programmers,
+ gCreditsEntry_SatoshiNohara,
+ gCreditsEntry_MiyukiIwasawa,
+ gCreditsEntry_YoshinoriMatsuda,
+ gCreditsEntry_KeitaKagaya,
+ },
+ {
+ gCreditsEntry_Programmers,
+ gCreditsEntry_TetsuyaWatanabe,
+ gCreditsEntry_SosukeTamada,
+ gCreditsEntry_TakenoriOhta,
+ _,
+ },
+ {
+ _,
+ gCreditsEntry_GraphicDesigners,
+ gCreditsEntry_MotofumiFujiwara,
+ gCreditsEntry_SatoshiOhta,
+ _,
+ },
+ {
+ gCreditsEntry_GraphicDesigners,
+ gCreditsEntry_KenkichiToyama,
+ gCreditsEntry_AsukaIwashita,
+ gCreditsEntry_TakaoUnno,
+ _,
+ },
+ {
+ gCreditsEntry_GraphicDesigners,
+ gCreditsEntry_KenSugimori,
+ gCreditsEntry_HironobuYoshida,
+ gCreditsEntry_AimiTomita,
+ gCreditsEntry_KanakoEo,
+ },
+ {
+ gCreditsEntry_MusicComposition,
+ gCreditsEntry_GoIchinose,
+ gCreditsEntry_JunichiMasuda,
+ gCreditsEntry_MorikazuAoki,
+ gCreditsEntry_HitomiSato,
+ },
+ {
+ _,
+ gCreditsEntry_SoundEffectsAndPkmnVoices,
+ gCreditsEntry_GoIchinose,
+ gCreditsEntry_MorikazuAoki,
+ _,
+ },
+ {
+ gCreditsEntry_GameDesigners,
+ gCreditsEntry_ShigekiMorimoto,
+ gCreditsEntry_TeruyukiShimoyamada,
+ gCreditsEntry_TakeshiKawachimaru,
+ gCreditsEntry_AkihitoTomisawa,
+ },
+ {
+ gCreditsEntry_GameDesigners,
+ gCreditsEntry_SuguruNakatsui,
+ gCreditsEntry_TetsujiOhta,
+ gCreditsEntry_HitomiSato,
+ gCreditsEntry_KenjiMatsushima,
+ },
+ {
+ gCreditsEntry_GameDesigners,
+ gCreditsEntry_JunichiMasuda,
+ gCreditsEntry_KojiNishino,
+ gCreditsEntry_ShigeruOhmori,
+ gCreditsEntry_TadashiTakahashi,
+ },
+ {
+ gCreditsEntry_ScenarioPlot,
+ gCreditsEntry_AkihitoTomisawa,
+ gCreditsEntry_JunichiMasuda,
+ gCreditsEntry_KojiNishino,
+ _,
+ },
+ {
+ gCreditsEntry_Scenario,
+ gCreditsEntry_AkihitoTomisawa,
+ gCreditsEntry_HitomiSato,
+ gCreditsEntry_ToshinobuMatsumiya,
+ _,
+ },
+ {
+ gCreditsEntry_ScriptDesigners,
+ gCreditsEntry_TomomichiOhta,
+ gCreditsEntry_SatoshiNohara,
+ _,
+ _,
+ },
+ {
+ gCreditsEntry_MapDesigners,
+ gCreditsEntry_SuguruNakatsui,
+ gCreditsEntry_TeruyukiShimoyamada,
+ gCreditsEntry_ShigeruOhmori,
+ gCreditsEntry_TetsujiOhta,
+ },
+ {
+ _,
+ gCreditsEntry_BattleFrontierData,
+ gCreditsEntry_TetsujiOhta,
+ _,
+ _,
+ },
+ {
+ gCreditsEntry_ParametricDesigners,
+ gCreditsEntry_TeruyukiShimoyamada,
+ gCreditsEntry_ShigekiMorimoto,
+ gCreditsEntry_TetsujiOhta,
+ gCreditsEntry_KojiNishino,
+ },
+ {
+ _,
+ gCreditsEntry_PokedexText,
+ gCreditsEntry_KenjiMatsushima,
+ _,
+ _,
+ },
+ {
+ gCreditsEntry_EnvAndToolPgrms,
+ gCreditsEntry_HisashiSogabe,
+ gCreditsEntry_SosukeTamada,
+ gCreditsEntry_HiroyukiNakamura,
+ gCreditsEntry_AkitoMori,
+ },
+ {
+ gCreditsEntry_PkmnDesigners,
+ gCreditsEntry_KenSugimori,
+ gCreditsEntry_MotofumiFujiwara,
+ gCreditsEntry_ShigekiMorimoto,
+ _,
+ },
+ {
+ gCreditsEntry_PkmnDesigners,
+ gCreditsEntry_HironobuYoshida,
+ gCreditsEntry_SatoshiOhta,
+ gCreditsEntry_AsukaIwashita,
+ _,
+ },
+ {
+ gCreditsEntry_PkmnDesigners,
+ gCreditsEntry_TakaoUnno,
+ gCreditsEntry_KanakoEo,
+ gCreditsEntry_AimiTomita,
+ _,
+ },
+ {
+ gCreditsEntry_PkmnDesigners,
+ gCreditsEntry_AtsukoNishida,
+ gCreditsEntry_MuneoSaito,
+ gCreditsEntry_RenaYoshikawa,
+ gCreditsEntry_JunOkutani,
+ },
+ {
+ _,
+ gCreditsEntry_SupportProgrammers,
+ gCreditsEntry_SatoshiMitsuhara,
+ gCreditsEntry_DaisukeHoshino,
+ _,
+ },
+ {
+ _,
+ gCreditsEntry_NCLProductTesting,
+ gCreditsEntry_NCLSuperMarioClub,
+ _,
+ _,
+ },
+ {
+ _,
+ gCreditsEntry_PackageAndManual,
+ gCreditsEntry_KenSugimori,
+ _,
+ _,
+ },
+ {
+ _,
+ gCreditsEntry_SpecialThanks,
+ gCreditsEntry_KenjiTominaga,
+ gCreditsEntry_HirokiEnomoto,
+ _,
+ },
+ {
+ gCreditsEntry_SpecialThanks,
+ gCreditsEntry_KazuyaSuyama,
+ gCreditsEntry_KenjiroIto,
+ gCreditsEntry_MichikoTakizawa,
+ gCreditsEntry_MakikoTakada,
+ },
+ {
+ gCreditsEntry_SpecialThanks,
+ gCreditsEntry_MikikoOhhashi,
+ gCreditsEntry_TakanaoKondo,
+ gCreditsEntry_RuiKawaguchi,
+ _,
+ },
+ {
+ gCreditsEntry_SpecialThanks,
+ gCreditsEntry_TakahiroOhnishi,
+ gCreditsEntry_NorihideOkamura,
+ gCreditsEntry_ShunsukeKohori,
+ _,
+ },
+ {
+ gCreditsEntry_InfoSupervisors,
+ gCreditsEntry_KazuyukiTerada,
+ gCreditsEntry_YuriSakurai,
+ gCreditsEntry_YumiFunasaka,
+ gCreditsEntry_NaokoYanase,
+ },
+ {
+ _,
+ gCreditsEntry_Artwork,
+ gCreditsEntry_SachikoNakamichi,
+ gCreditsEntry_FujikoNomura,
+ _,
+ },
+ {
+ _,
+ gCreditsEntry_Artwork,
+ gCreditsEntry_HideyukiNakajima,
+ gCreditsEntry_HidenoriSaeki,
+ _,
+ },
+ {
+ gCreditsEntry_Artwork,
+ gCreditsEntry_YokoWatanabe,
+ gCreditsEntry_SakaeKimura,
+ gCreditsEntry_ChiakiShinkai,
+ _,
+ },
+ {
+ gCreditsEntry_Coordinators,
+ gCreditsEntry_KazukiYoshihara,
+ gCreditsEntry_AkiraKinashi,
+ gCreditsEntry_RetsujiNomoto,
+ _,
+ },
+ {
+ _,
+ gCreditsEntry_EnglishVersion,
+ gCreditsEntry_HiroNakamura,
+ gCreditsEntry_SethMcMahill,
+ _,
+ },
+ {
+ _,
+ gCreditsEntry_Translator,
+ gCreditsEntry_NobOgasawara,
+ _,
+ _,
+ },
+ {
+ _,
+ gCreditsEntry_TextEditor,
+ gCreditsEntry_TeresaLillygren,
+ _,
+ _,
+ },
+ {
+ _,
+ gCreditsEntry_NCLCoordinator,
+ gCreditsEntry_KimikoNakamichi,
+ _,
+ _,
+ },
+ {
+ gCreditsEntry_Programmers,
+ gCreditsEntry_TerukiMurakawa,
+ gCreditsEntry_SouichiYamamoto,
+ gCreditsEntry_YuichiroIto,
+ gCreditsEntry_AkiraKinashi,
+ },
+ {
+ _,
+ gCreditsEntry_GraphicDesigner,
+ gCreditsEntry_AkiraKinashi,
+ _,
+ _,
+ },
+ {
+ gCreditsEntry_EnvAndToolPgrms,
+ gCreditsEntry_TerukiMurakawa,
+ gCreditsEntry_SouichiYamamoto,
+ gCreditsEntry_KimikoNakamichi,
+ _,
+ },
+ {
+ gCreditsEntry_NOAProductTesting,
+ gCreditsEntry_ThomasHertzog,
+ gCreditsEntry_ErikJohnson,
+ gCreditsEntry_MikaKurosawa,
+ _,
+ },
+ {
+ gCreditsEntry_BrailleCodeCheck,
+ gCreditsEntry_NationalFederationBlind,
+ gCreditsEntry_PatriciaAMaurer,
+ gCreditsEntry_JapanBrailleLibrary,
+ gCreditsEntry_EuropeanBlindUnion,
+ },
+ {
+ _,
+ gCreditsEntry_BrailleCodeCheck,
+ gCreditsEntry_AustralianBrailleAuthority,
+ gCreditsEntry_RoyalNewZealandFederationBlind,
+ _,
+ },
+ {
+ gCreditsEntry_SpecialThanks,
+ gCreditsEntry_HiroyukiUesugi,
+ gCreditsEntry_MotoyasuTojima,
+ gCreditsEntry_NicolaPrattBarlow,
+ gCreditsEntry_ShellieDow,
+ },
+ {
+ _,
+ gCreditsEntry_TaskManagers,
+ gCreditsEntry_AzusaTajima,
+ gCreditsEntry_ShusakuEgami,
+ _,
+ },
+ {
+ gCreditsEntry_Producers,
+ gCreditsEntry_HiroyukiJinnai,
+ gCreditsEntry_HitoshiYamagami,
+ gCreditsEntry_GakujiNomoto,
+ gCreditsEntry_HiroakiTsuru,
+ },
+ {
+ _,
+ gCreditsEntry_ExecutiveDirector,
+ gCreditsEntry_SatoshiTajiri,
+ _,
+ _,
+ },
+ {
+ _,
+ gCreditsEntry_ExecProducers,
+ gCreditsEntry_SatoruIwata,
+ _,
+ _,
+ },
+ {
+ _,
+ gCreditsEntry_ExecProducers,
+ gCreditsEntry_TsunekazIshihara,
+ _,
+ _,
+ },
+};
+#undef _
+
+static const struct BgTemplate gUnknown_085E6F68[] =
+{
+ {
+ .bg = 0,
+ .charBaseIndex = 2,
+ .mapBaseIndex = 28,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 0,
+ .baseTile = 0
+ },
+};
+static const struct WindowTemplate gUnknown_085E6F6C[] =
+{
+ { 0x00, 0x00, 0x09, 0x1E, 0x0C, 0x08, 0x0001 },
+ DUMMY_WIN_TEMPLATE,
+};
+static const u8 gUnknown_085E6F7C[][2] =
+{
+ {104, 36},
+ {120, 36},
+ {136, 36},
+};
+
+static const union AnimCmd gUnknown_085E6F84[] =
+{
+ ANIMCMD_FRAME(0, 8),
+ ANIMCMD_FRAME(64, 8),
+ ANIMCMD_FRAME(128, 8),
+ ANIMCMD_FRAME(192, 8),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd gUnknown_085E6F98[] =
+{
+ ANIMCMD_FRAME(0, 4),
+ ANIMCMD_FRAME(64, 4),
+ ANIMCMD_FRAME(128, 4),
+ ANIMCMD_FRAME(192, 4),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd gUnknown_085E6FAC[] =
+{
+ ANIMCMD_FRAME(256, 4),
+ ANIMCMD_FRAME(320, 4),
+ ANIMCMD_FRAME(384, 4),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_085E6FBC[] =
+{
+ ANIMCMD_FRAME(384, 30),
+ ANIMCMD_FRAME(320, 30),
+ ANIMCMD_FRAME(256, 30),
+ ANIMCMD_FRAME(256, 30),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_085E6FD0[] =
+{
+ gUnknown_085E6F84,
+ gUnknown_085E6F98,
+ gUnknown_085E6FAC,
+ gUnknown_085E6FBC,
+};
+
+static const union AnimCmd gUnknown_085E6FE0[] =
+{
+ ANIMCMD_FRAME(0, 8),
+ ANIMCMD_FRAME(64, 8),
+ ANIMCMD_FRAME(128, 8),
+ ANIMCMD_FRAME(192, 8),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd gUnknown_085E6FF4[] =
+{
+ ANIMCMD_FRAME(0, 4),
+ ANIMCMD_FRAME(64, 4),
+ ANIMCMD_FRAME(128, 4),
+ ANIMCMD_FRAME(192, 4),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd gUnknown_085E7008[] =
+{
+ ANIMCMD_FRAME(0, 4),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_085E7010[] =
+{
+ gUnknown_085E6FE0,
+ gUnknown_085E6FF4,
+ gUnknown_085E7008,
+};
+
+static const struct SpriteSheet gUnknown_085E701C[] = {
+ { gDecompressionBuffer, 6144, 1001 },
+ { NULL },
+};
+static const struct SpritePalette gUnknown_085E702C[] = {
+ { (const u16 *)(gDecompressionBuffer + 0x1800), 1001 },
+ { NULL },
+};
+
+static const struct OamData gUnknown_085E703C =
+{
+ .y = 160,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 3,
+ .tileNum = 0,
+ .priority = 1,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const union AnimCmd gUnknown_085E7044[] =
+{
+ ANIMCMD_FRAME(0, 8),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_085E704C[] =
+{
+ ANIMCMD_FRAME(64, 8),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_085E7054[] =
+{
+ ANIMCMD_FRAME(128, 8),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_085E705C[] =
+{
+ gUnknown_085E7044,
+ gUnknown_085E704C,
+ gUnknown_085E7054,
+};
+
+static const struct SpriteTemplate gUnknown_085E7068 =
+{
+ .tileTag = 1001,
+ .paletteTag = 1001,
+ .oam = &gUnknown_085E703C,
+ .anims = gUnknown_085E705C,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_81772B8,
+};
+
+void sub_8175620(void);
+static void sub_8175744(u8 taskIdA);
+static void sub_8175774(u8 taskIdA);
+static void sub_8175808(u8 taskIdA);
+static void c2_080C9BFC(u8 taskIdA);
+static void sub_81758E4(u8 taskIdA);
+static void sub_81758A4(u8 taskIdA);
+static void sub_8175A9C(u8 taskIdA);
+static void sub_8175AE4(u8 taskIdA);
+static void sub_8175B1C(u8 taskIdA);
+static void sub_8175B90(u8 taskIdA);
+static void sub_8175BD8(u8 taskIdA);
+static void sub_8175C34(u8 taskIdA);
+static void sub_8175CC8(u8 taskIdA);
+static void sub_8175CE4(void);
+static void sub_8175DA0(u8 taskIdB);
+static u8 sub_817603C(u8 page, u8 taskIdA);
+static void sub_81760FC(u8 taskIdA);
+static void sub_817651C(u8 taskIdA);
+static void sub_817624C(u8 taskIdA);
+static bool8 sub_8176AB0(u8 data, u8 taskIdA);
+static void sub_8176CA0(u8 taskIdA);
+static void sub_8176D1C(u16, u16, u16);
+static void sub_8176E40(u16 arg0, u16 palette);
+static void sub_8176EE8(struct Sprite *sprite);
+static void sub_8176F90(struct Sprite *sprite);
+static u8 sub_8177224(u16 species, s16 x, s16 y, u16 position);
+static void sub_8177388(void);
+
+static void sub_81754C8(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+static void sub_81754DC(void)
+{
+ RunTasks();
+ AnimateSprites();
+
+ if ((gMain.heldKeys & B_BUTTON)
+ && gHasHallOfFameRecords != 0
+ && gTasks[gUnknown_0203BCE2].func == sub_8175774)
+ {
+ sub_81754C8();
+ RunTasks();
+ AnimateSprites();
+ gUnknown_0203BCE5 = 1;
+ }
+ BuildOamBuffer();
+ UpdatePaletteFade();
+}
+
+static void sub_8175548(void)
+{
+ ResetBgsAndClearDma3BusyFlags(0);
+ InitBgsFromTemplates(0, gUnknown_085E6F68, 1);
+ SetBgTilemapBuffer(0, AllocZeroed(0x800));
+ LoadPalette(gUnknown_085E56F0, 0x80, 0x40);
+ InitWindows(gUnknown_085E6F6C);
+ DeactivateAllTextPrinters();
+ PutWindowTilemap(0);
+ CopyWindowToVram(0, 3);
+ ShowBg(0);
+}
+
+static void sub_81755A4(void)
+{
+ void *ptr;
+ FreeAllWindowBuffers();
+ ptr = GetBgTilemapBuffer(0);
+ if (ptr)
+ Free(ptr);
+}
+
+static void sub_81755BC(const u8 *string, u8 y, u8 a2)
+{
+ u8 x;
+ u8 color[3];
+
+ color[0] = 0;
+
+ if (a2 == 1)
+ {
+ color[1] = 3;
+ color[2] = 4;
+ }
+ else
+ {
+ color[1] = 1;
+ color[2] = 2;
+ }
+
+ x = GetStringCenterAlignXOffsetWithLetterSpacing(1, string, 0xF0, 1);
+ AddTextPrinterParameterized2(0, 1, x, y, 1, 0, color, -1, string);
+}
+
+void sub_8175620(void)
+{
+ u8 taskIdA;
+ s16 taskIdC;
+ u8 taskIdB;
+ u16 savedIme;
+
+ sub_8175CE4();
+ SetVBlankCallback(NULL);
+ InitHeap(gHeap, HEAP_SIZE);
+ ResetPaletteFade();
+ ResetTasks();
+ sub_8175548();
+
+ taskIdA = CreateTask(sub_8175744, 0);
+
+ gTasks[taskIdA].data[TDA_4] = 0;
+ gTasks[taskIdA].data[TDA_7] = 0;
+ gTasks[taskIdA].data[TDA_11] = 0;
+ gTasks[taskIdA].data[TDA_13] = 1;
+
+ while (TRUE)
+ {
+ if (sub_8176AB0(0, taskIdA))
+ break;
+ }
+
+ taskIdC = gTasks[taskIdA].data[TDA_TASK_C_ID];
+ gTasks[taskIdC].data[TDC_0] = 40;
+
+ SetGpuReg(REG_OFFSET_BG0VOFS, 0xFFFC);
+
+ taskIdB = CreateTask(sub_8175DA0, 0);
+
+ gTasks[taskIdB].data[TDB_TASK_A_ID] = taskIdA;
+ gTasks[taskIdA].data[TDA_TASK_B_ID] = taskIdB;
+
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK);
+ EnableInterrupts(INTR_FLAG_VBLANK);
+ SetVBlankCallback(sub_81754C8);
+ m4aSongNumStart(MUS_THANKFOR);
+ SetMainCallback2(sub_81754DC);
+ gUnknown_0203BCE5 = 0;
+ gUnknown_0203BCE8 = AllocZeroed(sizeof(struct Unk201C000));
+
+ sub_8177388();
+
+ gUnknown_0203BCE8->unk8E = 0;
+ gUnknown_0203BCE8->unk90 = 0;
+ gUnknown_0203BCE8->unk92 = 0;
+
+ gUnknown_0203BCE2 = taskIdA;
+}
+
+static void sub_8175744(u8 taskIdA)
+{
+ if (!gPaletteFade.active)
+ gTasks[taskIdA].func = sub_8175774;
+}
+
+static void sub_8175774(u8 taskIdA)
+{
+ u16 data1;
+
+ if (gTasks[taskIdA].data[TDA_4])
+ {
+ s16 taskIdC;
+
+ taskIdC = gTasks[taskIdA].data[TDA_TASK_C_ID];
+ gTasks[taskIdC].data[TDC_0] = 30;
+
+ gTasks[taskIdA].data[TDA_12] = 0x100;
+ gTasks[taskIdA].func = sub_8175A9C;
+ return;
+ }
+
+ gUnknown_0203BCE0 = 0;
+ data1 = gTasks[taskIdA].data[TDA_11];
+
+ if (gTasks[taskIdA].data[TDA_11] == 1)
+ {
+ gTasks[taskIdA].data[TDA_13] = data1;
+ gTasks[taskIdA].data[TDA_11] = 0;
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK);
+ gTasks[taskIdA].func = sub_8175808;
+ }
+ else if (gTasks[taskIdA].data[TDA_11] == 2)
+ {
+ gTasks[taskIdA].data[TDA_13] = data1;
+ gTasks[taskIdA].data[TDA_11] = 0;
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK);
+ gTasks[taskIdA].func = sub_81758A4;
+ }
+}
+
+static void sub_8175808(u8 taskIdA)
+{
+ if (!gPaletteFade.active)
+ {
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ sub_8176CA0(taskIdA);
+ gTasks[taskIdA].func = c2_080C9BFC;
+ }
+}
+
+static void c2_080C9BFC(u8 taskIdA)
+{
+ u16 backup;
+
+ SetVBlankCallback(NULL);
+
+ if (sub_8176AB0(gTasks[taskIdA].data[TDA_7], taskIdA))
+ {
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK);
+ EnableInterrupts(INTR_FLAG_VBLANK);
+ SetVBlankCallback(sub_81754C8);
+ gTasks[taskIdA].func = sub_8175744;
+ }
+}
+
+static void sub_81758A4(u8 taskIdA)
+{
+ if (!gPaletteFade.active)
+ {
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ sub_8176CA0(taskIdA);
+ gTasks[taskIdA].func = sub_81758E4;
+ }
+}
+
+static void sub_81758E4(u8 taskIdA)
+{
+ switch (gMain.state)
+ {
+ default:
+ case 0:
+ {
+ u16 i;
+ u16 *temp;
+
+ ResetSpriteData();
+ dp13_810BB8C();
+ FreeAllSpritePalettes();
+ gReservedSpritePaletteCount = 8;
+ LZ77UnCompVram(&gBirchHelpGfx, (void *)VRAM);
+ LZ77UnCompVram(&gBirchGrassTilemap, (void *)(VRAM + 0x3800));
+ LoadPalette(gBirchBagGrassPal[0] + 1, 1, 31 * 2);
+
+ for (i = 0; i < 0x800; i++)
+ gDecompressionBuffer[i] = 0x11;
+ for (i = 0; i < 0x800; i++)
+ (gDecompressionBuffer + 0x800)[i] = 0x22;
+ for (i = 0; i < 0x800; i++)
+ (gDecompressionBuffer + 0x1000)[i] = 0x33;
+
+ temp = (u16 *)(&gDecompressionBuffer[0x1800]);
+ temp[0] = RGB_BLACK;
+ temp[1] = RGB(31, 31, 20); // light yellow
+ temp[2] = RGB(31, 20, 20); // light red
+ temp[3] = RGB(20, 20, 31); // light blue
+
+ LoadSpriteSheet(gUnknown_085E701C);
+ LoadSpritePalette(gUnknown_085E702C);
+
+ gMain.state += 1;
+ break;
+ }
+ case 1:
+ gTasks[taskIdA].data[TDA_TASK_D_ID] = CreateTask(sub_81760FC, 0);
+ gTasks[gTasks[taskIdA].data[TDA_TASK_D_ID]].data[TDD_STATE] = 1;
+ gTasks[gTasks[taskIdA].data[TDA_TASK_D_ID]].data[TDD_TASK_A_ID] = taskIdA;
+ gTasks[gTasks[taskIdA].data[TDA_TASK_D_ID]].data[TDD_2] = gTasks[taskIdA].data[TDA_7];
+
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK);
+ SetGpuReg(REG_OFFSET_BG3HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG3VOFS, 32);
+ SetGpuReg(REG_OFFSET_BG3CNT, BGCNT_PRIORITY(3)
+ | BGCNT_CHARBASE(0)
+ | BGCNT_SCREENBASE(7)
+ | BGCNT_16COLOR
+ | BGCNT_TXT256x256);
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0
+ | DISPCNT_OBJ_1D_MAP
+ | DISPCNT_BG0_ON
+ | DISPCNT_BG3_ON
+ | DISPCNT_OBJ_ON);
+
+ gMain.state = 0;
+ gUnknown_0203BD28 = 0;
+ gTasks[taskIdA].func = sub_8175744;
+ break;
+ }
+}
+
+static void sub_8175A9C(u8 taskIdA)
+{
+ if (gTasks[taskIdA].data[TDA_12])
+ {
+ gTasks[taskIdA].data[TDA_12] -= 1;
+ return;
+ }
+
+ BeginNormalPaletteFade(0xFFFFFFFF, 12, 0, 16, RGB_BLACK);
+ gTasks[taskIdA].func = sub_8175AE4;
+}
+
+static void sub_8175AE4(u8 taskIdA)
+{
+ if (!gPaletteFade.active)
+ {
+ sub_8176CA0(taskIdA);
+ gTasks[taskIdA].func = sub_8175B1C;
+ }
+}
+
+static void sub_8175B1C(u8 taskIdA)
+{
+ sub_8175CE4();
+ ResetPaletteFade();
+ sub_8176D1C(0, 0x3800, 0);
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ BeginNormalPaletteFade(0xFFFFFFFF, 8, 16, 0, RGB_BLACK);
+
+ SetGpuReg(REG_OFFSET_BG0CNT, BGCNT_PRIORITY(0)
+ | BGCNT_CHARBASE(0)
+ | BGCNT_SCREENBASE(7)
+ | BGCNT_16COLOR
+ | BGCNT_TXT256x256);
+ EnableInterrupts(INTR_FLAG_VBLANK);
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0
+ | DISPCNT_OBJ_1D_MAP
+ | DISPCNT_BG0_ON);
+
+ gTasks[taskIdA].data[TDA_0] = 0xEB;
+ gTasks[taskIdA].func = sub_8175B90;
+}
+
+static void sub_8175B90(u8 taskIdA)
+{
+ if (gTasks[taskIdA].data[TDA_0])
+ {
+ gTasks[taskIdA].data[TDA_0] -= 1;
+ return;
+ }
+
+ BeginNormalPaletteFade(0xFFFFFFFF, 6, 0, 16, RGB_BLACK);
+ gTasks[taskIdA].func = sub_8175BD8;
+}
+
+static void sub_8175BD8(u8 taskIdA)
+{
+ if (!gPaletteFade.active)
+ {
+ sub_8176E40(0x3800, 0);
+
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0, RGB_BLACK);
+ gTasks[taskIdA].data[TDA_0] = 7200;
+ gTasks[taskIdA].func = sub_8175C34;
+ }
+}
+
+static void sub_8175C34(u8 taskIdA)
+{
+ if (!gPaletteFade.active)
+ {
+ if (gTasks[taskIdA].data[TDA_0] == 0 || gMain.newKeys)
+ {
+ FadeOutBGM(4);
+ BeginNormalPaletteFade(0xFFFFFFFF, 8, 0, 16, RGB_WHITEALPHA);
+ gTasks[taskIdA].func = sub_8175CC8;
+ return;
+ }
+
+ if (gTasks[taskIdA].data[TDA_0] == 7144)
+ FadeOutBGM(8);
+
+ if (gTasks[taskIdA].data[TDA_0] == 6840)
+ m4aSongNumStart(MUS_END);
+
+ gTasks[taskIdA].data[TDA_0] -= 1;
+ }
+}
+
+static void sub_8175CC8(u8 taskIdA)
+{
+ if (!gPaletteFade.active)
+ SoftReset(0xFF);
+}
+
+static void sub_8175CE4(void)
+{
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+
+ SetGpuReg(REG_OFFSET_BG3HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG3VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG2HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG2VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG0HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG0VOFS, 0);
+
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+
+ DmaFill16(3, 0, (void *)VRAM, VRAM_SIZE);
+ DmaFill32(3, 0, (void *)OAM, OAM_SIZE);
+ DmaFill16(3, 0, (void *)(PLTT + 2), PLTT_SIZE - 2);
+}
+
+static void sub_8175DA0(u8 taskIdB)
+{
+ int i;
+
+ switch (gTasks[taskIdB].data[TDB_0])
+ {
+ case 0:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ default:
+ if (!gPaletteFade.active)
+ {
+ gTasks[taskIdB].data[TDB_0] = 1;
+ gTasks[taskIdB].data[TDB_3] = 0x48;
+ gTasks[gTasks[taskIdB].data[TDB_TASK_A_ID]].data[TDA_14] = 0;
+ gUnknown_0203BCE0 = 0;
+ }
+ return;
+ case 1:
+ if (gTasks[taskIdB].data[TDB_3] != 0)
+ {
+ gTasks[taskIdB].data[TDB_3] -= 1;
+ return;
+ }
+ gTasks[taskIdB].data[TDB_0] += 1;
+ return;
+ case 2:
+ if (gTasks[gTasks[taskIdB].data[TDB_TASK_A_ID]].func == sub_8175774)
+ {
+ if (gTasks[taskIdB].data[TDB_CURRENT_PAGE] < PAGE_COUNT)
+ {
+ for (i = 0; i < 5; i++)
+ sub_81755BC(gCreditsEntryPointerTable[gTasks[taskIdB].data[TDB_CURRENT_PAGE]][i]->text, 5 + i * 16, gCreditsEntryPointerTable[gTasks[taskIdB].data[TDB_CURRENT_PAGE]][i]->var_1);
+
+ CopyWindowToVram(0, 2);
+
+ gTasks[taskIdB].data[TDB_CURRENT_PAGE] += 1;
+ gTasks[taskIdB].data[TDB_0] += 1;
+
+ gTasks[gTasks[taskIdB].data[TDB_TASK_A_ID]].data[TDA_14] = 1;
+
+ if (gTasks[gTasks[taskIdB].data[TDB_TASK_A_ID]].data[TDA_13] == 1)
+ BeginNormalPaletteFade(0x00000300, 0, 16, 0, COLOR_LIGHT_GREEN);
+ else
+ BeginNormalPaletteFade(0x00000300, 0, 16, 0, COLOR_DARK_GREEN);
+ return;
+ }
+ gTasks[taskIdB].data[TDB_0] = 10;
+ return;
+ }
+ gTasks[gTasks[taskIdB].data[TDB_TASK_A_ID]].data[TDA_14] = 0;
+ return;
+ case 3:
+ if (!gPaletteFade.active)
+ {
+ gTasks[taskIdB].data[TDB_3] = 0x73;
+ gTasks[taskIdB].data[TDB_0] += 1;
+ }
+ return;
+ case 4:
+ if (gTasks[taskIdB].data[TDB_3] != 0)
+ {
+ gTasks[taskIdB].data[TDB_3] -= 1;
+ return;
+ }
+
+ if (sub_817603C((u8)gTasks[taskIdB].data[TDB_CURRENT_PAGE], (u8)gTasks[taskIdB].data[TDB_TASK_A_ID]))
+ {
+ gTasks[taskIdB].data[TDB_0] += 1;
+ return;
+ }
+ gTasks[taskIdB].data[TDB_0] += 1;
+ if (gTasks[gTasks[taskIdB].data[TDB_TASK_A_ID]].data[TDA_13] == 1)
+ BeginNormalPaletteFade(0x00000300, 0, 0, 16, COLOR_LIGHT_GREEN);
+ else
+ BeginNormalPaletteFade(0x00000300, 0, 0, 16, COLOR_DARK_GREEN);
+ return;
+ case 5:
+ if (!gPaletteFade.active)
+ {
+ FillWindowPixelBuffer(0, 0);
+ CopyWindowToVram(0, 2);
+ gTasks[taskIdB].data[TDB_0] = 2;
+ }
+ return;
+ case 10:
+ gTasks[gTasks[taskIdB].data[TDB_TASK_A_ID]].data[TDA_4] = 1;
+ DestroyTask(taskIdB);
+ sub_81755A4();
+ FREE_AND_SET_NULL(gUnknown_0203BCE8);
+ return;
+ }
+}
+
+static u8 sub_817603C(u8 page, u8 taskIdA)
+{
+ // Starts with bike + ocean + morning
+
+ if (page == 6)
+ {
+ // Grass patch
+ gTasks[taskIdA].data[TDA_11] = 2;
+ }
+
+ if (page == 12)
+ {
+ // Bike + ocean + sunset
+ gTasks[taskIdA].data[TDA_7] = 1;
+ gTasks[taskIdA].data[TDA_11] = 1;
+ }
+
+ if (page == 18)
+ {
+ // Grass patch
+ gTasks[taskIdA].data[TDA_11] = 2;
+ }
+
+ if (page == 24)
+ {
+ // Bike + forest + sunset
+ gTasks[taskIdA].data[TDA_7] = 2;
+ gTasks[taskIdA].data[TDA_11] = 1;
+ }
+
+ if (page == 30)
+ {
+ // Grass patch
+ gTasks[taskIdA].data[TDA_11] = 2;
+ }
+
+ if (page == 36)
+ {
+ // Bike + forest + sunset
+ gTasks[taskIdA].data[TDA_7] = 3;
+ gTasks[taskIdA].data[TDA_11] = 1;
+ }
+
+ if (page == 42)
+ {
+ // Grass patch
+ gTasks[taskIdA].data[TDA_11] = 2;
+ }
+
+ if (page == 48)
+ {
+ // Bike + town + night
+ gTasks[taskIdA].data[TDA_7] = 4;
+ gTasks[taskIdA].data[TDA_11] = 1;
+ }
+
+ if (gTasks[taskIdA].data[TDA_11] != 0)
+ {
+ // Returns true if changed?
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void sub_81760FC(u8 taskIdD)
+{
+ u8 r2;
+
+ switch (gTasks[taskIdD].data[TDD_STATE])
+ {
+ case 0:
+ break;
+ case 1:
+ if (gUnknown_0203BCE8->unk90 == 0 && gTasks[gTasks[taskIdD].data[TDD_TASK_A_ID]].data[TDA_14] == 0)
+ break;
+ gTasks[taskIdD].data[TDD_STATE]++;
+ break;
+ case 2:
+ if (gUnknown_0203BCE8->unk8E == 71 || gTasks[gTasks[taskIdD].data[TDD_TASK_A_ID]].func != sub_8175774)
+ break;
+ r2 = sub_8177224(gUnknown_0203BCE8->unk0[gUnknown_0203BCE8->unk92], gUnknown_085E6F7C[gUnknown_0203BCE8->unk90][0], gUnknown_085E6F7C[gUnknown_0203BCE8->unk90][1], gUnknown_0203BCE8->unk90);
+ if (gUnknown_0203BCE8->unk92 < gUnknown_0203BCE8->unk94 - 1)
+ {
+ gUnknown_0203BCE8->unk92++;
+ gSprites[r2].data[3] = 50;
+ }
+ else
+ {
+ gUnknown_0203BCE8->unk92 = 0;
+ gSprites[r2].data[3] = 512;
+ }
+ gUnknown_0203BCE8->unk8E++;
+ if (gUnknown_0203BCE8->unk90 == 2)
+ gUnknown_0203BCE8->unk90 = 0;
+ else
+ gUnknown_0203BCE8->unk90++;
+ gTasks[taskIdD].data[TDD_3] = 50;
+ gTasks[taskIdD].data[TDD_STATE]++;
+ break;
+ case 3:
+ if (gTasks[taskIdD].data[TDD_3] != 0)
+ gTasks[taskIdD].data[TDD_3]--;
+ else
+ gTasks[taskIdD].data[TDD_STATE] = 1;
+ break;
+ }
+}
+
+static void sub_817624C(u8 taskIdC)
+{
+ switch (gTasks[taskIdC].data[TDC_0])
+ {
+ case 0:
+ gUnknown_0203BD26 = Sin((gTasks[taskIdC].data[TDC_5] >> 1) & 0x7F, 12);
+ gTasks[taskIdC].data[TDC_5]++;
+ break;
+ case 1:
+ if (gUnknown_0203BD26 != 0)
+ {
+ gUnknown_0203BD26 = Sin((gTasks[taskIdC].data[TDC_5] >> 1) & 0x7F, 12);
+ gTasks[taskIdC].data[TDC_5]++;
+ }
+ else
+ {
+ gSprites[gTasks[taskIdC].data[TDC_2]].data[0] = 2;
+ gTasks[taskIdC].data[TDC_5] = 0;
+ gTasks[taskIdC].data[TDC_0]++;
+ }
+ break;
+ case 2:
+ if (gTasks[taskIdC].data[TDC_5] < 64)
+ {
+ gTasks[taskIdC].data[TDC_5]++;
+ gUnknown_0203BD26 = Sin(gTasks[taskIdC].data[TDC_5] & 0x7F, 20);
+ }
+ else
+ {
+ gTasks[taskIdC].data[TDC_0]++;
+ }
+ break;
+ case 3:
+ gSprites[gTasks[taskIdC].data[TDC_2]].data[0] = 3;
+ gSprites[gTasks[taskIdC].data[TDC_3]].data[0] = 1;
+ gTasks[taskIdC].data[TDC_4] = 120;
+ gTasks[taskIdC].data[TDC_0]++;
+ break;
+ case 4:
+ if (gTasks[taskIdC].data[TDC_4] != 0)
+ {
+ gTasks[taskIdC].data[TDC_4]--;
+ }
+ else
+ {
+ gTasks[taskIdC].data[TDC_5] = 64;
+ gTasks[taskIdC].data[TDC_0]++;
+ }
+ break;
+ case 5:
+ if (gTasks[taskIdC].data[TDC_5] > 0)
+ {
+ gTasks[taskIdC].data[TDC_5]--;
+ gUnknown_0203BD26 = Sin(gTasks[taskIdC].data[TDC_5] & 0x7F, 20);
+ }
+ else
+ {
+ gSprites[gTasks[taskIdC].data[TDC_2]].data[0] = 1;
+ gTasks[taskIdC].data[TDC_0]++;
+ }
+ break;
+ case 6:
+ gTasks[taskIdC].data[TDC_0] = 50;
+ break;
+ case 10:
+ gSprites[gTasks[taskIdC].data[TDC_3]].data[0] = 2;
+ gTasks[taskIdC].data[TDC_0] = 50;
+ break;
+ case 20:
+ gSprites[gTasks[taskIdC].data[TDC_2]].data[0] = 4;
+ gTasks[taskIdC].data[TDC_0] = 50;
+ break;
+ case 30:
+ gSprites[gTasks[taskIdC].data[TDC_2]].data[0] = 5;
+ gSprites[gTasks[taskIdC].data[TDC_3]].data[0] = 3;
+ gTasks[taskIdC].data[TDC_0] = 50;
+ break;
+ case 50:
+ gTasks[taskIdC].data[TDC_0] = 0;
+ break;
+ }
+}
+
+static void sub_817651C(u8 taskIdE)
+{
+ s16 taskIdC;
+
+ switch (gTasks[taskIdE].data[TDE_0])
+ {
+ default:
+ case 0:
+ if (gTasks[taskIdE].data[TDE_1] != 0x7FFF)
+ {
+
+ if (gTasks[gTasks[gTasks[taskIdE].data[TDE_TASK_A_ID]].data[TDA_TASK_B_ID]].data[TDB_CURRENT_PAGE] == 2)
+ {
+ gTasks[gTasks[gTasks[taskIdE].data[TDE_TASK_A_ID]].data[TDA_TASK_C_ID]].data[TDC_0] = 20;
+ gTasks[taskIdE].data[TDE_1] = 0x7FFF;
+ }
+ }
+ sub_817B540(0);
+ break;
+ case 1:
+ sub_817B540(0);
+ break;
+ case 2:
+ if (gTasks[taskIdE].data[TDE_1] != 0x7FFF)
+ {
+ taskIdC = gTasks[gTasks[taskIdE].data[TDE_TASK_A_ID]].data[TDA_TASK_C_ID];
+
+ // Floor to multiple of 128
+ if ((gTasks[taskIdC].data[TDC_5] & -128) == 640)
+ {
+ gTasks[taskIdC].data[TDC_0] = 1;
+ gTasks[taskIdE].data[TDE_1] = 0x7FFF;
+ }
+ }
+ sub_817B540(1);
+ break;
+ case 3:
+ if (gTasks[taskIdE].data[TDE_1] != 0x7FFF)
+ {
+
+ if (gTasks[taskIdE].data[TDE_1] == 0x248)
+ {
+ gTasks[gTasks[gTasks[taskIdE].data[TDE_TASK_A_ID]].data[TDA_TASK_C_ID]].data[TDC_0] = 10;
+ gTasks[taskIdE].data[TDE_1] = 0x7FFF;
+ }
+ else
+ {
+ gTasks[taskIdE].data[TDE_1] += 1;
+ }
+ }
+ sub_817B540(1);
+ break;
+ case 4:
+ sub_817B540(2);
+ break;
+ }
+}
+
+static void sub_817664C(u8 data, u8 taskIdA)
+{
+ switch (data)
+ {
+ case 0:
+ gSprites[gTasks[taskIdA].data[TDA_PLAYER_CYCLIST]].invisible = 0;
+ gSprites[gTasks[taskIdA].data[TDA_RIVAL_CYCLIST]].invisible = 0;
+ gSprites[gTasks[taskIdA].data[TDA_PLAYER_CYCLIST]].pos1.x = 272;
+ gSprites[gTasks[taskIdA].data[TDA_RIVAL_CYCLIST]].pos1.x = 272;
+ gSprites[gTasks[taskIdA].data[TDA_PLAYER_CYCLIST]].pos1.y = 46;
+ gSprites[gTasks[taskIdA].data[TDA_RIVAL_CYCLIST]].pos1.y = 46;
+ gSprites[gTasks[taskIdA].data[TDA_PLAYER_CYCLIST]].data[0] = 0;
+ gSprites[gTasks[taskIdA].data[TDA_RIVAL_CYCLIST]].data[0] = 0;
+ gTasks[taskIdA].data[TDA_0] = sub_817B3DC(0, 0x2000, 0x20, 8);
+ break;
+ case 1:
+ gSprites[gTasks[taskIdA].data[TDA_PLAYER_CYCLIST]].invisible = 0;
+ gSprites[gTasks[taskIdA].data[TDA_RIVAL_CYCLIST]].invisible = 0;
+ gSprites[gTasks[taskIdA].data[TDA_PLAYER_CYCLIST]].pos1.x = 120;
+ gSprites[gTasks[taskIdA].data[TDA_RIVAL_CYCLIST]].pos1.x = 272;
+ gSprites[gTasks[taskIdA].data[TDA_PLAYER_CYCLIST]].pos1.y = 46;
+ gSprites[gTasks[taskIdA].data[TDA_RIVAL_CYCLIST]].pos1.y = 46;
+ gSprites[gTasks[taskIdA].data[TDA_PLAYER_CYCLIST]].data[0] = 0;
+ gSprites[gTasks[taskIdA].data[TDA_RIVAL_CYCLIST]].data[0] = 0;
+ gTasks[taskIdA].data[TDA_0] = sub_817B3DC(0, 0x2000, 0x20, 8);
+ break;
+ case 2:
+ gSprites[gTasks[taskIdA].data[TDA_PLAYER_CYCLIST]].invisible = 0;
+ gSprites[gTasks[taskIdA].data[TDA_RIVAL_CYCLIST]].invisible = 0;
+ gSprites[gTasks[taskIdA].data[TDA_PLAYER_CYCLIST]].pos1.x = 120;
+ gSprites[gTasks[taskIdA].data[TDA_RIVAL_CYCLIST]].pos1.x = 272;
+ gSprites[gTasks[taskIdA].data[TDA_PLAYER_CYCLIST]].pos1.y = 46;
+ gSprites[gTasks[taskIdA].data[TDA_RIVAL_CYCLIST]].pos1.y = 46;
+ gSprites[gTasks[taskIdA].data[TDA_PLAYER_CYCLIST]].data[0] = 0;
+ gSprites[gTasks[taskIdA].data[TDA_RIVAL_CYCLIST]].data[0] = 0;
+ gTasks[taskIdA].data[TDA_0] = sub_817B3DC(1, 0x2000, 0x200, 8);
+ break;
+ case 3:
+ gSprites[gTasks[taskIdA].data[TDA_PLAYER_CYCLIST]].invisible = 0;
+ gSprites[gTasks[taskIdA].data[TDA_RIVAL_CYCLIST]].invisible = 0;
+ gSprites[gTasks[taskIdA].data[TDA_PLAYER_CYCLIST]].pos1.x = 120;
+ gSprites[gTasks[taskIdA].data[TDA_RIVAL_CYCLIST]].pos1.x = -32;
+ gSprites[gTasks[taskIdA].data[TDA_PLAYER_CYCLIST]].pos1.y = 46;
+ gSprites[gTasks[taskIdA].data[TDA_RIVAL_CYCLIST]].pos1.y = 46;
+ gSprites[gTasks[taskIdA].data[TDA_PLAYER_CYCLIST]].data[0] = 0;
+ gSprites[gTasks[taskIdA].data[TDA_RIVAL_CYCLIST]].data[0] = 0;
+ gTasks[taskIdA].data[TDA_0] = sub_817B3DC(1, 0x2000, 0x200, 8);
+ break;
+ case 4:
+ gSprites[gTasks[taskIdA].data[TDA_PLAYER_CYCLIST]].invisible = 0;
+ gSprites[gTasks[taskIdA].data[TDA_RIVAL_CYCLIST]].invisible = 0;
+ gSprites[gTasks[taskIdA].data[TDA_PLAYER_CYCLIST]].pos1.x = 88;
+ gSprites[gTasks[taskIdA].data[TDA_RIVAL_CYCLIST]].pos1.x = 152;
+ gSprites[gTasks[taskIdA].data[TDA_PLAYER_CYCLIST]].pos1.y = 46;
+ gSprites[gTasks[taskIdA].data[TDA_RIVAL_CYCLIST]].pos1.y = 46;
+ gSprites[gTasks[taskIdA].data[TDA_PLAYER_CYCLIST]].data[0] = 0;
+ gSprites[gTasks[taskIdA].data[TDA_RIVAL_CYCLIST]].data[0] = 0;
+ gTasks[taskIdA].data[TDA_0] = sub_817B3DC(2, 0x2000, 0x200, 8);
+ break;
+ }
+
+ gTasks[taskIdA].data[TDA_TASK_E_ID] = CreateTask(sub_817651C, 0);
+ gTasks[gTasks[taskIdA].data[TDA_TASK_E_ID]].data[TDE_0] = data;
+ gTasks[gTasks[taskIdA].data[TDA_TASK_E_ID]].data[TDE_1] = 0;
+ gTasks[gTasks[taskIdA].data[TDA_TASK_E_ID]].data[TDE_TASK_A_ID] = taskIdA;
+
+ gTasks[taskIdA].data[TDA_TASK_C_ID] = CreateTask(sub_817624C, 0);
+ gTasks[gTasks[taskIdA].data[TDA_TASK_C_ID]].data[TDC_0] = 0;
+ gTasks[gTasks[taskIdA].data[TDA_TASK_C_ID]].data[TDC_1] = taskIdA;
+ gTasks[gTasks[taskIdA].data[TDA_TASK_C_ID]].data[TDC_2] = gTasks[taskIdA].data[TDA_PLAYER_CYCLIST];
+ gTasks[gTasks[taskIdA].data[TDA_TASK_C_ID]].data[TDC_3] = gTasks[taskIdA].data[TDA_RIVAL_CYCLIST];
+ gTasks[gTasks[taskIdA].data[TDA_TASK_C_ID]].data[TDC_4] = 0;
+
+ if (data == 2)
+ gTasks[gTasks[taskIdA].data[TDA_TASK_C_ID]].data[TDC_5] = 0x45;
+}
+
+static bool8 sub_8176AB0(u8 data, u8 taskIdA)
+{
+ u8 spriteId;
+
+ switch (gMain.state)
+ {
+ default:
+ case 0:
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ SetGpuReg(REG_OFFSET_BG3HOFS, 8);
+ SetGpuReg(REG_OFFSET_BG3VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG2HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG2VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1VOFS, 0);
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ gMain.state = 1;
+ break;
+ case 1:
+ gUnknown_0203BD24 = 34;
+ gUnknown_0203BD26 = 0;
+ sub_817B1C8(data);
+ gMain.state += 1;
+ break;
+ case 2:
+ if (gSaveBlock2Ptr->playerGender == MALE)
+ {
+ LoadCompressedObjectPic(gUnknown_085F5334);
+ LoadCompressedObjectPic(gUnknown_085F53BC);
+ LoadCompressedObjectPic(gUnknown_085F5354);
+ LoadSpritePalettes(gUnknown_085F5384);
+
+ spriteId = intro_create_brendan_sprite(120, 46);
+ gTasks[taskIdA].data[TDA_PLAYER_CYCLIST] = spriteId;
+ gSprites[spriteId].callback = sub_8176EE8;
+ gSprites[spriteId].anims = gUnknown_085E6FD0;
+
+ spriteId = intro_create_may_sprite(272, 46);
+ gTasks[taskIdA].data[TDA_RIVAL_CYCLIST] = spriteId;
+ gSprites[spriteId].callback = sub_8176F90;
+ gSprites[spriteId].anims = gUnknown_085E7010;
+ }
+ else
+ {
+ LoadCompressedObjectPic(gUnknown_085F5344);
+ LoadCompressedObjectPic(gUnknown_085F53AC);
+ LoadCompressedObjectPic(gUnknown_085F5354);
+ LoadSpritePalettes(gUnknown_085F5384);
+
+ spriteId = intro_create_may_sprite(120, 46);
+ gTasks[taskIdA].data[TDA_PLAYER_CYCLIST] = spriteId;
+ gSprites[spriteId].callback = sub_8176EE8;
+ gSprites[spriteId].anims = gUnknown_085E6FD0;
+
+ spriteId = intro_create_brendan_sprite(272, 46);
+ gTasks[taskIdA].data[TDA_RIVAL_CYCLIST] = spriteId;
+ gSprites[spriteId].callback = sub_8176F90;
+ gSprites[spriteId].anims = gUnknown_085E7010;
+ };
+ gMain.state += 1;
+ break;
+ case 3:
+ sub_817664C(data, taskIdA);
+ sub_817B3A8(data);
+ gMain.state = 0;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void sub_8176CA0(u8 taskIdA)
+{
+ if (gTasks[taskIdA].data[TDA_0] != 0)
+ {
+ DestroyTask(gTasks[taskIdA].data[TDA_0]);
+ gTasks[taskIdA].data[TDA_0] = 0;
+ }
+
+ if (gTasks[taskIdA].data[TDA_TASK_C_ID] != 0)
+ {
+ DestroyTask(gTasks[taskIdA].data[TDA_TASK_C_ID]);
+ gTasks[taskIdA].data[TDA_TASK_C_ID] = 0;
+ }
+
+ if (gTasks[taskIdA].data[TDA_TASK_E_ID] != 0)
+ {
+ DestroyTask(gTasks[taskIdA].data[TDA_TASK_E_ID]);
+ gTasks[taskIdA].data[TDA_TASK_E_ID] = 0;
+ }
+
+ if (gTasks[taskIdA].data[TDA_TASK_D_ID] != 0)
+ {
+ DestroyTask(gTasks[taskIdA].data[TDA_TASK_D_ID]);
+ gTasks[taskIdA].data[TDA_TASK_D_ID] = 0;
+ }
+
+ gUnknown_0203BD28 = 1;
+}
+
+static void sub_8176D1C(u16 arg0, u16 arg1, u16 arg2)
+{
+ u16 baseTile;
+ u16 i;
+
+ LZ77UnCompVram(gCreditsCopyrightEnd_Gfx, (void *)(VRAM + arg0));
+ LoadPalette(gIntroCopyright_Pal, arg2, sizeof(gIntroCopyright_Pal));
+
+ baseTile = (arg2 / 16) << 12;
+
+ for (i = 0; i < 32 * 32; i++)
+ ((u16 *) (VRAM + arg1))[i] = baseTile + 1;
+}
+
+static u16 sub_8176D78(u8 arg0)
+{
+ u16 out = (arg0 & 0x3F) + 80;
+
+ if (arg0 == 0xFF)
+ return 1;
+
+ if (arg0 & (1 << 7))
+ out |= 1 << 11;
+ if (arg0 & (1 << 6))
+ out |= 1 << 10;
+
+ return out;
+}
+
+static void sub_8176DBC(const u8 arg0[], u8 baseX, u8 baseY, u16 arg3, u16 palette)
+{
+ u8 y, x;
+ const u16 tileOffset = (palette / 16) << 12;
+
+ for (y = 0; y < 5; y++)
+ {
+ for (x = 0; x < 3; x++)
+ ((u16 *) (VRAM + arg3 + (baseY + y) * 64))[baseX + x] = tileOffset + sub_8176D78(arg0[y * 3 + x]);
+ }
+}
+
+static void sub_8176E40(u16 arg0, u16 palette)
+{
+ u16 pos;
+ u16 baseTile = (palette / 16) << 12;
+
+ for (pos = 0; pos < 32 * 32; pos++)
+ ((u16 *) (VRAM + arg0))[pos] = baseTile + 1;
+
+ sub_8176DBC(gUnknown_085E5BAC, 3, 7, arg0, palette);
+ sub_8176DBC(gUnknown_085E5BBB, 7, 7, arg0, palette);
+ sub_8176DBC(gUnknown_085E5BCA, 11, 7, arg0, palette);
+ sub_8176DBC(gUnknown_085E5BCA, 16, 7, arg0, palette);
+ sub_8176DBC(gUnknown_085E5BD9, 20, 7, arg0, palette);
+ sub_8176DBC(gUnknown_085E5BE8, 24, 7, arg0, palette);
+}
+
+static void sub_8176EE8(struct Sprite *sprite)
+{
+ if (gUnknown_0203BD28 != 0)
+ {
+ DestroySprite(sprite);
+ return;
+ }
+
+ switch (sprite->data[0])
+ {
+ case 0:
+ StartSpriteAnimIfDifferent(sprite, 0);
+ break;
+ case 1:
+ StartSpriteAnimIfDifferent(sprite, 1);
+ if (sprite->pos1.x > -32)
+ sprite->pos1.x -= 1;
+ break;
+ case 2:
+ StartSpriteAnimIfDifferent(sprite, 2);
+ break;
+ case 3:
+ StartSpriteAnimIfDifferent(sprite, 3);
+ break;
+ case 4:
+ StartSpriteAnimIfDifferent(sprite, 0);
+ if (sprite->pos1.x > 120)
+ sprite->pos1.x -= 1;
+ break;
+ case 5:
+ StartSpriteAnimIfDifferent(sprite, 0);
+ if (sprite->pos1.x > -32)
+ sprite->pos1.x -= 1;
+ break;
+ }
+}
+
+static void sub_8176F90(struct Sprite *sprite)
+{
+ if (gUnknown_0203BD28 != 0)
+ {
+ DestroySprite(sprite);
+ return;
+ }
+
+ switch (sprite->data[0])
+ {
+ case 0:
+ sprite->pos2.y = 0;
+ StartSpriteAnimIfDifferent(sprite, 0);
+ break;
+ case 1:
+ if (sprite->pos1.x > 200)
+ StartSpriteAnimIfDifferent(sprite, 1);
+ else
+ StartSpriteAnimIfDifferent(sprite, 2);
+ if (sprite->pos1.x > -32)
+ sprite->pos1.x -= 2;
+ sprite->pos2.y = -gUnknown_0203BD26;
+ break;
+ case 2:
+ sprite->data[7] += 1;
+ StartSpriteAnimIfDifferent(sprite, 0);
+ if ((sprite->data[7] & 3) == 0)
+ sprite->pos1.x += 1;
+ break;
+ case 3:
+ StartSpriteAnimIfDifferent(sprite, 0);
+ if (sprite->pos1.x > -32)
+ sprite->pos1.x -= 1;
+ break;
+ }
+}
+
+static void sub_8177050(struct Sprite *sprite)
+{
+ if (gUnknown_0203BD28)
+ {
+ sub_818D820(sprite->data[6]);
+ return;
+ }
+
+ sprite->data[7] += 1;
+ switch (sprite->data[0])
+ {
+ case 0:
+ default:
+ sprite->oam.affineMode = 1;
+ sprite->oam.matrixNum = sprite->data[1];
+ sprite->data[2] = 16;
+ SetOamMatrix(sprite->data[1], 0x10000 / sprite->data[2], 0, 0, 0x10000 / sprite->data[2]);
+ sprite->invisible = FALSE;
+ sprite->data[0] = 1;
+ break;
+ case 1:
+ if (sprite->data[2] < 256)
+ {
+ sprite->data[2] += 8;
+ SetOamMatrix(sprite->data[1], 0x10000 / sprite->data[2], 0, 0, 0x10000 / sprite->data[2]);
+ }
+ else
+ {
+ sprite->data[0] += 1;
+ }
+ switch (sprite->data[1])
+ {
+ case 1:
+ if ((sprite->data[7] & 3) == 0)
+ sprite->pos1.y += 1;
+ sprite->pos1.x -= 2;
+ break;
+ case 2:
+ break;
+ case 3:
+ if ((sprite->data[7] & 3) == 0)
+ sprite->pos1.y += 1;
+ sprite->pos1.x += 2;
+ break;
+ }
+ break;
+ case 2:
+ if (sprite->data[3] != 0)
+ {
+ sprite->data[3] -= 1;
+ }
+ else
+ {
+ SetGpuReg(REG_OFFSET_BLDCNT, 0xF40);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0x10);
+ sprite->oam.objMode = 1;
+ sprite->data[3] = 16;
+ sprite->data[0] += 1;
+ }
+ break;
+ case 3:
+ if (sprite->data[3] != 0)
+ {
+ int data3;
+
+ sprite->data[3] -= 1;
+
+ data3 = 16 - sprite->data[3];
+ SetGpuReg(REG_OFFSET_BLDALPHA, (data3 << 8) + sprite->data[3]);
+ }
+ else
+ {
+ sprite->invisible = TRUE;
+ sprite->data[0] = 9;
+ }
+ break;
+ case 9:
+ sprite->data[0] += 1;
+ break;
+ case 10:
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ sub_818D820(sprite->data[6]);
+ break;
+ }
+}
+
+static u8 sub_8177224(u16 species, s16 x, s16 y, u16 position)
+{
+ u8 spriteId;
+ u8 spriteId2;
+
+ spriteId = sub_80C0E9C(species, x, y, position);
+ gSprites[spriteId].oam.priority = 1;
+ gSprites[spriteId].data[1] = position + 1;
+ gSprites[spriteId].invisible = TRUE;
+ gSprites[spriteId].callback = sub_8177050;
+ gSprites[spriteId].data[6] = spriteId;
+
+ spriteId2 = CreateSprite(&gUnknown_085E7068, gSprites[spriteId].pos1.x, gSprites[spriteId].pos1.y, 1);
+ gSprites[spriteId2].data[0] = spriteId;
+
+ StartSpriteAnimIfDifferent(&gSprites[spriteId2], position);
+
+ return spriteId;
+}
+
+static void sub_81772B8(struct Sprite *sprite)
+{
+ if (gSprites[sprite->data[0]].data[0] == 10 || gUnknown_0203BD28)
+ {
+ DestroySprite(sprite);
+ return;
+ }
+
+ sprite->invisible = gSprites[sprite->data[0]].invisible;
+ sprite->oam.objMode = gSprites[sprite->data[0]].oam.objMode;
+ sprite->oam.affineMode = gSprites[sprite->data[0]].oam.affineMode;
+ sprite->oam.matrixNum = gSprites[sprite->data[0]].oam.matrixNum;
+ sprite->pos1.x = gSprites[sprite->data[0]].pos1.x;
+ sprite->pos1.y = gSprites[sprite->data[0]].pos1.y;
+}
+
+static void sub_8177388(void)
+{
+ u16 starter = SpeciesToNationalPokedexNum(GetStarterPokemon(VarGet(VAR_FIRST_POKE)));
+ u16 page;
+ u16 dexNum;
+ u16 j;
+
+ for (dexNum = 1, j = 0; dexNum < 386; dexNum++)
+ {
+ if (GetSetPokedexFlag(dexNum, 1))
+ {
+ gUnknown_0203BCE8->unk96[j] = dexNum;
+ j++;
+ }
+ }
+
+ for (dexNum = j; dexNum < 386; dexNum++)
+ gUnknown_0203BCE8->unk96[dexNum] = 0;
+
+ gUnknown_0203BCE8->unk39A = j;
+ if (gUnknown_0203BCE8->unk39A < 71)
+ gUnknown_0203BCE8->unk94 = j;
+ else
+ gUnknown_0203BCE8->unk94 = 71;
+
+ j = 0;
+ do
+ {
+ page = Random() % gUnknown_0203BCE8->unk39A;
+ gUnknown_0203BCE8->unk0[j] = gUnknown_0203BCE8->unk96[page];
+
+ j++;
+ gUnknown_0203BCE8->unk96[page] = 0;
+ gUnknown_0203BCE8->unk39A--;
+ if (page != gUnknown_0203BCE8->unk39A)
+ {
+ gUnknown_0203BCE8->unk96[page] = gUnknown_0203BCE8->unk96[gUnknown_0203BCE8->unk39A];
+ gUnknown_0203BCE8->unk96[gUnknown_0203BCE8->unk39A] = 0;
+ }
+ }
+ while (gUnknown_0203BCE8->unk39A != 0 && j < 71);
+
+ if (gUnknown_0203BCE8->unk94 < 71)
+ {
+ for (j = gUnknown_0203BCE8->unk94, page = 0; j < 71; j++)
+ {
+ gUnknown_0203BCE8->unk0[j] = gUnknown_0203BCE8->unk0[page];
+
+ page++;
+ if (page == gUnknown_0203BCE8->unk94)
+ page = 0;
+ }
+ gUnknown_0203BCE8->unk0[70] = starter;
+ }
+ else
+ {
+ for (dexNum = 0; gUnknown_0203BCE8->unk0[dexNum] != starter && dexNum < 71; dexNum++);
+
+ if (dexNum < gUnknown_0203BCE8->unk94 - 1)
+ {
+ gUnknown_0203BCE8->unk0[dexNum] = gUnknown_0203BCE8->unk0[70];
+ gUnknown_0203BCE8->unk0[70] = starter;
+ }
+ else
+ {
+ gUnknown_0203BCE8->unk0[70] = starter;
+ }
+ }
+ gUnknown_0203BCE8->unk94 = 71;
+}
diff --git a/src/daycare.c b/src/daycare.c
index 89c0a48d8..d567ff79a 100644
--- a/src/daycare.c
+++ b/src/daycare.c
@@ -41,12 +41,11 @@ extern const u8 gDaycareText_PlayOther[];
extern u8 GetCursorSelectionMonId(void);
extern u16 ItemIdToBattleMoveId(u16);
extern s32 ListMenuHandleInputGetItemId(u8);
-extern void sub_81AE6C8(u8, u16*, u16*);
+extern void DestroyListMenuTask(u8, u16*, u16*);
extern void sub_819746C(u8, bool8);
extern void NewMenuHelpers_DrawStdWindowFrame(u8, bool8);
extern void sub_81B9328(void);
-extern void sub_81AF078(u32, bool8, struct ListMenu *);
-extern void c2_exit_to_overworld_2_switch(void);
+extern void CB2_ReturnToField(void);
// this file's functions
static void ClearDaycareMonMisc(struct DaycareMiscMon *misc);
@@ -79,18 +78,18 @@ static const struct ListMenuTemplate sDaycareListMenuLevelTemplate =
.unk_08 = DaycarePrintMonInfo,
.totalItems = 3,
.maxShowed = 3,
- .unk_10 = 0,
+ .windowId = 0,
.unk_11 = 0,
.unk_12 = 8,
- .cursor_Y = 0,
+ .cursor_X = 0,
.upText_Y = 1,
- .cursorColor = 2,
- .fillColor = 1,
- .cursorShadowColor = 3,
- .unk_16_0 = TRUE,
- .spaceBetweenItems = 0,
- .unk_16_7 = FALSE,
- .unk_17_0 = 1,
+ .cursorPal = 2,
+ .fillValue = 1,
+ .cursorShadowPal = 3,
+ .lettersSpacing = 1,
+ .unk_16_3 = 0,
+ .scrollMultiple = LIST_NO_MULTIPLE_SCROLL,
+ .fontId = 1,
.cursorKind = 0
};
@@ -1271,7 +1270,7 @@ static void Task_HandleDaycareLevelMenuInput(u8 taskId)
gSpecialVar_Result = 2;
break;
}
- sub_81AE6C8(gTasks[taskId].tMenuListTaskId, NULL, NULL);
+ DestroyListMenuTask(gTasks[taskId].tMenuListTaskId, NULL, NULL);
sub_819746C(gTasks[taskId].tWindowId, TRUE);
RemoveWindow(gTasks[taskId].tWindowId);
DestroyTask(taskId);
@@ -1280,7 +1279,7 @@ static void Task_HandleDaycareLevelMenuInput(u8 taskId)
else if (gMain.newKeys & B_BUTTON)
{
gSpecialVar_Result = 2;
- sub_81AE6C8(gTasks[taskId].tMenuListTaskId, NULL, NULL);
+ DestroyListMenuTask(gTasks[taskId].tMenuListTaskId, NULL, NULL);
sub_819746C(gTasks[taskId].tWindowId, TRUE);
RemoveWindow(gTasks[taskId].tWindowId);
DestroyTask(taskId);
@@ -1299,7 +1298,7 @@ void ShowDaycareLevelMenu(void)
NewMenuHelpers_DrawStdWindowFrame(windowId, FALSE);
menuTemplate = sDaycareListMenuLevelTemplate;
- menuTemplate.unk_10 = windowId;
+ menuTemplate.windowId = windowId;
listMenuTaskId = ListMenuInit(&menuTemplate, 0, 0);
CopyWindowToVram(windowId, 3);
@@ -1315,5 +1314,5 @@ void ShowDaycareLevelMenu(void)
void ChooseSendDaycareMon(void)
{
sub_81B9328();
- gMain.savedCallback = c2_exit_to_overworld_2_switch;
+ gMain.savedCallback = CB2_ReturnToField;
}
diff --git a/src/decompress.c b/src/decompress.c
index 8e8827194..1d4165d75 100644
--- a/src/decompress.c
+++ b/src/decompress.c
@@ -117,7 +117,7 @@ void Unused_LZDecompressWramIndirect(const void **src, void *dest)
}
// This one (unused) function is really challenging, won't even try to decompile it.
-__attribute__((naked))
+NAKED
void sub_803471C()
{
asm(".syntax unified\n\
diff --git a/src/decoration.c b/src/decoration.c
index db19ff4c6..1fc94c80e 100644
--- a/src/decoration.c
+++ b/src/decoration.c
@@ -111,7 +111,7 @@ void sub_812719C(u8 taskId);
void sub_81271CC(u8 taskId);
void sub_8127268(u8 taskId);
void sub_8127454(u8 *dest, u16 decorId);
-void sub_8127480(u32 a0, bool8 flag, struct ListMenu *menu);
+void sub_8127480(s32 a0, bool8 flag, struct ListMenu *menu);
void sub_81274A0(u8 a0, s32 a1, u8 a2);
void sub_8127620(u8 taskId);
void sub_812764C(u8 taskId);
@@ -560,7 +560,7 @@ void SecretBasePC_Cancel(u8 taskId)
}
else
{
- sub_816B060(taskId);
+ ReshowPlayerPC(taskId);
}
}
@@ -799,7 +799,7 @@ void sub_8127330(u8 taskId)
sDecorPCBuffer->items[i].name = sDecorPCBuffer->names[i];
sDecorPCBuffer->items[i].id = -2;
gMultiuseListMenuTemplate = gUnknown_085A6BD0;
- gMultiuseListMenuTemplate.unk_10 = sDecorMenuWindowIndices[1];
+ gMultiuseListMenuTemplate.windowId = sDecorMenuWindowIndices[1];
gMultiuseListMenuTemplate.totalItems = sDecorPCBuffer->unk_520;
gMultiuseListMenuTemplate.items = sDecorPCBuffer->items;
gMultiuseListMenuTemplate.maxShowed = sDecorPCBuffer->unk_521;
@@ -811,7 +811,7 @@ void sub_8127454(u8 *dest, u16 decorId)
StringAppend(dest, gDecorations[decorId].name);
}
-void sub_8127480(u32 a0, bool8 flag, struct ListMenu *menu)
+void sub_8127480(s32 a0, bool8 flag, struct ListMenu *menu)
{
if (flag != TRUE)
{
@@ -890,7 +890,7 @@ void sub_812764C(u8 taskId)
if (!gPaletteFade.active)
{
input = ListMenuHandleInputGetItemId(data[13]);
- sub_81AE860(data[13], &sSecretBasePCSelectDecorPageNo, &sSecretBasePCSelectDecorLineNo);
+ ListMenuGetScrollAndRow(data[13], &sSecretBasePCSelectDecorPageNo, &sSecretBasePCSelectDecorLineNo);
switch (input)
{
case -1:
@@ -903,7 +903,7 @@ void sub_812764C(u8 taskId)
PlaySE(SE_SELECT);
gCurDecorationIndex = input;
sub_8127554();
- sub_81AE6C8(data[13], &sSecretBasePCSelectDecorPageNo, &sSecretBasePCSelectDecorLineNo);
+ DestroyListMenuTask(data[13], &sSecretBasePCSelectDecorPageNo, &sSecretBasePCSelectDecorLineNo);
sub_8126A58(1);
sub_81277A8();
free(sDecorPCBuffer);
@@ -1072,7 +1072,7 @@ void sub_8127A8C(u8 taskId)
data = gTasks[taskId].data;
sub_8127554();
sub_81277A8();
- sub_81AE6C8(data[13], NULL, NULL);
+ DestroyListMenuTask(data[13], NULL, NULL);
free(sDecorPCBuffer);
sub_8126E44(taskId);
}
@@ -1292,7 +1292,7 @@ void sub_8128060(u8 taskId)
gTasks[taskId].data[2] = 2;
break;
case 2:
- if (sub_80ABDFC() == TRUE)
+ if (IsWeatherNotFadingIn() == TRUE)
{
gTasks[taskId].data[12] = 0;
sub_8128FD8(taskId);
@@ -1303,12 +1303,12 @@ void sub_8128060(u8 taskId)
void ConfigureCameraObjectForPlacingDecoration(struct PlaceDecorationGraphicsDataBuffer *data, u8 decor)
{
- sDecor_CameraSpriteObjectIdx1 = gSprites[gUnknown_03005DD0.unk4].data[0];
- gUnknown_03005DD0.unk4 = gpu_pal_decompress_alloc_tag_and_upload(data, decor);
- gSprites[gUnknown_03005DD0.unk4].oam.priority = 1;
- gSprites[gUnknown_03005DD0.unk4].callback = sub_81292D0;
- gSprites[gUnknown_03005DD0.unk4].pos1.x = gUnknown_085A7250[data->decoration->shape].x;
- gSprites[gUnknown_03005DD0.unk4].pos1.y = gUnknown_085A7250[data->decoration->shape].y;
+ sDecor_CameraSpriteObjectIdx1 = gSprites[gUnknown_03005DD0.spriteId].data[0];
+ gUnknown_03005DD0.spriteId = gpu_pal_decompress_alloc_tag_and_upload(data, decor);
+ gSprites[gUnknown_03005DD0.spriteId].oam.priority = 1;
+ gSprites[gUnknown_03005DD0.spriteId].callback = sub_81292D0;
+ gSprites[gUnknown_03005DD0.spriteId].pos1.x = gUnknown_085A7250[data->decoration->shape].x;
+ gSprites[gUnknown_03005DD0.spriteId].pos1.y = gUnknown_085A7250[data->decoration->shape].y;
}
void SetUpPlacingDecorationPlayerAvatar(u8 taskId, struct PlaceDecorationGraphicsDataBuffer *data)
@@ -1330,7 +1330,7 @@ void SetUpPlacingDecorationPlayerAvatar(u8 taskId, struct PlaceDecorationGraphic
}
gSprites[sDecor_CameraSpriteObjectIdx2].oam.priority = 1;
DestroySprite(&gSprites[sDecor_CameraSpriteObjectIdx1]);
- sDecor_CameraSpriteObjectIdx1 = gUnknown_03005DD0.unk4;
+ sDecor_CameraSpriteObjectIdx1 = gUnknown_03005DD0.spriteId;
}
void sub_812826C(u8 taskId)
@@ -1682,7 +1682,7 @@ void c1_overworld_prev_quest(u8 taskId)
sub_812A3C8();
FreeSpritePaletteByTag(OVERWORLD_PLACE_DECOR_SELECTOR_PAL_TAG);
gFieldCallback = sub_8128CD4;
- SetMainCallback2(c2_exit_to_overworld_2_switch);
+ SetMainCallback2(CB2_ReturnToField);
DestroyTask(taskId);
break;
}
@@ -1708,7 +1708,7 @@ void sub_8128C64(u8 taskId)
data[2] ++;
break;
case 3:
- if (sub_80ABDFC() == TRUE)
+ if (IsWeatherNotFadingIn() == TRUE)
{
gTasks[taskId].func = sub_812764C;
}
@@ -2218,7 +2218,7 @@ void sub_81298EC(u8 taskId)
gTasks[taskId].data[2] = 3;
break;
case 3:
- if (sub_80ABDFC() == TRUE)
+ if (IsWeatherNotFadingIn() == TRUE)
{
StringExpandPlaceholders(gStringVar4, gText_DecorationReturnedToPC);
DisplayItemMessageOnField(taskId, gStringVar4, sub_8129D64);
@@ -2249,9 +2249,9 @@ bool8 sub_81299AC(u8 taskId)
void SetUpPuttingAwayDecorationPlayerAvatar(void)
{
player_get_direction_lower_nybble();
- sDecor_CameraSpriteObjectIdx1 = gSprites[gUnknown_03005DD0.unk4].data[0];
+ sDecor_CameraSpriteObjectIdx1 = gSprites[gUnknown_03005DD0.spriteId].data[0];
sub_812A39C();
- gUnknown_03005DD0.unk4 = CreateSprite(&gUnknown_085A7404, 0x78, 0x50, 0);
+ gUnknown_03005DD0.spriteId = CreateSprite(&gUnknown_085A7404, 0x78, 0x50, 0);
if (gSaveBlock2Ptr->playerGender == MALE)
{
sDecor_CameraSpriteObjectIdx2 = AddPseudoFieldObject(0xC1, SpriteCallbackDummy, 0x88, 0x48, 0);
@@ -2262,7 +2262,7 @@ void SetUpPuttingAwayDecorationPlayerAvatar(void)
}
gSprites[sDecor_CameraSpriteObjectIdx2].oam.priority = 1;
DestroySprite(&gSprites[sDecor_CameraSpriteObjectIdx1]);
- sDecor_CameraSpriteObjectIdx1 = gUnknown_03005DD0.unk4;
+ sDecor_CameraSpriteObjectIdx1 = gUnknown_03005DD0.spriteId;
gSprites[sDecor_CameraSpriteObjectIdx1].oam.priority = 1;
}
@@ -2288,7 +2288,7 @@ void sub_8129ABC(u8 taskId)
data[2] = 2;
break;
case 2:
- if (sub_80ABDFC() == TRUE)
+ if (IsWeatherNotFadingIn() == TRUE)
{
data[12] = 1;
sub_8129B34(taskId);
@@ -2505,30 +2505,27 @@ void sub_812A040(u8 left, u8 top, u8 right, u8 bottom)
}
}
-#ifdef NONMATCHING
void sub_812A0E8(u8 taskId)
{
u8 i;
u8 xOff;
u8 yOff;
- u8 decor;
- register u8 decor asm("r1");
- struct DecorRearrangementDataBuffer *data;
+ u8 var1;
+ u32 var2;
sCurDecorSelectedInRearrangement = 0;
if (sub_8129FC8(taskId) != TRUE)
{
- for (i = 0; i < gUnknown_0203A17C.size; i ++)
+ for (i = 0; i < gUnknown_0203A17C.size; i++)
{
- decor = gUnknown_0203A17C.items[i];
- if (decor != DECOR_NONE)
+ var1 = gUnknown_0203A17C.items[i];
+ if (var1 != DECOR_NONE)
{
- data = &sDecorRearrangementDataBuffer[0];
- sub_8129D8C(decor, data);
- if (sub_8129E74(taskId, i, data) == TRUE)
+ sub_8129D8C(var1, &sDecorRearrangementDataBuffer[0]);
+ if (sub_8129E74(taskId, i, &sDecorRearrangementDataBuffer[0]) == TRUE)
{
- data->idx = i;
- sCurDecorSelectedInRearrangement ++;
+ sDecorRearrangementDataBuffer[0].idx = i;
+ sCurDecorSelectedInRearrangement++;
break;
}
}
@@ -2537,95 +2534,13 @@ void sub_812A0E8(u8 taskId)
{
xOff = gUnknown_0203A17C.pos[sDecorRearrangementDataBuffer[0].idx] >> 4;
yOff = gUnknown_0203A17C.pos[sDecorRearrangementDataBuffer[0].idx] & 0x0F;
- sub_812A040(xOff, yOff - sDecorRearrangementDataBuffer[0].height + 1, xOff + sDecorRearrangementDataBuffer[0].width - 1, yOff); // Arithmetic register swap at the r2 argument: `add r2, r0, r2` instead of `add r2, r2, r0`
+ var1 = yOff - sDecorRearrangementDataBuffer[0].height + 1;
+ var2 = sDecorRearrangementDataBuffer[0].width + xOff - 1;
+
+ sub_812A040(xOff, var1, var2, yOff);
}
}
}
-#else
-__attribute__((naked)) void sub_812A0E8(u8 taskId)
-{
- asm_unified("\tpush {r4-r7,lr}\n"
- "\tlsls r0, 24\n"
- "\tlsrs r6, r0, 24\n"
- "\tldr r4, =sCurDecorSelectedInRearrangement\n"
- "\tmovs r0, 0\n"
- "\tstrb r0, [r4]\n"
- "\tadds r0, r6, 0\n"
- "\tbl sub_8129FC8\n"
- "\tlsls r0, 24\n"
- "\tlsrs r0, 24\n"
- "\tcmp r0, 0x1\n"
- "\tbeq _0812A18C\n"
- "\tmovs r5, 0\n"
- "\tldr r0, =gUnknown_0203A17C\n"
- "\tldrb r1, [r0, 0x8]\n"
- "\tcmp r5, r1\n"
- "\tbcs _0812A15A\n"
- "\tadds r7, r4, 0\n"
- "_0812A10E:\n"
- "\tldr r0, [r0]\n"
- "\tadds r0, r5\n"
- "\tldrb r1, [r0]\n"
- "\tcmp r1, 0\n"
- "\tbeq _0812A14C\n"
- "\tldr r4, =sDecorRearrangementDataBuffer\n"
- "\tadds r0, r1, 0\n"
- "\tadds r1, r4, 0\n"
- "\tbl sub_8129D8C\n"
- "\tadds r0, r6, 0\n"
- "\tadds r1, r5, 0\n"
- "\tadds r2, r4, 0\n"
- "\tbl sub_8129E74\n"
- "\tlsls r0, 24\n"
- "\tlsrs r0, 24\n"
- "\tcmp r0, 0x1\n"
- "\tbne _0812A14C\n"
- "\tstrb r5, [r4]\n"
- "\tldrb r0, [r7]\n"
- "\tadds r0, 0x1\n"
- "\tstrb r0, [r7]\n"
- "\tb _0812A15A\n"
- "\t.pool\n"
- "_0812A14C:\n"
- "\tadds r0, r5, 0x1\n"
- "\tlsls r0, 24\n"
- "\tlsrs r5, r0, 24\n"
- "\tldr r0, =gUnknown_0203A17C\n"
- "\tldrb r1, [r0, 0x8]\n"
- "\tcmp r5, r1\n"
- "\tbcc _0812A10E\n"
- "_0812A15A:\n"
- "\tldr r0, =sCurDecorSelectedInRearrangement\n"
- "\tldrb r0, [r0]\n"
- "\tcmp r0, 0\n"
- "\tbeq _0812A18C\n"
- "\tldr r0, =gUnknown_0203A17C\n"
- "\tldr r2, =sDecorRearrangementDataBuffer\n"
- "\tldrb r1, [r2]\n"
- "\tldr r0, [r0, 0x4]\n"
- "\tadds r0, r1\n"
- "\tldrb r1, [r0]\n"
- "\tlsrs r0, r1, 4\n"
- "\tmovs r3, 0xF\n"
- "\tands r3, r1\n"
- "\tldrb r1, [r2, 0x2]\n"
- "\tsubs r1, r3, r1\n"
- "\tadds r1, 0x1\n"
- "\tlsls r1, 24\n"
- "\tlsrs r1, 24\n"
- "\tldrb r2, [r2, 0x1]\n"
- "\tadds r2, r0\n"
- "\tsubs r2, 0x1\n"
- "\tlsls r2, 24\n"
- "\tlsrs r2, 24\n"
- "\tbl sub_812A040\n"
- "_0812A18C:\n"
- "\tpop {r4-r7}\n"
- "\tpop {r0}\n"
- "\tbx r0\n"
- "\t.pool");
-}
-#endif
void sub_812A1A0(u8 taskId)
{
@@ -2673,7 +2588,7 @@ void sub_812A25C(u8 taskId)
case 1:
sub_812A3C8();
gFieldCallback = sub_812A334;
- SetMainCallback2(c2_exit_to_overworld_2_switch);
+ SetMainCallback2(CB2_ReturnToField);
DestroyTask(taskId);
break;
}
@@ -2699,7 +2614,7 @@ void sub_812A2C4(u8 taskId)
data[2] ++;
break;
case 3:
- if (sub_80ABDFC() == TRUE)
+ if (IsWeatherNotFadingIn() == TRUE)
{
gTasks[taskId].func = sub_8126B80;
}
diff --git a/src/dewford_trend.c b/src/dewford_trend.c
new file mode 100644
index 000000000..3ceec6563
--- /dev/null
+++ b/src/dewford_trend.c
@@ -0,0 +1,340 @@
+#include "global.h"
+#include "dewford_trend.h"
+#include "easy_chat.h"
+#include "constants/easy_chat.h"
+#include "event_data.h"
+#include "link.h"
+#include "malloc.h"
+#include "random.h"
+#include "text.h"
+#include "tv.h"
+
+// static functions
+static void sub_8122804(struct EasyChatPair *s, u16 b, u8 c);
+static bool8 sub_8122A58(struct EasyChatPair *a, struct EasyChatPair *b, u8 c);
+static void sub_8122B28(struct EasyChatPair *s);
+static bool8 SB1ContainsWords(u16 *a);
+static bool8 IsEasyChatPairEqual(u16 *words1, u16 *words2);
+static s16 GetEqualEasyChatPairIndex(struct EasyChatPair *s, struct EasyChatPair *a, u16 b);
+
+// text
+void InitDewfordTrend(void)
+{
+ u16 i;
+
+ for (i = 0; i < 5; i++)
+ {
+ gSaveBlock1Ptr->easyChatPairs[i].words[0] = sub_811EE38(EC_GROUP_CONDITIONS);
+
+ if (Random() & 1)
+ gSaveBlock1Ptr->easyChatPairs[i].words[1] = sub_811EE38(EC_GROUP_LIFESTYLE);
+ else
+ gSaveBlock1Ptr->easyChatPairs[i].words[1] = sub_811EE38(EC_GROUP_HOBBIES);
+
+ gSaveBlock1Ptr->easyChatPairs[i].unk1_6 = Random() & 1;
+ sub_8122B28(&(gSaveBlock1Ptr->easyChatPairs[i]));
+ }
+ sub_8122804(gSaveBlock1Ptr->easyChatPairs, 5, 0);
+}
+
+void UpdateDewfordTrendPerDay(u16 a)
+{
+ u16 i;
+
+ if (a != 0)
+ {
+ u32 sp0 = a * 5;
+
+ for (i = 0; i < 5; i++)
+ {
+ u32 r4;
+ u32 r2 = sp0;
+ struct EasyChatPair *r5 = &(gSaveBlock1Ptr->easyChatPairs[i]);
+
+ if (r5->unk1_6 == 0)
+ {
+ if (r5->unk0_0 >= (u16)r2)
+ {
+ r5->unk0_0 -= r2;
+ if (r5->unk0_0 == 0)
+ r5->unk1_6 = 1;
+ continue;
+ }
+ r2 -= r5->unk0_0;
+ r5->unk0_0 = 0;
+ r5->unk1_6 = 1;
+ }
+ r4 = r5->unk0_0 + r2;
+ if ((u16)r4 > r5->unk0_7)
+ {
+ u32 sp4 = r4 % r5->unk0_7;
+ r4 = r4 / r5->unk0_7;
+
+ r5->unk1_6 = r4 ^ 1;
+ if (r5->unk1_6)
+ r5->unk0_0 = sp4;
+ else
+ r5->unk0_0 = r5->unk0_7 - sp4;
+ }
+ else
+ {
+ r5->unk0_0 = r4;
+
+ if (r5->unk0_0 == r5->unk0_7)
+ r5->unk1_6 = 0;
+ }
+ }
+ sub_8122804(gSaveBlock1Ptr->easyChatPairs, 5, 0);
+ }
+}
+
+
+bool8 sub_81226D8(u16 *a)
+{
+ struct EasyChatPair s = {0};
+ u16 i;
+
+ if (!SB1ContainsWords(a))
+ {
+ if (!FlagGet(FLAG_SYS_POPWORD_INPUT))
+ {
+ FlagSet(FLAG_SYS_POPWORD_INPUT);
+ if (!FlagGet(FLAG_SYS_MIX_RECORD))
+ {
+ gSaveBlock1Ptr->easyChatPairs[0].words[0] = a[0];
+ gSaveBlock1Ptr->easyChatPairs[0].words[1] = a[1];
+ return TRUE;
+ }
+ }
+
+ s.words[0] = a[0];
+ s.words[1] = a[1];
+ s.unk1_6 = 1;
+ sub_8122B28(&s);
+
+ for (i = 0; i < 5; i++)
+ {
+ if (sub_8122A58(&s, &(gSaveBlock1Ptr->easyChatPairs[i]), 0))
+ {
+ u16 r3 = 4;
+
+ while (r3 > i)
+ {
+ gSaveBlock1Ptr->easyChatPairs[r3] = gSaveBlock1Ptr->easyChatPairs[r3 - 1];
+ r3--;
+ }
+ gSaveBlock1Ptr->easyChatPairs[i] = s;
+ if(i == 4)
+ sub_80EDC60(a);
+ return (i == 0);
+ }
+ }
+ gSaveBlock1Ptr->easyChatPairs[4] = s;
+ sub_80EDC60(a);
+ }
+ return FALSE;
+}
+
+
+static void sub_8122804(struct EasyChatPair *s, u16 b, u8 c)
+{
+ u16 h;
+
+ for (h = 0; h < b; h++)
+ {
+ u16 i;
+
+ for (i = h + 1; i < b; i++)
+ {
+ if (sub_8122A58(&s[i], &s[h], c))
+ {
+ struct EasyChatPair temp;
+
+ temp = s[i];
+ s[i] = s[h];
+ s[h] = temp;
+ }
+ }
+ }
+}
+
+void sub_812287C(void *a, u32 b, u8 unused)
+{
+ u16 i, j, r3, players;
+ struct EasyChatPair *buffer1, *buffer2, *src, *dst, *foo_of_buffer2;
+
+ buffer1 = Alloc(0x100);
+ if(buffer1 != NULL)
+ {
+ buffer2 = Alloc(0x100);
+ if(buffer2 == NULL)
+ {
+ Free(buffer1);
+ }
+ else
+ {
+ players = GetLinkPlayerCount();
+ for (i = 0; i < players; i++)
+ memcpy(&(buffer1[i * 5]), (u8 *)a + i * b, 40);
+ src = buffer1;
+ dst = buffer2;
+ r3 = 0;
+ for (i = 0; i < players; i++)
+ {
+ for (j = 0; j < 5; j++)
+ {
+ s16 foo = GetEqualEasyChatPairIndex(buffer2, src, r3);
+ if (foo < 0)
+ {
+ *(dst++) = *src;
+ r3++;
+ }
+ else
+ {
+ foo_of_buffer2 = (struct EasyChatPair *)((u32)buffer2 + (foo * 8)); //required to do this to reverse the order of register operands in add ASM statement
+ if (foo_of_buffer2->unk0_0 < src->unk0_0)
+ {
+ *foo_of_buffer2 = *src;
+ }
+ }
+ src++;
+ }
+ }
+ sub_8122804(buffer2, r3, 2);
+ src = buffer2;
+ dst = gSaveBlock1Ptr->easyChatPairs;
+ for (i = 0; i < 5; i++)
+ *(dst++) = *(src++);
+ Free(buffer1);
+ Free(buffer2);
+ }
+ }
+}
+
+void BufferTrendyPhraseString(void)
+{
+ struct EasyChatPair *s = &gSaveBlock1Ptr->easyChatPairs[gSpecialVar_0x8004];
+
+ ConvertEasyChatWordsToString(gStringVar1, s->words, 2, 1);
+}
+
+void TrendyPhraseIsOld(void)
+{
+ u16 result = 0;
+
+ if (gSaveBlock1Ptr->easyChatPairs[0].unk0_0 - gSaveBlock1Ptr->easyChatPairs[1].unk0_0 < 2)
+ {
+ asm("":::"r2"); //Force the compiler to store address of gSaveBlock1 in r3 instead of r2
+ if (!gSaveBlock1Ptr->easyChatPairs[0].unk1_6 && gSaveBlock1Ptr->easyChatPairs[1].unk1_6)
+ result = 1;
+ }
+ gSpecialVar_Result = result;
+}
+
+void GetDewfordHallPaintingNameIndex(void)
+{
+ gSpecialVar_Result = (gSaveBlock1Ptr->easyChatPairs[0].words[0] + gSaveBlock1Ptr->easyChatPairs[0].words[1]) & 7;
+}
+
+static bool8 sub_8122A58(struct EasyChatPair *a, struct EasyChatPair *b, u8 c)
+{
+ switch (c)
+ {
+ case 0:
+ if (a->unk0_0 > b->unk0_0)
+ return 1;
+ if (a->unk0_0 < b->unk0_0)
+ return 0;
+ if (a->unk0_7 > b->unk0_7)
+ return 1;
+ if (a->unk0_7 < b->unk0_7)
+ return 0;
+ break;
+ case 1:
+ if (a->unk0_7 > b->unk0_7)
+ return 1;
+ if (a->unk0_7 < b->unk0_7)
+ return 0;
+ if (a->unk0_0 > b->unk0_0)
+ return 1;
+ if (a->unk0_0 < b->unk0_0)
+ return 0;
+ break;
+ case 2:
+ if (a->unk0_0 > b->unk0_0)
+ return 1;
+ if (a->unk0_0 < b->unk0_0)
+ return 0;
+ if (a->unk0_7 > b->unk0_7)
+ return 1;
+ if (a->unk0_7 < b->unk0_7)
+ return 0;
+ if (a->unk2 > b->unk2)
+ return 1;
+ if (a->unk2 < b->unk2)
+ return 0;
+ if (a->words[0] > b->words[0])
+ return 1;
+ if (a->words[0] < b->words[0])
+ return 0;
+ if (a->words[1] > b->words[1])
+ return 1;
+ if (a->words[1] < b->words[1])
+ return 0;
+ return 1;
+ }
+ return Random() & 1;
+}
+
+static void sub_8122B28(struct EasyChatPair *s)
+{
+ u16 r4;
+
+ r4 = Random() % 98;
+ if (r4 > 50)
+ {
+ r4 = Random() % 98;
+ if (r4 > 80)
+ r4 = Random() % 98;
+ }
+ s->unk0_7 = r4 + 30;
+ s->unk0_0 = (Random() % (r4 + 1)) + 30;
+ s->unk2 = Random();
+}
+
+static bool8 SB1ContainsWords(u16 *a)
+{
+ u16 i;
+
+ for (i = 0; i < 5; i++)
+ {
+ if (IsEasyChatPairEqual(a, gSaveBlock1Ptr->easyChatPairs[i].words) != 0)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool8 IsEasyChatPairEqual(u16 *words1, u16 *words2)
+{
+ u16 i;
+
+ for (i = 0; i < 2; i++)
+ {
+ if (*(words1++) != *(words2++))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static s16 GetEqualEasyChatPairIndex(struct EasyChatPair*s, struct EasyChatPair *a, u16 b)
+{
+ s16 i;
+
+ for (i = 0; i < b; i++)
+ {
+ if (IsEasyChatPairEqual(a->words, s->words))
+ return i;
+ s++;
+ }
+ return -1;
+}
diff --git a/src/egg_hatch.c b/src/egg_hatch.c
index 5a2fe5ca2..8914d6ff3 100644
--- a/src/egg_hatch.c
+++ b/src/egg_hatch.c
@@ -25,6 +25,7 @@
#include "window.h"
#include "constants/abilities.h"
#include "daycare.h"
+#include "overworld.h"
#include "battle.h" // to get rid of later
struct EggHatchData
@@ -44,9 +45,6 @@ struct EggHatchData
u8 textColor[3];
};
-extern struct SpriteTemplate gUnknown_0202499C;
-extern void (*gFieldCallback)(void);
-
extern const struct CompressedSpriteSheet gMonFrontPicTable[];
extern const u8 gBattleTextboxTiles[];
extern const u8 gBattleTextboxTilemap[];
@@ -58,20 +56,14 @@ extern const u8 gText_HatchedFromEgg[];
extern const u8 gText_NickHatchPrompt[];
extern u8 sav1_map_get_name(void);
-extern s8 ProcessMenuInputNoWrap_(void);
extern void TVShowConvertInternationalString(u8* str1, u8* str2, u8);
extern void sub_806A068(u16, u8);
extern void FadeScreen(u8, u8);
extern void overworld_free_bg_tilemaps(void);
extern void sub_80AF168(void);
-extern void AllocateMonSpritesGfx(void);
-extern void FreeMonSpritesGfx(void);
extern void ScanlineEffect_Stop(void);
-extern void reset_temp_tile_data_buffers(void);
-extern void c2_exit_to_overworld_2_switch(void);
+extern void CB2_ReturnToField(void);
extern void play_some_sound(void);
-extern void copy_decompressed_tile_data_to_vram_autofree(u8 bg_id, const void* src, u16 size, u16 offset, u8 mode);
-extern void CreateYesNoMenu(const struct WindowTemplate*, u16, u8, u8);
extern void DoNamingScreen(u8, const u8*, u16, u8, u32, MainCallback);
extern u16 sub_80D22D0(void);
extern u8 CountPartyAliveNonEggMonsExcept(u8);
@@ -440,12 +432,12 @@ static u8 EggHatchCreateMonSprite(u8 a0, u8 switchID, u8 pokeID, u16* speciesLoc
HandleLoadSpecialPokePic_DontHandleDeoxys(&gMonFrontPicTable[species],
gMonSpritesGfxPtr->sprites[(a0 * 2) + 1],
species, pid);
- LoadCompressedObjectPalette(sub_806E794(mon));
+ LoadCompressedObjectPalette(GetMonSpritePalStruct(mon));
*speciesLoc = species;
}
break;
case 1:
- sub_806A068(sub_806E794(mon)->tag, r5);
+ sub_806A068(GetMonSpritePalStruct(mon)->tag, r5);
spriteID = CreateSprite(&gUnknown_0202499C, 120, 75, 6);
gSprites[spriteID].invisible = 1;
gSprites[spriteID].callback = SpriteCallbackDummy;
@@ -571,7 +563,7 @@ static void EggHatchSetMonNickname(void)
SetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar3);
FreeMonSpritesGfx();
Free(sEggHatchData);
- SetMainCallback2(c2_exit_to_overworld_2_switch);
+ SetMainCallback2(CB2_ReturnToField);
}
static void Task_EggHatchPlayBGM(u8 taskID)
@@ -582,10 +574,10 @@ static void Task_EggHatchPlayBGM(u8 taskID)
play_some_sound();
}
if (gTasks[taskID].data[0] == 1)
- PlayBGM(376);
+ PlayBGM(MUS_ME_SHINKA);
if (gTasks[taskID].data[0] > 60)
{
- PlayBGM(377);
+ PlayBGM(MUS_SHINKA);
DestroyTask(taskID);
// UB: task is destroyed, yet the value is incremented
}
@@ -695,7 +687,7 @@ static void CB2_EggHatch_1(void)
UnsetBgTilemapBuffer(0);
UnsetBgTilemapBuffer(1);
Free(sEggHatchData);
- SetMainCallback2(c2_exit_to_overworld_2_switch);
+ SetMainCallback2(CB2_ReturnToField);
}
break;
}
diff --git a/src/evolution_scene.c b/src/evolution_scene.c
index f38f9f19c..74eac32de 100644
--- a/src/evolution_scene.c
+++ b/src/evolution_scene.c
@@ -48,9 +48,7 @@ extern u16 gBattle_BG2_X;
extern u16 gBattle_BG2_Y;
extern u16 gBattle_BG3_X;
extern u16 gBattle_BG3_Y;
-extern struct SpriteTemplate gUnknown_0202499C;
extern bool8 gAffineAnimsDisabled;
-extern u16 gMoveToLearn;
extern const u8 gSpeciesNames[][11];
#define sEvoCursorPos gBattleCommunication[1] // when learning a new move
@@ -60,16 +58,8 @@ extern const struct WindowTemplate gUnknown_0833900C;
extern const struct CompressedSpriteSheet gMonFrontPicTable[];
// strings
-extern const u8 gText_PkmnIsEvolving[];
-extern const u8 gText_CongratsPkmnEvolved[];
-extern const u8 gText_BattleYesNoChoice[];
-extern const u8 gText_PkmnStoppedEvolving[];
-extern const u8 gText_EllipsisQuestionMark[];
extern const u8 gText_CommunicationStandby5[];
-extern void copy_decompressed_tile_data_to_vram_autofree(u8 arg0, const void *arg1, bool32 arg2, u16 arg3, u8 arg4);
-extern u32 sub_80391E0(u8, u8);
-extern void SpriteCallbackDummy_2(struct Sprite *sprite);
extern void sub_80356D0(void);
extern void sub_807B154(void);
extern void sub_806A068(u16, u8);
@@ -471,10 +461,10 @@ static void CB2_TradeEvolutionSceneLoadGraphics(void)
}
break;
case 6:
- if (gLinkVSyncDisabled)
+ if (gWirelessCommType)
{
sub_800E0E8();
- sub_800DFB4(0, 0);
+ CreateWirelessStatusIndicatorSprite(0, 0);
}
BlendPalettes(-1,0x10, 0);
gMain.state++;
@@ -1255,7 +1245,7 @@ static void Task_TradeEvolutionScene(u8 taskID)
case 5:
if (!gPaletteFade.active)
{
- if (gLinkVSyncDisabled)
+ if (gWirelessCommType)
sub_800E084();
Free(GetBgTilemapBuffer(3));
diff --git a/src/field_camera.c b/src/field_camera.c
index 17ced6aa5..95167ee10 100644
--- a/src/field_camera.c
+++ b/src/field_camera.c
@@ -1,9 +1,20 @@
-
-// Includes
#include "global.h"
+#include "berry.h"
+#include "bike.h"
+#include "field_camera.h"
+#include "field_player_avatar.h"
+#include "fieldmap.h"
+#include "field_map_obj.h"
+#include "gpu_regs.h"
+#include "menu.h"
+#include "overworld.h"
+#include "rotating_gate.h"
+#include "sprite.h"
+#include "text.h"
-// Static type declarations
+EWRAM_DATA bool8 gUnusedBikeCameraAheadPanback = FALSE;
+// Static type declarations
struct FieldCameraUnknownStruct
{
u8 unk0;
@@ -13,16 +24,478 @@ struct FieldCameraUnknownStruct
bool8 unk4;
};
-// Static RAM declarations
+// static functions
+static void RedrawMapSliceNorth(struct FieldCameraUnknownStruct *a, const struct MapData *mapData);
+static void RedrawMapSliceSouth(struct FieldCameraUnknownStruct *a, const struct MapData *mapData);
+static void RedrawMapSliceEast(struct FieldCameraUnknownStruct *a, const struct MapData *mapData);
+static void RedrawMapSliceWest(struct FieldCameraUnknownStruct *a, const struct MapData *mapData);
+static s32 MapPosToBgTilemapOffset(struct FieldCameraUnknownStruct *a, s32 x, s32 y);
+static void DrawWholeMapViewInternal(int x, int y, const struct MapData *mapData);
+static void DrawMetatileAt(const struct MapData *mapData, u16, int, int);
+static void DrawMetatile(s32 a, u16 *b, u16 c);
+static void CameraPanningCB_PanAhead(void);
+
+// IWRAM bss vars
+static IWRAM_DATA struct FieldCameraUnknownStruct gUnknown_03000E20;
+static IWRAM_DATA s16 gUnknown_03000E28;
+static IWRAM_DATA s16 gUnknown_03000E2A;
+static IWRAM_DATA u8 gUnknown_03000E2C;
+static IWRAM_DATA void (*gUnknown_03000E30)(void);
+
+struct CameraObject gUnknown_03005DD0;
+u16 gUnknown_03005DE8;
+u16 gUnknown_03005DEC;
+
+// text
+static void move_tilemap_camera_to_upper_left_corner_(struct FieldCameraUnknownStruct *a)
+{
+ a->unk2 = 0;
+ a->unk3 = 0;
+ a->unk0 = 0;
+ a->unk1 = 0;
+ a->unk4 = TRUE;
+}
+
+static void tilemap_move_something(struct FieldCameraUnknownStruct *a, u32 b, u32 c)
+{
+ a->unk2 += b;
+ a->unk2 %= 32;
+ a->unk3 += c;
+ a->unk3 %= 32;
+}
+
+static void coords8_add(struct FieldCameraUnknownStruct *a, u32 b, u32 c)
+{
+ a->unk0 += b;
+ a->unk1 += c;
+}
+
+void move_tilemap_camera_to_upper_left_corner(void)
+{
+ move_tilemap_camera_to_upper_left_corner_(&gUnknown_03000E20);
+}
+
+void FieldUpdateBgTilemapScroll(void)
+{
+ u32 r4, r5;
+ r5 = gUnknown_03000E20.unk0 + gUnknown_03000E28;
+ r4 = gUnknown_03000E2A + gUnknown_03000E20.unk1 + 8;
+
+ SetGpuReg(REG_OFFSET_BG1HOFS, r5);
+ SetGpuReg(REG_OFFSET_BG1VOFS, r4);
+ SetGpuReg(REG_OFFSET_BG2HOFS, r5);
+ SetGpuReg(REG_OFFSET_BG2VOFS, r4);
+ SetGpuReg(REG_OFFSET_BG3HOFS, r5);
+ SetGpuReg(REG_OFFSET_BG3VOFS, r4);
+}
+
+void sub_8089C08(s16 *a, s16 *b)
+{
+ *a = gUnknown_03000E20.unk0 + gUnknown_03000E28;
+ *b = gUnknown_03000E20.unk1 + gUnknown_03000E2A + 8;
+}
+
+void DrawWholeMapView(void)
+{
+ DrawWholeMapViewInternal(gSaveBlock1Ptr->pos.x, gSaveBlock1Ptr->pos.y, gMapHeader.mapData);
+ gUnknown_03000E20.unk4 = TRUE;
+}
+
+static void DrawWholeMapViewInternal(int x, int y, const struct MapData *mapData)
+{
+ u8 i;
+ u8 j;
+ u32 r6;
+ u8 temp;
+
+ for (i = 0; i < 32; i += 2)
+ {
+ temp = gUnknown_03000E20.unk3 + i;
+ if (temp >= 32)
+ temp -= 32;
+ r6 = temp * 32;
+ for (j = 0; j < 32; j += 2)
+ {
+ temp = gUnknown_03000E20.unk2 + j;
+ if (temp >= 32)
+ temp -= 32;
+ DrawMetatileAt(mapData, r6 + temp, x + j / 2, y + i / 2);
+ }
+ }
+}
+
+static void RedrawMapSlicesForCameraUpdate(struct FieldCameraUnknownStruct *a, int x, int y)
+{
+ const struct MapData *mapData = gMapHeader.mapData;
+
+ if (x > 0)
+ RedrawMapSliceWest(a, mapData);
+ if (x < 0)
+ RedrawMapSliceEast(a, mapData);
+ if (y > 0)
+ RedrawMapSliceNorth(a, mapData);
+ if (y < 0)
+ RedrawMapSliceSouth(a, mapData);
+ a->unk4 = TRUE;
+}
+
+static void RedrawMapSliceNorth(struct FieldCameraUnknownStruct *a, const struct MapData *mapData)
+{
+ u8 i;
+ u8 temp;
+ u32 r7;
+
+ temp = a->unk3 + 28;
+ if (temp >= 32)
+ temp -= 32;
+ r7 = temp * 32;
+ for (i = 0; i < 32; i += 2)
+ {
+ temp = a->unk2 + i;
+ if (temp >= 32)
+ temp -= 32;
+ DrawMetatileAt(mapData, r7 + temp, gSaveBlock1Ptr->pos.x + i / 2, gSaveBlock1Ptr->pos.y + 14);
+ }
+}
+
+static void RedrawMapSliceSouth(struct FieldCameraUnknownStruct *a, const struct MapData *mapData)
+{
+ u8 i;
+ u8 temp;
+ u32 r7 = a->unk3 * 32;
+
+ for (i = 0; i < 32; i += 2)
+ {
+ temp = a->unk2 + i;
+ if (temp >= 32)
+ temp -= 32;
+ DrawMetatileAt(mapData, r7 + temp, gSaveBlock1Ptr->pos.x + i / 2, gSaveBlock1Ptr->pos.y);
+ }
+}
+
+static void RedrawMapSliceEast(struct FieldCameraUnknownStruct *a, const struct MapData *mapData)
+{
+ u8 i;
+ u8 temp;
+ u32 r6 = a->unk2;
+
+ for (i = 0; i < 32; i += 2)
+ {
+ temp = a->unk3 + i;
+ if (temp >= 32)
+ temp -= 32;
+ DrawMetatileAt(mapData, temp * 32 + r6, gSaveBlock1Ptr->pos.x, gSaveBlock1Ptr->pos.y + i / 2);
+ }
+}
+
+static void RedrawMapSliceWest(struct FieldCameraUnknownStruct *a, const struct MapData *mapData)
+{
+ u8 i;
+ u8 temp;
+ u8 r5 = a->unk2 + 28;
+
+ if (r5 >= 32)
+ r5 -= 32;
+ for (i = 0; i < 32; i += 2)
+ {
+ temp = a->unk3 + i;
+ if (temp >= 32)
+ temp -= 32;
+ DrawMetatileAt(mapData, temp * 32 + r5, gSaveBlock1Ptr->pos.x + 14, gSaveBlock1Ptr->pos.y + i / 2);
+ }
+}
+
+void CurrentMapDrawMetatileAt(int a, int b)
+{
+ int offset = MapPosToBgTilemapOffset(&gUnknown_03000E20, a, b);
+
+ if (offset >= 0)
+ {
+ DrawMetatileAt(gMapHeader.mapData, offset, a, b);
+ gUnknown_03000E20.unk4 = TRUE;
+ }
+}
+
+void DrawDoorMetatileAt(int x, int y, u16 *arr)
+{
+ int offset = MapPosToBgTilemapOffset(&gUnknown_03000E20, x, y);
+
+ if (offset >= 0)
+ {
+ DrawMetatile(1, arr, offset);
+ gUnknown_03000E20.unk4 = TRUE;
+ }
+}
+
+static void DrawMetatileAt(const struct MapData *mapData, u16 b, int c, int d)
+{
+ u16 metatileId = MapGridGetMetatileIdAt(c, d);
+ u16 *metatiles;
+
+ if (metatileId > 1024)
+ metatileId = 0;
+ if (metatileId < 512)
+ metatiles = mapData->primaryTileset->metatiles;
+ else
+ {
+ metatiles = mapData->secondaryTileset->metatiles;
+ metatileId -= 512;
+ }
+ DrawMetatile(MapGridGetMetatileLayerTypeAt(c, d), metatiles + metatileId * 8, b);
+}
+
+static void DrawMetatile(s32 a, u16 *b, u16 c)
+{
+ switch (a)
+ {
+ case 2:
+ gBGTilemapBuffers3[c] = b[0];
+ gBGTilemapBuffers3[c + 1] = b[1];
+ gBGTilemapBuffers3[c + 0x20] = b[2];
+ gBGTilemapBuffers3[c + 0x21] = b[3];
+
+ gBGTilemapBuffers1[c] = 0;
+ gBGTilemapBuffers1[c + 1] = 0;
+ gBGTilemapBuffers1[c + 0x20] = 0;
+ gBGTilemapBuffers1[c + 0x21] = 0;
+
+ gBGTilemapBuffers2[c] = b[4];
+ gBGTilemapBuffers2[c + 1] = b[5];
+ gBGTilemapBuffers2[c + 0x20] = b[6];
+ gBGTilemapBuffers2[c + 0x21] = b[7];
+ break;
+ case 1:
+ gBGTilemapBuffers3[c] = b[0];
+ gBGTilemapBuffers3[c + 1] = b[1];
+ gBGTilemapBuffers3[c + 0x20] = b[2];
+ gBGTilemapBuffers3[c + 0x21] = b[3];
+
+ gBGTilemapBuffers1[c] = b[4];
+ gBGTilemapBuffers1[c + 1] = b[5];
+ gBGTilemapBuffers1[c + 0x20] = b[6];
+ gBGTilemapBuffers1[c + 0x21] = b[7];
+
+ gBGTilemapBuffers2[c] = 0;
+ gBGTilemapBuffers2[c + 1] = 0;
+ gBGTilemapBuffers2[c + 0x20] = 0;
+ gBGTilemapBuffers2[c + 0x21] = 0;
+ break;
+ case 0:
+ gBGTilemapBuffers3[c] = 0x3014;
+ gBGTilemapBuffers3[c + 1] = 0x3014;
+ gBGTilemapBuffers3[c + 0x20] = 0x3014;
+ gBGTilemapBuffers3[c + 0x21] = 0x3014;
+
+ gBGTilemapBuffers1[c] = b[0];
+ gBGTilemapBuffers1[c + 1] = b[1];
+ gBGTilemapBuffers1[c + 0x20] = b[2];
+ gBGTilemapBuffers1[c + 0x21] = b[3];
+
+ gBGTilemapBuffers2[c] = b[4];
+ gBGTilemapBuffers2[c + 1] = b[5];
+ gBGTilemapBuffers2[c + 0x20] = b[6];
+ gBGTilemapBuffers2[c + 0x21] = b[7];
+ break;
+ }
+ schedule_bg_copy_tilemap_to_vram(1);
+ schedule_bg_copy_tilemap_to_vram(2);
+ schedule_bg_copy_tilemap_to_vram(3);
+}
+
+static s32 MapPosToBgTilemapOffset(struct FieldCameraUnknownStruct *a, s32 x, s32 y)
+{
+ x -= gSaveBlock1Ptr->pos.x;
+ x *= 2;
+ if (x >= 32 || x < 0)
+ return -1;
+ x = x + a->unk2;
+ if (x >= 32)
+ x -= 32;
+
+ y = (y - gSaveBlock1Ptr->pos.y) * 2;
+ if (y >= 32 || y < 0)
+ return -1;
+ y = y + a->unk3;
+ if (y >= 32)
+ y -= 32;
+
+ return y * 32 + x;
+}
+
+static void CameraUpdateCallback(struct CameraObject *a)
+{
+ if (a->spriteId != 0)
+ {
+ a->unk8 = gSprites[a->spriteId].data[2];
+ a->unkC = gSprites[a->spriteId].data[3];
+ }
+}
+
+void ResetCameraUpdateInfo(void)
+{
+ gUnknown_03005DD0.unk8 = 0;
+ gUnknown_03005DD0.unkC = 0;
+ gUnknown_03005DD0.x = 0;
+ gUnknown_03005DD0.y = 0;
+ gUnknown_03005DD0.spriteId = 0;
+ gUnknown_03005DD0.callback = NULL;
+}
-IWRAM_DATA struct FieldCameraUnknownStruct gUnknown_03000E20;
-IWRAM_DATA s16 gUnknown_03000E28;
-IWRAM_DATA s16 gUnknown_03000E2A;
-IWRAM_DATA u8 gUnknown_03000E2C;
-IWRAM_DATA void (*gUnknown_03000E30)(void);
+u32 InitCameraUpdateCallback(u8 a)
+{
+ if (gUnknown_03005DD0.spriteId != 0)
+ DestroySprite(&gSprites[gUnknown_03005DD0.spriteId]);
+ gUnknown_03005DD0.spriteId = AddCameraObject(a);
+ gUnknown_03005DD0.callback = CameraUpdateCallback;
+ return 0;
+}
+
+void CameraUpdate(void)
+{
+ int deltaX;
+ int deltaY;
+ int r0;
+ int r1;
+ int r7;
+ int r8;
+
+ if (gUnknown_03005DD0.callback != NULL)
+ gUnknown_03005DD0.callback(&gUnknown_03005DD0);
+ r7 = gUnknown_03005DD0.unk8;
+ r8 = gUnknown_03005DD0.unkC;
+ deltaX = 0;
+ deltaY = 0;
+ r1 = gUnknown_03005DD0.x;
+ r0 = gUnknown_03005DD0.y;
+
+
+ if (r1 == 0 && r7 != 0)
+ {
+ if (r7 > 0)
+ deltaX = 1;
+ else
+ deltaX = -1;
+ }
+ if (r0 == 0 && r8 != 0)
+ {
+ if (r8 > 0)
+ deltaY = 1;
+ else
+ deltaY = -1;
+ }
+ if (r1 != 0 && r1 == -r7)
+ {
+ if (r7 > 0)
+ deltaX = 1;
+ else
+ deltaX = -1;
+ }
+ if (r0 != 0 && r0 == -r8)
+ {
+ if (r8 > 0)
+ deltaX = 1;
+ else
+ deltaX = -1;
+ }
+
+ gUnknown_03005DD0.x += r7;
+ gUnknown_03005DD0.x = gUnknown_03005DD0.x - 16 * (gUnknown_03005DD0.x / 16);
+ gUnknown_03005DD0.y += r8;
+ gUnknown_03005DD0.y = gUnknown_03005DD0.y - 16 * (gUnknown_03005DD0.y / 16);
+
+ if (deltaX != 0 || deltaY != 0)
+ {
+ CameraMove(deltaX, deltaY);
+ UpdateFieldObjectsForCameraUpdate(deltaX, deltaY);
+ RotatingGatePuzzleCameraUpdate(deltaX, deltaY);
+ ResetBerryTreeSparkleFlags();
+ tilemap_move_something(&gUnknown_03000E20, deltaX * 2, deltaY * 2);
+ RedrawMapSlicesForCameraUpdate(&gUnknown_03000E20, deltaX * 2, deltaY * 2);
+ }
+
+ coords8_add(&gUnknown_03000E20, r7, r8);
+ gUnknown_03005DEC -= r7;
+ gUnknown_03005DE8 -= r8;
+}
+
+void camera_move_and_redraw(int a, int b) //unused
+{
+ CameraMove(a, b);
+ UpdateFieldObjectsForCameraUpdate(a, b);
+ DrawWholeMapView();
+ gUnknown_03005DEC -= a * 16;
+ gUnknown_03005DE8 -= b * 16;
+}
+
+void SetCameraPanningCallback(void (*a)(void))
+{
+ gUnknown_03000E30 = a;
+}
+
+void SetCameraPanning(s16 a, s16 b)
+{
+ gUnknown_03000E28 = a;
+ gUnknown_03000E2A = b + 32;
+}
+
+void InstallCameraPanAheadCallback(void)
+{
+ gUnknown_03000E30 = CameraPanningCB_PanAhead;
+ gUnknown_03000E2C = 0;
+ gUnknown_03000E28 = 0;
+ gUnknown_03000E2A = 32;
+}
+
+void UpdateCameraPanning(void)
+{
+ if (gUnknown_03000E30 != NULL)
+ gUnknown_03000E30();
+ //Update sprite offset of overworld objects
+ gSpriteCoordOffsetX = gUnknown_03005DEC - gUnknown_03000E28;
+ gSpriteCoordOffsetY = gUnknown_03005DE8 - gUnknown_03000E2A - 8;
+}
+
+static void CameraPanningCB_PanAhead(void)
+{
+ u8 var;
-// Static ROM declarations
+ if (gUnusedBikeCameraAheadPanback == FALSE)
+ {
+ InstallCameraPanAheadCallback();
+ }
+ else
+ {
+ // this code is never reached.
+ if (gPlayerAvatar.tileTransitionState == T_TILE_TRANSITION)
+ {
+ gUnknown_03000E2C ^= 1;
+ if (gUnknown_03000E2C == 0)
+ return;
+ }
+ else
+ {
+ gUnknown_03000E2C = 0;
+ }
-// .rodata
+ var = player_get_direction_upper_nybble();
+ if (var == 2)
+ {
+ if (gUnknown_03000E2A > -8)
+ gUnknown_03000E2A -= 2;
+ }
+ else if (var == 1)
+ {
+ if (gUnknown_03000E2A < 72)
+ gUnknown_03000E2A += 2;
+ }
+ else if (gUnknown_03000E2A < 32)
+ {
+ gUnknown_03000E2A += 2;
+ }
+ else if (gUnknown_03000E2A > 32)
+ {
+ gUnknown_03000E2A -= 2;
+ }
+ }
+}
-// .text
diff --git a/src/field_effect.c b/src/field_effect.c
index 628dc776a..692090779 100644
--- a/src/field_effect.c
+++ b/src/field_effect.c
@@ -1,15 +1,3897 @@
// Includes
#include "global.h"
+#include "field_effect.h"
+#include "battle_dome_cards.h"
+#include "decompress.h"
+#include "field_camera.h"
+#include "field_effect_helpers.h"
+#include "field_map_obj.h"
+#include "field_map_obj_helpers.h"
+#include "field_player_avatar.h"
+#include "field_screen.h"
+#include "field_weather.h"
+#include "fieldmap.h"
+#include "fldeff_groundshake.h"
+#include "gpu_regs.h"
+#include "main.h"
+#include "menu.h"
+#include "metatile_behavior.h"
+#include "overworld.h"
+#include "palette.h"
+#include "party_menu.h"
+#include "pokemon.h"
+#include "script.h"
+#include "sound.h"
+#include "sprite.h"
+#include "task.h"
+#include "trig.h"
+#include "util.h"
+#include "constants/rgb.h"
+#include "constants/songs.h"
+
+#define subsprite_table(ptr) {.subsprites = ptr, .subspriteCount = (sizeof ptr) / (sizeof(struct Subsprite))}
+
+EWRAM_DATA s32 gFieldEffectArguments[8] = {0};
// Static type declarations
// Static RAM declarations
-IWRAM_DATA u8 gUnknown_03000F58[32];
+static IWRAM_DATA u8 sActiveList[32];
// Static ROM declarations
+extern u8 *gFieldEffectScriptPointers[];
+
// .rodata
+const u32 gNewGameBirchPic[] = INCBIN_U32("graphics/birch_speech/birch.4bpp");
+const u32 gUnusedBirchBeauty[] = INCBIN_U32("graphics/unused/intro_birch_beauty.4bpp");
+const u16 gNewGameBirchPalette[16] = INCBIN_U16("graphics/birch_speech/birch.gbapal");
+const u32 gSpriteImage_855A970[] = INCBIN_U32("graphics/misc/pokeball_glow.4bpp");
+const u16 gFieldEffectObjectPalette4[16] = INCBIN_U16("graphics/map_objects/palettes/field_effect_object_palette_04.gbapal");
+const u32 gSpriteImage_855A9B0[] = INCBIN_U32("graphics/misc/pokecenter_monitor/0.4bpp");
+const u32 gSpriteImage_855AA70[] = INCBIN_U32("graphics/misc/pokecenter_monitor/1.4bpp");
+const u32 gSpriteImage_855AB30[] = INCBIN_U32("graphics/misc/big_hof_monitor.4bpp");
+const u8 gSpriteImage_855AD30[] = INCBIN_U8("graphics/misc/small_hof_monitor.4bpp");
+const u16 gFieldEffectObjectPalette5[16] = INCBIN_U16("graphics/map_objects/palettes/field_effect_object_palette_05.gbapal");
+
+// Graphics for the lights streaking past your Pokemon when it uses a field move.
+const u32 gFieldMoveStreaksTiles[] = INCBIN_U32("graphics/misc/field_move_streaks.4bpp");
+const u16 gFieldMoveStreaksPalette[16] = INCBIN_U16("graphics/misc/field_move_streaks.gbapal");
+const u16 gFieldMoveStreaksTilemap[] = INCBIN_U16("graphics/misc/field_move_streaks_map.bin");
+
+// The following light streaks effect is used when the map is dark (e.g. a cave).
+const u32 gDarknessFieldMoveStreaksTiles[] = INCBIN_U32("graphics/misc/darkness_field_move_streaks.4bpp");
+const u16 gDarknessFieldMoveStreaksPalette[16] = INCBIN_U16("graphics/misc/darkness_field_move_streaks.gbapal");
+const u16 gDarknessFieldMoveStreaksTilemap[] = INCBIN_U16("graphics/misc/darkness_field_move_streaks_map.bin");
+
+const u16 gUnknown_0855B610[16] = INCBIN_U16("graphics/misc/spotlight.gbapal");
+const u8 gUnknown_0855B630[] = INCBIN_U8("graphics/misc/spotlight.4bpp");
+const u8 gUnknown_0855C170[] = INCBIN_U8("graphics/unknown/unknown_55C170.4bpp");
+const u8 gUnknown_0855C190[] = INCBIN_U8("graphics/unknown/unknown_55C190.4bpp");
+const u8 gUnknown_0855C1B0[] = INCBIN_U8("graphics/unknown/unknown_55C1B0.4bpp");
+const u8 gUnknown_0855C1D0[] = INCBIN_U8("graphics/unknown/unknown_55C1D0.4bpp");
+
+bool8 (*const gFieldEffectScriptFuncs[])(u8 **, u32 *) = {
+ FieldEffectCmd_loadtiles,
+ FieldEffectCmd_loadfadedpal,
+ FieldEffectCmd_loadpal,
+ FieldEffectCmd_callnative,
+ FieldEffectCmd_end,
+ FieldEffectCmd_loadgfx_callnative,
+ FieldEffectCmd_loadtiles_callnative,
+ FieldEffectCmd_loadfadedpal_callnative,
+};
+
+const struct OamData gNewGameBirchOamAttributes = {.size = 3};
+const struct OamData gOamData_855C218 = {.size = 0};
+const struct OamData gOamData_855C220 = {.size = 1};
+
+const struct SpriteFrameImage gNewGameBirchPicTable[] = {
+ obj_frame_tiles(gNewGameBirchPic)
+};
+const struct SpritePalette gNewGameBirchObjectPaletteInfo = {.data = gNewGameBirchPalette, .tag = 0x1006};
+
+const union AnimCmd gNewGameBirchImageAnim[] = {
+ ANIMCMD_FRAME(.imageValue = 0, .duration = 1),
+ ANIMCMD_END
+};
+
+const union AnimCmd *const gNewGameBirchImageAnimTable[] = {
+ gNewGameBirchImageAnim
+};
+
+const struct SpriteTemplate gNewGameBirchObjectTemplate = {
+ .tileTag = 0xffff,
+ .paletteTag = 4102,
+ .oam = &gNewGameBirchOamAttributes,
+ .anims = gNewGameBirchImageAnimTable,
+ .images = gNewGameBirchPicTable,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy
+};
+
+const struct SpritePalette gFieldEffectObjectPaletteInfo4 = {.data = gFieldEffectObjectPalette4, .tag = 0x1007};
+const struct SpritePalette gFieldEffectObjectPaletteInfo5 = {.data = gFieldEffectObjectPalette5, .tag = 0x1010};
+const struct OamData gOamData_855C26C = {
+ .shape = 1,
+ .size = 2
+};
+
+const struct SpriteFrameImage gSpriteImageTable_855C274[] = {
+ obj_frame_tiles(gSpriteImage_855A970)
+};
+
+const struct SpriteFrameImage gSpriteImageTable_855C27C[] = {
+ obj_frame_tiles(gSpriteImage_855A9B0),
+ obj_frame_tiles(gSpriteImage_855AA70)
+};
+
+const struct SpriteFrameImage gSpriteImageTable_855C28C[] = {
+ obj_frame_tiles(gSpriteImage_855AB30)
+};
+
+const struct SpriteFrameImage gSpriteImageTable_855C294[] = {
+ {.data = gSpriteImage_855AD30, .size = 0x200} // the macro breaks down here
+};
+
+const struct Subsprite gSubspriteTable_855C29C[] = {
+ {.x = -12, .y = -8, .priority = 2, .tileOffset = 0, .shape = 1, .size = 0},
+ {.x = 4, .y = -8, .priority = 2, .tileOffset = 2, .shape = 0, .size = 0},
+ {.x = -12, .y = 0, .priority = 2, .tileOffset = 3, .shape = 1, .size = 0},
+ {.x = 4, .y = 0, .priority = 2, .tileOffset = 5, .shape = 0, .size = 0}
+};
+
+const struct SubspriteTable gUnknown_0855C2AC = subsprite_table(gSubspriteTable_855C29C);
+
+const struct Subsprite gSubspriteTable_855C2B4[] = {
+ {.x = -32, .y = -8, .priority = 2, .tileOffset = 0, .shape = 1, .size = 1},
+ {.x = 0, .y = -8, .priority = 2, .tileOffset = 4, .shape = 1, .size = 1},
+ {.x = -32, .y = 0, .priority = 2, .tileOffset = 8, .shape = 1, .size = 1},
+ {.x = 0, .y = 0, .priority = 2, .tileOffset = 12, .shape = 1, .size = 1}
+};
+
+const struct SubspriteTable gUnknown_0855C2C4 = subsprite_table(gSubspriteTable_855C2B4);
+
+const union AnimCmd gSpriteAnim_855C2CC[] = {
+ ANIMCMD_FRAME(.imageValue = 0, .duration = 1),
+ ANIMCMD_JUMP(0)
+};
+
+const union AnimCmd gSpriteAnim_855C2D4[] = {
+ ANIMCMD_FRAME(.imageValue = 0, .duration = 16),
+ ANIMCMD_FRAME(.imageValue = 1, .duration = 16),
+ ANIMCMD_FRAME(.imageValue = 0, .duration = 16),
+ ANIMCMD_FRAME(.imageValue = 1, .duration = 16),
+ ANIMCMD_FRAME(.imageValue = 0, .duration = 16),
+ ANIMCMD_FRAME(.imageValue = 1, .duration = 16),
+ ANIMCMD_FRAME(.imageValue = 0, .duration = 16),
+ ANIMCMD_FRAME(.imageValue = 1, .duration = 16),
+ ANIMCMD_END
+};
+
+const union AnimCmd *const gSpriteAnimTable_855C2F8[] = {
+ gSpriteAnim_855C2CC,
+ gSpriteAnim_855C2D4
+};
+
+const union AnimCmd *const gSpriteAnimTable_855C300[] = {
+ gSpriteAnim_855C2CC
+};
+
+const struct SpriteTemplate gSpriteTemplate_855C304 = {
+ .tileTag = 0xffff,
+ .paletteTag = 4103,
+ .oam = &gOamData_855C218,
+ .anims = gSpriteAnimTable_855C2F8,
+ .images = gSpriteImageTable_855C274,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_PokeballGlow
+};
+
+const struct SpriteTemplate gSpriteTemplate_855C31C = {
+ .tileTag = 0xffff,
+ .paletteTag = 4100,
+ .oam = &gOamData_855C220,
+ .anims = gSpriteAnimTable_855C2F8,
+ .images = gSpriteImageTable_855C27C,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_PokecenterMonitor
+};
+
+const struct SpriteTemplate gSpriteTemplate_855C334 = {
+ .tileTag = 0xffff,
+ .paletteTag = 4112,
+ .oam = &gOamData_855C220,
+ .anims = gSpriteAnimTable_855C300,
+ .images = gSpriteImageTable_855C28C,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_HallOfFameMonitor
+};
+
+const struct SpriteTemplate gSpriteTemplate_855C34C = {
+ .tileTag = 0xffff,
+ .paletteTag = 4112,
+ .oam = &gOamData_855C26C,
+ .anims = gSpriteAnimTable_855C300,
+ .images = gSpriteImageTable_855C294,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_HallOfFameMonitor
+};
+
+void (*const gUnknown_0855C364[])(struct Task *) = {
+ PokecenterHealEffect_0,
+ PokecenterHealEffect_1,
+ PokecenterHealEffect_2,
+ PokecenterHealEffect_3
+};
+
+void (*const gUnknown_0855C374[])(struct Task *) = {
+ HallOfFameRecordEffect_0,
+ HallOfFameRecordEffect_1,
+ HallOfFameRecordEffect_2,
+ HallOfFameRecordEffect_3
+};
+
+void (*const gUnknown_0855C384[])(struct Sprite *) = {
+ PokeballGlowEffect_0,
+ PokeballGlowEffect_1,
+ PokeballGlowEffect_2,
+ PokeballGlowEffect_3,
+ PokeballGlowEffect_4,
+ PokeballGlowEffect_5,
+ PokeballGlowEffect_6,
+ PokeballGlowEffect_7
+};
+
+const struct Coords16 gUnknown_0855C3A4[] = {
+ {.x = 0, .y = 0},
+ {.x = 6, .y = 0},
+ {.x = 0, .y = 4},
+ {.x = 6, .y = 4},
+ {.x = 0, .y = 8},
+ {.x = 6, .y = 8}
+};
+
+const u8 gUnknown_0855C3BC[] = {16, 12, 8, 0};
+const u8 gUnknown_0855C3C0[] = {16, 12, 8, 0};
+const u8 gUnknown_0855C3C4[] = { 0, 0, 0, 0};
+
+bool8 (*const gUnknown_0855C3C8[])(struct Task *) = {
+ sub_80B6BCC,
+ sub_80B6C74,
+ sub_80B6C90,
+ sub_80B6D04,
+ sub_80B6DBC,
+ sub_80B6DD8,
+ sub_80B6E18,
+};
+
+bool8 (*const gUnknown_0855C3E4[])(struct Task *) = {
+ sub_80B6EC0,
+ sub_80B6EE0,
+ sub_80B6F50,
+ sub_80B6F74,
+ sub_80B6F84,
+ sub_80B6FA8,
+};
+
+bool8 (*const gUnknown_0855C3FC[])(struct Task *) = {
+ sub_80B7114,
+ sub_80B7190,
+ sub_80B71D0,
+ sub_80B7230,
+ sub_80B7270,
+ sub_80B72D0,
+ sub_80B72F4,
+};
+
+bool8 (*const gUnknown_0855C418[])(struct Task *, struct MapObject *) = {
+ sub_80B73D0,
+ waterfall_1_do_anim_probably,
+ waterfall_2_wait_anim_finish_probably,
+ sub_80B7450,
+ sub_80B7478,
+};
+
+bool8 (*const gUnknown_0855C42C[])(struct Task *) = {
+ dive_1_lock,
+ dive_2_unknown,
+ dive_3_unknown,
+};
+
+bool8 (*const gUnknown_0855C438[])(struct Task *, struct MapObject *, struct Sprite *) = {
+ sub_80B764C,
+ sub_80B7684,
+ sub_80B76B8,
+ sub_80B7704,
+ sub_80B77F8,
+ sub_80B7814,
+};
+
+bool8 (*const gUnknown_0855C450[])(struct Task *, struct MapObject *, struct Sprite *) = {
+ sub_80B78EC,
+ sub_80B791C,
+ sub_80B7968,
+ sub_80B79BC,
+};
+
+bool8 (*const gUnknown_0855C460[])(struct Task *, struct MapObject *, struct Sprite *) = {
+ sub_80B7AE8,
+ sub_80B7B18,
+ sub_80B7B94,
+ sub_80B7BCC,
+ sub_80B7BF4,
+};
+
+void (*const gUnknown_0855C474[])(struct Task *) = {
+ sub_80B7D14,
+ sub_80B7D34,
+};
// .text
+
+u32 FieldEffectStart(u8 id)
+{
+ u8 *script;
+ u32 val;
+
+ FieldEffectActiveListAdd(id);
+
+ script = gFieldEffectScriptPointers[id];
+
+ while (gFieldEffectScriptFuncs[*script](&script, &val))
+ ;
+
+ return val;
+}
+
+bool8 FieldEffectCmd_loadtiles(u8 **script, u32 *val)
+{
+ (*script)++;
+ FieldEffectScript_LoadTiles(script);
+ return TRUE;
+}
+
+bool8 FieldEffectCmd_loadfadedpal(u8 **script, u32 *val)
+{
+ (*script)++;
+ FieldEffectScript_LoadFadedPalette(script);
+ return TRUE;
+}
+
+bool8 FieldEffectCmd_loadpal(u8 **script, u32 *val)
+{
+ (*script)++;
+ FieldEffectScript_LoadPalette(script);
+ return TRUE;
+}
+
+bool8 FieldEffectCmd_callnative(u8 **script, u32 *val)
+{
+ (*script)++;
+ FieldEffectScript_CallNative(script, val);
+ return TRUE;
+}
+
+bool8 FieldEffectCmd_end(u8 **script, u32 *val)
+{
+ return FALSE;
+}
+
+bool8 FieldEffectCmd_loadgfx_callnative(u8 **script, u32 *val)
+{
+ (*script)++;
+ FieldEffectScript_LoadTiles(script);
+ FieldEffectScript_LoadFadedPalette(script);
+ FieldEffectScript_CallNative(script, val);
+ return TRUE;
+}
+
+bool8 FieldEffectCmd_loadtiles_callnative(u8 **script, u32 *val)
+{
+ (*script)++;
+ FieldEffectScript_LoadTiles(script);
+ FieldEffectScript_CallNative(script, val);
+ return TRUE;
+}
+
+bool8 FieldEffectCmd_loadfadedpal_callnative(u8 **script, u32 *val)
+{
+ (*script)++;
+ FieldEffectScript_LoadFadedPalette(script);
+ FieldEffectScript_CallNative(script, val);
+ return TRUE;
+}
+
+u32 FieldEffectScript_ReadWord(u8 **script)
+{
+ return (*script)[0]
+ + ((*script)[1] << 8)
+ + ((*script)[2] << 16)
+ + ((*script)[3] << 24);
+}
+
+void FieldEffectScript_LoadTiles(u8 **script)
+{
+ struct SpriteSheet *sheet = (struct SpriteSheet *)FieldEffectScript_ReadWord(script);
+ if (GetSpriteTileStartByTag(sheet->tag) == 0xFFFF)
+ LoadSpriteSheet(sheet);
+ (*script) += 4;
+}
+
+void FieldEffectScript_LoadFadedPalette(u8 **script)
+{
+ struct SpritePalette *palette = (struct SpritePalette *)FieldEffectScript_ReadWord(script);
+ LoadSpritePalette(palette);
+ UpdateSpritePaletteWithWeather(IndexOfSpritePaletteTag(palette->tag));
+ (*script) += 4;
+}
+
+void FieldEffectScript_LoadPalette(u8 **script)
+{
+ struct SpritePalette *palette = (struct SpritePalette *)FieldEffectScript_ReadWord(script);
+ LoadSpritePalette(palette);
+ (*script) += 4;
+}
+
+void FieldEffectScript_CallNative(u8 **script, u32 *val)
+{
+ u32 (*func)(void) = (u32 (*)(void))FieldEffectScript_ReadWord(script);
+ *val = func();
+ (*script) += 4;
+}
+
+void FieldEffectFreeGraphicsResources(struct Sprite *sprite)
+{
+ u16 sheetTileStart = sprite->sheetTileStart;
+ u32 paletteNum = sprite->oam.paletteNum;
+ DestroySprite(sprite);
+ FieldEffectFreeTilesIfUnused(sheetTileStart);
+ FieldEffectFreePaletteIfUnused(paletteNum);
+}
+
+void FieldEffectStop(struct Sprite *sprite, u8 id)
+{
+ FieldEffectFreeGraphicsResources(sprite);
+ FieldEffectActiveListRemove(id);
+}
+
+void FieldEffectFreeTilesIfUnused(u16 tileStart)
+{
+ u8 i;
+ u16 tag = GetSpriteTileTagByTileStart(tileStart);
+
+ if (tag != 0xFFFF)
+ {
+ for (i = 0; i < MAX_SPRITES; i++)
+ if (gSprites[i].inUse && gSprites[i].usingSheet && tileStart == gSprites[i].sheetTileStart)
+ return;
+ FreeSpriteTilesByTag(tag);
+ }
+}
+
+void FieldEffectFreePaletteIfUnused(u8 paletteNum)
+{
+ u8 i;
+ u16 tag = GetSpritePaletteTagByPaletteNum(paletteNum);
+
+ if (tag != 0xFFFF)
+ {
+ for (i = 0; i < MAX_SPRITES; i++)
+ if (gSprites[i].inUse && gSprites[i].oam.paletteNum == paletteNum)
+ return;
+ FreeSpritePaletteByTag(tag);
+ }
+}
+
+void FieldEffectActiveListClear(void)
+{
+ u8 i;
+ for (i = 0; i < ARRAY_COUNT(sActiveList); i++)
+ sActiveList[i] = 0xFF;
+}
+
+void FieldEffectActiveListAdd(u8 id)
+{
+ u8 i;
+ for (i = 0; i < ARRAY_COUNT(sActiveList); i++)
+ {
+ if (sActiveList[i] == 0xFF)
+ {
+ sActiveList[i] = id;
+ return;
+ }
+ }
+}
+
+void FieldEffectActiveListRemove(u8 id)
+{
+ u8 i;
+ for (i = 0; i < ARRAY_COUNT(sActiveList); i++)
+ {
+ if (sActiveList[i] == id)
+ {
+ sActiveList[i] = 0xFF;
+ return;
+ }
+ }
+}
+
+bool8 FieldEffectActiveListContains(u8 id)
+{
+ u8 i;
+ for (i = 0; i < ARRAY_COUNT(sActiveList); i++)
+ if (sActiveList[i] == id)
+ return TRUE;
+ return FALSE;
+}
+
+u8 CreateTrainerSprite(u8 trainerSpriteID, s16 x, s16 y, u8 subpriority, u8 *buffer)
+{
+ struct SpriteTemplate spriteTemplate;
+ LoadCompressedObjectPaletteOverrideBuffer(&gTrainerFrontPicPaletteTable[trainerSpriteID], buffer);
+ LoadCompressedObjectPicOverrideBuffer(&gTrainerFrontPicTable[trainerSpriteID], buffer);
+ spriteTemplate.tileTag = gTrainerFrontPicTable[trainerSpriteID].tag;
+ spriteTemplate.paletteTag = gTrainerFrontPicPaletteTable[trainerSpriteID].tag;
+ spriteTemplate.oam = &gNewGameBirchOamAttributes;
+ spriteTemplate.anims = gDummySpriteAnimTable;
+ spriteTemplate.images = NULL;
+ spriteTemplate.affineAnims = gDummySpriteAffineAnimTable;
+ spriteTemplate.callback = SpriteCallbackDummy;
+ return CreateSprite(&spriteTemplate, x, y, subpriority);
+}
+
+void LoadTrainerGfx_TrainerCard(u8 gender, u16 palOffset, u8 *dest)
+{
+ LZDecompressVram(gTrainerFrontPicTable[gender].data, dest);
+ LoadCompressedPalette(gTrainerFrontPicPaletteTable[gender].data, palOffset, 0x20);
+}
+
+u8 AddNewGameBirchObject(s16 x, s16 y, u8 subpriority)
+{
+ LoadSpritePalette(&gNewGameBirchObjectPaletteInfo);
+ return CreateSprite(&gNewGameBirchObjectTemplate, x, y, subpriority);
+}
+
+#ifdef NONMATCHING
+u8 CreateMonSprite_PicBox(u16 species, s16 x, s16 y)
+{
+ u16 spriteId = sub_818D7D8(species, 0, 0x8000, 1, x, y, 0, gMonPaletteTable[species].tag);
+ PreservePaletteInWeather(IndexOfSpritePaletteTag(gMonPaletteTable[species].tag) + 0x10);
+ if (spriteId == 0xFFFF)
+ return 0x40;
+
+ return spriteId;
+}
+#else
+NAKED
+u8 CreateMonSprite_PicBox(u16 species, s16 x, s16 y)
+{
+ asm_unified("push {r4,r5,lr}\n\
+ sub sp, 0x10\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ movs r3, 0x80\n\
+ lsls r3, 8\n\
+ lsls r1, 16\n\
+ asrs r1, 16\n\
+ str r1, [sp]\n\
+ lsls r2, 16\n\
+ asrs r2, 16\n\
+ str r2, [sp, 0x4]\n\
+ movs r1, 0\n\
+ str r1, [sp, 0x8]\n\
+ ldr r1, =gMonPaletteTable\n\
+ lsls r4, r0, 3\n\
+ adds r4, r1\n\
+ ldrh r1, [r4, 0x4]\n\
+ str r1, [sp, 0xC]\n\
+ movs r1, 0\n\
+ adds r2, r3, 0\n\
+ movs r3, 0x1\n\
+ bl sub_818D7D8\n\
+ lsls r0, 16\n\
+ lsrs r5, r0, 16\n\
+ ldrh r0, [r4, 0x4]\n\
+ bl IndexOfSpritePaletteTag\n\
+ adds r0, 0x10\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ bl PreservePaletteInWeather\n\
+ ldr r0, =0x0000ffff\n\
+ cmp r5, r0\n\
+ beq _080B5FDC\n\
+ lsls r0, r5, 24\n\
+ lsrs r0, 24\n\
+ b _080B5FDE\n\
+ .pool\n\
+_080B5FDC:\n\
+ movs r0, 0x40\n\
+_080B5FDE:\n\
+ add sp, 0x10\n\
+ pop {r4,r5}\n\
+ pop {r1}\n\
+ bx r1");
+}
+#endif //NONMATCHING
+
+u8 CreateMonSprite_FieldMove(u16 species, u32 d, u32 g, s16 x, s16 y, u8 subpriority)
+{
+ const struct CompressedSpritePalette *spritePalette = GetMonSpritePalStructFromOtIdPersonality(species, d, g);
+ u16 spriteId = sub_818D7D8(species, d, g, 1, x, y, 0, spritePalette->tag);
+ PreservePaletteInWeather(IndexOfSpritePaletteTag(spritePalette->tag) + 0x10);
+ if (spriteId == 0xFFFF)
+ return 0x40;
+
+ return spriteId;
+}
+
+void FreeResourcesAndDestroySprite(struct Sprite *sprite, u8 spriteId)
+{
+ ResetPreservedPalettesInWeather();
+ if (sprite->oam.affineMode != 0)
+ {
+ FreeOamMatrix(sprite->oam.matrixNum);
+ }
+ sub_818D820(spriteId);
+}
+
+#ifdef NONMATCHING
+void MultiplyInvertedPaletteRGBComponents(u16 i, u8 r, u8 g, u8 b)
+{
+ int curRed;
+ int curGreen;
+ int curBlue;
+
+ curRed = gPlttBufferUnfaded[i] & 0x1f;
+ curGreen = (gPlttBufferUnfaded[i] & (0x1f << 5)) >> 5;
+ curBlue = (gPlttBufferUnfaded[i] & (0x1f << 10)) >> 10;
+ curRed += (((0x1f - curRed) * r) >> 4);
+ curGreen += (((0x1f - curGreen) * g) >> 4);
+ curBlue += (((0x1f - curBlue) * b) >> 4);
+ gPlttBufferFaded[i] = RGB(curRed, curGreen, curBlue);
+}
+
+void MultiplyPaletteRGBComponents(u16 i, u8 r, u8 g, u8 b)
+{
+ int curRed;
+ int curGreen;
+ int curBlue;
+
+ curRed = gPlttBufferUnfaded[i] & 0x1f;
+ curGreen = (gPlttBufferUnfaded[i] & (0x1f << 5)) >> 5;
+ curBlue = (gPlttBufferUnfaded[i] & (0x1f << 10)) >> 10;
+ curRed -= ((curRed * r) >> 4);
+ curGreen -= ((curGreen * g) >> 4);
+ curBlue -= ((curBlue * b) >> 4);
+ gPlttBufferFaded[i] = RGB(curRed, curGreen, curBlue);
+}
+#else
+NAKED
+void MultiplyInvertedPaletteRGBComponents(u16 i, u8 r, u8 g, u8 b)
+{
+ asm(".syntax unified\n"
+ "\tpush {r4-r7,lr}\n"
+ "\tmov r7, r9\n"
+ "\tmov r6, r8\n"
+ "\tpush {r6,r7}\n"
+ "\tlsls r0, 16\n"
+ "\tlsls r1, 24\n"
+ "\tlsrs r1, 24\n"
+ "\tlsls r2, 24\n"
+ "\tlsrs r2, 24\n"
+ "\tlsls r3, 24\n"
+ "\tlsrs r3, 24\n"
+ "\tldr r4, _08085D00 @ =gPlttBufferUnfaded\n"
+ "\tlsrs r0, 15\n"
+ "\tadds r4, r0, r4\n"
+ "\tldrh r4, [r4]\n"
+ "\tmovs r5, 0x1F\n"
+ "\tmov r9, r5\n"
+ "\tmov r8, r4\n"
+ "\tmov r6, r8\n"
+ "\tands r6, r5\n"
+ "\tmov r8, r6\n"
+ "\tmovs r6, 0xF8\n"
+ "\tlsls r6, 2\n"
+ "\tands r6, r4\n"
+ "\tlsrs r6, 5\n"
+ "\tmovs r5, 0xF8\n"
+ "\tlsls r5, 7\n"
+ "\tands r4, r5\n"
+ "\tlsrs r4, 10\n"
+ "\tmov r7, r9\n"
+ "\tmov r5, r8\n"
+ "\tsubs r7, r5\n"
+ "\tmov r12, r7\n"
+ "\tmov r7, r12\n"
+ "\tmuls r7, r1\n"
+ "\tadds r1, r7, 0\n"
+ "\tasrs r1, 4\n"
+ "\tadd r8, r1\n"
+ "\tmov r5, r9\n"
+ "\tsubs r1, r5, r6\n"
+ "\tmuls r1, r2\n"
+ "\tasrs r1, 4\n"
+ "\tadds r6, r1\n"
+ "\tsubs r5, r4\n"
+ "\tmov r9, r5\n"
+ "\tmov r1, r9\n"
+ "\tmuls r1, r3\n"
+ "\tasrs r1, 4\n"
+ "\tadds r4, r1\n"
+ "\tmov r7, r8\n"
+ "\tlsls r7, 16\n"
+ "\tlsls r6, 21\n"
+ "\torrs r6, r7\n"
+ "\tlsls r4, 26\n"
+ "\torrs r4, r6\n"
+ "\tlsrs r4, 16\n"
+ "\tldr r1, _08085D04 @ =gPlttBufferFaded\n"
+ "\tadds r0, r1\n"
+ "\tstrh r4, [r0]\n"
+ "\tpop {r3,r4}\n"
+ "\tmov r8, r3\n"
+ "\tmov r9, r4\n"
+ "\tpop {r4-r7}\n"
+ "\tpop {r0}\n"
+ "\tbx r0\n"
+ "\t.align 2, 0\n"
+ "_08085D00: .4byte gPlttBufferUnfaded\n"
+ "_08085D04: .4byte gPlttBufferFaded\n"
+ ".syntax divided");
+}
+
+NAKED
+void MultiplyPaletteRGBComponents(u16 i, u8 r, u8 g, u8 b)
+{
+ asm(".syntax unified\n"
+ "\tpush {r4-r6,lr}\n"
+ "\tmov r6, r8\n"
+ "\tpush {r6}\n"
+ "\tlsls r0, 16\n"
+ "\tlsls r1, 24\n"
+ "\tlsrs r1, 24\n"
+ "\tlsls r2, 24\n"
+ "\tlsrs r2, 24\n"
+ "\tlsls r3, 24\n"
+ "\tlsrs r3, 24\n"
+ "\tldr r4, _08085D78 @ =gPlttBufferUnfaded\n"
+ "\tlsrs r0, 15\n"
+ "\tadds r4, r0, r4\n"
+ "\tldrh r4, [r4]\n"
+ "\tmovs r5, 0x1F\n"
+ "\tmov r8, r5\n"
+ "\tmov r6, r8\n"
+ "\tands r6, r4\n"
+ "\tmov r8, r6\n"
+ "\tmovs r5, 0xF8\n"
+ "\tlsls r5, 2\n"
+ "\tands r5, r4\n"
+ "\tlsrs r5, 5\n"
+ "\tmovs r6, 0xF8\n"
+ "\tlsls r6, 7\n"
+ "\tands r4, r6\n"
+ "\tlsrs r4, 10\n"
+ "\tmov r6, r8\n"
+ "\tmuls r6, r1\n"
+ "\tadds r1, r6, 0\n"
+ "\tasrs r1, 4\n"
+ "\tmov r6, r8\n"
+ "\tsubs r6, r1\n"
+ "\tadds r1, r5, 0\n"
+ "\tmuls r1, r2\n"
+ "\tasrs r1, 4\n"
+ "\tsubs r5, r1\n"
+ "\tadds r1, r4, 0\n"
+ "\tmuls r1, r3\n"
+ "\tasrs r1, 4\n"
+ "\tsubs r4, r1\n"
+ "\tlsls r6, 16\n"
+ "\tlsls r5, 21\n"
+ "\torrs r5, r6\n"
+ "\tlsls r4, 26\n"
+ "\torrs r4, r5\n"
+ "\tlsrs r4, 16\n"
+ "\tldr r1, _08085D7C @ =gPlttBufferFaded\n"
+ "\tadds r0, r1\n"
+ "\tstrh r4, [r0]\n"
+ "\tpop {r3}\n"
+ "\tmov r8, r3\n"
+ "\tpop {r4-r6}\n"
+ "\tpop {r0}\n"
+ "\tbx r0\n"
+ "\t.align 2, 0\n"
+ "_08085D78: .4byte gPlttBufferUnfaded\n"
+ "_08085D7C: .4byte gPlttBufferFaded\n"
+ ".syntax divided");
+}
+#endif
+
+void Task_PokecenterHeal(u8 taskId);
+u8 CreatePokeballGlowSprite(s16, s16, s16, u16);
+u8 PokecenterHealEffectHelper(s16, s16);
+
+bool8 FldEff_PokecenterHeal(void)
+{
+ u8 nPokemon;
+ struct Task *task;
+
+ nPokemon = CalculatePlayerPartyCount();
+ task = &gTasks[CreateTask(Task_PokecenterHeal, 0xff)];
+ task->data[1] = nPokemon;
+ task->data[2] = 0x5d;
+ task->data[3] = 0x24;
+ task->data[4] = 0x7c;
+ task->data[5] = 0x18;
+ return FALSE;
+}
+
+void Task_PokecenterHeal(u8 taskId)
+{
+ struct Task *task;
+ task = &gTasks[taskId];
+ gUnknown_0855C364[task->data[0]](task);
+}
+
+void PokecenterHealEffect_0(struct Task *task)
+{
+ task->data[0]++;
+ task->data[6] = CreatePokeballGlowSprite(task->data[1], task->data[2], task->data[3], 1);
+ task->data[7] = PokecenterHealEffectHelper(task->data[4], task->data[5]);
+}
+
+void PokecenterHealEffect_1(struct Task *task)
+{
+ if (gSprites[task->data[6]].data[0] > 1)
+ {
+ gSprites[task->data[7]].data[0]++;
+ task->data[0]++;
+ }
+}
+
+void PokecenterHealEffect_2(struct Task *task)
+{
+ if (gSprites[task->data[6]].data[0] > 4)
+ {
+ task->data[0]++;
+ }
+}
+
+void PokecenterHealEffect_3(struct Task *task)
+{
+ if (gSprites[task->data[6]].data[0] > 6)
+ {
+ DestroySprite(&gSprites[task->data[6]]);
+ FieldEffectActiveListRemove(FLDEFF_POKECENTER_HEAL);
+ DestroyTask(FindTaskIdByFunc(Task_PokecenterHeal));
+ }
+}
+
+void Task_HallOfFameRecord(u8 taskId);
+void HallOfFameRecordEffectHelper(s16, s16, s16, u8);
+
+bool8 FldEff_HallOfFameRecord(void)
+{
+ u8 nPokemon;
+ struct Task *task;
+
+ nPokemon = CalculatePlayerPartyCount();
+ task = &gTasks[CreateTask(Task_HallOfFameRecord, 0xff)];
+ task->data[1] = nPokemon;
+ task->data[2] = 0x75;
+ task->data[3] = 0x34;
+ return FALSE;
+}
+
+void Task_HallOfFameRecord(u8 taskId)
+{
+ struct Task *task;
+ task = &gTasks[taskId];
+ gUnknown_0855C374[task->data[0]](task);
+}
+
+void HallOfFameRecordEffect_0(struct Task *task)
+{
+ u8 taskId;
+ task->data[0]++;
+ task->data[6] = CreatePokeballGlowSprite(task->data[1], task->data[2], task->data[3], 0);
+ taskId = FindTaskIdByFunc(Task_HallOfFameRecord);
+ HallOfFameRecordEffectHelper(taskId, 0x78, 0x18, 0);
+ HallOfFameRecordEffectHelper(taskId, 0x28, 0x08, 1);
+ HallOfFameRecordEffectHelper(taskId, 0x48, 0x08, 1);
+ HallOfFameRecordEffectHelper(taskId, 0xa8, 0x08, 1);
+ HallOfFameRecordEffectHelper(taskId, 0xc8, 0x08, 1);
+}
+
+void HallOfFameRecordEffect_1(struct Task *task)
+{
+ if (gSprites[task->data[6]].data[0] > 1)
+ {
+ task->data[15]++; // was this ever initialized? is this ever used?
+ task->data[0]++;
+ }
+}
+
+void HallOfFameRecordEffect_2(struct Task *task)
+{
+ if (gSprites[task->data[6]].data[0] > 4)
+ {
+ task->data[0]++;
+ }
+}
+
+void HallOfFameRecordEffect_3(struct Task *task)
+{
+ if (gSprites[task->data[6]].data[0] > 6)
+ {
+ DestroySprite(&gSprites[task->data[6]]);
+ FieldEffectActiveListRemove(FLDEFF_HALL_OF_FAME_RECORD);
+ DestroyTask(FindTaskIdByFunc(Task_HallOfFameRecord));
+ }
+}
+
+void SpriteCB_PokeballGlowEffect(struct Sprite *);
+
+u8 CreatePokeballGlowSprite(s16 data6, s16 x, s16 y, u16 data5)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+ spriteId = CreateInvisibleSprite(SpriteCB_PokeballGlowEffect);
+ sprite = &gSprites[spriteId];
+ sprite->pos2.x = x;
+ sprite->pos2.y = y;
+ sprite->data[5] = data5;
+ sprite->data[6] = data6;
+ sprite->data[7] = spriteId;
+ return spriteId;
+}
+
+void SpriteCB_PokeballGlowEffect(struct Sprite *sprite)
+{
+ gUnknown_0855C384[sprite->data[0]](sprite);
+}
+
+void PokeballGlowEffect_0(struct Sprite *sprite)
+{
+ u8 endSpriteId;
+ if (sprite->data[1] == 0 || (--sprite->data[1]) == 0)
+ {
+ sprite->data[1] = 25;
+ endSpriteId = CreateSpriteAtEnd(&gSpriteTemplate_855C304, gUnknown_0855C3A4[sprite->data[2]].x + sprite->pos2.x, gUnknown_0855C3A4[sprite->data[2]].y + sprite->pos2.y, 0);
+ gSprites[endSpriteId].oam.priority = 2;
+ gSprites[endSpriteId].data[0] = sprite->data[7];
+ sprite->data[2]++;
+ sprite->data[6]--;
+ PlaySE(SE_BOWA);
+ }
+ if (sprite->data[6] == 0)
+ {
+ sprite->data[1] = 32;
+ sprite->data[0]++;
+ }
+}
+
+void PokeballGlowEffect_1(struct Sprite *sprite)
+{
+ if ((--sprite->data[1]) == 0)
+ {
+ sprite->data[0]++;
+ sprite->data[1] = 8;
+ sprite->data[2] = 0;
+ sprite->data[3] = 0;
+ if (sprite->data[5])
+ {
+ PlayFanfare(MUS_ME_ASA);
+ }
+ }
+}
+
+void PokeballGlowEffect_2(struct Sprite *sprite)
+{
+ u8 phase;
+ if ((--sprite->data[1]) == 0)
+ {
+ sprite->data[1] = 8;
+ sprite->data[2]++;
+ sprite->data[2] &= 3;
+ if (sprite->data[2] == 0)
+ {
+ sprite->data[3]++;
+ }
+ }
+ phase = (sprite->data[2] + 3) & 3;
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x108, gUnknown_0855C3BC[phase], gUnknown_0855C3C0[phase], gUnknown_0855C3C4[phase]);
+ phase = (sprite->data[2] + 2) & 3;
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x106, gUnknown_0855C3BC[phase], gUnknown_0855C3C0[phase], gUnknown_0855C3C4[phase]);
+ phase = (sprite->data[2] + 1) & 3;
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x102, gUnknown_0855C3BC[phase], gUnknown_0855C3C0[phase], gUnknown_0855C3C4[phase]);
+ phase = sprite->data[2];
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x105, gUnknown_0855C3BC[phase], gUnknown_0855C3C0[phase], gUnknown_0855C3C4[phase]);
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x103, gUnknown_0855C3BC[phase], gUnknown_0855C3C0[phase], gUnknown_0855C3C4[phase]);
+ if (sprite->data[3] > 2)
+ {
+ sprite->data[0]++;
+ sprite->data[1] = 8;
+ sprite->data[2] = 0;
+ }
+}
+
+void PokeballGlowEffect_3(struct Sprite *sprite)
+{
+ u8 phase;
+ if ((--sprite->data[1]) == 0)
+ {
+ sprite->data[1] = 8;
+ sprite->data[2]++;
+ sprite->data[2] &= 3;
+ if (sprite->data[2] == 3)
+ {
+ sprite->data[0]++;
+ sprite->data[1] = 30;
+ }
+ }
+ phase = sprite->data[2];
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x108, gUnknown_0855C3BC[phase], gUnknown_0855C3C0[phase], gUnknown_0855C3C4[phase]);
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x106, gUnknown_0855C3BC[phase], gUnknown_0855C3C0[phase], gUnknown_0855C3C4[phase]);
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x102, gUnknown_0855C3BC[phase], gUnknown_0855C3C0[phase], gUnknown_0855C3C4[phase]);
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x105, gUnknown_0855C3BC[phase], gUnknown_0855C3C0[phase], gUnknown_0855C3C4[phase]);
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x103, gUnknown_0855C3BC[phase], gUnknown_0855C3C0[phase], gUnknown_0855C3C4[phase]);
+}
+
+void PokeballGlowEffect_4(struct Sprite *sprite)
+{
+ if ((--sprite->data[1]) == 0)
+ {
+ sprite->data[0]++;
+ }
+}
+
+void PokeballGlowEffect_5(struct Sprite *sprite)
+{
+ sprite->data[0]++;
+}
+
+void PokeballGlowEffect_6(struct Sprite *sprite)
+{
+ if (sprite->data[5] == 0 || IsFanfareTaskInactive())
+ {
+ sprite->data[0]++;
+ }
+}
+
+void PokeballGlowEffect_7(struct Sprite *sprite)
+{
+}
+
+void SpriteCB_PokeballGlow(struct Sprite *sprite)
+{
+ if (gSprites[sprite->data[0]].data[0] > 4)
+ {
+ FieldEffectFreeGraphicsResources(sprite);
+ }
+}
+
+u8 PokecenterHealEffectHelper(s16 x, s16 y)
+{
+ u8 spriteIdAtEnd;
+ struct Sprite *sprite;
+ spriteIdAtEnd = CreateSpriteAtEnd(&gSpriteTemplate_855C31C, x, y, 0);
+ sprite = &gSprites[spriteIdAtEnd];
+ sprite->oam.priority = 2;
+ sprite->invisible = 1;
+ SetSubspriteTables(sprite, &gUnknown_0855C2AC);
+ return spriteIdAtEnd;
+}
+
+void SpriteCB_PokecenterMonitor(struct Sprite *sprite)
+{
+ if (sprite->data[0] != 0)
+ {
+ sprite->data[0] = 0;
+ sprite->invisible = 0;
+ StartSpriteAnim(sprite, 1);
+ }
+ if (sprite->animEnded)
+ {
+ FieldEffectFreeGraphicsResources(sprite);
+ }
+}
+
+void HallOfFameRecordEffectHelper(s16 a0, s16 a1, s16 a2, u8 a3)
+{
+ u8 spriteIdAtEnd;
+ if (!a3)
+ {
+ spriteIdAtEnd = CreateSpriteAtEnd(&gSpriteTemplate_855C334, a1, a2, 0);
+ SetSubspriteTables(&gSprites[spriteIdAtEnd], &gUnknown_0855C2C4);
+ } else
+ {
+ spriteIdAtEnd = CreateSpriteAtEnd(&gSpriteTemplate_855C34C, a1, a2, 0);
+ }
+ gSprites[spriteIdAtEnd].invisible = 1;
+ gSprites[spriteIdAtEnd].data[0] = a0;
+}
+
+void SpriteCB_HallOfFameMonitor(struct Sprite *sprite)
+{
+ if (gTasks[sprite->data[0]].data[15])
+ {
+ if (sprite->data[1] == 0 || (--sprite->data[1]) == 0)
+ {
+ sprite->data[1] = 16;
+ sprite->invisible ^= 1;
+ }
+ sprite->data[2]++;
+ }
+ if (sprite->data[2] > 127)
+ {
+ FieldEffectFreeGraphicsResources(sprite);
+ }
+}
+
+void mapldr_080842E8(void);
+void mapldr_08084390(void);
+void task00_8084310(u8);
+void c3_080843F8(u8);
+
+void sub_80B69DC(void)
+{
+ SetMainCallback2(CB2_ReturnToField);
+ gFieldCallback = mapldr_080842E8;
+}
+
+void mapldr_080842E8(void)
+{
+ pal_fill_black();
+ CreateTask(task00_8084310, 0);
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ gFieldCallback = NULL;
+}
+
+void task00_8084310(u8 taskId)
+{
+ struct Task *task;
+ task = &gTasks[taskId];
+ if (!task->data[0])
+ {
+ if (!IsWeatherNotFadingIn())
+ {
+ return;
+ }
+ gFieldEffectArguments[0] = GetCursorSelectionMonId();
+ if ((int)gFieldEffectArguments[0] > 5)
+ {
+ gFieldEffectArguments[0] = 0;
+ }
+ FieldEffectStart(FLDEFF_USE_FLY);
+ task->data[0]++;
+ }
+ if (!FieldEffectActiveListContains(FLDEFF_USE_FLY))
+ {
+ Overworld_ResetStateAfterFly();
+ warp_in();
+ SetMainCallback2(CB2_LoadMap);
+ gFieldCallback = mapldr_08084390;
+ DestroyTask(taskId);
+ }
+}
+
+void mapldr_08084390(void)
+{
+ Overworld_PlaySpecialMapMusic();
+ pal_fill_black();
+ CreateTask(c3_080843F8, 0);
+ gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_13 = 1;
+ if (gPlayerAvatar.flags & 0x08)
+ {
+ FieldObjectTurn(&gMapObjects[gPlayerAvatar.mapObjectId], DIR_WEST);
+ }
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ gFieldCallback = NULL;
+}
+
+void c3_080843F8(u8 taskId)
+{
+ struct Task *task;
+ task = &gTasks[taskId];
+ if (task->data[0] == 0)
+ {
+ if (gPaletteFade.active)
+ {
+ return;
+ }
+ FieldEffectStart(FLDEFF_FLY_IN);
+ task->data[0]++;
+ }
+ if (!FieldEffectActiveListContains(FLDEFF_FLY_IN))
+ {
+ ScriptContext2_Disable();
+ UnfreezeMapObjects();
+ DestroyTask(taskId);
+ }
+}
+
+extern void pal_fill_for_maplights(void);
+void sub_80B6B94(u8);
+extern void CameraObjectReset2(void);
+extern void CameraObjectReset1(void);
+
+void sub_80B6B68(void)
+{
+ Overworld_PlaySpecialMapMusic();
+ pal_fill_for_maplights();
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ CreateTask(sub_80B6B94, 0);
+ gFieldCallback = NULL;
+}
+
+void sub_80B6B94(u8 taskId)
+{
+ struct Task *task;
+ task = &gTasks[taskId];
+ while (gUnknown_0855C3C8[task->data[0]](task)); // return code signifies whether to continue blocking here
+}
+
+bool8 sub_80B6BCC(struct Task *task) // gUnknown_0855C3C8[0]
+{
+ struct MapObject *playerObject;
+ struct Sprite *playerSprite;
+ playerObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ playerSprite = &gSprites[gPlayerAvatar.spriteId];
+ CameraObjectReset2();
+ gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_13 = 1;
+ gPlayerAvatar.preventStep = TRUE;
+ FieldObjectSetSpecialAnim(playerObject, GetFaceDirectionAnimId(player_get_direction_lower_nybble()));
+ task->data[4] = playerSprite->subspriteMode;
+ playerObject->mapobj_bit_26 = 1;
+ playerSprite->oam.priority = 1;
+ playerSprite->subspriteMode = 2;
+ task->data[0]++;
+ return TRUE;
+}
+
+bool8 sub_80B6C74(struct Task *task) // gUnknown_0855C3C8[1]
+{
+ if (IsWeatherNotFadingIn())
+ {
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+bool8 sub_80B6C90(struct Task *task) // gUnknown_0855C3C8[2]
+{
+ struct Sprite *sprite;
+ s16 centerToCornerVecY;
+ sprite = &gSprites[gPlayerAvatar.spriteId];
+ centerToCornerVecY = -(sprite->centerToCornerVecY << 1);
+ sprite->pos2.y = -(sprite->pos1.y + sprite->centerToCornerVecY + gSpriteCoordOffsetY + centerToCornerVecY);
+ task->data[1] = 1;
+ task->data[2] = 0;
+ gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_13 = 0;
+ PlaySE(SE_RU_HYUU);
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 sub_80B6D04(struct Task *task)
+{
+ struct MapObject *mapObject;
+ struct Sprite *sprite;
+
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ sprite = &gSprites[gPlayerAvatar.spriteId];
+ sprite->pos2.y += task->data[1];
+ if (task->data[1] < 8)
+ {
+ task->data[2] += task->data[1];
+ if (task->data[2] & 0xf)
+ {
+ task->data[1] <<= 1;
+ }
+ }
+ if (task->data[3] == 0 && sprite->pos2.y >= -16)
+ {
+ task->data[3]++;
+ mapObject->mapobj_bit_26 = 0;
+ sprite->subspriteMode = task->data[4];
+ mapObject->mapobj_bit_2 = 1;
+ }
+ if (sprite->pos2.y >= 0)
+ {
+ PlaySE(SE_W070);
+ mapObject->mapobj_bit_3 = 1;
+ mapObject->mapobj_bit_5 = 1;
+ sprite->pos2.y = 0;
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+bool8 sub_80B6DBC(struct Task *task)
+{
+ task->data[0]++;
+ task->data[1] = 4;
+ task->data[2] = 0;
+ SetCameraPanningCallback(NULL);
+ return TRUE;
+}
+
+bool8 sub_80B6DD8(struct Task *task)
+{
+ SetCameraPanning(0, task->data[1]);
+ task->data[1] = -task->data[1];
+ task->data[2]++;
+ if ((task->data[2] & 3) == 0)
+ {
+ task->data[1] >>= 1;
+ }
+ if (task->data[1] == 0)
+ {
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+bool8 sub_80B6E18(struct Task *task)
+{
+ gPlayerAvatar.preventStep = FALSE;
+ ScriptContext2_Disable();
+ CameraObjectReset1();
+ UnfreezeMapObjects();
+ InstallCameraPanAheadCallback();
+ DestroyTask(FindTaskIdByFunc(sub_80B6B94));
+ return FALSE;
+}
+
+void sub_80B6E88(u8);
+extern void sub_80E1558(u8);
+extern void sub_80AF0B4(void);
+
+void sub_80B6FB8(struct Task *);
+void sub_80B7004(struct Task *);
+void sub_80B7050(void);
+void sub_80B7060(void);
+bool8 sub_80859A0(void);
+void sub_80B70B4(void);
+void sub_80E1570(void);
+void sub_80B70DC(u8);
+
+void sub_80B6E4C(u8 a0, u8 priority)
+{
+ u8 taskId;
+ taskId = CreateTask(sub_80B6E88, priority);
+ gTasks[taskId].data[1] = 0;
+ if (a0 == 0x6a)
+ {
+ gTasks[taskId].data[1] = 1;
+ }
+}
+
+void sub_80B6E88(u8 taskId)
+{
+ struct Task *task;
+ task = &gTasks[taskId];
+ while (gUnknown_0855C3E4[task->data[0]](task));
+}
+
+bool8 sub_80B6EC0(struct Task *task)
+{
+ FreezeMapObjects();
+ CameraObjectReset2();
+ sub_80E1558(task->data[1]);
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 sub_80B6EE0(struct Task *task)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(mapObject) || FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ FieldObjectSetSpecialAnim(mapObject, GetFaceDirectionAnimId(player_get_direction_lower_nybble()));
+ task->data[0]++;
+ task->data[2] = 0;
+ task->data[3] = 0;
+ if ((u8)task->data[1] == 0)
+ {
+ task->data[0] = 4;
+ }
+ PlaySE(SE_ESUKA);
+ }
+ return FALSE;
+}
+
+bool8 sub_80B6F50(struct Task *task)
+{
+ sub_80B6FB8(task);
+ if (task->data[2] > 3)
+ {
+ sub_80B7050();
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+bool8 sub_80B6F74(struct Task *task)
+{
+ sub_80B6FB8(task);
+ sub_80B7060();
+ return FALSE;
+}
+
+bool8 sub_80B6F84(struct Task *task)
+{
+ sub_80B7004(task);
+ if (task->data[2] > 3)
+ {
+ sub_80B7050();
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+bool8 sub_80B6FA8(struct Task *task)
+{
+ sub_80B7004(task);
+ sub_80B7060();
+ return FALSE;
+}
+
+void sub_80B6FB8(struct Task *task)
+{
+ struct Sprite *sprite;
+ sprite = &gSprites[gPlayerAvatar.spriteId];
+ sprite->pos2.x = Cos(0x84, task->data[2]);
+ sprite->pos2.y = Sin(0x94, task->data[2]);
+ task->data[3]++;
+ if (task->data[3] & 1)
+ {
+ task->data[2]++;
+ }
+}
+
+void sub_80B7004(struct Task *task)
+{
+ struct Sprite *sprite;
+ sprite = &gSprites[gPlayerAvatar.spriteId];
+ sprite->pos2.x = Cos(0x7c, task->data[2]);
+ sprite->pos2.y = Sin(0x76, task->data[2]);
+ task->data[3]++;
+ if (task->data[3] & 1)
+ {
+ task->data[2]++;
+ }
+}
+
+void sub_80B7050(void)
+{
+ music_something();
+ sub_80AF0B4();
+}
+
+void sub_80B7060(void)
+{
+ if (!gPaletteFade.active && sub_80859A0() == TRUE)
+ {
+ sub_80E1570();
+ warp_in();
+ gFieldCallback = sub_80B70B4;
+ SetMainCallback2(CB2_LoadMap);
+ DestroyTask(FindTaskIdByFunc(sub_80B6E88));
+ }
+}
+
+void sub_80B70B4(void)
+{
+ Overworld_PlaySpecialMapMusic();
+ pal_fill_for_maplights();
+ ScriptContext2_Enable();
+ CreateTask(sub_80B70DC, 0);
+ gFieldCallback = NULL;
+}
+
+void sub_80B70DC(u8 taskId)
+{
+ struct Task *task;
+ task = &gTasks[taskId];
+ while (gUnknown_0855C3FC[task->data[0]](task));
+}
+
+bool8 sub_80B7114(struct Task *task)
+{
+ struct MapObject *mapObject;
+ s16 x;
+ s16 y;
+ u8 behavior;
+ CameraObjectReset2();
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ FieldObjectSetSpecialAnim(mapObject, GetFaceDirectionAnimId(DIR_EAST));
+ PlayerGetDestCoords(&x, &y);
+ behavior = MapGridGetMetatileBehaviorAt(x, y);
+ task->data[0]++;
+ task->data[1] = 16;
+ if (behavior == 0x6b)
+ {
+ behavior = 1;
+ task->data[0] = 3;
+ } else
+ {
+ behavior = 0;
+ }
+ sub_80E1558(behavior);
+ return TRUE;
+}
+
+bool8 sub_80B7190(struct Task *task)
+{
+ struct Sprite *sprite;
+ sprite = &gSprites[gPlayerAvatar.spriteId];
+ sprite->pos2.x = Cos(0x84, task->data[1]);
+ sprite->pos2.y = Sin(0x94, task->data[1]);
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 sub_80B71D0(struct Task *task)
+{
+ struct Sprite *sprite;
+ sprite = &gSprites[gPlayerAvatar.spriteId];
+ sprite->pos2.x = Cos(0x84, task->data[1]);
+ sprite->pos2.y = Sin(0x94, task->data[1]);
+ task->data[2]++;
+ if (task->data[2] & 1)
+ {
+ task->data[1]--;
+ }
+ if (task->data[1] == 0)
+ {
+ sprite->pos2.x = 0;
+ sprite->pos2.y = 0;
+ task->data[0] = 5;
+ }
+ return FALSE;
+}
+
+bool8 sub_80B7230(struct Task *task)
+{
+ struct Sprite *sprite;
+ sprite = &gSprites[gPlayerAvatar.spriteId];
+ sprite->pos2.x = Cos(0x7c, task->data[1]);
+ sprite->pos2.y = Sin(0x76, task->data[1]);
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 sub_80B7270(struct Task *task)
+{
+ struct Sprite *sprite;
+ sprite = &gSprites[gPlayerAvatar.spriteId];
+ sprite->pos2.x = Cos(0x7c, task->data[1]);
+ sprite->pos2.y = Sin(0x76, task->data[1]);
+ task->data[2]++;
+ if (task->data[2] & 1)
+ {
+ task->data[1]--;
+ }
+ if (task->data[1] == 0)
+ {
+ sprite->pos2.x = 0;
+ sprite->pos2.y = 0;
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+extern bool8 sub_80E1584(void);
+
+bool8 sub_80B72D0(struct Task *task)
+{
+ if (sub_80E1584())
+ {
+ return FALSE;
+ }
+ sub_80E1570();
+ task->data[0]++;
+ return TRUE;
+}
+
+bool8 sub_80B72F4(struct Task *task)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ CameraObjectReset1();
+ ScriptContext2_Disable();
+ FieldObjectSetSpecialAnim(mapObject, GetGoSpeed0AnimId(DIR_EAST));
+ DestroyTask(FindTaskIdByFunc(sub_80B70DC));
+ }
+ return FALSE;
+}
+
+void sub_80B7384(u8);
+
+bool8 FldEff_UseWaterfall(void)
+{
+ u8 taskId;
+ taskId = CreateTask(sub_80B7384, 0xff);
+ gTasks[taskId].data[1] = gFieldEffectArguments[0];
+ sub_80B7384(taskId);
+ return FALSE;
+}
+
+void sub_80B7384(u8 taskId)
+{
+ while (gUnknown_0855C418[gTasks[taskId].data[0]](&gTasks[taskId], &gMapObjects[gPlayerAvatar.mapObjectId]));
+}
+
+bool8 sub_80B73D0(struct Task *task, struct MapObject *mapObject)
+{
+ ScriptContext2_Enable();
+ gPlayerAvatar.preventStep = TRUE;
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 waterfall_1_do_anim_probably(struct Task *task, struct MapObject *mapObject)
+{
+ ScriptContext2_Enable();
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(mapObject))
+ {
+ FieldObjectClearAnimIfSpecialAnimFinished(mapObject);
+ gFieldEffectArguments[0] = task->data[1];
+ FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON_INIT);
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+bool8 waterfall_2_wait_anim_finish_probably(struct Task *task, struct MapObject *mapObject)
+{
+ if (FieldEffectActiveListContains(FLDEFF_FIELD_MOVE_SHOW_MON))
+ {
+ return FALSE;
+ }
+ task->data[0]++;
+ return TRUE;
+}
+
+bool8 sub_80B7450(struct Task *task, struct MapObject *mapObject)
+{
+ FieldObjectSetSpecialAnim(mapObject, GetSimpleGoAnimId(DIR_NORTH));
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 sub_80B7478(struct Task *task, struct MapObject *mapObject)
+{
+ if (!FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ return FALSE;
+ }
+ if (MetatileBehavior_IsWaterfall(mapObject->mapobj_unk_1E))
+ {
+ task->data[0] = 3;
+ return TRUE;
+ }
+ ScriptContext2_Disable();
+ gPlayerAvatar.preventStep = FALSE;
+ DestroyTask(FindTaskIdByFunc(sub_80B7384));
+ FieldEffectActiveListRemove(FLDEFF_USE_WATERFALL);
+ return FALSE;
+}
+
+void Task_Dive(u8);
+extern int dive_warp(struct MapPosition *, u16);
+
+bool8 FldEff_UseDive(void)
+{
+ u8 taskId;
+ taskId = CreateTask(Task_Dive, 0xff);
+ gTasks[taskId].data[15] = gFieldEffectArguments[0];
+ gTasks[taskId].data[14] = gFieldEffectArguments[1];
+ Task_Dive(taskId);
+ return FALSE;
+}
+
+void Task_Dive(u8 taskId)
+{
+ while (gUnknown_0855C42C[gTasks[taskId].data[0]](&gTasks[taskId]));
+}
+
+bool8 dive_1_lock(struct Task *task)
+{
+ gPlayerAvatar.preventStep = TRUE;
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 dive_2_unknown(struct Task *task)
+{
+ ScriptContext2_Enable();
+ gFieldEffectArguments[0] = task->data[15];
+ FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON_INIT);
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 dive_3_unknown(struct Task *task)
+{
+ struct MapPosition mapPosition;
+ PlayerGetDestCoords(&mapPosition.x, &mapPosition.y);
+ if (!FieldEffectActiveListContains(FLDEFF_FIELD_MOVE_SHOW_MON))
+ {
+ dive_warp(&mapPosition, gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1E);
+ DestroyTask(FindTaskIdByFunc(Task_Dive));
+ FieldEffectActiveListRemove(FLDEFF_USE_DIVE);
+ }
+ return FALSE;
+}
+
+void sub_80B75F0(u8);
+void mapldr_080851BC(void);
+
+void sub_80B75D8(u8 priority)
+{
+ CreateTask(sub_80B75F0, priority);
+}
+
+void sub_80B75F0(u8 taskId)
+{
+ while (gUnknown_0855C438[gTasks[taskId].data[0]](&gTasks[taskId], &gMapObjects[gPlayerAvatar.mapObjectId], &gSprites[gPlayerAvatar.spriteId]));
+}
+
+bool8 sub_80B764C(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FreezeMapObjects();
+ CameraObjectReset2();
+ SetCameraPanningCallback(NULL);
+ gPlayerAvatar.preventStep = TRUE;
+ mapObject->mapobj_bit_26 = 1;
+ task->data[1] = 1;
+ task->data[0]++;
+ return TRUE;
+}
+
+bool8 sub_80B7684(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ SetCameraPanning(0, task->data[1]);
+ task->data[1] = -task->data[1];
+ task->data[2]++;
+ if (task->data[2] > 7)
+ {
+ task->data[2] = 0;
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+bool8 sub_80B76B8(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sprite->pos2.y = 0;
+ task->data[3] = 1;
+ gFieldEffectArguments[0] = mapObject->coords2.x;
+ gFieldEffectArguments[1] = mapObject->coords2.y;
+ gFieldEffectArguments[2] = sprite->subpriority - 1;
+ gFieldEffectArguments[3] = sprite->oam.priority;
+ FieldEffectStart(FLDEFF_LAVARIDGE_GYM_WARP);
+ PlaySE(SE_W153);
+ task->data[0]++;
+ return TRUE;
+}
+
+bool8 sub_80B7704(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ s16 centerToCornerVecY;
+ SetCameraPanning(0, task->data[1]);
+ if (task->data[1] = -task->data[1], ++task->data[2] <= 17)
+ {
+ if (!(task->data[2] & 1) && (task->data[1] <= 3))
+ {
+ task->data[1] <<= 1;
+ }
+ } else if (!(task->data[2] & 4) && (task->data[1] > 0))
+ {
+ task->data[1] >>= 1;
+ }
+ if (task->data[2] > 6)
+ {
+ centerToCornerVecY = -(sprite->centerToCornerVecY << 1);
+ if (sprite->pos2.y > -(sprite->pos1.y + sprite->centerToCornerVecY + gSpriteCoordOffsetY + centerToCornerVecY))
+ {
+ sprite->pos2.y -= task->data[3];
+ if (task->data[3] <= 7)
+ {
+ task->data[3]++;
+ }
+ } else
+ {
+ task->data[4] = 1;
+ }
+ }
+ if (task->data[5] == 0 && sprite->pos2.y < -0x10)
+ {
+ task->data[5]++;
+ mapObject->mapobj_bit_26 = 1;
+ sprite->oam.priority = 1;
+ sprite->subspriteMode = 2;
+ }
+ if (task->data[1] == 0 && task->data[4] != 0)
+ {
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+bool8 sub_80B77F8(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ music_something();
+ sub_80AF0B4();
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 sub_80B7814(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (!gPaletteFade.active && sub_80859A0() == TRUE)
+ {
+ warp_in();
+ gFieldCallback = mapldr_080851BC;
+ SetMainCallback2(CB2_LoadMap);
+ DestroyTask(FindTaskIdByFunc(sub_80B75F0));
+ }
+ return FALSE;
+}
+
+void sub_80B7890(u8);
+
+void mapldr_080851BC(void)
+{
+ Overworld_PlaySpecialMapMusic();
+ pal_fill_for_maplights();
+ ScriptContext2_Enable();
+ gFieldCallback = NULL;
+ CreateTask(sub_80B7890, 0);
+}
+
+void sub_80B7890(u8 taskId)
+{
+ while (gUnknown_0855C450[gTasks[taskId].data[0]](&gTasks[taskId], &gMapObjects[gPlayerAvatar.mapObjectId], &gSprites[gPlayerAvatar.spriteId]));
+}
+
+bool8 sub_80B78EC(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ CameraObjectReset2();
+ FreezeMapObjects();
+ gPlayerAvatar.preventStep = TRUE;
+ mapObject->mapobj_bit_13 = 1;
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 sub_80B791C(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (IsWeatherNotFadingIn())
+ {
+ gFieldEffectArguments[0] = mapObject->coords2.x;
+ gFieldEffectArguments[1] = mapObject->coords2.y;
+ gFieldEffectArguments[2] = sprite->subpriority - 1;
+ gFieldEffectArguments[3] = sprite->oam.priority;
+ task->data[1] = FieldEffectStart(FLDEFF_POP_OUT_OF_ASH);
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+bool8 sub_80B7968(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sprite = &gSprites[task->data[1]];
+ if (sprite->animCmdIndex > 1)
+ {
+ task->data[0]++;
+ mapObject->mapobj_bit_13 = 0;
+ CameraObjectReset1();
+ PlaySE(SE_W091);
+ FieldObjectSetSpecialAnim(mapObject, sub_8093514(DIR_EAST));
+ }
+ return FALSE;
+}
+
+bool8 sub_80B79BC(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ gPlayerAvatar.preventStep = FALSE;
+ ScriptContext2_Disable();
+ UnfreezeMapObjects();
+ DestroyTask(FindTaskIdByFunc(sub_80B7890));
+ }
+ return FALSE;
+}
+
+extern const struct SpriteTemplate *const gFieldEffectObjectTemplatePointers[36];
+
+u8 FldEff_LavaridgeGymWarp(void)
+{
+ u8 spriteId;
+ sub_80930E0((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[33], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
+ gSprites[spriteId].oam.priority = gFieldEffectArguments[3];
+ gSprites[spriteId].coordOffsetEnabled = 1;
+ return spriteId;
+}
+
+void sub_80B7A58(struct Sprite *sprite)
+{
+ if (sprite->animEnded)
+ {
+ FieldEffectStop(sprite, FLDEFF_LAVARIDGE_GYM_WARP);
+ }
+}
+
+void sub_80B7A8C(u8);
+
+void sub_80B7A74(u8 priority)
+{
+ CreateTask(sub_80B7A8C, priority);
+}
+
+void sub_80B7A8C(u8 taskId)
+{
+ while(gUnknown_0855C460[gTasks[taskId].data[0]](&gTasks[taskId], &gMapObjects[gPlayerAvatar.mapObjectId], &gSprites[gPlayerAvatar.spriteId]));
+}
+
+bool8 sub_80B7AE8(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FreezeMapObjects();
+ CameraObjectReset2();
+ gPlayerAvatar.preventStep = TRUE;
+ mapObject->mapobj_bit_26 = 1;
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 sub_80B7B18(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ if (task->data[1] > 3)
+ {
+ gFieldEffectArguments[0] = mapObject->coords2.x;
+ gFieldEffectArguments[1] = mapObject->coords2.y;
+ gFieldEffectArguments[2] = sprite->subpriority - 1;
+ gFieldEffectArguments[3] = sprite->oam.priority;
+ task->data[1] = FieldEffectStart(FLDEFF_POP_OUT_OF_ASH);
+ task->data[0]++;
+ } else
+ {
+ task->data[1]++;
+ FieldObjectSetSpecialAnim(mapObject, GetStepInPlaceDelay4AnimId(mapObject->mapobj_unk_18));
+ PlaySE(SE_FU_ZUZUZU);
+ }
+ }
+ return FALSE;
+}
+
+bool8 sub_80B7B94(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (gSprites[task->data[1]].animCmdIndex == 2)
+ {
+ mapObject->mapobj_bit_13 = 1;
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+bool8 sub_80B7BCC(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (!FieldEffectActiveListContains(FLDEFF_POP_OUT_OF_ASH))
+ {
+ music_something();
+ sub_80AF0B4();
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+void sub_80B7CE4(u8);
+void mapldr_080859D4(void);
+
+bool8 sub_80B7BF4(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (!gPaletteFade.active && sub_80859A0() == TRUE)
+ {
+ warp_in();
+ gFieldCallback = sub_80B6B68;
+ SetMainCallback2(CB2_LoadMap);
+ DestroyTask(FindTaskIdByFunc(sub_80B7A8C));
+ }
+ return FALSE;
+}
+
+u8 FldEff_PopOutOfAsh(void)
+{
+ u8 spriteId;
+ sub_80930E0((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[32], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
+ gSprites[spriteId].oam.priority = gFieldEffectArguments[3];
+ gSprites[spriteId].coordOffsetEnabled = 1;
+ return spriteId;
+}
+
+void sub_80B7CAC(struct Sprite *sprite)
+{
+ if (sprite->animEnded)
+ {
+ FieldEffectStop(sprite, FLDEFF_POP_OUT_OF_ASH);
+ }
+}
+
+void sub_80B7CC8(void)
+{
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ CreateTask(sub_80B7CE4, 0x50);
+}
+
+void sub_80B7CE4(u8 taskId)
+{
+ gUnknown_0855C474[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_80B7D14(struct Task *task)
+{
+ task->data[0]++;
+ task->data[14] = 64;
+ task->data[15] = player_get_direction_lower_nybble();
+}
+
+void sub_80B7D34(struct Task *task)
+{
+ struct MapObject *mapObject;
+ u8 spinDirections[5] = {1, 3, 4, 2, 1};
+ if (task->data[14] != 0 && (--task->data[14]) == 0)
+ {
+ music_something();
+ sub_80AF0B4();
+ }
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(mapObject) || FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ if (task->data[14] == 0 && !gPaletteFade.active && sub_80859A0() == TRUE)
+ {
+ FieldObjectSetDirection(mapObject, task->data[15]);
+ sub_8084E14();
+ warp_in();
+ gFieldCallback = mapldr_080859D4;
+ SetMainCallback2(CB2_LoadMap);
+ DestroyTask(FindTaskIdByFunc(sub_80B7CE4));
+ } else if (task->data[1] == 0 || (--task->data[1]) == 0)
+ {
+ FieldObjectSetSpecialAnim(mapObject, GetFaceDirectionAnimId(spinDirections[mapObject->mapobj_unk_18]));
+ if (task->data[2] < 12)
+ {
+ task->data[2]++;
+ }
+ task->data[1] = 8 >> (task->data[2] >> 2);
+ }
+ }
+}
+
+void (*const gUnknown_0855C484[])(struct Task *) = {
+ sub_80B7EC4,
+ sub_80B7EE8
+};
+
+void sub_80B7E94(u8);
+
+void mapldr_080859D4(void)
+{
+ Overworld_PlaySpecialMapMusic();
+ pal_fill_for_maplights();
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ gFieldCallback = NULL;
+ gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_13 = 1;
+ CreateTask(sub_80B7E94, 0);
+}
+
+void sub_80B7E94(u8 taskId)
+{
+ gUnknown_0855C484[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_80B7EC4(struct Task *task)
+{
+ if (IsWeatherNotFadingIn())
+ {
+ task->data[0]++;
+ task->data[15] = player_get_direction_lower_nybble();
+ }
+}
+
+void sub_80B7EE8(struct Task *task)
+{
+ u8 spinDirections[5] = {1, 3, 4, 2, 1};
+ struct MapObject *mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (task->data[1] == 0 || (--task->data[1]) == 0)
+ {
+ if (FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(mapObject) && !FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ return;
+ }
+ if (task->data[2] >= 32 && task->data[15] == player_get_direction_lower_nybble())
+ {
+ mapObject->mapobj_bit_13 = 0;
+ ScriptContext2_Disable();
+ UnfreezeMapObjects();
+ DestroyTask(FindTaskIdByFunc(sub_80B7E94));
+ return;
+ }
+ FieldObjectSetSpecialAnim(mapObject, GetFaceDirectionAnimId(spinDirections[mapObject->mapobj_unk_18]));
+ if (task->data[2] < 32)
+ {
+ task->data[2]++;
+ }
+ task->data[1] = task->data[2] >> 2;
+ }
+ mapObject->mapobj_bit_13 ^= 1;
+}
+
+static void ExecuteTeleportFieldEffectTask(u8);
+static void TeleportFieldEffectTask1(struct Task*);
+static void TeleportFieldEffectTask2(struct Task*);
+static void TeleportFieldEffectTask3(struct Task*);
+static void TeleportFieldEffectTask4(struct Task*);
+static void mapldr_08085D88(void);
+
+void CreateTeleportFieldEffectTask(void)
+{
+ CreateTask(ExecuteTeleportFieldEffectTask, 0);
+}
+
+static void (*const sTeleportFieldEffectTasks[])(struct Task *) = {
+ TeleportFieldEffectTask1,
+ TeleportFieldEffectTask2,
+ TeleportFieldEffectTask3,
+ TeleportFieldEffectTask4
+};
+
+static void ExecuteTeleportFieldEffectTask(u8 taskId)
+{
+ sTeleportFieldEffectTasks[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+static void TeleportFieldEffectTask1(struct Task *task)
+{
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ CameraObjectReset2();
+ task->data[15] = player_get_direction_lower_nybble();
+ task->data[0]++;
+}
+
+static void TeleportFieldEffectTask2(struct Task *task)
+{
+ u8 spinDirections[5] = {DIR_SOUTH, DIR_WEST, DIR_EAST, DIR_NORTH, DIR_SOUTH};
+ struct MapObject *mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (task->data[1] == 0 || (--task->data[1]) == 0)
+ {
+ FieldObjectTurn(mapObject, spinDirections[mapObject->mapobj_unk_18]);
+ task->data[1] = 8;
+ task->data[2]++;
+ }
+ if (task->data[2] > 7 && task->data[15] == mapObject->mapobj_unk_18)
+ {
+ task->data[0]++;
+ task->data[1] = 4;
+ task->data[2] = 8;
+ task->data[3] = 1;
+ PlaySE(SE_TK_WARPIN);
+ }
+}
+
+static void TeleportFieldEffectTask3(struct Task *task)
+{
+ u8 spinDirections[5] = {DIR_SOUTH, DIR_WEST, DIR_EAST, DIR_NORTH, DIR_SOUTH};
+ struct MapObject *mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ struct Sprite *sprite = &gSprites[gPlayerAvatar.spriteId];
+ if ((--task->data[1]) <= 0)
+ {
+ task->data[1] = 4;
+ FieldObjectTurn(mapObject, spinDirections[mapObject->mapobj_unk_18]);
+ }
+ sprite->pos1.y -= task->data[3];
+ task->data[4] += task->data[3];
+ if ((--task->data[2]) <= 0 && (task->data[2] = 4, task->data[3] < 8))
+ {
+ task->data[3] <<= 1;
+ }
+ if (task->data[4] > 8 && (sprite->oam.priority = 1, sprite->subspriteMode != 0))
+ {
+ sprite->subspriteMode = 2;
+ }
+ if (task->data[4] >= 0xa8)
+ {
+ task->data[0]++;
+ music_something();
+ sub_80AF0B4();
+ }
+}
+
+static void TeleportFieldEffectTask4(struct Task *task)
+{
+ if (!gPaletteFade.active)
+ {
+ if (task->data[5] == FALSE)
+ {
+ sub_81BE72C();
+ task->data[5] = TRUE;
+ }
+
+ if (sub_80859A0() == TRUE)
+ {
+ Overworld_SetWarpDestToLastHealLoc();
+ warp_in();
+ SetMainCallback2(CB2_LoadMap);
+ gFieldCallback = mapldr_08085D88;
+ DestroyTask(FindTaskIdByFunc(ExecuteTeleportFieldEffectTask));
+ }
+ }
+}
+
+void sub_80B8250(u8);
+
+static void mapldr_08085D88(void)
+{
+ Overworld_PlaySpecialMapMusic();
+ pal_fill_for_maplights();
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ gFieldCallback = NULL;
+ gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_13 = 1;
+ CameraObjectReset2();
+ CreateTask(sub_80B8250, 0);
+}
+
+void (*const gUnknown_0855C49C[])(struct Task *) = {
+ sub_80B8280,
+ sub_80B830C,
+ sub_80B8410
+};
+
+void sub_80B8250(u8 taskId)
+{
+ gUnknown_0855C49C[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_80B8280(struct Task *task)
+{
+ struct Sprite *sprite;
+ s16 centerToCornerVecY;
+ if (IsWeatherNotFadingIn())
+ {
+ sprite = &gSprites[gPlayerAvatar.spriteId];
+ centerToCornerVecY = -(sprite->centerToCornerVecY << 1);
+ sprite->pos2.y = -(sprite->pos1.y + sprite->centerToCornerVecY + gSpriteCoordOffsetY + centerToCornerVecY);
+ gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_13 = 0;
+ task->data[0]++;
+ task->data[1] = 8;
+ task->data[2] = 1;
+ task->data[14] = sprite->subspriteMode;
+ task->data[15] = player_get_direction_lower_nybble();
+ PlaySE(SE_TK_WARPIN);
+ }
+}
+
+void sub_80B830C(struct Task *task)
+{
+ u8 spinDirections[5] = {1, 3, 4, 2, 1};
+ struct MapObject *mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ struct Sprite *sprite = &gSprites[gPlayerAvatar.spriteId];
+ if ((sprite->pos2.y += task->data[1]) >= -8)
+ {
+ if (task->data[13] == 0)
+ {
+ task->data[13]++;
+ mapObject->mapobj_bit_2 = 1;
+ sprite->subspriteMode = task->data[14];
+ }
+ } else
+ {
+ sprite->oam.priority = 1;
+ if (sprite->subspriteMode != 0)
+ {
+ sprite->subspriteMode = 2;
+ }
+ }
+ if (sprite->pos2.y >= -0x30 && task->data[1] > 1 && !(sprite->pos2.y & 1))
+ {
+ task->data[1]--;
+ }
+ if ((--task->data[2]) == 0)
+ {
+ task->data[2] = 4;
+ FieldObjectTurn(mapObject, spinDirections[mapObject->mapobj_unk_18]);
+ }
+ if (sprite->pos2.y >= 0)
+ {
+ sprite->pos2.y = 0;
+ task->data[0]++;
+ task->data[1] = 1;
+ task->data[2] = 0;
+ }
+}
+
+void sub_80B8410(struct Task *task)
+{
+ u8 spinDirections[5] = {1, 3, 4, 2, 1};
+ struct MapObject *mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if ((--task->data[1]) == 0)
+ {
+ FieldObjectTurn(mapObject, spinDirections[mapObject->mapobj_unk_18]);
+ task->data[1] = 8;
+ if ((++task->data[2]) > 4 && task->data[14] == mapObject->mapobj_unk_18)
+ {
+ ScriptContext2_Disable();
+ CameraObjectReset1();
+ UnfreezeMapObjects();
+ DestroyTask(FindTaskIdByFunc(sub_80B8250));
+ }
+ }
+}
+
+void sub_80B8554(u8);
+void sub_80B88B4(u8);
+u8 sub_80B8C60(u32, u32, u32);
+void sub_80B880C(void);
+void sub_80B8874(u16);
+void sub_80B8CC0(struct Sprite *);
+
+bool8 FldEff_FieldMoveShowMon(void)
+{
+ u8 taskId;
+ if (is_map_type_1_2_3_5_or_6(Overworld_GetMapTypeOfSaveblockLocation()) == TRUE)
+ {
+ taskId = CreateTask(sub_80B8554, 0xff);
+ } else
+ {
+ taskId = CreateTask(sub_80B88B4, 0xff);
+ }
+ gTasks[taskId].data[15] = sub_80B8C60(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
+ return FALSE;
+}
+
+bool8 FldEff_FieldMoveShowMonInit(void)
+{
+ struct Pokemon *pokemon;
+ u32 flag = gFieldEffectArguments[0] & 0x80000000;
+ pokemon = &gPlayerParty[(u8)gFieldEffectArguments[0]];
+ gFieldEffectArguments[0] = GetMonData(pokemon, MON_DATA_SPECIES);
+ gFieldEffectArguments[1] = GetMonData(pokemon, MON_DATA_OT_ID);
+ gFieldEffectArguments[2] = GetMonData(pokemon, MON_DATA_PERSONALITY);
+ gFieldEffectArguments[0] |= flag;
+ FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON);
+ FieldEffectActiveListRemove(FLDEFF_FIELD_MOVE_SHOW_MON_INIT);
+ return FALSE;
+}
+
+void (*const gUnknown_0855C4A8[])(struct Task *) = {
+ sub_80B8584,
+ sub_80B85F8,
+ sub_80B8660,
+ sub_80B86EC,
+ sub_80B871C,
+ sub_80B8770,
+ overworld_bg_setup_2,
+};
+
+void sub_80B8554(u8 taskId)
+{
+ gUnknown_0855C4A8[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_80B8584(struct Task *task)
+{
+ task->data[11] = REG_WININ;
+ task->data[12] = REG_WINOUT;
+ StoreWordInTwoHalfwords(&task->data[13], (u32)gMain.vblankCallback);
+ task->data[1] = 0xf0f1;
+ task->data[2] = 0x5051;
+ task->data[3] = 0x3f;
+ task->data[4] = 0x3e;
+ SetGpuReg(REG_OFFSET_WIN0H, task->data[1]);
+ SetGpuReg(REG_OFFSET_WIN0V, task->data[2]);
+ SetGpuReg(REG_OFFSET_WININ, task->data[3]);
+ SetGpuReg(REG_OFFSET_WINOUT, task->data[4]);
+ SetVBlankCallback(sub_80B880C);
+ task->data[0]++;
+}
+
+void sub_80B85F8(struct Task *task)
+{
+ u16 offset;
+ u16 delta;
+ offset = ((REG_BG0CNT >> 2) << 14);
+ delta = ((REG_BG0CNT >> 8) << 11);
+ CpuCopy16(gFieldMoveStreaksTiles, (void *)(VRAM + offset), 0x200);
+ CpuFill32(0, (void *)(VRAM + delta), 0x800);
+ LoadPalette(gFieldMoveStreaksPalette, 0xf0, 0x20);
+ sub_80B8874(delta);
+ task->data[0]++;
+}
+
+void sub_80B8660(struct Task *task)
+{
+ s16 v0;
+ s16 v2;
+ s16 v3;
+ task->data[5] -= 16;
+ v0 = ((u16)task->data[1] >> 8);
+ v2 = ((u16)task->data[2] >> 8);
+ v3 = ((u16)task->data[2] & 0xff);
+ v0 -= 16;
+ v2 -= 2;
+ v3 += 2;
+ if (v0 < 0)
+ {
+ v0 = 0;
+ }
+ if (v2 < 0x28)
+ {
+ v2 = 0x28;
+ }
+ if (v3 > 0x78)
+ {
+ v3 = 0x78;
+ }
+ task->data[1] = (v0 << 8) | (task->data[1] & 0xff);
+ task->data[2] = (v2 << 8) | v3;
+ if (v0 == 0 && v2 == 0x28 && v3 == 0x78)
+ {
+ gSprites[task->data[15]].callback = sub_80B8CC0;
+ task->data[0]++;
+ }
+}
+
+void sub_80B86EC(struct Task *task)
+{
+ task->data[5] -= 16;
+ if (gSprites[task->data[15]].data[7])
+ {
+ task->data[0]++;
+ }
+}
+
+void sub_80B871C(struct Task *task)
+{
+ s16 v2;
+ s16 v3;
+ task->data[5] -= 16;
+ v2 = (task->data[2] >> 8);
+ v3 = (task->data[2] & 0xff);
+ v2 += 6;
+ v3 -= 6;
+ if (v2 > 0x50)
+ {
+ v2 = 0x50;
+ }
+ if (v3 < 0x51)
+ {
+ v3 = 0x51;
+ }
+ task->data[2] = (v2 << 8) | v3;
+ if (v2 == 0x50 && v3 == 0x51)
+ {
+ task->data[0]++;
+ }
+}
+
+void sub_80B8770(struct Task *task)
+{
+ u16 bg0cnt;
+ bg0cnt = (REG_BG0CNT >> 8) << 11;
+ CpuFill32(0, (void *)VRAM + bg0cnt, 0x800);
+ task->data[1] = 0xf1;
+ task->data[2] = 0xa1;
+ task->data[3] = task->data[11];
+ task->data[4] = task->data[12];
+ task->data[0]++;
+}
+
+void overworld_bg_setup_2(struct Task *task)
+{
+ IntrCallback callback;
+ LoadWordFromTwoHalfwords((u16 *)&task->data[13], (u32 *)&callback);
+ SetVBlankCallback(callback);
+ sub_8197200();
+ FreeResourcesAndDestroySprite(&gSprites[task->data[15]], task->data[15]);
+ FieldEffectActiveListRemove(FLDEFF_FIELD_MOVE_SHOW_MON);
+ DestroyTask(FindTaskIdByFunc(sub_80B8554));
+}
+
+void sub_80B880C(void)
+{
+ struct Task *task;
+ IntrCallback callback;
+ task = &gTasks[FindTaskIdByFunc(sub_80B8554)];
+ LoadWordFromTwoHalfwords((u16 *)&task->data[13], (u32 *)&callback);
+ callback();
+ SetGpuReg(REG_OFFSET_WIN0H, task->data[1]);
+ SetGpuReg(REG_OFFSET_WIN0V, task->data[2]);
+ SetGpuReg(REG_OFFSET_WININ, task->data[3]);
+ SetGpuReg(REG_OFFSET_WINOUT, task->data[4]);
+ SetGpuReg(REG_OFFSET_BG0HOFS, task->data[5]);
+ SetGpuReg(REG_OFFSET_BG0VOFS, task->data[6]);
+}
+
+void sub_80B8874(u16 offs)
+{
+ u16 i;
+ u16 *dest;
+ dest = (u16 *)(VRAM + 0x140 + offs);
+ for (i = 0; i < 0x140; i++, dest++)
+ {
+ *dest = gFieldMoveStreaksTilemap[i] | 0xf000;
+ }
+}
+
+void sub_80B8AE0(void);
+bool8 sub_80B8B38(struct Task *);
+void sub_80B8B28(struct Task *);
+bool8 sub_80B8BF0(struct Task *);
+
+void (*const gUnknown_0855C4C4[])(struct Task *) = {
+ sub_80B88E4,
+ sub_80B8920,
+ sub_80B898C,
+ sub_80B89DC,
+ sub_80B8A0C,
+ sub_80B8A44,
+ sub_80B8A64,
+};
+
+void sub_80B88B4(u8 taskId)
+{
+ gUnknown_0855C4C4[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_80B88E4(struct Task *task)
+{
+ SetGpuReg(REG_OFFSET_BG0HOFS, task->data[1]);
+ SetGpuReg(REG_OFFSET_BG0VOFS, task->data[2]);
+ StoreWordInTwoHalfwords((u16 *)&task->data[13], (u32)gMain.vblankCallback);
+ SetVBlankCallback(sub_80B8AE0);
+ task->data[0]++;
+}
+
+void sub_80B8920(struct Task *task)
+{
+ u16 offset;
+ u16 delta;
+ offset = ((REG_BG0CNT >> 2) << 14);
+ delta = ((REG_BG0CNT >> 8) << 11);
+ task->data[12] = delta;
+ CpuCopy16(gDarknessFieldMoveStreaksTiles, (void *)(VRAM + offset), 0x80);
+ CpuFill32(0, (void *)(VRAM + delta), 0x800);
+ LoadPalette(gDarknessFieldMoveStreaksPalette, 0xf0, 0x20);
+ task->data[0]++;
+}
+
+void sub_80B898C(struct Task *task)
+{
+ if (sub_80B8B38(task))
+ {
+ SetGpuReg(REG_OFFSET_WIN1H, 0x00f0);
+ SetGpuReg(REG_OFFSET_WIN1V, 0x2878);
+ gSprites[task->data[15]].callback = sub_80B8CC0;
+ task->data[0]++;
+ }
+ sub_80B8B28(task);
+}
+
+void sub_80B89DC(struct Task *task)
+{
+ sub_80B8B28(task);
+ if (gSprites[task->data[15]].data[7])
+ {
+ task->data[0]++;
+ }
+}
+
+void sub_80B8A0C(struct Task *task)
+{
+ sub_80B8B28(task);
+ task->data[3] = task->data[1] & 7;
+ task->data[4] = 0;
+ SetGpuReg(REG_OFFSET_WIN1H, 0xffff);
+ SetGpuReg(REG_OFFSET_WIN1V, 0xffff);
+ task->data[0]++;
+}
+
+void sub_80B8A44(struct Task *task)
+{
+ sub_80B8B28(task);
+ if (sub_80B8BF0(task))
+ {
+ task->data[0]++;
+ }
+}
+
+void sub_80B8A64(struct Task *task)
+{
+ IntrCallback intrCallback;
+ u16 bg0cnt;
+ bg0cnt = (REG_BG0CNT >> 8) << 11;
+ CpuFill32(0, (void *)VRAM + bg0cnt, 0x800);
+ LoadWordFromTwoHalfwords((u16 *)&task->data[13], (u32 *)&intrCallback);
+ SetVBlankCallback(intrCallback);
+ sub_8197200();
+ FreeResourcesAndDestroySprite(&gSprites[task->data[15]], task->data[15]);
+ FieldEffectActiveListRemove(FLDEFF_FIELD_MOVE_SHOW_MON);
+ DestroyTask(FindTaskIdByFunc(sub_80B88B4));
+}
+
+void sub_80B8AE0(void)
+{
+ IntrCallback intrCallback;
+ struct Task *task;
+ task = &gTasks[FindTaskIdByFunc(sub_80B88B4)];
+ LoadWordFromTwoHalfwords((u16 *)&task->data[13], (u32 *)&intrCallback);
+ intrCallback();
+ SetGpuReg(REG_OFFSET_BG0HOFS, task->data[1]);
+ SetGpuReg(REG_OFFSET_BG0VOFS, task->data[2]);
+}
+
+void sub_80B8B28(struct Task *task)
+{
+ task->data[1] -= 16;
+ task->data[3] += 16;
+}
+
+#ifdef NONMATCHING
+bool8 sub_80B8B38(struct Task *task)
+{
+ u16 i;
+ u16 srcOffs;
+ u16 dstOffs;
+ u16 *dest;
+ if (task->data[4] >= 32)
+ {
+ return TRUE;
+ }
+ dstOffs = (task->data[3] >> 3) & 0x1f;
+ if (dstOffs >= task->data[4])
+ {
+ dstOffs = (32 - dstOffs) & 0x1f;
+ srcOffs = (32 - task->data[4]) & 0x1f;
+ dest = (u16 *)(VRAM + 0x140 + (u16)task->data[12]);
+ for (i=0; i<10; i++)
+ {
+ dest[dstOffs + i * 32] = gDarknessFieldMoveStreaksTilemap[srcOffs + i * 32] | 0xf000;
+ dest[((dstOffs + 1) & 0x1f) + i * 32] = gDarknessFieldMoveStreaksTilemap[((srcOffs + 1) & 0x1f) + i * 32] | 0xf000;
+ }
+ task->data[4] += 2;
+ }
+ return FALSE;
+}
+#else
+NAKED
+bool8 sub_80B8B38(struct Task *task)
+{
+ asm_unified("\tpush {r4-r7,lr}\n"
+ "\tmov r7, r10\n"
+ "\tmov r6, r9\n"
+ "\tmov r5, r8\n"
+ "\tpush {r5-r7}\n"
+ "\tsub sp, 0x4\n"
+ "\tadds r5, r0, 0\n"
+ "\tldrh r2, [r5, 0x10]\n"
+ "\tmovs r1, 0x10\n"
+ "\tldrsh r0, [r5, r1]\n"
+ "\tcmp r0, 0x1F\n"
+ "\tble _08088724\n"
+ "\tmovs r0, 0x1\n"
+ "\tb _080887A8\n"
+ "_08088724:\n"
+ "\tldrh r0, [r5, 0xE]\n"
+ "\tlsls r0, 16\n"
+ "\tasrs r3, r0, 19\n"
+ "\tmovs r1, 0x1F\n"
+ "\tands r3, r1\n"
+ "\tmovs r4, 0x10\n"
+ "\tldrsh r0, [r5, r4]\n"
+ "\tcmp r3, r0\n"
+ "\tblt _080887A6\n"
+ "\tmovs r0, 0x20\n"
+ "\tsubs r3, r0, r3\n"
+ "\tands r3, r1\n"
+ "\tsubs r0, r2\n"
+ "\tmov r12, r0\n"
+ "\tmov r7, r12\n"
+ "\tands r7, r1\n"
+ "\tmov r12, r7\n"
+ "\tldrh r0, [r5, 0x20]\n"
+ "\tldr r1, _080887B8 @ =0x06000140\n"
+ "\tadds r1, r0\n"
+ "\tmov r8, r1\n"
+ "\tmovs r4, 0\n"
+ "\tldr r7, _080887BC @ =gDarknessFieldMoveStreaksTilemap\n"
+ "\tmov r10, r7\n"
+ "\tmovs r0, 0xF0\n"
+ "\tlsls r0, 8\n"
+ "\tmov r9, r0\n"
+ "\tadds r1, r3, 0x1\n"
+ "\tmovs r0, 0x1F\n"
+ "\tands r1, r0\n"
+ "\tstr r1, [sp]\n"
+ "\tmov r6, r12\n"
+ "\tadds r6, 0x1\n"
+ "\tands r6, r0\n"
+ "_08088768:\n"
+ "\tlsls r1, r4, 5\n"
+ "\tadds r2, r1, r3\n"
+ "\tlsls r2, 1\n"
+ "\tadd r2, r8\n"
+ "\tmov r7, r12\n"
+ "\tadds r0, r7, r1\n"
+ "\tlsls r0, 1\n"
+ "\tadd r0, r10\n"
+ "\tldrh r0, [r0]\n"
+ "\tmov r7, r9\n"
+ "\torrs r0, r7\n"
+ "\tstrh r0, [r2]\n"
+ "\tldr r0, [sp]\n"
+ "\tadds r2, r1, r0\n"
+ "\tlsls r2, 1\n"
+ "\tadd r2, r8\n"
+ "\tadds r1, r6, r1\n"
+ "\tlsls r1, 1\n"
+ "\tadd r1, r10\n"
+ "\tldrh r0, [r1]\n"
+ "\tmov r1, r9\n"
+ "\torrs r0, r1\n"
+ "\tstrh r0, [r2]\n"
+ "\tadds r0, r4, 0x1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r4, r0, 16\n"
+ "\tcmp r4, 0x9\n"
+ "\tbls _08088768\n"
+ "\tldrh r0, [r5, 0x10]\n"
+ "\tadds r0, 0x2\n"
+ "\tstrh r0, [r5, 0x10]\n"
+ "_080887A6:\n"
+ "\tmovs r0, 0\n"
+ "_080887A8:\n"
+ "\tadd sp, 0x4\n"
+ "\tpop {r3-r5}\n"
+ "\tmov r8, r3\n"
+ "\tmov r9, r4\n"
+ "\tmov r10, r5\n"
+ "\tpop {r4-r7}\n"
+ "\tpop {r1}\n"
+ "\tbx r1\n"
+ "\t.align 2, 0\n"
+ "_080887B8: .4byte 0x06000140\n"
+ "_080887BC: .4byte gDarknessFieldMoveStreaksTilemap");
+}
+#endif
+
+bool8 sub_80B8BF0(struct Task *task)
+{
+ u16 i;
+ u16 dstOffs;
+ u16 *dest;
+ if (task->data[4] >= 32)
+ {
+ return TRUE;
+ }
+ dstOffs = task->data[3] >> 3;
+ if (dstOffs >= task->data[4])
+ {
+ dstOffs = (task->data[1] >> 3) & 0x1f;
+ dest = (u16 *)(VRAM + 0x140 + (u16)task->data[12]);
+ for (i=0; i<10; i++)
+ {
+ dest[dstOffs + i * 32] = 0xf000;
+ dest[((dstOffs + 1) & 0x1f) + i * 32] = 0xf000;
+ }
+ task->data[4] += 2;
+ }
+ return FALSE;
+}
+
+u8 sub_80B8C60(u32 a0, u32 a1, u32 a2)
+{
+ u16 v0;
+ u8 monSprite;
+ struct Sprite *sprite;
+ v0 = (a0 & 0x80000000) >> 16;
+ a0 &= 0x7fffffff;
+ monSprite = CreateMonSprite_FieldMove(a0, a1, a2, 0x140, 0x50, 0);
+ sprite = &gSprites[monSprite];
+ sprite->callback = SpriteCallbackDummy;
+ sprite->oam.priority = 0;
+ sprite->data[0] = a0;
+ sprite->data[6] = v0;
+ return monSprite;
+}
+
+void sub_80B8D04(struct Sprite *);
+
+void sub_80B8CC0(struct Sprite *sprite)
+{
+ if ((sprite->pos1.x -= 20) <= 0x78)
+ {
+ sprite->pos1.x = 0x78;
+ sprite->data[1] = 30;
+ sprite->callback = sub_80B8D04;
+ if (sprite->data[6])
+ {
+ PlayCry2(sprite->data[0], 0, 0x7d, 0xa);
+ } else
+ {
+ PlayCry1(sprite->data[0], 0);
+ }
+ }
+}
+
+void sub_80B8D20(struct Sprite *);
+
+void sub_80B8D04(struct Sprite *sprite)
+{
+ if ((--sprite->data[1]) == 0)
+ {
+ sprite->callback = sub_80B8D20;
+ }
+}
+
+void sub_80B8D20(struct Sprite *sprite)
+{
+ if (sprite->pos1.x < -0x40)
+ {
+ sprite->data[7] = 1;
+ } else
+ {
+ sprite->pos1.x -= 20;
+ }
+}
+
+void sub_80B8D84(u8);
+
+u8 FldEff_UseSurf(void)
+{
+ u8 taskId;
+ taskId = CreateTask(sub_80B8D84, 0xff);
+ gTasks[taskId].data[15] = gFieldEffectArguments[0];
+ Overworld_ClearSavedMusic();
+ Overworld_ChangeMusicTo(MUS_NAMINORI);
+ return FALSE;
+}
+
+void (*const gUnknown_0855C4E0[])(struct Task *) = {
+ sub_80B8DB4,
+ sub_80B8E14,
+ sub_80B8E60,
+ sub_80B8EA8,
+ sub_80B8F24,
+};
+
+void sub_80B8D84(u8 taskId)
+{
+ gUnknown_0855C4E0[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_80B8DB4(struct Task *task)
+{
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ gPlayerAvatar.preventStep = TRUE;
+ SetPlayerAvatarStateMask(8);
+ PlayerGetDestCoords(&task->data[1], &task->data[2]);
+ MoveCoords(gMapObjects[gPlayerAvatar.mapObjectId].placeholder18, &task->data[1], &task->data[2]);
+ task->data[0]++;
+}
+
+void sub_80B8E14(struct Task *task)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(mapObject) || FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ sub_808C114();
+ FieldObjectSetSpecialAnim(mapObject, 0x39);
+ task->data[0]++;
+ }
+}
+
+void sub_80B8E60(struct Task *task)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (FieldObjectCheckIfSpecialAnimFinishedOrInactive(mapObject))
+ {
+ gFieldEffectArguments[0] = task->data[15] | 0x80000000;
+ FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON_INIT);
+ task->data[0]++;
+ }
+}
+
+void sub_80B8EA8(struct Task *task)
+{
+ struct MapObject *mapObject;
+ if (!FieldEffectActiveListContains(FLDEFF_FIELD_MOVE_SHOW_MON))
+ {
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ FieldObjectSetGraphicsId(mapObject, GetPlayerAvatarGraphicsIdByStateId(3));
+ FieldObjectClearAnimIfSpecialAnimFinished(mapObject);
+ FieldObjectSetSpecialAnim(mapObject, sub_8093540(mapObject->placeholder18));
+ gFieldEffectArguments[0] = task->data[1];
+ gFieldEffectArguments[1] = task->data[2];
+ gFieldEffectArguments[2] = gPlayerAvatar.mapObjectId;
+ mapObject->mapobj_unk_1A = FieldEffectStart(FLDEFF_SURF_BLOB);
+ task->data[0]++;
+ }
+}
+
+void sub_80B8F24(struct Task *task)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ gPlayerAvatar.preventStep = FALSE;
+ gPlayerAvatar.flags &= 0xdf;
+ FieldObjectSetSpecialAnim(mapObject, GetFaceDirectionAnimId(mapObject->placeholder18));
+ sub_81555AC(mapObject->mapobj_unk_1A, 1);
+ UnfreezeMapObjects();
+ ScriptContext2_Disable();
+ FieldEffectActiveListRemove(FLDEFF_USE_SURF);
+ DestroyTask(FindTaskIdByFunc(sub_80B8D84));
+ }
+}
+
+#ifdef NONMATCHING
+u8 sub_80B8F98(void)
+{
+ u8 spriteId, i, j, k, l;
+ struct Sprite *sprite;
+ spriteId = CreateSprite(gFieldEffectObjectTemplatePointers[36], 0x78, -0x18, 1);
+ sprite = &gSprites[spriteId];
+ sprite->oam.priority = 1;
+ sprite->oam.paletteNum = 4;
+ sprite->data[0] = 0;
+ sprite->data[1] = 0;
+ sprite->data[2] = 0;
+ sprite->data[3] = -1;
+ sprite->data[4] = sprite->pos1.y;
+ sprite->data[5] = 0;
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG0 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_OBJ | BLDCNT_TGT2_BD);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(14, 14));
+ SetGpuReg(REG_OFFSET_WININ, 0x3F3F);
+ LoadPalette(gUnknown_0855B610, 0xC0, sizeof(gUnknown_0855B610));
+ SetGpuReg(REG_OFFSET_BG0VOFS, 120);
+ for (i = 3; i < 15; i++)
+ {
+ for (j = 12; j < 18; j++)
+ {
+ ((u16*)(VRAM + 0xF800))[i * 32 + j] = 0xBFF4 + i * 6 + j + 1;
+ }
+ }
+ for (k = 0; k < 90; k++)
+ {
+ for (l = 0; l < 8; l++)
+ {
+ *(u16*)(VRAM + 0x8000 + (k + 1) * 32 + l * 4) = (gUnknown_0855B630[k * 32 + l * 4 + 1] << 8) + gUnknown_0855B630[k * 32 + l * 4];
+ *(u16*)(VRAM + 0x8000 + (k + 1) * 32 + l * 4 + 2) = (gUnknown_0855B630[k * 32 + l * 4 + 3] << 8) + gUnknown_0855B630[k * 32 + l * 4 + 2];
+ }
+ }
+ return spriteId;
+}
+#else
+NAKED
+u8 sub_80B8F98(void)
+{
+ asm_unified("push {r4-r7,lr}\n\
+ mov r7, r8\n\
+ push {r7}\n\
+ ldr r0, =gFieldEffectObjectTemplatePointers\n\
+ adds r0, 0x90\n\
+ ldr r0, [r0]\n\
+ movs r2, 0x18\n\
+ negs r2, r2\n\
+ movs r1, 0x78\n\
+ movs r3, 0x1\n\
+ bl CreateSprite\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ mov r8, r0\n\
+ lsls r1, r0, 4\n\
+ add r1, r8\n\
+ lsls r1, 2\n\
+ ldr r0, =gSprites\n\
+ adds r1, r0\n\
+ ldrb r2, [r1, 0x5]\n\
+ movs r0, 0xD\n\
+ negs r0, r0\n\
+ ands r0, r2\n\
+ movs r2, 0x4\n\
+ orrs r0, r2\n\
+ movs r2, 0xF\n\
+ ands r0, r2\n\
+ movs r2, 0x40\n\
+ orrs r0, r2\n\
+ strb r0, [r1, 0x5]\n\
+ movs r2, 0\n\
+ strh r2, [r1, 0x2E]\n\
+ strh r2, [r1, 0x30]\n\
+ strh r2, [r1, 0x32]\n\
+ ldr r0, =0x0000ffff\n\
+ strh r0, [r1, 0x34]\n\
+ ldrh r0, [r1, 0x22]\n\
+ strh r0, [r1, 0x36]\n\
+ strh r2, [r1, 0x38]\n\
+ ldr r1, =0x00003e41\n\
+ movs r0, 0x50\n\
+ bl SetGpuReg\n\
+ ldr r1, =0x00000e0e\n\
+ movs r0, 0x52\n\
+ bl SetGpuReg\n\
+ ldr r1, =0x00003f3f\n\
+ movs r0, 0x48\n\
+ bl SetGpuReg\n\
+ ldr r0, =gUnknown_0855B610\n\
+ movs r1, 0xC0\n\
+ movs r2, 0x20\n\
+ bl LoadPalette\n\
+ movs r0, 0x12\n\
+ movs r1, 0x78\n\
+ bl SetGpuReg\n\
+ movs r4, 0x3\n\
+ ldr r7, =0x0600f800\n\
+ ldr r0, =0x0000bff4\n\
+ adds r6, r0, 0\n\
+_080B901A:\n\
+ movs r2, 0xC\n\
+ lsls r0, r4, 1\n\
+ lsls r5, r4, 5\n\
+ adds r0, r4\n\
+ lsls r3, r0, 1\n\
+_080B9024:\n\
+ adds r0, r5, r2\n\
+ lsls r0, 1\n\
+ adds r0, r7\n\
+ adds r1, r2, r6\n\
+ adds r1, r3, r1\n\
+ adds r1, 0x1\n\
+ strh r1, [r0]\n\
+ adds r0, r2, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r2, r0, 24\n\
+ cmp r2, 0x11\n\
+ bls _080B9024\n\
+ adds r0, r4, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r4, r0, 24\n\
+ cmp r4, 0xE\n\
+ bls _080B901A\n\
+ movs r0, 0\n\
+ ldr r5, =gUnknown_0855B630\n\
+_080B904A:\n\
+ movs r4, 0\n\
+ adds r7, r0, 0x1\n\
+ lsls r6, r0, 5\n\
+_080B9050:\n\
+ lsls r1, r4, 2\n\
+ adds r1, r6, r1\n\
+ ldr r0, =0x06008020\n\
+ adds r3, r1, r0\n\
+ adds r0, r1, 0x1\n\
+ adds r0, r5\n\
+ ldrb r2, [r0]\n\
+ lsls r2, 8\n\
+ adds r0, r1, r5\n\
+ ldrb r0, [r0]\n\
+ adds r0, r2\n\
+ strh r0, [r3]\n\
+ ldr r0, =0x06008022\n\
+ adds r3, r1, r0\n\
+ adds r0, r1, 0x3\n\
+ adds r0, r5\n\
+ ldrb r2, [r0]\n\
+ lsls r2, 8\n\
+ adds r1, 0x2\n\
+ adds r1, r5\n\
+ ldrb r0, [r1]\n\
+ adds r0, r2\n\
+ strh r0, [r3]\n\
+ adds r0, r4, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r4, r0, 24\n\
+ cmp r4, 0x7\n\
+ bls _080B9050\n\
+ lsls r0, r7, 24\n\
+ lsrs r0, 24\n\
+ cmp r0, 0x59\n\
+ bls _080B904A\n\
+ mov r0, r8\n\
+ pop {r3}\n\
+ mov r8, r3\n\
+ pop {r4-r7}\n\
+ pop {r1}\n\
+ bx r1\n\
+ .pool");
+}
+#endif // NONMATCHING
+
+void sub_80B9128(struct Sprite *);
+
+u8 FldEff_NPCFlyOut(void)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+ spriteId = CreateSprite(gFieldEffectObjectTemplatePointers[26], 0x78, 0, 1);
+ sprite = &gSprites[spriteId];
+ sprite->oam.paletteNum = 0;
+ sprite->oam.priority = 1;
+ sprite->callback = sub_80B9128;
+ sprite->data[1] = gFieldEffectArguments[0];
+ PlaySE(SE_W019);
+ return spriteId;
+}
+
+void sub_80B9128(struct Sprite *sprite)
+{
+ struct Sprite *npcSprite;
+ sprite->pos2.x = Cos(sprite->data[2], 0x8c);
+ sprite->pos2.y = Sin(sprite->data[2], 0x48);
+ sprite->data[2] = (sprite->data[2] + 4) & 0xff;
+ if (sprite->data[0])
+ {
+ npcSprite = &gSprites[sprite->data[1]];
+ npcSprite->coordOffsetEnabled = 0;
+ npcSprite->pos1.x = sprite->pos1.x + sprite->pos2.x;
+ npcSprite->pos1.y = sprite->pos1.y + sprite->pos2.y - 8;
+ npcSprite->pos2.x = 0;
+ npcSprite->pos2.y = 0;
+ }
+ if (sprite->data[2] >= 0x80)
+ {
+ FieldEffectStop(sprite, FLDEFF_NPCFLY_OUT);
+ }
+}
+
+void sub_80B91D4(u8);
+extern void sub_81555D8(u8, u8);
+u8 sub_80B94C4(void);
+bool8 sub_80B9508(u8);
+void sub_80B9524(u8);
+void sub_80B9560(u8, u8);
+void sub_80B957C(struct Sprite *);
+void sub_80B963C(struct Sprite *);
+
+u8 FldEff_UseFly(void)
+{
+ u8 taskId;
+ taskId = CreateTask(sub_80B91D4, 0xfe);
+ gTasks[taskId].data[1] = gFieldEffectArguments[0];
+ return 0;
+}
+
+void (*const gUnknown_0855C4F4[])(struct Task *) = {
+ sub_80B9204,
+ sub_80B925C,
+ sub_80B92A0,
+ sub_80B92F8,
+ sub_80B933C,
+ sub_80B9390,
+ sub_80B9418,
+ sub_80B9474,
+ sub_80B9494,
+};
+
+void sub_80B91D4(u8 taskId)
+{
+ gUnknown_0855C4F4[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_80B9204(struct Task *task)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(mapObject) || FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ task->data[15] = gPlayerAvatar.flags;
+ gPlayerAvatar.preventStep = TRUE;
+ SetPlayerAvatarStateMask(1);
+ sub_808C114();
+ FieldObjectSetSpecialAnim(mapObject, 0x39);
+ task->data[0]++;
+ }
+}
+
+void sub_80B925C(struct Task *task)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ task->data[0]++;
+ gFieldEffectArguments[0] = task->data[1];
+ FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON_INIT);
+ }
+}
+
+void sub_80B92A0(struct Task *task)
+{
+ struct MapObject *mapObject;
+ if (!FieldEffectActiveListContains(FLDEFF_FIELD_MOVE_SHOW_MON))
+ {
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (task->data[15] & 0x08)
+ {
+ sub_81555AC(mapObject->mapobj_unk_1A, 2);
+ sub_81555D8(mapObject->mapobj_unk_1A, 0);
+ }
+ task->data[1] = sub_80B94C4();
+ task->data[0]++;
+ }
+}
+
+void sub_80B92F8(struct Task *task)
+{
+ if (sub_80B9508(task->data[1]))
+ {
+ task->data[0]++;
+ task->data[2] = 16;
+ SetPlayerAvatarTransitionFlags(PLAYER_AVATAR_FLAG_ON_FOOT);
+ FieldObjectSetSpecialAnim(&gMapObjects[gPlayerAvatar.mapObjectId], 0x02);
+ }
+}
+
+void sub_80B933C(struct Task *task)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if ((task->data[2] == 0 || (--task->data[2]) == 0) && FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ task->data[0]++;
+ PlaySE(SE_W019);
+ sub_80B9524(task->data[1]);
+ }
+}
+
+void sub_80B9390(struct Task *task)
+{
+ struct MapObject *mapObject;
+ if ((++task->data[2]) >= 8)
+ {
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ FieldObjectSetGraphicsId(mapObject, GetPlayerAvatarGraphicsIdByStateId(0x03));
+ StartSpriteAnim(&gSprites[mapObject->spriteId], 0x16);
+ mapObject->mapobj_bit_12 = 1;
+ FieldObjectSetSpecialAnim(mapObject, 0x48);
+ if (task->data[15] & 0x08)
+ {
+ DestroySprite(&gSprites[mapObject->mapobj_unk_1A]);
+ }
+ task->data[0]++;
+ task->data[2] = 0;
+ }
+}
+
+void sub_80B9418(struct Task *task)
+{
+ struct MapObject *mapObject;
+ if ((++task->data[2]) >= 10)
+ {
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ FieldObjectClearAnimIfSpecialAnimActive(mapObject);
+ mapObject->mapobj_bit_12 = 0;
+ mapObject->mapobj_bit_22 = 0;
+ sub_80B9560(task->data[1], mapObject->spriteId);
+ CameraObjectReset2();
+ task->data[0]++;
+ }
+}
+
+void sub_80B9474(struct Task *task)
+{
+ if (sub_80B9508(task->data[1]))
+ {
+ sub_80AF0B4();
+ task->data[0]++;
+ }
+}
+
+void sub_80B9494(struct Task *task)
+{
+ if (!gPaletteFade.active)
+ {
+ FieldEffectActiveListRemove(FLDEFF_USE_FLY);
+ DestroyTask(FindTaskIdByFunc(sub_80B91D4));
+ }
+}
+
+u8 sub_80B94C4(void)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+ spriteId = CreateSprite(gFieldEffectObjectTemplatePointers[26], 0xff, 0xb4, 0x1);
+ sprite = &gSprites[spriteId];
+ sprite->oam.paletteNum = 0;
+ sprite->oam.priority = 1;
+ sprite->callback = sub_80B957C;
+ return spriteId;
+}
+
+u8 sub_80B9508(u8 spriteId)
+{
+ return gSprites[spriteId].data[7];
+}
+
+void sub_80B9524(u8 spriteId)
+{
+ struct Sprite *sprite;
+ sprite = &gSprites[spriteId];
+ sprite->callback = sub_80B963C;
+ sprite->pos1.x = 0x78;
+ sprite->pos1.y = 0x00;
+ sprite->pos2.x = 0;
+ sprite->pos2.y = 0;
+ memset(&sprite->data[0], 0, 8 * sizeof(u16) /* zero all data cells */);
+ sprite->data[6] = 0x40;
+}
+
+void sub_80B9560(u8 a0, u8 a1)
+{
+ gSprites[a0].data[6] = a1;
+}
+
+const union AffineAnimCmd SpriteAffineAnim_855C518[] = {
+ AFFINEANIMCMD_FRAME(8, 8, -30, 0),
+ AFFINEANIMCMD_FRAME(28, 28, 0, 30),
+ AFFINEANIMCMD_END
+};
+
+const union AffineAnimCmd SpriteAffineAnim_855C530[] = {
+ AFFINEANIMCMD_FRAME(256, 256, 64, 0),
+ AFFINEANIMCMD_FRAME(-10, -10, 0, 22),
+ AFFINEANIMCMD_END
+};
+
+const union AffineAnimCmd *const gSpriteAffineAnimTable_0855C548[] = {
+ SpriteAffineAnim_855C518,
+ SpriteAffineAnim_855C530
+};
+
+void sub_80B957C(struct Sprite *sprite)
+{
+ if (sprite->data[7] == 0)
+ {
+ if (sprite->data[0] == 0)
+ {
+ sprite->oam.affineMode = 3;
+ sprite->affineAnims = gSpriteAffineAnimTable_0855C548;
+ InitSpriteAffineAnim(sprite);
+ StartSpriteAffineAnim(sprite, 0);
+ sprite->pos1.x = 0x76;
+ sprite->pos1.y = -0x30;
+ sprite->data[0]++;
+ sprite->data[1] = 0x40;
+ sprite->data[2] = 0x100;
+ }
+ sprite->data[1] += (sprite->data[2] >> 8);
+ sprite->pos2.x = Cos(sprite->data[1], 0x78);
+ sprite->pos2.y = Sin(sprite->data[1], 0x78);
+ if (sprite->data[2] < 0x800)
+ {
+ sprite->data[2] += 0x60;
+ }
+ if (sprite->data[1] > 0x81)
+ {
+ sprite->data[7]++;
+ sprite->oam.affineMode = 0;
+ FreeOamMatrix(sprite->oam.matrixNum);
+ CalcCenterToCornerVec(sprite, sprite->oam.shape, sprite->oam.size, 0);
+ }
+ }
+}
+
+void sub_80B963C(struct Sprite *sprite)
+{
+ struct Sprite *sprite1;
+ sprite->pos2.x = Cos(sprite->data[2], 0x8c);
+ sprite->pos2.y = Sin(sprite->data[2], 0x48);
+ sprite->data[2] = (sprite->data[2] + 4) & 0xff;
+ if (sprite->data[6] != 0x40)
+ {
+ sprite1 = &gSprites[sprite->data[6]];
+ sprite1->coordOffsetEnabled = 0;
+ sprite1->pos1.x = sprite->pos1.x + sprite->pos2.x;
+ sprite1->pos1.y = sprite->pos1.y + sprite->pos2.y - 8;
+ sprite1->pos2.x = 0;
+ sprite1->pos2.y = 0;
+ }
+ if (sprite->data[2] >= 0x80)
+ {
+ sprite->data[7] = 1;
+ }
+}
+
+void sub_80B96B0(struct Sprite *sprite)
+{
+ if (sprite->data[7] == 0)
+ {
+ if (sprite->data[0] == 0)
+ {
+ sprite->oam.affineMode = 3;
+ sprite->affineAnims = gSpriteAffineAnimTable_0855C548;
+ InitSpriteAffineAnim(sprite);
+ StartSpriteAffineAnim(sprite, 1);
+ sprite->pos1.x = 0x5e;
+ sprite->pos1.y = -0x20;
+ sprite->data[0]++;
+ sprite->data[1] = 0xf0;
+ sprite->data[2] = 0x800;
+ sprite->data[4] = 0x80;
+ }
+ sprite->data[1] += sprite->data[2] >> 8;
+ sprite->data[3] += sprite->data[2] >> 8;
+ sprite->data[1] &= 0xff;
+ sprite->pos2.x = Cos(sprite->data[1], 0x20);
+ sprite->pos2.y = Sin(sprite->data[1], 0x78);
+ if (sprite->data[2] > 0x100)
+ {
+ sprite->data[2] -= sprite->data[4];
+ }
+ if (sprite->data[4] < 0x100)
+ {
+ sprite->data[4] += 24;
+ }
+ if (sprite->data[2] < 0x100)
+ {
+ sprite->data[2] = 0x100;
+ }
+ if (sprite->data[3] >= 60)
+ {
+ sprite->data[7]++;
+ sprite->oam.affineMode = 0;
+ FreeOamMatrix(sprite->oam.matrixNum);
+ sprite->invisible = 1;
+ }
+ }
+}
+
+void sub_80B9794(u8 spriteId)
+{
+ sub_80B9524(spriteId);
+ gSprites[spriteId].callback = sub_80B96B0;
+}
+
+void sub_80B97D4(u8);
+
+u8 FldEff_FlyIn(void)
+{
+ CreateTask(sub_80B97D4, 0xfe);
+ return 0;
+}
+
+void (*const gUnknown_0855C550[])(struct Task *) = {
+ sub_80B9804,
+ sub_80B98B8,
+ sub_80B9924,
+ sub_80B9978,
+ sub_80B99F0,
+ sub_80B9A28,
+ sub_80B9A60,
+};
+
+void sub_80B97D4(u8 taskId)
+{
+ gUnknown_0855C550[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_80B9804(struct Task *task)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(mapObject) || FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ task->data[0]++;
+ task->data[2] = 17;
+ task->data[15] = gPlayerAvatar.flags;
+ gPlayerAvatar.preventStep = TRUE;
+ SetPlayerAvatarStateMask(0x01);
+ if (task->data[15] & 0x08)
+ {
+ sub_81555AC(mapObject->mapobj_unk_1A, 0);
+ }
+ FieldObjectSetGraphicsId(mapObject, GetPlayerAvatarGraphicsIdByStateId(0x3));
+ CameraObjectReset2();
+ FieldObjectTurn(mapObject, DIR_WEST);
+ StartSpriteAnim(&gSprites[mapObject->spriteId], 0x16);
+ mapObject->mapobj_bit_13 = 0;
+ task->data[1] = sub_80B94C4();
+ sub_80B9524(task->data[1]);
+ sub_80B9560(task->data[1], mapObject->spriteId);
+ }
+}
+
+void sub_80B98B8(struct Task *task)
+{
+ struct MapObject *mapObject;
+ struct Sprite *sprite;
+ if (task->data[2] == 0 || (--task->data[2]) == 0)
+ {
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ sprite = &gSprites[mapObject->spriteId];
+ sub_80B9560(task->data[1], 0x40);
+ sprite->pos1.x += sprite->pos2.x;
+ sprite->pos1.y += sprite->pos2.y;
+ sprite->pos2.x = 0;
+ sprite->pos2.y = 0;
+ task->data[0]++;
+ task->data[2] = 0;
+ }
+}
+
+void sub_80B9924(struct Task *task)
+{
+ s16 unknown_0855C56C[18] = {
+ -2,
+ -4,
+ -5,
+ -6,
+ -7,
+ -8,
+ -8,
+ -8,
+ -7,
+ -7,
+ -6,
+ -5,
+ -3,
+ -2,
+ 0,
+ 2,
+ 4,
+ 8
+ };
+ struct Sprite *sprite = &gSprites[gPlayerAvatar.spriteId];
+ sprite->pos2.y = unknown_0855C56C[task->data[2]];
+ if ((++task->data[2]) >= 18)
+ {
+ task->data[0]++;
+ }
+}
+
+void sub_80B9978(struct Task *task)
+{
+ struct MapObject *mapObject;
+ struct Sprite *sprite;
+ if (sub_80B9508(task->data[1]))
+ {
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ sprite = &gSprites[mapObject->spriteId];
+ mapObject->mapobj_bit_12 = 0;
+ sub_808EB08(mapObject, mapObject->coords2.x, mapObject->coords2.y);
+ sprite->pos2.x = 0;
+ sprite->pos2.y = 0;
+ sprite->coordOffsetEnabled = 1;
+ sub_808C114();
+ FieldObjectSetSpecialAnim(mapObject, 0x39);
+ task->data[0]++;
+ }
+}
+
+void sub_80B99F0(struct Task *task)
+{
+ if (FieldObjectClearAnimIfSpecialAnimFinished(&gMapObjects[gPlayerAvatar.mapObjectId]))
+ {
+ task->data[0]++;
+ sub_80B9794(task->data[1]);
+ }
+}
+
+void sub_80B9A28(struct Task *task)
+{
+ if (sub_80B9508(task->data[1]))
+ {
+ DestroySprite(&gSprites[task->data[1]]);
+ task->data[0]++;
+ task->data[1] = 0x10;
+ }
+}
+
+void sub_80B9A60(struct Task *task)
+{
+ u8 state;
+ struct MapObject *mapObject;
+ if ((--task->data[1]) == 0)
+ {
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ state = 0;
+ if (task->data[15] & 0x08)
+ {
+ state = 3;
+ sub_81555AC(mapObject->mapobj_unk_1A, 1);
+ }
+ FieldObjectSetGraphicsId(mapObject, GetPlayerAvatarGraphicsIdByStateId(state));
+ FieldObjectTurn(mapObject, DIR_SOUTH);
+ gPlayerAvatar.flags = task->data[15];
+ gPlayerAvatar.preventStep = FALSE;
+ FieldEffectActiveListRemove(FLDEFF_FLY_IN);
+ DestroyTask(FindTaskIdByFunc(sub_80B97D4));
+ }
+}
+
+void sub_80B9BE8(u8 taskId);
+
+bool8 sub_80B9ADC(void)
+{
+ u8 taskId;
+ u8 mapObjectIdBuffer;
+ if (!TryGetFieldObjectIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2], &mapObjectIdBuffer))
+ {
+ taskId = CreateTask(sub_80B9BE8, 0x50);
+ gTasks[taskId].data[2] = mapObjectIdBuffer;
+ gTasks[taskId].data[6] = gFieldEffectArguments[0];
+ gTasks[taskId].data[7] = gFieldEffectArguments[1];
+ gTasks[taskId].data[8] = gFieldEffectArguments[2];
+ }
+ else
+ {
+ FieldEffectActiveListRemove(0x41);
+ }
+ return FALSE;
+}
+
+void sub_80B9B3C(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ if (data[7] != 0)
+ {
+ if (++data[6] > 20)
+ {
+ data[6] = 0;
+ if (data[5] != 0)
+ data[5]--;
+ }
+ }
+ else
+ {
+ data[5] = 4;
+ }
+
+ if (++data[0] > 1)
+ {
+ data[0] = 0;
+ if (++data[1] & 1)
+ {
+ SetCameraPanning(0, -data[5]);
+ }
+ else
+ {
+ SetCameraPanning(0, data[5]);
+ }
+ }
+ UpdateCameraPanning();
+ if (data[5] == 0)
+ DestroyTask(taskId);
+}
+
+void sub_80B9BD0(u8 taskId)
+{
+ gTasks[taskId].data[7] = 1;
+}
+
+void (*const gUnknown_0855C590[])(s16*, u8) = {
+ sub_80B9C28,
+ sub_80B9C54,
+ sub_80B9CDC,
+};
+
+void sub_80B9BE8(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ InstallCameraPanAheadCallback();
+ SetCameraPanningCallback(0);
+ gUnknown_0855C590[data[1]](data, taskId);
+}
+
+void sub_80B9C28(s16* data, u8 taskId)
+{
+ u8 newTaskId = CreateTask(sub_80B9B3C, 0x5A);
+ PlaySE(SE_T_KAMI2);
+ data[5] = newTaskId;
+ data[1]++;
+}
+
+void sub_80B9D24(struct Sprite*);
+
+void sub_80B9C54(s16* data, u8 taskId)
+{
+ if (++data[3] > 0x78)
+ {
+ struct Sprite *sprite = &gSprites[gMapObjects[data[2]].spriteId];
+ gMapObjects[data[2]].mapobj_bit_13 = TRUE;
+ BlendPalettes(0x0000FFFF, 0x10, RGB_WHITE);
+ BeginNormalPaletteFade(0x0000FFFF, 0, 0x10, 0, RGB_WHITE);
+ sub_80B9D24(sprite);
+ PlaySE(SE_T_KAMI);
+ sub_80B9BD0(data[5]);
+ data[3] = 0;
+ data[1]++;
+ }
+}
+
+void sub_80B9CDC(s16* a0, u8 taskId)
+{
+ if (!gPaletteFade.active && !FuncIsActiveTask(sub_80B9B3C))
+ {
+ InstallCameraPanAheadCallback();
+ RemoveFieldObjectByLocalIdAndMap(a0[6], a0[7], a0[8]);
+ FieldEffectActiveListRemove(0x41);
+ DestroyTask(taskId);
+ }
+}
+
+void sub_80B9DB8(struct Sprite* sprite);
+
+const struct SpriteFrameImage gSpriteImageTable_855C59C[] = {
+ obj_frame_tiles(gUnknown_0855C170),
+ obj_frame_tiles(gUnknown_0855C190),
+ obj_frame_tiles(gUnknown_0855C1B0),
+ obj_frame_tiles(gUnknown_0855C1D0),
+};
+
+const union AnimCmd gSpriteAnim_855C5BC[] = {
+ ANIMCMD_FRAME(.imageValue = 0),
+ ANIMCMD_END
+};
+
+const union AnimCmd gSpriteAnim_855C5C4[] = {
+ ANIMCMD_FRAME(.imageValue = 1),
+ ANIMCMD_END
+};
+
+const union AnimCmd gSpriteAnim_855C5CC[] = {
+ ANIMCMD_FRAME(.imageValue = 2),
+ ANIMCMD_END
+};
+
+const union AnimCmd gSpriteAnim_855C5D4[] = {
+ ANIMCMD_FRAME(.imageValue = 3),
+ ANIMCMD_END
+};
+
+const union AnimCmd *const gSpriteAnimTable_855C5DC[] = {
+ gSpriteAnim_855C5BC,
+ gSpriteAnim_855C5C4,
+ gSpriteAnim_855C5CC,
+ gSpriteAnim_855C5D4,
+};
+
+const struct SpriteTemplate gUnknown_0855C5EC = {
+ .tileTag = 0xffff,
+ .paletteTag = 4378,
+ .oam = &gOamData_855C218,
+ .anims = gSpriteAnimTable_855C5DC,
+ .images = gSpriteImageTable_855C59C,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B9DB8
+};
+
+void sub_80B9D24(struct Sprite* sprite)
+{
+ int i;
+ int xPos = (s16)gUnknown_03005DEC + sprite->pos1.x + sprite->pos2.x;
+ int yPos = (s16)gUnknown_03005DE8 + sprite->pos1.y + sprite->pos2.y - 4;
+
+ for (i = 0; i < 4; i++)
+ {
+ u8 spriteId = CreateSprite(&gUnknown_0855C5EC, xPos, yPos, 0);
+ if (spriteId != 0x40)
+ {
+ StartSpriteAnim(&gSprites[spriteId], i);
+ gSprites[spriteId].data[0] = i;
+ gSprites[spriteId].oam.paletteNum = sprite->oam.paletteNum;
+ }
+ }
+}
+
+void sub_80B9DB8(struct Sprite* sprite)
+{
+ switch (sprite->data[0])
+ {
+ case 0:
+ sprite->pos1.x -= 16;
+ sprite->pos1.y -= 12;
+ break;
+ case 1:
+ sprite->pos1.x += 16;
+ sprite->pos1.y -= 12;
+ break;
+ case 2:
+ sprite->pos1.x -= 16;
+ sprite->pos1.y += 12;
+ break;
+ case 3:
+ sprite->pos1.x += 16;
+ sprite->pos1.y += 12;
+ break;
+ }
+ if ((u16)(sprite->pos1.x + 4) > 0xF8 || sprite->pos1.y < -4 || sprite->pos1.y > 0xA4)
+ DestroySprite(sprite);
+}
+
+void sub_80B9EDC(u8 taskId);
+
+bool8 sub_80B9E28(struct Sprite* sprite)
+{
+ u8 mapObjectIdBuffer;
+ if (!TryGetFieldObjectIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2], &mapObjectIdBuffer))
+ {
+ struct MapObject *object;
+ int xPos, yPos;
+ u8 taskId;
+ object = &gMapObjects[mapObjectIdBuffer];
+ xPos = object->coords2.x - 7;
+ yPos = object->coords2.y - 7;
+ xPos = (gFieldEffectArguments[3] - xPos) * 16;
+ yPos = (gFieldEffectArguments[4] - yPos) * 16;
+ npc_coords_shift(object, gFieldEffectArguments[3] + 7, gFieldEffectArguments[4] + 7);
+ taskId = CreateTask(sub_80B9EDC, 0x50);
+ gTasks[taskId].data[1] = object->spriteId;
+ gTasks[taskId].data[2] = gSprites[object->spriteId].pos1.x + xPos;
+ gTasks[taskId].data[3] = gSprites[object->spriteId].pos1.y + yPos;
+ gTasks[taskId].data[8] = gFieldEffectArguments[5];
+ gTasks[taskId].data[9] = mapObjectIdBuffer;
+ }
+ return FALSE;
+}
+
+void sub_80B9EDC(u8 taskId)
+{
+ // BUG: Possible divide by zero
+ s16 *data = gTasks[taskId].data;
+ struct Sprite *sprite = &gSprites[data[1]];
+ switch (data[0])
+ {
+ case 0:
+ data[4] = sprite->pos1.x << 4;
+ data[5] = sprite->pos1.y << 4;
+ data[6] = (data[2] * 16 - data[4]) / data[8];
+ data[7] = (data[3] * 16 - data[5]) / data[8];
+ data[0]++;
+ case 1:
+ if (data[8] != 0)
+ {
+ data[8]--;
+ data[4] += data[6];
+ data[5] += data[7];
+ sprite->pos1.x = data[4] >> 4;
+ sprite->pos1.y = data[5] >> 4;
+ }
+ else
+ {
+ struct MapObject *object = &gMapObjects[data[9]];
+ sprite->pos1.x = data[2];
+ sprite->pos1.y = data[3];
+ npc_coords_shift_still(object);
+ object->mapobj_bit_3 = TRUE;
+ FieldEffectActiveListRemove(0x42);
+ DestroyTask(taskId);
+ }
+ break;
+ }
+}
diff --git a/src/field_map_obj.c b/src/field_map_obj.c
index 906eff4b7..af018eb16 100644
--- a/src/field_map_obj.c
+++ b/src/field_map_obj.c
@@ -198,7 +198,7 @@ static void npcs_clear_ids_and_state(void)
void sub_808D438(void)
{
- strange_npc_table_clear();
+ ZeroAllLinkPlayerMapObjects();
npcs_clear_ids_and_state();
ClearPlayerAvatarInfo();
sub_808D450();
@@ -353,7 +353,7 @@ static u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u
return slot;
}
#else
-static __attribute__((naked)) u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u8 mapId, u8 mapGroupId)
+static NAKED u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u8 mapId, u8 mapGroupId)
{
asm_unified("\tpush {r4-r7,lr}\n"
"\tmov r7, r9\n"
@@ -1146,7 +1146,7 @@ const struct MapObjectGraphicsInfo *GetFieldObjectGraphicsInfo(u8 graphicsId)
}
if (graphicsId == 0x45)
{
- bard = sub_81201C8();
+ bard = GetCurrentMauvilleOldMan();
return gMauvilleOldManGraphicsInfoPointers[bard];
}
if (graphicsId >= NUM_OBJECT_GRAPHICS_INFO)
@@ -1673,7 +1673,7 @@ struct MapObjectTemplate *GetFieldObjectTemplateByLocalIdAndMap(u8 localId, u8 m
}
else
{
- mapHeader = get_mapheader_by_bank_and_number(mapGroup, mapNum);
+ mapHeader = Overworld_GetMapHeaderByGroupAndId(mapGroup, mapNum);
templates = mapHeader->events->mapObjects;
count = mapHeader->events->mapObjectCount;
}
diff --git a/src/field_map_obj_helpers.c b/src/field_map_obj_helpers.c
index de26cb034..b8efcfe72 100755
--- a/src/field_map_obj_helpers.c
+++ b/src/field_map_obj_helpers.c
@@ -529,16 +529,17 @@ void DoRippleFieldEffect(struct MapObject *mapObject, struct Sprite *sprite)
FieldEffectStart(FLDEFF_RIPPLE);
}
-#ifdef NONMATCHING
bool32 sub_8097E50(struct MapObject *mapObject, struct Sprite *sprite)
{
+ u32 one;
bool32 ableToStore = FALSE;
if (gUnknown_020375B8 == NULL)
{
gUnknown_020375B8 = AllocZeroed(0x14);
gUnknown_020375B8[0] = mapObject->localId;
- gUnknown_020375B8[16] = 1;
- ableToStore = TRUE;
+ // needed to match
+ gUnknown_020375B8[16] = (one = 1);
+ ableToStore = one;
}
else
{
@@ -561,7 +562,7 @@ bool32 sub_8097E50(struct MapObject *mapObject, struct Sprite *sprite)
{
gUnknown_020375B8[firstFreeSlot] = mapObject->localId;
gUnknown_020375B8[16]++;
- ableToStore = TRUE; // the nonmatching problem is that ableToStore == TRUE isnt being merged with the above ableToStore = TRUE assignment.
+ ableToStore = TRUE;
}
}
@@ -574,174 +575,34 @@ bool32 sub_8097E50(struct MapObject *mapObject, struct Sprite *sprite)
sprite->data[2] = 1;
return TRUE;
}
-#else
-__attribute__((naked))
-bool32 sub_8097E50(struct MapObject *mapObject, struct Sprite *sprite)
-{
- asm(".syntax unified\n\
- push {r4-r7,lr}\n\
- mov r7, r8\n\
- push {r7}\n\
- adds r4, r0, 0\n\
- mov r8, r1\n\
- movs r0, 0\n\
- mov r12, r0\n\
- ldr r0, =gUnknown_020375B8\n\
- ldr r1, [r0]\n\
- adds r6, r0, 0\n\
- cmp r1, 0\n\
- bne _08097E80\n\
- movs r0, 0x14\n\
- bl AllocZeroed\n\
- str r0, [r6]\n\
- ldrb r1, [r4, 0x8]\n\
- strb r1, [r0]\n\
- ldr r1, [r6]\n\
- movs r0, 0x1\n\
- strb r0, [r1, 0x10]\n\
- b _08097ECC\n\
- .pool\n\
-_08097E80:\n\
- movs r2, 0x10\n\
- movs r5, 0\n\
- movs r1, 0\n\
- adds r3, r6, 0\n\
- b _08097E90\n\
-_08097E8A:\n\
- adds r0, r1, 0x1\n\
- lsls r0, 24\n\
- lsrs r1, r0, 24\n\
-_08097E90:\n\
- cmp r1, 0xF\n\
- bhi _08097EB2\n\
- cmp r2, 0x10\n\
- bne _08097EA4\n\
- ldr r0, [r3]\n\
- adds r0, r1\n\
- ldrb r0, [r0]\n\
- cmp r0, 0\n\
- bne _08097EA4\n\
- adds r2, r1, 0\n\
-_08097EA4:\n\
- ldr r0, [r3]\n\
- adds r0, r1\n\
- ldrb r0, [r0]\n\
- ldrb r7, [r4, 0x8]\n\
- cmp r0, r7\n\
- bne _08097E8A\n\
- movs r5, 0x1\n\
-_08097EB2:\n\
- cmp r5, 0\n\
- bne _08097ECE\n\
- cmp r2, 0x10\n\
- beq _08097ECE\n\
- ldr r0, [r6]\n\
- adds r0, r2\n\
- ldrb r1, [r4, 0x8]\n\
- strb r1, [r0]\n\
- ldr r1, [r6]\n\
- ldrb r0, [r1, 0x10]\n\
- adds r0, 0x1\n\
- strb r0, [r1, 0x10]\n\
- movs r0, 0x1\n\
-_08097ECC:\n\
- mov r12, r0\n\
-_08097ECE:\n\
- mov r1, r12\n\
- cmp r1, 0x1\n\
- bne _08097EE0\n\
- ldrb r0, [r4, 0x1]\n\
- movs r1, 0x10\n\
- orrs r0, r1\n\
- movs r1, 0x2\n\
- orrs r0, r1\n\
- strb r0, [r4, 0x1]\n\
-_08097EE0:\n\
- movs r0, 0x1\n\
- mov r7, r8\n\
- strh r0, [r7, 0x32]\n\
- pop {r3}\n\
- mov r8, r3\n\
- pop {r4-r7}\n\
- pop {r1}\n\
- bx r1\n\
- .syntax divided");
-}
-#endif
-
-// this function is very similar to the above one and I don't want to decompile this one until the above is matching.
-__attribute__((naked))
+
bool32 sub_8097EF0(struct MapObject *mapObject, struct Sprite *sprite)
{
- asm(".syntax unified\n\
- push {r4-r7,lr}\n\
- mov r7, r8\n\
- push {r7}\n\
- adds r6, r0, 0\n\
- mov r8, r1\n\
- movs r0, 0x1\n\
- strh r0, [r1, 0x32]\n\
- ldr r5, =gUnknown_020375B8\n\
- ldr r0, [r5]\n\
- cmp r0, 0\n\
- beq _08097F68\n\
- movs r7, 0\n\
- adds r0, r6, 0\n\
- bl sub_8097F78\n\
- lsls r0, 24\n\
- lsrs r1, r0, 24\n\
- cmp r1, 0x10\n\
- beq _08097F28\n\
- ldr r0, [r5]\n\
- adds r0, r1\n\
- movs r1, 0\n\
- strb r1, [r0]\n\
- ldr r1, [r5]\n\
- ldrb r0, [r1, 0x10]\n\
- subs r0, 0x1\n\
- strb r0, [r1, 0x10]\n\
- movs r7, 0x1\n\
-_08097F28:\n\
- ldr r0, [r5]\n\
- ldrb r4, [r0, 0x10]\n\
- cmp r4, 0\n\
- bne _08097F36\n\
- bl Free\n\
- str r4, [r5]\n\
-_08097F36:\n\
- cmp r7, 0x1\n\
- bne _08097F68\n\
- ldrb r0, [r6, 0x5]\n\
- bl GetFieldObjectGraphicsInfo\n\
- ldrb r1, [r0, 0xC]\n\
- lsls r1, 25\n\
- lsrs r1, 31\n\
- lsls r1, 4\n\
- ldrb r2, [r6, 0x1]\n\
- movs r0, 0x11\n\
- negs r0, r0\n\
- ands r0, r2\n\
- orrs r0, r1\n\
- movs r1, 0x3\n\
- negs r1, r1\n\
- ands r0, r1\n\
- strb r0, [r6, 0x1]\n\
- mov r2, r8\n\
- adds r2, 0x2C\n\
- ldrb r1, [r2]\n\
- movs r0, 0x41\n\
- negs r0, r0\n\
- ands r0, r1\n\
- strb r0, [r2]\n\
-_08097F68:\n\
- movs r0, 0x1\n\
- pop {r3}\n\
- mov r8, r3\n\
- pop {r4-r7}\n\
- pop {r1}\n\
- bx r1\n\
- .pool\n\
- .syntax divided");
+ bool32 ableToStore;
+ u8 id;
+
+ sprite->data[2] = 1;
+ if (gUnknown_020375B8 != NULL)
+ {
+ ableToStore = FALSE;
+ id = sub_8097F78(mapObject);
+ if (id != 16)
+ {
+ gUnknown_020375B8[id] = 0;
+ gUnknown_020375B8[16]--;
+ ableToStore = TRUE;
+ }
+ if (gUnknown_020375B8[16] == 0)
+ FREE_AND_SET_NULL(gUnknown_020375B8);
+ if (ableToStore == TRUE)
+ {
+ mapObject->mapobj_bit_12 = GetFieldObjectGraphicsInfo(mapObject->graphicsId)->inanimate;
+ mapObject->mapobj_bit_9 = 0;
+ sprite->animPaused = 0;
+ }
+ }
+
+ return TRUE;
}
u8 sub_8097F78(struct MapObject *mapObject)
diff --git a/src/fieldmap.c b/src/fieldmap.c
new file mode 100644
index 000000000..245c88327
--- /dev/null
+++ b/src/fieldmap.c
@@ -0,0 +1,1034 @@
+#include "global.h"
+#include "overworld.h"
+#include "bg.h"
+#include "battle_frontier_2.h"
+#include "constants/rgb.h"
+#include "fieldmap.h"
+#include "fldeff_80F9BCC.h"
+#include "fldeff_cut.h"
+#include "fldeff_groundshake.h"
+#include "menu.h"
+#include "palette.h"
+#include "pokenav.h"
+#include "script.h"
+#include "secret_base.h"
+#include "tv.h"
+
+struct ConnectionFlags
+{
+ u8 south:1;
+ u8 north:1;
+ u8 west:1;
+ u8 east:1;
+};
+
+EWRAM_DATA static u16 gUnknown_02032318[0x2800] = {0};
+EWRAM_DATA struct MapHeader gMapHeader = {0};
+EWRAM_DATA struct Camera gCamera = {0};
+EWRAM_DATA static struct ConnectionFlags gUnknown_02037340 = {0};
+EWRAM_DATA static u32 sFiller_02037344 = 0; // without this, the next file won't align properly
+
+struct BackupMapData gUnknown_03005DC0;
+
+static const struct ConnectionFlags sDummyConnectionFlags = {0};
+
+struct MapHeader const *const mapconnection_get_mapheader(struct MapConnection *connection)
+{
+ return Overworld_GetMapHeaderByGroupAndId(connection->mapGroup, connection->mapNum);
+}
+
+void not_trainer_hill_battle_pyramid(void)
+{
+ mapheader_copy_mapdata_with_padding(&gMapHeader);
+ sub_80E8EE0(gMapHeader.events);
+ mapheader_run_script_with_tag_x1();
+}
+
+void sub_8087D74(void)
+{
+ mapheader_copy_mapdata_with_padding(&gMapHeader);
+ sub_80E9238(0);
+ sub_80E8EE0(gMapHeader.events);
+ mapdata_from_sav2();
+ mapheader_run_script_with_tag_x1();
+ UpdateTVScreensOnMap(gUnknown_03005DC0.width, gUnknown_03005DC0.height);
+}
+
+void battle_pyramid_map_load_related(u8 a0)
+{
+ CpuFastFill(0x03ff03ff, gUnknown_02032318, sizeof(gUnknown_02032318));
+ sub_81AA078(gUnknown_02032318, a0);
+}
+
+void trainer_hill_map_load_related(void)
+{
+ CpuFastFill(0x03ff03ff, gUnknown_02032318, sizeof(gUnknown_02032318));
+ sub_81D5FB4(gUnknown_02032318);
+}
+
+void mapheader_copy_mapdata_with_padding(struct MapHeader *mapHeader)
+{
+ struct MapData const *mapData;
+ int width;
+ int height;
+ mapData = mapHeader->mapData;
+ CpuFastFill16(0x03ff, gUnknown_02032318, sizeof(gUnknown_02032318));
+ gUnknown_03005DC0.map = gUnknown_02032318;
+ width = mapData->width + 15;
+ gUnknown_03005DC0.width = width;
+ height = mapData->height + 14;
+ gUnknown_03005DC0.height = height;
+ if (width * height <= 0x2800)
+ {
+ map_copy_with_padding(mapData->map, mapData->width, mapData->height);
+ mapheader_copy_mapdata_of_adjacent_maps(mapHeader);
+ }
+}
+
+void map_copy_with_padding(u16 *map, u16 width, u16 height)
+{
+ u16 *dest;
+ int y;
+ dest = gUnknown_03005DC0.map;
+ dest += gUnknown_03005DC0.width * 7 + 7;
+ for (y = 0; y < height; y++)
+ {
+ CpuCopy16(map, dest, width * 2);
+ dest += width + 0xf;
+ map += width;
+ }
+}
+
+void mapheader_copy_mapdata_of_adjacent_maps(struct MapHeader *mapHeader)
+{
+ int count;
+ struct MapConnection *connection;
+ int i;
+
+ if (mapHeader->connections)
+ {
+ count = mapHeader->connections->count;
+ connection = mapHeader->connections->connections;
+
+ gUnknown_02037340 = sDummyConnectionFlags;
+ for (i = 0; i < count; i++, connection++)
+ {
+ struct MapHeader const *cMap = mapconnection_get_mapheader(connection);
+ u32 offset = connection->offset;
+
+ switch (connection->direction)
+ {
+ case CONNECTION_SOUTH:
+ fillSouthConnection(mapHeader, cMap, offset);
+ gUnknown_02037340.south = 1;
+ break;
+ case CONNECTION_NORTH:
+ fillNorthConnection(mapHeader, cMap, offset);
+ gUnknown_02037340.north = 1;
+ break;
+ case CONNECTION_WEST:
+ fillWestConnection(mapHeader, cMap, offset);
+ gUnknown_02037340.west = 1;
+ break;
+ case CONNECTION_EAST:
+ fillEastConnection(mapHeader, cMap, offset);
+ gUnknown_02037340.east = 1;
+ break;
+ }
+ }
+ }
+}
+
+void sub_8087F54(int x, int y, struct MapHeader const *mapHeader, int x2, int y2, int width, int height)
+{
+ int i;
+ u16 *src;
+ u16 *dest;
+ int mapWidth;
+
+ mapWidth = mapHeader->mapData->width;
+ src = &mapHeader->mapData->map[mapWidth * y2 + x2];
+ dest = &gUnknown_03005DC0.map[gUnknown_03005DC0.width * y + x];
+
+ for (i = 0; i < height; i++)
+ {
+ CpuCopy16(src, dest, width * 2);
+ dest += gUnknown_03005DC0.width;
+ src += mapWidth;
+ }
+}
+
+void fillSouthConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset)
+{
+ int x, y;
+ int x2;
+ int width;
+ int cWidth;
+
+ if (connectedMapHeader)
+ {
+ cWidth = connectedMapHeader->mapData->width;
+ x = offset + 7;
+ y = mapHeader->mapData->height + 7;
+ if (x < 0)
+ {
+ x2 = -x;
+ x += cWidth;
+ if (x < gUnknown_03005DC0.width)
+ {
+ width = x;
+ }
+ else
+ {
+ width = gUnknown_03005DC0.width;
+ }
+ x = 0;
+ }
+ else
+ {
+ x2 = 0;
+ if (x + cWidth < gUnknown_03005DC0.width)
+ {
+ width = cWidth;
+ }
+ else
+ {
+ width = gUnknown_03005DC0.width - x;
+ }
+ }
+
+ sub_8087F54(
+ x, y,
+ connectedMapHeader,
+ x2, /*y2*/ 0,
+ width, /*height*/ 7);
+ }
+}
+
+void fillNorthConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset)
+{
+ int x;
+ int x2, y2;
+ int width;
+ int cWidth, cHeight;
+
+ if (connectedMapHeader)
+ {
+ cWidth = connectedMapHeader->mapData->width;
+ cHeight = connectedMapHeader->mapData->height;
+ x = offset + 7;
+ y2 = cHeight - 7;
+ if (x < 0)
+ {
+ x2 = -x;
+ x += cWidth;
+ if (x < gUnknown_03005DC0.width)
+ {
+ width = x;
+ }
+ else
+ {
+ width = gUnknown_03005DC0.width;
+ }
+ x = 0;
+ }
+ else
+ {
+ x2 = 0;
+ if (x + cWidth < gUnknown_03005DC0.width)
+ {
+ width = cWidth;
+ }
+ else
+ {
+ width = gUnknown_03005DC0.width - x;
+ }
+ }
+
+ sub_8087F54(
+ x, /*y*/ 0,
+ connectedMapHeader,
+ x2, y2,
+ width, /*height*/ 7);
+
+ }
+}
+
+void fillWestConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset)
+{
+ int y;
+ int x2, y2;
+ int height;
+ int cWidth, cHeight;
+ if (connectedMapHeader)
+ {
+ cWidth = connectedMapHeader->mapData->width;
+ cHeight = connectedMapHeader->mapData->height;
+ y = offset + 7;
+ x2 = cWidth - 7;
+ if (y < 0)
+ {
+ y2 = -y;
+ if (y + cHeight < gUnknown_03005DC0.height)
+ {
+ height = y + cHeight;
+ }
+ else
+ {
+ height = gUnknown_03005DC0.height;
+ }
+ y = 0;
+ }
+ else
+ {
+ y2 = 0;
+ if (y + cHeight < gUnknown_03005DC0.height)
+ {
+ height = cHeight;
+ }
+ else
+ {
+ height = gUnknown_03005DC0.height - y;
+ }
+ }
+
+ sub_8087F54(
+ /*x*/ 0, y,
+ connectedMapHeader,
+ x2, y2,
+ /*width*/ 7, height);
+ }
+}
+
+void fillEastConnection(struct MapHeader const *mapHeader, struct MapHeader const *connectedMapHeader, s32 offset)
+{
+ int x, y;
+ int y2;
+ int height;
+ int cHeight;
+ if (connectedMapHeader)
+ {
+ cHeight = connectedMapHeader->mapData->height;
+ x = mapHeader->mapData->width + 7;
+ y = offset + 7;
+ if (y < 0)
+ {
+ y2 = -y;
+ if (y + cHeight < gUnknown_03005DC0.height)
+ {
+ height = y + cHeight;
+ }
+ else
+ {
+ height = gUnknown_03005DC0.height;
+ }
+ y = 0;
+ }
+ else
+ {
+ y2 = 0;
+ if (y + cHeight < gUnknown_03005DC0.height)
+ {
+ height = cHeight;
+ }
+ else
+ {
+ height = gUnknown_03005DC0.height - y;
+ }
+ }
+
+ sub_8087F54(
+ x, y,
+ connectedMapHeader,
+ /*x2*/ 0, y2,
+ /*width*/ 8, height);
+ }
+}
+
+union Block
+{
+ struct
+ {
+ u16 block:10;
+ u16 collision:2;
+ u16 elevation:4;
+ } block;
+ u16 value;
+};
+
+u8 MapGridGetZCoordAt(int x, int y)
+{
+ u16 block;
+ int i;
+ u16 *border;
+
+ if (x >= 0 && x < gUnknown_03005DC0.width
+ && y >= 0 && y < gUnknown_03005DC0.height)
+ {
+ block = gUnknown_03005DC0.map[x + gUnknown_03005DC0.width * y];
+ }
+ else
+ {
+ border = gMapHeader.mapData->border;
+ i = (x + 1) & 1;
+ i += ((y + 1) & 1) * 2;
+ block = gMapHeader.mapData->border[i];
+ block |= 0xc00;
+ }
+
+ if (block == 0x3ff)
+ {
+ return 0;
+ }
+
+ return block >> 12;
+}
+
+u8 MapGridIsImpassableAt(int x, int y)
+{
+ u16 block;
+ int i;
+ u16 *border;
+
+ if (x >= 0 && x < gUnknown_03005DC0.width
+ && y >= 0 && y < gUnknown_03005DC0.height)
+ {
+ block = gUnknown_03005DC0.map[x + gUnknown_03005DC0.width * y];
+ }
+ else
+ {
+ border = gMapHeader.mapData->border;
+ i = (x + 1) & 1;
+ i += ((y + 1) & 1) * 2;
+ block = gMapHeader.mapData->border[i];
+ block |= 0xc00;
+ }
+ if (block == 0x3ff)
+ {
+ return 1;
+ }
+ return (block & 0xc00) >> 10;
+}
+
+u32 MapGridGetMetatileIdAt(int x, int y)
+{
+ u16 block;
+ int i;
+ int j;
+ struct MapData const *mapData;
+ u16 *border;
+ u16 block2;
+
+ if (x >= 0 && x < gUnknown_03005DC0.width
+ && y >= 0 && y < gUnknown_03005DC0.height)
+ {
+ block = gUnknown_03005DC0.map[x + gUnknown_03005DC0.width * y];
+ }
+ else
+ {
+ mapData = gMapHeader.mapData;
+ i = (x + 1) & 1;
+ i += ((y + 1) & 1) * 2;
+ block = mapData->border[i] | 0xc00;
+ }
+ if (block == 0x3ff)
+ {
+ border = gMapHeader.mapData->border;
+ j = (x + 1) & 1;
+ j += ((y + 1) & 1) * 2;
+ block2 = gMapHeader.mapData->border[j];
+ block2 |= 0xc00;
+ return block2 & block;
+ }
+ return block & 0x3ff;
+}
+
+u32 MapGridGetMetatileBehaviorAt(int x, int y)
+{
+ u16 metatile;
+ metatile = MapGridGetMetatileIdAt(x, y);
+ return GetBehaviorByMetatileId(metatile) & 0xff;
+}
+
+u8 MapGridGetMetatileLayerTypeAt(int x, int y)
+{
+ u16 metatile;
+ metatile = MapGridGetMetatileIdAt(x, y);
+ return (GetBehaviorByMetatileId(metatile) & 0xf000) >> 12;
+}
+
+void MapGridSetMetatileIdAt(int x, int y, u16 metatile)
+{
+ int i;
+ if (x >= 0 && x < gUnknown_03005DC0.width
+ && y >= 0 && y < gUnknown_03005DC0.height)
+ {
+ i = x + y * gUnknown_03005DC0.width;
+ gUnknown_03005DC0.map[i] = (gUnknown_03005DC0.map[i] & 0xf000) | (metatile & 0xfff);
+ }
+}
+
+void MapGridSetMetatileEntryAt(int x, int y, u16 metatile)
+{
+ int i;
+ if (x >= 0 && x < gUnknown_03005DC0.width
+ && y >= 0 && y < gUnknown_03005DC0.height)
+ {
+ i = x + gUnknown_03005DC0.width * y;
+ gUnknown_03005DC0.map[i] = metatile;
+ }
+}
+
+u16 GetBehaviorByMetatileId(u16 metatile)
+{
+ u16 *attributes;
+ if (metatile <= 0x1ff)
+ {
+ attributes = gMapHeader.mapData->primaryTileset->metatileAttributes;
+ return attributes[metatile];
+ }
+ else if (metatile <= 0x3ff)
+ {
+ attributes = gMapHeader.mapData->secondaryTileset->metatileAttributes;
+ return attributes[metatile - 0x200];
+ }
+ else
+ {
+ return 0xff;
+ }
+}
+
+void save_serialize_map(void)
+{
+ int i, j;
+ int x, y;
+ u16 *mapView;
+ int width;
+ mapView = gSaveBlock1Ptr->mapView;
+ width = gUnknown_03005DC0.width;
+ x = gSaveBlock1Ptr->pos.x;
+ y = gSaveBlock1Ptr->pos.y;
+ for (i = y; i < y + 14; i++)
+ {
+ for (j = x; j < x + 15; j++)
+ {
+ *mapView++ = gUnknown_02032318[width * i + j];
+ }
+ }
+}
+
+int sub_8088438(void)
+{
+ u16 i;
+ u32 r2;
+ r2 = 0;
+ for (i = 0; i < 0x200; i++)
+ {
+ r2 |= gSaveBlock1Ptr->mapView[i];
+ }
+ if (r2 == 0)
+ {
+ return 1;
+ }
+ return 0;
+}
+
+void sav2_mapdata_clear(void)
+{
+ CpuFill16(0, gSaveBlock1Ptr->mapView, sizeof(gSaveBlock1Ptr->mapView));
+}
+
+void mapdata_from_sav2(void)
+{
+ u8 a0;
+ int i, j;
+ int x, y;
+ u16 *mapView;
+ int width;
+ mapView = gSaveBlock1Ptr->mapView;
+ if (!sub_8088438())
+ {
+ width = gUnknown_03005DC0.width;
+ x = gSaveBlock1Ptr->pos.x;
+ y = gSaveBlock1Ptr->pos.y;
+ for (i = y; i < y + 14; i++)
+ {
+ if (i == y && i != 0)
+ a0 = 0;
+ else if (i == y + 13 && i != gMapHeader.mapData->height - 1)
+ a0 = 1;
+ else
+ a0 = -1;
+
+ for (j = x; j < x + 15; j++)
+ {
+ if (!sub_8088BF0(&gUnknown_02032318[j + width * i], width, a0))
+ gUnknown_02032318[j + width * i] = *mapView;
+ mapView++;
+ }
+ }
+ for (j = x; j < x + 15; j++)
+ {
+ if (y != 0)
+ sub_80D423C(j, y - 1);
+ if (i < gMapHeader.mapData->height - 1)
+ sub_80D42B8(j, y + 13);
+ }
+ sav2_mapdata_clear();
+ }
+}
+
+void sub_80885C4(u8 a1)
+{
+ int width;
+ u16 *mapView;
+ int x0, y0;
+ int x2, y2;
+ u16 *src, *dest;
+ int srci, desti;
+ int r9, r8;
+ int x, y;
+ int i, j;
+ mapView = gSaveBlock1Ptr->mapView;
+ width = gUnknown_03005DC0.width;
+ r9 = 0;
+ r8 = 0;
+ x0 = gSaveBlock1Ptr->pos.x;
+ y0 = gSaveBlock1Ptr->pos.y;
+ x2 = 15;
+ y2 = 14;
+ switch (a1)
+ {
+ case CONNECTION_NORTH:
+ y0 += 1;
+ y2 = 13;
+ break;
+ case CONNECTION_SOUTH:
+ r8 = 1;
+ y2 = 13;
+ break;
+ case CONNECTION_WEST:
+ x0 += 1;
+ x2 = 14;
+ break;
+ case CONNECTION_EAST:
+ r9 = 1;
+ x2 = 14;
+ break;
+ }
+ for (y = 0; y < y2; y++)
+ {
+ i = 0;
+ j = 0;
+ for (x = 0; x < x2; x++)
+ {
+ desti = width * (y + y0);
+ srci = (y + r8) * 15 + r9;
+ src = &mapView[srci + i];
+ dest = &gUnknown_02032318[x0 + desti + j];
+ *dest = *src;
+ i++;
+ j++;
+ }
+ }
+ sav2_mapdata_clear();
+}
+
+int GetMapBorderIdAt(int x, int y)
+{
+ struct MapData const *mapData;
+ u16 block, block2;
+ int i, j;
+ if (x >= 0 && x < gUnknown_03005DC0.width
+ && y >= 0 && y < gUnknown_03005DC0.height)
+ {
+ i = gUnknown_03005DC0.width;
+ i *= y;
+ block = gUnknown_03005DC0.map[x + i];
+ if (block == 0x3ff)
+ {
+ goto fail;
+ }
+ }
+ else
+ {
+ mapData = gMapHeader.mapData;
+ j = (x + 1) & 1;
+ j += ((y + 1) & 1) * 2;
+ block2 = 0xc00 | mapData->border[j];
+ if (block2 == 0x3ff)
+ {
+ goto fail;
+ }
+ }
+ goto success;
+fail:
+ return -1;
+success:
+
+ if (x >= (gUnknown_03005DC0.width - 8))
+ {
+ if (!gUnknown_02037340.east)
+ {
+ return -1;
+ }
+ return CONNECTION_EAST;
+ }
+ else if (x < 7)
+ {
+ if (!gUnknown_02037340.west)
+ {
+ return -1;
+ }
+ return CONNECTION_WEST;
+ }
+ else if (y >= (gUnknown_03005DC0.height - 7))
+ {
+ if (!gUnknown_02037340.south)
+ {
+ return -1;
+ }
+ return CONNECTION_SOUTH;
+ }
+ else if (y < 7)
+ {
+ if (!gUnknown_02037340.north)
+ {
+ return -1;
+ }
+ return CONNECTION_NORTH;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+int GetPostCameraMoveMapBorderId(int x, int y)
+{
+ return GetMapBorderIdAt(gSaveBlock1Ptr->pos.x + 7 + x, gSaveBlock1Ptr->pos.y + 7 + y);
+}
+
+int CanCameraMoveInDirection(int direction)
+{
+ int x, y;
+ x = gSaveBlock1Ptr->pos.x + 7 + gUnknown_08339D64[direction].x;
+ y = gSaveBlock1Ptr->pos.y + 7 + gUnknown_08339D64[direction].y;
+ if (GetMapBorderIdAt(x, y) == -1)
+ {
+ return 0;
+ }
+ return 1;
+}
+
+void sub_80887F8(struct MapConnection *connection, int direction, int x, int y)
+{
+ struct MapHeader const *mapHeader;
+ mapHeader = mapconnection_get_mapheader(connection);
+ switch (direction)
+ {
+ case CONNECTION_EAST:
+ gSaveBlock1Ptr->pos.x = -x;
+ gSaveBlock1Ptr->pos.y -= connection->offset;
+ break;
+ case CONNECTION_WEST:
+ gSaveBlock1Ptr->pos.x = mapHeader->mapData->width;
+ gSaveBlock1Ptr->pos.y -= connection->offset;
+ break;
+ case CONNECTION_SOUTH:
+ gSaveBlock1Ptr->pos.x -= connection->offset;
+ gSaveBlock1Ptr->pos.y = -y;
+ break;
+ case CONNECTION_NORTH:
+ gSaveBlock1Ptr->pos.x -= connection->offset;
+ gSaveBlock1Ptr->pos.y = mapHeader->mapData->height;
+ break;
+ }
+}
+
+bool8 CameraMove(int x, int y)
+{
+ unsigned int direction;
+ struct MapConnection *connection;
+ int old_x, old_y;
+ gCamera.active = FALSE;
+ direction = GetPostCameraMoveMapBorderId(x, y);
+ if (direction + 1 <= 1)
+ {
+ gSaveBlock1Ptr->pos.x += x;
+ gSaveBlock1Ptr->pos.y += y;
+ }
+ else
+ {
+ save_serialize_map();
+ sub_81BE72C();
+ old_x = gSaveBlock1Ptr->pos.x;
+ old_y = gSaveBlock1Ptr->pos.y;
+ connection = sub_8088950(direction, gSaveBlock1Ptr->pos.x, gSaveBlock1Ptr->pos.y);
+ sub_80887F8(connection, direction, x, y);
+ mliX_load_map(connection->mapGroup, connection->mapNum);
+ gCamera.active = TRUE;
+ gCamera.x = old_x - gSaveBlock1Ptr->pos.x;
+ gCamera.y = old_y - gSaveBlock1Ptr->pos.y;
+ gSaveBlock1Ptr->pos.x += x;
+ gSaveBlock1Ptr->pos.y += y;
+ sub_80885C4(direction);
+ }
+ return gCamera.active;
+}
+
+struct MapConnection *sub_8088950(u8 direction, int x, int y)
+{
+ int count;
+ struct MapConnection *connection;
+ int i;
+ count = gMapHeader.connections->count;
+ connection = gMapHeader.connections->connections;
+ for (i = 0; i < count; i++, connection++)
+ {
+ if (connection->direction == direction && sub_80889A8(direction, x, y, connection) == TRUE)
+ return connection;
+ }
+ return NULL;
+}
+
+bool8 sub_80889A8(u8 direction, int x, int y, struct MapConnection *connection)
+{
+ struct MapHeader const *mapHeader;
+ mapHeader = mapconnection_get_mapheader(connection);
+ switch (direction)
+ {
+ case CONNECTION_SOUTH:
+ case CONNECTION_NORTH:
+ return sub_8088A0C(x, gMapHeader.mapData->width, mapHeader->mapData->width, connection->offset);
+ case CONNECTION_WEST:
+ case CONNECTION_EAST:
+ return sub_8088A0C(y, gMapHeader.mapData->height, mapHeader->mapData->height, connection->offset);
+ }
+ return FALSE;
+}
+
+bool8 sub_8088A0C(int x, int src_width, int dest_width, int offset)
+{
+ int offset2;
+ offset2 = offset;
+
+ if (offset2 < 0)
+ offset2 = 0;
+
+ if (dest_width + offset < src_width)
+ src_width = dest_width + offset;
+
+ if (offset2 <= x && x <= src_width)
+ return TRUE;
+
+ return FALSE;
+}
+
+int sub_8088A38(int x, int width)
+{
+ if (x >= 0 && x < width)
+ return TRUE;
+
+ return FALSE;
+}
+
+int sub_8088A4C(struct MapConnection *connection, int x, int y)
+{
+ struct MapHeader const *mapHeader;
+ mapHeader = mapconnection_get_mapheader(connection);
+ switch (connection->direction)
+ {
+ case CONNECTION_SOUTH:
+ case CONNECTION_NORTH:
+ return sub_8088A38(x - connection->offset, mapHeader->mapData->width);
+ case CONNECTION_WEST:
+ case CONNECTION_EAST:
+ return sub_8088A38(y - connection->offset, mapHeader->mapData->height);
+ }
+ return FALSE;
+}
+
+struct MapConnection *sub_8088A8C(s16 x, s16 y)
+{
+ int count;
+ struct MapConnection *connection;
+ int i;
+ u8 direction;
+ if (!gMapHeader.connections)
+ {
+ return NULL;
+ }
+ else
+ {
+ count = gMapHeader.connections->count;
+ connection = gMapHeader.connections->connections;
+ for (i = 0; i < count; i++, connection++)
+ {
+ direction = connection->direction;
+ if ((direction == CONNECTION_DIVE || direction == CONNECTION_EMERGE)
+ || (direction == CONNECTION_NORTH && y > 6)
+ || (direction == CONNECTION_SOUTH && y < gMapHeader.mapData->height + 7)
+ || (direction == CONNECTION_WEST && x > 6)
+ || (direction == CONNECTION_EAST && x < gMapHeader.mapData->width + 7))
+ {
+ continue;
+ }
+ if (sub_8088A4C(connection, x - 7, y - 7) == TRUE)
+ {
+ return connection;
+ }
+ }
+ }
+ return NULL;
+}
+
+void sub_8088B3C(u16 x, u16 y)
+{
+ gSaveBlock1Ptr->pos.x = x - 7;
+ gSaveBlock1Ptr->pos.y = y - 7;
+}
+
+void sav1_camera_get_focus_coords(u16 *x, u16 *y)
+{
+ *x = gSaveBlock1Ptr->pos.x + 7;
+ *y = gSaveBlock1Ptr->pos.y + 7;
+}
+
+void SetCameraCoords(u16 x, u16 y)
+{
+ gSaveBlock1Ptr->pos.x = x;
+ gSaveBlock1Ptr->pos.y = y;
+}
+
+void GetCameraCoords(u16 *x, u16 *y)
+{
+ *x = gSaveBlock1Ptr->pos.x;
+ *y = gSaveBlock1Ptr->pos.y;
+}
+
+void sub_8088B94(int x, int y, int a2)
+{
+ if (x >= 0 && x < gUnknown_03005DC0.width && y >= 0 && y < gUnknown_03005DC0.height)
+ {
+ if (a2 != 0)
+ gUnknown_03005DC0.map[x + gUnknown_03005DC0.width * y] |= 0xC00;
+ else
+ gUnknown_03005DC0.map[x + gUnknown_03005DC0.width * y] &= 0xF3FF;
+ }
+}
+
+bool8 sub_8088BF0(u16* a0, u16 a1, u8 a2)
+{
+ if (a2 == 0xFF)
+ return FALSE;
+
+ if (a2 == 0)
+ a0 -= a1;
+ else
+ a0 += a1;
+
+ if (sub_80FADE4(*a0 & 0x3FF, a2) == 1)
+ return TRUE;
+ return FALSE;
+}
+
+void copy_tileset_patterns_to_vram(struct Tileset const *tileset, u16 numTiles, u16 offset)
+{
+ if (tileset)
+ {
+ if (!tileset->isCompressed)
+ LoadBgTiles(2, tileset->tiles, numTiles * 32, offset);
+ else
+ decompress_and_copy_tile_data_to_vram(2, tileset->tiles, numTiles * 32, offset, 0);
+ }
+}
+
+void copy_tileset_patterns_to_vram2(struct Tileset const *tileset, u16 numTiles, u16 offset)
+{
+ if (tileset)
+ {
+ if (!tileset->isCompressed)
+ LoadBgTiles(2, tileset->tiles, numTiles * 32, offset);
+ else
+ copy_decompressed_tile_data_to_vram_autofree(2, tileset->tiles, numTiles * 32, offset, 0);
+ }
+}
+
+void nullsub_3(u16 a0, u16 a1)
+{
+
+}
+
+void nullsub_90(void)
+{
+
+}
+
+void apply_map_tileset_palette(struct Tileset const *tileset, u16 destOffset, u16 size)
+{
+ u16 black = RGB_BLACK;
+
+ if (tileset)
+ {
+ if (tileset->isSecondary == FALSE)
+ {
+ LoadPalette(&black, destOffset, 2);
+ LoadPalette(((u16*)tileset->palettes) + 1, destOffset + 1, size - 2);
+ nullsub_3(destOffset + 1, (size - 2) >> 1);
+ }
+ else if (tileset->isSecondary == TRUE)
+ {
+ LoadPalette(((u16*)tileset->palettes) + 0x60, destOffset, size);
+ nullsub_3(destOffset, size >> 1);
+ }
+ else
+ {
+ LoadCompressedPalette((u16*)tileset->palettes, destOffset, size);
+ nullsub_3(destOffset, size >> 1);
+ }
+ }
+}
+
+void copy_map_tileset1_to_vram(struct MapData const *mapData)
+{
+ copy_tileset_patterns_to_vram(mapData->primaryTileset, 0x200, 0);
+}
+
+void copy_map_tileset2_to_vram(struct MapData const *mapData)
+{
+ copy_tileset_patterns_to_vram(mapData->secondaryTileset, 0x200, 0x200);
+}
+
+void copy_map_tileset2_to_vram_2(struct MapData const *mapData)
+{
+ copy_tileset_patterns_to_vram2(mapData->secondaryTileset, 0x200, 0x200);
+}
+
+void apply_map_tileset1_palette(struct MapData const *mapData)
+{
+ apply_map_tileset_palette(mapData->primaryTileset, 0, 0xC0);
+}
+
+void apply_map_tileset2_palette(struct MapData const *mapData)
+{
+ apply_map_tileset_palette(mapData->secondaryTileset, 0x60, 0xE0);
+}
+
+void copy_map_tileset1_tileset2_to_vram(struct MapData const *mapData)
+{
+ if (mapData)
+ {
+ copy_tileset_patterns_to_vram2(mapData->primaryTileset, 0x200, 0);
+ copy_tileset_patterns_to_vram2(mapData->secondaryTileset, 0x200, 0x200);
+ }
+}
+
+void apply_map_tileset1_tileset2_palette(struct MapData const *mapData)
+{
+ if (mapData)
+ {
+ apply_map_tileset1_palette(mapData);
+ apply_map_tileset2_palette(mapData);
+ }
+}
diff --git a/src/fldeff_flash.c b/src/fldeff_flash.c
new file mode 100644
index 000000000..4f3a091ce
--- /dev/null
+++ b/src/fldeff_flash.c
@@ -0,0 +1,367 @@
+#include "global.h"
+#include "constants/songs.h"
+#include "braille_puzzles.h"
+#include "event_data.h"
+#include "event_scripts.h"
+#include "field_effect.h"
+#include "gpu_regs.h"
+#include "gba/io_reg.h"
+#include "main.h"
+#include "palette.h"
+#include "party_menu.h"
+#include "overworld.h"
+#include "rom6.h"
+#include "script.h"
+#include "sound.h"
+#include "sprite.h"
+#include "task.h"
+
+// structures
+struct FlashStruct
+{
+ u8 unk0;
+ u8 unk1;
+ bool8 unk2;
+ bool8 unk3;
+ void (*func)(void);
+};
+
+// static functions
+static void hm2_flash(void);
+static void sub_81371B4(void);
+static bool8 sub_8137304(void);
+static void sub_81373F0(void);
+static void sub_8137404(u8 taskId);
+static void sub_8137420(u8 taskId);
+static void sub_81374C4(u8 taskId);
+static void sub_813750C(u8 taskId);
+static void sub_8137574(u8 taskId);
+static void sub_81375A8(void);
+static void sub_81375BC(u8 taskId);
+static void sub_81375D8(u8 taskId);
+static void sub_8137678(u8 taskId);
+static void sub_81376DC(u8 taskId);
+
+// rodata
+static const struct FlashStruct gUnknown_085B27C8[] =
+{
+ {1, 4, 1, 0, sub_81375A8},
+ {2, 4, 1, 0, sub_81375A8},
+ {3, 4, 1, 0, sub_81375A8},
+ {5, 4, 1, 0, sub_81375A8},
+ {6, 4, 1, 0, sub_81375A8},
+ {7, 4, 1, 0, sub_81375A8},
+ {8, 4, 1, 0, sub_81375A8},
+ {9, 4, 1, 0, sub_81375A8},
+ {4, 1, 0, 1, sub_81373F0},
+ {4, 2, 0, 1, sub_81373F0},
+ {4, 3, 0, 1, sub_81373F0},
+ {4, 5, 0, 1, sub_81373F0},
+ {4, 6, 0, 1, sub_81373F0},
+ {4, 7, 0, 1, sub_81373F0},
+ {4, 8, 0, 1, sub_81373F0},
+ {4, 9, 0, 1, sub_81373F0},
+ {0, 0, 0, 0, NULL},
+};
+
+static const u16 gCaveTransitionPalette_White[] = INCBIN_U16("graphics/misc/cave_transition_white.gbapal");
+static const u16 gCaveTransitionPalette_Black[] = INCBIN_U16("graphics/misc/cave_transition_black.gbapal");
+
+static const u16 gUnknown_085B2890[] = INCBIN_U16("graphics/misc/85B2890.gbapal");
+static const u16 gUnknown_085B28A0[] = INCBIN_U16("graphics/misc/85B28A0.gbapal");
+static const u16 gCaveTransitionTilemap[] = INCBIN_U16("graphics/misc/cave_transition_map.bin.lz");
+static const u8 gCaveTransitionTiles[] = INCBIN_U8("graphics/misc/cave_transition.4bpp.lz");
+
+// text
+bool8 SetUpFieldMove_Flash(void)
+{
+ if (ShouldDoBrailleFlyEffect())
+ {
+ gSpecialVar_Result = GetCursorSelectionMonId();
+ gUnknown_03005DB0 = FieldCallback_Teleport;
+ gUnknown_0203CEEC = sub_8179918;
+ return TRUE;
+ }
+ else if (gMapHeader.cave == TRUE && !FlagGet(FLAG_SYS_USE_FLASH))
+ {
+ gUnknown_03005DB0 = FieldCallback_Teleport;
+ gUnknown_0203CEEC = hm2_flash;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void hm2_flash(void)
+{
+ u8 taskId = oei_task_add();
+ gFieldEffectArguments[0] = GetCursorSelectionMonId();
+ gTasks[taskId].data[8] = (uintptr_t)sub_81371B4 >> 16;
+ gTasks[taskId].data[9] = (uintptr_t)sub_81371B4;
+}
+
+static void sub_81371B4(void)
+{
+ PlaySE(SE_W115);
+ FlagSet(FLAG_SYS_USE_FLASH);
+ ScriptContext1_SetupScript(EventScript_2926F8);
+}
+
+static void sub_81371D4(void)
+{
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+}
+
+static void sub_81371EC(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+void c2_change_map(void)
+{
+ u16 ime;
+
+ SetVBlankCallback(NULL);
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ SetGpuReg(REG_OFFSET_BG2CNT, 0);
+ SetGpuReg(REG_OFFSET_BG1CNT, 0);
+ SetGpuReg(REG_OFFSET_BG0CNT, 0);
+ SetGpuReg(REG_OFFSET_BG2HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG2VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG0HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG0VOFS, 0);
+ DmaFill16(3, 0, (void *)VRAM, VRAM_SIZE);
+ DmaFill32(3, 0, (void *)OAM, OAM_SIZE);
+ DmaFill16(3, 0, (void *)(PLTT + 2), PLTT_SIZE - 2);
+ ResetPaletteFade();
+ ResetTasks();
+ ResetSpriteData();
+ ime = REG_IME;
+ REG_IME = 0;
+ REG_IE |= INTR_FLAG_VBLANK;
+ REG_IME = ime;
+ SetVBlankCallback(sub_81371EC);
+ SetMainCallback2(sub_81371D4);
+ if (!sub_8137304())
+ SetMainCallback2(gMain.savedCallback);
+}
+
+static bool8 sub_8137304(void)
+{
+ u8 i;
+ u8 v0 = get_map_light_from_warp0();
+ u8 v1 = Overworld_GetMapTypeOfSaveblockLocation();
+
+ for (i = 0; gUnknown_085B27C8[i].unk0; i++)
+ {
+ if (gUnknown_085B27C8[i].unk0 == v0 && gUnknown_085B27C8[i].unk1 == v1)
+ {
+ gUnknown_085B27C8[i].func();
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+bool8 sub_8137360(u8 a1, u8 a2)
+{
+ u8 i;
+ u8 v0 = a1;
+ u8 v1 = a2;
+
+ for (i = 0; gUnknown_085B27C8[i].unk0; i++)
+ {
+ if (gUnknown_085B27C8[i].unk0 == v0 && gUnknown_085B27C8[i].unk1 == v1)
+ {
+ return gUnknown_085B27C8[i].unk2;
+ }
+ }
+
+ return FALSE;
+}
+
+bool8 fade_type_for_given_maplight_pair(u8 a1, u8 a2)
+{
+ u8 i;
+ u8 v0 = a1;
+ u8 v1 = a2;
+
+ for (i = 0; gUnknown_085B27C8[i].unk0; i++)
+ {
+ if (gUnknown_085B27C8[i].unk0 == v0 && gUnknown_085B27C8[i].unk1 == v1)
+ {
+ return gUnknown_085B27C8[i].unk3;
+ }
+ }
+
+ return FALSE;
+}
+
+static void sub_81373F0(void)
+{
+ CreateTask(sub_8137404, 0);
+}
+
+static void sub_8137404(u8 taskId)
+{
+ gTasks[taskId].func = sub_8137420;
+}
+
+static void sub_8137420(u8 taskId)
+{
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ LZ77UnCompVram(gCaveTransitionTiles, (void *)0x600C000);
+ LZ77UnCompVram(gCaveTransitionTilemap, (void *)0x600F800);
+ LoadPalette(gCaveTransitionPalette_White, 0xE0, 0x20);
+ LoadPalette(gUnknown_085B28A0, 0xE0, 0x10);
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG0
+ | BLDCNT_EFFECT_BLEND
+ | BLDCNT_TGT2_BG1
+ | BLDCNT_TGT2_BG2
+ | BLDCNT_TGT2_BG3
+ | BLDCNT_TGT2_OBJ
+ | BLDCNT_TGT2_BD);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ SetGpuReg(REG_OFFSET_BG0CNT, BGCNT_PRIORITY(0)
+ | BGCNT_CHARBASE(3)
+ | BGCNT_SCREENBASE(31)
+ | BGCNT_16COLOR
+ | BGCNT_TXT256x256);
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0
+ | DISPCNT_OBJ_1D_MAP
+ | DISPCNT_BG0_ON
+ | DISPCNT_OBJ_ON);
+ gTasks[taskId].func = sub_81374C4;
+ gTasks[taskId].data[0] = 16;
+ gTasks[taskId].data[1] = 0;
+}
+
+static void sub_81374C4(u8 taskId)
+{
+ u16 count = gTasks[taskId].data[1];
+ u16 blend = count + 0x1000;
+
+ SetGpuReg(REG_OFFSET_BLDALPHA, blend);
+ if (count <= 0x10)
+ {
+ gTasks[taskId].data[1]++;
+ }
+ else
+ {
+ gTasks[taskId].data[2] = 0;
+ gTasks[taskId].func = sub_813750C;
+ }
+}
+
+static void sub_813750C(u8 taskId)
+{
+ u16 count;
+
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 16));
+ count = gTasks[taskId].data[2];
+
+ if (count < 8)
+ {
+ gTasks[taskId].data[2]++;
+ LoadPalette(&gUnknown_085B28A0[count], 0xE0, 16 - 2 * count);
+ }
+ else
+ {
+ LoadPalette(gCaveTransitionPalette_White, 0, 0x20);
+ gTasks[taskId].func = sub_8137574;
+ gTasks[taskId].data[2] = 8;
+ }
+}
+
+static void sub_8137574(u8 taskId)
+{
+ if (gTasks[taskId].data[2])
+ gTasks[taskId].data[2]--;
+ else
+ SetMainCallback2(gMain.savedCallback);
+}
+
+static void sub_81375A8(void)
+{
+ CreateTask(sub_81375BC, 0);
+}
+
+static void sub_81375BC(u8 taskId)
+{
+ gTasks[taskId].func = sub_81375D8;
+}
+
+static void sub_81375D8(u8 taskId)
+{
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ LZ77UnCompVram(gCaveTransitionTiles, (void *)0x600C000);
+ LZ77UnCompVram(gCaveTransitionTilemap, (void *)0x600F800);
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ SetGpuReg(REG_OFFSET_BG0CNT, BGCNT_PRIORITY(0)
+ | BGCNT_CHARBASE(3)
+ | BGCNT_SCREENBASE(31)
+ | BGCNT_16COLOR
+ | BGCNT_TXT256x256);
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0
+ | DISPCNT_OBJ_1D_MAP
+ | DISPCNT_BG0_ON
+ | DISPCNT_OBJ_ON);
+ LoadPalette(gCaveTransitionPalette_White, 0xE0, 0x20);
+ LoadPalette(gCaveTransitionPalette_Black, 0, 0x20);
+ gTasks[taskId].func = sub_8137678;
+ gTasks[taskId].data[0] = 16;
+ gTasks[taskId].data[1] = 0;
+ gTasks[taskId].data[2] = 0;
+}
+
+static void sub_8137678(u8 taskId)
+{
+ u16 count = gTasks[taskId].data[2];
+
+ if (count < 16)
+ {
+ gTasks[taskId].data[2]++;
+ gTasks[taskId].data[2]++;
+ LoadPalette(&gUnknown_085B2890[15 - count], 0xE0, 2 * (count + 1));
+ }
+ else
+ {
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 16));
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG0
+ | BLDCNT_EFFECT_BLEND
+ | BLDCNT_TGT2_BG1
+ | BLDCNT_TGT2_BG2
+ | BLDCNT_TGT2_BG3
+ | BLDCNT_TGT2_OBJ
+ | BLDCNT_TGT2_BD);
+ gTasks[taskId].func = sub_81376DC;
+ }
+}
+
+static void sub_81376DC(u8 taskId)
+{
+ u16 count = 16 - gTasks[taskId].data[1];
+ u16 blend = count + 0x1000;
+
+ SetGpuReg(REG_OFFSET_BLDALPHA, blend);
+ if (count)
+ {
+ gTasks[taskId].data[1]++;
+ }
+ else
+ {
+ LoadPalette(gCaveTransitionPalette_Black, 0, 0x20);
+ SetMainCallback2(gMain.savedCallback);
+ }
+}
diff --git a/src/fldeff_groundshake.c b/src/fldeff_groundshake.c
new file mode 100644
index 000000000..bee4d2c4b
--- /dev/null
+++ b/src/fldeff_groundshake.c
@@ -0,0 +1,299 @@
+#include "global.h"
+#include "global.fieldmap.h"
+#include "constants/flags.h"
+#include "constants/songs.h"
+#include "event_data.h"
+#include "field_camera.h"
+#include "field_map_obj.h"
+#include "malloc.h"
+#include "random.h"
+#include "roulette_util.h"
+#include "script.h"
+#include "sound.h"
+#include "sprite.h"
+#include "task.h"
+
+// structures
+struct Struct203CF18 {
+ u8 taskId;
+ struct InnerStruct203CF18 unk4;
+}; //size = 0xC8
+
+// extern data
+extern const struct SpriteSheet gUnknown_08617D94[];
+extern const s16 gUnknown_08617D64[][3];
+
+// static functions
+static void sub_81BE808(u8 taskId);
+static void sub_81BE900(u8 taskId);
+static void sub_81BE968(void);
+static void sub_81BE9C0(u8 taskId);
+static void sub_81BEA00(u8 taskId);
+static void sub_81BEA20(void);
+static void sub_81BEAD8(struct Sprite* sprite);
+
+// rodata
+static const u8 gUnknown_08617E18[] = {0x3b, 0x43, 0x61, 0x00, 0x0f, 0x05, 0xff, 0x9b};
+
+static const union AnimCmd gSpriteAnim_8617E20[] =
+{
+ ANIMCMD_FRAME(0, 12),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const gSpriteAnimTable_8617E28[] =
+{
+ gSpriteAnim_8617E20,
+};
+
+static const struct OamData gUnknown_08617E2C =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 0,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const struct SpriteTemplate gUnknown_08617E34 = {
+ 0x0FA0, 0xFFFF, &gUnknown_08617E2C, gSpriteAnimTable_8617E28, NULL, gDummySpriteAffineAnimTable, sub_81BEAD8
+};
+
+static const union AnimCmd gSpriteAnim_8617E4C[] =
+{
+ ANIMCMD_FRAME(0, 12),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const gSpriteAnim_8617E54[] =
+{
+ gSpriteAnim_8617E4C,
+};
+
+static const struct OamData gSpriteAnim_8617E58 =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 1,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const struct SpriteTemplate gUnknown_08617E60 = {
+ 0x0FA0, 0xFFFF, &gSpriteAnim_8617E58, gSpriteAnim_8617E54, NULL, gDummySpriteAffineAnimTable, sub_81BEAD8
+};
+
+// ewram
+EWRAM_DATA struct Struct203CF18 *gUnknown_0203CF18 = NULL;
+
+// text
+bool8 sub_81BE66C(void)
+{
+ if (!(gSaveBlock1Ptr->location.mapGroup == 0x0 && gSaveBlock1Ptr->location.mapNum == 0x1A))
+ return 0;
+ return FlagGet(FLAG_0x14E);
+}
+
+void sub_81BE698(u8 taskId)
+{
+ sub_8151E50(&(gUnknown_0203CF18->unk4));
+}
+
+void sub_81BE6AC(void)
+{
+ gUnknown_0203CF18 = NULL;
+}
+
+void sub_81BE6B8(void)
+{
+ if(gUnknown_0203CF18 != NULL)
+ {
+ gUnknown_0203CF18 = NULL;
+ return;
+ }
+ if(!(gSaveBlock1Ptr->location.mapGroup == 0x0 && gSaveBlock1Ptr->location.mapNum == 0x1A) || !FlagGet(FLAG_0x14E))
+ return;
+
+ gUnknown_0203CF18 = (struct Struct203CF18 *)AllocZeroed(sizeof(struct Struct203CF18));
+ sub_8151B3C(&(gUnknown_0203CF18->unk4));
+ sub_8151B68(&(gUnknown_0203CF18->unk4), gUnknown_08617E18);
+ sub_8151CA8(&(gUnknown_0203CF18->unk4), 1, 1);
+ gUnknown_0203CF18->taskId = CreateTask(sub_81BE698, 0xFF);
+}
+
+void sub_81BE72C(void)
+{
+ if(!(gSaveBlock1Ptr->location.mapGroup == 0x0 && gSaveBlock1Ptr->location.mapNum == 0x1A) || !FlagGet(FLAG_0x14E) || gUnknown_0203CF18 == NULL)
+ return;
+ if(FuncIsActiveTask(sub_81BE698))
+ DestroyTask(gUnknown_0203CF18->taskId);
+ sub_8151D28(&(gUnknown_0203CF18->unk4), 1, 1);
+ sub_8151C50(&(gUnknown_0203CF18->unk4), 1, 1);
+ Free(gUnknown_0203CF18);
+ gUnknown_0203CF18 = NULL;
+}
+
+void sub_81BE79C(void)
+{
+ u16 rand;
+ bool8 chance;
+
+ if(VarGet(VAR_0x40CB) != 0)
+ {
+ FlagClear(FLAG_0x14E);
+ return;
+ }
+ rand = Random();
+ chance = rand & 1;
+ if(FlagGet(FLAG_0x09D) == TRUE)
+ chance = TRUE;
+ if(chance)
+ {
+ FlagSet(FLAG_0x14E);
+ sub_81BE6B8();
+ return;
+ }
+ FlagClear(FLAG_0x14E);
+}
+
+void sub_81BE7F4(void)
+{
+ CreateTask(sub_81BE808, 0x8);
+}
+
+static void sub_81BE808(u8 taskId)
+{
+ u8 mapObjectIdBuffer;
+ struct MapObject *fieldMapObject;
+ struct MapObject *playerAvatarMapObject;
+
+ TryGetFieldObjectIdByLocalIdAndMap(0x2D, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &mapObjectIdBuffer);
+ fieldMapObject = &(gMapObjects[mapObjectIdBuffer]);
+ gSprites[fieldMapObject->spriteId].pos2.y += 4;
+ playerAvatarMapObject = &(gMapObjects[gPlayerAvatar.mapObjectId]);
+
+ if((gSprites[fieldMapObject->spriteId].pos1.y + gSprites[fieldMapObject->spriteId].pos2.y) >=
+ (gSprites[playerAvatarMapObject->spriteId].pos1.y + gSprites[playerAvatarMapObject->spriteId].pos2.y))
+ {
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+ }
+}
+
+static void sp136_strengh_sound(u8 a, u8 b, u8 c, u8 d)
+{
+ u8 taskId;
+
+ taskId = CreateTask(sub_81BE900, 0x9);
+ gTasks[taskId].data[0] = b;
+ gTasks[taskId].data[1] = 0;
+ gTasks[taskId].data[2] = c;
+ gTasks[taskId].data[3] = d;
+ gTasks[taskId].data[4] = a;
+ SetCameraPanningCallback(NULL);
+ PlaySE(SE_W070);
+}
+
+static void sub_81BE900(u8 taskId)
+{
+ s16 *data;
+
+ data = gTasks[taskId].data;
+ data[1]++;
+ if((data[1] % data[3]) == 0)
+ {
+ data[1] = 0;
+ data[2]--;
+ data[0] = -data[0];
+ data[4] = -data[4];
+ SetCameraPanning(data[0], data[4]);
+ if(!data[2])
+ {
+ sub_81BE968();
+ DestroyTask(taskId);
+ InstallCameraPanAheadCallback();
+ }
+ }
+}
+
+static void sub_81BE968(void)
+{
+ u8 taskId;
+
+ taskId = FindTaskIdByFunc(sub_81BE9C0);
+ if(taskId != 0xFF)
+ gTasks[taskId].data[0]++;
+}
+
+void sub_81BE994(void)
+{
+ LoadSpriteSheets(gUnknown_08617D94);
+ sub_81BEA20();
+ CreateTask(sub_81BE9C0, 0x8);
+ sp136_strengh_sound(2, 1, 16, 3);
+}
+
+static void sub_81BE9C0(u8 taskId)
+{
+ u16 *data;
+
+ data = gTasks[taskId].data;
+ data[1]++;
+ if(data[1] == 1000 || data[0] == 17)
+ gTasks[taskId].func = sub_81BEA00;
+}
+
+static void sub_81BEA00(u8 taskId)
+{
+ FreeSpriteTilesByTag(4000);
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+}
+
+static void sub_81BEA20(void)
+{
+ u8 i;
+ u8 spriteId;
+
+ for(i = 0; i < 8; i++)
+ {
+ spriteId = CreateSprite(&gUnknown_08617E60, gUnknown_08617D64[i][0] + 120, gUnknown_08617D64[i][1], 8);
+ gSprites[spriteId].oam.priority = 0;
+ gSprites[spriteId].oam.paletteNum = 0;
+ gSprites[spriteId].data[0] = i;
+ }
+ for(i = 0; i < 8; i++)
+ {
+ spriteId = CreateSprite(&gUnknown_08617E34, gUnknown_08617D64[i][0] + 115, gUnknown_08617D64[i][1] - 3, 8);
+ gSprites[spriteId].oam.priority = 0;
+ gSprites[spriteId].oam.paletteNum = 0;
+ gSprites[spriteId].data[0] = i;
+ }
+}
+
+static void sub_81BEAD8(struct Sprite* sprite)
+{
+ sprite->data[1] += 2;
+ sprite->pos2.y = (sprite->data[1] / 2);
+ if(((sprite->pos1.y) + (sprite->pos2.y)) > gUnknown_08617D64[sprite->data[0]][2])
+ {
+ DestroySprite(sprite);
+ sub_81BE968();
+ }
+}
diff --git a/src/fldeff_softboiled.c b/src/fldeff_softboiled.c
new file mode 100644
index 000000000..d0a40a9a9
--- /dev/null
+++ b/src/fldeff_softboiled.c
@@ -0,0 +1,109 @@
+#include "global.h"
+#include "menu.h"
+#include "party_menu.h"
+#include "pokemon.h"
+#include "constants/songs.h"
+#include "sound.h"
+#include "sprite.h"
+#include "string_util.h"
+#include "strings.h"
+#include "task.h"
+
+static void sub_816166C(u8 taskId);
+static void sub_81616C0(u8 taskId);
+static void sub_8161724(u8 taskId);
+static void sub_81617B8(u8 taskId);
+
+bool8 SetUpFieldMove_SoftBoiled(void)
+{
+ u16 maxHp;
+ u16 hp;
+ u16 minHp;
+
+ maxHp = GetMonData(&gPlayerParty[GetCursorSelectionMonId()], MON_DATA_MAX_HP);
+ hp = GetMonData(&gPlayerParty[GetCursorSelectionMonId()], MON_DATA_HP);
+
+ minHp = (maxHp / 5);
+ if (hp > minHp)
+ return TRUE;
+ return FALSE;
+}
+
+void sub_8161560(u8 taskId)
+{
+ gUnknown_0203CEC8.unkB = 0xA;
+ gUnknown_0203CEC8.unkA = gUnknown_0203CEC8.unk9;
+ sub_81B0FCC(GetCursorSelectionMonId(), 0x1);
+ display_pokemon_menu_message(0x5);
+ gTasks[taskId].func = sub_81B1370;
+}
+
+void sub_81615A8(u8 taskId)
+{
+ u16 hp;
+
+ u8 unk9 = gUnknown_0203CEC8.unk9;
+ u8 pokemonIndex = gUnknown_0203CEC8.unkA;
+ if(pokemonIndex > 6)
+ {
+ gUnknown_0203CEC8.unkB = 0;
+ display_pokemon_menu_message(0x0);
+ gTasks[taskId].func = sub_81B1370;
+ return;
+ }
+
+ hp = GetMonData(&gPlayerParty[pokemonIndex], MON_DATA_HP);
+ if(hp == 0 || unk9 == pokemonIndex || GetMonData(&gPlayerParty[pokemonIndex], MON_DATA_MAX_HP) == hp)
+ {
+ sub_81617B8(taskId);
+ return;
+ }
+
+ PlaySE(SE_KAIFUKU);
+ sub_81B1F18(taskId, unk9, -1, GetMonData(&gPlayerParty[unk9], MON_DATA_MAX_HP)/5, sub_816166C);
+}
+
+static void sub_816166C(u8 taskId)
+{
+ PlaySE(SE_KAIFUKU);
+ sub_81B1F18(taskId, gUnknown_0203CEC8.unkA, 1, GetMonData(&gPlayerParty[gUnknown_0203CEC8.unk9], MON_DATA_MAX_HP)/5, sub_81616C0);
+}
+
+static void sub_81616C0(u8 taskId)
+{
+ GetMonNickname(&gPlayerParty[gUnknown_0203CEC8.unkA], gStringVar1);
+ StringExpandPlaceholders(gStringVar4, gText_PkmnHPRestoredByVar2);
+ sub_81B1B5C(gStringVar4, 0);
+ schedule_bg_copy_tilemap_to_vram(2);
+ gTasks[taskId].func = sub_8161724;
+}
+
+static void sub_8161724(u8 taskId)
+{
+ if(sub_81B1BD4() == 1)
+ return;
+ gUnknown_0203CEC8.unkB = 0x0;
+ sub_81B0FCC(gUnknown_0203CEC8.unk9, 0);
+ gUnknown_0203CEC8.unk9 = gUnknown_0203CEC8.unkA;
+ sub_81B0FCC(gUnknown_0203CEC8.unkA, 1);
+ sub_8198070(0x6, FALSE);
+ ClearWindowTilemap(0x6);
+ display_pokemon_menu_message(0);
+ gTasks[taskId].func = sub_81B1370;
+}
+
+static void sub_8161784(u8 taskId)
+{
+ if(sub_81B1BD4() == 1)
+ return;
+ display_pokemon_menu_message(0x5);
+ gTasks[taskId].func = sub_81B1370;
+}
+
+static void sub_81617B8(u8 taskId)
+{
+ PlaySE(SE_SELECT);
+ sub_81B1B5C(&gText_CantBeUsedOnPkmn, 0);
+ schedule_bg_copy_tilemap_to_vram(2);
+ gTasks[taskId].func = sub_8161784;
+}
diff --git a/src/fldeff_strength.c b/src/fldeff_strength.c
new file mode 100644
index 000000000..162479c73
--- /dev/null
+++ b/src/fldeff_strength.c
@@ -0,0 +1,46 @@
+#include "global.h"
+#include "event_data.h"
+#include "event_scripts.h"
+#include "field_effect.h"
+#include "party_menu.h"
+#include "rom6.h"
+#include "script.h"
+#include "task.h"
+
+// static functions
+static void FldEff_UseStrength(void);
+static void sub_8145E74(void);
+
+// text
+bool8 SetUpFieldMove_Strength(void)
+{
+ if (npc_before_player_of_type(87) == TRUE)
+ {
+ gSpecialVar_Result = GetCursorSelectionMonId();
+ gUnknown_03005DB0 = FieldCallback_Teleport;
+ gUnknown_0203CEEC = FldEff_UseStrength;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void FldEff_UseStrength(void)
+{
+ gFieldEffectArguments[0] = GetCursorSelectionMonId();
+ ScriptContext1_SetupScript(FieryPath_EventScript_2908FD);
+}
+
+bool8 sub_8145E2C(void)
+{
+ u8 taskId = oei_task_add();
+ gTasks[taskId].data[8] = (u32)sub_8145E74 >> 16;
+ gTasks[taskId].data[9] = (u32)sub_8145E74;
+ GetMonNickname(&gPlayerParty[gFieldEffectArguments[0]], gStringVar1);
+ return FALSE;
+}
+
+static void sub_8145E74(void)
+{
+ FieldEffectActiveListRemove(FLDEFF_USE_STRENGTH);
+ EnableBothScriptContexts();
+}
diff --git a/src/fldeff_sweetscent.c b/src/fldeff_sweetscent.c
new file mode 100644
index 000000000..100e440a5
--- /dev/null
+++ b/src/fldeff_sweetscent.c
@@ -0,0 +1,98 @@
+#include "global.h"
+#include "constants/rgb.h"
+#include "constants/songs.h"
+#include "event_data.h"
+#include "event_scripts.h"
+#include "field_effect.h"
+#include "field_player_avatar.h"
+#include "field_screen.h"
+#include "palette.h"
+#include "party_menu.h"
+#include "rom6.h"
+#include "script.h"
+#include "sound.h"
+#include "sprite.h"
+#include "task.h"
+#include "wild_encounter.h"
+
+void hm2_sweet_scent(void);
+void sub_8159F5C(void);
+void sub_8159FEC(u8 taskId);
+void sub_815A090(u8 taskId);
+void sub_81BE6B8(void);
+void sub_81BE72C(void);
+
+bool8 SetUpFieldMove_SweetScent(void)
+{
+ gUnknown_03005DB0 = FieldCallback_Teleport;
+ gUnknown_0203CEEC = hm2_sweet_scent;
+ return TRUE;
+}
+
+void hm2_sweet_scent(void)
+{
+ FieldEffectStart(FLDEFF_SWEET_SCENT);
+ gFieldEffectArguments[0] = GetCursorSelectionMonId();
+}
+
+bool8 FldEff_SweetScent()
+{
+ u8 taskId;
+
+ sub_80AC3D0();
+ taskId = oei_task_add();
+ gTasks[taskId].data[8] = (u32)sub_8159F5C >> 16;
+ gTasks[taskId].data[9] = (u32)sub_8159F5C;
+ return FALSE;
+}
+
+void sub_8159F5C(void)
+{
+ u8 taskId;
+
+ PlaySE(SE_W230);
+ CpuFastSet(gPlttBufferUnfaded, gPaletteDecompressionBuffer, 0x100);
+ CpuFastSet(gPlttBufferFaded, gPlttBufferUnfaded, 0x100);
+ BeginNormalPaletteFade(~(1 << (gSprites[GetPlayerAvatarObjectId()].oam.paletteNum + 16)), 4, 0, 8, RGB_RED);
+ taskId = CreateTask(sub_8159FEC, 0);
+ gTasks[taskId].data[0] = 0;
+ FieldEffectActiveListRemove(FLDEFF_SWEET_SCENT);
+}
+
+void sub_8159FEC(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ sub_81BE72C();
+ BlendPalettes(0x00000040, 8, RGB_RED);
+ if (gTasks[taskId].data[0] == 64)
+ {
+ gTasks[taskId].data[0] = 0;
+ if (SweetScentWildEncounter() == TRUE)
+ {
+ DestroyTask(taskId);
+ }
+ else
+ {
+ gTasks[taskId].func = sub_815A090;
+ BeginNormalPaletteFade(~(1 << (gSprites[GetPlayerAvatarObjectId()].oam.paletteNum + 16)), 4, 8, 0, RGB_RED);
+ sub_81BE6B8();
+ }
+ }
+ else
+ {
+ gTasks[taskId].data[0]++;
+ }
+ }
+}
+
+void sub_815A090(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ CpuFastSet(gPaletteDecompressionBuffer, gPlttBufferUnfaded, 0x100);
+ sub_80AC3E4();
+ ScriptContext1_SetupScript(EventScript_290CAE);
+ DestroyTask(taskId);
+ }
+}
diff --git a/src/fldeff_teleport.c b/src/fldeff_teleport.c
index 5b3492db0..1b88b42d7 100644
--- a/src/fldeff_teleport.c
+++ b/src/fldeff_teleport.c
@@ -7,17 +7,14 @@
#include "rom6.h"
#include "task.h"
-extern bool8 (*gUnknown_03005DB0)(void);
-extern void (*gUnknown_0203CEEC)(void);
-
bool8 SetUpFieldMove_Teleport(void)
{
if (Overworld_MapTypeAllowsTeleportAndFly(gMapHeader.mapType) == TRUE)
{
gUnknown_03005DB0 = FieldCallback_Teleport;
- gUnknown_0203CEEC = hm_teleport_run_dp02scr;
+ gUnknown_0203CEEC = hm_teleport_run_dp02scr;
return TRUE;
- }
+ }
return FALSE;
}
@@ -40,7 +37,7 @@ bool8 FldEff_UseTeleport(void)
void sub_817C94C(void)
{
FieldEffectActiveListRemove(FLDEFF_USE_TELEPORT);
- sub_80B7FC8();
+ CreateTeleportFieldEffectTask();
}
diff --git a/src/fossil_specials.c b/src/fossil_specials.c
new file mode 100644
index 000000000..060915fa6
--- /dev/null
+++ b/src/fossil_specials.c
@@ -0,0 +1,770 @@
+#include "global.h"
+#include "constants/flags.h"
+#include "constants/songs.h"
+#include "bg.h"
+#include "event_data.h"
+#include "field_camera.h"
+#include "field_map_obj.h"
+#include "fieldmap.h"
+#include "global.fieldmap.h"
+#include "gpu_regs.h"
+#include "malloc.h"
+#include "menu.h"
+#include "random.h"
+#include "script.h"
+#include "sound.h"
+#include "sprite.h"
+#include "task.h"
+#include "window.h"
+
+#define MIRAGE_TOWER_GFX_LENGTH (sizeof(gUnknown_08617274) + sizeof(gMirageTower_Gfx))
+#define MIRAGE_TOWER_PALETTE_LENGTH 0x800
+#define ROOT_FOSSIL_GFX_LENGTH sizeof(gRootFossil_Gfx)
+#define ROOT_FOSSIL_GFX_RANDOMIZER_LENGTH 0x100
+
+//struct
+struct Struct8617DA4 {
+ u8 x;
+ u8 y;
+ u16 tileId;
+};
+
+struct Struct203CF10 {
+ u8 *buffer;
+ u8 curr_buffer_index;
+};
+
+struct DynamicSpriteFrameImage{
+ u8 *data;
+ u16 size;
+};
+
+struct Struct203CF0C {
+ u8 *frameImageTiles;
+ struct DynamicSpriteFrameImage *frameImage;
+ u8 spriteId;
+ u16 *unkC;
+ u16 unk10;
+};
+
+// static functions
+static void sub_81BED50(u8 taskId);
+static void sub_81BEBF4(u8 taskId);
+static void sub_81BF028(u8 taskId);
+static void sub_81BF248(struct Sprite *);
+/*static*/ void sub_81BF2B8(u8* a, u16 b, u8 c, u8 d, u8 e);
+
+// .rodata
+static const u8 gUnknown_08617274[] = {00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00};
+static const u8 gMirageTower_Gfx[] = INCBIN_U8("graphics/misc/mirage_tower.4bpp");
+static const u16 gUnknown_08617B94[] = INCBIN_U16("graphics/misc/mirage_tower.bin");
+static const u16 gRootFossil_Pal[] = INCBIN_U16("graphics/misc/fossil.gbapal");
+static const u8 gRootFossil_Gfx[] = INCBIN_U8("graphics/misc/fossil.4bpp");
+static const u8 gMirageTowerCrumbles_Gfx[] = INCBIN_U8("graphics/misc/mirage_tower_crumbles.4bpp");
+static const u16 gMirageTowerCrumbles_Palette[] = INCBIN_U16("graphics/misc/mirage_tower_crumbles.gbapal");
+
+const s16 gUnknown_08617D64[][3] =
+ {
+ { 0, 10, 65},
+ { 17, 3, 50},
+ {-12, 0, 75},
+ { 10, 15, 90},
+ { 7, 8, 65},
+ {-18, 5, 75},
+ { 22, -10, 55},
+ {-24, -4, 65},
+ };
+
+const struct SpriteSheet gUnknown_08617D94[] =
+{
+ {gMirageTowerCrumbles_Gfx, 0x0080, 0x0fa0},
+ {NULL}
+};
+
+static const struct Struct8617DA4 gUnknown_08617DA4[] =
+ {
+ {0x12, 0x35, 0x251},
+ {0x13, 0x35, 0x251},
+ {0x14, 0x35, 0x251},
+ {0x12, 0x36, 0x251},
+ {0x13, 0x36, 0x251},
+ {0x14, 0x36, 0x251},
+ {0x12, 0x37, 0x251},
+ {0x13, 0x37, 0x251},
+ {0x14, 0x37, 0x251},
+ {0x12, 0x38, 0x251},
+ {0x13, 0x38, 0x251},
+ {0x14, 0x38, 0x251},
+ {0x12, 0x39, 0x259},
+ {0x13, 0x39, 0x259},
+ {0x14, 0x39, 0x259},
+ {0x12, 0x3A, 0x121},
+ {0x13, 0x3A, 0x121},
+ {0x14, 0x3A, 0x121},
+ };
+
+static const union AnimCmd gSpriteAnim_8617DEC[] =
+{
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END,
+};
+
+static const struct OamData gOamData_8617DF4 =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 1,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 3,
+ .affineParam = 0,
+};
+
+static const union AnimCmd *const gSpriteAnimTable_8617DFC[] =
+{
+ gSpriteAnim_8617DEC,
+};
+
+static const struct SpriteTemplate gUnknown_08617E00 = {
+ 0xFFFF, 0xFFFF, &gOamData_8617DF4, gSpriteAnimTable_8617DFC, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy
+};
+
+// ewram
+EWRAM_DATA u8* gUnknown_0203CF04 = NULL;
+EWRAM_DATA u8* gUnknown_0203CF08 = NULL;
+EWRAM_DATA struct Struct203CF0C *gUnknown_0203CF0C = NULL;
+EWRAM_DATA struct Struct203CF10 *gUnknown_0203CF10 = NULL;
+EWRAM_DATA u16 *gUnknown_0203CF14 = NULL;
+
+// iwram
+IWRAM_DATA u16 gUnknown_030012A8[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+
+// text
+void sub_81BEB24(void)
+{
+ u8 i;
+ for(i = 0; i < (sizeof(gUnknown_08617DA4)/sizeof(gUnknown_08617DA4[0])); i++)
+ MapGridSetMetatileIdAt(gUnknown_08617DA4[i].x + 7, gUnknown_08617DA4[i].y + 7, gUnknown_08617DA4[i].tileId);
+ DrawWholeMapView();
+}
+
+void sub_81BEB54(void)
+{
+ CreateTask(sub_81BED50, 0x9);
+}
+
+void sub_81BEB68(void)
+{
+ CreateTask(sub_81BEBF4, 0x9);
+}
+
+void sub_81BEB7C(void)
+{
+ CreateTask(sub_81BF028, 0x9);
+}
+
+void sub_81BEB90(void)
+{
+ SetGpuReg(REG_OFFSET_BG0HOFS, gUnknown_0203CF14[0]);
+ SetGpuReg(REG_OFFSET_BG0VOFS, gUnknown_0203CF14[1]);
+}
+
+void sub_81BEBB4(u8 taskId)
+{
+ if(!(gTasks[taskId].data[0]))
+ {
+ gUnknown_0203CF14[0] = -gUnknown_0203CF14[0];
+ gTasks[taskId].data[0] = 2;
+ sub_81BEB90();
+ }
+ else
+ gTasks[taskId].data[0]--;
+}
+
+static void sub_81BEBF4(u8 taskId)
+{
+ u8 zero;
+
+ switch(gTasks[taskId].data[0])
+ {
+ case 0:
+ FreeAllWindowBuffers();
+ SetBgAttribute(0, BG_CTRL_ATTR_MOSAIC, 2);
+ gTasks[taskId].data[0]++;
+ break;
+ case 1:
+ gUnknown_0203CF04 = (u8 *)AllocZeroed(MIRAGE_TOWER_GFX_LENGTH);
+ gUnknown_0203CF08 = (u8 *)AllocZeroed(MIRAGE_TOWER_PALETTE_LENGTH);
+ ChangeBgX(0, 0, 0);
+ ChangeBgY(0, 0, 0);
+ gTasks[taskId].data[0]++;
+ break;
+ case 2:
+ CpuSet(gUnknown_08617274, gUnknown_0203CF04, MIRAGE_TOWER_GFX_LENGTH / 2);
+ LoadBgTiles(0, gUnknown_0203CF04, MIRAGE_TOWER_GFX_LENGTH, 0);
+ gTasks[taskId].data[0]++;
+ break;
+ case 3:
+ SetBgTilemapBuffer(0, gUnknown_0203CF08);
+ CopyToBgTilemapBufferRect_ChangePalette(0, &gUnknown_08617B94, 12, 29, 6, 12, 17);
+ CopyBgTilemapBufferToVram(0);
+ gTasks[taskId].data[0]++;
+ break;
+ case 4:
+ ShowBg(0);
+ gTasks[taskId].data[0]++;
+ break;
+ case 5:
+ sub_81BEB24();
+ gTasks[taskId].data[0]++;
+ break;
+ case 6:
+ gUnknown_0203CF14 = (u16 *)Alloc(4);
+ zero = 0;
+ gUnknown_0203CF14[0] = 2;
+ gUnknown_0203CF14[1] = zero;
+ CreateTask(sub_81BEBB4, 0xA);
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+ break;
+ }
+}
+
+#ifdef NONMATCHING
+#define OUTER_BUFFER_LENGTH 0x60
+#define INNER_BUFFER_LENGTH 0x30
+static void sub_81BED50(u8 taskId)
+{
+ u8 anotherTaskId, j;
+
+
+ switch(gTasks[taskId].data[0])
+ {
+ case 1:
+ gUnknown_0203CF10 = (struct Struct203CF10 *)AllocZeroed(OUTER_BUFFER_LENGTH * sizeof(struct Struct203CF10));
+ break;
+ case 3:
+ {
+ u16 i;
+ u16 left;
+ u32 index, next;
+
+ index = (u16)gTasks[taskId].data[3];
+ if(gTasks[taskId].data[3] <= (OUTER_BUFFER_LENGTH - 1))
+ {
+ if(gTasks[taskId].data[1] > 1)
+ {
+ index = (u8)index;
+ gUnknown_0203CF10[index].buffer = (u8 *)Alloc(INNER_BUFFER_LENGTH);
+ for(i = 0; i <= (INNER_BUFFER_LENGTH - 1); i++)
+ gUnknown_0203CF10[index].buffer[i] = i;
+ for(i = 0; i <= (INNER_BUFFER_LENGTH - 1); i++)
+ {
+ u16 rand1, rand2, temp;
+
+ rand1 = Random() % 0x30;
+ rand2 = Random() % 0x30;
+ temp = gUnknown_0203CF10[index].buffer[rand2];
+ gUnknown_0203CF10[index].buffer[rand2] = gUnknown_0203CF10[index].buffer[rand1];
+ gUnknown_0203CF10[index].buffer[rand1] = temp;
+ }
+ if(gTasks[taskId].data[3] <= (OUTER_BUFFER_LENGTH - 1))
+ gTasks[taskId].data[3]++;
+ gTasks[taskId].data[1] = 0;
+ }
+ gTasks[taskId].data[1]++;
+ }
+ index = (u8)gTasks[taskId].data[3];
+ for(left = (u8)gTasks[taskId].data[2]; left < (u16)index; left = next)
+ {
+ j = 0;
+ next = left + 1;
+ while(!j)
+ {
+ sub_81BF2B8(gUnknown_0203CF04, ((((OUTER_BUFFER_LENGTH - 1) - left) * INNER_BUFFER_LENGTH) + gUnknown_0203CF10[left].buffer[(gUnknown_0203CF10[left].curr_buffer_index)++]), 0, INNER_BUFFER_LENGTH, 1);
+ j++;
+ }
+ if(gUnknown_0203CF10[left].curr_buffer_index > (INNER_BUFFER_LENGTH - 1))
+ {
+ FREE_AND_SET_NULL(gUnknown_0203CF10[left].buffer);
+ gTasks[taskId].data[2]++;
+ if((left % 2) == 1)
+ gUnknown_0203CF14[1]--;
+ }
+ }
+ LoadBgTiles(0, gUnknown_0203CF04, MIRAGE_TOWER_GFX_LENGTH, 0);
+ if(gUnknown_0203CF10[OUTER_BUFFER_LENGTH - 1].curr_buffer_index > (INNER_BUFFER_LENGTH - 1))
+ break;
+ return;
+ }
+ case 4:
+ UnsetBgTilemapBuffer(0);
+ anotherTaskId = FindTaskIdByFunc(sub_81BEBB4);
+ if(anotherTaskId != 0xFF)
+ DestroyTask(anotherTaskId);
+ gUnknown_0203CF14[1] = gUnknown_0203CF14[0] = 0;
+ sub_81BEB90();
+ break;
+ case 5:
+ FREE_AND_SET_NULL(gUnknown_0203CF14);
+ FREE_AND_SET_NULL(gUnknown_0203CF10);
+ FREE_AND_SET_NULL(gUnknown_0203CF04);
+ FREE_AND_SET_NULL(gUnknown_0203CF08);
+ break;
+ case 6:
+ SetGpuRegBits(REG_OFFSET_BG2CNT, 0x2);
+ SetGpuRegBits(REG_OFFSET_BG0CNT, 0x0);
+ SetBgAttribute(0, BG_CTRL_ATTR_MOSAIC, 0);
+ sub_81971D0();
+ break;
+ case 7:
+ ShowBg(0);
+ break;
+ case 8:
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+ break;
+ }
+ gTasks[taskId].data[0]++;
+}
+
+#else
+NAKED
+static void sub_81BED50(u8 taskId)
+{
+ asm("\n\
+ .syntax unified\n\
+ push {r4-r7,lr}\n\
+ mov r7, r10\n\
+ mov r6, r9\n\
+ mov r5, r8\n\
+ push {r5-r7}\n\
+ sub sp, 0x10\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ mov r10, r0\n\
+ ldr r1, =gTasks\n\
+ lsls r0, 2\n\
+ add r0, r10\n\
+ lsls r0, 3\n\
+ adds r0, r1\n\
+ ldrh r0, [r0, 0x8]\n\
+ subs r0, 0x1\n\
+ lsls r0, 16\n\
+ asrs r0, 16\n\
+ adds r6, r1, 0\n\
+ cmp r0, 0x7\n\
+ bls _081BED7C\n\
+ b _081BF002\n\
+ _081BED7C:\n\
+ lsls r0, 2\n\
+ ldr r1, =_081BED90\n\
+ adds r0, r1\n\
+ ldr r0, [r0]\n\
+ mov pc, r0\n\
+ .pool\n\
+ .align 2, 0\n\
+ _081BED90:\n\
+ .4byte _081BEDB0\n\
+ .4byte _081BF002\n\
+ .4byte _081BEDC4\n\
+ .4byte _081BEF64\n\
+ .4byte _081BEF94\n\
+ .4byte _081BEFD0\n\
+ .4byte _081BEFF0\n\
+ .4byte _081BEFF8\n\
+ _081BEDB0:\n\
+ ldr r4, =gUnknown_0203CF10\n\
+ movs r0, 0xC0\n\
+ lsls r0, 2\n\
+ bl AllocZeroed\n\
+ str r0, [r4]\n\
+ b _081BF002\n\
+ .pool\n\
+ _081BEDC4:\n\
+ mov r1, r10\n\
+ lsls r0, r1, 2\n\
+ adds r1, r0, r1\n\
+ lsls r1, 3\n\
+ adds r2, r1, r6\n\
+ ldrh r3, [r2, 0xE]\n\
+ movs r4, 0xE\n\
+ ldrsh r1, [r2, r4]\n\
+ str r0, [sp, 0x8]\n\
+ cmp r1, 0x5F\n\
+ bgt _081BEE8A\n\
+ movs r1, 0xA\n\
+ ldrsh r0, [r2, r1]\n\
+ cmp r0, 0x1\n\
+ ble _081BEE7C\n\
+ lsls r0, r3, 24\n\
+ lsrs r4, r0, 24\n\
+ movs r0, 0x30\n\
+ bl Alloc\n\
+ ldr r3, =gUnknown_0203CF10\n\
+ ldr r1, [r3]\n\
+ lsls r2, r4, 3\n\
+ adds r1, r2, r1\n\
+ str r0, [r1]\n\
+ movs r5, 0\n\
+ adds r4, r2, 0\n\
+ _081BEDFA:\n\
+ ldr r0, [r3]\n\
+ adds r0, r4, r0\n\
+ ldr r0, [r0]\n\
+ adds r0, r5\n\
+ strb r5, [r0]\n\
+ adds r0, r5, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r5, r0, 16\n\
+ cmp r5, 0x2F\n\
+ bls _081BEDFA\n\
+ movs r5, 0\n\
+ ldr r7, =gUnknown_0203CF10\n\
+ adds r6, r2, 0\n\
+ _081BEE14:\n\
+ bl Random\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ movs r1, 0x30\n\
+ bl __umodsi3\n\
+ adds r4, r0, 0\n\
+ lsls r4, 16\n\
+ lsrs r4, 16\n\
+ bl Random\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ movs r1, 0x30\n\
+ bl __umodsi3\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ ldr r1, [r7]\n\
+ adds r1, r6, r1\n\
+ ldr r1, [r1]\n\
+ adds r0, r1, r0\n\
+ ldrb r2, [r0]\n\
+ adds r1, r4 \n\
+ ldrb r1, [r1]\n\
+ strb r1, [r0]\n\
+ ldr r0, [r7]\n\
+ adds r0, r6, r0\n\
+ ldr r0, [r0]\n\
+ adds r0, r4\n\
+ strb r2, [r0]\n\
+ adds r0, r5, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r5, r0, 16\n\
+ cmp r5, 0x2F\n\
+ bls _081BEE14\n\
+ ldr r0, =gTasks\n\
+ ldr r1, [sp, 0x8]\n\
+ add r1, r10\n\
+ lsls r1, 3\n\
+ adds r2, r1, r0\n\
+ ldrh r3, [r2, 0xE]\n\
+ movs r4, 0xE\n\
+ ldrsh r1, [r2, r4]\n\
+ adds r6, r0, 0\n\
+ cmp r1, 0x5F\n\
+ bgt _081BEE78\n\
+ adds r0, r3, 0x1\n\
+ strh r0, [r2, 0xE]\n\
+ _081BEE78:\n\
+ movs r0, 0\n\
+ strh r0, [r2, 0xA]\n\
+ _081BEE7C:\n\
+ ldr r1, [sp, 0x8]\n\
+ add r1, r10\n\
+ lsls r1, 3\n\
+ adds r1, r6\n\
+ ldrh r0, [r1, 0xA]\n\
+ adds r0, 0x1\n\
+ strh r0, [r1, 0xA]\n\
+ _081BEE8A:\n\
+ ldr r0, [sp, 0x8]\n\
+ add r0, r10\n\
+ lsls r0, 3\n\
+ adds r0, r6\n\
+ ldrb r4, [r0, 0xE]\n\
+ ldrb r5, [r0, 0xC]\n\
+ lsls r0, r4, 16\n\
+ cmp r5, r4\n\
+ bcs _081BEF32\n\
+ str r0, [sp, 0xC]\n\
+ _081BEE9E:\n\
+ movs r6, 0\n\
+ adds r0, r5, 0x1\n\
+ str r0, [sp, 0x4]\n\
+ lsls r4, r5, 3\n\
+ movs r2, 0x5F\n\
+ subs r1, r2, r5\n\
+ lsls r0, r1, 1\n\
+ adds r0, r1\n\
+ lsls r0, 4\n\
+ mov r9, r0\n\
+ _081BEEB2:\n\
+ ldr r0, =gUnknown_0203CF04\n\
+ ldr r0, [r0]\n\
+ ldr r7, =gUnknown_0203CF10\n\
+ ldr r3, [r7]\n\
+ adds r3, r4, r3\n\
+ ldrb r2, [r3, 0x4]\n\
+ adds r1, r2, 0x1\n\
+ strb r1, [r3, 0x4]\n\
+ lsls r2, 24\n\
+ lsrs r2, 24\n\
+ ldr r1, [r3]\n\
+ adds r1, r2\n\
+ ldrb r1, [r1]\n\
+ add r1, r9\n\
+ lsls r1, 16\n\
+ lsrs r1, 16\n\
+ movs r2, 0x1\n\
+ mov r8, r2\n\
+ str r2, [sp]\n\
+ movs r2, 0\n\
+ movs r3, 0x30\n\
+ bl sub_81BF2B8\n\
+ adds r0, r6, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r6, r0, 24\n\
+ cmp r6, 0\n\
+ beq _081BEEB2\n\
+ ldr r0, [r7]\n\
+ adds r1, r4, r0\n\
+ ldrb r0, [r1, 0x4]\n\
+ cmp r0, 0x2F\n\
+ bls _081BEF24\n\
+ ldr r0, [r1]\n\
+ bl Free\n\
+ ldr r0, [r7]\n\
+ adds r0, r4, r0\n\
+ movs r1, 0\n\
+ str r1, [r0]\n\
+ ldr r1, [sp, 0x8]\n\
+ add r1, r10\n\
+ lsls r1, 3\n\
+ ldr r4, =gTasks\n\
+ adds r1, r4\n\
+ ldrh r0, [r1, 0xC]\n\
+ adds r0, 0x1\n\
+ strh r0, [r1, 0xC]\n\
+ mov r0, r8\n\
+ ands r5, r0\n\
+ cmp r5, 0x1\n\
+ bne _081BEF24\n\
+ ldr r0, =gUnknown_0203CF14\n\
+ ldr r1, [r0]\n\
+ ldrh r0, [r1, 0x2]\n\
+ subs r0, 0x1\n\
+ strh r0, [r1, 0x2]\n\
+ _081BEF24:\n\
+ ldr r1, [sp, 0x4]\n\
+ lsls r0, r1, 16\n\
+ lsrs r5, r0, 16\n\
+ ldr r2, [sp, 0xC]\n\
+ lsrs r0, r2, 16\n\
+ cmp r5, r0\n\
+ bcc _081BEE9E\n\
+ _081BEF32:\n\
+ ldr r0, =gUnknown_0203CF04\n\
+ ldr r1, [r0]\n\
+ movs r2, 0x92\n\
+ lsls r2, 4\n\
+ movs r0, 0\n\
+ movs r3, 0\n\
+ bl LoadBgTiles\n\
+ ldr r0, =gUnknown_0203CF10\n\
+ ldr r0, [r0]\n\
+ movs r4, 0xBE\n\
+ lsls r4, 2\n\
+ adds r0, r4\n\
+ ldrb r0, [r0, 0x4]\n\
+ cmp r0, 0x2F\n\
+ bhi _081BF002\n\
+ b _081BF014\n\
+ .pool\n\
+ _081BEF64:\n\
+ movs r0, 0\n\
+ bl UnsetBgTilemapBuffer\n\
+ ldr r0, =sub_81BEBB4\n\
+ bl FindTaskIdByFunc\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ cmp r0, 0xFF\n\
+ beq _081BEF7C\n\
+ bl DestroyTask\n\
+ _081BEF7C:\n\
+ ldr r0, =gUnknown_0203CF14\n\
+ ldr r1, [r0]\n\
+ movs r0, 0\n\
+ strh r0, [r1]\n\
+ strh r0, [r1, 0x2]\n\
+ bl sub_81BEB90\n\
+ b _081BF002\n\
+ .pool\n\
+ _081BEF94:\n\
+ ldr r4, =gUnknown_0203CF14\n\
+ ldr r0, [r4]\n\
+ bl Free\n\
+ movs r5, 0\n\
+ str r5, [r4]\n\
+ ldr r4, =gUnknown_0203CF10\n\
+ ldr r0, [r4]\n\
+ bl Free\n\
+ str r5, [r4]\n\
+ ldr r4, =gUnknown_0203CF04\n\
+ ldr r0, [r4]\n\
+ bl Free\n\
+ str r5, [r4]\n\
+ ldr r4, =gUnknown_0203CF08\n\
+ ldr r0, [r4]\n\
+ bl Free\n\
+ str r5, [r4]\n\
+ b _081BF002\n\
+ .pool\n\
+ _081BEFD0:\n\
+ movs r0, 0xC\n\
+ movs r1, 0x2\n\
+ bl SetGpuRegBits\n\
+ movs r0, 0x8\n\
+ movs r1, 0\n\
+ bl SetGpuRegBits\n\
+ movs r0, 0\n\
+ movs r1, 0x7\n\
+ movs r2, 0\n\
+ bl SetBgAttribute\n\
+ bl sub_81971D0\n\
+ b _081BF002\n\
+ _081BEFF0:\n\
+ movs r0, 0\n\
+ bl ShowBg\n\
+ b _081BF002\n\
+ _081BEFF8:\n\
+ mov r0, r10\n\
+ bl DestroyTask\n\
+ bl EnableBothScriptContexts\n\
+ _081BF002:\n\
+ ldr r0, =gTasks\n\
+ mov r2, r10\n\
+ lsls r1, r2, 2\n\
+ add r1, r10\n\
+ lsls r1, 3\n\
+ adds r1, r0\n\
+ ldrh r0, [r1, 0x8]\n\
+ adds r0, 0x1\n\
+ strh r0, [r1, 0x8]\n\
+ _081BF014:\n\
+ add sp, 0x10\n\
+ pop {r3-r5}\n\
+ mov r8, r3\n\
+ mov r9, r4\n\
+ mov r10, r5\n\
+ pop {r4-r7}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .pool\n\
+ .syntax divided");
+}
+#endif // NONMATCHING
+
+static void sub_81BF028(u8 taskId)
+{
+ u16 i;
+
+ switch(gTasks[taskId].data[0])
+ {
+ case 1:
+ gUnknown_0203CF0C = (struct Struct203CF0C *)AllocZeroed(sizeof(struct Struct203CF0C));
+ gUnknown_0203CF0C->frameImageTiles = (u8 *)AllocZeroed(ROOT_FOSSIL_GFX_LENGTH);
+ gUnknown_0203CF0C->frameImage = (struct DynamicSpriteFrameImage *) AllocZeroed(sizeof(struct DynamicSpriteFrameImage));
+ gUnknown_0203CF0C->unkC = (u16 *)AllocZeroed(ROOT_FOSSIL_GFX_RANDOMIZER_LENGTH * sizeof(u16));
+ gUnknown_0203CF0C->unk10 = 0;
+ break;
+ case 2:
+ {
+ u8 *buffer;
+ buffer = gUnknown_0203CF0C->frameImageTiles;
+ for(i = 0; i < ROOT_FOSSIL_GFX_LENGTH; i++, buffer++)
+ *buffer = gRootFossil_Gfx[i];
+ }
+ break;
+ case 3:
+ gUnknown_0203CF0C->frameImage->data = gUnknown_0203CF0C->frameImageTiles;
+ gUnknown_0203CF0C->frameImage->size = ROOT_FOSSIL_GFX_LENGTH;
+ break;
+ case 4:
+ {
+ u8 spriteId, zero;
+ struct SpriteTemplate fossilTemplate;
+
+ fossilTemplate = gUnknown_08617E00;
+ fossilTemplate.images = (struct SpriteFrameImage *)(gUnknown_0203CF0C->frameImage);
+ spriteId = CreateSprite(&fossilTemplate, 128, -16, 1);
+ gUnknown_0203CF0C->spriteId = spriteId;
+ zero = 0;
+ gSprites[gUnknown_0203CF0C->spriteId].centerToCornerVecX = zero;
+ gSprites[gUnknown_0203CF0C->spriteId].data[0] = gSprites[gUnknown_0203CF0C->spriteId].pos1.x;
+ gSprites[gUnknown_0203CF0C->spriteId].data[1] = 1;
+ }
+ case 5:
+ for(i = 0; i < ROOT_FOSSIL_GFX_RANDOMIZER_LENGTH; i++)
+ gUnknown_0203CF0C->unkC[i] = i;
+ break;
+ case 6:
+ {
+ u16 rand1, rand2, temp, j;
+ j = (ROOT_FOSSIL_GFX_RANDOMIZER_LENGTH * sizeof(u16)) - 1;
+ for(i = 0; i <= j; i++)
+ {
+ rand1 = Random() % 0x100;
+ rand2 = Random() % 0x100;
+ j = (ROOT_FOSSIL_GFX_RANDOMIZER_LENGTH * sizeof(u16)) - 1;
+ temp = gUnknown_0203CF0C->unkC[rand2];
+ gUnknown_0203CF0C->unkC[rand2] = gUnknown_0203CF0C->unkC[rand1];
+ gUnknown_0203CF0C->unkC[rand1] = temp;
+ }
+ gSprites[gUnknown_0203CF0C->spriteId].callback = sub_81BF248;
+ break;
+ }
+ case 7:
+ if(gSprites[gUnknown_0203CF0C->spriteId].callback != SpriteCallbackDummy)
+ return;
+ DestroySprite(&gSprites[gUnknown_0203CF0C->spriteId]);
+ FREE_AND_SET_NULL(gUnknown_0203CF0C->unkC);;
+ FREE_AND_SET_NULL(gUnknown_0203CF0C->frameImage);
+ FREE_AND_SET_NULL(gUnknown_0203CF0C->frameImageTiles);
+ FREE_AND_SET_NULL(gUnknown_0203CF0C);
+ break;
+ case 8:
+ EnableBothScriptContexts();
+ }
+ ++gTasks[taskId].data[0];
+}
+
+static void sub_81BF248(struct Sprite *sprite)
+{
+ if (gUnknown_0203CF0C->unk10 >= (ROOT_FOSSIL_GFX_RANDOMIZER_LENGTH))
+ {
+ sprite->callback = SpriteCallbackDummy;
+ }
+ else if (sprite->pos1.y >= 0x60)
+ {
+ u8 i;
+ for (i = 0; i < 2; i++)
+ {
+ sub_81BF2B8(gUnknown_0203CF0C->frameImageTiles, gUnknown_0203CF0C->unkC[gUnknown_0203CF0C->unk10++], 0, 16, 0);
+ }
+ StartSpriteAnim(sprite, 0);
+ }
+ else
+ {
+ sprite->pos1.y++;
+ }
+}
diff --git a/src/gym_leader_rematch.c b/src/gym_leader_rematch.c
new file mode 100644
index 000000000..355ae5534
--- /dev/null
+++ b/src/gym_leader_rematch.c
@@ -0,0 +1,106 @@
+#include "global.h"
+#include "constants/flags.h"
+#include "random.h"
+#include "event_data.h"
+#include "battle_setup.h"
+#include "gym_leader_rematch.h"
+
+static void UpdateGymLeaderRematchFromArray(const u16 *data, size_t size, u32 maxRematch);
+static s32 GetRematchIndex(u32 trainerIdx);
+
+static const u16 GymLeaderRematches_AfterNewMauville[] = {
+ REMATCH_ROXANNE,
+ REMATCH_BRAWLY,
+ REMATCH_WATTSON,
+ REMATCH_FLANNERY,
+ REMATCH_NORMAN,
+ REMATCH_WINONA,
+ REMATCH_TATE_AND_LIZA,
+ REMATCH_JUAN
+};
+
+static const u16 GymLeaderRematches_BeforeNewMauville[] = {
+ REMATCH_ROXANNE,
+ REMATCH_BRAWLY,
+ // Wattson isn't available at this time
+ REMATCH_FLANNERY,
+ REMATCH_NORMAN,
+ REMATCH_WINONA,
+ REMATCH_TATE_AND_LIZA,
+ REMATCH_JUAN
+};
+
+void UpdateGymLeaderRematch(void)
+{
+ if (FlagGet(FLAG_SYS_GAME_CLEAR) && (Random() % 100) <= 30)
+ {
+ if (FlagGet(FLAG_WATTSON_REMATCH_AVAILABLE))
+ UpdateGymLeaderRematchFromArray(GymLeaderRematches_AfterNewMauville, ARRAY_COUNT(GymLeaderRematches_AfterNewMauville), 5);
+ else
+ UpdateGymLeaderRematchFromArray(GymLeaderRematches_BeforeNewMauville, ARRAY_COUNT(GymLeaderRematches_BeforeNewMauville), 1);
+ }
+}
+
+static void UpdateGymLeaderRematchFromArray(const u16 *data, size_t size, u32 maxRematch)
+{
+ s32 whichLeader = 0;
+ s32 lowestRematchIndex = 5;
+ u32 i;
+ s32 rematchIndex;
+ for (i = 0; i < size; i++)
+ {
+ if (!gSaveBlock1Ptr->trainerRematches[data[i]])
+ {
+ rematchIndex = GetRematchIndex(data[i]);
+ if (lowestRematchIndex > rematchIndex)
+ lowestRematchIndex = rematchIndex;
+ whichLeader++;
+ }
+ }
+ if (whichLeader != 0 && lowestRematchIndex <= maxRematch)
+ {
+ whichLeader = 0;
+ for (i = 0; i < size; i++)
+ {
+ if (!gSaveBlock1Ptr->trainerRematches[data[i]])
+ {
+ rematchIndex = GetRematchIndex(data[i]);
+ if (rematchIndex == lowestRematchIndex)
+ whichLeader++;
+ }
+ }
+ if (whichLeader != 0)
+ {
+ whichLeader = Random() % whichLeader;
+ for (i = 0; i < size; i++)
+ {
+ if (!gSaveBlock1Ptr->trainerRematches[data[i]])
+ {
+ rematchIndex = GetRematchIndex(data[i]);
+ if (rematchIndex == lowestRematchIndex)
+ {
+ if (whichLeader == 0)
+ {
+ gSaveBlock1Ptr->trainerRematches[data[i]] = lowestRematchIndex;
+ break;
+ }
+ whichLeader--;
+ }
+ }
+ }
+ }
+ }
+}
+
+static s32 GetRematchIndex(u32 trainerIdx)
+{
+ s32 i;
+ for (i = 0; i < 5; i++)
+ {
+ if (!HasTrainerBeenFought(gRematchTable[trainerIdx].trainerIds[i]))
+ {
+ return i;
+ }
+ }
+ return 5;
+}
diff --git a/src/hall_of_fame.c b/src/hall_of_fame.c
index 6dda6ad9c..83df30d05 100644
--- a/src/hall_of_fame.c
+++ b/src/hall_of_fame.c
@@ -369,7 +369,7 @@ static const struct HallofFameMon sDummyFameMon =
0x3EA03EA, 0, 0, 0, {0}
};
-static const u8 sUnused2[6] = {2, 1, 3, 6, 4, 5};
+static const u8 sUnused2[] = {2, 1, 3, 6, 4, 5, 0, 0};
// code
static void VBlankCB_HallOfFame(void)
@@ -516,7 +516,7 @@ static void Task_Hof_InitTeamSaveData(u8 taskId)
}
else
{
- if (sub_81534D0(3) != TRUE)
+ if (Save_LoadGameData(3) != TRUE)
memset(gDecompressionBuffer, 0, 0x2000);
}
@@ -885,7 +885,7 @@ void CB2_DoHallOfFamePC(void)
static void Task_HofPC_CopySaveData(u8 taskId)
{
sub_81980F0(0, 0x1E, 0, 0xC, 0x226);
- if (sub_81534D0(3) != 1)
+ if (Save_LoadGameData(3) != 1)
{
gTasks[taskId].func = Task_HofPC_PrintDataIsCorrupted;
}
diff --git a/src/hof_pc.c b/src/hof_pc.c
index e772f04e8..44b929337 100644
--- a/src/hof_pc.c
+++ b/src/hof_pc.c
@@ -7,7 +7,6 @@
#include "script_menu.h"
#include "task.h"
-extern void (*gFieldCallback)(void);
extern void (*gUnknown_0300485C)(void);
extern void Overworld_PlaySpecialMapMusic(void);
@@ -25,7 +24,7 @@ void AccessHallOfFamePC(void)
void ReturnFromHallOfFamePC(void)
{
- SetMainCallback2(c2_exit_to_overworld_2_switch);
+ SetMainCallback2(CB2_ReturnToField);
gFieldCallback = ReshowPCMenuAfterHallOfFamePC;
}
diff --git a/src/international_string_util.c b/src/international_string_util.c
index 89b4a7a69..9de338c59 100644
--- a/src/international_string_util.c
+++ b/src/international_string_util.c
@@ -42,7 +42,7 @@ s32 GetMaxWidthInMenuTable(const struct MenuAction *str, s32 arg1)
return convert_pixel_width_to_tile_width(var);
}
-s32 sub_81DB3D8(const struct MenuAction *str, u8* arg1, s32 arg2)
+s32 sub_81DB3D8(const struct MenuAction *str, const u8* arg1, s32 arg2)
{
s32 i, var;
diff --git a/src/intro.c b/src/intro.c
new file mode 100644
index 000000000..f21ad348d
--- /dev/null
+++ b/src/intro.c
@@ -0,0 +1,3020 @@
+#include "global.h"
+#include "main.h"
+#include "palette.h"
+#include "scanline_effect.h"
+#include "task.h"
+#include "title_screen.h"
+#include "libgcnmultiboot.h"
+#include "malloc.h"
+#include "gpu_regs.h"
+#include "link.h"
+#include "multiboot_pokemon_colosseum.h"
+#include "load_save.h"
+#include "save.h"
+#include "new_game.h"
+#include "m4a.h"
+#include "random.h"
+#include "decompress.h"
+#include "constants/songs.h"
+#include "intro_credits_graphics.h"
+#include "trig.h"
+#include "intro.h"
+#include "graphics.h"
+#include "sound.h"
+#include "constants/species.h"
+#include "blend_palette.h"
+#include "title_screen.h"
+#include "constants/rgb.h"
+
+extern const struct CompressedSpriteSheet gBattleAnimPicTable[];
+extern const struct CompressedSpritePalette gBattleAnimPaletteTable[];
+extern const struct SpriteTemplate gUnknown_08596C10[];
+
+//ewram
+EWRAM_DATA u16 gUnknown_0203BCC8 = 0;
+EWRAM_DATA u16 gUnknown_0203BCCA = 0;
+EWRAM_DATA u16 gUnknown_0203BCCC = 0;
+
+//iwram
+u32 gIntroFrameCounter;
+struct GcmbStruct gMultibootProgramStruct;
+
+//.rodata
+static const u16 gIntro1DropsPal[] = INCBIN_U16("graphics/intro/intro1_drops.gbapal");
+static const u16 gIntro1GFLogoPal[] = INCBIN_U16("graphics/intro/intro1_gflogo.gbapal");
+static const u8 gIntroTiles[] = INCBIN_U8("graphics/intro/intro.4bpp.lz");
+static const u16 gIntro1BGPals[16][16] = INCBIN_U16("graphics/intro/intro1_bgpal.gbapal");
+static const u8 gIntro1BG0_Tilemap[] = INCBIN_U8("graphics/intro/intro1_bg0_map.bin.lz");
+static const u8 gIntro1BG1_Tilemap[] = INCBIN_U8("graphics/intro/intro1_bg1_map.bin.lz");
+static const u8 gIntro1BG2_Tilemap[] = INCBIN_U8("graphics/intro/intro1_bg2_map.bin.lz");
+static const u8 gIntro1BG3_Tilemap[] = INCBIN_U8("graphics/intro/intro1_bg3_map.bin.lz");
+static const u8 gIntro1BGLeavesGfx[] = INCBIN_U8("graphics/intro/introgfx.4bpp.lz");
+static const u16 gIntro3PokeballPal[] = INCBIN_U16("graphics/intro/intro3_pokeball.gbapal");
+static const u8 gIntro3Pokeball_Tilemap[] = INCBIN_U8("graphics/intro/intro3_pokeball_map.bin.lz");
+static const u8 gIntro3Pokeball_Gfx[] = INCBIN_U8("graphics/intro/intro3_pokeball.8bpp.lz");
+static const u16 gIntro3Streaks_Pal_Unused[] = INCBIN_U16("graphics/intro/intro3_streaks.gbapal");
+static const u8 gIntro3Streaks_Gfx_Unused[] = INCBIN_U8("graphics/intro/intro3_streaks.4bpp.lz");
+static const u8 gIntro3Streaks_Tilemap_Unused[] = INCBIN_U8("graphics/intro/intro3_streaks_map.bin.lz");
+static const u16 gIntro3Misc1Palette[] = INCBIN_U16("graphics/intro/intro3_misc1.gbapal");
+static const u16 gIntro3Misc2Palette_Unused[] = INCBIN_U16("graphics/intro/intro3_misc2.gbapal");
+static const u8 gIntro3MiscTiles[] = INCBIN_U8("graphics/intro/intro3_misc.4bpp.lz");
+static const u16 gIntro1FlygonPalette[] = INCBIN_U16("graphics/intro/intro1_flygon.gbapal");
+static const u8 gIntro1EonTiles_Unused[] = INCBIN_U8("graphics/intro/intro1_eon.4bpp.lz");
+static const u8 sUnknownBytes[] = {
+ 0x02, 0x03, 0x04, 0x05, 0x01, 0x01, 0x01, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x02, 0x0D,
+ 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x02, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x02, 0x0D, 0x0E, 0x0F, 0x10,
+ 0x11, 0x12, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x00
+};
+static const struct CompressedSpriteSheet gUnknown_085E4A74[] =
+{
+ {gIntro1SparkleGfx, 0x400, 1505},
+ {NULL},
+};
+static const struct SpritePalette gUnknown_085E4A84[] =
+{
+ {gIntro3LightningPal, 1505},
+ {NULL},
+};
+static const struct OamData gUnknown_085E4A94 =
+{
+ .y = 160,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 1,
+ .tileNum = 0,
+ .priority = 1,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+static const union AnimCmd gUnknown_085E4A9C[] =
+{
+ ANIMCMD_FRAME(0, 2),
+ ANIMCMD_FRAME(4, 2),
+ ANIMCMD_FRAME(8, 2),
+ ANIMCMD_FRAME(12, 2),
+ ANIMCMD_FRAME(16, 2),
+ ANIMCMD_JUMP(0),
+};
+static const union AnimCmd *const gUnknown_085E4AB4[] =
+{
+ gUnknown_085E4A9C,
+};
+static void sub_816D338(struct Sprite *sprite);
+static const struct SpriteTemplate gUnknown_085E4AB8 =
+{
+ .tileTag = 1505,
+ .paletteTag = 1505,
+ .oam = &gUnknown_085E4A94,
+ .anims = gUnknown_085E4AB4,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_816D338,
+};
+static const u8 gUnknown_085E4AD0[][2] =
+{
+ {0x7C, 0x28},
+ {0x66, 0x1E},
+ {0x4D, 0x1E},
+ {0x36, 0x0F},
+ {0x94, 0x09},
+ {0x3F, 0x1C},
+ {0x5D, 0x28},
+ {0x94, 0x20},
+ {0xAD, 0x29},
+ {0x5E, 0x14},
+ {0xD0, 0x26},
+ {0x00, 0x00},
+};
+static const struct CompressedSpriteSheet gUnknown_085E4AE8[] =
+{
+ {gIntro2VolbeatGfx, 0x400, 1500},
+ {gIntro2TorchicGfx, 0xC00, 1501},
+ {gIntro2ManectricGfx, 0x2000, 1502},
+ {NULL},
+};
+static const struct SpritePalette gUnknown_085E4B08[] =
+{
+ {gIntro2VolbeatPal, 1500},
+ {gIntro2TorchicPal, 1501},
+ {gIntro2ManectricPal, 1502},
+ {NULL},
+};
+static const struct OamData gUnknown_085E4B28 =
+{
+ .y = 160,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 2,
+ .tileNum = 0,
+ .priority = 1,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+static const union AnimCmd gUnknown_085E4B30[] =
+{
+ ANIMCMD_FRAME(0, 2),
+ ANIMCMD_FRAME(16, 2),
+ ANIMCMD_JUMP(0),
+};
+static const union AnimCmd *const gUnknown_085E4B3C[] =
+{
+ gUnknown_085E4B30,
+};
+static void sub_816D81C(struct Sprite *sprite);
+static const struct SpriteTemplate gUnknown_085E4B40 =
+{
+ .tileTag = 1500,
+ .paletteTag = 1500,
+ .oam = &gUnknown_085E4B28,
+ .anims = gUnknown_085E4B3C,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_816D81C,
+};
+static const struct OamData gUnknown_085E4B58 =
+{
+ .y = 160,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 2,
+ .tileNum = 0,
+ .priority = 1,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+static const union AnimCmd gUnknown_085E4B60[] =
+{
+ ANIMCMD_FRAME(0, 5),
+ ANIMCMD_FRAME(16, 5),
+ ANIMCMD_FRAME(32, 5),
+ ANIMCMD_FRAME(16, 5),
+ ANIMCMD_JUMP(0),
+};
+static const union AnimCmd gUnknown_085E4B74[] =
+{
+ ANIMCMD_FRAME(0, 3),
+ ANIMCMD_FRAME(16, 3),
+ ANIMCMD_FRAME(32, 3),
+ ANIMCMD_FRAME(16, 3),
+ ANIMCMD_JUMP(0),
+};
+static const union AnimCmd gUnknown_085E4B88[] =
+{
+ ANIMCMD_FRAME(48, 4),
+ ANIMCMD_FRAME(64, 6),
+ ANIMCMD_FRAME(80, 0),
+ ANIMCMD_END,
+};
+static const union AnimCmd *const gUnknown_085E4B98[] =
+{
+ gUnknown_085E4B60,
+ gUnknown_085E4B74,
+ gUnknown_085E4B88,
+};
+static void sub_816D9C0(struct Sprite *sprite);
+static const struct SpriteTemplate gUnknown_085E4BA4 =
+{
+ .tileTag = 1501,
+ .paletteTag = 1501,
+ .oam = &gUnknown_085E4B58,
+ .anims = gUnknown_085E4B98,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_816D9C0,
+};
+static const struct OamData gUnknown_085E4BBC =
+{
+ .y = 160,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 3,
+ .tileNum = 0,
+ .priority = 1,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+static const union AnimCmd gUnknown_085E4BC4[] =
+{
+ ANIMCMD_FRAME(0, 4),
+ ANIMCMD_FRAME(64, 4),
+ ANIMCMD_FRAME(128, 4),
+ ANIMCMD_FRAME(192, 4),
+ ANIMCMD_JUMP(0),
+};
+static const union AnimCmd *const gUnknown_085E4BD8[] =
+{
+ gUnknown_085E4BC4,
+};
+static void sub_816DAE8(struct Sprite *sprite);
+static const struct SpriteTemplate gUnknown_085E4BDC =
+{
+ .tileTag = 1502,
+ .paletteTag = 1502,
+ .oam = &gUnknown_085E4BBC,
+ .anims = gUnknown_085E4BD8,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_816DAE8,
+};
+static const struct CompressedSpriteSheet gUnknown_085E4BF4[] =
+{
+ {gIntro3LightningGfx, 0xC00, 1503},
+ {NULL},
+};
+static const struct SpritePalette gUnknown_085E4C04[] =
+{
+ {gIntro3LightningPal, 1503},
+ {NULL},
+};
+static const struct OamData gUnknown_085E4C14 =
+{
+ .y = 160,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 2,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+static const union AnimCmd gUnknown_085E4C1C[] =
+{
+ ANIMCMD_FRAME(0, 2),
+ ANIMCMD_FRAME(48, 2),
+ ANIMCMD_END,
+};
+static const union AnimCmd gUnknown_085E4C28[] =
+{
+ ANIMCMD_FRAME(16, 2),
+ ANIMCMD_FRAME(64, 2),
+ ANIMCMD_END,
+};
+static const union AnimCmd gUnknown_085E4C34[] =
+{
+ ANIMCMD_FRAME(32, 2),
+ ANIMCMD_FRAME(80, 2),
+ ANIMCMD_END,
+};
+static const union AnimCmd *const gUnknown_085E4C40[] =
+{
+ gUnknown_085E4C1C,
+ gUnknown_085E4C28,
+ gUnknown_085E4C34,
+};
+static void sub_816EC6C(struct Sprite *sprite);
+static const struct SpriteTemplate gUnknown_085E4C4C =
+{
+ .tileTag = 1503,
+ .paletteTag = 1503,
+ .oam = &gUnknown_085E4C14,
+ .anims = gUnknown_085E4C40,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_816EC6C,
+};
+static const s16 gUnknown_085E4C64[][3] =
+{
+ {0x68, 0x00, 0x0C0},
+ {0x8E, 0x03, 0x280},
+ {0x53, 0x01, 0x180},
+ {0x9B, 0x00, 0x080},
+ {0x38, 0x02, 0x200},
+ {0xAE, 0x01, 0x100},
+};
+static const struct CompressedSpriteSheet gUnknown_085E4C88[] =
+{
+ {gIntro2BubblesGfx, 0x600, 1504},
+ {NULL},
+};
+static const struct SpritePalette gUnknown_085E4C98[] =
+{
+ {gIntro2BubblesPal, 1504},
+ {NULL},
+};
+static const s16 gUnknown_085E4CA8[][3] =
+{
+ {0x42, 0x40, 0x1},
+ {0x60, 0x60, 0x8},
+ {0x80, 0x40, 0x1},
+ {0x90, 0x30, 0x8},
+ {0xA0, 0x48, 0x1},
+ {0xB0, 0x60, 0x8},
+ {0x60, 0x60, 0x4},
+ {0x70, 0x68, 0x8},
+ {0x80, 0x60, 0x4},
+ {0x58, 0x20, 0x4},
+ {0x68, 0x18, 0x8},
+ {0x78, 0x20, 0x4},
+};
+static const struct OamData gUnknown_085E4CF0 =
+{
+ .y = 160,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 2,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 2,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+static const union AnimCmd gUnknown_085E4CF8[] =
+{
+ ANIMCMD_FRAME(0, 4),
+ ANIMCMD_FRAME(8, 4),
+ ANIMCMD_FRAME(16, 4),
+ ANIMCMD_FRAME(24, 4),
+ ANIMCMD_FRAME(32, 4),
+ ANIMCMD_END,
+};
+static const union AnimCmd *const gUnknown_085E4D10[] =
+{
+ gUnknown_085E4CF8,
+};
+static void sub_816E7B4(struct Sprite *sprite);
+static const struct SpriteTemplate gUnknown_085E4D14 =
+{
+ .tileTag = 1504,
+ .paletteTag = 1504,
+ .oam = &gUnknown_085E4CF0,
+ .anims = gUnknown_085E4D10,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_816E7B4,
+};
+static const struct OamData gUnknown_085E4D2C =
+{
+ .y = 160,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 2,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+static const union AnimCmd gUnknown_085E4D34[] =
+{
+ ANIMCMD_FRAME(16, 8),
+ ANIMCMD_END,
+};
+static const union AnimCmd gUnknown_085E4D3C[] =
+{
+ ANIMCMD_FRAME(24, 8),
+ ANIMCMD_END,
+};
+static const union AnimCmd gUnknown_085E4D44[] =
+{
+ ANIMCMD_FRAME(0, 8),
+ ANIMCMD_END,
+};
+static const union AnimCmd gUnknown_085E4D4C[] =
+{
+ ANIMCMD_FRAME(48, 8),
+ ANIMCMD_END,
+};
+static const union AnimCmd *const gUnknown_085E4D54[] =
+{
+ gUnknown_085E4D34,
+ gUnknown_085E4D3C,
+ gUnknown_085E4D44,
+ gUnknown_085E4D4C,
+};
+static void sub_816F454(struct Sprite *sprite);
+static const struct SpriteTemplate gUnknown_085E4D64 =
+{
+ .tileTag = 2000,
+ .paletteTag = 2000,
+ .oam = &gUnknown_085E4D2C,
+ .anims = gUnknown_085E4D54,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_816F454,
+};
+static const union AnimCmd gUnknown_085E4D7C[] =
+{
+ ANIMCMD_FRAME(0, 4),
+ ANIMCMD_FRAME(64, 4),
+ ANIMCMD_FRAME(128, 4),
+ ANIMCMD_FRAME(192, 4),
+ ANIMCMD_JUMP(0),
+};
+static const union AnimCmd gUnknown_085E4D90[] =
+{
+ ANIMCMD_FRAME(0, 8),
+ ANIMCMD_FRAME(64, 8),
+ ANIMCMD_FRAME(128, 8),
+ ANIMCMD_FRAME(192, 8),
+ ANIMCMD_JUMP(0),
+};
+static const union AnimCmd gUnknown_085E4DA4[] =
+{
+ ANIMCMD_FRAME(256, 4),
+ ANIMCMD_FRAME(0x140, 4),
+ ANIMCMD_FRAME(0x180, 4),
+ ANIMCMD_END,
+};
+static const union AnimCmd gUnknown_085E4DB4[] =
+{
+ ANIMCMD_FRAME(0x180, 16),
+ ANIMCMD_FRAME(0x140, 16),
+ ANIMCMD_FRAME(256, 16),
+ ANIMCMD_END,
+};
+static const union AnimCmd *const gUnknown_085E4DC4[] =
+{
+ gUnknown_085E4D7C,
+ gUnknown_085E4D90,
+ gUnknown_085E4DA4,
+ gUnknown_085E4DB4,
+};
+static const struct OamData gUnknown_085E4DD4 =
+{
+ .y = 160,
+ .affineMode = 3,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 1,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+static const struct OamData gUnknown_085E4DDC =
+{
+ .y = 160,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 0,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+static const struct OamData gUnknown_085E4DE4 =
+{
+ .y = 160,
+ .affineMode = 3,
+ .objMode = 1,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 2,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 3,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+static const union AnimCmd gUnknown_085E4DEC[] =
+{
+ ANIMCMD_FRAME(80, 8),
+ ANIMCMD_END,
+};
+static const union AnimCmd gUnknown_085E4DF4[] =
+{
+ ANIMCMD_FRAME(84, 8),
+ ANIMCMD_END,
+};
+static const union AnimCmd gUnknown_085E4DFC[] =
+{
+ ANIMCMD_FRAME(88, 8),
+ ANIMCMD_END,
+};
+static const union AnimCmd gUnknown_085E4E04[] =
+{
+ ANIMCMD_FRAME(92, 8),
+ ANIMCMD_END,
+};
+static const union AnimCmd gUnknown_085E4E0C[] =
+{
+ ANIMCMD_FRAME(96, 8),
+ ANIMCMD_END,
+};
+static const union AnimCmd gUnknown_085E4E14[] =
+{
+ ANIMCMD_FRAME(100, 8),
+ ANIMCMD_END,
+};
+static const union AnimCmd gUnknown_085E4E1C[] =
+{
+ ANIMCMD_FRAME(104, 8),
+ ANIMCMD_END,
+};
+static const union AnimCmd gUnknown_085E4E24[] =
+{
+ ANIMCMD_FRAME(112, 8),
+ ANIMCMD_END,
+};
+static const union AnimCmd gUnknown_085E4E2C[] =
+{
+ ANIMCMD_FRAME(113, 8),
+ ANIMCMD_END,
+};
+static const union AnimCmd gUnknown_085E4E34[] =
+{
+ ANIMCMD_FRAME(114, 8),
+ ANIMCMD_END,
+};
+static const union AnimCmd gUnknown_085E4E3C[] =
+{
+ ANIMCMD_FRAME(115, 8),
+ ANIMCMD_END,
+};
+static const union AnimCmd gUnknown_085E4E44[] =
+{
+ ANIMCMD_FRAME(116, 8),
+ ANIMCMD_END,
+};
+static const union AnimCmd gUnknown_085E4E4C[] =
+{
+ ANIMCMD_FRAME(117, 8),
+ ANIMCMD_END,
+};
+static const union AnimCmd gUnknown_085E4E54[] =
+{
+ ANIMCMD_FRAME(128, 8),
+ ANIMCMD_END,
+};
+static const union AnimCmd *const gUnknown_085E4E5C[] =
+{
+ gUnknown_085E4DEC,
+ gUnknown_085E4DF4,
+ gUnknown_085E4DFC,
+ gUnknown_085E4E04,
+ gUnknown_085E4E0C,
+ gUnknown_085E4E14,
+ gUnknown_085E4E1C,
+};
+static const union AnimCmd *const gUnknown_085E4E78[] =
+{
+ gUnknown_085E4E24,
+ gUnknown_085E4E2C,
+ gUnknown_085E4E34,
+ gUnknown_085E4E3C,
+ gUnknown_085E4E44,
+ gUnknown_085E4E4C,
+};
+static const union AnimCmd *const gUnknown_085E4E90[] =
+{
+ gUnknown_085E4E54,
+};
+static const s16 gUnknown_085E4E94[][2] =
+{
+ {0, -72},
+ {1, -56},
+ {2, -40},
+ {3, -24},
+ {4, 8},
+ {5, 24},
+ {3, 40},
+ {1, 56},
+ {6, 72},
+ {0, -28},
+ {1, -20},
+ {2, -12},
+ {3, -4},
+ {2, 4},
+ {4, 12},
+ {5, 20},
+ {3, 28},
+};
+static const union AffineAnimCmd gUnknown_085E4ED8[] =
+{
+ AFFINEANIMCMD_FRAME(128, 128, 0, 0),
+ AFFINEANIMCMD_END,
+};
+static const union AffineAnimCmd gUnknown_085E4EE8[] =
+{
+ AFFINEANIMCMD_FRAME(128, 128, 0, 0),
+ AFFINEANIMCMD_FRAME(16, 16, 0, 16),
+ AFFINEANIMCMD_FRAME(-16, -16, 0, 8),
+ AFFINEANIMCMD_END,
+};
+static const union AffineAnimCmd gUnknown_085E4F08[] =
+{
+ AFFINEANIMCMD_FRAME(256, 256, 0, 0),
+ AFFINEANIMCMD_FRAME(8, 8, 0, 48),
+ AFFINEANIMCMD_END,
+};
+static const union AffineAnimCmd gUnknown_085E4F20[] =
+{
+ AFFINEANIMCMD_FRAME(256, 256, 0, 0),
+ AFFINEANIMCMD_FRAME(2, 2, 0, 48),
+ AFFINEANIMCMD_END,
+};
+static const union AffineAnimCmd *const gUnknown_085E4F38[] =
+{
+ gUnknown_085E4ED8,
+ gUnknown_085E4EE8,
+ gUnknown_085E4F08,
+ gUnknown_085E4F20,
+};
+static const u16 gUnknown_085E4F48[] =
+{
+ 0x100, 0xC0, 0x80, 0x40, 0x00, 0x40, 0x80, 0xC0, 0x100
+};
+static void sub_816FB38(struct Sprite *sprite);
+static const struct SpriteTemplate gUnknown_085E4F5C =
+{
+ .tileTag = 2000,
+ .paletteTag = 2001,
+ .oam = &gUnknown_085E4DD4,
+ .anims = gUnknown_085E4E5C,
+ .images = NULL,
+ .affineAnims = gUnknown_085E4F38,
+ .callback = sub_816FB38,
+};
+static const struct SpriteTemplate gUnknown_085E4F74 =
+{
+ .tileTag = 2000,
+ .paletteTag = 2001,
+ .oam = &gUnknown_085E4DDC,
+ .anims = gUnknown_085E4E78,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_816FB38,
+};
+static void sub_816FD44(struct Sprite *sprite);
+static const struct SpriteTemplate gUnknown_085E4F8C =
+{
+ .tileTag = 2000,
+ .paletteTag = 2001,
+ .oam = &gUnknown_085E4DE4,
+ .anims = gUnknown_085E4E90,
+ .images = NULL,
+ .affineAnims = gUnknown_085E4F38,
+ .callback = sub_816FD44,
+};
+static const u8 gUnknown_085E4FA4[] =
+{
+ 0x00, 0x17, 0x17, 0x31, 0x3E, 0x24, 0x24, 0x0A, 0x0A
+};
+static const struct OamData gUnknown_085E4FB0 =
+{
+ .y = 160,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 1,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 3,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+static const union AnimCmd gUnknown_085E4FB8[] =
+{
+ ANIMCMD_FRAME(0, 10),
+ ANIMCMD_JUMP(0),
+};
+static const union AnimCmd *const gUnknown_085E4FC0[] =
+{
+ gUnknown_085E4FB8,
+};
+static void sub_816FEDC(struct Sprite *sprite);
+static const struct SpriteTemplate gUnknown_085E4FC4 =
+{
+ .tileTag = 2002,
+ .paletteTag = 2002,
+ .oam = &gUnknown_085E4FB0,
+ .anims = gUnknown_085E4FC0,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_816FEDC,
+};
+static const struct CompressedSpriteSheet gUnknown_085E4FDC[] =
+{
+ {gIntroTiles, 0x1400, 2000},
+ {NULL},
+};
+static const struct CompressedSpriteSheet gUnknown_085E4FEC[] =
+{
+ {gIntro1FlygonGfx, 0x400, 2002},
+ {NULL},
+};
+static const struct SpritePalette gUnknown_085E4FFC[] =
+{
+ {gIntro1DropsPal, 2000},
+ {gIntro1GFLogoPal, 2001},
+ {gIntro1FlygonPalette, 2002},
+ {NULL},
+};
+static const struct OamData gUnknown_085E501C =
+{
+ .y = 160,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 3,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+static const union AnimCmd gUnknown_085E5024[] =
+{
+ ANIMCMD_FRAME(16, 8),
+ ANIMCMD_END,
+};
+static const union AnimCmd *const gUnknown_085E502C[] =
+{
+ gUnknown_085E5024,
+};
+static void sub_8170040(struct Sprite *sprite);
+static const struct SpriteTemplate gUnknown_085E5030 =
+{
+ .tileTag = 2003,
+ .paletteTag = 2003,
+ .oam = &gUnknown_085E501C,
+ .anims = gUnknown_085E502C,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_8170040,
+};
+static const struct CompressedSpriteSheet gUnknown_085E5048[] =
+{
+ {gIntro3MiscTiles, 0xA00, 2003},
+ {NULL},
+};
+static const struct SpritePalette gUnknown_085E5058[] =
+{
+ {gIntro3Misc1Palette, 2003},
+ {NULL},
+};
+
+// this file's functions
+static void MainCB2_EndIntro(void);
+static void Task_IntroLoadPart1Graphics(u8);
+static u8 CreateWaterDrop(s16, s16, u16, u16, u16, u8);
+static void Task_IntroFadeIn(u8);
+static void intro_reset_and_hide_bgs(void);
+static void Task_IntroWaterDrops(u8);
+static void Task_IntroWaterDrops_1(u8);
+static void Task_IntroWaterDrops_2(u8);
+static void Task_IntroWaterDrops_3(u8);
+static void Task_IntroScrollDownAndShowFlygon(u8);
+static void Task_IntroWaitToSetupPart2(u8);
+static void Task_IntroLoadPart2Graphics(u8);
+static void Task_IntroStartBikeRide(u8);
+static void Task_IntroHandleBikeAndFlygonMovement(u8);
+static void Task_IntroWaitToSetupPart3(u8);
+static void Task_IntroLoadPart3Graphics(u8);
+static void Task_IntroSpinAndZoomPokeball(u8);
+static void Task_IntroWaitToSetupPart3LegendsFight(u8);
+static void Task_IntroLoadPart1Graphics3(u8);
+static void Task_IntroLoadPart1Graphics4(u8);
+static void Task_IntroLoadPart1Graphics5(u8);
+static void Task_IntroLoadPart1Graphics6(u8);
+static void Task_IntroLoadPart1Graphics7(u8);
+static void Task_IntroLoadPart1Graphics8(u8);
+static void Task_IntroLoadPart1Graphics9(u8);
+static void Task_IntroFadeIn0(u8);
+static void Task_IntroFadeIn1(u8);
+static void Task_IntroFadeIn2(u8);
+static void Task_IntroFadeIn3(u8);
+static void Task_IntroFadeIn4(u8);
+static void Task_IntroFadeIn5(u8);
+static void Task_IntroFadeIn6(u8);
+static void Task_IntroFadeIn7(u8);
+static void Task_IntroFadeIn8(u8);
+static void Task_IntroFadeIn9(u8);
+static void sub_816E190(u8);
+static void sub_816E1F8(struct Sprite *);
+static void sub_816E6D4(u8);
+static void sub_816E74C(void);
+static void sub_816EEA8(u8);
+static void sub_816F46C(struct Sprite *);
+static void sub_816F5B4(struct Sprite *);
+static void sub_816F660(struct Sprite *);
+static void SpriteCB_WaterDropFall(struct Sprite *);
+static void sub_816F318(struct Sprite *);
+static void sub_816F9D4(struct Sprite *);
+static void sub_816FAB0(struct Sprite *);
+static u8 sub_816FDB8(s16, s16, s16);
+
+static void VBlankCB_Intro(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+ ScanlineEffect_InitHBlankDmaTransfer();
+}
+
+static void MainCB2_Intro(void)
+{
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+ if (gMain.newKeys && !gPaletteFade.active)
+ SetMainCallback2(MainCB2_EndIntro);
+ else if (gIntroFrameCounter != -1)
+ gIntroFrameCounter++;
+}
+
+static void MainCB2_EndIntro(void)
+{
+ if (!UpdatePaletteFade())
+ SetMainCallback2(CB2_InitTitleScreen);
+}
+
+static void LoadCopyrightGraphics(u16 tilesetAddress, u16 tilemapAddress, u16 paletteAddress)
+{
+ LZ77UnCompVram(gIntroCopyright_Gfx, (void *)(VRAM + tilesetAddress));
+ LZ77UnCompVram(gIntroCopyright_Tilemap, (void *)(VRAM + tilemapAddress));
+ LoadPalette(gIntroCopyright_Pal, paletteAddress, 0x20);
+}
+
+static void SerialCB_CopyrightScreen(void)
+{
+ GameCubeMultiBoot_HandleSerialInterrupt(&gMultibootProgramStruct);
+}
+
+static u8 SetUpCopyrightScreen(void)
+{
+ u16 ime;
+
+ switch (gMain.state)
+ {
+ case 0:
+ SetVBlankCallback(NULL);
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ *(u16 *)PLTT = 0x7FFF;
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ SetGpuReg(REG_OFFSET_BG0HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG0VOFS, 0);
+ CpuFill32(0, (void *)VRAM, VRAM_SIZE);
+ CpuFill32(0, (void *)OAM, OAM_SIZE);
+ CpuFill16(0, (void *)(PLTT + 2), PLTT_SIZE - 2);
+ ResetPaletteFade();
+ LoadCopyrightGraphics(0, 0x3800, 0);
+ ScanlineEffect_Stop();
+ ResetTasks();
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, RGB_WHITEALPHA);
+ SetGpuReg(REG_OFFSET_BG0CNT, BGCNT_PRIORITY(0)
+ | BGCNT_CHARBASE(0)
+ | BGCNT_SCREENBASE(7)
+ | BGCNT_16COLOR
+ | BGCNT_TXT256x256);
+ EnableInterrupts(INTR_FLAG_VBLANK);
+ SetVBlankCallback(VBlankCB_Intro);
+ REG_DISPCNT = DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON;
+ SetSerialCallback(SerialCB_CopyrightScreen);
+ GameCubeMultiBoot_Init(&gMultibootProgramStruct);
+ default:
+ UpdatePaletteFade();
+ gMain.state++;
+ GameCubeMultiBoot_Main(&gMultibootProgramStruct);
+ break;
+ case 140:
+ GameCubeMultiBoot_Main(&gMultibootProgramStruct);
+ if (gMultibootProgramStruct.gcmb_field_2 != 1)
+ {
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK);
+ gMain.state++;
+ }
+ break;
+ case 141:
+ if (UpdatePaletteFade())
+ break;
+ CreateTask(Task_IntroLoadPart1Graphics, 0);
+ SetMainCallback2(MainCB2_Intro);
+ if (gMultibootProgramStruct.gcmb_field_2 != 0)
+ {
+ if (gMultibootProgramStruct.gcmb_field_2 == 2)
+ {
+ // check the multiboot ROM header game code to see if we already did this
+ if (*(u32 *)(EWRAM_START + 0xAC) == 0x65366347) // "Gc6e" in ASCII
+ {
+ CpuCopy16(&gMultiBootProgram_PokemonColosseum_Start, (void *)EWRAM_START, sizeof(gMultiBootProgram_PokemonColosseum_Start));
+ *(u32 *)(EWRAM_START + 0xAC) = 0x65366347;
+ }
+ GameCubeMultiBoot_ExecuteProgram(&gMultibootProgramStruct);
+ }
+ }
+ else
+ {
+ GameCubeMultiBoot_Quit();
+ SetSerialCallback(SerialCB);
+ }
+ return 0;
+ }
+
+ return 1;
+}
+
+void CB2_InitCopyrightScreenAfterBootup(void)
+{
+ if (!SetUpCopyrightScreen())
+ {
+ SetSaveBlocksPointers(sub_815355C());
+ sub_808447C();
+ Save_ResetSaveCounters();
+ Save_LoadGameData(SAVE_NORMAL);
+ if (gSaveFileStatus == 0 || gSaveFileStatus == 2)
+ Sav2_ClearSetDefault();
+ SetPokemonCryStereo(gSaveBlock2Ptr->optionsSound);
+ InitHeap(gHeap, HEAP_SIZE);
+ }
+}
+
+void CB2_InitCopyrightScreenAfterTitleScreen(void)
+{
+ SetUpCopyrightScreen();
+}
+
+static void Task_IntroLoadPart1Graphics(u8 taskId)
+{
+ SetVBlankCallback(NULL);
+ gUnknown_0203BCC8 = Random() & 1;
+ intro_reset_and_hide_bgs();
+ SetGpuReg(REG_OFFSET_BG3VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG2VOFS, 0x50);
+ SetGpuReg(REG_OFFSET_BG1VOFS, 0x18);
+ SetGpuReg(REG_OFFSET_BG0VOFS, 0x28);
+ LZ77UnCompVram(gIntro1BGLeavesGfx, (void *)VRAM);
+ LZ77UnCompVram(gIntro1BG0_Tilemap, (void *)(VRAM + 0x8000));
+ DmaClear16(3, VRAM + 0x8800, 0x800);
+ LZ77UnCompVram(gIntro1BG1_Tilemap, (void *)(VRAM + 0x9000));
+ DmaClear16(3, VRAM + 0x9800, 0x800);
+ LZ77UnCompVram(gIntro1BG2_Tilemap, (void *)(VRAM + 0xA000));
+ DmaClear16(3, VRAM + 0xA800, 0x800);
+ LZ77UnCompVram(gIntro1BG3_Tilemap, (void *)(VRAM + 0xB000));
+ DmaClear16(3, VRAM + 0xB800, 0x800);
+ LoadPalette(gIntro1BGPals, 0, sizeof(gIntro1BGPals));
+ SetGpuReg(REG_OFFSET_BG3CNT, BGCNT_PRIORITY(3) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(22) | BGCNT_16COLOR | BGCNT_TXT256x512);
+ SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(2) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(20) | BGCNT_16COLOR | BGCNT_TXT256x512);
+ SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(1) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(18) | BGCNT_16COLOR | BGCNT_TXT256x512);
+ SetGpuReg(REG_OFFSET_BG0CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(16) | BGCNT_16COLOR | BGCNT_TXT256x512);
+ LoadCompressedObjectPic(gUnknown_085E4FDC);
+ LoadCompressedObjectPic(gUnknown_085E4FEC);
+ LoadSpritePalettes(gUnknown_085E4FFC);
+ LoadCompressedObjectPic(gUnknown_085E4A74);
+ LoadSpritePalettes(gUnknown_085E4A84);
+ CpuCopy16(gPlttBufferUnfaded + 0x100, gPlttBufferUnfaded + 0x1F0, 0x20);
+ CpuCopy16(gPlttBufferUnfaded + 0x100, gPlttBufferUnfaded + 0x1E1, 0x1E);
+ CpuCopy16(gPlttBufferUnfaded + 0x100, gPlttBufferUnfaded + 0x1D2, 0x1C);
+ CpuCopy16(gPlttBufferUnfaded + 0x100, gPlttBufferUnfaded + 0x1C3, 0x1A);
+ CpuCopy16(gPlttBufferUnfaded + 0x100, gPlttBufferUnfaded + 0x1B4, 0x18);
+ CpuCopy16(gPlttBufferUnfaded + 0x100, gPlttBufferUnfaded + 0x1A5, 0x16);
+ CpuCopy16(gPlttBufferUnfaded + 0x100, gPlttBufferUnfaded + 0x196, 0x14);
+ sub_816FDB8(0x78, 0x50, 0);
+ gTasks[taskId].data[0] = CreateWaterDrop(236, -14, 0x200, 1, 0x78, FALSE);
+ gTasks[taskId].func = Task_IntroFadeIn;
+}
+
+static void Task_IntroFadeIn(u8 taskId)
+{
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK);
+ SetVBlankCallback(VBlankCB_Intro);
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG_ALL_ON | DISPCNT_OBJ_ON);
+ gTasks[taskId].func = Task_IntroWaterDrops;
+ gIntroFrameCounter = 0;
+ m4aSongNumStart(MUS_DEMO1);
+ ResetSerial();
+}
+
+static void Task_IntroWaterDrops(u8 taskId)
+{
+ //start moving rock
+ if (gIntroFrameCounter == 76)
+ gSprites[gTasks[taskId].data[0]].data[0] = 1;
+
+ if (gIntroFrameCounter == 128)
+ CreateTask(Task_IntroWaterDrops_1, 0);
+
+ //drop rock
+ if (gIntroFrameCounter == 251)
+ gSprites[gTasks[taskId].data[0]].data[0] = 2;
+
+ if (gIntroFrameCounter == 256)
+ CreateTask(Task_IntroWaterDrops_2, 0);
+
+ if (gIntroFrameCounter == 368)
+ CreateWaterDrop(48, 0, 0x400, 5, 0x70, TRUE);
+
+ if (gIntroFrameCounter == 384)
+ CreateWaterDrop(200, 60, 0x400, 9, 0x80, TRUE);
+
+ if (gIntroFrameCounter == 560)
+ CreateTask(Task_IntroWaterDrops_3, 0);
+
+ if (gIntroFrameCounter > 560)
+ {
+ gTasks[taskId].data[1] = 0x50;
+ gTasks[taskId].data[2] = 0;
+ gTasks[taskId].data[3] = 0x18;
+ gTasks[taskId].data[4] = 0;
+ gTasks[taskId].data[5] = 0x28;
+ gTasks[taskId].data[6] = 0;
+ gTasks[taskId].func = Task_IntroScrollDownAndShowFlygon;
+ }
+}
+
+static void Task_IntroWaterDrops_3(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ if (++data[2] & 1)
+ data[3]++;
+
+ switch (data[0])
+ {
+ case 0:
+ CreateSprite(&gUnknown_085E4AB8, gUnknown_085E4AD0[data[4]][0], gUnknown_085E4AD0[data[4]][1] + data[3], 0);
+ data[0]++;
+ data[1] = 0xC;
+ data[4]++;
+ break;
+ case 1:
+ if (!--data[1])
+ data[0] = 0;
+ break;
+ }
+
+ if (data[3] > 0x3C)
+ DestroyTask(taskId);
+}
+
+static void sub_816D338(struct Sprite *sprite)
+{
+ if (++sprite->data[0] == 0xC)
+ DestroySprite(sprite);
+}
+
+static void Task_IntroScrollDownAndShowFlygon(u8 taskId)
+{
+ if (gIntroFrameCounter < 904)
+ {
+ s32 r2;
+
+ //slide backgrounds downward
+ r2 = (gTasks[taskId].data[1] << 16) + (u16)gTasks[taskId].data[2];
+ r2 -= 0x6000;
+ gTasks[taskId].data[1] = r2 >> 16;
+ gTasks[taskId].data[2] = r2;
+ SetGpuReg(REG_OFFSET_BG2VOFS, gTasks[taskId].data[1]);
+ r2 = (gTasks[taskId].data[3] << 16) + (u16)gTasks[taskId].data[4];
+ r2 -= 0x8000;
+ gTasks[taskId].data[3] = r2 >> 16;
+ gTasks[taskId].data[4] = r2;
+ SetGpuReg(REG_OFFSET_BG1VOFS, gTasks[taskId].data[3]);
+ r2 = (gTasks[taskId].data[5] << 16) + (u16)gTasks[taskId].data[6];
+ r2 -= 0xC000;
+ gTasks[taskId].data[5] = r2 >> 16;
+ gTasks[taskId].data[6] = r2;
+ SetGpuReg(REG_OFFSET_BG0VOFS, gTasks[taskId].data[5]);
+
+ //show Flygon sprite
+ if (gIntroFrameCounter == 832)
+ {
+ u8 spriteId = CreateSprite(&gUnknown_085E4FC4, 120, 160, 10);
+ gSprites[spriteId].invisible = TRUE;
+ }
+ }
+ else
+ {
+ //fade to white
+ if (gIntroFrameCounter > 1007)
+ {
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_WHITEALPHA);
+ gTasks[taskId].func = Task_IntroWaitToSetupPart2;
+ }
+ }
+}
+
+static void Task_IntroWaitToSetupPart2(u8 taskId)
+{
+ if (gIntroFrameCounter > 1026)
+ gTasks[taskId].func = Task_IntroLoadPart2Graphics;
+}
+
+static void Task_IntroLoadPart2Graphics(u8 taskId)
+{
+ intro_reset_and_hide_bgs();
+ SetVBlankCallback(NULL);
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ gUnknown_0203BD24 = 0;
+ gUnknown_0203BD26 = 0;
+ gUnknown_0203BCCC = 0;
+ load_intro_part2_graphics(1);
+ gTasks[taskId].func = Task_IntroStartBikeRide;
+}
+
+static void Task_IntroStartBikeRide(u8 taskId)
+{
+ u8 spriteId;
+
+ if (gUnknown_0203BCC8 == 0)
+ LoadCompressedObjectPic(gIntro2BrendanSpriteSheet);
+ else
+ LoadCompressedObjectPic(gIntro2MaySpriteSheet);
+
+ LoadCompressedObjectPic(gIntro2BicycleSpriteSheet);
+ LoadCompressedObjectPic(gIntro2FlygonSpriteSheet);
+
+ for (spriteId = 0; spriteId < 3; spriteId++)
+ {
+ LoadCompressedObjectPic(&gUnknown_085E4AE8[spriteId]);
+ }
+
+ LoadSpritePalettes(gUnknown_085F530C);
+ LoadSpritePalettes(gUnknown_085E4B08);
+ CreateSprite(&gUnknown_085E4BDC, 0x110, 0x80, 0);
+ CreateSprite(&gUnknown_085E4BA4, 0x120, 0x6E, 1);
+
+ if (gUnknown_0203BCC8 == 0)
+ spriteId = intro_create_brendan_sprite(0x110, 100);
+ else
+ spriteId = intro_create_may_sprite(0x110, 100);
+
+ gSprites[spriteId].callback = sub_816F9D4;
+ gSprites[spriteId].anims = gUnknown_085E4DC4;
+ gTasks[taskId].data[1] = spriteId;
+ CreateSprite(&gUnknown_085E4B40, 0x110, 0x50, 0x4);
+ spriteId = intro_create_flygon_sprite(-0x40, 0x3C);
+ gSprites[spriteId].callback = sub_816FAB0;
+ gTasks[taskId].data[2] = spriteId;
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_WHITEALPHA);
+ SetVBlankCallback(VBlankCB_Intro);
+ gTasks[taskId].data[0] = sub_817B3DC(1, 0x4000, 0x400, 0x10);
+ sub_817B150(1);
+ gTasks[taskId].func = Task_IntroHandleBikeAndFlygonMovement;
+}
+
+static void Task_IntroHandleBikeAndFlygonMovement(u8 taskId)
+{
+ s16 a;
+ u16 sine;
+
+ if (gIntroFrameCounter == 1856)
+ {
+ gUnknown_0203BD28 = 2;
+ DestroyTask(gTasks[taskId].data[0]);
+ }
+ if (gIntroFrameCounter > 1946)
+ {
+ BeginNormalPaletteFade(0xFFFFFFFF, 8, 0, 16, RGB_WHITEALPHA);
+ gTasks[taskId].func = Task_IntroWaitToSetupPart3;
+ }
+ if (gIntroFrameCounter == 1109)
+ gSprites[gTasks[taskId].data[1]].data[0] = 1;
+ if (gIntroFrameCounter == 1214)
+ gSprites[gTasks[taskId].data[1]].data[0] = 0;
+ if (gIntroFrameCounter == 1394)
+ gSprites[gTasks[taskId].data[2]].data[0] = 1;
+ if (gIntroFrameCounter == 1398)
+ gSprites[gTasks[taskId].data[1]].data[0] = 2;
+ if (gIntroFrameCounter == 1576)
+ gSprites[gTasks[taskId].data[1]].data[0] = 3;
+ if (gIntroFrameCounter == 1727)
+ gSprites[gTasks[taskId].data[1]].data[0] = 4;
+
+ sine = Sin(gTasks[taskId].data[3] >> 2 & 0x7F, 48);
+ gUnknown_0203BCCC = sine;
+ if (gTasks[taskId].data[3] < 512)
+ gTasks[taskId].data[3]++;
+ sub_817B540(0);
+}
+
+static void Task_IntroWaitToSetupPart3(u8 taskId)
+{
+ if (gIntroFrameCounter > 2068)
+ gTasks[taskId].func = Task_IntroLoadPart3Graphics;
+}
+
+static void sub_816D81C(struct Sprite *sprite)
+{
+ sprite->data[3] += 4;
+ switch (sprite->data[0])
+ {
+ case 0:
+ if (++sprite->data[1] < 180)
+ break;
+ ++sprite->data[0];
+ case 1:
+ sprite->pos1.x -= 4;
+ if (sprite->pos1.x == 0x3C)
+ {
+ sprite->data[0] = 8;
+ sprite->data[1] = 20;
+ sprite->data[2] = 2;
+ }
+ break;
+ case 2:
+ sprite->pos1.x += 8;
+ sprite->pos1.y -= 2;
+ if (sprite->pos1.x == 0x7C)
+ {
+ sprite->data[0] = 8;
+ sprite->data[1] = 20;
+ sprite->data[2] = 3;
+ }
+ break;
+ case 3:
+ sprite->pos1.y += 4;
+ if (sprite->pos1.y == 0x50)
+ {
+ sprite->data[0] = 8;
+ sprite->data[1] = 10;
+ sprite->data[2] = 4;
+ }
+ break;
+ case 4:
+ sprite->pos1.x -= 8;
+ sprite->pos1.y -= 2;
+ if (sprite->pos1.x == 0x3C)
+ {
+ sprite->data[0] = 8;
+ sprite->data[1] = 10;
+ sprite->data[2] = 5;
+ }
+ break;
+ case 5:
+ sprite->pos1.x += 0x3C;
+ sprite->data[4] = 0xC0;
+ sprite->data[5] = 0x80;
+ sprite->data[6] = 0x3;
+ sprite->data[0]++;
+ case 6:
+ sprite->pos2.x = Sin((u8)sprite->data[4], 0x3C);
+ sprite->pos2.y = Sin((u8)sprite->data[5], 0x14);
+ sprite->data[4] += 2;
+ sprite->data[5] += 4;
+ if ((sprite->data[4] & 0xFF) == 0x40)
+ {
+ sprite->hFlip = FALSE;
+ if (!--sprite->data[6])
+ {
+ sprite->pos1.x += sprite->pos2.x;
+ sprite->pos2.x = 0;
+ sprite->data[0]++;
+ }
+ }
+ break;
+ case 7:
+ sprite->pos1.x -= 2;
+ sprite->pos2.y = Sin((u8)sprite->data[5], 0x14);
+ sprite->data[5] += 4;
+ if (sprite->pos1.x < -16)
+ DestroySprite(sprite);
+ break;
+ case 8:
+ sprite->pos2.y = Cos((u8)sprite->data[3], 2);
+ if (!--sprite->data[1])
+ sprite->data[0] = sprite->data[2];
+ break;
+ }
+}
+
+static void sub_816D9C0(struct Sprite *sprite)
+{
+ switch (sprite->data[0])
+ {
+ case 0:
+ if (gIntroFrameCounter == 1224)
+ {
+ StartSpriteAnim(sprite, 1);
+ sprite->data[0]++;
+ }
+ break;
+ case 1:
+ if (gIntroFrameCounter == 1576)
+ {
+ StartSpriteAnim(sprite, 0);
+ sprite->data[0]++;
+ }
+ else
+ {
+ sprite->data[1] += 0x40;
+ if (sprite->data[1] & 0xFF00)
+ {
+ sprite->pos1.x--;
+ sprite->data[1] &= 0xFF;
+ }
+ }
+ break;
+ case 2:
+ if (gIntroFrameCounter != 1735)
+ {
+ sprite->data[1] += 0x20;
+ if (sprite->data[1] & 0xFF00)
+ {
+ sprite->pos1.x++;
+ sprite->data[1] &= 0xFF;
+ }
+ }
+ else
+ {
+ StartSpriteAnim(sprite, 1);
+ sprite->data[0]++;
+ sprite->data[2] = 0x50;
+ }
+ break;
+ case 3:
+ if (--sprite->data[2])
+ {
+ sprite->data[1] += 0x40;
+ if (sprite->data[1] & 0xFF00)
+ {
+ sprite->pos1.x--;
+ sprite->data[1] &= 0xFF;
+ }
+ }
+ else
+ {
+ StartSpriteAnim(sprite, 2);
+ sprite->data[0]++;
+ }
+ break;
+ case 4:
+ if (sprite->animEnded)
+ sprite->pos1.x += 4;
+
+ if (sprite->pos1.x > 336)
+ {
+ StartSpriteAnim(sprite, 1);
+ sprite->data[0]++;
+ }
+ break;
+ case 5:
+ if (gIntroFrameCounter > 1855)
+ sprite->pos1.x -= 2;
+ break;
+ }
+}
+
+static void sub_816DAE8(struct Sprite *sprite)
+{
+ switch (sprite->data[0])
+ {
+ case 0:
+ if (gIntroFrameCounter == 1088)
+ sprite->data[0]++;
+ break;
+ case 1:
+ sprite->pos1.x -= 2;
+ if (gIntroFrameCounter != 1168)
+ break;
+ sprite->pos1.y -= 12;
+ sprite->data[1] = 0x80;
+ sprite->data[2] = 0;
+ sprite->data[0]++;
+ case 2:
+ if (sprite->pos1.x + sprite->pos2.x <= -0x20)
+ {
+ DestroySprite(sprite);
+ }
+ else
+ {
+ if ((sprite->data[1] & 0xFF) < 0x40)
+ {
+ sprite->pos2.x = Sin((u8)sprite->data[1], 0x10);
+ }
+ else
+ {
+ if ((sprite->data[1] & 0xFF) == 0x40)
+ sprite->pos1.x -= 0x30;
+ sprite->pos2.x = Sin((u8)sprite->data[1], 0x40);
+ }
+ sprite->data[1]++;
+ sprite->pos2.y = Cos((u8)sprite->data[2], 0xC);
+ sprite->data[2]++;
+ }
+ break;
+ }
+}
+
+static void Task_IntroLoadPart3Graphics(u8 taskId)
+{
+ intro_reset_and_hide_bgs();
+ LZ77UnCompVram(gIntro3Pokeball_Gfx, (void *)VRAM);
+ LZ77UnCompVram(gIntro3Pokeball_Tilemap, (void *)(VRAM + 0x4000));
+ LoadPalette(gIntro3PokeballPal, 0, 0x200);
+ gTasks[taskId].data[0] = 0;
+ gTasks[taskId].data[1] = 0;
+ gTasks[taskId].data[2] = 0;
+ gTasks[taskId].data[3] = 0;
+ sub_816F2A8(0x78, 0x50, 0, 0);
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, RGB_WHITEALPHA);
+ SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(3) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(8) | BGCNT_256COLOR | BGCNT_AFF256x256);
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_1 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG2_ON | DISPCNT_OBJ_ON);
+ gTasks[taskId].func = Task_IntroSpinAndZoomPokeball;
+ gIntroFrameCounter = 0;
+ m4aSongNumStart(MUS_T_BATTLE);
+}
+
+static void Task_IntroSpinAndZoomPokeball(u8 taskId)
+{
+ gTasks[taskId].data[0] += 0x400;
+
+ if (gTasks[taskId].data[1] <= 0x6BF)
+ {
+ gTasks[taskId].data[1] += gTasks[taskId].data[2];
+ gTasks[taskId].data[2] += 2;
+ }
+ else
+ {
+ gTasks[taskId].func = Task_IntroWaitToSetupPart3LegendsFight;
+ }
+
+ sub_816F2A8(0x78, 0x50, 0x10000 / gTasks[taskId].data[1], gTasks[taskId].data[0]);
+
+ if (gIntroFrameCounter == 28)
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_WHITEALPHA);
+}
+
+static void Task_IntroWaitToSetupPart3LegendsFight(u8 taskId)
+{
+ if (gIntroFrameCounter > 43)
+ gTasks[taskId].func = Task_IntroLoadPart1Graphics3;
+}
+
+static void Task_IntroLoadPart1Graphics3(u8 taskId)
+{
+ u16 i;
+
+ if (!gPaletteFade.active)
+ {
+ intro_reset_and_hide_bgs();
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ gReservedSpritePaletteCount = 8;
+ LZDecompressVram(gIntro3GroudonGfx, (void *)VRAM);
+ LZDecompressVram(gIntro3GroudonTilemap, (void *)(VRAM + 0xC000));
+ LZDecompressVram(gIntro3LegendBgGfx, (void *)(VRAM + 0x4000));
+ LZDecompressVram(gIntro3GroudonBgTilemap, (void *)(VRAM + 0xE000));
+ LoadCompressedObjectPicUsingHeap(&gBattleAnimPicTable[0x3A]);
+ LoadCompressedObjectPaletteUsingHeap(&gBattleAnimPaletteTable[0x3A]);
+ CpuCopy16(gIntro3BgPal, gPlttBufferUnfaded, sizeof(gIntro3BgPal));
+ gTasks[taskId].func = Task_IntroLoadPart1Graphics4;
+ }
+}
+
+static void Task_IntroLoadPart1Graphics4(u8 taskId)
+{
+ SetGpuReg(REG_OFFSET_WIN0H, 0xF0);
+ SetGpuReg(REG_OFFSET_WIN0V, 0xA0);
+ SetGpuReg(REG_OFFSET_WININ, 0x3F);
+ SetGpuReg(REG_OFFSET_WINOUT, 0);
+ SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(0)
+ | BGCNT_CHARBASE(0)
+ | BGCNT_SCREENBASE(24)
+ | BGCNT_256COLOR
+ | BGCNT_WRAP
+ | BGCNT_AFF512x512);
+ SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(1)
+ | BGCNT_CHARBASE(1)
+ | BGCNT_SCREENBASE(28)
+ | BGCNT_16COLOR
+ | BGCNT_TXT256x256);
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_1
+ | DISPCNT_OBJ_1D_MAP
+ | DISPCNT_BG1_ON
+ | DISPCNT_BG2_ON
+ | DISPCNT_OBJ_ON
+ | DISPCNT_WIN0_ON);
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, RGB_WHITEALPHA);
+ gTasks[taskId].data[0] = 0;
+ gTasks[taskId].data[1] = 0xFFA0;
+ gTasks[taskId].data[2] = 0xFF51;
+ gTasks[taskId].data[3] = 0x100;
+ sub_816F2A8(0xFFA0, 0xFF51, 0x100, 0);
+ gTasks[taskId].func = Task_IntroLoadPart1Graphics5;
+}
+
+static void Task_IntroLoadPart1Graphics5(u8 taskId)
+{
+ u16 foo = gTasks[taskId].data[0];
+
+ if (gTasks[taskId].data[0] != 32)
+ {
+ gTasks[taskId].data[0] += 4;
+ SetGpuReg(REG_OFFSET_WIN0V, (gTasks[taskId].data[0] * 256) - (foo -= 0x9C));
+ }
+ else
+ {
+ SetGpuReg(REG_OFFSET_WIN0V, 0x2080);
+ gTasks[taskId].func = Task_IntroLoadPart1Graphics6;
+ }
+}
+
+static void Task_IntroLoadPart1Graphics6(u8 taskId)
+{
+ gTasks[taskId].func = Task_IntroLoadPart1Graphics7;
+}
+
+static void Task_IntroLoadPart1Graphics7(u8 taskId)
+{
+ gTasks[taskId].data[0] = 0;
+ gTasks[taskId].func = Task_IntroLoadPart1Graphics8;
+ ScanlineEffect_InitWave(0, 0xA0, 0x4, 4, 1, 4, 0);
+}
+
+static void Task_IntroLoadPart1Graphics8(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ data[5]++;
+ if ((u16)(data[0] - 1) < 7 && data[5] % 2 == 0)
+ data[4] ^= 3;
+ sub_816F2A8(data[1], data[2] + data[4], data[3], 0);
+ switch (data[0])
+ {
+ case 0:
+ data[1] += 0x10;
+ if (data[1] == 0xA0)
+ {
+ data[0]++;
+ data[6] = 2;
+ data[7] = 0x1E2;
+ sub_816E190(taskId);
+ }
+ break;
+ case 1:
+ if (--data[6] == 0)
+ {
+ data[6] = 2;
+ CpuCopy16(&gIntro3BgPal[data[7]], &gPlttBufferFaded[31], sizeof(u16));
+ data[7] += 2;
+ if (data[7] == 0x1EC)
+ data[0]++;
+ }
+ break;
+ case 2:
+ if (--data[6] == 0)
+ {
+ data[6] = 2;
+ data[0]++;
+ }
+ break;
+ case 3:
+ if (--data[6] == 0)
+ {
+ data[6] = 2;
+ CpuCopy16(&gIntro3BgPal[data[7]], &gPlttBufferFaded[31], sizeof(u16));
+ data[7] -= 2;
+ if (data[7] == 0x1E0)
+ {
+ data[6] = 8;
+ data[0]++;
+ }
+ }
+ break;
+ case 4:
+ if (--data[6] == 0)
+ {
+ data[1] = -0x60;
+ data[2] = 0xA9;
+ data[6] = 3;
+ data[0]++;
+ }
+ break;
+ case 5:
+ if (--data[6] == 0)
+ {
+ data[1] = 0x50;
+ data[2] = 0x29;
+ data[6] = 0x10;
+ PlayCryInternal(SPECIES_GROUDON, 0, 100, 10, 0);
+ data[0]++;
+ }
+ break;
+ case 6:
+ if (--data[6] == 0)
+ {
+ data[1] = 0x50;
+ data[2] = 0x28;
+ data[0]++;
+ }
+ break;
+ case 7:
+ data[1] += 4;
+ data[2] += 4;
+ data[6] += 0x666;
+ data[3] = Sin((data[6] & 0xFF00) >> 8, 0x40) + 0x100;
+ if (data[1] == 0x78)
+ {
+ BeginNormalPaletteFade(0xFFFFFFFE, 3, 0, 16, RGB_WHITE);
+ data[3] = 0x100;
+ data[4] = 0;
+ data[0]++;
+ }
+ break;
+ case 8:
+ if (data[3])
+ data[3] -= 8;
+ else
+ data[0]++;
+ break;
+ case 9:
+ if (!gPaletteFade.active)
+ {
+ gTasks[taskId].func = Task_IntroLoadPart1Graphics9;
+ gScanlineEffect.state = 3;
+ }
+ break;
+ }
+}
+
+static void sub_816E190(u8 a0)
+{
+ int i;
+ u8 spriteId;
+
+ for (i = 0; i < 6; i++)
+ {
+ spriteId = CreateSprite(gUnknown_08596C10, gUnknown_085E4C64[i][0], 0xA0, i);
+ gSprites[spriteId].callback = sub_816E1F8;
+ gSprites[spriteId].oam.priority = 0;
+ gSprites[spriteId].data[1] = i;
+ gSprites[spriteId].data[4] = a0;
+ StartSpriteAnim(&gSprites[spriteId], gUnknown_085E4C64[i][1]);
+ }
+}
+
+static void sub_816E1F8(struct Sprite *sprite)
+{
+ sprite->data[3]++;
+ if (sprite->data[3] % 2 == 0)
+ sprite->pos2.y ^= 3;
+
+ switch(sprite->data[0])
+ {
+ case 0:
+ sprite->data[2] += gUnknown_085E4C64[sprite->data[1]][2];
+ sprite->pos1.y -= (sprite->data[2] & 0xFF00) >> 8;
+ sprite->data[2] &= 0xFF;
+ if (gTasks[sprite->data[4]].data[0] > 7)
+ sprite->data[0]++;
+ break;
+ case 1:
+ if (sprite->pos1.x < 0x78)
+ sprite->pos1.x -= 2;
+ else
+ sprite->pos1.x += 2;
+
+ if (sprite->pos1.y < 0x50)
+ sprite->pos1.y -= 2;
+ else
+ sprite->pos1.y += 2;
+ break;
+ }
+}
+
+static void Task_IntroLoadPart1Graphics9(u8 taskId)
+{
+ ResetSpriteData();
+ LZDecompressVram(gIntro3KyogreGfx, (void *)VRAM);
+ LZDecompressVram(gIntro3KyogreTilemap, (void *)(VRAM + 0xC000));
+ LZDecompressVram(gIntro3KyogreBgTilemap, (void *)(VRAM + 0xE000));
+ LoadCompressedObjectPic(gUnknown_085E4C88);
+ LoadSpritePalette(gUnknown_085E4C98);
+ BeginNormalPaletteFade(0xFFFFFFFE, 0, 0x10, 0, RGB_WHITEALPHA);
+ gTasks[taskId].func = Task_IntroFadeIn0;
+ gTasks[taskId].data[0] = 0;
+ gTasks[taskId].data[1] = 0x150;
+ gTasks[taskId].data[2] = 0x50;
+ gTasks[taskId].data[6] = 0x10;
+ gTasks[taskId].data[3] = 0x100;
+ sub_816F2A8(0x150, 0x50, 0x100, 0);
+ ScanlineEffect_InitWave(0, 0xA0, 4, 4, 1, 6, 0);
+}
+
+static void Task_IntroFadeIn0(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ sub_816F2A8(data[1], data[2], data[3], 0);
+
+ switch (data[0])
+ {
+ case 0:
+ if (--data[6] != 0)
+ break;
+ data[0]++;
+ case 1:
+ data[6] += 4;
+ gTasks[taskId].data[1] = 0x158 - Sin(data[6], 0x100);
+ gTasks[taskId].data[2] = 0x54 - Cos(data[6], 0x40);
+ if (data[6] == 0x40)
+ {
+ data[6] = 0x19;
+ data[7] = 1;
+ data[0]++;
+ sub_816E6D4(0);
+ }
+ break;
+ case 2:
+ if (--data[6] == 0)
+ {
+ gTasks[taskId].data[1] += 0x100;
+ gTasks[taskId].data[2] -= 0x102;
+ data[6] = 8;
+ data[0]++;
+ sub_816E6D4(0);
+ sub_816E74C();
+ }
+ break;
+ case 3:
+ if (--data[6] == 0)
+ {
+ gTasks[taskId].data[1] -= 0x100;
+ gTasks[taskId].data[2] += 0x102;
+ data[6] = 8;
+ data[0]++;
+ }
+ break;
+ case 4:
+ if (--data[6] == 0)
+ {
+ gTasks[taskId].data[2] -= 0xFC;
+ data[6] = 8;
+ data[0]++;
+ }
+ break;
+ case 5:
+ if (--data[6] == 0)
+ {
+ gTasks[taskId].data[2] += 0xFC;
+ if (data[7] != 0)
+ {
+ data[6] = 12;
+ data[7]--;
+ data[0] = 2;
+ }
+ else
+ {
+ data[6] = 1;
+ data[0]++;
+ PlayCryInternal(SPECIES_KYOGRE, 0, 120, 10, 0);
+ }
+ }
+ break;
+ case 6:
+ if (--data[6] == 0)
+ {
+ data[6] = 4;
+ data[7] = 0x1EA;
+ data[0]++;
+ }
+ break;
+ case 7:
+ if (--data[6] == 0)
+ {
+ data[6] = 4;
+ CpuCopy16(&gIntro3BgPal[data[7]], &gPlttBufferFaded[47], sizeof(u16));
+ data[7] -= 2;
+ if (data[7] == 0x1E0)
+ data[0]++;
+ }
+ break;
+ case 8:
+ if (--data[6] == 0)
+ {
+ data[6] = 4;
+ data[7] = 0x1E2;
+ data[0]++;
+ }
+ break;
+ case 9:
+ if (--data[6] == 0)
+ {
+ data[6] = 4;
+ CpuCopy16(&gIntro3BgPal[data[7]], &gPlttBufferFaded[47], sizeof(u16));
+ data[7] += 2;
+ if (data[7] == 0x1EE)
+ {
+ data[6] = 0x10;
+ data[0]++;
+ }
+ }
+ break;
+ case 10:
+ if (--data[6] == 0)
+ {
+ data[6] = 0;
+ data[0]++;
+ sub_816E6D4(taskId);
+ }
+ break;
+ case 11:
+ data[6] += 4;
+ data[3] -= 8;
+ gTasks[taskId].data[1] = Sin(data[6], 0x3C) + 0x58;
+ if (data[6] == 0x40)
+ {
+ BeginNormalPaletteFade(0xFFFFFFFE, 3, 0, 16, RGB_WHITE);
+ data[0]++;
+ }
+ break;
+ case 12:
+ data[6] += 4;
+ data[3] -= 8;
+ gTasks[taskId].data[1] = Sin(data[6], 0x14) + 0x80;
+ if (data[6] == 0x80)
+ data[0]++;
+ break;
+ case 13:
+ if (!gPaletteFade.active)
+ {
+ gTasks[taskId].func = Task_IntroFadeIn1;
+ gScanlineEffect.state = 3;
+ }
+ break;
+ }
+}
+
+static void sub_816E6D4(u8 a0)
+{
+ int i;
+ u8 spriteId;
+
+ for (i = 0; i < 6; i++)
+ {
+ spriteId = CreateSprite(&gUnknown_085E4D14, gUnknown_085E4CA8[i][0], gUnknown_085E4CA8[i][1], i);
+ gSprites[spriteId].invisible = TRUE;
+ gSprites[spriteId].data[5] = a0;
+ gSprites[spriteId].data[6] = gUnknown_085E4CA8[i][2];
+ gSprites[spriteId].data[7] = 0x40;
+ }
+}
+
+static void sub_816E74C(void)
+{
+ int i;
+ u8 spriteId;
+
+ for (i = 0; i < 6; i++)
+ {
+ spriteId = CreateSprite(&gUnknown_085E4D14, gUnknown_085E4CA8[i + 6][0], gUnknown_085E4CA8[i + 6][1], i);
+ gSprites[spriteId].invisible = TRUE;
+ gSprites[spriteId].data[6] = gUnknown_085E4CA8[i][2];
+ gSprites[spriteId].data[7] = 0x40;
+ }
+}
+
+static void sub_816E7B4(struct Sprite *sprite)
+{
+ switch(sprite->data[0])
+ {
+ case 0:
+ if (sprite->data[6] == 0)
+ {
+ sprite->data[1] = (sprite->data[1] + 11) & 0xFF;
+ sprite->pos2.x = Sin(sprite->data[1], 4);
+ sprite->data[2] += 0x30;
+ sprite->pos2.y = -(sprite->data[2] >> 8);
+ if (sprite->animEnded)
+ DestroySprite(sprite);
+ }
+ else if (--sprite->data[6] == 0)
+ {
+ StartSpriteAnim(sprite, 0);
+ sprite->invisible = FALSE;
+ }
+ if (gTasks[sprite->data[5]].data[0] > 11)
+ sprite->data[0]++;
+ break;
+ case 1:
+ if (sprite->pos1.x < 120)
+ sprite->pos1.x -= 3;
+ else
+ sprite->pos1.x += 3;
+
+ if (sprite->pos1.y < 80)
+ sprite->pos1.y -= 3;
+ else
+ sprite->pos1.y += 3;
+ if ((u16)(sprite->pos1.y - 20) > 140)
+ DestroySprite(sprite);
+ break;
+ }
+}
+
+static void Task_IntroFadeIn1(u8 taskId)
+{
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG0
+ | BLDCNT_TGT1_BG1
+ | BLDCNT_TGT1_BG2
+ | BLDCNT_EFFECT_LIGHTEN);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(31, 31));
+ SetGpuReg(REG_OFFSET_BLDY, 31);
+ SetGpuReg(REG_OFFSET_BG0CNT, BGCNT_PRIORITY(0)
+ | BGCNT_CHARBASE(0)
+ | BGCNT_SCREENBASE(24)
+ | BGCNT_16COLOR
+ | BGCNT_TXT512x256);
+ SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(0)
+ | BGCNT_CHARBASE(1)
+ | BGCNT_SCREENBASE(26)
+ | BGCNT_16COLOR
+ | BGCNT_TXT512x256);
+ SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(2)
+ | BGCNT_CHARBASE(1)
+ | BGCNT_SCREENBASE(28)
+ | BGCNT_16COLOR
+ | BGCNT_TXT256x256);
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0
+ | DISPCNT_OBJ_1D_MAP
+ | DISPCNT_BG0_ON
+ | DISPCNT_BG1_ON
+ | DISPCNT_BG2_ON
+ | DISPCNT_OBJ_ON
+ | DISPCNT_WIN0_ON);
+ SetGpuReg(REG_OFFSET_BG0HOFS, 80);
+ SetGpuReg(REG_OFFSET_BG0VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1HOFS, -80);
+ SetGpuReg(REG_OFFSET_BG1VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG2HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG2VOFS, 0);
+ LZDecompressVram(gIntro3CloudsGfx, (void *)VRAM);
+ LZDecompressVram(gIntro3CloudsGfx, (void *)(VRAM + 0x4000));
+ LZDecompressVram(gIntro3Clouds3Tilemap, (void *)(VRAM + 0xE000));
+ gTasks[taskId].func = Task_IntroFadeIn2;
+}
+
+static void Task_IntroFadeIn2(u8 taskId)
+{
+ LZDecompressVram(gIntro3Clouds1Tilemap, (void *)(VRAM + 0xC000));
+ LZDecompressVram(gIntro3Clouds2Tilemap, (void *)(VRAM + 0xD000));
+ gTasks[taskId].func = Task_IntroFadeIn3;
+}
+
+static void Task_IntroFadeIn3(u8 taskId)
+{
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ gTasks[taskId].func = Task_IntroFadeIn4;
+ gTasks[taskId].data[0] = 0;
+ gTasks[taskId].data[6] = 16;
+}
+
+static void Task_IntroFadeIn4(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ SetGpuReg(REG_OFFSET_BG0HOFS, (data[6] >> 8));
+ SetGpuReg(REG_OFFSET_BG1HOFS, -(data[6] >> 8));
+
+ switch (data[0])
+ {
+ case 0:
+ if (--data[6] == 0)
+ {
+ BeginNormalPaletteFade(0xFFFFFFFE, 0, 16, 0, RGB_WHITEALPHA);
+ data[6] = 0x5000;
+ data[0]++;
+ }
+ break;
+ case 1:
+ if (data[6] == 0x2800)
+ BeginNormalPaletteFade(0x0000FFFE, 3, 0, 16, RGB(9, 10, 10));
+
+ if (data[6] != 0)
+ data[6] -= 0x80;
+ else if (!gPaletteFade.active)
+ gTasks[taskId].func = Task_IntroFadeIn5;
+ break;
+ }
+}
+
+static void Task_IntroFadeIn5(u8 taskId)
+{
+ LZDecompressVram(gIntro3RayquazaTilemap, (void *)(VRAM + 0xE000));
+ LZDecompressVram(gIntro3Clouds4Tilemap, (void *)(VRAM + 0xC000));
+ LZDecompressVram(gIntro3RayquazaGfx, (void *)(VRAM + 0x4000));
+ LZDecompressVram(gIntro3Clouds2Gfx, (void *)VRAM);
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0
+ | DISPCNT_OBJ_1D_MAP
+ | DISPCNT_BG0_ON
+ | DISPCNT_BG2_ON
+ | DISPCNT_OBJ_ON
+ | DISPCNT_WIN0_ON);
+ gTasks[taskId].func = Task_IntroFadeIn6;
+ gTasks[taskId].data[0] = 0;
+ gTasks[taskId].data[6] = 1;
+ gTasks[taskId].data[7] = 0;
+ LoadCompressedObjectPicUsingHeap(gUnknown_085E4BF4);
+ LoadSpritePalettes(gUnknown_085E4C04);
+}
+
+static void Task_IntroFadeIn6(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ u8 spriteId;
+
+ switch (data[0])
+ {
+ case 0:
+ if (--data[6] == 0)
+ {
+ CreateSprite(&gUnknown_085E4C4C, 200, 48, 0);
+ spriteId = CreateSprite(&gUnknown_085E4C4C, 200, 80, 1);
+ StartSpriteAnim(&gSprites[spriteId], 1);
+ spriteId = CreateSprite(&gUnknown_085E4C4C, 200, 112, 2);
+ StartSpriteAnim(&gSprites[spriteId], 2);
+ data[0]++;
+ data[6] = 72;
+ }
+ break;
+ case 1:
+ if (--data[6] == 0)
+ {
+ CreateSprite(&gUnknown_085E4C4C, 40, 48, 0);
+ spriteId = CreateSprite(&gUnknown_085E4C4C, 40, 80, 1);
+ StartSpriteAnim(&gSprites[spriteId], 1);
+ spriteId = CreateSprite(&gUnknown_085E4C4C, 40, 112, 2);
+ StartSpriteAnim(&gSprites[spriteId], 2);
+ data[0]++;
+ data[6] = 48;
+ }
+ break;
+ case 2:
+ if (--data[6] == 0)
+ gTasks[taskId].func = Task_IntroFadeIn7;
+ break;
+ }
+}
+
+static void sub_816EC6C(struct Sprite *sprite)
+{
+ if (sprite->animEnded)
+ sprite->invisible = TRUE;
+
+ switch(sprite->data[0])
+ {
+ case 0:
+ sprite->data[1] = 0x1C2;
+ sprite->data[0]++;
+ case 1:
+ CpuCopy16(&gIntro3BgPal[sprite->data[1]], &gPlttBufferFaded[93], 2);
+ sprite->data[1] += 2;
+ if (sprite->data[1] != 0x1CE)
+ break;
+ sprite->data[1] = 0x1CC;
+ sprite->data[2] = 4;
+ sprite->data[0]++;
+ case 2:
+ if (--sprite->data[2] == 0)
+ {
+ sprite->data[2] = 4;
+ CpuCopy16(&gIntro3BgPal[sprite->data[1]], &gPlttBufferFaded[93], 2);
+ sprite->data[1] -= 2;
+ if (sprite->data[1] == 0x1C0)
+ DestroySprite(sprite);
+ }
+ break;
+ }
+}
+
+static void Task_IntroFadeIn7(u8 taskId)
+{
+ u8 newTaskId;
+
+ LoadCompressedObjectPic(gUnknown_085E5048);
+ LoadSpritePalettes(gUnknown_085E5058);
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0
+ | DISPCNT_OBJ_1D_MAP
+ | DISPCNT_BG0_ON
+ | DISPCNT_BG2_ON
+ | DISPCNT_OBJ_ON
+ | DISPCNT_WIN0_ON);
+ gTasks[taskId].func = Task_IntroFadeIn8;
+ BeginNormalPaletteFade(0x0000FFDE, 0, 16, 0, RGB(9, 10, 10));
+ gTasks[taskId].data[0] = 0;
+ gTasks[taskId].data[1] = 0xA8;
+ gTasks[taskId].data[2] = -0x10;
+ gTasks[taskId].data[3] = -0x88;
+ gTasks[taskId].data[4] = -0x10;
+ newTaskId = CreateTask(sub_816EEA8, 0);
+ gTasks[newTaskId].data[4] = taskId;
+}
+
+static void Task_IntroFadeIn8(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ if (data[7] % 2 == 0)
+ data[6] ^= 2;
+
+ data[7]++;
+
+ switch(data[0])
+ {
+ case 0:
+ if ((data[7] & 1) != 0)
+ {
+ data[1] -= 2;
+ data[2]++;
+ data[3] += 2;
+ data[4]++;
+ }
+ if (data[1] == 0x68)
+ {
+ data[0]++;
+ data[5] = 1;
+ }
+ break;
+ case 1:
+ data[0]++;
+ data[5] = 4;
+ break;
+ case 2:
+ data[1] += 4;
+ data[2] -= 2;
+ data[3] -= 4;
+ data[4] -= 2;
+ if (!gPaletteFade.active)
+ {
+ data[5] = 0x8C;
+ data[0]++;
+ }
+ break;
+ case 3:
+ if (--data[5] == 0)
+ gTasks[taskId].func = Task_IntroFadeIn9;
+ break;
+ }
+}
+
+static void Task_IntroFadeIn9(u8 taskId)
+{
+ DestroyTask(taskId);
+ SetMainCallback2(MainCB2_EndIntro);
+}
+
+static void sub_816EEA8(u8 taskId)
+{
+ u8 spriteId;
+ s16 *data = gTasks[taskId].data;
+
+ data[2]++;
+
+ switch(data[0])
+ {
+ case 0:
+ if ((data[2] & 1) != 0)
+ {
+ CpuCopy16(&gIntro3BgPal[0x1A2 + data[1] * 2], &gPlttBufferFaded[94], 2);
+ data[1]++;
+ }
+ if (data[1] == 6)
+ {
+ data[0]++;
+ data[1] = 0;
+ data[3] = 10;
+ }
+ break;
+ case 1:
+ if (data[3] == 0)
+ {
+ if ((data[2] & 1) != 0)
+ {
+ CpuCopy16(&gIntro3BgPal[0x1A2 + data[1] * 2], &gPlttBufferFaded[88], 2);
+ data[1]++;
+ }
+ if (data[1] == 6)
+ {
+ data[0]++;
+ data[3] = 10;
+ }
+ }
+ else
+ {
+ data[3]--;
+ }
+ break;
+ case 2:
+ if (data[3] == 0)
+ {
+ if ((data[2] & 1) != 0)
+ {
+ CpuCopy16(&gIntro3BgPal[0x182 + data[1] * 2], &gPlttBufferFaded[92], 2);
+ data[1]++;
+ }
+ if (data[1] == 6)
+ {
+ spriteId = CreateSprite(&gUnknown_085E5030, 120, 88, 15);
+ PlaySE(SE_OP_BASYU);
+ gSprites[spriteId].invisible = TRUE;
+ gSprites[spriteId].data[3] = data[4];
+ data[0]++;
+ data[3] = 16;
+ }
+ }
+ else
+ {
+ data[3]--;
+ }
+ break;
+ case 3:
+ if ((data[2] & 1) != 0)
+ {
+ if (--data[3] != 0)
+ {
+ BlendPalette(0x50, 16, data[3], RGB(9, 10, 10));
+ CpuCopy16(&gIntro3BgPal[0x1AC], &gPlttBufferFaded[94], 2);
+ CpuCopy16(&gIntro3BgPal[0x1AC], &gPlttBufferFaded[88], 2);
+ CpuCopy16(&gIntro3BgPal[0x18C], &gPlttBufferFaded[92], 2);
+ }
+ else
+ {
+ data[0]++;
+ data[3] = 53;
+ }
+ }
+ break;
+ case 4:
+ if (--data[3] == 0)
+ {
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_WHITE);
+ data[0]++;
+ }
+ break;
+ case 5:
+ if (!gPaletteFade.active)
+ DestroyTask(taskId);
+ break;
+ }
+}
+
+static void intro_reset_and_hide_bgs(void)
+{
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ SetGpuReg(REG_OFFSET_BG3HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG3VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG2HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG2VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG0HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG0VOFS, 0);
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+}
+
+static void Task_IntroWaterDrops_1(u8 taskId)
+{
+ switch (gTasks[taskId].data[0])
+ {
+ case 0:
+ default:
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_BLEND
+ | BLDCNT_TGT2_BG0
+ | BLDCNT_TGT2_BG1
+ | BLDCNT_TGT2_BG2
+ | BLDCNT_TGT2_BG3
+ | BLDCNT_TGT2_OBJ
+ | BLDCNT_TGT2_BD);
+ SetGpuReg(REG_OFFSET_BLDALPHA, gUnknown_0853FF70[31]);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ gTasks[taskId].data[1] = 0x40;
+ gTasks[taskId].data[0]++;
+ break;
+ case 1:
+ if (gTasks[taskId].data[1] != 0)
+ {
+ u8 tmp;
+
+ gTasks[taskId].data[1]--;
+ tmp = gTasks[taskId].data[1] / 2;
+ SetGpuReg(REG_OFFSET_BLDALPHA, gUnknown_0853FF70[tmp]);
+ }
+ else
+ {
+ SetGpuReg(REG_OFFSET_BLDALPHA, gUnknown_0853FF70[0]);
+ gTasks[taskId].data[1] = 0x10;
+ gTasks[taskId].data[0]++;
+ }
+ break;
+ case 2:
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ DestroyTask(taskId);
+ break;
+ }
+}
+
+static void Task_IntroWaterDrops_2(u8 taskId)
+{
+ switch (gTasks[taskId].data[0])
+ {
+ case 0:
+ default:
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_BLEND
+ | BLDCNT_TGT2_BG0
+ | BLDCNT_TGT2_BG1
+ | BLDCNT_TGT2_BG2
+ | BLDCNT_TGT2_BG3
+ | BLDCNT_TGT2_OBJ
+ | BLDCNT_TGT2_BD);
+ SetGpuReg(REG_OFFSET_BLDALPHA, gUnknown_0853FF70[0]);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ gTasks[taskId].data[1] = 0;
+ gTasks[taskId].data[0]++;
+ break;
+ case 1:
+ if (gTasks[taskId].data[1] < 62)
+ {
+ u8 tmp;
+
+ gTasks[taskId].data[1]++;
+ tmp = gTasks[taskId].data[1] / 2;
+ SetGpuReg(REG_OFFSET_BLDALPHA, gUnknown_0853FF70[tmp]);
+ }
+ else
+ {
+ SetGpuReg(REG_OFFSET_BLDALPHA, gUnknown_0853FF70[31]);
+ gTasks[taskId].data[1] = 0x10;
+ gTasks[taskId].data[0]++;
+ }
+ break;
+ case 2:
+ if (gTasks[taskId].data[1] != 0)
+ {
+ gTasks[taskId].data[1]--;
+ }
+ else
+ {
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ DestroyTask(taskId);
+ }
+ break;
+ }
+}
+
+void sub_816F2A8(u16 scrX, u16 scrY, u16 zoom, u16 alpha)
+{
+ struct BgAffineSrcData src;
+ struct BgAffineDstData dest;
+
+ src.texX = 0x8000;
+ src.texY = 0x8000;
+ src.scrX = scrX;
+ src.scrY = scrY;
+ src.sx = zoom;
+ src.sy = zoom;
+ src.alpha = alpha;
+ BgAffineSet(&src, &dest, 1);
+ SetGpuReg(REG_OFFSET_BG2PA, dest.pa);
+ SetGpuReg(REG_OFFSET_BG2PB, dest.pb);
+ SetGpuReg(REG_OFFSET_BG2PC, dest.pc);
+ SetGpuReg(REG_OFFSET_BG2PD, dest.pd);
+ SetGpuReg(REG_OFFSET_BG2X_L, dest.dx);
+ SetGpuReg(REG_OFFSET_BG2X_H, dest.dx >> 16);
+ SetGpuReg(REG_OFFSET_BG2Y_L, dest.dy);
+ SetGpuReg(REG_OFFSET_BG2Y_H, dest.dy >> 16);
+}
+
+static void sub_816F318(struct Sprite *sprite)
+{
+ u8 r0;
+
+ if (sprite->data[2] >= 192)
+ {
+ if (sprite->data[3] != 0)
+ {
+ sprite->data[3]--;
+ }
+ else
+ {
+ sprite->invisible = FALSE;
+ SetOamMatrix(sprite->data[1], sprite->data[2], 0, 0, sprite->data[2]);
+ sprite->data[2] = (sprite->data[2] * 95) / 100;
+ r0 = (sprite->data[2] - 192) / 128 + 9;
+ if (r0 > 15)
+ r0 = 15;
+ sprite->oam.paletteNum = r0;
+ }
+ }
+ else
+ {
+ DestroySprite(sprite);
+ }
+}
+
+static void sub_816F3A4(struct Sprite *sprite)
+{
+ if (gSprites[sprite->data[7]].data[7] != 0)
+ {
+ sprite->invisible = TRUE;
+ sprite->pos1.x += sprite->pos2.x;
+ sprite->pos1.y += sprite->pos2.y;
+ StartSpriteAnim(sprite, 3);
+ sprite->data[2] = 1024;
+ sprite->data[3] = 8 * (sprite->data[1] & 3);
+ sprite->callback = sub_816F318;
+ sprite->oam.shape = 1;
+ sprite->oam.size = 3;
+ CalcCenterToCornerVec(sprite, 1, 3, 2);
+ }
+ else
+ {
+ sprite->pos2.x = gSprites[sprite->data[7]].pos2.x;
+ sprite->pos2.y = gSprites[sprite->data[7]].pos2.y;
+ sprite->pos1.x = gSprites[sprite->data[7]].pos1.x;
+ sprite->pos1.y = gSprites[sprite->data[7]].pos1.y;
+ }
+}
+
+static void sub_816F454(struct Sprite *sprite)
+{
+ if (sprite->data[0] != 0)
+ sprite->callback = sub_816F46C;
+}
+
+static void sub_816F46C(struct Sprite *sprite)
+{
+ if (sprite->pos1.x <= 116)
+ {
+ sprite->pos1.y += sprite->pos2.y;
+ sprite->pos2.y = 0;
+ sprite->pos1.x += 4;
+ sprite->pos2.x = -4;
+ sprite->data[4] = 128;
+ sprite->callback = sub_816F5B4;
+ }
+ else
+ {
+ u16 data2;
+ u16 data3;
+ u16 data4;
+ s16 sin1;
+ s16 sin2;
+ s16 sin3;
+ s16 sin4;
+ s16 var1;
+ s16 var2;
+ s16 var3;
+ s16 var4;
+ s16 temp;
+
+ data4 = sprite->data[4];
+ sin1 = gSineTable[(u8)data4];
+ sin2 = gSineTable[(u8)(data4 + 64)];
+ sprite->data[4] += 2;
+ sprite->pos2.y = sin1 / 32;
+ sprite->pos1.x--;
+ if (sprite->pos1.x & 1)
+ sprite->pos1.y++;
+ temp = -sin2 / 16;
+ data2 = sprite->data[2];
+ data3 = sprite->data[3];
+ sin3 = gSineTable[(u8)(temp - 16)];
+ sin4 = gSineTable[(u8)(temp + 48)];
+ var1 = sin4 * data2 / 256;
+ var2 = -sin3 * data3 / 256;
+ var3 = sin3 * data2 / 256;
+ var4 = sin4 * data3 / 256;
+ SetOamMatrix(sprite->data[1], data2, 0, 0, data3);
+ SetOamMatrix(sprite->data[1] + 1, var1, var3, var2, var4);
+ SetOamMatrix(sprite->data[1] + 2, var1, var3, var2 * 2, var4 * 2);
+ }
+}
+
+static void sub_816F5B4(struct Sprite *sprite)
+{
+ SetOamMatrix(sprite->data[1], sprite->data[6] + 64, 0, 0, sprite->data[6] + 64);
+ SetOamMatrix(sprite->data[1] + 1, sprite->data[6] + 64, 0, 0, sprite->data[6] + 64);
+ SetOamMatrix(sprite->data[1] + 2, sprite->data[6] + 64, 0, 0, sprite->data[6] + 64);
+ if (sprite->data[4] != 64)
+ {
+ u16 data4;
+
+ sprite->data[4] -= 8;
+ data4 = sprite->data[4];
+ sprite->pos2.x = gSineTable[(u8)(data4 + 64)] / 64;
+ sprite->pos2.y = gSineTable[(u8)data4] / 64;
+ }
+ else
+ {
+ sprite->data[4] = 0;
+ sprite->callback = sub_816F660;
+ }
+}
+
+static void sub_816F660(struct Sprite *sprite)
+{
+ if (sprite->data[0] != 2)
+ {
+ s16 r2;
+
+ sprite->data[4] += 8;
+ r2 = gSineTable[(u8)sprite->data[4]] / 16 + 64;
+ sprite->pos2.x = gSineTable[(u8)(r2 + 64)] / 64;
+ sprite->pos2.y = gSineTable[(u8)r2] / 64;
+ }
+ else
+ {
+ sprite->callback = SpriteCB_WaterDropFall;
+ }
+}
+
+static void SpriteCB_WaterDropFall(struct Sprite *sprite)
+{
+ if (sprite->pos1.y < sprite->data[5])
+ {
+ sprite->pos1.y += 4;
+ }
+ else
+ {
+ sprite->data[7] = 1;
+ sprite->invisible = TRUE;
+ sprite->pos1.x += sprite->pos2.x;
+ sprite->pos1.y += sprite->pos2.y;
+ StartSpriteAnim(sprite, 3);
+ sprite->data[2] = 1024;
+ sprite->data[3] = 8 * (sprite->data[1] & 3);
+ sprite->callback = sub_816F318;
+ sprite->oam.shape = 1;
+ sprite->oam.size = 3;
+ CalcCenterToCornerVec(sprite, 1, 3, 2);
+ }
+}
+
+//Duplicate function
+static void SpriteCB_WaterDropFall_2(struct Sprite *sprite)
+{
+ if (sprite->pos1.y < sprite->data[5])
+ {
+ sprite->pos1.y += 4;
+ }
+ else
+ {
+ sprite->data[7] = 1;
+ sprite->invisible = TRUE;
+ sprite->pos1.x += sprite->pos2.x;
+ sprite->pos1.y += sprite->pos2.y;
+ StartSpriteAnim(sprite, 3);
+ sprite->data[2] = 1024;
+ sprite->data[3] = 8 * (sprite->data[1] & 3);
+ sprite->callback = sub_816F318;
+ sprite->oam.shape = 1;
+ sprite->oam.size = 3;
+ CalcCenterToCornerVec(sprite, 1, 3, 2);
+ }
+}
+
+static u8 CreateWaterDrop(s16 x, s16 y, u16 c, u16 d, u16 e, u8 fallImmediately)
+{
+ u8 spriteId;
+ u8 oldSpriteId;
+
+ spriteId = CreateSprite(&gUnknown_085E4D64, x, y, 1);
+ gSprites[spriteId].data[0] = 0;
+ gSprites[spriteId].data[7] = 0;
+ gSprites[spriteId].data[1] = d;
+ gSprites[spriteId].data[2] = c;
+ gSprites[spriteId].data[3] = c;
+ gSprites[spriteId].data[5] = e;
+ gSprites[spriteId].data[6] = c;
+ gSprites[spriteId].oam.affineMode = 3;
+ gSprites[spriteId].oam.matrixNum = d;
+ CalcCenterToCornerVec(&gSprites[spriteId], 0, 2, 2);
+ StartSpriteAnim(&gSprites[spriteId], 2);
+ if (!fallImmediately)
+ gSprites[spriteId].callback = sub_816F454;
+ else
+ gSprites[spriteId].callback = SpriteCB_WaterDropFall_2;
+ oldSpriteId = spriteId;
+
+ spriteId = CreateSprite(&gUnknown_085E4D64, x, y, 1);
+ gSprites[spriteId].data[7] = oldSpriteId;
+ gSprites[spriteId].data[1] = d + 1;
+ gSprites[spriteId].oam.affineMode = 3;
+ gSprites[spriteId].oam.matrixNum = d + 1;
+ CalcCenterToCornerVec(&gSprites[spriteId], 0, 2, 2);
+ gSprites[spriteId].callback = sub_816F3A4;
+
+ spriteId = CreateSprite(&gUnknown_085E4D64, x, y, 1);
+ gSprites[spriteId].data[7] = oldSpriteId;
+ gSprites[spriteId].data[1] = d + 2;
+ StartSpriteAnim(&gSprites[spriteId], 1);
+ gSprites[spriteId].oam.affineMode = 3;
+ gSprites[spriteId].oam.matrixNum = d + 2;
+ CalcCenterToCornerVec(&gSprites[spriteId], 0, 2, 2);
+ gSprites[spriteId].callback = sub_816F3A4;
+
+ SetOamMatrix(d, c + 32, 0, 0, c + 32);
+ SetOamMatrix(d + 1, c + 32, 0, 0, c + 32);
+ SetOamMatrix(d + 2, c + 32, 0, 0, 2 * (c + 32));
+
+ return oldSpriteId;
+}
+
+static void sub_816F9D4(struct Sprite *sprite)
+{
+ switch (sprite->data[0])
+ {
+ case 0:
+ StartSpriteAnimIfDifferent(sprite, 0);
+ sprite->pos1.x--;
+ break;
+ case 1:
+ StartSpriteAnimIfDifferent(sprite, 0);
+ if (gIntroFrameCounter & 7)
+ return;
+ sprite->pos1.x++;
+ break;
+ case 2:
+ if (sprite->pos1.x <= 120 || gIntroFrameCounter & 7)
+ sprite->pos1.x++;
+ break;
+ case 3:
+ break;
+ case 4:
+ if (sprite->pos1.x > -32)
+ sprite->pos1.x -= 2;
+ break;
+ }
+ if (gIntroFrameCounter & 7)
+ return;
+ if (sprite->pos2.y != 0)
+ {
+ sprite->pos2.y = 0;
+ }
+ else
+ {
+ switch (Random() & 3)
+ {
+ case 0:
+ sprite->pos2.y = -1;
+ break;
+ case 1:
+ sprite->pos2.y = 1;
+ break;
+ case 2:
+ case 3:
+ sprite->pos2.y = 0;
+ break;
+ }
+ }
+}
+
+static void sub_816FAB0(struct Sprite *sprite)
+{
+ switch (sprite->data[0])
+ {
+ case 0:
+ break;
+ case 1:
+ if (sprite->pos2.x + sprite->pos1.x < 304)
+ sprite->pos2.x += 8;
+ else
+ sprite->data[0] = 2;
+ break;
+ case 2:
+ if (sprite->pos2.x + sprite->pos1.x > 120)
+ sprite->pos2.x -= 1;
+ else
+ sprite->data[0] = 3;
+ break;
+ case 3:
+ if (sprite->pos2.x > 0)
+ sprite->pos2.x -= 2;
+ break;
+ }
+ sprite->pos2.y = Sin((u8)sprite->data[1], 8) - gUnknown_0203BCCC;
+ sprite->data[1] += 4;
+}
+
+static void sub_816FB38(struct Sprite *sprite)
+{
+ switch (sprite->data[0])
+ {
+ case 0:
+ if (sprite->data[1] != 0)
+ {
+ sprite->data[1]--;
+ }
+ else
+ {
+ sprite->invisible = FALSE;
+ StartSpriteAffineAnim(sprite, 1);
+ sprite->data[0]++;
+ }
+ break;
+ case 1:
+ if (gIntroFrameCounter == 0x90)
+ {
+ sprite->data[0]++;
+ sprite->data[1] = 9;
+ sprite->data[3] = 2;
+ }
+ break;
+ case 2:
+ if (sprite->data[3] == 0)
+ {
+ sprite->data[3] = 2;
+ if (sprite->data[1] != 0)
+ {
+ CpuCopy16(&gIntro1GameFreakTextFadePal[sprite->data[1]], &gPlttBufferFaded[0x11F], 2);
+ CpuCopy16(&gIntro1GameFreakTextFadePal[sprite->data[1] + 0x10], &gPlttBufferFaded[0x114], 2);
+ CpuCopy16(&gIntro1GameFreakTextFadePal[sprite->data[1] + 0x20], &gPlttBufferFaded[0x11A], 2);
+ sprite->data[1]--;
+ }
+ else
+ {
+ CpuCopy16(&gIntro1GameFreakTextFadePal[sprite->data[1]], &gPlttBufferFaded[0x11F], 2);
+ CpuCopy16(&gIntro1GameFreakTextFadePal[sprite->data[1] + 0x10], &gPlttBufferFaded[0x114], 2);
+ CpuCopy16(&gIntro1GameFreakTextFadePal[sprite->data[1] + 0x20], &gPlttBufferFaded[0x11A], 2);
+ sprite->data[0]++;
+ }
+ }
+ else
+ {
+ sprite->data[3]--;
+ }
+ break;
+ case 3:
+ if (sprite->data[3] != 0)
+ {
+ sprite->data[3]--;
+ }
+ else
+ {
+ sprite->data[3] = 2;
+ if (sprite->data[1] < 10)
+ {
+ CpuCopy16(&gIntro1GameFreakTextFadePal[sprite->data[1]], &gPlttBufferFaded[0x11F], 2);
+ CpuCopy16(&gIntro1GameFreakTextFadePal[sprite->data[1] + 0x10], &gPlttBufferFaded[0x114], 2);
+ CpuCopy16(&gIntro1GameFreakTextFadePal[sprite->data[1] + 0x20], &gPlttBufferFaded[0x11A], 2);
+ sprite->data[1]++;
+ }
+ else
+ {
+ sprite->data[0]++;
+ }
+ }
+ break;
+ case 4:
+ if (gIntroFrameCounter == 0x110)
+ {
+ StartSpriteAffineAnim(sprite, 2);
+ sprite->oam.objMode = 1;
+ sprite->data[0]++;
+ }
+ break;
+ case 5:
+ sprite->data[3] += gUnknown_085E4F48[sprite->data[2]];
+ sprite->pos2.x = (sprite->data[3] & 0xFF00) >> 8;
+ if (sprite->data[2] < 4)
+ {
+ s16 temp = sprite->pos2.x;
+ sprite->pos2.x = -temp;
+ }
+ if (sprite->affineAnimEnded)
+ DestroySprite(sprite);
+ break;
+ }
+}
+
+static void sub_816FD44(struct Sprite *sprite)
+{
+ switch(sprite->data[0])
+ {
+ case 0:
+ if (gIntroFrameCounter == 0x80)
+ {
+ sprite->invisible = FALSE;
+ sprite->data[0]++;
+ }
+ break;
+ case 1:
+ if (gIntroFrameCounter == 0x110)
+ {
+ StartSpriteAffineAnim(sprite, 3);
+ sprite->data[0]++;
+ }
+ break;
+ case 2:
+ if (sprite->affineAnimEnded)
+ DestroySprite(sprite);
+ break;
+ }
+}
+
+static u8 sub_816FDB8(s16 a0, s16 a1, s16 a2)
+{
+ u16 i;
+ u8 spriteId;
+
+ for (i = 0; i < 9; i++)
+ {
+ spriteId = CreateSprite(&gUnknown_085E4F5C, gUnknown_085E4E94[i][1] + a0, a1 - 4, 0);
+ gSprites[spriteId].data[0] = 0;
+ gSprites[spriteId].data[1] = gUnknown_085E4FA4[i];
+ gSprites[spriteId].data[2] = i;
+ gSprites[spriteId].invisible = TRUE;
+ gSprites[spriteId].oam.matrixNum = i + 12;
+ StartSpriteAnim(&gSprites[spriteId], gUnknown_085E4E94[i][0]);
+ StartSpriteAffineAnim(&gSprites[spriteId], 0);
+ }
+ spriteId = CreateSprite(&gUnknown_085E4F8C, 120, a1 - 6, 0);
+ gSprites[spriteId].data[0] = 0;
+ gSprites[spriteId].invisible = TRUE;
+ gSprites[spriteId].oam.matrixNum = i + 12;
+ StartSpriteAffineAnim(&gSprites[spriteId], 1);
+ return spriteId;
+}
+
+static void sub_816FEDC(struct Sprite *sprite)
+{
+ sprite->data[7]++;
+
+ if (sprite->data[0] != 0)
+ {
+ s16 sin1;
+ s16 sin2;
+
+ s16 a, b, c, d;
+
+ sin1 = gSineTable[(u8)sprite->data[2]];
+ sin2 = gSineTable[(u8)(sprite->data[2] + 64)];
+
+ d = Q_8_8_TO_INT(sin2 * sprite->data[1]);
+ c = Q_8_8_TO_INT(-sin1 * sprite->data[1]);
+ b = Q_8_8_TO_INT(sin1 * sprite->data[1]);
+ a = Q_8_8_TO_INT(sin2 * sprite->data[1]);
+
+ SetOamMatrix(1, a, b, c, d);
+ }
+
+ switch (sprite->data[0])
+ {
+ case 0:
+ default:
+ sprite->oam.affineMode = 3;
+ sprite->oam.matrixNum = 1;
+ CalcCenterToCornerVec(sprite, 1, 3, 3);
+ sprite->invisible = FALSE;
+ sprite->data[0] = 1;
+ sprite->data[1] = 0x80;
+ sprite->data[2] = 0;
+ sprite->data[3] = 0;
+ break;
+ case 1:
+ sprite->pos2.x = -Sin((u8)sprite->data[3], 140);
+ sprite->pos2.y = -Sin((u8)sprite->data[3], 120);
+ sprite->data[1] += 7;
+ sprite->data[3] += 3;
+ if (sprite->pos1.x + sprite->pos2.x <= -16)
+ {
+ sprite->oam.priority = 3;
+ sprite->data[0]++;
+ sprite->pos1.x = 20;
+ sprite->pos1.y = 40;
+ sprite->data[1] = 0x200;
+ sprite->data[2] = 0;
+ sprite->data[3] = 0x10;
+ }
+ break;
+ case 2:
+ sprite->pos2.x = Sin((u8)sprite->data[3], 34);
+ sprite->pos2.y = -Cos((u8)sprite->data[3], 60);
+ sprite->data[1] += 2;
+ if (sprite->data[7] % 5 == 0)
+ sprite->data[3]++;
+ break;
+ }
+}
+
+static void sub_8170040(struct Sprite *sprite)
+{
+ u16 foo;
+
+ //I'm not sure why a switch statement was used here.
+ //if (sprite->data[0] != 1) would have been more appropriate.
+ switch (sprite->data[0])
+ {
+ case 0:
+ default:
+ sprite->invisible = FALSE;
+ sprite->oam.affineMode = 3;
+ sprite->oam.matrixNum = 18;
+ CalcCenterToCornerVec(sprite, 0, 3, 3);
+ sprite->data[1] = 0;
+ sprite->data[0] = 1;
+ //fall through
+ case 1:
+ sprite->data[7]++;
+ if (sprite->data[7] & 1)
+ {
+ sprite->invisible = TRUE;
+ }
+ else
+ {
+ sprite->invisible = FALSE;
+ if (sprite->data[1] < 64)
+ sprite->data[1]++;
+ }
+ foo = 256 - gSineTable[(u8)sprite->data[1]] / 2;
+ SetOamMatrix(18, foo, 0, 0, foo);
+ break;
+ }
+}
diff --git a/src/intro_credits_graphics.c b/src/intro_credits_graphics.c
new file mode 100644
index 000000000..d570b2992
--- /dev/null
+++ b/src/intro_credits_graphics.c
@@ -0,0 +1,740 @@
+#include "global.h"
+#include "intro_credits_graphics.h"
+#include "palette.h"
+#include "decompress.h"
+#include "gpu_regs.h"
+#include "task.h"
+#include "main.h"
+#include "graphics.h"
+
+struct IntroCreditsSpriteMetadata
+{
+ u8 animNum:4;
+ u8 shape:2;
+ u8 size:2;
+ u8 x;
+ u8 y;
+ u8 subpriority;
+ u16 xOff;
+};
+
+static const u16 gUnknown_085F06E0[] = INCBIN_U16("graphics/intro/intro2_grass.gbapal");
+static const u16 gUnknown_085F0700[] = INCBIN_U16("graphics/intro/intro2_grass_afternoon.gbapal");
+static const u16 gUnknown_085F0720[] = INCBIN_U16("graphics/intro/intro2_grass_night.gbapal");
+static const u8 gUnknown_085F0740[] = INCBIN_U8("graphics/intro/intro2_grass.4bpp.lz");
+static const u8 gUnknown_085F0BC0[] = INCBIN_U8("graphics/intro/intro2_grass_map.bin.lz");
+static const u16 gUnknown_085F0CFC[] = INCBIN_U16("graphics/intro/85F0CFC.gbapal");
+static const u16 gUnknown_085F0D5C[] = INCBIN_U16("graphics/intro/85F0D5C.gbapal");
+static const u8 gUnknown_085F0DBC[] = INCBIN_U8("graphics/intro/intro2_bgclouds.4bpp.lz");
+static const u8 gUnknown_085F1398[] = INCBIN_U8("graphics/intro/intro2_bgclouds_map.bin.lz");
+static const u16 gUnknown_085F1668[] = INCBIN_U16("graphics/intro/intro2_bgclouds.gbapal");
+static const u16 gUnknown_085F1688[] = INCBIN_U16("graphics/intro/intro2_bgclouds_afternoon.gbapal");
+static const u8 gUnknown_085F16A8[] = INCBIN_U8("graphics/intro/intro2_bgclouds2.4bpp.lz");
+static const u16 gUnknown_085F17E4[] = INCBIN_U16("graphics/intro/intro2_bgtrees2.gbapal");
+static const u16 gUnknown_085F1804[] = INCBIN_U16("graphics/intro/intro2_bgtrees2_afternoon.gbapal");
+static const u8 gUnknown_085F1824[] = INCBIN_U8("graphics/intro/intro2_bgtrees.4bpp.lz");
+static const u8 gUnknown_085F1EAC[] = INCBIN_U8("graphics/intro/intro2_bgtrees_map.bin.lz");
+static const u16 gUnknown_085F21B0[] = INCBIN_U16("graphics/intro/intro2_bgtrees.gbapal");
+static const u8 gIntro2TreeTiles[] = INCBIN_U8("graphics/intro/intro2_bgtreessmall.4bpp.lz");
+static const u16 gUnknown_085F231C[] = INCBIN_U16("graphics/intro/85F231C.gbapal");
+static const u8 gUnknown_085F235C[] = INCBIN_U8("graphics/intro/intro2_bgnight.4bpp.lz");
+static const u16 gUnknown_085F2548[] = INCBIN_U16("graphics/intro/intro2_bgnight.gbapal");
+static const u8 gUnknown_085F2568[] = INCBIN_U8("graphics/intro/intro2_bgnight_map.bin.lz");
+static const u8 gIntro2NightTiles[] = INCBIN_U8("graphics/intro/intro2_night.4bpp.lz");
+static const u16 gIntro2BrendanPalette[] = INCBIN_U16("graphics/intro/intro2_brendan.gbapal");
+static const u8 gIntro2BrendanTiles[] = INCBIN_U8("graphics/intro/intro2_brendan.4bpp.lz");
+static const u16 gIntro2MayPalette[] = INCBIN_U16("graphics/intro/intro2_may.gbapal");
+static const u16 gUnknown_085F3490[0xF0] = {0};
+static const u8 gIntro2MayTiles[] = INCBIN_U8("graphics/intro/intro2_may.4bpp.lz");
+static const u8 gIntro2BicycleTiles[] = INCBIN_U8("graphics/intro/intro2_bicycle.4bpp.lz");
+static const u16 gIntro2LatiosPalette[] = INCBIN_U16("graphics/intro/intro2_latios.gbapal");
+static const u8 gIntro2LatiosTiles[] = INCBIN_U8("graphics/intro/intro2_latios.4bpp.lz");
+static const u16 gIntro2LatiasPalette[] = INCBIN_U16("graphics/intro/intro2_latias.gbapal");
+static const u8 gIntro2LatiasTiles[] = INCBIN_U8("graphics/intro/intro2_latias.4bpp.lz");
+
+static void sub_817B62C(struct Sprite *sprite);
+static void nullsub_65(struct Sprite *sprite);
+static void sub_817B7C4(struct Sprite *sprite);
+static void nullsub_66(struct Sprite *sprite);
+
+static const struct SpriteTemplate gUnknown_085F504C = {
+ 2000, 0xFFFF, &gDummyOamData, gDummySpriteAnimTable, NULL, gDummySpriteAffineAnimTable, sub_817B62C
+};
+
+static const struct CompressedSpriteSheet gUnknown_085F5064[] = {
+ { gUnknown_085F16A8, 0x400, 2000 },
+ { NULL }
+};
+
+static const union AnimCmd gUnknown_085F5074[] = {
+ ANIMCMD_FRAME( 0, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd gUnknown_085F507C[] = {
+ ANIMCMD_FRAME(16, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd gUnknown_085F5084[] = {
+ ANIMCMD_FRAME(20, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd gUnknown_085F508C[] = {
+ ANIMCMD_FRAME(22, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const gUnknown_085F5094[] = {
+ gUnknown_085F5074,
+ gUnknown_085F507C,
+ gUnknown_085F5084,
+ gUnknown_085F508C
+};
+
+static const struct IntroCreditsSpriteMetadata gUnknown_085F50A4[] = {
+ { 0, ST_OAM_SQUARE, 2, 72, 32, 100, 0xc00 },
+ { 0, ST_OAM_SQUARE, 2, 158, 32, 100, 0xc00 },
+ { 1, ST_OAM_SQUARE, 1, 192, 40, 101, 0x800 },
+ { 1, ST_OAM_SQUARE, 1, 56, 40, 101, 0x800 },
+ { 2, ST_OAM_H_RECTANGLE, 0, 100, 44, 102, 0x400 },
+ { 2, ST_OAM_H_RECTANGLE, 0, 152, 44, 102, 0x400 },
+ { 3, ST_OAM_H_RECTANGLE, 0, 8, 46, 103, 0x100 },
+ { 3, ST_OAM_H_RECTANGLE, 0, 56, 46, 103, 0x100 },
+ { 3, ST_OAM_H_RECTANGLE, 0, 240, 46, 103, 0x100 },
+};
+
+static const struct CompressedSpriteSheet gUnknown_085F50EC[] = {
+ { gIntro2TreeTiles, 0x400, 2000 },
+ { NULL }
+};
+
+static const union AnimCmd gUnknown_085F50FC[] = {
+ ANIMCMD_FRAME( 0, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd gUnknown_085F5104[] = {
+ ANIMCMD_FRAME(16, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd gUnknown_085F510C[] = {
+ ANIMCMD_FRAME(24, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const gUnknown_085F5114[] = {
+ gUnknown_085F50FC,
+ gUnknown_085F5104,
+ gUnknown_085F510C
+};
+
+static const struct IntroCreditsSpriteMetadata gUnknown_085F5120[] = {
+ { 0, ST_OAM_SQUARE, 2, 16, 88, 100, 0x2000 },
+ { 0, ST_OAM_SQUARE, 2, 80, 88, 100, 0x2000 },
+ { 0, ST_OAM_SQUARE, 2, 144, 88, 100, 0x2000 },
+ { 0, ST_OAM_SQUARE, 2, 208, 88, 100, 0x2000 },
+ { 1, ST_OAM_V_RECTANGLE, 2, 40, 88, 101, 0x1000 },
+ { 1, ST_OAM_V_RECTANGLE, 2, 104, 88, 101, 0x1000 },
+ { 1, ST_OAM_V_RECTANGLE, 2, 168, 88, 101, 0x1000 },
+ { 1, ST_OAM_V_RECTANGLE, 2, 232, 88, 101, 0x1000 },
+ { 2, ST_OAM_V_RECTANGLE, 2, 56, 88, 102, 0x800 },
+ { 2, ST_OAM_V_RECTANGLE, 2, 120, 88, 102, 0x800 },
+ { 2, ST_OAM_V_RECTANGLE, 2, 184, 88, 102, 0x800 },
+ { 2, ST_OAM_V_RECTANGLE, 2, 248, 88, 102, 0x800 },
+};
+
+static const struct CompressedSpriteSheet gUnknown_085F5180[] = {
+ { gIntro2NightTiles, 0x400, 2000 },
+ { NULL }
+};
+
+static const union AnimCmd gUnknown_085F5190[] = {
+ ANIMCMD_FRAME(0, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const gUnknown_085F5198[] = {
+ gUnknown_085F5190
+};
+
+static const struct IntroCreditsSpriteMetadata gUnknown_085F519C[] = {
+ { 0, ST_OAM_SQUARE, 2, 24, 88, 100, 0x1000 },
+ { 0, ST_OAM_SQUARE, 2, 64, 88, 100, 0x1000 },
+ { 0, ST_OAM_SQUARE, 2, 104, 88, 100, 0x1000 },
+ { 0, ST_OAM_SQUARE, 2, 144, 88, 100, 0x1000 },
+ { 0, ST_OAM_SQUARE, 2, 184, 88, 100, 0x1000 },
+ { 0, ST_OAM_SQUARE, 2, 224, 88, 100, 0x1000 },
+};
+
+static const struct OamData gOamData_85F51CC = {
+ .y = 160, .shape = ST_OAM_SQUARE, .size = 3, .priority = 1
+};
+
+static const union AnimCmd gUnknown_085F51D4[] = {
+ ANIMCMD_FRAME( 0, 8),
+ ANIMCMD_FRAME( 64, 8),
+ ANIMCMD_FRAME(128, 8),
+ ANIMCMD_FRAME(192, 8),
+ ANIMCMD_JUMP(0)
+};
+
+static const union AnimCmd *const gUnknown_085F51E8[] = {
+ gUnknown_085F51D4
+};
+
+static const struct SpriteTemplate gUnknown_085F51EC = {
+ 1002, 1002, &gOamData_85F51CC, gUnknown_085F51E8, NULL, gDummySpriteAffineAnimTable, nullsub_65
+};
+
+static const struct SpriteTemplate gUnknown_085F5204 = {
+ 1003, 1003, &gOamData_85F51CC, gUnknown_085F51E8, NULL, gDummySpriteAffineAnimTable, nullsub_65
+};
+
+static const struct OamData gUnknown_085F521C = {
+ .y = 160, .shape = ST_OAM_H_RECTANGLE, .size = 3, .priority = 1
+};
+
+static const union AnimCmd gUnknown_085F5224[] = {
+ ANIMCMD_FRAME( 0, 8),
+ ANIMCMD_FRAME( 32, 8),
+ ANIMCMD_FRAME( 64, 8),
+ ANIMCMD_FRAME( 96, 8),
+ ANIMCMD_JUMP(0)
+};
+
+static const union AnimCmd *const gUnknown_085F5238[] = {
+ gUnknown_085F5224
+};
+
+static const struct SpriteTemplate gUnknown_085F523C = {
+ 1001, 1002, &gUnknown_085F521C, gUnknown_085F5238, NULL, gDummySpriteAffineAnimTable, sub_817B7C4
+};
+
+static const struct SpriteTemplate gUnknown_085F5254 = {
+ 1001, 1003, &gUnknown_085F521C, gUnknown_085F5238, NULL, gDummySpriteAffineAnimTable, sub_817B7C4
+};
+
+static const struct OamData gUnknown_085F526C = {
+ .y = 160, .shape = ST_OAM_SQUARE, .size = 3, .priority = 1
+};
+
+static const union AnimCmd gUnknown_085F5274[] = {
+ ANIMCMD_FRAME( 0, 16),
+ ANIMCMD_END
+};
+
+static const union AnimCmd gUnknown_085F527C[] = {
+ ANIMCMD_FRAME( 64, 16),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const gUnknown_085F5284[] = {
+ gUnknown_085F5274,
+ gUnknown_085F527C
+};
+
+static const struct SpriteTemplate gUnknown_085F528C = {
+ 1004, 1004, &gUnknown_085F526C, gUnknown_085F5284, NULL, gDummySpriteAffineAnimTable, nullsub_66
+};
+
+static const struct SpriteTemplate gUnknown_085F52A4 = {
+ 1005, 1005, &gUnknown_085F526C, gUnknown_085F5284, NULL, gDummySpriteAffineAnimTable, nullsub_66
+};
+
+const struct CompressedSpriteSheet gIntro2BrendanSpriteSheet[] = {
+ { gIntro2BrendanNoTurnGfx, 0x2000, 1002 },
+ { NULL }
+};
+
+const struct CompressedSpriteSheet gIntro2MaySpriteSheet[] = {
+ { gIntro2MayNoTurnGfx, 0x2000, 1003 },
+ { NULL }
+};
+
+const struct CompressedSpriteSheet gIntro2BicycleSpriteSheet[] = {
+ { gIntro2BicycleTiles, 0x1000, 1001 },
+ { NULL }
+};
+
+static const struct CompressedSpriteSheet gUnknown_085F52EC[] = {
+ { gIntro2FlygonGfx, 0x1000, 1004 },
+ { NULL }
+};
+
+const struct CompressedSpriteSheet gIntro2FlygonSpriteSheet[] = {
+ { gIntro2FlygonGfx, 0x1000, 1005 },
+ { NULL }
+};
+
+const struct SpritePalette gUnknown_085F530C[] = {
+ { gIntro2BrendanNoTurnPal, 1002 },
+ { gIntro2BrendanNoTurnPal, 1003 },
+ { gIntro2FlygonPal, 1004 },
+ { gIntro2FlygonPal, 1005 },
+ { NULL }
+};
+
+const struct CompressedSpriteSheet gUnknown_085F5334[] = {
+ { gIntro2BrendanTiles, 0x3800, 1002 },
+ { NULL }
+};
+
+const struct CompressedSpriteSheet gUnknown_085F5344[] = {
+ { gIntro2MayTiles, 0x3800, 1003 },
+ { NULL }
+};
+
+const struct CompressedSpriteSheet gUnknown_085F5354[] = {
+ { gIntro2BicycleTiles, 0x1000, 1001 },
+ { NULL }
+};
+
+static const struct CompressedSpriteSheet gUnknown_085F5364[] = {
+ { gIntro2LatiosTiles, 0x1000, 1004 },
+ { NULL }
+};
+
+static const struct CompressedSpriteSheet gUnknown_085F5374[] = {
+ { gIntro2LatiasTiles, 0x1000, 1005 },
+ { NULL }
+};
+
+const struct SpritePalette gUnknown_085F5384[] = {
+ { gIntro2BrendanPalette, 1002 },
+ { gIntro2MayPalette, 1003 },
+ { gIntro2LatiosPalette, 1004 },
+ { gIntro2LatiasPalette, 1005 },
+ { NULL }
+};
+
+const struct CompressedSpriteSheet gUnknown_085F53AC[] = {
+ { gIntro2BrendanTiles, 0x2000, 1002},
+ { NULL }
+};
+
+const struct CompressedSpriteSheet gUnknown_085F53BC[] = {
+ { gIntro2MayTiles, 0x2000, 1003},
+ { NULL }
+};
+
+EWRAM_DATA u16 gUnknown_0203BD24 = 0;
+EWRAM_DATA s16 gUnknown_0203BD26 = 0;
+EWRAM_DATA s16 gUnknown_0203BD28 = 0;
+
+static void sub_817B76C(void);
+static void sub_817B788(void);
+static void sub_817B7A4(void);
+static void sub_817B458(u8);
+
+void load_intro_part2_graphics(u8 a)
+{
+ LZ77UnCompVram(&gUnknown_085F0740, (void *)(VRAM + 0x4000));
+ LZ77UnCompVram(&gUnknown_085F0BC0, (void *)(VRAM + 0x7800));
+ LoadPalette(&gUnknown_085F06E0, 240, 32);
+ switch (a)
+ {
+ case 0:
+ default:
+ LZ77UnCompVram(&gUnknown_085F0DBC, (void *)(VRAM));
+ LZ77UnCompVram(&gUnknown_085F1398, (void *)(VRAM + 0x3000));
+ LoadPalette(&gUnknown_085F0CFC, 0, 96);
+ LoadCompressedObjectPic(gUnknown_085F5064);
+ LoadPalette(&gUnknown_085F1668, 256, 32);
+ sub_817B76C();
+ break;
+ case 1:
+ LZ77UnCompVram(&gUnknown_085F1824, (void *)(VRAM));
+ LZ77UnCompVram(&gUnknown_085F1EAC, (void *)(VRAM + 0x3000));
+ LoadPalette(&gUnknown_085F17E4, 0, 32);
+ LoadCompressedObjectPic(gUnknown_085F50EC);
+ LoadPalette(&gUnknown_085F21B0, 256, 32);
+ sub_817B788();
+ break;
+ }
+ gUnknown_0203BD28 = 0;
+ gReservedSpritePaletteCount = 8;
+}
+
+void sub_817B150(u8 a)
+{
+ switch (a)
+ {
+ default:
+ case 0:
+ SetGpuReg(REG_OFFSET_BG3CNT, BGCNT_PRIORITY(3)
+ | BGCNT_CHARBASE(0)
+ | BGCNT_16COLOR
+ | BGCNT_SCREENBASE(6)
+ | BGCNT_TXT256x256);
+ SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(2)
+ | BGCNT_CHARBASE(0)
+ | BGCNT_16COLOR
+ | BGCNT_SCREENBASE(7)
+ | BGCNT_TXT256x256);
+ SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(1)
+ | BGCNT_CHARBASE(1)
+ | BGCNT_16COLOR
+ | BGCNT_SCREENBASE(15)
+ | BGCNT_TXT256x256);
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0
+ | DISPCNT_OBJ_1D_MAP
+ | DISPCNT_BG1_ON
+ | DISPCNT_BG2_ON
+ | DISPCNT_BG3_ON
+ | DISPCNT_OBJ_ON);
+ break;
+ case 1:
+ SetGpuReg(REG_OFFSET_BG3CNT, BGCNT_PRIORITY(3)
+ | BGCNT_CHARBASE(0)
+ | BGCNT_16COLOR
+ | BGCNT_SCREENBASE(6)
+ | BGCNT_TXT256x256);
+ SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(2)
+ | BGCNT_CHARBASE(0)
+ | BGCNT_16COLOR
+ | BGCNT_SCREENBASE(7)
+ | BGCNT_TXT256x256);
+ SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(1)
+ | BGCNT_CHARBASE(1)
+ | BGCNT_16COLOR
+ | BGCNT_SCREENBASE(15)
+ | BGCNT_TXT256x256);
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0
+ | DISPCNT_OBJ_1D_MAP
+ | DISPCNT_BG1_ON
+ | DISPCNT_BG2_ON
+ | DISPCNT_BG3_ON
+ | DISPCNT_OBJ_ON);
+ break;
+ case 2:
+ SetGpuReg(REG_OFFSET_BG3CNT, BGCNT_PRIORITY(3)
+ | BGCNT_CHARBASE(0)
+ | BGCNT_16COLOR
+ | BGCNT_SCREENBASE(6)
+ | BGCNT_TXT256x256);
+ SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(2)
+ | BGCNT_CHARBASE(0)
+ | BGCNT_16COLOR
+ | BGCNT_SCREENBASE(7)
+ | BGCNT_TXT256x256);
+ SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(1)
+ | BGCNT_CHARBASE(1)
+ | BGCNT_16COLOR
+ | BGCNT_SCREENBASE(15)
+ | BGCNT_TXT256x256);
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0
+ | DISPCNT_OBJ_1D_MAP
+ | DISPCNT_BG1_ON
+ | DISPCNT_BG2_ON
+ | DISPCNT_BG3_ON
+ | DISPCNT_OBJ_ON);
+ break;
+ }
+}
+
+void sub_817B1C8(u8 a)
+{
+ LZ77UnCompVram(&gUnknown_085F0740, (void *)(VRAM + 0x4000));
+ LZ77UnCompVram(&gUnknown_085F0BC0, (void *)(VRAM + 0x7800));
+ switch (a)
+ {
+ case 0:
+ default:
+ LoadPalette(&gUnknown_085F06E0, 240, 32);
+ LZ77UnCompVram(&gUnknown_085F0DBC, (void *)(VRAM));
+ LZ77UnCompVram(&gUnknown_085F1398, (void *)(VRAM + 0x3000));
+ LoadPalette(&gUnknown_085F0CFC, 0, 96);
+ LoadCompressedObjectPic(gUnknown_085F5064);
+ LZ77UnCompVram(&gUnknown_085F16A8, (void *)(VRAM + 0x10000));
+ LoadPalette(&gUnknown_085F1668, 256, 32);
+ sub_817B76C();
+ break;
+ case 1:
+ LoadPalette(&gUnknown_085F0700, 240, 32);
+ LZ77UnCompVram(&gUnknown_085F0DBC, (void *)(VRAM));
+ LZ77UnCompVram(&gUnknown_085F1398, (void *)(VRAM + 0x3000));
+ LoadPalette(&gUnknown_085F0D5C, 0, 96);
+ LoadCompressedObjectPic(gUnknown_085F5064);
+ LZ77UnCompVram(&gUnknown_085F16A8, (void *)(VRAM + 0x10000));
+ LoadPalette(&gUnknown_085F1688, 256, 32);
+ sub_817B76C();
+ break;
+ case 2:
+ case 3:
+ LoadPalette(&gUnknown_085F0700, 240, 32);
+ LZ77UnCompVram(&gUnknown_085F1824, (void *)(VRAM));
+ LZ77UnCompVram(&gUnknown_085F1EAC, (void *)(VRAM + 0x3000));
+ LoadPalette(&gUnknown_085F1804, 0, 32);
+ LoadCompressedObjectPic(gUnknown_085F50EC);
+ LoadPalette(&gUnknown_085F1804, 256, 32);
+ sub_817B788();
+ break;
+ case 4:
+ LoadPalette(&gUnknown_085F0720, 240, 32);
+ LZ77UnCompVram(&gUnknown_085F235C, (void *)(VRAM));
+ LZ77UnCompVram(&gUnknown_085F2568, (void *)(VRAM + 0x3000));
+ LoadPalette(&gUnknown_085F231C, 0, 64);
+ LoadCompressedObjectPic(gUnknown_085F5180);
+ LoadPalette(&gUnknown_085F2548, 256, 32);
+ sub_817B7A4();
+ break;
+ }
+ gReservedSpritePaletteCount = 8;
+ gUnknown_0203BD28 = 0;
+}
+
+void sub_817B3A8(u8 a)
+{
+ SetGpuReg(REG_OFFSET_BG3CNT, BGCNT_PRIORITY(3)
+ | BGCNT_CHARBASE(0)
+ | BGCNT_16COLOR
+ | BGCNT_SCREENBASE(6)
+ | BGCNT_TXT256x256);
+ SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(2)
+ | BGCNT_CHARBASE(0)
+ | BGCNT_16COLOR
+ | BGCNT_SCREENBASE(7)
+ | BGCNT_TXT256x256);
+ SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(1)
+ | BGCNT_CHARBASE(1)
+ | BGCNT_16COLOR
+ | BGCNT_SCREENBASE(15)
+ | BGCNT_TXT256x256);
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0
+ | DISPCNT_OBJ_1D_MAP
+ | DISPCNT_BG_ALL_ON
+ | DISPCNT_OBJ_ON);
+}
+
+u8 sub_817B3DC(u8 a, u16 b, u16 c, u16 d)
+{
+ u8 taskId = CreateTask(&sub_817B458, 0);
+
+ gTasks[taskId].data[0] = a;
+ gTasks[taskId].data[1] = b;
+ gTasks[taskId].data[2] = 0;
+ gTasks[taskId].data[3] = 0;
+ gTasks[taskId].data[4] = c;
+ gTasks[taskId].data[5] = 0;
+ gTasks[taskId].data[6] = 0;
+ gTasks[taskId].data[7] = d;
+ gTasks[taskId].data[8] = 8;
+ gTasks[taskId].data[9] = 0;
+ sub_817B458(taskId);
+ return taskId;
+}
+
+static void sub_817B458(u8 taskId)
+{
+ s16 data1;
+ s16 data4;
+ s16 data7;
+ s32 r2;
+
+ data1 = gTasks[taskId].data[1];
+ if (data1 != 0)
+ {
+ r2 = (gTasks[taskId].data[2] << 16) + (u16)gTasks[taskId].data[3];
+ r2 -= (u16)data1 << 4;
+ gTasks[taskId].data[2] = r2 >> 16;
+ gTasks[taskId].data[3] = r2;
+ SetGpuReg(REG_OFFSET_BG1HOFS, gTasks[taskId].data[2]);
+ SetGpuReg(REG_OFFSET_BG1VOFS, gUnknown_0203BD24 + gUnknown_0203BD26);
+ }
+
+ data4 = gTasks[taskId].data[4];
+ if (data4 != 0)
+ {
+ r2 = (gTasks[taskId].data[5] << 16) + (u16)gTasks[taskId].data[6];
+ r2 -= (u16)data4 << 4;
+ gTasks[taskId].data[5] = r2 >> 16;
+ gTasks[taskId].data[6] = r2;
+ SetGpuReg(REG_OFFSET_BG2HOFS, gTasks[taskId].data[5]);
+ if (gTasks[taskId].data[0] != 0)
+ SetGpuReg(REG_OFFSET_BG2VOFS, gUnknown_0203BD24 + gUnknown_0203BD26);
+ else
+ SetGpuReg(REG_OFFSET_BG2VOFS, gUnknown_0203BD24);
+ }
+
+ data7 = gTasks[taskId].data[7];
+ if (data7 != 0)
+ {
+ r2 = (gTasks[taskId].data[8] << 16) + (u16)gTasks[taskId].data[9];
+ r2 -= (u16)data7 << 4;
+ gTasks[taskId].data[8] = r2 >> 16;
+ gTasks[taskId].data[9] = r2;
+ SetGpuReg(REG_OFFSET_BG3HOFS, gTasks[taskId].data[8]);
+ SetGpuReg(REG_OFFSET_BG3VOFS, gUnknown_0203BD24);
+ }
+}
+
+void sub_817B540(u8 mode)
+{
+ u16 x;
+ u16 y;
+ switch (mode)
+ {
+ case 0:
+ default:
+ /* stuff */
+ if (gMain.vblankCounter1 & 3 || gPaletteFade.active)
+ break;
+ if (gMain.vblankCounter1 & 4)
+ {
+ x = gPlttBufferUnfaded[9];
+ y = gPlttBufferUnfaded[10];
+ }
+ else
+ {
+ x = gPlttBufferUnfaded[10];
+ y = gPlttBufferUnfaded[9];
+ }
+ LoadPalette(&x, 9, 2);
+ LoadPalette(&y, 10, 2);
+ break;
+ case 2:
+ if (gMain.vblankCounter1 & 3 || gPaletteFade.active)
+ break;
+ if (gMain.vblankCounter1 & 4)
+ {
+ x = 0x3D27;
+ y = 0x295;
+ }
+ else
+ {
+ x = 0x31C;
+ y = 0x3D27;
+ }
+ LoadPalette(&x, 12, 2);
+ LoadPalette(&y, 13, 2);
+ break;
+ case 1:
+ break;
+ }
+}
+
+static void sub_817B62C(struct Sprite *sprite)
+{
+ s32 var;
+ s16 var2 = gUnknown_0203BD28;
+
+ if (var2 != 2)
+ {
+ switch (var2)
+ {
+ default:
+ DestroySprite(sprite);
+ break;
+ case 0:
+ var = ((sprite->pos1.x << 16) | (u16)sprite->data[2]) + (u16)sprite->data[1];
+ sprite->pos1.x = var >> 16;
+ sprite->data[2] = var;
+ if (sprite->pos1.x > 0xFF)
+ sprite->pos1.x = -0x20;
+ if (sprite->data[0])
+ sprite->pos2.y = -(gUnknown_0203BD24 + gUnknown_0203BD26);
+ else
+ sprite->pos2.y = -gUnknown_0203BD24;
+ break;
+ }
+ }
+}
+
+static void sub_817B698(u8 a, const struct IntroCreditsSpriteMetadata *b, const union AnimCmd *const *c, u8 d)
+{
+ u8 i;
+
+ for(i = 0; i < d; i++)
+ {
+ u8 sprite = CreateSprite(&gUnknown_085F504C, b[i].x, b[i].y, b[i].subpriority);
+ CalcCenterToCornerVec(&gSprites[sprite], b[i].shape, b[i].size, 0);
+ gSprites[sprite].oam.priority = 3;
+ gSprites[sprite].oam.shape = b[i].shape;
+ gSprites[sprite].oam.size = b[i].size;
+ gSprites[sprite].oam.paletteNum = 0;
+ gSprites[sprite].anims = c;
+ StartSpriteAnim(&gSprites[sprite], b[i].animNum);
+ gSprites[sprite].data[0] = a;
+ gSprites[sprite].data[1] = b[i].xOff;
+ gSprites[sprite].data[2] = 0;
+ }
+}
+
+static void sub_817B76C(void)
+{
+ sub_817B698(0, gUnknown_085F50A4, gUnknown_085F5094, 9);
+}
+
+static void sub_817B788(void)
+{
+ sub_817B698(1, gUnknown_085F5120, gUnknown_085F5114, 12);
+}
+
+static void sub_817B7A4(void)
+{
+ sub_817B698(1, gUnknown_085F519C, gUnknown_085F5198, 6);
+}
+
+static void nullsub_65(struct Sprite *sprite)
+{
+}
+
+static void sub_817B7C4(struct Sprite* sprite)
+{
+ sprite->invisible = gSprites[sprite->data[0]].invisible;
+ sprite->pos1.x = gSprites[sprite->data[0]].pos1.x;
+ sprite->pos1.y = gSprites[sprite->data[0]].pos1.y + 8;
+ sprite->pos2.x = gSprites[sprite->data[0]].pos2.x;
+ sprite->pos2.y = gSprites[sprite->data[0]].pos2.y;
+}
+
+u8 intro_create_brendan_sprite(s16 a, s16 b)
+{
+ u8 sprite = CreateSprite(&gUnknown_085F51EC, a, b, 2);
+ u8 brendan = CreateSprite(&gUnknown_085F523C, a, b + 8, 3);
+ gSprites[brendan].data[0] = sprite;
+ return sprite;
+}
+
+u8 intro_create_may_sprite(s16 a, s16 b)
+{
+ u8 sprite = CreateSprite(&gUnknown_085F5204, a, b, 2);
+ u8 may = CreateSprite(&gUnknown_085F5254, a, b + 8, 3);
+ gSprites[may].data[0] = sprite;
+ return sprite;
+}
+
+static void nullsub_66(struct Sprite *sprite)
+{
+}
+
+static void sub_817B8E8(struct Sprite* sprite)
+{
+ sprite->invisible = gSprites[sprite->data[0]].invisible;
+ sprite->pos1.y = gSprites[sprite->data[0]].pos1.y;
+ sprite->pos2.x = gSprites[sprite->data[0]].pos2.x;
+ sprite->pos2.y = gSprites[sprite->data[0]].pos2.y;
+}
+
+static u8 sub_817B948(s16 a, s16 b)
+{
+ u8 sprite = CreateSprite(&gUnknown_085F528C, a - 32, b, 5);
+ u8 latios = CreateSprite(&gUnknown_085F528C, a + 32, b, 6);
+ gSprites[latios].data[0] = sprite;
+ StartSpriteAnim(&gSprites[latios], 1);
+ gSprites[latios].callback = &sub_817B8E8;
+ return sprite;
+}
+
+u8 intro_create_flygon_sprite(s16 a, s16 b)
+{
+ u8 sprite = CreateSprite(&gUnknown_085F52A4, a - 32, b, 5);
+ u8 flygon = CreateSprite(&gUnknown_085F52A4, a + 32, b, 6);
+ gSprites[flygon].data[0] = sprite;
+ StartSpriteAnim(&gSprites[flygon], 1);
+ gSprites[flygon].callback = &sub_817B8E8;
+ return sprite;
+}
diff --git a/src/item.c b/src/item.c
index ef815fb81..319d167fc 100644
--- a/src/item.c
+++ b/src/item.c
@@ -5,41 +5,48 @@
#include "string_util.h"
#include "text.h"
#include "event_data.h"
+#include "malloc.h"
+#include "secret_base.h"
+#include "item_menu.h"
+#include "strings.h"
+#include "load_save.h"
-extern void ApplyNewEncryptionKeyToHword(u16* hword, u32 newKey);
extern bool8 InBattlePyramid(void);
+extern u16 gUnknown_0203CF30[];
+extern const struct Item gItems[];
-extern const u8 gText_PokeBalls[];
-extern const u8 gText_Berries[];
-extern const u8 gText_Berry[];
+// this file's functions
+static bool8 CheckPyramidBagHasItem(u16 itemId, u16 count);
+static bool8 CheckPyramidBagHasSpace(u16 itemId, u16 count);
-bool8 CheckPyramidBagHasItem(u16 itemId, u16 count);
-bool8 CheckPyramidBagHasSpace(u16 itemId, u16 count);
+// EWRAM variables
+EWRAM_DATA struct BagPocket gBagPockets[POCKETS_COUNT] = {0};
-u16 GetBagItemQuantity(u16* quantity)
+// code
+static u16 GetBagItemQuantity(u16 *quantity)
{
return gSaveBlock2Ptr->encryptionKey ^ *quantity;
}
-void SetBagItemQuantity(u16* quantity, u16 newValue)
+static void SetBagItemQuantity(u16 *quantity, u16 newValue)
{
*quantity = newValue ^ gSaveBlock2Ptr->encryptionKey;
}
-u16 GetBagItemId(u16* slot)
+static u16 GetPCItemQuantity(u16 *quantity)
{
- return *slot;
+ return *quantity;
}
-void SetBagItemId(u16* slot, u16 newItemId)
+static void SetPCItemQuantity(u16 *quantity, u16 newValue)
{
- *slot = newItemId;
+ *quantity = newValue;
}
void ApplyNewEncryptionKeyToBagItems(u32 newKey)
{
u32 pocket, item;
- for (pocket = 0; pocket < 5; pocket++)
+ for (pocket = 0; pocket < POCKETS_COUNT; pocket++)
{
for (item = 0; item < gBagPockets[pocket].capacity; item++)
ApplyNewEncryptionKeyToHword(&(gBagPockets[pocket].itemSlots[item].quantity), newKey);
@@ -51,58 +58,57 @@ void ApplyNewEncryptionKeyToBagItems_(u32 newKey) // really GF?
ApplyNewEncryptionKeyToBagItems(newKey);
}
-// TODO: move those max values to defines
-
void SetBagItemsPointers(void)
{
- gBagPockets[BAG_ITEMS - 1].itemSlots = gSaveBlock1Ptr->bagPocket_Items;
- gBagPockets[BAG_ITEMS - 1].capacity = 30;
+ gBagPockets[ITEMS_POCKET].itemSlots = gSaveBlock1Ptr->bagPocket_Items;
+ gBagPockets[ITEMS_POCKET].capacity = BAG_ITEMS_COUNT;
- gBagPockets[BAG_KEYITEMS - 1].itemSlots = gSaveBlock1Ptr->bagPocket_KeyItems;
- gBagPockets[BAG_KEYITEMS - 1].capacity = 30;
+ gBagPockets[KEYITEMS_POCKET].itemSlots = gSaveBlock1Ptr->bagPocket_KeyItems;
+ gBagPockets[KEYITEMS_POCKET].capacity = BAG_KEYITEMS_COUNT;
- gBagPockets[BAG_POKEBALLS - 1].itemSlots = gSaveBlock1Ptr->bagPocket_PokeBalls;
- gBagPockets[BAG_POKEBALLS - 1].capacity = 16;
+ gBagPockets[BALLS_POCKET].itemSlots = gSaveBlock1Ptr->bagPocket_PokeBalls;
+ gBagPockets[BALLS_POCKET].capacity = BAG_POKEBALLS_COUNT;
- gBagPockets[BAG_TMsHMs - 1].itemSlots = gSaveBlock1Ptr->bagPocket_TMHM;
- gBagPockets[BAG_TMsHMs - 1].capacity = 64;
+ gBagPockets[TMHM_POCKET].itemSlots = gSaveBlock1Ptr->bagPocket_TMHM;
+ gBagPockets[TMHM_POCKET].capacity = BAG_TMHM_COUNT;
- gBagPockets[BAG_BERRIES - 1].itemSlots = gSaveBlock1Ptr->bagPocket_Berries;
- gBagPockets[BAG_BERRIES - 1].capacity = 46;
+ gBagPockets[BERRIES_POCKET].itemSlots = gSaveBlock1Ptr->bagPocket_Berries;
+ gBagPockets[BERRIES_POCKET].capacity = BAG_BERRIES_COUNT;
}
-void CopyItemName(u16 itemId, u8 *string)
+void CopyItemName(u16 itemId, u8 *dst)
{
- StringCopy(string, ItemId_GetItem(itemId)->name);
+ StringCopy(dst, ItemId_GetName(itemId));
}
-void CopyItemNameHandlePlural(u16 itemId, u8 *string, u32 quantity)
+void CopyItemNameHandlePlural(u16 itemId, u8 *dst, u32 quantity)
{
if (itemId == ITEM_POKE_BALL)
{
if (quantity < 2)
- StringCopy(string, ItemId_GetItem(ITEM_POKE_BALL)->name);
+ StringCopy(dst, ItemId_GetName(ITEM_POKE_BALL));
else
- StringCopy(string, gText_PokeBalls);
+ StringCopy(dst, gText_PokeBalls);
}
else
{
if (itemId >= ITEM_CHERI_BERRY && itemId <= ITEM_ENIGMA_BERRY)
- GetBerryCountString(string, gBerries[itemId - ITEM_CHERI_BERRY].name, quantity);
+ GetBerryCountString(dst, gBerries[itemId - ITEM_CHERI_BERRY].name, quantity);
else
- StringCopy(string, ItemId_GetItem(itemId)->name);
+ StringCopy(dst, ItemId_GetName(itemId));
}
}
-void GetBerryCountString(u8* dst, const u8* berryName, u32 quantity)
+void GetBerryCountString(u8 *dst, const u8 *berryName, u32 quantity)
{
- const u8* berryString;
- u8* txtPtr;
+ const u8 *berryString;
+ u8 *txtPtr;
if (quantity < 2)
berryString = gText_Berry;
else
berryString = gText_Berries;
+
txtPtr = StringCopy(dst, berryName);
*txtPtr = CHAR_SPACE;
StringCopy(txtPtr + 1, berryString);
@@ -127,21 +133,21 @@ bool8 CheckBagHasItem(u16 itemId, u16 count)
if (ItemId_GetPocket(itemId) == 0)
return FALSE;
- if (InBattlePyramid() || FlagGet(0x4004) == TRUE)
+ if (InBattlePyramid() || FlagGet(FLAG_SPECIAL_FLAG_0x4004) == TRUE)
return CheckPyramidBagHasItem(itemId, count);
pocket = ItemId_GetPocket(itemId) - 1;
- //Check for item slots that contain the item
+ // Check for item slots that contain the item
for (i = 0; i < gBagPockets[pocket].capacity; i++)
{
if (gBagPockets[pocket].itemSlots[i].itemId == itemId)
{
u16 quantity;
- //Does this item slot contain enough of the item?
+ // Does this item slot contain enough of the item?
quantity = GetBagItemQuantity(&gBagPockets[pocket].itemSlots[i].quantity);
if (quantity >= count)
return TRUE;
count -= quantity;
- //Does this item slot and all previous slots contain enough of the item?
+ // Does this item slot and all previous slots contain enough of the item?
if (count == 0)
return TRUE;
}
@@ -152,69 +158,945 @@ bool8 CheckBagHasItem(u16 itemId, u16 count)
bool8 HasAtLeastOneBerry(void)
{
u16 i;
- for (i = 0x85; i < 0xB3; i++)
+
+ for (i = FIRST_BERRY_INDEX; i < ITEM_BRIGHT_POWDER; i++)
{
if (CheckBagHasItem(i, 1) == TRUE)
{
- gSpecialVar_Result = 1;
+ gSpecialVar_Result = TRUE;
return TRUE;
}
}
- gSpecialVar_Result = 0;
+ gSpecialVar_Result = FALSE;
return FALSE;
}
-/* Refuses to match.
+#ifdef NONMATCHING
+// Refuses to match.
bool8 CheckBagHasSpace(u16 itemId, u16 count)
{
u8 i;
- u8 pocket;
- u16 slotCapacity;
- u16 quantity;
- if (ItemId_GetPocket(itemId) == 0)
+ if (ItemId_GetPocket(itemId) == POCKET_NONE)
return FALSE;
- if (InBattlePyramid() || FlagGet(0x4004) == TRUE)
+
+ if (InBattlePyramid() || FlagGet(FLAG_SPECIAL_FLAG_0x4004) == TRUE)
+ {
return CheckPyramidBagHasSpace(itemId, count);
- pocket = ItemId_GetPocket(itemId) - 1;
- if (pocket != BAG_BERRIES)
- slotCapacity = 99;
+ }
else
- slotCapacity = 999;
+ {
+ u8 pocket;
+ u16 slotCapacity;
+ u16 ownedCount;
- //Check space in any existing item slots that already contain this item
- for (i = 0; i < gBagPockets[pocket].capacity; i++)
+ pocket = ItemId_GetPocket(itemId) - 1;
+ if (pocket != BERRIES_POCKET)
+ slotCapacity = 99;
+ else
+ slotCapacity = 999;
+
+ // Check space in any existing item slots that already contain this item
+ for (i = 0; i < gBagPockets[pocket].capacity; i++)
+ {
+ if (gBagPockets[pocket].itemSlots[i].itemId == itemId)
+ {
+ ownedCount = GetBagItemQuantity(&gBagPockets[pocket].itemSlots[i].quantity);
+ if (ownedCount + count <= slotCapacity)
+ return TRUE;
+ if (pocket == TMHM_POCKET || pocket == BERRIES_POCKET)
+ return FALSE;
+ count -= slotCapacity - ownedCount;
+ if (count == 0)
+ return TRUE;
+ }
+ }
+
+ // Check space in empty item slots
+ if (count > 0)
+ {
+ for (i = 0; i < gBagPockets[pocket].capacity; i++)
+ {
+ if (gBagPockets[pocket].itemSlots[i].itemId == 0)
+ {
+ if (count <= slotCapacity)
+ return TRUE;
+ if (pocket == TMHM_POCKET || pocket == BERRIES_POCKET)
+ return FALSE;
+ count -= slotCapacity;
+ }
+ }
+ if (count > 0)
+ return FALSE; // No more item slots. The bag is full
+ }
+
+ return TRUE;
+ }
+}
+#else
+NAKED
+bool8 CheckBagHasSpace(u16 itemId, u16 count)
+{
+ asm_unified("push {r4-r7,lr}\n\
+ mov r7, r10\n\
+ mov r6, r9\n\
+ mov r5, r8\n\
+ push {r5-r7}\n\
+ sub sp, 0x4\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ mov r8, r0\n\
+ lsls r1, 16\n\
+ lsrs r5, r1, 16\n\
+ bl ItemId_GetPocket\n\
+ lsls r0, 24\n\
+ cmp r0, 0\n\
+ beq _080D6906\n\
+ bl InBattlePyramid\n\
+ lsls r0, 24\n\
+ cmp r0, 0\n\
+ bne _080D6838\n\
+ ldr r0, =0x00004004\n\
+ bl FlagGet\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ cmp r0, 0x1\n\
+ bne _080D684C\n\
+_080D6838:\n\
+ mov r0, r8\n\
+ adds r1, r5, 0\n\
+ bl CheckPyramidBagHasSpace\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ b _080D6916\n\
+ .pool\n\
+_080D684C:\n\
+ mov r0, r8\n\
+ bl ItemId_GetPocket\n\
+ subs r0, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r2, r0, 24\n\
+ ldr r7, =0x000003e7\n\
+ cmp r2, 0x3\n\
+ beq _080D6860\n\
+ movs r7, 0x63\n\
+_080D6860:\n\
+ movs r6, 0\n\
+ ldr r1, =gBagPockets\n\
+ lsls r4, r2, 3\n\
+ adds r0, r4, r1\n\
+ mov r9, r4\n\
+ ldrb r0, [r0, 0x4]\n\
+ cmp r6, r0\n\
+ bcs _080D68BC\n\
+ subs r0, r2, 0x2\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ mov r10, r0\n\
+_080D6878:\n\
+ adds r0, r4, r1\n\
+ ldr r1, [r0]\n\
+ lsls r0, r6, 2\n\
+ adds r1, r0, r1\n\
+ ldrh r0, [r1]\n\
+ cmp r0, r8\n\
+ bne _080D68AC\n\
+ adds r0, r1, 0x2\n\
+ str r2, [sp]\n\
+ bl GetBagItemQuantity\n\
+ lsls r0, 16\n\
+ lsrs r1, r0, 16\n\
+ adds r0, r1, r5\n\
+ ldr r2, [sp]\n\
+ cmp r0, r7\n\
+ ble _080D6914\n\
+ mov r0, r10\n\
+ cmp r0, 0x1\n\
+ bls _080D6906\n\
+ subs r0, r7, r1\n\
+ subs r0, r5, r0\n\
+ lsls r0, 16\n\
+ lsrs r5, r0, 16\n\
+ cmp r5, 0\n\
+ beq _080D6914\n\
+_080D68AC:\n\
+ adds r0, r6, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r6, r0, 24\n\
+ ldr r1, =gBagPockets\n\
+ adds r0, r4, r1\n\
+ ldrb r0, [r0, 0x4]\n\
+ cmp r6, r0\n\
+ bcc _080D6878\n\
+_080D68BC:\n\
+ cmp r5, 0\n\
+ beq _080D6914\n\
+ movs r6, 0\n\
+ ldr r3, =gBagPockets\n\
+ mov r1, r9\n\
+ adds r0, r1, r3\n\
+ ldrb r0, [r0, 0x4]\n\
+ cmp r6, r0\n\
+ bcs _080D6902\n\
+ adds r4, r3, 0\n\
+ subs r0, r2, 0x2\n\
+ lsls r0, 24\n\
+ lsrs r2, r0, 24\n\
+_080D68D6:\n\
+ adds r0, r1, r4\n\
+ ldr r1, [r0]\n\
+ lsls r0, r6, 2\n\
+ adds r0, r1\n\
+ ldrh r0, [r0]\n\
+ cmp r0, 0\n\
+ bne _080D68F2\n\
+ cmp r5, r7\n\
+ bls _080D6914\n\
+ cmp r2, 0x1\n\
+ bls _080D6906\n\
+ subs r0, r5, r7\n\
+ lsls r0, 16\n\
+ lsrs r5, r0, 16\n\
+_080D68F2:\n\
+ adds r0, r6, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r6, r0, 24\n\
+ mov r1, r9\n\
+ adds r0, r1, r3\n\
+ ldrb r0, [r0, 0x4]\n\
+ cmp r6, r0\n\
+ bcc _080D68D6\n\
+_080D6902:\n\
+ cmp r5, 0\n\
+ beq _080D6914\n\
+_080D6906:\n\
+ movs r0, 0\n\
+ b _080D6916\n\
+ .pool\n\
+_080D6914:\n\
+ movs r0, 0x1\n\
+_080D6916:\n\
+ add sp, 0x4\n\
+ pop {r3-r5}\n\
+ mov r8, r3\n\
+ mov r9, r4\n\
+ mov r10, r5\n\
+ pop {r4-r7}\n\
+ pop {r1}\n\
+ bx r1");
+}
+#endif // NONMATCHING
+
+bool8 AddBagItem(u16 itemId, u16 count)
+{
+ u8 i;
+
+ if (ItemId_GetPocket(itemId) == POCKET_NONE)
+ return FALSE;
+
+ // check Battle Pyramid Bag
+ if (InBattlePyramid() || FlagGet(FLAG_SPECIAL_FLAG_0x4004) == TRUE)
{
- if (gBagPockets[pocket].itemSlots[i].itemId == itemId)
+ return AddPyramidBagItem(itemId, count);
+ }
+ else
+ {
+ struct BagPocket *itemPocket;
+ struct ItemSlot *newItems;
+ u16 slotCapacity;
+ u16 ownedCount;
+ u8 pocket = ItemId_GetPocket(itemId) - 1;
+
+ itemPocket = &gBagPockets[pocket];
+ newItems = AllocZeroed(itemPocket->capacity * sizeof(struct ItemSlot));
+ memcpy(newItems, itemPocket->itemSlots, itemPocket->capacity * sizeof(struct ItemSlot));
+
+ if (pocket != BERRIES_POCKET)
+ slotCapacity = 99;
+ else
+ slotCapacity = 999;
+
+ for (i = 0; i < itemPocket->capacity; i++)
{
- quantity = GetBagItemQuantity(&gBagPockets[pocket].itemSlots[i].quantity);
- if (quantity + count <= slotCapacity)
- return TRUE;
- if (pocket == BAG_TMsHMs || pocket == BAG_BERRIES)
+ if (newItems[i].itemId == itemId)
+ {
+ ownedCount = GetBagItemQuantity(&newItems[i].quantity);
+ // check if won't exceed max slot capacity
+ if (ownedCount + count <= slotCapacity)
+ {
+ // successfully added to already existing item's count
+ SetBagItemQuantity(&newItems[i].quantity, ownedCount + count);
+
+ // goto SUCCESS_ADD_ITEM;
+ // is equivalent but won't match
+
+ memcpy(itemPocket->itemSlots, newItems, itemPocket->capacity * sizeof(struct ItemSlot));
+ Free(newItems);
+ return TRUE;
+ }
+ else
+ {
+ // try creating another instance of the item if possible
+ if (pocket == TMHM_POCKET || pocket == BERRIES_POCKET)
+ {
+ Free(newItems);
+ return FALSE;
+ }
+ else
+ {
+ count -= slotCapacity - ownedCount;
+ SetBagItemQuantity(&newItems[i].quantity, slotCapacity);
+ // don't create another instance of the item if it's at max slot capacity and count is equal to 0
+ if (count == 0)
+ {
+ goto SUCCESS_ADD_ITEM;
+ }
+ }
+ }
+ }
+ }
+
+ // we're done if quantity is equal to 0
+ if (count > 0)
+ {
+ // either no existing item was found or we have to create another instance, because the capacity was exceeded
+ for (i = 0; i < itemPocket->capacity; i++)
+ {
+ if (newItems[i].itemId == ITEM_NONE)
+ {
+ newItems[i].itemId = itemId;
+ if (count > slotCapacity)
+ {
+ // try creating a new slot with max capacity if duplicates are possible
+ if (pocket == TMHM_POCKET || pocket == BERRIES_POCKET)
+ {
+ Free(newItems);
+ return FALSE;
+ }
+ count -= slotCapacity;
+ SetBagItemQuantity(&newItems[i].quantity, slotCapacity);
+ }
+ else
+ {
+ // created a new slot and added quantity
+ SetBagItemQuantity(&newItems[i].quantity, count);
+ goto SUCCESS_ADD_ITEM;
+ }
+ }
+ }
+
+ if (count > 0)
+ {
+ Free(newItems);
return FALSE;
- count -= slotCapacity - quantity;
+ }
+ }
+
+ SUCCESS_ADD_ITEM:
+ memcpy(itemPocket->itemSlots, newItems, itemPocket->capacity * sizeof(struct ItemSlot));
+ Free(newItems);
+ return TRUE;
+ }
+}
+
+bool8 RemoveBagItem(u16 itemId, u16 count)
+{
+ u8 i;
+ u16 totalQuantity = 0;
+
+ if (ItemId_GetPocket(itemId) == POCKET_NONE || itemId == ITEM_NONE)
+ return FALSE;
+
+ // check Battle Pyramid Bag
+ if (InBattlePyramid() || FlagGet(FLAG_SPECIAL_FLAG_0x4004) == TRUE)
+ {
+ return RemovePyramidBagItem(itemId, count);
+ }
+ else
+ {
+ u8 pocket;
+ u8 var;
+ u16 ownedCount;
+ struct BagPocket *itemPocket;
+
+ pocket = ItemId_GetPocket(itemId) - 1;
+ itemPocket = &gBagPockets[pocket];
+
+ for (i = 0; i < itemPocket->capacity; i++)
+ {
+ if (itemPocket->itemSlots[i].itemId == itemId)
+ totalQuantity += GetBagItemQuantity(&itemPocket->itemSlots[i].quantity);
+ }
+
+ if (totalQuantity < count)
+ return FALSE; // We don't have enough of the item
+
+ if (CurrentMapIsSecretBase() == TRUE)
+ {
+ VarSet(VAR_0x40EE, VarGet(VAR_0x40EE) | 0x200);
+ VarSet(VAR_0x40ED, itemId);
+ }
+
+ var = sub_81ABB2C(pocket);
+ if (itemPocket->capacity > var
+ && itemPocket->itemSlots[var].itemId == itemId)
+ {
+ ownedCount = GetBagItemQuantity(&itemPocket->itemSlots[var].quantity);
+ if (ownedCount >= count)
+ {
+ SetBagItemQuantity(&itemPocket->itemSlots[var].quantity, ownedCount - count);
+ count = 0;
+ }
+ else
+ {
+ count -= ownedCount;
+ SetBagItemQuantity(&itemPocket->itemSlots[var].quantity, 0);
+ }
+
+ if (GetBagItemQuantity(&itemPocket->itemSlots[var].quantity) == 0)
+ itemPocket->itemSlots[var].itemId = ITEM_NONE;
+
if (count == 0)
return TRUE;
}
+
+ for (i = 0; i < itemPocket->capacity; i++)
+ {
+ if (itemPocket->itemSlots[i].itemId == itemId)
+ {
+ ownedCount = GetBagItemQuantity(&itemPocket->itemSlots[i].quantity);
+ if (ownedCount >= count)
+ {
+ SetBagItemQuantity(&itemPocket->itemSlots[i].quantity, ownedCount - count);
+ count = 0;
+ }
+ else
+ {
+ count -= ownedCount;
+ SetBagItemQuantity(&itemPocket->itemSlots[i].quantity, 0);
+ }
+
+ if (GetBagItemQuantity(&itemPocket->itemSlots[i].quantity) == 0)
+ itemPocket->itemSlots[i].itemId = ITEM_NONE;
+
+ if (count == 0)
+ return TRUE;
+ }
+ }
+ return TRUE;
}
+}
- //Check space in empty item slots
- if (count > 0)
+u8 GetPocketByItemId(u16 itemId)
+{
+ return ItemId_GetPocket(itemId);
+}
+
+void ClearItemSlots(struct ItemSlot *itemSlots, u8 itemCount)
+{
+ u16 i;
+
+ for (i = 0; i < itemCount; i++)
{
- for (i = 0; i < gBagPockets[pocket].capacity; i++)
+ itemSlots[i].itemId = ITEM_NONE;
+ SetBagItemQuantity(&itemSlots[i].quantity, 0);
+ }
+}
+
+static s32 FindFreePCItemSlot(void)
+{
+ s8 i;
+
+ for (i = 0; i < PC_ITEMS_COUNT; i++)
+ {
+ if (gSaveBlock1Ptr->pcItems[i].itemId == ITEM_NONE)
+ return i;
+ }
+ return -1;
+}
+
+u8 CountUsedPCItemSlots(void)
+{
+ u8 usedSlots = 0;
+ u8 i;
+
+ for (i = 0; i < PC_ITEMS_COUNT; i++)
+ {
+ if (gSaveBlock1Ptr->pcItems[i].itemId != ITEM_NONE)
+ usedSlots++;
+ }
+ return usedSlots;
+}
+
+bool8 CheckPCHasItem(u16 itemId, u16 count)
+{
+ u8 i;
+
+ for (i = 0; i < PC_ITEMS_COUNT; i++)
+ {
+ if (gSaveBlock1Ptr->pcItems[i].itemId == itemId && GetPCItemQuantity(&gSaveBlock1Ptr->pcItems[i].quantity) >= count)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 AddPCItem(u16 itemId, u16 count)
+{
+ u8 i;
+ s8 freeSlot;
+ u16 ownedCount;
+ struct ItemSlot *newItems;
+
+ // Copy PC items
+ newItems = AllocZeroed(sizeof(gSaveBlock1Ptr->pcItems));
+ memcpy(newItems, gSaveBlock1Ptr->pcItems, sizeof(gSaveBlock1Ptr->pcItems));
+
+ // Use any item slots that already contain this item
+ for (i = 0; i < PC_ITEMS_COUNT; i++)
+ {
+ if (newItems[i].itemId == itemId)
{
- if (gBagPockets[pocket].itemSlots[i].itemId == 0)
+ ownedCount = GetPCItemQuantity(&newItems[i].quantity);
+ if (ownedCount + count <= 999)
{
- if (count <= slotCapacity)
- return TRUE;
- if (pocket == BAG_TMsHMs || pocket == BAG_BERRIES)
- return FALSE;
- count -= slotCapacity;
+ SetPCItemQuantity(&newItems[i].quantity, ownedCount + count);
+ memcpy(gSaveBlock1Ptr->pcItems, newItems, sizeof(gSaveBlock1Ptr->pcItems));
+ Free(newItems);
+ return TRUE;
+ }
+ count += ownedCount - 999;
+ SetPCItemQuantity(&newItems[i].quantity, 999);
+ if (count == 0)
+ {
+ memcpy(gSaveBlock1Ptr->pcItems, newItems, sizeof(gSaveBlock1Ptr->pcItems));
+ Free(newItems);
+ return TRUE;
}
}
- if (count > 0)
- return FALSE; //No more item slots. The bag is full
}
+ // Put any remaining items into a new item slot.
+ if (count > 0)
+ {
+ freeSlot = FindFreePCItemSlot();
+ if (freeSlot == -1)
+ {
+ Free(newItems);
+ return FALSE;
+ }
+ else
+ {
+ newItems[freeSlot].itemId = itemId;
+ SetPCItemQuantity(&newItems[freeSlot].quantity, count);
+ }
+ }
+
+ // Copy items back to the PC
+ memcpy(gSaveBlock1Ptr->pcItems, newItems, sizeof(gSaveBlock1Ptr->pcItems));
+ Free(newItems);
return TRUE;
-}*/
+}
+
+void RemovePCItem(u8 index, u16 count)
+{
+ // UB: should use GetPCItemQuantity and SetPCItemQuantity functions
+ gSaveBlock1Ptr->pcItems[index].quantity -= count;
+ if (gSaveBlock1Ptr->pcItems[index].quantity == 0)
+ {
+ gSaveBlock1Ptr->pcItems[index].itemId = ITEM_NONE;
+ CompactPCItems();
+ }
+}
+
+void CompactPCItems(void)
+{
+ u16 i;
+ u16 j;
+
+ for (i = 0; i < PC_ITEMS_COUNT - 1; i++)
+ {
+ for (j = i + 1; j < PC_ITEMS_COUNT; j++)
+ {
+ if (gSaveBlock1Ptr->pcItems[i].itemId == 0)
+ {
+ struct ItemSlot temp = gSaveBlock1Ptr->pcItems[i];
+ gSaveBlock1Ptr->pcItems[i] = gSaveBlock1Ptr->pcItems[j];
+ gSaveBlock1Ptr->pcItems[j] = temp;
+ }
+ }
+ }
+}
+
+void SwapRegisteredBike(void)
+{
+ switch (gSaveBlock1Ptr->registeredItem)
+ {
+ case ITEM_MACH_BIKE:
+ gSaveBlock1Ptr->registeredItem = ITEM_ACRO_BIKE;
+ break;
+ case ITEM_ACRO_BIKE:
+ gSaveBlock1Ptr->registeredItem = ITEM_MACH_BIKE;
+ break;
+ }
+}
+
+u16 BagGetItemIdByPocketPosition(u8 pocketId, u16 pocketPos)
+{
+ return gBagPockets[pocketId - 1].itemSlots[pocketPos].itemId;
+}
+
+u16 BagGetQuantityByPocketPosition(u8 pocketId, u16 pocketPos)
+{
+ return GetBagItemQuantity(&gBagPockets[pocketId - 1].itemSlots[pocketPos].quantity);
+}
+
+static void SwapItemSlots(struct ItemSlot *a, struct ItemSlot *b)
+{
+ struct ItemSlot temp = *a;
+ *a = *b;
+ *b = temp;
+}
+
+void CompactItemsInBagPocket(struct BagPocket *bagPocket)
+{
+ u16 i, j;
+
+ for (i = 0; i < bagPocket->capacity - 1; i++)
+ {
+ for (j = i + 1; j < bagPocket->capacity; j++)
+ {
+ if (GetBagItemQuantity(&bagPocket->itemSlots[i].quantity) == 0)
+ SwapItemSlots(&bagPocket->itemSlots[i], &bagPocket->itemSlots[j]);
+ }
+ }
+}
+
+void SortBerriesOrTMHMs(struct BagPocket *bagPocket)
+{
+ u16 i, j;
+
+ for (i = 0; i < bagPocket->capacity - 1; i++)
+ {
+ for (j = i + 1; j < bagPocket->capacity; j++)
+ {
+ if (GetBagItemQuantity(&bagPocket->itemSlots[i].quantity) != 0)
+ {
+ if (GetBagItemQuantity(&bagPocket->itemSlots[j].quantity) == 0)
+ continue;
+ if (bagPocket->itemSlots[i].itemId <= bagPocket->itemSlots[j].itemId)
+ continue;
+ }
+ SwapItemSlots(&bagPocket->itemSlots[i], &bagPocket->itemSlots[j]);
+ }
+ }
+}
+
+void MoveItemSlotInList(struct ItemSlot* itemSlots_, u32 from, u32 to_)
+{
+ // dumb assignments needed to match
+ struct ItemSlot *itemSlots = itemSlots_;
+ u32 to = to_;
+
+ if (from != to)
+ {
+ s16 i, count;
+ struct ItemSlot firstSlot = itemSlots[from];
+
+ if (to > from)
+ {
+ to--;
+ for (i = from, count = to; i < count; i++)
+ itemSlots[i] = itemSlots[i + 1];
+ }
+ else
+ {
+ for (i = from, count = to; i > count; i--)
+ itemSlots[i] = itemSlots[i - 1];
+ }
+ itemSlots[to] = firstSlot;
+ }
+}
+
+void ClearBag(void)
+{
+ u16 i;
+
+ for (i = 0; i < POCKETS_COUNT; i++)
+ {
+ ClearItemSlots(gBagPockets[i].itemSlots, gBagPockets[i].capacity);
+ }
+}
+
+u16 CountTotalItemQuantityInBag(u16 itemId)
+{
+ u16 i;
+ u16 ownedCount = 0;
+ struct BagPocket *bagPocket = &gBagPockets[ItemId_GetPocket(itemId) - 1];
+
+ for (i = 0; i < bagPocket->capacity; i++)
+ {
+ if (bagPocket->itemSlots[i].itemId == itemId)
+ ownedCount += GetBagItemQuantity(&bagPocket->itemSlots[i].quantity);
+ }
+
+ return ownedCount;
+}
+
+static bool8 CheckPyramidBagHasItem(u16 itemId, u16 count)
+{
+ u8 i;
+ u16 *items = gSaveBlock2Ptr->pyramidBag.itemId[gSaveBlock2Ptr->frontierChosenLvl];
+ u8 *quantities = gSaveBlock2Ptr->pyramidBag.quantity[gSaveBlock2Ptr->frontierChosenLvl];
+
+ for (i = 0; i < PYRAMID_BAG_ITEMS_COUNT; i++)
+ {
+ if (items[i] == itemId)
+ {
+ if (quantities[i] >= count)
+ return TRUE;
+
+ count -= quantities[i];
+ if (count == 0)
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static bool8 CheckPyramidBagHasSpace(u16 itemId, u16 count)
+{
+ u8 i;
+ u16 *items = gSaveBlock2Ptr->pyramidBag.itemId[gSaveBlock2Ptr->frontierChosenLvl];
+ u8 *quantities = gSaveBlock2Ptr->pyramidBag.quantity[gSaveBlock2Ptr->frontierChosenLvl];
+
+ for (i = 0; i < PYRAMID_BAG_ITEMS_COUNT; i++)
+ {
+ if (items[i] == itemId || items[i] == ITEM_NONE)
+ {
+ if (quantities[i] + count <= 99)
+ return TRUE;
+
+ count = (quantities[i] + count) - 99;
+ if (count == 0)
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+bool8 AddPyramidBagItem(u16 itemId, u16 count)
+{
+ u16 i;
+
+ u16 *items = gSaveBlock2Ptr->pyramidBag.itemId[gSaveBlock2Ptr->frontierChosenLvl];
+ u8 *quantities = gSaveBlock2Ptr->pyramidBag.quantity[gSaveBlock2Ptr->frontierChosenLvl];
+
+ u16 *newItems = Alloc(PYRAMID_BAG_ITEMS_COUNT * sizeof(u16));
+ u8 *newQuantities = Alloc(PYRAMID_BAG_ITEMS_COUNT * sizeof(u8));
+
+ memcpy(newItems, items, PYRAMID_BAG_ITEMS_COUNT * sizeof(u16));
+ memcpy(newQuantities, quantities, PYRAMID_BAG_ITEMS_COUNT * sizeof(u8));
+
+ for (i = 0; i < PYRAMID_BAG_ITEMS_COUNT; i++)
+ {
+ if (newItems[i] == itemId && newQuantities[i] < 99)
+ {
+ newQuantities[i] += count;
+ if (newQuantities[i] > 99)
+ {
+ count = newQuantities[i] - 99;
+ newQuantities[i] = 99;
+ }
+ else
+ {
+ count = 0;
+ }
+
+ if (count == 0)
+ break;
+ }
+ }
+
+ if (count > 0)
+ {
+ for (i = 0; i < PYRAMID_BAG_ITEMS_COUNT; i++)
+ {
+ if (newItems[i] == ITEM_NONE)
+ {
+ newItems[i] = itemId;
+ newQuantities[i] = count;
+ if (newQuantities[i] > 99)
+ {
+ count = newQuantities[i] - 99;
+ newQuantities[i] = 99;
+ }
+ else
+ {
+ count = 0;
+ }
+
+ if (count == 0)
+ break;
+ }
+ }
+ }
+
+ if (count == 0)
+ {
+ memcpy(items, newItems, PYRAMID_BAG_ITEMS_COUNT * sizeof(u16));
+ memcpy(quantities, newQuantities, PYRAMID_BAG_ITEMS_COUNT * sizeof(u8));
+ Free(newItems);
+ Free(newQuantities);
+ return TRUE;
+ }
+ else
+ {
+ Free(newItems);
+ Free(newQuantities);
+ return FALSE;
+ }
+}
+
+bool8 RemovePyramidBagItem(u16 itemId, u16 count)
+{
+ u16 i;
+
+ u16 *items = gSaveBlock2Ptr->pyramidBag.itemId[gSaveBlock2Ptr->frontierChosenLvl];
+ u8 *quantities = gSaveBlock2Ptr->pyramidBag.quantity[gSaveBlock2Ptr->frontierChosenLvl];
+
+ i = gUnknown_0203CF30[3] + gUnknown_0203CF30[4];
+ if (items[i] == itemId && quantities[i] >= count)
+ {
+ quantities[i] -= count;
+ if (quantities[i] == 0)
+ items[i] = ITEM_NONE;
+ return TRUE;
+ }
+ else
+ {
+ u16 *newItems = Alloc(PYRAMID_BAG_ITEMS_COUNT * sizeof(u16));
+ u8 *newQuantities = Alloc(PYRAMID_BAG_ITEMS_COUNT * sizeof(u8));
+
+ memcpy(newItems, items, PYRAMID_BAG_ITEMS_COUNT * sizeof(u16));
+ memcpy(newQuantities, quantities, PYRAMID_BAG_ITEMS_COUNT * sizeof(u8));
+
+ for (i = 0; i < PYRAMID_BAG_ITEMS_COUNT; i++)
+ {
+ if (newItems[i] == itemId)
+ {
+ if (newQuantities[i] >= count)
+ {
+ newQuantities[i] -= count;
+ count = 0;
+ if (newQuantities[i] == 0)
+ newItems[i] = ITEM_NONE;
+ }
+ else
+ {
+ count -= newQuantities[i];
+ newQuantities[i] = 0;
+ newItems[i] = ITEM_NONE;
+ }
+
+ if (count == 0)
+ break;
+ }
+ }
+
+ if (count == 0)
+ {
+ memcpy(items, newItems, PYRAMID_BAG_ITEMS_COUNT * sizeof(u16));
+ memcpy(quantities, newQuantities, PYRAMID_BAG_ITEMS_COUNT * sizeof(u8));
+ Free(newItems);
+ Free(newQuantities);
+ return TRUE;
+ }
+ else
+ {
+ Free(newItems);
+ Free(newQuantities);
+ return FALSE;
+ }
+ }
+}
+
+static u16 SanitizeItemId(u16 itemId)
+{
+ if (itemId >= ITEM_LAST_ID + 1)
+ return ITEM_NONE;
+ else
+ return itemId;
+}
+
+const u8 *ItemId_GetName(u16 itemId)
+{
+ return gItems[SanitizeItemId(itemId)].name;
+}
+
+u16 ItemId_GetId(u16 itemId)
+{
+ return gItems[SanitizeItemId(itemId)].itemId;
+}
+
+u16 ItemId_GetPrice(u16 itemId)
+{
+ return gItems[SanitizeItemId(itemId)].price;
+}
+
+u8 ItemId_GetHoldEffect(u16 itemId)
+{
+ return gItems[SanitizeItemId(itemId)].holdEffect;
+}
+
+u8 ItemId_GetHoldEffectParam(u16 itemId)
+{
+ return gItems[SanitizeItemId(itemId)].holdEffectParam;
+}
+
+const u8 *ItemId_GetDescription(u16 itemId)
+{
+ return gItems[SanitizeItemId(itemId)].description;
+}
+
+u8 ItemId_GetImportance(u16 itemId)
+{
+ return gItems[SanitizeItemId(itemId)].importance;
+}
+
+// unused
+u8 ItemId_GetUnknownValue(u16 itemId)
+{
+ return gItems[SanitizeItemId(itemId)].unk19;
+}
+
+u8 ItemId_GetPocket(u16 itemId)
+{
+ return gItems[SanitizeItemId(itemId)].pocket;
+}
+
+u8 ItemId_GetType(u16 itemId)
+{
+ return gItems[SanitizeItemId(itemId)].type;
+}
+
+ItemUseFunc ItemId_GetFieldFunc(u16 itemId)
+{
+ return gItems[SanitizeItemId(itemId)].fieldUseFunc;
+}
+
+u8 ItemId_GetBattleUsage(u16 itemId)
+{
+ return gItems[SanitizeItemId(itemId)].battleUsage;
+}
+
+ItemUseFunc ItemId_GetBattleFunc(u16 itemId)
+{
+ return gItems[SanitizeItemId(itemId)].battleUseFunc;
+}
+
+u8 ItemId_GetSecondaryId(u16 itemId)
+{
+ return gItems[SanitizeItemId(itemId)].secondaryId;
+}
diff --git a/src/item_icon.c b/src/item_icon.c
index 4aaad9c31..d6fedf892 100644
--- a/src/item_icon.c
+++ b/src/item_icon.c
@@ -4,13 +4,13 @@
#include "sprite.h"
#include "decompress.h"
#include "constants/items.h"
+#include "data/item_icon_table.h"
// EWRAM vars
EWRAM_DATA void *gItemIconDecompressionBuffer = NULL;
EWRAM_DATA void *gItemIcon4x4Buffer = NULL;
// const rom data
-extern const void *const gItemIconTable[][2]; // todo: move to C file
static const struct OamData sOamData_ItemIcon =
{
diff --git a/src/item_menu.c b/src/item_menu.c
new file mode 100755
index 000000000..4742d07a1
--- /dev/null
+++ b/src/item_menu.c
@@ -0,0 +1,2245 @@
+#include "global.h"
+#include "item_menu.h"
+#include "battle.h"
+#include "battle_controllers.h"
+#include "battle_frontier_2.h"
+#include "berry_tag_screen.h"
+#include "bg.h"
+#include "constants/items.h"
+#include "constants/songs.h"
+#include "decompress.h"
+#include "event_data.h"
+#include "field_map_obj_helpers.h"
+#include "field_player_avatar.h"
+#include "field_specials.h"
+#include "graphics.h"
+#include "gpu_regs.h"
+#include "international_string_util.h"
+#include "item.h"
+#include "item_menu_icons.h"
+#include "item_use.h"
+#include "lilycove_lady.h"
+#include "list_menu.h"
+#include "link.h"
+#include "mail.h"
+#include "main.h"
+#include "malloc.h"
+#include "map_name_popup.h"
+#include "menu.h"
+#include "menu_indicators.h"
+#include "money.h"
+#include "overworld.h"
+#include "palette.h"
+#include "party_menu.h"
+#include "player_pc.h"
+#include "pokemon.h"
+#include "pokemon_summary_screen.h"
+#include "rom_818CFC8.h"
+#include "scanline_effect.h"
+#include "script.h"
+#include "shop.h"
+#include "sound.h"
+#include "sprite.h"
+#include "string.h"
+#include "strings.h"
+#include "string_util.h"
+#include "task.h"
+#include "text_window.h"
+#include "menu_helpers.h"
+#include "window.h"
+
+void GoToBagMenu(u8 bagMenuType, u8 pocketId, void ( *postExitMenuMainCallback2)());
+void CB2_Bag(void);
+bool8 setup_bag_menu(void);
+void bag_menu_init_bgs(void);
+bool8 load_bag_menu_graphics(void);
+void setup_bag_menu_textboxes(void);
+void allocate_bag_item_list_buffers(void);
+void load_bag_item_list_buffers(u8);
+void bag_menu_print_pocket_names(u8*, u8*);
+void bag_menu_copy_pocket_name_to_window(u32);
+void bag_menu_draw_pocket_indicator_square(u8, u8);
+void bag_menu_add_pocket_scroll_arrow_indicators_maybe(void);
+void bag_menu_add_list_scroll_arrow_indicators_maybe(void);
+void bag_menu_prepare_tmhm_move_window(void);
+bool8 IsWallysBag(void);
+void Task_WallyTutorialBagMenu(u8);
+void Task_BagMenu(u8);
+void get_name(s8*, u16);
+u16 ItemIdToBattleMoveId(u16);
+u16 BagGetItemIdByPocketPosition(u8, u16);
+void AddBagItemIconSprite(u16, u8);
+void bag_menu_print_description_box_text(int);
+void bag_menu_print_cursor(u8, u8);
+void bag_menu_print(u8, u8, const u8*, u8, u8, u8, u8, u8, u8);
+bool8 ItemId_GetImportance(u16);
+u16 BagGetQuantityByPocketPosition(u8, u16);
+void sub_81AB89C(void);
+void task_close_bag_menu_2(u8);
+u8 AddItemMessageWindow(u8);
+void bag_menu_RemoveBagItem_message_window(u8);
+void set_callback3_to_bag(u8);
+void sub_81ABC54(u8, s16);
+u8 bag_menu_add_window(u8);
+u8 GetSwitchBagPocketDirection(void);
+void SwitchBagPocket(u8, s16, u16);
+bool8 sub_81AC2C0(void);
+void bag_menu_swap_items(u8);
+void sub_81AC10C(u8);
+void sub_81AC3C0(u8);
+void sub_81AC498(u8);
+void sub_81AC590(u8);
+void PrintTMHMMoveData(u16);
+void sub_81ACAF8(u8);
+void sub_81ACB54(u8, u8, u8);
+void Task_HandleInBattleItemMenuInput(u8);
+void Task_HandleOutOfBattleItemMenuInput(u8);
+bool8 sub_81ACDFC(s8);
+void bag_menu_remove_window(u8);
+void bag_menu_print_there_is_no_pokemon(u8);
+void Task_ChooseHowManyToToss(u8);
+void BagMenuConfirmToss(u8);
+void bag_menu_yes_no(u8, u8, const struct YesNoFuncTable*);
+void Task_ActuallyToss(u8);
+void ItemMenu_Cancel(u8);
+void sub_81AD350(u8);
+void bag_menu_print_cant_be_held_msg(u8);
+void bag_menu_AddMoney_window(void);
+void sub_81AD680(u8);
+void sub_81AD730(u8);
+void sub_81AD6E4(u8);
+void bag_menu_remove_money_window(void);
+void bag_menu_RemoveBagItem_message_window(u8);
+void sub_81AD794(u8);
+void sub_81AD8C8(u8);
+void sub_81AD9C0(u8);
+void sub_81ADB14(u8);
+void sub_81ADA7C(u8);
+void sub_81ADC0C(u8);
+void bag_menu_leave_maybe_3(void);
+void bag_menu_leave_maybe_2(void);
+void bag_menu_leave_maybe(void);
+void sub_81ABA6C(void);
+void sub_81ABAC4(void);
+void sub_81ABAE0(void);
+u8 sub_81AB1F0(u8);
+void sub_81AC23C(u8);
+void bag_menu_change_item_callback(s32 a, bool8 b, struct ListMenu*);
+void sub_81AB520(u8 rboxId, int item_index_in_pocket, u8 a);
+void ItemMenu_UseOutOfBattle(u8 taskId);
+void ItemMenu_Toss(u8 taskId);
+void ItemMenu_Register(u8 taskId);
+void ItemMenu_Give(u8 taskId);
+void ItemMenu_Cancel(u8 taskId);
+void ItemMenu_UseInBattle(u8 taskId);
+void ItemMenu_CheckTag(u8 taskId);
+void unknown_ItemMenu_Confirm(u8 taskId);
+void unknown_ItemMenu_Show(u8 taskId);
+void unknown_ItemMenu_Give2(u8 taskId);
+void unknown_ItemMenu_Confirm2(u8 taskId);
+void unknown_item_menu_type(u8 taskId);
+void item_menu_type_2(u8 taskId);
+void display_sell_item_ask_str(u8 taskId);
+void unknown_ItemMenu_Confirm(u8 taskId);
+void display_deposit_item_ask_str(u8 taskId);
+void item_menu_type_b(u8 taskId);
+void BagMenuActuallyToss(u8 taskId);
+void BagMenuCancelToss(u8 taskId);
+void sub_81AD84C(u8 taskId);
+void sub_81AD6FC(u8 taskId);
+
+// .rodata
+
+const struct BgTemplate gUnknown_08613F90[3] = {
+ {0, 0, 31, 0, 0, 1, 0},
+ {1, 0, 30, 0, 0, 0, 0},
+ {2, 3, 29, 0, 0, 2, 0}
+};
+
+const struct ListMenuTemplate gUnknown_08613F9C = {
+ NULL, bag_menu_change_item_callback, sub_81AB520, 0, 0, 0, 0, 8, 0, 1, 1, 0, 3, 0, 0, 0, 7, 0
+};
+
+const struct MenuAction gUnknown_08613FB4[] = {
+ {gMenuText_Use, ItemMenu_UseOutOfBattle},
+ {gMenuText_Toss, ItemMenu_Toss},
+ {gMenuText_Register, ItemMenu_Register},
+ {gMenuText_Give, ItemMenu_Give},
+ {gText_Cancel2, ItemMenu_Cancel},
+ {gMenuText_Use, ItemMenu_UseInBattle},
+ {gMenuText_Check, ItemMenu_UseOutOfBattle},
+ {gMenuText_Walk, ItemMenu_UseOutOfBattle},
+ {gMenuText_Deselect, ItemMenu_Register},
+ {gMenuText_CheckTag, ItemMenu_CheckTag},
+ {gMenuText_Confirm, unknown_ItemMenu_Confirm},
+ {gMenuText_Show, unknown_ItemMenu_Show},
+ {gMenuText_Give2, unknown_ItemMenu_Give2},
+ {gMenuText_Confirm, unknown_ItemMenu_Confirm2},
+ {gText_EmptyString2, NULL}
+};
+
+const u8 gUnknown_0861402C[] = {0, 3, 1, 4};
+const u8 gUnknown_08614030[] = {0, 2, 14, 4};
+const u8 gUnknown_08614034[] = {3, 14, 1, 4};
+const u8 gUnknown_08614038[] = {0, 3, 14, 4};
+const u8 gUnknown_0861403C[] = {9, 14, 0, 3, 1, 4};
+const u8 gUnknown_08614042[] = {5, 4};
+const u8 gUnknown_08614044[] = {3, 4};
+const u8 gUnknown_08614046 = 4;
+const u8 gUnknown_08614047[] = {10, 9, 14, 4};
+const u8 gUnknown_0861404B[] = {11, 4};
+const u8 gUnknown_0861404D[] = {12, 4};
+const u8 gUnknown_0861404F[] = {13, 4};
+
+const TaskFunc gUnknown_08614054[] = {
+ unknown_item_menu_type,
+ unknown_item_menu_type,
+ item_menu_type_2,
+ display_sell_item_ask_str,
+ unknown_ItemMenu_Confirm,
+ unknown_item_menu_type,
+ display_deposit_item_ask_str,
+ unknown_item_menu_type,
+ unknown_item_menu_type,
+ unknown_item_menu_type,
+ NULL,
+ item_menu_type_b
+};
+
+const struct YesNoFuncTable gUnknown_08614084 = {BagMenuActuallyToss, BagMenuCancelToss};
+
+const struct YesNoFuncTable gUnknown_0861408C = {sub_81AD84C, sub_81AD6FC};
+
+const struct ArrowStruct gUnknown_08614094 = {0, 0x1C, 16, 1, 100, 16, -1, -1, 0x6F, 0x6F, 0};
+
+const u8 gUnknown_086140A4[] = INCBIN_U8("graphics/interface/select_button.4bpp");
+
+const u8 gUnknown_08614164[][3] = {
+ {0, 1, 3},
+ {0, 1, 4},
+ {0, 3, 6},
+ {2, 1, 3},
+ {0, 14, 10}
+};
+
+const struct WindowTemplate gUnknown_08614174[] = {
+ {0, 14, 2, 15, 16, 1, 0x27},
+ {0, 0, 13, 14, 6, 1, 0x117},
+ {0, 4, 1, 8, 2, 1, 0x1A1},
+ {0, 1, 13, 5, 6, 12, 0x16B},
+ {0, 7, 13, 4, 6, 12, 0x189},
+ {1, 2, 15, 27, 4, 15, 0x1B1},
+ {0xFF, 0, 0, 0, 0, 0, 0}
+};
+
+const struct WindowTemplate gUnknown_086141AC[] = {
+ {1, 22, 17, 7, 2, 15, 0x21D},
+ {1, 22, 15, 7, 4, 15, 0x21D},
+ {1, 15, 15, 14, 4, 15, 0x21D},
+ {1, 15, 13, 14, 6, 15, 0x21D},
+ {1, 2, 15, 27, 4, 15, 0x1B1},
+ {1, 24, 15, 5, 4, 15, 0x21D},
+ {1, 21, 9, 5, 4, 15, 0x21D},
+ {1, 24, 17, 5, 2, 15, 0x21D},
+ {1, 18, 11, 10, 2, 15, 0x245},
+ {1, 1, 1, 10, 2, 15, 0x231}
+};
+
+// .text
+
+struct ListBuffer1 {
+ struct ListMenuItem subBuffers[65];
+};
+
+struct ListBuffer2 {
+ s8 name[65][24];
+};
+
+struct TempWallyStruct {
+ struct ItemSlot bagPocket_Items[30];
+ struct ItemSlot bagPocket_PokeBalls[16];
+ u16 cursorPosition[5];
+ u16 scrollPosition[5];
+ u8 filler[0x2];
+ u16 pocket;
+};
+
+EWRAM_DATA struct UnkBagStruct *gUnknown_0203CE54 = 0;
+EWRAM_DATA struct BagStruct gUnknown_0203CE58 = {0, 0, 0, {0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}};
+EWRAM_DATA struct ListBuffer1 *gUnknown_0203CE74 = 0;
+EWRAM_DATA struct ListBuffer2 *gUnknown_0203CE78 = 0;
+EWRAM_DATA u16 gSpecialVar_ItemId = 0;
+EWRAM_DATA struct TempWallyStruct *gUnknown_0203CE80 = 0;
+
+extern u8 *gPocketNamesStringsTable[];
+extern u8 gUnknown_08D9A88C[];
+extern struct ListMenuTemplate gUnknown_08613F9C;
+extern const u8 gMoveNames[][0xD];
+extern u8* gReturnToXStringsTable[];
+extern u32 gUnknown_0203CE5E[];
+extern const u8 EventScript_2736B3[];
+extern const u16 gUnknown_0860F074[];
+
+void ResetBagScrollPositions(void)
+{
+ gUnknown_0203CE58.pocket = 0;
+ memset(gUnknown_0203CE58.cursorPosition, 0, 10);
+ memset(gUnknown_0203CE58.scrollPosition, 0, 10);
+}
+
+void CB2_BagMenuFromStartMenu(void)
+{
+ GoToBagMenu(0, 5, CB2_ReturnToFieldWithOpenMenu);
+}
+
+void sub_81AABB0(void)
+{
+ if (!InBattlePyramid())
+ GoToBagMenu(1, 5, SetCB2ToReshowScreenAfterMenu2);
+ else
+ sub_81C4F98(1, SetCB2ToReshowScreenAfterMenu2);
+}
+
+void CB2_ChooseBerry(void)
+{
+ GoToBagMenu(4, 3, sub_80861B0);
+}
+
+void sub_81AABF0(void(*callback)(void))
+{
+ GoToBagMenu(5, 3, callback);
+}
+
+void CB2_GoToSellMenu(void)
+{
+ GoToBagMenu(3, 5, CB2_ExitSellMenu);
+}
+
+void sub_81AAC14(void)
+{
+ GoToBagMenu(6, 5, sub_816B31C);
+}
+
+void sub_81AAC28(void)
+{
+ GoToBagMenu(9, 5, bag_menu_leave_maybe_3);
+ gSpecialVar_0x8005 = 0;
+ gSpecialVar_Result = 0;
+}
+
+void sub_81AAC50(void)
+{
+ GoToBagMenu(7, 5, bag_menu_leave_maybe_2);
+ gSpecialVar_Result = 0;
+}
+
+void sub_81AAC70(void)
+{
+ GoToBagMenu(8, 5, bag_menu_leave_maybe);
+ gSpecialVar_Result = 0;
+}
+
+void GoToBagMenu(u8 bagMenuType, u8 pocketId, void ( *postExitMenuMainCallback2)())
+{
+ u8 temp;
+ gUnknown_0203CE54 = AllocZeroed(sizeof(struct UnkBagStruct));
+ if (gUnknown_0203CE54 == 0)
+ {
+ SetMainCallback2(postExitMenuMainCallback2);
+ }
+ else
+ {
+ if (bagMenuType != 12)
+ gUnknown_0203CE58.location = bagMenuType;
+ if (postExitMenuMainCallback2)
+ gUnknown_0203CE58.bagCallback = postExitMenuMainCallback2;
+ if (pocketId <= 4)
+ gUnknown_0203CE58.pocket = pocketId;
+ temp = gUnknown_0203CE58.location - 4;
+ if (temp <= 1)
+ gUnknown_0203CE54->unk81B = 1;
+ gUnknown_0203CE54->unk0 = 0;
+ gUnknown_0203CE54->unk81A = 0xFF;
+ gUnknown_0203CE54->unk81E = -1;
+ gUnknown_0203CE54->unk81F = -1;
+ memset(gUnknown_0203CE54->unk804, 0xFF, sizeof(gUnknown_0203CE54->unk804));
+ memset(gUnknown_0203CE54->unk810, 0xFF, 10);
+ SetMainCallback2(CB2_Bag);
+ }
+}
+
+void c2_bag_3(void)
+{
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ do_scheduled_bg_tilemap_copies_to_vram();
+ UpdatePaletteFade();
+}
+
+void vblank_cb_bag_menu(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+void CB2_Bag(void)
+{
+ while(sub_81221EC() != TRUE && setup_bag_menu() != TRUE && sub_81221AC() != TRUE) {};
+}
+
+bool8 setup_bag_menu(void)
+{
+ u32 index;
+ u8 taskId;
+
+ switch (gMain.state)
+ {
+ case 0:
+ SetVBlankHBlankCallbacksToNull();
+ clear_scheduled_bg_copies_to_vram();
+ gMain.state++;
+ break;
+ case 1:
+ ScanlineEffect_Stop();
+ gMain.state++;
+ break;
+ case 2:
+ FreeAllSpritePalettes();
+ gMain.state++;
+ break;
+ case 3:
+ ResetPaletteFade();
+ gPaletteFade.bufferTransferDisabled = TRUE;
+ gMain.state++;
+ break;
+ case 4:
+ ResetSpriteData();
+ gMain.state++;
+ break;
+ case 5:
+ gMain.state++;
+ break;
+ case 6:
+ if (sub_81221AC() == FALSE)
+ ResetTasks();
+ gMain.state++;
+ break;
+ case 7:
+ bag_menu_init_bgs();
+ gUnknown_0203CE54->unk834 = 0;
+ gMain.state++;
+ break;
+ case 8:
+ if (!load_bag_menu_graphics())
+ break;
+ gMain.state++;
+ break;
+ case 9:
+ setup_bag_menu_textboxes();
+ gMain.state++;
+ break;
+ case 10:
+ sub_81ABA6C();
+ sub_81ABAC4();
+ sub_81ABAE0();
+ gMain.state++;
+ break;
+ case 11:
+ allocate_bag_item_list_buffers();
+ gMain.state++;
+ break;
+ case 12:
+ load_bag_item_list_buffers(gUnknown_0203CE58.pocket);
+ gMain.state++;
+ break;
+ case 13:
+ bag_menu_print_pocket_names(gPocketNamesStringsTable[gUnknown_0203CE58.pocket], 0);
+ bag_menu_copy_pocket_name_to_window(0);
+ bag_menu_draw_pocket_indicator_square(gUnknown_0203CE58.pocket, 1);
+ gMain.state++;
+ break;
+ case 14:
+ taskId = sub_81AB1F0(gUnknown_0203CE58.location);
+ gTasks[taskId].data[0] = ListMenuInit(&gMultiuseListMenuTemplate, gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket], gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]);
+ gTasks[taskId].data[3] = 0;
+ gTasks[taskId].data[8] = 0;
+ gMain.state++;
+ break;
+ case 15:
+ AddBagVisualSprite(gUnknown_0203CE58.pocket);
+ gMain.state++;
+ break;
+ case 16:
+ sub_80D4FAC();
+ gMain.state++;
+ break;
+ case 17:
+ bag_menu_add_pocket_scroll_arrow_indicators_maybe();
+ bag_menu_add_list_scroll_arrow_indicators_maybe();
+ gMain.state++;
+ break;
+ case 18:
+ bag_menu_prepare_tmhm_move_window();
+ gMain.state++;
+ break;
+ case 19:
+ BlendPalettes(-1, 16, 0);
+ gMain.state++;
+ break;
+ case 20:
+ BeginNormalPaletteFade(-1, 0, 16, 0, 0);
+ gPaletteFade.bufferTransferDisabled = FALSE;
+ gMain.state++;
+ break;
+ default:
+ SetVBlankCallback(vblank_cb_bag_menu);
+ SetMainCallback2(c2_bag_3);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void bag_menu_init_bgs(void)
+{
+ ResetVramOamAndBgCntRegs();
+ memset(gUnknown_0203CE54->unk4, 0, 0x800);
+ ResetBgsAndClearDma3BusyFlags(0);
+ InitBgsFromTemplates(0, gUnknown_08613F90, 3);
+ SetBgTilemapBuffer(2, gUnknown_0203CE54->unk4);
+ ResetAllBgsCoordinates();
+ schedule_bg_copy_tilemap_to_vram(2);
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
+ ShowBg(0);
+ ShowBg(1);
+ ShowBg(2);
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+}
+
+bool8 load_bag_menu_graphics(void)
+{
+ switch (gUnknown_0203CE54->unk834)
+ {
+ case 0:
+ reset_temp_tile_data_buffers();
+ decompress_and_copy_tile_data_to_vram(2, gBagScreen_Gfx, 0, 0, 0);
+ gUnknown_0203CE54->unk834++;
+ break;
+ case 1:
+ if (free_temp_tile_data_buffers_if_possible() != TRUE)
+ {
+ LZDecompressWram(gUnknown_08D9A88C, gUnknown_0203CE54->unk4);
+ gUnknown_0203CE54->unk834++;
+ }
+ break;
+ case 2:
+ if (!IsWallysBag() && gSaveBlock2Ptr->playerGender != MALE)
+ LoadCompressedPalette(gBagScreenFemale_Pal, 0, 0x40);
+ else
+ LoadCompressedPalette(gBagScreenMale_Pal, 0, 0x40);
+ gUnknown_0203CE54->unk834++;
+ break;
+ case 3:
+ if (IsWallysBag() == TRUE || gSaveBlock2Ptr->playerGender == MALE)
+ LoadCompressedObjectPic(&gUnknown_0857FB34);
+ else
+ LoadCompressedObjectPic(&gUnknown_0857FB3C);
+ gUnknown_0203CE54->unk834++;
+ break;
+ case 4:
+ LoadCompressedObjectPalette(&gUnknown_0857FB44);
+ gUnknown_0203CE54->unk834++;
+ break;
+ default:
+ LoadListMenuArrowsGfx();
+ gUnknown_0203CE54->unk834 = 0;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+u8 sub_81AB1F0(u8 a)
+{
+ u8 taskId;
+ if (a == 10)
+ taskId = CreateTask(Task_WallyTutorialBagMenu, 0);
+ else
+ taskId = CreateTask(Task_BagMenu, 0);
+ return taskId;
+}
+
+void allocate_bag_item_list_buffers(void)
+{
+ gUnknown_0203CE74 = Alloc(sizeof(struct ListBuffer1));
+ gUnknown_0203CE78 = Alloc(sizeof(struct ListBuffer2));
+}
+
+void load_bag_item_list_buffers(u8 pocketId)
+{
+ u16 i;
+ struct BagPocket *pocket = &gBagPockets[pocketId];
+ struct ListMenuItem *subBuffer;
+
+ if (!gUnknown_0203CE54->unk81B_2)
+ {
+ for (i = 0; i < gUnknown_0203CE54->unk829[pocketId] - 1; i++)
+ {
+ get_name(gUnknown_0203CE78->name[i], pocket->itemSlots[i].itemId);
+ subBuffer = gUnknown_0203CE74->subBuffers;
+ subBuffer[i].name = gUnknown_0203CE78->name[i];
+ subBuffer[i].id = i;
+ }
+ StringCopy(gUnknown_0203CE78->name[i], gText_CloseBag);
+ subBuffer = gUnknown_0203CE74->subBuffers;
+ subBuffer[i].name = gUnknown_0203CE78->name[i];
+ subBuffer[i].id = -2;
+ }
+ else
+ {
+ for (i = 0; i < gUnknown_0203CE54->unk829[pocketId]; i++)
+ {
+ get_name(gUnknown_0203CE78->name[i], pocket->itemSlots[i].itemId);
+ subBuffer = gUnknown_0203CE74->subBuffers;
+ subBuffer[i].name = gUnknown_0203CE78->name[i];
+ subBuffer[i].id = i;
+ }
+ }
+ gMultiuseListMenuTemplate = gUnknown_08613F9C;
+ gMultiuseListMenuTemplate.totalItems = gUnknown_0203CE54->unk829[pocketId];
+ gMultiuseListMenuTemplate.items = gUnknown_0203CE74->subBuffers;
+ gMultiuseListMenuTemplate.maxShowed = gUnknown_0203CE54->unk82E[pocketId];
+}
+
+void get_name(s8 *dest, u16 itemId)
+{
+ switch (gUnknown_0203CE58.pocket)
+ {
+ case 2:
+ StringCopy(gStringVar2, gMoveNames[ItemIdToBattleMoveId(itemId)]);
+ if (itemId >= ITEM_HM01)
+ {
+ ConvertIntToDecimalStringN(gStringVar1, itemId - ITEM_HM01 + 1, 2, 1);
+ StringExpandPlaceholders(dest, gText_ClearTo11Var1Clear5Var2);
+ }
+ else
+ {
+ ConvertIntToDecimalStringN(gStringVar1, itemId - ITEM_TM01 + 1, 2, 2);
+ StringExpandPlaceholders(dest, gText_UnkF908Var1Clear7Var2);
+ }
+ break;
+ case 3:
+ ConvertIntToDecimalStringN(gStringVar1, itemId - ITEM_CHERI_BERRY + 1, 2, 2);
+ CopyItemName(itemId, gStringVar2);
+ StringExpandPlaceholders(dest, gText_UnkF908Var1Clear7Var2);
+ break;
+ default:
+ CopyItemName(itemId, dest);
+ break;
+ }
+}
+
+void bag_menu_change_item_callback(s32 a, bool8 b, struct ListMenu *unused)
+{
+ if (b != 1)
+ {
+ PlaySE(SE_SELECT);
+ ShakeBagVisual();
+ }
+ if (gUnknown_0203CE54->unk81A == 0xFF)
+ {
+ RemoveBagItemIconSprite(1 ^ gUnknown_0203CE54->unk81B_1);
+ if (a != -2)
+ AddBagItemIconSprite(BagGetItemIdByPocketPosition(gUnknown_0203CE58.pocket + 1, a), gUnknown_0203CE54->unk81B_1);
+ else
+ AddBagItemIconSprite(-1, gUnknown_0203CE54->unk81B_1);
+ gUnknown_0203CE54->unk81B_1 ^= 1;
+ if (!gUnknown_0203CE54->unk81B_3)
+ bag_menu_print_description_box_text(a);
+ }
+}
+
+void sub_81AB520(u8 rboxId, int item_index_in_pocket, u8 a)
+{
+ u16 itemId;
+ u16 itemQuantity;
+ bool8 unique;
+ int offset;
+ if (item_index_in_pocket != -2)
+ {
+ if (gUnknown_0203CE54->unk81A != 0xFF)
+ {
+ if (gUnknown_0203CE54->unk81A == (u8)item_index_in_pocket)
+ bag_menu_print_cursor(a, 2);
+ else
+ bag_menu_print_cursor(a, -1);
+ }
+ itemId = BagGetItemIdByPocketPosition(gUnknown_0203CE58.pocket + 1, item_index_in_pocket);
+ itemQuantity = BagGetQuantityByPocketPosition(gUnknown_0203CE58.pocket + 1, item_index_in_pocket);
+ if ((u16)(itemId - ITEM_HM01) <= 7)
+ BlitBitmapToWindow(rboxId, gBagMenuHMIcon_Gfx, 8, a - 1, 16, 16);
+ if (gUnknown_0203CE58.pocket == 3)
+ {
+ ConvertIntToDecimalStringN(gStringVar1, itemQuantity, 1, 3);
+ StringExpandPlaceholders(gStringVar4, gText_xVar1);
+ offset = GetStringRightAlignXOffset(7, gStringVar4, 0x77);
+ bag_menu_print(rboxId, 7, gStringVar4, offset, a, 0, 0, -1, 0);
+ }
+ else if (gUnknown_0203CE58.pocket != 4 && (unique = ItemId_GetImportance(itemId)) == FALSE)
+ {
+ ConvertIntToDecimalStringN(gStringVar1, itemQuantity, 1, 2);
+ StringExpandPlaceholders(gStringVar4, gText_xVar1);
+ offset = GetStringRightAlignXOffset(7, gStringVar4, 0x77);
+ bag_menu_print(rboxId, 7, gStringVar4, offset, a, unique, unique, -1, unique);
+ }
+ else
+ {
+ if (gSaveBlock1Ptr->registeredItem && gSaveBlock1Ptr->registeredItem == itemId)
+ BlitBitmapToWindow(rboxId, gUnknown_086140A4, 0x60, a - 1, 0x18, 16);
+ }
+ }
+}
+
+void bag_menu_print_description_box_text(int a)
+{
+ u8* str;
+ if (a != -2)
+ {
+ str = (u8*)ItemId_GetDescription(BagGetItemIdByPocketPosition(gUnknown_0203CE58.pocket + 1, a));
+ }
+ else
+ {
+ StringCopy(gStringVar1, gReturnToXStringsTable[gUnknown_0203CE58.location]);
+ StringExpandPlaceholders(gStringVar4, gText_ReturnToVar1);
+ str = gStringVar4;
+ }
+ FillWindowPixelBuffer(1, 0);
+ bag_menu_print(1, 1, str, 3, 1, 0, 0, 0, 0);
+}
+
+void bag_menu_print_cursor_(u8 a, u8 b)
+{
+ bag_menu_print_cursor(ListMenuGetYCoordForPrintingArrowCursor(a), b);
+}
+
+void bag_menu_print_cursor(u8 a, u8 b)
+{
+ if (b == 0xFF)
+ FillWindowPixelRect(0, 0, 0, a, GetMenuCursorDimensionByFont(1, 0), GetMenuCursorDimensionByFont(1, 1));
+ else
+ bag_menu_print(0, 1, gText_SelectorArrow2, 0, a, 0, 0, 0, b);
+
+}
+
+void bag_menu_add_pocket_scroll_arrow_indicators_maybe(void)
+{
+ if (gUnknown_0203CE54->unk81E == 0xFF)
+ gUnknown_0203CE54->unk81E = AddScrollIndicatorArrowPairParametrized(2, 0xAC, 12, 0x94, gUnknown_0203CE54->unk829[gUnknown_0203CE58.pocket] - gUnknown_0203CE54->unk82E[gUnknown_0203CE58.pocket], 0x6E, 0x6E, &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket]);
+}
+
+void sub_81AB824(void)
+{
+ if (gUnknown_0203CE54->unk81E != 0xFF)
+ {
+ RemoveScrollIndicatorArrowPair(gUnknown_0203CE54->unk81E);
+ gUnknown_0203CE54->unk81E = 0xFF;
+ }
+ sub_81AB89C();
+}
+
+void bag_menu_add_list_scroll_arrow_indicators_maybe(void)
+{
+ if (gUnknown_0203CE54->unk81B != 1 && gUnknown_0203CE54->unk81F == 0xFF)
+ gUnknown_0203CE54->unk81F = AddScrollIndicatorArrowPair(&gUnknown_08614094, gUnknown_0203CE58.unk6);
+}
+
+void sub_81AB89C(void)
+{
+ if (gUnknown_0203CE54->unk81F != 0xFF)
+ {
+ RemoveScrollIndicatorArrowPair(gUnknown_0203CE54->unk81F);
+ gUnknown_0203CE54->unk81F = 0xFF;
+ }
+}
+
+void free_bag_item_list_buffers(void)
+{
+ Free(gUnknown_0203CE78);
+ Free(gUnknown_0203CE74);
+ FreeAllWindowBuffers();
+ Free(gUnknown_0203CE54);
+}
+
+void unknown_ItemMenu_Confirm(u8 taskId)
+{
+ BeginNormalPaletteFade(-1, 0, 0, 16, 0);
+ gTasks[taskId].func = task_close_bag_menu_2;
+}
+
+void task_close_bag_menu_2(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+ if (!gPaletteFade.active)
+ {
+ DestroyListMenuTask(data[0], &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket], &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]);
+ if (gUnknown_0203CE54->unk0 != 0)
+ SetMainCallback2(gUnknown_0203CE54->unk0);
+ else
+ SetMainCallback2(gUnknown_0203CE58.bagCallback);
+ sub_81AB824();
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ free_bag_item_list_buffers();
+ DestroyTask(taskId);
+ }
+}
+
+void sub_81AB9A8(u8 pocketId)
+{
+ u16 i;
+ struct BagPocket *pocket = &gBagPockets[pocketId];
+ switch (pocketId)
+ {
+ case 2:
+ case 3:
+ SortBerriesOrTMHMs(pocket);
+ break;
+ default:
+ CompactItemsInBagPocket(pocket);
+ break;
+ }
+ gUnknown_0203CE54->unk829[pocketId] = 0;
+ for (i = 0; i < pocket->capacity && pocket->itemSlots[i].itemId; i++)
+ gUnknown_0203CE54->unk829[pocketId]++;
+ if (!gUnknown_0203CE54->unk81B_2)
+ gUnknown_0203CE54->unk829[pocketId]++;
+ if (gUnknown_0203CE54->unk829[pocketId] > 8)
+ gUnknown_0203CE54->unk82E[pocketId] = 8;
+ else
+ gUnknown_0203CE54->unk82E[pocketId] = gUnknown_0203CE54->unk829[pocketId];
+}
+
+void sub_81ABA6C(void)
+{
+ u8 i;
+ for (i = 0; i < 5; i++)
+ sub_81AB9A8(i);
+}
+
+void sub_81ABA88(u8 a)
+{
+ sub_812225C(&gUnknown_0203CE58.scrollPosition[a], &gUnknown_0203CE58.cursorPosition[a], gUnknown_0203CE54->unk82E[a], gUnknown_0203CE54->unk829[a]);
+}
+
+void sub_81ABAC4(void)
+{
+ u8 i;
+ for (i = 0; i < 5; i++)
+ sub_81ABA88(i);
+}
+
+void sub_81ABAE0(void)
+{
+ u8 i;
+ for (i = 0; i < 5; i++)
+ sub_8122298(&gUnknown_0203CE58.scrollPosition[i], &gUnknown_0203CE58.cursorPosition[i], gUnknown_0203CE54->unk82E[i], gUnknown_0203CE54->unk829[i], 8);
+}
+
+u8 sub_81ABB2C(u8 pocketId)
+{
+ return gUnknown_0203CE58.scrollPosition[pocketId] + gUnknown_0203CE58.cursorPosition[pocketId];
+}
+
+void DisplayItemMessage(u8 taskId, u8 fontId, const u8 *str, void ( *callback)(u8 taskId))
+{
+ s16* data = gTasks[taskId].data;
+
+ data[10] = AddItemMessageWindow(4);
+ FillWindowPixelBuffer(data[10], 17);
+ DisplayMessageAndContinueTask(taskId, data[10], 10, 13, fontId, GetPlayerTextSpeed(), str, callback);
+ schedule_bg_copy_tilemap_to_vram(1);
+}
+
+void bag_menu_inits_lists_menu(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+ u16* scrollPos = &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket];
+ u16* cursorPos = &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket];
+ bag_menu_RemoveBagItem_message_window(4);
+ DestroyListMenuTask(data[0], scrollPos, cursorPos);
+ sub_81AB9A8(gUnknown_0203CE58.pocket);
+ sub_81ABA88(gUnknown_0203CE58.pocket);
+ load_bag_item_list_buffers(gUnknown_0203CE58.pocket);
+ data[0] = ListMenuInit(&gMultiuseListMenuTemplate, *scrollPos, *cursorPos);
+ schedule_bg_copy_tilemap_to_vram(0);
+ set_callback3_to_bag(taskId);
+}
+
+void sub_81ABC3C(u8 a)
+{
+ sub_81ABC54(bag_menu_add_window(a), 1);
+}
+
+void sub_81ABC54(u8 a, s16 b)
+{
+ u8 r3 = (gUnknown_0203CE58.pocket == 3) ? 3 : 2;
+ ConvertIntToDecimalStringN(gStringVar1, b, 2, r3);
+ StringExpandPlaceholders(gStringVar4, gText_xVar1);
+ PrintTextOnWindow(a, 1, gStringVar4, GetStringCenterAlignXOffset(1, gStringVar4, 0x28), 2, 0, 0);
+}
+
+void sub_81ABCC0(int a, int b, int c)
+{
+ u8 r3 = (gUnknown_0203CE58.pocket == 3) ? 3 : 2;
+ ConvertIntToDecimalStringN(gStringVar1, b, 2, r3);
+ StringExpandPlaceholders(gStringVar4, gText_xVar1);
+ PrintTextOnWindow(a, 1, gStringVar4, 0, 1, -1, 0);
+ PrintMoneyAmount(a, 0x26, 1, c, 0);
+}
+
+void Task_BagMenu(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+ u16* scrollPos = &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket];
+ u16* cursorPos = &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket];
+ u16 select;
+ if (sub_81221EC() != TRUE && !gPaletteFade.active)
+ {
+ switch (GetSwitchBagPocketDirection())
+ {
+ case 1:
+ SwitchBagPocket(taskId, -1, 0);
+ return;
+ case 2:
+ SwitchBagPocket(taskId, 1, 0);
+ return;
+ }
+ if ((select = (gMain.newKeys & SELECT_BUTTON)))
+ {
+ if (sub_81AC2C0() == 1)
+ {
+ ListMenuGetScrollAndRow(data[0], scrollPos, cursorPos);
+ if ((*scrollPos + *cursorPos) != gUnknown_0203CE54->unk829[gUnknown_0203CE58.pocket] - 1)
+ {
+ PlaySE(SE_SELECT);
+ bag_menu_swap_items(taskId);
+ }
+ }
+ return;
+ }
+ else
+ {
+ int r4 = ListMenuHandleInputGetItemId(data[0]);
+ ListMenuGetScrollAndRow(data[0], scrollPos, cursorPos);
+ switch (r4)
+ {
+ case -1:
+ break;
+ case -2:
+ if (gUnknown_0203CE58.location == 5)
+ {
+ PlaySE(SE_HAZURE);
+ break;
+ }
+ PlaySE(SE_SELECT);
+ gSpecialVar_ItemId = select;
+ gTasks[taskId].func = unknown_ItemMenu_Confirm;
+ break;
+ default:
+ PlaySE(SE_SELECT);
+ sub_81AB824();
+ bag_menu_print_cursor_(data[0], 2);
+ data[1] = r4;
+ data[2] = BagGetQuantityByPocketPosition(gUnknown_0203CE58.pocket + 1, r4);
+ gSpecialVar_ItemId = BagGetItemIdByPocketPosition(gUnknown_0203CE58.pocket + 1, r4);
+ gUnknown_08614054[gUnknown_0203CE58.location](taskId);
+ break;
+ }
+ }
+ }
+}
+
+void set_callback3_to_bag(u8 taskId)
+{
+ bag_menu_add_pocket_scroll_arrow_indicators_maybe();
+ bag_menu_add_list_scroll_arrow_indicators_maybe();
+ ClearWindowTilemap(3);
+ ClearWindowTilemap(4);
+ PutWindowTilemap(1);
+ schedule_bg_copy_tilemap_to_vram(0);
+ gTasks[taskId].func = Task_BagMenu;
+}
+
+u8 GetSwitchBagPocketDirection(void)
+{
+ u8 LRKeys;
+ if (gUnknown_0203CE54->unk81B != 0)
+ return 0;
+ LRKeys = GetLRKeysState();
+ if ((gMain.newKeys & DPAD_LEFT) || LRKeys == 1)
+ {
+ PlaySE(SE_SELECT);
+ return 1;
+ }
+ if ((gMain.newKeys & DPAD_RIGHT) || LRKeys == 2)
+ {
+ PlaySE(SE_SELECT);
+ return 2;
+ }
+ return 0;
+}
+
+void ChangeBagPocketId(u8 *bagPocketId, s8 deltaBagPocketId)
+{
+ if (deltaBagPocketId == 1 && *bagPocketId == 4)
+ *bagPocketId = 0;
+ else if (deltaBagPocketId == -1 && *bagPocketId == 0)
+ *bagPocketId = 4;
+ else
+ *bagPocketId += deltaBagPocketId;
+}
+
+void SwitchBagPocket(u8 taskId, s16 deltaBagPocketId, u16 a3)
+{
+ s16* data = gTasks[taskId].data;
+ u8 pocketId;
+
+ data[13] = 0;
+ data[12] = 0;
+ data[11] = deltaBagPocketId;
+ if (a3 == 0)
+ {
+ ClearWindowTilemap(0);
+ ClearWindowTilemap(1);
+ DestroyListMenuTask(data[0], &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket], &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]);
+ schedule_bg_copy_tilemap_to_vram(0);
+ gSprites[gUnknown_0203CE54->unk804[2 + (gUnknown_0203CE54->unk81B_1 ^ 1)]].invisible = 1;
+ sub_81AB824();
+ }
+ pocketId = gUnknown_0203CE58.pocket;
+ ChangeBagPocketId(&pocketId, deltaBagPocketId);
+ if (deltaBagPocketId == 1)
+ {
+ bag_menu_print_pocket_names(gPocketNamesStringsTable[gUnknown_0203CE58.pocket], gPocketNamesStringsTable[pocketId]);
+ bag_menu_copy_pocket_name_to_window(0);
+ }
+ else
+ {
+ bag_menu_print_pocket_names(gPocketNamesStringsTable[pocketId], gPocketNamesStringsTable[gUnknown_0203CE58.pocket]);
+ bag_menu_copy_pocket_name_to_window(8);
+ }
+ bag_menu_draw_pocket_indicator_square(gUnknown_0203CE58.pocket, 0);
+ bag_menu_draw_pocket_indicator_square(pocketId, 1);
+ FillBgTilemapBufferRect_Palette0(2, 11, 14, 2, 15, 16);
+ schedule_bg_copy_tilemap_to_vram(2);
+ SetBagVisualPocketId(pocketId, 1);
+ RemoveBagSprite(1);
+ AddSwitchPocketRotatingBallSprite(deltaBagPocketId);
+ SetTaskFuncWithFollowupFunc(taskId, sub_81AC10C, gTasks[taskId].func);
+}
+
+void sub_81AC10C(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+
+ if (!sub_81221AC() && !IsWallysBag())
+ {
+ switch (GetSwitchBagPocketDirection())
+ {
+ case 1:
+ ChangeBagPocketId(&gUnknown_0203CE58.pocket, data[11]);
+ SwitchTaskToFollowupFunc(taskId);
+ SwitchBagPocket(taskId, -1, 1);
+ return;
+ case 2:
+ ChangeBagPocketId(&gUnknown_0203CE58.pocket, data[11]);
+ SwitchTaskToFollowupFunc(taskId);
+ SwitchBagPocket(taskId, 1, 1);
+ return;
+ }
+ }
+ switch (data[13])
+ {
+ case 0:
+ sub_81AC23C(data[12]);
+ if (!(++data[12] & 1))
+ {
+ if (data[11] == 1)
+ bag_menu_copy_pocket_name_to_window((u8)(data[12] >> 1));
+ else
+ bag_menu_copy_pocket_name_to_window((u8)(8 - (data[12] >> 1)));
+ }
+ if (data[12] == 16)
+ data[13]++;
+ break;
+ case 1:
+ ChangeBagPocketId(&gUnknown_0203CE58.pocket, data[11]);
+ load_bag_item_list_buffers(gUnknown_0203CE58.pocket);
+ data[0] = ListMenuInit(&gMultiuseListMenuTemplate, gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket], gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]);
+ PutWindowTilemap(1);
+ PutWindowTilemap(2);
+ schedule_bg_copy_tilemap_to_vram(0);
+ bag_menu_add_pocket_scroll_arrow_indicators_maybe();
+ bag_menu_add_list_scroll_arrow_indicators_maybe();
+ SwitchTaskToFollowupFunc(taskId);
+ }
+}
+
+void sub_81AC23C(u8 a)
+{
+ FillBgTilemapBufferRect_Palette0(2, 17, 14, a + 2, 15, 1);
+ schedule_bg_copy_tilemap_to_vram(2);
+}
+
+void bag_menu_draw_pocket_indicator_square(u8 x, u8 is_current_bag)
+{
+ if (is_current_bag == 0)
+ FillBgTilemapBufferRect_Palette0(2, 0x1017, x + 5, 3, 1, 1);
+ else
+ FillBgTilemapBufferRect_Palette0(2, 0x102B, x + 5, 3, 1, 1);
+ schedule_bg_copy_tilemap_to_vram(2);
+}
+
+bool8 sub_81AC2C0(void)
+{
+ if (gUnknown_0203CE58.location <= 1)
+ {
+ u8 temp = gUnknown_0203CE58.pocket - 2;
+ if (temp > 1)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void bag_menu_swap_items(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+
+ sub_81AF15C(data[0], 16, 1);
+ data[1] = gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket] + gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket];
+ gUnknown_0203CE54->unk81A = data[1];
+ CopyItemName(BagGetItemIdByPocketPosition(gUnknown_0203CE58.pocket + 1, data[1]), gStringVar1);
+ StringExpandPlaceholders(gStringVar4, gText_MoveVar1Where);
+ FillWindowPixelBuffer(1, 0);
+ bag_menu_print(1, 1, gStringVar4, 3, 1, 0, 0, 0, 0);
+ sub_80D4FEC(data[1]);
+ sub_81AB89C();
+ bag_menu_print_cursor_(data[0], 2);
+ gTasks[taskId].func = sub_81AC3C0;
+}
+
+void sub_81AC3C0(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+ int r7;
+
+ if (sub_81221EC() != TRUE)
+ {
+ if (gMain.newKeys & SELECT_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ ListMenuGetScrollAndRow(data[0], &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket], &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]);
+ sub_81AC498(taskId);
+ }
+ else
+ {
+ r7 = ListMenuHandleInputGetItemId(data[0]);
+ ListMenuGetScrollAndRow(data[0], &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket], &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]);
+ sub_80D4FC8(0);
+ sub_80D4FEC(gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]);
+ switch (r7)
+ {
+ case -1:
+ break;
+ case -2:
+ PlaySE(SE_SELECT);
+ if (gMain.newKeys & A_BUTTON)
+ sub_81AC498(taskId);
+ else
+ sub_81AC590(taskId);
+ break;
+ default:
+ PlaySE(SE_SELECT);
+ sub_81AC498(taskId);
+ }
+ }
+ }
+}
+
+void sub_81AC498(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+ u16* scrollPos = &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket];
+ u16* cursorPos = &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket];
+ u16 realPos = (*scrollPos + *cursorPos);
+
+ if (data[1] == realPos || data[1] == (realPos - 1))
+ sub_81AC590(taskId);
+ else
+ {
+ MoveItemSlotInList(gBagPockets[gUnknown_0203CE58.pocket].itemSlots, data[1], realPos);
+ gUnknown_0203CE54->unk81A = -1;
+ DestroyListMenuTask(data[0], scrollPos, cursorPos);
+ if (data[1] < realPos)
+ gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]--;
+ load_bag_item_list_buffers(gUnknown_0203CE58.pocket);
+ data[0] = ListMenuInit(&gMultiuseListMenuTemplate, *scrollPos, *cursorPos);
+ sub_80D4FC8(1);
+ bag_menu_add_list_scroll_arrow_indicators_maybe();
+ gTasks[taskId].func = Task_BagMenu;
+ }
+}
+
+void sub_81AC590(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+ u16* scrollPos = &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket];
+ u16* cursorPos = &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket];
+
+ gUnknown_0203CE54->unk81A = -1;
+ DestroyListMenuTask(data[0], scrollPos, cursorPos);
+ if (data[1] < (*scrollPos + *cursorPos))
+ gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]--;
+ load_bag_item_list_buffers(gUnknown_0203CE58.pocket);
+ data[0] = ListMenuInit(&gMultiuseListMenuTemplate, *scrollPos, *cursorPos);
+ sub_80D4FC8(1);
+ bag_menu_add_list_scroll_arrow_indicators_maybe();
+ gTasks[taskId].func = Task_BagMenu;
+}
+
+void sub_81AC644(u8 unused)
+{
+ switch (gUnknown_0203CE58.location - 1)
+ {
+ case 0:
+ case 9:
+ if (ItemId_GetBattleUsage(gSpecialVar_ItemId))
+ {
+ gUnknown_0203CE54->unk820 = gUnknown_08614042;
+ gUnknown_0203CE54->unk828 = 2;
+ }
+ else
+ {
+ gUnknown_0203CE54->unk820 = &gUnknown_08614046;
+ gUnknown_0203CE54->unk828 = 1;
+ }
+ break;
+ case 4:
+ gUnknown_0203CE54->unk820 = gUnknown_08614047;
+ gUnknown_0203CE54->unk828 = 4;
+ break;
+ case 8:
+ if (!ItemId_GetImportance(gSpecialVar_ItemId) && gSpecialVar_ItemId != ITEM_ENIGMA_BERRY)
+ {
+ gUnknown_0203CE54->unk820 = gUnknown_0861404B;
+ gUnknown_0203CE54->unk828 = 2;
+ }
+ else
+ {
+ gUnknown_0203CE54->unk820 = &gUnknown_08614046;
+ gUnknown_0203CE54->unk828 = 1;
+ }
+ break;
+ case 6:
+ if (!ItemId_GetImportance(gSpecialVar_ItemId) && gSpecialVar_ItemId != ITEM_ENIGMA_BERRY)
+ {
+ gUnknown_0203CE54->unk820 = gUnknown_0861404D;
+ gUnknown_0203CE54->unk828 = 2;
+ }
+ else
+ {
+ gUnknown_0203CE54->unk820 = &gUnknown_08614046;
+ gUnknown_0203CE54->unk828 = 1;
+ }
+ break;
+ case 7:
+ if (!ItemId_GetImportance(gSpecialVar_ItemId) && gSpecialVar_ItemId != ITEM_ENIGMA_BERRY)
+ {
+ gUnknown_0203CE54->unk820 = gUnknown_0861404F;
+ gUnknown_0203CE54->unk828 = 2;
+ }
+ else
+ {
+ gUnknown_0203CE54->unk820 = &gUnknown_08614046;
+ gUnknown_0203CE54->unk828 = 1;
+ }
+ break;
+ case 1:
+ case 2:
+ case 3:
+ case 5:
+ default:
+ if (sub_81221AC() == TRUE || InUnionRoom() == TRUE)
+ {
+ if (gUnknown_0203CE58.pocket == 4 || !sub_8122148(gSpecialVar_ItemId))
+ {
+ gUnknown_0203CE54->unk820 = &gUnknown_08614046;
+ gUnknown_0203CE54->unk828 = 1;
+ }
+ else
+ {
+ gUnknown_0203CE54->unk820 = gUnknown_08614044;
+ gUnknown_0203CE54->unk828 = 2;
+ }
+ }
+ else
+ {
+ switch (gUnknown_0203CE58.pocket)
+ {
+ case 0:
+ gUnknown_0203CE54->unk820 = &gUnknown_0203CE54->unk824;
+ gUnknown_0203CE54->unk828 = 4;
+ memcpy(&gUnknown_0203CE54->unk824, &gUnknown_0861402C, 4);
+ if (ItemIsMail(gSpecialVar_ItemId) == TRUE)
+ gUnknown_0203CE54->unk824 = 6;
+ break;
+ case 4:
+ gUnknown_0203CE54->unk820 = &gUnknown_0203CE54->unk824;
+ gUnknown_0203CE54->unk828 = 4;
+ memcpy(&gUnknown_0203CE54->unk824, &gUnknown_08614030, 4);
+ if (gSaveBlock1Ptr->registeredItem == gSpecialVar_ItemId)
+ gUnknown_0203CE54->unk825 = 8;
+ if (gSpecialVar_ItemId == ITEM_MACH_BIKE || gSpecialVar_ItemId == ITEM_ACRO_BIKE)
+ {
+ if (TestPlayerAvatarFlags(6))
+ gUnknown_0203CE54->unk824 = 7;
+ }
+ break;
+ case 1:
+ gUnknown_0203CE54->unk820 = gUnknown_08614034;
+ gUnknown_0203CE54->unk828 = 4;
+ break;
+ case 2:
+ gUnknown_0203CE54->unk820 = gUnknown_08614038;
+ gUnknown_0203CE54->unk828 = 4;
+ break;
+ case 3:
+ gUnknown_0203CE54->unk820 = gUnknown_0861403C;
+ gUnknown_0203CE54->unk828 = 6;
+ break;
+ }
+ }
+ }
+ if (gUnknown_0203CE58.pocket == 2)
+ {
+ ClearWindowTilemap(1);
+ PrintTMHMMoveData(gSpecialVar_ItemId);
+ PutWindowTilemap(3);
+ PutWindowTilemap(4);
+ schedule_bg_copy_tilemap_to_vram(0);
+ }
+ else
+ {
+ CopyItemName(gSpecialVar_ItemId, gStringVar1);
+ StringExpandPlaceholders(gStringVar4, gText_Var1IsSelected);
+ FillWindowPixelBuffer(1, 0);
+ bag_menu_print(1, 1, gStringVar4, 3, 1, 0, 0, 0, 0);
+ }
+ if (gUnknown_0203CE54->unk828 == 1)
+ sub_81ACAF8(bag_menu_add_window(0));
+ else if (gUnknown_0203CE54->unk828 == 2)
+ sub_81ACAF8(bag_menu_add_window(1));
+ else if (gUnknown_0203CE54->unk828 == 4)
+ sub_81ACB54(bag_menu_add_window(2), 2, 2);
+ else
+ sub_81ACB54(bag_menu_add_window(3), 2, 3);
+}
+
+void sub_81ACAF8(u8 a)
+{
+ AddItemMenuActionTextPrinters(a, 7, 8, 1, 0, 16, gUnknown_0203CE54->unk828, gUnknown_08613FB4, gUnknown_0203CE54->unk820);
+ InitMenuInUpperLeftCornerPlaySoundWhenAPressed(a, gUnknown_0203CE54->unk828, 0);
+}
+
+void sub_81ACB54(u8 a, u8 b, u8 c)
+{
+ sub_8198DBC(a, 7, 8, 1, 0x38, b, c, gUnknown_08613FB4, gUnknown_0203CE54->unk820);
+ sub_8199944(a, 0x38, b, c, 0);
+}
+
+void unknown_item_menu_type(u8 taskId)
+{
+ sub_81AC644(taskId);
+ if (gUnknown_0203CE54->unk828 <= 2)
+ gTasks[taskId].func = Task_HandleInBattleItemMenuInput;
+ else
+ gTasks[taskId].func = Task_HandleOutOfBattleItemMenuInput;
+}
+
+void Task_HandleInBattleItemMenuInput(u8 taskId)
+{
+ if (sub_81221EC() != TRUE)
+ {
+ s8 r4 = ProcessMenuInputNoWrapAround();
+ switch (r4)
+ {
+ case -2:
+ break;
+ case -1:
+ PlaySE(SE_SELECT);
+ gUnknown_08613FB4[4].func.void_u8(taskId);
+ break;
+ default:
+ PlaySE(SE_SELECT);
+ gUnknown_08613FB4[gUnknown_0203CE54->unk820[r4]].func.void_u8(taskId);
+ break;
+ }
+ }
+}
+
+void Task_HandleOutOfBattleItemMenuInput(u8 taskId)
+{
+ if (sub_81221EC() != TRUE)
+ {
+ s8 cursorPos = GetMenuCursorPos();
+ if (gMain.newKeys & DPAD_UP)
+ {
+ if (cursorPos > 0 && sub_81ACDFC(cursorPos - 2))
+ {
+ PlaySE(SE_SELECT);
+ sub_8199134(0, -1);
+ }
+ }
+ else if (gMain.newKeys & DPAD_DOWN)
+ {
+ if (cursorPos < (gUnknown_0203CE54->unk828 - 2) && sub_81ACDFC(cursorPos + 2))
+ {
+ PlaySE(SE_SELECT);
+ sub_8199134(0, 1);
+ }
+ }
+ else if ((gMain.newKeys & DPAD_LEFT) || GetLRKeysState() == 1)
+ {
+ if ((cursorPos & 1) && sub_81ACDFC(cursorPos - 1))
+ {
+ PlaySE(SE_SELECT);
+ sub_8199134(-1, 0);
+ }
+ }
+ else if ((gMain.newKeys & DPAD_RIGHT) || GetLRKeysState() == 2)
+ {
+ if (!(cursorPos & 1) && sub_81ACDFC(cursorPos + 1))
+ {
+ PlaySE(SE_SELECT);
+ sub_8199134(1, 0);
+ }
+ }
+ else if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ gUnknown_08613FB4[gUnknown_0203CE54->unk820[cursorPos]].func.void_u8(taskId);
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ gUnknown_08613FB4[4].func.void_u8(taskId);
+ }
+ }
+}
+
+bool8 sub_81ACDFC(s8 a)
+{
+ if (a < 0)
+ return FALSE;
+ if (a > gUnknown_0203CE54->unk828)
+ return FALSE;
+ if (gUnknown_0203CE54->unk820[a] == 14)
+ return FALSE;
+ return TRUE;
+}
+
+void bag_menu_remove_some_window(void)
+{
+ if (gUnknown_0203CE54->unk828 == 1)
+ bag_menu_remove_window(0);
+ else if (gUnknown_0203CE54->unk828 == 2)
+ {
+ bag_menu_remove_window(1);
+ }
+ else if (gUnknown_0203CE54->unk828 == 4)
+ {
+ bag_menu_remove_window(2);
+ }
+ else
+ bag_menu_remove_window(3);
+}
+
+void ItemMenu_UseOutOfBattle(u8 taskId)
+{
+ if (ItemId_GetFieldFunc(gSpecialVar_ItemId))
+ {
+ bag_menu_remove_some_window();
+ if (CalculatePlayerPartyCount() == 0 && ItemId_GetType(gSpecialVar_ItemId) == 1)
+ bag_menu_print_there_is_no_pokemon(taskId);
+ else
+ {
+ FillWindowPixelBuffer(1, 0);
+ schedule_bg_copy_tilemap_to_vram(0);
+ if (gUnknown_0203CE58.pocket != 3)
+ ItemId_GetFieldFunc(gSpecialVar_ItemId)(taskId);
+ else
+ sub_80FDD10(taskId);
+ }
+ }
+}
+
+void ItemMenu_Toss(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+
+ bag_menu_remove_some_window();
+ data[8] = 1;
+ if (data[2] == 1)
+ {
+ BagMenuConfirmToss(taskId);
+ }
+ else
+ {
+ CopyItemName(gSpecialVar_ItemId, gStringVar1);
+ StringExpandPlaceholders(gStringVar4, gText_TossHowManyVar1s);
+ FillWindowPixelBuffer(1, 0);
+ bag_menu_print(1, 1, gStringVar4, 3, 1, 0, 0, 0, 0);
+ sub_81ABC3C(7);
+ gTasks[taskId].func = Task_ChooseHowManyToToss;
+ }
+}
+
+void BagMenuConfirmToss(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+
+ CopyItemName(gSpecialVar_ItemId, gStringVar1);
+ ConvertIntToDecimalStringN(gStringVar2, data[8], 0, 3);
+ StringExpandPlaceholders(gStringVar4, gText_ConfirmTossItems);
+ FillWindowPixelBuffer(1, 0);
+ bag_menu_print(1, 1, gStringVar4, 3, 1, 0, 0, 0, 0);
+ bag_menu_yes_no(taskId, 5, &gUnknown_08614084);
+}
+
+void BagMenuCancelToss(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+
+ bag_menu_print_description_box_text(data[1]);
+ bag_menu_print_cursor_(data[0], 0);
+ set_callback3_to_bag(taskId);
+}
+
+void Task_ChooseHowManyToToss(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+
+ if (AdjustQuantityAccordingToDPadInput(&data[8], data[2]) == TRUE)
+ {
+ sub_81ABC54(gUnknown_0203CE54->unk817, data[8]);
+ }
+ else if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ bag_menu_remove_window(7);
+ BagMenuConfirmToss(taskId);
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ bag_menu_remove_window(7);
+ BagMenuCancelToss(taskId);
+ }
+}
+
+void BagMenuActuallyToss(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+
+ CopyItemName(gSpecialVar_ItemId, gStringVar1);
+ ConvertIntToDecimalStringN(gStringVar2, data[8], 0, 3);
+ StringExpandPlaceholders(gStringVar4, gText_ThrewAwayVar2Var1s);
+ FillWindowPixelBuffer(1, 0);
+ bag_menu_print(1, 1, gStringVar4, 3, 1, 0, 0, 0, 0);
+ gTasks[taskId].func = Task_ActuallyToss;
+}
+
+void Task_ActuallyToss(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+ u16* scrollPos = &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket];
+ u16* cursorPos = &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket];
+
+ if (gMain.newKeys & (A_BUTTON | B_BUTTON))
+ {
+ PlaySE(SE_SELECT);
+ RemoveBagItem(gSpecialVar_ItemId, data[8]);
+ DestroyListMenuTask(data[0], scrollPos, cursorPos);
+ sub_81AB9A8(gUnknown_0203CE58.pocket);
+ sub_81ABA88(gUnknown_0203CE58.pocket);
+ load_bag_item_list_buffers(gUnknown_0203CE58.pocket);
+ data[0] = ListMenuInit(&gMultiuseListMenuTemplate, *scrollPos, *cursorPos);
+ schedule_bg_copy_tilemap_to_vram(0);
+ set_callback3_to_bag(taskId);
+ }
+}
+
+void ItemMenu_Register(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+ u16* scrollPos = &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket];
+ u16* cursorPos = &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket];
+
+ if (gSaveBlock1Ptr->registeredItem == gSpecialVar_ItemId)
+ gSaveBlock1Ptr->registeredItem = 0;
+ else
+ gSaveBlock1Ptr->registeredItem = gSpecialVar_ItemId;
+ DestroyListMenuTask(data[0], scrollPos, cursorPos);
+ load_bag_item_list_buffers(gUnknown_0203CE58.pocket);
+ data[0] = ListMenuInit(&gMultiuseListMenuTemplate, *scrollPos, *cursorPos);
+ schedule_bg_copy_tilemap_to_vram(0);
+ ItemMenu_Cancel(taskId);
+}
+
+void ItemMenu_Give(u8 taskId)
+{
+ bag_menu_remove_some_window();
+ if (!itemid_80BF6D8_mail_related(gSpecialVar_ItemId))
+ {
+ DisplayItemMessage(taskId, 1, gText_CantWriteMail, sub_81AD350);
+ }
+ else if (!ItemId_GetImportance(gSpecialVar_ItemId))
+ {
+ if (CalculatePlayerPartyCount() == 0)
+ bag_menu_print_there_is_no_pokemon(taskId);
+ else
+ {
+ gUnknown_0203CE54->unk0 = sub_81B7F60;
+ unknown_ItemMenu_Confirm(taskId);
+ }
+ }
+ else
+ {
+ bag_menu_print_cant_be_held_msg(taskId);
+ }
+}
+
+void bag_menu_print_there_is_no_pokemon(u8 taskId)
+{
+ DisplayItemMessage(taskId, 1, gText_NoPokemon, sub_81AD350);
+}
+
+void bag_menu_print_cant_be_held_msg(u8 taskId)
+{
+ CopyItemName(gSpecialVar_ItemId, gStringVar1);
+ StringExpandPlaceholders(gStringVar4, gText_Var1CantBeHeld);
+ DisplayItemMessage(taskId, 1, gStringVar4, sub_81AD350);
+}
+
+void sub_81AD350(u8 taskId)
+{
+ if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ bag_menu_inits_lists_menu(taskId);
+ }
+}
+
+void ItemMenu_CheckTag(u8 taskId)
+{
+ gUnknown_0203CE54->unk0 = DoBerryTagScreen;
+ unknown_ItemMenu_Confirm(taskId);
+}
+
+void ItemMenu_Cancel(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+
+ bag_menu_remove_some_window();
+ bag_menu_print_description_box_text(data[1]);
+ schedule_bg_copy_tilemap_to_vram(0);
+ schedule_bg_copy_tilemap_to_vram(1);
+ bag_menu_print_cursor_(data[0], 0);
+ set_callback3_to_bag(taskId);
+}
+
+void ItemMenu_UseInBattle(u8 taskId)
+{
+ if (ItemId_GetBattleFunc(gSpecialVar_ItemId))
+ {
+ bag_menu_remove_some_window();
+ ItemId_GetBattleFunc(gSpecialVar_ItemId)(taskId);
+ }
+}
+
+void bag_menu_mail_related(void)
+{
+ GoToBagMenu(12, 5, NULL);
+}
+
+void item_menu_type_2(u8 taskId)
+{
+ if (!itemid_80BF6D8_mail_related(gSpecialVar_ItemId))
+ {
+ DisplayItemMessage(taskId, 1, gText_CantWriteMail, sub_81AD350);
+ }
+ else if (!sub_8122148(gSpecialVar_ItemId))
+ {
+ CopyItemName(gSpecialVar_ItemId, gStringVar1);
+ StringExpandPlaceholders(gStringVar4, gText_Var1CantBeHeldHere);
+ DisplayItemMessage(taskId, 1, gStringVar4, sub_81AD350);
+ }
+ else if (gUnknown_0203CE58.pocket != 4 && !ItemId_GetImportance(gSpecialVar_ItemId))
+ {
+ unknown_ItemMenu_Confirm(taskId);
+ }
+ else
+ {
+ bag_menu_print_cant_be_held_msg(taskId);
+ }
+}
+
+void item_menu_type_b(u8 taskId)
+{
+ if (ItemIsMail(gSpecialVar_ItemId) == TRUE)
+ DisplayItemMessage(taskId, 1, gText_CantWriteMail, sub_81AD350);
+ else if (gUnknown_0203CE58.pocket != 4 && !ItemId_GetImportance(gSpecialVar_ItemId))
+ gTasks[taskId].func = unknown_ItemMenu_Confirm;
+ else
+ bag_menu_print_cant_be_held_msg(taskId);
+}
+
+bool8 UseRegisteredKeyItemOnField(void)
+{
+ u8 taskId;
+
+ if (InUnionRoom() == TRUE || InBattlePyramid() || InBattlePike() || InMultiBattleRoom() == TRUE)
+ return FALSE;
+ HideMapNamePopUpWindow();
+ ChangeBgY_ScreenOff(0, 0, 0);
+ if (gSaveBlock1Ptr->registeredItem != ITEM_NONE)
+ {
+ if (CheckBagHasItem(gSaveBlock1Ptr->registeredItem, 1) == TRUE)
+ {
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ sub_808B864();
+ sub_808BCF4();
+ gSpecialVar_ItemId = gSaveBlock1Ptr->registeredItem;
+ taskId = CreateTask(ItemId_GetFieldFunc(gSaveBlock1Ptr->registeredItem), 8);
+ gTasks[taskId].data[3] = 1;
+ return TRUE;
+ }
+ else
+ gSaveBlock1Ptr->registeredItem = ITEM_NONE;
+ }
+ ScriptContext1_SetupScript(EventScript_2736B3);
+ return TRUE;
+}
+
+void display_sell_item_ask_str(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+
+ if (ItemId_GetPrice(gSpecialVar_ItemId) == 0)
+ {
+ CopyItemName(gSpecialVar_ItemId, gStringVar2);
+ StringExpandPlaceholders(gStringVar4, gText_CantBuyKeyItem);
+ DisplayItemMessage(taskId, 1, gStringVar4, bag_menu_inits_lists_menu);
+ }
+ else
+ {
+ data[8] = 1;
+ if (data[2] == 1)
+ {
+ bag_menu_AddMoney_window();
+ sub_81AD680(taskId);
+ }
+ else
+ {
+ CopyItemName(gSpecialVar_ItemId, gStringVar2);
+ StringExpandPlaceholders(gStringVar4, gText_HowManyToSell);
+ DisplayItemMessage(taskId, 1, gStringVar4, sub_81AD730);
+ }
+ }
+}
+
+void sub_81AD680(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+
+ ConvertIntToDecimalStringN(gStringVar1, (ItemId_GetPrice(gSpecialVar_ItemId) / 2) * data[8], 0, 6);
+ StringExpandPlaceholders(gStringVar4, gText_ICanPayVar1);
+ DisplayItemMessage(taskId, 1, gStringVar4, sub_81AD6E4);
+}
+
+void sub_81AD6E4(u8 taskId)
+{
+ bag_menu_yes_no(taskId, 6, &gUnknown_0861408C);
+}
+
+void sub_81AD6FC(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+
+ bag_menu_remove_money_window();
+ bag_menu_RemoveBagItem_message_window(4);
+ bag_menu_print_cursor_(data[0], 0);
+ set_callback3_to_bag(taskId);
+}
+
+void sub_81AD730(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+ u8 windowId = bag_menu_add_window(8);
+
+ sub_81ABCC0(windowId, 1, (ItemId_GetPrice(gSpecialVar_ItemId) / 2) * data[8]);
+ bag_menu_AddMoney_window();
+ gTasks[taskId].func = sub_81AD794;
+}
+
+void sub_81AD794(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+
+ if (AdjustQuantityAccordingToDPadInput(&data[8], data[2]) == TRUE)
+ {
+ sub_81ABCC0(gUnknown_0203CE54->unk818, data[8], (ItemId_GetPrice(gSpecialVar_ItemId) / 2) * data[8]);
+ }
+ else if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ bag_menu_remove_window(8);
+ sub_81AD680(taskId);
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ bag_menu_print_cursor_(data[0], 0);
+ bag_menu_remove_money_window();
+ bag_menu_remove_window(8);
+ bag_menu_RemoveBagItem_message_window(4);
+ set_callback3_to_bag(taskId);
+ }
+}
+
+void sub_81AD84C(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+
+ CopyItemName(gSpecialVar_ItemId, gStringVar2);
+ ConvertIntToDecimalStringN(gStringVar1, (ItemId_GetPrice(gSpecialVar_ItemId) / 2) * data[8], 0, 6);
+ StringExpandPlaceholders(gStringVar4, gText_TurnedOverVar1ForVar2);
+ DisplayItemMessage(taskId, 1, gStringVar4, sub_81AD8C8);
+}
+
+void sub_81AD8C8(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+ u16* scrollPos = &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket];
+ u16* cursorPos = &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket];
+
+ PlaySE(SE_REGI);
+ RemoveBagItem(gSpecialVar_ItemId, data[8]);
+ AddMoney(&gSaveBlock1Ptr->money, (ItemId_GetPrice(gSpecialVar_ItemId) / 2) * data[8]);
+ DestroyListMenuTask(data[0], scrollPos, cursorPos);
+ sub_81AB9A8(gUnknown_0203CE58.pocket);
+ sub_81ABA88(gUnknown_0203CE58.pocket);
+ load_bag_item_list_buffers(gUnknown_0203CE58.pocket);
+ data[0] = ListMenuInit(&gMultiuseListMenuTemplate, *scrollPos, *cursorPos);
+ bag_menu_print_cursor_(data[0], 2);
+ PrintMoneyAmountInMoneyBox(gUnknown_0203CE54->unk819, GetMoney(&gSaveBlock1Ptr->money), 0);
+ gTasks[taskId].func = sub_81AD9C0;
+}
+
+void sub_81AD9C0(u8 taskId)
+{
+ if (gMain.newKeys & (A_BUTTON | B_BUTTON))
+ {
+ PlaySE(SE_SELECT);
+ bag_menu_remove_money_window();
+ bag_menu_inits_lists_menu(taskId);
+ }
+}
+
+void display_deposit_item_ask_str(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+
+ data[8] = 1;
+ if (data[2] == 1)
+ {
+ sub_81ADB14(taskId);
+ }
+ else
+ {
+ CopyItemName(gSpecialVar_ItemId, gStringVar1);
+ StringExpandPlaceholders(gStringVar4, gText_DepositHowManyVar1);
+ FillWindowPixelBuffer(1, 0);
+ bag_menu_print(1, 1, gStringVar4, 3, 1, 0, 0, 0, 0);
+ sub_81ABC3C(7);
+ gTasks[taskId].func = sub_81ADA7C;
+ }
+}
+
+void sub_81ADA7C(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+
+ if (AdjustQuantityAccordingToDPadInput(&data[8], data[2]) == TRUE)
+ {
+ sub_81ABC54(gUnknown_0203CE54->unk817, data[8]);
+ }
+ else if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ bag_menu_remove_window(7);
+ sub_81ADB14(taskId);
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ bag_menu_print_description_box_text(data[1]);
+ bag_menu_print_cursor_(data[0], 0);
+ bag_menu_remove_window(7);
+ set_callback3_to_bag(taskId);
+ }
+}
+
+void sub_81ADB14(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+
+ FillWindowPixelBuffer(1, 0);
+ if (ItemId_GetImportance(gSpecialVar_ItemId))
+ {
+ bag_menu_print(1, 1, gText_CantStoreImportantItems, 3, 1, 0, 0, 0, 0);
+ gTasks[taskId].func = sub_81ADC0C;
+ }
+ else if (AddPCItem(gSpecialVar_ItemId, data[8]) == TRUE)
+ {
+ CopyItemName(gSpecialVar_ItemId, gStringVar1);
+ ConvertIntToDecimalStringN(gStringVar2, data[8], 0, 3);
+ StringExpandPlaceholders(gStringVar4, gText_DepositedVar2Var1s);
+ bag_menu_print(1, 1, gStringVar4, 3, 1, 0, 0, 0, 0);
+ gTasks[taskId].func = Task_ActuallyToss;
+ }
+ else
+ {
+ bag_menu_print(1, 1, gText_NoRoomForItems, 3, 1, 0, 0, 0, 0);
+ gTasks[taskId].func = sub_81ADC0C;
+ }
+}
+
+void sub_81ADC0C(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+
+ if (gMain.newKeys & (A_BUTTON | B_BUTTON))
+ {
+ PlaySE(SE_SELECT);
+ bag_menu_print_description_box_text(data[1]);
+ bag_menu_print_cursor_(data[0], 0);
+ set_callback3_to_bag(taskId);
+ }
+}
+
+bool8 IsWallysBag(void)
+{
+ if (gUnknown_0203CE58.location == 10)
+ return TRUE;
+ return FALSE;
+}
+
+void PrepareBagForWallyTutorial(void)
+{
+ u32 i;
+
+ gUnknown_0203CE80 = AllocZeroed(sizeof(struct TempWallyStruct));
+ memcpy(gUnknown_0203CE80->bagPocket_Items, gSaveBlock1Ptr->bagPocket_Items, sizeof(gSaveBlock1Ptr->bagPocket_Items));
+ memcpy(gUnknown_0203CE80->bagPocket_PokeBalls, gSaveBlock1Ptr->bagPocket_PokeBalls, sizeof(gSaveBlock1Ptr->bagPocket_PokeBalls));
+ gUnknown_0203CE80->pocket = gUnknown_0203CE58.pocket;
+ for (i = 0; i <= 4; i++)
+ {
+ gUnknown_0203CE80->cursorPosition[i] = gUnknown_0203CE58.cursorPosition[i];
+ gUnknown_0203CE80->scrollPosition[i] = gUnknown_0203CE58.scrollPosition[i];
+ }
+ ClearItemSlots(gSaveBlock1Ptr->bagPocket_Items, 30);
+ ClearItemSlots(gSaveBlock1Ptr->bagPocket_PokeBalls, 16);
+ ResetBagScrollPositions();
+}
+
+void RestoreBagAfterWallyTutorial(void)
+{
+ u32 i;
+
+ memcpy(gSaveBlock1Ptr->bagPocket_Items, gUnknown_0203CE80->bagPocket_Items, sizeof(gUnknown_0203CE80->bagPocket_Items));
+ memcpy(gSaveBlock1Ptr->bagPocket_PokeBalls, gUnknown_0203CE80->bagPocket_PokeBalls, sizeof(gUnknown_0203CE80->bagPocket_PokeBalls));
+ gUnknown_0203CE58.pocket = gUnknown_0203CE80->pocket;
+ for (i = 0; i <= 4; i++)
+ {
+ gUnknown_0203CE58.cursorPosition[i] = gUnknown_0203CE80->cursorPosition[i];
+ gUnknown_0203CE58.scrollPosition[i] = gUnknown_0203CE80->scrollPosition[i];
+ }
+ Free(gUnknown_0203CE80);
+}
+
+void DoWallyTutorialBagMenu(void)
+{
+ PrepareBagForWallyTutorial();
+ AddBagItem(ITEM_POTION, 1);
+ AddBagItem(ITEM_POKE_BALL, 1);
+ GoToBagMenu(10, 0, SetCB2ToReshowScreenAfterMenu2);
+}
+
+void Task_WallyTutorialBagMenu(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+
+ if (!gPaletteFade.active)
+ {
+ switch (data[8])
+ {
+ case 0x66:
+ PlaySE(SE_SELECT);
+ SwitchBagPocket(taskId, 1, 0);
+ data[8]++;
+ break;
+ case 0xCC:
+ PlaySE(SE_SELECT);
+ bag_menu_print_cursor_(data[0], 2);
+ gSpecialVar_ItemId = ITEM_POKE_BALL;
+ sub_81AC644(taskId);
+ data[8]++;
+ break;
+ case 0x132:
+ PlaySE(SE_SELECT);
+ bag_menu_remove_some_window();
+ DestroyListMenuTask(data[0], 0, 0);
+ RestoreBagAfterWallyTutorial();
+ unknown_ItemMenu_Confirm(taskId);
+ break;
+ default:
+ data[8]++;
+ break;
+ }
+ }
+}
+
+void unknown_ItemMenu_Show(u8 taskId)
+{
+ gSpecialVar_0x8005 = gSpecialVar_ItemId;
+ gSpecialVar_Result = 1;
+ bag_menu_remove_some_window();
+ unknown_ItemMenu_Confirm(taskId);
+}
+
+void bag_menu_leave_maybe_3(void)
+{
+ gFieldCallback = sub_819FA50;
+ SetMainCallback2(CB2_ReturnToField);
+}
+
+void unknown_ItemMenu_Give2(u8 taskId)
+{
+ RemoveBagItem(gSpecialVar_ItemId, 1);
+ gSpecialVar_Result = 1;
+ bag_menu_remove_some_window();
+ unknown_ItemMenu_Confirm(taskId);
+}
+
+void bag_menu_leave_maybe_2(void)
+{
+ gFieldCallback = sub_818DEF4;
+ SetMainCallback2(CB2_ReturnToField);
+}
+
+void unknown_ItemMenu_Confirm2(u8 taskId)
+{
+ gSpecialVar_Result = 1;
+ bag_menu_remove_some_window();
+ unknown_ItemMenu_Confirm(taskId);
+}
+
+void bag_menu_leave_maybe(void)
+{
+ gFieldCallback = sub_818E564;
+ SetMainCallback2(CB2_ReturnToField);
+}
+
+void bag_menu_print_pocket_names(u8 *pocketName1, u8 *pocketName2)
+{
+ struct WindowTemplate window = {0, 0, 0, 0, 0, 0, 0};
+ u16 windowId;
+ int offset;
+
+ window.width = 16;
+ window.height = 2;
+ windowId = AddWindow(&window);
+ FillWindowPixelBuffer(windowId, 0);
+ offset = GetStringCenterAlignXOffset(1, pocketName1, 0x40);
+ bag_menu_print(windowId, 1, pocketName1, offset, 1, 0, 0, -1, 1);
+ if (pocketName2)
+ {
+ offset = GetStringCenterAlignXOffset(1, pocketName2, 0x40);
+ bag_menu_print(windowId, 1, pocketName2, offset + 0x40, 1, 0, 0, -1, 1);
+ }
+ CpuCopy32((u8*)GetWindowAttribute(windowId, 7), gUnknown_0203CE54->unk844, 0x400);
+ RemoveWindow(windowId);
+}
+
+void bag_menu_copy_pocket_name_to_window(u32 a)
+{
+ u8 (* r4)[32][32];
+ u8* windowAttribute;
+ int b;
+ if (a > 8)
+ a = 8;
+ r4 = &gUnknown_0203CE54->unk844;
+ windowAttribute = (u8*)GetWindowAttribute(2, 7);
+ CpuCopy32(r4[0][a], windowAttribute, 0x100);
+ b = a + 16;
+ CpuCopy32(r4[0][b], windowAttribute + 0x100, 0x100);
+ CopyWindowToVram(2, 2);
+}
+
+void setup_bag_menu_textboxes(void)
+{
+ u8 i;
+
+ InitWindows(gUnknown_08614174);
+ DeactivateAllTextPrinters();
+ sub_809882C(0, 1, -32);
+ copy_textbox_border_tile_patterns_to_vram(0, 10, -48);
+ sub_819A2BC(-64, 1);
+ LoadPalette(&gUnknown_0860F074, 0xF0, 0x20);
+ for (i = 0; i < 3; i++)
+ {
+ FillWindowPixelBuffer(i, 0);
+ PutWindowTilemap(i);
+ }
+ schedule_bg_copy_tilemap_to_vram(0);
+ schedule_bg_copy_tilemap_to_vram(1);
+}
+
+void bag_menu_print(u8 a, u8 b, const u8 *str, u8 c, u8 d, u8 e, u8 f, u8 g, u8 h)
+{
+ AddTextPrinterParameterized2(a, b, c, d, e, f, gUnknown_08614164[h], g, str);
+}
+
+u8 sub_81AE124(u8 a)
+{
+ return gUnknown_0203CE54->unk810[a];
+}
+
+u8 bag_menu_add_window(u8 a)
+{
+ u8 *ptr = &gUnknown_0203CE54->unk810[a];
+ if (*ptr == 0xFF)
+ {
+ *ptr = AddWindow(&gUnknown_086141AC[a]);
+ SetWindowBorderStyle(*ptr, 0, 1, 14);
+ schedule_bg_copy_tilemap_to_vram(1);
+ }
+ return *ptr;
+}
+
+void bag_menu_remove_window(u8 a)
+{
+ u8 *ptr = &gUnknown_0203CE54->unk810[a];
+ if (*ptr != 0xFF)
+ {
+ sub_8198070(*ptr, 0);
+ ClearWindowTilemap(*ptr);
+ RemoveWindow(*ptr);
+ schedule_bg_copy_tilemap_to_vram(1);
+ *ptr = 0xFF;
+ }
+}
+
+u8 AddItemMessageWindow(u8 a)
+{
+ u8 *ptr = &gUnknown_0203CE54->unk810[a];
+ if (*ptr == 0xFF)
+ *ptr = AddWindow(&gUnknown_086141AC[a]);
+ return *ptr;
+}
+
+void bag_menu_RemoveBagItem_message_window(u8 a)
+{
+ u8 *ptr = &gUnknown_0203CE54->unk810[a];
+ if (*ptr != 0xFF)
+ {
+ sub_8197DF8(*ptr, 0);
+ ClearWindowTilemap(*ptr);
+ RemoveWindow(*ptr);
+ schedule_bg_copy_tilemap_to_vram(1);
+ *ptr = 0xFF;
+ }
+}
+
+void bag_menu_yes_no(u8 a, u8 b, const struct YesNoFuncTable *funcTable)
+{
+ CreateYesNoMenuWithCallbacks(a, &gUnknown_086141AC[b], 1, 0, 2, 1, 14, funcTable);
+}
+
+void bag_menu_AddMoney_window(void)
+{
+ u8 windowId = bag_menu_add_window(9);
+ PrintMoneyAmountInMoneyBoxWithBorder(windowId, 1, 14, GetMoney(&gSaveBlock1Ptr->money));
+ AddMoneyLabelObject(19, 11);
+}
+
+void bag_menu_remove_money_window(void)
+{
+ bag_menu_remove_window(9);
+ RemoveMoneyLabelObject();
+}
+
+void bag_menu_prepare_tmhm_move_window(void)
+{
+ FillWindowPixelBuffer(3, 0);
+ blit_move_info_icon(3, 19, 0, 0);
+ blit_move_info_icon(3, 20, 0, 12);
+ blit_move_info_icon(3, 21, 0, 24);
+ blit_move_info_icon(3, 22, 0, 36);
+ CopyWindowToVram(3, 2);
+}
+
+void PrintTMHMMoveData(u16 itemId)
+{
+ u8 i;
+ u16 moveId;
+ const u8* text;
+
+ FillWindowPixelBuffer(4, 0);
+ if (itemId == ITEM_NONE)
+ {
+ for (i = 0; i < 4; i++)
+ bag_menu_print(4, 1, gText_ThreeDashes, 7, i * 12, 0, 0, -1, 4);
+ CopyWindowToVram(4, 2);
+ }
+ else
+ {
+ moveId = ItemIdToBattleMoveId(itemId);
+ blit_move_info_icon(4, gBattleMoves[moveId].type + 1, 0, 0);
+ if (gBattleMoves[moveId].power <= 1)
+ {
+ text = gText_ThreeDashes;
+ }
+ else
+ {
+ ConvertIntToDecimalStringN(gStringVar1, gBattleMoves[moveId].power, 1, 3);
+ text = gStringVar1;
+ }
+ bag_menu_print(4, 1, text, 7, 12, 0, 0, -1, 4);
+ if (gBattleMoves[moveId].accuracy == 0)
+ {
+ text = gText_ThreeDashes;
+ }
+ else
+ {
+ ConvertIntToDecimalStringN(gStringVar1, gBattleMoves[moveId].accuracy, 1, 3);
+ text = gStringVar1;
+ }
+ bag_menu_print(4, 1, text, 7, 24, 0, 0, -1, 4);
+ ConvertIntToDecimalStringN(gStringVar1, gBattleMoves[moveId].pp, 1, 3);
+ bag_menu_print(4, 1, gStringVar1, 7, 36, 0, 0, -1, 4);
+ CopyWindowToVram(4, 2);
+ }
+}
diff --git a/src/item_menu_icons.c b/src/item_menu_icons.c
new file mode 100644
index 000000000..f12bb454e
--- /dev/null
+++ b/src/item_menu_icons.c
@@ -0,0 +1,684 @@
+#include "global.h"
+#include "sprite.h"
+#include "decompress.h"
+#include "item_menu.h"
+#include "item_icon.h"
+#include "item_menu_icons.h"
+#include "window.h"
+#include "menu_helpers.h"
+#include "berry.h"
+#include "graphics.h"
+#include "constants/items.h"
+#include "item.h"
+#include "item_use.h"
+#include "constants/hold_effects.h"
+
+struct CompressedTilesPal
+{
+ const u8 *tiles;
+ const u8 *pal;
+};
+
+extern void sub_80D5860(struct Sprite *sprite);
+extern void sub_80D58F8(struct Sprite *sprite);
+extern void sub_80D5968(struct Sprite *sprite);
+extern void sub_80D5A94(struct Sprite *sprite);
+extern void sub_80D5B48(struct Sprite *sprite);
+
+// this file's functions
+static void SpriteCB_BagVisualSwitchingPockets(struct Sprite *sprite);
+static void SpriteCB_ShakeBagVisual(struct Sprite *sprite);
+static void SpriteCB_SwitchPocketRotatingBallInit(struct Sprite *sprite);
+static void SpriteCB_SwitchPocketRotatingBallContinue(struct Sprite *sprite);
+
+// static const rom data
+static const u16 gUnknown_0857F564[] = INCBIN_U16("graphics/interface/bag_spinner.gbapal");
+static const u8 gUnknown_0857F584[] = INCBIN_U8("graphics/interface/bag_spinner.4bpp");
+static const u8 gUnknown_0857F604[] = INCBIN_U8("graphics/unused/cherry.4bpp");
+static const u16 gUnknown_0857FA84[] = INCBIN_U16("graphics/unused/cherry.gbapal");
+
+static const struct OamData sOamData_857FAA4 =
+{
+ .y = 0,
+ .affineMode = 1,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 3,
+ .tileNum = 0,
+ .priority = 1,
+ .paletteNum = 0,
+ .affineParam = 0
+};
+
+static const union AnimCmd sSpriteAnim_857FAAC[] =
+{
+ ANIMCMD_FRAME(0, 4),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_857FAB4[] =
+{
+ ANIMCMD_FRAME(64, 4),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_857FABC[] =
+{
+ ANIMCMD_FRAME(128, 4),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_857FAC4[] =
+{
+ ANIMCMD_FRAME(192, 4),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_857FACC[] =
+{
+ ANIMCMD_FRAME(256, 4),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_857FAD4[] =
+{
+ ANIMCMD_FRAME(320, 4),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_857FADC[] =
+{
+ sSpriteAnim_857FAAC,
+ sSpriteAnim_857FAB4,
+ sSpriteAnim_857FAC4,
+ sSpriteAnim_857FACC,
+ sSpriteAnim_857FAD4,
+ sSpriteAnim_857FABC
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_857FAF4[] =
+{
+ AFFINEANIMCMD_FRAME(256, 256, 0, 0),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_857FB04[] =
+{
+ AFFINEANIMCMD_FRAME(0, 0, 254, 2),
+ AFFINEANIMCMD_FRAME(0, 0, 2, 4),
+ AFFINEANIMCMD_FRAME(0, 0, 254, 4),
+ AFFINEANIMCMD_FRAME(0, 0, 2, 2),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd *const sSpriteAffineAnimTable_857FB2C[] =
+{
+ sSpriteAffineAnim_857FAF4,
+ sSpriteAffineAnim_857FB04
+};
+
+const struct CompressedSpriteSheet gUnknown_0857FB34 =
+{
+ gBagMaleTiles, 0x3000, 100
+};
+
+const struct CompressedSpriteSheet gUnknown_0857FB3C =
+{
+ gBagFemaleTiles, 0x3000, 100
+};
+
+const struct CompressedSpritePalette gUnknown_0857FB44 =
+{
+ gBagPalette, 100
+};
+
+static const struct SpriteTemplate gUnknown_0857FB4C =
+{
+ .tileTag = 100,
+ .paletteTag = 100,
+ .oam = &sOamData_857FAA4,
+ .anims = sSpriteAnimTable_857FADC,
+ .images = NULL,
+ .affineAnims = sSpriteAffineAnimTable_857FB2C,
+ .callback = SpriteCallbackDummy,
+};
+
+static const struct OamData sOamData_857FB64 =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 4,
+ .size = 1,
+ .tileNum = 0,
+ .priority = 2,
+ .paletteNum = 0,
+ .affineParam = 0
+};
+
+static const union AnimCmd sSpriteAnim_857FB6C[] =
+{
+ ANIMCMD_FRAME(0, 0),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_857FB74[] =
+{
+ sSpriteAnim_857FB6C
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_857FB78[] =
+{
+ AFFINEANIMCMD_FRAME(0, 0, 8, 16),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_857FB88[] =
+{
+ AFFINEANIMCMD_FRAME(0, 0, 248, 16),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd *const sSpriteAffineAnimTable_857FB98[] =
+{
+ sSpriteAffineAnim_857FB78,
+};
+
+static const union AffineAnimCmd *const sSpriteAffineAnimTable_857FB9C[] =
+{
+ sSpriteAffineAnim_857FB88,
+};
+
+static const struct SpriteSheet gUnknown_0857FBA0 =
+{
+ gUnknown_0857F584, 0x80, 101
+};
+
+static const struct SpritePalette gUnknown_0857FBA8 =
+{
+ gUnknown_0857F564, 101
+};
+
+static const struct SpriteTemplate gUnknown_0857FBB0 =
+{
+ .tileTag = 101,
+ .paletteTag = 101,
+ .oam = &sOamData_857FB64,
+ .anims = sSpriteAnimTable_857FB74,
+ .images = NULL,
+ .affineAnims = sSpriteAffineAnimTable_857FB98,
+ .callback = SpriteCB_SwitchPocketRotatingBallInit,
+};
+
+static const struct OamData sOamData_857FBC8 =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 3,
+ .tileNum = 0,
+ .priority = 1,
+ .paletteNum = 7,
+ .affineParam = 0
+};
+
+static const struct OamData sOamData_857FBD0 =
+{
+ .y = 0,
+ .affineMode = 3,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 3,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 7,
+ .affineParam = 0
+};
+
+static const union AnimCmd sSpriteAnim_857FBD8[] =
+{
+ ANIMCMD_FRAME(0, 0),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_857FBE0[] =
+{
+ sSpriteAnim_857FBD8
+};
+
+static const struct SpriteFrameImage sSpriteImageTable_857FBE4[] =
+{
+ {&gDecompressionBuffer[0], 0x800},
+};
+
+static const struct SpriteTemplate gUnknown_0857FBEC =
+{
+ .tileTag = 65535,
+ .paletteTag = 30020,
+ .oam = &sOamData_857FBC8,
+ .anims = sSpriteAnimTable_857FBE0,
+ .images = sSpriteImageTable_857FBE4,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_857FC04[] =
+{
+ AFFINEANIMCMD_FRAME(-1, -1, 253, 96),
+ AFFINEANIMCMD_FRAME(0, 0, 0, 16),
+ AFFINEANIMCMD_FRAME(-2, -2, 255, 64),
+ AFFINEANIMCMD_FRAME(-8, 0, 0, 16),
+ AFFINEANIMCMD_FRAME(0, -8, 0, 16),
+ AFFINEANIMCMD_FRAME(256, 256, 0, 0),
+ AFFINEANIMCMD_JUMP(0)
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_857FC3C[] =
+{
+ AFFINEANIMCMD_FRAME(-1, -1, 3, 96),
+ AFFINEANIMCMD_FRAME(0, 0, 0, 16),
+ AFFINEANIMCMD_FRAME(-2, -2, 1, 64),
+ AFFINEANIMCMD_FRAME(-8, 0, 0, 16),
+ AFFINEANIMCMD_FRAME(0, -8, 0, 16),
+ AFFINEANIMCMD_FRAME(256, 256, 0, 0),
+ AFFINEANIMCMD_JUMP(0)
+};
+
+static const union AffineAnimCmd *const sSpriteAffineAnimTable_857FC74[] =
+{
+ sSpriteAffineAnim_857FC04,
+ sSpriteAffineAnim_857FC3C
+};
+
+static const struct SpriteTemplate gUnknown_0857FC7C =
+{
+ .tileTag = 0xFFFF,
+ .paletteTag = 0x7544,
+ .oam = &sOamData_857FBD0,
+ .anims = sSpriteAnimTable_857FBE0,
+ .images = sSpriteImageTable_857FBE4,
+ .affineAnims = sSpriteAffineAnimTable_857FC74,
+ .callback = SpriteCallbackDummy,
+};
+
+static const struct CompressedTilesPal gBerryPicTable[] =
+{
+ {gBerryPic_Cheri, gBerryPalette_Cheri},
+ {gBerryPic_Chesto, gBerryPalette_Chesto},
+ {gBerryPic_Pecha, gBerryPalette_Pecha},
+ {gBerryPic_Rawst, gBerryPalette_Rawst},
+ {gBerryPic_Aspear, gBerryPalette_Aspear},
+ {gBerryPic_Leppa, gBerryPalette_Leppa},
+ {gBerryPic_Oran, gBerryPalette_Oran},
+ {gBerryPic_Persim, gBerryPalette_Persim},
+ {gBerryPic_Lum, gBerryPalette_Lum},
+ {gBerryPic_Sitrus, gBerryPalette_Sitrus},
+ {gBerryPic_Figy, gBerryPalette_Figy},
+ {gBerryPic_Wiki, gBerryPalette_Wiki},
+ {gBerryPic_Mago, gBerryPalette_Mago},
+ {gBerryPic_Aguav, gBerryPalette_Aguav},
+ {gBerryPic_Iapapa, gBerryPalette_Iapapa},
+ {gBerryPic_Razz, gBerryPalette_Razz},
+ {gBerryPic_Bluk, gBerryPalette_Bluk},
+ {gBerryPic_Nanab, gBerryPalette_Nanab},
+ {gBerryPic_Wepear, gBerryPalette_Wepear},
+ {gBerryPic_Pinap, gBerryPalette_Pinap},
+ {gBerryPic_Pomeg, gBerryPalette_Pomeg},
+ {gBerryPic_Kelpsy, gBerryPalette_Kelpsy},
+ {gBerryPic_Qualot, gBerryPalette_Qualot},
+ {gBerryPic_Hondew, gBerryPalette_Hondew},
+ {gBerryPic_Grepa, gBerryPalette_Grepa},
+ {gBerryPic_Tamato, gBerryPalette_Tamato},
+ {gBerryPic_Cornn, gBerryPalette_Cornn},
+ {gBerryPic_Magost, gBerryPalette_Magost},
+ {gBerryPic_Rabuta, gBerryPalette_Rabuta},
+ {gBerryPic_Nomel, gBerryPalette_Nomel},
+ {gBerryPic_Spelon, gBerryPalette_Spelon},
+ {gBerryPic_Pamtre, gBerryPalette_Pamtre},
+ {gBerryPic_Watmel, gBerryPalette_Watmel},
+ {gBerryPic_Durin, gBerryPalette_Durin},
+ {gBerryPic_Belue, gBerryPalette_Belue},
+ {gBerryPic_Liechi, gBerryPalette_Liechi},
+ {gBerryPic_Ganlon, gBerryPalette_Ganlon},
+ {gBerryPic_Salac, gBerryPalette_Salac},
+ {gBerryPic_Petaya, gBerryPalette_Petaya},
+ {gBerryPic_Apicot, gBerryPalette_Apicot},
+ {gBerryPic_Lansat, gBerryPalette_Lansat},
+ {gBerryPic_Starf, gBerryPalette_Starf},
+ {gBerryPic_Enigma, gBerryPalette_Enigma},
+};
+
+const struct CompressedSpriteSheet gUnknown_0857FDEC =
+{
+ gBerryCheckCircle_Gfx, 0x800, 10000
+};
+
+const struct CompressedSpritePalette gUnknown_0857FDF4 =
+{
+ gUnknown_08D9BEF0, 10000
+};
+
+static const struct OamData sOamData_857FDFC =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 3,
+ .tileNum = 0,
+ .priority = 1,
+ .paletteNum = 0,
+ .affineParam = 0
+};
+
+static const union AnimCmd sSpriteAnim_857FE04[] =
+{
+ ANIMCMD_FRAME(0, 0),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_857FE0C[] =
+{
+ sSpriteAnim_857FE04
+};
+
+static const struct SpriteTemplate gUnknown_0857FE10 =
+{
+ .tileTag = 10000,
+ .paletteTag = 10000,
+ .oam = &sOamData_857FDFC,
+ .anims = sSpriteAnimTable_857FE0C,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+const struct SpriteTemplate gUnknown_0857FE28 =
+{
+ .tileTag = 0,
+ .paletteTag = 0,
+ .oam = &gDummyOamData,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80D5860,
+};
+
+const struct SpriteTemplate gUnknown_0857FE40 =
+{
+ .tileTag = 0,
+ .paletteTag = 0,
+ .oam = &gDummyOamData,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80D58F8,
+};
+
+const struct SpriteTemplate gUnknown_0857FE58 =
+{
+ .tileTag = 0,
+ .paletteTag = 0,
+ .oam = &gDummyOamData,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80D5968,
+};
+
+const struct SpriteTemplate gUnknown_0857FE70 =
+{
+ .tileTag = 0,
+ .paletteTag = 0,
+ .oam = &gDummyOamData,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80D5A94,
+};
+
+const struct SpriteTemplate gUnknown_0857FE88 =
+{
+ .tileTag = 0,
+ .paletteTag = 0,
+ .oam = &gDummyOamData,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80D5B48,
+};
+
+#include "data/text/item_descriptions.h"
+#include "data/items.h"
+
+// code
+void RemoveBagSprite(u8 id)
+{
+ u8 *spriteId = &gUnknown_0203CE54->unk804[id];
+ if (*spriteId != 0xFF)
+ {
+ FreeSpriteTilesByTag(id + 100);
+ FreeSpritePaletteByTag(id + 100);
+ FreeSpriteOamMatrix(&gSprites[*spriteId]);
+ DestroySprite(&gSprites[*spriteId]);
+ *spriteId = 0xFF;
+ }
+}
+
+void AddBagVisualSprite(u8 bagPocketId)
+{
+ u8 *spriteId = &gUnknown_0203CE54->unk804[0];
+ *spriteId = CreateSprite(&gUnknown_0857FB4C, 68, 66, 0);
+ SetBagVisualPocketId(bagPocketId, FALSE);
+}
+
+void SetBagVisualPocketId(u8 bagPocketId, bool8 isSwitchingPockets)
+{
+ struct Sprite *sprite = &gSprites[gUnknown_0203CE54->unk804[0]];
+ if (isSwitchingPockets)
+ {
+ sprite->pos2.y = -5;
+ sprite->callback = SpriteCB_BagVisualSwitchingPockets;
+ sprite->data[0] = bagPocketId + 1;
+ StartSpriteAnim(sprite, 0);
+ }
+ else
+ {
+ StartSpriteAnim(sprite, bagPocketId + 1);
+ }
+}
+
+static void SpriteCB_BagVisualSwitchingPockets(struct Sprite *sprite)
+{
+ if (sprite->pos2.y != 0)
+ {
+ sprite->pos2.y++;
+ }
+ else
+ {
+ StartSpriteAnim(sprite, sprite->data[0]);
+ sprite->callback = SpriteCallbackDummy;
+ }
+}
+
+void ShakeBagVisual(void)
+{
+ struct Sprite *sprite = &gSprites[gUnknown_0203CE54->unk804[0]];
+ if (sprite->affineAnimEnded)
+ {
+ StartSpriteAffineAnim(sprite, 1);
+ sprite->callback = SpriteCB_ShakeBagVisual;
+ }
+}
+
+static void SpriteCB_ShakeBagVisual(struct Sprite *sprite)
+{
+ if (sprite->affineAnimEnded)
+ {
+ StartSpriteAffineAnim(sprite, 0);
+ sprite->callback = SpriteCallbackDummy;
+ }
+}
+
+void AddSwitchPocketRotatingBallSprite(s16 rotationDirection)
+{
+ u8 *spriteId = &gUnknown_0203CE54->unk804[1];
+ LoadSpriteSheet(&gUnknown_0857FBA0);
+ LoadSpritePalette(&gUnknown_0857FBA8);
+ *spriteId = CreateSprite(&gUnknown_0857FBB0, 16, 16, 0);
+ gSprites[*spriteId].data[0] = rotationDirection;
+}
+
+static void update_switch_pocket_rotating_ball_coords(struct Sprite *sprite)
+{
+ sprite->centerToCornerVecX = sprite->data[1] - ((sprite->data[3] + 1) & 1);
+ sprite->centerToCornerVecY = sprite->data[1] - ((sprite->data[3] + 1) & 1);
+}
+
+static void SpriteCB_SwitchPocketRotatingBallInit(struct Sprite *sprite)
+{
+ sprite->oam.affineMode = 1;
+ if (sprite->data[0] == -1)
+ sprite->affineAnims = sSpriteAffineAnimTable_857FB98;
+ else
+ sprite->affineAnims = sSpriteAffineAnimTable_857FB9C;
+
+ InitSpriteAffineAnim(sprite);
+ sprite->data[1] = sprite->centerToCornerVecX;
+ sprite->data[1] = sprite->centerToCornerVecY;
+ update_switch_pocket_rotating_ball_coords(sprite);
+ sprite->callback = SpriteCB_SwitchPocketRotatingBallContinue;
+}
+
+static void SpriteCB_SwitchPocketRotatingBallContinue(struct Sprite *sprite)
+{
+ sprite->data[3]++;
+ update_switch_pocket_rotating_ball_coords(sprite);
+ if (sprite->data[3] == 16)
+ RemoveBagSprite(1);
+}
+
+void AddBagItemIconSprite(u16 itemId, u8 id)
+{
+ u8 *spriteId = &gUnknown_0203CE54->unk804[id + 2];
+ if (*spriteId == 0xFF)
+ {
+ u8 iconSpriteId;
+
+ FreeSpriteTilesByTag(id + 102);
+ FreeSpritePaletteByTag(id + 102);
+ iconSpriteId = AddItemIconSprite(id + 102, id + 102, itemId);
+ if (iconSpriteId != MAX_SPRITES)
+ {
+ *spriteId = iconSpriteId;
+ gSprites[iconSpriteId].pos2.x = 24;
+ gSprites[iconSpriteId].pos2.y = 88;
+ }
+ }
+}
+
+void RemoveBagItemIconSprite(u8 id)
+{
+ RemoveBagSprite(id + 2);
+}
+
+void sub_80D4FAC(void)
+{
+ sub_8122344(&gUnknown_0203CE54->unk804[4], 8);
+}
+
+void sub_80D4FC8(u8 arg0)
+{
+ sub_81223FC(&gUnknown_0203CE54->unk804[4], 8, arg0);
+}
+
+void sub_80D4FEC(u8 arg0)
+{
+ sub_8122448(&gUnknown_0203CE54->unk804[4], 136, 120, (arg0 + 1) * 16);
+}
+
+static void sub_80D5018(void *mem0, void *mem1)
+{
+ u8 i, j;
+
+ memset(mem1, 0, 0x800);
+ mem1 += 0x100;
+ for (i = 0; i < 6; i++)
+ {
+ mem1 += 0x20;
+ for (j = 0; j < 6; j++)
+ {
+ memcpy(mem1, mem0, 0x20);
+ mem1 += 0x20;
+ mem0 += 0x20;
+ }
+ if (i != 5)
+ mem1 += 0x20;
+ }
+}
+
+static void sub_80D5070(u8 berryId)
+{
+ struct CompressedSpritePalette pal;
+
+ if (berryId == ITEM_TO_BERRY(ITEM_ENIGMA_BERRY) - 1 && IsEnigmaBerryValid())
+ {
+ // unknown empty if statement
+ }
+
+ pal.data = gBerryPicTable[berryId].pal;
+ pal.tag = 0x7544;
+ LoadCompressedObjectPalette(&pal);
+ LZDecompressWram(gBerryPicTable[berryId].tiles, &gDecompressionBuffer[0x1000]);
+ sub_80D5018(&gDecompressionBuffer[0x1000], &gDecompressionBuffer[0]);
+}
+
+u8 CreateBerryTagSprite(u8 id, s16 x, s16 y)
+{
+ sub_80D5070(id);
+ return CreateSprite(&gUnknown_0857FBEC, x, y, 0);
+}
+
+void FreeBerryTagSpritePalette(void)
+{
+ FreeSpritePaletteByTag(0x7544);
+}
+
+u8 sub_80D511C(u8 berryId, u8 x, u8 y, bool8 startAffine)
+{
+ u8 spriteId;
+
+ FreeSpritePaletteByTag(0x7544);
+ sub_80D5070(berryId);
+ spriteId = CreateSprite(&gUnknown_0857FC7C, x, y, 0);
+ if (startAffine == TRUE)
+ StartSpriteAffineAnim(&gSprites[spriteId], 1);
+
+ return spriteId;
+}
+
+u8 CreateBerryFlavorCircleSprite(s16 x)
+{
+ return CreateSprite(&gUnknown_0857FE10, x, 116, 0);
+}
diff --git a/src/item_use.c b/src/item_use.c
index 1fdd925ac..d036da6d3 100755
--- a/src/item_use.c
+++ b/src/item_use.c
@@ -1,6 +1,7 @@
#include "global.h"
#include "item_use.h"
#include "battle.h"
+#include "main.h"
#include "berry.h"
#include "bike.h"
#include "coins.h"
@@ -45,7 +46,7 @@ extern void ItemUseOutOfBattle_EvolutionStone(u8 b);
extern void bag_menu_mail_related(void);
extern void OpenPokeblockCase(u8 a, void(*b)(void));
extern void overworld_free_bg_tilemaps(void);
-extern bool32 sav1_map_is_biking_allowed(void);
+extern bool32 Overworld_IsBikingAllowed(void);
extern bool8 IsPlayerFacingSurfableFishableWater(void);
extern bool8 sub_81221AC(void);
extern u8 gText_ItemFinderNothing[];
@@ -85,9 +86,8 @@ extern void sub_81C59BC(void);
extern void sub_81AB9A8(u8);
extern void sub_81ABA88(u8);
extern void sub_80B7CC8(void);
-extern void flagmods_08054D70(void);
+extern void Overworld_ResetStateAfterDigEscRope(void);
extern u8* sub_806CF78(u16);
-extern bool8 ExecuteTableBasedItemEffect_(struct Pokemon*, u16, u8, u8);
extern void sub_81B89F0(void);
extern u8 GetItemEffectType(u16);
extern struct MapConnection *sub_8088A8C(s16, s16);
@@ -114,13 +114,13 @@ void sub_80FE024(u8 taskId);
void sub_80FE124(u8 taskId);
void sub_80FE164(u8 taskId);
-void DisplayItemMessage(u8 taskId, u8 a, u8* str, void(*callback)(u8 taskId));
+void DisplayItemMessage(u8 taskId, u8 a, const u8* str, void(*callback)(u8 taskId));
void DisplayItemMessageInBattlePyramid(u8 taskId, u8* str, void(*callback)(u8 taskId));
void DisplayItemMessageOnField(u8 taskId, u8* str, void(*callback)(u8 taskId));
void sub_81C6714(u8 taskId);
void CleanUpAfterFailingToUseRegisteredKeyItemOnField(u8 taskId);
void StartFishing(u8 a);
-bool8 ItemfinderCheckForHiddenItems(struct MapEvents *, u8);
+bool8 ItemfinderCheckForHiddenItems(const struct MapEvents *, u8);
u8 sub_80FD9B0(s16 a, s16 b);
void sub_80FDA24(u8 a);
void sub_80FD8E0(u8 taskId, s16 x, s16 y);
@@ -166,7 +166,7 @@ void MapPostLoadHook_UseItem(void)
void Task_CallItemUseOnFieldCallback(u8 taskId)
{
- if (sub_80ABDFC() == 1)
+ if (IsWeatherNotFadingIn() == 1)
gUnknown_0203A0F4(taskId);
}
@@ -237,7 +237,7 @@ void ItemUseOutOfBattle_Bike(u8 taskId)
DisplayCannotDismountBikeMessage(taskId, data[3]);
else
{
- if (sav1_map_is_biking_allowed() == TRUE && IsBikingDisallowedByPlayer() == 0)
+ if (Overworld_IsBikingAllowed() == TRUE && IsBikingDisallowedByPlayer() == 0)
{
gUnknown_0203A0F4 = ItemUseOnFieldCB_Bike;
SetUpItemUseOnFieldCallback(taskId);
@@ -364,7 +364,7 @@ void sub_80FD5CC(u8 taskId)
DestroyTask(taskId);
}
-bool8 ItemfinderCheckForHiddenItems(struct MapEvents *events, u8 taskId)
+bool8 ItemfinderCheckForHiddenItems(const struct MapEvents *events, u8 taskId)
{
int distanceX, distanceY;
s16 x, y, i, newDistanceX, newDistanceY;
@@ -391,7 +391,7 @@ bool8 ItemfinderCheckForHiddenItems(struct MapEvents *events, u8 taskId)
return FALSE;
}
-bool8 sub_80FD6D4(struct MapEvents *events, s16 x, s16 y)
+bool8 sub_80FD6D4(const struct MapEvents *events, s16 x, s16 y)
{
u8 bgEventCount = events->bgEventCount;
struct BgEvent *bgEvent = events->bgEvents;
@@ -638,7 +638,7 @@ void sub_80FDC00(u8 taskId)
if (!gPaletteFade.active)
{
overworld_free_bg_tilemaps();
- OpenPokeblockCase(0, c2_exit_to_overworld_2_switch);
+ OpenPokeblockCase(0, CB2_ReturnToField);
DestroyTask(taskId);
}
}
@@ -679,7 +679,7 @@ void sub_80FDD10(u8 taskId)
{
gUnknown_0203A0F4 = sub_80FDD74;
gFieldCallback = MapPostLoadHook_UseItem;
- *gUnknown_0203CE54 = c2_exit_to_overworld_2_switch;
+ *gUnknown_0203CE54 = CB2_ReturnToField;
unknown_ItemMenu_Confirm(taskId);
}
else
@@ -905,13 +905,13 @@ void task08_080A1C44(u8 taskId)
void re_escape_rope(u8 taskId)
{
- flagmods_08054D70();
+ Overworld_ResetStateAfterDigEscRope();
sub_80FE058();
gTasks[taskId].data[0] = 0;
DisplayItemMessageOnField(taskId, gStringVar4, task08_080A1C44);
}
-bool8 sub_80FE314(void)
+bool8 CanUseEscapeRopeOnCurrMap(void)
{
if (gMapHeader.flags & 2)
return TRUE;
@@ -921,7 +921,7 @@ bool8 sub_80FE314(void)
void ItemUseOutOfBattle_EscapeRope(u8 taskId)
{
- if (sub_80FE314() == TRUE)
+ if (CanUseEscapeRopeOnCurrMap() == TRUE)
{
gUnknown_0203A0F4 = re_escape_rope;
SetUpItemUseOnFieldCallback(taskId);
@@ -984,7 +984,7 @@ void ItemUseInBattle_StatIncrease(u8 taskId)
{
u16 partyId = gBattlerPartyIndexes[gBattlerInMenuId];
- if (ExecuteTableBasedItemEffect_(&gPlayerParty[partyId], gSpecialVar_ItemId, partyId, 0) != FALSE)
+ if (ExecuteTableBasedItemEffect(&gPlayerParty[partyId], gSpecialVar_ItemId, partyId, 0) != FALSE)
{
if (!InBattlePyramid())
DisplayItemMessage(taskId, 1, gText_WontHaveEffect, bag_menu_inits_lists_menu);
diff --git a/src/librfu_rfu.c b/src/librfu_rfu.c
index cf3fe12ad..c5aa25c10 100644
--- a/src/librfu_rfu.c
+++ b/src/librfu_rfu.c
@@ -3,38 +3,6 @@
#include "librfu.h"
-struct RfuUnk1
-{
- u8 unk_0[0x14];
- u32 unk_14;
- u32 unk_18;
- struct RfuIntrStruct unk_1c;
-};
-
-struct RfuUnk2
-{
- u8 unk_0[0x68];
- u32 unk_68;
- u32 unk_6c;
- u8 unk_70[0x70];
-};
-
-struct RfuUnk3
-{
- u32 unk_0;
- u32 unk_4;
- u8 unk_8[0xD4];
- u32 unk_dc;
-};
-
-extern u32 *gUnknown_03007890;
-extern u32 *gUnknown_03007894;
-extern struct RfuUnk3* gUnknown_03007898;
-extern struct RfuUnk2* gUnknown_03007880[4];
-extern struct RfuUnk1* gUnknown_03007870[4];
-extern void* sub_82E53F4;
-extern void rfu_STC_clearAPIVariables(void);
-
// Nonmatching, only register differences
/*u16 rfu_initializeAPI(u32 *unk0, u16 unk1, IntrFunc *interrupt, bool8 copyInterruptToRam)
{
diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c
index cbfb8484c..6c798967a 100644
--- a/src/lilycove_lady.c
+++ b/src/lilycove_lady.c
@@ -392,7 +392,7 @@ bool8 sub_818DC60(void)
static void sub_818DCAC(u8 *dest, u16 itemId)
{
- StringCopy(dest, ItemId_GetItem(itemId)->name);
+ StringCopy(dest, ItemId_GetName(itemId));
}
void sub_818DCC8(void)
@@ -606,7 +606,6 @@ u8 sub_818E06C(void)
}
}
-#ifdef NONMATCHING
static u8 sub_818E13C(void)
{
u8 retval;
@@ -627,9 +626,11 @@ static u8 sub_818E13C(void)
len = sub_818E258(gUnknown_0203CD68->playerName);
if (len == sub_818E258(gSaveBlock2Ptr->playerName))
{
+ u8 *name = gUnknown_0203CD68->playerName;
for (i = 0; i < len; i ++)
{
- if (gUnknown_0203CD68->playerName[i] != gSaveBlock2Ptr->playerName[i])
+ name = gUnknown_0203CD68->playerName;
+ if (name[i] != gSaveBlock2Ptr->playerName[i])
{
retval = 2;
break;
@@ -640,85 +641,6 @@ static u8 sub_818E13C(void)
}
return retval;
}
-#else
-__attribute__((naked)) static u8 sub_818E13C(void)
-{
- asm_unified("\tpush {r4-r7,lr}\n"
- "\tmovs r7, 0x1\n"
- "\tldr r5, =gUnknown_0203CD68\n"
- "\tldr r0, =gSaveBlock1Ptr\n"
- "\tldr r1, [r0]\n"
- "\tldr r2, =0x00003b58\n"
- "\tadds r0, r1, r2\n"
- "\tstr r0, [r5]\n"
- "\tldrb r0, [r0, 0x18]\n"
- "\tcmp r0, 0xFF\n"
- "\tbne _0818E174\n"
- "\tldr r0, =gStringVar1\n"
- "\tldr r1, =gText_Lady2\n"
- "\tbl StringCopy7\n"
- "\tmovs r7, 0\n"
- "\tb _0818E1DC\n"
- "\t.pool\n"
- "_0818E174:\n"
- "\tldr r4, =gStringVar1\n"
- "\tldr r0, =0x00003b70\n"
- "\tadds r1, r0\n"
- "\tadds r0, r4, 0\n"
- "\tbl StringCopy7\n"
- "\tldr r0, [r5]\n"
- "\tadds r0, 0x2D\n"
- "\tldrb r1, [r0]\n"
- "\tadds r0, r4, 0\n"
- "\tbl ConvertInternationalString\n"
- "\tldr r0, [r5]\n"
- "\tadds r0, 0x18\n"
- "\tbl sub_818E258\n"
- "\tlsls r0, 24\n"
- "\tlsrs r4, r0, 24\n"
- "\tldr r6, =gSaveBlock2Ptr\n"
- "\tldr r0, [r6]\n"
- "\tbl sub_818E258\n"
- "\tlsls r0, 24\n"
- "\tlsrs r0, 24\n"
- "\tcmp r4, r0\n"
- "\tbne _0818E1DC\n"
- "\tldr r0, [r5]\n"
- "\tmovs r2, 0\n"
- "\tcmp r2, r4\n"
- "\tbcs _0818E1DC\n"
- "\tldr r1, [r6]\n"
- "\tldrb r0, [r0, 0x18]\n"
- "\tldrb r1, [r1]\n"
- "\tcmp r0, r1\n"
- "\tbne _0818E1DA\n"
- "_0818E1BA:\n"
- "\tadds r0, r2, 0x1\n"
- "\tlsls r0, 24\n"
- "\tlsrs r2, r0, 24\n"
- "\tcmp r2, r4\n"
- "\tbcs _0818E1DC\n"
- "\tldr r0, =gUnknown_0203CD68\n"
- "\tldr r1, [r0]\n"
- "\tadds r1, 0x18\n"
- "\tadds r1, r2\n"
- "\tldr r0, =gSaveBlock2Ptr\n"
- "\tldr r0, [r0]\n"
- "\tadds r0, r2\n"
- "\tldrb r1, [r1]\n"
- "\tldrb r0, [r0]\n"
- "\tcmp r1, r0\n"
- "\tbeq _0818E1BA\n"
- "_0818E1DA:\n"
- "\tmovs r7, 0x2\n"
- "_0818E1DC:\n"
- "\tadds r0, r7, 0\n"
- "\tpop {r4-r7}\n"
- "\tpop {r1}\n"
- "\tbx r1\n"
- "\t.pool");
-}
-#endif
static u8 sub_818E1F4(void)
{
@@ -749,7 +671,7 @@ static u8 sub_818E258(const u8 *str)
void sub_818E274(void)
{
- StringCopy(gStringVar1, ItemId_GetItem(gUnknown_0203CD68->itemId)->name);
+ StringCopy(gStringVar1, ItemId_GetName(gUnknown_0203CD68->itemId));
}
bool8 sub_818E298(void)
@@ -1079,7 +1001,7 @@ void sub_818E914(void)
void sub_818E92C(void)
{
- OpenPokeblockCase(3, c2_exit_to_overworld_2_switch);
+ OpenPokeblockCase(3, CB2_ReturnToField);
}
void sub_818E940(void)
diff --git a/src/link.c b/src/link.c
index ae2cd1992..acdb6cae0 100644
--- a/src/link.c
+++ b/src/link.c
@@ -1,6 +1,34 @@
// Includes
#include "global.h"
+#include "m4a.h"
+#include "malloc.h"
+#include "reset_save_heap.h"
+#include "save.h"
+#include "bg.h"
+#include "window.h"
+#include "librfu.h"
+#include "random.h"
+#include "decompress.h"
+#include "string_util.h"
+#include "event_data.h"
+#include "item_menu.h"
+#include "overworld.h"
+#include "gpu_regs.h"
+#include "palette.h"
+#include "task.h"
+#include "scanline_effect.h"
+#include "menu.h"
+#include "text.h"
+#include "strings.h"
+#include "constants/songs.h"
+#include "sound.h"
+#include "trade.h"
+#include "battle.h"
+#include "link.h"
+#include "link_rfu.h"
+
+extern u16 gUnknown_03005DA8;
// Static type declarations
@@ -8,7 +36,7 @@ struct BlockTransfer
{
u16 pos;
u16 size;
- void *src;
+ const u8 *src;
bool8 active;
u8 multiplayerId;
};
@@ -23,34 +51,2392 @@ struct LinkTestBGInfo
// Static RAM declarations
-IWRAM_DATA struct BlockTransfer gUnknown_03000D10;
+IWRAM_DATA struct BlockTransfer sBlockSend;
IWRAM_DATA u32 link_c_unused_03000d1c;
-IWRAM_DATA struct BlockTransfer gUnknown_03000D20[4];
-IWRAM_DATA u32 gUnknown_03000D50;
+IWRAM_DATA struct BlockTransfer sBlockRecv[MAX_LINK_PLAYERS];
+IWRAM_DATA u32 sBlockSendDelayCounter;
IWRAM_DATA u32 gUnknown_03000D54;
IWRAM_DATA u8 gUnknown_03000D58;
-IWRAM_DATA u32 gUnknown_03000D5C;
+IWRAM_DATA u32 sPlayerDataExchangeStatus;
IWRAM_DATA u32 gUnknown_03000D60;
-IWRAM_DATA u8 gUnknown_03000D64[4]; // not really, but won't match otherwise
-IWRAM_DATA u8 gUnknown_03000D68[4];
-IWRAM_DATA u8 gUnknown_03000D6C;
-IWRAM_DATA bool8 gUnknown_03000D6D;
-IWRAM_DATA u16 gUnknown_03000D6E;
-IWRAM_DATA u16 gUnknown_03000D70;
-IWRAM_DATA u8 gUnknown_03000D72;
-IWRAM_DATA u8 gUnknown_03000D73;
-IWRAM_DATA u8 gUnknown_03000D74[4]; // not really, but won't match otherwise
-IWRAM_DATA u8 gUnknown_03000D78[8]; // not really, but won't match otherwise
-IWRAM_DATA u8 gUnknown_03000D80[16];
-IWRAM_DATA u16 gUnknown_03000D90[8];
-IWRAM_DATA u32 gUnknown_03000DA0;
-IWRAM_DATA u32 gUnknown_03000DA4;
-IWRAM_DATA void *gUnknown_03000DA8;
-IWRAM_DATA void *gUnknown_03000DAC;
-IWRAM_DATA bool32 gUnknown_03000DB0;
+IWRAM_DATA u8 sLinkTestLastBlockSendPos;
+ALIGNED() IWRAM_DATA u8 sLinkTestLastBlockRecvPos[MAX_LINK_PLAYERS];
+IWRAM_DATA u8 sNumVBlanksWithoutSerialIntr;
+IWRAM_DATA bool8 sSendBufferEmpty;
+IWRAM_DATA u16 sSendNonzeroCheck;
+IWRAM_DATA u16 sRecvNonzeroCheck;
+IWRAM_DATA u8 sChecksumAvailable;
+IWRAM_DATA u8 sHandshakePlayerCount;
+
+u16 gLinkPartnersHeldKeys[6];
+u32 gLinkDebugSeed;
+struct LinkPlayerBlock gLocalLinkPlayerBlock;
+bool8 gLinkErrorOccurred;
+u32 gLinkDebugFlags;
+u32 gFiller_03003074;
+bool8 gRemoteLinkPlayersNotReceived[MAX_LINK_PLAYERS];
+u8 gBlockReceivedStatus[MAX_LINK_PLAYERS];
+u32 gFiller_03003080;
+u16 gLinkHeldKeys;
+u16 gRecvCmds[MAX_RFU_PLAYERS][CMD_LENGTH];
+u32 gLinkStatus;
+bool8 gUnknown_030030E4;
+bool8 gUnknown_030030E8;
+bool8 gUnknown_030030EC[MAX_LINK_PLAYERS];
+bool8 gUnknown_030030F0[MAX_LINK_PLAYERS];
+u16 gUnknown_030030F4;
+u8 gSuppressLinkErrorMessage;
+bool8 gWirelessCommType;
+bool8 gSavedLinkPlayerCount;
+u16 gSendCmd[CMD_LENGTH];
+u8 gSavedMultiplayerId;
+bool8 gReceivedRemoteLinkPlayers;
+struct LinkTestBGInfo gLinkTestBGInfo;
+void (*gLinkCallback)(void);
+u8 gShouldAdvanceLinkState;
+u16 gLinkTestBlockChecksums[MAX_LINK_PLAYERS];
+u8 gBlockRequestType;
+u32 gFiller_03003154;
+u32 gFiller_03003158;
+u32 gFiller_0300315c;
+u8 gLastSendQueueCount;
+struct Link gLink;
+u8 gLastRecvQueueCount;
+u16 gLinkSavedIme;
+u32 gFiller_03004138;
+u32 gFiller_0300413C;
+
+EWRAM_DATA u8 gLinkTestDebugValuesEnabled = 0;
+EWRAM_DATA u8 gUnknown_020223BD = 0;
+EWRAM_DATA u32 gUnknown_020223C0 = 0;
+EWRAM_DATA u16 gBlockRecvBuffer[MAX_RFU_PLAYERS][BLOCK_BUFFER_SIZE / 2] = {};
+EWRAM_DATA u8 gBlockSendBuffer[BLOCK_BUFFER_SIZE] = {};
+EWRAM_DATA bool8 gLinkOpen = FALSE;
+EWRAM_DATA u16 gLinkType = 0;
+EWRAM_DATA u16 gLinkTimeOutCounter = 0;
+EWRAM_DATA struct LinkPlayer gLocalLinkPlayer = {};
+EWRAM_DATA struct LinkPlayer gLinkPlayers[MAX_RFU_PLAYERS] = {};
+EWRAM_DATA struct LinkPlayer gSavedLinkPlayers[MAX_RFU_PLAYERS] = {};
+EWRAM_DATA struct {
+ u32 status;
+ u8 lastRecvQueueCount;
+ u8 lastSendQueueCount;
+ u8 unk_06;
+} sLinkErrorBuffer = {};
+EWRAM_DATA u16 gUnknown_02022B08 = 0;
+EWRAM_DATA void *gUnknown_02022B0C = NULL;
// Static ROM declarations
+static void InitLocalLinkPlayer(void);
+static void sub_80096BC(void);
+static void CB2_LinkTest(void);
+static void ProcessRecvCmds(u8 unused);
+static void sub_8009F70(void);
+static void ResetBlockSend(void);
+static bool32 InitBlockSend(const void *src, size_t size);
+static void LinkCB_BlockSendBegin(void);
+static void LinkCB_BlockSend(void);
+static void LinkCB_BlockSendEnd(void);
+static void SetBlockReceivedFlag(u8 who);
+static u16 LinkTestCalcBlockChecksum(const u16 *src, u16 size);
+static void LinkTest_prnthex(u32 pos, u8 a0, u8 a1, u8 a2);
+static void LinkCB_RequestPlayerDataExchange(void);
+static void Task_PrintTestData(u8 taskId);
+
+static void sub_800AC80(void);
+static void sub_800ACAC(void);
+static void sub_800AD5C(void);
+static void sub_800AD88(void);
+static void sub_800AE30(void);
+static void sub_800AE5C(void);
+
+static void CheckErrorStatus(void);
+static void CB2_PrintErrorMessage(void);
+static bool8 IsSioMultiMaster(void);
+static void sub_800B4A4(void);
+static void DisableSerial(void);
+static void EnableSerial(void);
+static void CheckMasterOrSlave(void);
+static void InitTimer(void);
+static void EnqueueSendCmd(u16 *sendCmd);
+static void DequeueRecvCmds(u16 (*recvCmds)[CMD_LENGTH]);
+
+static void StartTransfer(void);
+static bool8 DoHandshake(void);
+static void DoRecv(void);
+static void DoSend(void);
+static void StopTimer(void);
+static void SendRecvDone(void);
+
// .rodata
+ALIGNED(4) const u16 gWirelessLinkDisplayPal[] = INCBIN_U16("graphics/interface/wireless_link_display.gbapal");
+const u8 gWirelessLinkDisplayGfx[] = INCBIN_U8("graphics/interface/wireless_link_display.4bpp.lz");
+const u8 gWirelessLinkDisplayTilemap[] = INCBIN_U8("graphics/interface/wireless_link_display.bin.lz");
+const u16 gLinkTestDigitsPal[] = INCBIN_U16("graphics/interface/link_test_digits.gbapal");
+const u16 gLinkTestDigitsGfx[] = INCBIN_U16("graphics/interface/link_test_digits.4bpp");
+const u8 unkstring_82ed160[] = _("{HIGHLIGHT TRANSPARENT}{COLOR WHITE}");
+const u16 g2BlankTilesGfx[] = INCBIN_U16("graphics/interface/blank_1x2.4bpp");
+const struct BlockRequest gUnknown_082ED1A8[] = {
+ {gBlockSendBuffer, 200},
+ {gBlockSendBuffer, 200},
+ {gBlockSendBuffer, 100},
+ {gBlockSendBuffer, 220},
+ {gBlockSendBuffer, 40}
+};
+const u8 gBGControlRegs[] = {
+ REG_OFFSET_BG0CNT,
+ REG_OFFSET_BG1CNT,
+ REG_OFFSET_BG2CNT,
+ REG_OFFSET_BG3CNT
+};
+const char gASCIIGameFreakInc[] = "GameFreak inc.";
+const char gASCIITestPrint[] = "TEST PRINT\nP0\nP1\nP2\nP3";
+const struct BgTemplate gUnknown_082ED1FC[] = {
+ {
+ .bg = 0,
+ .charBaseIndex = 2,
+ .mapBaseIndex = 31,
+ .priority = 0
+ }, {
+ .bg = 1,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 8,
+ .priority = 1
+ }
+};
+const struct WindowTemplate gUnknown_082ED204[] = {
+ {0x00, 0x00, 0x00, 0x1E, 0x05, 0x0F, 0x0002},
+ {0x00, 0x00, 0x06, 0x1E, 0x07, 0x0F, 0x0098},
+ {0x00, 0x00, 0x0D, 0x1E, 0x07, 0x0F, 0x016A},
+ DUMMY_WIN_TEMPLATE
+};
+const u8 gUnknown_082ED224[] = {
+ 0x00, 0x01, 0x02, 0x00,
+ 0xff, 0xfe, 0xff, 0x00
+};
+
// .text
+
+bool8 sub_80093CC(void)
+{
+ sub_800B488();
+ sub_800E700();
+ if (sub_800BEC0() == 0x8001)
+ {
+ rfu_REQ_stopMode();
+ rfu_waitREQComplete();
+ return TRUE;
+ }
+ sub_800B4A4();
+ CloseLink();
+ RestoreSerialTimer3IntrHandlers();
+ return FALSE;
+}
+
+void Task_DestroySelf(u8 taskId)
+{
+ DestroyTask(taskId);
+}
+
+static void InitLinkTestBG(u8 paletteNum, u8 bgNum, u8 screenBaseBlock, u8 charBaseBlock, u16 a4)
+{
+ LoadPalette(gLinkTestDigitsPal, paletteNum * 16, 0x20);
+ DmaCopy16(3, gLinkTestDigitsGfx, (u16 *)BG_CHAR_ADDR(charBaseBlock) + (16 * a4), sizeof gLinkTestDigitsGfx);
+ gLinkTestBGInfo.screenBaseBlock = screenBaseBlock;
+ gLinkTestBGInfo.paletteNum = paletteNum;
+ gLinkTestBGInfo.dummy_8 = a4;
+ switch (bgNum)
+ {
+ case 1:
+ SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_SCREENBASE(screenBaseBlock) | BGCNT_PRIORITY(1) | BGCNT_CHARBASE(charBaseBlock));
+ break;
+ case 2:
+ SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_SCREENBASE(screenBaseBlock) | BGCNT_PRIORITY(1) | BGCNT_CHARBASE(charBaseBlock));
+ break;
+ case 3:
+ SetGpuReg(REG_OFFSET_BG3CNT, BGCNT_SCREENBASE(screenBaseBlock) | BGCNT_PRIORITY(1) | BGCNT_CHARBASE(charBaseBlock));
+ break;
+ }
+ SetGpuReg(REG_OFFSET_BG0HOFS + bgNum * 4, 0);
+ SetGpuReg(REG_OFFSET_BG0VOFS + bgNum * 4, 0);
+}
+
+void sub_80094EC(u8 paletteNum, u8 bgNum, u8 screenBaseBlock, u8 charBaseBlock)
+{
+ LoadPalette(gLinkTestDigitsPal, paletteNum * 16, 0x20);
+ DmaCopy16(3, gLinkTestDigitsGfx, (u16 *)BG_CHAR_ADDR(charBaseBlock), sizeof gLinkTestDigitsGfx);
+ gLinkTestBGInfo.screenBaseBlock = screenBaseBlock;
+ gLinkTestBGInfo.paletteNum = paletteNum;
+ gLinkTestBGInfo.dummy_8 = 0;
+ SetGpuReg(gBGControlRegs[bgNum], BGCNT_SCREENBASE(screenBaseBlock) | BGCNT_CHARBASE(charBaseBlock));
+}
+
+void LinkTestScreen(void)
+{
+ int i;
+
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ ResetTasks();
+ SetVBlankCallback(sub_80096BC);
+ ResetBlockSend();
+ gLinkType = 0x1111;
+ OpenLink();
+ SeedRng(gMain.vblankCounter2);
+ for (i = 0; i < MAX_LINK_PLAYERS; i++)
+ {
+ gSaveBlock2Ptr->playerTrainerId[i] = Random() % 256;
+ }
+ InitLinkTestBG(0, 2, 4, 0, 0);
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON | DISPCNT_BG2_ON | DISPCNT_OBJ_ON);
+ CreateTask(Task_DestroySelf, 0);
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+ gUnknown_03000D60 = 0;
+ InitLocalLinkPlayer();
+ CreateTask(Task_PrintTestData, 0);
+ SetMainCallback2(CB2_LinkTest);
+}
+
+void sub_8009628(u8 a0)
+{
+ gLocalLinkPlayer.lp_field_18 = a0;
+}
+
+static void InitLocalLinkPlayer(void)
+{
+ gLocalLinkPlayer.trainerId = gSaveBlock2Ptr->playerTrainerId[0] | (gSaveBlock2Ptr->playerTrainerId[1] << 8) | (gSaveBlock2Ptr->playerTrainerId[2] << 16) | (gSaveBlock2Ptr->playerTrainerId[3] << 24);
+ StringCopy(gLocalLinkPlayer.name, gSaveBlock2Ptr->playerName);
+ gLocalLinkPlayer.gender = gSaveBlock2Ptr->playerGender;
+ gLocalLinkPlayer.linkType = gLinkType;
+ gLocalLinkPlayer.language = gGameLanguage;
+ gLocalLinkPlayer.version = gGameVersion + 0x4000;
+ gLocalLinkPlayer.lp_field_2 = 0x8000;
+ gLocalLinkPlayer.name[8] = IsNationalPokedexEnabled();
+ if (FlagGet(FLAG_0x87F))
+ {
+ gLocalLinkPlayer.name[8] |= 0x10;
+ }
+}
+
+static void sub_80096BC(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+static void InitLink(void)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ {
+ gSendCmd[i] = 0xefff;
+ }
+ gLinkOpen = TRUE;
+ EnableSerial();
+}
+
+static void Task_TriggerHandshake(u8 taskId)
+{
+ if (++gTasks[taskId].data[0] == 5)
+ {
+ gShouldAdvanceLinkState = 1;
+ DestroyTask(taskId);
+ }
+}
+
+void OpenLink(void)
+{
+ int i;
+
+ if (!gWirelessCommType)
+ {
+ ResetSerial();
+ InitLink();
+ gLinkCallback = LinkCB_RequestPlayerDataExchange;
+ gLinkVSyncDisabled = FALSE;
+ gLinkErrorOccurred = FALSE;
+ gSuppressLinkErrorMessage = FALSE;
+ ResetBlockReceivedFlags();
+ ResetBlockSend();
+ gUnknown_03000D54 = 0;
+ gUnknown_030030E8 = FALSE;
+ gUnknown_030030E4 = FALSE;
+ gUnknown_030030F4 = 0;
+ CreateTask(Task_TriggerHandshake, 2);
+ }
+ else
+ {
+ sub_800E700();
+ }
+ gReceivedRemoteLinkPlayers = 0;
+ for (i = 0; i < MAX_LINK_PLAYERS; i++)
+ {
+ gRemoteLinkPlayersNotReceived[i] = TRUE;
+ gUnknown_030030F0[i] = FALSE;
+ gUnknown_030030EC[i] = FALSE;
+ }
+}
+
+void CloseLink(void)
+{
+ gReceivedRemoteLinkPlayers = FALSE;
+ if (gWirelessCommType)
+ {
+ sub_800EDD4();
+ }
+ gLinkOpen = FALSE;
+ DisableSerial();
+}
+
+static void TestBlockTransfer(u8 nothing, u8 is, u8 used)
+{
+ u8 i;
+ u8 status;
+
+ if (sLinkTestLastBlockSendPos != sBlockSend.pos)
+ {
+ LinkTest_prnthex(sBlockSend.pos, 2, 3, 2);
+ sLinkTestLastBlockSendPos = sBlockSend.pos;
+ }
+ for (i = 0; i < MAX_LINK_PLAYERS; i++)
+ {
+ if (sLinkTestLastBlockRecvPos[i] != sBlockRecv[i].pos)
+ {
+ LinkTest_prnthex(sBlockRecv[i].pos, 2, i + 4, 2);
+ sLinkTestLastBlockRecvPos[i] = sBlockRecv[i].pos;
+ }
+ }
+ status = GetBlockReceivedStatus();
+ if (status == 0xF) // 0b1111
+ {
+ for (i = 0; i < MAX_LINK_PLAYERS; i++)
+ {
+ if ((status >> i) & 1)
+ {
+ gLinkTestBlockChecksums[i] = LinkTestCalcBlockChecksum(gBlockRecvBuffer[i], sBlockRecv[i].size);
+ ResetBlockReceivedFlag(i);
+ if (gLinkTestBlockChecksums[i] != 0x0342)
+ {
+ gLinkTestDebugValuesEnabled = FALSE;
+ gUnknown_020223BD = FALSE;
+ }
+ }
+ }
+ }
+}
+
+static void LinkTestProcessKeyInput(void)
+{
+ if (gMain.newKeys & A_BUTTON)
+ {
+ gShouldAdvanceLinkState = 1;
+ }
+ if (gMain.heldKeys & B_BUTTON)
+ {
+ InitBlockSend(gHeap + 0x4000, 0x00002004);
+ }
+ if (gMain.newKeys & L_BUTTON)
+ {
+ BeginNormalPaletteFade(-1, 0, 16, 0, 2);
+ }
+ if (gMain.newKeys & START_BUTTON)
+ {
+ SetSuppressLinkErrorMessage(TRUE);
+ }
+ if (gMain.newKeys & R_BUTTON)
+ {
+ TrySavingData(1);
+ }
+ if (gMain.newKeys & SELECT_BUTTON)
+ {
+ sub_800AC34();
+ }
+ if (gLinkTestDebugValuesEnabled)
+ {
+ SetLinkDebugValues(gMain.vblankCounter2, gLinkCallback ? gLinkVSyncDisabled : gLinkVSyncDisabled | 0x10);
+ }
+}
+
+static void CB2_LinkTest(void)
+{
+ LinkTestProcessKeyInput();
+ TestBlockTransfer(1, 1, 0);
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+}
+
+u16 LinkMain2(const u16 *heldKeys)
+{
+ u8 i;
+
+ if (!gLinkOpen)
+ {
+ return 0;
+ }
+ for (i = 0; i < 8; i++)
+ {
+ gSendCmd[i] = 0;
+ }
+ gLinkHeldKeys = *heldKeys;
+ if (gLinkStatus & LINK_STAT_CONN_ESTABLISHED)
+ {
+ ProcessRecvCmds(SIO_MULTI_CNT->id);
+ if (gLinkCallback != NULL)
+ {
+ gLinkCallback();
+ }
+ CheckErrorStatus();
+ }
+ return gLinkStatus;
+}
+
+static void HandleReceiveRemoteLinkPlayer(u8 who)
+{
+ int i;
+ int count;
+
+ count = 0;
+ gRemoteLinkPlayersNotReceived[who] = FALSE;
+ for (i = 0; i < GetLinkPlayerCount_2(); i++)
+ {
+ count += gRemoteLinkPlayersNotReceived[i];
+ }
+ if (count == 0 && gReceivedRemoteLinkPlayers == 0)
+ {
+ gReceivedRemoteLinkPlayers = 1;
+ }
+}
+
+static void ProcessRecvCmds(u8 unused)
+{
+ u16 i;
+
+ for (i = 0; i < MAX_LINK_PLAYERS; i++)
+ {
+ gLinkPartnersHeldKeys[i] = 0;
+ if (gRecvCmds[i][0] == 0)
+ {
+ continue;
+ }
+ switch (gRecvCmds[i][0])
+ {
+ case LINKCMD_SEND_LINK_TYPE:
+ {
+ struct LinkPlayerBlock *block;
+
+ InitLocalLinkPlayer();
+ block = &gLocalLinkPlayerBlock;
+ block->linkPlayer = gLocalLinkPlayer;
+ memcpy(block->magic1, gASCIIGameFreakInc, sizeof(block->magic1) - 1);
+ memcpy(block->magic2, gASCIIGameFreakInc, sizeof(block->magic2) - 1);
+ InitBlockSend(block, sizeof(*block));
+ break;
+ }
+ case LINKCMD_SEND_HELD_KEYS:
+ gLinkPartnersHeldKeys[i] = gRecvCmds[i][1];
+ break;
+ case LINKCMD_0x5555:
+ gUnknown_030030E8 = TRUE;
+ break;
+ case LINKCMD_0x5566:
+ gUnknown_030030E8 = TRUE;
+ break;
+ case LINKCMD_INIT_BLOCK:
+ {
+ struct BlockTransfer *blockRecv;
+
+ blockRecv = &sBlockRecv[i];
+ blockRecv->pos = 0;
+ blockRecv->size = gRecvCmds[i][1];
+ blockRecv->multiplayerId = gRecvCmds[i][2];
+ break;
+ }
+ case LINKCMD_CONT_BLOCK:
+ {
+ if (sBlockRecv[i].size > BLOCK_BUFFER_SIZE)
+ {
+ u16 *buffer;
+ u16 j;
+
+ buffer = (u16 *)gDecompressionBuffer;
+ for (j = 0; j < CMD_LENGTH - 1; j++)
+ {
+ buffer[(sBlockRecv[i].pos / 2) + j] = gRecvCmds[i][j + 1];
+ }
+ }
+ else
+ {
+ u16 j;
+
+ for (j = 0; j < CMD_LENGTH - 1; j++)
+ {
+ gBlockRecvBuffer[i][(sBlockRecv[i].pos / 2) + j] = gRecvCmds[i][j + 1];
+ }
+ }
+
+ sBlockRecv[i].pos += (CMD_LENGTH - 1) * 2;
+
+ if (sBlockRecv[i].pos >= sBlockRecv[i].size)
+ {
+ if (gRemoteLinkPlayersNotReceived[i] == TRUE)
+ {
+ struct LinkPlayerBlock *block;
+ struct LinkPlayer *linkPlayer;
+
+ block = (struct LinkPlayerBlock *)&gBlockRecvBuffer[i];
+ linkPlayer = &gLinkPlayers[i];
+ *linkPlayer = block->linkPlayer;
+ if ((linkPlayer->version & 0xFF) == VERSION_RUBY || (linkPlayer->version & 0xFF) == VERSION_SAPPHIRE)
+ {
+ linkPlayer->name[10] = 0;
+ linkPlayer->name[9] = 0;
+ linkPlayer->name[8] = 0;
+ }
+ sub_800B524(linkPlayer);
+ if (strcmp(block->magic1, gASCIIGameFreakInc) != 0
+ || strcmp(block->magic2, gASCIIGameFreakInc) != 0)
+ {
+ SetMainCallback2(CB2_LinkError);
+ }
+ else
+ {
+ HandleReceiveRemoteLinkPlayer(i);
+ }
+ }
+ else
+ {
+ SetBlockReceivedFlag(i);
+ }
+ }
+ }
+ break;
+ case LINKCMD_0x5FFF:
+ gUnknown_030030F0[i] = TRUE;
+ break;
+ case LINKCMD_0x2FFE:
+ gUnknown_030030EC[i] = TRUE;
+ break;
+ case LINKCMD_0xAAAA:
+ sub_800A418();
+ break;
+ case LINKCMD_0xCCCC:
+ SendBlock(0, gUnknown_082ED1A8[gRecvCmds[i][1]].address, gUnknown_082ED1A8[gRecvCmds[i][1]].size);
+ break;
+ case LINKCMD_SEND_HELD_KEYS_2:
+ gLinkPartnersHeldKeys[i] = gRecvCmds[i][1];
+ break;
+ }
+ }
+}
+
+static void BuildSendCmd(u16 command)
+{
+ switch (command)
+ {
+ case LINKCMD_SEND_LINK_TYPE:
+ gSendCmd[0] = LINKCMD_SEND_LINK_TYPE;
+ gSendCmd[1] = gLinkType;
+ break;
+ case LINKCMD_0x2FFE:
+ gSendCmd[0] = LINKCMD_0x2FFE;
+ break;
+ case LINKCMD_SEND_HELD_KEYS:
+ gSendCmd[0] = LINKCMD_SEND_HELD_KEYS;
+ gSendCmd[1] = gMain.heldKeys;
+ break;
+ case LINKCMD_0x5555:
+ gSendCmd[0] = LINKCMD_0x5555;
+ break;
+ case LINKCMD_0x6666:
+ gSendCmd[0] = LINKCMD_0x6666;
+ gSendCmd[1] = 0;
+ break;
+ case LINKCMD_0x7777:
+ {
+ u8 i;
+
+ gSendCmd[0] = LINKCMD_0x7777;
+ for (i = 0; i < 5; i++)
+ {
+ gSendCmd[i + 1] = 0xEE;
+ }
+ break;
+ }
+ case LINKCMD_INIT_BLOCK:
+ gSendCmd[0] = LINKCMD_INIT_BLOCK;
+ gSendCmd[1] = sBlockSend.size;
+ gSendCmd[2] = sBlockSend.multiplayerId + 0x80;
+ break;
+ case LINKCMD_0xAAAA:
+ gSendCmd[0] = LINKCMD_0xAAAA;
+ break;
+ case LINKCMD_0xAAAB:
+ gSendCmd[0] = LINKCMD_0xAAAB;
+ gSendCmd[1] = gSpecialVar_ItemId;
+ break;
+ case LINKCMD_0xCCCC:
+ gSendCmd[0] = LINKCMD_0xCCCC;
+ gSendCmd[1] = gBlockRequestType;
+ break;
+ case LINKCMD_0x5FFF:
+ gSendCmd[0] = LINKCMD_0x5FFF;
+ gSendCmd[1] = gUnknown_030030F4;
+ break;
+ case LINKCMD_0x5566:
+ gSendCmd[0] = LINKCMD_0x5566;
+ break;
+ case LINKCMD_SEND_HELD_KEYS_2:
+ if (gUnknown_03005DA8 == 0 || gLinkTransferringData)
+ {
+ break;
+ }
+ gSendCmd[0] = LINKCMD_SEND_HELD_KEYS_2;
+ gSendCmd[1] = gUnknown_03005DA8;
+ break;
+ }
+}
+
+void sub_8009F18(void)
+{
+ if (gWirelessCommType)
+ {
+ sub_800F804();
+ }
+ gLinkCallback = sub_8009F70;
+}
+
+bool32 sub_8009F3C(void)
+{
+ if (gWirelessCommType)
+ {
+ return sub_800F7E4();
+ }
+ if (gLinkCallback == sub_8009F70)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void sub_8009F70(void)
+{
+ if (gReceivedRemoteLinkPlayers == TRUE)
+ {
+ BuildSendCmd(LINKCMD_SEND_HELD_KEYS_2);
+ }
+}
+
+void ClearLinkCallback(void)
+{
+ if (gWirelessCommType)
+ {
+ Rfu_set_zero();
+ }
+ else
+ {
+ gLinkCallback = NULL;
+ }
+}
+
+void ClearLinkCallback_2(void)
+{
+ if (gWirelessCommType)
+ {
+ Rfu_set_zero();
+ }
+ else
+ {
+ gLinkCallback = NULL;
+ }
+}
+
+u8 GetLinkPlayerCount(void)
+{
+ if (gWirelessCommType)
+ {
+ return sub_80104F4();
+ }
+ return EXTRACT_PLAYER_COUNT(gLinkStatus);
+}
+
+static int sub_8009FF8(u32 version1, u32 version2)
+{
+ int i;
+ u8 nPlayers;
+
+ nPlayers = GetLinkPlayerCount();
+ for (i = 0; i < nPlayers; i++)
+ {
+ if ((gLinkPlayers[i].version & 0xFF) == version1 || (gLinkPlayers[i].version & 0xFF) == version2)
+ {
+ return 1;
+ }
+ }
+ return -1;
+}
+
+u32 sub_800A03C(void)
+{
+ return 2;
+}
+
+bool32 sub_800A040(void)
+{
+ if (GetLinkPlayerCount() != 4 || sub_8009FF8(VERSION_RUBY, VERSION_SAPPHIRE) < 0)
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool32 Link_AnyPartnersPlayingRubyOrSapphire(void)
+{
+ if (sub_8009FF8(VERSION_RUBY, VERSION_SAPPHIRE) >= 0)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool32 sub_800A07C(void)
+{
+ int i;
+
+ i = sub_8009FF8(VERSION_FIRE_RED, VERSION_LEAF_GREEN);
+ if (i >= 0 && gLinkPlayers[i].language == LANGUAGE_JAPANESE)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void OpenLinkTimed(void)
+{
+ sPlayerDataExchangeStatus = EXCHANGE_NOT_STARTED;
+ gLinkTimeOutCounter = 0;
+ OpenLink();
+}
+
+u8 GetLinkPlayerDataExchangeStatusTimed(int lower, int upper)
+{
+ int i;
+ int count;
+ u32 index;
+ u8 cmpVal;
+ u32 linkType1;
+ u32 linkType2;
+
+ count = 0;
+ if (gReceivedRemoteLinkPlayers == TRUE)
+ {
+ cmpVal = GetLinkPlayerCount_2();
+ if (lower > cmpVal || cmpVal > upper)
+ {
+ sPlayerDataExchangeStatus = EXCHANGE_STAT_6;
+ return 6;
+ }
+ else
+ {
+ if (GetLinkPlayerCount() == 0)
+ {
+ gLinkErrorOccurred = TRUE;
+ CloseLink();
+ }
+ for (i = 0, index = 0; i < GetLinkPlayerCount(); index++, i++)
+ {
+ if (gLinkPlayers[index].linkType == gLinkPlayers[0].linkType)
+ {
+ count++;
+ }
+ }
+ if (count == GetLinkPlayerCount())
+ {
+ if (gLinkPlayers[0].linkType == 0x1133)
+ {
+ switch (sub_807A728())
+ {
+ case 1:
+ sPlayerDataExchangeStatus = EXCHANGE_STAT_4;
+ break;
+ case 2:
+ sPlayerDataExchangeStatus = EXCHANGE_STAT_5;
+ break;
+ case 0:
+ sPlayerDataExchangeStatus = EXCHANGE_COMPLETE;
+ break;
+ }
+ }
+ else
+ {
+ sPlayerDataExchangeStatus = EXCHANGE_COMPLETE;
+ }
+ }
+ else
+ {
+ sPlayerDataExchangeStatus = EXCHANGE_IN_PROGRESS;
+ linkType1 = gLinkPlayers[GetMultiplayerId()].linkType;
+ linkType2 = gLinkPlayers[GetMultiplayerId() ^ 1].linkType;
+ if ((linkType1 == 0x2266 && linkType2 == 0x2277) || (linkType1 == 0x2277 && linkType2 == 0x2266))
+ {
+ gSpecialVar_0x8005 = 3;
+ }
+ }
+ }
+ }
+ else if (++gLinkTimeOutCounter > 600)
+ {
+ sPlayerDataExchangeStatus = EXCHANGE_TIMED_OUT;
+ }
+ return sPlayerDataExchangeStatus;
+}
+
+bool8 IsLinkPlayerDataExchangeComplete(void)
+{
+ u8 i;
+ u8 count;
+ bool8 retval;
+
+ count = 0;
+ for (i = 0; i < GetLinkPlayerCount(); i++)
+ {
+ if (gLinkPlayers[i].linkType == gLinkPlayers[0].linkType)
+ {
+ count++;
+ }
+ }
+ if (count == GetLinkPlayerCount())
+ {
+ retval = TRUE;
+ sPlayerDataExchangeStatus = EXCHANGE_COMPLETE;
+ }
+ else
+ {
+ retval = FALSE;
+ sPlayerDataExchangeStatus = EXCHANGE_IN_PROGRESS;
+ }
+ return retval;
+}
+
+u32 GetLinkPlayerTrainerId(u8 who)
+{
+ return gLinkPlayers[who].trainerId;
+}
+
+void ResetLinkPlayers(void)
+{
+ int i;
+
+ for (i = 0; i <= MAX_LINK_PLAYERS; i++)
+ {
+ gLinkPlayers[i] = (struct LinkPlayer){};
+ }
+}
+
+static void ResetBlockSend(void)
+{
+ sBlockSend.active = FALSE;
+ sBlockSend.pos = 0;
+ sBlockSend.size = 0;
+ sBlockSend.src = NULL;
+}
+
+static bool32 InitBlockSend(const void *src, size_t size)
+{
+ if (sBlockSend.active)
+ {
+ return FALSE;
+ }
+ sBlockSend.multiplayerId = GetMultiplayerId();
+ sBlockSend.active = TRUE;
+ sBlockSend.size = size;
+ sBlockSend.pos = 0;
+ if (size > 0x100)
+ {
+ sBlockSend.src = src;
+ }
+ else
+ {
+ if (src != gBlockSendBuffer)
+ {
+ memcpy(gBlockSendBuffer, src, size);
+ }
+ sBlockSend.src = gBlockSendBuffer;
+ }
+ BuildSendCmd(LINKCMD_INIT_BLOCK);
+ gLinkCallback = LinkCB_BlockSendBegin;
+ sBlockSendDelayCounter = 0;
+ return TRUE;
+}
+
+static void LinkCB_BlockSendBegin(void)
+{
+ if (++sBlockSendDelayCounter > 2)
+ {
+ gLinkCallback = LinkCB_BlockSend;
+ }
+}
+
+static void LinkCB_BlockSend(void)
+{
+ int i;
+ const u8 *src;
+
+ src = sBlockSend.src;
+ gSendCmd[0] = LINKCMD_CONT_BLOCK;
+ for (i = 0; i < 7; i++)
+ {
+ gSendCmd[i + 1] = (src[sBlockSend.pos + i * 2 + 1] << 8) | src[sBlockSend.pos + i * 2];
+ }
+ sBlockSend.pos += 14;
+ if (sBlockSend.size <= sBlockSend.pos)
+ {
+ sBlockSend.active = FALSE;
+ gLinkCallback = LinkCB_BlockSendEnd;
+ }
+}
+
+static void LinkCB_BlockSendEnd(void)
+{
+ gLinkCallback = NULL;
+}
+
+static void sub_800A3F8(void)
+{
+ GetMultiplayerId();
+ BuildSendCmd(LINKCMD_SEND_HELD_KEYS);
+ gUnknown_020223C0++;
+}
+
+void sub_800A418(void)
+{
+ gUnknown_020223C0 = 0;
+ if (gWirelessCommType)
+ {
+ sub_800F850();
+ }
+ else
+ {
+ gLinkCallback = sub_800A3F8;
+ }
+}
+
+u32 sub_800A44C(void)
+{
+ return gUnknown_020223C0;
+}
+
+void sub_800A458(void)
+{
+ BuildSendCmd(LINKCMD_0xAAAA);
+}
+
+u8 GetMultiplayerId(void)
+{
+ if (gWirelessCommType == TRUE)
+ {
+ return rfu_get_multiplayer_id();
+ }
+ return SIO_MULTI_CNT->id;
+}
+
+u8 bitmask_all_link_players_but_self(void)
+{
+ u8 mpId;
+
+ mpId = GetMultiplayerId();
+ return ((1 << MAX_LINK_PLAYERS) - 1) ^ (1 << mpId);
+}
+
+bool8 SendBlock(u8 unused, const void *src, u16 size)
+{
+ if (gWirelessCommType == TRUE)
+ {
+ return sub_800FE84(src, size);
+ }
+ return InitBlockSend(src, size);
+}
+
+bool8 sub_800A4D8(u8 a0)
+{
+ if (gWirelessCommType == TRUE)
+ {
+ return sub_8010100(a0);
+ }
+ if (gLinkCallback == NULL)
+ {
+ gBlockRequestType = a0;
+ BuildSendCmd(LINKCMD_0xCCCC);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_800A520(void)
+{
+ if (gWirelessCommType == TRUE)
+ {
+ return sub_8010500();
+ }
+ return gLinkCallback == NULL;
+}
+
+u8 GetBlockReceivedStatus(void)
+{
+ if (gWirelessCommType == TRUE)
+ {
+ return sub_800FCD8();
+ }
+ return (gBlockReceivedStatus[3] << 3) | (gBlockReceivedStatus[2] << 2) | (gBlockReceivedStatus[1] << 1) | (gBlockReceivedStatus[0] << 0);
+}
+
+static void SetBlockReceivedFlag(u8 who)
+{
+ if (gWirelessCommType == TRUE)
+ {
+ sub_800F6FC(who);
+ }
+ else
+ {
+ gBlockReceivedStatus[who] = TRUE;
+ }
+}
+
+void ResetBlockReceivedFlags(void)
+{
+ int i;
+
+ if (gWirelessCommType == TRUE)
+ {
+ for (i = 0; i < MAX_RFU_PLAYERS; i++)
+ {
+ sub_800F728(i);
+ }
+ }
+ else
+ {
+ for (i = 0; i < MAX_LINK_PLAYERS; i++)
+ {
+ gBlockReceivedStatus[i] = FALSE;
+ }
+ }
+}
+
+void ResetBlockReceivedFlag(u8 who)
+{
+ if (gWirelessCommType == TRUE)
+ {
+ sub_800F728(who);
+ }
+ else if (gBlockReceivedStatus[who])
+ {
+ gBlockReceivedStatus[who] = FALSE;
+ }
+}
+
+void sub_800A620(void)
+{
+ if ((gLinkStatus & LINK_STAT_MASTER) && EXTRACT_PLAYER_COUNT(gLinkStatus) > 1)
+ {
+ gShouldAdvanceLinkState = 1;
+ }
+}
+
+static u16 LinkTestCalcBlockChecksum(const u16 *src, u16 size)
+{
+ u16 chksum;
+ u16 i;
+
+ chksum = 0;
+ for (i = 0; i < size / 2; i++)
+ {
+ chksum += src[i];
+ }
+ return chksum;
+}
+
+static void LinkTest_prnthexchar(char a0, u8 a1, u8 a2)
+{
+ u16 *vAddr;
+
+ vAddr = (u16 *)BG_SCREEN_ADDR(gLinkTestBGInfo.screenBaseBlock);
+ vAddr[a2 * 32 + a1] = (gLinkTestBGInfo.paletteNum << 12) | (a0 + 1 + gLinkTestBGInfo.dummy_8);
+}
+
+static void LinkTest_prntchar(char a0, u8 a1, u8 a2)
+{
+ u16 *vAddr;
+
+ vAddr = (u16 *)BG_SCREEN_ADDR(gLinkTestBGInfo.screenBaseBlock);
+ vAddr[a2 * 32 + a1] = (gLinkTestBGInfo.paletteNum << 12) | (a0 + gLinkTestBGInfo.dummy_8);
+}
+
+static void LinkTest_prnthex(u32 pos, u8 a0, u8 a1, u8 a2)
+{
+ char sp[32 / 2];
+ int i;
+
+ for (i = 0; i < a2; i++)
+ {
+ sp[i] = pos & 0xf;
+ pos >>= 4;
+ }
+ for (i = a2 - 1; i >= 0; i--)
+ {
+ LinkTest_prnthexchar(sp[i], a0, a1);
+ a0++;
+ }
+}
+
+static void LinkTest_prntint(int a0, u8 a1, u8 a2, u8 a3)
+{
+ char sp[32 / 2];
+ int sp10;
+ int i;
+
+ sp10 = -1;
+ if (a0 < 0)
+ {
+ sp10 = a1;
+ a0 = -a0;
+ }
+ for (i = 0; i < a3; i++)
+ {
+ sp[i] = a0 % 10;
+ a0 /= 10;
+ }
+ for (i = a3 - 1; i >= 0; i--)
+ {
+ LinkTest_prnthexchar(sp[i], a1, a2);
+ a1++;
+ }
+ if (sp10 != -1)
+ {
+ LinkTest_prnthexchar(*"\n", sp10, a2);
+ }
+}
+
+static void LinkTest_prntstr(const char *a0, u8 a1, u8 a2)
+{
+ int r6;
+ int i;
+ int r5;
+
+ r5 = 0;
+ r6 = 0;
+ for (i = 0; a0[i] != 0; a0++)
+ {
+ if (a0[i] == *"\n")
+ {
+ r5++;
+ r6 = 0;
+ }
+ else
+ {
+ LinkTest_prntchar(a0[i], a1 + r6, a2 + r5);
+ r6++;
+ }
+ }
+}
+
+static void LinkCB_RequestPlayerDataExchange(void)
+{
+ if (gLinkStatus & LINK_STAT_MASTER)
+ {
+ BuildSendCmd(LINKCMD_SEND_LINK_TYPE);
+ }
+ gLinkCallback = NULL;
+}
+
+static void Task_PrintTestData(u8 taskId)
+{
+ char sp[32];
+ int i;
+
+ strcpy(sp, gASCIITestPrint);
+ LinkTest_prntstr(sp, 5, 2);
+ LinkTest_prnthex(gShouldAdvanceLinkState, 2, 1, 2);
+ LinkTest_prnthex(gLinkStatus, 15, 1, 8);
+ LinkTest_prnthex(gLink.state, 2, 10, 2);
+ LinkTest_prnthex(EXTRACT_PLAYER_COUNT(gLinkStatus), 15, 10, 2);
+ LinkTest_prnthex(GetMultiplayerId(), 15, 12, 2);
+ LinkTest_prnthex(gLastSendQueueCount, 25, 1, 2);
+ LinkTest_prnthex(gLastRecvQueueCount, 25, 2, 2);
+ LinkTest_prnthex(GetBlockReceivedStatus(), 15, 5, 2);
+ LinkTest_prnthex(gLinkDebugSeed, 2, 12, 8);
+ LinkTest_prnthex(gLinkDebugFlags, 2, 13, 8);
+ LinkTest_prnthex(GetSioMultiSI(), 25, 5, 1);
+ LinkTest_prnthex(IsSioMultiMaster(), 25, 6, 1);
+ LinkTest_prnthex(IsLinkConnectionEstablished(), 25, 7, 1);
+ LinkTest_prnthex(HasLinkErrorOccurred(), 25, 8, 1);
+ for (i = 0; i < MAX_LINK_PLAYERS; i++)
+ {
+ LinkTest_prnthex(gLinkTestBlockChecksums[i], 10, 4 + i, 4);
+ }
+}
+
+void SetLinkDebugValues(u32 seed, u32 flags)
+{
+ gLinkDebugSeed = seed;
+ gLinkDebugFlags = flags;
+}
+
+u8 sub_800A9A8(void)
+{
+ int i;
+ u8 flags;
+
+ flags = 0;
+ for (i = 0; i < gSavedLinkPlayerCount; i++)
+ {
+ flags |= (1 << i);
+ }
+ return flags;
+}
+
+u8 sub_800A9D8(void)
+{
+ int i;
+ u8 flags;
+
+ flags = 0;
+ for (i = 0; i < GetLinkPlayerCount(); i++)
+ {
+ flags |= (1 << i);
+ }
+ return flags;
+}
+
+void sub_800AA04(u8 a0)
+{
+ int i;
+
+ gSavedLinkPlayerCount = a0;
+ gSavedMultiplayerId = GetMultiplayerId();
+ for (i = 0; i < MAX_RFU_PLAYERS; i++)
+ {
+ gSavedLinkPlayers[i] = gLinkPlayers[i];
+ }
+}
+
+u8 sub_800AA48(void)
+{
+ return gSavedLinkPlayerCount;
+}
+
+u8 sub_800AA54(void)
+{
+ return gSavedMultiplayerId;
+}
+
+bool8 sub_800AA60(void)
+{
+ int i;
+ unsigned count;
+
+ count = 0;
+ for (i = 0; i < gSavedLinkPlayerCount; i++)
+ {
+ if (gLinkPlayers[i].trainerId == gSavedLinkPlayers[i].trainerId)
+ {
+ if (gLinkType == 0x2288)
+ {
+ if (gLinkType == gLinkPlayers[i].linkType)
+ {
+ count++;
+ }
+ }
+ else
+ {
+ count++;
+ }
+ }
+ }
+ if (count == gSavedLinkPlayerCount)
+ {
+ if (GetLinkPlayerCount_2() == gSavedLinkPlayerCount)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void sub_800AAF4(void)
+{
+ int i;
+
+ // Clearly not what was meant to be written, but here it is anyway.
+ for (i = 0; i < 4; i++)
+ {
+ CpuSet(&gSavedLinkPlayers[i], NULL, sizeof(struct LinkPlayer));
+ }
+}
+
+void sub_800AB18(void)
+{
+ u8 i;
+
+ for (i = 0; i < gSavedLinkPlayerCount; i++)
+ {
+ if (gSavedLinkPlayers[i].trainerId != gLinkPlayers[i].trainerId || StringCompare(gSavedLinkPlayers[i].name, gLinkPlayers[i].name) != 0)
+ {
+ gLinkErrorOccurred = TRUE;
+ CloseLink();
+ SetMainCallback2(CB2_LinkError);
+ }
+ }
+}
+
+void sub_800AB98(void)
+{
+ gSavedLinkPlayerCount = 0;
+ gSavedMultiplayerId = 0;
+}
+
+u8 GetLinkPlayerCount_2(void)
+{
+ return EXTRACT_PLAYER_COUNT(gLinkStatus);
+}
+
+bool8 IsLinkMaster(void)
+{
+ if (gWirelessCommType)
+ {
+ return Rfu_IsMaster();
+ }
+ return EXTRACT_MASTER(gLinkStatus);
+}
+
+u8 sub_800ABE8(void)
+{
+ return gUnknown_03000D58;
+}
+
+void sub_800ABF4(u16 a0)
+{
+ if (gWirelessCommType == TRUE)
+ {
+ task_add_05_task_del_08FA224_when_no_RfuFunc();
+ }
+ else
+ {
+ if (gLinkCallback == NULL)
+ {
+ gLinkCallback = sub_800AC80;
+ gUnknown_030030E4 = FALSE;
+ gUnknown_030030F4 = a0;
+ }
+ }
+}
+
+void sub_800AC34(void)
+{
+ if (gWirelessCommType == TRUE)
+ {
+ task_add_05_task_del_08FA224_when_no_RfuFunc();
+ }
+ else
+ {
+ if (gLinkCallback != NULL)
+ {
+ gUnknown_02022B08++;
+ }
+ else
+ {
+ gLinkCallback = sub_800AC80;
+ gUnknown_030030E4 = FALSE;
+ gUnknown_030030F4 = 0;
+ }
+ }
+}
+
+static void sub_800AC80(void)
+{
+ if (gLastRecvQueueCount == 0)
+ {
+ BuildSendCmd(LINKCMD_0x5FFF);
+ gLinkCallback = sub_800ACAC;
+ }
+}
+
+static void sub_800ACAC(void)
+{
+ int i;
+ unsigned count;
+ u8 linkPlayerCount;
+
+ linkPlayerCount = GetLinkPlayerCount();
+ count = 0;
+ for (i = 0; i < linkPlayerCount; i++)
+ {
+ if (gUnknown_030030F0[i])
+ {
+ count++;
+ }
+ }
+ if (count == linkPlayerCount)
+ {
+ gBattleTypeFlags &= ~BATTLE_TYPE_20;
+ gLinkVSyncDisabled = TRUE;
+ CloseLink();
+ gLinkCallback = NULL;
+ gUnknown_030030E4 = TRUE;
+ }
+}
+
+void sub_800AD10(void)
+{
+ if (gWirelessCommType == TRUE)
+ {
+ task_add_05_task_del_08FA224_when_no_RfuFunc();
+ }
+ else
+ {
+ if (gLinkCallback != NULL)
+ {
+ gUnknown_02022B08++;
+ }
+ else
+ {
+ gLinkCallback = sub_800AD5C;
+ gUnknown_030030E4 = FALSE;
+ gUnknown_030030F4 = 0;
+ }
+ }
+}
+
+static void sub_800AD5C(void)
+{
+ if (gLastRecvQueueCount == 0)
+ {
+ BuildSendCmd(LINKCMD_0x5FFF);
+ gLinkCallback = sub_800AD88;
+ }
+}
+
+static void sub_800AD88(void)
+{
+ int i;
+ unsigned count;
+ u8 linkPlayerCount;
+
+ linkPlayerCount = GetLinkPlayerCount();
+ count = 0;
+ for (i = 0; i < linkPlayerCount; i++)
+ {
+ if (gLinkPlayers[i].language == LANGUAGE_JAPANESE)
+ {
+ count++;
+ }
+ else if (gUnknown_030030F0[i])
+ {
+ count++;
+ }
+ }
+ if (count == linkPlayerCount)
+ {
+ gBattleTypeFlags &= ~BATTLE_TYPE_20;
+ gLinkVSyncDisabled = TRUE;
+ CloseLink();
+ gLinkCallback = NULL;
+ gUnknown_030030E4 = TRUE;
+ }
+}
+
+void sub_800ADF8(void)
+{
+ if (gWirelessCommType == TRUE)
+ {
+ sub_8010434();
+ }
+ else
+ {
+ if (gLinkCallback == NULL)
+ {
+ gLinkCallback = sub_800AE30;
+ }
+ gUnknown_030030E4 = FALSE;
+ }
+}
+
+static void sub_800AE30(void)
+{
+ if (gLastRecvQueueCount == 0)
+ {
+ BuildSendCmd(LINKCMD_0x2FFE);
+ gLinkCallback = sub_800AE5C;
+ }
+}
+
+static void sub_800AE5C(void)
+{
+ u8 i;
+ u8 linkPlayerCount;
+
+ linkPlayerCount = GetLinkPlayerCount();
+ for (i = 0; i < linkPlayerCount; i++)
+ {
+ if (!gUnknown_030030EC[i])
+ {
+ break;
+ }
+ }
+ if (i == linkPlayerCount)
+ {
+ for (i = 0; i < MAX_LINK_PLAYERS; i++)
+ {
+ gUnknown_030030EC[i] = FALSE;
+ }
+ gLinkCallback = NULL;
+ }
+}
+
+static void CheckErrorStatus(void)
+{
+ if (gLinkOpen && EXTRACT_LINK_ERRORS(gLinkStatus))
+ {
+ if (!gSuppressLinkErrorMessage)
+ {
+ sLinkErrorBuffer.status = gLinkStatus;
+ sLinkErrorBuffer.lastRecvQueueCount = gLastRecvQueueCount;
+ sLinkErrorBuffer.lastSendQueueCount = gLastSendQueueCount;
+ SetMainCallback2(CB2_LinkError);
+ }
+ gLinkErrorOccurred = TRUE;
+ CloseLink();
+ }
+}
+
+void sub_800AF18(u32 status, u8 lastSendQueueCount, u8 lastRecvQueueCount, u8 unk_06)
+{
+ sLinkErrorBuffer.status = status;
+ sLinkErrorBuffer.lastSendQueueCount = lastSendQueueCount;
+ sLinkErrorBuffer.lastRecvQueueCount = lastRecvQueueCount;
+ sLinkErrorBuffer.unk_06 = unk_06;
+}
+
+void CB2_LinkError(void)
+{
+ u8 *tilemapBuffer;
+
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ m4aMPlayStop(&gMPlayInfo_SE1);
+ m4aMPlayStop(&gMPlayInfo_SE2);
+ m4aMPlayStop(&gMPlayInfo_SE3);
+ InitHeap(gHeap, HEAP_SIZE);
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ ResetPaletteFadeControl();
+ FillPalette(0, 0, 2);
+ ResetTasks();
+ ScanlineEffect_Stop();
+ if (gWirelessCommType)
+ {
+ if (!sLinkErrorBuffer.unk_06)
+ {
+ gWirelessCommType = 3;
+ }
+ sub_800E604();
+ }
+ SetVBlankCallback(sub_80096BC);
+ ResetBgsAndClearDma3BusyFlags(0);
+ InitBgsFromTemplates(0, gUnknown_082ED1FC, 2);
+ gUnknown_02022B0C = tilemapBuffer = malloc(0x800);
+ SetBgTilemapBuffer(1, tilemapBuffer);
+ if (InitWindows(gUnknown_082ED204))
+ {
+ DeactivateAllTextPrinters();
+ reset_temp_tile_data_buffers();
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BG0HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG0VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1VOFS, 0);
+ ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON | DISPCNT_WIN1_ON | DISPCNT_OBJWIN_ON);
+ LoadPalette(gUnknown_0860F074, 0xf0, 0x20);
+ gSoftResetDisabled = FALSE;
+ CreateTask(Task_DestroySelf, 0);
+ StopMapMusic();
+ gMain.callback1 = NULL;
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+ SetMainCallback2(CB2_PrintErrorMessage);
+ }
+}
+
+static void sub_800B080(void)
+{
+ LoadBgTiles(0, g2BlankTilesGfx, 0x20, 0);
+ copy_decompressed_tile_data_to_vram_autofree(1, gWirelessLinkDisplayGfx, FALSE, 0, 0);
+ CopyToBgTilemapBuffer(1, gWirelessLinkDisplayTilemap, 0, 0);
+ CopyBgTilemapBufferToVram(1);
+ LoadPalette(gWirelessLinkDisplayPal, 0, 0x20);
+ FillWindowPixelBuffer(0, 0x00);
+ FillWindowPixelBuffer(2, 0x00);
+ box_print(0, 3, 2, 6, gUnknown_082ED224, 0, gText_CommErrorEllipsis);
+ box_print(2, 3, 2, 1, gUnknown_082ED224, 0, gText_MoveCloserToLinkPartner);
+ PutWindowTilemap(0);
+ PutWindowTilemap(2);
+ CopyWindowToVram(0, 0);
+ CopyWindowToVram(2, 3);
+}
+
+static void sub_800B138(void)
+{
+ LoadBgTiles(0, g2BlankTilesGfx, 0x20, 0);
+ FillWindowPixelBuffer(1, 0x00);
+ FillWindowPixelBuffer(2, 0x00);
+ box_print(1, 3, 2, 0, gUnknown_082ED224, 0, gText_CommErrorCheckConnections);
+ PutWindowTilemap(1);
+ PutWindowTilemap(2);
+ CopyWindowToVram(1, 0);
+ CopyWindowToVram(2, 3);
+}
+
+static void CB2_PrintErrorMessage(void)
+{
+ switch (gMain.state)
+ {
+ case 00:
+ if (sLinkErrorBuffer.unk_06)
+ {
+ sub_800B080();
+ }
+ else
+ {
+ sub_800B138();
+ }
+ break;
+ case 02:
+ ShowBg(0);
+ if (sLinkErrorBuffer.unk_06)
+ {
+ ShowBg(1);
+ }
+ break;
+ case 30:
+ PlaySE(SE_BOO);
+ break;
+ case 60:
+ PlaySE(SE_BOO);
+ break;
+ case 90:
+ PlaySE(SE_BOO);
+ break;
+ case 130:
+ if (gWirelessCommType == 2)
+ {
+ box_print(0, 3, 2, 20, gUnknown_082ED224, 0, gText_ABtnTitleScreen);
+ }
+ else if (gWirelessCommType == 1)
+ {
+ box_print(0, 3, 2, 20, gUnknown_082ED224, 0, gText_ABtnRegistrationCounter);
+ }
+ break;
+ }
+ if (gMain.state == 160)
+ {
+ if (gWirelessCommType == 1)
+ {
+ if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_PIN);
+ gWirelessCommType = 0;
+ sLinkErrorBuffer.unk_06 = 0;
+ sub_81700F8();
+ }
+ }
+ else if (gWirelessCommType == 2)
+ {
+ if (gMain.newKeys & A_BUTTON)
+ {
+ rfu_REQ_stopMode();
+ rfu_waitREQComplete();
+ DoSoftReset();
+ }
+ }
+ }
+ if (gMain.state != 160)
+ {
+ gMain.state++;
+ }
+}
+
+// TODO: there might be a file boundary here, let's name it
+
+bool8 GetSioMultiSI(void)
+{
+ return (REG_SIOCNT & 0x04) != 0;
+}
+
+static bool8 IsSioMultiMaster(void)
+{
+ return (REG_SIOCNT & 0x8) && !(REG_SIOCNT & 0x04);
+}
+
+bool8 IsLinkConnectionEstablished(void)
+{
+ return EXTRACT_CONN_ESTABLISHED(gLinkStatus);
+}
+
+void SetSuppressLinkErrorMessage(bool8 flag)
+{
+ gSuppressLinkErrorMessage = flag;
+}
+
+bool8 HasLinkErrorOccurred(void)
+{
+ return gLinkErrorOccurred;
+}
+
+void sub_800B348(void)
+{
+ struct LinkPlayerBlock *block;
+
+ InitLocalLinkPlayer();
+ block = &gLocalLinkPlayerBlock;
+ block->linkPlayer = gLocalLinkPlayer;
+ memcpy(block->magic1, gASCIIGameFreakInc, sizeof(block->magic1) - 1);
+ memcpy(block->magic2, gASCIIGameFreakInc, sizeof(block->magic2) - 1);
+ memcpy(gBlockSendBuffer, block, sizeof(*block));
+}
+
+void sub_800B3A4(u32 who)
+{
+ u8 who_ = who;
+ struct LinkPlayerBlock *block;
+ struct LinkPlayer *player;
+
+ block = (struct LinkPlayerBlock *)gBlockRecvBuffer[who_];
+ player = &gLinkPlayers[who_];
+ *player = block->linkPlayer;
+ sub_800B524(player);
+ if (strcmp(block->magic1, gASCIIGameFreakInc) != 0 || strcmp(block->magic2, gASCIIGameFreakInc) != 0)
+ {
+ SetMainCallback2(CB2_LinkError);
+ }
+}
+
+bool8 HandleLinkConnection(void)
+{
+ bool32 r4;
+ bool32 r5;
+
+ if (gWirelessCommType == 0)
+ {
+ gLinkStatus = LinkMain1(&gShouldAdvanceLinkState, gSendCmd, gRecvCmds);
+ LinkMain2(&gMain.heldKeys);
+ if ((gLinkStatus & LINK_STAT_RECEIVED_NOTHING) && sub_808766C() == TRUE)
+ {
+ return TRUE;
+ }
+ }
+ else
+ {
+ r4 = sub_8010EC0();
+ r5 = sub_8010F1C();
+ if (sub_808766C() == TRUE)
+ {
+ if (r4 == TRUE || sub_800F0B8() || r5)
+ {
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+void sub_800B488(void)
+{
+ if (gReceivedRemoteLinkPlayers == 0)
+ {
+ gWirelessCommType = 1;
+ }
+}
+
+static void sub_800B4A4(void)
+{
+ if (gReceivedRemoteLinkPlayers == 0)
+ {
+ gWirelessCommType = 0;
+ }
+}
+
+void sub_800B4C0(void)
+{
+ if (gReceivedRemoteLinkPlayers == 0)
+ {
+ gWirelessCommType = 0;
+ }
+}
+
+u32 sub_800B4DC(void)
+{
+ if (gWirelessCommType != 0)
+ {
+ return sub_80124D4();
+ }
+ return gLink.recvQueue.count;
+}
+
+bool8 sub_800B504(void)
+{
+ if (sub_800B4DC() > 2)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+u8 sub_800B518(void)
+{
+ return gWirelessCommType;
+}
+
+void sub_800B524(struct LinkPlayer *player)
+{
+ player->name[10] = player->name[8];
+ ConvertInternationalString(player->name, player->language);
+}
+
+static void DisableSerial(void)
+{
+ DisableInterrupts(INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL);
+ REG_SIOCNT = SIO_MULTI_MODE;
+ REG_TMCNT_H(3) = 0;
+ REG_IF = INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL;
+ REG_SIOMLT_SEND = 0;
+ REG_SIOMLT_RECV = 0;
+ CpuFill32(0, &gLink, sizeof(gLink));
+}
+
+static void EnableSerial(void)
+{
+ DisableInterrupts(INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL);
+ REG_RCNT = 0;
+ REG_SIOCNT = SIO_MULTI_MODE;
+ REG_SIOCNT |= SIO_115200_BPS | SIO_INTR_ENABLE;
+ EnableInterrupts(INTR_FLAG_SERIAL);
+ REG_SIOMLT_SEND = 0;
+ CpuFill32(0, &gLink, sizeof(gLink));
+ sNumVBlanksWithoutSerialIntr = 0;
+ sSendNonzeroCheck = 0;
+ sRecvNonzeroCheck = 0;
+ sChecksumAvailable = 0;
+ sHandshakePlayerCount = 0;
+ gLastSendQueueCount = 0;
+ gLastRecvQueueCount = 0;
+}
+
+void ResetSerial(void)
+{
+ EnableSerial();
+ DisableSerial();
+}
+
+// link_main1.c
+
+u32 LinkMain1(u8 *shouldAdvanceLinkState, u16 *sendCmd, u16 (*recvCmds)[CMD_LENGTH])
+{
+ u32 retVal;
+ u32 retVal2;
+
+ switch (gLink.state)
+ {
+ case LINK_STATE_START0:
+ DisableSerial();
+ gLink.state = 1;
+ break;
+ case LINK_STATE_START1:
+ if (*shouldAdvanceLinkState == 1)
+ {
+ EnableSerial();
+ gLink.state = 2;
+ }
+ break;
+ case LINK_STATE_HANDSHAKE:
+ switch (*shouldAdvanceLinkState)
+ {
+ default:
+ CheckMasterOrSlave();
+ break;
+ case 1:
+ if (gLink.isMaster == LINK_MASTER && gLink.playerCount > 1)
+ {
+ gLink.handshakeAsMaster = TRUE;
+ }
+ break;
+ case 2:
+ gLink.state = LINK_STATE_START0;
+ REG_SIOMLT_SEND = 0;
+ break;
+ }
+ break;
+ case LINK_STATE_INIT_TIMER:
+ InitTimer();
+ gLink.state = LINK_STATE_CONN_ESTABLISHED;
+ // fallthrough
+ case LINK_STATE_CONN_ESTABLISHED:
+ EnqueueSendCmd(sendCmd);
+ DequeueRecvCmds(recvCmds);
+ break;
+ }
+ *shouldAdvanceLinkState = 0;
+ retVal = gLink.localId;
+ retVal |= (gLink.playerCount << LINK_STAT_PLAYER_COUNT_SHIFT);
+ if (gLink.isMaster == LINK_MASTER)
+ {
+ retVal |= LINK_STAT_MASTER;
+ }
+ {
+ u32 receivedNothing = gLink.receivedNothing << LINK_STAT_RECEIVED_NOTHING_SHIFT;
+ u32 link_field_F = gLink.link_field_F << LINK_STAT_UNK_FLAG_9_SHIFT;
+ u32 hardwareError = gLink.hardwareError << LINK_STAT_ERROR_HARDWARE_SHIFT;
+ u32 badChecksum = gLink.badChecksum << LINK_STAT_ERROR_CHECKSUM_SHIFT;
+ u32 queueFull = gLink.queueFull << LINK_STAT_ERROR_QUEUE_FULL_SHIFT;
+ u32 val;
+
+ if (gLink.state == LINK_STATE_CONN_ESTABLISHED)
+ {
+ val = LINK_STAT_CONN_ESTABLISHED;
+ val |= receivedNothing;
+ val |= retVal;
+ val |= link_field_F;
+ val |= hardwareError;
+ val |= badChecksum;
+ val |= queueFull;
+ }
+ else
+ {
+ val = retVal;
+ val |= receivedNothing;
+ val |= link_field_F;
+ val |= hardwareError;
+ val |= badChecksum;
+ val |= queueFull;
+ }
+
+ retVal = val;
+ }
+
+ if (gLink.lag == LAG_MASTER)
+ {
+ retVal |= LINK_STAT_ERROR_LAG_MASTER;
+ }
+
+ if (gLink.localId >= MAX_LINK_PLAYERS)
+ {
+ retVal |= LINK_STAT_ERROR_INVALID_ID;
+ }
+
+ retVal2 = retVal;
+ if (gLink.lag == LAG_SLAVE)
+ {
+ retVal2 |= LINK_STAT_ERROR_LAG_SLAVE;
+ }
+
+ return retVal2;
+}
+
+static void CheckMasterOrSlave(void)
+{
+ u32 terminals;
+
+ terminals = *(vu32 *)REG_ADDR_SIOCNT & (SIO_MULTI_SD | SIO_MULTI_SI);
+ if (terminals == SIO_MULTI_SD && gLink.localId == 0)
+ {
+ gLink.isMaster = LINK_MASTER;
+ }
+ else
+ {
+ gLink.isMaster = LINK_SLAVE;
+ }
+}
+
+static void InitTimer(void)
+{
+ if (gLink.isMaster)
+ {
+ REG_TM3CNT_L = -197;
+ REG_TM3CNT_H = TIMER_64CLK | TIMER_INTR_ENABLE;
+ EnableInterrupts(INTR_FLAG_TIMER3);
+ }
+}
+
+static void EnqueueSendCmd(u16 *sendCmd)
+{
+ u8 i;
+ u8 offset;
+
+ gLinkSavedIme = REG_IME;
+ REG_IME = 0;
+ if (gLink.sendQueue.count < QUEUE_CAPACITY)
+ {
+ offset = gLink.sendQueue.pos + gLink.sendQueue.count;
+ if (offset >= QUEUE_CAPACITY)
+ {
+ offset -= QUEUE_CAPACITY;
+ }
+ for (i = 0; i < CMD_LENGTH; i++)
+ {
+ sSendNonzeroCheck |= *sendCmd;
+ gLink.sendQueue.data[i][offset] = *sendCmd;
+ *sendCmd = 0;
+ sendCmd++;
+ }
+ }
+ else
+ {
+ gLink.queueFull = QUEUE_FULL_SEND;
+ }
+ if (sSendNonzeroCheck)
+ {
+ gLink.sendQueue.count++;
+ sSendNonzeroCheck = 0;
+ }
+ REG_IME = gLinkSavedIme;
+ gLastSendQueueCount = gLink.sendQueue.count;
+}
+
+
+static void DequeueRecvCmds(u16 (*recvCmds)[CMD_LENGTH])
+{
+ u8 i;
+ u8 j;
+
+ gLinkSavedIme = REG_IME;
+ REG_IME = 0;
+ if (gLink.recvQueue.count == 0)
+ {
+ for (i = 0; i < gLink.playerCount; i++)
+ {
+ for (j = 0; j < CMD_LENGTH; j++)
+ {
+ recvCmds[i][j] = 0;
+ }
+ }
+
+ gLink.receivedNothing = TRUE;
+ }
+ else
+ {
+ for (i = 0; i < gLink.playerCount; i++)
+ {
+ for (j = 0; j < CMD_LENGTH; j++)
+ {
+ recvCmds[i][j] = gLink.recvQueue.data[i][j][gLink.recvQueue.pos];
+ }
+ }
+ gLink.recvQueue.count--;
+ gLink.recvQueue.pos++;
+ if (gLink.recvQueue.pos >= QUEUE_CAPACITY)
+ {
+ gLink.recvQueue.pos = 0;
+ }
+ gLink.receivedNothing = FALSE;
+ }
+ REG_IME = gLinkSavedIme;
+}
+
+// link_intr.c
+
+void LinkVSync(void)
+{
+ if (gLink.isMaster)
+ {
+ switch (gLink.state)
+ {
+ case LINK_STATE_CONN_ESTABLISHED:
+ if (gLink.serialIntrCounter < 9)
+ {
+ if (gLink.hardwareError != TRUE)
+ {
+ gLink.lag = LAG_MASTER;
+ }
+ else
+ {
+ StartTransfer();
+ }
+ }
+ else if (gLink.lag != LAG_MASTER)
+ {
+ gLink.serialIntrCounter = 0;
+ StartTransfer();
+ }
+ break;
+ case LINK_STATE_HANDSHAKE:
+ StartTransfer();
+ break;
+ }
+ }
+ else if (gLink.state == LINK_STATE_CONN_ESTABLISHED || gLink.state == LINK_STATE_HANDSHAKE)
+ {
+ if (++sNumVBlanksWithoutSerialIntr > 10)
+ {
+ if (gLink.state == LINK_STATE_CONN_ESTABLISHED)
+ {
+ gLink.lag = LAG_SLAVE;
+ }
+ if (gLink.state == LINK_STATE_HANDSHAKE)
+ {
+ gLink.playerCount = 0;
+ gLink.link_field_F = FALSE;
+ }
+ }
+ }
+}
+
+void Timer3Intr(void)
+{
+ StopTimer();
+ StartTransfer();
+}
+
+void SerialCB(void)
+{
+ gLink.localId = SIO_MULTI_CNT->id;
+ switch (gLink.state)
+ {
+ case LINK_STATE_CONN_ESTABLISHED:
+ gLink.hardwareError = SIO_MULTI_CNT->error;
+ DoRecv();
+ DoSend();
+ SendRecvDone();
+ break;
+ case LINK_STATE_HANDSHAKE:
+ if (DoHandshake())
+ {
+ if (gLink.isMaster)
+ {
+ gLink.state = LINK_STATE_INIT_TIMER;
+ gLink.serialIntrCounter = 8;
+ }
+ else
+ {
+ gLink.state = LINK_STATE_CONN_ESTABLISHED;
+ }
+ }
+ break;
+ }
+ gLink.serialIntrCounter++;
+ sNumVBlanksWithoutSerialIntr = 0;
+ if (gLink.serialIntrCounter == 8)
+ {
+ gLastRecvQueueCount = gLink.recvQueue.count;
+ }
+}
+
+static void StartTransfer(void)
+{
+ REG_SIOCNT |= SIO_START;
+}
+
+static bool8 DoHandshake(void)
+{
+ u8 i;
+ u8 playerCount;
+ u16 minRecv;
+
+ playerCount = 0;
+ minRecv = 0xFFFF;
+ if (gLink.handshakeAsMaster == TRUE)
+ {
+ REG_SIOMLT_SEND = MASTER_HANDSHAKE;
+ }
+ else
+ {
+ REG_SIOMLT_SEND = SLAVE_HANDSHAKE;
+ }
+ *(u64 *)gLink.tempRecvBuffer = REG_SIOMLT_RECV;
+ REG_SIOMLT_RECV = 0;
+ gLink.handshakeAsMaster = FALSE;
+ for (i = 0; i < 4; i++)
+ {
+ if ((gLink.tempRecvBuffer[i] & ~0x3) == SLAVE_HANDSHAKE || gLink.tempRecvBuffer[i] == MASTER_HANDSHAKE)
+ {
+ playerCount++;
+ if (minRecv > gLink.tempRecvBuffer[i] && gLink.tempRecvBuffer[i] != 0)
+ {
+ minRecv = gLink.tempRecvBuffer[i];
+ }
+ }
+ else
+ {
+ if (gLink.tempRecvBuffer[i] != 0xFFFF)
+ {
+ playerCount = 0;
+ }
+ break;
+ }
+ }
+ gLink.playerCount = playerCount;
+ if (gLink.playerCount > 1 && gLink.playerCount == sHandshakePlayerCount && gLink.tempRecvBuffer[0] == MASTER_HANDSHAKE)
+ {
+ return TRUE;
+ }
+ if (gLink.playerCount > 1)
+ {
+ gLink.link_field_F = (minRecv & 3) + 1;
+ }
+ else
+ {
+ gLink.link_field_F = 0;
+ }
+ sHandshakePlayerCount = gLink.playerCount;
+ return FALSE;
+}
+
+static void DoRecv(void)
+{
+ u16 recv[4];
+ u8 i;
+ u8 index;
+
+ *(u64 *)recv = REG_SIOMLT_RECV;
+ if (gLink.sendCmdIndex == 0)
+ {
+ for (i = 0; i < gLink.playerCount; i++)
+ {
+ if (gLink.checksum != recv[i] && sChecksumAvailable)
+ {
+ gLink.badChecksum = TRUE;
+ }
+ }
+ gLink.checksum = 0;
+ sChecksumAvailable = TRUE;
+ }
+ else
+ {
+ index = gLink.recvQueue.pos + gLink.recvQueue.count;
+ if (index >= QUEUE_CAPACITY)
+ {
+ index -= QUEUE_CAPACITY;
+ }
+ if (gLink.recvQueue.count < QUEUE_CAPACITY)
+ {
+ for (i = 0; i < gLink.playerCount; i++)
+ {
+ gLink.checksum += recv[i];
+ sRecvNonzeroCheck |= recv[i];
+ gLink.recvQueue.data[i][gLink.recvCmdIndex][index] = recv[i];
+ }
+ }
+ else
+ {
+ gLink.queueFull = QUEUE_FULL_RECV;
+ }
+ gLink.recvCmdIndex++;
+ if (gLink.recvCmdIndex == CMD_LENGTH && sRecvNonzeroCheck)
+ {
+ gLink.recvQueue.count++;
+ sRecvNonzeroCheck = 0;
+ }
+ }
+}
+
+static void DoSend(void)
+{
+ if (gLink.sendCmdIndex == CMD_LENGTH)
+ {
+ REG_SIOMLT_SEND = gLink.checksum;
+ if (!sSendBufferEmpty)
+ {
+ gLink.sendQueue.count--;
+ gLink.sendQueue.pos++;
+ if (gLink.sendQueue.pos >= QUEUE_CAPACITY)
+ {
+ gLink.sendQueue.pos = 0;
+ }
+ }
+ else
+ {
+ sSendBufferEmpty = FALSE;
+ }
+ }
+ else
+ {
+ if (!sSendBufferEmpty && gLink.sendQueue.count == 0)
+ {
+ sSendBufferEmpty = TRUE;
+ }
+ if (sSendBufferEmpty)
+ {
+ REG_SIOMLT_SEND = 0;
+ }
+ else
+ {
+ REG_SIOMLT_SEND = gLink.sendQueue.data[gLink.sendCmdIndex][gLink.sendQueue.pos];
+ }
+ gLink.sendCmdIndex++;
+ }
+}
+
+static void StopTimer(void)
+{
+ if (gLink.isMaster)
+ {
+ REG_TM3CNT_H &= ~TIMER_ENABLE;
+ REG_TM3CNT_L = -197;
+ }
+}
+
+static void SendRecvDone(void)
+{
+ if (gLink.recvCmdIndex == CMD_LENGTH)
+ {
+ gLink.sendCmdIndex = 0;
+ gLink.recvCmdIndex = 0;
+ }
+ else if (gLink.isMaster)
+ {
+ REG_TM3CNT_H |= TIMER_ENABLE;
+ }
+}
+
+void ResetSendBuffer(void)
+{
+ u8 i;
+ u8 j;
+
+ gLink.sendQueue.count = 0;
+ gLink.sendQueue.pos = 0;
+ for (i = 0; i < CMD_LENGTH; i++)
+ {
+ for (j = 0; j < QUEUE_CAPACITY; j++)
+ {
+ gLink.sendQueue.data[i][j] = 0xEFFF;
+ }
+ }
+}
+
+void ResetRecvBuffer(void)
+{
+ u8 i;
+ u8 j;
+ u8 k;
+
+ gLink.recvQueue.count = 0;
+ gLink.recvQueue.pos = 0;
+ for (i = 0; i < MAX_LINK_PLAYERS; i++)
+ {
+ for (j = 0; j < CMD_LENGTH; j++)
+ {
+ for (k = 0; k < QUEUE_CAPACITY; k++)
+ {
+ gLink.recvQueue.data[i][j][k] = 0xEFFF;
+ }
+ }
+ }
+}
diff --git a/src/link_rfu.c b/src/link_rfu.c
new file mode 100644
index 000000000..37aa20950
--- /dev/null
+++ b/src/link_rfu.c
@@ -0,0 +1,4942 @@
+
+// Includes
+#include "global.h"
+#include "malloc.h"
+#include "battle.h"
+#include "berry_blender.h"
+#include "task.h"
+#include "random.h"
+#include "decompress.h"
+#include "text.h"
+#include "string_util.h"
+#include "event_data.h"
+#include "overworld.h"
+#include "link.h"
+#include "librfu.h"
+#include "rom_8011DC0.h"
+#include "link_rfu.h"
+
+extern u16 gUnknown_03005DA8;
+
+// Static type declarations
+
+// Static RAM declarations
+
+struct UnkRfuStruct_1 gUnknown_03004140;
+struct UnkRfuStruct_2 gUnknown_03005000;
+
+IWRAM_DATA u8 gUnknown_03000D74;
+ALIGNED(4) IWRAM_DATA u8 gUnknown_03000D78[8];
+IWRAM_DATA u8 gUnknown_03000D80[16];
+IWRAM_DATA u16 gUnknown_03000D90[8];
+
+EWRAM_DATA u8 gWirelessStatusIndicatorSpriteId = 0;
+EWRAM_DATA ALIGNED(4) struct UnkLinkRfuStruct_02022B14 gUnknown_02022B14 = {};
+EWRAM_DATA ALIGNED(2) u8 gUnknown_02022B22[8] = {};
+EWRAM_DATA struct UnkLinkRfuStruct_02022B2C gUnknown_02022B2C = {};
+EWRAM_DATA struct UnkLinkRfuStruct_02022B44 gUnknown_02022B44 = {};
+
+// Static ROM declarations
+
+static void sub_800C000(void);
+static void sub_800C7B4(u16 r8, u16 r6);
+static void sub_800C744(u32 a0);
+static void sub_800CEB0(u16 r6);
+static void sub_800CF34(void);
+static void sub_800D158(void);
+static void sub_800D20C(void);
+static void sub_800D268(void);
+static u8 sub_800D294(void);
+static void sub_800D30C(u8 a0, u8 a1);
+static void sub_800D334(u8 a0);
+static void sub_800D358(u8 a0);
+static void sub_800D434(void);
+static void sub_800D610(void);
+void sub_800D630(void);
+static bool8 sub_800DAC8(struct UnkRfuStruct_2_Sub_c1c *q1, u8 *q2);
+static void sub_800EAB4(void);
+static void sub_800EAFC(void);
+void sub_800ED34(u16 unused);
+static void sub_800EDBC(u16 unused);
+static void sub_800F048(void);
+static void sub_800F86C(u8 unused);
+static void sub_800FCC4(struct UnkRfuStruct_2_Sub_6c *data);
+void sub_800FD14(u16 command);
+static void rfufunc_80F9F44(void);
+static void sub_800FFB0(void);
+static void rfufunc_80FA020(void);
+bool32 sub_8010454(u32 a0);
+static void sub_8010528(void);
+void sub_8010750(void);
+int sub_80107A0(void);
+void sub_801084C(u8 taskId);
+void sub_80109E8(u16 a0);
+void sub_8010A70(void *a0);
+void sub_8010AAC(u8 taskId);
+void sub_8010D0C(u8 taskId);
+void sub_80115EC(u16 a0);
+u8 sub_8011CE4(const u8 *a0, u16 a1);
+void sub_8011D6C(u8 a0);
+void sub_8011E94(u8 a0, u8 a1);
+u8 sub_8012224(void);
+void sub_801227C(void);
+
+// .rodata
+
+const u16 gWirelessLinkIconPalette[] = INCBIN_U16("graphics/interface/wireless_link_icon.gbapal");
+const u8 gWirelessLinkIconPic[] = INCBIN_U8("graphics/interface/wireless_link_icon.4bpp.lz");
+const u8 sWireless_ASCIItoRSETable[] = {
+ 0xff, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x00, 0xab, 0xb5, 0xb6, 0xb1, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xb2, 0xf1, 0x00, 0xae, 0xad, 0xba,
+ 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
+ 0xa9, 0xaa, 0x00, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0x00, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1,
+ 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
+ 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1,
+ 0xd2, 0xd3, 0xd4, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
+ 0x00, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb,
+ 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
+ 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
+ 0xec, 0xed, 0xee, 0x2d, 0x2f, 0x30, 0x31, 0x32,
+ 0x33, 0x34, 0x35, 0x36, 0x50, 0x00, 0x01, 0x02,
+ 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
+ 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
+ 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,
+ 0x1b, 0xad, 0xb3, 0xb4, 0x00, 0xaf, 0x7d, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0xa0,
+ 0xae, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7e, 0xb0, 0xac,
+ 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
+ 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
+ 0x2c, 0x2e, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c,
+ 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94
+};
+const u8 sWireless_RSEtoASCIITable[] = {
+ 0x20, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c,
+ 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94,
+ 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c,
+ 0x9d, 0x9e, 0x9f, 0xa0, 0xe0, 0xe1, 0xe2, 0xe3,
+ 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
+ 0xec, 0xed, 0xee, 0xef, 0xf0, 0x7b, 0xf1, 0x7c,
+ 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x84, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xa6, 0xdd, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xf2,
+ 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,
+ 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0x01, 0x02, 0x03,
+ 0x04, 0x05, 0x06, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0xaf, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
+ 0x37, 0x38, 0x39, 0x21, 0xdf, 0xa1, 0xb0, 0xa5,
+ 0xde, 0x24, 0x2a, 0xa2, 0xa3, 0x22, 0x23, 0x20,
+ 0xa4, 0x20, 0x2f, 0x41, 0x42, 0x43, 0x44, 0x45,
+ 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d,
+ 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55,
+ 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63,
+ 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
+ 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
+ 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x20,
+ 0x20, 0x2b, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00
+};
+const struct OamData sWirelessStatusIndicatorOamData = {
+ .size = 1
+};
+static const union AnimCmd sWirelessStatusIndicatorAnim0[] = {
+ // 3 bars
+ ANIMCMD_FRAME( 4, 5),
+ ANIMCMD_FRAME( 8, 5),
+ ANIMCMD_FRAME(12, 5),
+ ANIMCMD_FRAME(16, 10),
+ ANIMCMD_FRAME(12, 5),
+ ANIMCMD_FRAME( 8, 5),
+ ANIMCMD_JUMP(0)
+};
+static const union AnimCmd sWirelessStatusIndicatorAnim1[] = {
+ // 2 bars
+ ANIMCMD_FRAME( 4, 5),
+ ANIMCMD_FRAME( 8, 5),
+ ANIMCMD_FRAME(12, 10),
+ ANIMCMD_FRAME( 8, 5),
+ ANIMCMD_JUMP(0)
+};
+static const union AnimCmd sWirelessStatusIndicatorAnim2[] = {
+ // 1 bar
+ ANIMCMD_FRAME(4, 5),
+ ANIMCMD_FRAME(8, 5),
+ ANIMCMD_JUMP(0)
+};
+static const union AnimCmd sWirelessStatusIndicatorAnim3[] = {
+ // searching
+ ANIMCMD_FRAME( 4, 10),
+ ANIMCMD_FRAME(20, 10),
+ ANIMCMD_JUMP(0)
+};
+static const union AnimCmd sWirelessStatusIndicatorAnim4[] = {
+ // error
+ ANIMCMD_FRAME(24, 10),
+ ANIMCMD_FRAME( 4, 10),
+ ANIMCMD_JUMP(0)
+};
+static const union AnimCmd *const sWirelessStatusIndicatorAnims[] = {
+ sWirelessStatusIndicatorAnim0,
+ sWirelessStatusIndicatorAnim1,
+ sWirelessStatusIndicatorAnim2,
+ sWirelessStatusIndicatorAnim3,
+ sWirelessStatusIndicatorAnim4
+};
+const struct CompressedSpriteSheet sWirelessStatusIndicatorSpriteSheet = {
+ gWirelessLinkIconPic, 0x0380, 0xD431
+};
+const struct SpritePalette sWirelessStatusIndicatorSpritePalette = {
+ gWirelessLinkIconPalette, 0xD432
+};
+static const struct SpriteTemplate sWirelessStatusIndicatorSpriteTemplate = {
+ 0xD431,
+ 0xD432,
+ &sWirelessStatusIndicatorOamData,
+ sWirelessStatusIndicatorAnims,
+ NULL,
+ gDummySpriteAffineAnimTable,
+ SpriteCallbackDummy
+};
+
+const struct UnkLinkRfuStruct_02022B2C gUnknown_082ED608 = {
+ 0x04, 0x20, 0x00, 0x00, 0x02,
+ &gUnknown_02022B14,
+ gUnknown_02022B22,
+ 0x01, 0x00, 0x258, 0x12c
+};
+const u8 gUnknown_082ED620[] = {
+ 0, 3, 2, 1, 0
+};
+const u32 gUnknown_082ED628[] = {
+ 0x000000,
+ 0x000001,
+ 0x000003,
+ 0x000007,
+ 0x00000f,
+ 0x00001f,
+ 0x00003f,
+ 0x00007f,
+ 0x0000ff,
+ 0x0001ff,
+ 0x0003ff,
+ 0x0007ff,
+ 0x000fff,
+ 0x001fff,
+ 0x003fff,
+ 0x007fff,
+ 0x00ffff,
+ 0x01ffff,
+ 0x03ffff,
+ 0x07ffff,
+ 0x0fffff,
+ 0x1fffff,
+ 0x3fffff,
+ 0x7fffff,
+ 0xffffff
+};
+const u8 gUnknown_082ED68C[] = {
+ 0, 0, 1,
+ 1, 2, 2,
+ 2, 2, 3
+};
+const u8 gUnknown_082ED695[] = {
+ 0, 1, 1, 2,
+ 1, 2, 2, 3,
+ 1, 2, 2, 3,
+ 2, 3, 3, 4
+};
+const u8 gUnknown_082ED6A5[] = {
+ 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+};
+const struct {
+ u8 *buffer;
+ u32 size;
+} gUnknown_082ED6B8[] = {
+ { gBlockSendBuffer, 200 },
+ { gBlockSendBuffer, 200 },
+ { gBlockSendBuffer, 100 },
+ { gBlockSendBuffer, 220 },
+ { gBlockSendBuffer, 40 }
+};
+const u16 gUnknown_082ED6E0[] = {
+ 0x0002, 0x7f7d, 0x0000, 0xffff
+};
+
+const char sUnref_082ED6E8[][15] = {
+ "RFU WAIT",
+ "RFU BOOT",
+ "RFU ERROR",
+ "RFU RESET",
+ "RFU CONFIG",
+ "RFU START",
+ "RFU SC POLL",
+ "RFU SP POLL",
+ "RFU START",
+ "RFU SEND ERR",
+ "RFU CP POLL"
+};
+const char sUnref_082ED6E9[][16] = {
+ " ",
+ "RECOVER START ",
+ "DISSCONECT ",
+ "RECOVER SUUSES",
+ "RECOVER FAILED"
+};
+const TaskFunc gUnknown_082ED7E0[] = {
+ sub_801084C,
+ sub_8010AAC,
+ sub_8010D0C
+};
+const char gUnknown_082ED7EC[] = "PokemonSioInfo";
+const char gUnknown_082ED7FC[] = "LINK LOSS DISCONNECT!";
+const char gUnknown_082ED814[] = "LINK LOSS RECOVERY NOW";
+
+// .text
+
+u32 sub_800BEC0(void)
+{
+ u32 r4;
+
+ r4 = rfu_REQBN_softReset_and_checkID();
+ if (r4 == 0x8001)
+ {
+ gUnknown_03004140.unk_08 = 1;
+ }
+ if (gUnknown_03004140.unk_04 != 0x17 && gUnknown_03004140.unk_04 != 0x01)
+ {
+ gUnknown_03004140.unk_05 = 0;
+ gUnknown_03004140.unk_04 = 0;
+ }
+ gUnknown_03004140.unk_07 = 0;
+ gUnknown_03004140.unk_0d = 0;
+ gUnknown_03004140.unk_01 = 0;
+ gUnknown_03004140.unk_00 = 0;
+ gUnknown_03004140.unk_06 = -1;
+ sub_800D610();
+ return r4;
+}
+
+void rfu_REQ_sendData_wrapper(u8 r2)
+{
+ u8 val;
+ if (!gUnknown_03007890->unk_00)
+ {
+ val = gUnknown_03004140.unk_02;
+ r2 = 0;
+ if (val == 1)
+ {
+ r2 = 1;
+ }
+ }
+ else
+ {
+ gUnknown_03004140.unk_03 = 0;
+ }
+ rfu_REQ_sendData(r2);
+}
+
+int sub_800BF4C(void (*func1)(u8, u8), void (*func2)(u16))
+{
+ if (func1 == NULL)
+ {
+ return 4;
+ }
+ CpuFill16(0, &gUnknown_03004140, offsetof(struct UnkRfuStruct_1, filler_48));
+ gUnknown_03004140.unk_06 = -1;
+ gUnknown_03004140.unk_40 = func1;
+ gUnknown_03004140.unk_44 = func2;
+ rfu_setMSCCallback(sub_800CEB0);
+ rfu_setREQCallback(sub_800C7B4);
+ return 0;
+}
+
+void sub_800BFA0(void)
+{
+ CpuFill16(0, &gUnknown_03004140, offsetof(struct UnkRfuStruct_1, unk_40));
+ gUnknown_03004140.unk_06 = -1;
+}
+
+void sub_800BFCC(const struct UnkLinkRfuStruct_02022B2C *unk0)
+{
+ sub_800C000();
+ gUnknown_03004140.unk_04 = 1;
+ gUnknown_03004140.unk_05 = 2;
+ gUnknown_03004140.unk_3c = unk0;
+ gUnknown_03004140.unk_09 = unk0->unk_11;
+ gUnknown_03004140.unk_32 = unk0->unk_12;
+ gUnknown_03004140.unk_18 = unk0->unk_14;
+ if (unk0->unk_10)
+ {
+ gUnknown_03004140.unk_0b = 1;
+ }
+}
+
+static void sub_800C000(void)
+{
+ u8 i;
+
+ gUnknown_03004140.unk_05 = 0;
+ gUnknown_03004140.unk_04 = 0;
+ gUnknown_03004140.unk_06 = -1;
+ gUnknown_03004140.unk_07 = 0;
+ gUnknown_03004140.unk_10 = 0;
+ gUnknown_03004140.unk_0c = 0;
+ gUnknown_03004140.unk_24 = 0;
+ gUnknown_03004140.unk_30 = 0;
+ for (i = 0; i < 4; i++)
+ {
+ gUnknown_03004140.unk_28[i] = 0;
+ gUnknown_03004140.unk_34[i] = 0;
+ }
+}
+
+void sub_800C048(void)
+{
+ gUnknown_03004140.unk_04 = 0x15;
+}
+
+u8 sub_800C054(u8 r5, u16 r7, u16 r8, const u16 *r6)
+{
+ u8 i;
+ const u16 *buffer;
+
+ if (gUnknown_03004140.unk_04 != 0 && (gUnknown_03004140.unk_04 != 0x08 || r5 != 1))
+ {
+ gUnknown_03004140.unk_14 = 1;
+ sub_800D30C(0xf3, 0x01);
+ return 1;
+ }
+ if (!rfu_getMasterSlave())
+ {
+ gUnknown_03004140.unk_14 = 2;
+ sub_800D30C(0xf3, 0x01);
+ return 2;
+ }
+ for (i = 0, buffer = r6; i < 16; i++)
+ {
+ if (*buffer++ == 0xFFFF)
+ {
+ break;
+ }
+ }
+ if (i == 16)
+ {
+ gUnknown_03004140.unk_14 = 4;
+ sub_800D30C(0xf3, 0x01);
+ return 4;
+ }
+ if (r5 > 1)
+ {
+ gUnknown_03004140.unk_07 = 1;
+ r5 = 1;
+ r7 = 0;
+ }
+ else
+ {
+ gUnknown_03004140.unk_07 = 0;
+ }
+ if (r5 != 0)
+ {
+ gUnknown_03004140.unk_04 = 5;
+ }
+ else
+ {
+ gUnknown_03004140.unk_04 = 9;
+ if (gUnknown_03004140.unk_0b)
+ {
+ gUnknown_03004140.unk_0b = 2;
+ }
+ }
+ gUnknown_03004140.unk_06 = r5;
+ gUnknown_03004140.unk_1a = r7;
+ gUnknown_03004140.unk_26 = r8;
+ gUnknown_03004140.unk_20 = r6;
+ return 0;
+}
+
+u8 sub_800C12C(u16 r6, u16 r8)
+{
+ u8 i;
+ struct RfuUnk5 *tmp;
+
+ if (gUnknown_03004140.unk_04 != 0 && (gUnknown_03004140.unk_04 < 9 || gUnknown_03004140.unk_04 > 11))
+ {
+ gUnknown_03004140.unk_14 = 1;
+ sub_800D30C(0xF3, 0x01);
+ return 1;
+ }
+ if (!rfu_getMasterSlave())
+ {
+ gUnknown_03004140.unk_14 = 2;
+ sub_800D30C(0xF3, 0x01);
+ return 2;
+ }
+ for (i = 0; i < gUnknown_03007890->unk_08; i++)
+ {
+ if (gUnknown_03007890->unk_14[i].unk_00 == r6)
+ {
+ break;
+ }
+ }
+ if (gUnknown_03007890->unk_08 == 0 || i == gUnknown_03007890->unk_08)
+ {
+ gUnknown_03004140.unk_14 = 3;
+ sub_800D30C(0xF3, 0x01);
+ return 3;
+ }
+ if (gUnknown_03004140.unk_04 == 0 || gUnknown_03004140.unk_04 == 9)
+ {
+ gUnknown_03004140.unk_04 = 12;
+ gUnknown_03004140.unk_05 = 13;
+ }
+ else
+ {
+ gUnknown_03004140.unk_04 = 11;
+ gUnknown_03004140.unk_05 = 12;
+ }
+ gUnknown_03004140.unk_1e = r6;
+ gUnknown_03004140.unk_1a = r8;
+ if (gUnknown_03004140.unk_07 != 0)
+ {
+ gUnknown_03004140.unk_07 = 7;
+ }
+ return 0;
+}
+
+void sub_800C210(u8 a0)
+{
+ u8 i;
+
+ if (a0 & gUnknown_03004140.unk_30)
+ {
+ gUnknown_03004140.unk_30 &= ~a0;
+ for (i = 0; i < 4; i++)
+ {
+ if ((a0 >> i) & 1)
+ {
+ gUnknown_03004140.unk_34[i] = 0;
+ }
+ }
+ i = gUnknown_03007890->unk_03 & a0;
+ if (i)
+ {
+ sub_800D334(i);
+ }
+ gUnknown_03004140.unk_14 = i;
+ sub_800D30C(0x33, i);
+ }
+}
+
+void sub_800C27C(bool8 a0)
+{
+ u8 r2;
+
+ r2 = 0;
+ gUnknown_03004140.unk_07 = 0;
+ if (a0)
+ {
+ sub_800C000();
+ gUnknown_03004140.unk_04 = 23;
+ }
+ else
+ {
+ switch (gUnknown_03004140.unk_04)
+ {
+ case 5:
+ gUnknown_03004140.unk_04 = 8;
+ gUnknown_03004140.unk_05 = 0;
+ r2 = 0x13;
+ break;
+ case 6:
+ gUnknown_03004140.unk_04 = 7;
+ gUnknown_03004140.unk_05 = 8;
+ break;
+ case 7:
+ gUnknown_03004140.unk_04 = 7;
+ gUnknown_03004140.unk_05 = 8;
+ break;
+ case 8:
+ break;
+ case 9:
+ gUnknown_03004140.unk_05 = 0;
+ gUnknown_03004140.unk_04 = 0;
+ r2 = 0x21;
+ break;
+ case 10:
+ gUnknown_03004140.unk_04 = 11;
+ gUnknown_03004140.unk_05 = 0;
+ break;
+ case 11:
+ gUnknown_03004140.unk_04 = 11;
+ gUnknown_03004140.unk_05 = 0;
+ break;
+ case 12:
+ gUnknown_03004140.unk_05 = 0;
+ gUnknown_03004140.unk_04 = 0;
+ r2 = 0x23;
+ break;
+ case 13:
+ gUnknown_03004140.unk_04 = 14;
+ break;
+ case 14:
+ gUnknown_03004140.unk_04 = 14;
+ break;
+ case 15:
+ break;
+ case 16:
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_11;
+ gUnknown_03004140.unk_05 = gUnknown_03004140.unk_12;
+ sub_800D334(gUnknown_03007890->unk_03);
+ gUnknown_03004140.unk_14 = gUnknown_03007890->unk_03;
+ sub_800D30C(0x33, 0x01);
+ return;
+ case 17:
+ gUnknown_03004140.unk_04 = 18;
+ break;
+ case 18:
+ gUnknown_03004140.unk_04 = 18;
+ break;
+ default:
+ gUnknown_03004140.unk_05 = 0;
+ gUnknown_03004140.unk_04 = 0;
+ r2 = 0x43;
+ break;
+ }
+ if (gUnknown_03004140.unk_04 == 0)
+ {
+ sub_800D30C(r2, 0);
+ }
+ }
+}
+
+bool8 sub_800C36C(u16 a0)
+{
+ bool8 retVal;
+ u8 i;
+ u8 sp0;
+ u8 sp1;
+ u8 sp2;
+ u8 flags;
+
+ retVal = FALSE;
+ rfu_REQBN_watchLink(a0, &sp0, &sp1, &sp2);
+ if (sp0)
+ {
+ gUnknown_03004140.unk_14 = sp0;
+ gUnknown_03004140.unk_16 = sp1;
+ if (gUnknown_03004140.unk_09)
+ {
+ gUnknown_03004140.unk_0a = 1;
+ if (gUnknown_03004140.unk_06 == 0 && sp1 == 0)
+ {
+ gUnknown_03004140.unk_0a = 4;
+ }
+ if (gUnknown_03004140.unk_0a == 1)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ if ((sp0 >> i) & 1)
+ {
+ gUnknown_03004140.unk_30 |= (1 << i);
+ gUnknown_03004140.unk_34[i] = gUnknown_03004140.unk_32;
+ }
+ }
+ sub_800D30C(0x31, 0x01);
+ }
+ else
+ {
+ gUnknown_03004140.unk_0a = 0;
+ sub_800D334(sp0);
+ retVal = TRUE;
+ sub_800D30C(0x33, 0x01);
+ }
+ }
+ else
+ {
+ sub_800D334(sp0);
+ retVal = TRUE;
+ sub_800D30C(0x30, 0x02);
+ }
+ sub_800D610();
+ }
+ if (gUnknown_03007890->unk_00 == 1)
+ {
+ if (sp2)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ if ((gUnknown_03004140.unk_30 >> i) & 1 && (sp2 >> i) & 1)
+ {
+ gUnknown_03004140.unk_34[i] = 0;
+ }
+ }
+ gUnknown_03004140.unk_30 &= ~sp2;
+ gUnknown_03004140.unk_14 = sp2;
+ sub_800D30C(0x32, 0x01);
+ }
+ if (gUnknown_03004140.unk_30)
+ {
+ flags = 0;
+ for (i = 0; i < 4; i++)
+ {
+ if ((gUnknown_03004140.unk_30 >> i) & 1 && gUnknown_03004140.unk_34[i] && --gUnknown_03004140.unk_34[i] == 0)
+ {
+ gUnknown_03004140.unk_30 &= ~(1 << i);
+ flags |= (1 << i);
+ }
+ }
+ if (flags)
+ {
+ sub_800D334(flags);
+ retVal = TRUE;
+ gUnknown_03004140.unk_14 = flags;
+ sub_800D30C(0x33, 0x01);
+ }
+ }
+ if (!gUnknown_03004140.unk_30)
+ {
+ gUnknown_03004140.unk_0a = 0;
+ }
+ }
+ return retVal;
+}
+
+void rfu_syncVBlank_(void)
+{
+ if (rfu_syncVBlank())
+ {
+ sub_800D30C(0xF1, 0x00);
+ sub_800D610();
+ }
+}
+
+void sub_800C54C(u32 a0)
+{
+ u8 r2;
+
+ if (gUnknown_03004140.unk_40 == NULL && gUnknown_03004140.unk_04 != 0)
+ {
+ gUnknown_03004140.unk_04 = 0;
+ }
+ else
+ {
+ if (gUnknown_03004140.unk_07 != 0)
+ {
+ sub_800C744(a0);
+ }
+ do
+ {
+ if (gUnknown_03004140.unk_04 != 0)
+ {
+ rfu_waitREQComplete();
+ gUnknown_03004140.unk_0e = 1;
+ switch (gUnknown_03004140.unk_04)
+ {
+ case 23:
+ r2 = sub_800BEC0() == 0x8001 ? 0x44 : 0xFF;
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0;
+ sub_800D30C(r2, 0);
+ break;
+ case 1:
+ if (sub_800BEC0() == 0x8001)
+ {
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05;
+ gUnknown_03004140.unk_05 = 3;
+ }
+ else
+ {
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0;
+ sub_800D30C(0xFF, 0);
+ }
+ break;
+ case 2:
+ rfu_REQ_reset();
+ break;
+ case 3:
+ rfu_REQ_configSystem(gUnknown_03004140.unk_3c->unk_02, gUnknown_03004140.unk_3c->unk_00, gUnknown_03004140.unk_3c->unk_01);
+ break;
+ case 4:
+ rfu_REQ_configGameData(gUnknown_03004140.unk_3c->unk_04, gUnknown_03004140.unk_3c->unk_06, gUnknown_03004140.unk_3c->unk_08, gUnknown_03004140.unk_3c->unk_0c);
+ break;
+ case 5:
+ rfu_REQ_startSearchChild();
+ break;
+ case 6:
+ rfu_REQ_pollSearchChild();
+ break;
+ case 7:
+ rfu_REQ_endSearchChild();
+ break;
+ case 8:
+ break;
+ case 9:
+ rfu_REQ_startSearchParent();
+ break;
+ case 10:
+ rfu_REQ_pollSearchParent();
+ break;
+ case 11:
+ rfu_REQ_endSearchParent();
+ break;
+ case 12:
+ rfu_REQ_startConnectParent(gUnknown_03004140.unk_1e);
+ break;
+ case 13:
+ rfu_REQ_pollConnectParent();
+ break;
+ case 14:
+ rfu_REQ_endConnectParent();
+ break;
+ case 15:
+ break;
+ case 16:
+ rfu_REQ_CHILD_startConnectRecovery(gUnknown_03007890->unk_03);
+ break;
+ case 17:
+ rfu_REQ_CHILD_pollConnectRecovery();
+ break;
+ case 18:
+ rfu_REQ_CHILD_endConnectRecovery();
+ break;
+ case 19:
+ rfu_REQ_changeMasterSlave();
+ break;
+ case 20:
+ break;
+ case 21:
+ rfu_REQ_stopMode();
+ break;
+ case 22:
+ break;
+ }
+ rfu_waitREQComplete();
+ gUnknown_03004140.unk_0e = 0;
+ }
+ } while (gUnknown_03004140.unk_04 == 18 || gUnknown_03004140.unk_04 == 19);
+ if (gUnknown_03007890->unk_00 != 1 || !sub_800C36C(0))
+ {
+ sub_800CF34();
+ sub_800D158();
+ sub_800D268();
+ sub_800D434();
+ }
+ }
+}
+
+static void sub_800C744(u32 a0)
+{
+ if (gUnknown_03004140.unk_07 == 5)
+ {
+ gUnknown_03004140.unk_06 = 1;
+ gUnknown_03004140.unk_04 = 5;
+ gUnknown_03004140.unk_1a = gUnknown_03004140.unk_1c;
+ if (gUnknown_03004140.unk_1a)
+ {
+ gUnknown_03004140.unk_07 = 6;
+ }
+ else
+ {
+ gUnknown_03004140.unk_07 = 1;
+ }
+ }
+ if (gUnknown_03004140.unk_07 == 1)
+ {
+ gUnknown_03004140.unk_06 = 1;
+ gUnknown_03004140.unk_04 = 5;
+ gUnknown_03004140.unk_1a = a0 % 140;
+ gUnknown_03004140.unk_1c = 140 - gUnknown_03004140.unk_1a;
+ if (gUnknown_03004140.unk_1a)
+ {
+ gUnknown_03004140.unk_07 = 2;
+ }
+ else
+ {
+ gUnknown_03004140.unk_07 = 3;
+ }
+ }
+ if (gUnknown_03004140.unk_07 == 3)
+ {
+ gUnknown_03004140.unk_06 = 0;
+ gUnknown_03004140.unk_1a = 40;
+ gUnknown_03004140.unk_07 = 4;
+ gUnknown_03004140.unk_04 = 9;
+ }
+}
+
+static void sub_800C7B4(u16 r8, u16 r6)
+{
+ u8 sp0;
+ register u8 *stwiRecvBuffer asm("r0");
+ u8 *tmp;
+ u8 i;
+
+ if (gUnknown_03004140.unk_0e != 0)
+ {
+ gUnknown_03004140.unk_0e = 0;
+ switch (r8)
+ {
+ case 16:
+ if (r6 == 0)
+ {
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05;
+ gUnknown_03004140.unk_05 = 4;
+ }
+ break;
+ case 23:
+ if (r6 == 0)
+ {
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05;
+ gUnknown_03004140.unk_05 = 0;
+ }
+ break;
+ case 22:
+ if (r6 == 0)
+ {
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0;
+ sub_800D30C(0x00, 0x00);
+ }
+ break;
+ case 25:
+ if (r6 == 0)
+ {
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 6;
+ }
+ break;
+ case 26:
+ if (gUnknown_03004140.unk_1a && --gUnknown_03004140.unk_1a == 0)
+ {
+ gUnknown_03004140.unk_04 = 7;
+ gUnknown_03004140.unk_05 = 8;
+ }
+ break;
+ case 27:
+ if (r6 == 0)
+ {
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05;
+ gUnknown_03004140.unk_05 = 0;
+ if (gUnknown_03004140.unk_07 == 0)
+ {
+ sub_800D30C(0x13, 0x00);
+ }
+ }
+ break;
+ case 28:
+ if (r6 == 0)
+ {
+ if (gUnknown_03004140.unk_0b == 1 && gUnknown_03004140.unk_1a > 1)
+ {
+ gUnknown_03004140.unk_1a--;
+ }
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 10;
+ }
+ break;
+ case 29:
+ if (r6 == 0)
+ {
+ sp0 = sub_800D294();
+ gUnknown_03004140.unk_14 = sp0;
+ if (sp0)
+ {
+ sub_800D30C(0x20, 0x01);
+ }
+ if (gUnknown_03004140.unk_0b && gUnknown_03004140.unk_1a != 1 && gUnknown_03007890->unk_08 == 4)
+ {
+ rfu_REQ_endSearchParent();
+ rfu_waitREQComplete();
+ gUnknown_03004140.unk_04 = 9;
+ gUnknown_03004140.unk_0b = 1;
+ }
+ }
+ if (gUnknown_03004140.unk_1a && --gUnknown_03004140.unk_1a == 0)
+ {
+ gUnknown_03004140.unk_04 = 11;
+ gUnknown_03004140.unk_05 = 0;
+ }
+ break;
+ case 30:
+ if (r6 == 0)
+ {
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05;
+ if (gUnknown_03004140.unk_07 == 0)
+ {
+ if (gUnknown_03004140.unk_04 == 0)
+ {
+ sub_800D30C(0x21, 0x00);
+ }
+ }
+ else if (gUnknown_03004140.unk_07 != 7)
+ {
+ gUnknown_03004140.unk_04 = 5;
+ gUnknown_03004140.unk_07 = 5;
+ }
+ }
+ break;
+ case 31:
+ if (r6 == 0)
+ {
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 13;
+ }
+ break;
+ case 32:
+ if (r6 == 0 && !rfu_getConnectParentStatus(&sp0, &gUnknown_03004140.unk_10) && !sp0)
+ {
+ gUnknown_03004140.unk_04 = 14;
+ }
+ if (gUnknown_03004140.unk_1a && --gUnknown_03004140.unk_1a == 0)
+ {
+ gUnknown_03004140.unk_04 = 14;
+ }
+ break;
+ case 33:
+ if (r6 == 0 && !rfu_getConnectParentStatus(&sp0, &gUnknown_03004140.unk_10))
+ {
+ if (!sp0)
+ {
+ gUnknown_03004140.unk_04 = 19;
+ gUnknown_03004140.unk_05 = 15;
+ gUnknown_03004140.unk_1e = 0x22;
+ gUnknown_03004140.unk_14 = gUnknown_03004140.unk_10;
+ }
+ else
+ {
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0;
+ gUnknown_03004140.unk_1e = 0x23;
+ gUnknown_03004140.unk_14 = sp0;
+ if (gUnknown_03004140.unk_07)
+ {
+ gUnknown_03004140.unk_07 = 3;
+ gUnknown_03004140.unk_04 = 9;
+ }
+ }
+ sub_800D30C(gUnknown_03004140.unk_1e, 0x01);
+ gUnknown_03004140.unk_1e = 0;
+ }
+ break;
+ case 50:
+ if (r6 == 0)
+ {
+ gUnknown_03004140.unk_14 = gUnknown_03007890->unk_03;
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 17;
+ for (gUnknown_03004140.unk_10 = 0; gUnknown_03004140.unk_10 < 4; gUnknown_03004140.unk_10 ++)
+ {
+ if ((gUnknown_03007890->unk_03 >> gUnknown_03004140.unk_10) & 1)
+ {
+ break;
+ }
+ }
+ }
+ break;
+ case 51:
+ if (r6 == 0 && !rfu_CHILD_getConnectRecoveryStatus(&sp0) && sp0 < 2)
+ {
+ gUnknown_03004140.unk_04 = 18;
+ }
+ if (gUnknown_03004140.unk_34[gUnknown_03004140.unk_10] && --gUnknown_03004140.unk_34[gUnknown_03004140.unk_10] == 0)
+ {
+ gUnknown_03004140.unk_04 = 18;
+ }
+ break;
+ case 52:
+ if (r6 == 0 && !rfu_CHILD_getConnectRecoveryStatus(&sp0))
+ {
+ if (!sp0)
+ {
+ gUnknown_03004140.unk_04 = 19;
+ gUnknown_03004140.unk_05 = 22;
+ gUnknown_03004140.unk_1e = 0x32;
+ }
+ else
+ {
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0;
+ sub_800D334(gUnknown_03007890->unk_03);
+ gUnknown_03004140.unk_1e = 0x33;
+ }
+ gUnknown_03004140.unk_34[gUnknown_03004140.unk_10] = 0;
+ gUnknown_03004140.unk_30 = 0;
+ gUnknown_03004140.unk_0a = 0;
+ sub_800D30C(gUnknown_03004140.unk_1e, 0x01);
+ gUnknown_03004140.unk_1e = 0;
+ }
+ break;
+ case 39:
+ if (r6 == 0)
+ {
+ if (gUnknown_03004140.unk_05 == 22)
+ {
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_11;
+ gUnknown_03004140.unk_05 = gUnknown_03004140.unk_12;
+ gUnknown_03004140.unk_02 = 1;
+ sub_800D30C(0x41, 0x00);
+ }
+ else if (gUnknown_03004140.unk_05 == 15)
+ {
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05;
+ gUnknown_03004140.unk_02 = 1;
+ sub_800D30C(0x41, 0x00);
+ gUnknown_03004140.unk_24 |= 1 << gUnknown_03004140.unk_10;
+ gUnknown_03004140.unk_28[gUnknown_03004140.unk_10] = gUnknown_03004140.unk_26;
+ rfu_clearSlot(4, gUnknown_03004140.unk_10);
+ tmp = &sp0;
+ *tmp = rfu_NI_CHILD_setSendGameName(gUnknown_03004140.unk_10, 0x0e);
+ if (*tmp)
+ {
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0;
+ sub_800D610();
+ sub_800D334(gUnknown_03007890->unk_02 | gUnknown_03007890->unk_03);
+ gUnknown_03004140.unk_14 = sp0;
+ sub_800D30C(0x25, 0x01);
+ }
+ }
+ }
+ break;
+ case 61:
+ if (r6 == 0)
+ {
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0;
+ sub_800D30C(0x42, 0x00);
+ }
+ break;
+ }
+ gUnknown_03004140.unk_0e = 1;
+ }
+ else if (r6 == 3 && gUnknown_03004140.unk_0f && (r8 == 0x24 || r8 == 0x26 || r8 == 0x27))
+ {
+ rfu_REQ_RFUStatus();
+ rfu_waitREQComplete();
+ rfu_getRFUStatus(&sp0);
+ if (sp0 == 0 && gUnknown_03007890->unk_00 == 0)
+ {
+ stwiRecvBuffer = rfu_getSTWIRecvBuffer();
+ stwiRecvBuffer[4] = gUnknown_03007890->unk_02;
+ stwiRecvBuffer[5] = 1;
+ sub_800C36C(0x29);
+ r6 = 0;
+ }
+ }
+ switch (r8)
+ {
+ case 48:
+ if (r6 == 0)
+ {
+ stwiRecvBuffer = rfu_getSTWIRecvBuffer();
+ gUnknown_03004140.unk_14 = stwiRecvBuffer[8];
+ sub_800D358(gUnknown_03004140.unk_14);
+ if (gUnknown_03004140.unk_30)
+ {
+ gUnknown_03004140.unk_30 &= ~gUnknown_03004140.unk_14;
+ for (i = 0; i < 4; i++)
+ {
+ if ((gUnknown_03004140.unk_14 >> i) & 1)
+ {
+ gUnknown_03004140.unk_34[i] = 0;
+ }
+ }
+ if (gUnknown_03004140.unk_06 == 0)
+ {
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0;
+ }
+ }
+ sp0 = gUnknown_03004140.unk_00 & gUnknown_03004140.unk_14;
+ for (i = 0; i < 4; i++)
+ {
+ if ((sp0 >> i) & 1 && gUnknown_03004140.unk_01)
+ {
+ gUnknown_03004140.unk_01--;
+ }
+ }
+ gUnknown_03004140.unk_00 &= ~gUnknown_03004140.unk_14;
+ if (gUnknown_03004140.unk_07)
+ {
+ if (gUnknown_03007890->unk_00 == 0xFF)
+ {
+ if (gUnknown_03004140.unk_07 == 8)
+ {
+ gUnknown_03004140.unk_1a = gUnknown_03004140.unk_1c;
+ gUnknown_03004140.unk_07 = 6;
+ gUnknown_03004140.unk_04 = 6;
+ }
+ else if (gUnknown_03004140.unk_04 != 6 && gUnknown_03004140.unk_04 != 7)
+ {
+ gUnknown_03004140.unk_07 = 1;
+ gUnknown_03004140.unk_04 = 5;
+ }
+ }
+ }
+ if (gUnknown_03007890->unk_00 == 0xFF)
+ {
+ if (gUnknown_03004140.unk_04 == 0)
+ {
+ gUnknown_03004140.unk_06 = -1;
+ }
+ }
+ if (gUnknown_03004140.unk_0e == 0)
+ {
+ sub_800D30C(0x40, 0x01);
+ }
+ }
+ break;
+ case 38:
+ sub_800D20C();
+ if (gUnknown_03007890->unk_00 != 0xFF)
+ {
+ sub_800D30C(0x50, 0x00);
+ }
+ break;
+ case 16:
+ case 61:
+ if (r6 == 0)
+ {
+ gUnknown_03004140.unk_0d = 0;
+ gUnknown_03004140.unk_01 = 0;
+ gUnknown_03004140.unk_00 = 0;;
+ gUnknown_03004140.unk_06 = -1;
+ sub_800D610();
+ if (r8 == 61)
+ {
+ sub_800BFA0();
+ }
+ }
+ break;
+ }
+ if (r6 != 0)
+ {
+ if (r8 == 28 && r6 != 0 && gUnknown_03004140.unk_07 == 4)
+ {
+ gUnknown_03007890->unk_00 = 1;
+ gUnknown_03007890->unk_02 = 15;
+ sub_800D334(15);
+ rfu_waitREQComplete();
+ return;
+ }
+ else
+ {
+ gUnknown_03004140.unk_14 = r8;
+ gUnknown_03004140.unk_16 = r6;
+ if (gUnknown_03004140.unk_0e)
+ {
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0;
+ }
+ sub_800D30C(0xf0, 0x02);
+ sub_800D610();
+ }
+ }
+ if (r8 == 0xFF)
+ {
+ sub_800D30C(0xf2, 0x00);
+ sub_800D610();
+ }
+}
+
+static void sub_800CEB0(u16 r6)
+{
+ u8 r7;
+ u8 sp0;
+
+ r7 = gUnknown_03004140.unk_0e;
+ gUnknown_03004140.unk_0e = 0;
+ gUnknown_03004140.unk_0f = 1;
+ if (gUnknown_03007890->unk_00 == 0)
+ {
+ sub_800C36C(r6);
+ if (gUnknown_03004140.unk_02 != 1)
+ {
+ sub_800D610();
+ gUnknown_03004140.unk_0f = 0;
+ gUnknown_03004140.unk_0e = r7;
+ return;
+ }
+ }
+ else
+ {
+ if (!rfu_UNI_PARENT_getDRAC_ACK(&sp0))
+ {
+ gUnknown_03004140.unk_03 |= sp0;
+ }
+ }
+ if (gUnknown_03004140.unk_44 != NULL)
+ {
+ gUnknown_03004140.unk_44(r6);
+ rfu_waitREQComplete();
+ if (gUnknown_03004140.unk_02 == 2)
+ {
+ sub_800D610();
+ }
+ }
+ gUnknown_03004140.unk_0f = 0;
+ gUnknown_03004140.unk_0e = r7;
+}
+
+static void sub_800CF34(void)
+{
+ u8 flags;
+ u8 sp0;
+ u8 i;
+ u8 r5;
+ u8 r4;
+ const u16 *ptr;
+
+ if (gUnknown_03004140.unk_04 == 5 || gUnknown_03004140.unk_04 == 6 || gUnknown_03004140.unk_04 == 7 || gUnknown_03004140.unk_04 == 8)
+ {
+ flags = ((gUnknown_03007890->unk_02 ^ gUnknown_03004140.unk_0c) & gUnknown_03007890->unk_02) & ~gUnknown_03007890->unk_07;
+ gUnknown_03004140.unk_0c = gUnknown_03007890->unk_02;
+ if (flags)
+ {
+ gUnknown_03004140.unk_14 = flags;
+ sub_800D30C(0x10, 0x01);
+ }
+ sp0 = 0x00;
+ for (i = 0; i < 4; i++)
+ {
+ r4 = 1 << i;
+ r5 = 0x00;
+ if (flags & r4)
+ {
+ gUnknown_03004140.unk_28[i] = gUnknown_03004140.unk_26;
+ gUnknown_03004140.unk_24 |= r4;
+ }
+ else if (gUnknown_03004140.unk_24 & r4)
+ {
+ if (gUnknown_03007880[i]->unk_34 == 0x46)
+ {
+ if (gUnknown_03007880[i]->unk_61 == 1)
+ {
+ r5 = 0x02;
+ for (ptr = gUnknown_03004140.unk_20; *ptr != 0xFFFF; ptr++)
+ {
+ if (gUnknown_03007890->unk_14[i].unk_04 == *ptr)
+ {
+ gUnknown_03004140.unk_00 |= r4;
+ gUnknown_03004140.unk_01++;
+ sp0 |= r4;
+ r5 |= 0x01;
+ break;
+ }
+ }
+ if (!(r5 & 0x01))
+ {
+ r5 |= 0x04;
+ }
+ }
+ }
+ else if (--gUnknown_03004140.unk_28[i] == 0)
+ {
+ r5 = 0x06;
+ }
+ if (r5 & 0x02)
+ {
+ gUnknown_03004140.unk_24 &= ~r4;
+ gUnknown_03004140.unk_28[i] = 0;
+ rfu_clearSlot(0x08, i);
+ }
+ if (r5 & 0x04)
+ {
+ gUnknown_03004140.unk_0d |= r4;
+ }
+ }
+ }
+ if (sp0)
+ {
+ gUnknown_03004140.unk_14 = sp0;
+ sub_800D30C(0x11, 0x01);
+ }
+ if (gUnknown_03004140.unk_0d)
+ {
+ r5 = 0x01;
+ if (gUnknown_03007890->unk_06 && ((gUnknown_03004140.unk_03 & gUnknown_03004140.unk_00) != gUnknown_03004140.unk_00))
+ {
+ r5 = 0x00;
+ }
+ if (r5)
+ {
+ sub_800D334(gUnknown_03004140.unk_0d);
+ gUnknown_03004140.unk_14 = gUnknown_03004140.unk_0d;
+ gUnknown_03004140.unk_0d = 0;
+ sub_800D30C(0x12, 0x01);
+ }
+ }
+ if (gUnknown_03004140.unk_24 == 0 && gUnknown_03004140.unk_04 == 8)
+ {
+ if (gUnknown_03004140.unk_07 == 0)
+ {
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0;
+ sub_800D30C(0x14, 0x00);
+ }
+ else
+ {
+ if (gUnknown_03004140.unk_07 == 2)
+ {
+ gUnknown_03004140.unk_07 = 3;
+ gUnknown_03004140.unk_04 = 9;
+ }
+ else
+ {
+ gUnknown_03004140.unk_07 = 1;
+ gUnknown_03004140.unk_04 = 5;
+ }
+ if (gUnknown_03004140.unk_00)
+ {
+ gUnknown_03004140.unk_1a = 0;
+ gUnknown_03004140.unk_07 = 8;
+ gUnknown_03004140.unk_04 = 5;
+ }
+ }
+ }
+ }
+}
+
+static void sub_800D158(void)
+{
+ u16 imeBak = REG_IME;
+ REG_IME = 0;
+ if (gUnknown_03004140.unk_04 == 15)
+ {
+ if (--gUnknown_03004140.unk_28[gUnknown_03004140.unk_10] == 0 || gUnknown_03007880[gUnknown_03004140.unk_10]->unk_0 == 0x27)
+ {
+ sub_800D630();
+ gUnknown_03004140.unk_04 = 24;
+ rfu_clearSlot(4, gUnknown_03004140.unk_10);
+ gUnknown_03004140.unk_24 &= ~(1 << gUnknown_03004140.unk_10);
+ gUnknown_03004140.unk_28[gUnknown_03004140.unk_10] = 0;
+ }
+ }
+ REG_IME = imeBak;
+ if (gUnknown_03004140.unk_04 == 24)
+ {
+ if (gUnknown_03004140.unk_02 == 1)
+ {
+ sub_800D630();
+ }
+ if (gUnknown_03004140.unk_02 == 0)
+ {
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0;
+ sub_800D334(gUnknown_03007890->unk_02 | gUnknown_03007890->unk_03);
+ gUnknown_03004140.unk_14 = 0;
+ sub_800D30C(0x25, 0x01);
+ }
+ }
+}
+
+static void sub_800D20C(void)
+{
+ if (gUnknown_03004140.unk_04 == 15 && gUnknown_03007880[gUnknown_03004140.unk_10]->unk_0 == 0x26)
+ {
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0;
+ rfu_clearSlot(4, gUnknown_03004140.unk_10);
+ gUnknown_03004140.unk_24 &= ~(1 << gUnknown_03004140.unk_10);
+ gUnknown_03004140.unk_28[gUnknown_03004140.unk_10] = 0;
+ sub_800D30C(0x24, 0x00);
+ }
+}
+
+static void sub_800D268(void)
+{
+ if (gUnknown_03004140.unk_06 == 0 && gUnknown_03004140.unk_0a == 1)
+ {
+ gUnknown_03004140.unk_11 = gUnknown_03004140.unk_04;
+ gUnknown_03004140.unk_12 = gUnknown_03004140.unk_05;
+ gUnknown_03004140.unk_04 = 16;
+ gUnknown_03004140.unk_05 = 17;
+ gUnknown_03004140.unk_0a = 2;
+ }
+}
+
+static u8 sub_800D294(void)
+{
+ u8 i;
+ const u16 *ptr;
+ u8 flags = 0x00;
+
+ for (i = 0; i < gUnknown_03007890->unk_08; i++)
+ {
+ for (ptr = gUnknown_03004140.unk_20; *ptr != 0xffff; ptr++)
+ {
+ if (gUnknown_03007890->unk_14[i].unk_04 == *ptr)
+ {
+ flags |= (1 << i);
+ }
+ }
+ }
+ return flags;
+}
+
+static void sub_800D30C(u8 a0, u8 a1)
+{
+ if (gUnknown_03004140.unk_40 != NULL)
+ {
+ gUnknown_03004140.unk_40(a0, a1);
+ }
+ gUnknown_03004140.unk_14 = gUnknown_03004140.unk_16 = 0;
+}
+
+static void sub_800D334(u8 a0)
+{
+ u8 unk_0e_bak = gUnknown_03004140.unk_0e;
+ gUnknown_03004140.unk_0e = 1;
+ rfu_REQ_disconnect(a0);
+ rfu_waitREQComplete();
+ gUnknown_03004140.unk_0e = unk_0e_bak;
+}
+
+static void sub_800D358(u8 a0)
+{
+ u8 i;
+
+ if (gUnknown_03007890->unk_04)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ if (gUnknown_03007880[i]->unk_0 & 0x8000 && gUnknown_03007880[i]->unk_1a & a0)
+ {
+ rfu_changeSendTarget(0x20, i, gUnknown_03007880[i]->unk_1a & ~a0);
+ }
+ }
+ }
+ if (gUnknown_03007890->unk_05)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ if (gUnknown_03007880[i]->unk_34 & 0x8000 && gUnknown_03007880[i]->unk_4e & a0)
+ {
+ rfu_NI_stopReceivingData(i);
+ }
+ }
+ }
+ if (gUnknown_03007890->unk_06)
+ {
+ gUnknown_03007890->unk_06 &= ~a0;
+ for (i = 0; i < 4; i++)
+ {
+ if (gUnknown_03007870[i]->unk_0 == 0x8024 && a0 & gUnknown_03007870[i]->unk_3)
+ {
+ gUnknown_03007870[i]->unk_3 &= ~a0;
+ }
+ }
+ }
+}
+
+static void sub_800D434(void)
+{
+ u8 i;
+ u8 j;
+ u8 flags;
+
+ if (gUnknown_03004140.unk_18)
+ {
+ if (gUnknown_03007890->unk_04)
+ {
+ for (i = 0; i < 4; i ++)
+ {
+ if (gUnknown_03007880[i]->unk_0 & 0x8000)
+ {
+ flags = 0;
+ for (j = 0; j < 4; j++)
+ {
+ if ((gUnknown_03007880[i]->unk_1a >> j) & 1 && gUnknown_03007880[j]->unk_2 > gUnknown_03004140.unk_18)
+ {
+ flags |= (1 << j);
+ }
+ if (flags)
+ {
+ rfu_changeSendTarget(0x20, i, flags ^ gUnknown_03007880[i]->unk_1a);
+ }
+ }
+ }
+ }
+ }
+ if (gUnknown_03007890->unk_05)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ if (gUnknown_03007880[i]->unk_34 & 0x8000 && gUnknown_03007880[i]->unk_36 > gUnknown_03004140.unk_18)
+ {
+ rfu_NI_stopReceivingData(i);
+ }
+ }
+ }
+ }
+}
+
+void sub_800D52C(void (*func)(u16))
+{
+ gUnknown_03004140.unk_44 = func;
+ rfu_setMSCCallback(sub_800CEB0);
+}
+
+void sub_800D544(void (*func)(u8, u8))
+{
+ gUnknown_03004140.unk_40 = func;
+}
+
+u8 sub_800D550(u8 a0, u16 a1)
+{
+ u16 imeBak;
+ if (gUnknown_03004140.unk_09 && a0 == 0 && gUnknown_03004140.unk_30)
+ {
+ return 5;
+ }
+ imeBak = REG_IME;
+ REG_IME = 0;
+ gUnknown_03004140.unk_09 = a0;
+ gUnknown_03004140.unk_32 = a1;
+ REG_IME = imeBak;
+ return 0;
+}
+
+u8 sub_800D594(u16 a0)
+{
+ if (gUnknown_03007890->unk_04 | gUnknown_03007890->unk_05)
+ {
+ gUnknown_03004140.unk_14 = 6;
+ sub_800D30C(0xf3, 0x01);
+ return 6;
+ }
+ gUnknown_03004140.unk_18 = a0;
+ return 0;
+}
+
+u8 sub_800D5D0(u8 a0)
+{
+ if (gUnknown_03004140.unk_04 == 9 || gUnknown_03004140.unk_04 == 10 || gUnknown_03004140.unk_04 == 11)
+ {
+ gUnknown_03004140.unk_14 = 7;
+ sub_800D30C(0xf3, 0x01);
+ return 7;
+ }
+ if (a0)
+ {
+ gUnknown_03004140.unk_0b = 1;
+ }
+ else
+ {
+ gUnknown_03004140.unk_0b = 0;
+ }
+ return 0;
+}
+
+static void sub_800D610(void)
+{
+ if (gUnknown_03004140.unk_02)
+ {
+ gUnknown_03004140.unk_02 = 0;
+ sub_800D30C(0x45, 0x00);
+ }
+}
+
+void sub_800D630(void)
+{
+ if (gUnknown_03004140.unk_02 == 0)
+ {
+ sub_800D30C(0x45, 0x00);
+ }
+ else if (gUnknown_03004140.unk_02 == 1)
+ {
+ gUnknown_03004140.unk_02 = 2;
+ }
+}
+
+void sub_800D658(void)
+{
+ if (gUnknown_03004140.unk_07)
+ {
+ switch (gUnknown_03004140.unk_04)
+ {
+ case 5:
+ gUnknown_03004140.unk_07 = 3;
+ gUnknown_03004140.unk_04 = 9;
+ break;
+ case 6:
+ gUnknown_03004140.unk_07 = 2;
+ gUnknown_03004140.unk_1a = 1;
+ break;
+ case 7:
+ case 8:
+ gUnknown_03004140.unk_07 = 2;
+ break;
+ case 9:
+ case 10:
+ gUnknown_03004140.unk_1a = 40;
+ break;
+ case 11:
+ gUnknown_03004140.unk_1a = 40;
+ gUnknown_03004140.unk_04 = 10;
+ break;
+ }
+ }
+}
+
+// TODO: Is there a file boundary here?
+
+void sub_800D6C8(struct UnkRfuStruct_2_Sub_124 *ptr)
+{
+ int i;
+ int j;
+
+ for (i = 0; i < 32; i++)
+ {
+ for (j = 0; j < 70; j++)
+ {
+ ptr->unk_00[i][j] = 0;
+ }
+ }
+ ptr->unk_8c1 = 0;
+ ptr->unk_8c0 = 0;
+ ptr->unk_8c2 = 0;
+ ptr->unk_8c3 = 0;
+}
+
+void sub_800D724(struct UnkRfuStruct_2_Sub_9e8 *ptr)
+{
+ int i;
+ int j;
+
+ for (i = 0; i < 40; i++)
+ {
+ for (j = 0; j < 14; j++)
+ {
+ ptr->unk_00[i][j] = 0;
+ }
+ }
+ ptr->unk_231 = 0;
+ ptr->unk_230 = 0;
+ ptr->unk_232 = 0;
+ ptr->unk_233 = 0;
+}
+
+void sub_800D780(struct UnkRfuStruct_Sub_Unused *ptr)
+{
+ int i;
+ int j;
+
+ for (i = 0; i < 2; i++)
+ {
+ for (j = 0; j < 256; j++)
+ {
+ ptr->unk_00[i][j] = 0;
+ }
+ }
+ ptr->unk_201 = 0;
+ ptr->unk_200 = 0;
+ ptr->unk_202 = 0;
+ ptr->unk_203 = 0;
+}
+
+void sub_800D7D8(struct UnkRfuStruct_2_Sub_124 *q1, u8 *q2)
+{
+ int i;
+ u16 imeBak;
+ u8 count;
+
+ if (q1->unk_8c2 < 32)
+ {
+ imeBak = REG_IME;
+ REG_IME = 0;
+ count = 0;
+ for (i = 0; i < 70; i += 14)
+ {
+ if (q2[i] == 0 && q2[i + 1] == 0)
+ {
+ count++;
+ }
+ }
+ if (count != 5)
+ {
+ for (i = 0; i < 70; i++)
+ {
+ q1->unk_00[q1->unk_8c0][i] = q2[i];
+ }
+ q1->unk_8c0++;
+ q1->unk_8c0 %= 32;
+ q1->unk_8c2++;
+ for (i = 0; i < 70; i++)
+ {
+ q2[i] = 0;
+ }
+ }
+ REG_IME = imeBak;
+ }
+ else
+ {
+ q1->unk_8c3 = 1;
+ }
+}
+
+void sub_800D888(struct UnkRfuStruct_2_Sub_9e8 *q1, u8 *q2)
+{
+ int i;
+ u16 imeBak;
+
+ if (q1->unk_232 < 40)
+ {
+ imeBak = REG_IME;
+ REG_IME = 0;
+ for (i = 0; i < 14; i++)
+ {
+ if (q2[i] != 0)
+ {
+ break;
+ }
+ }
+ if (i != 14)
+ {
+ for (i = 0; i < 14; i++)
+ {
+ q1->unk_00[q1->unk_230][i] = q2[i];
+ }
+ q1->unk_230++;
+ q1->unk_230 %= 40;
+ q1->unk_232++;
+ for (i = 0; i < 14; i++)
+ {
+ q2[i] = 0;
+ }
+ }
+ REG_IME = imeBak;
+ }
+ else
+ {
+ q1->unk_233 = 1;
+ }
+}
+
+bool8 sub_800D934(struct UnkRfuStruct_2_Sub_124 *q1, u8 *q2)
+{
+ u16 imeBak;
+ int i;
+
+ imeBak = REG_IME;
+ REG_IME = 0;
+ if (q1->unk_8c0 == q1->unk_8c1 || q1->unk_8c3 != 0)
+ {
+ for (i = 0; i < 70; i++)
+ {
+ q2[i] = 0;
+ }
+ REG_IME = imeBak;
+ return FALSE;
+ }
+ for (i = 0; i < 70; i++)
+ {
+ q2[i] = q1->unk_00[q1->unk_8c1][i];
+ }
+ q1->unk_8c1++;
+ q1->unk_8c1 %= 32;
+ q1->unk_8c2--;
+ REG_IME = imeBak;
+ return TRUE;
+}
+
+bool8 sub_800D9DC(struct UnkRfuStruct_2_Sub_9e8 *q1, u8 *q2)
+{
+ int i;
+ u16 imeBak;
+
+ if (q1->unk_230 == q1->unk_231 || q1->unk_233 != 0)
+ {
+ return FALSE;
+ }
+ imeBak = REG_IME;
+ REG_IME = 0;
+ for (i = 0; i < 14; i++)
+ {
+ q2[i] = q1->unk_00[q1->unk_231][i];
+ }
+ q1->unk_231++;
+ q1->unk_231 %= 40;
+ q1->unk_232--;
+ REG_IME = imeBak;
+ return TRUE;
+}
+
+void sub_800DA68(struct UnkRfuStruct_2_Sub_c1c *q1, const u8 *q2)
+{
+ int i;
+
+ if (q2[1] == 0)
+ {
+ sub_800DAC8(q1, NULL);
+ }
+ else
+ {
+ for (i = 0; i < 14; i++)
+ {
+ q1->unk_00[q1->unk_1c][i] = q2[i];
+ }
+ q1->unk_1c++;
+ q1->unk_1c %= 2;
+ if (q1->unk_1e < 2)
+ {
+ q1->unk_1e++;
+ }
+ else
+ {
+ q1->unk_1d = q1->unk_1c;
+ }
+ }
+}
+
+static bool8 sub_800DAC8(struct UnkRfuStruct_2_Sub_c1c *q1, u8 *q2)
+{
+ int i;
+
+ if (q1->unk_1e == 0)
+ {
+ return FALSE;
+ }
+ if (q2 != NULL)
+ {
+ for (i = 0; i < 14; i++)
+ {
+ q2[i] = q1->unk_00[q1->unk_1d][i];
+ }
+ }
+ q1->unk_1d++;
+ q1->unk_1d %= 2;
+ q1->unk_1e--;
+ return TRUE;
+}
+
+void sub_800DB18(struct UnkRfuStruct_Sub_Unused *q1, u8 *q2)
+{
+ int i;
+
+ if (q1->unk_202 < 2)
+ {
+ for (i = 0; i < 256; i++)
+ {
+ q1->unk_00[q1->unk_200][i] = q2[i];
+ }
+ q1->unk_200++;
+ q1->unk_200 %= 2;
+ q1->unk_202++;
+ }
+ else
+ {
+ q1->unk_203 = 1;
+ }
+}
+
+bool8 sub_800DB84(struct UnkRfuStruct_Sub_Unused *q1, u8 *q2)
+{
+ int i;
+
+ if (q1->unk_200 == q1->unk_201 || q1->unk_203)
+ {
+ return FALSE;
+ }
+ for (i = 0; i < 256; i++)
+ {
+ q2[i] = q1->unk_00[q1->unk_201][i];
+ }
+ q1->unk_201++;
+ q1->unk_201 %= 2;
+ q1->unk_202--;
+ return TRUE;
+}
+
+void sub_800DBF8(u8 *q1, u8 mode)
+{
+ int i;
+ u8 rval;
+ u16 r5 = 0;
+ switch (mode)
+ {
+ case 0:
+ for (i = 0; i < 200; i++)
+ {
+ q1[i] = i + 1;
+ r5 += i + 1;
+ }
+ *((u16 *)(q1 + i)) = r5;
+ break;
+ case 1:
+ for (i = 0; i < 100; i++)
+ {
+ q1[i] = i + 1;
+ r5 += i + 1;
+ }
+ *((u16 *)(q1 + 200)) = r5;
+ break;
+ case 2:
+ for (i = 0; i < 200; i++)
+ {
+ rval = Random();
+ q1[i] = rval;
+ r5 += rval;
+ }
+ *((u16 *)(q1 + i)) = r5;
+ break;
+ case 3:
+ for (i = 0; i < 200; i++)
+ {
+ q1[i] = i + 1 + gUnknown_03000D74;
+ r5 += (i + 1 + gUnknown_03000D74) & 0xFF;
+ }
+ *((u16 *)(q1 + i)) = r5;
+ gUnknown_03000D74++;
+ break;
+ }
+}
+
+void PkmnStrToASCII(u8 *q1, const u8 *q2)
+{
+ int i;
+
+ for (i = 0; q2[i] != EOS; i++)
+ {
+ q1[i] = sWireless_RSEtoASCIITable[q2[i]];
+ }
+ q1[i] = 0;
+}
+
+void ASCIIToPkmnStr(u8 *q1, const u8 *q2)
+{
+ int i;
+
+ for (i = 0; q2[i] != 0; i++)
+ {
+ q1[i] = sWireless_ASCIItoRSETable[q2[i]];
+ }
+ q1[i] = EOS;
+}
+
+#ifdef NONMATCHING
+u8 sub_800DD1C(u8 maxFlags)
+{
+ u8 flagCount = 0;
+ u8 flags = gUnknown_03007890->unk_02;
+ u8 i;
+
+ if (gUnknown_03007890->unk_00 == 1)
+ {
+ i = 0;
+ for (i = 0; i < 4; flags >>= 1, i++)
+ {
+ if (flags & 1)
+ {
+ if (maxFlags == flagCount + 1)
+ {
+ return gUnknown_03007890->unk_0a[i];
+ }
+ flagCount++;
+ }
+ }
+ }
+ else
+ {
+ for (i = 0; i < 4; flags >>= 1, i++)
+ {
+ if (flags & 1)
+ {
+ return gUnknown_03007890->unk_0a[i];
+ }
+ }
+ }
+ return 0;
+}
+#else
+NAKED u8 sub_800DD1C(u8 maxFlags)
+{
+ asm_unified("\tpush {r4-r7,lr}\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r5, r0, 24\n"
+ "\tmovs r6, 0\n"
+ "\tldr r0, =gUnknown_03007890\n"
+ "\tldr r4, [r0]\n"
+ "\tldrb r2, [r4, 0x2]\n"
+ "\tldrb r1, [r4]\n"
+ "\tadds r7, r0, 0\n"
+ "\tcmp r1, 0x1\n"
+ "\tbne _0800DD72\n"
+ "\tmovs r3, 0\n"
+ "\tands r1, r2\n"
+ "\tcmp r1, 0\n"
+ "\tbeq _0800DD4E\n"
+ "\tcmp r5, 0x1\n"
+ "\tbne _0800DD48\n"
+ "\tldrb r0, [r4, 0xA]\n"
+ "\tb _0800DD8C\n"
+ "\t.pool\n"
+ "_0800DD48:\n"
+ "\tadds r0, r6, 0x1\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r6, r0, 24\n"
+ "_0800DD4E:\n"
+ "\tlsrs r2, 1\n"
+ "\tadds r0, r3, 0x1\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r3, r0, 24\n"
+ "\tcmp r3, 0x3\n"
+ "\tbhi _0800DD8A\n"
+ "\tmovs r0, 0x1\n"
+ "\tands r0, r2\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _0800DD4E\n"
+ "\tadds r0, r6, 0x1\n"
+ "\tcmp r5, r0\n"
+ "\tbne _0800DD48\n"
+ "_0800DD68:\n"
+ "\tldr r0, [r7]\n"
+ "\tadds r0, 0xA\n"
+ "\tadds r0, r3\n"
+ "\tldrb r0, [r0]\n"
+ "\tb _0800DD8C\n"
+ "_0800DD72:\n"
+ "\tmovs r3, 0\n"
+ "\tmovs r1, 0x1\n"
+ "_0800DD76:\n"
+ "\tadds r0, r2, 0\n"
+ "\tands r0, r1\n"
+ "\tcmp r0, 0\n"
+ "\tbne _0800DD68\n"
+ "\tlsrs r2, 1\n"
+ "\tadds r0, r3, 0x1\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r3, r0, 24\n"
+ "\tcmp r3, 0x3\n"
+ "\tbls _0800DD76\n"
+ "_0800DD8A:\n"
+ "\tmovs r0, 0\n"
+ "_0800DD8C:\n"
+ "\tpop {r4-r7}\n"
+ "\tpop {r1}\n"
+ "\tbx r1");
+}
+#endif
+
+void sub_800DD94(struct UnkLinkRfuStruct_02022B14 *data, u8 r9, bool32 r2, int r3)
+{
+ int i;
+
+ for (i = 0; i < 2; i++)
+ {
+ data->playerTrainerId[i] = gSaveBlock2Ptr->playerTrainerId[i];
+ }
+ for (i = 0; i < 4; i++)
+ {
+ data->unk_04[i] = r3;
+ r3 >>= 8;
+ }
+ data->playerGender = gSaveBlock2Ptr->playerGender;
+ data->unk_0a_0 = r9;
+ data->unk_0a_7 = r2;
+ data->unk_00_0 = 2;
+ data->unk_01_2 = 3;
+ data->unk_00_4 = 0;
+ data->unk_00_5 = 0;
+ data->unk_00_6 = 0;
+ data->unk_00_7 = FlagGet(FLAG_0x87F);
+ data->unk_01_0 = IsNationalPokedexEnabled();
+ data->unk_01_1 = FlagGet(FLAG_SYS_GAME_CLEAR);
+}
+
+bool8 sub_800DE7C(struct UnkLinkRfuStruct_02022B14 *buff1, u8 *buff2, u8 idx)
+{
+ bool8 retVal;
+
+ if (gUnknown_03004140.unk_06 == 1)
+ {
+ retVal = TRUE;
+ if (sub_8010454(gUnknown_03007890->unk_14[idx].unk_04) && ((gUnknown_03007890->unk_07 >> idx) & 1))
+ {
+ memcpy(buff1, &gUnknown_03007890->unk_14[idx].unk_06, sizeof(gUnknown_03007890->unk_14[idx].unk_06));
+ memcpy(buff2, gUnknown_03007890->unk_14[idx].unk_15, sizeof(gUnknown_03007890->unk_14[idx].unk_15));
+ }
+ else
+ {
+ memset(buff1, 0, sizeof(gUnknown_03007890->unk_14[idx].unk_06));
+ memset(buff2, 0, sizeof(gUnknown_03007890->unk_14[idx].unk_15));
+ }
+ }
+ else
+ {
+ retVal = FALSE;
+ if (sub_8010454(gUnknown_03007890->unk_14[idx].unk_04))
+ {
+ memcpy(buff1, &gUnknown_03007890->unk_14[idx].unk_06, sizeof(gUnknown_03007890->unk_14[idx].unk_06));
+ memcpy(buff2, gUnknown_03007890->unk_14[idx].unk_15, sizeof(gUnknown_03007890->unk_14[idx].unk_15));
+ }
+ else
+ {
+ memset(buff1, 0, sizeof(gUnknown_03007890->unk_14[idx].unk_06));
+ memset(buff2, 0, sizeof(gUnknown_03007890->unk_14[idx].unk_15));
+ }
+ }
+ return retVal;
+}
+
+bool8 sub_800DF34(struct UnkLinkRfuStruct_02022B14 *buff1, u8 *buff2, u8 idx)
+{
+ bool8 retVal = FALSE;
+ if (gUnknown_03007890->unk_14[idx].unk_04 == 0x7F7D)
+ {
+ *buff1 = gUnknown_03007890->unk_14[idx].unk_06;
+ memcpy(buff2, gUnknown_03007890->unk_14[idx].unk_15, 8);
+ retVal = TRUE;
+ }
+ else
+ {
+ *buff1 = (struct UnkLinkRfuStruct_02022B14){};
+ memset(buff2, 0, 8);
+ }
+ return retVal;
+}
+
+void sub_800DF90(struct UnkLinkRfuStruct_02022B14 *buff1, u8 *buff2)
+{
+ *buff1 = gUnknown_02022B14;
+ memcpy(buff2, gUnknown_02022B22, 8);
+}
+
+void CreateWirelessStatusIndicatorSprite(u8 x, u8 y)
+{
+ u8 sprId;
+
+ if (x == 0 && y == 0)
+ {
+ x = 0xE7;
+ y = 0x08;
+ }
+ if (gUnknown_03007890->unk_00 == 1)
+ {
+ sprId = CreateSprite(&sWirelessStatusIndicatorSpriteTemplate, x, y, 0);
+ gSprites[sprId].data[7] = 0x1234;
+ gSprites[sprId].data[6] = GetSpriteTileStartByTag(sWirelessStatusIndicatorSpriteSheet.tag);
+ gSprites[sprId].invisible = TRUE;
+ gWirelessStatusIndicatorSpriteId = sprId;
+ }
+ else
+ {
+ gWirelessStatusIndicatorSpriteId = CreateSprite(&sWirelessStatusIndicatorSpriteTemplate, x, y, 0);
+ gSprites[gWirelessStatusIndicatorSpriteId].data[7] = 0x1234;
+ gSprites[gWirelessStatusIndicatorSpriteId].data[6] = GetSpriteTileStartByTag(sWirelessStatusIndicatorSpriteSheet.tag);
+ gSprites[gWirelessStatusIndicatorSpriteId].invisible = TRUE;
+ }
+}
+
+void sub_800E084(void)
+{
+ if (gSprites[gWirelessStatusIndicatorSpriteId].data[7] == 0x1234)
+ {
+ gSprites[gWirelessStatusIndicatorSpriteId].data[7] = 0;
+ DestroySprite(&gSprites[gWirelessStatusIndicatorSpriteId]);
+ gMain.oamBuffer[125] = gDummyOamData;
+ CpuCopy16(&gDummyOamData, (struct OamData *)OAM + 125, sizeof(struct OamData));
+ }
+}
+
+void sub_800E0E8(void)
+{
+ if (GetSpriteTileStartByTag(sWirelessStatusIndicatorSpriteSheet.tag) == 0xFFFF)
+ {
+ LoadCompressedObjectPic(&sWirelessStatusIndicatorSpriteSheet);
+ }
+ LoadSpritePalette(&sWirelessStatusIndicatorSpritePalette);
+ gWirelessStatusIndicatorSpriteId = 0xFF;
+}
+
+u8 sub_800E124(void)
+{
+ u8 i;
+ u8 flags = gUnknown_03007890->unk_02;
+ for (i = 0; i < 4; i++)
+ {
+ if (flags & 1)
+ {
+ return gUnknown_03007890->unk_0a[i];
+ }
+ flags >>= 1;
+ }
+ return 0;
+}
+
+void sub_800E15C(struct Sprite *sprite, int signalStrengthAnimNum)
+{
+ if (sprite->data[2] != signalStrengthAnimNum)
+ {
+ sprite->data[2] = signalStrengthAnimNum;
+ sprite->data[3] = 0;
+ sprite->data[4] = 0;
+ }
+}
+
+void sub_800E174(void)
+{
+ if (gWirelessStatusIndicatorSpriteId != 0xFF && gSprites[gWirelessStatusIndicatorSpriteId].data[7] == 0x1234)
+ {
+ struct Sprite *sprite = &gSprites[gWirelessStatusIndicatorSpriteId];
+ u8 signalStrength = 255;
+ u8 i = 0;
+ if (gUnknown_03007890->unk_00 == 1)
+ {
+ for (i = 0; i < GetLinkPlayerCount() - 1; i++)
+ {
+ if (signalStrength >= sub_800DD1C(i + 1))
+ {
+ signalStrength = sub_800DD1C(i + 1);
+ }
+ }
+ }
+ else
+ {
+ signalStrength = sub_800E124();
+ }
+ if (sub_8012224() == TRUE)
+ {
+ sprite->data[0] = 4;
+ }
+ else if (signalStrength < 25)
+ {
+ sprite->data[0] = 3;
+ }
+ else if (signalStrength >= 25 && signalStrength < 127)
+ {
+ sprite->data[0] = 2;
+ }
+ else if (signalStrength >= 127 && signalStrength < 229)
+ {
+ sprite->data[0] = 1;
+ }
+ else if (signalStrength >= 229)
+ {
+ sprite->data[0] = 0;
+ }
+ if (sprite->data[0] != sprite->data[1])
+ {
+ sub_800E15C(sprite, sprite->data[0]);
+ sprite->data[1] = sprite->data[0];
+ }
+ if (sprite->anims[sprite->data[2]][sprite->data[4]].frame.duration < sprite->data[3])
+ {
+ sprite->data[4]++;
+ sprite->data[3] = 0;
+ if (sprite->anims[sprite->data[2]][sprite->data[4]].type == -2)
+ {
+ sprite->data[4] = 0;
+ }
+ }
+ else
+ {
+ sprite->data[3]++;
+ }
+ gMain.oamBuffer[125] = sWirelessStatusIndicatorOamData;
+ gMain.oamBuffer[125].x = sprite->pos1.x + sprite->centerToCornerVecX;
+ gMain.oamBuffer[125].y = sprite->pos1.y + sprite->centerToCornerVecY;
+ gMain.oamBuffer[125].paletteNum = sprite->oam.paletteNum;
+ gMain.oamBuffer[125].tileNum = sprite->data[6] + sprite->anims[sprite->data[2]][sprite->data[4]].frame.imageValue;
+ CpuCopy16(gMain.oamBuffer + 125, (struct OamData *)OAM + 125, sizeof(struct OamData));
+ if (sub_8011A74() == 1)
+ {
+ sub_800E084();
+ }
+ }
+}
+
+void sub_800E378(struct UnkSaveSubstruct_3b98 *dest, u32 trainerId, const u8 *name)
+{
+ dest->trainerId = trainerId;
+ StringCopy(dest->trainerName, name);
+}
+
+bool32 sub_800E388(const u8 *name)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ {
+ if (name[i] != 0)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void sub_800E3A8(void)
+{
+ if (gWirelessCommType != 0)
+ {
+ int i;
+ int j;
+ int cnt;
+ int sp0[5];
+ struct UnkSaveSubstruct_3b98 *sp14 = calloc(20, sizeof(struct UnkSaveSubstruct_3b98));
+ for (i = 0; i < GetLinkPlayerCount(); i++)
+ {
+ sp0[i] = -1;
+ for (j = 0; j < 20; j++)
+ {
+ if ((u16)gLinkPlayers[i].trainerId == gSaveBlock1Ptr->unk_3B98[j].trainerId && StringCompare(gLinkPlayers[i].name, gSaveBlock1Ptr->unk_3B98[j].trainerName) == 0)
+ {
+ sp0[i] = j;
+ }
+ }
+ }
+ cnt = 0;
+ for (i = 0; i < GetLinkPlayerCount(); i++)
+ {
+ if (i != GetMultiplayerId() && gLinkPlayers[i].language != LANGUAGE_JAPANESE)
+ {
+ sub_800E378(&sp14[cnt], (u16)gLinkPlayers[i].trainerId, gLinkPlayers[i].name);
+ if (sp0[i] >= 0)
+ {
+ memset(gSaveBlock1Ptr->unk_3B98[sp0[i]].trainerName, 0, 8);
+ }
+ cnt++;
+ }
+ }
+ for (i = 0; i < 20; i++)
+ {
+ if (sub_800E388(gSaveBlock1Ptr->unk_3B98[i].trainerName))
+ {
+ sub_800E378(&sp14[cnt], gSaveBlock1Ptr->unk_3B98[i].trainerId, gSaveBlock1Ptr->unk_3B98[i].trainerName);
+ if (++cnt >= 20)
+ {
+ break;
+ }
+ }
+ }
+ memcpy(gSaveBlock1Ptr->unk_3B98, sp14, 20 * sizeof(struct UnkSaveSubstruct_3b98));
+ free(sp14);
+ }
+}
+
+bool32 sub_800E540(u16 id, u8 *name)
+{
+ int i;
+
+ for (i = 0; i < 20; i++)
+ {
+ if (StringCompare(gSaveBlock1Ptr->unk_3B98[i].trainerName, name) == 0 && gSaveBlock1Ptr->unk_3B98[i].trainerId == id)
+ {
+ return TRUE;
+ }
+ if (!sub_800E388(gSaveBlock1Ptr->unk_3B98[i].trainerName))
+ {
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+
+void sub_800E5AC(void)
+{
+ int i;
+
+ for (i = 0; i < 20; i++)
+ {
+ gSaveBlock1Ptr->unk_3B98[i].trainerId = 0;
+ CpuFill16(0, gSaveBlock1Ptr->unk_3B98[i].trainerName, 8);
+ }
+}
+
+void nullsub_5(void *unused_0, u8 unused_1, u8 unused_2)
+{
+ // debug?
+}
+
+void nullsub_13(u8 unused_0, u8 unused_1, u8 unused_2, u8 unused_3)
+{
+
+}
+
+void sub_800E604(void)
+{
+ int i;
+ u8 unk_ee_bak = gUnknown_03005000.unk_ee;
+ CpuFill16(0, &gUnknown_03005000, sizeof gUnknown_03005000);
+ gUnknown_03005000.unk_ee = unk_ee_bak;
+ gUnknown_03005000.unk_0c = 0xFF;
+ if (gUnknown_03005000.unk_ee != 4)
+ {
+ gUnknown_03005000.unk_ee = 0;
+ }
+ for (i = 0; i < 5; i++)
+ {
+ sub_800FCC4(gUnknown_03005000.unk_80 + i);
+ }
+ sub_800FCC4(&gUnknown_03005000.unk_6c);
+ sub_800D6C8(&gUnknown_03005000.unk_124);
+ sub_800D724(&gUnknown_03005000.unk_9e8);
+ CpuFill16(0, gSendCmd, sizeof gSendCmd);
+ CpuFill16(0, gRecvCmds, sizeof gRecvCmds);
+ CpuFill16(0, gLinkPlayers, sizeof gLinkPlayers)
+}
+
+void sub_800E6D0(void)
+{
+ IntrFunc serialIntr = gIntrTable[1];
+ IntrFunc timerIntr = gIntrTable[2];
+ sub_800E700();
+ rfu_REQ_stopMode();
+ rfu_waitREQComplete();
+ REG_IME = 0;
+ gIntrTable[1] = serialIntr;
+ gIntrTable[2] = timerIntr;
+ REG_IME = INTR_FLAG_VBLANK;
+}
+
+void sub_800E700(void)
+{
+ if (!rfu_initializeAPI(gUnknown_03004140.unk_50, sizeof gUnknown_03004140.unk_50, gIntrTable + 1, TRUE))
+ {
+ gLinkType = 0;
+ sub_800AAF4();
+ sub_80111B0(0);
+ sub_800E604();
+ rfu_setTimerInterrupt(3, gIntrTable + 2);
+ }
+}
+
+void sub_800E748(u8 taskId)
+{
+ sub_8010750();
+ switch (gUnknown_03005000.unk_04)
+ {
+ case 0:
+ sub_800BFCC(&gUnknown_02022B2C);
+ gUnknown_03005000.unk_04 = 1;
+ gTasks[taskId].data[1] = 1;
+ break;
+ case 1:
+ break;
+ case 2:
+ sub_800C054(gUnknown_03005000.unk_0c, 0, 240, gUnknown_082ED6E0);
+ gUnknown_03005000.unk_04 = 3;
+ gTasks[taskId].data[1] = 6;
+ break;
+ case 3:
+ break;
+ case 4:
+ sub_800C27C(FALSE);
+ gUnknown_03005000.unk_04 = 5;
+ break;
+ case 5:
+ break;
+ case 18:
+ gUnknown_03005000.unk_cdb = 0;
+ sub_800D52C(sub_800EDBC);
+ sub_800EAB4();
+ sub_800EAFC();
+ gUnknown_03005000.unk_04 = 20;
+ gTasks[taskId].data[1] = 8;
+ CreateTask(sub_801084C, 5);
+ DestroyTask(taskId);
+ break;
+ }
+}
+
+u8 sub_800E87C(u8 idx)
+{
+ return gUnknown_082ED6A5[idx];
+}
+
+void sub_800E88C(int r2, int r5)
+{
+ u8 i;
+ u8 r4 = 1;
+ int r1 = r2;
+ int r6 = 0;
+ if (r5 == -1)
+ {
+ for (i = 0; i < 4; r2 >>= 1, i++)
+ {
+ if (r2 & 1)
+ {
+ gUnknown_03005000.unk_cde[i] = r4;
+ r4++;
+ }
+ }
+ }
+ else
+ {
+ for (i = 0; i < 4; r1 >>= 1, i++)
+ {
+ if (!(r1 & 1))
+ {
+ gUnknown_03005000.unk_cde[i] = 0;
+ }
+ }
+ for (r4 = 4; r4 != 0; r4--)
+ {
+ for (i = 0; i < 4 && gUnknown_03005000.unk_cde[i] != r4; i++);
+ if (i == 4)
+ {
+ r6 = r4;
+ }
+ }
+ for (r5 &= ~r2, i = 0; i < 4; r5 >>= 1, i++)
+ {
+ if (r5 & 1)
+ {
+ gUnknown_03005000.unk_cde[i] = r6++;
+ }
+ }
+ }
+}
+
+void sub_800E94C(u8 taskId)
+{
+ switch (gUnknown_03005000.unk_04)
+ {
+ case 0:
+ sub_800BFCC(&gUnknown_082ED608);
+ gUnknown_03005000.unk_04 = 1;
+ gTasks[taskId].data[1] = 1;
+ break;
+ case 1:
+ break;
+ case 6:
+ sub_800C054(gUnknown_03005000.unk_0c, 0, 0xf0, gUnknown_082ED6E0);
+ gUnknown_03005000.unk_04 = 7;
+ gTasks[taskId].data[1] = 7;
+ break;
+ case 7:
+ break;
+ case 9:
+ gTasks[taskId].data[1] = 10;
+ break;
+ case 11:
+ switch (sub_80107A0())
+ {
+ case 5:
+ gUnknown_03005000.unk_04 = 12;
+ break;
+ case 6:
+ case 9:
+ sub_800D630();
+ gUnknown_03005000.unk_ce4 = 2;
+ DestroyTask(taskId);
+ break;
+ }
+ break;
+ case 12:
+ {
+ u8 r5 = 1 << gUnknown_03005000.unk_c3e;
+ rfu_clearSlot(12, gUnknown_03005000.unk_c3e);
+ rfu_setRecvBuffer(16, gUnknown_03005000.unk_c3e, gUnknown_03005000.unk_c3f, 70);
+ rfu_UNI_setSendData(r5, gUnknown_03005000.unk_4c, 14);
+ gTasks[taskId].data[1] = 8;
+ DestroyTask(taskId);
+ if (gUnknown_02022B44.unk_0f == 0)
+ {
+ sub_801227C();
+ gUnknown_02022B44.unk_0f++;
+ }
+ CreateTask(sub_801084C, 5);
+ break;
+ }
+ }
+}
+
+static void sub_800EAB4(void)
+{
+ u8 i;
+ u8 r5 = gUnknown_03004140.unk_00;
+ for (i = 0; i < 4; i++)
+ {
+ if (r5 & 1)
+ {
+ rfu_setRecvBuffer(16, i, gUnknown_03005000.unk_14[i], 14);
+ rfu_clearSlot(3, i);
+ }
+ r5 >>= 1;
+ }
+}
+
+static void sub_800EAFC(void)
+{
+ u8 r5 = gUnknown_03004140.unk_00;
+ rfu_UNI_setSendData(r5, gUnknown_03005000.unk_c87, 70);
+ gUnknown_03005000.unk_cda = sub_800E87C(r5);
+ gUnknown_03005000.unk_ce2 = r5;
+ sub_800E88C(r5, -1);
+ gUnknown_03005000.unk_0c = 1;
+}
+
+void sub_800EB44(u8 taskId)
+{
+ if (sub_800F7DC()->unk_0a_0 == 0x54 && sub_8011A74() == 4)
+ {
+ rfu_REQ_disconnect(gUnknown_03004140.unk_00);
+ rfu_waitREQComplete();
+ sub_8011A64(0, 0);
+ }
+ switch (gUnknown_03005000.unk_04)
+ {
+ case 0:
+ sub_800BFCC(&gUnknown_02022B2C);
+ gUnknown_03005000.unk_04 = 1;
+ gTasks[taskId].data[1] = 1;
+ break;
+ case 1:
+ break;
+ case 17:
+ sub_800C054(2, 0, 240, gUnknown_082ED6E0);
+ sub_800D52C(sub_800ED34);
+ gUnknown_03005000.unk_04 = 18;
+ break;
+ case 18:
+ break;
+ case 13:
+ if (rfu_UNI_setSendData(1 << gUnknown_03005000.unk_c3e, gUnknown_03005000.unk_4c, 14) == 0)
+ {
+ gUnknown_03005000.unk_0c = 0;
+ DestroyTask(taskId);
+ if (gTasks[taskId].data[7])
+ {
+ CreateTask(sub_8010D0C, 1);
+ }
+ else
+ {
+ CreateTask(sub_801084C, 5);
+ }
+ }
+ break;
+ case 14:
+ sub_800C27C(0);
+ gUnknown_03005000.unk_04 = 15;
+ break;
+ case 15:
+ break;
+ case 16:
+ gUnknown_03005000.unk_cdb = 0;
+ sub_800D52C(sub_800EDBC);
+ sub_8011068(1);
+ sub_800EAB4();
+ sub_800EAFC();
+ gUnknown_03005000.unk_04 = 20;
+ gTasks[taskId].data[1] = 8;
+ gUnknown_03005000.unk_0c = 1;
+ CreateTask(sub_801084C, 5);
+ gUnknown_03005000.unk_ce8 = 1;
+ DestroyTask(taskId);
+ break;
+ }
+}
+
+void sub_800ED10(void)
+{
+ sub_800C054(1, 0, 240, gUnknown_082ED6E0);
+}
+
+void sub_800ED28(void)
+{
+ sub_800C27C(FALSE);
+}
+
+void sub_800ED34(u16 unused)
+{
+ int i;
+
+ for (i = 0; i < 14; i++)
+ {
+ gUnknown_03005000.unk_4c[i] = 0;
+ }
+ rfu_REQ_recvData();
+ rfu_waitREQComplete();
+ if (gUnknown_03007870[gUnknown_03005000.unk_c3e]->unk_12)
+ {
+ gUnknown_03005000.unk_cd0++;
+ sub_800D7D8(&gUnknown_03005000.unk_124, gUnknown_03005000.unk_c3f);
+ gUnknown_02022B44.unk_06++;
+ sub_800F048();
+ rfu_UNI_readySendData(gUnknown_03005000.unk_c3e);
+ rfu_UNI_clearRecvNewDataFlag(gUnknown_03005000.unk_c3e);
+ }
+ rfu_REQ_sendData_wrapper(1);
+}
+
+static void sub_800EDBC(u16 unused)
+{
+ gUnknown_03005000.unk_cdb = 1;
+}
+
+void sub_800EDD4(void)
+{
+ u8 i;
+
+ sub_800C048();
+ if (gUnknown_03005000.unk_0c == 1)
+ {
+ if (FuncIsActiveTask(sub_800E748) == TRUE)
+ {
+ DestroyTask(gUnknown_03005000.unk_67);
+ sub_800E604();
+ }
+ }
+ else if (gUnknown_03005000.unk_0c == 0)
+ {
+ if (FuncIsActiveTask(sub_800E94C) == TRUE)
+ {
+ DestroyTask(gUnknown_03005000.unk_67);
+ sub_800E604();
+ }
+ }
+ else if (gUnknown_03005000.unk_0c == 2)
+ {
+ if (FuncIsActiveTask(sub_800EB44) == TRUE)
+ {
+ DestroyTask(gUnknown_03005000.unk_67);
+ sub_800E604();
+ }
+ }
+ for (i = 0; i < 3; i++)
+ {
+ if (FuncIsActiveTask(gUnknown_082ED7E0[i]) == TRUE)
+ {
+ DestroyTask(FindTaskIdByFunc(gUnknown_082ED7E0[i]));
+ }
+ }
+}
+
+void sub_800EE78(void)
+{
+ gUnknown_03005000.unk_67 = CreateTask(sub_800E748, 1);
+}
+
+bool8 sub_800EE94(void)
+{
+ if (gUnknown_03005000.unk_04 == 7 && gUnknown_03005000.unk_ccd)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_800EEBC(void)
+{
+ if (gUnknown_03005000.unk_04 == 7 && !sub_800C12C(gUnknown_03007890->unk_14[gUnknown_03005000.unk_c3d].unk_00, 240))
+ {
+ gUnknown_03005000.unk_04 = 9;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void sub_800EF00(void)
+{
+ gUnknown_03005000.unk_67 = CreateTask(sub_800E94C, 1);
+}
+
+bool8 sub_800EF1C(void)
+{
+ if (gUnknown_03004140.unk_00)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void sub_800EF38(void)
+{
+ gUnknown_03005000.unk_04 = 4;
+ gUnknown_03005000.unk_ce7 = gUnknown_03004140.unk_00;
+}
+
+bool8 sub_800EF58(bool32 a0)
+{
+ if (gUnknown_03005000.unk_04 == 17 || a0)
+ {
+ gUnknown_03005000.unk_04 = 18;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void sub_800EF7C(void)
+{
+ gUnknown_03005000.unk_04 = 14;
+}
+
+void sub_800EF88(u8 a0)
+{
+ u8 i;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (a0 & 1)
+ {
+ rfu_UNI_readySendData(i);
+ break;
+ }
+ a0 >>= 1;
+ }
+}
+
+#ifdef NONMATCHING
+// FIXME: gUnknown_03005000.unk_c87 should be in r5
+// FIXME: gRecvCmds should be in r6 and r7
+void sub_800EFB0(void)
+{
+ int i, j;
+ for (i = 0; i < 5; i++)
+ {
+ for (j = 0; j < 7; j++)
+ {
+ gUnknown_03005000.unk_c87[i][j][1] = gRecvCmds[i][j] >> 8;
+ gUnknown_03005000.unk_c87[i][j][0] = gRecvCmds[i][j];
+ }
+ }
+ CpuFill16(0, gRecvCmds, sizeof gRecvCmds);
+}
+#else
+NAKED void sub_800EFB0(void)
+{
+ asm_unified("\tpush {r4-r7,lr}\n"
+ "\tsub sp, 0x4\n"
+ "\tmovs r2, 0\n"
+ "\tldr r7, =gRecvCmds\n"
+ "\tldr r0, =gUnknown_03005000\n"
+ "\tadds r6, r7, 0\n"
+ "\tldr r1, =0x00000c87\n"
+ "\tadds r5, r0, r1\n"
+ "_0800EFC0:\n"
+ "\tmovs r3, 0\n"
+ "\tlsls r0, r2, 3\n"
+ "\tlsls r1, r2, 4\n"
+ "\tadds r4, r2, 0x1\n"
+ "\tsubs r0, r2\n"
+ "\tlsls r0, 1\n"
+ "\tadds r2, r0, r5\n"
+ "\tadds r1, r6\n"
+ "_0800EFD0:\n"
+ "\tldrh r0, [r1]\n"
+ "\tlsrs r0, 8\n"
+ "\tstrb r0, [r2, 0x1]\n"
+ "\tldrh r0, [r1]\n"
+ "\tstrb r0, [r2]\n"
+ "\tadds r2, 0x2\n"
+ "\tadds r1, 0x2\n"
+ "\tadds r3, 0x1\n"
+ "\tcmp r3, 0x6\n"
+ "\tble _0800EFD0\n"
+ "\tadds r2, r4, 0\n"
+ "\tcmp r2, 0x4\n"
+ "\tble _0800EFC0\n"
+ "\tmovs r0, 0\n"
+ "\tmov r1, sp\n"
+ "\tstrh r0, [r1]\n"
+ "\tldr r2, =0x01000028\n"
+ "\tmov r0, sp\n"
+ "\tadds r1, r7, 0\n"
+ "\tbl CpuSet\n"
+ "\tadd sp, 0x4\n"
+ "\tpop {r4-r7}\n"
+ "\tpop {r0}\n"
+ "\tbx r0\n"
+ "\t.pool");
+}
+#endif
+
+void sub_800F014(void)
+{
+ int i;
+ for (i = 0; i < 7; i++)
+ {
+ gRecvCmds[0][i] = gSendCmd[i];
+ }
+ for (i = 0; i < 7; i++)
+ {
+ gSendCmd[i] = 0;
+ }
+}
+
+static void sub_800F048(void)
+{
+ if (gUnknown_03005000.unk_c3c)
+ {
+ u8 r2 = sub_800DAC8(&gUnknown_03005000.unk_c1c, gUnknown_03005000.unk_4c);
+ if (gUnknown_03005000.unk_c1c.unk_1e == 0)
+ {
+ gUnknown_03005000.unk_c3c = 0;
+ }
+ if (r2)
+ {
+ return;
+ }
+ }
+ if (gUnknown_03005000.unk_c3c == 0)
+ {
+ sub_800D9DC(&gUnknown_03005000.unk_9e8, gUnknown_03005000.unk_4c);
+ sub_800DA68(&gUnknown_03005000.unk_c1c, gUnknown_03005000.unk_4c);
+ }
+}
+
+bool32 sub_800F0B8(void)
+{
+ int i;
+ int j;
+
+ if (gUnknown_03007890->unk_06 == 0)
+ {
+ return FALSE;
+ }
+ for (i = 0; i < 5; i++)
+ {
+ for (j = 0; j < 7; j++)
+ {
+ if (gRecvCmds[i][j] != 0)
+ {
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+bool32 sub_800F0F8(void)
+{
+ if (gUnknown_03005000.unk_04 < 20)
+ {
+ rfu_REQ_recvData();
+ rfu_waitREQComplete();
+ rfu_REQ_sendData_wrapper(0);
+ }
+ else
+ {
+ gUnknown_03005000.unk_cdb = 0;
+ if ((gUnknown_03005000.unk_ce2 & gUnknown_03007890->unk_02) == gUnknown_03005000.unk_ce2 && (gUnknown_03005000.unk_ce2 & gUnknown_03007890->unk_02))
+ {
+ if (!gUnknown_03005000.unk_cdc)
+ {
+ if (gUnknown_03005000.unk_ce3)
+ {
+ sub_8011D6C(gUnknown_03005000.unk_ce3);
+ gUnknown_03005000.unk_ce3 = 0;
+ if (gUnknown_03005000.unk_ce4 == 1)
+ {
+ sub_8011A64(2, 0x8000);
+ sub_8011170(0x8000);
+ return FALSE;
+ }
+ if (!gUnknown_03004140.unk_00)
+ {
+ sub_800EDD4();
+ gReceivedRemoteLinkPlayers = 0;
+ return FALSE;
+ }
+ }
+ sub_800EFB0();
+ rfu_UNI_readySendData(gUnknown_03005000.unk_cda);
+ rfu_REQ_sendData_wrapper(1);
+ }
+ else
+ {
+ rfu_REQ_PARENT_resumeRetransmitAndChange();
+ }
+ gUnknown_03005000.unk_0e = 1;
+ }
+ }
+ return FALSE;
+}
+
+bool32 sub_800F1E0(void)
+{
+ u16 i;
+ u16 flags;
+ u8 r0;
+ u16 j;
+ u8 retval;
+
+ if (gUnknown_03005000.unk_04 >= 20 && gUnknown_03005000.unk_0e == 1)
+ {
+ rfu_waitREQComplete();
+ while (gUnknown_03005000.unk_cdb == 0)
+ {
+ if (gUnknown_03005000.unk_ee != 0)
+ {
+ return FALSE;
+ }
+ }
+ rfu_REQ_recvData();
+ rfu_waitREQComplete();
+ if ((gUnknown_03004140.unk_03 & gUnknown_03005000.unk_ce2) == gUnknown_03005000.unk_ce2)
+ {
+ gUnknown_03005000.unk_cdc = 0;
+ gUnknown_02022B44.unk_06++;
+ flags = gUnknown_03004140.unk_00;
+ for (i = 0; i < 4; i++)
+ {
+ if (flags & 1)
+ {
+ if (gUnknown_03005000.unk_14[i][1])
+ {
+ if (gUnknown_03005000.unk_cee[i] != 0xff && (gUnknown_03005000.unk_14[i][0] >> 5) != ((gUnknown_03005000.unk_cee[i] + 1) & 7))
+ {
+ if (++gUnknown_03005000.unk_cea[i] > 4)
+ sub_8011170(0x8100);
+ }
+ else
+ {
+ gUnknown_03005000.unk_cee[i] = gUnknown_03005000.unk_14[i][0] / 32;
+ gUnknown_03005000.unk_cea[i] = 0;
+ gUnknown_03005000.unk_14[i][0] &= 0x1f;
+ r0 = gUnknown_03005000.unk_cde[i];
+ for (j = 0; j < 7; j++)
+ {
+ gRecvCmds[r0][j] = (gUnknown_03005000.unk_14[i][(j << 1) + 1] << 8) | gUnknown_03005000.unk_14[i][(j << 1) + 0];
+ gUnknown_03005000.unk_14[i][(j << 1) + 1] = 0;
+ gUnknown_03005000.unk_14[i][(j << 1) + 0] = 0;
+ }
+ }
+ }
+ rfu_UNI_clearRecvNewDataFlag(i);
+ }
+ flags >>= 1;
+ }
+ sub_800F014();
+ sub_800F86C(0);
+ sub_8010528();
+ if (gUnknown_03005000.unk_ce5 && !gUnknown_03005000.unk_cd9)
+ {
+ gUnknown_02022B44.unk_0e = 0;
+ rfu_clearSlot(3, gUnknown_03005000.unk_cda);
+ for (i = 0; i < 4; i++)
+ {
+ if ((gUnknown_03005000.unk_ce5 >> i) & 1)
+ {
+ rfu_setRecvBuffer(0x10, i, gUnknown_03005000.unk_14[i], 14);
+ }
+ }
+ sub_800E88C(gUnknown_03005000.unk_ce2, gUnknown_03005000.unk_ce2 | gUnknown_03005000.unk_ce5);
+ gUnknown_03005000.unk_ce9 = gUnknown_03005000.unk_ce5;
+ gUnknown_03005000.unk_ce2 |= gUnknown_03005000.unk_ce5;
+ gUnknown_03005000.unk_ce5 = 0;
+ rfu_UNI_setSendData(gUnknown_03005000.unk_ce2, gUnknown_03005000.unk_c87, 70);
+ gUnknown_03005000.unk_cda = sub_800E87C(gUnknown_03005000.unk_ce2);
+ CreateTask(sub_8010AAC, 0);
+ }
+ }
+ else
+ {
+ gUnknown_03005000.unk_cdc = 1;
+ gUnknown_03005000.unk_0e = 0;
+ }
+ gUnknown_03005000.unk_0e = 0;
+ }
+ retval = gUnknown_03005000.unk_cdc;
+ return gUnknown_03007890->unk_06 ? retval & 1 : FALSE;
+}
+
+void sub_800F498(u16 *a0, u8 *a1)
+{
+ int i;
+
+ if (a0[0])
+ {
+ a0[0] |= (gUnknown_03005000.unk_102 << 5);
+ gUnknown_03005000.unk_102 = (gUnknown_03005000.unk_102 + 1) & 7;
+ for (i = 0; i < 7; i++)
+ {
+ a1[2 * i + 1] = a0[i] >> 8;
+ a1[2 * i + 0] = a0[i];
+ }
+ }
+ else
+ {
+ for (i = 0; i < 14; i++)
+ a1[i] = 0;
+ }
+}
+
+bool32 sub_800F4F0(void)
+{
+ u8 i;
+ u8 j;
+ u8 sp00[MAX_RFU_PLAYERS * (2 * (CMD_LENGTH - 1))];
+ u8 sp48[2 * (CMD_LENGTH - 1)];
+ u8 switchval;
+
+ sub_800D934(&gUnknown_03005000.unk_124, sp00);
+ for (i = 0; i < MAX_RFU_PLAYERS; i++)
+ {
+ for (j = 0; j < CMD_LENGTH - 1; j++)
+ {
+ gRecvCmds[i][j] = (sp00[i * 14 + (j << 1) + 1] << 8) | sp00[i * 14 + (j << 1) + 0];
+ }
+ }
+ sub_800F86C(0);
+ if (gUnknown_03004140.unk_02 == 0 && gUnknown_03005000.unk_ce4)
+ {
+ rfu_REQ_disconnect(gUnknown_03007890->unk_02 | gUnknown_03007890->unk_03);
+ rfu_waitREQComplete();
+ switchval = sub_8011A74();
+ if (switchval != 1 && switchval != 6 && switchval != 9)
+ sub_8011A64(2, 0x9000);
+ rfu_clearAllSlot();
+ gReceivedRemoteLinkPlayers = FALSE;
+ gUnknown_03005000.unk_00 = 0;
+ if (gUnknown_03005000.unk_ce4 == 1)
+ {
+ sub_8011A64(2, 0x9000);
+ sub_8011170(0x9000);
+ }
+ gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0;
+ gUnknown_03005000.unk_ce4 = 0;
+ }
+ if (gUnknown_03005000.unk_cd0)
+ {
+ gUnknown_03005000.unk_cd0--;
+ sub_8010528();
+ sub_800F498(gSendCmd, sp48);
+ sub_800D888(&gUnknown_03005000.unk_9e8, sp48);
+ for (i = 0; i < CMD_LENGTH - 1; i++)
+ gSendCmd[i] = 0;
+ }
+ return sub_800F0B8();
+}
+
+#ifdef NONMATCHING
+void sub_800F638(u8 unused, u32 flags)
+{
+ int i;
+ int j;
+
+ u8 *r10 = gUnknown_03005000.unk_6c.unk_04;
+ for (i = 0; i < gUnknown_03005000.unk_6c.unk_02; i++)
+ {
+ if (!(flags & 1))
+ {
+ gUnknown_03000D90[0] = (~0x76ff) | i;
+ for (j = 0; j < 7; j++)
+ {
+ gUnknown_03000D90[j + 1] = (r10[12 * i + (j << 1) + 1] << 8) | r10[12 * i + (j << 1) + 0];
+ }
+ for (j = 0; j < 7; j++)
+ // This should be an ascending loop.
+ // GCC compiles this as descending.
+ {
+ gUnknown_03000D80[2 * j + 1] = gUnknown_03000D90[j] >> 8;
+ gUnknown_03000D80[2 * j + 0] = gUnknown_03000D90[j];
+ }
+ sub_800D888(&gUnknown_03005000.unk_9e8, gUnknown_03000D80);
+ gUnknown_03005000.unk_6c.unk_0c |= (1 << i);
+ }
+ flags >>= 1;
+ }
+}
+#else
+NAKED void sub_800F638(u8 unused, u32 flags)
+{
+ asm_unified("\tpush {r4-r7,lr}\n"
+ "\tmov r7, r10\n"
+ "\tmov r6, r9\n"
+ "\tmov r5, r8\n"
+ "\tpush {r5-r7}\n"
+ "\tldr r0, =gUnknown_03005000\n"
+ "\tldr r2, [r0, 0x70]\n"
+ "\tmov r10, r2\n"
+ "\tmovs r5, 0\n"
+ "\tadds r2, r0, 0\n"
+ "\tadds r2, 0x6E\n"
+ "\tldrh r3, [r2]\n"
+ "\tcmp r5, r3\n"
+ "\tbge _0800F6D4\n"
+ "\tmov r9, r0\n"
+ "\tldr r0, =gUnknown_03000D90\n"
+ "\tmov r8, r0\n"
+ "_0800F65A:\n"
+ "\tmovs r0, 0x1\n"
+ "\tands r0, r1\n"
+ "\tlsrs r7, r1, 1\n"
+ "\tadds r6, r5, 0x1\n"
+ "\tcmp r0, 0\n"
+ "\tbne _0800F6C8\n"
+ "\tldr r1, =0xffff8900\n"
+ "\tadds r0, r1, 0\n"
+ "\tadds r1, r5, 0\n"
+ "\torrs r1, r0\n"
+ "\tmov r2, r8\n"
+ "\tstrh r1, [r2]\n"
+ "\tmovs r4, 0\n"
+ "\tlsls r0, r5, 1\n"
+ "\tldr r3, =gUnknown_03000D80\n"
+ "\tmov r12, r3\n"
+ "\tadds r0, r5\n"
+ "\tlsls r0, 2\n"
+ "\tmov r1, r10\n"
+ "\tadds r2, r0, r1\n"
+ "\tmov r3, r8\n"
+ "\tadds r3, 0x2\n"
+ "_0800F686:\n"
+ "\tldrb r1, [r2, 0x1]\n"
+ "\tlsls r1, 8\n"
+ "\tldrb r0, [r2]\n"
+ "\torrs r0, r1\n"
+ "\tstrh r0, [r3]\n"
+ "\tadds r2, 0x2\n"
+ "\tadds r3, 0x2\n"
+ "\tadds r4, 0x1\n"
+ "\tcmp r4, 0x6\n"
+ "\tble _0800F686\n"
+ "\tmovs r4, 0\n"
+ "\tldr r2, =gUnknown_03000D90\n"
+ "\tldr r1, =gUnknown_03000D80\n"
+ "_0800F6A0:\n"
+ "\tldrh r0, [r2]\n"
+ "\tlsrs r0, 8\n"
+ "\tstrb r0, [r1, 0x1]\n"
+ "\tldrh r0, [r2]\n"
+ "\tstrb r0, [r1]\n"
+ "\tadds r2, 0x2\n"
+ "\tadds r1, 0x2\n"
+ "\tadds r4, 0x1\n"
+ "\tcmp r4, 0x6\n"
+ "\tble _0800F6A0\n"
+ "\tldr r0, =gUnknown_03005000+0x9E8\n"
+ "\tmov r1, r12\n"
+ "\tbl sub_800D888\n"
+ "\tmovs r1, 0x1\n"
+ "\tlsls r1, r5\n"
+ "\tmov r2, r9\n"
+ "\tldr r0, [r2, 0x78]\n"
+ "\torrs r0, r1\n"
+ "\tstr r0, [r2, 0x78]\n"
+ "_0800F6C8:\n"
+ "\tadds r1, r7, 0\n"
+ "\tadds r5, r6, 0\n"
+ "\tldr r3, =gUnknown_03005000+0x6E\n"
+ "\tldrh r3, [r3]\n"
+ "\tcmp r5, r3\n"
+ "\tblt _0800F65A\n"
+ "_0800F6D4:\n"
+ "\tpop {r3-r5}\n"
+ "\tmov r8, r3\n"
+ "\tmov r9, r4\n"
+ "\tmov r10, r5\n"
+ "\tpop {r4-r7}\n"
+ "\tpop {r0}\n"
+ "\tbx r0\n"
+ "\t.pool");
+}
+#endif
+
+void sub_800F6FC(u8 a0)
+{
+ if (gUnknown_03005000.unk_0c == 1 && a0)
+ gUnknown_03005000.unk_61[a0] = 1;
+ else
+ gUnknown_03005000.unk_5c[a0] = 1;
+}
+
+void sub_800F728(u8 a0)
+{
+ gUnknown_03005000.unk_5c[a0] = 0;
+ gUnknown_03005000.unk_80[a0].unk_12 = 0;
+}
+
+u8 sub_800F74C(const u8 *a0)
+{
+ u8 i;
+
+ if (gUnknown_03005000.unk_0c == 1)
+ return FALSE;
+ for (i = 0; i < 4; i++)
+ {
+ gUnknown_03005000.unk_cde[i] = a0[i];
+ }
+ return a0[gUnknown_03005000.unk_c3e];
+}
+
+void rfu_func_080F97B8(void)
+{
+ if (gReceivedRemoteLinkPlayers && gUnknown_03005DA8 && gLinkTransferringData != 1)
+ {
+ gUnknown_03000D78[0]++;
+ gUnknown_03005DA8 |= (gUnknown_03000D78[0] << 8);
+ sub_800FD14(0xbe00);
+ }
+}
+
+struct UnkLinkRfuStruct_02022B14 *sub_800F7DC(void)
+{
+ return &gUnknown_02022B14;
+}
+
+bool32 sub_800F7E4(void)
+{
+ return gUnknown_03005000.unk_00 == rfu_func_080F97B8;
+}
+
+void sub_800F804(void)
+{
+ gUnknown_03005000.unk_00 = rfu_func_080F97B8;
+}
+
+void Rfu_set_zero(void)
+{
+ gUnknown_03005000.unk_00 = NULL;
+}
+
+void sub_800F820(void)
+{
+ sub_800FD14(0x4400);
+ if (GetMultiplayerId() == 0)
+ gSendCmd[6] = GetBlenderArrowPosition();
+ gUnknown_020223C0++;
+}
+
+void sub_800F850(void)
+{
+ if (gUnknown_03005000.unk_00 == NULL)
+ gUnknown_03005000.unk_00 = sub_800F820;
+}
+
+static void sub_800F86C(u8 unused)
+{
+ u16 i;
+ u16 j;
+
+ for (i = 0; i < MAX_RFU_PLAYERS; i++)
+ {
+ switch (gRecvCmds[i][0] & 0xff00)
+ {
+ case 0x7800:
+ if (gUnknown_03005000.unk_0c == 0 && gReceivedRemoteLinkPlayers != 0)
+ return;
+ // fallthrough
+ case 0x7700:
+ if (gUnknown_03007890->unk_00 == 0)
+ {
+ gUnknown_03005000.playerCount = gRecvCmds[i][1];
+ gUnknown_03005000.unk_cce = sub_800F74C((u8 *)(gRecvCmds[i] + 2));
+ }
+ break;
+ case 0x8800:
+ if (gUnknown_03005000.unk_80[i].unk_12 == 0)
+ {
+ gUnknown_03005000.unk_80[i].unk_00 = 0;
+ gUnknown_03005000.unk_80[i].unk_02 = gRecvCmds[i][1];
+ gUnknown_03005000.unk_80[i].unk_11 = gRecvCmds[i][2];
+ gUnknown_03005000.unk_80[i].unk_08 = 0;
+ gUnknown_03005000.unk_80[i].unk_12 = 1;
+ gUnknown_03005000.unk_5c[i] = 0;
+ }
+ break;
+ case 0x8900:
+ if (gUnknown_03005000.unk_80[i].unk_12 == 1)
+ {
+ gUnknown_03005000.unk_80[i].unk_00 = gRecvCmds[i][0] & 0xff;
+ gUnknown_03005000.unk_80[i].unk_08 |= (1 << gUnknown_03005000.unk_80[i].unk_00);
+ for (j = 0; j < 6; j++)
+ gBlockRecvBuffer[i][gUnknown_03005000.unk_80[i].unk_00 * 6 + j] = gRecvCmds[i][j + 1];
+ if (gUnknown_03005000.unk_80[i].unk_08 == gUnknown_082ED628[gUnknown_03005000.unk_80[i].unk_02])
+ {
+ gUnknown_03005000.unk_80[i].unk_12 = 2;
+ sub_800F6FC(i);
+ if (sub_800F7DC()->unk_0a_0 == 0x45 && gReceivedRemoteLinkPlayers != 0 && gUnknown_03005000.unk_0c == 0)
+ sub_8010A70(gBlockRecvBuffer);
+ }
+ }
+ break;
+ case 0xa100:
+ sub_800FE84(gUnknown_082ED6B8[gRecvCmds[i][1]].buffer, (u16)gUnknown_082ED6B8[gRecvCmds[i][1]].size);
+ break;
+ case 0x5f00:
+ gUnknown_03005000.unk_e4[i] = 1;
+ break;
+ case 0x6600:
+ if (gUnknown_03005000.unk_100 == gRecvCmds[i][1])
+ gUnknown_03005000.unk_e9[i] = 1;
+ break;
+ case 0xed00:
+ if (gUnknown_03005000.unk_0c == 0)
+ {
+ if (gReceivedRemoteLinkPlayers != 0)
+ {
+ if (gRecvCmds[i][1] & gUnknown_03007890->unk_02)
+ {
+ gReceivedRemoteLinkPlayers = 0;
+ sub_800D630();
+ gUnknown_03005000.unk_ce4 = gRecvCmds[i][2];
+ }
+ gUnknown_03005000.playerCount = gRecvCmds[i][3];
+ sub_80109E8(gRecvCmds[i][1]);
+ }
+ }
+ else
+ {
+ sub_800FD14(0xee00);
+ gSendCmd[1] = gRecvCmds[i][1];
+ gSendCmd[2] = gRecvCmds[i][2];
+ gSendCmd[3] = gRecvCmds[i][3];
+ }
+ break;
+ case 0xee00:
+ if (gUnknown_03005000.unk_0c == 1)
+ {
+ gUnknown_03005000.unk_ce3 |= gRecvCmds[i][1];
+ gUnknown_03005000.unk_ce4 = gRecvCmds[i][2];
+ sub_80109E8(gRecvCmds[i][1]);
+ }
+ break;
+ case 0x4400:
+ case 0xbe00:
+ gLinkPartnersHeldKeys[i] = gRecvCmds[i][1];
+ break;
+ }
+ if (gUnknown_03005000.unk_0c == 1 && gUnknown_03005000.unk_61[i])
+ {
+ if (gUnknown_03005000.unk_61[i] == 4)
+ {
+ gUnknown_03005000.unk_5c[i] = 1;
+ gUnknown_03005000.unk_61[i] = 0;
+ }
+ else
+ gUnknown_03005000.unk_61[i]++;
+ }
+ }
+}
+
+bool8 sub_800FC60(void)
+{
+ int i;
+
+ for (i = 0; i < 5; i++)
+ {
+ if (gUnknown_03005000.unk_80[i].unk_12)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool8 sub_800FC88(void)
+{
+ int i;
+
+ for (i = 0; i < gUnknown_03005000.playerCount; i++)
+ {
+ if (gUnknown_03005000.unk_80[i].unk_12 != 2 || gUnknown_03005000.unk_5c[i] != 1)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void sub_800FCC4(struct UnkRfuStruct_2_Sub_6c *data)
+{
+ data->unk_00 = 0;
+ data->unk_02 = 0;
+ data->unk_04 = NULL;
+ data->unk_08 = 0;
+ data->unk_10 = 0;
+ data->unk_11 = 0;
+ data->unk_12 = 0;
+}
+
+u8 sub_800FCD8(void)
+{
+ u8 flags = 0;
+ int i;
+
+ for (i = 0; i < 5; i++)
+ {
+ if (gUnknown_03005000.unk_80[i].unk_12 == 2 && gUnknown_03005000.unk_5c[i] == 1)
+ {
+ flags |= (1 << i);
+ }
+ }
+ return flags;
+}
+
+#ifdef NONMATCHING
+// The switch tree is incorrect
+void sub_800FD14(u16 command)
+{
+ u8 i;
+ u8 *buff;
+ u8 tmp;
+
+ gSendCmd[0] = command;
+ switch (command)
+ {
+ case 0x8800:
+ gSendCmd[1] = gUnknown_03005000.unk_6c.unk_02;
+ gSendCmd[2] = gUnknown_03005000.unk_6c.unk_11 + 0x80;
+ break;
+ case 0xa100:
+ if (sub_800FC60())
+ gSendCmd[1] = gUnknown_03005000.unk_5a;
+ break;
+ case 0x7800:
+ case 0x7700:
+ tmp = gUnknown_03005000.unk_ce2 ^ gUnknown_03005000.unk_ce3;
+ gUnknown_03005000.playerCount = gUnknown_082ED695[tmp] + 1;
+ gSendCmd[1] = gUnknown_03005000.playerCount;
+ buff = (u8 *)(gSendCmd + 2);
+ for (i = 0; i < 4; i++)
+ buff[i] = gUnknown_03005000.unk_cde[i];
+ break;
+ case 0x6600:
+ case 0x5f00:
+ gSendCmd[1] = gUnknown_03005000.unk_100;
+ break;
+ case 0x4400:
+ gSendCmd[0] = 0x4400;
+ gSendCmd[1] = gMain.heldKeys;
+ break;
+ case 0x2f00:
+ for (i = 0; i < 6; i++)
+ gSendCmd[1 + i] = gUnknown_03005000.unk_f2[i];
+ break;
+ case 0xbe00:
+ gSendCmd[1] = gUnknown_03005DA8;
+ break;
+ }
+}
+#else
+NAKED void sub_800FD14(u16 command)
+{
+ asm_unified("\tpush {r4,r5,lr}\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r1, r0, 16\n"
+ "\tldr r5, =gSendCmd\n"
+ "\tstrh r1, [r5]\n"
+ "\tmovs r0, 0xF0\n"
+ "\tlsls r0, 7\n"
+ "\tadds r4, r5, 0\n"
+ "\tcmp r1, r0\n"
+ "\tbeq _0800FDB0_case_7700_case_7800\n"
+ "\tcmp r1, r0\n"
+ "\tbgt _0800FD62\n"
+ "\tmovs r0, 0xBE\n"
+ "\tlsls r0, 7\n"
+ "\tcmp r1, r0\n"
+ "\tbeq _0800FE00_case_5f00_case_6600\n"
+ "\tcmp r1, r0\n"
+ "\tbgt _0800FD50\n"
+ "\tmovs r0, 0xBC\n"
+ "\tlsls r0, 6\n"
+ "\tcmp r1, r0\n"
+ "\tbeq _0800FE20_case_2f00\n"
+ "\tmovs r0, 0x88\n"
+ "\tlsls r0, 7\n"
+ "\tcmp r1, r0\n"
+ "\tbeq _0800FE14_case_4400\n"
+ "\tb _0800FE46_break\n"
+ "\t.pool\n"
+ "_0800FD50:\n"
+ "\tmovs r0, 0xCC\n"
+ "\tlsls r0, 7\n"
+ "\tcmp r1, r0\n"
+ "\tbeq _0800FE00_case_5f00_case_6600\n"
+ "\tmovs r0, 0xEE\n"
+ "\tlsls r0, 7\n"
+ "\tcmp r1, r0\n"
+ "\tbeq _0800FDB0_case_7700_case_7800\n"
+ "\tb _0800FE46_break\n"
+ "_0800FD62:\n"
+ "\tmovs r0, 0xBE\n"
+ "\tlsls r0, 8\n"
+ "\tcmp r1, r0\n"
+ "\tbeq _0800FE40_case_be00\n"
+ "\tcmp r1, r0\n"
+ "\tbgt _0800FE46_break\n"
+ "\tmovs r0, 0x88\n"
+ "\tlsls r0, 8\n"
+ "\tcmp r1, r0\n"
+ "\tbeq _0800FD80_case_8800\n"
+ "\tmovs r0, 0xA1\n"
+ "\tlsls r0, 8\n"
+ "\tcmp r1, r0\n"
+ "\tbeq _0800FD98_case_a100\n"
+ "\tb _0800FE46_break\n"
+ "_0800FD80_case_8800:\n"
+ "\tldr r0, =gUnknown_03005000\n"
+ "\tadds r1, r0, 0\n"
+ "\tadds r1, 0x6E\n"
+ "\tldrh r1, [r1]\n"
+ "\tstrh r1, [r5, 0x2]\n"
+ "\tadds r0, 0x7D\n"
+ "\tldrb r0, [r0]\n"
+ "\tadds r0, 0x80\n"
+ "\tstrh r0, [r5, 0x4]\n"
+ "\tb _0800FE46_break\n"
+ "\t.pool\n"
+ "_0800FD98_case_a100:\n"
+ "\tbl sub_800FC60\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _0800FE46_break\n"
+ "\tldr r0, =gUnknown_03005000\n"
+ "\tadds r0, 0x5A\n"
+ "\tldrb r0, [r0]\n"
+ "\tb _0800FE44_str_break\n"
+ "\t.pool\n"
+ "_0800FDB0_case_7700_case_7800:\n"
+ "\tldr r3, =gUnknown_03005000\n"
+ "\tldr r1, =0x00000ce2\n"
+ "\tadds r0, r3, r1\n"
+ "\tldr r2, =0x00000ce3\n"
+ "\tadds r1, r3, r2\n"
+ "\tldrb r2, [r0]\n"
+ "\tldrb r0, [r1]\n"
+ "\teors r0, r2\n"
+ "\tldr r1, =gUnknown_082ED695\n"
+ "\tadds r0, r1\n"
+ "\tldrb r0, [r0]\n"
+ "\tadds r0, 0x1\n"
+ "\tstrb r0, [r3, 0xD]\n"
+ "\tldrb r0, [r3, 0xD]\n"
+ "\tstrh r0, [r4, 0x2]\n"
+ "\tadds r2, r4, 0x4\n"
+ "\tmovs r4, 0\n"
+ "\tldr r0, =0x00000cde\n"
+ "\tadds r3, r0\n"
+ "_0800FDD6:\n"
+ "\tadds r1, r2, r4\n"
+ "\tadds r0, r4, r3\n"
+ "\tldrb r0, [r0]\n"
+ "\tstrb r0, [r1]\n"
+ "\tadds r0, r4, 0x1\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r4, r0, 24\n"
+ "\tcmp r4, 0x3\n"
+ "\tbls _0800FDD6\n"
+ "\tb _0800FE46_break\n"
+ "\t.pool\n"
+ "_0800FE00_case_5f00_case_6600:\n"
+ "\tldr r0, =gUnknown_03005000\n"
+ "\tmovs r1, 0x80\n"
+ "\tlsls r1, 1\n"
+ "\tadds r0, r1\n"
+ "\tldrh r0, [r0]\n"
+ "\tstrh r0, [r4, 0x2]\n"
+ "\tb _0800FE46_break\n"
+ "\t.pool\n"
+ "_0800FE14_case_4400:\n"
+ "\tstrh r1, [r5]\n"
+ "\tldr r0, =gMain\n"
+ "\tldrh r0, [r0, 0x2C]\n"
+ "\tb _0800FE44_str_break\n"
+ "\t.pool\n"
+ "_0800FE20_case_2f00:\n"
+ "\tmovs r4, 0\n"
+ "\tldr r3, =gUnknown_03005000+0xF2\n"
+ "_0800FE24:\n"
+ "\tadds r2, r4, 0x1\n"
+ "\tlsls r1, r2, 1\n"
+ "\tadds r1, r5\n"
+ "\tlsls r0, r4, 1\n"
+ "\tadds r0, r3\n"
+ "\tldrh r0, [r0]\n"
+ "\tstrh r0, [r1]\n"
+ "\tlsls r2, 24\n"
+ "\tlsrs r4, r2, 24\n"
+ "\tcmp r4, 0x5\n"
+ "\tbls _0800FE24\n"
+ "\tb _0800FE46_break\n"
+ "\t.pool\n"
+ "_0800FE40_case_be00:\n"
+ "\tldr r0, =gUnknown_03005DA8\n"
+ "\tldrh r0, [r0]\n"
+ "_0800FE44_str_break:\n"
+ "\tstrh r0, [r5, 0x2]\n"
+ "_0800FE46_break:\n"
+ "\tpop {r4,r5}\n"
+ "\tpop {r0}\n"
+ "\tbx r0\n"
+ "\t.pool");
+}
+#endif
+
+void sub_800FE50(u16 *a0)
+{
+ if (gSendCmd[0] == 0 && sub_8011A80() == 0)
+ {
+ memcpy(gUnknown_03005000.unk_f2, a0, sizeof(gUnknown_03005000.unk_f2));
+ sub_800FD14(0x2f00);
+ }
+}
+
+bool32 sub_800FE84(const u8 *src, size_t size)
+{
+ bool8 r4;
+ if (gUnknown_03005000.unk_00 != NULL)
+ return FALSE;
+ if (gSendCmd[0] != 0)
+ return FALSE;
+ if (gUnknown_03005000.unk_6c.unk_10 != 0)
+ {
+ gUnknown_02022B44.unk_83++;
+ return FALSE;
+ }
+ r4 = (size % 12) != 0;
+ gUnknown_03005000.unk_6c.unk_11 = GetMultiplayerId();
+ gUnknown_03005000.unk_6c.unk_10 = 1;
+ gUnknown_03005000.unk_6c.unk_02 = (size / 12) + r4;
+ gUnknown_03005000.unk_6c.unk_00 = 0;
+ if (size > 0x100)
+ gUnknown_03005000.unk_6c.unk_04 = src;
+ else
+ {
+ if (src != gBlockSendBuffer)
+ memcpy(gBlockSendBuffer, src, size);
+ gUnknown_03005000.unk_6c.unk_04 = gBlockSendBuffer;
+ }
+ sub_800FD14(0x8800);
+ gUnknown_03005000.unk_00 = rfufunc_80F9F44;
+ gUnknown_03005000.unk_5b = 0;
+ return TRUE;
+}
+
+static void rfufunc_80F9F44(void)
+{
+ if (gSendCmd[0] == 0)
+ {
+ sub_800FD14(0x8800);
+ if (gUnknown_03005000.unk_0c == 1)
+ {
+ if (++gUnknown_03005000.unk_5b > 2)
+ gUnknown_03005000.unk_00 = sub_800FFB0;
+ }
+ else
+ {
+ if ((gRecvCmds[GetMultiplayerId()][0] & 0xff00) == 0x8800)
+ gUnknown_03005000.unk_00 = sub_800FFB0;
+ }
+ }
+}
+
+static void sub_800FFB0(void)
+{
+ int i;
+ const u8 *src = gUnknown_03005000.unk_6c.unk_04;
+ gSendCmd[0] = 0x8900 | gUnknown_03005000.unk_6c.unk_00;
+ for (i = 0; i < 7; i++)
+ gSendCmd[i + 1] = (src[(i << 1) + gUnknown_03005000.unk_6c.unk_00 * 12 + 1] << 8) | src[(i << 1) + gUnknown_03005000.unk_6c.unk_00 * 12 + 0];
+ gUnknown_03005000.unk_6c.unk_00++;
+ if (gUnknown_03005000.unk_6c.unk_02 <= gUnknown_03005000.unk_6c.unk_00)
+ {
+ gUnknown_03005000.unk_6c.unk_10 = 0;
+ gUnknown_03005000.unk_00 = rfufunc_80FA020;
+ }
+}
+
+static void rfufunc_80FA020(void)
+{
+ const u8 *src = gUnknown_03005000.unk_6c.unk_04;
+ u8 mpId = GetMultiplayerId();
+ int i;
+ if (gUnknown_03005000.unk_0c == 0)
+ {
+ gSendCmd[0] = (~0x76ff) | (gUnknown_03005000.unk_6c.unk_02 - 1);
+ for (i = 0; i < 7; i++)
+ gSendCmd[i + 1] = (src[(i << 1) + (gUnknown_03005000.unk_6c.unk_02 - 1) * 12 + 1] << 8) | src[(i << 1) + (gUnknown_03005000.unk_6c.unk_02 - 1) * 12 + 0];
+ if ((u8)gRecvCmds[mpId][0] == gUnknown_03005000.unk_6c.unk_02 - 1)
+ {
+ if (gUnknown_03005000.unk_80[mpId].unk_08 != gUnknown_082ED628[gUnknown_03005000.unk_80[mpId].unk_02])
+ {
+ sub_800F638(mpId, gUnknown_03005000.unk_80[mpId].unk_08);
+ gUnknown_02022B44.unk_64++;
+ }
+ else
+ gUnknown_03005000.unk_00 = NULL;
+ }
+ }
+ else
+ gUnknown_03005000.unk_00 = NULL;
+}
+
+bool8 sub_8010100(u8 a0)
+{
+ gUnknown_03005000.unk_5a = a0;
+ sub_800FD14(0xa100);
+ return TRUE;
+}
+
+void sub_801011C(void)
+{
+ rfu_clearAllSlot();
+ sub_800C048();
+ gReceivedRemoteLinkPlayers = 0;
+ gUnknown_03005000.unk_ef = 1;
+ gUnknown_03005000.unk_00 = NULL;
+}
+
+void sub_8010148(void)
+{
+ rfu_REQ_disconnect(gUnknown_03007890->unk_02 | gUnknown_03007890->unk_03);
+ rfu_waitREQComplete();
+ sub_801011C();
+}
+
+void sub_8010168(void)
+{
+ if (gUnknown_03005000.unk_0c == 0)
+ {
+ sub_800D630();
+ gUnknown_03005000.unk_ce4 = 2;
+ }
+ else
+ gUnknown_03005000.unk_00 = sub_8010148;
+}
+
+void sub_8010198(void)
+{
+ sub_800D630();
+ gUnknown_03005000.unk_ce4 = 1;
+ gUnknown_03005000.unk_ce3 = gUnknown_03007890->unk_02 | gUnknown_03007890->unk_03;
+}
+
+void sub_80101CC(void)
+{
+ int i;
+ u8 playerCount = gUnknown_03005000.playerCount;
+ int count = 0;
+
+ for (i = 0; i < MAX_RFU_PLAYERS; i++)
+ {
+ if (gUnknown_03005000.unk_e4[i])
+ count++;
+ }
+ if (count == playerCount)
+ {
+ gBattleTypeFlags &= ~BATTLE_TYPE_20;
+ if (gUnknown_03005000.unk_0c == 0)
+ {
+ gUnknown_03005000.unk_ee = 3;
+ sub_8010168();
+ }
+ else
+ gUnknown_03005000.unk_00 = sub_8010168;
+ }
+}
+
+void sub_801022C(void)
+{
+ if (gSendCmd[0] == 0 && gUnknown_03005000.unk_ce8 == 0)
+ {
+ sub_800FD14(0x5f00);
+ gUnknown_03005000.unk_00 = sub_80101CC;
+ }
+}
+
+void sub_8010264(u8 taskId)
+{
+ if (gUnknown_03005000.unk_00 == NULL)
+ {
+ gUnknown_03005000.unk_cd9 = 1;
+ gUnknown_03005000.unk_00 = sub_801022C;
+ DestroyTask(taskId);
+ }
+}
+
+void task_add_05_task_del_08FA224_when_no_RfuFunc(void)
+{
+ if (!FuncIsActiveTask(sub_8010264))
+ CreateTask(sub_8010264, 5);
+}
+
+void sub_80102B8(void)
+{
+ u8 playerCount;
+ u8 i;
+
+ if (GetMultiplayerId() != 0)
+ {
+ u8 r4 = gUnknown_03005000.unk_124.unk_8c2;
+ if (r4 == 0 && gUnknown_03005000.unk_fe > 0x3c)
+ {
+ sub_800FD14(0x6600);
+ gUnknown_03005000.unk_fe = r4;
+ }
+ }
+ playerCount = GetLinkPlayerCount();
+ for (i = 0; i < playerCount; i++)
+ {
+ if (gUnknown_03005000.unk_e9[i] == 0)
+ break;
+ }
+ if (i == playerCount)
+ {
+ for (i = 0; i < MAX_RFU_PLAYERS; i++)
+ gUnknown_03005000.unk_e9[i] = 0;
+ gUnknown_03005000.unk_100++;
+ gUnknown_03005000.unk_00 = NULL;
+ }
+ gUnknown_03005000.unk_fe++;
+}
+
+void sub_8010358(void)
+{
+ if (gUnknown_03005000.unk_124.unk_8c2 == 0 && gSendCmd[0] == 0)
+ {
+ sub_800FD14(0x6600);
+ gUnknown_03005000.unk_00 = sub_80102B8;
+ }
+}
+
+void sub_8010390(void)
+{
+ u8 i;
+ u8 playerCount;
+
+ if (GetMultiplayerId() != 0)
+ {
+ if (gUnknown_03005000.unk_124.unk_8c2 == 0 && gSendCmd[0] == 0)
+ {
+ sub_800FD14(0x6600);
+ gUnknown_03005000.unk_00 = sub_80102B8;
+ }
+ }
+ else
+ {
+ playerCount = GetLinkPlayerCount();
+ for (i = 1; i < playerCount; i++)
+ {
+ if (gUnknown_03005000.unk_e9[i] == 0)
+ break;
+ }
+ if (i == playerCount)
+ {
+ if (gUnknown_03005000.unk_124.unk_8c2 == 0 && gSendCmd[0] == 0)
+ {
+ sub_800FD14(0x6600);
+ gUnknown_03005000.unk_00 = sub_8010358;
+ }
+ }
+ }
+}
+
+void sub_8010434(void)
+{
+ if (gUnknown_03005000.unk_00 == NULL)
+ {
+ gUnknown_03005000.unk_00 = sub_8010390;
+ gUnknown_03005000.unk_fe = 0;
+ }
+}
+
+bool32 sub_8010454(u32 a0)
+{
+ int i;
+ for (i = 0; gUnknown_082ED6E0[i] != a0; i++)
+ {
+ if (gUnknown_082ED6E0[i] == 0xffff)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+u8 sub_801048C(bool32 a0)
+{
+ if (a0 == 0)
+ return sub_800D550(0, 0);
+ sub_800D550(1, 0x258);
+ return FALSE;
+}
+
+void sub_80104B0(void)
+{
+ gUnknown_03005000.unk_cd9 = 1;
+ sub_800C27C(FALSE);
+}
+
+u8 rfu_get_multiplayer_id(void)
+{
+ if (gUnknown_03005000.unk_0c == 1)
+ return 0;
+ return gUnknown_03005000.unk_cce;
+}
+
+u8 sub_80104F4(void)
+{
+ return gUnknown_03005000.playerCount;
+}
+
+bool8 sub_8010500(void)
+{
+ if (gUnknown_03005000.unk_f1 == 2)
+ return FALSE;
+ return gUnknown_03005000.unk_00 ? FALSE : TRUE;
+}
+
+static void sub_8010528(void)
+{
+ if (gUnknown_03005000.unk_00)
+ gUnknown_03005000.unk_00();
+}
+
+bool8 sub_8010540(void)
+{
+ int i;
+ bool8 retval = FALSE;
+ for (i = 0; i < 4; i++)
+ {
+ if (gUnknown_03005000.unk_cd1[i] < 5 || gUnknown_03005000.unk_cd1[i] > 6)
+ {
+ if (gUnknown_03007880[i]->unk_34 == 0x46 || gUnknown_03007880[i]->unk_34 == 0x48)
+ {
+ if (gUnknown_03005000.unk_cd5[i] == 8)
+ {
+ gUnknown_03005000.unk_cd1[i] = 9;
+ gUnknown_03005000.unk_cd5[i] = 10;
+ rfu_clearSlot(8, i);
+ rfu_NI_setSendData(1 << i, 8, gUnknown_03005000.unk_cd1 + i, 1);
+ retval = TRUE;
+ }
+
+ }
+ else if (gUnknown_03007880[gUnknown_03005000.unk_c3e]->unk_34 == 0x47)
+ rfu_clearSlot(8, i);
+ {
+
+ }
+ }
+ }
+ return retval;
+}
+
+bool8 sub_80105EC(void)
+{
+ u8 flags = 0;
+ int i;
+ for (i = 0; i < 4; i++)
+ {
+ if (gUnknown_03005000.unk_cd5[i] == 11)
+ {
+ flags |= (1 << i);
+ gUnknown_03005000.unk_cd5[i] = 0;
+ }
+ }
+ if (flags)
+ {
+ rfu_REQ_disconnect(flags);
+ rfu_waitREQComplete();
+ }
+ for (i = 0; i < 4; i++)
+ {
+ if (gUnknown_03005000.unk_cd5[i] == 10 || gUnknown_03005000.unk_cd5[i] == 11)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_801064C(u16 a0, const u8 *a1)
+{
+ u8 r1 = sub_8011CE4(a1, a0);
+ if (r1 == 0xFF)
+ return TRUE;
+ if (gUnknown_03005000.unk_cd1[r1] == 9)
+ return TRUE;
+ return FALSE;
+}
+
+void sub_8010688(u8 a0, u16 a1, const u8 *a2)
+{
+ u8 r4 = sub_8011CE4(a2, a1);
+ gUnknown_03005000.unk_cd1[r4] = a0;
+ rfu_clearSlot(4, r4);
+ rfu_NI_setSendData(1 << r4, 8, gUnknown_03005000.unk_cd1 + r4, 1);
+}
+
+void sub_80106D4(void)
+{
+ gUnknown_03005000.unk_c85 = 8;
+ rfu_clearSlot(4, gUnknown_03005000.unk_c3e);
+ rfu_NI_setSendData(1 << gUnknown_03005000.unk_c3e, 8, &gUnknown_03005000.unk_c85, 1);
+}
+
+u8 sub_8010714(u16 a0, const u8 *a1)
+{
+ u8 r0 = sub_8011CE4(a1, a0);
+ if (r0 == 0xff)
+ return 2;
+ if (gUnknown_03007880[r0]->unk_0 == 0)
+ return TRUE;
+ return FALSE;
+}
+
+void sub_8010750(void)
+{
+ int i;
+
+ sub_8010540();
+ for (i = 0; i < 4; i++)
+ {
+ if (gUnknown_03007880[i]->unk_0 == 0x26 || gUnknown_03007880[i]->unk_0 == 0x27)
+ {
+ if (gUnknown_03005000.unk_cd5[i] == 10)
+ gUnknown_03005000.unk_cd5[i] = 11;
+ rfu_clearSlot(4, i);
+ }
+ }
+}
+
+int sub_80107A0(void)
+{
+ int retval = 0;
+ if (gUnknown_03005000.unk_c85 == 8)
+ {
+ if (gUnknown_03007880[gUnknown_03005000.unk_c3e]->unk_0 == 0x26 || gUnknown_03007880[gUnknown_03005000.unk_c3e]->unk_0 == 0x27)
+ rfu_clearSlot(4, gUnknown_03005000.unk_c3e);
+ }
+ if (gUnknown_03007880[gUnknown_03005000.unk_c3e]->unk_34 == 0x46 || gUnknown_03007880[gUnknown_03005000.unk_c3e]->unk_34 == 0x48)
+ {
+ rfu_clearSlot(8, gUnknown_03005000.unk_c3e);
+ sub_8011A64(gUnknown_03005000.unk_c86, 0);
+ retval = gUnknown_03005000.unk_c86;
+ }
+ else if (gUnknown_03007880[gUnknown_03005000.unk_c3e]->unk_34 == 0x47)
+ {
+ rfu_clearSlot(8, gUnknown_03005000.unk_c3e);
+ retval = 6;
+ }
+ return retval;
+}
+
+void sub_801084C(u8 taskId)
+{
+ int i;
+
+ if (gUnknown_03005000.unk_f1 == 1 || gUnknown_03005000.unk_f1 == 2)
+ {
+ gUnknown_03005000.unk_ce8 = 0;
+ DestroyTask(taskId);
+ }
+ switch (gTasks[taskId].data[0])
+ {
+ case 0:
+ if (sub_800FC60())
+ {
+ ResetBlockReceivedFlags();
+ sub_800B348();
+ gTasks[taskId].data[0]++;
+ }
+ break;
+ case 1:
+ if (gUnknown_03005000.unk_0c == 1)
+ {
+ if (gReceivedRemoteLinkPlayers)
+ sub_800FD14(0x7800);
+ else
+ sub_800FD14(0x7700);
+ gTasks[taskId].data[0] = 101;
+ }
+ else
+ gTasks[taskId].data[0] = 2;
+ break;
+ case 101:
+ if (gSendCmd[0] == 0)
+ gTasks[taskId].data[0] = 2;
+ break;
+ case 2:
+ if (gUnknown_03005000.playerCount)
+ gTasks[taskId].data[0]++;
+ break;
+ case 3:
+ if (gUnknown_03005000.unk_0c == 1)
+ {
+ if (sub_800FC60())
+ {
+ gUnknown_03005000.unk_5a = 0;
+ sub_800FD14(0xa100);
+ gTasks[taskId].data[0]++;
+ }
+ }
+ else
+ gTasks[taskId].data[0]++;
+ break;
+ case 4:
+ if (sub_800FC88())
+ gTasks[taskId].data[0]++;
+ break;
+ case 5:
+ for (i = 0; i < gUnknown_03005000.playerCount; i++)
+ {
+ sub_800B3A4(i);
+ sub_800F728(i);
+ }
+ gTasks[taskId].data[0]++;
+ break;
+ case 6:
+ DestroyTask(taskId);
+ gReceivedRemoteLinkPlayers = 1;
+ gUnknown_03005000.unk_ce8 = 0;
+ sub_800D550(1, 0x258);
+ if (gUnknown_03005000.unk_ce6)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ if ((gUnknown_03005000.unk_ce6 >> i) & 1)
+ {
+ gUnknown_03005000.unk_ce5 = 1 << i;
+ gUnknown_03005000.unk_ce6 ^= (1 << i);
+ }
+ }
+ }
+ break;
+ }
+}
+
+void sub_80109E8(u16 a0)
+{
+ int i;
+
+ for (i = 0; i < 4; i++)
+ {
+ if ((a0 >> i) & 1)
+ gUnknown_03005000.unk_cde[i] = 0;
+ }
+}
+
+void sub_8010A14(const struct UnkRfuStruct_8010A14 *a0)
+{
+ int i;
+ gUnknown_03005000.playerCount = a0->unk_0f;
+ for (i = 0; i < 4; i++)
+ gUnknown_03005000.unk_cde[i] = a0->unk_10[i];
+ for (i = 0; i < MAX_RFU_PLAYERS; i++)
+ {
+ gLinkPlayers[i] = a0->unk_14[i];
+ sub_800B524(gLinkPlayers + i);
+ }
+}
+
+void sub_8010A70(void *a0)
+{
+ if (strcmp(gUnknown_082ED7EC, a0) == 0)
+ {
+ sub_8010A14(a0);
+ CpuFill16(0, a0, sizeof(struct UnkRfuStruct_8010A14));
+ ResetBlockReceivedFlag(0);
+ }
+}
+
+void sub_8010AAC(u8 taskId)
+{
+ int i;
+ struct LinkPlayerBlock *r2;
+ struct UnkRfuStruct_8010A14 *r5;
+ u8 r4 = gUnknown_03005000.unk_cde[gUnknown_082ED68C[gUnknown_03005000.unk_ce9]];
+ if (gUnknown_03005000.unk_f1 == 1 || gUnknown_03005000.unk_f1 == 2)
+ {
+ gUnknown_03005000.unk_ce8 = 0;
+ DestroyTask(taskId);
+ }
+ switch (gTasks[taskId].data[0])
+ {
+ case 0:
+ if (gSendCmd[0] == 0)
+ {
+ ResetBlockReceivedFlag(r4);
+ sub_800FD14(0x7800);
+ gTasks[taskId].data[0]++;
+ }
+ break;
+ case 1:
+ if (gSendCmd[0] == 0)
+ gTasks[taskId].data[0]++;
+ break;
+ case 2:
+ if ((GetBlockReceivedStatus() >> r4) & 1)
+ {
+ ResetBlockReceivedFlag(r4);
+ r2 = (struct LinkPlayerBlock *)gBlockRecvBuffer[r4];
+ gLinkPlayers[r4] = r2->linkPlayer;
+ sub_800B524(gLinkPlayers + r4);
+ gTasks[taskId].data[0]++;
+ }
+ break;
+ case 3:
+ r5 = (struct UnkRfuStruct_8010A14 *)gBlockSendBuffer;
+ memcpy(r5->unk_00, gUnknown_082ED7EC, sizeof gUnknown_082ED7EC);
+ r5->unk_0f = gUnknown_03005000.playerCount;
+ for (i = 0; i < 4; i++)
+ r5->unk_10[i] = gUnknown_03005000.unk_cde[i];
+ memcpy(r5->unk_14, gLinkPlayers, sizeof gLinkPlayers);
+ gTasks[taskId].data[0]++;
+ // fallthrough
+ case 4:
+ r5 = (struct UnkRfuStruct_8010A14 *)gBlockSendBuffer;
+ r5->unk_0f = gUnknown_03005000.playerCount;
+ for (i = 0; i < 4; i++)
+ r5->unk_10[i] = gUnknown_03005000.unk_cde[i];
+ memcpy(r5->unk_14, gLinkPlayers, sizeof gLinkPlayers);
+ if (SendBlock(0, gBlockSendBuffer, 0xa0))
+ gTasks[taskId].data[0]++;
+ break;
+ case 5:
+ if (sub_800A520() && GetBlockReceivedStatus() & 1)
+ {
+ CpuFill16(0, gBlockRecvBuffer, sizeof(struct UnkRfuStruct_8010A14));
+ ResetBlockReceivedFlag(0);
+ gUnknown_03005000.unk_ce8 = 0;
+ if (gUnknown_03005000.unk_ce6)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ if ((gUnknown_03005000.unk_ce6 >> i) & 1)
+ {
+ gUnknown_03005000.unk_ce5 = 1 << i;
+ gUnknown_03005000.unk_ce6 ^= (1 << i);
+ gUnknown_03005000.unk_ce8 = 1;
+ break;
+ }
+ }
+ }
+ DestroyTask(taskId);
+ }
+ break;
+ }
+}
+
+void sub_8010D0C(u8 taskId)
+{
+ if (gUnknown_03005000.unk_f1 == 1 || gUnknown_03005000.unk_f1 == 2)
+ DestroyTask(taskId);
+ switch (gTasks[taskId].data[0])
+ {
+ case 0:
+ if (gUnknown_03005000.playerCount)
+ {
+ sub_800B348();
+ SendBlock(0, gBlockSendBuffer, sizeof(struct LinkPlayerBlock));
+ gTasks[taskId].data[0]++;
+ }
+ break;
+ case 1:
+ if (sub_800A520())
+ gTasks[taskId].data[0]++;
+ break;
+ case 2:
+ if (GetBlockReceivedStatus() & 1)
+ {
+ sub_8010A14((const struct UnkRfuStruct_8010A14 *)gBlockRecvBuffer);
+ ResetBlockReceivedFlag(0);
+ gReceivedRemoteLinkPlayers = 1;
+ DestroyTask(taskId);
+ }
+ break;
+ }
+}
+
+void sub_8010DB4(void)
+{
+ if (gUnknown_03005000.unk_ee == 1 && gUnknown_03004140.unk_02 == 0)
+ {
+ if (gMain.callback2 == sub_8018438 || gUnknown_03004140.unk_3c->unk_04)
+ gWirelessCommType = 2;
+ SetMainCallback2(CB2_LinkError);
+ gMain.savedCallback = CB2_LinkError;
+ sub_800AF18((gUnknown_03005000.unk_0a << 16) | (gUnknown_03005000.unk_10 << 8) | gUnknown_03005000.unk_12, gUnknown_03005000.unk_124.unk_8c2, gUnknown_03005000.unk_9e8.unk_232, sub_8011A74() == 2);
+ gUnknown_03005000.unk_ee = 2;
+ CloseLink();
+ }
+ else if (gUnknown_03005000.unk_9e8.unk_233 == 1 || gUnknown_03005000.unk_124.unk_8c3 == 1)
+ {
+ if (gUnknown_03004140.unk_02)
+ sub_800D630();
+ sub_8011A64(1, 0x7000);
+ sub_8011170(0x7000);
+ }
+}
+
+void rfu_REQ_recvData_then_sendData(void)
+{
+ if (gUnknown_03004140.unk_06 == 1)
+ {
+ rfu_REQ_recvData();
+ rfu_waitREQComplete();
+ rfu_REQ_sendData_wrapper(0);
+ }
+}
+
+bool32 sub_8010EC0(void)
+{
+ bool32 retval = FALSE;
+ gUnknown_03005000.unk_ccd = 0;
+ sub_800C54C(Random2());
+ if (gUnknown_03005000.unk_ef == 0)
+ {
+ switch (gUnknown_03005000.unk_0c)
+ {
+ case 1:
+ sub_800F0F8();
+ break;
+ case 0:
+ retval = sub_800F4F0();
+ break;
+ case 2:
+ rfu_REQ_recvData_then_sendData();
+ break;
+ }
+ }
+ return retval;
+}
+
+bool32 sub_8010F1C(void)
+{
+ bool32 retval = FALSE;
+ if (gUnknown_03005000.unk_ef == 0)
+ {
+ if (gUnknown_03005000.unk_0c == 1)
+ retval = sub_800F1E0();
+ sub_8010DB4();
+ }
+ return retval;
+}
+
+void sub_8010F48(void)
+{
+ StringCopy(gUnknown_02022B22, gSaveBlock2Ptr->playerName);
+}
+
+void sub_8010F60(void)
+{
+ gUnknown_02022B14 = (struct UnkLinkRfuStruct_02022B14){};
+ sub_800DD94(&gUnknown_02022B14, 0, 0, 0);
+}
+
+void sub_8010F84(u8 a0, u32 a1, u32 a2)
+{
+ sub_800DD94(&gUnknown_02022B14, a0, a2, a1);
+}
+
+void sub_8010FA0(bool32 a0, bool32 a1)
+{
+ gUnknown_02022B14.unk_00_4 = a0;
+ gUnknown_02022B14.unk_00_5 = a1;
+}
+
+void sub_8010FCC(u32 a0, u32 a1, u32 a2)
+{
+ gUnknown_02022B14.unk_09_2 = a0;
+ gUnknown_02022B14.unk_08_0 = a1;
+ gUnknown_02022B14.unk_0b_1 = a2;
+}
+
+u8 sub_801100C(int a0)
+{
+ u8 retval = 0x80;
+ retval |= (gLinkPlayers[a0].gender << 3);
+ retval |= (gLinkPlayers[a0].trainerId & 7);
+ return retval;
+}
+
+void sub_801103C(void)
+{
+ struct UnkLinkRfuStruct_02022B14 *r5 = &gUnknown_02022B14;
+ int i;
+
+ for (i = 1; i < GetLinkPlayerCount(); i++)
+ r5->unk_04[i - 1] = sub_801100C(i);
+}
+
+void sub_8011068(u8 a0)
+{
+ gUnknown_02022B14.unk_0a_7 = a0;
+ rfu_REQ_configGameData(0, 2, &gUnknown_02022B14, gUnknown_02022B22);
+}
+
+void sub_8011090(u8 a0, u32 a1, u32 a2)
+{
+ if (a0)
+ sub_8010F84(a0, a1, a2);
+ rfu_REQ_configGameData(0, 2, &gUnknown_02022B14, gUnknown_02022B22);
+}
+
+void sub_80110B8(u32 a0)
+{
+ int i;
+ u32 r5;
+ u32 r7;
+ int r8;
+
+ if (sub_800F7DC()->unk_0a_0 == 0x45)
+ {
+ r5 = 0;
+ r7 = 0;
+ r8 = gUnknown_03005000.unk_ce2 ^ gUnknown_03005000.unk_ce3;
+ for (i = 0; i < 4; i++)
+ {
+ if ((r8 >> i) & 1)
+ {
+ r7 |= ((0x80 | ((gLinkPlayers[gUnknown_03005000.unk_cde[i]].gender & 1) << 3) | (gLinkPlayers[gUnknown_03005000.unk_cde[i]].trainerId & 7)) << (r5 << 3));
+ r5++;
+ if (r5 == a0 - 1)
+ break;
+ }
+ }
+ sub_8011090(0x45, r7, 0);
+ }
+}
+
+void sub_8011170(u32 a0)
+{
+ if (gUnknown_03005000.unk_ee == 0)
+ {
+ gUnknown_03005000.unk_10 = gUnknown_03004140.unk_14;
+ gUnknown_03005000.unk_12 = gUnknown_03004140.unk_16;
+ gUnknown_03005000.unk_0a = a0;
+ gUnknown_03005000.unk_ee = 1;
+ }
+}
+
+void sub_80111A0(void)
+{
+ gUnknown_03005000.unk_ee = 0;
+}
+
+void sub_80111B0(bool32 a0)
+{
+ if (!a0)
+ gUnknown_03005000.unk_ee = 0;
+ else
+ gUnknown_03005000.unk_ee = 4;
+}
+
+void sub_80111DC(void)
+{
+ sub_8011E94(gUnknown_03004140.unk_00, 1);
+ gUnknown_03005000.unk_00 = NULL;
+}
+
+void sub_80111FC(void)
+{
+ gUnknown_03005000.unk_00 = sub_80111DC;
+}
+
+#ifdef NONMATCHING
+void sub_801120C(u8 a0)
+{
+ u8 i;
+ u8 r6 = 0;
+ struct RfuUnk5Sub *unk5Sub;
+ switch (a0)
+ {
+ case 0x00:
+ gUnknown_03005000.unk_04 = 2;
+ break;
+ case 0x10:
+ break;
+ case 0x11:
+ sub_80115EC(gUnknown_03004140.unk_14);
+ for (i = 0; i < 4; i++)
+ {
+ if ((gUnknown_03004140.unk_14 >> i) & 1)
+ {
+ unk5Sub = &gUnknown_03007890->unk_14[i];
+ if (unk5Sub->unk_06.unk_0a_0 == sub_800F7DC()->unk_0a_0)
+ {
+ gUnknown_03005000.unk_cd1[i] = 0;
+ gUnknown_03005000.unk_cd5[i] = 0;
+ rfu_setRecvBuffer(0x20, i, gUnknown_03005000.unk_cd5 + i, 1);
+ }
+ else
+ {
+ r6 |= (1 << i);
+ }
+ }
+ }
+ if (r6)
+ {
+ rfu_REQ_disconnect(r6);
+ rfu_waitREQComplete();
+ }
+ break;
+ case 0x12:
+ break;
+ case 0x13:
+ break;
+ case 0x14:
+ if (gUnknown_03005000.unk_ce7 != gUnknown_03004140.unk_00)
+ {
+ rfu_REQ_disconnect(gUnknown_03005000.unk_ce7 ^ gUnknown_03004140.unk_00);
+ rfu_waitREQComplete();
+ }
+ gUnknown_03005000.unk_04 = 0x11;
+ break;
+ case 0x31:
+ gUnknown_03005000.unk_f0 = 1;
+ break;
+ case 0x32:
+ gUnknown_03005000.unk_f0 = 3;
+ break;
+ case 0x30:
+ case 0x33:
+ gUnknown_03005000.unk_f0 = 4;
+ gUnknown_03005000.unk_ce2 &= ~gUnknown_03004140.unk_14;
+ if (gReceivedRemoteLinkPlayers == 1)
+ {
+ if (gUnknown_03005000.unk_ce2 == 0)
+ sub_8011170(a0);
+ else
+ sub_80111FC();
+ }
+ sub_8011A64(2, a0);
+ break;
+ case 0x42 ... 0x44:
+ break;
+ case 0xf3:
+ sub_8011A64(1, a0);
+ sub_8011170(a0);
+ gUnknown_03005000.unk_ef = 1;
+ break;
+ case 0xf0 ... 0xf2:
+ case 0xff:
+ sub_8011170(a0);
+ sub_8011A64(1, a0);
+ gUnknown_03005000.unk_cdb = 1;
+ break;
+ }
+}
+#else
+NAKED void sub_801120C(u8 a0)
+{
+ asm_unified("\tpush {r4-r7,lr}\n"
+ "\tmov r7, r10\n"
+ "\tmov r6, r9\n"
+ "\tmov r5, r8\n"
+ "\tpush {r5-r7}\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r4, r0, 24\n"
+ "\tmovs r6, 0\n"
+ "\tcmp r4, 0x32\n"
+ "\tbne _08011222\n"
+ "\tb _08011360_case_32\n"
+ "_08011222:\n"
+ "\tcmp r4, 0x32\n"
+ "\tbgt _08011252\n"
+ "\tcmp r4, 0x13\n"
+ "\tbgt _08011240\n"
+ "\tcmp r4, 0x12\n"
+ "\tblt _08011230\n"
+ "\tb _080113EE_break\n"
+ "_08011230:\n"
+ "\tcmp r4, 0x10\n"
+ "\tbne _08011236\n"
+ "\tb _080113EE_break\n"
+ "_08011236:\n"
+ "\tcmp r4, 0x10\n"
+ "\tbgt _0801128C_case_11\n"
+ "\tcmp r4, 0\n"
+ "\tbeq _0801127E_case_00\n"
+ "\tb _080113EE_break\n"
+ "_08011240:\n"
+ "\tcmp r4, 0x30\n"
+ "\tbne _08011246\n"
+ "\tb _0801136C_case_30_case_33\n"
+ "_08011246:\n"
+ "\tcmp r4, 0x30\n"
+ "\tble _0801124C\n"
+ "\tb _08011354_case_31\n"
+ "_0801124C:\n"
+ "\tcmp r4, 0x14\n"
+ "\tbeq _08011328_case_14\n"
+ "\tb _080113EE_break\n"
+ "_08011252:\n"
+ "\tcmp r4, 0x44\n"
+ "\tbgt _08011264\n"
+ "\tcmp r4, 0x42\n"
+ "\tblt _0801125C\n"
+ "\tb _080113EE_break\n"
+ "_0801125C:\n"
+ "\tcmp r4, 0x33\n"
+ "\tbne _08011262\n"
+ "\tb _0801136C_case_30_case_33\n"
+ "_08011262:\n"
+ "\tb _080113EE_break\n"
+ "_08011264:\n"
+ "\tcmp r4, 0xF3\n"
+ "\tbne _0801126A\n"
+ "\tb _080113BA_case_f3\n"
+ "_0801126A:\n"
+ "\tcmp r4, 0xF3\n"
+ "\tbgt _08011276\n"
+ "\tcmp r4, 0xF0\n"
+ "\tbge _08011274\n"
+ "\tb _080113EE_break\n"
+ "_08011274:\n"
+ "\tb _080113D4_case_f0_f1_f2_ff\n"
+ "_08011276:\n"
+ "\tcmp r4, 0xFF\n"
+ "\tbne _0801127C\n"
+ "\tb _080113D4_case_f0_f1_f2_ff\n"
+ "_0801127C:\n"
+ "\tb _080113EE_break\n"
+ "_0801127E_case_00:\n"
+ "\tldr r1, =gUnknown_03005000\n"
+ "\tmovs r0, 0x2\n"
+ "\tstrh r0, [r1, 0x4]\n"
+ "\tb _080113EE_break\n"
+ "\t.pool\n"
+ "_0801128C_case_11:\n"
+ "\tldr r0, =gUnknown_03004140\n"
+ "\tldrh r0, [r0, 0x14]\n"
+ "\tbl sub_80115EC\n"
+ "\tmovs r5, 0\n"
+ "\tmovs r0, 0x1\n"
+ "\tmov r8, r0\n"
+ "\tldr r1, =gUnknown_03005000\n"
+ "\tmov r9, r1\n"
+ "\tldr r3, =0x00000cd5\n"
+ "\tadd r3, r9\n"
+ "\tmov r10, r3\n"
+ "\tmovs r7, 0x7F\n"
+ "_080112A6:\n"
+ "\tldr r0, =gUnknown_03004140\n"
+ "\tldrh r0, [r0, 0x14]\n"
+ "\tasrs r0, r5\n"
+ "\tmov r1, r8\n"
+ "\tands r0, r1\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _0801130E\n"
+ "\tldr r0, =gUnknown_03007890\n"
+ "\tlsls r1, r5, 5\n"
+ "\tadds r1, 0x14\n"
+ "\tldr r0, [r0]\n"
+ "\tadds r0, r1\n"
+ "\tldrb r0, [r0, 0x10]\n"
+ "\tadds r4, r7, 0\n"
+ "\tands r4, r0\n"
+ "\tbl sub_800F7DC\n"
+ "\tldrb r1, [r0, 0xA]\n"
+ "\tadds r0, r7, 0\n"
+ "\tands r0, r1\n"
+ "\tcmp r4, r0\n"
+ "\tbne _08011304\n"
+ "\tldr r0, =0x00000cd1\n"
+ "\tadd r0, r9\n"
+ "\tadds r0, r5, r0\n"
+ "\tmovs r1, 0\n"
+ "\tstrb r1, [r0]\n"
+ "\tmov r3, r10\n"
+ "\tadds r2, r5, r3\n"
+ "\tstrb r1, [r2]\n"
+ "\tmovs r0, 0x20\n"
+ "\tadds r1, r5, 0\n"
+ "\tmovs r3, 0x1\n"
+ "\tbl rfu_setRecvBuffer\n"
+ "\tb _0801130E\n"
+ "\t.pool\n"
+ "_08011304:\n"
+ "\tmov r0, r8\n"
+ "\tlsls r0, r5\n"
+ "\torrs r6, r0\n"
+ "\tlsls r0, r6, 24\n"
+ "\tlsrs r6, r0, 24\n"
+ "_0801130E:\n"
+ "\tadds r0, r5, 0x1\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r5, r0, 24\n"
+ "\tcmp r5, 0x3\n"
+ "\tbls _080112A6\n"
+ "\tcmp r6, 0\n"
+ "\tbeq _080113EE_break\n"
+ "\tadds r0, r6, 0\n"
+ "\tbl rfu_REQ_disconnect\n"
+ "\tbl rfu_waitREQComplete\n"
+ "\tb _080113EE_break\n"
+ "_08011328_case_14:\n"
+ "\tldr r4, =gUnknown_03005000\n"
+ "\tldr r1, =0x00000ce7\n"
+ "\tadds r0, r4, r1\n"
+ "\tldr r1, =gUnknown_03004140\n"
+ "\tldrb r2, [r0]\n"
+ "\tldrb r0, [r1]\n"
+ "\tcmp r2, r0\n"
+ "\tbeq _08011342\n"
+ "\teors r0, r2\n"
+ "\tbl rfu_REQ_disconnect\n"
+ "\tbl rfu_waitREQComplete\n"
+ "_08011342:\n"
+ "\tmovs r0, 0x11\n"
+ "\tstrh r0, [r4, 0x4]\n"
+ "\tb _080113EE_break\n"
+ "\t.pool\n"
+ "_08011354_case_31:\n"
+ "\tldr r0, =gUnknown_03005000\n"
+ "\tadds r0, 0xF0\n"
+ "\tb _080113EA\n"
+ "\t.pool\n"
+ "_08011360_case_32:\n"
+ "\tldr r0, =gUnknown_03005000\n"
+ "\tadds r0, 0xF0\n"
+ "\tmovs r1, 0x3\n"
+ "\tb _080113EC\n"
+ "\t.pool\n"
+ "_0801136C_case_30_case_33:\n"
+ "\tldr r1, =gUnknown_03005000\n"
+ "\tadds r2, r1, 0\n"
+ "\tadds r2, 0xF0\n"
+ "\tmovs r0, 0x4\n"
+ "\tstrb r0, [r2]\n"
+ "\tldr r3, =0x00000ce2\n"
+ "\tadds r1, r3\n"
+ "\tldr r0, =gUnknown_03004140\n"
+ "\tldrb r2, [r0, 0x14]\n"
+ "\tldrb r0, [r1]\n"
+ "\tadds r3, r0, 0\n"
+ "\tbics r3, r2\n"
+ "\tadds r2, r3, 0\n"
+ "\tstrb r2, [r1]\n"
+ "\tldr r0, =gReceivedRemoteLinkPlayers\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r0, 0x1\n"
+ "\tbne _080113B0\n"
+ "\tcmp r2, 0\n"
+ "\tbne _080113AC\n"
+ "\tadds r0, r4, 0\n"
+ "\tbl sub_8011170\n"
+ "\tb _080113B0\n"
+ "\t.pool\n"
+ "_080113AC:\n"
+ "\tbl sub_80111FC\n"
+ "_080113B0:\n"
+ "\tmovs r0, 0x2\n"
+ "\tadds r1, r4, 0\n"
+ "\tbl sub_8011A64\n"
+ "\tb _080113EE_break\n"
+ "_080113BA_case_f3:\n"
+ "\tmovs r0, 0x1\n"
+ "\tmovs r1, 0xF3\n"
+ "\tbl sub_8011A64\n"
+ "\tmovs r0, 0xF3\n"
+ "\tbl sub_8011170\n"
+ "\tldr r0, =gUnknown_03005000\n"
+ "\tadds r0, 0xEF\n"
+ "\tb _080113EA\n"
+ "\t.pool\n"
+ "_080113D4_case_f0_f1_f2_ff:\n"
+ "\tadds r0, r4, 0\n"
+ "\tbl sub_8011170\n"
+ "\tmovs r0, 0x1\n"
+ "\tadds r1, r4, 0\n"
+ "\tbl sub_8011A64\n"
+ "\tldr r0, =gUnknown_03005000\n"
+ "\tldr r1, =0x00000cdb\n"
+ "\tadds r0, r1\n"
+ "\tldrb r1, [r0]\n"
+ "_080113EA:\n"
+ "\tmovs r1, 0x1\n"
+ "_080113EC:\n"
+ "\tstrb r1, [r0]\n"
+ "_080113EE_break:\n"
+ "\tpop {r3-r5}\n"
+ "\tmov r8, r3\n"
+ "\tmov r9, r4\n"
+ "\tmov r10, r5\n"
+ "\tpop {r4-r7}\n"
+ "\tpop {r0}\n"
+ "\tbx r0\n"
+ "\t.pool");
+}
+#endif
diff --git a/src/list_menu.c b/src/list_menu.c
new file mode 100644
index 000000000..c78d32bb3
--- /dev/null
+++ b/src/list_menu.c
@@ -0,0 +1,633 @@
+#include "global.h"
+#include "menu.h"
+#include "list_menu.h"
+#include "window.h"
+#include "text_window.h"
+#include "main.h"
+#include "task.h"
+#include "menu_indicators.h"
+#include "strings.h"
+#include "sound.h"
+#include "constants/songs.h"
+
+struct UnknownMysteryGiftLinkMenuStruct
+{
+ s32 field_0;
+ u8 field_4;
+ u8 field_5;
+ u8 field_6;
+};
+
+struct UnknownListMenuPals
+{
+ u8 cursorPal:4;
+ u8 fillValue:4;
+ u8 cursorShadowPal:4;
+ u8 lettersSpacing:6;
+ u8 field_2_2:6; // unused
+ u8 fontId:7;
+ u8 field_3_7:1;
+};
+
+extern struct UnknownMysteryGiftLinkMenuStruct gUnknown_0203CE84;
+
+// this file's functions
+static u8 ListMenuInitInternal(struct ListMenuTemplate *listMenuTemplate, u16 scrollOffset, u16 selectedRow);
+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);
+static void ListMenuCallSelectionChangedCallback(struct ListMenu *list, u8 a2);
+static u8 ListMenuAddCursorObject(struct ListMenu *list, u32 cursorKind);
+
+// IWRAM common
+struct UnknownListMenuPals gUnknown_03006300;
+struct ListMenuTemplate gMultiuseListMenuTemplate;
+
+// code
+static void ListMenuDummyTask(u8 taskId)
+{
+
+}
+
+s32 DoMysteryGiftListMenu(struct WindowTemplate *windowTemplate, struct ListMenuTemplate *listMenuTemplate, u8 arg2, u16 tileNum, u16 palNum)
+{
+ switch (gUnknown_0203CE84.field_4)
+ {
+ case 0:
+ default:
+ gUnknown_0203CE84.field_5 = AddWindow(windowTemplate);
+ switch (arg2)
+ {
+ case 2:
+ sub_809882C(gUnknown_0203CE84.field_5, tileNum, palNum);
+ case 1:
+ sub_8098858(gUnknown_0203CE84.field_5, tileNum, palNum / 16);
+ break;
+ }
+ gMultiuseListMenuTemplate = *listMenuTemplate;
+ gMultiuseListMenuTemplate.windowId = gUnknown_0203CE84.field_5;
+ gUnknown_0203CE84.field_6 = ListMenuInit(&gMultiuseListMenuTemplate, 0, 0);
+ CopyWindowToVram(gUnknown_0203CE84.field_5, 1);
+ gUnknown_0203CE84.field_4 = 1;
+ break;
+ case 1:
+ gUnknown_0203CE84.field_0 = ListMenuHandleInputGetItemId(gUnknown_0203CE84.field_6);
+ if (gMain.newKeys & A_BUTTON)
+ {
+ gUnknown_0203CE84.field_4 = 2;
+ }
+ if (gMain.newKeys & B_BUTTON)
+ {
+ gUnknown_0203CE84.field_0 = LIST_B_PRESSED;
+ gUnknown_0203CE84.field_4 = 2;
+ }
+ if (gUnknown_0203CE84.field_4 == 2)
+ {
+ if (arg2 == 0)
+ {
+ ClearWindowTilemap(gUnknown_0203CE84.field_5);
+ }
+ else
+ {
+ switch (arg2)
+ {
+ case 0: // can never be reached, because of the if statement above
+ sub_819746C(gUnknown_0203CE84.field_5, FALSE);
+ break;
+ case 2:
+ case 1:
+ sub_819746C(gUnknown_0203CE84.field_5, FALSE);
+ break;
+ }
+ }
+
+ CopyWindowToVram(gUnknown_0203CE84.field_5, 1);
+ }
+ break;
+ case 2:
+ DestroyListMenuTask(gUnknown_0203CE84.field_6, NULL, NULL);
+ RemoveWindow(gUnknown_0203CE84.field_5);
+ gUnknown_0203CE84.field_4 = 0;
+ return gUnknown_0203CE84.field_0;
+ }
+
+ return -1;
+}
+
+u8 ListMenuInit(struct ListMenuTemplate *listMenuTemplate, u16 scrollOffset, u16 selectedRow)
+{
+ u8 taskId = ListMenuInitInternal(listMenuTemplate, scrollOffset, selectedRow);
+ PutWindowTilemap(listMenuTemplate->windowId);
+ CopyWindowToVram(listMenuTemplate->windowId, 2);
+
+ return taskId;
+}
+
+// unused
+u8 ListMenuInitWithWindows(struct ListMenuTemplate *listMenuTemplate, struct UnknownListMenuWindowStruct *arg1, u16 scrollOffset, u16 selectedRow)
+{
+ s32 i;
+
+ u8 taskId = ListMenuInitInternal(listMenuTemplate, scrollOffset, selectedRow);
+ for (i = 0; arg1[i].palNum != 0xFF; i++)
+ {
+ PutWindowRectTilemapOverridePalette(listMenuTemplate->windowId,
+ arg1[i].x,
+ arg1[i].y,
+ arg1[i].width,
+ arg1[i].height,
+ arg1[i].palNum);
+ }
+ CopyWindowToVram(listMenuTemplate->windowId, 2);
+
+ return taskId;
+}
+
+s32 ListMenuHandleInputGetItemId(u8 listTaskId)
+{
+ struct ListMenu *list = (void*) gTasks[listTaskId].data;
+
+ if (gMain.newKeys & A_BUTTON)
+ {
+ return list->template.items[list->scrollOffset + list->selectedRow].id;
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ return LIST_B_PRESSED;
+ }
+ else if (gMain.newAndRepeatedKeys & DPAD_UP)
+ {
+ ListMenuChangeSelection(list, TRUE, 1, FALSE);
+ return LIST_NOTHING_CHOSEN;
+ }
+ else if (gMain.newAndRepeatedKeys & DPAD_DOWN)
+ {
+ ListMenuChangeSelection(list, TRUE, 1, TRUE);
+ return LIST_NOTHING_CHOSEN;
+ }
+ else // try to move by one window scroll
+ {
+ bool16 rightButton, leftButton;
+ switch (list->template.scrollMultiple)
+ {
+ case LIST_NO_MULTIPLE_SCROLL:
+ default:
+ leftButton = FALSE;
+ rightButton = FALSE;
+ break;
+ case LIST_MULTIPLE_SCROLL_DPAD:
+ leftButton = gMain.newAndRepeatedKeys & DPAD_LEFT;
+ rightButton = gMain.newAndRepeatedKeys & DPAD_RIGHT;
+ break;
+ case LIST_MULTIPLE_SCROLL_L_R:
+ leftButton = gMain.newAndRepeatedKeys & L_BUTTON;
+ rightButton = gMain.newAndRepeatedKeys & R_BUTTON;
+ break;
+ }
+
+ if (leftButton)
+ {
+ ListMenuChangeSelection(list, TRUE, list->template.maxShowed, FALSE);
+ return LIST_NOTHING_CHOSEN;
+ }
+ else if (rightButton)
+ {
+ ListMenuChangeSelection(list, TRUE, list->template.maxShowed, TRUE);
+ return LIST_NOTHING_CHOSEN;
+ }
+ else
+ {
+ return LIST_NOTHING_CHOSEN;
+ }
+ }
+}
+
+void DestroyListMenuTask(u8 listTaskId, u16 *scrollOffset, u16 *selectedRow)
+{
+ struct ListMenu *list = (void*) gTasks[listTaskId].data;
+
+ if (scrollOffset != NULL)
+ *scrollOffset = list->scrollOffset;
+ if (selectedRow != NULL)
+ *selectedRow = list->selectedRow;
+
+ if (list->unk_1E != 0xFF)
+ ListMenuRemoveCursorObject(list->unk_1E, list->template.cursorKind - 2);
+
+ DestroyTask(listTaskId);
+}
+
+void sub_81AE70C(u8 listTaskId)
+{
+ struct ListMenu *list = (void*) gTasks[listTaskId].data;
+
+ FillWindowPixelBuffer(list->template.windowId, (list->template.fillValue << 4) | (list->template.fillValue));
+ ListMenuPrintEntries(list, list->scrollOffset, 0, list->template.maxShowed);
+ ListMenuDrawCursor(list);
+ CopyWindowToVram(list->template.windowId, 2);
+}
+
+// unused
+void ChangeListMenuPals(u8 listTaskId, u8 cursorPal, u8 fillValue, u8 cursorShadowPal)
+{
+ struct ListMenu *list = (void*) gTasks[listTaskId].data;
+
+ list->template.cursorPal = cursorPal;
+ list->template.fillValue = fillValue;
+ list->template.cursorShadowPal = cursorShadowPal;
+}
+
+// unused
+void ChangeListMenuCoords(u8 listTaskId, u8 x, u8 y)
+{
+ struct ListMenu *list = (void*) gTasks[listTaskId].data;
+
+ SetWindowAttribute(list->template.windowId, WINDOW_TILEMAP_LEFT, x);
+ SetWindowAttribute(list->template.windowId, WINDOW_TILEMAP_TOP, y);
+}
+
+// unused
+s32 ListMenuTestInput(struct ListMenuTemplate *template, u32 scrollOffset, u32 selectedRow, u16 keys, u16 *newScrollOffset, u16 *newSelectedRow)
+{
+ struct ListMenu list;
+
+ list.template = *template;
+ list.scrollOffset = scrollOffset;
+ list.selectedRow = selectedRow;
+ list.unk_1C = 0;
+ list.unk_1D = 0;
+
+ if (keys == DPAD_UP)
+ ListMenuChangeSelection(&list, FALSE, 1, FALSE);
+ if (keys == DPAD_DOWN)
+ ListMenuChangeSelection(&list, FALSE, 1, TRUE);
+
+ if (newScrollOffset != NULL)
+ *newScrollOffset = list.scrollOffset;
+ if (newSelectedRow != NULL)
+ *newSelectedRow = list.selectedRow;
+
+ return LIST_NOTHING_CHOSEN;
+}
+
+void ListMenuGetCurrentItemArrayId(u8 listTaskId, u16 *arrayId)
+{
+ struct ListMenu *list = (void*) gTasks[listTaskId].data;
+
+ if (arrayId != NULL)
+ *arrayId = list->scrollOffset + list->selectedRow;
+}
+
+void ListMenuGetScrollAndRow(u8 listTaskId, u16 *scrollOffset, u16 *selectedRow)
+{
+ struct ListMenu *list = (void*) gTasks[listTaskId].data;
+
+ if (scrollOffset != NULL)
+ *scrollOffset = list->scrollOffset;
+ if (selectedRow != NULL)
+ *selectedRow = list->selectedRow;
+}
+
+u16 ListMenuGetYCoordForPrintingArrowCursor(u8 listTaskId)
+{
+ struct ListMenu *list = (void*) gTasks[listTaskId].data;
+ u8 yMultiplier = GetFontAttribute(list->template.fontId, 1) + list->template.unk_16_3;
+
+ return list->selectedRow * yMultiplier + list->template.upText_Y;
+}
+
+static u8 ListMenuInitInternal(struct ListMenuTemplate *listMenuTemplate, u16 scrollOffset, u16 selectedRow)
+{
+ u8 listTaskId = CreateTask(ListMenuDummyTask, 0);
+ struct ListMenu *list = (void*) gTasks[listTaskId].data;
+
+ list->template = *listMenuTemplate;
+ list->scrollOffset = scrollOffset;
+ list->selectedRow = selectedRow;
+ list->unk_1C = 0;
+ list->unk_1D = 0;
+ list->unk_1E = 0xFF;
+ list->unk_1F = 0;
+
+ gUnknown_03006300.cursorPal = list->template.cursorPal;
+ gUnknown_03006300.fillValue = list->template.fillValue;
+ gUnknown_03006300.cursorShadowPal = list->template.cursorShadowPal;
+ gUnknown_03006300.lettersSpacing = list->template.lettersSpacing;
+ gUnknown_03006300.fontId = list->template.fontId;
+ gUnknown_03006300.field_3_7 = 0;
+
+ if (list->template.totalItems < list->template.maxShowed)
+ list->template.maxShowed = list->template.totalItems;
+
+ FillWindowPixelBuffer(list->template.windowId, (list->template.fillValue << 4) | (list->template.fillValue));
+ ListMenuPrintEntries(list, list->scrollOffset, 0, list->template.maxShowed);
+ ListMenuDrawCursor(list);
+ ListMenuCallSelectionChangedCallback(list, 1);
+
+ return listTaskId;
+}
+
+static void ListMenuPrint(struct ListMenu *list, const u8 *str, u8 x, u8 y)
+{
+ u8 colors[3];
+ if (gUnknown_03006300.field_3_7)
+ {
+ colors[0] = gUnknown_03006300.fillValue;
+ colors[1] = gUnknown_03006300.cursorPal;
+ colors[2] = gUnknown_03006300.cursorShadowPal;
+ AddTextPrinterParameterized2(list->template.windowId,
+ gUnknown_03006300.fontId,
+ x, y,
+ gUnknown_03006300.lettersSpacing,
+ 0, colors, TEXT_SPEED_FF, str);
+
+ gUnknown_03006300.field_3_7 = 0;
+ }
+ else
+ {
+ colors[0] = list->template.fillValue;
+ colors[1] = list->template.cursorPal;
+ colors[2] = list->template.cursorShadowPal;
+ AddTextPrinterParameterized2(list->template.windowId,
+ list->template.fontId,
+ x, y,
+ list->template.lettersSpacing,
+ 0, colors, TEXT_SPEED_FF, str);
+ }
+}
+
+static void ListMenuPrintEntries(struct ListMenu *list, u16 startIndex, u16 yOffset, u16 count)
+{
+ s32 i;
+ u8 x, y;
+ u8 yMultiplier = GetFontAttribute(list->template.fontId, 1) + list->template.unk_16_3;
+
+ for (i = 0; i < count; i++)
+ {
+ if (list->template.items[startIndex].id != -3)
+ x = list->template.unk_12;
+ else
+ x = list->template.unk_11;
+
+ y = (yOffset + i) * yMultiplier + list->template.upText_Y;
+ if (list->template.unk_08 != NULL)
+ list->template.unk_08(list->template.windowId, list->template.items[startIndex].id, y);
+
+ ListMenuPrint(list, list->template.items[startIndex].name, x, y);
+ startIndex++;
+ }
+}
+
+static void ListMenuDrawCursor(struct ListMenu *list)
+{
+ u8 yMultiplier = GetFontAttribute(list->template.fontId, 1) + list->template.unk_16_3;
+ u8 x = list->template.cursor_X;
+ u8 y = list->selectedRow * yMultiplier + list->template.upText_Y;
+ switch (list->template.cursorKind)
+ {
+ case 0:
+ ListMenuPrint(list, gText_SelectorArrow2, x, y);
+ break;
+ case 1:
+ break;
+ case 2:
+ if (list->unk_1E == 0xFF)
+ list->unk_1E = ListMenuAddCursorObject(list, 0);
+ ListMenuUpdateCursorObject(list->unk_1E,
+ GetWindowAttribute(list->template.windowId, WINDOW_TILEMAP_LEFT) * 8 - 1,
+ GetWindowAttribute(list->template.windowId, WINDOW_TILEMAP_TOP) * 8 + y - 1, 0);
+ break;
+ case 3:
+ if (list->unk_1E == 0xFF)
+ list->unk_1E = ListMenuAddCursorObject(list, 1);
+ ListMenuUpdateCursorObject(list->unk_1E,
+ GetWindowAttribute(list->template.windowId, WINDOW_TILEMAP_LEFT) * 8 + x,
+ GetWindowAttribute(list->template.windowId, WINDOW_TILEMAP_TOP) * 8 + y, 1);
+ break;
+ }
+}
+
+static u8 ListMenuAddCursorObject(struct ListMenu *list, u32 cursorKind)
+{
+ struct CursorStruct cursor;
+
+ cursor.unk0 = 0;
+ cursor.unk1 = 0xA0;
+ cursor.unk2 = GetWindowAttribute(list->template.windowId, WINDOW_WIDTH) * 8 + 2;
+ cursor.unk4 = GetFontAttribute(list->template.fontId, 1) + 2;
+ cursor.unk6 = 0x4000;
+ cursor.unk8 = 0xFFFF;
+ cursor.unkA = 0xF;
+
+ return ListMenuAddCursorObjectInternal(&cursor, cursorKind);
+}
+
+static void ListMenuErasePrintedCursor(struct ListMenu *list, u16 selectedRow)
+{
+ u8 cursorKind = list->template.cursorKind;
+ if (cursorKind == 0)
+ {
+ u8 yMultiplier = GetFontAttribute(list->template.fontId, 1) + list->template.unk_16_3;
+ u8 width = GetMenuCursorDimensionByFont(list->template.fontId, 0);
+ u8 height = GetMenuCursorDimensionByFont(list->template.fontId, 1);
+ FillWindowPixelRect(list->template.windowId,
+ (list->template.fillValue << 4) | (list->template.fillValue),
+ list->template.cursor_X,
+ selectedRow * yMultiplier + list->template.upText_Y,
+ width,
+ height);
+ }
+}
+
+static u8 ListMenuUpdateSelectedRowIndexAndScrollOffset(struct ListMenu *list, bool8 movingDown)
+{
+ u16 selectedRow = list->selectedRow;
+ u16 scrollOffset = list->scrollOffset;
+ u16 newRow;
+ u32 newScroll;
+
+ if (!movingDown)
+ {
+ if (list->template.maxShowed == 1)
+ newRow = 0;
+ else
+ newRow = list->template.maxShowed - ((list->template.maxShowed / 2) + (list->template.maxShowed % 2)) - 1;
+
+ if (scrollOffset == 0)
+ {
+ while (selectedRow != 0)
+ {
+ selectedRow--;
+ if (list->template.items[scrollOffset + selectedRow].id != -3)
+ {
+ list->selectedRow = selectedRow;
+ return 1;
+ }
+ }
+
+ return 0;
+ }
+ else
+ {
+ while (selectedRow > newRow)
+ {
+ selectedRow--;
+ if (list->template.items[scrollOffset + selectedRow].id != -3)
+ {
+ list->selectedRow = selectedRow;
+ return 1;
+ }
+ }
+
+ newScroll = scrollOffset - 1;
+ }
+ }
+ else
+ {
+ if (list->template.maxShowed == 1)
+ newRow = 0;
+ else
+ newRow = ((list->template.maxShowed / 2) + (list->template.maxShowed % 2));
+
+ if (scrollOffset == list->template.totalItems - list->template.maxShowed)
+ {
+ while (selectedRow < list->template.maxShowed - 1)
+ {
+ selectedRow++;
+ if (list->template.items[scrollOffset + selectedRow].id != -3)
+ {
+ list->selectedRow = selectedRow;
+ return 1;
+ }
+ }
+
+ return 0;
+ }
+ else
+ {
+ while (selectedRow < newRow)
+ {
+ selectedRow++;
+ if (list->template.items[scrollOffset + selectedRow].id != -3)
+ {
+ list->selectedRow = selectedRow;
+ return 1;
+ }
+ }
+
+ newScroll = scrollOffset + 1;
+ }
+ }
+
+ list->selectedRow = newRow;
+ list->scrollOffset = newScroll;
+ return 2;
+}
+
+static void ListMenuScroll(struct ListMenu *list, u8 count, bool8 movingDown)
+{
+ if (count >= list->template.maxShowed)
+ {
+ FillWindowPixelBuffer(list->template.windowId, (list->template.fillValue << 4) | (list->template.fillValue));
+ ListMenuPrintEntries(list, list->scrollOffset, 0, list->template.maxShowed);
+ }
+ else
+ {
+ u8 yMultiplier = GetFontAttribute(list->template.fontId, 1) + list->template.unk_16_3;
+
+ if (!movingDown)
+ {
+ u16 y, width, height;
+
+ ScrollWindow(list->template.windowId, 1, count * yMultiplier, (list->template.fillValue << 4) | (list->template.fillValue));
+ ListMenuPrintEntries(list, list->scrollOffset, 0, count);
+
+ y = (list->template.maxShowed * yMultiplier) + list->template.upText_Y;
+ width = GetWindowAttribute(list->template.windowId, WINDOW_WIDTH) * 8;
+ height = (GetWindowAttribute(list->template.windowId, WINDOW_HEIGHT) * 8) - y;
+ FillWindowPixelRect(list->template.windowId,
+ (list->template.fillValue << 4) | (list->template.fillValue),
+ 0, y, width, height);
+ }
+ else
+ {
+ u16 width;
+
+ ScrollWindow(list->template.windowId, 0, count * yMultiplier, (list->template.fillValue << 4) | (list->template.fillValue));
+ ListMenuPrintEntries(list, list->scrollOffset + (list->template.maxShowed - count), list->template.maxShowed - count, count);
+
+ width = GetWindowAttribute(list->template.windowId, WINDOW_WIDTH) * 8;
+ FillWindowPixelRect(list->template.windowId,
+ (list->template.fillValue << 4) | (list->template.fillValue),
+ 0, 0, width, list->template.upText_Y);
+ }
+ }
+}
+
+static bool8 ListMenuChangeSelection(struct ListMenu *list, bool8 updateCursorAndCallCallback, u8 count, bool8 movingDown)
+{
+ u16 oldSelectedRow;
+ u8 selectionChange, i, cursorCount;
+
+ oldSelectedRow = list->selectedRow;
+ cursorCount = 0;
+ selectionChange = 0;
+ for (i = 0; i < count; i++)
+ {
+ do
+ {
+ u8 ret = ListMenuUpdateSelectedRowIndexAndScrollOffset(list, movingDown);
+ selectionChange |= ret;
+ if (ret != 2)
+ break;
+ cursorCount++;
+ } while (list->template.items[list->scrollOffset + list->selectedRow].id == -3);
+ }
+
+ if (updateCursorAndCallCallback)
+ {
+ switch (selectionChange)
+ {
+ case 0:
+ default:
+ return TRUE;
+ case 1:
+ ListMenuErasePrintedCursor(list, oldSelectedRow);
+ ListMenuDrawCursor(list);
+ ListMenuCallSelectionChangedCallback(list, 0);
+ CopyWindowToVram(list->template.windowId, 2);
+ break;
+ case 2:
+ case 3:
+ ListMenuErasePrintedCursor(list, oldSelectedRow);
+ ListMenuScroll(list, cursorCount, movingDown);
+ ListMenuDrawCursor(list);
+ ListMenuCallSelectionChangedCallback(list, 0);
+ CopyWindowToVram(list->template.windowId, 2);
+ break;
+ }
+ }
+
+ return FALSE;
+}
+
+static void ListMenuCallSelectionChangedCallback(struct ListMenu *list, u8 a2)
+{
+ if (list->template.moveCursorFunc != NULL)
+ list->template.moveCursorFunc(list->template.items[list->scrollOffset + list->selectedRow].id, a2, list);
+}
+
+// unused
+void sub_81AF028(u8 cursorPal, u8 fillValue, u8 cursorShadowPal)
+{
+ gUnknown_03006300.cursorPal = cursorPal;
+ gUnknown_03006300.fillValue = fillValue;
+ gUnknown_03006300.cursorShadowPal = cursorShadowPal;
+ gUnknown_03006300.field_3_7 = 1;
+}
+
+void sub_81AF078(s32 arg0, u8 arg1, struct ListMenu *list)
+{
+ if (!arg1)
+ PlaySE(SE_SELECT);
+}
diff --git a/src/load_save.c b/src/load_save.c
index a516c08c2..917c1dfe1 100644
--- a/src/load_save.c
+++ b/src/load_save.c
@@ -4,33 +4,30 @@
#include "main.h"
#include "pokemon.h"
#include "random.h"
+#include "malloc.h"
+#include "item.h"
extern void* gUnknown_0203CF5C;
extern bool16 IdentifyFlash(void);
-extern void SetBagItemsPointers(void);
extern void SetDecorationInventoriesPointers(void);
extern void ApplyNewEncryptionKeyToGameStats(u32 key);
-extern void ApplyNewEncryptionKeyToBagItems(u32 newKey);
-extern void ApplyNewEncryptionKeyToBagItems_(u32 key);
extern void ApplyNewEncryptionKeyToBerryPowder(u32 key);
extern void sub_8084FAC(int unused);
-// this is probably wrong or misleading due to it being used in ResetHeap...
-extern void InitHeap(void *pointer, u32 size);
-
#define SAVEBLOCK_MOVE_RANGE 128
struct LoadedSaveData
{
- /*0x0000*/ struct ItemSlot items[30];
- /*0x0078*/ struct ItemSlot keyItems[30];
- /*0x00F0*/ struct ItemSlot pokeBalls[16];
- /*0x0130*/ struct ItemSlot TMsHMs[64];
- /*0x0230*/ struct ItemSlot berries[46];
+ /*0x0000*/ struct ItemSlot items[BAG_ITEMS_COUNT];
+ /*0x0078*/ struct ItemSlot keyItems[BAG_KEYITEMS_COUNT];
+ /*0x00F0*/ struct ItemSlot pokeBalls[BAG_POKEBALLS_COUNT];
+ /*0x0130*/ struct ItemSlot TMsHMs[BAG_TMHM_COUNT];
+ /*0x0230*/ struct ItemSlot berries[BAG_BERRIES_COUNT];
/*0x02E8*/ struct MailStruct mail[MAIL_COUNT];
};
+// EWRAM DATA
EWRAM_DATA struct SaveBlock2 gSaveblock2 = {0};
EWRAM_DATA u8 gSaveblock2_DMA[SAVEBLOCK_MOVE_RANGE] = {0};
@@ -43,8 +40,13 @@ EWRAM_DATA u8 gSaveblock3_DMA[SAVEBLOCK_MOVE_RANGE] = {0};
EWRAM_DATA struct LoadedSaveData gLoadedSaveData = {0};
EWRAM_DATA u32 gLastEncryptionKey = {0};
-void ApplyNewEncryptionKeyToAllEncryptedData(u32 encryptionKey);
+// IWRAM common
+IWRAM_DATA bool32 gFlashMemoryPresent;
+IWRAM_DATA struct SaveBlock1 *gSaveBlock1Ptr;
+IWRAM_DATA struct SaveBlock2 *gSaveBlock2Ptr;
+IWRAM_DATA struct PokemonStorage *gPokemonStoragePtr;
+// code
void CheckForFlashMemory(void)
{
if (!IdentifyFlash())
@@ -53,7 +55,9 @@ void CheckForFlashMemory(void)
InitFlashTimer();
}
else
+ {
gFlashMemoryPresent = FALSE;
+ }
}
void ClearSav2(void)
@@ -80,8 +84,6 @@ void SetSaveBlocksPointers(u16 offset)
SetDecorationInventoriesPointers();
}
-extern u8 gHeap[];
-
void MoveSaveBlocks_ResetHeap(void)
{
void *vblankCB, *hblankCB;
@@ -132,13 +134,12 @@ void MoveSaveBlocks_ResetHeap(void)
gSaveBlock2Ptr->encryptionKey = encryptionKey;
}
-
-u8 sav2_x1_query_bit1(void)
+u32 GetSecretBase2Field_9(void)
{
return gSaveBlock2Ptr->specialSaveWarp & 1;
}
-void sav2_x9_clear_bit1(void)
+void ClearSecretBase2Field_9(void)
{
gSaveBlock2Ptr->specialSaveWarp &= ~1;
}
@@ -159,112 +160,112 @@ void sav2_gender2_inplace_and_xFE(void)
gSaveBlock2Ptr->specialSaveWarp &= ~1;
}
-void copy_player_party_to_sav1(void) // SavePlayerParty
+void SavePlayerParty(void)
{
int i;
gSaveBlock1Ptr->playerPartyCount = gPlayerPartyCount;
- for (i = 0; i < 6; i++)
+ for (i = 0; i < PARTY_SIZE; i++)
gSaveBlock1Ptr->playerParty[i] = gPlayerParty[i];
}
-void copy_player_party_from_sav1(void) // LoadPlayerParty
+void LoadPlayerParty(void)
{
int i;
gPlayerPartyCount = gSaveBlock1Ptr->playerPartyCount;
- for (i = 0; i < 6; i++)
+ for (i = 0; i < PARTY_SIZE; i++)
gPlayerParty[i] = gSaveBlock1Ptr->playerParty[i];
}
-void save_serialize_npcs(void) // SaveMapObjects
+void SaveMapObjects(void)
{
int i;
- for (i = 0; i < 16; i++)
+ for (i = 0; i < MAP_OBJECTS_COUNT; i++)
gSaveBlock1Ptr->mapObjects[i] = gMapObjects[i];
}
-void save_deserialize_npcs(void) // LoadMapObjects
+void LoadMapObjects(void)
{
int i;
- for (i = 0; i < 16; i++)
+ for (i = 0; i < MAP_OBJECTS_COUNT; i++)
gMapObjects[i] = gSaveBlock1Ptr->mapObjects[i];
}
void SaveSerializedGame(void)
{
- copy_player_party_to_sav1();
- save_serialize_npcs();
+ SavePlayerParty();
+ SaveMapObjects();
}
void LoadSerializedGame(void)
{
- copy_player_party_from_sav1();
- save_deserialize_npcs();
+ LoadPlayerParty();
+ LoadMapObjects();
}
-void copy_bags_and_unk_data_from_save_blocks(void)
+void LoadPlayerBag(void)
{
int i;
// load player items.
- for (i = 0; i < 30; i++)
+ for (i = 0; i < BAG_ITEMS_COUNT; i++)
gLoadedSaveData.items[i] = gSaveBlock1Ptr->bagPocket_Items[i];
// load player key items.
- for (i = 0; i < 30; i++)
+ for (i = 0; i < BAG_KEYITEMS_COUNT; i++)
gLoadedSaveData.keyItems[i] = gSaveBlock1Ptr->bagPocket_KeyItems[i];
// load player pokeballs.
- for (i = 0; i < 16; i++)
+ for (i = 0; i < BAG_POKEBALLS_COUNT; i++)
gLoadedSaveData.pokeBalls[i] = gSaveBlock1Ptr->bagPocket_PokeBalls[i];
// load player TMs and HMs.
- for (i = 0; i < 64; i++)
+ for (i = 0; i < BAG_TMHM_COUNT; i++)
gLoadedSaveData.TMsHMs[i] = gSaveBlock1Ptr->bagPocket_TMHM[i];
// load player berries.
- for (i = 0; i < 46; i++)
+ for (i = 0; i < BAG_BERRIES_COUNT; i++)
gLoadedSaveData.berries[i] = gSaveBlock1Ptr->bagPocket_Berries[i];
// load mail.
- for (i = 0; i < 16; i++)
+ for (i = 0; i < MAIL_COUNT; i++)
gLoadedSaveData.mail[i] = gSaveBlock1Ptr->mail[i];
gLastEncryptionKey = gSaveBlock2Ptr->encryptionKey;
}
-void copy_bags_and_unk_data_to_save_blocks(void)
+void SavePlayerBag(void)
{
int i;
u32 encryptionKeyBackup;
// save player items.
- for (i = 0; i < 30; i++)
+ for (i = 0; i < BAG_ITEMS_COUNT; i++)
gSaveBlock1Ptr->bagPocket_Items[i] = gLoadedSaveData.items[i];
// save player key items.
- for (i = 0; i < 30; i++)
+ for (i = 0; i < BAG_KEYITEMS_COUNT; i++)
gSaveBlock1Ptr->bagPocket_KeyItems[i] = gLoadedSaveData.keyItems[i];
// save player pokeballs.
- for (i = 0; i < 16; i++)
+ for (i = 0; i < BAG_POKEBALLS_COUNT; i++)
gSaveBlock1Ptr->bagPocket_PokeBalls[i] = gLoadedSaveData.pokeBalls[i];
// save player TMs and HMs.
- for (i = 0; i < 64; i++)
+ for (i = 0; i < BAG_TMHM_COUNT; i++)
gSaveBlock1Ptr->bagPocket_TMHM[i] = gLoadedSaveData.TMsHMs[i];
// save player berries.
- for (i = 0; i < 46; i++)
+ for (i = 0; i < BAG_BERRIES_COUNT; i++)
gSaveBlock1Ptr->bagPocket_Berries[i] = gLoadedSaveData.berries[i];
// save mail.
- for (i = 0; i < 16; i++)
+ for (i = 0; i < MAIL_COUNT; i++)
gSaveBlock1Ptr->mail[i] = gLoadedSaveData.mail[i];
encryptionKeyBackup = gSaveBlock2Ptr->encryptionKey;
diff --git a/src/mail.c b/src/mail.c
index ac263ac67..8fddc7045 100644
--- a/src/mail.c
+++ b/src/mail.c
@@ -101,7 +101,7 @@ struct MailRead
/*0x021c*/ u8 monIconSprite;
/*0x021d*/ u8 language;
/*0x021e*/ bool8 playerIsSender;
- /*0x0220*/ void (*parserSingle)(u8 *dest, u16 word);
+ /*0x0220*/ u8 * (*parserSingle)(u8 *dest, u16 word);
/*0x0224*/ void (*parserMultiple)(u8 *dest, const u16 *src, u16 length1, u16 length2);
/*0x0228*/ const struct MailLayout *layout;
/*0x022c*/ u8 bg1TilemapBuffer[0x1000];
@@ -403,11 +403,11 @@ static bool8 MailReadBuildGraphics(void)
switch (sMailRead->animsActive)
{
case 1:
- sub_80D2F68(icon);
+ LoadMonIconPalette(icon);
sMailRead->monIconSprite = sub_80D2D78(icon, SpriteCallbackDummy, 0x60, 0x80, 0, 0);
break;
case 2:
- sub_80D2F68(icon);
+ LoadMonIconPalette(icon);
sMailRead->monIconSprite = sub_80D2D78(icon, SpriteCallbackDummy, 0x28, 0x80, 0, 0);
break;
}
@@ -540,7 +540,7 @@ static void CB2_ExitMailReadFreeVars(void)
{
case 1:
case 2:
- sub_80D2FF0(sub_80D2E84(sMailRead->mail->species));
+ FreeMonIconPalette(sub_80D2E84(sMailRead->mail->species));
sub_80D2EF8(&gSprites[sMailRead->monIconSprite]);
}
memset(sMailRead, 0, sizeof(*sMailRead));
diff --git a/src/main.c b/src/main.c
index d4601293b..f04f9b61b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,50 +1,32 @@
#include "global.h"
-#include "main.h"
+#include "crt0.h"
+#include "malloc.h"
+#include "link.h"
+#include "link_rfu.h"
+#include "librfu.h"
#include "m4a.h"
+#include "bg.h"
#include "rtc.h"
+#include "scanline_effect.h"
+#include "overworld.h"
+#include "play_time.h"
#include "random.h"
#include "dma3.h"
#include "gba/flash_internal.h"
+#include "load_save.h"
+#include "gpu_regs.h"
+#include "agb_flash.h"
+#include "sound.h"
#include "battle.h"
+#include "battle_controllers.h"
+#include "text.h"
+#include "intro.h"
+#include "main.h"
-extern u16 GetGpuReg(u8);
-extern void SetGpuReg(u8, u16);
-extern void LinkVSync(void);
-extern void sub_800E174(void);
extern void sub_800B9B8(void);
-extern void InitGpuRegManager(void);
-extern void sub_800E6D0(void);
-extern void CheckForFlashMemory(void);
-extern void InitMapMusic(void);
-extern void ResetBgs(void);
-extern void SetDefaultFontsPointer(void);
-extern void InitHeap(void *heapStart, u32 heapSize); // malloc.h
-extern void rfu_REQ_stopMode(void);
-extern void rfu_waitREQComplete(void);
-extern bool32 sub_8087634(void);
-extern bool32 sub_80875C8(void);
-extern void ClearSpriteCopyRequests(void);
-extern void PlayTimeCounter_Update(void);
-extern void MapMusicMain(void);
-extern void EnableInterrupts(u16);
-extern void sub_8033648(void);
-extern u16 SetFlashTimerIntr(u8 timerNum, void (**intrFunc)(void));
-extern void ScanlineEffect_Stop(void);
-
-extern struct SoundInfo gSoundInfo;
-extern u32 gFlashMemoryPresent;
-extern u32 IntrMain[];
-extern u8 gHeap[];
-extern struct SaveBlock2 gSaveblock2;
-extern struct PokemonStorage gPokemonStorage;
-extern u32 gBattleTypeFlags;
extern u8 gUnknown_03002748;
extern u32 *gUnknown_0203CF5C;
-void Timer3Intr(void);
-bool8 HandleLinkConnection(void);
-void c2_copyright_1(void);
-
static void VBlankIntr(void);
static void HBlankIntr(void);
static void VCountIntr(void);
@@ -79,19 +61,19 @@ const IntrFunc gIntrTableTemplate[] =
static u16 gUnknown_03000000;
-extern u16 gKeyRepeatStartDelay;
-extern u8 gUnknown_030022B4;
-extern struct Main gMain;
-extern u16 gKeyRepeatContinueDelay;
-extern u8 gSoftResetDisabled;
-extern IntrFunc gIntrTable[INTR_COUNT];
-extern bool8 gLinkVSyncDisabled;
-extern u32 IntrMain_Buffer[0x200];
-extern u8 gPcmDmaCounter;
+u16 gKeyRepeatStartDelay;
+bool8 gLinkTransferringData;
+struct Main gMain;
+u16 gKeyRepeatContinueDelay;
+bool8 gSoftResetDisabled;
+IntrFunc gIntrTable[INTR_COUNT];
+u8 gLinkVSyncDisabled;
+u32 IntrMain_Buffer[0x200];
+u8 gPcmDmaCounter;
-extern u16 gTrainerId;
+static EWRAM_DATA u16 gTrainerId = 0;
-EWRAM_DATA void (**gFlashTimerIntrFunc)(void) = NULL;
+//EWRAM_DATA void (**gFlashTimerIntrFunc)(void) = NULL;
static void UpdateLinkAndCallCallbacks(void);
static void InitMainCallbacks(void);
@@ -129,7 +111,7 @@ void AgbMain()
if (gFlashMemoryPresent != TRUE)
SetMainCallback2(NULL);
- gUnknown_030022B4 = 0;
+ gLinkTransferringData = FALSE;
gUnknown_03000000 = 0xFC0;
for (;;)
@@ -147,22 +129,22 @@ void AgbMain()
if (sub_8087634() == 1)
{
- gUnknown_030022B4 = 1;
+ gLinkTransferringData = TRUE;
UpdateLinkAndCallCallbacks();
- gUnknown_030022B4 = 0;
+ gLinkTransferringData = FALSE;
}
else
{
- gUnknown_030022B4 = 0;
+ gLinkTransferringData = FALSE;
UpdateLinkAndCallCallbacks();
if (sub_80875C8() == 1)
{
gMain.newKeys = 0;
ClearSpriteCopyRequests();
- gUnknown_030022B4 = 1;
+ gLinkTransferringData = TRUE;
UpdateLinkAndCallCallbacks();
- gUnknown_030022B4 = 0;
+ gLinkTransferringData = FALSE;
}
}
@@ -184,7 +166,7 @@ static void InitMainCallbacks(void)
gUnknown_0203CF5C = NULL;
gMain.vblankCounter2 = 0;
gMain.callback1 = NULL;
- SetMainCallback2(c2_copyright_1);
+ SetMainCallback2(CB2_InitCopyrightScreenAfterBootup);
gSaveBlock2Ptr = &gSaveblock2;
gPokemonStoragePtr = &gPokemonStorage;
}
@@ -335,10 +317,10 @@ extern void CopyBufferedValuesToGpuRegs(void);
static void VBlankIntr(void)
{
- if (gLinkVSyncDisabled != FALSE)
+ if (gWirelessCommType != 0)
+ RfuVSync();
+ else if (gLinkVSyncDisabled == FALSE)
LinkVSync();
- else if (gUnknown_03002748 == FALSE)
- sub_800B9B8();
gMain.vblankCounter1++;
diff --git a/src/main_menu.c b/src/main_menu.c
index 8608159c2..3d6c1df76 100644
--- a/src/main_menu.c
+++ b/src/main_menu.c
@@ -1,15 +1,1977 @@
// Includes
#include "global.h"
+#include "battle_dome_cards.h"
+#include "bg.h"
+#include "constants/flags.h"
+#include "constants/rgb.h"
+#include "constants/songs.h"
+#include "constants/species.h"
+#include "decompress.h"
+#include "event_data.h"
+#include "field_effect.h"
+#include "gpu_regs.h"
+#include "graphics.h"
+#include "international_string_util.h"
+#include "link.h"
+#include "main.h"
+#include "menu.h"
+#include "menu_indicators.h"
+#include "mystery_event_menu.h"
+#include "naming_screen.h"
+#include "option_menu.h"
+#include "overworld.h"
+#include "palette.h"
+#include "pokeball.h"
+#include "pokedex.h"
+#include "pokemon_3.h"
+#include "random.h"
+#include "rtc.h"
+#include "save.h"
+#include "scanline_effect.h"
+#include "sound.h"
+#include "sprite.h"
+#include "string.h"
+#include "strings.h"
+#include "string_util.h"
+#include "task.h"
+#include "text.h"
+#include "text_window.h"
+#include "title_screen.h"
+#include "window.h"
// Static type declarations
// Static RAM declarations
+EWRAM_DATA u8 gUnknown_02022D04 = 0;
+EWRAM_DATA u16 gUnknown_02022D06 = 0;
+
IWRAM_DATA u8 gUnknown_03000DD0;
// Static ROM declarations
+u32 InitMainMenu(bool8);
+void Task_MainMenuCheckSaveFile(u8);
+void Task_MainMenuCheckBattery(u8);
+void Task_WaitForSaveFileErrorWindow(u8);
+void CreateMainMenuErrorWindow(const u8*);
+void sub_8032250(const struct WindowTemplate*);
+void Task_DisplayMainMenu(u8);
+void Task_WaitForBatteryDryErrorWindow(u8);
+void fmt_savegame(void);
+void HighlightSelectedMainMenuItem(u8, u8, s16);
+void Task_HandleMainMenuInput(u8);
+void Task_HandleMainMenuAPressed(u8);
+void Task_HandleMainMenuBPressed(u8);
+void task_new_game_prof_birch_speech_1(u8);
+void Task_DisplayMainMenuInvalidActionError(u8);
+void AddBirchSpeechObjects(u8);
+void task_new_game_prof_birch_speech_2(u8);
+void sub_8031BAC(u8, u8);
+void sub_8031D34(u8, u8);
+void task_new_game_prof_birch_speech_3(u8);
+void unknown_rbox_to_vram(u8, u8);
+void sub_8032318(u8);
+void task_new_game_prof_birch_speech_4(u8);
+void task_new_game_prof_birch_speech_5(u8);
+void sub_80323A0(struct TextSubPrinter *printer, u16 a);
+void task_new_game_prof_birch_speech_6(u8);
+void sub_8030B14(u8);
+void task_new_game_prof_birch_speech_7(u8);
+void sub_8031ACC(u8, u8);
+void sub_8031C88(u8, u8);
+void task_new_game_prof_birch_speech_8(u8);
+void task_new_game_prof_birch_speech_9(u8);
+void task_new_game_prof_birch_speech_10(u8);
+void task_new_game_prof_birch_speech_11(u8);
+void LoadMainMenuWindowFrameTiles(u8, u16);
+void DrawMainMenuWindowBorder(const struct WindowTemplate*, u16);
+void Task_HighlightSelectedMainMenuItem(u8);
+void task_new_game_prof_birch_speech_12(u8);
+void task_new_game_prof_birch_speech_13(u8);
+void sub_8031D74(void);
+s8 sub_8031DB4(void);
+void sub_80322E0(u8, u8);
+void task_new_game_prof_birch_speech_14(u8);
+void sub_8030ED4(u8);
+void sub_8030F7C(u8);
+void task_new_game_prof_birch_speech_15(u8);
+void task_new_game_prof_birch_speech_16(u8);
+void task_new_game_prof_birch_speech_17(u8);
+void new_game_prof_birch_speech_part2_start(void);
+void set_default_player_name(u8);
+void task_new_game_prof_birch_speech_part2_3(u8);
+void task_new_game_prof_birch_speech_part2_4(u8);
+void sub_80323CC(u8, u8, u16, u16, u8, u8);
+void task_new_game_prof_birch_speech_part2_5(u8);
+void task_new_game_prof_birch_speech_part2_6(u8);
+void task_new_game_prof_birch_speech_part2_7(u8);
+void task_new_game_prof_birch_speech_part2_8(u8);
+void task_new_game_prof_birch_speech_part2_9(u8);
+void sub_80318D8(struct Sprite*);
+void task_new_game_prof_birch_speech_part2_10(u8);
+void task_new_game_prof_birch_speech_part2_11(u8);
+void task_new_game_prof_birch_speech_part2_12(u8);
+void nullsub_11();
+void task_new_game_prof_birch_speech_part2_1(u8);
+void fmt_time(void);
+void fmt_pokedex(void);
+void fmt_player(void);
+void fmt_badges(void);
+void sub_8032474(u8, u8, u8, u8, u8, u8);
+
// .rodata
+const u16 gUnknown_082FECFC[][16] = {
+ INCBIN_U16("graphics/birch_speech/bg0.gbapal"),
+ INCBIN_U16("graphics/birch_speech/bg1.gbapal")
+};
+
+const u8 gBirchIntroShadowGfx[] = INCBIN_U8("graphics/birch_speech/shadow.4bpp.lz");
+const u8 gUnknown_082FEEF0[] = INCBIN_U8("graphics/birch_speech/map.bin.lz");
+const u16 gUnknown_082FF018[] = INCBIN_U16("graphics/birch_speech/bg2.gbapal");
+const u16 gUnknown_082FF028[] = {0, 0, 0, 0, 0, 0, 0, 0};
+
+const struct WindowTemplate gUnknown_082FF038[] = {
+ {0, 2, 1, 26, 2, 15, 1},
+ {0, 2, 5, 26, 2, 15, 0x35}
+};
+
+const struct WindowTemplate gUnknown_082FF048[] = {
+ {0, 2, 1, 26, 6, 15, 1},
+ {0, 2, 9, 26, 2, 15, 0x9D},
+ {0, 2, 13, 26, 2, 15, 0xD1},
+ {0, 2, 17, 26, 2, 15, 0x105},
+ {0, 2, 21, 26, 2, 15, 0x139}
+};
+
+const struct WindowTemplate gUnknown_082FF070[] = {
+ {0, 2, 15, 26, 4, 15, 0x16D},
+ {0xFF, 0, 0, 0, 0, 0, 0}
+};
+
+const struct WindowTemplate gUnknown_082FF080[] = {
+ {0, 2, 15, 27, 4, 15, 1},
+ {0, 3, 5, 6, 4, 15, 0x6D},
+ {0, 3, 2, 9, 10, 15, 0x85},
+ {0xFF, 0, 0, 0, 0, 0, 0}
+};
+
+const u16 gMainMenuBgPal[] = INCBIN_U16("graphics/misc/main_menu_bg.gbapal");
+const u16 gMainMenuTextPal[] = INCBIN_U16("graphics/misc/main_menu_text.gbapal");
+
+const u8 gUnknown_082FF0E0[] = {10, 11, 12};
+const u8 gUnknown_082FF0E3[] = {10, 1, 12};
+
+const struct BgTemplate gUnknown_082FF0E8[] = {
+ {
+ .bg = 0,
+ .charBaseIndex = 2,
+ .mapBaseIndex = 30,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 0,
+ .baseTile = 0
+ },
+ {
+ .bg = 1,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 7,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 3,
+ .baseTile = 0
+ }
+};
+
+const struct BgTemplate gUnknown_082FF0F0 = {
+ .bg = 0,
+ .charBaseIndex = 3,
+ .mapBaseIndex = 30,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 0,
+ .baseTile = 0
+};
+
+const struct ArrowStruct gUnknown_082FF0F4 = {2, 0x78, 8, 3, 0x78, 0x98, 3, 4, 1, 1, 0};
+
+const union AffineAnimCmd gUnknown_082FF104[] = {
+ AFFINEANIMCMD_FRAME(-2, -2, 0, 0x30),
+ AFFINEANIMCMD_END
+};
+
+const union AffineAnimCmd *const gUnknown_082FF114 = gUnknown_082FF104;
+
+const struct MenuAction gUnknown_082FF118[] = {
+ {gText_BirchBoy, NULL},
+ {gText_BirchGirl, NULL}
+};
+
+const u8 *const gMalePresetNames[] = {
+ gText_DefaultNameStu,
+ gText_DefaultNameMilton,
+ gText_DefaultNameTom,
+ gText_DefaultNameKenny,
+ gText_DefaultNameReid,
+ gText_DefaultNameJude,
+ gText_DefaultNameJaxson,
+ gText_DefaultNameEaston,
+ gText_DefaultNameWalker,
+ gText_DefaultNameTeru,
+ gText_DefaultNameJohnny,
+ gText_DefaultNameBrett,
+ gText_DefaultNameSeth,
+ gText_DefaultNameTerry,
+ gText_DefaultNameCasey,
+ gText_DefaultNameDarren,
+ gText_DefaultNameLandon,
+ gText_DefaultNameCollin,
+ gText_DefaultNameStanley,
+ gText_DefaultNameQuincy
+};
+
+const u8 *const gFemalePresetNames[] = {
+ gText_DefaultNameKimmy,
+ gText_DefaultNameTiara,
+ gText_DefaultNameBella,
+ gText_DefaultNameJayla,
+ gText_DefaultNameAllie,
+ gText_DefaultNameLianna,
+ gText_DefaultNameSara,
+ gText_DefaultNameMonica,
+ gText_DefaultNameCamila,
+ gText_DefaultNameAubree,
+ gText_DefaultNameRuthie,
+ gText_DefaultNameHazel,
+ gText_DefaultNameNadine,
+ gText_DefaultNameTanja,
+ gText_DefaultNameYasmin,
+ gText_DefaultNameNicola,
+ gText_DefaultNameLillie,
+ gText_DefaultNameTerra,
+ gText_DefaultNameLucy,
+ gText_DefaultNameHalie
+};
+
// .text
+
+enum
+{
+ HAS_NO_SAVED_GAME, //NEW GAME, OPTION
+ HAS_SAVED_GAME, //CONTINUE, NEW GAME, OPTION
+ HAS_MYSTERY_GIFT, //CONTINUE, NEW GAME, MYSTERY EVENTS, OPTION
+ HAS_MYSTERY_EVENTS,
+};
+
+#define MAIN_MENU_BORDER_TILE 0x1D5
+
+void CB2_MainMenu(void)
+{
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+}
+
+void VBlankCB_MainMenu(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+void CB2_InitMainMenu(void)
+{
+ InitMainMenu(FALSE);
+}
+
+void CB2_ReinitMainMenu(void)
+{
+ InitMainMenu(TRUE);
+}
+
+u32 InitMainMenu(bool8 returningFromOptionsMenu)
+{
+ SetVBlankCallback(NULL);
+
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ SetGpuReg(REG_OFFSET_BG2CNT, 0);
+ SetGpuReg(REG_OFFSET_BG1CNT, 0);
+ SetGpuReg(REG_OFFSET_BG0CNT, 0);
+ SetGpuReg(REG_OFFSET_BG2HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG2VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG0HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG0VOFS, 0);
+
+ DmaFill16(3, 0, (void *)VRAM, VRAM_SIZE);
+ DmaFill32(3, 0, (void *)OAM, OAM_SIZE);
+ DmaFill16(3, 0, (void *)(PLTT + 2), PLTT_SIZE - 2);
+
+ ResetPaletteFade();
+ LoadPalette(gMainMenuBgPal, 0, 32);
+ LoadPalette(gMainMenuTextPal, 0xF0, 32);
+ ScanlineEffect_Stop();
+ ResetTasks();
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ if (returningFromOptionsMenu)
+ BeginNormalPaletteFade(-1, 0, 0x10, 0, 0x0000); // fade to black
+ else
+ BeginNormalPaletteFade(-1, 0, 0x10, 0, 0xFFFF); // fade to white
+ ResetBgsAndClearDma3BusyFlags(0);
+ InitBgsFromTemplates(0, gUnknown_082FF0E8, 2);
+ ChangeBgX(0, 0, 0);
+ ChangeBgY(0, 0, 0);
+ ChangeBgX(1, 0, 0);
+ ChangeBgY(1, 0, 0);
+ InitWindows(gUnknown_082FF038);
+ DeactivateAllTextPrinters();
+ LoadMainMenuWindowFrameTiles(0, MAIN_MENU_BORDER_TILE);
+
+ SetGpuReg(REG_OFFSET_WIN0H, 0);
+ SetGpuReg(REG_OFFSET_WIN0V, 0);
+ SetGpuReg(REG_OFFSET_WININ, 0);
+ SetGpuReg(REG_OFFSET_WINOUT, 0);
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+
+ EnableInterrupts(1);
+ SetVBlankCallback(VBlankCB_MainMenu);
+ SetMainCallback2(CB2_MainMenu);
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON | DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
+ ShowBg(0);
+ HideBg(1);
+ CreateTask(Task_MainMenuCheckSaveFile, 0);
+
+ return 0;
+}
+
+void Task_MainMenuCheckSaveFile(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+
+ if (!gPaletteFade.active)
+ {
+ SetGpuReg(REG_OFFSET_WIN0H, 0);
+ SetGpuReg(REG_OFFSET_WIN0V, 0);
+ SetGpuReg(REG_OFFSET_WININ, 17);
+ SetGpuReg(REG_OFFSET_WINOUT, 0x31);
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_DARKEN | BLDCNT_TGT1_BG0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BLDY, 7);
+
+ if (sub_80093CC())
+ data[15] = 1;
+ switch (gSaveFileStatus)
+ {
+ case 1:
+ data[0] = HAS_SAVED_GAME;
+ if (IsMysteryGiftEnabled())
+ data[0]++;
+ gTasks[taskId].func = Task_MainMenuCheckBattery;
+ break;
+ case 2:
+ CreateMainMenuErrorWindow(gText_SaveFileErased);
+ data[0] = 0;
+ gTasks[taskId].func = Task_WaitForSaveFileErrorWindow;
+ break;
+ case 0xFF:
+ CreateMainMenuErrorWindow(gText_SaveFileCorrupted);
+ gTasks[taskId].func = Task_WaitForSaveFileErrorWindow;
+ data[0] = HAS_SAVED_GAME;
+ if (IsMysteryGiftEnabled() == TRUE)
+ data[0]++;
+ break;
+ case 0:
+ default:
+ data[0] = HAS_NO_SAVED_GAME;
+ gTasks[taskId].func = Task_MainMenuCheckBattery;
+ break;
+ case 4:
+ CreateMainMenuErrorWindow(gJPText_No1MSubCircuit);
+ gTasks[taskId].data[0] = HAS_NO_SAVED_GAME;
+ gTasks[taskId].func = Task_WaitForSaveFileErrorWindow;
+ break;
+ }
+ if (gUnknown_02022D06 & 0x8000)
+ {
+ switch (data[0])
+ {
+ case HAS_NO_SAVED_GAME:
+ case HAS_SAVED_GAME:
+ gUnknown_02022D06 = data[0] + 1;
+ break;
+ case HAS_MYSTERY_GIFT:
+ gUnknown_02022D06 = 3;
+ break;
+ case 3:
+ gUnknown_02022D06 = 4;
+ break;
+ }
+ }
+ gUnknown_02022D06 &= 0x7FFF;
+ data[1] = gUnknown_02022D06;
+ data[12] = data[0] + 2;
+ }
+}
+
+void Task_WaitForSaveFileErrorWindow(u8 taskId)
+{
+ RunTextPrinters();
+ if (!IsTextPrinterActive(7) && (gMain.newKeys & A_BUTTON))
+ {
+ ClearWindowTilemap(7);
+ sub_8032250(gUnknown_082FF070);
+ gTasks[taskId].func = Task_MainMenuCheckBattery;
+ }
+}
+
+void Task_MainMenuCheckBattery(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ SetGpuReg(REG_OFFSET_WIN0H, 0);
+ SetGpuReg(REG_OFFSET_WIN0V, 0);
+ SetGpuReg(REG_OFFSET_WININ, 17);
+ SetGpuReg(REG_OFFSET_WINOUT, 0x31);
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_DARKEN | BLDCNT_TGT1_BG0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BLDY, 7);
+
+ if (!(RtcGetErrorStatus() & RTC_ERR_FLAG_MASK))
+ {
+ gTasks[taskId].func = Task_DisplayMainMenu;
+ }
+ else
+ {
+ CreateMainMenuErrorWindow(gText_BatteryRunDry);
+ gTasks[taskId].func = Task_WaitForBatteryDryErrorWindow;
+ }
+ }
+}
+
+void Task_WaitForBatteryDryErrorWindow(u8 taskId)
+{
+ RunTextPrinters();
+ if (!IsTextPrinterActive(7) && (gMain.newKeys & A_BUTTON))
+ {
+ ClearWindowTilemap(7);
+ sub_8032250(gUnknown_082FF070);
+ gTasks[taskId].func = Task_DisplayMainMenu;
+ }
+}
+
+void Task_DisplayMainMenu(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+ u16 palette;
+
+ if (!gPaletteFade.active)
+ {
+ SetGpuReg(REG_OFFSET_WIN0H, 0);
+ SetGpuReg(REG_OFFSET_WIN0V, 0);
+ SetGpuReg(REG_OFFSET_WININ, 17);
+ SetGpuReg(REG_OFFSET_WINOUT, 0x31);
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_DARKEN | BLDCNT_TGT1_BG0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BLDY, 7);
+
+ palette = RGB_BLACK;
+ LoadPalette(&palette, 254, 2);
+
+ palette = RGB_WHITE;
+ LoadPalette(&palette, 250, 2);
+
+ palette = RGB(12, 12, 12);
+ LoadPalette(&palette, 251, 2);
+
+ palette = RGB(26, 26, 25);
+ LoadPalette(&palette, 252, 2);
+
+ if (gSaveBlock2Ptr->playerGender == MALE)
+ {
+ palette = RGB(4, 16, 31);
+ LoadPalette(&palette, 241, 2);
+ }
+ else
+ {
+ palette = RGB(31, 3, 21);
+ LoadPalette(&palette, 241, 2);
+ }
+
+ switch (gTasks[taskId].data[0])
+ {
+ case HAS_NO_SAVED_GAME:
+ default:
+ FillWindowPixelBuffer(0, 0xAA);
+ FillWindowPixelBuffer(1, 0xAA);
+ box_print(0, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuNewGame);
+ box_print(1, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuOption);
+ PutWindowTilemap(0);
+ PutWindowTilemap(1);
+ CopyWindowToVram(0, 2);
+ CopyWindowToVram(1, 2);
+ DrawMainMenuWindowBorder(gUnknown_082FF038, MAIN_MENU_BORDER_TILE);
+ DrawMainMenuWindowBorder(&gUnknown_082FF038[1], MAIN_MENU_BORDER_TILE);
+ break;
+ case HAS_SAVED_GAME:
+ FillWindowPixelBuffer(2, 0xAA);
+ FillWindowPixelBuffer(3, 0xAA);
+ FillWindowPixelBuffer(4, 0xAA);
+ box_print(2, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuContinue);
+ box_print(3, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuNewGame);
+ box_print(4, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuOption);
+ fmt_savegame();
+ PutWindowTilemap(2);
+ PutWindowTilemap(3);
+ PutWindowTilemap(4);
+ CopyWindowToVram(2, 2);
+ CopyWindowToVram(3, 2);
+ CopyWindowToVram(4, 2);
+ DrawMainMenuWindowBorder(gUnknown_082FF048, MAIN_MENU_BORDER_TILE);
+ DrawMainMenuWindowBorder(&gUnknown_082FF048[1], MAIN_MENU_BORDER_TILE);
+ DrawMainMenuWindowBorder(&gUnknown_082FF048[2], MAIN_MENU_BORDER_TILE);
+ break;
+ case HAS_MYSTERY_GIFT:
+ FillWindowPixelBuffer(2, 0xAA);
+ FillWindowPixelBuffer(3, 0xAA);
+ FillWindowPixelBuffer(4, 0xAA);
+ FillWindowPixelBuffer(5, 0xAA);
+ box_print(2, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuContinue);
+ box_print(3, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuNewGame);
+ box_print(4, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuMysteryGift);
+ box_print(5, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuOption);
+ fmt_savegame();
+ PutWindowTilemap(2);
+ PutWindowTilemap(3);
+ PutWindowTilemap(4);
+ PutWindowTilemap(5);
+ CopyWindowToVram(2, 2);
+ CopyWindowToVram(3, 2);
+ CopyWindowToVram(4, 2);
+ CopyWindowToVram(5, 2);
+ DrawMainMenuWindowBorder(gUnknown_082FF048, MAIN_MENU_BORDER_TILE);
+ DrawMainMenuWindowBorder(&gUnknown_082FF048[1], MAIN_MENU_BORDER_TILE);
+ DrawMainMenuWindowBorder(&gUnknown_082FF048[2], MAIN_MENU_BORDER_TILE);
+ DrawMainMenuWindowBorder(&gUnknown_082FF048[3], MAIN_MENU_BORDER_TILE);
+ break;
+ case HAS_MYSTERY_EVENTS:
+ FillWindowPixelBuffer(2, 0xAA);
+ FillWindowPixelBuffer(3, 0xAA);
+ FillWindowPixelBuffer(4, 0xAA);
+ FillWindowPixelBuffer(5, 0xAA);
+ FillWindowPixelBuffer(6, 0xAA);
+ box_print(2, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuContinue);
+ box_print(3, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuNewGame);
+ box_print(4, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuMysteryGift2);
+ box_print(5, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuMysteryEvents);
+ box_print(6, 1, 0, 1, gUnknown_082FF0E0, -1, gText_MainMenuOption);
+ fmt_savegame();
+ PutWindowTilemap(2);
+ PutWindowTilemap(3);
+ PutWindowTilemap(4);
+ PutWindowTilemap(5);
+ PutWindowTilemap(6);
+ CopyWindowToVram(2, 2);
+ CopyWindowToVram(3, 2);
+ CopyWindowToVram(4, 2);
+ CopyWindowToVram(5, 2);
+ CopyWindowToVram(6, 2);
+ DrawMainMenuWindowBorder(gUnknown_082FF048, MAIN_MENU_BORDER_TILE);
+ DrawMainMenuWindowBorder(&gUnknown_082FF048[1], MAIN_MENU_BORDER_TILE);
+ DrawMainMenuWindowBorder(&gUnknown_082FF048[2], MAIN_MENU_BORDER_TILE);
+ DrawMainMenuWindowBorder(&gUnknown_082FF048[3], MAIN_MENU_BORDER_TILE);
+ DrawMainMenuWindowBorder(&gUnknown_082FF048[4], MAIN_MENU_BORDER_TILE);
+ data[13] = AddScrollIndicatorArrowPair(&gUnknown_082FF0F4, &gUnknown_02022D06);
+ gTasks[data[13]].func = Task_ScrollIndicatorArrowPairOnMainMenu;
+ if (gUnknown_02022D06 == 4)
+ {
+ ChangeBgY(0, 0x2000, 1);
+ ChangeBgY(1, 0x2000, 1);
+ data[14] = 1;
+ gTasks[data[13]].data[15] = 1;
+ }
+ break;
+ }
+ gTasks[taskId].func = Task_HighlightSelectedMainMenuItem;
+ }
+}
+
+void Task_HighlightSelectedMainMenuItem(u8 taskId)
+{
+ HighlightSelectedMainMenuItem(gTasks[taskId].data[0], gTasks[taskId].data[1], gTasks[taskId].data[14]);
+ gTasks[taskId].func = Task_HandleMainMenuInput;
+}
+
+bool8 HandleMainMenuInput(u8 taskId)
+{
+ s16* data = gTasks[taskId].data;
+
+ if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ sub_80093CC();
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, RGB_BLACK);
+ gTasks[taskId].func = Task_HandleMainMenuAPressed;
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, RGB_WHITEALPHA);
+ SetGpuReg(REG_OFFSET_WIN0H, 0xF0);
+ SetGpuReg(REG_OFFSET_WIN0V, 0xA0);
+ gTasks[taskId].func = Task_HandleMainMenuBPressed;
+ }
+ else if ((gMain.newKeys & DPAD_UP) && data[1] > 0)
+ {
+ if (data[0] == 3 && data[14] == 1 && data[1] == 1)
+ {
+ ChangeBgY(0, 0x2000, 2);
+ ChangeBgY(1, 0x2000, 2);
+ gTasks[data[13]].data[15] = data[14] = 0;
+ }
+ data[1]--;
+ gUnknown_02022D06 = data[1];
+ return TRUE;
+ }
+ else if ((gMain.newKeys & DPAD_DOWN) && data[1] < data[12] - 1)
+ {
+ if (data[0] == 3 && data[1] == 3 && data[14] == 0)
+ {
+ ChangeBgY(0, 0x2000, 1);
+ ChangeBgY(1, 0x2000, 1);
+ gTasks[data[13]].data[15] = data[14] = 1;
+ }
+ data[1]++;
+ gUnknown_02022D06 = data[1];
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void Task_HandleMainMenuInput(u8 taskId)
+{
+ if (HandleMainMenuInput(taskId))
+ gTasks[taskId].func = Task_HighlightSelectedMainMenuItem;
+}
+
+void Task_HandleMainMenuAPressed(u8 taskId)
+{
+ bool8 r2;
+ u8 action;
+
+ if (!gPaletteFade.active)
+ {
+ if (gTasks[taskId].data[0] == 3)
+ RemoveScrollIndicatorArrowPair(gTasks[taskId].data[13]);
+ sub_819746C(0, 1);
+ sub_819746C(1, 1);
+ sub_819746C(2, 1);
+ sub_819746C(3, 1);
+ sub_819746C(4, 1);
+ sub_819746C(5, 1);
+ sub_819746C(6, 1);
+ sub_819746C(7, 1);
+ r2 = sub_80093CC();
+ switch (gTasks[taskId].data[0])
+ {
+ case HAS_NO_SAVED_GAME:
+ default:
+ switch (gTasks[taskId].data[1])
+ {
+ case 0:
+ default:
+ action = 0;
+ break;
+ case 1:
+ action = 2;
+ break;
+ }
+ break;
+ case HAS_SAVED_GAME:
+ switch (gTasks[taskId].data[1])
+ {
+ case 0:
+ default:
+ action = 1;
+ break;
+ case 1:
+ action = 0;
+ break;
+ case 2:
+ action = 2;
+ break;
+ }
+ break;
+ case HAS_MYSTERY_GIFT:
+ switch (gTasks[taskId].data[1])
+ {
+ case 0:
+ default:
+ action = 1;
+ break;
+ case 1:
+ action = 0;
+ break;
+ case 2:
+ action = 3;
+ if (r2 == FALSE)
+ {
+ action = 6;
+ gTasks[taskId].data[0] = 0;
+ }
+ break;
+ case 3:
+ action = 2;
+ break;
+ }
+ break;
+ case HAS_MYSTERY_EVENTS:
+ switch (gTasks[taskId].data[1])
+ {
+ case 0:
+ default:
+ action = 1;
+ break;
+ case 1:
+ action = 0;
+ break;
+ case 2:
+ if (gTasks[taskId].data[15])
+ {
+ action = 3;
+ if (r2 == FALSE)
+ {
+ action = 6;
+ gTasks[taskId].data[0] = 0;
+ }
+ }
+ else if (r2)
+ {
+ action = 6;
+ gTasks[taskId].data[0] = 1;
+ }
+ else
+ {
+ action = 5;
+ }
+ break;
+ case 3:
+ if (r2)
+ {
+ action = 6;
+ gTasks[taskId].data[0] = 2;
+ }
+ else
+ {
+ action = 4;
+ }
+ break;
+ case 4:
+ action = 2;
+ break;
+ }
+ break;
+ }
+ ChangeBgY(0, 0, 0);
+ ChangeBgY(1, 0, 0);
+ switch (action)
+ {
+ case 0:
+ default:
+ gPlttBufferUnfaded[0] = RGB_BLACK;
+ gPlttBufferFaded[0] = RGB_BLACK;
+ gTasks[taskId].func = task_new_game_prof_birch_speech_1;
+ break;
+ case 1:
+ gPlttBufferUnfaded[0] = RGB_BLACK;
+ gPlttBufferFaded[0] = RGB_BLACK;
+ SetMainCallback2(CB2_ContinueSavedGame);
+ DestroyTask(taskId);
+ break;
+ case 2:
+ gMain.savedCallback = CB2_ReinitMainMenu;
+ SetMainCallback2(CB2_InitOptionMenu);
+ DestroyTask(taskId);
+ break;
+ case 3:
+ SetMainCallback2(c2_mystery_gift);
+ DestroyTask(taskId);
+ break;
+ case 4:
+ SetMainCallback2(CB2_InitMysteryEventMenu);
+ DestroyTask(taskId);
+ break;
+ case 5:
+ SetMainCallback2(sub_801867C);
+ DestroyTask(taskId);
+ break;
+ case 6:
+ gTasks[taskId].data[1] = 0;
+ gTasks[taskId].func = Task_DisplayMainMenuInvalidActionError;
+ gPlttBufferUnfaded[0xF1] = RGB_WHITE;
+ gPlttBufferFaded[0xF1] = RGB_WHITE;
+ SetGpuReg(REG_OFFSET_BG2HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG2VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG0HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG0VOFS, 0);
+ BeginNormalPaletteFade(-1, 0, 16, 0, 0);
+ return;
+ }
+ FreeAllWindowBuffers();
+ if (action != 2)
+ gUnknown_02022D06 = 0;
+ else
+ gUnknown_02022D06 |= 0x8000;
+ }
+}
+
+void Task_HandleMainMenuBPressed(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ if (gTasks[taskId].data[0] == 3)
+ RemoveScrollIndicatorArrowPair(gTasks[taskId].data[13]);
+ gUnknown_02022D06 = 0;
+ FreeAllWindowBuffers();
+ SetMainCallback2(CB2_InitTitleScreen);
+ DestroyTask(taskId);
+ }
+}
+
+void Task_DisplayMainMenuInvalidActionError(u8 taskId)
+{
+ switch (gTasks[taskId].data[1])
+ {
+ case 0:
+ FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 30, 20);
+ switch (gTasks[taskId].data[0])
+ {
+ case 0:
+ CreateMainMenuErrorWindow(gText_WirelessNotConnected);
+ break;
+ case 1:
+ CreateMainMenuErrorWindow(gText_MysteryGiftCantUse);
+ break;
+ case 2:
+ CreateMainMenuErrorWindow(gText_MysteryEventsCantUse);
+ break;
+ }
+ gTasks[taskId].data[1]++;
+ break;
+ case 1:
+ if (!gPaletteFade.active)
+ gTasks[taskId].data[1]++;
+ break;
+ case 2:
+ RunTextPrinters();
+ if (!IsTextPrinterActive(7))
+ gTasks[taskId].data[1]++;
+ break;
+ case 3:
+ if (gMain.newKeys & (A_BUTTON | B_BUTTON))
+ {
+ PlaySE(SE_SELECT);
+ BeginNormalPaletteFade(-1, 0, 0, 16, RGB_BLACK);
+ gTasks[taskId].func = Task_HandleMainMenuBPressed;
+ }
+ }
+}
+
+void HighlightSelectedMainMenuItem(u8 menuType, u8 selectedMenuItem, s16 a)
+{
+ SetGpuReg(REG_OFFSET_WIN0H, 0x9E7);
+
+ switch (menuType)
+ {
+ case HAS_NO_SAVED_GAME:
+ default:
+ switch (selectedMenuItem)
+ {
+ case 0:
+ default:
+ SetGpuReg(REG_OFFSET_WIN0V, 0x11F);
+ break;
+ case 1:
+ SetGpuReg(REG_OFFSET_WIN0V, 0x213F);
+ break;
+ }
+ break;
+ case HAS_SAVED_GAME:
+ switch (selectedMenuItem)
+ {
+ case 0:
+ default:
+ SetGpuReg(REG_OFFSET_WIN0V, 0x13F);
+ break;
+ case 1:
+ SetGpuReg(REG_OFFSET_WIN0V, 0x415F);
+ break;
+ case 2:
+ SetGpuReg(REG_OFFSET_WIN0V, 0x617F);
+ break;
+ }
+ break;
+ case HAS_MYSTERY_GIFT:
+ switch (selectedMenuItem)
+ {
+ case 0:
+ default:
+ SetGpuReg(REG_OFFSET_WIN0V, 0x13F);
+ break;
+ case 1:
+ SetGpuReg(REG_OFFSET_WIN0V, 0x415F);
+ break;
+ case 2:
+ SetGpuReg(REG_OFFSET_WIN0V, 0x617F);
+ break;
+ case 3:
+ SetGpuReg(REG_OFFSET_WIN0V, 0x819F);
+ break;
+ }
+ break;
+ case HAS_MYSTERY_EVENTS:
+ switch (selectedMenuItem)
+ {
+ case 0:
+ default:
+ SetGpuReg(REG_OFFSET_WIN0V, 0x13F);
+ break;
+ case 1:
+ if (a)
+ SetGpuReg(REG_OFFSET_WIN0V, 0x213F);
+ else
+ SetGpuReg(REG_OFFSET_WIN0V, 0x415F);
+ break;
+ case 2:
+ if (a)
+ SetGpuReg(REG_OFFSET_WIN0V, 0x415F);
+ else
+ SetGpuReg(REG_OFFSET_WIN0V, 0x617F);
+ break;
+ case 3:
+ if (a)
+ SetGpuReg(REG_OFFSET_WIN0V, 0x617F);
+ else
+ SetGpuReg(REG_OFFSET_WIN0V, 0x819F);
+ break;
+ case 4:
+ SetGpuReg(REG_OFFSET_WIN0V, 0x819F);
+ break;
+ }
+ break;
+ }
+}
+
+void task_new_game_prof_birch_speech_1(u8 taskId)
+{
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
+ InitBgFromTemplate(&gUnknown_082FF0F0);
+ SetGpuReg(REG_OFFSET_WIN0H, 0);
+ SetGpuReg(REG_OFFSET_WIN0V, 0);
+ SetGpuReg(REG_OFFSET_WININ, 0);
+ SetGpuReg(REG_OFFSET_WINOUT, 0);
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+
+ LZ77UnCompVram(gBirchIntroShadowGfx, (void*)VRAM);
+ LZ77UnCompVram(gUnknown_082FEEF0, (void*)(VRAM + 0x3800));
+ LoadPalette(gUnknown_082FECFC, 0, 64);
+ LoadPalette(gUnknown_082FF028, 1, 16);
+ ScanlineEffect_Stop();
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ dp13_810BB8C();
+ AddBirchSpeechObjects(taskId);
+ BeginNormalPaletteFade(-1, 0, 16, 0, 0);
+ gTasks[taskId].data[4] = 0;
+ gTasks[taskId].func = task_new_game_prof_birch_speech_2;
+ gTasks[taskId].data[2] = 0xFF;
+ gTasks[taskId].data[3] = 0xFF;
+ gTasks[taskId].data[7] = 0xD8;
+ PlayBGM(MUS_DOORO_X4);
+ ShowBg(0);
+ ShowBg(1);
+}
+
+void task_new_game_prof_birch_speech_2(u8 taskId)
+{
+ u8 spriteId;
+
+ if (gTasks[taskId].data[7])
+ {
+ gTasks[taskId].data[7]--;
+ }
+ else
+ {
+ spriteId = gTasks[taskId].data[8];
+ gSprites[spriteId].pos1.x = 0x88;
+ gSprites[spriteId].pos1.y = 0x3C;
+ gSprites[spriteId].invisible = 0;
+ gSprites[spriteId].oam.objMode = 1;
+ sub_8031BAC(taskId, 10);
+ sub_8031D34(taskId, 20);
+ gTasks[taskId].data[7] = 0x50;
+ gTasks[taskId].func = task_new_game_prof_birch_speech_3;
+ }
+}
+
+void task_new_game_prof_birch_speech_3(u8 taskId)
+{
+ if (gTasks[taskId].data[5])
+ {
+ gSprites[gTasks[taskId].data[8]].oam.objMode = 0;
+ if (gTasks[taskId].data[7])
+ {
+ gTasks[taskId].data[7]--;
+ }
+ else
+ {
+ InitWindows(gUnknown_082FF080);
+ LoadMainMenuWindowFrameTiles(0, 0xF3);
+ copy_textbox_border_tile_patterns_to_vram(0, 0xFC, 0xF0);
+ unknown_rbox_to_vram(0, 1);
+ PutWindowTilemap(0);
+ CopyWindowToVram(0, 2);
+ sub_8032318(0);
+ StringExpandPlaceholders(gStringVar4, gText_Birch_Welcome);
+ AddTextPrinterForMessage(1);
+ gTasks[taskId].func = task_new_game_prof_birch_speech_4;
+ }
+ }
+}
+
+void task_new_game_prof_birch_speech_4(u8 taskId)
+{
+ if (!gPaletteFade.active && !sub_8197224())
+ {
+ gTasks[taskId].func = task_new_game_prof_birch_speech_5;
+ StringExpandPlaceholders(gStringVar4, gText_ThisIsAPokemon);
+ AddTextPrinterWithCallbackForMessage(1, sub_80323A0);
+ gUnknown_03000DD0 = taskId;
+ }
+}
+
+void task_new_game_prof_birch_speech_5(u8 taskId)
+{
+ if (!sub_8197224())
+ {
+ StringExpandPlaceholders(gStringVar4, gText_Birch_MainSpeech);
+ AddTextPrinterForMessage(1);
+ gTasks[taskId].func = task_new_game_prof_birch_speech_6;
+ }
+}
+
+void sub_8030A70(u8 taskId)
+{
+ u8 spriteId = gTasks[gUnknown_03000DD0].data[9];
+
+ gSprites[spriteId].pos1.x = 0x64;
+ gSprites[spriteId].pos1.y = 0x4B;
+ gSprites[spriteId].invisible = 0;
+ gSprites[spriteId].data[0] = 0;
+
+ CreatePokeballSpriteToReleaseMon(spriteId, gSprites[spriteId].oam.paletteNum, 0x70, 0x3A, 0, 0, 0x20, 0xFFFF, SPECIES_LOTAD);
+ gTasks[taskId].func = sub_8030B14;
+ gTasks[gUnknown_03000DD0].data[7] = 0;
+}
+
+void sub_8030B14(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ struct Sprite *sprite = &gSprites[gTasks[gUnknown_03000DD0].data[9]];
+
+ switch (data[0])
+ {
+ case 0:
+ if (sprite->callback == SpriteCallbackDummy)
+ {
+ sprite->oam.affineMode = 0;
+ goto _08030B98_inc_data0;
+ }
+ break;
+ case 1:
+ if (gTasks[gUnknown_03000DD0].data[7] >= 0x60)
+ {
+ DestroyTask(taskId);
+ if (gTasks[gUnknown_03000DD0].data[7] < 0x4000)
+ gTasks[gUnknown_03000DD0].data[7]++;
+ }
+ break;
+ _08030B98_inc_data0:
+ default:
+ data[0]++;
+ if (gTasks[gUnknown_03000DD0].data[7] < 0x4000)
+ gTasks[gUnknown_03000DD0].data[7]++;
+ break;
+ }
+}
+
+void task_new_game_prof_birch_speech_6(u8 taskId)
+{
+ if (!sub_8197224())
+ {
+ gUnknown_02022D04 = 0;
+ StringExpandPlaceholders(gStringVar4, gText_Birch_AndYouAre);
+ AddTextPrinterForMessage(1);
+ gTasks[taskId].func = task_new_game_prof_birch_speech_7;
+ }
+}
+
+void task_new_game_prof_birch_speech_7(u8 taskId)
+{
+ if (!sub_8197224())
+ {
+ gSprites[gTasks[taskId].data[8]].oam.objMode = 1;
+ gSprites[gTasks[taskId].data[9]].oam.objMode = 1;
+ sub_8031ACC(taskId, 2);
+ sub_8031C88(taskId, 1);
+ gTasks[taskId].data[7] = 0x40;
+ gTasks[taskId].func = task_new_game_prof_birch_speech_8;
+ }
+}
+
+void task_new_game_prof_birch_speech_8(u8 taskId)
+{
+ if (gTasks[taskId].data[4] != -60)
+ {
+ gTasks[taskId].data[4] -= 2;
+ SetGpuReg(REG_OFFSET_BG1HOFS, gTasks[taskId].data[4]);
+ }
+ else
+ {
+ gTasks[taskId].data[4] = -60;
+ gTasks[taskId].func = task_new_game_prof_birch_speech_9;
+ }
+}
+
+void task_new_game_prof_birch_speech_9(u8 taskId)
+{
+ if (gTasks[taskId].data[5])
+ {
+ gSprites[gTasks[taskId].data[8]].invisible = 1;
+ gSprites[gTasks[taskId].data[9]].invisible = 1;
+ if (gTasks[taskId].data[7])
+ {
+ gTasks[taskId].data[7]--;
+ }
+ else
+ {
+ u8 spriteId = gTasks[taskId].data[10];
+
+ gSprites[spriteId].pos1.x = 0xB4;
+ gSprites[spriteId].pos1.y = 0x3C;
+ gSprites[spriteId].invisible = 0;
+ gSprites[spriteId].oam.objMode = 1;
+ gTasks[taskId].data[2] = spriteId;
+ gTasks[taskId].data[6] = 0;
+ sub_8031BAC(taskId, 2);
+ sub_8031D34(taskId, 1);
+ gTasks[taskId].func = task_new_game_prof_birch_speech_10;
+ }
+ }
+}
+
+void task_new_game_prof_birch_speech_10(u8 taskId)
+{
+ if (gTasks[taskId].data[5])
+ {
+ gSprites[gTasks[taskId].data[2]].oam.objMode = 0;
+ gTasks[taskId].func = task_new_game_prof_birch_speech_11;
+ }
+}
+
+void task_new_game_prof_birch_speech_11(u8 taskId)
+{
+ sub_8032318(0);
+ StringExpandPlaceholders(gStringVar4, gText_Birch_BoyOrGirl);
+ AddTextPrinterForMessage(1);
+ gTasks[taskId].func = task_new_game_prof_birch_speech_12;
+}
+
+void task_new_game_prof_birch_speech_12(u8 taskId)
+{
+ if (!sub_8197224())
+ {
+ sub_8031D74();
+ gTasks[taskId].func = task_new_game_prof_birch_speech_13;
+ }
+}
+
+void task_new_game_prof_birch_speech_13(u8 taskId)
+{
+ int gender = sub_8031DB4();
+ int r3;
+
+ switch (gender)
+ {
+ case MALE:
+ PlaySE(SE_SELECT);
+ gSaveBlock2Ptr->playerGender = gender;
+ sub_80322E0(1, 1);
+ gTasks[taskId].func = task_new_game_prof_birch_speech_14;
+ break;
+ case FEMALE:
+ PlaySE(SE_SELECT);
+ gSaveBlock2Ptr->playerGender = gender;
+ sub_80322E0(1, 1);
+ gTasks[taskId].func = task_new_game_prof_birch_speech_14;
+ break;
+ }
+ r3 = GetMenuCursorPos();
+ if (r3 != gTasks[taskId].data[6])
+ {
+ gTasks[taskId].data[6] = r3;
+ gSprites[gTasks[taskId].data[2]].oam.objMode = 1;
+ sub_8031ACC(taskId, 0);
+ gTasks[taskId].func = sub_8030ED4;
+ }
+}
+
+void sub_8030ED4(u8 taskId)
+{
+ u8 spriteId = gTasks[taskId].data[2];
+ if (gTasks[taskId].data[5] == 0)
+ {
+ gSprites[spriteId].pos1.x += 4;
+ }
+ else
+ {
+ gSprites[spriteId].invisible = 1;
+ if (gTasks[taskId].data[6])
+ spriteId = gTasks[taskId].data[11];
+ else
+ spriteId = gTasks[taskId].data[10];
+ gSprites[spriteId].pos1.x = 0xF0;
+ gSprites[spriteId].pos1.y = 0x3C;
+ gSprites[spriteId].invisible = 0;
+ gTasks[taskId].data[2] = spriteId;
+ gSprites[spriteId].oam.objMode = 1;
+ sub_8031BAC(taskId, 0);
+ gTasks[taskId].func = sub_8030F7C;
+ }
+}
+
+void sub_8030F7C(u8 taskId)
+{
+ u8 spriteId = gTasks[taskId].data[2];
+
+ if (gSprites[spriteId].pos1.x > 0xB4)
+ {
+ gSprites[spriteId].pos1.x -= 4;
+ }
+ else
+ {
+ gSprites[spriteId].pos1.x = 0xB4;
+ if (gTasks[taskId].data[5])
+ {
+ gSprites[spriteId].oam.objMode = 0;
+ gTasks[taskId].func = task_new_game_prof_birch_speech_13;
+ }
+ }
+}
+
+void task_new_game_prof_birch_speech_14(u8 taskId)
+{
+ sub_8032318(0);
+ StringExpandPlaceholders(gStringVar4, gText_Birch_WhatsYourName);
+ AddTextPrinterForMessage(1);
+ gTasks[taskId].func = task_new_game_prof_birch_speech_15;
+}
+
+void task_new_game_prof_birch_speech_15(u8 taskId)
+{
+ if (!sub_8197224())
+ gTasks[taskId].func = task_new_game_prof_birch_speech_16;
+}
+
+void task_new_game_prof_birch_speech_16(u8 taskId)
+{
+ if ((gMain.newKeys & A_BUTTON) || (gMain.newKeys & B_BUTTON))
+ {
+ BeginNormalPaletteFade(-1, 0, 0, 16, RGB_BLACK);
+ gTasks[taskId].func = task_new_game_prof_birch_speech_17;
+ }
+}
+
+void task_new_game_prof_birch_speech_17(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ FreeAllWindowBuffers();
+ sub_818D820(gTasks[taskId].data[9]);
+ set_default_player_name(Random() % 20);
+ DestroyTask(taskId);
+ DoNamingScreen(0, gSaveBlock2Ptr->playerName, gSaveBlock2Ptr->playerGender, 0, 0, new_game_prof_birch_speech_part2_start);
+ }
+}
+
+void task_new_game_prof_birch_speech_part2_2(u8 taskId)
+{
+ sub_8032318(0);
+ StringExpandPlaceholders(gStringVar4, gText_Birch_SoItsPlayer);
+ AddTextPrinterForMessage(1);
+ gTasks[taskId].func = task_new_game_prof_birch_speech_part2_3;
+}
+
+void task_new_game_prof_birch_speech_part2_3(u8 taskId)
+{
+ if (!sub_8197224())
+ {
+ sub_80323CC(2, 1, 0xF3, 0xDF, 2, 15);
+ gTasks[taskId].func = task_new_game_prof_birch_speech_part2_4;
+ }
+}
+
+void task_new_game_prof_birch_speech_part2_4(u8 taskId)
+{
+ switch (ProcessMenuInputNoWrap_())
+ {
+ case 0:
+ PlaySE(SE_SELECT);
+ gSprites[gTasks[taskId].data[2]].oam.objMode = 1;
+ sub_8031ACC(taskId, 2);
+ sub_8031C88(taskId, 1);
+ gTasks[taskId].func = task_new_game_prof_birch_speech_part2_5;
+ break;
+ case -1:
+ case 1:
+ PlaySE(SE_SELECT);
+ gTasks[taskId].func = task_new_game_prof_birch_speech_11;
+ }
+}
+
+void task_new_game_prof_birch_speech_part2_5(u8 taskId)
+{
+ if (gTasks[taskId].data[4])
+ {
+ gTasks[taskId].data[4] += 2;
+ SetGpuReg(REG_OFFSET_BG1HOFS, gTasks[taskId].data[4]);
+ }
+ else
+ {
+ gTasks[taskId].func = task_new_game_prof_birch_speech_part2_6;
+ }
+}
+
+void task_new_game_prof_birch_speech_part2_6(u8 taskId)
+{
+ u8 spriteId;
+
+ if (gTasks[taskId].data[5])
+ {
+ gSprites[gTasks[taskId].data[10]].invisible = TRUE;
+ gSprites[gTasks[taskId].data[11]].invisible = TRUE;
+ spriteId = gTasks[taskId].data[8];
+ gSprites[spriteId].pos1.x = 0x88;
+ gSprites[spriteId].pos1.y = 0x3C;
+ gSprites[spriteId].invisible = FALSE;
+ gSprites[spriteId].oam.objMode = 1;
+ spriteId = gTasks[taskId].data[9];
+ gSprites[spriteId].pos1.x = 0x64;
+ gSprites[spriteId].pos1.y = 0x4B;
+ gSprites[spriteId].invisible = FALSE;
+ gSprites[spriteId].oam.objMode = 1;
+ sub_8031BAC(taskId, 2);
+ sub_8031D34(taskId, 1);
+ sub_8032318(0);
+ StringExpandPlaceholders(gStringVar4, gText_Birch_YourePlayer);
+ AddTextPrinterForMessage(1);
+ gTasks[taskId].func = task_new_game_prof_birch_speech_part2_7;
+ }
+}
+
+void task_new_game_prof_birch_speech_part2_7(u8 taskId)
+{
+ if (gTasks[taskId].data[5])
+ {
+ gSprites[gTasks[taskId].data[8]].oam.objMode = 0;
+ gSprites[gTasks[taskId].data[9]].oam.objMode = 0;
+ if (!sub_8197224())
+ {
+ gSprites[gTasks[taskId].data[8]].oam.objMode = 1;
+ gSprites[gTasks[taskId].data[9]].oam.objMode = 1;
+ sub_8031ACC(taskId, 2);
+ sub_8031C88(taskId, 1);
+ gTasks[taskId].data[7] = 64;
+ gTasks[taskId].func = task_new_game_prof_birch_speech_part2_8;
+ }
+ }
+}
+
+void task_new_game_prof_birch_speech_part2_8(u8 taskId)
+{
+ u8 spriteId;
+
+ if (gTasks[taskId].data[5])
+ {
+ gSprites[gTasks[taskId].data[8]].invisible = 1;
+ gSprites[gTasks[taskId].data[9]].invisible = 1;
+ if (gTasks[taskId].data[7])
+ {
+ gTasks[taskId].data[7]--;
+ return;
+ }
+ if (gSaveBlock2Ptr->playerGender != MALE)
+ spriteId = gTasks[taskId].data[11];
+ else
+ spriteId = gTasks[taskId].data[10];
+ gSprites[spriteId].pos1.x = 0x78;
+ gSprites[spriteId].pos1.y = 0x3C;
+ gSprites[spriteId].invisible = 0;
+ gSprites[spriteId].oam.objMode = 1;
+ gTasks[taskId].data[2] = spriteId;
+ sub_8031BAC(taskId, 2);
+ sub_8031D34(taskId, 1);
+ StringExpandPlaceholders(gStringVar4, gText_Birch_AreYouReady);
+ AddTextPrinterForMessage(1);
+ gTasks[taskId].func = task_new_game_prof_birch_speech_part2_9;
+ }
+}
+
+void task_new_game_prof_birch_speech_part2_9(u8 taskId)
+{
+ u8 spriteId;
+
+ if (gTasks[taskId].data[5])
+ {
+ gSprites[gTasks[taskId].data[2]].oam.objMode = 0;
+ if (!sub_8197224())
+ {
+ spriteId = gTasks[taskId].data[2];
+ gSprites[spriteId].oam.affineMode = 1;
+ gSprites[spriteId].affineAnims = &gUnknown_082FF114;
+ InitSpriteAffineAnim(&gSprites[spriteId]);
+ StartSpriteAffineAnim(&gSprites[spriteId], 0);
+ gSprites[spriteId].callback = sub_80318D8;
+ BeginNormalPaletteFade(0x0000FFFF, 0, 0, 16, RGB_BLACK);
+ FadeOutBGM(4);
+ gTasks[taskId].func = task_new_game_prof_birch_speech_part2_10;
+ }
+ }
+}
+
+void task_new_game_prof_birch_speech_part2_10(u8 taskId)
+{
+ u8 spriteId = gTasks[taskId].data[2];
+
+ if (gSprites[spriteId].affineAnimEnded)
+ gTasks[taskId].func = task_new_game_prof_birch_speech_part2_11;
+}
+
+void task_new_game_prof_birch_speech_part2_11(u8 taskId)
+{
+ u8 spriteId;
+
+ if (!gPaletteFade.active)
+ {
+ spriteId = gTasks[taskId].data[2];
+ gSprites[spriteId].callback = nullsub_11;
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
+ BeginNormalPaletteFade(0xFFFF0000, 0, 0, 16, RGB_WHITEALPHA);
+ gTasks[taskId].func = task_new_game_prof_birch_speech_part2_12;
+ }
+}
+
+void task_new_game_prof_birch_speech_part2_12(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ FreeAllWindowBuffers();
+ sub_818D820(gTasks[taskId].data[9]);
+ dp13_810BB8C();
+ SetMainCallback2(CB2_NewGame);
+ DestroyTask(taskId);
+ }
+}
+
+void new_game_prof_birch_speech_part2_start(void)
+{
+ u8 taskId;
+ u8 spriteId;
+ u16 savedIme;
+
+ ResetBgsAndClearDma3BusyFlags(0);
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
+ InitBgsFromTemplates(0, gUnknown_082FF0E8, 2);
+ InitBgFromTemplate(&gUnknown_082FF0F0);
+ SetVBlankCallback(NULL);
+ SetGpuReg(REG_OFFSET_BG2CNT, 0);
+ SetGpuReg(REG_OFFSET_BG1CNT, 0);
+ SetGpuReg(REG_OFFSET_BG0CNT, 0);
+ SetGpuReg(REG_OFFSET_BG2HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG2VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG0HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG0VOFS, 0);
+ DmaFill16(3, 0, VRAM, VRAM_SIZE);
+ DmaFill32(3, 0, OAM, OAM_SIZE);
+ DmaFill16(3, 0, PLTT, PLTT_SIZE);
+ ResetPaletteFade();
+ LZ77UnCompVram(gBirchIntroShadowGfx, (u8*)VRAM);
+ LZ77UnCompVram(gUnknown_082FEEF0, (u8*)(VRAM + 0x3800));
+ LoadPalette(gUnknown_082FECFC, 0, 64);
+ LoadPalette(&gUnknown_082FF018[1], 1, 16);
+ ResetTasks();
+ taskId = CreateTask(task_new_game_prof_birch_speech_part2_1, 0);
+ gTasks[taskId].data[7] = 5;
+ gTasks[taskId].data[4] = -60;
+ ScanlineEffect_Stop();
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ dp13_810BB8C();
+ AddBirchSpeechObjects(taskId);
+ if (gSaveBlock2Ptr->playerGender != MALE)
+ {
+ gTasks[taskId].data[6] = FEMALE;
+ spriteId = gTasks[taskId].data[11];
+ }
+ else
+ {
+ gTasks[taskId].data[6] = MALE;
+ spriteId = gTasks[taskId].data[10];
+ }
+ gSprites[spriteId].pos1.x = 0xB4;
+ gSprites[spriteId].pos1.y = 0x3C;
+ gSprites[spriteId].invisible = 0;
+ gTasks[taskId].data[2] = spriteId;
+ SetGpuReg(REG_OFFSET_BG1HOFS, -60);
+ BeginNormalPaletteFade(-1, 0, 16, 0, 0);
+ SetGpuReg(REG_OFFSET_WIN0H, 0);
+ SetGpuReg(REG_OFFSET_WIN0V, 0);
+ SetGpuReg(REG_OFFSET_WININ, 0);
+ SetGpuReg(REG_OFFSET_WINOUT, 0);
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ ShowBg(0);
+ ShowBg(1);
+ savedIme = REG_IME;
+ REG_IME = 0;
+ REG_IE |= 1;
+ REG_IME = savedIme;
+ SetVBlankCallback(VBlankCB_MainMenu);
+ SetMainCallback2(CB2_MainMenu);
+ InitWindows(gUnknown_082FF080);
+ LoadMainMenuWindowFrameTiles(0, 0xF3);
+ copy_textbox_border_tile_patterns_to_vram(0, 0xFC, 0xF0);
+ PutWindowTilemap(0);
+ CopyWindowToVram(0, 3);
+}
+
+void nullsub_11(struct Sprite *sprite)
+{
+}
+
+void sub_80318D8(struct Sprite *sprite)
+{
+ u32 y;
+
+ y = (sprite->pos1.y << 16) + sprite->data[0] + 0xC000;
+ sprite->pos1.y = y >> 16;
+ sprite->data[0] = y;
+}
+
+u8 sub_80318F4(u8 a, u8 b)
+{
+ return sub_818D3E4(SPECIES_LOTAD, 8, 0, 1, a, b, 14, -1);
+}
+
+void AddBirchSpeechObjects(u8 taskId)
+{
+ u8 spriteId = AddNewGameBirchObject(0x88, 0x3C, 1);
+ u8 spriteId2;
+ u8 spriteId3;
+ u8 spriteId4;
+
+ gSprites[spriteId].callback = nullsub_11;
+ gSprites[spriteId].oam.priority = 0;
+ gSprites[spriteId].invisible = TRUE;
+ gTasks[taskId].data[8] = spriteId;
+ spriteId2 = sub_80318F4(100, 0x4B);
+ gSprites[spriteId2].callback = nullsub_11;
+ gSprites[spriteId2].oam.priority = 0;
+ gSprites[spriteId2].invisible = TRUE;
+ gTasks[taskId].data[9] = spriteId2;
+ spriteId3 = CreateTrainerSprite(FacilityClassToPicIndex(0x3C), 0x78, 0x3C, 0, gDecompressionBuffer);
+ gSprites[spriteId3].callback = nullsub_11;
+ gSprites[spriteId3].invisible = TRUE;
+ gSprites[spriteId3].oam.priority = 0;
+ gTasks[taskId].data[10] = spriteId3;
+ spriteId4 = CreateTrainerSprite(FacilityClassToPicIndex(0x3F), 0x78, 0x3C, 0, &gDecompressionBuffer[0x800]);
+ gSprites[spriteId4].callback = nullsub_11;
+ gSprites[spriteId4].invisible = TRUE;
+ gSprites[spriteId4].oam.priority = 0;
+ gTasks[taskId].data[11] = spriteId4;
+}
+
+void sub_8031A5C(u8 taskId)
+{
+ int alpha;
+
+ if (gTasks[taskId].data[1] == 0)
+ {
+ gTasks[gTasks[taskId].data[0]].data[5] = 1;
+ DestroyTask(taskId);
+ }
+ else if (gTasks[taskId].data[4])
+ {
+ gTasks[taskId].data[4]--;
+ }
+ else
+ {
+ gTasks[taskId].data[4] = gTasks[taskId].data[3];
+ gTasks[taskId].data[1]--;
+ gTasks[taskId].data[2]++;
+ alpha = gTasks[taskId].data[2] << 8;
+ SetGpuReg(REG_OFFSET_BLDALPHA, gTasks[taskId].data[1] + alpha);
+ }
+}
+
+void sub_8031ACC(u8 taskId, u8 a)
+{
+ u8 taskId2;
+
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_OBJ);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0));
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ gTasks[taskId].data[5] = 0;
+ taskId2 = CreateTask(sub_8031A5C, 0);
+ gTasks[taskId2].data[0] = taskId;
+ gTasks[taskId2].data[1] = 16;
+ gTasks[taskId2].data[2] = 0;
+ gTasks[taskId2].data[3] = a;
+ gTasks[taskId2].data[4] = a;
+}
+
+void sub_8031B3C(u8 taskId)
+{
+ int alpha;
+
+ if (gTasks[taskId].data[1] == 16)
+ {
+ gTasks[gTasks[taskId].data[0]].data[5] = 1;
+ DestroyTask(taskId);
+ }
+ else if (gTasks[taskId].data[4])
+ {
+ gTasks[taskId].data[4]--;
+ }
+ else
+ {
+ gTasks[taskId].data[4] = gTasks[taskId].data[3];
+ gTasks[taskId].data[1]++;
+ gTasks[taskId].data[2]--;
+ alpha = gTasks[taskId].data[2] << 8;
+ SetGpuReg(REG_OFFSET_BLDALPHA, gTasks[taskId].data[1] + alpha);
+ }
+}
+
+void sub_8031BAC(u8 taskId, u8 a)
+{
+ u8 taskId2;
+
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_OBJ);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16));
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ gTasks[taskId].data[5] = 0;
+ taskId2 = CreateTask(sub_8031B3C, 0);
+ gTasks[taskId2].data[0] = taskId;
+ gTasks[taskId2].data[1] = 0;
+ gTasks[taskId2].data[2] = 16;
+ gTasks[taskId2].data[3] = a;
+ gTasks[taskId2].data[4] = a;
+}
+
+void sub_8031C1C(u8 taskId)
+{
+ if (gTasks[taskId].data[2])
+ {
+ gTasks[taskId].data[2]--;
+ }
+ else if (gTasks[taskId].data[1] == 8)
+ {
+ DestroyTask(taskId);
+ }
+ else if (gTasks[taskId].data[4])
+ {
+ gTasks[taskId].data[4]--;
+ }
+ else
+ {
+ gTasks[taskId].data[4] = gTasks[taskId].data[3];
+ gTasks[taskId].data[1]++;
+ LoadPalette(&gUnknown_082FF018[gTasks[taskId].data[1]], 1, 16);
+ }
+}
+
+void sub_8031C88(u8 taskId, u8 a)
+{
+ u8 taskId2;
+
+ taskId2 = CreateTask(sub_8031C1C, 0);
+ gTasks[taskId2].data[0] = taskId;
+ gTasks[taskId2].data[1] = 0;
+ gTasks[taskId2].data[2] = 8;
+ gTasks[taskId2].data[3] = a;
+ gTasks[taskId2].data[4] = a;
+}
+
+void sub_8031CC8(u8 taskId)
+{
+ if (gTasks[taskId].data[2])
+ {
+ gTasks[taskId].data[2]--;
+ }
+ else if (gTasks[taskId].data[1] == 0)
+ {
+ DestroyTask(taskId);
+ }
+ else if (gTasks[taskId].data[4])
+ {
+ gTasks[taskId].data[4]--;
+ }
+ else
+ {
+ gTasks[taskId].data[4] = gTasks[taskId].data[3];
+ gTasks[taskId].data[1]--;
+ LoadPalette(&gUnknown_082FF018[gTasks[taskId].data[1]], 1, 16);
+ }
+}
+
+void sub_8031D34(u8 taskId, u8 a)
+{
+ u8 taskId2;
+
+ taskId2 = CreateTask(sub_8031CC8, 0);
+ gTasks[taskId2].data[0] = taskId;
+ gTasks[taskId2].data[1] = 8;
+ gTasks[taskId2].data[2] = 8;
+ gTasks[taskId2].data[3] = a;
+ gTasks[taskId2].data[4] = a;
+}
+
+void sub_8031D74(void)
+{
+ DrawMainMenuWindowBorder(&gUnknown_082FF080[1], 0xF3);
+ FillWindowPixelBuffer(1, 17);
+ PrintMenuTable(1, 2, gUnknown_082FF118);
+ InitMenuInUpperLeftCornerPlaySoundWhenAPressed(1, 2, 0);
+ PutWindowTilemap(1);
+ CopyWindowToVram(1, 3);
+}
+
+s8 sub_8031DB4(void)
+{
+ return ProcessMenuInputNoWrapAround();
+}
+
+void set_default_player_name(u8 nameId)
+{
+ const u8* name;
+ u8 i;
+
+ if (gSaveBlock2Ptr->playerGender == MALE)
+ name = gMalePresetNames[nameId];
+ else
+ name = gFemalePresetNames[nameId];
+ for (i = 0; i < 7; i++)
+ gSaveBlock2Ptr->playerName[i] = name[i];
+ gSaveBlock2Ptr->playerName[7] = 0xFF;
+}
+
+void CreateMainMenuErrorWindow(const u8* str)
+{
+ FillWindowPixelBuffer(7, 17);
+ PrintTextOnWindow(7, 1, str, 0, 1, 2, 0);
+ PutWindowTilemap(7);
+ CopyWindowToVram(7, 2);
+ DrawMainMenuWindowBorder(gUnknown_082FF070, MAIN_MENU_BORDER_TILE);
+ SetGpuReg(REG_OFFSET_WIN0H, 0x9E7);
+ SetGpuReg(REG_OFFSET_WIN0V, 0x719F);
+}
+
+void fmt_savegame(void)
+{
+ fmt_time();
+ fmt_pokedex();
+ fmt_player();
+ fmt_badges();
+}
+
+void fmt_time(void)
+{
+ StringExpandPlaceholders(gStringVar4, gText_ContinueMenuPlayer);
+ box_print(2, 1, 0, 17, gUnknown_082FF0E3, -1, gStringVar4);
+ box_print(2, 1, GetStringRightAlignXOffset(1, gSaveBlock2Ptr->playerName, 100), 17, gUnknown_082FF0E3, -1, gSaveBlock2Ptr->playerName);
+}
+
+void fmt_player(void)
+{
+ u8 str[0x20];
+ u8* ptr;
+
+ StringExpandPlaceholders(gStringVar4, gText_ContinueMenuTime);
+ box_print(2, 1, 0x6C, 17, gUnknown_082FF0E3, -1, gStringVar4);
+ ptr = ConvertIntToDecimalStringN(str, gSaveBlock2Ptr->playTimeHours, 0, 3);
+ *ptr = 0xF0;
+ ConvertIntToDecimalStringN(ptr + 1, gSaveBlock2Ptr->playTimeMinutes, 2, 2);
+ box_print(2, 1, GetStringRightAlignXOffset(1, str, 0xD0), 17, gUnknown_082FF0E3, -1, str);
+}
+
+void fmt_pokedex(void)
+{
+ u8 str[0x20];
+ u16 dexCount;
+
+ if (FlagGet(FLAG_SYS_POKEDEX_GET) == TRUE)
+ {
+ if (IsNationalPokedexEnabled())
+ dexCount = GetNationalPokedexCount(1);
+ else
+ dexCount = GetHoennPokedexCount(1);
+ StringExpandPlaceholders(gStringVar4, gText_ContinueMenuPokedex);
+ box_print(2, 1, 0, 33, gUnknown_082FF0E3, -1, gStringVar4);
+ ConvertIntToDecimalStringN(str, dexCount, 0, 3);
+ box_print(2, 1, GetStringRightAlignXOffset(1, str, 100), 33, gUnknown_082FF0E3, -1, str);
+ }
+}
+
+void fmt_badges(void)
+{
+ u8 str[0x20];
+ u8 badgeCount = 0;
+ u32 i;
+
+ for (i = FLAG_BADGE01_GET; i <= FLAG_BADGE08_GET; i++)
+ {
+ if (FlagGet(i))
+ badgeCount++;
+ }
+ StringExpandPlaceholders(gStringVar4, gText_ContinueMenuBadges);
+ box_print(2, 1, 0x6C, 33, gUnknown_082FF0E3, -1, gStringVar4);
+ ConvertIntToDecimalStringN(str, badgeCount, 2, 1);
+ box_print(2, 1, GetStringRightAlignXOffset(1, str, 0xD0), 33, gUnknown_082FF0E3, -1, str);
+}
+
+void LoadMainMenuWindowFrameTiles(u8 bgId, u16 tileOffset)
+{
+ LoadBgTiles(bgId, GetWindowFrameTilesPal(gSaveBlock2Ptr->optionsWindowFrameType)->tiles, 0x120, tileOffset);
+ LoadPalette(GetWindowFrameTilesPal(gSaveBlock2Ptr->optionsWindowFrameType)->pal, 32, 32);
+}
+
+void DrawMainMenuWindowBorder(const struct WindowTemplate *template, u16 baseTileNum)
+{
+ u16 r9 = 1 + baseTileNum;
+ u16 r10 = 2 + baseTileNum;
+ u16 sp18 = 3 + baseTileNum;
+ u16 spC = 5 + baseTileNum;
+ u16 sp10 = 6 + baseTileNum;
+ u16 sp14 = 7 + baseTileNum;
+ u16 r6 = 8 + baseTileNum;
+
+ FillBgTilemapBufferRect(template->priority, baseTileNum, template->tilemapLeft - 1, template->tilemapTop - 1, 1, 1, 2);
+ FillBgTilemapBufferRect(template->priority, r9, template->tilemapLeft, template->tilemapTop - 1, template->width, 1, 2);
+ FillBgTilemapBufferRect(template->priority, r10, template->tilemapLeft + template->width, template->tilemapTop - 1, 1, 1, 2);
+ FillBgTilemapBufferRect(template->priority, sp18, template->tilemapLeft - 1, template->tilemapTop, 1, template->height, 2);
+ FillBgTilemapBufferRect(template->priority, spC, template->tilemapLeft + template->width, template->tilemapTop, 1, template->height, 2);
+ FillBgTilemapBufferRect(template->priority, sp10, template->tilemapLeft - 1, template->tilemapTop + template->height, 1, 1, 2);
+ FillBgTilemapBufferRect(template->priority, sp14, template->tilemapLeft, template->tilemapTop + template->height, template->width, 1, 2);
+ FillBgTilemapBufferRect(template->priority, r6, template->tilemapLeft + template->width, template->tilemapTop + template->height, 1, 1, 2);
+ CopyBgTilemapBufferToVram(template->priority);
+}
+
+void sub_8032250(const struct WindowTemplate *template)
+{
+ FillBgTilemapBufferRect(template->priority, 0, template->tilemapLeft - 1, template->tilemapTop - 1, template->tilemapLeft + template->width + 1, template->tilemapTop + template->height + 1, 2);
+ CopyBgTilemapBufferToVram(template->priority);
+}
+
+void sub_8032298(u8 a, u8 b, u8 c, u8 d, u8 e, u8 unused)
+{
+ FillBgTilemapBufferRect(a, 0, b + 0xFF, c + 0xFF, d + 2, e + 2, 2);
+}
+
+void sub_80322E0(u8 windowId, u8 a)
+{
+ CallWindowFunction(windowId, sub_8032298);
+ FillWindowPixelBuffer(windowId, 0x11);
+ ClearWindowTilemap(windowId);
+ if (a == 1)
+ CopyWindowToVram(windowId, 3);
+}
+
+void sub_8032318(u8 a)
+{
+ u8 fontAttribute = GetFontAttribute(1, 6);
+ u8 fontAttribute2 = GetFontAttribute(1, 0);
+ u8 fontAttribute3 = GetFontAttribute(1, 1);
+ u8 windowAttribute = GetWindowAttribute(a, 3);
+ u8 windowAttribute2 = GetWindowAttribute(a, 4);
+
+ FillWindowPixelRect(a, fontAttribute, 0, 0, fontAttribute2 * windowAttribute, fontAttribute3 * windowAttribute2);
+ CopyWindowToVram(a, 2);
+}
+
+void sub_80323A0(struct TextSubPrinter *printer, u16 a)
+{
+ if (*(printer->current_text_offset - 2) == 8 && gUnknown_02022D04 == 0)
+ {
+ gUnknown_02022D04 = 1;
+ CreateTask(sub_8030A70, 0);
+ }
+}
+
+void sub_80323CC(u8 a, u8 b, u16 c, u16 d, u8 e, u8 f)
+{
+ struct WindowTemplate sp;
+
+ sp = sub_8198A50(0, a + 1, b + 1, 5, 4, f, d);
+ CreateYesNoMenu(&sp, c, e, 0);
+}
+
+void unknown_rbox_to_vram(u8 windowId, u8 a)
+{
+ CallWindowFunction(windowId, sub_8032474);
+ FillWindowPixelBuffer(windowId, 17);
+ PutWindowTilemap(windowId);
+ if (a == 1)
+ CopyWindowToVram(windowId, 3);
+}
+
+void sub_8032474 (u8 a, u8 b, u8 c, u8 d, u8 e, u8 f)
+{
+ FillBgTilemapBufferRect(a, 0xFD, b-2, c-1, 1, 1, f);
+ FillBgTilemapBufferRect(a, 0xFF, b-1, c-1, 1, 1, f);
+ FillBgTilemapBufferRect(a, 0x100, b, c-1, d, 1, f);
+ FillBgTilemapBufferRect(a, 0x101, b+d-1, c-1, 1, 1, f);
+ FillBgTilemapBufferRect(a, 0x102, b+d, c-1, 1, 1, f);
+ FillBgTilemapBufferRect(a, 0x103, b-2, c, 1, 5, f);
+ FillBgTilemapBufferRect(a, 0x105, b-1, c, d+1, 5, f);
+ FillBgTilemapBufferRect(a, 0x106, b+d, c, 1, 5, f);
+ FillBgTilemapBufferRect(a, BG_TILE_V_FLIP(0xFD), b-2, c+e, 1, 1, f);
+ FillBgTilemapBufferRect(a, BG_TILE_V_FLIP(0xFF), b-1, c+e, 1, 1, f);
+ FillBgTilemapBufferRect(a, BG_TILE_V_FLIP(0x100), b, c+e, d-1, 1, f);
+ FillBgTilemapBufferRect(a, BG_TILE_V_FLIP(0x101), b+d-1, c+e, 1, 1, f);
+ FillBgTilemapBufferRect(a, BG_TILE_V_FLIP(0x102), b+d, c+e, 1, 1, f);
+}
+
+void task_new_game_prof_birch_speech_part2_1(u8 taskId)
+{
+ if (gTasks[taskId].data[7]-- <= 0)
+ {
+ unknown_rbox_to_vram(0, 1);
+ gTasks[taskId].func = task_new_game_prof_birch_speech_part2_2;
+ }
+}
diff --git a/src/map_name_popup.c b/src/map_name_popup.c
new file mode 100644
index 000000000..1782e9af8
--- /dev/null
+++ b/src/map_name_popup.c
@@ -0,0 +1,474 @@
+#include "global.h"
+#include "constants/region_map_sections.h"
+#include "constants/weather.h"
+#include "bg.h"
+#include "event_data.h"
+#include "gpu_regs.h"
+#include "international_string_util.h"
+#include "menu.h"
+#include "map_name_popup.h"
+#include "palette.h"
+#include "region_map.h"
+#include "rom_818CFC8.h"
+#include "start_menu.h"
+#include "string_util.h"
+#include "task.h"
+#include "text.h"
+
+
+// enums
+enum MapPopUp_Themes
+{
+ MAPPOPUP_THEME_WOOD,
+ MAPPOPUP_THEME_MARBLE,
+ MAPPOPUP_THEME_STONE,
+ MAPPOPUP_THEME_BRICK,
+ MAPPOPUP_THEME_UNDERWATER,
+ MAPPOPUP_THEME_STONE2,
+};
+
+// static functions
+static void Task_MapNamePopUpWindow(u8 taskId);
+static void ShowMapNamePopUpWindow(void);
+static void LoadMapNamePopUpWindowBg(void);
+
+// EWRAM
+static EWRAM_DATA u8 mapNamePopupTaskId = 0;
+
+// .rodata
+static const u8 gMapPopUp_Table[][960] =
+{
+ INCBIN_U8("graphics/interface/map_popup/wood.4bpp"),
+ INCBIN_U8("graphics/interface/map_popup/marble.4bpp"),
+ INCBIN_U8("graphics/interface/map_popup/stone.4bpp"),
+ INCBIN_U8("graphics/interface/map_popup/brick.4bpp"),
+ INCBIN_U8("graphics/interface/map_popup/underwater.4bpp"),
+ INCBIN_U8("graphics/interface/map_popup/stone2.4bpp"),
+};
+
+static const u8 gMapPopUp_Outline_Table[][960] =
+{
+ INCBIN_U8("graphics/interface/map_popup/wood_outline.4bpp"),
+ INCBIN_U8("graphics/interface/map_popup/marble_outline.4bpp"),
+ INCBIN_U8("graphics/interface/map_popup/stone_outline.4bpp"),
+ INCBIN_U8("graphics/interface/map_popup/brick_outline.4bpp"),
+ INCBIN_U8("graphics/interface/map_popup/underwater_outline.4bpp"),
+ INCBIN_U8("graphics/interface/map_popup/stone2_outline.4bpp"),
+};
+
+static const u16 gMapPopUp_Palette_Table[][16] =
+{
+ INCBIN_U16("graphics/interface/map_popup/wood.gbapal"),
+ INCBIN_U16("graphics/interface/map_popup/marble_outline.gbapal"),
+ INCBIN_U16("graphics/interface/map_popup/stone_outline.gbapal"),
+ INCBIN_U16("graphics/interface/map_popup/brick_outline.gbapal"),
+ INCBIN_U16("graphics/interface/map_popup/underwater_outline.gbapal"),
+ INCBIN_U16("graphics/interface/map_popup/stone2_outline.gbapal"),
+};
+
+static const u16 gUnknown_0857F444[16] = INCBIN_U16("graphics/interface/map_popup/857F444.gbapal");
+
+static const u8 gRegionMapSectionId_To_PopUpThemeIdMapping[] =
+{
+ MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_WOOD,
+ MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_BRICK,
+ MAPPOPUP_THEME_MARBLE, MAPPOPUP_THEME_MARBLE, MAPPOPUP_THEME_MARBLE, MAPPOPUP_THEME_BRICK,
+ MAPPOPUP_THEME_MARBLE, MAPPOPUP_THEME_BRICK, MAPPOPUP_THEME_MARBLE, MAPPOPUP_THEME_BRICK,
+ MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_WOOD,
+ MAPPOPUP_THEME_UNDERWATER, MAPPOPUP_THEME_UNDERWATER, MAPPOPUP_THEME_UNDERWATER, MAPPOPUP_THEME_UNDERWATER,
+ MAPPOPUP_THEME_UNDERWATER, MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_WOOD,
+ MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_WOOD,
+ MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_WOOD,
+ MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_UNDERWATER, MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_UNDERWATER,
+ MAPPOPUP_THEME_UNDERWATER, MAPPOPUP_THEME_UNDERWATER, MAPPOPUP_THEME_UNDERWATER, MAPPOPUP_THEME_UNDERWATER,
+ MAPPOPUP_THEME_UNDERWATER, MAPPOPUP_THEME_UNDERWATER, MAPPOPUP_THEME_UNDERWATER, MAPPOPUP_THEME_UNDERWATER,
+ MAPPOPUP_THEME_UNDERWATER, MAPPOPUP_THEME_UNDERWATER, MAPPOPUP_THEME_STONE2, MAPPOPUP_THEME_STONE2,
+ MAPPOPUP_THEME_STONE2, MAPPOPUP_THEME_STONE2, MAPPOPUP_THEME_STONE2, MAPPOPUP_THEME_STONE,
+ MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_MARBLE, MAPPOPUP_THEME_WOOD,
+ MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_MARBLE, MAPPOPUP_THEME_STONE,
+ MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_STONE,
+ MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_STONE2, MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_WOOD,
+ MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_STONE,
+ MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_STONE2,
+ MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_STONE,
+ MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_MARBLE,
+ MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_WOOD,
+ MAPPOPUP_THEME_WOOD, MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_STONE2,
+ MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_STONE2, MAPPOPUP_THEME_STONE2, MAPPOPUP_THEME_STONE2,
+ MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_STONE, MAPPOPUP_THEME_MARBLE
+};
+
+static const u8 gText_PyramidFloor1[] = _("PYRAMID FLOOR 1");
+static const u8 gText_PyramidFloor2[] = _("PYRAMID FLOOR 2");
+static const u8 gText_PyramidFloor3[] = _("PYRAMID FLOOR 3");
+static const u8 gText_PyramidFloor4[] = _("PYRAMID FLOOR 4");
+static const u8 gText_PyramidFloor5[] = _("PYRAMID FLOOR 5");
+static const u8 gText_PyramidFloor6[] = _("PYRAMID FLOOR 6");
+static const u8 gText_PyramidFloor7[] = _("PYRAMID FLOOR 7");
+static const u8 gText_Pyramid[] = _("PYRAMID");
+
+static const u8 * const gBattlePyramid_MapHeaderStrings[] =
+{
+ gText_PyramidFloor1,
+ gText_PyramidFloor2,
+ gText_PyramidFloor3,
+ gText_PyramidFloor4,
+ gText_PyramidFloor5,
+ gText_PyramidFloor6,
+ gText_PyramidFloor7,
+ gText_Pyramid,
+};
+
+// text
+bool8 sub_80D47D4(void)
+{
+ HideStartMenu();
+ ShowMapNamePopup();
+ return 1;
+}
+
+void ShowMapNamePopup(void)
+{
+ if (FlagGet(FLAG_SPECIAL_FLAG_0x4000) != TRUE)
+ {
+ if (!FuncIsActiveTask(Task_MapNamePopUpWindow))
+ {
+ mapNamePopupTaskId = CreateTask(Task_MapNamePopUpWindow, 90);
+ SetGpuReg(REG_OFFSET_BG0VOFS, 40);
+ gTasks[mapNamePopupTaskId].data[0] = 6;
+ gTasks[mapNamePopupTaskId].data[2] = 40;
+ }
+ else
+ {
+ if (gTasks[mapNamePopupTaskId].data[0] != 2)
+ gTasks[mapNamePopupTaskId].data[0] = 2;
+ gTasks[mapNamePopupTaskId].data[3] = 1;
+ }
+ }
+}
+
+static void Task_MapNamePopUpWindow(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 6:
+ task->data[4]++;
+ if (task->data[4] > 30)
+ {
+ task->data[0] = 0;
+ task->data[4] = 0;
+ ShowMapNamePopUpWindow();
+ }
+ break;
+ case 0:
+ task->data[2] -= 2;
+ if (task->data[2] <= 0 )
+ {
+ task->data[2] = 0;
+ task->data[0] = 1;
+ gTasks[mapNamePopupTaskId].data[1] = 0;
+ }
+ break;
+ case 1:
+ task->data[1]++;
+ if (task->data[1] > 120 )
+ {
+ task->data[1] = 0;
+ task->data[0] = 2;
+ }
+ break;
+ case 2:
+ task->data[2] += 2;
+ if (task->data[2] > 39)
+ {
+ task->data[2] = 40;
+ if (task->data[3])
+ {
+ task->data[0] = 6;
+ task->data[4] = 0;
+ task->data[3] = 0;
+ }
+ else
+ {
+ task->data[0] = 4;
+ return;
+ }
+ }
+ break;
+ case 4:
+ sub_819746C(GetMapNamePopUpWindowId(), TRUE);
+ task->data[0] = 5;
+ break;
+ case 5:
+ HideMapNamePopUpWindow();
+ return;
+ }
+ SetGpuReg(REG_OFFSET_BG0VOFS, task->data[2]);
+}
+
+void HideMapNamePopUpWindow(void)
+{
+ if (FuncIsActiveTask(Task_MapNamePopUpWindow))
+ {
+ sub_819746C(GetMapNamePopUpWindowId(), TRUE);
+ RemoveMapNamePopUpWindow();
+ SetGpuReg_ForcedBlank(REG_OFFSET_BG0VOFS, 0);
+ DestroyTask(mapNamePopupTaskId);
+ }
+}
+
+static void ShowMapNamePopUpWindow(void)
+{
+ u8 mapDisplayHeader[24];
+ u8 *withoutPrefixPtr;
+ u8 x;
+ const u8* mapDisplayHeaderSource;
+
+ if(InBattlePyramid())
+ {
+ if(gMapHeader.mapDataId == 0x17A)
+ {
+ withoutPrefixPtr = &(mapDisplayHeader[3]);
+ mapDisplayHeaderSource = gBattlePyramid_MapHeaderStrings[7];
+ }
+ else
+ {
+ withoutPrefixPtr = &(mapDisplayHeader[3]);
+ mapDisplayHeaderSource = gBattlePyramid_MapHeaderStrings[gSaveBlock2Ptr->battlePyramidWildHeaderId];
+ }
+ StringCopy(withoutPrefixPtr, mapDisplayHeaderSource);
+ }
+ else
+ {
+ withoutPrefixPtr = &(mapDisplayHeader[3]);
+ GetMapName(withoutPrefixPtr, gMapHeader.regionMapSectionId, 0);
+ }
+ AddMapNamePopUpWindow();
+ LoadMapNamePopUpWindowBg();
+ x = GetStringCenterAlignXOffset(7, withoutPrefixPtr, 80);
+ mapDisplayHeader[0] = EXT_CTRL_CODE_BEGIN;
+ mapDisplayHeader[1] = EXT_CTRL_CODE_HIGHLIGHT;
+ mapDisplayHeader[2] = TEXT_COLOR_TRANSPARENT;
+ PrintTextOnWindow(GetMapNamePopUpWindowId(), 7, mapDisplayHeader, x, 3, 0xFF, NULL);
+ CopyWindowToVram(GetMapNamePopUpWindowId(), 3);
+}
+
+#ifdef NONMATCHING
+static void sub_80D4A78(u8 bg, u8 x, u8 y, u8 deltaX, u8 deltaY, u8 unused)
+{
+ s32 i;
+
+ for(i=0; i<=11; i++)
+ {
+ FillBgTilemapBufferRect(bg, 0x21D + i, x + i - 1, y - 1, 1, 1, 0xE);
+ }
+ FillBgTilemapBufferRect(bg, 0x229 + i, x - 1, y, 1, 1, 0xE);
+ FillBgTilemapBufferRect(bg, 0x22A + i, deltaX + x, y, 1, 1, 0xE);
+ FillBgTilemapBufferRect(bg, 0x22B + i, x - 1, y + 1 , 1, 1, 0xE);
+ FillBgTilemapBufferRect(bg, 0x22C + i, deltaX + x, y + 1, 1, 1, 0xE);
+ FillBgTilemapBufferRect(bg, 0x22D + i, x - 1, y + 2, 1, 1, 0xE);
+ FillBgTilemapBufferRect(bg, 0x22E + i, deltaX + x, y + 2, 1, 1, 0xE);
+ for(i=0; i<=11; i++)
+ {
+ FillBgTilemapBufferRect(bg, 0x22F + i, x + i - 1, y + deltaY, 1, 1, 0xE);
+ }
+}
+#else
+NAKED
+static void sub_80D4A78(u8 bg, u8 x, u8 y, u8 deltaX, u8 deltaY, u8 unused)
+{
+ asm("\n\
+ .syntax unified\n\
+ push {r4-r7,lr}\n\
+ mov r7, r10\n\
+ mov r6, r9\n\
+ mov r5, r8\n\
+ push {r5-r7}\n\
+ sub sp, 0x1C\n\
+ ldr r4, [sp, 0x3C]\n\
+ lsls r0, 24\n\
+ lsrs r7, r0, 24\n\
+ lsls r1, 24\n\
+ lsrs r1, 24\n\
+ mov r10, r1\n\
+ lsls r2, 24\n\
+ lsls r3, 24\n\
+ lsrs r3, 24\n\
+ str r3, [sp, 0x10]\n\
+ lsls r4, 24\n\
+ lsrs r4, 24\n\
+ str r4, [sp, 0x14]\n\
+ movs r5, 0\n\
+ lsls r0, r1, 24\n\
+ asrs r1, r0, 24\n\
+ lsrs r3, r2, 24\n\
+ str r3, [sp, 0xC]\n\
+ movs r6, 0xFF\n\
+ lsls r6, 24\n\
+ adds r6, r2\n\
+ mov r8, r6\n\
+ str r0, [sp, 0x18]\n\
+ subs r4, r1, 0x1\n\
+ _080D4AB4:\n\
+ ldr r0, =0x0000021d\n\
+ adds r1, r5, r0\n\
+ lsls r1, 16\n\
+ lsrs r1, 16\n\
+ lsls r2, r4, 24\n\
+ lsrs r2, 24\n\
+ movs r3, 0x1\n\
+ str r3, [sp]\n\
+ str r3, [sp, 0x4]\n\
+ movs r6, 0xE\n\
+ mov r9, r6\n\
+ str r6, [sp, 0x8]\n\
+ adds r0, r7, 0\n\
+ mov r6, r8\n\
+ lsrs r3, r6, 24\n\
+ bl FillBgTilemapBufferRect\n\
+ adds r4, 0x1\n\
+ adds r5, 0x1\n\
+ cmp r5, 0xB\n\
+ ble _080D4AB4\n\
+ ldr r1, =0x00000229\n\
+ movs r0, 0x1\n\
+ negs r0, r0\n\
+ add r0, r10\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ mov r8, r0\n\
+ movs r5, 0x1\n\
+ str r5, [sp]\n\
+ str r5, [sp, 0x4]\n\
+ mov r2, r9\n\
+ str r2, [sp, 0x8]\n\
+ adds r0, r7, 0\n\
+ mov r2, r8\n\
+ ldr r3, [sp, 0xC]\n\
+ bl FillBgTilemapBufferRect\n\
+ ldr r1, =0x0000022a\n\
+ ldr r6, [sp, 0x10]\n\
+ add r6, r10\n\
+ lsls r6, 24\n\
+ lsrs r6, 24\n\
+ str r5, [sp]\n\
+ str r5, [sp, 0x4]\n\
+ mov r3, r9\n\
+ str r3, [sp, 0x8]\n\
+ adds r0, r7, 0\n\
+ adds r2, r6, 0\n\
+ ldr r3, [sp, 0xC]\n\
+ bl FillBgTilemapBufferRect\n\
+ ldr r1, =0x0000022b\n\
+ ldr r4, [sp, 0xC]\n\
+ adds r4, 0x1\n\
+ lsls r4, 24\n\
+ lsrs r4, 24\n\
+ str r5, [sp]\n\
+ str r5, [sp, 0x4]\n\
+ mov r0, r9\n\
+ str r0, [sp, 0x8]\n\
+ adds r0, r7, 0\n\
+ mov r2, r8\n\
+ adds r3, r4, 0\n\
+ bl FillBgTilemapBufferRect\n\
+ movs r1, 0x8B\n\
+ lsls r1, 2\n\
+ str r5, [sp]\n\
+ str r5, [sp, 0x4]\n\
+ mov r2, r9\n\
+ str r2, [sp, 0x8]\n\
+ adds r0, r7, 0\n\
+ adds r2, r6, 0\n\
+ adds r3, r4, 0\n\
+ bl FillBgTilemapBufferRect\n\
+ ldr r1, =0x0000022d\n\
+ ldr r4, [sp, 0xC]\n\
+ adds r4, 0x2\n\
+ lsls r4, 24\n\
+ lsrs r4, 24\n\
+ str r5, [sp]\n\
+ str r5, [sp, 0x4]\n\
+ mov r3, r9\n\
+ str r3, [sp, 0x8]\n\
+ adds r0, r7, 0\n\
+ mov r2, r8\n\
+ adds r3, r4, 0\n\
+ bl FillBgTilemapBufferRect\n\
+ ldr r1, =0x0000022e\n\
+ str r5, [sp]\n\
+ str r5, [sp, 0x4]\n\
+ mov r0, r9\n\
+ str r0, [sp, 0x8]\n\
+ adds r0, r7, 0\n\
+ adds r2, r6, 0\n\
+ adds r3, r4, 0\n\
+ bl FillBgTilemapBufferRect\n\
+ movs r5, 0\n\
+ ldr r1, [sp, 0xC]\n\
+ ldr r2, [sp, 0x14]\n\
+ adds r0, r1, r2\n\
+ lsls r4, r0, 24\n\
+ movs r6, 0x1\n\
+ _080D4B8A:\n\
+ ldr r3, =0x0000022f\n\
+ adds r1, r5, r3\n\
+ lsls r1, 16\n\
+ lsrs r1, 16\n\
+ subs r0, r5, 0x1\n\
+ ldr r3, [sp, 0x18]\n\
+ asrs r2, r3, 24\n\
+ adds r2, r0\n\
+ lsls r2, 24\n\
+ lsrs r2, 24\n\
+ str r6, [sp]\n\
+ str r6, [sp, 0x4]\n\
+ movs r0, 0xE\n\
+ str r0, [sp, 0x8]\n\
+ adds r0, r7, 0\n\
+ lsrs r3, r4, 24\n\
+ bl FillBgTilemapBufferRect\n\
+ adds r5, 0x1\n\
+ cmp r5, 0xB\n\
+ ble _080D4B8A\n\
+ add sp, 0x1C\n\
+ pop {r3-r5}\n\
+ mov r8, r3\n\
+ mov r9, r4\n\
+ mov r10, r5\n\
+ pop {r4-r7}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .pool\n\
+ .syntax divided");
+}
+#endif // NONMATCHING
+
+static void LoadMapNamePopUpWindowBg(void)
+{
+ u8 popupWindowId;
+ u16 regionMapSectionId;
+ u8 popUpThemeId;
+
+ popupWindowId = GetMapNamePopUpWindowId();
+ regionMapSectionId = gMapHeader.regionMapSectionId;
+ if(regionMapSectionId > MAPSEC_DYNAMIC)
+ {
+ if(regionMapSectionId > MAPSEC_SPECIAL_AREA)
+ regionMapSectionId -= (MAPSEC_SPECIAL_AREA - MAPSEC_DYNAMIC);
+ else
+ regionMapSectionId = 0; //discard kanto region sections
+ }
+ popUpThemeId = gRegionMapSectionId_To_PopUpThemeIdMapping[regionMapSectionId];
+
+ LoadBgTiles(GetWindowAttribute(popupWindowId, 0), &(gMapPopUp_Outline_Table[popUpThemeId][0]), 0x400, 0x21D);
+ CallWindowFunction(popupWindowId, sub_80D4A78);
+ PutWindowTilemap(popupWindowId);
+ if(gMapHeader.weather == WEATHER_BUBBLES)
+ LoadPalette(&gUnknown_0857F444, 0xE0, 0x20);
+ else
+ LoadPalette(&(gMapPopUp_Palette_Table[popUpThemeId][0]), 0xE0, 0x20);
+ BlitBitmapToWindow(popupWindowId, &(gMapPopUp_Table[popUpThemeId][0]), 0, 0, 80, 24);
+}
diff --git a/src/map_obj_lock.c b/src/map_obj_lock.c
new file mode 100644
index 000000000..688d0594d
--- /dev/null
+++ b/src/map_obj_lock.c
@@ -0,0 +1,187 @@
+#include "global.h"
+#include "event_data.h"
+#include "field_map_obj.h"
+#include "field_map_obj_helpers.h"
+#include "field_player_avatar.h"
+#include "map_obj_lock.h"
+#include "script_movement.h"
+#include "task.h"
+#include "trainer_see.h"
+
+bool8 walkrun_is_standing_still(void)
+{
+ if (gPlayerAvatar.tileTransitionState == T_TILE_TRANSITION)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+static void sub_80983A4(u8 taskId)
+{
+ if (walkrun_is_standing_still())
+ {
+ sub_808B864();
+ DestroyTask(taskId);
+ }
+}
+
+bool8 sub_80983C4(void)
+{
+ if (FuncIsActiveTask(sub_80983A4))
+ {
+ return FALSE;
+ }
+ else
+ {
+ sub_808BCF4();
+ return TRUE;
+ }
+}
+
+
+void ScriptFreezeMapObjects(void)
+{
+ FreezeMapObjects();
+ CreateTask(sub_80983A4, 80);
+}
+
+static void sub_8098400(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ if (!task->data[0] && walkrun_is_standing_still() == TRUE)
+ {
+ sub_808B864();
+ task->data[0] = 1;
+ }
+ if (!task->data[1] && !gMapObjects[gSelectedMapObject].mapobj_bit_1)
+ {
+ FreezeMapObject(&gMapObjects[gSelectedMapObject]);
+ task->data[1] = 1;
+ }
+ if (task->data[0] && task->data[1])
+ DestroyTask(taskId);
+}
+
+bool8 sub_809847C(void)
+{
+ if (FuncIsActiveTask(sub_8098400))
+ {
+ return FALSE;
+ }
+ else
+ {
+ sub_808BCF4();
+ return TRUE;
+ }
+}
+
+void LockSelectedMapObject(void)
+{
+ u8 taskId;
+ FreezeMapObjectsExceptOne(gSelectedMapObject);
+ taskId = CreateTask(sub_8098400, 80);
+ if (!gMapObjects[gSelectedMapObject].mapobj_bit_1)
+ {
+ FreezeMapObject(&gMapObjects[gSelectedMapObject]);
+ gTasks[taskId].data[1] = 1;
+ }
+}
+
+void sub_80984F4(void)
+{
+ u8 objectId = GetFieldObjectIdByLocalIdAndMap(0xFF, 0, 0);
+ FieldObjectClearAnimIfSpecialAnimFinished(&gMapObjects[objectId]);
+ sub_80D338C();
+ UnfreezeMapObjects();
+}
+
+void sub_8098524(void)
+{
+ u8 objectId;
+
+ if (gMapObjects[gSelectedMapObject].active)
+ FieldObjectClearAnimIfSpecialAnimFinished(&gMapObjects[gSelectedMapObject]);
+ objectId = GetFieldObjectIdByLocalIdAndMap(0xFF, 0, 0);
+ FieldObjectClearAnimIfSpecialAnimFinished(&gMapObjects[objectId]);
+ sub_80D338C();
+ UnfreezeMapObjects();
+}
+
+void sub_8098574(void)
+{
+ FieldObjectFaceOppositeDirection(&gMapObjects[gSelectedMapObject], gSpecialVar_Facing);
+}
+
+void sub_809859C(void)
+{
+ FieldObjectClearAnimIfSpecialAnimActive(&gMapObjects[gSelectedMapObject]);
+}
+
+static void sub_80985BC(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ u8 mapObjectId = task->data[2];
+
+ if (!task->data[0] && walkrun_is_standing_still() == TRUE)
+ {
+ sub_808B864();
+ task->data[0] = 1;
+ }
+ if (!task->data[1] && !gMapObjects[mapObjectId].mapobj_bit_1)
+ {
+ FreezeMapObject(&gMapObjects[mapObjectId]);
+ task->data[1] = 1;
+ }
+ if (task->data[0] && task->data[1])
+ DestroyTask(taskId);
+}
+
+void sub_8098630(void)
+{
+ u8 trainerObjectId1, trainerObjectId2, taskId;
+ trainerObjectId1 = GetChosenApproachingTrainerMapObjectId(0);
+ if(gNoOfApproachingTrainers == 2)
+ {
+ trainerObjectId2 = GetChosenApproachingTrainerMapObjectId(1);
+ sub_8098074(trainerObjectId1, trainerObjectId2);
+ taskId = CreateTask(sub_80985BC, 80);
+ gTasks[taskId].data[2] = trainerObjectId1;
+ if(!gMapObjects[trainerObjectId1].mapobj_bit_1)
+ {
+ FreezeMapObject(&gMapObjects[trainerObjectId1]);
+ gTasks[taskId].data[1] = 1;
+ }
+ taskId = CreateTask(sub_80985BC, 81);
+ gTasks[taskId].data[2] = trainerObjectId2;
+ if(!gMapObjects[trainerObjectId2].mapobj_bit_1)
+ {
+ FreezeMapObject(&gMapObjects[trainerObjectId2]);
+ gTasks[taskId].data[1] = 1;
+ }
+ }
+ else
+ {
+ FreezeMapObjectsExceptOne(trainerObjectId1);
+ taskId = CreateTask(sub_80985BC, 80);
+ gTasks[taskId].data[2] = trainerObjectId1;
+ if(!gMapObjects[trainerObjectId1].mapobj_bit_1)
+ {
+ FreezeMapObject(&gMapObjects[trainerObjectId1]);
+ gTasks[taskId].data[1] = 1;
+ }
+ }
+}
+
+bool8 sub_8098734(void)
+{
+ if (FuncIsActiveTask(sub_80985BC))
+ {
+ return FALSE;
+ }
+ else
+ {
+ sub_808BCF4();
+ return TRUE;
+ }
+}
diff --git a/src/match_call.c b/src/match_call.c
new file mode 100644
index 000000000..aa6945161
--- /dev/null
+++ b/src/match_call.c
@@ -0,0 +1,1275 @@
+
+// Includes
+#include "global.h"
+#include "battle_setup.h"
+#include "event_data.h"
+#include "string_util.h"
+#include "battle.h"
+#include "battle_frontier_1.h"
+#include "gym_leader_rematch.h"
+
+extern const u8 gTrainerClassNames[][13];
+
+// Static type declarations
+
+typedef struct MatchCallTextDataStruct {
+ const u8 *text;
+ u16 flag;
+ u16 flag2;
+} match_call_text_data_t;
+
+struct MatchCallStructCommon {
+ u8 type;
+ u8 v1;
+ u16 flag;
+};
+
+struct MatchCallStruct0 {
+ u8 type;
+ u8 v1;
+ u16 flag;
+ const u8 *desc;
+ const u8 *name;
+ const match_call_text_data_t *textData;
+};
+
+struct MatchCallStruct1 {
+ u8 type;
+ u8 v1;
+ u16 flag;
+ u16 rematchTableIdx;
+ const u8 *desc;
+ const u8 *name;
+ const match_call_text_data_t *textData;
+};
+
+struct MatchCallSubstruct2 {
+ u16 flag;
+ u8 v2;
+};
+
+struct MatchCallStruct2 {
+ u8 type;
+ u8 v1;
+ u16 flag;
+ u16 rematchTableIdx;
+ const u8 *desc;
+ const match_call_text_data_t *textData;
+ const struct MatchCallSubstruct2 *v10;
+};
+
+struct MatchCallStruct3 {
+ u8 type;
+ u8 v1;
+ u16 flag;
+ const u8 *desc;
+ const u8 *name;
+};
+
+struct MatchCallStruct4 {
+ u8 type;
+ u8 gender;
+ u16 flag;
+ const u8 *desc;
+ const u8 *name;
+ const match_call_text_data_t *textData;
+};
+
+struct MatchCallStruct5 {
+ u8 type;
+ u8 v1;
+ u16 flag;
+ u16 v4;
+ const u8 *desc;
+ const u8 *name;
+ const match_call_text_data_t *textData;
+};
+
+#define MATCHCALLDEF(name, type_, ...) \
+static const struct MatchCallStruct##type_ name = { \
+ .type = type_, \
+ __VA_ARGS__ \
+};
+
+typedef union {
+ const struct MatchCallStructCommon *common;
+ const struct MatchCallStruct0 *type0;
+ const struct MatchCallStruct1 *type1;
+ const struct MatchCallStruct2 *type2;
+ const struct MatchCallStruct3 *type3;
+ const struct MatchCallStruct4 *type4;
+ const struct MatchCallStruct5 *type5;
+} match_call_t;
+
+struct UnkStruct_08625388 {
+ u16 idx;
+ u16 v2;
+ u16 v4;
+ const u8 *v8[4];
+};
+
+// Static RAM declarations
+
+// Static ROM declarations
+
+static bool32 MatchCallGetFlag_Type0(match_call_t);
+static bool32 MatchCallGetFlag_Type1(match_call_t);
+static bool32 MatchCallGetFlag_Type2(match_call_t);
+static bool32 MatchCallGetFlag_Type3(match_call_t);
+static bool32 MatchCallGetFlag_Type4(match_call_t);
+
+static u8 sub_81D1714(match_call_t);
+static u8 sub_81D1718(match_call_t);
+static u8 sub_81D171C(match_call_t);
+static u8 sub_81D1750(match_call_t);
+static u8 sub_81D1754(match_call_t);
+
+static bool32 MatchCall_IsRematchable_Type0(match_call_t);
+static bool32 MatchCall_IsRematchable_Type1(match_call_t);
+static bool32 MatchCall_IsRematchable_Type2(match_call_t);
+static bool32 MatchCall_IsRematchable_Type3(match_call_t);
+static bool32 MatchCall_IsRematchable_Type4(match_call_t);
+
+static bool32 sub_81D1840(match_call_t);
+static bool32 sub_81D1844(match_call_t);
+static bool32 sub_81D1848(match_call_t);
+static bool32 sub_81D184C(match_call_t);
+static bool32 sub_81D1850(match_call_t);
+
+static u32 MatchCall_GetRematchTableIdx_Type0(match_call_t);
+static u32 MatchCall_GetRematchTableIdx_Type1(match_call_t);
+static u32 MatchCall_GetRematchTableIdx_Type2(match_call_t);
+static u32 MatchCall_GetRematchTableIdx_Type3(match_call_t);
+static u32 MatchCall_GetRematchTableIdx_Type4(match_call_t);
+
+static void MatchCall_GetMessage_Type0(match_call_t, u8 *);
+static void MatchCall_GetMessage_Type1(match_call_t, u8 *);
+static void MatchCall_GetMessage_Type2(match_call_t, u8 *);
+static void MatchCall_GetMessage_Type3(match_call_t, u8 *);
+static void MatchCall_GetMessage_Type4(match_call_t, u8 *);
+
+static void MatchCall_GetNameAndDesc_Type0(match_call_t, const u8 **, const u8 **);
+static void MatchCall_GetNameAndDesc_Type1(match_call_t, const u8 **, const u8 **);
+static void MatchCall_GetNameAndDesc_Type2(match_call_t, const u8 **, const u8 **);
+static void MatchCall_GetNameAndDesc_Type3(match_call_t, const u8 **, const u8 **);
+static void MatchCall_GetNameAndDesc_Type4(match_call_t, const u8 **, const u8 **);
+
+static void sub_81D1920(const match_call_text_data_t *, u8 *);
+static void sub_81D199C(const match_call_text_data_t *, u16, u8 *);
+static void MatchCall_GetNameAndDescByRematchIdx(u32, const u8 **, const u8 **);
+
+extern const u8 gText_MrStone_Pokenav_2B60C0[];
+extern const u8 gText_MrStone_Pokenav_2B61E6[];
+extern const u8 gText_MrStone_Pokenav_2B6302[];
+extern const u8 gText_MrStone_Pokenav_2B63A0[];
+extern const u8 gText_MrStone_Pokenav_2B64A2[];
+extern const u8 gText_MrStone_Pokenav_2B6526[];
+extern const u8 gText_MrStone_Pokenav_2B65BB[];
+extern const u8 gText_MrStone_Pokenav_2B6664[];
+extern const u8 gText_MrStone_Pokenav_2B66B1[];
+extern const u8 gText_MrStone_Pokenav_2B6703[];
+extern const u8 gText_MrStone_Pokenav_2B67ED[];
+
+extern const u8 gMrStoneMatchCallDesc[];
+extern const u8 gMrStoneMatchCallName[];
+
+extern const u8 gText_Norman_Pokenav_2B5719[];
+extern const u8 gText_Norman_Pokenav_2B5795[];
+extern const u8 gText_Norman_Pokenav_2B584D[];
+extern const u8 gText_Norman_Pokenav_2B58E3[];
+extern const u8 gText_Norman_Pokenav_2B5979[];
+extern const u8 gText_Norman_Pokenav_2B5A07[];
+extern const u8 gText_Norman_Pokenav_2B5A69[];
+extern const u8 gText_Norman_Pokenav_2B5ACF[];
+extern const u8 gText_Norman_Pokenav_2B5B5E[];
+
+extern const u8 gNormanMatchCallDesc[];
+extern const u8 gNormanMatchCallName[];
+
+extern const u8 gProfBirchMatchCallDesc[];
+extern const u8 gProfBirchMatchCallName[];
+
+extern const u8 gText_Mom_Pokenav_2B227B[];
+extern const u8 gText_Mom_Pokenav_2B2310[];
+extern const u8 gText_Mom_Pokenav_2B23F3[];
+
+extern const u8 gMomMatchCallDesc[];
+extern const u8 gMomMatchCallName[];
+
+extern const u8 gText_Steven_Pokenav_2B5B95[];
+extern const u8 gText_Steven_Pokenav_2B5C53[];
+extern const u8 gText_Steven_Pokenav_2B5CC9[];
+extern const u8 gText_Steven_Pokenav_2B5DB4[];
+extern const u8 gText_Steven_Pokenav_2B5E26[];
+extern const u8 gText_Steven_Pokenav_2B5EA2[];
+extern const u8 gText_Steven_Pokenav_2B5ED9[];
+
+extern const u8 gStevenMatchCallDesc[];
+extern const u8 gStevenMatchCallName[];
+
+extern const u8 gText_May_Pokenav_2B3AB3[];
+extern const u8 gText_May_Pokenav_2B3B3F[];
+extern const u8 gText_May_Pokenav_2B3C13[];
+extern const u8 gText_May_Pokenav_2B3CF3[];
+extern const u8 gText_May_Pokenav_2B3D4B[];
+extern const u8 gText_May_Pokenav_2B3DD1[];
+extern const u8 gText_May_Pokenav_2B3E69[];
+extern const u8 gText_May_Pokenav_2B3ECD[];
+extern const u8 gText_May_Pokenav_2B3F2B[];
+extern const u8 gText_May_Pokenav_2B3FFB[];
+extern const u8 gText_May_Pokenav_2B402B[];
+extern const u8 gText_May_Pokenav_2B414B[];
+extern const u8 gText_May_Pokenav_2B4228[];
+extern const u8 gText_May_Pokenav_2B42E0[];
+extern const u8 gText_May_Pokenav_2B4350[];
+extern const u8 gMayBrendanMatchCallDesc[];
+extern const u8 gExpandedPlaceholder_May[];
+extern const u8 gText_Brendan_Pokenav_2B43EF[];
+extern const u8 gText_Brendan_Pokenav_2B4486[];
+extern const u8 gText_Brendan_Pokenav_2B4560[];
+extern const u8 gText_Brendan_Pokenav_2B463F[];
+extern const u8 gText_Brendan_Pokenav_2B46B7[];
+extern const u8 gText_Brendan_Pokenav_2B4761[];
+extern const u8 gText_Brendan_Pokenav_2B47F4[];
+extern const u8 gText_Brendan_Pokenav_2B4882[];
+extern const u8 gText_Brendan_Pokenav_2B4909[];
+extern const u8 gText_Brendan_Pokenav_2B49C4[];
+extern const u8 gText_Brendan_Pokenav_2B4A44[];
+extern const u8 gText_Brendan_Pokenav_2B4B28[];
+extern const u8 gText_Brendan_Pokenav_2B4C15[];
+extern const u8 gText_Brendan_Pokenav_2B4CD8[];
+extern const u8 gText_Brendan_Pokenav_2B4D46[];
+extern const u8 gExpandedPlaceholder_Brendan[];
+extern const u8 gText_Wally_Pokenav_2B4DE2[];
+extern const u8 gText_Wally_Pokenav_2B4E57[];
+extern const u8 gText_Wally_Pokenav_2B4EA5[];
+extern const u8 gText_Wally_Pokenav_2B4F41[];
+extern const u8 gText_Wally_Pokenav_2B4FF3[];
+extern const u8 gText_Wally_Pokenav_2B50B1[];
+extern const u8 gText_Wally_Pokenav_2B5100[];
+extern const u8 gWallyMatchCallDesc[];
+extern const u8 gText_Scott_Pokenav_2B5184[];
+extern const u8 gText_Scott_Pokenav_2B5275[];
+extern const u8 gText_Scott_Pokenav_2B5323[];
+extern const u8 gText_Scott_Pokenav_2B53DB[];
+extern const u8 gText_Scott_Pokenav_2B54A5[];
+extern const u8 gText_Scott_Pokenav_2B5541[];
+extern const u8 gText_Scott_Pokenav_2B56CA[];
+extern const u8 gScottMatchCallDesc[];
+extern const u8 gScottMatchCallName[];
+extern const u8 gText_Roxanne_Pokenav_2B2456[];
+extern const u8 gText_Roxanne_Pokenav_2B250E[];
+extern const u8 gText_Roxanne_Pokenav_2B25C1[];
+extern const u8 gText_Roxanne_Pokenav_2B2607[];
+extern const u8 gRoxanneMatchCallDesc[];
+extern const u8 gText_Brawly_Pokenav_2B2659[];
+extern const u8 gText_Brawly_Pokenav_2B275D[];
+extern const u8 gText_Brawly_Pokenav_2B286F[];
+extern const u8 gText_Brawly_Pokenav_2B28D1[];
+extern const u8 gBrawlyMatchCallDesc[];
+extern const u8 gText_Wattson_Pokenav_2B2912[];
+extern const u8 gText_Wattson_Pokenav_2B29CA[];
+extern const u8 gText_Wattson_Pokenav_2B2AB6[];
+extern const u8 gText_Wattson_Pokenav_2B2B01[];
+extern const u8 gWattsonMatchCallDesc[];
+extern const u8 gText_Flannery_Pokenav_2B2B4D[];
+extern const u8 gText_Flannery_Pokenav_2B2C0E[];
+extern const u8 gText_Flannery_Pokenav_2B2CF1[];
+extern const u8 gText_Flannery_Pokenav_2B2D54[];
+extern const u8 gFlanneryMatchCallDesc[];
+extern const u8 gText_Winona_Pokenav_2B2DA4[];
+extern const u8 gText_Winona_Pokenav_2B2E2B[];
+extern const u8 gText_Winona_Pokenav_2B2EC2[];
+extern const u8 gText_Winona_Pokenav_2B2F16[];
+extern const u8 gWinonaMatchCallDesc[];
+extern const u8 gText_TateLiza_Pokenav_2B2F97[];
+extern const u8 gText_TateLiza_Pokenav_2B306E[];
+extern const u8 gText_TateLiza_Pokenav_2B3158[];
+extern const u8 gText_TateLiza_Pokenav_2B31CD[];
+extern const u8 gTateLizaMatchCallDesc[];
+extern const u8 gText_Juan_Pokenav_2B3249[];
+extern const u8 gText_Juan_Pokenav_2B32EC[];
+extern const u8 gText_Juan_Pokenav_2B33AA[];
+extern const u8 gText_Juan_Pokenav_2B341E[];
+extern const u8 gJuanMatchCallDesc[];
+extern const u8 gText_Sidney_Pokenav_2B34CC[];
+extern const u8 gEliteFourMatchCallDesc[];
+extern const u8 gText_Phoebe_Pokenav_2B3561[];
+extern const u8 gText_Glacia_Pokenav_2B35E4[];
+extern const u8 gText_Drake_Pokenav_2B368B[];
+extern const u8 gText_Wallace_Pokenav_2B3790[];
+extern const u8 gChampionMatchCallDesc[];
+extern const u8 gMatchCallStevenStrategyText[];
+extern const u8 gMatchCall_StevenTrainersPokemonText[];
+extern const u8 gMatchCall_StevenSelfIntroductionText_Line1_BeforeMeteorFallsBattle[];
+extern const u8 gMatchCall_StevenSelfIntroductionText_Line2_BeforeMeteorFallsBattle[];
+extern const u8 gMatchCall_StevenSelfIntroductionText_Line1_AfterMeteorFallsBattle[];
+extern const u8 gMatchCall_StevenSelfIntroductionText_Line2_AfterMeteorFallsBattle[];
+extern const u8 gMatchCall_BrendanStrategyText[];
+extern const u8 gMatchCall_BrendanTrainersPokemonText[];
+extern const u8 gMatchCall_BrendanSelfIntroductionText_Line1[];
+extern const u8 gMatchCall_BrendanSelfIntroductionText_Line2[];
+extern const u8 gMatchCall_MayStrategyText[];
+extern const u8 gMatchCall_MayTrainersPokemonText[];
+extern const u8 gMatchCall_MaySelfIntroductionText_Line1[];
+extern const u8 gMatchCall_MaySelfIntroductionText_Line2[];
+// .rodata
+
+static const match_call_text_data_t sMrStoneTextScripts[] = {
+ { gText_MrStone_Pokenav_2B60C0, 0xFFFF, FLAG_0x158 },
+ { gText_MrStone_Pokenav_2B61E6, FLAG_0x158, 0xFFFF },
+ { gText_MrStone_Pokenav_2B6302, FLAG_0x0BD, 0xFFFF },
+ { gText_MrStone_Pokenav_2B63A0, FLAG_0x110, 0xFFFF },
+ { gText_MrStone_Pokenav_2B64A2, FLAG_0x06A, 0xFFFF },
+ { gText_MrStone_Pokenav_2B6526, FLAG_0x4F4, 0xFFFF },
+ { gText_MrStone_Pokenav_2B65BB, FLAG_0x097, 0xFFFF },
+ { gText_MrStone_Pokenav_2B6664, FLAG_0x06F, 0xFFFF },
+ { gText_MrStone_Pokenav_2B66B1, FLAG_0x070, 0xFFFF },
+ { gText_MrStone_Pokenav_2B6703, FLAG_0x4F7, 0xFFFF },
+ { gText_MrStone_Pokenav_2B67ED, FLAG_SYS_GAME_CLEAR, 0xFFFF },
+ { NULL, 0xFFFF, 0xFFFF }
+};
+
+MATCHCALLDEF(sMrStoneMatchCallHeader, 0, 10, 0xffff, gMrStoneMatchCallDesc, gMrStoneMatchCallName, sMrStoneTextScripts);
+
+static const match_call_text_data_t sNormanTextScripts[] = {
+ { gText_Norman_Pokenav_2B5719, FLAG_0x132, 0xFFFF },
+ { gText_Norman_Pokenav_2B5795, FLAG_0x4F1, 0xFFFF },
+ { gText_Norman_Pokenav_2B584D, FLAG_0x4F3, 0xFFFF },
+ { gText_Norman_Pokenav_2B58E3, FLAG_0x4F4, 0xFFFF },
+ { gText_Norman_Pokenav_2B5979, FLAG_0x0D4, 0xFFFF },
+ { gText_Norman_Pokenav_2B5A07, 0xFFFE, 0xFFFF },
+ { gText_Norman_Pokenav_2B5A69, FLAG_SYS_GAME_CLEAR, 0xFFFF },
+ { gText_Norman_Pokenav_2B5ACF, FLAG_SYS_GAME_CLEAR, 0xFFFF },
+ { gText_Norman_Pokenav_2B5B5E, FLAG_SYS_GAME_CLEAR, 0xFFFF },
+ { NULL, 0xFFFF, 0xFFFF }
+};
+
+MATCHCALLDEF(sNormanMatchCallHeader, 5, 7, FLAG_0x132, 0x45, gNormanMatchCallDesc, gNormanMatchCallName, sNormanTextScripts);
+
+MATCHCALLDEF(sProfBirchMatchCallHeader, 3, 0, FLAG_0x119, gProfBirchMatchCallDesc, gProfBirchMatchCallName)
+
+static const match_call_text_data_t sMomTextScripts[] = {
+ { gText_Mom_Pokenav_2B227B, 0xffff, 0xffff },
+ { gText_Mom_Pokenav_2B2310, FLAG_0x4F4, 0xffff },
+ { gText_Mom_Pokenav_2B23F3, FLAG_SYS_GAME_CLEAR, 0xffff },
+ { NULL, 0xffff, 0xffff }
+};
+
+MATCHCALLDEF(sMomMatchCallHeader, 0, 0, FLAG_0x0D8, gMomMatchCallDesc, gMomMatchCallName, sMomTextScripts);
+
+static const match_call_text_data_t sStevenTextScripts[] = {
+ { gText_Steven_Pokenav_2B5B95, 0xffff, 0xffff },
+ { gText_Steven_Pokenav_2B5C53, FLAG_0x0C7, 0xffff },
+ { gText_Steven_Pokenav_2B5CC9, FLAG_0x0D4, 0xffff },
+ { gText_Steven_Pokenav_2B5DB4, FLAG_0x070, 0xffff },
+ { gText_Steven_Pokenav_2B5E26, FLAG_0x4F6, 0xffff },
+ { gText_Steven_Pokenav_2B5EA2, FLAG_0x081, 0xffff },
+ { gText_Steven_Pokenav_2B5ED9, FLAG_SYS_GAME_CLEAR, 0xffff },
+ { NULL, 0xffff, 0xffff },
+};
+
+MATCHCALLDEF(sStevenMatchCallHeader, 0, 0xd5, FLAG_0x131, gStevenMatchCallDesc, gStevenMatchCallName, sStevenTextScripts);
+
+static const match_call_text_data_t sMayTextScripts[] = {
+ { gText_May_Pokenav_2B3AB3, 0xFFFF, 0xFFFF },
+ { gText_May_Pokenav_2B3B3F, FLAG_0x4F1, 0xFFFF },
+ { gText_May_Pokenav_2B3C13, FLAG_0x095, 0xFFFF },
+ { gText_May_Pokenav_2B3CF3, FLAG_0x324, 0xFFFF },
+ { gText_May_Pokenav_2B3D4B, FLAG_0x06A, 0xFFFF },
+ { gText_May_Pokenav_2B3DD1, FLAG_0x4F3, 0xFFFF },
+ { gText_May_Pokenav_2B3E69, FLAG_0x4F4, 0xFFFF },
+ { gText_May_Pokenav_2B3ECD, FLAG_0x097, 0xFFFF },
+ { gText_May_Pokenav_2B3F2B, FLAG_0x0D4, 0xFFFF },
+ { gText_May_Pokenav_2B3FFB, FLAG_0x06F, 0xFFFF },
+ { gText_May_Pokenav_2B402B, FLAG_0x061, 0xFFFF },
+ { gText_May_Pokenav_2B414B, FLAG_0x070, 0xFFFF },
+ { gText_May_Pokenav_2B4228, FLAG_0x081, 0xFFFF },
+ { gText_May_Pokenav_2B42E0, FLAG_0x4F7, 0xFFFF },
+ { gText_May_Pokenav_2B4350, FLAG_SYS_GAME_CLEAR, 0xFFFF },
+ { NULL, 0xFFFF, 0xFFFF }
+};
+
+MATCHCALLDEF(sMayMatchCallHeader, 4, MALE, FLAG_0x0FD, gMayBrendanMatchCallDesc, gExpandedPlaceholder_May, sMayTextScripts);
+
+static const match_call_text_data_t sBrendanTextScripts[] = {
+ { gText_Brendan_Pokenav_2B43EF, 0xFFFF, 0xFFFF },
+ { gText_Brendan_Pokenav_2B4486, FLAG_0x4F1, 0xFFFF },
+ { gText_Brendan_Pokenav_2B4560, FLAG_0x095, 0xFFFF },
+ { gText_Brendan_Pokenav_2B463F, FLAG_0x324, 0xFFFF },
+ { gText_Brendan_Pokenav_2B46B7, FLAG_0x06A, 0xFFFF },
+ { gText_Brendan_Pokenav_2B4761, FLAG_0x4F3, 0xFFFF },
+ { gText_Brendan_Pokenav_2B47F4, FLAG_0x4F4, 0xFFFF },
+ { gText_Brendan_Pokenav_2B4882, FLAG_0x097, 0xFFFF },
+ { gText_Brendan_Pokenav_2B4909, FLAG_0x0D4, 0xFFFF },
+ { gText_Brendan_Pokenav_2B49C4, FLAG_0x06F, 0xFFFF },
+ { gText_Brendan_Pokenav_2B4A44, FLAG_0x061, 0xFFFF },
+ { gText_Brendan_Pokenav_2B4B28, FLAG_0x070, 0xFFFF },
+ { gText_Brendan_Pokenav_2B4C15, FLAG_0x081, 0xFFFF },
+ { gText_Brendan_Pokenav_2B4CD8, FLAG_0x4F7, 0xFFFF },
+ { gText_Brendan_Pokenav_2B4D46, FLAG_SYS_GAME_CLEAR, 0xFFFF },
+ { NULL, 0xFFFF, 0xFFFF }
+};
+
+MATCHCALLDEF(sBrendanMatchCallHeader, 4, FEMALE, FLAG_0x0FD, gMayBrendanMatchCallDesc, gExpandedPlaceholder_Brendan, sBrendanTextScripts);
+
+static const match_call_text_data_t sWallyTextScripts[] = {
+ { gText_Wally_Pokenav_2B4DE2, 0xFFFF, 0xFFFF },
+ { gText_Wally_Pokenav_2B4E57, FLAG_0x0C7, 0xFFFF },
+ { gText_Wally_Pokenav_2B4EA5, FLAG_0x4F3, 0xFFFF },
+ { gText_Wally_Pokenav_2B4F41, FLAG_0x097, 0xFFFF },
+ { gText_Wally_Pokenav_2B4FF3, FLAG_0x06F, 0xFFFF },
+ { gText_Wally_Pokenav_2B50B1, FLAG_0x081, 0xFFFF },
+ { gText_Wally_Pokenav_2B5100, FLAG_0x07E, 0xFFFF },
+ { NULL, 0xFFFF, 0xFFFF }
+};
+
+const struct MatchCallSubstruct2 sWallyAdditionalData[] = {
+ { FLAG_0x324, 0x05 },
+ { FLAG_0x06F, 0xD5 },
+ { FLAG_0x35A, 0x46 },
+ { 0xFFFF, 0xD5 }
+};
+
+MATCHCALLDEF(sWallyMatchCallHeader, 2, 0, FLAG_0x0D6, REMATCH_WALLY_3, gWallyMatchCallDesc, sWallyTextScripts, sWallyAdditionalData);
+
+static const match_call_text_data_t sScottTextScripts[] = {
+ { gText_Scott_Pokenav_2B5184, 0xFFFF, 0xFFFF },
+ { gText_Scott_Pokenav_2B5275, FLAG_0x08B, 0xFFFF },
+ { gText_Scott_Pokenav_2B5323, FLAG_0x097, 0xFFFF },
+ { gText_Scott_Pokenav_2B53DB, FLAG_0x0D4, 0xFFFF },
+ { gText_Scott_Pokenav_2B54A5, FLAG_0x070, 0xFFFF },
+ { gText_Scott_Pokenav_2B5541, FLAG_0x4F7, 0xFFFF },
+ { gText_Scott_Pokenav_2B56CA, FLAG_SYS_GAME_CLEAR, 0xFFFF },
+ { NULL, 0xFFFF, 0xFFFF }
+};
+
+
+MATCHCALLDEF(sScottMatchCallHeader, 0, 0xD5, FLAG_0x0D7, gScottMatchCallDesc, gScottMatchCallName, sScottTextScripts);
+
+static const match_call_text_data_t sRoxanneTextScripts[] = {
+ { gText_Roxanne_Pokenav_2B2456, 0xFFFE, 0xFFFF },
+ { gText_Roxanne_Pokenav_2B250E, 0xFFFF, 0xFFFF },
+ { gText_Roxanne_Pokenav_2B25C1, 0xFFFF, 0xFFFF },
+ { gText_Roxanne_Pokenav_2B2607, FLAG_SYS_GAME_CLEAR, 0xFFFF },
+ { NULL, 0xFFFF, 0xFFFF }
+};
+
+MATCHCALLDEF(sRoxanneMatchCallHeader, 5, 10, FLAG_0x1D3, 0x41, gRoxanneMatchCallDesc, NULL, sRoxanneTextScripts);
+
+static const match_call_text_data_t sBrawlyTextScripts[] = {
+ { gText_Brawly_Pokenav_2B2659, 0xFFFE, 0xFFFF },
+ { gText_Brawly_Pokenav_2B275D, 0xFFFF, 0xFFFF },
+ { gText_Brawly_Pokenav_2B286F, 0xFFFF, 0xFFFF },
+ { gText_Brawly_Pokenav_2B28D1, FLAG_SYS_GAME_CLEAR, 0xFFFF },
+ { NULL, 0xFFFF, 0xFFFF }
+};
+
+MATCHCALLDEF(sBrawlyMatchCallHeader, 5, 2, FLAG_0x1D4, 0x42, gBrawlyMatchCallDesc, NULL, sBrawlyTextScripts);
+
+static const match_call_text_data_t sWattsonTextScripts[] = {
+ { gText_Wattson_Pokenav_2B2912, 0xFFFE, 0xFFFF },
+ { gText_Wattson_Pokenav_2B29CA, 0xFFFF, 0xFFFF },
+ { gText_Wattson_Pokenav_2B2AB6, 0xFFFF, 0xFFFF },
+ { gText_Wattson_Pokenav_2B2B01, FLAG_SYS_GAME_CLEAR, 0xFFFF },
+ { NULL, 0xFFFF, 0xFFFF }
+};
+
+MATCHCALLDEF(sWattsonMatchCallHeader, 5, 9, FLAG_0x1D5, 0x43, gWattsonMatchCallDesc, NULL, sWattsonTextScripts);
+
+static const match_call_text_data_t sFlanneryTextScripts[] = {
+ { gText_Flannery_Pokenav_2B2B4D, 0xFFFE, 0xFFFF },
+ { gText_Flannery_Pokenav_2B2C0E, 0xFFFF, 0xFFFF },
+ { gText_Flannery_Pokenav_2B2CF1, 0xFFFF, 0xFFFF },
+ { gText_Flannery_Pokenav_2B2D54, FLAG_SYS_GAME_CLEAR, 0xFFFF },
+ { NULL, 0xFFFF, 0xFFFF }
+};
+
+MATCHCALLDEF(sFlanneryMatchCallHeader, 5, 3, FLAG_0x1D6, 0x44, gFlanneryMatchCallDesc, NULL, sFlanneryTextScripts);
+
+static const match_call_text_data_t sWinonaTextScripts[] = {
+ { gText_Winona_Pokenav_2B2DA4, 0xFFFE, 0xFFFF },
+ { gText_Winona_Pokenav_2B2E2B, 0xFFFF, 0xFFFF },
+ { gText_Winona_Pokenav_2B2EC2, 0xFFFF, 0xFFFF },
+ { gText_Winona_Pokenav_2B2F16, FLAG_SYS_GAME_CLEAR, 0xFFFF },
+ { NULL, 0xFFFF, 0xFFFF }
+};
+
+MATCHCALLDEF(sWinonaMatchCallHeader, 5, 11, FLAG_0x1D7, 0x46, gWinonaMatchCallDesc, NULL, sWinonaTextScripts);
+
+static const match_call_text_data_t sTateLizaTextScripts[] = {
+ { gText_TateLiza_Pokenav_2B2F97, 0xFFFE, 0xFFFF },
+ { gText_TateLiza_Pokenav_2B306E, 0xFFFF, 0xFFFF },
+ { gText_TateLiza_Pokenav_2B3158, 0xFFFF, 0xFFFF },
+ { gText_TateLiza_Pokenav_2B31CD, FLAG_SYS_GAME_CLEAR, 0xFFFF },
+ { NULL, 0xFFFF, 0xFFFF }
+};
+
+MATCHCALLDEF(sTateLizaMatchCallHeader, 5, 13, FLAG_0x1D8, 0x47, gTateLizaMatchCallDesc, NULL, sTateLizaTextScripts);
+
+static const match_call_text_data_t sJuanTextScripts[] = {
+ { gText_Juan_Pokenav_2B3249, 0xFFFE, 0xFFFF },
+ { gText_Juan_Pokenav_2B32EC, 0xFFFF, 0xFFFF },
+ { gText_Juan_Pokenav_2B33AA, 0xFFFF, 0xFFFF },
+ { gText_Juan_Pokenav_2B341E, FLAG_SYS_GAME_CLEAR, 0xFFFF },
+ { NULL, 0xFFFF, 0xFFFF }
+};
+
+MATCHCALLDEF(sJuanMatchCallHeader, 5, 14, FLAG_0x1D9, 0x48, gJuanMatchCallDesc, NULL, sJuanTextScripts);
+
+static const match_call_text_data_t sSidneyTextScripts[] = {
+ { gText_Sidney_Pokenav_2B34CC, 0xFFFF, 0xFFFF },
+ { NULL, 0xFFFF, 0xFFFF }
+};
+
+MATCHCALLDEF(sSidneyMatchCallHeader, 5, 15, FLAG_0x1A5, 0x49, gEliteFourMatchCallDesc, NULL, sSidneyTextScripts);
+
+static const match_call_text_data_t sPhoebeTextScripts[] = {
+ { gText_Phoebe_Pokenav_2B3561, 0xFFFF, 0xFFFF },
+ { NULL, 0xFFFF, 0xFFFF }
+};
+
+MATCHCALLDEF(sPhoebeMatchCallHeader, 5, 15, FLAG_0x1A6, 0x4A, gEliteFourMatchCallDesc, NULL, sPhoebeTextScripts);
+
+static const match_call_text_data_t sGlaciaTextScripts[] = {
+ { gText_Glacia_Pokenav_2B35E4, 0xFFFF, 0xFFFF },
+ { NULL, 0xFFFF, 0xFFFF }
+};
+
+MATCHCALLDEF(sGlaciaMatchCallHeader, 5, 15, FLAG_0x1A7, 0x4B, gEliteFourMatchCallDesc, NULL, sGlaciaTextScripts);
+
+static const match_call_text_data_t sDrakeTextScripts[] = {
+ { gText_Drake_Pokenav_2B368B, 0xFFFF, 0xFFFF },
+ { NULL, 0xFFFF, 0xFFFF }
+};
+
+MATCHCALLDEF(sDrakeMatchCallHeader, 5, 15, FLAG_0x1A8, 0x4C, gEliteFourMatchCallDesc, NULL, sDrakeTextScripts);
+
+static const match_call_text_data_t sWallaceTextScripts[] = {
+ { gText_Wallace_Pokenav_2B3790, 0xFFFF, 0xFFFF },
+ { NULL, 0xFFFF, 0xFFFF }
+};
+
+MATCHCALLDEF(sWallaceMatchCallHeader, 5, 15, FLAG_0x1A9, 0x4D, gChampionMatchCallDesc, NULL, sWallaceTextScripts);
+
+static const match_call_t sMatchCallHeaders[] = {
+ {.type0 = &sMrStoneMatchCallHeader},
+ {.type3 = &sProfBirchMatchCallHeader},
+ {.type4 = &sBrendanMatchCallHeader},
+ {.type4 = &sMayMatchCallHeader},
+ {.type2 = &sWallyMatchCallHeader},
+ {.type5 = &sNormanMatchCallHeader},
+ {.type0 = &sMomMatchCallHeader},
+ {.type0 = &sStevenMatchCallHeader},
+ {.type0 = &sScottMatchCallHeader},
+ {.type5 = &sRoxanneMatchCallHeader},
+ {.type5 = &sBrawlyMatchCallHeader},
+ {.type5 = &sWattsonMatchCallHeader},
+ {.type5 = &sFlanneryMatchCallHeader},
+ {.type5 = &sWinonaMatchCallHeader},
+ {.type5 = &sTateLizaMatchCallHeader},
+ {.type5 = &sJuanMatchCallHeader},
+ {.type5 = &sSidneyMatchCallHeader},
+ {.type5 = &sPhoebeMatchCallHeader},
+ {.type5 = &sGlaciaMatchCallHeader},
+ {.type5 = &sDrakeMatchCallHeader},
+ {.type5 = &sWallaceMatchCallHeader}
+};
+
+static bool32 (*const sMatchCallGetFlagFuncs[])(match_call_t) = {
+ MatchCallGetFlag_Type0,
+ MatchCallGetFlag_Type1,
+ MatchCallGetFlag_Type2,
+ MatchCallGetFlag_Type3,
+ MatchCallGetFlag_Type4
+};
+
+static u8 (*const gUnknown_08625310[])(match_call_t) = {
+ sub_81D1714,
+ sub_81D1718,
+ sub_81D171C,
+ sub_81D1750,
+ sub_81D1754
+};
+
+static bool32 (*const sMatchCall_IsRematchableFunctions[])(match_call_t) = {
+ MatchCall_IsRematchable_Type0,
+ MatchCall_IsRematchable_Type1,
+ MatchCall_IsRematchable_Type2,
+ MatchCall_IsRematchable_Type3,
+ MatchCall_IsRematchable_Type4
+};
+
+static bool32 (*const gUnknown_08625338[])(match_call_t) = {
+ sub_81D1840,
+ sub_81D1844,
+ sub_81D1848,
+ sub_81D184C,
+ sub_81D1850
+};
+
+static u32 (*const sMatchCall_GetRematchTableIdxFunctions[])(match_call_t) = {
+ MatchCall_GetRematchTableIdx_Type0,
+ MatchCall_GetRematchTableIdx_Type1,
+ MatchCall_GetRematchTableIdx_Type2,
+ MatchCall_GetRematchTableIdx_Type3,
+ MatchCall_GetRematchTableIdx_Type4
+};
+
+static void (*const sMatchCall_GetMessageFunctions[])(match_call_t, u8 *) = {
+ MatchCall_GetMessage_Type0,
+ MatchCall_GetMessage_Type1,
+ MatchCall_GetMessage_Type2,
+ MatchCall_GetMessage_Type3,
+ MatchCall_GetMessage_Type4
+};
+
+static void (*const sMatchCall_GetNameAndDescFunctions[])(match_call_t, const u8 **, const u8 **) = {
+ MatchCall_GetNameAndDesc_Type0,
+ MatchCall_GetNameAndDesc_Type1,
+ MatchCall_GetNameAndDesc_Type2,
+ MatchCall_GetNameAndDesc_Type3,
+ MatchCall_GetNameAndDesc_Type4
+};
+
+static const struct UnkStruct_08625388 sMatchCallCheckPageOverrides[] = {
+ { 7, 0x4B, 0xffff, { gMatchCallStevenStrategyText, gMatchCall_StevenTrainersPokemonText, gMatchCall_StevenSelfIntroductionText_Line1_BeforeMeteorFallsBattle, gMatchCall_StevenSelfIntroductionText_Line2_BeforeMeteorFallsBattle } }, // STEVEN
+ { 7, 0x4B, FLAG_0x4F6, { gMatchCallStevenStrategyText, gMatchCall_StevenTrainersPokemonText, gMatchCall_StevenSelfIntroductionText_Line1_AfterMeteorFallsBattle, gMatchCall_StevenSelfIntroductionText_Line2_AfterMeteorFallsBattle } }, // STEVEN
+ { 2, 0x3c, 0xffff, { gMatchCall_BrendanStrategyText, gMatchCall_BrendanTrainersPokemonText, gMatchCall_BrendanSelfIntroductionText_Line1, gMatchCall_BrendanSelfIntroductionText_Line2 } }, // Brendan
+ { 3, 0x3f, 0xffff, { gMatchCall_MayStrategyText, gMatchCall_MayTrainersPokemonText, gMatchCall_MaySelfIntroductionText_Line1, gMatchCall_MaySelfIntroductionText_Line2 } } // May
+};
+
+// .text
+
+static u32 MatchCallGetFunctionIndex(match_call_t matchCall)
+{
+ switch (matchCall.common->type)
+ {
+ case 0:
+ default:
+ return 0;
+ case 1:
+ case 5:
+ return 1;
+ case 2:
+ return 2;
+ case 4:
+ return 3;
+ case 3:
+ return 4;
+ }
+}
+
+u32 GetTrainerIdxByRematchIdx(u32 rematchIdx)
+{
+ return gRematchTable[rematchIdx].trainerIds[0];
+}
+
+s32 GetRematchIdxByTrainerIdx(s32 trainerIdx)
+{
+ s32 rematchIdx;
+
+ for (rematchIdx = 0; rematchIdx < REMATCH_TABLE_ENTRIES; rematchIdx++)
+ {
+ if (gRematchTable[rematchIdx].trainerIds[0] == trainerIdx)
+ return rematchIdx;
+ }
+ return -1;
+}
+
+bool32 MatchCallFlagGetByIndex(u32 idx)
+{
+ match_call_t matchCall;
+ u32 i;
+
+ if (idx > 20)
+ return FALSE;
+ matchCall = sMatchCallHeaders[idx];
+ i = MatchCallGetFunctionIndex(matchCall);
+ return sMatchCallGetFlagFuncs[i](matchCall);
+}
+
+static bool32 MatchCallGetFlag_Type0(match_call_t matchCall)
+{
+ if (matchCall.type0->flag == 0xffff)
+ return TRUE;
+ return FlagGet(matchCall.type0->flag);
+}
+
+static bool32 MatchCallGetFlag_Type1(match_call_t matchCall)
+{
+ if (matchCall.type1->flag == 0xffff)
+ return TRUE;
+ return FlagGet(matchCall.type1->flag);
+}
+
+static bool32 MatchCallGetFlag_Type2(match_call_t matchCall)
+{
+ if (matchCall.type2->flag == 0xffff)
+ return TRUE;
+ return FlagGet(matchCall.type2->flag);
+}
+
+static bool32 MatchCallGetFlag_Type3(match_call_t matchCall)
+{
+ if (matchCall.type4->gender != gSaveBlock2Ptr->playerGender)
+ return FALSE;
+ if (matchCall.type4->flag == 0xffff)
+ return TRUE;
+ return FlagGet(matchCall.type4->flag);
+}
+
+static bool32 MatchCallGetFlag_Type4(match_call_t matchCall)
+{
+ return FlagGet(matchCall.type3->flag);
+}
+
+u8 sub_81D16DC(u32 idx)
+{
+ match_call_t matchCall;
+ u32 i;
+
+ if (idx > 20)
+ return 0;
+ matchCall = sMatchCallHeaders[idx];
+ i = MatchCallGetFunctionIndex(matchCall);
+ return gUnknown_08625310[i](matchCall);
+}
+
+static u8 sub_81D1714(match_call_t matchCall)
+{
+ return matchCall.type0->v1;
+}
+
+static u8 sub_81D1718(match_call_t matchCall)
+{
+ return matchCall.type1->v1;
+}
+
+static u8 sub_81D171C(match_call_t matchCall)
+{
+ s32 i;
+
+ for (i = 0; matchCall.type2->v10[i].flag != 0xffff; i++)
+ {
+ if (!FlagGet(matchCall.type2->v10[i].flag))
+ break;
+ }
+ return matchCall.type2->v10[i].v2;
+}
+
+static u8 sub_81D1750(match_call_t matchCall)
+{
+ return 0xd5;
+}
+
+static u8 sub_81D1754(match_call_t matchCall)
+{
+ return 0xd5;
+}
+
+bool32 MatchCall_IsRematchable(u32 idx)
+{
+ match_call_t matchCall;
+ u32 i;
+
+ if (idx > 20)
+ return 0;
+ matchCall = sMatchCallHeaders[idx];
+ i = MatchCallGetFunctionIndex(matchCall);
+ return sMatchCall_IsRematchableFunctions[i](matchCall);
+}
+
+static bool32 MatchCall_IsRematchable_Type0(match_call_t matchCall)
+{
+ return FALSE;
+}
+
+static bool32 MatchCall_IsRematchable_Type1(match_call_t matchCall)
+{
+ if (matchCall.type1->rematchTableIdx >= REMATCH_ELITE_FOUR_ENTRIES)
+ return FALSE;
+ return gSaveBlock1Ptr->trainerRematches[matchCall.type1->rematchTableIdx] ? TRUE : FALSE;
+}
+
+static bool32 MatchCall_IsRematchable_Type2(match_call_t matchCall)
+{
+ return gSaveBlock1Ptr->trainerRematches[matchCall.type2->rematchTableIdx] ? TRUE : FALSE;
+}
+
+static bool32 MatchCall_IsRematchable_Type3(match_call_t matchCall)
+{
+ return FALSE;
+}
+
+static bool32 MatchCall_IsRematchable_Type4(match_call_t matchCall)
+{
+ return FALSE;
+}
+
+bool32 sub_81D17E8(u32 idx)
+{
+ match_call_t matchCall;
+ u32 i;
+
+ if (idx > 20)
+ return FALSE;
+ matchCall = sMatchCallHeaders[idx];
+ i = MatchCallGetFunctionIndex(matchCall);
+ if (gUnknown_08625338[i](matchCall))
+ return TRUE;
+ for (i = 0; i < 4; i++)
+ {
+ if (sMatchCallCheckPageOverrides[i].idx == idx)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool32 sub_81D1840(match_call_t matchCall)
+{
+ return FALSE;
+}
+
+static bool32 sub_81D1844(match_call_t matchCall)
+{
+ return TRUE;
+}
+
+static bool32 sub_81D1848(match_call_t matchCall)
+{
+ return TRUE;
+}
+
+static bool32 sub_81D184C(match_call_t matchCall)
+{
+ return FALSE;
+}
+
+static bool32 sub_81D1850(match_call_t matchCall)
+{
+ return FALSE;
+}
+
+u32 MatchCall_GetRematchTableIdx(u32 idx)
+{
+ match_call_t matchCall;
+ u32 i;
+
+ if (idx > 20)
+ return REMATCH_TABLE_ENTRIES;
+ matchCall = sMatchCallHeaders[idx];
+ i = MatchCallGetFunctionIndex(matchCall);
+ return sMatchCall_GetRematchTableIdxFunctions[i](matchCall);
+}
+
+static u32 MatchCall_GetRematchTableIdx_Type0(match_call_t matchCall)
+{
+ return REMATCH_TABLE_ENTRIES;
+}
+
+static u32 MatchCall_GetRematchTableIdx_Type1(match_call_t matchCall)
+{
+ return matchCall.type1->rematchTableIdx;
+}
+
+static u32 MatchCall_GetRematchTableIdx_Type2(match_call_t matchCall)
+{
+ return matchCall.type2->rematchTableIdx;
+}
+
+static u32 MatchCall_GetRematchTableIdx_Type3(match_call_t matchCall)
+{
+ return REMATCH_TABLE_ENTRIES;
+}
+
+static u32 MatchCall_GetRematchTableIdx_Type4(match_call_t matchCall)
+{
+ return REMATCH_TABLE_ENTRIES;
+}
+
+void MatchCall_GetMessage(u32 idx, u8 *dest)
+{
+ match_call_t matchCall;
+ u32 i;
+
+ if (idx > 20)
+ return;
+ matchCall = sMatchCallHeaders[idx];
+ i = MatchCallGetFunctionIndex(matchCall);
+ sMatchCall_GetMessageFunctions[i](matchCall, dest);
+}
+
+static void MatchCall_GetMessage_Type0(match_call_t matchCall, u8 *dest)
+{
+ sub_81D1920(matchCall.type0->textData, dest);
+}
+
+static void MatchCall_GetMessage_Type1(match_call_t matchCall, u8 *dest)
+{
+ if (matchCall.common->type != 5)
+ sub_81D1920(matchCall.type5->textData, dest);
+ else
+ sub_81D199C(matchCall.type1->textData, matchCall.type1->rematchTableIdx, dest);
+}
+
+static void MatchCall_GetMessage_Type2(match_call_t matchCall, u8 *dest)
+{
+ sub_81D1920(matchCall.type2->textData, dest);
+}
+
+static void MatchCall_GetMessage_Type3(match_call_t matchCall, u8 *dest)
+{
+ sub_81D1920(matchCall.type4->textData, dest);
+}
+
+static void MatchCall_GetMessage_Type4(match_call_t matchCall, u8 *dest)
+{
+ sub_8197080(dest);
+}
+
+void sub_81D1920(const match_call_text_data_t *sub0, u8 *dest)
+{
+ u32 i;
+ for (i = 0; sub0[i].text != NULL; i++)
+ ;
+ if (i)
+ i--;
+ while (i)
+ {
+ if (sub0[i].flag != 0xffff && FlagGet(sub0[i].flag) == TRUE)
+ break;
+ i--;
+ }
+ if (sub0[i].flag2 != 0xffff)
+ FlagSet(sub0[i].flag2);
+ StringExpandPlaceholders(dest, sub0[i].text);
+}
+
+#ifdef NONMATCHING
+// There's some weird upmerge going on that I cannot replicate at this time.
+static void sub_81D199C(const match_call_text_data_t *sub0, u16 idx, u8 *dest)
+{
+ u32 i;
+ for (i = 0; sub0[i].text != NULL; i++)
+ {
+ if (sub0[i].flag == 0xfffe)
+ break;
+ if (sub0[i].flag == 0xffff && !FlagGet(sub0[i].flag))
+ break;
+ }
+ if (sub0[i].flag != 0xfffe)
+ {
+ if (i)
+ i--;
+ if (sub0[i].flag2 != 0xffff)
+ FlagSet(sub0[i].flag2);
+ StringExpandPlaceholders(dest, sub0[i].text);
+ }
+ else
+ {
+ if (!FlagGet(FLAG_SYS_GAME_CLEAR))
+ ;
+ else if (gSaveBlock1Ptr->trainerRematches[idx])
+ i += 2;
+ else if (CountBattledRematchTeams(idx) >= 2)
+ i += 3;
+ else
+ i++;
+ StringExpandPlaceholders(dest, sub0[i].text);
+ }
+}
+#else
+static NAKED void sub_81D199C(const match_call_text_data_t *sub0, u16 idx, u8 *dest)
+{
+ asm_unified("\tpush {r4-r7,lr}\n"
+ "\tmov r7, r10\n"
+ "\tmov r6, r9\n"
+ "\tmov r5, r8\n"
+ "\tpush {r5-r7}\n"
+ "\tadds r6, r0, 0\n"
+ "\tmov r10, r2\n"
+ "\tlsls r1, 16\n"
+ "\tlsrs r7, r1, 16\n"
+ "\tmovs r5, 0\n"
+ "\tldr r0, [r6]\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _081D19E6\n"
+ "\tldrh r0, [r6, 0x4]\n"
+ "\tldr r1, =0x0000fffe\n"
+ "\tcmp r0, r1\n"
+ "\tbeq _081D1A24\n"
+ "\tldr r0, =0x0000ffff\n"
+ "\tmov r9, r0\n"
+ "\tmov r8, r1\n"
+ "\tadds r4, r6, 0\n"
+ "_081D19C6:\n"
+ "\tldrh r0, [r4, 0x4]\n"
+ "\tcmp r0, r9\n"
+ "\tbeq _081D19D6\n"
+ "\tbl FlagGet\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _081D19E6\n"
+ "_081D19D6:\n"
+ "\tadds r4, 0x8\n"
+ "\tadds r5, 0x1\n"
+ "\tldr r0, [r4]\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _081D19E6\n"
+ "\tldrh r0, [r4, 0x4]\n"
+ "\tcmp r0, r8\n"
+ "\tbne _081D19C6\n"
+ "_081D19E6:\n"
+ "\tlsls r0, r5, 3\n"
+ "\tadds r0, r6\n"
+ "\tldrh r1, [r0, 0x4]\n"
+ "\tldr r0, =0x0000fffe\n"
+ "\tcmp r1, r0\n"
+ "\tbeq _081D1A24\n"
+ "\tcmp r5, 0\n"
+ "\tbeq _081D19F8\n"
+ "\tsubs r5, 0x1\n"
+ "_081D19F8:\n"
+ "\tlsls r0, r5, 3\n"
+ "\tadds r4, r0, r6\n"
+ "\tldrh r1, [r4, 0x6]\n"
+ "\tldr r0, =0x0000ffff\n"
+ "\tcmp r1, r0\n"
+ "\tbeq _081D1A0A\n"
+ "\tadds r0, r1, 0\n"
+ "\tbl FlagSet\n"
+ "_081D1A0A:\n"
+ "\tldr r1, [r4]\n"
+ "\tmov r0, r10\n"
+ "\tbl StringExpandPlaceholders\n"
+ "\tb _081D1A5C\n"
+ "\t.pool\n"
+ "_081D1A1C:\n"
+ "\tadds r5, 0x2\n"
+ "\tb _081D1A50\n"
+ "_081D1A20:\n"
+ "\tadds r5, 0x3\n"
+ "\tb _081D1A50\n"
+ "_081D1A24:\n"
+ "\tldr r0, =0x00000864\n"
+ "\tbl FlagGet\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _081D1A50\n"
+ "\tldr r0, =gSaveBlock1Ptr\n"
+ "\tldr r0, [r0]\n"
+ "\tldr r1, =0x000009ca\n"
+ "\tadds r0, r1\n"
+ "\tadds r0, r7\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r0, 0\n"
+ "\tbne _081D1A1C\n"
+ "\tadds r0, r7, 0\n"
+ "\tbl CountBattledRematchTeams\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r0, 16\n"
+ "\tcmp r0, 0x1\n"
+ "\tbhi _081D1A20\n"
+ "\tadds r5, 0x1\n"
+ "_081D1A50:\n"
+ "\tlsls r0, r5, 3\n"
+ "\tadds r0, r6\n"
+ "\tldr r1, [r0]\n"
+ "\tmov r0, r10\n"
+ "\tbl StringExpandPlaceholders\n"
+ "_081D1A5C:\n"
+ "\tpop {r3-r5}\n"
+ "\tmov r8, r3\n"
+ "\tmov r9, r4\n"
+ "\tmov r10, r5\n"
+ "\tpop {r4-r7}\n"
+ "\tpop {r0}\n"
+ "\tbx r0\n"
+ "\t.pool");
+}
+#endif
+
+void sub_81D1A78(u32 idx, const u8 **desc, const u8 **name)
+{
+ match_call_t matchCall;
+ u32 i;
+
+ if (idx > 20)
+ return;
+ matchCall = sMatchCallHeaders[idx];
+ i = MatchCallGetFunctionIndex(matchCall);
+ sMatchCall_GetNameAndDescFunctions[i](matchCall, desc, name);
+}
+
+static void MatchCall_GetNameAndDesc_Type0(match_call_t matchCall, const u8 **desc, const u8 **name)
+{
+ *desc = matchCall.type0->desc;
+ *name = matchCall.type0->name;
+}
+
+static void MatchCall_GetNameAndDesc_Type1(match_call_t matchCall, const u8 **desc, const u8 **name)
+{
+ match_call_t _matchCall = matchCall;
+ if (_matchCall.type1->name == NULL)
+ MatchCall_GetNameAndDescByRematchIdx(_matchCall.type1->rematchTableIdx, desc, name);
+ else
+ *name = _matchCall.type1->name;
+ *desc = _matchCall.type1->desc;
+}
+
+static void MatchCall_GetNameAndDesc_Type2(match_call_t matchCall, const u8 **desc, const u8 **name)
+{
+ MatchCall_GetNameAndDescByRematchIdx(matchCall.type2->rematchTableIdx, desc, name);
+ *desc = matchCall.type2->desc;
+}
+
+static void MatchCall_GetNameAndDesc_Type3(match_call_t matchCall, const u8 **desc, const u8 **name)
+{
+ *desc = matchCall.type4->desc;
+ *name = matchCall.type4->name;
+}
+
+static void MatchCall_GetNameAndDesc_Type4(match_call_t matchCall, const u8 **desc, const u8 **name)
+{
+ *desc = matchCall.type3->desc;
+ *name = matchCall.type3->name;
+}
+
+static void MatchCall_GetNameAndDescByRematchIdx(u32 idx, const u8 **desc, const u8 **name)
+{
+ const struct Trainer *trainer = gTrainers + GetTrainerIdxByRematchIdx(idx);
+ *desc = gTrainerClassNames[trainer->trainerClass];
+ *name = trainer->trainerName;
+}
+
+#ifdef NONMATCHING
+const u8 *sub_81D1B40(u32 idx, u32 offset)
+{
+ u32 i;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (sMatchCallCheckPageOverrides[i].idx == idx)
+ {
+ for (; i + 1 < 4 && sMatchCallCheckPageOverrides[i + 1].idx == idx; i++)
+ {
+ if (!FlagGet(sMatchCallCheckPageOverrides[i + 1].v4))
+ break;
+ }
+ return sMatchCallCheckPageOverrides[i].v8[offset];
+ }
+ }
+ return NULL;
+}
+#else
+NAKED const u8 *sub_81D1B40(u32 idx, u32 offset)
+{
+ asm_unified("\tpush {r4-r7,lr}\n"
+ "\tmov r7, r9\n"
+ "\tmov r6, r8\n"
+ "\tpush {r6,r7}\n"
+ "\tadds r6, r0, 0\n"
+ "\tmovs r5, 0\n"
+ "\tldr r2, =sMatchCallCheckPageOverrides\n"
+ "\tmovs r0, 0x8\n"
+ "\tadds r0, r2\n"
+ "\tmov r9, r0\n"
+ "_081D1B54:\n"
+ "\tlsls r0, r5, 1\n"
+ "\tadds r0, r5\n"
+ "\tlsls r0, 3\n"
+ "\tadds r0, r2\n"
+ "\tldrh r0, [r0]\n"
+ "\tcmp r0, r6\n"
+ "\tbne _081D1BBC\n"
+ "\tadds r4, r5, 0x1\n"
+ "\tlsls r1, 2\n"
+ "\tmov r8, r1\n"
+ "\tcmp r4, 0x3\n"
+ "\tbhi _081D1BA8\n"
+ "\tlsls r0, r4, 1\n"
+ "\tadds r0, r4\n"
+ "\tlsls r0, 3\n"
+ "\tadds r0, r2\n"
+ "\tldrh r0, [r0]\n"
+ "\tcmp r0, r6\n"
+ "\tbne _081D1BA8\n"
+ "\tldr r7, =sMatchCallCheckPageOverrides\n"
+ "_081D1B7C:\n"
+ "\tlsls r0, r4, 1\n"
+ "\tadds r0, r4\n"
+ "\tlsls r0, 3\n"
+ "\tadds r1, r7, 0x4\n"
+ "\tadds r0, r1\n"
+ "\tldrh r0, [r0]\n"
+ "\tbl FlagGet\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _081D1BA8\n"
+ "\tadds r5, r4, 0\n"
+ "\tadds r4, r5, 0x1\n"
+ "\tcmp r4, 0x3\n"
+ "\tbhi _081D1BA8\n"
+ "\tlsls r0, r4, 1\n"
+ "\tadds r0, r4\n"
+ "\tlsls r0, 3\n"
+ "\tadds r0, r7\n"
+ "\tldrh r0, [r0]\n"
+ "\tcmp r0, r6\n"
+ "\tbeq _081D1B7C\n"
+ "_081D1BA8:\n"
+ "\tlsls r0, r5, 1\n"
+ "\tadds r0, r5\n"
+ "\tlsls r0, 3\n"
+ "\tadd r0, r8\n"
+ "\tadd r0, r9\n"
+ "\tldr r0, [r0]\n"
+ "\tb _081D1BC4\n"
+ "\t.pool\n"
+ "_081D1BBC:\n"
+ "\tadds r5, 0x1\n"
+ "\tcmp r5, 0x3\n"
+ "\tbls _081D1B54\n"
+ "\tmovs r0, 0\n"
+ "_081D1BC4:\n"
+ "\tpop {r3,r4}\n"
+ "\tmov r8, r3\n"
+ "\tmov r9, r4\n"
+ "\tpop {r4-r7}\n"
+ "\tpop {r1}\n"
+ "\tbx r1");
+}
+#endif
+
+s32 sub_81D1BD0(u32 idx)
+{
+ u32 i;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (sMatchCallCheckPageOverrides[i].idx == idx)
+ return sMatchCallCheckPageOverrides[i].v2;
+ }
+ return -1;
+}
+
+bool32 sub_81D1BF8(u32 idx)
+{
+ s32 i;
+
+ for (i = 0; i < 21; i++)
+ {
+ u32 r0 = MatchCall_GetRematchTableIdx(i);
+ if (r0 != REMATCH_TABLE_ENTRIES && r0 == idx)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void SetMatchCallRegisteredFlag(void)
+{
+ s32 r0 = GetRematchIdxByTrainerIdx(gSpecialVar_0x8004);
+ if (r0 >= 0)
+ FlagSet(FLAG_MATCH_CALL_REGISTERED + r0);
+}
diff --git a/src/mauville_old_man.c b/src/mauville_old_man.c
new file mode 100644
index 000000000..5c8be1581
--- /dev/null
+++ b/src/mauville_old_man.c
@@ -0,0 +1,1247 @@
+#include "global.h"
+#include "main.h"
+#include "constants/songs.h"
+#include "constants/easy_chat.h"
+#include "constants/map_objects.h"
+#include "constants/vars.h"
+#include "mauville_old_man.h"
+#include "event_data.h"
+#include "string_util.h"
+#include "text.h"
+#include "easy_chat.h"
+#include "script.h"
+#include "random.h"
+#include "event_scripts.h"
+#include "task.h"
+#include "menu.h"
+#include "m4a.h"
+#include "bard_music.h"
+#include "sound.h"
+#include "strings.h"
+#include "overworld.h"
+#include "field_message_box.h"
+#include "script_menu.h"
+#include "trader.h"
+
+#define CHAR_SONG_WORD_SEPARATOR 0x37
+
+extern struct MusicPlayerInfo gMPlayInfo_SE2;
+
+static void InitGiddyTaleList(void);
+static void StartBardSong(bool8 useTemporaryLyrics);
+static void Task_BardSong(u8 taskId);
+static void StorytellerSetup(void);
+static void Storyteller_ResetFlag(void);
+
+IWRAM_DATA u8 sSelectedStory;
+
+struct BardSong gBardSong;
+
+static EWRAM_DATA u16 sUnknownBardRelated = 0;
+static EWRAM_DATA struct MauvilleManStoryteller * sStorytellerPtr = NULL;
+static EWRAM_DATA u8 sStorytellerWindowId = 0;
+
+static const u16 sDefaultBardSongLyrics[6] = {
+ EC_WORD_SHAKE,
+ EC_WORD_IT,
+ EC_WORD_DO,
+ EC_WORD_THE,
+ EC_WORD_DIET,
+ EC_WORD_DANCE
+};
+
+static const u8 * const sGiddyAdjectives[] = {
+ gText_SoPretty,
+ gText_SoDarling,
+ gText_SoRelaxed,
+ gText_SoSunny,
+ gText_SoDesirable,
+ gText_SoExciting,
+ gText_SoAmusing,
+ gText_SoMagical
+};
+
+static const u8 * const sGiddyQuestions[] = {
+ gUnknown_08294313,
+ gUnknown_08294359,
+ gUnknown_08294398,
+ gUnknown_082943DA,
+ gUnknown_0829441C,
+ gUnknown_08294460,
+ gUnknown_082944A0,
+ gUnknown_082944D5
+};
+
+static void SetupBard(void)
+{
+ u16 i;
+ struct MauvilleManBard *bard = &gSaveBlock1Ptr->oldMan.bard;
+
+ bard->id = MAUVILLE_MAN_BARD;
+ bard->hasChangedSong = FALSE;
+ bard->language = gGameLanguage;
+ for (i = 0; i < 6; i++)
+ bard->songLyrics[i] = sDefaultBardSongLyrics[i];
+}
+
+static void SetupHipster(void)
+{
+ struct MauvilleManHipster *hipster = &gSaveBlock1Ptr->oldMan.hipster;
+
+ hipster->id = MAUVILLE_MAN_HIPSTER;
+ hipster->alreadySpoken = FALSE;
+ hipster->language = gGameLanguage;
+}
+
+static void SetupStoryteller(void)
+{
+ StorytellerSetup();
+}
+
+static void SetupGiddy(void)
+{
+ struct MauvilleManGiddy *giddy = &gSaveBlock1Ptr->oldMan.giddy;
+
+ giddy->id = MAUVILLE_MAN_GIDDY;
+ giddy->taleCounter = 0;
+ giddy->language = gGameLanguage;
+}
+
+static void SetupTrader(void)
+{
+ TraderSetup();
+}
+
+void SetMauvilleOldMan(void)
+{
+ u16 trainerId = (gSaveBlock2Ptr->playerTrainerId[1] << 8) | gSaveBlock2Ptr->playerTrainerId[0];
+
+
+ // Determine man based on the last digit of the player's trainer ID.
+ switch ((trainerId % 10) / 2)
+ {
+ case MAUVILLE_MAN_BARD:
+ SetupBard();
+ break;
+ case MAUVILLE_MAN_HIPSTER:
+ SetupHipster();
+ break;
+ case MAUVILLE_MAN_TRADER:
+ SetupTrader();
+ break;
+ case MAUVILLE_MAN_STORYTELLER:
+ SetupStoryteller();
+ break;
+ case MAUVILLE_MAN_GIDDY:
+ SetupGiddy();
+ break;
+ }
+ ScrSpecial_SetMauvilleOldManMapObjGfx();
+}
+
+u8 GetCurrentMauvilleOldMan(void)
+{
+ struct MauvilleManCommon *common = &gSaveBlock1Ptr->oldMan.common;
+
+ return common->id;
+}
+
+void ScrSpecial_GetCurrentMauvilleMan(void)
+{
+ gSpecialVar_Result = GetCurrentMauvilleOldMan();
+}
+
+void ScrSpecial_HasBardSongBeenChanged(void)
+{
+ u16 *scriptResult = &gSpecialVar_Result; // why??
+ struct MauvilleManBard *bard = &gSaveBlock1Ptr->oldMan.bard;
+
+ *scriptResult = bard->hasChangedSong;
+}
+
+void ScrSpecial_SaveBardSongLyrics(void)
+{
+ u16 i;
+ struct MauvilleManBard *bard = &gSaveBlock1Ptr->oldMan.bard;
+
+ StringCopy(bard->playerName, gSaveBlock2Ptr->playerName);
+
+ for (i = 0; i < 4; i++)
+ bard->playerTrainerId[i] = gSaveBlock2Ptr->playerTrainerId[i];
+
+ for (i = 0; i < 6; i++)
+ bard->songLyrics[i] = bard->temporaryLyrics[i];
+
+ bard->hasChangedSong = TRUE;
+}
+
+// Copies lyrics into gStringVar4
+static void PrepareSongText(void)
+{
+ struct MauvilleManBard *bard = &gSaveBlock1Ptr->oldMan.bard;
+ u16 * lyrics = gSpecialVar_0x8004 == 0 ? bard->songLyrics : bard->temporaryLyrics;
+ u8 * wordEnd = gStringVar4;
+ u8 * str = wordEnd;
+ u16 lineNum;
+
+ // Put three words on each line
+ for (lineNum = 0; lineNum < 2; lineNum++)
+ {
+ wordEnd = CopyEasyChatWord(wordEnd, *(lyrics++));
+ while (wordEnd != str)
+ {
+ if (*str == CHAR_SPACE)
+ *str = CHAR_SONG_WORD_SEPARATOR;
+ str++;
+ }
+
+ str++;
+ *(wordEnd++) = CHAR_SPACE;
+
+ wordEnd = CopyEasyChatWord(wordEnd, *(lyrics++));
+ while (wordEnd != str)
+ {
+ if (*str == CHAR_SPACE)
+ *str = CHAR_SONG_WORD_SEPARATOR;
+ str++;
+ }
+
+ str++;
+ *(wordEnd++) = CHAR_NEWLINE;
+
+ wordEnd = CopyEasyChatWord(wordEnd, *(lyrics++));
+ while (wordEnd != str)
+ {
+ if (*str == CHAR_SPACE)
+ *str = CHAR_SONG_WORD_SEPARATOR;
+ str++;
+ }
+
+ if (lineNum == 0)
+ {
+ *(wordEnd++) = EXT_CTRL_CODE_BEGIN;
+ *(wordEnd++) = 15;
+ }
+ }
+}
+
+void ScrSpecial_PlayBardSong(void)
+{
+ StartBardSong(gSpecialVar_0x8004);
+ ScriptContext1_Stop();
+}
+
+void ScrSpecial_GetHipsterSpokenFlag(void)
+{
+ u16 *scriptResult = &gSpecialVar_Result; // again??
+ struct MauvilleManHipster *hipster = &gSaveBlock1Ptr->oldMan.hipster;
+
+ *scriptResult = hipster->alreadySpoken;
+}
+
+void ScrSpecial_SetHipsterSpokenFlag(void)
+{
+ struct MauvilleManHipster *hipster = &gSaveBlock1Ptr->oldMan.hipster;
+
+ hipster->alreadySpoken = TRUE;
+}
+
+void ScrSpecial_HipsterTeachWord(void)
+{
+ u16 var = sub_811F01C();
+
+ if (var == 0xFFFF)
+ {
+ gSpecialVar_Result = FALSE;
+ }
+ else
+ {
+ CopyEasyChatWord(gStringVar1, var);
+ gSpecialVar_Result = TRUE;
+ }
+}
+
+void ScrSpecial_GiddyShouldTellAnotherTale(void)
+{
+ struct MauvilleManGiddy *giddy = &gSaveBlock1Ptr->oldMan.giddy;
+
+ if (giddy->taleCounter == 10)
+ {
+ gSpecialVar_Result = FALSE;
+ giddy->taleCounter = 0;
+ }
+ else
+ {
+ gSpecialVar_Result = TRUE;
+ }
+}
+
+void ScrSpecial_GenerateGiddyLine(void)
+{
+ struct MauvilleManGiddy *giddy = &gSaveBlock1Ptr->oldMan.giddy;
+
+ if (giddy->taleCounter == 0)
+ InitGiddyTaleList();
+
+ if (giddy->randomWords[giddy->taleCounter] != 0xFFFF) // is not the last element of the array?
+ {
+ u8 *stringPtr;
+ u32 adjective = Random();
+
+ adjective %= 8;
+ stringPtr = CopyEasyChatWord(gStringVar4, giddy->randomWords[giddy->taleCounter]);
+ stringPtr = StringCopy(stringPtr, gOtherText_Is);
+ stringPtr = StringCopy(stringPtr, sGiddyAdjectives[adjective]);
+ StringCopy(stringPtr, gOtherText_DontYouAgree);
+ }
+ else
+ {
+ StringCopy(gStringVar4, sGiddyQuestions[giddy->questionList[giddy->questionNum++]]);
+ }
+
+ if (!(Random() % 10))
+ giddy->taleCounter = 10;
+ else
+ giddy->taleCounter++;
+
+ gSpecialVar_Result = TRUE;
+}
+
+static void InitGiddyTaleList(void)
+{
+ struct MauvilleManGiddy *giddy = &gSaveBlock1Ptr->oldMan.giddy;
+ u16 arr[][2] = {
+ {EC_GROUP_POKEMON, 0},
+ {EC_GROUP_LIFESTYLE, 0},
+ {EC_GROUP_HOBBIES, 0},
+ {EC_GROUP_MOVE_1, 0},
+ {EC_GROUP_MOVE_2, 0},
+ {EC_GROUP_POKEMON_2, 0}
+ };
+ u16 i;
+ u16 r10;
+ u16 r7;
+ u16 r1;
+
+ for (i = 0; i < 8; i++)
+ giddy->questionList[i] = i;
+
+ for (i = 0; i < 8; i++)
+ {
+ r1 = Random() % (i + 1);
+ r7 = giddy->questionList[i];
+ giddy->questionList[i] = giddy->questionList[r1];
+ giddy->questionList[r1] = r7;
+ }
+
+ r10 = 0;
+ for (i = 0; i < 6; i++)
+ {
+ arr[i][1] = EasyChat_GetNumWordsInGroup(arr[i][0]);
+ r10 += arr[i][1];
+ }
+
+ giddy->questionNum = 0;
+ r7 = 0;
+ for (i = 0; i < 10; i++)
+ {
+ r1 = Random() % 10;
+ if (r1 < 3 && r7 < 8)
+ {
+ giddy->randomWords[i] = 0xFFFF;
+ r7++;
+ }
+ else
+ {
+ s16 r2 = Random() % r10;
+ for (r1 = 0; i < 6; r1++)
+ if ((r2 -= arr[r1][1]) <= 0)
+ break;
+ if (r1 == 6)
+ r1 = 0;
+ giddy->randomWords[i] = sub_811EE90(arr[r1][0]);
+ }
+ }
+}
+static void ResetBardFlag(void)
+{
+ struct MauvilleManBard *bard = &gSaveBlock1Ptr->oldMan.bard;
+
+ bard->hasChangedSong = FALSE;
+}
+
+static void ResetHipsterFlag(void)
+{
+ struct MauvilleManHipster *hipster = &gSaveBlock1Ptr->oldMan.hipster;
+
+ hipster->alreadySpoken = FALSE;
+}
+
+static void ResetTraderFlag(void)
+{
+ Trader_ResetFlag();
+}
+
+static void ResetStorytellerFlag(void)
+{
+ Storyteller_ResetFlag();
+}
+
+void ResetMauvilleOldManFlag(void)
+{
+ switch (GetCurrentMauvilleOldMan())
+ {
+ case MAUVILLE_MAN_BARD:
+ ResetBardFlag();
+ break;
+ case MAUVILLE_MAN_HIPSTER:
+ ResetHipsterFlag();
+ break;
+ case MAUVILLE_MAN_STORYTELLER:
+ ResetStorytellerFlag();
+ break;
+ case MAUVILLE_MAN_TRADER:
+ ResetTraderFlag();
+ break;
+ case MAUVILLE_MAN_GIDDY:
+ break;
+ }
+ ScrSpecial_SetMauvilleOldManMapObjGfx();
+}
+
+
+#define tState data[0]
+#define tCharIndex data[3]
+#define tCurrWord data[4]
+#define tUseTemporaryLyrics data[5]
+
+#define MACRO1(a) (((a) & 3) + (((a) / 8) & 1))
+#define MACRO2(a) (((a) % 4) + (((a) / 8) & 1))
+
+static void StartBardSong(bool8 useTemporaryLyrics)
+{
+ u8 taskId = CreateTask(Task_BardSong, 80);
+
+ gTasks[taskId].tUseTemporaryLyrics = useTemporaryLyrics;
+}
+
+static void sub_81206F0(void)
+{
+ gUnknown_03002F84 = FALSE;
+}
+
+static void BardSong_TextSubPrinter(struct TextSubPrinter * printer, u16 a1)
+{
+ gUnknown_03002F84 = TRUE;
+}
+
+static void sub_8120708(const u8 * src)
+{
+ NewMenuHelpers_DrawDialogueFrame(0, 0);
+ PrintTextOnWindow(0, 1, src, 0, 1, 1, BardSong_TextSubPrinter);
+ gUnknown_03002F84 = TRUE;
+ CopyWindowToVram(0, 3);
+}
+
+static void BardSing(struct Task *task, struct BardSong *song)
+{
+ switch (task->tState)
+ {
+ case 0: // Initialize song
+ {
+ struct MauvilleManBard *bard = &gSaveBlock1Ptr->oldMan.bard;
+ u16 *lyrics;
+ s32 i;
+
+ // Copy lyrics
+ if (gSpecialVar_0x8004 == 0)
+ lyrics = bard->songLyrics;
+ else
+ lyrics = bard->temporaryLyrics;
+ for (i = 0; i < 6; i++)
+ song->lyrics[i] = lyrics[i];
+ song->currWord = 0;
+ }
+ break;
+ case 1: // Wait for BGM to end
+ break;
+ case 2: // Initialize word
+ {
+ u16 word = song->lyrics[song->currWord];
+ song->sound = GetWordSounds(word);
+ GetWordPhonemes(song, MACRO1(word));
+ song->currWord++;
+ if (song->sound->var00 != 0xFF)
+ song->state = 0;
+ else
+ {
+ song->state = 3;
+ song->phonemeTimer = 2;
+ }
+ break;
+ }
+ case 3:
+ case 4:
+ {
+ const struct BardSound *sound = &song->sound[song->currPhoneme];
+
+ switch (song->state)
+ {
+ case 0:
+ song->phonemeTimer = song->phonemes[song->currPhoneme].length;
+ if (sound->var00 <= 50)
+ {
+ u8 num = sound->var00 / 3;
+ m4aSongNumStart(PH_TRAP_HELD + 3 * num);
+ }
+ song->state = 2;
+ song->phonemeTimer--;
+ break;
+ case 2:
+ song->state = 1;
+ if (sound->var00 <= 50)
+ {
+ song->volume = 0x100 + sound->volume * 16;
+ m4aMPlayVolumeControl(&gMPlayInfo_SE2, 0xFFFF, song->volume);
+ song->pitch = 0x200 + song->phonemes[song->currPhoneme].pitch;
+ m4aMPlayPitchControl(&gMPlayInfo_SE2, 0xFFFF, song->pitch);
+ }
+ break;
+ case 1:
+ if (song->voiceInflection > 10)
+ song->volume -= 2;
+ if (song->voiceInflection & 1)
+ song->pitch += 64;
+ else
+ song->pitch -= 64;
+ m4aMPlayVolumeControl(&gMPlayInfo_SE2, 0xFFFF, song->volume);
+ m4aMPlayPitchControl(&gMPlayInfo_SE2, 0xFFFF, song->pitch);
+ song->voiceInflection++;
+ song->phonemeTimer--;
+ if (song->phonemeTimer == 0)
+ {
+ song->currPhoneme++;
+ if (song->currPhoneme != 6 && song->sound[song->currPhoneme].var00 != 0xFF)
+ song->state = 0;
+ else
+ {
+ song->state = 3;
+ song->phonemeTimer = 2;
+ }
+ }
+ break;
+ case 3:
+ song->phonemeTimer--;
+ if (song->phonemeTimer == 0)
+ {
+ m4aMPlayStop(&gMPlayInfo_SE2);
+ song->state = 4;
+ }
+ break;
+ }
+ }
+ break;
+ case 5:
+ break;
+ }
+}
+
+static void Task_BardSong(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId]; // r5
+
+ BardSing(task, &gBardSong);
+ switch (task->tState)
+ {
+ case 0: // Initialize song
+ PrepareSongText();
+ sub_8120708(gStringVar4);
+ task->data[1] = 0;
+ task->data[2] = 0;
+ task->tCharIndex = 0;
+ task->tCurrWord = 0;
+ FadeOutBGMTemporarily(4);
+ task->tState = 1;
+ break;
+ case 1: // Wait for BGM to end
+ if (IsBGMPausedOrStopped())
+ task->tState = 2;
+ break;
+ case 2: // Initialize word
+ {
+ struct MauvilleManBard *bard = &gSaveBlock1Ptr->oldMan.bard;
+ u8 *str = gStringVar4 + task->tCharIndex;
+ u16 wordLen = 0;
+ // Can't get it to match without hacking
+ u32 temp;
+ register s16 zero asm("r1");
+
+ while (*str != CHAR_SPACE
+ && *str != CHAR_NEWLINE
+ && *str != EXT_CTRL_CODE_BEGIN
+ && *str != EOS)
+ {
+ str++;
+ wordLen++;
+ }
+ if (!task->tUseTemporaryLyrics)
+ sUnknownBardRelated = MACRO2(bard->songLyrics[task->tCurrWord]);
+ else
+ sUnknownBardRelated = MACRO2(bard->temporaryLyrics[task->tCurrWord]);
+ temp = gBardSong.length / wordLen;
+ zero = 0;
+ gBardSong.length = temp;
+ if (gBardSong.length <= 0)
+ gBardSong.length = 1;
+ task->tCurrWord++;
+ if (task->data[2] == 0)
+ task->tState = 3;
+ else
+ task->tState = 5;
+ task->data[1] = zero;
+ }
+ break;
+ case 5:
+ if (task->data[2] == 0)
+ task->tState = 3;
+ else
+ task->data[2]--;
+ break;
+ case 3:
+ if (gStringVar4[task->tCharIndex] == EOS)
+ {
+ FadeInBGM(6);
+ m4aMPlayFadeOutTemporarily(&gMPlayInfo_SE2, 2);
+ EnableBothScriptContexts();
+ DestroyTask(taskId);
+ }
+ else if (gStringVar4[task->tCharIndex] == CHAR_SPACE)
+ {
+
+ sub_81206F0();
+ task->tCharIndex++;
+ task->tState = 2;
+ task->data[2] = 0;
+ }
+ else if (gStringVar4[task->tCharIndex] == CHAR_NEWLINE)
+ {
+ task->tCharIndex++;
+ task->tState = 2;
+ task->data[2] = 0;
+ }
+ else if (gStringVar4[task->tCharIndex] == EXT_CTRL_CODE_BEGIN)
+ {
+ task->tCharIndex += 2; // skip over control codes
+ task->tState = 2;
+ task->data[2] = 8;
+ }
+ else if (gStringVar4[task->tCharIndex] == CHAR_SONG_WORD_SEPARATOR)
+ {
+ gStringVar4[task->tCharIndex] = CHAR_SPACE; // restore it back to a space
+ sub_81206F0();
+ task->tCharIndex++;
+ task->data[2] = 0;
+ }
+ else
+ {
+ switch (task->data[1])
+ {
+ case 0:
+ sub_81206F0();
+ task->data[1]++;
+ break;
+ case 1:
+ task->data[1]++;
+ break;
+ case 2:
+ task->tCharIndex++;
+ task->data[1] = 0;
+ task->data[2] = gBardSong.length;
+ task->tState = 4;
+ break;
+ }
+ }
+ break;
+ case 4:
+ task->data[2]--;
+ if (task->data[2] == 0)
+ task->tState = 3;
+ break;
+ }
+ sub_8197224();
+}
+
+void ScrSpecial_SetMauvilleOldManMapObjGfx(void)
+{
+ VarSet(VAR_0x4010, MAP_OBJ_GFX_BARD);
+}
+
+// Language fixers?
+
+void sub_8120B70(union OldMan * oldMan)
+{
+ s32 i;
+ u8 sp00[8];
+
+ switch (oldMan->common.id)
+ {
+ case MAUVILLE_MAN_TRADER:
+ {
+ struct MauvilleOldManTrader * trader = &oldMan->trader;
+ for (i = 0; i < 4; i++)
+ {
+ if (trader->language[i] == LANGUAGE_JAPANESE)
+ {
+ ConvertInternationalString(trader->playerNames[i], LANGUAGE_JAPANESE);
+ }
+ }
+ }
+ break;
+ case MAUVILLE_MAN_STORYTELLER:
+ {
+ struct MauvilleManStoryteller * storyteller = &oldMan->storyteller;
+ for (i = 0; i < 4; i++)
+ {
+ if (storyteller->gameStatIDs[i] != 0)
+ {
+ memcpy(sp00, storyteller->trainerNames[i], 7);
+ sp00[7] = EOS;
+ if (IsStringJapanese(sp00))
+ {
+ memset(sp00, CHAR_SPACE, 8);
+ StringCopy(sp00, gText_Friend);
+ memcpy(storyteller->trainerNames[i], sp00, 7);
+ storyteller->language[i] = GAME_LANGUAGE;
+ }
+ }
+ }
+ }
+ break;
+ }
+}
+
+void sub_8120C0C(union OldMan * oldMan, u32 r8, u32 r7, u32 r3)
+{
+ s32 i;
+
+ switch (oldMan->common.id)
+ {
+ case MAUVILLE_MAN_TRADER:
+ {
+ struct MauvilleOldManTrader * trader = &oldMan->trader;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (IsStringJapanese(trader->playerNames[i]))
+ {
+ trader->language[i] = r8;
+ }
+ else
+ {
+ trader->language[i] = r7;
+ }
+ }
+ }
+ break;
+ case MAUVILLE_MAN_STORYTELLER:
+ {
+ struct MauvilleManStoryteller * storyteller = &oldMan->storyteller;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (IsStringJapanese(storyteller->trainerNames[i]))
+ {
+ storyteller->language[i] = r8;
+ }
+ else
+ {
+ storyteller->language[i] = r7;
+ }
+ }
+ }
+ break;
+ case MAUVILLE_MAN_BARD:
+ {
+ struct MauvilleManBard * bard = &oldMan->bard;
+
+ if (r3 == LANGUAGE_JAPANESE)
+ bard->language = r8;
+ else
+ bard->language = r7;
+ }
+ break;
+ case MAUVILLE_MAN_HIPSTER:
+ {
+ struct MauvilleManHipster * hipster = &oldMan->hipster;
+
+ if (r3 == LANGUAGE_JAPANESE)
+ hipster->language = r8;
+ else
+ hipster->language = r7;
+ }
+ break;
+ case MAUVILLE_MAN_GIDDY:
+ {
+ struct MauvilleManGiddy * giddy = &oldMan->giddy;
+
+ if (r3 == LANGUAGE_JAPANESE)
+ giddy->language = r8;
+ else
+ giddy->language = r7;
+ }
+ break;
+ }
+}
+
+void sub_8120CD0(union OldMan * oldMan, u32 unused, u32 a2)
+{
+ u8 sp00[8];
+ s32 i;
+ if (oldMan->common.id == MAUVILLE_MAN_STORYTELLER && a2 == LANGUAGE_JAPANESE)
+ {
+ struct MauvilleManStoryteller * storyteller = &oldMan->storyteller;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (storyteller->gameStatIDs[i] != 0)
+ {
+ memcpy(sp00, storyteller->trainerNames[i], 7);
+ sp00[7] = EOS;
+ if (IsStringJapanese(sp00))
+ storyteller->language[i] = LANGUAGE_JAPANESE;
+ else
+ storyteller->language[i] = GAME_LANGUAGE;
+ }
+ }
+ }
+}
+
+void sub_8120D34(union OldMan * oldMan, u32 r1, u32 r6)
+{
+ u32 r2 = (r1 == LANGUAGE_JAPANESE || r1 == LANGUAGE_ENGLISH) ? 1 : 0;
+ switch (oldMan->common.id)
+ {
+ case MAUVILLE_MAN_TRADER:
+ {
+ struct MauvilleOldManTrader * trader = &oldMan->trader;
+ s32 i;
+
+ if (r2)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ u8 * str = trader->playerNames[i];
+ if (str[0] == EXT_CTRL_CODE_BEGIN && str[1] == EXT_CTRL_CODE_JPN)
+ {
+ StripExtCtrlCodes(str);
+ trader->language[i] = LANGUAGE_JAPANESE;
+ }
+ else
+ trader->language[i] = r6;
+ }
+ }
+ else
+ {
+ for (i = 0; i < 4; i++)
+ {
+ if (trader->language[i] == LANGUAGE_JAPANESE)
+ {
+ StripExtCtrlCodes(trader->playerNames[i]);
+ }
+ }
+ }
+ }
+ break;
+ case MAUVILLE_MAN_STORYTELLER:
+ {
+
+ struct MauvilleManStoryteller * storyteller = &oldMan->storyteller;
+ s32 i;
+
+ if (r2)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ if (storyteller->gameStatIDs[i] != 0)
+ storyteller->language[i] = r6;
+ }
+ }
+ }
+ break;
+ case MAUVILLE_MAN_BARD:
+ {
+ struct MauvilleManBard * bard = &oldMan->bard;
+
+ if (r2)
+ {
+ bard->language = r6;
+ }
+ }
+ break;
+ case MAUVILLE_MAN_HIPSTER:
+ {
+ struct MauvilleManHipster * hipster = &oldMan->hipster;
+
+ if (r2)
+ {
+ hipster->language = r6;
+ }
+ }
+ break;
+ case MAUVILLE_MAN_GIDDY:
+ {
+ struct MauvilleManGiddy * giddy = &oldMan->giddy;
+
+ if (r2)
+ {
+ giddy->language = r6;
+ }
+ }
+ break;
+ }
+}
+
+struct Story
+{
+ u8 stat;
+ u8 minVal;
+ const u8 *title;
+ const u8 *action;
+ const u8 *fullText;
+};
+
+static const struct Story sStorytellerStories[] = {
+ {GAME_STAT_50, 1, MauvilleCity_PokemonCenter_1F_Text_28E930, MauvilleCity_PokemonCenter_1F_Text_28E947, MauvilleCity_PokemonCenter_1F_Text_28E956},
+ {GAME_STAT_STARTED_TRENDS, 1, MauvilleCity_PokemonCenter_1F_Text_28E9D7, MauvilleCity_PokemonCenter_1F_Text_28E9EF, MauvilleCity_PokemonCenter_1F_Text_28E9FE},
+ {GAME_STAT_PLANTED_BERRIES, 1, MauvilleCity_PokemonCenter_1F_Text_28EA7D, MauvilleCity_PokemonCenter_1F_Text_28EA98, MauvilleCity_PokemonCenter_1F_Text_28EAA8},
+ {GAME_STAT_TRADED_BIKES, 1, MauvilleCity_PokemonCenter_1F_Text_28EB19, MauvilleCity_PokemonCenter_1F_Text_28EB31, MauvilleCity_PokemonCenter_1F_Text_28EB3E},
+ {GAME_STAT_GOT_INTERVIEWED, 1, MauvilleCity_PokemonCenter_1F_Text_28EBB5, MauvilleCity_PokemonCenter_1F_Text_28EBCD, MauvilleCity_PokemonCenter_1F_Text_28EBDD},
+ {GAME_STAT_TRAINER_BATTLES, 1, MauvilleCity_PokemonCenter_1F_Text_28EC60, MauvilleCity_PokemonCenter_1F_Text_28EC79, MauvilleCity_PokemonCenter_1F_Text_28EC81},
+ {GAME_STAT_POKEMON_CAPTURES, 1, MauvilleCity_PokemonCenter_1F_Text_28ED04, MauvilleCity_PokemonCenter_1F_Text_28ED21, MauvilleCity_PokemonCenter_1F_Text_28ED30},
+ {GAME_STAT_FISHING_CAPTURES, 1, MauvilleCity_PokemonCenter_1F_Text_28EDA1, MauvilleCity_PokemonCenter_1F_Text_28EDB5, MauvilleCity_PokemonCenter_1F_Text_28EDCF},
+ {GAME_STAT_HATCHED_EGGS, 1, MauvilleCity_PokemonCenter_1F_Text_28EE45, MauvilleCity_PokemonCenter_1F_Text_28EE5D, MauvilleCity_PokemonCenter_1F_Text_28EE6A},
+ {GAME_STAT_EVOLVED_POKEMON, 1, MauvilleCity_PokemonCenter_1F_Text_28EEDD, MauvilleCity_PokemonCenter_1F_Text_28EEF1, MauvilleCity_PokemonCenter_1F_Text_28EF01},
+ {GAME_STAT_USED_POKECENTER, 1, MauvilleCity_PokemonCenter_1F_Text_28EF73, MauvilleCity_PokemonCenter_1F_Text_28EF95, MauvilleCity_PokemonCenter_1F_Text_28EFAA},
+ {GAME_STAT_RESTED_AT_HOME, 1, MauvilleCity_PokemonCenter_1F_Text_28F045, MauvilleCity_PokemonCenter_1F_Text_28F05A, MauvilleCity_PokemonCenter_1F_Text_28F071},
+ {GAME_STAT_ENTERED_SAFARI_ZONE, 1, MauvilleCity_PokemonCenter_1F_Text_28F0F3, MauvilleCity_PokemonCenter_1F_Text_28F10D, MauvilleCity_PokemonCenter_1F_Text_28F125},
+ {GAME_STAT_USED_CUT, 1, MauvilleCity_PokemonCenter_1F_Text_28F1BE, MauvilleCity_PokemonCenter_1F_Text_28F1D5, MauvilleCity_PokemonCenter_1F_Text_28F1DE},
+ {GAME_STAT_USED_ROCK_SMASH, 1, MauvilleCity_PokemonCenter_1F_Text_28F24F, MauvilleCity_PokemonCenter_1F_Text_28F269, MauvilleCity_PokemonCenter_1F_Text_28F277},
+ {GAME_STAT_MOVED_SECRET_BASE, 1, MauvilleCity_PokemonCenter_1F_Text_28F2FC, MauvilleCity_PokemonCenter_1F_Text_28F314, MauvilleCity_PokemonCenter_1F_Text_28F32A},
+ {GAME_STAT_USED_SPLASH, 1, MauvilleCity_PokemonCenter_1F_Text_28F3AD, MauvilleCity_PokemonCenter_1F_Text_28F3C6, MauvilleCity_PokemonCenter_1F_Text_28F3D2},
+ {GAME_STAT_USED_STRUGGLE, 1, MauvilleCity_PokemonCenter_1F_Text_28F44B, MauvilleCity_PokemonCenter_1F_Text_28F461, MauvilleCity_PokemonCenter_1F_Text_28F47C},
+ {GAME_STAT_SLOT_JACKPOTS, 1, MauvilleCity_PokemonCenter_1F_Text_28F50C, MauvilleCity_PokemonCenter_1F_Text_28F51B, MauvilleCity_PokemonCenter_1F_Text_28F538},
+ {GAME_STAT_CONSECUTIVE_ROULETTE_WINS, 2, MauvilleCity_PokemonCenter_1F_Text_28F5BE, MauvilleCity_PokemonCenter_1F_Text_28F5D1, MauvilleCity_PokemonCenter_1F_Text_28F5F2},
+ {GAME_STAT_ENTERED_BATTLE_TOWER, 1, MauvilleCity_PokemonCenter_1F_Text_28F678, MauvilleCity_PokemonCenter_1F_Text_28F694, MauvilleCity_PokemonCenter_1F_Text_28F6B4},
+ {GAME_STAT_POKEBLOCKS, 1, MauvilleCity_PokemonCenter_1F_Text_28F751, MauvilleCity_PokemonCenter_1F_Text_28F76A, MauvilleCity_PokemonCenter_1F_Text_28F776},
+ {GAME_STAT_ENTERED_CONTEST, 1, MauvilleCity_PokemonCenter_1F_Text_28F7F6, MauvilleCity_PokemonCenter_1F_Text_28F811, MauvilleCity_PokemonCenter_1F_Text_28F822},
+ {GAME_STAT_WON_CONTEST, 1, MauvilleCity_PokemonCenter_1F_Text_28F89C, MauvilleCity_PokemonCenter_1F_Text_28F8AF, MauvilleCity_PokemonCenter_1F_Text_28F8BC},
+ {GAME_STAT_SHOPPED, 1, MauvilleCity_PokemonCenter_1F_Text_28F92F, MauvilleCity_PokemonCenter_1F_Text_28F941, MauvilleCity_PokemonCenter_1F_Text_28F949},
+ {GAME_STAT_USED_ITEMFINDER, 1, MauvilleCity_PokemonCenter_1F_Text_28F9D1, MauvilleCity_PokemonCenter_1F_Text_28F9EA, MauvilleCity_PokemonCenter_1F_Text_28F9FD},
+ {GAME_STAT_GOT_RAINED_ON, 1, MauvilleCity_PokemonCenter_1F_Text_28FA81, MauvilleCity_PokemonCenter_1F_Text_28FA99, MauvilleCity_PokemonCenter_1F_Text_28FAA7},
+ {GAME_STAT_CHECKED_POKEDEX, 1, MauvilleCity_PokemonCenter_1F_Text_28FB1D, MauvilleCity_PokemonCenter_1F_Text_28FB35, MauvilleCity_PokemonCenter_1F_Text_28FB47},
+ {GAME_STAT_RECEIVED_RIBBONS, 1, MauvilleCity_PokemonCenter_1F_Text_28FBC4, MauvilleCity_PokemonCenter_1F_Text_28FBD9, MauvilleCity_PokemonCenter_1F_Text_28FBEA},
+ {GAME_STAT_JUMPED_DOWN_LEDGES, 1, MauvilleCity_PokemonCenter_1F_Text_28FC6B, MauvilleCity_PokemonCenter_1F_Text_28FC85, MauvilleCity_PokemonCenter_1F_Text_28FC98},
+ {GAME_STAT_WATCHED_TV, 1, MauvilleCity_PokemonCenter_1F_Text_28FD1D, MauvilleCity_PokemonCenter_1F_Text_28FD35, MauvilleCity_PokemonCenter_1F_Text_28FD40},
+ {GAME_STAT_CHECKED_CLOCK, 1, MauvilleCity_PokemonCenter_1F_Text_28FDA2, MauvilleCity_PokemonCenter_1F_Text_28FDBD, MauvilleCity_PokemonCenter_1F_Text_28FDCE},
+ {GAME_STAT_WON_POKEMON_LOTTERY, 1, MauvilleCity_PokemonCenter_1F_Text_28FE57, MauvilleCity_PokemonCenter_1F_Text_28FE72, MauvilleCity_PokemonCenter_1F_Text_28FE88},
+ {GAME_STAT_USED_DAYCARE, 1, MauvilleCity_PokemonCenter_1F_Text_28FF0C, MauvilleCity_PokemonCenter_1F_Text_28FF27, MauvilleCity_PokemonCenter_1F_Text_28FF44},
+ {GAME_STAT_RODE_CABLE_CAR, 1, MauvilleCity_PokemonCenter_1F_Text_28FFDD, MauvilleCity_PokemonCenter_1F_Text_28FFFA, MauvilleCity_PokemonCenter_1F_Text_29000D},
+ {GAME_STAT_ENTERED_HOT_SPRINGS, 1, MauvilleCity_PokemonCenter_1F_Text_290097, MauvilleCity_PokemonCenter_1F_Text_2900B5, MauvilleCity_PokemonCenter_1F_Text_2900CB}
+};
+
+static void StorytellerSetup(void)
+{
+ s32 i;
+ sStorytellerPtr = &gSaveBlock1Ptr->oldMan.storyteller;
+
+ sStorytellerPtr->id = MAUVILLE_MAN_STORYTELLER;
+ sStorytellerPtr->alreadyRecorded = FALSE;
+ for (i = 0; i < 4; i++)
+ {
+ sStorytellerPtr->gameStatIDs[i] = 0;
+ sStorytellerPtr->trainerNames[0][i] = EOS; // Maybe they meant storyteller->trainerNames[i][0] instead?
+ }
+}
+
+static void Storyteller_ResetFlag(void)
+{
+ sStorytellerPtr = &gSaveBlock1Ptr->oldMan.storyteller;
+
+ sStorytellerPtr->id = MAUVILLE_MAN_STORYTELLER;
+ sStorytellerPtr->alreadyRecorded = FALSE;
+}
+
+static u32 StorytellerGetGameStat(u8 stat)
+{
+ if (stat == 50)
+ stat = 0;
+ return GetGameStat(stat);
+}
+
+static const struct Story *GetStoryByStat(u32 stat)
+{
+ s32 i;
+
+ for (i = 0; i < 36; i++)
+ {
+ if (sStorytellerStories[i].stat == stat)
+ return &sStorytellerStories[i];
+ }
+ return &sStorytellerStories[35];
+}
+
+static const u8 *GetStoryTitleByStat(u32 stat)
+{
+ return GetStoryByStat(stat)->title;
+}
+
+static const u8 *GetStoryTextByStat(u32 stat)
+{
+ return GetStoryByStat(stat)->fullText;
+}
+
+static const u8 *GetStoryActionByStat(u32 stat)
+{
+ return GetStoryByStat(stat)->action;
+}
+
+static u8 GetFreeStorySlot(void)
+{
+ u8 i;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (sStorytellerPtr->gameStatIDs[i] == 0)
+ break;
+ }
+ return i;
+}
+
+static u32 StorytellerGetRecordedTrainerStat(u32 trainer)
+{
+ u8 *ptr = sStorytellerPtr->statValues[trainer];
+
+ return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24);
+}
+
+static void StorytellerSetRecordedTrainerStat(u32 trainer, u32 val)
+{
+ u8 *ptr = sStorytellerPtr->statValues[trainer];
+
+ ptr[0] = val;
+ ptr[1] = val >> 8;
+ ptr[2] = val >> 16;
+ ptr[3] = val >> 24;
+}
+
+static bool32 HasTrainerStatIncreased(u32 trainer)
+{
+ if (StorytellerGetGameStat(sStorytellerPtr->gameStatIDs[trainer]) > StorytellerGetRecordedTrainerStat(trainer))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static void GetStoryByStattellerPlayerName(u32 player, void *dst)
+{
+ u8 *name = sStorytellerPtr->trainerNames[player];
+
+ memset(dst, EOS, 8);
+ memcpy(dst, name, 7);
+}
+
+static void StorytellerSetPlayerName(u32 player, const u8 * src)
+{
+ u8 * name = sStorytellerPtr->trainerNames[player];
+ memset(name, EOS, 7);
+ memcpy(name, src, 7);
+}
+
+
+static void StorytellerRecordNewStat(u32 player, u32 stat)
+{
+ sStorytellerPtr->gameStatIDs[player] = stat;
+ StorytellerSetPlayerName(player, gSaveBlock2Ptr->playerName);
+ StorytellerSetRecordedTrainerStat(player, StorytellerGetGameStat(stat));
+ ConvertIntToDecimalStringN(gStringVar1, StorytellerGetGameStat(stat), STR_CONV_MODE_LEFT_ALIGN, 10);
+ StringCopy(gStringVar2, GetStoryActionByStat(stat));
+ sStorytellerPtr->language[player] = gGameLanguage;
+}
+
+static void ScrambleStatList(u8 * arr, s32 count)
+{
+ s32 i;
+
+ for (i = 0; i < count; i++)
+ arr[i] = i;
+ for (i = 0; i < count; i++)
+ {
+ u32 a = Random() % count;
+ u32 b = Random() % count;
+ u8 temp = arr[a];
+ arr[a] = arr[b];
+ arr[b] = temp;
+ }
+}
+
+struct UnknownStruct_0859F288
+{
+ s32 length;
+ u32 unused2;
+};
+
+static const struct UnknownStruct_0859F288 sStorytellerStuff = {
+ ARRAY_COUNT(sStorytellerStories),
+ sizeof(sStorytellerStuff)
+};
+
+static bool8 StorytellerInitializeRandomStat(void)
+{
+ u8 arr[sStorytellerStuff.length];
+ s32 i;
+ s32 j;
+
+ ScrambleStatList(arr, ARRAY_COUNT(sStorytellerStories));
+ for (i = 0; i < (s32)ARRAY_COUNT(sStorytellerStories); i++)
+ {
+ u8 stat = sStorytellerStories[arr[i]].stat;
+ u8 minVal = sStorytellerStories[arr[i]].minVal;
+
+ for (j = 0; j < 4; j++)
+ {
+ if (sStorytellerPtr->gameStatIDs[j] == stat)
+ break;
+ }
+ if (j == 4 && StorytellerGetGameStat(stat) >= minVal)
+ {
+ sStorytellerPtr->alreadyRecorded = TRUE;
+ if (GetFreeStorySlot() == 4)
+ StorytellerRecordNewStat(sSelectedStory, stat);
+ else
+ StorytellerRecordNewStat(GetFreeStorySlot(), stat);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static void StorytellerDisplayStory(u32 player)
+{
+ u8 stat = sStorytellerPtr->gameStatIDs[player];
+
+ ConvertIntToDecimalStringN(gStringVar1, StorytellerGetRecordedTrainerStat(player), 0, 10);
+ StringCopy(gStringVar2, GetStoryActionByStat(stat));
+ GetStoryByStattellerPlayerName(player, gStringVar3);
+ ConvertInternationalString(gStringVar3, sStorytellerPtr->language[player]);
+ ShowFieldMessage(GetStoryTextByStat(stat));
+}
+
+static void PrintStoryList(void)
+{
+ s32 i;
+ s32 width = GetStringWidth(1, gText_Exit, 0);
+ u8 tileWidth;
+ for (i = 0; i < 4; i++)
+ {
+ s32 curWidth;
+ u16 gameStatID = sStorytellerPtr->gameStatIDs[i];
+
+ if (gameStatID == 0)
+ break;
+ curWidth = GetStringWidth(1, GetStoryTitleByStat(gameStatID), 0);
+ if (curWidth > width)
+ width = curWidth;
+ }
+ sStorytellerWindowId = CreateWindowFromRect(0, 0, convert_pixel_width_to_tile_width(width), GetFreeStorySlot() * 2 + 2);
+ SetStandardWindowBorderStyle(sStorytellerWindowId, 0);
+ for (i = 0; i < 4; i++)
+ {
+ u16 gameStatID = sStorytellerPtr->gameStatIDs[i];
+ if (gameStatID == 0)
+ break;
+ PrintTextOnWindow(sStorytellerWindowId, 1, GetStoryTitleByStat(gameStatID), 8, 16 * i + 1, 0xFF, NULL);
+ }
+ PrintTextOnWindow(sStorytellerWindowId, 1, gText_Exit, 8, 16 * i + 1, 0xFF, NULL);
+ InitMenuInUpperLeftCornerPlaySoundWhenAPressed(sStorytellerWindowId, GetFreeStorySlot() + 1, 0);
+ CopyWindowToVram(sStorytellerWindowId, 3);
+}
+
+static void Task_StoryListMenu(u8 taskId) // Task_StoryListMenu
+{
+ struct Task *task = &gTasks[taskId];
+ s32 selection;
+
+ switch (task->data[0])
+ {
+ case 0:
+ PrintStoryList();
+ task->data[0]++;
+ break;
+ case 1:
+ selection = ProcessMenuInput();
+ if (selection == -2)
+ break;
+ if (selection == -1 || selection == GetFreeStorySlot())
+ {
+ gSpecialVar_Result = 0;
+ }
+ else
+ {
+ gSpecialVar_Result = 1;
+ sSelectedStory = selection;
+ }
+ sub_80E2A78(sStorytellerWindowId);
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+ break;
+ }
+}
+
+// Sets gSpecialVar_Result to TRUE if player selected a story
+void ScrSpecial_StorytellerStoryListMenu(void)
+{
+ CreateTask(Task_StoryListMenu, 80);
+}
+
+void ScrSpecial_StorytellerDisplayStory(void)
+{
+ StorytellerDisplayStory(sSelectedStory);
+}
+
+u8 ScrSpecial_StorytellerGetFreeStorySlot(void)
+{
+ sStorytellerPtr = &gSaveBlock1Ptr->oldMan.storyteller;
+ return GetFreeStorySlot();
+}
+
+// Returns TRUE if stat has increased
+bool8 ScrSpecial_StorytellerUpdateStat(void)
+{
+ u8 r4;
+ sStorytellerPtr = &gSaveBlock1Ptr->oldMan.storyteller;
+ r4 = sStorytellerPtr->gameStatIDs[sSelectedStory];
+
+ if (HasTrainerStatIncreased(sSelectedStory) == TRUE)
+ {
+ StorytellerRecordNewStat(sSelectedStory, r4);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 ScrSpecial_HasStorytellerAlreadyRecorded(void)
+{
+ sStorytellerPtr = &gSaveBlock1Ptr->oldMan.storyteller;
+
+ if (sStorytellerPtr->alreadyRecorded == FALSE)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+bool8 ScrSpecial_StorytellerInitializeRandomStat(void)
+{
+ sStorytellerPtr = &gSaveBlock1Ptr->oldMan.storyteller;
+ return StorytellerInitializeRandomStat();
+}
+
diff --git a/src/menu.c b/src/menu.c
index d06f950d3..dedfcc3be 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -25,11 +25,11 @@
#define STD_WINDOW_PALETTE_NUM 14
#define STD_WINDOW_BASE_TILE_NUM 0x214
-struct SomeUnkStruct_60F0D4
+struct MoveMenuInfoIcon
{
- u8 unk1;
- u8 unk2;
- u16 unk3;
+ u8 width;
+ u8 height;
+ u16 offset;
};
struct Menu
@@ -48,7 +48,7 @@ struct Menu
bool8 APressMuted;
};
-static EWRAM_DATA u8 gUnknown_0203CD8C = 0;
+static EWRAM_DATA u8 gStartMenuWindowId = 0;
static EWRAM_DATA u8 gUnknown_0203CD8D = 0;
static EWRAM_DATA struct Menu gUnknown_0203CD90 = {0};
static EWRAM_DATA u16 gUnknown_0203CD9C = 0;
@@ -63,7 +63,7 @@ static EWRAM_DATA void *gUnknown_0203CDAC[0x20] = {NULL};
const u16 gUnknown_0860F074[] = INCBIN_U16("graphics/interface/860F074.gbapal");
static const u8 gUnknown_0860F094[] = { 8, 4, 1 };
-static const struct WindowTemplate gUnknown_0860F098[] =
+static const struct WindowTemplate gUnknown_0860F098[] =
{
{ 0x00, 0x02, 0x0F, 0x1B, 0x04, 0x0F, 0x194 },
DUMMY_WIN_TEMPLATE
@@ -76,34 +76,36 @@ static const struct WindowTemplate gUnknown_0860F0A8 =
const u16 gUnknown_0860F0B0[] = INCBIN_U16("graphics/interface/860F0B0.gbapal");
const u8 gUnknown_0860F0D0[] = { 15, 1, 2 };
-const struct SomeUnkStruct_60F0D4 gUnknown_0860F0D4[] =
-{
- { 12, 12, 0x00 },
- { 32, 12, 0x20 },
- { 32, 12, 0x64 },
- { 32, 12, 0x60 },
- { 32, 12, 0x80 },
- { 32, 12, 0x48 },
- { 32, 12, 0x44 },
- { 32, 12, 0x6C },
- { 32, 12, 0x68 },
- { 32, 12, 0x88 },
- { 32, 12, 0xA4 },
- { 32, 12, 0x24 },
- { 32, 12, 0x28 },
- { 32, 12, 0x2C },
- { 32, 12, 0x40 },
- { 32, 12, 0x84 },
- { 32, 12, 0x4C },
- { 32, 12, 0xA0 },
- { 32, 12, 0x8C },
- { 42, 12, 0xA8 },
- { 42, 12, 0xC0 },
- { 42, 12, 0xC8 },
- { 42, 12, 0xE0 },
- { 42, 12, 0xE8 },
- { 8, 8, 0xAE },
- { 8, 8, 0xAF },
+
+// Table of move info icon offsets in graphics/interface_fr/menu.png
+const struct MoveMenuInfoIcon gMoveMenuInfoIcons[] =
+{ // { width, height, offset }
+ { 12, 12, 0x00 }, // Unused
+ { 32, 12, 0x20 }, // Normal icon
+ { 32, 12, 0x64 }, // Fight icon
+ { 32, 12, 0x60 }, // Flying icon
+ { 32, 12, 0x80 }, // Poison icon
+ { 32, 12, 0x48 }, // Ground icon
+ { 32, 12, 0x44 }, // Rock icon
+ { 32, 12, 0x6C }, // Bug icon
+ { 32, 12, 0x68 }, // Ghost icon
+ { 32, 12, 0x88 }, // Steel icon
+ { 32, 12, 0xA4 }, // ??? (Mystery) icon
+ { 32, 12, 0x24 }, // Fire icon
+ { 32, 12, 0x28 }, // Water icon
+ { 32, 12, 0x2C }, // Grass icon
+ { 32, 12, 0x40 }, // Electric icon
+ { 32, 12, 0x84 }, // Psychic icon
+ { 32, 12, 0x4C }, // Ice icon
+ { 32, 12, 0xA0 }, // Dragon icon
+ { 32, 12, 0x8C }, // Dark icon
+ { 42, 12, 0xA8 }, // -Type- icon
+ { 42, 12, 0xC0 }, // -Power- icon
+ { 42, 12, 0xC8 }, // -Accuracy- icon
+ { 42, 12, 0xE0 }, // -PP- icon
+ { 42, 12, 0xE8 }, // -Effect- icon
+ { 8, 8, 0xAE }, // Unused (Small white pokeball)
+ { 8, 8, 0xAF }, // Unused (Small dark pokeball)
};
// Forward declarations
@@ -125,7 +127,7 @@ extern void task_free_buf_after_copying_tile_data_to_vram(u8 taskId);
void sub_81971D0(void)
{
InitWindows(gUnknown_0860F098);
- gUnknown_0203CD8C = 0xFF;
+ gStartMenuWindowId = 0xFF;
gUnknown_0203CD8D = 0xFF;
}
@@ -151,7 +153,7 @@ u16 sub_8197224(void)
u16 AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 *str, u8 speed, void (*callback)(struct TextSubPrinter *, u16), u8 fgColor, u8 bgColor, u8 shadowColor)
{
struct TextSubPrinter printer;
-
+
printer.current_text_offset = str;
printer.windowId = windowId;
printer.fontId = fontId;
@@ -165,9 +167,9 @@ u16 AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 *str, u8 speed,
printer.fgColor = fgColor;
printer.bgColor = bgColor;
printer.shadowColor = shadowColor;
-
+
gTextFlags.flag_1 = 0;
- return AddTextPrinter(&printer, speed, callback);
+ return AddTextPrinter(&printer, speed, callback);
}
void AddTextPrinterForMessage(bool8 allowSkippingDelayWithButtonPress)
@@ -234,7 +236,7 @@ void sub_819746C(u8 windowId, bool8 copyToVram)
void DrawStandardFrame(u8 bg, u8 tilemapLeft, u8 tilemapTop, u8 width, u8 height, u8 paletteNum)
{
int i;
-
+
FillBgTilemapBufferRect(bg,
STD_WINDOW_BASE_TILE_NUM + 0,
tilemapLeft - 1,
@@ -256,7 +258,7 @@ void DrawStandardFrame(u8 bg, u8 tilemapLeft, u8 tilemapTop, u8 width, u8 height
1,
1,
STD_WINDOW_PALETTE_NUM);
-
+
for (i = tilemapTop; i < tilemapTop + height; i++)
{
FillBgTilemapBufferRect(bg,
@@ -274,7 +276,7 @@ void DrawStandardFrame(u8 bg, u8 tilemapLeft, u8 tilemapTop, u8 width, u8 height
1,
STD_WINDOW_PALETTE_NUM);
}
-
+
FillBgTilemapBufferRect(bg,
STD_WINDOW_BASE_TILE_NUM + 6,
tilemapLeft - 1,
@@ -471,22 +473,22 @@ u8 GetPlayerTextSpeed(void)
u8 sub_81979C4(u8 a1)
{
- if (gUnknown_0203CD8C == 0xFF)
- gUnknown_0203CD8C = sub_8198AA4(0, 0x16, 1, 7, (a1 * 2) + 2, 0xF, 0x139);
- return gUnknown_0203CD8C;
+ if (gStartMenuWindowId == 0xFF)
+ gStartMenuWindowId = sub_8198AA4(0, 0x16, 1, 7, (a1 * 2) + 2, 0xF, 0x139);
+ return gStartMenuWindowId;
}
u8 GetStartMenuWindowId(void)
{
- return gUnknown_0203CD8C;
+ return gStartMenuWindowId;
}
-void remove_start_menu_window_maybe(void)
+void RemoveStartMenuWindow(void)
{
- if (gUnknown_0203CD8C != 0xFF)
+ if (gStartMenuWindowId != 0xFF)
{
- RemoveWindow(gUnknown_0203CD8C);
- gUnknown_0203CD8C = 0xFF;
+ RemoveWindow(gStartMenuWindowId);
+ gStartMenuWindowId = 0xFF;
}
}
@@ -1941,7 +1943,7 @@ void box_print(u8 windowId, u8 fontId, u8 left, u8 top, const u8 *color, s8 spee
printer.fgColor = color[1];
printer.bgColor = color[0];
printer.shadowColor = color[2];
-
+
AddTextPrinter(&printer, speed, NULL);
}
@@ -1962,7 +1964,7 @@ void AddTextPrinterParameterized2(u8 windowId, u8 fontId, u8 left, u8 top, u8 le
printer.fgColor = color[1];
printer.bgColor = color[0];
printer.shadowColor = color[2];
-
+
AddTextPrinter(&printer, speed, NULL);
}
@@ -1988,7 +1990,7 @@ void sub_8199F74(u8 windowId, u8 fontId, const u8 *str, u8 left, u8 top, u8 spee
AddTextPrinter(&printer, speed, callback);
}
-void sub_819A024(u8 windowId, const u8 *src, u16 a2, u16 a3)
+void PrintPlayerNameOnWindow(u8 windowId, const u8 *src, u16 x, u16 y)
{
int count = 0;
while (gSaveBlock2Ptr->playerName[count] != EOS)
@@ -1996,7 +1998,7 @@ void sub_819A024(u8 windowId, const u8 *src, u16 a2, u16 a3)
StringExpandPlaceholders(gStringVar4, src);
- PrintTextOnWindow(windowId, 1, gStringVar4, a2, a3, 0xFF, 0);
+ PrintTextOnWindow(windowId, 1, gStringVar4, x, y, 0xFF, 0);
}
//Screw this function, it's long and unreferenced and ugh
@@ -2078,7 +2080,7 @@ void sub_819A080(struct UnkStruct_819A080 *a0, struct UnkStruct_819A080 *a1, u16
}
}
#else
-__attribute__((naked))
+NAKED
void sub_819A080(struct UnkStruct_819A080 *a0, struct UnkStruct_819A080 *a1, u16 a2, u16 a3, u16 a4, u16 a5, u16 a6, u16 a7)
{
asm("push {r4-r7,lr}\n\
@@ -2364,23 +2366,23 @@ void sub_819A2BC(u8 palOffset, u8 palId)
void blit_move_info_icon(u8 windowId, u8 iconId, u16 x, u16 y)
{
- BlitBitmapRectToWindow(windowId, gFireRedMenuElements_Gfx + gUnknown_0860F0D4[iconId].unk3 * 32, 0, 0, 128, 128, x, y, gUnknown_0860F0D4[iconId].unk1, gUnknown_0860F0D4[iconId].unk2);
+ BlitBitmapRectToWindow(windowId, gFireRedMenuElements_Gfx + gMoveMenuInfoIcons[iconId].offset * 32, 0, 0, 128, 128, x, y, gMoveMenuInfoIcons[iconId].width, gMoveMenuInfoIcons[iconId].height);
}
-void sub_819A344(u8 a0, u8 *a1, u8 a2)
+void sub_819A344(u8 a0, u8 *dest, u8 color)
{
s32 curFlag;
s32 flagCount;
u8 *endOfString;
- u8 *string = a1;
-
+ u8 *string = dest;
+
*(string++) = EXT_CTRL_CODE_BEGIN;
*(string++) = EXT_CTRL_CODE_COLOR;
- *(string++) = a2;
+ *(string++) = color;
*(string++) = EXT_CTRL_CODE_BEGIN;
*(string++) = EXT_CTRL_CODE_SHADOW;
- *(string++) = a2 + 1;
-
+ *(string++) = color + 1;
+
switch (a0)
{
case 0:
@@ -2388,9 +2390,9 @@ void sub_819A344(u8 a0, u8 *a1, u8 a2)
break;
case 1:
if (IsNationalPokedexEnabled())
- string = ConvertIntToDecimalStringN(string, pokedex_count(1), 0, 3);
+ string = ConvertIntToDecimalStringN(string, GetNationalPokedexCount(1), 0, 3);
else
- string = ConvertIntToDecimalStringN(string, sub_80C0844(1), 0, 3);
+ string = ConvertIntToDecimalStringN(string, GetHoennPokedexCount(1), 0, 3);
*string = EOS;
break;
case 2:
diff --git a/src/menu_helpers.c b/src/menu_helpers.c
new file mode 100644
index 000000000..178fbb5fa
--- /dev/null
+++ b/src/menu_helpers.c
@@ -0,0 +1,455 @@
+#include "global.h"
+#include "task.h"
+#include "window.h"
+#include "menu.h"
+#include "menu_helpers.h"
+#include "gpu_regs.h"
+#include "bg.h"
+#include "main.h"
+#include "text.h"
+#include "link.h"
+#include "string_util.h"
+#include "sound.h"
+#include "mail.h"
+#include "overworld.h"
+#include "decompress.h"
+#include "constants/songs.h"
+#include "constants/items.h"
+#include "constants/maps.h"
+
+extern bool32 sub_800B504(void);
+
+extern const u8 gBagSwapLineGfx[];
+extern const u8 gBagSwapLinePal[];
+
+// this file's functions
+static void Task_ContinueTaskAfterMessagePrints(u8 taskId);
+static void Task_CallYesOrNoCallback(u8 taskId);
+
+// EWRAM vars
+EWRAM_DATA static struct YesNoFuncTable gUnknown_0203A138 = {0};
+EWRAM_DATA static u8 gUnknown_0203A140 = 0;
+
+// IWRAM bss vars
+IWRAM_DATA static TaskFunc gUnknown_0300117C;
+
+// const rom data
+static const struct OamData sOamData_859F4E8 =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 1,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0
+};
+
+static const union AnimCmd sSpriteAnim_859F4F0[] =
+{
+ ANIMCMD_FRAME(0, 0),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_859F4F8[] =
+{
+ ANIMCMD_FRAME(4, 0),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_859F500[] =
+{
+ ANIMCMD_FRAME(0, 0, 1, 0),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_859F508[] =
+{
+ sSpriteAnim_859F4F0,
+ sSpriteAnim_859F4F8,
+ sSpriteAnim_859F500
+};
+
+static const struct CompressedSpriteSheet gUnknown_0859F514 =
+{
+ gBagSwapLineGfx, 0x100, 109
+};
+
+static const struct CompressedSpritePalette gUnknown_0859F51C =
+{
+ gBagSwapLinePal, 109
+};
+
+static const struct SpriteTemplate gUnknown_0859F524 =
+{
+ .tileTag = 109,
+ .paletteTag = 109,
+ .oam = &sOamData_859F4E8,
+ .anims = sSpriteAnimTable_859F508,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+// code
+void ResetVramOamAndBgCntRegs(void)
+{
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ SetGpuReg(REG_OFFSET_BG3CNT, 0);
+ SetGpuReg(REG_OFFSET_BG2CNT, 0);
+ SetGpuReg(REG_OFFSET_BG1CNT, 0);
+ SetGpuReg(REG_OFFSET_BG0CNT, 0);
+ CpuFill16(0, (void*) VRAM, VRAM_SIZE);
+ CpuFill32(0, (void*) OAM, OAM_SIZE);
+ CpuFill16(0, (void*) PLTT, PLTT_SIZE);
+}
+
+void ResetAllBgsCoordinates(void)
+{
+ ChangeBgX(0, 0, 0);
+ ChangeBgY(0, 0, 0);
+ ChangeBgX(1, 0, 0);
+ ChangeBgY(1, 0, 0);
+ ChangeBgX(2, 0, 0);
+ ChangeBgY(2, 0, 0);
+ ChangeBgX(3, 0, 0);
+ ChangeBgY(3, 0, 0);
+}
+
+void SetVBlankHBlankCallbacksToNull(void)
+{
+ SetVBlankCallback(NULL);
+ SetHBlankCallback(NULL);
+}
+
+void DisplayMessageAndContinueTask(u8 taskId, u8 windowId, u16 arg2, u8 arg3, u8 fontId, u8 textSpeed, const u8 *string, void *taskFunc)
+{
+ gUnknown_0203A140 = windowId;
+ sub_8197B1C(windowId, TRUE, arg2, arg3);
+
+ if (string != gStringVar4)
+ StringExpandPlaceholders(gStringVar4, string);
+
+ gTextFlags.flag_0 = 1;
+ AddTextPrinterParameterized(windowId, fontId, gStringVar4, textSpeed, NULL, 2, 1, 3);
+ gUnknown_0300117C = taskFunc;
+ gTasks[taskId].func = Task_ContinueTaskAfterMessagePrints;
+}
+
+bool16 RunTextPrintersRetIsActive(u8 textPrinterId)
+{
+ RunTextPrinters();
+ return IsTextPrinterActive(textPrinterId);
+}
+
+static void Task_ContinueTaskAfterMessagePrints(u8 taskId)
+{
+ if (!RunTextPrintersRetIsActive(gUnknown_0203A140))
+ gUnknown_0300117C(taskId);
+}
+
+void sub_8121F68(u8 taskId, const struct YesNoFuncTable *data)
+{
+ gUnknown_0203A138 = *data;
+ gTasks[taskId].func = Task_CallYesOrNoCallback;
+}
+
+void CreateYesNoMenuWithCallbacks(u8 taskId, const struct WindowTemplate *template, u8 arg2, u8 arg3, u8 arg4, u16 tileStart, u8 palette, const struct YesNoFuncTable *yesNo)
+{
+ CreateYesNoMenu(template, tileStart, palette, 0);
+ gUnknown_0203A138 = *yesNo;
+ gTasks[taskId].func = Task_CallYesOrNoCallback;
+}
+
+static void Task_CallYesOrNoCallback(u8 taskId)
+{
+ switch (ProcessMenuInputNoWrap_())
+ {
+ case 0:
+ PlaySE(SE_SELECT);
+ gUnknown_0203A138.yesFunc(taskId);
+ break;
+ case 1:
+ case MENU_B_PRESSED:
+ PlaySE(SE_SELECT);
+ gUnknown_0203A138.noFunc(taskId);
+ break;
+ }
+}
+
+bool8 AdjustQuantityAccordingToDPadInput(s16 *arg0, u16 arg1)
+{
+ s16 valBefore = (*arg0);
+
+ if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_UP)
+ {
+ (*arg0)++;
+ if ((*arg0) > arg1)
+ (*arg0) = 1;
+
+ if ((*arg0) == valBefore)
+ {
+ return FALSE;
+ }
+ else
+ {
+ PlaySE(SE_SELECT);
+ return TRUE;
+ }
+ }
+ else if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_DOWN)
+ {
+ (*arg0)--;
+ if ((*arg0) <= 0)
+ (*arg0) = arg1;
+
+ if ((*arg0) == valBefore)
+ {
+ return FALSE;
+ }
+ else
+ {
+ PlaySE(SE_SELECT);
+ return TRUE;
+ }
+ }
+ else if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_RIGHT)
+ {
+ (*arg0) += 10;
+ if ((*arg0) > arg1)
+ (*arg0) = arg1;
+
+ if ((*arg0) == valBefore)
+ {
+ return FALSE;
+ }
+ else
+ {
+ PlaySE(SE_SELECT);
+ return TRUE;
+ }
+ }
+ else if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_LEFT)
+ {
+ (*arg0) -= 10;
+ if ((*arg0) <= 0)
+ (*arg0) = 1;
+
+ if ((*arg0) == valBefore)
+ {
+ return FALSE;
+ }
+ else
+ {
+ PlaySE(SE_SELECT);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+u8 GetLRKeysState(void)
+{
+ if (gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_LR)
+ {
+ if (gMain.newKeys & L_BUTTON)
+ return 1;
+ if (gMain.newKeys & R_BUTTON)
+ return 2;
+ }
+
+ return 0;
+}
+
+u8 sub_812210C(void)
+{
+ if (gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_LR)
+ {
+ if (gMain.newAndRepeatedKeys & L_BUTTON)
+ return 1;
+ if (gMain.newAndRepeatedKeys & R_BUTTON)
+ return 2;
+ }
+
+ return 0;
+}
+
+bool8 sub_8122148(u16 itemId)
+{
+ if (itemId != ITEM_ENIGMA_BERRY)
+ return TRUE;
+ else if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(TRADE_CENTER) && gSaveBlock1Ptr->location.mapNum == MAP_NUM(TRADE_CENTER))
+ return FALSE;
+ else if (InUnionRoom() != TRUE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 itemid_80BF6D8_mail_related(u16 itemId)
+{
+ if (is_c1_link_related_active() != TRUE && InUnionRoom() != TRUE)
+ return TRUE;
+ else if (ItemIsMail(itemId) != TRUE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_81221AC(void)
+{
+ if (is_c1_link_related_active() == TRUE || gReceivedRemoteLinkPlayers == 1)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static bool8 sub_81221D0(void)
+{
+ if (!sub_81221AC())
+ return FALSE;
+ else
+ return sub_8087598();
+}
+
+bool8 sub_81221EC(void)
+{
+ if (sub_81221D0() == TRUE)
+ return TRUE;
+ else if (sub_800B504() != TRUE)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+void sub_812220C(struct ItemSlot *slots, u8 count, u8 *arg2, u8 *usedSlotsCount, u8 maxUsedSlotsCount)
+{
+ u16 i;
+ struct ItemSlot *slots_ = slots;
+
+ (*usedSlotsCount) = 0;
+ for (i = 0; i < count; i++)
+ {
+ if (slots_[i].itemId != ITEM_NONE)
+ (*usedSlotsCount)++;
+ }
+
+ (*usedSlotsCount)++;
+ if ((*usedSlotsCount) > maxUsedSlotsCount)
+ *arg2 = maxUsedSlotsCount;
+ else
+ *arg2 = (*usedSlotsCount);
+}
+
+void sub_812225C(u16 *arg0, u16 *arg1, u8 arg2, u8 arg3)
+{
+ if ((*arg0) != 0 && (*arg0) + arg2 > arg3)
+ (*arg0) = arg3 - arg2;
+
+ if ((*arg0) + (*arg1) >= arg3)
+ {
+ if (arg3 == 0)
+ (*arg1) = 0;
+ else
+ (*arg1) = arg3 - 1;
+ }
+}
+
+void sub_8122298(u16 *arg0, u16 *arg1, u8 arg2, u8 arg3, u8 arg4)
+{
+ u8 i;
+
+ if (arg4 % 2 != 0)
+ {
+ if ((*arg1) >= arg4 / 2)
+ {
+ for (i = 0; i < (*arg1) - (arg4 / 2); i++)
+ {
+ if ((*arg0) + arg2 == arg3)
+ break;
+ (*arg1)--;
+ (*arg0)++;
+ }
+ }
+ }
+ else
+ {
+ if ((*arg1) >= (arg4 / 2) + 1)
+ {
+ for (i = 0; i <= (*arg1) - (arg4 / 2); i++)
+ {
+ if ((*arg0) + arg2 == arg3)
+ break;
+ (*arg1)--;
+ (*arg0)++;
+ }
+ }
+ }
+}
+
+void LoadListMenuArrowsGfx(void)
+{
+ LoadCompressedObjectPic(&gUnknown_0859F514);
+ LoadCompressedObjectPalette(&gUnknown_0859F51C);
+}
+
+void sub_8122344(u8 *spriteIds, u8 count)
+{
+ u8 i;
+
+ for (i = 0; i < count; i++)
+ {
+ spriteIds[i] = CreateSprite(&gUnknown_0859F524, i * 16, 0, 0);
+ if (i != 0)
+ StartSpriteAnim(&gSprites[spriteIds[i]], 1);
+
+ gSprites[spriteIds[i]].invisible = 1;
+ }
+}
+
+void sub_81223B0(u8 *spriteIds, u8 count)
+{
+ u8 i;
+
+ for (i = 0; i < count; i++)
+ {
+ if (i == count - 1)
+ DestroySpriteAndFreeResources(&gSprites[spriteIds[i]]);
+ else
+ DestroySprite(&gSprites[spriteIds[i]]);
+ }
+}
+
+void sub_81223FC(u8 *spriteIds, u8 count, bool8 invisible)
+{
+ u8 i;
+
+ for (i = 0; i < count; i++)
+ {
+ gSprites[spriteIds[i]].invisible = invisible;
+ }
+}
+
+void sub_8122448(u8 *spriteIds, u8 count, s16 x, u16 y)
+{
+ u8 i;
+ bool8 unknownBit = count & 0x80;
+ count &= ~(0x80);
+
+ for (i = 0; i < count; i++)
+ {
+ if (i == count - 1 && unknownBit)
+ gSprites[spriteIds[i]].pos2.x = x - 8;
+ else
+ gSprites[spriteIds[i]].pos2.x = x;
+
+ gSprites[spriteIds[i]].pos1.y = 1 + y;
+ }
+}
diff --git a/src/mon_markings.c b/src/mon_markings.c
new file mode 100644
index 000000000..147872ab6
--- /dev/null
+++ b/src/mon_markings.c
@@ -0,0 +1,611 @@
+#include "global.h"
+#include "dma3.h"
+#include "graphics.h"
+#include "main.h"
+#include "menu_indicators.h"
+#include "mon_markings.h"
+#include "constants/songs.h"
+#include "sound.h"
+#include "sprite.h"
+#include "text_window.h"
+
+#define MENU_TEXT_SPRITE_X_OFFSET 32
+
+// static functions
+static void sub_811FC80(s16, s16, u16, u16);
+static void TaskDummy7(struct Sprite *);
+static void sub_811FF40(struct Sprite *);
+static void sub_811FF7C(struct Sprite *);
+static struct Sprite *sub_811FFD4(u16, u16, const u16 *, u16);
+
+// .rodata
+static const u16 gUnknown_0859E65C[] = INCBIN_U16("graphics/misc/mon_markings.gbapal");
+static const u8 gUnknown_0859E67C[] = INCBIN_U8("graphics/misc/mon_markings.4bpp");
+
+static const struct OamData gUnknown_0859EE7C =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 3,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const struct OamData gUnknown_0859EE84 =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 0,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const union AnimCmd gUnknown_0859EE8C[] =
+{
+ ANIMCMD_FRAME(0, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EE94[] =
+{
+ ANIMCMD_FRAME(1, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EE9C[] =
+{
+ ANIMCMD_FRAME(2, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EEA4[] =
+{
+ ANIMCMD_FRAME(3, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EEAC[] =
+{
+ ANIMCMD_FRAME(4, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EEB4[] =
+{
+ ANIMCMD_FRAME(5, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EEBC[] =
+{
+ ANIMCMD_FRAME(6, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EEC4[] =
+{
+ ANIMCMD_FRAME(7, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EECC[] =
+{
+ ANIMCMD_FRAME(8, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EED4[] =
+{
+ ANIMCMD_FRAME(9, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_0859EEDC[] =
+{
+ gUnknown_0859EE8C,
+ gUnknown_0859EE94,
+ gUnknown_0859EE9C,
+ gUnknown_0859EEA4,
+ gUnknown_0859EEAC,
+ gUnknown_0859EEB4,
+ gUnknown_0859EEBC,
+ gUnknown_0859EEC4,
+ gUnknown_0859EECC,
+ gUnknown_0859EED4,
+};
+
+static const union AnimCmd gUnknown_0859EF04[] =
+{
+ ANIMCMD_FRAME(0, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EF0C[] =
+{
+ ANIMCMD_FRAME(64, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_0859EF14[] =
+{
+ gUnknown_0859EF04,
+ gUnknown_0859EF0C,
+};
+
+static const struct OamData gUnknown_0859EF1C =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 1,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 1,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const union AnimCmd gUnknown_0859EF24[] =
+{
+ ANIMCMD_FRAME(0, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EF2C[] =
+{
+ ANIMCMD_FRAME(4, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EF34[] =
+{
+ ANIMCMD_FRAME(8, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EF3C[] =
+{
+ ANIMCMD_FRAME(12, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EF44[] =
+{
+ ANIMCMD_FRAME(16, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EF4C[] =
+{
+ ANIMCMD_FRAME(20, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EF54[] =
+{
+ ANIMCMD_FRAME(24, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EF5C[] =
+{
+ ANIMCMD_FRAME(28, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EF64[] =
+{
+ ANIMCMD_FRAME(32, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EF6C[] =
+{
+ ANIMCMD_FRAME(36, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EF74[] =
+{
+ ANIMCMD_FRAME(40, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EF7C[] =
+{
+ ANIMCMD_FRAME(44, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EF84[] =
+{
+ ANIMCMD_FRAME(48, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EF8C[] =
+{
+ ANIMCMD_FRAME(52, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EF94[] =
+{
+ ANIMCMD_FRAME(56, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_0859EF9C[] =
+{
+ ANIMCMD_FRAME(60, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_0859EFA4[] =
+{
+ gUnknown_0859EF24,
+ gUnknown_0859EF2C,
+ gUnknown_0859EF34,
+ gUnknown_0859EF3C,
+ gUnknown_0859EF44,
+ gUnknown_0859EF4C,
+ gUnknown_0859EF54,
+ gUnknown_0859EF5C,
+ gUnknown_0859EF64,
+ gUnknown_0859EF6C,
+ gUnknown_0859EF74,
+ gUnknown_0859EF7C,
+ gUnknown_0859EF84,
+ gUnknown_0859EF8C,
+ gUnknown_0859EF94,
+ gUnknown_0859EF9C,
+};
+
+static EWRAM_DATA struct PokemonMarkMenu *sMenu = NULL;
+
+void sub_811F90C(struct PokemonMarkMenu *ptr)
+{
+ sMenu = ptr;
+}
+
+void sub_811F918(void)
+{
+ const struct TilesPal *frame = GetWindowFrameTilesPal(gSaveBlock2Ptr->optionsWindowFrameType);
+ sMenu->frameTiles = frame->tiles;
+ sMenu->framePalette = frame->pal;
+ sMenu->tileLoadState = 0;
+ CpuFill16(0, sMenu->menuWindowSpriteTiles, sizeof(sMenu->menuWindowSpriteTiles));
+}
+
+bool8 sub_811F960(void)
+{
+ u16 i;
+ u8 *dest = sMenu->menuWindowSpriteTiles + sMenu->tileLoadState * 0x100;
+
+ switch (sMenu->tileLoadState)
+ {
+ case 0:
+ CpuFastCopy(sMenu->frameTiles, dest, TILE_SIZE_4BPP);
+ for (i = 0; i < 6; i++)
+ {
+ CpuFastCopy(sMenu->frameTiles + TILE_SIZE_4BPP, dest + TILE_SIZE_4BPP * (i + 1), TILE_SIZE_4BPP);
+ }
+ CpuFastCopy(sMenu->frameTiles + TILE_SIZE_4BPP * 2, dest + TILE_SIZE_4BPP * 7, TILE_SIZE_4BPP);
+ sMenu->tileLoadState++;
+ break;
+ default:
+ CpuFastCopy(sMenu->frameTiles + TILE_SIZE_4BPP * 3, dest, TILE_SIZE_4BPP);
+ for (i = 0; i < 6; i++)
+ {
+ CpuFastCopy(sMenu->frameTiles + TILE_SIZE_4BPP * 4, dest + TILE_SIZE_4BPP * (i + 1), TILE_SIZE_4BPP);
+ }
+ CpuFastCopy(sMenu->frameTiles + TILE_SIZE_4BPP * 5, dest + TILE_SIZE_4BPP * 7, TILE_SIZE_4BPP);
+ sMenu->tileLoadState++;
+ break;
+ case 13:
+ CpuFastCopy(sMenu->frameTiles + TILE_SIZE_4BPP * 6, dest, TILE_SIZE_4BPP);
+ for (i = 0; i < 6; i++)
+ {
+ CpuFastCopy(sMenu->frameTiles + TILE_SIZE_4BPP * 7, dest + TILE_SIZE_4BPP * (i + 1), TILE_SIZE_4BPP);
+ }
+ CpuFastCopy(sMenu->frameTiles + TILE_SIZE_4BPP * 8, dest + TILE_SIZE_4BPP * 7, TILE_SIZE_4BPP);
+ sMenu->tileLoadState++;
+ return FALSE;
+ case 14:
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void sub_811FA90(void)
+{
+ sub_811F918();
+ while (sub_811F960());
+}
+
+void sub_811FAA4(u8 markings, s16 x, s16 y)
+{
+ u16 i;
+ sMenu->cursorPos = 0;
+ sMenu->markings = markings;
+ for (i = 0; i < 4; i++)
+ sMenu->markingsArray[i] = (sMenu->markings >> i) & 1;
+ sub_811FC80(x, y, sMenu->baseTileTag, sMenu->basePaletteTag);
+}
+
+void sub_811FAF8(void)
+{
+ u16 i;
+
+ for (i = 0; i < 2; i++)
+ {
+ FreeSpriteTilesByTag(sMenu->baseTileTag + i);
+ FreeSpritePaletteByTag(sMenu->basePaletteTag + i);
+ }
+ for (i = 0; i < 2; i++)
+ {
+ if (!sMenu->menuWindowSprites[i])
+ return;
+ DestroySprite(sMenu->menuWindowSprites[i]);
+ sMenu->menuWindowSprites[i] = NULL;
+ }
+ for (i = 0; i < 4; i++)
+ {
+ if (!sMenu->menuMarkingSprites[i])
+ return;
+ DestroySprite(sMenu->menuMarkingSprites[i]);
+ sMenu->menuMarkingSprites[i] = NULL;
+ }
+ if (sMenu->unkSprite)
+ {
+ DestroySprite(sMenu->unkSprite);
+ sMenu->unkSprite = NULL;
+ }
+ if (sMenu->menuTextSprite)
+ {
+ DestroySprite(sMenu->menuTextSprite);
+ sMenu->menuTextSprite = NULL;
+ }
+}
+
+
+bool8 sub_811FBA4(void)
+{
+ u16 i;
+
+ if (gMain.newKeys & DPAD_UP)
+ {
+ s8 pos;
+ PlaySE(SE_SELECT);
+ pos = --sMenu->cursorPos;
+ if (pos < 0)
+ sMenu->cursorPos = 5;
+ return TRUE;
+ }
+
+ if (gMain.newKeys & DPAD_DOWN)
+ {
+ s8 pos;
+ PlaySE(SE_SELECT);
+ pos = ++sMenu->cursorPos;
+ if (pos > 5)
+ sMenu->cursorPos = 0;
+ return TRUE;
+ }
+
+ if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+
+ switch (sMenu->cursorPos)
+ {
+ case 4:
+ sMenu->markings = 0;
+ for (i = 0; i < 4; i++)
+ sMenu->markings |= sMenu->markingsArray[i] << i;
+ return FALSE;
+ case 5:
+ return FALSE;
+ }
+
+ sMenu->markingsArray[sMenu->cursorPos] = !sMenu->markingsArray[sMenu->cursorPos];
+ return TRUE;
+ }
+
+ if (gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void sub_811FC80(s16 x, s16 y, u16 baseTileTag, u16 basePaletteTag)
+{
+ u16 i;
+ u8 spriteId;
+
+ struct SpriteSheet sheets[] =
+ {
+ { sMenu->menuWindowSpriteTiles, 0x1000, baseTileTag },
+ { gPokenavConditionMarker_Gfx, 0x320, baseTileTag + 1 },
+ { NULL, 0 }
+ };
+
+ struct SpritePalette palettes[] =
+ {
+ { sMenu->framePalette, basePaletteTag },
+ { gPokenavConditionMarker_Pal, basePaletteTag + 1},
+ { NULL, 0 }
+ };
+
+ struct SpriteTemplate sprTemplate =
+ {
+ baseTileTag,
+ basePaletteTag,
+ &gUnknown_0859EE7C,
+ gUnknown_0859EF14,
+ NULL,
+ gDummySpriteAffineAnimTable,
+ TaskDummy7,
+ };
+
+ LoadSpriteSheets(sheets);
+ LoadSpritePalettes(palettes);
+
+ for (i = 0; i < 2; i++)
+ {
+ spriteId = CreateSprite(&sprTemplate, x + 32, y + 32, 1);
+ if (spriteId != 64)
+ {
+ sMenu->menuWindowSprites[i] = &gSprites[spriteId];
+ StartSpriteAnim(&gSprites[spriteId], i);
+ }
+ else
+ {
+ sMenu->menuWindowSprites[i] = NULL;
+ return;
+ }
+ }
+
+ sMenu->menuWindowSprites[1]->pos1.y = y + 96;
+
+ sprTemplate.tileTag++;
+ sprTemplate.paletteTag++;
+ sprTemplate.anims = gUnknown_0859EEDC;
+ sprTemplate.callback = sub_811FF40;
+ sprTemplate.oam = &gUnknown_0859EE84;
+
+ for (i = 0; i < 4; i++)
+ {
+ spriteId = CreateSprite(&sprTemplate, x + 32, y + 16 + 16 * i, 0);
+ if (spriteId != 64)
+ {
+ sMenu->menuMarkingSprites[i] = &gSprites[spriteId];
+ gSprites[spriteId].data[0] = i;
+ }
+ else
+ {
+ sMenu->menuMarkingSprites[i] = NULL;
+ return;
+ }
+ }
+
+ sprTemplate.callback = SpriteCallbackDummy;
+
+ spriteId = CreateSprite(&sprTemplate, 0, 0, 0);
+
+ if (spriteId != 64)
+ {
+ sMenu->menuTextSprite = &gSprites[spriteId];
+ sMenu->menuTextSprite->oam.shape = ST_OAM_SQUARE;
+ sMenu->menuTextSprite->oam.size = 2;
+ StartSpriteAnim(sMenu->menuTextSprite, 9);
+ sMenu->menuTextSprite->pos1.x = x + MENU_TEXT_SPRITE_X_OFFSET;
+ sMenu->menuTextSprite->pos1.y = y + 80;
+ CalcCenterToCornerVec(sMenu->menuTextSprite, 1, 2, 0);
+ }
+ else
+ {
+ sMenu->menuTextSprite = NULL;
+ }
+
+ sprTemplate.callback = sub_811FF7C;
+ spriteId = CreateSprite(&sprTemplate, x + 12, 0, 0);
+ if(spriteId != 64)
+ {
+ sMenu->unkSprite = &gSprites[spriteId];
+ sMenu->unkSprite->data[0] = y + 16;
+ StartSpriteAnim(sMenu->unkSprite, 8);
+ }
+ else
+ {
+ sMenu->unkSprite = NULL;
+ }
+
+}
+
+static void TaskDummy7(struct Sprite *sprite)
+{
+}
+
+static void sub_811FF40(struct Sprite *sprite)
+{
+ if (sMenu->markingsArray[sprite->data[0]])
+ StartSpriteAnim(sprite, 2 * sprite->data[0] + 1);
+ else
+ StartSpriteAnim(sprite, 2 * sprite->data[0]);
+}
+
+static void sub_811FF7C(struct Sprite *sprite)
+{
+ sprite->pos1.y = (16 * sMenu->cursorPos) + sprite->data[0];
+}
+
+struct Sprite *sub_811FF94(u16 tileTag, u16 paletteTag, const u16 *palette)
+{
+ if (!palette)
+ palette = gUnknown_0859E65C;
+ return sub_811FFD4(tileTag, paletteTag, palette, 16);
+}
+
+struct Sprite *sub_811FFB4(u16 tileTag, u16 paletteTag, const u16 *palette)
+{
+ if (!palette)
+ palette = gUnknown_0859E65C;
+ return sub_811FFD4(tileTag, paletteTag, palette, 1);
+}
+
+static struct Sprite *sub_811FFD4(u16 tileTag, u16 paletteTag, const u16 *palette, u16 size)
+{
+ u8 spriteId;
+ struct SpriteTemplate sprTemplate;
+ struct SpriteSheet sheet = { gUnknown_0859E67C, 0x80, tileTag };
+ struct SpritePalette sprPalette = { palette, paletteTag };
+
+ sprTemplate.tileTag = tileTag;
+ sprTemplate.paletteTag = paletteTag;
+ sprTemplate.oam = &gUnknown_0859EF1C;
+ sprTemplate.anims = gUnknown_0859EFA4;
+ sprTemplate.images = NULL;
+ sprTemplate.affineAnims = gDummySpriteAffineAnimTable;
+ sprTemplate.callback = TaskDummy7;
+
+ sheet.size = size * 0x80;
+
+ LoadSpriteSheet(&sheet);
+ LoadSpritePalette(&sprPalette);
+
+ spriteId = CreateSprite(&sprTemplate, 0, 0, 0);
+ if (spriteId != 64)
+ return &gSprites[spriteId];
+ else
+ return NULL;
+}
+
+void sub_8120084(u8 markings, void *dest)
+{
+ RequestDma3Copy(gUnknown_0859E67C + markings * 0x80, dest, 0x80, 0x10);
+}
diff --git a/src/mystery_event_menu.c b/src/mystery_event_menu.c
index 31b366ae9..8a7671c5b 100644
--- a/src/mystery_event_menu.c
+++ b/src/mystery_event_menu.c
@@ -189,7 +189,7 @@ static void CB2_MysteryEventMenu(void)
{
if (gReceivedRemoteLinkPlayers != 0)
{
- if (sub_800A0C8(2, 2) == 3)
+ if (GetLinkPlayerDataExchangeStatusTimed(2, 2) == 3)
{
sub_800AC34();
GetEventLoadMessage(gStringVar4, 1);
@@ -241,7 +241,7 @@ static void CB2_MysteryEventMenu(void)
u16 unkVal = RunMysteryEventScript(gDecompressionBuffer);
CpuFill32(0, gDecompressionBuffer, 0x7D4);
if (!GetEventLoadMessage(gStringVar4, unkVal))
- TrySavingData(NORMAL_SAVE);
+ TrySavingData(SAVE_NORMAL);
gMain.state++;
}
break;
diff --git a/src/naming_screen.c b/src/naming_screen.c
index 47d8b8ad1..0e350aa35 100644
--- a/src/naming_screen.c
+++ b/src/naming_screen.c
@@ -75,7 +75,7 @@ static const u8 gSpriteImage_858BCB8[] = INCBIN_U8("graphics/naming_screen/pc_ic
static const u16 gUnknown_0858BD78[] = INCBIN_U16("graphics/naming_screen/0.gbapal");
static const u16 gUnknown_0858BD98[] = INCBIN_U16("graphics/naming_screen/1.gbapal");
-static const u8 *const gUnknown_0858BDB8[] =
+static const u8 *const gUnknown_0858BDB8[] =
{
gText_PkmnTransferredSomeonesPC,
gText_PkmnTransferredLanettesPC,
@@ -85,7 +85,7 @@ static const u8 *const gUnknown_0858BDB8[] =
static const u8 gUnknown_0858BDC8[] = _("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!");
-static const struct BgTemplate gUnknown_0858BE00[] =
+static const struct BgTemplate gUnknown_0858BE00[] =
{
{
.bg = 0,
@@ -226,10 +226,10 @@ void DoNamingScreen(u8 templateNum, u8 *destBuffer, u16 monSpecies, u16 monGende
gNamingScreenData->monPersonality = monPersonality;
gNamingScreenData->destBuffer = destBuffer;
gNamingScreenData->returnCallback = returnCallback;
-
+
if (templateNum == 0)
StartTimer1();
-
+
SetMainCallback2(C2_NamingScreen);
}
}
@@ -316,15 +316,15 @@ static void sub_80E2FA4(void)
static void NamingScreen_InitBGs(void)
{
u8 i;
-
+
DmaClearLarge16(3, (void *)VRAM, VRAM_SIZE, 0x1000);
DmaClear32(3, (void *)OAM, OAM_SIZE);
DmaClear16(3, (void *)PLTT, PLTT_SIZE);
-
+
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0);
ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, gUnknown_0858BE00, 4);
-
+
ChangeBgX(0, 0, 0);
ChangeBgY(0, 0, 0);
ChangeBgX(1, 0, 0);
@@ -333,21 +333,21 @@ static void NamingScreen_InitBGs(void)
ChangeBgY(2, 0, 0);
ChangeBgX(3, 0, 0);
ChangeBgY(3, 0, 0);
-
+
sub_81971D0();
sub_8197200();
-
+
for (i = 0; i < 5; i++)
gNamingScreenData->windows[i] = AddWindow(&gUnknown_0858BE10[i]);
-
+
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON);
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2);
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0xC, 0x8));
-
+
SetBgTilemapBuffer(1, gNamingScreenData->tilemapBuffer1);
SetBgTilemapBuffer(2, gNamingScreenData->tilemapBuffer2);
SetBgTilemapBuffer(3, gNamingScreenData->tilemapBuffer3);
-
+
FillBgTilemapBufferRect_Palette0(1, 0, 0, 0, 0x20, 0x20);
FillBgTilemapBufferRect_Palette0(2, 0, 0, 0, 0x20, 0x20);
FillBgTilemapBufferRect_Palette0(3, 0, 0, 0, 0x20, 0x20);
@@ -511,7 +511,7 @@ static bool8 MainState_WaitFadeOutAndExit(void)
static void DisplaySentToPCMessage(void)
{
u8 stringToDisplay = 0;
-
+
if (!sub_813B260())
{
StringCopy(gStringVar1, GetBoxNamePtr(VarGet(VAR_STORAGE_UNKNOWN)));
@@ -524,10 +524,10 @@ static void DisplaySentToPCMessage(void)
StringCopy(gStringVar3, GetBoxNamePtr(get_unknown_box_id()));
stringToDisplay = 2;
}
-
+
if (FlagGet(FLAG_SYS_PC_LANETTE))
stringToDisplay++;
-
+
StringExpandPlaceholders(gStringVar4, gUnknown_0858BDB8[stringToDisplay]);
NewMenuHelpers_DrawDialogueFrame(0, 0);
gTextFlags.flag_0 = TRUE;
@@ -538,10 +538,10 @@ static void DisplaySentToPCMessage(void)
static bool8 sub_80E3604(void)
{
RunTextPrinters();
-
+
if (!IsTextPrinterActive(0) && (gMain.newKeys & A_BUTTON))
gNamingScreenData->state = MAIN_STATE_BEGIN_FADE_OUT;
-
+
return FALSE;
}
@@ -562,17 +562,17 @@ static bool8 MainState_WaitPageSwap(void)
s16 cursorX;
s16 cursorY;
bool32 var3;
-
+
if (IsPageSwapAnimNotInProgress())
{
-
+
GetCursorPos(&cursorX, &cursorY);
var3 = (cursorX == GetCurrentPageColumnCount());
-
+
gNamingScreenData->state = MAIN_STATE_HANDLE_INPUT;
gNamingScreenData->currentPage++;
gNamingScreenData->currentPage %= 3;
-
+
if (var3)
{
cursorX = GetCurrentPageColumnCount();
@@ -582,7 +582,7 @@ static bool8 MainState_WaitPageSwap(void)
if (cursorX >= GetCurrentPageColumnCount())
cursorX = GetCurrentPageColumnCount() - 1;
}
-
+
SetCursorPos(cursorX, cursorY);
sub_80E4E5C();
SetInputState(INPUT_STATE_ENABLED);
@@ -603,7 +603,7 @@ static bool8 PageSwapAnimState_1(struct Task *);
static bool8 PageSwapAnimState_2(struct Task *);
static bool8 PageSwapAnimState_Done(struct Task *);
-static bool8 (*const sPageSwapAnimStateFuncs[])(struct Task *) =
+static bool8 (*const sPageSwapAnimStateFuncs[])(struct Task *) =
{
PageSwapAnimState_Init,
PageSwapAnimState_1,
@@ -754,7 +754,7 @@ static void Task_80E39BC(u8 taskId)
task->data[3] += task->data[4];
task->data[6] += task->data[4];
}
-
+
if (task->data[3] == 16 && task->data[6] == 22)
{
task->data[4] = -4;
@@ -893,7 +893,7 @@ static void CursorInit(void)
static void SetCursorPos(s16 x, s16 y)
{
struct Sprite *cursorSprite = &gSprites[gNamingScreenData->cursorSpriteId];
-
+
if (x < gUnknown_0858BEA0[sub_80E3274()])
cursorSprite->pos1.x = gUnknown_0858BEA3[x + sub_80E3274() * 8] + 38;
else
@@ -909,7 +909,7 @@ static void SetCursorPos(s16 x, s16 y)
static void GetCursorPos(s16 *x, s16 *y)
{
struct Sprite *cursorSprite = &gSprites[gNamingScreenData->cursorSpriteId];
-
+
*x = cursorSprite->data[0];
*y = cursorSprite->data[1];
}
@@ -1133,7 +1133,7 @@ static void CreateInputTargetIcon(void)
static void TaskDummy2(void)
{
-
+
}
static void NamingScreen_CreatePlayerIcon(void)
@@ -1160,7 +1160,7 @@ static void NamingScreen_CreateMonIcon(void)
{
u8 spriteId;
- sub_80D2F04();
+ LoadMonIconPalettes();
spriteId = CreateMonIcon(gNamingScreenData->monSpecies, SpriteCallbackDummy, 0x38, 0x28, 0, gNamingScreenData->monPersonality, 1);
gSprites[spriteId].oam.priority = 3;
}
@@ -1331,7 +1331,7 @@ static void InputState_Disabled(struct Task *task)
static void InputState_Enabled(struct Task *task)
{
task->tKeyboardEvent = 0;
-
+
if (gMain.newKeys & A_BUTTON)
task->tKeyboardEvent = KBEVENT_PRESSED_A;
else if (gMain.newKeys & B_BUTTON)
@@ -1454,7 +1454,7 @@ static void sub_80E4894(void)
static void sub_80E48E8(void)
{
u8 buffer[0x20];
-
+
StringCopy(buffer, gSpeciesNames[gNamingScreenData->monSpecies]);
StringAppendN(buffer, gNamingScreenData->template->title, 15);
FillWindowPixelBuffer(gNamingScreenData->windows[3], 0x11);
@@ -1492,10 +1492,10 @@ static void sub_80E498C(void)
static void TaskDummy3(void)
{
-
+
}
-static const u8 sGenderColors[2][3] =
+static const u8 sGenderColors[2][3] =
{
{0, 9, 8},
{0, 5, 4}
@@ -1505,7 +1505,7 @@ static void sub_80E49BC(void)
{
u8 genderSymbol[2];
bool8 isFemale = FALSE;
-
+
StringCopy(genderSymbol, gText_MaleSymbol);
if (gNamingScreenData->monGender != MON_GENDERLESS)
@@ -1575,7 +1575,7 @@ static bool8 sub_80E4B54(void)
sub_80E4D10();
CopyBgTilemapBufferToVram(3);
PlaySE(SE_SELECT);
-
+
if (GetPreviousTextCaretPosition() != gNamingScreenData->template->maxChars - 1)
return FALSE;
else
@@ -1633,7 +1633,7 @@ static void sub_80E4CF8(u8 bg, const void *src)
static void nullsub_10(u8 a1, u8 a2)
{
-
+
}
static void sub_80E4D10(void)
@@ -1643,18 +1643,18 @@ static void sub_80E4D10(void)
u16 unk2;
u8 maxChars = gNamingScreenData->template->maxChars;
u16 unk = gNamingScreenData->inputCharBaseXPos - 0x40;
-
+
FillWindowPixelBuffer(gNamingScreenData->windows[2], 0x11);
-
+
for (i = 0; i < maxChars; i++)
{
temp[0] = gNamingScreenData->textBuffer[i];
temp[1] = gExpandedPlaceholder_Empty[0];
unk2 = (sub_80E503C(temp[0]) == 1) ? 2 : 0;
-
+
PrintTextOnWindow(gNamingScreenData->windows[2], 1, temp, i * 8 + unk + unk2, 1, 0xFF, NULL);
}
-
+
sub_80E498C();
CopyWindowToVram(gNamingScreenData->windows[2], 2);
PutWindowTilemap(gNamingScreenData->windows[2]);
@@ -1674,12 +1674,12 @@ static const struct TextColorThing sUnkColorStruct =
}
};
-static const u8 sFillValues[3] =
+static const u8 sFillValues[3] =
{
0xEE, 0xDD, 0xFF
};
-static const u8 *const sUnkColors[3] =
+static const u8 *const sUnkColors[3] =
{
sUnkColorStruct.colors[1],
sUnkColorStruct.colors[0],
@@ -1689,18 +1689,18 @@ static const u8 *const sUnkColors[3] =
static void sub_80E4DE4(u8 window, u8 a1)
{
u8 i;
-
+
FillWindowPixelBuffer(window, sFillValues[a1]);
-
+
for (i = 0; i < 4; i++)
{
box_print(window, 1, 0, i * 16 + 1, sUnkColors[a1], 0, gUnknown_0858C198[a1][i]);
}
-
+
PutWindowTilemap(window);
}
-static const u8 *const gUnknown_0858BF98[] =
+static const u8 *const gUnknown_0858BF98[] =
{
gUnknown_08DD4620,
gUnknown_08DD46E0,
@@ -1714,7 +1714,7 @@ static void sub_80E4E5C(void)
u8 unk3;
u8 bg1Priority = GetGpuReg(REG_OFFSET_BG1CNT) & 3;
u8 bg2Priority = GetGpuReg(REG_OFFSET_BG2CNT) & 3;
-
+
if (bg1Priority > bg2Priority)
{
unk1 = 1;
@@ -1727,7 +1727,7 @@ static void sub_80E4E5C(void)
unk2 = 2;
unk3 = gNamingScreenData->windows[1];
}
-
+
sub_80E4CF8(unk1, gUnknown_0858BF98[gNamingScreenData->currentPage]);
sub_80E4DE4(unk3, sub_80E3254());
nullsub_10(unk1, sub_80E3254());
@@ -1737,7 +1737,7 @@ static void sub_80E4E5C(void)
static void sub_80E4EF0(void)
{
const u8 color[3] = { 15, 1, 2 };
-
+
FillWindowPixelBuffer(gNamingScreenData->windows[4], 0xFF);
box_print(gNamingScreenData->windows[4], 0, 2, 1, color, 0, gText_MoveOkBack);
PutWindowTilemap(gNamingScreenData->windows[4]);
@@ -1787,7 +1787,7 @@ static void sub_80E501C(void)
static bool8 sub_80E503C(u8 character)
{
u8 i;
-
+
for (i = 0; gUnknown_0858BDC8[i] != EOS; i++)
{
if (character == gUnknown_0858BDC8[i])
@@ -1798,22 +1798,22 @@ static bool8 sub_80E503C(u8 character)
static void sub_80E5074(void)
{
- DoNamingScreen(0, gSaveBlock2Ptr->playerName, gSaveBlock2Ptr->playerGender, 0, 0, sub_8086194);
+ DoNamingScreen(0, gSaveBlock2Ptr->playerName, gSaveBlock2Ptr->playerGender, 0, 0, CB2_ReturnToFieldWithOpenMenu);
}
static void sub_80E509C(void)
{
- DoNamingScreen(1, gSaveBlock2Ptr->playerName, gSaveBlock2Ptr->playerGender, 0, 0, sub_8086194);
+ DoNamingScreen(1, gSaveBlock2Ptr->playerName, gSaveBlock2Ptr->playerGender, 0, 0, CB2_ReturnToFieldWithOpenMenu);
}
static void sub_80E50C4(void)
{
- DoNamingScreen(2, gSaveBlock2Ptr->playerName, gSaveBlock2Ptr->playerGender, 0, 0, sub_8086194);
+ DoNamingScreen(2, gSaveBlock2Ptr->playerName, gSaveBlock2Ptr->playerGender, 0, 0, CB2_ReturnToFieldWithOpenMenu);
}
static void sub_80E50EC(void)
{
- DoNamingScreen(3, gSaveBlock2Ptr->playerName, gSaveBlock2Ptr->playerGender, 0, 0, sub_8086194);
+ DoNamingScreen(3, gSaveBlock2Ptr->playerName, gSaveBlock2Ptr->playerGender, 0, 0, CB2_ReturnToFieldWithOpenMenu);
}
//--------------------------------------------------
@@ -1987,20 +1987,20 @@ static const struct SpriteFrameImage gUnknown_0858C080[] =
{gSpriteImage_858BCB8, sizeof(gSpriteImage_858BCB8)},
};
-static const union AnimCmd gSpriteAnim_858C090[] =
+static const union AnimCmd gSpriteAnim_858C090[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_JUMP(0)
};
-static const union AnimCmd gSpriteAnim_858C098[] =
+static const union AnimCmd gSpriteAnim_858C098[] =
{
ANIMCMD_FRAME(4, 8),
ANIMCMD_FRAME(8, 8),
ANIMCMD_END
};
-static const union AnimCmd gSpriteAnim_858C0A4[] =
+static const union AnimCmd gSpriteAnim_858C0A4[] =
{
ANIMCMD_FRAME(0, 2),
ANIMCMD_FRAME(1, 2),
@@ -2023,7 +2023,7 @@ static const union AnimCmd *const gSpriteAnimTable_858C0BC[] =
gSpriteAnim_858C0A4
};
-static const struct SpriteTemplate gUnknown_0858C0C0 =
+static const struct SpriteTemplate gUnknown_0858C0C0 =
{
.tileTag = 0x0002,
.paletteTag = 0x0004,
@@ -2034,7 +2034,7 @@ static const struct SpriteTemplate gUnknown_0858C0C0 =
.callback = sub_80E4084
};
-static const struct SpriteTemplate gUnknown_0858C0D8 =
+static const struct SpriteTemplate gUnknown_0858C0D8 =
{
.tileTag = 0x0003,
.paletteTag = 0x0001,
@@ -2045,7 +2045,7 @@ static const struct SpriteTemplate gUnknown_0858C0D8 =
.callback = SpriteCallbackDummy
};
-static const struct SpriteTemplate gUnknown_0858C0F0 =
+static const struct SpriteTemplate gUnknown_0858C0F0 =
{
.tileTag = 0x0004,
.paletteTag = 0x0004,
@@ -2056,7 +2056,7 @@ static const struct SpriteTemplate gUnknown_0858C0F0 =
.callback = SpriteCallbackDummy
};
-static const struct SpriteTemplate gUnknown_0858C108 =
+static const struct SpriteTemplate gUnknown_0858C108 =
{
.tileTag = 0x0000,
.paletteTag = 0x0006,
@@ -2067,7 +2067,7 @@ static const struct SpriteTemplate gUnknown_0858C108 =
.callback = SpriteCallbackDummy
};
-static const struct SpriteTemplate gUnknown_0858C120 =
+static const struct SpriteTemplate gUnknown_0858C120 =
{
.tileTag = 0x0001,
.paletteTag = 0x0007,
@@ -2078,7 +2078,7 @@ static const struct SpriteTemplate gUnknown_0858C120 =
.callback = SpriteCallbackDummy
};
-static const struct SpriteTemplate gUnknown_0858C138 =
+static const struct SpriteTemplate gUnknown_0858C138 =
{
.tileTag = 0x0007,
.paletteTag = 0x0005,
@@ -2089,7 +2089,7 @@ static const struct SpriteTemplate gUnknown_0858C138 =
.callback = sub_80E3B30
};
-static const struct SpriteTemplate sSpriteTemplate_InputArrow =
+static const struct SpriteTemplate sSpriteTemplate_InputArrow =
{
.tileTag = 0x000A,
.paletteTag = 0x0003,
@@ -2100,7 +2100,7 @@ static const struct SpriteTemplate sSpriteTemplate_InputArrow =
.callback = sub_80E3C20
};
-static const struct SpriteTemplate sSpriteTemplate_Underscore =
+static const struct SpriteTemplate sSpriteTemplate_Underscore =
{
.tileTag = 0x000B,
.paletteTag = 0x0003,
@@ -2111,7 +2111,7 @@ static const struct SpriteTemplate sSpriteTemplate_Underscore =
.callback = sub_80E3C6C
};
-static const struct SpriteTemplate gUnknown_0858C180 =
+static const struct SpriteTemplate gUnknown_0858C180 =
{
.tileTag = 0xFFFF,
.paletteTag = 0x0000,
@@ -2122,7 +2122,7 @@ static const struct SpriteTemplate gUnknown_0858C180 =
.callback = SpriteCallbackDummy
};
-static const u8* const gUnknown_0858C198[][4] =
+static const u8* const gUnknown_0858C198[][4] =
{
{
gUnknown_0862B88D,
diff --git a/src/new_game.c b/src/new_game.c
index 89771e92b..37336016e 100644
--- a/src/new_game.c
+++ b/src/new_game.c
@@ -20,8 +20,10 @@
#include "tv.h"
#include "coins.h"
#include "text.h"
+#include "overworld.h"
+#include "mail.h"
+#include "battle_records.h"
-extern u8 gPlayerPartyCount;
extern u8 gDifferentSaveFile;
extern u16 gSaveFileStatus;
extern u8 gUnknown_030060B0;
@@ -29,19 +31,15 @@ extern u8 gUnknown_030060B0;
// TODO: replace those declarations with file headers
extern u16 GetGeneratedTrainerIdLower(void);
extern void ClearContestWinnerPicsInContestHall(void);
-extern void Overworld_SetWarpDestination(s8 mapBank, s8 mapNo, s8 warpNo, s8 xPos, s8 yPos);
extern void warp_in(void);
extern void sub_80BB358(void);
extern void ResetBagScrollPositions(void);
extern void ResetPokedex(void);
extern void sub_8084400(void);
-extern void ClearMailData(void);
extern void ResetGabbyAndTy(void);
extern void ResetSecretBases(void);
extern void ResetLinkContestBoolean(void);
-extern void ResetGameStats(void);
extern void sub_8052DA8(void);
-extern void InitLinkBattleRecords(void);
extern void ResetPokemonStorageSystem(void);
extern void ClearBag(void);
extern void NewGameInitPCItems(void);
@@ -58,7 +56,7 @@ extern void ResetContestLinkResults(void);
extern void ResetPokeJumpResults(void);
extern void SetBerryPowder(u32* powder, u32 newValue);
-extern u8 EventScript_2715DE[];
+extern const u8 EventScript_2715DE[];
void WriteUnalignedWord(u32 var, u8 *dataPtr)
{
@@ -178,7 +176,7 @@ void NewGameInitData(void)
ResetLinkContestBoolean();
ResetGameStats();
ClearAllContestWinnerPics();
- InitLinkBattleRecords();
+ ClearPlayerLinkBattleRecords();
InitSeedotSizeRecord();
InitLotadSizeRecord();
gPlayerPartyCount = 0;
diff --git a/src/option_menu.c b/src/option_menu.c
index cbbe14b77..de9a216a6 100644
--- a/src/option_menu.c
+++ b/src/option_menu.c
@@ -146,23 +146,7 @@ void CB2_InitOptionMenu(void)
gMain.state++;
break;
case 1:
- {
- u8 *addr;
- u32 size;
-
- addr = (u8 *)VRAM;
- size = 0x18000;
- while (1)
- {
- DmaFill16(3, 0, addr, 0x1000);
- addr += 0x1000;
- size -= 0x1000;
- if (size <= 0x1000)
- {
- DmaFill16(3, 0, addr, size);
- break;
- }
- }
+ DmaClearLarge16(3, (void*)(VRAM), VRAM_SIZE, 0x1000);
DmaClear32(3, OAM, OAM_SIZE);
DmaClear16(3, PLTT, PLTT_SIZE);
SetGpuReg(REG_OFFSET_DISPCNT, 0);
@@ -189,7 +173,6 @@ void CB2_InitOptionMenu(void)
ShowBg(0);
ShowBg(1);
gMain.state++;
- }
break;
case 2:
ResetPaletteFade();
diff --git a/src/overworld.c b/src/overworld.c
index c538595f2..3d9a1bdc2 100644
--- a/src/overworld.c
+++ b/src/overworld.c
@@ -1,19 +1,3181 @@
-
-// Includes
#include "global.h"
+#include "overworld.h"
+#include "main.h"
+#include "battle_setup.h"
+#include "berry.h"
+// #include "cable_club.h"
+#include "clock.h"
+#include "event_data.h"
+#include "field_camera.h"
+#include "field_control_avatar.h"
+#include "field_effect.h"
+#include "field_fadetransition.h"
+#include "field_ground_effect.h"
+#include "field_map_obj.h"
+#include "field_map_obj_helpers.h"
+#include "field_message_box.h"
+#include "field_player_avatar.h"
+#include "field_screen_effect.h"
+// #include "field_special_scene.h"
+#include "field_specials.h"
+#include "field_tasks.h"
+#include "field_weather.h"
+#include "fieldmap.h"
+// #include "fldeff_flash.h"
+#include "heal_location.h"
+#include "link.h"
+#include "load_save.h"
+#include "main.h"
+#include "m4a.h"
+#include "constants/maps.h"
+#include "map_name_popup.h"
+#include "menu.h"
+#include "metatile_behavior.h"
+#include "new_game.h"
+#include "palette.h"
+#include "play_time.h"
+#include "random.h"
+#include "roamer.h"
+// #include "rotating_gate.h"
+#include "safari_zone.h"
+#include "save.h"
+#include "script.h"
+// #include "script_pokemon_80C4.h"
+#include "secret_base.h"
+#include "constants/songs.h"
+#include "sound.h"
+#include "constants/species.h"
+#include "start_menu.h"
+#include "task.h"
+// #include "tileset_anim.h"
+#include "time_events.h"
+#include "tv.h"
+#include "scanline_effect.h"
+#include "wild_encounter.h"
+#include "bg.h"
+#include "money.h"
+#include "save_location.h"
+#include "constants/abilities.h"
+#include "malloc.h"
+#include "gpu_regs.h"
+#include "link_rfu.h"
+
+// event scripts
+extern const u8 EventScript_WhiteOut[];
+extern const u8 EventScript_271862[];
+extern const u8 EventScript_277513[];
+extern const u8 EventScript_TradeRoom_TooBusyToNotice[];
+extern const u8 EventScript_TradeRoom_ReadTrainerCard1[];
+extern const u8 EventScript_TradeRoom_ReadTrainerCard2[];
+extern const u8 gUnknown_08277388[];
+extern const u8 gUnknown_082773A3[];
+extern const u8 gUnknown_082773BE[];
+extern const u8 gUnknown_082773D9[];
+extern const u8 gUnknown_0827741D[];
+extern const u8 gUnknown_08277432[];
+extern const u8 gUnknown_08277447[];
+extern const u8 gUnknown_0827745C[];
+extern const u8 gUnknown_08277374[];
+extern const u8 gUnknown_0827737E[];
+extern const u8 gUnknown_082773FF[];
+extern const u8 gUnknown_082773F5[];
+extern const u8 gUnknown_082774EF[];
+extern const u8 gUnknown_08277509[];
+
+// vars
+extern const struct MapData *const gMapAttributes[];
+extern const struct MapHeader *const *const gMapGroups[];
+extern const s32 gMaxFlashLevel;
+extern const u16 gUnknown_82EC7C4[];
+
+u16 gUnknown_03005DA8;
+MainCallback gFieldCallback;
+bool8 (*gUnknown_03005DB0)(void);
+u8 gUnknown_03005DB4;
+u8 gFieldLinkPlayerCount;
+
+// functions
+extern void HealPlayerParty(void);
+extern void move_tilemap_camera_to_upper_left_corner(void);
+extern void cur_mapheader_run_tileset_funcs_after_some_cpuset(void);
+extern void DrawWholeMapView(void);
+extern void copy_map_tileset1_tileset2_to_vram(const struct MapData *);
+extern void apply_map_tileset1_tileset2_palette(const struct MapData *);
+extern void ResetCyclingRoadChallengeData(void);
+extern void ApplyNewEncryptionKeyToWord(u32 *word, u32 newKey);
+extern void mapheader_run_script_with_tag_x5(void);
+extern void ResetFieldTasksArgs(void);
+extern void sub_80A0A2C(void);
+extern void not_trainer_hill_battle_pyramid(void);
+extern void apply_map_tileset2_palette(const struct MapData *);
+extern void copy_map_tileset2_to_vram_2(const struct MapData *);
+extern void prev_quest_postbuffer_cursor_backup_reset(void);
+extern void ShowMapNamePopup(void);
+extern bool32 InTrainerHill(void);
+extern bool32 sub_808651C(void);
+extern bool8 sub_80AF6A4(void);
+extern bool8 sub_81A9E6C(void);
+extern bool8 sub_80E909C(void);
+extern void sub_81AA1D8(void);
+extern void c2_change_map(void);
+extern void sub_81D5DF8(void);
+extern void sub_80EB218(void);
+extern void sub_81BE72C(void);
+extern void sub_80AF3C8(void);
+extern void sub_81971F4(void);
+extern void sub_808B578(void);
+extern void sub_80AF314(void);
+extern void sub_80AF214(void);
+extern void sub_80AF188(void);
+extern void door_upload_tiles(void);
+extern void RotatingGate_InitPuzzleAndGraphics(void);
+extern void sub_80AF168(void);
+extern void sub_80AF3C8(void);
+extern void ExecuteTruckSequence(void);
+extern void sub_80A0A38(void);
+extern void trainer_hill_map_load_related(void);
+extern void sub_8087D74(void);
+extern void battle_pyramid_map_load_related(u8);
+extern void sub_80B00E8(u8);
+extern void sub_80E9238(u8);
+extern void sub_81A3908(void);
+extern void sub_81AA2F8(void);
+extern void sub_8195E10(void);
+extern void sub_80EDB44(void);
+extern void sub_81D64C0(void);
+extern void sub_81BE6AC(void);
+extern void sub_8098128(void);
+extern void copy_map_tileset1_to_vram(const struct MapData *);
+extern void copy_map_tileset2_to_vram(const struct MapData *);
+extern void FieldUpdateBgTilemapScroll(void);
+extern void TransferTilesetAnimsBuffer(void);
+extern bool32 sub_81D5F48(void);
+extern u8 GetCurrentTrainerHillMapId(void);
+extern bool8 warp0_in_pokecenter(void);
+extern void dp13_810BB8C(void);
+extern void FieldEffectActiveListClear(void);
+extern void SetUpFieldTasks(void);
+extern void sub_81BE6B8(void);
+extern void sub_80AAFA4(void);
+extern void ShowStartMenu(void);
+extern void sub_80AEE84(void);
+extern void mapldr_default(void);
+extern void npc_paltag_set_load(u8);
+extern void sub_8088B3C(u16, u16);
+extern bool32 sub_800F0B8(void);
+extern bool32 sub_8009F3C(void);
+extern void sub_8010198(void);
+extern u32 sub_800B4DC(void);
+extern bool32 sub_80B39D4(u8);
+extern const u8* sub_809C2C8(struct MapPosition *a1, u8, u8);
+extern u8 *sub_809D0F4(void*);
+extern u8 sub_808BD6C(u8);
+extern u8 sub_808BD7C(u8);
+extern void sub_80979D4(struct Sprite*, u8);
+
+// this file's functions
+static void Overworld_ResetStateAfterWhiteOut(void);
+static void c2_80567AC(void);
+static void CB2_LoadMap2(void);
+static void VBlankCB_Field(void);
+static void SpriteCB_LinkPlayer(struct Sprite *sprite);
+static void ChooseAmbientCrySpecies(void);
+static void do_load_map_stuff_loop(u8 *state);
+static bool32 map_loading_iteration_3(u8 *state);
+static bool32 sub_8086638(u8 *state);
+static bool32 load_map_stuff(u8 *state, u32);
+static bool32 map_loading_iteration_2_link(u8 *state);
+static void mli4_mapscripts_and_other(void);
+static void map_loading_lcd_reset(void);
+static u8 sub_8087858(u8);
+static u16 sub_80871C0(u32 a1);
+static void sub_80867C8(void);
+static void sub_80867D8(void);
+static void sub_8086AE4(void);
+static void sub_80869DC(void);
+static void sub_8086B14(void);
+static void sub_8086AAC(void);
+static void sub_8086988(bool32 arg0);
+static void sub_8086A80(void);
+static void sub_8086A68(void);
+static void sub_8086860(void);
+static void sub_8086AC8(void);
+static void sub_8086B9C(void);
+static void sub_8086C40(void);
+static void sub_8086C90(void);
+static void sub_8086FA0(u16);
+static void sub_8086F38(u16*, s32);
+static u8 npc_something3(u8 a1, u8 a2);
+static u8 LinkPlayerDetectCollision(u8 selfMapObjId, u8 a2, s16 x, s16 y);
+static void CreateLinkPlayerSprite(u8 linkPlayerId, u8 gameVersion);
+static void sub_8087878(u8 linkPlayerId, u16 *x, u16 *y);
+static u8 sub_80878A0(u8 linkPlayerId);
+static u8 sub_80878C0(u8 linkPlayerId);
+static s32 sub_80878E4(u8 linkPlayerId);
+static u8 GetLinkPlayerIdAt(s16 x, s16 y);
+static void sub_808796C(u8 linkPlayerId, u8 a2);
+static void ZeroMapObject(struct MapObject *mapObj);
+static void SpawnLinkPlayerMapObject(u8 linkPlayerId, s16 x, s16 y, u8 a4);
+static void InitLinkPlayerMapObjectPos(struct MapObject *mapObj, s16 x, s16 y);
+static void sub_80877DC(u8 linkPlayerId, u8 a2);
+static void sub_808780C(u8 linkPlayerId);
+static u8 sub_8087858(u8 linkPlayerId);
+static void sub_8087584(void);
+static u32 sub_8087690(void);
+static void ZeroLinkPlayerMapObject(struct LinkPlayerMapObject *linkPlayerMapObj);
+static const u8 *sub_80873B4(struct UnkStruct_8054FF8 *a1);
+static u16 sub_8087480(const u8 *script);
+static void sub_8087510(void);
+static void sub_808751C(void);
+static void sub_8087530(const u8 *script);
+static void sub_808754C(void);
+static void sub_8087568(const u8 *script);
+static void sub_80872D8(s32 linkPlayerId, s32 a2, struct UnkStruct_8054FF8 *a3);
+static bool32 sub_8087340(struct UnkStruct_8054FF8 *a1);
+static bool32 sub_8087358(struct UnkStruct_8054FF8 *a1);
+static u8 *sub_8087370(struct UnkStruct_8054FF8 *a1);
+static bool32 sub_8087388(struct UnkStruct_8054FF8 *a1);
+static const u8 *sub_80873B4(struct UnkStruct_8054FF8 *a1);
+static u16 sub_808711C(u32);
+static u16 sub_8087140(u32);
+static void sub_808709C(u16 *a1);
+static u16 sub_80870B0(u32 a1);
+static u16 sub_80870F8(u32 a1);
+static u16 sub_8087068(u16 a1);
+static void c1_link_related(void);
+static void c1_link_related_func_set(u16 (*func)(u32));
+static void SetFieldVBlankCallback(void);
+static void FieldClearVBlankHBlankCallbacks(void);
+static void sub_8085810(void);
+static u8 sub_808532C(struct UnkPlayerStruct *playerStruct, u16 a2, u8 a3);
+static u8 sub_808538C(struct UnkPlayerStruct *playerStruct, u8 a2, u16 a3, u8 a4);
+static u16 cur_mapdata_block_role_at_screen_center_acc_to_sav1(void);
+
+// IWRAM bss vars
+IWRAM_DATA static void *sUnknown_03000E0C;
+IWRAM_DATA static u8 sUnknown_03000E10[4];
+IWRAM_DATA static u16 (*sUnknown_03000E14)(u32);
+IWRAM_DATA static u8 sUnknown_03000E18;
+IWRAM_DATA static u8 sUnknown_03000E19;
+IWRAM_DATA static u32 sUnusedVar;
+
+// EWRAM vars
+EWRAM_DATA static u8 sUnknown_020322D8 = 0;
+EWRAM_DATA struct WarpData gUnknown_020322DC = {0};
+EWRAM_DATA static struct WarpData sWarpDestination = {0}; // new warp position
+EWRAM_DATA static struct WarpData sUnknown_020322EC = {0};
+EWRAM_DATA static struct WarpData sUnknown_020322F4 = {0};
+EWRAM_DATA static u16 sLastMapSectionId = 0;
+EWRAM_DATA static struct UnkPlayerStruct sUnknown_02032300 = {0};
+EWRAM_DATA static u16 sAmbientCrySpecies = 0;
+EWRAM_DATA static bool8 sIsAmbientCryWaterMon = FALSE;
+EWRAM_DATA struct LinkPlayerMapObject gLinkPlayerMapObjects[4] = {0};
+
+// const rom data
+static const struct WarpData sDummyWarpData =
+{
+ .mapGroup = -1,
+ .mapNum = -1,
+ .warpId = -1,
+ .x = -1,
+ .y = -1,
+};
+
+static const u8 sUnusedData[] =
+{
+ 0xB0, 0x04, 0x00, 0x00,
+ 0x10, 0x0E, 0x00, 0x00,
+ 0xB0, 0x04, 0x00, 0x00,
+ 0x60, 0x09, 0x00, 0x00,
+ 0x32, 0x00, 0x00, 0x00,
+ 0x50, 0x00, 0x00, 0x00,
+ 0xD4, 0xFF, 0xFF, 0xFF,
+ 0x2C, 0x00, 0x00, 0x00,
+};
+
+const struct UCoords32 gUnknown_08339D64[] =
+{
+ { 0, 0},
+ { 0, 1},
+ { 0, -1},
+ {-1, 0},
+ { 1, 0},
+ {-1, 1},
+ { 1, 1},
+ {-1, -1},
+ { 1, -1},
+};
+
+static const struct BgTemplate gUnknown_08339DAC[] =
+{
+ {
+ .bg = 0,
+ .charBaseIndex = 2,
+ .mapBaseIndex = 31,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 0,
+ .baseTile = 0
+ },
+ {
+ .bg = 1,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 29,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 1,
+ .baseTile = 0
+ },
+ {
+ .bg = 2,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 28,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 2,
+ .baseTile = 0
+ },
+ {
+ .bg = 3,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 30,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 3,
+ .baseTile = 0
+ }
+};
+
+static const struct ScanlineEffectParams gUnknown_08339DBC =
+{
+ (void *)REG_ADDR_WIN0H,
+ ((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_DEST_RELOAD) << 16) | 1,
+ 1,
+ 0,
+};
+
+static u8 sub_80879D8(struct LinkPlayerMapObject *, struct MapObject *, u8);
+static u8 sub_80879F8(struct LinkPlayerMapObject *, struct MapObject *, u8);
+static u8 sub_80879FC(struct LinkPlayerMapObject *, struct MapObject *, u8);
+
+static u8 (*const gUnknown_08339DC8[])(struct LinkPlayerMapObject *, struct MapObject *, u8) =
+{
+ sub_80879D8,
+ sub_80879F8,
+ sub_80879FC,
+};
+
+static u8 sub_8087A1C(struct LinkPlayerMapObject *, struct MapObject *, u8);
+static u8 sub_8087A20(struct LinkPlayerMapObject *, struct MapObject *, u8);
+static u8 sub_8087A88(struct LinkPlayerMapObject *, struct MapObject *, u8);
+
+static u8 (*const gUnknown_08339DD4[])(struct LinkPlayerMapObject *, struct MapObject *, u8) =
+{
+ sub_8087A1C,
+ sub_8087A20,
+ sub_8087A20,
+ sub_8087A20,
+ sub_8087A20,
+ sub_8087A1C,
+ sub_8087A1C,
+ sub_8087A88,
+ sub_8087A88,
+ sub_8087A88,
+ sub_8087A88,
+};
+
+static void sub_8087AA0(struct LinkPlayerMapObject *, struct MapObject *);
+static void sub_8087AA8(struct LinkPlayerMapObject *, struct MapObject *);
+
+static void (*const gUnknown_08339E00[])(struct LinkPlayerMapObject *, struct MapObject *) =
+{
+ sub_8087AA0,
+ sub_8087AA8,
+};
+
+// code
+void DoWhiteOut(void)
+{
+ ScriptContext2_RunNewScript(EventScript_WhiteOut);
+ SetMoney(&gSaveBlock1Ptr->money, GetMoney(&gSaveBlock1Ptr->money) / 2);
+ HealPlayerParty();
+ Overworld_ResetStateAfterWhiteOut();
+ Overworld_SetWarpDestToLastHealLoc();
+ warp_in();
+}
+
+void Overworld_ResetStateAfterFly(void)
+{
+ player_avatar_init_params_reset();
+ FlagClear(FLAG_SYS_CYCLING_ROAD);
+ FlagClear(FLAG_SYS_CRUISE_MODE);
+ FlagClear(FLAG_SYS_SAFARI_MODE);
+ FlagClear(FLAG_SYS_USE_STRENGTH);
+ FlagClear(FLAG_SYS_USE_FLASH);
+}
+
+void Overworld_ResetStateAfterTeleport(void)
+{
+ player_avatar_init_params_reset();
+ FlagClear(FLAG_SYS_CYCLING_ROAD);
+ FlagClear(FLAG_SYS_CRUISE_MODE);
+ FlagClear(FLAG_SYS_SAFARI_MODE);
+ FlagClear(FLAG_SYS_USE_STRENGTH);
+ FlagClear(FLAG_SYS_USE_FLASH);
+ ScriptContext2_RunNewScript(EventScript_271862);
+}
+
+void Overworld_ResetStateAfterDigEscRope(void)
+{
+ player_avatar_init_params_reset();
+ FlagClear(FLAG_SYS_CYCLING_ROAD);
+ FlagClear(FLAG_SYS_CRUISE_MODE);
+ FlagClear(FLAG_SYS_SAFARI_MODE);
+ FlagClear(FLAG_SYS_USE_STRENGTH);
+ FlagClear(FLAG_SYS_USE_FLASH);
+}
+
+static void Overworld_ResetStateAfterWhiteOut(void)
+{
+ player_avatar_init_params_reset();
+ FlagClear(FLAG_SYS_CYCLING_ROAD);
+ FlagClear(FLAG_SYS_CRUISE_MODE);
+ FlagClear(FLAG_SYS_SAFARI_MODE);
+ FlagClear(FLAG_SYS_USE_STRENGTH);
+ FlagClear(FLAG_SYS_USE_FLASH);
+ if (VarGet(VAR_0x4039) == 1)
+ {
+ VarSet(VAR_0x4039, 0);
+ VarSet(VAR_0x4037, 0);
+ }
+}
+
+static void sub_8084788(void)
+{
+ FlagClear(FLAG_SYS_SAFARI_MODE);
+ ChooseAmbientCrySpecies();
+ ResetCyclingRoadChallengeData();
+ UpdateLocationHistoryForRoamer();
+ RoamerMoveToOtherLocationSet();
+}
+
+void ResetGameStats(void)
+{
+ s32 i;
+
+ for (i = 0; i < NUM_GAME_STATS; i++)
+ SetGameStat(i, 0);
+}
+
+void IncrementGameStat(u8 index)
+{
+ if (index < NUM_USED_GAME_STATS)
+ {
+ u32 statVal = GetGameStat(index);
+ if (statVal < 0xFFFFFF)
+ statVal++;
+ else
+ statVal = 0xFFFFFF;
+
+ SetGameStat(index, statVal);
+ }
+}
+
+u32 GetGameStat(u8 index)
+{
+ if (index >= NUM_USED_GAME_STATS)
+ return 0;
+
+ return gSaveBlock1Ptr->gameStats[index] ^ gSaveBlock2Ptr->encryptionKey;
+}
+
+void SetGameStat(u8 index, u32 value)
+{
+ if (index < NUM_USED_GAME_STATS)
+ gSaveBlock1Ptr->gameStats[index] = value ^ gSaveBlock2Ptr->encryptionKey;
+}
+
+void ApplyNewEncryptionKeyToGameStats(u32 newKey)
+{
+ u8 i;
+
+ for (i = 0; i < NUM_GAME_STATS; i++)
+ ApplyNewEncryptionKeyToWord(&gSaveBlock1Ptr->gameStats[i], newKey);
+}
+
+void LoadMapObjTemplatesFromHeader(void)
+{
+ // Clear map object templates
+ CpuFill32(0, gSaveBlock1Ptr->mapObjectTemplates, sizeof(gSaveBlock1Ptr->mapObjectTemplates));
+
+ // Copy map header events to save block
+ CpuCopy32(gMapHeader.events->mapObjects,
+ gSaveBlock1Ptr->mapObjectTemplates,
+ gMapHeader.events->mapObjectCount * sizeof(struct MapObjectTemplate));
+}
+
+void LoadSaveblockMapObjScripts(void)
+{
+ struct MapObjectTemplate *mapHeaderObjTemplates = gMapHeader.events->mapObjects;
+ struct MapObjectTemplate *savObjTemplates = gSaveBlock1Ptr->mapObjectTemplates;
+ s32 i;
+
+ for (i = 0; i < 64; i++)
+ savObjTemplates[i].script = mapHeaderObjTemplates[i].script;
+}
+
+void Overworld_SetMapObjTemplateCoords(u8 localId, s16 x, s16 y)
+{
+ s32 i;
+ struct MapObjectTemplate *savObjTemplates = gSaveBlock1Ptr->mapObjectTemplates;
+
+ for (i = 0; i < 64; i++)
+ {
+ struct MapObjectTemplate *mapObjectTemplate = &savObjTemplates[i];
+ if (mapObjectTemplate->localId == localId)
+ {
+ mapObjectTemplate->x = x;
+ mapObjectTemplate->y = y;
+ return;
+ }
+ }
+}
+
+void Overworld_SetMapObjTemplateMovementType(u8 localId, u8 movementType)
+{
+ s32 i;
+
+ struct MapObjectTemplate *savObjTemplates = gSaveBlock1Ptr->mapObjectTemplates;
+ for (i = 0; i < 64; i++)
+ {
+ struct MapObjectTemplate *mapObjectTemplate = &savObjTemplates[i];
+ if (mapObjectTemplate->localId == localId)
+ {
+ mapObjectTemplate->movementType = movementType;
+ return;
+ }
+ }
+}
+
+static void mapdata_load_assets_to_gpu_and_full_redraw(void)
+{
+ move_tilemap_camera_to_upper_left_corner();
+ copy_map_tileset1_tileset2_to_vram(gMapHeader.mapData);
+ apply_map_tileset1_tileset2_palette(gMapHeader.mapData);
+ DrawWholeMapView();
+ cur_mapheader_run_tileset_funcs_after_some_cpuset();
+}
+
+const struct MapData *get_mapdata_header(void)
+{
+ u16 mapDataId = gSaveBlock1Ptr->mapDataId;
+ if (mapDataId)
+ return gMapAttributes[mapDataId - 1];
+ return NULL;
+}
+
+void ApplyCurrentWarp(void)
+{
+ gUnknown_020322DC = gSaveBlock1Ptr->location;
+ gSaveBlock1Ptr->location = sWarpDestination;
+ sUnknown_020322EC = sDummyWarpData;
+ sUnknown_020322F4 = sDummyWarpData;
+}
+
+void set_warp2_warp3_to_neg_1(void)
+{
+ sUnknown_020322EC = sDummyWarpData;
+ sUnknown_020322F4 = sDummyWarpData;
+}
+
+void SetWarpData(struct WarpData *warp, s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
+{
+ warp->mapGroup = mapGroup;
+ warp->mapNum = mapNum;
+ warp->warpId = warpId;
+ warp->x = x;
+ warp->y = y;
+}
+
+bool32 warp_data_is_not_neg_1(struct WarpData *warp)
+{
+ if (warp->mapGroup != -1)
+ return FALSE;
+ else if (warp->mapNum != -1)
+ return FALSE;
+ else if (warp->warpId != -1)
+ return FALSE;
+ else if (warp->x != -1)
+ return FALSE;
+ else if (warp->y != -1)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+struct MapHeader const *const Overworld_GetMapHeaderByGroupAndId(u16 mapGroup, u16 mapNum)
+{
+ return gMapGroups[mapGroup][mapNum];
+}
+
+struct MapHeader const *const warp1_get_mapheader(void)
+{
+ return Overworld_GetMapHeaderByGroupAndId(sWarpDestination.mapGroup, sWarpDestination.mapNum);
+}
+
+void set_current_map_header_from_sav1_save_old_name(void)
+{
+ sLastMapSectionId = gMapHeader.regionMapSectionId;
+ gMapHeader = *Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum);
+ gSaveBlock1Ptr->mapDataId = gMapHeader.mapDataId;
+ gMapHeader.mapData = get_mapdata_header();
+}
+
+void LoadSaveblockMapHeader(void)
+{
+ gMapHeader = *Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum);
+ gMapHeader.mapData = get_mapdata_header();
+}
+
+void update_camera_pos_from_warpid(void)
+{
+ if (gSaveBlock1Ptr->location.warpId >= 0 && gSaveBlock1Ptr->location.warpId < gMapHeader.events->warpCount)
+ {
+ gSaveBlock1Ptr->pos.x = gMapHeader.events->warps[gSaveBlock1Ptr->location.warpId].x;
+ gSaveBlock1Ptr->pos.y = gMapHeader.events->warps[gSaveBlock1Ptr->location.warpId].y;
+ }
+ else if (gSaveBlock1Ptr->location.x >= 0 && gSaveBlock1Ptr->location.y >= 0)
+ {
+ gSaveBlock1Ptr->pos.x = gSaveBlock1Ptr->location.x;
+ gSaveBlock1Ptr->pos.y = gSaveBlock1Ptr->location.y;
+ }
+ else
+ {
+ gSaveBlock1Ptr->pos.x = gMapHeader.mapData->width / 2;
+ gSaveBlock1Ptr->pos.y = gMapHeader.mapData->height / 2;
+ }
+}
+
+void warp_in(void)
+{
+ ApplyCurrentWarp();
+ set_current_map_header_from_sav1_save_old_name();
+ update_camera_pos_from_warpid();
+}
+
+void Overworld_SetWarpDestination(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
+{
+ SetWarpData(&sWarpDestination, mapGroup, mapNum, warpId, x, y);
+}
+
+void warp1_set_2(s8 mapGroup, s8 mapNum, s8 warpId)
+{
+ Overworld_SetWarpDestination(mapGroup, mapNum, warpId, -1, -1);
+}
+
+void saved_warp2_set(s32 unused, s8 mapGroup, s8 mapNum, s8 warpId)
+{
+ SetWarpData(&gSaveBlock1Ptr->warp2, mapGroup, mapNum, warpId, gSaveBlock1Ptr->pos.x, gSaveBlock1Ptr->pos.y);
+}
+
+void saved_warp2_set_2(s32 unused, s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
+{
+ SetWarpData(&gSaveBlock1Ptr->warp2, mapGroup, mapNum, warpId, x, y);
+}
+
+void copy_saved_warp2_bank_and_enter_x_to_warp1(u8 unused)
+{
+ sWarpDestination = gSaveBlock1Ptr->warp2;
+}
+
+void sub_8084CCC(u8 a1)
+{
+ const struct HealLocation *warp = GetHealLocationPointer(a1);
+
+ if (warp)
+ Overworld_SetWarpDestination(warp->group, warp->map, -1, warp->x, warp->y);
+}
+
+void Overworld_SetWarpDestToLastHealLoc(void)
+{
+ sWarpDestination = gSaveBlock1Ptr->lastHealLocation;
+}
+
+void Overworld_SetHealLocationWarp(u8 healLocationId)
+{
+ const struct HealLocation *healLocation = GetHealLocationPointer(healLocationId);
+
+ if (healLocation != NULL)
+ SetWarpData(&gSaveBlock1Ptr->lastHealLocation, healLocation->group, healLocation->map, -1, healLocation->x, healLocation->y);
+}
+
+void sub_8084D5C(s16 a1, s16 a2)
+{
+ u8 currMapType = Overworld_GetMapTypeOfSaveblockLocation();
+ u8 destMapType = GetMapTypeByGroupAndId(sWarpDestination.mapGroup, sWarpDestination.mapNum);
+ if (is_map_type_1_2_3_5_or_6(currMapType) && is_map_type_1_2_3_5_or_6(destMapType) != TRUE)
+ sub_8084DD4(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, -1, a1 - 7, a2 - 6);
+}
+
+void sub_8084DD4(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
+{
+ SetWarpData(&gSaveBlock1Ptr->warp4, mapGroup, mapNum, warpId, x, y);
+}
+
+void sub_8084E14(void)
+{
+ sWarpDestination = gSaveBlock1Ptr->warp4;
+}
+
+void sub_8084E2C(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
+{
+ SetWarpData(&sUnknown_020322EC, mapGroup, mapNum, warpId, x, y);
+}
+
+void warp1_set_to_warp2(void)
+{
+ sWarpDestination = sUnknown_020322EC;
+}
+
+void sub_8084E80(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
+{
+ SetWarpData(&sUnknown_020322F4, mapGroup, mapNum, warpId, x, y);
+}
+
+void sub_8084EBC(s16 x, s16 y)
+{
+ if (warp_data_is_not_neg_1(&sUnknown_020322F4) == TRUE)
+ sWarpDestination = gUnknown_020322DC;
+ else
+ Overworld_SetWarpDestination(sUnknown_020322F4.mapGroup, sUnknown_020322F4.mapNum, -1, x, y);
+}
+
+void warp1_set_to_sav1w(void)
+{
+ sWarpDestination = gSaveBlock1Ptr->warp1;
+}
+
+void sub_8084F2C(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
+{
+ SetWarpData(&gSaveBlock1Ptr->warp1, mapGroup, mapNum, warpId, x, y);
+}
+
+void sub_8084F6C(u8 a1)
+{
+ const struct HealLocation *warp = GetHealLocationPointer(a1);
+ if (warp)
+ SetWarpData(&gSaveBlock1Ptr->warp1, warp->group, warp->map, -1, warp->x, warp->y);
+}
+
+void sub_8084FAC(void)
+{
+ gSaveBlock1Ptr->warp1 = gSaveBlock1Ptr->warp2;
+}
+
+const struct MapConnection *GetMapConnection(u8 dir)
+{
+ s32 i;
+ s32 count = gMapHeader.connections->count;
+ const struct MapConnection *connection = gMapHeader.connections->connections;
+
+ if (connection == NULL)
+ return NULL;
+
+ for(i = 0; i < count; i++, connection++)
+ if (connection->direction == dir)
+ return connection;
+
+ return NULL;
+}
+
+bool8 sub_8084FF8(u8 dir, u16 x, u16 y)
+{
+ const struct MapConnection *connection = GetMapConnection(dir);
+
+ if (connection != NULL)
+ {
+ Overworld_SetWarpDestination(connection->mapGroup, connection->mapNum, -1, x, y);
+ }
+ else
+ {
+ mapheader_run_script_with_tag_x6();
+ if (warp_data_is_not_neg_1(&sUnknown_020322EC))
+ return FALSE;
+ warp1_set_to_warp2();
+ }
+ return TRUE;
+}
+
+bool8 sub_8085058(u16 x, u16 y)
+{
+ return sub_8084FF8(CONNECTION_EMERGE, x, y);
+}
+
+bool8 sub_8085078(u16 x, u16 y)
+{
+ return sub_8084FF8(CONNECTION_DIVE, x, y);
+}
+
+void mliX_load_map(u8 mapGroup, u8 mapNum)
+{
+ s32 paletteIndex;
+
+ Overworld_SetWarpDestination(mapGroup, mapNum, -1, -1, -1);
+ if (gMapHeader.regionMapSectionId != 0x3A)
+ sub_8085810();
+
+ ApplyCurrentWarp();
+ set_current_map_header_from_sav1_save_old_name();
+ LoadMapObjTemplatesFromHeader();
+ TrySetMapSaveWarpStatus();
+ ClearTempFieldEventData();
+ ResetCyclingRoadChallengeData();
+ prev_quest_postbuffer_cursor_backup_reset();
+ TryUpdateRandomTrainerRematches(mapGroup, mapNum);
+ DoTimeBasedEvents();
+ SetSav1WeatherFromCurrMapHeader();
+ ChooseAmbientCrySpecies();
+ SetDefaultFlashLevel();
+ Overworld_ClearSavedMusic();
+ mapheader_run_script_with_tag_x3();
+ not_trainer_hill_battle_pyramid();
+ copy_map_tileset2_to_vram_2(gMapHeader.mapData);
+ apply_map_tileset2_palette(gMapHeader.mapData);
+
+ for (paletteIndex = 6; paletteIndex < 13; paletteIndex++)
+ ApplyWeatherGammaShiftToPal(paletteIndex);
+
+ sub_80A0A2C();
+ UpdateLocationHistoryForRoamer();
+ RoamerMove();
+ DoCurrentWeather();
+ ResetFieldTasksArgs();
+ mapheader_run_script_with_tag_x5();
+
+ if (gMapHeader.regionMapSectionId != 0x3A || gMapHeader.regionMapSectionId != sLastMapSectionId)
+ ShowMapNamePopup();
+}
+
+static void mli0_load_map(u32 a1)
+{
+ bool8 v2;
+ bool8 indoors;
+
+ set_current_map_header_from_sav1_save_old_name();
+ if (!(sUnknown_020322D8 & 1))
+ {
+ if (gMapHeader.mapDataId == 0x169)
+ sub_81AA1D8();
+ else if (InTrainerHill())
+ sub_81D5DF8();
+ else
+ LoadMapObjTemplatesFromHeader();
+ }
+
+ v2 = is_map_type_1_2_3_5_or_6(gMapHeader.mapType);
+ indoors = Overworld_MapTypeIsIndoors(gMapHeader.mapType);
+
+ sub_80EB218();
+ TrySetMapSaveWarpStatus();
+ ClearTempFieldEventData();
+ ResetCyclingRoadChallengeData();
+ prev_quest_postbuffer_cursor_backup_reset();
+ TryUpdateRandomTrainerRematches(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum);
+ if (a1 != 1)
+ DoTimeBasedEvents();
+ SetSav1WeatherFromCurrMapHeader();
+ ChooseAmbientCrySpecies();
+ if (v2)
+ FlagClear(FLAG_SYS_USE_FLASH);
+ SetDefaultFlashLevel();
+ Overworld_ClearSavedMusic();
+ mapheader_run_script_with_tag_x3();
+ UpdateLocationHistoryForRoamer();
+ RoamerMoveToOtherLocationSet();
+ if (gMapHeader.mapDataId == 0x169)
+ battle_pyramid_map_load_related(0);
+ else if (InTrainerHill())
+ trainer_hill_map_load_related();
+ else
+ not_trainer_hill_battle_pyramid();
+
+ if (a1 != 1 && indoors)
+ {
+ UpdateTVScreensOnMap(gUnknown_03005DC0.width, gUnknown_03005DC0.height);
+ sub_80E9238(1);
+ }
+}
+
+void player_avatar_init_params_reset(void)
+{
+ sUnknown_02032300.player_field_1 = 1;
+ sUnknown_02032300.player_field_0 = 1;
+}
+
+void walkrun_find_lowest_active_bit_in_bitfield(void)
+{
+ sUnknown_02032300.player_field_1 = player_get_direction_lower_nybble();
+
+ if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE))
+ sUnknown_02032300.player_field_0 = 2;
+ else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_ACRO_BIKE))
+ sUnknown_02032300.player_field_0 = 4;
+ else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING))
+ sUnknown_02032300.player_field_0 = 8;
+ else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_4))
+ sUnknown_02032300.player_field_0 = 16;
+ else
+ sUnknown_02032300.player_field_0 = 1;
+}
+
+static struct UnkPlayerStruct *sub_80852D4(void)
+{
+ struct UnkPlayerStruct playerStruct;
+ u8 mapType = Overworld_GetMapTypeOfSaveblockLocation();
+ u16 v2 = cur_mapdata_block_role_at_screen_center_acc_to_sav1();
+ u8 v4 = sub_808532C(&sUnknown_02032300, v2, mapType);
+ playerStruct.player_field_0 = v4;
+ playerStruct.player_field_1 = sub_808538C(&sUnknown_02032300, v4, v2, mapType);
+ sUnknown_02032300 = playerStruct;
+ return &sUnknown_02032300;
+}
+
+static u8 sub_808532C(struct UnkPlayerStruct *playerStruct, u16 a2, u8 a3)
+{
+ if (a3 != 8 && FlagGet(FLAG_SYS_CRUISE_MODE))
+ return 1;
+ else if (a3 == 5)
+ return 16;
+ else if (MetatileBehavior_IsSurfableWaterOrUnderwater(a2) == 1)
+ return 8;
+ else if (Overworld_IsBikingAllowed() != TRUE)
+ return 1;
+ else if (playerStruct->player_field_0 == 2)
+ return 2;
+ else if (playerStruct->player_field_0 != 4)
+ return 1;
+ else
+ return 4;
+}
+
+static u8 sub_808538C(struct UnkPlayerStruct *playerStruct, u8 a2, u16 a3, u8 a4)
+{
+ if (FlagGet(FLAG_SYS_CRUISE_MODE) && a4 == 6)
+ return 4;
+ else if (MetatileBehavior_IsDeepSouthWarp(a3) == TRUE)
+ return 2;
+ else if (MetatileBehavior_IsNonAnimDoor(a3) == TRUE || MetatileBehavior_IsDoor(a3) == TRUE)
+ return 1;
+ else if (MetatileBehavior_IsSouthArrowWarp(a3) == TRUE)
+ return 2;
+ else if (MetatileBehavior_IsNorthArrowWarp(a3) == TRUE)
+ return 1;
+ else if (MetatileBehavior_IsWestArrowWarp(a3) == TRUE)
+ return 4;
+ else if (MetatileBehavior_IsEastArrowWarp(a3) == TRUE)
+ return 3;
+ else if ((playerStruct->player_field_0 == 16 && a2 == 8)
+ || (playerStruct->player_field_0 == 8 && a2 == 16))
+ return playerStruct->player_field_1;
+ else if (MetatileBehavior_IsLadder(a3) == TRUE)
+ return playerStruct->player_field_1;
+ else
+ return 1;
+}
+
+static u16 cur_mapdata_block_role_at_screen_center_acc_to_sav1(void)
+{
+ return MapGridGetMetatileBehaviorAt(gSaveBlock1Ptr->pos.x + 7, gSaveBlock1Ptr->pos.y + 7);
+}
+
+bool32 Overworld_IsBikingAllowed(void)
+{
+ if (!(gMapHeader.flags & 1))
+ return FALSE;
+ else
+ return TRUE;
+}
+
+void SetDefaultFlashLevel(void)
+{
+ if (!gMapHeader.cave)
+ gSaveBlock1Ptr->flashLevel = 0;
+ else if (FlagGet(FLAG_SYS_USE_FLASH))
+ gSaveBlock1Ptr->flashLevel = 1;
+ else
+ gSaveBlock1Ptr->flashLevel = gMaxFlashLevel - 1;
+}
+
+void Overworld_SetFlashLevel(s32 flashLevel)
+{
+ if (flashLevel < 0 || flashLevel > gMaxFlashLevel)
+ flashLevel = 0;
+ gSaveBlock1Ptr->flashLevel = flashLevel;
+}
+
+u8 Overworld_GetFlashLevel(void)
+{
+ return gSaveBlock1Ptr->flashLevel;
+}
+
+void sub_8085524(u16 mapDataId)
+{
+ gSaveBlock1Ptr->mapDataId = mapDataId;
+ gMapHeader.mapData = get_mapdata_header();
+}
+
+void sub_8085540(u8 var)
+{
+ sUnknown_020322D8 = var;
+}
+
+u8 sub_808554C(void)
+{
+ return sUnknown_020322D8;
+}
+
+static bool16 ShouldLegendaryMusicPlayAtLocation(struct WarpData *warp)
+{
+ if (!FlagGet(FLAG_SYS_WEATHER_CTRL))
+ return FALSE;
+ if (warp->mapGroup == 0)
+ {
+ switch (warp->mapNum)
+ {
+ case MAP_NUM(LILYCOVE_CITY):
+ case MAP_NUM(MOSSDEEP_CITY):
+ case MAP_NUM(SOOTOPOLIS_CITY):
+ case MAP_NUM(EVER_GRANDE_CITY):
+ case MAP_NUM(ROUTE124):
+ case MAP_NUM(ROUTE125):
+ case MAP_NUM(ROUTE126):
+ case MAP_NUM(ROUTE127):
+ case MAP_NUM(ROUTE128):
+ return TRUE;
+ default:
+ if (VarGet(VAR_0x405E) < 4)
+ return FALSE;
+ switch (warp->mapNum)
+ {
+ case MAP_NUM(ROUTE129):
+ case MAP_NUM(ROUTE130):
+ case MAP_NUM(ROUTE131):
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+static bool16 NoMusicInSotopolisWithLegendaries(struct WarpData *warp)
+{
+ if (VarGet(VAR_0x40CA) != 1)
+ return FALSE;
+ else if (warp->mapGroup != MAP_GROUP(SOOTOPOLIS_CITY))
+ return FALSE;
+ else if (warp->mapNum == MAP_NUM(SOOTOPOLIS_CITY))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static bool16 IsInfiltratedWeatherInstitute(struct WarpData *warp)
+{
+ if (VarGet(VAR_WEATHER_INSTITUTE_STATE))
+ return FALSE;
+ else if (warp->mapGroup != MAP_GROUP(ROUTE119_WEATHER_INSTITUTE_1F))
+ return FALSE;
+ else if (warp->mapNum == MAP_NUM(ROUTE119_WEATHER_INSTITUTE_1F)
+ || warp->mapNum == MAP_NUM(ROUTE119_WEATHER_INSTITUTE_2F))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static bool16 IsInflitratedSpaceCenter(struct WarpData *warp)
+{
+ if (VarGet(VAR_0x405D) == 0)
+ return FALSE;
+ else if (VarGet(VAR_0x405D) > 2)
+ return FALSE;
+ else if (warp->mapGroup != MAP_GROUP(MOSSDEEP_CITY_SPACE_CENTER_1F))
+ return FALSE;
+ else if (warp->mapNum == MAP_NUM(MOSSDEEP_CITY_SPACE_CENTER_1F)
+ || warp->mapNum == MAP_NUM(MOSSDEEP_CITY_SPACE_CENTER_2F))
+ return TRUE;
+ return FALSE;
+}
+
+u16 GetLocationMusic(struct WarpData *warp)
+{
+ if (NoMusicInSotopolisWithLegendaries(warp) == TRUE)
+ return 0xFFFF;
+ else if (ShouldLegendaryMusicPlayAtLocation(warp) == TRUE)
+ return MUS_OOAME;
+ else if (IsInflitratedSpaceCenter(warp) == TRUE)
+ return MUS_MGM0;
+ else if (IsInfiltratedWeatherInstitute(warp) == TRUE)
+ return MUS_TOZAN;
+ else
+ return Overworld_GetMapHeaderByGroupAndId(warp->mapGroup, warp->mapNum)->music;
+}
+
+u16 GetCurrLocationDefaultMusic(void)
+{
+ u16 music;
+
+ // Play the desert music only when the sandstorm is active on Route 111.
+ if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(ROUTE111)
+ && gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE111)
+ && GetSav1Weather() == 8)
+ return MUS_ASHROAD;
+
+ music = GetLocationMusic(&gSaveBlock1Ptr->location);
+ if (music != 0x7FFF)
+ {
+ return music;
+ }
+ else
+ {
+ if (gSaveBlock1Ptr->pos.x < 24)
+ return MUS_DOORO_X1;
+ else
+ return MUS_GRANROAD;
+ }
+}
+
+u16 GetWarpDestinationMusic(void)
+{
+ u16 music = GetLocationMusic(&sWarpDestination);
+ if (music != 0x7FFF)
+ {
+ return music;
+ }
+ else
+ {
+ if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(MAUVILLE_CITY)
+ && gSaveBlock1Ptr->location.mapNum == MAP_NUM(MAUVILLE_CITY))
+ return MUS_DOORO_X1;
+ else
+ return MUS_GRANROAD;
+ }
+}
+
+void Overworld_ResetMapMusic(void)
+{
+ ResetMapMusic();
+}
+
+void Overworld_PlaySpecialMapMusic(void)
+{
+ u16 music = GetCurrLocationDefaultMusic();
+
+ if (music != MUS_OOAME && music != 0xFFFF)
+ {
+ if (gSaveBlock1Ptr->savedMusic)
+ music = gSaveBlock1Ptr->savedMusic;
+ else if (Overworld_GetMapTypeOfSaveblockLocation() == MAP_TYPE_UNDERWATER)
+ music = MUS_DEEPDEEP;
+ else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING))
+ music = MUS_NAMINORI;
+ }
+
+ if (music != GetCurrentMapMusic())
+ PlayNewMapMusic(music);
+}
+
+void Overworld_SetSavedMusic(u16 songNum)
+{
+ gSaveBlock1Ptr->savedMusic = songNum;
+}
+
+void Overworld_ClearSavedMusic(void)
+{
+ gSaveBlock1Ptr->savedMusic = 0;
+}
+
+static void sub_8085810(void)
+{
+ if (FlagGet(FLAG_SPECIAL_FLAG_0x4001) != TRUE)
+ {
+ u16 newMusic = GetWarpDestinationMusic();
+ u16 currentMusic = GetCurrentMapMusic();
+ if (newMusic != MUS_OOAME && newMusic != 0xFFFF)
+ {
+ if (currentMusic == MUS_DEEPDEEP || currentMusic == MUS_NAMINORI)
+ return;
+ if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING))
+ newMusic = MUS_NAMINORI;
+ }
+ if (newMusic != currentMusic)
+ {
+ if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE))
+ FadeOutAndFadeInNewMapMusic(newMusic, 4, 4);
+ else
+ FadeOutAndPlayNewMapMusic(newMusic, 8);
+ }
+ }
+}
+
+void Overworld_ChangeMusicToDefault(void)
+{
+ u16 currentMusic = GetCurrentMapMusic();
+ if (currentMusic != GetCurrLocationDefaultMusic())
+ FadeOutAndPlayNewMapMusic(GetCurrLocationDefaultMusic(), 8);
+}
+
+void Overworld_ChangeMusicTo(u16 newMusic)
+{
+ u16 currentMusic = GetCurrentMapMusic();
+ if (currentMusic != newMusic && currentMusic != MUS_OOAME)
+ FadeOutAndPlayNewMapMusic(newMusic, 8);
+}
+
+u8 GetMapMusicFadeoutSpeed(void)
+{
+ const struct MapHeader *mapHeader = warp1_get_mapheader();
+ if (Overworld_MapTypeIsIndoors(mapHeader->mapType) == TRUE)
+ return 2;
+ else
+ return 4;
+}
+
+void music_something(void)
+{
+ u16 currentMusic = GetCurrentMapMusic();
+ u16 warpMusic = GetWarpDestinationMusic();
+ if (FlagGet(FLAG_SPECIAL_FLAG_0x4001) != TRUE && warpMusic != GetCurrentMapMusic())
+ {
+ if (currentMusic == MUS_NAMINORI
+ && VarGet(VAR_0x40CA) == 2
+ && gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(SOOTOPOLIS_CITY)
+ && gSaveBlock1Ptr->location.mapNum == MAP_NUM(SOOTOPOLIS_CITY)
+ && sWarpDestination.mapGroup == MAP_GROUP(SOOTOPOLIS_CITY)
+ && sWarpDestination.mapNum == MAP_NUM(SOOTOPOLIS_CITY)
+ && sWarpDestination.x == 0x1D
+ && sWarpDestination.y == 0x35)
+ return;
+ FadeOutMapMusic(GetMapMusicFadeoutSpeed());
+ }
+}
+
+bool8 sub_80859A0(void)
+{
+ return IsNotWaitingForBGMStop();
+}
+
+void Overworld_FadeOutMapMusic(void)
+{
+ FadeOutMapMusic(4);
+}
+
+static void PlayAmbientCry(void)
+{
+ s16 x, y;
+ s8 pan;
+ s8 volume;
+
+ PlayerGetDestCoords(&x, &y);
+ if (sIsAmbientCryWaterMon == TRUE
+ && !MetatileBehavior_IsSurfableWaterOrUnderwater(MapGridGetMetatileBehaviorAt(x, y)))
+ return;
+ pan = (Random() % 88) + 212;
+ volume = (Random() % 30) + 50;
+ PlayCry2(sAmbientCrySpecies, pan, volume, 1);
+}
+
+void UpdateAmbientCry(s16 *state, u16 *delayCounter)
+{
+ u8 i, monsCount, divBy;
+
+ switch (*state)
+ {
+ case 0:
+ if (sAmbientCrySpecies == SPECIES_NONE)
+ *state = 4;
+ else
+ *state = 1;
+ break;
+ case 1:
+ *delayCounter = (Random() % 2400) + 1200;
+ *state = 3;
+ break;
+ case 2:
+ divBy = 1;
+ monsCount = CalculatePlayerPartyCount();
+ for (i = 0; i < monsCount; i++)
+ {
+ if (!GetMonData(&gPlayerParty[i], MON_DATA_SANITY_BIT3)
+ && GetMonAbility(&gPlayerParty[0]) == ABILITY_SWARM)
+ {
+ divBy = 2;
+ break;
+ }
+ }
+ *delayCounter = ((Random() % 1200) + 1200) / divBy;
+ *state = 3;
+ break;
+ case 3:
+ (*delayCounter)--;
+ if (*delayCounter == 0)
+ {
+ PlayAmbientCry();
+ *state = 2;
+ }
+ break;
+ case 4:
+ break;
+ }
+}
+
+static void ChooseAmbientCrySpecies(void)
+{
+ if ((gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(ROUTE130)
+ && gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE130))
+ && !IsMirageIslandPresent())
+ {
+ // Only play water pokemon cries on this route
+ // when Mirage Island is not present
+ sIsAmbientCryWaterMon = TRUE;
+ sAmbientCrySpecies = GetLocalWaterMon();
+ }
+ else
+ {
+ sAmbientCrySpecies = GetLocalWildMon(&sIsAmbientCryWaterMon);
+ }
+}
+
+u8 GetMapTypeByGroupAndId(s8 mapGroup, s8 mapNum)
+{
+ return Overworld_GetMapHeaderByGroupAndId(mapGroup, mapNum)->mapType;
+}
+
+u8 GetMapTypeByWarpData(struct WarpData *warp)
+{
+ return GetMapTypeByGroupAndId(warp->mapGroup, warp->mapNum);
+}
+
+u8 Overworld_GetMapTypeOfSaveblockLocation(void)
+{
+ return GetMapTypeByWarpData(&gSaveBlock1Ptr->location);
+}
+
+u8 get_map_light_from_warp0(void)
+{
+ return GetMapTypeByWarpData(&gUnknown_020322DC);
+}
+
+bool8 is_map_type_1_2_3_5_or_6(u8 mapType)
+{
+ if (mapType == MAP_TYPE_ROUTE
+ || mapType == MAP_TYPE_TOWN
+ || mapType == MAP_TYPE_UNDERWATER
+ || mapType == MAP_TYPE_CITY
+ || mapType == MAP_TYPE_6)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 Overworld_MapTypeAllowsTeleportAndFly(u8 mapType)
+{
+ if (mapType == MAP_TYPE_ROUTE
+ || mapType == MAP_TYPE_TOWN
+ || mapType == MAP_TYPE_6
+ || mapType == MAP_TYPE_CITY)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 Overworld_MapTypeIsIndoors(u8 mapType)
+{
+ if (mapType == MAP_TYPE_INDOOR
+ || mapType == MAP_TYPE_SECRET_BASE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+u8 sav1_saved_warp2_map_get_name(void)
+{
+ return Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->warp2.mapGroup, gSaveBlock1Ptr->warp2.mapNum)->regionMapSectionId;
+}
+
+u8 sav1_map_get_name(void)
+{
+ return Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum)->regionMapSectionId;
+}
+
+u8 GetCurrentMapBattleScene(void)
+{
+ return Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum)->battleType;
+}
+
+static void overworld_bg_setup(void)
+{
+ InitBgsFromTemplates(0, gUnknown_08339DAC, ARRAY_COUNT(gUnknown_08339DAC));
+ SetBgAttribute(1, BG_CTRL_ATTR_PALETTEMODE, 1);
+ SetBgAttribute(2, BG_CTRL_ATTR_PALETTEMODE, 1);
+ SetBgAttribute(3, BG_CTRL_ATTR_PALETTEMODE, 1);
+ gBGTilemapBuffers2 = AllocZeroed(0x800);
+ gBGTilemapBuffers1 = AllocZeroed(0x800);
+ gBGTilemapBuffers3 = AllocZeroed(0x800);
+ SetBgTilemapBuffer(1, gBGTilemapBuffers2);
+ SetBgTilemapBuffer(2, gBGTilemapBuffers1);
+ SetBgTilemapBuffer(3, gBGTilemapBuffers3);
+ sub_81971D0();
+}
+
+void overworld_free_bg_tilemaps(void)
+{
+ sub_81BE72C();
+ sub_81971F4();
+ if (gBGTilemapBuffers3 != NULL)
+ FREE_AND_SET_NULL(gBGTilemapBuffers3);
+ if (gBGTilemapBuffers1 != NULL)
+ FREE_AND_SET_NULL(gBGTilemapBuffers1);
+ if (gBGTilemapBuffers2 != NULL)
+ FREE_AND_SET_NULL(gBGTilemapBuffers2);
+}
+
+static void ResetSafariZoneFlag_(void)
+{
+ ResetSafariZoneFlag();
+}
+
+bool32 is_c1_link_related_active(void)
+{
+ if (gMain.callback1 == c1_link_related)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static void DoCB1_Overworld(u16 newKeys, u16 heldKeys)
+{
+ struct FieldInput inputStruct;
+
+ sub_808B578();
+ FieldClearPlayerInput(&inputStruct);
+ FieldGetPlayerInput(&inputStruct, newKeys, heldKeys);
+ if (!ScriptContext2_IsEnabled())
+ {
+ if (sub_809C014(&inputStruct) == 1)
+ {
+ ScriptContext2_Enable();
+ HideMapNamePopUpWindow();
+ }
+ else
+ {
+ player_step(inputStruct.dpadDirection, newKeys, heldKeys);
+ }
+ }
+}
+
+void CB1_Overworld(void)
+{
+ if (gMain.callback2 == CB2_Overworld)
+ DoCB1_Overworld(gMain.newKeys, gMain.heldKeys);
+}
+
+static void OverworldBasic(void)
+{
+ ScriptContext2_RunScript();
+ RunTasks();
+ AnimateSprites();
+ CameraUpdate();
+ UpdateCameraPanning();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+ sub_80A0A38();
+ do_scheduled_bg_tilemap_copies_to_vram();
+}
+
+// This CB2 is used when starting
+void CB2_OverworldBasic(void)
+{
+ OverworldBasic();
+}
+
+void CB2_Overworld(void)
+{
+ bool32 fading = (gPaletteFade.active != 0);
+ if (fading)
+ SetVBlankCallback(NULL);
+ OverworldBasic();
+ if (fading)
+ SetFieldVBlankCallback();
+}
+
+void SetMainCallback1(MainCallback cb)
+{
+ gMain.callback1 = cb;
+}
+
+void sub_8085E94(void *a0)
+{
+ sUnknown_03000E0C = a0;
+}
+
+static bool8 map_post_load_hook_exec(void)
+{
+ if (gUnknown_03005DB0 != NULL)
+ {
+ if (!gUnknown_03005DB0())
+ {
+ return FALSE;
+ }
+ else
+ {
+ gUnknown_03005DB0 = NULL;
+ gFieldCallback = NULL;
+ }
+ }
+ else
+ {
+ if (gFieldCallback != NULL)
+ gFieldCallback();
+ else
+ mapldr_default();
+
+ gFieldCallback = NULL;
+ }
+
+ return TRUE;
+}
+
+void CB2_NewGame(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ StopMapMusic();
+ ResetSafariZoneFlag_();
+ NewGameInitData();
+ player_avatar_init_params_reset();
+ PlayTimeCounter_Start();
+ ScriptContext1_Init();
+ ScriptContext2_Disable();
+ gFieldCallback = ExecuteTruckSequence;
+ gUnknown_03005DB0 = NULL;
+ do_load_map_stuff_loop(&gMain.state);
+ SetFieldVBlankCallback();
+ SetMainCallback1(CB1_Overworld);
+ SetMainCallback2(CB2_Overworld);
+}
+
+void CB2_WhiteOut(void)
+{
+ u8 val;
+
+ if (++gMain.state >= 120)
+ {
+ FieldClearVBlankHBlankCallbacks();
+ StopMapMusic();
+ ResetSafariZoneFlag_();
+ DoWhiteOut();
+ player_avatar_init_params_reset();
+ ScriptContext1_Init();
+ ScriptContext2_Disable();
+ gFieldCallback = sub_80AF3C8;
+ val = 0;
+ do_load_map_stuff_loop(&val);
+ SetFieldVBlankCallback();
+ SetMainCallback1(CB1_Overworld);
+ SetMainCallback2(CB2_Overworld);
+ }
+}
+
+void CB2_LoadMap(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ ScriptContext1_Init();
+ ScriptContext2_Disable();
+ SetMainCallback1(NULL);
+ SetMainCallback2(c2_change_map);
+ gMain.savedCallback = CB2_LoadMap2;
+}
+
+static void CB2_LoadMap2(void)
+{
+ do_load_map_stuff_loop(&gMain.state);
+ SetFieldVBlankCallback();
+ SetMainCallback1(CB1_Overworld);
+ SetMainCallback2(CB2_Overworld);
+}
+
+void sub_8086024(void)
+{
+ if (!gMain.state)
+ {
+ FieldClearVBlankHBlankCallbacks();
+ ScriptContext1_Init();
+ ScriptContext2_Disable();
+ SetMainCallback1(NULL);
+ }
+ if (load_map_stuff(&gMain.state, 1))
+ {
+ SetFieldVBlankCallback();
+ SetMainCallback1(CB1_Overworld);
+ SetMainCallback2(CB2_Overworld);
+ }
+}
+
+void sub_8086074(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ gFieldCallback = sub_80AF314;
+ SetMainCallback2(c2_80567AC);
+}
+
+static void c2_80567AC(void)
+{
+ if (map_loading_iteration_3(&gMain.state))
+ {
+ SetFieldVBlankCallback();
+ SetMainCallback1(c1_link_related);
+ sub_8086C2C();
+ SetMainCallback2(CB2_Overworld);
+ }
+}
+
+void CB2_ReturnToField(void)
+{
+ if (is_c1_link_related_active() == TRUE)
+ {
+ SetMainCallback2(CB2_ReturnToFieldLink);
+ }
+ else
+ {
+ FieldClearVBlankHBlankCallbacks();
+ SetMainCallback2(CB2_ReturnToFieldLocal);
+ }
+}
+
+void CB2_ReturnToFieldLocal(void)
+{
+ if (sub_8086638(&gMain.state))
+ {
+ SetFieldVBlankCallback();
+ SetMainCallback2(CB2_Overworld);
+ }
+}
+
+void CB2_ReturnToFieldLink(void)
+{
+ if (!sub_8087598() && map_loading_iteration_2_link(&gMain.state))
+ SetMainCallback2(CB2_Overworld);
+}
+
+void c2_8056854(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ StopMapMusic();
+ SetMainCallback1(c1_link_related);
+ sub_8086C2C();
+
+ if (gWirelessCommType != 0)
+ gFieldCallback = sub_80AF314;
+ else
+ gFieldCallback = sub_80AF214;
+
+ ScriptContext1_Init();
+ ScriptContext2_Disable();
+ CB2_ReturnToField();
+}
+
+void CB2_ReturnToFieldWithOpenMenu(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ gUnknown_03005DB0 = sub_80AF6A4;
+ CB2_ReturnToField();
+}
+
+void sub_80861B0(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ gFieldCallback = sub_80AF188;
+ CB2_ReturnToField();
+}
+
+void CB2_ReturnToFieldContinueScript(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ gFieldCallback = sub_80AF168;
+ CB2_ReturnToField();
+}
+
+void sub_80861E8(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ gFieldCallback = sub_80AF3C8;
+ CB2_ReturnToField();
+}
+
+static void sub_8086204(void)
+{
+ if ((gMapHeader.flags & 0xF8) == 8 && sub_80E909C() == TRUE)
+ ShowMapNamePopup();
+ sub_80AF3C8();
+}
+
+void CB2_ContinueSavedGame(void)
+{
+ u8 trainerHillMapId;
+
+ FieldClearVBlankHBlankCallbacks();
+ StopMapMusic();
+ ResetSafariZoneFlag_();
+ if (gSaveFileStatus == 0xFF)
+ sub_81A3908();
+
+ LoadSaveblockMapHeader();
+ set_warp2_warp3_to_neg_1();
+ trainerHillMapId = GetCurrentTrainerHillMapId();
+ if (gMapHeader.mapDataId == 0x169)
+ sub_81AA2F8();
+ else if (trainerHillMapId != 0 && trainerHillMapId != 6)
+ sub_81D5F48();
+ else
+ LoadSaveblockMapObjScripts();
+
+ UnfreezeMapObjects();
+ DoTimeBasedEvents();
+ sub_8084788();
+ if (gMapHeader.mapDataId == 0x169)
+ battle_pyramid_map_load_related(1);
+ else if (trainerHillMapId != 0)
+ trainer_hill_map_load_related();
+ else
+ sub_8087D74();
+
+ PlayTimeCounter_Start();
+ ScriptContext1_Init();
+ ScriptContext2_Disable();
+ sub_8195E10();
+ if (GetSecretBase2Field_9() == 1)
+ {
+ ClearSecretBase2Field_9();
+ warp1_set_to_sav1w();
+ warp_in();
+ sub_80EDB44();
+ SetMainCallback2(CB2_LoadMap);
+ }
+ else
+ {
+ sub_80EDB44();
+ gFieldCallback = sub_8086204;
+ SetMainCallback1(CB1_Overworld);
+ CB2_ReturnToField();
+ }
+}
+
+static void FieldClearVBlankHBlankCallbacks(void)
+{
+ if (warp0_in_pokecenter() == TRUE)
+ CloseLink();
+
+ if (gWirelessCommType != 0)
+ {
+ EnableInterrupts(INTR_FLAG_VBLANK | INTR_FLAG_VCOUNT | INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL);
+ DisableInterrupts(INTR_FLAG_HBLANK);
+ }
+ else
+ {
+ u16 savedIme = REG_IME;
+ REG_IME = 0;
+ REG_IE &= ~INTR_FLAG_HBLANK;
+ REG_IE |= INTR_FLAG_VBLANK;
+ REG_IME = savedIme;
+ }
+
+ SetVBlankCallback(NULL);
+ SetHBlankCallback(NULL);
+}
+
+static void SetFieldVBlankCallback(void)
+{
+ SetVBlankCallback(VBlankCB_Field);
+}
+
+static void VBlankCB_Field(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ ScanlineEffect_InitHBlankDmaTransfer();
+ FieldUpdateBgTilemapScroll();
+ TransferPlttBuffer();
+ TransferTilesetAnimsBuffer();
+}
+
+static void sub_80863B0(void)
+{
+ u8 val;
+
+ if (sub_81A9E6C())
+ {
+ door_upload_tiles();
+ ScanlineEffect_SetParams(gUnknown_08339DBC);
+ }
+ else if ((val = Overworld_GetFlashLevel()))
+ {
+ sub_80B00E8(val);
+ ScanlineEffect_SetParams(gUnknown_08339DBC);
+ }
+}
+
+static bool32 map_loading_iteration_3(u8 *state)
+{
+ switch (*state)
+ {
+ case 0:
+ overworld_bg_setup();
+ ScriptContext1_Init();
+ ScriptContext2_Disable();
+ sub_80867C8();
+ sub_80867D8();
+ (*state)++;
+ break;
+ case 1:
+ mli0_load_map(1);
+ (*state)++;
+ break;
+ case 2:
+ sub_8086988(TRUE);
+ (*state)++;
+ break;
+ case 3:
+ sub_8086AE4();
+ sub_80869DC();
+ sub_8086B14();
+ sub_8086AAC();
+ (*state)++;
+ break;
+ case 4:
+ sub_80863B0();
+ map_loading_lcd_reset();
+ sub_8197200();
+ (*state)++;
+ break;
+ case 5:
+ move_tilemap_camera_to_upper_left_corner();
+ (*state)++;
+ break;
+ case 6:
+ copy_map_tileset1_to_vram(gMapHeader.mapData);
+ (*state)++;
+ break;
+ case 7:
+ copy_map_tileset2_to_vram(gMapHeader.mapData);
+ (*state)++;
+ break;
+ case 8:
+ if (free_temp_tile_data_buffers_if_possible() != TRUE)
+ {
+ apply_map_tileset1_tileset2_palette(gMapHeader.mapData);
+ (*state)++;
+ }
+ break;
+ case 9:
+ DrawWholeMapView();
+ (*state)++;
+ break;
+ case 10:
+ cur_mapheader_run_tileset_funcs_after_some_cpuset();
+ (*state)++;
+ break;
+ case 11:
+ if (gWirelessCommType != 0)
+ {
+ sub_800E0E8();
+ CreateWirelessStatusIndicatorSprite(0, 0);
+ }
+ (*state)++;
+ break;
+ case 12:
+ if (map_post_load_hook_exec())
+ (*state)++;
+ break;
+ case 13:
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static bool32 load_map_stuff(u8 *state, u32 a2)
+{
+ switch (*state)
+ {
+ case 0:
+ FieldClearVBlankHBlankCallbacks();
+ mli0_load_map(a2);
+ (*state)++;
+ break;
+ case 1:
+ sub_80867C8();
+ sub_80867D8();
+ (*state)++;
+ break;
+ case 2:
+ sub_8086988(a2);
+ (*state)++;
+ break;
+ case 3:
+ mli4_mapscripts_and_other();
+ sub_8086A80();
+ (*state)++;
+ break;
+ case 4:
+ sub_80863B0();
+ map_loading_lcd_reset();
+ sub_8197200();
+ (*state)++;
+ break;
+ case 5:
+ move_tilemap_camera_to_upper_left_corner();
+ (*state)++;
+ break;
+ case 6:
+ copy_map_tileset1_to_vram(gMapHeader.mapData);
+ (*state)++;
+ break;
+ case 7:
+ copy_map_tileset2_to_vram(gMapHeader.mapData);
+ (*state)++;
+ break;
+ case 8:
+ if (free_temp_tile_data_buffers_if_possible() != TRUE)
+ {
+ apply_map_tileset1_tileset2_palette(gMapHeader.mapData);
+ (*state)++;
+ }
+ break;
+ case 9:
+ DrawWholeMapView();
+ (*state)++;
+ break;
+ case 10:
+ cur_mapheader_run_tileset_funcs_after_some_cpuset();
+ (*state)++;
+ break;
+ case 11:
+ if ((gMapHeader.flags & 0xF8) == 8 && sub_80E909C() == 1)
+ ShowMapNamePopup();
+ (*state)++;
+ break;
+ case 12:
+ if (map_post_load_hook_exec())
+ (*state)++;
+ break;
+ case 13:
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static bool32 sub_8086638(u8 *state)
+{
+ switch (*state)
+ {
+ case 0:
+ sub_80867C8();
+ sub_80867D8();
+ sub_8086988(0);
+ sub_8086A68();
+ sub_8086A80();
+ (*state)++;
+ break;
+ case 1:
+ sub_8086860();
+ sub_81D64C0();
+ (*state)++;
+ break;
+ case 2:
+ if (map_post_load_hook_exec())
+ (*state)++;
+ break;
+ case 3:
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static bool32 map_loading_iteration_2_link(u8 *state)
+{
+ switch (*state)
+ {
+ case 0:
+ FieldClearVBlankHBlankCallbacks();
+ sub_80867C8();
+ sub_80867D8();
+ (*state)++;
+ break;
+ case 1:
+ sub_8086988(1);
+ (*state)++;
+ break;
+ case 2:
+ sub_8086B9C();
+ sub_8086A68();
+ sub_8086AC8();
+ (*state)++;
+ break;
+ case 3:
+ sub_80863B0();
+ map_loading_lcd_reset();
+ sub_8197200();
+ (*state)++;
+ break;
+ case 4:
+ move_tilemap_camera_to_upper_left_corner();
+ (*state)++;
+ break;
+ case 5:
+ copy_map_tileset1_to_vram(gMapHeader.mapData);
+ (*state)++;
+ break;
+ case 6:
+ copy_map_tileset2_to_vram(gMapHeader.mapData);
+ (*state)++;
+ break;
+ case 7:
+ if (free_temp_tile_data_buffers_if_possible() != TRUE)
+ {
+ apply_map_tileset1_tileset2_palette(gMapHeader.mapData);
+ (*state)++;
+ }
+ break;
+ case 8:
+ DrawWholeMapView();
+ (*state)++;
+ break;
+ case 9:
+ cur_mapheader_run_tileset_funcs_after_some_cpuset();
+ (*state)++;
+ break;
+ case 11:
+ if (gWirelessCommType != 0)
+ {
+ sub_800E0E8();
+ CreateWirelessStatusIndicatorSprite(0, 0);
+ }
+ (*state)++;
+ break;
+ case 12:
+ if (map_post_load_hook_exec())
+ (*state)++;
+ break;
+ case 10:
+ (*state)++;
+ break;
+ case 13:
+ SetFieldVBlankCallback();
+ (*state)++;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void do_load_map_stuff_loop(u8 *state)
+{
+ while (!load_map_stuff(state, 0));
+}
+
+static void sub_80867C8(void)
+{
+ sub_81BE6AC();
+ MoveSaveBlocks_ResetHeap();
+}
+
+static void sub_80867D8(void)
+{
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ ScanlineEffect_Stop();
+
+ DmaClear16(3, PLTT + 2, PLTT_SIZE - 2);
+ DmaFillLarge16(3, 0, (void *)(VRAM + 0x0), 0x18000, 0x1000);
+ ResetOamRange(0, 128);
+ LoadOam();
+}
+
+static void sub_8086860(void)
+{
+ sub_80863B0();
+ map_loading_lcd_reset();
+ sub_8197200();
+ mapdata_load_assets_to_gpu_and_full_redraw();
+}
+
+static void map_loading_lcd_reset(void)
+{
+ clear_scheduled_bg_copies_to_vram();
+ reset_temp_tile_data_buffers();
+ SetGpuReg(REG_OFFSET_MOSAIC, 0);
+ SetGpuReg(REG_OFFSET_WININ, 0x1F1F);
+ SetGpuReg(REG_OFFSET_WINOUT, 0x101);
+ SetGpuReg(REG_OFFSET_WIN0H, 0xFF);
+ SetGpuReg(REG_OFFSET_WIN0V, 0xFF);
+ SetGpuReg(REG_OFFSET_WIN1H, 0xFFFF);
+ SetGpuReg(REG_OFFSET_WIN1V, 0xFFFF);
+ SetGpuReg(REG_OFFSET_BLDCNT, gUnknown_82EC7C4[1] | gUnknown_82EC7C4[2] | gUnknown_82EC7C4[3]
+ | BLDCNT_TGT2_OBJ | BLDCNT_EFFECT_BLEND);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(13, 7));
+ overworld_bg_setup();
+ schedule_bg_copy_tilemap_to_vram(1);
+ schedule_bg_copy_tilemap_to_vram(2);
+ schedule_bg_copy_tilemap_to_vram(3);
+ ChangeBgX(0, 0, 0);
+ ChangeBgY(0, 0, 0);
+ ChangeBgX(1, 0, 0);
+ ChangeBgY(1, 0, 0);
+ ChangeBgX(2, 0, 0);
+ ChangeBgY(2, 0, 0);
+ ChangeBgX(3, 0, 0);
+ ChangeBgY(3, 0, 0);
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_WIN0_ON | DISPCNT_WIN1_ON
+ | DISPCNT_OBJ_1D_MAP | DISPCNT_HBLANK_INTERVAL);
+ ShowBg(0);
+ ShowBg(1);
+ ShowBg(2);
+ ShowBg(3);
+ sub_8098128();
+}
+
+static void sub_8086988(u32 a1)
+{
+ ResetTasks();
+ ResetSpriteData();
+ ResetPaletteFade();
+ ScanlineEffect_Clear();
+ dp13_810BB8C();
+ ResetCameraUpdateInfo();
+ InstallCameraPanAheadCallback();
+ if (!a1)
+ npc_paltag_set_load(0);
+ else
+ npc_paltag_set_load(1);
+
+ FieldEffectActiveListClear();
+ sub_80AAFA4();
+ sub_80AEE84();
+ if (!a1)
+ SetUpFieldTasks();
+ mapheader_run_script_with_tag_x5();
+ sub_81BE6B8();
+}
+
+static void sub_80869DC(void)
+{
+ gUnknown_03005DEC = 0;
+ gUnknown_03005DE8 = 0;
+ sub_808D438();
+ SpawnFieldObjectsInView(0, 0);
+ mapheader_run_first_tag4_script_list_match();
+}
+
+static void mli4_mapscripts_and_other(void)
+{
+ s16 x, y;
+ struct UnkPlayerStruct *player;
+
+ gUnknown_03005DEC = 0;
+ gUnknown_03005DE8 = 0;
+ sub_808D438();
+ sav1_camera_get_focus_coords(&x, &y);
+ player = sub_80852D4();
+ InitPlayerAvatar(x, y, player->player_field_1, gSaveBlock2Ptr->playerGender);
+ SetPlayerAvatarTransitionFlags(player->player_field_0);
+ player_avatar_init_params_reset();
+ SpawnFieldObjectsInView(0, 0);
+ mapheader_run_first_tag4_script_list_match();
+}
+
+static void sub_8086A68(void)
+{
+ sub_808E16C(0, 0);
+ RotatingGate_InitPuzzleAndGraphics();
+ mapheader_run_script_with_tag_x7();
+}
+
+static void sub_8086A80(void)
+{
+ gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_15 = 1;
+ InitCameraUpdateCallback(gPlayerAvatar.spriteId);
+}
+
+static void sub_8086AAC(void)
+{
+ InitCameraUpdateCallback(sub_8087858(gUnknown_03005DB4));
+}
+
+static void sub_8086AC8(void)
+{
+ InitCameraUpdateCallback(sub_8087858(gUnknown_03005DB4));
+}
+
+static void sub_8086AE4(void)
+{
+ u16 x, y;
+ sav1_camera_get_focus_coords(&x, &y);
+ sub_8088B3C(x + gUnknown_03005DB4, y);
+}
+
+static void sub_8086B14(void)
+{
+ u16 i;
+ u16 x, y;
+
+ sav1_camera_get_focus_coords(&x, &y);
+ x -= gUnknown_03005DB4;
+
+ for (i = 0; i < gFieldLinkPlayerCount; i++)
+ {
+ SpawnLinkPlayerMapObject(i, i + x, y, gLinkPlayers[i].gender);
+ CreateLinkPlayerSprite(i, gLinkPlayers[i].version);
+ }
+
+ sub_8086C40();
+}
+
+static void sub_8086B9C(void)
+{
+ u16 i;
+ for (i = 0; i < gFieldLinkPlayerCount; i++)
+ CreateLinkPlayerSprite(i, gLinkPlayers[i].version);
+}
+
+static void c1_link_related(void)
+{
+ if (gWirelessCommType == 0 || !sub_800F0B8() || !sub_8009F3C())
+ {
+ u8 var = gUnknown_03005DB4;
+ sub_8086F38(gLinkPartnersHeldKeys, var);
+ sub_8086FA0(sUnknown_03000E14(var));
+ sub_8086C40();
+ }
+}
+
+void sub_8086C2C(void)
+{
+ sub_8086C90();
+ c1_link_related_func_set(sub_80870B0);
+}
+
+static void sub_8086C40(void)
+{
+ sub_808709C(gLinkPartnersHeldKeys);
+}
+
+static void c1_link_related_func_set(u16 (*func)(u32))
+{
+ sUnknown_03000E19 = 0;
+ sUnknown_03000E14 = func;
+}
+
+static void sub_8086C64(void)
+{
+ if (gWirelessCommType != 0 && ++sUnknown_03000E19 > 60)
+ sub_8010198();
+}
+
+static void sub_8086C90(void)
+{
+ s32 i;
+ for (i = 0; i < 4; i++)
+ sUnknown_03000E10[i] = 0x80;
+}
+
+static bool32 sub_8086CA8(u16 a1)
+{
+ s32 i;
+ s32 count = gFieldLinkPlayerCount;
+
+ for (i = 0; i < count; i++)
+ if (sUnknown_03000E10[i] != a1)
+ return FALSE;
+ return TRUE;
+}
+
+static bool32 sub_8086CE0(u16 a1)
+{
+ s32 i;
+ s32 count = gFieldLinkPlayerCount;
+
+ for (i = 0; i < count; i++)
+ if (sUnknown_03000E10[i] == a1)
+ return TRUE;
+ return FALSE;
+}
+
+static void sub_8086D18(u32 a1, u16 a2, struct UnkStruct_8054FF8 *a3, u16 *a4)
+{
+ const u8 *script;
+
+ if (sUnknown_03000E10[a1] == 0x80)
+ {
+ script = sub_8087370(a3);
+ if (script)
+ {
+ *a4 = sub_8087480(script);
+ sUnknown_03000E10[a1] = 0x81;
+ if (a3->b)
+ {
+ c1_link_related_func_set(sub_80870F8);
+ sub_8087530(script);
+ }
+ return;
+ }
+ if (sub_8086CE0(0x83) == 1)
+ {
+ sUnknown_03000E10[a1] = 0x81;
+ if (a3->b)
+ {
+ c1_link_related_func_set(sub_80870F8);
+ sub_8087584();
+ }
+ return;
+ }
+ switch (a2)
+ {
+ case 24:
+ if (sub_8087358(a3))
+ {
+ sUnknown_03000E10[a1] = 0x81;
+ if (a3->b)
+ {
+ c1_link_related_func_set(sub_80870F8);
+ sub_808751C();
+ }
+ }
+ break;
+ case 18:
+ if (sub_8087388(a3) == TRUE)
+ {
+ sUnknown_03000E10[a1] = 0x81;
+ if (a3->b)
+ {
+ c1_link_related_func_set(sub_80870F8);
+ sub_808754C();
+ }
+ }
+ break;
+ case 25:
+ script = sub_80873B4(a3);
+ if (script)
+ {
+ sUnknown_03000E10[a1] = 0x81;
+ if (a3->b)
+ {
+ c1_link_related_func_set(sub_80870F8);
+ sub_8087568(script);
+ }
+ }
+ break;
+ case 27:
+ if (sub_8087340(a3))
+ {
+ sUnknown_03000E10[a1] = 0x81;
+ if (a3->b)
+ {
+ c1_link_related_func_set(sub_808711C);
+ sub_8087510();
+ }
+ }
+ break;
+ case 28:
+ if (sub_8087340(a3))
+ {
+ sUnknown_03000E10[a1] = 0x81;
+ if (a3->b)
+ {
+ c1_link_related_func_set(sub_8087140);
+ sub_8087510();
+ }
+ }
+ break;
+ }
+ }
+
+ switch (a2)
+ {
+ case 23:
+ sUnknown_03000E10[a1] = 0x83;
+ break;
+ case 22:
+ sUnknown_03000E10[a1] = 0x82;
+ break;
+ case 26:
+ sUnknown_03000E10[a1] = 0x80;
+ if (a3->b)
+ c1_link_related_func_set(sub_80870B0);
+ break;
+ case 29:
+ if (sUnknown_03000E10[a1] == 0x82)
+ sUnknown_03000E10[a1] = 0x81;
+ break;
+ }
+}
+
+static void sub_8086F38(u16 *a1, s32 a2)
+{
+ struct UnkStruct_8054FF8 st;
+ s32 i;
+
+ for (i = 0; i < 4; i++)
+ {
+ u8 v5 = a1[i];
+ u16 v8 = 0;
+ sub_80872D8(i, a2, &st);
+ sub_8086D18(i, v5, &st, &v8);
+ if (sUnknown_03000E10[i] == 0x80)
+ v8 = sub_8087068(v5);
+ sub_808796C(i, v8);
+ }
+}
+
+static void sub_8086FA0(u16 a1)
+{
+ if (a1 >= 17 && a1 < 30)
+ gUnknown_03005DA8 = a1;
+ else
+ gUnknown_03005DA8 = 17;
+
+ if (gWirelessCommType != 0
+ && sub_8087690() > 1
+ && is_c1_link_related_active() == TRUE
+ && sub_8009F3C() == TRUE)
+ {
+ switch (a1)
+ {
+ case 17:
+ case 18:
+ case 19:
+ case 20:
+ case 21:
+ case 24:
+ case 25:
+ gUnknown_03005DA8 = 0;
+ break;
+ }
+ }
+}
+
+static u16 sub_808700C(u32 a1)
+{
+ if (gMain.heldKeys & DPAD_UP)
+ return 19;
+ else if (gMain.heldKeys & DPAD_DOWN)
+ return 18;
+ else if (gMain.heldKeys & DPAD_LEFT)
+ return 20;
+ else if (gMain.heldKeys & DPAD_RIGHT)
+ return 21;
+ else if (gMain.newKeys & START_BUTTON)
+ return 24;
+ else if (gMain.newKeys & A_BUTTON)
+ return 25;
+ else
+ return 17;
+}
+
+static u16 sub_8087068(u16 a1)
+{
+ switch (a1)
+ {
+ case 21:
+ return 4;
+ case 20:
+ return 3;
+ case 19:
+ return 1;
+ case 18:
+ return 2;
+ default:
+ return 0;
+ }
+}
+
+static void sub_808709C(u16 *a1)
+{
+ s32 i;
+ for (i = 0; i < 4; i++)
+ a1[i] = 17;
+}
+
+static u16 sub_80870B0(u32 a1)
+{
+ if (ScriptContext2_IsEnabled() == 1)
+ return 17;
+ if (sub_800B4DC() > 4)
+ return 27;
+ if (sub_8087690() <= 4)
+ return sub_808700C(a1);
+ return 28;
+}
+
+static u16 sub_80870EC(u32 a1)
+{
+ sub_8086C64();
+ return 17;
+}
+
+static u16 sub_80870F8(u32 a1)
+{
+ u16 retVal;
+ if (ScriptContext2_IsEnabled() == TRUE)
+ {
+ retVal = 17;
+ }
+ else
+ {
+ retVal = 26;
+ c1_link_related_func_set(sub_80870EC);
+ }
+ return retVal;
+}
+
+static u16 sub_808711C(u32 a1)
+{
+ u16 retVal;
+ if (sub_800B4DC() > 2)
+ {
+ retVal = 17;
+ }
+ else
+ {
+ retVal = 26;
+ ScriptContext2_Disable();
+ c1_link_related_func_set(sub_80870EC);
+ }
+ return retVal;
+}
+
+static u16 sub_8087140(u32 a1)
+{
+ u16 retVal;
+ if (sub_8087690() > 2)
+ {
+ retVal = 17;
+ }
+ else
+ {
+ retVal = 26;
+ ScriptContext2_Disable();
+ c1_link_related_func_set(sub_80870EC);
+ }
+ return retVal;
+}
+
+static u16 sub_8087164(u32 a1)
+{
+ sub_8086C64();
+ return 17;
+}
+
+static u16 sub_8087170(u32 linkPlayerId)
+{
+ if (sUnknown_03000E10[linkPlayerId] == 0x82)
+ {
+ if (gMain.newKeys & B_BUTTON)
+ {
+ c1_link_related_func_set(sub_8087164);
+ return 29;
+ }
+ else
+ {
+ return 17;
+ }
+ }
+ else
+ {
+ sub_8086C64();
+ return 17;
+ }
+}
+
+static u16 sub_80871AC(u32 a1)
+{
+ c1_link_related_func_set(sub_8087170);
+ return 22;
+}
+
+static u16 sub_80871C0(u32 a1)
+{
+ return 17;
+}
+
+static u16 sub_80871C4(u32 a1)
+{
+ if (sUnknown_03000E10[a1] != 0x83)
+ sub_8086C64();
+ if (sub_8086CA8(0x83) == TRUE)
+ {
+ ScriptContext1_SetupScript(EventScript_277513);
+ c1_link_related_func_set(sub_80871C0);
+ }
+ return 17;
+}
+
+static u16 sub_80871FC(u32 a1)
+{
+ c1_link_related_func_set(sub_80871C4);
+ return 23;
+}
+
+static u16 sub_8087210(u32 a1)
+{
+ return 17;
+}
+
+u32 sub_8087214(void)
+{
+ if (sub_8086CE0(0x83) == TRUE)
+ return 2;
+ if (sUnknown_03000E14 == sub_8087170 && sUnknown_03000E10[gUnknown_03005DB4] != 0x82)
+ return 0;
+ if (sUnknown_03000E14 == sub_8087164 && sUnknown_03000E10[gUnknown_03005DB4] == 0x81)
+ return 2;
+ if (sub_8086CA8(0x82) != 0)
+ return 1;
+ return 0;
+}
+
+bool32 sub_808727C(void)
+{
+ return sub_8086CE0(0x83);
+}
+
+u16 sub_8087288(void)
+{
+ c1_link_related_func_set(sub_80871AC);
+ return 0;
+}
+
+u16 sub_808729C(void)
+{
+ c1_link_related_func_set(sub_80870F8);
+ return 0;
+}
+
+u16 sub_80872B0(void)
+{
+ c1_link_related_func_set(sub_80871FC);
+ return 0;
+}
+
+u16 sub_80872C4(void)
+{
+ c1_link_related_func_set(sub_8087210);
+ return 0;
+}
+
+static void sub_80872D8(s32 linkPlayerId, s32 a2, struct UnkStruct_8054FF8 *a3)
+{
+ s16 x, y;
+
+ a3->a = linkPlayerId;
+ a3->b = (linkPlayerId == a2) ? 1 : 0;
+ a3->c = gLinkPlayerMapObjects[linkPlayerId].mode;
+ a3->d = sub_80878A0(linkPlayerId);
+ sub_8087878(linkPlayerId, &x, &y);
+ a3->sub.x = x;
+ a3->sub.y = y;
+ a3->sub.height = sub_80878C0(linkPlayerId);
+ a3->field_C = MapGridGetMetatileBehaviorAt(x, y);
+}
+
+static bool32 sub_8087340(struct UnkStruct_8054FF8 *a1)
+{
+ u8 v1 = a1->c;
+ if (v1 == 2 || v1 == 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static bool32 sub_8087358(struct UnkStruct_8054FF8 *a1)
+{
+ u8 v1 = a1->c;
+ if (v1 == 2 || v1 == 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static u8 *sub_8087370(struct UnkStruct_8054FF8 *a1)
+{
+ if (a1->c != 2)
+ return 0;
+ return sub_809D0F4(&a1->sub);
+}
+
+static bool32 sub_8087388(struct UnkStruct_8054FF8 *a1)
+{
+ if (a1->c != 2 && a1->c != 0)
+ return FALSE;
+ else if (!MetatileBehavior_IsSouthArrowWarp(a1->field_C))
+ return FALSE;
+ else if (a1->d != 1)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+static const u8 *sub_80873B4(struct UnkStruct_8054FF8 *a1)
+{
+ struct MapPosition unkStruct;
+ u8 linkPlayerId;
+
+ if (a1->c && a1->c != 2)
+ return 0;
+
+ unkStruct = a1->sub;
+ unkStruct.x += gUnknown_08339D64[a1->d].x;
+ unkStruct.y += gUnknown_08339D64[a1->d].y;
+ unkStruct.height = 0;
+ linkPlayerId = GetLinkPlayerIdAt(unkStruct.x, unkStruct.y);
+
+ if (linkPlayerId != 4)
+ {
+ if (!a1->b)
+ return EventScript_TradeRoom_TooBusyToNotice;
+ else if (sUnknown_03000E10[linkPlayerId] != 0x80)
+ return EventScript_TradeRoom_TooBusyToNotice;
+ else if (!sub_80B39D4(linkPlayerId))
+ return EventScript_TradeRoom_ReadTrainerCard1;
+ else
+ return EventScript_TradeRoom_ReadTrainerCard2;
+ }
+
+ return sub_809C2C8(&unkStruct, a1->field_C, a1->d);
+}
+
+static u16 sub_8087480(const u8 *script)
+{
+ if (script == gUnknown_08277388)
+ return 10;
+ else if (script == gUnknown_082773A3)
+ return 9;
+ else if (script == gUnknown_082773BE)
+ return 10;
+ else if (script == gUnknown_082773D9)
+ return 9;
+ else if (script == gUnknown_0827741D)
+ return 10;
+ else if (script == gUnknown_08277432)
+ return 9;
+ else if (script == gUnknown_08277447)
+ return 10;
+ else if (script == gUnknown_0827745C)
+ return 9;
+ else if (script == gUnknown_08277374)
+ return 10;
+ else if (script == gUnknown_0827737E)
+ return 9;
+ else if (script == gUnknown_082773F5)
+ return 10;
+ else if (script == gUnknown_082773FF)
+ return 9;
+ else
+ return 0;
+}
+
+static void sub_8087510(void)
+{
+ ScriptContext2_Enable();
+}
+
+static void sub_808751C(void)
+{
+ PlaySE(SE_WIN_OPEN);
+ ShowStartMenu();
+ ScriptContext2_Enable();
+}
+
+static void sub_8087530(const u8 *script)
+{
+ PlaySE(SE_SELECT);
+ ScriptContext1_SetupScript(script);
+ ScriptContext2_Enable();
+}
+
+static void sub_808754C(void)
+{
+ PlaySE(SE_WIN_OPEN);
+ ScriptContext1_SetupScript(gUnknown_082774EF);
+ ScriptContext2_Enable();
+}
+
+static void sub_8087568(const u8 *script)
+{
+ PlaySE(SE_SELECT);
+ ScriptContext1_SetupScript(script);
+ ScriptContext2_Enable();
+}
+
+static void sub_8087584(void)
+{
+ ScriptContext1_SetupScript(gUnknown_08277509);
+ ScriptContext2_Enable();
+}
+
+bool32 sub_8087598(void)
+{
+ if (!is_c1_link_related_active())
+ return 0;
+ if (sub_800B4DC() >= 3)
+ sUnknown_03000E18 = 1;
+ else
+ sUnknown_03000E18 = 0;
+ return sUnknown_03000E18;
+}
+
+bool32 sub_80875C8(void)
+{
+ u8 temp;
+
+ if (sub_800B4DC() < 2)
+ return FALSE;
+ else if (is_c1_link_related_active() != TRUE)
+ return FALSE;
+ else if (sub_8009F3C() != TRUE)
+ return FALSE;
+ else if (sUnknown_03000E14 == sub_808711C)
+ return TRUE;
+ else if (sUnknown_03000E14 != sub_80870F8)
+ return FALSE;
+
+ temp = sUnknown_03000E18;
+ sUnknown_03000E18 = 0;
+
+ if (temp == TRUE)
+ return TRUE;
+ else if (gPaletteFade.active && gPaletteFade.softwareFadeFinishing)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool32 sub_8087634(void)
+{
+ if (sub_8087690() < 2)
+ return FALSE;
+ else if (is_c1_link_related_active() != TRUE)
+ return FALSE;
+ else if (sub_8009F3C() != TRUE)
+ return FALSE;
+ else if (sUnknown_03000E14 == sub_8087140)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool32 sub_808766C(void)
+{
+ if (gWirelessCommType != 0)
+ return FALSE;
+ else if (!sub_8009F3C())
+ return FALSE;
+ else
+ return TRUE;
+}
+
+static u32 sub_8087690(void)
+{
+ if (gWirelessCommType != 0)
+ return gUnknown_03005000.unk_9e8.unk_232;
+ else
+ return gLink.sendQueue.count;
+}
+
+static void ZeroLinkPlayerMapObject(struct LinkPlayerMapObject *linkPlayerMapObj)
+{
+ memset(linkPlayerMapObj, 0, sizeof(struct LinkPlayerMapObject));
+}
+
+void ZeroAllLinkPlayerMapObjects(void)
+{
+ memset(gLinkPlayerMapObjects, 0, sizeof(gLinkPlayerMapObjects));
+}
+
+static void ZeroMapObject(struct MapObject *mapObj)
+{
+ memset(mapObj, 0, sizeof(struct MapObject));
+}
+
+static void SpawnLinkPlayerMapObject(u8 linkPlayerId, s16 x, s16 y, u8 a4)
+{
+ u8 mapObjId = sub_808D4F4();
+ struct LinkPlayerMapObject *linkPlayerMapObj = &gLinkPlayerMapObjects[linkPlayerId];
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+
+ ZeroLinkPlayerMapObject(linkPlayerMapObj);
+ ZeroMapObject(mapObj);
+
+ linkPlayerMapObj->active = 1;
+ linkPlayerMapObj->linkPlayerId = linkPlayerId;
+ linkPlayerMapObj->mapObjId = mapObjId;
+ linkPlayerMapObj->mode = 0;
+
+ mapObj->active = 1;
+ mapObj->mapobj_bit_1 = a4;
+ mapObj->range.as_byte = 2;
+ mapObj->spriteId = 64;
+
+ InitLinkPlayerMapObjectPos(mapObj, x, y);
+}
+
+static void InitLinkPlayerMapObjectPos(struct MapObject *mapObj, s16 x, s16 y)
+{
+ mapObj->coords2.x = x;
+ mapObj->coords2.y = y;
+ mapObj->coords3.x = x;
+ mapObj->coords3.y = y;
+ sub_8093038(x, y, &mapObj->coords1.x, &mapObj->coords1.y);
+ mapObj->coords1.x += 8;
+ FieldObjectUpdateZCoord(mapObj);
+}
+
+static void sub_80877DC(u8 linkPlayerId, u8 a2)
+{
+ if (gLinkPlayerMapObjects[linkPlayerId].active)
+ {
+ u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+ mapObj->range.as_byte = a2;
+ }
+}
+
+static void sub_808780C(u8 linkPlayerId)
+{
+ struct LinkPlayerMapObject *linkPlayerMapObj = &gLinkPlayerMapObjects[linkPlayerId];
+ u8 mapObjId = linkPlayerMapObj->mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+ if (mapObj->spriteId != 64 )
+ DestroySprite(&gSprites[mapObj->spriteId]);
+ linkPlayerMapObj->active = 0;
+ mapObj->active = 0;
+}
+
+static u8 sub_8087858(u8 linkPlayerId)
+{
+ u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+ return mapObj->spriteId;
+}
+
+static void sub_8087878(u8 linkPlayerId, u16 *x, u16 *y)
+{
+ u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+ *x = mapObj->coords2.x;
+ *y = mapObj->coords2.y;
+}
+
+static u8 sub_80878A0(u8 linkPlayerId)
+{
+ u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+ return mapObj->range.as_byte;
+}
+
+static u8 sub_80878C0(u8 linkPlayerId)
+{
+ u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+ return mapObj->mapobj_unk_0B_0;
+}
+
+static s32 sub_80878E4(u8 linkPlayerId)
+{
+ u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+ return 16 - (s8)mapObj->mapobj_unk_21;
+}
+
+static u8 GetLinkPlayerIdAt(s16 x, s16 y)
+{
+ u8 i;
+ for (i = 0; i < 4; i++)
+ {
+ if (gLinkPlayerMapObjects[i].active
+ && (gLinkPlayerMapObjects[i].mode == 0 || gLinkPlayerMapObjects[i].mode == 2))
+ {
+ struct MapObject *mapObj = &gMapObjects[gLinkPlayerMapObjects[i].mapObjId];
+ if (mapObj->coords2.x == x && mapObj->coords2.y == y)
+ return i;
+ }
+ }
+ return 4;
+}
+
+static void sub_808796C(u8 linkPlayerId, u8 a2)
+{
+ struct LinkPlayerMapObject *linkPlayerMapObj = &gLinkPlayerMapObjects[linkPlayerId];
+ u8 mapObjId = linkPlayerMapObj->mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+
+ if (linkPlayerMapObj->active)
+ {
+ if (a2 > 10)
+ mapObj->mapobj_bit_2 = 1;
+ else
+ gUnknown_08339E00[gUnknown_08339DC8[linkPlayerMapObj->mode](linkPlayerMapObj, mapObj, a2)](linkPlayerMapObj, mapObj);
+ }
+}
+
+static u8 sub_80879D8(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3)
+{
+ return gUnknown_08339DD4[a3](linkPlayerMapObj, mapObj, a3);
+}
+
+static u8 sub_80879F8(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3)
+{
+ return 1;
+}
+
+static u8 sub_80879FC(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3)
+{
+ return gUnknown_08339DD4[a3](linkPlayerMapObj, mapObj, a3);
+}
+
+static u8 sub_8087A1C(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3)
+{
+ return 0;
+}
+
+static u8 sub_8087A20(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3)
+{
+ s16 x, y;
+
+ mapObj->range.as_byte = npc_something3(a3, mapObj->range.as_byte);
+ FieldObjectMoveDestCoords(mapObj, mapObj->range.as_byte, &x, &y);
+
+ if (LinkPlayerDetectCollision(linkPlayerMapObj->mapObjId, mapObj->range.as_byte, x, y))
+ {
+ return 0;
+ }
+ else
+ {
+ mapObj->mapobj_unk_21 = 16;
+ npc_coords_shift(mapObj, x, y);
+ FieldObjectUpdateZCoord(mapObj);
+ return 1;
+ }
+}
+
+static u8 sub_8087A88(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3)
+{
+ mapObj->range.as_byte = npc_something3(a3, mapObj->range.as_byte);
+ return 0;
+}
+
+static void sub_8087AA0(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj)
+{
+ linkPlayerMapObj->mode = 0;
+}
+
+static void sub_8087AA8(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj)
+{
+ mapObj->mapobj_unk_21--;
+ linkPlayerMapObj->mode = 1;
+ MoveCoords(mapObj->range.as_byte, &mapObj->coords1.x, &mapObj->coords1.y);
+ if (!mapObj->mapobj_unk_21)
+ {
+ npc_coords_shift_still(mapObj);
+ linkPlayerMapObj->mode = 2;
+ }
+}
+
+static u8 npc_something3(u8 a1, u8 a2)
+{
+ switch (a1 - 1)
+ {
+ case 0:
+ case 6:
+ return 2;
+ case 1:
+ case 7:
+ return 1;
+ case 2:
+ case 8:
+ return 3;
+ case 3:
+ case 9:
+ return 4;
+ }
+ return a2;
+}
+
+static u8 LinkPlayerDetectCollision(u8 selfMapObjId, u8 a2, s16 x, s16 y)
+{
+ u8 i;
+ for (i = 0; i < 16; i++)
+ {
+ if (i != selfMapObjId)
+ {
+ if ((gMapObjects[i].coords2.x == x && gMapObjects[i].coords2.y == y)
+ || (gMapObjects[i].coords3.x == x && gMapObjects[i].coords3.y == y))
+ {
+ return 1;
+ }
+ }
+ }
+ return MapGridIsImpassableAt(x, y);
+}
+
+static void CreateLinkPlayerSprite(u8 linkPlayerId, u8 gameVersion)
+{
+ struct LinkPlayerMapObject *linkPlayerMapObj = &gLinkPlayerMapObjects[linkPlayerId];
+ u8 mapObjId = linkPlayerMapObj->mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+ struct Sprite *sprite;
-// Static type declarations
+ if (linkPlayerMapObj->active)
+ {
+ switch (gameVersion)
+ {
+ case VERSION_FIRE_RED:
+ case VERSION_LEAF_GREEN:
+ mapObj->spriteId = AddPseudoFieldObject(sub_808BD6C(mapObj->mapobj_bit_1), SpriteCB_LinkPlayer, 0, 0, 0);
+ break;
+ case VERSION_RUBY:
+ case VERSION_SAPPHIRE:
+ mapObj->spriteId = AddPseudoFieldObject(sub_808BD7C(mapObj->mapobj_bit_1), SpriteCB_LinkPlayer, 0, 0, 0);
+ break;
+ case VERSION_EMERALD:
+ mapObj->spriteId = AddPseudoFieldObject(GetRivalAvatarGraphicsIdByStateIdAndGender(0, mapObj->mapobj_bit_1), SpriteCB_LinkPlayer, 0, 0, 0);
+ break;
+ }
-// Static RAM declarations
-IWRAM_DATA void *gUnknown_03000E0C;
-IWRAM_DATA u8 gUnknown_03000E10[4];
-IWRAM_DATA u8 (*gUnknown_03000E14)(u32);
-IWRAM_DATA u8 gUnknown_03000E18;
-IWRAM_DATA u8 gUnknown_03000E19;
-IWRAM_DATA void *rom4_c_unused_03000e1c;
+ sprite = &gSprites[mapObj->spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->data[0] = linkPlayerId;
+ mapObj->mapobj_bit_2 = 0;
+ }
+}
-// Static ROM declarations
+static void SpriteCB_LinkPlayer(struct Sprite *sprite)
+{
+ struct LinkPlayerMapObject *linkPlayerMapObj = &gLinkPlayerMapObjects[sprite->data[0]];
+ struct MapObject *mapObj = &gMapObjects[linkPlayerMapObj->mapObjId];
+ sprite->pos1.x = mapObj->coords1.x;
+ sprite->pos1.y = mapObj->coords1.y;
+ SetObjectSubpriorityByZCoord(mapObj->elevation, sprite, 1);
+ sprite->oam.priority = ZCoordToPriority(mapObj->elevation);
-// .rodata
+ if (!linkPlayerMapObj->mode)
+ StartSpriteAnim(sprite, FieldObjectDirectionToImageAnimId(mapObj->range.as_byte));
+ else
+ StartSpriteAnimIfDifferent(sprite, get_go_image_anim_num(mapObj->range.as_byte));
-// .text
+ sub_80979D4(sprite, 0);
+ if (mapObj->mapobj_bit_2)
+ {
+ sprite->invisible = ((sprite->data[7] & 4) >> 2);
+ sprite->data[7]++;
+ }
+}
diff --git a/src/player_pc.c b/src/player_pc.c
new file mode 100644
index 000000000..2bdf527e7
--- /dev/null
+++ b/src/player_pc.c
@@ -0,0 +1,1364 @@
+#include "global.h"
+#include "constants/songs.h"
+#include "bg.h"
+#include "decoration.h"
+#include "event_scripts.h"
+#include "field_fadetransition.h"
+#include "field_map_obj.h"
+#include "field_screen.h"
+#include "field_weather.h"
+#include "international_string_util.h"
+#include "item.h"
+#include "item_icon.h"
+#include "item_menu.h"
+#include "constants/items.h"
+#include "list_menu.h"
+#include "mail.h"
+#include "main.h"
+#include "malloc.h"
+#include "menu.h"
+#include "menu_helpers.h"
+#include "menu_indicators.h"
+#include "overworld.h"
+#include "palette.h"
+#include "party_menu.h"
+#include "pokenav.h"
+#include "player_pc.h"
+#include "script.h"
+#include "sound.h"
+#include "sprite.h"
+#include "string_util.h"
+#include "strings.h"
+#include "task.h"
+#include "window.h"
+
+// structures
+struct Struct203BCC4
+{
+ struct ListMenuItem unk0[51];
+ u8 unk198[51][0x18];
+ u8 windowIds[6];
+ u8 unk666;
+ u8 spriteId;
+ u8 spriteIds[7];
+};
+
+// extern offset
+void (*gFieldCallback)(void);
+
+// static functions
+static void InitPlayerPCMenu(u8 taskId);
+static void PlayerPCProcessMenuInput(u8 taskId);
+static void InitItemStorageMenu(u8 taskId, u8 var);
+
+static u8 GetMailboxMailCount(void);
+static void Mailbox_UpdateMailList(void);
+static void Mailbox_DrawMailboxMenu(u8 taskId);
+static void Mailbox_ProcessInput(u8 taskId);
+static void Mailbox_PrintWhatToDoWithPlayerMailText(u8 taskId);
+static void Mailbox_ReturnToPlayerPC(u8);
+static void Mailbox_PrintMailOptions(u8 taskId);
+static void Mailbox_MailOptionsProcessInput(u8 taskId);
+
+static void PlayerPC_ItemStorage(u8 taskId);
+static void PlayerPC_Mailbox(u8 taskId);
+static void PlayerPC_Decoration(u8 var);
+static void PlayerPC_TurnOff(u8 taskId);
+
+static void Mailbox_DoMailMoveToBag(u8 taskId);
+static void Mailbox_DoMailRead(u8 taskId);
+static void Mailbox_MoveToBag(u8 taskId);
+static void Mailbox_Give(u8 taskId);
+static void Mailbox_Cancel(u8 taskId);
+
+static void Mailbox_CancelMoveToBag(u8 taskId);
+static void Mailbox_MoveToBagYesNoPrompt(u8 taskId);
+static void Mailbox_DrawYesNoBeforeMove(u8 taskId);
+static void Mailbox_DoGiveMailPokeMenu(u8 taskId);
+static void Mailbox_NoPokemonForMail(u8 taskId);
+
+static void Mailbox_FadeAndReadMail(u8 taskId);
+static void Mailbox_ReturnToFieldFromReadMail(void);
+static void Mailbox_DoRedrawMailboxMenuAfterReturn(void);
+static void pal_fill_for_maplights_or_black(void);
+static void Mailbox_HandleReturnToProcessInput(u8 taskId);
+static void Mailbox_UpdateMailListAfterDeposit(void);
+
+static void ItemStorage_Withdraw(u8 taskId);
+static void ItemStorage_Deposit(u8 taskId);
+static void ItemStorage_Toss(u8 taskId);
+static void ItemStorage_Exit(u8 taskId);
+static void ItemStorage_ResumeInputFromYesToss(u8 taskId);
+static void ItemStorage_ResumeInputFromNoToss(u8 taskId);
+
+static void ItemStorageMenuPrint(const u8 *);
+static void ItemStorageMenuProcessInput(u8 taskId);
+static void ItemStorage_ProcessWithdrawTossInput(u8 taskId);
+static void ItemStorage_SetItemAndMailCount(u8);
+static void ItemStorage_HandleReturnToProcessInput(u8 taskId);
+
+static void ItemStorage_WithdrawToss_Helper(u8 taskId, bool8 toss);
+static void Task_ItemStorage_Deposit(u8 taskId);
+static void ItemStorage_DoItemWithdraw(u8 taskId);
+static void ItemStorage_DoItemToss(u8 taskid);
+static void ItemStorage_HandleQuantityRolling(u8 taskid);
+static void ItemStorage_GoBackToPlayerPCMenu(u8 taskId);
+static void ItemStorage_ItemSwapChoosePrompt(u8 taskId);
+static void ItemStorage_DoItemAction(u8 taskId);
+static void ItemStorage_ProcessInput(u8 taskId);
+static void ItemStorage_DoItemSwap(u8 taskId, bool8 a);
+static void ItemStorage_HandleRemoveItem(u8 taskId);
+static void ItemStorage_WaitPressHandleResumeProcessInput(u8 taskId);
+static void ItemStorage_StartScrollIndicatorAndProcessInput(u8 taskId);
+
+static const u8* ItemStorage_GetItemPcResponse(u16);
+static void CopyItemName_PlayerPC(u8 *string, u16 itemId);
+
+static void sub_816BC14(void);
+static void sub_816BFE0(u8 y, u8, u8 speed);
+static void sub_816BCC4(u8);
+static void sub_816C690(u8);
+static void sub_816C4FC(u8 taskId);
+static void sub_816C0C8(void);
+static void sub_816C060(u16 itemId);
+static void sub_816BEF0(s32 id);
+static void sub_816B4DC(u8 taskId);
+static void ItemStorage_MoveCursor(s32 id, bool8 b, struct ListMenu * thisMenu);
+static void fish4_goto_x5_or_x6(u8 windowId, s32 id, u8 yOffset);
+
+// EWRAM
+static EWRAM_DATA const u8 *gPcItemMenuOptionOrder = NULL;
+static EWRAM_DATA u8 gPcItemMenuOptionsNum = 0;
+EWRAM_DATA struct PlayerPCItemPageStruct playerPCItemPageInfo = {0, 0, 0, 0, {0, 0, 0}, 0};
+static EWRAM_DATA struct Struct203BCC4 *gUnknown_0203BCC4 = NULL;
+
+// .rodata
+static const u8 *const gPCText_OptionDescList[] =
+{
+ gText_TakeOutItemsFromPC,
+ gText_StoreItemsInPC,
+ gText_ThrowAwayItemsInPC,
+ gText_GoBackPrevMenu,
+};
+
+static const struct MenuAction sPlayerPCMenuActions[] =
+{
+ { gText_ItemStorage, PlayerPC_ItemStorage },
+ { gText_Mailbox, PlayerPC_Mailbox },
+ { gText_Decoration, PlayerPC_Decoration },
+ { gText_TurnOff, PlayerPC_TurnOff }
+};
+
+static const u8 gBedroomPC_OptionOrder[] =
+{
+ PLAYERPC_MENU_ITEMSTORAGE,
+ PLAYERPC_MENU_MAILBOX,
+ PLAYERPC_MENU_DECORATION,
+ PLAYERPC_MENU_TURNOFF
+};
+
+static const u8 gPlayerPC_OptionOrder[] =
+{
+ PLAYERPC_MENU_ITEMSTORAGE,
+ PLAYERPC_MENU_MAILBOX,
+ PLAYERPC_MENU_TURNOFF
+};
+
+static const struct MenuAction gPCText_ItemPCOptionsText[] =
+{
+ { gText_WithdrawItem, ItemStorage_Withdraw },
+ { gText_DepositItem, ItemStorage_Deposit },
+ { gText_TossItem, ItemStorage_Toss },
+ { gText_Cancel, ItemStorage_Exit }
+};
+
+static const struct ItemSlot gNewGamePCItems[] =
+{
+ { ITEM_POTION, 1 },
+ { ITEM_NONE, 0 }
+};
+
+const struct MenuAction gMailboxMailOptions[] =
+{
+ { gText_Read, Mailbox_DoMailRead },
+ { gText_MoveToBag, Mailbox_MoveToBag },
+ { gText_Give2, Mailbox_Give },
+ { gText_Cancel2, Mailbox_Cancel }
+};
+
+static const struct WindowTemplate gUnknown_085DFF24[3] =
+{
+ {0x00, 0x01, 0x01, 0x09, 0x06, 0x0F, 0x0001},
+ {0x00, 0x01, 0x01, 0x09, 0x08, 0x0F, 0x0001},
+ {0x00, 0x01, 0x01, 0x0A, 0x08, 0x0F, 0x0001}
+};
+
+static const struct YesNoFuncTable ResumeFromWithdrawYesNoFuncList = // ResumeFromWithdrawYesNoFuncList
+{
+ ItemStorage_ResumeInputFromYesToss,
+ ItemStorage_ResumeInputFromNoToss
+};
+
+static const struct ListMenuTemplate gUnknown_085DFF44 = {
+ NULL,
+ ItemStorage_MoveCursor,
+ fish4_goto_x5_or_x6,
+ 0, 0,
+ 0, 0, 8, 0,
+ 9, 2, 1, 3, FALSE, 0, FALSE, 7
+};
+
+static const struct WindowTemplate gUnknown_085DFF5C[5] =
+{
+ {0x00, 0x10, 0x01, 0x0D, 0x12, 0x0F, 0x0001},
+ {0x00, 0x01, 0x0D, 0x0D, 0x06, 0x0F, 0x00EB},
+ {0x00, 0x01, 0x08, 0x03, 0x03, 0x0F, 0x0153},
+ {0x00, 0x01, 0x01, 0x0D, 0x02, 0x0F, 0x0139},
+ {0x00, 0x08, 0x09, 0x06, 0x02, 0x0F, 0x015C}
+};
+
+static const struct WindowTemplate gUnknown_085DFF84 =
+{
+ 0x00, 0x09, 0x07, 0x05, 0x04, 0x0F, 0x0168
+};
+
+static const u8 gUnknown_085DFF8C[] = {0x01, 0x03, 0x02, 0x00};
+
+// text
+void NewGameInitPCItems(void)
+{
+ u8 i;
+
+ // because Game Freak don't know how to use a struct or a 2d array
+ for(i = 0, ClearItemSlots(gSaveBlock1Ptr->pcItems, ARRAY_COUNT(gSaveBlock1Ptr->pcItems)); NEW_GAME_PC_ITEMS(i, PC_ITEM_ID) && NEW_GAME_PC_ITEMS(i, PC_QUANTITY) &&
+ AddPCItem(NEW_GAME_PC_ITEMS(i, PC_ITEM_ID), NEW_GAME_PC_ITEMS(i, PC_QUANTITY)) == TRUE; i++);
+}
+
+void BedroomPC(void)
+{
+ gPcItemMenuOptionOrder = gBedroomPC_OptionOrder;
+ gPcItemMenuOptionsNum = 4;
+ DisplayItemMessageOnField(CreateTask(TaskDummy, 0), gText_WhatWouldYouLike, InitPlayerPCMenu);
+}
+
+void PlayerPC(void)
+{
+ gPcItemMenuOptionOrder = gPlayerPC_OptionOrder;
+ gPcItemMenuOptionsNum = 3;
+ DisplayItemMessageOnField(CreateTask(TaskDummy, 0), gText_WhatWouldYouLike, InitPlayerPCMenu);
+}
+
+static void InitPlayerPCMenu(u8 taskId)
+{
+ u16 *data;
+ struct WindowTemplate windowTemplate;
+
+ data = gTasks[taskId].data;
+ if(gPcItemMenuOptionsNum == 3)
+ windowTemplate = gUnknown_085DFF24[0];
+ else
+ windowTemplate = gUnknown_085DFF24[1];
+ windowTemplate.width = sub_81DB3D8(sPlayerPCMenuActions, gPcItemMenuOptionOrder, gPcItemMenuOptionsNum);
+ data[4] = AddWindow(&windowTemplate);
+ SetStandardWindowBorderStyle(data[4], 0);
+ sub_81995E4(data[4], gPcItemMenuOptionsNum, sPlayerPCMenuActions, gPcItemMenuOptionOrder);
+ InitMenuInUpperLeftCornerPlaySoundWhenAPressed(data[4], gPcItemMenuOptionsNum, 0);
+ schedule_bg_copy_tilemap_to_vram(0);
+ gTasks[taskId].func = PlayerPCProcessMenuInput;
+}
+
+static void PlayerPCProcessMenuInput(u8 taskId)
+{
+ u16 *data;
+ s8 inputOptionId;
+
+ data = gTasks[taskId].data;
+ if(gPcItemMenuOptionsNum > 3)
+ inputOptionId = ProcessMenuInput();
+ else
+ inputOptionId = ProcessMenuInputNoWrapAround();
+
+ switch(inputOptionId)
+ {
+ case -2:
+ break;
+ case -1:
+ PlaySE(SE_SELECT);
+ sub_8198070(data[4], FALSE);
+ ClearWindowTilemap(data[4]);
+ RemoveWindow(data[4]);
+ schedule_bg_copy_tilemap_to_vram(0);
+ gTasks[taskId].func = PlayerPC_TurnOff;
+ break;
+ default:
+ sub_8198070(data[4], FALSE);
+ ClearWindowTilemap(data[4]);
+ RemoveWindow(data[4]);
+ schedule_bg_copy_tilemap_to_vram(0);
+ gTasks[taskId].func = sPlayerPCMenuActions[gPcItemMenuOptionOrder[inputOptionId]].func.void_u8;
+ break;
+ }
+}
+
+void ReshowPlayerPC(u8 var)
+{
+ DisplayItemMessageOnField(var, gText_WhatWouldYouLike, InitPlayerPCMenu);
+}
+
+static void PlayerPC_ItemStorage(u8 taskId)
+{
+ InitItemStorageMenu(taskId, ITEMPC_MENU_WITHDRAW);
+ gTasks[taskId].func = ItemStorageMenuProcessInput;
+}
+
+static void PlayerPC_Mailbox(u8 taskId)
+{
+ playerPCItemPageInfo.count = GetMailboxMailCount();
+
+ if (playerPCItemPageInfo.count == 0)
+ DisplayItemMessageOnField(taskId, gText_NoMailHere, ReshowPlayerPC);
+ else
+ {
+ playerPCItemPageInfo.cursorPos = 0;
+ playerPCItemPageInfo.itemsAbove = 0;
+ playerPCItemPageInfo.scrollIndicatorId = 0xFF;
+ Mailbox_UpdateMailList();
+ ItemStorage_SetItemAndMailCount(taskId);
+ if(sub_81D1C44(playerPCItemPageInfo.count) == TRUE)
+ {
+ sub_8197434(0, 0);
+ Mailbox_DrawMailboxMenu(taskId);
+ gTasks[taskId].func = Mailbox_ProcessInput;
+ }
+ else
+ DisplayItemMessageOnField(taskId, gText_NoMailHere, ReshowPlayerPC);
+ }
+}
+
+static void PlayerPC_Decoration(u8 var)
+{
+ sub_8126B2C(var); //DoPlayerPCDecoration(var);
+}
+
+static void PlayerPC_TurnOff(u8 taskId)
+{
+ if (gPcItemMenuOptionsNum == 4) // if the option count is 4, we are at the bedroom PC and not player PC, so do gender specific handling.
+ {
+ if (gSaveBlock2Ptr->playerGender == MALE)
+ ScriptContext1_SetupScript(LittlerootTown_BrendansHouse_2F_EventScript_1F863F);
+ else
+ ScriptContext1_SetupScript(LittlerootTown_MaysHouse_2F_EventScript_1F958F);
+ }
+ else
+ {
+ EnableBothScriptContexts();
+ }
+ DestroyTask(taskId);
+}
+
+static void InitItemStorageMenu(u8 taskId, u8 var)
+{
+ u16 *data;
+ struct WindowTemplate windowTemplate;
+
+ data = gTasks[taskId].data;
+ windowTemplate = gUnknown_085DFF24[2];
+ windowTemplate.width = GetMaxWidthInMenuTable(gPCText_ItemPCOptionsText, 4);
+ data[4] = AddWindow(&windowTemplate);
+ SetStandardWindowBorderStyle(data[4], 0);
+ PrintMenuTable(data[4], 4, gPCText_ItemPCOptionsText);
+ InitMenuInUpperLeftCornerPlaySoundWhenAPressed(data[4], 4, var);
+ schedule_bg_copy_tilemap_to_vram(0);
+ ItemStorageMenuPrint(gPCText_OptionDescList[var]);
+}
+
+static void ItemStorageMenuPrint(const u8 *textPtr)
+{
+ NewMenuHelpers_DrawDialogueFrame(0, 0);
+ PrintTextOnWindow(0, 1, textPtr, 0, 1, 0, 0);
+}
+
+static void ItemStorageMenuProcessInput(u8 taskId)
+{
+ s8 r5;
+ s8 r2;
+ s8 inputOptionId;
+
+ r5 = GetMenuCursorPos();
+ inputOptionId = ProcessMenuInput();
+ r2 = GetMenuCursorPos();
+ switch(inputOptionId)
+ {
+ case -2:
+ if (r5 != r2)
+ ItemStorageMenuPrint(gPCText_OptionDescList[r2]);
+ break;
+ case -1:
+ PlaySE(SE_SELECT);
+ ItemStorage_Exit(taskId);
+ break;
+ default:
+ PlaySE(SE_SELECT);
+ gPCText_ItemPCOptionsText[inputOptionId].func.void_u8(taskId);
+ break;
+ }
+}
+
+static void ItemStorage_Deposit(u8 taskId)
+{
+ gTasks[taskId].func = Task_ItemStorage_Deposit;
+ FadeScreen(1, 0);
+}
+
+static void Task_ItemStorage_Deposit(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ overworld_free_bg_tilemaps();
+ sub_81AAC14();
+ DestroyTask(taskId);
+ }
+}
+
+void sub_816B31C(void)
+{
+ gFieldCallback = Mailbox_DoRedrawMailboxMenuAfterReturn;
+ SetMainCallback2(CB2_ReturnToField);
+}
+
+void Mailbox_DoRedrawMailboxMenuAfterReturn(void)
+{
+ sub_81973A4();
+ NewMenuHelpers_DrawDialogueFrame(0, 1);
+ InitItemStorageMenu(CreateTask(ItemStorage_HandleReturnToProcessInput, 0), 1);
+ pal_fill_black();
+}
+
+static void ItemStorage_HandleReturnToProcessInput(u8 taskId)
+{
+ if (IsWeatherNotFadingIn() == TRUE)
+ gTasks[taskId].func = ItemStorageMenuProcessInput;
+}
+
+static void ItemStorage_Withdraw(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ NUM_ITEMS = CountUsedPCItemSlots();
+ if (NUM_ITEMS != 0)
+ ItemStorage_WithdrawToss_Helper(taskId, FALSE);
+ else
+ {
+ sub_816B4DC(taskId);
+ DisplayItemMessageOnField(taskId, gText_NoItems, PlayerPC_ItemStorage);
+ }
+
+}
+
+static void ItemStorage_Toss(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ NUM_ITEMS = CountUsedPCItemSlots();
+ if (NUM_ITEMS != 0)
+ ItemStorage_WithdrawToss_Helper(taskId, TRUE);
+ else
+ {
+ sub_816B4DC(taskId);
+ DisplayItemMessageOnField(taskId, gText_NoItems, PlayerPC_ItemStorage);
+ }
+}
+
+static void ItemStorage_WithdrawToss_Helper(u8 taskId, bool8 toss)
+{
+ u16 *data = gTasks[taskId].data;
+
+ data[3] = toss;
+ sub_816B4DC(taskId);
+ playerPCItemPageInfo.cursorPos = 0;
+ playerPCItemPageInfo.itemsAbove = 0;
+ playerPCItemPageInfo.scrollIndicatorId = 0xFF;
+ ItemStorage_SetItemAndMailCount(taskId);
+ sub_816BC14();
+ gpu_pal_allocator_reset__manage_upper_four();
+ LoadListMenuArrowsGfx();
+ sub_8122344(gUnknown_0203BCC4->spriteIds, 7);
+ sub_8197434(0,0);
+ gTasks[taskId].func = ItemStorage_ProcessWithdrawTossInput;
+}
+
+static void ItemStorage_Exit(u8 taskId)
+{
+ sub_816B4DC(taskId);
+ ReshowPlayerPC(taskId);
+}
+
+
+static void ItemStorage_SetItemAndMailCount(u8 taskId)
+{
+ if (playerPCItemPageInfo.count > 7)
+ playerPCItemPageInfo.pageItems = 8;
+ else
+ playerPCItemPageInfo.pageItems = playerPCItemPageInfo.count + 1;
+}
+
+static void sub_816B4DC(u8 taskId)
+{
+ u16 *data = gTasks[taskId].data;
+
+ sub_8198070(data[4], FALSE);
+ ClearWindowTilemap(data[4]);
+ RemoveWindow(data[4]);
+ schedule_bg_copy_tilemap_to_vram(0);
+}
+
+static u8 GetMailboxMailCount(void)
+{
+ u8 i, j;
+
+ for(i = 0, j = 6; j < 16; j++)
+ if(gSaveBlock1Ptr->mail[j].itemId != 0)
+ i++;
+
+ return i;
+}
+
+static void Mailbox_UpdateMailList(void)
+{
+ struct MailStruct mailBuffer;
+ u8 i, j;
+
+ for (i=6; i<15; i++)
+ {
+ for (j=i+1; j<16; j++)
+ {
+ if (gSaveBlock1Ptr->mail[i].itemId == 0)
+ {
+ mailBuffer = gSaveBlock1Ptr->mail[i];
+ gSaveBlock1Ptr->mail[i] = gSaveBlock1Ptr->mail[j];
+ gSaveBlock1Ptr->mail[j] = mailBuffer;
+ }
+ }
+ }
+}
+
+static void Mailbox_DrawMailboxMenu(u8 taskId)
+{
+ u8 windowId;
+
+ windowId = sub_81D1C84(0);
+ sub_81D1C84(1);
+ PrintTextOnWindow(windowId, 1, gText_Mailbox, GetStringCenterAlignXOffset(1, gText_Mailbox, 0x40), 1, 0, NULL);
+ schedule_bg_copy_tilemap_to_vram(0);
+ gTasks[taskId].data[5] = sub_81D1DC0(&playerPCItemPageInfo);
+ sub_81D1E90(&playerPCItemPageInfo);
+}
+
+static void Mailbox_ProcessInput(u8 taskId)
+{
+ u16 *data = gTasks[taskId].data;
+ s32 inputOptionId;
+
+ if(!gPaletteFade.active)
+ {
+ inputOptionId = ListMenuHandleInputGetItemId(data[5]);
+ ListMenuGetScrollAndRow(data[5], &(playerPCItemPageInfo.itemsAbove), &(playerPCItemPageInfo.cursorPos));
+
+ switch(inputOptionId)
+ {
+ case -1:
+ break;
+ case -2:
+ PlaySE(SE_SELECT);
+ RemoveScrollIndicatorArrowPair(playerPCItemPageInfo.scrollIndicatorId);
+ Mailbox_ReturnToPlayerPC(taskId);
+ break;
+ default:
+ PlaySE(SE_SELECT);
+ sub_81D1D04(0);
+ sub_81D1D04(1);
+ DestroyListMenuTask(data[5], &(playerPCItemPageInfo.itemsAbove), &(playerPCItemPageInfo.cursorPos));
+ schedule_bg_copy_tilemap_to_vram(0);
+ RemoveScrollIndicatorArrowPair(playerPCItemPageInfo.scrollIndicatorId);
+ gTasks[taskId].func = Mailbox_PrintWhatToDoWithPlayerMailText;
+ break;
+ }
+ }
+}
+
+static void Mailbox_PrintWhatToDoWithPlayerMailText(u8 taskId)
+{
+ StringCopy(gStringVar1, gSaveBlock1Ptr->mail[playerPCItemPageInfo.itemsAbove + 6 + playerPCItemPageInfo.cursorPos].playerName);
+ sub_81DB554(gStringVar1, 0);
+ StringExpandPlaceholders(gStringVar4, gText_WhatToDoWithVar1sMail);
+ DisplayItemMessageOnField(taskId, gStringVar4, Mailbox_PrintMailOptions);
+}
+
+static void Mailbox_ReturnToPlayerPC(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ sub_81D1D04(0);
+ sub_81D1D04(1);
+ DestroyListMenuTask(data[5], NULL, NULL);
+ schedule_bg_copy_tilemap_to_vram(0);
+ sub_81D1EC0();
+ ReshowPlayerPC(taskId);
+}
+
+static void Mailbox_PrintMailOptions(u8 taskId)
+{
+ u8 r4 = sub_81D1C84(2);
+ PrintMenuTable(r4, 4, gMailboxMailOptions);
+ InitMenuInUpperLeftCornerPlaySoundWhenAPressed(r4, 4, 0);
+ schedule_bg_copy_tilemap_to_vram(0);
+ gTasks[taskId].func = Mailbox_MailOptionsProcessInput;
+}
+
+static void Mailbox_MailOptionsProcessInput(u8 taskId)
+{
+ s8 inputOptionId = ProcessMenuInput_other();
+
+ switch(inputOptionId)
+ {
+ case -2:
+ break;
+ case -1:
+ PlaySE(SE_SELECT);
+ Mailbox_Cancel(taskId);
+ break;
+
+ default:
+ PlaySE(SE_SELECT);
+ gMailboxMailOptions[inputOptionId].func.void_u8(taskId);
+ break;
+ }
+}
+
+static void Mailbox_DoMailRead(u8 taskId)
+{
+ FadeScreen(1, 0);
+ gTasks[taskId].func = Mailbox_FadeAndReadMail;
+}
+
+static void Mailbox_FadeAndReadMail(u8 taskId)
+{
+ if(!gPaletteFade.active)
+ {
+ sub_81D1EC0();
+ overworld_free_bg_tilemaps();
+ ReadMail(&(gSaveBlock1Ptr->mail[playerPCItemPageInfo.itemsAbove + 6 + playerPCItemPageInfo.cursorPos]), Mailbox_ReturnToFieldFromReadMail, TRUE);
+ DestroyTask(taskId);
+ }
+}
+
+static void Mailbox_ReturnToFieldFromReadMail(void)
+{
+ gFieldCallback = pal_fill_for_maplights_or_black;
+ SetMainCallback2(CB2_ReturnToField);
+}
+
+static void pal_fill_for_maplights_or_black(void)
+{
+ u8 taskId;
+
+ sub_81973A4();
+ taskId = CreateTask(Mailbox_HandleReturnToProcessInput, 0);
+ if(sub_81D1C44(playerPCItemPageInfo.count) == TRUE)
+ Mailbox_DrawMailboxMenu(taskId);
+ else
+ DestroyTask(taskId);
+ pal_fill_black();
+}
+
+static void Mailbox_HandleReturnToProcessInput(u8 taskId)
+{
+ if(IsWeatherNotFadingIn() == TRUE)
+ gTasks[taskId].func = Mailbox_ProcessInput;
+}
+
+static void Mailbox_MoveToBag(u8 taskId)
+{
+ DisplayItemMessageOnField(taskId, gText_MessageWillBeLost, Mailbox_DrawYesNoBeforeMove);
+}
+
+static void Mailbox_DrawYesNoBeforeMove(u8 taskId)
+{
+ sub_8197930();
+ gTasks[taskId].func = Mailbox_MoveToBagYesNoPrompt;
+}
+
+static void Mailbox_MoveToBagYesNoPrompt(u8 taskId)
+{
+ switch(ProcessMenuInputNoWrap_())
+ {
+ case 0:
+ Mailbox_DoMailMoveToBag(taskId);
+ break;
+ case -1:
+ PlaySE(SE_SELECT);
+ case 1:
+ Mailbox_CancelMoveToBag(taskId);
+ break;
+ case -2:
+ default:
+ break;
+ }
+}
+
+static void Mailbox_DoMailMoveToBag(u8 taskId)
+{
+ struct MailStruct *mailStruct = &(gSaveBlock1Ptr->mail[playerPCItemPageInfo.itemsAbove + 6 + playerPCItemPageInfo.cursorPos]);
+ if(!AddBagItem(mailStruct->itemId, 1))
+ {
+ DisplayItemMessageOnField(taskId, gText_BagIsFull, Mailbox_Cancel);
+ }
+ else
+ {
+ DisplayItemMessageOnField(taskId, gText_MailToBagMessageErased, Mailbox_Cancel);
+ ClearMailStruct(mailStruct);
+ Mailbox_UpdateMailList();
+ playerPCItemPageInfo.count--;
+ if(playerPCItemPageInfo.count < (playerPCItemPageInfo.pageItems + playerPCItemPageInfo.itemsAbove) && playerPCItemPageInfo.itemsAbove != 0)
+ playerPCItemPageInfo.itemsAbove--;
+ ItemStorage_SetItemAndMailCount(taskId);
+ }
+}
+
+static void Mailbox_CancelMoveToBag(u8 taskId)
+{
+ Mailbox_Cancel(taskId);
+}
+
+static void Mailbox_Give(u8 taskId)
+{
+ if(CalculatePlayerPartyCount() == 0)
+ Mailbox_NoPokemonForMail(taskId);
+ else
+ {
+ FadeScreen(1, 0);
+ gTasks[taskId].func = Mailbox_DoGiveMailPokeMenu;
+ }
+}
+
+static void Mailbox_DoGiveMailPokeMenu(u8 taskId)
+{
+ if(!gPaletteFade.active)
+ {
+ sub_81D1EC0();
+ overworld_free_bg_tilemaps();
+ sub_81B8448();
+ DestroyTask(taskId);
+ }
+}
+
+void Mailbox_ReturnToMailListAfterDeposit(void)
+{
+ gFieldCallback = Mailbox_UpdateMailListAfterDeposit;
+ SetMainCallback2(CB2_ReturnToField);
+}
+
+static void Mailbox_UpdateMailListAfterDeposit(void)
+{
+ u8 taskId;
+ u8 prevCount;
+ taskId = CreateTask(Mailbox_HandleReturnToProcessInput, 0);
+ prevCount = playerPCItemPageInfo.count;
+ playerPCItemPageInfo.count = GetMailboxMailCount();
+ Mailbox_UpdateMailList();
+ if(prevCount != playerPCItemPageInfo.count && (playerPCItemPageInfo.count < (playerPCItemPageInfo.pageItems + playerPCItemPageInfo.itemsAbove))
+ && playerPCItemPageInfo.itemsAbove != 0)
+ playerPCItemPageInfo.itemsAbove--;
+ ItemStorage_SetItemAndMailCount(taskId);
+ sub_81973A4();
+ if(sub_81D1C44(playerPCItemPageInfo.count) == TRUE)
+ Mailbox_DrawMailboxMenu(taskId);
+ else
+ DestroyTask(taskId);
+ pal_fill_black();
+}
+
+static void Mailbox_NoPokemonForMail(u8 taskId)
+{
+ DisplayItemMessageOnField(taskId, gText_NoPokemon, Mailbox_Cancel);
+}
+
+static void Mailbox_Cancel(u8 taskId)
+{
+ sub_81D1D04(2);
+ sub_8197434(0, 0);
+ Mailbox_DrawMailboxMenu(taskId);
+ schedule_bg_copy_tilemap_to_vram(0);
+ gTasks[taskId].func = Mailbox_ProcessInput;
+}
+
+static void sub_816BC14(void)
+{
+ gUnknown_0203BCC4 = AllocZeroed(sizeof(struct Struct203BCC4));
+ memset(gUnknown_0203BCC4->windowIds, 0xFF, 0x6);
+ gUnknown_0203BCC4->unk666 = 0xFF;
+ gUnknown_0203BCC4->spriteId = 0xFF;
+}
+
+static void sub_816BC58(void)
+{
+ u32 i;
+
+ for(i = 0; i < 6; i++)
+ sub_816BCC4(i);
+ Free(gUnknown_0203BCC4);
+}
+
+static u8 sub_816BC7C(u8 a)
+{
+ u8 *windowIdLoc = &(gUnknown_0203BCC4->windowIds[a]);
+ if(*windowIdLoc == 0xFF)
+ {
+ *windowIdLoc = AddWindow(&gUnknown_085DFF5C[a]);
+ SetWindowBorderStyle(*windowIdLoc, FALSE, 0x214, 0xE);
+ schedule_bg_copy_tilemap_to_vram(0);
+ }
+ return *windowIdLoc;
+}
+
+static void sub_816BCC4(u8 a)
+{
+ u8 *windowIdLoc = &(gUnknown_0203BCC4->windowIds[a]);
+ if(*windowIdLoc != 0xFF)
+ {
+ sub_8198070(*windowIdLoc, FALSE);
+ ClearWindowTilemap(*windowIdLoc);
+ schedule_bg_copy_tilemap_to_vram(0);
+ RemoveWindow(*windowIdLoc);
+ *windowIdLoc = 0xFF;
+ }
+}
+
+void ItemStorage_RefreshListMenu(void)
+{
+ u16 i;
+
+ for(i = 0; i < playerPCItemPageInfo.count - 1; i++)
+ {
+ CopyItemName_PlayerPC(&(gUnknown_0203BCC4->unk198[i][0]), gSaveBlock1Ptr->pcItems[i].itemId);
+ gUnknown_0203BCC4->unk0[i].name = &(gUnknown_0203BCC4->unk198[i][0]);
+ gUnknown_0203BCC4->unk0[i].id = i;
+ }
+ StringCopy(&(gUnknown_0203BCC4->unk198[i][0]) ,gText_Cancel2);
+ gUnknown_0203BCC4->unk0[i].name = &(gUnknown_0203BCC4->unk198[i][0]);
+ gUnknown_0203BCC4->unk0[i].id = -2;
+ gMultiuseListMenuTemplate = gUnknown_085DFF44;
+ gMultiuseListMenuTemplate.windowId = sub_816BC7C(0);
+ gMultiuseListMenuTemplate.totalItems = playerPCItemPageInfo.count;
+ gMultiuseListMenuTemplate.items = gUnknown_0203BCC4->unk0;
+ gMultiuseListMenuTemplate.maxShowed = playerPCItemPageInfo.pageItems;
+}
+
+void CopyItemName_PlayerPC(u8 *string, u16 itemId)
+{
+ CopyItemName(itemId, string);
+}
+
+static void ItemStorage_MoveCursor(s32 id, bool8 b, struct ListMenu *thisMenu)
+{
+ if(b != TRUE)
+ PlaySE(SE_SELECT);
+ if(gUnknown_0203BCC4->unk666 == 0xFF)
+ {
+ sub_816C0C8();
+ if(id != -2)
+ sub_816C060(gSaveBlock1Ptr->pcItems[id].itemId);
+ else
+ sub_816C060(ITEMPC_GO_BACK_TO_PREV);
+ sub_816BEF0(id);
+ }
+}
+
+static void fish4_goto_x5_or_x6(u8 windowId, s32 id, u8 yOffset)
+{
+ if(id != -2)
+ {
+ if(gUnknown_0203BCC4->unk666 != 0xFF)
+ {
+ if(gUnknown_0203BCC4->unk666 == (u8)id)
+ sub_816BFE0(yOffset, 0, 0xFF);
+ else
+ sub_816BFE0(yOffset, 0xFF, 0xFF);
+ }
+ ConvertIntToDecimalStringN(gStringVar1, gSaveBlock1Ptr->pcItems[id].quantity, STR_CONV_MODE_RIGHT_ALIGN, 3);
+ StringExpandPlaceholders(gStringVar4, gText_xVar1);
+ PrintTextOnWindow(windowId, 7, gStringVar4, GetStringRightAlignXOffset(7, gStringVar4, 104), yOffset, 0xFF, NULL);
+ }
+}
+
+static void sub_816BEF0(s32 id)
+{
+ const u8* description;
+ u8 windowId = gUnknown_0203BCC4->windowIds[1];
+
+ if(id != -2)
+ description = (u8 *)ItemId_GetDescription(gSaveBlock1Ptr->pcItems[id].itemId);
+ else
+ description = ItemStorage_GetItemPcResponse(ITEMPC_GO_BACK_TO_PREV);
+ FillWindowPixelBuffer(windowId, 17);
+ PrintTextOnWindow(windowId, 1, description, 0, 1, 0, NULL);
+}
+
+static void ItemStorage_StartScrollIndicator(void)
+{
+ if(playerPCItemPageInfo.scrollIndicatorId == 0xFF)
+ playerPCItemPageInfo.scrollIndicatorId = AddScrollIndicatorArrowPairParametrized(0x2, 0xB0, 0xC, 0x94, playerPCItemPageInfo.count - playerPCItemPageInfo.pageItems, 0x13F8, 0x13F8, &(playerPCItemPageInfo.itemsAbove));
+}
+
+static void ItemStorage_RemoveScrollIndicator(void)
+{
+ if(playerPCItemPageInfo.scrollIndicatorId != 0xFF)
+ {
+ RemoveScrollIndicatorArrowPair(playerPCItemPageInfo.scrollIndicatorId);
+ playerPCItemPageInfo.scrollIndicatorId = 0xFF;
+ }
+}
+
+static void sub_816BFB8(u8 a, u8 b, u8 speed)
+{
+ sub_816BFE0(ListMenuGetYCoordForPrintingArrowCursor(a), b, speed);
+}
+
+static void sub_816BFE0(u8 y, u8 b, u8 speed)
+{
+ u8 windowId = gUnknown_0203BCC4->windowIds[0];
+ if(b == 0xFF)
+ FillWindowPixelRect(windowId, 17, 0, y, GetMenuCursorDimensionByFont(1, 0), GetMenuCursorDimensionByFont(1, 1));
+ else
+ AddTextPrinterParameterized2(windowId, 1, 0, y, 0, 0, gUnknown_085DFF8C, speed, gText_SelectorArrow2);
+}
+
+static void sub_816C060(u16 itemId)
+{
+ u8 spriteId;
+ u8* spriteIdLoc = &(gUnknown_0203BCC4->spriteId);
+
+ if(*spriteIdLoc == 0xFF)
+ {
+ FreeSpriteTilesByTag(0x13F6);
+ FreeSpritePaletteByTag(0x13F6);
+ spriteId = AddItemIconSprite(0x13F6, 0x13F6, itemId);
+ if(spriteId != 64)
+ {
+ *spriteIdLoc = spriteId;
+ gSprites[spriteId].oam.priority = 0;
+ gSprites[spriteId].pos2.x = 24;
+ gSprites[spriteId].pos2.y = 80;
+ }
+ }
+}
+
+static void sub_816C0C8(void)
+{
+ u8* spriteIdLoc = &(gUnknown_0203BCC4->spriteId);
+ if(*spriteIdLoc != 0xFF)
+ {
+ FreeSpriteTilesByTag(0x13F6);
+ FreeSpritePaletteByTag(0x13F6);
+ DestroySprite(&(gSprites[*spriteIdLoc]));
+ *spriteIdLoc = 0xFF;
+ }
+}
+
+static void sub_816C110(void)
+{
+ CompactPCItems();
+ sub_812220C(gSaveBlock1Ptr->pcItems, 50, &(playerPCItemPageInfo.pageItems), &(playerPCItemPageInfo.count), 0x8);
+}
+
+static void sub_816C140(void)
+{
+ sub_812225C(&(playerPCItemPageInfo.itemsAbove), &(playerPCItemPageInfo.cursorPos), playerPCItemPageInfo.pageItems, playerPCItemPageInfo.count);
+}
+
+static void ItemStorage_ProcessWithdrawTossInput(u8 taskId)
+{
+ s16 *data;
+ bool32 toss;
+ u32 i, x;
+ u8 windowId;
+ const u8* text;
+
+ data = gTasks[taskId].data;
+ for(i = 0; i <=3; i++)
+ sub_816BC7C(i);
+ toss = data[3];
+ text = gText_TossItem;
+ if(!toss)
+ text = gText_WithdrawItem;
+ x = GetStringCenterAlignXOffset(1, text, 104);
+ PrintTextOnWindow(gUnknown_0203BCC4->windowIds[3], 1, text, x, 1, 0, NULL);
+ CopyWindowToVram(gUnknown_0203BCC4->windowIds[2], 2);
+ sub_816C110();
+ sub_816C140();
+ ItemStorage_RefreshListMenu();
+ data[5] = ListMenuInit(&gMultiuseListMenuTemplate, playerPCItemPageInfo.itemsAbove, playerPCItemPageInfo.cursorPos);
+ ItemStorage_StartScrollIndicator();
+ schedule_bg_copy_tilemap_to_vram(0);
+ gTasks[taskId].func = ItemStorage_ProcessInput;
+}
+
+static const u8* ItemStorage_GetItemPcResponse(u16 itemId)
+{
+ const u8 *string;
+
+ switch(itemId)
+ {
+ case ITEMPC_GO_BACK_TO_PREV:
+ string = gText_GoBackPrevMenu;
+ break;
+ case ITEMPC_HOW_MANY_TO_WITHDRAW:
+ string = gText_WithdrawHowManyItems;
+ break;
+ case ITEMPC_WITHDREW_THING:
+ string = gText_WithdrawXItems;
+ break;
+ case ITEMPC_HOW_MANY_TO_TOSS:
+ string = gText_TossHowManyVar1s;
+ break;
+ case ITEMPC_THREW_AWAY_ITEM:
+ string = gText_ThrewAwayVar2Var1s;
+ break;
+ case ITEMPC_NO_MORE_ROOM:
+ string = gText_NoRoomInBag;
+ break;
+ case ITEMPC_TOO_IMPORTANT:
+ string = gText_TooImportantToToss;
+ break;
+ case ITEMPC_OKAY_TO_THROW_AWAY:
+ string = gText_ConfirmTossItems;
+ break;
+ case ITEMPC_SWITCH_WHICH_ITEM:
+ string = gText_MoveVar1Where;
+ break;
+ default:
+ string = ItemId_GetDescription(itemId);
+ break;
+ }
+ return string;
+}
+
+static void ItemStorage_PrintItemPcResponse(const u8 *string)
+{
+ u8 windowId = gUnknown_0203BCC4->windowIds[1];
+ FillWindowPixelBuffer(windowId, 0x11);
+ StringExpandPlaceholders(gStringVar4, string);
+ PrintTextOnWindow(windowId, 1, gStringVar4, 0, 1, 0, NULL);
+}
+
+static void ItemStorage_ProcessInput(u8 taskId)
+{
+ s16 *data;
+ s32 id;
+
+ data = gTasks[taskId].data;
+ if(gMain.newKeys & SELECT_BUTTON)
+ {
+ ListMenuGetScrollAndRow(data[5], &(playerPCItemPageInfo.itemsAbove), &(playerPCItemPageInfo.cursorPos));
+ if((playerPCItemPageInfo.itemsAbove + playerPCItemPageInfo.cursorPos) != (playerPCItemPageInfo.count - 1))
+ {
+ PlaySE(SE_SELECT);
+ ItemStorage_ItemSwapChoosePrompt(taskId);
+ }
+ }
+ else
+ {
+ id = ListMenuHandleInputGetItemId(data[5]);
+ ListMenuGetScrollAndRow(data[5], &(playerPCItemPageInfo.itemsAbove), &(playerPCItemPageInfo.cursorPos));
+ switch(id)
+ {
+ case -1:
+ break;
+ case -2:
+ PlaySE(SE_SELECT);
+ ItemStorage_GoBackToPlayerPCMenu(taskId);
+ break;
+ default:
+ PlaySE(SE_SELECT);
+ ItemStorage_DoItemAction(taskId);
+ break;
+ }
+ }
+}
+
+static void ItemStorage_GoBackToPlayerPCMenu_InitStorage(u8 taskId)
+{
+ s16 *data;
+
+ data = gTasks[taskId].data;
+ if(!IsDma3ManagerBusyWithBgCopy())
+ {
+ NewMenuHelpers_DrawDialogueFrame(0, 0);
+ if(!data[3])
+ InitItemStorageMenu(taskId, ITEMPC_MENU_WITHDRAW);
+ else
+ InitItemStorageMenu(taskId, ITEMPC_MENU_TOSS);
+ gTasks[taskId].func = ItemStorageMenuProcessInput;
+ }
+}
+
+static void ItemStorage_GoBackToPlayerPCMenu(u8 taskId)
+{
+ s16 *data;
+
+ data = gTasks[taskId].data;
+ sub_816C0C8();
+ ItemStorage_RemoveScrollIndicator();
+ DestroyListMenuTask(data[5], NULL, NULL);
+ sub_81223B0(gUnknown_0203BCC4->spriteIds, 7);
+ sub_816BC58();
+ gTasks[taskId].func = ItemStorage_GoBackToPlayerPCMenu_InitStorage;
+}
+
+static void ItemStorage_ItemSwapChoosePrompt(u8 taskId)
+{
+ s16 *data;
+
+ data = gTasks[taskId].data;
+ sub_81AF15C(data[5], 16, 1);
+ gUnknown_0203BCC4->unk666 = (playerPCItemPageInfo.itemsAbove + playerPCItemPageInfo.cursorPos);
+ sub_816BFB8(data[5], 0, 0);
+ sub_816C690(gUnknown_0203BCC4->unk666);
+ CopyItemName(gSaveBlock1Ptr->pcItems[gUnknown_0203BCC4->unk666].itemId, gStringVar1);
+ ItemStorage_PrintItemPcResponse(ItemStorage_GetItemPcResponse(ITEMPC_SWITCH_WHICH_ITEM));
+ gTasks[taskId].func = sub_816C4FC;
+}
+
+static void sub_816C4FC(u8 taskId)
+{
+ s16 *data;
+ s32 id;
+
+ data = gTasks[taskId].data;
+ if(gMain.newKeys & SELECT_BUTTON)
+ {
+ ListMenuGetScrollAndRow(data[5], &(playerPCItemPageInfo.itemsAbove), &(playerPCItemPageInfo.cursorPos));
+ ItemStorage_DoItemSwap(taskId, FALSE);
+ return;
+ }
+ id = ListMenuHandleInputGetItemId(data[5]);
+ ListMenuGetScrollAndRow(data[5], &(playerPCItemPageInfo.itemsAbove), &(playerPCItemPageInfo.cursorPos));
+ sub_81223FC(gUnknown_0203BCC4->spriteIds, 7, 0);
+ sub_816C690(playerPCItemPageInfo.cursorPos);
+ switch(id)
+ {
+ case -1:
+ break;
+ case -2:
+ if(gMain.newKeys & A_BUTTON)
+ {
+ ItemStorage_DoItemSwap(taskId, FALSE);
+ }
+ else
+ ItemStorage_DoItemSwap(taskId, TRUE);
+ break;
+ default:
+ ItemStorage_DoItemSwap(taskId, FALSE);
+ break;
+ }
+}
+
+static void ItemStorage_DoItemSwap(u8 taskId, bool8 a)
+{
+ s16 *data;
+ u16 b;
+ u8 c;
+
+ data = gTasks[taskId].data;
+ b = (playerPCItemPageInfo.itemsAbove + playerPCItemPageInfo.cursorPos);
+ PlaySE(SE_SELECT);
+ DestroyListMenuTask(data[5], &(playerPCItemPageInfo.itemsAbove), &(playerPCItemPageInfo.cursorPos));
+ if(!a)
+ {
+ c = gUnknown_0203BCC4->unk666;
+ if(c != b)
+ {
+ if(c != b - 1)
+ {
+ MoveItemSlotInList(gSaveBlock1Ptr->pcItems, c, b);
+ ItemStorage_RefreshListMenu();
+ }
+ }
+ else
+ goto LABEL_SKIP_CURSOR_DECREMENT;
+ }
+ if (gUnknown_0203BCC4->unk666 < b)
+ playerPCItemPageInfo.cursorPos--;
+ LABEL_SKIP_CURSOR_DECREMENT:
+ sub_81223FC(gUnknown_0203BCC4->spriteIds, 7, 1);
+ gUnknown_0203BCC4->unk666 = 0xFF;
+ data[5] = ListMenuInit(&gMultiuseListMenuTemplate, playerPCItemPageInfo.itemsAbove, playerPCItemPageInfo.cursorPos);
+ schedule_bg_copy_tilemap_to_vram(0);
+ gTasks[taskId].func = ItemStorage_ProcessInput;
+}
+
+static void sub_816C690(u8 a)
+{
+ sub_8122448(gUnknown_0203BCC4->spriteIds, 7, 128, ((a+1) * 16));
+}
+
+static void sub_816C6BC(u8 windowId, u16 value, u32 mode, u8 x, u8 y, u8 n)
+{
+ ConvertIntToDecimalStringN(gStringVar1, value, mode, n);
+ StringExpandPlaceholders(gStringVar4, gText_xVar1);
+ PrintTextOnWindow(windowId, 1, gStringVar4, GetStringCenterAlignXOffset(1, gStringVar4, 48), y, 0, NULL);
+}
+
+static void ItemStorage_DoItemAction(u8 taskId)
+{
+ s16 *data;
+ u16 b;
+
+ data = gTasks[taskId].data;
+ b = (playerPCItemPageInfo.cursorPos + playerPCItemPageInfo.itemsAbove);
+ ItemStorage_RemoveScrollIndicator();
+ data[2] = 1;
+ if(!data[3])
+ {
+ if(gSaveBlock1Ptr->pcItems[b].quantity == 1)
+ {
+ ItemStorage_DoItemWithdraw(taskId);
+ return;
+ }
+ CopyItemName(gSaveBlock1Ptr->pcItems[b].itemId, gStringVar1);
+ ItemStorage_PrintItemPcResponse(ItemStorage_GetItemPcResponse(ITEMPC_HOW_MANY_TO_WITHDRAW));
+ }
+ else
+ {
+ if(gSaveBlock1Ptr->pcItems[b].quantity == 1)
+ {
+ ItemStorage_DoItemToss(taskId);
+ return;
+ }
+ CopyItemName(gSaveBlock1Ptr->pcItems[b].itemId, gStringVar1);
+ ItemStorage_PrintItemPcResponse(ItemStorage_GetItemPcResponse(ITEMPC_HOW_MANY_TO_TOSS));
+ }
+ sub_816C6BC(sub_816BC7C(4), data[2], STR_CONV_MODE_LEADING_ZEROS, 8, 1, 3);
+ gTasks[taskId].func = ItemStorage_HandleQuantityRolling;
+}
+
+static void ItemStorage_HandleQuantityRolling(u8 taskId)
+{
+ s16 *data;
+ u16 b;
+
+ data = gTasks[taskId].data;
+ b = (playerPCItemPageInfo.cursorPos + playerPCItemPageInfo.itemsAbove);
+ if(AdjustQuantityAccordingToDPadInput(&(data[2]), gSaveBlock1Ptr->pcItems[b].quantity) == TRUE)
+ sub_816C6BC(sub_816BC7C(4), data[2], STR_CONV_MODE_LEADING_ZEROS, 8, 1, 3);
+ else
+ {
+ if(gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ sub_816BCC4(4);
+ if(!data[3])
+ ItemStorage_DoItemWithdraw(taskId);
+ else
+ ItemStorage_DoItemToss(taskId);
+ }
+ else if(gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ sub_816BCC4(4);
+ ItemStorage_PrintItemPcResponse(ItemStorage_GetItemPcResponse(gSaveBlock1Ptr->pcItems[b].itemId));
+ ItemStorage_StartScrollIndicatorAndProcessInput(taskId);
+ }
+ }
+}
+
+static void ItemStorage_DoItemWithdraw(u8 taskId)
+{
+ s16 *data;
+ u16 b;
+
+ data = gTasks[taskId].data;
+ b = (playerPCItemPageInfo.cursorPos + playerPCItemPageInfo.itemsAbove);
+ if(AddBagItem(gSaveBlock1Ptr->pcItems[b].itemId, data[2]) == TRUE)
+ {
+ CopyItemName(gSaveBlock1Ptr->pcItems[b].itemId, gStringVar1);
+ ConvertIntToDecimalStringN(gStringVar2, data[2], STR_CONV_MODE_LEFT_ALIGN, 3);
+ ItemStorage_PrintItemPcResponse(ItemStorage_GetItemPcResponse(ITEMPC_WITHDREW_THING));
+ gTasks[taskId].func = ItemStorage_HandleRemoveItem;
+ }
+ else
+ {
+ data[2] = 0;
+ ItemStorage_PrintItemPcResponse(ItemStorage_GetItemPcResponse(ITEMPC_NO_MORE_ROOM));
+ gTasks[taskId].func = ItemStorage_WaitPressHandleResumeProcessInput;
+ }
+}
+
+static void ItemStorage_DoItemToss(u8 taskId)
+{
+ s16 *data;
+ u16 b;
+
+ data = gTasks[taskId].data;
+ b = (playerPCItemPageInfo.cursorPos + playerPCItemPageInfo.itemsAbove);
+ if(!ItemId_GetImportance(gSaveBlock1Ptr->pcItems[b].itemId))
+ {
+ CopyItemName(gSaveBlock1Ptr->pcItems[b].itemId, gStringVar1);
+ ConvertIntToDecimalStringN(gStringVar2, data[2], STR_CONV_MODE_LEFT_ALIGN, 3);
+ ItemStorage_PrintItemPcResponse(ItemStorage_GetItemPcResponse(ITEMPC_OKAY_TO_THROW_AWAY));
+ CreateYesNoMenuWithCallbacks(taskId, &gUnknown_085DFF84, 1, 0, 1, 0x214, 0xE, &ResumeFromWithdrawYesNoFuncList);
+ }
+ else
+ {
+ data[2] = 0;
+ ItemStorage_PrintItemPcResponse(ItemStorage_GetItemPcResponse(ITEMPC_TOO_IMPORTANT));
+ gTasks[taskId].func = ItemStorage_WaitPressHandleResumeProcessInput;
+ }
+}
+
+static void ItemStorage_ResumeInputFromYesToss(u8 taskId)
+{
+ ItemStorage_PrintItemPcResponse(ItemStorage_GetItemPcResponse(ITEMPC_THREW_AWAY_ITEM));
+ gTasks[taskId].func = ItemStorage_HandleRemoveItem;
+}
+
+static void ItemStorage_ResumeInputFromNoToss(u8 taskId)
+{
+ ItemStorage_PrintItemPcResponse(ItemStorage_GetItemPcResponse(gSaveBlock1Ptr->pcItems[(playerPCItemPageInfo.itemsAbove + playerPCItemPageInfo.cursorPos)].itemId));
+ ItemStorage_StartScrollIndicatorAndProcessInput(taskId);
+}
+
+static void ItemStorage_HandleRemoveItem(u8 taskId)
+{
+ s16 *data;
+
+ data = gTasks[taskId].data;
+ if(gMain.newKeys & (A_BUTTON | B_BUTTON))
+ {
+ RemovePCItem((playerPCItemPageInfo.cursorPos + playerPCItemPageInfo.itemsAbove), data[2]);
+ DestroyListMenuTask(data[5], &(playerPCItemPageInfo.itemsAbove), &(playerPCItemPageInfo.cursorPos));
+ sub_816C110();
+ sub_816C140();
+ ItemStorage_RefreshListMenu();
+ data[5] = ListMenuInit(&gMultiuseListMenuTemplate, playerPCItemPageInfo.itemsAbove, playerPCItemPageInfo.cursorPos);
+ ItemStorage_StartScrollIndicatorAndProcessInput(taskId);
+ }
+}
+
+static void ItemStorage_WaitPressHandleResumeProcessInput(u8 taskId)
+{
+ s16 *data;
+
+ data = gTasks[taskId].data;
+ if(gMain.newKeys & (A_BUTTON | B_BUTTON))
+ {
+ ItemStorage_PrintItemPcResponse(ItemStorage_GetItemPcResponse(gSaveBlock1Ptr->pcItems[(playerPCItemPageInfo.itemsAbove + playerPCItemPageInfo.cursorPos)].itemId));
+ ItemStorage_StartScrollIndicatorAndProcessInput(taskId);
+ }
+}
+
+static void ItemStorage_StartScrollIndicatorAndProcessInput(u8 taskId)
+{
+ ItemStorage_StartScrollIndicator();
+ gTasks[taskId].func = ItemStorage_ProcessInput;
+}
diff --git a/src/pokeball.c b/src/pokeball.c
index 795a33827..8173c4a90 100644
--- a/src/pokeball.c
+++ b/src/pokeball.c
@@ -43,7 +43,7 @@ static void sub_80768F0(struct Sprite *sprite);
static void sub_80769A8(struct Sprite *sprite);
static void sub_80769CC(struct Sprite *sprite);
static void SpriteCB_HitAnimHealthoxEffect(struct Sprite *sprite);
-static u16 GetBankPokeballItemId(u8 bank);
+static u16 GetBattlerPokeballItemId(u8 battlerId);
// rom const data
@@ -317,11 +317,11 @@ const struct SpriteTemplate gBallSpriteTemplates[POKEBALL_COUNT] =
},
};
-#define tFrames data[0]
-#define tPan data[1]
-#define tThrowId data[2]
-#define tBank data[3]
-#define tOpponentBank data[4]
+#define tFrames data[0]
+#define tPan data[1]
+#define tThrowId data[2]
+#define tBattler data[3]
+#define tOpponentBattler data[4]
u8 DoPokeballSendOutAnimation(s16 pan, u8 kindOfThrow)
{
@@ -333,17 +333,17 @@ u8 DoPokeballSendOutAnimation(s16 pan, u8 kindOfThrow)
taskId = CreateTask(Task_DoPokeballSendOutAnim, 5);
gTasks[taskId].tPan = pan;
gTasks[taskId].tThrowId = kindOfThrow;
- gTasks[taskId].tBank = gActiveBattler;
+ gTasks[taskId].tBattler = gActiveBattler;
return 0;
}
-#define sBank data[6]
+#define sBattler data[6]
static void Task_DoPokeballSendOutAnim(u8 taskId)
{
u16 throwCaseId;
- u8 bank;
+ u8 battlerId;
u16 itemId, ballId;
u8 ballSpriteId;
bool8 notSendOut = FALSE;
@@ -355,12 +355,12 @@ static void Task_DoPokeballSendOutAnim(u8 taskId)
}
throwCaseId = gTasks[taskId].tThrowId;
- bank = gTasks[taskId].tBank;
+ battlerId = gTasks[taskId].tBattler;
- if (GetBattlerSide(bank) != B_SIDE_PLAYER)
- itemId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[bank]], MON_DATA_POKEBALL);
+ if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
+ itemId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_POKEBALL);
else
- itemId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_POKEBALL);
+ itemId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_POKEBALL);
ballId = ItemIdToBallId(itemId);
LoadBallGfx(ballId);
@@ -372,15 +372,15 @@ static void Task_DoPokeballSendOutAnim(u8 taskId)
switch (throwCaseId)
{
case POKEBALL_PLAYER_SENDOUT:
- gBattlerTarget = bank;
+ gBattlerTarget = battlerId;
gSprites[ballSpriteId].pos1.x = 24;
gSprites[ballSpriteId].pos1.y = 68;
gSprites[ballSpriteId].callback = SpriteCB_PlayerMonSendOut_1;
break;
case POKEBALL_OPPONENT_SENDOUT:
- gSprites[ballSpriteId].pos1.x = GetBattlerSpriteCoord(bank, BANK_X_POS);
- gSprites[ballSpriteId].pos1.y = GetBattlerSpriteCoord(bank, BANK_Y_POS) + 24;
- gBattlerTarget = bank;
+ gSprites[ballSpriteId].pos1.x = GetBattlerSpriteCoord(battlerId, BANK_X_POS);
+ gSprites[ballSpriteId].pos1.y = GetBattlerSpriteCoord(battlerId, BANK_Y_POS) + 24;
+ gBattlerTarget = battlerId;
gSprites[ballSpriteId].data[0] = 0;
gSprites[ballSpriteId].callback = SpriteCB_OpponentMonSendOut;
break;
@@ -390,7 +390,7 @@ static void Task_DoPokeballSendOutAnim(u8 taskId)
break;
}
- gSprites[ballSpriteId].sBank = gBattlerTarget;
+ gSprites[ballSpriteId].sBattler = gBattlerTarget;
if (!notSendOut)
{
DestroyTask(taskId);
@@ -404,7 +404,7 @@ static void Task_DoPokeballSendOutAnim(u8 taskId)
gSprites[ballSpriteId].data[5] = -40;
sub_80A68D4(&gSprites[ballSpriteId]);
gSprites[ballSpriteId].oam.affineParam = taskId;
- gTasks[taskId].tOpponentBank = gBattlerTarget;
+ gTasks[taskId].tOpponentBattler = gBattlerTarget;
gTasks[taskId].func = TaskDummy;
PlaySE(SE_NAGERU);
}
@@ -415,7 +415,7 @@ static void SpriteCB_TestBallThrow(struct Sprite *sprite)
{
u16 ballId;
u8 taskId = sprite->oam.affineParam;
- u8 opponentBank = gTasks[taskId].tOpponentBank;
+ u8 opponentBattler = gTasks[taskId].tOpponentBattler;
u8 noOfShakes = gTasks[taskId].tThrowId;
StartSpriteAnim(sprite, 1);
@@ -425,10 +425,10 @@ static void SpriteCB_TestBallThrow(struct Sprite *sprite)
sprite->pos2.x = 0;
sprite->pos2.y = 0;
sprite->data[5] = 0;
- ballId = ItemIdToBallId(GetBankPokeballItemId(opponentBank));
+ ballId = ItemIdToBallId(GetBattlerPokeballItemId(opponentBattler));
LaunchBallStarsTask(sprite->pos1.x, sprite->pos1.y - 5, 1, 0x1C, ballId);
- sprite->data[0] = LaunchBallFadeMonTask(FALSE, opponentBank, 14, ballId);
- sprite->sBank = opponentBank;
+ sprite->data[0] = LaunchBallFadeMonTask(FALSE, opponentBattler, 14, ballId);
+ sprite->sBattler = opponentBattler;
sprite->data[7] = noOfShakes;
DestroyTask(taskId);
sprite->callback = sub_80756D4;
@@ -438,8 +438,8 @@ static void SpriteCB_TestBallThrow(struct Sprite *sprite)
#undef tFrames
#undef tPan
#undef tThrowId
-#undef tBank
-#undef tOpponentBank
+#undef tBattler
+#undef tOpponentBattler
static void sub_80756D4(struct Sprite *sprite)
{
@@ -452,9 +452,9 @@ static void sub_80756E0(struct Sprite *sprite)
{
sprite->data[5] = 0;
sprite->callback = sub_807574C;
- StartSpriteAffineAnim(&gSprites[gBattlerSpriteIds[sprite->sBank]], 2);
- AnimateSprite(&gSprites[gBattlerSpriteIds[sprite->sBank]]);
- gSprites[gBattlerSpriteIds[sprite->sBank]].data[1] = 0;
+ StartSpriteAffineAnim(&gSprites[gBattlerSpriteIds[sprite->sBattler]], 2);
+ AnimateSprite(&gSprites[gBattlerSpriteIds[sprite->sBattler]]);
+ gSprites[gBattlerSpriteIds[sprite->sBattler]].data[1] = 0;
}
}
@@ -463,17 +463,17 @@ static void sub_807574C(struct Sprite *sprite)
sprite->data[5]++;
if (sprite->data[5] == 11)
PlaySE(SE_SUIKOMU);
- if (gSprites[gBattlerSpriteIds[sprite->sBank]].affineAnimEnded)
+ if (gSprites[gBattlerSpriteIds[sprite->sBattler]].affineAnimEnded)
{
StartSpriteAnim(sprite, 2);
- gSprites[gBattlerSpriteIds[sprite->sBank]].invisible = TRUE;
+ gSprites[gBattlerSpriteIds[sprite->sBattler]].invisible = TRUE;
sprite->data[5] = 0;
sprite->callback = sub_80757E4;
}
else
{
- gSprites[gBattlerSpriteIds[sprite->sBank]].data[1] += 0x60;
- gSprites[gBattlerSpriteIds[sprite->sBank]].pos2.y = -gSprites[gBattlerSpriteIds[sprite->sBank]].data[1] >> 8;
+ gSprites[gBattlerSpriteIds[sprite->sBattler]].data[1] += 0x60;
+ gSprites[gBattlerSpriteIds[sprite->sBattler]].pos2.y = -gSprites[gBattlerSpriteIds[sprite->sBattler]].data[1] >> 8;
}
}
@@ -641,7 +641,7 @@ static void sub_8075970(struct Sprite *sprite)
#define tCryTaskSpecies data[0]
#define tCryTaskPan data[1]
#define tCryTaskWantedCry data[2]
-#define tCryTaskBank data[3]
+#define tCryTaskBattler data[3]
#define tCryTaskMonSpriteId data[4]
#define tCryTaskMonPtr1 data[5]
#define tCryTaskMonPtr2 data[6]
@@ -653,7 +653,7 @@ static void Task_PlayCryWhenReleasedFromBall(u8 taskId)
u8 wantedCry = gTasks[taskId].tCryTaskWantedCry;
s8 pan = gTasks[taskId].tCryTaskPan;
u16 species = gTasks[taskId].tCryTaskSpecies;
- u8 bank = gTasks[taskId].tCryTaskBank;
+ u8 battlerId = gTasks[taskId].tCryTaskBattler;
u8 monSpriteId = gTasks[taskId].tCryTaskMonSpriteId;
struct Pokemon *mon = (void*)(u32)((gTasks[taskId].tCryTaskMonPtr1 << 0x10) | (u16)(gTasks[taskId].tCryTaskMonPtr2));
@@ -669,7 +669,7 @@ static void Task_PlayCryWhenReleasedFromBall(u8 taskId)
PlayCry3(species, pan, 0);
else
PlayCry3(species, pan, 11);
- gBattleSpritesDataPtr->healthBoxesData[bank].field_1_x40 = 0;
+ gBattleSpritesDataPtr->healthBoxesData[battlerId].field_1_x40 = 0;
DestroyTask(taskId);
break;
case 2:
@@ -685,7 +685,7 @@ static void Task_PlayCryWhenReleasedFromBall(u8 taskId)
else
PlayCry4(species, pan, 12);
- gBattleSpritesDataPtr->healthBoxesData[bank].field_1_x40 = 0;
+ gBattleSpritesDataPtr->healthBoxesData[battlerId].field_1_x40 = 0;
DestroyTask(taskId);
}
else
@@ -724,7 +724,7 @@ static void Task_PlayCryWhenReleasedFromBall(u8 taskId)
else
PlayCry4(species, pan, 11);
- gBattleSpritesDataPtr->healthBoxesData[bank].field_1_x40 = 0;
+ gBattleSpritesDataPtr->healthBoxesData[battlerId].field_1_x40 = 0;
DestroyTask(taskId);
break;
}
@@ -732,13 +732,13 @@ static void Task_PlayCryWhenReleasedFromBall(u8 taskId)
static void SpriteCB_ReleaseMonFromBall(struct Sprite *sprite)
{
- u8 bank = sprite->sBank;
+ u8 battlerId = sprite->sBattler;
u32 ballId;
StartSpriteAnim(sprite, 1);
- ballId = ItemIdToBallId(GetBankPokeballItemId(bank));
+ ballId = ItemIdToBallId(GetBattlerPokeballItemId(battlerId));
LaunchBallStarsTask(sprite->pos1.x, sprite->pos1.y - 5, 1, 0x1C, ballId);
- sprite->data[0] = LaunchBallFadeMonTask(1, sprite->sBank, 14, ballId);
+ sprite->data[0] = LaunchBallFadeMonTask(1, sprite->sBattler, 14, ballId);
sprite->callback = HandleBallAnimEnd;
if (gMain.inBattle)
@@ -749,19 +749,19 @@ static void SpriteCB_ReleaseMonFromBall(struct Sprite *sprite)
u16 wantedCryCase;
u8 taskId;
- if (GetBattlerSide(bank) != B_SIDE_PLAYER)
+ if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
{
- mon = &gEnemyParty[gBattlerPartyIndexes[bank]];
+ mon = &gEnemyParty[gBattlerPartyIndexes[battlerId]];
pan = 25;
}
else
{
- mon = &gPlayerParty[gBattlerPartyIndexes[bank]];
+ mon = &gPlayerParty[gBattlerPartyIndexes[battlerId]];
pan = -25;
}
species = GetMonData(mon, MON_DATA_SPECIES);
- if ((bank == GetBattlerAtPosition(B_POSITION_PLAYER_LEFT) || bank == GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT))
+ if ((battlerId == GetBattlerAtPosition(B_POSITION_PLAYER_LEFT) || battlerId == GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT))
&& IsDoubleBattle() && gBattleSpritesDataPtr->animationData->field_9_x1)
{
if (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_LINK)
@@ -777,39 +777,39 @@ static void SpriteCB_ReleaseMonFromBall(struct Sprite *sprite)
if (!IsDoubleBattle() || !gBattleSpritesDataPtr->animationData->field_9_x1)
wantedCryCase = 0;
- else if (bank == GetBattlerAtPosition(B_POSITION_PLAYER_LEFT) || bank == GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT))
+ else if (battlerId == GetBattlerAtPosition(B_POSITION_PLAYER_LEFT) || battlerId == GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT))
wantedCryCase = 1;
else
wantedCryCase = 2;
- gBattleSpritesDataPtr->healthBoxesData[bank].field_1_x40 = 1;
+ gBattleSpritesDataPtr->healthBoxesData[battlerId].field_1_x40 = 1;
taskId = CreateTask(Task_PlayCryWhenReleasedFromBall, 3);
gTasks[taskId].tCryTaskSpecies = species;
gTasks[taskId].tCryTaskPan = pan;
gTasks[taskId].tCryTaskWantedCry = wantedCryCase;
- gTasks[taskId].tCryTaskBank = bank;
- gTasks[taskId].tCryTaskMonSpriteId = gBattlerSpriteIds[sprite->sBank];
+ gTasks[taskId].tCryTaskBattler = battlerId;
+ gTasks[taskId].tCryTaskMonSpriteId = gBattlerSpriteIds[sprite->sBattler];
gTasks[taskId].tCryTaskMonPtr1 = (u32)(mon) >> 0x10;
gTasks[taskId].tCryTaskMonPtr2 = (u32)(mon);
gTasks[taskId].tCryTaskState = 0;
}
- StartSpriteAffineAnim(&gSprites[gBattlerSpriteIds[sprite->sBank]], 1);
+ StartSpriteAffineAnim(&gSprites[gBattlerSpriteIds[sprite->sBattler]], 1);
- if (GetBattlerSide(sprite->sBank) == B_SIDE_OPPONENT)
- gSprites[gBattlerSpriteIds[sprite->sBank]].callback = sub_8039B58;
+ if (GetBattlerSide(sprite->sBattler) == B_SIDE_OPPONENT)
+ gSprites[gBattlerSpriteIds[sprite->sBattler]].callback = sub_8039B58;
else
- gSprites[gBattlerSpriteIds[sprite->sBank]].callback = sub_8039E44;
+ gSprites[gBattlerSpriteIds[sprite->sBattler]].callback = sub_8039E44;
- AnimateSprite(&gSprites[gBattlerSpriteIds[sprite->sBank]]);
- gSprites[gBattlerSpriteIds[sprite->sBank]].data[1] = 0x1000;
+ AnimateSprite(&gSprites[gBattlerSpriteIds[sprite->sBattler]]);
+ gSprites[gBattlerSpriteIds[sprite->sBattler]].data[1] = 0x1000;
}
#undef tCryTaskSpecies
#undef tCryTaskPan
#undef tCryTaskWantedCry
-#undef tCryTaskBank
+#undef tCryTaskBattler
#undef tCryTaskMonSpriteId
#undef tCryTaskMonPtr1
#undef tCryTaskMonPtr2
@@ -828,37 +828,37 @@ static void sub_8075FB4(struct Sprite *sprite)
static void HandleBallAnimEnd(struct Sprite *sprite)
{
bool8 affineAnimEnded = FALSE;
- u8 bank = sprite->sBank;
+ u8 battlerId = sprite->sBattler;
- gSprites[gBattlerSpriteIds[bank]].invisible = FALSE;
+ gSprites[gBattlerSpriteIds[battlerId]].invisible = FALSE;
if (sprite->animEnded)
sprite->invisible = TRUE;
- if (gSprites[gBattlerSpriteIds[bank]].affineAnimEnded)
+ if (gSprites[gBattlerSpriteIds[battlerId]].affineAnimEnded)
{
- StartSpriteAffineAnim(&gSprites[gBattlerSpriteIds[bank]], 0);
+ StartSpriteAffineAnim(&gSprites[gBattlerSpriteIds[battlerId]], 0);
affineAnimEnded = TRUE;
}
else
{
- gSprites[gBattlerSpriteIds[bank]].data[1] -= 288;
- gSprites[gBattlerSpriteIds[bank]].pos2.y = gSprites[gBattlerSpriteIds[bank]].data[1] >> 8;
+ gSprites[gBattlerSpriteIds[battlerId]].data[1] -= 288;
+ gSprites[gBattlerSpriteIds[battlerId]].pos2.y = gSprites[gBattlerSpriteIds[battlerId]].data[1] >> 8;
}
if (sprite->animEnded && affineAnimEnded)
{
- s32 i, doneBanks;
+ s32 i, doneBattlers;
- gSprites[gBattlerSpriteIds[bank]].pos2.y = 0;
+ gSprites[gBattlerSpriteIds[battlerId]].pos2.y = 0;
gDoingBattleAnim = FALSE;
- gBattleSpritesDataPtr->healthBoxesData[bank].ballAnimActive = 0;
+ gBattleSpritesDataPtr->healthBoxesData[battlerId].ballAnimActive = 0;
FreeSpriteOamMatrix(sprite);
DestroySprite(sprite);
- for (doneBanks = 0, i = 0; i < MAX_BATTLERS_COUNT; i++)
+ for (doneBattlers = 0, i = 0; i < MAX_BATTLERS_COUNT; i++)
{
if (gBattleSpritesDataPtr->healthBoxesData[i].ballAnimActive == 0)
- doneBanks++;
+ doneBattlers++;
}
- if (doneBanks == MAX_BATTLERS_COUNT)
+ if (doneBattlers == MAX_BATTLERS_COUNT)
{
for (i = 0; i < POKEBALL_COUNT; i++)
FreeBallGfx(i);
@@ -868,7 +868,7 @@ static void HandleBallAnimEnd(struct Sprite *sprite)
static void sub_80760F8(struct Sprite *sprite)
{
- u8 bank = sprite->sBank;
+ u8 battlerId = sprite->sBattler;
sprite->data[4]++;
if (sprite->data[4] == 40)
@@ -883,21 +883,21 @@ static void sub_80760F8(struct Sprite *sprite)
}
else if (sprite->data[4] == 315)
{
- FreeOamMatrix(gSprites[gBattlerSpriteIds[sprite->sBank]].oam.matrixNum);
- DestroySprite(&gSprites[gBattlerSpriteIds[sprite->sBank]]);
+ FreeOamMatrix(gSprites[gBattlerSpriteIds[sprite->sBattler]].oam.matrixNum);
+ DestroySprite(&gSprites[gBattlerSpriteIds[sprite->sBattler]]);
DestroySpriteAndFreeResources(sprite);
if (gMain.inBattle)
- gBattleSpritesDataPtr->healthBoxesData[bank].ballAnimActive = 0;
+ gBattleSpritesDataPtr->healthBoxesData[battlerId].ballAnimActive = 0;
}
}
static void SpriteCB_PlayerMonSendOut_1(struct Sprite *sprite)
{
sprite->data[0] = 25;
- sprite->data[2] = GetBattlerSpriteCoord(sprite->sBank, 2);
- sprite->data[4] = GetBattlerSpriteCoord(sprite->sBank, 3) + 24;
+ sprite->data[2] = GetBattlerSpriteCoord(sprite->sBattler, 2);
+ sprite->data[4] = GetBattlerSpriteCoord(sprite->sBattler, 3) + 24;
sprite->data[5] = -30;
- sprite->oam.affineParam = sprite->sBank;
+ sprite->oam.affineParam = sprite->sBattler;
sub_80A68D4(sprite);
sprite->callback = SpriteCB_PlayerMonSendOut_2;
}
@@ -923,7 +923,7 @@ static void SpriteCB_PlayerMonSendOut_2(struct Sprite *sprite)
}
r4 = sprite->data[0];
sub_80A6F3C(sprite);
- sprite->data[7] += sprite->sBank / 3;
+ sprite->data[7] += sprite->sBattler / 3;
sprite->pos2.y += Sin(HIBYTE(sprite->data[7]), sprite->data[5]);
sprite->oam.affineParam += 0x100;
if ((sprite->oam.affineParam >> 8) % 3 != 0)
@@ -946,11 +946,11 @@ static void SpriteCB_PlayerMonSendOut_2(struct Sprite *sprite)
sprite->pos1.y += sprite->pos2.y;
sprite->pos2.y = 0;
sprite->pos2.x = 0;
- sprite->sBank = sprite->oam.affineParam & 0xFF;
+ sprite->sBattler = sprite->oam.affineParam & 0xFF;
sprite->data[0] = 0;
if (IsDoubleBattle() && gBattleSpritesDataPtr->animationData->field_9_x1
- && sprite->sBank == GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT))
+ && sprite->sBattler == GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT))
sprite->callback = SpriteCB_ReleaseMon2FromBall;
else
sprite->callback = SpriteCB_ReleaseMonFromBall;
@@ -976,26 +976,26 @@ static void SpriteCB_OpponentMonSendOut(struct Sprite *sprite)
{
sprite->data[0] = 0;
if (IsDoubleBattle() && gBattleSpritesDataPtr->animationData->field_9_x1
- && sprite->sBank == GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT))
+ && sprite->sBattler == GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT))
sprite->callback = SpriteCB_ReleaseMon2FromBall;
else
sprite->callback = SpriteCB_ReleaseMonFromBall;
}
}
-#undef sBank
+#undef sBattler
static u8 LaunchBallStarsTaskForPokeball(u8 x, u8 y, u8 kindOfStars, u8 d)
{
return LaunchBallStarsTask(x, y, kindOfStars, d, BALL_POKE);
}
-static u8 LaunchBallFadeMonTaskForPokeball(bool8 unFadeLater, u8 bank, u32 arg2)
+static u8 LaunchBallFadeMonTaskForPokeball(bool8 unFadeLater, u8 battlerId, u32 arg2)
{
- return LaunchBallFadeMonTask(unFadeLater, bank, arg2, BALL_POKE);
+ return LaunchBallFadeMonTask(unFadeLater, battlerId, arg2, BALL_POKE);
}
-void CreatePokeballSpriteToReleaseMon(u8 monSpriteId, u8 bank, u8 x, u8 y, u8 oamPriority, u8 subpriortiy, u8 g, u32 h, u16 species)
+void CreatePokeballSpriteToReleaseMon(u8 monSpriteId, u8 battlerId, u8 x, u8 y, u8 oamPriority, u8 subpriortiy, u8 g, u32 h, u16 species)
{
u8 spriteId;
@@ -1012,7 +1012,7 @@ void CreatePokeballSpriteToReleaseMon(u8 monSpriteId, u8 bank, u8 x, u8 y, u8 oa
gSprites[monSpriteId].data[7] = species;
gSprites[spriteId].data[1] = g;
- gSprites[spriteId].data[2] = bank;
+ gSprites[spriteId].data[2] = battlerId;
gSprites[spriteId].data[3] = h;
gSprites[spriteId].data[4] = h >> 0x10;
gSprites[spriteId].oam.priority = oamPriority;
@@ -1027,7 +1027,7 @@ static void sub_8076524(struct Sprite *sprite)
{
u8 r5;
u8 r7 = sprite->data[0];
- u8 bank = sprite->data[2];
+ u8 battlerId = sprite->data[2];
u32 r4 = (u16)sprite->data[3] | ((u16)sprite->data[4] << 16);
if (sprite->subpriority != 0)
@@ -1037,7 +1037,7 @@ static void sub_8076524(struct Sprite *sprite)
StartSpriteAnim(sprite, 1);
LaunchBallStarsTaskForPokeball(sprite->pos1.x, sprite->pos1.y - 5, sprite->oam.priority, r5);
- sprite->data[1] = LaunchBallFadeMonTaskForPokeball(1, bank, r4);
+ sprite->data[1] = LaunchBallFadeMonTaskForPokeball(1, battlerId, r4);
sprite->callback = sub_80765E0;
gSprites[r7].invisible = FALSE;
StartSpriteAffineAnim(&gSprites[r7], 1);
@@ -1175,16 +1175,16 @@ static void DestroySpriteAndFreeResources_(struct Sprite *sprite)
DestroySpriteAndFreeResources(sprite);
}
-void sub_8076918(u8 bank)
+void sub_8076918(u8 battlerId)
{
- struct Sprite *healthboxSprite = &gSprites[gHealthboxSpriteIds[bank]];
+ struct Sprite *healthboxSprite = &gSprites[gHealthboxSpriteIds[battlerId]];
healthboxSprite->data[0] = 5;
healthboxSprite->data[1] = 0;
healthboxSprite->pos2.x = 0x73;
healthboxSprite->pos2.y = 0;
healthboxSprite->callback = sub_80769CC;
- if (GetBattlerSide(bank) != B_SIDE_PLAYER)
+ if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
{
healthboxSprite->data[0] = -healthboxSprite->data[0];
healthboxSprite->data[1] = -healthboxSprite->data[1];
@@ -1192,7 +1192,7 @@ void sub_8076918(u8 bank)
healthboxSprite->pos2.y = -healthboxSprite->pos2.y;
}
gSprites[healthboxSprite->data[5]].callback(&gSprites[healthboxSprite->data[5]]);
- if (GetBattlerPosition(bank) == B_POSITION_PLAYER_RIGHT)
+ if (GetBattlerPosition(battlerId) == B_POSITION_PLAYER_RIGHT)
healthboxSprite->callback = sub_80769A8;
}
@@ -1214,13 +1214,13 @@ static void sub_80769CC(struct Sprite *sprite)
sprite->callback = SpriteCallbackDummy;
}
-void DoHitAnimHealthboxEffect(u8 bank)
+void DoHitAnimHealthboxEffect(u8 battlerId)
{
u8 spriteId;
spriteId = CreateInvisibleSpriteWithCallback(SpriteCB_HitAnimHealthoxEffect);
gSprites[spriteId].data[0] = 1;
- gSprites[spriteId].data[1] = gHealthboxSpriteIds[bank];
+ gSprites[spriteId].data[1] = gHealthboxSpriteIds[battlerId];
gSprites[spriteId].callback = SpriteCB_HitAnimHealthoxEffect;
}
@@ -1267,10 +1267,10 @@ void FreeBallGfx(u8 ballId)
FreeSpritePaletteByTag(gBallSpritePalettes[ballId].tag);
}
-static u16 GetBankPokeballItemId(u8 bank)
+static u16 GetBattlerPokeballItemId(u8 battlerId)
{
- if (GetBattlerSide(bank) == B_SIDE_PLAYER)
- return GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_POKEBALL);
+ if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
+ return GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_POKEBALL);
else
- return GetMonData(&gEnemyParty[gBattlerPartyIndexes[bank]], MON_DATA_POKEBALL);
+ return GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_POKEBALL);
}
diff --git a/src/pokeblock.c b/src/pokeblock.c
index b9d1d94c6..f57b2f0c2 100644
--- a/src/pokeblock.c
+++ b/src/pokeblock.c
@@ -29,6 +29,7 @@
#include "battle_message.h"
#include "safari_zone.h"
#include "lilycove_lady.h"
+#include "overworld.h"
#define POKEBLOCK_MAX_FEEL 99
#define FIELD_E75_COUNT 7
@@ -70,11 +71,10 @@ enum
};
extern u16 gSpecialVar_ItemId;
-extern void (*gFieldCallback)(void);
extern const u16 gUnknown_0860F074[];
-extern void c2_exit_to_overworld_2_switch(void);
+extern void CB2_ReturnToField(void);
extern bool8 sub_81221EC(void);
extern void sub_809882C(u8, u16, u8);
extern void copy_textbox_border_tile_patterns_to_vram(u8, u16, u8);
@@ -91,7 +91,7 @@ static void sub_81362E0(void);
static void sub_8136344(void);
static void HandlePokeblockListMenuItems(void);
static void sub_81363BC(void);
-static void MovePokeblockMenuCursor(u32 pkblId, bool8 arg1, struct ListMenu *arg2);
+static void MovePokeblockMenuCursor(s32 pkblId, bool8 arg1, struct ListMenu *arg2);
static void PutPokeblockInfoText(void);
static void HandlePokeblockMenuCursor(u16 cursorPos, u16 arg1);
static void PutPokeblockListMenuString(u8 *dst, u16 pkblId);
@@ -319,18 +319,18 @@ static const struct ListMenuTemplate sPokeblockListMenuTemplate =
.unk_08 = NULL,
.totalItems = 0,
.maxShowed = 0,
- .unk_10 = 1,
+ .windowId = 1,
.unk_11 = 0,
.unk_12 = 1,
- .cursor_Y = 0,
+ .cursor_X = 0,
.upText_Y = 1,
- .cursorColor = 2,
- .fillColor = 0,
- .cursorShadowColor = 3,
- .unk_16_0 = FALSE,
- .spaceBetweenItems = 32,
- .unk_16_7 = FALSE,
- .unk_17_0 = 1,
+ .cursorPal = 2,
+ .fillValue = 0,
+ .cursorShadowPal = 3,
+ .lettersSpacing = 0,
+ .unk_16_3 = 0,
+ .scrollMultiple = LIST_MULTIPLE_SCROLL_DPAD,
+ .fontId = 1,
.cursorKind = 1
};
@@ -374,7 +374,7 @@ void OpenPokeblockCaseInBattle(void)
void OpenPokeblockCaseOnFeeder(void)
{
- OpenPokeblockCase(PBLOCK_CASE_FEEDER, c2_exit_to_overworld_2_switch);
+ OpenPokeblockCase(PBLOCK_CASE_FEEDER, CB2_ReturnToField);
}
static void CB2_PokeblockMenu(void)
@@ -460,7 +460,7 @@ static bool8 InitPokeblockMenu(void)
gMain.state++;
break;
case 10:
- sub_8122344(&sPokeblockMenu->field_E75, FIELD_E75_COUNT);
+ sub_8122344(sPokeblockMenu->field_E75, FIELD_E75_COUNT);
gMain.state++;
break;
case 11:
@@ -589,7 +589,7 @@ static void PutPokeblockInfoText(void)
{
u8 i;
- const u8 *itemName = ItemId_GetItem(ITEM_POKEBLOCK_CASE)->name;
+ const u8 *itemName = ItemId_GetName(ITEM_POKEBLOCK_CASE);
PrintOnPokeblockWindow(0, itemName, GetStringCenterAlignXOffset(1, itemName, 0x48));
PrintOnPokeblockWindow(2, gText_Spicy, 0);
@@ -620,7 +620,7 @@ static void HandlePokeblockListMenuItems(void)
sPokeblockMenu->items[i].id = LIST_B_PRESSED;
gMultiuseListMenuTemplate = sPokeblockListMenuTemplate;
- gMultiuseListMenuTemplate.unk_17_0 = 7;
+ gMultiuseListMenuTemplate.fontId = 7;
gMultiuseListMenuTemplate.totalItems = sPokeblockMenu->itemsNo;
gMultiuseListMenuTemplate.items = sPokeblockMenu->items;
gMultiuseListMenuTemplate.maxShowed = sPokeblockMenu->maxShowed;
@@ -639,7 +639,7 @@ static void PutPokeblockListMenuString(u8 *dst, u16 pkblId)
StringExpandPlaceholders(txtPtr, gText_LvVar1);
}
-static void MovePokeblockMenuCursor(u32 pkblId, bool8 arg1, struct ListMenu *arg2)
+static void MovePokeblockMenuCursor(s32 pkblId, bool8 arg1, struct ListMenu *arg2)
{
if (arg1 != TRUE)
{
@@ -869,7 +869,7 @@ static void Task_FreeDataAndExitPokeblockCase(u8 taskId)
if (sPokeblockMenu->caseId == PBLOCK_CASE_FEEDER || sPokeblockMenu->caseId == PBLOCK_CASE_GIVE)
gFieldCallback = sub_80AF168;
- sub_81AE6C8(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
+ DestroyListMenuTask(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
sub_8136418();
ResetSpriteData();
FreeAllSpritePalettes();
@@ -893,7 +893,7 @@ static void Task_HandlePokeblockMenuInput(u8 taskId)
{
if (gMain.newKeys & SELECT_BUTTON)
{
- sub_81AE860(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
+ ListMenuGetScrollAndRow(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
if (sSavedPokeblockData.lastItemPage + sSavedPokeblockData.lastItemPos != sPokeblockMenu->itemsNo - 1)
{
PlaySE(SE_SELECT);
@@ -908,7 +908,7 @@ static void Task_HandlePokeblockMenuInput(u8 taskId)
u16 oldPosition = sSavedPokeblockData.lastItemPos;
s32 itemId = ListMenuHandleInputGetItemId(data[0]);
- sub_81AE860(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
+ ListMenuGetScrollAndRow(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
if (oldPosition != sSavedPokeblockData.lastItemPos)
{
HandlePokeblockMenuCursor(oldPosition, 5);
@@ -945,7 +945,7 @@ static void Task_HandlePokeblocksSwapInput(u8 taskId)
if (gMain.newKeys & SELECT_BUTTON)
{
PlaySE(SE_SELECT);
- sub_81AE860(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
+ ListMenuGetScrollAndRow(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
HandlePokeblocksSwap(taskId, FALSE);
}
else
@@ -954,7 +954,7 @@ static void Task_HandlePokeblocksSwapInput(u8 taskId)
u16 var = sSavedPokeblockData.lastItemPos;
s32 itemId = ListMenuHandleInputGetItemId(data[0]);
- sub_81AE860(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
+ ListMenuGetScrollAndRow(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
if (i != sSavedPokeblockData.lastItemPage || var != sSavedPokeblockData.lastItemPos)
{
for (i = 0; i < 9; i++)
@@ -996,7 +996,7 @@ static void HandlePokeblocksSwap(u8 taskId, bool8 noSwap)
u16 swappedFromId = sSavedPokeblockData.lastItemPage + sSavedPokeblockData.lastItemPos;
sPokeblockMenu->isSwapping = FALSE;
- sub_81AE6C8(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
+ DestroyListMenuTask(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
if (!noSwap && data[2] != swappedFromId && data[2] != swappedFromId - 1)
{
@@ -1112,7 +1112,7 @@ static void HandleErasePokeblock(u8 taskId)
lastPos = &sSavedPokeblockData.lastItemPos;
data = gTasks[taskId].data;
- sub_81AE6C8(data[0], lastPage, lastPos);
+ DestroyListMenuTask(data[0], lastPage, lastPos);
HandlePokeblockMenuCursor(*lastPos, 5);
SetMenuItemsCountAndMaxShowed();
sub_81362E0();
diff --git a/src/pokeblock_feed.c b/src/pokeblock_feed.c
index 2039808cb..db92d56a8 100644
--- a/src/pokeblock_feed.c
+++ b/src/pokeblock_feed.c
@@ -50,7 +50,6 @@ struct PokeblockFeedStruct
extern u16 gSpecialVar_ItemId;
extern struct MusicPlayerInfo gMPlayInfo_BGM;
-extern struct SpriteTemplate gUnknown_0202499C;
extern const u8 gBattleTerrainPalette_Frontier[];
extern const u8 gBattleTerrainTiles_Building[];
@@ -837,7 +836,7 @@ static u8 CreateMonSprite(struct Pokemon* mon)
gSprites[spriteId].callback = SpriteCallbackDummy;
sPokeblockFeed->noMonFlip = TRUE;
- if (!IsPokeSpriteNotFlipped(species))
+ if (!IsMonSpriteNotFlipped(species))
{
gSprites[spriteId].affineAnims = sSpriteAffineAnimTable_MonNoFlip;
gSprites[spriteId].oam.affineMode = 3;
diff --git a/src/pokemon.c b/src/pokemon.c
new file mode 100644
index 000000000..800b7c0cd
--- /dev/null
+++ b/src/pokemon.c
@@ -0,0 +1,6096 @@
+#include "global.h"
+#include "pokemon.h"
+#include "battle.h"
+#include "battle_setup.h"
+#include "battle_message.h"
+#include "random.h"
+#include "main.h"
+#include "constants/species.h"
+#include "constants/abilities.h"
+#include "constants/items.h"
+#include "constants/trainers.h"
+#include "constants/moves.h"
+#include "constants/hold_effects.h"
+#include "constants/battle_move_effects.h"
+#include "constants/songs.h"
+#include "string_util.h"
+#include "text.h"
+#include "link.h"
+#include "event_data.h"
+#include "item.h"
+#include "battle_controllers.h"
+#include "battle_message.h"
+#include "evolution_scene.h"
+#include "pokemon_animation.h"
+#include "pokedex.h"
+#include "pokeblock.h"
+#include "sound.h"
+#include "task.h"
+#include "rtc.h"
+#include "m4a.h"
+#include "malloc.h"
+#include "util.h"
+#include "strings.h"
+#include "pokenav.h"
+#include "pokemon_storage_system.h"
+#include "recorded_battle.h"
+
+struct SpeciesItem
+{
+ u16 species;
+ u16 item;
+};
+
+// Extracts the upper 16 bits of a 32-bit number
+#define HIHALF(n) (((n) & 0xFFFF0000) >> 16)
+
+// Extracts the lower 16 bits of a 32-bit number
+#define LOHALF(n) ((n) & 0xFFFF)
+
+extern const struct OamData gUnknown_0831ACB0;
+extern const struct OamData gUnknown_0831ACA8;
+extern const struct SpriteFrameImage gUnknown_082FF3A8[];
+extern const struct SpriteFrameImage gUnknown_082FF3C8[];
+extern const struct SpriteFrameImage gUnknown_082FF3E8[];
+extern const struct SpriteFrameImage gUnknown_082FF408[];
+extern const struct SpriteFrameImage gUnknown_082FF428[];
+extern const struct SpriteFrameImage gUnknown_082FF448[];
+extern const struct SpriteFrameImage gUnknown_082FF468[];
+extern const struct SpriteFrameImage gUnknown_082FF490[];
+extern const struct SpriteFrameImage gUnknown_082FF4B8[];
+extern const struct SpriteFrameImage gUnknown_082FF4D8[];
+extern const struct SpriteFrameImage gUnknown_082FF4F8[];
+extern const struct SpriteFrameImage gUnknown_082FF518[];
+extern const union AffineAnimCmd *const gUnknown_082FF618[];
+extern const union AffineAnimCmd *const gUnknown_082FF694[];
+extern const union AnimCmd *gUnknown_082FF70C[];
+extern const union AnimCmd *const *const gMonAnimationsSpriteAnimsPtrTable[];
+extern const union AnimCmd *const *const gUnknown_08305D0C[];
+extern const union AnimCmd *const *const gUnknown_0830536C[];
+extern const u8 gSpeciesNames[][POKEMON_NAME_LENGTH + 1];
+extern const struct UnknownPokemonStruct3 gUnknown_08610970[];
+extern const struct CompressedSpritePalette gMonPaletteTable[];
+extern const struct CompressedSpritePalette gMonShinyPaletteTable[];
+extern const u8 gTrainerClassNames[][13];
+
+extern u8 pokemon_order_func(u8);
+extern u16 get_unknown_box_id(void);
+extern u8 StorageGetCurrentBox(void);
+extern void set_unknown_box_id(u8);
+extern void sub_803FA70(u8 battlerId);
+extern u8 sav1_map_get_name(void);
+extern const u8 *sub_81A1650(u8, u8 language);
+extern u8 BattleFrontierGetOpponentLvl(u8);
+extern u16 FacilityClassToPicIndex(u16);
+extern bool8 InBattlePyramid(void);
+extern bool8 InBattlePike(void);
+extern bool8 sub_806F104(void);
+extern u8 GetTrainerEncounterMusicIdInBattlePyramind(u16 trainerOpponentId);
+extern u8 sub_81D63C8(u16 trainerOpponentId);
+extern u8 GetFrontierOpponentClass(u16 trainerId);
+extern void GetFrontierTrainerName(u8* dest, u16 trainerId);
+extern void sub_81C488C(u8);
+
+// this file's functions
+static u16 CalculateBoxMonChecksum(struct BoxPokemon *boxMon);
+static union PokemonSubstruct *GetSubstruct(struct BoxPokemon *boxMon, u32 personality, u8 substructType);
+static void EncryptBoxMon(struct BoxPokemon *boxMon);
+static void DecryptBoxMon(struct BoxPokemon *boxMon);
+static void sub_806E6CC(u8 taskId);
+static bool8 ShouldGetStatBadgeBoost(u16 flagId, u8 battlerId);
+
+// EWRAM vars
+EWRAM_DATA static u8 sLearningMoveTableID = 0;
+EWRAM_DATA u8 gPlayerPartyCount = 0;
+EWRAM_DATA u8 gEnemyPartyCount = 0;
+EWRAM_DATA struct Pokemon gPlayerParty[PARTY_SIZE] = {0};
+EWRAM_DATA struct Pokemon gEnemyParty[PARTY_SIZE] = {0};
+EWRAM_DATA struct SpriteTemplate gUnknown_0202499C = {0};
+EWRAM_DATA struct Unknown_806F160_Struct *gUnknown_020249B4[2] = {NULL};
+
+// const rom data
+#include "data/battle_moves.h"
+static const u8 sUnreferencedData[] = {0x34, 0x00, 0x10, 0x00, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00};
+
+const u16 gSpeciesToHoennPokedexNum[] = {203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 156, 157, 112, 113, 227, 228, 229, 230, 231, 232, 233, 234, 153, 154, 138, 139, 63, 64, 88, 89, 90, 235, 236, 237, 238, 239, 240, 241, 242, 158, 159, 243, 244, 245, 246, 247, 248, 249, 39, 40, 41, 73, 74, 75, 250, 251, 252, 66, 67, 57, 58, 59, 253, 254, 255, 256, 82, 83, 257, 92, 93, 258, 259, 106, 107, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 84, 85, 270, 271, 272, 273, 274, 275, 276, 108, 109, 169, 170, 277, 278, 279, 184, 185, 50, 51, 143, 144, 280, 281, 282, 283, 284, 167, 285, 52, 53, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 65, 181, 182, 155, 324, 137, 325, 326, 162, 163, 327, 328, 329, 91, 55, 56, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 161, 164, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 168, 357, 358, 359, 103, 104, 360, 361, 180, 362, 363, 364, 365, 115, 366, 367, 186, 165, 166, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 42, 43, 44, 25, 26, 34, 35, 114, 27, 28, 32, 33, 99, 100, 61, 62, 145, 131, 132, 60, 105, 68, 127, 128, 183, 129, 130, 140, 141, 97, 98, 116, 117, 118, 48, 49, 78, 79, 101, 102, 173, 174, 175, 119, 120, 171, 172, 125, 126, 54, 110, 111, 80, 81, 69, 76, 77, 121, 122, 160, 148, 149, 94, 36, 37, 38, 95, 96, 150, 45, 46, 47, 176, 177, 178, 152, 146, 147, 124, 123, 179, 70, 71, 72, 142, 86, 87, 133, 134, 135, 136, 29, 30, 31, 187, 188, 189, 190, 191, 192, 193, 194, 195, 198, 199, 200, 196, 197, 201, 202, 151};
+const u16 gSpeciesToNationalPokedexNum[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 290, 291, 292, 276, 277, 285, 286, 327, 278, 279, 283, 284, 320, 321, 300, 301, 352, 343, 344, 299, 324, 302, 339, 340, 370, 341, 342, 349, 350, 318, 319, 328, 329, 330, 296, 297, 309, 310, 322, 323, 363, 364, 365, 331, 332, 361, 362, 337, 338, 298, 325, 326, 311, 312, 303, 307, 308, 333, 334, 360, 355, 356, 315, 287, 288, 289, 316, 317, 357, 293, 294, 295, 366, 367, 368, 359, 353, 354, 336, 335, 369, 304, 305, 306, 351, 313, 314, 345, 346, 347, 348, 280, 281, 282, 371, 372, 373, 374, 375, 376, 377, 378, 379, 382, 383, 384, 380, 381, 385, 386, 358};
+const u16 gHoennToNationalOrder[] = {252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 63, 64, 65, 290, 291, 292, 293, 294, 295, 296, 297, 118, 119, 129, 130, 298, 183, 184, 74, 75, 76, 299, 300, 301, 41, 42, 169, 72, 73, 302, 303, 304, 305, 306, 66, 67, 68, 307, 308, 309, 310, 311, 312, 81, 82, 100, 101, 313, 314, 43, 44, 45, 182, 84, 85, 315, 316, 317, 318, 319, 320, 321, 322, 323, 218, 219, 324, 88, 89, 109, 110, 325, 326, 27, 28, 327, 227, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 174, 39, 40, 349, 350, 351, 120, 121, 352, 353, 354, 355, 356, 357, 358, 359, 37, 38, 172, 25, 26, 54, 55, 360, 202, 177, 178, 203, 231, 232, 127, 214, 111, 112, 361, 362, 363, 364, 365, 366, 367, 368, 369, 222, 170, 171, 370, 116, 117, 230, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 34, 35, 36, 46, 47, 48, 49, 50, 51, 52, 53, 56, 57, 58, 59, 60, 61, 62, 69, 70, 71, 77, 78, 79, 80, 83, 86, 87, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 102, 103, 104, 105, 106, 107, 108, 113, 114, 115, 122, 123, 124, 125, 126, 128, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 173, 175, 176, 179, 180, 181, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 215, 216, 217, 220, 221, 223, 224, 225, 226, 228, 229, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411};
+
+const struct SpindaSpot gSpindaSpotGraphics[] =
+{
+ {16, 7, INCBIN_U16("graphics/spinda_spots/spot_0.bin")},
+ {40, 8, INCBIN_U16("graphics/spinda_spots/spot_1.bin")},
+ {22, 25, INCBIN_U16("graphics/spinda_spots/spot_2.bin")},
+ {34, 26, INCBIN_U16("graphics/spinda_spots/spot_3.bin")}
+};
+
+#include "data/pokemon/item_effects.h"
+
+const s8 gNatureStatTable[][5] =
+{
+ // Atk Def Spd Sp.Atk Sp.Def
+ { 0, 0, 0, 0, 0}, // Hardy
+ { +1, -1, 0, 0, 0}, // Lonely
+ { +1, 0, -1, 0, 0}, // Brave
+ { +1, 0, 0, -1, 0}, // Adamant
+ { +1, 0, 0, 0, -1}, // Naughty
+ { -1, +1, 0, 0, 0}, // Bold
+ { 0, 0, 0, 0, 0}, // Docile
+ { 0, +1, -1, 0, 0}, // Relaxed
+ { 0, +1, 0, -1, 0}, // Impish
+ { 0, +1, 0, 0, -1}, // Lax
+ { -1, 0, +1, 0, 0}, // Timid
+ { 0, -1, +1, 0, 0}, // Hasty
+ { 0, 0, 0, 0, 0}, // Serious
+ { 0, 0, +1, -1, 0}, // Jolly
+ { 0, 0, +1, 0, -1}, // Naive
+ { -1, 0, 0, +1, 0}, // Modest
+ { 0, -1, 0, +1, 0}, // Mild
+ { 0, 0, -1, +1, 0}, // Quiet
+ { 0, 0, 0, 0, 0}, // Bashful
+ { 0, 0, 0, +1, -1}, // Rash
+ { -1, 0, 0, 0, +1}, // Calm
+ { 0, -1, 0, 0, +1}, // Gentle
+ { 0, 0, -1, 0, +1}, // Sassy
+ { 0, 0, 0, -1, +1}, // Careful
+ { 0, 0, 0, 0, 0}, // Quirky
+};
+
+#include "data/pokemon/tmhm_learnsets.h"
+#include "data/pokemon/trainer_class_lookups.h"
+#include "data/pokemon/cry_ids.h"
+#include "data/pokemon/experience_tables.h"
+#include "data/pokemon/base_stats.h"
+#include "data/pokemon/level_up_learnsets.h"
+#include "data/pokemon/evolution.h"
+#include "data/pokemon/level_up_learnset_pointers.h"
+
+static const u8 sMonFrontAnimIdsTable[] =
+{
+ 0x06, // SPECIES_BULBASAUR
+ 0x17, // SPECIES_IVYSAUR
+ 0x2f, // SPECIES_VENUSAUR
+ 0x52, // SPECIES_CHARMANDER
+ 0x25, // SPECIES_CHARMELEON
+ 0x10, // SPECIES_CHARIZARD
+ 0x0b, // SPECIES_SQUIRTLE
+ 0x13, // SPECIES_WARTORTLE
+ 0x19, // SPECIES_BLASTOISE
+ 0x0b, // SPECIES_CATERPIE
+ 0x0b, // SPECIES_METAPOD
+ 0x1d, // SPECIES_BUTTERFREE
+ 0x46, // SPECIES_WEEDLE
+ 0x20, // SPECIES_KAKUNA
+ 0x02, // SPECIES_BEEDRILL
+ 0x47, // SPECIES_PIDGEY
+ 0x17, // SPECIES_PIDGEOTTO
+ 0x29, // SPECIES_PIDGEOT
+ 0x43, // SPECIES_RATTATA
+ 0x2b, // SPECIES_RATICATE
+ 0x18, // SPECIES_SPEAROW
+ 0x2b, // SPECIES_FEAROW
+ 0x16, // SPECIES_EKANS
+ 0x17, // SPECIES_ARBOK
+ 0x2c, // SPECIES_PIKACHU
+ 0x17, // SPECIES_RAICHU
+ 0x2d, // SPECIES_SANDSHREW
+ 0x17, // SPECIES_SANDSLASH
+ 0x00, // SPECIES_NIDORAN_F
+ 0x17, // SPECIES_NIDORINA
+ 0x0f, // SPECIES_NIDOQUEEN
+ 0x09, // SPECIES_NIDORAN_M
+ 0x13, // SPECIES_NIDORINO
+ 0x0f, // SPECIES_NIDOKING
+ 0x00, // SPECIES_CLEFAIRY
+ 0x4a, // SPECIES_CLEFABLE
+ 0x17, // SPECIES_VULPIX
+ 0x10, // SPECIES_NINETALES
+ 0x48, // SPECIES_JIGGLYPUFF
+ 0x31, // SPECIES_WIGGLYTUFF
+ 0x00, // SPECIES_ZUBAT
+ 0x1d, // SPECIES_GOLBAT
+ 0x00, // SPECIES_ODDISH
+ 0x45, // SPECIES_GLOOM
+ 0x49, // SPECIES_VILEPLUME
+ 0x46, // SPECIES_PARAS
+ 0x0f, // SPECIES_PARASECT
+ 0x06, // SPECIES_VENONAT
+ 0x4b, // SPECIES_VENOMOTH
+ 0x10, // SPECIES_DIGLETT
+ 0x4c, // SPECIES_DUGTRIO
+ 0x52, // SPECIES_MEOWTH
+ 0x17, // SPECIES_PERSIAN
+ 0x06, // SPECIES_PSYDUCK
+ 0x4c, // SPECIES_GOLDUCK
+ 0x32, // SPECIES_MANKEY
+ 0x48, // SPECIES_PRIMEAPE
+ 0x25, // SPECIES_GROWLITHE
+ 0x02, // SPECIES_ARCANINE
+ 0x00, // SPECIES_POLIWAG
+ 0x32, // SPECIES_POLIWHIRL
+ 0x19, // SPECIES_POLIWRATH
+ 0x31, // SPECIES_ABRA
+ 0x09, // SPECIES_KADABRA
+ 0x17, // SPECIES_ALAKAZAM
+ 0x00, // SPECIES_MACHOP
+ 0x10, // SPECIES_MACHOKE
+ 0x31, // SPECIES_MACHAMP
+ 0x17, // SPECIES_BELLSPROUT
+ 0x0d, // SPECIES_WEEPINBELL
+ 0x32, // SPECIES_VICTREEBEL
+ 0x00, // SPECIES_TENTACOOL
+ 0x00, // SPECIES_TENTACRUEL
+ 0x48, // SPECIES_GEODUDE
+ 0x48, // SPECIES_GRAVELER
+ 0x2f, // SPECIES_GOLEM
+ 0x20, // SPECIES_PONYTA
+ 0x11, // SPECIES_RAPIDASH
+ 0x45, // SPECIES_SLOWPOKE
+ 0x0b, // SPECIES_SLOWBRO
+ 0x54, // SPECIES_MAGNEMITE
+ 0x2c, // SPECIES_MAGNETON
+ 0x48, // SPECIES_FARFETCHD
+ 0x4c, // SPECIES_DODUO
+ 0x41, // SPECIES_DODRIO
+ 0x0b, // SPECIES_SEEL
+ 0x45, // SPECIES_DEWGONG
+ 0x46, // SPECIES_GRIMER
+ 0x30, // SPECIES_MUK
+ 0x12, // SPECIES_SHELLDER
+ 0x1d, // SPECIES_CLOYSTER
+ 0x15, // SPECIES_GASTLY
+ 0x35, // SPECIES_HAUNTER
+ 0x3a, // SPECIES_GENGAR
+ 0x43, // SPECIES_ONIX
+ 0x4f, // SPECIES_DROWZEE
+ 0x09, // SPECIES_HYPNO
+ 0x03, // SPECIES_KRABBY
+ 0x4b, // SPECIES_KINGLER
+ 0x00, // SPECIES_VOLTORB
+ 0x00, // SPECIES_ELECTRODE
+ 0x46, // SPECIES_EXEGGCUTE
+ 0x32, // SPECIES_EXEGGUTOR
+ 0x48, // SPECIES_CUBONE
+ 0x05, // SPECIES_MAROWAK
+ 0x16, // SPECIES_HITMONLEE
+ 0x09, // SPECIES_HITMONCHAN
+ 0x45, // SPECIES_LICKITUNG
+ 0x13, // SPECIES_KOFFING
+ 0x04, // SPECIES_WEEZING
+ 0x10, // SPECIES_RHYHORN
+ 0x13, // SPECIES_RHYDON
+ 0x45, // SPECIES_CHANSEY
+ 0x48, // SPECIES_TANGELA
+ 0x17, // SPECIES_KANGASKHAN
+ 0x12, // SPECIES_HORSEA
+ 0x04, // SPECIES_SEADRA
+ 0x0d, // SPECIES_GOLDEEN
+ 0x1c, // SPECIES_SEAKING
+ 0x4e, // SPECIES_STARYU
+ 0x12, // SPECIES_STARMIE
+ 0x46, // SPECIES_MR_MIME
+ 0x02, // SPECIES_SCYTHER
+ 0x17, // SPECIES_JYNX
+ 0x2c, // SPECIES_ELECTABUZZ
+ 0x0f, // SPECIES_MAGMAR
+ 0x09, // SPECIES_PINSIR
+ 0x19, // SPECIES_TAUROS
+ 0x05, // SPECIES_MAGIKARP
+ 0x48, // SPECIES_GYARADOS
+ 0x17, // SPECIES_LAPRAS
+ 0x01, // SPECIES_DITTO
+ 0x17, // SPECIES_EEVEE
+ 0x17, // SPECIES_VAPOREON
+ 0x00, // SPECIES_JOLTEON
+ 0x17, // SPECIES_FLAREON
+ 0x52, // SPECIES_PORYGON
+ 0x51, // SPECIES_OMANYTE
+ 0x09, // SPECIES_OMASTAR
+ 0x1d, // SPECIES_KABUTO
+ 0x0f, // SPECIES_KABUTOPS
+ 0x47, // SPECIES_AERODACTYL
+ 0x0b, // SPECIES_SNORLAX
+ 0x09, // SPECIES_ARTICUNO
+ 0x2c, // SPECIES_ZAPDOS
+ 0x45, // SPECIES_MOLTRES
+ 0x00, // SPECIES_DRATINI
+ 0x10, // SPECIES_DRAGONAIR
+ 0x47, // SPECIES_DRAGONITE
+ 0x09, // SPECIES_MEWTWO
+ 0x0d, // SPECIES_MEW
+ 0x00, // SPECIES_CHIKORITA
+ 0x00, // SPECIES_BAYLEEF
+ 0x17, // SPECIES_MEGANIUM
+ 0x52, // SPECIES_CYNDAQUIL
+ 0x17, // SPECIES_QUILAVA
+ 0x10, // SPECIES_TYPHLOSION
+ 0x31, // SPECIES_TOTODILE
+ 0x0f, // SPECIES_CROCONAW
+ 0x0f, // SPECIES_FERALIGATR
+ 0x00, // SPECIES_SENTRET
+ 0x32, // SPECIES_FURRET
+ 0x47, // SPECIES_HOOTHOOT
+ 0x17, // SPECIES_NOCTOWL
+ 0x52, // SPECIES_LEDYBA
+ 0x47, // SPECIES_LEDIAN
+ 0x4f, // SPECIES_SPINARAK
+ 0x0f, // SPECIES_ARIADOS
+ 0x00, // SPECIES_CROBAT
+ 0x45, // SPECIES_CHINCHOU
+ 0x51, // SPECIES_LANTURN
+ 0x1e, // SPECIES_PICHU
+ 0x52, // SPECIES_CLEFFA
+ 0x0c, // SPECIES_IGGLYBUFF
+ 0x0b, // SPECIES_TOGEPI
+ 0x00, // SPECIES_TOGETIC
+ 0x31, // SPECIES_NATU
+ 0x09, // SPECIES_XATU
+ 0x00, // SPECIES_MAREEP
+ 0x1e, // SPECIES_FLAAFFY
+ 0x2c, // SPECIES_AMPHAROS
+ 0x0b, // SPECIES_BELLOSSOM
+ 0x00, // SPECIES_MARILL
+ 0x4a, // SPECIES_AZUMARILL
+ 0x46, // SPECIES_SUDOWOODO
+ 0x32, // SPECIES_POLITOED
+ 0x1c, // SPECIES_HOPPIP
+ 0x18, // SPECIES_SKIPLOOM
+ 0x51, // SPECIES_JUMPLUFF
+ 0x32, // SPECIES_AIPOM
+ 0x52, // SPECIES_SUNKERN
+ 0x00, // SPECIES_SUNFLORA
+ 0x2b, // SPECIES_YANMA
+ 0x00, // SPECIES_WOOPER
+ 0x16, // SPECIES_QUAGSIRE
+ 0x09, // SPECIES_ESPEON
+ 0x10, // SPECIES_UMBREON
+ 0x00, // SPECIES_MURKROW
+ 0x13, // SPECIES_SLOWKING
+ 0x1c, // SPECIES_MISDREAVUS
+ 0x0a, // SPECIES_UNOWN
+ 0x30, // SPECIES_WOBBUFFET
+ 0x1e, // SPECIES_GIRAFARIG
+ 0x0b, // SPECIES_PINECO
+ 0x10, // SPECIES_FORRETRESS
+ 0x00, // SPECIES_DUNSPARCE
+ 0x13, // SPECIES_GLIGAR
+ 0x0f, // SPECIES_STEELIX
+ 0x17, // SPECIES_SNUBBULL
+ 0x10, // SPECIES_GRANBULL
+ 0x3a, // SPECIES_QWILFISH
+ 0x02, // SPECIES_SCIZOR
+ 0x0b, // SPECIES_SHUCKLE
+ 0x41, // SPECIES_HERACROSS
+ 0x16, // SPECIES_SNEASEL
+ 0x17, // SPECIES_TEDDIURSA
+ 0x10, // SPECIES_URSARING
+ 0x17, // SPECIES_SLUGMA
+ 0x17, // SPECIES_MAGCARGO
+ 0x00, // SPECIES_SWINUB
+ 0x0f, // SPECIES_PILOSWINE
+ 0x03, // SPECIES_CORSOLA
+ 0x52, // SPECIES_REMORAID
+ 0x17, // SPECIES_OCTILLERY
+ 0x52, // SPECIES_DELIBIRD
+ 0x0d, // SPECIES_MANTINE
+ 0x17, // SPECIES_SKARMORY
+ 0x17, // SPECIES_HOUNDOUR
+ 0x10, // SPECIES_HOUNDOOM
+ 0x42, // SPECIES_KINGDRA
+ 0x32, // SPECIES_PHANPY
+ 0x19, // SPECIES_DONPHAN
+ 0x00, // SPECIES_PORYGON2
+ 0x00, // SPECIES_STANTLER
+ 0x31, // SPECIES_SMEARGLE
+ 0x16, // SPECIES_TYROGUE
+ 0x02, // SPECIES_HITMONTOP
+ 0x09, // SPECIES_SMOOCHUM
+ 0x2c, // SPECIES_ELEKID
+ 0x00, // SPECIES_MAGBY
+ 0x45, // SPECIES_MILTANK
+ 0x00, // SPECIES_BLISSEY
+ 0x2c, // SPECIES_RAIKOU
+ 0x09, // SPECIES_ENTEI
+ 0x10, // SPECIES_SUICUNE
+ 0x52, // SPECIES_LARVITAR
+ 0x10, // SPECIES_PUPITAR
+ 0x0f, // SPECIES_TYRANITAR
+ 0x3a, // SPECIES_LUGIA
+ 0x09, // SPECIES_HO_OH
+ 0x18, // SPECIES_CELEBI
+ 0x00, // 252
+ 0x00, // 253
+ 0x00, // 254
+ 0x00, // 255
+ 0x00, // 256
+ 0x00, // 257
+ 0x00, // 258
+ 0x00, // 259
+ 0x00, // 260
+ 0x00, // 261
+ 0x00, // 262
+ 0x00, // 263
+ 0x00, // 264
+ 0x00, // 265
+ 0x00, // 266
+ 0x00, // 267
+ 0x00, // 268
+ 0x00, // 269
+ 0x00, // 270
+ 0x00, // 271
+ 0x00, // 272
+ 0x00, // 273
+ 0x00, // 274
+ 0x00, // 275
+ 0x00, // 276
+ 0x00, // SPECIES_TREECKO
+ 0x17, // SPECIES_GROVYLE
+ 0x10, // SPECIES_SCEPTILE
+ 0x16, // SPECIES_TORCHIC
+ 0x06, // SPECIES_COMBUSKEN
+ 0x0f, // SPECIES_BLAZIKEN
+ 0x01, // SPECIES_MUDKIP
+ 0x04, // SPECIES_MARSHTOMP
+ 0x1e, // SPECIES_SWAMPERT
+ 0x10, // SPECIES_POOCHYENA
+ 0x10, // SPECIES_MIGHTYENA
+ 0x03, // SPECIES_ZIGZAGOON
+ 0x09, // SPECIES_LINOONE
+ 0x00, // SPECIES_WURMPLE
+ 0x00, // SPECIES_SILCOON
+ 0x04, // SPECIES_BEAUTIFLY
+ 0x04, // SPECIES_CASCOON
+ 0x06, // SPECIES_DUSTOX
+ 0x00, // SPECIES_LOTAD
+ 0x00, // SPECIES_LOMBRE
+ 0x49, // SPECIES_LUDICOLO
+ 0x05, // SPECIES_SEEDOT
+ 0x00, // SPECIES_NUZLEAF
+ 0x02, // SPECIES_SHIFTRY
+ 0x00, // SPECIES_NINCADA
+ 0x46, // SPECIES_NINJASK
+ 0x1c, // SPECIES_SHEDINJA
+ 0x1e, // SPECIES_TAILLOW
+ 0x01, // SPECIES_SWELLOW
+ 0x00, // SPECIES_SHROOMISH
+ 0x00, // SPECIES_BRELOOM
+ 0x31, // SPECIES_SPINDA
+ 0x1b, // SPECIES_WINGULL
+ 0x1c, // SPECIES_PELIPPER
+ 0x00, // SPECIES_SURSKIT
+ 0x00, // SPECIES_MASQUERAIN
+ 0x01, // SPECIES_WAILMER
+ 0x1c, // SPECIES_WAILORD
+ 0x00, // SPECIES_SKITTY
+ 0x17, // SPECIES_DELCATTY
+ 0x35, // SPECIES_KECLEON
+ 0x1d, // SPECIES_BALTOY
+ 0x51, // SPECIES_CLAYDOL
+ 0x49, // SPECIES_NOSEPASS
+ 0x17, // SPECIES_TORKOAL
+ 0x15, // SPECIES_SABLEYE
+ 0x49, // SPECIES_BARBOACH
+ 0x49, // SPECIES_WHISCASH
+ 0x1d, // SPECIES_LUVDISC
+ 0x10, // SPECIES_CORPHISH
+ 0x09, // SPECIES_CRAWDAUNT
+ 0x49, // SPECIES_FEEBAS
+ 0x22, // SPECIES_MILOTIC
+ 0x49, // SPECIES_CARVANHA
+ 0x56, // SPECIES_SHARPEDO
+ 0x10, // SPECIES_TRAPINCH
+ 0x0f, // SPECIES_VIBRAVA
+ 0x4b, // SPECIES_FLYGON
+ 0x0b, // SPECIES_MAKUHITA
+ 0x34, // SPECIES_HARIYAMA
+ 0x00, // SPECIES_ELECTRIKE
+ 0x00, // SPECIES_MANECTRIC
+ 0x04, // SPECIES_NUMEL
+ 0x10, // SPECIES_CAMERUPT
+ 0x53, // SPECIES_SPHEAL
+ 0x17, // SPECIES_SEALEO
+ 0x0f, // SPECIES_WALREIN
+ 0x49, // SPECIES_CACNEA
+ 0x04, // SPECIES_CACTURNE
+ 0x45, // SPECIES_SNORUNT
+ 0x0a, // SPECIES_GLALIE
+ 0x0e, // SPECIES_LUNATONE
+ 0x08, // SPECIES_SOLROCK
+ 0x00, // SPECIES_AZURILL
+ 0x56, // SPECIES_SPOINK
+ 0x32, // SPECIES_GRUMPIG
+ 0x00, // SPECIES_PLUSLE
+ 0x01, // SPECIES_MINUN
+ 0x00, // SPECIES_MAWILE
+ 0x05, // SPECIES_MEDITITE
+ 0x45, // SPECIES_MEDICHAM
+ 0x04, // SPECIES_SWABLU
+ 0x16, // SPECIES_ALTARIA
+ 0x32, // SPECIES_WYNAUT
+ 0x0a, // SPECIES_DUSKULL
+ 0x02, // SPECIES_DUSCLOPS
+ 0x45, // SPECIES_ROSELIA
+ 0x45, // SPECIES_SLAKOTH
+ 0x31, // SPECIES_VIGOROTH
+ 0x45, // SPECIES_SLAKING
+ 0x00, // SPECIES_GULPIN
+ 0x45, // SPECIES_SWALOT
+ 0x10, // SPECIES_TROPIUS
+ 0x03, // SPECIES_WHISMUR
+ 0x49, // SPECIES_LOUDRED
+ 0x19, // SPECIES_EXPLOUD
+ 0x12, // SPECIES_CLAMPERL
+ 0x09, // SPECIES_HUNTAIL
+ 0x1c, // SPECIES_GOREBYSS
+ 0x11, // SPECIES_ABSOL
+ 0x1c, // SPECIES_SHUPPET
+ 0x0d, // SPECIES_BANETTE
+ 0x17, // SPECIES_SEVIPER
+ 0x09, // SPECIES_ZANGOOSE
+ 0x1a, // SPECIES_RELICANTH
+ 0x45, // SPECIES_ARON
+ 0x00, // SPECIES_LAIRON
+ 0x19, // SPECIES_AGGRON
+ 0x1d, // SPECIES_CASTFORM
+ 0x00, // SPECIES_VOLBEAT
+ 0x05, // SPECIES_ILLUMISE
+ 0x17, // SPECIES_LILEEP
+ 0x19, // SPECIES_CRADILY
+ 0x12, // SPECIES_ANORITH
+ 0x10, // SPECIES_ARMALDO
+ 0x45, // SPECIES_RALTS
+ 0x00, // SPECIES_KIRLIA
+ 0x00, // SPECIES_GARDEVOIR
+ 0x19, // SPECIES_BAGON
+ 0x04, // SPECIES_SHELGON
+ 0x0f, // SPECIES_SALAMENCE
+ 0x0f, // SPECIES_BELDUM
+ 0x04, // SPECIES_METANG
+ 0x10, // SPECIES_METAGROSS
+ 0x01, // SPECIES_REGIROCK
+ 0x44, // SPECIES_REGICE
+ 0x09, // SPECIES_REGISTEEL
+ 0x2d, // SPECIES_KYOGRE
+ 0x10, // SPECIES_GROUDON
+ 0x0f, // SPECIES_RAYQUAZA
+ 0x2d, // SPECIES_LATIAS
+ 0x10, // SPECIES_LATIOS
+ 0x0d, // SPECIES_JIRACHI
+ 0x1b, // SPECIES_DEOXYS
+ 0x1d, // SPECIES_CHIMECHO
+};
+
+static const u8 sMonAnimationDelayTable[] =
+{
+ 0x00, // SPECIES_BULBASAUR
+ 0x00, // SPECIES_IVYSAUR
+ 0x00, // SPECIES_VENUSAUR
+ 0x00, // SPECIES_CHARMANDER
+ 0x00, // SPECIES_CHARMELEON
+ 0x00, // SPECIES_CHARIZARD
+ 0x00, // SPECIES_SQUIRTLE
+ 0x00, // SPECIES_WARTORTLE
+ 0x32, // SPECIES_BLASTOISE
+ 0x00, // SPECIES_CATERPIE
+ 0x00, // SPECIES_METAPOD
+ 0x00, // SPECIES_BUTTERFREE
+ 0x0a, // SPECIES_WEEDLE
+ 0x14, // SPECIES_KAKUNA
+ 0x23, // SPECIES_BEEDRILL
+ 0x00, // SPECIES_PIDGEY
+ 0x19, // SPECIES_PIDGEOTTO
+ 0x00, // SPECIES_PIDGEOT
+ 0x00, // SPECIES_RATTATA
+ 0x00, // SPECIES_RATICATE
+ 0x00, // SPECIES_SPEAROW
+ 0x02, // SPECIES_FEAROW
+ 0x1e, // SPECIES_EKANS
+ 0x00, // SPECIES_ARBOK
+ 0x00, // SPECIES_PIKACHU
+ 0x00, // SPECIES_RAICHU
+ 0x00, // SPECIES_SANDSHREW
+ 0x00, // SPECIES_SANDSLASH
+ 0x1c, // SPECIES_NIDORAN_F
+ 0x00, // SPECIES_NIDORINA
+ 0x00, // SPECIES_NIDOQUEEN
+ 0x00, // SPECIES_NIDORAN_M
+ 0x00, // SPECIES_NIDORINO
+ 0x19, // SPECIES_NIDOKING
+ 0x00, // SPECIES_CLEFAIRY
+ 0x00, // SPECIES_CLEFABLE
+ 0x00, // SPECIES_VULPIX
+ 0x00, // SPECIES_NINETALES
+ 0x00, // SPECIES_JIGGLYPUFF
+ 0x00, // SPECIES_WIGGLYTUFF
+ 0x00, // SPECIES_ZUBAT
+ 0x00, // SPECIES_GOLBAT
+ 0x00, // SPECIES_ODDISH
+ 0x00, // SPECIES_GLOOM
+ 0x00, // SPECIES_VILEPLUME
+ 0x0a, // SPECIES_PARAS
+ 0x2d, // SPECIES_PARASECT
+ 0x14, // SPECIES_VENONAT
+ 0x00, // SPECIES_VENOMOTH
+ 0x19, // SPECIES_DIGLETT
+ 0x23, // SPECIES_DUGTRIO
+ 0x28, // SPECIES_MEOWTH
+ 0x14, // SPECIES_PERSIAN
+ 0x00, // SPECIES_PSYDUCK
+ 0x00, // SPECIES_GOLDUCK
+ 0x14, // SPECIES_MANKEY
+ 0x00, // SPECIES_PRIMEAPE
+ 0x1e, // SPECIES_GROWLITHE
+ 0x28, // SPECIES_ARCANINE
+ 0x00, // SPECIES_POLIWAG
+ 0x05, // SPECIES_POLIWHIRL
+ 0x00, // SPECIES_POLIWRATH
+ 0x00, // SPECIES_ABRA
+ 0x00, // SPECIES_KADABRA
+ 0x00, // SPECIES_ALAKAZAM
+ 0x00, // SPECIES_MACHOP
+ 0x00, // SPECIES_MACHOKE
+ 0x00, // SPECIES_MACHAMP
+ 0x00, // SPECIES_BELLSPROUT
+ 0x03, // SPECIES_WEEPINBELL
+ 0x00, // SPECIES_VICTREEBEL
+ 0x00, // SPECIES_TENTACOOL
+ 0x00, // SPECIES_TENTACRUEL
+ 0x00, // SPECIES_GEODUDE
+ 0x00, // SPECIES_GRAVELER
+ 0x00, // SPECIES_GOLEM
+ 0x00, // SPECIES_PONYTA
+ 0x00, // SPECIES_RAPIDASH
+ 0x00, // SPECIES_SLOWPOKE
+ 0x00, // SPECIES_SLOWBRO
+ 0x00, // SPECIES_MAGNEMITE
+ 0x00, // SPECIES_MAGNETON
+ 0x00, // SPECIES_FARFETCHD
+ 0x00, // SPECIES_DODUO
+ 0x00, // SPECIES_DODRIO
+ 0x00, // SPECIES_SEEL
+ 0x00, // SPECIES_DEWGONG
+ 0x00, // SPECIES_GRIMER
+ 0x2d, // SPECIES_MUK
+ 0x14, // SPECIES_SHELLDER
+ 0x00, // SPECIES_CLOYSTER
+ 0x00, // SPECIES_GASTLY
+ 0x17, // SPECIES_HAUNTER
+ 0x00, // SPECIES_GENGAR
+ 0x00, // SPECIES_ONIX
+ 0x30, // SPECIES_DROWZEE
+ 0x28, // SPECIES_HYPNO
+ 0x00, // SPECIES_KRABBY
+ 0x00, // SPECIES_KINGLER
+ 0x00, // SPECIES_VOLTORB
+ 0x00, // SPECIES_ELECTRODE
+ 0x00, // SPECIES_EXEGGCUTE
+ 0x00, // SPECIES_EXEGGUTOR
+ 0x00, // SPECIES_CUBONE
+ 0x00, // SPECIES_MAROWAK
+ 0x00, // SPECIES_HITMONLEE
+ 0x19, // SPECIES_HITMONCHAN
+ 0x00, // SPECIES_LICKITUNG
+ 0x00, // SPECIES_KOFFING
+ 0x00, // SPECIES_WEEZING
+ 0x00, // SPECIES_RHYHORN
+ 0x00, // SPECIES_RHYDON
+ 0x00, // SPECIES_CHANSEY
+ 0x00, // SPECIES_TANGELA
+ 0x00, // SPECIES_KANGASKHAN
+ 0x00, // SPECIES_HORSEA
+ 0x00, // SPECIES_SEADRA
+ 0x00, // SPECIES_GOLDEEN
+ 0x00, // SPECIES_SEAKING
+ 0x00, // SPECIES_STARYU
+ 0x00, // SPECIES_STARMIE
+ 0x00, // SPECIES_MR_MIME
+ 0x0a, // SPECIES_SCYTHER
+ 0x00, // SPECIES_JYNX
+ 0x00, // SPECIES_ELECTABUZZ
+ 0x00, // SPECIES_MAGMAR
+ 0x00, // SPECIES_PINSIR
+ 0x0a, // SPECIES_TAUROS
+ 0x00, // SPECIES_MAGIKARP
+ 0x00, // SPECIES_GYARADOS
+ 0x00, // SPECIES_LAPRAS
+ 0x00, // SPECIES_DITTO
+ 0x00, // SPECIES_EEVEE
+ 0x00, // SPECIES_VAPOREON
+ 0x00, // SPECIES_JOLTEON
+ 0x00, // SPECIES_FLAREON
+ 0x00, // SPECIES_PORYGON
+ 0x00, // SPECIES_OMANYTE
+ 0x00, // SPECIES_OMASTAR
+ 0x00, // SPECIES_KABUTO
+ 0x00, // SPECIES_KABUTOPS
+ 0x00, // SPECIES_AERODACTYL
+ 0x00, // SPECIES_SNORLAX
+ 0x00, // SPECIES_ARTICUNO
+ 0x00, // SPECIES_ZAPDOS
+ 0x00, // SPECIES_MOLTRES
+ 0x00, // SPECIES_DRATINI
+ 0x00, // SPECIES_DRAGONAIR
+ 0x00, // SPECIES_DRAGONITE
+ 0x00, // SPECIES_MEWTWO
+ 0x00, // SPECIES_MEW
+ 0x00, // SPECIES_CHIKORITA
+ 0x00, // SPECIES_BAYLEEF
+ 0x00, // SPECIES_MEGANIUM
+ 0x00, // SPECIES_CYNDAQUIL
+ 0x00, // SPECIES_QUILAVA
+ 0x14, // SPECIES_TYPHLOSION
+ 0x00, // SPECIES_TOTODILE
+ 0x00, // SPECIES_CROCONAW
+ 0x05, // SPECIES_FERALIGATR
+ 0x00, // SPECIES_SENTRET
+ 0x00, // SPECIES_FURRET
+ 0x00, // SPECIES_HOOTHOOT
+ 0x00, // SPECIES_NOCTOWL
+ 0x00, // SPECIES_LEDYBA
+ 0x00, // SPECIES_LEDIAN
+ 0x00, // SPECIES_SPINARAK
+ 0x00, // SPECIES_ARIADOS
+ 0x00, // SPECIES_CROBAT
+ 0x00, // SPECIES_CHINCHOU
+ 0x00, // SPECIES_LANTURN
+ 0x00, // SPECIES_PICHU
+ 0x00, // SPECIES_CLEFFA
+ 0x00, // SPECIES_IGGLYBUFF
+ 0x00, // SPECIES_TOGEPI
+ 0x00, // SPECIES_TOGETIC
+ 0x1e, // SPECIES_NATU
+ 0x00, // SPECIES_XATU
+ 0x32, // SPECIES_MAREEP
+ 0x00, // SPECIES_FLAAFFY
+ 0x0a, // SPECIES_AMPHAROS
+ 0x00, // SPECIES_BELLOSSOM
+ 0x00, // SPECIES_MARILL
+ 0x00, // SPECIES_AZUMARILL
+ 0x00, // SPECIES_SUDOWOODO
+ 0x28, // SPECIES_POLITOED
+ 0x00, // SPECIES_HOPPIP
+ 0x00, // SPECIES_SKIPLOOM
+ 0x00, // SPECIES_JUMPLUFF
+ 0x00, // SPECIES_AIPOM
+ 0x00, // SPECIES_SUNKERN
+ 0x00, // SPECIES_SUNFLORA
+ 0x00, // SPECIES_YANMA
+ 0x00, // SPECIES_WOOPER
+ 0x00, // SPECIES_QUAGSIRE
+ 0x00, // SPECIES_ESPEON
+ 0x00, // SPECIES_UMBREON
+ 0x00, // SPECIES_MURKROW
+ 0x00, // SPECIES_SLOWKING
+ 0x00, // SPECIES_MISDREAVUS
+ 0x00, // SPECIES_UNOWN
+ 0x00, // SPECIES_WOBBUFFET
+ 0x00, // SPECIES_GIRAFARIG
+ 0x00, // SPECIES_PINECO
+ 0x00, // SPECIES_FORRETRESS
+ 0x0a, // SPECIES_DUNSPARCE
+ 0x00, // SPECIES_GLIGAR
+ 0x2d, // SPECIES_STEELIX
+ 0x00, // SPECIES_SNUBBULL
+ 0x00, // SPECIES_GRANBULL
+ 0x27, // SPECIES_QWILFISH
+ 0x13, // SPECIES_SCIZOR
+ 0x00, // SPECIES_SHUCKLE
+ 0x00, // SPECIES_HERACROSS
+ 0x00, // SPECIES_SNEASEL
+ 0x00, // SPECIES_TEDDIURSA
+ 0x00, // SPECIES_URSARING
+ 0x00, // SPECIES_SLUGMA
+ 0x00, // SPECIES_MAGCARGO
+ 0x00, // SPECIES_SWINUB
+ 0x00, // SPECIES_PILOSWINE
+ 0x00, // SPECIES_CORSOLA
+ 0x00, // SPECIES_REMORAID
+ 0x14, // SPECIES_OCTILLERY
+ 0x00, // SPECIES_DELIBIRD
+ 0x00, // SPECIES_MANTINE
+ 0x00, // SPECIES_SKARMORY
+ 0x00, // SPECIES_HOUNDOUR
+ 0x00, // SPECIES_HOUNDOOM
+ 0x00, // SPECIES_KINGDRA
+ 0x00, // SPECIES_PHANPY
+ 0x00, // SPECIES_DONPHAN
+ 0x00, // SPECIES_PORYGON2
+ 0x00, // SPECIES_STANTLER
+ 0x00, // SPECIES_SMEARGLE
+ 0x00, // SPECIES_TYROGUE
+ 0x00, // SPECIES_HITMONTOP
+ 0x28, // SPECIES_SMOOCHUM
+ 0x00, // SPECIES_ELEKID
+ 0x00, // SPECIES_MAGBY
+ 0x00, // SPECIES_MILTANK
+ 0x00, // SPECIES_BLISSEY
+ 0x00, // SPECIES_RAIKOU
+ 0x00, // SPECIES_ENTEI
+ 0x00, // SPECIES_SUICUNE
+ 0x00, // SPECIES_LARVITAR
+ 0x00, // SPECIES_PUPITAR
+ 0x0a, // SPECIES_TYRANITAR
+ 0x14, // SPECIES_LUGIA
+ 0x00, // SPECIES_HO_OH
+ 0x00, // SPECIES_CELEBI
+ 0x00, // 252
+ 0x00, // 253
+ 0x00, // 254
+ 0x00, // 255
+ 0x00, // 256
+ 0x00, // 257
+ 0x00, // 258
+ 0x00, // 259
+ 0x00, // 260
+ 0x00, // 261
+ 0x00, // 262
+ 0x00, // 263
+ 0x00, // 264
+ 0x00, // 265
+ 0x00, // 266
+ 0x00, // 267
+ 0x00, // 268
+ 0x00, // 269
+ 0x00, // 270
+ 0x00, // 271
+ 0x00, // 272
+ 0x00, // 273
+ 0x00, // 274
+ 0x00, // 275
+ 0x00, // 276
+ 0x00, // SPECIES_TREECKO
+ 0x00, // SPECIES_GROVYLE
+ 0x00, // SPECIES_SCEPTILE
+ 0x00, // SPECIES_TORCHIC
+ 0x00, // SPECIES_COMBUSKEN
+ 0x00, // SPECIES_BLAZIKEN
+ 0x00, // SPECIES_MUDKIP
+ 0x00, // SPECIES_MARSHTOMP
+ 0x00, // SPECIES_SWAMPERT
+ 0x00, // SPECIES_POOCHYENA
+ 0x00, // SPECIES_MIGHTYENA
+ 0x00, // SPECIES_ZIGZAGOON
+ 0x00, // SPECIES_LINOONE
+ 0x00, // SPECIES_WURMPLE
+ 0x00, // SPECIES_SILCOON
+ 0x00, // SPECIES_BEAUTIFLY
+ 0x00, // SPECIES_CASCOON
+ 0x00, // SPECIES_DUSTOX
+ 0x00, // SPECIES_LOTAD
+ 0x00, // SPECIES_LOMBRE
+ 0x00, // SPECIES_LUDICOLO
+ 0x00, // SPECIES_SEEDOT
+ 0x00, // SPECIES_NUZLEAF
+ 0x00, // SPECIES_SHIFTRY
+ 0x00, // SPECIES_NINCADA
+ 0x00, // SPECIES_NINJASK
+ 0x00, // SPECIES_SHEDINJA
+ 0x00, // SPECIES_TAILLOW
+ 0x00, // SPECIES_SWELLOW
+ 0x00, // SPECIES_SHROOMISH
+ 0x00, // SPECIES_BRELOOM
+ 0x00, // SPECIES_SPINDA
+ 0x00, // SPECIES_WINGULL
+ 0x00, // SPECIES_PELIPPER
+ 0x00, // SPECIES_SURSKIT
+ 0x00, // SPECIES_MASQUERAIN
+ 0x00, // SPECIES_WAILMER
+ 0x0a, // SPECIES_WAILORD
+ 0x00, // SPECIES_SKITTY
+ 0x00, // SPECIES_DELCATTY
+ 0x1e, // SPECIES_KECLEON
+ 0x00, // SPECIES_BALTOY
+ 0x00, // SPECIES_CLAYDOL
+ 0x00, // SPECIES_NOSEPASS
+ 0x00, // SPECIES_TORKOAL
+ 0x00, // SPECIES_SABLEYE
+ 0x00, // SPECIES_BARBOACH
+ 0x00, // SPECIES_WHISCASH
+ 0x00, // SPECIES_LUVDISC
+ 0x00, // SPECIES_CORPHISH
+ 0x00, // SPECIES_CRAWDAUNT
+ 0x00, // SPECIES_FEEBAS
+ 0x2d, // SPECIES_MILOTIC
+ 0x00, // SPECIES_CARVANHA
+ 0x00, // SPECIES_SHARPEDO
+ 0x00, // SPECIES_TRAPINCH
+ 0x00, // SPECIES_VIBRAVA
+ 0x00, // SPECIES_FLYGON
+ 0x00, // SPECIES_MAKUHITA
+ 0x00, // SPECIES_HARIYAMA
+ 0x00, // SPECIES_ELECTRIKE
+ 0x00, // SPECIES_MANECTRIC
+ 0x00, // SPECIES_NUMEL
+ 0x00, // SPECIES_CAMERUPT
+ 0x0f, // SPECIES_SPHEAL
+ 0x00, // SPECIES_SEALEO
+ 0x00, // SPECIES_WALREIN
+ 0x00, // SPECIES_CACNEA
+ 0x00, // SPECIES_CACTURNE
+ 0x14, // SPECIES_SNORUNT
+ 0x00, // SPECIES_GLALIE
+ 0x00, // SPECIES_LUNATONE
+ 0x00, // SPECIES_SOLROCK
+ 0x00, // SPECIES_AZURILL
+ 0x00, // SPECIES_SPOINK
+ 0x0f, // SPECIES_GRUMPIG
+ 0x00, // SPECIES_PLUSLE
+ 0x00, // SPECIES_MINUN
+ 0x00, // SPECIES_MAWILE
+ 0x00, // SPECIES_MEDITITE
+ 0x00, // SPECIES_MEDICHAM
+ 0x00, // SPECIES_SWABLU
+ 0x00, // SPECIES_ALTARIA
+ 0x0f, // SPECIES_WYNAUT
+ 0x00, // SPECIES_DUSKULL
+ 0x1e, // SPECIES_DUSCLOPS
+ 0x00, // SPECIES_ROSELIA
+ 0x00, // SPECIES_SLAKOTH
+ 0x00, // SPECIES_VIGOROTH
+ 0x00, // SPECIES_SLAKING
+ 0x00, // SPECIES_GULPIN
+ 0x00, // SPECIES_SWALOT
+ 0x00, // SPECIES_TROPIUS
+ 0x00, // SPECIES_WHISMUR
+ 0x00, // SPECIES_LOUDRED
+ 0x00, // SPECIES_EXPLOUD
+ 0x00, // SPECIES_CLAMPERL
+ 0x00, // SPECIES_HUNTAIL
+ 0x00, // SPECIES_GOREBYSS
+ 0x2d, // SPECIES_ABSOL
+ 0x00, // SPECIES_SHUPPET
+ 0x00, // SPECIES_BANETTE
+ 0x00, // SPECIES_SEVIPER
+ 0x00, // SPECIES_ZANGOOSE
+ 0x00, // SPECIES_RELICANTH
+ 0x00, // SPECIES_ARON
+ 0x00, // SPECIES_LAIRON
+ 0x00, // SPECIES_AGGRON
+ 0x00, // SPECIES_CASTFORM
+ 0x00, // SPECIES_VOLBEAT
+ 0x00, // SPECIES_ILLUMISE
+ 0x00, // SPECIES_LILEEP
+ 0x00, // SPECIES_CRADILY
+ 0x00, // SPECIES_ANORITH
+ 0x00, // SPECIES_ARMALDO
+ 0x00, // SPECIES_RALTS
+ 0x00, // SPECIES_KIRLIA
+ 0x00, // SPECIES_GARDEVOIR
+ 0x00, // SPECIES_BAGON
+ 0x00, // SPECIES_SHELGON
+ 0x46, // SPECIES_SALAMENCE
+ 0x00, // SPECIES_BELDUM
+ 0x00, // SPECIES_METANG
+ 0x00, // SPECIES_METAGROSS
+ 0x00, // SPECIES_REGIROCK
+ 0x00, // SPECIES_REGICE
+ 0x00, // SPECIES_REGISTEEL
+ 0x3c, // SPECIES_KYOGRE
+ 0x00, // SPECIES_GROUDON
+ 0x3c, // SPECIES_RAYQUAZA
+ 0x00, // SPECIES_LATIAS
+ 0x00, // SPECIES_LATIOS
+ 0x00, // SPECIES_JIRACHI
+ 0x00, // SPECIES_DEOXYS
+ 0x00, // SPECIES_CHIMECHO
+};
+
+const u8 gUnknown_08329D22[] = {0x03, 0x0c, 0x30, 0xc0}; // Masks for getting PP Up count, also PP Max values
+const u8 gUnknown_08329D26[] = {0xfc, 0xf3, 0xcf, 0x3f}; // Masks for setting PP Up count
+const u8 gUnknown_08329D2A[] = {0x01, 0x04, 0x10, 0x40}; // Values added to PP Up count
+
+const u8 gStatStageRatios[][2] =
+{
+ {10, 40}, // -6
+ {10, 35}, // -5
+ {10, 30}, // -4
+ {10, 25}, // -3
+ {10, 20}, // -2
+ {10, 15}, // -1
+ {10, 10}, // 0
+ {15, 10}, // +1
+ {20, 10}, // +2
+ {25, 10}, // +3
+ {30, 10}, // +4
+ {35, 10}, // +5
+ {40, 10}, // +6
+};
+
+static const u16 sDeoxysBaseStats[] =
+{
+ 50, // Hp
+ 95, // Attack
+ 90, // Defense
+ 180, // Speed
+ 95, // Sp.Attack
+ 90, // Sp.Defense
+};
+
+const u16 gUnknown_08329D54[] =
+{
+ FACILITY_CLASS_COOLTRAINER_M, FACILITY_CLASS_BLACK_BELT, FACILITY_CLASS_CAMPER,
+ FACILITY_CLASS_YOUNGSTER, FACILITY_CLASS_PSYCHIC_M, FACILITY_CLASS_BUG_CATCHER,
+ FACILITY_CLASS_PKMN_BREEDER_2, FACILITY_CLASS_GUITARIST, FACILITY_CLASS_COOLTRAINER_F,
+ FACILITY_CLASS_HEX_MANIAC, FACILITY_CLASS_PICNICKER, FACILITY_CLASS_LASS,
+ FACILITY_CLASS_PSYCHIC_F, FACILITY_CLASS_BATTLE_GIRL, FACILITY_CLASS_PKMN_BREEDER_1,
+ FACILITY_CLASS_BEAUTY
+};
+
+static const u8 sHoldEffectToType[][2] =
+{
+ {HOLD_EFFECT_BUG_POWER, TYPE_BUG},
+ {HOLD_EFFECT_STEEL_POWER, TYPE_STEEL},
+ {HOLD_EFFECT_GROUND_POWER, TYPE_GROUND},
+ {HOLD_EFFECT_ROCK_POWER, TYPE_ROCK},
+ {HOLD_EFFECT_GRASS_POWER, TYPE_GRASS},
+ {HOLD_EFFECT_DARK_POWER, TYPE_DARK},
+ {HOLD_EFFECT_FIGHTING_POWER, TYPE_FIGHTING},
+ {HOLD_EFFECT_ELECTRIC_POWER, TYPE_ELECTRIC},
+ {HOLD_EFFECT_WATER_POWER, TYPE_WATER},
+ {HOLD_EFFECT_FLYING_POWER, TYPE_FLYING},
+ {HOLD_EFFECT_POISON_POWER, TYPE_POISON},
+ {HOLD_EFFECT_ICE_POWER, TYPE_ICE},
+ {HOLD_EFFECT_GHOST_POWER, TYPE_GHOST},
+ {HOLD_EFFECT_PSYCHIC_POWER, TYPE_PSYCHIC},
+ {HOLD_EFFECT_FIRE_POWER, TYPE_FIRE},
+ {HOLD_EFFECT_DRAGON_POWER, TYPE_DRAGON},
+ {HOLD_EFFECT_NORMAL_POWER, TYPE_NORMAL},
+};
+
+const struct SpriteTemplate gUnknown_08329D98[MAX_BATTLERS_COUNT] =
+{
+ { // B_POSITION_PLAYER_LEFT
+ .tileTag = 0xFFFF,
+ .paletteTag = 0,
+ .oam = &gUnknown_0831ACB0,
+ .anims = NULL,
+ .images = gUnknown_082FF3A8,
+ .affineAnims = gUnknown_082FF618,
+ .callback = sub_8039BB4,
+ },
+ { // B_POSITION_OPPONENT_LEFT
+ .tileTag = 0xFFFF,
+ .paletteTag = 0,
+ .oam = &gUnknown_0831ACA8,
+ .anims = NULL,
+ .images = gUnknown_082FF3C8,
+ .affineAnims = gUnknown_082FF694,
+ .callback = oac_poke_opponent,
+ },
+ { // B_POSITION_PLAYER_RIGHT
+ .tileTag = 0xFFFF,
+ .paletteTag = 0,
+ .oam = &gUnknown_0831ACB0,
+ .anims = NULL,
+ .images = gUnknown_082FF3E8,
+ .affineAnims = gUnknown_082FF618,
+ .callback = sub_8039BB4,
+ },
+ { // B_POSITION_OPPONENT_RIGHT
+ .tileTag = 0xFFFF,
+ .paletteTag = 0,
+ .oam = &gUnknown_0831ACA8,
+ .anims = NULL,
+ .images = gUnknown_082FF408,
+ .affineAnims = gUnknown_082FF694,
+ .callback = oac_poke_opponent
+ },
+};
+
+static const struct SpriteTemplate gUnknown_08329DF8[] =
+{
+ {
+ .tileTag = 0xFFFF,
+ .paletteTag = 0,
+ .oam = &gUnknown_0831ACB0,
+ .anims = NULL,
+ .images = gUnknown_082FF428,
+ .affineAnims = gUnknown_082FF618,
+ .callback = sub_8039BB4,
+ },
+ {
+ .tileTag = 0xFFFF,
+ .paletteTag = 0,
+ .oam = &gUnknown_0831ACB0,
+ .anims = NULL,
+ .images = gUnknown_082FF448,
+ .affineAnims = gUnknown_082FF618,
+ .callback = sub_8039BB4,
+ },
+ {
+ .tileTag = 0xFFFF,
+ .paletteTag = 0,
+ .oam = &gUnknown_0831ACB0,
+ .anims = NULL,
+ .images = gUnknown_082FF468,
+ .affineAnims = gUnknown_082FF618,
+ .callback = sub_8039BB4,
+ },
+ {
+ .tileTag = 0xFFFF,
+ .paletteTag = 0,
+ .oam = &gUnknown_0831ACB0,
+ .anims = NULL,
+ .images = gUnknown_082FF490,
+ .affineAnims = gUnknown_082FF618,
+ .callback = sub_8039BB4,
+ },
+ {
+ .tileTag = 0xFFFF,
+ .paletteTag = 0,
+ .oam = &gUnknown_0831ACB0,
+ .anims = NULL,
+ .images = gUnknown_082FF4B8,
+ .affineAnims = gUnknown_082FF618,
+ .callback = sub_8039BB4,
+ },
+ {
+ .tileTag = 0xFFFF,
+ .paletteTag = 0,
+ .oam = &gUnknown_0831ACB0,
+ .anims = NULL,
+ .images = gUnknown_082FF4D8,
+ .affineAnims = gUnknown_082FF618,
+ .callback = sub_8039BB4,
+ },
+ {
+ .tileTag = 0xFFFF,
+ .paletteTag = 0,
+ .oam = &gUnknown_0831ACB0,
+ .anims = NULL,
+ .images = gUnknown_082FF4F8,
+ .affineAnims = gUnknown_082FF618,
+ .callback = sub_8039BB4,
+ },
+ {
+ .tileTag = 0xFFFF,
+ .paletteTag = 0,
+ .oam = &gUnknown_0831ACB0,
+ .anims = NULL,
+ .images = gUnknown_082FF518,
+ .affineAnims = gUnknown_082FF618,
+ .callback = sub_8039BB4,
+ },
+};
+
+static const u8 sSecretBaseFacilityClasses[2][5] =
+{
+ {FACILITY_CLASS_YOUNGSTER, FACILITY_CLASS_BUG_CATCHER, FACILITY_CLASS_RICH_BOY, FACILITY_CLASS_CAMPER, FACILITY_CLASS_COOLTRAINER_M},
+ {FACILITY_CLASS_LASS, FACILITY_CLASS_SCHOOL_KID_F, FACILITY_CLASS_LADY, FACILITY_CLASS_PICNICKER, FACILITY_CLASS_COOLTRAINER_F}
+};
+
+static const u8 sGetMonDataEVConstants[] =
+{
+ MON_DATA_HP_EV,
+ MON_DATA_ATK_EV,
+ MON_DATA_DEF_EV,
+ MON_DATA_SPEED_EV,
+ MON_DATA_SPDEF_EV,
+ MON_DATA_SPATK_EV
+};
+
+static const u8 gUnknown_08329EC8[] =
+{
+ STAT_ATK, STAT_ATK, STAT_SPEED, STAT_DEF, STAT_SPATK, STAT_ACC
+};
+
+static const s8 gUnknown_08329ECE[][3] =
+{
+ { 5, 3, 2},
+ { 5, 3, 2},
+ { 1, 1, 0},
+ { 3, 2, 1},
+ { 1, 1, 0},
+ { 1, 1, 1},
+ {-1, -1, -1},
+ {-5, -5, -10},
+ {-5, -5, -10},
+};
+
+static const u16 sHMMoves[] =
+{
+ MOVE_CUT, MOVE_FLY, MOVE_SURF, MOVE_STRENGTH, MOVE_FLASH,
+ MOVE_ROCK_SMASH, MOVE_WATERFALL, MOVE_DIVE, 0xFFFF
+};
+
+static const struct SpeciesItem sAlteringCaveWildMonHeldItems[] =
+{
+ {SPECIES_NONE, ITEM_NONE},
+ {SPECIES_MAREEP, ITEM_GANLON_BERRY},
+ {SPECIES_PINECO, ITEM_APICOT_BERRY},
+ {SPECIES_HOUNDOUR, ITEM_BIG_MUSHROOM},
+ {SPECIES_TEDDIURSA, ITEM_PETAYA_BERRY},
+ {SPECIES_AIPOM, ITEM_BERRY_JUICE},
+ {SPECIES_SHUCKLE, ITEM_BERRY_JUICE},
+ {SPECIES_STANTLER, ITEM_PETAYA_BERRY},
+ {SPECIES_SMEARGLE, ITEM_SALAC_BERRY},
+};
+
+static const struct OamData sOamData_8329F20 =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 3,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0
+};
+
+static const struct SpriteTemplate gUnknown_08329F28 =
+{
+ .tileTag = 0xFFFF,
+ .paletteTag = 0xFFFF,
+ .oam = &sOamData_8329F20,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+// code
+void ZeroBoxMonData(struct BoxPokemon *boxMon)
+{
+ u8 *raw = (u8 *)boxMon;
+ u32 i;
+ for (i = 0; i < sizeof(struct BoxPokemon); i++)
+ raw[i] = 0;
+}
+
+void ZeroMonData(struct Pokemon *mon)
+{
+ u32 arg;
+ ZeroBoxMonData(&mon->box);
+ arg = 0;
+ SetMonData(mon, MON_DATA_STATUS, &arg);
+ SetMonData(mon, MON_DATA_LEVEL, &arg);
+ SetMonData(mon, MON_DATA_HP, &arg);
+ SetMonData(mon, MON_DATA_MAX_HP, &arg);
+ SetMonData(mon, MON_DATA_ATK, &arg);
+ SetMonData(mon, MON_DATA_DEF, &arg);
+ SetMonData(mon, MON_DATA_SPEED, &arg);
+ SetMonData(mon, MON_DATA_SPATK, &arg);
+ SetMonData(mon, MON_DATA_SPDEF, &arg);
+ arg = 255;
+ SetMonData(mon, MON_DATA_MAIL, &arg);
+}
+
+void ZeroPlayerPartyMons(void)
+{
+ s32 i;
+ for (i = 0; i < PARTY_SIZE; i++)
+ ZeroMonData(&gPlayerParty[i]);
+}
+
+void ZeroEnemyPartyMons(void)
+{
+ s32 i;
+ for (i = 0; i < PARTY_SIZE; i++)
+ ZeroMonData(&gEnemyParty[i]);
+}
+
+void CreateMon(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 hasFixedPersonality, u32 fixedPersonality, u8 otIdType, u32 fixedOtId)
+{
+ u32 arg;
+ ZeroMonData(mon);
+ CreateBoxMon(&mon->box, species, level, fixedIV, hasFixedPersonality, fixedPersonality, otIdType, fixedOtId);
+ SetMonData(mon, MON_DATA_LEVEL, &level);
+ arg = 255;
+ SetMonData(mon, MON_DATA_MAIL, &arg);
+ CalculateMonStats(mon);
+}
+
+void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV, u8 hasFixedPersonality, u32 fixedPersonality, u8 otIdType, u32 fixedOtId)
+{
+ u8 speciesName[POKEMON_NAME_LENGTH + 1];
+ u32 personality;
+ u32 value;
+ u16 checksum;
+
+ ZeroBoxMonData(boxMon);
+
+ if (hasFixedPersonality)
+ personality = fixedPersonality;
+ else
+ personality = Random32();
+
+ SetBoxMonData(boxMon, MON_DATA_PERSONALITY, &personality);
+
+ //Determine original trainer ID
+ if (otIdType == OT_ID_RANDOM_NO_SHINY) //Pokemon cannot be shiny
+ {
+ u32 shinyValue;
+ do
+ {
+ value = Random32();
+ shinyValue = HIHALF(value) ^ LOHALF(value) ^ HIHALF(personality) ^ LOHALF(personality);
+ } while (shinyValue < 8);
+ }
+ else if (otIdType == OT_ID_PRESET) //Pokemon has a preset OT ID
+ {
+ value = fixedOtId;
+ }
+ else //Player is the OT
+ {
+ value = gSaveBlock2Ptr->playerTrainerId[0]
+ | (gSaveBlock2Ptr->playerTrainerId[1] << 8)
+ | (gSaveBlock2Ptr->playerTrainerId[2] << 16)
+ | (gSaveBlock2Ptr->playerTrainerId[3] << 24);
+ }
+
+ SetBoxMonData(boxMon, MON_DATA_OT_ID, &value);
+
+ checksum = CalculateBoxMonChecksum(boxMon);
+ SetBoxMonData(boxMon, MON_DATA_CHECKSUM, &checksum);
+ EncryptBoxMon(boxMon);
+ GetSpeciesName(speciesName, species);
+ SetBoxMonData(boxMon, MON_DATA_NICKNAME, speciesName);
+ SetBoxMonData(boxMon, MON_DATA_LANGUAGE, &gGameLanguage);
+ SetBoxMonData(boxMon, MON_DATA_OT_NAME, gSaveBlock2Ptr->playerName);
+ SetBoxMonData(boxMon, MON_DATA_SPECIES, &species);
+ SetBoxMonData(boxMon, MON_DATA_EXP, &gExperienceTables[gBaseStats[species].growthRate][level]);
+ SetBoxMonData(boxMon, MON_DATA_FRIENDSHIP, &gBaseStats[species].friendship);
+ value = sav1_map_get_name();
+ SetBoxMonData(boxMon, MON_DATA_MET_LOCATION, &value);
+ SetBoxMonData(boxMon, MON_DATA_MET_LEVEL, &level);
+ SetBoxMonData(boxMon, MON_DATA_MET_GAME, &gGameVersion);
+ value = ITEM_POKE_BALL;
+ SetBoxMonData(boxMon, MON_DATA_POKEBALL, &value);
+ SetBoxMonData(boxMon, MON_DATA_OT_GENDER, &gSaveBlock2Ptr->playerGender);
+
+ if (fixedIV < 32)
+ {
+ SetBoxMonData(boxMon, MON_DATA_HP_IV, &fixedIV);
+ SetBoxMonData(boxMon, MON_DATA_ATK_IV, &fixedIV);
+ SetBoxMonData(boxMon, MON_DATA_DEF_IV, &fixedIV);
+ SetBoxMonData(boxMon, MON_DATA_SPEED_IV, &fixedIV);
+ SetBoxMonData(boxMon, MON_DATA_SPATK_IV, &fixedIV);
+ SetBoxMonData(boxMon, MON_DATA_SPDEF_IV, &fixedIV);
+ }
+ else
+ {
+ u32 iv;
+ value = Random();
+
+ iv = value & 0x1F;
+ SetBoxMonData(boxMon, MON_DATA_HP_IV, &iv);
+ iv = (value & 0x3E0) >> 5;
+ SetBoxMonData(boxMon, MON_DATA_ATK_IV, &iv);
+ iv = (value & 0x7C00) >> 10;
+ SetBoxMonData(boxMon, MON_DATA_DEF_IV, &iv);
+
+ value = Random();
+
+ iv = value & 0x1F;
+ SetBoxMonData(boxMon, MON_DATA_SPEED_IV, &iv);
+ iv = (value & 0x3E0) >> 5;
+ SetBoxMonData(boxMon, MON_DATA_SPATK_IV, &iv);
+ iv = (value & 0x7C00) >> 10;
+ SetBoxMonData(boxMon, MON_DATA_SPDEF_IV, &iv);
+ }
+
+ if (gBaseStats[species].ability2)
+ {
+ value = personality & 1;
+ SetBoxMonData(boxMon, MON_DATA_ALT_ABILITY, &value);
+ }
+
+ GiveBoxMonInitialMoveset(boxMon);
+}
+
+void CreateMonWithNature(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 nature)
+{
+ u32 personality;
+
+ do
+ {
+ personality = Random32();
+ }
+ while (nature != GetNatureFromPersonality(personality));
+
+ CreateMon(mon, species, level, fixedIV, 1, personality, OT_ID_PLAYER_ID, 0);
+}
+
+void CreateMonWithGenderNatureLetter(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 gender, u8 nature, u8 unownLetter)
+{
+ u32 personality;
+
+ if ((u8)(unownLetter - 1) < 28)
+ {
+ u16 actualLetter;
+
+ do
+ {
+ personality = Random32();
+ actualLetter = ((((personality & 0x3000000) >> 18) | ((personality & 0x30000) >> 12) | ((personality & 0x300) >> 6) | (personality & 0x3)) % 28);
+ }
+ while (nature != GetNatureFromPersonality(personality)
+ || gender != GetGenderFromSpeciesAndPersonality(species, personality)
+ || actualLetter != unownLetter - 1);
+ }
+ else
+ {
+ do
+ {
+ personality = Random32();
+ }
+ while (nature != GetNatureFromPersonality(personality)
+ || gender != GetGenderFromSpeciesAndPersonality(species, personality));
+ }
+
+ CreateMon(mon, species, level, fixedIV, 1, personality, OT_ID_PLAYER_ID, 0);
+}
+
+// This is only used to create Wally's Ralts.
+void CreateMaleMon(struct Pokemon *mon, u16 species, u8 level)
+{
+ u32 personality;
+ u32 otId;
+
+ do
+ {
+ otId = Random32();
+ personality = Random32();
+ }
+ while (GetGenderFromSpeciesAndPersonality(species, personality) != MON_MALE);
+ CreateMon(mon, species, level, 32, 1, personality, OT_ID_PRESET, otId);
+}
+
+void CreateMonWithIVsPersonality(struct Pokemon *mon, u16 species, u8 level, u32 ivs, u32 personality)
+{
+ CreateMon(mon, species, level, 0, 1, personality, OT_ID_PLAYER_ID, 0);
+ SetMonData(mon, MON_DATA_IVS, &ivs);
+ CalculateMonStats(mon);
+}
+
+void CreateMonWithIVsOTID(struct Pokemon *mon, u16 species, u8 level, u8 *ivs, u32 otId)
+{
+ CreateMon(mon, species, level, 0, 0, 0, OT_ID_PRESET, otId);
+ SetMonData(mon, MON_DATA_HP_IV, &ivs[0]);
+ SetMonData(mon, MON_DATA_ATK_IV, &ivs[1]);
+ SetMonData(mon, MON_DATA_DEF_IV, &ivs[2]);
+ SetMonData(mon, MON_DATA_SPEED_IV, &ivs[3]);
+ SetMonData(mon, MON_DATA_SPATK_IV, &ivs[4]);
+ SetMonData(mon, MON_DATA_SPDEF_IV, &ivs[5]);
+ CalculateMonStats(mon);
+}
+
+void CreateMonWithEVSpread(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 evSpread)
+{
+ s32 i;
+ s32 statCount = 0;
+ u16 evAmount;
+ u8 evsBits;
+
+ CreateMon(mon, species, level, fixedIV, 0, 0, 0, 0);
+
+ evsBits = evSpread;
+
+ for (i = 0; i < NUM_STATS; i++)
+ {
+ if (evsBits & 1)
+ statCount++;
+ evsBits >>= 1;
+ }
+
+ evAmount = MAX_TOTAL_EVS / statCount;
+
+ evsBits = 1;
+
+ for (i = 0; i < NUM_STATS; i++)
+ {
+ if (evSpread & evsBits)
+ SetMonData(mon, MON_DATA_HP_EV + i, &evAmount);
+ evsBits <<= 1;
+ }
+
+ CalculateMonStats(mon);
+}
+
+void sub_806819C(struct Pokemon *mon, struct UnknownPokemonStruct *src)
+{
+ s32 i;
+ u8 nickname[30];
+ u8 language;
+ u8 value;
+
+ CreateMon(mon, src->species, src->level, 0, 1, src->personality, 1, src->otId);
+
+ for (i = 0; i < 4; i++)
+ SetMonMoveSlot(mon, src->moves[i], i);
+
+ SetMonData(mon, MON_DATA_PP_BONUSES, &src->ppBonuses);
+ SetMonData(mon, MON_DATA_HELD_ITEM, &src->heldItem);
+ SetMonData(mon, MON_DATA_FRIENDSHIP, &src->friendship);
+
+ StringCopy(nickname, src->nickname);
+
+ if (nickname[0] == EXT_CTRL_CODE_BEGIN && nickname[1] == EXT_CTRL_CODE_JPN)
+ {
+ language = LANGUAGE_JAPANESE;
+ StripExtCtrlCodes(nickname);
+ }
+ else
+ {
+ language = GAME_LANGUAGE;
+ }
+
+ SetMonData(mon, MON_DATA_LANGUAGE, &language);
+ SetMonData(mon, MON_DATA_NICKNAME, nickname);
+ SetMonData(mon, MON_DATA_HP_EV, &src->hpEV);
+ SetMonData(mon, MON_DATA_ATK_EV, &src->attackEV);
+ SetMonData(mon, MON_DATA_DEF_EV, &src->defenseEV);
+ SetMonData(mon, MON_DATA_SPEED_EV, &src->speedEV);
+ SetMonData(mon, MON_DATA_SPATK_EV, &src->spAttackEV);
+ SetMonData(mon, MON_DATA_SPDEF_EV, &src->spDefenseEV);
+ value = src->altAbility;
+ SetMonData(mon, MON_DATA_ALT_ABILITY, &value);
+ value = src->hpIV;
+ SetMonData(mon, MON_DATA_HP_IV, &value);
+ value = src->attackIV;
+ SetMonData(mon, MON_DATA_ATK_IV, &value);
+ value = src->defenseIV;
+ SetMonData(mon, MON_DATA_DEF_IV, &value);
+ value = src->speedIV;
+ SetMonData(mon, MON_DATA_SPEED_IV, &value);
+ value = src->spAttackIV;
+ SetMonData(mon, MON_DATA_SPATK_IV, &value);
+ value = src->spDefenseIV;
+ SetMonData(mon, MON_DATA_SPDEF_IV, &value);
+ MonRestorePP(mon);
+ CalculateMonStats(mon);
+}
+
+void sub_8068338(struct Pokemon *mon, struct UnknownPokemonStruct *src, bool8 lvl50)
+{
+ s32 i;
+ u8 nickname[30];
+ u8 level;
+ u8 language;
+ u8 value;
+
+ if (gSaveBlock2Ptr->frontierChosenLvl != 0)
+ level = BattleFrontierGetOpponentLvl(gSaveBlock2Ptr->frontierChosenLvl);
+ else if (lvl50)
+ level = 50;
+ else
+ level = src->level;
+
+ CreateMon(mon, src->species, level, 0, 1, src->personality, 1, src->otId);
+
+ for (i = 0; i < 4; i++)
+ SetMonMoveSlot(mon, src->moves[i], i);
+
+ SetMonData(mon, MON_DATA_PP_BONUSES, &src->ppBonuses);
+ SetMonData(mon, MON_DATA_HELD_ITEM, &src->heldItem);
+ SetMonData(mon, MON_DATA_FRIENDSHIP, &src->friendship);
+
+ StringCopy(nickname, src->nickname);
+
+ if (nickname[0] == EXT_CTRL_CODE_BEGIN && nickname[1] == EXT_CTRL_CODE_JPN)
+ {
+ language = LANGUAGE_JAPANESE;
+ StripExtCtrlCodes(nickname);
+ }
+ else
+ {
+ language = GAME_LANGUAGE;
+ }
+
+ SetMonData(mon, MON_DATA_LANGUAGE, &language);
+ SetMonData(mon, MON_DATA_NICKNAME, nickname);
+ SetMonData(mon, MON_DATA_HP_EV, &src->hpEV);
+ SetMonData(mon, MON_DATA_ATK_EV, &src->attackEV);
+ SetMonData(mon, MON_DATA_DEF_EV, &src->defenseEV);
+ SetMonData(mon, MON_DATA_SPEED_EV, &src->speedEV);
+ SetMonData(mon, MON_DATA_SPATK_EV, &src->spAttackEV);
+ SetMonData(mon, MON_DATA_SPDEF_EV, &src->spDefenseEV);
+ value = src->altAbility;
+ SetMonData(mon, MON_DATA_ALT_ABILITY, &value);
+ value = src->hpIV;
+ SetMonData(mon, MON_DATA_HP_IV, &value);
+ value = src->attackIV;
+ SetMonData(mon, MON_DATA_ATK_IV, &value);
+ value = src->defenseIV;
+ SetMonData(mon, MON_DATA_DEF_IV, &value);
+ value = src->speedIV;
+ SetMonData(mon, MON_DATA_SPEED_IV, &value);
+ value = src->spAttackIV;
+ SetMonData(mon, MON_DATA_SPATK_IV, &value);
+ value = src->spDefenseIV;
+ SetMonData(mon, MON_DATA_SPDEF_IV, &value);
+ MonRestorePP(mon);
+ CalculateMonStats(mon);
+}
+
+void sub_8068528(struct Pokemon *mon, const struct UnknownPokemonStruct2 *src, u8 monId)
+{
+ s32 i;
+ u16 evAmount;
+ u8 language;
+ u32 otId = gUnknown_08610970[src->field_0_0].field_30;
+ u32 personality = ((gUnknown_08610970[src->field_0_0].field_30 >> 8) | ((gUnknown_08610970[src->field_0_0].field_30 & 0xFF) << 8))
+ + src->mons[monId].species + src->field_2;
+
+ CreateMon(mon,
+ src->mons[monId].species,
+ BattleFrontierGetOpponentLvl(src->field_0_1 - 1),
+ 0x1F,
+ TRUE,
+ personality,
+ TRUE,
+ otId);
+
+ SetMonData(mon, MON_DATA_HELD_ITEM, &src->mons[monId].item);
+ for (i = 0; i < 4; i++)
+ SetMonMoveSlot(mon, src->mons[monId].moves[i], i);
+
+ evAmount = MAX_TOTAL_EVS / NUM_STATS;
+ for (i = 0; i < NUM_STATS; i++)
+ SetMonData(mon, MON_DATA_HP_EV + i, &evAmount);
+
+ language = src->language;
+ SetMonData(mon, MON_DATA_LANGUAGE, &language);
+ SetMonData(mon, MON_DATA_OT_NAME, sub_81A1650(src->field_0_0, language));
+ CalculateMonStats(mon);
+}
+
+void CreateMonWithEVSpreadPersonalityOTID(struct Pokemon *mon, u16 species, u8 level, u8 nature, u8 fixedIV, u8 evSpread, u32 otId)
+{
+ s32 i;
+ s32 statCount = 0;
+ u8 evsBits;
+ u16 evAmount;
+
+ // i is reused as personality value
+ do
+ {
+ i = Random32();
+ } while (nature != GetNatureFromPersonality(i));
+
+ CreateMon(mon, species, level, fixedIV, TRUE, i, TRUE, otId);
+ evsBits = evSpread;
+ for (i = 0; i < NUM_STATS; i++)
+ {
+ if (evsBits & 1)
+ statCount++;
+ evsBits >>= 1;
+ }
+
+ evAmount = MAX_TOTAL_EVS / statCount;
+ evsBits = 1;
+ for (i = 0; i < NUM_STATS; i++)
+ {
+ if (evSpread & evsBits)
+ SetMonData(mon, MON_DATA_HP_EV + i, &evAmount);
+ evsBits <<= 1;
+ }
+
+ CalculateMonStats(mon);
+}
+
+void sub_80686FC(struct Pokemon *mon, struct UnknownPokemonStruct *dest)
+{
+ s32 i;
+ u16 heldItem;
+
+ dest->species = GetMonData(mon, MON_DATA_SPECIES, NULL);
+ heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, NULL);
+
+ if (heldItem == ITEM_ENIGMA_BERRY)
+ heldItem = 0;
+
+ dest->heldItem = heldItem;
+
+ for (i = 0; i < 4; i++)
+ dest->moves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, NULL);
+
+ dest->level = GetMonData(mon, MON_DATA_LEVEL, NULL);
+ dest->ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES, NULL);
+ dest->otId = GetMonData(mon, MON_DATA_OT_ID, NULL);
+ dest->hpEV = GetMonData(mon, MON_DATA_HP_EV, NULL);
+ dest->attackEV = GetMonData(mon, MON_DATA_ATK_EV, NULL);
+ dest->defenseEV = GetMonData(mon, MON_DATA_DEF_EV, NULL);
+ dest->speedEV = GetMonData(mon, MON_DATA_SPEED_EV, NULL);
+ dest->spAttackEV = GetMonData(mon, MON_DATA_SPATK_EV, NULL);
+ dest->spDefenseEV = GetMonData(mon, MON_DATA_SPDEF_EV, NULL);
+ dest->friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, NULL);
+ dest->hpIV = GetMonData(mon, MON_DATA_HP_IV, NULL);
+ dest->attackIV = GetMonData(mon, MON_DATA_ATK_IV, NULL);
+ dest->defenseIV = GetMonData(mon, MON_DATA_DEF_IV, NULL);
+ dest->speedIV = GetMonData(mon, MON_DATA_SPEED_IV, NULL);
+ dest->spAttackIV = GetMonData(mon, MON_DATA_SPATK_IV, NULL);
+ dest->spDefenseIV = GetMonData(mon, MON_DATA_SPDEF_IV, NULL);
+ dest->altAbility = GetMonData(mon, MON_DATA_ALT_ABILITY, NULL);
+ dest->personality = GetMonData(mon, MON_DATA_PERSONALITY, NULL);
+ GetMonData(mon, MON_DATA_NICKNAME, dest->nickname);
+}
+
+void CreateObedientMon(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 hasFixedPersonality, u32 fixedPersonality, u8 otIdType, u32 fixedOtId)
+{
+ bool32 obedient = TRUE;
+
+ CreateMon(mon, species, level, fixedIV, hasFixedPersonality, fixedPersonality, otIdType, fixedOtId);
+ SetMonData(mon, MON_DATA_OBEDIENCE, &obedient);
+}
+
+bool8 sub_80688F8(u8 caseId, u8 battlerId)
+{
+ switch (caseId)
+ {
+ case 0:
+ default:
+ return FALSE;
+ case 1:
+ if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI))
+ return FALSE;
+ if (!gMain.inBattle)
+ return FALSE;
+ if (gLinkPlayers[GetMultiplayerId()].lp_field_18 == battlerId)
+ return FALSE;
+ break;
+ case 2:
+ break;
+ case 3:
+ if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI))
+ return FALSE;
+ if (!gMain.inBattle)
+ return FALSE;
+ if (battlerId == 1 || battlerId == 4 || battlerId == 5)
+ return TRUE;
+ return FALSE;
+ case 4:
+ break;
+ case 5:
+ if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ {
+ if (!gMain.inBattle)
+ return FALSE;
+ if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
+ {
+ if (gLinkPlayers[GetMultiplayerId()].lp_field_18 == battlerId)
+ return FALSE;
+ }
+ else
+ {
+ if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (!gMain.inBattle)
+ return FALSE;
+ if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
+ return FALSE;
+ }
+ break;
+ }
+
+ return TRUE;
+}
+
+static s32 GetDeoxysStat(struct Pokemon *mon, s32 statId)
+{
+ s32 ivVal, evVal;
+ s32 statValue;
+ u8 nature, statId_;
+
+ if (gBattleTypeFlags & BATTLE_TYPE_20)
+ return 0;
+ if (GetMonData(mon, MON_DATA_SPECIES, NULL) != SPECIES_DEOXYS)
+ return 0;
+
+ ivVal = GetMonData(mon, MON_DATA_HP_IV + statId, NULL);
+ evVal = GetMonData(mon, MON_DATA_HP_EV + statId, NULL);
+ statValue = (u16)(((sDeoxysBaseStats[statId] * 2 + ivVal + evVal / 4) * mon->level) / 100 + 5);
+
+ nature = GetNature(mon);
+ statId_ = statId; // needed to match
+ statValue = ModifyStatByNature(nature, statValue, statId_);
+
+ return statValue;
+}
+
+void SetDeoxysStats(void)
+{
+ s32 i, value;
+
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ struct Pokemon *mon = &gPlayerParty[i];
+
+ if (GetMonData(mon, MON_DATA_SPECIES, NULL) != SPECIES_DEOXYS)
+ continue;
+
+ value = GetMonData(mon, MON_DATA_ATK, NULL);
+ SetMonData(mon, MON_DATA_ATK, &value);
+
+ value = GetMonData(mon, MON_DATA_DEF, NULL);
+ SetMonData(mon, MON_DATA_DEF, &value);
+
+ value = GetMonData(mon, MON_DATA_SPEED, NULL);
+ SetMonData(mon, MON_DATA_SPEED, &value);
+
+ value = GetMonData(mon, MON_DATA_SPATK, NULL);
+ SetMonData(mon, MON_DATA_SPATK, &value);
+
+ value = GetMonData(mon, MON_DATA_SPDEF, NULL);
+ SetMonData(mon, MON_DATA_SPDEF, &value);
+ }
+}
+
+u16 sub_8068B48(void)
+{
+ u8 linkId;
+ u32 arrId;
+
+ if (gBattleTypeFlags & BATTLE_TYPE_x2000000)
+ linkId = gUnknown_0203C7B4 ^ 1;
+ else
+ linkId = GetMultiplayerId() ^ 1;
+
+ arrId = gLinkPlayers[linkId].trainerId & 7;
+ arrId |= gLinkPlayers[linkId].gender << 3;
+ return FacilityClassToPicIndex(gUnknown_08329D54[arrId]);
+}
+
+u16 sub_8068BB0(void)
+{
+ u8 linkId;
+ u32 arrId;
+
+ if (gBattleTypeFlags & BATTLE_TYPE_x2000000)
+ linkId = gUnknown_0203C7B4 ^ 1;
+ else
+ linkId = GetMultiplayerId() ^ 1;
+
+ arrId = gLinkPlayers[linkId].trainerId & 7;
+ arrId |= gLinkPlayers[linkId].gender << 3;
+ return gFacilityClassToTrainerClass[gUnknown_08329D54[arrId]];
+}
+
+void CreateObedientEnemyMon(void)
+{
+ s32 species = gSpecialVar_0x8004;
+ s32 level = gSpecialVar_0x8005;
+ s32 itemId = gSpecialVar_0x8006;
+
+ ZeroEnemyPartyMons();
+ CreateObedientMon(&gEnemyParty[0], species, level, 32, 0, 0, 0, 0);
+ if (itemId)
+ {
+ u8 heldItem[2];
+ heldItem[0] = itemId;
+ heldItem[1] = itemId >> 8;
+ SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, heldItem);
+ }
+}
+
+static u16 CalculateBoxMonChecksum(struct BoxPokemon *boxMon)
+{
+ u16 checksum = 0;
+ union PokemonSubstruct *substruct0 = GetSubstruct(boxMon, boxMon->personality, 0);
+ union PokemonSubstruct *substruct1 = GetSubstruct(boxMon, boxMon->personality, 1);
+ union PokemonSubstruct *substruct2 = GetSubstruct(boxMon, boxMon->personality, 2);
+ union PokemonSubstruct *substruct3 = GetSubstruct(boxMon, boxMon->personality, 3);
+ s32 i;
+
+ for (i = 0; i < 6; i++)
+ checksum += substruct0->raw[i];
+
+ for (i = 0; i < 6; i++)
+ checksum += substruct1->raw[i];
+
+ for (i = 0; i < 6; i++)
+ checksum += substruct2->raw[i];
+
+ for (i = 0; i < 6; i++)
+ checksum += substruct3->raw[i];
+
+ return checksum;
+}
+
+#define CALC_STAT(base, iv, ev, statIndex, field) \
+{ \
+ u8 baseStat = gBaseStats[species].base; \
+ s32 n = (((2 * baseStat + iv + ev / 4) * level) / 100) + 5; \
+ u8 nature = GetNature(mon); \
+ n = ModifyStatByNature(nature, n, statIndex); \
+ SetMonData(mon, field, &n); \
+}
+
+void CalculateMonStats(struct Pokemon *mon)
+{
+ s32 oldMaxHP = GetMonData(mon, MON_DATA_MAX_HP, NULL);
+ s32 currentHP = GetMonData(mon, MON_DATA_HP, NULL);
+ s32 hpIV = GetMonData(mon, MON_DATA_HP_IV, NULL);
+ s32 hpEV = GetMonData(mon, MON_DATA_HP_EV, NULL);
+ s32 attackIV = GetMonData(mon, MON_DATA_ATK_IV, NULL);
+ s32 attackEV = GetMonData(mon, MON_DATA_ATK_EV, NULL);
+ s32 defenseIV = GetMonData(mon, MON_DATA_DEF_IV, NULL);
+ s32 defenseEV = GetMonData(mon, MON_DATA_DEF_EV, NULL);
+ s32 speedIV = GetMonData(mon, MON_DATA_SPEED_IV, NULL);
+ s32 speedEV = GetMonData(mon, MON_DATA_SPEED_EV, NULL);
+ s32 spAttackIV = GetMonData(mon, MON_DATA_SPATK_IV, NULL);
+ s32 spAttackEV = GetMonData(mon, MON_DATA_SPATK_EV, NULL);
+ s32 spDefenseIV = GetMonData(mon, MON_DATA_SPDEF_IV, NULL);
+ s32 spDefenseEV = GetMonData(mon, MON_DATA_SPDEF_EV, NULL);
+ u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
+ s32 level = GetLevelFromMonExp(mon);
+ s32 newMaxHP;
+
+ SetMonData(mon, MON_DATA_LEVEL, &level);
+
+ if (species == SPECIES_SHEDINJA)
+ {
+ newMaxHP = 1;
+ }
+ else
+ {
+ s32 n = 2 * gBaseStats[species].baseHP + hpIV;
+ newMaxHP = (((n + hpEV / 4) * level) / 100) + level + 10;
+ }
+
+ gBattleScripting.field_23 = newMaxHP - oldMaxHP;
+ if (gBattleScripting.field_23 == 0)
+ gBattleScripting.field_23 = 1;
+
+ SetMonData(mon, MON_DATA_MAX_HP, &newMaxHP);
+
+ CALC_STAT(baseAttack, attackIV, attackEV, 1, MON_DATA_ATK)
+ CALC_STAT(baseDefense, defenseIV, defenseEV, 2, MON_DATA_DEF)
+ CALC_STAT(baseSpeed, speedIV, speedEV, 3, MON_DATA_SPEED)
+ CALC_STAT(baseSpAttack, spAttackIV, spAttackEV, 4, MON_DATA_SPATK)
+ CALC_STAT(baseSpDefense, spDefenseIV, spDefenseEV, 5, MON_DATA_SPDEF)
+
+ if (species == SPECIES_SHEDINJA)
+ {
+ if (currentHP != 0 || oldMaxHP == 0)
+ currentHP = 1;
+ else
+ return;
+ }
+ else
+ {
+ if (currentHP == 0 && oldMaxHP == 0)
+ currentHP = newMaxHP;
+ else if (currentHP != 0)
+ currentHP += newMaxHP - oldMaxHP;
+ else
+ return;
+ }
+
+ SetMonData(mon, MON_DATA_HP, &currentHP);
+}
+
+void BoxMonToMon(const struct BoxPokemon *src, struct Pokemon *dest)
+{
+ u32 value = 0;
+ dest->box = *src;
+ SetMonData(dest, MON_DATA_STATUS, &value);
+ SetMonData(dest, MON_DATA_HP, &value);
+ SetMonData(dest, MON_DATA_MAX_HP, &value);
+ value = 255;
+ SetMonData(dest, MON_DATA_MAIL, &value);
+ CalculateMonStats(dest);
+}
+
+u8 GetLevelFromMonExp(struct Pokemon *mon)
+{
+ u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
+ u32 exp = GetMonData(mon, MON_DATA_EXP, NULL);
+ s32 level = 1;
+
+ while (level <= MAX_MON_LEVEL && gExperienceTables[gBaseStats[species].growthRate][level] <= exp)
+ level++;
+
+ return level - 1;
+}
+
+u8 GetLevelFromBoxMonExp(struct BoxPokemon *boxMon)
+{
+ u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL);
+ u32 exp = GetBoxMonData(boxMon, MON_DATA_EXP, NULL);
+ s32 level = 1;
+
+ while (level <= MAX_MON_LEVEL && gExperienceTables[gBaseStats[species].growthRate][level] <= exp)
+ level++;
+
+ return level - 1;
+}
+
+u16 GiveMoveToMon(struct Pokemon *mon, u16 move)
+{
+ return GiveMoveToBoxMon(&mon->box, move);
+}
+
+u16 GiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move)
+{
+ s32 i;
+ for (i = 0; i < 4; i++)
+ {
+ u16 existingMove = GetBoxMonData(boxMon, MON_DATA_MOVE1 + i, NULL);
+ if (!existingMove)
+ {
+ SetBoxMonData(boxMon, MON_DATA_MOVE1 + i, &move);
+ SetBoxMonData(boxMon, MON_DATA_PP1 + i, &gBattleMoves[move].pp);
+ return move;
+ }
+ if (existingMove == move)
+ return -2;
+ }
+ return -1;
+}
+
+u16 GiveMoveToBattleMon(struct BattlePokemon *mon, u16 move)
+{
+ s32 i;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (!mon->moves[i])
+ {
+ mon->moves[i] = move;
+ mon->pp[i] = gBattleMoves[move].pp;
+ return move;
+ }
+ }
+
+ return -1;
+}
+
+void SetMonMoveSlot(struct Pokemon *mon, u16 move, u8 slot)
+{
+ SetMonData(mon, MON_DATA_MOVE1 + slot, &move);
+ SetMonData(mon, MON_DATA_PP1 + slot, &gBattleMoves[move].pp);
+}
+
+void SetBattleMonMoveSlot(struct BattlePokemon *mon, u16 move, u8 slot)
+{
+ mon->moves[slot] = move;
+ mon->pp[slot] = gBattleMoves[move].pp;
+}
+
+void GiveMonInitialMoveset(struct Pokemon *mon)
+{
+ GiveBoxMonInitialMoveset(&mon->box);
+}
+
+void GiveBoxMonInitialMoveset(struct BoxPokemon *boxMon)
+{
+ u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL);
+ s32 level = GetLevelFromBoxMonExp(boxMon);
+ s32 i;
+
+ for (i = 0; gLevelUpLearnsets[species][i] != (u16)-1; i++)
+ {
+ u16 moveLevel;
+ u16 move;
+
+ moveLevel = (gLevelUpLearnsets[species][i] & 0xFE00);
+
+ if (moveLevel > (level << 9))
+ break;
+
+ move = (gLevelUpLearnsets[species][i] & 0x1FF);
+
+ if (GiveMoveToBoxMon(boxMon, move) == (u16)-1)
+ DeleteFirstMoveAndGiveMoveToBoxMon(boxMon, move);
+ }
+}
+
+u16 MonTryLearningNewMove(struct Pokemon *mon, bool8 firstMove)
+{
+ u32 retVal = 0;
+ u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
+ u8 level = GetMonData(mon, MON_DATA_LEVEL, NULL);
+
+ // since you can learn more than one move per level
+ // the game needs to know whether you decided to
+ // learn it or keep the old set to avoid asking
+ // you to learn the same move over and over again
+ if (firstMove)
+ {
+ sLearningMoveTableID = 0;
+
+ while ((gLevelUpLearnsets[species][sLearningMoveTableID] & 0xFE00) != (level << 9))
+ {
+ sLearningMoveTableID++;
+ if (gLevelUpLearnsets[species][sLearningMoveTableID] == 0xFFFF)
+ return 0;
+ }
+ }
+
+ if ((gLevelUpLearnsets[species][sLearningMoveTableID] & 0xFE00) == (level << 9))
+ {
+ gMoveToLearn = (gLevelUpLearnsets[species][sLearningMoveTableID] & 0x1FF);
+ sLearningMoveTableID++;
+ retVal = GiveMoveToMon(mon, gMoveToLearn);
+ }
+
+ return retVal;
+}
+
+void DeleteFirstMoveAndGiveMoveToMon(struct Pokemon *mon, u16 move)
+{
+ s32 i;
+ u16 moves[4];
+ u8 pp[4];
+ u8 ppBonuses;
+
+ for (i = 0; i < 3; i++)
+ {
+ moves[i] = GetMonData(mon, MON_DATA_MOVE2 + i, NULL);
+ pp[i] = GetMonData(mon, MON_DATA_PP2 + i, NULL);
+ }
+
+ ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES, NULL);
+ ppBonuses >>= 2;
+ moves[3] = move;
+ pp[3] = gBattleMoves[move].pp;
+
+ for (i = 0; i < 4; i++)
+ {
+ SetMonData(mon, MON_DATA_MOVE1 + i, &moves[i]);
+ SetMonData(mon, MON_DATA_PP1 + i, &pp[i]);
+ }
+
+ SetMonData(mon, MON_DATA_PP_BONUSES, &ppBonuses);
+}
+
+void DeleteFirstMoveAndGiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move)
+{
+ s32 i;
+ u16 moves[4];
+ u8 pp[4];
+ u8 ppBonuses;
+
+ for (i = 0; i < 3; i++)
+ {
+ moves[i] = GetBoxMonData(boxMon, MON_DATA_MOVE2 + i, NULL);
+ pp[i] = GetBoxMonData(boxMon, MON_DATA_PP2 + i, NULL);
+ }
+
+ ppBonuses = GetBoxMonData(boxMon, MON_DATA_PP_BONUSES, NULL);
+ ppBonuses >>= 2;
+ moves[3] = move;
+ pp[3] = gBattleMoves[move].pp;
+
+ for (i = 0; i < 4; i++)
+ {
+ SetBoxMonData(boxMon, MON_DATA_MOVE1 + i, &moves[i]);
+ SetBoxMonData(boxMon, MON_DATA_PP1 + i, &pp[i]);
+ }
+
+ SetBoxMonData(boxMon, MON_DATA_PP_BONUSES, &ppBonuses);
+}
+
+#define APPLY_STAT_MOD(var, mon, stat, statIndex) \
+{ \
+ (var) = (stat) * (gStatStageRatios)[(mon)->statStages[(statIndex)]][0]; \
+ (var) /= (gStatStageRatios)[(mon)->statStages[(statIndex)]][1]; \
+}
+
+s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *defender, u32 move, u16 sideStatus, u16 powerOverride, u8 typeOverride, u8 battlerIdAtk, u8 battlerIdDef)
+{
+ u32 i;
+ s32 damage = 0;
+ s32 damageHelper;
+ u8 type;
+ u16 attack, defense;
+ u16 spAttack, spDefense;
+ u8 defenderHoldEffect;
+ u8 defenderHoldEffectParam;
+ u8 attackerHoldEffect;
+ u8 attackerHoldEffectParam;
+
+ if (!powerOverride)
+ gBattleMovePower = gBattleMoves[move].power;
+ else
+ gBattleMovePower = powerOverride;
+
+ if (!typeOverride)
+ type = gBattleMoves[move].type;
+ else
+ type = typeOverride & 0x3F;
+
+ attack = attacker->attack;
+ defense = defender->defense;
+ spAttack = attacker->spAttack;
+ spDefense = defender->spDefense;
+
+ if (attacker->item == ITEM_ENIGMA_BERRY)
+ {
+ attackerHoldEffect = gEnigmaBerries[battlerIdAtk].holdEffect;
+ attackerHoldEffectParam = gEnigmaBerries[battlerIdAtk].holdEffectParam;
+ }
+ else
+ {
+ attackerHoldEffect = ItemId_GetHoldEffect(attacker->item);
+ attackerHoldEffectParam = ItemId_GetHoldEffectParam(attacker->item);
+ }
+
+ if (defender->item == ITEM_ENIGMA_BERRY)
+ {
+ defenderHoldEffect = gEnigmaBerries[battlerIdDef].holdEffect;
+ defenderHoldEffectParam = gEnigmaBerries[battlerIdDef].holdEffectParam;
+ }
+ else
+ {
+ defenderHoldEffect = ItemId_GetHoldEffect(defender->item);
+ defenderHoldEffectParam = ItemId_GetHoldEffectParam(defender->item);
+ }
+
+ if (attacker->ability == ABILITY_HUGE_POWER || attacker->ability == ABILITY_PURE_POWER)
+ attack *= 2;
+
+ if (ShouldGetStatBadgeBoost(FLAG_BADGE01_GET, battlerIdAtk))
+ attack = (110 * attack) / 100;
+ if (ShouldGetStatBadgeBoost(FLAG_BADGE05_GET, battlerIdDef))
+ defense = (110 * defense) / 100;
+ if (ShouldGetStatBadgeBoost(FLAG_BADGE07_GET, battlerIdAtk))
+ spAttack = (110 * spAttack) / 100;
+ if (ShouldGetStatBadgeBoost(FLAG_BADGE07_GET, battlerIdDef))
+ spDefense = (110 * spDefense) / 100;
+
+ for (i = 0; i < ARRAY_COUNT(sHoldEffectToType); i++)
+ {
+ if (attackerHoldEffect == sHoldEffectToType[i][0]
+ && type == sHoldEffectToType[i][1])
+ {
+ if (type <= 8)
+ attack = (attack * (attackerHoldEffectParam + 100)) / 100;
+ else
+ spAttack = (spAttack * (attackerHoldEffectParam + 100)) / 100;
+ break;
+ }
+ }
+
+ if (attackerHoldEffect == HOLD_EFFECT_CHOICE_BAND)
+ attack = (150 * attack) / 100;
+ if (attackerHoldEffect == HOLD_EFFECT_SOUL_DEW && !(gBattleTypeFlags & (BATTLE_TYPE_FRONTIER)) && (attacker->species == SPECIES_LATIAS || attacker->species == SPECIES_LATIOS))
+ spAttack = (150 * spAttack) / 100;
+ if (defenderHoldEffect == HOLD_EFFECT_SOUL_DEW && !(gBattleTypeFlags & (BATTLE_TYPE_FRONTIER)) && (defender->species == SPECIES_LATIAS || defender->species == SPECIES_LATIOS))
+ spDefense = (150 * spDefense) / 100;
+ if (attackerHoldEffect == HOLD_EFFECT_DEEP_SEA_TOOTH && attacker->species == SPECIES_CLAMPERL)
+ spAttack *= 2;
+ if (defenderHoldEffect == HOLD_EFFECT_DEEP_SEA_SCALE && defender->species == SPECIES_CLAMPERL)
+ spDefense *= 2;
+ if (attackerHoldEffect == HOLD_EFFECT_LIGHT_BALL && attacker->species == SPECIES_PIKACHU)
+ spAttack *= 2;
+ if (defenderHoldEffect == HOLD_EFFECT_METAL_POWDER && defender->species == SPECIES_DITTO)
+ defense *= 2;
+ if (attackerHoldEffect == HOLD_EFFECT_THICK_CLUB && (attacker->species == SPECIES_CUBONE || attacker->species == SPECIES_MAROWAK))
+ attack *= 2;
+ if (defender->ability == ABILITY_THICK_FAT && (type == TYPE_FIRE || type == TYPE_ICE))
+ spAttack /= 2;
+ if (attacker->ability == ABILITY_HUSTLE)
+ attack = (150 * attack) / 100;
+ if (attacker->ability == ABILITY_PLUS && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_MINUS, 0, 0))
+ spAttack = (150 * spAttack) / 100;
+ if (attacker->ability == ABILITY_MINUS && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_PLUS, 0, 0))
+ spAttack = (150 * spAttack) / 100;
+ if (attacker->ability == ABILITY_GUTS && attacker->status1)
+ attack = (150 * attack) / 100;
+ if (defender->ability == ABILITY_MARVEL_SCALE && defender->status1)
+ defense = (150 * defense) / 100;
+ if (type == TYPE_ELECTRIC && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, 0, 0xFD, 0))
+ gBattleMovePower /= 2;
+ if (type == TYPE_FIRE && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, 0, 0xFE, 0))
+ gBattleMovePower /= 2;
+ if (type == TYPE_GRASS && attacker->ability == ABILITY_OVERGROW && attacker->hp <= (attacker->maxHP / 3))
+ gBattleMovePower = (150 * gBattleMovePower) / 100;
+ if (type == TYPE_FIRE && attacker->ability == ABILITY_BLAZE && attacker->hp <= (attacker->maxHP / 3))
+ gBattleMovePower = (150 * gBattleMovePower) / 100;
+ if (type == TYPE_WATER && attacker->ability == ABILITY_TORRENT && attacker->hp <= (attacker->maxHP / 3))
+ gBattleMovePower = (150 * gBattleMovePower) / 100;
+ if (type == TYPE_BUG && attacker->ability == ABILITY_SWARM && attacker->hp <= (attacker->maxHP / 3))
+ gBattleMovePower = (150 * gBattleMovePower) / 100;
+ if (gBattleMoves[gCurrentMove].effect == EFFECT_EXPLOSION)
+ defense /= 2;
+
+ if (type < TYPE_MYSTERY) // is physical
+ {
+ if (gCritMultiplier == 2)
+ {
+ if (attacker->statStages[STAT_ATK] > 6)
+ APPLY_STAT_MOD(damage, attacker, attack, STAT_ATK)
+ else
+ damage = attack;
+ }
+ else
+ APPLY_STAT_MOD(damage, attacker, attack, STAT_ATK)
+
+ damage = damage * gBattleMovePower;
+ damage *= (2 * attacker->level / 5 + 2);
+
+ if (gCritMultiplier == 2)
+ {
+ if (defender->statStages[STAT_DEF] < 6)
+ APPLY_STAT_MOD(damageHelper, defender, defense, STAT_DEF)
+ else
+ damageHelper = defense;
+ }
+ else
+ APPLY_STAT_MOD(damageHelper, defender, defense, STAT_DEF)
+
+ damage = damage / damageHelper;
+ damage /= 50;
+
+ if ((attacker->status1 & STATUS1_BURN) && attacker->ability != ABILITY_GUTS)
+ damage /= 2;
+
+ if ((sideStatus & SIDE_STATUS_REFLECT) && gCritMultiplier == 1)
+ {
+ if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && CountAliveMonsInBattle(2) == 2)
+ damage = 2 * (damage / 3);
+ else
+ damage /= 2;
+ }
+
+ if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gBattleMoves[move].target == 8 && CountAliveMonsInBattle(2) == 2)
+ damage /= 2;
+
+ // moves always do at least 1 damage.
+ if (damage == 0)
+ damage = 1;
+ }
+
+ if (type == TYPE_MYSTERY)
+ damage = 0; // is ??? type. does 0 damage.
+
+ if (type > TYPE_MYSTERY) // is special?
+ {
+ if (gCritMultiplier == 2)
+ {
+ if (attacker->statStages[STAT_SPATK] > 6)
+ APPLY_STAT_MOD(damage, attacker, spAttack, STAT_SPATK)
+ else
+ damage = spAttack;
+ }
+ else
+ APPLY_STAT_MOD(damage, attacker, spAttack, STAT_SPATK)
+
+ damage = damage * gBattleMovePower;
+ damage *= (2 * attacker->level / 5 + 2);
+
+ if (gCritMultiplier == 2)
+ {
+ if (defender->statStages[STAT_SPDEF] < 6)
+ APPLY_STAT_MOD(damageHelper, defender, spDefense, STAT_SPDEF)
+ else
+ damageHelper = spDefense;
+ }
+ else
+ APPLY_STAT_MOD(damageHelper, defender, spDefense, STAT_SPDEF)
+
+ damage = (damage / damageHelper);
+ damage /= 50;
+
+ if ((sideStatus & SIDE_STATUS_LIGHTSCREEN) && gCritMultiplier == 1)
+ {
+ if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && CountAliveMonsInBattle(2) == 2)
+ damage = 2 * (damage / 3);
+ else
+ damage /= 2;
+ }
+
+ if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gBattleMoves[move].target == 8 && CountAliveMonsInBattle(2) == 2)
+ damage /= 2;
+
+ // are effects of weather negated with cloud nine or air lock
+ if (!AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_CLOUD_NINE, 0, 0)
+ && !AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_AIR_LOCK, 0, 0))
+ {
+ if (gBattleWeather & WEATHER_RAIN_TEMPORARY)
+ {
+ switch (type)
+ {
+ case TYPE_FIRE:
+ damage /= 2;
+ break;
+ case TYPE_WATER:
+ damage = (15 * damage) / 10;
+ break;
+ }
+ }
+
+ // any weather except sun weakens solar beam
+ if ((gBattleWeather & (WEATHER_RAIN_ANY | WEATHER_SANDSTORM_ANY | WEATHER_HAIL)) && gCurrentMove == MOVE_SOLAR_BEAM)
+ damage /= 2;
+
+ // sunny
+ if (gBattleWeather & WEATHER_SUN_ANY)
+ {
+ switch (type)
+ {
+ case TYPE_FIRE:
+ damage = (15 * damage) / 10;
+ break;
+ case TYPE_WATER:
+ damage /= 2;
+ break;
+ }
+ }
+ }
+
+ // flash fire triggered
+ if ((gBattleResources->flags->flags[battlerIdAtk] & UNKNOWN_FLAG_FLASH_FIRE) && type == TYPE_FIRE)
+ damage = (15 * damage) / 10;
+ }
+
+ return damage + 2;
+}
+
+u8 CountAliveMonsInBattle(u8 caseId)
+{
+ s32 i;
+ u8 retVal = 0;
+
+ switch (caseId)
+ {
+ case BATTLE_ALIVE_EXCEPT_ACTIVE:
+ for (i = 0; i < 4; i++)
+ {
+ if (i != gActiveBattler && !(gAbsentBattlerFlags & gBitTable[i]))
+ retVal++;
+ }
+ break;
+ case BATTLE_ALIVE_ATK_SIDE:
+ for (i = 0; i < 4; i++)
+ {
+ if (GetBattlerSide(i) == GetBattlerSide(gBattlerAttacker) && !(gAbsentBattlerFlags & gBitTable[i]))
+ retVal++;
+ }
+ break;
+ case BATTLE_ALIVE_DEF_SIDE:
+ for (i = 0; i < 4; i++)
+ {
+ if (GetBattlerSide(i) == GetBattlerSide(gBattlerTarget) && !(gAbsentBattlerFlags & gBitTable[i]))
+ retVal++;
+ }
+ break;
+ }
+
+ return retVal;
+}
+
+static bool8 ShouldGetStatBadgeBoost(u16 badgeFlag, u8 battlerId)
+{
+ if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_x2000000 | BATTLE_TYPE_FRONTIER))
+ return FALSE;
+ if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
+ return FALSE;
+ if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && gTrainerBattleOpponent_A == SECRET_BASE_OPPONENT)
+ return FALSE;
+ if (FlagGet(badgeFlag))
+ return TRUE;
+ return FALSE;
+}
+
+u8 GetDefaultMoveTarget(u8 battlerId)
+{
+ u8 opposing = BATTLE_OPPOSITE(GetBattlerPosition(battlerId) & BIT_SIDE);
+
+ if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
+ return GetBattlerAtPosition(opposing);
+ if (CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_ACTIVE) > 1)
+ {
+ u8 position;
+
+ if ((Random() & 1) == 0)
+ position = BATTLE_PARTNER(opposing);
+ else
+ position = opposing;
+
+ return GetBattlerAtPosition(position);
+ }
+ else
+ {
+ if ((gAbsentBattlerFlags & gBitTable[opposing]))
+ return GetBattlerAtPosition(BATTLE_PARTNER(opposing));
+ else
+ return GetBattlerAtPosition(opposing);
+ }
+}
+
+u8 GetMonGender(struct Pokemon *mon)
+{
+ return GetBoxMonGender(&mon->box);
+}
+
+u8 GetBoxMonGender(struct BoxPokemon *boxMon)
+{
+ u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL);
+ u32 personality = GetBoxMonData(boxMon, MON_DATA_PERSONALITY, NULL);
+
+ switch (gBaseStats[species].genderRatio)
+ {
+ case MON_MALE:
+ case MON_FEMALE:
+ case MON_GENDERLESS:
+ return gBaseStats[species].genderRatio;
+ }
+
+ if (gBaseStats[species].genderRatio > (personality & 0xFF))
+ return MON_FEMALE;
+ else
+ return MON_MALE;
+}
+
+u8 GetGenderFromSpeciesAndPersonality(u16 species, u32 personality)
+{
+ switch (gBaseStats[species].genderRatio)
+ {
+ case MON_MALE:
+ case MON_FEMALE:
+ case MON_GENDERLESS:
+ return gBaseStats[species].genderRatio;
+ }
+
+ if (gBaseStats[species].genderRatio > (personality & 0xFF))
+ return MON_FEMALE;
+ else
+ return MON_MALE;
+}
+
+void sub_806A068(u16 species, u8 battlerPosition)
+{
+ if (gMonSpritesGfxPtr != NULL)
+ gUnknown_0202499C = gMonSpritesGfxPtr->templates[battlerPosition];
+ else if (gUnknown_020249B4[0])
+ gUnknown_0202499C = gUnknown_020249B4[0]->templates[battlerPosition];
+ else if (gUnknown_020249B4[1])
+ gUnknown_0202499C = gUnknown_020249B4[1]->templates[battlerPosition];
+ else
+ gUnknown_0202499C = gUnknown_08329D98[battlerPosition];
+
+ gUnknown_0202499C.paletteTag = species;
+ if (battlerPosition == 0 || battlerPosition == 2)
+ gUnknown_0202499C.anims = gUnknown_082FF70C;
+ else if (species > 500)
+ gUnknown_0202499C.anims = gMonAnimationsSpriteAnimsPtrTable[species - 500];
+ else
+ gUnknown_0202499C.anims = gMonAnimationsSpriteAnimsPtrTable[species];
+}
+
+void sub_806A12C(u16 trainerSpriteId, u8 battlerPosition)
+{
+ gUnknown_0202499C.paletteTag = trainerSpriteId;
+ if (battlerPosition == B_POSITION_PLAYER_LEFT || battlerPosition == B_POSITION_PLAYER_RIGHT)
+ {
+ gUnknown_0202499C = gUnknown_08329DF8[trainerSpriteId];
+ gUnknown_0202499C.anims = gUnknown_08305D0C[trainerSpriteId];
+ }
+ else
+ {
+ if (gMonSpritesGfxPtr != NULL)
+ gUnknown_0202499C = gMonSpritesGfxPtr->templates[battlerPosition];
+ else
+ gUnknown_0202499C = gUnknown_08329D98[battlerPosition];
+ gUnknown_0202499C.anims = gUnknown_0830536C[trainerSpriteId];
+ }
+}
+
+void sub_806A1C0(u16 arg0, u8 battlerPosition)
+{
+ if (gMonSpritesGfxPtr != NULL)
+ gUnknown_0202499C = gMonSpritesGfxPtr->templates[battlerPosition];
+ else
+ gUnknown_0202499C = gUnknown_08329D98[battlerPosition];
+
+ gUnknown_0202499C.paletteTag = arg0;
+ gUnknown_0202499C.anims = gUnknown_0830536C[arg0];
+}
+
+static void EncryptBoxMon(struct BoxPokemon *boxMon)
+{
+ u32 i;
+ for (i = 0; i < 12; i++)
+ {
+ boxMon->secure.raw[i] ^= boxMon->personality;
+ boxMon->secure.raw[i] ^= boxMon->otId;
+ }
+}
+
+static void DecryptBoxMon(struct BoxPokemon *boxMon)
+{
+ u32 i;
+ for (i = 0; i < 12; i++)
+ {
+ boxMon->secure.raw[i] ^= boxMon->otId;
+ boxMon->secure.raw[i] ^= boxMon->personality;
+ }
+}
+
+#define SUBSTRUCT_CASE(n, v1, v2, v3, v4) \
+case n: \
+ { \
+ union PokemonSubstruct *substructs0 = boxMon->secure.substructs; \
+ union PokemonSubstruct *substructs1 = boxMon->secure.substructs; \
+ union PokemonSubstruct *substructs2 = boxMon->secure.substructs; \
+ union PokemonSubstruct *substructs3 = boxMon->secure.substructs; \
+ union PokemonSubstruct *substructs4 = boxMon->secure.substructs; \
+ union PokemonSubstruct *substructs5 = boxMon->secure.substructs; \
+ union PokemonSubstruct *substructs6 = boxMon->secure.substructs; \
+ union PokemonSubstruct *substructs7 = boxMon->secure.substructs; \
+ union PokemonSubstruct *substructs8 = boxMon->secure.substructs; \
+ union PokemonSubstruct *substructs9 = boxMon->secure.substructs; \
+ union PokemonSubstruct *substructs10 = boxMon->secure.substructs; \
+ union PokemonSubstruct *substructs11 = boxMon->secure.substructs; \
+ union PokemonSubstruct *substructs12 = boxMon->secure.substructs; \
+ union PokemonSubstruct *substructs13 = boxMon->secure.substructs; \
+ union PokemonSubstruct *substructs14 = boxMon->secure.substructs; \
+ union PokemonSubstruct *substructs15 = boxMon->secure.substructs; \
+ union PokemonSubstruct *substructs16 = boxMon->secure.substructs; \
+ union PokemonSubstruct *substructs17 = boxMon->secure.substructs; \
+ union PokemonSubstruct *substructs18 = boxMon->secure.substructs; \
+ union PokemonSubstruct *substructs19 = boxMon->secure.substructs; \
+ union PokemonSubstruct *substructs20 = boxMon->secure.substructs; \
+ union PokemonSubstruct *substructs21 = boxMon->secure.substructs; \
+ union PokemonSubstruct *substructs22 = boxMon->secure.substructs; \
+ union PokemonSubstruct *substructs23 = boxMon->secure.substructs; \
+ \
+ switch (substructType) \
+ { \
+ case 0: \
+ substruct = &substructs ## n [v1]; \
+ break; \
+ case 1: \
+ substruct = &substructs ## n [v2]; \
+ break; \
+ case 2: \
+ substruct = &substructs ## n [v3]; \
+ break; \
+ case 3: \
+ substruct = &substructs ## n [v4]; \
+ break; \
+ } \
+ break; \
+ } \
+
+
+static union PokemonSubstruct *GetSubstruct(struct BoxPokemon *boxMon, u32 personality, u8 substructType)
+{
+ union PokemonSubstruct *substruct = NULL;
+
+ switch (personality % 24)
+ {
+ SUBSTRUCT_CASE( 0,0,1,2,3)
+ SUBSTRUCT_CASE( 1,0,1,3,2)
+ SUBSTRUCT_CASE( 2,0,2,1,3)
+ SUBSTRUCT_CASE( 3,0,3,1,2)
+ SUBSTRUCT_CASE( 4,0,2,3,1)
+ SUBSTRUCT_CASE( 5,0,3,2,1)
+ SUBSTRUCT_CASE( 6,1,0,2,3)
+ SUBSTRUCT_CASE( 7,1,0,3,2)
+ SUBSTRUCT_CASE( 8,2,0,1,3)
+ SUBSTRUCT_CASE( 9,3,0,1,2)
+ SUBSTRUCT_CASE(10,2,0,3,1)
+ SUBSTRUCT_CASE(11,3,0,2,1)
+ SUBSTRUCT_CASE(12,1,2,0,3)
+ SUBSTRUCT_CASE(13,1,3,0,2)
+ SUBSTRUCT_CASE(14,2,1,0,3)
+ SUBSTRUCT_CASE(15,3,1,0,2)
+ SUBSTRUCT_CASE(16,2,3,0,1)
+ SUBSTRUCT_CASE(17,3,2,0,1)
+ SUBSTRUCT_CASE(18,1,2,3,0)
+ SUBSTRUCT_CASE(19,1,3,2,0)
+ SUBSTRUCT_CASE(20,2,1,3,0)
+ SUBSTRUCT_CASE(21,3,1,2,0)
+ SUBSTRUCT_CASE(22,2,3,1,0)
+ SUBSTRUCT_CASE(23,3,2,1,0)
+ }
+
+ return substruct;
+}
+
+u32 GetMonData(struct Pokemon *mon, s32 field, u8* data)
+{
+ u32 ret;
+
+ switch (field)
+ {
+ case MON_DATA_STATUS:
+ ret = mon->status;
+ break;
+ case MON_DATA_LEVEL:
+ ret = mon->level;
+ break;
+ case MON_DATA_HP:
+ ret = mon->hp;
+ break;
+ case MON_DATA_MAX_HP:
+ ret = mon->maxHP;
+ break;
+ case MON_DATA_ATK:
+ ret = (u16)GetDeoxysStat(mon, STAT_ATK);
+ if (!ret)
+ ret = mon->attack;
+ break;
+ case MON_DATA_DEF:
+ ret = (u16)GetDeoxysStat(mon, STAT_DEF);
+ if (!ret)
+ ret = mon->defense;
+ break;
+ case MON_DATA_SPEED:
+ ret = (u16)GetDeoxysStat(mon, STAT_SPEED);
+ if (!ret)
+ ret = mon->speed;
+ break;
+ case MON_DATA_SPATK:
+ ret = (u16)GetDeoxysStat(mon, STAT_SPATK);
+ if (!ret)
+ ret = mon->spAttack;
+ break;
+ case MON_DATA_SPDEF:
+ ret = (u16)GetDeoxysStat(mon, STAT_SPDEF);
+ if (!ret)
+ ret = mon->spDefense;
+ break;
+ case MON_DATA_ATK2:
+ ret = mon->attack;
+ break;
+ case MON_DATA_DEF2:
+ ret = mon->defense;
+ break;
+ case MON_DATA_SPEED2:
+ ret = mon->speed;
+ break;
+ case MON_DATA_SPATK2:
+ ret = mon->spAttack;
+ break;
+ case MON_DATA_SPDEF2:
+ ret = mon->spDefense;
+ break;
+ case MON_DATA_MAIL:
+ ret = mon->mail;
+ break;
+ default:
+ ret = GetBoxMonData(&mon->box, field, data);
+ break;
+ }
+ return ret;
+}
+
+u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data)
+{
+ s32 i;
+ u32 retVal = 0;
+ struct PokemonSubstruct0 *substruct0 = NULL;
+ struct PokemonSubstruct1 *substruct1 = NULL;
+ struct PokemonSubstruct2 *substruct2 = NULL;
+ struct PokemonSubstruct3 *substruct3 = NULL;
+
+ if (field > MON_DATA_10)
+ {
+ substruct0 = &(GetSubstruct(boxMon, boxMon->personality, 0)->type0);
+ substruct1 = &(GetSubstruct(boxMon, boxMon->personality, 1)->type1);
+ substruct2 = &(GetSubstruct(boxMon, boxMon->personality, 2)->type2);
+ substruct3 = &(GetSubstruct(boxMon, boxMon->personality, 3)->type3);
+
+ DecryptBoxMon(boxMon);
+
+ if (CalculateBoxMonChecksum(boxMon) != boxMon->checksum)
+ {
+ boxMon->isBadEgg = 1;
+ boxMon->isEgg = 1;
+ substruct3->isEgg = 1;
+ }
+ }
+
+ switch (field)
+ {
+ case MON_DATA_PERSONALITY:
+ retVal = boxMon->personality;
+ break;
+ case MON_DATA_OT_ID:
+ retVal = boxMon->otId;
+ break;
+ case MON_DATA_NICKNAME:
+ {
+ if (boxMon->isBadEgg)
+ {
+ for (retVal = 0;
+ retVal < POKEMON_NAME_LENGTH && gText_BadEgg[retVal] != EOS;
+ data[retVal] = gText_BadEgg[retVal], retVal++) {}
+
+ data[retVal] = EOS;
+ }
+ else if (boxMon->isEgg)
+ {
+ StringCopy(data, gText_EggNickname);
+ retVal = StringLength(data);
+ }
+ else if (boxMon->language == LANGUAGE_JAPANESE)
+ {
+ data[0] = EXT_CTRL_CODE_BEGIN;
+ data[1] = EXT_CTRL_CODE_JPN;
+
+ for (retVal = 2, i = 0;
+ i < 5 && boxMon->nickname[i] != EOS;
+ data[retVal] = boxMon->nickname[i], retVal++, i++) {}
+
+ data[retVal++] = EXT_CTRL_CODE_BEGIN;
+ data[retVal++] = EXT_CTRL_CODE_ENG;
+ data[retVal] = EOS;
+ }
+ else
+ {
+ for (retVal = 0;
+ retVal < POKEMON_NAME_LENGTH;
+ data[retVal] = boxMon->nickname[retVal], retVal++){}
+
+ data[retVal] = EOS;
+ }
+ break;
+ }
+ case MON_DATA_LANGUAGE:
+ retVal = boxMon->language;
+ break;
+ case MON_DATA_SANITY_BIT1:
+ retVal = boxMon->isBadEgg;
+ break;
+ case MON_DATA_SANITY_BIT2:
+ retVal = boxMon->hasSpecies;
+ break;
+ case MON_DATA_SANITY_BIT3:
+ retVal = boxMon->isEgg;
+ break;
+ case MON_DATA_OT_NAME:
+ {
+ retVal = 0;
+
+ while (retVal < OT_NAME_LENGTH)
+ {
+ data[retVal] = boxMon->otName[retVal];
+ retVal++;
+ }
+
+ data[retVal] = EOS;
+ break;
+ }
+ case MON_DATA_MARKINGS:
+ retVal = boxMon->markings;
+ break;
+ case MON_DATA_CHECKSUM:
+ retVal = boxMon->checksum;
+ break;
+ case MON_DATA_10:
+ retVal = boxMon->unknown;
+ break;
+ case MON_DATA_SPECIES:
+ retVal = boxMon->isBadEgg ? SPECIES_EGG : substruct0->species;
+ break;
+ case MON_DATA_HELD_ITEM:
+ retVal = substruct0->heldItem;
+ break;
+ case MON_DATA_EXP:
+ retVal = substruct0->experience;
+ break;
+ case MON_DATA_PP_BONUSES:
+ retVal = substruct0->ppBonuses;
+ break;
+ case MON_DATA_FRIENDSHIP:
+ retVal = substruct0->friendship;
+ break;
+ case MON_DATA_MOVE1:
+ case MON_DATA_MOVE2:
+ case MON_DATA_MOVE3:
+ case MON_DATA_MOVE4:
+ retVal = substruct1->moves[field - MON_DATA_MOVE1];
+ break;
+ case MON_DATA_PP1:
+ case MON_DATA_PP2:
+ case MON_DATA_PP3:
+ case MON_DATA_PP4:
+ retVal = substruct1->pp[field - MON_DATA_PP1];
+ break;
+ case MON_DATA_HP_EV:
+ retVal = substruct2->hpEV;
+ break;
+ case MON_DATA_ATK_EV:
+ retVal = substruct2->attackEV;
+ break;
+ case MON_DATA_DEF_EV:
+ retVal = substruct2->defenseEV;
+ break;
+ case MON_DATA_SPEED_EV:
+ retVal = substruct2->speedEV;
+ break;
+ case MON_DATA_SPATK_EV:
+ retVal = substruct2->spAttackEV;
+ break;
+ case MON_DATA_SPDEF_EV:
+ retVal = substruct2->spDefenseEV;
+ break;
+ case MON_DATA_COOL:
+ retVal = substruct2->cool;
+ break;
+ case MON_DATA_BEAUTY:
+ retVal = substruct2->beauty;
+ break;
+ case MON_DATA_CUTE:
+ retVal = substruct2->cute;
+ break;
+ case MON_DATA_SMART:
+ retVal = substruct2->smart;
+ break;
+ case MON_DATA_TOUGH:
+ retVal = substruct2->tough;
+ break;
+ case MON_DATA_SHEEN:
+ retVal = substruct2->sheen;
+ break;
+ case MON_DATA_POKERUS:
+ retVal = substruct3->pokerus;
+ break;
+ case MON_DATA_MET_LOCATION:
+ retVal = substruct3->metLocation;
+ break;
+ case MON_DATA_MET_LEVEL:
+ retVal = substruct3->metLevel;
+ break;
+ case MON_DATA_MET_GAME:
+ retVal = substruct3->metGame;
+ break;
+ case MON_DATA_POKEBALL:
+ retVal = substruct3->pokeball;
+ break;
+ case MON_DATA_OT_GENDER:
+ retVal = substruct3->otGender;
+ break;
+ case MON_DATA_HP_IV:
+ retVal = substruct3->hpIV;
+ break;
+ case MON_DATA_ATK_IV:
+ retVal = substruct3->attackIV;
+ break;
+ case MON_DATA_DEF_IV:
+ retVal = substruct3->defenseIV;
+ break;
+ case MON_DATA_SPEED_IV:
+ retVal = substruct3->speedIV;
+ break;
+ case MON_DATA_SPATK_IV:
+ retVal = substruct3->spAttackIV;
+ break;
+ case MON_DATA_SPDEF_IV:
+ retVal = substruct3->spDefenseIV;
+ break;
+ case MON_DATA_IS_EGG:
+ retVal = substruct3->isEgg;
+ break;
+ case MON_DATA_ALT_ABILITY:
+ retVal = substruct3->altAbility;
+ break;
+ case MON_DATA_COOL_RIBBON:
+ retVal = substruct3->coolRibbon;
+ break;
+ case MON_DATA_BEAUTY_RIBBON:
+ retVal = substruct3->beautyRibbon;
+ break;
+ case MON_DATA_CUTE_RIBBON:
+ retVal = substruct3->cuteRibbon;
+ break;
+ case MON_DATA_SMART_RIBBON:
+ retVal = substruct3->smartRibbon;
+ break;
+ case MON_DATA_TOUGH_RIBBON:
+ retVal = substruct3->toughRibbon;
+ break;
+ case MON_DATA_CHAMPION_RIBBON:
+ retVal = substruct3->championRibbon;
+ break;
+ case MON_DATA_WINNING_RIBBON:
+ retVal = substruct3->winningRibbon;
+ break;
+ case MON_DATA_VICTORY_RIBBON:
+ retVal = substruct3->victoryRibbon;
+ break;
+ case MON_DATA_ARTIST_RIBBON:
+ retVal = substruct3->artistRibbon;
+ break;
+ case MON_DATA_EFFORT_RIBBON:
+ retVal = substruct3->effortRibbon;
+ break;
+ case MON_DATA_GIFT_RIBBON_1:
+ retVal = substruct3->giftRibbon1;
+ break;
+ case MON_DATA_GIFT_RIBBON_2:
+ retVal = substruct3->giftRibbon2;
+ break;
+ case MON_DATA_GIFT_RIBBON_3:
+ retVal = substruct3->giftRibbon3;
+ break;
+ case MON_DATA_GIFT_RIBBON_4:
+ retVal = substruct3->giftRibbon4;
+ break;
+ case MON_DATA_GIFT_RIBBON_5:
+ retVal = substruct3->giftRibbon5;
+ break;
+ case MON_DATA_GIFT_RIBBON_6:
+ retVal = substruct3->giftRibbon6;
+ break;
+ case MON_DATA_GIFT_RIBBON_7:
+ retVal = substruct3->giftRibbon7;
+ break;
+ case MON_DATA_FATEFUL_ENCOUNTER:
+ retVal = substruct3->fatefulEncounter;
+ break;
+ case MON_DATA_OBEDIENCE:
+ retVal = substruct3->obedient;
+ break;
+ case MON_DATA_SPECIES2:
+ retVal = substruct0->species;
+ if (substruct0->species && (substruct3->isEgg || boxMon->isBadEgg))
+ retVal = SPECIES_EGG;
+ break;
+ case MON_DATA_IVS:
+ retVal = substruct3->hpIV | (substruct3->attackIV << 5) | (substruct3->defenseIV << 10) | (substruct3->speedIV << 15) | (substruct3->spAttackIV << 20) | (substruct3->spDefenseIV << 25);
+ break;
+ case MON_DATA_KNOWN_MOVES:
+ if (substruct0->species && !substruct3->isEgg)
+ {
+ u16 *moves = (u16 *)data;
+ s32 i = 0;
+
+ while (moves[i] != 355)
+ {
+ u16 move = moves[i];
+ if (substruct1->moves[0] == move
+ || substruct1->moves[1] == move
+ || substruct1->moves[2] == move
+ || substruct1->moves[3] == move)
+ retVal |= gBitTable[i];
+ i++;
+ }
+ }
+ break;
+ case MON_DATA_RIBBON_COUNT:
+ retVal = 0;
+ if (substruct0->species && !substruct3->isEgg)
+ {
+ retVal += substruct3->coolRibbon;
+ retVal += substruct3->beautyRibbon;
+ retVal += substruct3->cuteRibbon;
+ retVal += substruct3->smartRibbon;
+ retVal += substruct3->toughRibbon;
+ retVal += substruct3->championRibbon;
+ retVal += substruct3->winningRibbon;
+ retVal += substruct3->victoryRibbon;
+ retVal += substruct3->artistRibbon;
+ retVal += substruct3->effortRibbon;
+ retVal += substruct3->giftRibbon1;
+ retVal += substruct3->giftRibbon2;
+ retVal += substruct3->giftRibbon3;
+ retVal += substruct3->giftRibbon4;
+ retVal += substruct3->giftRibbon5;
+ retVal += substruct3->giftRibbon6;
+ retVal += substruct3->giftRibbon7;
+ }
+ break;
+ case MON_DATA_RIBBONS:
+ retVal = 0;
+ if (substruct0->species && !substruct3->isEgg)
+ {
+ retVal = substruct3->championRibbon
+ | (substruct3->coolRibbon << 1)
+ | (substruct3->beautyRibbon << 4)
+ | (substruct3->cuteRibbon << 7)
+ | (substruct3->smartRibbon << 10)
+ | (substruct3->toughRibbon << 13)
+ | (substruct3->winningRibbon << 16)
+ | (substruct3->victoryRibbon << 17)
+ | (substruct3->artistRibbon << 18)
+ | (substruct3->effortRibbon << 19)
+ | (substruct3->giftRibbon1 << 20)
+ | (substruct3->giftRibbon2 << 21)
+ | (substruct3->giftRibbon3 << 22)
+ | (substruct3->giftRibbon4 << 23)
+ | (substruct3->giftRibbon5 << 24)
+ | (substruct3->giftRibbon6 << 25)
+ | (substruct3->giftRibbon7 << 26);
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (field > MON_DATA_10)
+ EncryptBoxMon(boxMon);
+
+ return retVal;
+}
+
+#define SET8(lhs) (lhs) = *data
+#define SET16(lhs) (lhs) = data[0] + (data[1] << 8)
+#define SET32(lhs) (lhs) = data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24)
+
+void SetMonData(struct Pokemon *mon, s32 field, const void *dataArg)
+{
+ const u8* data = dataArg;
+ switch (field)
+ {
+ case MON_DATA_STATUS:
+ SET32(mon->status);
+ break;
+ case MON_DATA_LEVEL:
+ SET8(mon->level);
+ break;
+ case MON_DATA_HP:
+ SET16(mon->hp);
+ break;
+ case MON_DATA_MAX_HP:
+ SET16(mon->maxHP);
+ break;
+ case MON_DATA_ATK:
+ SET16(mon->attack);
+ break;
+ case MON_DATA_DEF:
+ SET16(mon->defense);
+ break;
+ case MON_DATA_SPEED:
+ SET16(mon->speed);
+ break;
+ case MON_DATA_SPATK:
+ SET16(mon->spAttack);
+ break;
+ case MON_DATA_SPDEF:
+ SET16(mon->spDefense);
+ break;
+ case MON_DATA_MAIL:
+ SET8(mon->mail);
+ break;
+ case MON_DATA_SPECIES2:
+ break;
+ default:
+ SetBoxMonData(&mon->box, field, data);
+ break;
+ }
+}
+
+void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg)
+{
+ const u8* data = dataArg;
+
+ struct PokemonSubstruct0 *substruct0 = NULL;
+ struct PokemonSubstruct1 *substruct1 = NULL;
+ struct PokemonSubstruct2 *substruct2 = NULL;
+ struct PokemonSubstruct3 *substruct3 = NULL;
+
+ if (field > MON_DATA_10)
+ {
+ substruct0 = &(GetSubstruct(boxMon, boxMon->personality, 0)->type0);
+ substruct1 = &(GetSubstruct(boxMon, boxMon->personality, 1)->type1);
+ substruct2 = &(GetSubstruct(boxMon, boxMon->personality, 2)->type2);
+ substruct3 = &(GetSubstruct(boxMon, boxMon->personality, 3)->type3);
+
+ DecryptBoxMon(boxMon);
+
+ if (CalculateBoxMonChecksum(boxMon) != boxMon->checksum)
+ {
+ boxMon->isBadEgg = 1;
+ boxMon->isEgg = 1;
+ substruct3->isEgg = 1;
+ EncryptBoxMon(boxMon);
+ return;
+ }
+ }
+
+ switch (field)
+ {
+ case MON_DATA_PERSONALITY:
+ SET32(boxMon->personality);
+ break;
+ case MON_DATA_OT_ID:
+ SET32(boxMon->otId);
+ break;
+ case MON_DATA_NICKNAME:
+ {
+ s32 i;
+ for (i = 0; i < POKEMON_NAME_LENGTH; i++)
+ boxMon->nickname[i] = data[i];
+ break;
+ }
+ case MON_DATA_LANGUAGE:
+ SET8(boxMon->language);
+ break;
+ case MON_DATA_SANITY_BIT1:
+ SET8(boxMon->isBadEgg);
+ break;
+ case MON_DATA_SANITY_BIT2:
+ SET8(boxMon->hasSpecies);
+ break;
+ case MON_DATA_SANITY_BIT3:
+ SET8(boxMon->isEgg);
+ break;
+ case MON_DATA_OT_NAME:
+ {
+ s32 i;
+ for (i = 0; i < OT_NAME_LENGTH; i++)
+ boxMon->otName[i] = data[i];
+ break;
+ }
+ case MON_DATA_MARKINGS:
+ SET8(boxMon->markings);
+ break;
+ case MON_DATA_CHECKSUM:
+ SET16(boxMon->checksum);
+ break;
+ case MON_DATA_10:
+ SET16(boxMon->unknown);
+ break;
+ case MON_DATA_SPECIES:
+ {
+ SET16(substruct0->species);
+ if (substruct0->species)
+ boxMon->hasSpecies = 1;
+ else
+ boxMon->hasSpecies = 0;
+ break;
+ }
+ case MON_DATA_HELD_ITEM:
+ SET16(substruct0->heldItem);
+ break;
+ case MON_DATA_EXP:
+ SET32(substruct0->experience);
+ break;
+ case MON_DATA_PP_BONUSES:
+ SET8(substruct0->ppBonuses);
+ break;
+ case MON_DATA_FRIENDSHIP:
+ SET8(substruct0->friendship);
+ break;
+ case MON_DATA_MOVE1:
+ case MON_DATA_MOVE2:
+ case MON_DATA_MOVE3:
+ case MON_DATA_MOVE4:
+ SET16(substruct1->moves[field - MON_DATA_MOVE1]);
+ break;
+ case MON_DATA_PP1:
+ case MON_DATA_PP2:
+ case MON_DATA_PP3:
+ case MON_DATA_PP4:
+ SET8(substruct1->pp[field - MON_DATA_PP1]);
+ break;
+ case MON_DATA_HP_EV:
+ SET8(substruct2->hpEV);
+ break;
+ case MON_DATA_ATK_EV:
+ SET8(substruct2->attackEV);
+ break;
+ case MON_DATA_DEF_EV:
+ SET8(substruct2->defenseEV);
+ break;
+ case MON_DATA_SPEED_EV:
+ SET8(substruct2->speedEV);
+ break;
+ case MON_DATA_SPATK_EV:
+ SET8(substruct2->spAttackEV);
+ break;
+ case MON_DATA_SPDEF_EV:
+ SET8(substruct2->spDefenseEV);
+ break;
+ case MON_DATA_COOL:
+ SET8(substruct2->cool);
+ break;
+ case MON_DATA_BEAUTY:
+ SET8(substruct2->beauty);
+ break;
+ case MON_DATA_CUTE:
+ SET8(substruct2->cute);
+ break;
+ case MON_DATA_SMART:
+ SET8(substruct2->smart);
+ break;
+ case MON_DATA_TOUGH:
+ SET8(substruct2->tough);
+ break;
+ case MON_DATA_SHEEN:
+ SET8(substruct2->sheen);
+ break;
+ case MON_DATA_POKERUS:
+ SET8(substruct3->pokerus);
+ break;
+ case MON_DATA_MET_LOCATION:
+ SET8(substruct3->metLocation);
+ break;
+ case MON_DATA_MET_LEVEL:
+ {
+ u8 metLevel = *data;
+ substruct3->metLevel = metLevel;
+ break;
+ }
+ case MON_DATA_MET_GAME:
+ SET8(substruct3->metGame);
+ break;
+ case MON_DATA_POKEBALL:
+ {
+ u8 pokeball = *data;
+ substruct3->pokeball = pokeball;
+ break;
+ }
+ case MON_DATA_OT_GENDER:
+ SET8(substruct3->otGender);
+ break;
+ case MON_DATA_HP_IV:
+ SET8(substruct3->hpIV);
+ break;
+ case MON_DATA_ATK_IV:
+ SET8(substruct3->attackIV);
+ break;
+ case MON_DATA_DEF_IV:
+ SET8(substruct3->defenseIV);
+ break;
+ case MON_DATA_SPEED_IV:
+ SET8(substruct3->speedIV);
+ break;
+ case MON_DATA_SPATK_IV:
+ SET8(substruct3->spAttackIV);
+ break;
+ case MON_DATA_SPDEF_IV:
+ SET8(substruct3->spDefenseIV);
+ break;
+ case MON_DATA_IS_EGG:
+ SET8(substruct3->isEgg);
+ if (substruct3->isEgg)
+ boxMon->isEgg = 1;
+ else
+ boxMon->isEgg = 0;
+ break;
+ case MON_DATA_ALT_ABILITY:
+ SET8(substruct3->altAbility);
+ break;
+ case MON_DATA_COOL_RIBBON:
+ SET8(substruct3->coolRibbon);
+ break;
+ case MON_DATA_BEAUTY_RIBBON:
+ SET8(substruct3->beautyRibbon);
+ break;
+ case MON_DATA_CUTE_RIBBON:
+ SET8(substruct3->cuteRibbon);
+ break;
+ case MON_DATA_SMART_RIBBON:
+ SET8(substruct3->smartRibbon);
+ break;
+ case MON_DATA_TOUGH_RIBBON:
+ SET8(substruct3->toughRibbon);
+ break;
+ case MON_DATA_CHAMPION_RIBBON:
+ SET8(substruct3->championRibbon);
+ break;
+ case MON_DATA_WINNING_RIBBON:
+ SET8(substruct3->winningRibbon);
+ break;
+ case MON_DATA_VICTORY_RIBBON:
+ SET8(substruct3->victoryRibbon);
+ break;
+ case MON_DATA_ARTIST_RIBBON:
+ SET8(substruct3->artistRibbon);
+ break;
+ case MON_DATA_EFFORT_RIBBON:
+ SET8(substruct3->effortRibbon);
+ break;
+ case MON_DATA_GIFT_RIBBON_1:
+ SET8(substruct3->giftRibbon1);
+ break;
+ case MON_DATA_GIFT_RIBBON_2:
+ SET8(substruct3->giftRibbon2);
+ break;
+ case MON_DATA_GIFT_RIBBON_3:
+ SET8(substruct3->giftRibbon3);
+ break;
+ case MON_DATA_GIFT_RIBBON_4:
+ SET8(substruct3->giftRibbon4);
+ break;
+ case MON_DATA_GIFT_RIBBON_5:
+ SET8(substruct3->giftRibbon5);
+ break;
+ case MON_DATA_GIFT_RIBBON_6:
+ SET8(substruct3->giftRibbon6);
+ break;
+ case MON_DATA_GIFT_RIBBON_7:
+ SET8(substruct3->giftRibbon7);
+ break;
+ case MON_DATA_FATEFUL_ENCOUNTER:
+ SET8(substruct3->fatefulEncounter);
+ break;
+ case MON_DATA_OBEDIENCE:
+ SET8(substruct3->obedient);
+ break;
+ case MON_DATA_IVS:
+ {
+ u32 ivs = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
+ substruct3->hpIV = ivs & 0x1F;
+ substruct3->attackIV = (ivs >> 5) & 0x1F;
+ substruct3->defenseIV = (ivs >> 10) & 0x1F;
+ substruct3->speedIV = (ivs >> 15) & 0x1F;
+ substruct3->spAttackIV = (ivs >> 20) & 0x1F;
+ substruct3->spDefenseIV = (ivs >> 25) & 0x1F;
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (field > MON_DATA_10)
+ {
+ boxMon->checksum = CalculateBoxMonChecksum(boxMon);
+ EncryptBoxMon(boxMon);
+ }
+}
+
+void CopyMon(void *dest, void *src, size_t size)
+{
+ memcpy(dest, src, size);
+}
+
+u8 GiveMonToPlayer(struct Pokemon *mon)
+{
+ s32 i;
+
+ SetMonData(mon, MON_DATA_OT_NAME, gSaveBlock2Ptr->playerName);
+ SetMonData(mon, MON_DATA_OT_GENDER, &gSaveBlock2Ptr->playerGender);
+ SetMonData(mon, MON_DATA_OT_ID, gSaveBlock2Ptr->playerTrainerId);
+
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL) == SPECIES_NONE)
+ break;
+ }
+
+ if (i >= PARTY_SIZE)
+ return SendMonToPC(mon);
+
+ CopyMon(&gPlayerParty[i], mon, sizeof(*mon));
+ gPlayerPartyCount = i + 1;
+ return MON_GIVEN_TO_PARTY;
+}
+
+u8 SendMonToPC(struct Pokemon* mon)
+{
+ s32 boxNo, boxPos;
+
+ set_unknown_box_id(VarGet(VAR_STORAGE_UNKNOWN));
+
+ boxNo = StorageGetCurrentBox();
+
+ do
+ {
+ for (boxPos = 0; boxPos < 30; boxPos++)
+ {
+ struct BoxPokemon* checkingMon = GetBoxedMonPtr(boxNo, boxPos);
+ if (GetBoxMonData(checkingMon, MON_DATA_SPECIES, NULL) == SPECIES_NONE)
+ {
+ MonRestorePP(mon);
+ CopyMon(checkingMon, &mon->box, sizeof(mon->box));
+ gSpecialVar_MonBoxId = boxNo;
+ gSpecialVar_MonBoxPos = boxPos;
+ if (get_unknown_box_id() != boxNo)
+ FlagClear(FLAG_SYS_STORAGE_UNKNOWN_FLAG);
+ VarSet(VAR_STORAGE_UNKNOWN, boxNo);
+ return MON_GIVEN_TO_PC;
+ }
+ }
+
+ boxNo++;
+ if (boxNo == 14)
+ boxNo = 0;
+ } while (boxNo != StorageGetCurrentBox());
+
+ return MON_CANT_GIVE;
+}
+
+u8 CalculatePlayerPartyCount(void)
+{
+ gPlayerPartyCount = 0;
+
+ while (gPlayerPartyCount < 6
+ && GetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_SPECIES, NULL) != SPECIES_NONE)
+ {
+ gPlayerPartyCount++;
+ }
+
+ return gPlayerPartyCount;
+}
+
+u8 CalculateEnemyPartyCount(void)
+{
+ gEnemyPartyCount = 0;
+
+ while (gEnemyPartyCount < 6
+ && GetMonData(&gEnemyParty[gEnemyPartyCount], MON_DATA_SPECIES, NULL) != SPECIES_NONE)
+ {
+ gEnemyPartyCount++;
+ }
+
+ return gEnemyPartyCount;
+}
+
+u8 GetMonsStateToDoubles(void)
+{
+ s32 aliveCount = 0;
+ s32 i;
+ CalculatePlayerPartyCount();
+
+ if (gPlayerPartyCount == 1)
+ return gPlayerPartyCount; // PLAYER_HAS_ONE_MON
+
+ for (i = 0; i < gPlayerPartyCount; i++)
+ {
+ if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) != SPECIES_EGG
+ && GetMonData(&gPlayerParty[i], MON_DATA_HP, NULL) != 0
+ && GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) != SPECIES_NONE)
+ aliveCount++;
+ }
+
+ return (aliveCount > 1) ? PLAYER_HAS_TWO_USABLE_MONS : PLAYER_HAS_ONE_USABLE_MON;
+}
+
+u8 GetMonsStateToDoubles_2(void)
+{
+ s32 aliveCount = 0;
+ s32 i;
+
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ u32 species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL);
+ if (species != SPECIES_EGG && species != SPECIES_NONE
+ && GetMonData(&gPlayerParty[i], MON_DATA_HP, NULL) != 0)
+ aliveCount++;
+ }
+
+ if (aliveCount == 1)
+ return PLAYER_HAS_ONE_MON; // may have more than one, but only one is alive
+
+ return (aliveCount > 1) ? PLAYER_HAS_TWO_USABLE_MONS : PLAYER_HAS_ONE_USABLE_MON;
+}
+
+u8 GetAbilityBySpecies(u16 species, bool8 altAbility)
+{
+ if (altAbility)
+ gLastUsedAbility = gBaseStats[species].ability2;
+ else
+ gLastUsedAbility = gBaseStats[species].ability1;
+
+ return gLastUsedAbility;
+}
+
+u8 GetMonAbility(struct Pokemon *mon)
+{
+ u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
+ u8 altAbility = GetMonData(mon, MON_DATA_ALT_ABILITY, NULL);
+ return GetAbilityBySpecies(species, altAbility);
+}
+
+void CreateSecretBaseEnemyParty(struct SecretBaseRecord *secretBaseRecord)
+{
+ s32 i, j;
+
+ ZeroEnemyPartyMons();
+ *gBattleResources->secretBase = *secretBaseRecord;
+
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ if (gBattleResources->secretBase->party.species[i])
+ {
+ CreateMon(&gEnemyParty[i],
+ gBattleResources->secretBase->party.species[i],
+ gBattleResources->secretBase->party.levels[i],
+ 15,
+ 1,
+ gBattleResources->secretBase->party.personality[i],
+ 2,
+ 0);
+
+ SetMonData(&gEnemyParty[i], MON_DATA_HELD_ITEM, &gBattleResources->secretBase->party.heldItems[i]);
+
+ for (j = 0; j < 6; j++)
+ SetMonData(&gEnemyParty[i], MON_DATA_HP_EV + j, &gBattleResources->secretBase->party.EVs[i]);
+
+ for (j = 0; j < 4; j++)
+ {
+ SetMonData(&gEnemyParty[i], MON_DATA_MOVE1 + j, &gBattleResources->secretBase->party.moves[i * 4 + j]);
+ SetMonData(&gEnemyParty[i], MON_DATA_PP1 + j, &gBattleMoves[gBattleResources->secretBase->party.moves[i * 4 + j]].pp);
+ }
+ }
+ }
+}
+
+u8 GetSecretBaseTrainerPicIndex(void)
+{
+ u8 facilityClass = sSecretBaseFacilityClasses[gBattleResources->secretBase->gender][gBattleResources->secretBase->trainerId[0] % 5];
+ return gFacilityClassToPicIndex[facilityClass];
+}
+
+u8 GetSecretBaseTrainerClass(void)
+{
+ u8 facilityClass = sSecretBaseFacilityClasses[gBattleResources->secretBase->gender][gBattleResources->secretBase->trainerId[0] % 5];
+ return gFacilityClassToTrainerClass[facilityClass];
+}
+
+bool8 IsPlayerPartyAndPokemonStorageFull(void)
+{
+ s32 i;
+
+ for (i = 0; i < PARTY_SIZE; i++)
+ if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL) == SPECIES_NONE)
+ return FALSE;
+
+ return IsPokemonStorageFull();
+}
+
+bool8 IsPokemonStorageFull(void)
+{
+ s32 i, j;
+
+ for (i = 0; i < 14; i++)
+ for (j = 0; j < 30; j++)
+ if (GetBoxMonDataFromAnyBox(i, j, MON_DATA_SPECIES) == SPECIES_NONE)
+ return FALSE;
+
+ return TRUE;
+}
+
+void GetSpeciesName(u8 *name, u16 species)
+{
+ s32 i;
+
+ for (i = 0; i <= POKEMON_NAME_LENGTH; i++)
+ {
+ if (species > NUM_SPECIES)
+ name[i] = gSpeciesNames[0][i];
+ else
+ name[i] = gSpeciesNames[species][i];
+
+ if (name[i] == EOS)
+ break;
+ }
+
+ name[i] = EOS;
+}
+
+u8 CalculatePPWithBonus(u16 move, u8 ppBonuses, u8 moveIndex)
+{
+ u8 basePP = gBattleMoves[move].pp;
+ return basePP + ((basePP * 20 * ((gUnknown_08329D22[moveIndex] & ppBonuses) >> (2 * moveIndex))) / 100);
+}
+
+void RemoveMonPPBonus(struct Pokemon *mon, u8 moveIndex)
+{
+ u8 ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES, NULL);
+ ppBonuses &= gUnknown_08329D26[moveIndex];
+ SetMonData(mon, MON_DATA_PP_BONUSES, &ppBonuses);
+}
+
+void RemoveBattleMonPPBonus(struct BattlePokemon *mon, u8 moveIndex)
+{
+ mon->ppBonuses &= gUnknown_08329D26[moveIndex];
+}
+
+void CopyPlayerPartyMonToBattleData(u8 battlerId, u8 partyIndex)
+{
+ u16* hpSwitchout;
+ s32 i;
+ u8 nickname[POKEMON_NAME_LENGTH * 2];
+
+ gBattleMons[battlerId].species = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPECIES, NULL);
+ gBattleMons[battlerId].item = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HELD_ITEM, NULL);
+
+ for (i = 0; i < 4; i++)
+ {
+ gBattleMons[battlerId].moves[i] = GetMonData(&gPlayerParty[partyIndex], MON_DATA_MOVE1 + i, NULL);
+ gBattleMons[battlerId].pp[i] = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PP1 + i, NULL);
+ }
+
+ gBattleMons[battlerId].ppBonuses = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PP_BONUSES, NULL);
+ gBattleMons[battlerId].friendship = GetMonData(&gPlayerParty[partyIndex], MON_DATA_FRIENDSHIP, NULL);
+ gBattleMons[battlerId].experience = GetMonData(&gPlayerParty[partyIndex], MON_DATA_EXP, NULL);
+ gBattleMons[battlerId].hpIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HP_IV, NULL);
+ gBattleMons[battlerId].attackIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_ATK_IV, NULL);
+ gBattleMons[battlerId].defenseIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_DEF_IV, NULL);
+ gBattleMons[battlerId].speedIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPEED_IV, NULL);
+ gBattleMons[battlerId].spAttackIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPATK_IV, NULL);
+ gBattleMons[battlerId].spDefenseIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPDEF_IV, NULL);
+ gBattleMons[battlerId].personality = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PERSONALITY, NULL);
+ gBattleMons[battlerId].status1 = GetMonData(&gPlayerParty[partyIndex], MON_DATA_STATUS, NULL);
+ gBattleMons[battlerId].level = GetMonData(&gPlayerParty[partyIndex], MON_DATA_LEVEL, NULL);
+ gBattleMons[battlerId].hp = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HP, NULL);
+ gBattleMons[battlerId].maxHP = GetMonData(&gPlayerParty[partyIndex], MON_DATA_MAX_HP, NULL);
+ gBattleMons[battlerId].attack = GetMonData(&gPlayerParty[partyIndex], MON_DATA_ATK, NULL);
+ gBattleMons[battlerId].defense = GetMonData(&gPlayerParty[partyIndex], MON_DATA_DEF, NULL);
+ gBattleMons[battlerId].speed = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPEED, NULL);
+ gBattleMons[battlerId].spAttack = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPATK, NULL);
+ gBattleMons[battlerId].spDefense = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPDEF, NULL);
+ gBattleMons[battlerId].isEgg = GetMonData(&gPlayerParty[partyIndex], MON_DATA_IS_EGG, NULL);
+ gBattleMons[battlerId].altAbility = GetMonData(&gPlayerParty[partyIndex], MON_DATA_ALT_ABILITY, NULL);
+ gBattleMons[battlerId].otId = GetMonData(&gPlayerParty[partyIndex], MON_DATA_OT_ID, NULL);
+ gBattleMons[battlerId].type1 = gBaseStats[gBattleMons[battlerId].species].type1;
+ gBattleMons[battlerId].type2 = gBaseStats[gBattleMons[battlerId].species].type2;
+ gBattleMons[battlerId].ability = GetAbilityBySpecies(gBattleMons[battlerId].species, gBattleMons[battlerId].altAbility);
+ GetMonData(&gPlayerParty[partyIndex], MON_DATA_NICKNAME, nickname);
+ StringCopy10(gBattleMons[battlerId].nickname, nickname);
+ GetMonData(&gPlayerParty[partyIndex], MON_DATA_OT_NAME, gBattleMons[battlerId].otName);
+
+ hpSwitchout = &gBattleStruct->hpOnSwitchout[GetBattlerSide(battlerId)];
+ *hpSwitchout = gBattleMons[battlerId].hp;
+
+ for (i = 0; i < 8; i++)
+ gBattleMons[battlerId].statStages[i] = 6;
+
+ gBattleMons[battlerId].status2 = 0;
+ sub_803FA70(battlerId);
+ ClearTemporarySpeciesSpriteData(battlerId, FALSE);
+}
+
+bool8 ExecuteTableBasedItemEffect(struct Pokemon *mon, u16 item, u8 partyIndex, u8 moveIndex)
+{
+ return PokemonUseItemEffects(mon, item, partyIndex, moveIndex, 0);
+}
+
+bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 moveIndex, u8 e)
+{
+ u32 dataUnsigned;
+ s32 dataSigned;
+ s32 friendship;
+ s32 cmdIndex;
+ bool8 retVal = TRUE;
+ const u8 *itemEffect;
+ u8 var_3C = 6;
+ u32 var_38;
+ s8 var_34 = 0;
+ u8 holdEffect;
+ u8 battlerId = 4;
+ u32 var_28 = 0;
+ u16 heldItem;
+ u8 r10;
+ u32 r4;
+ u32 r5;
+ s8 r2;
+ u16 evCount;
+
+ heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, NULL);
+ if (heldItem == ITEM_ENIGMA_BERRY)
+ {
+ if (gMain.inBattle)
+ holdEffect = gEnigmaBerries[gBattlerInMenuId].holdEffect;
+ else
+ holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect;
+ }
+ else
+ {
+ holdEffect = ItemId_GetHoldEffect(heldItem);
+ }
+
+ gPotentialItemEffectBattler = gBattlerInMenuId;
+ if (gMain.inBattle)
+ {
+ gActiveBattler = gBattlerInMenuId;
+ cmdIndex = (GetBattlerSide(gActiveBattler) != B_SIDE_PLAYER);
+ while (cmdIndex < gBattlersCount)
+ {
+ if (gBattlerPartyIndexes[cmdIndex] == partyIndex)
+ {
+ battlerId = cmdIndex;
+ break;
+ }
+ cmdIndex += 2;
+ }
+ }
+ else
+ {
+ gActiveBattler = 0;
+ battlerId = MAX_BATTLERS_COUNT;
+ }
+
+ if (!IS_POKEMON_ITEM(item))
+ return TRUE;
+ if (gItemEffectTable[item - 13] == NULL && item != ITEM_ENIGMA_BERRY)
+ return TRUE;
+
+ if (item == ITEM_ENIGMA_BERRY)
+ {
+ if (gMain.inBattle)
+ itemEffect = gEnigmaBerries[gActiveBattler].itemEffect;
+ else
+ itemEffect = gSaveBlock1Ptr->enigmaBerry.itemEffect;
+ }
+ else
+ {
+ itemEffect = gItemEffectTable[item - 13];
+ }
+
+ for (cmdIndex = 0; cmdIndex < 6; cmdIndex++)
+ {
+ switch (cmdIndex)
+ {
+ // status healing effects
+ case 0:
+ if ((itemEffect[cmdIndex] & 0x80)
+ && gMain.inBattle && battlerId != 4 && (gBattleMons[battlerId].status2 & STATUS2_INFATUATION))
+ {
+ gBattleMons[battlerId].status2 &= ~STATUS2_INFATUATION;
+ retVal = FALSE;
+ }
+ if ((itemEffect[cmdIndex] & 0x30)
+ && !(gBattleMons[gActiveBattler].status2 & STATUS2_FOCUS_ENERGY))
+ {
+ gBattleMons[gActiveBattler].status2 |= STATUS2_FOCUS_ENERGY;
+ retVal = FALSE;
+ }
+ if ((itemEffect[cmdIndex] & 0xF)
+ && gBattleMons[gActiveBattler].statStages[STAT_ATK] < 12)
+ {
+ gBattleMons[gActiveBattler].statStages[STAT_ATK] += itemEffect[cmdIndex] & 0xF;
+ if (gBattleMons[gActiveBattler].statStages[STAT_ATK] > 12)
+ gBattleMons[gActiveBattler].statStages[STAT_ATK] = 12;
+ retVal = FALSE;
+ }
+ break;
+ // in-battle stat boosting effects?
+ case 1:
+ if ((itemEffect[cmdIndex] & 0xF0)
+ && gBattleMons[gActiveBattler].statStages[STAT_DEF] < 12)
+ {
+ gBattleMons[gActiveBattler].statStages[STAT_DEF] += (itemEffect[cmdIndex] & 0xF0) >> 4;
+ if (gBattleMons[gActiveBattler].statStages[STAT_DEF] > 12)
+ gBattleMons[gActiveBattler].statStages[STAT_DEF] = 12;
+ retVal = FALSE;
+ }
+ if ((itemEffect[cmdIndex] & 0xF)
+ && gBattleMons[gActiveBattler].statStages[STAT_SPEED] < 12)
+ {
+ gBattleMons[gActiveBattler].statStages[STAT_SPEED] += itemEffect[cmdIndex] & 0xF;
+ if (gBattleMons[gActiveBattler].statStages[STAT_SPEED] > 12)
+ gBattleMons[gActiveBattler].statStages[STAT_SPEED] = 12;
+ retVal = FALSE;
+ }
+ break;
+ // more stat boosting effects?
+ case 2:
+ if ((itemEffect[cmdIndex] & 0xF0)
+ && gBattleMons[gActiveBattler].statStages[STAT_ACC] < 12)
+ {
+ gBattleMons[gActiveBattler].statStages[STAT_ACC] += (itemEffect[cmdIndex] & 0xF0) >> 4;
+ if (gBattleMons[gActiveBattler].statStages[STAT_ACC] > 12)
+ gBattleMons[gActiveBattler].statStages[STAT_ACC] = 12;
+ retVal = FALSE;
+ }
+ if ((itemEffect[cmdIndex] & 0xF)
+ && gBattleMons[gActiveBattler].statStages[STAT_SPATK] < 12)
+ {
+ gBattleMons[gActiveBattler].statStages[STAT_SPATK] += itemEffect[cmdIndex] & 0xF;
+ if (gBattleMons[gActiveBattler].statStages[STAT_SPATK] > 12)
+ gBattleMons[gActiveBattler].statStages[STAT_SPATK] = 12;
+ retVal = FALSE;
+ }
+ break;
+ case 3:
+ if ((itemEffect[cmdIndex] & 0x80)
+ && gSideTimers[GetBattlerSide(gActiveBattler)].mistTimer == 0)
+ {
+ gSideTimers[GetBattlerSide(gActiveBattler)].mistTimer = 5;
+ retVal = FALSE;
+ }
+ if ((itemEffect[cmdIndex] & 0x40) // raise level
+ && GetMonData(mon, MON_DATA_LEVEL, NULL) != MAX_MON_LEVEL)
+ {
+ dataUnsigned = gExperienceTables[gBaseStats[GetMonData(mon, MON_DATA_SPECIES, NULL)].growthRate][GetMonData(mon, MON_DATA_LEVEL, NULL) + 1];
+ SetMonData(mon, MON_DATA_EXP, &dataUnsigned);
+ CalculateMonStats(mon);
+ retVal = FALSE;
+ }
+ if ((itemEffect[cmdIndex] & 0x20)
+ && HealStatusConditions(mon, partyIndex, 7, battlerId) == 0)
+ {
+ if (battlerId != 4)
+ gBattleMons[battlerId].status2 &= ~STATUS2_NIGHTMARE;
+ retVal = FALSE;
+ }
+ if ((itemEffect[cmdIndex] & 0x10) && HealStatusConditions(mon, partyIndex, STATUS1_PSN_ANY | STATUS1_TOXIC_COUNTER, battlerId) == 0)
+ retVal = FALSE;
+ if ((itemEffect[cmdIndex] & 8) && HealStatusConditions(mon, partyIndex, STATUS1_BURN, battlerId) == 0)
+ retVal = FALSE;
+ if ((itemEffect[cmdIndex] & 4) && HealStatusConditions(mon, partyIndex, STATUS1_FREEZE, battlerId) == 0)
+ retVal = FALSE;
+ if ((itemEffect[cmdIndex] & 2) && HealStatusConditions(mon, partyIndex, STATUS1_PARALYSIS, battlerId) == 0)
+ retVal = FALSE;
+ if ((itemEffect[cmdIndex] & 1) // heal confusion
+ && gMain.inBattle && battlerId != 4 && (gBattleMons[battlerId].status2 & STATUS2_CONFUSION))
+ {
+ gBattleMons[battlerId].status2 &= ~STATUS2_CONFUSION;
+ retVal = FALSE;
+ }
+ break;
+ // EV, HP, and PP raising effects
+ case 4:
+ r10 = itemEffect[cmdIndex];
+ if (r10 & 0x20)
+ {
+ r10 &= ~0x20;
+ dataUnsigned = (GetMonData(mon, MON_DATA_PP_BONUSES, NULL) & gUnknown_08329D22[moveIndex]) >> (moveIndex * 2);
+ var_38 = CalculatePPWithBonus(GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL), GetMonData(mon, MON_DATA_PP_BONUSES, NULL), moveIndex);
+ if (dataUnsigned <= 2 && var_38 > 4)
+ {
+ dataUnsigned = GetMonData(mon, MON_DATA_PP_BONUSES, NULL) + gUnknown_08329D2A[moveIndex];
+ SetMonData(mon, MON_DATA_PP_BONUSES, &dataUnsigned);
+
+ dataUnsigned = CalculatePPWithBonus(GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL), dataUnsigned, moveIndex) - var_38;
+ dataUnsigned = GetMonData(mon, MON_DATA_PP1 + moveIndex, NULL) + dataUnsigned;
+ SetMonData(mon, MON_DATA_PP1 + moveIndex, &dataUnsigned);
+ retVal = FALSE;
+ }
+ }
+ var_38 = 0;
+ while (r10 != 0)
+ {
+ if (r10 & 1)
+ {
+ switch (var_38)
+ {
+ case 0:
+ case 1:
+ evCount = GetMonEVCount(mon);
+ r5 = itemEffect[var_3C];
+ dataSigned = GetMonData(mon, sGetMonDataEVConstants[var_38], NULL);
+ r2 = r5;
+ if (r2 > 0)
+ {
+ if (evCount >= MAX_TOTAL_EVS)
+ return TRUE;
+ if (dataSigned >= 100)
+ break;
+
+ if (dataSigned + r2 > 100)
+ r5 = 100 - (dataSigned + r2) + r2;
+ else
+ r5 = r2;
+
+ if (evCount + r5 > MAX_TOTAL_EVS)
+ r5 += MAX_TOTAL_EVS - (evCount + r5);
+ dataSigned += r5;
+ }
+ else
+ {
+ if (dataSigned == 0)
+ {
+ var_28 = 1;
+ var_3C++;
+ break;
+ }
+ dataSigned += r2;
+ if (dataSigned < 0)
+ dataSigned = 0;
+ }
+ SetMonData(mon, sGetMonDataEVConstants[var_38], &dataSigned);
+ CalculateMonStats(mon);
+ var_3C++;
+ retVal = FALSE;
+ break;
+ case 2:
+ // revive?
+ if (r10 & 0x10)
+ {
+ if (GetMonData(mon, MON_DATA_HP, NULL) != 0)
+ {
+ var_3C++;
+ break;
+ }
+ if (gMain.inBattle)
+ {
+ if (battlerId != 4)
+ {
+ gAbsentBattlerFlags &= ~gBitTable[battlerId];
+ CopyPlayerPartyMonToBattleData(battlerId, pokemon_order_func(gBattlerPartyIndexes[battlerId]));
+ if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER && gBattleResults.unk4 < 255)
+ gBattleResults.unk4++;
+ }
+ else
+ {
+ gAbsentBattlerFlags &= ~gBitTable[gActiveBattler ^ 2];
+ if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER && gBattleResults.unk4 < 255)
+ gBattleResults.unk4++;
+ }
+ }
+ }
+ else
+ {
+ if (GetMonData(mon, MON_DATA_HP, NULL) == 0)
+ {
+ var_3C++;
+ break;
+ }
+ }
+ dataUnsigned = itemEffect[var_3C++];
+ switch (dataUnsigned)
+ {
+ case 0xFF:
+ dataUnsigned = GetMonData(mon, MON_DATA_MAX_HP, NULL) - GetMonData(mon, MON_DATA_HP, NULL);
+ break;
+ case 0xFE:
+ dataUnsigned = GetMonData(mon, MON_DATA_MAX_HP, NULL) / 2;
+ if (dataUnsigned == 0)
+ dataUnsigned = 1;
+ break;
+ case 0xFD:
+ dataUnsigned = gBattleScripting.field_23;
+ break;
+ }
+ if (GetMonData(mon, MON_DATA_MAX_HP, NULL) != GetMonData(mon, MON_DATA_HP, NULL))
+ {
+ if (e == 0)
+ {
+ dataUnsigned = GetMonData(mon, MON_DATA_HP, NULL) + dataUnsigned;
+ if (dataUnsigned > GetMonData(mon, MON_DATA_MAX_HP, NULL))
+ dataUnsigned = GetMonData(mon, MON_DATA_MAX_HP, NULL);
+ SetMonData(mon, MON_DATA_HP, &dataUnsigned);
+ if (gMain.inBattle && battlerId != 4)
+ {
+ gBattleMons[battlerId].hp = dataUnsigned;
+ if (!(r10 & 0x10) && GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
+ {
+ if (gBattleResults.unk3 < 255)
+ gBattleResults.unk3++;
+ // I have to re-use this variable to match.
+ r5 = gActiveBattler;
+ gActiveBattler = battlerId;
+ BtlController_EmitGetMonData(0, 0, 0);
+ MarkBattlerForControllerExec(gActiveBattler);
+ gActiveBattler = r5;
+ }
+ }
+ }
+ else
+ {
+ gBattleMoveDamage = -dataUnsigned;
+ }
+ retVal = FALSE;
+ }
+ r10 &= 0xEF;
+ break;
+ case 3:
+ if (!(r10 & 2))
+ {
+ for (r5 = 0; (signed)(r5) < (signed)(4); r5++)
+ {
+ u16 moveId;
+
+ dataUnsigned = GetMonData(mon, MON_DATA_PP1 + r5, NULL);
+ moveId = GetMonData(mon, MON_DATA_MOVE1 + r5, NULL);
+ if (dataUnsigned != CalculatePPWithBonus(moveId, GetMonData(mon, MON_DATA_PP_BONUSES, NULL), r5))
+ {
+ dataUnsigned += itemEffect[var_3C];
+ moveId = GetMonData(mon, MON_DATA_MOVE1 + r5, NULL);
+ if (dataUnsigned > CalculatePPWithBonus(moveId, GetMonData(mon, MON_DATA_PP_BONUSES, NULL), r5))
+ {
+ moveId = GetMonData(mon, MON_DATA_MOVE1 + r5, NULL);
+ dataUnsigned = CalculatePPWithBonus(moveId, GetMonData(mon, MON_DATA_PP_BONUSES, NULL), r5);
+ }
+ SetMonData(mon, MON_DATA_PP1 + r5, &dataUnsigned);
+ if (gMain.inBattle
+ && battlerId != 4 && !(gBattleMons[battlerId].status2 & STATUS2_TRANSFORMED)
+ && !(gDisableStructs[battlerId].unk18_b & gBitTable[r5]))
+ gBattleMons[battlerId].pp[r5] = dataUnsigned;
+ retVal = FALSE;
+ }
+ }
+ var_3C++;
+ }
+ else
+ {
+ u16 moveId;
+
+ dataUnsigned = GetMonData(mon, MON_DATA_PP1 + moveIndex, NULL);
+ moveId = GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL);
+ if (dataUnsigned != CalculatePPWithBonus(moveId, GetMonData(mon, MON_DATA_PP_BONUSES, NULL), moveIndex))
+ {
+ dataUnsigned += itemEffect[var_3C++];
+ moveId = GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL);
+ if (dataUnsigned > CalculatePPWithBonus(moveId, GetMonData(mon, MON_DATA_PP_BONUSES, NULL), moveIndex))
+ {
+ moveId = GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL);
+ dataUnsigned = CalculatePPWithBonus(moveId, GetMonData(mon, MON_DATA_PP_BONUSES, NULL), moveIndex);
+ }
+ SetMonData(mon, MON_DATA_PP1 + moveIndex, &dataUnsigned);
+ if (gMain.inBattle
+ && battlerId != 4 && !(gBattleMons[battlerId].status2 & STATUS2_TRANSFORMED)
+ && !(gDisableStructs[battlerId].unk18_b & gBitTable[moveIndex]))
+ gBattleMons[battlerId].pp[moveIndex] = dataUnsigned;
+ retVal = FALSE;
+ }
+ }
+ break;
+ case 7:
+ {
+ u16 targetSpecies = GetEvolutionTargetSpecies(mon, 2, item);
+
+ if (targetSpecies != SPECIES_NONE)
+ {
+ BeginEvolutionScene(mon, targetSpecies, 0, partyIndex);
+ return FALSE;
+ }
+ }
+ break;
+ }
+ }
+ var_38++;
+ r10 >>= 1;
+ }
+ break;
+ case 5:
+ r10 = itemEffect[cmdIndex];
+ var_38 = 0;
+ while (r10 != 0)
+ {
+ if (r10 & 1)
+ {
+ switch (var_38)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ evCount = GetMonEVCount(mon);
+ r5 = itemEffect[var_3C];
+ dataSigned = GetMonData(mon, sGetMonDataEVConstants[var_38 + 2], NULL);
+ r2 = r5;
+ if (r2 > 0)
+ {
+ if (evCount >= MAX_TOTAL_EVS)
+ return TRUE;
+ if (dataSigned >= 100)
+ break;
+
+ if (dataSigned + r2 > 100)
+ r5 = 100 - (dataSigned + r2) + r2;
+ else
+ r5 = r2;
+
+ if (evCount + r5 > MAX_TOTAL_EVS)
+ r5 += MAX_TOTAL_EVS - (evCount + r5);
+ dataSigned += r5;
+ }
+ else
+ {
+ if (dataSigned == 0)
+ {
+ var_28 = 1;
+ var_3C++;
+ break;
+ }
+ dataSigned += r2;
+ if (dataSigned < 0)
+ dataSigned = 0;
+ }
+ SetMonData(mon, sGetMonDataEVConstants[var_38 + 2], &dataSigned);
+ CalculateMonStats(mon);
+ retVal = FALSE;
+ var_3C++;
+ break;
+ case 4:
+ dataUnsigned = (GetMonData(mon, MON_DATA_PP_BONUSES, NULL) & gUnknown_08329D22[moveIndex]) >> (moveIndex * 2);
+ r5 = CalculatePPWithBonus(GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL), GetMonData(mon, MON_DATA_PP_BONUSES, NULL), moveIndex);
+ if (dataUnsigned < 3 && r5 > 4)
+ {
+ dataUnsigned = GetMonData(mon, MON_DATA_PP_BONUSES, NULL);
+ dataUnsigned &= gUnknown_08329D26[moveIndex];
+ dataUnsigned += gUnknown_08329D2A[moveIndex] * 3;
+
+ SetMonData(mon, MON_DATA_PP_BONUSES, &dataUnsigned);
+ dataUnsigned = CalculatePPWithBonus(GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL), dataUnsigned, moveIndex) - r5;
+ dataUnsigned = GetMonData(mon, MON_DATA_PP1 + moveIndex, NULL) + dataUnsigned;
+ SetMonData(mon, MON_DATA_PP1 + moveIndex, &dataUnsigned);
+ retVal = FALSE;
+ }
+ break;
+ case 5:
+ if (GetMonData(mon, MON_DATA_FRIENDSHIP, NULL) < 100 && (retVal == 0 || var_28 != 0) && !sub_806F104() && var_34 == 0)
+ {
+ var_34 = itemEffect[var_3C];
+ friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, NULL);
+ if (var_34 > 0 && holdEffect == HOLD_EFFECT_HAPPINESS_UP)
+ friendship += 150 * var_34 / 100;
+ else
+ friendship += var_34;
+ if (var_34 > 0)
+ {
+ if (GetMonData(mon, MON_DATA_POKEBALL, NULL) == 11)
+ friendship++;
+ if (GetMonData(mon, MON_DATA_MET_LOCATION, NULL) == sav1_map_get_name())
+ friendship++;
+ }
+ if (friendship < 0)
+ friendship = 0;
+ if (friendship > 255)
+ friendship = 255;
+ SetMonData(mon, MON_DATA_FRIENDSHIP, &friendship);
+ retVal = FALSE;
+ }
+ var_3C++;
+ break;
+ case 6:
+ if (GetMonData(mon, MON_DATA_FRIENDSHIP, NULL) >= 100 && GetMonData(mon, MON_DATA_FRIENDSHIP, NULL) < 200
+ && (retVal == 0 || var_28 != 0) && !sub_806F104() && var_34 == 0)
+ {
+ var_34 = itemEffect[var_3C];
+ friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, NULL);
+ if ((s8)(var_34) > 0 && holdEffect == HOLD_EFFECT_HAPPINESS_UP)
+ friendship += 150 * var_34 / 100;
+ else
+ friendship += var_34;
+ if (var_34 > 0)
+ {
+ if (GetMonData(mon, MON_DATA_POKEBALL, NULL) == 11)
+ friendship++;
+ if (GetMonData(mon, MON_DATA_MET_LOCATION, NULL) == sav1_map_get_name())
+ friendship++;
+ }
+ if (friendship < 0)
+ friendship = 0;
+ if (friendship > 255)
+ friendship = 255;
+ SetMonData(mon, MON_DATA_FRIENDSHIP, &friendship);
+ retVal = FALSE;
+ }
+ var_3C++;
+ break;
+ case 7:
+ if (GetMonData(mon, MON_DATA_FRIENDSHIP, NULL) >= 200 && (retVal == 0 || var_28 != 0) && !sub_806F104() && var_34 == 0)
+ {
+ var_34 = itemEffect[var_3C];
+ friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, NULL);
+ if ((s8)(var_34) > 0 && holdEffect == HOLD_EFFECT_HAPPINESS_UP)
+ friendship += 150 * var_34 / 100;
+ else
+ friendship += var_34;
+ if (var_34 > 0)
+ {
+ if (GetMonData(mon, MON_DATA_POKEBALL, NULL) == 11)
+ friendship++;
+ if (GetMonData(mon, MON_DATA_MET_LOCATION, NULL) == sav1_map_get_name())
+ friendship++;
+ }
+ if (friendship < 0)
+ friendship = 0;
+ if (friendship > 255)
+ friendship = 255;
+ SetMonData(mon, MON_DATA_FRIENDSHIP, &friendship);
+ retVal = FALSE;
+ }
+ var_3C++;
+ break;
+ }
+ }
+ var_38++;
+ r10 >>= 1;
+ }
+ break;
+ }
+ }
+ return retVal;
+}
+
+bool8 HealStatusConditions(struct Pokemon *mon, u32 battlePartyId, u32 healMask, u8 battlerId)
+{
+ u32 status = GetMonData(mon, MON_DATA_STATUS, 0);
+
+ if (status & healMask)
+ {
+ status &= ~healMask;
+ SetMonData(mon, MON_DATA_STATUS, &status);
+ if (gMain.inBattle && battlerId != MAX_BATTLERS_COUNT)
+ gBattleMons[battlerId].status1 &= ~healMask;
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+}
+
+u8 GetItemEffectParamOffset(u16 itemId, u8 effectByte, u8 effectBit)
+{
+ const u8 *temp;
+ const u8 *itemEffect;
+ u8 offset;
+ int i;
+ u8 j;
+ u8 val;
+
+ offset = 6;
+
+ temp = gItemEffectTable[itemId - 13];
+
+ if (!temp && itemId != ITEM_ENIGMA_BERRY)
+ return 0;
+
+ if (itemId == ITEM_ENIGMA_BERRY)
+ {
+ temp = gEnigmaBerries[gActiveBattler].itemEffect;
+ }
+
+ itemEffect = temp;
+
+ for (i = 0; i < 6; i++)
+ {
+ switch (i)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ if (i == effectByte)
+ return 0;
+ break;
+ case 4:
+ val = itemEffect[4];
+ if (val & 0x20)
+ val &= 0xDF;
+ j = 0;
+ while (val)
+ {
+ if (val & 1)
+ {
+ switch (j)
+ {
+ case 2:
+ if (val & 0x10)
+ val &= 0xEF;
+ case 0:
+ if (i == effectByte && (val & effectBit))
+ return offset;
+ offset++;
+ break;
+ case 1:
+ if (i == effectByte && (val & effectBit))
+ return offset;
+ offset++;
+ break;
+ case 3:
+ if (i == effectByte && (val & effectBit))
+ return offset;
+ offset++;
+ break;
+ case 7:
+ if (i == effectByte)
+ return 0;
+ break;
+ }
+ }
+ j++;
+ val >>= 1;
+ if (i == effectByte)
+ effectBit >>= 1;
+ }
+ break;
+ case 5:
+ val = itemEffect[5];
+ j = 0;
+ while (val)
+ {
+ if (val & 1)
+ {
+ switch (j)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ if (i == effectByte && (val & effectBit))
+ return offset;
+ offset++;
+ break;
+ case 7:
+ if (i == effectByte)
+ return 0;
+ break;
+ }
+ }
+ j++;
+ val >>= 1;
+ if (i == effectByte)
+ effectBit >>= 1;
+ }
+ break;
+ }
+ }
+
+ return offset;
+}
+
+static void sub_806CF24(s32 arg0)
+{
+ gBattlerTarget = gBattlerInMenuId;
+ StringCopy(gBattleTextBuff1, gStatNamesTable[gUnknown_08329EC8[arg0]]);
+ StringCopy(gBattleTextBuff2, gText_StatRose);
+ BattleStringExpandPlaceholdersToDisplayedString(gText_PkmnsStatChanged2);
+}
+
+u8 *sub_806CF78(u16 itemId)
+{
+ int i;
+ const u8 *itemEffect;
+
+ if (itemId == ITEM_ENIGMA_BERRY)
+ {
+ if (gMain.inBattle)
+ itemEffect = gEnigmaBerries[gBattlerInMenuId].itemEffect;
+ else
+ itemEffect = gSaveBlock1Ptr->enigmaBerry.itemEffect;
+ }
+ else
+ {
+ itemEffect = gItemEffectTable[itemId - 13];
+ }
+
+ gPotentialItemEffectBattler = gBattlerInMenuId;
+
+ for (i = 0; i < 3; i++)
+ {
+ if (itemEffect[i] & 0xF)
+ sub_806CF24(i * 2);
+ if (itemEffect[i] & 0xF0)
+ {
+ if (i)
+ {
+ sub_806CF24(i * 2 + 1);
+ }
+ else
+ {
+ gBattlerAttacker = gBattlerInMenuId;
+ BattleStringExpandPlaceholdersToDisplayedString(gText_PkmnGettingPumped);
+ }
+ }
+ }
+
+ if (itemEffect[3] & 0x80)
+ {
+ gBattlerAttacker = gBattlerInMenuId;
+ BattleStringExpandPlaceholdersToDisplayedString(gText_PkmnShroudedInMist);
+ }
+
+ return gDisplayedStringBattle;
+}
+
+u8 GetNature(struct Pokemon *mon)
+{
+ return GetMonData(mon, MON_DATA_PERSONALITY, 0) % 25;
+}
+
+u8 GetNatureFromPersonality(u32 personality)
+{
+ return personality % 25;
+}
+
+u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 type, u16 evolutionItem)
+{
+ int i;
+ u16 targetSpecies = 0;
+ u16 species = GetMonData(mon, MON_DATA_SPECIES, 0);
+ u16 heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0);
+ u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0);
+ u8 level;
+ u16 friendship;
+ u8 beauty = GetMonData(mon, MON_DATA_BEAUTY, 0);
+ u16 upperPersonality = personality >> 16;
+ u8 holdEffect;
+
+ if (heldItem == ITEM_ENIGMA_BERRY)
+ holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect;
+ else
+ holdEffect = ItemId_GetHoldEffect(heldItem);
+
+ if (holdEffect == 38 && type != 3)
+ return 0;
+
+ switch (type)
+ {
+ case 0:
+ level = GetMonData(mon, MON_DATA_LEVEL, 0);
+ friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, 0);
+
+ for (i = 0; i < 5; i++)
+ {
+ switch (gEvolutionTable[species][i].method)
+ {
+ case EVO_FRIENDSHIP:
+ if (friendship >= 220)
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ case EVO_FRIENDSHIP_DAY:
+ RtcCalcLocalTime();
+ if (gLocalTime.hours >= 12 && gLocalTime.hours < 24 && friendship >= 220)
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ case EVO_FRIENDSHIP_NIGHT:
+ RtcCalcLocalTime();
+ if (gLocalTime.hours >= 0 && gLocalTime.hours < 12 && friendship >= 220)
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ case EVO_LEVEL:
+ if (gEvolutionTable[species][i].param <= level)
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ case EVO_LEVEL_ATK_GT_DEF:
+ if (gEvolutionTable[species][i].param <= level)
+ if (GetMonData(mon, MON_DATA_ATK, 0) > GetMonData(mon, MON_DATA_DEF, 0))
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ case EVO_LEVEL_ATK_EQ_DEF:
+ if (gEvolutionTable[species][i].param <= level)
+ if (GetMonData(mon, MON_DATA_ATK, 0) == GetMonData(mon, MON_DATA_DEF, 0))
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ case EVO_LEVEL_ATK_LT_DEF:
+ if (gEvolutionTable[species][i].param <= level)
+ if (GetMonData(mon, MON_DATA_ATK, 0) < GetMonData(mon, MON_DATA_DEF, 0))
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ case EVO_LEVEL_SILCOON:
+ if (gEvolutionTable[species][i].param <= level && (upperPersonality % 10) <= 4)
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ case EVO_LEVEL_CASCOON:
+ if (gEvolutionTable[species][i].param <= level && (upperPersonality % 10) > 4)
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ case EVO_LEVEL_NINJASK:
+ if (gEvolutionTable[species][i].param <= level)
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ case EVO_BEAUTY:
+ if (gEvolutionTable[species][i].param <= beauty)
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ }
+ }
+ break;
+ case 1:
+ for (i = 0; i < 5; i++)
+ {
+ switch (gEvolutionTable[species][i].method)
+ {
+ case EVO_TRADE:
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ case EVO_TRADE_ITEM:
+ if (gEvolutionTable[species][i].param == heldItem)
+ {
+ heldItem = 0;
+ SetMonData(mon, MON_DATA_HELD_ITEM, (u8 *)&heldItem);
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ }
+ break;
+ }
+ }
+ break;
+ case 2:
+ case 3:
+ for (i = 0; i < 5; i++)
+ {
+ if (gEvolutionTable[species][i].method == EVO_ITEM
+ && gEvolutionTable[species][i].param == evolutionItem)
+ {
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ }
+ }
+ break;
+ }
+
+ return targetSpecies;
+}
+
+u16 HoennPokedexNumToSpecies(u16 hoennNum)
+{
+ u16 species;
+
+ if (!hoennNum)
+ return 0;
+
+ species = 0;
+
+ while (species < 411 && gSpeciesToHoennPokedexNum[species] != hoennNum)
+ species++;
+
+ if (species == 411)
+ return 0;
+
+ return species + 1;
+}
+
+u16 NationalPokedexNumToSpecies(u16 nationalNum)
+{
+ u16 species;
+
+ if (!nationalNum)
+ return 0;
+
+ species = 0;
+
+ while (species < 411 && gSpeciesToNationalPokedexNum[species] != nationalNum)
+ species++;
+
+ if (species == 411)
+ return 0;
+
+ return species + 1;
+}
+
+u16 NationalToHoennOrder(u16 nationalNum)
+{
+ u16 hoennNum;
+
+ if (!nationalNum)
+ return 0;
+
+ hoennNum = 0;
+
+ while (hoennNum < 411 && gHoennToNationalOrder[hoennNum] != nationalNum)
+ hoennNum++;
+
+ if (hoennNum == 411)
+ return 0;
+
+ return hoennNum + 1;
+}
+
+u16 SpeciesToNationalPokedexNum(u16 species)
+{
+ if (!species)
+ return 0;
+
+ return gSpeciesToNationalPokedexNum[species - 1];
+}
+
+u16 SpeciesToHoennPokedexNum(u16 species)
+{
+ if (!species)
+ return 0;
+
+ return gSpeciesToHoennPokedexNum[species - 1];
+}
+
+u16 HoennToNationalOrder(u16 hoennNum)
+{
+ if (!hoennNum)
+ return 0;
+
+ return gHoennToNationalOrder[hoennNum - 1];
+}
+
+u16 SpeciesToCryId(u16 species)
+{
+ if (species <= 250)
+ return species;
+
+ if (species < 276)
+ return 200;
+
+ return gSpeciesIdToCryId[species - 276];
+}
+
+void sub_806D544(u16 species, u32 personality, u8 *dest)
+{
+ if (species == SPECIES_SPINDA
+ && dest != gMonSpritesGfxPtr->sprites[0]
+ && dest != gMonSpritesGfxPtr->sprites[2])
+ {
+ int i;
+ for (i = 0; i < 4; i++)
+ {
+ int j;
+ u8 x = gSpindaSpotGraphics[i].x + ((personality & 0x0F) - 8);
+ u8 y = gSpindaSpotGraphics[i].y + (((personality & 0xF0) >> 4) - 8);
+
+ for (j = 0; j < 16; j++)
+ {
+ int k;
+ s32 row = gSpindaSpotGraphics[i].image[j];
+
+ for (k = x; k < x + 16; k++)
+ {
+ u8 *val = dest + ((k / 8) * 32) + ((k % 8) / 2) + ((y >> 3) << 8) + ((y & 7) << 2);
+
+ if (row & 1)
+ {
+ if (k & 1)
+ {
+ if ((u8)((*val & 0xF0) - 0x10) <= 0x20)
+ *val += 0x40;
+ }
+ else
+ {
+ if ((u8)((*val & 0xF) - 0x01) <= 0x02)
+ *val += 0x04;
+ }
+ }
+
+ row >>= 1;
+ }
+
+ y++;
+ }
+
+ personality >>= 8;
+ }
+ }
+}
+
+void DrawSpindaSpots(u16 species, u32 personality, u8 *dest, u8 a4)
+{
+ if (species == SPECIES_SPINDA && a4)
+ {
+ int i;
+ for (i = 0; i < 4; i++)
+ {
+ int j;
+ u8 x = gSpindaSpotGraphics[i].x + ((personality & 0x0F) - 8);
+ u8 y = gSpindaSpotGraphics[i].y + (((personality & 0xF0) >> 4) - 8);
+
+ for (j = 0; j < 16; j++)
+ {
+ int k;
+ s32 row = gSpindaSpotGraphics[i].image[j];
+
+ for (k = x; k < x + 16; k++)
+ {
+ u8 *val = dest + ((k / 8) * 32) + ((k % 8) / 2) + ((y >> 3) << 8) + ((y & 7) << 2);
+
+ if (row & 1)
+ {
+ if (k & 1)
+ {
+ if ((u8)((*val & 0xF0) - 0x10) <= 0x20)
+ *val += 0x40;
+ }
+ else
+ {
+ if ((u8)((*val & 0xF) - 0x01) <= 0x02)
+ *val += 0x04;
+ }
+ }
+
+ row >>= 1;
+ }
+
+ y++;
+ }
+
+ personality >>= 8;
+ }
+ }
+}
+
+void EvolutionRenameMon(struct Pokemon *mon, u16 oldSpecies, u16 newSpecies)
+{
+ u8 language;
+ GetMonData(mon, MON_DATA_NICKNAME, gStringVar1);
+ language = GetMonData(mon, MON_DATA_LANGUAGE, &language);
+ if (language == GAME_LANGUAGE && !StringCompare(gSpeciesNames[oldSpecies], gStringVar1))
+ SetMonData(mon, MON_DATA_NICKNAME, gSpeciesNames[newSpecies]);
+}
+
+bool8 sub_806D7EC(void)
+{
+ bool8 retVal = FALSE;
+ switch (gLinkPlayers[GetMultiplayerId()].lp_field_18)
+ {
+ case 0:
+ case 3:
+ retVal = FALSE;
+ break;
+ case 1:
+ case 2:
+ retVal = TRUE;
+ break;
+ }
+ return retVal;
+}
+
+bool16 sub_806D82C(u8 id)
+{
+ bool16 retVal = FALSE;
+ switch (gLinkPlayers[id].lp_field_18)
+ {
+ case 0:
+ case 3:
+ retVal = FALSE;
+ break;
+ case 1:
+ case 2:
+ retVal = TRUE;
+ break;
+ }
+ return retVal;
+}
+
+s32 GetBattlerMultiplayerId(u16 a1)
+{
+ s32 id;
+ for (id = 0; id < MAX_LINK_PLAYERS; id++)
+ if (gLinkPlayers[id].lp_field_18 == a1)
+ break;
+ return id;
+}
+
+u8 GetTrainerEncounterMusicId(u16 trainerOpponentId)
+{
+ if (InBattlePyramid())
+ return GetTrainerEncounterMusicIdInBattlePyramind(trainerOpponentId);
+ if (sub_81D5C18())
+ return sub_81D63C8(trainerOpponentId);
+ return TRAINER_ENCOUNTER_MUSIC(trainerOpponentId);
+}
+
+u16 ModifyStatByNature(u8 nature, u16 n, u8 statIndex)
+{
+ if (statIndex < 1 || statIndex > 5)
+ {
+ // should just be "return n", but it wouldn't match without this
+ u16 retVal = n;
+ retVal++;
+ retVal--;
+ return retVal;
+ }
+
+ switch (gNatureStatTable[nature][statIndex - 1])
+ {
+ case 1:
+ return (u16)(n * 110) / 100;
+ case -1:
+ return (u16)(n * 90) / 100;
+ }
+
+ return n;
+}
+
+void AdjustFriendship(struct Pokemon *mon, u8 event)
+{
+ u16 species, heldItem;
+ u8 holdEffect;
+
+ if (sub_806F104())
+ return;
+
+ species = GetMonData(mon, MON_DATA_SPECIES2, 0);
+ heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0);
+
+ if (heldItem == ITEM_ENIGMA_BERRY)
+ {
+ if (gMain.inBattle)
+ holdEffect = gEnigmaBerries[0].holdEffect;
+ else
+ holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect;
+ }
+ else
+ {
+ holdEffect = ItemId_GetHoldEffect(heldItem);
+ }
+
+ if (species && species != SPECIES_EGG)
+ {
+ u8 friendshipLevel = 0;
+ s16 friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, 0);
+ if (friendship > 99)
+ friendshipLevel++;
+ if (friendship > 199)
+ friendshipLevel++;
+ if ((event != 5 || !(Random() & 1))
+ && (event != 3
+ || ((gBattleTypeFlags & BATTLE_TYPE_TRAINER)
+ && (gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_ELITE_FOUR
+ || gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_LEADER
+ || gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_CHAMPION))))
+ {
+ s8 mod = gUnknown_08329ECE[event][friendshipLevel];
+ if (mod > 0 && holdEffect == HOLD_EFFECT_HAPPINESS_UP)
+ mod = (150 * mod) / 100;
+ friendship += mod;
+ if (mod > 0)
+ {
+ if (GetMonData(mon, MON_DATA_POKEBALL, 0) == ITEM_LUXURY_BALL)
+ friendship++;
+ if (GetMonData(mon, MON_DATA_MET_LOCATION, 0) == sav1_map_get_name())
+ friendship++;
+ }
+ if (friendship < 0)
+ friendship = 0;
+ if (friendship > 255)
+ friendship = 255;
+ SetMonData(mon, MON_DATA_FRIENDSHIP, &friendship);
+ }
+ }
+}
+
+void MonGainEVs(struct Pokemon *mon, u16 defeatedSpecies)
+{
+ u8 evs[NUM_STATS];
+ u16 evIncrease = 0;
+ u16 totalEVs = 0;
+ u16 heldItem;
+ u8 holdEffect;
+ int i;
+
+ for (i = 0; i < NUM_STATS; i++)
+ {
+ evs[i] = GetMonData(mon, MON_DATA_HP_EV + i, 0);
+ totalEVs += evs[i];
+ }
+
+ for (i = 0; i < NUM_STATS; i++)
+ {
+ u8 hasHadPokerus;
+ int multiplier;
+
+ if (totalEVs >= MAX_TOTAL_EVS)
+ break;
+
+ hasHadPokerus = CheckPartyHasHadPokerus(mon, 0);
+
+ if (hasHadPokerus)
+ multiplier = 2;
+ else
+ multiplier = 1;
+
+ switch (i)
+ {
+ case 0:
+ evIncrease = gBaseStats[defeatedSpecies].evYield_HP * multiplier;
+ break;
+ case 1:
+ evIncrease = gBaseStats[defeatedSpecies].evYield_Attack * multiplier;
+ break;
+ case 2:
+ evIncrease = gBaseStats[defeatedSpecies].evYield_Defense * multiplier;
+ break;
+ case 3:
+ evIncrease = gBaseStats[defeatedSpecies].evYield_Speed * multiplier;
+ break;
+ case 4:
+ evIncrease = gBaseStats[defeatedSpecies].evYield_SpAttack * multiplier;
+ break;
+ case 5:
+ evIncrease = gBaseStats[defeatedSpecies].evYield_SpDefense * multiplier;
+ break;
+ }
+
+ heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0);
+
+ if (heldItem == ITEM_ENIGMA_BERRY)
+ {
+ if (gMain.inBattle)
+ holdEffect = gEnigmaBerries[0].holdEffect;
+ else
+ holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect;
+ }
+ else
+ {
+ holdEffect = ItemId_GetHoldEffect(heldItem);
+ }
+
+ if (holdEffect == HOLD_EFFECT_MACHO_BRACE)
+ evIncrease *= 2;
+
+ if (totalEVs + (s16)evIncrease > MAX_TOTAL_EVS)
+ evIncrease = ((s16)evIncrease + MAX_TOTAL_EVS) - (totalEVs + evIncrease);
+
+ if (evs[i] + (s16)evIncrease > 255)
+ {
+ int val1 = (s16)evIncrease + 255;
+ int val2 = evs[i] + evIncrease;
+ evIncrease = val1 - val2;
+ }
+
+ evs[i] += evIncrease;
+ totalEVs += evIncrease;
+ SetMonData(mon, MON_DATA_HP_EV + i, &evs[i]);
+ }
+}
+
+u16 GetMonEVCount(struct Pokemon *mon)
+{
+ int i;
+ u16 count = 0;
+
+ for (i = 0; i < NUM_STATS; i++)
+ count += GetMonData(mon, MON_DATA_HP_EV + i, 0);
+
+ return count;
+}
+
+void RandomlyGivePartyPokerus(struct Pokemon *party)
+{
+ u16 rnd = Random();
+ if (rnd == 0x4000 || rnd == 0x8000 || rnd == 0xC000)
+ {
+ struct Pokemon *mon;
+
+ do
+ {
+ do
+ {
+ rnd = Random() % PARTY_SIZE;
+ mon = &party[rnd];
+ }
+ while (!GetMonData(mon, MON_DATA_SPECIES, 0));
+ }
+ while (GetMonData(mon, MON_DATA_IS_EGG, 0));
+
+ if (!(CheckPartyHasHadPokerus(party, gBitTable[rnd])))
+ {
+ u8 rnd2;
+
+ do
+ {
+ rnd2 = Random();
+ }
+ while ((rnd2 & 0x7) == 0);
+
+ if (rnd2 & 0xF0)
+ rnd2 &= 0x7;
+
+ rnd2 |= (rnd2 << 4);
+ rnd2 &= 0xF3;
+ rnd2++;
+
+ SetMonData(&party[rnd], MON_DATA_POKERUS, &rnd2);
+ }
+ }
+}
+
+u8 CheckPartyPokerus(struct Pokemon *party, u8 selection)
+{
+ u8 retVal;
+
+ int partyIndex = 0;
+ unsigned curBit = 1;
+ retVal = 0;
+
+ if (selection)
+ {
+ do
+ {
+ if ((selection & 1) && (GetMonData(&party[partyIndex], MON_DATA_POKERUS, 0) & 0xF))
+ retVal |= curBit;
+ partyIndex++;
+ curBit <<= 1;
+ selection >>= 1;
+ }
+ while (selection);
+ }
+ else if (GetMonData(&party[0], MON_DATA_POKERUS, 0) & 0xF)
+ {
+ retVal = 1;
+ }
+
+ return retVal;
+}
+
+u8 CheckPartyHasHadPokerus(struct Pokemon *party, u8 selection)
+{
+ u8 retVal;
+
+ int partyIndex = 0;
+ unsigned curBit = 1;
+ retVal = 0;
+
+ if (selection)
+ {
+ do
+ {
+ if ((selection & 1) && GetMonData(&party[partyIndex], MON_DATA_POKERUS, 0))
+ retVal |= curBit;
+ partyIndex++;
+ curBit <<= 1;
+ selection >>= 1;
+ }
+ while (selection);
+ }
+ else if (GetMonData(&party[0], MON_DATA_POKERUS, 0))
+ {
+ retVal = 1;
+ }
+
+ return retVal;
+}
+
+void UpdatePartyPokerusTime(u16 days)
+{
+ int i;
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, 0))
+ {
+ u8 pokerus = GetMonData(&gPlayerParty[i], MON_DATA_POKERUS, 0);
+ if (pokerus & 0xF)
+ {
+ if ((pokerus & 0xF) < days || days > 4)
+ pokerus &= 0xF0;
+ else
+ pokerus -= days;
+
+ if (pokerus == 0)
+ pokerus = 0x10;
+
+ SetMonData(&gPlayerParty[i], MON_DATA_POKERUS, &pokerus);
+ }
+ }
+ }
+}
+
+void PartySpreadPokerus(struct Pokemon *party)
+{
+ if ((Random() % 3) == 0)
+ {
+ int i;
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ if (GetMonData(&party[i], MON_DATA_SPECIES, 0))
+ {
+ u8 pokerus = GetMonData(&party[i], MON_DATA_POKERUS, 0);
+ u8 curPokerus = pokerus;
+ if (pokerus)
+ {
+ if (pokerus & 0xF)
+ {
+ // spread to adjacent party members
+ if (i != 0 && !(GetMonData(&party[i - 1], MON_DATA_POKERUS, 0) & 0xF0))
+ SetMonData(&party[i - 1], MON_DATA_POKERUS, &curPokerus);
+ if (i != (PARTY_SIZE - 1) && !(GetMonData(&party[i + 1], MON_DATA_POKERUS, 0) & 0xF0))
+ {
+ SetMonData(&party[i + 1], MON_DATA_POKERUS, &curPokerus);
+ i++;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+bool8 TryIncrementMonLevel(struct Pokemon *mon)
+{
+ u16 species = GetMonData(mon, MON_DATA_SPECIES, 0);
+ u8 nextLevel = GetMonData(mon, MON_DATA_LEVEL, 0) + 1;
+ u32 expPoints = GetMonData(mon, MON_DATA_EXP, 0);
+ if (expPoints > gExperienceTables[gBaseStats[species].growthRate][MAX_MON_LEVEL])
+ {
+ expPoints = gExperienceTables[gBaseStats[species].growthRate][MAX_MON_LEVEL];
+ SetMonData(mon, MON_DATA_EXP, &expPoints);
+ }
+ if (nextLevel > MAX_MON_LEVEL || expPoints < gExperienceTables[gBaseStats[species].growthRate][nextLevel])
+ {
+ return FALSE;
+ }
+ else
+ {
+ SetMonData(mon, MON_DATA_LEVEL, &nextLevel);
+ return TRUE;
+ }
+}
+
+u32 CanMonLearnTMHM(struct Pokemon *mon, u8 tm)
+{
+ u16 species = GetMonData(mon, MON_DATA_SPECIES2, 0);
+ if (species == SPECIES_EGG)
+ {
+ return 0;
+ }
+ else if (tm < 32)
+ {
+ u32 mask = 1 << tm;
+ return gTMHMLearnsets[species][0] & mask;
+ }
+ else
+ {
+ u32 mask = 1 << (tm - 32);
+ return gTMHMLearnsets[species][1] & mask;
+ }
+}
+
+u32 CanSpeciesLearnTMHM(u16 species, u8 tm)
+{
+ if (species == SPECIES_EGG)
+ {
+ return 0;
+ }
+ else if (tm < 32)
+ {
+ u32 mask = 1 << tm;
+ return gTMHMLearnsets[species][0] & mask;
+ }
+ else
+ {
+ u32 mask = 1 << (tm - 32);
+ return gTMHMLearnsets[species][1] & mask;
+ }
+}
+
+u8 GetMoveRelearnerMoves(struct Pokemon *mon, u16 *moves)
+{
+ u16 learnedMoves[4];
+ u8 numMoves = 0;
+ u16 species = GetMonData(mon, MON_DATA_SPECIES, 0);
+ u8 level = GetMonData(mon, MON_DATA_LEVEL, 0);
+ int i, j, k;
+
+ for (i = 0; i < 4; i++)
+ learnedMoves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, 0);
+
+ for (i = 0; i < 20; i++)
+ {
+ u16 moveLevel;
+
+ if (gLevelUpLearnsets[species][i] == 0xFFFF)
+ break;
+
+ moveLevel = gLevelUpLearnsets[species][i] & 0xFE00;
+
+ if (moveLevel <= (level << 9))
+ {
+ for (j = 0; j < 4 && learnedMoves[j] != (gLevelUpLearnsets[species][i] & 0x1FF); j++)
+ ;
+
+ if (j == 4)
+ {
+ for (k = 0; k < numMoves && moves[k] != (gLevelUpLearnsets[species][i] & 0x1FF); k++)
+ ;
+
+ if (k == numMoves)
+ moves[numMoves++] = gLevelUpLearnsets[species][i] & 0x1FF;
+ }
+ }
+ }
+
+ return numMoves;
+}
+
+u8 GetLevelUpMovesBySpecies(u16 species, u16 *moves)
+{
+ u8 numMoves = 0;
+ int i;
+
+ for (i = 0; i < 20 && gLevelUpLearnsets[species][i] != 0xFFFF; i++)
+ moves[numMoves++] = gLevelUpLearnsets[species][i] & 0x1FF;
+
+ return numMoves;
+}
+
+u8 GetNumberOfRelearnableMoves(struct Pokemon *mon)
+{
+ u16 learnedMoves[4];
+ u16 moves[20];
+ u8 numMoves = 0;
+ u16 species = GetMonData(mon, MON_DATA_SPECIES2, 0);
+ u8 level = GetMonData(mon, MON_DATA_LEVEL, 0);
+ int i, j, k;
+
+ if (species == SPECIES_EGG)
+ return 0;
+
+ for (i = 0; i < 4; i++)
+ learnedMoves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, 0);
+
+ for (i = 0; i < 20; i++)
+ {
+ u16 moveLevel;
+
+ if (gLevelUpLearnsets[species][i] == 0xFFFF)
+ break;
+
+ moveLevel = gLevelUpLearnsets[species][i] & 0xFE00;
+
+ if (moveLevel <= (level << 9))
+ {
+ for (j = 0; j < 4 && learnedMoves[j] != (gLevelUpLearnsets[species][i] & 0x1FF); j++)
+ ;
+
+ if (j == 4)
+ {
+ for (k = 0; k < numMoves && moves[k] != (gLevelUpLearnsets[species][i] & 0x1FF); k++)
+ ;
+
+ if (k == numMoves)
+ moves[numMoves++] = gLevelUpLearnsets[species][i] & 0x1FF;
+ }
+ }
+ }
+
+ return numMoves;
+}
+
+u16 SpeciesToPokedexNum(u16 species)
+{
+ if (IsNationalPokedexEnabled())
+ {
+ return SpeciesToNationalPokedexNum(species);
+ }
+ else
+ {
+ species = SpeciesToHoennPokedexNum(species);
+ if (species <= 202)
+ return species;
+ return 0xFFFF;
+ }
+}
+
+bool32 sub_806E3F8(u16 species)
+{
+ if (SpeciesToHoennPokedexNum(species) > 202)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+void ClearBattleMonForms(void)
+{
+ int i;
+ for (i = 0; i < MAX_BATTLERS_COUNT; i++)
+ gBattleMonForms[i] = 0;
+}
+
+u16 GetBattleBGM(void)
+{
+ if (gBattleTypeFlags & BATTLE_TYPE_KYOGRE_GROUDON)
+ return MUS_BATTLE34;
+ if (gBattleTypeFlags & BATTLE_TYPE_REGI)
+ return MUS_BATTLE36;
+ if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000))
+ return MUS_BATTLE20;
+ if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
+ {
+ u8 trainerClass;
+
+ if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
+ trainerClass = GetFrontierOpponentClass(gTrainerBattleOpponent_A);
+ else if (gBattleTypeFlags & BATTLE_TYPE_x4000000)
+ trainerClass = TRAINER_CLASS_EXPERT;
+ else
+ trainerClass = gTrainers[gTrainerBattleOpponent_A].trainerClass;
+
+ switch (trainerClass)
+ {
+ case TRAINER_CLASS_AQUA_LEADER:
+ case TRAINER_CLASS_MAGMA_LEADER:
+ return MUS_BATTLE30;
+ case TRAINER_CLASS_TEAM_AQUA:
+ case TRAINER_CLASS_TEAM_MAGMA:
+ case TRAINER_CLASS_AQUA_ADMIN:
+ case TRAINER_CLASS_MAGMA_ADMIN:
+ return MUS_BATTLE31;
+ case TRAINER_CLASS_LEADER:
+ return MUS_BATTLE32;
+ case TRAINER_CLASS_CHAMPION:
+ return MUS_BATTLE33;
+ case TRAINER_CLASS_PKMN_TRAINER_3:
+ if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
+ return MUS_BATTLE35;
+ if (!StringCompare(gTrainers[gTrainerBattleOpponent_A].trainerName, gText_BattleWallyName))
+ return MUS_BATTLE20;
+ return MUS_BATTLE35;
+ case TRAINER_CLASS_ELITE_FOUR:
+ return MUS_BATTLE38;
+ case TRAINER_CLASS_SALON_MAIDEN:
+ case TRAINER_CLASS_DOME_ACE:
+ case TRAINER_CLASS_PALACE_MAVEN:
+ case TRAINER_CLASS_ARENA_TYCOON:
+ case TRAINER_CLASS_FACTORY_HEAD:
+ case TRAINER_CLASS_PIKE_QUEEN:
+ case TRAINER_CLASS_PYRAMID_KING:
+ return MUS_VS_FRONT;
+ default:
+ return MUS_BATTLE20;
+ }
+ }
+ return MUS_BATTLE27;
+}
+
+void PlayBattleBGM(void)
+{
+ ResetMapMusic();
+ m4aMPlayAllStop();
+ PlayBGM(GetBattleBGM());
+}
+
+void PlayMapChosenOrBattleBGM(u16 songId)
+{
+ ResetMapMusic();
+ m4aMPlayAllStop();
+ if (songId)
+ PlayNewMapMusic(songId);
+ else
+ PlayNewMapMusic(GetBattleBGM());
+}
+
+void sub_806E694(u16 songId)
+{
+ u8 taskId;
+
+ ResetMapMusic();
+ m4aMPlayAllStop();
+
+ taskId = CreateTask(sub_806E6CC, 0);
+ gTasks[taskId].data[0] = songId;
+}
+
+static void sub_806E6CC(u8 taskId)
+{
+ if (gTasks[taskId].data[0])
+ PlayNewMapMusic(gTasks[taskId].data[0]);
+ else
+ PlayNewMapMusic(GetBattleBGM());
+ DestroyTask(taskId);
+}
+
+const u8 *GetMonFrontSpritePal(struct Pokemon *mon)
+{
+ u16 species = GetMonData(mon, MON_DATA_SPECIES2, 0);
+ u32 otId = GetMonData(mon, MON_DATA_OT_ID, 0);
+ u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0);
+ return GetFrontSpritePalFromSpeciesAndPersonality(species, otId, personality);
+}
+
+// Extracts the upper 16 bits of a 32-bit number
+#define HIHALF(n) (((n) & 0xFFFF0000) >> 16)
+
+// Extracts the lower 16 bits of a 32-bit number
+#define LOHALF(n) ((n) & 0xFFFF)
+
+const u8 *GetFrontSpritePalFromSpeciesAndPersonality(u16 species, u32 otId, u32 personality)
+{
+ u32 shinyValue;
+
+ if (species > SPECIES_EGG)
+ return gMonPaletteTable[0].data;
+
+ shinyValue = HIHALF(otId) ^ LOHALF(otId) ^ HIHALF(personality) ^ LOHALF(personality);
+ if (shinyValue < 8)
+ return gMonShinyPaletteTable[species].data;
+ else
+ return gMonPaletteTable[species].data;
+}
+
+const struct CompressedSpritePalette *GetMonSpritePalStruct(struct Pokemon *mon)
+{
+ u16 species = GetMonData(mon, MON_DATA_SPECIES2, 0);
+ u32 otId = GetMonData(mon, MON_DATA_OT_ID, 0);
+ u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0);
+ return GetMonSpritePalStructFromOtIdPersonality(species, otId, personality);
+}
+
+const struct CompressedSpritePalette *GetMonSpritePalStructFromOtIdPersonality(u16 species, u32 otId , u32 personality)
+{
+ u32 shinyValue;
+
+ shinyValue = HIHALF(otId) ^ LOHALF(otId) ^ HIHALF(personality) ^ LOHALF(personality);
+ if (shinyValue < 8)
+ return &gMonShinyPaletteTable[species];
+ else
+ return &gMonPaletteTable[species];
+}
+
+bool32 IsHMMove2(u16 move)
+{
+ int i = 0;
+ while (sHMMoves[i] != 0xFFFF)
+ {
+ if (sHMMoves[i++] == move)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 IsMonSpriteNotFlipped(u16 species)
+{
+ return gBaseStats[species].noFlip;
+}
+
+s8 GetMonFlavorRelation(struct Pokemon *mon, u8 flavor)
+{
+ u8 nature = GetNature(mon);
+ return gPokeblockFlavorCompatibilityTable[nature * 5 + flavor];
+}
+
+s8 GetFlavorRelationByPersonality(u32 personality, u8 flavor)
+{
+ u8 nature = GetNatureFromPersonality(personality);
+ return gPokeblockFlavorCompatibilityTable[nature * 5 + flavor];
+}
+
+bool8 IsTradedMon(struct Pokemon *mon)
+{
+ u8 otName[OT_NAME_LENGTH + 1];
+ u32 otId;
+ GetMonData(mon, MON_DATA_OT_NAME, otName);
+ otId = GetMonData(mon, MON_DATA_OT_ID, 0);
+ return IsOtherTrainer(otId, otName);
+}
+
+bool8 IsOtherTrainer(u32 otId, u8 *otName)
+{
+ if (otId ==
+ (gSaveBlock2Ptr->playerTrainerId[0]
+ | (gSaveBlock2Ptr->playerTrainerId[1] << 8)
+ | (gSaveBlock2Ptr->playerTrainerId[2] << 16)
+ | (gSaveBlock2Ptr->playerTrainerId[3] << 24)))
+ {
+ int i;
+
+ for (i = 0; otName[i] != EOS; i++)
+ if (otName[i] != gSaveBlock2Ptr->playerName[i])
+ return TRUE;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void MonRestorePP(struct Pokemon *mon)
+{
+ BoxMonRestorePP(&mon->box);
+}
+
+void BoxMonRestorePP(struct BoxPokemon *boxMon)
+{
+ int i;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (GetBoxMonData(boxMon, MON_DATA_MOVE1 + i, 0))
+ {
+ u16 move = GetBoxMonData(boxMon, MON_DATA_MOVE1 + i, 0);
+ u16 bonus = GetBoxMonData(boxMon, MON_DATA_PP_BONUSES, 0);
+ u8 pp = CalculatePPWithBonus(move, bonus, i);
+ SetBoxMonData(boxMon, MON_DATA_PP1 + i, &pp);
+ }
+ }
+}
+
+void sub_806E994(void)
+{
+ gLastUsedAbility = gBattleStruct->field_B0;
+
+ gBattleTextBuff1[0] = B_BUFF_PLACEHOLDER_BEGIN;
+ gBattleTextBuff1[1] = B_BUFF_MON_NICK_WITH_PREFIX;
+ gBattleTextBuff1[2] = gBattleStruct->field_49;
+ gBattleTextBuff1[4] = B_BUFF_EOS;
+
+ if (!GetBattlerSide(gBattleStruct->field_49))
+ gBattleTextBuff1[3] = pokemon_order_func(gBattlerPartyIndexes[gBattleStruct->field_49]);
+ else
+ gBattleTextBuff1[3] = gBattlerPartyIndexes[gBattleStruct->field_49];
+
+ PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff2, gBattlerInMenuId, pokemon_order_func(gBattlerPartyIndexes[gBattlerInMenuId]))
+
+ BattleStringExpandPlaceholders(gText_PkmnsXPreventsSwitching, gStringVar4);
+}
+
+static s32 GetWildMonTableIdInAlteringCave(u16 species)
+{
+ s32 i;
+ for (i = 0; i < (s32) ARRAY_COUNT(sAlteringCaveWildMonHeldItems); i++)
+ if (sAlteringCaveWildMonHeldItems[i].species == species)
+ return i;
+ return 0;
+}
+
+void SetWildMonHeldItem(void)
+{
+ if (!(gBattleTypeFlags & (BATTLE_TYPE_LEGENDARY | BATTLE_TYPE_TRAINER | BATTLE_TYPE_PYRAMID | BATTLE_TYPE_PIKE)))
+ {
+ u16 rnd = Random() % 100;
+ u16 species = GetMonData(&gEnemyParty[0], MON_DATA_SPECIES, 0);
+ u16 var1 = 45;
+ u16 var2 = 95;
+ if (!GetMonData(&gPlayerParty[0], MON_DATA_SANITY_BIT3, 0)
+ && GetMonAbility(&gPlayerParty[0]) == ABILITY_COMPOUND_EYES)
+ {
+ var1 = 20;
+ var2 = 80;
+ }
+ if (gMapHeader.mapDataId == 0x1A4)
+ {
+ s32 alteringCaveId = GetWildMonTableIdInAlteringCave(species);
+ if (alteringCaveId != 0)
+ {
+ if (rnd < var2)
+ return;
+ SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &sAlteringCaveWildMonHeldItems[alteringCaveId].item);
+ }
+ else
+ {
+ if (rnd < var1)
+ return;
+ if (rnd < var2)
+ SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gBaseStats[species].item1);
+ else
+ SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gBaseStats[species].item2);
+ }
+ }
+ else
+ {
+ if (gBaseStats[species].item1 == gBaseStats[species].item2 && gBaseStats[species].item1 != 0)
+ {
+ SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gBaseStats[species].item1);
+ }
+ else
+ {
+ if (rnd < var1)
+ return;
+ if (rnd < var2)
+ SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gBaseStats[species].item1);
+ else
+ SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gBaseStats[species].item2);
+ }
+ }
+ }
+}
+
+bool8 IsMonShiny(struct Pokemon *mon)
+{
+ u32 otId = GetMonData(mon, MON_DATA_OT_ID, 0);
+ u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0);
+ return IsShinyOtIdPersonality(otId, personality);
+}
+
+bool8 IsShinyOtIdPersonality(u32 otId, u32 personality)
+{
+ bool8 retVal = FALSE;
+ u32 shinyValue = HIHALF(otId) ^ LOHALF(otId) ^ HIHALF(personality) ^ LOHALF(personality);
+ if (shinyValue < 8)
+ retVal = TRUE;
+ return retVal;
+}
+
+const u8 *GetTrainerPartnerName(void)
+{
+ if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
+ {
+ if (gPartnerTrainerId == STEVEN_PARTNER_ID)
+ {
+ return gTrainers[TRAINER_STEVEN].trainerName;
+ }
+ else
+ {
+ GetFrontierTrainerName(gStringVar1, gPartnerTrainerId);
+ return gStringVar1;
+ }
+ }
+ else
+ {
+ u8 id = GetMultiplayerId();
+ return gLinkPlayers[GetBattlerMultiplayerId(gLinkPlayers[id].lp_field_18 ^ 2)].name;
+ }
+}
+
+#define READ_PTR_FROM_TASK(taskId, dataId) \
+ (void*)( \
+ ((u16)(gTasks[taskId].data[dataId]) | \
+ ((u16)(gTasks[taskId].data[dataId + 1]) << 0x10)))
+
+#define STORE_PTR_IN_TASK(ptr, taskId, dataId) \
+{ \
+ gTasks[taskId].data[dataId] = (u32)(ptr); \
+ gTasks[taskId].data[dataId + 1] = (u32)(ptr) >> 0x10; \
+}
+
+static void Task_AnimateAfterDelay(u8 taskId)
+{
+ if (--gTasks[taskId].data[3] == 0)
+ {
+ LaunchAnimationTaskForFrontSprite(READ_PTR_FROM_TASK(taskId, 0), gTasks[taskId].data[2]);
+ DestroyTask(taskId);
+ }
+}
+
+static void Task_PokemonSummaryAnimateAfterDelay(u8 taskId)
+{
+ if (--gTasks[taskId].data[3] == 0)
+ {
+ StartMonSummaryAnimation(READ_PTR_FROM_TASK(taskId, 0), gTasks[taskId].data[2]);
+ sub_81C488C(0xFF);
+ DestroyTask(taskId);
+ }
+}
+
+void BattleAnimateFrontSprite(struct Sprite* sprite, u16 species, bool8 noCry, u8 arg3)
+{
+ if (gHitMarker & HITMARKER_NO_ANIMATIONS && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000)))
+ DoMonFrontSpriteAnimation(sprite, species, noCry, arg3 | 0x80);
+ else
+ DoMonFrontSpriteAnimation(sprite, species, noCry, arg3);
+}
+
+void DoMonFrontSpriteAnimation(struct Sprite* sprite, u16 species, bool8 noCry, u8 arg3)
+{
+ s8 pan;
+ switch (arg3 & 0x7F)
+ {
+ case 0:
+ pan = -25;
+ break;
+ case 1:
+ pan = 25;
+ break;
+ default:
+ pan = 0;
+ break;
+ }
+ if (arg3 & 0x80)
+ {
+ if (!noCry)
+ PlayCry1(species, pan);
+ sprite->callback = SpriteCallbackDummy;
+ }
+ else
+ {
+ if (!noCry)
+ {
+ PlayCry1(species, pan);
+ if (HasTwoFramesAnimation(species))
+ StartSpriteAnim(sprite, 1);
+ }
+ if (sMonAnimationDelayTable[species - 1] != 0)
+ {
+ u8 taskId = CreateTask(Task_AnimateAfterDelay, 0);
+ STORE_PTR_IN_TASK(sprite, taskId, 0);
+ gTasks[taskId].data[2] = sMonFrontAnimIdsTable[species - 1];
+ gTasks[taskId].data[3] = sMonAnimationDelayTable[species - 1];
+ }
+ else
+ {
+ LaunchAnimationTaskForFrontSprite(sprite, sMonFrontAnimIdsTable[species - 1]);
+ }
+ sprite->callback = SpriteCallbackDummy_2;
+ }
+}
+
+void PokemonSummaryDoMonAnimation(struct Sprite* sprite, u16 species, bool8 oneFrame)
+{
+ if (!oneFrame && HasTwoFramesAnimation(species))
+ StartSpriteAnim(sprite, 1);
+ if (sMonAnimationDelayTable[species - 1] != 0)
+ {
+ u8 taskId = CreateTask(Task_PokemonSummaryAnimateAfterDelay, 0);
+ STORE_PTR_IN_TASK(sprite, taskId, 0);
+ gTasks[taskId].data[2] = sMonFrontAnimIdsTable[species - 1];
+ gTasks[taskId].data[3] = sMonAnimationDelayTable[species - 1];
+ sub_81C488C(taskId);
+ SetSpriteCB_MonAnimDummy(sprite);
+ }
+ else
+ {
+ StartMonSummaryAnimation(sprite, sMonFrontAnimIdsTable[species - 1]);
+ }
+}
+
+void sub_806EE98(void)
+{
+ u8 delayTaskId = FindTaskIdByFunc(Task_PokemonSummaryAnimateAfterDelay);
+ if (delayTaskId != 0xFF)
+ DestroyTask(delayTaskId);
+}
+
+void BattleAnimateBackSprite(struct Sprite* sprite, u16 species)
+{
+ if (gHitMarker & HITMARKER_NO_ANIMATIONS && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000)))
+ {
+ sprite->callback = SpriteCallbackDummy;
+ }
+ else
+ {
+ LaunchAnimationTaskForBackSprite(sprite, GetSpeciesBackAnimSet(species));
+ sprite->callback = SpriteCallbackDummy_2;
+ }
+}
+
+u8 sub_806EF08(u8 arg0)
+{
+ s32 i;
+ s32 var = 0;
+ u8 multiplayerId = GetMultiplayerId();
+ switch (gLinkPlayers[multiplayerId].lp_field_18)
+ {
+ case 0:
+ case 2:
+ var = (arg0 != 0) ? 1 : 3;
+ break;
+ case 1:
+ case 3:
+ var = (arg0 != 0) ? 2 : 0;
+ break;
+ }
+ for (i = 0; i < 4; i++)
+ {
+ if (gLinkPlayers[i].lp_field_18 == (s16)(var))
+ break;
+ }
+ return i;
+}
+
+u8 sub_806EF84(u8 arg0, u8 arg1)
+{
+ s32 i;
+ s32 var = 0;
+ switch (gLinkPlayers[arg1].lp_field_18)
+ {
+ case 0:
+ case 2:
+ var = (arg0 != 0) ? 1 : 3;
+ break;
+ case 1:
+ case 3:
+ var = (arg0 != 0) ? 2 : 0;
+ break;
+ }
+ for (i = 0; i < 4; i++)
+ {
+ if (gLinkPlayers[i].lp_field_18 == (s16)(var))
+ break;
+ }
+ return i;
+}
+
+u16 FacilityClassToPicIndex(u16 facilityClass)
+{
+ return gFacilityClassToPicIndex[facilityClass];
+}
+
+u16 PlayerGenderToFrontTrainerPicId(u8 playerGender)
+{
+ if (playerGender != MALE)
+ return FacilityClassToPicIndex(FACILITY_CLASS_PKMN_TRAINER_BRENDAN);
+ else
+ return FacilityClassToPicIndex(FACILITY_CLASS_PKMN_TRAINER_MAY);
+}
+
+void HandleSetPokedexFlag(u16 nationalNum, u8 caseId, u32 personality)
+{
+ u8 getFlagCaseId = (caseId == FLAG_SET_SEEN) ? FLAG_GET_SEEN : FLAG_GET_CAUGHT;
+ if (!GetSetPokedexFlag(nationalNum, getFlagCaseId)) // don't set if it's already set
+ {
+ GetSetPokedexFlag(nationalNum, caseId);
+ if (NationalPokedexNumToSpecies(nationalNum) == SPECIES_UNOWN)
+ gSaveBlock2Ptr->pokedex.unownPersonality = personality;
+ if (NationalPokedexNumToSpecies(nationalNum) == SPECIES_SPINDA)
+ gSaveBlock2Ptr->pokedex.spindaPersonality = personality;
+ }
+}
+
+const u8 *GetTrainerClassNameFromId(u16 trainerId)
+{
+ if (trainerId > NO_OF_TRAINERS)
+ trainerId = 0;
+ return gTrainerClassNames[gTrainers[trainerId].trainerClass];
+}
+
+const u8 *GetTrainerNameFromId(u16 trainerId)
+{
+ if (trainerId > NO_OF_TRAINERS)
+ trainerId = 0;
+ return gTrainers[trainerId].trainerName;
+}
+
+bool8 HasTwoFramesAnimation(u16 species)
+{
+ return (species != SPECIES_CASTFORM
+ && species != SPECIES_DEOXYS
+ && species != SPECIES_SPINDA
+ && species != SPECIES_UNOWN);
+}
+
+bool8 sub_806F104(void)
+{
+ if (gMain.inBattle && gBattleTypeFlags & (BATTLE_TYPE_FRONTIER))
+ return TRUE;
+ if (!gMain.inBattle && (InBattlePike() || InBattlePyramid()))
+ return TRUE;
+ return FALSE;
+}
+
+#define FORCE_SIGNED(x)(-(x * (-1)))
+
+static void sub_806F160(struct Unknown_806F160_Struct* structPtr)
+{
+ u16 i, j;
+ for (i = 0; i < FORCE_SIGNED(structPtr->field_0_0); i++)
+ {
+ structPtr->templates[i] = gUnknown_08329D98[i];
+ for (j = 0; j < structPtr->field_1; j++)
+ {
+ asm("");
+ structPtr->frameImages[i * structPtr->field_1 + j].data = &structPtr->byteArrays[i][j * 0x800];
+ }
+ structPtr->templates[i].images = &structPtr->frameImages[i * structPtr->field_1];
+ }
+}
+
+static void sub_806F1FC(struct Unknown_806F160_Struct* structPtr)
+{
+ u16 i, j;
+ for (i = 0; i < FORCE_SIGNED(structPtr->field_0_0); i++)
+ {
+ structPtr->templates[i] = gUnknown_08329F28;
+ for (j = 0; j < structPtr->field_1; j++)
+ {
+ structPtr->frameImages[i * structPtr->field_0_0 + j].data = &structPtr->byteArrays[i][j * 0x800];
+ }
+ structPtr->templates[i].images = &structPtr->frameImages[i * structPtr->field_0_0];
+ structPtr->templates[i].anims = gUnknown_082FF70C;
+ structPtr->templates[i].paletteTag = i;
+ }
+}
+
+struct Unknown_806F160_Struct *sub_806F2AC(u8 id, u8 arg1)
+{
+ u8 i;
+ u8 flags;
+ struct Unknown_806F160_Struct *structPtr;
+
+ flags = 0;
+ id %= 2;
+ structPtr = AllocZeroed(sizeof(*structPtr));
+ if (structPtr == NULL)
+ return NULL;
+
+ switch (arg1)
+ {
+ case 2:
+ structPtr->field_0_0 = 7;
+ structPtr->field_0_1 = 7;
+ structPtr->field_1 = 4;
+ structPtr->field_3_0 = 1;
+ structPtr->field_3_1 = 2;
+ break;
+ case 0:
+ default:
+ structPtr->field_0_0 = 4;
+ structPtr->field_0_1 = 4;
+ structPtr->field_1 = 4;
+ structPtr->field_3_0 = 1;
+ structPtr->field_3_1 = 0;
+ break;
+ }
+
+ structPtr->bytes = AllocZeroed(structPtr->field_3_0 * 0x800 * 4 * structPtr->field_0_0);
+ structPtr->byteArrays = AllocZeroed(structPtr->field_0_0 * 32);
+ if (structPtr->bytes == NULL || structPtr->byteArrays == NULL)
+ {
+ flags |= 1;
+ }
+ else
+ {
+ for (i = 0; i < FORCE_SIGNED(structPtr->field_0_0); i++)
+ structPtr->byteArrays[i] = structPtr->bytes + (structPtr->field_3_0 * (i << 0xD));
+ }
+
+ structPtr->templates = AllocZeroed(sizeof(struct SpriteTemplate) * structPtr->field_0_0);
+ structPtr->frameImages = AllocZeroed(sizeof(struct SpriteFrameImage) * structPtr->field_0_0 * structPtr->field_1);
+ if (structPtr->templates == NULL || structPtr->frameImages == NULL)
+ {
+ flags |= 2;
+ }
+ else
+ {
+ for (i = 0; i < structPtr->field_1 * structPtr->field_0_0; i++)
+ structPtr->frameImages[i].size = 0x800;
+
+ switch (structPtr->field_3_1)
+ {
+ case 2:
+ sub_806F1FC(structPtr);
+ break;
+ case 0:
+ case 1:
+ default:
+ sub_806F160(structPtr);
+ break;
+ }
+ }
+
+ if (flags & 2)
+ {
+ if (structPtr->frameImages != NULL)
+ FREE_AND_SET_NULL(structPtr->frameImages);
+ if (structPtr->templates != NULL)
+ FREE_AND_SET_NULL(structPtr->templates);
+ }
+ if (flags & 1)
+ {
+ if (structPtr->byteArrays != NULL)
+ FREE_AND_SET_NULL(structPtr->byteArrays);
+ if (structPtr->bytes != NULL)
+ FREE_AND_SET_NULL(structPtr->bytes);
+ }
+
+ if (flags)
+ {
+ memset(structPtr, 0, sizeof(*structPtr));
+ Free(structPtr);
+ }
+ else
+ {
+ structPtr->magic = 0xA3;
+ gUnknown_020249B4[id] = structPtr;
+ }
+
+ return gUnknown_020249B4[id];
+}
+
+void sub_806F47C(u8 id)
+{
+ struct Unknown_806F160_Struct *structPtr;
+
+ id %= 2;
+ structPtr = gUnknown_020249B4[id];
+ if (structPtr == NULL)
+ return;
+
+ if (structPtr->magic != 0xA3)
+ {
+ memset(structPtr, 0, sizeof(struct Unknown_806F160_Struct));
+ }
+ else
+ {
+
+ if (structPtr->frameImages != NULL)
+ FREE_AND_SET_NULL(structPtr->frameImages);
+ if (structPtr->templates != NULL)
+ FREE_AND_SET_NULL(structPtr->templates);
+ if (structPtr->byteArrays != NULL)
+ FREE_AND_SET_NULL(structPtr->byteArrays);
+ if (structPtr->bytes != NULL)
+ FREE_AND_SET_NULL(structPtr->bytes);
+
+ memset(structPtr, 0, sizeof(struct Unknown_806F160_Struct));
+ Free(structPtr);
+ }
+}
+
+u8 *sub_806F4F8(u8 id, u8 arg1)
+{
+ struct Unknown_806F160_Struct *structPtr = gUnknown_020249B4[id % 2];
+ if (structPtr->magic != 0xA3)
+ {
+ return NULL;
+ }
+ else
+ {
+ if (arg1 >= FORCE_SIGNED(structPtr->field_0_0))
+ arg1 = 0;
+
+ return structPtr->byteArrays[arg1];
+ }
+}
diff --git a/src/pokemon_1.c b/src/pokemon_1.c
deleted file mode 100644
index cafd86c07..000000000
--- a/src/pokemon_1.c
+++ /dev/null
@@ -1,457 +0,0 @@
-#include "global.h"
-#include "pokemon.h"
-#include "random.h"
-#include "main.h"
-#include "constants/species.h"
-#include "constants/abilities.h"
-#include "constants/items.h"
-#include "constants/trainers.h"
-#include "constants/moves.h"
-#include "string_util.h"
-#include "text.h"
-
-//Extracts the upper 16 bits of a 32-bit number
-#define HIHALF(n) (((n) & 0xFFFF0000) >> 16)
-
-//Extracts the lower 16 bits of a 32-bit number
-#define LOHALF(n) ((n) & 0xFFFF)
-
-extern u8 sav1_map_get_name(void);
-
-// EWRAM vars
-EWRAM_DATA u8 sLearningMoveTableID = 0;
-EWRAM_DATA u8 gPlayerPartyCount = 0;
-EWRAM_DATA u8 gEnemyPartyCount = 0;
-EWRAM_DATA struct Pokemon gPlayerParty[PARTY_SIZE] = {0};
-EWRAM_DATA struct Pokemon gEnemyParty[PARTY_SIZE] = {0};
-
-// const rom data
-const u16 gSpeciesToHoennPokedexNum[] = {203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 156, 157, 112, 113, 227, 228, 229, 230, 231, 232, 233, 234, 153, 154, 138, 139, 63, 64, 88, 89, 90, 235, 236, 237, 238, 239, 240, 241, 242, 158, 159, 243, 244, 245, 246, 247, 248, 249, 39, 40, 41, 73, 74, 75, 250, 251, 252, 66, 67, 57, 58, 59, 253, 254, 255, 256, 82, 83, 257, 92, 93, 258, 259, 106, 107, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 84, 85, 270, 271, 272, 273, 274, 275, 276, 108, 109, 169, 170, 277, 278, 279, 184, 185, 50, 51, 143, 144, 280, 281, 282, 283, 284, 167, 285, 52, 53, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 65, 181, 182, 155, 324, 137, 325, 326, 162, 163, 327, 328, 329, 91, 55, 56, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 161, 164, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 168, 357, 358, 359, 103, 104, 360, 361, 180, 362, 363, 364, 365, 115, 366, 367, 186, 165, 166, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 42, 43, 44, 25, 26, 34, 35, 114, 27, 28, 32, 33, 99, 100, 61, 62, 145, 131, 132, 60, 105, 68, 127, 128, 183, 129, 130, 140, 141, 97, 98, 116, 117, 118, 48, 49, 78, 79, 101, 102, 173, 174, 175, 119, 120, 171, 172, 125, 126, 54, 110, 111, 80, 81, 69, 76, 77, 121, 122, 160, 148, 149, 94, 36, 37, 38, 95, 96, 150, 45, 46, 47, 176, 177, 178, 152, 146, 147, 124, 123, 179, 70, 71, 72, 142, 86, 87, 133, 134, 135, 136, 29, 30, 31, 187, 188, 189, 190, 191, 192, 193, 194, 195, 198, 199, 200, 196, 197, 201, 202, 151};
-const u16 gSpeciesToNationalPokedexNum[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 290, 291, 292, 276, 277, 285, 286, 327, 278, 279, 283, 284, 320, 321, 300, 301, 352, 343, 344, 299, 324, 302, 339, 340, 370, 341, 342, 349, 350, 318, 319, 328, 329, 330, 296, 297, 309, 310, 322, 323, 363, 364, 365, 331, 332, 361, 362, 337, 338, 298, 325, 326, 311, 312, 303, 307, 308, 333, 334, 360, 355, 356, 315, 287, 288, 289, 316, 317, 357, 293, 294, 295, 366, 367, 368, 359, 353, 354, 336, 335, 369, 304, 305, 306, 351, 313, 314, 345, 346, 347, 348, 280, 281, 282, 371, 372, 373, 374, 375, 376, 377, 378, 379, 382, 383, 384, 380, 381, 385, 386, 358};
-const u16 gHoennToNationalOrder[] = {252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 63, 64, 65, 290, 291, 292, 293, 294, 295, 296, 297, 118, 119, 129, 130, 298, 183, 184, 74, 75, 76, 299, 300, 301, 41, 42, 169, 72, 73, 302, 303, 304, 305, 306, 66, 67, 68, 307, 308, 309, 310, 311, 312, 81, 82, 100, 101, 313, 314, 43, 44, 45, 182, 84, 85, 315, 316, 317, 318, 319, 320, 321, 322, 323, 218, 219, 324, 88, 89, 109, 110, 325, 326, 27, 28, 327, 227, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 174, 39, 40, 349, 350, 351, 120, 121, 352, 353, 354, 355, 356, 357, 358, 359, 37, 38, 172, 25, 26, 54, 55, 360, 202, 177, 178, 203, 231, 232, 127, 214, 111, 112, 361, 362, 363, 364, 365, 366, 367, 368, 369, 222, 170, 171, 370, 116, 117, 230, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 34, 35, 36, 46, 47, 48, 49, 50, 51, 52, 53, 56, 57, 58, 59, 60, 61, 62, 69, 70, 71, 77, 78, 79, 80, 83, 86, 87, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 102, 103, 104, 105, 106, 107, 108, 113, 114, 115, 122, 123, 124, 125, 126, 128, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 173, 175, 176, 179, 180, 181, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 215, 216, 217, 220, 221, 223, 224, 225, 226, 228, 229, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411};
-
-const struct SpindaSpot gSpindaSpotGraphics[] =
-{
- {16, 7, INCBIN_U16("graphics/spinda_spots/spot_0.bin")},
- {40, 8, INCBIN_U16("graphics/spinda_spots/spot_1.bin")},
- {22, 25, INCBIN_U16("graphics/spinda_spots/spot_2.bin")},
- {34, 26, INCBIN_U16("graphics/spinda_spots/spot_3.bin")}
-};
-
-#include "data/pokemon/item_effects.h"
-
-const s8 gNatureStatTable[][5] =
-{
- // Atk Def Spd Sp.Atk Sp.Def
- { 0, 0, 0, 0, 0}, // Hardy
- { +1, -1, 0, 0, 0}, // Lonely
- { +1, 0, -1, 0, 0}, // Brave
- { +1, 0, 0, -1, 0}, // Adamant
- { +1, 0, 0, 0, -1}, // Naughty
- { -1, +1, 0, 0, 0}, // Bold
- { 0, 0, 0, 0, 0}, // Docile
- { 0, +1, -1, 0, 0}, // Relaxed
- { 0, +1, 0, -1, 0}, // Impish
- { 0, +1, 0, 0, -1}, // Lax
- { -1, 0, +1, 0, 0}, // Timid
- { 0, -1, +1, 0, 0}, // Hasty
- { 0, 0, 0, 0, 0}, // Serious
- { 0, 0, +1, -1, 0}, // Jolly
- { 0, 0, +1, 0, -1}, // Naive
- { -1, 0, 0, +1, 0}, // Modest
- { 0, -1, 0, +1, 0}, // Mild
- { 0, 0, -1, +1, 0}, // Quiet
- { 0, 0, 0, 0, 0}, // Bashful
- { 0, 0, 0, +1, -1}, // Rash
- { -1, 0, 0, 0, +1}, // Calm
- { 0, -1, 0, 0, +1}, // Gentle
- { 0, 0, -1, 0, +1}, // Sassy
- { 0, 0, 0, -1, +1}, // Careful
- { 0, 0, 0, 0, 0}, // Quirky
-};
-
-#include "data/pokemon/tmhm_learnsets.h"
-#include "data/pokemon/trainer_class_lookups.h"
-#include "data/pokemon/cry_ids.h"
-#include "data/pokemon/experience_tables.h"
-#include "data/pokemon/base_stats.h"
-#include "data/pokemon/level_up_learnsets.h"
-#include "data/pokemon/evolution.h"
-#include "data/pokemon/level_up_learnset_pointers.h"
-
-// code
-void ZeroBoxMonData(struct BoxPokemon *boxMon)
-{
- u8 *raw = (u8 *)boxMon;
- u32 i;
- for (i = 0; i < sizeof(struct BoxPokemon); i++)
- raw[i] = 0;
-}
-
-void ZeroMonData(struct Pokemon *mon)
-{
- u32 arg;
- ZeroBoxMonData(&mon->box);
- arg = 0;
- SetMonData(mon, MON_DATA_STATUS, &arg);
- SetMonData(mon, MON_DATA_LEVEL, &arg);
- SetMonData(mon, MON_DATA_HP, &arg);
- SetMonData(mon, MON_DATA_MAX_HP, &arg);
- SetMonData(mon, MON_DATA_ATK, &arg);
- SetMonData(mon, MON_DATA_DEF, &arg);
- SetMonData(mon, MON_DATA_SPEED, &arg);
- SetMonData(mon, MON_DATA_SPATK, &arg);
- SetMonData(mon, MON_DATA_SPDEF, &arg);
- arg = 255;
- SetMonData(mon, MON_DATA_MAIL, &arg);
-}
-
-void ZeroPlayerPartyMons(void)
-{
- s32 i;
- for (i = 0; i < PARTY_SIZE; i++)
- ZeroMonData(&gPlayerParty[i]);
-}
-
-void ZeroEnemyPartyMons(void)
-{
- s32 i;
- for (i = 0; i < PARTY_SIZE; i++)
- ZeroMonData(&gEnemyParty[i]);
-}
-
-void CreateMon(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 hasFixedPersonality, u32 fixedPersonality, u8 otIdType, u32 fixedOtId)
-{
- u32 arg;
- ZeroMonData(mon);
- CreateBoxMon(&mon->box, species, level, fixedIV, hasFixedPersonality, fixedPersonality, otIdType, fixedOtId);
- SetMonData(mon, MON_DATA_LEVEL, &level);
- arg = 255;
- SetMonData(mon, MON_DATA_MAIL, &arg);
- CalculateMonStats(mon);
-}
-
-void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV, u8 hasFixedPersonality, u32 fixedPersonality, u8 otIdType, u32 fixedOtId)
-{
- u8 speciesName[POKEMON_NAME_LENGTH + 1];
- u32 personality;
- u32 value;
- u16 checksum;
-
- ZeroBoxMonData(boxMon);
-
- if (hasFixedPersonality)
- personality = fixedPersonality;
- else
- personality = Random32();
-
- SetBoxMonData(boxMon, MON_DATA_PERSONALITY, &personality);
-
- //Determine original trainer ID
- if (otIdType == OT_ID_RANDOM_NO_SHINY) //Pokemon cannot be shiny
- {
- u32 shinyValue;
- do
- {
- value = Random32();
- shinyValue = HIHALF(value) ^ LOHALF(value) ^ HIHALF(personality) ^ LOHALF(personality);
- } while (shinyValue < 8);
- }
- else if (otIdType == OT_ID_PRESET) //Pokemon has a preset OT ID
- {
- value = fixedOtId;
- }
- else //Player is the OT
- {
- value = gSaveBlock2Ptr->playerTrainerId[0]
- | (gSaveBlock2Ptr->playerTrainerId[1] << 8)
- | (gSaveBlock2Ptr->playerTrainerId[2] << 16)
- | (gSaveBlock2Ptr->playerTrainerId[3] << 24);
- }
-
- SetBoxMonData(boxMon, MON_DATA_OT_ID, &value);
-
- checksum = CalculateBoxMonChecksum(boxMon);
- SetBoxMonData(boxMon, MON_DATA_CHECKSUM, &checksum);
- EncryptBoxMon(boxMon);
- GetSpeciesName(speciesName, species);
- SetBoxMonData(boxMon, MON_DATA_NICKNAME, speciesName);
- SetBoxMonData(boxMon, MON_DATA_LANGUAGE, &gGameLanguage);
- SetBoxMonData(boxMon, MON_DATA_OT_NAME, gSaveBlock2Ptr->playerName);
- SetBoxMonData(boxMon, MON_DATA_SPECIES, &species);
- SetBoxMonData(boxMon, MON_DATA_EXP, &gExperienceTables[gBaseStats[species].growthRate][level]);
- SetBoxMonData(boxMon, MON_DATA_FRIENDSHIP, &gBaseStats[species].friendship);
- value = sav1_map_get_name();
- SetBoxMonData(boxMon, MON_DATA_MET_LOCATION, &value);
- SetBoxMonData(boxMon, MON_DATA_MET_LEVEL, &level);
- SetBoxMonData(boxMon, MON_DATA_MET_GAME, &gGameVersion);
- value = ITEM_POKE_BALL;
- SetBoxMonData(boxMon, MON_DATA_POKEBALL, &value);
- SetBoxMonData(boxMon, MON_DATA_OT_GENDER, &gSaveBlock2Ptr->playerGender);
-
- if (fixedIV < 32)
- {
- SetBoxMonData(boxMon, MON_DATA_HP_IV, &fixedIV);
- SetBoxMonData(boxMon, MON_DATA_ATK_IV, &fixedIV);
- SetBoxMonData(boxMon, MON_DATA_DEF_IV, &fixedIV);
- SetBoxMonData(boxMon, MON_DATA_SPEED_IV, &fixedIV);
- SetBoxMonData(boxMon, MON_DATA_SPATK_IV, &fixedIV);
- SetBoxMonData(boxMon, MON_DATA_SPDEF_IV, &fixedIV);
- }
- else
- {
- u32 iv;
- value = Random();
-
- iv = value & 0x1F;
- SetBoxMonData(boxMon, MON_DATA_HP_IV, &iv);
- iv = (value & 0x3E0) >> 5;
- SetBoxMonData(boxMon, MON_DATA_ATK_IV, &iv);
- iv = (value & 0x7C00) >> 10;
- SetBoxMonData(boxMon, MON_DATA_DEF_IV, &iv);
-
- value = Random();
-
- iv = value & 0x1F;
- SetBoxMonData(boxMon, MON_DATA_SPEED_IV, &iv);
- iv = (value & 0x3E0) >> 5;
- SetBoxMonData(boxMon, MON_DATA_SPATK_IV, &iv);
- iv = (value & 0x7C00) >> 10;
- SetBoxMonData(boxMon, MON_DATA_SPDEF_IV, &iv);
- }
-
- if (gBaseStats[species].ability2)
- {
- value = personality & 1;
- SetBoxMonData(boxMon, MON_DATA_ALT_ABILITY, &value);
- }
-
- GiveBoxMonInitialMoveset(boxMon);
-}
-
-void CreateMonWithNature(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 nature)
-{
- u32 personality;
-
- do
- {
- personality = Random32();
- }
- while (nature != GetNatureFromPersonality(personality));
-
- CreateMon(mon, species, level, fixedIV, 1, personality, OT_ID_PLAYER_ID, 0);
-}
-
-void CreateMonWithGenderNatureLetter(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 gender, u8 nature, u8 unownLetter)
-{
- u32 personality;
-
- if ((u8)(unownLetter - 1) < 28)
- {
- u16 actualLetter;
-
- do
- {
- personality = Random32();
- actualLetter = ((((personality & 0x3000000) >> 18) | ((personality & 0x30000) >> 12) | ((personality & 0x300) >> 6) | (personality & 0x3)) % 28);
- }
- while (nature != GetNatureFromPersonality(personality)
- || gender != GetGenderFromSpeciesAndPersonality(species, personality)
- || actualLetter != unownLetter - 1);
- }
- else
- {
- do
- {
- personality = Random32();
- }
- while (nature != GetNatureFromPersonality(personality)
- || gender != GetGenderFromSpeciesAndPersonality(species, personality));
- }
-
- CreateMon(mon, species, level, fixedIV, 1, personality, OT_ID_PLAYER_ID, 0);
-}
-
-// This is only used to create Wally's Ralts.
-void CreateMaleMon(struct Pokemon *mon, u16 species, u8 level)
-{
- u32 personality;
- u32 otId;
-
- do
- {
- otId = Random32();
- personality = Random32();
- }
- while (GetGenderFromSpeciesAndPersonality(species, personality) != MON_MALE);
- CreateMon(mon, species, level, 32, 1, personality, OT_ID_PRESET, otId);
-}
-
-void CreateMonWithIVsPersonality(struct Pokemon *mon, u16 species, u8 level, u32 ivs, u32 personality)
-{
- CreateMon(mon, species, level, 0, 1, personality, OT_ID_PLAYER_ID, 0);
- SetMonData(mon, MON_DATA_IVS, &ivs);
- CalculateMonStats(mon);
-}
-
-void CreateMonWithIVsOTID(struct Pokemon *mon, u16 species, u8 level, u8 *ivs, u32 otId)
-{
- CreateMon(mon, species, level, 0, 0, 0, OT_ID_PRESET, otId);
- SetMonData(mon, MON_DATA_HP_IV, &ivs[0]);
- SetMonData(mon, MON_DATA_ATK_IV, &ivs[1]);
- SetMonData(mon, MON_DATA_DEF_IV, &ivs[2]);
- SetMonData(mon, MON_DATA_SPEED_IV, &ivs[3]);
- SetMonData(mon, MON_DATA_SPATK_IV, &ivs[4]);
- SetMonData(mon, MON_DATA_SPDEF_IV, &ivs[5]);
- CalculateMonStats(mon);
-}
-
-void CreateMonWithEVSpread(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 evSpread)
-{
- s32 i;
- s32 statCount = 0;
- u16 evAmount;
- u8 temp;
-
- CreateMon(mon, species, level, fixedIV, 0, 0, 0, 0);
-
- temp = evSpread;
-
- for (i = 0; i < 6; i++)
- {
- if (temp & 1)
- statCount++;
- temp >>= 1;
- }
-
- evAmount = 510 / statCount;
-
- temp = 1;
-
- for (i = 0; i < 6; i++)
- {
- if (evSpread & temp)
- SetMonData(mon, MON_DATA_HP_EV + i, &evAmount);
- temp <<= 1;
- }
-
- CalculateMonStats(mon);
-}
-
-void sub_806819C(struct Pokemon *mon, struct UnknownPokemonStruct *src)
-{
- s32 i;
- u8 nickname[30];
- u8 language;
- u8 value;
-
- CreateMon(mon, src->species, src->level, 0, 1, src->personality, 1, src->otId);
-
- for (i = 0; i < 4; i++)
- SetMonMoveSlot(mon, src->moves[i], i);
-
- SetMonData(mon, MON_DATA_PP_BONUSES, &src->ppBonuses);
- SetMonData(mon, MON_DATA_HELD_ITEM, &src->heldItem);
- SetMonData(mon, MON_DATA_FRIENDSHIP, &src->friendship);
-
- StringCopy(nickname, src->nickname);
-
- if (nickname[0] == EXT_CTRL_CODE_BEGIN && nickname[1] == EXT_CTRL_CODE_JPN)
- {
- language = LANGUAGE_JAPANESE;
- StripExtCtrlCodes(nickname);
- }
- else
- {
- language = GAME_LANGUAGE;
- }
-
- SetMonData(mon, MON_DATA_LANGUAGE, &language);
- SetMonData(mon, MON_DATA_NICKNAME, nickname);
- SetMonData(mon, MON_DATA_HP_EV, &src->hpEV);
- SetMonData(mon, MON_DATA_ATK_EV, &src->attackEV);
- SetMonData(mon, MON_DATA_DEF_EV, &src->defenseEV);
- SetMonData(mon, MON_DATA_SPEED_EV, &src->speedEV);
- SetMonData(mon, MON_DATA_SPATK_EV, &src->spAttackEV);
- SetMonData(mon, MON_DATA_SPDEF_EV, &src->spDefenseEV);
- value = src->altAbility;
- SetMonData(mon, MON_DATA_ALT_ABILITY, &value);
- value = src->hpIV;
- SetMonData(mon, MON_DATA_HP_IV, &value);
- value = src->attackIV;
- SetMonData(mon, MON_DATA_ATK_IV, &value);
- value = src->defenseIV;
- SetMonData(mon, MON_DATA_DEF_IV, &value);
- value = src->speedIV;
- SetMonData(mon, MON_DATA_SPEED_IV, &value);
- value = src->spAttackIV;
- SetMonData(mon, MON_DATA_SPATK_IV, &value);
- value = src->spDefenseIV;
- SetMonData(mon, MON_DATA_SPDEF_IV, &value);
- MonRestorePP(mon);
- CalculateMonStats(mon);
-}
-
-u8 BattleFrontierGetOpponentLvl(u8);
-
-void sub_8068338(struct Pokemon *mon, struct UnknownPokemonStruct *src, bool8 lvl50)
-{
- s32 i;
- u8 nickname[30];
- u8 level;
- u8 language;
- u8 value;
-
- if (gSaveBlock2Ptr->frontierChosenLvl != 0)
- level = BattleFrontierGetOpponentLvl(gSaveBlock2Ptr->frontierChosenLvl);
- else if (lvl50)
- level = 50;
- else
- level = src->level;
-
- CreateMon(mon, src->species, level, 0, 1, src->personality, 1, src->otId);
-
- for (i = 0; i < 4; i++)
- SetMonMoveSlot(mon, src->moves[i], i);
-
- SetMonData(mon, MON_DATA_PP_BONUSES, &src->ppBonuses);
- SetMonData(mon, MON_DATA_HELD_ITEM, &src->heldItem);
- SetMonData(mon, MON_DATA_FRIENDSHIP, &src->friendship);
-
- StringCopy(nickname, src->nickname);
-
- if (nickname[0] == EXT_CTRL_CODE_BEGIN && nickname[1] == EXT_CTRL_CODE_JPN)
- {
- language = LANGUAGE_JAPANESE;
- StripExtCtrlCodes(nickname);
- }
- else
- {
- language = GAME_LANGUAGE;
- }
-
- SetMonData(mon, MON_DATA_LANGUAGE, &language);
- SetMonData(mon, MON_DATA_NICKNAME, nickname);
- SetMonData(mon, MON_DATA_HP_EV, &src->hpEV);
- SetMonData(mon, MON_DATA_ATK_EV, &src->attackEV);
- SetMonData(mon, MON_DATA_DEF_EV, &src->defenseEV);
- SetMonData(mon, MON_DATA_SPEED_EV, &src->speedEV);
- SetMonData(mon, MON_DATA_SPATK_EV, &src->spAttackEV);
- SetMonData(mon, MON_DATA_SPDEF_EV, &src->spDefenseEV);
- value = src->altAbility;
- SetMonData(mon, MON_DATA_ALT_ABILITY, &value);
- value = src->hpIV;
- SetMonData(mon, MON_DATA_HP_IV, &value);
- value = src->attackIV;
- SetMonData(mon, MON_DATA_ATK_IV, &value);
- value = src->defenseIV;
- SetMonData(mon, MON_DATA_DEF_IV, &value);
- value = src->speedIV;
- SetMonData(mon, MON_DATA_SPEED_IV, &value);
- value = src->spAttackIV;
- SetMonData(mon, MON_DATA_SPATK_IV, &value);
- value = src->spDefenseIV;
- SetMonData(mon, MON_DATA_SPDEF_IV, &value);
- MonRestorePP(mon);
- CalculateMonStats(mon);
-}
diff --git a/src/pokemon_2.c b/src/pokemon_2.c
deleted file mode 100644
index 3f37381c3..000000000
--- a/src/pokemon_2.c
+++ /dev/null
@@ -1,1365 +0,0 @@
-#include "global.h"
-#include "pokemon.h"
-#include "battle.h"
-#include "event_data.h"
-#include "random.h"
-#include "sprite.h"
-#include "constants/species.h"
-#include "text.h"
-#include "string_util.h"
-
-struct Unknown_020249B4
-{
- u8 unk0[0xC];
- struct SpriteTemplate* templates;
-};
-
-extern u8 gAbsentBattlerFlags;
-extern u8 gActiveBattler;
-extern u8 gBattlerAttacker;
-extern u8 gBattlerTarget;
-extern u8 gLastUsedAbility;
-extern u16 gTrainerBattleOpponent_A;
-extern u32 gBattleTypeFlags;
-extern struct SpriteTemplate gUnknown_0202499C;
-extern struct Unknown_020249B4* gUnknown_020249B4[2];
-
-extern const u32 gBitTable[];
-extern const struct SpriteTemplate gUnknown_08329D98[];
-extern const struct SpriteTemplate gUnknown_08329DF8[];
-extern const union AnimCmd* gUnknown_082FF70C[];
-extern const union AnimCmd* const * const gMonAnimationsSpriteAnimsPtrTable[];
-extern const union AnimCmd* const * const gUnknown_08305D0C[];
-extern const union AnimCmd* const * const gUnknown_0830536C[];
-extern const u8 gText_BadEgg[];
-extern const u8 gText_EggNickname[];
-
-extern u8 GetBattlerSide(u8 bank);
-extern u8 GetBattlerAtPosition(u8 bank);
-extern u8 GetBattlerPosition(u8 bank);
-
-u8 CountAliveMonsInBattle(u8 caseId)
-{
- s32 i;
- u8 retVal = 0;
-
- switch (caseId)
- {
- case BATTLE_ALIVE_EXCEPT_ACTIVE:
- for (i = 0; i < 4; i++)
- {
- if (i != gActiveBattler && !(gAbsentBattlerFlags & gBitTable[i]))
- retVal++;
- }
- break;
- case BATTLE_ALIVE_ATK_SIDE:
- for (i = 0; i < 4; i++)
- {
- if (GetBattlerSide(i) == GetBattlerSide(gBattlerAttacker) && !(gAbsentBattlerFlags & gBitTable[i]))
- retVal++;
- }
- break;
- case BATTLE_ALIVE_DEF_SIDE:
- for (i = 0; i < 4; i++)
- {
- if (GetBattlerSide(i) == GetBattlerSide(gBattlerTarget) && !(gAbsentBattlerFlags & gBitTable[i]))
- retVal++;
- }
- break;
- }
-
- return retVal;
-}
-
-bool8 ShouldGetStatBadgeBoost(u16 badgeFlag, u8 bank)
-{
- if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_x2000000 | BATTLE_TYPE_FRONTIER))
- return FALSE;
- if (GetBattlerSide(bank) != B_SIDE_PLAYER)
- return FALSE;
- if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && gTrainerBattleOpponent_A == SECRET_BASE_OPPONENT)
- return FALSE;
- if (FlagGet(badgeFlag))
- return TRUE;
- return FALSE;
-}
-
-u8 GetDefaultMoveTarget(u8 bank)
-{
- u8 status = GetBattlerPosition(bank) & 1;
-
- status ^= 1;
- if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
- return GetBattlerAtPosition(status);
- if (CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_ACTIVE) > 1)
- {
- u8 val;
-
- if ((Random() & 1) == 0)
- val = status ^ 2;
- else
- val = status;
- return GetBattlerAtPosition(val);
- }
- else
- {
- if ((gAbsentBattlerFlags & gBitTable[status]))
- return GetBattlerAtPosition(status ^ 2);
- else
- return GetBattlerAtPosition(status);
- }
-}
-
-u8 GetMonGender(struct Pokemon *mon)
-{
- return GetBoxMonGender(&mon->box);
-}
-
-u8 GetBoxMonGender(struct BoxPokemon *boxMon)
-{
- u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL);
- u32 personality = GetBoxMonData(boxMon, MON_DATA_PERSONALITY, NULL);
-
- switch (gBaseStats[species].genderRatio)
- {
- case MON_MALE:
- case MON_FEMALE:
- case MON_GENDERLESS:
- return gBaseStats[species].genderRatio;
- }
-
- if (gBaseStats[species].genderRatio > (personality & 0xFF))
- return MON_FEMALE;
- else
- return MON_MALE;
-}
-
-u8 GetGenderFromSpeciesAndPersonality(u16 species, u32 personality)
-{
- switch (gBaseStats[species].genderRatio)
- {
- case MON_MALE:
- case MON_FEMALE:
- case MON_GENDERLESS:
- return gBaseStats[species].genderRatio;
- }
-
- if (gBaseStats[species].genderRatio > (personality & 0xFF))
- return MON_FEMALE;
- else
- return MON_MALE;
-}
-
-void sub_806A068(u16 species, u8 bankIdentity)
-{
- if (gMonSpritesGfxPtr != NULL)
- gUnknown_0202499C = gMonSpritesGfxPtr->templates[bankIdentity];
- else if (gUnknown_020249B4[0])
- gUnknown_0202499C = gUnknown_020249B4[0]->templates[bankIdentity];
- else if (gUnknown_020249B4[1])
- gUnknown_0202499C = gUnknown_020249B4[1]->templates[bankIdentity];
- else
- gUnknown_0202499C = gUnknown_08329D98[bankIdentity];
-
- gUnknown_0202499C.paletteTag = species;
- if (bankIdentity == 0 || bankIdentity == 2)
- gUnknown_0202499C.anims = gUnknown_082FF70C;
- else if (species > 500)
- gUnknown_0202499C.anims = gMonAnimationsSpriteAnimsPtrTable[species - 500];
- else
- gUnknown_0202499C.anims = gMonAnimationsSpriteAnimsPtrTable[species];
-}
-
-void sub_806A12C(u16 trainerSpriteId, u8 bankIdentity)
-{
- gUnknown_0202499C.paletteTag = trainerSpriteId;
- if (bankIdentity == 0 || bankIdentity == 2)
- {
- gUnknown_0202499C = gUnknown_08329DF8[trainerSpriteId];
- gUnknown_0202499C.anims = gUnknown_08305D0C[trainerSpriteId];
- }
- else
- {
- if (gMonSpritesGfxPtr != NULL)
- gUnknown_0202499C = gMonSpritesGfxPtr->templates[bankIdentity];
- else
- gUnknown_0202499C = gUnknown_08329D98[bankIdentity];
- gUnknown_0202499C.anims = gUnknown_0830536C[trainerSpriteId];
- }
-}
-
-void sub_806A1C0(u16 arg0, u8 bankIdentity)
-{
- if (gMonSpritesGfxPtr != NULL)
- gUnknown_0202499C = gMonSpritesGfxPtr->templates[bankIdentity];
- else
- gUnknown_0202499C = gUnknown_08329D98[bankIdentity];
-
- gUnknown_0202499C.paletteTag = arg0;
- gUnknown_0202499C.anims = gUnknown_0830536C[arg0];
-}
-
-void EncryptBoxMon(struct BoxPokemon *boxMon)
-{
- u32 i;
- for (i = 0; i < 12; i++)
- {
- boxMon->secure.raw[i] ^= boxMon->personality;
- boxMon->secure.raw[i] ^= boxMon->otId;
- }
-}
-
-void DecryptBoxMon(struct BoxPokemon *boxMon)
-{
- u32 i;
- for (i = 0; i < 12; i++)
- {
- boxMon->secure.raw[i] ^= boxMon->otId;
- boxMon->secure.raw[i] ^= boxMon->personality;
- }
-}
-
-#define SUBSTRUCT_CASE(n, v1, v2, v3, v4) \
-case n: \
- { \
- union PokemonSubstruct *substructs0 = boxMon->secure.substructs; \
- union PokemonSubstruct *substructs1 = boxMon->secure.substructs; \
- union PokemonSubstruct *substructs2 = boxMon->secure.substructs; \
- union PokemonSubstruct *substructs3 = boxMon->secure.substructs; \
- union PokemonSubstruct *substructs4 = boxMon->secure.substructs; \
- union PokemonSubstruct *substructs5 = boxMon->secure.substructs; \
- union PokemonSubstruct *substructs6 = boxMon->secure.substructs; \
- union PokemonSubstruct *substructs7 = boxMon->secure.substructs; \
- union PokemonSubstruct *substructs8 = boxMon->secure.substructs; \
- union PokemonSubstruct *substructs9 = boxMon->secure.substructs; \
- union PokemonSubstruct *substructs10 = boxMon->secure.substructs; \
- union PokemonSubstruct *substructs11 = boxMon->secure.substructs; \
- union PokemonSubstruct *substructs12 = boxMon->secure.substructs; \
- union PokemonSubstruct *substructs13 = boxMon->secure.substructs; \
- union PokemonSubstruct *substructs14 = boxMon->secure.substructs; \
- union PokemonSubstruct *substructs15 = boxMon->secure.substructs; \
- union PokemonSubstruct *substructs16 = boxMon->secure.substructs; \
- union PokemonSubstruct *substructs17 = boxMon->secure.substructs; \
- union PokemonSubstruct *substructs18 = boxMon->secure.substructs; \
- union PokemonSubstruct *substructs19 = boxMon->secure.substructs; \
- union PokemonSubstruct *substructs20 = boxMon->secure.substructs; \
- union PokemonSubstruct *substructs21 = boxMon->secure.substructs; \
- union PokemonSubstruct *substructs22 = boxMon->secure.substructs; \
- union PokemonSubstruct *substructs23 = boxMon->secure.substructs; \
- \
- switch (substructType) \
- { \
- case 0: \
- substruct = &substructs ## n [v1]; \
- break; \
- case 1: \
- substruct = &substructs ## n [v2]; \
- break; \
- case 2: \
- substruct = &substructs ## n [v3]; \
- break; \
- case 3: \
- substruct = &substructs ## n [v4]; \
- break; \
- } \
- break; \
- } \
-
-
-union PokemonSubstruct *GetSubstruct(struct BoxPokemon *boxMon, u32 personality, u8 substructType)
-{
- union PokemonSubstruct *substruct = NULL;
-
- switch (personality % 24)
- {
- SUBSTRUCT_CASE( 0,0,1,2,3)
- SUBSTRUCT_CASE( 1,0,1,3,2)
- SUBSTRUCT_CASE( 2,0,2,1,3)
- SUBSTRUCT_CASE( 3,0,3,1,2)
- SUBSTRUCT_CASE( 4,0,2,3,1)
- SUBSTRUCT_CASE( 5,0,3,2,1)
- SUBSTRUCT_CASE( 6,1,0,2,3)
- SUBSTRUCT_CASE( 7,1,0,3,2)
- SUBSTRUCT_CASE( 8,2,0,1,3)
- SUBSTRUCT_CASE( 9,3,0,1,2)
- SUBSTRUCT_CASE(10,2,0,3,1)
- SUBSTRUCT_CASE(11,3,0,2,1)
- SUBSTRUCT_CASE(12,1,2,0,3)
- SUBSTRUCT_CASE(13,1,3,0,2)
- SUBSTRUCT_CASE(14,2,1,0,3)
- SUBSTRUCT_CASE(15,3,1,0,2)
- SUBSTRUCT_CASE(16,2,3,0,1)
- SUBSTRUCT_CASE(17,3,2,0,1)
- SUBSTRUCT_CASE(18,1,2,3,0)
- SUBSTRUCT_CASE(19,1,3,2,0)
- SUBSTRUCT_CASE(20,2,1,3,0)
- SUBSTRUCT_CASE(21,3,1,2,0)
- SUBSTRUCT_CASE(22,2,3,1,0)
- SUBSTRUCT_CASE(23,3,2,1,0)
- }
-
- return substruct;
-}
-
-extern u16 GetDeoxysStat(struct Pokemon *mon, s32 statId);
-
-u32 GetMonData(struct Pokemon *mon, s32 field, u8* data)
-{
- u32 ret;
-
- switch (field)
- {
- case MON_DATA_STATUS:
- ret = mon->status;
- break;
- case MON_DATA_LEVEL:
- ret = mon->level;
- break;
- case MON_DATA_HP:
- ret = mon->hp;
- break;
- case MON_DATA_MAX_HP:
- ret = mon->maxHP;
- break;
- case MON_DATA_ATK:
- ret = GetDeoxysStat(mon, STAT_ATK);
- if (!ret)
- ret = mon->attack;
- break;
- case MON_DATA_DEF:
- ret = GetDeoxysStat(mon, STAT_DEF);
- if (!ret)
- ret = mon->defense;
- break;
- case MON_DATA_SPEED:
- ret = GetDeoxysStat(mon, STAT_SPEED);
- if (!ret)
- ret = mon->speed;
- break;
- case MON_DATA_SPATK:
- ret = GetDeoxysStat(mon, STAT_SPATK);
- if (!ret)
- ret = mon->spAttack;
- break;
- case MON_DATA_SPDEF:
- ret = GetDeoxysStat(mon, STAT_SPDEF);
- if (!ret)
- ret = mon->spDefense;
- break;
- case MON_DATA_ATK2:
- ret = mon->attack;
- break;
- case MON_DATA_DEF2:
- ret = mon->defense;
- break;
- case MON_DATA_SPEED2:
- ret = mon->speed;
- break;
- case MON_DATA_SPATK2:
- ret = mon->spAttack;
- break;
- case MON_DATA_SPDEF2:
- ret = mon->spDefense;
- break;
- case MON_DATA_MAIL:
- ret = mon->mail;
- break;
- default:
- ret = GetBoxMonData(&mon->box, field, data);
- break;
- }
- return ret;
-}
-
-u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data)
-{
- s32 i;
- u32 retVal = 0;
- struct PokemonSubstruct0 *substruct0 = NULL;
- struct PokemonSubstruct1 *substruct1 = NULL;
- struct PokemonSubstruct2 *substruct2 = NULL;
- struct PokemonSubstruct3 *substruct3 = NULL;
-
- if (field > MON_DATA_10)
- {
- substruct0 = &(GetSubstruct(boxMon, boxMon->personality, 0)->type0);
- substruct1 = &(GetSubstruct(boxMon, boxMon->personality, 1)->type1);
- substruct2 = &(GetSubstruct(boxMon, boxMon->personality, 2)->type2);
- substruct3 = &(GetSubstruct(boxMon, boxMon->personality, 3)->type3);
-
- DecryptBoxMon(boxMon);
-
- if (CalculateBoxMonChecksum(boxMon) != boxMon->checksum)
- {
- boxMon->isBadEgg = 1;
- boxMon->isEgg = 1;
- substruct3->isEgg = 1;
- }
- }
-
- switch (field)
- {
- case MON_DATA_PERSONALITY:
- retVal = boxMon->personality;
- break;
- case MON_DATA_OT_ID:
- retVal = boxMon->otId;
- break;
- case MON_DATA_NICKNAME:
- {
- if (boxMon->isBadEgg)
- {
- for (retVal = 0;
- retVal < POKEMON_NAME_LENGTH && gText_BadEgg[retVal] != EOS;
- data[retVal] = gText_BadEgg[retVal], retVal++) {}
-
- data[retVal] = EOS;
- }
- else if (boxMon->isEgg)
- {
- StringCopy(data, gText_EggNickname);
- retVal = StringLength(data);
- }
- else if (boxMon->language == LANGUAGE_JAPANESE)
- {
- data[0] = EXT_CTRL_CODE_BEGIN;
- data[1] = EXT_CTRL_CODE_JPN;
-
- for (retVal = 2, i = 0;
- i < 5 && boxMon->nickname[i] != EOS;
- data[retVal] = boxMon->nickname[i], retVal++, i++) {}
-
- data[retVal++] = EXT_CTRL_CODE_BEGIN;
- data[retVal++] = EXT_CTRL_CODE_ENG;
- data[retVal] = EOS;
- }
- else
- {
- for (retVal = 0;
- retVal < POKEMON_NAME_LENGTH;
- data[retVal] = boxMon->nickname[retVal], retVal++){}
-
- data[retVal] = EOS;
- }
- break;
- }
- case MON_DATA_LANGUAGE:
- retVal = boxMon->language;
- break;
- case MON_DATA_SANITY_BIT1:
- retVal = boxMon->isBadEgg;
- break;
- case MON_DATA_SANITY_BIT2:
- retVal = boxMon->hasSpecies;
- break;
- case MON_DATA_SANITY_BIT3:
- retVal = boxMon->isEgg;
- break;
- case MON_DATA_OT_NAME:
- {
- retVal = 0;
-
- while (retVal < OT_NAME_LENGTH)
- {
- data[retVal] = boxMon->otName[retVal];
- retVal++;
- }
-
- data[retVal] = EOS;
- break;
- }
- case MON_DATA_MARKINGS:
- retVal = boxMon->markings;
- break;
- case MON_DATA_CHECKSUM:
- retVal = boxMon->checksum;
- break;
- case MON_DATA_10:
- retVal = boxMon->unknown;
- break;
- case MON_DATA_SPECIES:
- retVal = boxMon->isBadEgg ? SPECIES_EGG : substruct0->species;
- break;
- case MON_DATA_HELD_ITEM:
- retVal = substruct0->heldItem;
- break;
- case MON_DATA_EXP:
- retVal = substruct0->experience;
- break;
- case MON_DATA_PP_BONUSES:
- retVal = substruct0->ppBonuses;
- break;
- case MON_DATA_FRIENDSHIP:
- retVal = substruct0->friendship;
- break;
- case MON_DATA_MOVE1:
- case MON_DATA_MOVE2:
- case MON_DATA_MOVE3:
- case MON_DATA_MOVE4:
- retVal = substruct1->moves[field - MON_DATA_MOVE1];
- break;
- case MON_DATA_PP1:
- case MON_DATA_PP2:
- case MON_DATA_PP3:
- case MON_DATA_PP4:
- retVal = substruct1->pp[field - MON_DATA_PP1];
- break;
- case MON_DATA_HP_EV:
- retVal = substruct2->hpEV;
- break;
- case MON_DATA_ATK_EV:
- retVal = substruct2->attackEV;
- break;
- case MON_DATA_DEF_EV:
- retVal = substruct2->defenseEV;
- break;
- case MON_DATA_SPEED_EV:
- retVal = substruct2->speedEV;
- break;
- case MON_DATA_SPATK_EV:
- retVal = substruct2->spAttackEV;
- break;
- case MON_DATA_SPDEF_EV:
- retVal = substruct2->spDefenseEV;
- break;
- case MON_DATA_COOL:
- retVal = substruct2->cool;
- break;
- case MON_DATA_BEAUTY:
- retVal = substruct2->beauty;
- break;
- case MON_DATA_CUTE:
- retVal = substruct2->cute;
- break;
- case MON_DATA_SMART:
- retVal = substruct2->smart;
- break;
- case MON_DATA_TOUGH:
- retVal = substruct2->tough;
- break;
- case MON_DATA_SHEEN:
- retVal = substruct2->sheen;
- break;
- case MON_DATA_POKERUS:
- retVal = substruct3->pokerus;
- break;
- case MON_DATA_MET_LOCATION:
- retVal = substruct3->metLocation;
- break;
- case MON_DATA_MET_LEVEL:
- retVal = substruct3->metLevel;
- break;
- case MON_DATA_MET_GAME:
- retVal = substruct3->metGame;
- break;
- case MON_DATA_POKEBALL:
- retVal = substruct3->pokeball;
- break;
- case MON_DATA_OT_GENDER:
- retVal = substruct3->otGender;
- break;
- case MON_DATA_HP_IV:
- retVal = substruct3->hpIV;
- break;
- case MON_DATA_ATK_IV:
- retVal = substruct3->attackIV;
- break;
- case MON_DATA_DEF_IV:
- retVal = substruct3->defenseIV;
- break;
- case MON_DATA_SPEED_IV:
- retVal = substruct3->speedIV;
- break;
- case MON_DATA_SPATK_IV:
- retVal = substruct3->spAttackIV;
- break;
- case MON_DATA_SPDEF_IV:
- retVal = substruct3->spDefenseIV;
- break;
- case MON_DATA_IS_EGG:
- retVal = substruct3->isEgg;
- break;
- case MON_DATA_ALT_ABILITY:
- retVal = substruct3->altAbility;
- break;
- case MON_DATA_COOL_RIBBON:
- retVal = substruct3->coolRibbon;
- break;
- case MON_DATA_BEAUTY_RIBBON:
- retVal = substruct3->beautyRibbon;
- break;
- case MON_DATA_CUTE_RIBBON:
- retVal = substruct3->cuteRibbon;
- break;
- case MON_DATA_SMART_RIBBON:
- retVal = substruct3->smartRibbon;
- break;
- case MON_DATA_TOUGH_RIBBON:
- retVal = substruct3->toughRibbon;
- break;
- case MON_DATA_CHAMPION_RIBBON:
- retVal = substruct3->championRibbon;
- break;
- case MON_DATA_WINNING_RIBBON:
- retVal = substruct3->winningRibbon;
- break;
- case MON_DATA_VICTORY_RIBBON:
- retVal = substruct3->victoryRibbon;
- break;
- case MON_DATA_ARTIST_RIBBON:
- retVal = substruct3->artistRibbon;
- break;
- case MON_DATA_EFFORT_RIBBON:
- retVal = substruct3->effortRibbon;
- break;
- case MON_DATA_GIFT_RIBBON_1:
- retVal = substruct3->giftRibbon1;
- break;
- case MON_DATA_GIFT_RIBBON_2:
- retVal = substruct3->giftRibbon2;
- break;
- case MON_DATA_GIFT_RIBBON_3:
- retVal = substruct3->giftRibbon3;
- break;
- case MON_DATA_GIFT_RIBBON_4:
- retVal = substruct3->giftRibbon4;
- break;
- case MON_DATA_GIFT_RIBBON_5:
- retVal = substruct3->giftRibbon5;
- break;
- case MON_DATA_GIFT_RIBBON_6:
- retVal = substruct3->giftRibbon6;
- break;
- case MON_DATA_GIFT_RIBBON_7:
- retVal = substruct3->giftRibbon7;
- break;
- case MON_DATA_FATEFUL_ENCOUNTER:
- retVal = substruct3->fatefulEncounter;
- break;
- case MON_DATA_OBEDIENCE:
- retVal = substruct3->obedient;
- break;
- case MON_DATA_SPECIES2:
- retVal = substruct0->species;
- if (substruct0->species && (substruct3->isEgg || boxMon->isBadEgg))
- retVal = SPECIES_EGG;
- break;
- case MON_DATA_IVS:
- retVal = substruct3->hpIV | (substruct3->attackIV << 5) | (substruct3->defenseIV << 10) | (substruct3->speedIV << 15) | (substruct3->spAttackIV << 20) | (substruct3->spDefenseIV << 25);
- break;
- case MON_DATA_KNOWN_MOVES:
- if (substruct0->species && !substruct3->isEgg)
- {
- u16 *moves = (u16 *)data;
- s32 i = 0;
-
- while (moves[i] != 355)
- {
- u16 move = moves[i];
- if (substruct1->moves[0] == move
- || substruct1->moves[1] == move
- || substruct1->moves[2] == move
- || substruct1->moves[3] == move)
- retVal |= gBitTable[i];
- i++;
- }
- }
- break;
- case MON_DATA_RIBBON_COUNT:
- retVal = 0;
- if (substruct0->species && !substruct3->isEgg)
- {
- retVal += substruct3->coolRibbon;
- retVal += substruct3->beautyRibbon;
- retVal += substruct3->cuteRibbon;
- retVal += substruct3->smartRibbon;
- retVal += substruct3->toughRibbon;
- retVal += substruct3->championRibbon;
- retVal += substruct3->winningRibbon;
- retVal += substruct3->victoryRibbon;
- retVal += substruct3->artistRibbon;
- retVal += substruct3->effortRibbon;
- retVal += substruct3->giftRibbon1;
- retVal += substruct3->giftRibbon2;
- retVal += substruct3->giftRibbon3;
- retVal += substruct3->giftRibbon4;
- retVal += substruct3->giftRibbon5;
- retVal += substruct3->giftRibbon6;
- retVal += substruct3->giftRibbon7;
- }
- break;
- case MON_DATA_RIBBONS:
- retVal = 0;
- if (substruct0->species && !substruct3->isEgg)
- {
- retVal = substruct3->championRibbon
- | (substruct3->coolRibbon << 1)
- | (substruct3->beautyRibbon << 4)
- | (substruct3->cuteRibbon << 7)
- | (substruct3->smartRibbon << 10)
- | (substruct3->toughRibbon << 13)
- | (substruct3->winningRibbon << 16)
- | (substruct3->victoryRibbon << 17)
- | (substruct3->artistRibbon << 18)
- | (substruct3->effortRibbon << 19)
- | (substruct3->giftRibbon1 << 20)
- | (substruct3->giftRibbon2 << 21)
- | (substruct3->giftRibbon3 << 22)
- | (substruct3->giftRibbon4 << 23)
- | (substruct3->giftRibbon5 << 24)
- | (substruct3->giftRibbon6 << 25)
- | (substruct3->giftRibbon7 << 26);
- }
- break;
- default:
- break;
- }
-
- if (field > MON_DATA_10)
- EncryptBoxMon(boxMon);
-
- return retVal;
-}
-
-#define SET8(lhs) (lhs) = *data
-#define SET16(lhs) (lhs) = data[0] + (data[1] << 8)
-#define SET32(lhs) (lhs) = data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24)
-
-void SetMonData(struct Pokemon *mon, s32 field, const void *dataArg)
-{
- const u8* data = dataArg;
- switch (field)
- {
- case MON_DATA_STATUS:
- SET32(mon->status);
- break;
- case MON_DATA_LEVEL:
- SET8(mon->level);
- break;
- case MON_DATA_HP:
- SET16(mon->hp);
- break;
- case MON_DATA_MAX_HP:
- SET16(mon->maxHP);
- break;
- case MON_DATA_ATK:
- SET16(mon->attack);
- break;
- case MON_DATA_DEF:
- SET16(mon->defense);
- break;
- case MON_DATA_SPEED:
- SET16(mon->speed);
- break;
- case MON_DATA_SPATK:
- SET16(mon->spAttack);
- break;
- case MON_DATA_SPDEF:
- SET16(mon->spDefense);
- break;
- case MON_DATA_MAIL:
- SET8(mon->mail);
- break;
- case MON_DATA_SPECIES2:
- break;
- default:
- SetBoxMonData(&mon->box, field, data);
- break;
- }
-}
-
-void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg)
-{
- const u8* data = dataArg;
-
- struct PokemonSubstruct0 *substruct0 = NULL;
- struct PokemonSubstruct1 *substruct1 = NULL;
- struct PokemonSubstruct2 *substruct2 = NULL;
- struct PokemonSubstruct3 *substruct3 = NULL;
-
- if (field > MON_DATA_10)
- {
- substruct0 = &(GetSubstruct(boxMon, boxMon->personality, 0)->type0);
- substruct1 = &(GetSubstruct(boxMon, boxMon->personality, 1)->type1);
- substruct2 = &(GetSubstruct(boxMon, boxMon->personality, 2)->type2);
- substruct3 = &(GetSubstruct(boxMon, boxMon->personality, 3)->type3);
-
- DecryptBoxMon(boxMon);
-
- if (CalculateBoxMonChecksum(boxMon) != boxMon->checksum)
- {
- boxMon->isBadEgg = 1;
- boxMon->isEgg = 1;
- substruct3->isEgg = 1;
- EncryptBoxMon(boxMon);
- return;
- }
- }
-
- switch (field)
- {
- case MON_DATA_PERSONALITY:
- SET32(boxMon->personality);
- break;
- case MON_DATA_OT_ID:
- SET32(boxMon->otId);
- break;
- case MON_DATA_NICKNAME:
- {
- s32 i;
- for (i = 0; i < POKEMON_NAME_LENGTH; i++)
- boxMon->nickname[i] = data[i];
- break;
- }
- case MON_DATA_LANGUAGE:
- SET8(boxMon->language);
- break;
- case MON_DATA_SANITY_BIT1:
- SET8(boxMon->isBadEgg);
- break;
- case MON_DATA_SANITY_BIT2:
- SET8(boxMon->hasSpecies);
- break;
- case MON_DATA_SANITY_BIT3:
- SET8(boxMon->isEgg);
- break;
- case MON_DATA_OT_NAME:
- {
- s32 i;
- for (i = 0; i < OT_NAME_LENGTH; i++)
- boxMon->otName[i] = data[i];
- break;
- }
- case MON_DATA_MARKINGS:
- SET8(boxMon->markings);
- break;
- case MON_DATA_CHECKSUM:
- SET16(boxMon->checksum);
- break;
- case MON_DATA_10:
- SET16(boxMon->unknown);
- break;
- case MON_DATA_SPECIES:
- {
- SET16(substruct0->species);
- if (substruct0->species)
- boxMon->hasSpecies = 1;
- else
- boxMon->hasSpecies = 0;
- break;
- }
- case MON_DATA_HELD_ITEM:
- SET16(substruct0->heldItem);
- break;
- case MON_DATA_EXP:
- SET32(substruct0->experience);
- break;
- case MON_DATA_PP_BONUSES:
- SET8(substruct0->ppBonuses);
- break;
- case MON_DATA_FRIENDSHIP:
- SET8(substruct0->friendship);
- break;
- case MON_DATA_MOVE1:
- case MON_DATA_MOVE2:
- case MON_DATA_MOVE3:
- case MON_DATA_MOVE4:
- SET16(substruct1->moves[field - MON_DATA_MOVE1]);
- break;
- case MON_DATA_PP1:
- case MON_DATA_PP2:
- case MON_DATA_PP3:
- case MON_DATA_PP4:
- SET8(substruct1->pp[field - MON_DATA_PP1]);
- break;
- case MON_DATA_HP_EV:
- SET8(substruct2->hpEV);
- break;
- case MON_DATA_ATK_EV:
- SET8(substruct2->attackEV);
- break;
- case MON_DATA_DEF_EV:
- SET8(substruct2->defenseEV);
- break;
- case MON_DATA_SPEED_EV:
- SET8(substruct2->speedEV);
- break;
- case MON_DATA_SPATK_EV:
- SET8(substruct2->spAttackEV);
- break;
- case MON_DATA_SPDEF_EV:
- SET8(substruct2->spDefenseEV);
- break;
- case MON_DATA_COOL:
- SET8(substruct2->cool);
- break;
- case MON_DATA_BEAUTY:
- SET8(substruct2->beauty);
- break;
- case MON_DATA_CUTE:
- SET8(substruct2->cute);
- break;
- case MON_DATA_SMART:
- SET8(substruct2->smart);
- break;
- case MON_DATA_TOUGH:
- SET8(substruct2->tough);
- break;
- case MON_DATA_SHEEN:
- SET8(substruct2->sheen);
- break;
- case MON_DATA_POKERUS:
- SET8(substruct3->pokerus);
- break;
- case MON_DATA_MET_LOCATION:
- SET8(substruct3->metLocation);
- break;
- case MON_DATA_MET_LEVEL:
- {
- u8 metLevel = *data;
- substruct3->metLevel = metLevel;
- break;
- }
- case MON_DATA_MET_GAME:
- SET8(substruct3->metGame);
- break;
- case MON_DATA_POKEBALL:
- {
- u8 pokeball = *data;
- substruct3->pokeball = pokeball;
- break;
- }
- case MON_DATA_OT_GENDER:
- SET8(substruct3->otGender);
- break;
- case MON_DATA_HP_IV:
- SET8(substruct3->hpIV);
- break;
- case MON_DATA_ATK_IV:
- SET8(substruct3->attackIV);
- break;
- case MON_DATA_DEF_IV:
- SET8(substruct3->defenseIV);
- break;
- case MON_DATA_SPEED_IV:
- SET8(substruct3->speedIV);
- break;
- case MON_DATA_SPATK_IV:
- SET8(substruct3->spAttackIV);
- break;
- case MON_DATA_SPDEF_IV:
- SET8(substruct3->spDefenseIV);
- break;
- case MON_DATA_IS_EGG:
- SET8(substruct3->isEgg);
- if (substruct3->isEgg)
- boxMon->isEgg = 1;
- else
- boxMon->isEgg = 0;
- break;
- case MON_DATA_ALT_ABILITY:
- SET8(substruct3->altAbility);
- break;
- case MON_DATA_COOL_RIBBON:
- SET8(substruct3->coolRibbon);
- break;
- case MON_DATA_BEAUTY_RIBBON:
- SET8(substruct3->beautyRibbon);
- break;
- case MON_DATA_CUTE_RIBBON:
- SET8(substruct3->cuteRibbon);
- break;
- case MON_DATA_SMART_RIBBON:
- SET8(substruct3->smartRibbon);
- break;
- case MON_DATA_TOUGH_RIBBON:
- SET8(substruct3->toughRibbon);
- break;
- case MON_DATA_CHAMPION_RIBBON:
- SET8(substruct3->championRibbon);
- break;
- case MON_DATA_WINNING_RIBBON:
- SET8(substruct3->winningRibbon);
- break;
- case MON_DATA_VICTORY_RIBBON:
- SET8(substruct3->victoryRibbon);
- break;
- case MON_DATA_ARTIST_RIBBON:
- SET8(substruct3->artistRibbon);
- break;
- case MON_DATA_EFFORT_RIBBON:
- SET8(substruct3->effortRibbon);
- break;
- case MON_DATA_GIFT_RIBBON_1:
- SET8(substruct3->giftRibbon1);
- break;
- case MON_DATA_GIFT_RIBBON_2:
- SET8(substruct3->giftRibbon2);
- break;
- case MON_DATA_GIFT_RIBBON_3:
- SET8(substruct3->giftRibbon3);
- break;
- case MON_DATA_GIFT_RIBBON_4:
- SET8(substruct3->giftRibbon4);
- break;
- case MON_DATA_GIFT_RIBBON_5:
- SET8(substruct3->giftRibbon5);
- break;
- case MON_DATA_GIFT_RIBBON_6:
- SET8(substruct3->giftRibbon6);
- break;
- case MON_DATA_GIFT_RIBBON_7:
- SET8(substruct3->giftRibbon7);
- break;
- case MON_DATA_FATEFUL_ENCOUNTER:
- SET8(substruct3->fatefulEncounter);
- break;
- case MON_DATA_OBEDIENCE:
- SET8(substruct3->obedient);
- break;
- case MON_DATA_IVS:
- {
- u32 ivs = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
- substruct3->hpIV = ivs & 0x1F;
- substruct3->attackIV = (ivs >> 5) & 0x1F;
- substruct3->defenseIV = (ivs >> 10) & 0x1F;
- substruct3->speedIV = (ivs >> 15) & 0x1F;
- substruct3->spAttackIV = (ivs >> 20) & 0x1F;
- substruct3->spDefenseIV = (ivs >> 25) & 0x1F;
- break;
- }
- default:
- break;
- }
-
- if (field > MON_DATA_10)
- {
- boxMon->checksum = CalculateBoxMonChecksum(boxMon);
- EncryptBoxMon(boxMon);
- }
-}
-
-void CopyMon(void *dest, void *src, size_t size)
-{
- memcpy(dest, src, size);
-}
-
-u8 GiveMonToPlayer(struct Pokemon *mon)
-{
- s32 i;
-
- SetMonData(mon, MON_DATA_OT_NAME, gSaveBlock2Ptr->playerName);
- SetMonData(mon, MON_DATA_OT_GENDER, &gSaveBlock2Ptr->playerGender);
- SetMonData(mon, MON_DATA_OT_ID, gSaveBlock2Ptr->playerTrainerId);
-
- i = 0;
-
- while (i < 6 && GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL) != SPECIES_NONE)
- i++;
-
- if (i >= 6)
- return SendMonToPC(mon);
-
- CopyMon(&gPlayerParty[i], mon, sizeof(*mon));
- gPlayerPartyCount = i + 1;
- return MON_GIVEN_TO_PARTY;
-}
-
-extern u16 get_unknown_box_id(void);
-extern u8 StorageGetCurrentBox(void);
-extern void set_unknown_box_id(u8);
-extern struct BoxPokemon* GetBoxedMonPtr(u8 boxNumber, u8 boxPosition);
-
-u8 SendMonToPC(struct Pokemon* mon)
-{
- s32 boxNo, boxPos;
-
- set_unknown_box_id(VarGet(VAR_STORAGE_UNKNOWN));
-
- boxNo = StorageGetCurrentBox();
-
- do
- {
- for (boxPos = 0; boxPos < 30; boxPos++)
- {
- struct BoxPokemon* checkingMon = GetBoxedMonPtr(boxNo, boxPos);
- if (GetBoxMonData(checkingMon, MON_DATA_SPECIES, NULL) == SPECIES_NONE)
- {
- MonRestorePP(mon);
- CopyMon(checkingMon, &mon->box, sizeof(mon->box));
- gSpecialVar_MonBoxId = boxNo;
- gSpecialVar_MonBoxPos = boxPos;
- if (get_unknown_box_id() != boxNo)
- FlagClear(FLAG_SYS_STORAGE_UNKNOWN_FLAG);
- VarSet(VAR_STORAGE_UNKNOWN, boxNo);
- return MON_GIVEN_TO_PC;
- }
- }
-
- boxNo++;
- if (boxNo == 14)
- boxNo = 0;
- } while (boxNo != StorageGetCurrentBox());
-
- return MON_CANT_GIVE;
-}
-
-u8 CalculatePlayerPartyCount(void)
-{
- gPlayerPartyCount = 0;
-
- while (gPlayerPartyCount < 6
- && GetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_SPECIES, NULL) != SPECIES_NONE)
- {
- gPlayerPartyCount++;
- }
-
- return gPlayerPartyCount;
-}
-
-u8 CalculateEnemyPartyCount(void)
-{
- gEnemyPartyCount = 0;
-
- while (gEnemyPartyCount < 6
- && GetMonData(&gEnemyParty[gEnemyPartyCount], MON_DATA_SPECIES, NULL) != SPECIES_NONE)
- {
- gEnemyPartyCount++;
- }
-
- return gEnemyPartyCount;
-}
-
-u8 GetMonsStateToDoubles(void)
-{
- s32 aliveCount = 0;
- s32 i;
- CalculatePlayerPartyCount();
-
- if (gPlayerPartyCount == 1)
- return gPlayerPartyCount; // PLAYER_HAS_ONE_MON
-
- for (i = 0; i < gPlayerPartyCount; i++)
- {
- if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) != SPECIES_EGG
- && GetMonData(&gPlayerParty[i], MON_DATA_HP, NULL) != 0
- && GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) != SPECIES_NONE)
- aliveCount++;
- }
-
- return (aliveCount > 1) ? PLAYER_HAS_TWO_USABLE_MONS : PLAYER_HAS_ONE_USABLE_MON;
-}
-
-u8 GetMonsStateToDoubles_2(void)
-{
- s32 aliveCount = 0;
- s32 i;
-
- for (i = 0; i < PARTY_SIZE; i++)
- {
- u32 species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL);
- if (species != SPECIES_EGG && species != SPECIES_NONE
- && GetMonData(&gPlayerParty[i], MON_DATA_HP, NULL) != 0)
- aliveCount++;
- }
-
- if (aliveCount == 1)
- return PLAYER_HAS_ONE_MON; // may have more than one, but only one is alive
-
- return (aliveCount > 1) ? PLAYER_HAS_TWO_USABLE_MONS : PLAYER_HAS_ONE_USABLE_MON;
-}
-
-u8 GetAbilityBySpecies(u16 species, bool8 altAbility)
-{
- if (altAbility)
- gLastUsedAbility = gBaseStats[species].ability2;
- else
- gLastUsedAbility = gBaseStats[species].ability1;
-
- return gLastUsedAbility;
-}
-
-u8 GetMonAbility(struct Pokemon *mon)
-{
- u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
- u8 altAbility = GetMonData(mon, MON_DATA_ALT_ABILITY, NULL);
- return GetAbilityBySpecies(species, altAbility);
-}
-
-extern const struct BattleMove gBattleMoves[];
-
-void CreateSecretBaseEnemyParty(struct SecretBaseRecord *secretBaseRecord)
-{
- s32 i, j;
-
- ZeroEnemyPartyMons();
- *gBattleResources->secretBase = *secretBaseRecord;
-
- for (i = 0; i < PARTY_SIZE; i++)
- {
- if (gBattleResources->secretBase->party.species[i])
- {
- CreateMon(&gEnemyParty[i],
- gBattleResources->secretBase->party.species[i],
- gBattleResources->secretBase->party.levels[i],
- 15,
- 1,
- gBattleResources->secretBase->party.personality[i],
- 2,
- 0);
-
- SetMonData(&gEnemyParty[i], MON_DATA_HELD_ITEM, &gBattleResources->secretBase->party.heldItems[i]);
-
- for (j = 0; j < 6; j++)
- SetMonData(&gEnemyParty[i], MON_DATA_HP_EV + j, &gBattleResources->secretBase->party.EVs[i]);
-
- for (j = 0; j < 4; j++)
- {
- SetMonData(&gEnemyParty[i], MON_DATA_MOVE1 + j, &gBattleResources->secretBase->party.moves[i * 4 + j]);
- SetMonData(&gEnemyParty[i], MON_DATA_PP1 + j, &gBattleMoves[gBattleResources->secretBase->party.moves[i * 4 + j]].pp);
- }
- }
- }
-}
-
-extern const u8 gFacilityClassToPicIndex[];
-extern const u8 gFacilityClassToTrainerClass[];
-extern const u8 gSecretBaseTrainerClasses[][5];
-
-u8 GetSecretBaseTrainerPicIndex(void)
-{
- u8 trainerClass = gSecretBaseTrainerClasses[gBattleResources->secretBase->gender][gBattleResources->secretBase->trainerId[0] % 5];
- return gFacilityClassToPicIndex[trainerClass];
-}
-
-u8 GetSecretBaseTrainerNameIndex(void)
-{
- u8 trainerClass = gSecretBaseTrainerClasses[gBattleResources->secretBase->gender][gBattleResources->secretBase->trainerId[0] % 5];
- return gFacilityClassToTrainerClass[trainerClass];
-}
-
-bool8 IsPlayerPartyAndPokemonStorageFull(void)
-{
- s32 i;
-
- for (i = 0; i < 6; i++)
- if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL) == SPECIES_NONE)
- return FALSE;
-
- return IsPokemonStorageFull();
-}
-
-extern u32 GetBoxMonDataFromAnyBox(u8 boxNo, u8 boxPos, s32 field);
-
-bool8 IsPokemonStorageFull(void)
-{
- s32 i, j;
-
- for (i = 0; i < 14; i++)
- for (j = 0; j < 30; j++)
- if (GetBoxMonDataFromAnyBox(i, j, MON_DATA_SPECIES) == SPECIES_NONE)
- return FALSE;
-
- return TRUE;
-}
-
-extern const u8 gSpeciesNames[][POKEMON_NAME_LENGTH + 1];
-
-void GetSpeciesName(u8 *name, u16 species)
-{
- s32 i;
-
- for (i = 0; i <= POKEMON_NAME_LENGTH; i++)
- {
- if (species > NUM_SPECIES)
- name[i] = gSpeciesNames[0][i];
- else
- name[i] = gSpeciesNames[species][i];
-
- if (name[i] == EOS)
- break;
- }
-
- name[i] = EOS;
-}
-
-extern const u8 gUnknown_08329D22[];
-extern const u8 gUnknown_08329D26[];
-
-u8 CalculatePPWithBonus(u16 move, u8 ppBonuses, u8 moveIndex)
-{
- u8 basePP = gBattleMoves[move].pp;
- return basePP + ((basePP * 20 * ((gUnknown_08329D22[moveIndex] & ppBonuses) >> (2 * moveIndex))) / 100);
-}
-
-void RemoveMonPPBonus(struct Pokemon *mon, u8 moveIndex)
-{
- u8 ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES, NULL);
- ppBonuses &= gUnknown_08329D26[moveIndex];
- SetMonData(mon, MON_DATA_PP_BONUSES, &ppBonuses);
-}
-
-void RemoveBattleMonPPBonus(struct BattlePokemon *mon, u8 moveIndex)
-{
- mon->ppBonuses &= gUnknown_08329D26[moveIndex];
-}
-
-void sub_803FA70(u8 bank);
-void ClearTemporarySpeciesSpriteData(u8 bank, bool8);
-
-extern struct BattlePokemon gBattleMons[4];
-
-void CopyPlayerPartyMonToBattleData(u8 bank, u8 partyIndex)
-{
- u16* hpSwitchout;
- s32 i;
- u8 nickname[POKEMON_NAME_LENGTH * 2];
-
- gBattleMons[bank].species = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPECIES, NULL);
- gBattleMons[bank].item = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HELD_ITEM, NULL);
-
- for (i = 0; i < 4; i++)
- {
- gBattleMons[bank].moves[i] = GetMonData(&gPlayerParty[partyIndex], MON_DATA_MOVE1 + i, NULL);
- gBattleMons[bank].pp[i] = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PP1 + i, NULL);
- }
-
- gBattleMons[bank].ppBonuses = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PP_BONUSES, NULL);
- gBattleMons[bank].friendship = GetMonData(&gPlayerParty[partyIndex], MON_DATA_FRIENDSHIP, NULL);
- gBattleMons[bank].experience = GetMonData(&gPlayerParty[partyIndex], MON_DATA_EXP, NULL);
- gBattleMons[bank].hpIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HP_IV, NULL);
- gBattleMons[bank].attackIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_ATK_IV, NULL);
- gBattleMons[bank].defenseIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_DEF_IV, NULL);
- gBattleMons[bank].speedIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPEED_IV, NULL);
- gBattleMons[bank].spAttackIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPATK_IV, NULL);
- gBattleMons[bank].spDefenseIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPDEF_IV, NULL);
- gBattleMons[bank].personality = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PERSONALITY, NULL);
- gBattleMons[bank].status1 = GetMonData(&gPlayerParty[partyIndex], MON_DATA_STATUS, NULL);
- gBattleMons[bank].level = GetMonData(&gPlayerParty[partyIndex], MON_DATA_LEVEL, NULL);
- gBattleMons[bank].hp = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HP, NULL);
- gBattleMons[bank].maxHP = GetMonData(&gPlayerParty[partyIndex], MON_DATA_MAX_HP, NULL);
- gBattleMons[bank].attack = GetMonData(&gPlayerParty[partyIndex], MON_DATA_ATK, NULL);
- gBattleMons[bank].defense = GetMonData(&gPlayerParty[partyIndex], MON_DATA_DEF, NULL);
- gBattleMons[bank].speed = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPEED, NULL);
- gBattleMons[bank].spAttack = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPATK, NULL);
- gBattleMons[bank].spDefense = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPDEF, NULL);
- gBattleMons[bank].isEgg = GetMonData(&gPlayerParty[partyIndex], MON_DATA_IS_EGG, NULL);
- gBattleMons[bank].altAbility = GetMonData(&gPlayerParty[partyIndex], MON_DATA_ALT_ABILITY, NULL);
- gBattleMons[bank].otId = GetMonData(&gPlayerParty[partyIndex], MON_DATA_OT_ID, NULL);
- gBattleMons[bank].type1 = gBaseStats[gBattleMons[bank].species].type1;
- gBattleMons[bank].type2 = gBaseStats[gBattleMons[bank].species].type2;
- gBattleMons[bank].ability = GetAbilityBySpecies(gBattleMons[bank].species, gBattleMons[bank].altAbility);
- GetMonData(&gPlayerParty[partyIndex], MON_DATA_NICKNAME, nickname);
- StringCopy10(gBattleMons[bank].nickname, nickname);
- GetMonData(&gPlayerParty[partyIndex], MON_DATA_OT_NAME, gBattleMons[bank].otName);
-
- hpSwitchout = &gBattleStruct->hpOnSwitchout[GetBattlerSide(bank)];
- *hpSwitchout = gBattleMons[bank].hp;
-
- for (i = 0; i < 8; i++)
- gBattleMons[bank].statStages[i] = 6;
-
- gBattleMons[bank].status2 = 0;
- sub_803FA70(bank);
- ClearTemporarySpeciesSpriteData(bank, FALSE);
-}
diff --git a/src/pokemon_3.c b/src/pokemon_3.c
deleted file mode 100644
index 0dd1131de..000000000
--- a/src/pokemon_3.c
+++ /dev/null
@@ -1,1749 +0,0 @@
-#include "global.h"
-#include "pokemon.h"
-#include "main.h"
-#include "constants/items.h"
-#include "string_util.h"
-#include "battle_message.h"
-#include "rtc.h"
-#include "item.h"
-#include "battle.h"
-#include "constants/species.h"
-#include "link.h"
-#include "constants/hold_effects.h"
-#include "random.h"
-#include "constants/trainers.h"
-#include "constants/songs.h"
-#include "sound.h"
-#include "m4a.h"
-#include "task.h"
-#include "sprite.h"
-#include "text.h"
-#include "constants/abilities.h"
-#include "pokemon_animation.h"
-#include "pokedex.h"
-#include "pokeblock.h"
-
-extern struct BattlePokemon gBattleMons[4];
-extern struct BattleEnigmaBerry gEnigmaBerries[4];
-extern u8 gActiveBattler;
-extern u8 gBattlerInMenuId;
-extern u8 gBattlerTarget;
-extern u8 gBattlerAttacker;
-extern u8 gPotentialItemEffectBattler;
-extern u16 gTrainerBattleOpponent_A;
-extern u32 gBattleTypeFlags;
-extern u8 gBattleMonForms[4];
-extern u16 gBattlerPartyIndexes[4];
-extern u8 gLastUsedAbility;
-extern u16 gPartnerTrainerId;
-extern u32 gHitMarker;
-
-extern const u16 gSpeciesToHoennPokedexNum[];
-extern const u16 gSpeciesToNationalPokedexNum[];
-extern const u16 gHoennToNationalOrder[];
-extern const u16 gSpeciesIdToCryId[];
-extern const struct SpindaSpot gSpindaSpotGraphics[];
-extern const u8* const gStatNamesTable[];
-extern const u8 gSpeciesNames[][11];
-extern const u8 gUnknown_08329EC8[];
-extern const u8 gText_StatRose[];
-extern const u8 gText_PkmnsStatChanged2[];
-extern const u8 gText_PkmnGettingPumped[];
-extern const u8 gText_PkmnShroudedInMist[];
-extern const s8 gNatureStatTable[][5];
-extern const s8 gUnknown_08329ECE[][3];
-extern const u32 gBitTable[];
-extern const u32 gTMHMLearnsets[][2];
-extern const u8 gText_BattleWallyName[];
-extern const u8 gText_PkmnsXPreventsSwitching[];
-extern const struct CompressedSpritePalette gMonPaletteTable[];
-extern const struct CompressedSpritePalette gMonShinyPaletteTable[];
-extern const u16 gHMMoves[];
-extern const u8 gMonAnimationDelayTable[];
-extern const u8 gMonFrontAnimIdsTable[];
-
-extern bool8 InBattlePyramid(void);
-extern bool8 InBattlePike(void);
-extern bool8 sub_81D5C18(void);
-extern bool8 sub_806F104(void);
-extern bool32 IsNationalPokedexEnabled(void);
-extern u8 GetTrainerEncounterMusicIdInBattlePyramind(u16 trainerOpponentId);
-extern u8 sub_81D63C8(u16 trainerOpponentId);
-extern u8 sav1_map_get_name(void);
-extern u8 GetFrontierOpponentClass(u16 trainerId);
-extern u8 pokemon_order_func(u8 bankPartyId);
-extern void GetFrontierTrainerName(u8* dest, u16 trainerId);
-extern void sub_81C488C(u8);
-
-static void sub_806E6CC(u8 taskId);
-
-bool8 HealStatusConditions(struct Pokemon *mon, u32 battlePartyId, u32 healMask, u8 battleBank)
-{
- u32 status = GetMonData(mon, MON_DATA_STATUS, 0);
-
- if (status & healMask)
- {
- status &= ~healMask;
- SetMonData(mon, MON_DATA_STATUS, (u8 *)&status);
- if (gMain.inBattle && battleBank != 4)
- gBattleMons[battleBank].status1 &= ~healMask;
- return FALSE;
- }
- else
- {
- return TRUE;
- }
-}
-
-u8 GetItemEffectParamOffset(u16 itemId, u8 effectByte, u8 effectBit)
-{
- const u8 *temp;
- const u8 *itemEffect;
- u8 offset;
- int i;
- u8 j;
- u8 val;
-
- offset = 6;
-
- temp = gItemEffectTable[itemId - 13];
-
- if (!temp && itemId != ITEM_ENIGMA_BERRY)
- return 0;
-
- if (itemId == ITEM_ENIGMA_BERRY)
- {
- temp = gEnigmaBerries[gActiveBattler].itemEffect;
- }
-
- itemEffect = temp;
-
- for (i = 0; i < 6; i++)
- {
- switch (i)
- {
- case 0:
- case 1:
- case 2:
- case 3:
- if (i == effectByte)
- return 0;
- break;
- case 4:
- val = itemEffect[4];
- if (val & 0x20)
- val &= 0xDF;
- j = 0;
- while (val)
- {
- if (val & 1)
- {
- switch (j)
- {
- case 2:
- if (val & 0x10)
- val &= 0xEF;
- case 0:
- if (i == effectByte && (val & effectBit))
- return offset;
- offset++;
- break;
- case 1:
- if (i == effectByte && (val & effectBit))
- return offset;
- offset++;
- break;
- case 3:
- if (i == effectByte && (val & effectBit))
- return offset;
- offset++;
- break;
- case 7:
- if (i == effectByte)
- return 0;
- break;
- }
- }
- j++;
- val >>= 1;
- if (i == effectByte)
- effectBit >>= 1;
- }
- break;
- case 5:
- val = itemEffect[5];
- j = 0;
- while (val)
- {
- if (val & 1)
- {
- switch (j)
- {
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- if (i == effectByte && (val & effectBit))
- return offset;
- offset++;
- break;
- case 7:
- if (i == effectByte)
- return 0;
- break;
- }
- }
- j++;
- val >>= 1;
- if (i == effectByte)
- effectBit >>= 1;
- }
- break;
- }
- }
-
- return offset;
-}
-
-void sub_806CF24(s32 stat)
-{
- gBattlerTarget = gBattlerInMenuId;
- StringCopy(gBattleTextBuff1, gStatNamesTable[gUnknown_08329EC8[stat]]);
- StringCopy(gBattleTextBuff2, gText_StatRose);
- BattleStringExpandPlaceholdersToDisplayedString(gText_PkmnsStatChanged2);
-}
-
-u8 *sub_806CF78(u16 itemId)
-{
- int i;
- const u8 *itemEffect;
-
- if (itemId == ITEM_ENIGMA_BERRY)
- {
- if (gMain.inBattle)
- itemEffect = gEnigmaBerries[gBattlerInMenuId].itemEffect;
- else
- itemEffect = gSaveBlock1Ptr->enigmaBerry.itemEffect;
- }
- else
- {
- itemEffect = gItemEffectTable[itemId - 13];
- }
-
- gPotentialItemEffectBattler = gBattlerInMenuId;
-
- for (i = 0; i < 3; i++)
- {
- if (itemEffect[i] & 0xF)
- sub_806CF24(i * 2);
- if (itemEffect[i] & 0xF0)
- {
- if (i)
- {
- sub_806CF24(i * 2 + 1);
- }
- else
- {
- gBattlerAttacker = gBattlerInMenuId;
- BattleStringExpandPlaceholdersToDisplayedString(gText_PkmnGettingPumped);
- }
- }
- }
-
- if (itemEffect[3] & 0x80)
- {
- gBattlerAttacker = gBattlerInMenuId;
- BattleStringExpandPlaceholdersToDisplayedString(gText_PkmnShroudedInMist);
- }
-
- return gDisplayedStringBattle;
-}
-
-u8 GetNature(struct Pokemon *mon)
-{
- return GetMonData(mon, MON_DATA_PERSONALITY, 0) % 25;
-}
-
-u8 GetNatureFromPersonality(u32 personality)
-{
- return personality % 25;
-}
-
-u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 type, u16 evolutionItem)
-{
- int i;
- u16 targetSpecies = 0;
- u16 species = GetMonData(mon, MON_DATA_SPECIES, 0);
- u16 heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0);
- u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0);
- u8 level;
- u16 friendship;
- u8 beauty = GetMonData(mon, MON_DATA_BEAUTY, 0);
- u16 upperPersonality = personality >> 16;
- u8 holdEffect;
-
- if (heldItem == ITEM_ENIGMA_BERRY)
- holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect;
- else
- holdEffect = ItemId_GetHoldEffect(heldItem);
-
- if (holdEffect == 38 && type != 3)
- return 0;
-
- switch (type)
- {
- case 0:
- level = GetMonData(mon, MON_DATA_LEVEL, 0);
- friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, 0);
-
- for (i = 0; i < 5; i++)
- {
- switch (gEvolutionTable[species][i].method)
- {
- case EVO_FRIENDSHIP:
- if (friendship >= 220)
- targetSpecies = gEvolutionTable[species][i].targetSpecies;
- break;
- case EVO_FRIENDSHIP_DAY:
- RtcCalcLocalTime();
- if (gLocalTime.hours >= 12 && gLocalTime.hours < 24 && friendship >= 220)
- targetSpecies = gEvolutionTable[species][i].targetSpecies;
- break;
- case EVO_FRIENDSHIP_NIGHT:
- RtcCalcLocalTime();
- if (gLocalTime.hours >= 0 && gLocalTime.hours < 12 && friendship >= 220)
- targetSpecies = gEvolutionTable[species][i].targetSpecies;
- break;
- case EVO_LEVEL:
- if (gEvolutionTable[species][i].param <= level)
- targetSpecies = gEvolutionTable[species][i].targetSpecies;
- break;
- case EVO_LEVEL_ATK_GT_DEF:
- if (gEvolutionTable[species][i].param <= level)
- if (GetMonData(mon, MON_DATA_ATK, 0) > GetMonData(mon, MON_DATA_DEF, 0))
- targetSpecies = gEvolutionTable[species][i].targetSpecies;
- break;
- case EVO_LEVEL_ATK_EQ_DEF:
- if (gEvolutionTable[species][i].param <= level)
- if (GetMonData(mon, MON_DATA_ATK, 0) == GetMonData(mon, MON_DATA_DEF, 0))
- targetSpecies = gEvolutionTable[species][i].targetSpecies;
- break;
- case EVO_LEVEL_ATK_LT_DEF:
- if (gEvolutionTable[species][i].param <= level)
- if (GetMonData(mon, MON_DATA_ATK, 0) < GetMonData(mon, MON_DATA_DEF, 0))
- targetSpecies = gEvolutionTable[species][i].targetSpecies;
- break;
- case EVO_LEVEL_SILCOON:
- if (gEvolutionTable[species][i].param <= level && (upperPersonality % 10) <= 4)
- targetSpecies = gEvolutionTable[species][i].targetSpecies;
- break;
- case EVO_LEVEL_CASCOON:
- if (gEvolutionTable[species][i].param <= level && (upperPersonality % 10) > 4)
- targetSpecies = gEvolutionTable[species][i].targetSpecies;
- break;
- case EVO_LEVEL_NINJASK:
- if (gEvolutionTable[species][i].param <= level)
- targetSpecies = gEvolutionTable[species][i].targetSpecies;
- break;
- case EVO_BEAUTY:
- if (gEvolutionTable[species][i].param <= beauty)
- targetSpecies = gEvolutionTable[species][i].targetSpecies;
- break;
- }
- }
- break;
- case 1:
- for (i = 0; i < 5; i++)
- {
- switch (gEvolutionTable[species][i].method)
- {
- case EVO_TRADE:
- targetSpecies = gEvolutionTable[species][i].targetSpecies;
- break;
- case EVO_TRADE_ITEM:
- if (gEvolutionTable[species][i].param == heldItem)
- {
- heldItem = 0;
- SetMonData(mon, MON_DATA_HELD_ITEM, (u8 *)&heldItem);
- targetSpecies = gEvolutionTable[species][i].targetSpecies;
- }
- break;
- }
- }
- break;
- case 2:
- case 3:
- for (i = 0; i < 5; i++)
- {
- if (gEvolutionTable[species][i].method == EVO_ITEM
- && gEvolutionTable[species][i].param == evolutionItem)
- {
- targetSpecies = gEvolutionTable[species][i].targetSpecies;
- break;
- }
- }
- break;
- }
-
- return targetSpecies;
-}
-
-u16 HoennPokedexNumToSpecies(u16 hoennNum)
-{
- u16 species;
-
- if (!hoennNum)
- return 0;
-
- species = 0;
-
- while (species < 411 && gSpeciesToHoennPokedexNum[species] != hoennNum)
- species++;
-
- if (species == 411)
- return 0;
-
- return species + 1;
-}
-
-u16 NationalPokedexNumToSpecies(u16 nationalNum)
-{
- u16 species;
-
- if (!nationalNum)
- return 0;
-
- species = 0;
-
- while (species < 411 && gSpeciesToNationalPokedexNum[species] != nationalNum)
- species++;
-
- if (species == 411)
- return 0;
-
- return species + 1;
-}
-
-u16 NationalToHoennOrder(u16 nationalNum)
-{
- u16 hoennNum;
-
- if (!nationalNum)
- return 0;
-
- hoennNum = 0;
-
- while (hoennNum < 411 && gHoennToNationalOrder[hoennNum] != nationalNum)
- hoennNum++;
-
- if (hoennNum == 411)
- return 0;
-
- return hoennNum + 1;
-}
-
-u16 SpeciesToNationalPokedexNum(u16 species)
-{
- if (!species)
- return 0;
-
- return gSpeciesToNationalPokedexNum[species - 1];
-}
-
-u16 SpeciesToHoennPokedexNum(u16 species)
-{
- if (!species)
- return 0;
-
- return gSpeciesToHoennPokedexNum[species - 1];
-}
-
-u16 HoennToNationalOrder(u16 hoennNum)
-{
- if (!hoennNum)
- return 0;
-
- return gHoennToNationalOrder[hoennNum - 1];
-}
-
-u16 SpeciesToCryId(u16 species)
-{
- if (species <= 250)
- return species;
-
- if (species < 276)
- return 200;
-
- return gSpeciesIdToCryId[species - 276];
-}
-
-void sub_806D544(u16 species, u32 personality, u8 *dest)
-{
- if (species == SPECIES_SPINDA
- && dest != gMonSpritesGfxPtr->sprites[0]
- && dest != gMonSpritesGfxPtr->sprites[2])
- {
- int i;
- for (i = 0; i < 4; i++)
- {
- int j;
- u8 x = gSpindaSpotGraphics[i].x + ((personality & 0x0F) - 8);
- u8 y = gSpindaSpotGraphics[i].y + (((personality & 0xF0) >> 4) - 8);
-
- for (j = 0; j < 16; j++)
- {
- int k;
- s32 row = gSpindaSpotGraphics[i].image[j];
-
- for (k = x; k < x + 16; k++)
- {
- u8 *val = dest + ((k / 8) * 32) + ((k % 8) / 2) + ((y >> 3) << 8) + ((y & 7) << 2);
-
- if (row & 1)
- {
- if (k & 1)
- {
- if ((u8)((*val & 0xF0) - 0x10) <= 0x20)
- *val += 0x40;
- }
- else
- {
- if ((u8)((*val & 0xF) - 0x01) <= 0x02)
- *val += 0x04;
- }
- }
-
- row >>= 1;
- }
-
- y++;
- }
-
- personality >>= 8;
- }
- }
-}
-
-void DrawSpindaSpots(u16 species, u32 personality, u8 *dest, u8 a4)
-{
- if (species == SPECIES_SPINDA && a4)
- {
- int i;
- for (i = 0; i < 4; i++)
- {
- int j;
- u8 x = gSpindaSpotGraphics[i].x + ((personality & 0x0F) - 8);
- u8 y = gSpindaSpotGraphics[i].y + (((personality & 0xF0) >> 4) - 8);
-
- for (j = 0; j < 16; j++)
- {
- int k;
- s32 row = gSpindaSpotGraphics[i].image[j];
-
- for (k = x; k < x + 16; k++)
- {
- u8 *val = dest + ((k / 8) * 32) + ((k % 8) / 2) + ((y >> 3) << 8) + ((y & 7) << 2);
-
- if (row & 1)
- {
- if (k & 1)
- {
- if ((u8)((*val & 0xF0) - 0x10) <= 0x20)
- *val += 0x40;
- }
- else
- {
- if ((u8)((*val & 0xF) - 0x01) <= 0x02)
- *val += 0x04;
- }
- }
-
- row >>= 1;
- }
-
- y++;
- }
-
- personality >>= 8;
- }
- }
-}
-
-void EvolutionRenameMon(struct Pokemon *mon, u16 oldSpecies, u16 newSpecies)
-{
- u8 language;
- GetMonData(mon, MON_DATA_NICKNAME, gStringVar1);
- language = GetMonData(mon, MON_DATA_LANGUAGE, &language);
- if (language == GAME_LANGUAGE && !StringCompare(gSpeciesNames[oldSpecies], gStringVar1))
- SetMonData(mon, MON_DATA_NICKNAME, gSpeciesNames[newSpecies]);
-}
-
-bool8 sub_806D7EC(void)
-{
- bool8 retVal = FALSE;
- switch (gLinkPlayers[GetMultiplayerId()].lp_field_18)
- {
- case 0:
- case 3:
- retVal = FALSE;
- break;
- case 1:
- case 2:
- retVal = TRUE;
- break;
- }
- return retVal;
-}
-
-bool16 sub_806D82C(u8 id)
-{
- bool16 retVal = FALSE;
- switch (gLinkPlayers[id].lp_field_18)
- {
- case 0:
- case 3:
- retVal = FALSE;
- break;
- case 1:
- case 2:
- retVal = TRUE;
- break;
- }
- return retVal;
-}
-
-s32 GetBattlerMultiplayerId(u16 a1)
-{
- s32 id;
- for (id = 0; id < MAX_LINK_PLAYERS; id++)
- if (gLinkPlayers[id].lp_field_18 == a1)
- break;
- return id;
-}
-
-u8 GetTrainerEncounterMusicId(u16 trainerOpponentId)
-{
- if (InBattlePyramid())
- return GetTrainerEncounterMusicIdInBattlePyramind(trainerOpponentId);
- if (sub_81D5C18())
- return sub_81D63C8(trainerOpponentId);
- return TRAINER_ENCOUNTER_MUSIC(trainerOpponentId);
-}
-
-u16 nature_stat_mod(u8 nature, u16 n, u8 statIndex)
-{
- if (statIndex < 1 || statIndex > 5)
- {
- // should just be "return n", but it wouldn't match without this
- u16 retVal = n;
- retVal++;
- retVal--;
- return retVal;
- }
-
- switch (gNatureStatTable[nature][statIndex - 1])
- {
- case 1:
- return (u16)(n * 110) / 100;
- case -1:
- return (u16)(n * 90) / 100;
- }
-
- return n;
-}
-
-void AdjustFriendship(struct Pokemon *mon, u8 event)
-{
- u16 species, heldItem;
- u8 holdEffect;
-
- if (sub_806F104())
- return;
-
- species = GetMonData(mon, MON_DATA_SPECIES2, 0);
- heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0);
-
- if (heldItem == ITEM_ENIGMA_BERRY)
- {
- if (gMain.inBattle)
- holdEffect = gEnigmaBerries[0].holdEffect;
- else
- holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect;
- }
- else
- {
- holdEffect = ItemId_GetHoldEffect(heldItem);
- }
-
- if (species && species != SPECIES_EGG)
- {
- u8 friendshipLevel = 0;
- s16 friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, 0);
- if (friendship > 99)
- friendshipLevel++;
- if (friendship > 199)
- friendshipLevel++;
- if ((event != 5 || !(Random() & 1))
- && (event != 3
- || ((gBattleTypeFlags & BATTLE_TYPE_TRAINER)
- && (gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_ELITE_FOUR
- || gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_LEADER
- || gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_CHAMPION))))
- {
- s8 mod = gUnknown_08329ECE[event][friendshipLevel];
- if (mod > 0 && holdEffect == HOLD_EFFECT_HAPPINESS_UP)
- mod = (150 * mod) / 100;
- friendship += mod;
- if (mod > 0)
- {
- if (GetMonData(mon, MON_DATA_POKEBALL, 0) == ITEM_LUXURY_BALL)
- friendship++;
- if (GetMonData(mon, MON_DATA_MET_LOCATION, 0) == sav1_map_get_name())
- friendship++;
- }
- if (friendship < 0)
- friendship = 0;
- if (friendship > 255)
- friendship = 255;
- SetMonData(mon, MON_DATA_FRIENDSHIP, &friendship);
- }
- }
-}
-
-void MonGainEVs(struct Pokemon *mon, u16 defeatedSpecies)
-{
- u8 evs[NUM_STATS];
- u16 evIncrease = 0;
- u16 totalEVs = 0;
- u16 heldItem;
- u8 holdEffect;
- int i;
-
- for (i = 0; i < NUM_STATS; i++)
- {
- evs[i] = GetMonData(mon, MON_DATA_HP_EV + i, 0);
- totalEVs += evs[i];
- }
-
- for (i = 0; i < NUM_STATS; i++)
- {
- u8 hasHadPokerus;
- int multiplier;
-
- if (totalEVs >= MAX_TOTAL_EVS)
- break;
-
- hasHadPokerus = CheckPartyHasHadPokerus(mon, 0);
-
- if (hasHadPokerus)
- multiplier = 2;
- else
- multiplier = 1;
-
- switch (i)
- {
- case 0:
- evIncrease = gBaseStats[defeatedSpecies].evYield_HP * multiplier;
- break;
- case 1:
- evIncrease = gBaseStats[defeatedSpecies].evYield_Attack * multiplier;
- break;
- case 2:
- evIncrease = gBaseStats[defeatedSpecies].evYield_Defense * multiplier;
- break;
- case 3:
- evIncrease = gBaseStats[defeatedSpecies].evYield_Speed * multiplier;
- break;
- case 4:
- evIncrease = gBaseStats[defeatedSpecies].evYield_SpAttack * multiplier;
- break;
- case 5:
- evIncrease = gBaseStats[defeatedSpecies].evYield_SpDefense * multiplier;
- break;
- }
-
- heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0);
-
- if (heldItem == ITEM_ENIGMA_BERRY)
- {
- if (gMain.inBattle)
- holdEffect = gEnigmaBerries[0].holdEffect;
- else
- holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect;
- }
- else
- {
- holdEffect = ItemId_GetHoldEffect(heldItem);
- }
-
- if (holdEffect == HOLD_EFFECT_MACHO_BRACE)
- evIncrease *= 2;
-
- if (totalEVs + (s16)evIncrease > MAX_TOTAL_EVS)
- evIncrease = ((s16)evIncrease + MAX_TOTAL_EVS) - (totalEVs + evIncrease);
-
- if (evs[i] + (s16)evIncrease > 255)
- {
- int val1 = (s16)evIncrease + 255;
- int val2 = evs[i] + evIncrease;
- evIncrease = val1 - val2;
- }
-
- evs[i] += evIncrease;
- totalEVs += evIncrease;
- SetMonData(mon, MON_DATA_HP_EV + i, &evs[i]);
- }
-}
-
-u16 GetMonEVCount(struct Pokemon *mon)
-{
- int i;
- u16 count = 0;
-
- for (i = 0; i < NUM_STATS; i++)
- count += GetMonData(mon, MON_DATA_HP_EV + i, 0);
-
- return count;
-}
-
-void RandomlyGivePartyPokerus(struct Pokemon *party)
-{
- u16 rnd = Random();
- if (rnd == 0x4000 || rnd == 0x8000 || rnd == 0xC000)
- {
- struct Pokemon *mon;
-
- do
- {
- do
- {
- rnd = Random() % PARTY_SIZE;
- mon = &party[rnd];
- }
- while (!GetMonData(mon, MON_DATA_SPECIES, 0));
- }
- while (GetMonData(mon, MON_DATA_IS_EGG, 0));
-
- if (!(CheckPartyHasHadPokerus(party, gBitTable[rnd])))
- {
- u8 rnd2;
-
- do
- {
- rnd2 = Random();
- }
- while ((rnd2 & 0x7) == 0);
-
- if (rnd2 & 0xF0)
- rnd2 &= 0x7;
-
- rnd2 |= (rnd2 << 4);
- rnd2 &= 0xF3;
- rnd2++;
-
- SetMonData(&party[rnd], MON_DATA_POKERUS, &rnd2);
- }
- }
-}
-
-u8 CheckPartyPokerus(struct Pokemon *party, u8 selection)
-{
- u8 retVal;
-
- int partyIndex = 0;
- unsigned curBit = 1;
- retVal = 0;
-
- if (selection)
- {
- do
- {
- if ((selection & 1) && (GetMonData(&party[partyIndex], MON_DATA_POKERUS, 0) & 0xF))
- retVal |= curBit;
- partyIndex++;
- curBit <<= 1;
- selection >>= 1;
- }
- while (selection);
- }
- else if (GetMonData(&party[0], MON_DATA_POKERUS, 0) & 0xF)
- {
- retVal = 1;
- }
-
- return retVal;
-}
-
-u8 CheckPartyHasHadPokerus(struct Pokemon *party, u8 selection)
-{
- u8 retVal;
-
- int partyIndex = 0;
- unsigned curBit = 1;
- retVal = 0;
-
- if (selection)
- {
- do
- {
- if ((selection & 1) && GetMonData(&party[partyIndex], MON_DATA_POKERUS, 0))
- retVal |= curBit;
- partyIndex++;
- curBit <<= 1;
- selection >>= 1;
- }
- while (selection);
- }
- else if (GetMonData(&party[0], MON_DATA_POKERUS, 0))
- {
- retVal = 1;
- }
-
- return retVal;
-}
-
-void UpdatePartyPokerusTime(u16 days)
-{
- int i;
- for (i = 0; i < PARTY_SIZE; i++)
- {
- if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, 0))
- {
- u8 pokerus = GetMonData(&gPlayerParty[i], MON_DATA_POKERUS, 0);
- if (pokerus & 0xF)
- {
- if ((pokerus & 0xF) < days || days > 4)
- pokerus &= 0xF0;
- else
- pokerus -= days;
-
- if (pokerus == 0)
- pokerus = 0x10;
-
- SetMonData(&gPlayerParty[i], MON_DATA_POKERUS, &pokerus);
- }
- }
- }
-}
-
-void PartySpreadPokerus(struct Pokemon *party)
-{
- if ((Random() % 3) == 0)
- {
- int i;
- for (i = 0; i < PARTY_SIZE; i++)
- {
- if (GetMonData(&party[i], MON_DATA_SPECIES, 0))
- {
- u8 pokerus = GetMonData(&party[i], MON_DATA_POKERUS, 0);
- u8 curPokerus = pokerus;
- if (pokerus)
- {
- if (pokerus & 0xF)
- {
- // spread to adjacent party members
- if (i != 0 && !(GetMonData(&party[i - 1], MON_DATA_POKERUS, 0) & 0xF0))
- SetMonData(&party[i - 1], MON_DATA_POKERUS, &curPokerus);
- if (i != (PARTY_SIZE - 1) && !(GetMonData(&party[i + 1], MON_DATA_POKERUS, 0) & 0xF0))
- {
- SetMonData(&party[i + 1], MON_DATA_POKERUS, &curPokerus);
- i++;
- }
- }
- }
- }
- }
- }
-}
-
-bool8 TryIncrementMonLevel(struct Pokemon *mon)
-{
- u16 species = GetMonData(mon, MON_DATA_SPECIES, 0);
- u8 nextLevel = GetMonData(mon, MON_DATA_LEVEL, 0) + 1;
- u32 expPoints = GetMonData(mon, MON_DATA_EXP, 0);
- if (expPoints > gExperienceTables[gBaseStats[species].growthRate][MAX_MON_LEVEL])
- {
- expPoints = gExperienceTables[gBaseStats[species].growthRate][MAX_MON_LEVEL];
- SetMonData(mon, MON_DATA_EXP, &expPoints);
- }
- if (nextLevel > MAX_MON_LEVEL || expPoints < gExperienceTables[gBaseStats[species].growthRate][nextLevel])
- {
- return FALSE;
- }
- else
- {
- SetMonData(mon, MON_DATA_LEVEL, &nextLevel);
- return TRUE;
- }
-}
-
-u32 CanMonLearnTMHM(struct Pokemon *mon, u8 tm)
-{
- u16 species = GetMonData(mon, MON_DATA_SPECIES2, 0);
- if (species == SPECIES_EGG)
- {
- return 0;
- }
- else if (tm < 32)
- {
- u32 mask = 1 << tm;
- return gTMHMLearnsets[species][0] & mask;
- }
- else
- {
- u32 mask = 1 << (tm - 32);
- return gTMHMLearnsets[species][1] & mask;
- }
-}
-
-u32 CanSpeciesLearnTMHM(u16 species, u8 tm)
-{
- if (species == SPECIES_EGG)
- {
- return 0;
- }
- else if (tm < 32)
- {
- u32 mask = 1 << tm;
- return gTMHMLearnsets[species][0] & mask;
- }
- else
- {
- u32 mask = 1 << (tm - 32);
- return gTMHMLearnsets[species][1] & mask;
- }
-}
-
-u8 GetMoveRelearnerMoves(struct Pokemon *mon, u16 *moves)
-{
- u16 learnedMoves[4];
- u8 numMoves = 0;
- u16 species = GetMonData(mon, MON_DATA_SPECIES, 0);
- u8 level = GetMonData(mon, MON_DATA_LEVEL, 0);
- int i, j, k;
-
- for (i = 0; i < 4; i++)
- learnedMoves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, 0);
-
- for (i = 0; i < 20; i++)
- {
- u16 moveLevel;
-
- if (gLevelUpLearnsets[species][i] == 0xFFFF)
- break;
-
- moveLevel = gLevelUpLearnsets[species][i] & 0xFE00;
-
- if (moveLevel <= (level << 9))
- {
- for (j = 0; j < 4 && learnedMoves[j] != (gLevelUpLearnsets[species][i] & 0x1FF); j++)
- ;
-
- if (j == 4)
- {
- for (k = 0; k < numMoves && moves[k] != (gLevelUpLearnsets[species][i] & 0x1FF); k++)
- ;
-
- if (k == numMoves)
- moves[numMoves++] = gLevelUpLearnsets[species][i] & 0x1FF;
- }
- }
- }
-
- return numMoves;
-}
-
-u8 GetLevelUpMovesBySpecies(u16 species, u16 *moves)
-{
- u8 numMoves = 0;
- int i;
-
- for (i = 0; i < 20 && gLevelUpLearnsets[species][i] != 0xFFFF; i++)
- moves[numMoves++] = gLevelUpLearnsets[species][i] & 0x1FF;
-
- return numMoves;
-}
-
-u8 GetNumberOfRelearnableMoves(struct Pokemon *mon)
-{
- u16 learnedMoves[4];
- u16 moves[20];
- u8 numMoves = 0;
- u16 species = GetMonData(mon, MON_DATA_SPECIES2, 0);
- u8 level = GetMonData(mon, MON_DATA_LEVEL, 0);
- int i, j, k;
-
- if (species == SPECIES_EGG)
- return 0;
-
- for (i = 0; i < 4; i++)
- learnedMoves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, 0);
-
- for (i = 0; i < 20; i++)
- {
- u16 moveLevel;
-
- if (gLevelUpLearnsets[species][i] == 0xFFFF)
- break;
-
- moveLevel = gLevelUpLearnsets[species][i] & 0xFE00;
-
- if (moveLevel <= (level << 9))
- {
- for (j = 0; j < 4 && learnedMoves[j] != (gLevelUpLearnsets[species][i] & 0x1FF); j++)
- ;
-
- if (j == 4)
- {
- for (k = 0; k < numMoves && moves[k] != (gLevelUpLearnsets[species][i] & 0x1FF); k++)
- ;
-
- if (k == numMoves)
- moves[numMoves++] = gLevelUpLearnsets[species][i] & 0x1FF;
- }
- }
- }
-
- return numMoves;
-}
-
-u16 SpeciesToPokedexNum(u16 species)
-{
- if (IsNationalPokedexEnabled())
- {
- return SpeciesToNationalPokedexNum(species);
- }
- else
- {
- species = SpeciesToHoennPokedexNum(species);
- if (species <= 202)
- return species;
- return 0xFFFF;
- }
-}
-
-bool32 sub_806E3F8(u16 species)
-{
- if (SpeciesToHoennPokedexNum(species) > 202)
- return FALSE;
- else
- return TRUE;
-}
-
-void ClearBattleMonForms(void)
-{
- int i;
- for (i = 0; i < 4; i++)
- gBattleMonForms[i] = 0;
-}
-
-u16 GetBattleBGM(void)
-{
- if (gBattleTypeFlags & BATTLE_TYPE_KYOGRE_GROUDON)
- return MUS_BATTLE34;
- if (gBattleTypeFlags & BATTLE_TYPE_REGI)
- return MUS_BATTLE36;
- if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000))
- return MUS_BATTLE20;
- if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
- {
- u8 trainerClass;
-
- if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
- trainerClass = GetFrontierOpponentClass(gTrainerBattleOpponent_A);
- else if (gBattleTypeFlags & BATTLE_TYPE_x4000000)
- trainerClass = TRAINER_CLASS_EXPERT;
- else
- trainerClass = gTrainers[gTrainerBattleOpponent_A].trainerClass;
-
- switch (trainerClass)
- {
- case TRAINER_CLASS_AQUA_LEADER:
- case TRAINER_CLASS_MAGMA_LEADER:
- return MUS_BATTLE30;
- case TRAINER_CLASS_TEAM_AQUA:
- case TRAINER_CLASS_TEAM_MAGMA:
- case TRAINER_CLASS_AQUA_ADMIN:
- case TRAINER_CLASS_MAGMA_ADMIN:
- return MUS_BATTLE31;
- case TRAINER_CLASS_LEADER:
- return MUS_BATTLE32;
- case TRAINER_CLASS_CHAMPION:
- return MUS_BATTLE33;
- case TRAINER_CLASS_PKMN_TRAINER_3:
- if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
- return MUS_BATTLE35;
- if (!StringCompare(gTrainers[gTrainerBattleOpponent_A].trainerName, gText_BattleWallyName))
- return MUS_BATTLE20;
- return MUS_BATTLE35;
- case TRAINER_CLASS_ELITE_FOUR:
- return MUS_BATTLE38;
- case TRAINER_CLASS_SALON_MAIDEN:
- case TRAINER_CLASS_DOME_ACE:
- case TRAINER_CLASS_PALACE_MAVEN:
- case TRAINER_CLASS_ARENA_TYCOON:
- case TRAINER_CLASS_FACTORY_HEAD:
- case TRAINER_CLASS_PIKE_QUEEN:
- case TRAINER_CLASS_PYRAMID_KING:
- return MUS_VS_FRONT;
- default:
- return MUS_BATTLE20;
- }
- }
- return MUS_BATTLE27;
-}
-
-void PlayBattleBGM(void)
-{
- ResetMapMusic();
- m4aMPlayAllStop();
- PlayBGM(GetBattleBGM());
-}
-
-void PlayMapChosenOrBattleBGM(u16 songId)
-{
- ResetMapMusic();
- m4aMPlayAllStop();
- if (songId)
- PlayNewMapMusic(songId);
- else
- PlayNewMapMusic(GetBattleBGM());
-}
-
-void sub_806E694(u16 songId)
-{
- u8 taskId;
-
- ResetMapMusic();
- m4aMPlayAllStop();
-
- taskId = CreateTask(sub_806E6CC, 0);
- gTasks[taskId].data[0] = songId;
-}
-
-static void sub_806E6CC(u8 taskId)
-{
- if (gTasks[taskId].data[0])
- PlayNewMapMusic(gTasks[taskId].data[0]);
- else
- PlayNewMapMusic(GetBattleBGM());
- DestroyTask(taskId);
-}
-
-const u8 *GetMonFrontSpritePal(struct Pokemon *mon)
-{
- u16 species = GetMonData(mon, MON_DATA_SPECIES2, 0);
- u32 otId = GetMonData(mon, MON_DATA_OT_ID, 0);
- u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0);
- return GetFrontSpritePalFromSpeciesAndPersonality(species, otId, personality);
-}
-
-// Extracts the upper 16 bits of a 32-bit number
-#define HIHALF(n) (((n) & 0xFFFF0000) >> 16)
-
-// Extracts the lower 16 bits of a 32-bit number
-#define LOHALF(n) ((n) & 0xFFFF)
-
-const u8 *GetFrontSpritePalFromSpeciesAndPersonality(u16 species, u32 otId, u32 personality)
-{
- u32 shinyValue;
-
- if (species > SPECIES_EGG)
- return gMonPaletteTable[0].data;
-
- shinyValue = HIHALF(otId) ^ LOHALF(otId) ^ HIHALF(personality) ^ LOHALF(personality);
- if (shinyValue < 8)
- return gMonShinyPaletteTable[species].data;
- else
- return gMonPaletteTable[species].data;
-}
-
-const struct CompressedSpritePalette *sub_806E794(struct Pokemon *mon)
-{
- u16 species = GetMonData(mon, MON_DATA_SPECIES2, 0);
- u32 otId = GetMonData(mon, MON_DATA_OT_ID, 0);
- u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0);
- return GetMonSpritePalStructFromOtIdPersonality(species, otId, personality);
-}
-
-const struct CompressedSpritePalette *GetMonSpritePalStructFromOtIdPersonality(u16 species, u32 otId , u32 personality)
-{
- u32 shinyValue;
-
- shinyValue = HIHALF(otId) ^ LOHALF(otId) ^ HIHALF(personality) ^ LOHALF(personality);
- if (shinyValue < 8)
- return &gMonShinyPaletteTable[species];
- else
- return &gMonPaletteTable[species];
-}
-
-bool32 IsHMMove2(u16 move)
-{
- int i = 0;
- while (gHMMoves[i] != 0xFFFF)
- {
- if (gHMMoves[i++] == move)
- return TRUE;
- }
- return FALSE;
-}
-
-bool8 IsPokeSpriteNotFlipped(u16 species)
-{
- return gBaseStats[species].noFlip;
-}
-
-s8 GetMonFlavorRelation(struct Pokemon *mon, u8 flavor)
-{
- u8 nature = GetNature(mon);
- return gPokeblockFlavorCompatibilityTable[nature * 5 + flavor];
-}
-
-s8 GetFlavorRelationByPersonality(u32 personality, u8 flavor)
-{
- u8 nature = GetNatureFromPersonality(personality);
- return gPokeblockFlavorCompatibilityTable[nature * 5 + flavor];
-}
-
-bool8 IsTradedMon(struct Pokemon *mon)
-{
- u8 otName[OT_NAME_LENGTH + 1];
- u32 otId;
- GetMonData(mon, MON_DATA_OT_NAME, otName);
- otId = GetMonData(mon, MON_DATA_OT_ID, 0);
- return IsOtherTrainer(otId, otName);
-}
-
-bool8 IsOtherTrainer(u32 otId, u8 *otName)
-{
- if (otId ==
- (gSaveBlock2Ptr->playerTrainerId[0]
- | (gSaveBlock2Ptr->playerTrainerId[1] << 8)
- | (gSaveBlock2Ptr->playerTrainerId[2] << 16)
- | (gSaveBlock2Ptr->playerTrainerId[3] << 24)))
- {
- int i;
-
- for (i = 0; otName[i] != EOS; i++)
- if (otName[i] != gSaveBlock2Ptr->playerName[i])
- return TRUE;
- return FALSE;
- }
-
- return TRUE;
-}
-
-void MonRestorePP(struct Pokemon *mon)
-{
- BoxMonRestorePP(&mon->box);
-}
-
-void BoxMonRestorePP(struct BoxPokemon *boxMon)
-{
- int i;
-
- for (i = 0; i < 4; i++)
- {
- if (GetBoxMonData(boxMon, MON_DATA_MOVE1 + i, 0))
- {
- u16 move = GetBoxMonData(boxMon, MON_DATA_MOVE1 + i, 0);
- u16 bonus = GetBoxMonData(boxMon, MON_DATA_PP_BONUSES, 0);
- u8 pp = CalculatePPWithBonus(move, bonus, i);
- SetBoxMonData(boxMon, MON_DATA_PP1 + i, &pp);
- }
- }
-}
-
-void sub_806E994(void)
-{
- gLastUsedAbility = gBattleStruct->field_B0;
-
- gBattleTextBuff1[0] = B_BUFF_PLACEHOLDER_BEGIN;
- gBattleTextBuff1[1] = B_BUFF_MON_NICK_WITH_PREFIX;
- gBattleTextBuff1[2] = gBattleStruct->field_49;
- gBattleTextBuff1[4] = B_BUFF_EOS;
-
- if (!GetBattlerSide(gBattleStruct->field_49))
- gBattleTextBuff1[3] = pokemon_order_func(gBattlerPartyIndexes[gBattleStruct->field_49]);
- else
- gBattleTextBuff1[3] = gBattlerPartyIndexes[gBattleStruct->field_49];
-
- PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff2, gBattlerInMenuId, pokemon_order_func(gBattlerPartyIndexes[gBattlerInMenuId]))
-
- BattleStringExpandPlaceholders(gText_PkmnsXPreventsSwitching, gStringVar4);
-}
-
-struct PokeItem
-{
- u16 species;
- u16 item;
-};
-
-extern const struct PokeItem gAlteringCaveWildMonHeldItems[9];
-
-static s32 GetWildMonTableIdInAlteringCave(u16 species)
-{
- s32 i;
- for (i = 0; i < (s32) ARRAY_COUNT(gAlteringCaveWildMonHeldItems); i++)
- if (gAlteringCaveWildMonHeldItems[i].species == species)
- return i;
- return 0;
-}
-
-void SetWildMonHeldItem(void)
-{
- if (!(gBattleTypeFlags & (BATTLE_TYPE_LEGENDARY | BATTLE_TYPE_TRAINER | BATTLE_TYPE_PYRAMID | BATTLE_TYPE_PIKE)))
- {
- u16 rnd = Random() % 100;
- u16 species = GetMonData(&gEnemyParty[0], MON_DATA_SPECIES, 0);
- u16 var1 = 45;
- u16 var2 = 95;
- if (!GetMonData(&gPlayerParty[0], MON_DATA_SANITY_BIT3, 0)
- && GetMonAbility(&gPlayerParty[0]) == ABILITY_COMPOUND_EYES)
- {
- var1 = 20;
- var2 = 80;
- }
- if (gMapHeader.mapDataId == 0x1A4)
- {
- s32 alteringCaveId = GetWildMonTableIdInAlteringCave(species);
- if (alteringCaveId != 0)
- {
- if (rnd < var2)
- return;
- SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gAlteringCaveWildMonHeldItems[alteringCaveId].item);
- }
- else
- {
- if (rnd < var1)
- return;
- if (rnd < var2)
- SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gBaseStats[species].item1);
- else
- SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gBaseStats[species].item2);
- }
- }
- else
- {
- if (gBaseStats[species].item1 == gBaseStats[species].item2 && gBaseStats[species].item1 != 0)
- {
- SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gBaseStats[species].item1);
- }
- else
- {
- if (rnd < var1)
- return;
- if (rnd < var2)
- SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gBaseStats[species].item1);
- else
- SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gBaseStats[species].item2);
- }
- }
- }
-}
-
-bool8 IsMonShiny(struct Pokemon *mon)
-{
- u32 otId = GetMonData(mon, MON_DATA_OT_ID, 0);
- u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0);
- return IsShinyOtIdPersonality(otId, personality);
-}
-
-bool8 IsShinyOtIdPersonality(u32 otId, u32 personality)
-{
- bool8 retVal = FALSE;
- u32 shinyValue = HIHALF(otId) ^ LOHALF(otId) ^ HIHALF(personality) ^ LOHALF(personality);
- if (shinyValue < 8)
- retVal = TRUE;
- return retVal;
-}
-
-const u8 *GetTrainerPartnerName(void)
-{
- if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
- {
- if (gPartnerTrainerId == STEVEN_PARTNER_ID)
- {
- return gTrainers[TRAINER_STEVEN].trainerName;
- }
- else
- {
- GetFrontierTrainerName(gStringVar1, gPartnerTrainerId);
- return gStringVar1;
- }
- }
- else
- {
- u8 id = GetMultiplayerId();
- return gLinkPlayers[GetBattlerMultiplayerId(gLinkPlayers[id].lp_field_18 ^ 2)].name;
- }
-}
-
-#define READ_PTR_FROM_TASK(taskId, dataId) \
- (void*)( \
- ((u16)(gTasks[taskId].data[dataId]) | \
- ((u16)(gTasks[taskId].data[dataId + 1]) << 0x10)))
-
-#define STORE_PTR_IN_TASK(ptr, taskId, dataId) \
-{ \
- gTasks[taskId].data[dataId] = (u32)(ptr); \
- gTasks[taskId].data[dataId + 1] = (u32)(ptr) >> 0x10; \
-}
-
-static void Task_AnimateAfterDelay(u8 taskId)
-{
- if (--gTasks[taskId].data[3] == 0)
- {
- LaunchAnimationTaskForFrontSprite(READ_PTR_FROM_TASK(taskId, 0), gTasks[taskId].data[2]);
- DestroyTask(taskId);
- }
-}
-
-static void Task_PokemonSummaryAnimateAfterDelay(u8 taskId)
-{
- if (--gTasks[taskId].data[3] == 0)
- {
- StartMonSummaryAnimation(READ_PTR_FROM_TASK(taskId, 0), gTasks[taskId].data[2]);
- sub_81C488C(0xFF);
- DestroyTask(taskId);
- }
-}
-
-void BattleAnimateFrontSprite(struct Sprite* sprite, u16 species, bool8 noCry, u8 arg3)
-{
- if (gHitMarker & HITMARKER_NO_ANIMATIONS && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000)))
- DoMonFrontSpriteAnimation(sprite, species, noCry, arg3 | 0x80);
- else
- DoMonFrontSpriteAnimation(sprite, species, noCry, arg3);
-}
-
-extern void SpriteCallbackDummy_2(struct Sprite*);
-
-void DoMonFrontSpriteAnimation(struct Sprite* sprite, u16 species, bool8 noCry, u8 arg3)
-{
- s8 pan;
- switch (arg3 & 0x7F)
- {
- case 0:
- pan = -25;
- break;
- case 1:
- pan = 25;
- break;
- default:
- pan = 0;
- break;
- }
- if (arg3 & 0x80)
- {
- if (!noCry)
- PlayCry1(species, pan);
- sprite->callback = SpriteCallbackDummy;
- }
- else
- {
- if (!noCry)
- {
- PlayCry1(species, pan);
- if (HasTwoFramesAnimation(species))
- StartSpriteAnim(sprite, 1);
- }
- if (gMonAnimationDelayTable[species - 1] != 0)
- {
- u8 taskId = CreateTask(Task_AnimateAfterDelay, 0);
- STORE_PTR_IN_TASK(sprite, taskId, 0);
- gTasks[taskId].data[2] = gMonFrontAnimIdsTable[species - 1];
- gTasks[taskId].data[3] = gMonAnimationDelayTable[species - 1];
- }
- else
- {
- LaunchAnimationTaskForFrontSprite(sprite, gMonFrontAnimIdsTable[species - 1]);
- }
- sprite->callback = SpriteCallbackDummy_2;
- }
-}
-
-void PokemonSummaryDoMonAnimation(struct Sprite* sprite, u16 species, bool8 oneFrame)
-{
- if (!oneFrame && HasTwoFramesAnimation(species))
- StartSpriteAnim(sprite, 1);
- if (gMonAnimationDelayTable[species - 1] != 0)
- {
- u8 taskId = CreateTask(Task_PokemonSummaryAnimateAfterDelay, 0);
- STORE_PTR_IN_TASK(sprite, taskId, 0);
- gTasks[taskId].data[2] = gMonFrontAnimIdsTable[species - 1];
- gTasks[taskId].data[3] = gMonAnimationDelayTable[species - 1];
- sub_81C488C(taskId);
- SetSpriteCB_MonAnimDummy(sprite);
- }
- else
- {
- StartMonSummaryAnimation(sprite, gMonFrontAnimIdsTable[species - 1]);
- }
-}
-
-void sub_806EE98(void)
-{
- u8 delayTaskId = FindTaskIdByFunc(Task_PokemonSummaryAnimateAfterDelay);
- if (delayTaskId != 0xFF)
- DestroyTask(delayTaskId);
-}
-
-void BattleAnimateBackSprite(struct Sprite* sprite, u16 species)
-{
- if (gHitMarker & HITMARKER_NO_ANIMATIONS && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000)))
- {
- sprite->callback = SpriteCallbackDummy;
- }
- else
- {
- LaunchAnimationTaskForBackSprite(sprite, GetSpeciesBackAnimSet(species));
- sprite->callback = SpriteCallbackDummy_2;
- }
-}
-
-u8 sub_806EF08(u8 arg0)
-{
- s32 i;
- s32 var = 0;
- u8 multiplayerId = GetMultiplayerId();
- switch (gLinkPlayers[multiplayerId].lp_field_18)
- {
- case 0:
- case 2:
- var = (arg0 != 0) ? 1 : 3;
- break;
- case 1:
- case 3:
- var = (arg0 != 0) ? 2 : 0;
- break;
- }
- for (i = 0; i < 4; i++)
- {
- if (gLinkPlayers[i].lp_field_18 == (s16)(var))
- break;
- }
- return i;
-}
-
-u8 sub_806EF84(u8 arg0, u8 arg1)
-{
- s32 i;
- s32 var = 0;
- switch (gLinkPlayers[arg1].lp_field_18)
- {
- case 0:
- case 2:
- var = (arg0 != 0) ? 1 : 3;
- break;
- case 1:
- case 3:
- var = (arg0 != 0) ? 2 : 0;
- break;
- }
- for (i = 0; i < 4; i++)
- {
- if (gLinkPlayers[i].lp_field_18 == (s16)(var))
- break;
- }
- return i;
-}
-
-extern const u8 gFacilityClassToPicIndex[];
-
-u16 sub_806EFF0(u16 arg0)
-{
- return gFacilityClassToPicIndex[arg0];
-}
-
-u16 PlayerGenderToFrontTrainerPicId(u8 playerGender)
-{
- if (playerGender)
- return sub_806EFF0(0x3F);
- else
- return sub_806EFF0(0x3C);
-}
-
-extern const u8 gTrainerClassNames[][13];
-
-void HandleSetPokedexFlag(u16 nationalNum, u8 caseId, u32 personality)
-{
- u8 getFlagCaseId = (caseId == FLAG_SET_SEEN) ? FLAG_GET_SEEN : FLAG_GET_CAUGHT;
- if (!GetSetPokedexFlag(nationalNum, getFlagCaseId)) // don't set if it's already set
- {
- GetSetPokedexFlag(nationalNum, caseId);
- if (NationalPokedexNumToSpecies(nationalNum) == SPECIES_UNOWN)
- gSaveBlock2Ptr->pokedex.unownPersonality = personality;
- if (NationalPokedexNumToSpecies(nationalNum) == SPECIES_SPINDA)
- gSaveBlock2Ptr->pokedex.spindaPersonality = personality;
- }
-}
-
-const u8 *GetTrainerClassNameFromId(u16 trainerId)
-{
- if (trainerId > NO_OF_TRAINERS)
- trainerId = 0;
- return gTrainerClassNames[gTrainers[trainerId].trainerClass];
-}
-
-const u8 *GetTrainerNameFromId(u16 trainerId)
-{
- if (trainerId > NO_OF_TRAINERS)
- trainerId = 0;
- return gTrainers[trainerId].trainerName;
-}
-
-bool8 HasTwoFramesAnimation(u16 species)
-{
- return (species != SPECIES_CASTFORM
- && species != SPECIES_DEOXYS
- && species != SPECIES_SPINDA
- && species != SPECIES_UNOWN);
-}
-
-bool8 sub_806F104(void)
-{
- if (gMain.inBattle && gBattleTypeFlags & (BATTLE_TYPE_FRONTIER))
- return TRUE;
- if (!gMain.inBattle && (InBattlePike() || InBattlePyramid()))
- return TRUE;
- return FALSE;
-}
-
-/*
-
-extern const struct SpriteTemplate gUnknown_08329D98[];
-
-struct Unknown_806F160_Struct
-{
- u8 field_0;
- u8 field_1;
- u8 field_2;
- u8 field_3;
- u8 field_4;
- u8 field_5;
- u8 field_6;
- u8 field_7;
- u8 field_8;
- u8 field_9;
- u8 field_A;
- u8 field_B;
- struct SpriteTemplate* templates;
-};
-
-void sub_806F160(struct Unknown_806F160_Struct* structPtr)
-{
- u16 i, j;
- for (i = 0; i < structPtr->field_0; i++)
- {
- structPtr->templates[i] = gUnknown_08329D98[i];
- for (j = 0; j < structPtr->field_1)
- {
- // no clue what the pointer in the struct point to :/
- }
- }
-} */
-
diff --git a/src/pokemon_animation.c b/src/pokemon_animation.c
index 02755fe40..c50aa4a75 100644
--- a/src/pokemon_animation.c
+++ b/src/pokemon_animation.c
@@ -1184,7 +1184,7 @@ static void sub_817F9F4(struct Sprite *sprite)
}
#else
-__attribute__((naked))
+NAKED
static void sub_817F9F4(struct Sprite *sprite)
{
asm(".syntax unified\n\
diff --git a/src/pokemon_icon.c b/src/pokemon_icon.c
index 4d1cc51c5..253ab2cb4 100644
--- a/src/pokemon_icon.c
+++ b/src/pokemon_icon.c
@@ -1,9 +1,28 @@
#include "global.h"
#include "sprite.h"
+#include "mail.h"
#include "graphics.h"
+#include "constants/species.h"
+#include "palette.h"
+#include "pokemon_icon.h"
#define POKE_ICON_BASE_PAL_TAG 56000
+struct MonIconSpriteTemplate
+{
+ const struct OamData *oam;
+ const u8 *image;
+ const union AnimCmd *const *anims;
+ const union AffineAnimCmd *const *affineAnims;
+ void (*callback)(struct Sprite *);
+ u16 paletteTag;
+};
+
+// static functions
+static u8 CreateMonIconSprite(struct MonIconSpriteTemplate *, s16, s16, u8);
+
+// .rodata
+
const u8 * const gMonIconTable[] =
{
gMonIcon_Bulbasaur,
@@ -1012,3 +1031,288 @@ const u16 sSpriteImageSizes[3][4] =
0x400, // 4×8
},
};
+
+u8 CreateMonIcon(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority, u32 personality, bool32 extra)
+{
+ u8 spriteId;
+ struct MonIconSpriteTemplate iconTemplate =
+ {
+ .oam = &sMonIconOamData,
+ .image = GetMonIconPtr(species, personality, extra),
+ .anims = sMonIconAnims,
+ .affineAnims = sMonIconAffineAnims,
+ .callback = callback,
+ .paletteTag = POKE_ICON_BASE_PAL_TAG + gMonIconPaletteIndices[species],
+ };
+
+ if (species > SPECIES_EGG)
+ iconTemplate.paletteTag = POKE_ICON_BASE_PAL_TAG;
+
+ spriteId = CreateMonIconSprite(&iconTemplate, x, y, subpriority);
+
+ UpdateMonIconFrame(&gSprites[spriteId]);
+
+ return spriteId;
+}
+
+u8 sub_80D2D78(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority, bool32 extra)
+{
+ u8 spriteId;
+ struct MonIconSpriteTemplate iconTemplate =
+ {
+ .oam = &sMonIconOamData,
+ .image = NULL,
+ .anims = sMonIconAnims,
+ .affineAnims = sMonIconAffineAnims,
+ .callback = callback,
+ .paletteTag = POKE_ICON_BASE_PAL_TAG + gMonIconPaletteIndices[species],
+ };
+
+ iconTemplate.image = GetMonIconTiles(species, extra);
+ spriteId = CreateMonIconSprite(&iconTemplate, x, y, subpriority);
+
+ UpdateMonIconFrame(&gSprites[spriteId]);
+
+ return spriteId;
+}
+
+u16 mon_icon_convert_unown_species_id(u16 species, u32 personality)
+{
+ u16 result;
+
+ if (species == SPECIES_UNOWN)
+ {
+ u16 letter = GetUnownLetterByPersonality(personality);
+ if (letter == 0)
+ letter = SPECIES_UNOWN;
+ else
+ letter += (SPECIES_UNOWN_B - 1);
+ result = letter;
+ }
+ else
+ {
+ if (species > SPECIES_EGG)
+ result = 260;
+ else
+ result = species;
+ }
+
+ return result;
+}
+
+u16 GetUnownLetterByPersonality(u32 personality)
+{
+ if (!personality)
+ return 0;
+ return (((personality & 0x3000000) >> 18) | ((personality & 0x30000) >> 12) | ((personality & 0x300) >> 6) | (personality & 0x3)) % 0x1C;
+}
+
+u16 sub_80D2E84(u16 species)
+{
+ u16 value;
+
+ if (MailSpeciesToSpecies(species, &value) == SPECIES_UNOWN)
+ {
+ if (value == 0)
+ value += SPECIES_UNOWN;
+ else
+ value += (SPECIES_UNOWN_B - 1);
+ return value;
+ }
+ else
+ {
+ if(species > (SPECIES_UNOWN_B - 1))
+ species = 260;
+ return mon_icon_convert_unown_species_id(species, 0);
+ }
+}
+
+const u8 *GetMonIconPtr(u16 species, u32 personality, bool32 extra)
+{
+ return GetMonIconTiles(mon_icon_convert_unown_species_id(species, personality), extra);
+}
+
+
+
+void sub_80D2EF8(struct Sprite *sprite)
+{
+ sub_80D328C(sprite);
+}
+
+void LoadMonIconPalettes(void)
+{
+ u8 i;
+ for (i = 0; i < 6; i++)
+ LoadSpritePalette(&gMonIconPaletteTable[i]);
+}
+
+// unused
+void SafeLoadMonIconPalette(u16 species)
+{
+ u8 palIndex;
+ if (species > SPECIES_EGG)
+ species = 260;
+ palIndex = gMonIconPaletteIndices[species];
+ if (IndexOfSpritePaletteTag(gMonIconPaletteTable[palIndex].tag) == 0xFF)
+ LoadSpritePalette(&gMonIconPaletteTable[palIndex]);
+}
+
+void LoadMonIconPalette(u16 species)
+{
+ u8 palIndex = gMonIconPaletteIndices[species];
+ if (IndexOfSpritePaletteTag(gMonIconPaletteTable[palIndex].tag) == 0xFF)
+ LoadSpritePalette(&gMonIconPaletteTable[palIndex]);
+}
+
+void FreeMonIconPalettes(void)
+{
+ u8 i;
+ for (i = 0; i < 6; i++)
+ FreeSpritePaletteByTag(gMonIconPaletteTable[i].tag);
+}
+
+// unused
+void SafeFreeMonIconPalette(u16 species)
+{
+ u8 palIndex;
+ if (species > SPECIES_EGG)
+ species = 260;
+ palIndex = gMonIconPaletteIndices[species];
+ FreeSpritePaletteByTag(gMonIconPaletteTable[palIndex].tag);
+}
+
+void FreeMonIconPalette(u16 species)
+{
+ u8 palIndex;
+ palIndex = gMonIconPaletteIndices[species];
+ FreeSpritePaletteByTag(gMonIconPaletteTable[palIndex].tag);
+}
+
+void sub_80D3014(struct Sprite *sprite)
+{
+ UpdateMonIconFrame(sprite);
+}
+
+const u8* GetMonIconTiles(u16 species, bool32 extra)
+{
+ const u8* iconSprite = gMonIconTable[species];
+ if(species == SPECIES_DEOXYS && extra == TRUE)
+ {
+ iconSprite = (const u8*)(0x400 + (u32)iconSprite); //WTF?
+ }
+ return iconSprite;
+}
+
+void sub_80D304C(u16 offset)
+{
+ s32 i;
+ const struct SpritePalette* monIconPalettePtr;
+
+ if(offset <= 0xA0)
+ {
+ monIconPalettePtr = gMonIconPaletteTable;
+ for(i = 5; i >= 0 ; i--)
+ {
+ LoadPalette(monIconPalettePtr->data, offset, 0x20);
+ offset += 0x10;
+ monIconPalettePtr++;
+ }
+ }
+}
+
+u8 sub_80D3080(u16 species)
+{
+ if (species > SPECIES_EGG)
+ species = 260;
+ return gMonIconPaletteIndices[species];
+}
+
+u8 sub_80D30A0(u16 species)
+{
+ return gMonIconPaletteIndices[species];
+}
+
+const u16* GetValidMonIconPalettePtr(u16 species)
+{
+ if (species > SPECIES_EGG)
+ species = 260;
+ return gMonIconPaletteTable[gMonIconPaletteIndices[species]].data;
+}
+
+// TODO: try to find a way to avoid using asm statement
+u8 UpdateMonIconFrame(struct Sprite *sprite)
+{
+ u8 result = 0;
+
+ if (sprite->animDelayCounter == 0)
+ {
+ s16 frame = sprite->anims[sprite->animNum][sprite->animCmdIndex].frame.imageValue;
+
+ switch (frame)
+ {
+ case -1:
+ break;
+ case -2:
+ sprite->animCmdIndex = 0;
+ break;
+ default:
+ RequestSpriteCopy(
+ // pointer arithmetic is needed to get the correct pointer to perform the sprite copy on.
+ // because sprite->images is a struct def, it has to be casted to (u8 *) before any
+ // arithmetic can be performed.
+ (u8 *)sprite->images + (sSpriteImageSizes[sprite->oam.shape][sprite->oam.size] * frame),
+ (u8 *)(OBJ_VRAM0 + sprite->oam.tileNum * TILE_SIZE_4BPP),
+ sSpriteImageSizes[sprite->oam.shape][sprite->oam.size]);
+ {
+ register u8 duration asm("r0") = sprite->anims[sprite->animNum][sprite->animCmdIndex].frame.duration;
+ sprite->animDelayCounter = duration;
+ }
+ sprite->animCmdIndex++;
+ result = sprite->animCmdIndex;
+ break;
+ }
+ }
+ else
+ {
+ sprite->animDelayCounter--;
+ }
+ return result;
+}
+
+static u8 CreateMonIconSprite(struct MonIconSpriteTemplate *iconTemplate, s16 x, s16 y, u8 subpriority)
+{
+ u8 spriteId;
+
+ struct SpriteFrameImage image = { NULL, sSpriteImageSizes[iconTemplate->oam->shape][iconTemplate->oam->size] };
+
+ struct SpriteTemplate spriteTemplate =
+ {
+ .tileTag = 0xFFFF,
+ .paletteTag = iconTemplate->paletteTag,
+ .oam = iconTemplate->oam,
+ .anims = iconTemplate->anims,
+ .images = &image,
+ .affineAnims = iconTemplate->affineAnims,
+ .callback = iconTemplate->callback,
+ };
+
+ spriteId = CreateSprite(&spriteTemplate, x, y, subpriority);
+ gSprites[spriteId].animPaused = TRUE;
+ gSprites[spriteId].animBeginning = FALSE;
+ gSprites[spriteId].images = (const struct SpriteFrameImage *)iconTemplate->image;
+ return spriteId;
+}
+
+void sub_80D328C(struct Sprite *sprite)
+{
+ struct SpriteFrameImage image = { NULL, sSpriteImageSizes[sprite->oam.shape][sprite->oam.size] };
+ sprite->images = &image;
+ DestroySprite(sprite);
+}
+
+void sub_80D32C8(struct Sprite *sprite, u8 animNum)
+{
+ sprite->animNum = animNum;
+ sprite->animDelayCounter = 0;
+ sprite->animCmdIndex = 0;
+}
diff --git a/src/pokemon_summary_screen.c b/src/pokemon_summary_screen.c
index 8c9e7a8a0..74dc11973 100644
--- a/src/pokemon_summary_screen.c
+++ b/src/pokemon_summary_screen.c
@@ -21,6 +21,12 @@
#include "text.h"
#include "window.h"
#include "event_data.h"
+#include "gpu_regs.h"
+#include "menu.h"
+#include "international_string_util.h"
+#include "scanline_effect.h"
+#include "menu_helpers.h"
+#include "daycare.h"
struct ContestMove
{
@@ -42,7 +48,6 @@ extern struct BgTemplate gUnknown_0861CBB4;
extern u8 gUnknown_0203CF20;
extern struct MusicPlayerInfo gMPlayInfo_BGM;
extern s8 gUnknown_0861CC1C[];
-extern u8 gUnknown_08329D22[];
extern u8 gUnknown_0203CF21;
extern struct UnkStruct_61CC04 gUnknown_0861CC04;
extern struct UnkStruct_61CC04 gUnknown_0861CC10;
@@ -65,20 +70,9 @@ extern u8 gUnknown_0861CE7B[];
extern struct WindowTemplate gUnknown_0861CCEC;
extern struct WindowTemplate gUnknown_0861CD14;
-extern void sub_806F2AC(u8 a, u8 b);
void sub_81C488C(u8 a);
-extern void do_scheduled_bg_tilemap_copies_to_vram(void);
extern u8 sub_81221EC();
extern u8 sub_81221AC();
-extern void SetVBlankHBlankCallbacksToNull();
-extern void ResetVramOamAndBgCntRegs();
-extern void clear_scheduled_bg_copies_to_vram();
-extern void ScanlineEffect_Stop();
-extern void ResetBgsAndClearDma3BusyFlags(u32 leftoverFireRedLeafGreenVariable);
-extern void ShowBg(u8 a);
-extern void SetGpuReg(u8 regOffset, u16 value);
-extern void schedule_bg_copy_tilemap_to_vram(u8 a);
-extern void SetBgTilemapBuffer(u8 bg, void *tilemap);
extern u8 gUnknown_08D9862C;
extern u8 gUnknown_08D98CC8;
extern u8 gUnknown_08D987FC;
@@ -93,9 +87,6 @@ extern struct CompressedSpritePalette gUnknown_0861D100;
extern struct CompressedSpritePalette gUnknown_0861D07C;
extern u8 gMoveTypes_Pal;
extern u8 gUnknown_08D97D0C;
-extern void reset_temp_tile_data_buffers();
-extern void decompress_and_copy_tile_data_to_vram(u8 a, void* tiledata, u8 b, u8 c, u8 d);
-extern u8 free_temp_tile_data_buffers_if_possible();
extern void sub_81C1E20(u8 taskId);
extern u8 *GetMonNickname(struct Pokemon *mon, u8 *dest);
extern u16 SpeciesToPokedexNum(u16 species);
@@ -125,8 +116,6 @@ extern u8 gText_Appeal[];
extern u8 gText_Jam[];
extern u8 gText_OTSlash[];
extern u8 gText_UnkCtrlF907F908[];
-extern u8 gAbilityNames[][13];
-extern u8 *gAbilityDescriptionPointers[];
extern u8 gText_XNature[];
extern u8 gText_XNatureHatchedAtYZ[];
extern u8 gText_XNatureHatchedSomewhereAt[];
@@ -156,13 +145,8 @@ extern u8 gText_OneDash[];
extern u8 gText_TwoDashes[];
extern u8 gText_ThreeDashes[];
extern u8 gUnknown_0861CE97[];
-extern struct BattleMove gBattleMoves[];
-extern u32 ChangeBgX(u8 bg, u32 value, u8 op);
extern void sub_8199C30(u8 a, u8 b, u8 c, u8 d, u8 e, u8 f);
-extern void AddTextPrinterParameterized2(u8 windowId, u8 fontId, u8 x, u8 y, u8 letterSpacing, u8 lineSpacing, const u8* colors, s8 speed, u8 *str);
-extern s32 GetStringCenterAlignXOffset(u8 fontId, u8 *str, s32 totalWidth);
-extern s32 GetStringRightAlignXOffset(u8 fontId, u8 *str, s32 totalWidth);
extern bool8 sub_81A6BF4();
extern bool8 sub_81B9E94();
extern void UnkTextUtil_Reset();
@@ -1433,7 +1417,7 @@ void sub_81C14BC(struct Pokemon *mon, u8 swappingFromId, u8 swappingToId)
*ppBonusesPtr = localPpBonuses;
}
#else
-__attribute__((naked))
+NAKED
void sub_81C14BC(struct Pokemon *mon, u8 swappingFromId, u8 swappingToId)
{
asm(".syntax unified\n\
@@ -1644,7 +1628,7 @@ void sub_81C15EC(struct BoxPokemon *mon, u8 swappingFromId, u8 swappingToId)
*ppBonusesPtr = localPpBonuses;
}
#else
-__attribute__((naked))
+NAKED
void sub_81C15EC(struct BoxPokemon *mon, u8 swappingFromId, u8 swappingToId)
{
asm(".syntax unified\n\
@@ -1841,7 +1825,7 @@ void sub_81C174C(u8 taskId)
}
else
{
- PlaySE(0x20);
+ PlaySE(SE_HAZURE);
sub_81C18F4(taskId);
}
}
@@ -2055,7 +2039,7 @@ void sub_81C1CB0(struct UnkStruct_61CC04 *a, u16 *b, u8 c, u8 d)
Free(alloced);
}
#else
-__attribute__((naked))
+NAKED
void sub_81C1CB0(struct UnkStruct_61CC04 *a, u16 *b, u8 c, u8 d)
{
asm(".syntax unified\n\
@@ -2357,7 +2341,7 @@ void sub_81C2194(u16 *a, u16 b, u8 c)
}
}
#else
-__attribute__((naked))
+NAKED
void sub_81C2194(u16 *a, u16 b, u8 c)
{
asm(".syntax unified\n\
@@ -2553,7 +2537,7 @@ void sub_81C2554()
gUnknown_0203CF1C->unk40CB[i] |= 0xFF;
}
-void sub_81C25A4(u8 a, u8 *b, u8 c, u8 d, u8 e, u8 f)
+void sub_81C25A4(u8 a, const u8 *b, u8 c, u8 d, u8 e, u8 f)
{
AddTextPrinterParameterized2(a, 1, c, d, 0, e, gUnknown_0861CD2C[f], 0, b);
}
@@ -2792,93 +2776,27 @@ void sub_81C2C38(u8 a)
schedule_bg_copy_tilemap_to_vram(0);
}
-
-
-#ifdef NONMATCHING
u8 sub_81C2D2C(struct WindowTemplate *template, u8 a)
{
- u8 *r4 = gUnknown_0203CF1C->unk40CB;
- if (r4[a] == 0xFF)
+ u8 *windowIdPtr = &(gUnknown_0203CF1C->unk40CB[a]);
+ if (*windowIdPtr == 0xFF)
{
- r4[a] = AddWindow(&template[a]);
- FillWindowPixelBuffer(r4[a], 0);
+ *windowIdPtr = AddWindow(&template[a]);
+ FillWindowPixelBuffer(*windowIdPtr, 0);
}
- return r4[a];
+ return *windowIdPtr;
}
-#else
-__attribute__((naked))
-u8 sub_81C2D2C(struct WindowTemplate *template, u8 a)
-{
- asm(".syntax unified\n\
- push {r4,lr}\n\
- adds r3, r0, 0\n\
- lsls r1, 24\n\
- lsrs r2, r1, 24\n\
- ldr r0, =gUnknown_0203CF1C\n\
- ldr r4, =0x000040cb\n\
- adds r1, r2, r4\n\
- ldr r0, [r0]\n\
- adds r4, r0, r1\n\
- ldrb r0, [r4]\n\
- cmp r0, 0xFF\n\
- bne _081C2D56\n\
- lsls r0, r2, 3\n\
- adds r0, r3, r0\n\
- bl AddWindow\n\
- strb r0, [r4]\n\
- ldrb r0, [r4]\n\
- movs r1, 0\n\
- bl FillWindowPixelBuffer\n\
-_081C2D56:\n\
- ldrb r0, [r4]\n\
- pop {r4}\n\
- pop {r1}\n\
- bx r1\n\
- .pool\n\
- .syntax divided\n");
-}
-#endif
-#ifdef NONMATCHING
void sub_81C2D68(u8 a)
{
- u8 *r4 = gUnknown_0203CF1C->unk40CB;
- if (r4[a] != 0xFF)
+ u8 *windowIdPtr = &(gUnknown_0203CF1C->unk40CB[a]);
+ if (*windowIdPtr != 0xFF)
{
- ClearWindowTilemap(r4[a]);
- RemoveWindow(r4[a]);
- r4[a] = 0xFF;
+ ClearWindowTilemap(*windowIdPtr);
+ RemoveWindow(*windowIdPtr);
+ *windowIdPtr = 0xFF;
}
}
-#else
-__attribute__((naked))
-void sub_81C2D68(u8 a)
-{
- asm(".syntax unified\n\
- push {r4,lr}\n\
- lsls r0, 24\n\
- lsrs r0, 24\n\
- ldr r1, =gUnknown_0203CF1C\n\
- ldr r2, =0x000040cb\n\
- adds r0, r2\n\
- ldr r1, [r1]\n\
- adds r4, r1, r0\n\
- ldrb r0, [r4]\n\
- cmp r0, 0xFF\n\
- beq _081C2D8C\n\
- bl ClearWindowTilemap\n\
- ldrb r0, [r4]\n\
- bl RemoveWindow\n\
- movs r0, 0xFF\n\
- strb r0, [r4]\n\
-_081C2D8C:\n\
- pop {r4}\n\
- pop {r0}\n\
- bx r0\n\
- .pool\n\
- .syntax divided\n");
-}
-#endif
void sub_81C2D9C(u8 a)
{
@@ -3041,7 +2959,7 @@ void sub_81C31F0(u8 *a)
{
u8 level = gUnknown_0203CF1C->summary.metLevel;
if (level == 0)
- level = 5;
+ level = EGG_HATCH_LEVEL;
ConvertIntToDecimalStringN(a, level, 0, 3);
UnkTextUtil_SetPtrI(3, a);
}
@@ -3108,7 +3026,7 @@ void sub_81C335C()
sub_81C25A4(r4, gText_FiveMarks, r5, 1, 0, 1);
}
#else
-__attribute__((naked))
+NAKED
void sub_81C335C()
{
asm(".syntax unified\n\
@@ -3255,11 +3173,11 @@ void sub_81C3554(u8 taskId)
void sub_81C35E4()
{
- u8 *text;
+ const u8 *text;
int offset;
if (gUnknown_0203CF1C->summary.item == ITEM_ENIGMA_BERRY && sub_81B1250() == 1 && (gUnknown_0203CF1C->unk40BE == 1 || gUnknown_0203CF1C->unk40BE == 4 || gUnknown_0203CF1C->unk40BE == 5))
{
- text = (u8*)ItemId_GetItem(ITEM_ENIGMA_BERRY);
+ text = ItemId_GetName(ITEM_ENIGMA_BERRY);
}
else if (gUnknown_0203CF1C->summary.item == ITEM_NONE)
text = gText_None;
@@ -3451,7 +3369,7 @@ void sub_81C3B08(u8 a)
sub_81C25A4(sp, text, offset, (a<<4), 0, r5);
}
#else
-__attribute__((naked))
+NAKED
void sub_81C3B08(u8 a)
{
asm(".syntax unified\n\
diff --git a/src/random.c b/src/random.c
index f2f0ede58..f0b2d9e5f 100644
--- a/src/random.c
+++ b/src/random.c
@@ -7,6 +7,10 @@
EWRAM_DATA static u8 sUnknown = 0;
EWRAM_DATA static u32 sRandCount = 0;
+// IWRAM common
+IWRAM_DATA u32 gRngValue;
+IWRAM_DATA u32 gRng2Value;
+
u16 Random(void)
{
gRngValue = 1103515245 * gRngValue + 24691;
diff --git a/src/record_mixing.c b/src/record_mixing.c
index 79db07bf0..1a39dfde9 100644
--- a/src/record_mixing.c
+++ b/src/record_mixing.c
@@ -106,8 +106,6 @@ void sub_80E89F8(void *dest);
void sub_80E8A54(void *src);
void sub_80E8AC0(union BattleTowerRecord *);
void sub_80EAF80(struct SecretBaseRecord *, size_t, u8);
-void sub_80F01E8(void *, size_t, u8);
-void sub_80F0C7C(PokeNews *, size_t, u8);
void sub_812287C(struct EasyChatPair *, size_t, u8);
void TaskDummy4(union BattleTowerRecord *src);
@@ -299,7 +297,7 @@ static void sub_80E715C(u8 taskId)
if (!gTasks[data[10]].isActive)
{
data[0] = 4;
- if (!gLinkVSyncDisabled)
+ if (gWirelessCommType == 0)
{
data[10] = sub_80B3050();
}
@@ -319,7 +317,7 @@ static void sub_80E715C(u8 taskId)
free(gUnknown_0203A014);
free(gUnknown_0203A018);
sub_808729C();
- if (gLinkVSyncDisabled)
+ if (gWirelessCommType != 0)
{
CreateTask(sub_80AF2B4, 10);
}
@@ -344,7 +342,7 @@ static void sub_80E7324(u8 taskId)
sub_80E70F4(gText_MixingRecords);
task->data[8] = 0x708;
task->data[0] = 400;
- sub_8009FAC();
+ ClearLinkCallback_2();
break;
case 100:
if (++ task->data[12] > 20)
@@ -546,7 +544,6 @@ static void sub_80E77D4(u8 taskId)
gUnknown_03001130 = TRUE;
}
-
static void *sub_80E77FC(const u16 *asShort)
{
return (void *)(asShort[0] | (asShort[1] << 16));
@@ -618,7 +615,7 @@ static void sub_80E78C4(OldMan *oldMan, size_t recordSize, u8 which)
sub_8120CD0(dest, version, language);
}
memcpy(gUnknown_03001140, (void *)oldMan + recordSize * mixIndices[which], sizeof(OldMan));
- sub_8120670();
+ ResetMauvilleOldManFlag();
}
static void sub_80E7948(union BattleTowerRecord *battleTowerRecord, size_t recordSize, u8 which)
@@ -1427,7 +1424,7 @@ __attribute__((naked)) static void sub_80E7B60(struct UnkStruct_80E7B60 *src, si
static void sub_80E7F68(u16 *item, u8 which)
{
- if (which != 0 && *item != ITEM_NONE && GetPocketByItemId(*item) == BAG_KEYITEMS)
+ if (which != 0 && *item != ITEM_NONE && GetPocketByItemId(*item) == POCKET_KEY_ITEMS)
{
if (!CheckBagHasItem(*item, 1) && !CheckPCHasItem(*item, 1) && AddBagItem(*item, 1))
{
@@ -1501,7 +1498,7 @@ static void sub_80E7FF8(u8 taskId)
case 7:
if (!FuncIsActiveTask(sub_8153688))
{
- if (gLinkVSyncDisabled)
+ if (gWirelessCommType)
{
sub_801048C(1);
task->data[0] = 8;
diff --git a/src/recorded_battle.c b/src/recorded_battle.c
index e60457257..eb48ab15a 100644
--- a/src/recorded_battle.c
+++ b/src/recorded_battle.c
@@ -100,7 +100,6 @@ EWRAM_DATA static u16 sUnknown_0203CCDC[6] = {0};
EWRAM_DATA static u8 sUnknown_0203CCE8 = 0;
extern u32 sub_81A513C(void);
-extern void PlayMapChosenOrBattleBGM(bool8);
// this file's functions
static u8 sub_8185278(u8 *arg0, u8 *arg1, u8 *arg2);
@@ -476,7 +475,7 @@ u32 MoveRecordedBattleToSaveData(void)
}
#else
-__attribute__((naked))
+NAKED
u32 MoveRecordedBattleToSaveData(void)
{
asm(".syntax unified\n\
diff --git a/src/region_map.c b/src/region_map.c
index 086c0ba68..f16787fc9 100644
--- a/src/region_map.c
+++ b/src/region_map.c
@@ -881,7 +881,7 @@ static void RegionMap_InitializeStateBasedOnPlayerLocation(void)
return;
}
- switch (get_map_light_level_by_bank_and_number(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum))
+ switch (GetMapTypeByGroupAndId(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum))
{
default:
case 1:
@@ -904,7 +904,7 @@ static void RegionMap_InitializeStateBasedOnPlayerLocation(void)
case 7:
if (gMapHeader.flags & 0x02)
{
- mapHeader = get_mapheader_by_bank_and_number(gSaveBlock1Ptr->warp4.mapGroup, gSaveBlock1Ptr->warp4.mapNum);
+ mapHeader = Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->warp4.mapGroup, gSaveBlock1Ptr->warp4.mapNum);
gRegionMap->mapSecId = mapHeader->regionMapSectionId;
gRegionMap->playerIsInCave = TRUE;
mapWidth = mapHeader->mapData->width;
@@ -923,7 +923,7 @@ static void RegionMap_InitializeStateBasedOnPlayerLocation(void)
}
break;
case 9:
- mapHeader = get_mapheader_by_bank_and_number((u16)gSaveBlock1Ptr->warp2.mapGroup, (u16)gSaveBlock1Ptr->warp2.mapNum);
+ mapHeader = Overworld_GetMapHeaderByGroupAndId((u16)gSaveBlock1Ptr->warp2.mapGroup, (u16)gSaveBlock1Ptr->warp2.mapNum);
gRegionMap->mapSecId = mapHeader->regionMapSectionId;
gRegionMap->playerIsInCave = TRUE;
mapWidth = mapHeader->mapData->width;
@@ -937,12 +937,12 @@ static void RegionMap_InitializeStateBasedOnPlayerLocation(void)
if (gRegionMap->mapSecId != MAPSEC_DYNAMIC)
{
storedWarp = &gSaveBlock1Ptr->warp4;
- mapHeader = get_mapheader_by_bank_and_number(storedWarp->mapGroup, storedWarp->mapNum);
+ mapHeader = Overworld_GetMapHeaderByGroupAndId(storedWarp->mapGroup, storedWarp->mapNum);
}
else
{
storedWarp = &gSaveBlock1Ptr->warp2;
- mapHeader = get_mapheader_by_bank_and_number(storedWarp->mapGroup, storedWarp->mapNum);
+ mapHeader = Overworld_GetMapHeaderByGroupAndId(storedWarp->mapGroup, storedWarp->mapNum);
gRegionMap->mapSecId = mapHeader->regionMapSectionId;
}
if (RegionMap_IsPlayerInCave(gRegionMap->mapSecId))
@@ -1065,7 +1065,7 @@ static void RegionMap_InitializeStateBasedOnSSTidalLocation(void)
break;
default:
case 0:
- mapHeader = get_mapheader_by_bank_and_number(mapGroup, mapNum);
+ mapHeader = Overworld_GetMapHeaderByGroupAndId(mapGroup, mapNum);
gRegionMap->mapSecId = mapHeader->regionMapSectionId;
dimensionScale = mapHeader->mapData->width / gRegionMapEntries[gRegionMap->mapSecId].width;
@@ -1581,7 +1581,7 @@ void MCB2_FlyMap(void)
gUnknown_0203A148 = malloc(sizeof(*gUnknown_0203A148));
if (gUnknown_0203A148 == NULL)
{
- SetMainCallback2(sub_8086194);
+ SetMainCallback2(CB2_ReturnToFieldWithOpenMenu);
}
else
{
diff --git a/src/reset_save_heap.c b/src/reset_save_heap.c
index 9950f6691..1d90448b2 100644
--- a/src/reset_save_heap.c
+++ b/src/reset_save_heap.c
@@ -20,11 +20,11 @@ void sub_81700F8(void)
gMain.inBattle = FALSE;
SetSaveBlocksPointers(sub_815355C());
sub_808447C();
- ResetSaveCounters();
- sub_81534D0(0);
+ Save_ResetSaveCounters();
+ Save_LoadGameData(0);
if (gSaveFileStatus == 0 || gSaveFileStatus == 2)
Sav2_ClearSetDefault();
SetPokemonCryStereo(gSaveBlock2Ptr->optionsSound);
InitHeap(gHeap, HEAP_SIZE);
- SetMainCallback2(sub_8086230);
+ SetMainCallback2(CB2_ContinueSavedGame);
}
diff --git a/src/reshow_battle_screen.c b/src/reshow_battle_screen.c
index b12917c61..45f0f5a9e 100644
--- a/src/reshow_battle_screen.c
+++ b/src/reshow_battle_screen.c
@@ -13,6 +13,7 @@
#include "constants/species.h"
#include "battle_interface.h"
#include "battle_anim.h"
+#include "data2.h"
extern u16 gBattle_BG0_X;
extern u16 gBattle_BG0_Y;
@@ -22,18 +23,17 @@ extern u16 gBattle_BG2_X;
extern u16 gBattle_BG2_Y;
extern u16 gBattle_BG3_X;
extern u16 gBattle_BG3_Y;
-extern struct SpriteTemplate gUnknown_0202499C;
extern const union AnimCmd * const * const gMonAnimationsSpriteAnimsPtrTable[];
-extern void sub_806A068(u16 species, u8 bankIdentity);
-extern void sub_806A12C(u16 backPicId, u8 bankIdentity);
+extern void sub_806A068(u16 species, u8 battlerPosition);
+extern void sub_806A12C(u16 backPicId, u8 battlerPosition);
// this file's functions
static void CB2_ReshowBattleScreenAfterMenu(void);
-static bool8 LoadBattlerSpriteGfx(u8 bank);
-static void CreateBattlerSprite(u8 bank);
-static void CreateHealthboxSprite(u8 bank);
+static bool8 LoadBattlerSpriteGfx(u8 battlerId);
+static void CreateBattlerSprite(u8 battlerId);
+static void CreateHealthboxSprite(u8 battlerId);
static void sub_80A95F4(void);
void nullsub_35(void)
@@ -162,10 +162,10 @@ static void CB2_ReshowBattleScreenAfterMenu(void)
ActionSelectionCreateCursorAt(gActionSelectionCursor[gBattlerInMenuId], 0);
- if (gLinkVSyncDisabled != 0 && gReceivedRemoteLinkPlayers != 0)
+ if (gWirelessCommType != 0 && gReceivedRemoteLinkPlayers != 0)
{
sub_800E0E8();
- sub_800DFB4(0, 0);
+ CreateWirelessStatusIndicatorSprite(0, 0);
}
}
break;
@@ -218,16 +218,6 @@ static bool8 LoadBattlerSpriteGfx(u8 battler)
return TRUE;
}
-// todo: get rid of it once the struct is declared in a header
-struct MonCoords
-{
- // This would use a bitfield, but sub_8079F44
- // uses it as a u8 and casting won't match.
- u8 coords; // u8 x:4, y:4;
- u8 y_offset;
-};
-extern const struct MonCoords gTrainerBackPicCoords[];
-
static void CreateBattlerSprite(u8 battler)
{
if (battler < gBattlersCount)
diff --git a/src/rom6.c b/src/rom6.c
new file mode 100644
index 000000000..4a5c506b6
--- /dev/null
+++ b/src/rom6.c
@@ -0,0 +1,209 @@
+#include "global.h"
+#include "constants/map_objects.h"
+#include "constants/songs.h"
+#include "rom6.h"
+#include "braille_puzzles.h"
+#include "event_data.h"
+#include "event_scripts.h"
+#include "field_effect.h"
+#include "field_map_obj.h"
+#include "field_player_avatar.h"
+#include "item_use.h"
+#include "party_menu.h"
+#include "overworld.h"
+#include "script.h"
+#include "sound.h"
+#include "sprite.h"
+#include "task.h"
+
+// static functions
+static void task08_080C9820(u8 taskId);
+static void sub_8135578(u8 taskId);
+static void sub_813552C(u8 taskId);
+static void sub_813561C(u8 taskId);
+static void sub_81356C4(void);
+static void sub_8135714(void);
+static void hm2_dig(void);
+static void sub_8135780(void);
+
+// extern RAM loc
+extern struct MapPosition gUnknown_0203AB40;
+
+// text
+bool8 npc_before_player_of_type(u8 a)
+{
+ u8 mapObjId;
+
+ GetXYCoordsOneStepInFrontOfPlayer(&gUnknown_0203AB40.x, &gUnknown_0203AB40.y);
+ gUnknown_0203AB40.height = PlayerGetZCoord();
+ mapObjId = GetFieldObjectIdByXYZ(gUnknown_0203AB40.x, gUnknown_0203AB40.y, gUnknown_0203AB40.height);
+ if (gMapObjects[mapObjId].graphicsId != a)
+ {
+ return FALSE;
+ }
+ else
+ {
+ gSpecialVar_LastTalked = gMapObjects[mapObjId].localId;
+ return TRUE;
+ }
+}
+
+u8 oei_task_add(void)
+{
+ GetXYCoordsOneStepInFrontOfPlayer(&gUnknown_0203AB40.x, &gUnknown_0203AB40.y);
+ return CreateTask(task08_080C9820, 8);
+}
+
+static void task08_080C9820(u8 taskId)
+{
+ u8 mapObjId;
+
+ ScriptContext2_Enable();
+ gPlayerAvatar.preventStep = TRUE;
+ mapObjId = gPlayerAvatar.mapObjectId;
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(&gMapObjects[mapObjId])
+ || FieldObjectClearAnimIfSpecialAnimFinished(&gMapObjects[mapObjId]))
+ {
+ if (gMapHeader.mapType == MAP_TYPE_UNDERWATER)
+ {
+ FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON_INIT);
+ gTasks[taskId].func = sub_8135578;
+ }
+ else
+ {
+ sub_808C114();
+ FieldObjectSetSpecialAnim(&gMapObjects[mapObjId], 0x39);
+ gTasks[taskId].func = sub_813552C;
+ }
+ }
+}
+
+static void sub_813552C(u8 taskId)
+{
+ if (FieldObjectCheckIfSpecialAnimFinishedOrInactive(&gMapObjects[gPlayerAvatar.mapObjectId]) == TRUE)
+ {
+ FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON_INIT);
+ gTasks[taskId].func = sub_8135578;
+ }
+}
+
+static void sub_8135578(u8 taskId)
+{
+ if (!FieldEffectActiveListContains(6))
+ {
+ gFieldEffectArguments[1] = player_get_direction_lower_nybble();
+ if (gFieldEffectArguments[1] == 1)
+ gFieldEffectArguments[2] = 0;
+ if (gFieldEffectArguments[1] == 2)
+ gFieldEffectArguments[2] = 1;
+ if (gFieldEffectArguments[1] == 3)
+ gFieldEffectArguments[2] = 2;
+ if (gFieldEffectArguments[1] == 4)
+ gFieldEffectArguments[2] = 3;
+ FieldObjectSetGraphicsId(&gMapObjects[gPlayerAvatar.mapObjectId], GetPlayerAvatarGraphicsIdByCurrentState());
+ StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], gFieldEffectArguments[2]);
+ FieldEffectActiveListRemove(6);
+ gTasks[taskId].func = sub_813561C;
+ }
+}
+
+static void sub_813561C(u8 taskId)
+{
+ void (*func)(void) = (void (*)(void))(((u16)gTasks[taskId].data[8] << 16) | (u16)gTasks[taskId].data[9]);
+
+ func();
+ gPlayerAvatar.preventStep = FALSE;
+ DestroyTask(taskId);
+}
+
+bool8 SetUpFieldMove_RockSmash(void)
+{
+ if(ShouldDoBrailleStrengthEffect())
+ {
+ gSpecialVar_Result = GetCursorSelectionMonId();
+ gUnknown_03005DB0 = FieldCallback_Teleport;
+ gUnknown_0203CEEC = sub_8179834;
+ return TRUE;
+ }
+ else if (npc_before_player_of_type(0x56) == TRUE)
+ {
+ gUnknown_03005DB0 = FieldCallback_Teleport;
+ gUnknown_0203CEEC = sub_81356C4;
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+static void sub_81356C4(void)
+{
+ gFieldEffectArguments[0] = GetCursorSelectionMonId();
+ ScriptContext1_SetupScript(Route111_EventScript_2907F0);
+}
+
+bool8 FldEff_UseRockSmash(void)
+{
+ u8 taskId = oei_task_add();
+
+ gTasks[taskId].data[8] = (u32)sub_8135714 >> 16;
+ gTasks[taskId].data[9] = (u32)sub_8135714;
+ IncrementGameStat(GAME_STAT_USED_ROCK_SMASH);
+ return FALSE;
+}
+
+static void sub_8135714(void)
+{
+ PlaySE(SE_W088);
+ FieldEffectActiveListRemove(FLDEFF_USE_ROCK_SMASH);
+ EnableBothScriptContexts();
+}
+
+bool8 SetUpFieldMove_Dig(void)
+{
+ if (CanUseEscapeRopeOnCurrMap() == TRUE)
+ {
+ gUnknown_03005DB0 = FieldCallback_Teleport;
+ gUnknown_0203CEEC = hm2_dig;
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+static void hm2_dig(void)
+{
+ Overworld_ResetStateAfterDigEscRope();
+ FieldEffectStart(FLDEFF_USE_DIG);
+ gFieldEffectArguments[0] = GetCursorSelectionMonId();
+}
+
+bool8 FldEff_UseDig(void)
+{
+ u8 taskId = oei_task_add();
+
+ gTasks[taskId].data[8] = (u32)sub_8135780 >> 16;
+ gTasks[taskId].data[9] = (u32)sub_8135780;
+ if (!ShouldDoBrailleDigEffect())
+ SetPlayerAvatarTransitionFlags(1);
+ return FALSE;
+}
+
+static void sub_8135780(void)
+{
+ u8 taskId;
+
+ FieldEffectActiveListRemove(FLDEFF_USE_DIG);
+ if (ShouldDoBrailleDigEffect())
+ {
+ DoBrailleDigEffect();
+ }
+ else
+ {
+ taskId = CreateTask(task08_080A1C44, 8);
+ gTasks[taskId].data[0] = 0;
+ }
+}
diff --git a/src/rom_8011DC0.c b/src/rom_8011DC0.c
new file mode 100644
index 000000000..9076b611a
--- /dev/null
+++ b/src/rom_8011DC0.c
@@ -0,0 +1,18 @@
+
+// Includes
+#include "global.h"
+
+// Static type declarations
+
+// Static RAM declarations
+IWRAM_DATA u32 gUnknown_03000DA0;
+IWRAM_DATA u32 gUnknown_03000DA4;
+IWRAM_DATA void *gUnknown_03000DA8;
+IWRAM_DATA void *gUnknown_03000DAC;
+IWRAM_DATA bool32 gUnknown_03000DB0;
+
+// Static ROM declarations
+
+// .rodata
+
+// .text
diff --git a/src/rotating_gate.c b/src/rotating_gate.c
new file mode 100644
index 000000000..a16401fa2
--- /dev/null
+++ b/src/rotating_gate.c
@@ -0,0 +1,1188 @@
+#include "global.h"
+#include "bike.h"
+#include "event_data.h"
+#include "field_map_obj.h"
+#include "constants/maps.h"
+#include "constants/songs.h"
+#include "sound.h"
+#include "sprite.h"
+
+#define ROTATING_GATE_TILE_TAG 0x1300
+#define ROTATING_GATE_PUZZLE_MAX 12
+#define GATE_ARM_MAX_LENGTH 2
+
+#define GATE_ROT(rotationDirection, arm, longArm) \
+ ((rotationDirection & 15) << 4) | ((arm & 7) << 1) | (longArm & 1)
+#define GATE_ROT_CW(arm, longArm) GATE_ROT(ROTATE_CLOCKWISE, arm, longArm)
+#define GATE_ROT_ACW(arm, longArm) GATE_ROT(ROTATE_ANTICLOCKWISE, arm, longArm)
+#define GATE_ROT_NONE 255
+
+// static functions
+static void SpriteCallback_RotatingGate(struct Sprite *sprite);
+static u8 RotatingGate_CreateGate(u8 gateId, s16 deltaX, s16 deltaY);
+static void RotatingGate_HideGatesOutsideViewport(struct Sprite *sprite);
+
+// enums
+enum
+{
+ /*
+ * |
+ * +--
+ */
+ GATE_SHAPE_L1,
+
+ /*
+ * |
+ * |
+ * +--
+ */
+ GATE_SHAPE_L2,
+
+ /*
+ * |
+ * +----
+ */
+ GATE_SHAPE_L3,
+
+ /*
+ * |
+ * |
+ * +----
+ */
+ GATE_SHAPE_L4,
+
+ /*
+ * |
+ * +--
+ * |
+ */
+ GATE_SHAPE_T1,
+
+ /*
+ * |
+ * |
+ * +--
+ * |
+ */
+ GATE_SHAPE_T2,
+
+ /*
+ * |
+ * +----
+ * |
+ */
+ GATE_SHAPE_T3,
+
+ /*
+ * An unused T-shape gate
+ * |
+ * +--
+ * |
+ * |
+ */
+ GATE_SHAPE_T4,
+
+ /*
+ * An unused T-shape gate
+ * |
+ * |
+ * +----
+ * |
+ */
+ GATE_SHAPE_UNUSED_T1,
+
+ /*
+ * An unused T-shape gate
+ * |
+ * |
+ * +--
+ * |
+ * |
+ */
+ GATE_SHAPE_UNUSED_T2,
+
+ /*
+ * An unused T-shape gate
+ * |
+ * +----
+ * |
+ * |
+ */
+ GATE_SHAPE_UNUSED_T3,
+
+ /*
+ * An unused T-shape gate
+ * |
+ * |
+ * +----
+ * |
+ * |
+ */
+ GATE_SHAPE_UNUSED_T4,
+};
+
+enum
+{
+ /*
+ * 0 degrees (clockwise)
+ * |
+ * +--
+ * |
+ */
+ GATE_ORIENTATION_0,
+
+ /*
+ * 90 degress (clockwise)
+ * --+--
+ * |
+ */
+ GATE_ORIENTATION_90,
+
+ /*
+ * 180 degrees (clockwise)
+ * |
+ * --+
+ * |
+ */
+ GATE_ORIENTATION_180,
+
+ /*
+ * 270 degrees (clockwise)
+ * |
+ * --+--
+ */
+ GATE_ORIENTATION_270,
+
+ GATE_ORIENTATION_MAX,
+};
+
+// Describes the location of the gates "arms" when the gate has not
+// been rotated (i.e. rotated 0 degrees)
+enum
+{
+ GATE_ARM_NORTH,
+ GATE_ARM_EAST,
+ GATE_ARM_SOUTH,
+ GATE_ARM_WEST,
+};
+
+enum
+{
+ ROTATE_NONE,
+ ROTATE_ANTICLOCKWISE,
+ ROTATE_CLOCKWISE,
+};
+
+enum
+{
+ PUZZLE_NONE,
+ PUZZLE_FORTREE_CITY_GYM,
+ PUZZLE_ROUTE110_TRICK_HOUSE_PUZZLE6,
+};
+
+// structure
+struct RotatingGatePuzzle
+{
+ s16 x;
+ s16 y;
+ u8 shape;
+ u8 orientation;
+};
+
+struct Coords8
+{
+ s8 deltaX;
+ s8 deltaY;
+};
+
+// .rodata
+// Fortree
+static const struct RotatingGatePuzzle sRotatingGate_FortreePuzzleConfig[] =
+{
+ { 6, 7, GATE_SHAPE_T2, GATE_ORIENTATION_90},
+ { 9, 15, GATE_SHAPE_T2, GATE_ORIENTATION_180},
+ { 3, 19, GATE_SHAPE_T2, GATE_ORIENTATION_90},
+ { 2, 6, GATE_SHAPE_T1, GATE_ORIENTATION_90},
+ { 9, 12, GATE_SHAPE_T1, GATE_ORIENTATION_0},
+ { 6, 23, GATE_SHAPE_T1, GATE_ORIENTATION_0},
+ {12, 22, GATE_SHAPE_T1, GATE_ORIENTATION_0},
+ { 6, 3, GATE_SHAPE_L4, GATE_ORIENTATION_180},
+};
+
+// Trickhouse
+static const struct RotatingGatePuzzle sRotatingGate_TrickHousePuzzleConfig[] =
+{
+ {14, 5, GATE_SHAPE_T1, GATE_ORIENTATION_90},
+ {10, 6, GATE_SHAPE_L2, GATE_ORIENTATION_180},
+ { 6, 6, GATE_SHAPE_L4, GATE_ORIENTATION_90},
+ {14, 8, GATE_SHAPE_T1, GATE_ORIENTATION_90},
+ { 3, 10, GATE_SHAPE_L3, GATE_ORIENTATION_270},
+ { 9, 14, GATE_SHAPE_L1, GATE_ORIENTATION_90},
+ { 3, 15, GATE_SHAPE_T3, GATE_ORIENTATION_0},
+ { 2, 17, GATE_SHAPE_L2, GATE_ORIENTATION_180},
+ {12, 18, GATE_SHAPE_T3, GATE_ORIENTATION_270},
+ { 5, 18, GATE_SHAPE_L4, GATE_ORIENTATION_90},
+ {10, 19, GATE_SHAPE_L3, GATE_ORIENTATION_180},
+};
+
+static const u8 sRotatingGateTiles_1[] = INCBIN_U8("graphics/misc/rotating_gate_1.4bpp");
+static const u8 sRotatingGateTiles_2[] = INCBIN_U8("graphics/misc/rotating_gate_2.4bpp");
+static const u8 sRotatingGateTiles_3[] = INCBIN_U8("graphics/misc/rotating_gate_3.4bpp");
+static const u8 sRotatingGateTiles_4[] = INCBIN_U8("graphics/misc/rotating_gate_4.4bpp");
+static const u8 sRotatingGateTiles_5[] = INCBIN_U8("graphics/misc/rotating_gate_5.4bpp");
+static const u8 sRotatingGateTiles_6[] = INCBIN_U8("graphics/misc/rotating_gate_6.4bpp");
+static const u8 sRotatingGateTiles_7[] = INCBIN_U8("graphics/misc/rotating_gate_7.4bpp");
+static const u8 sRotatingGateTiles_8[] = INCBIN_U8("graphics/misc/rotating_gate_8.4bpp");
+
+static const struct OamData sOamData_RotatingGateLarge =
+{
+ .y = 0,
+ .affineMode = ST_OAM_AFFINE_NORMAL,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = ST_OAM_4BPP,
+ .shape = ST_OAM_SQUARE,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 3,
+ .tileNum = 0,
+ .priority = 2,
+ .paletteNum = 2,
+ .affineParam = 0,
+};
+
+static const struct OamData sOamData_RotatingGateRegular =
+{
+ .y = 0,
+ .affineMode = ST_OAM_AFFINE_NORMAL,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = ST_OAM_4BPP,
+ .shape = ST_OAM_SQUARE,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 2,
+ .tileNum = 0,
+ .priority = 2,
+ .paletteNum = 2,
+ .affineParam = 0,
+};
+
+static const struct SpriteSheet sRotatingGatesGraphicsTable[] =
+{
+ {sRotatingGateTiles_1, 0x200, ROTATING_GATE_TILE_TAG + GATE_SHAPE_L1},
+ {sRotatingGateTiles_2, 0x800, ROTATING_GATE_TILE_TAG + GATE_SHAPE_L2},
+ {sRotatingGateTiles_3, 0x800, ROTATING_GATE_TILE_TAG + GATE_SHAPE_L3},
+ {sRotatingGateTiles_4, 0x800, ROTATING_GATE_TILE_TAG + GATE_SHAPE_L4},
+ {sRotatingGateTiles_5, 0x200, ROTATING_GATE_TILE_TAG + GATE_SHAPE_T1},
+ {sRotatingGateTiles_6, 0x800, ROTATING_GATE_TILE_TAG + GATE_SHAPE_T2},
+ {sRotatingGateTiles_7, 0x800, ROTATING_GATE_TILE_TAG + GATE_SHAPE_T3},
+ {sRotatingGateTiles_8, 0x800, ROTATING_GATE_TILE_TAG + GATE_SHAPE_T4},
+ {NULL},
+};
+
+static const union AnimCmd sSpriteAnim_RotatingGateLarge[] =
+{
+ ANIMCMD_FRAME(0, 0),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd sSpriteAnim_RotatingGateRegular[] =
+{
+ ANIMCMD_FRAME(0, 0), ANIMCMD_END,
+};
+
+static const union AnimCmd *const sSpriteAnimTable_RotatingGateLarge[] =
+{
+ sSpriteAnim_RotatingGateLarge,
+};
+
+static const union AnimCmd *const sSpriteAnimTable_RotatingGateRegular[] =
+{
+ sSpriteAnim_RotatingGateRegular,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_Rotated0[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_JUMP(0),
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_Rotated90[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, -64, 0),
+ AFFINEANIMCMD_JUMP(0),
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_Rotated180[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, -128, 0),
+ AFFINEANIMCMD_JUMP(0),
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_Rotated270[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 64, 0),
+ AFFINEANIMCMD_JUMP(0),
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingClockwise0to90[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -4, 16),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingClockwise90to180[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, -64, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -4, 16),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingClockwise180to270[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, -128, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -4, 16),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingClockwise270to360[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 64, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -4, 16),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingAnticlockwise360to270[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 4, 16),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingAnticlockwise270to180[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 64, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 4, 16),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingAnticlockwise180to90[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, -128, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 4, 16),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingAnticlockwise90to0[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, -64, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 4, 16),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingClockwise0to90Faster[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -8, 8),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingClockwise90to180Faster[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, -64, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -8, 8),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingClockwise180to270Faster[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, -128, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -8, 8),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingClockwise270to360Faster[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 64, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -8, 8),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingAnticlockwise360to270Faster[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 8, 8),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingAnticlockwise270to180Faster[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 64, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 8, 8),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingAnticlockwise180to90Faster[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, -128, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 8, 8),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_RotatingAnticlockwise90to0Faster[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, -64, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 8, 8),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const sSpriteAffineAnimTable_RotatingGate[] =
+{
+ sSpriteAffineAnim_Rotated0,
+ sSpriteAffineAnim_Rotated90,
+ sSpriteAffineAnim_Rotated180,
+ sSpriteAffineAnim_Rotated270,
+ sSpriteAffineAnim_RotatingAnticlockwise360to270,
+ sSpriteAffineAnim_RotatingAnticlockwise90to0,
+ sSpriteAffineAnim_RotatingAnticlockwise180to90,
+ sSpriteAffineAnim_RotatingAnticlockwise270to180,
+ sSpriteAffineAnim_RotatingClockwise0to90,
+ sSpriteAffineAnim_RotatingClockwise90to180,
+ sSpriteAffineAnim_RotatingClockwise180to270,
+ sSpriteAffineAnim_RotatingClockwise270to360,
+ sSpriteAffineAnim_RotatingAnticlockwise360to270Faster,
+ sSpriteAffineAnim_RotatingAnticlockwise90to0Faster,
+ sSpriteAffineAnim_RotatingAnticlockwise180to90Faster,
+ sSpriteAffineAnim_RotatingAnticlockwise270to180Faster,
+ sSpriteAffineAnim_RotatingClockwise0to90Faster,
+ sSpriteAffineAnim_RotatingClockwise90to180Faster,
+ sSpriteAffineAnim_RotatingClockwise180to270Faster,
+ sSpriteAffineAnim_RotatingClockwise270to360Faster,
+};
+
+
+static const struct SpriteTemplate sSpriteTemplate_RotatingGateLarge =
+{
+ .tileTag = ROTATING_GATE_TILE_TAG,
+ .paletteTag = 0xFFFF,
+ .oam = &sOamData_RotatingGateLarge,
+ .anims = sSpriteAnimTable_RotatingGateLarge,
+ .images = NULL,
+ .affineAnims = sSpriteAffineAnimTable_RotatingGate,
+ .callback = SpriteCallback_RotatingGate,
+};
+
+static const struct SpriteTemplate sSpriteTemplate_RotatingGateRegular =
+{
+ .tileTag = ROTATING_GATE_TILE_TAG,
+ .paletteTag = 0xFFFF,
+ .oam = &sOamData_RotatingGateRegular,
+ .anims = sSpriteAnimTable_RotatingGateRegular,
+ .images = NULL,
+ .affineAnims = sSpriteAffineAnimTable_RotatingGate,
+ .callback = SpriteCallback_RotatingGate,
+};
+
+// These structures describe what happens to the gate if you hit it at
+// a given coordinate in a 4x4 grid when walking in the specified
+// direction. Either the gate does not rotate, or it rotates in the
+// given direction. This information is compared against the gate
+// "arm" layout to see if there is an arm at the position in order to
+// produce the final rotation.
+static const u8 sRotatingGate_RotationInfoNorth[4 * 4] =
+{
+ GATE_ROT_NONE, GATE_ROT_NONE, GATE_ROT_NONE, GATE_ROT_NONE,
+ GATE_ROT_CW(GATE_ARM_WEST, 1), GATE_ROT_CW(GATE_ARM_WEST, 0), GATE_ROT_ACW(GATE_ARM_EAST, 0), GATE_ROT_ACW(GATE_ARM_EAST, 1),
+ GATE_ROT_NONE, GATE_ROT_NONE, GATE_ROT_NONE, GATE_ROT_NONE,
+ GATE_ROT_NONE, GATE_ROT_NONE, GATE_ROT_NONE, GATE_ROT_NONE,
+};
+
+static const u8 sRotatingGate_RotationInfoSouth[4 * 4] =
+{
+ GATE_ROT_NONE, GATE_ROT_NONE, GATE_ROT_NONE, GATE_ROT_NONE,
+ GATE_ROT_NONE, GATE_ROT_NONE, GATE_ROT_NONE, GATE_ROT_NONE,
+ GATE_ROT_ACW(GATE_ARM_WEST, 1), GATE_ROT_ACW(GATE_ARM_WEST, 0), GATE_ROT_CW(GATE_ARM_EAST, 0), GATE_ROT_CW(GATE_ARM_EAST, 1),
+ GATE_ROT_NONE, GATE_ROT_NONE, GATE_ROT_NONE, GATE_ROT_NONE,
+};
+
+static const u8 sRotatingGate_RotationInfoWest[4 * 4] =
+{
+ GATE_ROT_NONE, GATE_ROT_ACW(GATE_ARM_NORTH, 1), GATE_ROT_NONE, GATE_ROT_NONE,
+ GATE_ROT_NONE, GATE_ROT_ACW(GATE_ARM_NORTH, 0), GATE_ROT_NONE, GATE_ROT_NONE,
+ GATE_ROT_NONE, GATE_ROT_CW(GATE_ARM_SOUTH, 0), GATE_ROT_NONE, GATE_ROT_NONE,
+ GATE_ROT_NONE, GATE_ROT_CW(GATE_ARM_SOUTH, 1), GATE_ROT_NONE, GATE_ROT_NONE,
+};
+
+static const u8 sRotatingGate_RotationInfoEast[4 * 4] =
+{
+ GATE_ROT_NONE, GATE_ROT_NONE, GATE_ROT_CW(GATE_ARM_NORTH, 1), GATE_ROT_NONE,
+ GATE_ROT_NONE, GATE_ROT_NONE, GATE_ROT_CW(GATE_ARM_NORTH, 0), GATE_ROT_NONE,
+ GATE_ROT_NONE, GATE_ROT_NONE, GATE_ROT_ACW(GATE_ARM_SOUTH, 0), GATE_ROT_NONE,
+ GATE_ROT_NONE, GATE_ROT_NONE, GATE_ROT_ACW(GATE_ARM_SOUTH, 1), GATE_ROT_NONE,
+};
+
+// These tables describe the relative coordinate positions the arms
+// must move through in order to be rotated.
+static const struct Coords8 sRotatingGate_ArmPositionsClockwiseRotation[] = {
+ { 0, -1 }, { 1, -2 }, { 0, 0 }, { 1, 0 }, { -1, 0 }, { -1, 1 }, { -1, -1 }, { -2, -1 },
+};
+
+static const struct Coords8 sRotatingGate_ArmPositionsAntiClockwiseRotation[] = {
+ { -1, -1 }, { -1, -2 }, { 0, -1 }, { 1, -1 }, { 0, 0 }, { 0, 1 }, { -1, 0 }, { -2, 0 },
+};
+
+// Describes where the gates "arms" are in the order north, east, south, west.
+// These are adjusted using the current orientation to perform collision checking
+static const u8 sRotatingGate_ArmLayout[][4 * 2] =
+{
+ // L-shape gates
+ {
+ 1, 0,
+ 1, 0,
+ 0, 0,
+ 0, 0,
+ },
+ {
+ 1, 1,
+ 1, 0,
+ 0, 0,
+ 0, 0,
+ },
+ {
+ 1, 0,
+ 1, 1,
+ 0, 0,
+ 0, 0,
+ },
+ {
+ 1, 1,
+ 1, 1,
+ 0, 0,
+ 0, 0,
+ },
+
+ // T-shape gates
+ {
+ 1, 0,
+ 1, 0,
+ 1, 0,
+ 0, 0,
+ },
+ {
+ 1, 1,
+ 1, 0,
+ 1, 0,
+ 0, 0,
+ },
+ {
+ 1, 0,
+ 1, 1,
+ 1, 0,
+ 0, 0,
+ },
+ {
+ 1, 0,
+ 1, 0,
+ 1, 1,
+ 0, 0,
+ },
+
+ // Unused T-shape gates
+ // These have 2-3 long arms and cannot actually be used anywhere
+ // since configuration for them is missing from the other tables.
+ {
+ 1, 1,
+ 1, 1,
+ 1, 0,
+ 0, 0,
+ },
+ {
+ 1, 1,
+ 1, 0,
+ 1, 1,
+ 0, 0,
+ },
+ {
+ 1, 0,
+ 1, 1,
+ 1, 1,
+ 0, 0,
+ },
+ {
+ 1, 1,
+ 1, 1,
+ 1, 1,
+ 0, 0,
+ },
+};
+
+// ewram
+static EWRAM_DATA u8 gRotatingGate_GateSpriteIds[ROTATING_GATE_PUZZLE_MAX] = {0};
+static EWRAM_DATA const struct RotatingGatePuzzle *gRotatingGate_PuzzleConfig = NULL;
+static EWRAM_DATA u8 gRotatingGate_PuzzleCount = 0;
+
+// text
+static s32 GetCurrentMapRotatingGatePuzzleType(void)
+{
+ if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(FORTREE_CITY_GYM) &&
+ gSaveBlock1Ptr->location.mapNum == MAP_NUM(FORTREE_CITY_GYM))
+ {
+ return PUZZLE_FORTREE_CITY_GYM;
+ }
+
+ if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(ROUTE110_TRICK_HOUSE_PUZZLE6) &&
+ gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE110_TRICK_HOUSE_PUZZLE6))
+ {
+ return PUZZLE_ROUTE110_TRICK_HOUSE_PUZZLE6;
+ }
+
+ return PUZZLE_NONE;
+}
+
+static void RotatingGate_ResetAllGateOrientations(void)
+{
+ s32 i;
+ u8 *ptr;
+
+ ptr = (u8 *)GetVarPointer(VAR_0x4000);
+
+ for (i = 0; i < gRotatingGate_PuzzleCount; i++)
+ {
+ ptr[i] = gRotatingGate_PuzzleConfig[i].orientation;
+ }
+}
+
+static s32 RotatingGate_GetGateOrientation(u8 gateId)
+{
+ return ((u8 *)GetVarPointer(VAR_0x4000))[gateId];
+}
+
+static void RotatingGate_SetGateOrientation(u8 gateId, u8 orientation)
+{
+ ((u8 *)GetVarPointer(VAR_0x4000))[gateId] = orientation;
+}
+
+static void RotatingGate_RotateInDirection(u8 gateId, u32 rotationDirection)
+{
+ u8 orientation = RotatingGate_GetGateOrientation(gateId);
+
+ if (rotationDirection == ROTATE_ANTICLOCKWISE)
+ {
+ if (orientation)
+ orientation--;
+ else
+ orientation = GATE_ORIENTATION_270;
+ }
+ else
+ {
+ orientation = ++orientation % GATE_ORIENTATION_MAX;
+ }
+ RotatingGate_SetGateOrientation(gateId, orientation);
+}
+
+static void RotatingGate_LoadPuzzleConfig(void)
+{
+ s32 puzzleType = GetCurrentMapRotatingGatePuzzleType();
+ u32 i;
+
+ switch (puzzleType)
+ {
+ case PUZZLE_FORTREE_CITY_GYM:
+ gRotatingGate_PuzzleConfig = sRotatingGate_FortreePuzzleConfig;
+ gRotatingGate_PuzzleCount =
+ sizeof(sRotatingGate_FortreePuzzleConfig) / sizeof(struct RotatingGatePuzzle);
+ break;
+ case PUZZLE_ROUTE110_TRICK_HOUSE_PUZZLE6:
+ gRotatingGate_PuzzleConfig = sRotatingGate_TrickHousePuzzleConfig;
+ gRotatingGate_PuzzleCount =
+ sizeof(sRotatingGate_TrickHousePuzzleConfig) / sizeof(struct RotatingGatePuzzle);
+ break;
+ case PUZZLE_NONE:
+ default:
+ return;
+ }
+
+ for (i = 0; i < ROTATING_GATE_PUZZLE_MAX - 1; i++)
+ {
+ gRotatingGate_GateSpriteIds[i] = MAX_SPRITES;
+ }
+}
+
+static void RotatingGate_CreateGatesWithinViewport(s16 deltaX, s16 deltaY)
+{
+ u8 i;
+
+ // Calculate the bounding box of the camera
+ // Same as RotatingGate_DestroyGatesOutsideViewport
+ s16 x = gSaveBlock1Ptr->pos.x - 2;
+ s16 x2 = gSaveBlock1Ptr->pos.x + 0x11;
+ s16 y = gSaveBlock1Ptr->pos.y - 2;
+ s16 y2 = gSaveBlock1Ptr->pos.y + 0xe;
+
+ s16 x3, y3;
+
+ for (i = 0; i < gRotatingGate_PuzzleCount; i++)
+ {
+ x3 = gRotatingGate_PuzzleConfig[i].x + 7;
+ y3 = gRotatingGate_PuzzleConfig[i].y + 7;
+
+ if (y <= y3 && y2 >= y3 && x <= x3 && x2 >= x3 &&
+ gRotatingGate_GateSpriteIds[i] == MAX_SPRITES)
+ {
+ gRotatingGate_GateSpriteIds[i] = RotatingGate_CreateGate(i, deltaX, deltaY);
+ }
+ }
+}
+
+static u8 RotatingGate_CreateGate(u8 gateId, s16 deltaX, s16 deltaY)
+{
+ struct Sprite *sprite;
+ struct SpriteTemplate template;
+ const struct RotatingGatePuzzle *gate;
+ u8 spriteId;
+ s16 x, y;
+
+ gate = &gRotatingGate_PuzzleConfig[gateId];
+
+ if (gate->shape == GATE_SHAPE_L1 || gate->shape == GATE_SHAPE_T1)
+ template = sSpriteTemplate_RotatingGateRegular;
+ else
+ template = sSpriteTemplate_RotatingGateLarge;
+
+ template.tileTag = gate->shape + ROTATING_GATE_TILE_TAG;
+
+ spriteId = CreateSprite(&template, 0, 0, 0x94);
+ if (spriteId == MAX_SPRITES)
+ return MAX_SPRITES;
+
+ x = gate->x + 7;
+ y = gate->y + 7;
+
+ sprite = &gSprites[spriteId];
+ sprite->data[0] = gateId;
+ sprite->coordOffsetEnabled = 1;
+
+ sub_8092FF0(x + deltaX, y + deltaY, &sprite->pos1.x, &sprite->pos1.y);
+ RotatingGate_HideGatesOutsideViewport(sprite);
+ StartSpriteAffineAnim(sprite, RotatingGate_GetGateOrientation(gateId));
+
+ return spriteId;
+}
+
+static void SpriteCallback_RotatingGate(struct Sprite *sprite)
+{
+ u8 rotationDirection;
+ u8 orientation;
+ u8 affineAnimation;
+
+ rotationDirection = sprite->data[1];
+ orientation = sprite->data[2];
+
+ RotatingGate_HideGatesOutsideViewport(sprite);
+
+ if (rotationDirection == ROTATE_ANTICLOCKWISE)
+ {
+ affineAnimation = orientation + 4;
+
+ if (GetPlayerSpeed() != 1)
+ affineAnimation += 8;
+
+ PlaySE(SE_HI_TURUN);
+ StartSpriteAffineAnim(sprite, affineAnimation);
+ }
+ else if (rotationDirection == ROTATE_CLOCKWISE)
+ {
+ affineAnimation = orientation + 8;
+
+ if (GetPlayerSpeed() != 1)
+ affineAnimation += 8;
+
+ PlaySE(SE_HI_TURUN);
+ StartSpriteAffineAnim(sprite, affineAnimation);
+ }
+
+ sprite->data[1] = ROTATE_NONE;
+}
+
+static void RotatingGate_HideGatesOutsideViewport(struct Sprite *sprite)
+{
+ u16 x;
+ s16 x2;
+ u16 y;
+ s16 y2;
+
+ sprite->invisible = FALSE;
+ x = sprite->pos1.x + sprite->pos2.x + sprite->centerToCornerVecX + gSpriteCoordOffsetX;
+ y = sprite->pos1.y + sprite->pos2.y + sprite->centerToCornerVecY + gSpriteCoordOffsetY;
+
+ x2 = x + 0x40; // Dimensions of the rotating gate
+ y2 = y + 0x40;
+
+ if ((s16)x > DISPLAY_WIDTH + 0x10 - 1 || x2 < -0x10)
+ {
+ sprite->invisible = TRUE;
+ }
+
+ if ((s16)y > DISPLAY_HEIGHT + 0x10 - 1 || y2 < -0x10)
+ {
+ sprite->invisible = TRUE;
+ }
+}
+
+static void LoadRotatingGatePics(void)
+{
+ LoadSpriteSheets(sRotatingGatesGraphicsTable);
+}
+
+/*
+static*/ void RotatingGate_DestroyGatesOutsideViewport(void)
+{
+ s16 x;
+ s16 x2;
+ s16 y;
+ s16 y2;
+ s16 xGate;
+ s16 yGate;
+ s32 i;
+ struct Sprite *sprite;
+
+ // Same as RotatingGate_CreateGatesWithinViewport
+ x = gSaveBlock1Ptr->pos.x - 2;
+ x2 = gSaveBlock1Ptr->pos.x + 0x11;
+ y = gSaveBlock1Ptr->pos.y - 2;
+ y2 = gSaveBlock1Ptr->pos.y + 0xe;
+
+ for (i = 0; i < gRotatingGate_PuzzleCount; i++)
+ {
+ xGate = gRotatingGate_PuzzleConfig[i].x + 7;
+ yGate = gRotatingGate_PuzzleConfig[i].y + 7;
+
+ if (gRotatingGate_GateSpriteIds[i] == MAX_SPRITES)
+ continue;
+
+ if (xGate < x || xGate > x2 || yGate < y || yGate > y2)
+ {
+ sprite = &gSprites[gRotatingGate_GateSpriteIds[i]];
+ FreeSpriteOamMatrix(sprite);
+ DestroySprite(sprite);
+ gRotatingGate_GateSpriteIds[i] = MAX_SPRITES;
+ }
+ }
+}
+
+
+#ifdef NONMATCHING
+bool8 MapGridIsImpassableAt(s32, s32); //fool the compiler
+
+static s32 RotatingGate_CanRotate(u8 gateId, s16 rotationDirection)
+{
+ const struct Coords8 *armPos;
+ u8 orientation;
+ s16 x;
+ s16 y;
+ u8 shape;
+ u32 shape8;
+ s32 i;
+ s32 j;
+ s32 armOrientation;
+ const u8 *gateArmCollisionData;
+ u8 armIndex;
+
+ if (rotationDirection == ROTATE_ANTICLOCKWISE)
+ armPos = sRotatingGate_ArmPositionsAntiClockwiseRotation;
+ else if (rotationDirection == ROTATE_CLOCKWISE)
+ armPos = sRotatingGate_ArmPositionsClockwiseRotation;
+ else
+ return FALSE;
+
+ orientation = RotatingGate_GetGateOrientation(gateId);
+
+ shape = gRotatingGate_PuzzleConfig[gateId].shape;
+ x = gRotatingGate_PuzzleConfig[gateId].x + 7;
+ y = gRotatingGate_PuzzleConfig[gateId].y + 7;
+
+
+ // Loop through the gate's "arms" clockwise (north, south, east, west)
+ for (i = GATE_ARM_NORTH, shape8 = shape* 4*2 ; i <= GATE_ARM_WEST; i++)
+ {
+ // Ensure that no part of the arm collides with the map
+ for (j = 0, armOrientation = orientation + i, gateArmCollisionData = (u8 *)((u32)sRotatingGate_ArmLayout + shape8 + 2*i); j < GATE_ARM_MAX_LENGTH; j++)
+ {
+ armIndex = 2 * (armOrientation % 4) + j;
+
+ if (*gateArmCollisionData)
+ {
+ if (MapGridIsImpassableAt(x + armPos[armIndex].deltaX, y + armPos[armIndex].deltaY) == TRUE)
+ return FALSE;
+ }
+ gateArmCollisionData++;
+ }
+ }
+
+ return TRUE;
+}
+
+#else
+NAKED
+static s32 RotatingGate_CanRotate(u8 a, s16 rotationDirection)
+{
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ mov r7, r10\n\
+ mov r6, r9\n\
+ mov r5, r8\n\
+ push {r5-r7}\n\
+ sub sp, 0xC\n\
+ lsls r0, 24\n\
+ lsrs r4, r0, 24\n\
+ cmp r1, 0x1\n\
+ bne _080FBCFC\n\
+ ldr r0, =sRotatingGate_ArmPositionsAntiClockwiseRotation\n\
+ mov r10, r0\n\
+ b _080FBD08\n\
+ .pool\n\
+_080FBCFC:\n\
+ cmp r1, 0x2\n\
+ beq _080FBD04\n\
+_080FBD00:\n\
+ movs r0, 0\n\
+ b _080FBD98\n\
+_080FBD04:\n\
+ ldr r1, =sRotatingGate_ArmPositionsClockwiseRotation\n\
+ mov r10, r1\n\
+_080FBD08:\n\
+ adds r0, r4, 0\n\
+ bl RotatingGate_GetGateOrientation\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ str r0, [sp]\n\
+ ldr r0, =gRotatingGate_PuzzleConfig\n\
+ ldr r1, [r0]\n\
+ lsls r0, r4, 3\n\
+ adds r0, r1\n\
+ ldrb r2, [r0, 0x4]\n\
+ ldrh r1, [r0]\n\
+ adds r1, 0x7\n\
+ ldrh r0, [r0, 0x2]\n\
+ adds r0, 0x7\n\
+ movs r3, 0\n\
+ lsls r2, 3\n\
+ str r2, [sp, 0x4]\n\
+ lsls r1, 16\n\
+ asrs r1, 16\n\
+ mov r9, r1\n\
+ lsls r0, 16\n\
+ asrs r0, 16\n\
+ mov r8, r0\n\
+_080FBD38:\n\
+ movs r6, 0\n\
+ ldr r2, [sp]\n\
+ adds r7, r2, r3\n\
+ lsls r0, r3, 1\n\
+ adds r5, r7, 0\n\
+ ldr r1, [sp, 0x4]\n\
+ adds r0, r1\n\
+ ldr r2, =sRotatingGate_ArmLayout\n\
+ adds r4, r0, r2\n\
+_080FBD4A:\n\
+ adds r0, r5, 0\n\
+ cmp r5, 0\n\
+ bge _080FBD52\n\
+ adds r0, r7, 0x3\n\
+_080FBD52:\n\
+ asrs r0, 2\n\
+ lsls r0, 2\n\
+ subs r0, r5, r0\n\
+ lsls r0, 1\n\
+ adds r0, r6\n\
+ lsls r0, 24\n\
+ lsrs r1, r0, 24\n\
+ ldrb r0, [r4]\n\
+ cmp r0, 0\n\
+ beq _080FBD88\n\
+ lsls r1, 2\n\
+ add r1, r10\n\
+ movs r0, 0\n\
+ ldrsb r0, [r1, r0]\n\
+ add r0, r9\n\
+ ldrb r1, [r1, 0x1]\n\
+ lsls r1, 24\n\
+ asrs r1, 24\n\
+ add r1, r8\n\
+ str r3, [sp, 0x8]\n\
+ bl MapGridIsImpassableAt\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ ldr r3, [sp, 0x8]\n\
+ cmp r0, 0x1\n\
+ beq _080FBD00\n\
+_080FBD88:\n\
+ adds r4, 0x1\n\
+ adds r6, 0x1\n\
+ cmp r6, 0x1\n\
+ ble _080FBD4A\n\
+ adds r3, 0x1\n\
+ cmp r3, 0x3\n\
+ ble _080FBD38\n\
+ movs r0, 0x1\n\
+_080FBD98:\n\
+ add sp, 0xC\n\
+ pop {r3-r5}\n\
+ mov r8, r3\n\
+ mov r9, r4\n\
+ mov r10, r5\n\
+ pop {r4-r7}\n\
+ pop {r1}\n\
+ bx r1\n\
+ .pool\n\
+.syntax divided\n");
+}
+#endif
+
+static s32 RotatingGate_HasArm(u8 gateId, u8 armInfo)
+{
+ s32 isLongArm;
+ s8 armOrientation;
+ s32 arm;
+ s32 shape;
+
+ arm = armInfo >> 1;
+ isLongArm = armInfo & 1;
+
+ armOrientation = (arm - RotatingGate_GetGateOrientation(gateId) + 4) % 4;
+ shape = gRotatingGate_PuzzleConfig[gateId].shape;
+ return sRotatingGate_ArmLayout[shape][armOrientation * 2 + isLongArm];
+}
+
+static void RotatingGate_TriggerRotationAnimation(u8 gateId, s32 rotationDirection)
+{
+ struct Sprite *sprite;
+
+ if (gRotatingGate_GateSpriteIds[gateId] != MAX_SPRITES)
+ {
+ sprite = &gSprites[gRotatingGate_GateSpriteIds[gateId]];
+ sprite->data[1] = rotationDirection;
+ sprite->data[2] = RotatingGate_GetGateOrientation(gateId);
+ }
+}
+
+static u8 RotatingGate_GetRotationInfo(u8 direction, s16 x, s16 y)
+{
+ register const u8 *ptr;
+
+ if (direction == DIR_NORTH)
+ ptr = sRotatingGate_RotationInfoNorth;
+ else if (direction == DIR_SOUTH)
+ ptr = sRotatingGate_RotationInfoSouth;
+ else if (direction == DIR_WEST)
+ ptr = sRotatingGate_RotationInfoWest;
+ else if (direction == DIR_EAST)
+ ptr = sRotatingGate_RotationInfoEast;
+ else
+ return GATE_ROT_NONE;
+
+ return ptr[y * 4 + x];
+}
+
+void RotatingGate_InitPuzzle(void)
+{
+ if (GetCurrentMapRotatingGatePuzzleType())
+ {
+ RotatingGate_LoadPuzzleConfig();
+ RotatingGate_ResetAllGateOrientations();
+ }
+}
+
+void RotatingGatePuzzleCameraUpdate(u16 deltaX, u16 deltaY)
+{
+ if (GetCurrentMapRotatingGatePuzzleType())
+ {
+ RotatingGate_CreateGatesWithinViewport(deltaX, deltaY);
+ RotatingGate_DestroyGatesOutsideViewport();
+ }
+}
+
+void RotatingGate_InitPuzzleAndGraphics(void)
+{
+ if (GetCurrentMapRotatingGatePuzzleType())
+ {
+ LoadRotatingGatePics();
+ RotatingGate_LoadPuzzleConfig();
+ RotatingGate_CreateGatesWithinViewport(0, 0);
+ }
+}
+
+bool8 CheckForRotatingGatePuzzleCollision(u8 direction, s16 x, s16 y)
+{
+ s32 i;
+
+ if (!GetCurrentMapRotatingGatePuzzleType())
+ return FALSE;
+ for (i = 0; i < gRotatingGate_PuzzleCount; i++)
+ {
+ s16 gateX = gRotatingGate_PuzzleConfig[i].x + 7;
+ s16 gateY = gRotatingGate_PuzzleConfig[i].y + 7;
+
+ if (gateX - 2 <= x && x <= gateX + 1 && gateY - 2 <= y && y <= gateY + 1)
+ {
+ s16 centerX = x - gateX + 2;
+ s16 centerY = y - gateY + 2;
+ u8 rotationInfo = RotatingGate_GetRotationInfo(direction, centerX, centerY);
+
+ if (rotationInfo != GATE_ROT_NONE)
+ {
+ u8 rotationDirection = ((rotationInfo & 0xF0) >> 4);
+ u8 armInfo = rotationInfo & 0xF;
+
+ if (RotatingGate_HasArm(i, armInfo))
+ {
+ if (RotatingGate_CanRotate(i, rotationDirection))
+ {
+ RotatingGate_TriggerRotationAnimation(i, rotationDirection);
+ RotatingGate_RotateInDirection(i, rotationDirection);
+ return FALSE;
+ }
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+bool8 CheckForRotatingGatePuzzleCollisionWithoutAnimation(u8 direction, s16 x, s16 y)
+{
+ s32 i;
+
+ if (!GetCurrentMapRotatingGatePuzzleType())
+ return FALSE;
+ for (i = 0; i < gRotatingGate_PuzzleCount; i++)
+ {
+ s16 gateX = gRotatingGate_PuzzleConfig[i].x + 7;
+ s16 gateY = gRotatingGate_PuzzleConfig[i].y + 7;
+
+ if (gateX - 2 <= x && x <= gateX + 1 && gateY - 2 <= y && y <= gateY + 1)
+ {
+ s16 centerX = x - gateX + 2;
+ s16 centerY = y - gateY + 2;
+ u8 rotationInfo = RotatingGate_GetRotationInfo(direction, centerX, centerY);
+
+ if (rotationInfo != GATE_ROT_NONE)
+ {
+ u8 rotationDirection = ((rotationInfo & 0xF0) >> 4);
+ u8 armInfo = rotationInfo & 0xF;
+
+ if (RotatingGate_HasArm(i, armInfo))
+ {
+ if (!RotatingGate_CanRotate(i, rotationDirection))
+ {
+ return TRUE;
+ }
+ }
+ }
+ }
+ }
+ return FALSE;
+}
diff --git a/src/safari_zone.c b/src/safari_zone.c
index dd3cf3733..ab5c38f3a 100644
--- a/src/safari_zone.c
+++ b/src/safari_zone.c
@@ -30,9 +30,9 @@ extern void sub_80EE44C(u8, u8);
extern void IncrementGameStat(u8 index);
extern void ScriptContext1_SetupScript(u8*);
extern void ScriptContext2_RunNewScript(u8*);
-extern void c2_exit_to_overworld_2_switch(void);
-extern void c2_exit_to_overworld_1_continue_scripts_restart_music(void);
-extern void c2_load_new_map(void);
+extern void CB2_ReturnToField(void);
+extern void CB2_ReturnToFieldContinueScript(void);
+extern void CB2_LoadMap(void);
extern void sub_80AF6F0(void);
extern void ScriptContext1_Stop(void);
extern void warp_in(void);
@@ -112,20 +112,20 @@ void CB2_EndSafariBattle(void)
sSafariZoneCaughtMons++;
if (gNumSafariBalls != 0)
{
- SetMainCallback2(c2_exit_to_overworld_2_switch);
+ SetMainCallback2(CB2_ReturnToField);
}
else if (gBattleOutcome == B_OUTCOME_NO_SAFARI_BALLS)
{
ScriptContext2_RunNewScript(EventScript_2A4B4C);
warp_in();
gFieldCallback = sub_80AF6F0;
- SetMainCallback2(c2_load_new_map);
+ SetMainCallback2(CB2_LoadMap);
}
else if (gBattleOutcome == B_OUTCOME_CAUGHT)
{
ScriptContext1_SetupScript(EventScript_2A4B9B);
ScriptContext1_Stop();
- SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+ SetMainCallback2(CB2_ReturnToFieldContinueScript);
}
}
diff --git a/src/save.c b/src/save.c
index 8d77e801a..81731692e 100644
--- a/src/save.c
+++ b/src/save.c
@@ -3,17 +3,16 @@
#include "save.h"
#include "constants/game_stat.h"
#include "task.h"
+#include "decompress.h"
+#include "load_save.h"
+#include "overworld.h"
// for the chunk declarations
-extern struct SaveBlock2 gSaveblock2;
-extern struct SaveBlock1 gSaveblock1;
-extern struct PokemonStorage gPokemonStorage;
extern struct SaveSectionLocation gRamSaveSectionLocations[0xE];
-extern u8 gDecompressionBuffer[];
-extern u32 gFlashMemoryPresent;
extern u16 gUnknown_03006294;
extern bool8 gSoftResetDisabled;
+extern u32 gUnknown_0203CF5C;
// Divide save blocks into individual chunks to be written to flash sectors
@@ -23,13 +22,13 @@ extern bool8 gSoftResetDisabled;
/*
* Sector Layout:
- *
+ *
* Sectors 0 - 13: Save Slot 1
* Sectors 14 - 27: Save Slot 2
* Sectors 28 - 29: Hall of Fame
* Sector 30: e-Reader/Mystery Gift Stuff (note: e-Reader is deprecated in Emerald US)
* Sector 31: Recorded Battle
- *
+ *
* There are two save slots for saving the player's game data. We alternate between
* them each time the game is saved, so that if the current save slot is corrupt,
* we can load the previous one. We also rotate the sectors in each save slot
@@ -40,7 +39,7 @@ extern bool8 gSoftResetDisabled;
// (u8 *)structure was removed from the first statement of the macro in Emerald.
// This is because malloc is used to allocate addresses so storing the raw
-// addresses should not be done in the offsets information.
+// addresses should not be done in the offsets information.
#define SAVEBLOCK_CHUNK(structure, chunkNum) \
{ \
chunkNum * SECTOR_DATA_SIZE, \
@@ -68,8 +67,10 @@ const struct SaveSectionOffsets gSaveSectionOffsets[] =
};
extern void DoSaveFailedScreen(u8); // save_failed_screen
-extern void LoadSerializedGame(void); // load_save
extern bool32 ProgramFlashSectorAndVerify(u8 sector, u8 *data);
+extern void save_serialize_map(void);
+extern void sub_800ADF8(void);
+extern bool8 sub_800A520(void);
// iwram common
u16 gLastWrittenSector;
@@ -96,7 +97,7 @@ void ClearSaveData(void)
}
}
-void ResetSaveCounters(void)
+void Save_ResetSaveCounters(void)
{
gSaveCounter = 0;
gLastWrittenSector = 0;
@@ -655,11 +656,6 @@ void UpdateSaveAddresses(void)
}
}
-extern u32 GetGameStat(u8 index); // rom4
-extern void IncrementGameStat(u8 index); // rom4
-extern void SaveSerializedGame(void); // load_save
-extern u32 gUnknown_0203CF5C;
-
u8 HandleSavingData(u8 saveType)
{
u8 i;
@@ -670,25 +666,25 @@ u8 HandleSavingData(u8 saveType)
UpdateSaveAddresses();
switch (saveType)
{
- case HOF_DELETE_SAVE: // deletes HOF before overwriting HOF completely. unused
+ case SAVE_HALL_OF_FAME_ERASE_BEFORE: // deletes HOF before overwriting HOF completely. unused
for (i = 0xE * 2 + 0; i < 32; i++)
EraseFlashSector(i);
- case HOF_SAVE: // hall of fame.
+ case SAVE_HALL_OF_FAME: // hall of fame.
if (GetGameStat(GAME_STAT_ENTERED_HOF) < 999)
IncrementGameStat(GAME_STAT_ENTERED_HOF);
SaveSerializedGame();
save_write_to_flash(0xFFFF, gRamSaveSectionLocations);
- tempAddr = (u8 *)0x201C000; // FIXME: make this a label.
+ tempAddr = gDecompressionBuffer;
HandleWriteSectorNBytes(0x1C, tempAddr, 0xF80);
HandleWriteSectorNBytes(0x1D, tempAddr + 0xF80, 0xF80);
break;
- case NORMAL_SAVE: // normal save. also called by overwriting your own save.
+ case SAVE_NORMAL: // normal save. also called by overwriting your own save.
default:
SaveSerializedGame();
save_write_to_flash(0xFFFF, gRamSaveSectionLocations);
break;
- case LINK_SAVE: // _081532C4
- case LINK2_SAVE:
+ case SAVE_LINK: // _081532C4
+ case SAVE_LINK2:
SaveSerializedGame();
for(i = 0; i < 5; i++)
ClearSaveData_2(i, gRamSaveSectionLocations);
@@ -702,7 +698,7 @@ u8 HandleSavingData(u8 saveType)
save_write_to_flash(0, gRamSaveSectionLocations);
break;
*/
- case DIFFERENT_FILE_SAVE:
+ case SAVE_OVERWRITE_DIFFERENT_FILE:
for (i = (0xE * 2 + 0); i < 32; i++)
EraseFlashSector(i); // erase HOF.
SaveSerializedGame();
@@ -799,7 +795,7 @@ bool8 sub_8153474(void)
return retVal;
}
-u8 sub_81534D0(u8 a1)
+u8 Save_LoadGameData(u8 a1)
{
u8 result;
@@ -835,7 +831,7 @@ u16 sub_815355C(void)
struct SaveSection* savSection;
savSection = gFastSaveSection = &gSaveDataBuffer;
- if (gFlashMemoryPresent != 1)
+ if (gFlashMemoryPresent != TRUE)
return 0;
UpdateSaveAddresses();
GetSaveValidStatus(gRamSaveSectionLocations);
@@ -896,12 +892,6 @@ u32 sub_8153634(u8 sector, u8* src)
return 1;
}
-extern void save_serialize_map(void);
-extern void sub_8076D5C(void);
-extern void sav2_gender2_inplace_and_xFE(void);
-extern void sub_800ADF8(void);
-extern bool8 sub_800A520(void);
-
void sub_8153688(u8 taskId)
{
s16* taskData = gTasks[taskId].data;
diff --git a/src/scrcmd.c b/src/scrcmd.c
index d2e9c13c9..a29e64979 100644
--- a/src/scrcmd.c
+++ b/src/scrcmd.c
@@ -31,7 +31,6 @@
#include "mystery_event_script.h"
#include "palette.h"
#include "party_menu.h"
-#include "pokemon_3.h"
#include "pokemon_storage_system.h"
#include "random.h"
#include "overworld.h"
@@ -1477,20 +1476,14 @@ bool8 ScrCmd_showcontestwinner(struct ScriptContext *ctx)
return TRUE;
}
-// Lots of math, can't figure it out.
-/*
bool8 ScrCmd_braillemessage(struct ScriptContext *ctx)
{
u8 *ptr = (u8 *)ScriptReadWord(ctx);
- struct WindowTemplate template1;
- struct WindowTemplate template2;
- int i;
- u8 width;
- u8 height;
- int temp1;
- int temp2;
- u8 x;
- u8 y;
+ struct WindowTemplate winTemplate;
+ s32 i;
+ u8 width, height;
+ u8 xWindow, yWindow, xText, yText;
+ u8 temp;
StringExpandPlaceholders(gStringVar4, ptr + 6);
@@ -1508,168 +1501,30 @@ bool8 ScrCmd_braillemessage(struct ScriptContext *ctx)
if (height > 0x12)
height = 0x12;
- x = width + 2;
- temp1 = (0x1E - x) / 2;
- x = temp1 + 1;
- temp1 = ((x - temp1 - 1) * 8 + 3);
+ temp = width + 2;
+ xWindow = (0x1E - temp) / 2;
- y = height + 2;
- temp2 = (0x14 - y) / 2;
- y = temp2 + 2;
- temp2 = ((y - temp2 - 1) * 8);
+ temp = height + 2;
+ yText = (0x14 - temp) / 2;
- sub_8198A50(&template1, 0, x, y, width, height, 0xF, 0x1);
- template2 = template1;
- gUnknown_03000F30 = AddWindow(&template2);
+ xText = xWindow;
+ xWindow += 1;
+
+ yWindow = yText;
+ yText += 2;
+
+ xText = (xWindow - xText - 1) * 8 + 3;
+ yText = (yText - yWindow - 1) * 8;
+
+ winTemplate = sub_8198A50(0, xWindow, yWindow + 1, width, height, 0xF, 0x1);
+ gUnknown_03000F30 = AddWindow(&winTemplate);
sub_809882C(gUnknown_03000F30, 0x214, 0xE0);
NewMenuHelpers_DrawStdWindowFrame(gUnknown_03000F30, 0);
PutWindowTilemap(gUnknown_03000F30);
FillWindowPixelBuffer(gUnknown_03000F30, 0x11);
- PrintTextOnWindow(gUnknown_03000F30, 6, gStringVar4, temp1, temp2, 0xFF, 0x0);
+ PrintTextOnWindow(gUnknown_03000F30, 6, gStringVar4, xText, yText, 0xFF, 0x0);
CopyWindowToVram(gUnknown_03000F30, 3);
return FALSE;
-}*/
-__attribute__((naked))
-bool8 ScrCmd_braillemessage(struct ScriptContext *ctx)
-{
- asm("push {r4-r7,lr}\n\
- mov r7, r8\n\
- push {r7}\n\
- sub sp, #0x20\n\
- bl ScriptReadWord\n\
- add r1, r0, #0\n\
- ldr r4, =gStringVar4\n\
- add r1, #0x6\n\
- add r0, r4, #0\n\
- bl StringExpandPlaceholders\n\
- mov r2, #0x1\n\
- neg r2, r2\n\
- mov r0, #0x6\n\
- add r1, r4, #0\n\
- bl GetStringWidth\n\
- lsr r0, #3\n\
- lsl r0, #24\n\
- lsr r7, r0, #24\n\
- cmp r7, #0x1C\n\
- bls _0809AE9C\n\
- mov r7, #0x1C\n\
-_0809AE9C:\n\
- mov r5, #0x4\n\
- ldrb r0, [r4]\n\
- add r2, r7, #0x2\n\
- add r1, sp, #0x18\n\
- mov r8, r1\n\
- cmp r0, #0xFF\n\
- beq _0809AEC0\n\
- add r1, r4, #0\n\
-_0809AEAC:\n\
- ldrb r0, [r1]\n\
- add r1, #0x1\n\
- cmp r0, #0xFE\n\
- bne _0809AEBA\n\
- add r0, r5, #0x3\n\
- lsl r0, #24\n\
- lsr r5, r0, #24\n\
-_0809AEBA:\n\
- ldrb r0, [r1]\n\
- cmp r0, #0xFF\n\
- bne _0809AEAC\n\
-_0809AEC0:\n\
- cmp r5, #0x12\n\
- bls _0809AEC6\n\
- mov r5, #0x12\n\
-_0809AEC6:\n\
- lsl r0, r2, #24\n\
- lsr r0, #24\n\
- mov r2, #0x1E\n\
- sub r2, r0\n\
- lsr r0, r2, #31\n\
- add r2, r0\n\
- asr r2, #1\n\
- lsl r2, #24\n\
- add r0, r5, #0x2\n\
- lsl r0, #24\n\
- lsr r0, #24\n\
- mov r4, #0x14\n\
- sub r4, r0\n\
- lsr r0, r4, #31\n\
- add r4, r0\n\
- asr r4, #1\n\
- lsl r4, #24\n\
- lsr r6, r2, #24\n\
- mov r0, #0x80\n\
- lsl r0, #17\n\
- add r2, r0\n\
- lsr r2, #24\n\
- lsr r3, r4, #24\n\
- mov r1, #0x80\n\
- lsl r1, #18\n\
- add r4, r1\n\
- lsr r4, #24\n\
- sub r6, r2, r6\n\
- sub r6, #0x1\n\
- lsl r6, #3\n\
- add r6, #0x3\n\
- lsl r6, #24\n\
- lsr r6, #24\n\
- sub r4, r3\n\
- sub r4, #0x1\n\
- lsl r4, #27\n\
- lsr r4, #24\n\
- add r3, #0x1\n\
- lsl r3, #24\n\
- lsr r3, #24\n\
- str r7, [sp]\n\
- str r5, [sp, #0x4]\n\
- mov r0, #0xF\n\
- str r0, [sp, #0x8]\n\
- mov r0, #0x1\n\
- str r0, [sp, #0xC]\n\
- add r0, sp, #0x10\n\
- mov r1, #0\n\
- bl sub_8198A50\n\
- ldr r0, [sp, #0x10]\n\
- ldr r1, [sp, #0x14]\n\
- str r0, [sp, #0x18]\n\
- str r1, [sp, #0x1C]\n\
- ldr r5, =gUnknown_03000F30\n\
- mov r0, r8\n\
- bl AddWindow\n\
- strb r0, [r5]\n\
- ldrb r0, [r5]\n\
- mov r1, #0x85\n\
- lsl r1, #2\n\
- mov r2, #0xE0\n\
- bl sub_809882C\n\
- ldrb r0, [r5]\n\
- mov r1, #0\n\
- bl NewMenuHelpers_DrawStdWindowFrame\n\
- ldrb r0, [r5]\n\
- bl PutWindowTilemap\n\
- ldrb r0, [r5]\n\
- mov r1, #0x11\n\
- bl FillWindowPixelBuffer\n\
- ldrb r0, [r5]\n\
- ldr r2, =gStringVar4\n\
- str r4, [sp]\n\
- mov r1, #0xFF\n\
- str r1, [sp, #0x4]\n\
- mov r1, #0\n\
- str r1, [sp, #0x8]\n\
- mov r1, #0x6\n\
- add r3, r6, #0\n\
- bl PrintTextOnWindow\n\
- ldrb r0, [r5]\n\
- mov r1, #0x3\n\
- bl CopyWindowToVram\n\
- mov r0, #0\n\
- add sp, #0x20\n\
- pop {r3}\n\
- mov r8, r3\n\
- pop {r4-r7}\n\
- pop {r1}\n\
- bx r1\n\
- .pool");
}
bool8 ScrCmd_cmdDA(struct ScriptContext *ctx)
@@ -1757,7 +1612,7 @@ bool8 ScrCmd_buffernumberstring(struct ScriptContext *ctx)
{
u8 stringVarIndex = ScriptReadByte(ctx);
u16 v1 = VarGet(ScriptReadHalfword(ctx));
- u8 v2 = sub_80EF370(v1);
+ u8 v2 = CountDigits(v1);
ConvertIntToDecimalStringN(sScriptStringVars[stringVarIndex], v1, 0, v2);
return FALSE;
@@ -2055,7 +1910,7 @@ bool8 ScrCmd_playslotmachine(struct ScriptContext *ctx)
{
u8 slotMachineIndex = VarGet(ScriptReadHalfword(ctx));
- PlaySlotMachine(slotMachineIndex, c2_exit_to_overworld_1_continue_scripts_restart_music);
+ PlaySlotMachine(slotMachineIndex, CB2_ReturnToFieldContinueScript);
ScriptContext1_Stop();
return TRUE;
}
diff --git a/src/script.c b/src/script.c
index 5a1c5daa9..8c868128b 100644
--- a/src/script.c
+++ b/src/script.c
@@ -243,7 +243,7 @@ void ScriptContext2_RunNewScript(const u8 *ptr)
u8 *mapheader_get_tagged_pointer(u8 tag)
{
- u8 *mapScripts = gMapHeader.mapScripts;
+ const u8 *mapScripts = gMapHeader.mapScripts;
if (!mapScripts)
return NULL;
diff --git a/src/script_movement.c b/src/script_movement.c
new file mode 100644
index 000000000..bbeb0eedc
--- /dev/null
+++ b/src/script_movement.c
@@ -0,0 +1,233 @@
+#include "global.h"
+#include "script_movement.h"
+#include "field_map_obj.h"
+#include "field_map_obj_helpers.h"
+#include "task.h"
+#include "util.h"
+
+// static functions
+static void sub_80D33AC(u8);
+static u8 sub_80D33F4(void);
+static bool8 sub_80D3408(u8, u8, const u8 *);
+static u8 sub_80D3474(u8, u8);
+static bool8 sub_80D3584(u8, u8);
+static void sub_80D35DC(u8, u8, u8, const u8 *);
+static void UnfreezeObjects(u8);
+static void sub_80D3660(u8);
+static void sub_80A2490(u8, u8, u8, const u8 *);
+
+// EWRAM_DATA
+static EWRAM_DATA const u8 *gUnknown_02039D90[16] = {0};
+
+// text
+bool8 ScriptMovement_StartObjectMovementScript(u8 localId, u8 mapNum, u8 mapGroup, const u8 *movementScript)
+{
+ u8 mapObjId;
+
+ if (TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjId))
+ return TRUE;
+ if (!FuncIsActiveTask(sub_80D3660))
+ sub_80D33AC(50);
+ return sub_80D3408(sub_80D33F4(), mapObjId, movementScript);
+}
+
+bool8 ScriptMovement_IsObjectMovementFinished(u8 localId, u8 mapNum, u8 mapBank)
+{
+ u8 mapObjId;
+ u8 r4;
+ u8 r1;
+
+ if (TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapBank, &mapObjId))
+ return TRUE;
+ r4 = sub_80D33F4();
+ r1 = sub_80D3474(r4, mapObjId);
+ if (r1 == 16)
+ return TRUE;
+ return sub_80D3584(r4, r1);
+}
+
+void sub_80D338C(void)
+{
+ u8 taskId;
+
+ taskId = sub_80D33F4();
+ if (taskId != 0xFF)
+ {
+ UnfreezeObjects(taskId);
+ DestroyTask(taskId);
+ }
+}
+
+
+static void sub_80D33AC(u8 priority)
+{
+ u8 taskId;
+ u8 i;
+
+ taskId = CreateTask(sub_80D3660, priority);
+ for (i = 1; i < 16; i++)
+ gTasks[taskId].data[i] = 0xFFFF;
+}
+
+static u8 sub_80D33F4(void)
+{
+ return FindTaskIdByFunc(sub_80D3660);
+}
+
+static bool8 sub_80D3408(u8 taskId, u8 mapObjId, const u8 *movementScript)
+{
+ u8 r4;
+
+ r4 = sub_80D3474(taskId, mapObjId);
+ if (r4 != 16)
+ {
+ if (sub_80D3584(taskId, r4) == 0)
+ {
+ return TRUE;
+ }
+ else
+ {
+ sub_80D35DC(taskId, r4, mapObjId, movementScript);
+ return FALSE;
+ }
+ }
+ r4 = sub_80D3474(taskId, 0xFF);
+ if (r4 == 16)
+ {
+ return TRUE;
+ }
+ else
+ {
+ sub_80D35DC(taskId, r4, mapObjId, movementScript);
+ return FALSE;
+ }
+}
+
+static u8 sub_80D3474(u8 taskId, u8 b)
+{
+ u8 *ptr;
+ u8 i;
+
+ ptr = (u8 *)&gTasks[taskId].data[1];
+ for (i = 0; i < 16; i++, ptr++)
+ {
+ if (*ptr == b)
+ return i;
+ }
+ return 16;
+}
+
+static void sub_80D34B0(u8 taskId, u8 b, u8 **c)
+{
+ u8 i;
+
+ *c = (u8 *)&gTasks[taskId].data[1];
+ for (i = 0; i < b; i++, (*c)++)
+ ;
+}
+
+static void sub_80D34E4(u8 taskId, u8 b, u8 c)
+{
+ u8 *ptr;
+
+ sub_80D34B0(taskId, b, &ptr);
+ *ptr = c; //what is this supposed to do?
+}
+
+static void sub_80D3508(u8 taskId, u8 b, u8 *c)
+{
+ u8 *ptr;
+
+ sub_80D34B0(taskId, b, &ptr);
+ *c = *ptr;
+}
+
+static void sub_80D352C(u8 a, u8 b)
+{
+ u16 var = ~gBitTable[b];
+
+ gTasks[a].data[0] &= var;
+}
+
+static void sub_80D355C(u8 taskId, u8 b)
+{
+ gTasks[taskId].data[0] |= gBitTable[b];
+}
+
+static bool8 sub_80D3584(u8 taskId, u8 b)
+{
+ u16 var = (u16)gTasks[taskId].data[0] & gBitTable[b];
+
+ if (var != 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static void npc_obj_offscreen_culling_and_flag_update(u8 a, const u8 *movementScript)
+{
+ gUnknown_02039D90[a] = movementScript;
+}
+
+static const u8 *sub_80D35CC(u8 a)
+{
+ return gUnknown_02039D90[a];
+}
+
+static void sub_80D35DC(u8 taskId, u8 b, u8 mapObjId, const u8 *movementScript)
+{
+ sub_80D352C(taskId, b);
+ npc_obj_offscreen_culling_and_flag_update(b, movementScript);
+ sub_80D34E4(taskId, b, mapObjId);
+}
+
+static void UnfreezeObjects(u8 taskId)
+{
+ u8 *pMapObjId;
+ u8 i;
+
+ pMapObjId = (u8 *)&gTasks[taskId].data[1];
+ for (i = 0; i < 16; i++, pMapObjId++)
+ {
+ if (*pMapObjId != 0xFF)
+ npc_sync_anim_pause_bits(&gMapObjects[*pMapObjId]);
+ }
+}
+
+static void sub_80D3660(u8 taskId)
+{
+ u8 i;
+ u8 var;
+
+ for (i = 0; i < 16; i++)
+ {
+ sub_80D3508(taskId, i, &var);
+ if (var != 0xFF)
+ sub_80A2490(taskId, i, var, sub_80D35CC(i));
+ }
+}
+
+static void sub_80A2490(u8 taskId, u8 b, u8 mapObjId, const u8 *d)
+{
+ u8 var;
+
+ if (FieldObjectIsSpecialAnimActive(&gMapObjects[mapObjId])
+ && !FieldObjectClearAnimIfSpecialAnimFinished(&gMapObjects[mapObjId]))
+ return;
+
+ var = *d;
+ if (var == 0xFE)
+ {
+ sub_80D355C(taskId, b);
+ FreezeMapObject(&gMapObjects[mapObjId]);
+ }
+ else
+ {
+ if (!FieldObjectSetSpecialAnim(&gMapObjects[mapObjId], var))
+ {
+ d++;
+ npc_obj_offscreen_culling_and_flag_update(b, d);
+ }
+ }
+}
+
diff --git a/src/secret_base.c b/src/secret_base.c
index e3c06a75d..e2b7e20f1 100644
--- a/src/secret_base.c
+++ b/src/secret_base.c
@@ -3,10 +3,11 @@
#include "global.h"
#include "constants/decorations.h"
#include "malloc.h"
+#include "main.h"
#include "task.h"
#include "palette.h"
-#include "list_menu.h"
#include "window.h"
+#include "list_menu.h"
#include "menu.h"
#include "menu_helpers.h"
#include "menu_indicators.h"
@@ -39,6 +40,8 @@
#include "tv.h"
#include "secret_base.h"
+extern void mapldr_default(void);
+
// Static type declarations
struct SecretBaseListMenuBuffer {
@@ -61,7 +64,7 @@ EWRAM_DATA struct SecretBaseListMenuBuffer *gUnknown_0203A020 = NULL;
void sub_80E9C9C(u8 taskId);
void game_continue(u8 taskId);
-void sub_80E9DEC(u32 a0, bool8 flag, struct ListMenu *menu);
+void sub_80E9DEC(s32 a0, bool8 flag, struct ListMenu *menu);
void sub_80E9E00(u8 taskId);
void sub_80E9E44(u8 taskId);
void sub_80E9E90(u8 taskId);
@@ -244,7 +247,7 @@ void sub_80E8C98(void)
void sub_80E8CB0(s16 *xPtr, s16 *yPtr, u16 tile)
{
- struct MapData *mapData;
+ const struct MapData *mapData;
s16 x;
s16 y;
@@ -322,7 +325,7 @@ void sub_80E8E18(void)
VarSet(VAR_SECRET_BASE_MAP, gMapHeader.regionMapSectionId);
}
-void sub_80E8EE0(struct MapEvents *events)
+void sub_80E8EE0(struct MapEvents const *events)
{
u16 bgEventIndex;
u16 i;
@@ -386,7 +389,7 @@ void sub_80E8FD0(u8 taskId)
sub_80E8F9C();
warp_in();
gFieldCallback = sub_80AF168;
- SetMainCallback2(c2_load_new_map);
+ SetMainCallback2(CB2_LoadMap);
DestroyTask(taskId);
break;
}
@@ -411,7 +414,7 @@ bool8 sub_80E909C(void)
void sub_80E90C8(u8 taskId)
{
FieldObjectTurn(&gMapObjects[gPlayerAvatar.mapObjectId], DIR_NORTH);
- if (sub_80ABDFC() == TRUE)
+ if (IsWeatherNotFadingIn() == TRUE)
{
EnableBothScriptContexts();
DestroyTask(taskId);
@@ -444,7 +447,7 @@ void sub_80E916C(u8 taskId)
Overworld_SetWarpDestination(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, -1, gUnknown_0858CFE8[idx + 2], gUnknown_0858CFE8[idx + 3]);
warp_in();
gFieldCallback = sub_80E9108;
- SetMainCallback2(c2_load_new_map);
+ SetMainCallback2(CB2_LoadMap);
DestroyTask(taskId);
}
}
@@ -642,7 +645,7 @@ void sub_80E96A4(u8 taskId)
copy_saved_warp2_bank_and_enter_x_to_warp1(0x7e);
warp_in();
gFieldCallback = mapldr_default;
- SetMainCallback2(c2_load_new_map);
+ SetMainCallback2(CB2_LoadMap);
ScriptContext2_Disable();
DestroyTask(taskId);
break;
@@ -773,7 +776,7 @@ void sub_80E9AD0(void)
u16 i;
u16 j;
s16 tile;
- struct MapEvents *events;
+ const struct MapEvents *events;
events = gMapHeader.events;
for (i = 0; i < events->bgEventCount; i ++)
@@ -908,13 +911,13 @@ void game_continue(u8 taskId)
data[3] = 8;
}
gMultiuseListMenuTemplate = gUnknown_0858D07C;
- gMultiuseListMenuTemplate.unk_10 = data[6];
+ gMultiuseListMenuTemplate.windowId = data[6];
gMultiuseListMenuTemplate.totalItems = data[0];
gMultiuseListMenuTemplate.items = gUnknown_0203A020->items;
gMultiuseListMenuTemplate.maxShowed = data[3];
}
-void sub_80E9DEC(u32 a0, bool8 flag, struct ListMenu *menu)
+void sub_80E9DEC(s32 a0, bool8 flag, struct ListMenu *menu)
{
if (flag != TRUE)
{
@@ -948,14 +951,14 @@ void sub_80E9E90(u8 taskId)
data = gTasks[taskId].data;
input = ListMenuHandleInputGetItemId(data[5]);
- sub_81AE860(data[5], &data[2], &data[1]);
+ ListMenuGetScrollAndRow(data[5], &data[2], &data[1]);
switch (input)
{
case -1:
break;
case -2:
PlaySE(SE_SELECT);
- sub_81AE6C8(data[5], NULL, NULL);
+ DestroyListMenuTask(data[5], NULL, NULL);
RemoveScrollIndicatorArrowPair(data[8]);
sub_819746C(data[6], 0);
ClearWindowTilemap(data[6]);
@@ -1037,7 +1040,7 @@ void sub_80EA08C(u8 taskId)
data = gTasks[taskId].data;
sub_8197434(0, 0);
- sub_81AE6C8(data[5], &data[2], &data[1]);
+ DestroyListMenuTask(data[5], &data[2], &data[1]);
gSaveBlock1Ptr->secretBases[data[4]].sbr_field_1_6 = 0;
game_continue(taskId);
sub_812225C(&data[2], &data[1], data[3], data[0]);
@@ -1056,7 +1059,7 @@ void sub_80EA13C(u8 taskId)
data = gTasks[taskId].data;
sub_8197434(0, 0);
- sub_81AE6C8(data[5], &data[2], &data[1]);
+ DestroyListMenuTask(data[5], &data[2], &data[1]);
sub_80E9E00(taskId);
gTasks[taskId].func = sub_80E9E90;
}
diff --git a/src/smokescreen.c b/src/smokescreen.c
new file mode 100644
index 000000000..9b37cd234
--- /dev/null
+++ b/src/smokescreen.c
@@ -0,0 +1,71 @@
+#include "global.h"
+#include "data2.h"
+#include "decompress.h"
+#include "sprite.h"
+#include "util.h"
+
+static void sub_8075370(struct Sprite *);
+
+u8 sub_807521C(s16 x, s16 y, u8 a3)
+{
+ u8 mainSpriteId;
+ u8 spriteId1, spriteId2, spriteId3, spriteId4;
+ struct Sprite *mainSprite;
+
+ if (GetSpriteTileStartByTag(gUnknown_0831C620.tag) == 0xFFFF)
+ {
+ LoadCompressedObjectPicUsingHeap(&gUnknown_0831C620);
+ LoadCompressedObjectPaletteUsingHeap(&gUnknown_0831C628);
+ }
+
+ mainSpriteId = CreateInvisibleSpriteWithCallback(sub_8075370);
+ mainSprite = &gSprites[mainSpriteId];
+ mainSprite->data[1] = a3;
+
+ spriteId1 = CreateSprite(&gUnknown_0831C688, x - 16, y - 16, 2);
+ gSprites[spriteId1].data[0] = mainSpriteId;
+ mainSprite->data[0]++;
+ AnimateSprite(&gSprites[spriteId1]);
+
+ spriteId2 = CreateSprite(&gUnknown_0831C688, x, y - 16, 2);
+ gSprites[spriteId2].data[0] = mainSpriteId;
+ mainSprite->data[0]++;
+ StartSpriteAnim(&gSprites[spriteId2], 1);
+ AnimateSprite(&gSprites[spriteId2]);
+
+ spriteId3 = CreateSprite(&gUnknown_0831C688, x - 16, y, 2);
+ gSprites[spriteId3].data[0] = mainSpriteId;
+ mainSprite->data[0]++;
+ StartSpriteAnim(&gSprites[spriteId3], 2);
+ AnimateSprite(&gSprites[spriteId3]);
+
+ spriteId4 = CreateSprite(&gUnknown_0831C688, x, y, 2);
+ gSprites[spriteId4].data[0] = mainSpriteId;
+ mainSprite->data[0]++;
+ StartSpriteAnim(&gSprites[spriteId4], 3);
+ AnimateSprite(&gSprites[spriteId4]);
+
+ return mainSpriteId;
+}
+
+static void sub_8075370(struct Sprite *sprite)
+{
+ if (!sprite->data[0])
+ {
+ FreeSpriteTilesByTag(gUnknown_0831C620.tag);
+ FreeSpritePaletteByTag(gUnknown_0831C628.tag);
+ if (!sprite->data[1])
+ DestroySprite(sprite);
+ else
+ sprite->callback = SpriteCallbackDummy;
+ }
+}
+
+void sub_80753B4(struct Sprite *sprite)
+{
+ if (sprite->animEnded)
+ {
+ gSprites[sprite->data[0]].data[0]--;
+ DestroySprite(sprite);
+ }
+}
diff --git a/src/start_menu.c b/src/start_menu.c
index d076d307d..c248ca86b 100644
--- a/src/start_menu.c
+++ b/src/start_menu.c
@@ -8,6 +8,31 @@
#include "text.h"
#include "strings.h"
#include "bg.h"
+#include "field_effect.h"
+#include "task.h"
+#include "overworld.h"
+#include "link.h"
+#include "battle_frontier_2.h"
+#include "rom_818CFC8.h"
+#include "field_specials.h"
+#include "field_map_obj_helpers.h"
+#include "script.h"
+#include "main.h"
+#include "sound.h"
+#include "pokedex.h"
+#include "field_weather.h"
+#include "palette.h"
+#include "item_menu.h"
+#include "option_menu.h"
+#include "event_scripts.h"
+#include "save.h"
+#include "gpu_regs.h"
+#include "scanline_effect.h"
+#include "text_window.h"
+#include "load_save.h"
+#include "international_string_util.h"
+#include "constants/songs.h"
+#include "field_player_avatar.h"
// Menu actions
enum
@@ -27,49 +52,99 @@ enum
MENU_ACTION_PYRAMID_BAG
};
-extern bool32 is_c1_link_related_active(void);
-extern bool32 InUnionRoom(void);
-extern bool8 InBattlePike(void);
-extern bool8 InBattlePyramid(void);
-extern bool8 InMultiBattleRoom(void);
-extern void NewMenuHelpers_DrawStdWindowFrame(u8 windowId, u8 a1);
-extern void sub_8198070(u8 windowId, u8 a1);
-
-// this file's functions
-static void BuildStartMenuActions_LinkMode(void);
-static void BuildStartMenuActions_UnionRoom(void);
-static void BuildStartMenuActions_SafariZone(void);
-static void BuildStartMenuActions_BattlePike(void);
-static void BuildStartMenuActions_BattlePyramid(void);
-static void BuildStartMenuActions_MultiBattleRoom(void);
-static void BuildStartMenuActions_Normal(void);
-bool8 StartMenu_Pokedex(void);
-bool8 StartMenu_Pokemon(void);
-bool8 StartMenu_Bag(void);
-bool8 StartMenu_PokeNav(void);
-bool8 StartMenu_PlayerName(void);
-bool8 StartMenu_Save(void);
-bool8 StartMenu_Option(void);
-bool8 StartMenu_Exit(void);
-bool8 StartMenu_SafariZoneRetire(void);
-bool8 StartMenu_LinkModePlayerName(void);
-bool8 StartMenu_BattlePyramidRetire(void);
-bool8 StartMenu_BattlePyramidBag(void);
-
-// EWRAM vars
-EWRAM_DATA u8 sSafariBallsWindowId = 0;
-EWRAM_DATA u8 sBattlePyramidFloorWindowId = 0;
-EWRAM_DATA u8 sStartMenuCursorPos = 0;
-EWRAM_DATA u8 sNumStartMenuActions = 0;
-EWRAM_DATA u8 sCurrentStartMenuActions[9] = {0};
-EWRAM_DATA u8 gUnknown_02037619[2] = {0};
-EWRAM_DATA bool8 (*gUnknown_0203761C)(void) = NULL;
-EWRAM_DATA u8 gUnknown_02037620 = 0;
-EWRAM_DATA u8 gUnknown_02037621 = 0;
-EWRAM_DATA u8 gUnknown_02037622 = 0;
-
-// const rom data
-static const struct WindowTemplate gSafariBallsWindowTemplate = {0, 1, 1, 9, 4, 0xF, 8};
+// Save status
+enum
+{
+ SAVE_IN_PROGRESS,
+ SAVE_SUCCESS,
+ SAVE_CANCELED,
+ SAVE_ERROR
+};
+
+EWRAM_DATA static u8 sSafariBallsWindowId = 0;
+EWRAM_DATA static u8 sBattlePyramidFloorWindowId = 0;
+EWRAM_DATA static u8 sStartMenuCursorPos = 0;
+EWRAM_DATA static u8 sNumStartMenuActions = 0;
+EWRAM_DATA static u8 sCurrentStartMenuActions[9] = {0};
+EWRAM_DATA static u8 sUnknown_02037619[2] = {0};
+
+EWRAM_DATA static u8 (*sSaveDialogCallback)(void) = NULL;
+EWRAM_DATA static u8 sSaveDialogTimer = 0;
+EWRAM_DATA static bool8 sSavingComplete = FALSE;
+EWRAM_DATA static u8 sSaveInfoWindowId = 0;
+
+// Extern variables
+extern u8 gDifferentSaveFile;
+extern u16 gSaveFileStatus;
+extern u8 gUnknown_03005DB4;
+
+// Extern functions in uncompiled files
+extern void sub_80AF688(void);
+extern void var_800D_set_xB(void);
+extern void sub_808B864(void);
+extern void sub_80BB534(void);
+extern void play_some_sound(void);
+extern void CB2_PartyMenuFromStartMenu(void);
+extern void CB2_PokeNav(void);
+extern void sub_80C4DDC(void (*)(void));
+extern void sub_80C51C4(void (*)(void));
+extern void sub_80C4E74(u8, void (*)(void));
+extern void sub_81C4EFC(void);
+extern void sub_80984F4(void);
+extern void sub_81A9EC8(void);
+extern void save_serialize_map(void);
+extern void sub_81A9E90(void);
+
+// Menu action callbacks
+static bool8 StartMenuPokedexCallback(void);
+static bool8 StartMenuPokemonCallback(void);
+static bool8 StartMenuBagCallback(void);
+static bool8 StartMenuPokeNavCallback(void);
+static bool8 StartMenuPlayerNameCallback(void);
+static bool8 StartMenuSaveCallback(void);
+static bool8 StartMenuOptionCallback(void);
+static bool8 StartMenuExitCallback(void);
+static bool8 StartMenuSafariZoneRetireCallback(void);
+static bool8 StartMenuLinkModePlayerNameCallback(void);
+static bool8 StartMenuBattlePyramidRetireCallback(void);
+static bool8 StartMenuBattlePyramidBagCallback(void);
+
+// Menu callbacks
+static bool8 SaveStartCallback(void);
+static bool8 SaveCallback(void);
+static bool8 BattlePyramidRetireStartCallback(void);
+static bool8 BattlePyramidRetireReturnCallback(void);
+static bool8 BattlePyramidRetireCallback(void);
+static bool8 HandleStartMenuInput(void);
+
+// Save dialog callbacks
+static u8 SaveConfirmSaveCallback(void);
+static u8 SaveYesNoCallback(void);
+static u8 SaveConfirmInputCallback(void);
+static u8 SaveFileExistsCallback(void);
+static u8 SaveConfirmOverwriteNoCallback(void);
+static u8 SaveConfirmOverwriteCallback(void);
+static u8 SaveOverwriteInputCallback(void);
+static u8 SaveSavingMessageCallback(void);
+static u8 SaveDoSaveCallback(void);
+static u8 SaveSuccessCallback(void);
+static u8 SaveReturnSuccessCallback(void);
+static u8 SaveErrorCallback(void);
+static u8 SaveReturnErrorCallback(void);
+static u8 BattlePyramidConfirmRetireCallback(void);
+static u8 BattlePyramidRetireYesNoCallback(void);
+static u8 BattlePyramidRetireInputCallback(void);
+
+// Task callbacks
+static void StartMenuTask(u8 taskId);
+static void SaveGameTask(u8 taskId);
+static void sub_80A0550(u8 taskId);
+static void sub_80A08A4(u8 taskId);
+
+// Some other callback
+static bool8 sub_809FA00(void);
+
+static const struct WindowTemplate sSafariBallsWindowTemplate = {0, 1, 1, 9, 4, 0xF, 8};
static const u8* const sPyramindFloorNames[] =
{
@@ -83,27 +158,27 @@ static const u8* const sPyramindFloorNames[] =
gText_Peak
};
-static const struct WindowTemplate gPyramidFloorWindowTemplate_2 = {0, 1, 1, 0xA, 4, 0xF, 8};
-static const struct WindowTemplate gPyramidFloorWindowTemplate_1 = {0, 1, 1, 0xC, 4, 0xF, 8};
-
-const struct MenuAction sStartMenuItems[] =
-{
- {gText_MenuPokedex, {.u8_void = StartMenu_Pokedex}},
- {gText_MenuPokemon, {.u8_void = StartMenu_Pokemon}},
- {gText_MenuBag, {.u8_void = StartMenu_Bag}},
- {gText_MenuPokenav, {.u8_void = StartMenu_PokeNav}},
- {gText_MenuPlayer, {.u8_void = StartMenu_PlayerName}},
- {gText_MenuSave, {.u8_void = StartMenu_Save}},
- {gText_MenuOption, {.u8_void = StartMenu_Option}},
- {gText_MenuExit, {.u8_void = StartMenu_Exit}},
- {gText_MenuRetire, {.u8_void = StartMenu_SafariZoneRetire}},
- {gText_MenuPlayer, {.u8_void = StartMenu_LinkModePlayerName}},
- {gText_MenuRest, {.u8_void = StartMenu_Save}},
- {gText_MenuRetire, {.u8_void = StartMenu_BattlePyramidRetire}},
- {gText_MenuBag, {.u8_void = StartMenu_BattlePyramidBag}}
+static const struct WindowTemplate sPyramidFloorWindowTemplate_2 = {0, 1, 1, 0xA, 4, 0xF, 8};
+static const struct WindowTemplate sPyramidFloorWindowTemplate_1 = {0, 1, 1, 0xC, 4, 0xF, 8};
+
+static const struct MenuAction sStartMenuItems[] =
+{
+ {gText_MenuPokedex, {.u8_void = StartMenuPokedexCallback}},
+ {gText_MenuPokemon, {.u8_void = StartMenuPokemonCallback}},
+ {gText_MenuBag, {.u8_void = StartMenuBagCallback}},
+ {gText_MenuPokenav, {.u8_void = StartMenuPokeNavCallback}},
+ {gText_MenuPlayer, {.u8_void = StartMenuPlayerNameCallback}},
+ {gText_MenuSave, {.u8_void = StartMenuSaveCallback}},
+ {gText_MenuOption, {.u8_void = StartMenuOptionCallback}},
+ {gText_MenuExit, {.u8_void = StartMenuExitCallback}},
+ {gText_MenuRetire, {.u8_void = StartMenuSafariZoneRetireCallback}},
+ {gText_MenuPlayer, {.u8_void = StartMenuLinkModePlayerNameCallback}},
+ {gText_MenuRest, {.u8_void = StartMenuSaveCallback}},
+ {gText_MenuRetire, {.u8_void = StartMenuBattlePyramidRetireCallback}},
+ {gText_MenuBag, {.u8_void = StartMenuBattlePyramidBagCallback}}
};
-const struct BgTemplate gUnknown_085105A8[] =
+static const struct BgTemplate sUnknown_085105A8[] =
{
{
.bg = 0,
@@ -116,15 +191,47 @@ const struct BgTemplate gUnknown_085105A8[] =
}
};
-const struct WindowTemplate gUnknown_085105AC[] =
+static const struct WindowTemplate sUnknown_085105AC[] =
{
{0, 2, 0xF, 0x1A, 4, 0xF, 0x194},
DUMMY_WIN_TEMPLATE
};
-const struct WindowTemplate gUnknown_085105BC = {0, 1, 1, 0xE, 0xA, 0xF, 8};
+static const struct WindowTemplate sSaveInfoWindowTemplate = {0, 1, 1, 0xE, 0xA, 0xF, 8};
+
+// Local functions
+static void BuildStartMenuActions(void);
+static void AddStartMenuAction(u8 action);
+static void BuildNormalStartMenu(void);
+static void BuildSafariZoneStartMenu(void);
+static void BuildLinkModeStartMenu(void);
+static void BuildUnionRoomStartMenu(void);
+static void BuildBattlePikeStartMenu(void);
+static void BuildBattlePyramidStartMenu(void);
+static void BuildMultiBattleRoomStartMenu(void);
+static void ShowSafariBallsWindow(void);
+static void ShowPyramidFloorWindow(void);
+static void RemoveExtraStartMenuWindows(void);
+static bool32 PrintStartMenuActions(s8 *pIndex, u32 count);
+static bool32 InitStartMenuStep(void);
+static void InitStartMenu(void);
+static void CreateStartMenuTask(TaskFunc followupFunc);
+static void InitSave(void);
+static u8 RunSaveCallback(void);
+static void ShowSaveMessage(const u8 *message, u8 (*saveCallback)(void));
+static void sub_80A0014(void);
+static void HideSaveInfoWindow(void);
+static void SaveStartTimer(void);
+static bool8 SaveSuccesTimer(void);
+static bool8 SaveErrorTimer(void);
+static void InitBattlePyramidRetire(void);
+static void sub_80A03D8(void);
+static bool32 sub_80A03E4(u8 *par1);
+static void sub_80A0540(void);
+static void ShowSaveInfoWindow(void);
+static void RemoveSaveInfoWindow(void);
+static void HideStartMenuWindow(void);
-// code
void SetDexPokemonPokenavFlags(void) // unused
{
FlagSet(FLAG_SYS_POKEDEX_GET);
@@ -132,46 +239,70 @@ void SetDexPokemonPokenavFlags(void) // unused
FlagSet(FLAG_SYS_POKENAV_GET);
}
-void BuildStartMenuActions(void)
+static void BuildStartMenuActions(void)
{
sNumStartMenuActions = 0;
+
if (is_c1_link_related_active() == TRUE)
- BuildStartMenuActions_LinkMode();
+ {
+ BuildLinkModeStartMenu();
+ }
else if (InUnionRoom() == TRUE)
- BuildStartMenuActions_UnionRoom();
+ {
+ BuildUnionRoomStartMenu();
+ }
else if (GetSafariZoneFlag() == TRUE)
- BuildStartMenuActions_SafariZone();
+ {
+ BuildSafariZoneStartMenu();
+ }
else if (InBattlePike())
- BuildStartMenuActions_BattlePike();
+ {
+ BuildBattlePikeStartMenu();
+ }
else if (InBattlePyramid())
- BuildStartMenuActions_BattlePyramid();
+ {
+ BuildBattlePyramidStartMenu();
+ }
else if (InMultiBattleRoom())
- BuildStartMenuActions_MultiBattleRoom();
+ {
+ BuildMultiBattleRoomStartMenu();
+ }
else
- BuildStartMenuActions_Normal();
+ {
+ BuildNormalStartMenu();
+ }
}
-void AddStartMenuAction(u8 action)
+static void AddStartMenuAction(u8 action)
{
AppendToList(sCurrentStartMenuActions, &sNumStartMenuActions, action);
}
-static void BuildStartMenuActions_Normal(void)
+static void BuildNormalStartMenu(void)
{
if (FlagGet(FLAG_SYS_POKEDEX_GET) == TRUE)
+ {
AddStartMenuAction(MENU_ACTION_POKEDEX);
+ }
if (FlagGet(FLAG_SYS_POKEMON_GET) == TRUE)
+ {
AddStartMenuAction(MENU_ACTION_POKEMON);
+ }
+
AddStartMenuAction(MENU_ACTION_BAG);
+
if (FlagGet(FLAG_SYS_POKENAV_GET) == TRUE)
+ {
AddStartMenuAction(MENU_ACTION_POKENAV);
+ }
+
AddStartMenuAction(MENU_ACTION_PLAYER);
AddStartMenuAction(MENU_ACTION_SAVE);
AddStartMenuAction(MENU_ACTION_OPTION);
AddStartMenuAction(MENU_ACTION_EXIT);
}
-static void BuildStartMenuActions_SafariZone(void)
+static void BuildSafariZoneStartMenu(void)
{
AddStartMenuAction(MENU_ACTION_RETIRE_SAFARI);
AddStartMenuAction(MENU_ACTION_POKEDEX);
@@ -182,29 +313,37 @@ static void BuildStartMenuActions_SafariZone(void)
AddStartMenuAction(MENU_ACTION_EXIT);
}
-static void BuildStartMenuActions_LinkMode(void)
+static void BuildLinkModeStartMenu(void)
{
AddStartMenuAction(MENU_ACTION_POKEMON);
AddStartMenuAction(MENU_ACTION_BAG);
+
if (FlagGet(FLAG_SYS_POKENAV_GET) == TRUE)
+ {
AddStartMenuAction(MENU_ACTION_POKENAV);
+ }
+
AddStartMenuAction(MENU_ACTION_PLAYER_LINK);
AddStartMenuAction(MENU_ACTION_OPTION);
AddStartMenuAction(MENU_ACTION_EXIT);
}
-static void BuildStartMenuActions_UnionRoom(void)
+static void BuildUnionRoomStartMenu(void)
{
AddStartMenuAction(MENU_ACTION_POKEMON);
AddStartMenuAction(MENU_ACTION_BAG);
+
if (FlagGet(FLAG_SYS_POKENAV_GET) == TRUE)
+ {
AddStartMenuAction(MENU_ACTION_POKENAV);
+ }
+
AddStartMenuAction(MENU_ACTION_PLAYER);
AddStartMenuAction(MENU_ACTION_OPTION);
AddStartMenuAction(MENU_ACTION_EXIT);
}
-static void BuildStartMenuActions_BattlePike(void)
+static void BuildBattlePikeStartMenu(void)
{
AddStartMenuAction(MENU_ACTION_POKEDEX);
AddStartMenuAction(MENU_ACTION_POKEMON);
@@ -213,7 +352,7 @@ static void BuildStartMenuActions_BattlePike(void)
AddStartMenuAction(MENU_ACTION_EXIT);
}
-static void BuildStartMenuActions_BattlePyramid(void)
+static void BuildBattlePyramidStartMenu(void)
{
AddStartMenuAction(MENU_ACTION_POKEMON);
AddStartMenuAction(MENU_ACTION_PYRAMID_BAG);
@@ -224,7 +363,7 @@ static void BuildStartMenuActions_BattlePyramid(void)
AddStartMenuAction(MENU_ACTION_EXIT);
}
-static void BuildStartMenuActions_MultiBattleRoom(void)
+static void BuildMultiBattleRoomStartMenu(void)
{
AddStartMenuAction(MENU_ACTION_POKEMON);
AddStartMenuAction(MENU_ACTION_PLAYER);
@@ -232,74 +371,1056 @@ static void BuildStartMenuActions_MultiBattleRoom(void)
AddStartMenuAction(MENU_ACTION_EXIT);
}
-void DisplaySafariBallsWindow(void)
+static void ShowSafariBallsWindow(void)
{
- sSafariBallsWindowId = AddWindow(&gSafariBallsWindowTemplate);
+ sSafariBallsWindowId = AddWindow(&sSafariBallsWindowTemplate);
PutWindowTilemap(sSafariBallsWindowId);
- NewMenuHelpers_DrawStdWindowFrame(sSafariBallsWindowId, 0);
+ NewMenuHelpers_DrawStdWindowFrame(sSafariBallsWindowId, FALSE);
ConvertIntToDecimalStringN(gStringVar1, gNumSafariBalls, STR_CONV_MODE_RIGHT_ALIGN, 2);
StringExpandPlaceholders(gStringVar4, gText_SafariBallStock);
PrintTextOnWindow(sSafariBallsWindowId, 1, gStringVar4, 0, 1, 0xFF, NULL);
CopyWindowToVram(sSafariBallsWindowId, 2);
}
-void DisplayPyramidFloorWindow(void)
+static void ShowPyramidFloorWindow(void)
{
- // TODO: fix location
- if (gSaveBlock2Ptr->field_CAA[4] == 7)
- sBattlePyramidFloorWindowId = AddWindow(&gPyramidFloorWindowTemplate_1);
+ if (gSaveBlock2Ptr->field_CAA[4] == 7) // TODO: fix location
+ {
+ sBattlePyramidFloorWindowId = AddWindow(&sPyramidFloorWindowTemplate_1);
+ }
else
- sBattlePyramidFloorWindowId = AddWindow(&gPyramidFloorWindowTemplate_2);
+ {
+ sBattlePyramidFloorWindowId = AddWindow(&sPyramidFloorWindowTemplate_2);
+ }
+
PutWindowTilemap(sBattlePyramidFloorWindowId);
- NewMenuHelpers_DrawStdWindowFrame(sBattlePyramidFloorWindowId, 0);
+ NewMenuHelpers_DrawStdWindowFrame(sBattlePyramidFloorWindowId, FALSE);
StringCopy(gStringVar1, sPyramindFloorNames[gSaveBlock2Ptr->field_CAA[4]]);
StringExpandPlaceholders(gStringVar4, gText_BattlePyramidFloor);
PrintTextOnWindow(sBattlePyramidFloorWindowId, 1, gStringVar4, 0, 1, 0xFF, NULL);
CopyWindowToVram(sBattlePyramidFloorWindowId, 2);
}
-void RemoveExtraStartMenuWindows(void)
+static void RemoveExtraStartMenuWindows(void)
{
if (GetSafariZoneFlag())
{
- sub_8198070(sSafariBallsWindowId, 0);
+ sub_8198070(sSafariBallsWindowId, FALSE);
CopyWindowToVram(sSafariBallsWindowId, 2);
RemoveWindow(sSafariBallsWindowId);
}
if (InBattlePyramid())
{
- sub_8198070(sBattlePyramidFloorWindowId, 0);
+ sub_8198070(sBattlePyramidFloorWindowId, FALSE);
RemoveWindow(sBattlePyramidFloorWindowId);
}
}
-/*
-// Prints n menu items starting at *index
-static bool32 PrintStartMenuItemsMultistep(s16 *index, u32 n)
+static bool32 PrintStartMenuActions(s8 *pIndex, u32 count)
{
- s8 _index = *index;
-
+ s8 index = *pIndex;
+
do
{
- if (sStartMenuItems[sCurrentStartMenuActions[_index]].func.u8_void == StartMenu_PlayerName)
+ if (sStartMenuItems[sCurrentStartMenuActions[index]].func.u8_void == StartMenuPlayerNameCallback) {
+ PrintPlayerNameOnWindow(GetStartMenuWindowId(), sStartMenuItems[sCurrentStartMenuActions[index]].text, 8, (index << 4) + 9);
+ }
+ else {
+ StringExpandPlaceholders(gStringVar4, sStartMenuItems[sCurrentStartMenuActions[index]].text);
+ PrintTextOnWindow(GetStartMenuWindowId(), 1, gStringVar4, 8, (index << 4) + 9, 0xFF, NULL);
+ }
+
+ index++;
+ if (index >= sNumStartMenuActions) {
+ *pIndex = index;
+ return TRUE;
+ }
+
+ count--;
+ }
+ while (count != 0);
+
+ *pIndex = index;
+ return FALSE;
+}
+
+static bool32 InitStartMenuStep(void)
+{
+ s8 value = sUnknown_02037619[0];
+
+ switch (value)
+ {
+ case 0:
+ sUnknown_02037619[0]++;
+ break;
+ case 1:
+ BuildStartMenuActions();
+ sUnknown_02037619[0]++;
+ break;
+ case 2:
+ sub_81973A4();
+ NewMenuHelpers_DrawStdWindowFrame(sub_81979C4(sNumStartMenuActions), FALSE);
+ sUnknown_02037619[1] = 0;
+ sUnknown_02037619[0]++;
+ break;
+ case 3:
+ if (GetSafariZoneFlag() != FALSE)
+ {
+ ShowSafariBallsWindow();
+ }
+ if (InBattlePyramid() != FALSE)
+ {
+ ShowPyramidFloorWindow();
+ }
+ sUnknown_02037619[0]++;
+ break;
+ case 4:
+ if (PrintStartMenuActions(&sUnknown_02037619[1], 2) == FALSE)
{
+ break;
+ }
+ sUnknown_02037619[0]++;
+ break;
+ case 5:
+ sStartMenuCursorPos = sub_81983AC(GetStartMenuWindowId(), 1, 0, 9, 16, sNumStartMenuActions, sStartMenuCursorPos);
+ CopyWindowToVram(GetStartMenuWindowId(), TRUE);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void InitStartMenu(void)
+{
+ sUnknown_02037619[0] = 0;
+ sUnknown_02037619[1] = 0;
+ while (!InitStartMenuStep());
+}
+
+static void StartMenuTask(u8 taskId)
+{
+ if (InitStartMenuStep() == TRUE)
+ {
+ SwitchTaskToFollowupFunc(taskId);
+ }
+}
+
+static void CreateStartMenuTask(TaskFunc followupFunc)
+{
+ u8 taskId;
+
+ sUnknown_02037619[0] = 0;
+ sUnknown_02037619[1] = 0;
+ taskId = CreateTask(StartMenuTask, 0x50);
+ SetTaskFuncWithFollowupFunc(taskId, StartMenuTask, followupFunc);
+}
+
+static bool8 sub_809FA00(void)
+{
+ if (InitStartMenuStep() == FALSE)
+ {
+ return FALSE;
+ }
+
+ sub_80AF688();
+ return TRUE;
+}
+
+void sub_809FA18(void) // Called from field_screen.s
+{
+ sUnknown_02037619[0] = 0;
+ sUnknown_02037619[1] = 0;
+ gUnknown_03005DB0 = sub_809FA00;
+}
+
+void sub_809FA34(u8 taskId) // Referenced in field_screen.s and rom_8011DC0.s
+{
+ struct Task* task = &gTasks[taskId];
+ switch(task->data[0])
+ {
+ case 0:
+ if (InUnionRoom() == TRUE)
+ {
+ var_800D_set_xB();
}
- else
+
+ gMenuCallback = HandleStartMenuInput;
+ task->data[0]++;
+ break;
+ case 1:
+ if (gMenuCallback() == TRUE)
{
+ DestroyTask(taskId);
+ }
+ break;
+ }
+}
+
+void ShowStartMenu(void) // Called from overworld.c and field_control_avatar.s
+{
+ if (!is_c1_link_related_active())
+ {
+ FreezeMapObjects();
+ sub_808B864();
+ sub_808BCF4();
+ }
+ CreateStartMenuTask(sub_809FA34);
+ ScriptContext2_Enable();
+}
+static bool8 HandleStartMenuInput(void)
+{
+ if (gMain.newKeys & DPAD_UP)
+ {
+ PlaySE(SE_SELECT);
+ sStartMenuCursorPos = MoveMenuCursor(-1);
+ }
+
+ if (gMain.newKeys & DPAD_DOWN)
+ {
+ PlaySE(SE_SELECT);
+ sStartMenuCursorPos = MoveMenuCursor(1);
+ }
+
+ if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ if (sStartMenuItems[sCurrentStartMenuActions[sStartMenuCursorPos]].func.u8_void == StartMenuPokedexCallback)
+ {
+ if (GetNationalPokedexCount(0) == 0) {
+ return FALSE;
+ }
+ }
+
+ gMenuCallback = sStartMenuItems[sCurrentStartMenuActions[sStartMenuCursorPos]].func.u8_void;
+
+ if (gMenuCallback != StartMenuSaveCallback
+ && gMenuCallback != StartMenuExitCallback
+ && gMenuCallback != StartMenuSafariZoneRetireCallback
+ && gMenuCallback != StartMenuBattlePyramidRetireCallback)
+ {
+ FadeScreen(1, 0);
+ }
+
+ return FALSE;
+ }
+
+ if (gMain.newKeys & (START_BUTTON | B_BUTTON))
+ {
+ RemoveExtraStartMenuWindows();
+ HideStartMenu();
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static bool8 StartMenuPokedexCallback(void)
+{
+ if (!gPaletteFade.active)
+ {
+ IncrementGameStat(GAME_STAT_CHECKED_POKEDEX);
+ play_some_sound();
+ RemoveExtraStartMenuWindows();
+ overworld_free_bg_tilemaps();
+ SetMainCallback2(sub_80BB534); // Display pokedex
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static bool8 StartMenuPokemonCallback(void)
+{
+ if (!gPaletteFade.active)
+ {
+ play_some_sound();
+ RemoveExtraStartMenuWindows();
+ overworld_free_bg_tilemaps();
+ SetMainCallback2(CB2_PartyMenuFromStartMenu); // Display party menu
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static bool8 StartMenuBagCallback(void)
+{
+ if (!gPaletteFade.active)
+ {
+ play_some_sound();
+ RemoveExtraStartMenuWindows();
+ overworld_free_bg_tilemaps();
+ SetMainCallback2(CB2_BagMenuFromStartMenu); // Display bag menu
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static bool8 StartMenuPokeNavCallback(void)
+{
+ if (!gPaletteFade.active)
+ {
+ play_some_sound();
+ RemoveExtraStartMenuWindows();
+ overworld_free_bg_tilemaps();
+ SetMainCallback2(CB2_PokeNav); // Display PokeNav
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static bool8 StartMenuPlayerNameCallback(void)
+{
+ if (!gPaletteFade.active)
+ {
+ play_some_sound();
+ RemoveExtraStartMenuWindows();
+ overworld_free_bg_tilemaps();
+
+ if (is_c1_link_related_active() || InUnionRoom())
+ {
+ sub_80C4DDC(CB2_ReturnToFieldWithOpenMenu); // Display trainer card
+ }
+ else if (FlagGet(FLAG_SYS_FRONTIER_PASS))
+ {
+ sub_80C51C4(CB2_ReturnToFieldWithOpenMenu); // Display frontier pass
+ }
+ else
+ {
+ sub_80C4DDC(CB2_ReturnToFieldWithOpenMenu); // Display trainer card
}
- } while (++_index > sNumStartMenuActions);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static bool8 StartMenuSaveCallback(void)
+{
+ if (InBattlePyramid())
+ {
+ RemoveExtraStartMenuWindows();
+ }
+
+ gMenuCallback = SaveStartCallback; // Display save menu
+
+ return FALSE;
+}
+
+static bool8 StartMenuOptionCallback(void)
+{
+ if (!gPaletteFade.active)
+ {
+ play_some_sound();
+ RemoveExtraStartMenuWindows();
+ overworld_free_bg_tilemaps();
+ SetMainCallback2(CB2_InitOptionMenu); // Display option menu
+ gMain.savedCallback = CB2_ReturnToFieldWithOpenMenu;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static bool8 StartMenuExitCallback(void)
+{
+ RemoveExtraStartMenuWindows();
+ HideStartMenu(); // Hide start menu
+
+ return TRUE;
+}
+
+static bool8 StartMenuSafariZoneRetireCallback(void)
+{
+ RemoveExtraStartMenuWindows();
+ HideStartMenu();
+ SafariZoneRetirePrompt();
+
+ return TRUE;
+}
+
+static bool8 StartMenuLinkModePlayerNameCallback(void)
+{
+ if (!gPaletteFade.active)
+ {
+ play_some_sound();
+ overworld_free_bg_tilemaps();
+ sub_80C4E74(gUnknown_03005DB4, CB2_ReturnToFieldWithOpenMenu);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static bool8 StartMenuBattlePyramidRetireCallback(void)
+{
+ gMenuCallback = BattlePyramidRetireStartCallback; // Confirm retire
+
+ return FALSE;
+}
+
+void sub_809FDD4(void) // Called from battle_frontier_2.s
+{
+ sub_8197DF8(0, FALSE);
+ sub_80984F4();
+ CreateStartMenuTask(sub_809FA34);
+ ScriptContext2_Enable();
+}
+
+static bool8 StartMenuBattlePyramidBagCallback(void)
+{
+ if (!gPaletteFade.active)
+ {
+ play_some_sound();
+ RemoveExtraStartMenuWindows();
+ overworld_free_bg_tilemaps();
+ SetMainCallback2(sub_81C4EFC); // Display battle pyramid bag
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static bool8 SaveStartCallback(void)
+{
+ InitSave();
+ gMenuCallback = SaveCallback;
- if (--n == 0)
+ return FALSE;
+}
+
+static bool8 SaveCallback(void)
+{
+ switch (RunSaveCallback())
{
- *index = _index;
+ case SAVE_IN_PROGRESS:
+ return FALSE;
+ case SAVE_CANCELED: // Back to start menu
+ sub_8197DF8(0, FALSE);
+ InitStartMenu();
+ gMenuCallback = HandleStartMenuInput;
return FALSE;
+ case SAVE_SUCCESS:
+ case SAVE_ERROR: // Close start menu
+ sub_8197DF8(0, TRUE);
+ sub_80984F4();
+ ScriptContext2_Disable();
+ sub_81A9EC8();
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static bool8 BattlePyramidRetireStartCallback(void)
+{
+ InitBattlePyramidRetire();
+ gMenuCallback = BattlePyramidRetireCallback;
+
+ return FALSE;
+}
+
+static bool8 BattlePyramidRetireReturnCallback(void)
+{
+ InitStartMenu();
+ gMenuCallback = HandleStartMenuInput;
+
+ return FALSE;
+}
+
+static bool8 BattlePyramidRetireCallback(void)
+{
+ switch (RunSaveCallback())
+ {
+ case SAVE_SUCCESS: // No (Stay in battle pyramid)
+ RemoveExtraStartMenuWindows();
+ gMenuCallback = BattlePyramidRetireReturnCallback;
+ return FALSE;
+ case SAVE_IN_PROGRESS:
+ return FALSE;
+ case SAVE_CANCELED: // Yes (Retire from battle pyramid)
+ sub_8197DF8(0, TRUE);
+ sub_80984F4();
+ ScriptContext2_Disable();
+ ScriptContext1_SetupScript(BattleFrontier_BattlePyramidEmptySquare_EventScript_252C88);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void InitSave(void)
+{
+ save_serialize_map();
+ sSaveDialogCallback = SaveConfirmSaveCallback;
+ sSavingComplete = FALSE;
+}
+
+static u8 RunSaveCallback(void)
+{
+ // True if text is still printing
+ if (sub_8197224() == TRUE)
+ {
+ return SAVE_IN_PROGRESS;
+ }
+
+ sSavingComplete = FALSE;
+ return sSaveDialogCallback();
+}
+
+void SaveGame(void) // Called from cable_club.s
+{
+ InitSave();
+ CreateTask(SaveGameTask, 0x50);
+}
+
+static void ShowSaveMessage(const u8 *message, u8 (*saveCallback)(void))
+{
+ StringExpandPlaceholders(gStringVar4, message);
+ sub_819786C(0, TRUE);
+ AddTextPrinterForMessage_2(TRUE);
+ sSavingComplete = TRUE;
+ sSaveDialogCallback = saveCallback;
+}
+
+static void SaveGameTask(u8 taskId)
+{
+ u8 status = RunSaveCallback();
+
+ switch (status)
+ {
+ case SAVE_CANCELED:
+ case SAVE_ERROR:
+ gSpecialVar_Result = 0;
+ break;
+ case SAVE_SUCCESS:
+ gSpecialVar_Result = status;
+ break;
+ case SAVE_IN_PROGRESS:
+ return;
+ }
+
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+}
+
+static void sub_80A0014(void)
+{
+ sub_8197434(0, TRUE);
+}
+
+static void HideSaveInfoWindow(void)
+{
+ RemoveSaveInfoWindow();
+}
+
+static void SaveStartTimer(void)
+{
+ sSaveDialogTimer = 60;
+}
+
+static bool8 SaveSuccesTimer(void)
+{
+ sSaveDialogTimer--;
+
+ if (gMain.heldKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ return TRUE;
+ }
+ else if (sSaveDialogTimer == 0)
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static bool8 SaveErrorTimer(void)
+{
+ if (sSaveDialogTimer != 0)
+ {
+ sSaveDialogTimer--;
+ }
+ else if (gMain.heldKeys & A_BUTTON)
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static u8 SaveConfirmSaveCallback(void)
+{
+ sub_819746C(GetStartMenuWindowId(), FALSE);
+ RemoveStartMenuWindow();
+ ShowSaveInfoWindow();
+
+ if (InBattlePyramid())
+ {
+ ShowSaveMessage(gText_BattlePyramidConfirmRest, SaveYesNoCallback);
+ }
+ else
+ {
+ ShowSaveMessage(gText_ConfirmSave, SaveYesNoCallback);
+ }
+
+ return SAVE_IN_PROGRESS;
+}
+
+static u8 SaveYesNoCallback(void)
+{
+ sub_8197930(); // Show Yes/No menu
+ sSaveDialogCallback = SaveConfirmInputCallback;
+ return SAVE_IN_PROGRESS;
+}
+
+static u8 SaveConfirmInputCallback(void)
+{
+ switch (ProcessMenuInputNoWrap_())
+ {
+ case 0: // Yes
+ switch (gSaveFileStatus)
+ {
+ case 0:
+ case 2:
+ if (gDifferentSaveFile == FALSE)
+ {
+ sSaveDialogCallback = SaveFileExistsCallback;
+ return SAVE_IN_PROGRESS;
+ }
+
+ sSaveDialogCallback = SaveSavingMessageCallback;
+ return SAVE_IN_PROGRESS;
+ default:
+ sSaveDialogCallback = SaveFileExistsCallback;
+ return SAVE_IN_PROGRESS;
+ }
+ case -1: // B Button
+ case 1: // No
+ HideSaveInfoWindow();
+ sub_80A0014();
+ return SAVE_CANCELED;
+ }
+
+ return SAVE_IN_PROGRESS;
+}
+
+// A different save file exists
+static u8 SaveFileExistsCallback(void)
+{
+ if (gDifferentSaveFile == TRUE)
+ {
+ ShowSaveMessage(gText_DifferentSaveFile, SaveConfirmOverwriteNoCallback);
+ }
+ else
+ {
+ ShowSaveMessage(gText_AlreadySavedFile, SaveConfirmOverwriteCallback);
+ }
+
+ return SAVE_IN_PROGRESS;
+}
+
+static u8 SaveConfirmOverwriteNoCallback(void)
+{
+ sub_8197948(1); // Show Yes/No menu (No selected as default)
+ sSaveDialogCallback = SaveOverwriteInputCallback;
+ return SAVE_IN_PROGRESS;
+}
+
+static u8 SaveConfirmOverwriteCallback(void)
+{
+ sub_8197930(); // Show Yes/No menu
+ sSaveDialogCallback = SaveOverwriteInputCallback;
+ return SAVE_IN_PROGRESS;
+}
+
+static u8 SaveOverwriteInputCallback(void)
+{
+ switch (ProcessMenuInputNoWrap_())
+ {
+ case 0: // Yes
+ sSaveDialogCallback = SaveSavingMessageCallback;
+ return SAVE_IN_PROGRESS;
+ case -1: // B Button
+ case 1: // No
+ HideSaveInfoWindow();
+ sub_80A0014();
+ return SAVE_CANCELED;
+ }
+
+ return SAVE_IN_PROGRESS;
+}
+
+static u8 SaveSavingMessageCallback(void)
+{
+ ShowSaveMessage(gText_SavingDontTurnOff, SaveDoSaveCallback);
+ return SAVE_IN_PROGRESS;
+}
+
+static u8 SaveDoSaveCallback(void)
+{
+ u8 saveStatus;
+
+ IncrementGameStat(GAME_STAT_SAVED_GAME);
+ sub_81A9E90();
+
+ if (gDifferentSaveFile == TRUE)
+ {
+ saveStatus = TrySavingData(SAVE_OVERWRITE_DIFFERENT_FILE);
+ gDifferentSaveFile = FALSE;
+ }
+ else
+ {
+ saveStatus = TrySavingData(SAVE_NORMAL);
+ }
+
+ if (saveStatus == 1) // Save succeded
+ {
+ ShowSaveMessage(gText_PlayerSavedGame, SaveSuccessCallback);
+ }
+ else // Save error
+ {
+ ShowSaveMessage(gText_SaveError, SaveErrorCallback);
+ }
+
+ SaveStartTimer();
+ return SAVE_IN_PROGRESS;
+}
+
+static u8 SaveSuccessCallback(void)
+{
+ if (!IsTextPrinterActive(0))
+ {
+ PlaySE(SE_SAVE);
+ sSaveDialogCallback = SaveReturnSuccessCallback;
+ }
+
+ return SAVE_IN_PROGRESS;
+}
+
+static u8 SaveReturnSuccessCallback(void)
+{
+ if (!IsSEPlaying() && SaveSuccesTimer())
+ {
+ HideSaveInfoWindow();
+ return SAVE_SUCCESS;
+ }
+ else
+ {
+ return SAVE_IN_PROGRESS;
+ }
+}
+
+static u8 SaveErrorCallback(void)
+{
+ if (!IsTextPrinterActive(0))
+ {
+ PlaySE(SE_BOO);
+ sSaveDialogCallback = SaveReturnErrorCallback;
+ }
+
+ return SAVE_IN_PROGRESS;
+}
+
+static u8 SaveReturnErrorCallback(void)
+{
+ if (!SaveErrorTimer())
+ {
+ return SAVE_IN_PROGRESS;
}
else
{
- *index = _index;
+ HideSaveInfoWindow();
+ return SAVE_ERROR;
+ }
+}
+
+static void InitBattlePyramidRetire(void)
+{
+ sSaveDialogCallback = BattlePyramidConfirmRetireCallback;
+ sSavingComplete = FALSE;
+}
+
+static u8 BattlePyramidConfirmRetireCallback(void)
+{
+ sub_819746C(GetStartMenuWindowId(), FALSE);
+ RemoveStartMenuWindow();
+ ShowSaveMessage(gText_BattlePyramidConfirmRetire, BattlePyramidRetireYesNoCallback);
+
+ return SAVE_IN_PROGRESS;
+}
+
+static u8 BattlePyramidRetireYesNoCallback(void)
+{
+ sub_8197948(1); // Show Yes/No menu (No selected as default)
+ sSaveDialogCallback = BattlePyramidRetireInputCallback;
+
+ return SAVE_IN_PROGRESS;
+}
+
+static u8 BattlePyramidRetireInputCallback(void)
+{
+ switch (ProcessMenuInputNoWrap_())
+ {
+ case 0: // Yes
+ return SAVE_CANCELED;
+ case -1: // B Button
+ case 1: // No
+ sub_80A0014();
+ return SAVE_SUCCESS;
+ }
+
+ return SAVE_IN_PROGRESS;
+}
+
+static void sub_80A03D8(void)
+{
+ TransferPlttBuffer();
+}
+
+static bool32 sub_80A03E4(u8 *par1)
+{
+ switch (*par1)
+ {
+ case 0:
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0);
+ SetVBlankCallback(NULL);
+ ScanlineEffect_Stop();
+ DmaClear16(3, PLTT, PLTT_SIZE);
+ DmaFillLarge16(3, 0, (void *)(VRAM + 0x0), 0x18000, 0x1000);
+ break;
+ case 1:
+ ResetSpriteData();
+ ResetTasks();
+ ResetPaletteFade();
+ ScanlineEffect_Clear();
+ break;
+ case 2:
+ ResetBgsAndClearDma3BusyFlags(0);
+ InitBgsFromTemplates(0, sUnknown_085105A8, ARRAY_COUNT(sUnknown_085105A8));
+ InitWindows(sUnknown_085105AC);
+ box_border_load_tiles_and_pal(0, 8, 224);
+ sub_81978B0(240);
+ break;
+ case 3:
+ ShowBg(0);
+ BlendPalettes(-1, 16, 0);
+ SetVBlankCallback(sub_80A03D8);
+ EnableInterrupts(1);
+ break;
+ case 4:
return TRUE;
}
-}*/
+
+ (*par1)++;
+ return FALSE;
+}
+
+void sub_80A0514(void) // Called from cable_club.s
+{
+ if (sub_80A03E4(&gMain.state))
+ {
+ CreateTask(sub_80A0550, 0x50);
+ SetMainCallback2(sub_80A0540);
+ }
+}
+
+static void sub_80A0540(void)
+{
+ RunTasks();
+ UpdatePaletteFade();
+}
+
+static void sub_80A0550(u8 taskId)
+{
+ s16 *step = gTasks[taskId].data;
+
+ if (!gPaletteFade.active)
+ {
+ switch (*step)
+ {
+ case 0:
+ FillWindowPixelBuffer(0, 17);
+ AddTextPrinterParameterized(0,
+ 1,
+ gText_SavingDontTurnOffPower,
+ 255,
+ NULL,
+ 2,
+ 1,
+ 3);
+ sub_8098858(0, 8, 14);
+ PutWindowTilemap(0);
+ CopyWindowToVram(0, 3);
+ BeginNormalPaletteFade(-1, 0, 16, 0, 0);
+
+ if (gWirelessCommType != 0 && InUnionRoom())
+ {
+ if (sub_800A07C())
+ {
+ *step = 1;
+ }
+ else
+ {
+ *step = 5;
+ }
+ }
+ else
+ {
+ gSoftResetDisabled = 1;
+ *step = 1;
+ }
+ break;
+ case 1:
+ sub_8076D5C();
+ sub_8153430();
+ *step = 2;
+ break;
+ case 2:
+ if (sub_8153474())
+ {
+ sav2_gender2_inplace_and_xFE();
+ *step = 3;
+ gSoftResetDisabled = 0;
+ }
+ break;
+ case 3:
+ BeginNormalPaletteFade(-1, 0, 0, 16, 0);
+ *step = 4;
+ break;
+ case 4:
+ FreeAllWindowBuffers();
+ SetMainCallback2(gMain.savedCallback);
+ DestroyTask(taskId);
+ break;
+ case 5:
+ CreateTask(sub_8153688, 0x5);
+ *step = 6;
+ break;
+ case 6:
+ if (!FuncIsActiveTask(sub_8153688))
+ {
+ *step = 3;
+ }
+ break;
+ }
+ }
+}
+
+static void ShowSaveInfoWindow(void)
+{
+ struct WindowTemplate saveInfoWindow = sSaveInfoWindowTemplate;
+ u8 gender;
+ u8 color;
+ u32 xOffset;
+ u32 yOffset;
+
+ if (!FlagGet(FLAG_SYS_POKEDEX_GET))
+ {
+ saveInfoWindow.height -= 2;
+ }
+
+ sSaveInfoWindowId = AddWindow(&saveInfoWindow);
+ NewMenuHelpers_DrawStdWindowFrame(sSaveInfoWindowId, FALSE);
+
+ gender = gSaveBlock2Ptr->playerGender;
+ color = TEXT_COLOR_RED; // Red when female, blue when male.
+
+ if (gender == MALE)
+ {
+ color = TEXT_COLOR_BLUE;
+ }
+
+ // Print region name
+ yOffset = 1;
+ sub_819A344(3, gStringVar4, TEXT_COLOR_GREEN);
+ PrintTextOnWindow(sSaveInfoWindowId, 1, gStringVar4, 0, yOffset, 0xFF, NULL);
+
+ // Print player name
+ yOffset = 0x11;
+ PrintTextOnWindow(sSaveInfoWindowId, 1, gText_SavingPlayer, 0, yOffset, 0xFF, NULL);
+ sub_819A344(0, gStringVar4, color);
+ xOffset = GetStringRightAlignXOffset(1, gStringVar4, 0x70);
+ PrintPlayerNameOnWindow(sSaveInfoWindowId, gStringVar4, xOffset, yOffset);
+
+ // Print badge count
+ yOffset = 0x21;
+ PrintTextOnWindow(sSaveInfoWindowId, 1, gText_SavingBadges, 0, yOffset, 0xFF, NULL);
+ sub_819A344(4, gStringVar4, color);
+ xOffset = GetStringRightAlignXOffset(1, gStringVar4, 0x70);
+ PrintTextOnWindow(sSaveInfoWindowId, 1, gStringVar4, xOffset, yOffset, 0xFF, NULL);
+
+ if (FlagGet(FLAG_SYS_POKEDEX_GET) == TRUE)
+ {
+ // Print pokedex count
+ yOffset = 0x31;
+ PrintTextOnWindow(sSaveInfoWindowId, 1, gText_SavingPokedex, 0, yOffset, 0xFF, NULL);
+ sub_819A344(1, gStringVar4, color);
+ xOffset = GetStringRightAlignXOffset(1, gStringVar4, 0x70);
+ PrintTextOnWindow(sSaveInfoWindowId, 1, gStringVar4, xOffset, yOffset, 0xFF, NULL);
+ }
+
+ // Print play time
+ yOffset += 0x10;
+ PrintTextOnWindow(sSaveInfoWindowId, 1, gText_SavingTime, 0, yOffset, 0xFF, NULL);
+ sub_819A344(2, gStringVar4, color);
+ xOffset = GetStringRightAlignXOffset(1, gStringVar4, 0x70);
+ PrintTextOnWindow(sSaveInfoWindowId, 1, gStringVar4, xOffset, yOffset, 0xFF, NULL);
+
+ CopyWindowToVram(sSaveInfoWindowId, 2);
+}
+
+static void RemoveSaveInfoWindow(void)
+{
+ sub_819746C(sSaveInfoWindowId, FALSE);
+ RemoveWindow(sSaveInfoWindowId);
+}
+
+static void sub_80A08A4(u8 taskId)
+{
+ if (!FuncIsActiveTask(sub_8153688))
+ {
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+ }
+}
+
+void sub_80A08CC(void) // Referenced in data/specials.inc and data/scripts/maps/BattleFrontier_BattleTowerLobby.inc
+{
+ u8 taskId = CreateTask(sub_8153688, 0x5);
+ gTasks[taskId].data[2] = 1;
+ gTasks[CreateTask(sub_80A08A4, 0x6)].data[1] = taskId;
+}
+
+static void HideStartMenuWindow(void)
+{
+ sub_819746C(GetStartMenuWindowId(), TRUE);
+ RemoveStartMenuWindow();
+ sub_80984F4();
+ ScriptContext2_Disable();
+}
+
+void HideStartMenu(void) // Called from map_name_popup.s
+{
+ PlaySE(SE_SELECT);
+ HideStartMenuWindow();
+}
+
+void AppendToList(u8 *list, u8 *pos, u8 newEntry)
+{
+ list[*pos] = newEntry;
+ (*pos)++;
+} \ No newline at end of file
diff --git a/src/starter_choose.c b/src/starter_choose.c
index 83a7b8112..480edbcb7 100644
--- a/src/starter_choose.c
+++ b/src/starter_choose.c
@@ -25,12 +25,6 @@
#define STARTER_PKMN_POS_X 120
#define STARTER_PKMN_POS_Y 64
-// graphics
-extern const u32 gBirchHelpGfx[];
-extern const u32 gBirchBagTilemap[];
-extern const u32 gBirchGrassTilemap[];
-extern const u16 gBirchBagGrassPal[];
-
// text
extern const u8 gText_BirchInTrouble[];
extern const u8 gText_ConfirmStarterChoice[];
diff --git a/src/text.c b/src/text.c
index 6a83d5d15..f7c68f549 100644
--- a/src/text.c
+++ b/src/text.c
@@ -4,18 +4,15 @@
#include "m4a.h"
#include "palette.h"
#include "sound.h"
+#include "constants/songs.h"
#include "string_util.h"
#include "window.h"
#include "text.h"
+#include "blit.h"
-extern void FillBitmapRect4Bit(struct Bitmap *surface, u16 x, u16 y, u16 width, u16 height, u8 fillValue);
-extern void FillWindowPixelRect(u8 windowId, u8 fillValue, u16 x, u16 y, u16 width, u16 height);
-extern void BlitBitmapRectToWindow(u8 windowId, const u8 *pixels, u16 srcX, u16 srcY, u16 srcWidth, int srcHeight, u16 destX, u16 destY, u16 rectWidth, u16 rectHeight);
extern u8 GetKeypadIconWidth(u8 keypadIconId);
-extern void CopyWindowToVram(u8 windowId, u8 mode);
extern u16 Font6Func(struct TextPrinter *textPrinter);
extern u32 GetGlyphWidthFont6(u16 glyphId, bool32 isJapanese);
-extern void PlaySE(u16 songNum);
extern u8* UnkTextUtil_GetPtrI(u8 a1);
extern int sub_8197964();
@@ -27,7 +24,6 @@ static u16 gLastTextBgColor;
static u16 gLastTextFgColor;
static u16 gLastTextShadowColor;
-extern struct Main gMain;
extern struct MusicPlayerInfo gMPlayInfo_BGM;
const struct FontInfo *gFonts;
@@ -379,7 +375,7 @@ void GenerateFontHalfRowLookupTable(u8 fgColor, u8 bgColor, u8 shadowColor)
*(current++) = (shadowColor << 12) | (shadowColor << 8) | (shadowColor << 4) | shadowColor;
}
#else
-__attribute__((naked))
+NAKED
void GenerateFontHalfRowLookupTable(u8 fgColor, u8 bgColor, u8 shadowColor)
{
asm("push {r4-r7,lr}\n\
@@ -875,7 +871,7 @@ void DecompressGlyphTile(const u16 *src, u16 *dest)
*(dest) = (gFontHalfRowLookupTable[gFontHalfRowOffsets[src[1] & 0xFF]] << 16) | gFontHalfRowLookupTable[gFontHalfRowOffsets[src[1] >> 8]];
}
#else
-__attribute__((naked))
+NAKED
void DecompressGlyphTile(const u16 *src, u16 *dest)
{
asm("push {r4-r7,lr}\n\
@@ -1056,7 +1052,7 @@ u8 GetLastTextColor(u8 colorType)
}
}
-__attribute__((naked))
+NAKED
void CopyGlyphToWindow(struct TextPrinter *x)
{
asm("push {r4-r7,lr}\n\
@@ -1986,7 +1982,7 @@ bool16 TextPrinterWaitWithDownArrow(struct TextPrinter *textPrinter)
if (gMain.newKeys & (A_BUTTON | B_BUTTON))
{
result = TRUE;
- PlaySE(5);
+ PlaySE(SE_SELECT);
}
}
return result;
@@ -2004,7 +2000,7 @@ bool16 TextPrinterWait(struct TextPrinter *textPrinter)
if (gMain.newKeys & (A_BUTTON | B_BUTTON))
{
result = TRUE;
- PlaySE(5);
+ PlaySE(SE_SELECT);
}
}
return result;
@@ -2285,7 +2281,6 @@ u16 RenderText(struct TextPrinter *textPrinter)
else
textPrinter->subPrinter.currentX += gUnknown_03002F90[0x80];
}
-
return 0;
case 1: // _08005C78
if (TextPrinterWait(textPrinter))
@@ -2346,7 +2341,7 @@ u16 RenderText(struct TextPrinter *textPrinter)
return 1;
}
#else
-__attribute__((naked))
+NAKED
u16 RenderText(struct TextPrinter *textPrinter)
{
asm("push {r4-r6,lr}\n\
diff --git a/src/text_window.c b/src/text_window.c
index 33cd7cffe..c3b9f7197 100644
--- a/src/text_window.c
+++ b/src/text_window.c
@@ -7,26 +7,26 @@
#include "graphics.h"
// const rom data
-const u32 gTextWindowFrame1_Gfx[] = INCBIN_U32("graphics/text_window/1.4bpp");
-static const u32 sTextWindowFrame2_Gfx[] = INCBIN_U32("graphics/text_window/2.4bpp");
-static const u32 sTextWindowFrame3_Gfx[] = INCBIN_U32("graphics/text_window/3.4bpp");
-static const u32 sTextWindowFrame4_Gfx[] = INCBIN_U32("graphics/text_window/4.4bpp");
-static const u32 sTextWindowFrame5_Gfx[] = INCBIN_U32("graphics/text_window/5.4bpp");
-static const u32 sTextWindowFrame6_Gfx[] = INCBIN_U32("graphics/text_window/6.4bpp");
-static const u32 sTextWindowFrame7_Gfx[] = INCBIN_U32("graphics/text_window/7.4bpp");
-static const u32 sTextWindowFrame8_Gfx[] = INCBIN_U32("graphics/text_window/8.4bpp");
-static const u32 sTextWindowFrame9_Gfx[] = INCBIN_U32("graphics/text_window/9.4bpp");
-static const u32 sTextWindowFrame10_Gfx[] = INCBIN_U32("graphics/text_window/10.4bpp");
-static const u32 sTextWindowFrame11_Gfx[] = INCBIN_U32("graphics/text_window/11.4bpp");
-static const u32 sTextWindowFrame12_Gfx[] = INCBIN_U32("graphics/text_window/12.4bpp");
-static const u32 sTextWindowFrame13_Gfx[] = INCBIN_U32("graphics/text_window/13.4bpp");
-static const u32 sTextWindowFrame14_Gfx[] = INCBIN_U32("graphics/text_window/14.4bpp");
-static const u32 sTextWindowFrame15_Gfx[] = INCBIN_U32("graphics/text_window/15.4bpp");
-static const u32 sTextWindowFrame16_Gfx[] = INCBIN_U32("graphics/text_window/16.4bpp");
-static const u32 sTextWindowFrame17_Gfx[] = INCBIN_U32("graphics/text_window/17.4bpp");
-static const u32 sTextWindowFrame18_Gfx[] = INCBIN_U32("graphics/text_window/18.4bpp");
-static const u32 sTextWindowFrame19_Gfx[] = INCBIN_U32("graphics/text_window/19.4bpp");
-static const u32 sTextWindowFrame20_Gfx[] = INCBIN_U32("graphics/text_window/20.4bpp");
+const u8 gTextWindowFrame1_Gfx[] = INCBIN_U8("graphics/text_window/1.4bpp");
+static const u8 sTextWindowFrame2_Gfx[] = INCBIN_U8("graphics/text_window/2.4bpp");
+static const u8 sTextWindowFrame3_Gfx[] = INCBIN_U8("graphics/text_window/3.4bpp");
+static const u8 sTextWindowFrame4_Gfx[] = INCBIN_U8("graphics/text_window/4.4bpp");
+static const u8 sTextWindowFrame5_Gfx[] = INCBIN_U8("graphics/text_window/5.4bpp");
+static const u8 sTextWindowFrame6_Gfx[] = INCBIN_U8("graphics/text_window/6.4bpp");
+static const u8 sTextWindowFrame7_Gfx[] = INCBIN_U8("graphics/text_window/7.4bpp");
+static const u8 sTextWindowFrame8_Gfx[] = INCBIN_U8("graphics/text_window/8.4bpp");
+static const u8 sTextWindowFrame9_Gfx[] = INCBIN_U8("graphics/text_window/9.4bpp");
+static const u8 sTextWindowFrame10_Gfx[] = INCBIN_U8("graphics/text_window/10.4bpp");
+static const u8 sTextWindowFrame11_Gfx[] = INCBIN_U8("graphics/text_window/11.4bpp");
+static const u8 sTextWindowFrame12_Gfx[] = INCBIN_U8("graphics/text_window/12.4bpp");
+static const u8 sTextWindowFrame13_Gfx[] = INCBIN_U8("graphics/text_window/13.4bpp");
+static const u8 sTextWindowFrame14_Gfx[] = INCBIN_U8("graphics/text_window/14.4bpp");
+static const u8 sTextWindowFrame15_Gfx[] = INCBIN_U8("graphics/text_window/15.4bpp");
+static const u8 sTextWindowFrame16_Gfx[] = INCBIN_U8("graphics/text_window/16.4bpp");
+static const u8 sTextWindowFrame17_Gfx[] = INCBIN_U8("graphics/text_window/17.4bpp");
+static const u8 sTextWindowFrame18_Gfx[] = INCBIN_U8("graphics/text_window/18.4bpp");
+static const u8 sTextWindowFrame19_Gfx[] = INCBIN_U8("graphics/text_window/19.4bpp");
+static const u8 sTextWindowFrame20_Gfx[] = INCBIN_U8("graphics/text_window/20.4bpp");
const u16 gTextWindowFrame1_Pal[] = INCBIN_U16("graphics/text_window/1.gbapal");
static const u16 sTextWindowFrame2_Pal[] = INCBIN_U16("graphics/text_window/2.gbapal");
diff --git a/src/time_events.c b/src/time_events.c
index 1f169a5c6..1f46e7705 100644
--- a/src/time_events.c
+++ b/src/time_events.c
@@ -81,7 +81,7 @@ void UpdateShoalTideFlag(void)
1, // 23
};
- if (is_light_level_1_2_3_5_or_6(get_map_light_from_warp0()))
+ if (is_map_type_1_2_3_5_or_6(get_map_light_from_warp0()))
{
RtcCalcLocalTime();
if (tide[gLocalTime.hours])
diff --git a/src/title_screen.c b/src/title_screen.c
index 4e25c8152..15a0482dc 100644
--- a/src/title_screen.c
+++ b/src/title_screen.c
@@ -19,6 +19,7 @@
#include "gpu_regs.h"
#include "trig.h"
#include "constants/rgb.h"
+#include "constants/songs.h"
#define VERSION_BANNER_SHAPE 1
#define VERSION_BANNER_RIGHT_TILEOFFSET 64
@@ -574,7 +575,7 @@ void CB2_InitTitleScreen(void)
| DISPCNT_OBJ_ON
| DISPCNT_WIN0_ON
| DISPCNT_OBJWIN_ON);
- m4aSongNumStart(0x19D);
+ m4aSongNumStart(MUS_TITLE3);
gMain.state = 5;
break;
case 5:
diff --git a/src/trader.c b/src/trader.c
new file mode 100644
index 000000000..c4d70ac9a
--- /dev/null
+++ b/src/trader.c
@@ -0,0 +1,209 @@
+#include "global.h"
+#include "constants/decorations.h"
+#include "constants/mauville_man.h"
+#include "decoration.h"
+#include "decoration_inventory.h"
+#include "event_data.h"
+#include "main.h"
+#include "menu.h"
+#include "menu_helpers.h"
+#include "script.h"
+#include "constants/songs.h"
+#include "sound.h"
+#include "string_util.h"
+#include "strings.h"
+#include "task.h"
+#include "script_menu.h"
+
+static const u8 * const sDefaultTraderNames[] =
+{
+ gText_Tristan,
+ gText_Philip,
+ gText_Dennis,
+ gText_Roberto,
+};
+
+static const u8 sDefaultTraderDecorations[] =
+{
+ DECOR_DUSKULL_DOLL,
+ DECOR_BALL_CUSHION,
+ DECOR_TIRE,
+ DECOR_PRETTY_FLOWERS,
+};
+
+void TraderSetup(void)
+{
+ u8 i;
+ struct MauvilleOldManTrader *trader = &gSaveBlock1Ptr->oldMan.trader;
+
+ trader->id = MAUVILLE_MAN_TRADER;
+ trader->alreadyTraded = FALSE;
+
+ for (i = 0; i < 4; i++)
+ {
+ StringCopy(trader->playerNames[i], sDefaultTraderNames[i]);
+ trader->decorIds[i] = sDefaultTraderDecorations[i];
+ trader->language[i] = GAME_LANGUAGE;
+ }
+}
+
+void Trader_ResetFlag(void)
+{
+ struct MauvilleOldManTrader *trader = &gSaveBlock1Ptr->oldMan.trader;
+ trader->alreadyTraded = FALSE;
+}
+
+void CreateAvailableDecorationsMenu(u8 taskId)
+{
+ u8 i;
+ s16 * data = gTasks[taskId].data;
+ struct MauvilleOldManTrader *trader = &gSaveBlock1Ptr->oldMan.trader;
+ struct WindowTemplate windowTemplate = {0, 1, 1, 10, 10, 15, 1};
+ s32 windowWidth = GetStringWidth(1, gText_Exit, 0);
+ s32 fiveMarksWidth = GetStringWidth(1, gText_FiveMarks, 0);
+ for (i = 0; i < 4; i++)
+ {
+ s32 curWidth;
+ if (trader->decorIds[i] > NUM_DECORATIONS)
+ curWidth = fiveMarksWidth;
+ else
+ curWidth = GetStringWidth(1, gDecorations[trader->decorIds[i]].name, 0);
+ if (curWidth > windowWidth)
+ windowWidth = curWidth;
+ }
+ windowTemplate.width = convert_pixel_width_to_tile_width(windowWidth);
+ data[3] = AddWindow(&windowTemplate);
+ SetWindowBorderStyle(data[3], FALSE, 0x214, 14);
+ for (i = 0; i < 4; i++)
+ {
+ if (trader->decorIds[i] > NUM_DECORATIONS)
+ PrintTextOnWindow(data[3], 1, gText_FiveMarks, 8, 16 * i + 1, 255, NULL);
+ else
+ PrintTextOnWindow(data[3], 1, gDecorations[trader->decorIds[i]].name, 8, 16 * i + 1, 255, NULL);
+ }
+ PrintTextOnWindow(data[3], 1, gText_Exit, 8, 16 * i + 1, 255, NULL);
+ InitMenuInUpperLeftCornerPlaySoundWhenAPressed(data[3], 5, 0);
+ schedule_bg_copy_tilemap_to_vram(0);
+}
+
+void sub_8133BE4(u8 taskId, u8 decorationId)
+{
+ s16 * data = gTasks[taskId].data;
+ if (decorationId > NUM_DECORATIONS)
+ {
+ gSpecialVar_0x8004 = 0xFFFF;
+ }
+ else
+ {
+ gSpecialVar_0x8004 = decorationId;
+ }
+
+ sub_8198070(data[3], FALSE);
+ ClearWindowTilemap(data[3]);
+ RemoveWindow(data[3]);
+ schedule_bg_copy_tilemap_to_vram(0);
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+}
+
+void Task_HandleGetDecorationMenuInput(u8 taskId)
+{
+ struct MauvilleOldManTrader *trader = &gSaveBlock1Ptr->oldMan.trader;
+ s8 input = ProcessMenuInput();
+
+ switch (input)
+ {
+ case -2:
+ break;
+ case -1:
+ case 4:
+ PlaySE(SE_SELECT);
+ sub_8133BE4(taskId, 0);
+ break;
+ default:
+ PlaySE(SE_SELECT);
+ gSpecialVar_0x8005 = input;
+ StringCopy(gStringVar1, trader->playerNames[input]);
+ ConvertInternationalString(gStringVar1, trader->language[input]);
+ sub_8133BE4(taskId, trader->decorIds[input]);
+ break;
+ }
+}
+
+void ScrSpecial_GetTraderTradedFlag(void)
+{
+ struct MauvilleOldManTrader *trader = &gSaveBlock1Ptr->oldMan.trader;
+ gSpecialVar_Result = trader->alreadyTraded;
+}
+
+void ScrSpecial_DoesPlayerHaveNoDecorations(void)
+{
+ u8 i;
+
+ for (i = 0; i < 8; i++)
+ {
+ if (CountDecorationCategoryN(i))
+ {
+ gSpecialVar_Result = FALSE;
+ return;
+ }
+ }
+ gSpecialVar_Result = TRUE;
+}
+
+void ScrSpecial_IsDecorationFull(void)
+{
+ gSpecialVar_Result = FALSE;
+ if (gDecorations[gSpecialVar_0x8004].category != gDecorations[gSpecialVar_0x8006].category
+ && GetFirstEmptyDecorSlot(gDecorations[gSpecialVar_0x8004].category) == -1)
+ {
+ sub_8127250(gStringVar2, gDecorations[gSpecialVar_0x8004].category);
+ gSpecialVar_Result = TRUE;
+ }
+}
+
+void ScrSpecial_TraderMenuGiveDecoration(void)
+{
+ CreateTask(sub_8127208, 0);
+}
+
+void sub_8133DA0(u8 taskId)
+{
+ if (IsSelectedDecorInThePC() == TRUE)
+ {
+ gSpecialVar_0x8006 = gCurDecorInventoryItems[gCurDecorationIndex];
+ StringCopy(gStringVar3, gDecorations[gSpecialVar_0x8004].name);
+ StringCopy(gStringVar2, gDecorations[gSpecialVar_0x8006].name);
+ }
+ else
+ {
+ gSpecialVar_0x8006 = 0xFFFF;
+ }
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+}
+
+void sub_8133E1C(u8 taskId)
+{
+ gSpecialVar_0x8006 = 0;
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+}
+
+void ScrSpecial_TraderDoDecorationTrade(void)
+{
+ struct MauvilleOldManTrader *trader = &gSaveBlock1Ptr->oldMan.trader;
+
+ DecorationRemove(gSpecialVar_0x8006);
+ DecorationAdd(gSpecialVar_0x8004);
+ StringCopy(trader->playerNames[gSpecialVar_0x8005], gSaveBlock2Ptr->playerName);
+ trader->decorIds[gSpecialVar_0x8005] = gSpecialVar_0x8006;
+ trader->language[gSpecialVar_0x8005] = GAME_LANGUAGE;
+ trader->alreadyTraded = TRUE;
+}
+
+void ScrSpecial_TraderMenuGetDecoration(void)
+{
+ u8 taskId = CreateTask(Task_HandleGetDecorationMenuInput, 0);
+ CreateAvailableDecorationsMenu(taskId);
+}
diff --git a/src/tv.c b/src/tv.c
index ddcff9f1d..a48a2d638 100644
--- a/src/tv.c
+++ b/src/tv.c
@@ -36,9 +36,7 @@
#include "decoration.h"
#include "secret_base.h"
#include "tv.h"
-
-extern const u8 gSpeciesNames[][11];
-extern const u8 gMoveNames[][13];
+#include "data2.h"
// Static type declarations
@@ -87,101 +85,100 @@ void tv_store_id_3x(TVShow *show);
void DeleteTVShowInArrayByIdx(TVShow *shows, u8 idx);
s8 FindEmptyTVSlotWithinFirstFiveShowsOfArray(TVShow *shows);
void FindActiveBroadcastByShowType_SetScriptResult(u8 kind);
-void InterviewBefore_BravoTrainerPkmnProfile(void);
-void InterviewBefore_NameRater(void);
+static void InterviewBefore_BravoTrainerPkmnProfile(void);
+static void InterviewBefore_NameRater(void);
u16 TV_GetSomeOtherSpeciesAlreadySeenByPlayer(u16 passedSpecies);
-void sub_80EFA88(void);
-void sub_80EF93C(TVShow *shows);
+static void sub_80EFA88(void);
+static void sub_80EF93C(TVShow *shows);
s8 sub_80EEE30(PokeNews *pokeNews);
bool8 sub_80EF0E4(u8 newsKind);
void ClearPokemonNewsI(u8 i);
-void sub_80F1254(TVShow *shows);
-void sub_80F12A4(TVShow *shows);
-void sub_80F0358(TVShow *player1, TVShow *player2, TVShow *player3, TVShow *player4);
-void sub_80F0C04(void);
-void sub_80F0708(void);
-void sub_80F0B64(void);
-s8 sub_80F06D0(TVShow *tvShows);
-bool8 sub_80F049C(TVShow *dest[], TVShow *src[], u8 idx);
-bool8 sub_80F0580(TVShow *tv1, TVShow *tv2, u8 idx);
-bool8 sub_80F05E8(TVShow *tv1, TVShow *tv2, u8 idx);
-bool8 sub_80F0668(TVShow *tv1, TVShow *tv2, u8 idx);
-void sub_80F0B00(u8 showIdx);
-void sub_80F0B24(u16 species, u8 showIdx);
-void sub_80F0D60(PokeNews *player1, PokeNews *player2, PokeNews *player3, PokeNews *player4);
-void sub_80F0EEC(void);
-void sub_80F0F24(void);
-s8 sub_80F0ECC(PokeNews *pokeNews, u8 idx);
-void sub_80F0E58(PokeNews *dest[], PokeNews *src[]);
-bool8 sub_80F0E84(PokeNews *dest, PokeNews *src, s8 slot);
+static void sub_80F1254(TVShow *shows);
+static void sub_80F12A4(TVShow *shows);
+static void sub_80F0358(TVShow *player1, TVShow *player2, TVShow *player3, TVShow *player4);
+static void sub_80F0C04(void);
+static void sub_80F0708(void);
+static void sub_80F0B64(void);
+static s8 sub_80F06D0(TVShow *tvShows);
+static bool8 sub_80F049C(TVShow *dest[], TVShow *src[], u8 idx);
+static bool8 sub_80F0580(TVShow *tv1, TVShow *tv2, u8 idx);
+static bool8 sub_80F05E8(TVShow *tv1, TVShow *tv2, u8 idx);
+static bool8 sub_80F0668(TVShow *tv1, TVShow *tv2, u8 idx);
+void SetTvShowInactive(u8 showIdx);
+static void sub_80F0B24(u16 species, u8 showIdx);
+static void sub_80F0D60(PokeNews *player1, PokeNews *player2, PokeNews *player3, PokeNews *player4);
+static void sub_80F0EEC(void);
+static void sub_80F0F24(void);
+static s8 sub_80F0ECC(PokeNews *pokeNews, u8 idx);
+static void sub_80F0E58(PokeNews *dest[], PokeNews *src[]);
+static bool8 sub_80F0E84(PokeNews *dest, PokeNews *src, s8 slot);
void TVShowDone(void);
-void InterviewAfter_FanClubLetter(void);
-void InterviewAfter_RecentHappenings(void);
-void InterviewAfter_PkmnFanClubOpinions(void);
-void InterviewAfter_DummyShow4(void);
-void InterviewAfter_BravoTrainerPokemonProfile(void);
-void InterviewAfter_BravoTrainerBattleTowerProfile(void);
-void InterviewAfter_ContestLiveUpdates(void);
+static void InterviewAfter_FanClubLetter(void);
+static void InterviewAfter_RecentHappenings(void);
+static void InterviewAfter_PkmnFanClubOpinions(void);
+static void InterviewAfter_DummyShow4(void);
+static void InterviewAfter_BravoTrainerPokemonProfile(void);
+static void InterviewAfter_BravoTrainerBattleTowerProfile(void);
+static void InterviewAfter_ContestLiveUpdates(void);
void UpdateWorldOfMastersAndPutItOnTheAir(void);
void PutPokemonTodayFailedOnTheAir(void);
-void sub_80ED718(void);
-void sub_80EED88(void);
+static void sub_80ED718(void);
+static void sub_80EED88(void);
void TV_SortPurchasesByQuantity(void);
-void sub_80ED8B4(u16 days);
+static void sub_80ED8B4(u16 days);
void UpdateMassOutbreakTimeLeft(u16 days);
-void sub_80EF120(u16 days);
-void sub_80EDA48(u16 days);
-void sub_80EEB98(u16 days);
+static void sub_80EF120(u16 days);
+static void sub_80EDA48(u16 days);
+static void sub_80EEB98(u16 days);
void PutFishingAdviceShowOnTheAir(void);
-void sub_80EDA80(void);
u8 TV_MonDataIdxToRibbon(u8 monDataIdx);
-void sub_80EEBF4(u8 actionIdx);
+static void sub_80EEBF4(u8 actionIdx);
bool8 IsPriceDiscounted(u8 newsKind);
-void InterviewBefore_FanClubLetter(void);
-void InterviewBefore_RecentHappenings(void);
-void InterviewBefore_PkmnFanClubOpinions(void);
-void InterviewBefore_Dummy(void);
-void InterviewBefore_BravoTrainerBTProfile(void);
-void InterviewBefore_ContestLiveUpdates(void);
-void InterviewBefore_3CheersForPokeblocks(void);
-void InterviewBefore_FanClubSpecial(void);
+static void InterviewBefore_FanClubLetter(void);
+static void InterviewBefore_RecentHappenings(void);
+static void InterviewBefore_PkmnFanClubOpinions(void);
+static void InterviewBefore_Dummy(void);
+static void InterviewBefore_BravoTrainerBTProfile(void);
+static void InterviewBefore_ContestLiveUpdates(void);
+static void InterviewBefore_3CheersForPokeblocks(void);
+static void InterviewBefore_FanClubSpecial(void);
void ChangeBoxPokemonNickname_CB(void);
-void DoTVShowPokemonFanClubLetter(void);
-void DoTVShowRecentHappenings(void);
-void DoTVShowPokemonFanClubOpinions(void);
-void DoTVShowDummiedOut(void);
-void DoTVShowPokemonNewsMassOutbreak(void);
-void DoTVShowBravoTrainerPokemonProfile(void);
-void DoTVShowBravoTrainerBattleTower(void);
-void DoTVShowPokemonTodaySuccessfulCapture(void);
-void DoTVShowTodaysSmartShopper(void);
-void DoTVShowTheNameRaterShow(void);
-void DoTVShowPokemonContestLiveUpdates(void);
-void DoTVShowPokemonBattleUpdate(void);
-void DoTVShow3CheersForPokeblocks(void);
-void DoTVShowPokemonTodayFailedCapture(void);
-void DoTVShowPokemonAngler(void);
-void DoTVShowTheWorldOfMasters(void);
-void DoTVShowTodaysRivalTrainer(void);
-void DoTVShowDewfordTrendWatcherNetwork(void);
-void DoTVShowHoennTreasureInvestigators(void);
-void DoTVShowFindThatGamer(void);
-void DoTVShowBreakingNewsTV(void);
-void DoTVShowSecretBaseVisit(void);
-void DoTVShowPokemonLotteryWinnerFlashReport(void);
-void DoTVShowThePokemonBattleSeminar(void);
-void DoTVShowTrainerFanClubSpecial(void);
-void DoTVShowTrainerFanClub(void);
-void DoTVShowSpotTheCuties(void);
-void DoTVShowPokemonNewsBattleFrontier(void);
-void DoTVShowWhatsNo1InHoennToday(void);
-void DoTVShowSecretBaseSecrets(void);
-void DoTVShowSafariFanClub(void);
-void DoTVShowPokemonContestLiveUpdates2(void);
+static void DoTVShowPokemonFanClubLetter(void);
+static void DoTVShowRecentHappenings(void);
+static void DoTVShowPokemonFanClubOpinions(void);
+static void DoTVShowDummiedOut(void);
+static void DoTVShowPokemonNewsMassOutbreak(void);
+static void DoTVShowBravoTrainerPokemonProfile(void);
+static void DoTVShowBravoTrainerBattleTower(void);
+static void DoTVShowPokemonTodaySuccessfulCapture(void);
+static void DoTVShowTodaysSmartShopper(void);
+static void DoTVShowTheNameRaterShow(void);
+static void DoTVShowPokemonContestLiveUpdates(void);
+static void DoTVShowPokemonBattleUpdate(void);
+static void DoTVShow3CheersForPokeblocks(void);
+static void DoTVShowPokemonTodayFailedCapture(void);
+static void DoTVShowPokemonAngler(void);
+static void DoTVShowTheWorldOfMasters(void);
+static void DoTVShowTodaysRivalTrainer(void);
+static void DoTVShowDewfordTrendWatcherNetwork(void);
+static void DoTVShowHoennTreasureInvestigators(void);
+static void DoTVShowFindThatGamer(void);
+static void DoTVShowBreakingNewsTV(void);
+static void DoTVShowSecretBaseVisit(void);
+static void DoTVShowPokemonLotteryWinnerFlashReport(void);
+static void DoTVShowThePokemonBattleSeminar(void);
+static void DoTVShowTrainerFanClubSpecial(void);
+static void DoTVShowTrainerFanClub(void);
+static void DoTVShowSpotTheCuties(void);
+static void DoTVShowPokemonNewsBattleFrontier(void);
+static void DoTVShowWhatsNo1InHoennToday(void);
+static void DoTVShowSecretBaseSecrets(void);
+static void DoTVShowSafariFanClub(void);
+static void DoTVShowPokemonContestLiveUpdates2(void);
// .rodata
-const struct {
+static const struct {
u16 species;
u16 moves[4];
u8 level;
@@ -214,8 +211,7 @@ const struct {
}
};
-// TODO: Figure out what these are, and define constants in include/flags.h
-const u16 sGoldSymbolFlags[] = {
+static const u16 sGoldSymbolFlags[] = {
FLAG_SYS_TOWER_GOLD,
FLAG_SYS_DOME_GOLD,
FLAG_SYS_PALACE_GOLD,
@@ -225,7 +221,7 @@ const u16 sGoldSymbolFlags[] = {
FLAG_SYS_PYRAMID_GOLD
};
-const u16 sSilverSymbolFlags[] = {
+static const u16 sSilverSymbolFlags[] = {
FLAG_SYS_TOWER_SILVER,
FLAG_SYS_DOME_SILVER,
FLAG_SYS_PALACE_SILVER,
@@ -235,8 +231,7 @@ const u16 sSilverSymbolFlags[] = {
FLAG_SYS_PYRAMID_SILVER
};
-// TODO: Figure out what these are, and define constants in include/vars.h
-const u16 sNumberOneVarsAndThresholds[][2] = {
+static const u16 sNumberOneVarsAndThresholds[][2] = {
{VAR_DAILY_SLOTS, 100},
{VAR_DAILY_ROULETTE, 50},
{VAR_DAILY_WILDS, 100},
@@ -246,7 +241,7 @@ const u16 sNumberOneVarsAndThresholds[][2] = {
{VAR_DAILY_BP, 30}
};
-const u8 *const sPokeNewsTextGroup_Upcoming[] = {
+static const u8 *const sPokeNewsTextGroup_Upcoming[] = {
NULL,
gPokeNewsTextSlateport_Upcoming,
gPokeNewsTextGameCorner_Upcoming,
@@ -254,7 +249,7 @@ const u8 *const sPokeNewsTextGroup_Upcoming[] = {
gPokeNewsTextBlendMaster_Upcoming
};
-const u8 *const sPokeNewsTextGroup_Ongoing[] = {
+static const u8 *const sPokeNewsTextGroup_Ongoing[] = {
NULL,
gPokeNewsTextSlateport_Ongoing,
gPokeNewsTextGameCorner_Ongoing,
@@ -262,7 +257,7 @@ const u8 *const sPokeNewsTextGroup_Ongoing[] = {
gPokeNewsTextBlendMaster_Ongoing
};
-const u8 *const sPokeNewsTextGroup_Ending[] = {
+static const u8 *const sPokeNewsTextGroup_Ending[] = {
NULL,
gPokeNewsTextSlateport_Ending,
gPokeNewsTextGameCorner_Ending,
@@ -276,7 +271,7 @@ u8 *const gTVStringVarPtrs[] = {
gStringVar3
};
-const u8 *const sTVFanClubTextGroup[] = {
+static const u8 *const sTVFanClubTextGroup[] = {
gTVFanClubText00,
gTVFanClubText01,
gTVFanClubText02,
@@ -287,7 +282,7 @@ const u8 *const sTVFanClubTextGroup[] = {
gTVFanClubText07
};
-const u8 *const sTVRecentHappeninssTextGroup[] = {
+static const u8 *const sTVRecentHappeninssTextGroup[] = {
gTVRecentHappeningsText00,
gTVRecentHappeningsText01,
gTVRecentHappeningsText02,
@@ -296,7 +291,7 @@ const u8 *const sTVRecentHappeninssTextGroup[] = {
gTVRecentHappeningsText05
};
-const u8 *const sTVFanClubOpinionsTextGroup[] = {
+static const u8 *const sTVFanClubOpinionsTextGroup[] = {
gTVFanClubOpinionsText00,
gTVFanClubOpinionsText01,
gTVFanClubOpinionsText02,
@@ -304,11 +299,11 @@ const u8 *const sTVFanClubOpinionsTextGroup[] = {
gTVFanClubOpinionsText04
};
-const u8 *const sTVMassOutbreakTextGroup[] = {
+static const u8 *const sTVMassOutbreakTextGroup[] = {
gTVMassOutbreakText00
};
-const u8 *const sTVPokemonTodaySuccessfulTextGroup[] = {
+static const u8 *const sTVPokemonTodaySuccessfulTextGroup[] = {
gTVPokemonTodaySuccessfulText00,
gTVPokemonTodaySuccessfulText01,
gTVPokemonTodaySuccessfulText02,
@@ -323,7 +318,7 @@ const u8 *const sTVPokemonTodaySuccessfulTextGroup[] = {
gTVPokemonTodaySuccessfulText11
};
-const u8 *const sTVTodaysSmartShopperTextGroup[] = {
+static const u8 *const sTVTodaysSmartShopperTextGroup[] = {
gTVTodaysSmartShopperText00,
gTVTodaysSmartShopperText01,
gTVTodaysSmartShopperText02,
@@ -339,7 +334,7 @@ const u8 *const sTVTodaysSmartShopperTextGroup[] = {
gTVTodaysSmartShopperText12
};
-const u8 *const sTVBravoTrainerTextGroup[] = {
+static const u8 *const sTVBravoTrainerTextGroup[] = {
gTVBravoTrainerText00,
gTVBravoTrainerText01,
gTVBravoTrainerText02,
@@ -351,7 +346,7 @@ const u8 *const sTVBravoTrainerTextGroup[] = {
gTVBravoTrainerText08
};
-const u8 *const sTV3CheersForPokeblocksTextGroup[] = {
+static const u8 *const sTV3CheersForPokeblocksTextGroup[] = {
gTV3CheersForPokeblocksText00,
gTV3CheersForPokeblocksText01,
gTV3CheersForPokeblocksText02,
@@ -360,7 +355,7 @@ const u8 *const sTV3CheersForPokeblocksTextGroup[] = {
gTV3CheersForPokeblocksText05
};
-const u8 *const sTVBravoTrainerBattleTowerTextGroup[] = {
+static const u8 *const sTVBravoTrainerBattleTowerTextGroup[] = {
gTVBravoTrainerBattleTowerText00,
gTVBravoTrainerBattleTowerText01,
gTVBravoTrainerBattleTowerText02,
@@ -378,7 +373,7 @@ const u8 *const sTVBravoTrainerBattleTowerTextGroup[] = {
gTVBravoTrainerBattleTowerText14
};
-const u8 *const sTVContestLiveUpdatesTextGroup[] = {
+static const u8 *const sTVContestLiveUpdatesTextGroup[] = {
gTVContestLiveUpdatesText00,
gTVContestLiveUpdatesText01,
gTVContestLiveUpdatesText02,
@@ -414,7 +409,7 @@ const u8 *const sTVContestLiveUpdatesTextGroup[] = {
gTVContestLiveUpdatesText32
};
-const u8 *const sTVPokemonBattleUpdateTextGroup[] = {
+static const u8 *const sTVPokemonBattleUpdateTextGroup[] = {
gTVPokemonBattleUpdateText00,
gTVPokemonBattleUpdateText01,
gTVPokemonBattleUpdateText02,
@@ -425,7 +420,7 @@ const u8 *const sTVPokemonBattleUpdateTextGroup[] = {
gTVPokemonBattleUpdateText07
};
-const u8 *const sTVTrainerFanClubSpecialTextGroup[] = {
+static const u8 *const sTVTrainerFanClubSpecialTextGroup[] = {
gTVTrainerFanClubSpecialText00,
gTVTrainerFanClubSpecialText01,
gTVTrainerFanClubSpecialText02,
@@ -434,7 +429,7 @@ const u8 *const sTVTrainerFanClubSpecialTextGroup[] = {
gTVTrainerFanClubSpecialText05
};
-const u8 *const sTVNameRaterTextGroup[] = {
+static const u8 *const sTVNameRaterTextGroup[] = {
gTVNameRaterText00,
gTVNameRaterText01,
gTVNameRaterText02,
@@ -456,14 +451,14 @@ const u8 *const sTVNameRaterTextGroup[] = {
gTVNameRaterText18
};
-const u8 *const sTVPokemonContestLiveUpdates2TextGroup[] = {
+static const u8 *const sTVPokemonContestLiveUpdates2TextGroup[] = {
gTVPokemonContestLiveUpdates2Text00,
gTVPokemonContestLiveUpdates2Text01,
gTVPokemonContestLiveUpdates2Text02,
gTVPokemonContestLiveUpdates2Text03
};
-const u8 *const sTVPokemonTodayFailedTextGroup[] = {
+static const u8 *const sTVPokemonTodayFailedTextGroup[] = {
gTVPokemonTodayFailedText00,
gTVPokemonTodayFailedText01,
gTVPokemonTodayFailedText02,
@@ -473,18 +468,18 @@ const u8 *const sTVPokemonTodayFailedTextGroup[] = {
gTVPokemonTodayFailedText06
};
-const u8 *const sTVPokemonAnslerTextGroup[] = {
+static const u8 *const sTVPokemonAnslerTextGroup[] = {
gTVPokemonAnglerText00,
gTVPokemonAnglerText01
};
-const u8 *const sTVWorldOfMastersTextGroup[] = {
+static const u8 *const sTVWorldOfMastersTextGroup[] = {
gTVWorldOfMastersText00,
gTVWorldOfMastersText01,
gTVWorldOfMastersText02
};
-const u8 *const sTVTodaysRivalTrainerTextGroup[] = {
+static const u8 *const sTVTodaysRivalTrainerTextGroup[] = {
gTVTodaysRivalTrainerText00,
gTVTodaysRivalTrainerText01,
gTVTodaysRivalTrainerText02,
@@ -498,7 +493,7 @@ const u8 *const sTVTodaysRivalTrainerTextGroup[] = {
gTVTodaysRivalTrainerText10
};
-const u8 *const sTVDewfordTrendWatcherNetworkTextGroup[] = {
+static const u8 *const sTVDewfordTrendWatcherNetworkTextGroup[] = {
gTVDewfordTrendWatcherNetworkText00,
gTVDewfordTrendWatcherNetworkText01,
gTVDewfordTrendWatcherNetworkText02,
@@ -508,20 +503,20 @@ const u8 *const sTVDewfordTrendWatcherNetworkTextGroup[] = {
gTVDewfordTrendWatcherNetworkText06
};
-const u8 *const sTVHoennTreasureInvestisatorsTextGroup[] = {
+static const u8 *const sTVHoennTreasureInvestisatorsTextGroup[] = {
gTVHoennTreasureInvestigatorsText00,
gTVHoennTreasureInvestigatorsText01,
gTVHoennTreasureInvestigatorsText02
};
-const u8 *const sTVFindThatGamerTextGroup[] = {
+static const u8 *const sTVFindThatGamerTextGroup[] = {
gTVFindThatGamerText00,
gTVFindThatGamerText01,
gTVFindThatGamerText02,
gTVFindThatGamerText03
};
-const u8 *const sTVBreakinsNewsTextGroup[] = {
+static const u8 *const sTVBreakinsNewsTextGroup[] = {
gTVBreakingNewsText00,
gTVBreakingNewsText01,
gTVBreakingNewsText02,
@@ -537,7 +532,7 @@ const u8 *const sTVBreakinsNewsTextGroup[] = {
gTVBreakingNewsText12
};
-const u8 *const sTVSecretBaseVisitTextGroup[] = {
+static const u8 *const sTVSecretBaseVisitTextGroup[] = {
gTVSecretBaseVisitText00,
gTVSecretBaseVisitText01,
gTVSecretBaseVisitText02,
@@ -554,11 +549,11 @@ const u8 *const sTVSecretBaseVisitTextGroup[] = {
gTVSecretBaseVisitText13
};
-const u8 *const sTVPokemonLotteryWinnerFlashReportTextGroup[] = {
+static const u8 *const sTVPokemonLotteryWinnerFlashReportTextGroup[] = {
gTVPokemonLotteryWinnerFlashReportText00
};
-const u8 *const sTVThePokemonBattleSeminarTextGroup[] = {
+static const u8 *const sTVThePokemonBattleSeminarTextGroup[] = {
gTVThePokemonBattleSeminarText00,
gTVThePokemonBattleSeminarText01,
gTVThePokemonBattleSeminarText02,
@@ -568,7 +563,7 @@ const u8 *const sTVThePokemonBattleSeminarTextGroup[] = {
gTVThePokemonBattleSeminarText06
};
-const u8 *const sTVTrainerFanClubTextGroup[] = {
+static const u8 *const sTVTrainerFanClubTextGroup[] = {
gTVTrainerFanClubText00,
gTVTrainerFanClubText01,
gTVTrainerFanClubText02,
@@ -583,7 +578,7 @@ const u8 *const sTVTrainerFanClubTextGroup[] = {
gTVTrainerFanClubText11
};
-const u8 *const sTVCutiesTextGroup[] = {
+static const u8 *const sTVCutiesTextGroup[] = {
gTVCutiesText00,
gTVCutiesText01,
gTVCutiesText02,
@@ -602,7 +597,7 @@ const u8 *const sTVCutiesTextGroup[] = {
gTVCutiesText15
};
-const u8 *const sTVPokemonNewsBattleFrontierTextGroup[] = {
+static const u8 *const sTVPokemonNewsBattleFrontierTextGroup[] = {
gTVPokemonNewsBattleFrontierText00,
gTVPokemonNewsBattleFrontierText01,
gTVPokemonNewsBattleFrontierText02,
@@ -624,7 +619,7 @@ const u8 *const sTVPokemonNewsBattleFrontierTextGroup[] = {
gTVPokemonNewsBattleFrontierText18
};
-const u8 *const sTVWhatsNo1InHoennTodayTextGroup[] = {
+static const u8 *const sTVWhatsNo1InHoennTodayTextGroup[] = {
gTVWhatsNo1InHoennTodayText00,
gTVWhatsNo1InHoennTodayText01,
gTVWhatsNo1InHoennTodayText02,
@@ -636,7 +631,7 @@ const u8 *const sTVWhatsNo1InHoennTodayTextGroup[] = {
gTVWhatsNo1InHoennTodayText08
};
-const u8 *const sTVSecretBaseSecretsTextGroup[] = {
+static const u8 *const sTVSecretBaseSecretsTextGroup[] = {
gTVSecretBaseSecretsText00,
gTVSecretBaseSecretsText01,
gTVSecretBaseSecretsText02,
@@ -682,7 +677,7 @@ const u8 *const sTVSecretBaseSecretsTextGroup[] = {
gTVSecretBaseSecretsText42
};
-const u8 *const sTVSafariFanClubTextGroup[] = {
+static const u8 *const sTVSafariFanClubTextGroup[] = {
gTVSafariFanClubText00,
gTVSafariFanClubText01,
gTVSafariFanClubText02,
@@ -696,7 +691,7 @@ const u8 *const sTVSafariFanClubTextGroup[] = {
gTVSafariFanClubText10
};
-const u8 *const sTVInSearchOfTrainersTextGroup[] = {
+static const u8 *const sTVInSearchOfTrainersTextGroup[] = {
gTVInSearchOfTrainersText00,
gTVInSearchOfTrainersText01,
gTVInSearchOfTrainersText02,
@@ -1253,7 +1248,7 @@ void tv_store_id_2x(TVShow *show)
show->common.trainerIdHi = id >> 8;
}
-void InterviewAfter_ContestLiveUpdates(void)
+static void InterviewAfter_ContestLiveUpdates(void)
{
TVShow *show;
TVShow *show2;
@@ -1281,7 +1276,7 @@ void InterviewAfter_ContestLiveUpdates(void)
}
}
-void PutBattleUpdateOnTheAir(u8 a0, u16 a1, u16 a2, u16 a3)
+void PutBattleUpdateOnTheAir(u8 opponentLinkPlayerId, u16 move, u16 speciesPlayer, u16 speciesOpponent)
{
TVShow *show;
u8 name[32];
@@ -1308,21 +1303,21 @@ void PutBattleUpdateOnTheAir(u8 a0, u16 a1, u16 a2, u16 a3)
{
show->battleUpdate.battleType = 0;
}
- show->battleUpdate.move = a1;
- show->battleUpdate.species2 = a2;
- show->battleUpdate.species = a3;
- StringCopy(name, gLinkPlayers[a0].name);
+ show->battleUpdate.move = move;
+ show->battleUpdate.speciesPlayer = speciesPlayer;
+ show->battleUpdate.speciesOpponent = speciesOpponent;
+ StringCopy(name, gLinkPlayers[opponentLinkPlayerId].name);
StripExtCtrlCodes(name);
StringCopy(show->battleUpdate.linkOpponentName, name);
tv_store_id_2x(show);
show->battleUpdate.language = gGameLanguage;
- if (show->battleUpdate.language == LANGUAGE_JAPANESE || gLinkPlayers[a0].language == LANGUAGE_JAPANESE)
+ if (show->battleUpdate.language == LANGUAGE_JAPANESE || gLinkPlayers[opponentLinkPlayerId].language == LANGUAGE_JAPANESE)
{
show->battleUpdate.linkOpponentLanguage = LANGUAGE_JAPANESE;
}
else
{
- show->battleUpdate.linkOpponentLanguage = gLinkPlayers[a0].language;
+ show->battleUpdate.linkOpponentLanguage = gLinkPlayers[opponentLinkPlayerId].language;
}
}
}
@@ -1385,13 +1380,13 @@ void PutFanClubSpecialOnTheAir(void)
StringCopy(show->fanClubSpecial.idolName, name);
tv_store_id_2x(show);
show->fanClubSpecial.language = gGameLanguage;
- if (show->fanClubSpecial.language == LANGUAGE_JAPANESE || gSaveBlock1Ptr->unk_31A0 == LANGUAGE_JAPANESE)
+ if (show->fanClubSpecial.language == LANGUAGE_JAPANESE || gSaveBlock1Ptr->linkBattleRecords.languages[0] == LANGUAGE_JAPANESE)
{
show->fanClubSpecial.idolNameLanguage = LANGUAGE_JAPANESE;
}
else
{
- show->fanClubSpecial.idolNameLanguage = gSaveBlock1Ptr->unk_31A0;
+ show->fanClubSpecial.idolNameLanguage = gSaveBlock1Ptr->linkBattleRecords.languages[0];
}
}
@@ -1472,7 +1467,7 @@ void ContestLiveUpdates_BeforeInterview_5(u8 a0, u8 a1)
}
}
-void InterviewAfter_BravoTrainerPokemonProfile(void)
+static void InterviewAfter_BravoTrainerPokemonProfile(void)
{
TVShow *show;
TVShow *show2;
@@ -1538,7 +1533,7 @@ void BravoTrainerPokemonProfile_BeforeInterview2(u8 a0)
}
}
-void InterviewAfter_BravoTrainerBattleTowerProfile(void)
+static void InterviewAfter_BravoTrainerBattleTowerProfile(void)
{
TVShow *show;
@@ -1671,7 +1666,7 @@ void PutLilycoveContestLadyShowOnTheAir(void)
}
}
-void InterviewAfter_FanClubLetter(void)
+static void InterviewAfter_FanClubLetter(void)
{
TVShow *show;
@@ -1684,7 +1679,7 @@ void InterviewAfter_FanClubLetter(void)
show->fanclubLetter.language = gGameLanguage;
}
-void InterviewAfter_RecentHappenings(void)
+static void InterviewAfter_RecentHappenings(void)
{
TVShow *show;
@@ -1697,7 +1692,7 @@ void InterviewAfter_RecentHappenings(void)
show->recentHappenings.language = gGameLanguage;
}
-void InterviewAfter_PkmnFanClubOpinions(void)
+static void InterviewAfter_PkmnFanClubOpinions(void)
{
TVShow *show;
@@ -1722,14 +1717,14 @@ void InterviewAfter_PkmnFanClubOpinions(void)
}
}
-void InterviewAfter_DummyShow4()
+static void InterviewAfter_DummyShow4(void)
{
TVShow *show;
show = &gSaveBlock1Ptr->tvShows[sCurTVShowSlot];
}
-void sub_80ED718(void)
+static void sub_80ED718(void)
{
u8 i;
u16 outbreakIdx;
@@ -1794,7 +1789,6 @@ void EndMassOutbreak(void)
void UpdateTVShowsPerDay(u16 days)
{
-
sub_80ED8B4(days);
UpdateMassOutbreakTimeLeft(days);
sub_80EF120(days);
@@ -1802,7 +1796,7 @@ void UpdateTVShowsPerDay(u16 days)
sub_80EEB98(days);
}
-void sub_80ED8B4(u16 days)
+static void sub_80ED8B4(u16 days)
{
u8 i;
TVShow *show;
@@ -1872,7 +1866,7 @@ void PutFishingAdviceShowOnTheAir(void)
{
TVShow *show;
- sCurTVShowSlot = FindEmptyTVSlotBeyondFirstFiveShowsOfArray(gSaveBlock1Ptr->tvShows);
+ sCurTVShowSlot = FindEmptyTVSlotBeyondFirstFiveShowsOfArray(gSaveBlock1Ptr->tvShows);
if (sCurTVShowSlot != -1 && HasMixableShowAlreadyBeenSpawnedWithPlayerID(TVSHOW_FISHING_ADVICE, FALSE) != TRUE)
{
show = &gSaveBlock1Ptr->tvShows[sCurTVShowSlot];
@@ -1892,7 +1886,7 @@ void SetPokemonAnglerSpecies(u16 species)
sPokemonAnglerSpecies = species;
}
-void sub_80EDA48(u16 days)
+static void sub_80EDA48(u16 days)
{
TVShow *show;
@@ -1957,11 +1951,11 @@ void sub_80EDB44(void)
show->rivalTrainer.badgeCount = nBadges;
if (IsNationalPokedexEnabled())
{
- show->rivalTrainer.dexCount = pokedex_count(0x01);
+ show->rivalTrainer.dexCount = GetNationalPokedexCount(0x01);
}
else
{
- show->rivalTrainer.dexCount = sub_80C0844(0x01);
+ show->rivalTrainer.dexCount = GetHoennPokedexCount(0x01);
}
show->rivalTrainer.location = gMapHeader.regionMapSectionId;
show->rivalTrainer.mapDataId = gMapHeader.mapDataId;
@@ -2088,8 +2082,7 @@ void sub_80EDE84(u16 nCoinsSpent)
sFindThatGamerCoinsSpent = nCoinsSpent;
}
-#ifdef NONMATCHING // FIXME: Register allocation shenanigans
-void sub_80EDE98(TVShow *show)
+static void sub_80EDE98(TVShow *show)
{
u8 i;
u8 j;
@@ -2140,11 +2133,11 @@ void sub_80EDE98(TVShow *show)
default:
for (k = 0; k < n * n; k ++)
{
- i = Random() % n;
+ deco = Random() % n;
j = Random() % n;
- x = sTV_DecorationsBuffer[i];
- sTV_DecorationsBuffer[i] = sTV_DecorationsBuffer[j];
- sTV_DecorationsBuffer[j] = x;
+ i = sTV_DecorationsBuffer[deco];
+ sTV_DecorationsBuffer[deco] = sTV_DecorationsBuffer[j];
+ sTV_DecorationsBuffer[j] = i;
}
for (i = 0; i < show->secretBaseVisit.nDecorations; i ++)
{
@@ -2153,157 +2146,8 @@ void sub_80EDE98(TVShow *show)
break;
}
}
-#else
-__attribute__((naked))
-void sub_80EDE98(TVShow *show)
-{
- asm_unified("\tpush {r4-r7,lr}\n"
- "\tmov r7, r9\n"
- "\tmov r6, r8\n"
- "\tpush {r6,r7}\n"
- "\tmov r8, r0\n"
- "\tmovs r3, 0\n"
- "\tldr r6, =sTV_DecorationsBuffer\n"
- "\tldr r7, =gSaveBlock1Ptr\n"
- "\tadds r2, r6, 0\n"
- "\tmovs r1, 0\n"
- "_080EDEAC:\n"
- "\tadds r0, r3, r2\n"
- "\tstrb r1, [r0]\n"
- "\tadds r0, r3, 0x1\n"
- "\tlsls r0, 24\n"
- "\tlsrs r3, r0, 24\n"
- "\tcmp r3, 0xF\n"
- "\tbls _080EDEAC\n"
- "\tmovs r3, 0\n"
- "\tmovs r5, 0\n"
- "_080EDEBE:\n"
- "\tldr r0, [r7]\n"
- "\tldr r1, =0x00001aae\n"
- "\tadds r0, r1\n"
- "\tadds r0, r3\n"
- "\tldrb r4, [r0]\n"
- "\tadds r3, 0x1\n"
- "\tcmp r4, 0\n"
- "\tbeq _080EDF0A\n"
- "\tmovs r1, 0\n"
- "\tldrb r0, [r6]\n"
- "\tcmp r0, 0\n"
- "\tbne _080EDEE8\n"
- "\tstrb r4, [r6]\n"
- "\tb _080EDF04\n"
- "\t.pool\n"
- "_080EDEE8:\n"
- "\tadds r0, r1, r6\n"
- "\tldrb r0, [r0]\n"
- "\tcmp r0, r4\n"
- "\tbeq _080EDF0A\n"
- "\tadds r0, r1, 0x1\n"
- "\tlsls r0, 24\n"
- "\tlsrs r1, r0, 24\n"
- "\tcmp r1, 0xF\n"
- "\tbhi _080EDF0A\n"
- "\tadds r2, r1, r6\n"
- "\tldrb r0, [r2]\n"
- "\tcmp r0, 0\n"
- "\tbne _080EDEE8\n"
- "\tstrb r4, [r2]\n"
- "_080EDF04:\n"
- "\tadds r0, r5, 0x1\n"
- "\tlsls r0, 24\n"
- "\tlsrs r5, r0, 24\n"
- "_080EDF0A:\n"
- "\tlsls r0, r3, 24\n"
- "\tlsrs r3, r0, 24\n"
- "\tcmp r3, 0xF\n"
- "\tbls _080EDEBE\n"
- "\tcmp r5, 0x4\n"
- "\tbls _080EDF1E\n"
- "\tmovs r0, 0x4\n"
- "\tmov r1, r8\n"
- "\tstrb r0, [r1, 0x3]\n"
- "\tb _080EDF22\n"
- "_080EDF1E:\n"
- "\tmov r0, r8\n"
- "\tstrb r5, [r0, 0x3]\n"
- "_080EDF22:\n"
- "\tmov r1, r8\n"
- "\tldrb r0, [r1, 0x3]\n"
- "\tcmp r0, 0\n"
- "\tbeq _080EDFA4\n"
- "\tcmp r0, 0x1\n"
- "\tbne _080EDF34\n"
- "\tldrb r0, [r6]\n"
- "\tstrb r0, [r1, 0x4]\n"
- "\tb _080EDFA4\n"
- "_080EDF34:\n"
- "\tmovs r6, 0\n"
- "\tadds r7, r5, 0\n"
- "\tmuls r7, r5\n"
- "\tcmp r6, r7\n"
- "\tbge _080EDF7E\n"
- "\tldr r0, =sTV_DecorationsBuffer\n"
- "\tmov r9, r0\n"
- "_080EDF42:\n"
- "\tbl Random\n"
- "\tlsls r0, 16\n"
- "\tlsrs r0, 16\n"
- "\tadds r1, r5, 0\n"
- "\tbl __modsi3\n"
- "\tlsls r0, 24\n"
- "\tlsrs r4, r0, 24\n"
- "\tbl Random\n"
- "\tlsls r0, 16\n"
- "\tlsrs r0, 16\n"
- "\tadds r1, r5, 0\n"
- "\tbl __modsi3\n"
- "\tlsls r0, 24\n"
- "\tlsrs r1, r0, 24\n"
- "\tmov r0, r9\n"
- "\tadds r2, r4, r0\n"
- "\tldrb r3, [r2]\n"
- "\tadd r1, r9\n"
- "\tldrb r0, [r1]\n"
- "\tstrb r0, [r2]\n"
- "\tstrb r3, [r1]\n"
- "\tadds r0, r6, 0x1\n"
- "\tlsls r0, 16\n"
- "\tlsrs r6, r0, 16\n"
- "\tcmp r6, r7\n"
- "\tblt _080EDF42\n"
- "_080EDF7E:\n"
- "\tmovs r3, 0\n"
- "\tmov r1, r8\n"
- "\tldrb r1, [r1, 0x3]\n"
- "\tcmp r3, r1\n"
- "\tbcs _080EDFA4\n"
- "\tmov r2, r8\n"
- "\tadds r2, 0x4\n"
- "\tldr r4, =sTV_DecorationsBuffer\n"
- "_080EDF8E:\n"
- "\tadds r1, r2, r3\n"
- "\tadds r0, r3, r4\n"
- "\tldrb r0, [r0]\n"
- "\tstrb r0, [r1]\n"
- "\tadds r0, r3, 0x1\n"
- "\tlsls r0, 24\n"
- "\tlsrs r3, r0, 24\n"
- "\tmov r0, r8\n"
- "\tldrb r0, [r0, 0x3]\n"
- "\tcmp r3, r0\n"
- "\tbcc _080EDF8E\n"
- "_080EDFA4:\n"
- "\tpop {r3,r4}\n"
- "\tmov r8, r3\n"
- "\tmov r9, r4\n"
- "\tpop {r4-r7}\n"
- "\tpop {r0}\n"
- "\tbx r0\n"
- "\t.pool");
-}
-#endif
-void sub_80EDFB4(TVShow *show)
+static void sub_80EDFB4(TVShow *show)
{
u8 i;
u16 move;
@@ -2621,7 +2465,7 @@ bool8 sub_80EE7C0(void)
{
return TRUE;
}
- if (gSaveBlock1Ptr->linkBattleRecords[0].name[0] == EOS)
+ if (gSaveBlock1Ptr->linkBattleRecords.entries[0].name[0] == EOS)
{
return TRUE;
}
@@ -2740,7 +2584,7 @@ void sub_80EEA70(void)
}
}
-void sub_80EEB98(u16 days)
+static void sub_80EEB98(u16 days)
{
u8 i;
@@ -2758,7 +2602,7 @@ void sub_80EEB98(u16 days)
}
}
-void sub_80EEBF4(u8 actionIdx)
+static void sub_80EEBF4(u8 actionIdx)
{
TVShow *show;
@@ -2814,7 +2658,7 @@ void sub_80EED60(u16 delta)
// PokeNews
-void sub_80EED88(void)
+static void sub_80EED88(void)
{
u8 newsKind;
@@ -2865,7 +2709,7 @@ void ClearPokemonNewsI(u8 i)
gSaveBlock1Ptr->pokeNews[i].days = 0;
}
-void sub_80EEEB8(void)
+static void sub_80EEEB8(void)
{
u8 i;
u8 j;
@@ -2995,7 +2839,7 @@ bool8 sub_80EF0E4(u8 newsKind)
return FALSE;
}
-void sub_80EF120(u16 days)
+static void sub_80EF120(u16 days)
{
u8 i;
@@ -3073,48 +2917,25 @@ void TV_PrintIntToStringVar(u8 varIdx, int value)
{
int nDigits;
- nDigits = sub_80EF370(value);
+ nDigits = CountDigits(value);
ConvertIntToDecimalStringN(gTVStringVarPtrs[varIdx], value, STR_CONV_MODE_LEFT_ALIGN, nDigits);
}
-size_t sub_80EF370(int value)
+size_t CountDigits(int value)
{
- if (value / 10 == 0)
- {
- return 1;
- }
- if (value / 100 == 0)
- {
- return 2;
- }
- if (value / 1000 == 0)
- {
- return 3;
- }
- if (value / 10000 == 0)
- {
- return 4;
- }
- if (value / 100000 == 0)
- {
- return 5;
- }
- if (value / 1000000 == 0)
- {
- return 6;
- }
- if (value / 10000000 == 0)
- {
- return 7;
- }
- if (value / 100000000 == 0)
- {
- return 8;
- }
+ if (value / 10 == 0) return 1;
+ if (value / 100 == 0) return 2;
+ if (value / 1000 == 0) return 3;
+ if (value / 10000 == 0) return 4;
+ if (value / 100000 == 0) return 5;
+ if (value / 1000000 == 0) return 6;
+ if (value / 10000000 == 0) return 7;
+ if (value / 100000000 == 0) return 8;
+
return 1;
}
-void sub_80EF40C(u8 varIdx, TVShow *show)
+static void sub_80EF40C(u8 varIdx, TVShow *show)
{
u8 i;
int price;
@@ -3124,7 +2945,7 @@ void sub_80EF40C(u8 varIdx, TVShow *show)
{
if (show->smartshopperShow.itemIds[i] != ITEM_NONE)
{
- price += itemid_get_market_price(show->smartshopperShow.itemIds[i]) * show->smartshopperShow.itemAmounts[i];
+ price += ItemId_GetPrice(show->smartshopperShow.itemIds[i]) * show->smartshopperShow.itemAmounts[i];
}
}
if (show->smartshopperShow.priceReduced == TRUE)
@@ -3245,7 +3066,7 @@ void InterviewBefore(void)
}
}
-void InterviewBefore_FanClubLetter(void)
+static void InterviewBefore_FanClubLetter(void)
{
FindActiveBroadcastByShowType_SetScriptResult(TVSHOW_FAN_CLUB_LETTER);
if (!gSpecialVar_Result)
@@ -3255,7 +3076,7 @@ void InterviewBefore_FanClubLetter(void)
}
}
-void InterviewBefore_RecentHappenings(void)
+static void InterviewBefore_RecentHappenings(void)
{
FindActiveBroadcastByShowType_SetScriptResult(TVSHOW_RECENT_HAPPENINGS);
if (!gSpecialVar_Result)
@@ -3264,7 +3085,7 @@ void InterviewBefore_RecentHappenings(void)
}
}
-void InterviewBefore_PkmnFanClubOpinions(void)
+static void InterviewBefore_PkmnFanClubOpinions(void)
{
FindActiveBroadcastByShowType_SetScriptResult(TVSHOW_PKMN_FAN_CLUB_OPINIONS);
if (!gSpecialVar_Result)
@@ -3276,17 +3097,17 @@ void InterviewBefore_PkmnFanClubOpinions(void)
}
}
-void InterviewBefore_Dummy(void)
+static void InterviewBefore_Dummy(void)
{
gSpecialVar_Result = TRUE;
}
-void InterviewBefore_NameRater(void)
+static void InterviewBefore_NameRater(void)
{
FindActiveBroadcastByShowType_SetScriptResult(TVSHOW_NAME_RATER_SHOW);
}
-void InterviewBefore_BravoTrainerPkmnProfile(void)
+static void InterviewBefore_BravoTrainerPkmnProfile(void)
{
FindActiveBroadcastByShowType_SetScriptResult(TVSHOW_BRAVO_TRAINER_POKEMON_PROFILE);
if (!gSpecialVar_Result)
@@ -3295,17 +3116,17 @@ void InterviewBefore_BravoTrainerPkmnProfile(void)
}
}
-void InterviewBefore_ContestLiveUpdates(void)
+static void InterviewBefore_ContestLiveUpdates(void)
{
FindActiveBroadcastByShowType_SetScriptResult(TVSHOW_CONTEST_LIVE_UPDATES);
}
-void InterviewBefore_3CheersForPokeblocks(void)
+static void InterviewBefore_3CheersForPokeblocks(void)
{
FindActiveBroadcastByShowType_SetScriptResult(TVSHOW_3_CHEERS_FOR_POKEBLOCKS);
}
-void InterviewBefore_BravoTrainerBTProfile(void)
+static void InterviewBefore_BravoTrainerBTProfile(void)
{
FindActiveBroadcastByShowType_SetScriptResult(TVSHOW_BRAVO_TRAINER_BATTLE_TOWER_PROFILE);
if (!gSpecialVar_Result)
@@ -3314,7 +3135,7 @@ void InterviewBefore_BravoTrainerBTProfile(void)
}
}
-void InterviewBefore_FanClubSpecial(void)
+static void InterviewBefore_FanClubSpecial(void)
{
FindActiveBroadcastByShowType_SetScriptResult(TVSHOW_FAN_CLUB_SPECIAL);
if (!gSpecialVar_Result)
@@ -3355,7 +3176,7 @@ void DeleteTVShowInArrayByIdx(TVShow *shows, u8 idx)
}
}
-void sub_80EF93C(TVShow *shows)
+static void sub_80EF93C(TVShow *shows)
{
u8 i;
u8 j;
@@ -3427,7 +3248,7 @@ u16 TV_GetSomeOtherSpeciesAlreadySeenByPlayer(u16 passedSpecies)
return species;
}
-void sub_80EFA88(void)
+static void sub_80EFA88(void)
{
sCurTVShowSlot = FindEmptyTVSlotWithinFirstFiveShowsOfArray(gSaveBlock1Ptr->tvShows);
gSpecialVar_0x8006 = sCurTVShowSlot;
@@ -3633,7 +3454,7 @@ void ChangePokemonNickname(void)
void ChangePokemonNickname_CB(void)
{
SetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar2);
- c2_exit_to_overworld_1_continue_scripts_restart_music();
+ CB2_ReturnToFieldContinueScript();
}
void ChangeBoxPokemonNickname(void)
@@ -3649,7 +3470,7 @@ void ChangeBoxPokemonNickname(void)
void ChangeBoxPokemonNickname_CB(void)
{
SetBoxMonNickFromAnyBox(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, gStringVar2);
- c2_exit_to_overworld_1_continue_scripts_restart_music();
+ CB2_ReturnToFieldContinueScript();
}
void TV_CopyNicknameToStringVar1AndEnsureTerminated(void)
@@ -3836,7 +3657,7 @@ void sub_80F01E8(void *src, u32 size, u8 masterIdx)
}
}
-void sub_80F0358(TVShow player1[25], TVShow player2[25], TVShow player3[25], TVShow player4[25])
+static void sub_80F0358(TVShow player1[25], TVShow player2[25], TVShow player3[25], TVShow player4[25])
{
u8 i;
u8 j;
@@ -3884,7 +3705,7 @@ void sub_80F0358(TVShow player1[25], TVShow player2[25], TVShow player3[25], TVS
}
}
-bool8 sub_80F049C(TVShow *dest[25], TVShow *src[25], u8 idx)
+static bool8 sub_80F049C(TVShow *dest[25], TVShow *src[25], u8 idx)
{
u8 value;
u8 switchval;
@@ -3915,7 +3736,7 @@ bool8 sub_80F049C(TVShow *dest[25], TVShow *src[25], u8 idx)
return FALSE;
}
-u8 sub_80F0580(TVShow *tv1, TVShow *tv2, u8 idx)
+static bool8 sub_80F0580(TVShow *tv1, TVShow *tv2, u8 idx)
{
u32 linkTrainerId = GetLinkPlayerTrainerId(idx);
@@ -3932,7 +3753,7 @@ u8 sub_80F0580(TVShow *tv1, TVShow *tv2, u8 idx)
return TRUE;
}
-u8 sub_80F05E8(TVShow *tv1, TVShow *tv2, u8 idx)
+static bool8 sub_80F05E8(TVShow *tv1, TVShow *tv2, u8 idx)
{
u32 linkTrainerId = GetLinkPlayerTrainerId(idx);
if ((linkTrainerId & 0xFF) == tv2->common.srcTrainerIdLo && ((linkTrainerId >> 8) & 0xFF) == tv2->common.srcTrainerIdHi)
@@ -3952,7 +3773,7 @@ u8 sub_80F05E8(TVShow *tv1, TVShow *tv2, u8 idx)
return TRUE;
}
-u8 sub_80F0668(TVShow *tv1, TVShow *tv2, u8 idx)
+static bool8 sub_80F0668(TVShow *tv1, TVShow *tv2, u8 idx)
{
u32 linkTrainerId = GetLinkPlayerTrainerId(idx);
if ((linkTrainerId & 0xFF) == tv2->common.trainerIdLo && ((linkTrainerId >> 8) & 0xFF) == tv2->common.trainerIdHi)
@@ -3969,7 +3790,7 @@ u8 sub_80F0668(TVShow *tv1, TVShow *tv2, u8 idx)
return TRUE;
}
-s8 sub_80F06D0(TVShow *tvShows)
+static s8 sub_80F06D0(TVShow *tvShows)
{
u8 i;
@@ -3984,7 +3805,7 @@ s8 sub_80F06D0(TVShow *tvShows)
}
#ifdef NONMATCHING
-void sub_80F0708(void) // FIXME: register allocation shenanigans
+static void sub_80F0708(void) // FIXME: register allocation shenanigans
{
u16 i;
TVShow *show;
@@ -4000,8 +3821,8 @@ void sub_80F0708(void) // FIXME: register allocation shenanigans
case TVSHOW_3_CHEERS_FOR_POKEBLOCKS:
break;
case TVSHOW_BATTLE_UPDATE:
- sub_80F0B24((&gSaveBlock1Ptr->tvShows[i])->battleUpdate.species2, i);
- sub_80F0B24((&gSaveBlock1Ptr->tvShows[i])->battleUpdate.species, i);
+ sub_80F0B24((&gSaveBlock1Ptr->tvShows[i])->battleUpdate.speciesPlayer, i);
+ sub_80F0B24((&gSaveBlock1Ptr->tvShows[i])->battleUpdate.speciesOpponent, i);
break;
case TVSHOW_FAN_CLUB_SPECIAL:
break;
@@ -4104,13 +3925,13 @@ void sub_80F0708(void) // FIXME: register allocation shenanigans
break;
default:
- sub_80F0B00(i);
+ SetTvShowInactive(i);
break;
}
}
}
#else
-__attribute__((naked)) void sub_80F0708(void)
+NAKED static void sub_80F0708(void)
{
asm_unified("\tpush {r4-r7,lr}\n"
"\tmov r7, r9\n"
@@ -4527,7 +4348,7 @@ __attribute__((naked)) void sub_80F0708(void)
"\tmov r2, r9\n"
"\tlsls r0, r2, 24\n"
"\tlsrs r0, 24\n"
- "\tbl sub_80F0B00\n"
+ "\tbl SetTvShowInactive\n"
"_080F0AE2_break:\n"
"\tmov r0, r9\n"
"\tadds r0, 0x1\n"
@@ -4548,12 +4369,12 @@ __attribute__((naked)) void sub_80F0708(void)
}
#endif
-void sub_80F0B00(u8 showIdx)
+void SetTvShowInactive(u8 showIdx)
{
gSaveBlock1Ptr->tvShows[showIdx].common.active = FALSE;
}
-void sub_80F0B24(u16 species, u8 showIdx)
+static void sub_80F0B24(u16 species, u8 showIdx)
{
if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), 0) == 0)
{
@@ -4561,7 +4382,7 @@ void sub_80F0B24(u16 species, u8 showIdx)
}
}
-void sub_80F0B64(void)
+static void sub_80F0B64(void)
{
u16 i;
@@ -4594,7 +4415,7 @@ void sub_80F0BB8(void)
}
}
-void sub_80F0C04(void)
+static void sub_80F0C04(void)
{
s8 i;
s8 ct;
@@ -4648,7 +4469,7 @@ void sub_80F0C7C(void *src, u32 size, u8 masterIdx)
}
}
-void sub_80F0D60(PokeNews player1[16], PokeNews player2[16], PokeNews player3[16], PokeNews player4[16])
+static void sub_80F0D60(PokeNews player1[16], PokeNews player2[16], PokeNews player3[16], PokeNews player4[16])
{
u8 i;
u8 j;
@@ -4680,7 +4501,7 @@ void sub_80F0D60(PokeNews player1[16], PokeNews player2[16], PokeNews player3[16
}
}
-void sub_80F0E58(PokeNews *dest[16], PokeNews *src[16])
+static void sub_80F0E58(PokeNews *dest[16], PokeNews *src[16])
{
PokeNews *ptr1;
PokeNews *ptr2;
@@ -4691,7 +4512,7 @@ void sub_80F0E58(PokeNews *dest[16], PokeNews *src[16])
sub_80F0E84(ptr1, ptr2, sCurTVShowSlot);
}
-bool8 sub_80F0E84(PokeNews *dest, PokeNews *src, s8 slot)
+static bool8 sub_80F0E84(PokeNews *dest, PokeNews *src, s8 slot)
{
u8 i;
u8 kind;
@@ -4713,7 +4534,7 @@ bool8 sub_80F0E84(PokeNews *dest, PokeNews *src, s8 slot)
return TRUE;
}
-s8 sub_80F0ECC(PokeNews *pokeNews, u8 idx)
+static s8 sub_80F0ECC(PokeNews *pokeNews, u8 idx)
{
if (pokeNews[idx].kind == POKENEWS_NONE)
{
@@ -4722,7 +4543,7 @@ s8 sub_80F0ECC(PokeNews *pokeNews, u8 idx)
return idx;
}
-void sub_80F0EEC(void)
+static void sub_80F0EEC(void)
{
u8 i;
@@ -4736,7 +4557,7 @@ void sub_80F0EEC(void)
sub_80EEEB8();
}
-void sub_80F0F24(void)
+static void sub_80F0F24(void)
{
u8 i;
@@ -4759,7 +4580,7 @@ else \
(langptr) = langfix; \
}
-void sub_80F0F64(TVShow *show, u32 language)
+static void sub_80F0F64(TVShow *show, u32 language)
{
int i;
TVShow **r4;
@@ -4841,7 +4662,7 @@ void sub_80F1208(TVShow *shows)
}
}
-void sub_80F1254(TVShow *shows)
+static void sub_80F1254(TVShow *shows)
{
TVShow *curShow;
@@ -4866,7 +4687,7 @@ u8 TV_GetStringLanguage(u8 *str)
return IsStringJapanese(str) ? LANGUAGE_JAPANESE : LANGUAGE_ENGLISH;
}
-void sub_80F12A4(TVShow *shows)
+static void sub_80F12A4(TVShow *shows)
{
TVShow *curShow;
@@ -5106,7 +4927,7 @@ void DoTVShow(void)
}
}
-void DoTVShowBravoTrainerPokemonProfile(void)
+static void DoTVShowBravoTrainerPokemonProfile(void)
{
TVShow *show;
u8 state;
@@ -5178,7 +4999,7 @@ void DoTVShowBravoTrainerPokemonProfile(void)
ShowFieldMessage(sTVBravoTrainerTextGroup[state]);
}
-void DoTVShowBravoTrainerBattleTower(void)
+static void DoTVShowBravoTrainerBattleTower(void)
{
TVShow *show;
u8 state;
@@ -5275,7 +5096,7 @@ void DoTVShowBravoTrainerBattleTower(void)
ShowFieldMessage(sTVBravoTrainerBattleTowerTextGroup[state]);
}
-void DoTVShowTodaysSmartShopper(void)
+static void DoTVShowTodaysSmartShopper(void)
{
TVShow *show;
u8 state;
@@ -5299,7 +5120,7 @@ void DoTVShowTodaysSmartShopper(void)
break;
case 1:
TVShowConvertInternationalString(gStringVar1, show->smartshopperShow.playerName, show->smartshopperShow.language);
- StringCopy(gStringVar2, ItemId_GetItem(show->smartshopperShow.itemIds[0])->name);
+ StringCopy(gStringVar2, ItemId_GetName(show->smartshopperShow.itemIds[0]));
TV_PrintIntToStringVar(2, show->smartshopperShow.itemAmounts[0]);
sTVShowState += 1 + (Random() % 4);
break;
@@ -5327,7 +5148,7 @@ void DoTVShowTodaysSmartShopper(void)
}
break;
case 6:
- StringCopy(gStringVar2, ItemId_GetItem(show->smartshopperShow.itemIds[1])->name);
+ StringCopy(gStringVar2, ItemId_GetName(show->smartshopperShow.itemIds[1]));
TV_PrintIntToStringVar(2, show->smartshopperShow.itemAmounts[1]);
if (show->smartshopperShow.itemIds[2] != ITEM_NONE)
{
@@ -5343,7 +5164,7 @@ void DoTVShowTodaysSmartShopper(void)
}
break;
case 7:
- StringCopy(gStringVar2, ItemId_GetItem(show->smartshopperShow.itemIds[2])->name);
+ StringCopy(gStringVar2, ItemId_GetName(show->smartshopperShow.itemIds[2]));
TV_PrintIntToStringVar(2, show->smartshopperShow.itemAmounts[2]);
if (show->smartshopperShow.priceReduced == TRUE)
{
@@ -5380,7 +5201,7 @@ void DoTVShowTodaysSmartShopper(void)
break;
case 11:
TVShowConvertInternationalString(gStringVar1, show->smartshopperShow.playerName, show->smartshopperShow.language);
- StringCopy(gStringVar2, ItemId_GetItem(show->smartshopperShow.itemIds[0])->name);
+ StringCopy(gStringVar2, ItemId_GetName(show->smartshopperShow.itemIds[0]));
if (show->smartshopperShow.priceReduced == TRUE)
{
sTVShowState = 8;
@@ -5398,7 +5219,7 @@ void DoTVShowTodaysSmartShopper(void)
ShowFieldMessage(sTVTodaysSmartShopperTextGroup[state]);
}
-void DoTVShowTheNameRaterShow(void)
+static void DoTVShowTheNameRaterShow(void)
{
TVShow *show;
u8 state;
@@ -5496,7 +5317,7 @@ void DoTVShowTheNameRaterShow(void)
ShowFieldMessage(sTVNameRaterTextGroup[state]);
}
-void DoTVShowPokemonTodaySuccessfulCapture(void)
+static void DoTVShowPokemonTodaySuccessfulCapture(void)
{
TVShow *show;
u8 state;
@@ -5523,7 +5344,7 @@ void DoTVShowPokemonTodaySuccessfulCapture(void)
sTVShowState = 2;
break;
case 2:
- StringCopy(gStringVar2, ItemId_GetItem(show->pokemonToday.ball)->name);
+ StringCopy(gStringVar2, ItemId_GetName(show->pokemonToday.ball));
TV_PrintIntToStringVar(2, show->pokemonToday.nBallsUsed);
if (show->pokemonToday.nBallsUsed < 4)
{
@@ -5574,7 +5395,7 @@ void DoTVShowPokemonTodaySuccessfulCapture(void)
ShowFieldMessage(sTVPokemonTodaySuccessfulTextGroup[state]);
}
-void DoTVShowPokemonTodayFailedCapture(void)
+static void DoTVShowPokemonTodayFailedCapture(void)
{
TVShow *show;
u8 state;
@@ -5627,7 +5448,7 @@ void DoTVShowPokemonTodayFailedCapture(void)
ShowFieldMessage(sTVPokemonTodayFailedTextGroup[state]);
}
-void DoTVShowPokemonFanClubLetter(void)
+static void DoTVShowPokemonFanClubLetter(void)
{
TVShow *show;
u8 state;
@@ -5681,7 +5502,7 @@ void DoTVShowPokemonFanClubLetter(void)
ShowFieldMessage(sTVFanClubTextGroup[state]);
}
-void DoTVShowRecentHappenings(void)
+static void DoTVShowRecentHappenings(void)
{
TVShow *show;
u8 state;
@@ -5716,7 +5537,7 @@ void DoTVShowRecentHappenings(void)
ShowFieldMessage(sTVRecentHappeninssTextGroup[state]);
}
-void DoTVShowPokemonFanClubOpinions(void)
+static void DoTVShowPokemonFanClubOpinions(void)
{
TVShow *show;
u8 state;
@@ -5749,12 +5570,12 @@ void DoTVShowPokemonFanClubOpinions(void)
ShowFieldMessage(sTVFanClubOpinionsTextGroup[state]);
}
-void DoTVShowDummiedOut(void)
+static void DoTVShowDummiedOut(void)
{
}
-void DoTVShowPokemonNewsMassOutbreak(void)
+static void DoTVShowPokemonNewsMassOutbreak(void)
{
TVShow *show;
@@ -5766,7 +5587,7 @@ void DoTVShowPokemonNewsMassOutbreak(void)
ShowFieldMessage(sTVMassOutbreakTextGroup[sTVShowState]);
}
-void DoTVShowPokemonContestLiveUpdates(void)
+static void DoTVShowPokemonContestLiveUpdates(void)
{
TVShow *show;
u8 state;
@@ -6113,7 +5934,7 @@ void DoTVShowPokemonContestLiveUpdates(void)
ShowFieldMessage(sTVContestLiveUpdatesTextGroup[state]);
}
-void DoTVShowPokemonBattleUpdate(void)
+static void DoTVShowPokemonBattleUpdate(void)
{
TVShow *show;
u8 state;
@@ -6150,13 +5971,13 @@ void DoTVShowPokemonBattleUpdate(void)
break;
case 2:
TVShowConvertInternationalString(gStringVar1, show->battleUpdate.playerName, show->battleUpdate.language);
- StringCopy(gStringVar2, gSpeciesNames[show->battleUpdate.species2]);
+ StringCopy(gStringVar2, gSpeciesNames[show->battleUpdate.speciesPlayer]);
StringCopy(gStringVar3, gMoveNames[show->battleUpdate.move]);
sTVShowState = 3;
break;
case 3:
TVShowConvertInternationalString(gStringVar1, show->battleUpdate.linkOpponentName, show->battleUpdate.linkOpponentLanguage);
- StringCopy(gStringVar2, gSpeciesNames[show->battleUpdate.species]);
+ StringCopy(gStringVar2, gSpeciesNames[show->battleUpdate.speciesOpponent]);
sTVShowState = 4;
break;
case 4:
@@ -6171,21 +5992,21 @@ void DoTVShowPokemonBattleUpdate(void)
break;
case 6:
TVShowConvertInternationalString(gStringVar1, show->battleUpdate.playerName, show->battleUpdate.language);
- StringCopy(gStringVar2, gSpeciesNames[show->battleUpdate.species2]);
+ StringCopy(gStringVar2, gSpeciesNames[show->battleUpdate.speciesPlayer]);
StringCopy(gStringVar3, gMoveNames[show->battleUpdate.move]);
sTVShowState = 7;
break;
case 7:
TVShowConvertInternationalString(gStringVar1, show->battleUpdate.playerName, show->battleUpdate.language);
TVShowConvertInternationalString(gStringVar2, show->battleUpdate.linkOpponentName, show->battleUpdate.linkOpponentLanguage);
- StringCopy(gStringVar3, gSpeciesNames[show->battleUpdate.species]);
+ StringCopy(gStringVar3, gSpeciesNames[show->battleUpdate.speciesOpponent]);
TVShowDone();
break;
}
ShowFieldMessage(sTVPokemonBattleUpdateTextGroup[state]);
}
-void DoTVShow3CheersForPokeblocks(void)
+static void DoTVShow3CheersForPokeblocks(void)
{
TVShow *show;
u8 state;
@@ -6356,7 +6177,7 @@ void DoTVShowInSearchOfTrainers(void)
ShowFieldMessage(sTVInSearchOfTrainersTextGroup[state]);
}
-void DoTVShowPokemonAngler(void)
+static void DoTVShowPokemonAngler(void)
{
TVShow *show;
u8 state;
@@ -6390,7 +6211,7 @@ void DoTVShowPokemonAngler(void)
ShowFieldMessage(sTVPokemonAnslerTextGroup[state]);
}
-void DoTVShowTheWorldOfMasters(void)
+static void DoTVShowTheWorldOfMasters(void)
{
TVShow *show;
u8 state;
@@ -6420,7 +6241,7 @@ void DoTVShowTheWorldOfMasters(void)
ShowFieldMessage(sTVWorldOfMastersTextGroup[state]);
}
-void DoTVShowTodaysRivalTrainer(void)
+static void DoTVShowTodaysRivalTrainer(void)
{
TVShow *show;
u8 state;
@@ -6569,7 +6390,7 @@ void DoTVShowTodaysRivalTrainer(void)
ShowFieldMessage(sTVTodaysRivalTrainerTextGroup[state]);
}
-void DoTVShowDewfordTrendWatcherNetwork(void)
+static void DoTVShowDewfordTrendWatcherNetwork(void)
{
TVShow *show;
u8 state;
@@ -6625,7 +6446,7 @@ void DoTVShowDewfordTrendWatcherNetwork(void)
ShowFieldMessage(sTVDewfordTrendWatcherNetworkTextGroup[state]);
}
-void DoTVShowHoennTreasureInvestigators(void)
+static void DoTVShowHoennTreasureInvestigators(void)
{
TVShow *show;
u8 state;
@@ -6636,7 +6457,7 @@ void DoTVShowHoennTreasureInvestigators(void)
switch (state)
{
case 0:
- StringCopy(gStringVar1, ItemId_GetItem(show->treasureInvestigators.item)->name);
+ StringCopy(gStringVar1, ItemId_GetName(show->treasureInvestigators.item));
if (show->treasureInvestigators.location == MAPSEC_DYNAMIC)
{
switch (show->treasureInvestigators.mapDataId)
@@ -6655,13 +6476,13 @@ void DoTVShowHoennTreasureInvestigators(void)
}
break;
case 1:
- StringCopy(gStringVar1, ItemId_GetItem(show->treasureInvestigators.item)->name);
+ StringCopy(gStringVar1, ItemId_GetName(show->treasureInvestigators.item));
TVShowConvertInternationalString(gStringVar2, show->treasureInvestigators.playerName, show->treasureInvestigators.language);
GetMapName(gStringVar3, show->treasureInvestigators.location, 0);
TVShowDone();
break;
case 2:
- StringCopy(gStringVar1, ItemId_GetItem(show->treasureInvestigators.item)->name);
+ StringCopy(gStringVar1, ItemId_GetName(show->treasureInvestigators.item));
TVShowConvertInternationalString(gStringVar2, show->treasureInvestigators.playerName, show->treasureInvestigators.language);
TVShowDone();
break;
@@ -6669,7 +6490,7 @@ void DoTVShowHoennTreasureInvestigators(void)
ShowFieldMessage(sTVHoennTreasureInvestisatorsTextGroup[state]);
}
-void DoTVShowFindThatGamer(void)
+static void DoTVShowFindThatGamer(void)
{
TVShow *show;
u8 state;
@@ -6743,7 +6564,7 @@ void DoTVShowFindThatGamer(void)
ShowFieldMessage(sTVFindThatGamerTextGroup[state]);
}
-void DoTVShowBreakingNewsTV(void)
+static void DoTVShowBreakingNewsTV(void)
{
TVShow *show;
u8 state;
@@ -6777,7 +6598,7 @@ void DoTVShowBreakingNewsTV(void)
break;
case 3:
TV_PrintIntToStringVar(0, show->breakingNews.balls);
- StringCopy(gStringVar2, ItemId_GetItem(show->breakingNews.caughtMonBall)->name);
+ StringCopy(gStringVar2, ItemId_GetName(show->breakingNews.caughtMonBall));
sTVShowState = 4;
break;
case 4:
@@ -6846,7 +6667,7 @@ void DoTVShowBreakingNewsTV(void)
ShowFieldMessage(sTVBreakinsNewsTextGroup[state]);
}
-void DoTVShowSecretBaseVisit(void)
+static void DoTVShowSecretBaseVisit(void)
{
TVShow *show;
u8 state;
@@ -6942,7 +6763,7 @@ void DoTVShowSecretBaseVisit(void)
ShowFieldMessage(sTVSecretBaseVisitTextGroup[state]);
}
-void DoTVShowPokemonLotteryWinnerFlashReport(void)
+static void DoTVShowPokemonLotteryWinnerFlashReport(void)
{
TVShow *show;
u8 state;
@@ -6967,12 +6788,12 @@ void DoTVShowPokemonLotteryWinnerFlashReport(void)
{
StringCopy(gStringVar2, gText_Third);
}
- StringCopy(gStringVar3, ItemId_GetItem(show->lottoWinner.item)->name);
+ StringCopy(gStringVar3, ItemId_GetName(show->lottoWinner.item));
TVShowDone();
ShowFieldMessage(sTVPokemonLotteryWinnerFlashReportTextGroup[state]);
}
-void DoTVShowThePokemonBattleSeminar(void)
+static void DoTVShowThePokemonBattleSeminar(void)
{
TVShow *show;
u8 state;
@@ -7036,7 +6857,7 @@ void DoTVShowThePokemonBattleSeminar(void)
ShowFieldMessage(sTVThePokemonBattleSeminarTextGroup[state]);
}
-void DoTVShowTrainerFanClubSpecial(void)
+static void DoTVShowTrainerFanClubSpecial(void)
{
TVShow *show;
u8 state;
@@ -7101,7 +6922,7 @@ void DoTVShowTrainerFanClubSpecial(void)
ShowFieldMessage(sTVTrainerFanClubSpecialTextGroup[state]);
}
-void DoTVShowTrainerFanClub(void)
+static void DoTVShowTrainerFanClub(void)
{
TVShow *show;
u8 state;
@@ -7188,7 +7009,7 @@ void DoTVShowTrainerFanClub(void)
ShowFieldMessage(sTVTrainerFanClubTextGroup[state]);
}
-void DoTVShowSpotTheCuties(void)
+static void DoTVShowSpotTheCuties(void)
{
TVShow *show;
u8 state;
@@ -7293,7 +7114,7 @@ void DoTVShowSpotTheCuties(void)
ShowFieldMessage(sTVCutiesTextGroup[state]);
}
-void DoTVShowPokemonNewsBattleFrontier(void)
+static void DoTVShowPokemonNewsBattleFrontier(void)
{
TVShow *show;
u8 state;
@@ -7442,7 +7263,7 @@ void DoTVShowPokemonNewsBattleFrontier(void)
ShowFieldMessage(sTVPokemonNewsBattleFrontierTextGroup[state]);
}
-void DoTVShowWhatsNo1InHoennToday(void)
+static void DoTVShowWhatsNo1InHoennToday(void)
{
TVShow *show;
u8 state;
@@ -7557,7 +7378,7 @@ u8 sub_80F51AC(TVShow *show, u8 a1)
return 0;
}
-void DoTVShowSecretBaseSecrets(void)
+static void DoTVShowSecretBaseSecrets(void)
{
TVShow *show;
u8 state;
@@ -7709,7 +7530,7 @@ void DoTVShowSecretBaseSecrets(void)
sTVShowState = show->secretBaseSecrets.savedState;
break;
case 19:
- StringCopy(gStringVar2, ItemId_GetItem(show->secretBaseSecrets.item)->name);
+ StringCopy(gStringVar2, ItemId_GetName(show->secretBaseSecrets.item));
sTVShowState = show->secretBaseSecrets.savedState;
break;
case 20:
@@ -7795,7 +7616,7 @@ void DoTVShowSecretBaseSecrets(void)
ShowFieldMessage(sTVSecretBaseSecretsTextGroup[state]);
}
-void DoTVShowSafariFanClub(void)
+static void DoTVShowSafariFanClub(void)
{
TVShow *show;
u8 state;
@@ -7882,7 +7703,7 @@ void DoTVShowSafariFanClub(void)
ShowFieldMessage(sTVSafariFanClubTextGroup[state]);
}
-void DoTVShowPokemonContestLiveUpdates2(void)
+static void DoTVShowPokemonContestLiveUpdates2(void)
{
TVShow *show;
u8 state;
diff --git a/src/util.c b/src/util.c
index 58088c3ee..88be4e4a1 100644
--- a/src/util.c
+++ b/src/util.c
@@ -230,7 +230,7 @@ void CopySpriteTiles(u8 shape, u8 size, u8 *tiles, u16 *tilemap, u8 *output)
}
#else
-__attribute__((naked)) void CopySpriteTiles(u8 shape, u8 size, u8 *tiles, u16 *tilemap, u8 *output)
+NAKED void CopySpriteTiles(u8 shape, u8 size, u8 *tiles, u16 *tilemap, u8 *output)
{
asm("\n\
.syntax unified\n\
diff --git a/src/walda_phrase.c b/src/walda_phrase.c
index 59fd3fedb..0aa6f5aca 100644
--- a/src/walda_phrase.c
+++ b/src/walda_phrase.c
@@ -6,15 +6,14 @@
#include "main.h"
#include "text.h"
#include "new_game.h"
-
-extern void (*gFieldCallback)(void);
+#include "overworld.h"
extern const u8 gText_Peekaboo[];
extern u8 *GetWaldaPhrasePtr(void);
extern bool32 IsWaldaPhraseEmpty(void);
extern void sub_80AF168(void);
-extern void c2_exit_to_overworld_2_switch(void);
+extern void CB2_ReturnToField(void);
extern void SetWaldaPhrase(const u8 *src);
extern void SetWaldaWallpaperPatternId(u8 patternId);
extern void SetWaldaWallpaperIconId(u8 iconId);
@@ -80,7 +79,7 @@ static void CB2_HandleGivenWaldaPhrase(void)
StringCopy(gStringVar1, GetWaldaPhrasePtr());
gFieldCallback = sub_80AF168;
- SetMainCallback2(c2_exit_to_overworld_2_switch);
+ SetMainCallback2(CB2_ReturnToField);
}
static u32 GetWaldaPhraseInputCase(u8 *inputPtr)
diff --git a/src/window.c b/src/window.c
index 9a892d079..9a52a5a20 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1,9 +1,14 @@
#include "global.h"
#include "window.h"
#include "malloc.h"
-
-extern u8 gUnknown_03002F60;
-extern void* gUnknown_03002F70[];
+#include "bg.h"
+#include "blit.h"
+
+u32 filler_03002F58;
+u32 filler_03002F5C;
+u8 gUnknown_03002F60;
+u32 filler_03002F64;
+void *gUnknown_03002F70[4];
extern u32 gUnneededFireRedVariable;
#define WINDOWS_MAX 32
@@ -12,19 +17,6 @@ EWRAM_DATA struct Window gWindows[WINDOWS_MAX] = {0};
EWRAM_DATA static struct Window* sWindowPtr = NULL;
EWRAM_DATA static u16 sWindowSize = 0;
-extern void* GetBgTilemapBuffer(u8 bg);
-extern int DummiedOutFireRedLeafGreenTileAllocFunc(int, int, int, int);
-extern u16 GetBgAttribute(u8 bg, u8 attributeId);
-extern void SetBgTilemapBuffer(u8 bg, void *tilemap);
-extern void CopyBgTilemapBufferToVram(u8 bg);
-extern u8 LoadBgTiles(u8 bg, void *src, u16 size, u16 destOffset);
-extern void WriteSequenceToBgTilemapBuffer(u8 bg, u16 firstTileNum, u8 x, u8 y, u8 width, u8 height, u8 paletteSlot, u16 tileNumDelta);
-extern void FillBgTilemapBufferRect(u8 bg, u16 tileNum, u8 x, u8 y, u8 width, u8 height, u8 palette);
-extern void BlitBitmapRect4Bit(struct Bitmap *src, struct Bitmap *dest, u16 srcX, u16 srcY, u16 destX, u16 destY, u16 width, u16 height, u8 colorKey);
-extern void BlitBitmapRect4BitTo8Bit(struct Bitmap *src, struct Bitmap *dest, u16 srcX, u16 srcY, u16 destX, u16 destY, u16 width, u16 height, u8 colorKey, u8 paletteNum);
-extern void FillBitmapRect4Bit(struct Bitmap *surface, u16 x, u16 y, u16 width, u16 height, u8 fillValue);
-extern void FillBitmapRect8Bit(struct Bitmap *surface, u16 x, u16 y, u16 width, u16 height, u8 fillValue);
-
static u8 GetNumActiveWindowsOnBg(u8 bgId);
static u8 GetNumActiveWindowsOnBg8Bit(u8 bgId);
@@ -127,13 +119,13 @@ u16 AddWindow(const struct WindowTemplate *template)
u8 *allocatedTilemapBuffer;
int i;
- for (win = 0; win < 0x20; ++win)
+ for (win = 0; win < WINDOWS_MAX; ++win)
{
if ((bgLayer = gWindows[win].window.priority) == 0xFF)
break;
}
- if (win == 0x20)
+ if (win == WINDOWS_MAX)
return 0xFF;
bgLayer = template->priority;
@@ -196,13 +188,13 @@ int AddWindowWithoutTileMap(const struct WindowTemplate *template)
u8 bgLayer;
int allocatedBaseBlock;
- for (win = 0; win < 0x20; ++win)
+ for (win = 0; win < WINDOWS_MAX; ++win)
{
if (gWindows[win].window.priority == 0xFF)
break;
}
- if (win == 0x20)
+ if (win == WINDOWS_MAX)
return 0xFF;
bgLayer = template->priority;