summaryrefslogtreecommitdiff
path: root/src/field
diff options
context:
space:
mode:
Diffstat (limited to 'src/field')
-rw-r--r--src/field/bard_music.c69
-rw-r--r--src/field/berry.c1380
-rw-r--r--src/field/berry_tag_screen.c455
-rw-r--r--src/field/bike.c1011
-rw-r--r--src/field/birch_pc.c114
-rw-r--r--src/field/braille_puzzles.c262
-rw-r--r--src/field/choose_party.c987
-rw-r--r--src/field/coins.c84
-rw-r--r--src/field/coord_event_weather.c118
-rw-r--r--src/field/daycare.c1690
-rw-r--r--src/field/decoration.c4280
-rw-r--r--src/field/decoration_inventory.c169
-rw-r--r--src/field/dewford_trend.c332
-rw-r--r--src/field/diploma.c139
-rw-r--r--src/field/easy_chat.c444
-rw-r--r--src/field/event_data.c182
-rw-r--r--src/field/field_camera.c495
-rw-r--r--src/field/field_control_avatar.c878
-rw-r--r--src/field/field_door.c222
-rw-r--r--src/field/field_effect.c3405
-rw-r--r--src/field/field_effect_helpers.c1632
-rw-r--r--src/field/field_fadetransition.c626
-rw-r--r--src/field/field_ground_effect.c796
-rw-r--r--src/field/field_map_obj.c8356
-rw-r--r--src/field/field_map_obj_helpers.c318
-rw-r--r--src/field/field_message_box.c155
-rw-r--r--src/field/field_player_avatar.c1757
-rw-r--r--src/field/field_poison.c143
-rw-r--r--src/field/field_region_map.c125
-rw-r--r--src/field/field_screen_effect.c341
-rw-r--r--src/field/field_special_scene.c349
-rw-r--r--src/field/field_specials.c2383
-rw-r--r--src/field/field_tasks.c868
-rw-r--r--src/field/field_weather.c367
-rw-r--r--src/field/fieldmap.c955
-rw-r--r--src/field/fldeff_cut.c287
-rw-r--r--src/field/fldeff_flash.c306
-rw-r--r--src/field/fldeff_softboiled.c153
-rw-r--r--src/field/fldeff_strength.c76
-rw-r--r--src/field/fldeff_sweetscent.c88
-rw-r--r--src/field/fldeff_teleport.c46
-rw-r--r--src/field/heal_location.c63
-rw-r--r--src/field/hof_pc.c42
-rw-r--r--src/field/item.c674
-rw-r--r--src/field/item_menu.c4575
-rw-r--r--src/field/item_use.c1200
-rw-r--r--src/field/landmark.c73
-rw-r--r--src/field/lottery_corner.c174
-rw-r--r--src/field/map_name_popup.c107
-rw-r--r--src/field/map_obj_lock.c118
-rw-r--r--src/field/mauville_man.c1311
-rw-r--r--src/field/menu_helpers.c572
-rw-r--r--src/field/metatile_behavior.c1308
-rw-r--r--src/field/money.c263
-rw-r--r--src/field/overworld.c2674
-rw-r--r--src/field/party_menu.c1494
-rw-r--r--src/field/player_pc.c1368
-rw-r--r--src/field/pokeblock.c1133
-rw-r--r--src/field/pokenav.c42
-rw-r--r--src/field/region_map.c1847
-rw-r--r--src/field/roamer.c226
-rw-r--r--src/field/rotating_gate.c1155
-rw-r--r--src/field/safari_zone.c253
-rw-r--r--src/field/scrcmd.c2020
-rw-r--r--src/field/script_menu.c1178
-rw-r--r--src/field/script_movement.c228
-rw-r--r--src/field/secret_base.c1075
-rw-r--r--src/field/shop.c1351
-rw-r--r--src/field/slot_machine.c150
-rw-r--r--src/field/start_menu.c850
-rw-r--r--src/field/starter_choose.c757
-rw-r--r--src/field/trader.c262
-rw-r--r--src/field/trainer_see.c519
-rw-r--r--src/field/tv.c3259
-rw-r--r--src/field/use_pokeblock.c905
-rw-r--r--src/field/wallclock.c1061
-rw-r--r--src/field/wild_encounter.c3573
77 files changed, 74703 insertions, 0 deletions
diff --git a/src/field/bard_music.c b/src/field/bard_music.c
new file mode 100644
index 000000000..daf003233
--- /dev/null
+++ b/src/field/bard_music.c
@@ -0,0 +1,69 @@
+#include "global.h"
+#include "bard_music.h"
+#include "easy_chat.h"
+
+struct BardSound
+{
+ /*0x00*/ u8 var00;
+ /*0x01*/ s8 var01;
+ /*0x02*/ u16 var02;
+ /*0x04*/ u16 volume;
+ /*0x06*/ u16 var06;
+};
+
+extern const struct BardSound (*const gBardMusicTable[])[][6];
+extern s16 *gUnknown_08417068[];
+extern u32 gUnknown_084170F4[];
+
+static s16 CalcWordPitch(u32 arg0, u32 songPos)
+{
+ return gUnknown_08417068[arg0][songPos];
+}
+
+#if ENGLISH
+const struct BardSound *GetWordSounds(u16 group, u16 word)
+{
+ const struct BardSound (*sounds)[][6] = gBardMusicTable[group];
+
+ return (*sounds)[word];
+}
+#elif GERMAN
+const struct BardSound *GetWordSounds(u16 group, u16 word)
+{
+ const struct BardSound (*sounds)[][6] = gBardMusicTable[group];
+ u32 index = de_sub_80EB748(group, word);
+
+ return (*sounds)[index];
+}
+#endif
+
+s32 GetWordPhonemes(struct BardSong *song, const struct BardSound *src, u16 arg2)
+{
+ s32 i;
+ s32 j;
+ s32 thirty;
+
+ for (i = 0; i < 6; i++)
+ {
+ song->phonemes[i].sound = src[i].var00;
+ if (src[i].var00 != 0xFF)
+ {
+ s32 length = src[i].var01 + gUnknown_084170F4[src[i].var00];
+
+ song->phonemes[i].length = length;
+ song->phonemes[i].volume = src[i].volume;
+ song->var04 += length;
+ }
+ }
+
+ for (j = 0, thirty = 30; j < i; j++)
+ song->phonemes[j].pitch = CalcWordPitch(thirty + arg2, j);
+
+ song->currWord++;
+ song->currPhoneme = 0;
+ song->phonemeTimer = 0;
+ song->state = 0;
+ song->voiceInflection = 0;
+
+ //warning: no return statement in function returning non-void
+}
diff --git a/src/field/berry.c b/src/field/berry.c
new file mode 100644
index 000000000..d82eab2a6
--- /dev/null
+++ b/src/field/berry.c
@@ -0,0 +1,1380 @@
+#include "global.h"
+#include "berry.h"
+#include "field_control_avatar.h"
+#include "field_map_obj.h"
+#include "fieldmap.h"
+#include "item.h"
+#include "item_menu.h"
+#include "item_use.h"
+#include "items.h"
+#include "main.h"
+#include "rng.h"
+#include "text.h"
+
+#define BERRY_NAME_LENGTH 6
+
+#define FIRST_BERRY ITEM_CHERI_BERRY
+#define LAST_BERRY ITEM_ENIGMA_BERRY
+
+#ifdef ENGLISH
+#define NAME_CHERI_BERRY _("CHERI")
+#define NAME_CHESTO_BERRY _("CHESTO")
+#define NAME_PECHA_BERRY _("PECHA")
+#define NAME_RAWST_BERRY _("RAWST")
+#define NAME_ASPEAR_BERRY _("ASPEAR")
+#define NAME_LEPPA_BERRY _("LEPPA")
+#define NAME_ORAN_BERRY _("ORAN")
+#define NAME_PERSIM_BERRY _("PERSIM")
+#define NAME_LUM_BERRY _("LUM")
+#define NAME_SITRUS_BERRY _("SITRUS")
+#define NAME_FIGY_BERRY _("FIGY")
+#define NAME_WIKI_BERRY _("WIKI")
+#define NAME_MAGO_BERRY _("MAGO")
+#define NAME_AGUAV_BERRY _("AGUAV")
+#define NAME_IAPAPA_BERRY _("IAPAPA")
+#define NAME_RAZZ_BERRY _("RAZZ")
+#define NAME_BLUK_BERRY _("BLUK")
+#define NAME_NANAB_BERRY _("NANAB")
+#define NAME_WEPEAR_BERRY _("WEPEAR")
+#define NAME_PINAP_BERRY _("PINAP")
+#define NAME_POMEG_BERRY _("POMEG")
+#define NAME_KELPSY_BERRY _("KELPSY")
+#define NAME_QUALOT_BERRY _("QUALOT")
+#define NAME_HONDEW_BERRY _("HONDEW")
+#define NAME_GREPA_BERRY _("GREPA")
+#define NAME_TAMATO_BERRY _("TAMATO")
+#define NAME_CORNN_BERRY _("CORNN")
+#define NAME_MAGOST_BERRY _("MAGOST")
+#define NAME_RABUTA_BERRY _("RABUTA")
+#define NAME_NOMEL_BERRY _("NOMEL")
+#define NAME_SPELON_BERRY _("SPELON")
+#define NAME_PAMTRE_BERRY _("PAMTRE")
+#define NAME_WATMEL_BERRY _("WATMEL")
+#define NAME_DURIN_BERRY _("DURIN")
+#define NAME_BELUE_BERRY _("BELUE")
+#define NAME_LIECHI_BERRY _("LIECHI")
+#define NAME_GANLON_BERRY _("GANLON")
+#define NAME_SALAC_BERRY _("SALAC")
+#define NAME_PETAYA_BERRY _("PETAYA")
+#define NAME_APICOT_BERRY _("APICOT")
+#define NAME_LANSAT_BERRY _("LANSAT")
+#define NAME_STARF_BERRY _("STARF")
+#define NAME_ENIGMA_BERRY _("ENIGMA")
+
+const u8 gBerryDescriptionPart1_Cheri[] = _("Blooms with delicate pretty flowers.");
+const u8 gBerryDescriptionPart2_Cheri[] = _("The bright red BERRY is very spicy.");
+const u8 gBerryDescriptionPart1_Chesto[] = _("The BERRY’s thick skin and fruit are");
+const u8 gBerryDescriptionPart2_Chesto[] = _("very tough. It is dry-tasting all over.");
+const u8 gBerryDescriptionPart1_Pecha[] = _("Very sweet and delicious.");
+const u8 gBerryDescriptionPart2_Pecha[] = _("Also very tender - handle with care.");
+const u8 gBerryDescriptionPart1_Rawst[] = _("If the leaves grow long and curly,");
+const u8 gBerryDescriptionPart2_Rawst[] = _("the BERRY seems to grow very bitter.");
+const u8 gBerryDescriptionPart1_Aspear[] = _("The hard BERRY is dense with a rich");
+const u8 gBerryDescriptionPart2_Aspear[] = _("juice. It is quite sour.");
+const u8 gBerryDescriptionPart1_Leppa[] = _("Grows slower than CHERI and others.");
+const u8 gBerryDescriptionPart2_Leppa[] = _("The smaller the BERRY, the tastier.");
+const u8 gBerryDescriptionPart1_Oran[] = _("A peculiar BERRY with a mix of flavors.");
+const u8 gBerryDescriptionPart2_Oran[] = _("BERRIES grow in half a day.");
+const u8 gBerryDescriptionPart1_Persim[] = _("Loves sunlight. The BERRY’s color");
+const u8 gBerryDescriptionPart2_Persim[] = _("grows vivid when exposed to the sun.");
+const u8 gBerryDescriptionPart1_Lum[] = _("Slow to grow. If raised with loving");
+const u8 gBerryDescriptionPart2_Lum[] = _("care, it may grow two BERRIES.");
+const u8 gBerryDescriptionPart1_Sitrus[] = _("Closely related to ORAN. The large");
+const u8 gBerryDescriptionPart2_Sitrus[] = _("BERRY has a well-rounded flavor.");
+const u8 gBerryDescriptionPart1_Figy[] = _("The BERRY, which looks chewed up,");
+const u8 gBerryDescriptionPart2_Figy[] = _("brims with spicy substances.");
+const u8 gBerryDescriptionPart1_Wiki[] = _("The BERRY is said to have grown lumpy");
+const u8 gBerryDescriptionPart2_Wiki[] = _("to help POKéMON grip it.");
+const u8 gBerryDescriptionPart1_Mago[] = _("The BERRY turns curvy as it grows.");
+const u8 gBerryDescriptionPart2_Mago[] = _("The curvier, the sweeter and tastier.");
+const u8 gBerryDescriptionPart1_Aguav[] = _("The flower is dainty. It is rare in its");
+const u8 gBerryDescriptionPart2_Aguav[] = _("ability to grow without light.");
+const u8 gBerryDescriptionPart1_Iapapa[] = _("The BERRY is very big and sour.");
+const u8 gBerryDescriptionPart2_Iapapa[] = _("It takes at least a day to grow.");
+const u8 gBerryDescriptionPart1_Razz[] = _("The red BERRY tastes slightly spicy.");
+const u8 gBerryDescriptionPart2_Razz[] = _("It grows quickly in just four hours.");
+const u8 gBerryDescriptionPart1_Bluk[] = _("The BERRY is blue on the outside, but");
+const u8 gBerryDescriptionPart2_Bluk[] = _("it blackens the mouth when eaten.");
+const u8 gBerryDescriptionPart1_Nanab[] = _("This BERRY was the seventh");
+const u8 gBerryDescriptionPart2_Nanab[] = _("discovered in the world. It is sweet.");
+const u8 gBerryDescriptionPart1_Wepear[] = _("The flower is small and white. It has a");
+const u8 gBerryDescriptionPart2_Wepear[] = _("delicate balance of bitter and sour.");
+const u8 gBerryDescriptionPart1_Pinap[] = _("Weak against wind and cold.");
+const u8 gBerryDescriptionPart2_Pinap[] = _("The fruit is spicy and the skin, sour.");
+const u8 gBerryDescriptionPart1_Pomeg[] = _("However much it is watered,");
+const u8 gBerryDescriptionPart2_Pomeg[] = _("it only grows up to six BERRIES.");
+const u8 gBerryDescriptionPart1_Kelpsy[] = _("A rare variety shaped like a root.");
+const u8 gBerryDescriptionPart2_Kelpsy[] = _("Grows a very large flower.");
+const u8 gBerryDescriptionPart1_Qualot[] = _("Loves water. Grows strong even in");
+const u8 gBerryDescriptionPart2_Qualot[] = _("locations with constant rainfall.");
+const u8 gBerryDescriptionPart1_Hondew[] = _("A BERRY that is very valuable and");
+const u8 gBerryDescriptionPart2_Hondew[] = _("rarely seen. It is very delicious.");
+const u8 gBerryDescriptionPart1_Grepa[] = _("Despite its tenderness and round");
+const u8 gBerryDescriptionPart2_Grepa[] = _("shape, the BERRY is unimaginably sour.");
+const u8 gBerryDescriptionPart1_Tamato[] = _("The BERRY is lip-bendingly spicy.");
+const u8 gBerryDescriptionPart2_Tamato[] = _("It takes time to grow.");
+const u8 gBerryDescriptionPart1_Cornn[] = _("A BERRY from an ancient era. May not");
+const u8 gBerryDescriptionPart2_Cornn[] = _("grow unless planted in quantity.");
+const u8 gBerryDescriptionPart1_Magost[] = _("A BERRY that is widely said to have");
+const u8 gBerryDescriptionPart2_Magost[] = _("a finely balanced flavor.");
+const u8 gBerryDescriptionPart1_Rabuta[] = _("A rare variety that is overgrown with");
+const u8 gBerryDescriptionPart2_Rabuta[] = _("hair. It is quite bitter.");
+const u8 gBerryDescriptionPart1_Nomel[] = _("Quite sour. Just one bite makes it");
+const u8 gBerryDescriptionPart2_Nomel[] = _("impossible to taste for three days.");
+const u8 gBerryDescriptionPart1_Spelon[] = _("The vividly red BERRY is very spicy.");
+const u8 gBerryDescriptionPart2_Spelon[] = _("Its warts secrete a spicy substance.");
+const u8 gBerryDescriptionPart1_Pamtre[] = _("Drifts on the sea from somewhere.");
+const u8 gBerryDescriptionPart2_Pamtre[] = _("It is thought to grow elsewhere.");
+const u8 gBerryDescriptionPart1_Watmel[] = _("A huge BERRY, with some over 20");
+const u8 gBerryDescriptionPart2_Watmel[] = _("inches discovered. Exceedingly sweet.");
+const u8 gBerryDescriptionPart1_Durin[] = _("Bitter to even look at. It is so");
+const u8 gBerryDescriptionPart2_Durin[] = _("bitter, no one has ever eaten it as is.");
+const u8 gBerryDescriptionPart1_Belue[] = _("It is glossy and looks delicious, but");
+const u8 gBerryDescriptionPart2_Belue[] = _("it is awfully sour. Takes time to grow.");
+const u8 gBerryDescriptionPart1_Liechi[] = _("A mysterious BERRY. It is rumored to");
+const u8 gBerryDescriptionPart2_Liechi[] = _("contain the power of the sea.");
+const u8 gBerryDescriptionPart1_Ganlon[] = _("A mysterious BERRY. It is rumored to");
+const u8 gBerryDescriptionPart2_Ganlon[] = _("contain the power of the land.");
+const u8 gBerryDescriptionPart1_Salac[] = _("A mysterious BERRY. It is rumored to");
+const u8 gBerryDescriptionPart2_Salac[] = _("contain the power of the sky.");
+const u8 gBerryDescriptionPart1_Petaya[] = _("A mysterious BERRY. It is rumored to");
+const u8 gBerryDescriptionPart2_Petaya[] = _("contain the power of all living things.");
+const u8 gBerryDescriptionPart1_Apicot[] = _("A very mystifying BERRY. No telling");
+const u8 gBerryDescriptionPart2_Apicot[] = _("what may happen or how it can be used.");
+const u8 gBerryDescriptionPart1_Lansat[] = _("Said to be a legendary BERRY.");
+const u8 gBerryDescriptionPart2_Lansat[] = _("Holding it supposedly brings joy.");
+const u8 gBerryDescriptionPart1_Starf[] = _("So strong, it was abandoned at the");
+const u8 gBerryDescriptionPart2_Starf[] = _("world’s edge. Considered a mirage.");
+const u8 gBerryDescriptionPart1_Enigma[] = _("A completely enigmatic BERRY.");
+const u8 gBerryDescriptionPart2_Enigma[] = _("Appears to have the power of stars.");
+#elif defined(GERMAN)
+#define NAME_CHERI_BERRY _("AMRENA")
+#define NAME_CHESTO_BERRY _("MARON")
+#define NAME_PECHA_BERRY _("PIRSIF")
+#define NAME_RAWST_BERRY _("FRAGIA")
+#define NAME_ASPEAR_BERRY _("WILBIR")
+#define NAME_LEPPA_BERRY _("JONAGO")
+#define NAME_ORAN_BERRY _("SINEL")
+#define NAME_PERSIM_BERRY _("PERSIM")
+#define NAME_LUM_BERRY _("PRUNUS")
+#define NAME_SITRUS_BERRY _("TSITRU")
+#define NAME_FIGY_BERRY _("GIEFE")
+#define NAME_WIKI_BERRY _("WIKI")
+#define NAME_MAGO_BERRY _("MAGO")
+#define NAME_AGUAV_BERRY _("GAUVE")
+#define NAME_IAPAPA_BERRY _("YAPA")
+#define NAME_RAZZ_BERRY _("HIMMIH")
+#define NAME_BLUK_BERRY _("MORB")
+#define NAME_NANAB_BERRY _("NANAB")
+#define NAME_WEPEAR_BERRY _("NIRBE")
+#define NAME_PINAP_BERRY _("SANANA")
+#define NAME_POMEG_BERRY _("GRANA")
+#define NAME_KELPSY_BERRY _("SETANG")
+#define NAME_QUALOT_BERRY _("QUALOT")
+#define NAME_HONDEW_BERRY _("HONMEL")
+#define NAME_GREPA_BERRY _("LABRUS")
+#define NAME_TAMATO_BERRY _("TAMOT")
+#define NAME_CORNN_BERRY _("SAIM")
+#define NAME_MAGOST_BERRY _("MAGOST")
+#define NAME_RABUTA_BERRY _("RABUTA")
+#define NAME_NOMEL_BERRY _("TRONZI")
+#define NAME_SPELON_BERRY _("KIWAN")
+#define NAME_PAMTRE_BERRY _("PALLM")
+#define NAME_WATMEL_BERRY _("WASMEL")
+#define NAME_DURIN_BERRY _("DURIN")
+#define NAME_BELUE_BERRY _("MYRTIL")
+#define NAME_LIECHI_BERRY _("LYDZI")
+#define NAME_GANLON_BERRY _("LINGAN")
+#define NAME_SALAC_BERRY _("SALKA")
+#define NAME_PETAYA_BERRY _("TAHAY")
+#define NAME_APICOT_BERRY _("APIKO")
+#define NAME_LANSAT_BERRY _("LANSAT")
+#define NAME_STARF_BERRY _("KRAMBO")
+#define NAME_ENIGMA_BERRY _("ENIGMA")
+
+const u8 gBerryDescriptionPart1_Cheri[] = _("Erblüht mit hübschen, zarten Blumen.");
+const u8 gBerryDescriptionPart2_Cheri[] = _("Diese knallrote BEERE ist sehr scharf.");
+const u8 gBerryDescriptionPart1_Chesto[] = _("Diese BEERE hat eine dicke Haut und");
+const u8 gBerryDescriptionPart2_Chesto[] = _("hartes Fruchtfleisch. Trocken!");
+const u8 gBerryDescriptionPart1_Pecha[] = _("Sehr süß und delikat.");
+const u8 gBerryDescriptionPart2_Pecha[] = _("Sehr zart. Vorsichtig anfassen!");
+const u8 gBerryDescriptionPart1_Rawst[] = _("Wenn die Blätter lang und wellig sind,");
+const u8 gBerryDescriptionPart2_Rawst[] = _("wird die BEERE sehr bitter.");
+const u8 gBerryDescriptionPart1_Aspear[] = _("Diese harte BEERE ist sehr");
+const u8 gBerryDescriptionPart2_Aspear[] = _("saftig und sauer im Geschmack!");
+const u8 gBerryDescriptionPart1_Leppa[] = _("Wächst langsamer als AMRENA und");
+const u8 gBerryDescriptionPart2_Leppa[] = _("andere. Je kleiner, desto delikater.");
+const u8 gBerryDescriptionPart1_Oran[] = _("Eine BEERE unterschiedlichsten Ge-");
+const u8 gBerryDescriptionPart2_Oran[] = _("schmacks. Wächst an einem halben Tag.");
+const u8 gBerryDescriptionPart1_Persim[] = _("Liebt Sonnenlicht. Die BEERE");
+const u8 gBerryDescriptionPart2_Persim[] = _("wächst im Sonnenlicht sehr schnell.");
+const u8 gBerryDescriptionPart1_Lum[] = _("Langsamer Wuchs. Wird sie liebevoll ge-");
+const u8 gBerryDescriptionPart2_Lum[] = _("pflegt, kann sie 2 BEEREN tragen.");
+const u8 gBerryDescriptionPart1_Sitrus[] = _("Eng verwandt mit SINEL. Diese große");
+const u8 gBerryDescriptionPart2_Sitrus[] = _("BEERE ist von rundem Geschmack.");
+const u8 gBerryDescriptionPart1_Figy[] = _("Die BEERE sieht angekaut aus. Sie ist");
+const u8 gBerryDescriptionPart2_Figy[] = _("voller scharfer Substanzen.");
+const u8 gBerryDescriptionPart1_Wiki[] = _("Die BEERE wächst unförmig,");
+const u8 gBerryDescriptionPart2_Wiki[] = _("damit PKMN sie besser greifen können.");
+const u8 gBerryDescriptionPart1_Mago[] = _("Die BEERE hat Ausbeulungen. Je mehr");
+const u8 gBerryDescriptionPart2_Mago[] = _("Beulen, desto schmackhafter ist sie.");
+const u8 gBerryDescriptionPart1_Aguav[] = _("Die Blume ist zart. Sie ist fähig,");
+const u8 gBerryDescriptionPart2_Aguav[] = _("ohne Licht wachsen zu können.");
+const u8 gBerryDescriptionPart1_Iapapa[] = _("Die BEERE ist groß und sauer.");
+const u8 gBerryDescriptionPart2_Iapapa[] = _("Sie braucht einen Tag zum Wachsen.");
+const u8 gBerryDescriptionPart1_Razz[] = _("Diese rote BEERE schmeckt etwas");
+const u8 gBerryDescriptionPart2_Razz[] = _("scharf. Sie wächst in nur 4 Stunden.");
+const u8 gBerryDescriptionPart1_Bluk[] = _("Die BEERE ist außen blau, verfärbt");
+const u8 gBerryDescriptionPart2_Bluk[] = _("sich im Mund aber schwarz.");
+const u8 gBerryDescriptionPart1_Nanab[] = _("Diese BEERE war die 7., die auf der");
+const u8 gBerryDescriptionPart2_Nanab[] = _("Welt entdeckt wurde. Sie ist süß.");
+const u8 gBerryDescriptionPart1_Wepear[] = _("Die Blume ist klein und weiß. Angenehm");
+const u8 gBerryDescriptionPart2_Wepear[] = _("bitter und sauer zugleich.");
+const u8 gBerryDescriptionPart1_Pinap[] = _("Wind und Kälte verträgt sie nicht.");
+const u8 gBerryDescriptionPart2_Pinap[] = _("Fruchtfleisch: Scharf. Haut: Sauer.");
+const u8 gBerryDescriptionPart1_Pomeg[] = _("Egal wie viel Wasser sie bekommt, sie");
+const u8 gBerryDescriptionPart2_Pomeg[] = _("trägt immer bis zu 6 BEEREN.");
+const u8 gBerryDescriptionPart1_Kelpsy[] = _("Eine Seltenheit. Geformt wie eine");
+const u8 gBerryDescriptionPart2_Kelpsy[] = _("Wurzel. Hat eine große Blume.");
+const u8 gBerryDescriptionPart1_Qualot[] = _("Liebt das Wasser. Wächst besonders");
+const u8 gBerryDescriptionPart2_Qualot[] = _("gut in regenreichen Gegenden.");
+const u8 gBerryDescriptionPart1_Hondew[] = _("Eine wertvolle und seltene BEERE.");
+const u8 gBerryDescriptionPart2_Hondew[] = _("Sie ist sehr schmackhaft.");
+const u8 gBerryDescriptionPart1_Grepa[] = _("Die BEERE ist zart und von runder");
+const u8 gBerryDescriptionPart2_Grepa[] = _("Form. Aber sie ist unglaublich sauer!");
+const u8 gBerryDescriptionPart1_Tamato[] = _("Die Schärfe der BEERE verbrennt die");
+const u8 gBerryDescriptionPart2_Tamato[] = _("Lippen. Sie braucht Zeit zum Wachsen.");
+const u8 gBerryDescriptionPart1_Cornn[] = _("Eine BEERE aus alten Zeiten. Wächst");
+const u8 gBerryDescriptionPart2_Cornn[] = _("nur, wenn in großen Mengen gepflanzt.");
+const u8 gBerryDescriptionPart1_Magost[] = _("Eine BEERE, die für ihren feinen, aus-");
+const u8 gBerryDescriptionPart2_Magost[] = _("gewogenen Geschmack bekannt ist.");
+const u8 gBerryDescriptionPart1_Rabuta[] = _("Eine Seltenheit, die über und über mit");
+const u8 gBerryDescriptionPart2_Rabuta[] = _("Haaren bewachsen ist. Sehr bitter!");
+const u8 gBerryDescriptionPart1_Nomel[] = _("Sehr sauer. Ein Biss betäubt die");
+const u8 gBerryDescriptionPart2_Nomel[] = _("Geschmacksnerven für 3 Tage!");
+const u8 gBerryDescriptionPart1_Spelon[] = _("Die leuchtend rote BEERE ist sehr");
+const u8 gBerryDescriptionPart2_Spelon[] = _("scharf. Gibt scharfe Substanzen ab!");
+const u8 gBerryDescriptionPart1_Pamtre[] = _("Wird vom Meer angespült. Sie wächst");
+const u8 gBerryDescriptionPart2_Pamtre[] = _("an einem anderen Ort.");
+const u8 gBerryDescriptionPart1_Watmel[] = _("Eine große BEERE, 25 cm groß.");
+const u8 gBerryDescriptionPart2_Watmel[] = _("Außergewöhnlich süß.");
+const u8 gBerryDescriptionPart1_Durin[] = _("Bitter schon ihr Anblick! Sie ist so");
+const u8 gBerryDescriptionPart2_Durin[] = _("bitter, dass niemand sie pur isst.");
+const u8 gBerryDescriptionPart1_Belue[] = _("Sie glänzt, sieht zart aus, ist extrem");
+const u8 gBerryDescriptionPart2_Belue[] = _("sauer und braucht Zeit zum Wachsen.");
+const u8 gBerryDescriptionPart1_Liechi[] = _("Eine geheimnisvolle BEERE. Man sagt,");
+const u8 gBerryDescriptionPart2_Liechi[] = _("sie enthalte die Kraft des Meeres.");
+const u8 gBerryDescriptionPart1_Ganlon[] = _("Eine geheimnisvolle BEERE. Man sagt,");
+const u8 gBerryDescriptionPart2_Ganlon[] = _("sie enthalte die Kraft des Landes.");
+const u8 gBerryDescriptionPart1_Salac[] = _("Eine geheimnisvolle BEERE. Man sagt,");
+const u8 gBerryDescriptionPart2_Salac[] = _("sie enthalte die Kraft des Himmels.");
+const u8 gBerryDescriptionPart1_Petaya[] = _("Eine geheimnisvolle BEERE. Man sagt,");
+const u8 gBerryDescriptionPart2_Petaya[] = _("sie enthalte die Kraft allen Lebens.");
+const u8 gBerryDescriptionPart1_Apicot[] = _("Eine rätselhafte BEERE. Man kann");
+const u8 gBerryDescriptionPart2_Apicot[] = _("nicht sagen, wie und was sie ist.");
+const u8 gBerryDescriptionPart1_Lansat[] = _("Eine legendäre BEERE. Sie zu");
+const u8 gBerryDescriptionPart2_Lansat[] = _("tragen bringt Freude.");
+const u8 gBerryDescriptionPart1_Starf[] = _("So stark, dass sie an den Rand der");
+const u8 gBerryDescriptionPart2_Starf[] = _("Welt verbannt wurde. Ein Märchen?");
+const u8 gBerryDescriptionPart1_Enigma[] = _("Eine enigmatische BEERE. Sie scheint");
+const u8 gBerryDescriptionPart2_Enigma[] = _("die Macht der Sterne zu besitzen.");
+#endif
+
+const struct Berry gBerries[] =
+{
+ {
+ .name = NAME_CHERI_BERRY,
+ .firmness = BERRY_FIRMNESS_SOFT,
+ .size = 20,
+ .maxYield = 3,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Cheri,
+ .description2 = gBerryDescriptionPart2_Cheri,
+ .stageDuration = 3,
+ .spicy = 10,
+ .dry = 0,
+ .sweet = 0,
+ .bitter = 0,
+ .sour = 0,
+ .smoothness = 25,
+ },
+ {
+ .name = NAME_CHESTO_BERRY,
+ .firmness = BERRY_FIRMNESS_SUPER_HARD,
+ .size = 80,
+ .maxYield = 3,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Chesto,
+ .description2 = gBerryDescriptionPart2_Chesto,
+ .stageDuration = 3,
+ .spicy = 0,
+ .dry = 10,
+ .sweet = 0,
+ .bitter = 0,
+ .sour = 0,
+ .smoothness = 25,
+ },
+ {
+ .name = NAME_PECHA_BERRY,
+ .firmness = BERRY_FIRMNESS_VERY_SOFT,
+ .size = 40,
+ .maxYield = 3,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Pecha,
+ .description2 = gBerryDescriptionPart2_Pecha,
+ .stageDuration = 3,
+ .spicy = 0,
+ .dry = 0,
+ .sweet = 10,
+ .bitter = 0,
+ .sour = 0,
+ .smoothness = 25,
+ },
+ {
+ .name = NAME_RAWST_BERRY,
+ .firmness = BERRY_FIRMNESS_HARD,
+ .size = 32,
+ .maxYield = 3,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Rawst,
+ .description2 = gBerryDescriptionPart2_Rawst,
+ .stageDuration = 3,
+ .spicy = 0,
+ .dry = 0,
+ .sweet = 0,
+ .bitter = 10,
+ .sour = 0,
+ .smoothness = 25,
+ },
+ {
+ .name = NAME_ASPEAR_BERRY,
+ .firmness = BERRY_FIRMNESS_SUPER_HARD,
+ .size = 50,
+ .maxYield = 3,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Aspear,
+ .description2 = gBerryDescriptionPart2_Aspear,
+ .stageDuration = 3,
+ .spicy = 0,
+ .dry = 0,
+ .sweet = 0,
+ .bitter = 0,
+ .sour = 10,
+ .smoothness = 25,
+ },
+ {
+ .name = NAME_LEPPA_BERRY,
+ .firmness = BERRY_FIRMNESS_VERY_HARD,
+ .size = 28,
+ .maxYield = 3,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Leppa,
+ .description2 = gBerryDescriptionPart2_Leppa,
+ .stageDuration = 4,
+ .spicy = 10,
+ .dry = 0,
+ .sweet = 10,
+ .bitter = 10,
+ .sour = 10,
+ .smoothness = 20,
+ },
+ {
+ .name = NAME_ORAN_BERRY,
+ .firmness = BERRY_FIRMNESS_SUPER_HARD,
+ .size = 35,
+ .maxYield = 3,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Oran,
+ .description2 = gBerryDescriptionPart2_Oran,
+ .stageDuration = 3,
+ .spicy = 10,
+ .dry = 10,
+ .sweet = 10,
+ .bitter = 10,
+ .sour = 10,
+ .smoothness = 20,
+ },
+ {
+ .name = NAME_PERSIM_BERRY,
+ .firmness = BERRY_FIRMNESS_HARD,
+ .size = 47,
+ .maxYield = 3,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Persim,
+ .description2 = gBerryDescriptionPart2_Persim,
+ .stageDuration = 3,
+ .spicy = 10,
+ .dry = 10,
+ .sweet = 10,
+ .bitter = 10,
+ .sour = 10,
+ .smoothness = 20,
+ },
+ {
+ .name = NAME_LUM_BERRY,
+ .firmness = BERRY_FIRMNESS_SUPER_HARD,
+ .size = 34,
+ .maxYield = 2,
+ .minYield = 1,
+ .description1 = gBerryDescriptionPart1_Lum,
+ .description2 = gBerryDescriptionPart2_Lum,
+ .stageDuration = 12,
+ .spicy = 10,
+ .dry = 10,
+ .sweet = 10,
+ .bitter = 10,
+ .sour = 10,
+ .smoothness = 20,
+ },
+ {
+ .name = NAME_SITRUS_BERRY,
+ .firmness = BERRY_FIRMNESS_VERY_HARD,
+ .size = 95,
+ .maxYield = 3,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Sitrus,
+ .description2 = gBerryDescriptionPart2_Sitrus,
+ .stageDuration = 6,
+ .spicy = 10,
+ .dry = 10,
+ .sweet = 10,
+ .bitter = 10,
+ .sour = 10,
+ .smoothness = 20,
+ },
+ {
+ .name = NAME_FIGY_BERRY,
+ .firmness = BERRY_FIRMNESS_SOFT,
+ .size = 100,
+ .maxYield = 3,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Figy,
+ .description2 = gBerryDescriptionPart2_Figy,
+ .stageDuration = 6,
+ .spicy = 10,
+ .dry = 0,
+ .sweet = 0,
+ .bitter = 0,
+ .sour = 0,
+ .smoothness = 25,
+ },
+ {
+ .name = NAME_WIKI_BERRY,
+ .firmness = BERRY_FIRMNESS_HARD,
+ .size = 115,
+ .maxYield = 3,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Wiki,
+ .description2 = gBerryDescriptionPart2_Wiki,
+ .stageDuration = 6,
+ .spicy = 0,
+ .dry = 10,
+ .sweet = 0,
+ .bitter = 0,
+ .sour = 0,
+ .smoothness = 25,
+ },
+ {
+ .name = NAME_MAGO_BERRY,
+ .firmness = BERRY_FIRMNESS_HARD,
+ .size = 126,
+ .maxYield = 3,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Mago,
+ .description2 = gBerryDescriptionPart2_Mago,
+ .stageDuration = 6,
+ .spicy = 0,
+ .dry = 0,
+ .sweet = 10,
+ .bitter = 0,
+ .sour = 0,
+ .smoothness = 25,
+ },
+ {
+ .name = NAME_AGUAV_BERRY,
+ .firmness = BERRY_FIRMNESS_SUPER_HARD,
+ .size = 64,
+ .maxYield = 3,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Aguav,
+ .description2 = gBerryDescriptionPart2_Aguav,
+ .stageDuration = 6,
+ .spicy = 0,
+ .dry = 0,
+ .sweet = 0,
+ .bitter = 10,
+ .sour = 0,
+ .smoothness = 25,
+ },
+ {
+ .name = NAME_IAPAPA_BERRY,
+ .firmness = BERRY_FIRMNESS_SOFT,
+ .size = 223,
+ .maxYield = 3,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Iapapa,
+ .description2 = gBerryDescriptionPart2_Iapapa,
+ .stageDuration = 6,
+ .spicy = 0,
+ .dry = 0,
+ .sweet = 0,
+ .bitter = 0,
+ .sour = 10,
+ .smoothness = 25,
+ },
+ {
+ .name = NAME_RAZZ_BERRY,
+ .firmness = BERRY_FIRMNESS_VERY_HARD,
+ .size = 120,
+ .maxYield = 6,
+ .minYield = 3,
+ .description1 = gBerryDescriptionPart1_Razz,
+ .description2 = gBerryDescriptionPart2_Razz,
+ .stageDuration = 1,
+ .spicy = 10,
+ .dry = 10,
+ .sweet = 0,
+ .bitter = 0,
+ .sour = 0,
+ .smoothness = 20,
+ },
+ {
+ .name = NAME_BLUK_BERRY,
+ .firmness = BERRY_FIRMNESS_SOFT,
+ .size = 108,
+ .maxYield = 6,
+ .minYield = 3,
+ .description1 = gBerryDescriptionPart1_Bluk,
+ .description2 = gBerryDescriptionPart2_Bluk,
+ .stageDuration = 1,
+ .spicy = 0,
+ .dry = 10,
+ .sweet = 10,
+ .bitter = 0,
+ .sour = 0,
+ .smoothness = 20,
+ },
+ {
+ .name = NAME_NANAB_BERRY,
+ .firmness = BERRY_FIRMNESS_VERY_HARD,
+ .size = 77,
+ .maxYield = 6,
+ .minYield = 3,
+ .description1 = gBerryDescriptionPart1_Nanab,
+ .description2 = gBerryDescriptionPart2_Nanab,
+ .stageDuration = 1,
+ .spicy = 0,
+ .dry = 0,
+ .sweet = 10,
+ .bitter = 10,
+ .sour = 0,
+ .smoothness = 20,
+ },
+ {
+ .name = NAME_WEPEAR_BERRY,
+ .firmness = BERRY_FIRMNESS_SUPER_HARD,
+ .size = 74,
+ .maxYield = 6,
+ .minYield = 3,
+ .description1 = gBerryDescriptionPart1_Wepear,
+ .description2 = gBerryDescriptionPart2_Wepear,
+ .stageDuration = 1,
+ .spicy = 0,
+ .dry = 0,
+ .sweet = 0,
+ .bitter = 10,
+ .sour = 10,
+ .smoothness = 20,
+ },
+ {
+ .name = NAME_PINAP_BERRY,
+ .firmness = BERRY_FIRMNESS_HARD,
+ .size = 80,
+ .maxYield = 6,
+ .minYield = 3,
+ .description1 = gBerryDescriptionPart1_Pinap,
+ .description2 = gBerryDescriptionPart2_Pinap,
+ .stageDuration = 1,
+ .spicy = 10,
+ .dry = 0,
+ .sweet = 0,
+ .bitter = 0,
+ .sour = 10,
+ .smoothness = 20,
+ },
+ {
+ .name = NAME_POMEG_BERRY,
+ .firmness = BERRY_FIRMNESS_VERY_HARD,
+ .size = 135,
+ .maxYield = 6,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Pomeg,
+ .description2 = gBerryDescriptionPart2_Pomeg,
+ .stageDuration = 3,
+ .spicy = 10,
+ .dry = 0,
+ .sweet = 10,
+ .bitter = 10,
+ .sour = 0,
+ .smoothness = 20,
+ },
+ {
+ .name = NAME_KELPSY_BERRY,
+ .firmness = BERRY_FIRMNESS_HARD,
+ .size = 150,
+ .maxYield = 6,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Kelpsy,
+ .description2 = gBerryDescriptionPart2_Kelpsy,
+ .stageDuration = 3,
+ .spicy = 0,
+ .dry = 10,
+ .sweet = 0,
+ .bitter = 10,
+ .sour = 10,
+ .smoothness = 20,
+ },
+ {
+ .name = NAME_QUALOT_BERRY,
+ .firmness = BERRY_FIRMNESS_HARD,
+ .size = 110,
+ .maxYield = 6,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Qualot,
+ .description2 = gBerryDescriptionPart2_Qualot,
+ .stageDuration = 3,
+ .spicy = 10,
+ .dry = 0,
+ .sweet = 10,
+ .bitter = 0,
+ .sour = 10,
+ .smoothness = 20,
+ },
+ {
+ .name = NAME_HONDEW_BERRY,
+ .firmness = BERRY_FIRMNESS_HARD,
+ .size = 162,
+ .maxYield = 6,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Hondew,
+ .description2 = gBerryDescriptionPart2_Hondew,
+ .stageDuration = 3,
+ .spicy = 10,
+ .dry = 10,
+ .sweet = 0,
+ .bitter = 10,
+ .sour = 0,
+ .smoothness = 20,
+ },
+ {
+ .name = NAME_GREPA_BERRY,
+ .firmness = BERRY_FIRMNESS_SOFT,
+ .size = 149,
+ .maxYield = 6,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Grepa,
+ .description2 = gBerryDescriptionPart2_Grepa,
+ .stageDuration = 3,
+ .spicy = 0,
+ .dry = 10,
+ .sweet = 10,
+ .bitter = 0,
+ .sour = 10,
+ .smoothness = 20,
+ },
+ {
+ .name = NAME_TAMATO_BERRY,
+ .firmness = BERRY_FIRMNESS_SOFT,
+ .size = 200,
+ .maxYield = 4,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Tamato,
+ .description2 = gBerryDescriptionPart2_Tamato,
+ .stageDuration = 6,
+ .spicy = 20,
+ .dry = 10,
+ .sweet = 0,
+ .bitter = 0,
+ .sour = 0,
+ .smoothness = 30,
+ },
+ {
+ .name = NAME_CORNN_BERRY,
+ .firmness = BERRY_FIRMNESS_HARD,
+ .size = 75,
+ .maxYield = 4,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Cornn,
+ .description2 = gBerryDescriptionPart2_Cornn,
+ .stageDuration = 6,
+ .spicy = 0,
+ .dry = 20,
+ .sweet = 10,
+ .bitter = 0,
+ .sour = 0,
+ .smoothness = 30,
+ },
+ {
+ .name = NAME_MAGOST_BERRY,
+ .firmness = BERRY_FIRMNESS_HARD,
+ .size = 140,
+ .maxYield = 4,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Magost,
+ .description2 = gBerryDescriptionPart2_Magost,
+ .stageDuration = 6,
+ .spicy = 0,
+ .dry = 0,
+ .sweet = 20,
+ .bitter = 10,
+ .sour = 0,
+ .smoothness = 30,
+ },
+ {
+ .name = NAME_RABUTA_BERRY,
+ .firmness = BERRY_FIRMNESS_SOFT,
+ .size = 226,
+ .maxYield = 4,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Rabuta,
+ .description2 = gBerryDescriptionPart2_Rabuta,
+ .stageDuration = 6,
+ .spicy = 0,
+ .dry = 0,
+ .sweet = 0,
+ .bitter = 20,
+ .sour = 10,
+ .smoothness = 30,
+ },
+ {
+ .name = NAME_NOMEL_BERRY,
+ .firmness = BERRY_FIRMNESS_SUPER_HARD,
+ .size = 285,
+ .maxYield = 4,
+ .minYield = 2,
+ .description1 = gBerryDescriptionPart1_Nomel,
+ .description2 = gBerryDescriptionPart2_Nomel,
+ .stageDuration = 6,
+ .spicy = 10,
+ .dry = 0,
+ .sweet = 0,
+ .bitter = 0,
+ .sour = 20,
+ .smoothness = 30,
+ },
+ {
+ .name = NAME_SPELON_BERRY,
+ .firmness = BERRY_FIRMNESS_SOFT,
+ .size = 133,
+ .maxYield = 2,
+ .minYield = 1,
+ .description1 = gBerryDescriptionPart1_Spelon,
+ .description2 = gBerryDescriptionPart2_Spelon,
+ .stageDuration = 18,
+ .spicy = 40,
+ .dry = 10,
+ .sweet = 0,
+ .bitter = 0,
+ .sour = 0,
+ .smoothness = 70,
+ },
+ {
+ .name = NAME_PAMTRE_BERRY,
+ .firmness = BERRY_FIRMNESS_VERY_SOFT,
+ .size = 244,
+ .maxYield = 2,
+ .minYield = 1,
+ .description1 = gBerryDescriptionPart1_Pamtre,
+ .description2 = gBerryDescriptionPart2_Pamtre,
+ .stageDuration = 18,
+ .spicy = 0,
+ .dry = 40,
+ .sweet = 10,
+ .bitter = 0,
+ .sour = 0,
+ .smoothness = 70,
+ },
+ {
+ .name = NAME_WATMEL_BERRY,
+ .firmness = BERRY_FIRMNESS_SOFT,
+ .size = 250,
+ .maxYield = 2,
+ .minYield = 1,
+ .description1 = gBerryDescriptionPart1_Watmel,
+ .description2 = gBerryDescriptionPart2_Watmel,
+ .stageDuration = 18,
+ .spicy = 0,
+ .dry = 0,
+ .sweet = 40,
+ .bitter = 10,
+ .sour = 0,
+ .smoothness = 70,
+ },
+ {
+ .name = NAME_DURIN_BERRY,
+ .firmness = BERRY_FIRMNESS_HARD,
+ .size = 280,
+ .maxYield = 2,
+ .minYield = 1,
+ .description1 = gBerryDescriptionPart1_Durin,
+ .description2 = gBerryDescriptionPart2_Durin,
+ .stageDuration = 18,
+ .spicy = 0,
+ .dry = 0,
+ .sweet = 0,
+ .bitter = 40,
+ .sour = 10,
+ .smoothness = 70,
+ },
+ {
+ .name = NAME_BELUE_BERRY,
+ .firmness = BERRY_FIRMNESS_VERY_SOFT,
+ .size = 300,
+ .maxYield = 2,
+ .minYield = 1,
+ .description1 = gBerryDescriptionPart1_Belue,
+ .description2 = gBerryDescriptionPart2_Belue,
+ .stageDuration = 18,
+ .spicy = 10,
+ .dry = 0,
+ .sweet = 0,
+ .bitter = 0,
+ .sour = 40,
+ .smoothness = 70,
+ },
+ {
+ .name = NAME_LIECHI_BERRY,
+ .firmness = BERRY_FIRMNESS_VERY_HARD,
+ .size = 111,
+ .maxYield = 2,
+ .minYield = 1,
+ .description1 = gBerryDescriptionPart1_Liechi,
+ .description2 = gBerryDescriptionPart2_Liechi,
+ .stageDuration = 24,
+ .spicy = 40,
+ .dry = 0,
+ .sweet = 40,
+ .bitter = 0,
+ .sour = 10,
+ .smoothness = 80,
+ },
+ {
+ .name = NAME_GANLON_BERRY,
+ .firmness = BERRY_FIRMNESS_VERY_HARD,
+ .size = 33,
+ .maxYield = 2,
+ .minYield = 1,
+ .description1 = gBerryDescriptionPart1_Ganlon,
+ .description2 = gBerryDescriptionPart2_Ganlon,
+ .stageDuration = 24,
+ .spicy = 0,
+ .dry = 40,
+ .sweet = 0,
+ .bitter = 40,
+ .sour = 0,
+ .smoothness = 80,
+ },
+ {
+ .name = NAME_SALAC_BERRY,
+ .firmness = BERRY_FIRMNESS_VERY_HARD,
+ .size = 95,
+ .maxYield = 2,
+ .minYield = 1,
+ .description1 = gBerryDescriptionPart1_Salac,
+ .description2 = gBerryDescriptionPart2_Salac,
+ .stageDuration = 24,
+ .spicy = 0,
+ .dry = 0,
+ .sweet = 40,
+ .bitter = 0,
+ .sour = 40,
+ .smoothness = 80,
+ },
+ {
+ .name = NAME_PETAYA_BERRY,
+ .firmness = BERRY_FIRMNESS_VERY_HARD,
+ .size = 237,
+ .maxYield = 2,
+ .minYield = 1,
+ .description1 = gBerryDescriptionPart1_Petaya,
+ .description2 = gBerryDescriptionPart2_Petaya,
+ .stageDuration = 24,
+ .spicy = 40,
+ .dry = 0,
+ .sweet = 0,
+ .bitter = 40,
+ .sour = 0,
+ .smoothness = 80,
+ },
+ {
+ .name = NAME_APICOT_BERRY,
+ .firmness = BERRY_FIRMNESS_HARD,
+ .size = 75,
+ .maxYield = 2,
+ .minYield = 1,
+ .description1 = gBerryDescriptionPart1_Apicot,
+ .description2 = gBerryDescriptionPart2_Apicot,
+ .stageDuration = 24,
+ .spicy = 0,
+ .dry = 40,
+ .sweet = 0,
+ .bitter = 0,
+ .sour = 40,
+ .smoothness = 80,
+ },
+ {
+ .name = NAME_LANSAT_BERRY,
+ .firmness = BERRY_FIRMNESS_SOFT,
+ .size = 97,
+ .maxYield = 2,
+ .minYield = 1,
+ .description1 = gBerryDescriptionPart1_Lansat,
+ .description2 = gBerryDescriptionPart2_Lansat,
+ .stageDuration = 24,
+ .spicy = 10,
+ .dry = 10,
+ .sweet = 10,
+ .bitter = 10,
+ .sour = 10,
+ .smoothness = 30,
+ },
+ {
+ .name = NAME_STARF_BERRY,
+ .firmness = BERRY_FIRMNESS_SUPER_HARD,
+ .size = 153,
+ .maxYield = 2,
+ .minYield = 1,
+ .description1 = gBerryDescriptionPart1_Starf,
+ .description2 = gBerryDescriptionPart2_Starf,
+ .stageDuration = 24,
+ .spicy = 10,
+ .dry = 10,
+ .sweet = 10,
+ .bitter = 10,
+ .sour = 10,
+ .smoothness = 30,
+ },
+ {
+ .name = NAME_ENIGMA_BERRY,
+ .firmness = BERRY_FIRMNESS_UNKNOWN,
+ .size = 0,
+ .maxYield = 2,
+ .minYield = 1,
+ .description1 = gBerryDescriptionPart1_Enigma,
+ .description2 = gBerryDescriptionPart2_Enigma,
+ .stageDuration = 24,
+ .spicy = 40,
+ .dry = 40,
+ .sweet = 40,
+ .bitter = 40,
+ .sour = 40,
+ .smoothness = 40,
+ },
+};
+
+const struct BerryTree gBlankBerryTree = {0};
+
+extern u8 S_BerryTree[];
+extern u16 gScriptLastTalked;
+extern u16 gSpecialVar_0x8004;
+extern u16 gSpecialVar_0x8005;
+extern u16 gSpecialVar_0x8006;
+
+// unused
+void ClearEnigmaBerries(void)
+{
+ CpuFill16(0, &gSaveBlock1.enigmaBerry, sizeof(gSaveBlock1.enigmaBerry));
+}
+
+void SetEnigmaBerry(u8 *src)
+{
+ u32 i;
+ u8 *dest = (u8*)&gSaveBlock1.enigmaBerry;
+
+ for (i = 0; i < sizeof(gSaveBlock1.enigmaBerry); i++)
+ dest[i] = src[i];
+
+ gSaveBlock1.enigmaBerry.berry.description1 = gSaveBlock1.enigmaBerry.description1;
+ gSaveBlock1.enigmaBerry.berry.description2 = gSaveBlock1.enigmaBerry.description2;
+}
+
+u32 GetEnigmaBerryChecksum(struct EnigmaBerry *enigmaBerry)
+{
+ const u8 *description1;
+ const u8 *description2;
+ u32 i;
+ u32 checksum;
+ u8 *dest;
+
+ description1 = gSaveBlock1.enigmaBerry.berry.description1;
+ description2 = gSaveBlock1.enigmaBerry.berry.description2;
+ gSaveBlock1.enigmaBerry.berry.description1 = 0;
+ gSaveBlock1.enigmaBerry.berry.description2 = 0;
+
+ dest = (u8*)enigmaBerry;
+ checksum = 0;
+ for (i = 0; i < ((u32)&gSaveBlock1.enigmaBerry.checksum - (u32)&gSaveBlock1.enigmaBerry); i++)
+ {
+ checksum += dest[i];
+ }
+
+ gSaveBlock1.enigmaBerry.berry.description1 = description1;
+ gSaveBlock1.enigmaBerry.berry.description2 = description2;
+
+ return checksum;
+}
+
+bool32 IsEnigmaBerryValid(void)
+{
+ if (!gSaveBlock1.enigmaBerry.berry.stageDuration)
+ return FALSE;
+ if (!gSaveBlock1.enigmaBerry.berry.maxYield)
+ return FALSE;
+ if (GetEnigmaBerryChecksum(&gSaveBlock1.enigmaBerry) != gSaveBlock1.enigmaBerry.checksum)
+ return FALSE;
+ return TRUE;
+}
+
+const struct Berry *GetBerryInfo(u8 berry)
+{
+ if (berry == 0x2B && IsEnigmaBerryValid())
+ return &gSaveBlock1.enigmaBerry.berry;
+ else
+ {
+ if (berry == 0 || berry > 0x2B)
+ berry = 1;
+ return &gBerries[berry - 1];
+ }
+}
+
+struct BerryTree *GetBerryTreeInfo(u8 id)
+{
+ return &gSaveBlock1.berryTrees[id];
+}
+
+bool32 FieldObjectInteractionWaterBerryTree(void)
+{
+ struct BerryTree *tree = GetBerryTreeInfo(FieldObjectGetBerryTreeId(gSelectedMapObject));
+
+ switch (tree->stage)
+ {
+ case 1:
+ tree->watered1 = TRUE;
+ break;
+ case 2:
+ tree->watered2 = TRUE;
+ break;
+ case 3:
+ tree->watered3 = TRUE;
+ break;
+ case 4:
+ tree->watered4 = TRUE;
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool8 IsPlayerFacingPlantedBerryTree(void)
+{
+ if (GetFieldObjectScriptPointerForComparison() == S_BerryTree
+ && GetStageByBerryTreeId(FieldObjectGetBerryTreeId(gSelectedMapObject)) == 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 TryToWaterBerryTree(void)
+{
+ if (GetFieldObjectScriptPointerForComparison() != S_BerryTree)
+ return FALSE;
+ else
+ return FieldObjectInteractionWaterBerryTree();
+}
+
+void ClearBerryTrees(void)
+{
+ int i;
+ struct SaveBlock1 *saveBlock1 = &gSaveBlock1;
+ struct BerryTree berryTree = gBlankBerryTree;
+
+ for (i = 0; i < (u8)ARRAY_COUNT(saveBlock1->berryTrees); i++) // casting to u8 fixes a mismatched signed compare. what
+ saveBlock1->berryTrees[i] = berryTree;
+}
+
+bool32 BerryTreeGrow(struct BerryTree *tree)
+{
+ if (tree->growthSparkle)
+ return FALSE;
+ switch (tree->stage)
+ {
+ case 0:
+ return FALSE;
+ case 4:
+ tree->berryYield = CalcBerryYield(tree);
+ case 1:
+ case 2:
+ case 3:
+ tree->stage++;
+ break;
+ case 5:
+ tree->watered1 = 0;
+ tree->watered2 = 0;
+ tree->watered3 = 0;
+ tree->watered4 = 0;
+ tree->berryYield = 0;
+ tree->stage = 2;
+ if (++tree->regrowthCount == 10)
+ *tree = gBlankBerryTree;
+ break;
+ }
+ return TRUE;
+}
+
+void BerryTreeTimeUpdate(s32 minutes)
+{
+ int i;
+ struct BerryTree *tree;
+
+ for (i = 0; i < (u8)ARRAY_COUNT(gSaveBlock1.berryTrees); i++)
+ {
+ tree = &gSaveBlock1.berryTrees[i];
+
+ if (tree->berry && tree->stage && !tree->growthSparkle)
+ {
+ if (minutes >= GetStageDurationByBerryType(tree->berry) * 71)
+ {
+ *tree = gBlankBerryTree;
+ }
+ else
+ {
+ s32 time = minutes;
+
+ while (time != 0)
+ {
+ if (tree->minutesUntilNextStage > time)
+ {
+ tree->minutesUntilNextStage -= time;
+ break;
+ }
+ time -= tree->minutesUntilNextStage;
+ tree->minutesUntilNextStage = GetStageDurationByBerryType(tree->berry);
+ if (!BerryTreeGrow(tree))
+ break;
+ if (tree->stage == 5)
+ tree->minutesUntilNextStage *= 4;
+ }
+ }
+ }
+ }
+}
+
+void PlantBerryTree(u8 id, u8 berry, u8 stage, bool8 sparkle)
+{
+ struct BerryTree *tree = GetBerryTreeInfo(id);
+
+ *tree = gBlankBerryTree;
+ tree->berry = berry;
+ tree->minutesUntilNextStage = GetStageDurationByBerryType(berry);
+ tree->stage = stage;
+ if (stage == 5)
+ {
+ tree->berryYield = CalcBerryYield(tree);
+ tree->minutesUntilNextStage *= 4;
+ }
+ if (!sparkle)
+ {
+ tree->growthSparkle = TRUE;
+ }
+}
+
+void RemoveBerryTree(u8 id)
+{
+ gSaveBlock1.berryTrees[id] = gBlankBerryTree;
+}
+
+u8 GetBerryTypeByBerryTreeId(u8 id)
+{
+ return gSaveBlock1.berryTrees[id].berry;
+}
+
+u8 GetStageByBerryTreeId(u8 id)
+{
+ return gSaveBlock1.berryTrees[id].stage;
+}
+
+u8 ItemIdToBerryType(u16 item)
+{
+ u16 berry = item - FIRST_BERRY;
+
+ if (berry > LAST_BERRY - FIRST_BERRY)
+ return 1;
+ else
+ return item - FIRST_BERRY + 1;
+}
+
+u16 BerryTypeToItemId(u16 berry)
+{
+ u16 item = berry - 1;
+
+ if (item > LAST_BERRY - FIRST_BERRY)
+ return FIRST_BERRY;
+ else
+ return berry + FIRST_BERRY - 1;
+}
+
+void GetBerryNameByBerryType(u8 berry, u8 *string)
+{
+ memcpy(string, GetBerryInfo(berry)->name, BERRY_NAME_LENGTH);
+ string[BERRY_NAME_LENGTH] = EOS;
+}
+
+void ResetBerryTreeSparkleFlag(u8 id)
+{
+ GetBerryTreeInfo(id)->growthSparkle = 0;
+}
+
+u8 BerryTreeGetNumStagesWatered(struct BerryTree *tree)
+{
+ u8 count = 0;
+
+ if (tree->watered1)
+ count++;
+ if (tree->watered2)
+ count++;
+ if (tree->watered3)
+ count++;
+ if (tree->watered4)
+ count++;
+ return count;
+}
+
+u8 GetNumStagesWateredByBerryTreeId(u8 id)
+{
+ return BerryTreeGetNumStagesWatered(GetBerryTreeInfo(id));
+}
+
+u8 CalcBerryYieldInternal(u16 max, u16 min, u8 water)
+{
+ u32 randMin;
+ u32 randMax;
+ u32 rand;
+ u32 extraYield;
+
+ if (water == 0)
+ return min;
+ else
+ {
+ randMin = (max - min) * (water - 1);
+ randMax = (max - min) * (water);
+ rand = randMin + Random() % (randMax - randMin + 1);
+
+ if ((rand & 3) > 1)
+ extraYield = rand / 4 + 1;
+ else
+ extraYield = rand / 4;
+ return extraYield + min;
+ }
+}
+
+u8 CalcBerryYield(struct BerryTree *tree)
+{
+ const struct Berry *berry = GetBerryInfo(tree->berry);
+ u8 min = berry->minYield;
+ u8 max = berry->maxYield;
+
+ return CalcBerryYieldInternal(max, min, BerryTreeGetNumStagesWatered(tree));
+}
+
+u8 GetBerryCountByBerryTreeId(u8 id)
+{
+ return gSaveBlock1.berryTrees[id].berryYield;
+}
+
+u16 GetStageDurationByBerryType(u8 berry)
+{
+ return GetBerryInfo(berry)->stageDuration * 60;
+}
+
+void FieldObjectInteractionGetBerryTreeData(void)
+{
+ u8 id;
+ u8 berry;
+ u8 unk;
+ u8 group;
+ u8 num;
+
+ id = FieldObjectGetBerryTreeId(gSelectedMapObject);
+ berry = GetBerryTypeByBerryTreeId(id);
+ ResetBerryTreeSparkleFlag(id);
+ unk = gScriptLastTalked;
+ num = gSaveBlock1.location.mapNum;
+ group = gSaveBlock1.location.mapGroup;
+ if (sub_8060234(unk, num, group))
+ gSpecialVar_0x8004 = 0xFF;
+ else
+ gSpecialVar_0x8004 = GetStageByBerryTreeId(id);
+ gSpecialVar_0x8005 = GetNumStagesWateredByBerryTreeId(id);
+ gSpecialVar_0x8006 = GetBerryCountByBerryTreeId(id);
+ GetBerryNameByBerryType(berry, gStringVar1);
+}
+
+void sub_80B4EE4(void)
+{
+ SetMainCallback2(sub_80A68CC);
+}
+
+void FieldObjectInteractionPlantBerryTree(void)
+{
+ u8 berry = ItemIdToBerryType(gScriptItemId);
+
+ PlantBerryTree(FieldObjectGetBerryTreeId(gSelectedMapObject), berry, 1, TRUE);
+ FieldObjectInteractionGetBerryTreeData();
+}
+
+void FieldObjectInteractionPickBerryTree(void)
+{
+ u8 id = FieldObjectGetBerryTreeId(gSelectedMapObject);
+ u8 berry = GetBerryTypeByBerryTreeId(id);
+
+ gSpecialVar_0x8004 = AddBagItem(BerryTypeToItemId(berry), GetBerryCountByBerryTreeId(id));
+}
+
+void FieldObjectInteractionRemoveBerryTree(void)
+{
+ RemoveBerryTree(FieldObjectGetBerryTreeId(gSelectedMapObject));
+ sub_8060288(gScriptLastTalked, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup);
+}
+
+u8 PlayerHasBerries(void)
+{
+ return IsBagPocketNonEmpty(BAG_BERRIES);
+}
+
+void ResetBerryTreeSparkleFlags(void)
+{
+ s16 cam_left;
+ s16 cam_top;
+ s16 left;
+ s16 top;
+ s16 right;
+ s16 bottom;
+ int i;
+
+ GetCameraCoords(&cam_left, &cam_top);
+ left = cam_left;
+ top = cam_top + 3;
+ right = cam_left + 14;
+ bottom = top + 8;
+ for (i = 0; i < (u8)ARRAY_COUNT(gSaveBlock1.mapObjects); i++)
+ {
+ if (gMapObjects[i].active && gMapObjects[i].animPattern == 12)
+ {
+ cam_left = gMapObjects[i].coords2.x;
+ cam_top = gMapObjects[i].coords2.y;
+ if (left <= cam_left && cam_left <= right && top <= cam_top && cam_top <= bottom)
+ ResetBerryTreeSparkleFlag(gMapObjects[i].trainerRange_berryTreeId);
+ }
+ }
+}
diff --git a/src/field/berry_tag_screen.c b/src/field/berry_tag_screen.c
new file mode 100644
index 000000000..1413a02ca
--- /dev/null
+++ b/src/field/berry_tag_screen.c
@@ -0,0 +1,455 @@
+#include "global.h"
+#include "berry_tag_screen.h"
+#include "berry.h"
+#include "decompress.h"
+#include "field_map_obj.h"
+#include "item_menu.h"
+#include "items.h"
+#include "item_use.h"
+#include "main.h"
+#include "menu.h"
+#include "menu_helpers.h"
+#include "palette.h"
+#include "overworld.h"
+#include "songs.h"
+#include "sound.h"
+#include "sprite.h"
+#include "string_util.h"
+#include "strings.h"
+#include "task.h"
+#include "text.h"
+
+#define OFFSET_7B (123)
+#define FIRST_BERRY ITEM_CHERI_BERRY
+
+struct Struct2000000
+{
+ /*0x00*/ u8 filler_0[0x1FFFF];
+ /*0x1FFFF*/ u8 var_1FFFF;
+};
+
+extern struct Struct2000000 unk_2000000;
+extern u16 gUnknown_030041B4;
+
+static EWRAM_DATA u8 gUnknown_0203932C = 0;
+static EWRAM_DATA s16 gUnknown_0203932E[5] = {0};
+
+extern const struct CompressedSpriteSheet gUnknown_083C1F74;
+extern const struct CompressedSpritePalette gUnknown_083C1F7C;
+
+extern u8 gBerryCheck_Gfx[];
+extern u8 gBerryCheck_Pal[];
+extern u8 gUnknown_08E788E4[];
+extern u8 gUnknown_08E78A84[];
+
+static const u8 *const gUnknown_0841192C[] =
+{
+ ContestStatsText_VerySoft,
+ ContestStatsText_Soft,
+ ContestStatsText_Hard,
+ ContestStatsText_VeryHard,
+ ContestStatsText_SuperHard,
+};
+
+static void sub_8146014(void);
+static void sub_814602C(void);
+static bool8 sub_8146058(void);
+static void sub_8146288(void);
+static bool8 sub_81462B8(void);
+static void sub_814640C(u8 taskId);
+static void sub_8146440(u8 taskId);
+static void sub_8146480(u8 taskid);
+static void sub_81464E4(void);
+static void sub_8146600(u8 berry);
+static void sub_81466A0(void);
+static void sub_81466E8(u8 taskId, s8 direction);
+static void sub_8146798(u8 berry);
+static void sub_8146810(s8 berry);
+static void sub_81468BC(void);
+
+static void sub_8146014(void)
+{
+ AnimateSprites();
+ BuildOamBuffer();
+ RunTasks();
+ UpdatePaletteFade();
+}
+
+static void sub_814602C(void)
+{
+ REG_BG0VOFS = gUnknown_030041B4;
+ REG_BG1VOFS = gUnknown_030041B4;
+
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+static bool8 sub_8146058(void)
+{
+ u8 berry;
+ u16 backup;
+
+ switch (gMain.state)
+ {
+ case 0:
+ sub_80F9438();
+ sub_80F9368();
+ sub_8146288();
+ REG_BLDCNT = 0;
+ gMain.state += 1;
+ break;
+ case 1:
+ ResetPaletteFade();
+ gPaletteFade.bufferTransferDisabled = 1;
+ gMain.state += 1;
+ break;
+ case 2:
+ ResetSpriteData();
+ gMain.state += 1;
+ break;
+ case 3:
+ SetUpWindowConfig(&gWindowConfig_81E6E18);
+ gMain.state += 1;
+ break;
+ case 4:
+ MultistepInitMenuWindowBegin(&gWindowConfig_81E6E18);
+ gMain.state += 1;
+ break;
+ case 5:
+ if (!MultistepInitMenuWindowContinue())
+ break;
+ unk_2000000.var_1FFFF = 0;
+ gMain.state += 1;
+ break;
+ case 6:
+ if (!sub_81462B8())
+ break;
+ unk_2000000.var_1FFFF = 0;
+ gMain.state += 1;
+ break;
+ case 7:
+ sub_81464E4();
+ gMain.state += 1;
+ break;
+ case 8:
+ berry = gScriptItemId + OFFSET_7B;
+ gUnknown_0203932C = CreateBerrySprite(berry, 56, 64);
+ gMain.state += 1;
+ break;
+ case 9:
+ sub_8146600(gScriptItemId + OFFSET_7B);
+ gMain.state += 1;
+ break;
+ case 10:
+ backup = REG_IME;
+ REG_IME = 0;
+ REG_IE |= INTR_FLAG_VBLANK;
+ REG_IME = backup;
+ REG_DISPSTAT |= DISPSTAT_VBLANK_INTR;
+ SetVBlankCallback(sub_814602C);
+ REG_DISPCNT = DISPCNT_MODE_0 | DISPCNT_OBJ_ON | DISPCNT_BG_ALL_ON | DISPCNT_OBJ_1D_MAP;
+ gMain.state += 1;
+ break;
+ case 11:
+ if (sub_8055870() == TRUE)
+ break;
+ gMain.state += 1;
+ break;
+ case 12:
+ BeginNormalPaletteFade(-1, 0, 0x10, 0, 0);
+ gPaletteFade.bufferTransferDisabled = 0;
+ SetMainCallback2(sub_8146014);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void BerryTagScreen_814625C(u8 taskId)
+{
+ do
+ {
+ if (sub_8146058() == TRUE)
+ {
+ CreateTask(sub_8146480, 0);
+ return;
+ }
+ } while (sub_80F9344() != TRUE);
+}
+
+static void sub_8146288(void)
+{
+ REG_BG1CNT = BGCNT_PRIORITY(2) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(5) | BGCNT_16COLOR | BGCNT_TXT256x256;
+ REG_BG2CNT = BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(6) | BGCNT_16COLOR | BGCNT_TXT256x256;
+ REG_BG3CNT = BGCNT_PRIORITY(3) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(7) | BGCNT_16COLOR | BGCNT_TXT256x256;
+ gUnknown_030041B4 = 0;
+}
+
+bool8 sub_81462B8(void)
+{
+ u16 i;
+ void *addr;
+
+ switch (unk_2000000.var_1FFFF)
+ {
+ case 0:
+ LZDecompressVram(gBerryCheck_Gfx, (void *)VRAM);
+ unk_2000000.var_1FFFF += 1;
+ break;
+ case 1:
+ LZDecompressVram(gUnknown_08E788E4, (void *)VRAM + 0x2800);
+ unk_2000000.var_1FFFF += 1;
+ break;
+ case 2:
+ LZDecompressVram(gUnknown_08E78A84, (void *)VRAM + 0x3000);
+ unk_2000000.var_1FFFF += 1;
+ break;
+ case 3:
+ for (i = 0; i < 0x400; i++)
+ {
+ if (gSaveBlock2.playerGender == MALE)
+ gBGTilemapBuffers[2][i] = 0x4042;
+ else
+ gBGTilemapBuffers[2][i] = 0x5042;
+ }
+ addr = (void *)(VRAM + 0x3800);
+ DmaCopy16(3, gBGTilemapBuffers[2], addr, 0x800);
+ unk_2000000.var_1FFFF += 1;
+ break;
+ case 4:
+ LoadCompressedPalette(gBerryCheck_Pal, 0, 96 * 2);
+ unk_2000000.var_1FFFF += 1;
+ break;
+ case 5:
+ LoadCompressedObjectPic(&gUnknown_083C1F74);
+ unk_2000000.var_1FFFF += 1;
+ break;
+ case 6:
+ LoadCompressedObjectPalette(&gUnknown_083C1F7C);
+ unk_2000000.var_1FFFF = 0;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void sub_814640C(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ SetMainCallback2(sub_80A5B40);
+ sub_80A7DD4();
+ gpu_pal_allocator_reset__manage_upper_four();
+ DestroyTask(taskId);
+ }
+}
+
+static void sub_8146440(u8 taskId)
+{
+ PlaySE(SE_SELECT);
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ gTasks[taskId].func = sub_814640C;
+}
+
+static void sub_8146480(u8 taskid)
+{
+ if (!gPaletteFade.active)
+ {
+ if ((gMain.newAndRepeatedKeys & (DPAD_RIGHT | DPAD_LEFT | DPAD_UP | DPAD_DOWN)) == DPAD_UP)
+ sub_81466E8(taskid, -1);
+ if ((gMain.newAndRepeatedKeys & (DPAD_RIGHT | DPAD_LEFT | DPAD_UP | DPAD_DOWN)) == DPAD_DOWN)
+ sub_81466E8(taskid, 1);
+ if (gMain.newKeys & A_BUTTON || gMain.newKeys & B_BUTTON)
+ sub_8146440(taskid);
+ }
+}
+
+static void sub_81464E4(void)
+{
+ const struct Berry *berryInfo;
+#ifdef UNITS_IMPERIAL
+ u32 size;
+ s32 sizeMajor;
+ s32 sizeMinor;
+#endif
+#if GERMAN
+ u8 buffer[16];
+#endif
+
+ berryInfo = GetBerryInfo(gScriptItemId + OFFSET_7B + 1);
+
+ ConvertIntToDecimalStringN(gStringVar1, gScriptItemId - FIRST_BERRY + 1, STR_CONV_MODE_LEADING_ZEROS, 2);
+ MenuPrint(gStringVar1, 12, 4);
+
+#if ENGLISH
+ MenuPrint(berryInfo->name, 14, 4);
+#elif GERMAN
+ StringCopy(buffer, berryInfo->name);
+ StringAppend(buffer, gOtherText_Berry2);
+ MenuPrint(buffer, 14, 4);
+#endif
+
+ MenuPrint(berryInfo->description1, 4, 14);
+ MenuPrint(berryInfo->description2, 4, 16);
+
+#ifdef UNITS_IMPERIAL
+ size = (berryInfo->size * 1000) / 254;
+ if (size % 10 >= 5)
+ size += 10;
+ sizeMinor = (size % 100) / 10;
+ sizeMajor = size / 100;
+#endif
+
+ MenuPrint(gOtherText_Size, 11, 7);
+ if (berryInfo->size != 0)
+ {
+#ifdef UNITS_IMPERIAL
+ ConvertIntToDecimalStringN(gStringVar1, sizeMajor, STR_CONV_MODE_LEFT_ALIGN, 2);
+ ConvertIntToDecimalStringN(gStringVar2, sizeMinor, STR_CONV_MODE_LEFT_ALIGN, 2);
+#else
+ ConvertIntToDecimalStringN(gStringVar1, berryInfo->size / 10, STR_CONV_MODE_LEFT_ALIGN, 2);
+ ConvertIntToDecimalStringN(gStringVar2, berryInfo->size % 10, STR_CONV_MODE_LEFT_ALIGN, 2);
+#endif
+ MenuPrint(gContestStatsText_Unknown1, 16, 7);
+ }
+ else
+ {
+ MenuPrint(gOtherText_ThreeQuestions2, 16, 7);
+ }
+
+ MenuPrint(gOtherText_Firm, 11, 9);
+ if (berryInfo->firmness != 0)
+ MenuPrint(gUnknown_0841192C[berryInfo->firmness - 1], 16, 9);
+ else
+ MenuPrint(gOtherText_ThreeQuestions2, 16, 9);
+}
+
+static void sub_8146600(u8 berry)
+{
+ const struct Berry *berryInfo;
+ u16 i;
+
+ berryInfo = GetBerryInfo(berry + 1);
+ for (i = 0; i < 5; i++)
+ gUnknown_0203932E[i] = (u16)gUnknown_0203932E[i] | 0xFFFF;
+
+ // argument is the center of the circle
+ if (berryInfo->spicy)
+ gUnknown_0203932E[0] = sub_80A7E5C(48);
+ if (berryInfo->dry)
+ gUnknown_0203932E[1] = sub_80A7E5C(88);
+ if (berryInfo->sweet)
+ gUnknown_0203932E[2] = sub_80A7E5C(128);
+ if (berryInfo->bitter)
+ gUnknown_0203932E[3] = sub_80A7E5C(168);
+ if (berryInfo->sour)
+ gUnknown_0203932E[4] = sub_80A7E5C(208);
+}
+
+static void sub_81466A0(void)
+{
+ u16 i;
+
+ for (i = 0; i < 5; i++)
+ {
+ if (gUnknown_0203932E[i] != -1)
+ {
+ DestroySprite(&gSprites[gUnknown_0203932E[i]]);
+ gUnknown_0203932E[i] = -1;
+ }
+ }
+}
+
+static void sub_81466E8(u8 taskId, s8 direction)
+{
+ u8 berryPocket = 3;
+ s16 *data = gTasks[taskId].data;
+
+ if (gBagPocketScrollStates[berryPocket].scrollTop + gBagPocketScrollStates[berryPocket].cursorPos == 0
+ && direction < 0)
+ return;
+ if (gBagPocketScrollStates[berryPocket].scrollTop + gBagPocketScrollStates[berryPocket].cursorPos + 1 == gBagPocketScrollStates[berryPocket].numSlots
+ && direction > 0)
+ return;
+
+ PlaySE(SE_SELECT);
+ if (gBagPocketScrollStates[berryPocket].scrollTop + gBagPocketScrollStates[berryPocket].cursorPos + direction < 0)
+ data[1] = -(gBagPocketScrollStates[berryPocket].scrollTop + gBagPocketScrollStates[berryPocket].cursorPos);
+ else if (gBagPocketScrollStates[berryPocket].scrollTop + gBagPocketScrollStates[berryPocket].cursorPos + direction >= gBagPocketScrollStates[berryPocket].numSlots)
+ data[1] = gBagPocketScrollStates[berryPocket].numSlots - gBagPocketScrollStates[berryPocket].scrollTop - gBagPocketScrollStates[berryPocket].cursorPos - 1;
+ else
+ data[1] = direction;
+
+ gTasks[taskId].func = sub_8146798;
+
+ if (direction < 0)
+ data[0] = -16;
+ else
+ data[0] = 16;
+
+}
+
+static void sub_8146798(u8 taskId)
+{
+ s16 *taskData = gTasks[taskId].data;
+
+ gUnknown_030041B4 = (gUnknown_030041B4 + taskData[0]) & 0xFF;
+ if ((taskData[0] > 0 && gUnknown_030041B4 == 144)
+ || (taskData[0] < 0 && gUnknown_030041B4 == 112))
+ {
+ sub_8146810(gTasks[taskId].data[1]);
+ sub_81468BC();
+ }
+ if (gUnknown_030041B4 == 0)
+ {
+ gTasks[taskId].data[0] = gUnknown_030041B4;
+ gTasks[taskId].data[1] = gUnknown_030041B4;
+ gTasks[taskId].func = sub_8146480;
+ }
+}
+
+static void sub_8146810(s8 berry)
+{
+ u8 berryPocket = 3;
+
+ if (berry > 0)
+ {
+ if (gBagPocketScrollStates[berryPocket].cursorPos + berry > 7)
+ {
+ gBagPocketScrollStates[berryPocket].scrollTop += gBagPocketScrollStates[berryPocket].cursorPos - 7 + berry;
+ gBagPocketScrollStates[berryPocket].cursorPos = 7;
+ }
+ else
+ {
+ gBagPocketScrollStates[berryPocket].cursorPos += berry;
+ }
+ }
+ else
+ {
+ if (gBagPocketScrollStates[berryPocket].cursorPos + berry < 0)
+ {
+ gBagPocketScrollStates[berryPocket].scrollTop += gBagPocketScrollStates[berryPocket].cursorPos + berry;
+ gBagPocketScrollStates[berryPocket].cursorPos = 0;
+ }
+ else
+ {
+ gBagPocketScrollStates[berryPocket].cursorPos += berry;
+ }
+ }
+ gScriptItemId = gCurrentBagPocketItemSlots[gBagPocketScrollStates[berryPocket].scrollTop + gBagPocketScrollStates[berryPocket].cursorPos].itemId;
+ DestroySprite(&gSprites[gUnknown_0203932C]);
+ sub_81466A0();
+ sub_80A7DD4();
+}
+
+static void sub_81468BC(void)
+{
+ MenuZeroFillWindowRect(0, 4, 29, 19);
+ sub_81464E4();
+
+ // center of berry sprite
+ gUnknown_0203932C = CreateBerrySprite(gScriptItemId + OFFSET_7B, 56, 64);
+
+ sub_8146600(gScriptItemId + OFFSET_7B);
+}
diff --git a/src/field/bike.c b/src/field/bike.c
new file mode 100644
index 000000000..8df901b40
--- /dev/null
+++ b/src/field/bike.c
@@ -0,0 +1,1011 @@
+#include "global.h"
+#include "bike.h"
+#include "field_map_obj.h"
+#include "field_player_avatar.h"
+#include "fieldmap.h"
+#include "flags.h"
+#include "global.fieldmap.h"
+#include "metatile_behavior.h"
+#include "overworld.h"
+#include "songs.h"
+#include "sound.h"
+
+extern u8 gUnknown_02039250;
+extern u8 gUnknown_02039251;
+extern u8 gUnknown_0202E854;
+
+static void MovePlayerOnMachBike(u8, u16, u16);
+static u8 GetMachBikeTransition(u8 *);
+static void MachBikeTransition_FaceDirection(u8);
+static void MachBikeTransition_80E517C(u8);
+static void MachBikeTransition_80E51C4(u8);
+static void MachBikeTransition_80E5270(u8);
+static void MovePlayerOnAcroBike(u8, u16, u16);
+static u8 CheckMovementInputAcroBike(u8 *, u16, u16);
+static u8 AcroBikeHandleInputNormal(u8 *, u16, u16);
+static u8 AcroBikeHandleInputTurning(u8 *, u16, u16);
+static u8 AcroBikeHandleInputWheelieStanding(u8 *, u16, u16);
+static u8 AcroBikeHandleInputBunnyHop(u8 *, u16, u16);
+static u8 AcroBikeHandleInputWheelieMoving(u8 *, u16, u16);
+static u8 AcroBikeHandleInputState5(u8 *, u16, u16);
+static u8 AcroBikeHandleInputState6(u8 *, u16, u16);
+static void AcroBikeTransition_FaceDirection(u8);
+static void AcroBikeTransition_80E5708(u8);
+static void AcroBikeTransition_80E5744(u8);
+static void AcroBikeTransition_NormalToWheelie(u8);
+static void AcroBikeTransition_80E57F8(u8);
+static void AcroBikeTransition_80E5834(u8);
+static void AcroBikeTransition_80E5870(u8);
+static void AcroBikeTransition_80E58AC(u8);
+static void AcroBikeTransition_80E5920(u8);
+static void AcroBikeTransition_80E5990(u8);
+static void AcroBikeTransition_80E59A0(u8);
+static void AcroBikeTransition_80E5A30(u8);
+static void AcroBikeTransition_80E5AC0(u8);
+static void sub_80E5B60(u16, u16);
+static u8 sub_80E5C2C(void);
+static void sub_80E5C7C(u8);
+static void sub_80E5CB8(u8);
+static u8 sub_80E5CF4(u16);
+static u8 get_some_collision(u8);
+static u8 sub_80E5DA0(struct MapObject *, s16, s16, u8, u8);
+static bool8 IsRunningDisallowedByMetatile(u8);
+static void sub_80E5E4C();
+static u8 CanBikeFaceDirOnMetatile(u8, u8);
+static bool8 sub_80E5EC0(u8, u8);
+static void sub_80E6024(void);
+
+static void (*const sMachBikeTransitions[])(u8) =
+{
+ MachBikeTransition_FaceDirection,
+ MachBikeTransition_80E517C,
+ MachBikeTransition_80E51C4,
+ MachBikeTransition_80E5270,
+};
+
+static void (*const gUnknown_083DB5A4[])(u8) =
+{
+ PlayerGoSpeed0,
+ sub_80593C4,
+ sub_80593F4,
+};
+
+static void (*const sAcroBikeTransitions[])(u8) =
+{
+ AcroBikeTransition_FaceDirection,
+ AcroBikeTransition_80E5708,
+ AcroBikeTransition_80E5744,
+ AcroBikeTransition_NormalToWheelie,
+ AcroBikeTransition_80E57F8,
+ AcroBikeTransition_80E5834,
+ AcroBikeTransition_80E5870,
+ AcroBikeTransition_80E58AC,
+ AcroBikeTransition_80E5920,
+ AcroBikeTransition_80E5990,
+ AcroBikeTransition_80E59A0,
+ AcroBikeTransition_80E5A30,
+ AcroBikeTransition_80E5AC0,
+};
+
+static u8 (*const sAcroBikeInputHandlers[])(u8 *, u16, u16) =
+{
+ AcroBikeHandleInputNormal,
+ AcroBikeHandleInputTurning,
+ AcroBikeHandleInputWheelieStanding,
+ AcroBikeHandleInputBunnyHop,
+ AcroBikeHandleInputWheelieMoving,
+ AcroBikeHandleInputState5,
+ AcroBikeHandleInputState6,
+};
+
+const u16 gMachBikeSpeeds[] = {SPEED_NORMAL, SPEED_FAST, SPEED_FASTEST};
+static const u8 Unknown_3DB606[] = {4, 0};
+
+static const struct UnknownStruct1 gUnknown_083DB608[] =
+{
+ {1, 2, 15, 15, Unknown_3DB606, Unknown_3DB606, 1},
+ {2, 2, 15, 15, Unknown_3DB606, Unknown_3DB606, 2},
+ {3, 2, 15, 15, Unknown_3DB606, Unknown_3DB606, 3},
+ {4, 2, 15, 15, Unknown_3DB606, Unknown_3DB606, 4},
+};
+
+void MovePlayerOnBike(u8 direction, u16 newKeys, u16 heldKeys)
+{
+ if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_MACH_BIKE)
+ MovePlayerOnMachBike(direction, newKeys, heldKeys);
+ else
+ MovePlayerOnAcroBike(direction, newKeys, heldKeys);
+}
+
+static void MovePlayerOnMachBike(u8 direction, u16 newKeys, u16 heldKeys)
+{
+ sMachBikeTransitions[GetMachBikeTransition(&direction)](direction);
+}
+
+static u8 GetMachBikeTransition(u8 *ptr)
+{
+ u8 direction = player_get_direction_upper_nybble();
+
+ if (*ptr == 0)
+ {
+ *ptr = direction;
+ if (gPlayerAvatar.unkB == 0)
+ {
+ gPlayerAvatar.running2 = 0;
+ return 0;
+ }
+ gPlayerAvatar.running2 = 2;
+ return 3;
+ }
+
+ if (*ptr != direction && gPlayerAvatar.running2 != 2)
+ {
+ if (gPlayerAvatar.unkB != 0)
+ {
+ *ptr = direction;
+ gPlayerAvatar.running2 = 2;
+ return 3;
+ }
+ gPlayerAvatar.running2 = 1;
+ return 1;
+ }
+ else
+ {
+ gPlayerAvatar.running2 = 2;
+ return 2;
+ }
+}
+
+static void MachBikeTransition_FaceDirection(u8 direction)
+{
+ PlayerFaceDirection(direction);
+ sub_80E6024();
+}
+
+static void MachBikeTransition_80E517C(u8 direction)
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E))
+ {
+ PlayerTurnInPlace(direction);
+ sub_80E6024();
+ }
+ else
+ {
+ MachBikeTransition_FaceDirection(playerMapObj->mapobj_unk_18);
+ }
+}
+
+static void MachBikeTransition_80E51C4(u8 direction)
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+ u8 collision;
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E) == 0)
+ {
+ if (gPlayerAvatar.unkB)
+ MachBikeTransition_80E5270(playerMapObj->placeholder18);
+ else
+ MachBikeTransition_FaceDirection(playerMapObj->placeholder18);
+ }
+ else
+ {
+ collision = get_some_collision(direction);
+ if (collision > 0 && collision < 12)
+ {
+ if (collision == COLLISION_LEDGE_JUMP)
+ {
+ PlayerJumpLedge(direction);
+ }
+ else
+ {
+ sub_80E6024();
+ if (collision < 5 || collision > 8)
+ PlayerOnBikeCollide(direction);
+ }
+ }
+ else
+ {
+ gUnknown_083DB5A4[gPlayerAvatar.bikeFrameCounter](direction);
+ gPlayerAvatar.unkB = gPlayerAvatar.bikeFrameCounter + (gPlayerAvatar.bikeFrameCounter >> 1); // same as dividing by 2, but compiler is insistent on >> 1
+ if (gPlayerAvatar.bikeFrameCounter < 2) // do not go faster than the last element in the mach bike array
+ gPlayerAvatar.bikeFrameCounter++;
+ }
+ }
+}
+
+static void MachBikeTransition_80E5270(u8 var)
+{
+ u8 collision;
+
+ if (gPlayerAvatar.unkB != 0)
+ gPlayerAvatar.bikeFrameCounter = --gPlayerAvatar.unkB;
+
+ collision = get_some_collision(var);
+
+ if (collision > 0 && collision < 12)
+ {
+ if (collision == COLLISION_LEDGE_JUMP)
+ {
+ PlayerJumpLedge(var);
+ }
+ else
+ {
+ sub_80E6024();
+ if (collision < 5 || collision > 8)
+ PlayerOnBikeCollide(var);
+ }
+ }
+ else
+ {
+ gUnknown_083DB5A4[gPlayerAvatar.bikeFrameCounter](var);
+ }
+}
+
+static void MovePlayerOnAcroBike(u8 newDirection, u16 newKeys, u16 heldKeys)
+{
+ sAcroBikeTransitions[CheckMovementInputAcroBike(&newDirection, newKeys, heldKeys)](newDirection);
+}
+
+static u8 CheckMovementInputAcroBike(u8 *newDirection, u16 newKeys, u16 heldKeys)
+{
+ return sAcroBikeInputHandlers[gPlayerAvatar.acroBikeState](newDirection, newKeys, heldKeys);
+}
+
+static u8 AcroBikeHandleInputNormal(u8 *newDirection, u16 newKeys, u16 heldKeys)
+{
+ u8 direction = player_get_direction_upper_nybble();
+
+ gPlayerAvatar.bikeFrameCounter = 0;
+ if (*newDirection == DIR_NONE)
+ {
+ if (newKeys & B_BUTTON)
+ {
+ //We're standing still with the B button held.
+ //Do a wheelie.
+ *newDirection = direction;
+ gPlayerAvatar.running2 = 0;
+ gPlayerAvatar.acroBikeState = ACRO_STATE_WHEELIE_STANDING;
+ return ACRO_TRANS_NORMAL_TO_WHEELIE;
+ }
+ else
+ {
+ *newDirection = direction;
+ gPlayerAvatar.running2 = 0;
+ return ACRO_TRANS_FACE_DIRECTION;
+ }
+ }
+ if (*newDirection == direction && (heldKeys & B_BUTTON) && gPlayerAvatar.unkB == 0)
+ {
+ gPlayerAvatar.unkB++;
+ gPlayerAvatar.acroBikeState = ACRO_STATE_WHEELIE_MOVING;
+ return 11;
+ }
+ if (*newDirection != direction && gPlayerAvatar.running2 != 2)
+ {
+ gPlayerAvatar.acroBikeState = ACRO_STATE_TURNING;
+ gPlayerAvatar.unk9 = *newDirection;
+ gPlayerAvatar.running2 = 0;
+ return CheckMovementInputAcroBike(newDirection, newKeys, heldKeys);
+ }
+ gPlayerAvatar.running2 = 2;
+ return 2;
+}
+
+static u8 AcroBikeHandleInputTurning(u8 *newDirection, u16 newKeys, u16 heldKeys)
+{
+ u8 direction;
+
+ *newDirection = gPlayerAvatar.unk9;
+ gPlayerAvatar.bikeFrameCounter++;
+
+ //Wait 6 frames before actually changing direction
+ if (gPlayerAvatar.bikeFrameCounter > 6)
+ {
+ gPlayerAvatar.running2 = 1;
+ gPlayerAvatar.acroBikeState = ACRO_STATE_NORMAL;
+ sub_80E6024();
+ return 1;
+ }
+ direction = player_get_direction_upper_nybble();
+ if (*newDirection == sub_80E5C2C())
+ {
+ sub_80E6024();
+ gPlayerAvatar.unkB = 1;
+ if (*newDirection == GetOppositeDirection(direction))
+ {
+ gPlayerAvatar.acroBikeState = ACRO_STATE_6;
+ return 9;
+ }
+ else
+ {
+ gPlayerAvatar.running2 = 2;
+ gPlayerAvatar.acroBikeState = ACRO_STATE_5;
+ return 8;
+ }
+ }
+ *newDirection = direction;
+ return 0;
+}
+
+static u8 AcroBikeHandleInputWheelieStanding(u8 *ptr, u16 newKeys, u16 heldKeys)
+{
+ u8 direction;
+ struct MapObject *playerMapObj;
+
+ direction = player_get_direction_upper_nybble();
+ playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+ gPlayerAvatar.running2 = 0;
+
+ if (heldKeys & B_BUTTON)
+ gPlayerAvatar.bikeFrameCounter++;
+ else
+ {
+ //B button was released.
+ gPlayerAvatar.bikeFrameCounter = 0;
+ if (!MetatileBehavior_IsBumpySlope(playerMapObj->mapobj_unk_1E))
+ {
+ //Go back to normal on flat ground
+ *ptr = direction;
+ gPlayerAvatar.acroBikeState = ACRO_STATE_NORMAL;
+ sub_80E6024();
+ return 4;
+ }
+ }
+ if (gPlayerAvatar.bikeFrameCounter >= 40)
+ {
+ *ptr = direction;
+ gPlayerAvatar.acroBikeState = ACRO_STATE_BUNNY_HOP;
+ sub_80E6024();
+ return 6;
+ }
+ if (*ptr == direction)
+ {
+ gPlayerAvatar.running2 = 2;
+ gPlayerAvatar.acroBikeState = ACRO_STATE_WHEELIE_MOVING;
+ sub_80E6024();
+ return 10;
+ }
+ if (*ptr == 0)
+ {
+ *ptr = direction;
+ return 5;
+ }
+ gPlayerAvatar.running2 = 1;
+ return 5;
+}
+
+static u8 AcroBikeHandleInputBunnyHop(u8 *ptr, u16 newKeys, u16 heldKeys)
+{
+ u8 direction;
+ struct MapObject *playerMapObj;
+
+ direction = player_get_direction_upper_nybble();
+ playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (!(heldKeys & B_BUTTON))
+ {
+ //B button was released
+ sub_80E6024();
+ if (MetatileBehavior_IsBumpySlope(playerMapObj->mapobj_unk_1E))
+ {
+ //Do a standing wheelie on a bumpy slope
+ gPlayerAvatar.acroBikeState = ACRO_STATE_WHEELIE_STANDING;
+ return CheckMovementInputAcroBike(ptr, newKeys, heldKeys);
+ }
+ else
+ {
+ //Go back to normal on flat ground
+ *ptr = direction;
+ gPlayerAvatar.running2 = 0;
+ gPlayerAvatar.acroBikeState = ACRO_STATE_NORMAL;
+ return 4;
+ }
+ }
+
+ //B Button is still held
+
+ if (*ptr == DIR_NONE)
+ {
+ *ptr = direction;
+ gPlayerAvatar.running2 = 0;
+ return 6;
+ }
+ if (*ptr != direction && gPlayerAvatar.running2 != 2)
+ {
+ gPlayerAvatar.running2 = 1;
+ return 6;
+ }
+ gPlayerAvatar.running2 = 2;
+ return 7;
+}
+
+static u8 AcroBikeHandleInputWheelieMoving(u8 *ptr, u16 newKeys, u16 heldKeys)
+{
+ u8 direction;
+ struct MapObject *playerMapObj;
+
+ direction = player_get_direction_lower_nybble();
+ playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (!(heldKeys & B_BUTTON))
+ {
+ sub_80E6024();
+ if (!MetatileBehavior_IsBumpySlope(playerMapObj->mapobj_unk_1E))
+ {
+ gPlayerAvatar.acroBikeState = ACRO_STATE_NORMAL;
+ if (*ptr == 0)
+ {
+ *ptr = direction;
+ gPlayerAvatar.running2 = 0;
+ return 4;
+ }
+ if (*ptr != direction && gPlayerAvatar.running2 != 2)
+ {
+ gPlayerAvatar.running2 = 0;
+ return 4;
+ }
+ gPlayerAvatar.running2 = 2;
+ return 12;
+ }
+ gPlayerAvatar.acroBikeState = ACRO_STATE_WHEELIE_STANDING;
+ return CheckMovementInputAcroBike(ptr, newKeys, heldKeys);
+ }
+ if (*ptr == 0)
+ {
+ *ptr = direction;
+ gPlayerAvatar.acroBikeState = ACRO_STATE_WHEELIE_STANDING;
+ gPlayerAvatar.running2 = 0;
+ sub_80E6024();
+ return 5;
+ }
+ if (direction != *ptr && gPlayerAvatar.running2 != 2)
+ {
+ gPlayerAvatar.running2 = 0;
+ return 5;
+ }
+ gPlayerAvatar.running2 = 2;
+ return 10;
+}
+
+static u8 AcroBikeHandleInputState5(u8 *ptr, u16 newKeys, u16 heldKeys)
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ playerMapObj->mapobj_bit_9 = 0;
+ FieldObjectSetDirection(playerMapObj, playerMapObj->mapobj_unk_18);
+ gPlayerAvatar.acroBikeState = ACRO_STATE_NORMAL;
+ return CheckMovementInputAcroBike(ptr, newKeys, heldKeys);
+}
+
+static u8 AcroBikeHandleInputState6(u8 *ptr, u16 newKeys, u16 heldKeys)
+{
+ gPlayerAvatar.acroBikeState = ACRO_STATE_NORMAL;
+ return CheckMovementInputAcroBike(ptr, newKeys, heldKeys);
+}
+
+static void AcroBikeTransition_FaceDirection(u8 direction)
+{
+ PlayerFaceDirection(direction);
+}
+
+static void AcroBikeTransition_80E5708(u8 direction)
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E) == 0)
+ direction = playerMapObj->placeholder18;
+ PlayerFaceDirection(direction);
+}
+
+static void AcroBikeTransition_80E5744(u8 direction)
+{
+ u8 collision;
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E) == 0)
+ {
+ AcroBikeTransition_FaceDirection(playerMapObj->placeholder18);
+ return;
+ }
+ collision = get_some_collision(direction);
+ if (collision > 0 && collision < 12)
+ {
+ if (collision == COLLISION_LEDGE_JUMP)
+ PlayerJumpLedge(direction);
+ else if (collision < 5 || collision > 8)
+ PlayerOnBikeCollide(direction);
+ }
+ else
+ {
+ npc_use_some_d2s(direction);
+ }
+}
+
+static void AcroBikeTransition_NormalToWheelie(u8 direction)
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E) == 0)
+ direction = playerMapObj->placeholder18;
+ PlayerStartWheelie(direction);
+}
+
+static void AcroBikeTransition_80E57F8(u8 direction)
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E) == 0)
+ direction = playerMapObj->placeholder18;
+ sub_8059534(direction);
+}
+
+static void AcroBikeTransition_80E5834(u8 direction)
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E) == 0)
+ direction = playerMapObj->placeholder18;
+ sub_8059504(direction);
+}
+
+static void AcroBikeTransition_80E5870(u8 direction)
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E) == 0)
+ direction = playerMapObj->placeholder18;
+ sub_805954C(direction);
+}
+
+static void AcroBikeTransition_80E58AC(u8 direction)
+{
+ u8 var;
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E) == 0)
+ {
+ AcroBikeTransition_80E5870(playerMapObj->placeholder18);
+ return;
+ }
+ var = get_some_collision(direction);
+ //TODO: Try to get rid of this goto
+ if (var == 0 || var == 9)
+ {
+ goto derp;
+ }
+ else if (var == 6)
+ {
+ sub_8059594(direction);
+ }
+ else if (var < 5 || var > 8)
+ {
+ if (var <= 11)
+ {
+ AcroBikeTransition_80E5870(direction);
+ }
+ else
+ {
+ derp:
+ sub_8059570(direction);
+ }
+ }
+}
+
+static void AcroBikeTransition_80E5920(u8 direction)
+{
+ u8 var;
+ struct MapObject *playerMapObj;
+
+ var = get_some_collision(direction);
+ if (var != 0)
+ {
+ if (var == 7)
+ return;
+ if (var < 10)
+ {
+ AcroBikeTransition_80E5708(direction);
+ return;
+ }
+ if (sub_80E5EC0(var, direction) == 0)
+ {
+ AcroBikeTransition_80E5708(direction);
+ return;
+ }
+ }
+ playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+ PlaySE(SE_JITE_PYOKO);
+ playerMapObj->mapobj_bit_9 = 1;
+ PlayerSetAnimId(sub_80608A4(direction), 2);
+}
+
+static void AcroBikeTransition_80E5990(u8 direction)
+{
+ sub_80595B8(direction);
+}
+
+static void AcroBikeTransition_80E59A0(u8 direction)
+{
+ u8 var;
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E) == 0)
+ {
+ sub_8059504(playerMapObj->placeholder18);
+ return;
+ }
+ var = get_some_collision(direction);
+ if (var > 0 && var < 12)
+ {
+ if (var == 6)
+ {
+ sub_8059594(direction);
+ }
+ else if (var == 9)
+ {
+ sub_8059504(direction);
+ }
+ else if (var <= 4)
+ {
+ if (MetatileBehavior_IsBumpySlope(playerMapObj->mapobj_unk_1E))
+ sub_8059504(direction);
+ else
+ sub_80595DC(direction); //hit wall?
+ }
+ return;
+ }
+ sub_8059618(direction);
+ gPlayerAvatar.running2 = 2;
+}
+
+static void AcroBikeTransition_80E5A30(u8 direction)
+{
+ u8 var;
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E) == 0)
+ {
+ PlayerStartWheelie(playerMapObj->placeholder18);
+ return;
+ }
+ var = get_some_collision(direction);
+ if (var > 0 && var < 12)
+ {
+ if (var == 6)
+ {
+ sub_8059594(direction);
+ }
+ else if (var == 9)
+ {
+ sub_8059504(direction);
+ }
+ else if (var <= 4)
+ {
+ if (MetatileBehavior_IsBumpySlope(playerMapObj->mapobj_unk_1E))
+ sub_8059504(direction);
+ else
+ sub_80595DC(direction); //hit wall?
+ }
+ return;
+ }
+ sub_8059600(direction);
+ gPlayerAvatar.running2 = 2;
+}
+
+static void AcroBikeTransition_80E5AC0(u8 direction)
+{
+ u8 var;
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (CanBikeFaceDirOnMetatile(direction, playerMapObj->mapobj_unk_1E) == 0)
+ {
+ sub_8059534(playerMapObj->placeholder18);
+ return;
+ }
+ var = get_some_collision(direction);
+ if (var > 0 && var < 12)
+ {
+ if (var == 6)
+ PlayerJumpLedge(direction);
+ else if (var < 5 || var > 8)
+ sub_8059534(direction);
+ return;
+ }
+ sub_8059630(direction);
+}
+
+void sub_80E5B38(u16 a, u16 b)
+{
+ if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_ACRO_BIKE)
+ sub_80E5B60(a, b);
+}
+
+static void sub_80E5B60(u16 unused, u16 b)
+{
+ u8 var;
+
+ var = sub_80E5CF4(b);
+ if (var == (gPlayerAvatar.unkC & 0xF))
+ {
+ if (gPlayerAvatar.unk14[0] < 0xFF)
+ gPlayerAvatar.unk14[0]++;
+ }
+ else
+ {
+ sub_80E5C7C(var);
+ gPlayerAvatar.unkB = 0;
+ }
+
+ var = b & 0xF;
+ if (var == (gPlayerAvatar.unk10 & 0xF))
+ {
+ if (gPlayerAvatar.unk1C[0] < 0xFF)
+ gPlayerAvatar.unk1C[0]++;
+ }
+ else
+ {
+ sub_80E5CB8(var);
+ gPlayerAvatar.unkB = 0;
+ }
+}
+
+static bool8 sub_80E5BC8(const u8 *a, const u8 *b)
+{
+ u8 i;
+
+ for (i = 0; a[i] != 0; i++)
+ {
+ if (gPlayerAvatar.unk14[i] > a[i])
+ return FALSE;
+ }
+ for (i = 0; b[i] != 0; i++)
+ {
+ if (gPlayerAvatar.unk1C[i] > b[i])
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static u8 sub_80E5C2C(void)
+{
+ u32 i;
+
+ for (i = 0; i < 4; i++)
+ {
+ const struct UnknownStruct1 *s = &gUnknown_083DB608[i];
+ u32 r1 = gPlayerAvatar.unkC;
+ u32 r2 = gPlayerAvatar.unk10;
+
+ r1 &= s->unk8;
+ r2 &= s->unkC;
+ if (r1 == s->unk0 && r2 == s->unk4 && sub_80E5BC8(s->unk10, s->unk14))
+ return s->unk18;
+ }
+ return 0;
+}
+
+static void sub_80E5C7C(u8 a)
+{
+ u8 i;
+
+ gPlayerAvatar.unkC = (gPlayerAvatar.unkC << 4) | (a & 0xF);
+
+ for (i = 7; i != 0; i--)
+ gPlayerAvatar.unk14[i] = gPlayerAvatar.unk14[i - 1];
+ gPlayerAvatar.unk14[0] = 1;
+}
+
+static void sub_80E5CB8(u8 a)
+{
+ u8 i;
+
+ gPlayerAvatar.unk10 = (gPlayerAvatar.unk10 << 4) | (a & 0xF);
+
+ for (i = 7; i != 0; i--)
+ gPlayerAvatar.unk1C[i] = gPlayerAvatar.unk1C[i - 1];
+ gPlayerAvatar.unk1C[0] = 1;
+}
+
+static u8 sub_80E5CF4(u16 a)
+{
+ if (a & 0x40)
+ return 2;
+ if (a & 0x80)
+ return 1;
+ if (a & 0x20)
+ return 3;
+ if (a & 0x10)
+ return 4;
+ return 0;
+}
+
+static u8 get_some_collision(u8 direction)
+{
+ s16 x;
+ s16 y;
+ u8 metatitleBehavior;
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ x = playerMapObj->coords2.x;
+ y = playerMapObj->coords2.y;
+ MoveCoords(direction, &x, &y);
+ metatitleBehavior = MapGridGetMetatileBehaviorAt(x, y);
+ return sub_80E5DA0(playerMapObj, x, y, direction, metatitleBehavior);
+}
+
+static u8 sub_80E5DA0(struct MapObject *mapObject, s16 x, s16 y, u8 direction, u8 metatitleBehavior)
+{
+ u8 collision = CheckForFieldObjectCollision(mapObject, x, y, direction, metatitleBehavior);
+
+ if (collision > 4)
+ return collision;
+
+ if (collision == 0 && IsRunningDisallowedByMetatile(metatitleBehavior))
+ collision = 2;
+
+ if (collision)
+ sub_80E5E4C();
+
+ return collision;
+}
+
+bool8 IsRunningDisallowed(u8 tile)
+{
+ if (IsRunningDisallowedByMetatile(tile) != FALSE || gMapHeader.mapType == MAP_TYPE_INDOOR)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static bool8 IsRunningDisallowedByMetatile(u8 tile)
+{
+ if (MetatileBehavior_IsRunningDisallowed(tile))
+ return TRUE;
+ if (MetatileBehavior_IsFortreeBridge(tile) && (PlayerGetZCoord() & 1) == 0)
+ return TRUE;
+ return FALSE;
+}
+
+static void sub_80E5E4C(void)
+{
+ if (gUnknown_02039250 != 0 && gUnknown_02039251 < 100)
+ gUnknown_02039251++;
+}
+
+static bool8 CanBikeFaceDirOnMetatile(u8 direction, u8 tile)
+{
+ if (direction == DIR_EAST || direction == DIR_WEST)
+ {
+ //Bike cannot face east or west on a vertical rail
+ if (MetatileBehavior_IsIsolatedVerticalRail(tile)
+ || MetatileBehavior_IsVerticalRail(tile))
+ return FALSE;
+ }
+ else
+ {
+ //Bike cannot face north or south on a horizontal rail
+ if (MetatileBehavior_IsIsolatedHorizontalRail(tile)
+ || MetatileBehavior_IsHorizontalRail(tile))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static bool8 sub_80E5EC0(u8 var1, u8 direction)
+{
+ if (direction == DIR_NORTH || direction == DIR_SOUTH)
+ {
+ if (var1 == 10 || var1 == 12)
+ return FALSE;
+ }
+ else if (var1 == 11 || var1 == 13)
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+bool8 IsBikingDisallowedByPlayer(void)
+{
+ s16 x, y;
+ u8 tileBehavior;
+
+ if (!(gPlayerAvatar.flags & (PLAYER_AVATAR_FLAG_SURFING | PLAYER_AVATAR_FLAG_4)))
+ {
+ PlayerGetDestCoords(&x, &y);
+ tileBehavior = MapGridGetMetatileBehaviorAt(x, y);
+ if (!IsRunningDisallowedByMetatile(tileBehavior))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool8 player_should_look_direction_be_enforced_upon_movement(void)
+{
+ if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_ACRO_BIKE) != FALSE && MetatileBehavior_IsBumpySlope(gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1E) != FALSE)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+void GetOnOffBike(u8 var)
+{
+ gUnknown_0202E854 = 0;
+
+ if (gPlayerAvatar.flags & (PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE))
+ {
+ SetPlayerAvatarTransitionFlags(PLAYER_AVATAR_FLAG_ON_FOOT);
+ Overworld_ClearSavedMusic();
+ Overworld_PlaySpecialMapMusic();
+ }
+ else
+ {
+ SetPlayerAvatarTransitionFlags(var);
+ Overworld_SetSavedMusic(BGM_CYCLING);
+ Overworld_ChangeMusicTo(BGM_CYCLING);
+ }
+}
+
+void BikeClearState(int var1, int var2)
+{
+ u8 i;
+
+ gPlayerAvatar.acroBikeState = ACRO_STATE_NORMAL;
+ gPlayerAvatar.unk9 = 0;
+ gPlayerAvatar.bikeFrameCounter = 0;
+ gPlayerAvatar.unkB = 0;
+ gPlayerAvatar.unkC = var1;
+ gPlayerAvatar.unk10 = var2;
+
+ for (i = 0; i < 8; i++)
+ gPlayerAvatar.unk14[i] = 0;
+
+ for (i = 0; i < 8; i++)
+ gPlayerAvatar.unk1C[i] = 0;
+}
+
+void sub_80E6010(u8 var)
+{
+ gPlayerAvatar.bikeFrameCounter = var;
+ gPlayerAvatar.unkB = gPlayerAvatar.bikeFrameCounter + (gPlayerAvatar.bikeFrameCounter >> 1); // lazy way of multiplying by 1.5.
+}
+
+static void sub_80E6024(void)
+{
+ gPlayerAvatar.bikeFrameCounter = 0;
+ gPlayerAvatar.unkB = 0;
+}
+
+s16 GetPlayerSpeed(void)
+{
+ // because the player pressed a direction, it won't ever return a speed of 0 since this function returns the player's current speed.
+ s16 machSpeeds[3];
+
+ memcpy(machSpeeds, gMachBikeSpeeds, sizeof(machSpeeds));
+
+ if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_MACH_BIKE)
+ return machSpeeds[gPlayerAvatar.bikeFrameCounter];
+ else if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_ACRO_BIKE)
+ return SPEED_FASTER;
+ else if (gPlayerAvatar.flags & (PLAYER_AVATAR_FLAG_SURFING | PLAYER_AVATAR_FLAG_DASH))
+ return SPEED_FAST;
+ else
+ return SPEED_NORMAL;
+}
+
+void sub_80E6084(void)
+{
+ s16 x, y;
+ u8 tileBehavior;
+
+ if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_ACRO_BIKE)
+ {
+ PlayerGetDestCoords(&x, &y);
+ tileBehavior = MapGridGetMetatileBehaviorAt(x, y);
+ if (MetatileBehavior_IsBumpySlope(tileBehavior))
+ {
+ gPlayerAvatar.acroBikeState = ACRO_STATE_WHEELIE_STANDING;
+ sub_8059C94(player_get_direction_upper_nybble());
+ }
+ }
+}
diff --git a/src/field/birch_pc.c b/src/field/birch_pc.c
new file mode 100644
index 000000000..9872dd54d
--- /dev/null
+++ b/src/field/birch_pc.c
@@ -0,0 +1,114 @@
+#include "global.h"
+#include "event_data.h"
+#include "field_message_box.h"
+#include "pokedex.h"
+#include "species.h"
+
+extern u16 gSpecialVar_0x8004;
+extern u16 gSpecialVar_0x8005;
+extern u16 gSpecialVar_0x8006;
+
+extern const u8 gBirchDexRatingText_LessThan10[];
+extern const u8 gBirchDexRatingText_LessThan20[];
+extern const u8 gBirchDexRatingText_LessThan30[];
+extern const u8 gBirchDexRatingText_LessThan40[];
+extern const u8 gBirchDexRatingText_LessThan50[];
+extern const u8 gBirchDexRatingText_LessThan60[];
+extern const u8 gBirchDexRatingText_LessThan70[];
+extern const u8 gBirchDexRatingText_LessThan80[];
+extern const u8 gBirchDexRatingText_LessThan90[];
+extern const u8 gBirchDexRatingText_LessThan100[];
+extern const u8 gBirchDexRatingText_LessThan110[];
+extern const u8 gBirchDexRatingText_LessThan120[];
+extern const u8 gBirchDexRatingText_LessThan130[];
+extern const u8 gBirchDexRatingText_LessThan140[];
+extern const u8 gBirchDexRatingText_LessThan150[];
+extern const u8 gBirchDexRatingText_LessThan160[];
+extern const u8 gBirchDexRatingText_LessThan170[];
+extern const u8 gBirchDexRatingText_LessThan180[];
+extern const u8 gBirchDexRatingText_LessThan190[];
+extern const u8 gBirchDexRatingText_LessThan200[];
+extern const u8 gBirchDexRatingText_DexCompleted[];
+
+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/field/braille_puzzles.c b/src/field/braille_puzzles.c
new file mode 100644
index 000000000..b11b1ff3a
--- /dev/null
+++ b/src/field/braille_puzzles.c
@@ -0,0 +1,262 @@
+#include "global.h"
+#include "braille_puzzles.h"
+#include "event_data.h"
+#include "field_camera.h"
+#include "field_effect.h"
+#include "fieldmap.h"
+#include "flags.h"
+#include "main.h"
+#include "map_constants.h"
+#include "map_obj_lock.h"
+#include "menu.h"
+#include "rom6.h"
+#include "script.h"
+#include "songs.h"
+#include "sound.h"
+#include "species.h"
+#include "task.h"
+#include "text.h"
+
+extern u8 gPlayerPartyCount;
+extern u8 gLastFieldPokeMenuOpened;
+
+extern u8 S_OpenRegiceChamber[]; // regiice event script
+
+bool8 ShouldDoBrailleDigEffect(void)
+{
+ if (!FlagGet(SYS_BRAILLE_DIG)
+ && (gSaveBlock1.location.mapGroup == MAP_GROUP_SEALED_CHAMBER_OUTER_ROOM
+ && gSaveBlock1.location.mapNum == MAP_ID_SEALED_CHAMBER_OUTER_ROOM))
+ {
+ if (gSaveBlock1.pos.x == 10 && gSaveBlock1.pos.y == 3)
+ return TRUE;
+ else if (gSaveBlock1.pos.x == 9 && gSaveBlock1.pos.y == 3)
+ return TRUE;
+ else if (gSaveBlock1.pos.x == 11 && gSaveBlock1.pos.y == 3)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void DoBrailleDigEffect(void)
+{
+ MapGridSetMetatileIdAt(16, 8, 554);
+ MapGridSetMetatileIdAt(17, 8, 555);
+ MapGridSetMetatileIdAt(18, 8, 556);
+ MapGridSetMetatileIdAt(16, 9, 3634);
+ MapGridSetMetatileIdAt(17, 9, 563);
+ MapGridSetMetatileIdAt(18, 9, 3636);
+ DrawWholeMapView();
+ PlaySE(SE_BAN);
+ FlagSet(SYS_BRAILLE_DIG);
+ ScriptContext2_Disable();
+}
+
+bool8 CheckRelicanthWailord(void)
+{
+ // First comes Relicanth.
+ if (GetMonData(&gPlayerParty, MON_DATA_SPECIES2, 0) == SPECIES_RELICANTH)
+ {
+ CalculatePlayerPartyCount();
+ // Last comes Wailord
+ if (GetMonData(&gPlayerParty[gPlayerPartyCount - 1], MON_DATA_SPECIES2, 0) == SPECIES_WAILORD)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 ShouldDoBrailleStrengthEffect(void)
+{
+ if (!FlagGet(SYS_BRAILLE_STRENGTH) && (gSaveBlock1.location.mapGroup == MAP_GROUP_DESERT_RUINS && gSaveBlock1.location.mapNum == MAP_ID_DESERT_RUINS))
+ {
+ if (gSaveBlock1.pos.x == 10 && gSaveBlock1.pos.y == 23)
+ return TRUE;
+ else if (gSaveBlock1.pos.x == 9 && gSaveBlock1.pos.y == 23)
+ return TRUE;
+ else if (gSaveBlock1.pos.x == 11 && gSaveBlock1.pos.y == 23)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void DoBrailleStrengthEffect(void)
+{
+ FieldEffectActiveListRemove(0x28);
+ MapGridSetMetatileIdAt(14, 26, 554);
+ MapGridSetMetatileIdAt(15, 26, 555);
+ MapGridSetMetatileIdAt(16, 26, 556);
+ MapGridSetMetatileIdAt(14, 27, 3634);
+ MapGridSetMetatileIdAt(15, 27, 563);
+ MapGridSetMetatileIdAt(16, 27, 3636);
+ DrawWholeMapView();
+ PlaySE(SE_BAN);
+ FlagSet(SYS_BRAILLE_STRENGTH);
+ ScriptContext2_Disable();
+}
+
+bool8 ShouldDoBrailleFlyEffect(void)
+{
+ if (!FlagGet(SYS_BRAILLE_FLY) && (gSaveBlock1.location.mapGroup == MAP_GROUP_ANCIENT_TOMB && gSaveBlock1.location.mapNum == MAP_ID_ANCIENT_TOMB))
+ {
+ if (gSaveBlock1.pos.x == 8 && gSaveBlock1.pos.y == 25)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void DoBrailleFlyEffect(void)
+{
+ gFieldEffectArguments[0] = gLastFieldPokeMenuOpened;
+ FieldEffectStart(FLDEFF_USE_FLY_ANCIENT_TOMB);
+}
+
+bool8 FldEff_UseFlyAncientTomb(void)
+{
+ u8 taskId = oei_task_add();
+
+ gTasks[taskId].data[8] = (u32)UseFlyAncientTomb_Callback >> 16;
+ gTasks[taskId].data[9] = (u32)UseFlyAncientTomb_Callback;
+ return FALSE;
+}
+
+void UseFlyAncientTomb_Callback(void)
+{
+ FieldEffectActiveListRemove(FLDEFF_USE_FLY_ANCIENT_TOMB);
+ UseFlyAncientTomb_Finish();
+}
+
+void UseFlyAncientTomb_Finish(void)
+{
+ MapGridSetMetatileIdAt(14, 26, 554);
+ MapGridSetMetatileIdAt(15, 26, 555);
+ MapGridSetMetatileIdAt(16, 26, 556);
+ MapGridSetMetatileIdAt(14, 27, 3634);
+ MapGridSetMetatileIdAt(15, 27, 563);
+ MapGridSetMetatileIdAt(16, 27, 3636);
+ DrawWholeMapView();
+ PlaySE(SE_BAN);
+ FlagSet(SYS_BRAILLE_FLY);
+ ScriptContext2_Disable();
+}
+
+void DoBrailleWait(void)
+{
+ if (!FlagGet(SYS_BRAILLE_WAIT))
+ CreateTask(Task_BrailleWait, 0x50);
+}
+
+void Task_BrailleWait(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ switch (data[0])
+ {
+ case 0:
+ data[1] = 7200;
+ data[0] = 1;
+ break;
+ case 1:
+ if (BrailleWait_CheckButtonPress() != FALSE)
+ {
+ MenuZeroFillScreen();
+ PlaySE(SE_SELECT);
+ data[0] = 2;
+ }
+ else
+ {
+ data[1] = data[1] - 1;
+ if (data[1] == 0)
+ {
+ MenuZeroFillScreen();
+ data[0] = 3;
+ data[1] = 30;
+ }
+ }
+ break;
+ case 2:
+ if (BrailleWait_CheckButtonPress() == FALSE)
+ {
+ data[1] = data[1] - 1;
+ if (data[1] == 0)
+ data[0] = 4;
+ break;
+ }
+ sub_8064E2C();
+ DestroyTask(taskId);
+ ScriptContext2_Disable();
+ break;
+ case 3:
+ data[1] = data[1] - 1;
+ if (data[1] == 0)
+ data[0] = 4;
+ break;
+ case 4:
+ sub_8064E2C();
+ ScriptContext1_SetupScript(S_OpenRegiceChamber);
+ DestroyTask(taskId);
+ break;
+ }
+}
+
+bool32 BrailleWait_CheckButtonPress(void)
+{
+ u16 keyMask = A_BUTTON | B_BUTTON | START_BUTTON | SELECT_BUTTON | DPAD_ANY;
+
+ if (gSaveBlock2.optionsButtonMode == OPTIONS_BUTTON_MODE_LR)
+ keyMask |= L_BUTTON | R_BUTTON;
+ if (gSaveBlock2.optionsButtonMode == OPTIONS_BUTTON_MODE_L_EQUALS_A)
+ keyMask |= L_BUTTON;
+
+ if (gMain.newKeys & keyMask)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void DoSealedChamberShakingEffect1(void)
+{
+ u8 taskId = CreateTask(SealedChamberShakingEffect, 0x9);
+
+ gTasks[taskId].data[1] = 0;
+ gTasks[taskId].data[2] = 0;
+ gTasks[taskId].data[4] = 2;
+ gTasks[taskId].data[5] = 5;
+ gTasks[taskId].data[6] = 50;
+ SetCameraPanningCallback(0);
+}
+
+void DoSealedChamberShakingEffect2(void)
+{
+ u8 taskId = CreateTask(SealedChamberShakingEffect, 0x9);
+
+ gTasks[taskId].data[1] = 0;
+ gTasks[taskId].data[2] = 0;
+ gTasks[taskId].data[4] = 3;
+ gTasks[taskId].data[5] = 5;
+ gTasks[taskId].data[6] = 2;
+ SetCameraPanningCallback(0);
+}
+
+void SealedChamberShakingEffect(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ task->data[1]++;
+
+ if (!(task->data[1] % task->data[5]))
+ {
+ task->data[1] = 0;
+ task->data[2]++;
+ task->data[4] = -task->data[4];
+ SetCameraPanning(0, task->data[4]);
+ if (task->data[2] == task->data[6])
+ {
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+ InstallCameraPanAheadCallback();
+ }
+ }
+}
diff --git a/src/field/choose_party.c b/src/field/choose_party.c
new file mode 100644
index 000000000..9cdf63fc8
--- /dev/null
+++ b/src/field/choose_party.c
@@ -0,0 +1,987 @@
+#include "global.h"
+#include "decoration.h"
+#include "field_fadetransition.h"
+#include "main.h"
+#include "menu.h"
+#include "name_string_util.h"
+#include "palette.h"
+#include "party_menu.h"
+#include "pokemon_menu.h"
+#include "pokemon.h"
+#include "pokemon_summary_screen.h"
+#include "overworld.h"
+#include "script.h"
+#include "songs.h"
+#include "sound.h"
+#include "strings.h"
+#include "string_util.h"
+#include "task.h"
+#include "text.h"
+
+struct UnknownPokemonStruct2
+{
+ /*0x00*/ u16 species;
+ /*0x02*/ u16 heldItem;
+ /*0x04*/ u8 nickname[11];
+ /*0x0F*/ u8 level;
+ /*0x10*/ u16 hp;
+ /*0x12*/ u16 maxhp;
+ /*0x14*/ u32 status;
+ /*0x18*/ u32 personality;
+ /*0x1C*/ u8 gender;
+ /*0x1D*/ u8 language;
+};
+
+extern u8 gPlayerPartyCount;
+extern u8 gLastFieldPokeMenuOpened;
+extern u8 gUnknown_020384F0;
+extern struct UnknownPokemonStruct2 gUnknown_02023A00[];
+extern u8 gUnknown_0202E8F6;
+extern struct Pokemon gUnknown_030042FC[];
+extern const u16 gBattleTowerBanlist[];
+
+EWRAM_DATA u8 gSelectedOrderFromParty[3] = {0};
+
+extern void OpenPartyMenu();
+extern void TryCreatePartyMenuMonIcon(u8, u8, struct Pokemon *);
+extern void LoadHeldItemIconGraphics(void);
+extern void CreateHeldItemIcons_806DC34();
+extern u8 sub_806BD58(u8, u8);
+extern void PartyMenuPrintMonsLevelOrStatus(void);
+extern void PrintPartyMenuMonNicknames(void);
+extern void sub_806BC3C(u8, u8);
+extern u8 sub_806B58C(u8);
+extern u16 sub_806BE38();
+extern u8 sub_806CA38();
+extern TaskFunc PartyMenuGetPopupMenuFunc(u8, const struct PartyPopupMenu *, const struct PartyMenuItem *, u8);
+extern u8 sub_806B124();
+extern void sub_806C994();
+extern void sub_806C658();
+extern void sub_806AEDC(void);
+extern void sub_806AF4C();
+extern void ShowPokemonSummaryScreen(struct Pokemon *, u8, u8, void (*)(void), int);
+extern void sub_806C890();
+extern void sub_806D5A4();
+extern void sub_806B908(void);
+extern void CreateMonIcon_806D99C(int, u8, int, struct UnknownPokemonStruct2 *);
+extern void sub_806D50C(int, u8);
+extern void CreatePartyMenuMonIcon();
+extern void CreateHeldItemIcon_806DCD4(int, u8, int);
+extern u8 GetMonStatusAndPokerus();
+extern void PartyMenuPrintHP();
+extern void PartyMenuPutStatusTilemap(u8, int, u8);
+extern void PartyMenuPrintLevel();
+extern void PartyMenuPutNicknameTilemap();
+extern void PrintPartyMenuMonNickname();
+extern void PartyMenuDrawHPBar();
+extern bool8 sub_80F9344(void);
+extern void sub_806D4AC();
+extern void sub_806D3B4();
+extern void PartyMenuDoPrintLevel(u8, u8, u8);
+extern void PartyMenuDoDrawHPBar(u8, u8, u16, u16);
+extern void PartyMenuDoPutNicknameTilemap(u16, u8, u8, u8, const u8 *);
+extern void box_print(u8, int, const u8 *);
+extern void sub_806BCE8(void);
+extern void sub_806E750(u8, const struct PartyPopupMenu *, const struct PartyMenuItem *, int);
+
+static void ClearPartySelection(void);
+static bool8 IsMonAllowedInBattleTower(struct Pokemon *);
+static void sub_812238C(u8);
+static void sub_8122450(u8);
+static void sub_81224A8(u8);
+static void sub_8122728(u8);
+static void BattleTowerEntryMenuCallback_Exit(u8);
+static void sub_81228E8(u8);
+static void sub_8122950(u8);
+static void sub_81229B8(void);
+static void sub_8122AB8(u8);
+static void sub_8122B10(u8);
+static void sub_8122C18(u8);
+static void Task_DaycareStorageMenu8122EAC(u8);
+void sub_8123138(u8);
+static void sub_8123170(u8);
+static void sub_81231AC(void);
+
+void sub_8121E10(void)
+{
+ ClearPartySelection();
+ ewram1B000.unk263 = 0;
+ OpenPartyMenu(4, 0);
+}
+
+void sub_8121E34(void)
+{
+ ClearPartySelection();
+ ewram1B000.unk263 = 1;
+ OpenPartyMenu(4, 0);
+}
+
+static void ClearPartySelection(void)
+{
+ u8 i;
+
+ for (i = 0; i < 3; i++)
+ gSelectedOrderFromParty[i] = 0;
+}
+
+bool8 sub_8121E78(void)
+{
+ u8 i;
+
+ switch (ewram1B000_alt.unk264)
+ {
+ case 0:
+ if (ewram1B000_alt.unk266 < gPlayerPartyCount)
+ {
+ TryCreatePartyMenuMonIcon(ewram1B000_alt.unk260, ewram1B000_alt.unk266, &gPlayerParty[ewram1B000_alt.unk266]);
+ ewram1B000_alt.unk266++;
+ }
+ else
+ {
+ ewram1B000_alt.unk266 = 0;
+ ewram1B000_alt.unk264++;
+ }
+ break;
+ case 1:
+ LoadHeldItemIconGraphics();
+ ewram1B000_alt.unk264++;
+ break;
+ case 2:
+ CreateHeldItemIcons_806DC34(ewram1B000_alt.unk260);
+ ewram1B000_alt.unk264++;
+ break;
+ case 3:
+ if (sub_806BD58(ewram1B000_alt.unk260, ewram1B000_alt.unk266) == 1)
+ {
+ ewram1B000_alt.unk266 = 0;
+ ewram1B000_alt.unk264++;
+ }
+ else
+ {
+ ewram1B000_alt.unk266++;
+ }
+ break;
+ case 4:
+ PartyMenuPrintMonsLevelOrStatus();
+ ewram1B000_alt.unk264++;
+ break;
+ case 5:
+ PrintPartyMenuMonNicknames();
+ ewram1B000_alt.unk264++;
+ break;
+ case 6:
+ for (i = 0; i < gPlayerPartyCount; i++)
+ {
+ u8 j;
+
+ for (j = 0; j < 3; j++)
+ {
+ if (gSelectedOrderFromParty[j] == i + 1)
+ {
+ sub_806BC3C(i, j * 14 + 0x1C);
+ break;
+ }
+ }
+ if (j == 3)
+ {
+ if (IsMonAllowedInBattleTower(&gPlayerParty[i]) == TRUE)
+ sub_806BC3C(i, 0x70);
+ else
+ sub_806BC3C(i, 0x7E);
+ }
+ }
+ ewram1B000_alt.unk264++;
+ break;
+ case 7:
+ if (sub_806B58C(ewram1B000_alt.unk266) == 1)
+ {
+ ewram1B000_alt.unk266 = 0;
+ ewram1B000_alt.unk264 = 0;
+ return TRUE;
+ }
+ else
+ {
+ ewram1B000_alt.unk266++;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static bool8 IsMonAllowedInBattleTower(struct Pokemon *pkmn)
+{
+ u16 species;
+ s32 i = 0;
+
+ if (GetMonData(pkmn, MON_DATA_IS_EGG))
+ return FALSE;
+
+ if (ewram1B000.unk263 == 0)
+ {
+ if (GetMonData(pkmn, MON_DATA_HP) == 0)
+ return FALSE;
+ else
+ return TRUE;
+ }
+
+ if ((gSaveBlock2.filler_A8.var_4AC & 1) == 0
+ && GetMonData(pkmn, MON_DATA_LEVEL) > 50)
+ return FALSE;
+
+ // Check if the pkmn is in the ban list
+ species = GetMonData(pkmn, MON_DATA_SPECIES);
+ while (gBattleTowerBanlist[i] != 0xFFFF)
+ {
+ if (gBattleTowerBanlist[i] == species)
+ return FALSE;
+ i++;
+ }
+ return TRUE;
+}
+
+static u8 sub_81220C8(void)
+{
+ u8 i;
+
+ if (ewram1B000.unk263 == 0)
+ return 0xFF;
+ if (gSelectedOrderFromParty[2] == 0)
+ return 0x11;
+ for (i = 0; i < 2; i++)
+ {
+ u8 j;
+
+ ewram1B000.unk282 = GetMonData(&gUnknown_030042FC[gSelectedOrderFromParty[i]], MON_DATA_SPECIES);
+ ewram1B000.unk280 = GetMonData(&gUnknown_030042FC[gSelectedOrderFromParty[i]], MON_DATA_HELD_ITEM);
+ for (j = i + 1; j < 3; j++)
+ {
+ if (ewram1B000.unk282 == GetMonData(&gUnknown_030042FC[gSelectedOrderFromParty[j]], MON_DATA_SPECIES))
+ return 0x12;
+ if (ewram1B000.unk280 != 0 && ewram1B000.unk280 == GetMonData(&gUnknown_030042FC[gSelectedOrderFromParty[j]], MON_DATA_HELD_ITEM))
+ return 0x13;
+ }
+ }
+ return 0xFF;
+}
+
+//------------------------------------------------------------------------------
+// Battle Tower Entry Menu
+//------------------------------------------------------------------------------
+
+static void BattleTowerEntryMenuCallback_Summary(u8);
+static void BattleTowerEntryMenuCallback_Enter(u8);
+static void BattleTowerEntryMenuCallback_NoEntry(u8);
+static void BattleTowerEntryMenuCallback_Exit(u8);
+
+static const struct PartyMenuItem sBattleTowerEntryMenuItems[] =
+{
+ {OtherText_Summary, BattleTowerEntryMenuCallback_Summary},
+ {OtherText_Enter2, BattleTowerEntryMenuCallback_Enter},
+ {OtherText_NoEntry, BattleTowerEntryMenuCallback_NoEntry},
+ {gUnknownText_Exit, BattleTowerEntryMenuCallback_Exit},
+};
+
+static const u8 gUnknown_084017D0[] = {1, 0, 3};
+static const u8 gUnknown_084017D3[] = {2, 0, 3};
+static const u8 gUnknown_084017D6[] = {0, 3};
+
+static const struct PartyPopupMenu sBattleTowerEntryMenu[] =
+{
+ {ARRAY_COUNT(gUnknown_084017D0), 9, gUnknown_084017D0},
+ {ARRAY_COUNT(gUnknown_084017D3), 9, gUnknown_084017D3},
+ {ARRAY_COUNT(gUnknown_084017D6), 9, gUnknown_084017D6},
+};
+
+
+static bool8 IsPartyMemberAlreadySelected(u8 partyMember)
+{
+ u8 i;
+
+ for (i = 0; i < 3; i++)
+ {
+ if (gSelectedOrderFromParty[i] == partyMember)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void sub_81221F8(u8 taskId)
+{
+ sub_806D538(5, 1);
+ if (IsMonAllowedInBattleTower(&gPlayerParty[gLastFieldPokeMenuOpened]) == TRUE)
+ {
+ if (IsPartyMemberAlreadySelected(gLastFieldPokeMenuOpened + 1) == TRUE)
+ {
+ gTasks[taskId].data[4] = 1;
+ sub_806E750(1, sBattleTowerEntryMenu, sBattleTowerEntryMenuItems, 0);
+ }
+ else
+ {
+ gTasks[taskId].data[4] = 0;
+ sub_806E750(0, sBattleTowerEntryMenu, sBattleTowerEntryMenuItems, 0);
+ }
+ }
+ else
+ {
+ gTasks[taskId].data[4] = 2;
+ sub_806E750(2, sBattleTowerEntryMenu, sBattleTowerEntryMenuItems, 0);
+ }
+}
+
+void sub_81222B0(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ switch (sub_806BE38(taskId))
+ {
+ case 1:
+ PlaySE(SE_SELECT);
+ gLastFieldPokeMenuOpened = sub_806CA38(taskId);
+ if (gLastFieldPokeMenuOpened != 6)
+ {
+ GetMonNickname(&gPlayerParty[gLastFieldPokeMenuOpened], gStringVar1);
+ sub_81221F8(taskId);
+ gTasks[taskId].func = sub_812238C;
+ }
+ else
+ {
+ gTasks[taskId].func = sub_81224A8;
+ }
+ sub_808B5B4(taskId);
+ break;
+ case 2:
+ PlaySE(SE_SELECT);
+ ClearPartySelection();
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0);
+ gTasks[taskId].func = sub_8122450;
+ break;
+ }
+ }
+}
+
+// Handle input
+static void sub_812238C(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ if (gMain.newAndRepeatedKeys & 0x40)
+ {
+ if (GetMenuCursorPos() != 0)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor(-1);
+ }
+ return;
+ }
+ if (gMain.newAndRepeatedKeys & 0x80)
+ {
+ if (GetMenuCursorPos() != 3)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor(1);
+ }
+ return;
+ }
+ if (gMain.newKeys & A_BUTTON)
+ {
+ TaskFunc popupMenuFunc;
+
+ PlaySE(SE_SELECT);
+ popupMenuFunc = PartyMenuGetPopupMenuFunc(
+ gTasks[taskId].data[4],
+ sBattleTowerEntryMenu,
+ sBattleTowerEntryMenuItems,
+ GetMenuCursorPos());
+ popupMenuFunc(taskId);
+ return;
+ }
+ if (gMain.newKeys & B_BUTTON)
+ {
+ BattleTowerEntryMenuCallback_Exit(taskId);
+ return;
+ }
+ }
+}
+
+// Return from menu?
+static void sub_8122450(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ SetMainCallback2(gMain.savedCallback);
+ DestroyTask(taskId);
+ }
+}
+
+// Wait for A or B press
+static void sub_8122480(u8 taskId)
+{
+ if ((gMain.newKeys & A_BUTTON) || (gMain.newKeys & B_BUTTON))
+ BattleTowerEntryMenuCallback_Exit(taskId);
+}
+
+static void sub_81224A8(u8 taskId)
+{
+ u8 val = sub_81220C8();
+
+ if (val != 0xFF)
+ {
+ sub_806D538(val, 0);
+ gTasks[taskId].func = sub_8122480;
+ }
+ else
+ {
+ if (gSelectedOrderFromParty[0] != 0)
+ {
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0);
+ gTasks[taskId].func = sub_8122450;
+ }
+ else
+ {
+ PlaySE(SE_HAZURE);
+ sub_806D538(14, 0);
+ gTasks[taskId].func = sub_8122480;
+ }
+ }
+}
+
+// CB2 for menu?
+static void sub_8122530(void)
+{
+ while (1)
+ {
+ if (sub_806B124() == 1)
+ {
+ sub_806C994(ewram1B000.unk260, gUnknown_020384F0);
+ sub_806C658(ewram1B000.unk260, 0);
+ GetMonNickname(&gPlayerParty[gUnknown_020384F0], gStringVar1);
+ gLastFieldPokeMenuOpened = gUnknown_020384F0;
+ sub_81221F8(ewram1B000.unk260);
+ SetMainCallback2(sub_806AEDC);
+ break;
+ }
+ if (sub_80F9344() == 1)
+ break;
+ }
+}
+
+static void sub_81225A4(void)
+{
+ gPaletteFade.bufferTransferDisabled = TRUE;
+ sub_806AF4C(4, 0xFF, sub_812238C, 5);
+ SetMainCallback2(sub_8122530);
+}
+
+// Wait for fade, then show summary screen
+static void sub_81225D4(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ u8 r4 = gSprites[gTasks[taskId].data[3] >> 8].data0;
+
+ DestroyTask(taskId);
+ ewram1B000.unk262 = 1;
+ ShowPokemonSummaryScreen(gPlayerParty, r4, gPlayerPartyCount - 1, sub_81225A4, 0);
+ }
+}
+
+// Summary callback?
+static void BattleTowerEntryMenuCallback_Summary(u8 taskId)
+{
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0);
+ gTasks[taskId].func = sub_81225D4;
+}
+
+static void BattleTowerEntryMenuCallback_Enter(u8 taskId)
+{
+ u8 i;
+
+ for (i = 0; i < 3; i++)
+ {
+ if (gSelectedOrderFromParty[i] == 0)
+ {
+ gSelectedOrderFromParty[i] = gLastFieldPokeMenuOpened + 1;
+ sub_806BC3C(gLastFieldPokeMenuOpened, i * 14 + 0x1C);
+ if (i == 2)
+ sub_806C890(taskId);
+ BattleTowerEntryMenuCallback_Exit(taskId);
+ return;
+ }
+ }
+ PlaySE(SE_HAZURE);
+ MenuZeroFillWindowRect(20, 10, 29, 19);
+ HandleDestroyMenuCursors();
+ sub_806D5A4();
+ sub_806E834(gOtherText_NoMoreThreePoke, 1);
+ gTasks[taskId].func = sub_8122728;
+}
+
+static void sub_8122728(u8 taskId)
+{
+ if (gUnknown_0202E8F6 == 1)
+ return;
+
+ if ((gMain.newKeys & A_BUTTON) || (gMain.newKeys & B_BUTTON))
+ {
+ MenuZeroFillWindowRect(0, 14, 29, 19);
+ HandleDestroyMenuCursors();
+ BattleTowerEntryMenuCallback_Exit(taskId);
+ }
+}
+
+static void BattleTowerEntryMenuCallback_NoEntry(u8 taskId)
+{
+ u8 i;
+
+ for (i = 0; i < 3; i++)
+ {
+ if (gSelectedOrderFromParty[i] == gLastFieldPokeMenuOpened + 1)
+ {
+ gSelectedOrderFromParty[i] = 0;
+ switch (i)
+ {
+ case 0:
+ gSelectedOrderFromParty[0] = gSelectedOrderFromParty[1];
+ gSelectedOrderFromParty[1] = gSelectedOrderFromParty[2];
+ gSelectedOrderFromParty[2] = 0;
+ break;
+ case 1:
+ gSelectedOrderFromParty[1] = gSelectedOrderFromParty[2];
+ gSelectedOrderFromParty[2] = 0;
+ break;
+ }
+ break; // exit loop
+ }
+ }
+ sub_806BC3C(gLastFieldPokeMenuOpened, 0x70);
+ if (gSelectedOrderFromParty[0] != 0)
+ sub_806BC3C(gSelectedOrderFromParty[0] - 1, 0x1C);
+ if (gSelectedOrderFromParty[1] != 0)
+ sub_806BC3C(gSelectedOrderFromParty[1] - 1, 0x2A);
+ BattleTowerEntryMenuCallback_Exit(taskId);
+}
+
+static void sub_81227FC(u8 taskId)
+{
+ MenuZeroFillWindowRect(20, 10, 29, 19);
+ HandleDestroyMenuCursors();
+ sub_806D538(0, 0);
+ gTasks[taskId].func = sub_81222B0;
+}
+
+static void BattleTowerEntryMenuCallback_Exit(u8 taskId)
+{
+ PlaySE(SE_SELECT);
+ sub_81227FC(taskId);
+}
+
+bool8 sub_8122854(void)
+{
+ switch (ewram1B000_alt.unk264)
+ {
+ case 0:
+ sub_81228E8(ewram1B000_alt.unk260);
+ ewram1B000_alt.unk264++;
+ break;
+ case 1:
+ LoadHeldItemIconGraphics();
+ ewram1B000_alt.unk264++;
+ break;
+ case 2:
+ sub_8122950(ewram1B000_alt.unk260);
+ ewram1B000_alt.unk264++;
+ break;
+ case 3:
+ sub_81229B8();
+ ewram1B000_alt.unk264++;
+ break;
+ case 4:
+ sub_806B908();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void sub_81228E8(u8 a)
+{
+ u8 i;
+
+ for (i = 0; i < 3; i++)
+ {
+ if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) != 0)
+ CreatePartyMenuMonIcon(a, i, 3, &gPlayerParty[i]);
+ if (gUnknown_02023A00[i].species != 0)
+ {
+ CreateMonIcon_806D99C(a, i + 3, 3, &gUnknown_02023A00[i]);
+ sub_806D50C(a, i + 3);
+ }
+ }
+}
+
+static void sub_8122950(u8 a)
+{
+ u8 i;
+
+ for (i = 0; i < 3; i++)
+ {
+ if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) != 0)
+ {
+ u16 item = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM);
+
+ CreateHeldItemIcon_806DCD4(a, i, item);
+ }
+ if (gUnknown_02023A00[i].species != 0)
+ CreateHeldItemIcon_806DCD4(a, i + 3, gUnknown_02023A00[i].heldItem);
+ }
+}
+
+static void sub_81229B8(void)
+{
+ u8 i;
+
+ for (i = 0; i < 3; i++)
+ {
+ if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) != 0)
+ {
+ u8 status;
+
+ PartyMenuPrintHP(i, 3, &gPlayerParty[i]);
+ status = GetMonStatusAndPokerus(&gPlayerParty[i]);
+ if (status != 0 && status != 6)
+ PartyMenuPutStatusTilemap(i, 3, status - 1);
+ else
+ PartyMenuPrintLevel(i, 3, &gPlayerParty[i]);
+ PartyMenuPutNicknameTilemap(i, 3, &gPlayerParty[i]);
+ PrintPartyMenuMonNickname(i, 3, &gPlayerParty[i]);
+ PartyMenuDrawHPBar(i, 3, &gPlayerParty[i]);
+ }
+ }
+}
+
+void sub_8122A48(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ gTasks[taskId].data[0] = 30;
+ sub_806D4AC(taskId, gUnknown_02023A00[0].species, 0);
+ sub_806D4AC(taskId, gUnknown_02023A00[1].species, 1);
+ sub_806D4AC(taskId, gUnknown_02023A00[2].species, 2);
+ gTasks[taskId].func = sub_8122AB8;
+ ewram1B000.unk261 = 1;
+ }
+}
+
+static void sub_8122AB8(u8 taskId)
+{
+ sub_806D3B4(taskId, gUnknown_02023A00[1].species, gUnknown_02023A00[2].species);
+ if (gTasks[taskId].data[0] == 0)
+ {
+ gTasks[taskId].func = sub_8122B10;
+ ewram1B000.unk261 = 2;
+ PlaySE(SE_W231);
+ }
+}
+
+static void sub_8122B10(u8 taskId)
+{
+ u8 i;
+
+ for (i = 0; i < 3; i++)
+ {
+ if (gUnknown_02023A00[i].species != 0)
+ {
+ u8 r2;
+
+ PartyMenuDoPrintHP(i + 3, 3, gUnknown_02023A00[i].hp, gUnknown_02023A00[i].maxhp);
+ if (gUnknown_02023A00[i].hp == 0)
+ r2 = 7;
+ else
+ r2 = pokemon_ailments_get_primary(gUnknown_02023A00[i].status);
+ if (r2 != 0)
+ PartyMenuPutStatusTilemap(i + 3, 3, r2 - 1);
+ else
+ PartyMenuDoPrintLevel(i + 3, 3, gUnknown_02023A00[i].level);
+ PartyMenuDoPutNicknameTilemap(gUnknown_02023A00[i].species, gUnknown_02023A00[i].gender, 3, i + 3, gUnknown_02023A00[i].nickname);
+ StringCopy(gStringVar1, gUnknown_02023A00[i].nickname);
+ StringGetEnd10(gStringVar1);
+ SanitizeNameString(gStringVar1);
+ box_print(i + 3, 3, gStringVar1);
+ PartyMenuDoDrawHPBar(i + 3, 3, gUnknown_02023A00[i].hp, gUnknown_02023A00[i].maxhp);
+ }
+ }
+ gTasks[taskId].func = sub_8122C18;
+ gTasks[taskId].data[0] = 0;
+}
+
+static void sub_8122C18(u8 taskId)
+{
+ gTasks[taskId].data[0]++;
+ if (gTasks[taskId].data[0] == 256)
+ {
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0);
+ gTasks[taskId].func = sub_8122450;
+ }
+}
+
+// Exactly the same as sub_8121E78 except for case 6
+bool8 unref_sub_8122C60(void)
+{
+ switch (ewram1B000_alt.unk264)
+ {
+ case 0:
+ if (ewram1B000_alt.unk266 < gPlayerPartyCount)
+ {
+ TryCreatePartyMenuMonIcon(ewram1B000_alt.unk260, ewram1B000_alt.unk266, &gPlayerParty[ewram1B000_alt.unk266]);
+ ewram1B000_alt.unk266++;
+ }
+ else
+ {
+ ewram1B000_alt.unk266 = 0;
+ ewram1B000_alt.unk264++;
+ }
+ break;
+ case 1:
+ LoadHeldItemIconGraphics();
+ ewram1B000_alt.unk264++;
+ break;
+ case 2:
+ CreateHeldItemIcons_806DC34(ewram1B000_alt.unk260);
+ ewram1B000_alt.unk264++;
+ break;
+ case 3:
+ if (sub_806BD58(ewram1B000_alt.unk260, ewram1B000_alt.unk266) == 1)
+ {
+ ewram1B000_alt.unk266 = 0;
+ ewram1B000_alt.unk264++;
+ }
+ else
+ {
+ ewram1B000_alt.unk266++;
+ }
+ break;
+ case 4:
+ PartyMenuPrintMonsLevelOrStatus();
+ ewram1B000_alt.unk264++;
+ break;
+ case 5:
+ PrintPartyMenuMonNicknames();
+ ewram1B000_alt.unk264++;
+ break;
+ case 6:
+ sub_806BCE8();
+ ewram1B000_alt.unk264++;
+ break;
+ case 7:
+ if (sub_806B58C(ewram1B000_alt.unk266) == 1)
+ {
+ ewram1B000_alt.unk266 = 0;
+ ewram1B000_alt.unk264 = 0;
+ return TRUE;
+ }
+ else
+ {
+ ewram1B000_alt.unk266++;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+//------------------------------------------------------------------------------
+// Daycare Pokemon Storage Menu
+//------------------------------------------------------------------------------
+
+static void DaycareStorageMenuCallback_Store(u8);
+static void DaycareStorageMenuCallback_Summary(u8);
+static void DaycareStorageMenuCallback_Exit(u8);
+
+static const struct PartyMenuItem sDaycareStorageMenuItems[] =
+{
+ {OtherText_Store, DaycareStorageMenuCallback_Store},
+ {OtherText_Summary, DaycareStorageMenuCallback_Summary},
+ {gUnknownText_Exit, DaycareStorageMenuCallback_Exit},
+};
+
+static const u8 gUnknown_08401808[] = {0, 1, 2};
+static const u8 gUnknown_0840180B[] = {1, 2};
+
+static const struct PartyPopupMenu sDaycareStorageMenus[] =
+{
+ {ARRAY_COUNT(gUnknown_08401808), 9, gUnknown_08401808},
+ {ARRAY_COUNT(gUnknown_0840180B), 9, gUnknown_0840180B},
+};
+
+static void sub_8122D94(u8 taskId)
+{
+ if (!GetMonData(&gPlayerParty[gLastFieldPokeMenuOpened], MON_DATA_IS_EGG))
+ {
+ gTasks[taskId].data[4] = 0;
+ sub_806E750(0, sDaycareStorageMenus, sDaycareStorageMenuItems, 0);
+ }
+ else
+ {
+ gTasks[taskId].data[4] = 1;
+ sub_806E750(1, sDaycareStorageMenus, sDaycareStorageMenuItems, 0);
+ }
+}
+
+void sub_8122E0C(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ switch (sub_806BD80(taskId))
+ {
+ case 1:
+ PlaySE(SE_SELECT);
+ gLastFieldPokeMenuOpened = sub_806CA38(taskId);
+ GetMonNickname(&gPlayerParty[gLastFieldPokeMenuOpened], gStringVar1);
+ sub_8122D94(taskId);
+ gTasks[taskId].func = Task_DaycareStorageMenu8122EAC;
+ break;
+ case 2:
+ PlaySE(SE_SELECT);
+ gLastFieldPokeMenuOpened = 0xFF;
+ gSpecialVar_0x8004 = 0xFF;
+ sub_8123138(taskId);
+ break;
+ }
+ }
+}
+
+static void Task_DaycareStorageMenu8122EAC(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ if (gMain.newAndRepeatedKeys & 0x40)
+ {
+ if (GetMenuCursorPos() != 0)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor(-1);
+ }
+ return;
+ }
+ if (gMain.newAndRepeatedKeys & 0x80)
+ {
+ if (GetMenuCursorPos() != 3)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor(1);
+ }
+ return;
+ }
+ if (gMain.newKeys & A_BUTTON)
+ {
+ TaskFunc popupMenuFunc;
+
+ PlaySE(SE_SELECT);
+ popupMenuFunc = PartyMenuGetPopupMenuFunc(
+ gTasks[taskId].data[4],
+ sDaycareStorageMenus,
+ sDaycareStorageMenuItems,
+ GetMenuCursorPos());
+ popupMenuFunc(taskId);
+ return;
+ }
+ if (gMain.newKeys & B_BUTTON)
+ {
+ DaycareStorageMenuCallback_Exit(taskId);
+ return;
+ }
+ }
+}
+
+static void DaycareStorageMenuCallback_Store(u8 taskId)
+{
+ gSpecialVar_0x8004 = gLastFieldPokeMenuOpened;
+ sub_8123138(taskId);
+}
+
+static void sub_8122F90(void)
+{
+ while (1)
+ {
+ if (sub_806B124() == 1)
+ {
+ sub_806C994(ewram1B000.unk260, gUnknown_020384F0);
+ sub_806BF74(ewram1B000.unk260, 0);
+ GetMonNickname(&gPlayerParty[gUnknown_020384F0], gStringVar1);
+ gLastFieldPokeMenuOpened = gUnknown_020384F0;
+ sub_8122D94(ewram1B000.unk260);
+ SetMainCallback2(sub_806AEDC);
+ break;
+ }
+ if (sub_80F9344() == 1)
+ break;
+ }
+}
+
+static void sub_8123004(void)
+{
+ gPaletteFade.bufferTransferDisabled = TRUE;
+ sub_806AF4C(6, 0xFF, Task_DaycareStorageMenu8122EAC, 5);
+ SetMainCallback2(sub_8122F90);
+}
+
+static void sub_8123034(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ u8 r4 = gSprites[gTasks[taskId].data[3] >> 8].data0;
+
+ DestroyTask(taskId);
+ ewram1B000.unk262 = 1;
+ ShowPokemonSummaryScreen(gPlayerParty, r4, gPlayerPartyCount - 1, sub_8123004, 0);
+ }
+}
+
+static void DaycareStorageMenuCallback_Summary(u8 taskId)
+{
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0);
+ gTasks[taskId].func = sub_8123034;
+}
+
+static void DaycareStorageMenuCallback_Exit(u8 taskId)
+{
+ PlaySE(SE_SELECT);
+ MenuZeroFillWindowRect(20, 10, 29, 19);
+ HandleDestroyMenuCursors();
+ sub_806D538(15, 0);
+ gTasks[taskId].func = sub_8122E0C;
+}
+
+void sub_8123138(u8 taskId)
+{
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0);
+ gTasks[taskId].func = sub_8123170;
+}
+
+static void sub_8123170(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ gFieldCallback = sub_81231AC;
+ SetMainCallback2(c2_exit_to_overworld_2_switch);
+ DestroyTask(taskId);
+ }
+}
+
+// Do these last two functions really belong in here?
+
+static void sub_81231C4(u8);
+
+void sub_81231AC(void)
+{
+ pal_fill_black();
+ CreateTask(sub_81231C4, 10);
+}
+
+static void sub_81231C4(u8 taskId)
+{
+ if (sub_807D770() == TRUE)
+ {
+ DestroyTask(taskId);
+ ScriptContext2_Disable();
+ EnableBothScriptContexts();
+ }
+}
diff --git a/src/field/coins.c b/src/field/coins.c
new file mode 100644
index 000000000..91a4b508d
--- /dev/null
+++ b/src/field/coins.c
@@ -0,0 +1,84 @@
+#include "global.h"
+#include "coins.h"
+#include "menu.h"
+#include "string_util.h"
+#include "strings.h"
+
+#define MAX_COINS 9999
+
+void UpdateCoinsWindow(s32 coins, u8 x, u8 y)
+{
+ PrintCoins(coins, 4, x + 2, y + 1);
+}
+
+void ShowCoinsWindow(u32 coins, u8 x, u8 y)
+{
+ MenuDrawTextWindow(x, y, x + 9, y + 3);
+ UpdateCoinsWindow(coins, x, y);
+}
+
+void HideCoinsWindow(u8 x, u8 y)
+{
+ MenuZeroFillWindowRect(x, y, x + 9, y + 3);
+}
+
+void PrintCoins(s32 coins, u8 b, u8 x, u8 y)
+{
+ u8 string[16];
+ u8 *ptr;
+ u8 r1;
+ u8 foo;
+
+ ConvertIntToDecimalString(string, coins);
+ r1 = (b * 6 + 0x21 - 8 * (b + 2));
+ x = x - r1 / 8;
+ foo = r1 % 8;
+ ptr = gStringVar1;
+ if (foo)
+ {
+ ptr[0] = EXT_CTRL_CODE_BEGIN;
+ ptr[1] = 0x11;
+ ptr[2] = 8 - (foo);
+ ptr += 3;
+ }
+ ptr[0] = EXT_CTRL_CODE_BEGIN;
+ ptr[1] = 0x11;
+ ptr[2] = (b - StringLength(string)) * 6;
+ ptr += 3;
+ StringCopy(ptr, string);
+ MenuPrint(gOtherText_Coins2, x, y);
+}
+
+u16 GetCoins(void)
+{
+ return gSaveBlock1.coins;
+}
+
+bool8 GiveCoins(u16 coins)
+{
+ u32 newCoins;
+
+ if (GetCoins() >= MAX_COINS)
+ return FALSE;
+ newCoins = coins + gSaveBlock1.coins;
+ if (gSaveBlock1.coins > (u16)newCoins)
+ gSaveBlock1.coins = MAX_COINS;
+ else
+ {
+ gSaveBlock1.coins = newCoins;
+ if ((u16)newCoins > MAX_COINS)
+ gSaveBlock1.coins = MAX_COINS;
+ }
+ return TRUE;
+}
+
+bool8 TakeCoins(u16 coins)
+{
+ if (GetCoins() >= coins)
+ {
+ gSaveBlock1.coins -= coins;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
diff --git a/src/field/coord_event_weather.c b/src/field/coord_event_weather.c
new file mode 100644
index 000000000..9c5a1ca4d
--- /dev/null
+++ b/src/field/coord_event_weather.c
@@ -0,0 +1,118 @@
+#include "global.h"
+#include "coord_event_weather.h"
+#include "field_weather.h"
+
+struct CoordEventWeather
+{
+ u8 weather;
+ void (*func)(void);
+};
+
+static void CoordEventWeather_Indoor(void);
+static void CoordEventWeather_Sunny(void);
+static void CoordEventWeather_Rain(void);
+static void CoordEventWeather_Snowflakes(void);
+static void CoordEventWeather_Thunderstorm(void);
+static void CoordEventWeather_Fog(void);
+static void CoordEventWeather_DiagonalFog(void);
+static void CoordEventWeather_Snow(void);
+static void CoordEventWeather_Sandstorm(void);
+static void CoordEventWeather_Cloudy(void);
+static void CoordEventWeather_Drought(void);
+static void CoordEventWeather_UnderwaterFog(void);
+static void CoordEventWeather_UnderwaterBubbles(void);
+
+static const struct CoordEventWeather sCoordEventWeatherFuncs[] =
+{
+ { 0x1, CoordEventWeather_Indoor },
+ { 0x2, CoordEventWeather_Sunny },
+ { 0x3, CoordEventWeather_Rain },
+ { 0x4, CoordEventWeather_Snowflakes },
+ { 0x5, CoordEventWeather_Thunderstorm },
+ { 0x6, CoordEventWeather_Fog },
+ { 0x7, CoordEventWeather_DiagonalFog },
+ { 0x8, CoordEventWeather_Snow },
+ { 0x9, CoordEventWeather_Sandstorm },
+ { 0xa, CoordEventWeather_Cloudy },
+ { 0xb, CoordEventWeather_Drought },
+ { 0x14, CoordEventWeather_UnderwaterFog },
+ { 0x15, CoordEventWeather_UnderwaterBubbles },
+};
+
+static void CoordEventWeather_Indoor(void)
+{
+ SetWeather(1);
+}
+
+static void CoordEventWeather_Sunny(void)
+{
+ SetWeather(2);
+}
+
+static void CoordEventWeather_Rain(void)
+{
+ SetWeather(3);
+}
+
+static void CoordEventWeather_Snowflakes(void)
+{
+ SetWeather(4);
+}
+
+static void CoordEventWeather_Thunderstorm(void)
+{
+ SetWeather(5);
+}
+
+static void CoordEventWeather_Fog(void)
+{
+ SetWeather(6);
+}
+
+static void CoordEventWeather_DiagonalFog(void)
+{
+ SetWeather(9);
+}
+
+static void CoordEventWeather_Snow(void)
+{
+ SetWeather(7);
+}
+
+static void CoordEventWeather_Sandstorm(void)
+{
+ SetWeather(8);
+}
+
+static void CoordEventWeather_Cloudy(void)
+{
+ SetWeather(11);
+}
+
+static void CoordEventWeather_Drought(void)
+{
+ SetWeather(12);
+}
+
+static void CoordEventWeather_UnderwaterFog(void)
+{
+ SetWeather(20);
+}
+
+static void CoordEventWeather_UnderwaterBubbles(void)
+{
+ SetWeather(21);
+}
+
+void DoCoordEventWeather(u8 n)
+{
+ u8 i;
+ for (i = 0; i < ARRAY_COUNT(sCoordEventWeatherFuncs); i++)
+ {
+ if (sCoordEventWeatherFuncs[i].weather == n)
+ {
+ sCoordEventWeatherFuncs[i].func();
+ return;
+ }
+ }
+}
diff --git a/src/field/daycare.c b/src/field/daycare.c
new file mode 100644
index 000000000..591b5b188
--- /dev/null
+++ b/src/field/daycare.c
@@ -0,0 +1,1690 @@
+#include "global.h"
+#include "daycare.h"
+#include "pokemon.h"
+#include "event_data.h"
+#include "species.h"
+#include "items.h"
+#include "text.h"
+#include "string_util.h"
+#include "mail_data.h"
+#include "name_string_util.h"
+#include "pokemon_storage_system.h"
+#include "rng.h"
+#include "moves.h"
+#include "trade.h"
+#include "strings2.h"
+#include "data/pokemon/egg_moves.h"
+#include "party_menu.h"
+#include "field_effect.h"
+#include "main.h"
+#include "menu.h"
+#include "sound.h"
+#include "songs.h"
+#include "script.h"
+#include "overworld.h"
+
+IWRAM_DATA u16 gUnknown_03000470[52];
+IWRAM_DATA u16 gUnknown_030004D8[4];
+IWRAM_DATA u16 gUnknown_030004E0[4];
+IWRAM_DATA u16 gUnknown_030004E8[12];
+IWRAM_DATA u16 gUnknown_03000500[4];
+
+static void sub_80417F4(struct DayCareMail *);
+static void sub_80420FC(struct Pokemon *, u16, struct DayCareData *);
+static u8 daycare_relationship_score(struct DayCareData *);
+
+const u8 *const gUnknown_08209AC4[] = {
+ DaycareText_GetAlongVeryWell,
+ DaycareText_GetAlong,
+ DaycareText_DontLikeOther,
+ DaycareText_PlayOther
+};
+
+const u8 gUnknown_08209AD4[] = _("タマゴ");
+
+u8 *GetMonNick(struct Pokemon *mon, u8 *dest)
+{
+ s8 nickname[POKEMON_NAME_LENGTH * 2];
+
+ GetMonData(mon, MON_DATA_NICKNAME, nickname);
+ return StringCopy10(dest, nickname);
+}
+
+u8 *GetBoxMonNick(struct BoxPokemon *mon, u8 *dest)
+{
+ s8 nickname[POKEMON_NAME_LENGTH * 2];
+
+ GetBoxMonData(mon, MON_DATA_NICKNAME, nickname);
+ return StringCopy10(dest, nickname);
+}
+
+u8 Daycare_CountPokemon(struct DayCareData *daycare_data)
+{
+ u8 i, count;
+ count = 0;
+
+ for(i = 0;i <= 1;i++)
+ if(GetBoxMonData(&daycare_data->mons[i], MON_DATA_SPECIES) != 0)
+ count++;
+
+ return count;
+}
+
+void sub_8041324(struct BoxPokemon * box_pokemon, struct RecordMixingDayCareMail * daycareMailEtc)
+{
+ u8 i;
+ u8 specCount;
+ specCount = 0;
+ for (i=0; i<2; i++)
+ {
+ if (GetBoxMonData(&box_pokemon[i], MON_DATA_SPECIES) != SPECIES_NONE)
+ {
+ specCount ++;
+ if (GetBoxMonData(&box_pokemon[i], MON_DATA_HELD_ITEM) == ITEM_NONE)
+ {
+ daycareMailEtc->unk74[i] = 0;
+ } else
+ {
+ daycareMailEtc->unk74[i] = 1;
+ }
+ } else
+ {
+ daycareMailEtc->unk74[i] = 1;
+ }
+ }
+ daycareMailEtc->unk70 = specCount;
+}
+
+static s8 Daycare_FindEmptySpot(struct BoxPokemon * daycare_data)
+{
+ u8 i;
+
+ for(i = 0;i <= 1;i++)
+ if(GetBoxMonData(daycare_data + i, MON_DATA_SPECIES) == 0)
+ return i;
+
+ return -1;
+}
+
+static void Daycare_SendPokemon(struct Pokemon * mon, struct DayCareData * daycare_data)
+{
+ s8 empty_slot;
+ u8 mail;
+ u8 *names;
+
+ empty_slot = Daycare_FindEmptySpot(daycare_data->mons);
+ if(MonHasMail(mon)) {
+ StringCopy((names = daycare_data->misc.mail[empty_slot].names), gSaveBlock2.playerName);
+ PadNameString(names, 0xFC);
+ names += 8;
+ GetMonNick(mon, names);
+ mail = GetMonData(mon, MON_DATA_MAIL);
+ daycare_data->misc.mail[empty_slot].message = gSaveBlock1.mail[mail];
+ TakeMailFromMon(mon);
+ }
+ daycare_data->mons[empty_slot] = mon->box;
+ BoxMonRestorePP(&daycare_data->mons[empty_slot]);
+ daycare_data->misc.countersEtc.steps[empty_slot] = 0;
+ ZeroMonData(mon);
+ party_compaction();
+ CalculatePlayerPartyCount();
+}
+
+void Daycare_SendPokemon_Special()
+{
+ Daycare_SendPokemon(gPlayerParty + gLastFieldPokeMenuOpened, &gSaveBlock1.daycareData);
+}
+
+static void sub_80414C0(struct DayCareData * daycare_data)
+{
+ if((GetBoxMonData(&daycare_data->mons[1], MON_DATA_SPECIES) != 0) && GetBoxMonData(&daycare_data->mons[0], MON_DATA_SPECIES) == 0)
+ {
+ daycare_data->mons[0] = daycare_data->mons[1];
+ ZeroBoxMonData(&daycare_data->mons[1]);
+ daycare_data->misc.mail[0] = daycare_data->misc.mail[1];
+ daycare_data->misc.countersEtc.steps[0] = daycare_data->misc.countersEtc.steps[1];
+ daycare_data->misc.countersEtc.steps[1] = 0;
+ sub_80417F4(&daycare_data->misc.mail[1]);
+ }
+}
+
+u8 TryIncrementMonLevel(struct Pokemon *);
+extern u16 gMoveToLearn;
+
+static void DayCare_LevelUpMoves(struct Pokemon * mon)
+{
+ s32 i;
+ u8 r6;
+ u16 temp;
+
+ for (i = 0; i < MAX_LEVEL; i++)
+ {
+ if (TryIncrementMonLevel(mon))
+ {
+ r6 = 1;
+ while ((temp = MonTryLearningNewMove(mon, r6)) != 0)
+ {
+ r6 = 0;
+ if (temp == 0xffff)
+ DeleteFirstMoveAndGiveMoveToMon(mon, gMoveToLearn);
+ }
+ }
+ else
+ break;
+ }
+
+ CalculateMonStats(mon);
+}
+
+static u16 sub_8041570(struct DayCareData * daycare_data, u8 slot)
+{
+ u16 species;
+ u32 experience;
+ struct Pokemon pokemon;
+
+ GetBoxMonNick(&daycare_data->mons[slot], gStringVar1);
+ species = GetBoxMonData(&daycare_data->mons[slot], MON_DATA_SPECIES);
+ sub_803B4B4(&daycare_data->mons[slot], &pokemon);
+ if (GetMonData(&pokemon, MON_DATA_LEVEL) != MAX_LEVEL)
+ {
+ experience = GetMonData(&pokemon, MON_DATA_EXP) + daycare_data->misc.countersEtc.steps[slot];
+ SetMonData(&pokemon, MON_DATA_EXP, (u8 *)&experience);
+ DayCare_LevelUpMoves(&pokemon);
+ }
+ gPlayerParty[PARTY_SIZE - 1] = pokemon;
+ if (daycare_data->misc.mail[slot].message.itemId)
+ {
+ GiveMailToMon2(&gPlayerParty[PARTY_SIZE - 1], &daycare_data->misc.mail[slot].message);
+ sub_80417F4(&daycare_data->misc.mail[slot]);
+ }
+ party_compaction();
+ ZeroBoxMonData(&daycare_data->mons[slot]);
+ daycare_data->misc.countersEtc.steps[slot] = 0;
+ sub_80414C0(daycare_data);
+ CalculatePlayerPartyCount();
+ return species;
+}
+
+u16 sub_8041648()
+{
+ return sub_8041570(&gSaveBlock1.daycareData, gSpecialVar_0x8004);
+}
+
+u8 Daycare_GetLevelAfterSteps(struct BoxPokemon * mon, u32 steps){
+ struct BoxPokemon temp = *mon;
+ u32 new_exp = GetBoxMonData(mon, MON_DATA_EXP) + steps;
+ SetBoxMonData(&temp, MON_DATA_EXP, (u8 *) &new_exp);
+ return GetLevelFromBoxMonExp(&temp);
+}
+
+static u8 sub_80416A0(struct DayCareData *daycareData, u8 slot)
+{
+ u8 levelBefore;
+ u8 levelAfter;
+
+ levelBefore = GetLevelFromBoxMonExp(&daycareData->mons[slot]);
+ levelAfter = Daycare_GetLevelAfterSteps(&daycareData->mons[slot], daycareData->misc.countersEtc.steps[slot]);
+ return levelAfter - levelBefore;
+}
+
+static u8 sub_80416E8(struct DayCareData *dayCareData, u8 slot)
+{
+ u8 levelDelta = sub_80416A0(dayCareData, slot);
+ GetBoxMonNick(&dayCareData->mons[slot], gStringVar1);
+ ConvertIntToDecimalStringN(gStringVar2, levelDelta, STR_CONV_MODE_LEFT_ALIGN, 2);
+ return levelDelta;
+}
+
+static u16 sub_8041728(struct DayCareData *dayCareData, u8 slot)
+{
+ u16 cost;
+
+ u8 levelDelta = sub_80416A0(dayCareData, slot);
+ GetBoxMonNick(&dayCareData->mons[slot], gStringVar1);
+ cost = 100 + 100 * levelDelta;
+ ConvertIntToDecimalStringN(gStringVar2, cost, STR_CONV_MODE_LEFT_ALIGN, 5);
+ return cost;
+}
+
+void sub_8041770(void)
+{
+ gSpecialVar_0x8005 = sub_8041728(&gSaveBlock1.daycareData, gSpecialVar_0x8004);
+}
+
+void sub_8041790(u16 i)
+{
+ gSaveBlock1.daycareData.misc.countersEtc.steps[0] += i;
+ gSaveBlock1.daycareData.misc.countersEtc.steps[1] += i;
+}
+
+u8 sub_80417B8(void)
+{
+ if (GetBoxMonData(&gSaveBlock1.daycareData.mons[gSpecialVar_0x8004], MON_DATA_SPECIES) != 0)
+ return sub_80416E8(&gSaveBlock1.daycareData, gSpecialVar_0x8004);
+ return 0;
+}
+
+static void sub_80417F4(struct DayCareMail *mail)
+{
+ u8 zero;
+ u8 *names;
+ u8 *names2;
+ int i;
+ zero = 0;
+ for (i = 7, names = mail->names + 7; i >= 0; i --)
+ *names-- = zero;
+ names2 = mail->names + 8;
+ zero = 0;
+ names = mail->names + 18;
+ do *names-- = zero; while ((int)names >= (int)names2);
+ ClearMailStruct(&mail->message);
+}
+
+void unref_sub_8041824(struct DayCareData *dayCareData)
+{
+ u8 slot;
+ for (slot = 0; slot < ARRAY_COUNT(dayCareData->mons); slot ++)
+ {
+ ZeroBoxMonData(&dayCareData->mons[slot]);
+ dayCareData->misc.countersEtc.steps[slot] = 0;
+ sub_80417F4(&dayCareData->misc.mail[slot]);
+ }
+ dayCareData->misc.countersEtc.personalityLo = 0;
+ dayCareData->misc.countersEtc.unk_11a = 0;
+}
+
+u16 sub_8041870(u16 species)
+{
+ int i, j, k;
+ bool8 found;
+ for (i = 0; i < 5; i ++)
+ {
+ found = FALSE;
+ for (j = 1; j < NUM_SPECIES; j ++)
+ {
+ for (k = 0; k < 5; k ++)
+ {
+ if (gEvolutionTable[j].evolutions[k].targetSpecies == species)
+ {
+ species = j;
+ found = TRUE;
+ break;
+ }
+ }
+ if (found)
+ break;
+ }
+ if (j == 412)
+ break;
+ }
+ return species;
+}
+
+static void sub_80418F0(struct DayCareData *dayCareData)
+{
+ dayCareData->misc.countersEtc.personalityLo = (Random() % 0xfffe) + 1;
+ FlagSet(0x86);
+}
+
+static void sub_804191C(struct DayCareData *dayCareData)
+{
+ dayCareData->misc.countersEtc.personalityLo = Random() | 0x8000;
+ FlagSet(0x86);
+}
+
+void sub_8041940(void)
+{
+ sub_80418F0(&gSaveBlock1.daycareData);
+}
+
+void sub_8041950(void)
+{
+ sub_804191C(&gSaveBlock1.daycareData);
+}
+
+static void sub_8041960(u8 *data, u8 idx)
+{
+ int i, j;
+ u8 temp[6];
+ data[idx] = 0xff;
+ for (i = 0; i < 6; i ++)
+ temp[i] = data[i];
+ j = 0;
+ for (i = 0; i < 6; i ++)
+ if (temp[i] != 0xff)
+ data[j++] = temp[i];
+}
+
+static void InheritIVs(struct Pokemon *egg, struct DayCareData *dayCareData)
+{
+ u8 i;
+ u8 selectedIvs[3];
+ u8 allIvs[6];
+ u8 whichParent[3];
+ u8 iv;
+ for (i = 0; i < 6; i ++)
+ allIvs[i] = i;
+ for (i = 0; i < 3; i ++)
+ {
+ selectedIvs[i] = allIvs[Random() % (6 - i)];
+ sub_8041960(allIvs, selectedIvs[i]);
+ }
+ for (i = 0; i < 3; i ++)
+ whichParent[i] = Random() % 2;
+ for (i = 0; i < 3; i ++)
+ {
+ switch (selectedIvs[i])
+ {
+ case 0:
+ iv = GetBoxMonData(&dayCareData->mons[whichParent[i]], MON_DATA_HP_IV);
+ SetMonData(egg, MON_DATA_HP_IV, &iv);
+ break;
+ case 1:
+ iv = GetBoxMonData(&dayCareData->mons[whichParent[i]], MON_DATA_ATK_IV);
+ SetMonData(egg, MON_DATA_ATK_IV, &iv);
+ break;
+ case 2:
+ iv = GetBoxMonData(&dayCareData->mons[whichParent[i]], MON_DATA_DEF_IV);
+ SetMonData(egg, MON_DATA_DEF_IV, &iv);
+ break;
+ case 3:
+ iv = GetBoxMonData(&dayCareData->mons[whichParent[i]], MON_DATA_SPD_IV);
+ SetMonData(egg, MON_DATA_SPD_IV, &iv);
+ break;
+ case 4:
+ iv = GetBoxMonData(&dayCareData->mons[whichParent[i]], MON_DATA_SPATK_IV);
+ SetMonData(egg, MON_DATA_SPATK_IV, &iv);
+ break;
+ case 5:
+ iv = GetBoxMonData(&dayCareData->mons[whichParent[i]], MON_DATA_SPDEF_IV);
+ SetMonData(egg, MON_DATA_SPDEF_IV, &iv);
+ break;
+ }
+ }
+}
+
+#ifdef NONMATCHING
+static
+#endif
+u8 pokemon_get_eggmoves(struct Pokemon *pokemon, u16 *eggMoves)
+{
+ u16 eggMoveIdx;
+ u16 numMovesFound;
+ u16 species;
+ u16 i;
+
+ numMovesFound = 0;
+ eggMoveIdx = 0;
+ species = GetMonData(pokemon, MON_DATA_SPECIES);
+ for (i = 0; i < ARRAY_COUNT(gEggMoves) - 1; i ++)
+ {
+ if (gEggMoves[i] == species + EGG_MOVES_SPECIES_OFFSET)
+ {
+ eggMoveIdx = i + 1;
+ break;
+ }
+ }
+ for (i = 0; i < 10; i ++)
+ {
+ if (gEggMoves[eggMoveIdx + i] > EGG_MOVES_SPECIES_OFFSET)
+ {
+ break;
+ }
+ eggMoves[i] = gEggMoves[eggMoveIdx + i];
+ numMovesFound++;
+ }
+ return numMovesFound;
+}
+
+#ifdef NONMATCHING
+
+void daycare_build_child_moveset(struct Pokemon *egg, struct BoxPokemon *dad, struct BoxPokemon *mom)
+{
+ u16 numSharedParentMoves;
+ u8 numLevelUpMoves;
+ u8 numEggMoves;
+ u16 i, j;
+
+ numSharedParentMoves = 0;
+ for (i = 0; i < 4; i ++)
+ {
+ gUnknown_03000500[i] = 0;
+ gUnknown_030004D8[i] = 0;
+ gUnknown_030004E0[i] = 0;
+ }
+ for (i = 0; i < 10; i ++)
+ gUnknown_030004E8[i] = 0;
+ for (i = 0; i < 50; i ++)
+ gUnknown_03000470[i] = 0;
+
+ numLevelUpMoves = GetLevelUpMovesBySpecies(GetMonData(egg, MON_DATA_SPECIES), gUnknown_03000470);
+ for (i = 0; i < 4; i ++)
+ {
+ gUnknown_030004D8[i] = GetBoxMonData(dad, MON_DATA_MOVE1 + i);
+ gUnknown_03000500[i] = GetBoxMonData(mom, MON_DATA_MOVE1 + i);
+ }
+ numEggMoves = pokemon_get_eggmoves(egg, gUnknown_030004E8);
+
+ for (i = 0; i < 4; i ++)
+ {
+ if (gUnknown_030004D8[i] != MOVE_NONE)
+ {
+ for (j = 0; j < numEggMoves; j ++)
+ {
+ if (gUnknown_030004D8[i] == gUnknown_030004E8[j])
+ {
+ if (GiveMoveToMon(egg, gUnknown_030004D8[i]) == 0xffff)
+ DeleteFirstMoveAndGiveMoveToMon(egg, gUnknown_030004D8[i]);
+ break;
+ }
+ }
+ }
+ else
+ break;
+ }
+ for (i = 0; i < 4; i ++)
+ {
+ if (gUnknown_030004D8[i] != MOVE_NONE)
+ {
+ for (j = 0; j < 50 + 8; j ++)
+ {
+ if (gUnknown_030004D8[i] == ItemIdToBattleMoveId(ITEM_TM01 + j) && CanMonLearnTMHM(egg, j))
+ {
+ if (GiveMoveToMon(egg, gUnknown_030004D8[i]) == 0xffff)
+ DeleteFirstMoveAndGiveMoveToMon(egg, gUnknown_030004D8[i]);
+ }
+ }
+ }
+ }
+ for (i = 0; i < 4; i ++)
+ {
+ if (gUnknown_030004D8[i] == MOVE_NONE)
+ break;
+ for (j = 0; j < 4; j ++)
+ {
+ if (gUnknown_030004D8[i] == gUnknown_03000500[j] && gUnknown_030004D8[i] != MOVE_NONE)
+ gUnknown_030004E0[numSharedParentMoves++] = gUnknown_030004D8[i];
+ }
+ }
+ for (i = 0; i < 4; i ++)
+ {
+ if (gUnknown_030004E0[i] == MOVE_NONE)
+ break;
+ for (j = 0; j < numLevelUpMoves; j ++)
+ {
+ if (gUnknown_03000470[j] != MOVE_NONE && gUnknown_030004E0[i] == gUnknown_03000470[j])
+ {
+ if (GiveMoveToMon(egg, gUnknown_030004E0[i]) == 0xffff)
+ DeleteFirstMoveAndGiveMoveToMon(egg, gUnknown_030004E0[i]);
+ break;
+ }
+ }
+ }
+}
+#else
+__attribute__((naked))
+void daycare_build_child_moveset(struct Pokemon *egg, struct BoxPokemon *dad, struct BoxPokemon *mom)
+{
+ 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, 0xC\n"
+ "\tadds r7, r0, 0\n"
+ "\tmov r10, r1\n"
+ "\tmov r9, r2\n"
+ "\tmovs r0, 0\n"
+ "\tstr r0, [sp]\n"
+ "\tmovs r6, 0\n"
+ "\tldr r5, _08041CC8 @ =gUnknown_03000500\n"
+ "\tmovs r2, 0\n"
+ "\tldr r4, _08041CCC @ =gUnknown_030004D8\n"
+ "\tldr r3, _08041CD0 @ =gUnknown_030004E0\n"
+ "_08041BE4:\n"
+ "\tlsls r1, r6, 1\n"
+ "\tadds r0, r1, r5\n"
+ "\tstrh r2, [r0]\n"
+ "\tadds r0, r1, r4\n"
+ "\tstrh r2, [r0]\n"
+ "\tadds r1, r3\n"
+ "\tstrh r2, [r1]\n"
+ "\tadds r0, r6, 0x1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r6, r0, 16\n"
+ "\tcmp r6, 0x3\n"
+ "\tbls _08041BE4\n"
+ "\tmovs r6, 0\n"
+ "\tldr r2, _08041CD4 @ =gUnknown_030004E8\n"
+ "\tmovs r1, 0\n"
+ "_08041C02:\n"
+ "\tlsls r0, r6, 1\n"
+ "\tadds r0, r2\n"
+ "\tstrh r1, [r0]\n"
+ "\tadds r0, r6, 0x1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r6, r0, 16\n"
+ "\tcmp r6, 0x9\n"
+ "\tbls _08041C02\n"
+ "\tmovs r6, 0\n"
+ "\tldr r2, _08041CD8 @ =gUnknown_03000470\n"
+ "\tmovs r1, 0\n"
+ "_08041C18:\n"
+ "\tlsls r0, r6, 1\n"
+ "\tadds r0, r2\n"
+ "\tstrh r1, [r0]\n"
+ "\tadds r0, r6, 0x1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r6, r0, 16\n"
+ "\tcmp r6, 0x31\n"
+ "\tbls _08041C18\n"
+ "\tadds r0, r7, 0\n"
+ "\tmovs r1, 0xB\n"
+ "\tbl GetMonData\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r0, 16\n"
+ "\tldr r1, _08041CD8 @ =gUnknown_03000470\n"
+ "\tbl GetLevelUpMovesBySpecies\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r0, 24\n"
+ "\tstr r0, [sp, 0x4]\n"
+ "\tmovs r6, 0\n"
+ "\tldr r1, _08041CCC @ =gUnknown_030004D8\n"
+ "\tmov r8, r1\n"
+ "_08041C46:\n"
+ "\tadds r5, r6, 0\n"
+ "\tadds r5, 0xD\n"
+ "\tmov r0, r10\n"
+ "\tadds r1, r5, 0\n"
+ "\tbl GetBoxMonData\n"
+ "\tlsls r4, r6, 1\n"
+ "\tmov r2, r8\n"
+ "\tadds r1, r4, r2\n"
+ "\tstrh r0, [r1]\n"
+ "\tmov r0, r9\n"
+ "\tadds r1, r5, 0\n"
+ "\tbl GetBoxMonData\n"
+ "\tldr r1, _08041CC8 @ =gUnknown_03000500\n"
+ "\tadds r4, r1\n"
+ "\tstrh r0, [r4]\n"
+ "\tadds r0, r6, 0x1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r6, r0, 16\n"
+ "\tcmp r6, 0x3\n"
+ "\tbls _08041C46\n"
+ "\tldr r1, _08041CD4 @ =gUnknown_030004E8\n"
+ "\tadds r0, r7, 0\n"
+ "\tbl pokemon_get_eggmoves\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r0, 24\n"
+ "\tmov r8, r0\n"
+ "\tmovs r6, 0\n"
+ "_08041C82:\n"
+ "\tldr r0, _08041CCC @ =gUnknown_030004D8\n"
+ "\tlsls r1, r6, 1\n"
+ "\tadds r2, r1, r0\n"
+ "\tldrh r1, [r2]\n"
+ "\tmov r9, r0\n"
+ "\tcmp r1, 0\n"
+ "\tbeq _08041CF8\n"
+ "\tmovs r5, 0\n"
+ "\tcmp r5, r8\n"
+ "\tbcs _08041CEA\n"
+ "\tadds r4, r2, 0\n"
+ "\tldr r2, _08041CDC @ =0x0000ffff\n"
+ "_08041C9A:\n"
+ "\tldr r0, _08041CD4 @ =gUnknown_030004E8\n"
+ "\tlsls r1, r5, 1\n"
+ "\tadds r1, r0\n"
+ "\tldrh r0, [r4]\n"
+ "\tldrh r1, [r1]\n"
+ "\tcmp r0, r1\n"
+ "\tbne _08041CE0\n"
+ "\tadds r1, r0, 0\n"
+ "\tadds r0, r7, 0\n"
+ "\tstr r2, [sp, 0x8]\n"
+ "\tbl GiveMoveToMon\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r0, 16\n"
+ "\tldr r2, [sp, 0x8]\n"
+ "\tcmp r0, r2\n"
+ "\tbne _08041CEA\n"
+ "\tldrh r1, [r4]\n"
+ "\tadds r0, r7, 0\n"
+ "\tbl DeleteFirstMoveAndGiveMoveToMon\n"
+ "\tb _08041CEA\n"
+ "\t.align 2, 0\n"
+ "_08041CC8: .4byte gUnknown_03000500\n"
+ "_08041CCC: .4byte gUnknown_030004D8\n"
+ "_08041CD0: .4byte gUnknown_030004E0\n"
+ "_08041CD4: .4byte gUnknown_030004E8\n"
+ "_08041CD8: .4byte gUnknown_03000470\n"
+ "_08041CDC: .4byte 0x0000ffff\n"
+ "_08041CE0:\n"
+ "\tadds r0, r5, 0x1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r5, r0, 16\n"
+ "\tcmp r5, r8\n"
+ "\tbcc _08041C9A\n"
+ "_08041CEA:\n"
+ "\tadds r0, r6, 0x1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r6, r0, 16\n"
+ "\tldr r3, _08041E14 @ =gUnknown_030004D8\n"
+ "\tmov r9, r3\n"
+ "\tcmp r6, 0x3\n"
+ "\tbls _08041C82\n"
+ "_08041CF8:\n"
+ "\tmovs r6, 0\n"
+ "_08041CFA:\n"
+ "\tlsls r0, r6, 1\n"
+ "\tmov r2, r9\n"
+ "\tadds r1, r0, r2\n"
+ "\tldrh r1, [r1]\n"
+ "\tadds r2, r0, 0\n"
+ "\tadds r6, 0x1\n"
+ "\tmov r8, r6\n"
+ "\tcmp r1, 0\n"
+ "\tbeq _08041D5C\n"
+ "\tmovs r5, 0\n"
+ "\tldr r0, _08041E14 @ =gUnknown_030004D8\n"
+ "\tadds r4, r2, r0\n"
+ "\tldr r6, _08041E18 @ =0x0000ffff\n"
+ "\tmov r9, r0\n"
+ "_08041D16:\n"
+ "\tldr r3, _08041E1C @ =0x00000121\n"
+ "\tadds r0, r5, r3\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r0, 16\n"
+ "\tbl ItemIdToBattleMoveId\n"
+ "\tldrh r1, [r4]\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r0, 16\n"
+ "\tcmp r1, r0\n"
+ "\tbne _08041D52\n"
+ "\tlsls r1, r5, 24\n"
+ "\tlsrs r1, 24\n"
+ "\tadds r0, r7, 0\n"
+ "\tbl CanMonLearnTMHM\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _08041D52\n"
+ "\tldrh r1, [r4]\n"
+ "\tadds r0, r7, 0\n"
+ "\tbl GiveMoveToMon\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r0, 16\n"
+ "\tcmp r0, r6\n"
+ "\tbne _08041D52\n"
+ "\tldrh r1, [r4]\n"
+ "\tadds r0, r7, 0\n"
+ "\tbl DeleteFirstMoveAndGiveMoveToMon\n"
+ "_08041D52:\n"
+ "\tadds r0, r5, 0x1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r5, r0, 16\n"
+ "\tcmp r5, 0x39\n"
+ "\tbls _08041D16\n"
+ "_08041D5C:\n"
+ "\tmov r1, r8\n"
+ "\tlsls r0, r1, 16\n"
+ "\tlsrs r6, r0, 16\n"
+ "\tcmp r6, 0x3\n"
+ "\tbls _08041CFA\n"
+ "\tmovs r6, 0\n"
+ "\tmov r2, r9\n"
+ "\tldrh r0, [r2]\n"
+ "\tldr r3, _08041E20 @ =gUnknown_030004E0\n"
+ "\tmov r10, r3\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _08041DC6\n"
+ "\tmov r4, r9\n"
+ "\tldr r0, _08041E24 @ =gUnknown_03000500\n"
+ "\tmov r9, r0\n"
+ "\tmov r12, r10\n"
+ "_08041D7C:\n"
+ "\tmovs r5, 0\n"
+ "\tlsls r2, r6, 1\n"
+ "\tadds r6, 0x1\n"
+ "\tmov r8, r6\n"
+ "\tadds r3, r2, r4\n"
+ "_08041D86:\n"
+ "\tlsls r0, r5, 1\n"
+ "\tadd r0, r9\n"
+ "\tldrh r2, [r3]\n"
+ "\tadds r1, r2, 0\n"
+ "\tldrh r0, [r0]\n"
+ "\tcmp r1, r0\n"
+ "\tbne _08041DA8\n"
+ "\tcmp r1, 0\n"
+ "\tbeq _08041DA8\n"
+ "\tldr r1, [sp]\n"
+ "\tadds r0, r1, 0x1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r0, 16\n"
+ "\tstr r0, [sp]\n"
+ "\tlsls r1, 1\n"
+ "\tadd r1, r12\n"
+ "\tstrh r2, [r1]\n"
+ "_08041DA8:\n"
+ "\tadds r0, r5, 0x1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r5, r0, 16\n"
+ "\tcmp r5, 0x3\n"
+ "\tbls _08041D86\n"
+ "\tmov r1, r8\n"
+ "\tlsls r0, r1, 16\n"
+ "\tlsrs r6, r0, 16\n"
+ "\tcmp r6, 0x3\n"
+ "\tbhi _08041DC6\n"
+ "\tlsls r0, r6, 1\n"
+ "\tadds r0, r4\n"
+ "\tldrh r0, [r0]\n"
+ "\tcmp r0, 0\n"
+ "\tbne _08041D7C\n"
+ "_08041DC6:\n"
+ "\tmovs r6, 0\n"
+ "\tmov r2, r10\n"
+ "\tldrh r0, [r2]\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _08041E50\n"
+ "_08041DD0:\n"
+ "\tmovs r5, 0\n"
+ "\tadds r3, r6, 0x1\n"
+ "\tmov r8, r3\n"
+ "\tldr r0, [sp, 0x4]\n"
+ "\tcmp r5, r0\n"
+ "\tbcs _08041E38\n"
+ "\tldr r2, _08041E18 @ =0x0000ffff\n"
+ "_08041DDE:\n"
+ "\tldr r1, _08041E28 @ =gUnknown_03000470\n"
+ "\tlsls r0, r5, 1\n"
+ "\tadds r0, r1\n"
+ "\tldrh r1, [r0]\n"
+ "\tcmp r1, 0\n"
+ "\tbeq _08041E2C\n"
+ "\tlsls r0, r6, 1\n"
+ "\tmov r3, r10\n"
+ "\tadds r4, r0, r3\n"
+ "\tldrh r0, [r4]\n"
+ "\tcmp r0, r1\n"
+ "\tbne _08041E2C\n"
+ "\tadds r1, r0, 0\n"
+ "\tadds r0, r7, 0\n"
+ "\tstr r2, [sp, 0x8]\n"
+ "\tbl GiveMoveToMon\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r0, 16\n"
+ "\tldr r2, [sp, 0x8]\n"
+ "\tcmp r0, r2\n"
+ "\tbne _08041E38\n"
+ "\tldrh r1, [r4]\n"
+ "\tadds r0, r7, 0\n"
+ "\tbl DeleteFirstMoveAndGiveMoveToMon\n"
+ "\tb _08041E38\n"
+ "\t.align 2, 0\n"
+ "_08041E14: .4byte gUnknown_030004D8\n"
+ "_08041E18: .4byte 0x0000ffff\n"
+ "_08041E1C: .4byte 0x00000121\n"
+ "_08041E20: .4byte gUnknown_030004E0\n"
+ "_08041E24: .4byte gUnknown_03000500\n"
+ "_08041E28: .4byte gUnknown_03000470\n"
+ "_08041E2C:\n"
+ "\tadds r0, r5, 0x1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r5, r0, 16\n"
+ "\tldr r0, [sp, 0x4]\n"
+ "\tcmp r5, r0\n"
+ "\tbcc _08041DDE\n"
+ "_08041E38:\n"
+ "\tmov r1, r8\n"
+ "\tlsls r0, r1, 16\n"
+ "\tlsrs r6, r0, 16\n"
+ "\tcmp r6, 0x3\n"
+ "\tbhi _08041E50\n"
+ "\tldr r0, _08041E60 @ =gUnknown_030004E0\n"
+ "\tlsls r1, r6, 1\n"
+ "\tadds r1, r0\n"
+ "\tldrh r1, [r1]\n"
+ "\tmov r10, r0\n"
+ "\tcmp r1, 0\n"
+ "\tbne _08041DD0\n"
+ "_08041E50:\n"
+ "\tadd sp, 0xC\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.align 2, 0\n"
+ "_08041E60: .4byte gUnknown_030004E0");
+}
+#endif
+
+static void RemoveEggFromDayCare(struct DayCareData *dayCareData)
+{
+ dayCareData->misc.countersEtc.personalityLo = 0;
+ dayCareData->misc.countersEtc.unk_11a = 0;
+}
+
+void sub_8041E7C(void)
+{
+ RemoveEggFromDayCare(&gSaveBlock1.daycareData);
+}
+
+static void incense_effects(u16 *species, struct DayCareData *dayCareData)
+{
+ u16 momItem, dadItem;
+ if (*species == SPECIES_WYNAUT || *species == SPECIES_AZURILL)
+ {
+ momItem = GetBoxMonData(&dayCareData->mons[0], MON_DATA_HELD_ITEM);
+ dadItem = GetBoxMonData(&dayCareData->mons[1], MON_DATA_HELD_ITEM);
+ if (*species == SPECIES_WYNAUT && momItem != ITEM_LAX_INCENSE && dadItem != ITEM_LAX_INCENSE)
+ {
+ *species = SPECIES_WOBBUFFET;
+ }
+ if (*species == SPECIES_AZURILL && momItem != ITEM_SEA_INCENSE && dadItem != ITEM_SEA_INCENSE)
+ {
+ *species = SPECIES_MARILL;
+ }
+ }
+}
+
+static u16 sub_8041EEC(struct DayCareData *dayCareData, u8 *a1) // inherit_species_from_mom
+{
+ u16 i;
+ u16 species[2];
+ u16 eggSpecies;
+ u8 buffer;
+ for (i=0; i<2; i++)
+ {
+ species[i] = GetBoxMonData(&dayCareData->mons[i], MON_DATA_SPECIES);
+ if (species[i] == SPECIES_DITTO)
+ {
+ a1[0] = i ^ 1;
+ a1[1] = i;
+ }
+ else if (GetBoxMonGender(&dayCareData->mons[i]) == MON_FEMALE)
+ {
+ a1[0] = i;
+ a1[1] = i ^ 1;
+ }
+ }
+ eggSpecies = sub_8041870(species[a1[0]]);
+ if (eggSpecies == SPECIES_NIDORAN_F && dayCareData->misc.countersEtc.personalityLo & 0x8000)
+ {
+ eggSpecies = SPECIES_NIDORAN_M;
+ }
+ if (eggSpecies == SPECIES_ILLUMISE && dayCareData->misc.countersEtc.personalityLo & 0x8000)
+ {
+ eggSpecies = SPECIES_VOLBEAT;
+ }
+ if (species[a1[1]] == SPECIES_DITTO && GetBoxMonGender(&dayCareData->mons[a1[0]]) != MON_FEMALE)
+ {
+ buffer = a1[1];
+ a1[1] = a1[0];
+ a1[0] = buffer;
+ }
+ return eggSpecies;
+}
+
+static void sub_8041FC4(struct DayCareData *dayCareData) // give_egg
+{
+ struct Pokemon egg;
+ u16 species;
+ u8 parents[2];
+ u8 isEgg;
+ species = sub_8041EEC(dayCareData, parents);
+ incense_effects(&species, dayCareData);
+ sub_80420FC(&egg, species, dayCareData);
+ InheritIVs(&egg, dayCareData);
+ daycare_build_child_moveset(&egg, &dayCareData->mons[parents[1]], &dayCareData->mons[parents[0]]);
+ isEgg = TRUE;
+ SetMonData(&egg, MON_DATA_IS_EGG, &isEgg);
+ gPlayerParty[5] = egg;
+ party_compaction();
+ CalculatePlayerPartyCount();
+ RemoveEggFromDayCare(dayCareData);
+}
+
+
+void sub_8042044(struct Pokemon *mon, u16 species, u8 overwriteMetLocation) // scr_create_egg
+{
+ u8 metLevel;
+ u16 ball;
+ u8 language;
+ u8 metLocation;
+ u8 isEgg;
+ CreateMon(mon, species, 5, 0x20, FALSE, 0, FALSE, 0);
+ metLevel = 0;
+ ball = ITEM_POKE_BALL;
+ language = LANGUAGE_JAPANESE;
+ SetMonData(mon, MON_DATA_POKEBALL, (u8 *)&ball);
+ SetMonData(mon, MON_DATA_NICKNAME, gUnknown_08209AD4);
+ SetMonData(mon, MON_DATA_FRIENDSHIP, &gBaseStats[species].eggCycles);
+ SetMonData(mon, MON_DATA_MET_LEVEL, &metLevel);
+ SetMonData(mon, MON_DATA_LANGUAGE, &language);
+ if (overwriteMetLocation)
+ {
+ metLocation = 0xfd;
+ SetMonData(mon, MON_DATA_MET_LOCATION, &metLocation);
+ }
+ isEgg = TRUE;
+ SetMonData(mon, MON_DATA_IS_EGG, &isEgg);
+}
+
+static void sub_80420FC(struct Pokemon *mon, u16 species, struct DayCareData *dayCareData)
+{
+ u32 personality;
+ u16 ball;
+ u8 metLevel;
+ u8 language;
+ personality = dayCareData->misc.countersEtc.personalityLo | (Random() << 16);
+ CreateMon(mon, species, 5, 0x20, TRUE, personality, FALSE, 0);
+ metLevel = 0;
+ ball = ITEM_POKE_BALL;
+ language = LANGUAGE_JAPANESE;
+ SetMonData(mon, MON_DATA_POKEBALL, (u8 *)&ball);
+ SetMonData(mon, MON_DATA_NICKNAME, gUnknown_08209AD4);
+ SetMonData(mon, MON_DATA_FRIENDSHIP, &gBaseStats[species].eggCycles);
+ SetMonData(mon, MON_DATA_MET_LEVEL, &metLevel);
+ SetMonData(mon, MON_DATA_LANGUAGE, &language);
+}
+
+void sp0B8_daycare(void)
+{
+ sub_8041FC4(&gSaveBlock1.daycareData);
+}
+
+#ifdef NONMATCHING
+static bool8 sub_80421B0(struct DayCareData *dayCareData)
+{
+ struct BoxPokemon *parent;
+ u32 i;
+ int v0;
+ int steps;
+ v0 = 0;
+ for (i=0, parent=&dayCareData->mons[0]; i<2; parent++, i++)
+ {
+ if (GetBoxMonData(parent, MON_DATA_SANITY_BIT2, v0))
+ {
+ dayCareData->misc.countersEtc.steps[i]++;
+ v0++;
+ }
+ }
+ if (dayCareData->misc.countersEtc.personalityLo == 0 && v0 == 2 && dayCareData->misc.extra.misc[4] == 0xff && daycare_relationship_score(dayCareData) > (u32)((u32)(Random() * 100) / 0xffff))
+ {
+ sub_8041940();
+ }
+ if ((++dayCareData->misc.countersEtc.unk_11a) == 0xff)
+ {
+ for (i=0; i<gPlayerPartyCount; i++)
+ {
+ if (GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG))
+ {
+ steps = GetMonData(&gPlayerParty[i], MON_DATA_FRIENDSHIP);
+ if (steps == 0)
+ {
+ gSpecialVar_0x8004 = i;
+ return TRUE;
+ }
+ steps--;
+ SetMonData(&gPlayerParty[i], MON_DATA_FRIENDSHIP, (u8 *)&steps);
+ }
+ }
+ }
+ return FALSE;
+}
+#else
+__attribute__((naked))
+static bool8 sub_80421B0(struct DayCareData *dayCareData)
+{
+ asm_unified("\tpush {r4-r7,lr}\n"
+ "\tsub sp, 0x8\n"
+ "\tadds r7, r0, 0\n"
+ "\tmovs r2, 0\n"
+ "\tmovs r6, 0\n"
+ "\tadds r5, r7, 0\n"
+ "_080421BC:\n"
+ "\tlsls r4, r6, 2\n"
+ "\tadds r0, r5, 0\n"
+ "\tmovs r1, 0x5\n"
+ "\tstr r2, [sp, 0x4]\n"
+ "\tbl GetBoxMonData\n"
+ "\tldr r2, [sp, 0x4]\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _080421DE\n"
+ "\tmovs r0, 0x88\n"
+ "\tlsls r0, 1\n"
+ "\tadds r1, r7, r0\n"
+ "\tadds r1, r4\n"
+ "\tldr r0, [r1]\n"
+ "\tadds r0, 0x1\n"
+ "\tstr r0, [r1]\n"
+ "\tadds r2, 0x1\n"
+ "_080421DE:\n"
+ "\tadds r5, 0x50\n"
+ "\tadds r6, 0x1\n"
+ "\tcmp r6, 0x1\n"
+ "\tbls _080421BC\n"
+ "\tmovs r1, 0x8C\n"
+ "\tlsls r1, 1\n"
+ "\tadds r0, r7, r1\n"
+ "\tldrh r0, [r0]\n"
+ "\tcmp r0, 0\n"
+ "\tbne _08042226\n"
+ "\tcmp r2, 0x2\n"
+ "\tbne _08042226\n"
+ "\tsubs r1, 0x4\n"
+ "\tadds r0, r7, r1\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r0, 0xFF\n"
+ "\tbne _08042226\n"
+ "\tadds r0, r7, 0\n"
+ "\tbl daycare_relationship_score\n"
+ "\tadds r4, r0, 0\n"
+ "\tlsls r4, 24\n"
+ "\tlsrs r4, 24\n"
+ "\tbl Random\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r0, 16\n"
+ "\tmovs r1, 0x64\n"
+ "\tmuls r0, r1\n"
+ "\tldr r1, _08042240 @ =0x0000ffff\n"
+ "\tbl __udivsi3\n"
+ "\tcmp r4, r0\n"
+ "\tbls _08042226\n"
+ "\tbl sub_8041940\n"
+ "_08042226:\n"
+ "\tmovs r0, 0x8D\n"
+ "\tlsls r0, 1\n"
+ "\tadds r1, r7, r0\n"
+ "\tldrb r0, [r1]\n"
+ "\tadds r0, 0x1\n"
+ "\tstrb r0, [r1]\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r0, 24\n"
+ "\tcmp r0, 0xFF\n"
+ "\tbne _08042290\n"
+ "\tmovs r6, 0\n"
+ "\tb _08042288\n"
+ "\t.align 2, 0\n"
+ "_08042240: .4byte 0x0000ffff\n"
+ "_08042244:\n"
+ "\tmovs r0, 0x64\n"
+ "\tadds r1, r6, 0\n"
+ "\tmuls r1, r0\n"
+ "\tldr r0, _08042270 @ =gPlayerParty\n"
+ "\tadds r4, r1, r0\n"
+ "\tadds r0, r4, 0\n"
+ "\tmovs r1, 0x2D\n"
+ "\tbl GetMonData\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _08042286\n"
+ "\tadds r0, r4, 0\n"
+ "\tmovs r1, 0x20\n"
+ "\tbl GetMonData\n"
+ "\tstr r0, [sp]\n"
+ "\tcmp r0, 0\n"
+ "\tbne _08042278\n"
+ "\tldr r0, _08042274 @ =gSpecialVar_0x8004\n"
+ "\tstrh r6, [r0]\n"
+ "\tmovs r0, 0x1\n"
+ "\tb _08042292\n"
+ "\t.align 2, 0\n"
+ "_08042270: .4byte gPlayerParty\n"
+ "_08042274: .4byte gSpecialVar_0x8004\n"
+ "_08042278:\n"
+ "\tsubs r0, 0x1\n"
+ "\tstr r0, [sp]\n"
+ "\tadds r0, r4, 0\n"
+ "\tmovs r1, 0x20\n"
+ "\tmov r2, sp\n"
+ "\tbl SetMonData\n"
+ "_08042286:\n"
+ "\tadds r6, 0x1\n"
+ "_08042288:\n"
+ "\tldr r0, _0804229C @ =gPlayerPartyCount\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r6, r0\n"
+ "\tbcc _08042244\n"
+ "_08042290:\n"
+ "\tmovs r0, 0\n"
+ "_08042292:\n"
+ "\tadd sp, 0x8\n"
+ "\tpop {r4-r7}\n"
+ "\tpop {r1}\n"
+ "\tbx r1\n"
+ "\t.align 2, 0\n"
+ "_0804229C: .4byte gPlayerPartyCount");
+}
+#endif
+
+bool8 sub_80422A0(void)
+{
+ return sub_80421B0(&gSaveBlock1.daycareData);
+}
+
+static bool8 sub_80422B4(struct DayCareData *dayCareData)
+{
+ return (u32)((-dayCareData->misc.countersEtc.personalityLo) | dayCareData->misc.countersEtc.personalityLo) >> 31;
+}
+
+static void sub_80422C4(struct DayCareData *dayCareData)
+{
+ u8 language;
+ if (GetBoxMonData(&dayCareData->mons[0], MON_DATA_SPECIES) != 0)
+ {
+ GetBoxMonNick(&dayCareData->mons[0], gStringVar1);
+ language = GetBoxMonData(&dayCareData->mons[0], MON_DATA_LANGUAGE);
+ GetBoxMonData(&dayCareData->mons[0], MON_DATA_OT_NAME, gStringVar3);
+ ConvertInternationalString(gStringVar3, language);
+ }
+ if (GetBoxMonData(&dayCareData->mons[1], MON_DATA_SPECIES) != 0)
+ {
+ GetBoxMonNick(&dayCareData->mons[1], gStringVar2);
+ }
+}
+
+u16 sub_8042328(void)
+{
+ GetBoxMonNick(&gPlayerParty[gLastFieldPokeMenuOpened].box, gStringVar1);
+ return GetBoxMonData(&gPlayerParty[gLastFieldPokeMenuOpened].box, MON_DATA_SPECIES);
+}
+
+void sp0B5_daycare(void)
+{
+ sub_80422C4(&gSaveBlock1.daycareData);
+}
+
+u8 sp0B6_daycare(void)
+{
+ u8 monCount;
+ if (sub_80422B4(&gSaveBlock1.daycareData))
+ {
+ return 1;
+ }
+ monCount = Daycare_CountPokemon(&gSaveBlock1.daycareData);
+ if (monCount != 0)
+ {
+ return monCount + 1;
+ }
+ return 0;
+}
+
+#ifdef NONMATCHING
+static
+#endif
+bool8 sub_80423A8(u16 *a, u16 *b)
+{
+ int i, j;
+ u16 *v0, *v1, v2;
+ for (i=0, v0=a; i<2; v0++, i++)
+ {
+ for (j=0, v2=*v0, v1=b; j<2; v1++, j++)
+ {
+ if (v2 == *v1)
+ {
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+#ifdef NONMATCHING
+static u8 daycare_relationship_score(struct DayCareData *dayCareData)
+{
+ u16 species[2];
+ u32 otIds[2];
+ u32 genders[2];
+ u16 eggGroups[2][2];
+ int i;
+ u16 *spc;
+ u32 *ids;
+ u32 *gnd;
+ u16 *egg1;
+ u16 *egg2;
+ struct BoxPokemon *parent;
+ for (i=0, parent=&dayCareData->mons[0], spc=species, ids=otIds, gnd=genders, egg1=&eggGroups[0][0], egg2=&eggGroups[0][1]; i<2; spc++, egg1+=2, egg2+=2, parent++, i++)
+ {
+ *spc = GetBoxMonData(parent, MON_DATA_SPECIES);
+ *ids++ = GetBoxMonData(parent, MON_DATA_OT_ID);
+ *gnd++ = GetGenderFromSpeciesAndPersonality(*spc, GetBoxMonData(parent, MON_DATA_PERSONALITY));
+ *egg1 = gBaseStats[*spc].eggGroup1;
+ *egg2 = gBaseStats[*spc].eggGroup2;
+ }
+ if (eggGroups[0][0] == 0xf)
+ {
+ return 0;
+ }
+ if (eggGroups[1][0] == 0xf)
+ {
+ return 0;
+ }
+ if (eggGroups[0][0] == 0xd && eggGroups[1][0] == 0xd)
+ {
+ return 0;
+ }
+ else if (eggGroups[0][0] == 0xd || eggGroups[1][0] == 0xd)
+ {
+ if (otIds[0] == otIds[1])
+ {
+ return 20;
+ }
+ return 50;
+ }
+ if (genders[0] == genders[1] || genders[0] == MON_GENDERLESS || genders[1] == MON_GENDERLESS)
+ {
+ return 0;
+ }
+ if (!sub_80423A8(eggGroups[0], eggGroups[1]))
+ {
+ return 0;
+ }
+ if (species[0] == species[1])
+ {
+ if (otIds[0] == otIds[1])
+ {
+ return 50;
+ }
+ return 70;
+ }
+ else
+ {
+ if (otIds[0] != otIds[1])
+ {
+ return 50;
+ }
+ return 20;
+ }
+}
+#else
+__attribute__((naked))
+static u8 daycare_relationship_score(struct DayCareData *dayCareData)
+{
+ 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, 0x2C\n"
+ "\tmovs r1, 0\n"
+ "\tmov r8, r1\n"
+ "\tmov r2, sp\n"
+ "\tadds r2, 0x8\n"
+ "\tstr r2, [sp, 0x1C]\n"
+ "\tadd r1, sp, 0xC\n"
+ "\tmov r10, r1\n"
+ "\tadds r2, 0xC\n"
+ "\tstr r2, [sp, 0x20]\n"
+ "\tmov r1, sp\n"
+ "\tadds r1, 0x2\n"
+ "\tldr r2, _08042488 @ =gBaseStats\n"
+ "\tmov r9, r2\n"
+ "\tldr r5, [sp, 0x1C]\n"
+ "\tadds r7, r1, 0\n"
+ "\tmov r6, sp\n"
+ "\tldr r1, [sp, 0x20]\n"
+ "\tstr r1, [sp, 0x24]\n"
+ "\tmov r2, r10\n"
+ "\tstr r2, [sp, 0x28]\n"
+ "\tadds r4, r0, 0\n"
+ "_0804240E:\n"
+ "\tadds r0, r4, 0\n"
+ "\tmovs r1, 0xB\n"
+ "\tbl GetBoxMonData\n"
+ "\tstrh r0, [r5]\n"
+ "\tadds r0, r4, 0\n"
+ "\tmovs r1, 0x1\n"
+ "\tbl GetBoxMonData\n"
+ "\tldr r1, [sp, 0x28]\n"
+ "\tstm r1!, {r0}\n"
+ "\tstr r1, [sp, 0x28]\n"
+ "\tadds r0, r4, 0\n"
+ "\tmovs r1, 0\n"
+ "\tbl GetBoxMonData\n"
+ "\tadds r1, r0, 0\n"
+ "\tldrh r0, [r5]\n"
+ "\tbl GetGenderFromSpeciesAndPersonality\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r0, 24\n"
+ "\tldr r2, [sp, 0x24]\n"
+ "\tstm r2!, {r0}\n"
+ "\tstr r2, [sp, 0x24]\n"
+ "\tldrh r1, [r5]\n"
+ "\tlsls r0, r1, 3\n"
+ "\tsubs r0, r1\n"
+ "\tlsls r0, 2\n"
+ "\tadd r0, r9\n"
+ "\tldrb r0, [r0, 0x14]\n"
+ "\tstrh r0, [r6]\n"
+ "\tldrh r1, [r5]\n"
+ "\tlsls r0, r1, 3\n"
+ "\tsubs r0, r1\n"
+ "\tlsls r0, 2\n"
+ "\tadd r0, r9\n"
+ "\tldrb r0, [r0, 0x15]\n"
+ "\tstrh r0, [r7]\n"
+ "\tadds r5, 0x2\n"
+ "\tadds r7, 0x4\n"
+ "\tadds r6, 0x4\n"
+ "\tadds r4, 0x50\n"
+ "\tmovs r0, 0x1\n"
+ "\tadd r8, r0\n"
+ "\tmov r1, r8\n"
+ "\tcmp r1, 0x1\n"
+ "\tbls _0804240E\n"
+ "\tmov r0, sp\n"
+ "\tldrh r1, [r0]\n"
+ "\tcmp r1, 0xF\n"
+ "\tbeq _08042484\n"
+ "\tldrh r0, [r0, 0x4]\n"
+ "\tcmp r0, 0xF\n"
+ "\tbeq _08042484\n"
+ "\tcmp r1, 0xD\n"
+ "\tbne _0804248C\n"
+ "\tcmp r0, 0xD\n"
+ "\tbne _08042490\n"
+ "_08042484:\n"
+ "\tmovs r0, 0\n"
+ "\tb _080424E4\n"
+ "\t.align 2, 0\n"
+ "_08042488: .4byte gBaseStats\n"
+ "_0804248C:\n"
+ "\tcmp r0, 0xD\n"
+ "\tbne _0804249C\n"
+ "_08042490:\n"
+ "\tldr r1, [sp, 0xC]\n"
+ "\tmov r2, r10\n"
+ "\tldr r0, [r2, 0x4]\n"
+ "\tcmp r1, r0\n"
+ "\tbeq _080424DE\n"
+ "\tb _080424E2\n"
+ "_0804249C:\n"
+ "\tldr r0, [sp, 0x14]\n"
+ "\tldr r2, [sp, 0x20]\n"
+ "\tldr r1, [r2, 0x4]\n"
+ "\tcmp r0, r1\n"
+ "\tbeq _08042484\n"
+ "\tcmp r0, 0xFF\n"
+ "\tbeq _08042484\n"
+ "\tcmp r1, 0xFF\n"
+ "\tbeq _08042484\n"
+ "\tadd r1, sp, 0x4\n"
+ "\tmov r0, sp\n"
+ "\tbl sub_80423A8\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _08042484\n"
+ "\tldr r0, [sp, 0x1C]\n"
+ "\tldrh r1, [r0, 0x2]\n"
+ "\tldrh r0, [r0]\n"
+ "\tcmp r0, r1\n"
+ "\tbne _080424D4\n"
+ "\tldr r1, [sp, 0xC]\n"
+ "\tmov r2, r10\n"
+ "\tldr r0, [r2, 0x4]\n"
+ "\tcmp r1, r0\n"
+ "\tbeq _080424E2\n"
+ "\tmovs r0, 0x46\n"
+ "\tb _080424E4\n"
+ "_080424D4:\n"
+ "\tldr r1, [sp, 0xC]\n"
+ "\tmov r2, r10\n"
+ "\tldr r0, [r2, 0x4]\n"
+ "\tcmp r1, r0\n"
+ "\tbne _080424E2\n"
+ "_080424DE:\n"
+ "\tmovs r0, 0x14\n"
+ "\tb _080424E4\n"
+ "_080424E2:\n"
+ "\tmovs r0, 0x32\n"
+ "_080424E4:\n"
+ "\tadd sp, 0x2C\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");
+}
+#endif
+
+u8 daycare_relationship_score_from_savegame(void)
+{
+ return daycare_relationship_score(&gSaveBlock1.daycareData);
+}
+
+void sp0B9_daycare_relationship_comment(void)
+{
+ u8 whichString;
+ u8 relationshipScore;
+
+ relationshipScore = daycare_relationship_score_from_savegame();
+ whichString = 0;
+ if (relationshipScore == 0)
+ whichString = 3;
+ if (relationshipScore == 20)
+ whichString = 2;
+ if (relationshipScore == 50)
+ whichString = 1;
+ if (relationshipScore == 70)
+ whichString = 0;
+ StringCopy(gStringVar4, gUnknown_08209AC4[whichString]);
+}
+
+#ifdef NONMATCHING
+bool8 NameHasGenderSymbol(const u8 *name, u8 genderRatio)
+{
+ u8 i;
+ u8 flags[2];
+
+ // This portion is nonmatching
+ flags[1] = 0;
+ flags[0] = 0;
+ for (i = 0; name[i] != EOS; i ++)
+ // End nonmatching portion
+
+ {
+ if (name[i] == CHAR_MALE) flags[0] ++;
+ if (name[i] == CHAR_FEMALE) flags[1] ++;
+ }
+ if (genderRatio == MON_MALE && flags[0] && !flags[1]) return TRUE;
+ if (genderRatio == MON_FEMALE && flags[1] && !flags[0]) return TRUE;
+ return FALSE;
+}
+#else
+__attribute__((naked))
+bool8 NameHasGenderSymbol(const u8 *name, u8 genderRatio)
+{
+ asm_unified("\n"
+ "\tpush {r4,r5,lr}\n"
+ "\tsub sp, 0x4\n"
+ "\tadds r4, r0, 0\n"
+ "\tlsls r1, 24\n"
+ "\tlsrs r5, r1, 24\n"
+ "\tmov r2, sp\n"
+ "\tmov r1, sp\n"
+ "\tmovs r0, 0\n"
+ "\tstrb r0, [r1, 0x1]\n"
+ "\tstrb r0, [r2]\n"
+ "\tmovs r3, 0\n"
+ "\tldrb r0, [r4]\n"
+ "\tcmp r0, 0xFF\n"
+ "\tbeq _0804258C\n"
+ "_08042564:\n"
+ "\tadds r1, r4, r3\n"
+ "\tldrb r0, [r1]\n"
+ "\tcmp r0, 0xB5\n"
+ "\tbne _08042572\n"
+ "\tldrb r0, [r2]\n"
+ "\tadds r0, 0x1\n"
+ "\tstrb r0, [r2]\n"
+ "_08042572:\n"
+ "\tldrb r0, [r1]\n"
+ "\tcmp r0, 0xB6\n"
+ "\tbne _0804257E\n"
+ "\tldrb r0, [r2, 0x1]\n"
+ "\tadds r0, 0x1\n"
+ "\tstrb r0, [r2, 0x1]\n"
+ "_0804257E:\n"
+ "\tadds r0, r3, 0x1\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r3, r0, 24\n"
+ "\tadds r0, r4, r3\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r0, 0xFF\n"
+ "\tbne _08042564\n"
+ "_0804258C:\n"
+ "\tcmp r5, 0\n"
+ "\tbne _080425A0\n"
+ "\tmov r0, sp\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _080425A0\n"
+ "\tmov r0, sp\n"
+ "\tldrb r0, [r0, 0x1]\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _080425B4\n"
+ "_080425A0:\n"
+ "\tcmp r5, 0xFE\n"
+ "\tbne _080425B8\n"
+ "\tmov r0, sp\n"
+ "\tldrb r0, [r0, 0x1]\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _080425B8\n"
+ "\tmov r0, sp\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r0, 0\n"
+ "\tbne _080425B8\n"
+ "_080425B4:\n"
+ "\tmovs r0, 0x1\n"
+ "\tb _080425BA\n"
+ "_080425B8:\n"
+ "\tmovs r0, 0\n"
+ "_080425BA:\n"
+ "\tadd sp, 0x4\n"
+ "\tpop {r4,r5}\n"
+ "\tpop {r1}\n"
+ "\tbx r1");
+}
+#endif
+
+static u8 *AppendGenderSymbol(u8 *name, u8 gender)
+{
+ if (gender == MON_MALE)
+ {
+ if (!NameHasGenderSymbol(name, MON_MALE))
+ return StringAppend(name, gOtherText_MaleSymbol3);
+ }
+
+ else if (gender == MON_FEMALE)
+ {
+ if (!NameHasGenderSymbol(name, MON_FEMALE))
+ return StringAppend(name, gOtherText_FemaleSymbol3);
+ }
+ return StringAppend(name, gOtherText_GenderlessSymbol);
+}
+
+static u8 *MonAppendGenderSymbol(u8 *name, struct BoxPokemon *boxMon)
+{
+ return AppendGenderSymbol(name, GetBoxMonGender(boxMon));
+}
+
+static void DaycareLevelMenuGetText(struct DayCareData *dayCareData, u8 *dest)
+{
+ u8 buffers[2][20];
+ u8 i;
+ *dest = EOS;
+ for (i = 0; i < 2; i ++)
+ {
+ GetBoxMonNick(&dayCareData->mons[i], buffers[i]);
+ MonAppendGenderSymbol(buffers[i], &dayCareData->mons[i]);
+ }
+ StringCopy(dest, buffers[0]);
+ StringAppend(dest, gOtherText_NewLine2);
+ StringAppend(dest, buffers[1]);
+ StringAppend(dest, gOtherText_NewLine2);
+ StringAppend(dest, gOtherText_CancelAndLv);
+}
+
+static void DaycareLevelMenuGetLevelText(struct DayCareData *dayCareData, u8 *dest)
+{
+ u8 i;
+ u8 level;
+ *dest = EOS;
+ for (i = 0; i < 2; i ++)
+ {
+ level = Daycare_GetLevelAfterSteps(&dayCareData->mons[i], dayCareData->misc.countersEtc.steps[i]);
+ dest[0] = 0x34;
+ dest[1] = 0xFC;
+ dest[2] = 0x14;
+ dest[3] = 0x06;
+ dest = ConvertIntToDecimalStringN(dest + 4, level, STR_CONV_MODE_RIGHT_ALIGN, 3);
+ dest[0] = 0xFC;
+ dest[1] = 0x14;
+ dest[2] = 0x00;
+ dest = StringCopy(dest + 3, gOtherText_NewLine2);
+ }
+ *dest = EOS;
+}
+
+static void DaycareLevelMenuProcessKeyInput(u8 taskId)
+{
+ if (gMain.newKeys & DPAD_UP)
+ {
+ if (gTasks[taskId].data[0] != 0)
+ {
+ gTasks[taskId].data[0] --;
+ MoveMenuCursor(-1);
+ PlaySE(SE_SELECT);
+ }
+ }
+ else if (gMain.newKeys & DPAD_DOWN)
+ {
+ if (gTasks[taskId].data[0] != 2)
+ {
+ gTasks[taskId].data[0] ++;
+ MoveMenuCursor(+1);
+ PlaySE(SE_SELECT);
+ }
+ }
+ else if (gMain.newKeys & A_BUTTON)
+ {
+ HandleDestroyMenuCursors();
+ PlaySE(SE_SELECT);
+ gLastFieldPokeMenuOpened = gScriptResult = gTasks[taskId].data[0];
+ DestroyTask(taskId);
+ MenuZeroFillWindowRect(15, 6, 29, 13);
+ EnableBothScriptContexts();
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ HandleDestroyMenuCursors();
+ gLastFieldPokeMenuOpened = gScriptResult = 2;
+ DestroyTask(taskId);
+ MenuZeroFillWindowRect(15, 6, 29, 13);
+ EnableBothScriptContexts();
+ }
+}
+
+void ShowDaycareLevelMenu(void)
+{
+ u8 buffer[100];
+ MenuDrawTextWindow(15, 6, 29, 13);
+ DaycareLevelMenuGetText(&gSaveBlock1.daycareData, buffer);
+ MenuPrint(buffer, 16, 7);
+ DaycareLevelMenuGetLevelText(&gSaveBlock1.daycareData, buffer);
+ MenuPrint_PixelCoords(buffer, 0xce, 0x38, TRUE);
+ InitMenu(0, 16, 7, 3, 0, 13);
+ CreateTask(DaycareLevelMenuProcessKeyInput, 3);
+}
+
+void ChooseSendDaycareMon(void)
+{
+ OpenPartyMenu(6, 0);
+ gMain.savedCallback = c2_exit_to_overworld_2_switch;
+}
diff --git a/src/field/decoration.c b/src/field/decoration.c
new file mode 100644
index 000000000..e067191e9
--- /dev/null
+++ b/src/field/decoration.c
@@ -0,0 +1,4280 @@
+#include "global.h"
+#include "main.h"
+#include "map_object_constants.h"
+#include "overworld.h"
+#include "sound.h"
+#include "songs.h"
+#include "string_util.h"
+#include "menu.h"
+#include "menu_helpers.h"
+#include "strings.h"
+#include "script.h"
+#include "palette.h"
+#include "field_player_avatar.h"
+#include "field_camera.h"
+#include "field_fadetransition.h"
+#include "fieldmap.h"
+#include "metatile_behavior.h"
+#include "event_data.h"
+#include "field_weather.h"
+#include "decoration.h"
+
+EWRAM_DATA u8 *gUnknown_020388D0 = NULL;
+EWRAM_DATA u8 gUnknown_020388D4 = 0;
+EWRAM_DATA u8 gUnknown_020388D5 = 0;
+EWRAM_DATA u8 gUnknown_020388D6[16] = {0};
+EWRAM_DATA u8 gUnknown_020388E6[12] = {0};
+EWRAM_DATA u8 gUnknown_020388F2 = 0;
+EWRAM_DATA u8 gUnknown_020388F3 = 0;
+EWRAM_DATA u8 gUnknown_020388F4 = 0;
+EWRAM_DATA u8 gUnknown_020388F5 = 0;
+EWRAM_DATA u8 gUnknown_020388F6 = 0;
+EWRAM_DATA u8 gUnknown_020388F7[8] = {0};
+EWRAM_DATA struct UnkStruct_02038900 gUnknown_02038900 = {0};
+EWRAM_DATA u16 gUnknown_020391A4 = 0;
+EWRAM_DATA u16 gUnknown_020391A6 = 0;
+EWRAM_DATA u8 gUnknown_020391A8 = 0;
+EWRAM_DATA u8 gUnknown_020391A9 = 0;
+EWRAM_DATA u8 gUnknown_020391AA = 0;
+EWRAM_DATA struct OamData gUnknown_020391AC = {0};
+EWRAM_DATA struct UnkStruct_020391B4 gUnknown_020391B4[16] = {0};
+EWRAM_DATA u8 gUnknown_02039234 = 0;
+
+#if ENGLISH
+const u8 DecorDesc_SMALL_DESK[] = _(
+ "A small desk built\n"
+ "for one.");
+
+const u8 DecorDesc_POKEMON_DESK[] = _(
+ "A small desk built in\n"
+ "the shape of a POKé\n"
+ "BALL.");
+
+const u8 DecorDesc_HEAVY_DESK[] = _(
+ "A large desk made\n"
+ "of steel. Put some\n"
+ "decorations on it.");
+
+const u8 DecorDesc_RAGGED_DESK[] = _(
+ "A large desk made\n"
+ "of wood. Put some\n"
+ "decorations on it.");
+
+const u8 DecorDesc_COMFORT_DESK[] = _(
+ "A large desk made\n"
+ "of leaves. Put some\n"
+ "decorations on it.");
+
+const u8 DecorDesc_PRETTY_DESK[] = _(
+ "A huge desk made\n"
+ "of glass. Holds lots\n"
+ "of decorations.");
+
+const u8 DecorDesc_BRICK_DESK[] = _(
+ "A huge desk made\n"
+ "of brick. Holds lots\n"
+ "of decorations.");
+
+const u8 DecorDesc_CAMP_DESK[] = _(
+ "A huge desk made\n"
+ "of logs. Put lots of\n"
+ "decorations on it.");
+
+const u8 DecorDesc_HARD_DESK[] = _(
+ "A huge desk made\n"
+ "of rocks. Holds\n"
+ "many decorations.");
+
+const u8 DecorDesc_SMALL_CHAIR[] = _(
+ "A small chair made\n"
+ "for one.");
+
+const u8 DecorDesc_POKEMON_CHAIR[] = _(
+ "A small chair built\n"
+ "in the shape of a\n"
+ "POKé BALL.");
+
+const u8 DecorDesc_HEAVY_CHAIR[] = _(
+ "A small chair made\n"
+ "of steel.");
+
+const u8 DecorDesc_PRETTY_CHAIR[] = _(
+ "A small chair made\n"
+ "of glass.");
+
+const u8 DecorDesc_COMFORT_CHAIR[] = _(
+ "A small chair made\n"
+ "of leaves.");
+
+const u8 DecorDesc_RAGGED_CHAIR[] = _(
+ "A small chair made\n"
+ "of wood.");
+
+const u8 DecorDesc_BRICK_CHAIR[] = _(
+ "A small chair made\n"
+ "of brick.");
+
+const u8 DecorDesc_CAMP_CHAIR[] = _(
+ "A small chair made\n"
+ "of logs.");
+
+const u8 DecorDesc_HARD_CHAIR[] = _(
+ "A small chair made\n"
+ "of rock.");
+
+const u8 DecorDesc_RED_PLANT[] = _(
+ "A vivid red potted\n"
+ "plant.");
+
+const u8 DecorDesc_TROPICAL_PLANT[] = _(
+ "A flowering tropical\n"
+ "plant in a pot.");
+
+const u8 DecorDesc_PRETTY_FLOWERS[] = _(
+ "A pot of cute\n"
+ "flowers.");
+
+const u8 DecorDesc_COLORFUL_PLANT[] = _(
+ "A large pot with\n"
+ "many colorful\n"
+ "flowers.");
+
+const u8 DecorDesc_BIG_PLANT[] = _(
+ "A large, umbrella-\n"
+ "shaped plant in a\n"
+ "big pot.");
+
+const u8 DecorDesc_GORGEOUS_PLANT[] = _(
+ "A large, impressive\n"
+ "plant in a big pot.");
+
+const u8 DecorDesc_RED_BRICK[] = _(
+ "A red-colored brick.\n"
+ "Decorations can be\n"
+ "placed on top.");
+
+const u8 DecorDesc_YELLOW_BRICK[] = _(
+ "A yellow-colored\n"
+ "brick. Put some\n"
+ "decorations on top.");
+
+const u8 DecorDesc_BLUE_BRICK[] = _(
+ "A blue-colored\n"
+ "brick. Put some\n"
+ "decorations on top.");
+
+const u8 DecorDesc_RED_BALLOON[] = _(
+ "A red balloon filled\n"
+ "with water. Bursts\n"
+ "if stepped on.");
+
+const u8 DecorDesc_BLUE_BALLOON[] = _(
+ "A blue balloon filled\n"
+ "with water. Bursts\n"
+ "if stepped on.");
+
+const u8 DecorDesc_YELLOW_BALLOON[] = _(
+ "A yellow balloon\n"
+ "filled with water.\n"
+ "Pops if stepped on.");
+
+const u8 DecorDesc_RED_TENT[] = _(
+ "A large red tent.\n"
+ "You can hide inside\n"
+ "it.");
+
+const u8 DecorDesc_BLUE_TENT[] = _(
+ "A large blue tent.\n"
+ "You can hide inside\n"
+ "it.");
+
+const u8 DecorDesc_SOLID_BOARD[] = _(
+ "Place over a hole to\n"
+ "cross to the other\n"
+ "side.");
+
+const u8 DecorDesc_SLIDE[] = _(
+ "Use to slide down\n"
+ "from the platform.");
+
+const u8 DecorDesc_FENCE_LENGTH[] = _(
+ "A small fence that\n"
+ "blocks passage.");
+
+const u8 DecorDesc_FENCE_WIDTH[] = _(
+ "A small fence that\n"
+ "blocks passage.");
+
+const u8 DecorDesc_TIRE[] = _(
+ "An old large tire.\n"
+ "Decorations can be\n"
+ "placed on top.");
+
+const u8 DecorDesc_STAND[] = _(
+ "A large pedestal\n"
+ "with steps.");
+
+const u8 DecorDesc_MUD_BALL[] = _(
+ "A large ball of mud.\n"
+ "Crumbles if stepped\n"
+ "on.");
+
+const u8 DecorDesc_BREAKABLE_DOOR[] = _(
+ "A weird door that\n"
+ "people can walk\n"
+ "right through.");
+
+const u8 DecorDesc_SAND_ORNAMENT[] = _(
+ "An ornament made\n"
+ "of sand. Crumbles if\n"
+ "touched.");
+
+const u8 DecorDesc_SILVER_SHIELD[] = _(
+ "Awarded for 50\n"
+ "straight wins at\n"
+ "the BATTLE TOWER.");
+
+const u8 DecorDesc_GOLD_SHIELD[] = _(
+ "Awarded for 100\n"
+ "straight wins at\n"
+ "the BATTLE TOWER.");
+
+const u8 DecorDesc_GLASS_ORNAMENT[] = _(
+ "A glass replica of\n"
+ "a famous sculpture\n"
+ "at the ART MUSEUM.");
+
+const u8 DecorDesc_TV[] = _(
+ "A small, gray-\n"
+ "colored toy TV.");
+
+const u8 DecorDesc_ROUND_TV[] = _(
+ "A toy TV modeled\n"
+ "in the image of a\n"
+ "SEEDOT.");
+
+const u8 DecorDesc_CUTE_TV[] = _(
+ "A toy TV modeled\n"
+ "in the image of a\n"
+ "SKITTY.");
+
+const u8 DecorDesc_GLITTER_MAT[] = _(
+ "An odd mat that\n"
+ "glitters if stepped\n"
+ "on.");
+
+const u8 DecorDesc_JUMP_MAT[] = _(
+ "A trick mat that\n"
+ "jumps when it is\n"
+ "stepped on.");
+
+const u8 DecorDesc_SPIN_MAT[] = _(
+ "A trick mat that\n"
+ "spins around when\n"
+ "stepped on.");
+
+const u8 DecorDesc_C_LOW_NOTE_MAT[] = _(
+ "A mat that plays\n"
+ "a low C note when\n"
+ "stepped on.");
+
+const u8 DecorDesc_D_NOTE_MAT[] = _(
+ "A mat that plays\n"
+ "a D note when\n"
+ "stepped on.");
+
+const u8 DecorDesc_E_NOTE_MAT[] = _(
+ "A mat that plays\n"
+ "an E note when\n"
+ "stepped on.");
+
+const u8 DecorDesc_F_NOTE_MAT[] = _(
+ "A mat that plays\n"
+ "an F note when\n"
+ "stepped on.");
+
+const u8 DecorDesc_G_NOTE_MAT[] = _(
+ "A mat that plays\n"
+ "a G note when\n"
+ "stepped on.");
+
+const u8 DecorDesc_A_NOTE_MAT[] = _(
+ "A mat that plays\n"
+ "an A note when\n"
+ "stepped on.");
+
+const u8 DecorDesc_B_NOTE_MAT[] = _(
+ "A mat that plays\n"
+ "a B note when\n"
+ "stepped on.");
+
+const u8 DecorDesc_C_HIGH_NOTE_MAT[] = _(
+ "A mat that plays\n"
+ "a high C note when\n"
+ "stepped on.");
+
+const u8 DecorDesc_SURF_MAT[] = _(
+ "A mat designed with\n"
+ "a SURF image.\n"
+ "Put items on top.");
+
+const u8 DecorDesc_THUNDER_MAT[] = _(
+ "A mat designed with\n"
+ "a THUNDER image.\n"
+ "Put items on top.");
+
+const u8 DecorDesc_FIRE_BLAST_MAT[] = _(
+ "A mat designed with\n"
+ "a FIRE BLAST image.\n"
+ "Put items on top.");
+
+const u8 DecorDesc_POWDER_SNOW_MAT[] = _(
+ "A mat with a POWDER\n"
+ "SNOW image design.\n"
+ "Put items on top.");
+
+const u8 DecorDesc_ATTRACT_MAT[] = _(
+ "A mat designed with\n"
+ "an ATTRACT image.\n"
+ "Put items on top.");
+
+const u8 DecorDesc_FISSURE_MAT[] = _(
+ "A mat designed with\n"
+ "a FISSURE image.\n"
+ "Put items on top.");
+
+const u8 DecorDesc_SPIKES_MAT[] = _(
+ "A mat designed with\n"
+ "a SPIKES image.\n"
+ "Put items on top.");
+
+const u8 DecorDesc_BALL_POSTER[] = _(
+ "A small poster\n"
+ "printed with POKé\n"
+ "BALLS.");
+
+const u8 DecorDesc_GREEN_POSTER[] = _(
+ "A small poster with\n"
+ "a TREECKO print.");
+
+const u8 DecorDesc_RED_POSTER[] = _(
+ "A small poster with\n"
+ "a TORCHIC print.");
+
+const u8 DecorDesc_BLUE_POSTER[] = _(
+ "A small poster with\n"
+ "a MUDKIP print.");
+
+const u8 DecorDesc_CUTE_POSTER[] = _(
+ "A small poster with\n"
+ "an AZURILL print.");
+
+const u8 DecorDesc_PIKA_POSTER[] = _(
+ "A large poster with\n"
+ "a PIKACHU and\n"
+ "PICHU print.");
+
+const u8 DecorDesc_LONG_POSTER[] = _(
+ "A large poster with\n"
+ "a SEVIPER print.");
+
+const u8 DecorDesc_SEA_POSTER[] = _(
+ "A large poster with\n"
+ "a RELICANTH print.");
+
+const u8 DecorDesc_SKY_POSTER[] = _(
+ "A large poster with\n"
+ "a WINGULL print.");
+
+const u8 DecorDesc_KISS_POSTER[] = _(
+ "A large poster with\n"
+ "a SMOOCHUM print.");
+
+const u8 DecorDesc_PICHU_DOLL[] = _(
+ "A PICHU doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_PIKACHU_DOLL[] = _(
+ "A PIKACHU doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_MARILL_DOLL[] = _(
+ "A MARILL doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_TOGEPI_DOLL[] = _(
+#if REVISION >= 1
+ "A TOGEPI doll.\n"
+#else
+ "A TOPGEPI doll.\n"
+#endif
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_CYNDAQUIL_DOLL[] = _(
+ "A CYNDAQUIL doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_CHIKORITA_DOLL[] = _(
+ "A CHIKORITA doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_TOTODILE_DOLL[] = _(
+ "A TOTODILE doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_JIGGLYPUFF_DOLL[] = _(
+ "A JIGGLYPUFF doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_MEOWTH_DOLL[] = _(
+ "A MEOWTH doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_CLEFAIRY_DOLL[] = _(
+ "A CLEFAIRY doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_DITTO_DOLL[] = _(
+ "A DITTO doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_SMOOCHUM_DOLL[] = _(
+ "A SMOOCHUM doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_TREECKO_DOLL[] = _(
+ "A TREECKO doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_TORCHIC_DOLL[] = _(
+ "A TORCHIC doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_MUDKIP_DOLL[] = _(
+ "A MUDKIP doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_DUSKULL_DOLL[] = _(
+ "A DUSKULL doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_WYNAUT_DOLL[] = _(
+ "A WYNAUT doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_BALTOY_DOLL[] = _(
+ "A BALTOY doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_KECLEON_DOLL[] = _(
+ "A KECLEON doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_AZURILL_DOLL[] = _(
+ "An AZURILL doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_SKITTY_DOLL[] = _(
+ "A SKITTY doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_SWABLU_DOLL[] = _(
+ "A SWABLU doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_GULPIN_DOLL[] = _(
+ "A GULPIN doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_LOTAD_DOLL[] = _(
+ "A LOTAD doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_SEEDOT_DOLL[] = _(
+ "A SEEDOT doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_PIKA_CUSHION[] = _(
+ "A PIKACHU cushion.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_ROUND_CUSHION[] = _(
+ "A MARILL cushion.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_KISS_CUSHION[] = _(
+ "A SMOOCHUM\n"
+ "cushion. Place it on\n"
+ "a mat or a desk.");
+
+const u8 DecorDesc_ZIGZAG_CUSHION[] = _(
+ "A ZIGZAGOON\n"
+ "cushion. Place it on\n"
+ "a mat or a desk.");
+
+const u8 DecorDesc_SPIN_CUSHION[] = _(
+ "A SPINDA cushion.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_DIAMOND_CUSHION[] = _(
+ "A SABLEYE cushion.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_BALL_CUSHION[] = _(
+ "A BALL cushion.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_GRASS_CUSHION[] = _(
+ "A grass-mark\n"
+ "cushion. Place it on\n"
+ "a mat or a desk.");
+
+const u8 DecorDesc_FIRE_CUSHION[] = _(
+ "A fire-mark\n"
+ "cushion. Place it on\n"
+ "a mat or a desk.");
+
+const u8 DecorDesc_WATER_CUSHION[] = _(
+ "A water-mark\n"
+ "cushion. Place it on\n"
+ "a mat or a desk.");
+
+const u8 DecorDesc_SNORLAX_DOLL[] = _(
+ "A large doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_RHYDON_DOLL[] = _(
+ "A large doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_LAPRAS_DOLL[] = _(
+ "A large doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_VENUSAUR_DOLL[] = _(
+ "A large doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_CHARIZARD_DOLL[] = _(
+ "A large doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_BLASTOISE_DOLL[] = _(
+ "A large doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_WAILMER_DOLL[] = _(
+ "A large doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_REGIROCK_DOLL[] = _(
+ "A large doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_REGICE_DOLL[] = _(
+ "A large doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+
+const u8 DecorDesc_REGISTEEL_DOLL[] = _(
+ "A large doll.\n"
+ "Place it on a mat\n"
+ "or a desk.");
+#elif GERMAN
+#include "../data/decoration/descriptions_de.h"
+#endif
+
+const u16 DecorGfx_SMALL_DESK[] = {
+ 0x87
+};
+
+const u16 DecorGfx_POKEMON_DESK[] = {
+ 0x8F
+};
+
+const u16 DecorGfx_HEAVY_DESK[] = {
+ 0x90,
+ 0x91,
+ 0x92,
+ 0x98,
+ 0x99,
+ 0x9A
+};
+
+const u16 DecorGfx_RAGGED_DESK[] = {
+ 0x93,
+ 0x94,
+ 0x95,
+ 0x9B,
+ 0x9C,
+ 0x9D
+};
+
+const u16 DecorGfx_COMFORT_DESK[] = {
+ 0x96,
+ 0x97,
+ 0xA3,
+ 0x9E,
+ 0x9F,
+ 0xAB
+};
+
+const u16 DecorGfx_PRETTY_DESK[] = {
+ 0xBD,
+ 0xBE,
+ 0xBF,
+ 0xC5,
+ 0xC6,
+ 0xC7,
+ 0xCD,
+ 0xCE,
+ 0xCF
+};
+
+const u16 DecorGfx_BRICK_DESK[] = {
+ 0xA0,
+ 0xA1,
+ 0xA2,
+ 0xA8,
+ 0xA9,
+ 0xAA,
+ 0xB0,
+ 0xB1,
+ 0xB2
+};
+
+const u16 DecorGfx_CAMP_DESK[] = {
+ 0xA4,
+ 0xA5,
+ 0xA6,
+ 0xAC,
+ 0xAD,
+ 0xAE,
+ 0xB4,
+ 0xB5,
+ 0xB6
+};
+
+const u16 DecorGfx_HARD_DESK[] = {
+ 0xA7,
+ 0xBB,
+ 0xBC,
+ 0xAF,
+ 0xC3,
+ 0xC4,
+ 0xB7,
+ 0xCB,
+ 0xCC
+};
+
+const u16 DecorGfx_SMALL_CHAIR[] = {
+ 0xB8
+};
+
+const u16 DecorGfx_POKEMON_CHAIR[] = {
+ 0xB9
+};
+
+const u16 DecorGfx_HEAVY_CHAIR[] = {
+ 0xBA
+};
+
+const u16 DecorGfx_PRETTY_CHAIR[] = {
+ 0xC0
+};
+
+const u16 DecorGfx_COMFORT_CHAIR[] = {
+ 0xC1
+};
+
+const u16 DecorGfx_RAGGED_CHAIR[] = {
+ 0xC2
+};
+
+const u16 DecorGfx_BRICK_CHAIR[] = {
+ 0xC8
+};
+
+const u16 DecorGfx_CAMP_CHAIR[] = {
+ 0xC9
+};
+
+const u16 DecorGfx_HARD_CHAIR[] = {
+ 0xCA
+};
+
+const u16 DecorGfx_RED_PLANT[] = {
+ 0xD0,
+ 0xD8
+};
+
+const u16 DecorGfx_TROPICAL_PLANT[] = {
+ 0xD2,
+ 0xDA
+};
+
+const u16 DecorGfx_PRETTY_FLOWERS[] = {
+ 0xD4,
+ 0xDC
+};
+
+const u16 DecorGfx_COLORFUL_PLANT[] = {
+ 0xE0,
+ 0xE2,
+ 0xE8,
+ 0xE9
+};
+
+const u16 DecorGfx_BIG_PLANT[] = {
+ 0xE4,
+ 0xE6,
+ 0xEC,
+ 0xED
+};
+
+const u16 DecorGfx_GORGEOUS_PLANT[] = {
+ 0xF0,
+ 0xF2,
+ 0xF8,
+ 0xF9
+};
+
+const u16 DecorGfx_RED_BRICK[] = {
+ 0x25,
+ 0x2D
+};
+
+const u16 DecorGfx_YELLOW_BRICK[] = {
+ 0x26,
+ 0x2E
+};
+
+const u16 DecorGfx_BLUE_BRICK[] = {
+ 0x27,
+ 0x2F
+};
+
+const u16 DecorGfx_RED_BALLOON[] = {
+ 0x138
+};
+
+const u16 DecorGfx_BLUE_BALLOON[] = {
+ 0x13C
+};
+
+const u16 DecorGfx_YELLOW_BALLOON[] = {
+ 0x140
+};
+
+const u16 DecorGfx_RED_TENT[] = {
+ 0x30,
+ 0x31,
+ 0x32,
+ 0x38,
+ 0x39,
+ 0x3A,
+ 0x40,
+ 0x41,
+ 0x3B
+};
+
+const u16 DecorGfx_BLUE_TENT[] = {
+ 0x48,
+ 0x49,
+ 0x68,
+ 0x50,
+ 0x51,
+ 0x70,
+ 0x58,
+ 0x59,
+ 0x69
+};
+
+const u16 DecorGfx_SOLID_BOARD[] = {
+ 0x34,
+ 0x3C
+};
+
+const u16 DecorGfx_SLIDE[] = {
+ 0x35,
+ 0x36,
+ 0x3D,
+ 0x3E,
+ 0x63,
+ 0x64,
+ 0x6F,
+ 0x77
+};
+
+const u16 DecorGfx_FENCE_LENGTH[] = {
+ 0x33
+};
+
+const u16 DecorGfx_FENCE_WIDTH[] = {
+ 0x2C
+};
+
+const u16 DecorGfx_TIRE[] = {
+ 0x80,
+ 0x81,
+ 0x88,
+ 0x89
+};
+
+const u16 DecorGfx_STAND[] = {
+ 0x6A,
+ 0x6B,
+ 0x6C,
+ 0x6D,
+ 0x72,
+ 0x73,
+ 0x74,
+ 0x75
+};
+
+const u16 DecorGfx_MUD_BALL[] = {
+ 0x28
+};
+
+const u16 DecorGfx_BREAKABLE_DOOR[] = {
+ 0x37,
+ 0x3F
+};
+
+const u16 DecorGfx_SAND_ORNAMENT[] = {
+ 0x85,
+ 0x8D
+};
+
+const u16 DecorGfx_SILVER_SHIELD[] = {
+ 0xD6,
+ 0xDE
+};
+
+const u16 DecorGfx_GOLD_SHIELD[] = {
+ 0x12E,
+ 0x136
+};
+
+const u16 DecorGfx_GLASS_ORNAMENT[] = {
+ 0x82,
+ 0x8A
+};
+
+const u16 DecorGfx_TV[] = {
+ 0xF4
+};
+
+const u16 DecorGfx_ROUND_TV[] = {
+ 0xF5
+};
+
+const u16 DecorGfx_CUTE_TV[] = {
+ 0xF6
+};
+
+const u16 DecorGfx_GLITTER_MAT[] = {
+ 0x60
+};
+
+const u16 DecorGfx_JUMP_MAT[] = {
+ 0x61
+};
+
+const u16 DecorGfx_SPIN_MAT[] = {
+ 0x62
+};
+
+const u16 DecorGfx_C_LOW_NOTE_MAT[] = {
+ 0x78
+};
+
+const u16 DecorGfx_D_NOTE_MAT[] = {
+ 0x79
+};
+
+const u16 DecorGfx_E_NOTE_MAT[] = {
+ 0x7A
+};
+
+const u16 DecorGfx_F_NOTE_MAT[] = {
+ 0x7B
+};
+
+const u16 DecorGfx_G_NOTE_MAT[] = {
+ 0x7C
+};
+
+const u16 DecorGfx_A_NOTE_MAT[] = {
+ 0x7D
+};
+
+const u16 DecorGfx_B_NOTE_MAT[] = {
+ 0x7E
+};
+
+const u16 DecorGfx_C_HIGH_NOTE_MAT[] = {
+ 0xB3
+};
+
+const u16 DecorGfx_SURF_MAT[] = {
+ 0x42,
+ 0x43,
+ 0x44,
+ 0x4A,
+ 0x4B,
+ 0x4C,
+ 0x52,
+ 0x53,
+ 0x54
+};
+
+const u16 DecorGfx_THUNDER_MAT[] = {
+ 0x45,
+ 0x46,
+ 0x47,
+ 0x4D,
+ 0x4E,
+ 0x4F,
+ 0x55,
+ 0x56,
+ 0x57
+};
+
+const u16 DecorGfx_FIRE_BLAST_MAT[] = {
+ 0x5A,
+ 0x5B,
+ 0x5C,
+ 0x5D,
+ 0x5E,
+ 0x5F,
+ 0x65,
+ 0x66,
+ 0x67
+};
+
+const u16 DecorGfx_POWDER_SNOW_MAT[] = {
+ 0x100,
+ 0x101,
+ 0x102,
+ 0x108,
+ 0x109,
+ 0x10A,
+ 0x110,
+ 0x111,
+ 0x112
+};
+
+const u16 DecorGfx_ATTRACT_MAT[] = {
+ 0x103,
+ 0x104,
+ 0x105,
+ 0x10B,
+ 0x10C,
+ 0x10D,
+ 0x113,
+ 0x114,
+ 0x115
+};
+
+const u16 DecorGfx_FISSURE_MAT[] = {
+ 0x106,
+ 0x107,
+ 0x118,
+ 0x10E,
+ 0x10F,
+ 0x120,
+ 0x116,
+ 0x117,
+ 0x128
+};
+
+const u16 DecorGfx_SPIKES_MAT[] = {
+ 0x119,
+ 0x11A,
+ 0x11B,
+ 0x121,
+ 0x122,
+ 0x123,
+ 0x129,
+ 0x12A,
+ 0x12B
+};
+
+const u16 DecorGfx_BALL_POSTER[] = {
+ 0x130
+};
+
+const u16 DecorGfx_GREEN_POSTER[] = {
+ 0x131
+};
+
+const u16 DecorGfx_RED_POSTER[] = {
+ 0x132
+};
+
+const u16 DecorGfx_BLUE_POSTER[] = {
+ 0x133
+};
+
+const u16 DecorGfx_CUTE_POSTER[] = {
+ 0x134
+};
+
+const u16 DecorGfx_PIKA_POSTER[] = {
+ 0x11C,
+ 0x11D
+};
+
+const u16 DecorGfx_LONG_POSTER[] = {
+ 0x11E,
+ 0x11F
+};
+
+const u16 DecorGfx_SEA_POSTER[] = {
+ 0x124,
+ 0x125
+};
+
+const u16 DecorGfx_SKY_POSTER[] = {
+ 0x126,
+ 0x127
+};
+
+const u16 DecorGfx_KISS_POSTER[] = {
+ 0x12C,
+ 0x12D
+};
+
+const u16 DecorGfx_PICHU_DOLL[] = {
+ MAP_OBJ_GFX_PICHU_DOLL
+};
+
+const u16 DecorGfx_PIKACHU_DOLL[] = {
+ MAP_OBJ_GFX_PIKACHU_DOLL
+};
+
+const u16 DecorGfx_MARILL_DOLL[] = {
+ MAP_OBJ_GFX_MARILL_DOLL
+};
+
+const u16 DecorGfx_TOGEPI_DOLL[] = {
+ MAP_OBJ_GFX_TOGEPI_DOLL
+};
+
+const u16 DecorGfx_CYNDAQUIL_DOLL[] = {
+ MAP_OBJ_GFX_CYNDAQUIL_DOLL
+};
+
+const u16 DecorGfx_CHIKORITA_DOLL[] = {
+ MAP_OBJ_GFX_CHIKORITA_DOLL
+};
+
+const u16 DecorGfx_TOTODILE_DOLL[] = {
+ MAP_OBJ_GFX_TOTODILE_DOLL
+};
+
+const u16 DecorGfx_JIGGLYPUFF_DOLL[] = {
+ MAP_OBJ_GFX_JIGGLYPUFF_DOLL
+};
+
+const u16 DecorGfx_MEOWTH_DOLL[] = {
+ MAP_OBJ_GFX_MEOWTH_DOLL
+};
+
+const u16 DecorGfx_CLEFAIRY_DOLL[] = {
+ MAP_OBJ_GFX_CLEFAIRY_DOLL
+};
+
+const u16 DecorGfx_DITTO_DOLL[] = {
+ MAP_OBJ_GFX_DITTO_DOLL
+};
+
+const u16 DecorGfx_SMOOCHUM_DOLL[] = {
+ MAP_OBJ_GFX_SMOOCHUM_DOLL
+};
+
+const u16 DecorGfx_TREECKO_DOLL[] = {
+ MAP_OBJ_GFX_TREECKO_DOLL
+};
+
+const u16 DecorGfx_TORCHIC_DOLL[] = {
+ MAP_OBJ_GFX_TORCHIC_DOLL
+};
+
+const u16 DecorGfx_MUDKIP_DOLL[] = {
+ MAP_OBJ_GFX_MUDKIP_DOLL
+};
+
+const u16 DecorGfx_DUSKULL_DOLL[] = {
+ MAP_OBJ_GFX_DUSKULL_DOLL
+};
+
+const u16 DecorGfx_WYNAUT_DOLL[] = {
+ MAP_OBJ_GFX_WYNAUT_DOLL
+};
+
+const u16 DecorGfx_BALTOY_DOLL[] = {
+ MAP_OBJ_GFX_BALTOY_DOLL
+};
+
+const u16 DecorGfx_KECLEON_DOLL[] = {
+ MAP_OBJ_GFX_KECLEON_DOLL
+};
+
+const u16 DecorGfx_AZURILL_DOLL[] = {
+ MAP_OBJ_GFX_AZURILL_DOLL
+};
+
+const u16 DecorGfx_SKITTY_DOLL[] = {
+ MAP_OBJ_GFX_SKITTY_DOLL
+};
+
+const u16 DecorGfx_SWABLU_DOLL[] = {
+ MAP_OBJ_GFX_SWABLU_DOLL
+};
+
+const u16 DecorGfx_GULPIN_DOLL[] = {
+ MAP_OBJ_GFX_GULPIN_DOLL
+};
+
+const u16 DecorGfx_LOTAD_DOLL[] = {
+ MAP_OBJ_GFX_LOTAD_DOLL
+};
+
+const u16 DecorGfx_SEEDOT_DOLL[] = {
+ MAP_OBJ_GFX_SEEDOT_DOLL
+};
+
+const u16 DecorGfx_PIKA_CUSHION[] = {
+ MAP_OBJ_GFX_PIKA_CUSHION
+};
+
+const u16 DecorGfx_ROUND_CUSHION[] = {
+ MAP_OBJ_GFX_ROUND_CUSHION
+};
+
+const u16 DecorGfx_KISS_CUSHION[] = {
+ MAP_OBJ_GFX_KISS_CUSHION
+};
+
+const u16 DecorGfx_ZIGZAG_CUSHION[] = {
+ MAP_OBJ_GFX_ZIGZAG_CUSHION
+};
+
+const u16 DecorGfx_SPIN_CUSHION[] = {
+ MAP_OBJ_GFX_SPIN_CUSHION
+};
+
+const u16 DecorGfx_DIAMOND_CUSHION[] = {
+ MAP_OBJ_GFX_DIAMOND_CUSHION
+};
+
+const u16 DecorGfx_BALL_CUSHION[] = {
+ MAP_OBJ_GFX_BALL_CUSHION
+};
+
+const u16 DecorGfx_GRASS_CUSHION[] = {
+ MAP_OBJ_GFX_GRASS_CUSHION
+};
+
+const u16 DecorGfx_FIRE_CUSHION[] = {
+ MAP_OBJ_GFX_FIRE_CUSHION
+};
+
+const u16 DecorGfx_WATER_CUSHION[] = {
+ MAP_OBJ_GFX_WATER_CUSHION
+};
+
+const u16 DecorGfx_SNORLAX_DOLL[] = {
+ MAP_OBJ_GFX_BIG_SNORLAX_DOLL
+};
+
+const u16 DecorGfx_RHYDON_DOLL[] = {
+ MAP_OBJ_GFX_BIG_RHYDON_DOLL
+};
+
+const u16 DecorGfx_LAPRAS_DOLL[] = {
+ MAP_OBJ_GFX_BIG_LAPRAS_DOLL
+};
+
+const u16 DecorGfx_VENUSAUR_DOLL[] = {
+ MAP_OBJ_GFX_BIG_VENUSAUR_DOLL
+};
+
+const u16 DecorGfx_CHARIZARD_DOLL[] = {
+ MAP_OBJ_GFX_BIG_CHARIZARD_DOLL
+};
+
+const u16 DecorGfx_BLASTOISE_DOLL[] = {
+ MAP_OBJ_GFX_BIG_BLASTOISE_DOLL
+};
+
+const u16 DecorGfx_WAILMER_DOLL[] = {
+ MAP_OBJ_GFX_BIG_WAILMER_DOLL
+};
+
+const u16 DecorGfx_REGIROCK_DOLL[] = {
+ MAP_OBJ_GFX_BIG_REGIROCK_DOLL
+};
+
+const u16 DecorGfx_REGICE_DOLL[] = {
+ MAP_OBJ_GFX_BIG_REGICE_DOLL
+};
+
+const u16 DecorGfx_REGISTEEL_DOLL[] = {
+ MAP_OBJ_GFX_BIG_REGISTEEL_DOLL
+};
+
+#if ENGLISH
+const struct Decoration gDecorations[] = {
+ {DECOR_NONE, _("SMALL DESK"), DECORPERM_SOLID_FLOOR, DECORSHAPE_1x1, DECORCAT_DESK, 0, DecorDesc_SMALL_DESK, DecorGfx_SMALL_DESK},
+ {DECOR_SMALL_DESK, _("SMALL DESK"), DECORPERM_SOLID_FLOOR, DECORSHAPE_1x1, DECORCAT_DESK, 3000, DecorDesc_SMALL_DESK, DecorGfx_SMALL_DESK},
+ {DECOR_POKEMON_DESK, _("POKéMON DESK"), DECORPERM_SOLID_FLOOR, DECORSHAPE_1x1, DECORCAT_DESK, 3000, DecorDesc_POKEMON_DESK, DecorGfx_POKEMON_DESK},
+ {DECOR_HEAVY_DESK, _("HEAVY DESK"), DECORPERM_SOLID_FLOOR, DECORSHAPE_3x2, DECORCAT_DESK, 6000, DecorDesc_HEAVY_DESK, DecorGfx_HEAVY_DESK},
+ {DECOR_RAGGED_DESK, _("RAGGED DESK"), DECORPERM_SOLID_FLOOR, DECORSHAPE_3x2, DECORCAT_DESK, 6000, DecorDesc_RAGGED_DESK, DecorGfx_RAGGED_DESK},
+ {DECOR_COMFORT_DESK, _("COMFORT DESK"), DECORPERM_SOLID_FLOOR, DECORSHAPE_3x2, DECORCAT_DESK, 6000, DecorDesc_COMFORT_DESK, DecorGfx_COMFORT_DESK},
+ {DECOR_PRETTY_DESK, _("PRETTY DESK"), DECORPERM_SOLID_FLOOR, DECORSHAPE_3x3, DECORCAT_DESK, 9000, DecorDesc_PRETTY_DESK, DecorGfx_PRETTY_DESK},
+ {DECOR_BRICK_DESK, _("BRICK DESK"), DECORPERM_SOLID_FLOOR, DECORSHAPE_3x3, DECORCAT_DESK, 9000, DecorDesc_BRICK_DESK, DecorGfx_BRICK_DESK},
+ {DECOR_CAMP_DESK, _("CAMP DESK"), DECORPERM_SOLID_FLOOR, DECORSHAPE_3x3, DECORCAT_DESK, 9000, DecorDesc_CAMP_DESK, DecorGfx_CAMP_DESK},
+ {DECOR_HARD_DESK, _("HARD DESK"), DECORPERM_SOLID_FLOOR, DECORSHAPE_3x3, DECORCAT_DESK, 9000, DecorDesc_HARD_DESK, DecorGfx_HARD_DESK},
+ {DECOR_SMALL_CHAIR, _("SMALL CHAIR"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_CHAIR, 2000, DecorDesc_SMALL_CHAIR, DecorGfx_SMALL_CHAIR},
+ {DECOR_POKEMON_CHAIR, _("POKéMON CHAIR"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_CHAIR, 2000, DecorDesc_POKEMON_CHAIR, DecorGfx_POKEMON_CHAIR},
+ {DECOR_HEAVY_CHAIR, _("HEAVY CHAIR"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_CHAIR, 2000, DecorDesc_HEAVY_CHAIR, DecorGfx_HEAVY_CHAIR},
+ {DECOR_PRETTY_CHAIR, _("PRETTY CHAIR"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_CHAIR, 2000, DecorDesc_PRETTY_CHAIR, DecorGfx_PRETTY_CHAIR},
+ {DECOR_COMFORT_CHAIR, _("COMFORT CHAIR"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_CHAIR, 2000, DecorDesc_COMFORT_CHAIR, DecorGfx_COMFORT_CHAIR},
+ {DECOR_RAGGED_CHAIR, _("RAGGED CHAIR"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_CHAIR, 2000, DecorDesc_RAGGED_CHAIR, DecorGfx_RAGGED_CHAIR},
+ {DECOR_BRICK_CHAIR, _("BRICK CHAIR"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_CHAIR, 2000, DecorDesc_BRICK_CHAIR, DecorGfx_BRICK_CHAIR},
+ {DECOR_CAMP_CHAIR, _("CAMP CHAIR"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_CHAIR, 2000, DecorDesc_CAMP_CHAIR, DecorGfx_CAMP_CHAIR},
+ {DECOR_HARD_CHAIR, _("HARD CHAIR"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_CHAIR, 2000, DecorDesc_HARD_CHAIR, DecorGfx_HARD_CHAIR},
+ {DECOR_RED_PLANT, _("RED PLANT"), DECORPERM_BEHIND_FLOOR, DECORSHAPE_1x2, DECORCAT_PLANT, 3000, DecorDesc_RED_PLANT, DecorGfx_RED_PLANT},
+ {DECOR_TROPICAL_PLANT, _("TROPICAL PLANT"), DECORPERM_BEHIND_FLOOR, DECORSHAPE_1x2, DECORCAT_PLANT, 3000, DecorDesc_TROPICAL_PLANT, DecorGfx_TROPICAL_PLANT},
+ {DECOR_PRETTY_FLOWERS, _("PRETTY FLOWERS"), DECORPERM_BEHIND_FLOOR, DECORSHAPE_1x2, DECORCAT_PLANT, 3000, DecorDesc_PRETTY_FLOWERS, DecorGfx_PRETTY_FLOWERS},
+ {DECOR_COLORFUL_PLANT, _("COLORFUL PLANT"), DECORPERM_BEHIND_FLOOR, DECORSHAPE_2x2, DECORCAT_PLANT, 5000, DecorDesc_COLORFUL_PLANT, DecorGfx_COLORFUL_PLANT},
+ {DECOR_BIG_PLANT, _("BIG PLANT"), DECORPERM_BEHIND_FLOOR, DECORSHAPE_2x2, DECORCAT_PLANT, 5000, DecorDesc_BIG_PLANT, DecorGfx_BIG_PLANT},
+ {DECOR_GORGEOUS_PLANT, _("GORGEOUS PLANT"), DECORPERM_BEHIND_FLOOR, DECORSHAPE_2x2, DECORCAT_PLANT, 5000, DecorDesc_GORGEOUS_PLANT, DecorGfx_GORGEOUS_PLANT},
+ {DECOR_RED_BRICK, _("RED BRICK"), DECORPERM_SOLID_FLOOR, DECORSHAPE_1x2, DECORCAT_ORNAMENT, 500, DecorDesc_RED_BRICK, DecorGfx_RED_BRICK},
+ {DECOR_YELLOW_BRICK, _("YELLOW BRICK"), DECORPERM_SOLID_FLOOR, DECORSHAPE_1x2, DECORCAT_ORNAMENT, 500, DecorDesc_YELLOW_BRICK, DecorGfx_YELLOW_BRICK},
+ {DECOR_BLUE_BRICK, _("BLUE BRICK"), DECORPERM_SOLID_FLOOR, DECORSHAPE_1x2, DECORCAT_ORNAMENT, 500, DecorDesc_BLUE_BRICK, DecorGfx_BLUE_BRICK},
+ {DECOR_RED_BALLOON, _("RED BALLOON"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_ORNAMENT, 500, DecorDesc_RED_BALLOON, DecorGfx_RED_BALLOON},
+ {DECOR_BLUE_BALLOON, _("BLUE BALLOON"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_ORNAMENT, 500, DecorDesc_BLUE_BALLOON, DecorGfx_BLUE_BALLOON},
+ {DECOR_YELLOW_BALLOON, _("YELLOW BALLOON"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_ORNAMENT, 500, DecorDesc_YELLOW_BALLOON, DecorGfx_YELLOW_BALLOON},
+ {DECOR_RED_TENT, _("RED TENT"), DECORPERM_PASS_FLOOR, DECORSHAPE_3x3, DECORCAT_ORNAMENT, 10000, DecorDesc_RED_TENT, DecorGfx_RED_TENT},
+ {DECOR_BLUE_TENT, _("BLUE TENT"), DECORPERM_PASS_FLOOR, DECORSHAPE_3x3, DECORCAT_ORNAMENT, 10000, DecorDesc_BLUE_TENT, DecorGfx_BLUE_TENT},
+ {DECOR_SOLID_BOARD, _("SOLID BOARD"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x2, DECORCAT_ORNAMENT, 3000, DecorDesc_SOLID_BOARD, DecorGfx_SOLID_BOARD},
+ {DECOR_SLIDE, _("SLIDE"), DECORPERM_PASS_FLOOR, DECORSHAPE_2x4, DECORCAT_ORNAMENT, 8000, DecorDesc_SLIDE, DecorGfx_SLIDE},
+ {DECOR_FENCE_LENGTH, _("FENCE LENGTH"), DECORPERM_SOLID_FLOOR, DECORSHAPE_1x1, DECORCAT_ORNAMENT, 500, DecorDesc_FENCE_LENGTH, DecorGfx_FENCE_LENGTH},
+ {DECOR_FENCE_WIDTH, _("FENCE WIDTH"), DECORPERM_SOLID_FLOOR, DECORSHAPE_1x1, DECORCAT_ORNAMENT, 500, DecorDesc_FENCE_WIDTH, DecorGfx_FENCE_WIDTH},
+ {DECOR_TIRE, _("TIRE"), DECORPERM_SOLID_FLOOR, DECORSHAPE_2x2, DECORCAT_ORNAMENT, 800, DecorDesc_TIRE, DecorGfx_TIRE},
+ {DECOR_STAND, _("STAND"), DECORPERM_PASS_FLOOR, DECORSHAPE_4x2, DECORCAT_ORNAMENT, 7000, DecorDesc_STAND, DecorGfx_STAND},
+ {DECOR_MUD_BALL, _("MUD BALL"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_ORNAMENT, 200, DecorDesc_MUD_BALL, DecorGfx_MUD_BALL},
+ {DECOR_BREAKABLE_DOOR, _("BREAKABLE DOOR"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x2, DECORCAT_ORNAMENT, 3000, DecorDesc_BREAKABLE_DOOR, DecorGfx_BREAKABLE_DOOR},
+ {DECOR_SAND_ORNAMENT, _("SAND ORNAMENT"), DECORPERM_BEHIND_FLOOR, DECORSHAPE_1x2, DECORCAT_ORNAMENT, 3000, DecorDesc_SAND_ORNAMENT, DecorGfx_SAND_ORNAMENT},
+ {DECOR_SILVER_SHIELD, _("SILVER SHIELD"), DECORPERM_BEHIND_FLOOR, DECORSHAPE_1x2, DECORCAT_ORNAMENT, 0, DecorDesc_SILVER_SHIELD, DecorGfx_SILVER_SHIELD},
+ {DECOR_GOLD_SHIELD, _("GOLD SHIELD"), DECORPERM_BEHIND_FLOOR, DECORSHAPE_1x2, DECORCAT_ORNAMENT, 0, DecorDesc_GOLD_SHIELD, DecorGfx_GOLD_SHIELD},
+ {DECOR_GLASS_ORNAMENT, _("GLASS ORNAMENT"), DECORPERM_BEHIND_FLOOR, DECORSHAPE_1x2, DECORCAT_ORNAMENT, 0, DecorDesc_GLASS_ORNAMENT, DecorGfx_GLASS_ORNAMENT},
+ {DECOR_TV, _("TV"), DECORPERM_SOLID_FLOOR, DECORSHAPE_1x1, DECORCAT_ORNAMENT, 3000, DecorDesc_TV, DecorGfx_TV},
+ {DECOR_ROUND_TV, _("ROUND TV"), DECORPERM_SOLID_FLOOR, DECORSHAPE_1x1, DECORCAT_ORNAMENT, 4000, DecorDesc_ROUND_TV, DecorGfx_ROUND_TV},
+ {DECOR_CUTE_TV, _("CUTE TV"), DECORPERM_SOLID_FLOOR, DECORSHAPE_1x1, DECORCAT_ORNAMENT, 4000, DecorDesc_CUTE_TV, DecorGfx_CUTE_TV},
+ {DECOR_GLITTER_MAT, _("GLITTER MAT"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_MAT, 2000, DecorDesc_GLITTER_MAT, DecorGfx_GLITTER_MAT},
+ {DECOR_JUMP_MAT, _("JUMP MAT"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_MAT, 2000, DecorDesc_JUMP_MAT, DecorGfx_JUMP_MAT},
+ {DECOR_SPIN_MAT, _("SPIN MAT"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_MAT, 2000, DecorDesc_SPIN_MAT, DecorGfx_SPIN_MAT},
+ {DECOR_C_LOW_NOTE_MAT, _("C Low NOTE MAT"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_MAT, 500, DecorDesc_C_LOW_NOTE_MAT, DecorGfx_C_LOW_NOTE_MAT},
+ {DECOR_D_NOTE_MAT, _("D NOTE MAT"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_MAT, 500, DecorDesc_D_NOTE_MAT, DecorGfx_D_NOTE_MAT},
+ {DECOR_E_NOTE_MAT, _("E NOTE MAT"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_MAT, 500, DecorDesc_E_NOTE_MAT, DecorGfx_E_NOTE_MAT},
+ {DECOR_F_NOTE_MAT, _("F NOTE MAT"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_MAT, 500, DecorDesc_F_NOTE_MAT, DecorGfx_F_NOTE_MAT},
+ {DECOR_G_NOTE_MAT, _("G NOTE MAT"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_MAT, 500, DecorDesc_G_NOTE_MAT, DecorGfx_G_NOTE_MAT},
+ {DECOR_A_NOTE_MAT, _("A NOTE MAT"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_MAT, 500, DecorDesc_A_NOTE_MAT, DecorGfx_A_NOTE_MAT},
+ {DECOR_B_NOTE_MAT, _("B NOTE MAT"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_MAT, 500, DecorDesc_B_NOTE_MAT, DecorGfx_B_NOTE_MAT},
+ {DECOR_C_HIGH_NOTE_MAT, _("C High NOTE MAT"), DECORPERM_PASS_FLOOR, DECORSHAPE_1x1, DECORCAT_MAT, 500, DecorDesc_C_HIGH_NOTE_MAT, DecorGfx_C_HIGH_NOTE_MAT},
+ {DECOR_SURF_MAT, _("SURF MAT"), DECORPERM_PASS_FLOOR, DECORSHAPE_3x3, DECORCAT_MAT, 4000, DecorDesc_SURF_MAT, DecorGfx_SURF_MAT},
+ {DECOR_THUNDER_MAT, _("THUNDER MAT"), DECORPERM_PASS_FLOOR, DECORSHAPE_3x3, DECORCAT_MAT, 4000, DecorDesc_THUNDER_MAT, DecorGfx_THUNDER_MAT},
+ {DECOR_FIRE_BLAST_MAT, _("FIRE BLAST MAT"), DECORPERM_PASS_FLOOR, DECORSHAPE_3x3, DECORCAT_MAT, 4000, DecorDesc_FIRE_BLAST_MAT, DecorGfx_FIRE_BLAST_MAT},
+ {DECOR_POWDER_SNOW_MAT, _("POWDER SNOW MAT"), DECORPERM_PASS_FLOOR, DECORSHAPE_3x3, DECORCAT_MAT, 4000, DecorDesc_POWDER_SNOW_MAT, DecorGfx_POWDER_SNOW_MAT},
+ {DECOR_ATTRACT_MAT, _("ATTRACT MAT"), DECORPERM_PASS_FLOOR, DECORSHAPE_3x3, DECORCAT_MAT, 4000, DecorDesc_ATTRACT_MAT, DecorGfx_ATTRACT_MAT},
+ {DECOR_FISSURE_MAT, _("FISSURE MAT"), DECORPERM_PASS_FLOOR, DECORSHAPE_3x3, DECORCAT_MAT, 4000, DecorDesc_FISSURE_MAT, DecorGfx_FISSURE_MAT},
+ {DECOR_SPIKES_MAT, _("SPIKES MAT"), DECORPERM_PASS_FLOOR, DECORSHAPE_3x3, DECORCAT_MAT, 4000, DecorDesc_SPIKES_MAT, DecorGfx_SPIKES_MAT},
+ {DECOR_BALL_POSTER, _("BALL POSTER"), DECORPERM_NA_WALL, DECORSHAPE_1x1, DECORCAT_POSTER, 1000, DecorDesc_BALL_POSTER, DecorGfx_BALL_POSTER},
+ {DECOR_GREEN_POSTER, _("GREEN POSTER"), DECORPERM_NA_WALL, DECORSHAPE_1x1, DECORCAT_POSTER, 1000, DecorDesc_GREEN_POSTER, DecorGfx_GREEN_POSTER},
+ {DECOR_RED_POSTER, _("RED POSTER"), DECORPERM_NA_WALL, DECORSHAPE_1x1, DECORCAT_POSTER, 1000, DecorDesc_RED_POSTER, DecorGfx_RED_POSTER},
+ {DECOR_BLUE_POSTER, _("BLUE POSTER"), DECORPERM_NA_WALL, DECORSHAPE_1x1, DECORCAT_POSTER, 1000, DecorDesc_BLUE_POSTER, DecorGfx_BLUE_POSTER},
+ {DECOR_CUTE_POSTER, _("CUTE POSTER"), DECORPERM_NA_WALL, DECORSHAPE_1x1, DECORCAT_POSTER, 1000, DecorDesc_CUTE_POSTER, DecorGfx_CUTE_POSTER},
+ {DECOR_PIKA_POSTER, _("PIKA POSTER"), DECORPERM_NA_WALL, DECORSHAPE_2x1, DECORCAT_POSTER, 1500, DecorDesc_PIKA_POSTER, DecorGfx_PIKA_POSTER},
+ {DECOR_LONG_POSTER, _("LONG POSTER"), DECORPERM_NA_WALL, DECORSHAPE_2x1, DECORCAT_POSTER, 1500, DecorDesc_LONG_POSTER, DecorGfx_LONG_POSTER},
+ {DECOR_SEA_POSTER, _("SEA POSTER"), DECORPERM_NA_WALL, DECORSHAPE_2x1, DECORCAT_POSTER, 1500, DecorDesc_SEA_POSTER, DecorGfx_SEA_POSTER},
+ {DECOR_SKY_POSTER, _("SKY POSTER"), DECORPERM_NA_WALL, DECORSHAPE_2x1, DECORCAT_POSTER, 1500, DecorDesc_SKY_POSTER, DecorGfx_SKY_POSTER},
+ {DECOR_KISS_POSTER, _("KISS POSTER"), DECORPERM_NA_WALL, DECORSHAPE_2x1, DECORCAT_POSTER, 1500, DecorDesc_KISS_POSTER, DecorGfx_KISS_POSTER},
+ {DECOR_PICHU_DOLL, _("PICHU DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_PICHU_DOLL, DecorGfx_PICHU_DOLL},
+ {DECOR_PIKACHU_DOLL, _("PIKACHU DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_PIKACHU_DOLL, DecorGfx_PIKACHU_DOLL},
+ {DECOR_MARILL_DOLL, _("MARILL DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_MARILL_DOLL, DecorGfx_MARILL_DOLL},
+ {DECOR_TOGEPI_DOLL, _("TOGEPI DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_TOGEPI_DOLL, DecorGfx_TOGEPI_DOLL},
+ {DECOR_CYNDAQUIL_DOLL, _("CYNDAQUIL DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_CYNDAQUIL_DOLL, DecorGfx_CYNDAQUIL_DOLL},
+ {DECOR_CHIKORITA_DOLL, _("CHIKORITA DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_CHIKORITA_DOLL, DecorGfx_CHIKORITA_DOLL},
+ {DECOR_TOTODILE_DOLL, _("TOTODILE DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_TOTODILE_DOLL, DecorGfx_TOTODILE_DOLL},
+ {DECOR_JIGGLYPUFF_DOLL, _("JIGGLYPUFF DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_JIGGLYPUFF_DOLL, DecorGfx_JIGGLYPUFF_DOLL},
+ {DECOR_MEOWTH_DOLL, _("MEOWTH DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_MEOWTH_DOLL, DecorGfx_MEOWTH_DOLL},
+ {DECOR_CLEFAIRY_DOLL, _("CLEFAIRY DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_CLEFAIRY_DOLL, DecorGfx_CLEFAIRY_DOLL},
+ {DECOR_DITTO_DOLL, _("DITTO DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_DITTO_DOLL, DecorGfx_DITTO_DOLL},
+ {DECOR_SMOOCHUM_DOLL, _("SMOOCHUM DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_SMOOCHUM_DOLL, DecorGfx_SMOOCHUM_DOLL},
+ {DECOR_TREECKO_DOLL, _("TREECKO DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_TREECKO_DOLL, DecorGfx_TREECKO_DOLL},
+ {DECOR_TORCHIC_DOLL, _("TORCHIC DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_TORCHIC_DOLL, DecorGfx_TORCHIC_DOLL},
+ {DECOR_MUDKIP_DOLL, _("MUDKIP DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_MUDKIP_DOLL, DecorGfx_MUDKIP_DOLL},
+ {DECOR_DUSKULL_DOLL, _("DUSKULL DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_DUSKULL_DOLL, DecorGfx_DUSKULL_DOLL},
+ {DECOR_WYNAUT_DOLL, _("WYNAUT DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_WYNAUT_DOLL, DecorGfx_WYNAUT_DOLL},
+ {DECOR_BALTOY_DOLL, _("BALTOY DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_BALTOY_DOLL, DecorGfx_BALTOY_DOLL},
+ {DECOR_KECLEON_DOLL, _("KECLEON DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_KECLEON_DOLL, DecorGfx_KECLEON_DOLL},
+ {DECOR_AZURILL_DOLL, _("AZURILL DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_AZURILL_DOLL, DecorGfx_AZURILL_DOLL},
+ {DECOR_SKITTY_DOLL, _("SKITTY DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_SKITTY_DOLL, DecorGfx_SKITTY_DOLL},
+ {DECOR_SWABLU_DOLL, _("SWABLU DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_SWABLU_DOLL, DecorGfx_SWABLU_DOLL},
+ {DECOR_GULPIN_DOLL, _("GULPIN DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_GULPIN_DOLL, DecorGfx_GULPIN_DOLL},
+ {DECOR_LOTAD_DOLL, _("LOTAD DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_LOTAD_DOLL, DecorGfx_LOTAD_DOLL},
+ {DECOR_SEEDOT_DOLL, _("SEEDOT DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_DOLL, 3000, DecorDesc_SEEDOT_DOLL, DecorGfx_SEEDOT_DOLL},
+ {DECOR_PIKA_CUSHION, _("PIKA CUSHION"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_CUSHION, 2000, DecorDesc_PIKA_CUSHION, DecorGfx_PIKA_CUSHION},
+ {DECOR_ROUND_CUSHION, _("ROUND CUSHION"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_CUSHION, 2000, DecorDesc_ROUND_CUSHION, DecorGfx_ROUND_CUSHION},
+ {DECOR_KISS_CUSHION, _("KISS CUSHION"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_CUSHION, 2000, DecorDesc_KISS_CUSHION, DecorGfx_KISS_CUSHION},
+ {DECOR_ZIGZAG_CUSHION, _("ZIGZAG CUSHION"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_CUSHION, 2000, DecorDesc_ZIGZAG_CUSHION, DecorGfx_ZIGZAG_CUSHION},
+ {DECOR_SPIN_CUSHION, _("SPIN CUSHION"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_CUSHION, 2000, DecorDesc_SPIN_CUSHION, DecorGfx_SPIN_CUSHION},
+ {DECOR_DIAMOND_CUSHION, _("DIAMOND CUSHION"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_CUSHION, 2000, DecorDesc_DIAMOND_CUSHION, DecorGfx_DIAMOND_CUSHION},
+ {DECOR_BALL_CUSHION, _("BALL CUSHION"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_CUSHION, 2000, DecorDesc_BALL_CUSHION, DecorGfx_BALL_CUSHION},
+ {DECOR_GRASS_CUSHION, _("GRASS CUSHION"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_CUSHION, 2000, DecorDesc_GRASS_CUSHION, DecorGfx_GRASS_CUSHION},
+ {DECOR_FIRE_CUSHION, _("FIRE CUSHION"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_CUSHION, 2000, DecorDesc_FIRE_CUSHION, DecorGfx_FIRE_CUSHION},
+ {DECOR_WATER_CUSHION, _("WATER CUSHION"), DECORPERM_SOLID_MAT, DECORSHAPE_1x1, DECORCAT_CUSHION, 2000, DecorDesc_WATER_CUSHION, DecorGfx_WATER_CUSHION},
+ {DECOR_SNORLAX_DOLL, _("SNORLAX DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x2, DECORCAT_DOLL, 10000, DecorDesc_SNORLAX_DOLL, DecorGfx_SNORLAX_DOLL},
+ {DECOR_RHYDON_DOLL, _("RHYDON DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x2, DECORCAT_DOLL, 10000, DecorDesc_RHYDON_DOLL, DecorGfx_RHYDON_DOLL},
+ {DECOR_LAPRAS_DOLL, _("LAPRAS DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x2, DECORCAT_DOLL, 10000, DecorDesc_LAPRAS_DOLL, DecorGfx_LAPRAS_DOLL},
+ {DECOR_VENUSAUR_DOLL, _("VENUSAUR DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x2, DECORCAT_DOLL, 10000, DecorDesc_VENUSAUR_DOLL, DecorGfx_VENUSAUR_DOLL},
+ {DECOR_CHARIZARD_DOLL, _("CHARIZARD DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x2, DECORCAT_DOLL, 10000, DecorDesc_CHARIZARD_DOLL, DecorGfx_CHARIZARD_DOLL},
+ {DECOR_BLASTOISE_DOLL, _("BLASTOISE DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x2, DECORCAT_DOLL, 10000, DecorDesc_BLASTOISE_DOLL, DecorGfx_BLASTOISE_DOLL},
+ {DECOR_WAILMER_DOLL, _("WAILMER DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x2, DECORCAT_DOLL, 10000, DecorDesc_WAILMER_DOLL, DecorGfx_WAILMER_DOLL},
+ {DECOR_REGIROCK_DOLL, _("REGIROCK DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x2, DECORCAT_DOLL, 10000, DecorDesc_REGIROCK_DOLL, DecorGfx_REGIROCK_DOLL},
+ {DECOR_REGICE_DOLL, _("REGICE DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x2, DECORCAT_DOLL, 10000, DecorDesc_REGICE_DOLL, DecorGfx_REGICE_DOLL},
+ {DECOR_REGISTEEL_DOLL, _("REGISTEEL DOLL"), DECORPERM_SOLID_MAT, DECORSHAPE_1x2, DECORCAT_DOLL, 10000, DecorDesc_REGISTEEL_DOLL, DecorGfx_REGISTEEL_DOLL}
+};
+#elif GERMAN
+#include "../data/decoration/decorations.h"
+#endif
+
+const u8 *const gUnknown_083EC5E4[] = {
+ SecretBaseText_Desk,
+ SecretBaseText_Chair,
+ SecretBaseText_Plant,
+ SecretBaseText_Ornament,
+ SecretBaseText_Mat,
+ SecretBaseText_Poster,
+ SecretBaseText_Doll,
+ SecretBaseText_Cushion
+};
+
+const struct MenuAction2 gUnknown_083EC604[] = {
+ {SecretBaseText_Decorate, sub_80FF160},
+ {SecretBaseText_PutAway, sub_8100A0C},
+ {SecretBaseText_Toss, sub_8101700},
+ {gUnknownText_Exit, gpu_pal_decompress_alloc_tag_and_upload}
+};
+
+const u8 *const gUnknown_083EC624[] = {
+ SecretBaseText_PutOutDecor,
+ SecretBaseText_StoreChosenDecor,
+ SecretBaseText_ThrowAwayDecor,
+ gMenuText_GoBackToPrev
+};
+
+const struct YesNoFuncTable gUnknown_083EC634[] = {
+ {sub_80FF5BC, sub_80FF058},
+ {sub_81017A0, sub_80FF058},
+ {sub_81017A0, sub_80FF058},
+ {sub_8109D04, sub_80FF058}
+};
+
+const u16 gUnknown_083EC654[] = {0x6318, 0x739C, 0x7FFF};
+const u8 gUnknown_083EC65A[] = _("{PALETTE 13}{STR_VAR_1}");
+
+const u8 Unknown_3EC660[] = {0, 1, 2, 3};
+const u8 Unknown_3EC664[] = {0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13};
+const u8 Unknown_3EC670[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+const u8 Unknown_3EC680[] = {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21};
+const u8 Unknown_3EC68C[] = {0, 1, 2, 3, 4, 5, 6, 7};
+const u8 Unknown_3EC694[] = {0, 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};
+const u8 Unknown_3EC6B4[] = {0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21, 24, 25, 26, 27, 28, 29, 32, 33, 34, 35, 36, 37, 40, 41, 42, 43, 44, 45};
+const u8 Unknown_3EC6D8[] = {0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21, 24, 25, 26, 27, 28, 29};
+
+const u8 Unknown_3EC6F0[] = {0, 0, 0, 0};
+const u8 Unknown_3EC6F4[] = {0, 0, 1, 1, 0, 0, 1, 1};
+const u8 Unknown_3EC6FC[] = {0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2};
+const u8 Unknown_3EC708[] = {0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 4, 4, 5, 5, 6, 6, 7, 7};
+const u8 Unknown_3EC728[] = {0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 2, 2, 3, 3};
+const u8 Unknown_3EC738[] = {0, 0, 0, 0, 1, 1, 1, 1};
+const u8 Unknown_3EC740[] = {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2};
+const u8 Unknown_3EC74C[] = {0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 2, 2, 3, 3, 4, 4, 5, 5, 4, 4, 5, 5, 6, 6, 7, 7, 6, 6, 7, 7};
+const u8 Unknown_3EC76C[] = {0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 6, 6, 7, 7, 8, 8};
+const u8 Unknown_3EC790[] = {0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 3, 3, 4, 4, 5, 5};
+
+const u8 Unknown_3EC7A8[] = {4, 5, 6, 7};
+const u8 Unknown_3EC7AC[] = {4, 5, 4, 5, 6, 7, 6, 7};
+const u8 Unknown_3EC7B4[] = {4, 5, 4, 5, 4, 5, 6, 7, 6, 7, 6, 7};
+const u8 Unknown_3EC7C0[] = {4, 5, 4, 5, 4, 5, 4, 5, 6, 7, 6, 7, 6, 7, 6, 7, 4, 5, 4, 5, 4, 5, 4, 5, 6, 7, 6, 7, 6, 7, 6, 7};
+const u8 Unknown_3EC7E0[] = {4, 5, 4, 5, 6, 7, 6, 7, 4, 5, 4, 5, 6, 7, 6, 7};
+const u8 Unknown_3EC7F0[] = {4, 5, 6, 7, 4, 5, 6, 7};
+const u8 Unknown_3EC7F8[] = {4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7};
+const u8 Unknown_3EC804[] = {4, 5, 4, 5, 6, 7, 6, 7, 4, 5, 4, 5, 6, 7, 6, 7, 4, 5, 4, 5, 6, 7, 6, 7, 4, 5, 4, 5, 6, 7, 6, 7};
+const u8 Unknown_3EC824[] = {4, 5, 4, 5, 4, 5, 6, 7, 6, 7, 6, 7, 4, 5, 4, 5, 4, 5, 6, 7, 6, 7, 6, 7, 4, 5, 4, 5, 4, 5, 6, 7, 6, 7, 6, 7};
+const u8 Unknown_3EC848[] = {4, 5, 4, 5, 4, 5, 6, 7, 6, 7, 6, 7, 4, 5, 4, 5, 4, 5, 6, 7, 6, 7, 6, 7};
+
+const struct UnkStruct_803EC860 gUnknown_083EC860[] = {
+ {Unknown_3EC660, Unknown_3EC6F0, Unknown_3EC7A8, 0x4},
+ {Unknown_3EC68C, Unknown_3EC6F4, Unknown_3EC7AC, 0x8},
+ {Unknown_3EC664, Unknown_3EC6FC, Unknown_3EC7B4, 0xc},
+ {Unknown_3EC694, Unknown_3EC708, Unknown_3EC7C0, 0x20},
+ {Unknown_3EC670, Unknown_3EC728, Unknown_3EC7E0, 0x10},
+ {Unknown_3EC68C, Unknown_3EC738, Unknown_3EC7F0, 0x8},
+ {Unknown_3EC680, Unknown_3EC740, Unknown_3EC7F8, 0xc},
+ {Unknown_3EC694, Unknown_3EC74C, Unknown_3EC804, 0x20},
+ {Unknown_3EC6B4, Unknown_3EC76C, Unknown_3EC824, 0x24},
+ {Unknown_3EC6D8, Unknown_3EC790, Unknown_3EC848, 0x18}
+};
+
+const struct UnkStruct_083EC900 gUnknown_083EC900[] = {
+ {0, 1, 0x78, 0x4e},
+ {1, 2, 0x80, 0x4e},
+ {1, 3, 0x90, 0x56},
+ {1, 3, 0x90, 0x46},
+ {0, 2, 0x80, 0x46},
+ {2, 2, 0x78, 0x46},
+ {2, 3, 0x80, 0x56},
+ {2, 3, 0x80, 0x36},
+ {0, 3, 0x90, 0x46},
+ {1, 3, 0x90, 0x46}
+};
+
+const union AnimCmd gSpriteAnim_83EC928[] = {
+ ANIMCMD_FRAME(.imageValue = 0, .duration = 0),
+ ANIMCMD_END
+};
+
+const union AnimCmd *const gSpriteAnimTable_83EC930[] = {
+ gSpriteAnim_83EC928
+};
+
+const struct SpriteFrameImage gSpriteImageTable_83EC934[] = {
+ {.data = (u8 *)&gUnknown_02038900.image, .size = sizeof gUnknown_02038900.image}
+};
+
+const struct SpriteTemplate gSpriteTemplate_83EC93C = {
+ .tileTag = 0xffff,
+ .paletteTag = 3000,
+ .oam = &gUnknown_020391AC,
+ .anims = gSpriteAnimTable_83EC930,
+ .images = gSpriteImageTable_83EC934,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_81009A8
+};
+
+const struct SpritePalette gUnknown_083EC954 = {.data = (u16 *)&gUnknown_02038900.palette, .tag = 3000};
+
+const struct YesNoFuncTable gUnknown_083EC95C = {.yesFunc = sub_81000C4, .noFunc = sub_810065C};
+const struct YesNoFuncTable gUnknown_083EC964 = {.yesFunc = sub_810026C, .noFunc = sub_810065C};
+const struct YesNoFuncTable gUnknown_083EC96C[] = {
+ {.yesFunc = sub_80FFAB0, .noFunc = sub_80FFB08},
+ {.yesFunc = sub_8100F88, .noFunc = sub_8100FB4}
+};
+
+const u8 gUnknown_083EC97C[] = {4, 4, 4, 4, 0, 3, 3, 0};
+const u8 gUnknown_083EC984[] = {4, 4, 4, 4, 0, 4, 3, 0};
+
+const u16 gUnknown_083EC98C[] = INCBIN_U16("graphics/unknown/83EC98C.gbapal");
+const u16 Unknown_3EC9AC[] = INCBIN_U16("graphics/unknown/83EC9AC.gbapal");
+const struct YesNoFuncTable gUnknown_083EC9CC = {.yesFunc = sub_810153C, .noFunc = sub_8100EEC};
+const struct YesNoFuncTable gUnknown_083EC9D4 = {.yesFunc = sub_8101590, .noFunc = sub_8100EEC};
+const u32 gSpriteImage_83EC9DC[] = INCBIN_U32("graphics/unknown_sprites/83EC9DC.4bpp");
+const struct SpritePalette gUnknown_083ECA5C = {.data = gUnknown_083EC98C, .tag = 8};
+const struct SpritePalette gUnknown_083ECA64 = {.data = Unknown_3EC9AC, .tag = 8};
+const struct OamData gOamData_83ECA6C = {
+ .size = 1, .priority = 1
+};
+
+const union AnimCmd gSpriteAnim_83ECA74[] = {
+ ANIMCMD_FRAME(.imageValue = 0, .duration = 0),
+ ANIMCMD_END
+};
+
+const union AnimCmd *const gSpriteAnimTable_83ECA7C[] = {
+ gSpriteAnim_83ECA74
+};
+
+const struct SpriteFrameImage gSpriteImageTable_83ECA80[] = {
+ obj_frame_tiles(gSpriteImage_83EC9DC)
+};
+
+const struct SpriteTemplate gSpriteTemplate_83ECA88 = {
+ .tileTag = 0xffff,
+ .paletteTag = 8,
+ .oam = &gOamData_83ECA6C,
+ .anims = gSpriteAnimTable_83ECA7C,
+ .images = gSpriteImageTable_83ECA80,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_8101698
+};
+
+const struct YesNoFuncTable gUnknown_083ECAA0 = {.yesFunc = sub_8101848, .noFunc = sub_80FED3C};
+
+u8 *const unref_label_083ECAA8[] = {ewram};
+
+// text
+
+extern u8 gUnknown_0815F399[];
+
+void sub_80FE1DC(void)
+{
+ sub_80FE2B4();
+ MenuDrawTextWindow(0, 0, 10, 9);
+ PrintMenuItems(1, 1, 4, (const struct MenuAction *)gUnknown_083EC604);
+ InitMenu(0, 1, 1, 4, gUnknown_020388D4, 9);
+}
+
+void sub_80FE220(void)
+{
+ gUnknown_020388D4 = 0;
+ ScriptContext2_Enable();
+ sub_80FE1DC();
+ sub_80FE394();
+}
+
+void DecorationPC(u8 taskId)
+{
+ sub_80FE220();
+ gTasks[taskId].func = Task_DecorationPCProcessMenuInput;
+}
+
+void Task_SecretBasePC_Decoration(u8 taskId)
+{
+ DecorationPC(taskId);
+ ewram_1f000.items = gSaveBlock1.secretBases[0].decorations;
+ ewram_1f000.pos = gSaveBlock1.secretBases[0].decorationPos;
+ ewram_1f000.size = sizeof gSaveBlock1.secretBases[0].decorations;
+ ewram_1f000.isPlayerRoom = 0;
+}
+
+void DoPlayerPCDecoration(u8 taskId)
+{
+ DecorationPC(taskId);
+ ewram_1f000.items = gSaveBlock1.playerRoomDecor;
+ ewram_1f000.pos = gSaveBlock1.playerRoomDecorPos;
+ ewram_1f000.size = sizeof gSaveBlock1.playerRoomDecor;
+ ewram_1f000.isPlayerRoom = 1;
+}
+
+void sub_80FE2B4(void)
+{
+ u16 palettes[3];
+ memcpy(palettes, gUnknown_083EC654, sizeof gUnknown_083EC654);
+ LoadPalette(&palettes[2], 0xdf, 2);
+ LoadPalette(&palettes[1], 0xd1, 2);
+ LoadPalette(&palettes[0], 0xd8, 2);
+}
+
+void Task_DecorationPCProcessMenuInput(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ if (gMain.newKeys & DPAD_UP)
+ {
+ PlaySE(SE_SELECT);
+ gUnknown_020388D4 = MoveMenuCursor(-1);
+ sub_80FE394();
+ }
+ if (gMain.newKeys & DPAD_DOWN)
+ {
+ PlaySE(SE_SELECT);
+ gUnknown_020388D4 = MoveMenuCursor(1);
+ sub_80FE394();
+ }
+ if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ gUnknown_083EC604[gUnknown_020388D4].func(taskId);
+ } else if (gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ gpu_pal_decompress_alloc_tag_and_upload(taskId);
+ }
+ }
+}
+
+void sub_80FE394(void)
+{
+ MenuFillWindowRectWithBlankTile(2, 15, 27, 18);
+ MenuPrint(gUnknown_083EC624[gUnknown_020388D4], 2, 15);
+}
+
+void gpu_pal_decompress_alloc_tag_and_upload(u8 taskId)
+{
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(0, 0, 10, 9);
+ MenuFillWindowRectWithBlankTile(2, 15, 27, 18);
+ FreeSpritePaletteByTag(6);
+ if (ewram_1f000.isPlayerRoom == 0)
+ {
+ ScriptContext1_SetupScript(gUnknown_0815F399);
+ DestroyTask(taskId);
+ } else
+ {
+ ReshowPlayerPC(taskId);
+ }
+}
+
+void sub_80FE418(u8 taskId)
+{
+ sub_80FE5AC(taskId);
+}
+
+void sub_80FE428(u8 taskId)
+{
+ InitMenu(0, 1, 1, 4, gUnknown_020388D4, 9);
+ sub_80FE394();
+ gTasks[taskId].func = Task_DecorationPCProcessMenuInput;
+}
+
+void sub_80FE470(u8 decoCat, u8 left, u8 top, u8 palIdx) // PrintDecorationCategorySelectionMenuString
+{
+ u8 *strptr;
+ u8 v0;
+ v0 = sub_8072CBC();
+ // PALETTE {palIdx}
+ strptr = gStringVar4;
+ strptr[0] = EXT_CTRL_CODE_BEGIN;
+ strptr[1] = 5;
+ strptr[2] = palIdx;
+ strptr += 3;
+ strptr = StringCopy(strptr, gUnknown_083EC5E4[decoCat]);
+ strptr = sub_8072C14(strptr, sub_8134194(decoCat), 0x56, 1);
+ *strptr++ = 0xba;
+ strptr = sub_8072C14(strptr, gDecorationInventories[decoCat].size, 0x68, 1);
+ strptr[0] = EXT_CTRL_CODE_BEGIN;
+ strptr[1] = 5;
+ strptr[2] = v0;
+ strptr[3] = EOS;
+ MenuPrint(gStringVar4, left, top);
+}
+
+void sub_80FE528(u8 taskId) // PrintDecorationCategorySelectionMenuStrings
+{
+ u8 decoCat;
+ MenuDrawTextWindow(0, 0, 14, 19);
+ for (decoCat=0; decoCat<8; decoCat++)
+ {
+ if (ewram_1f000.isPlayerRoom == 1 && gTasks[taskId].data[11] == 0 && decoCat != DECORCAT_DOLL && decoCat != DECORCAT_CUSHION)
+ {
+ sub_80FE470(decoCat, 1, 2 * decoCat + 1, 13); // Selectable
+ } else
+ {
+ sub_80FE470(decoCat, 1, 2 * decoCat + 1, 255); // Unselectable
+ }
+ }
+ MenuPrint(gUnknownText_Exit, 1, 17);
+}
+
+void sub_80FE5AC(u8 taskId)
+{
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(0, 0, 29, 19);
+ sub_80FE528(taskId);
+ InitMenu(0, 1, 1, 9, gUnknown_020388F6, 13);
+ gTasks[taskId].func = sub_80FE604;
+}
+
+void sub_80FE604(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ if (gMain.newAndRepeatedKeys & DPAD_UP)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor(-1);
+ } else if (gMain.newAndRepeatedKeys & DPAD_DOWN)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor(1);
+ } else if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ gUnknown_020388F6 = GetMenuCursorPos();
+ if (gUnknown_020388F6 != 8)
+ {
+ gUnknown_020388D5 = sub_8134194(gUnknown_020388F6);
+ if (gUnknown_020388D5)
+ {
+ sub_8134104(gUnknown_020388F6);
+ gUnknown_020388D0 = gDecorationInventories[gUnknown_020388F6].items;
+ sub_80FEF50(taskId);
+ sub_80F944C();
+ sub_80F9480(gUnknown_020388F7, 8);
+ LoadScrollIndicatorPalette();
+ gTasks[taskId].func = sub_80FE868;
+ } else
+ {
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(0, 0, 14, 19);
+ DisplayItemMessageOnField(taskId, gSecretBaseText_NoDecors, sub_80FE418, 0);
+ }
+ } else
+ {
+ sub_80FE728(taskId);
+ }
+ } else if (gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ sub_80FE728(taskId);
+ }
+ }
+}
+
+void sub_80FE728(u8 taskId)
+{
+ if (gTasks[taskId].data[11] != 3)
+ {
+ sub_80FE758(taskId);
+ } else
+ {
+ sub_8109DAC(taskId);
+ }
+}
+
+void sub_80FE758(u8 taskId)
+{
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(0, 0, 14, 19);
+ if (gTasks[taskId].data[11] != 2)
+ {
+ sub_80FE1DC();
+ MenuDisplayMessageBox();
+ sub_80FE394();
+ gTasks[taskId].func = Task_DecorationPCProcessMenuInput;
+ } else
+ {
+ sub_80B3068(taskId);
+ }
+}
+
+void sub_80FE7A8(u8 taskId)
+{
+ gTasks[taskId].data[11] = 3;
+ gUnknown_020388F6 = 0;
+ sub_80FE5AC(taskId);
+}
+
+void sub_80FE7D4(u8 *dest, u8 decClass)
+{
+ StringCopy(dest, gUnknown_083EC5E4[decClass]);
+}
+
+void sub_80FE7EC(u8 taskId)
+{
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(0, 0, 29, 19);
+
+ sub_80FEC94(taskId);
+ sub_80FECB8(gUnknown_020388F6);
+
+#if ENGLISH
+ MenuDrawTextWindow(15, 12, 29, 19);
+#elif GERMAN
+ if ((gUnknown_020388F2 + gUnknown_020388F4) != gUnknown_020388D5)
+ {
+ MenuDrawTextWindow(15, 12, 29, 19);
+ }
+#endif
+
+ sub_80FECE0(gUnknown_020388F2 + gUnknown_020388F4);
+ InitMenu(0, 1, 2, gUnknown_020388F3 + 1, gUnknown_020388F2, 13);
+}
+
+void sub_80FE868(u8 taskId)
+{
+ sub_80FE7EC(taskId);
+ gTasks[taskId].func = sub_80FE948;
+}
+
+void sub_80FE894(u8 taskId /*r8*/, s8 cursorVector /*r5*/, s8 bgVector /*r7*/)
+{
+ int v0 /*r10*/;
+ u8 v1;
+ v0 = gUnknown_020388F2 + gUnknown_020388F4 == gUnknown_020388D5;
+ PlaySE(SE_SELECT);
+ if (cursorVector != 0)
+ {
+ gUnknown_020388F2 = MoveMenuCursor(cursorVector);
+ }
+ if (bgVector != 0)
+ {
+ v1 = gUnknown_020388F4;
+ gUnknown_020388F4 = v1 + bgVector;
+ sub_80FEABC(taskId, 1);
+ }
+ if (gUnknown_020388F2 + gUnknown_020388F4 != gUnknown_020388D5)
+ {
+ if (v0)
+ {
+ MenuDrawTextWindow(15, 12, 29, 19);
+ }
+ sub_80FECE0(gUnknown_020388F2 + gUnknown_020388F4);
+ } else
+ {
+ MenuZeroFillWindowRect(15, 12, 29, 19);
+ }
+}
+
+void sub_80FE948(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_UP)
+ {
+ if (gUnknown_020388F2 != 0)
+ {
+ sub_80FE894(taskId, -1, 0);
+ } else if (gUnknown_020388F4 != 0)
+ {
+ sub_80FE894(taskId, 0, -1);
+ }
+ }
+ if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_DOWN)
+ {
+ if (gUnknown_020388F2 != gUnknown_020388F3)
+ {
+ sub_80FE894(taskId, 1, 0);
+ } else if (gUnknown_020388F4 + gUnknown_020388F2 != gUnknown_020388D5)
+ {
+ sub_80FE894(taskId, 0, 1);
+ }
+ }
+ if (gMain.newKeys & A_BUTTON)
+ {
+ HandleDestroyMenuCursors();
+ PlaySE(SE_SELECT);
+ gUnknown_020388F5 = gUnknown_020388F2 + gUnknown_020388F4;
+ if (gUnknown_020388F5 == gUnknown_020388D5)
+ {
+ gUnknown_083EC634[gTasks[taskId].data[11]].noFunc(taskId);
+ } else
+ {
+ gUnknown_083EC634[gTasks[taskId].data[11]].yesFunc(taskId);
+ }
+ } else if (gMain.newKeys & B_BUTTON)
+ {
+ HandleDestroyMenuCursors();
+ PlaySE(SE_SELECT);
+ gUnknown_083EC634[gTasks[taskId].data[11]].noFunc(taskId);
+ }
+ }
+}
+
+void sub_80FEABC(u8 taskId, u8 dummy1)
+{
+ u16 i;
+ u16 j;
+ u8 ni;
+ if (gUnknown_020388F4 != 0 || (DestroyVerticalScrollIndicator(0), gUnknown_020388F4 != 0))
+ {
+ CreateVerticalScrollIndicators(0, 0x3c, 0x08);
+ }
+ if (gUnknown_020388F4 + 7 == gUnknown_020388D5)
+ {
+ DestroyVerticalScrollIndicator(1);
+ }
+ if (gUnknown_020388F4 + 7 < gUnknown_020388D5)
+ {
+ CreateVerticalScrollIndicators(1, 0x3c, 0x98);
+ }
+ for (i=gUnknown_020388F4; i<gUnknown_020388F4+8; i++)
+ {
+ ni = 2 * (i - gUnknown_020388F4) + 2;
+ if (gUnknown_020388F7[i - gUnknown_020388F4])
+ {
+ sub_80F94F8(&gUnknown_020388F7[i - gUnknown_020388F4]);
+ }
+ if (i == gUnknown_020388D5)
+ {
+ sub_8072A18(gUnknownText_Exit, 0x08, 8 * ni, 0x68, 1);
+ break;
+ }
+ if (gUnknown_020388D0[i])
+ {
+ if (ewram_1f000.isPlayerRoom == 1 && gUnknown_020388F6 != DECORCAT_DOLL && gUnknown_020388F6 != DECORCAT_CUSHION && gTasks[taskId].data[11] == 0)
+ {
+ StringCopy(gStringVar1, gDecorations[gUnknown_020388D0[i]].name);
+ sub_8072A18(gUnknown_083EC65A, 0x08, 8 * ni, 0x68, 1);
+ } else
+ {
+ sub_8072A18(gDecorations[gUnknown_020388D0[i]].name, 0x08, 8 * ni, 0x68, 1);
+ }
+ for (j=0; j<16; j++)
+ {
+ if (gUnknown_020388D6[j] - 1 == i)
+ {
+ sub_80F94A4(4, &gUnknown_020388F7[i - gUnknown_020388F4], 0x6c, (i - gUnknown_020388F4) * 16 + 24);
+ break;
+ }
+ }
+ for (j=0; j<12; j++)
+ {
+ if (gUnknown_020388E6[j] - 1 == i)
+ {
+ sub_80F94A4(5, &gUnknown_020388F7[i - gUnknown_020388F4], 0x6c, (i - gUnknown_020388F4) * 16 + 24);
+ break;
+ }
+ }
+ }
+ }
+}
+
+void sub_80FEC94(u8 taskId)
+{
+ MenuDrawTextWindow(0, 0, 14, 19);
+ sub_80FEABC(taskId, 0);
+}
+
+void sub_80FECB8(u8 decoCat)
+{
+ MenuDrawTextWindow(15, 0, 29, 3);
+ sub_80FE470(decoCat, 16, 1, 0xff);
+}
+
+#if ENGLISH
+void sub_80FECE0(u8 decoCat)
+{
+ sub_8072AB0(gDecorations[gUnknown_020388D0[decoCat]].description, 0x80, 0x68, 0x68, 0x30, 0x1);
+}
+#elif GERMAN
+__attribute__((naked))
+void sub_80FECE0(u8 decoCat)
+{
+ asm(".syntax unified\n\
+ push {lr}\n\
+ sub sp, 0x8\n\
+ lsls r0, 24\n\
+ lsrs r2, r0, 24\n\
+ ldr r0, _080FED18 @ =gUnknown_020388D5\n\
+ ldrb r0, [r0]\n\
+ cmp r2, r0\n\
+ beq _080FED24\n\
+ ldr r1, _080FED1C @ =gDecorations\n\
+ ldr r0, _080FED20 @ =gUnknown_020388D0\n\
+ ldr r0, [r0]\n\
+ adds r0, r2\n\
+ ldrb r0, [r0]\n\
+ lsls r0, 5\n\
+ adds r1, 0x18\n\
+ adds r0, r1\n\
+ ldr r0, [r0]\n\
+ movs r1, 0x30\n\
+ str r1, [sp]\n\
+ movs r1, 0x1\n\
+ str r1, [sp, 0x4]\n\
+ movs r1, 0x80\n\
+ movs r2, 0x68\n\
+ movs r3, 0x68\n\
+ bl sub_8072AB0\n\
+ movs r0, 0x1\n\
+ b _080FED26\n\
+ .align 2, 0\n\
+_080FED18: .4byte gUnknown_020388D5\n\
+_080FED1C: .4byte gDecorations\n\
+_080FED20: .4byte gUnknown_020388D0\n\
+_080FED24:\n\
+ movs r0, 0\n\
+_080FED26:\n\
+ add sp, 0x8\n\
+ pop {r1}\n\
+ bx r1\n\
+ .syntax divided\n");
+}
+#endif
+
+void sub_80FED1C(void)
+{
+ MenuZeroFillWindowRect(15, 0, 29, 3);
+ MenuZeroFillWindowRect(15, 12, 29, 19);
+}
+
+void sub_80FED3C(u8 taskId)
+{
+ LoadScrollIndicatorPalette();
+ gTasks[taskId].func = sub_80FE868;
+}
+
+bool8 sub_80FED64(u8 a0)
+{
+ u8 i;
+ for (i=0; i<16; i++)
+ {
+ if (gUnknown_020388D6[i] == a0)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void sub_80FED90(u8 taskId)
+{
+ u16 i;
+ u16 j;
+ u16 k;
+ u16 cnt;
+ cnt = 0;
+ for (i=0; i<16; i++)
+ {
+ gUnknown_020388D6[i] = 0;
+ if (i < 12)
+ {
+ gUnknown_020388E6[i] = 0;
+ }
+ }
+ for (i=0; i<16; i++)
+ {
+ if (gSaveBlock1.secretBases[0].decorations[i] != 0)
+ {
+ for (j=0; j<gDecorationInventories[gUnknown_020388F6].size; j++)
+ {
+ if (gUnknown_020388D0[j] == gSaveBlock1.secretBases[0].decorations[i])
+ {
+ for (k=0; k<cnt && gUnknown_020388D6[k]!=j+1; k++);
+ if (k == cnt)
+ {
+ gUnknown_020388D6[cnt] = j+1;
+ cnt++;
+ break;
+ }
+ }
+ }
+ }
+ }
+ cnt = 0;
+ for (i=0; i<12; i++)
+ {
+ if (gSaveBlock1.playerRoomDecor[i] != 0)
+ {
+ for (j=0; j<gDecorationInventories[gUnknown_020388F6].size; j++)
+ {
+ if (gUnknown_020388D0[j] == gSaveBlock1.playerRoomDecor[i] && !sub_80FED64(j + 1))
+ {
+ for (k=0; k<cnt && gUnknown_020388E6[k]!=j+1; k++);
+ if (k == cnt)
+ {
+ gUnknown_020388E6[cnt] = j+1;
+ cnt++;
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+void sub_80FEF28(void)
+{
+ if (gUnknown_020388D5 <= 7)
+ {
+ gUnknown_020388F3 = gUnknown_020388D5;
+ } else
+ {
+ gUnknown_020388F3 = 7;
+ }
+}
+
+void sub_80FEF50(u8 taskId)
+{
+ sub_80FED90(taskId);
+ sub_80FEF28();
+ gUnknown_020388F2 = 0;
+ gUnknown_020388F4 = 0;
+}
+
+void sub_80FEF74(void)
+{
+ sub_80F9520(gUnknown_020388F7, 8);
+ DestroyVerticalScrollIndicator(0);
+ DestroyVerticalScrollIndicator(1);
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(0, 0, 14, 19);
+}
+
+bool8 sub_80FEFA4(void)
+{
+ u16 i;
+ int v0;
+ for (i=0; i<16; i++)
+ {
+ v0 = gUnknown_020388F4 + gUnknown_020388F2 + 1;
+ if (gUnknown_020388D6[i] == v0 || (i < 12 && gUnknown_020388E6[i] == v0))
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+void sub_80FEFF4(u8 taskId)
+{
+ if (gMain.newKeys & A_BUTTON || gMain.newKeys & B_BUTTON)
+ {
+ LoadScrollIndicatorPalette();
+ gTasks[taskId].func = sub_80FE868;
+ }
+}
+
+void sub_80FF034(u8 taskId)
+{
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(0, 0, 14, 19);
+ sub_80FE5AC(taskId);
+}
+
+void sub_80FF058(u8 taskId)
+{
+ sub_80F9520(gUnknown_020388F7, 8);
+ DestroyVerticalScrollIndicator(0);
+ DestroyVerticalScrollIndicator(1);
+ BuyMenuFreeMemory();
+ gTasks[taskId].func = sub_80FF034;
+}
+
+void sub_80FF098(u8 taskId)
+{
+ gUnknown_020388D5--;
+ if (gUnknown_020388F4 + 7 > gUnknown_020388D5 && gUnknown_020388F4 != 0)
+ {
+ gUnknown_020388F4--;
+ }
+ sub_8134104(gUnknown_020388F6);
+ sub_80FED90(taskId);
+ sub_80FEF28();
+}
+
+void sub_80FF0E0(u8 taskId)
+{
+ gTasks[taskId].data[3] = gSaveBlock1.pos.x;
+ gTasks[taskId].data[4] = gSaveBlock1.pos.y;
+ PlayerGetDestCoords(&gTasks[taskId].data[0], &gTasks[taskId].data[1]);
+}
+
+void sub_80FF114(u8 taskId)
+{
+ DrawWholeMapView();
+ Overworld_SetWarpDestination(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum, -1, gTasks[taskId].data[3], gTasks[taskId].data[4]);
+ warp_in();
+}
+void sub_80FF160(u8 taskId)
+{
+ if (!sub_81341D4())
+ {
+ DisplayItemMessageOnField(taskId, gSecretBaseText_NoDecors, sub_80FE428, 0);
+ } else
+ {
+ gTasks[taskId].data[11] = 0;
+ gUnknown_020388F6 = 0;
+ sub_80FE5AC(taskId);
+ }
+}
+
+u16 sub_80FF1B0(u8 decoId, u8 a1)
+{
+ u16 retval;
+ retval = 0xffff;
+
+ switch (decoId)
+ {
+ case DECOR_STAND:
+ retval = gUnknown_083EC97C[a1] << 12;
+ return retval;
+ case DECOR_SLIDE:
+ retval = gUnknown_083EC984[a1] << 12;
+ return retval;
+ default:
+ return retval;
+ }
+}
+
+void sub_80FF1EC(u16 mapX, u16 mapY, u8 decWidth, u8 decHeight, u16 decIdx)
+{
+ u16 i;
+ u16 j; // r10
+ u16 behavior;
+ u16 flags; // r8
+ u16 v0;
+ u16 v1;
+ s16 x;
+ s16 decBottom;
+
+ for (i=0; i<decHeight; i++)
+ {
+ decBottom = mapY - decHeight + 1 + i;
+ for (j=0; j<decWidth; j++)
+ {
+ x = mapX + j;
+ behavior = GetBehaviorByMetatileId(0x200 + gDecorations[decIdx].tiles[i * decWidth + j]);
+ if (sub_8057288(behavior) == 1 || (gDecorations[decIdx].permission != DECORPERM_PASS_FLOOR && (behavior >> 12)))
+ {
+ flags = 0xc00;
+ } else
+ {
+ flags = 0x000;
+ }
+ if (gDecorations[decIdx].permission != DECORPERM_NA_WALL && sub_80572B0(MapGridGetMetatileBehaviorAt(x, decBottom)) == 1)
+ {
+ v0 = 1;
+ } else
+ {
+ v0 = 0;
+ }
+ v1 = sub_80FF1B0(gDecorations[decIdx].id, i * decWidth + j);
+ if (v1 != 0xffff)
+ {
+ MapGridSetMetatileEntryAt(x, decBottom, (gDecorations[decIdx].tiles[i * decWidth + j] + (0x200 | v0)) | flags | v1);
+ } else
+ {
+ MapGridSetMetatileIdAt(x, decBottom, (gDecorations[decIdx].tiles[i * decWidth + j] + (0x200 | v0)) | flags);
+ }
+ }
+ }
+}
+
+void sub_80FF394(u16 mapX, u16 mapY, u16 decIdx)
+{
+ switch (gDecorations[decIdx].shape)
+ {
+ case DECORSHAPE_1x1:
+ sub_80FF1EC(mapX, mapY, 1, 1, decIdx);
+ break;
+ case DECORSHAPE_2x1:
+ sub_80FF1EC(mapX, mapY, 2, 1, decIdx);
+ break;
+ case DECORSHAPE_3x1: // unused
+ sub_80FF1EC(mapX, mapY, 3, 1, decIdx);
+ break;
+ case DECORSHAPE_4x2:
+ sub_80FF1EC(mapX, mapY, 4, 2, decIdx);
+ break;
+ case DECORSHAPE_2x2:
+ sub_80FF1EC(mapX, mapY, 2, 2, decIdx);
+ break;
+ case DECORSHAPE_1x2:
+ sub_80FF1EC(mapX, mapY, 1, 2, decIdx);
+ break;
+ case DECORSHAPE_1x3: // unused
+ sub_80FF1EC(mapX, mapY, 1, 3, decIdx);
+ break;
+ case DECORSHAPE_2x4:
+ sub_80FF1EC(mapX, mapY, 2, 4, decIdx);
+ break;
+ case DECORSHAPE_3x3:
+ sub_80FF1EC(mapX, mapY, 3, 3, decIdx);
+ break;
+ case DECORSHAPE_3x2:
+ sub_80FF1EC(mapX, mapY, 3, 2, decIdx);
+ break;
+ }
+}
+
+void sub_80FF474(void)
+{
+ u8 i;
+ u8 j;
+ for (i=0; i<14; i++)
+ {
+ if (FlagGet(i + 0xae) == 1)
+ {
+ FlagClear(i + 0xae);
+ for (j=0; j<gMapHeader.events->mapObjectCount; j++)
+ {
+ if (gMapHeader.events->mapObjects[j].flagId == i + 0xae)
+ {
+ break;
+ }
+ }
+ VarSet(0x3f20 + gMapHeader.events->mapObjects[j].graphicsId, gUnknown_02038900.decoration->tiles[0]);
+ gSpecialVar_0x8005 = gMapHeader.events->mapObjects[j].localId;
+ gSpecialVar_0x8006 = gUnknown_020391A4;
+ gSpecialVar_0x8007 = gUnknown_020391A6;
+ show_sprite(gSpecialVar_0x8005, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup);
+ sub_805C0F8(gSpecialVar_0x8005, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup, gSpecialVar_0x8006, gSpecialVar_0x8007);
+ sub_805C78C(gSpecialVar_0x8005, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup);
+ break;
+ }
+ }
+}
+
+bool8 sub_80FF58C/*IsThereRoomForMoreDecorations*/(void)
+{
+ u16 i;
+ for (i=0; i<ewram_1f000.size; i++)
+ {
+ if (ewram_1f000.items[i] == 0)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void sub_80FF5BC(u8 taskId)
+{
+ if (ewram_1f000.isPlayerRoom == 1 && gUnknown_020388F6 != DECORCAT_DOLL && gUnknown_020388F6 != DECORCAT_CUSHION)
+ {
+ sub_80FEF74();
+ sub_80FED1C();
+ DisplayItemMessageOnField(taskId, gSecretBaseText_DecorCantPlace, sub_80FEFF4, 0);
+ } else if (sub_80FEFA4() == TRUE)
+ {
+ if (sub_80FF58C() == TRUE)
+ {
+ fade_screen(1, 0);
+ gTasks[taskId].data[2] = 0;
+ gTasks[taskId].func = sub_80FF6AC;
+ } else
+ {
+ sub_80FEF74();
+ sub_80FED1C();
+ ConvertIntToDecimalStringN(gStringVar1, ewram_1f000.size, STR_CONV_MODE_RIGHT_ALIGN, 2);
+ if (!ewram_1f000.isPlayerRoom)
+ {
+ StringExpandPlaceholders(gStringVar4, gSecretBaseText_NoMoreDecor);
+ } else
+ {
+ StringExpandPlaceholders(gStringVar4, gSecretBaseText_NoMoreDecor2);
+ }
+ DisplayItemMessageOnField(taskId, gStringVar4, sub_80FEFF4, 0);
+ }
+ } else
+ {
+ sub_80FEF74();
+ sub_80FED1C();
+ DisplayItemMessageOnField(taskId, gSecretBaseText_InUseAlready, sub_80FEFF4, 0);
+ }
+}
+
+void sub_80FF6AC(u8 taskId)
+{
+ switch (gTasks[taskId].data[2])
+ {
+ case 0:
+ if (!gPaletteFade.active)
+ {
+ sub_80FF0E0(taskId);
+ DestroyVerticalScrollIndicator(0);
+ DestroyVerticalScrollIndicator(1);
+ sub_80F9520(gUnknown_020388F7, 8);
+ BuyMenuFreeMemory();
+ gTasks[taskId].data[2] = 1;
+ }
+ break;
+ case 1:
+ gPaletteFade.bufferTransferDisabled = 1;
+ AddDecorationIconObjectFromFieldObject(&gUnknown_02038900, gUnknown_020388D0[gUnknown_020388F5]);
+ sub_80FF960(taskId);
+ SetUpPlacingDecorationPlayerAvatar(taskId, &gUnknown_02038900);
+ pal_fill_black();
+ gPaletteFade.bufferTransferDisabled = 0;
+ gTasks[taskId].data[2] = 2;
+ break;
+ case 2:
+ if (sub_807D770() == 1)
+ {
+ gTasks[taskId].data[12] = 0;
+ sub_810065C(taskId);
+ }
+ break;
+ }
+}
+
+void AddDecorationIconObjectFromFieldObject(struct UnkStruct_02038900 * unk_02038900, u8 decoIdx)
+{
+ sub_80FEF74();
+ sub_80FED1C();
+ sub_81006D0(unk_02038900);
+ unk_02038900->decoration = &gDecorations[decoIdx];
+ if (gDecorations[decoIdx].permission != DECORPERM_SOLID_MAT)
+ {
+ sub_81008BC(unk_02038900);
+ sub_8100930(unk_02038900->decoration->shape);
+ sub_8100874(unk_02038900);
+ sub_810070C(unk_02038900->palette, ((u16 *)gMapHeader.mapData->secondaryTileset->metatiles + 8 * unk_02038900->decoration->tiles[0])[7] >> 12);
+ LoadSpritePalette(&gUnknown_083EC954);
+ gUnknown_020391A8 = gSprites[gUnknown_03004880.unk4].data0;
+ gUnknown_03004880.unk4 = CreateSprite(&gSpriteTemplate_83EC93C, gUnknown_083EC900[unk_02038900->decoration->shape].x, gUnknown_083EC900[unk_02038900->decoration->shape].y, 0);
+ } else
+ {
+ gUnknown_020391A8 = gSprites[gUnknown_03004880.unk4].data0;
+ gUnknown_03004880.unk4 = AddPseudoFieldObject(unk_02038900->decoration->tiles[0], sub_81009A8, gUnknown_083EC900[unk_02038900->decoration->shape].x, gUnknown_083EC900[unk_02038900->decoration->shape].y, 1);
+ gSprites[gUnknown_03004880.unk4].oam.priority = 1;
+ }
+}
+
+void SetUpPlacingDecorationPlayerAvatar(u8 taskId, struct UnkStruct_02038900 *unk_02038900)
+{
+ u8 v0;
+ v0 = 16 * (u8)gTasks[taskId].data[5] + gUnknown_083EC900[unk_02038900->decoration->shape].x - 8 * ((u8)gTasks[taskId].data[5] - 1);
+ if (unk_02038900->decoration->shape == DECORSHAPE_3x1 || unk_02038900->decoration->shape == DECORSHAPE_3x3 || unk_02038900->decoration->shape == DECORSHAPE_3x2)
+ {
+ v0 -= 8;
+ }
+ if (gSaveBlock2.playerGender == MALE)
+ {
+ gUnknown_020391A9 = AddPseudoFieldObject(0xc1, SpriteCallbackDummy, v0, 0x48, 0);
+ } else
+ {
+ gUnknown_020391A9 = AddPseudoFieldObject(0xc2, SpriteCallbackDummy, v0, 0x48, 0);
+ }
+ gSprites[gUnknown_020391A9].oam.priority = 1;
+ DestroySprite(&gSprites[gUnknown_020391A8]);
+ gUnknown_020391A8 = gUnknown_03004880.unk4;
+}
+
+void sub_80FF960(u8 taskId)
+{
+ switch (gDecorations[gUnknown_020388D0[gUnknown_020388F5]].shape)
+ {
+ case DECORSHAPE_1x1:
+ gTasks[taskId].data[5] = 1;
+ gTasks[taskId].data[6] = 1;
+ break;
+ case DECORSHAPE_2x1:
+ gTasks[taskId].data[5] = 2;
+ gTasks[taskId].data[6] = 1;
+ break;
+ case DECORSHAPE_3x1:
+ gTasks[taskId].data[5] = 3;
+ gTasks[taskId].data[6] = 1;
+ break;
+ case DECORSHAPE_4x2:
+ gTasks[taskId].data[5] = 4;
+ gTasks[taskId].data[6] = 2;
+ break;
+ case DECORSHAPE_2x2:
+ gTasks[taskId].data[5] = 2;
+ gTasks[taskId].data[6] = 2;
+ break;
+ case DECORSHAPE_1x2:
+ gTasks[taskId].data[5] = 1;
+ gTasks[taskId].data[6] = 2;
+ break;
+ case DECORSHAPE_1x3:
+ gTasks[taskId].data[5] = 1;
+ gTasks[taskId].data[6] = 3;
+ gTasks[taskId].data[1]++;
+ break;
+ case DECORSHAPE_2x4:
+ gTasks[taskId].data[5] = 2;
+ gTasks[taskId].data[6] = 4;
+ break;
+ case DECORSHAPE_3x3:
+ gTasks[taskId].data[5] = 3;
+ gTasks[taskId].data[6] = 3;
+ break;
+ case DECORSHAPE_3x2:
+ gTasks[taskId].data[5] = 3;
+ gTasks[taskId].data[6] = 2;
+ break;
+ }
+}
+
+void sub_80FFAB0(u8 taskId)
+{
+ gTasks[taskId].data[10] = 0;
+ gSprites[gUnknown_020391A8].data7 = 1;
+ gSprites[gUnknown_020391A9].data7 = 1;
+ sub_810045C();
+ sub_8100038(taskId);
+}
+
+void sub_80FFB08(u8 taskId)
+{
+ gTasks[taskId].data[10] = 0;
+ gSprites[gUnknown_020391A8].data7 = 1;
+ gSprites[gUnknown_020391A9].data7 = 1;
+ sub_810045C();
+ DisplayItemMessageOnField(taskId, gSecretBaseText_CancelDecorating, sub_8100248, 0);
+}
+
+bool8 sub_80FFB6C(u8 a0, u16 a1)
+{
+ if (sub_8057274(a0) != 1 || a1 != 0)
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool8 sub_80FFB94(u8 taskId, s16 x, s16 y, u16 decoId)
+{
+ if (x == gTasks[taskId].data[3] + 7 && y == gTasks[taskId].data[4] + 7 && decoId != 0)
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool8 sub_80FFBDC(u16 a0, const struct Decoration *decoration)
+{
+ if (sub_8057274(a0) != 1)
+ {
+ if (decoration->id == DECOR_SOLID_BOARD && sub_8057300(a0) == 1)
+ {
+ return TRUE;
+ }
+ if (sub_805729C(a0))
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+// When behaviorBy is set, it is masked by 0xf000. This is the step that fails to match when built.
+#ifdef NONMATCHING
+bool8 sub_80FFC24(u8 taskId, const struct Decoration *decoration)
+{
+ u8 i;
+ u8 j;
+ u8 behaviorAt;
+ u16 behaviorBy;
+ u8 mapY;
+ u8 mapX;
+ s16 curY;
+ s16 curX;
+ mapY = gTasks[taskId].data[6];
+ mapX = gTasks[taskId].data[5];
+ switch (decoration->permission)
+ {
+ case DECORPERM_SOLID_FLOOR:
+ case DECORPERM_PASS_FLOOR:
+ for (i=0; i<mapY; i++)
+ {
+ curY = gTasks[taskId].data[1] - i;
+ for (j=0; j<mapX; j++)
+ {
+ curX = gTasks[taskId].data[0] + j;
+ behaviorAt = MapGridGetMetatileBehaviorAt(curX, curY);
+ behaviorBy = GetBehaviorByMetatileId(0x200 + decoration->tiles[(mapY - 1 - i) * mapX + j]) & 0xf000;
+ if (!sub_80FFBDC(behaviorAt, decoration))
+ {
+ return FALSE;
+ }
+ if (!sub_80FFB94(taskId, curX, curY, behaviorBy))
+ {
+ return FALSE;
+ }
+ behaviorAt = GetFieldObjectIdByXYZ(curX, curY, 0);
+ if (behaviorAt != 0 && behaviorAt != 16)
+ {
+ return FALSE;
+ }
+ }
+ }
+ break;
+ case DECORPERM_BEHIND_FLOOR:
+ for (i=0; i<mapY-1; i++)
+ {
+ curY = gTasks[taskId].data[1] - i;
+ for (j=0; j<mapX; j++)
+ {
+ curX = gTasks[taskId].data[0] + j;
+ behaviorAt = MapGridGetMetatileBehaviorAt(curX, curY);
+ behaviorBy = GetBehaviorByMetatileId(0x200 + decoration->tiles[(mapY - 1 - i) * mapX + j]) & 0xf000;
+ if (!sub_805729C(behaviorAt) && !sub_80FFB6C(behaviorAt, behaviorBy))
+ {
+ return FALSE;
+ }
+ if (!sub_80FFB94(taskId, curX, curY, behaviorBy))
+ {
+ return FALSE;
+ }
+ if (GetFieldObjectIdByXYZ(curX, curY, 0) != 16)
+ {
+ return FALSE;
+ }
+ }
+ }
+ curY = gTasks[taskId].data[1] - mapY + 1;
+ for (j=0; j<mapX; j++)
+ {
+ curX = gTasks[taskId].data[0] + j;
+ behaviorAt = MapGridGetMetatileBehaviorAt(curX, curY);
+ behaviorBy = GetBehaviorByMetatileId(0x200 + decoration->tiles[j]) & 0xf000;
+ if (!sub_805729C(behaviorAt) && !sub_80572B0(behaviorAt))
+ {
+ return FALSE;
+ }
+ if (!sub_80FFB94(taskId, curX, curY, behaviorBy))
+ {
+ return FALSE;
+ }
+ behaviorAt = GetFieldObjectIdByXYZ(curX, curY, 0);
+ if (behaviorAt != 0 && behaviorAt != 16)
+ {
+ return FALSE;
+ }
+ }
+ break;
+ case DECORPERM_NA_WALL:
+ for (i=0; i<mapY; i++)
+ {
+ curY = gTasks[taskId].data[1] - i;
+ for (j=0; j<mapX; j++)
+ {
+ curX = gTasks[taskId].data[0] + j;
+ if (!sub_80572B0(MapGridGetMetatileBehaviorAt(curX, curY)))
+ {
+ return FALSE;
+ }
+ if (MapGridGetMetatileIdAt(curX, curY + 1) == 0x28c)
+ {
+ return FALSE;
+ }
+ }
+ }
+ break;
+ case DECORPERM_SOLID_MAT:
+ curY = gTasks[taskId].data[1];
+ for (j=0; j<mapX; j++)
+ {
+ curX = gTasks[taskId].data[0] + j;
+ behaviorAt = MapGridGetMetatileBehaviorAt(curX, curY);
+ if (decoration->shape == DECORSHAPE_1x2)
+ {
+ if (!sub_80572EC(behaviorAt))
+ {
+ return FALSE;
+ }
+ }
+ else if (!sub_80572D8(behaviorAt))
+ {
+ if (!sub_80572EC(behaviorAt))
+ {
+ return FALSE;
+ }
+ }
+ if (GetFieldObjectIdByXYZ(curX, curY, 0) != 16)
+ {
+ return FALSE;
+ }
+ }
+ break;
+ }
+ return TRUE;
+}
+#else
+__attribute__((naked))
+bool8 sub_80FFC24(u8 taskId, const struct Decoration *decoration)
+{
+ asm(".syntax unified\n"
+ "\tpush {r4-r7,lr}\n"
+ "\tmov r7, r10\n"
+ "\tmov r6, r9\n"
+ "\tmov r5, r8\n"
+ "\tpush {r5-r7}\n"
+ "\tsub sp, 0x24\n"
+ "\tstr r1, [sp]\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r0, 24\n"
+ "\tmov r10, r0\n"
+ "\tldr r1, _080FFC60 @ =gTasks\n"
+ "\tlsls r0, 2\n"
+ "\tadd r0, r10\n"
+ "\tlsls r0, 3\n"
+ "\tadds r0, r1\n"
+ "\tldrb r2, [r0, 0x14]\n"
+ "\tstr r2, [sp, 0x4]\n"
+ "\tldrb r0, [r0, 0x12]\n"
+ "\tstr r0, [sp, 0x8]\n"
+ "\tldr r3, [sp]\n"
+ "\tldrb r0, [r3, 0x11]\n"
+ "\tadds r2, r1, 0\n"
+ "\tcmp r0, 0x4\n"
+ "\tbls _080FFC56\n"
+ "\tb _08100024\n"
+ "_080FFC56:\n"
+ "\tlsls r0, 2\n"
+ "\tldr r1, _080FFC64 @ =_080FFC68\n"
+ "\tadds r0, r1\n"
+ "\tldr r0, [r0]\n"
+ "\tmov pc, r0\n"
+ "\t.align 2, 0\n"
+ "_080FFC60: .4byte gTasks\n"
+ "_080FFC64: .4byte _080FFC68\n"
+ "\t.align 2, 0\n"
+ "_080FFC68:\n"
+ "\t.4byte _080FFC7C\n"
+ "\t.4byte _080FFC7C\n"
+ "\t.4byte _080FFD68\n"
+ "\t.4byte _080FFF1C\n"
+ "\t.4byte _080FFFA0\n"
+ "_080FFC7C:\n"
+ "\tmovs r6, 0\n"
+ "\tldr r0, [sp, 0x4]\n"
+ "\tcmp r6, r0\n"
+ "\tbcc _080FFC86\n"
+ "\tb _08100024\n"
+ "_080FFC86:\n"
+ "\tmov r1, r10\n"
+ "\tlsls r1, 2\n"
+ "\tstr r1, [sp, 0x1C]\n"
+ "_080FFC8C:\n"
+ "\tmov r2, r10\n"
+ "\tlsls r0, r2, 2\n"
+ "\tadd r0, r10\n"
+ "\tlsls r0, 3\n"
+ "\tldr r3, _080FFD64 @ =gTasks\n"
+ "\tadds r0, r3\n"
+ "\tldrh r0, [r0, 0xA]\n"
+ "\tsubs r0, r6\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r0, 16\n"
+ "\tmov r9, r0\n"
+ "\tmovs r7, 0\n"
+ "\tadds r6, 0x1\n"
+ "\tstr r6, [sp, 0x14]\n"
+ "\tldr r0, [sp, 0x8]\n"
+ "\tcmp r7, r0\n"
+ "\tbcs _080FFD56\n"
+ "\tmov r1, r9\n"
+ "\tlsls r1, 16\n"
+ "\tstr r1, [sp, 0xC]\n"
+ "\tasrs r1, 16\n"
+ "\tmov r9, r1\n"
+ "_080FFCB8:\n"
+ "\tldr r0, [sp, 0x1C]\n"
+ "\tadd r0, r10\n"
+ "\tlsls r0, 3\n"
+ "\tldr r2, _080FFD64 @ =gTasks\n"
+ "\tadds r0, r2\n"
+ "\tldrh r0, [r0, 0x8]\n"
+ "\tadds r0, r7\n"
+ "\tlsls r0, 16\n"
+ "\tmov r8, r0\n"
+ "\tasrs r6, r0, 16\n"
+ "\tadds r0, r6, 0\n"
+ "\tmov r1, r9\n"
+ "\tbl MapGridGetMetatileBehaviorAt\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r4, r0, 24\n"
+ "\tldr r3, [sp, 0x4]\n"
+ "\tldr r1, [sp, 0x14]\n"
+ "\tsubs r0, r3, r1\n"
+ "\tldr r2, [sp, 0x8]\n"
+ "\tadds r1, r0, 0\n"
+ "\tmuls r1, r2\n"
+ "\tadds r1, r7\n"
+ "\tldr r3, [sp]\n"
+ "\tldr r0, [r3, 0x1C]\n"
+ "\tlsls r1, 1\n"
+ "\tadds r1, r0\n"
+ "\tmovs r2, 0x80\n"
+ "\tlsls r2, 2\n"
+ "\tadds r0, r2, 0\n"
+ "\tldrh r1, [r1]\n"
+ "\tadds r0, r1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r0, 16\n"
+ "\tbl GetBehaviorByMetatileId\n"
+ "\tmovs r3, 0xF0\n"
+ "\tlsls r3, 8\n"
+ "\tadds r1, r3, 0\n"
+ "\tadds r5, r1, 0\n"
+ "\tands r5, r0\n"
+ "\tadds r0, r4, 0\n"
+ "\tldr r1, [sp]\n"
+ "\tbl sub_80FFBDC\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r0, 0\n"
+ "\tbne _080FFD1A\n"
+ "\tb _080FFFF4\n"
+ "_080FFD1A:\n"
+ "\tmov r0, r10\n"
+ "\tadds r1, r6, 0\n"
+ "\tmov r2, r9\n"
+ "\tadds r3, r5, 0\n"
+ "\tbl sub_80FFB94\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r0, 0\n"
+ "\tbne _080FFD2E\n"
+ "\tb _080FFFF4\n"
+ "_080FFD2E:\n"
+ "\tmov r1, r8\n"
+ "\tlsrs r0, r1, 16\n"
+ "\tldr r2, [sp, 0xC]\n"
+ "\tlsrs r1, r2, 16\n"
+ "\tmovs r2, 0\n"
+ "\tbl GetFieldObjectIdByXYZ\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r4, r0, 24\n"
+ "\tcmp r4, 0\n"
+ "\tbeq _080FFD4A\n"
+ "\tcmp r4, 0x10\n"
+ "\tbeq _080FFD4A\n"
+ "\tb _080FFFF4\n"
+ "_080FFD4A:\n"
+ "\tadds r0, r7, 0x1\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r7, r0, 24\n"
+ "\tldr r3, [sp, 0x8]\n"
+ "\tcmp r7, r3\n"
+ "\tbcc _080FFCB8\n"
+ "_080FFD56:\n"
+ "\tldr r1, [sp, 0x14]\n"
+ "\tlsls r0, r1, 24\n"
+ "\tlsrs r6, r0, 24\n"
+ "\tldr r2, [sp, 0x4]\n"
+ "\tcmp r6, r2\n"
+ "\tbcc _080FFC8C\n"
+ "\tb _08100024\n"
+ "\t.align 2, 0\n"
+ "_080FFD64: .4byte gTasks\n"
+ "_080FFD68:\n"
+ "\tmovs r6, 0\n"
+ "\tmov r3, r10\n"
+ "\tlsls r3, 2\n"
+ "\tstr r3, [sp, 0x1C]\n"
+ "\tldr r0, [sp, 0x4]\n"
+ "\tsubs r0, 0x1\n"
+ "\tstr r0, [sp, 0x18]\n"
+ "\tcmp r6, r0\n"
+ "\tbge _080FFE54\n"
+ "\tadds r0, r3, 0\n"
+ "\tadd r0, r10\n"
+ "\tlsls r0, 3\n"
+ "\tstr r0, [sp, 0x10]\n"
+ "_080FFD82:\n"
+ "\tldr r1, [sp, 0x10]\n"
+ "\tadds r0, r1, r2\n"
+ "\tldrh r0, [r0, 0xA]\n"
+ "\tsubs r0, r6\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r0, 16\n"
+ "\tmov r9, r0\n"
+ "\tmovs r7, 0\n"
+ "\tadds r6, 0x1\n"
+ "\tstr r6, [sp, 0x14]\n"
+ "\tldr r3, [sp, 0x8]\n"
+ "\tcmp r7, r3\n"
+ "\tbcs _080FFE48\n"
+ "\tlsls r0, 16\n"
+ "\tstr r0, [sp, 0x20]\n"
+ "_080FFDA0:\n"
+ "\tldr r1, [sp, 0x10]\n"
+ "\tadds r0, r1, r2\n"
+ "\tldrh r0, [r0, 0x8]\n"
+ "\tadds r0, r7\n"
+ "\tlsls r0, 16\n"
+ "\tmov r8, r0\n"
+ "\tasrs r6, r0, 16\n"
+ "\tmov r2, r9\n"
+ "\tlsls r1, r2, 16\n"
+ "\tadds r0, r6, 0\n"
+ "\tasrs r1, 16\n"
+ "\tbl MapGridGetMetatileBehaviorAt\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r4, r0, 24\n"
+ "\tldr r3, [sp, 0x4]\n"
+ "\tldr r1, [sp, 0x14]\n"
+ "\tsubs r0, r3, r1\n"
+ "\tldr r2, [sp, 0x8]\n"
+ "\tadds r1, r0, 0\n"
+ "\tmuls r1, r2\n"
+ "\tadds r1, r7\n"
+ "\tldr r3, [sp]\n"
+ "\tldr r0, [r3, 0x1C]\n"
+ "\tlsls r1, 1\n"
+ "\tadds r1, r0\n"
+ "\tmovs r2, 0x80\n"
+ "\tlsls r2, 2\n"
+ "\tadds r0, r2, 0\n"
+ "\tldrh r1, [r1]\n"
+ "\tadds r0, r1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r0, 16\n"
+ "\tbl GetBehaviorByMetatileId\n"
+ "\tmovs r3, 0xF0\n"
+ "\tlsls r3, 8\n"
+ "\tadds r1, r3, 0\n"
+ "\tadds r5, r1, 0\n"
+ "\tands r5, r0\n"
+ "\tadds r0, r4, 0\n"
+ "\tbl sub_805729C\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r0, 0\n"
+ "\tbne _080FFE0C\n"
+ "\tadds r0, r4, 0\n"
+ "\tadds r1, r5, 0\n"
+ "\tbl sub_80FFB6C\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r0, 0\n"
+ "\tbne _080FFE0C\n"
+ "\tb _080FFFF4\n"
+ "_080FFE0C:\n"
+ "\tmov r0, r10\n"
+ "\tadds r1, r6, 0\n"
+ "\tldr r3, [sp, 0x20]\n"
+ "\tasrs r2, r3, 16\n"
+ "\tadds r3, r5, 0\n"
+ "\tbl sub_80FFB94\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r0, 0\n"
+ "\tbne _080FFE22\n"
+ "\tb _080FFFF4\n"
+ "_080FFE22:\n"
+ "\tmov r1, r8\n"
+ "\tlsrs r0, r1, 16\n"
+ "\tldr r2, [sp, 0x20]\n"
+ "\tlsrs r1, r2, 16\n"
+ "\tmovs r2, 0\n"
+ "\tbl GetFieldObjectIdByXYZ\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r0, 24\n"
+ "\tcmp r0, 0x10\n"
+ "\tbeq _080FFE3A\n"
+ "\tb _080FFFF4\n"
+ "_080FFE3A:\n"
+ "\tadds r0, r7, 0x1\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r7, r0, 24\n"
+ "\tldr r2, _080FFF18 @ =gTasks\n"
+ "\tldr r3, [sp, 0x8]\n"
+ "\tcmp r7, r3\n"
+ "\tbcc _080FFDA0\n"
+ "_080FFE48:\n"
+ "\tldr r1, [sp, 0x14]\n"
+ "\tlsls r0, r1, 24\n"
+ "\tlsrs r6, r0, 24\n"
+ "\tldr r3, [sp, 0x18]\n"
+ "\tcmp r6, r3\n"
+ "\tblt _080FFD82\n"
+ "_080FFE54:\n"
+ "\tldr r0, [sp, 0x1C]\n"
+ "\tadd r0, r10\n"
+ "\tlsls r0, 3\n"
+ "\tadds r0, r2\n"
+ "\tldrh r0, [r0, 0xA]\n"
+ "\tldr r1, [sp, 0x4]\n"
+ "\tsubs r0, r1\n"
+ "\tadds r0, 0x1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r0, 16\n"
+ "\tmov r9, r0\n"
+ "\tmovs r7, 0\n"
+ "\tldr r3, [sp, 0x8]\n"
+ "\tcmp r7, r3\n"
+ "\tbcc _080FFE74\n"
+ "\tb _08100024\n"
+ "_080FFE74:\n"
+ "\tlsls r0, 16\n"
+ "\tstr r0, [sp, 0x20]\n"
+ "_080FFE78:\n"
+ "\tldr r0, [sp, 0x1C]\n"
+ "\tadd r0, r10\n"
+ "\tlsls r0, 3\n"
+ "\tldr r1, _080FFF18 @ =gTasks\n"
+ "\tadds r0, r1\n"
+ "\tldrh r0, [r0, 0x8]\n"
+ "\tadds r0, r7\n"
+ "\tlsls r0, 16\n"
+ "\tmov r8, r0\n"
+ "\tasrs r6, r0, 16\n"
+ "\tmov r2, r9\n"
+ "\tlsls r1, r2, 16\n"
+ "\tadds r0, r6, 0\n"
+ "\tasrs r1, 16\n"
+ "\tbl MapGridGetMetatileBehaviorAt\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r4, r0, 24\n"
+ "\tldr r3, [sp]\n"
+ "\tldr r0, [r3, 0x1C]\n"
+ "\tlsls r1, r7, 1\n"
+ "\tadds r1, r0\n"
+ "\tmovs r2, 0x80\n"
+ "\tlsls r2, 2\n"
+ "\tadds r0, r2, 0\n"
+ "\tldrh r1, [r1]\n"
+ "\tadds r0, r1\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r0, 16\n"
+ "\tbl GetBehaviorByMetatileId\n"
+ "\tmovs r3, 0xF0\n"
+ "\tlsls r3, 8\n"
+ "\tadds r1, r3, 0\n"
+ "\tadds r5, r1, 0\n"
+ "\tands r5, r0\n"
+ "\tadds r0, r4, 0\n"
+ "\tbl sub_805729C\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r0, 0\n"
+ "\tbne _080FFEDA\n"
+ "\tadds r0, r4, 0\n"
+ "\tbl sub_80572B0\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r0, 0\n"
+ "\tbne _080FFEDA\n"
+ "\tb _080FFFF4\n"
+ "_080FFEDA:\n"
+ "\tmov r0, r10\n"
+ "\tadds r1, r6, 0\n"
+ "\tldr r3, [sp, 0x20]\n"
+ "\tasrs r2, r3, 16\n"
+ "\tadds r3, r5, 0\n"
+ "\tbl sub_80FFB94\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r0, 0\n"
+ "\tbne _080FFEF0\n"
+ "\tb _080FFFF4\n"
+ "_080FFEF0:\n"
+ "\tmov r1, r8\n"
+ "\tlsrs r0, r1, 16\n"
+ "\tldr r2, [sp, 0x20]\n"
+ "\tlsrs r1, r2, 16\n"
+ "\tmovs r2, 0\n"
+ "\tbl GetFieldObjectIdByXYZ\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r4, r0, 24\n"
+ "\tcmp r4, 0\n"
+ "\tbeq _080FFF0A\n"
+ "\tcmp r4, 0x10\n"
+ "\tbne _080FFFF4\n"
+ "_080FFF0A:\n"
+ "\tadds r0, r7, 0x1\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r7, r0, 24\n"
+ "\tldr r3, [sp, 0x8]\n"
+ "\tcmp r7, r3\n"
+ "\tbcc _080FFE78\n"
+ "\tb _08100024\n"
+ "\t.align 2, 0\n"
+ "_080FFF18: .4byte gTasks\n"
+ "_080FFF1C:\n"
+ "\tmovs r6, 0\n"
+ "\tldr r0, [sp, 0x4]\n"
+ "\tcmp r6, r0\n"
+ "\tbcc _080FFF26\n"
+ "\tb _08100024\n"
+ "_080FFF26:\n"
+ "\tmov r1, r10\n"
+ "\tlsls r0, r1, 2\n"
+ "\tadd r0, r10\n"
+ "\tlsls r1, r0, 3\n"
+ "\tldr r2, _080FFF9C @ =gTasks\n"
+ "\tadds r0, r1, r2\n"
+ "\tldrh r0, [r0, 0xA]\n"
+ "\tsubs r0, r6\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r0, 16\n"
+ "\tmov r9, r0\n"
+ "\tmovs r7, 0\n"
+ "\tldr r3, [sp, 0x8]\n"
+ "\tcmp r7, r3\n"
+ "\tbcs _080FFF8C\n"
+ "\tadds r0, r2, 0\n"
+ "\tadds r1, r0\n"
+ "\tmov r8, r1\n"
+ "\tmov r1, r9\n"
+ "\tlsls r0, r1, 16\n"
+ "\tasrs r5, r0, 16\n"
+ "_080FFF50:\n"
+ "\tmov r2, r8\n"
+ "\tldrh r0, [r2, 0x8]\n"
+ "\tadds r0, r7\n"
+ "\tlsls r0, 16\n"
+ "\tasrs r4, r0, 16\n"
+ "\tadds r0, r4, 0\n"
+ "\tadds r1, r5, 0\n"
+ "\tbl MapGridGetMetatileBehaviorAt\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r0, 24\n"
+ "\tbl sub_80572B0\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _080FFFF4\n"
+ "\tadds r0, r4, 0\n"
+ "\tadds r1, r5, 0x1\n"
+ "\tbl MapGridGetMetatileIdAt\n"
+ "\tmovs r1, 0xA3\n"
+ "\tlsls r1, 2\n"
+ "\tcmp r0, r1\n"
+ "\tbeq _080FFFF4\n"
+ "\tadds r0, r7, 0x1\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r7, r0, 24\n"
+ "\tldr r3, [sp, 0x8]\n"
+ "\tcmp r7, r3\n"
+ "\tbcc _080FFF50\n"
+ "_080FFF8C:\n"
+ "\tadds r0, r6, 0x1\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r6, r0, 24\n"
+ "\tldr r0, [sp, 0x4]\n"
+ "\tcmp r6, r0\n"
+ "\tbcc _080FFF26\n"
+ "\tb _08100024\n"
+ "\t.align 2, 0\n"
+ "_080FFF9C: .4byte gTasks\n"
+ "_080FFFA0:\n"
+ "\tmov r3, r10\n"
+ "\tlsls r1, r3, 2\n"
+ "\tadds r0, r1, r3\n"
+ "\tlsls r0, 3\n"
+ "\tadds r0, r2\n"
+ "\tldrh r0, [r0, 0xA]\n"
+ "\tmov r9, r0\n"
+ "\tmovs r7, 0\n"
+ "\tstr r1, [sp, 0x1C]\n"
+ "\tldr r0, [sp, 0x8]\n"
+ "\tcmp r7, r0\n"
+ "\tbcs _08100024\n"
+ "\tadds r6, r2, 0\n"
+ "\tmov r1, r9\n"
+ "\tlsls r1, 16\n"
+ "\tstr r1, [sp, 0x20]\n"
+ "_080FFFC0:\n"
+ "\tldr r0, [sp, 0x1C]\n"
+ "\tadd r0, r10\n"
+ "\tlsls r0, 3\n"
+ "\tadds r0, r6\n"
+ "\tldrh r0, [r0, 0x8]\n"
+ "\tadds r0, r7\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r5, r0, 16\n"
+ "\tasrs r0, 16\n"
+ "\tmov r2, r9\n"
+ "\tlsls r1, r2, 16\n"
+ "\tasrs r1, 16\n"
+ "\tbl MapGridGetMetatileBehaviorAt\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r4, r0, 24\n"
+ "\tldr r3, [sp]\n"
+ "\tldrb r0, [r3, 0x12]\n"
+ "\tcmp r0, 0x5\n"
+ "\tbne _080FFFF8\n"
+ "_080FFFE8:\n"
+ "\tadds r0, r4, 0\n"
+ "\tbl sub_80572EC\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r0, 0\n"
+ "\tbne _08100004\n"
+ "_080FFFF4:\n"
+ "\tmovs r0, 0\n"
+ "\tb _08100026\n"
+ "_080FFFF8:\n"
+ "\tadds r0, r4, 0\n"
+ "\tbl sub_80572D8\n"
+ "\tlsls r0, 24\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _080FFFE8\n"
+ "_08100004:\n"
+ "\tadds r0, r5, 0\n"
+ "\tldr r2, [sp, 0x20]\n"
+ "\tlsrs r1, r2, 16\n"
+ "\tmovs r2, 0\n"
+ "\tbl GetFieldObjectIdByXYZ\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r0, 24\n"
+ "\tcmp r0, 0x10\n"
+ "\tbne _080FFFF4\n"
+ "\tadds r0, r7, 0x1\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r7, r0, 24\n"
+ "\tldr r3, [sp, 0x8]\n"
+ "\tcmp r7, r3\n"
+ "\tbcc _080FFFC0\n"
+ "_08100024:\n"
+ "\tmovs r0, 0x1\n"
+ "_08100026:\n"
+ "\tadd sp, 0x24\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"
+ ".syntax divided\n");
+}
+#endif
+
+void sub_8100038(u8 taskId)
+{
+ if (sub_80FFC24(taskId, &gDecorations[gUnknown_020388D0[gUnknown_020388F5]]) == 1)
+ {
+ DisplayItemMessageOnField(taskId, gSecretBaseText_PlaceItHere, sub_81000A0, 0);
+ } else
+ {
+ PlaySE(SE_HAZURE);
+ DisplayItemMessageOnField(taskId, gSecretBaseText_CantBePlacedHere, sub_81006A8, 0);
+ }
+}
+
+void sub_81000A0(u8 taskId)
+{
+ DisplayYesNoMenu(20, 8, 1);
+ DoYesNoFuncWithChoice(taskId, &gUnknown_083EC95C);
+}
+
+void sub_81000C4(u8 taskId)
+{
+ MenuZeroFillWindowRect(0, 0, 29, 19);
+ sub_8100174(taskId);
+ if (gDecorations[gUnknown_020388D0[gUnknown_020388F5]].permission != DECORPERM_SOLID_MAT)
+ {
+ sub_80FF394(gTasks[taskId].data[0], gTasks[taskId].data[1], gUnknown_020388D0[gUnknown_020388F5]);
+ } else
+ {
+ gUnknown_020391A4 = gTasks[taskId].data[0] - 7;
+ gUnknown_020391A6 = gTasks[taskId].data[1] - 7;
+ ScriptContext1_SetupScript(gUnknown_081A2F7B);
+ }
+ gSprites[gUnknown_020391A8].pos1.y += 2;
+ sub_810028C(taskId);
+}
+
+void sub_8100174(u8 taskId)
+{
+ u16 i;
+ for (i=0; i<ewram_1f000.size; i++)
+ {
+ if (ewram_1f000.items[i] == 0)
+ {
+ ewram_1f000.items[i] = gUnknown_020388D0[gUnknown_020388F5];
+ ewram_1f000.pos[i] = ((gTasks[taskId].data[0] - 7) << 4) + (gTasks[taskId].data[1] - 7);
+ break;
+ }
+ }
+ if (!ewram_1f000.isPlayerRoom)
+ {
+ for (i=0; i<16; i++)
+ {
+ if (gUnknown_020388D6[i] == 0)
+ {
+ gUnknown_020388D6[i] = gUnknown_020388F5 + 1;
+ break;
+ }
+ }
+ } else
+ {
+ for (i=0; i<12; i++)
+ {
+ if (gUnknown_020388E6[i] == 0)
+ {
+ gUnknown_020388E6[i] = gUnknown_020388F5 + 1;
+ break;
+ }
+ }
+ }
+}
+
+void sub_8100248(u8 taskId)
+{
+ DisplayYesNoMenu(20, 8, 1);
+ DoYesNoFuncWithChoice(taskId, &gUnknown_083EC964);
+}
+
+void sub_810026C(u8 taskId)
+{
+ MenuZeroFillWindowRect(0, 0, 29, 19);
+ sub_810028C(taskId);
+}
+
+void sub_810028C(u8 taskId)
+{
+ fade_screen(1, 0);
+ gTasks[taskId].data[2] = 0;
+ gTasks[taskId].func = c1_overworld_prev_quest;
+}
+
+void c1_overworld_prev_quest(u8 taskId)
+{
+ switch (gTasks[taskId].data[2])
+ {
+ case 0:
+ ScriptContext2_Enable();
+ if (!gPaletteFade.active)
+ {
+ sub_80FF114(taskId);
+ gTasks[taskId].data[2] = 1;
+ }
+ break;
+ case 1:
+ sub_81016F4();
+ FreeSpritePaletteByTag(0xbb8);
+ gFieldCallback = &sub_8100364;
+ SetMainCallback2(c2_exit_to_overworld_2_switch);
+ DestroyTask(taskId);
+ break;
+ }
+}
+
+void sub_8100334(u8 taskId)
+{
+ if (sub_807D770() == 1)
+ {
+ gTasks[taskId].func = sub_80FE948;
+ }
+}
+
+void sub_8100364(void)
+{
+ ScriptContext2_Enable();
+ LoadScrollIndicatorPalette();
+ pal_fill_black();
+ sub_80FE7EC(CreateTask(sub_8100334, 8));
+}
+
+bool8 sub_810038C(u8 taskId)
+{
+ s16 *data;
+ data = gTasks[taskId].data;
+ if (gUnknown_020391AA == DIR_SOUTH && data[1] - data[6] - 6 < 0)
+ {
+ data[1]++;
+ return FALSE;
+ } else if (gUnknown_020391AA == DIR_NORTH && data[1] - 7 >= gMapHeader.mapData->height)
+ {
+ data[1]--;
+ return FALSE;
+ } else if (gUnknown_020391AA == DIR_WEST && data[0] - 7 < 0)
+ {
+ data[0]++;
+ return FALSE;
+ } else if (gUnknown_020391AA == DIR_EAST && data[0] + data[5] - 8 >= gMapHeader.mapData->width)
+ {
+ data[0]--;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool8 sub_8100430(void)
+{
+ if ((gMain.heldKeys & DPAD_ANY) != DPAD_UP && (gMain.heldKeys & DPAD_ANY) != DPAD_DOWN && (gMain.heldKeys & DPAD_ANY) != DPAD_LEFT && (gMain.heldKeys & DPAD_ANY) != DPAD_RIGHT)
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void sub_810045C(void)
+{
+ gUnknown_020391AA = 0;
+ gSprites[gUnknown_020391A8].data2 = 0;
+ gSprites[gUnknown_020391A8].data3 = 0;
+}
+
+void sub_8100494(u8 taskId)
+{
+ if (!gSprites[gUnknown_020391A8].data4)
+ {
+ if (gTasks[taskId].data[10] == 1)
+ {
+ gUnknown_083EC96C[gTasks[taskId].data[12]].yesFunc(taskId);
+ return;
+ } else if (gTasks[taskId].data[10] == 2)
+ {
+ gUnknown_083EC96C[gTasks[taskId].data[12]].noFunc(taskId);
+ return;
+ }
+ if ((gMain.heldKeys & DPAD_ANY) == DPAD_UP)
+ {
+ gUnknown_020391AA = DIR_SOUTH;
+ gSprites[gUnknown_020391A8].data2 = 0;
+ gSprites[gUnknown_020391A8].data3 = -2;
+ gTasks[taskId].data[1]--;
+ }
+ if ((gMain.heldKeys & DPAD_ANY) == DPAD_DOWN)
+ {
+ gUnknown_020391AA = DIR_NORTH;
+ gSprites[gUnknown_020391A8].data2 = 0;
+ gSprites[gUnknown_020391A8].data3 = 2;
+ gTasks[taskId].data[1]++;
+ }
+ if ((gMain.heldKeys & DPAD_ANY) == DPAD_LEFT)
+ {
+ gUnknown_020391AA = DIR_WEST;
+ gSprites[gUnknown_020391A8].data2 = -2;
+ gSprites[gUnknown_020391A8].data3 = 0;
+ gTasks[taskId].data[0]--;
+ }
+ if ((gMain.heldKeys & DPAD_ANY) == DPAD_RIGHT)
+ {
+ gUnknown_020391AA = DIR_EAST;
+ gSprites[gUnknown_020391A8].data2 = 2;
+ gSprites[gUnknown_020391A8].data3 = 0;
+ gTasks[taskId].data[0]++;
+ }
+ if (!sub_8100430() || !sub_810038C(taskId))
+ {
+ sub_810045C();
+ }
+ }
+ if (gUnknown_020391AA)
+ {
+ gSprites[gUnknown_020391A8].data4++;
+ gSprites[gUnknown_020391A8].data4 &= 7;
+ }
+ if (!gTasks[taskId].data[10])
+ {
+ if (gMain.newKeys & A_BUTTON)
+ {
+ gTasks[taskId].data[10] = A_BUTTON;
+ }
+ if (gMain.newKeys & B_BUTTON)
+ {
+ gTasks[taskId].data[10] = B_BUTTON;
+ }
+ }
+}
+
+void sub_810065C(u8 taskId)
+{
+ MenuZeroFillWindowRect(0, 0, 29, 19);
+ gSprites[gUnknown_020391A8].data7 = 0;
+ gTasks[taskId].data[10] = 0;
+ gTasks[taskId].func = sub_8100494;
+}
+
+void sub_81006A8(u8 taskId)
+{
+ if ((gMain.newKeys & A_BUTTON) || (gMain.newKeys & B_BUTTON))
+ {
+ sub_810065C(taskId);
+ }
+}
+
+void sub_81006D0(struct UnkStruct_02038900 *unk_02038900)
+{
+ u16 i;
+ for (i=0; i<0x800; i++)
+ {
+ unk_02038900->image[i] = 0;
+ }
+ for (i=0; i<0x40; i++)
+ {
+ unk_02038900->tiles[i] = 0;
+ }
+}
+
+void sub_810070C(u16 *a0, u16 a1)
+{
+ u16 i;
+ for (i=0; i<16; i++)
+ {
+ a0[i] = ((u16 *)gMapHeader.mapData->primaryTileset->palettes)[16 * a1 + i];
+ }
+}
+
+void sub_8100740(u8 *dest, u16 flags)
+{
+ u8 buffer[32];
+ u16 mode;
+ u16 i;
+ mode = flags >> 10;
+ if (flags != 0)
+ {
+ flags &= 0x3ff;
+ }
+ for (i=0; i<32; i++)
+ {
+ buffer[i] = ((u8 *)gMapHeader.mapData->primaryTileset->tiles)[flags * 32 + i];
+ }
+ switch (mode)
+ {
+ case 0:
+ for (i=0; i<32; i++)
+ {
+ dest[i] = buffer[i];
+ }
+ break;
+ case 1:
+ for (i=0; i<8; i++)
+ {
+ dest[4*i] = (buffer[4*(i+1) - 1] >> 4) + ((buffer[4*(i+1) - 1] & 0xf) << 4);
+ dest[4*i + 1] = (buffer[4*(i+1) - 2] >> 4) + ((buffer[4*(i+1) - 2] & 0xf) << 4);
+ dest[4*i + 2] = (buffer[4*(i+1) - 3] >> 4) + ((buffer[4*(i+1) - 3] & 0xf) << 4);
+ dest[4*i + 3] = (buffer[4*(i+1) - 4] >> 4) + ((buffer[4*(i+1) - 4] & 0xf) << 4);
+ }
+ break;
+ case 2:
+ for (i=0; i<8; i++)
+ {
+ dest[4*i] = buffer[4*(7-i)];
+ dest[4*i + 1] = buffer[4*(7-i) + 1];
+ dest[4*i + 2] = buffer[4*(7-i) + 2];
+ dest[4*i + 3] = buffer[4*(7-i) + 3];
+ }
+ break;
+ case 3:
+ for (i=0; i<32; i++)
+ {
+ dest[i] = (buffer[31-i] >> 4) + ((buffer[31-i] & 0xf) << 4);
+ }
+ break;
+ }
+}
+
+void sub_8100874(struct UnkStruct_02038900 *unk_02038900)
+{
+ u16 i;
+ for (i=0; i<0x40; i++)
+ sub_8100740(&unk_02038900->image[i * 32], unk_02038900->tiles[i]);
+}
+
+u16 sub_810089C(u16 a0)
+{
+ return ((u16 *)gMapHeader.mapData->secondaryTileset->metatiles)[a0] & 0xfff;
+}
+
+void sub_81008BC(struct UnkStruct_02038900 *unk_02038900)
+{
+ u8 i;
+ u8 shape;
+ shape = unk_02038900->decoration->shape;
+ for (i=0; i<gUnknown_083EC860[shape].size; i++)
+ {
+ unk_02038900->tiles[gUnknown_083EC860[shape].tiles[i]] = sub_810089C(unk_02038900->decoration->tiles[gUnknown_083EC860[shape].y[i]] * 8 + gUnknown_083EC860[shape].x[i]);
+ }
+}
+
+void sub_8100930(u8 decoShape)
+{
+ gUnknown_020391AC.y = 0;
+ gUnknown_020391AC.affineMode = 0;
+ gUnknown_020391AC.objMode = 0;
+ gUnknown_020391AC.mosaic = 0;
+ gUnknown_020391AC.bpp = 0;
+ gUnknown_020391AC.shape = gUnknown_083EC900[decoShape].shape;
+ gUnknown_020391AC.x = 0;
+ gUnknown_020391AC.matrixNum = 0;
+ gUnknown_020391AC.size = gUnknown_083EC900[decoShape].size;
+ gUnknown_020391AC.tileNum = 0;
+ gUnknown_020391AC.priority = 1;
+ gUnknown_020391AC.paletteNum = 0;
+}
+
+void sub_81009A8(struct Sprite *sprite)
+{
+ sprite->data2 = 0;
+ sprite->data3 = 0;
+ sprite->data4 = 0;
+ sprite->data5 = 0;
+ sprite->data6 = 0;
+ sprite->data7 = 0;
+ sprite->callback = sub_81009C0;
+}
+
+void sub_81009C0(struct Sprite *sprite)
+{
+ if (sprite->data7 == 0)
+ {
+ if (sprite->data6 < 15)
+ {
+ sprite->invisible = 0;
+ } else
+ {
+ sprite->invisible = 1;
+ }
+ sprite->data6 = (sprite->data6 + 1) & 0x1f;
+ } else
+ {
+ sprite->invisible = 0;
+ }
+}
+
+void sub_8100A0C(u8 taskId)
+{
+ if (sub_8100D38(taskId) == 1)
+ {
+ fade_screen(1, 0);
+ gTasks[taskId].data[2] = 0;
+ gTasks[taskId].func = sub_8100E70;
+ } else
+ {
+ DisplayItemMessageOnField(taskId, gSecretBaseText_NoDecorInUse, sub_80FE428, 0);
+ }
+}
+
+void sub_8100A60(u8 a0)
+{
+ ewram_1f000.items[a0] = 0;
+ ewram_1f000.pos[a0] = 0;
+}
+
+void sub_8100A7C(void)
+{
+ u16 i;
+ gSpecialVar_0x8005 = 0;
+ gScriptResult = 0;
+ if (gSpecialVar_0x8004 == gUnknown_02039234)
+ {
+ gScriptResult = 1;
+ } else if (gDecorations[ewram_1f000.items[gUnknown_020391B4[gSpecialVar_0x8004].decorId]].permission == DECORPERM_SOLID_MAT)
+ {
+ gSpecialVar_0x8005 = gUnknown_020391B4[gSpecialVar_0x8004].flagId;
+ sub_8100A60(gUnknown_020391B4[gSpecialVar_0x8004].decorId);
+ for (i=0; i<gMapHeader.events->mapObjectCount; i++)
+ {
+ if (gMapHeader.events->mapObjects[i].flagId == gSpecialVar_0x8005)
+ {
+ gSpecialVar_0x8006 = gMapHeader.events->mapObjects[i].localId;
+ break;
+ }
+ }
+ }
+}
+
+void sub_8100B20(void)
+{
+ u8 i;
+ for (i=0; i<gMapHeader.events->mapObjectCount; i++)
+ {
+ if (gMapHeader.events->mapObjects[i].flagId == gSpecialVar_0x8004)
+ {
+ gSpecialVar_0x8005 = gMapHeader.events->mapObjects[i].localId;
+ break;
+ }
+ }
+}
+
+void sub_8100B6C(void)
+{
+ u8 i;
+ u8 j;
+ u8 k;
+ u8 x;
+ u8 y;
+ u8 permission;
+ for (i=0; i<gUnknown_02039234; i++)
+ {
+ permission = gDecorations[ewram_1f000.items[gUnknown_020391B4[i].decorId]].permission;
+ x = ewram_1f000.pos[gUnknown_020391B4[i].decorId] >> 4;
+ y = ewram_1f000.pos[gUnknown_020391B4[i].decorId] & 0xf;
+ if (permission != DECORPERM_SOLID_MAT)
+ {
+ if (ewram_1f000.items[gUnknown_020391B4[i].decorId] == DECOR_SAND_ORNAMENT && MapGridGetMetatileIdAt(x + 7, y + 7) == 0x28c)
+ {
+ gUnknown_020391B4[i].height++;
+ }
+ for (j=0; j<gUnknown_020391B4[i].height; j++)
+ {
+ for (k=0; k<gUnknown_020391B4[i].width; k++)
+ {
+ MapGridSetMetatileEntryAt(x + 7 + k, y + 7 - j, ((u16 *)gMapHeader.mapData->map)[(x + k) + gMapHeader.mapData->width * (y - j)] | 0x3000);
+ }
+ }
+ sub_8100A60(gUnknown_020391B4[i].decorId);
+ }
+ }
+}
+
+void sub_8100C88(u8 taskId)
+{
+ switch (gTasks[taskId].data[2])
+ {
+ case 0:
+ sub_8100B6C();
+ gTasks[taskId].data[2] = 1;
+ break;
+ case 1:
+ if (!gPaletteFade.active)
+ {
+ DrawWholeMapView();
+ ScriptContext1_SetupScript(gUnknown_081A2F8A);
+ MenuZeroFillWindowRect(0, 0, 29, 19);
+ gTasks[taskId].data[2] = 2;
+ }
+ break;
+ case 2:
+ ScriptContext2_Enable();
+ sub_80FED90(taskId);
+ pal_fill_black();
+ gTasks[taskId].data[2] = 3;
+ break;
+ case 3:
+ if (sub_807D770() == 1)
+ {
+ gTasks[taskId].data[13] = -1;
+ DisplayItemMessageOnField(taskId, gSecretBaseText_DecorReturned, sub_81010F0, 0);
+ }
+ break;
+ }
+}
+
+bool8 sub_8100D38(u8 taskId)
+{
+ u16 i;
+ for (i=0; i<ewram_1f000.size; i++)
+ {
+ if (ewram_1f000.items[i] != 0)
+ {
+ gTasks[taskId].data[13] = i;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void SetUpPuttingAwayDecorationPlayerAvatar(void)
+{
+ player_get_direction_lower_nybble();
+ MenuZeroFillWindowRect(0, 0, 29, 19);
+ gUnknown_020391A8 = gSprites[gUnknown_03004880.unk4].data0;
+ sub_81016C8();
+ gUnknown_03004880.unk4 = CreateSprite(&gSpriteTemplate_83ECA88, 0x78, 0x50, 0);
+ if (gSaveBlock2.playerGender == MALE)
+ {
+ gUnknown_020391A9 = AddPseudoFieldObject(0xc1, SpriteCallbackDummy, 0x88, 0x48, 0);
+ } else
+ {
+ gUnknown_020391A9 = AddPseudoFieldObject(0xc2, SpriteCallbackDummy, 0x88, 0x48, 0);
+ }
+ gSprites[gUnknown_020391A9].oam.priority = 1;
+ DestroySprite(&gSprites[gUnknown_020391A8]);
+ gUnknown_020391A8 = gUnknown_03004880.unk4;
+ gSprites[gUnknown_020391A8].oam.priority = 1;
+}
+
+void sub_8100E70(u8 taskId)
+{
+ s16 *data;
+ data = gTasks[taskId].data;
+ switch (data[2])
+ {
+ case 0:
+ if (!gPaletteFade.active)
+ {
+ sub_80FF0E0(taskId);
+ data[2] = 1;
+ data[6] = 1;
+ data[5] = 1;
+ HandleDestroyMenuCursors();
+ }
+ break;
+ case 1:
+ SetUpPuttingAwayDecorationPlayerAvatar();
+ pal_fill_black();
+ data[2] = 2;
+ break;
+ case 2:
+ if (sub_807D770() == TRUE)
+ {
+ data[12] = 1;
+ sub_8100EEC(taskId);
+ }
+ break;
+ }
+}
+
+void sub_8100EEC(u8 taskId)
+{
+ MenuZeroFillWindowRect(0, 0, 29, 19);
+ gSprites[gUnknown_020391A8].data7 = 0;
+ gSprites[gUnknown_020391A8].invisible = 0;
+ gSprites[gUnknown_020391A8].callback = sub_8101698;
+ gSprites[gUnknown_020391A9].pos1.x = 0x88;
+ gSprites[gUnknown_020391A9].pos1.y = 0x48;
+ gTasks[taskId].data[10] = 0;
+ gTasks[taskId].func = sub_8100494;
+}
+
+void sub_8100F88(u8 taskId)
+{
+ gTasks[taskId].data[10] = 0;
+ sub_810045C();
+ sub_8101024(taskId);
+}
+
+void sub_8100FB4(u8 taskId)
+{
+ gTasks[taskId].data[10] = 0;
+ sub_810045C();
+ gSprites[gUnknown_020391A8].invisible = 0;
+ gSprites[gUnknown_020391A8].callback = SpriteCallbackDummy;
+ DisplayItemMessageOnField(taskId, gSecretBaseText_StopPuttingAwayDecor, sub_810156C, 0);
+}
+
+void sub_8101024(u8 taskId)
+{
+ u8 mtBehavior;
+ s16 *data;
+ sub_8101460(taskId);
+ if (gUnknown_02039234 != 0)
+ {
+ DisplayItemMessageOnField(taskId, gSecretBaseText_ReturnDecor, sub_8101518, 0);
+ } else
+ {
+ data = gTasks[taskId].data;
+ mtBehavior = MapGridGetMetatileBehaviorAt(data[0], data[1]);
+ if (MetatileBehavior_IsSecretBasePC(mtBehavior) == TRUE || sub_805738C(mtBehavior) == TRUE)
+ {
+ gSprites[gUnknown_020391A8].invisible = 0;
+ gSprites[gUnknown_020391A8].callback = SpriteCallbackDummy;
+ DisplayItemMessageOnField(taskId, gSecretBaseText_StopPuttingAwayDecor, sub_810156C, 0);
+ } else
+ {
+ DisplayItemMessageOnField(taskId, gSecretBaseText_NoDecor, sub_81010F0, 0);
+ }
+ }
+}
+
+void sub_81010F0(u8 taskId)
+{
+ if ((gMain.newKeys & A_BUTTON) || (gMain.newKeys & B_BUTTON))
+ {
+ sub_8100EEC(taskId);
+ }
+}
+
+void sub_8101118(u8 decorIdx, struct UnkStruct_020391B4 *unk_020391B4)
+{
+ if (gDecorations[decorIdx].shape == DECORSHAPE_1x1)
+ {
+ unk_020391B4->width = 1;
+ unk_020391B4->height = 1;
+ } else if (gDecorations[decorIdx].shape == DECORSHAPE_2x1)
+ {
+ unk_020391B4->width = 2;
+ unk_020391B4->height = 1;
+ } else if (gDecorations[decorIdx].shape == DECORSHAPE_3x1)
+ {
+ unk_020391B4->width = 3;
+ unk_020391B4->height = 1;
+ } else if (gDecorations[decorIdx].shape == DECORSHAPE_4x2)
+ {
+ unk_020391B4->width = 4;
+ unk_020391B4->height = 2;
+ } else if (gDecorations[decorIdx].shape == DECORSHAPE_2x2)
+ {
+ unk_020391B4->width = 2;
+ unk_020391B4->height = 2;
+ } else if (gDecorations[decorIdx].shape == DECORSHAPE_1x2)
+ {
+ unk_020391B4->width = 1;
+ unk_020391B4->height = 2;
+ } else if (gDecorations[decorIdx].shape == DECORSHAPE_1x3)
+ {
+ unk_020391B4->width = 1;
+ unk_020391B4->height = 3;
+ } else if (gDecorations[decorIdx].shape == DECORSHAPE_2x4)
+ {
+ unk_020391B4->width = 2;
+ unk_020391B4->height = 4;
+ } else if (gDecorations[decorIdx].shape == DECORSHAPE_3x3)
+ {
+ unk_020391B4->width = 3;
+ unk_020391B4->height = 3;
+ } else if (gDecorations[decorIdx].shape == DECORSHAPE_3x2)
+ {
+ unk_020391B4->width = 3;
+ unk_020391B4->height = 2;
+ }
+}
+
+void sub_8101198(u8 x, u8 y)
+{
+ gSprites[gUnknown_020391A8].invisible = 1;
+ gSprites[gUnknown_020391A8].callback = SpriteCallbackDummy;
+ gSprites[gUnknown_020391A9].pos1.x = 0x88 + x * 16;
+ gSprites[gUnknown_020391A9].pos1.y = 0x48 + y * 16;
+}
+
+bool8 sub_8101200(u8 taskId, u8 decorIdx, struct UnkStruct_020391B4 *unk_020391B4)
+{
+ u8 x;
+ u8 y;
+ u8 xOff;
+ u8 yOff;
+ x = gTasks[taskId].data[0] - 7;
+ y = gTasks[taskId].data[1] - 7;
+ xOff = ewram_1f000.pos[decorIdx] >> 4;
+ yOff = ewram_1f000.pos[decorIdx] & 0xf;
+ if (ewram_1f000.items[decorIdx] == DECOR_SAND_ORNAMENT && MapGridGetMetatileIdAt(xOff + 7, yOff + 7) == 0x28c)
+ {
+ unk_020391B4->height--;
+ }
+ if (x >= xOff && x < xOff + unk_020391B4->width && y > yOff - unk_020391B4->height && y <= yOff)
+ {
+ sub_8101198(unk_020391B4->width - (x - xOff + 1), yOff - y);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void sub_81012A0(void)
+{
+ u8 xOff;
+ u8 yOff;
+ u16 i;
+ xOff = ewram_1f000.pos[gUnknown_020391B4[gUnknown_02039234].decorId] >> 4;
+ yOff = ewram_1f000.pos[gUnknown_020391B4[gUnknown_02039234].decorId] & 0xf;
+ for (i=0; i<0x40; i++)
+ {
+ if (gSaveBlock1.mapObjectTemplates[i].x == xOff && gSaveBlock1.mapObjectTemplates[i].y == yOff && !FlagGet(gSaveBlock1.mapObjectTemplates[i].flagId))
+ {
+ gUnknown_020391B4[gUnknown_02039234].flagId = gSaveBlock1.mapObjectTemplates[i].flagId;
+ break;
+ }
+ }
+}
+
+bool8 sub_8101340(u8 taskId)
+{
+ u16 i;
+ for (i=0; i<ewram_1f000.size; i++)
+ {
+ if (ewram_1f000.items[i] != 0)
+ {
+ if (gDecorations[ewram_1f000.items[i]].permission == DECORPERM_SOLID_MAT)
+ {
+ sub_8101118(ewram_1f000.items[i], gUnknown_020391B4);
+ if (sub_8101200(taskId, i, gUnknown_020391B4) == TRUE)
+ {
+ gUnknown_020391B4->decorId = i;
+ sub_81012A0();
+ gUnknown_02039234 = 1;
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+void sub_81013B8(u8 a0, u8 a1, u8 a2, u8 a3)
+{
+ u8 i;
+ u8 xOff;
+ u8 yOff;
+ u8 decorIdx;
+ for (i=0; i<ewram_1f000.size; i++)
+ {
+ decorIdx = ewram_1f000.items[i];
+ xOff = ewram_1f000.pos[i] >> 4;
+ yOff = ewram_1f000.pos[i] & 0xf;
+ if (decorIdx != 0 && gDecorations[decorIdx].permission == DECORPERM_SOLID_MAT && a0 <= xOff && a1 <= yOff && a2 >= xOff && a3 >= yOff)
+ {
+ gUnknown_020391B4[gUnknown_02039234].decorId = i;
+ sub_81012A0();
+ gUnknown_02039234++;
+ }
+ }
+}
+
+#ifdef NONMATCHING
+void sub_8101460(u8 taskId)
+{
+ u8 i;
+ u8 xOff;
+ u8 yOff;
+ gUnknown_02039234 = 0;
+ if (sub_8101340(taskId) != TRUE)
+ {
+ for (i=0; i<ewram_1f000.size; i++)
+ {
+ if (ewram_1f000.items[i] == 0) // This is using the wrong register!
+ {
+ continue;
+ }
+ sub_8101118(ewram_1f000.items[i], gUnknown_020391B4);
+ if (sub_8101200(taskId, i, gUnknown_020391B4) == TRUE)
+ {
+ gUnknown_020391B4[0].decorId = i;
+ gUnknown_02039234++;
+ break;
+ }
+ }
+ if (gUnknown_02039234 != 0)
+ {
+ xOff = ewram_1f000.pos[gUnknown_020391B4[0].decorId] >> 4;
+ yOff = ewram_1f000.pos[gUnknown_020391B4[0].decorId] & 0xf;
+ sub_81013B8(xOff, yOff - gUnknown_020391B4[0].height + 1, xOff + gUnknown_020391B4[0].width - 1, yOff);
+ }
+ }
+}
+#else
+__attribute__((naked))
+void sub_8101460(u8 taskId)
+{
+ asm(".syntax unified\n"
+ "\tpush {r4-r7,lr}\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r6, r0, 24\n"
+ "\tldr r4, _081014B8 @ =gUnknown_02039234\n"
+ "\tmovs r0, 0\n"
+ "\tstrb r0, [r4]\n"
+ "\tadds r0, r6, 0\n"
+ "\tbl sub_8101340\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r0, 24\n"
+ "\tcmp r0, 0x1\n"
+ "\tbeq _08101504\n"
+ "\tmovs r5, 0\n"
+ "\tldr r0, _081014BC @ =ewram_1f000\n"
+ "\tldrb r1, [r0, 0x8]\n"
+ "\tcmp r5, r1\n"
+ "\tbcs _081014D2\n"
+ "\tadds r7, r4, 0\n"
+ "_08101486:\n"
+ "\tldr r0, [r0]\n"
+ "\tadds r0, r5\n"
+ "\tldrb r1, [r0] @ compiler incorrectly uses r0 for this and the next instruction\n"
+ "\tcmp r1, 0\n"
+ "\tbeq _081014C4\n"
+ "\tldr r4, _081014C0 @ =gUnknown_020391B4\n"
+ "\tadds r0, r1, 0\n"
+ "\tadds r1, r4, 0\n"
+ "\tbl sub_8101118\n"
+ "\tadds r0, r6, 0\n"
+ "\tadds r1, r5, 0\n"
+ "\tadds r2, r4, 0\n"
+ "\tbl sub_8101200\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r0, 24\n"
+ "\tcmp r0, 0x1\n"
+ "\tbne _081014C4\n"
+ "\tstrb r5, [r4]\n"
+ "\tldrb r0, [r7]\n"
+ "\tadds r0, 0x1\n"
+ "\tstrb r0, [r7]\n"
+ "\tb _081014D2\n"
+ "\t.align 2, 0\n"
+ "_081014B8: .4byte gUnknown_02039234\n"
+ "_081014BC: .4byte 0x201f000\n"
+ "_081014C0: .4byte gUnknown_020391B4\n"
+ "_081014C4:\n"
+ "\tadds r0, r5, 0x1\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r5, r0, 24\n"
+ "\tldr r0, _0810150C @ =ewram_1f000\n"
+ "\tldrb r1, [r0, 0x8]\n"
+ "\tcmp r5, r1\n"
+ "\tbcc _08101486\n"
+ "_081014D2:\n"
+ "\tldr r0, _08101510 @ =gUnknown_02039234\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _08101504\n"
+ "\tldr r0, _0810150C @ =ewram_1f000\n"
+ "\tldr r2, _08101514 @ =gUnknown_020391B4\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_81013B8\n"
+ "_08101504:\n"
+ "\tpop {r4-r7}\n"
+ "\tpop {r0}\n"
+ "\tbx r0\n"
+ "\t.align 2, 0\n"
+ "_0810150C: .4byte 0x201f000\n"
+ "_08101510: .4byte gUnknown_02039234\n"
+ "_08101514: .4byte gUnknown_020391B4\n"
+ ".syntax divided\n");
+}
+#endif
+
+void sub_8101518(u8 taskId)
+{
+ DisplayYesNoMenu(20, 8, 1);
+ DoYesNoFuncWithChoice(taskId, &gUnknown_083EC9CC);
+}
+
+void sub_810153C(u8 taskId)
+{
+ fade_screen(1, 0);
+ gTasks[taskId].data[2] = 0;
+ gTasks[taskId].func = sub_8100C88;
+}
+
+void sub_810156C(u8 taskId)
+{
+ DisplayYesNoMenu(20, 8, 1);
+ DoYesNoFuncWithChoice(taskId, &gUnknown_083EC9D4);
+}
+
+void sub_8101590(u8 taskId)
+{
+ MenuZeroFillWindowRect(0, 0, 29, 19);
+ sub_81015B0(taskId);
+}
+
+void sub_81015B0(u8 taskId)
+{
+ fade_screen(1, 0);
+ gTasks[taskId].data[2] = 0;
+ gTasks[taskId].func = sub_81015E0;
+}
+
+void sub_81015E0(u8 taskId)
+{
+ switch (gTasks[taskId].data[2])
+ {
+ case 0:
+ if (!gPaletteFade.active)
+ {
+ sub_80FF114(taskId);
+ gTasks[taskId].data[2] = 1;
+ }
+ break;
+ case 1:
+ sub_81016F4();
+ gFieldCallback = sub_8101678;
+ SetMainCallback2(c2_exit_to_overworld_2_switch);
+ DestroyTask(taskId);
+ break;
+ }
+}
+
+void sub_8101648(u8 taskId)
+{
+ if (sub_807D770() == TRUE)
+ {
+ gTasks[taskId].func = Task_DecorationPCProcessMenuInput;
+ }
+}
+
+void sub_8101678(void)
+{
+ pal_fill_black();
+ MenuDisplayMessageBox();
+ sub_80FE220();
+ CreateTask(sub_8101648, 8);
+}
+
+void sub_8101698(struct Sprite *sprite)
+{
+ sprite->data0 = (sprite->data0 + 1) & 0x1f;
+ if (sprite->data0 >= 16)
+ {
+ sprite->invisible = TRUE;
+ } else
+ {
+ sprite->invisible = FALSE;
+ }
+}
+
+void sub_81016C8(void)
+{
+ if (gSaveBlock2.playerGender == MALE)
+ {
+ LoadSpritePalette(&gUnknown_083ECA5C);
+ } else
+ {
+ LoadSpritePalette(&gUnknown_083ECA64);
+ }
+}
+
+void sub_81016F4(void)
+{
+ FreeSpritePaletteByTag(8);
+}
+
+void sub_8101700(u8 taskId)
+{
+ if (!sub_81341D4())
+ {
+ DisplayItemMessageOnField(taskId, gSecretBaseText_NoDecors, sub_80FE428, 0);
+ } else
+ {
+ gTasks[taskId].data[11] = 1;
+ gUnknown_020388F6 = 0;
+ sub_80FE5AC(taskId);
+ }
+}
+
+void sub_8101750(u8 taskId)
+{
+ if (!sub_81341D4())
+ {
+ DisplayItemMessageOnField(taskId, gSecretBaseText_NoDecors, sub_80FE428, 0);
+ } else
+ {
+ gTasks[taskId].data[11] = 2;
+ gUnknown_020388F6 = 0;
+ sub_80FE5AC(taskId);
+ }
+}
+
+void sub_81017A0(u8 taskId)
+{
+ sub_80FEF74();
+ sub_80FED1C();
+ if (sub_80FEFA4() == TRUE)
+ {
+ StringCopy(gStringVar1, gDecorations[gUnknown_020388D0[gUnknown_020388F5]].name);
+ StringExpandPlaceholders(gStringVar4, gSecretBaseText_WillBeDiscarded);
+ DisplayItemMessageOnField(taskId, gStringVar4, sub_8101824, 0);
+ } else
+ {
+ DisplayItemMessageOnField(taskId, gSecretBaseText_DecorInUse, sub_80FEFF4, 0);
+ }
+}
+
+void sub_8101824(u8 taskId)
+{
+ DisplayYesNoMenu(20, 8, 1);
+ DoYesNoFuncWithChoice(taskId, &gUnknown_083ECAA0);
+}
+
+void sub_8101848(u8 taskId)
+{
+ MenuZeroFillWindowRect(20, 8, 26, 14);
+ sub_8109A30(gUnknown_020388D0[gUnknown_020388F5]);
+ gUnknown_020388D0[gUnknown_020388F5] = DECOR_NONE;
+ sub_80FF098(taskId);
+ DisplayItemMessageOnField(taskId, gSecretBaseText_DecorThrownAway, sub_80FEFF4, 0);
+}
diff --git a/src/field/decoration_inventory.c b/src/field/decoration_inventory.c
new file mode 100644
index 000000000..083cb260c
--- /dev/null
+++ b/src/field/decoration_inventory.c
@@ -0,0 +1,169 @@
+//
+
+//
+
+#include "global.h"
+#include "sprite.h"
+#include "task.h"
+#include "decoration.h"
+#include "decoration_inventory.h"
+
+#define DECOR_INV(ptr) {.items = (u8 *)&ptr, .size = sizeof ptr}
+
+struct DecorationInventory const gDecorationInventories[] = {
+ DECOR_INV(gSaveBlock1.decorDesk),
+ DECOR_INV(gSaveBlock1.decorChair),
+ DECOR_INV(gSaveBlock1.decorPlant),
+ DECOR_INV(gSaveBlock1.decorOrnament),
+ DECOR_INV(gSaveBlock1.decorMat),
+ DECOR_INV(gSaveBlock1.decorPoster),
+ DECOR_INV(gSaveBlock1.decorDoll),
+ DECOR_INV(gSaveBlock1.decorCushion)
+};
+
+void ClearDecorationInventory(u8 invIdx)
+{
+ u8 i;
+ for (i=0; i<gDecorationInventories[invIdx].size; i++)
+ {
+ gDecorationInventories[invIdx].items[i] = DECOR_NONE;
+ }
+}
+
+void ClearDecorationInventories(void)
+{
+ u8 i;
+ for (i=0; i<8; i++)
+ {
+ ClearDecorationInventory(i);
+ }
+}
+
+s8 sub_8133F9C(u8 invIdx)
+{
+ s8 i;
+ for (i=0; i<(s8)gDecorationInventories[invIdx].size; i++)
+ {
+ if (gDecorationInventories[invIdx].items[i] == DECOR_NONE)
+ {
+ return i;
+ }
+ }
+ return -1;
+}
+
+bool8 sub_8133FE4(u8 decorIdx)
+{
+ u8 invIdx;
+ u8 i;
+ invIdx = gDecorations[decorIdx].category;
+ for (i=0; i<gDecorationInventories[invIdx].size; i++)
+ {
+ if (gDecorationInventories[invIdx].items[i] == decorIdx)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+bool8 IsThereStorageSpaceForDecoration(u8 decorIdx)
+{
+ u8 invIdx;
+ s8 invSlot;
+ if (decorIdx == DECOR_NONE)
+ {
+ return FALSE;
+ }
+ invIdx = gDecorations[decorIdx].category;
+ invSlot = sub_8133F9C(invIdx);
+ if (invSlot == -1)
+ {
+ return FALSE;
+ }
+ gDecorationInventories[invIdx].items[invSlot] = decorIdx;
+ return TRUE;
+}
+
+bool8 sub_8134074(u8 decorIdx)
+{
+ u8 invIdx;
+ if (decorIdx == DECOR_NONE)
+ {
+ return FALSE;
+ }
+ invIdx = gDecorations[decorIdx].category;
+ if (sub_8133F9C(invIdx) == -1)
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+s8 sub_81340A8(u8 decorIdx)
+{
+ u8 i;
+ u8 invIdx;
+ i = 0;
+ if (decorIdx == DECOR_NONE)
+ {
+ return FALSE;
+ }
+ for (i=0; i<gDecorationInventories[gDecorations[decorIdx].category].size; i++)
+ {
+ invIdx = gDecorations[decorIdx].category;
+ if (gDecorationInventories[invIdx].items[i] == decorIdx)
+ {
+ gDecorationInventories[invIdx].items[i] = DECOR_NONE;
+ sub_8134104(invIdx);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void sub_8134104(u8 invIdx)
+{
+ u8 i;
+ u8 j;
+ u8 tmp;
+ for (i=0; i<gDecorationInventories[invIdx].size; i++)
+ {
+ for (j=i+1; j<gDecorationInventories[invIdx].size; j++)
+ {
+ if (gDecorationInventories[invIdx].items[j] != 0 && (gDecorationInventories[invIdx].items[i] == DECOR_NONE || gDecorationInventories[invIdx].items[i] > gDecorationInventories[invIdx].items[j]))
+ {
+ tmp = gDecorationInventories[invIdx].items[i];
+ gDecorationInventories[invIdx].items[i] = gDecorationInventories[invIdx].items[j];
+ gDecorationInventories[invIdx].items[j] = tmp;
+ }
+ }
+ }
+}
+
+u8 sub_8134194(u8 invIdx)
+{
+ u8 i;
+ u8 count;
+ count = 0;
+ for (i=0; i<gDecorationInventories[invIdx].size; i++)
+ {
+ if (gDecorationInventories[invIdx].items[i] != 0)
+ {
+ count++;
+ }
+ }
+ return count;
+}
+
+u8 sub_81341D4(void)
+{
+ u8 i;
+ u8 count;
+ count = 0;
+ for (i=0; i<8; i++)
+ {
+ count += sub_8134194(i);
+ }
+ return count;
+}
diff --git a/src/field/dewford_trend.c b/src/field/dewford_trend.c
new file mode 100644
index 000000000..aaf4dd66a
--- /dev/null
+++ b/src/field/dewford_trend.c
@@ -0,0 +1,332 @@
+#include "global.h"
+#include "dewford_trend.h"
+#include "easy_chat.h"
+#include "event_data.h"
+#include "link.h"
+#include "rng.h"
+#include "text.h"
+
+extern u8 unk_2000000[];
+
+extern u16 gScriptResult;
+extern u16 gSpecialVar_0x8004;
+
+static void sub_80FA46C(struct EasyChatPair *s, u16 b, u8 c);
+static bool8 sub_80FA670(struct EasyChatPair *a, struct EasyChatPair *b, u8 c);
+static void sub_80FA740(struct EasyChatPair *s);
+static bool8 SB1ContainsWords(u16 *a);
+static bool8 IsEasyChatPairEqual(u16 *words1, u16 *words2);
+static s16 sub_80FA828(struct EasyChatPair *a, u16 b);
+
+void InitDewfordTrend(void)
+{
+ u16 i;
+
+ for (i = 0; i < 5; i++)
+ {
+ gSaveBlock1.easyChatPairs[i].words[0] = sub_80EB72C(EC_GROUP_CONDITIONS);
+
+ if (Random() & 1)
+ gSaveBlock1.easyChatPairs[i].words[1] = sub_80EB72C(EC_GROUP_LIFESTYLE);
+ else
+ gSaveBlock1.easyChatPairs[i].words[1] = sub_80EB72C(EC_GROUP_HOBBIES);
+
+ gSaveBlock1.easyChatPairs[i].unk1_6 = Random() & 1;
+ sub_80FA740(&gSaveBlock1.easyChatPairs[i]);
+ }
+ sub_80FA46C(gSaveBlock1.easyChatPairs, 5, 0);
+}
+
+void UpdateDewfordTrendPerDay(u16 a)
+{
+ u16 i;
+
+ if (a != 0)
+ {
+ u32 sp0 = a * 5;
+
+ for (i = 0; i < 5; i++)
+ {
+ //_080FA24A
+ u32 r4;
+ u32 r2 = sp0;
+ struct EasyChatPair *r5 = &gSaveBlock1.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;
+ }
+ //_080FA290
+ r2 -= r5->unk0_0;
+ r5->unk0_0 = 0;
+ r5->unk1_6 = 1;
+ }
+ //_080FA2A0
+ 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
+ //_080FA2FA
+ r5->unk0_0 = r5->unk0_7 - sp4;
+ }
+ else
+ {
+ //_080FA310
+ r5->unk0_0 = r4;
+
+ if (r5->unk0_0 == r5->unk0_7)
+ r5->unk1_6 = 0;
+ }
+ }
+ sub_80FA46C(gSaveBlock1.easyChatPairs, 5, 0);
+ }
+ //_080FA34E
+}
+
+bool8 sub_80FA364(u16 *a)
+{
+ struct EasyChatPair s = {0};
+ u16 i;
+
+ if (!SB1ContainsWords(a))
+ {
+ if (!FlagGet(SYS_POPWORD_INPUT))
+ {
+ FlagSet(SYS_POPWORD_INPUT);
+ if (!FlagGet(SYS_MIX_RECORD))
+ {
+ gSaveBlock1.easyChatPairs[0].words[0] = a[0];
+ gSaveBlock1.easyChatPairs[0].words[1] = a[1];
+ return 1;
+ }
+ }
+
+ //_080FA3C8
+ s.words[0] = a[0];
+ s.words[1] = a[1];
+ s.unk1_6 = 1;
+ sub_80FA740(&s);
+
+ for (i = 0; i < 5; i++)
+ {
+ if (sub_80FA670(&s, &gSaveBlock1.easyChatPairs[i], 0))
+ {
+ u16 r3 = 4;
+
+ while (r3 > i)
+ {
+ gSaveBlock1.easyChatPairs[r3] = gSaveBlock1.easyChatPairs[r3 - 1];
+ r3--;
+ }
+ gSaveBlock1.easyChatPairs[i] = s;
+ return (i == 0);
+ }
+ //_080FA450
+ }
+ gSaveBlock1.easyChatPairs[4] = s;
+ }
+ return 0;
+}
+
+static void sub_80FA46C(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_80FA670(&s[i], &s[h], c))
+ {
+ struct EasyChatPair temp;
+
+ temp = s[i];
+ s[i] = s[h];
+ s[h] = temp;
+ }
+ }
+ }
+}
+
+void sub_80FA4E4(void *a, u32 b, u8 unused)
+{
+ u16 i;
+ u16 j;
+ u16 r7;
+ struct EasyChatPair *src;
+ struct EasyChatPair *dst;
+ u16 players = GetLinkPlayerCount();
+
+ for (i = 0; i < players; i++)
+ memcpy(&ARRAY_2007800[i * 5], (u8 *)a + i * b, 40);
+ src = ARRAY_2007800;
+ dst = ARRAY_2007900;
+ r7 = 0;
+ for (i = 0; i < players; i++)
+ {
+ for (j = 0; j < 5; j++)
+ {
+ s16 foo = sub_80FA828(src, r7);
+ if (foo < 0)
+ {
+ *(dst++) = *src;
+ r7++;
+ }
+ else
+ {
+ if (ARRAY_2007900[foo].unk0_0 < src->unk0_0)
+ {
+ ARRAY_2007900[foo] = *src;
+ }
+ }
+ src++;
+ }
+ }
+ sub_80FA46C(ARRAY_2007900, r7, 2);
+ src = ARRAY_2007900;
+ dst = gSaveBlock1.easyChatPairs;
+ for (i = 0; i < 5; i++)
+ *(dst++) = *(src++);
+}
+
+void sub_80FA5BC(void)
+{
+ struct EasyChatPair *s = &gSaveBlock1.easyChatPairs[gSpecialVar_0x8004];
+
+ ConvertEasyChatWordsToString(gStringVar1, s->words, 2, 1);
+}
+
+void sub_80FA5E4(void)
+{
+ u16 result = 0;
+
+ if (gSaveBlock1.easyChatPairs[0].unk0_0 - gSaveBlock1.easyChatPairs[1].unk0_0 < 2)
+ {
+ asm("":::"r2"); //Force the compiler to store address of gSaveBlock1 in r3 instead of r2
+ if (!gSaveBlock1.easyChatPairs[0].unk1_6 && gSaveBlock1.easyChatPairs[1].unk1_6)
+ result = 1;
+ }
+ gScriptResult = result;
+}
+
+void sub_80FA648(void)
+{
+ gScriptResult = (gSaveBlock1.easyChatPairs[0].words[0] + gSaveBlock1.easyChatPairs[0].words[1]) & 7;
+}
+
+static bool8 sub_80FA670(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_80FA740(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, gSaveBlock1.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 sub_80FA828(struct EasyChatPair *a, u16 b)
+{
+ s16 i;
+ struct EasyChatPair *s = ARRAY_2007900;
+
+ for (i = 0; i < b; i++)
+ {
+ if (IsEasyChatPairEqual(a->words, s->words))
+ return i;
+ s++;
+ }
+ return -1;
+}
diff --git a/src/field/diploma.c b/src/field/diploma.c
new file mode 100644
index 000000000..27601404c
--- /dev/null
+++ b/src/field/diploma.c
@@ -0,0 +1,139 @@
+#include "global.h"
+#include "diploma.h"
+#include "main.h"
+#include "menu.h"
+#include "palette.h"
+#include "pokedex.h"
+#include "overworld.h"
+#include "sprite.h"
+#include "string_util.h"
+#include "strings2.h"
+#include "task.h"
+#include "text.h"
+#include "unknown_task.h"
+
+static void VBlankCB(void);
+static void MainCB2(void);
+static void Task_DiplomaFadeIn(u8);
+static void Task_DiplomaWaitForKeyPress(u8);
+static void Task_DiplomaFadeOut(u8);
+static void DisplayDiplomaText(void);
+
+static const u16 gDiplomaPalettes[][16] =
+{
+ INCBIN_U16("graphics/misc/diploma_national.gbapal"),
+ INCBIN_U16("graphics/misc/diploma_hoenn.gbapal"),
+};
+
+static const u8 gDiplomaTilemap[] = INCBIN_U8("graphics/misc/diploma_map.bin.lz");
+static const u8 gDiplomaTiles[] = INCBIN_U8("graphics/misc/diploma.4bpp.lz");
+
+static void VBlankCB(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+void CB2_ShowDiploma(void)
+{
+ u32 savedIme;
+
+ SetVBlankCallback(NULL);
+
+ REG_DISPCNT = 0;
+ REG_BG3CNT = 0;
+ REG_BG2CNT = 0;
+ REG_BG1CNT = 0;
+ REG_BG0CNT = 0;
+ REG_BG3HOFS = 0;
+ REG_BG3VOFS = 0;
+ REG_BG2HOFS = 0;
+ REG_BG2VOFS = 0;
+ REG_BG1HOFS = 0;
+ REG_BG1VOFS = 0;
+ REG_BG0HOFS = 0;
+ REG_BG0VOFS = 0;
+
+ DmaFill16(3, 0, VRAM, VRAM_SIZE);
+ DmaFill32(3, 0, OAM, OAM_SIZE);
+ DmaFill16(3, 0, PLTT, PLTT_SIZE);
+
+ LZ77UnCompVram(gDiplomaTiles, (void *)VRAM);
+ LZ77UnCompVram(gDiplomaTilemap, (void *)(VRAM + 0x3000));
+
+ remove_some_task();
+ ResetTasks();
+ ResetSpriteData();
+ ResetPaletteFade();
+ FreeAllSpritePalettes();
+ LoadPalette(gDiplomaPalettes, 0, 64);
+ SetUpWindowConfig(&gWindowConfig_81E6C3C);
+ InitMenuWindow(&gWindowConfig_81E6CE4);
+ DisplayDiplomaText();
+ BeginNormalPaletteFade(-1, 0, 0x10, 0, 0);
+
+ savedIme = REG_IME;
+ REG_IME = 0;
+ REG_IE |= INTR_FLAG_VBLANK;
+ REG_IME = savedIme;
+ REG_DISPSTAT |= DISPSTAT_VBLANK_INTR;
+
+ SetVBlankCallback(VBlankCB);
+ SetMainCallback2(MainCB2);
+
+ REG_BLDCNT = 0;
+ REG_BLDALPHA = 0;
+ REG_BLDY = 0;
+ REG_BG3CNT = BGCNT_PRIORITY(3) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(6) | BGCNT_16COLOR | BGCNT_TXT512x256;
+ REG_DISPCNT = DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON | DISPCNT_BG3_ON | DISPCNT_OBJ_ON;
+
+ CreateTask(Task_DiplomaFadeIn, 0);
+}
+
+static void MainCB2(void)
+{
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+}
+
+static void Task_DiplomaFadeIn(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ gTasks[taskId].func = Task_DiplomaWaitForKeyPress;
+}
+
+static void Task_DiplomaWaitForKeyPress(u8 taskId)
+{
+ if (gMain.newKeys & (A_BUTTON | B_BUTTON))
+ {
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ gTasks[taskId].func = Task_DiplomaFadeOut;
+ }
+}
+
+static void Task_DiplomaFadeOut(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ DestroyTask(taskId);
+ SetMainCallback2(sub_80546F0);
+ }
+}
+
+static void DisplayDiplomaText(void)
+{
+ if (sub_8090FF4())
+ {
+ REG_BG3HOFS = 256;
+ StringCopy(gStringVar1, gOtherText_NationalDex);
+ }
+ else
+ {
+ REG_BG3HOFS = 0;
+ StringCopy(gStringVar1, gOtherText_HoennDex);
+ }
+ MenuPrint(gOtherText_DiplomaCertificationGameFreak, 6, 2);
+} \ No newline at end of file
diff --git a/src/field/easy_chat.c b/src/field/easy_chat.c
new file mode 100644
index 000000000..6014b3d14
--- /dev/null
+++ b/src/field/easy_chat.c
@@ -0,0 +1,444 @@
+#include "global.h"
+#include "easy_chat.h"
+#include "data2.h"
+#include "event_data.h"
+#include "field_message_box.h"
+#include "pokedex.h"
+#include "rng.h"
+#include "string_util.h"
+#include "strings.h"
+#include "strings2.h"
+#include "text.h"
+
+static bool8 sub_80EB680(u16 *, u16, u16, u16);
+static u16 sub_80EB9D8(void);
+static u16 sub_80EB960(void);
+
+extern void *gEasyChatGroupWords[];
+extern const u8 gEasyChatGroupSizes[];
+
+extern u16 gSpecialVar_0x8004;
+
+IWRAM_DATA u8 gUnknown_03000740;
+
+// returns the end of the destination buffer text
+u8 *EasyChat_GetWordText(u8 *dst, u16 word)
+{
+ u16 group;
+ u16 wordIndex;
+ u8 *src;
+ u16 i;
+
+ if (sub_80EB37C(word))
+ return StringCopy(dst, gOtherText_ThreeQuestions);
+
+ if (word == 0xFFFF)
+ {
+ *dst = EOS;
+ return dst;
+ }
+ else
+ {
+ group = EC_GROUP(word);
+ wordIndex = EC_INDEX(word);
+ switch (group)
+ {
+ case EC_GROUP_POKEMON: // 0
+ case EC_GROUP_POKEMON_2: // 21
+ dst = StringCopy(dst, gSpeciesNames[wordIndex]);
+ break;
+ case EC_GROUP_MOVE_1: // 18
+ case EC_GROUP_MOVE_2: // 19
+ dst = StringCopy(dst, gMoveNames[wordIndex]);
+ break;
+ default:
+ src = gEasyChatGroupWords[group];
+ for (i = wordIndex - 1; i != 0xFFFF; i--)
+ {
+ while (*src++ != EOS)
+ ;
+ }
+ dst = StringCopy(dst, src);
+ break;
+ }
+ *dst = EOS;
+ return dst;
+ }
+}
+
+u8 *ConvertEasyChatWordsToString(u8 *dst, u16 *words, u16 arg2, u16 arg3)
+{
+ u16 i;
+ u16 n;
+
+ const u16 i1 = arg2 - 1;
+
+ for (i = 0; i < arg3; i++)
+ {
+ u16 word;
+
+ for (n = 0; n < i1; n++)
+ {
+ dst = EasyChat_GetWordText(dst, words[0]);
+
+ if (words[0] != 0xFFFF)
+ {
+ dst[0] = CHAR_SPACE;
+ dst++;
+ }
+
+ words++;
+ }
+
+ word = words[0];
+ words++;
+ dst = EasyChat_GetWordText(dst, word);
+
+ dst[0] = CHAR_NEWLINE;
+ dst++;
+ }
+
+ dst--;
+ dst[0] = EOS;
+
+ return dst;
+}
+
+u8 *sub_80EB544(u8 *dst, u16 *words, u16 arg2, u16 arg3)
+{
+ u16 i;
+ u16 n;
+
+ const u16 i1 = arg2 - 1;
+
+ for (i = 0; i < arg3; i++)
+ {
+ u16 word;
+
+ for (n = 0; n < i1; n++)
+ {
+ dst = EasyChat_GetWordText(dst, words[0]);
+
+ if (words[0] != 0xFFFF)
+ {
+ dst[0] = CHAR_SPACE;
+ dst++;
+ }
+
+ words++;
+ }
+
+ word = words[0];
+ words++;
+ dst = EasyChat_GetWordText(dst, word);
+
+ // Only difference with ConvertEasyChatWordsToString
+ dst[0] = (i == 0) ? CHAR_NEWLINE : CHAR_PROMPT_SCROLL;
+ dst++;
+ }
+
+ dst--;
+ dst[0] = EOS;
+
+ return dst;
+}
+
+
+u16 unref_sub_80EB5E0(u16 arg0)
+{
+ const u8 *chars;
+ u16 i;
+ u16 length;
+ int group, word;
+
+
+ if (arg0 == 0xFFFF)
+ return 0;
+
+ group = EC_GROUP(arg0);
+ word = EC_INDEX(arg0);
+ switch (group)
+ {
+ case EC_GROUP_POKEMON: // 0
+ case EC_GROUP_POKEMON_2: // 21
+ chars = (u8 *) gSpeciesNames[word];
+ break;
+ case EC_GROUP_MOVE_1: // 18
+ case EC_GROUP_MOVE_2: // 19
+ chars = gMoveNames[word];
+ break;
+ default:
+ chars = gEasyChatGroupWords[group];
+ for (i = word - 1; i != 0xFFFF; i--)
+ {
+ while (*chars++ != EOS)
+ ;
+ }
+ break;
+ }
+
+ length = 0;
+ while (*chars != EOS)
+ {
+ chars++;
+ length++;
+ }
+
+ return length;
+}
+
+static bool8 sub_80EB680(u16 *arg0, u16 arg1, u16 arg2, u16 arg3)
+{
+ return FALSE;
+}
+
+void unref_sub_80EB684(u8 arg0, u16 arg1)
+{
+ u16 *ptr;
+ u16 c;
+
+ // FIXME: find actual tv shows used
+ switch (arg0)
+ {
+ case 5:
+ c = 6;
+ ptr = (u16*)((void *)&gSaveBlock1.tvShows[arg1] + 0x04);
+ break;
+ case 7:
+ c = 2;
+ ptr = (u16*)((void *)&gSaveBlock1.tvShows[arg1] + 0x1C);
+ break;
+ case 8:
+ c = 1;
+ ptr = (u16*)((void *)&gSaveBlock1.tvShows[arg1] + 0x02);
+ break;
+ default:
+ return;
+ }
+
+ c -= 1;
+ while (c != 0xFFFF)
+ {
+ *ptr = -1;
+ ptr++;
+ c -= 1;
+ }
+}
+
+void sub_80EB6FC(u16 *arg0, u16 arg1)
+{
+ u16 i;
+
+ for (i = arg1 - 1; i != 0xFFFF; i--)
+ {
+ *arg0 = 0xFFFF;
+ arg0++;
+ }
+
+}
+
+u16 sub_80EB72C(u16 group)
+{
+ u16 local1 = Random() % gEasyChatGroupSizes[group];
+
+ if (group == EC_GROUP_POKEMON
+ || group == EC_GROUP_POKEMON_2
+ || group == EC_GROUP_MOVE_1
+ || group == EC_GROUP_MOVE_2)
+ {
+ local1 = ((u16 *) gEasyChatGroupWords[group])[local1];
+ }
+
+ return ((group & 0x7F) << 9) | (local1 & 0x1FF);
+}
+
+u16 sub_80EB784(u16 group)
+{
+ if (!sub_80EAD7C(group))
+ return -1;
+
+ if (group != EC_GROUP_POKEMON)
+ {
+ if (group == EC_GROUP_TRENDY_SAYING)
+ return sub_80EB960();
+ }
+ else
+ {
+ return sub_80EB9D8();
+ }
+
+ return sub_80EB72C(group);
+}
+
+void sub_80EB7C4(void)
+{
+ u16 *words;
+ u16 arg1, arg2;
+
+ switch (gSpecialVar_0x8004)
+ {
+ case 0:
+ words = gSaveBlock1.unk2B1C;
+ arg1 = 2;
+ arg2 = 2;
+ break;
+ case 1:
+ words = gSaveBlock1.unk2B28;
+ if (sub_80EB680(gSaveBlock1.unk2B28, 3, 2, 20))
+ {
+ arg1 = 2;
+ arg2 = 3;
+ }
+ else
+ {
+ arg1 = 3;
+ arg2 = 2;
+ }
+ break;
+ case 2:
+ words = gSaveBlock1.unk2B34;
+ arg1 = 3;
+ arg2 = 2;
+ break;
+ case 3:
+ words = gSaveBlock1.unk2B40;
+ arg1 = 3;
+ arg2 = 2;
+ break;
+ default:
+ return;
+ }
+
+ ConvertEasyChatWordsToString(gStringVar4, words, arg1, arg2);
+ ShowFieldAutoScrollMessage(gStringVar4);
+}
+
+void sub_80EB83C(void)
+{
+ u16 group, local2;
+
+ if (Random() & 1)
+ group = EC_GROUP_HOBBIES;
+ else
+ group = EC_GROUP_LIFESTYLE;
+
+ local2 = sub_80EB784(group);
+ EasyChat_GetWordText(gStringVar2, local2);
+}
+
+u8 sub_80EB868(u8 arg0)
+{
+ int offset;
+ int index;
+
+ index = arg0 / 8;
+ offset = arg0 % 8;
+ return (gSaveBlock1.unk2D8C[index] >> offset) & 1;
+}
+
+void sub_80EB890(u8 arg0)
+{
+ int offset;
+ int index;
+
+ if (arg0 < 33)
+ {
+ index = arg0 / 8;
+ offset = arg0 % 8;
+ gSaveBlock1.unk2D8C[index] |= 1 << offset;
+ }
+}
+
+u8 sub_80EB8C0(void)
+{
+ u8 i, count;
+
+ for (i = 0, count = 0; i < 33; i++)
+ {
+ if (sub_80EB868(i))
+ count++;
+ }
+ return count;
+}
+
+u16 sub_80EB8EC(void)
+{
+ u16 i;
+ u16 local1, local2;
+
+ local1 = sub_80EB8C0();
+ if (local1 == 33)
+ return -1;
+
+ local2 = Random() % (33 - local1);
+ for (i = 0; i < 33; i++)
+ {
+ if (sub_80EB868(i) == 0)
+ {
+ if (local2 == 0)
+ {
+ sub_80EB890(i);
+ return (i & 0x1FF) | 0x2800;
+ }
+ local2--;
+ }
+ }
+ return -1;
+}
+
+static u16 sub_80EB960(void)
+{
+ u16 i;
+ u16 local1;
+
+ local1 = sub_80EB8C0();
+ if (local1 == 0)
+ return -1;
+
+ local1 = Random() % local1;
+ for (i = 0; i < 33; i++)
+ {
+ if (sub_80EB868(i))
+ {
+ if (local1 == 0)
+ return (i & 0x1FF) | 0x2800;
+ local1--;
+ }
+ }
+
+ return -1;
+}
+
+u8 sub_80EB9C8(void)
+{
+ return IsNationalPokedexEnabled();
+}
+
+static u16 sub_80EB9D8(void)
+{
+ u16 *speciesList;
+ u16 local1;
+ u16 i;
+
+ local1 = sub_80EAE88(0);
+
+ if (local1 == 0)
+ return -1;
+
+ local1 = Random() % local1;
+ speciesList = (u16 *) gEasyChatGroupWords[EC_GROUP_POKEMON];
+ for (i = 0; i < gEasyChatGroupSizes[EC_GROUP_POKEMON]; i++)
+ {
+ const u16 dexNum = SpeciesToNationalPokedexNum(*speciesList);
+ const u8 local2 = GetSetPokedexFlag(dexNum, 0);
+
+ if (local2)
+ {
+ if (local1 == 0)
+ return *speciesList & 0x1FF;
+ local1--;
+ }
+ speciesList++;
+ }
+ return -1;
+}
diff --git a/src/field/event_data.c b/src/field/event_data.c
new file mode 100644
index 000000000..43d49c417
--- /dev/null
+++ b/src/field/event_data.c
@@ -0,0 +1,182 @@
+#include "global.h"
+#include "event_data.h"
+#include "pokedex.h"
+
+#define TEMP_FLAGS_SIZE 0x4
+#define TEMP_UPPER_FLAGS_SIZE 0x8
+#define TEMP_VARS_SIZE 0x20
+
+EWRAM_DATA u16 gSpecialVar_0x8000 = 0;
+EWRAM_DATA u16 gSpecialVar_0x8001 = 0;
+EWRAM_DATA u16 gSpecialVar_0x8002 = 0;
+EWRAM_DATA u16 gSpecialVar_0x8003 = 0;
+EWRAM_DATA u16 gSpecialVar_0x8004 = 0;
+EWRAM_DATA u16 gSpecialVar_0x8005 = 0;
+EWRAM_DATA u16 gSpecialVar_0x8006 = 0;
+EWRAM_DATA u16 gSpecialVar_0x8007 = 0;
+EWRAM_DATA u16 gSpecialVar_0x8008 = 0;
+EWRAM_DATA u16 gSpecialVar_0x8009 = 0;
+EWRAM_DATA u16 gSpecialVar_0x800A = 0;
+EWRAM_DATA u16 gSpecialVar_0x800B = 0;
+EWRAM_DATA u16 gScriptResult = 0;
+EWRAM_DATA u16 gScriptLastTalked = 0;
+EWRAM_DATA u16 gScriptFacing = 0;
+EWRAM_DATA u8 gUnknown_0202E8E2[16] = {0};
+
+extern u16 *gSpecialVars[];
+
+void InitEventData(void)
+{
+ memset(gSaveBlock1.flags, 0, sizeof(gSaveBlock1.flags));
+ memset(gSaveBlock1.vars, 0, sizeof(gSaveBlock1.vars));
+ memset(gUnknown_0202E8E2, 0, sizeof(gUnknown_0202E8E2));
+}
+
+void ClearTempFieldEventData(void)
+{
+ memset(gSaveBlock1.flags, 0, TEMP_FLAGS_SIZE);
+ memset(gSaveBlock1.vars, 0, TEMP_VARS_SIZE);
+ FlagClear(SYS_ENC_UP_ITEM);
+ FlagClear(SYS_ENC_DOWN_ITEM);
+ FlagClear(SYS_USE_STRENGTH);
+ FlagClear(SYS_CTRL_OBJ_DELETE);
+}
+
+// probably had different flag splits at one point.
+void ClearUpperFlags(void)
+{
+ memset(gSaveBlock1.flags + 0x118, 0, TEMP_UPPER_FLAGS_SIZE);
+}
+
+void DisableNationalPokedex(void)
+{
+ u16 *nationalDexVar = GetVarPointer(VAR_NATIONAL_DEX);
+ gSaveBlock2.pokedex.nationalMagic = 0;
+ *nationalDexVar = 0;
+ FlagClear(SYS_NATIONAL_DEX);
+}
+
+void EnableNationalPokedex(void)
+{
+ u16 *nationalDexVar = GetVarPointer(VAR_NATIONAL_DEX);
+ gSaveBlock2.pokedex.nationalMagic = 0xDA;
+ *nationalDexVar = 0x302;
+ FlagSet(SYS_NATIONAL_DEX);
+ gSaveBlock2.pokedex.unknown1 = 1;
+ gSaveBlock2.pokedex.order = 0;
+ sub_808C0A0();
+}
+
+bool32 IsNationalPokedexEnabled(void)
+{
+ if (gSaveBlock2.pokedex.nationalMagic == 0xDA && VarGet(VAR_NATIONAL_DEX) == 0x302 && FlagGet(SYS_NATIONAL_DEX))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void DisableMysteryGift(void)
+{
+ FlagClear(SYS_EXDATA_ENABLE);
+}
+
+void EnableMysteryGift(void)
+{
+ FlagSet(SYS_EXDATA_ENABLE);
+}
+
+bool32 IsMysteryGiftEnabled(void)
+{
+ return FlagGet(SYS_EXDATA_ENABLE);
+}
+
+void DisableResetRTC(void)
+{
+ VarSet(VAR_RESET_RTC_ENABLE, 0);
+ FlagClear(SYS_RESET_RTC_ENABLE);
+}
+
+void EnableResetRTC(void)
+{
+ VarSet(VAR_RESET_RTC_ENABLE, 0x920);
+ FlagSet(SYS_RESET_RTC_ENABLE);
+}
+
+bool32 CanResetRTC(void)
+{
+ if (FlagGet(SYS_RESET_RTC_ENABLE) && VarGet(VAR_RESET_RTC_ENABLE) == 0x920)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+u16 *GetVarPointer(u16 id)
+{
+ if (id < 0x4000)
+ return NULL;
+ if (id < 0x8000)
+ return &gSaveBlock1.vars[id - 0x4000];
+ return gSpecialVars[id - 0x8000];
+}
+
+u16 VarGet(u16 id)
+{
+ u16 *ptr = GetVarPointer(id);
+ if (!ptr)
+ return id;
+ return *ptr;
+}
+
+bool8 VarSet(u16 id, u16 value)
+{
+ u16 *ptr = GetVarPointer(id);
+ if (!ptr)
+ return FALSE;
+ *ptr = value;
+ return TRUE;
+}
+
+u8 VarGetFieldObjectGraphicsId(u8 id)
+{
+ return VarGet(0x4010 + id);
+}
+
+u8 *GetFlagPointer(u16 id)
+{
+ if (id == 0)
+ return 0;
+
+ if (id < 0x4000)
+ return &gSaveBlock1.flags[id / 8];
+
+ return &gUnknown_0202E8E2[(id - 0x4000) / 8];
+}
+
+u8 FlagSet(u16 id)
+{
+ u8 *ptr = GetFlagPointer(id);
+ if (ptr)
+ *ptr |= 1 << (id & 7);
+ return 0;
+}
+
+u8 FlagClear(u16 id)
+{
+ u8 *ptr = GetFlagPointer(id);
+ if (ptr)
+ *ptr &= ~(1 << (id & 7));
+ return 0;
+}
+
+bool8 FlagGet(u16 id)
+{
+ u8 *ptr = GetFlagPointer(id);
+
+ if (!ptr)
+ return FALSE;
+
+ if (!(((*ptr) >> (id & 7)) & 1))
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/src/field/field_camera.c b/src/field/field_camera.c
new file mode 100644
index 000000000..db51cf054
--- /dev/null
+++ b/src/field/field_camera.c
@@ -0,0 +1,495 @@
+#include "global.h"
+#include "field_camera.h"
+#include "berry.h"
+#include "field_player_avatar.h"
+#include "fieldmap.h"
+#include "rotating_gate.h"
+#include "sprite.h"
+#include "text.h"
+
+EWRAM_DATA u8 gUnknown_0202E854 = 0;
+
+struct UnknownStruct
+{
+ u8 unk0;
+ u8 unk1;
+ u8 unk2;
+ u8 unk3;
+ bool8 unk4;
+};
+
+static struct UnknownStruct gUnknown_03000590;
+static u16 gUnknown_03000598;
+static s16 gUnknown_0300059A;
+static u8 gUnknown_0300059C;
+static void (*gUnknown_030005A0)(void);
+
+struct CameraSomething gUnknown_03004880;
+u16 gUnknown_03004898;
+u16 gUnknown_0300489C;
+
+static void RedrawMapSliceNorth(struct UnknownStruct *a, struct MapData *mapData);
+static void RedrawMapSliceSouth(struct UnknownStruct *a, struct MapData *mapData);
+static void RedrawMapSliceEast(struct UnknownStruct *a, struct MapData *mapData);
+static void RedrawMapSliceWest(struct UnknownStruct *a, struct MapData *mapData);
+static s32 MapPosToBgTilemapOffset(struct UnknownStruct *a, s32 x, s32 y);
+
+static void DrawWholeMapViewInternal(int x, int y, struct MapData *mapData);
+static void DrawMetatileAt(struct MapData *mapData, u16, int, int);
+static void DrawMetatile(s32 a, u16 *b, u16 c);
+static void CameraPanningCB_PanAhead(void);
+
+static void move_tilemap_camera_to_upper_left_corner_(struct UnknownStruct *a)
+{
+ a->unk2 = 0;
+ a->unk3 = 0;
+ a->unk0 = 0;
+ a->unk1 = 0;
+ a->unk4 = TRUE;
+}
+
+static void tilemap_move_something(struct UnknownStruct *a, u32 b, u32 c)
+{
+ a->unk2 += b;
+ a->unk2 %= 32;
+ a->unk3 += c;
+ a->unk3 %= 32;
+}
+
+static void coords8_add(struct UnknownStruct *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_03000590);
+ CpuFill16(0, gBGTilemapBuffers[2], 0x800);
+ CpuFill16(0, gBGTilemapBuffers[1], 0x800);
+ CpuFill16(0x3014, gBGTilemapBuffers[3], 0x800);
+}
+
+void sub_8057A58(void)
+{
+ *gBGHOffsetRegs[1] = gUnknown_03000590.unk0 + gUnknown_03000598;
+ *gBGVOffsetRegs[1] = gUnknown_03000590.unk1 + gUnknown_0300059A + 8;
+ *gBGHOffsetRegs[2] = gUnknown_03000590.unk0 + gUnknown_03000598;
+ *gBGVOffsetRegs[2] = gUnknown_03000590.unk1 + gUnknown_0300059A + 8;
+ *gBGHOffsetRegs[3] = gUnknown_03000590.unk0 + gUnknown_03000598;
+ *gBGVOffsetRegs[3] = gUnknown_03000590.unk1 + gUnknown_0300059A + 8;
+
+ if (gUnknown_03000590.unk4)
+ {
+ DmaCopy16(3, gBGTilemapBuffers[1], (void *)(VRAM + 0xE800), 0x800);
+ DmaCopy16(3, gBGTilemapBuffers[2], (void *)(VRAM + 0xE000), 0x800);
+ DmaCopy16(3, gBGTilemapBuffers[3], (void *)(VRAM + 0xF000), 0x800);
+ gUnknown_03000590.unk4 = FALSE;
+ }
+}
+
+void sub_8057B14(u16 *a, u16 *b)
+{
+ *a = gUnknown_03000590.unk0 + gUnknown_03000598;
+ *b = gUnknown_03000590.unk1 + gUnknown_0300059A + 8;
+}
+
+void DrawWholeMapView(void)
+{
+ DrawWholeMapViewInternal(gSaveBlock1.pos.x, gSaveBlock1.pos.y, gMapHeader.mapData);
+ gUnknown_03000590.unk4 = TRUE;
+}
+
+static void DrawWholeMapViewInternal(int x, int y, struct MapData *mapData)
+{
+ u8 i;
+ u8 j;
+ u32 r6;
+ u8 temp;
+
+ for (i = 0; i < 32; i += 2)
+ {
+ temp = gUnknown_03000590.unk3 + i;
+ if (temp >= 32)
+ temp -= 32;
+ r6 = temp * 32;
+ for (j = 0; j < 32; j += 2)
+ {
+ temp = gUnknown_03000590.unk2 + j;
+ if (temp >= 32)
+ temp -= 32;
+ DrawMetatileAt(mapData, r6 + temp, x + j / 2, y + i / 2);
+ }
+ }
+}
+
+static void RedrawMapSlicesForCameraUpdate(struct UnknownStruct *a, int x, int y)
+{
+ 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 UnknownStruct *a, 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, gSaveBlock1.pos.x + i / 2, gSaveBlock1.pos.y + 14);
+ }
+}
+
+static void RedrawMapSliceSouth(struct UnknownStruct *a, 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, gSaveBlock1.pos.x + i / 2, gSaveBlock1.pos.y);
+ }
+}
+
+static void RedrawMapSliceEast(struct UnknownStruct *a, 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, gSaveBlock1.pos.x, gSaveBlock1.pos.y + i / 2);
+ }
+}
+
+static void RedrawMapSliceWest(struct UnknownStruct *a, 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, gSaveBlock1.pos.x + 14, gSaveBlock1.pos.y + i / 2);
+ }
+}
+
+void CurrentMapDrawMetatileAt(int a, int b)
+{
+ int offset = MapPosToBgTilemapOffset(&gUnknown_03000590, a, b);
+
+ if (offset >= 0)
+ {
+ DrawMetatileAt(gMapHeader.mapData, offset, a, b);
+ gUnknown_03000590.unk4 = TRUE;
+ }
+}
+
+void DrawDoorMetatileAt(int x, int y, u16 *arr)
+{
+ int offset = MapPosToBgTilemapOffset(&gUnknown_03000590, x, y);
+
+ if (offset >= 0)
+ {
+ DrawMetatile(1, arr, offset);
+ gUnknown_03000590.unk4 = TRUE;
+ }
+}
+
+static void DrawMetatileAt(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:
+ gBGTilemapBuffers[3][c] = b[0];
+ gBGTilemapBuffers[3][c + 1] = b[1];
+ gBGTilemapBuffers[3][c + 0x20] = b[2];
+ gBGTilemapBuffers[3][c + 0x21] = b[3];
+
+ gBGTilemapBuffers[2][c] = 0;
+ gBGTilemapBuffers[2][c + 1] = 0;
+ gBGTilemapBuffers[2][c + 0x20] = 0;
+ gBGTilemapBuffers[2][c + 0x21] = 0;
+
+ gBGTilemapBuffers[1][c] = b[4];
+ gBGTilemapBuffers[1][c + 1] = b[5];
+ gBGTilemapBuffers[1][c + 0x20] = b[6];
+ gBGTilemapBuffers[1][c + 0x21] = b[7];
+ break;
+ case 1:
+ gBGTilemapBuffers[3][c] = b[0];
+ gBGTilemapBuffers[3][c + 1] = b[1];
+ gBGTilemapBuffers[3][c + 0x20] = b[2];
+ gBGTilemapBuffers[3][c + 0x21] = b[3];
+
+ gBGTilemapBuffers[2][c] = b[4];
+ gBGTilemapBuffers[2][c + 1] = b[5];
+ gBGTilemapBuffers[2][c + 0x20] = b[6];
+ gBGTilemapBuffers[2][c + 0x21] = b[7];
+
+ gBGTilemapBuffers[1][c] = 0;
+ gBGTilemapBuffers[1][c + 1] = 0;
+ gBGTilemapBuffers[1][c + 0x20] = 0;
+ gBGTilemapBuffers[1][c + 0x21] = 0;
+ break;
+ case 0:
+ gBGTilemapBuffers[3][c] = 0x3014;
+ gBGTilemapBuffers[3][c + 1] = 0x3014;
+ gBGTilemapBuffers[3][c + 0x20] = 0x3014;
+ gBGTilemapBuffers[3][c + 0x21] = 0x3014;
+
+ gBGTilemapBuffers[2][c] = b[0];
+ gBGTilemapBuffers[2][c + 1] = b[1];
+ gBGTilemapBuffers[2][c + 0x20] = b[2];
+ gBGTilemapBuffers[2][c + 0x21] = b[3];
+
+ gBGTilemapBuffers[1][c] = b[4];
+ gBGTilemapBuffers[1][c + 1] = b[5];
+ gBGTilemapBuffers[1][c + 0x20] = b[6];
+ gBGTilemapBuffers[1][c + 0x21] = b[7];
+ break;
+ }
+}
+
+static s32 MapPosToBgTilemapOffset(struct UnknownStruct *a, s32 x, s32 y)
+{
+ x -= gSaveBlock1.pos.x;
+ x *= 2;
+ if (x >= 32 || x < 0)
+ return -1;
+ x = x + a->unk2;
+ if (x >= 32)
+ x -= 32;
+
+ y = (y - gSaveBlock1.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 CameraSomething *a)
+{
+ if (a->unk4 != 0)
+ {
+ a->unk8 = gSprites[a->unk4].data2;
+ a->unkC = gSprites[a->unk4].data3;
+ }
+}
+
+void ResetCameraUpdateInfo(void)
+{
+ gUnknown_03004880.unk8 = 0;
+ gUnknown_03004880.unkC = 0;
+ gUnknown_03004880.unk10 = 0;
+ gUnknown_03004880.unk14 = 0;
+ gUnknown_03004880.unk4 = 0;
+ gUnknown_03004880.callback = NULL;
+}
+
+u32 InitCameraUpdateCallback(u8 a)
+{
+ if (gUnknown_03004880.unk4 != 0)
+ DestroySprite(&gSprites[gUnknown_03004880.unk4]);
+ gUnknown_03004880.unk4 = AddCameraObject(a);
+ gUnknown_03004880.callback = CameraUpdateCallback;
+ return 0;
+}
+
+void CameraUpdate(void)
+{
+ int deltaX;
+ int deltaY;
+ int r0;
+ int r1;
+ int r7;
+ int r8;
+
+ if (gUnknown_03004880.callback != NULL)
+ gUnknown_03004880.callback(&gUnknown_03004880);
+ r7 = gUnknown_03004880.unk8;
+ r8 = gUnknown_03004880.unkC;
+ deltaX = 0;
+ deltaY = 0;
+ r1 = gUnknown_03004880.unk10;
+ r0 = gUnknown_03004880.unk14;
+
+
+ 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_03004880.unk10 += r7;
+ gUnknown_03004880.unk10 = gUnknown_03004880.unk10 - 16 * (gUnknown_03004880.unk10 / 16);
+ gUnknown_03004880.unk14 += r8;
+ gUnknown_03004880.unk14 = gUnknown_03004880.unk14 - 16 * (gUnknown_03004880.unk14 / 16);
+
+ if (deltaX != 0 || deltaY != 0)
+ {
+ CameraMove(deltaX, deltaY);
+ UpdateFieldObjectsForCameraUpdate(deltaX, deltaY);
+ RotatingGatePuzzleCameraUpdate(deltaX, deltaY);
+ ResetBerryTreeSparkleFlags();
+ tilemap_move_something(&gUnknown_03000590, deltaX * 2, deltaY * 2);
+ RedrawMapSlicesForCameraUpdate(&gUnknown_03000590, deltaX * 2, deltaY * 2);
+ }
+
+ coords8_add(&gUnknown_03000590, r7, r8);
+ gUnknown_0300489C -= r7;
+ gUnknown_03004898 -= r8;
+}
+
+void camera_move_and_redraw(int a, int b)
+{
+ CameraMove(a, b);
+ UpdateFieldObjectsForCameraUpdate(a, b);
+ DrawWholeMapView();
+ gUnknown_0300489C -= a * 16;
+ gUnknown_03004898 -= b * 16;
+}
+
+void SetCameraPanningCallback(void (*a)(void))
+{
+ gUnknown_030005A0 = a;
+}
+
+void SetCameraPanning(s16 a, s16 b)
+{
+ gUnknown_03000598 = a;
+ gUnknown_0300059A = b + 32;
+}
+
+void InstallCameraPanAheadCallback(void)
+{
+ gUnknown_030005A0 = CameraPanningCB_PanAhead;
+ gUnknown_0300059C = 0;
+ gUnknown_03000598 = 0;
+ gUnknown_0300059A = 32;
+}
+
+void UpdateCameraPanning(void)
+{
+ if (gUnknown_030005A0 != NULL)
+ gUnknown_030005A0();
+ //Update sprite offset of overworld objects
+ gSpriteCoordOffsetX = gUnknown_0300489C - gUnknown_03000598;
+ gSpriteCoordOffsetY = gUnknown_03004898 - gUnknown_0300059A - 8;
+}
+
+static void CameraPanningCB_PanAhead(void)
+{
+ u8 var;
+
+ if (gUnknown_0202E854 == 0)
+ {
+ InstallCameraPanAheadCallback();
+ }
+ else
+ {
+ if (gPlayerAvatar.running1 == 1)
+ {
+ gUnknown_0300059C ^= 1;
+ if (gUnknown_0300059C == 0)
+ return;
+ }
+ else
+ {
+ gUnknown_0300059C = 0;
+ }
+
+ var = player_get_direction_upper_nybble();
+ if (var == 2)
+ {
+ if (gUnknown_0300059A > -8)
+ gUnknown_0300059A -= 2;
+ }
+ else if (var == 1)
+ {
+ if (gUnknown_0300059A < 72)
+ gUnknown_0300059A += 2;
+ }
+ else if (gUnknown_0300059A < 32)
+ {
+ gUnknown_0300059A += 2;
+ }
+ else if (gUnknown_0300059A > 32)
+ {
+ gUnknown_0300059A -= 2;
+ }
+ }
+}
diff --git a/src/field/field_control_avatar.c b/src/field/field_control_avatar.c
new file mode 100644
index 000000000..ff8e8504c
--- /dev/null
+++ b/src/field/field_control_avatar.c
@@ -0,0 +1,878 @@
+#include "global.h"
+#include "field_control_avatar.h"
+#include "battle_setup.h"
+#include "bike.h"
+#include "coord_event_weather.h"
+#include "daycare.h"
+#include "event_data.h"
+#include "field_fadetransition.h"
+#include "field_player_avatar.h"
+#include "field_poison.h"
+#include "field_specials.h"
+#include "fieldmap.h"
+#include "flags.h"
+#include "item_menu.h"
+#include "metatile_behavior.h"
+#include "overworld.h"
+#include "safari_zone.h"
+#include "script.h"
+#include "secret_base.h"
+#include "songs.h"
+#include "sound.h"
+#include "start_menu.h"
+#include "trainer_see.h"
+#include "vars.h"
+#include "wild_encounter.h"
+
+struct Coords32
+{
+ s32 x;
+ s32 y;
+};
+
+extern u16 gScriptLastTalked;
+extern u16 gScriptFacing;
+extern struct LinkPlayerMapObject gLinkPlayerMapObjects[];
+extern u16 gSpecialVar_0x8004;
+extern u16 gSpecialVar_0x8005;
+
+static EWRAM_DATA u8 gUnknown_0202E8C0 = 0;
+static EWRAM_DATA u16 gUnknown_0202E8C2 = 0;
+
+u8 gSelectedMapObject;
+
+//scripts
+extern u8 gUnknown_081A2C51[];
+extern u8 gUnknown_0815281E[];
+extern u8 gUnknown_08152C39[];
+extern u8 gUnknown_0815F36C[];
+extern u8 gUnknown_0815F43A[];
+extern u8 gUnknown_081A0009[];
+extern u8 gUnknown_081C6C02[];
+extern u8 HiddenItemScript[];
+extern u8 Event_TV[];
+extern u8 gUnknown_081A0009[];
+extern u8 ClosedSootopolisGymDoorScript[];
+extern u8 gUnknown_081A4363[];
+extern u8 gUnknown_081C346A[];
+extern u8 gUnknown_081616E1[];
+extern u8 Event_WorldMap[];
+extern u8 S_RunningShoesManual[];
+extern u8 PictureBookShelfScript[];
+extern u8 BookshelfScript[];
+extern u8 PokemonCenterBookshelfScript[];
+extern u8 VaseScript[];
+extern u8 TrashCanScript[];
+extern u8 ShopShelfScript[];
+extern u8 BlueprintScript[];
+extern u8 gUnknown_0815F36C[];
+extern u8 gUnknown_0815F43A[];
+extern u8 gUnknown_0815F523[];
+extern u8 gUnknown_0815F528[];
+extern u8 UseSurfScript[];
+extern u8 S_UseWaterfall[];
+extern u8 S_CannotUseWaterfall[];
+extern u8 UseDiveScript[];
+extern u8 S_UseDiveUnderwater[];
+extern u8 S_FallDownHole[];
+extern u8 gUnknown_081A14B8[];
+extern u8 S_EggHatch[];
+extern u8 gUnknown_0815FD0D[];
+extern u8 gUnknown_081C6BDE[];
+
+static void player_get_pos_to_and_height(struct MapPosition *);
+static void player_get_next_pos_and_height(struct MapPosition *);
+static u16 cur_mapdata_block_role_at_player_pos(int);
+static bool8 sub_80681F0(struct MapPosition *position, u16 b, u8 c);
+static u8 *TryGetScriptOnPressingA(struct MapPosition *position, u8 b, u8 c);
+static u8 *sub_8068364(struct MapPosition *, u8, u8);
+static u8 *TryGetInvisibleMapObjectScript(struct MapPosition *, u8, u8 c);
+static u8 *sub_8068500(struct MapPosition *, u8, u8);
+static u8 *TryGetFieldMoveScript(struct MapPosition *, u8, u8);
+static bool32 sub_8068770(void);
+static bool32 sub_80687A4(void);
+static bool8 sub_80687E4(struct MapPosition *, u16, u16);
+static void happiness_algorithm_step(void);
+static bool8 overworld_poison_step(void);
+static bool8 is_it_battle_time_3(u16);
+static bool8 mapheader_run_first_tag2_script_list_match_conditionally(struct MapPosition *, u16, u8);
+static bool8 sub_8068B30(u16);
+static bool8 is_non_stair_warp_tile(u16, u8);
+static s8 map_warp_check_packed(struct MapHeader *, struct MapPosition *);
+static void sub_8068C30(struct MapHeader *, s8, struct MapPosition *);
+static bool8 map_warp_consider_2_to_inside(struct MapPosition *, u16, u8);
+static s8 map_warp_check(struct MapHeader *, u16, u16, u8);
+static u8 *mapheader_trigger_activate_at(struct MapHeader *, u16, u16, u8);
+static struct BgEvent *FindInvisibleMapObjectByPosition(struct MapHeader *, u16, u16, u8);
+
+void FieldClearPlayerInput(struct FieldInput *input)
+{
+ input->pressedAButton = 0;
+ input->input_field_0_1 = 0;
+ input->pressedStartButton = 0;
+ input->pressedSelectButton = 0;
+ input->input_field_0_4 = 0;
+ input->input_field_0_5 = 0;
+ input->input_field_0_6 = 0;
+ input->pressedBButton = 0;
+ input->input_field_1_0 = 0;
+ input->input_field_1_1 = 0;
+ input->input_field_1_2 = 0;
+ input->input_field_1_3 = 0;
+ input->dpadDirection = 0;
+}
+
+void FieldGetPlayerInput(struct FieldInput *input, u16 newKeys, u16 heldKeys)
+{
+ u8 r6 = gPlayerAvatar.running1;
+ u8 r9 = gPlayerAvatar.running2;
+ bool8 forcedMove = MetatileBehavior_IsMoveTile(cur_mapdata_block_role_at_player_pos(r9));
+
+ if ((r6 == 2 && forcedMove == FALSE) || r6 == 0)
+ {
+ if (GetPlayerSpeed() != 4)
+ {
+ if (newKeys & START_BUTTON)
+ input->pressedStartButton = TRUE;
+ if (newKeys & SELECT_BUTTON)
+ input->pressedSelectButton = TRUE;
+ if (newKeys & A_BUTTON)
+ input->pressedAButton = TRUE;
+ if (newKeys & B_BUTTON)
+ input->pressedBButton = TRUE;
+ }
+ if (heldKeys & (DPAD_UP | DPAD_DOWN | DPAD_LEFT | DPAD_RIGHT))
+ {
+ input->input_field_0_4 = TRUE;
+ input->input_field_0_5 = TRUE;
+ }
+ }
+ if (forcedMove == FALSE)
+ {
+ if (r6 == 2 && r9 == 2)
+ input->input_field_0_6 = TRUE;
+ if (forcedMove == FALSE && r6 == 2)
+ input->input_field_0_1 = TRUE;
+ }
+ if (heldKeys & DPAD_UP)
+ input->dpadDirection = DIR_NORTH;
+ else if (heldKeys & DPAD_DOWN)
+ input->dpadDirection = DIR_SOUTH;
+ else if (heldKeys & DPAD_LEFT)
+ input->dpadDirection = DIR_WEST;
+ else if (heldKeys & DPAD_RIGHT)
+ input->dpadDirection = DIR_EAST;
+}
+
+int sub_8068024(struct FieldInput *input)
+{
+ struct MapPosition position;
+ u8 r6;
+ u16 r4;
+
+ r6 = player_get_direction_lower_nybble();
+ player_get_pos_to_and_height(&position);
+ r4 = MapGridGetMetatileBehaviorAt(position.x, position.y);
+ if (CheckTrainers() == TRUE)
+ return TRUE;
+ if (mapheader_run_first_tag2_script_list_match() == 1)
+ return TRUE;
+ if (input->pressedBButton && sub_80687A4() == 1)
+ return TRUE;
+ if (input->input_field_0_6)
+ {
+ IncrementGameStat(5);
+ if (sub_80687E4(&position, r4, r6) == 1)
+ return TRUE;
+ }
+ if (input->input_field_0_1 && is_it_battle_time_3(r4) == 1)
+ return TRUE;
+ if (input->input_field_0_4 && input->dpadDirection == r6)
+ {
+ if (mapheader_run_first_tag2_script_list_match_conditionally(&position, r4, r6) == 1)
+ return TRUE;
+ }
+ player_get_next_pos_and_height(&position);
+ r4 = MapGridGetMetatileBehaviorAt(position.x, position.y);
+ if (input->pressedAButton && sub_80681F0(&position, r4, r6) == 1)
+ return TRUE;
+ if (input->input_field_0_5 && input->dpadDirection == r6)
+ {
+ if (map_warp_consider_2_to_inside(&position, r4, r6) == 1)
+ return TRUE;
+ }
+ if (input->pressedAButton && sub_8068770() == 1)
+ return TRUE;
+ if (input->pressedStartButton)
+ {
+ PlaySE(SE_WIN_OPEN);
+ sub_8071310();
+ return TRUE;
+ }
+ if (input->pressedSelectButton && sub_80A6D1C() == TRUE)
+ return TRUE;
+ return FALSE;
+}
+
+static void player_get_pos_to_and_height(struct MapPosition *position)
+{
+ PlayerGetDestCoords(&position->x, &position->y);
+ position->height = PlayerGetZCoord();
+}
+
+static void player_get_next_pos_and_height(struct MapPosition *position)
+{
+ s16 x, y;
+
+ GetXYCoordsOneStepInFrontOfPlayer(&position->x, &position->y);
+ PlayerGetDestCoords(&x, &y);
+ if (MapGridGetZCoordAt(x, y) != 0)
+ position->height = PlayerGetZCoord();
+ else
+ position->height = 0;
+}
+
+static u16 cur_mapdata_block_role_at_player_pos(int unused)
+{
+ s16 x, y;
+
+ PlayerGetDestCoords(&x, &y);
+ return MapGridGetMetatileBehaviorAt(x, y);
+}
+
+static bool8 sub_80681F0(struct MapPosition *position, u16 b, u8 c)
+{
+ u8 *script = TryGetScriptOnPressingA(position, b, c);
+
+ if (script == NULL)
+ return FALSE;
+
+ if (script != gUnknown_0815281E
+ && script != gUnknown_08152C39
+ && script != gUnknown_0815F36C
+ && script != gUnknown_0815F43A
+ && script != gUnknown_081A0009)
+ PlaySE(5);
+
+ ScriptContext1_SetupScript(script);
+ return TRUE;
+}
+
+static u8 *TryGetScriptOnPressingA(struct MapPosition *position, u8 b, u8 c)
+{
+ u8 *script;
+
+ script = sub_8068364(position, b, c);
+ if (script != NULL)
+ return script;
+ script = TryGetInvisibleMapObjectScript(position, b, c);
+ if (script != NULL)
+ return script;
+ script = sub_8068500(position, b, c);
+ if (script != NULL)
+ return script;
+ script = TryGetFieldMoveScript(position, b, c);
+ if (script != NULL)
+ return script;
+
+ return NULL;
+}
+
+u8 *sub_80682A8(struct MapPosition *position, u8 unused, u8 c)
+{
+ u8 r3;
+ s32 i;
+
+ if (!MetatileBehavior_IsCounter(MapGridGetMetatileBehaviorAt(position->x, position->y)))
+ r3 = GetFieldObjectIdByXYZ(position->x, position->y, position->height);
+ else
+ r3 = GetFieldObjectIdByXYZ(position->x + gUnknown_0821664C[c].x, position->y + gUnknown_0821664C[c].y, position->height);
+ if (r3 == 16 || gMapObjects[r3].localId == 0xFF)
+ return NULL;
+ for (i = 0; i < 4; i++)
+ {
+ if (gLinkPlayerMapObjects[i].active == TRUE && gLinkPlayerMapObjects[i].mapObjId == r3)
+ return NULL;
+ }
+ gSelectedMapObject = r3;
+ gScriptLastTalked = gMapObjects[r3].localId;
+ gScriptFacing = c;
+ return GetFieldObjectScriptPointerByFieldObjectId(r3);
+}
+
+static u8 *sub_8068364(struct MapPosition *position, u8 b, u8 c)
+{
+ u8 r3;
+ u8 *script;
+
+ r3 = GetFieldObjectIdByXYZ(position->x, position->y, position->height);
+ if (r3 == 16 || gMapObjects[r3].localId == 0xFF)
+ {
+ if (MetatileBehavior_IsCounter(b) != TRUE)
+ return NULL;
+ r3 = GetFieldObjectIdByXYZ(position->x + gUnknown_0821664C[c].x, position->y + gUnknown_0821664C[c].y, position->height);
+ if (r3 == 16 || gMapObjects[r3].localId == 0xFF)
+ return NULL;
+ }
+ //_080683E8
+ gSelectedMapObject = r3;
+ gScriptLastTalked = gMapObjects[r3].localId;
+ gScriptFacing = c;
+ script = GetFieldObjectScriptPointerByFieldObjectId(r3);
+ script = GetRamScript(gScriptLastTalked, script);
+ return script;
+}
+
+static u8 *TryGetInvisibleMapObjectScript(struct MapPosition *position, u8 unused, u8 c)
+{
+ struct BgEvent *bgEvent = FindInvisibleMapObjectByPosition(&gMapHeader, position->x - 7, position->y - 7, position->height);
+
+ if (bgEvent == NULL)
+ return NULL;
+ if (bgEvent->bgUnion.script == NULL)
+ return gUnknown_081C6C02;
+ switch (bgEvent->kind)
+ {
+ case 0:
+ default:
+ return bgEvent->bgUnion.script;
+ case 1:
+ if (c != 2)
+ return NULL;
+ break;
+ case 2:
+ if (c != 1)
+ return NULL;
+ break;
+ case 3:
+ if (c != 4)
+ return NULL;
+ break;
+ case 4:
+ if (c != 3)
+ return NULL;
+ break;
+ case 5:
+ case 6:
+ case 7:
+ gSpecialVar_0x8004 = ((u32)bgEvent->bgUnion.script >> 16) + 0x258;
+ gSpecialVar_0x8005 = (u32)bgEvent->bgUnion.script;
+ if (FlagGet(gSpecialVar_0x8004) == TRUE)
+ return NULL;
+ return HiddenItemScript;
+ case 8:
+ if (c == 2)
+ {
+ gSpecialVar_0x8004 = (u32)bgEvent->bgUnion.script;
+ if (sub_80BC050())
+ return gUnknown_081A2C51;
+ }
+ return NULL;
+ }
+ return bgEvent->bgUnion.script;
+}
+
+static u8 *sub_8068500(struct MapPosition *position, u8 b, u8 c)
+{
+ s8 height;
+
+ if (MetatileBehavior_IsPlayerFacingTVScreen(b, c) == TRUE)
+ return Event_TV;
+ if (MetatileBehavior_IsPC(b) == TRUE)
+ return gUnknown_081A0009;
+ if (MetatileBehavior_IsClosedSootopolisGymDoor(b) == TRUE)
+ return ClosedSootopolisGymDoorScript;
+ if (is_tile_x84(b) == TRUE)
+ return gUnknown_081A4363;
+ if (MetatileBehavior_IsPokeblockFeeder(b) == TRUE)
+ return gUnknown_081C346A;
+ if (MetatileBehavior_IsTrickHousePuzzleDoor(b) == TRUE)
+ return gUnknown_081616E1;
+ if (MetatileBehavior_IsRegionMap(b) == TRUE)
+ return Event_WorldMap;
+ if (sub_805791C(b) == TRUE)
+ return S_RunningShoesManual;
+ if (MetatileBehavior_IsPictureBookShelf(b) == TRUE)
+ return PictureBookShelfScript;
+ if (MetatileBehavior_IsBookShelf(b) == TRUE)
+ return BookshelfScript;
+ if (MetatileBehavior_IsPokeCenterBookShelf(b) == TRUE)
+ return PokemonCenterBookshelfScript;
+ if (MetatileBehavior_IsVase(b) == TRUE)
+ return VaseScript;
+ if (MetatileBehavior_IsTrashCan(b) == TRUE)
+ return TrashCanScript;
+ if (MetatileBehavior_IsShopShelf(b) == TRUE)
+ return ShopShelfScript;
+ if (MetatileBehavior_IsBlueprint(b) == TRUE)
+ return BlueprintScript;
+ height = position->height;
+ if (height == MapGridGetZCoordAt(position->x, position->y))
+ {
+ if (MetatileBehavior_IsSecretBasePC(b) == TRUE)
+ return gUnknown_0815F36C;
+ if (sub_805724C(b) == TRUE)
+ return gUnknown_0815F43A;
+ if (sub_8057364(b) == TRUE)
+ return gUnknown_0815F523;
+ if (sub_8057378(b) == TRUE)
+ return gUnknown_0815F528;
+ }
+ return NULL;
+}
+
+static u8 *TryGetFieldMoveScript(struct MapPosition *unused1, u8 b, u8 unused2)
+{
+ if (FlagGet(BADGE05_GET) == TRUE && PartyHasMonWithSurf() == TRUE && IsPlayerFacingSurfableFishableWater() == TRUE)
+ return UseSurfScript;
+ if (MetatileBehavior_IsWaterfall(b) == TRUE)
+ {
+ if (FlagGet(BADGE08_GET) == TRUE && IsPlayerSurfingNorth() == TRUE)
+ return S_UseWaterfall;
+ else
+ return S_CannotUseWaterfall;
+ }
+ return NULL;
+}
+
+static bool32 sub_8068770(void)
+{
+ if (FlagGet(BADGE07_GET) && sub_8068F18() == 2)
+ {
+ ScriptContext1_SetupScript(UseDiveScript);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool32 sub_80687A4(void)
+{
+ if (FlagGet(BADGE07_GET) && gMapHeader.mapType == MAP_TYPE_UNDERWATER && sub_8068F18() == 1)
+ {
+ ScriptContext1_SetupScript(S_UseDiveUnderwater);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool8 sub_80687E4(struct MapPosition *position, u16 b, u16 unused)
+{
+ if (mapheader_trigger_activate_at__run_now(position) == TRUE)
+ return TRUE;
+ if (sub_8068A64(position, b) == TRUE)
+ return TRUE;
+ if (sub_8068870(b) == TRUE)
+ return TRUE;
+ if (sub_8068894() == TRUE)
+ return TRUE;
+ if (UpdateRepelCounter() == TRUE)
+ return TRUE;
+ return FALSE;
+}
+
+bool8 mapheader_trigger_activate_at__run_now(struct MapPosition *position)
+{
+ u8 *script = mapheader_trigger_activate_at(&gMapHeader, position->x - 7, position->y - 7, position->height);
+
+ if (script == NULL)
+ return FALSE;
+ ScriptContext1_SetupScript(script);
+ return TRUE;
+}
+
+//can be u8, u16, or u32
+bool8 sub_8068870(u16 a)
+{
+ if (MetatileBehavior_IsCrackedFloorHole(a))
+ {
+ ScriptContext1_SetupScript(S_FallDownHole);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8068894(void)
+{
+ sub_8082B78();
+ happiness_algorithm_step();
+ if (overworld_poison_step() == TRUE)
+ {
+ ScriptContext1_SetupScript(gUnknown_081A14B8);
+ return TRUE;
+ }
+ if (sub_80422A0())
+ {
+ IncrementGameStat(13);
+ ScriptContext1_SetupScript(S_EggHatch);
+ return TRUE;
+ }
+ if (SafariZoneTakeStep() == TRUE)
+ return TRUE;
+ if (CountSSTidalStep(1) == TRUE)
+ {
+ ScriptContext1_SetupScript(gUnknown_0815FD0D);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void unref_sub_80688F8(void)
+{
+ VarSet(VAR_HAPPINESS_STEP_COUNTER, 0);
+}
+
+static void happiness_algorithm_step(void)
+{
+ u16 *ptr = GetVarPointer(VAR_HAPPINESS_STEP_COUNTER);
+ int i;
+
+ (*ptr)++;
+ (*ptr) %= 128;
+ if (*ptr == 0)
+ {
+ struct Pokemon *pkmn = gPlayerParty;
+
+ for (i = 5; i >= 0; i--)
+ {
+ AdjustFriendship(pkmn, 5);
+ pkmn++;
+ }
+ }
+}
+
+void overworld_poison_timer_set(void)
+{
+ VarSet(VAR_POISON_STEP_COUNTER, 0);
+}
+
+static bool8 overworld_poison_step(void)
+{
+ u16 *ptr;
+
+ if (gMapHeader.mapType != MAP_TYPE_SECRET_BASE)
+ {
+ ptr = GetVarPointer(VAR_POISON_STEP_COUNTER);
+ (*ptr)++;
+ (*ptr) %= 4;
+ if (*ptr == 0)
+ {
+ switch (DoPoisonFieldEffect())
+ {
+ case 0:
+ return FALSE;
+ case 1:
+ return FALSE;
+ case 2:
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+void prev_quest_postbuffer_cursor_backup_reset(void)
+{
+ gUnknown_0202E8C0 = 0;
+}
+
+static bool8 is_it_battle_time_3(u16 a)
+{
+ if (gUnknown_0202E8C0 < 4)
+ {
+ gUnknown_0202E8C0++;
+ gUnknown_0202E8C2 = a;
+ return FALSE;
+ }
+ if (StandardWildEncounter(a, gUnknown_0202E8C2) == TRUE)
+ {
+ gUnknown_0202E8C0 = 0;
+ gUnknown_0202E8C2 = a;
+ return TRUE;
+ }
+ else
+ {
+ gUnknown_0202E8C2 = a;
+ return FALSE;
+ }
+}
+
+static bool8 mapheader_run_first_tag2_script_list_match_conditionally(struct MapPosition *position, u16 b, u8 c)
+{
+ s8 r6 = map_warp_check_packed(&gMapHeader, position);
+
+ if (is_non_stair_warp_tile(b, c) == TRUE && r6 != -1)
+ {
+ walkrun_find_lowest_active_bit_in_bitfield();
+ sub_8068C30(&gMapHeader, r6, position);
+ sub_8080E88();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8068A64(struct MapPosition *position, u16 b)
+{
+ s8 r4 = map_warp_check_packed(&gMapHeader, position);
+
+ if (r4 != -1 && sub_8068B30(b) == TRUE)
+ {
+ walkrun_find_lowest_active_bit_in_bitfield();
+ sub_8068C30(&gMapHeader, r4, position);
+ if (MetatileBehavior_IsEscalator(b) == TRUE)
+ {
+ sub_8080F2C(b);
+ return TRUE;
+ }
+ if (MetatileBehavior_IsLavaridgeB1FWarp(b) == TRUE)
+ {
+ sub_8080F48();
+ return TRUE;
+ }
+ if (MetatileBehavior_IsLavaridge1FWarp(b) == TRUE)
+ {
+ sub_8080F58();
+ return TRUE;
+ }
+ if (MetatileBehavior_IsAquaHideoutWarp(b) == TRUE)
+ {
+ sub_8080F68();
+ return TRUE;
+ }
+ if (MetatileBehavior_IsMtPyreHole(b) == TRUE)
+ {
+ ScriptContext1_SetupScript(gUnknown_081C6BDE);
+ return TRUE;
+ }
+ sub_8080E88();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool8 sub_8068B30(u16 a)
+{
+ if (MetatileBehavior_IsWarpDoor(a) != TRUE
+ && MetatileBehavior_IsLadder(a) != TRUE
+ && MetatileBehavior_IsEscalator(a) != TRUE
+ && MetatileBehavior_IsNonAnimDoor(a) != TRUE
+ && MetatileBehavior_IsLavaridgeB1FWarp(a) != TRUE
+ && MetatileBehavior_IsLavaridge1FWarp(a) != TRUE
+ && MetatileBehavior_IsAquaHideoutWarp(a) != TRUE
+ && MetatileBehavior_IsMtPyreHole(a) != TRUE)
+ return FALSE;
+ return TRUE;
+}
+
+static bool8 is_non_stair_warp_tile(u16 a, u8 b)
+{
+ switch (b)
+ {
+ case 2:
+ return MetatileBehavior_IsNorthArrowWarp(a);
+ case 1:
+ return MetatileBehavior_IsSouthArrowWarp(a);
+ case 3:
+ return MetatileBehavior_IsWestArrowWarp(a);
+ case 4:
+ return MetatileBehavior_IsEastArrowWarp(a);
+ }
+ return FALSE;
+}
+
+static s8 map_warp_check_packed(struct MapHeader *mapHeader, struct MapPosition *position)
+{
+ return map_warp_check(mapHeader, position->x - 7, position->y - 7, position->height);
+}
+
+static void sub_8068C30(struct MapHeader *unused, s8 b, struct MapPosition *position)
+{
+ struct WarpEvent *warpEvent = &gMapHeader.events->warps[b];
+
+ if (warpEvent->mapNum == 0x7F)
+ {
+ copy_saved_warp2_bank_and_enter_x_to_warp1(warpEvent->mapGroup);
+ }
+ else
+ {
+ struct MapHeader *mapHeader;
+
+ warp1_set_2(warpEvent->unk7, warpEvent->mapNum, warpEvent->mapGroup);
+ sub_80535C4(position->x, position->y);
+ mapHeader = Overworld_GetMapHeaderByGroupAndId(warpEvent->unk7, warpEvent->mapNum);
+ if (mapHeader->events->warps[warpEvent->mapGroup].mapNum == 0x7F)
+ saved_warp2_set(mapHeader->events->warps[b].mapGroup, gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum, b);
+ }
+}
+
+static bool8 map_warp_consider_2_to_inside(struct MapPosition *position, u16 b, u8 c)
+{
+ s8 r4;
+
+ if (c == 2)
+ {
+ if (sub_80571C0(b) == TRUE)
+ {
+ sub_80BC038(position, gMapHeader.events);
+ return TRUE;
+ }
+ if (MetatileBehavior_IsWarpDoor(b) == TRUE)
+ {
+ r4 = map_warp_check_packed(&gMapHeader, position);
+ if (r4 != -1 && sub_8068B30(b) == TRUE)
+ {
+ walkrun_find_lowest_active_bit_in_bitfield();
+ sub_8068C30(&gMapHeader, r4, position);
+ sub_8080EF0();
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+static s8 map_warp_check(struct MapHeader *mapHeader, u16 x, u16 y, u8 warpId)
+{
+ s32 i;
+ struct WarpEvent *warpEvent = mapHeader->events->warps;
+ u8 warpCount = mapHeader->events->warpCount;
+
+ for (i = 0; i < warpCount; i++, warpEvent++)
+ {
+ if ((u16)warpEvent->x == x && (u16)warpEvent->y == y)
+ {
+ if ((u8)warpEvent->warpId == warpId || (u8)warpEvent->warpId == 0)
+ return i;
+ }
+ }
+ return -1;
+}
+
+static u8 *trigger_activate(struct CoordEvent *coordEvent)
+{
+ if (coordEvent != NULL)
+ {
+ if (coordEvent->script == NULL)
+ {
+ DoCoordEventWeather(coordEvent->trigger);
+ return NULL;
+ }
+ if (coordEvent->trigger == 0)
+ {
+ ScriptContext2_RunNewScript(coordEvent->script);
+ return NULL;
+ }
+ if (VarGet(coordEvent->trigger) == (u8)coordEvent->index)
+ return coordEvent->script;
+ }
+ return NULL;
+}
+
+static u8 *mapheader_trigger_activate_at(struct MapHeader *mapHeader, u16 x, u16 y, u8 d)
+{
+ s32 i;
+ struct CoordEvent *coordEvents = mapHeader->events->coordEvents;
+ u8 coordEventCount = mapHeader->events->coordEventCount;
+ u8 *script;
+
+ for (i = 0; i < coordEventCount; i++)
+ {
+ if ((u16)coordEvents[i].x == x && (u16)coordEvents[i].y == y)
+ {
+ if (coordEvents[i].unk4 == d || coordEvents[i].unk4 == 0)
+ {
+ script = trigger_activate(&coordEvents[i]);
+ if (script != NULL)
+ return script;
+ }
+ }
+ }
+ return NULL;
+}
+
+u8 *sub_8068E24(struct MapPosition *position)
+{
+ return mapheader_trigger_activate_at(&gMapHeader, position->x - 7, position->y - 7, position->height);
+}
+
+static struct BgEvent *FindInvisibleMapObjectByPosition(struct MapHeader *mapHeader, u16 b, u16 c, u8 d)
+{
+ u8 i;
+ struct BgEvent *bgEvents = mapHeader->events->bgEvents;
+ u8 bgEventCount = mapHeader->events->bgEventCount;
+
+ for (i = 0; i < bgEventCount; i++)
+ {
+ if ((u16)bgEvents[i].x == b && (u16)bgEvents[i].y == c)
+ {
+ if (bgEvents[i].unk4 == d || bgEvents[i].unk4 == 0)
+ return &bgEvents[i];
+ }
+ }
+ return NULL;
+}
+
+int dive_warp(struct MapPosition *position, u16 b)
+{
+ if (gMapHeader.mapType == MAP_TYPE_UNDERWATER && sub_805750C(b) == 0)
+ {
+ if (sub_80538B0(position->x - 7, position->y - 7))
+ {
+ walkrun_find_lowest_active_bit_in_bitfield();
+ sp13E_warp_to_last_warp();
+ PlaySE(SE_W291);
+ return TRUE;
+ }
+ }
+ else if (sub_80574EC(b) == TRUE)
+ {
+ if (sub_80538D0(position->x - 7, position->y - 7))
+ {
+ walkrun_find_lowest_active_bit_in_bitfield();
+ sp13E_warp_to_last_warp();
+ PlaySE(SE_W291);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+u8 sub_8068F18(void)
+{
+ s16 x, y;
+ u8 r5;
+
+ PlayerGetDestCoords(&x, &y);
+ r5 = MapGridGetMetatileBehaviorAt(x, y);
+ if (gMapHeader.mapType == MAP_TYPE_UNDERWATER && sub_805750C(r5) == 0)
+ {
+ if (sub_80538B0(x - 7, y - 7) == TRUE)
+ return 1;
+ }
+ else if (sub_80574EC(r5) == TRUE)
+ {
+ if (sub_80538D0(x - 7, y - 7) == TRUE)
+ return 2;
+ }
+ return 0;
+}
+
+u8 *GetFieldObjectScriptPointerForComparison(void)
+{
+ u8 r4;
+ struct MapPosition position;
+
+ r4 = player_get_direction_upper_nybble();
+ player_get_next_pos_and_height(&position);
+ return sub_8068364(&position, MapGridGetMetatileBehaviorAt(position.x, position.y), r4);
+}
+
+int SetCableClubWarp(void)
+{
+ struct MapPosition position;
+
+ player_get_direction_upper_nybble(); //unnecessary
+ player_get_pos_to_and_height(&position);
+ MapGridGetMetatileBehaviorAt(position.x, position.y); //unnecessary
+ sub_8068C30(&gMapHeader, map_warp_check_packed(&gMapHeader, &position), &position);
+ return 0;
+}
diff --git a/src/field/field_door.c b/src/field/field_door.c
new file mode 100644
index 000000000..ab46f0696
--- /dev/null
+++ b/src/field/field_door.c
@@ -0,0 +1,222 @@
+#include "global.h"
+#include "field_door.h"
+#include "field_camera.h"
+#include "fieldmap.h"
+#include "metatile_behavior.h"
+#include "songs.h"
+#include "task.h"
+
+extern struct DoorAnimFrame gDoorOpenAnimFrames[];
+extern struct DoorAnimFrame gDoorCloseAnimFrames[];
+extern struct DoorGraphics gDoorAnimGraphicsTable[];
+
+static void CopyDoorTilesToVram(void *src)
+{
+ CpuFastSet(src, (void *)(VRAM + 0x7F00), 0x40);
+}
+
+static void door_build_blockdef(u16 *a, u16 b, u8 *c)
+{
+ int i;
+ u16 unk;
+
+ for (i = 0; i < 4; i++)
+ {
+ unk = *(c++) << 12;
+ a[i] = unk | (b + i);
+ }
+ for (; i < 8; i++)
+ {
+ unk = *(c++) << 12;
+ a[i] = unk;
+ }
+}
+
+static void DrawCurrentDoorAnimFrame(u32 x, u32 y, u8 *c)
+{
+ u16 arr[8];
+
+ door_build_blockdef(arr, 0x3F8, c);
+ DrawDoorMetatileAt(x, y - 1, arr);
+ door_build_blockdef(arr, 0x3FC, c + 4);
+ DrawDoorMetatileAt(x, y, arr);
+}
+
+static void DrawClosedDoorTiles(u32 x, u32 y)
+{
+ CurrentMapDrawMetatileAt(x, y - 1);
+ CurrentMapDrawMetatileAt(x, y);
+}
+
+static void DrawDoor(struct DoorGraphics *gfx, struct DoorAnimFrame *frame, u32 x, u32 y)
+{
+ if (frame->offset == 0xFFFF)
+ DrawClosedDoorTiles(x, y);
+ else
+ {
+ CopyDoorTilesToVram(gfx->tiles + frame->offset);
+ DrawCurrentDoorAnimFrame(x, y, gfx->palette);
+ }
+}
+
+enum
+{
+ TD_FRAMELIST = 0,
+ TD_GFX = 2,
+ TD_FRAME = 4,
+ TD_COUNTER,
+ TD_X,
+ TD_Y
+};
+
+static bool32 sub_8058464(struct DoorGraphics *gfx, struct DoorAnimFrame *frames, s16 *taskData)
+{
+ if (taskData[TD_COUNTER] == 0)
+ DrawDoor(gfx, &frames[taskData[TD_FRAME]], taskData[TD_X], taskData[TD_Y]);
+ if (taskData[TD_COUNTER] == frames[taskData[TD_FRAME]].time)
+ {
+ taskData[TD_COUNTER] = 0;
+ taskData[TD_FRAME]++;
+ if (frames[taskData[TD_FRAME]].time == 0)
+ return FALSE;
+ else
+ return TRUE;
+ }
+ taskData[TD_COUNTER]++;
+ return TRUE;
+}
+
+static void Task_AnimateDoor(u8 taskId)
+{
+ u16 *taskData = gTasks[taskId].data;
+ struct DoorAnimFrame *frames = (struct DoorAnimFrame *)(taskData[TD_FRAMELIST] << 16 | taskData[TD_FRAMELIST + 1]);
+ struct DoorGraphics *gfx = (struct DoorGraphics *)(taskData[TD_GFX] << 16 | taskData[TD_GFX + 1]);
+
+ if (sub_8058464(gfx, frames, taskData) == FALSE)
+ DestroyTask(taskId);
+}
+
+static struct DoorAnimFrame *GetLastDoorFrame(struct DoorAnimFrame *frame, void *unused)
+{
+ while (frame->time != 0)
+ frame++;
+ return frame - 1;
+}
+
+static struct DoorGraphics *GetDoorGraphics(struct DoorGraphics *gfx, u16 metatileNum)
+{
+ while (gfx->tiles != NULL)
+ {
+ if (gfx->metatileNum == metatileNum)
+ return gfx;
+ gfx++;
+ }
+ return NULL;
+}
+
+static s8 StartDoorAnimationTask(struct DoorGraphics *gfx, struct DoorAnimFrame *frames, u32 x, u32 y)
+{
+ if (FuncIsActiveTask(Task_AnimateDoor) == TRUE)
+ return -1;
+ else
+ {
+ u8 taskId = CreateTask(Task_AnimateDoor, 0x50);
+ s16 *taskData = gTasks[taskId].data;
+
+ taskData[TD_X] = x;
+ taskData[TD_Y] = y;
+
+ taskData[TD_FRAMELIST + 1] = (u32)frames;
+ taskData[TD_FRAMELIST] = (u32)frames >> 16;
+
+ taskData[TD_GFX + 1] = (u32)gfx;
+ taskData[TD_GFX] = (u32)gfx >> 16;
+
+ return taskId;
+ }
+}
+
+static void DrawClosedDoor(struct DoorGraphics *unused, u32 x, u32 y)
+{
+ DrawClosedDoorTiles(x, y);
+}
+
+static void DrawOpenedDoor(struct DoorGraphics *gfx, u32 x, u32 y)
+{
+ gfx = GetDoorGraphics(gfx, MapGridGetMetatileIdAt(x, y));
+ if (gfx != NULL)
+ DrawDoor(gfx, GetLastDoorFrame(gDoorOpenAnimFrames, gDoorOpenAnimFrames), x, y);
+}
+
+static s8 StartDoorOpenAnimation(struct DoorGraphics *gfx, u32 x, u32 y)
+{
+ gfx = GetDoorGraphics(gfx, MapGridGetMetatileIdAt(x, y));
+ if (gfx == NULL)
+ return -1;
+ else
+ return StartDoorAnimationTask(gfx, gDoorOpenAnimFrames, x, y);
+}
+
+static s8 StartDoorCloseAnimation(struct DoorGraphics *gfx, u32 x, u32 y)
+{
+ gfx = GetDoorGraphics(gfx, MapGridGetMetatileIdAt(x, y));
+ if (gfx == NULL)
+ return -1;
+ else
+ return StartDoorAnimationTask(gfx, gDoorCloseAnimFrames, x, y);
+}
+
+static s8 cur_mapdata_get_door_x2_at(struct DoorGraphics *gfx, u32 x, u32 y)
+{
+ gfx = GetDoorGraphics(gfx, MapGridGetMetatileIdAt(x, y));
+ if (gfx == NULL)
+ return -1;
+ else
+ return gfx->unk2;
+}
+
+void unref_sub_805869C(u32 x, u32 y)
+{
+ StartDoorOpenAnimation(gDoorAnimGraphicsTable, x, y);
+}
+
+void FieldSetDoorOpened(u32 x, u32 y)
+{
+ if (MetatileBehavior_IsDoor(MapGridGetMetatileBehaviorAt(x, y)))
+ DrawOpenedDoor(gDoorAnimGraphicsTable, x, y);
+}
+
+void FieldSetDoorClosed(u32 x, u32 y)
+{
+ if (MetatileBehavior_IsDoor(MapGridGetMetatileBehaviorAt(x, y)))
+ DrawClosedDoor(gDoorAnimGraphicsTable, x, y);
+}
+
+s8 FieldAnimateDoorClose(u32 x, u32 y)
+{
+ if (!MetatileBehavior_IsDoor(MapGridGetMetatileBehaviorAt(x, y)))
+ return -1;
+ else
+ return StartDoorCloseAnimation(gDoorAnimGraphicsTable, x, y);
+}
+
+s8 FieldAnimateDoorOpen(u32 x, u32 y)
+{
+ if (!MetatileBehavior_IsDoor(MapGridGetMetatileBehaviorAt(x, y)))
+ return -1;
+ else
+ return StartDoorOpenAnimation(gDoorAnimGraphicsTable, x, y);
+}
+
+bool8 FieldIsDoorAnimationRunning(void)
+{
+ return FuncIsActiveTask(Task_AnimateDoor);
+}
+
+u32 GetDoorSoundEffect(u32 x, u32 y)
+{
+ if (cur_mapdata_get_door_x2_at(gDoorAnimGraphicsTable, x, y) == 0)
+ return SE_DOOR;
+ else
+ return SE_JIDO_DOA;
+}
diff --git a/src/field/field_effect.c b/src/field/field_effect.c
new file mode 100644
index 000000000..afe020ac7
--- /dev/null
+++ b/src/field/field_effect.c
@@ -0,0 +1,3405 @@
+#include "global.h"
+#include "data2.h"
+#include "script.h"
+#include "trig.h"
+#include "main.h"
+#include "field_weather.h"
+#include "decompress.h"
+#include "sprite.h"
+#include "menu.h"
+#include "palette.h"
+#include "text.h"
+#include "overworld.h"
+#include "task.h"
+#include "sound.h"
+#include "songs.h"
+#include "decoration.h"
+#include "field_player_avatar.h"
+#include "field_map_obj_helpers.h"
+#include "field_map_obj.h"
+#include "metatile_behavior.h"
+#include "field_camera.h"
+#include "field_effect.h"
+#include "field_fadetransition.h"
+#include "fieldmap.h"
+#include "field_map_obj.h"
+#include "util.h"
+#include "field_effect_helpers.h"
+
+#define subsprite_table(ptr) {.subsprites = ptr, .subspriteCount = (sizeof ptr) / (sizeof(struct Subsprite))}
+
+EWRAM_DATA u32 gFieldEffectArguments[8] = {0};
+
+const u32 gSpriteImage_839DC14[] = INCBIN_U32("graphics/birch_speech/birch.4bpp");
+const u16 gBirchPalette[16] = INCBIN_U16("graphics/birch_speech/birch.gbapal");
+const u32 gSpriteImage_839E434[] = INCBIN_U32("graphics/misc/pokeball_glow.4bpp");
+const u16 gFieldEffectObjectPalette4[16] = INCBIN_U16("graphics/field_effect_objects/palettes/04.gbapal");
+const u32 gSpriteImage_839E474[] = INCBIN_U32("graphics/misc/pokecenter_monitor/0.4bpp");
+const u32 gSpriteImage_839E534[] = INCBIN_U32("graphics/misc/pokecenter_monitor/1.4bpp");
+const u32 gSpriteImage_839E5F4[] = INCBIN_U32("graphics/misc/big_hof_monitor.4bpp");
+const u32 gSpriteImage_839E7F4[] = INCBIN_U32("graphics/misc/small_hof_monitor.4bpp");
+const u16 gFieldEffectObjectPalette5[16] = INCBIN_U16("graphics/field_effect_objects/palettes/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");
+
+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 gOamData_839F0F4 = {.size = 3};
+const struct OamData gOamData_839F0FC = {.size = 0};
+const struct OamData gOamData_839F104 = {.size = 1};
+
+const struct SpriteFrameImage gSpriteImageTable_839F10C[] = {
+ obj_frame_tiles(gSpriteImage_839DC14)
+};
+const struct SpritePalette gUnknown_0839F114 = {.data = gBirchPalette, .tag = 0x1006};
+
+const union AnimCmd gSpriteAnim_839F11C[] = {
+ ANIMCMD_FRAME(.imageValue = 0, .duration = 1),
+ ANIMCMD_END
+};
+
+const union AnimCmd *const gSpriteAnimTable_839F124[] = {
+ gSpriteAnim_839F11C
+};
+
+const struct SpriteTemplate gSpriteTemplate_839F128 = {
+ .tileTag = 0xffff,
+ .paletteTag = 4102,
+ .oam = &gOamData_839F0F4,
+ .anims = (const union AnimCmd *const *)&gSpriteAnimTable_839F124,
+ .images = gSpriteImageTable_839F10C,
+ .affineAnims = (const union AffineAnimCmd *const *)&gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy
+};
+
+const struct SpritePalette gFieldEffectObjectPaletteInfo4 = {.data = gFieldEffectObjectPalette4, .tag = 0x1007};
+const struct SpritePalette gFieldEffectObjectPaletteInfo5 = {.data = gFieldEffectObjectPalette5, .tag = 0x1010};
+const struct OamData gOamData_839F150 = {
+ .shape = 1,
+ .size = 2
+};
+
+const struct SpriteFrameImage gSpriteImageTable_839F158[] = {
+ obj_frame_tiles(gSpriteImage_839E434)
+};
+
+const struct SpriteFrameImage gSpriteImageTable_839F160[] = {
+ obj_frame_tiles(gSpriteImage_839E474),
+ obj_frame_tiles(gSpriteImage_839E534)
+};
+
+const struct SpriteFrameImage gSpriteImageTable_839F170[] = {
+ obj_frame_tiles(gSpriteImage_839E5F4)
+};
+
+const struct SpriteFrameImage gSpriteImageTable_839F178[] = {
+ {.data = (u8 *)gSpriteImage_839E7F4, .size = 0x200} // the macro breaks down here
+};
+
+const struct Subsprite Unknown_39F180[] = {
+ {.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_0839F1A0 = subsprite_table(Unknown_39F180);
+
+const struct Subsprite Unknown_39F1A8[] = {
+ {.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_0839F1C8 = subsprite_table(Unknown_39F1A8);
+
+const union AnimCmd gSpriteAnim_839F1D0[] = {
+ ANIMCMD_FRAME(.imageValue = 0, .duration = 1),
+ ANIMCMD_JUMP(0)
+};
+
+const union AnimCmd gSpriteAnim_839F1D8[] = {
+ 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_839F1FC[] = {
+ gSpriteAnim_839F1D0,
+ gSpriteAnim_839F1D8
+};
+
+const union AnimCmd *const gSpriteAnimTable_839F204[] = {
+ gSpriteAnim_839F1D0
+};
+
+const struct SpriteTemplate gSpriteTemplate_839F208 = {
+ .tileTag = 0xffff,
+ .paletteTag = 4103,
+ .oam = &gOamData_839F0FC,
+ .anims = gSpriteAnimTable_839F1FC,
+ .images = gSpriteImageTable_839F158,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_PokeballGlow
+};
+
+
+const struct SpriteTemplate gSpriteTemplate_839F220 = {
+ .tileTag = 0xffff,
+ .paletteTag = 4100,
+ .oam = &gOamData_839F104,
+ .anims = gSpriteAnimTable_839F1FC,
+ .images = gSpriteImageTable_839F160,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_PokecenterMonitor
+};
+
+
+const struct SpriteTemplate gSpriteTemplate_839F238 = {
+ .tileTag = 0xffff,
+ .paletteTag = 4112,
+ .oam = &gOamData_839F104,
+ .anims = gSpriteAnimTable_839F204,
+ .images = gSpriteImageTable_839F170,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_HallOfFameMonitor
+};
+
+
+const struct SpriteTemplate gSpriteTemplate_839F250 = {
+ .tileTag = 0xffff,
+ .paletteTag = 4112,
+ .oam = &gOamData_839F150,
+ .anims = gSpriteAnimTable_839F204,
+ .images = gSpriteImageTable_839F178,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_HallOfFameMonitor
+};
+
+void (*const gUnknown_0839F268[])(struct Task *) = {
+ PokecenterHealEffect_0,
+ PokecenterHealEffect_1,
+ PokecenterHealEffect_2,
+ PokecenterHealEffect_3
+};
+
+void (*const gUnknown_0839F278[])(struct Task *) = {
+ HallOfFameRecordEffect_0,
+ HallOfFameRecordEffect_1,
+ HallOfFameRecordEffect_2,
+ HallOfFameRecordEffect_3
+};
+
+void (*const gUnknown_0839F288[])(struct Sprite *) = {
+ PokeballGlowEffect_0,
+ PokeballGlowEffect_1,
+ PokeballGlowEffect_2,
+ PokeballGlowEffect_3,
+ PokeballGlowEffect_4,
+ PokeballGlowEffect_5,
+ PokeballGlowEffect_6,
+ PokeballGlowEffect_7
+};
+
+const struct Coords16 gUnknown_0839F2A8[] = {
+ {.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_0839F2C0[] = {16, 12, 8, 0};
+const u8 gUnknown_0839F2C4[] = {16, 12, 8, 0};
+const u8 gUnknown_0839F2C8[] = { 0, 0, 0, 0};
+
+bool8 (*const gUnknown_0839F2CC[])(struct Task *) = {
+ sub_80867AC,
+ sub_8086854,
+ sub_8086870,
+ sub_80868E4,
+ sub_808699C,
+ sub_80869B8,
+ sub_80869F8
+};
+
+bool8 (*const gUnknown_0839F2E8[])(struct Task *) = {
+ sub_8086AA0,
+ sub_8086AC0,
+ sub_8086B30,
+ sub_8086B54,
+ sub_8086B64,
+ sub_8086B88
+};
+
+bool8 (*const gUnknown_0839F300[])(struct Task *) = {
+ sub_8086CF4,
+ sub_8086D70,
+ sub_8086DB0,
+ sub_8086E10,
+ sub_8086E50,
+ sub_8086EB0,
+ sub_8086ED4
+};
+
+bool8 (*const gUnknown_0839F31C[])(struct Task *, struct MapObject *) = {
+ sub_8086FB0,
+ waterfall_1_do_anim_probably,
+ waterfall_2_wait_anim_finish_probably,
+ sub_8087030,
+ sub_8087058
+};
+
+bool8 (*const gUnknown_0839F330[])(struct Task *) = {
+ sub_8087124,
+ dive_2_unknown,
+ dive_3_unknown
+};
+
+bool8 (*const gUnknown_0839F33C[])(struct Task *, struct MapObject *, struct Sprite *) = {
+ sub_808722C,
+ sub_8087264,
+ sub_8087298,
+ sub_80872E4,
+ sub_80873D8,
+ sub_80873F4
+};
+
+bool8 (*const gUnknown_0839F354[])(struct Task *, struct MapObject *, struct Sprite *) = {
+ sub_80874CC,
+ sub_80874FC,
+ sub_8087548,
+ sub_808759C
+};
+
+bool8 (*const gUnknown_0839F364[])(struct Task *, struct MapObject *, struct Sprite *) = {
+ sub_80876C8,
+ sub_80876F8,
+ sub_8087774,
+ sub_80877AC,
+ sub_80877D4
+};
+
+void (*const gUnknown_0839F378[])(struct Task *) = {
+ sub_80878F4,
+ sub_8087914
+};
+
+const u8 gUnknown_0839F380[] = {1, 3, 4, 2, 1};
+
+void (*const gUnknown_0839F388[])(struct Task *) = {
+ sub_8087AA4,
+ sub_8087AC8
+};
+
+void (*const gUnknown_0839F390[])(struct Task *) = {
+ sub_8087BEC,
+ sub_8087C14,
+ sub_8087CA4,
+ sub_8087D78
+};
+
+void (*const gUnknown_0839F3A0[])(struct Task *) = {
+ sub_8087E4C,
+ sub_8087ED8,
+ sub_8087FDC
+};
+
+void (*const gUnknown_0839F3AC[])(struct Task *) = {
+ sub_8088150,
+ sub_80881C0,
+ sub_8088228,
+ sub_80882B4,
+ sub_80882E4,
+ sub_8088338,
+ sub_8088380
+};
+
+void (*const gUnknown_0839F3C8[])(struct Task *) = {
+ sub_80884AC,
+ sub_80884E8,
+ sub_8088554,
+ sub_80885A8,
+ sub_80885D8,
+ sub_808860C,
+ sub_808862C
+};
+
+void (*const gUnknown_0839F3E4[])(struct Task *) = {
+ sub_8088984,
+ sub_80889E4,
+ sub_8088A30,
+ sub_8088A78,
+ sub_8088AF4
+};
+
+void (*const gUnknown_0839F3F8[])(struct Task *) = {
+ sub_8088CA0,
+ sub_8088CF8,
+ sub_8088D3C,
+ sub_8088D94,
+ sub_8088DD8,
+ sub_8088E2C,
+ sub_8088EB4,
+ sub_8088F10,
+ sub_8088F30
+};
+
+const union AffineAnimCmd SpriteAffineAnim_839F41C[] = {
+ AFFINEANIMCMD_FRAME(8, 8, -30, 0),
+ AFFINEANIMCMD_FRAME(28, 28, 0, 30),
+ AFFINEANIMCMD_END
+};
+
+const union AffineAnimCmd SpriteAffineAnim_839F434[] = {
+ AFFINEANIMCMD_FRAME(256, 256, 64, 0),
+ AFFINEANIMCMD_FRAME(-10, -10, 0, 22),
+ AFFINEANIMCMD_END
+};
+
+const union AffineAnimCmd *const gSpriteAffineAnimTable_0839F44C[] = {
+ SpriteAffineAnim_839F41C,
+ SpriteAffineAnim_839F434
+};
+
+void (*const gUnknown_0839F454[])(struct Task *) = {
+ sub_80892A0,
+ sub_8089354,
+ sub_80893C0,
+ sub_8089414,
+ sub_808948C,
+ sub_80894C4,
+ fishE
+};
+
+const s16 gUnknown_0839F470[] = {
+ -2,
+ -4,
+ -5,
+ -6,
+ -7,
+ -8,
+ -8,
+ -8,
+ -7,
+ -7,
+ -6,
+ -5,
+ -3,
+ -2,
+ 0,
+ 2,
+ 4,
+ 8
+};
+
+static u8 sActiveList[32];
+
+extern u8 *gFieldEffectScriptPointers[];
+
+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);
+ sub_807D78C(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 = &gOamData_839F0F4;
+ 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 CreateBirchSprite(s16 x, s16 y, u8 subpriority)
+{
+ LoadSpritePalette(&gUnknown_0839F114);
+ return CreateSprite(&gSpriteTemplate_839F128, x, y, subpriority);
+}
+
+u8 CreateMonSprite_PicBox(u16 species, s16 x, s16 y, u8 subpriority)
+{
+ DecompressPicFromTable_2(&gMonFrontPicTable[species], gMonFrontPicCoords[species].coords, gMonFrontPicCoords[species].y_offset, gUnknown_081FAF4C[3], gUnknown_081FAF4C[3], species);
+ LoadCompressedObjectPalette(&gMonPaletteTable[species]);
+ GetMonSpriteTemplate_803C56C(species, 3);
+ gUnknown_02024E8C.paletteTag = gMonPaletteTable[0].tag;
+ sub_807DE38(IndexOfSpritePaletteTag(gMonPaletteTable[0].tag) + 0x10);
+ return CreateSprite(&gUnknown_02024E8C, x, y, subpriority);
+}
+
+u8 CreateMonSprite_FieldMove(u16 species, u32 d, u32 g, s16 x, s16 y, u8 subpriority)
+{
+ const struct CompressedSpritePalette *spritePalette;
+
+ HandleLoadSpecialPokePic(&gMonFrontPicTable[species], gMonFrontPicCoords[species].coords, gMonFrontPicCoords[species].y_offset, (u32)gUnknown_081FAF4C[3] /* this is actually u8* or something, pointing to ewram */, gUnknown_081FAF4C[3], species, g);
+ spritePalette = GetMonSpritePalStructFromOtIdPersonality(species, d, g);
+ LoadCompressedObjectPalette(spritePalette);
+ GetMonSpriteTemplate_803C56C(species, 3);
+ gUnknown_02024E8C.paletteTag = spritePalette->tag;
+ sub_807DE38(IndexOfSpritePaletteTag(spritePalette->tag) + 0x10);
+ return CreateSprite(&gUnknown_02024E8C, x, y, subpriority);
+}
+
+void FreeResourcesAndDestroySprite(struct Sprite *sprite)
+{
+ sub_807DE68();
+ FreeSpritePaletteByTag(GetSpritePaletteTagByPaletteNum(sprite->oam.paletteNum));
+ if (sprite->oam.affineMode != 0)
+ {
+ FreeOamMatrix(sprite->oam.matrixNum);
+ }
+ DestroySprite(sprite);
+}
+
+#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
+__attribute__((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");
+}
+
+__attribute__((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_0839F268[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]].data0 > 1)
+ {
+ gSprites[task->data[7]].data0++;
+ task->data[0]++;
+ }
+}
+
+void PokecenterHealEffect_2(struct Task *task)
+{
+ if (gSprites[task->data[6]].data0 > 4)
+ {
+ task->data[0]++;
+ }
+}
+
+void PokecenterHealEffect_3(struct Task *task)
+{
+ if (gSprites[task->data[6]].data0 > 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_0839F278[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]].data0 > 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]].data0 > 4)
+ {
+ task->data[0]++;
+ }
+}
+
+void HallOfFameRecordEffect_3(struct Task *task)
+{
+ if (gSprites[task->data[6]].data0 > 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->data5 = data5;
+ sprite->data6 = data6;
+ sprite->data7 = spriteId;
+ return spriteId;
+}
+
+void SpriteCB_PokeballGlowEffect(struct Sprite *sprite)
+{
+ gUnknown_0839F288[sprite->data0](sprite);
+}
+
+void PokeballGlowEffect_0(struct Sprite *sprite)
+{
+ u8 endSpriteId;
+ if (sprite->data1 == 0 || (--sprite->data1) == 0)
+ {
+ sprite->data1 = 25;
+ endSpriteId = CreateSpriteAtEnd(&gSpriteTemplate_839F208, gUnknown_0839F2A8[sprite->data2].x + sprite->pos2.x, gUnknown_0839F2A8[sprite->data2].y + sprite->pos2.y, 0);
+ gSprites[endSpriteId].oam.priority = 2;
+ gSprites[endSpriteId].data0 = sprite->data7;
+ sprite->data2++;
+ sprite->data6--;
+ PlaySE(SE_BOWA);
+ }
+ if (sprite->data6 == 0)
+ {
+ sprite->data1 = 32;
+ sprite->data0++;
+ }
+}
+
+void PokeballGlowEffect_1(struct Sprite *sprite)
+{
+ if ((--sprite->data1) == 0)
+ {
+ sprite->data0++;
+ sprite->data1 = 8;
+ sprite->data2 = 0;
+ sprite->data3 = 0;
+ if (sprite->data5)
+ {
+ PlayFanfare(BGM_ME_ASA);
+ }
+ }
+}
+
+void PokeballGlowEffect_2(struct Sprite *sprite)
+{
+ u8 phase;
+ if ((--sprite->data1) == 0)
+ {
+ sprite->data1 = 8;
+ sprite->data2++;
+ sprite->data2 &= 3;
+ if (sprite->data2 == 0)
+ {
+ sprite->data3++;
+ }
+ }
+ phase = (sprite->data2 + 3) & 3;
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x108, gUnknown_0839F2C0[phase], gUnknown_0839F2C4[phase], gUnknown_0839F2C8[phase]);
+ phase = (sprite->data2 + 2) & 3;
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x106, gUnknown_0839F2C0[phase], gUnknown_0839F2C4[phase], gUnknown_0839F2C8[phase]);
+ phase = (sprite->data2 + 1) & 3;
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x102, gUnknown_0839F2C0[phase], gUnknown_0839F2C4[phase], gUnknown_0839F2C8[phase]);
+ phase = sprite->data2;
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x105, gUnknown_0839F2C0[phase], gUnknown_0839F2C4[phase], gUnknown_0839F2C8[phase]);
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x103, gUnknown_0839F2C0[phase], gUnknown_0839F2C4[phase], gUnknown_0839F2C8[phase]);
+ if (sprite->data3 > 2)
+ {
+ sprite->data0++;
+ sprite->data1 = 8;
+ sprite->data2 = 0;
+ }
+}
+
+void PokeballGlowEffect_3(struct Sprite *sprite)
+{
+ u8 phase;
+ if ((--sprite->data1) == 0)
+ {
+ sprite->data1 = 8;
+ sprite->data2++;
+ sprite->data2 &= 3;
+ if (sprite->data2 == 3)
+ {
+ sprite->data0++;
+ sprite->data1 = 30;
+ }
+ }
+ phase = sprite->data2;
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x108, gUnknown_0839F2C0[phase], gUnknown_0839F2C4[phase], gUnknown_0839F2C8[phase]);
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x106, gUnknown_0839F2C0[phase], gUnknown_0839F2C4[phase], gUnknown_0839F2C8[phase]);
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x102, gUnknown_0839F2C0[phase], gUnknown_0839F2C4[phase], gUnknown_0839F2C8[phase]);
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x105, gUnknown_0839F2C0[phase], gUnknown_0839F2C4[phase], gUnknown_0839F2C8[phase]);
+ MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(0x1007) << 4) + 0x103, gUnknown_0839F2C0[phase], gUnknown_0839F2C4[phase], gUnknown_0839F2C8[phase]);
+}
+
+void PokeballGlowEffect_4(struct Sprite *sprite)
+{
+ if ((--sprite->data1) == 0)
+ {
+ sprite->data0++;
+ }
+}
+
+void PokeballGlowEffect_5(struct Sprite *sprite)
+{
+ sprite->data0++;
+}
+
+void PokeballGlowEffect_6(struct Sprite *sprite)
+{
+ if (sprite->data5 == 0 || IsFanfareTaskInactive())
+ {
+ sprite->data0++;
+ }
+}
+
+void PokeballGlowEffect_7(struct Sprite *sprite)
+{
+}
+
+void SpriteCB_PokeballGlow(struct Sprite *sprite)
+{
+ if (gSprites[sprite->data0].data0 > 4)
+ {
+ FieldEffectFreeGraphicsResources(sprite);
+ }
+}
+
+u8 PokecenterHealEffectHelper(s16 x, s16 y)
+{
+ u8 spriteIdAtEnd;
+ struct Sprite *sprite;
+ spriteIdAtEnd = CreateSpriteAtEnd(&gSpriteTemplate_839F220, x, y, 0);
+ sprite = &gSprites[spriteIdAtEnd];
+ sprite->oam.priority = 2;
+ sprite->invisible = 1;
+ SetSubspriteTables(sprite, &gUnknown_0839F1A0);
+ return spriteIdAtEnd;
+}
+
+void SpriteCB_PokecenterMonitor(struct Sprite *sprite)
+{
+ if (sprite->data0 != 0)
+ {
+ sprite->data0 = 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_839F238, a1, a2, 0);
+ SetSubspriteTables(&gSprites[spriteIdAtEnd], &gUnknown_0839F1C8);
+ } else
+ {
+ spriteIdAtEnd = CreateSpriteAtEnd(&gSpriteTemplate_839F250, a1, a2, 0);
+ }
+ gSprites[spriteIdAtEnd].invisible = 1;
+ gSprites[spriteIdAtEnd].data0 = a0;
+}
+
+void SpriteCB_HallOfFameMonitor(struct Sprite *sprite)
+{
+ if (gTasks[sprite->data0].data[15])
+ {
+ if (sprite->data1 == 0 || (--sprite->data1) == 0)
+ {
+ sprite->data1 = 16;
+ sprite->invisible ^= 1;
+ }
+ sprite->data2++;
+ }
+ if (sprite->data2 > 127)
+ {
+ FieldEffectFreeGraphicsResources(sprite);
+ }
+}
+
+void mapldr_080842E8(void);
+void mapldr_08084390(void);
+void task00_8084310(u8);
+void c3_080843F8(u8);
+
+void sub_80865BC(void)
+{
+ SetMainCallback2(c2_exit_to_overworld_2_switch);
+ 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 (!sub_807D770())
+ {
+ return;
+ }
+ gFieldEffectArguments[0] = gLastFieldPokeMenuOpened;
+ 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_map_transition(void);
+void sub_8086774(u8);
+extern void CameraObjectReset2(void);
+extern void CameraObjectReset1(void);
+
+void sub_8086748(void)
+{
+ Overworld_PlaySpecialMapMusic();
+ pal_fill_for_map_transition();
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ CreateTask(sub_8086774, 0);
+ gFieldCallback = NULL;
+}
+
+void sub_8086774(u8 taskId)
+{
+ struct Task *task;
+ task = &gTasks[taskId];
+ while (gUnknown_0839F2CC[task->data[0]](task)); // return code signifies whether to continue blocking here
+}
+
+bool8 sub_80867AC(struct Task *task) // gUnknown_0839F2CC[0]
+{
+ struct MapObject *playerObject;
+ struct Sprite *playerSprite;
+ playerObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ playerSprite = &gSprites[gPlayerAvatar.spriteId];
+ CameraObjectReset2();
+ gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_13 = 1;
+ gPlayerAvatar.unk6 = 1;
+ 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_8086854(struct Task *task) // gUnknown_0839F2CC[1]
+{
+ if (sub_807D770())
+ {
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+bool8 sub_8086870(struct Task *task) // gUnknown_0839F2CC[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_80868E4(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_808699C(struct Task *task)
+{
+ task->data[0]++;
+ task->data[1] = 4;
+ task->data[2] = 0;
+ SetCameraPanningCallback(NULL);
+ return TRUE;
+}
+
+bool8 sub_80869B8(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_80869F8(struct Task *task)
+{
+ gPlayerAvatar.unk6 = 0;
+ ScriptContext2_Disable();
+ CameraObjectReset1();
+ UnfreezeMapObjects();
+ InstallCameraPanAheadCallback();
+ DestroyTask(FindTaskIdByFunc(sub_8086774));
+ return FALSE;
+}
+
+void sub_8086A68(u8);
+extern void sub_80B4824(u8);
+extern void sub_8053FF8(void);
+extern void fade_8080918(void);
+
+void sub_8086B98(struct Task *);
+void sub_8086BE4(struct Task *);
+void sub_8086C30(void);
+void sub_8086C40(void);
+bool8 sub_8054034(void);
+void sub_8086C94(void);
+void sub_80B483C(void);
+void sub_8086CBC(u8);
+
+void sub_8086A2C(u8 a0, u8 priority)
+{
+ u8 taskId;
+ taskId = CreateTask(sub_8086A68, priority);
+ gTasks[taskId].data[1] = 0;
+ if (a0 == 0x6a)
+ {
+ gTasks[taskId].data[1] = 1;
+ }
+}
+
+void sub_8086A68(u8 taskId)
+{
+ struct Task *task;
+ task = &gTasks[taskId];
+ while (gUnknown_0839F2E8[task->data[0]](task));
+}
+
+bool8 sub_8086AA0(struct Task *task)
+{
+ FreezeMapObjects();
+ CameraObjectReset2();
+ sub_80B4824(task->data[1]);
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 sub_8086AC0(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_8086B30(struct Task *task)
+{
+ sub_8086B98(task);
+ if (task->data[2] > 3)
+ {
+ sub_8086C30();
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+bool8 sub_8086B54(struct Task *task)
+{
+ sub_8086B98(task);
+ sub_8086C40();
+ return FALSE;
+}
+
+bool8 sub_8086B64(struct Task *task)
+{
+ sub_8086BE4(task);
+ if (task->data[2] > 3)
+ {
+ sub_8086C30();
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+bool8 sub_8086B88(struct Task *task)
+{
+ sub_8086BE4(task);
+ sub_8086C40();
+ return FALSE;
+}
+
+void sub_8086B98(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_8086BE4(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_8086C30(void)
+{
+ sub_8053FF8();
+ fade_8080918();
+}
+
+void sub_8086C40(void)
+{
+ if (!gPaletteFade.active && sub_8054034() == TRUE)
+ {
+ sub_80B483C();
+ warp_in();
+ gFieldCallback = sub_8086C94;
+ SetMainCallback2(CB2_LoadMap);
+ DestroyTask(FindTaskIdByFunc(sub_8086A68));
+ }
+}
+
+void sub_8086C94(void)
+{
+ Overworld_PlaySpecialMapMusic();
+ pal_fill_for_map_transition();
+ ScriptContext2_Enable();
+ CreateTask(sub_8086CBC, 0);
+ gFieldCallback = NULL;
+}
+
+void sub_8086CBC(u8 taskId)
+{
+ struct Task *task;
+ task = &gTasks[taskId];
+ while (gUnknown_0839F300[task->data[0]](task));
+}
+
+bool8 sub_8086CF4(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_80B4824(behavior);
+ return TRUE;
+}
+
+bool8 sub_8086D70(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_8086DB0(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_8086E10(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_8086E50(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_80B4850(void);
+
+bool8 sub_8086EB0(struct Task *task)
+{
+ if (sub_80B4850())
+ {
+ return FALSE;
+ }
+ sub_80B483C();
+ task->data[0]++;
+ return TRUE;
+}
+
+bool8 sub_8086ED4(struct Task *task)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ CameraObjectReset1();
+ ScriptContext2_Disable();
+ FieldObjectSetSpecialAnim(mapObject, GetGoSpeed0AnimId(DIR_EAST));
+ DestroyTask(FindTaskIdByFunc(sub_8086CBC));
+ }
+ return FALSE;
+}
+
+void sub_8086F64(u8);
+
+bool8 FldEff_UseWaterfall(void)
+{
+ u8 taskId;
+ taskId = CreateTask(sub_8086F64, 0xff);
+ gTasks[taskId].data[1] = gFieldEffectArguments[0];
+ sub_8086F64(taskId);
+ return FALSE;
+}
+
+void sub_8086F64(u8 taskId)
+{
+ while (gUnknown_0839F31C[gTasks[taskId].data[0]](&gTasks[taskId], &gMapObjects[gPlayerAvatar.mapObjectId]));
+}
+
+bool8 sub_8086FB0(struct Task *task, struct MapObject *mapObject)
+{
+ ScriptContext2_Enable();
+ gPlayerAvatar.unk6 = 1;
+ 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_8087030(struct Task *task, struct MapObject *mapObject)
+{
+ FieldObjectSetSpecialAnim(mapObject, GetSimpleGoAnimId(DIR_NORTH));
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 sub_8087058(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.unk6 = 0;
+ DestroyTask(FindTaskIdByFunc(sub_8086F64));
+ 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_0839F330[gTasks[taskId].data[0]](&gTasks[taskId]));
+}
+
+bool8 sub_8087124(struct Task *task)
+{
+ gPlayerAvatar.unk6 = 1;
+ 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_80871D0(u8);
+void mapldr_080851BC(void);
+
+void sub_80871B8(u8 priority)
+{
+ CreateTask(sub_80871D0, priority);
+}
+
+void sub_80871D0(u8 taskId)
+{
+ while (gUnknown_0839F33C[gTasks[taskId].data[0]](&gTasks[taskId], &gMapObjects[gPlayerAvatar.mapObjectId], &gSprites[gPlayerAvatar.spriteId]));
+}
+
+bool8 sub_808722C(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FreezeMapObjects();
+ CameraObjectReset2();
+ SetCameraPanningCallback(NULL);
+ gPlayerAvatar.unk6 = 1;
+ mapObject->mapobj_bit_26 = 1;
+ task->data[1] = 1;
+ task->data[0]++;
+ return TRUE;
+}
+
+bool8 sub_8087264(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_8087298(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_80872E4(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_80873D8(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8053FF8();
+ fade_8080918();
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 sub_80873F4(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (!gPaletteFade.active && sub_8054034() == TRUE)
+ {
+ warp_in();
+ gFieldCallback = mapldr_080851BC;
+ SetMainCallback2(CB2_LoadMap);
+ DestroyTask(FindTaskIdByFunc(sub_80871D0));
+ }
+ return FALSE;
+}
+
+void sub_8087470(u8);
+
+void mapldr_080851BC(void)
+{
+ Overworld_PlaySpecialMapMusic();
+ pal_fill_for_map_transition();
+ ScriptContext2_Enable();
+ gFieldCallback = NULL;
+ CreateTask(sub_8087470, 0);
+}
+
+void sub_8087470(u8 taskId)
+{
+ while (gUnknown_0839F354[gTasks[taskId].data[0]](&gTasks[taskId], &gMapObjects[gPlayerAvatar.mapObjectId], &gSprites[gPlayerAvatar.spriteId]));
+}
+
+bool8 sub_80874CC(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ CameraObjectReset2();
+ FreezeMapObjects();
+ gPlayerAvatar.unk6 = 1;
+ mapObject->mapobj_bit_13 = 1;
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 sub_80874FC(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_807D770())
+ {
+ 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_8087548(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_80608A4(DIR_EAST));
+ }
+ return FALSE;
+}
+
+bool8 sub_808759C(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ gPlayerAvatar.unk6 = 0;
+ ScriptContext2_Disable();
+ UnfreezeMapObjects();
+ DestroyTask(FindTaskIdByFunc(sub_8087470));
+ }
+ return FALSE;
+}
+
+extern void sub_8060470(s16 *x, s16 *y, s16 dx, s16 dy);
+extern const struct SpriteTemplate *const gFieldEffectObjectTemplatePointers[36];
+
+u8 FldEff_LavaridgeGymWarp(void)
+{
+ u8 spriteId;
+ sub_8060470((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_8087638(struct Sprite *sprite)
+{
+ if (sprite->animEnded)
+ {
+ FieldEffectStop(sprite, FLDEFF_LAVARIDGE_GYM_WARP);
+ }
+}
+
+void sub_808766C(u8);
+
+void sub_8087654(u8 priority)
+{
+ CreateTask(sub_808766C, priority);
+}
+
+void sub_808766C(u8 taskId)
+{
+ while(gUnknown_0839F364[gTasks[taskId].data[0]](&gTasks[taskId], &gMapObjects[gPlayerAvatar.mapObjectId], &gSprites[gPlayerAvatar.spriteId]));
+}
+
+bool8 sub_80876C8(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FreezeMapObjects();
+ CameraObjectReset2();
+ gPlayerAvatar.unk6 = 1;
+ mapObject->mapobj_bit_26 = 1;
+ task->data[0]++;
+ return FALSE;
+}
+
+bool8 sub_80876F8(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_8087774(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_80877AC(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (!FieldEffectActiveListContains(FLDEFF_POP_OUT_OF_ASH))
+ {
+ sub_8053FF8();
+ fade_8080918();
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+void sub_80878C4(u8);
+void mapldr_080859D4(void);
+
+bool8 sub_80877D4(struct Task *task, struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (!gPaletteFade.active && sub_8054034() == TRUE)
+ {
+ warp_in();
+ gFieldCallback = sub_8086748;
+ SetMainCallback2(CB2_LoadMap);
+ DestroyTask(FindTaskIdByFunc(sub_808766C));
+ }
+ return FALSE;
+}
+
+u8 FldEff_PopOutOfAsh(void)
+{
+ u8 spriteId;
+ sub_8060470((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_808788C(struct Sprite *sprite)
+{
+ if (sprite->animEnded)
+ {
+ FieldEffectStop(sprite, FLDEFF_POP_OUT_OF_ASH);
+ }
+}
+
+void sub_80878A8(void)
+{
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ CreateTask(sub_80878C4, 0x50);
+}
+
+void sub_80878C4(u8 taskId)
+{
+ gUnknown_0839F378[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_80878F4(struct Task *task)
+{
+ task->data[0]++;
+ task->data[14] = 64;
+ task->data[15] = player_get_direction_lower_nybble();
+}
+
+void sub_8087914(struct Task *task)
+{
+ struct MapObject *mapObject;
+ u8 unknown_0839F380[5];
+ memcpy(unknown_0839F380, gUnknown_0839F380, sizeof gUnknown_0839F380);
+ if (task->data[14] != 0 && (--task->data[14]) == 0)
+ {
+ sub_8053FF8();
+ fade_8080918();
+ }
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(mapObject) || FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ if (task->data[14] == 0 && !gPaletteFade.active && sub_8054034() == TRUE)
+ {
+ FieldObjectSetDirection(mapObject, task->data[15]);
+ sub_8053678();
+ warp_in();
+ gFieldCallback = mapldr_080859D4;
+ SetMainCallback2(CB2_LoadMap);
+ DestroyTask(FindTaskIdByFunc(sub_80878C4));
+ } else if (task->data[1] == 0 || (--task->data[1]) == 0)
+ {
+ FieldObjectSetSpecialAnim(mapObject, GetFaceDirectionAnimId(unknown_0839F380[mapObject->mapobj_unk_18]));
+ if (task->data[2] < 12)
+ {
+ task->data[2]++;
+ }
+ task->data[1] = 8 >> (task->data[2] >> 2);
+ }
+ }
+}
+
+void sub_8087A74(u8);
+
+void mapldr_080859D4(void)
+{
+ Overworld_PlaySpecialMapMusic();
+ pal_fill_for_map_transition();
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ gFieldCallback = NULL;
+ gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_13 = 1;
+ CreateTask(sub_8087A74, 0);
+}
+
+void sub_8087A74(u8 taskId)
+{
+ gUnknown_0839F388[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_8087AA4(struct Task *task)
+{
+ if (sub_807D770())
+ {
+ task->data[0]++;
+ task->data[15] = player_get_direction_lower_nybble();
+ }
+}
+
+void sub_8087AC8(struct Task *task)
+{
+ struct MapObject *mapObject;
+ u8 unknown_0839F380[5];
+ memcpy(unknown_0839F380, gUnknown_0839F380, sizeof gUnknown_0839F380);
+ 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_8087A74));
+ return;
+ }
+ FieldObjectSetSpecialAnim(mapObject, GetFaceDirectionAnimId(unknown_0839F380[mapObject->mapobj_unk_18]));
+ if (task->data[2] < 32)
+ {
+ task->data[2]++;
+ }
+ task->data[1] = task->data[2] >> 2;
+ }
+ mapObject->mapobj_bit_13 ^= 1;
+}
+
+void sub_8087BBC(u8);
+void mapldr_08085D88(void);
+
+void sub_8087BA8(void)
+{
+ CreateTask(sub_8087BBC, 0);
+}
+
+void sub_8087BBC(u8 taskId)
+{
+ gUnknown_0839F390[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_8087BEC(struct Task *task)
+{
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ CameraObjectReset2();
+ task->data[15] = player_get_direction_lower_nybble();
+ task->data[0]++;
+}
+
+void sub_8087C14(struct Task *task)
+{
+ struct MapObject *mapObject;
+ u8 unknown_0839F380[5];
+ memcpy(unknown_0839F380, gUnknown_0839F380, sizeof gUnknown_0839F380);
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (task->data[1] == 0 || (--task->data[1]) == 0)
+ {
+ FieldObjectTurn(mapObject, unknown_0839F380[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);
+ }
+}
+
+void sub_8087CA4(struct Task *task)
+{
+ struct MapObject *mapObject;
+ struct Sprite *sprite;
+ u8 unknown_0839F380[5];
+ memcpy(unknown_0839F380, gUnknown_0839F380, sizeof gUnknown_0839F380);
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ sprite = &gSprites[gPlayerAvatar.spriteId];
+ if ((--task->data[1]) <= 0)
+ {
+ task->data[1] = 4;
+ FieldObjectTurn(mapObject, unknown_0839F380[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]++;
+ sub_8053FF8();
+ fade_8080918();
+ }
+}
+
+void sub_8087D78(struct Task *task)
+{
+ if (!gPaletteFade.active && sub_8054034() == TRUE)
+ {
+ Overworld_SetWarpDestToLastHealLoc();
+ warp_in();
+ SetMainCallback2(CB2_LoadMap);
+ gFieldCallback = mapldr_08085D88;
+ DestroyTask(FindTaskIdByFunc(sub_8087BBC));
+ }
+}
+
+void sub_8087E1C(u8);
+
+void mapldr_08085D88(void)
+{
+ Overworld_PlaySpecialMapMusic();
+ pal_fill_for_map_transition();
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ gFieldCallback = NULL;
+ gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_13 = 1;
+ CameraObjectReset2();
+ CreateTask(sub_8087E1C, 0);
+}
+
+void sub_8087E1C(u8 taskId)
+{
+ gUnknown_0839F3A0[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_8087E4C(struct Task *task)
+{
+ struct Sprite *sprite;
+ s16 centerToCornerVecY;
+ if (sub_807D770())
+ {
+ 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_8087ED8(struct Task *task)
+{
+ u8 unknown_0839F380[5];
+ struct MapObject *mapObject;
+ struct Sprite *sprite;
+ memcpy(unknown_0839F380, gUnknown_0839F380, sizeof gUnknown_0839F380);
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ 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, unknown_0839F380[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_8087FDC(struct Task *task)
+{
+ u8 unknown_0839F380[5];
+ struct MapObject *mapObject;
+ memcpy(unknown_0839F380, gUnknown_0839F380, sizeof gUnknown_0839F380);
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if ((--task->data[1]) == 0)
+ {
+ FieldObjectTurn(mapObject, unknown_0839F380[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_8087E1C));
+ }
+ }
+}
+
+void sub_8088120(u8);
+void sub_808847C(u8);
+u8 sub_8088830(u32, u32, u32);
+void sub_80883DC(void);
+void sub_808843C(u16);
+void sub_8088890(struct Sprite *);
+
+bool8 FldEff_FieldMoveShowMon(void)
+{
+ u8 taskId;
+ if (is_map_type_1_2_3_5_or_6(Overworld_GetMapTypeOfSaveblockLocation()) == TRUE)
+ {
+ taskId = CreateTask(sub_8088120, 0xff);
+ } else
+ {
+ taskId = CreateTask(sub_808847C, 0xff);
+ }
+ gTasks[taskId].data[15] = sub_8088830(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 sub_8088120(u8 taskId)
+{
+ gUnknown_0839F3AC[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_8088150(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;
+ REG_WIN0H = task->data[1];
+ REG_WIN0V = task->data[2];
+ REG_WININ = task->data[3];
+ REG_WINOUT = task->data[4];
+ SetVBlankCallback(sub_80883DC);
+ task->data[0]++;
+}
+
+void sub_80881C0(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_808843C(delta);
+ task->data[0]++;
+}
+
+void sub_8088228(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_8088890;
+ task->data[0]++;
+ }
+}
+
+void sub_80882B4(struct Task *task)
+{
+ task->data[5] -= 16;
+ if (gSprites[task->data[15]].data7)
+ {
+ task->data[0]++;
+ }
+}
+
+void sub_80882E4(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_8088338(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 sub_8088380(struct Task *task)
+{
+ IntrCallback callback;
+ LoadWordFromTwoHalfwords((u16 *)&task->data[13], (u32 *)&callback);
+ SetVBlankCallback(callback);
+ SetUpWindowConfig(&gWindowConfig_81E6CE4);
+ InitMenuWindow(&gWindowConfig_81E6CE4);
+ FreeResourcesAndDestroySprite(&gSprites[task->data[15]]);
+ FieldEffectActiveListRemove(FLDEFF_FIELD_MOVE_SHOW_MON);
+ DestroyTask(FindTaskIdByFunc(sub_8088120));
+}
+
+void sub_80883DC(void)
+{
+ struct Task *task;
+ IntrCallback callback;
+ task = &gTasks[FindTaskIdByFunc(sub_8088120)];
+ LoadWordFromTwoHalfwords((u16 *)&task->data[13], (u32 *)&callback);
+ callback();
+ REG_WIN0H = task->data[1];
+ REG_WIN0V = task->data[2];
+ REG_WININ = task->data[3];
+ REG_WINOUT = task->data[4];
+ REG_BG0HOFS = task->data[5];
+ REG_BG0VOFS = task->data[6];
+}
+
+void sub_808843C(u16 offs)
+{
+ u16 i;
+ u16 *dest;
+ dest = (u16 *)(VRAM + 0x140 + offs);
+ for (i=0; i<0x140; i++, dest++)
+ {
+ *dest = gFieldMoveStreaksTilemap[i] | 0xf000;
+ }
+}
+
+void sub_80886B0(void);
+bool8 sub_8088708(struct Task *);
+void sub_80886F8(struct Task *);
+bool8 sub_80887C0(struct Task *);
+
+void sub_808847C(u8 taskId)
+{
+ gUnknown_0839F3C8[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_80884AC(struct Task *task)
+{
+ REG_BG0HOFS = task->data[1];
+ REG_BG0VOFS = task->data[2];
+ StoreWordInTwoHalfwords((u16 *)&task->data[13], (u32)gMain.vblankCallback);
+ SetVBlankCallback(sub_80886B0);
+ task->data[0]++;
+}
+
+void sub_80884E8(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_8088554(struct Task *task)
+{
+ if (sub_8088708(task))
+ {
+ REG_WIN1H = 0x00f0;
+ REG_WIN1V = 0x2878;
+ gSprites[task->data[15]].callback = sub_8088890;
+ task->data[0]++;
+ }
+ sub_80886F8(task);
+}
+
+void sub_80885A8(struct Task *task)
+{
+ sub_80886F8(task);
+ if (gSprites[task->data[15]].data7)
+ {
+ task->data[0]++;
+ }
+}
+
+void sub_80885D8(struct Task *task)
+{
+ sub_80886F8(task);
+ task->data[3] = task->data[1] & 7;
+ task->data[4] = 0;
+ REG_WIN1H = 0xffff;
+ REG_WIN1V = 0xffff;
+ task->data[0]++;
+}
+
+void sub_808860C(struct Task *task)
+{
+ sub_80886F8(task);
+ if (sub_80887C0(task))
+ {
+ task->data[0]++;
+ }
+}
+
+void sub_808862C(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);
+ SetUpWindowConfig(&gWindowConfig_81E6CE4);
+ InitMenuWindow(&gWindowConfig_81E6CE4);
+ FreeResourcesAndDestroySprite(&gSprites[task->data[15]]);
+ FieldEffectActiveListRemove(FLDEFF_FIELD_MOVE_SHOW_MON);
+ DestroyTask(FindTaskIdByFunc(sub_808847C));
+}
+
+void sub_80886B0(void)
+{
+ IntrCallback intrCallback;
+ struct Task *task;
+ task = &gTasks[FindTaskIdByFunc(sub_808847C)];
+ LoadWordFromTwoHalfwords((u16 *)&task->data[13], (u32 *)&intrCallback);
+ intrCallback();
+ REG_BG0HOFS = task->data[1];
+ REG_BG0VOFS = task->data[2];
+}
+
+void sub_80886F8(struct Task *task)
+{
+ task->data[1] -= 16;
+ task->data[3] += 16;
+}
+
+#ifdef NONMATCHING
+bool8 sub_8088708(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
+__attribute__((naked))
+bool8 sub_8088708(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_80887C0(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_8088830(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->data0 = a0;
+ sprite->data6 = v0;
+ return monSprite;
+}
+
+void sub_80888D4(struct Sprite *);
+
+void sub_8088890(struct Sprite *sprite)
+{
+ if ((sprite->pos1.x -= 20) <= 0x78)
+ {
+ sprite->pos1.x = 0x78;
+ sprite->data1 = 30;
+ sprite->callback = sub_80888D4;
+ if (sprite->data6)
+ {
+ PlayCry2(sprite->data0, 0, 0x7d, 0xa);
+ } else
+ {
+ PlayCry1(sprite->data0, 0);
+ }
+ }
+}
+
+void sub_80888F0(struct Sprite *);
+
+void sub_80888D4(struct Sprite *sprite)
+{
+ if ((--sprite->data1) == 0)
+ {
+ sprite->callback = sub_80888F0;
+ }
+}
+
+void sub_80888F0(struct Sprite *sprite)
+{
+ if (sprite->pos1.x < -0x40)
+ {
+ sprite->data7 = 1;
+ } else
+ {
+ sprite->pos1.x -= 20;
+ }
+}
+
+void sub_8088954(u8);
+
+u8 FldEff_UseSurf(void)
+{
+ u8 taskId;
+ taskId = CreateTask(sub_8088954, 0xff);
+ gTasks[taskId].data[15] = gFieldEffectArguments[0];
+ Overworld_ClearSavedMusic();
+ Overworld_ChangeMusicTo(0x016d);
+ return FALSE;
+}
+
+void sub_8088954(u8 taskId)
+{
+ gUnknown_0839F3E4[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_8088984(struct Task *task)
+{
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ gPlayerAvatar.unk6 = 1;
+ 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_80889E4(struct Task *task)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(mapObject) || FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ sub_8059BF4();
+ FieldObjectSetSpecialAnim(mapObject, 0x39);
+ task->data[0]++;
+ }
+}
+
+void sub_8088A30(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_8088A78(struct Task *task)
+{
+ struct MapObject *mapObject;
+ if (!FieldEffectActiveListContains(FLDEFF_FIELD_MOVE_SHOW_MON))
+ {
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ sub_805B980(mapObject, GetPlayerAvatarGraphicsIdByStateId(3));
+ FieldObjectClearAnimIfSpecialAnimFinished(mapObject);
+ FieldObjectSetSpecialAnim(mapObject, sub_80608D0(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_8088AF4(struct Task *task)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ gPlayerAvatar.unk6 = 0;
+ gPlayerAvatar.flags &= 0xdf;
+ FieldObjectSetSpecialAnim(mapObject, GetFaceDirectionAnimId(mapObject->placeholder18));
+ sub_8127ED0(mapObject->mapobj_unk_1A, 1);
+ UnfreezeMapObjects();
+ ScriptContext2_Disable();
+ FieldEffectActiveListRemove(FLDEFF_USE_SURF);
+ DestroyTask(FindTaskIdByFunc(sub_8088954));
+ }
+}
+
+void sub_8088BC4(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_8088BC4;
+ sprite->data1 = gFieldEffectArguments[0];
+ PlaySE(SE_W019);
+ return spriteId;
+}
+
+void sub_8088BC4(struct Sprite *sprite)
+{
+ struct Sprite *npcSprite;
+ sprite->pos2.x = Cos(sprite->data2, 0x8c);
+ sprite->pos2.y = Sin(sprite->data2, 0x48);
+ sprite->data2 = (sprite->data2 + 4) & 0xff;
+ if (sprite->data0)
+ {
+ npcSprite = &gSprites[sprite->data1];
+ 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->data2 >= 0x80)
+ {
+ FieldEffectStop(sprite, FLDEFF_NPCFLY_OUT);
+ }
+}
+
+void sub_8088C70(u8);
+extern void sub_8127EFC(u8, u8);
+u8 sub_8088F60(void);
+bool8 sub_8088FA4(u8);
+void sub_8088FC0(u8);
+void sub_8088FFC(u8, u8);
+void sub_8089018(struct Sprite *);
+void sub_80890D8(struct Sprite *);
+
+u8 FldEff_UseFly(void)
+{
+ u8 taskId;
+ taskId = CreateTask(sub_8088C70, 0xfe);
+ gTasks[taskId].data[1] = gFieldEffectArguments[0];
+ return 0;
+}
+
+void sub_8088C70(u8 taskId)
+{
+ gUnknown_0839F3F8[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_8088CA0(struct Task *task)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(mapObject) || FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ task->data[15] = gPlayerAvatar.flags;
+ gPlayerAvatar.unk6 = 0x01;
+ SetPlayerAvatarStateMask(1);
+ sub_8059BF4();
+ FieldObjectSetSpecialAnim(mapObject, 0x39);
+ task->data[0]++;
+ }
+}
+
+void sub_8088CF8(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_8088D3C(struct Task *task)
+{
+ struct MapObject *mapObject;
+ if (!FieldEffectActiveListContains(FLDEFF_FIELD_MOVE_SHOW_MON))
+ {
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (task->data[15] & 0x08)
+ {
+ sub_8127ED0(mapObject->mapobj_unk_1A, 2);
+ sub_8127EFC(mapObject->mapobj_unk_1A, 0);
+ }
+ task->data[1] = sub_8088F60();
+ task->data[0]++;
+ }
+}
+
+void sub_8088D94(struct Task *task)
+{
+ if (sub_8088FA4(task->data[1]))
+ {
+ task->data[0]++;
+ task->data[2] = 16;
+ SetPlayerAvatarTransitionFlags(0x01);
+ FieldObjectSetSpecialAnim(&gMapObjects[gPlayerAvatar.mapObjectId], 0x02);
+ }
+}
+
+void sub_8088DD8(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_8088FC0(task->data[1]);
+ }
+}
+
+void sub_8088E2C(struct Task *task)
+{
+ struct MapObject *mapObject;
+ if ((++task->data[2]) >= 8)
+ {
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ sub_805B980(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_8088EB4(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_8088FFC(task->data[1], mapObject->spriteId);
+ CameraObjectReset2();
+ task->data[0]++;
+ }
+}
+
+void sub_8088F10(struct Task *task)
+{
+ if (sub_8088FA4(task->data[1]))
+ {
+ fade_8080918();
+ task->data[0]++;
+ }
+}
+
+void sub_8088F30(struct Task *task)
+{
+ if (!gPaletteFade.active)
+ {
+ FieldEffectActiveListRemove(FLDEFF_USE_FLY);
+ DestroyTask(FindTaskIdByFunc(sub_8088C70));
+ }
+}
+
+u8 sub_8088F60(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_8089018;
+ return spriteId;
+}
+
+u8 sub_8088FA4(u8 spriteId)
+{
+ return gSprites[spriteId].data7;
+}
+
+void sub_8088FC0(u8 spriteId)
+{
+ struct Sprite *sprite;
+ sprite = &gSprites[spriteId];
+ sprite->callback = sub_80890D8;
+ sprite->pos1.x = 0x78;
+ sprite->pos1.y = 0x00;
+ sprite->pos2.x = 0;
+ sprite->pos2.y = 0;
+ memset(&sprite->data0, 0, 8 * sizeof(u16) /* zero all data cells */);
+ sprite->data6 = 0x40;
+}
+
+void sub_8088FFC(u8 a0, u8 a1)
+{
+ gSprites[a0].data6 = a1;
+}
+
+void sub_8089018(struct Sprite *sprite)
+{
+ if (sprite->data7 == 0)
+ {
+ if (sprite->data0 == 0)
+ {
+ sprite->oam.affineMode = 3;
+ sprite->affineAnims = gSpriteAffineAnimTable_0839F44C;
+ InitSpriteAffineAnim(sprite);
+ StartSpriteAffineAnim(sprite, 0);
+ sprite->pos1.x = 0x76;
+ sprite->pos1.y = -0x30;
+ sprite->data0++;
+ sprite->data1 = 0x40;
+ sprite->data2 = 0x100;
+ }
+ sprite->data1 += (sprite->data2 >> 8);
+ sprite->pos2.x = Cos(sprite->data1, 0x78);
+ sprite->pos2.y = Sin(sprite->data1, 0x78);
+ if (sprite->data2 < 0x800)
+ {
+ sprite->data2 += 0x60;
+ }
+ if (sprite->data1 > 0x81)
+ {
+ sprite->data7++;
+ sprite->oam.affineMode = 0;
+ FreeOamMatrix(sprite->oam.matrixNum);
+ CalcCenterToCornerVec(sprite, sprite->oam.shape, sprite->oam.size, 0);
+ }
+ }
+}
+
+void sub_80890D8(struct Sprite *sprite)
+{
+ struct Sprite *sprite1;
+ sprite->pos2.x = Cos(sprite->data2, 0x8c);
+ sprite->pos2.y = Sin(sprite->data2, 0x48);
+ sprite->data2 = (sprite->data2 + 4) & 0xff;
+ if (sprite->data6 != 0x40)
+ {
+ sprite1 = &gSprites[sprite->data6];
+ 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->data2 >= 0x80)
+ {
+ sprite->data7 = 1;
+ }
+}
+
+void sub_808914C(struct Sprite *sprite)
+{
+ if (sprite->data7 == 0)
+ {
+ if (sprite->data0 == 0)
+ {
+ sprite->oam.affineMode = 3;
+ sprite->affineAnims = gSpriteAffineAnimTable_0839F44C;
+ InitSpriteAffineAnim(sprite);
+ StartSpriteAffineAnim(sprite, 1);
+ sprite->pos1.x = 0x5e;
+ sprite->pos1.y = -0x20;
+ sprite->data0++;
+ sprite->data1 = 0xf0;
+ sprite->data2 = 0x800;
+ sprite->data4 = 0x80;
+ }
+ sprite->data1 += sprite->data2 >> 8;
+ sprite->data3 += sprite->data2 >> 8;
+ sprite->data1 &= 0xff;
+ sprite->pos2.x = Cos(sprite->data1, 0x20);
+ sprite->pos2.y = Sin(sprite->data1, 0x78);
+ if (sprite->data2 > 0x100)
+ {
+ sprite->data2 -= sprite->data4;
+ }
+ if (sprite->data4 < 0x100)
+ {
+ sprite->data4 += 24;
+ }
+ if (sprite->data2 < 0x100)
+ {
+ sprite->data2 = 0x100;
+ }
+ if (sprite->data3 >= 60)
+ {
+ sprite->data7++;
+ sprite->oam.affineMode = 0;
+ FreeOamMatrix(sprite->oam.matrixNum);
+ sprite->invisible = 1;
+ }
+ }
+}
+
+void sub_8089230(u8 spriteId)
+{
+ sub_8088FC0(spriteId);
+ gSprites[spriteId].callback = sub_808914C;
+}
+
+void sub_8089270(u8);
+
+u8 FldEff_FlyIn(void)
+{
+ CreateTask(sub_8089270, 0xfe);
+ return 0;
+}
+
+void sub_8089270(u8 taskId)
+{
+ gUnknown_0839F454[gTasks[taskId].data[0]](&gTasks[taskId]);
+}
+
+void sub_80892A0(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.unk6 = 1;
+ SetPlayerAvatarStateMask(0x01);
+ if (task->data[15] & 0x08)
+ {
+ sub_8127ED0(mapObject->mapobj_unk_1A, 0);
+ }
+ sub_805B980(mapObject, GetPlayerAvatarGraphicsIdByStateId(0x3));
+ CameraObjectReset2();
+ FieldObjectTurn(mapObject, DIR_WEST);
+ StartSpriteAnim(&gSprites[mapObject->spriteId], 0x16);
+ mapObject->mapobj_bit_13 = 0;
+ task->data[1] = sub_8088F60();
+ sub_8088FC0(task->data[1]);
+ sub_8088FFC(task->data[1], mapObject->spriteId);
+ }
+}
+
+void sub_8089354(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_8088FFC(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_80893C0(struct Task *task)
+{
+ s16 unknown_0839F470[18];
+ struct Sprite *sprite;
+ memcpy(unknown_0839F470, gUnknown_0839F470, sizeof gUnknown_0839F470);
+ sprite = &gSprites[gPlayerAvatar.spriteId];
+ sprite->pos2.y = unknown_0839F470[task->data[2]];
+ if ((++task->data[2]) >= 18)
+ {
+ task->data[0]++;
+ }
+}
+
+void sub_8089414(struct Task *task)
+{
+ struct MapObject *mapObject;
+ struct Sprite *sprite;
+ if (sub_8088FA4(task->data[1]))
+ {
+ mapObject = &gMapObjects[gPlayerAvatar.mapObjectId];
+ sprite = &gSprites[mapObject->spriteId];
+ mapObject->mapobj_bit_12 = 0;
+ sub_805C058(mapObject, mapObject->coords2.x, mapObject->coords2.y);
+ sprite->pos2.x = 0;
+ sprite->pos2.y = 0;
+ sprite->coordOffsetEnabled = 1;
+ sub_8059BF4();
+ FieldObjectSetSpecialAnim(mapObject, 0x39);
+ task->data[0]++;
+ }
+}
+
+void sub_808948C(struct Task *task)
+{
+ if (FieldObjectClearAnimIfSpecialAnimFinished(&gMapObjects[gPlayerAvatar.mapObjectId]))
+ {
+ task->data[0]++;
+ sub_8089230(task->data[1]);
+ }
+}
+
+void sub_80894C4(struct Task *task)
+{
+ if (sub_8088FA4(task->data[1]))
+ {
+ DestroySprite(&gSprites[task->data[1]]);
+ task->data[0]++;
+ task->data[1] = 0x10;
+ }
+}
+
+void fishE(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_8127ED0(mapObject->mapobj_unk_1A, 1);
+ }
+ sub_805B980(mapObject, GetPlayerAvatarGraphicsIdByStateId(state));
+ FieldObjectTurn(mapObject, DIR_SOUTH);
+ gPlayerAvatar.flags = task->data[15];
+ gPlayerAvatar.unk6 = 0;
+ FieldEffectActiveListRemove(FLDEFF_FLY_IN);
+ DestroyTask(FindTaskIdByFunc(sub_8089270));
+ }
+}
diff --git a/src/field/field_effect_helpers.c b/src/field/field_effect_helpers.c
new file mode 100644
index 000000000..2ad8bdce3
--- /dev/null
+++ b/src/field/field_effect_helpers.c
@@ -0,0 +1,1632 @@
+#include "global.h"
+#include "sprite.h"
+#include "fieldmap.h"
+#include "metatile_behavior.h"
+#include "songs.h"
+#include "sound.h"
+#include "field_map_obj.h"
+#include "field_camera.h"
+#include "field_map_obj_helpers.h"
+#include "field_weather.h"
+#include "field_effect.h"
+#include "field_ground_effect.h"
+#include "field_effect_helpers.h"
+
+static void sub_81269E0(struct Sprite *);
+static void npc_pal_op(struct MapObject *mapObject, struct Sprite *sprite);
+static void npc_pal_op_A(struct MapObject *, u8);
+static void npc_pal_op_B(struct MapObject *, u8);
+static void sub_81275A0(struct Sprite *);
+static void sub_81275C4(struct Sprite *);
+static void sub_8127DA0(struct Sprite *);
+static void sub_8127DD0(struct Sprite *);
+static void sub_8127E30(struct Sprite *);
+static void sub_812882C(struct Sprite *, u8, u8);
+static void sub_81278D8(struct Sprite *);
+static void sub_8127FD4(struct MapObject *, struct Sprite *);
+static void sub_812800C(struct MapObject *, struct Sprite *);
+static void sub_81280A0(struct MapObject *, struct Sprite *, struct Sprite *);
+static void sub_8128174(struct Sprite *);
+static u32 ShowDisguiseFieldEffect(u8, u8, u8);
+
+const u8 UnusedEggString_8401E28[] = _("タマゴ");
+
+const u16 gUnknown_08401E2C[] = {
+ 0x0c,
+ 0x1c,
+ 0x2c
+};
+
+const u8 gUnknown_08401E32[] = {
+ 0,
+ 1,
+ 2,
+ 3
+};
+
+const u16 gUnknown_08401E36[] = {
+ 4,
+ 4,
+ 4,
+ 16
+};
+
+void (*const gUnknown_08401E40[])(struct Sprite *) = {
+ sub_81275A0,
+ sub_81275C4
+};
+
+void (*const gUnknown_08401E48[])(struct Sprite *) = {
+ sub_8127DA0,
+ sub_8127DD0,
+ sub_8127E30
+};
+
+const u8 gUnknown_08401E54[] = {
+ 0,
+ 0,
+ 1,
+ 2,
+ 3
+};
+
+const u16 gUnknown_08401E5A[] = {
+ 3,
+ 7
+};
+
+void SetUpReflection(struct MapObject *mapObject, struct Sprite *sprite, bool8 flag)
+{
+ struct Sprite *newSprite;
+
+ newSprite = &gSprites[obj_unfreeze(sprite, sprite->pos1.x, sprite->pos1.y, 0x98)];
+ newSprite->callback = sub_81269E0;
+ newSprite->oam.priority = 3;
+ newSprite->oam.paletteNum = gUnknown_0830FD14[newSprite->oam.paletteNum];
+ newSprite->usingSheet = TRUE;
+ newSprite->anims = gDummySpriteAnimTable;
+ StartSpriteAnim(newSprite, 0);
+ newSprite->affineAnims = gDummySpriteAffineAnimTable;
+ newSprite->affineAnimBeginning = TRUE;
+ newSprite->subspriteMode = 0;
+ newSprite->data0 = sprite->data0;
+ newSprite->data1 = mapObject->localId;
+ newSprite->data7 = flag;
+ npc_pal_op(mapObject, newSprite);
+ if (!flag)
+ {
+ newSprite->oam.affineMode = 1;
+ }
+}
+
+static s16 sub_81268D0(struct MapObject *mapObject)
+{
+ return GetFieldObjectGraphicsInfo(mapObject->graphicsId)->height - 2;
+}
+
+static void npc_pal_op(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 whichElement;
+ u16 unk_8041e2c[ARRAY_COUNT(gUnknown_08401E2C)];
+
+ memcpy(unk_8041e2c, gUnknown_08401E2C, sizeof gUnknown_08401E2C);
+ sprite->data2 = 0;
+ if (!GetFieldObjectGraphicsInfo(mapObject->graphicsId)->disableReflectionPaletteLoad && ((whichElement = sub_8057450(mapObject->mapobj_unk_1F)) || (whichElement = sub_8057450(mapObject->mapobj_unk_1E))))
+ {
+ sprite->data2 = unk_8041e2c[whichElement - 1];
+ npc_pal_op_A(mapObject, sprite->oam.paletteNum);
+ }
+ else
+ {
+ npc_pal_op_B(mapObject, sprite->oam.paletteNum);
+ }
+}
+
+static void npc_pal_op_B(struct MapObject *mapObject, u8 paletteNum)
+{
+ const struct MapObjectGraphicsInfo *graphicsInfo;
+
+ graphicsInfo = GetFieldObjectGraphicsInfo(mapObject->graphicsId);
+ if (graphicsInfo->paletteTag2 != 0x11ff)
+ {
+ if (graphicsInfo->paletteSlot == 0)
+ {
+ npc_load_two_palettes__no_record(graphicsInfo->paletteTag1, paletteNum);
+ }
+ else if (graphicsInfo->paletteSlot == 10)
+ {
+ npc_load_two_palettes__and_record(graphicsInfo->paletteTag1, paletteNum);
+ }
+ else
+ {
+ pal_patch_for_npc(npc_paltag_by_palslot(paletteNum), paletteNum);
+ }
+ sub_807D78C(paletteNum);
+ }
+}
+
+static void npc_pal_op_A(struct MapObject *mapObject, u8 paletteNum)
+{
+ const struct MapObjectGraphicsInfo *graphicsInfo;
+
+ graphicsInfo = GetFieldObjectGraphicsInfo(mapObject->graphicsId);
+ if (graphicsInfo->paletteTag2 != 0x11ff)
+ {
+ pal_patch_for_npc(graphicsInfo->paletteTag2, paletteNum);
+ sub_807D78C(paletteNum);
+ }
+}
+
+static void sub_81269E0(struct Sprite *sprite)
+{
+ struct MapObject *mapObject;
+ struct Sprite *oldSprite;
+
+ mapObject = &gMapObjects[sprite->data0];
+ oldSprite = &gSprites[mapObject->spriteId];
+ if (!mapObject->active || !mapObject->mapobj_bit_17 || mapObject->localId != sprite->data1)
+ {
+ sprite->inUse = FALSE;
+ }
+ else
+ {
+ sprite->oam.paletteNum = gUnknown_0830FD14[oldSprite->oam.paletteNum];
+ sprite->oam.shape = oldSprite->oam.shape;
+ sprite->oam.size = oldSprite->oam.size;
+ sprite->oam.matrixNum = oldSprite->oam.matrixNum | 0x10;
+ sprite->oam.tileNum = oldSprite->oam.tileNum;
+ sprite->subspriteTables = oldSprite->subspriteTables;
+ sprite->subspriteTableNum = oldSprite->subspriteTableNum;
+ sprite->invisible = oldSprite->invisible;
+ sprite->pos1.x = oldSprite->pos1.x;
+ sprite->pos1.y = oldSprite->pos1.y + sub_81268D0(mapObject) + sprite->data2;
+ sprite->centerToCornerVecX = oldSprite->centerToCornerVecX;
+ sprite->centerToCornerVecY = oldSprite->centerToCornerVecY;
+ sprite->pos2.x = oldSprite->pos2.x;
+ sprite->pos2.y = -oldSprite->pos2.y;
+ sprite->coordOffsetEnabled = oldSprite->coordOffsetEnabled;
+ if (sprite->data7 == FALSE)
+ {
+ sprite->oam.matrixNum = 0;
+ if (oldSprite->oam.matrixNum & 0x8)
+ {
+ sprite->oam.matrixNum = 1;
+ }
+ }
+ }
+}
+
+u8 sub_8126B54(void)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[8] /*gFieldEffectSpriteTemplate_Arrow*/, 0, 0, 0x52);
+ if (spriteId != MAX_SPRITES)
+ {
+ sprite = &gSprites[spriteId];
+ sprite->oam.priority = 1;
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->invisible = TRUE;
+ }
+ return spriteId;
+}
+
+void objid_set_invisible(u8 spriteId)
+{
+ gSprites[spriteId].invisible = TRUE;
+}
+
+void sub_8126BC4(u8 spriteId, u8 animNum, s16 x, s16 y)
+{
+ s16 x2;
+ s16 y2;
+ struct Sprite *sprite;
+
+ sprite = &gSprites[spriteId];
+ if (sprite->invisible || sprite->data0 != x || sprite->data1 != y)
+ {
+ sub_80603CC(x, y, &x2, &y2);
+ sprite = &gSprites[spriteId];
+ sprite->pos1.x = x2 + 8;
+ sprite->pos1.y = y2 + 8;
+ sprite->invisible = FALSE;
+ sprite->data0 = x;
+ sprite->data1 = y;
+ StartSpriteAnim(sprite, animNum - 1);
+ }
+}
+
+u32 FldEff_Shadow(void)
+{
+ u8 mapObjectId;
+ const struct MapObjectGraphicsInfo *graphicsInfo;
+ u8 spriteId;
+
+ mapObjectId = GetFieldObjectIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
+ graphicsInfo = GetFieldObjectGraphicsInfo(gMapObjects[mapObjectId].graphicsId);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[gUnknown_08401E32[graphicsInfo->shadowSize]], 0, 0, 0x94);
+ if (spriteId != MAX_SPRITES)
+ {
+ gSprites[spriteId].coordOffsetEnabled = TRUE;
+ gSprites[spriteId].data0 = gFieldEffectArguments[0];
+ gSprites[spriteId].data1 = gFieldEffectArguments[1];
+ gSprites[spriteId].data2 = gFieldEffectArguments[2];
+ gSprites[spriteId].data3 = (graphicsInfo->height >> 1) - gUnknown_08401E36[graphicsInfo->shadowSize];
+ }
+ return 0;
+}
+
+void oamc_shadow(struct Sprite *sprite)
+{
+ u8 mapObjectId;
+ struct MapObject *mapObject;
+ struct Sprite *linkedSprite;
+
+ if (TryGetFieldObjectIdByLocalIdAndMap(sprite->data0, sprite->data1, sprite->data2, &mapObjectId))
+ {
+ FieldEffectStop(sprite, FLDEFF_SHADOW);
+ }
+ else
+ {
+ mapObject = &gMapObjects[mapObjectId];
+ linkedSprite = &gSprites[mapObject->spriteId];
+ sprite->oam.priority = linkedSprite->oam.priority;
+ sprite->pos1.x = linkedSprite->pos1.x;
+ sprite->pos1.y = linkedSprite->pos1.y + sprite->data3;
+ if (!mapObject->active || !mapObject->mapobj_bit_22 || MetatileBehavior_IsPokeGrass(mapObject->mapobj_unk_1E) || MetatileBehavior_IsSurfableWaterOrUnderwater(mapObject->mapobj_unk_1E) || MetatileBehavior_IsSurfableWaterOrUnderwater(mapObject->mapobj_unk_1F) || MetatileBehavior_IsReflective(mapObject->mapobj_unk_1E) || MetatileBehavior_IsReflective(mapObject->mapobj_unk_1F))
+ {
+ FieldEffectStop(sprite, FLDEFF_SHADOW);
+ }
+ }
+}
+
+u32 FldEff_TallGrass(void)
+{
+ s16 x;
+ s16 y;
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ x = gFieldEffectArguments[0];
+ y = gFieldEffectArguments[1];
+ sub_8060470(&x, &y, 8, 8);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[4], x, y, 0);
+ if (spriteId != MAX_SPRITES)
+ {
+ sprite = &gSprites[spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->oam.priority = gFieldEffectArguments[3];
+ sprite->data0 = gFieldEffectArguments[2];
+ sprite->data1 = gFieldEffectArguments[0];
+ sprite->data2 = gFieldEffectArguments[1];
+ sprite->data3 = gFieldEffectArguments[4];
+ sprite->data4 = gFieldEffectArguments[5];
+ sprite->data5 = gFieldEffectArguments[6];
+ if (gFieldEffectArguments[7])
+ {
+ SeekSpriteAnim(sprite, 4);
+ }
+ }
+ return 0;
+}
+
+void unc_grass_normal(struct Sprite *sprite)
+{
+ u8 mapNum;
+ u8 mapGroup;
+ u8 metatileBehavior;
+ u8 localId;
+ u8 mapObjectId;
+ struct MapObject *mapObject;
+
+ mapNum = sprite->data5 >> 8;
+ mapGroup = sprite->data5;
+ if (gCamera.field_0 && (gSaveBlock1.location.mapNum != mapNum || gSaveBlock1.location.mapGroup != mapGroup))
+ {
+ sprite->data1 -= gCamera.x;
+ sprite->data2 -= gCamera.y;
+ sprite->data5 = ((u8)gSaveBlock1.location.mapNum << 8) | (u8)gSaveBlock1.location.mapGroup;
+ }
+ localId = sprite->data3 >> 8;
+ mapNum = sprite->data3;
+ mapGroup = sprite->data4;
+ metatileBehavior = MapGridGetMetatileBehaviorAt(sprite->data1, sprite->data2);
+ if (TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId) || !MetatileBehavior_IsTallGrass(metatileBehavior) || (sprite->data7 && sprite->animEnded))
+ {
+ FieldEffectStop(sprite, FLDEFF_TALL_GRASS);
+ }
+ else
+ {
+ mapObject = &gMapObjects[mapObjectId];
+ if ((mapObject->coords2.x != sprite->data1 || mapObject->coords2.y != sprite->data2) && (mapObject->coords3.x != sprite->data1 || mapObject->coords3.y != sprite->data2))
+ {
+ sprite->data7 = TRUE;
+ }
+ metatileBehavior = 0;
+ if (sprite->animCmdIndex == 0)
+ {
+ metatileBehavior = 4;
+ }
+ sub_806487C(sprite, 0);
+ sub_812882C(sprite, sprite->data0, metatileBehavior);
+ }
+}
+
+u32 FldEff_JumpTallGrass(void)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ sub_8060470((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 12);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[10], gFieldEffectArguments[0], gFieldEffectArguments[1], 0);
+ if (spriteId != MAX_SPRITES)
+ {
+ sprite = &gSprites[spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->oam.priority = gFieldEffectArguments[3];
+ sprite->data0 = gFieldEffectArguments[2];
+ sprite->data1 = 12;
+ }
+ return 0;
+}
+
+u8 sub_8126FF0(u8 localId, u8 mapNum, u8 mapGroup, s16 x, s16 y)
+{
+ struct Sprite *sprite;
+ u8 i;
+
+ for (i = 0; i < MAX_SPRITES; i ++)
+ {
+ if (gSprites[i].inUse)
+ {
+ sprite = &gSprites[i];
+ if (sprite->callback == unc_grass_normal && (x == sprite->data1 && y == sprite->data2) && (localId == (u8)(sprite->data3 >> 8) && mapNum == (sprite->data3 & 0xFF) && mapGroup == sprite->data4))
+ {
+ return i;
+ }
+ }
+ }
+ return MAX_SPRITES;
+}
+
+u32 FldEff_LongGrass(void)
+{
+ s16 x;
+ s16 y;
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ x = gFieldEffectArguments[0];
+ y = gFieldEffectArguments[1];
+ sub_8060470(&x, &y, 8, 8);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[15], x, y, 0);
+ if (spriteId != MAX_SPRITES)
+ {
+ sprite = &gSprites[spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->oam.priority = ZCoordToPriority(gFieldEffectArguments[2]);
+ sprite->data0 = gFieldEffectArguments[2];
+ sprite->data1 = gFieldEffectArguments[0];
+ sprite->data2 = gFieldEffectArguments[1];
+ sprite->data3 = gFieldEffectArguments[4];
+ sprite->data4 = gFieldEffectArguments[5];
+ sprite->data5 = gFieldEffectArguments[6];
+ if (gFieldEffectArguments[7])
+ {
+ SeekSpriteAnim(sprite, 6);
+ }
+ }
+ return 0;
+}
+
+void unc_grass_tall(struct Sprite *sprite)
+{
+ u8 mapNum;
+ u8 mapGroup;
+ u8 metatileBehavior;
+ u8 localId;
+ u8 mapObjectId;
+ struct MapObject *mapObject;
+
+ mapNum = sprite->data5 >> 8;
+ mapGroup = sprite->data5;
+ if (gCamera.field_0 && (gSaveBlock1.location.mapNum != mapNum || gSaveBlock1.location.mapGroup != mapGroup))
+ {
+ sprite->data1 -= gCamera.x;
+ sprite->data2 -= gCamera.y;
+ sprite->data5 = ((u8)gSaveBlock1.location.mapNum << 8) | (u8)gSaveBlock1.location.mapGroup;
+ }
+ localId = sprite->data3 >> 8;
+ mapNum = sprite->data3;
+ mapGroup = sprite->data4;
+ metatileBehavior = MapGridGetMetatileBehaviorAt(sprite->data1, sprite->data2);
+ if (TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId) || !MetatileBehavior_IsLongGrass(metatileBehavior) || (sprite->data7 && sprite->animEnded))
+ {
+ FieldEffectStop(sprite, FLDEFF_LONG_GRASS);
+ }
+ else
+ {
+ mapObject = &gMapObjects[mapObjectId];
+ if ((mapObject->coords2.x != sprite->data1 || mapObject->coords2.y != sprite->data2) && (mapObject->coords3.x != sprite->data1 || mapObject->coords3.y != sprite->data2))
+ {
+ sprite->data7 = TRUE;
+ }
+ sub_806487C(sprite, 0);
+ sub_812882C(sprite, sprite->data0, 0);
+ }
+}
+
+u32 FldEff_JumpLongGrass(void)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ sub_8060470((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[16], gFieldEffectArguments[0], gFieldEffectArguments[1], 0);
+ if (spriteId != MAX_SPRITES)
+ {
+ sprite = &gSprites[spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->oam.priority = gFieldEffectArguments[3];
+ sprite->data0 = gFieldEffectArguments[2];
+ sprite->data1 = 18;
+ }
+ return 0;
+}
+
+u32 FldEff_ShortGrass(void)
+{
+ u8 mapObjectId;
+ struct MapObject *mapObject;
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ mapObjectId = GetFieldObjectIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
+ mapObject = &gMapObjects[mapObjectId];
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[30], 0, 0, 0);
+ if (spriteId != MAX_SPRITES)
+ {
+ sprite = &(gSprites[spriteId]);
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->oam.priority = gSprites[mapObject->spriteId].oam.priority;
+ sprite->data0 = gFieldEffectArguments[0];
+ sprite->data1 = gFieldEffectArguments[1];
+ sprite->data2 = gFieldEffectArguments[2];
+ sprite->data3 = gSprites[mapObject->spriteId].pos1.x;
+ sprite->data4 = gSprites[mapObject->spriteId].pos1.y;
+ }
+ return 0;
+}
+
+void sub_8127334(struct Sprite *sprite)
+{
+ u8 mapObjectId;
+ s16 x;
+ s16 y;
+ const struct MapObjectGraphicsInfo *graphicsInfo;
+ struct Sprite *linkedSprite;
+
+ if (TryGetFieldObjectIdByLocalIdAndMap(sprite->data0, sprite->data1, sprite->data2, &mapObjectId) || !gMapObjects[mapObjectId].mapobj_bit_18)
+ {
+ FieldEffectStop(sprite, FLDEFF_SHORT_GRASS);
+ }
+ else
+ {
+ graphicsInfo = GetFieldObjectGraphicsInfo(gMapObjects[mapObjectId].graphicsId);
+ linkedSprite = &gSprites[gMapObjects[mapObjectId].spriteId];
+ y = linkedSprite->pos1.y;
+ x = linkedSprite->pos1.x;
+ if (x != sprite->data3 || y != sprite->data4)
+ {
+ sprite->data3 = x;
+ sprite->data4 = y;
+ if (sprite->animEnded)
+ {
+ StartSpriteAnim(sprite, 0);
+ }
+ }
+ sprite->pos1.x = x;
+ sprite->pos1.y = y;
+ sprite->pos2.y = (graphicsInfo->height >> 1) - 8;
+ sprite->subpriority = linkedSprite->subpriority - 1;
+ sprite->oam.priority = linkedSprite->oam.priority;
+ sub_806487C(sprite, linkedSprite->invisible);
+ }
+}
+
+u32 FldEff_SandFootprints(void)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ sub_8060470((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[11], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
+ if (spriteId != MAX_SPRITES)
+ {
+ sprite = &gSprites[spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->oam.priority = gFieldEffectArguments[3];
+ sprite->data7 = FLDEFF_SAND_FOOTPRINTS;
+ StartSpriteAnim(sprite, gFieldEffectArguments[4]);
+ }
+ return 0;
+}
+
+u32 FldEff_DeepSandFootprints(void)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ sub_8060470((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[23], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
+ if (spriteId != MAX_SPRITES)
+ {
+ sprite = &gSprites[spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->oam.priority = gFieldEffectArguments[3];
+ sprite->data7 = FLDEFF_DEEP_SAND_FOOTPRINTS;
+ StartSpriteAnim(sprite, gFieldEffectArguments[4]);
+ }
+ return spriteId;
+}
+
+u32 FldEff_BikeTireTracks(void)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ sub_8060470((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[27], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
+ if (spriteId != MAX_SPRITES)
+ {
+ sprite = &gSprites[spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->oam.priority = gFieldEffectArguments[3];
+ sprite->data7 = FLDEFF_BIKE_TIRE_TRACKS;
+ StartSpriteAnim(sprite, gFieldEffectArguments[4]);
+ }
+ return spriteId;
+}
+
+void sub_8127584(struct Sprite *sprite)
+{
+ gUnknown_08401E40[sprite->data0](sprite);
+}
+
+static void sub_81275A0(struct Sprite *sprite)
+{
+ if (++sprite->data1 > 40)
+ {
+ sprite->data0 = 1;
+ }
+ sub_806487C(sprite, FALSE);
+}
+
+static void sub_81275C4(struct Sprite *sprite)
+{
+ sprite->invisible ^= 1;
+ sprite->data1 ++;
+ sub_806487C(sprite, sprite->invisible);
+ if (sprite->data1 > 56)
+ {
+ FieldEffectStop(sprite, sprite->data7);
+ }
+}
+
+u32 FldEff_Splash(void)
+{
+ u8 mapObjectId;
+ struct MapObject *mapObject;
+ u8 spriteId;
+ struct Sprite *sprite;
+ const struct MapObjectGraphicsInfo *graphicsInfo;
+ struct Sprite *linkedSprite;
+
+ mapObjectId = GetFieldObjectIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
+ mapObject = &gMapObjects[mapObjectId];
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[13], 0, 0, 0);
+ if (spriteId != MAX_SPRITES)
+ {
+ graphicsInfo = GetFieldObjectGraphicsInfo(mapObject->graphicsId);
+ sprite = &gSprites[spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ linkedSprite = &gSprites[mapObject->spriteId];
+ sprite->oam.priority = linkedSprite->oam.priority;
+ sprite->data0 = gFieldEffectArguments[0];
+ sprite->data1 = gFieldEffectArguments[1];
+ sprite->data2 = gFieldEffectArguments[2];
+ sprite->pos2.y = (graphicsInfo->height >> 1) - 4;
+ PlaySE(SE_MIZU);
+ }
+ return 0;
+}
+
+void sub_81276B4(struct Sprite *sprite)
+{
+ u8 mapObjectId;
+
+ if (sprite->animEnded || TryGetFieldObjectIdByLocalIdAndMap(sprite->data0, sprite->data1, sprite->data2, &mapObjectId))
+ {
+ FieldEffectStop(sprite, FLDEFF_SPLASH);
+ }
+ else
+ {
+ sprite->pos1.x = gSprites[gMapObjects[mapObjectId].spriteId].pos1.x;
+ sprite->pos1.y = gSprites[gMapObjects[mapObjectId].spriteId].pos1.y;
+ sub_806487C(sprite, FALSE);
+ }
+}
+
+u32 FldEff_JumpSmallSplash(void)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ sub_8060470((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 12);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[14], gFieldEffectArguments[0], gFieldEffectArguments[1], 0);
+ if (spriteId != MAX_SPRITES)
+ {
+ sprite = &gSprites[spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->oam.priority = gFieldEffectArguments[3];
+ sprite->data0 = gFieldEffectArguments[2];
+ sprite->data1 = FLDEFF_JUMP_SMALL_SPLASH;
+ }
+ return 0;
+}
+
+u32 FldEff_JumpBigSplash(void)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ sub_8060470((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[12], gFieldEffectArguments[0], gFieldEffectArguments[1], 0);
+ if (spriteId != MAX_SPRITES)
+ {
+ sprite = &gSprites[spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->oam.priority = gFieldEffectArguments[3];
+ sprite->data0 = gFieldEffectArguments[2];
+ sprite->data1 = FLDEFF_JUMP_BIG_SPLASH;
+ }
+ return 0;
+}
+
+u32 FldEff_FeetInFlowingWater(void)
+{
+ u8 mapObjectId;
+ struct MapObject *mapObject;
+ u8 spriteId;
+ struct Sprite *sprite;
+ const struct MapObjectGraphicsInfo *graphicsInfo;
+
+ mapObjectId = GetFieldObjectIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
+ mapObject = &gMapObjects[mapObjectId];
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[13], 0, 0, 0);
+ if (spriteId != MAX_SPRITES)
+ {
+ graphicsInfo = GetFieldObjectGraphicsInfo(mapObject->graphicsId);
+ sprite = &gSprites[spriteId];
+ sprite->callback = sub_81278D8;
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->oam.priority = gSprites[mapObject->spriteId].oam.priority;
+ sprite->data0 = gFieldEffectArguments[0];
+ sprite->data1 = gFieldEffectArguments[1];
+ sprite->data2 = gFieldEffectArguments[2];
+ sprite->data3 = -1;
+ sprite->data4 = -1;
+ sprite->pos2.y = (graphicsInfo->height >> 1) - 4;
+ StartSpriteAnim(sprite, 1);
+ }
+ return 0;
+}
+
+static void sub_81278D8(struct Sprite *sprite)
+{
+ u8 mapObjectId;
+ struct Sprite *linkedSprite;
+ struct MapObject *mapObject;
+
+ if (TryGetFieldObjectIdByLocalIdAndMap(sprite->data0, sprite->data1, sprite->data2, &mapObjectId) || !gMapObjects[mapObjectId].mapobj_bit_19)
+ {
+ FieldEffectStop(sprite, FLDEFF_FEET_IN_FLOWING_WATER);
+ }
+ else
+ {
+ mapObject = &gMapObjects[mapObjectId];
+ linkedSprite = &gSprites[mapObject->spriteId];
+ sprite->pos1.x = linkedSprite->pos1.x;
+ sprite->pos1.y = linkedSprite->pos1.y;
+ sprite->subpriority = linkedSprite->subpriority;
+ sub_806487C(sprite, FALSE);
+ if (mapObject->coords2.x != sprite->data3 || mapObject->coords2.y != sprite->data4)
+ {
+ sprite->data3 = mapObject->coords2.x;
+ sprite->data4 = mapObject->coords2.y;
+ if (!sprite->invisible)
+ {
+ PlaySE(SE_MIZU);
+ }
+ }
+ }
+}
+
+u32 FldEff_Ripple(void)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[5], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
+ if (spriteId != MAX_SPRITES)
+ {
+ sprite = &gSprites[spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->oam.priority = gFieldEffectArguments[3];
+ sprite->data0 = FLDEFF_RIPPLE;
+ }
+ return 0;
+}
+
+u32 FldEff_HotSpringsWater(void)
+{
+ u8 mapObjectId;
+ struct MapObject *mapObject;
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ mapObjectId = GetFieldObjectIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
+ mapObject = &gMapObjects[mapObjectId];
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[31], 0, 0, 0);
+ if (spriteId != MAX_SPRITES)
+ {
+ sprite = &gSprites[spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->oam.priority = gSprites[mapObject->spriteId].oam.priority;
+ sprite->data0 = gFieldEffectArguments[0];
+ sprite->data1 = gFieldEffectArguments[1];
+ sprite->data2 = gFieldEffectArguments[2];
+ sprite->data3 = gSprites[mapObject->spriteId].pos1.x;
+ sprite->data4 = gSprites[mapObject->spriteId].pos1.y;
+ }
+ return 0;
+}
+
+void sub_8127A7C(struct Sprite *sprite)
+{
+ u8 mapObjectId;
+ const struct MapObjectGraphicsInfo *graphicsInfo;
+ struct Sprite *linkedSprite;
+
+ if (TryGetFieldObjectIdByLocalIdAndMap(sprite->data0, sprite->data1, sprite->data2, &mapObjectId) || !gMapObjects[mapObjectId].mapobj_bit_21)
+ {
+ FieldEffectStop(sprite, FLDEFF_HOT_SPRINGS_WATER);
+ }
+ else
+ {
+ graphicsInfo = GetFieldObjectGraphicsInfo(gMapObjects[mapObjectId].graphicsId);
+ linkedSprite = &gSprites[gMapObjects[mapObjectId].spriteId];
+ sprite->pos1.x = linkedSprite->pos1.x;
+ sprite->pos1.y = (graphicsInfo->height >> 1) + linkedSprite->pos1.y - 8;
+ sprite->subpriority = linkedSprite->subpriority - 1;
+ sub_806487C(sprite, FALSE);
+ }
+}
+
+u32 FldEff_Unknown19(void)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ sub_8060470((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[17], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
+ if (spriteId != MAX_SPRITES)
+ {
+ sprite = &gSprites[spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->oam.priority = gFieldEffectArguments[3];
+ sprite->data0 = FLDEFF_UNKNOWN_19;
+ }
+ return 0;
+}
+
+u32 FldEff_Unknown20(void)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ sub_8060470((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[18], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
+ if (spriteId != MAX_SPRITES)
+ {
+ sprite = &gSprites[spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->oam.priority = gFieldEffectArguments[3];
+ sprite->data0 = FLDEFF_UNKNOWN_20;
+ }
+ return 0;
+}
+
+u32 FldEff_Unknown21(void)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ sub_8060470((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[19], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
+ if (spriteId != MAX_SPRITES)
+ {
+ sprite = &gSprites[spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->oam.priority = gFieldEffectArguments[3];
+ sprite->data0 = FLDEFF_UNKNOWN_21;
+ }
+ return 0;
+}
+
+u32 FldEff_Unknown22(void)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ sub_8060470((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[20], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
+ if (spriteId != MAX_SPRITES)
+ {
+ sprite = &gSprites[spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->oam.priority = gFieldEffectArguments[3];
+ sprite->data0 = FLDEFF_UNKNOWN_22;
+ }
+ return 0;
+}
+
+void ash(s16 x, s16 y, u16 c, s16 d)
+{
+ gFieldEffectArguments[0] = x;
+ gFieldEffectArguments[1] = y;
+ gFieldEffectArguments[2] = 0x52;
+ gFieldEffectArguments[3] = 1;
+ gFieldEffectArguments[4] = c;
+ gFieldEffectArguments[5] = d;
+ FieldEffectStart(FLDEFF_ASH);
+}
+
+u32 FldEff_Ash(void)
+{
+ s16 x;
+ s16 y;
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ x = gFieldEffectArguments[0];
+ y = gFieldEffectArguments[1];
+ sub_8060470(&x, &y, 8, 8);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[6], x, y, gFieldEffectArguments[2]);
+ if (spriteId != MAX_SPRITES)
+ {
+ sprite = &gSprites[spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->oam.priority = gFieldEffectArguments[3];
+ sprite->data1 = gFieldEffectArguments[0];
+ sprite->data2 = gFieldEffectArguments[1];
+ sprite->data3 = gFieldEffectArguments[4];
+ sprite->data4 = gFieldEffectArguments[5];
+ }
+ return 0;
+}
+
+void sub_8127D84(struct Sprite *sprite)
+{
+ gUnknown_08401E48[sprite->data0](sprite);
+}
+
+static void sub_8127DA0(struct Sprite *sprite)
+{
+ sprite->invisible = TRUE;
+ sprite->animPaused = TRUE;
+ if (--sprite->data4 == 0)
+ {
+ sprite->data0 = 1;
+ }
+}
+
+static void sub_8127DD0(struct Sprite *sprite)
+{
+ sprite->invisible = FALSE;
+ sprite->animPaused = FALSE;
+ MapGridSetMetatileIdAt(sprite->data1, sprite->data2, sprite->data3);
+ CurrentMapDrawMetatileAt(sprite->data1, sprite->data2);
+ gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_2 = TRUE;
+ sprite->data0 = 2;
+}
+
+static void sub_8127E30(struct Sprite *sprite)
+{
+ sub_806487C(sprite, FALSE);
+ if (sprite->animEnded)
+ {
+ FieldEffectStop(sprite, FLDEFF_ASH);
+ }
+}
+
+u32 FldEff_SurfBlob(void)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ sub_8060470((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[7], gFieldEffectArguments[0], gFieldEffectArguments[1], 0x96);
+ if (spriteId !=MAX_SPRITES)
+ {
+ sprite = &gSprites[spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->oam.paletteNum = 0;
+ sprite->data2 = gFieldEffectArguments[2];
+ sprite->data3 = -1;
+ sprite->data6 = -1;
+ sprite->data7 = -1;
+ }
+ FieldEffectActiveListRemove(FLDEFF_SURF_BLOB);
+ return spriteId;
+}
+
+void sub_8127ED0(u8 spriteId, u8 value)
+{
+ gSprites[spriteId].data0 = (gSprites[spriteId].data0 & ~0xF) | (value & 0xF);
+}
+
+void sub_8127EFC(u8 spriteId, u8 value)
+{
+ gSprites[spriteId].data0 = (gSprites[spriteId].data0 & ~0xF0) | ((value & 0xF) << 4);
+}
+
+void sub_8127F28(u8 spriteId, u8 value, s16 data1)
+{
+ gSprites[spriteId].data0 = (gSprites[spriteId].data0 & ~0xF00) | ((value & 0xF) << 8);
+ gSprites[spriteId].data1 = data1;
+}
+
+static u8 sub_8127F5C(struct Sprite *sprite)
+{
+ return sprite->data0 & 0xF;
+}
+
+static u8 sub_8127F64(struct Sprite *sprite)
+{
+ return (sprite->data0 & 0xF0) >> 4;
+}
+
+static u8 sub_8127F70(struct Sprite *sprite)
+{
+ return (sprite->data0 & 0xF00) >> 8;
+}
+
+void sub_8127F7C(struct Sprite *sprite)
+{
+ struct MapObject *mapObject;
+ struct Sprite *linkedSprite;
+
+ mapObject = &gMapObjects[sprite->data2];
+ linkedSprite = &gSprites[mapObject->spriteId];
+ sub_8127FD4(mapObject, sprite);
+ sub_812800C(mapObject, sprite);
+ sub_81280A0(mapObject, linkedSprite, sprite);
+ sprite->oam.priority = linkedSprite->oam.priority;
+}
+
+static void sub_8127FD4(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 unk_8041E54[ARRAY_COUNT(gUnknown_08401E54)];
+
+ memcpy(unk_8041E54, gUnknown_08401E54, sizeof gUnknown_08401E54);
+ if (sub_8127F64(sprite) == 0)
+ {
+ StartSpriteAnimIfDifferent(sprite, unk_8041E54[mapObject->placeholder18]);
+ }
+}
+
+#ifdef NONMATCHING
+static void sub_812800C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ s16 x;
+ s16 y;
+ u8 i;
+
+ x = mapObject->coords2.x;
+ y = mapObject->coords2.y;
+ if (sprite->pos2.y == 0 && (x != sprite->data6 || y != sprite->data7))
+ {
+ sprite->data5 = sprite->pos2.y;
+ for (sprite->data6 = x, sprite->data7 = y, i = DIR_SOUTH; i <= DIR_EAST; i ++, x = sprite->data6, y = sprite->data7)
+ {
+ MoveCoords(i, &x, &y);
+ if (MapGridGetZCoordAt(x, y) == 3)
+ {
+ sprite->data5 ++;
+ break;
+ }
+ }
+ }
+}
+#else
+__attribute__((naked)) static void sub_812800C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ asm_unified("\tpush {r4-r7,lr}\n"
+ "\tmov r7, r8\n"
+ "\tpush {r7}\n"
+ "\tsub sp, 0x4\n"
+ "\tadds r4, r1, 0\n"
+ "\tldrh r2, [r0, 0x10]\n"
+ "\tmov r1, sp\n"
+ "\tstrh r2, [r1]\n"
+ "\tldrh r1, [r0, 0x12]\n"
+ "\tmov r0, sp\n"
+ "\tadds r0, 0x2\n"
+ "\tstrh r1, [r0]\n"
+ "\tmovs r2, 0x26\n"
+ "\tldrsh r3, [r4, r2]\n"
+ "\tmov r8, r0\n"
+ "\tcmp r3, 0\n"
+ "\tbne _08128094\n"
+ "\tmov r0, sp\n"
+ "\tmovs r5, 0\n"
+ "\tldrsh r2, [r0, r5]\n"
+ "\tmovs r5, 0x3A\n"
+ "\tldrsh r0, [r4, r5]\n"
+ "\tcmp r2, r0\n"
+ "\tbne _08128048\n"
+ "\tlsls r0, r1, 16\n"
+ "\tasrs r0, 16\n"
+ "\tmovs r5, 0x3C\n"
+ "\tldrsh r1, [r4, r5]\n"
+ "\tcmp r0, r1\n"
+ "\tbeq _08128094\n"
+ "_08128048:\n"
+ "\tstrh r3, [r4, 0x38]\n"
+ "\tstrh r2, [r4, 0x3A]\n"
+ "\tmov r1, r8\n"
+ "\tmovs r2, 0\n"
+ "\tldrsh r0, [r1, r2]\n"
+ "\tstrh r0, [r4, 0x3C]\n"
+ "\tmovs r5, 0x1\n"
+ "\tmov r7, r8\n"
+ "\tmov r6, sp\n"
+ "_0812805A:\n"
+ "\tadds r0, r5, 0\n"
+ "\tmov r1, sp\n"
+ "\tadds r2, r7, 0\n"
+ "\tbl MoveCoords\n"
+ "\tmovs r1, 0\n"
+ "\tldrsh r0, [r6, r1]\n"
+ "\tmovs r2, 0\n"
+ "\tldrsh r1, [r7, r2]\n"
+ "\tbl MapGridGetZCoordAt\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r0, 24\n"
+ "\tcmp r0, 0x3\n"
+ "\tbne _08128080\n"
+ "\tldrh r0, [r4, 0x38]\n"
+ "\tadds r0, 0x1\n"
+ "\tstrh r0, [r4, 0x38]\n"
+ "\tb _08128094\n"
+ "_08128080:\n"
+ "\tadds r0, r5, 0x1\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r5, r0, 24\n"
+ "\tldrh r0, [r4, 0x3A]\n"
+ "\tstrh r0, [r6]\n"
+ "\tldrh r0, [r4, 0x3C]\n"
+ "\tmov r1, r8\n"
+ "\tstrh r0, [r1]\n"
+ "\tcmp r5, 0x4\n"
+ "\tbls _0812805A\n"
+ "_08128094:\n"
+ "\tadd sp, 0x4\n"
+ "\tpop {r3}\n"
+ "\tmov r8, r3\n"
+ "\tpop {r4-r7}\n"
+ "\tpop {r0}\n"
+ "\tbx r0");
+}
+#endif
+
+static void sub_81280A0(struct MapObject *mapObject, struct Sprite *linkedSprite, struct Sprite *sprite)
+{
+ u16 unk_8401E5A[ARRAY_COUNT(gUnknown_08401E5A)];
+ u8 v0;
+
+ memcpy(unk_8401E5A, gUnknown_08401E5A, sizeof gUnknown_08401E5A);
+ v0 = sub_8127F5C(sprite);
+ if (v0 != 0)
+ {
+ if (((u16)(++ sprite->data4) & unk_8401E5A[sprite->data5]) == 0)
+ {
+ sprite->pos2.y += sprite->data3;
+ }
+ if ((sprite->data4 & 0x0F) == 0)
+ {
+ sprite->data3 = -sprite->data3;
+ }
+ if (v0 != 2)
+ {
+ if (sub_8127F70(sprite) == 0)
+ {
+ linkedSprite->pos2.y = sprite->pos2.y;
+ }
+ else
+ {
+ linkedSprite->pos2.y = sprite->data1 + sprite->pos2.y;
+ }
+ sprite->pos1.x = linkedSprite->pos1.x;
+ sprite->pos1.y = linkedSprite->pos1.y + 8;
+ }
+ }
+}
+
+u8 sub_8128124(u8 oldSpriteId)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ spriteId = CreateSpriteAtEnd(&gDummySpriteTemplate, 0, 0, -1);
+ sprite = &gSprites[spriteId];
+ sprite->callback = sub_8128174;
+ sprite->invisible = TRUE;
+ sprite->data0 = oldSpriteId;
+ sprite->data1 = 1;
+ return spriteId;
+}
+
+static void sub_8128174(struct Sprite *sprite)
+{
+ struct Sprite *oldSprite;
+
+ oldSprite = &gSprites[sprite->data0];
+ if (((sprite->data2++) & 0x03) == 0)
+ {
+ oldSprite->pos2.y += sprite->data1;
+ }
+ if ((sprite->data2 & 0x0F) == 0)
+ {
+ sprite->data1 = -sprite->data1;
+ }
+}
+
+u32 FldEff_Dust(void)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ sub_8060470((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 12);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[9], gFieldEffectArguments[0], gFieldEffectArguments[1], 0);
+ if (spriteId != MAX_SPRITES)
+ {
+ sprite = &gSprites[spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->oam.priority = gFieldEffectArguments[3];
+ sprite->data0 = gFieldEffectArguments[2];
+ sprite->data1 = 10;
+ }
+ return 0;
+}
+
+u32 FldEff_SandPile(void)
+{
+ u8 mapObjectId;
+ struct MapObject *mapObject;
+ u8 spriteId;
+ struct Sprite *sprite;
+ const struct MapObjectGraphicsInfo *graphicsInfo;
+
+ mapObjectId = GetFieldObjectIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
+ mapObject = &gMapObjects[mapObjectId];
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[29], 0, 0, 0);
+ if (spriteId != MAX_SPRITES)
+ {
+ graphicsInfo = GetFieldObjectGraphicsInfo(mapObject->graphicsId);
+ sprite = &gSprites[spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->oam.priority = gSprites[mapObject->spriteId].oam.priority;
+ sprite->data0 = gFieldEffectArguments[0];
+ sprite->data1 = gFieldEffectArguments[1];
+ sprite->data2 = gFieldEffectArguments[2];
+ sprite->data3 = gSprites[mapObject->spriteId].pos1.x;
+ sprite->data4 = gSprites[mapObject->spriteId].pos1.y;
+ sprite->pos2.y = (graphicsInfo->height >> 1) - 2;
+ SeekSpriteAnim(sprite, 2);
+ }
+ return 0;
+}
+
+void sub_81282E0(struct Sprite *sprite)
+{
+ u8 mapObjectId;
+ s16 x;
+ s16 y;
+
+ if (TryGetFieldObjectIdByLocalIdAndMap(sprite->data0, sprite->data1, sprite->data2, &mapObjectId) || !gMapObjects[mapObjectId].mapobj_bit_20)
+ {
+ FieldEffectStop(sprite, FLDEFF_SAND_PILE);
+ }
+ else
+ {
+ y = gSprites[gMapObjects[mapObjectId].spriteId].pos1.y;
+ x = gSprites[gMapObjects[mapObjectId].spriteId].pos1.x;
+ if (x != sprite->data3 || y != sprite->data4)
+ {
+ sprite->data3 = x;
+ sprite->data4 = y;
+ if (sprite->animEnded)
+ {
+ StartSpriteAnim(sprite, 0);
+ }
+ }
+ sprite->pos1.x = x;
+ sprite->pos1.y = y;
+ sprite->subpriority = gSprites[gMapObjects[mapObjectId].spriteId].subpriority;
+ sub_806487C(sprite, FALSE);
+ }
+}
+
+u32 FldEff_Bubbles(void)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ sub_8060470((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 0);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[34], gFieldEffectArguments[0], gFieldEffectArguments[1], 0x52);
+ if (spriteId != MAX_SPRITES)
+ {
+ sprite = &gSprites[spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->oam.priority = 1;
+ }
+ return 0;
+}
+
+void sub_8128410(struct Sprite *sprite)
+{
+ sprite->data0 += 0x80;
+ sprite->data0 &= 0x100;
+ sprite->pos1.y -= sprite->data0 >> 8;
+ sub_806487C(sprite, FALSE);
+ if (sprite->invisible || sprite->animEnded)
+ {
+ FieldEffectStop(sprite, FLDEFF_BUBBLES);
+ }
+}
+
+u32 FldEff_BerryTreeGrowthSparkle(void)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ sub_8060470((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 4);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[22], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
+ if (spriteId != MAX_SPRITES)
+ {
+ sprite = &gSprites[spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->oam.priority = gFieldEffectArguments[3];
+ sprite->oam.paletteNum = 5;
+ sprite->data0 = FLDEFF_BERRY_TREE_GROWTH_SPARKLE;
+ }
+ return 0;
+}
+
+u32 FldEff_TreeDisguise(void)
+{
+ return ShowDisguiseFieldEffect(FLDEFF_TREE_DISGUISE, 0x18, 0x04);
+}
+
+
+u32 FldEff_MountainDisguise(void)
+{
+ return ShowDisguiseFieldEffect(FLDEFF_MOUNTAIN_DISGUISE, 0x19, 0x03);
+}
+
+
+u32 FldEff_SandDisguise(void)
+{
+ return ShowDisguiseFieldEffect(FLDEFF_SAND_DISGUISE, 0x1C, 0x02);
+}
+
+static u32 ShowDisguiseFieldEffect(u8 fldEff, u8 templateIdx, u8 paletteNum)
+{
+ u8 spriteId;
+ struct Sprite *sprite;
+
+ if (TryGetFieldObjectIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2], &spriteId))
+ {
+ FieldEffectActiveListRemove(fldEff);
+ return MAX_SPRITES;
+ }
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[templateIdx], 0, 0, 0);
+ if (spriteId != MAX_SPRITES)
+ {
+ sprite = &gSprites[spriteId];
+ sprite->coordOffsetEnabled ++;
+ sprite->oam.paletteNum = paletteNum;
+ sprite->data1 = fldEff;
+ sprite->data2 = gFieldEffectArguments[0];
+ sprite->data3 = gFieldEffectArguments[1];
+ sprite->data4 = gFieldEffectArguments[2];
+ }
+ return spriteId;
+}
+
+void sub_81285AC(struct Sprite *sprite)
+{
+ u8 mapObjectId;
+ const struct MapObjectGraphicsInfo *graphicsInfo;
+ struct Sprite *linkedSprite;
+
+ if (TryGetFieldObjectIdByLocalIdAndMap(sprite->data2, sprite->data3, sprite->data4, &mapObjectId))
+ {
+ FieldEffectStop(sprite, sprite->data1);
+ }
+ // else {
+ graphicsInfo = GetFieldObjectGraphicsInfo(gMapObjects[mapObjectId].graphicsId);
+ linkedSprite = &gSprites[gMapObjects[mapObjectId].spriteId];
+ sprite->invisible = linkedSprite->invisible;
+ sprite->pos1.x = linkedSprite->pos1.x;
+ sprite->pos1.y = (graphicsInfo->height >> 1) + linkedSprite->pos1.y - 16;
+ sprite->subpriority = linkedSprite->subpriority - 1;
+ if (sprite->data0 == 1)
+ {
+ sprite->data0 ++;
+ StartSpriteAnim(sprite, 1);
+ }
+ if (sprite->data0 == 2 && sprite->animEnded)
+ {
+ sprite->data7 = 1;
+ }
+ if (sprite->data0 == 3)
+ {
+ FieldEffectStop(sprite, sprite->data1);
+ }
+ // }
+}
+
+void sub_812869C(struct MapObject *mapObject)
+{
+ if (mapObject->mapobj_unk_21 == 1)
+ {
+ gSprites[mapObject->mapobj_unk_1A].data0 ++;
+ }
+}
+
+bool8 sub_81286C4(struct MapObject *mapObject)
+{
+ struct Sprite *sprite;
+
+ if (mapObject->mapobj_unk_21 == 2)
+ {
+ return TRUE;
+ }
+ if (mapObject->mapobj_unk_21 == 0)
+ {
+ return TRUE;
+ }
+ sprite = &gSprites[mapObject->mapobj_unk_1A];
+ if (sprite->data7)
+ {
+ mapObject->mapobj_unk_21 = 2;
+ sprite->data0 ++;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+u32 FldEff_Sparkle(void)
+{
+ u8 spriteId;
+
+ gFieldEffectArguments[0] += 7;
+ gFieldEffectArguments[1] += 7;
+ sub_8060470((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[35], gFieldEffectArguments[0], gFieldEffectArguments[1], 0x52);
+ if (spriteId != MAX_SPRITES)
+ {
+ gSprites[spriteId].oam.priority = gFieldEffectArguments[2];
+ gSprites[spriteId].coordOffsetEnabled = TRUE;
+ }
+ return 0;
+}
+
+void sub_8128774(struct Sprite *sprite)
+{
+ if (sprite->data0 == 0)
+ {
+ if (sprite->animEnded)
+ {
+ sprite->invisible = TRUE;
+ sprite->data0 ++;
+ }
+ if (sprite->data0 == 0)
+ {
+ return;
+ }
+ }
+ if (++ sprite->data1 >= 35)
+ {
+ FieldEffectStop(sprite, FLDEFF_SPARKLE);
+ }
+}
+
+void sub_81287C4(struct Sprite *sprite)
+{
+ if (sprite->animEnded)
+ {
+ FieldEffectStop(sprite, sprite->data1);
+ }
+ else
+ {
+ sub_806487C(sprite, FALSE);
+ SetObjectSubpriorityByZCoord(sprite->data0, sprite, 0);
+ }
+}
+
+void sub_8128800(struct Sprite *sprite)
+{
+ if (sprite->animEnded)
+ {
+ FieldEffectStop(sprite, sprite->data0);
+ }
+ else
+ {
+ sub_806487C(sprite, FALSE);
+ }
+}
+
+#ifdef NONMATCHING
+static void sub_812882C(struct Sprite *sprite /*r6*/, u8 z, u8 offset)
+{
+ u8 i;
+ s16 xlo;
+ s16 xhi;
+ s16 lx;
+ s16 lyhi;
+ s16 ly;
+ s16 ylo;
+ s16 yhi;
+ struct MapObject *mapObject; // r4
+ const struct MapObjectGraphicsInfo *graphicsInfo; // destroyed
+ struct Sprite *linkedSprite; // r5
+
+ SetObjectSubpriorityByZCoord(z, sprite, offset);
+ for (i = 0; i < 16; i ++)
+ {
+ mapObject = &gMapObjects[i];
+ if (mapObject->active)
+ {
+ graphicsInfo = GetFieldObjectGraphicsInfo(mapObject->graphicsId);
+ linkedSprite = &gSprites[mapObject->spriteId];
+ xhi = sprite->pos1.x + sprite->centerToCornerVecX;
+ xlo = sprite->pos1.x - sprite->centerToCornerVecX;
+ lx = linkedSprite->pos1.x;
+ if (xhi < lx && xlo > lx)
+ {
+ lyhi = linkedSprite->pos1.y + linkedSprite->centerToCornerVecY;
+ ly = linkedSprite->pos1.y;
+ ylo = sprite->pos1.y - sprite->centerToCornerVecY;
+ yhi = ylo + linkedSprite->centerToCornerVecY;
+ if ((lyhi < yhi || lyhi < ylo) && ly > yhi)
+ {
+ if (sprite->subpriority <= linkedSprite->subpriority)
+ {
+ sprite->subpriority = linkedSprite->subpriority + 2;
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+#else
+__attribute__((naked)) static void sub_812882C(struct Sprite *sprite /*r6*/, u8 z, u8 offset)
+{
+ asm_unified("\tpush {r4-r7,lr}\n"
+ "\tadds r6, r0, 0\n"
+ "\tadds r0, r1, 0\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r0, 24\n"
+ "\tlsls r2, 24\n"
+ "\tlsrs r2, 24\n"
+ "\tadds r1, r6, 0\n"
+ "\tbl SetObjectSubpriorityByZCoord\n"
+ "\tmovs r7, 0\n"
+ "_08128842:\n"
+ "\tlsls r0, r7, 3\n"
+ "\tadds r0, r7\n"
+ "\tlsls r0, 2\n"
+ "\tldr r1, _081288DC @ =gMapObjects\n"
+ "\tadds r4, r0, r1\n"
+ "\tldrb r0, [r4]\n"
+ "\tlsls r0, 31\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _081288E4\n"
+ "\tldrb r0, [r4, 0x5]\n"
+ "\tbl GetFieldObjectGraphicsInfo\n"
+ "\tldrb r1, [r4, 0x4]\n"
+ "\tlsls r0, r1, 4\n"
+ "\tadds r0, r1\n"
+ "\tlsls r0, 2\n"
+ "\tldr r1, _081288E0 @ =gSprites\n"
+ "\tadds r5, r0, r1\n"
+ "\tadds r0, r6, 0\n"
+ "\tadds r0, 0x28\n"
+ "\tmovs r2, 0\n"
+ "\tldrsb r2, [r0, r2]\n"
+ "\tldrh r0, [r6, 0x20]\n"
+ "\tadds r1, r0, r2\n"
+ "\tsubs r0, r2\n"
+ "\tlsls r0, 16\n"
+ "\tlsrs r4, r0, 16\n"
+ "\tlsls r1, 16\n"
+ "\tasrs r1, 16\n"
+ "\tmovs r0, 0x20\n"
+ "\tldrsh r2, [r5, r0]\n"
+ "\tcmp r1, r2\n"
+ "\tbge _081288E4\n"
+ "\tlsls r0, r4, 16\n"
+ "\tasrs r0, 16\n"
+ "\tcmp r0, r2\n"
+ "\tble _081288E4\n"
+ "\tadds r0, r5, 0\n"
+ "\tadds r0, 0x29\n"
+ "\tmovs r3, 0\n"
+ "\tldrsb r3, [r0, r3]\n"
+ "\tldrh r2, [r5, 0x22]\n"
+ "\tadds r2, r3\n"
+ "\tldrh r4, [r5, 0x22]\n"
+ "\tadds r0, r6, 0\n"
+ "\tadds r0, 0x29\n"
+ "\tmovs r1, 0\n"
+ "\tldrsb r1, [r0, r1]\n"
+ "\tldrh r0, [r6, 0x22]\n"
+ "\tsubs r0, r1\n"
+ "\tlsls r0, 16\n"
+ "\tasrs r0, 16\n"
+ "\tadds r3, r0, r3\n"
+ "\tlsls r2, 16\n"
+ "\tasrs r2, 16\n"
+ "\tlsls r3, 16\n"
+ "\tasrs r3, 16\n"
+ "\tcmp r2, r3\n"
+ "\tblt _081288BC\n"
+ "\tcmp r2, r0\n"
+ "\tbge _081288E4\n"
+ "_081288BC:\n"
+ "\tlsls r0, r4, 16\n"
+ "\tasrs r0, 16\n"
+ "\tcmp r0, r3\n"
+ "\tble _081288E4\n"
+ "\tadds r2, r6, 0\n"
+ "\tadds r2, 0x43\n"
+ "\tadds r0, r5, 0\n"
+ "\tadds r0, 0x43\n"
+ "\tldrb r1, [r0]\n"
+ "\tldrb r0, [r2]\n"
+ "\tcmp r0, r1\n"
+ "\tbhi _081288E4\n"
+ "\tadds r0, r1, 0x2\n"
+ "\tstrb r0, [r2]\n"
+ "\tb _081288EE\n"
+ "\t.align 2, 0\n"
+ "_081288DC: .4byte gMapObjects\n"
+ "_081288E0: .4byte gSprites\n"
+ "_081288E4:\n"
+ "\tadds r0, r7, 0x1\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r7, r0, 24\n"
+ "\tcmp r7, 0xF\n"
+ "\tbls _08128842\n"
+ "_081288EE:\n"
+ "\tpop {r4-r7}\n"
+ "\tpop {r0}\n"
+ "\tbx r0");
+}
+#endif
diff --git a/src/field/field_fadetransition.c b/src/field/field_fadetransition.c
new file mode 100644
index 000000000..82776d18c
--- /dev/null
+++ b/src/field/field_fadetransition.c
@@ -0,0 +1,626 @@
+#include "global.h"
+#include "cable_club.h"
+#include "fieldmap.h"
+#include "field_door.h"
+#include "field_effect.h"
+#include "field_fadetransition.h"
+#include "field_map_obj.h"
+#include "field_map_obj_helpers.h"
+#include "field_player_avatar.h"
+#include "field_special_scene.h"
+#include "field_weather.h"
+#include "fldeff_flash.h"
+#include "link.h"
+#include "main.h"
+#include "map_obj_lock.h"
+#include "metatile_behavior.h"
+#include "palette.h"
+#include "overworld.h"
+#include "script.h"
+#include "songs.h"
+#include "sound.h"
+#include "start_menu.h"
+#include "task.h"
+
+void sub_8080B9C(u8);
+void task_map_chg_seq_0807E20C(u8);
+void task_map_chg_seq_0807E2CC(u8);
+void task0A_fade_n_map_maybe(u8);
+void sub_808115C(u8);
+
+void palette_bg_fill_white(void)
+{
+ CpuFastFill16(RGB_WHITE, gPlttBufferFaded, PLTT_SIZE);
+}
+
+void palette_bg_fill_black(void)
+{
+ CpuFastFill16(RGB_BLACK, gPlttBufferFaded, PLTT_SIZE);
+}
+
+void pal_fill_for_map_transition(void)
+{
+ u8 map_light = get_map_type_from_warp0();
+ switch (fade_type_for_given_maplight_pair(map_light, Overworld_GetMapTypeOfSaveblockLocation()))
+ {
+ case 0:
+ fade_screen(0, 0);
+ palette_bg_fill_black();
+ break;
+ case 1:
+ fade_screen(2, 0);
+ palette_bg_fill_white();
+ }
+}
+
+void pal_fill_black(void)
+{
+ fade_screen(0, 0);
+ palette_bg_fill_black();
+}
+
+void fade_8080918(void)
+{
+ u8 light_level = Overworld_GetMapTypeOfSaveblockLocation();
+ switch (sub_810CDB8(light_level, warp1_get_mapheader()->mapType))
+ {
+ case 0:
+ fade_screen(1, 0);
+ break;
+ case 1:
+ fade_screen(3, 0);
+ }
+}
+
+void sub_8080958(u8 arg)
+{
+ sub_8059B88(!arg);
+}
+
+void task0A_asap_script_env_2_enable_and_set_ctx_running(u8 taskID)
+{
+ if (sub_8080E70() == TRUE)
+ {
+ DestroyTask(taskID);
+ EnableBothScriptContexts();
+ }
+}
+
+void sub_8080990(void)
+{
+ ScriptContext2_Enable();
+ Overworld_PlaySpecialMapMusic();
+ pal_fill_black();
+ CreateTask(task0A_asap_script_env_2_enable_and_set_ctx_running, 10);
+}
+
+void sub_80809B0(void)
+{
+ ScriptContext2_Enable();
+ pal_fill_black();
+ CreateTask(task0A_asap_script_env_2_enable_and_set_ctx_running, 10);
+}
+
+void task_mpl_807DD60(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ task->data[1] = sub_8083664();
+ task->data[0]++;
+ break;
+ case 1:
+ if (gTasks[task->data[1]].isActive != TRUE)
+ {
+ pal_fill_for_map_transition();
+ task->data[0]++;
+ }
+ break;
+ case 2:
+ if (sub_8080E70() == TRUE)
+ {
+ ScriptContext2_Disable();
+ DestroyTask(taskId);
+ }
+ }
+}
+
+void sub_8080A3C(void)
+{
+ ScriptContext2_Enable();
+ Overworld_PlaySpecialMapMusic();
+ palette_bg_fill_black();
+ CreateTask(task_mpl_807DD60, 10);
+}
+
+void sub_8080A5C(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ sub_80084A4();
+ task->data[0]++;
+ break;
+ case 1:
+ if (sub_8007ECC())
+ {
+ pal_fill_for_map_transition();
+ task->data[0]++;
+ }
+ break;
+ case 2:
+ if (sub_8080E70() == TRUE)
+ {
+ sub_8007B14();
+ ScriptContext2_Disable();
+ DestroyTask(taskId);
+ }
+ }
+}
+
+void sub_8080AC4(void)
+{
+ ScriptContext2_Enable();
+ Overworld_PlaySpecialMapMusic();
+ palette_bg_fill_black();
+ CreateTask(sub_8080A5C, 10);
+}
+
+void sub_8080AE4(void)
+{
+ s16 x, y;
+ u8 behavior;
+ TaskFunc func;
+ PlayerGetDestCoords(&x, &y);
+ behavior = MapGridGetMetatileBehaviorAt(x, y);
+ if (MetatileBehavior_IsDoor(behavior) == TRUE)
+ func = sub_8080B9C;
+ else if (MetatileBehavior_IsNonAnimDoor(behavior) == TRUE)
+ func = task_map_chg_seq_0807E20C;
+ else
+ func = task_map_chg_seq_0807E2CC;
+ CreateTask(func, 10);
+}
+
+void mapldr_default(void)
+{
+ Overworld_PlaySpecialMapMusic();
+ pal_fill_for_map_transition();
+ sub_8080AE4();
+ ScriptContext2_Enable();
+}
+
+void sub_8080B60(void)
+{
+ Overworld_PlaySpecialMapMusic();
+ pal_fill_black();
+ sub_8080AE4();
+ ScriptContext2_Enable();
+}
+
+void sub_8080B78(void)
+{
+ Overworld_PlaySpecialMapMusic();
+ pal_fill_for_map_transition();
+ PlaySE(SE_TK_WARPOUT);
+ CreateTask(task_map_chg_seq_0807E2CC, 10);
+ ScriptContext2_Enable();
+}
+
+void sub_8080B9C(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ s16 *x = &task->data[2];
+ s16 *y = &task->data[3];
+
+ switch (task->data[0])
+ {
+ case 0:
+ sub_8080958(0);
+ FreezeMapObjects();
+ PlayerGetDestCoords(x, y);
+ FieldSetDoorOpened(*x, *y);
+ task->data[0] = 1;
+ break;
+ case 1:
+ if (sub_8080E70())
+ {
+ u8 mapObjId;
+ sub_8080958(1);
+ mapObjId = GetFieldObjectIdByLocalIdAndMap(0xFF, 0, 0);
+ FieldObjectSetSpecialAnim(&gMapObjects[mapObjId], 8);
+ task->data[0] = 2;
+ }
+ break;
+ case 2:
+ if (walkrun_is_standing_still())
+ {
+ u8 mapObjId;
+ task->data[1] = FieldAnimateDoorClose(*x, *y);
+ mapObjId = GetFieldObjectIdByLocalIdAndMap(0xFF, 0, 0);
+ FieldObjectClearAnimIfSpecialAnimFinished(&gMapObjects[mapObjId]);
+ task->data[0] = 3;
+ }
+ break;
+ case 3:
+ if (task->data[1] < 0 || gTasks[task->data[1]].isActive != TRUE)
+ {
+ UnfreezeMapObjects();
+ task->data[0] = 4;
+ }
+ break;
+ case 4:
+ ScriptContext2_Disable();
+ DestroyTask(taskId);
+ break;
+ }
+}
+
+void task_map_chg_seq_0807E20C(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ s16 *x = &task->data[2];
+ s16 *y = &task->data[3];
+
+ switch (task->data[0])
+ {
+ case 0:
+ sub_8080958(0);
+ FreezeMapObjects();
+ PlayerGetDestCoords(x, y);
+ task->data[0] = 1;
+ break;
+ case 1:
+ if (sub_8080E70())
+ {
+ u8 mapObjId;
+ sub_8080958(1);
+ mapObjId = GetFieldObjectIdByLocalIdAndMap(0xFF, 0, 0);
+ FieldObjectSetSpecialAnim(&gMapObjects[mapObjId], GetGoSpeed0AnimId(player_get_direction_lower_nybble()));
+ task->data[0] = 2;
+ }
+ break;
+ case 2:
+ if (walkrun_is_standing_still())
+ {
+ UnfreezeMapObjects();
+ task->data[0] = 3;
+ }
+ break;
+ case 3:
+ ScriptContext2_Disable();
+ DestroyTask(taskId);
+ break;
+ }
+}
+
+void task_map_chg_seq_0807E2CC(u8 taskId)
+{
+ switch (gTasks[taskId].data[0])
+ {
+ case 0:
+ FreezeMapObjects();
+ ScriptContext2_Enable();
+ gTasks[taskId].data[0]++;
+ break;
+ case 1:
+ if (sub_8080E70())
+ {
+ UnfreezeMapObjects();
+ ScriptContext2_Disable();
+ DestroyTask(taskId);
+ }
+ break;
+ }
+}
+
+void sub_8080DC4(u8 taskId)
+{
+ if (sub_8080E70() == TRUE)
+ {
+ DestroyTask(taskId);
+ CreateTask(sub_80712B4, 80);
+ }
+}
+
+void atk17_seteffectuser(void)
+{
+ pal_fill_black();
+ CreateStartMenuTask(sub_8080DC4);
+ ScriptContext2_Enable();
+}
+
+void task_mpl_807E3C8(u8 taskId)
+{
+ if (sub_8080E70() == 1)
+ {
+ ScriptContext2_Disable();
+ DestroyTask(taskId);
+ sub_8064E2C();
+ }
+}
+
+void sub_8080E28(void)
+{
+ ScriptContext2_Enable();
+ pal_fill_black();
+ CreateTask(task_mpl_807E3C8, 10);
+}
+
+void sub_8080E44(void)
+{
+ ScriptContext2_Enable();
+ Overworld_PlaySpecialMapMusic();
+ pal_fill_black();
+ CreateTask(task_mpl_807E3C8, 10);
+}
+
+bool32 sub_8080E64(void)
+{
+ return gPaletteFade.active;
+}
+
+bool32 sub_8080E70(void)
+{
+ if (sub_807D770() == TRUE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void sub_8080E88(void)
+{
+ ScriptContext2_Enable();
+ sub_8053FF8();
+ fade_8080918();
+ PlayRainSoundEffect();
+ PlaySE(SE_KAIDAN);
+ gFieldCallback = mapldr_default;
+ CreateTask(task0A_fade_n_map_maybe, 10);
+}
+
+void sp13E_warp_to_last_warp(void)
+{
+ ScriptContext2_Enable();
+ sub_8053FF8();
+ fade_8080918();
+ PlayRainSoundEffect();
+ gFieldCallback = mapldr_default;
+ CreateTask(task0A_fade_n_map_maybe, 10);
+}
+
+void sub_8080EF0(void)
+{
+ ScriptContext2_Enable();
+ gFieldCallback = mapldr_default;
+ CreateTask(sub_808115C, 10);
+}
+
+void sp13F_fall_to_last_warp(void)
+{
+ sp13E_warp_to_last_warp();
+ gFieldCallback = sub_8086748;
+}
+
+void sub_8080F2C(u8 metatileBehavior)
+{
+ ScriptContext2_Enable();
+ sub_8086A2C(metatileBehavior, 10);
+}
+
+void sub_8080F48(void)
+{
+ ScriptContext2_Enable();
+ sub_80871B8(10);
+}
+
+void sub_8080F58(void)
+{
+ ScriptContext2_Enable();
+ sub_8087654(10);
+}
+
+void sub_8080F68(void)
+{
+ ScriptContext2_Enable();
+ sub_8053FF8();
+ fade_8080918();
+ PlaySE(SE_TK_WARPIN);
+ CreateTask(task0A_fade_n_map_maybe, 10);
+ gFieldCallback = sub_8080B78;
+}
+
+void sub_8080F9C(void)
+{
+ ScriptContext2_Enable();
+ fade_8080918();
+ CreateTask(task0A_fade_n_map_maybe, 10);
+ gFieldCallback = sub_80C791C;
+}
+
+void sub_8080FC4(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ ScriptContext2_Enable();
+ task->data[0]++;
+ break;
+ case 1:
+ if (!sub_8080E64() && sub_8054034())
+ {
+ task->data[0]++;
+ }
+ break;
+ case 2:
+ warp_in();
+ SetMainCallback2(sub_8054588);
+ DestroyTask(taskId);
+ break;
+ }
+}
+
+void DoCableClubWarp(void)
+{
+ ScriptContext2_Enable();
+ sub_8053FF8();
+ fade_8080918();
+ PlaySE(SE_KAIDAN);
+ CreateTask(sub_8080FC4, 10);
+}
+
+void sub_8081050(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ switch (data[0])
+ {
+ case 0:
+ ClearLinkCallback_2();
+ fade_screen(1, 0);
+ sub_8053FF8();
+ PlaySE(SE_KAIDAN);
+ data[0]++;
+ break;
+ case 1:
+ if (!sub_8080E64() && sub_8054034())
+ {
+ sub_800832C();
+ data[0]++;
+ }
+ break;
+ case 2:
+ if (!gReceivedRemoteLinkPlayers)
+ {
+ warp_in();
+ SetMainCallback2(CB2_LoadMap);
+ DestroyTask(taskId);
+ }
+ break;
+ }
+}
+
+void sub_80810DC(void)
+{
+ CreateTask(sub_8081050, 10);
+}
+
+void task0A_fade_n_map_maybe(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ FreezeMapObjects();
+ ScriptContext2_Enable();
+ task->data[0]++;
+ break;
+ case 1:
+ if (!sub_8080E64() && sub_8054034())
+ {
+ task->data[0]++;
+ }
+ break;
+ case 2:
+ warp_in();
+ SetMainCallback2(CB2_LoadMap);
+ DestroyTask(taskId);
+ break;
+ }
+}
+
+void sub_808115C(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ s16 *x = &task->data[2];
+ s16 *y = &task->data[3];
+
+ switch (task->data[0])
+ {
+ case 0:
+ FreezeMapObjects();
+ PlayerGetDestCoords(x, y);
+ PlaySE(GetDoorSoundEffect(*x, *y - 1));
+ task->data[1] = FieldAnimateDoorOpen(*x, *y - 1);
+ task->data[0] = 1;
+ break;
+ case 1:
+ if (task->data[1] < 0 || gTasks[task->data[1]].isActive != TRUE)
+ {
+ u8 mapObjId;
+ mapObjId = GetFieldObjectIdByLocalIdAndMap(0xFF, 0, 0);
+ FieldObjectClearAnimIfSpecialAnimActive(&gMapObjects[mapObjId]);
+ mapObjId = GetFieldObjectIdByLocalIdAndMap(0xFF, 0, 0);
+ FieldObjectSetSpecialAnim(&gMapObjects[mapObjId], 9);
+ task->data[0] = 2;
+ }
+ break;
+ case 2:
+ if (walkrun_is_standing_still())
+ {
+ u8 mapObjId;
+ task->data[1] = FieldAnimateDoorClose(*x, *y - 1);
+ mapObjId = GetFieldObjectIdByLocalIdAndMap(0xFF, 0, 0);
+ FieldObjectClearAnimIfSpecialAnimFinished(&gMapObjects[mapObjId]);
+ sub_8080958(0);
+ task->data[0] = 3;
+ }
+ break;
+ case 3:
+ if (task->data[1] < 0 || gTasks[task->data[1]].isActive != TRUE)
+ {
+ task->data[0] = 4;
+ }
+ break;
+ case 4:
+ sub_8053FF8();
+ fade_8080918();
+ PlayRainSoundEffect();
+ task->data[0] = 0;
+ task->func = task0A_fade_n_map_maybe;
+ break;
+ }
+}
+
+void sub_80812C8(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ FreezeMapObjects();
+ ScriptContext2_Enable();
+ task->data[0]++;
+ break;
+ case 1:
+ if (!sub_8080E64() && sub_8054034())
+ {
+ task->data[0]++;
+ }
+ break;
+ case 2:
+ warp_in();
+ SetMainCallback2(sub_8054534);
+ DestroyTask(taskId);
+ break;
+ }
+}
+
+void sub_8081334(void)
+{
+ ScriptContext2_Enable();
+ sub_8053FF8();
+ fade_8080918();
+ PlayRainSoundEffect();
+ PlaySE(SE_KAIDAN);
+ gFieldCallback = sub_8080B60;
+ CreateTask(sub_80812C8, 10);
+}
diff --git a/src/field/field_ground_effect.c b/src/field/field_ground_effect.c
new file mode 100644
index 000000000..5af8ea3e3
--- /dev/null
+++ b/src/field/field_ground_effect.c
@@ -0,0 +1,796 @@
+#include "global.h"
+#include "field_ground_effect.h"
+#include "field_effect.h"
+#include "field_effect_helpers.h"
+#include "field_map_obj_helpers.h"
+#include "fieldmap.h"
+#include "metatile_behavior.h"
+
+static void nullsub(struct MapObject *mapObj, struct Sprite *sprite, u8);
+static void DoTracksGroundEffect_Footprints(struct MapObject *mapObj, struct Sprite *sprite, u8);
+static void DoTracksGroundEffect_BikeTireTracks(
+ struct MapObject *mapObj, struct Sprite *sprite, u8);
+void GroundEffect_SpawnOnTallGrass(struct MapObject *mapObj, struct Sprite *sprite);
+void sub_8063E94(struct MapObject *mapObj, struct Sprite *sprite);
+void sub_8063EE0(struct MapObject *mapObj, struct Sprite *sprite);
+void sub_8063F2C(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_WaterReflection(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_IceReflection(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_FlowingWater(struct MapObject *mapObj, struct Sprite *sprite);
+void sub_8063FA0(struct MapObject *mapObj, struct Sprite *sprite);
+void sub_8063FCC(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_Ripple(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_StepOnPuddle(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_SandPile(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_JumpOnTallGrass(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_JumpOnLongGrass(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_JumpOnShallowWater(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_JumpOnWater(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_JumpLandingDust(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_ShortGrass(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_HotSprings(struct MapObject *mapObj, struct Sprite *sprite);
+void GroundEffect_Seaweed(struct MapObject *mapObj, struct Sprite *sprite);
+u8 GetReflectionTypeByMetatileBehavior(u32 behavior);
+
+static void GetAllGroundEffectFlags_OnSpawn(struct MapObject *mapObj, u32 *flags)
+{
+ FieldObjectUpdateMetatileBehaviors(mapObj);
+ GetGroundEffectFlags_Reflection(mapObj, flags);
+ GetGroundEffectFlags_TallGrassOnSpawn(mapObj, flags);
+ GetGroundEffectFlags_LongGrassOnSpawn(mapObj, flags);
+ GetGroundEffectFlags_SandPile(mapObj, flags);
+ GetGroundEffectFlags_ShallowFlowingWater(mapObj, flags);
+ GetGroundEffectFlags_ShortGrass(mapObj, flags);
+ GetGroundEffectFlags_HotSprings(mapObj, flags);
+}
+
+static void GetAllGroundEffectFlags_OnBeginStep(struct MapObject *mapObj, u32 *flags)
+{
+ FieldObjectUpdateMetatileBehaviors(mapObj);
+ GetGroundEffectFlags_Reflection(mapObj, flags);
+ GetGroundEffectFlags_TallGrassOnBeginStep(mapObj, flags);
+ GetGroundEffectFlags_LongGrassOnBeginStep(mapObj, flags);
+ GetGroundEffectFlags_Tracks(mapObj, flags);
+ GetGroundEffectFlags_SandPile(mapObj, flags);
+ GetGroundEffectFlags_ShallowFlowingWater(mapObj, flags);
+ GetGroundEffectFlags_Puddle(mapObj, flags);
+ GetGroundEffectFlags_ShortGrass(mapObj, flags);
+ GetGroundEffectFlags_HotSprings(mapObj, flags);
+}
+
+static void GetAllGroundEffectFlags_OnFinishStep(struct MapObject *mapObj, u32 *flags)
+{
+ FieldObjectUpdateMetatileBehaviors(mapObj);
+ GetGroundEffectFlags_ShallowFlowingWater(mapObj, flags);
+ GetGroundEffectFlags_SandPile(mapObj, flags);
+ GetGroundEffectFlags_Puddle(mapObj, flags);
+ GetGroundEffectFlags_Ripple(mapObj, flags);
+ GetGroundEffectFlags_ShortGrass(mapObj, flags);
+ GetGroundEffectFlags_HotSprings(mapObj, flags);
+ GetGroundEffectFlags_Seaweed(mapObj, flags);
+ GetGroundEffectFlags_JumpLanding(mapObj, flags);
+}
+
+void FieldObjectUpdateMetatileBehaviors(struct MapObject *mapObj)
+{
+ mapObj->mapobj_unk_1F = MapGridGetMetatileBehaviorAt(mapObj->coords3.x, mapObj->coords3.y);
+ mapObj->mapobj_unk_1E = MapGridGetMetatileBehaviorAt(mapObj->coords2.x, mapObj->coords2.y);
+}
+
+void GetGroundEffectFlags_Reflection(struct MapObject *mapObj, u32 *flags)
+{
+ u32 reflectionFlags[2] = { 0x00000020, 0x00000010 };
+ u8 type = FieldObjectCheckForReflectiveSurface(mapObj);
+
+ if (type)
+ {
+ if (!mapObj->mapobj_bit_17)
+ {
+ mapObj->mapobj_bit_17 = 0;
+ mapObj->mapobj_bit_17 = 1;
+ *flags |= reflectionFlags[type - 1];
+ }
+ }
+ else
+ {
+ mapObj->mapobj_bit_17 = 0;
+ }
+}
+
+void GetGroundEffectFlags_TallGrassOnSpawn(struct MapObject *mapObj, u32 *flags)
+{
+ if (MetatileBehavior_IsTallGrass(mapObj->mapobj_unk_1E))
+ *flags |= 0x1;
+}
+
+void GetGroundEffectFlags_TallGrassOnBeginStep(struct MapObject *mapObj, u32 *flags)
+{
+ if (MetatileBehavior_IsTallGrass(mapObj->mapobj_unk_1E))
+ *flags |= 0x2;
+}
+
+void GetGroundEffectFlags_LongGrassOnSpawn(struct MapObject *mapObj, u32 *flags)
+{
+ if (MetatileBehavior_IsLongGrass(mapObj->mapobj_unk_1E))
+ *flags |= 0x4;
+}
+
+void GetGroundEffectFlags_LongGrassOnBeginStep(struct MapObject *mapObj, u32 *flags)
+{
+ if (MetatileBehavior_IsLongGrass(mapObj->mapobj_unk_1E))
+ *flags |= 0x8;
+}
+
+void GetGroundEffectFlags_Tracks(struct MapObject *mapObj, u32 *flags)
+{
+ if (MetatileBehavior_IsDeepSand(mapObj->mapobj_unk_1F))
+ {
+ *flags |= 0x100;
+ }
+ else if (MetatileBehavior_IsSandOrDeepSand(mapObj->mapobj_unk_1F)
+ || MetatileBehavior_IsUnusedFootprintMetatile(mapObj->mapobj_unk_1F))
+ {
+ *flags |= 0x80;
+ }
+}
+
+void GetGroundEffectFlags_SandPile(struct MapObject *mapObj, u32 *flags)
+{
+ if (MetatileBehavior_IsDeepSand(mapObj->mapobj_unk_1E)
+ && MetatileBehavior_IsDeepSand(mapObj->mapobj_unk_1F))
+ {
+ if (!mapObj->mapobj_bit_20)
+ {
+ mapObj->mapobj_bit_20 = 0;
+ mapObj->mapobj_bit_20 = 1;
+ *flags |= 0x800;
+ }
+ }
+ else
+ {
+ mapObj->mapobj_bit_20 = 0;
+ }
+}
+
+void GetGroundEffectFlags_ShallowFlowingWater(struct MapObject *mapObj, u32 *flags)
+{
+ if ((MetatileBehavior_IsShallowFlowingWater(mapObj->mapobj_unk_1E)
+ && MetatileBehavior_IsShallowFlowingWater(mapObj->mapobj_unk_1F))
+ || (MetatileBehavior_IsPacifidlogLog(mapObj->mapobj_unk_1E)
+ && MetatileBehavior_IsPacifidlogLog(mapObj->mapobj_unk_1F)))
+ {
+ if (!mapObj->mapobj_bit_19)
+ {
+ mapObj->mapobj_bit_19 = 0;
+ mapObj->mapobj_bit_19 = 1;
+ *flags |= 0x40;
+ }
+ }
+ else
+ {
+ mapObj->mapobj_bit_19 = 0;
+ }
+}
+
+void GetGroundEffectFlags_Puddle(struct MapObject *mapObj, u32 *flags)
+{
+ if (MetatileBehavior_IsPuddle(mapObj->mapobj_unk_1E)
+ && MetatileBehavior_IsPuddle(mapObj->mapobj_unk_1F))
+ {
+ *flags |= 0x400;
+ }
+}
+
+void GetGroundEffectFlags_Ripple(struct MapObject *mapObj, u32 *flags)
+{
+ if (MetatileBehavior_HasRipples(mapObj->mapobj_unk_1E))
+ *flags |= 0x200;
+}
+
+void GetGroundEffectFlags_ShortGrass(struct MapObject *mapObj, u32 *flags)
+{
+ if (MetatileBehavior_IsShortGrass(mapObj->mapobj_unk_1E)
+ && MetatileBehavior_IsShortGrass(mapObj->mapobj_unk_1F))
+ {
+ if (!mapObj->mapobj_bit_18)
+ {
+ mapObj->mapobj_bit_18 = 0;
+ mapObj->mapobj_bit_18 = 1;
+ *flags |= 0x20000;
+ }
+ }
+ else
+ {
+ mapObj->mapobj_bit_18 = 0;
+ }
+}
+
+void GetGroundEffectFlags_HotSprings(struct MapObject *mapObj, u32 *flags)
+{
+ if (MetatileBehavior_IsHotSprings(mapObj->mapobj_unk_1E)
+ && MetatileBehavior_IsHotSprings(mapObj->mapobj_unk_1F))
+ {
+ if (!mapObj->mapobj_bit_21)
+ {
+ mapObj->mapobj_bit_21 = 0;
+ mapObj->mapobj_bit_21 = 1;
+ *flags |= 0x40000;
+ }
+ }
+ else
+ {
+ mapObj->mapobj_bit_21 = 0;
+ }
+}
+
+void GetGroundEffectFlags_Seaweed(struct MapObject *mapObj, u32 *flags)
+{
+ if (MetatileBehavior_IsSeaweed(mapObj->mapobj_unk_1E))
+ *flags |= 0x80000;
+}
+
+void GetGroundEffectFlags_JumpLanding(struct MapObject *mapObj, u32 *flags)
+{
+ typedef bool8 (*MetatileFunc)(u8);
+
+ static const MetatileFunc metatileFuncs[] = {
+ MetatileBehavior_IsTallGrass,
+ MetatileBehavior_IsLongGrass,
+ MetatileBehavior_IsPuddle,
+ MetatileBehavior_IsSurfableWaterOrUnderwater,
+ MetatileBehavior_IsShallowFlowingWater,
+ MetatileBehavior_IsATile,
+ };
+
+ static const u32 jumpLandingFlags[] = {
+ 0x00001000, // Landing in tall grass
+ 0x00002000, // Landing in long grass
+ 0x00004000, // Landing on puddle
+ 0x00008000, // Landing on surfable water or underwater
+ 0x00004000, // Landing on shallow flowing water
+ 0x00010000, // Landing on any other type of ground
+ };
+
+ if (mapObj->mapobj_bit_5 && !mapObj->mapobj_bit_25)
+ {
+ u8 i;
+
+ for (i = 0; i < 6; i++)
+ {
+ if (metatileFuncs[i](mapObj->mapobj_unk_1E))
+ {
+ *flags |= jumpLandingFlags[i];
+ return;
+ }
+ }
+ }
+}
+
+u8 FieldObjectCheckForReflectiveSurface(struct MapObject *mapObj)
+{
+ const struct MapObjectGraphicsInfo *info = GetFieldObjectGraphicsInfo(mapObj->graphicsId);
+
+ // ceil div by tile width?
+ s16 width = (info->width + 8) >> 4;
+ s16 height = (info->height + 8) >> 4;
+ s16 i;
+ s16 j;
+ u8 result;
+ u8 b;
+ s16 one;
+
+#define RETURN_REFLECTION_TYPE_AT(x, y) \
+ b = MapGridGetMetatileBehaviorAt(x, y); \
+ result = GetReflectionTypeByMetatileBehavior(b); \
+ if (result != 0) \
+ return result;
+
+ for (i = 0, one = 1; i < height; i++)
+ {
+ RETURN_REFLECTION_TYPE_AT(mapObj->coords2.x, mapObj->coords2.y + one + i)
+ RETURN_REFLECTION_TYPE_AT(mapObj->coords3.x, mapObj->coords3.y + one + i)
+ for (j = 1; j < width; j++)
+ {
+ RETURN_REFLECTION_TYPE_AT(mapObj->coords2.x + j, mapObj->coords2.y + one + i)
+ RETURN_REFLECTION_TYPE_AT(mapObj->coords2.x - j, mapObj->coords2.y + one + i)
+ RETURN_REFLECTION_TYPE_AT(mapObj->coords3.x + j, mapObj->coords3.y + one + i)
+ RETURN_REFLECTION_TYPE_AT(mapObj->coords3.x - j, mapObj->coords3.y + one + i)
+ }
+ }
+ return 0;
+
+#undef RETURN_REFLECTION_TYPE_AT
+}
+
+u8 GetReflectionTypeByMetatileBehavior(u32 behavior)
+{
+ if (MetatileBehavior_IsIce(behavior))
+ return 1;
+ else if (MetatileBehavior_IsReflective(behavior))
+ return 2;
+ else
+ return 0;
+}
+
+u8 GetLedgeJumpDirection(s16 x, s16 y, u8 z)
+{
+ static bool8 (*const unknown_08376040[])(u8) = {
+ MetatileBehavior_IsJumpSouth,
+ MetatileBehavior_IsJumpNorth,
+ MetatileBehavior_IsJumpWest,
+ MetatileBehavior_IsJumpEast,
+ };
+
+ u8 b;
+ u8 index = z;
+
+ if (index == 0)
+ return 0;
+ else if (index > 4)
+ index -= 4;
+
+ index--;
+ b = MapGridGetMetatileBehaviorAt(x, y);
+
+ if (unknown_08376040[index](b) == 1)
+ return index + 1;
+
+ return 0;
+}
+
+void FieldObjectSetSpriteOamTableForLongGrass(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ if (mapObj->mapobj_bit_4)
+ return;
+
+ if (!MetatileBehavior_IsLongGrass(mapObj->mapobj_unk_1E))
+ return;
+
+ if (!MetatileBehavior_IsLongGrass(mapObj->mapobj_unk_1F))
+ return;
+
+ sprite->subspriteTableNum = 4;
+
+ if (ZCoordToPriority(mapObj->elevation) == 1)
+ sprite->subspriteTableNum = 5;
+}
+
+bool8 IsZCoordMismatchAt(u8 z, s16 x, s16 y)
+{
+ u8 mapZ;
+
+ if (z == 0)
+ return FALSE;
+
+ mapZ = MapGridGetZCoordAt(x, y);
+
+ if (mapZ == 0 || mapZ == 0xF)
+ return FALSE;
+
+ if (mapZ != z)
+ return TRUE;
+
+ return FALSE;
+}
+
+static const u8 sUnknown_08376050[] = {
+ 0x73, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x00, 0x00, 0x73
+};
+
+// Each byte corresponds to a sprite priority for a field object.
+// This is directly the inverse of gFieldObjectPriorities_08376070.
+static const u8 sFieldObjectPriorities_08376060[] = {
+ 2, 2, 2, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 0, 0, 2
+};
+
+// Each byte corresponds to a sprite priority for a field object.
+// This is the inverse of gFieldObjectPriorities_08376060.
+// 1 = Above player sprite
+// 2 = Below player sprite
+static const u8 sFieldObjectPriorities_08376070[] = {
+ 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 0, 0, 1,
+};
+
+void FieldObjectUpdateZCoordAndPriority(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ if (mapObj->mapobj_bit_26)
+ return;
+
+ FieldObjectUpdateZCoord(mapObj);
+
+ sprite->subspriteTableNum = sFieldObjectPriorities_08376070[mapObj->elevation];
+ sprite->oam.priority = sFieldObjectPriorities_08376060[mapObj->elevation];
+}
+
+void InitObjectPriorityByZCoord(struct Sprite *sprite, u8 z)
+{
+ sprite->subspriteTableNum = sFieldObjectPriorities_08376070[z];
+ sprite->oam.priority = sFieldObjectPriorities_08376060[z];
+}
+
+u8 ZCoordToPriority(u8 z)
+{
+ return sFieldObjectPriorities_08376060[z];
+}
+
+void FieldObjectUpdateZCoord(struct MapObject *mapObj)
+{
+ u8 z = MapGridGetZCoordAt(mapObj->coords2.x, mapObj->coords2.y);
+ u8 z2 = MapGridGetZCoordAt(mapObj->coords3.x, mapObj->coords3.y);
+
+ if (z == 0xF || z2 == 0xF)
+ return;
+
+ mapObj->mapobj_unk_0B_0 = z;
+
+ if (z != 0 && z != 0xF)
+ mapObj->elevation = z;
+}
+
+void SetObjectSubpriorityByZCoord(u8 a, struct Sprite *sprite, u8 b)
+{
+ s32 tmp = sprite->centerToCornerVecY;
+ u32 tmpa = *(u16 *)&sprite->pos1.y;
+ u32 tmpb = *(u16 *)&gSpriteCoordOffsetY;
+ s32 tmp2 = (tmpa - tmp) + tmpb;
+ u16 tmp3 = (0x10 - ((((u32)tmp2 + 8) & 0xFF) >> 4)) * 2;
+ sprite->subpriority = tmp3 + sUnknown_08376050[a] + b;
+}
+
+void FieldObjectUpdateSubpriority(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ if (mapObj->mapobj_bit_26)
+ return;
+
+ SetObjectSubpriorityByZCoord(mapObj->elevation, sprite, 1);
+}
+
+bool8 AreZCoordsCompatible(u8 a, u8 b)
+{
+ if (a == 0 || b == 0)
+ return TRUE;
+
+ if (a != b)
+ return FALSE;
+
+ return TRUE;
+}
+
+void GroundEffect_SpawnOnTallGrass(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ u8 *ptr;
+
+ gFieldEffectArguments[0] = mapObj->coords2.x;
+ gFieldEffectArguments[1] = mapObj->coords2.y;
+ gFieldEffectArguments[2] = mapObj->elevation;
+ gFieldEffectArguments[3] = 2;
+ gFieldEffectArguments[4] = (mapObj->localId << 8) | mapObj->mapNum;
+ gFieldEffectArguments[5] = mapObj->mapGroup;
+
+ ptr = (u8 *)&gSaveBlock1;
+ gFieldEffectArguments[6] = ((u8)gSaveBlock1.location.mapNum << 8)
+ | (u8)gSaveBlock1.location.mapGroup;
+
+ gFieldEffectArguments[7] = 1;
+ FieldEffectStart(FLDEFF_TALL_GRASS);
+}
+
+void sub_8063E94(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ u8 *ptr;
+
+ gFieldEffectArguments[0] = mapObj->coords2.x;
+ gFieldEffectArguments[1] = mapObj->coords2.y;
+ gFieldEffectArguments[2] = mapObj->elevation;
+ gFieldEffectArguments[3] = 2;
+ gFieldEffectArguments[4] = (mapObj->localId << 8) | mapObj->mapNum;
+ gFieldEffectArguments[5] = mapObj->mapGroup;
+
+ ptr = (u8 *)&gSaveBlock1;
+ gFieldEffectArguments[6] = ((u8)gSaveBlock1.location.mapNum << 8)
+ | (u8)gSaveBlock1.location.mapGroup;
+
+ gFieldEffectArguments[7] = 0;
+ FieldEffectStart(FLDEFF_TALL_GRASS);
+}
+
+void sub_8063EE0(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ u8 *ptr;
+
+ gFieldEffectArguments[0] = mapObj->coords2.x;
+ gFieldEffectArguments[1] = mapObj->coords2.y;
+ gFieldEffectArguments[2] = mapObj->elevation;
+ gFieldEffectArguments[3] = 2;
+ gFieldEffectArguments[4] = (mapObj->localId << 8) | mapObj->mapNum;
+ gFieldEffectArguments[5] = mapObj->mapGroup;
+
+ ptr = (u8 *)&gSaveBlock1;
+ gFieldEffectArguments[6] = ((u8)gSaveBlock1.location.mapNum << 8)
+ | (u8)gSaveBlock1.location.mapGroup;
+
+ gFieldEffectArguments[7] = 1;
+ FieldEffectStart(FLDEFF_LONG_GRASS);
+}
+
+void sub_8063F2C(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ u8 *ptr;
+
+ gFieldEffectArguments[0] = mapObj->coords2.x;
+ gFieldEffectArguments[1] = mapObj->coords2.y;
+ gFieldEffectArguments[2] = mapObj->elevation;
+ gFieldEffectArguments[3] = 2;
+ gFieldEffectArguments[4] = (mapObj->localId << 8) | mapObj->mapNum;
+ gFieldEffectArguments[5] = mapObj->mapGroup;
+
+ ptr = (u8 *)&gSaveBlock1;
+ gFieldEffectArguments[6] = ((u8)gSaveBlock1.location.mapNum << 8)
+ | (u8)gSaveBlock1.location.mapGroup;
+
+ gFieldEffectArguments[7] = 0;
+ FieldEffectStart(FLDEFF_LONG_GRASS);
+}
+
+void GroundEffect_WaterReflection(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ SetUpReflection(mapObj, sprite, 0);
+}
+
+void GroundEffect_IceReflection(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ SetUpReflection(mapObj, sprite, 1);
+}
+
+void GroundEffect_FlowingWater(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ oe_exec_and_other_stuff(FLDEFF_FEET_IN_FLOWING_WATER, mapObj);
+}
+
+static void (*const gUnknown_08376080[])(struct MapObject *mapObj, struct Sprite *sprite, u8 a) = {
+ nullsub, DoTracksGroundEffect_Footprints, DoTracksGroundEffect_BikeTireTracks,
+};
+
+void sub_8063FA0(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ const struct MapObjectGraphicsInfo *info = GetFieldObjectGraphicsInfo(mapObj->graphicsId);
+ gUnknown_08376080[info->tracks](mapObj, sprite, 0);
+}
+
+void sub_8063FCC(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ const struct MapObjectGraphicsInfo *info = GetFieldObjectGraphicsInfo(mapObj->graphicsId);
+ gUnknown_08376080[info->tracks](mapObj, sprite, 1);
+}
+
+static void nullsub(struct MapObject *mapObj, struct Sprite *sprite, u8 a)
+{
+}
+
+static void DoTracksGroundEffect_Footprints(struct MapObject *mapObj, struct Sprite *sprite, u8 a)
+{
+ // First half-word is a Field Effect script id. (gFieldEffectScriptPointers)
+ u16 sandFootprints_FieldEffectData[2] = {
+ FLDEFF_SAND_FOOTPRINTS,
+ FLDEFF_DEEP_SAND_FOOTPRINTS
+ };
+
+ gFieldEffectArguments[0] = mapObj->coords3.x;
+ gFieldEffectArguments[1] = mapObj->coords3.y;
+ gFieldEffectArguments[2] = 149;
+ gFieldEffectArguments[3] = 2;
+ gFieldEffectArguments[4] = mapObj->mapobj_unk_18;
+ FieldEffectStart(sandFootprints_FieldEffectData[a]);
+}
+
+static void DoTracksGroundEffect_BikeTireTracks(
+ struct MapObject *mapObj, struct Sprite *sprite, u8 a)
+{
+ // Specifies which bike track shape to show next.
+ // For example, when the bike turns from up to right, it will show
+ // a track that curves to the right.
+ // Each 4-byte row corresponds to the initial direction of the bike, and
+ // each byte in that row is for the next direction of the bike in the order
+ // of down, up, left, right.
+ static const u8 bikeTireTracks_Transitions[4][4] = {
+ 1, 2, 7, 8,
+ 1, 2, 6, 5,
+ 5, 8, 3, 4,
+ 6, 7, 3, 4,
+ };
+
+ if (mapObj->coords2.x != mapObj->coords3.x || mapObj->coords2.y != mapObj->coords3.y)
+ {
+ gFieldEffectArguments[0] = mapObj->coords3.x;
+ gFieldEffectArguments[1] = mapObj->coords3.y;
+ gFieldEffectArguments[2] = 149;
+ gFieldEffectArguments[3] = 2;
+ gFieldEffectArguments[4] =
+ bikeTireTracks_Transitions[mapObj->mapobj_unk_20][mapObj->mapobj_unk_18 - 5];
+ FieldEffectStart(FLDEFF_BIKE_TIRE_TRACKS);
+ }
+}
+
+void GroundEffect_Ripple(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ DoRippleFieldEffect(mapObj, sprite);
+}
+
+void GroundEffect_StepOnPuddle(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ oe_exec_and_other_stuff(FLDEFF_SPLASH, mapObj);
+}
+
+void GroundEffect_SandPile(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ oe_exec_and_other_stuff(FLDEFF_SAND_PILE, mapObj);
+}
+
+void GroundEffect_JumpOnTallGrass(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ u8 spriteId;
+
+ gFieldEffectArguments[0] = mapObj->coords2.x;
+ gFieldEffectArguments[1] = mapObj->coords2.y;
+ gFieldEffectArguments[2] = mapObj->elevation;
+ gFieldEffectArguments[3] = 2;
+ FieldEffectStart(FLDEFF_JUMP_TALL_GRASS);
+
+ spriteId = sub_8126FF0(
+ mapObj->localId, mapObj->mapNum, mapObj->mapGroup, mapObj->coords2.x, mapObj->coords2.y);
+
+ if (spriteId == MAX_SPRITES)
+ GroundEffect_SpawnOnTallGrass(mapObj, sprite);
+}
+
+void GroundEffect_JumpOnLongGrass(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ gFieldEffectArguments[0] = mapObj->coords2.x;
+ gFieldEffectArguments[1] = mapObj->coords2.y;
+ gFieldEffectArguments[2] = mapObj->elevation;
+ gFieldEffectArguments[3] = 2;
+ FieldEffectStart(FLDEFF_JUMP_LONG_GRASS);
+}
+
+void GroundEffect_JumpOnShallowWater(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ gFieldEffectArguments[0] = mapObj->coords2.x;
+ gFieldEffectArguments[1] = mapObj->coords2.y;
+ gFieldEffectArguments[2] = mapObj->elevation;
+ gFieldEffectArguments[3] = sprite->oam.priority;
+ FieldEffectStart(FLDEFF_JUMP_SMALL_SPLASH);
+}
+
+void GroundEffect_JumpOnWater(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ gFieldEffectArguments[0] = mapObj->coords2.x;
+ gFieldEffectArguments[1] = mapObj->coords2.y;
+ gFieldEffectArguments[2] = mapObj->elevation;
+ gFieldEffectArguments[3] = sprite->oam.priority;
+ FieldEffectStart(FLDEFF_JUMP_BIG_SPLASH);
+}
+
+void GroundEffect_JumpLandingDust(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ gFieldEffectArguments[0] = mapObj->coords2.x;
+ gFieldEffectArguments[1] = mapObj->coords2.y;
+ gFieldEffectArguments[2] = mapObj->elevation;
+ gFieldEffectArguments[3] = sprite->oam.priority;
+ FieldEffectStart(FLDEFF_DUST);
+}
+
+void GroundEffect_ShortGrass(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ oe_exec_and_other_stuff(FLDEFF_SHORT_GRASS, mapObj);
+}
+
+void GroundEffect_HotSprings(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ oe_exec_and_other_stuff(FLDEFF_HOT_SPRINGS_WATER, mapObj);
+}
+
+void GroundEffect_Seaweed(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ gFieldEffectArguments[0] = mapObj->coords2.x;
+ gFieldEffectArguments[1] = mapObj->coords2.y;
+ FieldEffectStart(FLDEFF_BUBBLES);
+}
+
+static void (*const gUnknown_083760A0[])(struct MapObject *mapObj, struct Sprite *sprite) = {
+ GroundEffect_SpawnOnTallGrass,
+ sub_8063E94,
+ sub_8063EE0,
+ sub_8063F2C,
+ GroundEffect_WaterReflection,
+ GroundEffect_IceReflection,
+ GroundEffect_FlowingWater,
+ sub_8063FA0,
+ sub_8063FCC,
+ GroundEffect_Ripple,
+ GroundEffect_StepOnPuddle,
+ GroundEffect_SandPile,
+ GroundEffect_JumpOnTallGrass,
+ GroundEffect_JumpOnLongGrass,
+ GroundEffect_JumpOnShallowWater,
+ GroundEffect_JumpOnWater,
+ GroundEffect_JumpLandingDust,
+ GroundEffect_ShortGrass,
+ GroundEffect_HotSprings,
+ GroundEffect_Seaweed
+};
+
+void sub_8064218(struct MapObject *mapObj, struct Sprite *sprite, u32 flags)
+{
+ u8 i;
+ for (i = 0; i < ARRAY_COUNT(gUnknown_083760A0); i++, flags >>= 1)
+ if (flags & 1)
+ gUnknown_083760A0[i](mapObj, sprite);
+}
+
+void filters_out_some_ground_effects(struct MapObject *mapObj, u32 *flags)
+{
+ if (mapObj->mapobj_bit_4)
+ {
+ mapObj->mapobj_bit_18 = 0;
+ mapObj->mapobj_bit_20 = 0;
+ mapObj->mapobj_bit_19 = 0;
+ mapObj->mapobj_bit_21 = 0;
+ *flags &= 0xFFF9F7BD;
+ }
+}
+
+void FilterOutStepOnPuddleGroundEffectIfJumping(struct MapObject *mapObj, u32 *flags)
+{
+ if (mapObj->mapobj_bit_5)
+ *flags &= 0xFFFFFBFF;
+}
+
+void DoGroundEffects_OnSpawn(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ u32 flags;
+
+ if (mapObj->mapobj_bit_2)
+ {
+ flags = 0;
+ FieldObjectUpdateZCoordAndPriority(mapObj, sprite);
+ GetAllGroundEffectFlags_OnSpawn(mapObj, &flags);
+ FieldObjectSetSpriteOamTableForLongGrass(mapObj, sprite);
+ sub_8064218(mapObj, sprite, flags);
+ mapObj->mapobj_bit_2 = 0;
+ mapObj->mapobj_bit_4 = 0;
+ }
+}
+
+void DoGroundEffects_OnBeginStep(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ u32 flags;
+
+ if (mapObj->mapobj_bit_2)
+ {
+ flags = 0;
+ FieldObjectUpdateZCoordAndPriority(mapObj, sprite);
+ GetAllGroundEffectFlags_OnBeginStep(mapObj, &flags);
+ FieldObjectSetSpriteOamTableForLongGrass(mapObj, sprite);
+ filters_out_some_ground_effects(mapObj, &flags);
+ sub_8064218(mapObj, sprite, flags);
+ mapObj->mapobj_bit_2 = 0;
+ mapObj->mapobj_bit_4 = 0;
+ }
+}
+
+void DoGroundEffects_OnFinishStep(struct MapObject *mapObj, struct Sprite *sprite)
+{
+ u32 flags;
+
+ if (mapObj->mapobj_bit_3)
+ {
+ flags = 0;
+ FieldObjectUpdateZCoordAndPriority(mapObj, sprite);
+ GetAllGroundEffectFlags_OnFinishStep(mapObj, &flags);
+ FieldObjectSetSpriteOamTableForLongGrass(mapObj, sprite);
+ FilterOutStepOnPuddleGroundEffectIfJumping(mapObj, &flags);
+ sub_8064218(mapObj, sprite, flags);
+ mapObj->mapobj_bit_3 = 0;
+ mapObj->mapobj_bit_5 = 0;
+ }
+}
diff --git a/src/field/field_map_obj.c b/src/field/field_map_obj.c
new file mode 100644
index 000000000..0cba448a9
--- /dev/null
+++ b/src/field/field_map_obj.c
@@ -0,0 +1,8356 @@
+#include "global.h"
+#include "field_map_obj.h"
+#include "berry.h"
+#include "event_data.h"
+#include "field_camera.h"
+#include "field_effect.h"
+#include "field_effect_helpers.h"
+#include "field_ground_effect.h"
+#include "field_map_obj_helpers.h"
+#include "field_player_avatar.h"
+#include "fieldmap.h"
+#include "palette.h"
+#include "rng.h"
+#include "overworld.h"
+#include "sprite.h"
+#include "metatile_behavior.h"
+#include "map_constants.h"
+#include "map_object_constants.h"
+#include "trainer_see.h"
+
+// rodata
+
+const u8 gUnknown_0830FD14[] = {1, 1, 6, 7, 8, 9, 6, 7, 8, 9, 11, 11, 0, 0, 0, 0};
+
+void ObjectCB_CameraObject(struct Sprite *sprite);
+const struct SpriteTemplate gSpriteTemplate_830FD24 = {0, 0xFFFF, &gDummyOamData, gDummySpriteAnimTable, NULL, gDummySpriteAffineAnimTable, ObjectCB_CameraObject};
+
+void CameraObject_0(struct Sprite *);
+void CameraObject_1(struct Sprite *);
+void CameraObject_2(struct Sprite *);
+void (*const gCameraObjectFuncs[])(struct Sprite *) = {
+ CameraObject_0,
+ CameraObject_1,
+ CameraObject_2,
+};
+
+const u32 gMapObjectPic_BrendanNormal_0[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/normal/00.4bpp");
+const u32 gMapObjectPic_BrendanNormal_1[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/normal/01.4bpp");
+const u32 gMapObjectPic_BrendanNormal_2[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/normal/02.4bpp");
+const u32 gMapObjectPic_BrendanNormal_3[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/normal/03.4bpp");
+const u32 gMapObjectPic_BrendanNormal_4[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/normal/04.4bpp");
+const u32 gMapObjectPic_BrendanNormal_5[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/normal/05.4bpp");
+const u32 gMapObjectPic_BrendanNormal_6[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/normal/06.4bpp");
+const u32 gMapObjectPic_BrendanNormal_7[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/normal/07.4bpp");
+const u32 gMapObjectPic_BrendanNormal_8[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/normal/08.4bpp");
+const u32 gMapObjectPic_BrendanNormal_9[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/normal/09.4bpp");
+const u32 gMapObjectPic_BrendanNormal_10[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/normal/10.4bpp");
+const u32 gMapObjectPic_BrendanNormal_11[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/normal/11.4bpp");
+const u32 gMapObjectPic_BrendanNormal_12[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/normal/12.4bpp");
+const u32 gMapObjectPic_BrendanNormal_13[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/normal/13.4bpp");
+const u32 gMapObjectPic_BrendanNormal_14[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/normal/14.4bpp");
+const u32 gMapObjectPic_BrendanNormal_15[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/normal/15.4bpp");
+const u32 gMapObjectPic_BrendanNormal_16[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/normal/16.4bpp");
+const u32 gMapObjectPic_BrendanNormal_17[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/normal/17.4bpp");
+const u16 gMapObjectPalette8[] = INCBIN_U16("graphics/map_objects/palettes/08.gbapal");
+const u16 NullPalette_8310F68[16] = {};
+const u16 NullPalette_8310F88[16] = {};
+const u16 NullPalette_8310FA8[16] = {};
+const u16 NullPalette_8310FC8[16] = {};
+const u16 NullPalette_8310FE8[16] = {};
+const u16 NullPalette_8311008[16] = {};
+const u16 NullPalette_8311028[16] = {};
+const u16 NullPalette_8311048[16] = {};
+const u16 NullPalette_8311068[16] = {};
+const u16 NullPalette_8311088[16] = {};
+const u16 NullPalette_83110A8[16] = {};
+const u16 NullPalette_83110C8[16] = {};
+const u16 NullPalette_83110E8[16] = {};
+const u16 NullPalette_8311108[16] = {};
+const u16 NullPalette_8311128[16] = {};
+const u16 gMapObjectPalette9[] = INCBIN_U16("graphics/map_objects/palettes/09.gbapal");
+const u16 gMapObjectPalette10[] = INCBIN_U16("graphics/map_objects/palettes/10.gbapal");
+const u32 gMapObjectPic_BrendanFieldMove_0[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/field_move/0.4bpp");
+const u32 gMapObjectPic_BrendanFieldMove_1[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/field_move/1.4bpp");
+const u32 gMapObjectPic_BrendanFieldMove_2[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/field_move/2.4bpp");
+const u32 gMapObjectPic_BrendanFieldMove_3[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/field_move/3.4bpp");
+const u32 gMapObjectPic_BrendanFieldMove_4[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/field_move/4.4bpp");
+const u32 gMapObjectPic_BrendanSurfing_0[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/surfing/0.4bpp");
+const u32 gMapObjectPic_BrendanSurfing_3[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/surfing/3.4bpp");
+const u32 gMapObjectPic_BrendanSurfing_1[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/surfing/1.4bpp");
+const u32 gMapObjectPic_BrendanSurfing_4[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/surfing/4.4bpp");
+const u32 gMapObjectPic_BrendanSurfing_2[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/surfing/2.4bpp");
+const u32 gMapObjectPic_BrendanSurfing_5[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/surfing/5.4bpp");
+const u32 gMapObjectPic_BrendanMachBike_0[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/mach_bike/0.4bpp");
+const u32 gMapObjectPic_BrendanMachBike_1[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/mach_bike/1.4bpp");
+const u32 gMapObjectPic_BrendanMachBike_2[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/mach_bike/2.4bpp");
+const u32 gMapObjectPic_BrendanMachBike_3[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/mach_bike/3.4bpp");
+const u32 gMapObjectPic_BrendanMachBike_4[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/mach_bike/4.4bpp");
+const u32 gMapObjectPic_BrendanMachBike_5[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/mach_bike/5.4bpp");
+const u32 gMapObjectPic_BrendanMachBike_6[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/mach_bike/6.4bpp");
+const u32 gMapObjectPic_BrendanMachBike_7[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/mach_bike/7.4bpp");
+const u32 gMapObjectPic_BrendanMachBike_8[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/mach_bike/8.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_0[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/00.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_1[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/01.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_2[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/02.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_3[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/03.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_4[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/04.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_5[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/05.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_6[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/06.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_7[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/07.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_8[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/08.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_9[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/09.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_10[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/10.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_11[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/11.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_12[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/12.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_13[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/13.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_14[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/14.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_15[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/15.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_16[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/16.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_17[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/17.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_18[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/18.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_19[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/19.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_20[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/20.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_21[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/21.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_22[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/22.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_23[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/23.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_24[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/24.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_25[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/25.4bpp");
+const u32 gMapObjectPic_BrendanAcroBike_26[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/acro_bike/26.4bpp");
+const u32 gMapObjectPic_BrendanFishing_0[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/fishing/00.4bpp");
+const u32 gMapObjectPic_BrendanFishing_1[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/fishing/01.4bpp");
+const u32 gMapObjectPic_BrendanFishing_2[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/fishing/02.4bpp");
+const u32 gMapObjectPic_BrendanFishing_3[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/fishing/03.4bpp");
+const u32 gMapObjectPic_BrendanFishing_4[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/fishing/04.4bpp");
+const u32 gMapObjectPic_BrendanFishing_5[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/fishing/05.4bpp");
+const u32 gMapObjectPic_BrendanFishing_6[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/fishing/06.4bpp");
+const u32 gMapObjectPic_BrendanFishing_7[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/fishing/07.4bpp");
+const u32 gMapObjectPic_BrendanFishing_8[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/fishing/08.4bpp");
+const u32 gMapObjectPic_BrendanFishing_9[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/fishing/09.4bpp");
+const u32 gMapObjectPic_BrendanFishing_10[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/fishing/10.4bpp");
+const u32 gMapObjectPic_BrendanFishing_11[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/fishing/11.4bpp");
+const u32 gMapObjectPic_BrendanWatering_0[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/watering/0.4bpp");
+const u32 gMapObjectPic_BrendanWatering_3[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/watering/3.4bpp");
+const u32 gMapObjectPic_BrendanWatering_1[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/watering/1.4bpp");
+const u32 gMapObjectPic_BrendanWatering_4[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/watering/4.4bpp");
+const u32 gMapObjectPic_BrendanWatering_2[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/watering/2.4bpp");
+const u32 gMapObjectPic_BrendanWatering_5[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/watering/5.4bpp");
+const u32 gMapObjectPic_BrendanDecorating[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/decorating.4bpp");
+const u32 gMapObjectPic_MayDecorating[] = INCBIN_U32("graphics/map_objects/pics/people/may/decorating.4bpp");
+const u32 gMapObjectPic_BrendanUnderwater_0[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/underwater/0.4bpp");
+const u32 gMapObjectPic_BrendanUnderwater_1[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/underwater/1.4bpp");
+const u32 gMapObjectPic_BrendanUnderwater_2[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/underwater/2.4bpp");
+const u32 gMapObjectPic_BrendanUnderwater_3[] = INCBIN_U32("graphics/map_objects/pics/people/brendan/underwater/3.4bpp");
+const u32 gMapObjectPic_MayUnderwater_0[] = INCBIN_U32("graphics/map_objects/pics/people/may/underwater/0.4bpp");
+const u32 gMapObjectPic_MayUnderwater_1[] = INCBIN_U32("graphics/map_objects/pics/people/may/underwater/1.4bpp");
+const u32 gMapObjectPic_MayUnderwater_2[] = INCBIN_U32("graphics/map_objects/pics/people/may/underwater/2.4bpp");
+const u32 gMapObjectPic_MayUnderwater_3[] = INCBIN_U32("graphics/map_objects/pics/people/may/underwater/3.4bpp");
+const u16 gMapObjectPalette11[] = INCBIN_U16("graphics/map_objects/palettes/11.gbapal");
+const u32 gMapObjectPic_MayNormal_0[] = INCBIN_U32("graphics/map_objects/pics/people/may/normal/00.4bpp");
+const u32 gMapObjectPic_MayNormal_1[] = INCBIN_U32("graphics/map_objects/pics/people/may/normal/01.4bpp");
+const u32 gMapObjectPic_MayNormal_2[] = INCBIN_U32("graphics/map_objects/pics/people/may/normal/02.4bpp");
+const u32 gMapObjectPic_MayNormal_3[] = INCBIN_U32("graphics/map_objects/pics/people/may/normal/03.4bpp");
+const u32 gMapObjectPic_MayNormal_4[] = INCBIN_U32("graphics/map_objects/pics/people/may/normal/04.4bpp");
+const u32 gMapObjectPic_MayNormal_5[] = INCBIN_U32("graphics/map_objects/pics/people/may/normal/05.4bpp");
+const u32 gMapObjectPic_MayNormal_6[] = INCBIN_U32("graphics/map_objects/pics/people/may/normal/06.4bpp");
+const u32 gMapObjectPic_MayNormal_7[] = INCBIN_U32("graphics/map_objects/pics/people/may/normal/07.4bpp");
+const u32 gMapObjectPic_MayNormal_8[] = INCBIN_U32("graphics/map_objects/pics/people/may/normal/08.4bpp");
+const u32 gMapObjectPic_MayNormal_9[] = INCBIN_U32("graphics/map_objects/pics/people/may/normal/09.4bpp");
+const u32 gMapObjectPic_MayNormal_10[] = INCBIN_U32("graphics/map_objects/pics/people/may/normal/10.4bpp");
+const u32 gMapObjectPic_MayNormal_11[] = INCBIN_U32("graphics/map_objects/pics/people/may/normal/11.4bpp");
+const u32 gMapObjectPic_MayNormal_12[] = INCBIN_U32("graphics/map_objects/pics/people/may/normal/12.4bpp");
+const u32 gMapObjectPic_MayNormal_13[] = INCBIN_U32("graphics/map_objects/pics/people/may/normal/13.4bpp");
+const u32 gMapObjectPic_MayNormal_14[] = INCBIN_U32("graphics/map_objects/pics/people/may/normal/14.4bpp");
+const u32 gMapObjectPic_MayNormal_15[] = INCBIN_U32("graphics/map_objects/pics/people/may/normal/15.4bpp");
+const u32 gMapObjectPic_MayNormal_16[] = INCBIN_U32("graphics/map_objects/pics/people/may/normal/16.4bpp");
+const u32 gMapObjectPic_MayNormal_17[] = INCBIN_U32("graphics/map_objects/pics/people/may/normal/17.4bpp");
+const u16 gMapObjectPalette17[] = INCBIN_U16("graphics/map_objects/palettes/17.gbapal");
+const u16 gMapObjectPalette18[] = INCBIN_U16("graphics/map_objects/palettes/18.gbapal");
+const u16 NullPalette_831B7E8[16] = {};
+const u16 NullPalette_831B808[16] = {};
+const u16 NullPalette_831B828[16] = {};
+const u16 NullPalette_831B848[16] = {};
+const u16 NullPalette_831B868[16] = {};
+const u16 NullPalette_831B888[16] = {};
+const u16 NullPalette_831B8A8[16] = {};
+const u16 NullPalette_831B8C8[16] = {};
+const u16 NullPalette_831B8E8[16] = {};
+const u16 NullPalette_831B908[16] = {};
+const u16 NullPalette_831B928[16] = {};
+const u16 NullPalette_831B948[16] = {};
+const u16 NullPalette_831B968[16] = {};
+const u16 NullPalette_831B988[16] = {};
+const u32 gMapObjectPic_MayMachBike_0[] = INCBIN_U32("graphics/map_objects/pics/people/may/mach_bike/0.4bpp");
+const u32 gMapObjectPic_MayMachBike_1[] = INCBIN_U32("graphics/map_objects/pics/people/may/mach_bike/1.4bpp");
+const u32 gMapObjectPic_MayMachBike_2[] = INCBIN_U32("graphics/map_objects/pics/people/may/mach_bike/2.4bpp");
+const u32 gMapObjectPic_MayMachBike_3[] = INCBIN_U32("graphics/map_objects/pics/people/may/mach_bike/3.4bpp");
+const u32 gMapObjectPic_MayMachBike_4[] = INCBIN_U32("graphics/map_objects/pics/people/may/mach_bike/4.4bpp");
+const u32 gMapObjectPic_MayMachBike_5[] = INCBIN_U32("graphics/map_objects/pics/people/may/mach_bike/5.4bpp");
+const u32 gMapObjectPic_MayMachBike_6[] = INCBIN_U32("graphics/map_objects/pics/people/may/mach_bike/6.4bpp");
+const u32 gMapObjectPic_MayMachBike_7[] = INCBIN_U32("graphics/map_objects/pics/people/may/mach_bike/7.4bpp");
+const u32 gMapObjectPic_MayMachBike_8[] = INCBIN_U32("graphics/map_objects/pics/people/may/mach_bike/8.4bpp");
+const u32 gMapObjectPic_MayAcroBike_0[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/00.4bpp");
+const u32 gMapObjectPic_MayAcroBike_1[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/01.4bpp");
+const u32 gMapObjectPic_MayAcroBike_2[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/02.4bpp");
+const u32 gMapObjectPic_MayAcroBike_3[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/03.4bpp");
+const u32 gMapObjectPic_MayAcroBike_4[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/04.4bpp");
+const u32 gMapObjectPic_MayAcroBike_5[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/05.4bpp");
+const u32 gMapObjectPic_MayAcroBike_6[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/06.4bpp");
+const u32 gMapObjectPic_MayAcroBike_7[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/07.4bpp");
+const u32 gMapObjectPic_MayAcroBike_8[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/08.4bpp");
+const u32 gMapObjectPic_MayAcroBike_9[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/09.4bpp");
+const u32 gMapObjectPic_MayAcroBike_10[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/10.4bpp");
+const u32 gMapObjectPic_MayAcroBike_11[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/11.4bpp");
+const u32 gMapObjectPic_MayAcroBike_12[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/12.4bpp");
+const u32 gMapObjectPic_MayAcroBike_13[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/13.4bpp");
+const u32 gMapObjectPic_MayAcroBike_14[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/14.4bpp");
+const u32 gMapObjectPic_MayAcroBike_15[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/15.4bpp");
+const u32 gMapObjectPic_MayAcroBike_16[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/16.4bpp");
+const u32 gMapObjectPic_MayAcroBike_17[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/17.4bpp");
+const u32 gMapObjectPic_MayAcroBike_18[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/18.4bpp");
+const u32 gMapObjectPic_MayAcroBike_19[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/19.4bpp");
+const u32 gMapObjectPic_MayAcroBike_20[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/20.4bpp");
+const u32 gMapObjectPic_MayAcroBike_21[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/21.4bpp");
+const u32 gMapObjectPic_MayAcroBike_22[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/22.4bpp");
+const u32 gMapObjectPic_MayAcroBike_23[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/23.4bpp");
+const u32 gMapObjectPic_MayAcroBike_24[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/24.4bpp");
+const u32 gMapObjectPic_MayAcroBike_25[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/25.4bpp");
+const u32 gMapObjectPic_MayAcroBike_26[] = INCBIN_U32("graphics/map_objects/pics/people/may/acro_bike/26.4bpp");
+const u32 gMapObjectPic_MaySurfing_0[] = INCBIN_U32("graphics/map_objects/pics/people/may/surfing/0.4bpp");
+const u32 gMapObjectPic_MaySurfing_3[] = INCBIN_U32("graphics/map_objects/pics/people/may/surfing/3.4bpp");
+const u32 gMapObjectPic_MaySurfing_1[] = INCBIN_U32("graphics/map_objects/pics/people/may/surfing/1.4bpp");
+const u32 gMapObjectPic_MaySurfing_4[] = INCBIN_U32("graphics/map_objects/pics/people/may/surfing/4.4bpp");
+const u32 gMapObjectPic_MaySurfing_2[] = INCBIN_U32("graphics/map_objects/pics/people/may/surfing/2.4bpp");
+const u32 gMapObjectPic_MaySurfing_5[] = INCBIN_U32("graphics/map_objects/pics/people/may/surfing/5.4bpp");
+const u32 gMapObjectPic_MayFieldMove_0[] = INCBIN_U32("graphics/map_objects/pics/people/may/field_move/0.4bpp");
+const u32 gMapObjectPic_MayFieldMove_1[] = INCBIN_U32("graphics/map_objects/pics/people/may/field_move/1.4bpp");
+const u32 gMapObjectPic_MayFieldMove_2[] = INCBIN_U32("graphics/map_objects/pics/people/may/field_move/2.4bpp");
+const u32 gMapObjectPic_MayFieldMove_3[] = INCBIN_U32("graphics/map_objects/pics/people/may/field_move/3.4bpp");
+const u32 gMapObjectPic_MayFieldMove_4[] = INCBIN_U32("graphics/map_objects/pics/people/may/field_move/4.4bpp");
+const u32 gMapObjectPic_MayFishing_0[] = INCBIN_U32("graphics/map_objects/pics/people/may/fishing/00.4bpp");
+const u32 gMapObjectPic_MayFishing_1[] = INCBIN_U32("graphics/map_objects/pics/people/may/fishing/01.4bpp");
+const u32 gMapObjectPic_MayFishing_2[] = INCBIN_U32("graphics/map_objects/pics/people/may/fishing/02.4bpp");
+const u32 gMapObjectPic_MayFishing_3[] = INCBIN_U32("graphics/map_objects/pics/people/may/fishing/03.4bpp");
+const u32 gMapObjectPic_MayFishing_4[] = INCBIN_U32("graphics/map_objects/pics/people/may/fishing/04.4bpp");
+const u32 gMapObjectPic_MayFishing_5[] = INCBIN_U32("graphics/map_objects/pics/people/may/fishing/05.4bpp");
+const u32 gMapObjectPic_MayFishing_6[] = INCBIN_U32("graphics/map_objects/pics/people/may/fishing/06.4bpp");
+const u32 gMapObjectPic_MayFishing_7[] = INCBIN_U32("graphics/map_objects/pics/people/may/fishing/07.4bpp");
+const u32 gMapObjectPic_MayFishing_8[] = INCBIN_U32("graphics/map_objects/pics/people/may/fishing/08.4bpp");
+const u32 gMapObjectPic_MayFishing_9[] = INCBIN_U32("graphics/map_objects/pics/people/may/fishing/09.4bpp");
+const u32 gMapObjectPic_MayFishing_10[] = INCBIN_U32("graphics/map_objects/pics/people/may/fishing/10.4bpp");
+const u32 gMapObjectPic_MayFishing_11[] = INCBIN_U32("graphics/map_objects/pics/people/may/fishing/11.4bpp");
+const u32 gMapObjectPic_MayWatering_0[] = INCBIN_U32("graphics/map_objects/pics/people/may/watering/0.4bpp");
+const u32 gMapObjectPic_MayWatering_3[] = INCBIN_U32("graphics/map_objects/pics/people/may/watering/3.4bpp");
+const u32 gMapObjectPic_MayWatering_1[] = INCBIN_U32("graphics/map_objects/pics/people/may/watering/1.4bpp");
+const u32 gMapObjectPic_MayWatering_4[] = INCBIN_U32("graphics/map_objects/pics/people/may/watering/4.4bpp");
+const u32 gMapObjectPic_MayWatering_2[] = INCBIN_U32("graphics/map_objects/pics/people/may/watering/2.4bpp");
+const u32 gMapObjectPic_MayWatering_5[] = INCBIN_U32("graphics/map_objects/pics/people/may/watering/5.4bpp");
+const u16 gMapObjectPalette0[] = INCBIN_U16("graphics/map_objects/palettes/00.gbapal");
+const u16 gMapObjectPalette1[] = INCBIN_U16("graphics/map_objects/palettes/01.gbapal");
+const u16 gMapObjectPalette2[] = INCBIN_U16("graphics/map_objects/palettes/02.gbapal");
+const u16 gMapObjectPalette3[] = INCBIN_U16("graphics/map_objects/palettes/03.gbapal");
+const u16 gMapObjectPalette4[] = INCBIN_U16("graphics/map_objects/palettes/04.gbapal");
+const u16 gMapObjectPalette5[] = INCBIN_U16("graphics/map_objects/palettes/05.gbapal");
+const u16 gMapObjectPalette6[] = INCBIN_U16("graphics/map_objects/palettes/06.gbapal");
+const u16 gMapObjectPalette7[] = INCBIN_U16("graphics/map_objects/palettes/07.gbapal");
+const u32 gMapObjectPic_LittleBoy1_0[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_1/0.4bpp");
+const u32 gMapObjectPic_LittleBoy1_1[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_1/1.4bpp");
+const u32 gMapObjectPic_LittleBoy1_2[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_1/2.4bpp");
+const u32 gMapObjectPic_LittleBoy1_3[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_1/3.4bpp");
+const u32 gMapObjectPic_LittleBoy1_4[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_1/4.4bpp");
+const u32 gMapObjectPic_LittleBoy1_5[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_1/5.4bpp");
+const u32 gMapObjectPic_LittleBoy1_6[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_1/6.4bpp");
+const u32 gMapObjectPic_LittleBoy1_7[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_1/7.4bpp");
+const u32 gMapObjectPic_LittleBoy1_8[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_1/8.4bpp");
+const u32 gMapObjectPic_LittleGirl1_0[] = INCBIN_U32("graphics/map_objects/pics/people/little_girl_1/0.4bpp");
+const u32 gMapObjectPic_LittleGirl1_1[] = INCBIN_U32("graphics/map_objects/pics/people/little_girl_1/1.4bpp");
+const u32 gMapObjectPic_LittleGirl1_2[] = INCBIN_U32("graphics/map_objects/pics/people/little_girl_1/2.4bpp");
+const u32 gMapObjectPic_LittleGirl1_3[] = INCBIN_U32("graphics/map_objects/pics/people/little_girl_1/3.4bpp");
+const u32 gMapObjectPic_LittleGirl1_4[] = INCBIN_U32("graphics/map_objects/pics/people/little_girl_1/4.4bpp");
+const u32 gMapObjectPic_LittleGirl1_5[] = INCBIN_U32("graphics/map_objects/pics/people/little_girl_1/5.4bpp");
+const u32 gMapObjectPic_LittleGirl1_6[] = INCBIN_U32("graphics/map_objects/pics/people/little_girl_1/6.4bpp");
+const u32 gMapObjectPic_LittleGirl1_7[] = INCBIN_U32("graphics/map_objects/pics/people/little_girl_1/7.4bpp");
+const u32 gMapObjectPic_LittleGirl1_8[] = INCBIN_U32("graphics/map_objects/pics/people/little_girl_1/8.4bpp");
+const u32 gMapObjectPic_Boy1_0[] = INCBIN_U32("graphics/map_objects/pics/people/boy_1/0.4bpp");
+const u32 gMapObjectPic_Boy1_1[] = INCBIN_U32("graphics/map_objects/pics/people/boy_1/1.4bpp");
+const u32 gMapObjectPic_Boy1_2[] = INCBIN_U32("graphics/map_objects/pics/people/boy_1/2.4bpp");
+const u32 gMapObjectPic_Boy1_3[] = INCBIN_U32("graphics/map_objects/pics/people/boy_1/3.4bpp");
+const u32 gMapObjectPic_Boy1_4[] = INCBIN_U32("graphics/map_objects/pics/people/boy_1/4.4bpp");
+const u32 gMapObjectPic_Boy1_5[] = INCBIN_U32("graphics/map_objects/pics/people/boy_1/5.4bpp");
+const u32 gMapObjectPic_Boy1_6[] = INCBIN_U32("graphics/map_objects/pics/people/boy_1/6.4bpp");
+const u32 gMapObjectPic_Boy1_7[] = INCBIN_U32("graphics/map_objects/pics/people/boy_1/7.4bpp");
+const u32 gMapObjectPic_Boy1_8[] = INCBIN_U32("graphics/map_objects/pics/people/boy_1/8.4bpp");
+const u32 gMapObjectPic_Girl1_0[] = INCBIN_U32("graphics/map_objects/pics/people/girl_1/0.4bpp");
+const u32 gMapObjectPic_Girl1_1[] = INCBIN_U32("graphics/map_objects/pics/people/girl_1/1.4bpp");
+const u32 gMapObjectPic_Girl1_2[] = INCBIN_U32("graphics/map_objects/pics/people/girl_1/2.4bpp");
+const u32 gMapObjectPic_Girl1_3[] = INCBIN_U32("graphics/map_objects/pics/people/girl_1/3.4bpp");
+const u32 gMapObjectPic_Girl1_4[] = INCBIN_U32("graphics/map_objects/pics/people/girl_1/4.4bpp");
+const u32 gMapObjectPic_Girl1_5[] = INCBIN_U32("graphics/map_objects/pics/people/girl_1/5.4bpp");
+const u32 gMapObjectPic_Girl1_6[] = INCBIN_U32("graphics/map_objects/pics/people/girl_1/6.4bpp");
+const u32 gMapObjectPic_Girl1_7[] = INCBIN_U32("graphics/map_objects/pics/people/girl_1/7.4bpp");
+const u32 gMapObjectPic_Girl1_8[] = INCBIN_U32("graphics/map_objects/pics/people/girl_1/8.4bpp");
+const u32 gMapObjectPic_Boy2_0[] = INCBIN_U32("graphics/map_objects/pics/people/boy_2/0.4bpp");
+const u32 gMapObjectPic_Boy2_1[] = INCBIN_U32("graphics/map_objects/pics/people/boy_2/1.4bpp");
+const u32 gMapObjectPic_Boy2_2[] = INCBIN_U32("graphics/map_objects/pics/people/boy_2/2.4bpp");
+const u32 gMapObjectPic_Boy2_3[] = INCBIN_U32("graphics/map_objects/pics/people/boy_2/3.4bpp");
+const u32 gMapObjectPic_Boy2_4[] = INCBIN_U32("graphics/map_objects/pics/people/boy_2/4.4bpp");
+const u32 gMapObjectPic_Boy2_5[] = INCBIN_U32("graphics/map_objects/pics/people/boy_2/5.4bpp");
+const u32 gMapObjectPic_Boy2_6[] = INCBIN_U32("graphics/map_objects/pics/people/boy_2/6.4bpp");
+const u32 gMapObjectPic_Boy2_7[] = INCBIN_U32("graphics/map_objects/pics/people/boy_2/7.4bpp");
+const u32 gMapObjectPic_Boy2_8[] = INCBIN_U32("graphics/map_objects/pics/people/boy_2/8.4bpp");
+const u32 gMapObjectPic_Girl2_0[] = INCBIN_U32("graphics/map_objects/pics/people/girl_2/0.4bpp");
+const u32 gMapObjectPic_Girl2_1[] = INCBIN_U32("graphics/map_objects/pics/people/girl_2/1.4bpp");
+const u32 gMapObjectPic_Girl2_2[] = INCBIN_U32("graphics/map_objects/pics/people/girl_2/2.4bpp");
+const u32 gMapObjectPic_Girl2_3[] = INCBIN_U32("graphics/map_objects/pics/people/girl_2/3.4bpp");
+const u32 gMapObjectPic_Girl2_4[] = INCBIN_U32("graphics/map_objects/pics/people/girl_2/4.4bpp");
+const u32 gMapObjectPic_Girl2_5[] = INCBIN_U32("graphics/map_objects/pics/people/girl_2/5.4bpp");
+const u32 gMapObjectPic_Girl2_6[] = INCBIN_U32("graphics/map_objects/pics/people/girl_2/6.4bpp");
+const u32 gMapObjectPic_Girl2_7[] = INCBIN_U32("graphics/map_objects/pics/people/girl_2/7.4bpp");
+const u32 gMapObjectPic_Girl2_8[] = INCBIN_U32("graphics/map_objects/pics/people/girl_2/8.4bpp");
+const u32 gMapObjectPic_LittleBoy2_0[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_2/0.4bpp");
+const u32 gMapObjectPic_LittleBoy2_1[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_2/1.4bpp");
+const u32 gMapObjectPic_LittleBoy2_2[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_2/2.4bpp");
+const u32 gMapObjectPic_LittleBoy2_3[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_2/3.4bpp");
+const u32 gMapObjectPic_LittleBoy2_4[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_2/4.4bpp");
+const u32 gMapObjectPic_LittleBoy2_5[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_2/5.4bpp");
+const u32 gMapObjectPic_LittleBoy2_6[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_2/6.4bpp");
+const u32 gMapObjectPic_LittleBoy2_7[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_2/7.4bpp");
+const u32 gMapObjectPic_LittleBoy2_8[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_2/8.4bpp");
+const u32 gMapObjectPic_LittleGirl2_0[] = INCBIN_U32("graphics/map_objects/pics/people/little_girl_2/0.4bpp");
+const u32 gMapObjectPic_LittleGirl2_1[] = INCBIN_U32("graphics/map_objects/pics/people/little_girl_2/1.4bpp");
+const u32 gMapObjectPic_LittleGirl2_2[] = INCBIN_U32("graphics/map_objects/pics/people/little_girl_2/2.4bpp");
+const u32 gMapObjectPic_LittleGirl2_3[] = INCBIN_U32("graphics/map_objects/pics/people/little_girl_2/3.4bpp");
+const u32 gMapObjectPic_LittleGirl2_4[] = INCBIN_U32("graphics/map_objects/pics/people/little_girl_2/4.4bpp");
+const u32 gMapObjectPic_LittleGirl2_5[] = INCBIN_U32("graphics/map_objects/pics/people/little_girl_2/5.4bpp");
+const u32 gMapObjectPic_LittleGirl2_6[] = INCBIN_U32("graphics/map_objects/pics/people/little_girl_2/6.4bpp");
+const u32 gMapObjectPic_LittleGirl2_7[] = INCBIN_U32("graphics/map_objects/pics/people/little_girl_2/7.4bpp");
+const u32 gMapObjectPic_LittleGirl2_8[] = INCBIN_U32("graphics/map_objects/pics/people/little_girl_2/8.4bpp");
+const u32 gMapObjectPic_Boy3_0[] = INCBIN_U32("graphics/map_objects/pics/people/boy_3/0.4bpp");
+const u32 gMapObjectPic_Boy3_1[] = INCBIN_U32("graphics/map_objects/pics/people/boy_3/1.4bpp");
+const u32 gMapObjectPic_Boy3_2[] = INCBIN_U32("graphics/map_objects/pics/people/boy_3/2.4bpp");
+const u32 gMapObjectPic_Boy3_3[] = INCBIN_U32("graphics/map_objects/pics/people/boy_3/3.4bpp");
+const u32 gMapObjectPic_Boy3_4[] = INCBIN_U32("graphics/map_objects/pics/people/boy_3/4.4bpp");
+const u32 gMapObjectPic_Boy3_5[] = INCBIN_U32("graphics/map_objects/pics/people/boy_3/5.4bpp");
+const u32 gMapObjectPic_Boy3_6[] = INCBIN_U32("graphics/map_objects/pics/people/boy_3/6.4bpp");
+const u32 gMapObjectPic_Boy3_7[] = INCBIN_U32("graphics/map_objects/pics/people/boy_3/7.4bpp");
+const u32 gMapObjectPic_Boy3_8[] = INCBIN_U32("graphics/map_objects/pics/people/boy_3/8.4bpp");
+const u32 gMapObjectPic_Girl3_0[] = INCBIN_U32("graphics/map_objects/pics/people/girl_3/0.4bpp");
+const u32 gMapObjectPic_Girl3_1[] = INCBIN_U32("graphics/map_objects/pics/people/girl_3/1.4bpp");
+const u32 gMapObjectPic_Girl3_2[] = INCBIN_U32("graphics/map_objects/pics/people/girl_3/2.4bpp");
+const u32 gMapObjectPic_Girl3_3[] = INCBIN_U32("graphics/map_objects/pics/people/girl_3/3.4bpp");
+const u32 gMapObjectPic_Girl3_4[] = INCBIN_U32("graphics/map_objects/pics/people/girl_3/4.4bpp");
+const u32 gMapObjectPic_Girl3_5[] = INCBIN_U32("graphics/map_objects/pics/people/girl_3/5.4bpp");
+const u32 gMapObjectPic_Girl3_6[] = INCBIN_U32("graphics/map_objects/pics/people/girl_3/6.4bpp");
+const u32 gMapObjectPic_Girl3_7[] = INCBIN_U32("graphics/map_objects/pics/people/girl_3/7.4bpp");
+const u32 gMapObjectPic_Girl3_8[] = INCBIN_U32("graphics/map_objects/pics/people/girl_3/8.4bpp");
+const u32 gMapObjectPic_Boy4_0[] = INCBIN_U32("graphics/map_objects/pics/people/boy_4/0.4bpp");
+const u32 gMapObjectPic_Boy4_1[] = INCBIN_U32("graphics/map_objects/pics/people/boy_4/1.4bpp");
+const u32 gMapObjectPic_Boy4_2[] = INCBIN_U32("graphics/map_objects/pics/people/boy_4/2.4bpp");
+const u32 gMapObjectPic_Boy4_3[] = INCBIN_U32("graphics/map_objects/pics/people/boy_4/3.4bpp");
+const u32 gMapObjectPic_Boy4_4[] = INCBIN_U32("graphics/map_objects/pics/people/boy_4/4.4bpp");
+const u32 gMapObjectPic_Boy4_5[] = INCBIN_U32("graphics/map_objects/pics/people/boy_4/5.4bpp");
+const u32 gMapObjectPic_Boy4_6[] = INCBIN_U32("graphics/map_objects/pics/people/boy_4/6.4bpp");
+const u32 gMapObjectPic_Boy4_7[] = INCBIN_U32("graphics/map_objects/pics/people/boy_4/7.4bpp");
+const u32 gMapObjectPic_Boy4_8[] = INCBIN_U32("graphics/map_objects/pics/people/boy_4/8.4bpp");
+const u32 gMapObjectPic_Woman1_0[] = INCBIN_U32("graphics/map_objects/pics/people/woman_1/0.4bpp");
+const u32 gMapObjectPic_Woman1_1[] = INCBIN_U32("graphics/map_objects/pics/people/woman_1/1.4bpp");
+const u32 gMapObjectPic_Woman1_2[] = INCBIN_U32("graphics/map_objects/pics/people/woman_1/2.4bpp");
+const u32 gMapObjectPic_Woman1_3[] = INCBIN_U32("graphics/map_objects/pics/people/woman_1/3.4bpp");
+const u32 gMapObjectPic_Woman1_4[] = INCBIN_U32("graphics/map_objects/pics/people/woman_1/4.4bpp");
+const u32 gMapObjectPic_Woman1_5[] = INCBIN_U32("graphics/map_objects/pics/people/woman_1/5.4bpp");
+const u32 gMapObjectPic_Woman1_6[] = INCBIN_U32("graphics/map_objects/pics/people/woman_1/6.4bpp");
+const u32 gMapObjectPic_Woman1_7[] = INCBIN_U32("graphics/map_objects/pics/people/woman_1/7.4bpp");
+const u32 gMapObjectPic_Woman1_8[] = INCBIN_U32("graphics/map_objects/pics/people/woman_1/8.4bpp");
+const u32 gMapObjectPic_FatMan_0[] = INCBIN_U32("graphics/map_objects/pics/people/fat_man/0.4bpp");
+const u32 gMapObjectPic_FatMan_1[] = INCBIN_U32("graphics/map_objects/pics/people/fat_man/1.4bpp");
+const u32 gMapObjectPic_FatMan_2[] = INCBIN_U32("graphics/map_objects/pics/people/fat_man/2.4bpp");
+const u32 gMapObjectPic_FatMan_3[] = INCBIN_U32("graphics/map_objects/pics/people/fat_man/3.4bpp");
+const u32 gMapObjectPic_FatMan_4[] = INCBIN_U32("graphics/map_objects/pics/people/fat_man/4.4bpp");
+const u32 gMapObjectPic_FatMan_5[] = INCBIN_U32("graphics/map_objects/pics/people/fat_man/5.4bpp");
+const u32 gMapObjectPic_FatMan_6[] = INCBIN_U32("graphics/map_objects/pics/people/fat_man/6.4bpp");
+const u32 gMapObjectPic_FatMan_7[] = INCBIN_U32("graphics/map_objects/pics/people/fat_man/7.4bpp");
+const u32 gMapObjectPic_FatMan_8[] = INCBIN_U32("graphics/map_objects/pics/people/fat_man/8.4bpp");
+const u32 gMapObjectPic_Woman2_0[] = INCBIN_U32("graphics/map_objects/pics/people/woman_2/0.4bpp");
+const u32 gMapObjectPic_Woman2_1[] = INCBIN_U32("graphics/map_objects/pics/people/woman_2/1.4bpp");
+const u32 gMapObjectPic_Woman2_2[] = INCBIN_U32("graphics/map_objects/pics/people/woman_2/2.4bpp");
+const u32 gMapObjectPic_Woman2_3[] = INCBIN_U32("graphics/map_objects/pics/people/woman_2/3.4bpp");
+const u32 gMapObjectPic_Woman2_4[] = INCBIN_U32("graphics/map_objects/pics/people/woman_2/4.4bpp");
+const u32 gMapObjectPic_Woman2_5[] = INCBIN_U32("graphics/map_objects/pics/people/woman_2/5.4bpp");
+const u32 gMapObjectPic_Woman2_6[] = INCBIN_U32("graphics/map_objects/pics/people/woman_2/6.4bpp");
+const u32 gMapObjectPic_Woman2_7[] = INCBIN_U32("graphics/map_objects/pics/people/woman_2/7.4bpp");
+const u32 gMapObjectPic_Woman2_8[] = INCBIN_U32("graphics/map_objects/pics/people/woman_2/8.4bpp");
+const u32 gMapObjectPic_Man1_0[] = INCBIN_U32("graphics/map_objects/pics/people/man_1/0.4bpp");
+const u32 gMapObjectPic_Man1_1[] = INCBIN_U32("graphics/map_objects/pics/people/man_1/1.4bpp");
+const u32 gMapObjectPic_Man1_2[] = INCBIN_U32("graphics/map_objects/pics/people/man_1/2.4bpp");
+const u32 gMapObjectPic_Man1_3[] = INCBIN_U32("graphics/map_objects/pics/people/man_1/3.4bpp");
+const u32 gMapObjectPic_Man1_4[] = INCBIN_U32("graphics/map_objects/pics/people/man_1/4.4bpp");
+const u32 gMapObjectPic_Man1_5[] = INCBIN_U32("graphics/map_objects/pics/people/man_1/5.4bpp");
+const u32 gMapObjectPic_Man1_6[] = INCBIN_U32("graphics/map_objects/pics/people/man_1/6.4bpp");
+const u32 gMapObjectPic_Man1_7[] = INCBIN_U32("graphics/map_objects/pics/people/man_1/7.4bpp");
+const u32 gMapObjectPic_Man1_8[] = INCBIN_U32("graphics/map_objects/pics/people/man_1/8.4bpp");
+const u32 gMapObjectPic_Woman3_0[] = INCBIN_U32("graphics/map_objects/pics/people/woman_3/0.4bpp");
+const u32 gMapObjectPic_Woman3_1[] = INCBIN_U32("graphics/map_objects/pics/people/woman_3/1.4bpp");
+const u32 gMapObjectPic_Woman3_2[] = INCBIN_U32("graphics/map_objects/pics/people/woman_3/2.4bpp");
+const u32 gMapObjectPic_Woman3_3[] = INCBIN_U32("graphics/map_objects/pics/people/woman_3/3.4bpp");
+const u32 gMapObjectPic_Woman3_4[] = INCBIN_U32("graphics/map_objects/pics/people/woman_3/4.4bpp");
+const u32 gMapObjectPic_Woman3_5[] = INCBIN_U32("graphics/map_objects/pics/people/woman_3/5.4bpp");
+const u32 gMapObjectPic_Woman3_6[] = INCBIN_U32("graphics/map_objects/pics/people/woman_3/6.4bpp");
+const u32 gMapObjectPic_Woman3_7[] = INCBIN_U32("graphics/map_objects/pics/people/woman_3/7.4bpp");
+const u32 gMapObjectPic_Woman3_8[] = INCBIN_U32("graphics/map_objects/pics/people/woman_3/8.4bpp");
+const u32 gMapObjectPic_OldMan1_0[] = INCBIN_U32("graphics/map_objects/pics/people/old_man_1/0.4bpp");
+const u32 gMapObjectPic_OldMan1_1[] = INCBIN_U32("graphics/map_objects/pics/people/old_man_1/1.4bpp");
+const u32 gMapObjectPic_OldMan1_2[] = INCBIN_U32("graphics/map_objects/pics/people/old_man_1/2.4bpp");
+const u32 gMapObjectPic_OldMan1_3[] = INCBIN_U32("graphics/map_objects/pics/people/old_man_1/3.4bpp");
+const u32 gMapObjectPic_OldMan1_4[] = INCBIN_U32("graphics/map_objects/pics/people/old_man_1/4.4bpp");
+const u32 gMapObjectPic_OldMan1_5[] = INCBIN_U32("graphics/map_objects/pics/people/old_man_1/5.4bpp");
+const u32 gMapObjectPic_OldMan1_6[] = INCBIN_U32("graphics/map_objects/pics/people/old_man_1/6.4bpp");
+const u32 gMapObjectPic_OldMan1_7[] = INCBIN_U32("graphics/map_objects/pics/people/old_man_1/7.4bpp");
+const u32 gMapObjectPic_OldMan1_8[] = INCBIN_U32("graphics/map_objects/pics/people/old_man_1/8.4bpp");
+const u32 gMapObjectPic_OldWoman1_0[] = INCBIN_U32("graphics/map_objects/pics/people/old_woman_1/0.4bpp");
+const u32 gMapObjectPic_OldWoman1_1[] = INCBIN_U32("graphics/map_objects/pics/people/old_woman_1/1.4bpp");
+const u32 gMapObjectPic_OldWoman1_2[] = INCBIN_U32("graphics/map_objects/pics/people/old_woman_1/2.4bpp");
+const u32 gMapObjectPic_OldWoman1_3[] = INCBIN_U32("graphics/map_objects/pics/people/old_woman_1/3.4bpp");
+const u32 gMapObjectPic_OldWoman1_4[] = INCBIN_U32("graphics/map_objects/pics/people/old_woman_1/4.4bpp");
+const u32 gMapObjectPic_OldWoman1_5[] = INCBIN_U32("graphics/map_objects/pics/people/old_woman_1/5.4bpp");
+const u32 gMapObjectPic_OldWoman1_6[] = INCBIN_U32("graphics/map_objects/pics/people/old_woman_1/6.4bpp");
+const u32 gMapObjectPic_OldWoman1_7[] = INCBIN_U32("graphics/map_objects/pics/people/old_woman_1/7.4bpp");
+const u32 gMapObjectPic_OldWoman1_8[] = INCBIN_U32("graphics/map_objects/pics/people/old_woman_1/8.4bpp");
+const u32 gMapObjectPic_Man2_0[] = INCBIN_U32("graphics/map_objects/pics/people/man_2/0.4bpp");
+const u32 gMapObjectPic_Man2_1[] = INCBIN_U32("graphics/map_objects/pics/people/man_2/1.4bpp");
+const u32 gMapObjectPic_Man2_2[] = INCBIN_U32("graphics/map_objects/pics/people/man_2/2.4bpp");
+const u32 gMapObjectPic_Man2_3[] = INCBIN_U32("graphics/map_objects/pics/people/man_2/3.4bpp");
+const u32 gMapObjectPic_Man2_4[] = INCBIN_U32("graphics/map_objects/pics/people/man_2/4.4bpp");
+const u32 gMapObjectPic_Man2_5[] = INCBIN_U32("graphics/map_objects/pics/people/man_2/5.4bpp");
+const u32 gMapObjectPic_Man2_6[] = INCBIN_U32("graphics/map_objects/pics/people/man_2/6.4bpp");
+const u32 gMapObjectPic_Man2_7[] = INCBIN_U32("graphics/map_objects/pics/people/man_2/7.4bpp");
+const u32 gMapObjectPic_Man2_8[] = INCBIN_U32("graphics/map_objects/pics/people/man_2/8.4bpp");
+const u32 gMapObjectPic_Woman4_0[] = INCBIN_U32("graphics/map_objects/pics/people/woman_4/0.4bpp");
+const u32 gMapObjectPic_Woman4_1[] = INCBIN_U32("graphics/map_objects/pics/people/woman_4/1.4bpp");
+const u32 gMapObjectPic_Woman4_2[] = INCBIN_U32("graphics/map_objects/pics/people/woman_4/2.4bpp");
+const u32 gMapObjectPic_Woman4_3[] = INCBIN_U32("graphics/map_objects/pics/people/woman_4/3.4bpp");
+const u32 gMapObjectPic_Woman4_4[] = INCBIN_U32("graphics/map_objects/pics/people/woman_4/4.4bpp");
+const u32 gMapObjectPic_Woman4_5[] = INCBIN_U32("graphics/map_objects/pics/people/woman_4/5.4bpp");
+const u32 gMapObjectPic_Woman4_6[] = INCBIN_U32("graphics/map_objects/pics/people/woman_4/6.4bpp");
+const u32 gMapObjectPic_Woman4_7[] = INCBIN_U32("graphics/map_objects/pics/people/woman_4/7.4bpp");
+const u32 gMapObjectPic_Woman4_8[] = INCBIN_U32("graphics/map_objects/pics/people/woman_4/8.4bpp");
+const u32 gMapObjectPic_Man3_0[] = INCBIN_U32("graphics/map_objects/pics/people/man_3/0.4bpp");
+const u32 gMapObjectPic_Man3_1[] = INCBIN_U32("graphics/map_objects/pics/people/man_3/1.4bpp");
+const u32 gMapObjectPic_Man3_2[] = INCBIN_U32("graphics/map_objects/pics/people/man_3/2.4bpp");
+const u32 gMapObjectPic_Man3_3[] = INCBIN_U32("graphics/map_objects/pics/people/man_3/3.4bpp");
+const u32 gMapObjectPic_Man3_4[] = INCBIN_U32("graphics/map_objects/pics/people/man_3/4.4bpp");
+const u32 gMapObjectPic_Man3_5[] = INCBIN_U32("graphics/map_objects/pics/people/man_3/5.4bpp");
+const u32 gMapObjectPic_Man3_6[] = INCBIN_U32("graphics/map_objects/pics/people/man_3/6.4bpp");
+const u32 gMapObjectPic_Man3_7[] = INCBIN_U32("graphics/map_objects/pics/people/man_3/7.4bpp");
+const u32 gMapObjectPic_Man3_8[] = INCBIN_U32("graphics/map_objects/pics/people/man_3/8.4bpp");
+const u32 gMapObjectPic_Woman5_0[] = INCBIN_U32("graphics/map_objects/pics/people/woman_5/0.4bpp");
+const u32 gMapObjectPic_Woman5_1[] = INCBIN_U32("graphics/map_objects/pics/people/woman_5/1.4bpp");
+const u32 gMapObjectPic_Woman5_2[] = INCBIN_U32("graphics/map_objects/pics/people/woman_5/2.4bpp");
+const u32 gMapObjectPic_Woman5_3[] = INCBIN_U32("graphics/map_objects/pics/people/woman_5/3.4bpp");
+const u32 gMapObjectPic_Woman5_4[] = INCBIN_U32("graphics/map_objects/pics/people/woman_5/4.4bpp");
+const u32 gMapObjectPic_Woman5_5[] = INCBIN_U32("graphics/map_objects/pics/people/woman_5/5.4bpp");
+const u32 gMapObjectPic_Woman5_6[] = INCBIN_U32("graphics/map_objects/pics/people/woman_5/6.4bpp");
+const u32 gMapObjectPic_Woman5_7[] = INCBIN_U32("graphics/map_objects/pics/people/woman_5/7.4bpp");
+const u32 gMapObjectPic_Woman5_8[] = INCBIN_U32("graphics/map_objects/pics/people/woman_5/8.4bpp");
+const u32 gMapObjectPic_Cook_0[] = INCBIN_U32("graphics/map_objects/pics/people/cook/0.4bpp");
+const u32 gMapObjectPic_Cook_1[] = INCBIN_U32("graphics/map_objects/pics/people/cook/1.4bpp");
+const u32 gMapObjectPic_Cook_2[] = INCBIN_U32("graphics/map_objects/pics/people/cook/2.4bpp");
+const u32 gMapObjectPic_Woman6_0[] = INCBIN_U32("graphics/map_objects/pics/people/woman_6/0.4bpp");
+const u32 gMapObjectPic_Woman6_1[] = INCBIN_U32("graphics/map_objects/pics/people/woman_6/1.4bpp");
+const u32 gMapObjectPic_Woman6_2[] = INCBIN_U32("graphics/map_objects/pics/people/woman_6/2.4bpp");
+const u32 gMapObjectPic_Woman6_3[] = INCBIN_U32("graphics/map_objects/pics/people/woman_6/3.4bpp");
+const u32 gMapObjectPic_Woman6_4[] = INCBIN_U32("graphics/map_objects/pics/people/woman_6/4.4bpp");
+const u32 gMapObjectPic_Woman6_5[] = INCBIN_U32("graphics/map_objects/pics/people/woman_6/5.4bpp");
+const u32 gMapObjectPic_Woman6_6[] = INCBIN_U32("graphics/map_objects/pics/people/woman_6/6.4bpp");
+const u32 gMapObjectPic_Woman6_7[] = INCBIN_U32("graphics/map_objects/pics/people/woman_6/7.4bpp");
+const u32 gMapObjectPic_Woman6_8[] = INCBIN_U32("graphics/map_objects/pics/people/woman_6/8.4bpp");
+const u32 gMapObjectPic_OldMan2_0[] = INCBIN_U32("graphics/map_objects/pics/people/old_man_2/0.4bpp");
+const u32 gMapObjectPic_OldMan2_1[] = INCBIN_U32("graphics/map_objects/pics/people/old_man_2/1.4bpp");
+const u32 gMapObjectPic_OldMan2_2[] = INCBIN_U32("graphics/map_objects/pics/people/old_man_2/2.4bpp");
+const u32 gMapObjectPic_OldWoman2_0[] = INCBIN_U32("graphics/map_objects/pics/people/old_woman_2/0.4bpp");
+const u32 gMapObjectPic_OldWoman2_1[] = INCBIN_U32("graphics/map_objects/pics/people/old_woman_2/1.4bpp");
+const u32 gMapObjectPic_OldWoman2_2[] = INCBIN_U32("graphics/map_objects/pics/people/old_woman_2/2.4bpp");
+const u32 gMapObjectPic_Camper_0[] = INCBIN_U32("graphics/map_objects/pics/people/camper/0.4bpp");
+const u32 gMapObjectPic_Camper_1[] = INCBIN_U32("graphics/map_objects/pics/people/camper/1.4bpp");
+const u32 gMapObjectPic_Camper_2[] = INCBIN_U32("graphics/map_objects/pics/people/camper/2.4bpp");
+const u32 gMapObjectPic_Camper_3[] = INCBIN_U32("graphics/map_objects/pics/people/camper/3.4bpp");
+const u32 gMapObjectPic_Camper_4[] = INCBIN_U32("graphics/map_objects/pics/people/camper/4.4bpp");
+const u32 gMapObjectPic_Camper_5[] = INCBIN_U32("graphics/map_objects/pics/people/camper/5.4bpp");
+const u32 gMapObjectPic_Camper_6[] = INCBIN_U32("graphics/map_objects/pics/people/camper/6.4bpp");
+const u32 gMapObjectPic_Camper_7[] = INCBIN_U32("graphics/map_objects/pics/people/camper/7.4bpp");
+const u32 gMapObjectPic_Camper_8[] = INCBIN_U32("graphics/map_objects/pics/people/camper/8.4bpp");
+const u32 gMapObjectPic_Picnicker_0[] = INCBIN_U32("graphics/map_objects/pics/people/picnicker/0.4bpp");
+const u32 gMapObjectPic_Picnicker_1[] = INCBIN_U32("graphics/map_objects/pics/people/picnicker/1.4bpp");
+const u32 gMapObjectPic_Picnicker_2[] = INCBIN_U32("graphics/map_objects/pics/people/picnicker/2.4bpp");
+const u32 gMapObjectPic_Picnicker_3[] = INCBIN_U32("graphics/map_objects/pics/people/picnicker/3.4bpp");
+const u32 gMapObjectPic_Picnicker_4[] = INCBIN_U32("graphics/map_objects/pics/people/picnicker/4.4bpp");
+const u32 gMapObjectPic_Picnicker_5[] = INCBIN_U32("graphics/map_objects/pics/people/picnicker/5.4bpp");
+const u32 gMapObjectPic_Picnicker_6[] = INCBIN_U32("graphics/map_objects/pics/people/picnicker/6.4bpp");
+const u32 gMapObjectPic_Picnicker_7[] = INCBIN_U32("graphics/map_objects/pics/people/picnicker/7.4bpp");
+const u32 gMapObjectPic_Picnicker_8[] = INCBIN_U32("graphics/map_objects/pics/people/picnicker/8.4bpp");
+const u32 gMapObjectPic_Man4_0[] = INCBIN_U32("graphics/map_objects/pics/people/man_4/0.4bpp");
+const u32 gMapObjectPic_Man4_1[] = INCBIN_U32("graphics/map_objects/pics/people/man_4/1.4bpp");
+const u32 gMapObjectPic_Man4_2[] = INCBIN_U32("graphics/map_objects/pics/people/man_4/2.4bpp");
+const u32 gMapObjectPic_Man4_3[] = INCBIN_U32("graphics/map_objects/pics/people/man_4/3.4bpp");
+const u32 gMapObjectPic_Man4_4[] = INCBIN_U32("graphics/map_objects/pics/people/man_4/4.4bpp");
+const u32 gMapObjectPic_Man4_5[] = INCBIN_U32("graphics/map_objects/pics/people/man_4/5.4bpp");
+const u32 gMapObjectPic_Man4_6[] = INCBIN_U32("graphics/map_objects/pics/people/man_4/6.4bpp");
+const u32 gMapObjectPic_Man4_7[] = INCBIN_U32("graphics/map_objects/pics/people/man_4/7.4bpp");
+const u32 gMapObjectPic_Man4_8[] = INCBIN_U32("graphics/map_objects/pics/people/man_4/8.4bpp");
+const u32 gMapObjectPic_Woman7_0[] = INCBIN_U32("graphics/map_objects/pics/people/woman_7/0.4bpp");
+const u32 gMapObjectPic_Woman7_1[] = INCBIN_U32("graphics/map_objects/pics/people/woman_7/1.4bpp");
+const u32 gMapObjectPic_Woman7_2[] = INCBIN_U32("graphics/map_objects/pics/people/woman_7/2.4bpp");
+const u32 gMapObjectPic_Woman7_3[] = INCBIN_U32("graphics/map_objects/pics/people/woman_7/3.4bpp");
+const u32 gMapObjectPic_Woman7_4[] = INCBIN_U32("graphics/map_objects/pics/people/woman_7/4.4bpp");
+const u32 gMapObjectPic_Woman7_5[] = INCBIN_U32("graphics/map_objects/pics/people/woman_7/5.4bpp");
+const u32 gMapObjectPic_Woman7_6[] = INCBIN_U32("graphics/map_objects/pics/people/woman_7/6.4bpp");
+const u32 gMapObjectPic_Woman7_7[] = INCBIN_U32("graphics/map_objects/pics/people/woman_7/7.4bpp");
+const u32 gMapObjectPic_Woman7_8[] = INCBIN_U32("graphics/map_objects/pics/people/woman_7/8.4bpp");
+const u32 gMapObjectPic_Youngster_0[] = INCBIN_U32("graphics/map_objects/pics/people/youngster/0.4bpp");
+const u32 gMapObjectPic_Youngster_1[] = INCBIN_U32("graphics/map_objects/pics/people/youngster/1.4bpp");
+const u32 gMapObjectPic_Youngster_2[] = INCBIN_U32("graphics/map_objects/pics/people/youngster/2.4bpp");
+const u32 gMapObjectPic_Youngster_3[] = INCBIN_U32("graphics/map_objects/pics/people/youngster/3.4bpp");
+const u32 gMapObjectPic_Youngster_4[] = INCBIN_U32("graphics/map_objects/pics/people/youngster/4.4bpp");
+const u32 gMapObjectPic_Youngster_5[] = INCBIN_U32("graphics/map_objects/pics/people/youngster/5.4bpp");
+const u32 gMapObjectPic_Youngster_6[] = INCBIN_U32("graphics/map_objects/pics/people/youngster/6.4bpp");
+const u32 gMapObjectPic_Youngster_7[] = INCBIN_U32("graphics/map_objects/pics/people/youngster/7.4bpp");
+const u32 gMapObjectPic_Youngster_8[] = INCBIN_U32("graphics/map_objects/pics/people/youngster/8.4bpp");
+const u32 gMapObjectPic_BugCatcher_0[] = INCBIN_U32("graphics/map_objects/pics/people/bug_catcher/0.4bpp");
+const u32 gMapObjectPic_BugCatcher_1[] = INCBIN_U32("graphics/map_objects/pics/people/bug_catcher/1.4bpp");
+const u32 gMapObjectPic_BugCatcher_2[] = INCBIN_U32("graphics/map_objects/pics/people/bug_catcher/2.4bpp");
+const u32 gMapObjectPic_BugCatcher_3[] = INCBIN_U32("graphics/map_objects/pics/people/bug_catcher/3.4bpp");
+const u32 gMapObjectPic_BugCatcher_4[] = INCBIN_U32("graphics/map_objects/pics/people/bug_catcher/4.4bpp");
+const u32 gMapObjectPic_BugCatcher_5[] = INCBIN_U32("graphics/map_objects/pics/people/bug_catcher/5.4bpp");
+const u32 gMapObjectPic_BugCatcher_6[] = INCBIN_U32("graphics/map_objects/pics/people/bug_catcher/6.4bpp");
+const u32 gMapObjectPic_BugCatcher_7[] = INCBIN_U32("graphics/map_objects/pics/people/bug_catcher/7.4bpp");
+const u32 gMapObjectPic_BugCatcher_8[] = INCBIN_U32("graphics/map_objects/pics/people/bug_catcher/8.4bpp");
+const u32 gMapObjectPic_PsychicM_0[] = INCBIN_U32("graphics/map_objects/pics/people/psychic_m/0.4bpp");
+const u32 gMapObjectPic_PsychicM_1[] = INCBIN_U32("graphics/map_objects/pics/people/psychic_m/1.4bpp");
+const u32 gMapObjectPic_PsychicM_2[] = INCBIN_U32("graphics/map_objects/pics/people/psychic_m/2.4bpp");
+const u32 gMapObjectPic_PsychicM_3[] = INCBIN_U32("graphics/map_objects/pics/people/psychic_m/3.4bpp");
+const u32 gMapObjectPic_PsychicM_4[] = INCBIN_U32("graphics/map_objects/pics/people/psychic_m/4.4bpp");
+const u32 gMapObjectPic_PsychicM_5[] = INCBIN_U32("graphics/map_objects/pics/people/psychic_m/5.4bpp");
+const u32 gMapObjectPic_PsychicM_6[] = INCBIN_U32("graphics/map_objects/pics/people/psychic_m/6.4bpp");
+const u32 gMapObjectPic_PsychicM_7[] = INCBIN_U32("graphics/map_objects/pics/people/psychic_m/7.4bpp");
+const u32 gMapObjectPic_PsychicM_8[] = INCBIN_U32("graphics/map_objects/pics/people/psychic_m/8.4bpp");
+const u32 gMapObjectPic_SchoolKidM_0[] = INCBIN_U32("graphics/map_objects/pics/people/school_kid_m/0.4bpp");
+const u32 gMapObjectPic_SchoolKidM_1[] = INCBIN_U32("graphics/map_objects/pics/people/school_kid_m/1.4bpp");
+const u32 gMapObjectPic_SchoolKidM_2[] = INCBIN_U32("graphics/map_objects/pics/people/school_kid_m/2.4bpp");
+const u32 gMapObjectPic_SchoolKidM_3[] = INCBIN_U32("graphics/map_objects/pics/people/school_kid_m/3.4bpp");
+const u32 gMapObjectPic_SchoolKidM_4[] = INCBIN_U32("graphics/map_objects/pics/people/school_kid_m/4.4bpp");
+const u32 gMapObjectPic_SchoolKidM_5[] = INCBIN_U32("graphics/map_objects/pics/people/school_kid_m/5.4bpp");
+const u32 gMapObjectPic_SchoolKidM_6[] = INCBIN_U32("graphics/map_objects/pics/people/school_kid_m/6.4bpp");
+const u32 gMapObjectPic_SchoolKidM_7[] = INCBIN_U32("graphics/map_objects/pics/people/school_kid_m/7.4bpp");
+const u32 gMapObjectPic_SchoolKidM_8[] = INCBIN_U32("graphics/map_objects/pics/people/school_kid_m/8.4bpp");
+const u32 gMapObjectPic_Maniac_0[] = INCBIN_U32("graphics/map_objects/pics/people/maniac/0.4bpp");
+const u32 gMapObjectPic_Maniac_1[] = INCBIN_U32("graphics/map_objects/pics/people/maniac/1.4bpp");
+const u32 gMapObjectPic_Maniac_2[] = INCBIN_U32("graphics/map_objects/pics/people/maniac/2.4bpp");
+const u32 gMapObjectPic_Maniac_3[] = INCBIN_U32("graphics/map_objects/pics/people/maniac/3.4bpp");
+const u32 gMapObjectPic_Maniac_4[] = INCBIN_U32("graphics/map_objects/pics/people/maniac/4.4bpp");
+const u32 gMapObjectPic_Maniac_5[] = INCBIN_U32("graphics/map_objects/pics/people/maniac/5.4bpp");
+const u32 gMapObjectPic_Maniac_6[] = INCBIN_U32("graphics/map_objects/pics/people/maniac/6.4bpp");
+const u32 gMapObjectPic_Maniac_7[] = INCBIN_U32("graphics/map_objects/pics/people/maniac/7.4bpp");
+const u32 gMapObjectPic_Maniac_8[] = INCBIN_U32("graphics/map_objects/pics/people/maniac/8.4bpp");
+const u32 gMapObjectPic_HexManiac_0[] = INCBIN_U32("graphics/map_objects/pics/people/hex_maniac/0.4bpp");
+const u32 gMapObjectPic_HexManiac_1[] = INCBIN_U32("graphics/map_objects/pics/people/hex_maniac/1.4bpp");
+const u32 gMapObjectPic_HexManiac_2[] = INCBIN_U32("graphics/map_objects/pics/people/hex_maniac/2.4bpp");
+const u32 gMapObjectPic_HexManiac_3[] = INCBIN_U32("graphics/map_objects/pics/people/hex_maniac/3.4bpp");
+const u32 gMapObjectPic_HexManiac_4[] = INCBIN_U32("graphics/map_objects/pics/people/hex_maniac/4.4bpp");
+const u32 gMapObjectPic_HexManiac_5[] = INCBIN_U32("graphics/map_objects/pics/people/hex_maniac/5.4bpp");
+const u32 gMapObjectPic_HexManiac_6[] = INCBIN_U32("graphics/map_objects/pics/people/hex_maniac/6.4bpp");
+const u32 gMapObjectPic_HexManiac_7[] = INCBIN_U32("graphics/map_objects/pics/people/hex_maniac/7.4bpp");
+const u32 gMapObjectPic_HexManiac_8[] = INCBIN_U32("graphics/map_objects/pics/people/hex_maniac/8.4bpp");
+const u32 gMapObjectPic_Woman8_0[] = INCBIN_U32("graphics/map_objects/pics/people/woman_8/0.4bpp");
+const u32 gMapObjectPic_Woman8_1[] = INCBIN_U32("graphics/map_objects/pics/people/woman_8/1.4bpp");
+const u32 gMapObjectPic_Woman8_2[] = INCBIN_U32("graphics/map_objects/pics/people/woman_8/2.4bpp");
+const u32 gMapObjectPic_Woman8_3[] = INCBIN_U32("graphics/map_objects/pics/people/woman_8/3.4bpp");
+const u32 gMapObjectPic_Woman8_4[] = INCBIN_U32("graphics/map_objects/pics/people/woman_8/4.4bpp");
+const u32 gMapObjectPic_Woman8_5[] = INCBIN_U32("graphics/map_objects/pics/people/woman_8/5.4bpp");
+const u32 gMapObjectPic_Woman8_6[] = INCBIN_U32("graphics/map_objects/pics/people/woman_8/6.4bpp");
+const u32 gMapObjectPic_Woman8_7[] = INCBIN_U32("graphics/map_objects/pics/people/woman_8/7.4bpp");
+const u32 gMapObjectPic_Woman8_8[] = INCBIN_U32("graphics/map_objects/pics/people/woman_8/8.4bpp");
+const u32 gMapObjectPic_SwimmerM_0[] = INCBIN_U32("graphics/map_objects/pics/people/swimmer_m/0.4bpp");
+const u32 gMapObjectPic_SwimmerM_1[] = INCBIN_U32("graphics/map_objects/pics/people/swimmer_m/1.4bpp");
+const u32 gMapObjectPic_SwimmerM_2[] = INCBIN_U32("graphics/map_objects/pics/people/swimmer_m/2.4bpp");
+const u32 gMapObjectPic_SwimmerM_3[] = INCBIN_U32("graphics/map_objects/pics/people/swimmer_m/3.4bpp");
+const u32 gMapObjectPic_SwimmerM_4[] = INCBIN_U32("graphics/map_objects/pics/people/swimmer_m/4.4bpp");
+const u32 gMapObjectPic_SwimmerM_5[] = INCBIN_U32("graphics/map_objects/pics/people/swimmer_m/5.4bpp");
+const u32 gMapObjectPic_SwimmerM_6[] = INCBIN_U32("graphics/map_objects/pics/people/swimmer_m/6.4bpp");
+const u32 gMapObjectPic_SwimmerM_7[] = INCBIN_U32("graphics/map_objects/pics/people/swimmer_m/7.4bpp");
+const u32 gMapObjectPic_SwimmerM_8[] = INCBIN_U32("graphics/map_objects/pics/people/swimmer_m/8.4bpp");
+const u32 gMapObjectPic_SwimmerF_0[] = INCBIN_U32("graphics/map_objects/pics/people/swimmer_f/0.4bpp");
+const u32 gMapObjectPic_SwimmerF_1[] = INCBIN_U32("graphics/map_objects/pics/people/swimmer_f/1.4bpp");
+const u32 gMapObjectPic_SwimmerF_2[] = INCBIN_U32("graphics/map_objects/pics/people/swimmer_f/2.4bpp");
+const u32 gMapObjectPic_SwimmerF_3[] = INCBIN_U32("graphics/map_objects/pics/people/swimmer_f/3.4bpp");
+const u32 gMapObjectPic_SwimmerF_4[] = INCBIN_U32("graphics/map_objects/pics/people/swimmer_f/4.4bpp");
+const u32 gMapObjectPic_SwimmerF_5[] = INCBIN_U32("graphics/map_objects/pics/people/swimmer_f/5.4bpp");
+const u32 gMapObjectPic_SwimmerF_6[] = INCBIN_U32("graphics/map_objects/pics/people/swimmer_f/6.4bpp");
+const u32 gMapObjectPic_SwimmerF_7[] = INCBIN_U32("graphics/map_objects/pics/people/swimmer_f/7.4bpp");
+const u32 gMapObjectPic_SwimmerF_8[] = INCBIN_U32("graphics/map_objects/pics/people/swimmer_f/8.4bpp");
+const u32 gMapObjectPic_BlackBelt_0[] = INCBIN_U32("graphics/map_objects/pics/people/black_belt/0.4bpp");
+const u32 gMapObjectPic_BlackBelt_1[] = INCBIN_U32("graphics/map_objects/pics/people/black_belt/1.4bpp");
+const u32 gMapObjectPic_BlackBelt_2[] = INCBIN_U32("graphics/map_objects/pics/people/black_belt/2.4bpp");
+const u32 gMapObjectPic_BlackBelt_3[] = INCBIN_U32("graphics/map_objects/pics/people/black_belt/3.4bpp");
+const u32 gMapObjectPic_BlackBelt_4[] = INCBIN_U32("graphics/map_objects/pics/people/black_belt/4.4bpp");
+const u32 gMapObjectPic_BlackBelt_5[] = INCBIN_U32("graphics/map_objects/pics/people/black_belt/5.4bpp");
+const u32 gMapObjectPic_BlackBelt_6[] = INCBIN_U32("graphics/map_objects/pics/people/black_belt/6.4bpp");
+const u32 gMapObjectPic_BlackBelt_7[] = INCBIN_U32("graphics/map_objects/pics/people/black_belt/7.4bpp");
+const u32 gMapObjectPic_BlackBelt_8[] = INCBIN_U32("graphics/map_objects/pics/people/black_belt/8.4bpp");
+const u32 gMapObjectPic_Beauty_0[] = INCBIN_U32("graphics/map_objects/pics/people/beauty/0.4bpp");
+const u32 gMapObjectPic_Beauty_1[] = INCBIN_U32("graphics/map_objects/pics/people/beauty/1.4bpp");
+const u32 gMapObjectPic_Beauty_2[] = INCBIN_U32("graphics/map_objects/pics/people/beauty/2.4bpp");
+const u32 gMapObjectPic_Beauty_3[] = INCBIN_U32("graphics/map_objects/pics/people/beauty/3.4bpp");
+const u32 gMapObjectPic_Beauty_4[] = INCBIN_U32("graphics/map_objects/pics/people/beauty/4.4bpp");
+const u32 gMapObjectPic_Beauty_5[] = INCBIN_U32("graphics/map_objects/pics/people/beauty/5.4bpp");
+const u32 gMapObjectPic_Beauty_6[] = INCBIN_U32("graphics/map_objects/pics/people/beauty/6.4bpp");
+const u32 gMapObjectPic_Beauty_7[] = INCBIN_U32("graphics/map_objects/pics/people/beauty/7.4bpp");
+const u32 gMapObjectPic_Beauty_8[] = INCBIN_U32("graphics/map_objects/pics/people/beauty/8.4bpp");
+const u32 gMapObjectPic_Scientist1_0[] = INCBIN_U32("graphics/map_objects/pics/people/scientist_1/0.4bpp");
+const u32 gMapObjectPic_Scientist1_1[] = INCBIN_U32("graphics/map_objects/pics/people/scientist_1/1.4bpp");
+const u32 gMapObjectPic_Scientist1_2[] = INCBIN_U32("graphics/map_objects/pics/people/scientist_1/2.4bpp");
+const u32 gMapObjectPic_Scientist1_3[] = INCBIN_U32("graphics/map_objects/pics/people/scientist_1/3.4bpp");
+const u32 gMapObjectPic_Scientist1_4[] = INCBIN_U32("graphics/map_objects/pics/people/scientist_1/4.4bpp");
+const u32 gMapObjectPic_Scientist1_5[] = INCBIN_U32("graphics/map_objects/pics/people/scientist_1/5.4bpp");
+const u32 gMapObjectPic_Scientist1_6[] = INCBIN_U32("graphics/map_objects/pics/people/scientist_1/6.4bpp");
+const u32 gMapObjectPic_Scientist1_7[] = INCBIN_U32("graphics/map_objects/pics/people/scientist_1/7.4bpp");
+const u32 gMapObjectPic_Scientist1_8[] = INCBIN_U32("graphics/map_objects/pics/people/scientist_1/8.4bpp");
+const u32 gMapObjectPic_Lass_0[] = INCBIN_U32("graphics/map_objects/pics/people/lass/0.4bpp");
+const u32 gMapObjectPic_Lass_1[] = INCBIN_U32("graphics/map_objects/pics/people/lass/1.4bpp");
+const u32 gMapObjectPic_Lass_2[] = INCBIN_U32("graphics/map_objects/pics/people/lass/2.4bpp");
+const u32 gMapObjectPic_Lass_3[] = INCBIN_U32("graphics/map_objects/pics/people/lass/3.4bpp");
+const u32 gMapObjectPic_Lass_4[] = INCBIN_U32("graphics/map_objects/pics/people/lass/4.4bpp");
+const u32 gMapObjectPic_Lass_5[] = INCBIN_U32("graphics/map_objects/pics/people/lass/5.4bpp");
+const u32 gMapObjectPic_Lass_6[] = INCBIN_U32("graphics/map_objects/pics/people/lass/6.4bpp");
+const u32 gMapObjectPic_Lass_7[] = INCBIN_U32("graphics/map_objects/pics/people/lass/7.4bpp");
+const u32 gMapObjectPic_Lass_8[] = INCBIN_U32("graphics/map_objects/pics/people/lass/8.4bpp");
+const u32 gMapObjectPic_Gentleman_0[] = INCBIN_U32("graphics/map_objects/pics/people/gentleman/0.4bpp");
+const u32 gMapObjectPic_Gentleman_1[] = INCBIN_U32("graphics/map_objects/pics/people/gentleman/1.4bpp");
+const u32 gMapObjectPic_Gentleman_2[] = INCBIN_U32("graphics/map_objects/pics/people/gentleman/2.4bpp");
+const u32 gMapObjectPic_Gentleman_3[] = INCBIN_U32("graphics/map_objects/pics/people/gentleman/3.4bpp");
+const u32 gMapObjectPic_Gentleman_4[] = INCBIN_U32("graphics/map_objects/pics/people/gentleman/4.4bpp");
+const u32 gMapObjectPic_Gentleman_5[] = INCBIN_U32("graphics/map_objects/pics/people/gentleman/5.4bpp");
+const u32 gMapObjectPic_Gentleman_6[] = INCBIN_U32("graphics/map_objects/pics/people/gentleman/6.4bpp");
+const u32 gMapObjectPic_Gentleman_7[] = INCBIN_U32("graphics/map_objects/pics/people/gentleman/7.4bpp");
+const u32 gMapObjectPic_Gentleman_8[] = INCBIN_U32("graphics/map_objects/pics/people/gentleman/8.4bpp");
+const u32 gMapObjectPic_Sailor_0[] = INCBIN_U32("graphics/map_objects/pics/people/sailor/0.4bpp");
+const u32 gMapObjectPic_Sailor_1[] = INCBIN_U32("graphics/map_objects/pics/people/sailor/1.4bpp");
+const u32 gMapObjectPic_Sailor_2[] = INCBIN_U32("graphics/map_objects/pics/people/sailor/2.4bpp");
+const u32 gMapObjectPic_Sailor_3[] = INCBIN_U32("graphics/map_objects/pics/people/sailor/3.4bpp");
+const u32 gMapObjectPic_Sailor_4[] = INCBIN_U32("graphics/map_objects/pics/people/sailor/4.4bpp");
+const u32 gMapObjectPic_Sailor_5[] = INCBIN_U32("graphics/map_objects/pics/people/sailor/5.4bpp");
+const u32 gMapObjectPic_Sailor_6[] = INCBIN_U32("graphics/map_objects/pics/people/sailor/6.4bpp");
+const u32 gMapObjectPic_Sailor_7[] = INCBIN_U32("graphics/map_objects/pics/people/sailor/7.4bpp");
+const u32 gMapObjectPic_Sailor_8[] = INCBIN_U32("graphics/map_objects/pics/people/sailor/8.4bpp");
+const u32 gMapObjectPic_Fisherman_0[] = INCBIN_U32("graphics/map_objects/pics/people/fisherman/0.4bpp");
+const u32 gMapObjectPic_Fisherman_1[] = INCBIN_U32("graphics/map_objects/pics/people/fisherman/1.4bpp");
+const u32 gMapObjectPic_Fisherman_2[] = INCBIN_U32("graphics/map_objects/pics/people/fisherman/2.4bpp");
+const u32 gMapObjectPic_Fisherman_3[] = INCBIN_U32("graphics/map_objects/pics/people/fisherman/3.4bpp");
+const u32 gMapObjectPic_Fisherman_4[] = INCBIN_U32("graphics/map_objects/pics/people/fisherman/4.4bpp");
+const u32 gMapObjectPic_Fisherman_5[] = INCBIN_U32("graphics/map_objects/pics/people/fisherman/5.4bpp");
+const u32 gMapObjectPic_Fisherman_6[] = INCBIN_U32("graphics/map_objects/pics/people/fisherman/6.4bpp");
+const u32 gMapObjectPic_Fisherman_7[] = INCBIN_U32("graphics/map_objects/pics/people/fisherman/7.4bpp");
+const u32 gMapObjectPic_Fisherman_8[] = INCBIN_U32("graphics/map_objects/pics/people/fisherman/8.4bpp");
+const u32 gMapObjectPic_RunningTriathleteM_0[] = INCBIN_U32("graphics/map_objects/pics/people/running_triathlete_m/0.4bpp");
+const u32 gMapObjectPic_RunningTriathleteM_1[] = INCBIN_U32("graphics/map_objects/pics/people/running_triathlete_m/1.4bpp");
+const u32 gMapObjectPic_RunningTriathleteM_2[] = INCBIN_U32("graphics/map_objects/pics/people/running_triathlete_m/2.4bpp");
+const u32 gMapObjectPic_RunningTriathleteM_3[] = INCBIN_U32("graphics/map_objects/pics/people/running_triathlete_m/3.4bpp");
+const u32 gMapObjectPic_RunningTriathleteM_4[] = INCBIN_U32("graphics/map_objects/pics/people/running_triathlete_m/4.4bpp");
+const u32 gMapObjectPic_RunningTriathleteM_5[] = INCBIN_U32("graphics/map_objects/pics/people/running_triathlete_m/5.4bpp");
+const u32 gMapObjectPic_RunningTriathleteM_6[] = INCBIN_U32("graphics/map_objects/pics/people/running_triathlete_m/6.4bpp");
+const u32 gMapObjectPic_RunningTriathleteM_7[] = INCBIN_U32("graphics/map_objects/pics/people/running_triathlete_m/7.4bpp");
+const u32 gMapObjectPic_RunningTriathleteM_8[] = INCBIN_U32("graphics/map_objects/pics/people/running_triathlete_m/8.4bpp");
+const u32 gMapObjectPic_RunningTriathleteF_0[] = INCBIN_U32("graphics/map_objects/pics/people/running_triathlete_f/0.4bpp");
+const u32 gMapObjectPic_RunningTriathleteF_1[] = INCBIN_U32("graphics/map_objects/pics/people/running_triathlete_f/1.4bpp");
+const u32 gMapObjectPic_RunningTriathleteF_2[] = INCBIN_U32("graphics/map_objects/pics/people/running_triathlete_f/2.4bpp");
+const u32 gMapObjectPic_RunningTriathleteF_3[] = INCBIN_U32("graphics/map_objects/pics/people/running_triathlete_f/3.4bpp");
+const u32 gMapObjectPic_RunningTriathleteF_4[] = INCBIN_U32("graphics/map_objects/pics/people/running_triathlete_f/4.4bpp");
+const u32 gMapObjectPic_RunningTriathleteF_5[] = INCBIN_U32("graphics/map_objects/pics/people/running_triathlete_f/5.4bpp");
+const u32 gMapObjectPic_RunningTriathleteF_6[] = INCBIN_U32("graphics/map_objects/pics/people/running_triathlete_f/6.4bpp");
+const u32 gMapObjectPic_RunningTriathleteF_7[] = INCBIN_U32("graphics/map_objects/pics/people/running_triathlete_f/7.4bpp");
+const u32 gMapObjectPic_RunningTriathleteF_8[] = INCBIN_U32("graphics/map_objects/pics/people/running_triathlete_f/8.4bpp");
+const u32 gMapObjectPic_TuberF_0[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_f/0.4bpp");
+const u32 gMapObjectPic_TuberF_1[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_f/1.4bpp");
+const u32 gMapObjectPic_TuberF_2[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_f/2.4bpp");
+const u32 gMapObjectPic_TuberF_3[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_f/3.4bpp");
+const u32 gMapObjectPic_TuberF_4[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_f/4.4bpp");
+const u32 gMapObjectPic_TuberF_5[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_f/5.4bpp");
+const u32 gMapObjectPic_TuberF_6[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_f/6.4bpp");
+const u32 gMapObjectPic_TuberF_7[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_f/7.4bpp");
+const u32 gMapObjectPic_TuberF_8[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_f/8.4bpp");
+const u32 gMapObjectPic_TuberM_0[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_m/0.4bpp");
+const u32 gMapObjectPic_TuberM_1[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_m/1.4bpp");
+const u32 gMapObjectPic_TuberM_2[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_m/2.4bpp");
+const u32 gMapObjectPic_TuberM_3[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_m/3.4bpp");
+const u32 gMapObjectPic_TuberM_4[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_m/4.4bpp");
+const u32 gMapObjectPic_TuberM_5[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_m/5.4bpp");
+const u32 gMapObjectPic_TuberM_6[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_m/6.4bpp");
+const u32 gMapObjectPic_TuberM_7[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_m/7.4bpp");
+const u32 gMapObjectPic_TuberM_8[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_m/8.4bpp");
+const u32 gMapObjectPic_Hiker_0[] = INCBIN_U32("graphics/map_objects/pics/people/hiker/0.4bpp");
+const u32 gMapObjectPic_Hiker_1[] = INCBIN_U32("graphics/map_objects/pics/people/hiker/1.4bpp");
+const u32 gMapObjectPic_Hiker_2[] = INCBIN_U32("graphics/map_objects/pics/people/hiker/2.4bpp");
+const u32 gMapObjectPic_Hiker_3[] = INCBIN_U32("graphics/map_objects/pics/people/hiker/3.4bpp");
+const u32 gMapObjectPic_Hiker_4[] = INCBIN_U32("graphics/map_objects/pics/people/hiker/4.4bpp");
+const u32 gMapObjectPic_Hiker_5[] = INCBIN_U32("graphics/map_objects/pics/people/hiker/5.4bpp");
+const u32 gMapObjectPic_Hiker_6[] = INCBIN_U32("graphics/map_objects/pics/people/hiker/6.4bpp");
+const u32 gMapObjectPic_Hiker_7[] = INCBIN_U32("graphics/map_objects/pics/people/hiker/7.4bpp");
+const u32 gMapObjectPic_Hiker_8[] = INCBIN_U32("graphics/map_objects/pics/people/hiker/8.4bpp");
+const u32 gMapObjectPic_CyclingTriathleteM_0[] = INCBIN_U32("graphics/map_objects/pics/people/cycling_triathlete_m/0.4bpp");
+const u32 gMapObjectPic_CyclingTriathleteM_1[] = INCBIN_U32("graphics/map_objects/pics/people/cycling_triathlete_m/1.4bpp");
+const u32 gMapObjectPic_CyclingTriathleteM_2[] = INCBIN_U32("graphics/map_objects/pics/people/cycling_triathlete_m/2.4bpp");
+const u32 gMapObjectPic_CyclingTriathleteM_3[] = INCBIN_U32("graphics/map_objects/pics/people/cycling_triathlete_m/3.4bpp");
+const u32 gMapObjectPic_CyclingTriathleteM_4[] = INCBIN_U32("graphics/map_objects/pics/people/cycling_triathlete_m/4.4bpp");
+const u32 gMapObjectPic_CyclingTriathleteM_5[] = INCBIN_U32("graphics/map_objects/pics/people/cycling_triathlete_m/5.4bpp");
+const u32 gMapObjectPic_CyclingTriathleteM_6[] = INCBIN_U32("graphics/map_objects/pics/people/cycling_triathlete_m/6.4bpp");
+const u32 gMapObjectPic_CyclingTriathleteM_7[] = INCBIN_U32("graphics/map_objects/pics/people/cycling_triathlete_m/7.4bpp");
+const u32 gMapObjectPic_CyclingTriathleteM_8[] = INCBIN_U32("graphics/map_objects/pics/people/cycling_triathlete_m/8.4bpp");
+const u32 gMapObjectPic_CyclingTriathleteF_0[] = INCBIN_U32("graphics/map_objects/pics/people/cycling_triathlete_f/0.4bpp");
+const u32 gMapObjectPic_CyclingTriathleteF_1[] = INCBIN_U32("graphics/map_objects/pics/people/cycling_triathlete_f/1.4bpp");
+const u32 gMapObjectPic_CyclingTriathleteF_2[] = INCBIN_U32("graphics/map_objects/pics/people/cycling_triathlete_f/2.4bpp");
+const u32 gMapObjectPic_CyclingTriathleteF_3[] = INCBIN_U32("graphics/map_objects/pics/people/cycling_triathlete_f/3.4bpp");
+const u32 gMapObjectPic_CyclingTriathleteF_4[] = INCBIN_U32("graphics/map_objects/pics/people/cycling_triathlete_f/4.4bpp");
+const u32 gMapObjectPic_CyclingTriathleteF_5[] = INCBIN_U32("graphics/map_objects/pics/people/cycling_triathlete_f/5.4bpp");
+const u32 gMapObjectPic_CyclingTriathleteF_6[] = INCBIN_U32("graphics/map_objects/pics/people/cycling_triathlete_f/6.4bpp");
+const u32 gMapObjectPic_CyclingTriathleteF_7[] = INCBIN_U32("graphics/map_objects/pics/people/cycling_triathlete_f/7.4bpp");
+const u32 gMapObjectPic_CyclingTriathleteF_8[] = INCBIN_U32("graphics/map_objects/pics/people/cycling_triathlete_f/8.4bpp");
+const u32 gMapObjectPic_Man5_0[] = INCBIN_U32("graphics/map_objects/pics/people/man_5/0.4bpp");
+const u32 gMapObjectPic_Man5_1[] = INCBIN_U32("graphics/map_objects/pics/people/man_5/1.4bpp");
+const u32 gMapObjectPic_Man5_2[] = INCBIN_U32("graphics/map_objects/pics/people/man_5/2.4bpp");
+const u32 gMapObjectPic_Man5_3[] = INCBIN_U32("graphics/map_objects/pics/people/man_5/3.4bpp");
+const u32 gMapObjectPic_Man5_4[] = INCBIN_U32("graphics/map_objects/pics/people/man_5/4.4bpp");
+const u32 gMapObjectPic_Man5_5[] = INCBIN_U32("graphics/map_objects/pics/people/man_5/5.4bpp");
+const u32 gMapObjectPic_Man5_6[] = INCBIN_U32("graphics/map_objects/pics/people/man_5/6.4bpp");
+const u32 gMapObjectPic_Man5_7[] = INCBIN_U32("graphics/map_objects/pics/people/man_5/7.4bpp");
+const u32 gMapObjectPic_Man5_8[] = INCBIN_U32("graphics/map_objects/pics/people/man_5/8.4bpp");
+const u32 gMapObjectPic_Man6_0[] = INCBIN_U32("graphics/map_objects/pics/people/man_6/0.4bpp");
+const u32 gMapObjectPic_Man6_1[] = INCBIN_U32("graphics/map_objects/pics/people/man_6/1.4bpp");
+const u32 gMapObjectPic_Man6_2[] = INCBIN_U32("graphics/map_objects/pics/people/man_6/2.4bpp");
+const u32 gMapObjectPic_Man6_3[] = INCBIN_U32("graphics/map_objects/pics/people/man_6/3.4bpp");
+const u32 gMapObjectPic_Man6_4[] = INCBIN_U32("graphics/map_objects/pics/people/man_6/4.4bpp");
+const u32 gMapObjectPic_Man6_5[] = INCBIN_U32("graphics/map_objects/pics/people/man_6/5.4bpp");
+const u32 gMapObjectPic_Man6_6[] = INCBIN_U32("graphics/map_objects/pics/people/man_6/6.4bpp");
+const u32 gMapObjectPic_Man6_7[] = INCBIN_U32("graphics/map_objects/pics/people/man_6/7.4bpp");
+const u32 gMapObjectPic_Man6_8[] = INCBIN_U32("graphics/map_objects/pics/people/man_6/8.4bpp");
+const u32 gMapObjectPic_Nurse_0[] = INCBIN_U32("graphics/map_objects/pics/people/nurse/0.4bpp");
+const u32 gMapObjectPic_Nurse_1[] = INCBIN_U32("graphics/map_objects/pics/people/nurse/1.4bpp");
+const u32 gMapObjectPic_Nurse_2[] = INCBIN_U32("graphics/map_objects/pics/people/nurse/2.4bpp");
+const u32 gMapObjectPic_Nurse_3[] = INCBIN_U32("graphics/map_objects/pics/people/nurse/3.4bpp");
+const u32 gMapObjectPic_Nurse_4[] = INCBIN_U32("graphics/map_objects/pics/people/nurse/4.4bpp");
+const u32 gMapObjectPic_Nurse_5[] = INCBIN_U32("graphics/map_objects/pics/people/nurse/5.4bpp");
+const u32 gMapObjectPic_Nurse_6[] = INCBIN_U32("graphics/map_objects/pics/people/nurse/6.4bpp");
+const u32 gMapObjectPic_Nurse_7[] = INCBIN_U32("graphics/map_objects/pics/people/nurse/7.4bpp");
+const u32 gMapObjectPic_Nurse_8[] = INCBIN_U32("graphics/map_objects/pics/people/nurse/8.4bpp");
+const u32 gMapObjectPic_Nurse_9[] = INCBIN_U32("graphics/map_objects/pics/people/nurse/9.4bpp");
+const u32 gMapObjectPic_ItemBall[] = INCBIN_U32("graphics/map_objects/pics/misc/item_ball.4bpp");
+const u32 gMapObjectPic_ProfBirch_0[] = INCBIN_U32("graphics/map_objects/pics/people/prof_birch/0.4bpp");
+const u32 gMapObjectPic_ProfBirch_1[] = INCBIN_U32("graphics/map_objects/pics/people/prof_birch/1.4bpp");
+const u32 gMapObjectPic_ProfBirch_2[] = INCBIN_U32("graphics/map_objects/pics/people/prof_birch/2.4bpp");
+const u32 gMapObjectPic_ProfBirch_3[] = INCBIN_U32("graphics/map_objects/pics/people/prof_birch/3.4bpp");
+const u32 gMapObjectPic_ProfBirch_4[] = INCBIN_U32("graphics/map_objects/pics/people/prof_birch/4.4bpp");
+const u32 gMapObjectPic_ProfBirch_5[] = INCBIN_U32("graphics/map_objects/pics/people/prof_birch/5.4bpp");
+const u32 gMapObjectPic_ProfBirch_6[] = INCBIN_U32("graphics/map_objects/pics/people/prof_birch/6.4bpp");
+const u32 gMapObjectPic_ProfBirch_7[] = INCBIN_U32("graphics/map_objects/pics/people/prof_birch/7.4bpp");
+const u32 gMapObjectPic_ProfBirch_8[] = INCBIN_U32("graphics/map_objects/pics/people/prof_birch/8.4bpp");
+const u32 gMapObjectPic_ReporterM_0[] = INCBIN_U32("graphics/map_objects/pics/people/reporter_m/0.4bpp");
+const u32 gMapObjectPic_ReporterM_1[] = INCBIN_U32("graphics/map_objects/pics/people/reporter_m/1.4bpp");
+const u32 gMapObjectPic_ReporterM_2[] = INCBIN_U32("graphics/map_objects/pics/people/reporter_m/2.4bpp");
+const u32 gMapObjectPic_ReporterM_3[] = INCBIN_U32("graphics/map_objects/pics/people/reporter_m/3.4bpp");
+const u32 gMapObjectPic_ReporterM_4[] = INCBIN_U32("graphics/map_objects/pics/people/reporter_m/4.4bpp");
+const u32 gMapObjectPic_ReporterM_5[] = INCBIN_U32("graphics/map_objects/pics/people/reporter_m/5.4bpp");
+const u32 gMapObjectPic_ReporterM_6[] = INCBIN_U32("graphics/map_objects/pics/people/reporter_m/6.4bpp");
+const u32 gMapObjectPic_ReporterM_7[] = INCBIN_U32("graphics/map_objects/pics/people/reporter_m/7.4bpp");
+const u32 gMapObjectPic_ReporterM_8[] = INCBIN_U32("graphics/map_objects/pics/people/reporter_m/8.4bpp");
+const u32 gMapObjectPic_ReporterF_0[] = INCBIN_U32("graphics/map_objects/pics/people/reporter_f/0.4bpp");
+const u32 gMapObjectPic_ReporterF_1[] = INCBIN_U32("graphics/map_objects/pics/people/reporter_f/1.4bpp");
+const u32 gMapObjectPic_ReporterF_2[] = INCBIN_U32("graphics/map_objects/pics/people/reporter_f/2.4bpp");
+const u32 gMapObjectPic_ReporterF_3[] = INCBIN_U32("graphics/map_objects/pics/people/reporter_f/3.4bpp");
+const u32 gMapObjectPic_ReporterF_4[] = INCBIN_U32("graphics/map_objects/pics/people/reporter_f/4.4bpp");
+const u32 gMapObjectPic_ReporterF_5[] = INCBIN_U32("graphics/map_objects/pics/people/reporter_f/5.4bpp");
+const u32 gMapObjectPic_ReporterF_6[] = INCBIN_U32("graphics/map_objects/pics/people/reporter_f/6.4bpp");
+const u32 gMapObjectPic_ReporterF_7[] = INCBIN_U32("graphics/map_objects/pics/people/reporter_f/7.4bpp");
+const u32 gMapObjectPic_ReporterF_8[] = INCBIN_U32("graphics/map_objects/pics/people/reporter_f/8.4bpp");
+const u32 gMapObjectPic_MauvilleOldMan1_0[] = INCBIN_U32("graphics/map_objects/pics/people/mauville_old_man_1/0.4bpp");
+const u32 gMapObjectPic_MauvilleOldMan1_1[] = INCBIN_U32("graphics/map_objects/pics/people/mauville_old_man_1/1.4bpp");
+const u32 gMapObjectPic_MauvilleOldMan1_2[] = INCBIN_U32("graphics/map_objects/pics/people/mauville_old_man_1/2.4bpp");
+const u32 gMapObjectPic_MauvilleOldMan1_3[] = INCBIN_U32("graphics/map_objects/pics/people/mauville_old_man_1/3.4bpp");
+const u32 gMapObjectPic_MauvilleOldMan1_4[] = INCBIN_U32("graphics/map_objects/pics/people/mauville_old_man_1/4.4bpp");
+const u32 gMapObjectPic_MauvilleOldMan1_5[] = INCBIN_U32("graphics/map_objects/pics/people/mauville_old_man_1/5.4bpp");
+const u32 gMapObjectPic_MauvilleOldMan1_6[] = INCBIN_U32("graphics/map_objects/pics/people/mauville_old_man_1/6.4bpp");
+const u32 gMapObjectPic_MauvilleOldMan1_7[] = INCBIN_U32("graphics/map_objects/pics/people/mauville_old_man_1/7.4bpp");
+const u32 gMapObjectPic_MauvilleOldMan1_8[] = INCBIN_U32("graphics/map_objects/pics/people/mauville_old_man_1/8.4bpp");
+const u32 gMapObjectPic_MauvilleOldMan2_0[] = INCBIN_U32("graphics/map_objects/pics/people/mauville_old_man_2/0.4bpp");
+const u32 gMapObjectPic_MauvilleOldMan2_1[] = INCBIN_U32("graphics/map_objects/pics/people/mauville_old_man_2/1.4bpp");
+const u32 gMapObjectPic_MauvilleOldMan2_2[] = INCBIN_U32("graphics/map_objects/pics/people/mauville_old_man_2/2.4bpp");
+const u32 gMapObjectPic_MauvilleOldMan2_3[] = INCBIN_U32("graphics/map_objects/pics/people/mauville_old_man_2/3.4bpp");
+const u32 gMapObjectPic_MauvilleOldMan2_4[] = INCBIN_U32("graphics/map_objects/pics/people/mauville_old_man_2/4.4bpp");
+const u32 gMapObjectPic_MauvilleOldMan2_5[] = INCBIN_U32("graphics/map_objects/pics/people/mauville_old_man_2/5.4bpp");
+const u32 gMapObjectPic_MauvilleOldMan2_6[] = INCBIN_U32("graphics/map_objects/pics/people/mauville_old_man_2/6.4bpp");
+const u32 gMapObjectPic_MauvilleOldMan2_7[] = INCBIN_U32("graphics/map_objects/pics/people/mauville_old_man_2/7.4bpp");
+const u32 gMapObjectPic_MauvilleOldMan2_8[] = INCBIN_U32("graphics/map_objects/pics/people/mauville_old_man_2/8.4bpp");
+const u32 gMapObjectPic_MartEmployee_0[] = INCBIN_U32("graphics/map_objects/pics/people/mart_employee/0.4bpp");
+const u32 gMapObjectPic_MartEmployee_1[] = INCBIN_U32("graphics/map_objects/pics/people/mart_employee/1.4bpp");
+const u32 gMapObjectPic_MartEmployee_2[] = INCBIN_U32("graphics/map_objects/pics/people/mart_employee/2.4bpp");
+const u32 gMapObjectPic_MartEmployee_3[] = INCBIN_U32("graphics/map_objects/pics/people/mart_employee/3.4bpp");
+const u32 gMapObjectPic_MartEmployee_4[] = INCBIN_U32("graphics/map_objects/pics/people/mart_employee/4.4bpp");
+const u32 gMapObjectPic_MartEmployee_5[] = INCBIN_U32("graphics/map_objects/pics/people/mart_employee/5.4bpp");
+const u32 gMapObjectPic_MartEmployee_6[] = INCBIN_U32("graphics/map_objects/pics/people/mart_employee/6.4bpp");
+const u32 gMapObjectPic_MartEmployee_7[] = INCBIN_U32("graphics/map_objects/pics/people/mart_employee/7.4bpp");
+const u32 gMapObjectPic_MartEmployee_8[] = INCBIN_U32("graphics/map_objects/pics/people/mart_employee/8.4bpp");
+const u32 gMapObjectPic_RooftopSaleWoman_0[] = INCBIN_U32("graphics/map_objects/pics/people/rooftop_sale_woman/0.4bpp");
+const u32 gMapObjectPic_RooftopSaleWoman_1[] = INCBIN_U32("graphics/map_objects/pics/people/rooftop_sale_woman/1.4bpp");
+const u32 gMapObjectPic_RooftopSaleWoman_2[] = INCBIN_U32("graphics/map_objects/pics/people/rooftop_sale_woman/2.4bpp");
+const u32 gMapObjectPic_RooftopSaleWoman_3[] = INCBIN_U32("graphics/map_objects/pics/people/rooftop_sale_woman/3.4bpp");
+const u32 gMapObjectPic_RooftopSaleWoman_4[] = INCBIN_U32("graphics/map_objects/pics/people/rooftop_sale_woman/4.4bpp");
+const u32 gMapObjectPic_RooftopSaleWoman_5[] = INCBIN_U32("graphics/map_objects/pics/people/rooftop_sale_woman/5.4bpp");
+const u32 gMapObjectPic_RooftopSaleWoman_6[] = INCBIN_U32("graphics/map_objects/pics/people/rooftop_sale_woman/6.4bpp");
+const u32 gMapObjectPic_RooftopSaleWoman_7[] = INCBIN_U32("graphics/map_objects/pics/people/rooftop_sale_woman/7.4bpp");
+const u32 gMapObjectPic_RooftopSaleWoman_8[] = INCBIN_U32("graphics/map_objects/pics/people/rooftop_sale_woman/8.4bpp");
+const u32 gMapObjectPic_Teala_0[] = INCBIN_U32("graphics/map_objects/pics/people/teala/0.4bpp");
+const u32 gMapObjectPic_Teala_1[] = INCBIN_U32("graphics/map_objects/pics/people/teala/1.4bpp");
+const u32 gMapObjectPic_Teala_2[] = INCBIN_U32("graphics/map_objects/pics/people/teala/2.4bpp");
+const u32 gMapObjectPic_Teala_3[] = INCBIN_U32("graphics/map_objects/pics/people/teala/3.4bpp");
+const u32 gMapObjectPic_Teala_4[] = INCBIN_U32("graphics/map_objects/pics/people/teala/4.4bpp");
+const u32 gMapObjectPic_Teala_5[] = INCBIN_U32("graphics/map_objects/pics/people/teala/5.4bpp");
+const u32 gMapObjectPic_Teala_6[] = INCBIN_U32("graphics/map_objects/pics/people/teala/6.4bpp");
+const u32 gMapObjectPic_Teala_7[] = INCBIN_U32("graphics/map_objects/pics/people/teala/7.4bpp");
+const u32 gMapObjectPic_Teala_8[] = INCBIN_U32("graphics/map_objects/pics/people/teala/8.4bpp");
+const u32 gMapObjectPic_Artist_0[] = INCBIN_U32("graphics/map_objects/pics/people/artist/0.4bpp");
+const u32 gMapObjectPic_Artist_1[] = INCBIN_U32("graphics/map_objects/pics/people/artist/1.4bpp");
+const u32 gMapObjectPic_Artist_2[] = INCBIN_U32("graphics/map_objects/pics/people/artist/2.4bpp");
+const u32 gMapObjectPic_Artist_3[] = INCBIN_U32("graphics/map_objects/pics/people/artist/3.4bpp");
+const u32 gMapObjectPic_Artist_4[] = INCBIN_U32("graphics/map_objects/pics/people/artist/4.4bpp");
+const u32 gMapObjectPic_Artist_5[] = INCBIN_U32("graphics/map_objects/pics/people/artist/5.4bpp");
+const u32 gMapObjectPic_Artist_6[] = INCBIN_U32("graphics/map_objects/pics/people/artist/6.4bpp");
+const u32 gMapObjectPic_Artist_7[] = INCBIN_U32("graphics/map_objects/pics/people/artist/7.4bpp");
+const u32 gMapObjectPic_Artist_8[] = INCBIN_U32("graphics/map_objects/pics/people/artist/8.4bpp");
+const u32 gMapObjectPic_Cameraman_0[] = INCBIN_U32("graphics/map_objects/pics/people/cameraman/0.4bpp");
+const u32 gMapObjectPic_Cameraman_1[] = INCBIN_U32("graphics/map_objects/pics/people/cameraman/1.4bpp");
+const u32 gMapObjectPic_Cameraman_2[] = INCBIN_U32("graphics/map_objects/pics/people/cameraman/2.4bpp");
+const u32 gMapObjectPic_Cameraman_3[] = INCBIN_U32("graphics/map_objects/pics/people/cameraman/3.4bpp");
+const u32 gMapObjectPic_Cameraman_4[] = INCBIN_U32("graphics/map_objects/pics/people/cameraman/4.4bpp");
+const u32 gMapObjectPic_Cameraman_5[] = INCBIN_U32("graphics/map_objects/pics/people/cameraman/5.4bpp");
+const u32 gMapObjectPic_Cameraman_6[] = INCBIN_U32("graphics/map_objects/pics/people/cameraman/6.4bpp");
+const u32 gMapObjectPic_Cameraman_7[] = INCBIN_U32("graphics/map_objects/pics/people/cameraman/7.4bpp");
+const u32 gMapObjectPic_Cameraman_8[] = INCBIN_U32("graphics/map_objects/pics/people/cameraman/8.4bpp");
+const u32 gMapObjectPic_Scientist2_0[] = INCBIN_U32("graphics/map_objects/pics/people/scientist_2/0.4bpp");
+const u32 gMapObjectPic_Scientist2_1[] = INCBIN_U32("graphics/map_objects/pics/people/scientist_2/1.4bpp");
+const u32 gMapObjectPic_Scientist2_2[] = INCBIN_U32("graphics/map_objects/pics/people/scientist_2/2.4bpp");
+const u32 gMapObjectPic_Scientist2_3[] = INCBIN_U32("graphics/map_objects/pics/people/scientist_2/3.4bpp");
+const u32 gMapObjectPic_Scientist2_4[] = INCBIN_U32("graphics/map_objects/pics/people/scientist_2/4.4bpp");
+const u32 gMapObjectPic_Scientist2_5[] = INCBIN_U32("graphics/map_objects/pics/people/scientist_2/5.4bpp");
+const u32 gMapObjectPic_Scientist2_6[] = INCBIN_U32("graphics/map_objects/pics/people/scientist_2/6.4bpp");
+const u32 gMapObjectPic_Scientist2_7[] = INCBIN_U32("graphics/map_objects/pics/people/scientist_2/7.4bpp");
+const u32 gMapObjectPic_Scientist2_8[] = INCBIN_U32("graphics/map_objects/pics/people/scientist_2/8.4bpp");
+const u32 gMapObjectPic_Man7_0[] = INCBIN_U32("graphics/map_objects/pics/people/man_7/0.4bpp");
+const u32 gMapObjectPic_Man7_1[] = INCBIN_U32("graphics/map_objects/pics/people/man_7/1.4bpp");
+const u32 gMapObjectPic_Man7_2[] = INCBIN_U32("graphics/map_objects/pics/people/man_7/2.4bpp");
+const u32 gMapObjectPic_Man7_3[] = INCBIN_U32("graphics/map_objects/pics/people/man_7/3.4bpp");
+const u32 gMapObjectPic_Man7_4[] = INCBIN_U32("graphics/map_objects/pics/people/man_7/4.4bpp");
+const u32 gMapObjectPic_Man7_5[] = INCBIN_U32("graphics/map_objects/pics/people/man_7/5.4bpp");
+const u32 gMapObjectPic_Man7_6[] = INCBIN_U32("graphics/map_objects/pics/people/man_7/6.4bpp");
+const u32 gMapObjectPic_Man7_7[] = INCBIN_U32("graphics/map_objects/pics/people/man_7/7.4bpp");
+const u32 gMapObjectPic_Man7_8[] = INCBIN_U32("graphics/map_objects/pics/people/man_7/8.4bpp");
+const u32 gMapObjectPic_AquaMemberM_0[] = INCBIN_U32("graphics/map_objects/pics/people/aqua_member_m/0.4bpp");
+const u32 gMapObjectPic_AquaMemberM_1[] = INCBIN_U32("graphics/map_objects/pics/people/aqua_member_m/1.4bpp");
+const u32 gMapObjectPic_AquaMemberM_2[] = INCBIN_U32("graphics/map_objects/pics/people/aqua_member_m/2.4bpp");
+const u32 gMapObjectPic_AquaMemberM_3[] = INCBIN_U32("graphics/map_objects/pics/people/aqua_member_m/3.4bpp");
+const u32 gMapObjectPic_AquaMemberM_4[] = INCBIN_U32("graphics/map_objects/pics/people/aqua_member_m/4.4bpp");
+const u32 gMapObjectPic_AquaMemberM_5[] = INCBIN_U32("graphics/map_objects/pics/people/aqua_member_m/5.4bpp");
+const u32 gMapObjectPic_AquaMemberM_6[] = INCBIN_U32("graphics/map_objects/pics/people/aqua_member_m/6.4bpp");
+const u32 gMapObjectPic_AquaMemberM_7[] = INCBIN_U32("graphics/map_objects/pics/people/aqua_member_m/7.4bpp");
+const u32 gMapObjectPic_AquaMemberM_8[] = INCBIN_U32("graphics/map_objects/pics/people/aqua_member_m/8.4bpp");
+const u32 gMapObjectPic_AquaMemberF_0[] = INCBIN_U32("graphics/map_objects/pics/people/aqua_member_f/0.4bpp");
+const u32 gMapObjectPic_AquaMemberF_1[] = INCBIN_U32("graphics/map_objects/pics/people/aqua_member_f/1.4bpp");
+const u32 gMapObjectPic_AquaMemberF_2[] = INCBIN_U32("graphics/map_objects/pics/people/aqua_member_f/2.4bpp");
+const u32 gMapObjectPic_AquaMemberF_3[] = INCBIN_U32("graphics/map_objects/pics/people/aqua_member_f/3.4bpp");
+const u32 gMapObjectPic_AquaMemberF_4[] = INCBIN_U32("graphics/map_objects/pics/people/aqua_member_f/4.4bpp");
+const u32 gMapObjectPic_AquaMemberF_5[] = INCBIN_U32("graphics/map_objects/pics/people/aqua_member_f/5.4bpp");
+const u32 gMapObjectPic_AquaMemberF_6[] = INCBIN_U32("graphics/map_objects/pics/people/aqua_member_f/6.4bpp");
+const u32 gMapObjectPic_AquaMemberF_7[] = INCBIN_U32("graphics/map_objects/pics/people/aqua_member_f/7.4bpp");
+const u32 gMapObjectPic_AquaMemberF_8[] = INCBIN_U32("graphics/map_objects/pics/people/aqua_member_f/8.4bpp");
+const u32 gMapObjectPic_MagmaMemberM_0[] = INCBIN_U32("graphics/map_objects/pics/people/magma_member_m/0.4bpp");
+const u32 gMapObjectPic_MagmaMemberM_1[] = INCBIN_U32("graphics/map_objects/pics/people/magma_member_m/1.4bpp");
+const u32 gMapObjectPic_MagmaMemberM_2[] = INCBIN_U32("graphics/map_objects/pics/people/magma_member_m/2.4bpp");
+const u32 gMapObjectPic_MagmaMemberM_3[] = INCBIN_U32("graphics/map_objects/pics/people/magma_member_m/3.4bpp");
+const u32 gMapObjectPic_MagmaMemberM_4[] = INCBIN_U32("graphics/map_objects/pics/people/magma_member_m/4.4bpp");
+const u32 gMapObjectPic_MagmaMemberM_5[] = INCBIN_U32("graphics/map_objects/pics/people/magma_member_m/5.4bpp");
+const u32 gMapObjectPic_MagmaMemberM_6[] = INCBIN_U32("graphics/map_objects/pics/people/magma_member_m/6.4bpp");
+const u32 gMapObjectPic_MagmaMemberM_7[] = INCBIN_U32("graphics/map_objects/pics/people/magma_member_m/7.4bpp");
+const u32 gMapObjectPic_MagmaMemberM_8[] = INCBIN_U32("graphics/map_objects/pics/people/magma_member_m/8.4bpp");
+const u32 gMapObjectPic_MagmaMemberF_0[] = INCBIN_U32("graphics/map_objects/pics/people/magma_member_f/0.4bpp");
+const u32 gMapObjectPic_MagmaMemberF_1[] = INCBIN_U32("graphics/map_objects/pics/people/magma_member_f/1.4bpp");
+const u32 gMapObjectPic_MagmaMemberF_2[] = INCBIN_U32("graphics/map_objects/pics/people/magma_member_f/2.4bpp");
+const u32 gMapObjectPic_MagmaMemberF_3[] = INCBIN_U32("graphics/map_objects/pics/people/magma_member_f/3.4bpp");
+const u32 gMapObjectPic_MagmaMemberF_4[] = INCBIN_U32("graphics/map_objects/pics/people/magma_member_f/4.4bpp");
+const u32 gMapObjectPic_MagmaMemberF_5[] = INCBIN_U32("graphics/map_objects/pics/people/magma_member_f/5.4bpp");
+const u32 gMapObjectPic_MagmaMemberF_6[] = INCBIN_U32("graphics/map_objects/pics/people/magma_member_f/6.4bpp");
+const u32 gMapObjectPic_MagmaMemberF_7[] = INCBIN_U32("graphics/map_objects/pics/people/magma_member_f/7.4bpp");
+const u32 gMapObjectPic_MagmaMemberF_8[] = INCBIN_U32("graphics/map_objects/pics/people/magma_member_f/8.4bpp");
+const u32 gMapObjectPic_Sidney_0[] = INCBIN_U32("graphics/map_objects/pics/people/sidney/0.4bpp");
+const u32 gMapObjectPic_Sidney_1[] = INCBIN_U32("graphics/map_objects/pics/people/sidney/1.4bpp");
+const u32 gMapObjectPic_Sidney_2[] = INCBIN_U32("graphics/map_objects/pics/people/sidney/2.4bpp");
+const u32 gMapObjectPic_Phoebe_0[] = INCBIN_U32("graphics/map_objects/pics/people/phoebe/0.4bpp");
+const u32 gMapObjectPic_Phoebe_1[] = INCBIN_U32("graphics/map_objects/pics/people/phoebe/1.4bpp");
+const u32 gMapObjectPic_Phoebe_2[] = INCBIN_U32("graphics/map_objects/pics/people/phoebe/2.4bpp");
+const u32 gMapObjectPic_Glacia_0[] = INCBIN_U32("graphics/map_objects/pics/people/glacia/0.4bpp");
+const u32 gMapObjectPic_Glacia_1[] = INCBIN_U32("graphics/map_objects/pics/people/glacia/1.4bpp");
+const u32 gMapObjectPic_Glacia_2[] = INCBIN_U32("graphics/map_objects/pics/people/glacia/2.4bpp");
+const u32 gMapObjectPic_Drake_0[] = INCBIN_U32("graphics/map_objects/pics/people/drake/0.4bpp");
+const u32 gMapObjectPic_Drake_1[] = INCBIN_U32("graphics/map_objects/pics/people/drake/1.4bpp");
+const u32 gMapObjectPic_Drake_2[] = INCBIN_U32("graphics/map_objects/pics/people/drake/2.4bpp");
+const u32 gMapObjectPic_Roxanne_0[] = INCBIN_U32("graphics/map_objects/pics/people/roxanne/0.4bpp");
+const u32 gMapObjectPic_Roxanne_1[] = INCBIN_U32("graphics/map_objects/pics/people/roxanne/1.4bpp");
+const u32 gMapObjectPic_Roxanne_2[] = INCBIN_U32("graphics/map_objects/pics/people/roxanne/2.4bpp");
+const u32 gMapObjectPic_Brawly_0[] = INCBIN_U32("graphics/map_objects/pics/people/brawly/0.4bpp");
+const u32 gMapObjectPic_Brawly_1[] = INCBIN_U32("graphics/map_objects/pics/people/brawly/1.4bpp");
+const u32 gMapObjectPic_Brawly_2[] = INCBIN_U32("graphics/map_objects/pics/people/brawly/2.4bpp");
+const u32 gMapObjectPic_Wattson_0[] = INCBIN_U32("graphics/map_objects/pics/people/wattson/0.4bpp");
+const u32 gMapObjectPic_Wattson_1[] = INCBIN_U32("graphics/map_objects/pics/people/wattson/1.4bpp");
+const u32 gMapObjectPic_Wattson_2[] = INCBIN_U32("graphics/map_objects/pics/people/wattson/2.4bpp");
+const u32 gMapObjectPic_Flannery_0[] = INCBIN_U32("graphics/map_objects/pics/people/flannery/0.4bpp");
+const u32 gMapObjectPic_Flannery_1[] = INCBIN_U32("graphics/map_objects/pics/people/flannery/1.4bpp");
+const u32 gMapObjectPic_Flannery_2[] = INCBIN_U32("graphics/map_objects/pics/people/flannery/2.4bpp");
+const u32 gMapObjectPic_Norman_0[] = INCBIN_U32("graphics/map_objects/pics/people/norman/0.4bpp");
+const u32 gMapObjectPic_Norman_1[] = INCBIN_U32("graphics/map_objects/pics/people/norman/1.4bpp");
+const u32 gMapObjectPic_Norman_2[] = INCBIN_U32("graphics/map_objects/pics/people/norman/2.4bpp");
+const u32 gMapObjectPic_Norman_3[] = INCBIN_U32("graphics/map_objects/pics/people/norman/3.4bpp");
+const u32 gMapObjectPic_Norman_4[] = INCBIN_U32("graphics/map_objects/pics/people/norman/4.4bpp");
+const u32 gMapObjectPic_Norman_5[] = INCBIN_U32("graphics/map_objects/pics/people/norman/5.4bpp");
+const u32 gMapObjectPic_Norman_6[] = INCBIN_U32("graphics/map_objects/pics/people/norman/6.4bpp");
+const u32 gMapObjectPic_Norman_7[] = INCBIN_U32("graphics/map_objects/pics/people/norman/7.4bpp");
+const u32 gMapObjectPic_Norman_8[] = INCBIN_U32("graphics/map_objects/pics/people/norman/8.4bpp");
+const u32 gMapObjectPic_Winona_0[] = INCBIN_U32("graphics/map_objects/pics/people/winona/0.4bpp");
+const u32 gMapObjectPic_Winona_1[] = INCBIN_U32("graphics/map_objects/pics/people/winona/1.4bpp");
+const u32 gMapObjectPic_Winona_2[] = INCBIN_U32("graphics/map_objects/pics/people/winona/2.4bpp");
+const u32 gMapObjectPic_Liza_0[] = INCBIN_U32("graphics/map_objects/pics/people/liza/0.4bpp");
+const u32 gMapObjectPic_Liza_1[] = INCBIN_U32("graphics/map_objects/pics/people/liza/1.4bpp");
+const u32 gMapObjectPic_Liza_2[] = INCBIN_U32("graphics/map_objects/pics/people/liza/2.4bpp");
+const u32 gMapObjectPic_Tate_0[] = INCBIN_U32("graphics/map_objects/pics/people/tate/0.4bpp");
+const u32 gMapObjectPic_Tate_1[] = INCBIN_U32("graphics/map_objects/pics/people/tate/1.4bpp");
+const u32 gMapObjectPic_Tate_2[] = INCBIN_U32("graphics/map_objects/pics/people/tate/2.4bpp");
+const u32 gMapObjectPic_Wallace_0[] = INCBIN_U32("graphics/map_objects/pics/people/wallace/0.4bpp");
+const u32 gMapObjectPic_Wallace_1[] = INCBIN_U32("graphics/map_objects/pics/people/wallace/1.4bpp");
+const u32 gMapObjectPic_Wallace_2[] = INCBIN_U32("graphics/map_objects/pics/people/wallace/2.4bpp");
+const u32 gMapObjectPic_Wallace_3[] = INCBIN_U32("graphics/map_objects/pics/people/wallace/3.4bpp");
+const u32 gMapObjectPic_Wallace_4[] = INCBIN_U32("graphics/map_objects/pics/people/wallace/4.4bpp");
+const u32 gMapObjectPic_Wallace_5[] = INCBIN_U32("graphics/map_objects/pics/people/wallace/5.4bpp");
+const u32 gMapObjectPic_Wallace_6[] = INCBIN_U32("graphics/map_objects/pics/people/wallace/6.4bpp");
+const u32 gMapObjectPic_Wallace_7[] = INCBIN_U32("graphics/map_objects/pics/people/wallace/7.4bpp");
+const u32 gMapObjectPic_Wallace_8[] = INCBIN_U32("graphics/map_objects/pics/people/wallace/8.4bpp");
+const u32 gMapObjectPic_Steven_0[] = INCBIN_U32("graphics/map_objects/pics/people/steven/0.4bpp");
+const u32 gMapObjectPic_Steven_1[] = INCBIN_U32("graphics/map_objects/pics/people/steven/1.4bpp");
+const u32 gMapObjectPic_Steven_2[] = INCBIN_U32("graphics/map_objects/pics/people/steven/2.4bpp");
+const u32 gMapObjectPic_Steven_3[] = INCBIN_U32("graphics/map_objects/pics/people/steven/3.4bpp");
+const u32 gMapObjectPic_Steven_4[] = INCBIN_U32("graphics/map_objects/pics/people/steven/4.4bpp");
+const u32 gMapObjectPic_Steven_5[] = INCBIN_U32("graphics/map_objects/pics/people/steven/5.4bpp");
+const u32 gMapObjectPic_Steven_6[] = INCBIN_U32("graphics/map_objects/pics/people/steven/6.4bpp");
+const u32 gMapObjectPic_Steven_7[] = INCBIN_U32("graphics/map_objects/pics/people/steven/7.4bpp");
+const u32 gMapObjectPic_Steven_8[] = INCBIN_U32("graphics/map_objects/pics/people/steven/8.4bpp");
+const u32 gMapObjectPic_Wally_0[] = INCBIN_U32("graphics/map_objects/pics/people/wally/0.4bpp");
+const u32 gMapObjectPic_Wally_1[] = INCBIN_U32("graphics/map_objects/pics/people/wally/1.4bpp");
+const u32 gMapObjectPic_Wally_2[] = INCBIN_U32("graphics/map_objects/pics/people/wally/2.4bpp");
+const u32 gMapObjectPic_Wally_3[] = INCBIN_U32("graphics/map_objects/pics/people/wally/3.4bpp");
+const u32 gMapObjectPic_Wally_4[] = INCBIN_U32("graphics/map_objects/pics/people/wally/4.4bpp");
+const u32 gMapObjectPic_Wally_5[] = INCBIN_U32("graphics/map_objects/pics/people/wally/5.4bpp");
+const u32 gMapObjectPic_Wally_6[] = INCBIN_U32("graphics/map_objects/pics/people/wally/6.4bpp");
+const u32 gMapObjectPic_Wally_7[] = INCBIN_U32("graphics/map_objects/pics/people/wally/7.4bpp");
+const u32 gMapObjectPic_Wally_8[] = INCBIN_U32("graphics/map_objects/pics/people/wally/8.4bpp");
+const u32 gMapObjectPic_LittleBoy3_0[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_3/0.4bpp");
+const u32 gMapObjectPic_LittleBoy3_1[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_3/1.4bpp");
+const u32 gMapObjectPic_LittleBoy3_2[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_3/2.4bpp");
+const u32 gMapObjectPic_LittleBoy3_3[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_3/3.4bpp");
+const u32 gMapObjectPic_LittleBoy3_4[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_3/4.4bpp");
+const u32 gMapObjectPic_LittleBoy3_5[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_3/5.4bpp");
+const u32 gMapObjectPic_LittleBoy3_6[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_3/6.4bpp");
+const u32 gMapObjectPic_LittleBoy3_7[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_3/7.4bpp");
+const u32 gMapObjectPic_LittleBoy3_8[] = INCBIN_U32("graphics/map_objects/pics/people/little_boy_3/8.4bpp");
+const u32 gMapObjectPic_HotSpringsOldWoman_0[] = INCBIN_U32("graphics/map_objects/pics/people/hot_springs_old_woman/0.4bpp");
+const u32 gMapObjectPic_HotSpringsOldWoman_1[] = INCBIN_U32("graphics/map_objects/pics/people/hot_springs_old_woman/1.4bpp");
+const u32 gMapObjectPic_HotSpringsOldWoman_2[] = INCBIN_U32("graphics/map_objects/pics/people/hot_springs_old_woman/2.4bpp");
+const u32 gMapObjectPic_HotSpringsOldWoman_3[] = INCBIN_U32("graphics/map_objects/pics/people/hot_springs_old_woman/3.4bpp");
+const u32 gMapObjectPic_HotSpringsOldWoman_4[] = INCBIN_U32("graphics/map_objects/pics/people/hot_springs_old_woman/4.4bpp");
+const u32 gMapObjectPic_HotSpringsOldWoman_5[] = INCBIN_U32("graphics/map_objects/pics/people/hot_springs_old_woman/5.4bpp");
+const u32 gMapObjectPic_HotSpringsOldWoman_6[] = INCBIN_U32("graphics/map_objects/pics/people/hot_springs_old_woman/6.4bpp");
+const u32 gMapObjectPic_HotSpringsOldWoman_7[] = INCBIN_U32("graphics/map_objects/pics/people/hot_springs_old_woman/7.4bpp");
+const u32 gMapObjectPic_HotSpringsOldWoman_8[] = INCBIN_U32("graphics/map_objects/pics/people/hot_springs_old_woman/8.4bpp");
+const u32 gMapObjectPic_LatiasLatios_0[] = INCBIN_U32("graphics/map_objects/pics/pokemon/latias_latios/0.4bpp");
+const u32 gMapObjectPic_LatiasLatios_1[] = INCBIN_U32("graphics/map_objects/pics/pokemon/latias_latios/1.4bpp");
+const u32 gMapObjectPic_LatiasLatios_2[] = INCBIN_U32("graphics/map_objects/pics/pokemon/latias_latios/2.4bpp");
+const u32 gMapObjectPic_Boy5_0[] = INCBIN_U32("graphics/map_objects/pics/people/boy_5/0.4bpp");
+const u32 gMapObjectPic_Boy5_1[] = INCBIN_U32("graphics/map_objects/pics/people/boy_5/1.4bpp");
+const u32 gMapObjectPic_Boy5_2[] = INCBIN_U32("graphics/map_objects/pics/people/boy_5/2.4bpp");
+const u32 gMapObjectPic_ContestJudge_0[] = INCBIN_U32("graphics/map_objects/pics/people/contest_judge/0.4bpp");
+const u32 gMapObjectPic_ContestJudge_1[] = INCBIN_U32("graphics/map_objects/pics/people/contest_judge/1.4bpp");
+const u32 gMapObjectPic_ContestJudge_2[] = INCBIN_U32("graphics/map_objects/pics/people/contest_judge/2.4bpp");
+const u32 gMapObjectPic_ContestJudge_3[] = INCBIN_U32("graphics/map_objects/pics/people/contest_judge/3.4bpp");
+const u32 gMapObjectPic_ContestJudge_4[] = INCBIN_U32("graphics/map_objects/pics/people/contest_judge/4.4bpp");
+const u32 gMapObjectPic_ContestJudge_5[] = INCBIN_U32("graphics/map_objects/pics/people/contest_judge/5.4bpp");
+const u32 gMapObjectPic_ContestJudge_6[] = INCBIN_U32("graphics/map_objects/pics/people/contest_judge/6.4bpp");
+const u32 gMapObjectPic_ContestJudge_7[] = INCBIN_U32("graphics/map_objects/pics/people/contest_judge/7.4bpp");
+const u32 gMapObjectPic_ContestJudge_8[] = INCBIN_U32("graphics/map_objects/pics/people/contest_judge/8.4bpp");
+const u32 gMapObjectPic_Archie_0[] = INCBIN_U32("graphics/map_objects/pics/people/archie/0.4bpp");
+const u32 gMapObjectPic_Archie_1[] = INCBIN_U32("graphics/map_objects/pics/people/archie/1.4bpp");
+const u32 gMapObjectPic_Archie_2[] = INCBIN_U32("graphics/map_objects/pics/people/archie/2.4bpp");
+const u32 gMapObjectPic_Archie_3[] = INCBIN_U32("graphics/map_objects/pics/people/archie/3.4bpp");
+const u32 gMapObjectPic_Archie_4[] = INCBIN_U32("graphics/map_objects/pics/people/archie/4.4bpp");
+const u32 gMapObjectPic_Archie_5[] = INCBIN_U32("graphics/map_objects/pics/people/archie/5.4bpp");
+const u32 gMapObjectPic_Archie_6[] = INCBIN_U32("graphics/map_objects/pics/people/archie/6.4bpp");
+const u32 gMapObjectPic_Archie_7[] = INCBIN_U32("graphics/map_objects/pics/people/archie/7.4bpp");
+const u32 gMapObjectPic_Archie_8[] = INCBIN_U32("graphics/map_objects/pics/people/archie/8.4bpp");
+const u32 gMapObjectPic_Maxie_0[] = INCBIN_U32("graphics/map_objects/pics/people/maxie/0.4bpp");
+const u32 gMapObjectPic_Maxie_1[] = INCBIN_U32("graphics/map_objects/pics/people/maxie/1.4bpp");
+const u32 gMapObjectPic_Maxie_2[] = INCBIN_U32("graphics/map_objects/pics/people/maxie/2.4bpp");
+const u32 gMapObjectPic_Maxie_3[] = INCBIN_U32("graphics/map_objects/pics/people/maxie/3.4bpp");
+const u32 gMapObjectPic_Maxie_4[] = INCBIN_U32("graphics/map_objects/pics/people/maxie/4.4bpp");
+const u32 gMapObjectPic_Maxie_5[] = INCBIN_U32("graphics/map_objects/pics/people/maxie/5.4bpp");
+const u32 gMapObjectPic_Maxie_6[] = INCBIN_U32("graphics/map_objects/pics/people/maxie/6.4bpp");
+const u32 gMapObjectPic_Maxie_7[] = INCBIN_U32("graphics/map_objects/pics/people/maxie/7.4bpp");
+const u32 gMapObjectPic_Maxie_8[] = INCBIN_U32("graphics/map_objects/pics/people/maxie/8.4bpp");
+const u32 gMapObjectPic_Kyogre_0[] = INCBIN_U32("graphics/map_objects/pics/pokemon/kyogre/0.4bpp");
+const u32 gMapObjectPic_Kyogre_1[] = INCBIN_U32("graphics/map_objects/pics/pokemon/kyogre/1.4bpp");
+const u32 gMapObjectPic_Groudon_0[] = INCBIN_U32("graphics/map_objects/pics/pokemon/groudon/0.4bpp");
+const u32 gMapObjectPic_Groudon_1[] = INCBIN_U32("graphics/map_objects/pics/pokemon/groudon/1.4bpp");
+const u32 gMapObjectPic_Regi[] = INCBIN_U32("graphics/map_objects/pics/pokemon/regi.4bpp");
+const u32 gMapObjectPic_Skitty_0[] = INCBIN_U32("graphics/map_objects/pics/pokemon/skitty/0.4bpp");
+const u32 gMapObjectPic_Skitty_1[] = INCBIN_U32("graphics/map_objects/pics/pokemon/skitty/1.4bpp");
+const u32 gMapObjectPic_Skitty_2[] = INCBIN_U32("graphics/map_objects/pics/pokemon/skitty/2.4bpp");
+const u32 gMapObjectPic_Kecleon_0[] = INCBIN_U32("graphics/map_objects/pics/pokemon/kecleon/0.4bpp");
+const u32 gMapObjectPic_Kecleon_1[] = INCBIN_U32("graphics/map_objects/pics/pokemon/kecleon/1.4bpp");
+const u32 gMapObjectPic_Kecleon_2[] = INCBIN_U32("graphics/map_objects/pics/pokemon/kecleon/2.4bpp");
+const u32 gMapObjectPic_Rayquaza_0[] = INCBIN_U32("graphics/map_objects/pics/pokemon/rayquaza/0.4bpp");
+const u32 gMapObjectPic_Rayquaza_1[] = INCBIN_U32("graphics/map_objects/pics/pokemon/rayquaza/1.4bpp");
+const u32 gMapObjectPic_Zigzagoon_0[] = INCBIN_U32("graphics/map_objects/pics/pokemon/zigzagoon/0.4bpp");
+const u32 gMapObjectPic_Zigzagoon_1[] = INCBIN_U32("graphics/map_objects/pics/pokemon/zigzagoon/1.4bpp");
+const u32 gMapObjectPic_Zigzagoon_2[] = INCBIN_U32("graphics/map_objects/pics/pokemon/zigzagoon/2.4bpp");
+const u32 gMapObjectPic_Pikachu_0[] = INCBIN_U32("graphics/map_objects/pics/pokemon/pikachu/0.4bpp");
+const u32 gMapObjectPic_Pikachu_1[] = INCBIN_U32("graphics/map_objects/pics/pokemon/pikachu/1.4bpp");
+const u32 gMapObjectPic_Pikachu_2[] = INCBIN_U32("graphics/map_objects/pics/pokemon/pikachu/2.4bpp");
+const u32 gMapObjectPic_Azumarill_0[] = INCBIN_U32("graphics/map_objects/pics/pokemon/azumarill/0.4bpp");
+const u32 gMapObjectPic_Azumarill_1[] = INCBIN_U32("graphics/map_objects/pics/pokemon/azumarill/1.4bpp");
+const u32 gMapObjectPic_Azumarill_2[] = INCBIN_U32("graphics/map_objects/pics/pokemon/azumarill/2.4bpp");
+const u32 gMapObjectPic_Wingull_0[] = INCBIN_U32("graphics/map_objects/pics/pokemon/wingull/0.4bpp");
+const u32 gMapObjectPic_Wingull_3[] = INCBIN_U32("graphics/map_objects/pics/pokemon/wingull/3.4bpp");
+const u32 gMapObjectPic_Wingull_1[] = INCBIN_U32("graphics/map_objects/pics/pokemon/wingull/1.4bpp");
+const u32 gMapObjectPic_Wingull_4[] = INCBIN_U32("graphics/map_objects/pics/pokemon/wingull/4.4bpp");
+const u32 gMapObjectPic_Wingull_2[] = INCBIN_U32("graphics/map_objects/pics/pokemon/wingull/2.4bpp");
+const u32 gMapObjectPic_Wingull_5[] = INCBIN_U32("graphics/map_objects/pics/pokemon/wingull/5.4bpp");
+const u32 gMapObjectPic_TuberMSwimming_0[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_m_swimming/0.4bpp");
+const u32 gMapObjectPic_TuberMSwimming_1[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_m_swimming/1.4bpp");
+const u32 gMapObjectPic_TuberMSwimming_2[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_m_swimming/2.4bpp");
+const u32 gMapObjectPic_TuberMSwimming_3[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_m_swimming/3.4bpp");
+const u32 gMapObjectPic_TuberMSwimming_4[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_m_swimming/4.4bpp");
+const u32 gMapObjectPic_TuberMSwimming_5[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_m_swimming/5.4bpp");
+const u32 gMapObjectPic_TuberMSwimming_6[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_m_swimming/6.4bpp");
+const u32 gMapObjectPic_TuberMSwimming_7[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_m_swimming/7.4bpp");
+const u32 gMapObjectPic_TuberMSwimming_8[] = INCBIN_U32("graphics/map_objects/pics/people/tuber_m_swimming/8.4bpp");
+const u32 gMapObjectPic_Azurill_0[] = INCBIN_U32("graphics/map_objects/pics/pokemon/azurill/0.4bpp");
+const u32 gMapObjectPic_Azurill_1[] = INCBIN_U32("graphics/map_objects/pics/pokemon/azurill/1.4bpp");
+const u32 gMapObjectPic_Azurill_2[] = INCBIN_U32("graphics/map_objects/pics/pokemon/azurill/2.4bpp");
+const u32 gMapObjectPic_Mom_0[] = INCBIN_U32("graphics/map_objects/pics/people/mom/0.4bpp");
+const u32 gMapObjectPic_Mom_1[] = INCBIN_U32("graphics/map_objects/pics/people/mom/1.4bpp");
+const u32 gMapObjectPic_Mom_2[] = INCBIN_U32("graphics/map_objects/pics/people/mom/2.4bpp");
+const u32 gMapObjectPic_Mom_3[] = INCBIN_U32("graphics/map_objects/pics/people/mom/3.4bpp");
+const u32 gMapObjectPic_Mom_4[] = INCBIN_U32("graphics/map_objects/pics/people/mom/4.4bpp");
+const u32 gMapObjectPic_Mom_5[] = INCBIN_U32("graphics/map_objects/pics/people/mom/5.4bpp");
+const u32 gMapObjectPic_Mom_6[] = INCBIN_U32("graphics/map_objects/pics/people/mom/6.4bpp");
+const u32 gMapObjectPic_Mom_7[] = INCBIN_U32("graphics/map_objects/pics/people/mom/7.4bpp");
+const u32 gMapObjectPic_Mom_8[] = INCBIN_U32("graphics/map_objects/pics/people/mom/8.4bpp");
+const u16 gMapObjectPalette22[] = INCBIN_U16("graphics/map_objects/palettes/22.gbapal");
+const u16 gMapObjectPalette23[] = INCBIN_U16("graphics/map_objects/palettes/23.gbapal");
+const u16 gMapObjectPalette24[] = INCBIN_U16("graphics/map_objects/palettes/24.gbapal");
+const u16 gMapObjectPalette25[] = INCBIN_U16("graphics/map_objects/palettes/25.gbapal");
+const u32 gMapObjectPic_UnusedNatuDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/unused_natu_doll.4bpp");
+const u32 gMapObjectPic_UnusedMagnemiteDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/unused_magnemite_doll.4bpp");
+const u32 gMapObjectPic_UnusedSquirtleDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/unused_squirtle_doll.4bpp");
+const u32 gMapObjectPic_UnusedWooperDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/unused_wooper_doll.4bpp");
+const u32 gMapObjectPic_UnusedPikachuDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/unused_pikachu_doll.4bpp");
+const u32 gMapObjectPic_UnusedPorygon2Doll[] = INCBIN_U32("graphics/map_objects/pics/dolls/unused_porygon2_doll.4bpp");
+const u32 gMapObjectPic_PichuDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/pichu_doll.4bpp");
+const u32 gMapObjectPic_PikachuDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/pikachu_doll.4bpp");
+const u32 gMapObjectPic_MarillDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/marill_doll.4bpp");
+const u32 gMapObjectPic_TogepiDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/togepi_doll.4bpp");
+const u32 gMapObjectPic_CyndaquilDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/cyndaquil_doll.4bpp");
+const u32 gMapObjectPic_ChikoritaDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/chikorita_doll.4bpp");
+const u32 gMapObjectPic_TotodileDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/totodile_doll.4bpp");
+const u32 gMapObjectPic_JigglypuffDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/jigglypuff_doll.4bpp");
+const u32 gMapObjectPic_MeowthDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/meowth_doll.4bpp");
+const u32 gMapObjectPic_ClefairyDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/clefairy_doll.4bpp");
+const u32 gMapObjectPic_DittoDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/ditto_doll.4bpp");
+const u32 gMapObjectPic_SmoochumDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/smoochum_doll.4bpp");
+const u32 gMapObjectPic_TreeckoDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/treecko_doll.4bpp");
+const u32 gMapObjectPic_TorchicDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/torchic_doll.4bpp");
+const u32 gMapObjectPic_MudkipDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/mudkip_doll.4bpp");
+const u32 gMapObjectPic_DuskullDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/duskull_doll.4bpp");
+const u32 gMapObjectPic_WynautDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/wynaut_doll.4bpp");
+const u32 gMapObjectPic_BaltoyDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/baltoy_doll.4bpp");
+const u32 gMapObjectPic_KecleonDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/kecleon_doll.4bpp");
+const u32 gMapObjectPic_AzurillDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/azurill_doll.4bpp");
+const u32 gMapObjectPic_SkittyDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/skitty_doll.4bpp");
+const u32 gMapObjectPic_SwabluDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/swablu_doll.4bpp");
+const u32 gMapObjectPic_GulpinDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/gulpin_doll.4bpp");
+const u32 gMapObjectPic_LotadDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/lotad_doll.4bpp");
+const u32 gMapObjectPic_SeedotDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/seedot_doll.4bpp");
+const u32 gMapObjectPic_PikaCushion[] = INCBIN_U32("graphics/map_objects/pics/cushions/pika_cushion.4bpp");
+const u32 gMapObjectPic_RoundCushion[] = INCBIN_U32("graphics/map_objects/pics/cushions/round_cushion.4bpp");
+const u32 gMapObjectPic_KissCushion[] = INCBIN_U32("graphics/map_objects/pics/cushions/kiss_cushion.4bpp");
+const u32 gMapObjectPic_ZigzagCushion[] = INCBIN_U32("graphics/map_objects/pics/cushions/zigzag_cushion.4bpp");
+const u32 gMapObjectPic_SpinCushion[] = INCBIN_U32("graphics/map_objects/pics/cushions/spin_cushion.4bpp");
+const u32 gMapObjectPic_DiamondCushion[] = INCBIN_U32("graphics/map_objects/pics/cushions/diamond_cushion.4bpp");
+const u32 gMapObjectPic_BallCushion[] = INCBIN_U32("graphics/map_objects/pics/cushions/ball_cushion.4bpp");
+const u32 gMapObjectPic_GrassCushion[] = INCBIN_U32("graphics/map_objects/pics/cushions/grass_cushion.4bpp");
+const u32 gMapObjectPic_FireCushion[] = INCBIN_U32("graphics/map_objects/pics/cushions/fire_cushion.4bpp");
+const u32 gMapObjectPic_WaterCushion[] = INCBIN_U32("graphics/map_objects/pics/cushions/water_cushion.4bpp");
+const u32 gMapObjectPic_BigSnorlaxDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/big_snorlax_doll.4bpp");
+const u32 gMapObjectPic_BigRhydonDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/big_rhydon_doll.4bpp");
+const u32 gMapObjectPic_BigLaprasDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/big_lapras_doll.4bpp");
+const u32 gMapObjectPic_BigVenusaurDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/big_venusaur_doll.4bpp");
+const u32 gMapObjectPic_BigCharizardDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/big_charizard_doll.4bpp");
+const u32 gMapObjectPic_BigBlastoiseDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/big_blastoise_doll.4bpp");
+const u32 gMapObjectPic_BigWailmerDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/big_wailmer_doll.4bpp");
+const u32 gMapObjectPic_BigRegirockDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/big_regirock_doll.4bpp");
+const u32 gMapObjectPic_BigRegiceDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/big_regice_doll.4bpp");
+const u32 gMapObjectPic_BigRegisteelDoll[] = INCBIN_U32("graphics/map_objects/pics/dolls/big_registeel_doll.4bpp");
+const u32 gMapObjectPic_CuttableTree_0[] = INCBIN_U32("graphics/map_objects/pics/misc/cuttable_tree/0.4bpp");
+const u32 gMapObjectPic_CuttableTree_1[] = INCBIN_U32("graphics/map_objects/pics/misc/cuttable_tree/1.4bpp");
+const u32 gMapObjectPic_CuttableTree_2[] = INCBIN_U32("graphics/map_objects/pics/misc/cuttable_tree/2.4bpp");
+const u32 gMapObjectPic_CuttableTree_3[] = INCBIN_U32("graphics/map_objects/pics/misc/cuttable_tree/3.4bpp");
+const u32 gMapObjectPic_BreakableRock_0[] = INCBIN_U32("graphics/map_objects/pics/misc/breakable_rock/0.4bpp");
+const u32 gMapObjectPic_BreakableRock_1[] = INCBIN_U32("graphics/map_objects/pics/misc/breakable_rock/1.4bpp");
+const u32 gMapObjectPic_BreakableRock_2[] = INCBIN_U32("graphics/map_objects/pics/misc/breakable_rock/2.4bpp");
+const u32 gMapObjectPic_BreakableRock_3[] = INCBIN_U32("graphics/map_objects/pics/misc/breakable_rock/3.4bpp");
+const u32 gMapObjectPic_PushableBoulder[] = INCBIN_U32("graphics/map_objects/pics/misc/pushable_boulder.4bpp");
+const u32 gMapObjectPic_MrBrineysBoat_0[] = INCBIN_U32("graphics/map_objects/pics/misc/mr_brineys_boat/0.4bpp");
+const u32 gMapObjectPic_MrBrineysBoat_1[] = INCBIN_U32("graphics/map_objects/pics/misc/mr_brineys_boat/1.4bpp");
+const u32 gMapObjectPic_MrBrineysBoat_2[] = INCBIN_U32("graphics/map_objects/pics/misc/mr_brineys_boat/2.4bpp");
+const u32 gMapObjectPic_Fossil[] = INCBIN_U32("graphics/map_objects/pics/misc/fossil.4bpp");
+const u32 gMapObjectPic_SubmarineShadow[] = INCBIN_U32("graphics/map_objects/pics/misc/submarine_shadow.4bpp");
+const u16 gMapObjectPalette26[] = INCBIN_U16("graphics/map_objects/palettes/26.gbapal");
+const u32 gMapObjectPic_Truck[] = INCBIN_U32("graphics/map_objects/pics/misc/truck.4bpp");
+const u16 gMapObjectPalette14[] = INCBIN_U16("graphics/map_objects/palettes/14.gbapal");
+const u32 gMapObjectPic_MachokeCarryingBox_0[] = INCBIN_U32("graphics/map_objects/pics/pokemon/machoke_carrying_box/0.4bpp");
+const u32 gMapObjectPic_MachokeCarryingBox_1[] = INCBIN_U32("graphics/map_objects/pics/pokemon/machoke_carrying_box/1.4bpp");
+const u32 gMapObjectPic_MachokeCarryingBox_2[] = INCBIN_U32("graphics/map_objects/pics/pokemon/machoke_carrying_box/2.4bpp");
+const u32 gMapObjectPic_MachokeFacingAway_0[] = INCBIN_U32("graphics/map_objects/pics/pokemon/machoke_facing_away/0.4bpp");
+const u32 gMapObjectPic_MachokeFacingAway_1[] = INCBIN_U32("graphics/map_objects/pics/pokemon/machoke_facing_away/1.4bpp");
+const u16 gMapObjectPalette15[] = INCBIN_U16("graphics/map_objects/palettes/15.gbapal");
+const u32 gMapObjectPic_BirchsBag[] = INCBIN_U32("graphics/map_objects/pics/misc/birchs_bag.4bpp");
+const u32 gMapObjectPic_Poochyena_0[] = INCBIN_U32("graphics/map_objects/pics/pokemon/poochyena/0.4bpp");
+const u32 gMapObjectPic_Poochyena_1[] = INCBIN_U32("graphics/map_objects/pics/pokemon/poochyena/1.4bpp");
+const u32 gMapObjectPic_Poochyena_2[] = INCBIN_U32("graphics/map_objects/pics/pokemon/poochyena/2.4bpp");
+const u32 gMapObjectPic_Poochyena_3[] = INCBIN_U32("graphics/map_objects/pics/pokemon/poochyena/3.4bpp");
+const u32 gMapObjectPic_Poochyena_4[] = INCBIN_U32("graphics/map_objects/pics/pokemon/poochyena/4.4bpp");
+const u32 gMapObjectPic_Poochyena_5[] = INCBIN_U32("graphics/map_objects/pics/pokemon/poochyena/5.4bpp");
+const u32 gMapObjectPic_Poochyena_6[] = INCBIN_U32("graphics/map_objects/pics/pokemon/poochyena/6.4bpp");
+const u32 gMapObjectPic_Poochyena_7[] = INCBIN_U32("graphics/map_objects/pics/pokemon/poochyena/7.4bpp");
+const u32 gMapObjectPic_Poochyena_8[] = INCBIN_U32("graphics/map_objects/pics/pokemon/poochyena/8.4bpp");
+const u16 gMapObjectPalette16[] = INCBIN_U16("graphics/map_objects/palettes/16.gbapal");
+const u32 gMapObjectPic_CableCar[] = INCBIN_U32("graphics/map_objects/pics/misc/cable_car.4bpp");
+const u16 gMapObjectPalette20[] = INCBIN_U16("graphics/map_objects/palettes/20.gbapal");
+const u32 gMapObjectPic_SSTidal[] = INCBIN_U32("graphics/map_objects/pics/misc/ss_tidal.4bpp");
+const u16 gMapObjectPalette21[] = INCBIN_U16("graphics/map_objects/palettes/21.gbapal");
+const u32 gFieldEffectPic_BerryTreeGrowthSparkle_0[] = INCBIN_U32("graphics/field_effect_objects/pics/berry_tree_growth_sparkle/0.4bpp");
+const u32 gFieldEffectPic_BerryTreeGrowthSparkle_1[] = INCBIN_U32("graphics/field_effect_objects/pics/berry_tree_growth_sparkle/1.4bpp");
+const u32 gFieldEffectPic_BerryTreeGrowthSparkle_2[] = INCBIN_U32("graphics/field_effect_objects/pics/berry_tree_growth_sparkle/2.4bpp");
+const u32 gFieldEffectPic_BerryTreeGrowthSparkle_3[] = INCBIN_U32("graphics/field_effect_objects/pics/berry_tree_growth_sparkle/3.4bpp");
+const u32 gFieldEffectPic_BerryTreeGrowthSparkle_4[] = INCBIN_U32("graphics/field_effect_objects/pics/berry_tree_growth_sparkle/4.4bpp");
+const u32 gFieldEffectPic_BerryTreeGrowthSparkle_5[] = INCBIN_U32("graphics/field_effect_objects/pics/berry_tree_growth_sparkle/5.4bpp");
+const u32 gMapObjectPic_BerryTreeDirtPile[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/dirt_pile.4bpp");
+const u32 gMapObjectPic_BerryTreeSprout_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/sprout/0.4bpp");
+const u32 gMapObjectPic_BerryTreeSprout_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/sprout/1.4bpp");
+const u32 gMapObjectPic_PechaBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/pecha/0.4bpp");
+const u32 gMapObjectPic_PechaBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/pecha/1.4bpp");
+const u32 gMapObjectPic_PechaBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/pecha/2.4bpp");
+const u32 gMapObjectPic_PechaBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/pecha/3.4bpp");
+const u32 gMapObjectPic_PechaBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/pecha/4.4bpp");
+const u32 gMapObjectPic_PechaBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/pecha/5.4bpp");
+const u32 gMapObjectPic_KelpsyBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/kelpsy/0.4bpp");
+const u32 gMapObjectPic_KelpsyBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/kelpsy/1.4bpp");
+const u32 gMapObjectPic_KelpsyBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/kelpsy/2.4bpp");
+const u32 gMapObjectPic_KelpsyBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/kelpsy/3.4bpp");
+const u32 gMapObjectPic_KelpsyBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/kelpsy/4.4bpp");
+const u32 gMapObjectPic_KelpsyBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/kelpsy/5.4bpp");
+const u32 gMapObjectPic_WepearBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/wepear/0.4bpp");
+const u32 gMapObjectPic_WepearBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/wepear/1.4bpp");
+const u32 gMapObjectPic_WepearBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/wepear/2.4bpp");
+const u32 gMapObjectPic_WepearBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/wepear/3.4bpp");
+const u32 gMapObjectPic_WepearBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/wepear/4.4bpp");
+const u32 gMapObjectPic_WepearBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/wepear/5.4bpp");
+const u32 gMapObjectPic_IapapaBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/iapapa/0.4bpp");
+const u32 gMapObjectPic_IapapaBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/iapapa/1.4bpp");
+const u32 gMapObjectPic_IapapaBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/iapapa/2.4bpp");
+const u32 gMapObjectPic_IapapaBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/iapapa/3.4bpp");
+const u32 gMapObjectPic_IapapaBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/iapapa/4.4bpp");
+const u32 gMapObjectPic_IapapaBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/iapapa/5.4bpp");
+const u32 gMapObjectPic_CheriBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/cheri/0.4bpp");
+const u32 gMapObjectPic_CheriBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/cheri/1.4bpp");
+const u32 gMapObjectPic_CheriBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/cheri/2.4bpp");
+const u32 gMapObjectPic_CheriBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/cheri/3.4bpp");
+const u32 gMapObjectPic_CheriBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/cheri/4.4bpp");
+const u32 gMapObjectPic_CheriBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/cheri/5.4bpp");
+const u32 gMapObjectPic_FigyBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/figy/0.4bpp");
+const u32 gMapObjectPic_FigyBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/figy/1.4bpp");
+const u32 gMapObjectPic_FigyBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/figy/2.4bpp");
+const u32 gMapObjectPic_FigyBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/figy/3.4bpp");
+const u32 gMapObjectPic_FigyBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/figy/4.4bpp");
+const u32 gMapObjectPic_FigyBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/figy/5.4bpp");
+const u32 gMapObjectPic_MagoBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/mago/0.4bpp");
+const u32 gMapObjectPic_MagoBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/mago/1.4bpp");
+const u32 gMapObjectPic_MagoBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/mago/2.4bpp");
+const u32 gMapObjectPic_MagoBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/mago/3.4bpp");
+const u32 gMapObjectPic_MagoBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/mago/4.4bpp");
+const u32 gMapObjectPic_MagoBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/mago/5.4bpp");
+const u32 gMapObjectPic_LumBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/lum/0.4bpp");
+const u32 gMapObjectPic_LumBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/lum/1.4bpp");
+const u32 gMapObjectPic_LumBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/lum/2.4bpp");
+const u32 gMapObjectPic_LumBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/lum/3.4bpp");
+const u32 gMapObjectPic_LumBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/lum/4.4bpp");
+const u32 gMapObjectPic_LumBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/lum/5.4bpp");
+const u32 gMapObjectPic_RazzBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/razz/0.4bpp");
+const u32 gMapObjectPic_RazzBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/razz/1.4bpp");
+const u32 gMapObjectPic_RazzBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/razz/2.4bpp");
+const u32 gMapObjectPic_RazzBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/razz/3.4bpp");
+const u32 gMapObjectPic_RazzBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/razz/4.4bpp");
+const u32 gMapObjectPic_RazzBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/razz/5.4bpp");
+const u32 gMapObjectPic_GrepaBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/grepa/0.4bpp");
+const u32 gMapObjectPic_GrepaBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/grepa/1.4bpp");
+const u32 gMapObjectPic_GrepaBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/grepa/2.4bpp");
+const u32 gMapObjectPic_GrepaBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/grepa/3.4bpp");
+const u32 gMapObjectPic_GrepaBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/grepa/4.4bpp");
+const u32 gMapObjectPic_GrepaBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/grepa/5.4bpp");
+const u32 gMapObjectPic_RabutaBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/rabuta/0.4bpp");
+const u32 gMapObjectPic_RabutaBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/rabuta/1.4bpp");
+const u32 gMapObjectPic_RabutaBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/rabuta/2.4bpp");
+const u32 gMapObjectPic_RabutaBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/rabuta/3.4bpp");
+const u32 gMapObjectPic_RabutaBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/rabuta/4.4bpp");
+const u32 gMapObjectPic_RabutaBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/rabuta/5.4bpp");
+const u32 gMapObjectPic_NomelBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/nomel/0.4bpp");
+const u32 gMapObjectPic_NomelBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/nomel/1.4bpp");
+const u32 gMapObjectPic_NomelBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/nomel/2.4bpp");
+const u32 gMapObjectPic_NomelBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/nomel/3.4bpp");
+const u32 gMapObjectPic_NomelBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/nomel/4.4bpp");
+const u32 gMapObjectPic_NomelBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/nomel/5.4bpp");
+const u32 gMapObjectPic_LeppaBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/leppa/0.4bpp");
+const u32 gMapObjectPic_LeppaBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/leppa/1.4bpp");
+const u32 gMapObjectPic_LeppaBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/leppa/2.4bpp");
+const u32 gMapObjectPic_LeppaBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/leppa/3.4bpp");
+const u32 gMapObjectPic_LeppaBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/leppa/4.4bpp");
+const u32 gMapObjectPic_LeppaBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/leppa/5.4bpp");
+const u32 gMapObjectPic_LiechiBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/liechi/0.4bpp");
+const u32 gMapObjectPic_LiechiBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/liechi/1.4bpp");
+const u32 gMapObjectPic_LiechiBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/liechi/2.4bpp");
+const u32 gMapObjectPic_LiechiBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/liechi/3.4bpp");
+const u32 gMapObjectPic_LiechiBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/liechi/4.4bpp");
+const u32 gMapObjectPic_LiechiBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/liechi/5.4bpp");
+const u32 gMapObjectPic_HondewBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/hondew/0.4bpp");
+const u32 gMapObjectPic_HondewBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/hondew/1.4bpp");
+const u32 gMapObjectPic_HondewBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/hondew/2.4bpp");
+const u32 gMapObjectPic_HondewBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/hondew/3.4bpp");
+const u32 gMapObjectPic_HondewBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/hondew/4.4bpp");
+const u32 gMapObjectPic_HondewBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/hondew/5.4bpp");
+const u32 gMapObjectPic_AguavBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/aguav/0.4bpp");
+const u32 gMapObjectPic_AguavBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/aguav/1.4bpp");
+const u32 gMapObjectPic_AguavBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/aguav/2.4bpp");
+const u32 gMapObjectPic_AguavBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/aguav/3.4bpp");
+const u32 gMapObjectPic_AguavBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/aguav/4.4bpp");
+const u32 gMapObjectPic_AguavBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/aguav/5.4bpp");
+const u32 gMapObjectPic_WikiBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/wiki/0.4bpp");
+const u32 gMapObjectPic_WikiBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/wiki/1.4bpp");
+const u32 gMapObjectPic_WikiBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/wiki/2.4bpp");
+const u32 gMapObjectPic_WikiBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/wiki/3.4bpp");
+const u32 gMapObjectPic_WikiBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/wiki/4.4bpp");
+const u32 gMapObjectPic_WikiBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/wiki/5.4bpp");
+const u32 gMapObjectPic_PomegBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/pomeg/0.4bpp");
+const u32 gMapObjectPic_PomegBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/pomeg/1.4bpp");
+const u32 gMapObjectPic_PomegBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/pomeg/2.4bpp");
+const u32 gMapObjectPic_PomegBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/pomeg/3.4bpp");
+const u32 gMapObjectPic_PomegBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/pomeg/4.4bpp");
+const u32 gMapObjectPic_PomegBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/pomeg/5.4bpp");
+const u32 gMapObjectPic_RawstBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/rawst/0.4bpp");
+const u32 gMapObjectPic_RawstBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/rawst/1.4bpp");
+const u32 gMapObjectPic_RawstBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/rawst/2.4bpp");
+const u32 gMapObjectPic_RawstBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/rawst/3.4bpp");
+const u32 gMapObjectPic_RawstBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/rawst/4.4bpp");
+const u32 gMapObjectPic_RawstBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/rawst/5.4bpp");
+const u32 gMapObjectPic_SpelonBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/spelon/0.4bpp");
+const u32 gMapObjectPic_SpelonBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/spelon/1.4bpp");
+const u32 gMapObjectPic_SpelonBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/spelon/2.4bpp");
+const u32 gMapObjectPic_SpelonBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/spelon/3.4bpp");
+const u32 gMapObjectPic_SpelonBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/spelon/4.4bpp");
+const u32 gMapObjectPic_SpelonBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/spelon/5.4bpp");
+const u32 gMapObjectPic_ChestoBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/chesto/0.4bpp");
+const u32 gMapObjectPic_ChestoBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/chesto/1.4bpp");
+const u32 gMapObjectPic_ChestoBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/chesto/2.4bpp");
+const u32 gMapObjectPic_ChestoBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/chesto/3.4bpp");
+const u32 gMapObjectPic_ChestoBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/chesto/4.4bpp");
+const u32 gMapObjectPic_ChestoBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/chesto/5.4bpp");
+const u32 gMapObjectPic_OranBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/oran/0.4bpp");
+const u32 gMapObjectPic_OranBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/oran/1.4bpp");
+const u32 gMapObjectPic_OranBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/oran/2.4bpp");
+const u32 gMapObjectPic_OranBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/oran/3.4bpp");
+const u32 gMapObjectPic_OranBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/oran/4.4bpp");
+const u32 gMapObjectPic_OranBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/oran/5.4bpp");
+const u32 gMapObjectPic_PersimBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/persim/0.4bpp");
+const u32 gMapObjectPic_PersimBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/persim/1.4bpp");
+const u32 gMapObjectPic_PersimBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/persim/2.4bpp");
+const u32 gMapObjectPic_PersimBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/persim/3.4bpp");
+const u32 gMapObjectPic_PersimBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/persim/4.4bpp");
+const u32 gMapObjectPic_PersimBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/persim/5.4bpp");
+const u32 gMapObjectPic_SitrusBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/sitrus/0.4bpp");
+const u32 gMapObjectPic_SitrusBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/sitrus/1.4bpp");
+const u32 gMapObjectPic_SitrusBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/sitrus/2.4bpp");
+const u32 gMapObjectPic_SitrusBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/sitrus/3.4bpp");
+const u32 gMapObjectPic_SitrusBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/sitrus/4.4bpp");
+const u32 gMapObjectPic_SitrusBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/sitrus/5.4bpp");
+const u32 gMapObjectPic_AspearBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/aspear/0.4bpp");
+const u32 gMapObjectPic_AspearBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/aspear/1.4bpp");
+const u32 gMapObjectPic_AspearBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/aspear/2.4bpp");
+const u32 gMapObjectPic_AspearBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/aspear/3.4bpp");
+const u32 gMapObjectPic_AspearBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/aspear/4.4bpp");
+const u32 gMapObjectPic_AspearBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/aspear/5.4bpp");
+const u32 gMapObjectPic_PamtreBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/pamtre/0.4bpp");
+const u32 gMapObjectPic_PamtreBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/pamtre/1.4bpp");
+const u32 gMapObjectPic_PamtreBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/pamtre/2.4bpp");
+const u32 gMapObjectPic_PamtreBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/pamtre/3.4bpp");
+const u32 gMapObjectPic_PamtreBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/pamtre/4.4bpp");
+const u32 gMapObjectPic_PamtreBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/pamtre/5.4bpp");
+const u32 gMapObjectPic_CornnBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/cornn/0.4bpp");
+const u32 gMapObjectPic_CornnBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/cornn/1.4bpp");
+const u32 gMapObjectPic_CornnBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/cornn/2.4bpp");
+const u32 gMapObjectPic_CornnBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/cornn/3.4bpp");
+const u32 gMapObjectPic_CornnBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/cornn/4.4bpp");
+const u32 gMapObjectPic_CornnBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/cornn/5.4bpp");
+const u32 gMapObjectPic_LansatBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/lansat/0.4bpp");
+const u32 gMapObjectPic_LansatBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/lansat/1.4bpp");
+const u32 gMapObjectPic_LansatBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/lansat/2.4bpp");
+const u32 gMapObjectPic_LansatBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/lansat/3.4bpp");
+const u32 gMapObjectPic_LansatBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/lansat/4.4bpp");
+const u32 gMapObjectPic_LansatBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/lansat/5.4bpp");
+const u32 gMapObjectPic_DurinBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/durin/0.4bpp");
+const u32 gMapObjectPic_DurinBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/durin/1.4bpp");
+const u32 gMapObjectPic_DurinBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/durin/2.4bpp");
+const u32 gMapObjectPic_DurinBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/durin/3.4bpp");
+const u32 gMapObjectPic_DurinBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/durin/4.4bpp");
+const u32 gMapObjectPic_DurinBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/durin/5.4bpp");
+const u32 gMapObjectPic_TamatoBerryTree_0[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/tamato/0.4bpp");
+const u32 gMapObjectPic_TamatoBerryTree_1[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/tamato/1.4bpp");
+const u32 gMapObjectPic_TamatoBerryTree_2[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/tamato/2.4bpp");
+const u32 gMapObjectPic_TamatoBerryTree_3[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/tamato/3.4bpp");
+const u32 gMapObjectPic_TamatoBerryTree_4[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/tamato/4.4bpp");
+const u32 gMapObjectPic_TamatoBerryTree_5[] = INCBIN_U32("graphics/map_objects/pics/berry_trees/tamato/5.4bpp");
+const u32 gFieldEffectPic_SurfBlob_0[] = INCBIN_U32("graphics/field_effect_objects/pics/surf_blob/0.4bpp");
+const u32 gFieldEffectPic_SurfBlob_1[] = INCBIN_U32("graphics/field_effect_objects/pics/surf_blob/1.4bpp");
+const u32 gFieldEffectPic_SurfBlob_2[] = INCBIN_U32("graphics/field_effect_objects/pics/surf_blob/2.4bpp");
+const u32 gMapObjectPic_QuintyPlump_0[] = INCBIN_U32("graphics/map_objects/pics/people/quinty_plump/0.4bpp");
+const u32 gMapObjectPic_QuintyPlump_1[] = INCBIN_U32("graphics/map_objects/pics/people/quinty_plump/1.4bpp");
+const u32 gMapObjectPic_QuintyPlump_2[] = INCBIN_U32("graphics/map_objects/pics/people/quinty_plump/2.4bpp");
+const u32 gMapObjectPic_QuintyPlump_3[] = INCBIN_U32("graphics/map_objects/pics/people/quinty_plump/3.4bpp");
+const u32 gMapObjectPic_QuintyPlump_4[] = INCBIN_U32("graphics/map_objects/pics/people/quinty_plump/4.4bpp");
+const u32 gMapObjectPic_QuintyPlump_5[] = INCBIN_U32("graphics/map_objects/pics/people/quinty_plump/5.4bpp");
+const u32 gMapObjectPic_QuintyPlump_6[] = INCBIN_U32("graphics/map_objects/pics/people/quinty_plump/6.4bpp");
+const u16 gMapObjectPalette12[] = INCBIN_U16("graphics/map_objects/palettes/12.gbapal");
+const u16 gMapObjectPalette13[] = INCBIN_U16("graphics/map_objects/palettes/13.gbapal");
+
+const u32 gFieldEffectPic_ShadowSmall[] = INCBIN_U32("graphics/field_effect_objects/pics/shadow_small.4bpp");
+const u32 gFieldEffectPic_ShadowMedium[] = INCBIN_U32("graphics/field_effect_objects/pics/shadow_medium.4bpp");
+const u32 gFieldEffectPic_ShadowLarge[] = INCBIN_U32("graphics/field_effect_objects/pics/shadow_large.4bpp");
+const u32 gFieldEffectPic_ShadowExtraLarge[] = INCBIN_U32("graphics/field_effect_objects/pics/shadow_extra_large.4bpp");
+const u32 filler_8368A08[0x48] = {};
+const u32 gFieldEffectPic_CutGrass[] = INCBIN_U32("graphics/field_effect_objects/pics/cut_grass.4bpp");
+const u32 FieldEffectPic_CutGrass_Copy[] = INCBIN_U32("graphics/field_effect_objects/pics/cut_grass.4bpp");
+const u16 gFieldEffectObjectPalette6[] = INCBIN_U16("graphics/field_effect_objects/palettes/06.gbapal");
+const u32 gFieldEffectPic_Ripple_0[] = INCBIN_U32("graphics/field_effect_objects/pics/ripple/0.4bpp");
+const u32 gFieldEffectPic_Ripple_1[] = INCBIN_U32("graphics/field_effect_objects/pics/ripple/1.4bpp");
+const u32 gFieldEffectPic_Ripple_2[] = INCBIN_U32("graphics/field_effect_objects/pics/ripple/2.4bpp");
+const u32 gFieldEffectPic_Ripple_3[] = INCBIN_U32("graphics/field_effect_objects/pics/ripple/3.4bpp");
+const u32 gFieldEffectPic_Ripple_4[] = INCBIN_U32("graphics/field_effect_objects/pics/ripple/4.4bpp");
+const u32 gFieldEffectPic_Ash_0[] = INCBIN_U32("graphics/field_effect_objects/pics/ash/0.4bpp");
+const u32 gFieldEffectPic_Ash_1[] = INCBIN_U32("graphics/field_effect_objects/pics/ash/1.4bpp");
+const u32 gFieldEffectPic_Ash_2[] = INCBIN_U32("graphics/field_effect_objects/pics/ash/2.4bpp");
+const u32 gFieldEffectPic_Ash_3[] = INCBIN_U32("graphics/field_effect_objects/pics/ash/3.4bpp");
+const u32 gFieldEffectPic_Ash_4[] = INCBIN_U32("graphics/field_effect_objects/pics/ash/4.4bpp");
+const u32 gFieldEffectPic_Arrow_0[] = INCBIN_U32("graphics/field_effect_objects/pics/arrow/0.4bpp");
+const u32 gFieldEffectPic_Arrow_1[] = INCBIN_U32("graphics/field_effect_objects/pics/arrow/1.4bpp");
+const u32 gFieldEffectPic_Arrow_2[] = INCBIN_U32("graphics/field_effect_objects/pics/arrow/2.4bpp");
+const u32 gFieldEffectPic_Arrow_3[] = INCBIN_U32("graphics/field_effect_objects/pics/arrow/3.4bpp");
+const u32 gFieldEffectPic_Arrow_4[] = INCBIN_U32("graphics/field_effect_objects/pics/arrow/4.4bpp");
+const u32 gFieldEffectPic_Arrow_5[] = INCBIN_U32("graphics/field_effect_objects/pics/arrow/5.4bpp");
+const u32 gFieldEffectPic_Arrow_6[] = INCBIN_U32("graphics/field_effect_objects/pics/arrow/6.4bpp");
+const u32 gFieldEffectPic_Arrow_7[] = INCBIN_U32("graphics/field_effect_objects/pics/arrow/7.4bpp");
+const u16 gFieldEffectObjectPalette0[] = INCBIN_U16("graphics/field_effect_objects/palettes/00.gbapal");
+const u16 gFieldEffectObjectPalette1[] = INCBIN_U16("graphics/field_effect_objects/palettes/01.gbapal");
+const u32 gFieldEffectPic_Dust_0[] = INCBIN_U32("graphics/field_effect_objects/pics/dust/0.4bpp");
+const u32 gFieldEffectPic_Dust_1[] = INCBIN_U32("graphics/field_effect_objects/pics/dust/1.4bpp");
+const u32 gFieldEffectPic_Dust_2[] = INCBIN_U32("graphics/field_effect_objects/pics/dust/2.4bpp");
+const u32 unknown_8369588[] = INCBIN_U32("graphics/field_effect_objects/unknown.bin");
+const u32 gFieldEffectPic_JumpTallGrass_0[] = INCBIN_U32("graphics/field_effect_objects/pics/jump_tall_grass/0.4bpp");
+const u32 gFieldEffectPic_JumpTallGrass_1[] = INCBIN_U32("graphics/field_effect_objects/pics/jump_tall_grass/1.4bpp");
+const u32 gFieldEffectPic_JumpTallGrass_2[] = INCBIN_U32("graphics/field_effect_objects/pics/jump_tall_grass/2.4bpp");
+const u32 gFieldEffectPic_JumpTallGrass_3[] = INCBIN_U32("graphics/field_effect_objects/pics/jump_tall_grass/3.4bpp");
+const u32 UnusedGrass0[] = INCBIN_U32("graphics/field_effect_objects/pics/unused_grass/0.4bpp");
+const u32 UnusedGrass1[] = INCBIN_U32("graphics/field_effect_objects/pics/unused_grass/1.4bpp");
+const u32 UnusedGrass2[] = INCBIN_U32("graphics/field_effect_objects/pics/unused_grass/2.4bpp");
+const u32 UnusedGrass3[] = INCBIN_U32("graphics/field_effect_objects/pics/unused_grass/3.4bpp");
+const u32 gFieldEffectPic_JumpLongGrass_0[] = INCBIN_U32("graphics/field_effect_objects/pics/jump_long_grass/0.4bpp");
+const u32 gFieldEffectPic_JumpLongGrass_1[] = INCBIN_U32("graphics/field_effect_objects/pics/jump_long_grass/1.4bpp");
+const u32 gFieldEffectPic_JumpLongGrass_2[] = INCBIN_U32("graphics/field_effect_objects/pics/jump_long_grass/2.4bpp");
+const u32 gFieldEffectPic_JumpLongGrass_3[] = INCBIN_U32("graphics/field_effect_objects/pics/jump_long_grass/3.4bpp");
+const u32 gFieldEffectPic_JumpLongGrass_4[] = INCBIN_U32("graphics/field_effect_objects/pics/jump_long_grass/4.4bpp");
+const u32 UnusedGrassLong[] = INCBIN_U32("graphics/field_effect_objects/pics/jump_long_grass/unused.4bpp");
+const u32 gFieldEffectPic_JumpLongGrass_5[] = INCBIN_U32("graphics/field_effect_objects/pics/jump_long_grass/5.4bpp");
+const u32 gFieldEffectPic_Unknown17_0[] = INCBIN_U32("graphics/field_effect_objects/pics/unknown_17/0.4bpp");
+const u32 gFieldEffectPic_Unknown17_1[] = INCBIN_U32("graphics/field_effect_objects/pics/unknown_17/1.4bpp");
+const u32 gFieldEffectPic_Unknown17_2[] = INCBIN_U32("graphics/field_effect_objects/pics/unknown_17/2.4bpp");
+const u32 gFieldEffectPic_Unknown17_3[] = INCBIN_U32("graphics/field_effect_objects/pics/unknown_17/3.4bpp");
+const u32 gFieldEffectPic_Unknown17_4[] = INCBIN_U32("graphics/field_effect_objects/pics/unknown_17/4.4bpp");
+const u32 gFieldEffectPic_Unknown17_5[] = INCBIN_U32("graphics/field_effect_objects/pics/unknown_17/5.4bpp");
+const u32 gFieldEffectPic_Unknown17_6[] = INCBIN_U32("graphics/field_effect_objects/pics/unknown_17/6.4bpp");
+const u32 gFieldEffectPic_Unknown17_7[] = INCBIN_U32("graphics/field_effect_objects/pics/unknown_17/7.4bpp");
+const u32 gFieldEffectPic_Unknown18_0[] = INCBIN_U32("graphics/field_effect_objects/pics/unknown_18/0.4bpp");
+const u32 gFieldEffectPic_Unknown18_1[] = INCBIN_U32("graphics/field_effect_objects/pics/unknown_18/1.4bpp");
+const u32 gFieldEffectPic_Unknown18_2[] = INCBIN_U32("graphics/field_effect_objects/pics/unknown_18/2.4bpp");
+const u32 gFieldEffectPic_Unknown18_3[] = INCBIN_U32("graphics/field_effect_objects/pics/unknown_18/3.4bpp");
+const u32 gFieldEffectPic_LongGrass_0[] = INCBIN_U32("graphics/field_effect_objects/pics/long_grass/0.4bpp");
+const u32 gFieldEffectPic_LongGrass_1[] = INCBIN_U32("graphics/field_effect_objects/pics/long_grass/1.4bpp");
+const u32 gFieldEffectPic_LongGrass_2[] = INCBIN_U32("graphics/field_effect_objects/pics/long_grass/2.4bpp");
+const u32 gFieldEffectPic_LongGrass_3[] = INCBIN_U32("graphics/field_effect_objects/pics/long_grass/3.4bpp");
+const u32 gFieldEffectPic_TallGrass_0[] = INCBIN_U32("graphics/field_effect_objects/pics/tall_grass/0.4bpp");
+const u32 gFieldEffectPic_TallGrass_1[] = INCBIN_U32("graphics/field_effect_objects/pics/tall_grass/1.4bpp");
+const u32 gFieldEffectPic_TallGrass_2[] = INCBIN_U32("graphics/field_effect_objects/pics/tall_grass/2.4bpp");
+const u32 gFieldEffectPic_TallGrass_3[] = INCBIN_U32("graphics/field_effect_objects/pics/tall_grass/3.4bpp");
+const u32 gFieldEffectPic_TallGrass_4[] = INCBIN_U32("graphics/field_effect_objects/pics/tall_grass/4.4bpp");
+const u32 gFieldEffectPic_ShortGrass_0[] = INCBIN_U32("graphics/field_effect_objects/pics/short_grass/0.4bpp");
+const u32 gFieldEffectPic_ShortGrass_1[] = INCBIN_U32("graphics/field_effect_objects/pics/short_grass/1.4bpp");
+const u32 gFieldEffectPic_SandFootprints_0[] = INCBIN_U32("graphics/field_effect_objects/pics/sand_footprints/0.4bpp");
+const u32 gFieldEffectPic_SandFootprints_1[] = INCBIN_U32("graphics/field_effect_objects/pics/sand_footprints/1.4bpp");
+const u32 gFieldEffectPic_DeepSandFootprints_0[] = INCBIN_U32("graphics/field_effect_objects/pics/deep_sand_footprints/0.4bpp");
+const u32 gFieldEffectPic_DeepSandFootprints_1[] = INCBIN_U32("graphics/field_effect_objects/pics/deep_sand_footprints/1.4bpp");
+const u32 gFieldEffectPic_BikeTireTracks_0[] = INCBIN_U32("graphics/field_effect_objects/pics/bike_tire_tracks/0.4bpp");
+const u32 gFieldEffectPic_BikeTireTracks_1[] = INCBIN_U32("graphics/field_effect_objects/pics/bike_tire_tracks/1.4bpp");
+const u32 gFieldEffectPic_BikeTireTracks_2[] = INCBIN_U32("graphics/field_effect_objects/pics/bike_tire_tracks/2.4bpp");
+const u32 gFieldEffectPic_BikeTireTracks_3[] = INCBIN_U32("graphics/field_effect_objects/pics/bike_tire_tracks/3.4bpp");
+const u32 gFieldEffectPic_Unknown19_0[] = INCBIN_U32("graphics/field_effect_objects/pics/unknown_19/0.4bpp");
+const u32 gFieldEffectPic_Unknown19_1[] = INCBIN_U32("graphics/field_effect_objects/pics/unknown_19/1.4bpp");
+const u32 gFieldEffectPic_Unknown19_2[] = INCBIN_U32("graphics/field_effect_objects/pics/unknown_19/2.4bpp");
+const u32 gFieldEffectPic_Unknown19_3[] = INCBIN_U32("graphics/field_effect_objects/pics/unknown_19/3.4bpp");
+const u32 gFieldEffectPic_SandPile_0[] = INCBIN_U32("graphics/field_effect_objects/pics/sand_pile/0.4bpp");
+const u32 gFieldEffectPic_SandPile_1[] = INCBIN_U32("graphics/field_effect_objects/pics/sand_pile/1.4bpp");
+const u32 gFieldEffectPic_SandPile_2[] = INCBIN_U32("graphics/field_effect_objects/pics/sand_pile/2.4bpp");
+const u32 gFieldEffectPic_JumpBigSplash_0[] = INCBIN_U32("graphics/field_effect_objects/pics/jump_big_splash/0.4bpp");
+const u32 gFieldEffectPic_JumpBigSplash_1[] = INCBIN_U32("graphics/field_effect_objects/pics/jump_big_splash/1.4bpp");
+const u32 gFieldEffectPic_JumpBigSplash_2[] = INCBIN_U32("graphics/field_effect_objects/pics/jump_big_splash/2.4bpp");
+const u32 gFieldEffectPic_JumpBigSplash_3[] = INCBIN_U32("graphics/field_effect_objects/pics/jump_big_splash/3.4bpp");
+const u32 gFieldEffectPic_Splash_0[] = INCBIN_U32("graphics/field_effect_objects/pics/splash/0.4bpp");
+const u32 gFieldEffectPic_Splash_1[] = INCBIN_U32("graphics/field_effect_objects/pics/splash/1.4bpp");
+const u32 gFieldEffectPic_JumpSmallSplash_0[] = INCBIN_U32("graphics/field_effect_objects/pics/jump_small_splash/0.4bpp");
+const u32 gFieldEffectPic_JumpSmallSplash_1[] = INCBIN_U32("graphics/field_effect_objects/pics/jump_small_splash/1.4bpp");
+const u32 gFieldEffectPic_JumpSmallSplash_2[] = INCBIN_U32("graphics/field_effect_objects/pics/jump_small_splash/2.4bpp");
+const u32 gFieldEffectPic_Unknown20_0[] = INCBIN_U32("graphics/field_effect_objects/pics/unknown_20/0.4bpp");
+const u32 gFieldEffectPic_Unknown20_1[] = INCBIN_U32("graphics/field_effect_objects/pics/unknown_20/1.4bpp");
+const u32 gFieldEffectPic_Unknown20_2[] = INCBIN_U32("graphics/field_effect_objects/pics/unknown_20/2.4bpp");
+const u32 gFieldEffectPic_Unknown20_3[] = INCBIN_U32("graphics/field_effect_objects/pics/unknown_20/3.4bpp");
+const u32 gFieldEffectPic_Unknown20_4[] = INCBIN_U32("graphics/field_effect_objects/pics/unknown_20/4.4bpp");
+const u32 gFieldEffectPic_TreeDisguise_0[] = INCBIN_U32("graphics/field_effect_objects/pics/tree_disguise/0.4bpp");
+const u32 gFieldEffectPic_TreeDisguise_1[] = INCBIN_U32("graphics/field_effect_objects/pics/tree_disguise/1.4bpp");
+const u32 gFieldEffectPic_TreeDisguise_2[] = INCBIN_U32("graphics/field_effect_objects/pics/tree_disguise/2.4bpp");
+const u32 gFieldEffectPic_TreeDisguise_3[] = INCBIN_U32("graphics/field_effect_objects/pics/tree_disguise/3.4bpp");
+const u32 gFieldEffectPic_TreeDisguise_4[] = INCBIN_U32("graphics/field_effect_objects/pics/tree_disguise/4.4bpp");
+const u32 gFieldEffectPic_TreeDisguise_5[] = INCBIN_U32("graphics/field_effect_objects/pics/tree_disguise/5.4bpp");
+const u32 gFieldEffectPic_TreeDisguise_6[] = INCBIN_U32("graphics/field_effect_objects/pics/tree_disguise/6.4bpp");
+const u32 gFieldEffectPic_MountainDisguise_0[] = INCBIN_U32("graphics/field_effect_objects/pics/mountain_disguise/0.4bpp");
+const u32 gFieldEffectPic_MountainDisguise_1[] = INCBIN_U32("graphics/field_effect_objects/pics/mountain_disguise/1.4bpp");
+const u32 gFieldEffectPic_MountainDisguise_2[] = INCBIN_U32("graphics/field_effect_objects/pics/mountain_disguise/2.4bpp");
+const u32 gFieldEffectPic_MountainDisguise_3[] = INCBIN_U32("graphics/field_effect_objects/pics/mountain_disguise/3.4bpp");
+const u32 gFieldEffectPic_MountainDisguise_4[] = INCBIN_U32("graphics/field_effect_objects/pics/mountain_disguise/4.4bpp");
+const u32 gFieldEffectPic_MountainDisguise_5[] = INCBIN_U32("graphics/field_effect_objects/pics/mountain_disguise/5.4bpp");
+const u32 gFieldEffectPic_MountainDisguise_6[] = INCBIN_U32("graphics/field_effect_objects/pics/mountain_disguise/6.4bpp");
+const u32 gFieldEffectPic_SandDisguise_0[] = INCBIN_U32("graphics/field_effect_objects/pics/sand_disguise/0.4bpp");
+const u32 gFieldEffectPic_SandDisguise_1[] = INCBIN_U32("graphics/field_effect_objects/pics/sand_disguise/1.4bpp");
+const u32 gFieldEffectPic_SandDisguise_2[] = INCBIN_U32("graphics/field_effect_objects/pics/sand_disguise/2.4bpp");
+const u32 gFieldEffectPic_SandDisguise_3[] = INCBIN_U32("graphics/field_effect_objects/pics/sand_disguise/3.4bpp");
+const u32 gFieldEffectPic_SandDisguise_4[] = INCBIN_U32("graphics/field_effect_objects/pics/sand_disguise/4.4bpp");
+const u32 gFieldEffectPic_SandDisguise_5[] = INCBIN_U32("graphics/field_effect_objects/pics/sand_disguise/5.4bpp");
+const u32 gFieldEffectPic_SandDisguise_6[] = INCBIN_U32("graphics/field_effect_objects/pics/sand_disguise/6.4bpp");
+const u32 gFieldEffectPic_HotSpringsWater[] = INCBIN_U32("graphics/field_effect_objects/pics/hot_springs_water.4bpp");
+const u16 gFieldEffectObjectPalette2[] = INCBIN_U16("graphics/field_effect_objects/palettes/02.gbapal");
+const u32 gFieldEffectPic_PopOutOfAsh_0[] = INCBIN_U32("graphics/field_effect_objects/pics/pop_out_of_ash/0.4bpp");
+const u32 gFieldEffectPic_PopOutOfAsh_1[] = INCBIN_U32("graphics/field_effect_objects/pics/pop_out_of_ash/1.4bpp");
+const u32 gFieldEffectPic_PopOutOfAsh_2[] = INCBIN_U32("graphics/field_effect_objects/pics/pop_out_of_ash/2.4bpp");
+const u32 gFieldEffectPic_PopOutOfAsh_3[] = INCBIN_U32("graphics/field_effect_objects/pics/pop_out_of_ash/3.4bpp");
+const u32 gFieldEffectPic_PopOutOfAsh_4[] = INCBIN_U32("graphics/field_effect_objects/pics/pop_out_of_ash/4.4bpp");
+const u32 gFieldEffectPic_LavaridgeGymWarp_0[] = INCBIN_U32("graphics/field_effect_objects/pics/lavaridge_gym_warp/0.4bpp");
+const u32 gFieldEffectPic_LavaridgeGymWarp_1[] = INCBIN_U32("graphics/field_effect_objects/pics/lavaridge_gym_warp/1.4bpp");
+const u32 gFieldEffectPic_LavaridgeGymWarp_2[] = INCBIN_U32("graphics/field_effect_objects/pics/lavaridge_gym_warp/2.4bpp");
+const u32 gFieldEffectPic_LavaridgeGymWarp_3[] = INCBIN_U32("graphics/field_effect_objects/pics/lavaridge_gym_warp/3.4bpp");
+const u32 gFieldEffectPic_LavaridgeGymWarp_4[] = INCBIN_U32("graphics/field_effect_objects/pics/lavaridge_gym_warp/4.4bpp");
+const u32 gFieldEffectPic_Bubbles_0[] = INCBIN_U32("graphics/field_effect_objects/pics/bubbles/0.4bpp");
+const u32 gFieldEffectPic_Bubbles_1[] = INCBIN_U32("graphics/field_effect_objects/pics/bubbles/1.4bpp");
+const u32 gFieldEffectPic_Bubbles_2[] = INCBIN_U32("graphics/field_effect_objects/pics/bubbles/2.4bpp");
+const u32 gFieldEffectPic_Bubbles_3[] = INCBIN_U32("graphics/field_effect_objects/pics/bubbles/3.4bpp");
+const u32 gFieldEffectPic_Bubbles_4[] = INCBIN_U32("graphics/field_effect_objects/pics/bubbles/4.4bpp");
+const u32 gFieldEffectPic_Bubbles_5[] = INCBIN_U32("graphics/field_effect_objects/pics/bubbles/5.4bpp");
+const u32 gFieldEffectPic_Bubbles_6[] = INCBIN_U32("graphics/field_effect_objects/pics/bubbles/6.4bpp");
+const u32 gFieldEffectPic_Bubbles_7[] = INCBIN_U32("graphics/field_effect_objects/pics/bubbles/7.4bpp");
+const u32 gFieldEffectPic_Sparkle_0[] = INCBIN_U32("graphics/field_effect_objects/pics/sparkle/0.4bpp");
+const u32 gFieldEffectPic_Sparkle_1[] = INCBIN_U32("graphics/field_effect_objects/pics/sparkle/1.4bpp");
+const u16 gFieldEffectObjectPalette3[] = INCBIN_U16("graphics/field_effect_objects/palettes/03.gbapal");
+const u32 gFieldEffectPic_Bird[] = INCBIN_U32("graphics/field_effect_objects/pics/bird.4bpp");
+
+void (*const gUnknown_0836DA88[])(struct Sprite *) =
+{
+ sub_805C884,
+ sub_805CDE8,
+ sub_805C8AC,
+ sub_805CF28,
+ sub_805CF28,
+ sub_805D0AC,
+ sub_805D0AC,
+ sub_805D230,
+ sub_805D230,
+ sub_805D230,
+ sub_805D230,
+ sub_80587B4,
+ FieldObjectCB_BerryTree,
+ sub_805D4F4,
+ sub_805D634,
+ sub_805D774,
+ sub_805D8B4,
+ sub_805D9F4,
+ sub_805DB34,
+ sub_805DC74,
+ sub_805DDB4,
+ sub_805DEF4,
+ sub_805E034,
+ sub_805E174,
+ sub_805E278,
+ sub_805E37C,
+ sub_805E37C,
+ sub_805E37C,
+ sub_805E37C,
+ sub_805E5DC,
+ sub_805E668,
+ sub_805E6F4,
+ sub_805E780,
+ sub_805E80C,
+ sub_805E898,
+ sub_805E924,
+ sub_805E9B0,
+ sub_805EA3C,
+ sub_805EAC8,
+ sub_805EB54,
+ sub_805EBE0,
+ sub_805EC6C,
+ sub_805ECF8,
+ sub_805ED84,
+ sub_805EE10,
+ sub_805EE9C,
+ sub_805EF28,
+ sub_805EFB4,
+ sub_805F040,
+ sub_805F0CC,
+ sub_805F158,
+ sub_805F1E4,
+ sub_805F270,
+ sub_805F2FC,
+ sub_805F2FC,
+ sub_805F2FC,
+ sub_805F2FC,
+ FieldObjectCB_TreeDisguise,
+ FieldObjectCB_MountainDisguise,
+ sub_805F8E0,
+ sub_805F8E0,
+ sub_805F8E0,
+ sub_805F8E0,
+ FieldObjectCB_Hidden1,
+ sub_805FB20,
+ sub_805FB20,
+ sub_805FB20,
+ sub_805FB20,
+ sub_805FB90,
+ sub_805FB90,
+ sub_805FB90,
+ sub_805FB90,
+ sub_805FC00,
+ sub_805FC00,
+ sub_805FC00,
+ sub_805FC00,
+ sub_805FC70
+};
+
+const u8 gUnknown_0836DBBC[] = {0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+const u8 gUnknown_0836DC09[] = {DIR_SOUTH, DIR_SOUTH, DIR_SOUTH, DIR_NORTH, DIR_SOUTH, DIR_WEST, DIR_EAST, DIR_NORTH, DIR_SOUTH, DIR_WEST, DIR_EAST, DIR_SOUTH, DIR_SOUTH, DIR_SOUTH, DIR_WEST, DIR_NORTH, DIR_NORTH, DIR_SOUTH, DIR_SOUTH, DIR_SOUTH, DIR_SOUTH, DIR_NORTH, DIR_SOUTH, DIR_SOUTH, DIR_SOUTH, DIR_NORTH, DIR_SOUTH, DIR_WEST, DIR_EAST, DIR_NORTH, DIR_EAST, DIR_SOUTH, DIR_WEST, DIR_NORTH, DIR_WEST, DIR_SOUTH, DIR_EAST, DIR_WEST, DIR_NORTH, DIR_EAST, DIR_SOUTH, DIR_EAST, DIR_NORTH, DIR_WEST, DIR_SOUTH, DIR_NORTH, DIR_SOUTH, DIR_WEST, DIR_EAST, DIR_NORTH, DIR_SOUTH, DIR_WEST, DIR_EAST, DIR_NORTH, DIR_SOUTH, DIR_WEST, DIR_EAST, DIR_SOUTH, DIR_SOUTH, DIR_NORTH, DIR_SOUTH, DIR_WEST, DIR_EAST, DIR_SOUTH, DIR_SOUTH, DIR_NORTH, DIR_WEST, DIR_EAST, DIR_SOUTH, DIR_NORTH, DIR_WEST, DIR_EAST, DIR_SOUTH, DIR_NORTH, DIR_WEST, DIR_EAST, DIR_SOUTH};
+
+#include "data/field_map_obj/map_object_graphics_info_pointers.h"
+#include "data/field_map_obj/field_effect_object_template_pointers.h"
+#include "data/field_map_obj/map_object_pic_tables.h"
+#include "data/field_map_obj/map_object_anims.h"
+#include "data/field_map_obj/base_oam.h"
+#include "data/field_map_obj/map_object_subsprites.h"
+#include "data/field_map_obj/map_object_graphics_info.h"
+
+const struct SpritePalette gUnknown_0837377C[] = {
+ {gMapObjectPalette0, 0x1103},
+ {gMapObjectPalette1, 0x1104},
+ {gMapObjectPalette2, 0x1105},
+ {gMapObjectPalette3, 0x1106},
+ {gMapObjectPalette4, 0x1107},
+ {gMapObjectPalette5, 0x1108},
+ {gMapObjectPalette6, 0x1109},
+ {gMapObjectPalette7, 0x110A},
+ {gMapObjectPalette8, 0x1100},
+ {gMapObjectPalette9, 0x1101},
+ {gMapObjectPalette10, 0x1102},
+ {gMapObjectPalette11, 0x1115},
+ {gMapObjectPalette12, 0x110B},
+ {gMapObjectPalette13, 0x110C},
+ {gMapObjectPalette14, 0x110D},
+ {gMapObjectPalette15, 0x110E},
+ {gMapObjectPalette16, 0x110F},
+ {gMapObjectPalette17, 0x1110},
+ {gMapObjectPalette18, 0x1111},
+ {gMapObjectPalette19, 0x1112},
+ {gMapObjectPalette20, 0x1113},
+ {gMapObjectPalette21, 0x1114},
+ {gMapObjectPalette22, 0x1116},
+ {gMapObjectPalette23, 0x1117},
+ {gMapObjectPalette24, 0x1118},
+ {gMapObjectPalette25, 0x1119},
+ {gMapObjectPalette26, 0x111A},
+ {NULL, 0x0000}
+};
+
+const u16 Palettes_837385C[] = {
+ 0x1101,
+ 0x1101,
+ 0x1101,
+ 0x1101
+};
+
+const u16 Palettes_8373864[] = {
+ 0x1111,
+ 0x1111,
+ 0x1111,
+ 0x1111
+};
+
+const u16 Palettes_837386C[] = {
+ 0x1115,
+ 0x1115,
+ 0x1115,
+ 0x1115
+};
+
+const struct PairedPalettes gUnknown_08373874[] = {
+ {0x1100, Palettes_837385C},
+ {0x1110, Palettes_837385C},
+ {0x1115, Palettes_837386C},
+ {0x11FF, NULL}
+};
+
+const u16 Palettes_8373894[] = {
+ 0x110C,
+ 0x110C,
+ 0x110C,
+ 0x110C
+};
+
+const u16 Palettes_837389C[] = {
+ 0x110D,
+ 0x110D,
+ 0x110D,
+ 0x110D
+};
+
+const u16 Palettes_83738A4[] = {
+ 0x110E,
+ 0x110E,
+ 0x110E,
+ 0x110E
+};
+
+const u16 Palettes_83738AC[] = {
+ 0x1112,
+ 0x1112,
+ 0x1112,
+ 0x1112
+};
+
+const u16 Palettes_83738B4[] = {
+ 0x1113,
+ 0x1113,
+ 0x1113,
+ 0x1113
+};
+
+const u16 Palettes_83738BC[] = {
+ 0x1114,
+ 0x1114,
+ 0x1114,
+ 0x1114
+};
+
+const u16 Palettes_83738C4[] = {
+ 0x111A,
+ 0x111A,
+ 0x111A,
+ 0x111A
+};
+
+const u16 Palettes_83738CC[] = {
+ 0x1117,
+ 0x1117,
+ 0x1117,
+ 0x1117
+};
+
+const u16 Palettes_83738D4[] = {
+ 0x1119,
+ 0x1119,
+ 0x1119,
+ 0x1119
+};
+
+const u16 Palettes_83738DC[] = {
+ 0x1109,
+ 0x1109,
+ 0x1109,
+ 0x1109
+};
+
+const struct PairedPalettes gUnknown_083738E4[] = {
+ {0x1100, Palettes_837385C},
+ {0x1110, Palettes_837385C},
+ {0x110B, Palettes_8373894},
+ {0x110D, Palettes_837389C},
+ {0x110E, Palettes_83738A4},
+ {0x1112, Palettes_83738AC},
+ {0x1113, Palettes_83738B4},
+ {0x1114, Palettes_83738BC},
+ {0x1116, Palettes_83738CC},
+ {0x1118, Palettes_83738D4},
+ {0x1105, Palettes_83738DC},
+ {0x111A, Palettes_83738C4},
+ {0x11FF, NULL}
+};
+
+const u16 Unknown_837394C[] = {
+ 0x1100,
+ 0x1101,
+ 0x1103,
+ 0x1104,
+ 0x1105,
+ 0x1106,
+ 0x1107,
+ 0x1108,
+ 0x1109,
+ 0x110A
+};
+
+const u16 Unknown_8373960[] = {
+ 0x1100,
+ 0x1101,
+ 0x1103,
+ 0x1104,
+ 0x1105,
+ 0x1106,
+ 0x1107,
+ 0x1108,
+ 0x1109,
+ 0x110A
+};
+
+const u16 Unknown_8373974[] = {
+ 0x1100,
+ 0x1101,
+ 0x1103,
+ 0x1104,
+ 0x1105,
+ 0x1106,
+ 0x1107,
+ 0x1108,
+ 0x1109,
+ 0x110A
+};
+
+const u16 Unknown_8373988[] = {
+ 0x1100,
+ 0x1101,
+ 0x1103,
+ 0x1104,
+ 0x1105,
+ 0x1106,
+ 0x1107,
+ 0x1108,
+ 0x1109,
+ 0x110A
+};
+
+const u16 *const gUnknown_0837399C[] = {
+ Unknown_837394C,
+ Unknown_8373960,
+ Unknown_8373974,
+ Unknown_8373988
+};
+
+#include "data/field_map_obj/berry_tree_graphics_tables.h"
+#include "data/field_map_obj/field_effect_objects.h"
+
+const s16 gUnknown_0837520C[] = {0x20, 0x40, 0x60, 0x80};
+const s16 gUnknown_08375204[] = {0x20, 0x40, 0x80, 0xc0};
+const s16 gUnknown_0837521C[] = {0x20, 0x30, 0x40, 0x50};
+
+#include "data/field_map_obj/callback_subroutine_pointers.h"
+
+const u8 gUnknown_083755F4[] = {0x00, 0x00, 0x01, 0x02, 0x03, 0x00, 0x00, 0x01, 0x01};
+const u8 gUnknown_083755FD[] = {0x04, 0x04, 0x05, 0x06, 0x07, 0x04, 0x04, 0x05, 0x05};
+const u8 gUnknown_08375606[] = {0x08, 0x08, 0x09, 0x0A, 0x0B, 0x08, 0x08, 0x09, 0x09};
+const u8 gUnknown_0837560F[] = {0x0C, 0x0C, 0x0D, 0x0E, 0x0F, 0x0C, 0x0C, 0x0D, 0x0D};
+const u8 gUnknown_08375618[] = {0x10, 0x10, 0x11, 0x12, 0x13, 0x10, 0x10, 0x11, 0x11};
+const u8 gUnknown_08375621[] = {0x14, 0x14, 0x15, 0x16, 0x17, 0x14, 0x14, 0x15, 0x15};
+const u8 gUnknown_0837562A[] = {0x14, 0x14, 0x15, 0x16, 0x17, 0x14, 0x14, 0x15, 0x15};
+const u8 gUnknown_08375633[] = {0x18, 0x18, 0x19, 0x1A, 0x1B, 0x18, 0x18, 0x19, 0x19};
+const u8 gUnknown_0837563C[] = {0x1C, 0x1C, 0x1D, 0x1E, 0x1F, 0x1C, 0x1C, 0x1D, 0x1D};
+const u8 gUnknown_08375645[] = {0x20, 0x20, 0x21, 0x22, 0x23, 0x20, 0x20, 0x21, 0x21};
+const u8 gUnknown_0837564E[] = {0x24, 0x24, 0x25, 0x26, 0x27, 0x24, 0x24, 0x25, 0x25};
+const u8 gUnknown_08375657[] = {0x00, 0x00, 0x01, 0x02, 0x03, 0x00, 0x00, 0x01, 0x01};
+const u8 gUnknown_08375660[] = {0x04, 0x04, 0x05, 0x06, 0x07, 0x04, 0x04, 0x05, 0x05};
+const u8 gUnknown_08375669[] = {0x08, 0x08, 0x09, 0x0A, 0x0B, 0x08, 0x08, 0x09, 0x09};
+const u8 gUnknown_08375672[] = {0x14, 0x14, 0x15, 0x16, 0x17, 0x14, 0x14, 0x15, 0x15};
+const u8 gUnknown_0837567B[] = {0x08, 0x08, 0x07, 0x09, 0x0A, 0x08, 0x08, 0x07, 0x07};
+
+bool8 (*const gUnknown_08375684[])(u8) = {
+ MetatileBehavior_IsSouthBlocked,
+ MetatileBehavior_IsNorthBlocked,
+ MetatileBehavior_IsWestBlocked,
+ MetatileBehavior_IsEastBlocked
+};
+
+bool8 (*const gUnknown_08375694[])(u8) = {
+ MetatileBehavior_IsNorthBlocked,
+ MetatileBehavior_IsSouthBlocked,
+ MetatileBehavior_IsEastBlocked,
+ MetatileBehavior_IsWestBlocked
+};
+
+const struct Coords16 gDirectionToVector[] = {
+ { 0, 0},
+ { 0, 1},
+ { 0, -1},
+ {-1, 0},
+ { 1, 0},
+ {-1, 1},
+ { 1, 1},
+ {-1, -1},
+ { 1, -1}
+};
+
+const u8 gUnknown_083756C8[] = {0x00, 0x00, 0x01, 0x02, 0x03};
+const u8 gUnknown_083756CD[] = {0x04, 0x04, 0x05, 0x06, 0x07};
+const u8 gUnknown_083756D2[] = {0x08, 0x08, 0x09, 0x0A, 0x0B};
+const u8 gUnknown_083756D7[] = {0x15, 0x15, 0x16, 0x17, 0x18};
+const u8 gUnknown_083756DC[] = {0x29, 0x29, 0x2A, 0x2B, 0x2C};
+const u8 gUnknown_083756E1[] = {0x2D, 0x2D, 0x2E, 0x2F, 0x30};
+const u8 gUnknown_083756E6[] = {0x31, 0x31, 0x32, 0x33, 0x34};
+const u8 gUnknown_083756EB[] = {0x35, 0x35, 0x36, 0x37, 0x38};
+const u8 gUnknown_083756F0[] = {0x0C, 0x0C, 0x0D, 0x0E, 0x0F};
+const u8 gUnknown_083756F5[] = {0x46, 0x46, 0x47, 0x48, 0x49};
+const u8 gUnknown_083756FA[] = {0x4B, 0x4B, 0x4A, 0x4D, 0x4C};
+const u8 gUnknown_083756FF[] = {0x42, 0x42, 0x43, 0x44, 0x45};
+const u8 gUnknown_08375704[] = {0x3A, 0x3A, 0x3B, 0x3C, 0x3D};
+const u8 gUnknown_08375709[] = {0x19, 0x19, 0x1A, 0x1B, 0x1C};
+const u8 gUnknown_0837570E[] = {0x1D, 0x1D, 0x1E, 0x1F, 0x20};
+const u8 gUnknown_08375713[] = {0x21, 0x21, 0x22, 0x23, 0x24};
+const u8 gUnknown_08375718[] = {0x25, 0x25, 0x26, 0x27, 0x28};
+const u8 gUnknown_0837571D[] = {0x62, 0x62, 0x63, 0x64, 0x65};
+const u8 gUnknown_08375722[] = {0x66, 0x66, 0x67, 0x68, 0x69};
+const u8 gUnknown_08375727[] = {0x6A, 0x6A, 0x6B, 0x6C, 0x6D};
+const u8 gUnknown_0837572C[] = {0x6E, 0x6E, 0x6F, 0x70, 0x71};
+const u8 gUnknown_08375731[] = {0x72, 0x72, 0x73, 0x74, 0x75};
+const u8 gUnknown_08375736[] = {0x76, 0x76, 0x77, 0x78, 0x79};
+const u8 gUnknown_0837573B[] = {0x7A, 0x7A, 0x7B, 0x7C, 0x7D};
+const u8 gUnknown_08375740[] = {0x7E, 0x7E, 0x7F, 0x80, 0x81};
+const u8 gUnknown_08375745[] = {0x82, 0x82, 0x83, 0x84, 0x85};
+const u8 gUnknown_0837574A[] = {0x86, 0x86, 0x87, 0x88, 0x89};
+
+const u8 gUnknown_0837574F[] = {2, 1, 4, 3, 8, 7, 6, 5};
+
+const u8 gUnknown_08375757[][4] = {
+ {2, 1, 4, 3},
+ {1, 2, 3, 4},
+ {3, 4, 2, 1},
+ {4, 3, 1, 2}
+};
+
+const u8 gUnknown_08375767[][4] = {
+ {2, 1, 4, 3},
+ {1, 2, 3, 4},
+ {4, 3, 1, 2},
+ {3, 4, 2, 1}
+};
+
+#include "data/field_map_obj/anim_func_ptrs.h"
+
+// text
+
+extern void strange_npc_table_clear(void);
+extern void ClearPlayerAvatarInfo(void);
+extern void npc_load_two_palettes__no_record(u16, u8);
+extern void npc_load_two_palettes__and_record(u16, u8);
+extern void sub_8060388(s16, s16, s16 *, s16 *);
+void sub_80634D0(struct MapObject *, struct Sprite *);
+extern void pal_patch_for_npc(u16, u16);
+extern void CameraObjectReset1(void);
+
+extern struct LinkPlayerMapObject gLinkPlayerMapObjects[];
+extern u8 gReservedSpritePaletteCount;
+extern struct Camera gCamera;
+
+static u8 gUnknown_030005A4;
+static u16 gUnknown_030005A6;
+
+struct MapObject gMapObjects[16];
+
+void npc_clear_ids_and_state(struct MapObject *mapObj)
+{
+ memset(mapObj, 0, sizeof(struct MapObject));
+ mapObj->localId = 0xFF;
+ mapObj->mapNum = 0xFF;
+ mapObj->mapGroup = 0xFF;
+ mapObj->mapobj_unk_1C = 0xFF;
+}
+
+void npcs_clear_ids_and_state(void)
+{
+ u8 i;
+
+ for (i = 0; i < 16; i++)
+ npc_clear_ids_and_state(&gMapObjects[i]);
+}
+
+void sub_805AA98(void)
+{
+ strange_npc_table_clear();
+ npcs_clear_ids_and_state();
+ ClearPlayerAvatarInfo();
+ sub_805AAB0();
+}
+
+void sub_805AAB0(void)
+{
+ u8 spriteId;
+
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[21], 0, 0, 0x1F);
+
+ gSprites[spriteId].oam.affineMode = 1;
+ InitSpriteAffineAnim(&gSprites[spriteId]);
+ StartSpriteAffineAnim(&gSprites[spriteId], 0);
+ gSprites[spriteId].invisible = 1;
+
+ spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[21], 0, 0, 0x1F);
+
+ gSprites[spriteId].oam.affineMode = 1;
+ InitSpriteAffineAnim(&gSprites[spriteId]);
+ StartSpriteAffineAnim(&gSprites[spriteId], 1);
+ gSprites[spriteId].invisible = 1;
+}
+
+u8 sub_805AB54(void)
+{
+ u8 i;
+
+ for (i = 0; i < 16; i++)
+ {
+ if (!gMapObjects[i].active)
+ break;
+ }
+ return i;
+}
+
+u8 GetFieldObjectIdByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup)
+{
+ if (localId <= 0xFE)
+ return GetFieldObjectIdByLocalIdAndMapInternal(localId, mapNum, mapGroup);
+ else
+ return GetFieldObjectIdByLocalId(localId);
+}
+
+bool8 TryGetFieldObjectIdByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup, u8 *mapObjectId)
+{
+ *mapObjectId = GetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup);
+ if (*mapObjectId == 16)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+u8 GetFieldObjectIdByXY(s16 x, s16 y)
+{
+ u8 i;
+
+ for (i = 0; i < 16; i++)
+ {
+ if (gMapObjects[i].active && gMapObjects[i].coords2.x == x && gMapObjects[i].coords2.y == y)
+ break;
+ }
+ return i;
+}
+
+u8 GetFieldObjectIdByLocalIdAndMapInternal(u8 localId, u8 mapNum, u8 mapGroup)
+{
+ u8 i;
+
+ for (i = 0; i < 16; i++)
+ {
+ if (gMapObjects[i].active && gMapObjects[i].localId == localId && gMapObjects[i].mapNum == mapNum && gMapObjects[i].mapGroup == mapGroup)
+ return i;
+ }
+ return 16;
+}
+
+u8 GetFieldObjectIdByLocalId(u8 localId)
+{
+ u8 i;
+
+ for (i = 0; i < 16; i++)
+ {
+ if (gMapObjects[i].active && gMapObjects[i].localId == localId)
+ return i;
+ }
+ return 16;
+}
+
+#ifdef NONMATCHING
+u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u8 b, u8 c)
+{
+ struct MapObject2 *mapObj; //TODO: resolve the mapobj_unk_19b weirdness
+ u8 var;
+ u16 r3;
+ u16 r2;
+
+ //asm("nop"::"r"(b));
+ if (GetAvailableFieldObjectSlot(template->localId, b, c, &var) != 0)
+ return 16;
+ //_0805ACCE
+ mapObj = (struct MapObject2 *)&gMapObjects[var];
+ npc_clear_ids_and_state((struct MapObject *)mapObj);
+ r3 = template->x + 7;
+ r2 = template->y + 7;
+ mapObj->active = TRUE;
+ mapObj->mapobj_bit_2 = TRUE;
+ mapObj->graphicsId = template->graphicsId;
+ mapObj->animPattern = template->movementType;
+ mapObj->localId = template->localId;
+ mapObj->mapNum = b;
+ mapObj->mapGroup = c;
+ mapObj->coords1.x = r3;
+ mapObj->coords1.y = r2;
+ mapObj->coords2.x = r3;
+ mapObj->coords2.y = r2;
+ mapObj->coords3.x = r3;
+ mapObj->coords3.y = r2;
+ mapObj->mapobj_unk_0B_0 = template->elevation;
+ mapObj->elevation = template->elevation;
+ mapObj->mapobj_unk_19 = template->unkA_0;
+ mapObj->mapobj_unk_19b = template->unkA_4;
+ mapObj->trainerType = template->unkC;
+ mapObj->trainerRange_berryTreeId = template->unkE;
+ mapObj->mapobj_unk_20 = gUnknown_0836DC09[template->movementType];
+ FieldObjectSetDirection((struct MapObject *)mapObj, mapObj->mapobj_unk_20);
+ FieldObjectHandleDynamicGraphicsId(mapObj);
+ //asm("":::"r5","r6");
+ if (gUnknown_0836DBBC[mapObj->animPattern] != 0)
+ {
+ if (mapObj->mapobj_unk_19 == 0)
+ mapObj->mapobj_unk_19++;
+ if (mapObj->mapobj_unk_19b == 0)
+ mapObj->mapobj_unk_19b++;
+ }
+ return var;
+}
+#else
+__attribute__((naked))
+u8 InitFieldObjectStateFromTemplate(struct MapObjectTemplate *template, u8 b, u8 c)
+{
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ mov r7, r9\n\
+ mov r6, r8\n\
+ push {r6,r7}\n\
+ sub sp, 0x4\n\
+ adds r5, r0, 0\n\
+ lsls r1, 24\n\
+ lsrs r6, r1, 24\n\
+ lsls r2, 24\n\
+ lsrs r7, r2, 24\n\
+ ldrb r0, [r5]\n\
+ adds r1, r6, 0\n\
+ adds r2, r7, 0\n\
+ mov r3, sp\n\
+ bl GetAvailableFieldObjectSlot\n\
+ lsls r0, 24\n\
+ cmp r0, 0\n\
+ beq _0805ACCE\n\
+ movs r0, 0x10\n\
+ b _0805ADC2\n\
+_0805ACCE:\n\
+ mov r0, sp\n\
+ ldrb r1, [r0]\n\
+ lsls r0, r1, 3\n\
+ adds r0, r1\n\
+ lsls r0, 2\n\
+ ldr r1, _0805ADD0 @ =gMapObjects\n\
+ adds r4, r0, r1\n\
+ adds r0, r4, 0\n\
+ bl npc_clear_ids_and_state\n\
+ ldrh r3, [r5, 0x4]\n\
+ adds r3, 0x7\n\
+ lsls r3, 16\n\
+ lsrs r3, 16\n\
+ ldrh r2, [r5, 0x6]\n\
+ adds r2, 0x7\n\
+ lsls r2, 16\n\
+ lsrs r2, 16\n\
+ ldrb r0, [r4]\n\
+ movs r1, 0x1\n\
+ orrs r0, r1\n\
+ movs r1, 0x4\n\
+ orrs r0, r1\n\
+ strb r0, [r4]\n\
+ ldrb r0, [r5, 0x1]\n\
+ strb r0, [r4, 0x5]\n\
+ ldrb r0, [r5, 0x9]\n\
+ strb r0, [r4, 0x6]\n\
+ ldrb r0, [r5]\n\
+ strb r0, [r4, 0x8]\n\
+ strb r6, [r4, 0x9]\n\
+ strb r7, [r4, 0xA]\n\
+ strh r3, [r4, 0xC]\n\
+ strh r2, [r4, 0xE]\n\
+ strh r3, [r4, 0x10]\n\
+ strh r2, [r4, 0x12]\n\
+ strh r3, [r4, 0x14]\n\
+ strh r2, [r4, 0x16]\n\
+ ldrb r0, [r5, 0x8]\n\
+ movs r7, 0xF\n\
+ adds r1, r7, 0\n\
+ ands r1, r0\n\
+ ldrb r2, [r4, 0xB]\n\
+ movs r0, 0x10\n\
+ negs r0, r0\n\
+ mov r8, r0\n\
+ ands r0, r2\n\
+ orrs r0, r1\n\
+ strb r0, [r4, 0xB]\n\
+ ldrb r1, [r5, 0x8]\n\
+ lsls r1, 4\n\
+ ands r0, r7\n\
+ orrs r0, r1\n\
+ strb r0, [r4, 0xB]\n\
+ ldrb r1, [r5, 0xA]\n\
+ lsls r1, 28\n\
+ movs r0, 0xF\n\
+ mov r9, r0\n\
+ lsrs r1, 28\n\
+ ldrb r2, [r4, 0x19]\n\
+ mov r0, r8\n\
+ ands r0, r2\n\
+ orrs r0, r1\n\
+ strb r0, [r4, 0x19]\n\
+ ldrb r1, [r5, 0xA]\n\
+ lsrs r1, 4\n\
+ lsls r1, 4\n\
+ ands r0, r7\n\
+ orrs r0, r1\n\
+ strb r0, [r4, 0x19]\n\
+ ldrh r0, [r5, 0xC]\n\
+ strb r0, [r4, 0x7]\n\
+ ldrh r0, [r5, 0xE]\n\
+ strb r0, [r4, 0x1D]\n\
+ ldr r1, _0805ADD4 @ =gUnknown_0836DC09\n\
+ ldrb r0, [r5, 0x9]\n\
+ adds r0, r1\n\
+ ldrb r1, [r0]\n\
+ adds r0, r4, 0\n\
+ adds r0, 0x20\n\
+ strb r1, [r0]\n\
+ ldrb r1, [r0]\n\
+ adds r0, r4, 0\n\
+ bl FieldObjectSetDirection\n\
+ adds r0, r4, 0\n\
+ bl FieldObjectHandleDynamicGraphicsId\n\
+ ldr r1, _0805ADD8 @ =gUnknown_0836DBBC\n\
+ ldrb r0, [r4, 0x6]\n\
+ adds r0, r1\n\
+ ldrb r0, [r0]\n\
+ cmp r0, 0\n\
+ beq _0805ADBE\n\
+ ldrb r2, [r4, 0x19]\n\
+ adds r0, r7, 0\n\
+ ands r0, r2\n\
+ cmp r0, 0\n\
+ bne _0805ADA6\n\
+ lsls r0, r2, 28\n\
+ lsrs r0, 28\n\
+ adds r0, 0x1\n\
+ mov r1, r9\n\
+ ands r0, r1\n\
+ mov r1, r8\n\
+ ands r1, r2\n\
+ orrs r1, r0\n\
+ strb r1, [r4, 0x19]\n\
+_0805ADA6:\n\
+ ldrb r2, [r4, 0x19]\n\
+ movs r0, 0xF0\n\
+ ands r0, r2\n\
+ cmp r0, 0\n\
+ bne _0805ADBE\n\
+ lsrs r1, r2, 4\n\
+ adds r1, 0x1\n\
+ lsls r1, 4\n\
+ adds r0, r7, 0\n\
+ ands r0, r2\n\
+ orrs r0, r1\n\
+ strb r0, [r4, 0x19]\n\
+_0805ADBE:\n\
+ mov r0, sp\n\
+ ldrb r0, [r0]\n\
+_0805ADC2:\n\
+ add sp, 0x4\n\
+ pop {r3,r4}\n\
+ mov r8, r3\n\
+ mov r9, r4\n\
+ pop {r4-r7}\n\
+ pop {r1}\n\
+ bx r1\n\
+ .align 2, 0\n\
+_0805ADD0: .4byte gMapObjects\n\
+_0805ADD4: .4byte gUnknown_0836DC09\n\
+_0805ADD8: .4byte gUnknown_0836DBBC\n\
+ .syntax divided\n");
+}
+#endif
+
+u8 sub_805ADDC(u8 localId)
+{
+ u8 objectCount;
+ u8 i;
+
+ if (gMapHeader.events == NULL)
+ return 16;
+ objectCount = gMapHeader.events->mapObjectCount;
+ for (i = 0; i < objectCount; i++)
+ {
+ struct MapObjectTemplate *template = &gSaveBlock1.mapObjectTemplates[i];
+
+ if (template->localId == localId && !FlagGet(template->flagId))
+ return InitFieldObjectStateFromTemplate(template, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup);
+ }
+ return 16;
+}
+
+u8 GetAvailableFieldObjectSlot(u16 a, u8 b, u8 c, u8 *d)
+{
+ u8 i = 0;
+
+ for (i = 0; i < 16 && gMapObjects[i].active; i++)
+ {
+ if (gMapObjects[i].localId == a && gMapObjects[i].mapNum == b && gMapObjects[i].mapGroup == c)
+ return 1;
+ }
+ if (i >= 16)
+ return 1;
+ *d = i;
+ for (; i < 16; i++)
+ {
+ if (gMapObjects[i].active && gMapObjects[i].localId == a && gMapObjects[i].mapNum == b && gMapObjects[i].mapGroup == c)
+ return 1;
+ }
+ return 0;
+}
+
+void RemoveFieldObject(struct MapObject *mapObject)
+{
+ mapObject->active = FALSE;
+ RemoveFieldObjectInternal(mapObject);
+}
+
+void RemoveFieldObjectByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup)
+{
+ u8 mapObjectId;
+
+ if (TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId))
+ return;
+ FlagSet(GetFieldObjectFlagIdByFieldObjectId(mapObjectId));
+ RemoveFieldObject(&gMapObjects[mapObjectId]);
+}
+
+void RemoveFieldObjectInternal(struct MapObject *mapObject)
+{
+ struct SpriteFrameImage image;
+ const struct MapObjectGraphicsInfo *gfxInfo = GetFieldObjectGraphicsInfo(mapObject->graphicsId);
+
+ image.size = gfxInfo->size;
+ gSprites[mapObject->spriteId].images = &image;
+ DestroySprite(&gSprites[mapObject->spriteId]);
+}
+
+void npc_hide_all_but_player(void)
+{
+ u8 i;
+
+ for (i = 0; i < 16; i++)
+ {
+ if (i != gPlayerAvatar.mapObjectId)
+ RemoveFieldObject(&gMapObjects[i]);
+ }
+}
+
+u8 sub_805AFCC(struct MapObjectTemplate *mapObjTemplate, struct SpriteTemplate *sprTemplate, u8 c, u8 d, s16 e, s16 f)
+{
+ u8 mapObjectId;
+ u8 spriteId;
+ const struct MapObjectGraphicsInfo *gfxInfo;
+ struct MapObject *mapObject;
+ struct Sprite *sprite;
+
+ mapObjectId = InitFieldObjectStateFromTemplate(mapObjTemplate, c, d);
+ if (mapObjectId == 16)
+ return 16;
+
+ mapObject = &gMapObjects[mapObjectId];
+ gfxInfo = GetFieldObjectGraphicsInfo(mapObject->graphicsId);
+ if (gfxInfo->paletteSlot == 0)
+ npc_load_two_palettes__no_record(gfxInfo->paletteTag1, gfxInfo->paletteSlot);
+ else if (gfxInfo->paletteSlot == 10)
+ npc_load_two_palettes__and_record(gfxInfo->paletteTag1, gfxInfo->paletteSlot);
+ if (mapObject->animPattern == 0x4C)
+ mapObject->mapobj_bit_13 = TRUE;
+
+#ifdef NONMATCHING
+ sprTemplate->paletteTag = 0xFFFF;
+#else
+ *(u16 *)&sprTemplate->paletteTag = 0xFFFF;
+#endif
+ spriteId = CreateSprite(sprTemplate, 0, 0, 0);
+ if (spriteId == 64)
+ {
+ gMapObjects[mapObjectId].active = FALSE;
+ return 16;
+ }
+ sprite = &gSprites[spriteId];
+ sub_8060388(e + mapObject->coords2.x, f + mapObject->coords2.y, &sprite->pos1.x, &sprite->pos1.y);
+ sprite->centerToCornerVecX = -(gfxInfo->width >> 1);
+ sprite->centerToCornerVecY = -(gfxInfo->height >> 1);
+ sprite->pos1.x += 8;
+ sprite->pos1.y += 16 + sprite->centerToCornerVecY;
+ sprite->oam.paletteNum = gfxInfo->paletteSlot;
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->data0 = mapObjectId;
+ mapObject->spriteId = spriteId;
+ mapObject->mapobj_bit_12 = gfxInfo->inanimate;
+ if (!mapObject->mapobj_bit_12)
+ StartSpriteAnim(sprite, FieldObjectDirectionToImageAnimId(mapObject->mapobj_unk_18));
+ SetObjectSubpriorityByZCoord(mapObject->elevation, sprite, 1);
+ sub_80634D0(mapObject, sprite);
+ return mapObjectId;
+}
+
+u8 SpawnFieldObject(struct MapObjectTemplate *mapObjTemplate, u8 b, u8 c, s16 d, s16 e)
+{
+ struct SpriteTemplate spriteTemplate;
+ const struct SubspriteTable *subspriteTables = NULL;
+ struct SpriteFrameImage spriteFrameImage;
+ const struct MapObjectGraphicsInfo *gfxInfo;
+ u8 mapObjectId;
+
+ gfxInfo = GetFieldObjectGraphicsInfo(mapObjTemplate->graphicsId);
+ MakeObjectTemplateFromFieldObjectTemplate(mapObjTemplate, &spriteTemplate, &subspriteTables);
+ spriteFrameImage.size = gfxInfo->size;
+ spriteTemplate.images = &spriteFrameImage;
+ mapObjectId = sub_805AFCC(mapObjTemplate, &spriteTemplate, b, c, d, e);
+ if (mapObjectId == 16)
+ return 16;
+ gSprites[gMapObjects[mapObjectId].spriteId].images = gfxInfo->images;
+ if (subspriteTables != NULL)
+ SetSubspriteTables(&gSprites[gMapObjects[mapObjectId].spriteId], subspriteTables);
+ return mapObjectId;
+}
+
+u8 SpawnSpecialFieldObject(struct MapObjectTemplate *mapObjTemplate)
+{
+ s16 x;
+ s16 y;
+
+ GetFieldObjectMovingCameraOffset(&x, &y);
+ return SpawnFieldObject(mapObjTemplate, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup, x, y);
+}
+
+u8 SpawnSpecialFieldObjectParametrized(u8 a, u8 b, u8 c, s16 d, s16 e, u8 f)
+{
+ struct MapObjectTemplate mapObjTemplate;
+
+ d -= 7;
+ e -= 7;
+ mapObjTemplate.localId = c;
+ mapObjTemplate.graphicsId = a;
+ mapObjTemplate.unk2 = 0;
+ mapObjTemplate.x = d;
+ mapObjTemplate.y = e;
+ mapObjTemplate.elevation = f;
+ mapObjTemplate.movementType = b;
+ mapObjTemplate.unkA_0 = 0;
+ mapObjTemplate.unkA_4 = 0;
+ mapObjTemplate.unkC = 0;
+ mapObjTemplate.unkE = 0;
+ return SpawnSpecialFieldObject(&mapObjTemplate);
+}
+
+u8 show_sprite(u8 a, u8 b, u8 c)
+{
+ struct MapObjectTemplate *r5;
+ s16 x;
+ s16 y;
+
+ r5 = GetFieldObjectTemplateByLocalIdAndMap(a, b, c);
+ if (r5 == NULL)
+ return 16;
+ GetFieldObjectMovingCameraOffset(&x, &y);
+ return SpawnFieldObject(r5, b, c, x, y);
+}
+
+void MakeObjectTemplateFromFieldObjectGraphicsInfo(u16 graphicsId, void (*callback)(struct Sprite *), struct SpriteTemplate *sprTemplate, const struct SubspriteTable **subspriteTables)
+{
+ const struct MapObjectGraphicsInfo *gfxInfo = GetFieldObjectGraphicsInfo(graphicsId);
+
+ sprTemplate->tileTag = gfxInfo->tileTag;
+ sprTemplate->paletteTag = gfxInfo->paletteTag1;
+ sprTemplate->oam = gfxInfo->oam;
+ sprTemplate->anims = gfxInfo->anims;
+ sprTemplate->images = gfxInfo->images;
+ sprTemplate->affineAnims = gfxInfo->affineAnims;
+ sprTemplate->callback = callback;
+ *subspriteTables = gfxInfo->subspriteTables;
+}
+
+void MakeObjectTemplateFromFieldObjectGraphicsInfoWithCallbackIndex(u16 graphicsId, u16 callbackIndex, struct SpriteTemplate *sprTemplate, const struct SubspriteTable **subspriteTables)
+{
+ MakeObjectTemplateFromFieldObjectGraphicsInfo(graphicsId, gUnknown_0836DA88[callbackIndex], sprTemplate, subspriteTables);
+}
+
+void MakeObjectTemplateFromFieldObjectTemplate(struct MapObjectTemplate *mapObjTemplate, struct SpriteTemplate *sprTemplate, const struct SubspriteTable **subspriteTables)
+{
+ MakeObjectTemplateFromFieldObjectGraphicsInfoWithCallbackIndex(mapObjTemplate->graphicsId, mapObjTemplate->movementType, sprTemplate, subspriteTables);
+}
+
+u8 AddPseudoFieldObject(u16 graphicsId, void (*callback)(struct Sprite *), s16 c, s16 d, u8 subpriority)
+{
+ struct SpriteTemplate spriteTemplate;
+ const struct SubspriteTable *subspriteTables;
+ u8 spriteId;
+
+ MakeObjectTemplateFromFieldObjectGraphicsInfo(graphicsId, callback, &spriteTemplate, &subspriteTables);
+ if (spriteTemplate.paletteTag != 0xFFFF)
+ sub_805BDF8(spriteTemplate.paletteTag);
+ spriteId = CreateSprite(&spriteTemplate, c, d, subpriority);
+ if (spriteId != 64 && subspriteTables != NULL)
+ {
+ SetSubspriteTables(&gSprites[spriteId], subspriteTables);
+ gSprites[spriteId].subspriteMode = 2;
+ }
+ return spriteId;
+}
+
+extern void sub_8064970(struct Sprite *);
+extern void sub_8060470(s16 *, s16 *, s16, s16);
+extern void InitObjectPriorityByZCoord();
+
+u8 sub_805B410(u8 graphicsId, u8 b, s16 x, s16 y, u8 elevation, u8 direction)
+{
+ const struct MapObjectGraphicsInfo *gfxInfo;
+ struct SpriteTemplate spriteTemplate;
+ const struct SubspriteTable *subspriteTables;
+ u8 spriteId;
+
+ gfxInfo = GetFieldObjectGraphicsInfo(graphicsId);
+ MakeObjectTemplateFromFieldObjectGraphicsInfo(graphicsId, sub_8064970, &spriteTemplate, &subspriteTables);
+#ifdef NONMATCHING
+ spriteTemplate.paletteTag = 0xFFFF;
+#else
+ *(u16 *)&spriteTemplate.paletteTag = 0xFFFF;
+#endif
+ x += 7;
+ y += 7;
+ sub_8060470(&x, &y, 8, 16);
+ spriteId = CreateSpriteAtEnd(&spriteTemplate, x, y, 0);
+ if (spriteId != 64)
+ {
+ struct Sprite *sprite = &gSprites[spriteId];
+
+ sprite->centerToCornerVecX = -(gfxInfo->width >> 1);
+ sprite->centerToCornerVecY = -(gfxInfo->height >> 1);
+ sprite->pos1.y += sprite->centerToCornerVecY;
+ sprite->oam.paletteNum = gfxInfo->paletteSlot;
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->data0 = b;
+ sprite->data1 = elevation;
+ if (gfxInfo->paletteSlot == 10)
+ npc_load_two_palettes__and_record(gfxInfo->paletteTag1, gfxInfo->paletteSlot);
+ if (subspriteTables != NULL)
+ {
+ SetSubspriteTables(sprite, subspriteTables);
+ sprite->subspriteMode = 2;
+ }
+ InitObjectPriorityByZCoord(sprite, elevation);
+ SetObjectSubpriorityByZCoord(elevation, sprite, 1);
+ StartSpriteAnim(sprite, FieldObjectDirectionToImageAnimId(direction));
+ }
+ return spriteId;
+}
+
+void sub_805B55C(s16 a, s16 b)
+{
+ u8 i;
+
+ if (gMapHeader.events != NULL)
+ {
+ s16 r9 = gSaveBlock1.pos.x - 2;
+ s16 sp8 = gSaveBlock1.pos.x + 17;
+ s16 r10 = gSaveBlock1.pos.y;
+ s16 spC = gSaveBlock1.pos.y + 16;
+ u8 objectCount = gMapHeader.events->mapObjectCount;
+
+ for (i = 0; i < objectCount; i++)
+ {
+ struct MapObjectTemplate *template = &gSaveBlock1.mapObjectTemplates[i];
+ s16 foo = template->x + 7;
+ s16 bar = template->y + 7;
+
+ if (r10 <= bar && spC >= bar && r9 <= foo && sp8 >= foo
+ && !FlagGet(template->flagId))
+ SpawnFieldObject(template, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup, a, b);
+ }
+ }
+}
+
+void RemoveFieldObjectIfOutsideView(struct MapObject *mapObject);
+
+void RemoveFieldObjectsOutsideView(void)
+{
+ u8 i;
+ u8 j;
+
+ for (i = 0; i < 16; i++)
+ {
+ bool8 isActiveLinkPlayer;
+
+ for (j = 0, isActiveLinkPlayer = 0; j < 4; j++)
+ {
+ if (gLinkPlayerMapObjects[j].active && i == gLinkPlayerMapObjects[j].mapObjId)
+ isActiveLinkPlayer = TRUE;
+ }
+ if (!isActiveLinkPlayer)
+ {
+ struct MapObject *mapObject = &gMapObjects[i];
+
+ if (mapObject->active && !mapObject->mapobj_bit_16)
+ RemoveFieldObjectIfOutsideView(mapObject);
+ }
+ }
+}
+
+void RemoveFieldObjectIfOutsideView(struct MapObject *mapObject)
+{
+ s16 r7 = gSaveBlock1.pos.x - 2;
+ s16 r5 = gSaveBlock1.pos.x + 17;
+ s16 r4 = gSaveBlock1.pos.y;
+ s16 r6 = gSaveBlock1.pos.y + 16;
+
+ if (mapObject->coords2.x >= r7 && mapObject->coords2.x <= r5
+ && mapObject->coords2.y >= r4 && mapObject->coords2.y <= r6)
+ return;
+ if (mapObject->coords1.x >= r7 && mapObject->coords1.x <= r5
+ && mapObject->coords1.y >= r4 && mapObject->coords1.y <= r6)
+ return;
+ RemoveFieldObject(mapObject);
+}
+
+void sub_805B75C(u8, s16, s16);
+
+void sub_805B710(u16 a, u16 b)
+{
+ u8 i;
+
+ ClearPlayerAvatarInfo();
+ for (i = 0; i < 16; i++)
+ {
+ if (gMapObjects[i].active)
+ sub_805B75C(i, a, b);
+ }
+ sub_805AAB0();
+}
+
+extern void SetPlayerAvatarFieldObjectIdAndObjectId(u8, u8);
+extern void sub_805B914(struct MapObject *);
+
+void sub_805B75C(u8 a, s16 b, s16 c)
+{
+ struct SpriteTemplate sp0;
+ struct SpriteFrameImage sp18;
+ const struct SubspriteTable *subspriteTables;
+ const struct MapObjectGraphicsInfo *gfxInfo;
+ struct MapObject *mapObject;
+ u8 spriteId;
+
+ #define i spriteId
+ for (i = 0; i < 4; i++)
+ {
+ if (gLinkPlayerMapObjects[i].active && a == gLinkPlayerMapObjects[i].mapObjId)
+ return;
+ }
+ #undef i
+
+ mapObject = &gMapObjects[a];
+ asm("":::"r5");
+ subspriteTables = NULL;
+ gfxInfo = GetFieldObjectGraphicsInfo(mapObject->graphicsId);
+ sp18.size = gfxInfo->size;
+ MakeObjectTemplateFromFieldObjectGraphicsInfoWithCallbackIndex(mapObject->graphicsId, mapObject->animPattern, &sp0, &subspriteTables);
+ sp0.images = &sp18;
+ *(u16 *)&sp0.paletteTag = 0xFFFF;
+ if (gfxInfo->paletteSlot == 0)
+ npc_load_two_palettes__no_record(gfxInfo->paletteTag1, gfxInfo->paletteSlot);
+ if (gfxInfo->paletteSlot > 9)
+ npc_load_two_palettes__and_record(gfxInfo->paletteTag1, gfxInfo->paletteSlot);
+ *(u16 *)&sp0.paletteTag = 0xFFFF;
+ spriteId = CreateSprite(&sp0, 0, 0, 0);
+ if (spriteId != 64)
+ {
+ struct Sprite *sprite = &gSprites[spriteId];
+
+ sub_8060388(b + mapObject->coords2.x, c + mapObject->coords2.y, &sprite->pos1.x, &sprite->pos1.y);
+ sprite->centerToCornerVecX = -(gfxInfo->width >> 1);
+ sprite->centerToCornerVecY = -(gfxInfo->height >> 1);
+ sprite->pos1.x += 8;
+ sprite->pos1.y += 16 + sprite->centerToCornerVecY;
+ sprite->images = gfxInfo->images;
+ if (mapObject->animPattern == 11)
+ {
+ SetPlayerAvatarFieldObjectIdAndObjectId(a, spriteId);
+ mapObject->mapobj_unk_1B = sub_8126B54();
+ }
+ if (subspriteTables != NULL)
+ SetSubspriteTables(sprite, subspriteTables);
+ sprite->oam.paletteNum = gfxInfo->paletteSlot;
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->data0 = a;
+ mapObject->spriteId = spriteId;
+ if (!mapObject->mapobj_bit_12 && mapObject->animPattern != 11)
+ StartSpriteAnim(sprite, FieldObjectDirectionToImageAnimId(mapObject->mapobj_unk_18));
+ sub_805B914(mapObject);
+ SetObjectSubpriorityByZCoord(mapObject->elevation, sprite, 1);
+ }
+}
+
+void sub_805B914(struct MapObject *mapObject)
+{
+ mapObject->mapobj_bit_1 = FALSE;
+ mapObject->mapobj_bit_2 = TRUE;
+ mapObject->mapobj_bit_22 = FALSE;
+ mapObject->mapobj_bit_17 = FALSE;
+ mapObject->mapobj_bit_18 = FALSE;
+ mapObject->mapobj_bit_19 = FALSE;
+ mapObject->mapobj_bit_20 = FALSE;
+ mapObject->mapobj_bit_21 = FALSE;
+ FieldObjectClearAnim(mapObject);
+}
+
+void SetPlayerAvatarFieldObjectIdAndObjectId(u8 mapObjectId, u8 spriteId)
+{
+ gPlayerAvatar.mapObjectId = mapObjectId;
+ gPlayerAvatar.spriteId = spriteId;
+ gPlayerAvatar.gender = GetPlayerAvatarGenderByGraphicsId(gMapObjects[mapObjectId].graphicsId);
+ SetPlayerAvatarExtraStateTransition(gMapObjects[mapObjectId].graphicsId, 0x20);
+}
+
+void sub_805B980(struct MapObject *mapObject, u8 graphicsId)
+{
+ const struct MapObjectGraphicsInfo *gfxInfo;
+ struct Sprite *sprite;
+
+ gfxInfo = GetFieldObjectGraphicsInfo(graphicsId);
+ sprite = &gSprites[mapObject->spriteId];
+ if (gfxInfo->paletteSlot == 0)
+ pal_patch_for_npc(gfxInfo->paletteTag1, gfxInfo->paletteSlot);
+ if (gfxInfo->paletteSlot == 10)
+ npc_load_two_palettes__and_record(gfxInfo->paletteTag1, gfxInfo->paletteSlot);
+ sprite->oam.shape = gfxInfo->oam->shape;
+ sprite->oam.size = gfxInfo->oam->size;
+ sprite->images = gfxInfo->images;
+ sprite->anims = gfxInfo->anims;
+ sprite->subspriteTables = gfxInfo->subspriteTables;
+ sprite->oam.paletteNum = gfxInfo->paletteSlot;
+ mapObject->mapobj_bit_12 = gfxInfo->inanimate;
+ mapObject->graphicsId = graphicsId;
+ sub_80603CC(mapObject->coords2.x, mapObject->coords2.y, &sprite->pos1.x, &sprite->pos1.y);
+ sprite->centerToCornerVecX = -(gfxInfo->width >> 1);
+ sprite->centerToCornerVecY = -(gfxInfo->height >> 1);
+ sprite->pos1.x += 8;
+ sprite->pos1.y += 16 + sprite->centerToCornerVecY;
+ if (mapObject->mapobj_bit_15)
+ CameraObjectReset1();
+}
+
+void unref_sub_805BA80(u8 localId, u8 mapNum, u8 mapGroup, u8 graphicsId)
+{
+ u8 mapObjectId;
+
+ if (!TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId))
+ sub_805B980(&gMapObjects[mapObjectId], graphicsId);
+}
+
+void FieldObjectTurn(struct MapObject *mapObject, u8 direction)
+{
+ FieldObjectSetDirection(mapObject, direction);
+ if (!mapObject->mapobj_bit_12)
+ {
+ StartSpriteAnim(&gSprites[mapObject->spriteId], FieldObjectDirectionToImageAnimId(mapObject->mapobj_unk_18));
+ SeekSpriteAnim(&gSprites[mapObject->spriteId], 0);
+ }
+}
+
+void FieldObjectTurnByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup, u8 direction)
+{
+ u8 mapObjectId;
+
+ if (!TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId))
+ FieldObjectTurn(&gMapObjects[mapObjectId], direction);
+}
+
+void unref_TurnPlayer(struct PlayerAvatar *player, u8 direction)
+{
+ FieldObjectTurn(&gMapObjects[player->mapObjectId], direction);
+}
+
+void get_berry_tree_graphics(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 treeStage;
+ u8 treeId;
+
+ mapObject->mapobj_bit_13 = TRUE;
+ sprite->invisible = TRUE;
+ treeStage = GetStageByBerryTreeId(mapObject->trainerRange_berryTreeId);
+ if (treeStage != 0)
+ {
+ mapObject->mapobj_bit_13 = FALSE;
+ sprite->invisible = FALSE;
+ treeId = GetBerryTypeByBerryTreeId(mapObject->trainerRange_berryTreeId) - 1;
+ treeStage--;
+ if (treeId > 0x2B)
+ treeId = 0;
+ sub_805B980(mapObject, gBerryTreeGraphicsIdTablePointers[treeId][treeStage]);
+ sprite->images = gBerryTreePicTablePointers[treeId];
+ sprite->oam.paletteNum = gBerryTreePaletteSlotTablePointers[treeId][treeStage];
+ StartSpriteAnim(sprite, treeStage);
+ }
+}
+
+const struct MapObjectGraphicsInfo *GetFieldObjectGraphicsInfo(u8 graphicsId)
+{
+ if (graphicsId > 0xEF)
+ graphicsId = VarGetFieldObjectGraphicsId(graphicsId + 16);
+ if (graphicsId > 0xD9)
+ graphicsId = 5;
+ return gMapObjectGraphicsInfoPointers[graphicsId];
+}
+
+void FieldObjectHandleDynamicGraphicsId(struct MapObject *mapObject)
+{
+ if (mapObject->graphicsId > 0xEF)
+ mapObject->graphicsId = VarGetFieldObjectGraphicsId(mapObject->graphicsId + 16);
+}
+
+void npc_by_local_id_and_map_set_field_1_bit_x20(u8 localId, u8 mapNum, u8 mapGroup, u8 d)
+{
+ u8 mapObjectId;
+
+ if (!TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId))
+ gMapObjects[mapObjectId].mapobj_bit_13 = d;
+}
+
+void FieldObjectGetLocalIdAndMap(struct MapObject *mapObject, u8 *localId, u8 *mapNum, u8 *mapGroup)
+{
+ *localId = mapObject->localId;
+ *mapNum = mapObject->mapNum;
+ *mapGroup = mapObject->mapGroup;
+}
+
+void sub_805BCC0(s16 x, s16 y)
+{
+ u8 mapObjectId;
+ struct MapObject *mapObject;
+
+ mapObjectId = GetFieldObjectIdByXY(x, y);
+ if (mapObjectId != 16)
+ {
+ mapObject = &gMapObjects[mapObjectId];
+ mapObject->mapobj_bit_2 = TRUE;
+ }
+}
+
+void sub_805BCF0(u8 localId, u8 mapNum, u8 mapGroup, u8 subpriority)
+{
+ u8 mapObjectId;
+ struct MapObject *mapObject;
+ struct Sprite *sprite;
+
+ if (!TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId))
+ {
+ mapObject = &gMapObjects[mapObjectId];
+ sprite = &gSprites[mapObject->spriteId];
+ mapObject->mapobj_bit_26 = TRUE;
+ sprite->subpriority = subpriority;
+ }
+}
+
+void sub_805BD48(u8 localId, u8 mapNum, u8 mapGroup)
+{
+ u8 mapObjectId;
+ struct MapObject *mapObject;
+
+ if (!TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId))
+ {
+ mapObject = &gMapObjects[mapObjectId];
+ mapObject->mapobj_bit_26 = FALSE;
+ mapObject->mapobj_bit_2 = TRUE;
+ }
+}
+
+void sub_805BD90(u8 localId, u8 mapNum, u8 mapGroup, s16 x, s16 y)
+{
+ u8 mapObjectId;
+ struct Sprite *sprite;
+
+ if (!TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId))
+ {
+ sprite = &gSprites[gMapObjects[mapObjectId].spriteId];
+ sprite->pos2.x = x;
+ sprite->pos2.y = y;
+ }
+}
+
+void gpu_pal_allocator_reset__manage_upper_four(void)
+{
+ FreeAllSpritePalettes();
+ gReservedSpritePaletteCount = 12;
+}
+
+void sub_805BDF8(u16 tag)
+{
+ u16 paletteIndex = FindFieldObjectPaletteIndexByTag(tag);
+
+ if (paletteIndex != 0x11FF) //always happens. FindFieldObjectPaletteIndexByTag returns u8
+ sub_805BE58(&gUnknown_0837377C[paletteIndex]);
+}
+
+void unref_sub_805BE24(u16 *arr)
+{
+ u8 i;
+
+ for (i = 0; arr[i] != 0x11FF; i++)
+ sub_805BDF8(arr[i]);
+}
+
+u8 sub_805BE58(const struct SpritePalette *palette)
+{
+ if (IndexOfSpritePaletteTag(palette->tag) != 0xFF)
+ return 0xFF;
+ else
+ return LoadSpritePalette(palette);
+}
+
+void pal_patch_for_npc(u16 a, u16 b)
+{
+ u8 var = b;
+ u8 paletteIndex = FindFieldObjectPaletteIndexByTag(a);
+
+ LoadPalette(gUnknown_0837377C[paletteIndex].data, var * 16 + 0x100, 0x20);
+}
+
+void pal_patch_for_npc_range(const u16 *arr, u8 b, u8 c)
+{
+ for (; b < c; arr++, b++)
+ pal_patch_for_npc(*arr, b);
+}
+
+u8 FindFieldObjectPaletteIndexByTag(u16 tag)
+{
+ u8 i;
+
+ for (i = 0; gUnknown_0837377C[i].tag != 0x11FF; i++)
+ {
+ if (gUnknown_0837377C[i].tag == tag)
+ return i;
+ }
+ return 0xFF;
+}
+
+void npc_load_two_palettes__no_record(u16 a, u8 b)
+{
+ u8 i;
+
+ pal_patch_for_npc(a, b);
+ for (i = 0; gUnknown_08373874[i].tag != 0x11FF; i++)
+ {
+ if (gUnknown_08373874[i].tag == a)
+ {
+ pal_patch_for_npc(gUnknown_08373874[i].data[gUnknown_030005A4], gUnknown_0830FD14[b]);
+ break;
+ }
+ }
+}
+
+void npc_load_two_palettes__and_record(u16 a, u8 b)
+{
+ u8 i;
+
+ gUnknown_030005A6 = a;
+ pal_patch_for_npc(a, b);
+ for (i = 0; gUnknown_083738E4[i].tag != 0x11FF; i++)
+ {
+ if (gUnknown_083738E4[i].tag == a)
+ {
+ pal_patch_for_npc(gUnknown_083738E4[i].data[gUnknown_030005A4], gUnknown_0830FD14[b]);
+ break;
+ }
+ }
+}
+
+void unref_sub_805C014(struct MapObject *mapObject, s16 x, s16 y)
+{
+ mapObject->coords3.x = mapObject->coords2.x;
+ mapObject->coords3.y = mapObject->coords2.y;
+ mapObject->coords2.x += x;
+ mapObject->coords2.y += y;
+}
+
+void npc_coords_shift(struct MapObject *mapObject, s16 x, s16 y)
+{
+ mapObject->coords3.x = mapObject->coords2.x;
+ mapObject->coords3.y = mapObject->coords2.y;
+ mapObject->coords2.x = x;
+ mapObject->coords2.y = y;
+}
+
+void npc_coords_set(struct MapObject *mapObject, s16 x, s16 y)
+{
+ mapObject->coords3.x = x;
+ mapObject->coords3.y = y;
+ mapObject->coords2.x = x;
+ mapObject->coords2.y = y;
+}
+
+void sub_805C058(struct MapObject *mapObject, s16 x, s16 y)
+{
+ struct Sprite *sprite = &gSprites[mapObject->spriteId];
+ const struct MapObjectGraphicsInfo *gfxInfo = GetFieldObjectGraphicsInfo(mapObject->graphicsId);
+
+ npc_coords_set(mapObject, x, y);
+ sub_80603CC(mapObject->coords2.x, mapObject->coords2.y, &sprite->pos1.x, &sprite->pos1.y);
+ sprite->centerToCornerVecX = -(gfxInfo->width >> 1);
+ sprite->centerToCornerVecY = -(gfxInfo->height >> 1);
+ sprite->pos1.x += 8;
+ sprite->pos1.y += 16 + sprite->centerToCornerVecY;
+ sub_805B914(mapObject);
+ if (mapObject->mapobj_bit_15)
+ CameraObjectReset1();
+}
+
+void sub_805C0F8(u8 localId, u8 mapNum, u8 mapGroup, s16 x, s16 y)
+{
+ u8 mapObjectId;
+
+ if (!TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId))
+ {
+ x += 7;
+ y += 7;
+ sub_805C058(&gMapObjects[mapObjectId], x, y);
+ }
+}
+
+void npc_coords_shift_still(struct MapObject *mapObject)
+{
+ npc_coords_shift(mapObject, mapObject->coords2.x, mapObject->coords2.y);
+}
+
+void UpdateFieldObjectCoordsForCameraUpdate(void)
+{
+ u8 i;
+ s16 deltaX;
+ s16 deltaY;
+
+ if (gCamera.field_0)
+ {
+ deltaX = gCamera.x;
+ deltaY = gCamera.y;
+ for (i = 0; i < 16; i++)
+ {
+
+ if (gMapObjects[i].active)
+ {
+ gMapObjects[i].coords1.x -= deltaX;
+ gMapObjects[i].coords1.y -= deltaY;
+ gMapObjects[i].coords2.x -= deltaX;
+ gMapObjects[i].coords2.y -= deltaY;
+ gMapObjects[i].coords3.x -= deltaX;
+ gMapObjects[i].coords3.y -= deltaY;
+ }
+ }
+ }
+}
+
+bool8 FieldObjectDoesZCoordMatch(struct MapObject *, u8);
+
+u8 GetFieldObjectIdByXYZ(u16 x, u16 y, u8 z)
+{
+ u8 i;
+
+ for (i = 0; i < 16; i++)
+ {
+ if (gMapObjects[i].active && gMapObjects[i].coords2.x == x && gMapObjects[i].coords2.y == y
+ && FieldObjectDoesZCoordMatch(&gMapObjects[i], z))
+ return i;
+ }
+ return 16;
+}
+
+bool8 FieldObjectDoesZCoordMatch(struct MapObject *mapObject, u8 z)
+{
+ if (mapObject->mapobj_unk_0B_0 != 0 && z != 0
+ && mapObject->mapobj_unk_0B_0 != z)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+void UpdateFieldObjectsForCameraUpdate(s16 x, s16 y)
+{
+ UpdateFieldObjectCoordsForCameraUpdate();
+ sub_805B55C(x, y);
+ RemoveFieldObjectsOutsideView();
+}
+
+u8 AddCameraObject(u8 a)
+{
+ u8 spriteId = CreateSprite(&gSpriteTemplate_830FD24, 0, 0, 4);
+
+ gSprites[spriteId].invisible = TRUE;
+ gSprites[spriteId].data0 = a;
+ return spriteId;
+}
+
+void ObjectCB_CameraObject(struct Sprite *sprite)
+{
+ void (*cameraObjectFuncs[3])(struct Sprite *);
+ memcpy(cameraObjectFuncs, gCameraObjectFuncs, sizeof gCameraObjectFuncs);
+ cameraObjectFuncs[sprite->data1](sprite);
+}
+
+void CameraObject_0(struct Sprite *sprite)
+{
+ sprite->pos1.x = gSprites[sprite->data0].pos1.x;
+ sprite->pos1.y = gSprites[sprite->data0].pos1.y;
+ sprite->invisible = TRUE;
+ sprite->data1 = 1;
+ CameraObject_1(sprite);
+}
+
+void CameraObject_1(struct Sprite *sprite)
+{
+ s16 x = gSprites[sprite->data0].pos1.x;
+ s16 y = gSprites[sprite->data0].pos1.y;
+
+ sprite->data2 = x - sprite->pos1.x;
+ sprite->data3 = y - sprite->pos1.y;
+ sprite->pos1.x = x;
+ sprite->pos1.y = y;
+}
+
+void CameraObject_2(struct Sprite *sprite)
+{
+ sprite->pos1.x = gSprites[sprite->data0].pos1.x;
+ sprite->pos1.y = gSprites[sprite->data0].pos1.y;
+ sprite->data2 = 0;
+ sprite->data3 = 0;
+}
+
+struct Sprite *FindCameraObject(void)
+{
+ u8 i;
+
+ for (i = 0; i < 64; i++)
+ {
+ if (gSprites[i].inUse && gSprites[i].callback == ObjectCB_CameraObject)
+ return &gSprites[i];
+ }
+ return NULL;
+}
+
+void CameraObjectReset1(void)
+{
+ struct Sprite *cameraSprite = FindCameraObject();
+
+ if (cameraSprite != NULL)
+ {
+ cameraSprite->data1 = 0;
+ cameraSprite->callback(cameraSprite);
+ }
+}
+
+void CameraObjectSetFollowedObjectId(u8 spriteId)
+{
+ struct Sprite *cameraSprite = FindCameraObject();
+
+ if (cameraSprite != NULL)
+ {
+ cameraSprite->data0 = spriteId;
+ CameraObjectReset1();
+ }
+}
+
+u8 CameraObjectGetFollowedObjectId(void)
+{
+ struct Sprite *cameraSprite = FindCameraObject();
+
+ if (cameraSprite == NULL)
+ return 64;
+ else
+ return cameraSprite->data0;
+}
+
+void CameraObjectReset2(void)
+{
+ struct Sprite *cameraSprite = FindCameraObject();
+
+ cameraSprite->data1 = 2;
+}
+
+u8 unref_sub_805C43C(struct Sprite *src, s16 x, s16 y, u8 subpriority)
+{
+ u8 i;
+
+ for (i = 0; i < 64; i++)
+ {
+ if (!gSprites[i].inUse)
+ {
+ gSprites[i] = *src;
+ gSprites[i].pos1.x = x;
+ gSprites[i].pos1.y = y;
+ gSprites[i].subpriority = subpriority;
+ break;
+ }
+ }
+ return i;
+}
+
+u8 obj_unfreeze(struct Sprite *src, s16 x, s16 y, u8 subpriority)
+{
+ s16 i;
+
+ for (i = 63; i > -1; i--)
+ {
+ if (!gSprites[i].inUse)
+ {
+ gSprites[i] = *src;
+ gSprites[i].pos1.x = x;
+ gSprites[i].pos1.y = y;
+ gSprites[i].subpriority = subpriority;
+ return i;
+ }
+ }
+ return 64;
+}
+
+void FieldObjectSetDirection(struct MapObject *mapObject, u8 direction)
+{
+ mapObject->mapobj_unk_20 = mapObject->mapobj_unk_18;
+ if (!mapObject->mapobj_bit_9)
+ {
+ s8 _direction = direction; //needed for the asm to match
+ mapObject->mapobj_unk_18 = _direction;
+ }
+ mapObject->placeholder18 = direction;
+}
+
+u8 *GetFieldObjectScriptPointerByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup)
+{
+ struct MapObjectTemplate *template = GetFieldObjectTemplateByLocalIdAndMap(localId, mapNum, mapGroup);
+
+ return template->script;
+}
+
+u8 *GetFieldObjectScriptPointerByFieldObjectId(u8 mapObjectId)
+{
+ return GetFieldObjectScriptPointerByLocalIdAndMap(gMapObjects[mapObjectId].localId, gMapObjects[mapObjectId].mapNum, gMapObjects[mapObjectId].mapGroup);
+}
+
+u16 GetFieldObjectFlagIdByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup)
+{
+ struct MapObjectTemplate *template = GetFieldObjectTemplateByLocalIdAndMap(localId, mapNum, mapGroup);
+
+ return template->flagId;
+}
+
+u16 GetFieldObjectFlagIdByFieldObjectId(u8 mapObjectId)
+{
+ return GetFieldObjectFlagIdByLocalIdAndMap(gMapObjects[mapObjectId].localId, gMapObjects[mapObjectId].mapNum, gMapObjects[mapObjectId].mapGroup);
+}
+
+u8 unref_sub_805C5D0(u8 localId, u8 mapNum, u8 mapGroup)
+{
+ u8 mapObjectId;
+
+ if (TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId))
+ return 0xFF;
+ else
+ return gMapObjects[mapObjectId].trainerType;
+}
+
+u8 unref_sub_805C60C(u8 mapObjectId)
+{
+ return gMapObjects[mapObjectId].trainerType;
+}
+
+u8 unref_sub_805C624(u8 localId, u8 mapNum, u8 mapGroup)
+{
+ u8 mapObjectId;
+
+ if (TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId))
+ return 0xFF;
+ else
+ return gMapObjects[mapObjectId].trainerRange_berryTreeId;
+}
+
+u8 FieldObjectGetBerryTreeId(u8 mapObjectId)
+{
+ return gMapObjects[mapObjectId].trainerRange_berryTreeId;
+}
+
+struct MapObjectTemplate *FindFieldObjectTemplateInArrayByLocalId(u8, struct MapObjectTemplate *, u8);
+
+struct MapObjectTemplate *GetFieldObjectTemplateByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroup)
+{
+ if (gSaveBlock1.location.mapNum == mapNum && gSaveBlock1.location.mapGroup == mapGroup)
+ return FindFieldObjectTemplateInArrayByLocalId(localId, gSaveBlock1.mapObjectTemplates, gMapHeader.events->mapObjectCount);
+ else
+ {
+ struct MapHeader *mapHeader = Overworld_GetMapHeaderByGroupAndId(mapGroup, mapNum);
+
+ return FindFieldObjectTemplateInArrayByLocalId(localId, mapHeader->events->mapObjects, mapHeader->events->mapObjectCount);
+ }
+}
+
+struct MapObjectTemplate *FindFieldObjectTemplateInArrayByLocalId(u8 localId, struct MapObjectTemplate *templates, u8 count)
+{
+ u8 i;
+
+ for (i = 0; i < count; i++)
+ {
+ if (templates[i].localId == localId)
+ return &templates[i];
+ }
+ return NULL;
+}
+
+struct MapObjectTemplate *sub_805C700(struct MapObject *mapObject)
+{
+ s32 i;
+
+ if (mapObject->mapNum != gSaveBlock1.location.mapNum
+ || mapObject->mapGroup != gSaveBlock1.location.mapGroup)
+ return NULL;
+
+ for (i = 0; i < 64; i++)
+ {
+ if (mapObject->localId == gSaveBlock1.mapObjectTemplates[i].localId)
+ return &gSaveBlock1.mapObjectTemplates[i];
+ }
+ return NULL;
+}
+
+void sub_805C754(struct MapObject *mapObject)
+{
+ struct MapObjectTemplate *template = sub_805C700(mapObject);
+
+ if (template != NULL)
+ {
+ template->x = mapObject->coords2.x - 7;
+ template->y = mapObject->coords2.y - 7;
+ }
+}
+
+void sub_805C774(struct MapObject *mapObject, u8 movementType)
+{
+ struct MapObjectTemplate *template = sub_805C700(mapObject);
+
+ if (template != NULL)
+ template->movementType = movementType;
+}
+
+void sub_805C78C(u8 localId, u8 mapNum, u8 mapGroup)
+{
+ u8 mapObjectId;
+
+ if (!TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId))
+ sub_805C754(&gMapObjects[mapObjectId]);
+}
+
+void sub_805C7C4(u8 a)
+{
+ gpu_pal_allocator_reset__manage_upper_four();
+ gUnknown_030005A6 = 0x11FF;
+ gUnknown_030005A4 = a;
+ pal_patch_for_npc_range(gUnknown_0837399C[gUnknown_030005A4], 0, 10);
+}
+
+u16 npc_paltag_by_palslot(u8 a)
+{
+ u8 i;
+
+ if (a < 10)
+ return gUnknown_0837399C[gUnknown_030005A4][a];
+
+ for (i = 0; gUnknown_083738E4[i].tag != 0x11FF; i++)
+ {
+ if (gUnknown_083738E4[i].tag == gUnknown_030005A6)
+ {
+ return gUnknown_083738E4[i].data[gUnknown_030005A4];
+ }
+ }
+ return 0x11FF;
+}
+
+fieldmap_object_null_cb(sub_805C884, sub_805C8A8);
+fieldmap_object_cb(sub_805C8AC, sub_805C8D0, gUnknown_08375224);
+
+u8 sub_805C8F0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ sprite->data1 = 1;
+ return 1;
+}
+
+extern void FieldObjectSetRegularAnim(struct MapObject *, struct Sprite *, u8);
+
+u8 sub_805C904(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18));
+ sprite->data1 = 2;
+ return 1;
+}
+
+extern u8 FieldObjectExecRegularAnim(struct MapObject *, struct Sprite *);
+extern void sub_8064820(struct Sprite *, s16);
+
+u8 sub_805C930(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite) == 0)
+ {
+ return 0;
+ }
+ sub_8064820(sprite, gUnknown_0837520C[Random() & 3]);
+ sprite->data1 = 3;
+ return 1;
+}
+
+extern u8 sub_8064824(struct Sprite *);
+
+u8 sub_805C96C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8064824(sprite) != 0)
+ {
+ sprite->data1 = 4;
+ return 1;
+ }
+ return 0;
+}
+
+extern u8 sub_805FF20(struct MapObject *, u8);
+
+u8 sub_805C98C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 direction;
+ u8 directions[4];
+ memcpy(directions, gUnknown_08375240, 4);
+ direction = directions[Random() & 3];
+ FieldObjectSetDirection(mapObject, direction);
+ sprite->data1 = 5;
+ if (sub_805FF20(mapObject, direction) != 0)
+ {
+ sprite->data1 = 1;
+ }
+ return 1;
+}
+
+u8 sub_805C9D8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FieldObjectSetRegularAnim(mapObject, sprite, GetGoSpeed0AnimId(mapObject->placeholder18));
+ mapObject->mapobj_bit_1 = 1;
+ sprite->data1 = 6;
+ return 1;
+}
+
+u8 sub_805CA08(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite) != 0)
+ {
+ mapObject->mapobj_bit_1 = 0;
+ sprite->data1 = 1;
+ }
+ return 0;
+}
+
+u8 FieldObjectIsTrainerAndCloseToPlayer(struct MapObject *mapObject)
+{
+ s16 x;
+ s16 y;
+ s16 objx;
+ s16 objy;
+ s16 minx;
+ s16 maxx;
+ s16 miny;
+ s16 maxy;
+ if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_DASH) == 0)
+ {
+ return 0;
+ }
+ if (mapObject->trainerType != 1 && mapObject->trainerType != 3)
+ {
+ return 0;
+ }
+ PlayerGetDestCoords(&x, &y);
+ objx = mapObject->coords2.x;
+ objy = mapObject->coords2.y;
+ minx = objx - mapObject->trainerRange_berryTreeId;
+ miny = objy - mapObject->trainerRange_berryTreeId;
+ maxx = objx + mapObject->trainerRange_berryTreeId;
+ maxy = objy + mapObject->trainerRange_berryTreeId;
+ if (minx > x || maxx < x || miny > y || maxy < y)
+ {
+ return 0;
+ }
+ return 1;
+}
+
+u8 sub_805CAAC(s16 a0, s16 a1, s16 a2, s16 a3)
+{
+ u8 dirn;
+ if (a2 > a3)
+ {
+ dirn = DIR_EAST;
+ if (a0 < 0)
+ {
+ dirn = DIR_WEST;
+ }
+ }
+ else
+ {
+ dirn = DIR_SOUTH;
+ if (a1 < 0)
+ {
+ dirn = DIR_NORTH;
+ }
+ }
+ return dirn;
+}
+
+u8 sub_805CADC(s16 a0, s16 a1, s16 a2, s16 a3)
+{
+ u8 dirn;
+ dirn = DIR_SOUTH;
+ if (a1 < 0)
+ {
+ dirn = DIR_NORTH;
+ }
+ return dirn;
+}
+
+u8 sub_805CAEC(s16 a0, s16 a1, s16 a2, s16 a3)
+{
+ u8 dirn;
+ dirn = DIR_EAST;
+ if (a0 < 0)
+ {
+ dirn = DIR_WEST;
+ }
+ return dirn;
+}
+
+u8 sub_805CB00(s16 a0, s16 a1, s16 a2, s16 a3)
+{
+ u8 dirn;
+ dirn = sub_805CAAC(a0, a1, a2, a3);
+ if (dirn == DIR_SOUTH)
+ {
+ dirn = sub_805CAEC(a0, a1, a2, a3);
+ if (dirn == DIR_EAST)
+ {
+ dirn = DIR_NORTH;
+ }
+ }
+ else if (dirn == DIR_EAST)
+ {
+ dirn = sub_805CADC(a0, a1, a2, a3);
+ if (dirn == DIR_SOUTH)
+ {
+ dirn = DIR_NORTH;
+ }
+ }
+ return dirn;
+}
+
+u8 sub_805CB5C(s16 a0, s16 a1, s16 a2, s16 a3)
+{
+ u8 dirn;
+ dirn = sub_805CAAC(a0, a1, a2, a3);
+ if (dirn == DIR_SOUTH)
+ {
+ dirn = sub_805CAEC(a0, a1, a2, a3);
+ if (dirn == DIR_WEST)
+ {
+ dirn = DIR_NORTH;
+ }
+ }
+ else if (dirn == DIR_WEST)
+ {
+ dirn = sub_805CADC(a0, a1, a2, a3);
+ if (dirn == DIR_SOUTH)
+ {
+ dirn = DIR_NORTH;
+ }
+ }
+ return dirn;
+}
+
+u8 sub_805CBB8(s16 a0, s16 a1, s16 a2, s16 a3)
+{
+ u8 dirn;
+ dirn = sub_805CAAC(a0, a1, a2, a3);
+ if (dirn == DIR_NORTH)
+ {
+ dirn = sub_805CAEC(a0, a1, a2, a3);
+ if (dirn == DIR_EAST)
+ {
+ dirn = DIR_SOUTH;
+ }
+ }
+ else if (dirn == DIR_EAST)
+ {
+ dirn = sub_805CADC(a0, a1, a2, a3);
+ if (dirn == DIR_NORTH)
+ {
+ dirn = DIR_SOUTH;
+ }
+ }
+ return dirn;
+}
+
+u8 sub_805CC14(s16 a0, s16 a1, s16 a2, s16 a3) {
+ u8 dirn;
+ dirn = sub_805CAAC(a0, a1, a2, a3);
+ if (dirn == DIR_NORTH)
+ {
+ dirn = sub_805CAEC(a0, a1, a2, a3);
+ if (dirn == DIR_WEST)
+ {
+ dirn = DIR_SOUTH;
+ }
+ }
+ else if (dirn == DIR_WEST)
+ {
+ dirn = sub_805CADC(a0, a1, a2, a3);
+ if (dirn == DIR_NORTH)
+ {
+ dirn = DIR_SOUTH;
+ }
+ }
+ return dirn;
+}
+
+u8 sub_805CC70(s16 a0, s16 a1, s16 a2, s16 a3)
+{
+ u8 dirn;
+ dirn = sub_805CAAC(a0, a1, a2, a3);
+ if (dirn == DIR_EAST)
+ {
+ dirn = sub_805CADC(a0, a1, a2, a3);
+ }
+ return dirn;
+}
+
+u8 sub_805CCAC(s16 a0, s16 a1, s16 a2, s16 a3)
+{
+ u8 dirn;
+ dirn = sub_805CAAC(a0, a1, a2, a3);
+ if (dirn == DIR_WEST)
+ {
+ dirn = sub_805CADC(a0, a1, a2, a3);
+ }
+ return dirn;
+}
+
+u8 sub_805CCE8(s16 a0, s16 a1, s16 a2, s16 a3)
+{
+ u8 dirn;
+ dirn = sub_805CAAC(a0, a1, a2, a3);
+ if (dirn == DIR_SOUTH)
+ {
+ dirn = sub_805CAEC(a0, a1, a2, a3);
+ }
+ return dirn;
+}
+
+u8 sub_805CD24(s16 a0, s16 a1, s16 a2, s16 a3)
+{
+ u8 dirn;
+ dirn = sub_805CAAC(a0, a1, a2, a3);
+ if (dirn == DIR_NORTH)
+ {
+ dirn = sub_805CAEC(a0, a1, a2, a3);
+ }
+ return dirn;
+}
+
+u8 sub_805CD60(struct MapObject *mapObject, u8 a1)
+{
+ s16 x;
+ s16 y;
+ s16 x2;
+ s16 y2;
+ if (!FieldObjectIsTrainerAndCloseToPlayer(mapObject))
+ {
+ return 0;
+ }
+ PlayerGetDestCoords(&x, &y);
+ x -= mapObject->coords2.x;
+ y -= mapObject->coords2.y;
+ x2 = x;
+ y2 = y;
+ if (x2 < 0)
+ {
+ x2 = -x2;
+ }
+ if (y2 < 0)
+ {
+ y2 = -y2;
+ }
+ return gUnknown_08375244[a1](x, y, x2, y2);
+}
+
+fieldmap_object_cb(sub_805CDE8, sub_805CE0c, gUnknown_08375270);
+
+u8 sub_805CE2C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ sprite->data1 = 1;
+ return 1;
+}
+
+u8 sub_805CE40(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18));
+ sprite->data1 = 2;
+ return 1;
+}
+
+u8 sub_805CE6C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite) != 0)
+ {
+ sub_8064820(sprite, gUnknown_0837520C[Random() & 3]);
+ mapObject->mapobj_bit_1 = 0;
+ sprite->data1 = 3;
+ }
+ return 0;
+}
+
+u8 sub_805CEB0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8064824(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject))
+ {
+ sprite->data1 = 4;
+ return 1;
+ }
+ return 0;
+}
+
+u8 sub_805CEE0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 direction;
+ u8 directions[4];
+ memcpy(directions, gUnknown_08375240, 4);
+ direction = sub_805CD60(mapObject, 0);
+ if (direction == 0)
+ {
+ direction = directions[Random() & 3];
+ }
+ FieldObjectSetDirection(mapObject, direction);
+ sprite->data1 = 1;
+ return 1;
+}
+
+fieldmap_object_cb(sub_805CF28, sub_805CF4C, gUnknown_08375284);
+
+u8 sub_805CF6C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ sprite->data1 = 1;
+ return 1;
+}
+
+u8 sub_805CF80(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18));
+ sprite->data1 = 2;
+ return 1;
+}
+
+u8 sub_805CFAC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite) == 0)
+ {
+ return 0;
+ }
+ sub_8064820(sprite, gUnknown_0837520C[Random() & 3]);
+ sprite->data1 = 3;
+ return 1;
+}
+
+u8 sub_805CFE8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8064824(sprite) != 0)
+ {
+ sprite->data1 = 4;
+ return 1;
+ }
+ return 0;
+}
+
+u8 sub_805D008(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 direction;
+ u8 directions[2];
+ memcpy(directions, gUnknown_083752A0, 2);
+ direction = directions[Random() & 1];
+ FieldObjectSetDirection(mapObject, direction);
+ sprite->data1 = 5;
+ if (sub_805FF20(mapObject, direction) != 0)
+ {
+ sprite->data1 = 1;
+ }
+ return 1;
+}
+
+u8 sub_805D054(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FieldObjectSetRegularAnim(mapObject, sprite, GetGoSpeed0AnimId(mapObject->placeholder18));
+ mapObject->mapobj_bit_1 = 1;
+ sprite->data1 = 6;
+ return 1;
+}
+
+u8 sub_805D084(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite) != 0)
+ {
+ mapObject->mapobj_bit_1 = 0;
+ sprite->data1 = 1;
+ }
+ return 0;
+}
+
+fieldmap_object_cb(sub_805D0AC, sub_805D0D0, gUnknown_083752A4);
+
+u8 sub_805D0F0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ sprite->data1 = 1;
+ return 1;
+}
+
+u8 sub_805D104(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18));
+ sprite->data1 = 2;
+ return 1;
+}
+
+u8 sub_805D130(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite) == 0)
+ {
+ return 0;
+ }
+ sub_8064820(sprite, gUnknown_0837520C[Random() & 3]);
+ sprite->data1 = 3;
+ return 1;
+}
+
+u8 sub_805D16C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8064824(sprite) != 0)
+ {
+ sprite->data1 = 4;
+ return 1;
+ }
+ return 0;
+}
+
+u8 sub_805D18C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 direction;
+ u8 directions[2];
+ memcpy(directions, gUnknown_083752C0, 2);
+ direction = directions[Random() & 1];
+ FieldObjectSetDirection(mapObject, direction);
+ sprite->data1 = 5;
+ if (sub_805FF20(mapObject, direction) != 0)
+ {
+ sprite->data1 = 1;
+ }
+ return 1;
+}
+
+u8 sub_805D1D8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FieldObjectSetRegularAnim(mapObject, sprite, GetGoSpeed0AnimId(mapObject->placeholder18));
+ mapObject->mapobj_bit_1 = 1;
+ sprite->data1 = 6;
+ return 1;
+}
+
+u8 sub_805D208(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite) != 0)
+ {
+ mapObject->mapobj_bit_1 = 0;
+ sprite->data1 = 1;
+ }
+ return 0;
+}
+
+fieldmap_object_cb(sub_805D230, sub_805D254, gUnknown_083752C4);
+
+u8 sub_805D274(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18));
+ sprite->data1 = 1;
+ return 1;
+}
+
+u8 sub_805D2A0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite) != 0)
+ {
+ sprite->data1 = 2;
+ return 1;
+ }
+ return 0;
+}
+
+u8 sub_805D2C0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ mapObject->mapobj_bit_1 = 0;
+ return 0;
+}
+
+u8 sub_805D314(struct MapObject *mapObject, struct Sprite *sprite);
+
+void FieldObjectCB_BerryTree(struct Sprite *sprite)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[sprite->data0];
+ if (!(sprite->data7 & 1))
+ {
+ get_berry_tree_graphics(mapObject, sprite);
+ sprite->data7 |= 1;
+ }
+ meta_step(mapObject, sprite, sub_805D314);
+}
+
+u8 sub_805D314(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ return gUnknown_083752D0[sprite->data1](mapObject, sprite);
+}
+
+u8 do_berry_tree_growth_sparkle_1(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 berryTreeStage;
+ npc_reset(mapObject, sprite);
+ mapObject->mapobj_bit_13 = 1;
+ sprite->invisible = 1;
+ berryTreeStage = GetStageByBerryTreeId(mapObject->trainerRange_berryTreeId);
+ if (!berryTreeStage)
+ {
+ if (!(sprite->data7 & 4) && sprite->animNum == 4)
+ {
+ gFieldEffectArguments[0] = mapObject->coords2.x;
+ gFieldEffectArguments[1] = mapObject->coords2.y;
+ gFieldEffectArguments[2] = sprite->subpriority - 1;
+ gFieldEffectArguments[3] = sprite->oam.priority;
+ FieldEffectStart(FLDEFF_BERRY_TREE_GROWTH_SPARKLE);
+ sprite->animNum = 0;
+ }
+ return 0;
+ }
+ mapObject->mapobj_bit_13 = 0;
+ sprite->invisible = 0;
+ berryTreeStage--;
+ if (sprite->animNum != berryTreeStage)
+ {
+ sprite->data1 = 2;
+ return 1;
+ }
+ get_berry_tree_graphics(mapObject, sprite);
+ FieldObjectSetRegularAnim(mapObject, sprite, 0x39);
+ sprite->data1 = 1;
+ return 1;
+}
+
+u8 sub_805D3EC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite))
+ {
+ sprite->data1 = 0;
+ return 1;
+ }
+ return 0;
+}
+
+u8 do_berry_tree_growth_sparkle_2(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ mapObject->mapobj_bit_1 = 1;
+ sprite->data1 = 3;
+ sprite->data2 = 0;
+ sprite->data7 |= 2;
+ gFieldEffectArguments[0] = mapObject->coords2.x;
+ gFieldEffectArguments[1] = mapObject->coords2.y;
+ gFieldEffectArguments[2] = sprite->subpriority - 1;
+ gFieldEffectArguments[3] = sprite->oam.priority;
+ FieldEffectStart(FLDEFF_BERRY_TREE_GROWTH_SPARKLE);
+ return 1;
+}
+
+u8 sub_805D458(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sprite->data2++;
+ mapObject->mapobj_bit_13 = ((sprite->data2 & 0x2) >> 1);
+ sprite->animPaused = 1;
+ if (sprite->data2 > 64)
+ {
+ get_berry_tree_graphics(mapObject, sprite);
+ sprite->data1 = 4;
+ sprite->data2 = 0;
+ return 1;
+ }
+ return 0;
+}
+
+u8 sub_805D4A8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sprite->data2++;
+ mapObject->mapobj_bit_13 = ((sprite->data2 & 0x2) >> 1);
+ sprite->animPaused = 1;
+ if (sprite->data2 > 64)
+ {
+ sprite->data1 = 0;
+ sprite->data7 &= (-3);
+ return 1;
+ }
+ return 0;
+}
+
+fieldmap_object_cb(sub_805D4F4, sub_805D518, gUnknown_083752E4);
+
+u8 sub_805D538(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ sprite->data1 = 1;
+ return 1;
+}
+
+u8 sub_805D54C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18));
+ sprite->data1 = 2;
+ return 1;
+}
+
+u8 sub_805D578(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite))
+ {
+ sub_8064820(sprite, gUnknown_0837520C[Random() & 3]);
+ mapObject->mapobj_bit_1 = 0;
+ sprite->data1 = 3;
+ }
+ return 0;
+}
+
+u8 sub_805D5BC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8064824(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject))
+ {
+ sprite->data1 = 4;
+ return 1;
+ }
+ return 0;
+}
+
+u8 sub_805D5EC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 direction;
+ u8 directions[2];
+ memcpy(directions, gUnknown_083752A0, 2);
+ direction = sub_805CD60(mapObject, 1);
+ if (direction == 0)
+ {
+ direction = directions[Random() & 1];
+ }
+ FieldObjectSetDirection(mapObject, direction);
+ sprite->data1 = 1;
+ return 1;
+}
+
+fieldmap_object_cb(sub_805D634, sub_805D658, gUnknown_083752F8);
+
+u8 sub_805D678(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ sprite->data1 = 1;
+ return 1;
+}
+
+u8 sub_805D68C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18));
+ sprite->data1 = 2;
+ return 1;
+}
+
+u8 sub_805D6B8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite))
+ {
+ sub_8064820(sprite, gUnknown_0837520C[Random() & 3]);
+ mapObject->mapobj_bit_1 = 0;
+ sprite->data1 = 3;
+ }
+ return 0;
+}
+
+u8 sub_805D6FC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8064824(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject))
+ {
+ sprite->data1 = 4;
+ return 1;
+ }
+ return 0;
+}
+
+u8 sub_805D72C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 direction;
+ u8 directions[2];
+ memcpy(directions, gUnknown_083752C0, 2);
+ direction = sub_805CD60(mapObject, 2);
+ if (direction == 0)
+ {
+ direction = directions[Random() & 1];
+ }
+ FieldObjectSetDirection(mapObject, direction);
+ sprite->data1 = 1;
+ return 1;
+}
+
+fieldmap_object_cb(sub_805D774, sub_805D798, gUnknown_0837530C);
+
+u8 sub_805D7B8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ sprite->data1 = 1;
+ return 1;
+}
+
+u8 sub_805D7CC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18));
+ sprite->data1 = 2;
+ return 1;
+}
+
+u8 sub_805D7F8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite))
+ {
+ sub_8064820(sprite, gUnknown_0837521C[Random() & 3]);
+ mapObject->mapobj_bit_1 = 0;
+ sprite->data1 = 3;
+ }
+ return 0;
+}
+
+u8 sub_805D83C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8064824(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject))
+ {
+ sprite->data1 = 4;
+ return 1;
+ }
+ return 0;
+}
+
+u8 sub_805D86C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 direction;
+ u8 directions[2];
+ memcpy(directions, gUnknown_08375320, 2);
+ direction = sub_805CD60(mapObject, 3);
+ if (direction == 0)
+ {
+ direction = directions[Random() & 1];
+ }
+ FieldObjectSetDirection(mapObject, direction);
+ sprite->data1 = 1;
+ return 1;
+}
+
+fieldmap_object_cb(sub_805D8B4, sub_805D8D8, gUnknown_08375324);
+
+u8 sub_805D8F8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ sprite->data1 = 1;
+ return 1;
+}
+
+u8 sub_805D90C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18));
+ sprite->data1 = 2;
+ return 1;
+}
+
+u8 sub_805D938(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite))
+ {
+ sub_8064820(sprite, gUnknown_0837521C[Random() & 3]);
+ mapObject->mapobj_bit_1 = 0;
+ sprite->data1 = 3;
+ }
+ return 0;
+}
+
+u8 sub_805D97C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8064824(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject))
+ {
+ sprite->data1 = 4;
+ return 1;
+ }
+ return 0;
+}
+
+u8 sub_805D9AC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 direction;
+ u8 directions[2];
+ memcpy(directions, gUnknown_08375338, 2);
+ direction = sub_805CD60(mapObject, 4);
+ if (direction == 0)
+ {
+ direction = directions[Random() & 1];
+ }
+ FieldObjectSetDirection(mapObject, direction);
+ sprite->data1 = 1;
+ return 1;
+}
+
+fieldmap_object_cb(sub_805D9F4, sub_805DA18, gUnknown_0837533C);
+
+u8 sub_805DA38(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ sprite->data1 = 1;
+ return 1;
+}
+
+u8 sub_805DA4C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18));
+ sprite->data1 = 2;
+ return 1;
+}
+
+u8 sub_805DA78(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite))
+ {
+ sub_8064820(sprite, gUnknown_0837521C[Random() & 3]);
+ mapObject->mapobj_bit_1 = 0;
+ sprite->data1 = 3;
+ }
+ return 0;
+}
+
+u8 sub_805DABC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8064824(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject))
+ {
+ sprite->data1 = 4;
+ return 1;
+ }
+ return 0;
+}
+
+u8 sub_805DAEC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 direction;
+ u8 directions[2];
+ memcpy(directions, gUnknown_08375350, 2);
+ direction = sub_805CD60(mapObject, 5);
+ if (direction == 0)
+ {
+ direction = directions[Random() & 1];
+ }
+ FieldObjectSetDirection(mapObject, direction);
+ sprite->data1 = 1;
+ return 1;
+}
+
+fieldmap_object_cb(sub_805DB34, sub_805DB58, gUnknown_08375354);
+
+u8 sub_805DB78(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ sprite->data1 = 1;
+ return 1;
+}
+
+u8 sub_805DB8C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18));
+ sprite->data1 = 2;
+ return 1;
+}
+
+u8 sub_805DBB8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite))
+ {
+ sub_8064820(sprite, gUnknown_0837521C[Random() & 3]);
+ mapObject->mapobj_bit_1 = 0;
+ sprite->data1 = 3;
+ }
+ return 0;
+}
+
+u8 sub_805DBFC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8064824(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject))
+ {
+ sprite->data1 = 4;
+ return 1;
+ }
+ return 0;
+}
+
+u8 sub_805DC2C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 direction;
+ u8 directions[2];
+ memcpy(directions, gUnknown_08375368, 2);
+ direction = sub_805CD60(mapObject, 6);
+ if (direction == 0)
+ {
+ direction = directions[Random() & 1];
+ }
+ FieldObjectSetDirection(mapObject, direction);
+ sprite->data1 = 1;
+ return 1;
+}
+
+fieldmap_object_cb(sub_805DC74, sub_805DC98, gUnknown_0837536C);
+
+u8 sub_805DCB8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ sprite->data1 = 1;
+ return 1;
+}
+
+u8 sub_805DCCC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18));
+ sprite->data1 = 2;
+ return 1;
+}
+
+u8 sub_805DCF8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite))
+ {
+ sub_8064820(sprite, gUnknown_0837521C[Random() & 3]);
+ mapObject->mapobj_bit_1 = 0;
+ sprite->data1 = 3;
+ }
+ return 0;
+}
+
+u8 sub_805DD3C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8064824(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject))
+ {
+ sprite->data1 = 4;
+ return 1;
+ }
+ return 0;
+}
+
+u8 sub_805DD6C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 direction;
+ u8 directions[4];
+ memcpy(directions, gUnknown_08375380, 4);
+ direction = sub_805CD60(mapObject, 7);
+ if (direction == 0)
+ {
+ direction = directions[Random() & 3];
+ }
+ FieldObjectSetDirection(mapObject, direction);
+ sprite->data1 = 1;
+ return 1;
+}
+
+fieldmap_object_cb(sub_805DDB4, sub_805DDD8, gUnknown_08375384);
+
+u8 sub_805DDF8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ sprite->data1 = 1;
+ return 1;
+}
+
+u8 sub_805DE0C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18));
+ sprite->data1 = 2;
+ return 1;
+}
+
+u8 sub_805DE38(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite))
+ {
+ sub_8064820(sprite, gUnknown_0837521C[Random() & 3]);
+ mapObject->mapobj_bit_1 = 0;
+ sprite->data1 = 3;
+ }
+ return 0;
+}
+
+u8 sub_805DE7C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8064824(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject))
+ {
+ sprite->data1 = 4;
+ return 1;
+ }
+ return 0;
+}
+
+u8 sub_805DEAC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 direction;
+ u8 directions[4];
+ memcpy(directions, gUnknown_08375398, 4);
+ direction = sub_805CD60(mapObject, 8);
+ if (direction == 0)
+ {
+ direction = directions[Random() & 3];
+ }
+ FieldObjectSetDirection(mapObject, direction);
+ sprite->data1 = 1;
+ return 1;
+}
+
+fieldmap_object_cb(sub_805DEF4, sub_805DF18, gUnknown_0837539C);
+
+u8 sub_805DF38(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ sprite->data1 = 1;
+ return 1;
+}
+
+u8 sub_805DF4C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18));
+ sprite->data1 = 2;
+ return 1;
+}
+
+u8 sub_805DF78(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite))
+ {
+ sub_8064820(sprite, gUnknown_0837521C[Random() & 3]);
+ mapObject->mapobj_bit_1 = 0;
+ sprite->data1 = 3;
+ }
+ return 0;
+}
+
+u8 sub_805DFBC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8064824(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject))
+ {
+ sprite->data1 = 4;
+ return 1;
+ }
+ return 0;
+}
+
+u8 sub_805DFEC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 direction;
+ u8 directions[4];
+ memcpy(directions, gUnknown_083753B0, 4);
+ direction = sub_805CD60(mapObject, 9);
+ if (direction == 0)
+ {
+ direction = directions[Random() & 3];
+ }
+ FieldObjectSetDirection(mapObject, direction);
+ sprite->data1 = 1;
+ return 1;
+}
+
+fieldmap_object_cb(sub_805E034, sub_805E058, gUnknown_083753B4);
+
+u8 sub_805E078(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ sprite->data1 = 1;
+ return 1;
+}
+
+u8 sub_805E08C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18));
+ sprite->data1 = 2;
+ return 1;
+}
+
+u8 sub_805E0B8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite))
+ {
+ sub_8064820(sprite, gUnknown_0837521C[Random() & 3]);
+ mapObject->mapobj_bit_1 = 0;
+ sprite->data1 = 3;
+ }
+ return 0;
+}
+
+u8 sub_805E0FC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8064824(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject))
+ {
+ sprite->data1 = 4;
+ return 1;
+ }
+ return 0;
+}
+
+u8 sub_805E12C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 direction;
+ u8 directions[4];
+ memcpy(directions, gUnknown_083753C8, 4);
+ direction = sub_805CD60(mapObject, 10);
+ if (direction == 0)
+ {
+ direction = directions[Random() & 3];
+ }
+ FieldObjectSetDirection(mapObject, direction);
+ sprite->data1 = 1;
+ return 1;
+}
+
+fieldmap_object_cb(sub_805E174, sub_805E198, gUnknown_083753CC);
+
+u8 sub_805E1B8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18));
+ sprite->data1 = 1;
+ return 1;
+}
+
+u8 sub_805E1E4(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite))
+ {
+ sub_8064820(sprite, 0x30);
+ sprite->data1 = 2;
+ }
+ return 0;
+}
+
+u8 sub_805E208(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8064824(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject))
+ {
+ sprite->data1 = 3;
+ }
+ return 0;
+}
+
+u8 sub_805E234(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 direction;
+ u8 directions[5];
+ memcpy(directions, gUnknown_083753DC, 5);
+ direction = sub_805CD60(mapObject, 0);
+ if (direction == 0)
+ {
+ direction = directions[mapObject->mapobj_unk_18];
+ }
+ FieldObjectSetDirection(mapObject, direction);
+ sprite->data1 = 0;
+ return 1;
+}
+
+fieldmap_object_cb(sub_805E278, sub_803E29C, gUnknown_083753E4);
+
+u8 sub_805E2BC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18));
+ sprite->data1 = 1;
+ return 1;
+}
+
+u8 sub_805E2E8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite))
+ {
+ sub_8064820(sprite, 0x30);
+ sprite->data1 = 2;
+ }
+ return 0;
+}
+
+u8 sub_805E30C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8064824(sprite) || FieldObjectIsTrainerAndCloseToPlayer(mapObject))
+ {
+ sprite->data1 = 3;
+ }
+ return 0;
+}
+
+u8 sub_805E338(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 direction;
+ u8 directions[5];
+ memcpy(directions, gUnknown_083753F4, 5);
+ direction = sub_805CD60(mapObject, 0);
+ if (direction == 0)
+ {
+ direction = directions[mapObject->mapobj_unk_18];
+ }
+ FieldObjectSetDirection(mapObject, direction);
+ sprite->data1 = 0;
+ return 1;
+}
+
+fieldmap_object_cb(sub_805E37C, sub_805E3A0, gUnknown_083753FC);
+
+u8 sub_805E3C0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ sprite->data1 = 1;
+ return 1;
+}
+
+u8 sub_805E3D4(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 direction;
+ direction = gUnknown_0836DC09[mapObject->animPattern];
+ if (mapObject->mapobj_unk_21 != 0)
+ {
+ direction = GetOppositeDirection(direction);
+ }
+ FieldObjectSetDirection(mapObject, direction);
+ sprite->data1 = 2;
+ return 1;
+}
+
+u8 sub_805E40C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 v0;
+ u8 goSpeed0AnimId;
+ if (mapObject->mapobj_unk_21 && mapObject->coords1.x == mapObject->coords2.x && mapObject->coords1.y == mapObject->coords2.y)
+ {
+ mapObject->mapobj_unk_21 = 0;
+ FieldObjectSetDirection(mapObject, GetOppositeDirection(mapObject->placeholder18));
+ }
+ v0 = sub_805FF20(mapObject, mapObject->placeholder18);
+ goSpeed0AnimId = GetGoSpeed0AnimId(mapObject->placeholder18);
+ if (v0 == 1)
+ {
+ mapObject->mapobj_unk_21 ++;
+ FieldObjectSetDirection(mapObject, GetOppositeDirection(mapObject->placeholder18));
+ goSpeed0AnimId = GetGoSpeed0AnimId(mapObject->placeholder18);
+ v0 = sub_805FF20(mapObject, mapObject->placeholder18);
+ }
+ if (v0 != 0)
+ {
+ goSpeed0AnimId = GetStepInPlaceDelay16AnimId(mapObject->mapobj_unk_18);
+ }
+ FieldObjectSetRegularAnim(mapObject, sprite, goSpeed0AnimId);
+ mapObject->mapobj_bit_1 = 1;
+ sprite->data1 = 3;
+ return 1;
+}
+
+u8 sub_805E4C4(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_1 = 0;
+ sprite->data1 = 1;
+ }
+ return 0;
+}
+
+u8 sub_805E4EC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ sprite->data1 = 1;
+ return 1;
+}
+
+u8 MoveFieldObjectInNextDirectionInSequence(struct MapObject *mapObject, struct Sprite *sprite, u8 *directionSequence)
+{
+ u8 v0;
+ u8 goSpeed0AnimId;
+ if (mapObject->mapobj_unk_21 == 3 && mapObject->coords1.x == mapObject->coords2.x && mapObject->coords1.y == mapObject->coords2.y)
+ {
+ mapObject->mapobj_unk_21 = 0;
+ }
+ FieldObjectSetDirection(mapObject, directionSequence[mapObject->mapobj_unk_21]);
+ goSpeed0AnimId = GetGoSpeed0AnimId(mapObject->placeholder18);
+ v0 = sub_805FF20(mapObject, mapObject->placeholder18);
+ if (v0 == 1)
+ {
+ mapObject->mapobj_unk_21 ++;
+ FieldObjectSetDirection(mapObject, directionSequence[mapObject->mapobj_unk_21]);
+ goSpeed0AnimId = GetGoSpeed0AnimId(mapObject->placeholder18);
+ v0 = sub_805FF20(mapObject, mapObject->placeholder18);
+ }
+ if (v0 != 0)
+ {
+ goSpeed0AnimId = GetStepInPlaceDelay16AnimId(mapObject->mapobj_unk_18);
+ }
+ FieldObjectSetRegularAnim(mapObject, sprite, goSpeed0AnimId);
+ mapObject->mapobj_bit_1 = 1;
+ sprite->data1 = 2;
+ return 1;
+}
+
+u8 sub_805E5B4(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_1 = 0;
+ sprite->data1 = 1;
+ }
+ return 0;
+}
+
+fieldmap_object_cb(sub_805E5DC, sub_805E600, gUnknown_0837540C);
+
+u8 sub_805E620(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_08375418, 4);
+ if (mapObject->mapobj_unk_21 == 2 && mapObject->coords1.x == mapObject->coords2.x)
+ {
+ mapObject->mapobj_unk_21 = 3;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+}
+
+fieldmap_object_cb(sub_805E668, sub_805E68C, gUnknown_0837541C);
+
+u8 sub_805E6AC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_08375428, 4);
+ if (mapObject->mapobj_unk_21 == 1 && mapObject->coords1.x == mapObject->coords2.x)
+ {
+ mapObject->mapobj_unk_21 = 2;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+}
+
+fieldmap_object_cb(sub_805E6F4, sub_805E718, gUnknown_0837542C);
+
+u8 sub_805E738(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_08375438, 4);
+ if (mapObject->mapobj_unk_21 == 1 && mapObject->coords1.y == mapObject->coords2.y)
+ {
+ mapObject->mapobj_unk_21 = 2;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+}
+
+fieldmap_object_cb(sub_805E780, sub_805E7A4, gUnknown_0837543C);
+
+u8 sub_805E7C4(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_08375448, 4);
+ if (mapObject->mapobj_unk_21 == 2 && mapObject->coords1.y == mapObject->coords2.y)
+ {
+ mapObject->mapobj_unk_21 = 3;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+}
+
+
+
+fieldmap_object_cb(sub_805E80C, sub_805E830, gUnknown_0837544C);
+
+u8 sub_805E850(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_08375458, 4);
+ if (mapObject->mapobj_unk_21 == 2 && mapObject->coords1.x == mapObject->coords2.x)
+ {
+ mapObject->mapobj_unk_21 = 3;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+}
+
+fieldmap_object_cb(sub_805E898, sub_805E8BC, gUnknown_0837545C);
+
+u8 sub_805E8DC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_08375468, 4);
+ if (mapObject->mapobj_unk_21 == 1 && mapObject->coords1.x == mapObject->coords2.x)
+ {
+ mapObject->mapobj_unk_21 = 2;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+}
+
+fieldmap_object_cb(sub_805E924, sub_805E948, gUnknown_0837546C);
+
+u8 sub_805E968(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_08375240, 4);
+ if (mapObject->mapobj_unk_21 == 1 && mapObject->coords1.y == mapObject->coords2.y)
+ {
+ mapObject->mapobj_unk_21 = 2;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+}
+
+fieldmap_object_cb(sub_805E9B0, sub_805E9D4, gUnknown_08375478);
+
+u8 sub_805E9F4(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_08375484, 4);
+ if (mapObject->mapobj_unk_21 == 2 && mapObject->coords1.y == mapObject->coords2.y)
+ {
+ mapObject->mapobj_unk_21 = 3;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+}
+
+fieldmap_object_cb(sub_805EA3C, sub_805EA60, gUnknown_08375488);
+
+u8 sub_805EA80(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_08375494, 4);
+ if (mapObject->mapobj_unk_21 == 2 && mapObject->coords1.y == mapObject->coords2.y)
+ {
+ mapObject->mapobj_unk_21 = 3;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+}
+
+fieldmap_object_cb(sub_805EAC8, sub_805EAEC, gUnknown_08375498);
+
+u8 sub_805EB0C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_083754A4, 4);
+ if (mapObject->mapobj_unk_21 == 1 && mapObject->coords1.y == mapObject->coords2.y)
+ {
+ mapObject->mapobj_unk_21 = 2;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+}
+
+fieldmap_object_cb(sub_805EB54, sub_805EB78, gUnknown_083754A8);
+
+u8 sub_805EB98(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_083754B4, 4);
+ if (mapObject->mapobj_unk_21 == 1 && mapObject->coords1.x == mapObject->coords2.x)
+ {
+ mapObject->mapobj_unk_21 = 2;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+}
+
+fieldmap_object_cb(sub_805EBE0, sub_805EC04, gUnknown_083754B8);
+
+u8 sub_805EC24(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_083754C4, 4);
+ if (mapObject->mapobj_unk_21 == 2 && mapObject->coords1.x == mapObject->coords2.x)
+ {
+ mapObject->mapobj_unk_21 = 3;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+}
+
+fieldmap_object_cb(sub_805EC6C, sub_805EC90, gUnknown_083754C8);
+
+u8 sub_805ECB0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_083754D4, 4);
+ if (mapObject->mapobj_unk_21 == 2 && mapObject->coords1.y == mapObject->coords2.y)
+ {
+ mapObject->mapobj_unk_21 = 3;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+}
+
+fieldmap_object_cb(sub_805ECF8, sub_805ED1C, gUnknown_083754D8);
+
+u8 sub_805ED3C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_083754E4, 4);
+ if (mapObject->mapobj_unk_21 == 1 && mapObject->coords1.y == mapObject->coords2.y)
+ {
+ mapObject->mapobj_unk_21 = 2;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+}
+
+fieldmap_object_cb(sub_805ED84, sub_805EDA8, gUnknown_083754E8);
+
+u8 sub_805EDC8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_083754F4, 4);
+ if (mapObject->mapobj_unk_21 == 1 && mapObject->coords1.x == mapObject->coords2.x)
+ {
+ mapObject->mapobj_unk_21 = 2;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+}
+
+fieldmap_object_cb(sub_805EE10, sub_805EE34, gUnknown_083754F8);
+
+u8 sub_805EE54(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_08375504, 4);
+ if (mapObject->mapobj_unk_21 == 2 && mapObject->coords1.x == mapObject->coords2.x)
+ {
+ mapObject->mapobj_unk_21 = 3;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+}
+
+fieldmap_object_cb(sub_805EE9C, sub_805EEC0, gUnknown_08375508);
+
+u8 sub_805EEE0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_08375514, 4);
+ if (mapObject->mapobj_unk_21 == 2 && mapObject->coords1.y == mapObject->coords2.y)
+ {
+ mapObject->mapobj_unk_21 = 3;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+}
+
+fieldmap_object_cb(sub_805EF28, sub_805EF4C, gUnknown_08375518);
+
+u8 sub_805EF6C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_08375524, 4);
+ if (mapObject->mapobj_unk_21 == 2 && mapObject->coords1.y == mapObject->coords2.y)
+ {
+ mapObject->mapobj_unk_21 = 3;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+}
+
+fieldmap_object_cb(sub_805EFB4, sub_805EFD8, gUnknown_08375528);
+
+u8 sub_805EFF8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_08375534, 4);
+ if (mapObject->mapobj_unk_21 == 2 && mapObject->coords1.x == mapObject->coords2.x)
+ {
+ mapObject->mapobj_unk_21 = 3;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+}
+
+fieldmap_object_cb(sub_805F040, sub_805F064, gUnknown_08375538);
+
+u8 sub_805F084(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_08375544, 4);
+ if (mapObject->mapobj_unk_21 == 2 && mapObject->coords1.x == mapObject->coords2.x)
+ {
+ mapObject->mapobj_unk_21 = 3;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+}
+
+fieldmap_object_cb(sub_805F0CC, sub_805F0F0, gUnknown_08375548);
+
+u8 sub_805F110(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_08375554, 4);
+ if (mapObject->mapobj_unk_21 == 2 && mapObject->coords1.y == mapObject->coords2.y)
+ {
+ mapObject->mapobj_unk_21 = 3;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+}
+
+fieldmap_object_cb(sub_805F158, sub_805F17C, gUnknown_08375558);
+
+u8 sub_805F19C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_08375564, 4);
+ if (mapObject->mapobj_unk_21 == 2 && mapObject->coords1.y == mapObject->coords2.y)
+ {
+ mapObject->mapobj_unk_21 = 3;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+}
+
+fieldmap_object_cb(sub_805F1E4, sub_805F208, gUnknown_08375568);
+
+u8 sub_805F228(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_08375574, 4);
+ if (mapObject->mapobj_unk_21 == 2 && mapObject->coords1.x == mapObject->coords2.x)
+ {
+ mapObject->mapobj_unk_21 = 3;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+}
+
+fieldmap_object_cb(sub_805F270, sub_805F294, gUnknown_08375578);
+
+u8 sub_805F2B4(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 directions[4];
+ memcpy(directions, gUnknown_08375584, 4);
+ if (mapObject->mapobj_unk_21 == 2 && mapObject->coords1.x == mapObject->coords2.x)
+ {
+ mapObject->mapobj_unk_21 = 3;
+ }
+ return MoveFieldObjectInNextDirectionInSequence(mapObject, sprite, directions);
+};
+
+fieldmap_object_cb(sub_805F2FC, sub_805F320, gUnknown_08375588);
+
+u8 mss_npc_reset_oampriv3_1_unk2_unk3(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ if (mapObject->mapobj_unk_21 == 0)
+ {
+ mapObject->mapobj_unk_21 = player_get_direction_lower_nybble();
+ }
+ sprite->data1 = 1;
+ return 1;
+}
+
+u8 sub_805F364(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1C == 0xFF || gPlayerAvatar.running1 == 2)
+ {
+ return 0;
+ }
+ return gUnknown_08375594[player_get_x22()](mapObject, sprite, player_get_direction_upper_nybble(), NULL);
+}
+
+u8 sub_805F3C4(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_1 = 0;
+ sprite->data1 = 1;
+ }
+ return 0;
+}
+
+bool8 sub_805F3EC(struct MapObject *mapObject, struct Sprite *sprite, u8 a2, bool8 a3(u8))
+{
+ return 0;
+}
+
+bool8 sub_805F3F0(struct MapObject *mapObject, struct Sprite *sprite, u8 a2, bool8 a3(u8))
+{
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(state_to_direction(gUnknown_0836DC09[mapObject->animPattern], mapObject->mapobj_unk_21, a2)));
+ mapObject->mapobj_bit_1 = 1;
+ sprite->data1 = 2;
+ return 1;
+}
+
+bool8 sub_805F438(struct MapObject *mapObject, struct Sprite *sprite, u8 a2, bool8 a3(u8))
+{
+ u32 direction;
+ s16 x;
+ s16 y;
+
+ direction = a2;
+ direction = state_to_direction(gUnknown_0836DC09[mapObject->animPattern], mapObject->mapobj_unk_21, direction);
+ FieldObjectMoveDestCoords(mapObject, direction, &x, &y);
+ FieldObjectSetRegularAnim(mapObject, sprite, GetGoSpeed0AnimId(direction));
+ if (npc_block_way(mapObject, x, y, direction) || (a3 != NULL && !a3(MapGridGetMetatileBehaviorAt(x, y))))
+ {
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(direction));
+ }
+ mapObject->mapobj_bit_1 = 1;
+ sprite->data1 = 2;
+ return 1;
+}
+
+bool8 sub_805F4F0(struct MapObject *mapObject, struct Sprite *sprite, u8 playerDirection, bool8 tileCB(u8))
+{
+ u32 direction;
+ s16 x;
+ s16 y;
+
+ direction = playerDirection;
+ direction = state_to_direction(gUnknown_0836DC09[mapObject->animPattern], mapObject->mapobj_unk_21, direction);
+ FieldObjectMoveDestCoords(mapObject, direction, &x, &y);
+ FieldObjectSetRegularAnim(mapObject, sprite, sub_8060744(direction));
+ if (npc_block_way(mapObject, x, y, direction) || (tileCB != NULL && !tileCB(MapGridGetMetatileBehaviorAt(x, y))))
+ {
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(direction));
+ }
+ mapObject->mapobj_bit_1 = TRUE;
+ sprite->data1 = 2;
+ return TRUE;
+}
+
+bool8 sub_805F5A8(struct MapObject *mapObject, struct Sprite *sprite, u8 playerDirection, bool8 tileCB(u8))
+{
+ u32 direction;
+ s16 x;
+ s16 y;
+
+ direction = playerDirection;
+ direction = state_to_direction(gUnknown_0836DC09[mapObject->animPattern], mapObject->mapobj_unk_21, direction);
+ FieldObjectMoveDestCoords(mapObject, direction, &x, &y);
+ FieldObjectSetRegularAnim(mapObject, sprite, sub_806079C(direction));
+ if (npc_block_way(mapObject, x, y, direction) || (tileCB != NULL && !tileCB(MapGridGetMetatileBehaviorAt(x, y))))
+ {
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(direction));
+ }
+ mapObject->mapobj_bit_1 = TRUE;
+ sprite->data1 = 2;
+ return TRUE;
+}
+
+bool8 sub_805F660(struct MapObject *mapObject, struct Sprite *sprite, u8 playerDirection, bool8 tileCB(u8))
+{
+ u32 direction;
+ s16 x;
+ s16 y;
+
+ direction = playerDirection;
+ direction = state_to_direction(gUnknown_0836DC09[mapObject->animPattern], mapObject->mapobj_unk_21, direction);
+ FieldObjectMoveDestCoords(mapObject, direction, &x, &y);
+ FieldObjectSetRegularAnim(mapObject, sprite, sub_80607C8(direction));
+ if (npc_block_way(mapObject, x, y, direction) || (tileCB != NULL && !tileCB(MapGridGetMetatileBehaviorAt(x, y))))
+ {
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(direction));
+ }
+ mapObject->mapobj_bit_1 = TRUE;
+ sprite->data1 = 2;
+ return TRUE;
+}
+
+bool8 cph_IM_DIFFERENT(struct MapObject *mapObject, struct Sprite *sprite, u8 playerDirection, bool8 tileCB(u8))
+{
+ u32 direction;
+
+ direction = playerDirection;
+ direction = state_to_direction(gUnknown_0836DC09[mapObject->animPattern], mapObject->mapobj_unk_21, direction);
+ FieldObjectSetRegularAnim(mapObject, sprite, sub_806084C(direction));
+ mapObject->mapobj_bit_1 = TRUE;
+ sprite->data1 = 2;
+ return TRUE;
+}
+
+bool8 sub_805F760(struct MapObject *mapObject, struct Sprite *sprite, u8 playerDirection, bool8 tileCB(u8))
+{
+ u32 direction;
+ s16 x;
+ s16 y;
+
+ direction = playerDirection;
+ direction = state_to_direction(gUnknown_0836DC09[mapObject->animPattern], mapObject->mapobj_unk_21, direction);
+ FieldObjectMoveDestCoords(mapObject, direction, &x, &y);
+ FieldObjectSetRegularAnim(mapObject, sprite, sub_80608A4(direction));
+ if (npc_block_way(mapObject, x, y, direction) || (tileCB != NULL && !tileCB(MapGridGetMetatileBehaviorAt(x, y))))
+ {
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(direction));
+ }
+ mapObject->mapobj_bit_1 = TRUE;
+ sprite->data1 = 2;
+ return TRUE;
+}
+
+bool8 oac_hopping(struct MapObject *mapObject, struct Sprite *sprite, u8 playerDirection, bool8 tileCB(u8))
+{
+ u32 direction;
+ s16 x;
+ s16 y;
+
+ direction = playerDirection;
+ direction = state_to_direction(gUnknown_0836DC09[mapObject->animPattern], mapObject->mapobj_unk_21, direction);
+ x = mapObject->coords2.x;
+ y = mapObject->coords2.y;
+ sub_8060320(direction, &x, &y, 2, 2);
+ FieldObjectSetRegularAnim(mapObject, sprite, GetJumpLedgeAnimId(direction));
+ if (npc_block_way(mapObject, x, y, direction) || (tileCB != NULL && !tileCB(MapGridGetMetatileBehaviorAt(x, y))))
+ {
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(direction));
+ }
+ mapObject->mapobj_bit_1 = TRUE;
+ sprite->data1 = 2;
+ return TRUE;
+}
+
+fieldmap_object_cb(sub_805F8E0, sub_805F904, gUnknown_083755C0);
+
+u8 mss_08062EA4(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1C == 0xFF || gPlayerAvatar.running1 == 2)
+ {
+ return 0;
+ }
+ return gUnknown_08375594[player_get_x22()](mapObject, sprite, player_get_direction_upper_nybble(), MetatileBehavior_IsPokeGrass);
+}
+
+u8 sub_805F9F8(struct MapObject *, struct Sprite *);
+
+void FieldObjectCB_TreeDisguise(struct Sprite *sprite)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[sprite->data0];
+ if (mapObject->mapobj_unk_21 == 0 || (mapObject->mapobj_unk_21 == 1 && sprite->data7 == 0))
+ {
+ FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectArguments[0], (u8 *)&gFieldEffectArguments[1], (u8 *)&gFieldEffectArguments[2]);
+ mapObject->mapobj_unk_1A = FieldEffectStart(FLDEFF_TREE_DISGUISE);
+ mapObject->mapobj_unk_21 = 1;
+ sprite->data7 ++;
+ }
+ meta_step(&gMapObjects[sprite->data0], sprite, sub_805F9F8);
+}
+
+u8 sub_805F9F8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ return 0;
+}
+
+void FieldObjectCB_MountainDisguise(struct Sprite *sprite)
+{
+ struct MapObject *mapObject;
+ mapObject = &gMapObjects[sprite->data0];
+ if (mapObject->mapobj_unk_21 == 0 || (mapObject->mapobj_unk_21 == 1 && sprite->data7 == 0))
+ {
+ FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectArguments[0], (u8 *)&gFieldEffectArguments[1], (u8 *)&gFieldEffectArguments[2]);
+ mapObject->mapobj_unk_1A = FieldEffectStart(FLDEFF_MOUNTAIN_DISGUISE);
+ mapObject->mapobj_unk_21 = 1;
+ sprite->data7 ++;
+ }
+ meta_step(&gMapObjects[sprite->data0], sprite, sub_805F9F8);
+}
+
+u8 sub_805FAD8(struct MapObject *mapObject, struct Sprite *sprite);
+
+void FieldObjectCB_Hidden1(struct Sprite *sprite)
+{
+ if (sprite->data7 == 0)
+ {
+ gMapObjects[sprite->data0].mapobj_bit_26 = 1;
+ sprite->subspriteMode = 2;
+ sprite->oam.priority = 3;
+ sprite->data7 ++;
+ }
+ meta_step(&gMapObjects[sprite->data0], sprite, sub_805FAD8);
+}
+
+u8 sub_805FAD8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ return gUnknown_083755CC[sprite->data1](mapObject, sprite);
+}
+
+u8 sub_805FAF8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ return 0;
+}
+
+u8 sub_805FB04(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite))
+ {
+ sprite->data1 = 0;
+ }
+ return 0;
+}
+
+fieldmap_object_cb(sub_805FB20, sub_805FB44, gUnknown_083755D0);
+
+u8 sub_805FB64(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ FieldObjectSetRegularAnim(mapObject, sprite, GetStepInPlaceDelay16AnimId(mapObject->mapobj_unk_18));
+ sprite->data1 = 1;
+ return 1;
+}
+
+fieldmap_object_cb(sub_805FB90, sub_805FBB4, gUnknown_083755D8);
+
+u8 sub_805FBD4(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ FieldObjectSetRegularAnim(mapObject, sprite, GetStepInPlaceDelay8AnimId(mapObject->mapobj_unk_18));
+ sprite->data1 = 1;
+ return 1;
+}
+
+fieldmap_object_cb(sub_805FC00, sub_805FC24, gUnknown_083755E0);
+
+u8 sub_805FC44(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ FieldObjectSetRegularAnim(mapObject, sprite, GetStepInPlaceDelay4AnimId(mapObject->mapobj_unk_18));
+ sprite->data1 = 1;
+ return 1;
+}
+
+fieldmap_object_cb(sub_805FC70, sub_805FC94, gUnknown_083755E8);
+
+u8 sub_805FCB4(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_reset(mapObject, sprite);
+ FieldObjectSetRegularAnim(mapObject, sprite, GetFaceDirectionAnimId(mapObject->mapobj_unk_18));
+ mapObject->mapobj_bit_13 = 1;
+ sprite->data1 = 1;
+ return 1;
+}
+
+u8 sub_805FCE8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (FieldObjectExecRegularAnim(mapObject, sprite))
+ {
+ sprite->data1 = 2;
+ return 1;
+ }
+ return 0;
+}
+
+u8 sub_805FD08(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ mapObject->mapobj_bit_1 = 0;
+ return 0;
+}
+
+void sub_805FC70(struct Sprite *sprite);
+
+void npc_reset(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ mapObject->mapobj_bit_1 = 0;
+ mapObject->mapobj_bit_6 = 0;
+ mapObject->mapobj_bit_7 = 0;
+ mapObject->mapobj_unk_1C = 0xff;
+ sprite->data1 = 0;
+}
+
+u8 FieldObjectDirectionToImageAnimId(u8 direction)
+{
+ return gUnknown_083755F4[direction];
+}
+
+u8 get_go_image_anim_num(u8 direction)
+{
+ return gUnknown_083755FD[direction];
+}
+
+u8 get_go_fast_image_anim_num(u8 direction)
+{
+ return gUnknown_08375606[direction];
+}
+
+u8 get_go_faster_image_anim_num(u8 direction)
+{
+ return gUnknown_0837560F[direction];
+}
+
+u8 sub_805FD78(u8 direction)
+{
+ return gUnknown_08375618[direction];
+}
+
+u8 sub_805FD88(u8 direction)
+{
+ return gUnknown_08375621[direction];
+}
+
+u8 sub_805FD98(u8 direction)
+{
+ return gUnknown_0837562A[direction];
+}
+
+u8 unref_sub_805FDA8(u8 direction)
+{
+ return gUnknown_08375633[direction];
+}
+
+u8 sub_805FDB8(u8 direction)
+{
+ return gUnknown_0837563C[direction];
+}
+
+u8 sub_805FDC8(u8 direction)
+{
+ return gUnknown_08375645[direction];
+}
+
+u8 sub_805FDD8(u8 direction)
+{
+ return gUnknown_0837564E[direction];
+}
+
+u8 sub_805FDE8(u8 direction)
+{
+ return gUnknown_08375657[direction];
+}
+
+u8 sub_805FDF8(u8 direction)
+{
+ return gUnknown_08375660[direction];
+}
+
+u8 sub_805FE08(u8 direction)
+{
+ return gUnknown_08375669[direction];
+}
+
+u8 get_run_image_anim_num(u8 direction)
+{
+ return gUnknown_08375672[direction];
+}
+
+void sub_805FE28(struct MapObject *mapObject, struct Sprite *sprite, u8 animNum)
+{
+ if (!mapObject->mapobj_bit_12)
+ {
+ sprite->animNum = animNum;
+ if (sprite->animCmdIndex == 1)
+ {
+ sprite->animCmdIndex = 2;
+ } else if (sprite->animCmdIndex == 3)
+ {
+ sprite->animCmdIndex = 0;
+ }
+ SeekSpriteAnim(sprite, sprite->animCmdIndex);
+ }
+}
+
+void sub_805FE64(struct MapObject *mapObject, struct Sprite *sprite, u8 animNum)
+{
+ u8 animCmdIndex;
+ if (!mapObject->mapobj_bit_12)
+ {
+ sprite->animNum = animNum;
+ animCmdIndex = 3;
+ if (sprite->animCmdIndex < 2)
+ {
+ animCmdIndex = 1;
+ }
+ SeekSpriteAnim(sprite, animCmdIndex);
+ }
+}
+
+u8 sub_805FE90(s16 a0, s16 a1, s16 a2, s16 a3)
+{
+ if (a0 > a2)
+ {
+ return DIR_WEST;
+ } else if (a0 < a2)
+ {
+ return DIR_EAST;
+ } else if (a1 > a3)
+ {
+ return DIR_NORTH;
+ } else
+ {
+ return DIR_SOUTH;
+ }
+}
+
+void npc_set_running_behaviour_etc(struct MapObject *mapObject, u8 animPattern)
+{
+ mapObject->animPattern = animPattern;
+ mapObject->mapobj_unk_21 = 0;
+ mapObject->animId = 0;
+ gSprites[mapObject->spriteId].callback = gUnknown_0836DA88[animPattern];
+ gSprites[mapObject->spriteId].data1 = 0;
+}
+
+u8 npc_running_behaviour_by_direction(u8 direction)
+{
+ return gUnknown_0837567B[direction];
+}
+
+u8 sub_805FF20(struct MapObject *mapObject, u8 direction)
+{
+ s16 x;
+ s16 y;
+ x = mapObject->coords2.x;
+ y = mapObject->coords2.y;
+ MoveCoords(direction, &x, &y);
+ return npc_block_way(mapObject, x, y, direction);
+}
+
+bool8 IsCoordOutsideFieldObjectMovementRect(struct MapObject2 *mapObject, s16 x, s16 y);
+static bool8 DoesObjectCollideWithObjectAt(struct MapObject *mapObject, s16 x, s16 y);
+bool8 IsMetatileDirectionallyImpassable(struct MapObject *mapObject, s16 x, s16 y, u8 direction);
+
+u8 npc_block_way(struct MapObject *mapObject, s16 x, s16 y, u32 dirn)
+{
+ u8 direction;
+ direction = dirn;
+ if (IsCoordOutsideFieldObjectMovementRect((struct MapObject2 *)mapObject, x, y))
+ return 1;
+ else if (MapGridIsImpassableAt(x, y) || GetMapBorderIdAt(x, y) == -1 || IsMetatileDirectionallyImpassable(mapObject, x, y, direction))
+ return 2;
+ else if (mapObject->mapobj_bit_15 && !CanCameraMoveInDirection(direction))
+ return 2;
+ else if (IsZCoordMismatchAt(mapObject->mapobj_unk_0B_0, x, y))
+ return 3;
+ else if (DoesObjectCollideWithObjectAt(mapObject, x, y))
+ return 4;
+ return 0;
+}
+
+u8 sub_8060024(struct MapObject *mapObject, s16 x, s16 y, u8 direction)
+{
+ u8 flags = 0;
+
+ if (IsCoordOutsideFieldObjectMovementRect((struct MapObject2 *)mapObject, x, y))
+ flags |= 1;
+ if (MapGridIsImpassableAt(x, y) || GetMapBorderIdAt(x, y) == -1 || IsMetatileDirectionallyImpassable(mapObject, x, y, direction) || (mapObject->mapobj_bit_15 && !CanCameraMoveInDirection(direction)))
+ flags |= 2;
+ if (IsZCoordMismatchAt(mapObject->mapobj_unk_0B_0, x, y))
+ flags |= 4;
+ if (DoesObjectCollideWithObjectAt(mapObject, x, y))
+ flags |= 8;
+ return flags;
+}
+
+bool8 IsCoordOutsideFieldObjectMovementRect(struct MapObject2 *mapObject, s16 x, s16 y)
+{
+ s16 minv;
+ s16 maxv;
+
+ if (mapObject->mapobj_unk_19 != 0)
+ {
+ minv = mapObject->coords1.x - (mapObject->mapobj_unk_19);
+ maxv = mapObject->coords1.x + (mapObject->mapobj_unk_19);
+ if (minv > x || maxv < x)
+ return TRUE;
+ }
+ if (mapObject->mapobj_unk_19b != 0)
+ {
+ minv = mapObject->coords1.y - (mapObject->mapobj_unk_19b);
+ maxv = mapObject->coords1.y + (mapObject->mapobj_unk_19b);
+ if (minv > y || maxv < y)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 IsMetatileDirectionallyImpassable(struct MapObject *mapObject, s16 x, s16 y, u8 direction)
+{
+ if (gUnknown_08375684[direction - 1](mapObject->mapobj_unk_1E) || gUnknown_08375694[direction - 1](MapGridGetMetatileBehaviorAt(x, y)))
+ {
+ return 1;
+ }
+ return 0;
+}
+
+static bool8 DoesObjectCollideWithObjectAt(struct MapObject *mapObject, s16 x, s16 y)
+{
+ u8 i;
+
+ for (i = 0; i < 16; i++)
+ {
+ struct MapObject *mapObject2 = &gMapObjects[i];
+
+ if (mapObject2->active && mapObject2 != mapObject)
+ {
+ if (((mapObject2->coords2.x == x && mapObject2->coords2.y == y) || (mapObject2->coords3.x == x && mapObject2->coords3.y == y))
+ && AreZCoordsCompatible(mapObject->mapobj_unk_0B_0, mapObject2->mapobj_unk_0B_0))
+ return TRUE;
+ }
+ }
+ return 0;
+}
+
+bool8 sub_8060234(u8 localId, u8 mapNum, u8 mapGroup)
+{
+ u8 mapObjectId;
+ if (!TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId))
+ {
+ if (gSprites[gMapObjects[mapObjectId].spriteId].data7 & 2)
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void sub_8060288(u8 localId, u8 mapNum, u8 mapGroup)
+{
+ u8 mapObjectId;
+ if (!TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjectId))
+ {
+ gSprites[gMapObjects[mapObjectId].spriteId].data7 |= 4;
+ }
+}
+
+void MoveCoords(u8 direction, s16 *x, s16 *y)
+{
+ *x += gDirectionToVector[direction].x;
+ *y += gDirectionToVector[direction].y;
+}
+
+void unref_sub_80602F8(u8 direction, s16 *x, s16 *y)
+{
+ *x += gDirectionToVector[direction].x << 4;
+ *y += gDirectionToVector[direction].y << 4;
+}
+
+void sub_8060320(u32 dirn, s16 *x, s16 *y, s16 deltaX, s16 deltaY)
+{
+ u8 direction = dirn;
+ s16 dx2 = deltaX;
+ s16 dy2 = deltaY;
+ if (gDirectionToVector[direction].x > 0)
+ {
+ *x += dx2;
+ }
+ if (gDirectionToVector[direction].x < 0)
+ {
+ *x -= dx2;
+ }
+ if (gDirectionToVector[direction].y > 0)
+ {
+ *y += dy2;
+ }
+ if (gDirectionToVector[direction].y < 0)
+ {
+ *y -= dy2;
+ }
+}
+
+void sub_8060388(s16 x1, s16 y1, s16 *x2, s16 *y2)
+{
+ *x2 = (x1 - gSaveBlock1.pos.x) << 4;
+ *y2 = (y1 - gSaveBlock1.pos.y) << 4;
+ *x2 -= gUnknown_0300489C;
+ *y2 -= gUnknown_03004898;
+}
+
+void sub_80603CC(s16 x1, s16 y1, s16 *x2, s16 *y2)
+{
+ s16 x3;
+ s16 y3;
+ x3 = -gUnknown_0300489C - gUnknown_03004880.unk10;
+ y3 = -gUnknown_03004898 - gUnknown_03004880.unk14;
+ if (gUnknown_03004880.unk10 > 0)
+ {
+ x3 += 0x10;
+ }
+ if (gUnknown_03004880.unk10 < 0)
+ {
+ x3 -= 0x10;
+ }
+ if (gUnknown_03004880.unk14 > 0)
+ {
+ y3 += 0x10;
+ }
+ if (gUnknown_03004880.unk14 < 0)
+ {
+ y3 -= 0x10;
+ }
+ *x2 = ((x1 - gSaveBlock1.pos.x) << 4) + x3;
+ *y2 = ((y1 - gSaveBlock1.pos.y) << 4) + y3;
+}
+
+void sub_8060470(s16 *x, s16 *y, s16 dx, s16 dy)
+{
+ sub_80603CC(*x, *y, x, y);
+ *x += dx;
+ *y += dy;
+}
+
+void GetFieldObjectMovingCameraOffset(s16 *x, s16 *y)
+{
+ *x = 0;
+ *y = 0;
+ if (gUnknown_03004880.unk10 > 0)
+ {
+ (*x)++;
+ }
+ if (gUnknown_03004880.unk10 < 0)
+ {
+ (*x)--;
+ }
+ if (gUnknown_03004880.unk14 > 0)
+ {
+ (*y)++;
+ }
+ if (gUnknown_03004880.unk14 < 0)
+ {
+ (*y)--;
+ }
+}
+
+void FieldObjectMoveDestCoords(struct MapObject *mapObject, u32 direction, s16 *x, s16 *y)
+{
+ u8 newDirn = direction;
+ *x = mapObject->coords2.x;
+ *y = mapObject->coords2.y;
+ MoveCoords(newDirn, x, y);
+}
+
+bool8 FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(struct MapObject *mapObject)
+{
+ if (mapObject->mapobj_bit_1 || mapObject->mapobj_bit_6)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 FieldObjectIsSpecialAnimActive(struct MapObject *mapObject)
+{
+ if (mapObject->mapobj_bit_6 && mapObject->mapobj_unk_1C != 0xff)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 FieldObjectSetSpecialAnim(struct MapObject *mapObject, u8 specialAnimId)
+{
+ if (FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(mapObject))
+ {
+ return TRUE;
+ }
+ UnfreezeMapObject(mapObject);
+ mapObject->mapobj_unk_1C = specialAnimId;
+ mapObject->mapobj_bit_6 = 1;
+ mapObject->mapobj_bit_7 = 0;
+ gSprites[mapObject->spriteId].data2 = 0;
+ return FALSE;
+}
+
+void FieldObjectForceSetSpecialAnim(struct MapObject *mapObject, u8 specialAnimId)
+{
+ FieldObjectClearAnimIfSpecialAnimActive(mapObject);
+ FieldObjectSetSpecialAnim(mapObject, specialAnimId);
+}
+
+void FieldObjectClearAnimIfSpecialAnimActive(struct MapObject *mapObject)
+{
+ if (mapObject->mapobj_bit_6)
+ {
+ FieldObjectClearAnim(mapObject);
+ }
+}
+
+void FieldObjectClearAnim(struct MapObject *mapObject)
+{
+ mapObject->mapobj_unk_1C = 0xFF;
+ mapObject->mapobj_bit_6 = 0;
+ mapObject->mapobj_bit_7 = 0;
+ gSprites[mapObject->spriteId].data1 = 0;
+ gSprites[mapObject->spriteId].data2 = 0;
+}
+
+bool8 FieldObjectCheckIfSpecialAnimFinishedOrInactive(struct MapObject *mapObject)
+{
+ if (mapObject->mapobj_bit_6)
+ return mapObject->mapobj_bit_7;
+ return 0x10;
+}
+
+bool8 FieldObjectClearAnimIfSpecialAnimFinished(struct MapObject *mapObject)
+{
+ u8 specialAnimStatus;
+ specialAnimStatus = FieldObjectCheckIfSpecialAnimFinishedOrInactive(mapObject);
+ if (specialAnimStatus != 0 && specialAnimStatus != 0x10)
+ {
+ FieldObjectClearAnimIfSpecialAnimActive(mapObject);
+ }
+ return specialAnimStatus;
+}
+
+u8 FieldObjectGetSpecialAnim(struct MapObject *mapObject)
+{
+ if (mapObject->mapobj_bit_6)
+ {
+ return mapObject->mapobj_unk_1C;
+ }
+ return 0xFF;
+}
+
+extern void DoGroundEffects_OnSpawn(struct MapObject *mapObject, struct Sprite *sprite);
+extern void DoGroundEffects_OnBeginStep(struct MapObject *mapObject, struct Sprite *sprite);
+extern void DoGroundEffects_OnFinishStep(struct MapObject *mapObject, struct Sprite *sprite);
+void npc_obj_transfer_image_anim_pause_flag(struct MapObject *mapObject, struct Sprite *sprite);
+void sub_80634A0(struct MapObject *mapObject, struct Sprite *sprite);
+void FieldObjectExecSpecialAnim(struct MapObject *mapObject, struct Sprite *sprite);
+void FieldObjectUpdateSubpriority(struct MapObject *mapObject, struct Sprite *sprite);
+
+void meta_step(struct MapObject *mapObject, struct Sprite *sprite, u8 (*callback)(struct MapObject *, struct Sprite *))
+{
+ DoGroundEffects_OnSpawn(mapObject, sprite);
+ sub_80634A0(mapObject, sprite);
+ if (FieldObjectIsSpecialAnimActive(mapObject))
+ {
+ FieldObjectExecSpecialAnim(mapObject, sprite);
+ } else
+ {
+ if (!mapObject->mapobj_bit_8)
+ {
+ while (callback(mapObject, sprite));
+ }
+ }
+ DoGroundEffects_OnBeginStep(mapObject, sprite);
+ DoGroundEffects_OnFinishStep(mapObject, sprite);
+ npc_obj_transfer_image_anim_pause_flag(mapObject, sprite);
+ sub_80634D0(mapObject, sprite);
+ FieldObjectUpdateSubpriority(mapObject, sprite);
+}
+
+#define dirn_to_anim(name, table)\
+u8 name(u32 idx)\
+{\
+ u8 direction;\
+ u8 animIds[sizeof(table)];\
+ direction = idx;\
+ memcpy(animIds, (table), sizeof(table));\
+ if (direction > DIR_EAST) direction = 0;\
+ return animIds[direction];\
+}
+
+dirn_to_anim(GetFaceDirectionAnimId, gUnknown_083756C8)
+dirn_to_anim(GetSimpleGoAnimId, gUnknown_083756CD)
+dirn_to_anim(GetGoSpeed0AnimId, gUnknown_083756D2)
+dirn_to_anim(sub_8060744, gUnknown_083756D7)
+dirn_to_anim(d2s_08064034, gUnknown_083756DC)
+dirn_to_anim(sub_806079C, gUnknown_083756E1)
+dirn_to_anim(sub_80607C8, gUnknown_083756E6)
+dirn_to_anim(sub_80607F4, gUnknown_083756EB)
+dirn_to_anim(GetJumpLedgeAnimId, gUnknown_083756F0)
+dirn_to_anim(sub_806084C, gUnknown_083756F5)
+dirn_to_anim(sub_8060878, gUnknown_083756FA)
+dirn_to_anim(sub_80608A4, gUnknown_083756FF)
+dirn_to_anim(sub_80608D0, gUnknown_08375704)
+dirn_to_anim(GetStepInPlaceDelay32AnimId, gUnknown_08375709)
+dirn_to_anim(GetStepInPlaceDelay16AnimId, gUnknown_0837570E)
+dirn_to_anim(GetStepInPlaceDelay8AnimId, gUnknown_08375713)
+dirn_to_anim(GetStepInPlaceDelay4AnimId, gUnknown_08375718)
+
+u8 FieldObjectFaceOppositeDirection(struct MapObject *mapObject, u8 direction)
+{
+ return FieldObjectSetSpecialAnim(mapObject, GetFaceDirectionAnimId(GetOppositeDirection(direction)));
+}
+
+u8 sub_80609D8(u8 index)
+{
+ u8 directions[5];
+ memcpy(directions, gUnknown_0837571D, 5);
+ if (index >= 5)
+ {
+ index = 0;
+ }
+ return directions[index];
+}
+
+u8 sub_8060A04(u8 index)
+{
+ u8 directions[5];
+ memcpy(directions, gUnknown_08375722, 5);
+ if (index >= 5)
+ {
+ index = 0;
+ }
+ return directions[index];
+}
+
+u8 sub_8060A30(u8 index)
+{
+ u8 directions[5];
+ memcpy(directions, gUnknown_08375727, 5);
+ if (index >= 5)
+ {
+ index = 0;
+ }
+ return directions[index];
+}
+
+u8 sub_8060A5C(u8 index)
+{
+ u8 directions[5];
+ memcpy(directions, gUnknown_0837572C, 5);
+ if (index >= 5)
+ {
+ index = 0;
+ }
+ return directions[index];
+}
+
+u8 sub_8060A88(u8 index)
+{
+ u8 directions[5];
+ memcpy(directions, gUnknown_08375731, 5);
+ if (index >= 5)
+ {
+ index = 0;
+ }
+ return directions[index];
+}
+
+u8 sub_8060AB4(u8 index)
+{
+ u8 directions[5];
+ memcpy(directions, gUnknown_08375736, 5);
+ if (index >= 5)
+ {
+ index = 0;
+ }
+ return directions[index];
+}
+
+u8 sub_8060AE0(u8 index)
+{
+ u8 directions[5];
+ memcpy(directions, gUnknown_0837573B, 5);
+ if (index >= 5)
+ {
+ index = 0;
+ }
+ return directions[index];
+}
+
+u8 sub_8060B0C(u8 index)
+{
+ u8 directions[5];
+ memcpy(directions, gUnknown_08375740, 5);
+ if (index >= 5)
+ {
+ index = 0;
+ }
+ return directions[index];
+}
+
+u8 sub_8060B38(u8 index)
+{
+ u8 directions[5];
+ memcpy(directions, gUnknown_08375745, 5);
+ if (index >= 5)
+ {
+ index = 0;
+ }
+ return directions[index];
+}
+
+u8 sub_8060B64(u8 index)
+{
+ u8 directions[5];
+ memcpy(directions, gUnknown_0837574A, 5);
+ if (index >= 5)
+ {
+ index = 0;
+ }
+ return directions[index];
+}
+
+u8 GetOppositeDirection(u8 direction)
+{
+ u8 directions[8];
+ memcpy(directions, gUnknown_0837574F, 8);
+ if (direction == 0 || direction > 8)
+ {
+ return direction;
+ }
+ return directions[direction - 1];
+}
+
+u32 zffu_offset_calc(u8 a0, u8 a1)
+{
+ return gUnknown_08375757[a0 - 1][a1 - 1];
+}
+
+u32 state_to_direction(u8 a0, u32 a1, u32 a2)
+{
+ u32 zffuOffset;
+ u8 a1_2 = a1;
+ u8 a2_2 = a2;
+ if (a1_2 == 0 || a2_2 == 0 || a1_2 > DIR_EAST || a2_2 > DIR_EAST)
+ {
+ return 0;
+ }
+ zffuOffset = zffu_offset_calc(a1_2, a2);
+ return gUnknown_08375767[a0 - 1][zffuOffset - 1];
+}
+
+void FieldObjectExecSpecialAnim(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (gUnknown_08375778[mapObject->mapobj_unk_1C][sprite->data2](mapObject, sprite))
+ {
+ mapObject->mapobj_bit_7 = 1;
+ }
+}
+
+bool8 FieldObjectExecRegularAnim(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (gUnknown_08375778[mapObject->mapobj_unk_1C][sprite->data2](mapObject, sprite))
+ {
+ mapObject->mapobj_unk_1C = 0xFF;
+ sprite->data2 = 0;
+ return 1;
+ }
+ return 0;
+}
+
+void FieldObjectSetRegularAnim(struct MapObject *mapObject, struct Sprite *sprite, u8 animId)
+{
+ mapObject->mapobj_unk_1C = animId;
+ sprite->data2 = 0;
+}
+
+void an_look_any(struct MapObject *mapObject, struct Sprite *sprite, u8 direction)
+{
+ FieldObjectSetDirection(mapObject, direction);
+ npc_coords_shift_still(mapObject);
+ sub_805FE64(mapObject, sprite, get_go_image_anim_num(mapObject->mapobj_unk_18));
+ sprite->animPaused = 1;
+ sprite->data2 = 1;
+}
+
+u8 sub_8060CE0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ an_look_any(mapObject, sprite, DIR_SOUTH);
+ return 1;
+}
+
+u8 sub_8060CF0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ an_look_any(mapObject, sprite, DIR_NORTH);
+ return 1;
+}
+
+u8 sub_8060D00(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ an_look_any(mapObject, sprite, DIR_WEST);
+ return 1;
+}
+
+u8 sub_8060D10(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ an_look_any(mapObject, sprite, DIR_EAST);
+ return 1;
+}
+
+void sub_8060D20(struct MapObject *mapObject, struct Sprite *sprite, u8 direction, u8 a3)
+{
+ s16 x;
+ s16 y;
+ x = mapObject->coords2.x;
+ y = mapObject->coords2.y;
+ FieldObjectSetDirection(mapObject, direction);
+ MoveCoords(direction, &x, &y);
+ npc_coords_shift(mapObject, x, y);
+ oamt_npc_ministep_reset(sprite, direction, a3);
+ sprite->animPaused = 0;
+ mapObject->mapobj_bit_2 = 1;
+ sprite->data2 = 1;
+}
+
+extern u8 (*const gUnknown_083759C0[5])(u8);
+
+void do_go_anim(struct MapObject *mapObject, struct Sprite *sprite, u8 direction, u8 a3)
+{
+ u8 (*const functions[5])(u8);
+ memcpy((void *)functions, gUnknown_083759C0, sizeof(gUnknown_083759C0));
+ sub_8060D20(mapObject, sprite, direction, a3);
+ sub_805FE28(mapObject, sprite, functions[a3](mapObject->mapobj_unk_18));
+}
+
+void do_run_anim(struct MapObject *mapObject, struct Sprite *sprite, u8 direction)
+{
+ sub_8060D20(mapObject, sprite, direction, 1);
+ sub_805FE28(mapObject, sprite, get_run_image_anim_num(mapObject->mapobj_unk_18));
+}
+
+bool8 obj_npc_ministep(struct Sprite *);
+
+bool8 npc_obj_ministep_stop_on_arrival(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (obj_npc_ministep(sprite))
+ {
+ npc_coords_shift_still(mapObject);
+ mapObject->mapobj_bit_3 = 1;
+ sprite->animPaused = 1;
+ return 1;
+ }
+ return 0;
+}
+
+void sub_8060E68(struct MapObject *mapObject, struct Sprite *sprite, u8 direction)
+{
+ s16 x;
+ s16 y;
+ x = mapObject->coords2.x;
+ y = mapObject->coords2.y;
+ FieldObjectSetDirection(mapObject, direction);
+ MoveCoords(direction, &x, &y);
+ npc_coords_shift(mapObject, x, y);
+ sub_806467C(sprite, direction);
+ sprite->animPaused = 0;
+ mapObject->mapobj_bit_2 = 1;
+ sprite->data2 = 1;
+}
+
+void sub_8060ED8(struct MapObject *mapObject, struct Sprite *sprite, u8 direction)
+{
+ sub_8060E68(mapObject, sprite, direction);
+ sub_805FE28(mapObject, sprite, get_go_image_anim_num(mapObject->mapobj_unk_18));
+}
+
+bool8 an_walk_any_2(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_806468C(sprite))
+ {
+ npc_coords_shift_still(mapObject);
+ mapObject->mapobj_bit_3 = 1;
+ sprite->animPaused = 1;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8060F5C(struct MapObject *, struct Sprite *);
+
+bool8 sub_8060F3C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8060ED8(mapObject, sprite, DIR_SOUTH);
+ return sub_8060F5C(mapObject, sprite);
+}
+
+bool8 sub_8060F5C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (an_walk_any_2(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8060F9C(struct MapObject *, struct Sprite *);
+
+bool8 sub_8060F7C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8060ED8(mapObject, sprite, DIR_NORTH);
+ return sub_8060F9C(mapObject, sprite);
+}
+
+bool8 sub_8060F9C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (an_walk_any_2(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8060FDC(struct MapObject *, struct Sprite *);
+
+bool8 sub_8060FBC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8060ED8(mapObject, sprite, DIR_WEST);
+ return sub_8060FDC(mapObject, sprite);
+}
+
+bool8 sub_8060FDC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (an_walk_any_2(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_806101C(struct MapObject *, struct Sprite *);
+
+bool8 sub_8060FFC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8060ED8(mapObject, sprite, DIR_EAST);
+ return sub_806101C(mapObject, sprite);
+}
+
+bool8 sub_806101C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (an_walk_any_2(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_806105C(struct MapObject *, struct Sprite *);
+
+bool8 sub_806103C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_go_anim(mapObject, sprite, DIR_SOUTH, 0);
+ return sub_806105C(mapObject, sprite);
+}
+
+bool8 sub_806105C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_806109C(struct MapObject *, struct Sprite *);
+
+bool8 sub_806107C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_go_anim(mapObject, sprite, DIR_NORTH, 0);
+ return sub_806109C(mapObject, sprite);
+}
+
+bool8 sub_806109C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_80610DC(struct MapObject *, struct Sprite *);
+
+bool8 sub_80610BC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_go_anim(mapObject, sprite, DIR_WEST, 0);
+ return sub_80610DC(mapObject, sprite);
+}
+
+bool8 sub_80610DC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_806111C(struct MapObject *, struct Sprite *);
+
+bool8 sub_80610FC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_go_anim(mapObject, sprite, DIR_EAST, 0);
+ return sub_806111C(mapObject, sprite);
+}
+
+bool8 sub_806111C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void sub_806113C(struct MapObject *mapObject, struct Sprite *sprite, u8 direction, u8 a4, u8 a5)
+{
+ s16 vSPp4[3];
+ s16 x;
+ s16 y;
+ memcpy(vSPp4, gUnknown_08375A34, sizeof gUnknown_08375A34);
+ x = 0;
+ y = 0;
+ FieldObjectSetDirection(mapObject, direction);
+ sub_8060320(direction, &x, &y, vSPp4[a4], vSPp4[a4]);
+ npc_coords_shift(mapObject, mapObject->coords2.x + x, mapObject->coords2.y + y);
+ sub_80646E4(sprite, direction, a4, a5);
+ sprite->data2 = 1;
+ sprite->animPaused = 0;
+ mapObject->mapobj_bit_2 = 1;
+ mapObject->mapobj_bit_4 = 1;
+}
+
+void maybe_shadow_1(struct MapObject *mapObject, struct Sprite *sprite, u8 direction, u8 a4, u8 a5)
+{
+ sub_806113C(mapObject, sprite, direction, a4, a5);
+ sub_805FE28(mapObject, sprite, get_go_image_anim_num(mapObject->mapobj_unk_18));
+ DoShadowFieldEffect(mapObject);
+}
+
+u8 sub_806123C(struct MapObject *mapObject, struct Sprite *sprite, u8 (*const callback)(struct Sprite *))
+{
+ s16 vSPp4[3];
+ s16 x;
+ s16 y;
+ u8 retval;
+ memcpy(vSPp4, gUnknown_08375A3A, sizeof gUnknown_08375A3A);
+ retval = callback(sprite);
+ if (retval == 1 && vSPp4[sprite->data4] != 0)
+ {
+ x = 0;
+ y = 0;
+ sub_8060320(mapObject->placeholder18, &x, &y, vSPp4[sprite->data4], vSPp4[sprite->data4]);
+ npc_coords_shift(mapObject, mapObject->coords2.x + x, mapObject->coords2.y + y);
+ mapObject->mapobj_bit_2 = 1;
+ mapObject->mapobj_bit_4 = 1;
+ } else if (retval == 0xff)
+ {
+ npc_coords_shift_still(mapObject);
+ mapObject->mapobj_bit_3 = 1;
+ mapObject->mapobj_bit_5 = 1;
+ sprite->animPaused = 1;
+ }
+ return retval;
+}
+
+u8 sub_8061300(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ return sub_806123C(mapObject, sprite, sub_8064704);
+}
+
+u8 sub_8061314(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ return sub_806123C(mapObject, sprite, sub_806478C);
+}
+
+bool8 sub_8061328(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061300(mapObject, sprite) == 0xFF)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8061340(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061314(mapObject, sprite) == 0xFF)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8061358(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 retval;
+
+ retval = sub_8061300(mapObject, sprite);
+ if (retval != 1)
+ {
+ if (retval == 0xFF)
+ {
+ return TRUE;
+ }
+ return FALSE;
+ }
+ FieldObjectSetDirection(mapObject, GetOppositeDirection(mapObject->placeholder18));
+ sub_805FE64(mapObject, sprite, get_go_image_anim_num(mapObject->mapobj_unk_18));
+ return FALSE;
+}
+
+bool8 sub_80613D4(struct MapObject *, struct Sprite *);
+bool8 sub_806142C(struct MapObject *, struct Sprite *);
+bool8 sub_8061484(struct MapObject *, struct Sprite *);
+bool8 sub_80614DC(struct MapObject *, struct Sprite *);
+
+bool8 sub_80613A8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ maybe_shadow_1(mapObject, sprite, DIR_SOUTH, 2, 0);
+ return sub_80613D4(mapObject, sprite);
+}
+
+bool8 sub_80613D4(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8061400(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ maybe_shadow_1(mapObject, sprite, DIR_NORTH, 2, 0);
+ return sub_806142C(mapObject, sprite);
+}
+
+bool8 sub_806142C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8061458(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ maybe_shadow_1(mapObject, sprite, DIR_WEST, 2, 0);
+ return sub_8061484(mapObject, sprite);
+}
+
+bool8 sub_8061484(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_80614B0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ maybe_shadow_1(mapObject, sprite, DIR_EAST, 2, 0);
+ return sub_80614DC(mapObject, sprite);
+}
+
+bool8 sub_80614DC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void sub_8061508(struct Sprite *sprite, u16 duration)
+{
+ sprite->data2 = 1;
+ sprite->data3 = duration;
+}
+
+bool8 sub_8061510(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sprite->data3--;
+ if (!sprite->data3)
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_806152C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8061508(sprite, 1);
+ return sub_8061510(mapObject, sprite);
+}
+
+bool8 sub_806154C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8061508(sprite, 2);
+ return sub_8061510(mapObject, sprite);
+}
+
+bool8 sub_806156C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8061508(sprite, 4);
+ return sub_8061510(mapObject, sprite);
+}
+
+bool8 sub_806158C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8061508(sprite, 8);
+ return sub_8061510(mapObject, sprite);
+}
+
+bool8 sub_80615AC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8061508(sprite, 16);
+ return sub_8061510(mapObject, sprite);
+}
+
+bool8 sub_80615EC(struct MapObject *mapObject, struct Sprite *sprite);
+bool8 sub_806162C(struct MapObject *mapObject, struct Sprite *sprite);
+bool8 sub_806166C(struct MapObject *mapObject, struct Sprite *sprite);
+bool8 sub_80616AC(struct MapObject *mapObject, struct Sprite *sprite);
+
+bool8 sub_80615CC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_go_anim(mapObject, sprite, DIR_SOUTH, 1);
+ return sub_80615EC(mapObject, sprite);
+}
+
+bool8 sub_80615EC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+bool8 sub_806160C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_go_anim(mapObject, sprite, DIR_NORTH, 1);
+ return sub_806162C(mapObject, sprite);
+}
+
+bool8 sub_806162C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+bool8 sub_806164C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_go_anim(mapObject, sprite, DIR_WEST, 1);
+ return sub_806166C(mapObject, sprite);
+}
+
+bool8 sub_806166C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+bool8 sub_806168C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_go_anim(mapObject, sprite, DIR_EAST, 1);
+ return sub_80616AC(mapObject, sprite);
+}
+
+bool8 sub_80616AC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void sub_80616CC(struct MapObject *mapObject, struct Sprite *sprite, u8 direction, u8 animId, u16 duration)
+{
+ FieldObjectSetDirection(mapObject, direction);
+ sub_805FE28(mapObject, sprite, animId);
+ sprite->animPaused = 0;
+ sprite->data2 = 1;
+ sprite->data3 = duration;
+}
+
+bool8 sub_8061714(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sprite->data3--;
+ if (sprite->data3 == 0)
+ {
+ sprite->data2 = 2;
+ sprite->animPaused = 1;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_806173C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sprite->data3 & 1)
+ {
+ sprite->animDelayCounter++;
+ }
+ return sub_8061714(mapObject, sprite);
+}
+
+bool8 sub_8061778(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80616CC(mapObject, sprite, DIR_SOUTH, get_go_image_anim_num(DIR_SOUTH), 32);
+ return sub_806173C(mapObject, sprite);
+}
+
+bool8 sub_80617B0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80616CC(mapObject, sprite, DIR_NORTH, get_go_image_anim_num(DIR_NORTH), 32);
+ return sub_806173C(mapObject, sprite);
+}
+
+bool8 sub_80617E8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80616CC(mapObject, sprite, DIR_WEST, get_go_image_anim_num(DIR_WEST), 32);
+ return sub_806173C(mapObject, sprite);
+}
+
+bool8 sub_8061820(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80616CC(mapObject, sprite, DIR_EAST, get_go_image_anim_num(DIR_EAST), 32);
+ return sub_806173C(mapObject, sprite);
+}
+
+bool8 sub_8061858(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80616CC(mapObject, sprite, DIR_SOUTH, get_go_image_anim_num(DIR_SOUTH), 16);
+ return sub_8061714(mapObject, sprite);
+}
+
+bool8 sub_8061890(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80616CC(mapObject, sprite, DIR_NORTH, get_go_image_anim_num(DIR_NORTH), 16);
+ return sub_8061714(mapObject, sprite);
+}
+
+bool8 sub_80618C8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80616CC(mapObject, sprite, DIR_WEST, get_go_image_anim_num(DIR_WEST), 16);
+ return sub_8061714(mapObject, sprite);
+}
+
+bool8 sub_8061900(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80616CC(mapObject, sprite, DIR_EAST, get_go_image_anim_num(DIR_EAST), 16);
+ return sub_8061714(mapObject, sprite);
+}
+
+bool8 sub_8061938(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80616CC(mapObject, sprite, DIR_SOUTH, get_go_fast_image_anim_num(DIR_SOUTH), 8);
+ return sub_8061714(mapObject, sprite);
+}
+
+bool8 sub_8061970(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80616CC(mapObject, sprite, DIR_NORTH, get_go_fast_image_anim_num(DIR_NORTH), 8);
+ return sub_8061714(mapObject, sprite);
+}
+
+bool8 sub_80619A8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80616CC(mapObject, sprite, DIR_WEST, get_go_fast_image_anim_num(DIR_WEST), 8);
+ return sub_8061714(mapObject, sprite);
+}
+
+bool8 sub_80619E0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80616CC(mapObject, sprite, DIR_EAST, get_go_fast_image_anim_num(DIR_EAST), 8);
+ return sub_8061714(mapObject, sprite);
+}
+
+bool8 sub_8061A18(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80616CC(mapObject, sprite, DIR_SOUTH, get_go_faster_image_anim_num(DIR_SOUTH), 4);
+ return sub_8061714(mapObject, sprite);
+}
+
+bool8 sub_8061A50(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80616CC(mapObject, sprite, DIR_NORTH, get_go_faster_image_anim_num(DIR_NORTH), 4);
+ return sub_8061714(mapObject, sprite);
+}
+
+bool8 sub_8061A88(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80616CC(mapObject, sprite, DIR_WEST, get_go_faster_image_anim_num(DIR_WEST), 4);
+ return sub_8061714(mapObject, sprite);
+}
+
+bool8 sub_8061AC0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80616CC(mapObject, sprite, DIR_EAST, get_go_faster_image_anim_num(DIR_EAST), 4);
+ return sub_8061714(mapObject, sprite);
+}
+
+bool8 sub_8061B18(struct MapObject *, struct Sprite *);
+
+bool8 sub_8061AF8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_go_anim(mapObject, sprite, DIR_SOUTH, 2);
+ return sub_8061B18(mapObject, sprite);
+}
+
+bool8 sub_8061B18(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+bool8 sub_8061B58(struct MapObject *, struct Sprite *);
+
+bool8 sub_8061B38(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_go_anim(mapObject, sprite, DIR_NORTH, 2);
+ return sub_8061B58(mapObject, sprite);
+}
+
+bool8 sub_8061B58(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+bool8 sub_8061B98(struct MapObject *, struct Sprite *);
+
+bool8 sub_8061B78(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_go_anim(mapObject, sprite, DIR_WEST, 2);
+ return sub_8061B98(mapObject, sprite);
+}
+
+bool8 sub_8061B98(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+bool8 sub_8061BD8(struct MapObject *, struct Sprite *);
+
+bool8 sub_8061BB8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_go_anim(mapObject, sprite, DIR_EAST, 2);
+ return sub_8061BD8(mapObject, sprite);
+}
+
+bool8 sub_8061BD8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8061C18(struct MapObject *, struct Sprite *);
+
+bool8 sub_8061BF8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_go_anim(mapObject, sprite, DIR_SOUTH, 3);
+ return sub_8061C18(mapObject, sprite);
+}
+
+bool8 sub_8061C18(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8061C58(struct MapObject *, struct Sprite *);
+
+bool8 sub_8061C38(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_go_anim(mapObject, sprite, DIR_NORTH, 3);
+ return sub_8061C58(mapObject, sprite);
+}
+
+bool8 sub_8061C58(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+bool8 sub_8061C98(struct MapObject *, struct Sprite *);
+
+bool8 sub_8061C78(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_go_anim(mapObject, sprite, DIR_WEST, 3);
+ return sub_8061C98(mapObject, sprite);
+}
+
+bool8 sub_8061C98(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+bool8 sub_8061CD8(struct MapObject *, struct Sprite *);
+
+bool8 sub_8061CB8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_go_anim(mapObject, sprite, DIR_EAST, 3);
+ return sub_8061CD8(mapObject, sprite);
+}
+
+bool8 sub_8061CD8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8061D18(struct MapObject *, struct Sprite *);
+
+bool8 sub_8061CF8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_go_anim(mapObject, sprite, DIR_SOUTH, 4);
+ return sub_8061D18(mapObject, sprite);
+}
+
+bool8 sub_8061D18(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8061D58(struct MapObject *, struct Sprite *);
+
+bool8 sub_8061D38(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_go_anim(mapObject, sprite, DIR_NORTH, 4);
+ return sub_8061D58(mapObject, sprite);
+}
+
+bool8 sub_8061D58(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+bool8 sub_8061D98(struct MapObject *, struct Sprite *);
+
+bool8 sub_8061D78(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_go_anim(mapObject, sprite, DIR_WEST, 4);
+ return sub_8061D98(mapObject, sprite);
+}
+
+bool8 sub_8061D98(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+bool8 sub_8061DD8(struct MapObject *, struct Sprite *);
+
+bool8 sub_8061DB8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_go_anim(mapObject, sprite, DIR_EAST, 4);
+ return sub_8061DD8(mapObject, sprite);
+}
+
+bool8 sub_8061DD8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8061E18(struct MapObject *, struct Sprite *);
+
+bool8 do_run_south_anim(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_run_anim(mapObject, sprite, DIR_SOUTH);
+ return sub_8061E18(mapObject, sprite);
+}
+
+bool8 sub_8061E18(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8061E58(struct MapObject *, struct Sprite *);
+
+bool8 do_run_north_anim(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_run_anim(mapObject, sprite, DIR_NORTH);
+ return sub_8061E58(mapObject, sprite);
+}
+
+bool8 sub_8061E58(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8061E98(struct MapObject *, struct Sprite *);
+
+bool8 do_run_west_anim(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_run_anim(mapObject, sprite, DIR_WEST);
+ return sub_8061E98(mapObject, sprite);
+}
+
+bool8 sub_8061E98(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8061ED8(struct MapObject *, struct Sprite *);
+
+bool8 do_run_east_anim(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ do_run_anim(mapObject, sprite, DIR_EAST);
+ return sub_8061ED8(mapObject, sprite);
+}
+
+bool8 sub_8061ED8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void npc_set_direction_and_anim__an_proceed(struct MapObject *mapObject, struct Sprite *sprite, u8 direction, u8 animNum)
+{
+ obj_anim_image_set_and_seek(sprite, animNum, 0);
+ FieldObjectSetDirection(mapObject, direction);
+ sprite->data2 = 1;
+}
+
+bool8 sub_8061F24(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_set_direction_and_anim__an_proceed(mapObject, sprite, mapObject->placeholder18, sprite->animNum);
+ return FALSE;
+}
+
+bool8 sub_8064864(struct Sprite *);
+
+bool8 sub_8061F3C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8064864(sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void sub_8061F5C(struct MapObject *mapObject, struct Sprite *sprite, u8 direction)
+{
+ sub_806113C(mapObject, sprite, direction, 1, 0);
+ StartSpriteAnim(sprite, sub_805FD88(direction));
+}
+
+bool8 sub_8061FB0(struct MapObject *, struct Sprite *);
+
+bool8 sub_8061F90(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8061F5C(mapObject, sprite, DIR_SOUTH);
+ return sub_8061FB0(mapObject, sprite);
+}
+
+bool8 sub_8061FB0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061340(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ mapObject->mapobj_bit_5 = 0;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8061FF8(struct MapObject *, struct Sprite *);
+
+bool8 sub_8061FD8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8061F5C(mapObject, sprite, DIR_NORTH);
+ return sub_8061FF8(mapObject, sprite);
+}
+
+bool8 sub_8061FF8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061340(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ mapObject->mapobj_bit_5 = 0;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8062040(struct MapObject *, struct Sprite *);
+
+bool8 sub_8062020(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8061F5C(mapObject, sprite, DIR_WEST);
+ return sub_8062040(mapObject, sprite);
+}
+
+bool8 sub_8062040(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061340(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ mapObject->mapobj_bit_5 = 0;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8062088(struct MapObject *, struct Sprite *);
+
+bool8 sub_8062068(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8061F5C(mapObject, sprite, DIR_EAST);
+ return sub_8062088(mapObject, sprite);
+}
+
+bool8 sub_8062088(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061340(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ mapObject->mapobj_bit_5 = 0;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_80620B0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 objectId;
+ if (!TryGetFieldObjectIdByLocalIdAndMap(0xFF, MAP_GROUP_PETALBURG_CITY, MAP_ID_PETALBURG_CITY, &objectId))
+ {
+ an_look_any(mapObject, sprite, sub_805FE90(mapObject->coords2.x, mapObject->coords2.y, gMapObjects[objectId].coords2.x, gMapObjects[objectId].coords2.y));
+ }
+ sprite->data2 = 1;
+ return TRUE;
+}
+
+bool8 sub_806210C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u8 objectId;
+ if (!TryGetFieldObjectIdByLocalIdAndMap(0xFF, MAP_GROUP_PETALBURG_CITY, MAP_ID_PETALBURG_CITY, &objectId))
+ {
+ an_look_any(mapObject, sprite, GetOppositeDirection(sub_805FE90(mapObject->coords2.x, mapObject->coords2.y, gMapObjects[objectId].coords2.x, gMapObjects[objectId].coords2.y)));
+ }
+ sprite->data2 = 1;
+ return TRUE;
+}
+
+bool8 sub_8062170(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ mapObject->mapobj_bit_9 = 1;
+ sprite->data2 = 1;
+ return TRUE;
+}
+
+bool8 sub_8062180(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ mapObject->mapobj_bit_9 = 0;
+ sprite->data2 = 1;
+ return TRUE;
+}
+
+bool8 sub_80621BC(struct MapObject *mapObject, struct Sprite *sprite);
+
+bool8 sub_8062190(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ maybe_shadow_1(mapObject, sprite, DIR_SOUTH, 1, 2);
+ return sub_80621BC(mapObject, sprite);
+}
+
+bool8 sub_80621BC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8062214(struct MapObject *mapObject, struct Sprite *sprite);
+
+bool8 sub_80621E8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ maybe_shadow_1(mapObject, sprite, DIR_NORTH, 1, 2);
+ return sub_8062214(mapObject, sprite);
+}
+
+bool8 sub_8062214(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_806226C(struct MapObject *mapObject, struct Sprite *sprite);
+
+bool8 sub_8062240(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ maybe_shadow_1(mapObject, sprite, DIR_WEST, 1, 2);
+ return sub_806226C(mapObject, sprite);
+}
+
+bool8 sub_806226C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_80622C4(struct MapObject *mapObject, struct Sprite *sprite);
+
+bool8 sub_8062298(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ maybe_shadow_1(mapObject, sprite, DIR_EAST, 1, 2);
+ return sub_80622C4(mapObject, sprite);
+}
+
+bool8 sub_80622C4(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_806231C(struct MapObject *mapObject, struct Sprite *sprite);
+
+bool8 sub_80622F0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ maybe_shadow_1(mapObject, sprite, DIR_SOUTH, 0, 0);
+ return sub_806231C(mapObject, sprite);
+}
+
+bool8 sub_806231C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8062374(struct MapObject *mapObject, struct Sprite *sprite);
+
+bool8 sub_8062348(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ maybe_shadow_1(mapObject, sprite, DIR_NORTH, 0, 0);
+ return sub_8062374(mapObject, sprite);
+}
+
+bool8 sub_8062374(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_80623CC(struct MapObject *mapObject, struct Sprite *sprite);
+
+bool8 sub_80623A0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ maybe_shadow_1(mapObject, sprite, DIR_WEST, 0, 0);
+ return sub_80623CC(mapObject, sprite);
+}
+
+bool8 sub_80623CC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8062424(struct MapObject *mapObject, struct Sprite *sprite);
+
+bool8 sub_80623F8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ maybe_shadow_1(mapObject, sprite, DIR_EAST, 0, 0);
+ return sub_8062424(mapObject, sprite);
+}
+
+bool8 sub_8062424(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_806247C(struct MapObject *mapObject, struct Sprite *sprite);
+
+bool8 sub_8062450(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ maybe_shadow_1(mapObject, sprite, DIR_SOUTH, 0, 2);
+ return sub_806247C(mapObject, sprite);
+}
+
+bool8 sub_806247C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061358(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_80624D4(struct MapObject *mapObject, struct Sprite *sprite);
+
+bool8 sub_80624A8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ maybe_shadow_1(mapObject, sprite, DIR_NORTH, 0, 2);
+ return sub_80624D4(mapObject, sprite);
+}
+
+bool8 sub_80624D4(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061358(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_806252C(struct MapObject *mapObject, struct Sprite *sprite);
+
+bool8 sub_8062500(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ maybe_shadow_1(mapObject, sprite, DIR_WEST, 0, 2);
+ return sub_806252C(mapObject, sprite);
+}
+
+bool8 sub_806252C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061358(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8062584(struct MapObject *mapObject, struct Sprite *sprite);
+
+bool8 sub_8062558(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ maybe_shadow_1(mapObject, sprite, DIR_EAST, 0, 2);
+ return sub_8062584(mapObject, sprite);
+}
+
+bool8 sub_8062584(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061358(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_80625B0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ an_look_any(mapObject, sprite, gUnknown_0836DC09[mapObject->animPattern]);
+ return TRUE;
+}
+
+bool8 sub_80625C8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_set_direction_and_anim__an_proceed(mapObject, sprite, DIR_SOUTH, 0x14);
+ return FALSE;
+}
+
+bool8 sub_80625D8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ mapObject->mapobj_bit_25 = 0;
+ sprite->data2 = 1;
+ return TRUE;
+}
+
+bool8 sub_80625E8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ mapObject->mapobj_bit_25 = 1;
+ sprite->data2 = 1;
+ return TRUE;
+}
+
+bool8 sub_80625F8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ mapObject->mapobj_bit_12 = 1;
+ sprite->data2 = 1;
+ return TRUE;
+}
+
+bool8 sub_8062608(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ mapObject->mapobj_bit_12 = GetFieldObjectGraphicsInfo(mapObject->graphicsId)->inanimate;
+ sprite->data2 = 1;
+ return TRUE;
+}
+
+bool8 sub_8062634(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ mapObject->mapobj_bit_13 = 1;
+ sprite->data2 = 1;
+ return TRUE;
+}
+
+bool8 sub_8062644(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ mapObject->mapobj_bit_13 = 0;
+ sprite->data2 = 1;
+ return TRUE;
+}
+
+bool8 do_exclamation_mark_bubble_1(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectArguments[0], (u8 *)&gFieldEffectArguments[1], (u8 *)&gFieldEffectArguments[2]);
+ FieldEffectStart(FLDEFF_EXCLAMATION_MARK_ICON_1);
+ sprite->data2 = 1;
+ return TRUE;
+}
+
+bool8 do_exclamation_mark_bubble_2(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectArguments[0], (u8 *)&gFieldEffectArguments[1], (u8 *)&gFieldEffectArguments[2]);
+ FieldEffectStart(FLDEFF_EXCLAMATION_MARK_ICON_2);
+ sprite->data2 = 1;
+ return TRUE;
+}
+
+bool8 do_heart_bubble(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectArguments[0], (u8 *)&gFieldEffectArguments[1], (u8 *)&gFieldEffectArguments[2]);
+ FieldEffectStart(FLDEFF_HEART_ICON);
+ sprite->data2 = 1;
+ return TRUE;
+}
+
+bool8 sub_8062704(struct MapObject *, struct Sprite *);
+
+bool8 sub_80626C0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (mapObject->animPattern == 0x3F)
+ {
+ sub_8084794(mapObject);
+ return FALSE;
+ }
+ else if (mapObject->animPattern != 0x39 && mapObject->animPattern != 0x3A)
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ else
+ {
+ sub_812869C(mapObject);
+ sprite->data2 = 1;
+ return sub_8062704(mapObject, sprite);
+ }
+}
+
+bool8 sub_8062704(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_81286C4(mapObject))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8062724(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ obj_anim_image_set_and_seek(sprite, 1, 0);
+ sprite->data2 = 1;
+ return FALSE;
+}
+
+bool8 sub_8062740(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8064864(sprite))
+ {
+ sub_8064820(sprite, 0x20);
+ sprite->data2 = 2;
+ }
+ return FALSE;
+}
+
+bool8 sub_8062764(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ mapObject->mapobj_bit_13 ^= 1;
+ if (sub_8064824(sprite))
+ {
+ mapObject->mapobj_bit_13 = 1;
+ sprite->data2 = 3;
+ }
+ return FALSE;
+}
+
+bool8 sub_80627A0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ obj_anim_image_set_and_seek(sprite, 1, 0);
+ sprite->data2 = 1;
+ return FALSE;
+}
+
+bool8 sub_80627BC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8064864(sprite))
+ {
+ sub_8064820(sprite, 0x20);
+ sprite->data2 = 2;
+ }
+ return FALSE;
+}
+
+bool8 sub_80627E0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ mapObject->mapobj_bit_13 ^= 1;
+ if (sub_8064824(sprite))
+ {
+ mapObject->mapobj_bit_13 = 1;
+ sprite->data2 = 3;
+ }
+ return FALSE;
+}
+
+bool8 sub_806281C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ mapObject->mapobj_bit_26 = 1;
+ sprite->data2 = 1;
+ return TRUE;
+}
+
+bool8 sub_806282C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ mapObject->mapobj_bit_26 = 0;
+ sprite->data2 = 1;
+ return TRUE;
+}
+
+bool8 sub_806283C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sprite->oam.affineMode = 3;
+ InitSpriteAffineAnim(sprite);
+ sprite->affineAnimPaused = 1;
+ sprite->subspriteMode = 0;
+ return TRUE;
+}
+
+bool8 sub_806286C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ FreeOamMatrix(sprite->oam.matrixNum);
+ sprite->oam.affineMode = 0;
+ CalcCenterToCornerVec(sprite, sprite->oam.shape, sprite->oam.size, sprite->oam.affineMode);
+ return TRUE;
+}
+
+bool8 sub_80628D0(struct MapObject *, struct Sprite *);
+
+bool8 sub_806289C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8060ED8(mapObject, sprite, DIR_SOUTH);
+ sprite->affineAnimPaused = 0;
+ StartSpriteAffineAnimIfDifferent(sprite, 0);
+ return sub_80628D0(mapObject, sprite);
+}
+
+bool8 sub_80628D0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (an_walk_any_2(mapObject, sprite))
+ {
+ sprite->affineAnimPaused = 1;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8062930(struct MapObject *, struct Sprite *);
+
+bool8 sub_80628FC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8060ED8(mapObject, sprite, DIR_SOUTH);
+ sprite->affineAnimPaused = 0;
+ ChangeSpriteAffineAnimIfDifferent(sprite, 1);
+ return sub_8062930(mapObject, sprite);
+}
+
+bool8 sub_8062930(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (an_walk_any_2(mapObject, sprite))
+ {
+ sprite->affineAnimPaused = 1;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void sub_806295C(struct MapObject *mapObject, struct Sprite *sprite, u8 direction)
+{
+ FieldObjectSetDirection(mapObject, direction);
+ npc_coords_shift_still(mapObject);
+ sub_805FE64(mapObject, sprite, sub_805FDD8(direction));
+ sprite->animPaused = 1;
+ sprite->data2 = 1;
+}
+
+bool8 sub_806299C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_806295C(mapObject, sprite, DIR_SOUTH);
+ return TRUE;
+}
+
+bool8 sub_80629AC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_806295C(mapObject, sprite, DIR_NORTH);
+ return TRUE;
+}
+
+bool8 sub_80629BC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_806295C(mapObject, sprite, DIR_WEST);
+ return TRUE;
+}
+
+bool8 sub_80629CC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_806295C(mapObject, sprite, DIR_EAST);
+ return TRUE;
+}
+
+bool8 sub_80629DC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_set_direction_and_anim__an_proceed(mapObject, sprite, DIR_SOUTH, sub_805FD98(DIR_SOUTH));
+ return FALSE;
+}
+
+bool8 sub_8062A00(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_set_direction_and_anim__an_proceed(mapObject, sprite, DIR_NORTH, sub_805FD98(DIR_NORTH));
+ return FALSE;
+}
+
+bool8 sub_8062A24(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_set_direction_and_anim__an_proceed(mapObject, sprite, DIR_WEST, sub_805FD98(DIR_WEST));
+ return FALSE;
+}
+
+bool8 sub_8062A48(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_set_direction_and_anim__an_proceed(mapObject, sprite, DIR_EAST, sub_805FD98(DIR_EAST));
+ return FALSE;
+}
+
+bool8 sub_8062A6C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_set_direction_and_anim__an_proceed(mapObject, sprite, DIR_SOUTH, sub_805FDB8(DIR_SOUTH));
+ return FALSE;
+}
+
+bool8 sub_8062A90(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_set_direction_and_anim__an_proceed(mapObject, sprite, DIR_NORTH, sub_805FDB8(DIR_NORTH));
+ return FALSE;
+}
+
+bool8 sub_8062AB4(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_set_direction_and_anim__an_proceed(mapObject, sprite, DIR_WEST, sub_805FDB8(DIR_WEST));
+ return FALSE;
+}
+
+bool8 sub_8062AD8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_set_direction_and_anim__an_proceed(mapObject, sprite, DIR_EAST, sub_805FDB8(DIR_EAST));
+ return FALSE;
+}
+
+bool8 sub_8062AFC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_set_direction_and_anim__an_proceed(mapObject, sprite, DIR_SOUTH, sub_805FDC8(DIR_SOUTH));
+ return FALSE;
+}
+
+bool8 sub_8062B20(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_set_direction_and_anim__an_proceed(mapObject, sprite, DIR_NORTH, sub_805FDC8(DIR_NORTH));
+ return FALSE;
+}
+
+bool8 sub_8062B44(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_set_direction_and_anim__an_proceed(mapObject, sprite, DIR_WEST, sub_805FDC8(DIR_WEST));
+ return FALSE;
+}
+
+bool8 sub_8062B68(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ npc_set_direction_and_anim__an_proceed(mapObject, sprite, DIR_EAST, sub_805FDC8(DIR_EAST));
+ return FALSE;
+}
+
+void sub_8062B8C(struct MapObject *mapObject, struct Sprite *sprite, u8 direction, u8 a3, u8 a4)
+{
+ sub_806113C(mapObject, sprite, direction, a3, a4);
+ StartSpriteAnimIfDifferent(sprite, sub_805FD98(direction));
+ DoShadowFieldEffect(mapObject);
+}
+
+bool8 sub_8062BFC(struct MapObject *, struct Sprite *);
+
+bool8 sub_8062BD0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8062B8C(mapObject, sprite, DIR_SOUTH, 0, 1);
+ return sub_8062BFC(mapObject, sprite);
+}
+
+bool8 sub_8062BFC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8062C54(struct MapObject *, struct Sprite *);
+
+bool8 sub_8062C28(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8062B8C(mapObject, sprite, DIR_NORTH, 0, 1);
+ return sub_8062C54(mapObject, sprite);
+}
+
+bool8 sub_8062C54(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8062CAC(struct MapObject *, struct Sprite *);
+
+bool8 sub_8062C80(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8062B8C(mapObject, sprite, DIR_WEST, 0, 1);
+ return sub_8062CAC(mapObject, sprite);
+}
+
+bool8 sub_8062CAC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8062D04(struct MapObject *, struct Sprite *);
+
+bool8 sub_8062CD8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8062B8C(mapObject, sprite, DIR_EAST, 0, 1);
+ return sub_8062D04(mapObject, sprite);
+}
+
+bool8 sub_8062D04(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8062D5C(struct MapObject *, struct Sprite *);
+
+bool8 sub_8062D30(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8062B8C(mapObject, sprite, DIR_SOUTH, 1, 1);
+ return sub_8062D5C(mapObject, sprite);
+}
+
+bool8 sub_8062D5C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8062DB4(struct MapObject *, struct Sprite *);
+
+bool8 sub_8062D88(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8062B8C(mapObject, sprite, DIR_NORTH, 1, 1);
+ return sub_8062DB4(mapObject, sprite);
+}
+
+bool8 sub_8062DB4(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8062E0C(struct MapObject *, struct Sprite *);
+
+bool8 sub_8062DE0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8062B8C(mapObject, sprite, DIR_WEST, 1, 1);
+ return sub_8062E0C(mapObject, sprite);
+}
+
+bool8 sub_8062E0C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8062E64(struct MapObject *, struct Sprite *);
+
+bool8 sub_8062E38(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8062B8C(mapObject, sprite, DIR_EAST, 1, 1);
+ return sub_8062E64(mapObject, sprite);
+}
+
+bool8 sub_8062E64(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8062EBC(struct MapObject *, struct Sprite *);
+
+bool8 sub_8062E90(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8062B8C(mapObject, sprite, DIR_SOUTH, 2, 0);
+ return sub_8062EBC(mapObject, sprite);
+}
+
+bool8 sub_8062EBC(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8062F14(struct MapObject *, struct Sprite *);
+
+bool8 sub_8062EE8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8062B8C(mapObject, sprite, DIR_NORTH, 2, 0);
+ return sub_8062F14(mapObject, sprite);
+}
+
+bool8 sub_8062F14(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8062F6C(struct MapObject *, struct Sprite *);
+
+bool8 sub_8062F40(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8062B8C(mapObject, sprite, DIR_WEST, 2, 0);
+ return sub_8062F6C(mapObject, sprite);
+}
+
+bool8 sub_8062F6C(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8062FC4(struct MapObject *, struct Sprite *);
+
+bool8 sub_8062F98(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8062B8C(mapObject, sprite, DIR_EAST, 2, 0);
+ return sub_8062FC4(mapObject, sprite);
+}
+
+bool8 sub_8062FC4(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (sub_8061328(mapObject, sprite))
+ {
+ mapObject->mapobj_bit_22 = 0;
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8062FF0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80616CC(mapObject, sprite, DIR_SOUTH, sub_805FDD8(DIR_SOUTH), 8);
+ return sub_8061714(mapObject, sprite);
+}
+
+bool8 sub_8063028(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80616CC(mapObject, sprite, DIR_NORTH, sub_805FDD8(DIR_NORTH), 8);
+ return sub_8061714(mapObject, sprite);
+}
+
+bool8 sub_8063060(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80616CC(mapObject, sprite, DIR_WEST, sub_805FDD8(DIR_WEST), 8);
+ return sub_8061714(mapObject, sprite);
+}
+
+bool8 sub_8063098(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80616CC(mapObject, sprite, DIR_EAST, sub_805FDD8(DIR_EAST), 8);
+ return sub_8061714(mapObject, sprite);
+}
+
+void sub_80630D0(struct MapObject *mapObject, struct Sprite *sprite, u8 direction, u8 a3)
+{
+ sub_8060D20(mapObject, sprite, direction, a3);
+ StartSpriteAnim(sprite, sub_805FD98(mapObject->mapobj_unk_18));
+ SeekSpriteAnim(sprite, 0);
+}
+
+bool8 sub_8063128(struct MapObject *, struct Sprite *);
+
+bool8 sub_8063108(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80630D0(mapObject, sprite, DIR_SOUTH, 1);
+ return sub_8063128(mapObject, sprite);
+}
+
+bool8 sub_8063128(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8063168(struct MapObject *, struct Sprite *);
+
+bool8 sub_8063148(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80630D0(mapObject, sprite, DIR_NORTH, 1);
+ return sub_8063168(mapObject, sprite);
+}
+
+bool8 sub_8063168(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_80631A8(struct MapObject *, struct Sprite *);
+
+bool8 sub_8063188(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80630D0(mapObject, sprite, DIR_WEST, 1);
+ return sub_80631A8(mapObject, sprite);
+}
+
+bool8 sub_80631A8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_80631E8(struct MapObject *, struct Sprite *);
+
+bool8 sub_80631C8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80630D0(mapObject, sprite, DIR_EAST, 1);
+ return sub_80631E8(mapObject, sprite);
+}
+
+bool8 sub_80631E8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void sub_8063208(struct MapObject *mapObject, struct Sprite *sprite, u8 direction, u8 a3)
+{
+ sub_8060D20(mapObject, sprite, direction, a3);
+ sub_805FE28(mapObject, sprite, sub_805FDD8(mapObject->mapobj_unk_18));
+}
+
+bool8 sub_8063258(struct MapObject *, struct Sprite *);
+
+bool8 sub_8063238(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8063208(mapObject, sprite, DIR_SOUTH, 1);
+ return sub_8063258(mapObject, sprite);
+}
+
+bool8 sub_8063258(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8063298(struct MapObject *, struct Sprite *);
+
+bool8 sub_8063278(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8063208(mapObject, sprite, DIR_NORTH, 1);
+ return sub_8063298(mapObject, sprite);
+}
+
+bool8 sub_8063298(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_80632D8(struct MapObject *, struct Sprite *);
+
+bool8 sub_80632B8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8063208(mapObject, sprite, DIR_WEST, 1);
+ return sub_80632D8(mapObject, sprite);
+}
+
+bool8 sub_80632D8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8063318(struct MapObject *, struct Sprite *);
+
+bool8 sub_80632F8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8063208(mapObject, sprite, DIR_EAST, 1);
+ return sub_8063318(mapObject, sprite);
+}
+
+bool8 sub_8063318(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void sub_8063338(struct MapObject *mapObject, struct Sprite *sprite, u8 direction, u8 a3)
+{
+ sub_8060D20(mapObject, sprite, direction, a3);
+ StartSpriteAnim(sprite, sub_805FDB8(mapObject->mapobj_unk_18));
+ SeekSpriteAnim(sprite, 0);
+}
+
+bool8 sub_8063390(struct MapObject *, struct Sprite *);
+
+bool8 sub_8063370(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8063338(mapObject, sprite, DIR_SOUTH, 1);
+ return sub_8063390(mapObject, sprite);
+}
+
+bool8 sub_8063390(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_80633D0(struct MapObject *, struct Sprite *);
+
+bool8 sub_80633B0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8063338(mapObject, sprite, DIR_NORTH, 1);
+ return sub_80633D0(mapObject, sprite);
+}
+
+bool8 sub_80633D0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8063410(struct MapObject *, struct Sprite *);
+
+bool8 sub_80633F0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8063338(mapObject, sprite, DIR_WEST, 1);
+ return sub_8063410(mapObject, sprite);
+}
+
+bool8 sub_8063410(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8063450(struct MapObject *, struct Sprite *);
+
+bool8 sub_8063430(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_8063338(mapObject, sprite, DIR_EAST, 1);
+ return sub_8063450(mapObject, sprite);
+}
+
+bool8 sub_8063450(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (npc_obj_ministep_stop_on_arrival(mapObject, sprite))
+ {
+ sprite->data2 = 2;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_8063470(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ return TRUE;
+}
+
+bool8 sub_8063474(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sprite->animPaused = 1;
+ return TRUE;
+}
+
+void npc_obj_transfer_image_anim_pause_flag(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (mapObject->mapobj_bit_10)
+ {
+ sprite->animPaused = 1;
+ }
+}
+
+void sub_80634A0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ if (mapObject->mapobj_bit_11)
+ {
+ sprite->animPaused = 0;
+ mapObject->mapobj_bit_10 = 0;
+ mapObject->mapobj_bit_11 = 0;
+ }
+}
+
+void sub_80634E8(struct MapObject *, struct Sprite *);
+static void UpdateMapObjSpriteVisibility(struct MapObject *, struct Sprite *);
+
+void sub_80634D0(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sub_80634E8(mapObject, sprite);
+ UpdateMapObjSpriteVisibility(mapObject, sprite);
+}
+
+#ifdef NONMATCHING
+void sub_80634E8(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ u16 x;
+ u16 y;
+ s16 x2;
+ s16 y2;
+ const struct MapObjectGraphicsInfo *graphicsInfo;
+ mapObject->mapobj_bit_14 = 0;
+ graphicsInfo = GetFieldObjectGraphicsInfo(mapObject->graphicsId);
+ if (sprite->coordOffsetEnabled)
+ {
+ x = sprite->pos1.x + sprite->pos2.x + sprite->centerToCornerVecX + gSpriteCoordOffsetX;
+ y = sprite->pos1.y + sprite->pos2.y + sprite->centerToCornerVecY + gSpriteCoordOffsetY;
+ } else
+ {
+ x = sprite->pos1.x + sprite->pos2.x + sprite->centerToCornerVecX;
+ y = sprite->pos1.y + sprite->pos2.y + sprite->centerToCornerVecY;
+ }
+ x2 = graphicsInfo->width + x; // offending line
+ y2 = graphicsInfo->height + y; // similarly offending line
+ if ((s16)x >= 0x100 || x2 < -0x10)
+ {
+ mapObject->mapobj_bit_14 = 1;
+ }
+ if ((s16)y >= 0xB0 || y2 < -0x10)
+ {
+ mapObject->mapobj_bit_14 = 1;
+ }
+}
+#else
+__attribute__((naked))
+void sub_80634E8(struct MapObject *mapObject, struct Sprite *sprite) {
+ asm(".syntax unified\n\
+ push {r4-r6,lr}\n\
+ adds r5, r0, 0\n\
+ adds r4, r1, 0\n\
+ ldrb r1, [r5, 0x1]\n\
+ movs r0, 0x41\n\
+ negs r0, r0\n\
+ ands r0, r1\n\
+ strb r0, [r5, 0x1]\n\
+ ldrb r0, [r5, 0x5]\n\
+ bl GetFieldObjectGraphicsInfo\n\
+ adds r6, r0, 0\n\
+ adds r0, r4, 0\n\
+ adds r0, 0x3E\n\
+ ldrb r1, [r0]\n\
+ movs r0, 0x2\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ beq _0806354C\n\
+ ldrh r1, [r4, 0x24]\n\
+ ldrh r0, [r4, 0x20]\n\
+ adds r1, r0\n\
+ adds r0, r4, 0\n\
+ adds r0, 0x28\n\
+ ldrb r0, [r0]\n\
+ lsls r0, 24\n\
+ asrs r0, 24\n\
+ ldr r2, _08063544 @ =gSpriteCoordOffsetX\n\
+ adds r0, r1\n\
+ ldrh r2, [r2]\n\
+ adds r0, r2\n\
+ lsls r0, 16\n\
+ lsrs r3, r0, 16\n\
+ ldrh r1, [r4, 0x26]\n\
+ ldrh r0, [r4, 0x22]\n\
+ adds r1, r0\n\
+ adds r0, r4, 0\n\
+ adds r0, 0x29\n\
+ ldrb r0, [r0]\n\
+ lsls r0, 24\n\
+ asrs r0, 24\n\
+ ldr r2, _08063548 @ =gSpriteCoordOffsetY\n\
+ adds r0, r1\n\
+ ldrh r2, [r2]\n\
+ adds r0, r2\n\
+ b _08063574\n\
+ .align 2, 0\n\
+_08063544: .4byte gSpriteCoordOffsetX\n\
+_08063548: .4byte gSpriteCoordOffsetY\n\
+_0806354C:\n\
+ ldrh r1, [r4, 0x24]\n\
+ ldrh r0, [r4, 0x20]\n\
+ adds r1, r0\n\
+ adds r0, r4, 0\n\
+ adds r0, 0x28\n\
+ ldrb r0, [r0]\n\
+ lsls r0, 24\n\
+ asrs r0, 24\n\
+ adds r0, r1\n\
+ lsls r0, 16\n\
+ lsrs r3, r0, 16\n\
+ ldrh r1, [r4, 0x26]\n\
+ ldrh r0, [r4, 0x22]\n\
+ adds r1, r0\n\
+ adds r0, r4, 0\n\
+ adds r0, 0x29\n\
+ ldrb r0, [r0]\n\
+ lsls r0, 24\n\
+ asrs r0, 24\n\
+ adds r0, r1\n\
+_08063574:\n\
+ lsls r0, 16\n\
+ lsrs r2, r0, 16\n\
+ ldrh r0, [r6, 0x8]\n\
+ adds r0, r3\n\
+ lsls r0, 16\n\
+ lsrs r1, r0, 16\n\
+ ldrh r0, [r6, 0xA]\n\
+ adds r0, r2\n\
+ lsls r0, 16\n\
+ lsrs r4, r0, 16\n\
+ lsls r0, r3, 16\n\
+ asrs r0, 16\n\
+ cmp r0, 0xFF\n\
+ bgt _0806359C\n\
+ lsls r0, r1, 16\n\
+ asrs r0, 16\n\
+ movs r1, 0x10\n\
+ negs r1, r1\n\
+ cmp r0, r1\n\
+ bge _080635A4\n\
+_0806359C:\n\
+ ldrb r0, [r5, 0x1]\n\
+ movs r1, 0x40\n\
+ orrs r0, r1\n\
+ strb r0, [r5, 0x1]\n\
+_080635A4:\n\
+ lsls r0, r2, 16\n\
+ asrs r0, 16\n\
+ cmp r0, 0xAF\n\
+ bgt _080635B8\n\
+ lsls r0, r4, 16\n\
+ asrs r0, 16\n\
+ movs r1, 0x10\n\
+ negs r1, r1\n\
+ cmp r0, r1\n\
+ bge _080635C0\n\
+_080635B8:\n\
+ ldrb r0, [r5, 0x1]\n\
+ movs r1, 0x40\n\
+ orrs r0, r1\n\
+ strb r0, [r5, 0x1]\n\
+_080635C0:\n\
+ pop {r4-r6}\n\
+ pop {r0}\n\
+ bx r0\n\
+.syntax divided\n");
+}
+#endif
+
+void UpdateMapObjSpriteVisibility(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ sprite->invisible = 0;
+ if (mapObject->mapobj_bit_13 || mapObject->mapobj_bit_14)
+ {
+ sprite->invisible = 1;
+ }
+}
diff --git a/src/field/field_map_obj_helpers.c b/src/field/field_map_obj_helpers.c
new file mode 100644
index 000000000..b453d3794
--- /dev/null
+++ b/src/field/field_map_obj_helpers.c
@@ -0,0 +1,318 @@
+#include "global.h"
+#include "field_map_obj_helpers.h"
+#include "field_effect.h"
+#include "field_ground_effect.h"
+#include "field_map_obj.h"
+#include "sprite.h"
+
+typedef void (*SpriteStepFunc)(struct Sprite *sprite, u8 dir);
+
+extern s16 gUnknown_08376194[];
+extern SpriteStepFunc *gUnknown_08376180[];
+extern s8 *gUnknown_083761D0[];
+extern s16 gUnknown_083761DC[];
+extern u8 gUnknown_083761E2[];
+extern s16 gUnknown_083761E6[];
+extern u8 gUnknown_083761EC[];
+
+bool8 FreezeMapObject(struct MapObject *mapObject)
+{
+ if (mapObject->mapobj_bit_6 || mapObject->mapobj_bit_8)
+ {
+ return TRUE;
+ }
+ else
+ {
+ mapObject->mapobj_bit_8 = 1;
+ mapObject->mapobj_bit_23 = gSprites[mapObject->spriteId].animPaused;
+ mapObject->mapobj_bit_24 = gSprites[mapObject->spriteId].affineAnimPaused;
+ gSprites[mapObject->spriteId].animPaused = 1;
+ gSprites[mapObject->spriteId].affineAnimPaused = 1;
+ return FALSE;
+ }
+}
+
+void FreezeMapObjects(void)
+{
+ u8 i;
+ for (i = 0; i < 16; i++)
+ if (gMapObjects[i].active && i != gPlayerAvatar.mapObjectId)
+ FreezeMapObject(&gMapObjects[i]);
+}
+
+void FreezeMapObjectsExceptOne(u8 a1)
+{
+ u8 i;
+ for (i = 0; i < 16; i++)
+ if (i != a1 && gMapObjects[i].active && i != gPlayerAvatar.mapObjectId)
+ FreezeMapObject(&gMapObjects[i]);
+}
+
+void UnfreezeMapObject(struct MapObject *mapObject)
+{
+ if (mapObject->active && mapObject->mapobj_bit_8)
+ {
+ mapObject->mapobj_bit_8 = 0;
+ gSprites[mapObject->spriteId].animPaused = mapObject->mapobj_bit_23;
+ gSprites[mapObject->spriteId].affineAnimPaused = mapObject->mapobj_bit_24;
+ }
+}
+
+void UnfreezeMapObjects(void)
+{
+ u8 i;
+ for (i = 0; i < 16; i++)
+ if (gMapObjects[i].active)
+ UnfreezeMapObject(&gMapObjects[i]);
+}
+
+void Step1(struct Sprite *sprite, u8 dir)
+{
+ sprite->pos1.x += gDirectionToVector[dir].x;
+ sprite->pos1.y += gDirectionToVector[dir].y;
+}
+
+void Step2(struct Sprite *sprite, u8 dir)
+{
+ sprite->pos1.x += 2 * (u16) gDirectionToVector[dir].x;
+ sprite->pos1.y += 2 * (u16) gDirectionToVector[dir].y;
+}
+
+void Step3(struct Sprite *sprite, u8 dir)
+{
+ sprite->pos1.x += 2 * (u16) gDirectionToVector[dir].x + (u16) gDirectionToVector[dir].x;
+ sprite->pos1.y += 2 * (u16) gDirectionToVector[dir].y + (u16) gDirectionToVector[dir].y;
+}
+
+void Step4(struct Sprite *sprite, u8 dir)
+{
+ sprite->pos1.x += 4 * (u16) gDirectionToVector[dir].x;
+ sprite->pos1.y += 4 * (u16) gDirectionToVector[dir].y;
+}
+
+void Step8(struct Sprite *sprite, u8 dir)
+{
+ sprite->pos1.x += 8 * (u16) gDirectionToVector[dir].x;
+ sprite->pos1.y += 8 * (u16) gDirectionToVector[dir].y;
+}
+
+void oamt_npc_ministep_reset(struct Sprite *sprite, u8 a2, u8 a3)
+{
+ sprite->data3 = a2;
+ sprite->data4 = a3;
+ sprite->data5 = 0;
+}
+
+bool8 obj_npc_ministep(struct Sprite *sprite)
+{
+ if (sprite->data5 >= gUnknown_08376194[sprite->data4])
+ return FALSE;
+
+ gUnknown_08376180[sprite->data4][sprite->data5](sprite, sprite->data3);
+
+ sprite->data5++;
+
+ if (sprite->data5 < gUnknown_08376194[sprite->data4])
+ return FALSE;
+
+ return TRUE;
+}
+
+void sub_806467C(struct Sprite *sprite, u8 a2)
+{
+ sprite->data3 = a2;
+ sprite->data4 = 0;
+ sprite->data5 = 0;
+}
+
+bool8 sub_806468C(struct Sprite *sprite)
+{
+ if (!(sprite->data4 & 1))
+ {
+ Step1(sprite, sprite->data3);
+ sprite->data5++;
+ }
+
+ sprite->data4++;
+
+ if (sprite->data5 > 15)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+s16 sub_80646C8(s16 a1, u8 a2)
+{
+ return gUnknown_083761D0[a2][a1];
+}
+
+void sub_80646E4(struct Sprite *sprite, u8 a2, u8 a3, u8 a4)
+{
+ sprite->data3 = a2;
+ sprite->data4 = a3;
+ sprite->data5 = a4;
+ sprite->data6 = 0;
+}
+
+u8 sub_8064704(struct Sprite *sprite)
+{
+ u8 v2;
+ s16 v5[3];
+ u8 v6[3];
+
+ memcpy(v5, gUnknown_083761DC, 6);
+ memcpy(v6, gUnknown_083761E2, 3);
+
+ v2 = 0;
+
+ if (sprite->data4)
+ Step1(sprite, sprite->data3);
+
+ sprite->pos2.y = sub_80646C8(sprite->data6 >> v6[sprite->data4], sprite->data5);
+
+ sprite->data6++;
+
+ if (sprite->data6 == (v5[sprite->data4] >> 1))
+ v2 = 1;
+
+ if (sprite->data6 >= v5[sprite->data4])
+ {
+ sprite->pos2.y = 0;
+ v2 = -1;
+ }
+
+ return v2;
+}
+
+u8 sub_806478C(struct Sprite *sprite)
+{
+ u8 v2;
+ s16 v5[3];
+ u8 v6[3];
+
+ memcpy(v5, gUnknown_083761E6, 6);
+ memcpy(v6, gUnknown_083761EC, 3);
+
+ v2 = 0;
+
+ if (sprite->data4 && !(sprite->data6 & 1))
+ Step1(sprite, sprite->data3);
+
+ sprite->pos2.y = sub_80646C8(sprite->data6 >> v6[sprite->data4], sprite->data5);
+
+ sprite->data6++;
+
+ if (sprite->data6 == (v5[sprite->data4] >> 1))
+ v2 = 1;
+
+ if (sprite->data6 >= v5[sprite->data4])
+ {
+ sprite->pos2.y = 0;
+ v2 = -1;
+ }
+
+ return v2;
+}
+
+void sub_8064820(struct Sprite *sprite, u16 a2)
+{
+ sprite->data3 = a2;
+}
+
+bool8 sub_8064824(struct Sprite *sprite)
+{
+ sprite->data3--;
+
+ if (sprite->data3 == 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void obj_anim_image_set_and_seek(struct Sprite *sprite, u8 a2, u8 a3)
+{
+ sprite->animNum = a2;
+ sprite->animPaused = 0 ;
+ SeekSpriteAnim(sprite, a3);
+}
+
+bool8 sub_8064864(struct Sprite *sprite)
+{
+ if (sprite->animEnded)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void sub_806487C(struct Sprite *sprite, bool8 invisible)
+{
+ u16 x, y;
+ s16 x2, y2;
+
+ sprite->invisible = invisible;
+
+ if (sprite->coordOffsetEnabled)
+ {
+ x = sprite->pos1.x + sprite->pos2.x + sprite->centerToCornerVecX + gSpriteCoordOffsetX;
+ y = sprite->pos1.y + sprite->pos2.y + sprite->centerToCornerVecY + gSpriteCoordOffsetY;
+ }
+ else
+ {
+ x = sprite->pos1.x + sprite->pos2.x + sprite->centerToCornerVecX;
+ y = sprite->pos1.y + sprite->pos2.y + sprite->centerToCornerVecY;
+ }
+
+ x2 = x - (sprite->centerToCornerVecX >> 1);
+ y2 = y - (sprite->centerToCornerVecY >> 1);
+
+ if ((s16)x > 255 || x2 < -16)
+ sprite->invisible = 1;
+ if ((s16)y > 175 || y2 < -16)
+ sprite->invisible = 1;
+}
+
+void sub_8064970(struct Sprite *sprite)
+{
+ SetObjectSubpriorityByZCoord(sprite->data1, sprite, 1);
+ sub_806487C(sprite, 0);
+}
+
+void sub_8064990(u8 a1, u8 dir)
+{
+ u8 i;
+ for (i = 0; i < MAX_SPRITES; i++)
+ {
+ struct Sprite *sprite = &gSprites[i];
+ if (sprite->inUse && sprite->callback == sub_8064970 && (u8)sprite->data0 == a1)
+ {
+ u8 animNum = FieldObjectDirectionToImageAnimId(dir);
+ StartSpriteAnim(sprite, animNum);
+ break;
+ }
+ }
+}
+
+u32 oe_exec_and_other_stuff(u8 fieldEffectId, struct MapObject *mapObject)
+{
+ FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectArguments[0], (u8 *)&gFieldEffectArguments[1], (u8 *)&gFieldEffectArguments[2]);
+ return FieldEffectStart(fieldEffectId);
+}
+
+void DoShadowFieldEffect(struct MapObject *mapObject)
+{
+ if (!mapObject->mapobj_bit_22)
+ {
+ mapObject->mapobj_bit_22 = 1;
+ oe_exec_and_other_stuff(FLDEFF_SHADOW, mapObject);
+ }
+}
+
+void DoRippleFieldEffect(struct MapObject *mapObject, struct Sprite *sprite)
+{
+ const struct MapObjectGraphicsInfo *gfxInfo = GetFieldObjectGraphicsInfo(mapObject->graphicsId);
+ gFieldEffectArguments[0] = sprite->pos1.x;
+ gFieldEffectArguments[1] = sprite->pos1.y + (gfxInfo->height >> 1) - 2;
+ gFieldEffectArguments[2] = 151;
+ gFieldEffectArguments[3] = 3;
+ FieldEffectStart(FLDEFF_RIPPLE);
+}
diff --git a/src/field/field_message_box.c b/src/field/field_message_box.c
new file mode 100644
index 000000000..35aac7ac9
--- /dev/null
+++ b/src/field/field_message_box.c
@@ -0,0 +1,155 @@
+#include "global.h"
+#include "field_message_box.h"
+#include "menu.h"
+#include "string_util.h"
+#include "task.h"
+#include "text.h"
+#include "text_window.h"
+
+static EWRAM_DATA struct Window gFieldMessageBoxWindow = {0};
+
+static u8 sMessageBoxMode;
+
+static void Task_FieldMessageBox(u8 taskId);
+static void CreateFieldMessageBoxTask(void);
+static void DestroyFieldMessageBoxTask(void);
+static void PrintFieldMessage(const u8 *message);
+static void PrintFieldMessageFromStringVar4(void);
+
+void InitFieldMessageBox(void)
+{
+ sMessageBoxMode = FIELD_MESSAGE_BOX_HIDDEN;
+ SetMessageBoxBaseTileNum(gMenuTextWindowContentTileOffset);
+ InitWindowFromConfig(&gFieldMessageBoxWindow, &gWindowConfig_81E6CE4);
+}
+
+static void Task_FieldMessageBox(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ switch (task->data[0])
+ {
+ case 0:
+ LoadMessageBoxTiles(&gFieldMessageBoxWindow);
+ task->data[0]++;
+ break;
+ case 1:
+ DrawStandardMessageBox(&gFieldMessageBoxWindow);
+ task->data[0]++;
+ break;
+ case 2:
+ switch (sMessageBoxMode)
+ {
+ case FIELD_MESSAGE_BOX_NORMAL:
+ if (!sub_80035AC(&gFieldMessageBoxWindow))
+ return;
+ break;
+ case FIELD_MESSAGE_BOX_AUTO_SCROLL:
+ if (!sub_8003778(&gFieldMessageBoxWindow))
+ return;
+ break;
+ }
+ sMessageBoxMode = FIELD_MESSAGE_BOX_HIDDEN;
+ DestroyTask(taskId);
+ }
+}
+
+static void CreateFieldMessageBoxTask(void)
+{
+ CreateTask(Task_FieldMessageBox, 80);
+}
+
+static void DestroyFieldMessageBoxTask(void)
+{
+ u8 taskId = FindTaskIdByFunc(Task_FieldMessageBox);
+ if (taskId != 0xFF)
+ DestroyTask(taskId);
+}
+
+bool8 ShowFieldMessage(const u8 *message)
+{
+ if (sMessageBoxMode != FIELD_MESSAGE_BOX_HIDDEN)
+ {
+ return FALSE;
+ }
+ else
+ {
+ PrintFieldMessage(message);
+ sMessageBoxMode = FIELD_MESSAGE_BOX_NORMAL;
+ return TRUE;
+ }
+}
+
+bool8 ShowFieldAutoScrollMessage(const u8 *message)
+{
+ if (sMessageBoxMode != FIELD_MESSAGE_BOX_HIDDEN)
+ {
+ return FALSE;
+ }
+ else
+ {
+ sMessageBoxMode = FIELD_MESSAGE_BOX_AUTO_SCROLL;
+ PrintFieldMessage(message);
+ return TRUE;
+ }
+}
+
+bool8 unref_sub_8064BB8(const u8 *message)
+{
+ sMessageBoxMode = FIELD_MESSAGE_BOX_AUTO_SCROLL;
+ PrintFieldMessage(message);
+ return TRUE;
+}
+
+bool8 unref_sub_8064BD0(const u8 *message)
+{
+ if (sMessageBoxMode != FIELD_MESSAGE_BOX_HIDDEN)
+ {
+ return FALSE;
+ }
+ else
+ {
+ sMessageBoxMode = FIELD_MESSAGE_BOX_NORMAL;
+ PrintFieldMessageFromStringVar4();
+ return TRUE;
+ }
+}
+
+static void PrintFieldMessage(const u8 *message)
+{
+ StringExpandPlaceholders(gStringVar4, message);
+ sub_8002EB0(&gFieldMessageBoxWindow, gStringVar4, gMenuTextTileOffset, 2, 15);
+ CreateFieldMessageBoxTask();
+}
+
+static void PrintFieldMessageFromStringVar4(void)
+{
+ sub_8002EB0(&gFieldMessageBoxWindow, gStringVar4, gMenuTextTileOffset, 2, 15);
+ CreateFieldMessageBoxTask();
+}
+
+void HideFieldMessageBox(void)
+{
+ DestroyFieldMessageBoxTask();
+ ClearStandardMessageBox(&gFieldMessageBoxWindow);
+ sMessageBoxMode = FIELD_MESSAGE_BOX_HIDDEN;
+}
+
+u8 GetFieldMessageBoxMode(void)
+{
+ return sMessageBoxMode;
+}
+
+bool8 IsFieldMessageBoxHidden(void)
+{
+ if (sMessageBoxMode == FIELD_MESSAGE_BOX_HIDDEN)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void unref_sub_8064CA0(void)
+{
+ DestroyFieldMessageBoxTask();
+ DrawStandardMessageBox(&gFieldMessageBoxWindow);
+ sMessageBoxMode = FIELD_MESSAGE_BOX_HIDDEN;
+}
diff --git a/src/field/field_player_avatar.c b/src/field/field_player_avatar.c
new file mode 100644
index 000000000..6c1c9123a
--- /dev/null
+++ b/src/field/field_player_avatar.c
@@ -0,0 +1,1757 @@
+#include "global.h"
+#include "field_player_avatar.h"
+#include "bike.h"
+#include "event_data.h"
+#include "field_effect.h"
+#include "field_effect_helpers.h"
+#include "field_ground_effect.h"
+#include "field_map_obj.h"
+#include "field_map_obj_helpers.h"
+#include "fieldmap.h"
+#include "main.h"
+#include "map_object_constants.h"
+#include "menu.h"
+#include "metatile_behavior.h"
+#include "party_menu.h"
+#include "rng.h"
+#include "overworld.h"
+#include "rotating_gate.h"
+#include "script.h"
+#include "songs.h"
+#include "sound.h"
+#include "strings2.h"
+#include "task.h"
+#include "tv.h"
+#include "wild_encounter.h"
+
+EWRAM_DATA struct PlayerAvatar gPlayerAvatar = {0};
+
+//Functions
+static bool8 sub_8058854(struct MapObject *, u8);
+static void npc_clear_strange_bits(struct MapObject *a);
+static void MovePlayerAvatarUsingKeypadInput(u8 a, u16 b, u16 c);
+static void PlayerAllowForcedMovementIfMovingSameDirection(void);
+static u8 TryDoMetatileBehaviorForcedMovement(void);
+static u8 GetForcedMovementByMetatileBehavior(void);
+static void MovePlayerNotOnBike(u8 a, u16 b);
+static u8 CheckMovementInputNotOnBike(u8 a);
+static u8 CheckForPlayerAvatarCollision(u8 a);
+static u8 sub_8058EF0(s16 a, s16 b, u8 c);
+static bool8 ShouldJumpLedge(s16 a, s16 b, u8 c);
+static u8 sub_8058F6C(s16 a, s16 b, u8 c);
+static void check_acro_bike_metatile(int unused1, int unused2, u8 c, u8 *d);
+static void DoPlayerAvatarTransition(void);
+static bool8 player_is_anim_in_certain_ranges(void);
+static bool8 sub_80592A4(void);
+static bool8 PlayerIsAnimActive(void);
+static bool8 PlayerCheckIfAnimFinishedOrInactive(void);
+static void PlayerNotOnBikeCollide(u8 a);
+static void PlayCollisionSoundIfNotFacingWarp(u8 a);
+static void sub_8059D60(struct MapObject *a);
+static void StartStrengthAnim(u8 a, u8 b);
+static void sub_8059F94(void);
+static void sub_805A06C(void);
+
+static bool8 (*const gUnknown_0830FB58[])(u8) =
+{
+ MetatileBehavior_IsTrickHouseSlipperyFloor,
+ MetatileBehavior_IsIce_2,
+ MetatileBehavior_IsWalkSouth,
+ MetatileBehavior_IsWalkNorth,
+ MetatileBehavior_IsWalkWest,
+ MetatileBehavior_IsWalkEast,
+ MetatileBehavior_IsSouthwardCurrent,
+ MetatileBehavior_IsNorthwardCurrent,
+ MetatileBehavior_IsWestwardCurrent,
+ MetatileBehavior_IsEastwardCurrent,
+ MetatileBehavior_IsSlideSouth,
+ MetatileBehavior_IsSlideNorth,
+ MetatileBehavior_IsSlideWest,
+ MetatileBehavior_IsSlideEast,
+ MetatileBehavior_IsWaterfall,
+ MetatileBehavior_0xBB,
+ MetatileBehavior_0xBC,
+ MetatileBehavior_IsMuddySlope,
+};
+static u8 (*const gUnknown_0830FBA0[])(void) =
+{
+ ForcedMovement_None,
+ ForcedMovement_Slip,
+ ForcedMovement_Slip,
+ sub_8058AAC,
+ sub_8058AC4,
+ sub_8058ADC,
+ sub_8058AF4,
+ sub_8058B0C,
+ sub_8058B24,
+ sub_8058B3C,
+ sub_8058B54,
+ ForcedMovement_SlideSouth,
+ ForcedMovement_SlideNorth,
+ ForcedMovement_SlideWest,
+ ForcedMovement_SlideEast,
+ sub_8058B0C,
+ sub_8058C04,
+ sub_8058C10,
+ ForcedMovement_MuddySlope,
+};
+static void (*const gUnknown_0830FBEC[])(u8, u16) =
+{
+ PlayerNotOnBikeNotMoving,
+ PlayerNotOnBikeTurningInPlace,
+ sub_8058D0C,
+};
+static bool8 (*const gUnknown_0830FBF8[])(u8) =
+{
+ MetatileBehavior_IsBumpySlope,
+ MetatileBehavior_IsIsolatedVerticalRail,
+ MetatileBehavior_IsIsolatedHorizontalRail,
+ MetatileBehavior_IsVerticalRail,
+ MetatileBehavior_IsHorizontalRail,
+};
+static const u8 gUnknown_0830FC0C[] = {9, 10, 11, 12, 13};
+static void (*const gUnknown_0830FC14[])(struct MapObject *) =
+{
+ PlayerAvatarTransition_Normal,
+ PlayerAvatarTransition_MachBike,
+ PlayerAvatarTransition_AcroBike,
+ PlayerAvatarTransition_Surfing,
+ PlayerAvatarTransition_Underwater,
+ sub_80591F4,
+ nullsub_49,
+ nullsub_49,
+};
+static bool8 (*const gUnknown_0830FC34[])(u8) =
+{
+ MetatileBehavior_IsSouthArrowWarp,
+ MetatileBehavior_IsNorthArrowWarp,
+ MetatileBehavior_IsWestArrowWarp,
+ MetatileBehavior_IsEastArrowWarp,
+};
+static const u8 sRivalAvatarGfxIds[][2] =
+{
+ {MAP_OBJ_GFX_RIVAL_BRENDAN_NORMAL, MAP_OBJ_GFX_RIVAL_MAY_NORMAL},
+ {MAP_OBJ_GFX_RIVAL_BRENDAN_MACH_BIKE, MAP_OBJ_GFX_RIVAL_MAY_MACH_BIKE},
+ {MAP_OBJ_GFX_RIVAL_BRENDAN_ACRO_BIKE, MAP_OBJ_GFX_RIVAL_MAY_ACRO_BIKE},
+ {MAP_OBJ_GFX_RIVAL_BRENDAN_SURFING, MAP_OBJ_GFX_RIVAL_MAY_SURFING},
+ {MAP_OBJ_GFX_BRENDAN_UNDERWATER, MAP_OBJ_GFX_MAY_UNDERWATER},
+ {MAP_OBJ_GFX_RIVAL_BRENDAN_FIELD_MOVE, MAP_OBJ_GFX_RIVAL_MAY_FIELD_MOVE},
+ {MAP_OBJ_GFX_BRENDAN_FISHING, MAP_OBJ_GFX_MAY_FISHING},
+ {MAP_OBJ_GFX_BRENDAN_WATERING, MAP_OBJ_GFX_MAY_WATERING},
+};
+static const u8 sPlayerAvatarGfxIds[][2] =
+{
+ {MAP_OBJ_GFX_BRENDAN_NORMAL, MAP_OBJ_GFX_MAY_NORMAL},
+ {MAP_OBJ_GFX_BRENDAN_MACH_BIKE, MAP_OBJ_GFX_MAY_MACH_BIKE},
+ {MAP_OBJ_GFX_BRENDAN_ACRO_BIKE, MAP_OBJ_GFX_MAY_ACRO_BIKE},
+ {MAP_OBJ_GFX_BRENDAN_SURFING, MAP_OBJ_GFX_MAY_SURFING},
+ {MAP_OBJ_GFX_BRENDAN_UNDERWATER, MAP_OBJ_GFX_MAY_UNDERWATER},
+ {MAP_OBJ_GFX_BRENDAN_FIELD_MOVE, MAP_OBJ_GFX_MAY_FIELD_MOVE},
+ {MAP_OBJ_GFX_BRENDAN_FISHING, MAP_OBJ_GFX_MAY_FISHING},
+ {MAP_OBJ_GFX_BRENDAN_WATERING, MAP_OBJ_GFX_MAY_WATERING},
+};
+static const u8 gUnknown_0830FC64[2][5][2] =
+{
+ //male
+ {
+ {MAP_OBJ_GFX_BRENDAN_NORMAL, 1},
+ {MAP_OBJ_GFX_BRENDAN_MACH_BIKE, 2},
+ {MAP_OBJ_GFX_BRENDAN_ACRO_BIKE, 4},
+ {MAP_OBJ_GFX_BRENDAN_SURFING, 8},
+ {MAP_OBJ_GFX_BRENDAN_UNDERWATER, 16},
+ },
+ //female
+ {
+ {MAP_OBJ_GFX_MAY_NORMAL, 1},
+ {MAP_OBJ_GFX_MAY_MACH_BIKE, 2},
+ {MAP_OBJ_GFX_MAY_ACRO_BIKE, 4},
+ {MAP_OBJ_GFX_MAY_SURFING, 8},
+ {MAP_OBJ_GFX_MAY_UNDERWATER, 16},
+ }
+};
+static bool8 (*const gUnknown_0830FC78[])(u8) = //Duplicate of gUnknown_0830FC34
+{
+ MetatileBehavior_IsSouthArrowWarp,
+ MetatileBehavior_IsNorthArrowWarp,
+ MetatileBehavior_IsWestArrowWarp,
+ MetatileBehavior_IsEastArrowWarp,
+};
+static u8 (*const gUnknown_0830FC88[])(struct Task *, struct MapObject *, struct MapObject *) =
+{
+ sub_8059E84,
+ sub_8059EA4,
+ sub_8059F40,
+};
+static u8 (*const gUnknown_0830FC94[])(struct Task *, struct MapObject *) =
+{
+ sub_805A000,
+};
+static u8 (*const gUnknown_0830FC98[])(struct Task *, struct MapObject *) =
+{
+ sub_805A0D8,
+ sub_805A100,
+ sub_805A178,
+ sub_805A1B8,
+};
+
+fieldmap_object_null_cb(sub_80587B4, sub_80587D8);
+
+void player_step(u8 direction, u16 newKeys, u16 heldKeys)
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ sub_8059D60(playerMapObj);
+ if (gPlayerAvatar.unk6 == 0)
+ {
+ sub_80E5B38(newKeys, heldKeys);
+ if (!sub_8058854(playerMapObj, direction))
+ {
+ npc_clear_strange_bits(playerMapObj);
+ DoPlayerAvatarTransition();
+ if (TryDoMetatileBehaviorForcedMovement() == 0)
+ {
+ MovePlayerAvatarUsingKeypadInput(direction, newKeys, heldKeys);
+ PlayerAllowForcedMovementIfMovingSameDirection();
+ }
+ }
+ }
+}
+
+static bool8 sub_8058854(struct MapObject *playerMapObj, u8 direction)
+{
+ if (FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(playerMapObj)
+ && !FieldObjectClearAnimIfSpecialAnimFinished(playerMapObj))
+ {
+ u8 specialAnim = FieldObjectGetSpecialAnim(playerMapObj);
+
+ if (specialAnim > 24 && specialAnim < 29 && direction != DIR_NONE && playerMapObj->placeholder18 != direction)
+ {
+ FieldObjectClearAnim(playerMapObj);
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static void npc_clear_strange_bits(struct MapObject *a)
+{
+ a->mapobj_bit_12 = 0;
+ a->mapobj_bit_10 = 0;
+ a->mapobj_bit_9 = 0;
+ gPlayerAvatar.flags &= ~PLAYER_AVATAR_FLAG_DASH;
+}
+
+static void MovePlayerAvatarUsingKeypadInput(u8 direction, u16 newKeys, u16 heldKeys)
+{
+ if ((gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_MACH_BIKE)
+ || (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_ACRO_BIKE))
+ MovePlayerOnBike(direction, newKeys, heldKeys);
+ else
+ MovePlayerNotOnBike(direction, heldKeys);
+}
+
+static void PlayerAllowForcedMovementIfMovingSameDirection(void)
+{
+ if (gPlayerAvatar.running2 == 2)
+ gPlayerAvatar.flags &= ~PLAYER_AVATAR_FLAG_5;
+}
+
+static u8 TryDoMetatileBehaviorForcedMovement(void)
+{
+ return gUnknown_0830FBA0[GetForcedMovementByMetatileBehavior()]();
+}
+
+static u8 GetForcedMovementByMetatileBehavior(void)
+{
+ u8 i;
+
+ if (!(gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_5))
+ {
+ u8 r5 = gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1E;
+
+ for (i = 0; i < 18; i++)
+ {
+ if (gUnknown_0830FB58[i](r5))
+ return i + 1;
+ }
+ }
+ return 0;
+}
+
+u8 ForcedMovement_None(void)
+{
+ if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_6)
+ {
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ playerMapObj->mapobj_bit_9 = 0;
+ playerMapObj->mapobj_bit_11 = 1;
+ FieldObjectSetDirection(playerMapObj, playerMapObj->mapobj_unk_18);
+ gPlayerAvatar.flags &= ~PLAYER_AVATAR_FLAG_6;
+ }
+ return 0;
+}
+
+static u8 DoForcedMovement(u8 direction, void (*b)(u8))
+{
+ struct PlayerAvatar *playerAvatar = &gPlayerAvatar;
+ u8 collisionType = CheckForPlayerAvatarCollision(direction);
+
+ playerAvatar->flags |= PLAYER_AVATAR_FLAG_6;
+ if (collisionType != 0)
+ {
+ ForcedMovement_None();
+ if (collisionType <= 4)
+ {
+ return 0;
+ }
+ else
+ {
+ if (collisionType == COLLISION_LEDGE_JUMP)
+ PlayerJumpLedge(direction);
+ playerAvatar->flags |= PLAYER_AVATAR_FLAG_6;
+ playerAvatar->running2 = 2;
+ return 1;
+ }
+ }
+ else
+ {
+ playerAvatar->running2 = 2;
+ b(direction);
+ return 1;
+ }
+}
+
+static u8 DoForcedMovementInCurrentDirection(void (*a)(u8))
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ playerMapObj->mapobj_bit_10 = 1;
+ return DoForcedMovement(playerMapObj->placeholder18, a);
+}
+
+u8 ForcedMovement_Slip(void)
+{
+ return DoForcedMovementInCurrentDirection(sub_80593C4);
+}
+
+u8 sub_8058AAC(void)
+{
+ return DoForcedMovement(1, PlayerGoSpeed0);
+}
+
+u8 sub_8058AC4(void)
+{
+ return DoForcedMovement(2, PlayerGoSpeed0);
+}
+
+u8 sub_8058ADC(void)
+{
+ return DoForcedMovement(3, PlayerGoSpeed0);
+}
+
+u8 sub_8058AF4(void)
+{
+ return DoForcedMovement(4, PlayerGoSpeed0);
+}
+
+u8 sub_8058B0C(void)
+{
+ return DoForcedMovement(1, npc_use_some_d2s);
+}
+
+u8 sub_8058B24(void)
+{
+ return DoForcedMovement(2, npc_use_some_d2s);
+}
+
+u8 sub_8058B3C(void)
+{
+ return DoForcedMovement(3, npc_use_some_d2s);
+}
+
+u8 sub_8058B54(void)
+{
+ return DoForcedMovement(4, npc_use_some_d2s);
+}
+
+static u8 ForcedMovement_Slide(u8 direction, void (*b)(u8))
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ playerMapObj->mapobj_bit_10 = 1;
+ playerMapObj->mapobj_bit_9 = 1;
+ return DoForcedMovement(direction, b);
+}
+
+u8 ForcedMovement_SlideSouth(void)
+{
+ return ForcedMovement_Slide(1, sub_80593C4);
+}
+
+u8 ForcedMovement_SlideNorth(void)
+{
+ return ForcedMovement_Slide(2, sub_80593C4);
+}
+
+u8 ForcedMovement_SlideWest(void)
+{
+ return ForcedMovement_Slide(3, sub_80593C4);
+}
+
+u8 ForcedMovement_SlideEast(void)
+{
+ return ForcedMovement_Slide(4, sub_80593C4);
+}
+
+u8 sub_8058C04(void)
+{
+ sub_8059F94();
+ return 1;
+}
+
+u8 sub_8058C10(void)
+{
+ sub_805A06C();
+ return 1;
+}
+
+u8 ForcedMovement_MuddySlope(void)
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (playerMapObj->placeholder18 != 2 || GetPlayerSpeed() <= 3)
+ {
+ sub_80E6010(0);
+ playerMapObj->mapobj_bit_9 = 1;
+ return DoForcedMovement(1, sub_80593C4);
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+static void MovePlayerNotOnBike(u8 direction, u16 heldKeys)
+{
+ gUnknown_0830FBEC[CheckMovementInputNotOnBike(direction)](direction, heldKeys);
+}
+
+static u8 CheckMovementInputNotOnBike(u8 direction)
+{
+ if (direction == DIR_NONE)
+ {
+ gPlayerAvatar.running2 = 0;
+ return 0;
+ }
+ else if (direction != player_get_direction_upper_nybble() && gPlayerAvatar.running2 != 2)
+ {
+ gPlayerAvatar.running2 = 1;
+ return 1;
+ }
+ else
+ {
+ gPlayerAvatar.running2 = 2;
+ return 2;
+ }
+}
+
+void PlayerNotOnBikeNotMoving(u8 direction, u16 heldKeys)
+{
+ PlayerFaceDirection(player_get_direction_lower_nybble());
+}
+
+void PlayerNotOnBikeTurningInPlace(u8 direction, u16 heldKeys)
+{
+ PlayerTurnInPlace(direction);
+}
+
+void sub_8058D0C(u8 direction, u16 heldKeys)
+{
+ u8 r1 = CheckForPlayerAvatarCollision(direction);
+
+ switch (r1)
+ {
+ case 6:
+ PlayerJumpLedge(direction);
+ return;
+ default:
+ if (r1 > 8 || r1 < 5)
+ PlayerNotOnBikeCollide(direction);
+ return;
+ case 0:
+ if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_SURFING)
+ {
+ sub_80593C4(direction);
+ return;
+ }
+ if (!(gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_4) && (heldKeys & B_BUTTON) && FlagGet(SYS_B_DASH)
+ && IsRunningDisallowed(gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1E) == 0)
+ {
+ sub_805940C(direction);
+ gPlayerAvatar.flags |= PLAYER_AVATAR_FLAG_DASH;
+ }
+ else
+ {
+ PlayerGoSpeed0(direction);
+ }
+ }
+}
+
+static u8 CheckForPlayerAvatarCollision(u8 direction)
+{
+ s16 x, y;
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ x = playerMapObj->coords2.x;
+ y = playerMapObj->coords2.y;
+ MoveCoords(direction, &x, &y);
+ return CheckForFieldObjectCollision(playerMapObj, x, y, direction, MapGridGetMetatileBehaviorAt(x, y));
+}
+
+u8 CheckForFieldObjectCollision(struct MapObject *a, s16 x, s16 y, u8 direction, u8 e)
+{
+ u8 collision;
+
+ collision = npc_block_way(a, x, y, direction);
+ if (collision == 3 && sub_8058EF0(x, y, direction))
+ return 5;
+ if (ShouldJumpLedge(x, y, direction))
+ {
+ IncrementGameStat(0x2B);
+ return COLLISION_LEDGE_JUMP;
+ }
+ if (collision == 4 && sub_8058F6C(x, y, direction))
+ return 7;
+
+ if (collision == 0)
+ {
+ if (CheckForRotatingGatePuzzleCollision(direction, x, y))
+ return 8;
+ check_acro_bike_metatile(x, y, e, &collision);
+ }
+ return collision;
+}
+
+static u8 sub_8058EF0(s16 a, s16 b, u8 c)
+{
+ if ((gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_SURFING)
+ && MapGridGetZCoordAt(a, b) == 3
+ && GetFieldObjectIdByXYZ(a, b, 3) == 16)
+ {
+ sub_805A20C(c);
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+static bool8 ShouldJumpLedge(s16 a, s16 b, u8 c)
+{
+ if (GetLedgeJumpDirection(a, b, c) != 0)
+ return 1;
+ else
+ return 0;
+}
+
+static u8 sub_8058F6C(s16 a, s16 b, u8 c)
+{
+ if (FlagGet(SYS_USE_STRENGTH))
+ {
+ u8 mapObjectId = GetFieldObjectIdByXY(a, b);
+
+ if (mapObjectId != 16)
+ {
+ if (gMapObjects[mapObjectId].graphicsId == 0x57)
+ {
+ a = gMapObjects[mapObjectId].coords2.x;
+ b = gMapObjects[mapObjectId].coords2.y;
+ MoveCoords(c, &a, &b);
+ if (npc_block_way(&gMapObjects[mapObjectId], a, b, c) == 0
+ && MetatileBehavior_IsNonAnimDoor(MapGridGetMetatileBehaviorAt(a, b)) == 0)
+ {
+ StartStrengthAnim(mapObjectId, c);
+ return 1;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+static void check_acro_bike_metatile(int unused1, int unused2, u8 c, u8 *d)
+{
+ u8 i;
+
+ for (i = 0; i < 5; i++)
+ {
+ if (gUnknown_0830FBF8[i](c))
+ {
+ *d = gUnknown_0830FC0C[i];
+ return;
+ }
+ }
+}
+
+void SetPlayerAvatarTransitionFlags(u16 a)
+{
+ gPlayerAvatar.bike |= a;
+ DoPlayerAvatarTransition();
+}
+
+static void DoPlayerAvatarTransition(void)
+{
+ u8 i;
+ u32 flags = gPlayerAvatar.bike;
+
+ if (flags != 0)
+ {
+ for (i = 0; i < 8; i++, flags >>= 1)
+ {
+#ifdef NONMATCHING
+ if (flags & 1)
+ {
+ gUnknown_0830FC14[i](&gMapObjects[gPlayerAvatar.mapObjectId]);
+ }
+#else
+ if (flags & 1)
+ {
+ register void (*const *funcs)(struct MapObject *) asm("r0") = gUnknown_0830FC14;
+ funcs[i](&gMapObjects[gPlayerAvatar.mapObjectId]);
+ }
+#endif
+ }
+ gPlayerAvatar.bike = 0;
+ }
+}
+
+void nullsub_49(struct MapObject *a)
+{
+}
+
+void PlayerAvatarTransition_Normal(struct MapObject *a)
+{
+ sub_805B980(a, GetPlayerAvatarGraphicsIdByStateId(0));
+ FieldObjectTurn(a, a->placeholder18);
+ SetPlayerAvatarStateMask(1);
+}
+
+void PlayerAvatarTransition_MachBike(struct MapObject *a)
+{
+ sub_805B980(a, GetPlayerAvatarGraphicsIdByStateId(1));
+ FieldObjectTurn(a, a->placeholder18);
+ SetPlayerAvatarStateMask(2);
+ BikeClearState(0, 0);
+}
+
+void PlayerAvatarTransition_AcroBike(struct MapObject *a)
+{
+ sub_805B980(a, GetPlayerAvatarGraphicsIdByStateId(2));
+ FieldObjectTurn(a, a->placeholder18);
+ SetPlayerAvatarStateMask(4);
+ BikeClearState(0, 0);
+ sub_80E6084();
+}
+
+void PlayerAvatarTransition_Surfing(struct MapObject *a)
+{
+ u8 unk;
+
+ sub_805B980(a, GetPlayerAvatarGraphicsIdByStateId(3));
+ FieldObjectTurn(a, a->placeholder18);
+ SetPlayerAvatarStateMask(8);
+ gFieldEffectArguments[0] = a->coords2.x;
+ gFieldEffectArguments[1] = a->coords2.y;
+ gFieldEffectArguments[2] = gPlayerAvatar.mapObjectId;
+ unk = FieldEffectStart(FLDEFF_SURF_BLOB);
+ a->mapobj_unk_1A = unk;
+ sub_8127ED0(unk, 1);
+}
+
+void PlayerAvatarTransition_Underwater(struct MapObject *a)
+{
+ sub_805B980(a, GetPlayerAvatarGraphicsIdByStateId(4));
+ FieldObjectTurn(a, a->placeholder18);
+ SetPlayerAvatarStateMask(16);
+ a->mapobj_unk_1A = sub_8128124(a->spriteId);
+}
+
+void sub_80591F4(struct MapObject *a)
+{
+ gPlayerAvatar.flags |= PLAYER_AVATAR_FLAG_5;
+}
+
+void sub_8059204(void)
+{
+ gPlayerAvatar.running1 = 0;
+ if (PlayerIsAnimActive())
+ {
+ if (!PlayerCheckIfAnimFinishedOrInactive())
+ {
+ if (!player_is_anim_in_certain_ranges())
+ gPlayerAvatar.running1 = 1;
+ }
+ else
+ {
+ if (!sub_80592A4())
+ gPlayerAvatar.running1 = 2;
+ }
+ }
+}
+
+static bool8 player_is_anim_in_certain_ranges(void)
+{
+ u8 unk = gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1C;
+
+ if (unk < 4
+ || (unk >= 16 && unk < 0x15)
+ || (unk >= 25 && unk < 41)
+ || (unk >= 98 && unk < 110)
+ || (unk >= 122 && unk < 126))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static bool8 sub_80592A4(void)
+{
+ if (player_is_anim_in_certain_ranges() && gPlayerAvatar.running2 != 1)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static bool8 PlayerIsAnimActive(void)
+{
+ return FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(&gMapObjects[gPlayerAvatar.mapObjectId]);
+}
+
+static bool8 PlayerCheckIfAnimFinishedOrInactive(void)
+{
+ return FieldObjectCheckIfSpecialAnimFinishedOrInactive(&gMapObjects[gPlayerAvatar.mapObjectId]);
+}
+
+static void player_set_x22(u8 a)
+{
+ gMapObjects[gPlayerAvatar.mapObjectId].animId = a;
+}
+
+u8 player_get_x22(void)
+{
+ return gMapObjects[gPlayerAvatar.mapObjectId].animId;
+}
+
+static void sub_8059348(u8 a)
+{
+ FieldObjectForceSetSpecialAnim(&gMapObjects[gPlayerAvatar.mapObjectId], a);
+}
+
+void PlayerSetAnimId(u8 animId, u8 b)
+{
+ if (!PlayerIsAnimActive())
+ {
+ player_set_x22(b);
+ FieldObjectSetSpecialAnim(&gMapObjects[gPlayerAvatar.mapObjectId], animId);
+ }
+}
+
+void PlayerGoSpeed0(u8 a)
+{
+ PlayerSetAnimId(GetGoSpeed0AnimId(a), 2);
+}
+
+void sub_80593C4(u8 a)
+{
+ PlayerSetAnimId(sub_8060744(a), 2);
+}
+
+void npc_use_some_d2s(u8 a)
+{
+ PlayerSetAnimId(d2s_08064034(a), 2);
+}
+
+void sub_80593F4(u8 a)
+{
+ PlayerSetAnimId(sub_806079C(a), 2);
+}
+
+void sub_805940C(u8 a)
+{
+ PlayerSetAnimId(sub_80607F4(a), 2);
+}
+
+void PlayerOnBikeCollide(u8 a)
+{
+ PlayCollisionSoundIfNotFacingWarp(a);
+ PlayerSetAnimId(GetStepInPlaceDelay16AnimId(a), 2);
+}
+
+static void PlayerNotOnBikeCollide(u8 a)
+{
+ PlayCollisionSoundIfNotFacingWarp(a);
+ PlayerSetAnimId(GetStepInPlaceDelay32AnimId(a), 2);
+}
+
+void PlayerFaceDirection(u8 direction)
+{
+ PlayerSetAnimId(GetFaceDirectionAnimId(direction), 1);
+}
+
+void PlayerTurnInPlace(u8 direction)
+{
+ PlayerSetAnimId(GetStepInPlaceDelay8AnimId(direction), 1);
+}
+
+void PlayerJumpLedge(u8 direction)
+{
+ PlaySE(SE_DANSA);
+ PlayerSetAnimId(GetJumpLedgeAnimId(direction), 8);
+}
+
+void sub_80594C0(void)
+{
+ if (gPlayerAvatar.running1 == 2 || gPlayerAvatar.running1 == 0)
+ {
+ if (player_should_look_direction_be_enforced_upon_movement())
+ sub_8059348(GetFaceDirectionAnimId(gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_18));
+ }
+}
+
+void sub_8059504(u8 a)
+{
+ PlayerSetAnimId(sub_80609D8(a), 1);
+}
+
+//normal to wheelie
+void PlayerStartWheelie(u8 a)
+{
+ PlayerSetAnimId(sub_8060A04(a), 1);
+}
+
+void sub_8059534(u8 a)
+{
+ PlayerSetAnimId(sub_8060A30(a), 1);
+}
+
+void sub_805954C(u8 a)
+{
+ PlaySE(SE_JITE_PYOKO);
+ PlayerSetAnimId(sub_8060A5C(a), 1);
+}
+
+void sub_8059570(u8 a)
+{
+ PlaySE(SE_JITE_PYOKO);
+ PlayerSetAnimId(sub_8060A88(a), 2);
+}
+
+void sub_8059594(u8 a)
+{
+ PlaySE(SE_JITE_PYOKO);
+ PlayerSetAnimId(sub_8060AB4(a), 8);
+}
+
+void sub_80595B8(u8 direction)
+{
+ PlaySE(SE_JITE_PYOKO);
+ PlayerSetAnimId(sub_8060878(direction), 1);
+}
+
+void sub_80595DC(u8 direction)
+{
+ PlaySE(SE_WALL_HIT);
+ PlayerSetAnimId(sub_8060AE0(direction), 2);
+}
+
+void sub_8059600(u8 a)
+{
+ PlayerSetAnimId(sub_8060B0C(a), 2);
+}
+
+void sub_8059618(u8 a)
+{
+ PlayerSetAnimId(sub_8060B38(a), 2);
+}
+
+void sub_8059630(u8 a)
+{
+ PlayerSetAnimId(sub_8060B64(a), 2);
+}
+
+static void PlayCollisionSoundIfNotFacingWarp(u8 a)
+{
+ s16 x, y;
+ u8 unk = gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1E;
+
+ if (!gUnknown_0830FC34[a - 1](unk))
+ {
+ if (a == 2)
+ {
+ PlayerGetDestCoords(&x, &y);
+ MoveCoords(2, &x, &y);
+ if (MetatileBehavior_IsWarpDoor(MapGridGetMetatileBehaviorAt(x, y)))
+ return;
+ }
+ PlaySE(SE_WALL_HIT);
+ }
+}
+
+void GetXYCoordsOneStepInFrontOfPlayer(s16 *x, s16 *y)
+{
+ *x = gMapObjects[gPlayerAvatar.mapObjectId].coords2.x;
+ *y = gMapObjects[gPlayerAvatar.mapObjectId].coords2.y;
+ MoveCoords(player_get_direction_lower_nybble(), x, y);
+}
+
+void PlayerGetDestCoords(s16 *x, s16 *y)
+{
+ *x = gMapObjects[gPlayerAvatar.mapObjectId].coords2.x;
+ *y = gMapObjects[gPlayerAvatar.mapObjectId].coords2.y;
+}
+
+u8 player_get_direction_lower_nybble(void)
+{
+ return gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_18;
+}
+
+u8 player_get_direction_upper_nybble(void)
+{
+ return gMapObjects[gPlayerAvatar.mapObjectId].placeholder18;
+}
+
+u8 PlayerGetZCoord(void)
+{
+ return gMapObjects[gPlayerAvatar.mapObjectId].elevation;
+}
+
+void unref_sub_8059790(s16 a, s16 b)
+{
+ sub_805C058(&gMapObjects[gPlayerAvatar.mapObjectId], a, b);
+}
+
+u8 TestPlayerAvatarFlags(u8 a)
+{
+ return gPlayerAvatar.flags & a;
+}
+
+u8 sub_80597D0(void)
+{
+ return gPlayerAvatar.flags;
+}
+
+u8 GetPlayerAvatarObjectId(void)
+{
+ return gPlayerAvatar.spriteId;
+}
+
+void sub_80597E8(void)
+{
+ ForcedMovement_None();
+}
+
+void sub_80597F4(void)
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ npc_clear_strange_bits(playerMapObj);
+ FieldObjectSetDirection(playerMapObj, playerMapObj->mapobj_unk_18);
+ if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE))
+ {
+ sub_80E6084();
+ sub_80E6010(0);
+ }
+}
+
+u8 GetRivalAvatarGraphicsIdByStateIdAndGender(u8 state, u8 gender)
+{
+ return sRivalAvatarGfxIds[state][gender];
+}
+
+static u8 GetPlayerAvatarGraphicsIdByStateIdAndGender(u8 state, u8 gender)
+{
+ return sPlayerAvatarGfxIds[state][gender];
+}
+
+u8 GetPlayerAvatarGraphicsIdByStateId(u8 state)
+{
+ return GetPlayerAvatarGraphicsIdByStateIdAndGender(state, gPlayerAvatar.gender);
+}
+
+u8 unref_GetRivalAvatarGenderByGraphcsId(u8 gfxId)
+{
+ switch (gfxId)
+ {
+ case MAP_OBJ_GFX_RIVAL_MAY_NORMAL:
+ case MAP_OBJ_GFX_RIVAL_MAY_MACH_BIKE:
+ case MAP_OBJ_GFX_RIVAL_MAY_ACRO_BIKE:
+ case MAP_OBJ_GFX_RIVAL_MAY_SURFING:
+ case MAP_OBJ_GFX_RIVAL_MAY_FIELD_MOVE:
+ case MAP_OBJ_GFX_MAY_UNDERWATER:
+ case MAP_OBJ_GFX_MAY_FISHING:
+ case MAP_OBJ_GFX_MAY_WATERING:
+ return FEMALE;
+ default:
+ return MALE;
+ }
+}
+
+u8 GetPlayerAvatarGenderByGraphicsId(u8 gfxId)
+{
+ switch (gfxId)
+ {
+ case MAP_OBJ_GFX_MAY_NORMAL:
+ case MAP_OBJ_GFX_MAY_MACH_BIKE:
+ case MAP_OBJ_GFX_MAY_ACRO_BIKE:
+ case MAP_OBJ_GFX_MAY_SURFING:
+ case MAP_OBJ_GFX_MAY_FIELD_MOVE:
+ case MAP_OBJ_GFX_MAY_UNDERWATER:
+ case MAP_OBJ_GFX_MAY_FISHING:
+ case MAP_OBJ_GFX_MAY_WATERING:
+ return FEMALE;
+ default:
+ return MALE;
+ }
+}
+
+bool8 PartyHasMonWithSurf(void)
+{
+ u8 i;
+
+ if (!TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING))
+ {
+ for (i = 0; i < 6; i++)
+ {
+ if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) == 0)
+ break;
+ if (pokemon_has_move(&gPlayerParty[i], 0x39))
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+bool8 IsPlayerSurfingNorth(void)
+{
+ if (player_get_direction_upper_nybble() == DIR_NORTH && TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 IsPlayerFacingSurfableFishableWater(void)
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+ s16 x = playerMapObj->coords2.x;
+ s16 y = playerMapObj->coords2.y;
+
+ MoveCoords(playerMapObj->mapobj_unk_18, &x, &y);
+ if (npc_block_way(playerMapObj, x, y, playerMapObj->mapobj_unk_18) == 3 && PlayerGetZCoord() == 3
+ && MetatileBehavior_IsSurfableFishableWater(MapGridGetMetatileBehaviorAt(x, y)))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void ClearPlayerAvatarInfo(void)
+{
+ //TODO: 0x24 should be the size of gPlayerAvatar
+ memset(&gPlayerAvatar, 0, sizeof(struct PlayerAvatar));
+}
+
+void SetPlayerAvatarStateMask(u8 a)
+{
+ gPlayerAvatar.flags &= 0xE0;
+ gPlayerAvatar.flags |= a;
+}
+
+static u8 GetPlayerAvatarStateTransitionByGraphicsId(u8 a, u8 gender)
+{
+ u8 i;
+
+ for (i = 0; i < 5; i++)
+ {
+ if (gUnknown_0830FC64[gender][i][0] == a)
+ return gUnknown_0830FC64[gender][i][1];
+ }
+ return 1;
+}
+
+u8 GetPlayerAvatarGraphicsIdByCurrentState(void)
+{
+ u8 i;
+ u8 r5 = gPlayerAvatar.flags;
+
+ for (i = 0; i < 5; i++)
+ {
+ if (gUnknown_0830FC64[gPlayerAvatar.gender][i][1] & r5)
+ return gUnknown_0830FC64[gPlayerAvatar.gender][i][0];
+ }
+ return 0;
+}
+
+void SetPlayerAvatarExtraStateTransition(u8 a, u8 b)
+{
+ u8 unk = GetPlayerAvatarStateTransitionByGraphicsId(a, gPlayerAvatar.gender);
+
+ gPlayerAvatar.bike |= unk | b;
+ DoPlayerAvatarTransition();
+}
+
+void InitPlayerAvatar(s16 x, s16 y, u8 direction, u8 gender)
+{
+ struct MapObjectTemplate playerMapObjTemplate;
+ u8 mapObjectId;
+ struct MapObject *mapObject;
+
+ playerMapObjTemplate.localId = 0xFF;
+ playerMapObjTemplate.graphicsId = GetPlayerAvatarGraphicsIdByStateIdAndGender(0, gender);
+ playerMapObjTemplate.x = x - 7;
+ playerMapObjTemplate.y = y - 7;
+ playerMapObjTemplate.elevation = 0;
+ playerMapObjTemplate.movementType = 11;
+ playerMapObjTemplate.unkA_0 = 0;
+ playerMapObjTemplate.unkA_4 = 0;
+ playerMapObjTemplate.unkC = 0;
+ playerMapObjTemplate.unkE = 0;
+ playerMapObjTemplate.script = NULL;
+ playerMapObjTemplate.flagId = 0;
+ mapObjectId = SpawnSpecialFieldObject(&playerMapObjTemplate);
+ mapObject = &gMapObjects[mapObjectId];
+ mapObject->mapobj_bit_16 = 1;
+ mapObject->mapobj_unk_1B = sub_8126B54();
+ FieldObjectTurn(mapObject, direction);
+ ClearPlayerAvatarInfo();
+ gPlayerAvatar.running2 = 0;
+ gPlayerAvatar.running1 = 0;
+ gPlayerAvatar.mapObjectId = mapObjectId;
+ gPlayerAvatar.spriteId = mapObject->spriteId;
+ gPlayerAvatar.gender = gender;
+ SetPlayerAvatarStateMask(0x21);
+}
+
+void sub_8059B88(u8 a)
+{
+ gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_13 = a;
+ if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING))
+ gSprites[gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1A].invisible = a;
+}
+
+void sub_8059BF4(void)
+{
+ sub_805B980(&gMapObjects[gPlayerAvatar.mapObjectId], GetPlayerAvatarGraphicsIdByStateId(5));
+ StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], 0);
+}
+
+void sub_8059C3C(u8 a)
+{
+ sub_805B980(&gMapObjects[gPlayerAvatar.mapObjectId], GetPlayerAvatarGraphicsIdByStateId(6));
+ StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], sub_805FDE8(a));
+}
+
+void sub_8059C94(u8 a)
+{
+ sub_805B980(&gMapObjects[gPlayerAvatar.mapObjectId], GetPlayerAvatarGraphicsIdByStateId(2));
+ StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], sub_805FD98(a));
+ SeekSpriteAnim(&gSprites[gPlayerAvatar.spriteId], 1);
+}
+
+void sub_8059D08(u8 a)
+{
+ sub_805B980(&gMapObjects[gPlayerAvatar.mapObjectId], GetPlayerAvatarGraphicsIdByStateId(7));
+ StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], FieldObjectDirectionToImageAnimId(a));
+}
+
+static void sub_8059D60(struct MapObject *a)
+{
+ s16 x;
+ s16 y;
+ u8 r6;
+ u8 r8 = a->mapobj_unk_1E;
+
+ for (x = 0, r6 = 1; x < 4; x++, r6++)
+ {
+ if (gUnknown_0830FC78[x](r8) && r6 == a->placeholder18)
+ {
+ x = a->coords2.x;
+ y = a->coords2.y;
+ MoveCoords(r6, &x, &y);
+ sub_8126BC4(a->mapobj_unk_1B, r6, x, y);
+ return;
+ }
+ }
+ objid_set_invisible(a->mapobj_unk_1B);
+}
+
+/* Strength */
+
+static void sub_8059E2C(u8 taskId);
+
+static void StartStrengthAnim(u8 a, u8 b)
+{
+ u8 taskId = CreateTask(sub_8059E2C, 0xFF);
+
+ gTasks[taskId].data[1] = a;
+ gTasks[taskId].data[2] = b;
+ sub_8059E2C(taskId);
+}
+
+static void sub_8059E2C(u8 taskId)
+{
+ while (gUnknown_0830FC88[gTasks[taskId].data[0]](&gTasks[taskId],
+ &gMapObjects[gPlayerAvatar.mapObjectId],
+ &gMapObjects[gTasks[taskId].data[1]]))
+ ;
+}
+
+u8 sub_8059E84(struct Task *task, struct MapObject *b, struct MapObject *c)
+{
+ ScriptContext2_Enable();
+ gPlayerAvatar.unk6 = 1;
+ task->data[0]++;
+ return 0;
+}
+
+u8 sub_8059EA4(struct Task *task, struct MapObject *b, struct MapObject *c)
+{
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(b)
+ && !FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(c))
+ {
+ FieldObjectClearAnimIfSpecialAnimFinished(b);
+ FieldObjectClearAnimIfSpecialAnimFinished(c);
+ FieldObjectSetSpecialAnim(b, GetStepInPlaceDelay16AnimId((u8)task->data[2]));
+ FieldObjectSetSpecialAnim(c, GetSimpleGoAnimId((u8)task->data[2]));
+ gFieldEffectArguments[0] = c->coords2.x;
+ gFieldEffectArguments[1] = c->coords2.y;
+ gFieldEffectArguments[2] = c->elevation;
+ gFieldEffectArguments[3] = gSprites[c->spriteId].oam.priority;
+ FieldEffectStart(FLDEFF_DUST);
+ PlaySE(SE_W070);
+ task->data[0]++;
+ }
+ return 0;
+}
+
+u8 sub_8059F40(struct Task *task, struct MapObject *b, struct MapObject *c)
+{
+ if (FieldObjectCheckIfSpecialAnimFinishedOrInactive(b)
+ && FieldObjectCheckIfSpecialAnimFinishedOrInactive(c))
+ {
+ FieldObjectClearAnimIfSpecialAnimFinished(b);
+ FieldObjectClearAnimIfSpecialAnimFinished(c);
+ gPlayerAvatar.unk6 = 0;
+ ScriptContext2_Disable();
+ DestroyTask(FindTaskIdByFunc(sub_8059E2C));
+ }
+ return 0;
+}
+
+/* Some field effect */
+
+static void sub_8059FB4(u8 taskId);
+
+static void sub_8059F94(void)
+{
+ u8 taskId = CreateTask(sub_8059FB4, 0xFF);
+
+ sub_8059FB4(taskId);
+}
+
+static void sub_8059FB4(u8 taskId)
+{
+ while (gUnknown_0830FC94[gTasks[taskId].data[0]](&gTasks[taskId], &gMapObjects[gPlayerAvatar.mapObjectId]))
+ ;
+}
+
+u8 sub_805A000(struct Task *task, struct MapObject *mapObject)
+{
+ gPlayerAvatar.unk6 = 1;
+ if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ PlaySE(SE_DANSA);
+ FieldObjectSetSpecialAnim(mapObject, sub_806084C(mapObject->mapobj_unk_18));
+ task->data[1]++;
+ if (task->data[1] > 1)
+ {
+ gPlayerAvatar.unk6 = 0;
+ gPlayerAvatar.bike |= 0x20;
+ DestroyTask(FindTaskIdByFunc(sub_8059FB4));
+ }
+ }
+ return 0;
+}
+
+/* Some field effect */
+
+static void sub_805A08C(u8 taskId);
+
+static void sub_805A06C(void)
+{
+ u8 taskId = CreateTask(sub_805A08C, 0xFF);
+
+ sub_805A08C(taskId);
+}
+
+static void sub_805A08C(u8 taskId)
+{
+ while (gUnknown_0830FC98[gTasks[taskId].data[0]](&gTasks[taskId], &gMapObjects[gPlayerAvatar.mapObjectId]))
+ ;
+}
+
+u8 sub_805A0D8(struct Task *task, struct MapObject *mapObject)
+{
+ task->data[0]++;
+ task->data[1] = mapObject->placeholder18;
+ gPlayerAvatar.unk6 = 1;
+ ScriptContext2_Enable();
+ PlaySE(SE_TK_WARPIN);
+ return 1;
+}
+
+u8 sub_805A100(struct Task *task, struct MapObject *mapObject)
+{
+ u8 directions[] = {DIR_WEST, DIR_EAST, DIR_NORTH, DIR_SOUTH};
+
+ if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ u8 direction;
+
+ FieldObjectSetSpecialAnim(mapObject, GetFaceDirectionAnimId(direction = directions[mapObject->placeholder18 - 1]));
+ if (direction == (u8)task->data[1])
+ task->data[2]++;
+ task->data[0]++;
+ if (task->data[2] > 3 && direction == GetOppositeDirection(task->data[1]))
+ task->data[0]++;
+ }
+ return 0;
+}
+
+u8 sub_805A178(struct Task *task, struct MapObject *mapObject)
+{
+ const u8 arr[] = {16, 16, 17, 18, 19};
+
+ if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ FieldObjectSetSpecialAnim(mapObject, arr[task->data[2]]);
+ task->data[0] = 1;
+ }
+ return 0;
+}
+
+u8 sub_805A1B8(struct Task *task, struct MapObject *mapObject)
+{
+ if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject))
+ {
+ FieldObjectSetSpecialAnim(mapObject, GetSimpleGoAnimId(GetOppositeDirection(task->data[1])));
+ ScriptContext2_Disable();
+ gPlayerAvatar.unk6 = 0;
+ DestroyTask(FindTaskIdByFunc(sub_805A08C));
+ }
+ return 0;
+}
+
+/* Some Field effect */
+
+static void taskFF_0805D1D4(u8 taskId);
+static void sub_805A2D0(u8 taskId);
+
+void sub_805A20C(u8 a)
+{
+ u8 taskId;
+
+ ScriptContext2_Enable();
+ Overworld_ClearSavedMusic();
+ Overworld_ChangeMusicToDefault();
+ gPlayerAvatar.flags &= ~PLAYER_AVATAR_FLAG_SURFING;
+ gPlayerAvatar.flags |= PLAYER_AVATAR_FLAG_ON_FOOT;
+ gPlayerAvatar.unk6 = 1;
+ taskId = CreateTask(taskFF_0805D1D4, 0xFF);
+ gTasks[taskId].data[0] = a;
+ taskFF_0805D1D4(taskId);
+}
+
+static void taskFF_0805D1D4(u8 taskId)
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(playerMapObj))
+ {
+ if (!FieldObjectClearAnimIfSpecialAnimFinished(playerMapObj))
+ return;
+ }
+ sub_8127ED0(playerMapObj->mapobj_unk_1A, 2);
+ FieldObjectSetSpecialAnim(playerMapObj, sub_80608D0((u8)gTasks[taskId].data[0]));
+ gTasks[taskId].func = sub_805A2D0;
+}
+
+static void sub_805A2D0(u8 taskId)
+{
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (FieldObjectClearAnimIfSpecialAnimFinished(playerMapObj))
+ {
+ sub_805B980(playerMapObj, GetPlayerAvatarGraphicsIdByStateId(0));
+ FieldObjectSetSpecialAnim(playerMapObj, GetFaceDirectionAnimId(playerMapObj->mapobj_unk_18));
+ gPlayerAvatar.unk6 = 0;
+ ScriptContext2_Disable();
+ DestroySprite(&gSprites[playerMapObj->mapobj_unk_1A]);
+ DestroyTask(taskId);
+ }
+}
+
+/* Fishing */
+
+static u8 (*const sFishingStateFuncs[])(struct Task *) =
+{
+ Fishing1,
+ Fishing2,
+ Fishing3,
+ Fishing4,
+ Fishing5,
+ Fishing6,
+ Fishing7,
+ Fishing8,
+ Fishing9,
+ Fishing10,
+ Fishing11,
+ Fishing12,
+ Fishing13,
+ Fishing14,
+ Fishing15,
+ Fishing16,
+};
+
+static void Task_Fishing(u8 taskId);
+static void sub_805A954(void);
+
+#define tStep data[0]
+#define tFrameCounter data[1]
+#define tNumDots data[2]
+#define tDotsRequired data[3]
+#define tRoundsPlayed data[12]
+#define tMinRoundsRequired data[13]
+#define tPlayerGfxId data[14]
+#define tFishingRod data[15]
+
+#define FISHING_START_ROUND 3
+#define FISHING_GOT_BITE 6
+#define FISHING_ON_HOOK 9
+#define FISHING_NO_BITE 11
+#define FISHING_GOT_AWAY 12
+#define FISHING_SHOW_RESULT 13
+
+void StartFishing(u8 rod)
+{
+ u8 taskId = CreateTask(Task_Fishing, 0xFF);
+
+ gTasks[taskId].tFishingRod = rod;
+ Task_Fishing(taskId);
+}
+
+static void Task_Fishing(u8 taskId)
+{
+ while (sFishingStateFuncs[gTasks[taskId].tStep](&gTasks[taskId]))
+ ;
+}
+
+u8 Fishing1(struct Task *task)
+{
+ ScriptContext2_Enable();
+ gPlayerAvatar.unk6 = 1;
+ task->tStep++;
+ return 0;
+}
+
+u8 Fishing2(struct Task *task)
+{
+ struct MapObject *playerMapObj;
+ const s16 arr1[] = {1, 1, 1};
+ const s16 arr2[] = {1, 3, 6};
+
+ task->tRoundsPlayed = 0;
+ task->tMinRoundsRequired = arr1[task->tFishingRod] + (Random() % arr2[task->tFishingRod]);
+ task->tPlayerGfxId = gMapObjects[gPlayerAvatar.mapObjectId].graphicsId;
+ playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+ FieldObjectClearAnimIfSpecialAnimActive(playerMapObj);
+ playerMapObj->mapobj_bit_11 = 1;
+ sub_8059C3C(playerMapObj->mapobj_unk_18);
+ task->tStep++;
+ return 0;
+}
+
+u8 Fishing3(struct Task *task)
+{
+ sub_805A954();
+
+ // Wait one second before starting dot game
+ task->tFrameCounter++;
+ if (task->tFrameCounter >= 60)
+ task->tStep++;
+ return 0;
+}
+
+u8 Fishing4(struct Task *task)
+{
+ u32 randVal;
+
+ MenuDisplayMessageBox();
+ task->tStep++;
+ task->tFrameCounter = 0;
+ task->tNumDots = 0;
+ randVal = Random();
+ randVal %= 10;
+ task->tDotsRequired = randVal + 1;
+ if (task->tRoundsPlayed == 0)
+ task->tDotsRequired = randVal + 4;
+ if (task->tDotsRequired >= 10)
+ task->tDotsRequired = 10;
+ return 1;
+}
+
+// Play a round of the dot game
+u8 Fishing5(struct Task *task)
+{
+ const u8 dot[] = _("·");
+
+ sub_805A954();
+ task->tFrameCounter++;
+ if (gMain.newKeys & A_BUTTON)
+ {
+ task->tStep = FISHING_NO_BITE;
+ if (task->tRoundsPlayed != 0)
+ task->tStep = FISHING_GOT_AWAY;
+ return 1;
+ }
+ else
+ {
+ if (task->tFrameCounter >= 20)
+ {
+ task->tFrameCounter = 0;
+ if (task->tNumDots >= task->tDotsRequired)
+ {
+ task->tStep++;
+ if (task->tRoundsPlayed != 0)
+ task->tStep++;
+ task->tRoundsPlayed++;
+ }
+ else
+ {
+ MenuPrint(dot, task->tNumDots + 4, 15);
+ task->tNumDots++;
+ }
+ }
+ return 0;
+ }
+}
+
+// Determine if fish bites
+u8 Fishing6(struct Task *task)
+{
+ sub_805A954();
+ task->tStep++;
+ if (!DoesCurrentMapHaveFishingMons() || (Random() & 1))
+ task->tStep = FISHING_NO_BITE;
+ else
+ StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], sub_805FE08(player_get_direction_lower_nybble()));
+ return 1;
+}
+
+// Oh! A Bite!
+u8 Fishing7(struct Task *task)
+{
+ sub_805A954();
+ MenuPrint(gOtherText_OhABite, 4, 17);
+ task->tStep++;
+ task->tFrameCounter = 0;
+ return 0;
+}
+
+// We have a bite. Now, wait for the player to press A, or the timer to expire.
+u8 Fishing8(struct Task *task)
+{
+ const s16 reelTimeouts[3] = {36, 33, 30};
+
+ sub_805A954();
+ task->tFrameCounter++;
+ if (task->tFrameCounter >= reelTimeouts[task->tFishingRod])
+ task->tStep = FISHING_GOT_AWAY;
+ else if (gMain.newKeys & A_BUTTON)
+ task->tStep++;
+ return 0;
+}
+
+// Determine if we're going to play the dot game again
+u8 Fishing9(struct Task *task)
+{
+ const s16 arr[][2] =
+ {
+ {0, 0},
+ {40, 10},
+ {70, 30}
+ };
+
+ sub_805A954();
+ task->tStep++;
+ if (task->tRoundsPlayed < task->tMinRoundsRequired)
+ {
+ task->tStep = FISHING_START_ROUND;
+ }
+ else if (task->tRoundsPlayed < 2)
+ {
+ // probability of having to play another round
+ s16 probability = Random() % 100;
+
+ if (arr[task->tFishingRod][task->tRoundsPlayed] > probability)
+ task->tStep = FISHING_START_ROUND;
+ }
+ return 0;
+}
+
+u8 Fishing10(struct Task *task)
+{
+ sub_805A954();
+ MenuPrintMessageDefaultCoords(gOtherText_PokeOnHook);
+ MenuDisplayMessageBox();
+ task->tStep++;
+ task->tFrameCounter = 0;
+ return 0;
+}
+
+u8 Fishing11(struct Task *task)
+{
+ if (task->tFrameCounter == 0)
+ sub_805A954();
+
+ if (task->tFrameCounter == 0)
+ {
+ if (MenuUpdateWindowText())
+ {
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ sub_805B980(playerMapObj, task->tPlayerGfxId);
+ FieldObjectTurn(playerMapObj, playerMapObj->placeholder18);
+ if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_SURFING)
+ sub_8127F28(gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1A, 0, 0);
+ gSprites[gPlayerAvatar.spriteId].pos2.x = 0;
+ gSprites[gPlayerAvatar.spriteId].pos2.y = 0;
+ MenuZeroFillScreen();
+ task->tFrameCounter++;
+ return 0;
+ }
+ }
+
+ if (task->tFrameCounter != 0)
+ {
+ gPlayerAvatar.unk6 = 0;
+ ScriptContext2_Disable();
+ FishingWildEncounter(task->tFishingRod);
+ sub_80BE97C(1);
+ DestroyTask(FindTaskIdByFunc(Task_Fishing));
+ }
+ return 0;
+}
+
+// Not even a nibble
+u8 Fishing12(struct Task *task)
+{
+ sub_805A954();
+ StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], sub_805FDF8(player_get_direction_lower_nybble()));
+ MenuPrintMessageDefaultCoords(gOtherText_NotEvenANibble);
+ task->tStep = FISHING_SHOW_RESULT;
+ return 1;
+}
+
+// It got away
+u8 Fishing13(struct Task *task)
+{
+ sub_805A954();
+ StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], sub_805FDF8(player_get_direction_lower_nybble()));
+ MenuPrintMessageDefaultCoords(gOtherText_ItGotAway);
+ task->tStep++;
+ return 1;
+}
+
+// Display the message
+u8 Fishing14(struct Task *task)
+{
+ sub_805A954();
+ MenuDisplayMessageBox();
+ task->tStep++;
+ return 0;
+}
+
+u8 Fishing15(struct Task *task)
+{
+ sub_805A954();
+ if (gSprites[gPlayerAvatar.spriteId].animEnded)
+ {
+ struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ sub_805B980(playerMapObj, task->tPlayerGfxId);
+ FieldObjectTurn(playerMapObj, playerMapObj->placeholder18);
+ if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_SURFING)
+ sub_8127F28(gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1A, 0, 0);
+ gSprites[gPlayerAvatar.spriteId].pos2.x = 0;
+ gSprites[gPlayerAvatar.spriteId].pos2.y = 0;
+ task->tStep++;
+ }
+ return 0;
+}
+
+u8 Fishing16(struct Task *task)
+{
+ if (MenuUpdateWindowText())
+ {
+ gPlayerAvatar.unk6 = 0;
+ ScriptContext2_Disable();
+ UnfreezeMapObjects();
+ MenuZeroFillScreen();
+ sub_80BE97C(0);
+ DestroyTask(FindTaskIdByFunc(Task_Fishing));
+ }
+ return 0;
+}
+
+#undef tStep
+#undef tFrameCounter
+#undef tFishingRod
+
+static void sub_805A954(void)
+{
+ struct Sprite *playerSprite = &gSprites[gPlayerAvatar.spriteId];
+ u8 animCmdIndex;
+ u8 animType;
+
+ AnimateSprite(playerSprite);
+ playerSprite->pos2.x = 0;
+ playerSprite->pos2.y = 0;
+ animCmdIndex = playerSprite->animCmdIndex;
+ if (playerSprite->anims[playerSprite->animNum][animCmdIndex].type == -1)
+ {
+ animCmdIndex--;
+ }
+ else
+ {
+ playerSprite->animDelayCounter++;
+ if (playerSprite->anims[playerSprite->animNum][animCmdIndex].type == -1)
+ animCmdIndex--;
+ }
+ animType = playerSprite->anims[playerSprite->animNum][animCmdIndex].type;
+ if (animType == 1 || animType == 2 || animType == 3)
+ {
+ playerSprite->pos2.x = 8;
+ if (player_get_direction_lower_nybble() == 3)
+ playerSprite->pos2.x = -8;
+ }
+ if (animType == 5)
+ playerSprite->pos2.y = -8;
+ if (animType == 10 || animType == 11)
+ playerSprite->pos2.y = 8;
+ if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_SURFING)
+ sub_8127F28(gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1A, 1, playerSprite->pos2.y);
+}
diff --git a/src/field/field_poison.c b/src/field/field_poison.c
new file mode 100644
index 000000000..1244b9c62
--- /dev/null
+++ b/src/field/field_poison.c
@@ -0,0 +1,143 @@
+#include "global.h"
+#include "field_poison.h"
+#include "field_message_box.h"
+#include "fldeff_80C5CD4.h"
+#include "pokemon.h"
+#include "pokemon_summary_screen.h"
+#include "script.h"
+#include "string_util.h"
+#include "task.h"
+#include "text.h"
+
+extern u16 gScriptResult;
+extern u8 fieldPoisonText_PokemonFainted[];
+
+bool32 CheckMonIsValid(struct Pokemon *pkmn)
+{
+ // UB: Too few arguments for function 'GetMonData'
+ u16 species2 = GetMonData(pkmn, MON_DATA_SPECIES2);
+
+ if (species2 == 0 || species2 == 0x19C)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+bool32 AllMonsFainted(void)
+{
+ struct Pokemon *pkmn = &gPlayerParty[0];
+ int i;
+
+ for (i = 0; i < 6; i++, pkmn++)
+ {
+ // UB: Too few arguments for function 'GetMonData'
+ if (CheckMonIsValid(pkmn) && GetMonData(pkmn, MON_DATA_HP) != 0)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void MonFaintFromPoisonOnField(u8 partyMember)
+{
+ struct Pokemon *pkmn = &gPlayerParty[partyMember];
+ u32 val = 0;
+
+ AdjustFriendship(pkmn, 7);
+ SetMonData(pkmn, MON_DATA_STATUS, (u8*)&val);
+ GetMonData(pkmn, MON_DATA_NICKNAME, gStringVar1);
+ StringGetEnd10(gStringVar1);
+}
+
+bool32 CheckMonFaintedFromPoison(u8 partyMember)
+{
+ struct Pokemon *pkmn = &gPlayerParty[partyMember];
+
+ // UB: Too few arguments for function 'GetMonData'
+ if (CheckMonIsValid(pkmn) && GetMonData(pkmn, MON_DATA_HP) == 0
+ && pokemon_ailments_get_primary(GetMonData(pkmn, MON_DATA_STATUS)) == 1)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+//Task data
+enum
+{
+ TD_STATE,
+ TD_PARTY_MEMBER,
+};
+
+void Task_WhiteOut(u8 taskId)
+{
+ s16 *taskData = gTasks[taskId].data;
+
+ switch (taskData[TD_STATE])
+ {
+ case 0: //Check if Pokemon have fainted due to poison
+ while (taskData[TD_PARTY_MEMBER] < 6)
+ {
+ if (CheckMonFaintedFromPoison(taskData[TD_PARTY_MEMBER]))
+ {
+ MonFaintFromPoisonOnField(taskData[TD_PARTY_MEMBER]);
+ ShowFieldMessage(fieldPoisonText_PokemonFainted);
+ taskData[TD_STATE]++;
+ return;
+ }
+ taskData[TD_PARTY_MEMBER]++;
+ }
+ taskData[TD_STATE] = 2;
+ break;
+ case 1: //Wait for message box to disappear
+ if (IsFieldMessageBoxHidden())
+ taskData[TD_STATE]--; //Check next party member
+ break;
+ case 2: //Done checking Pokemon
+ if (AllMonsFainted())
+ gScriptResult = 1;
+ else
+ gScriptResult = 0;
+ EnableBothScriptContexts();
+ DestroyTask(taskId);
+ break;
+ }
+}
+
+void ExecuteWhiteOut(void)
+{
+ CreateTask(Task_WhiteOut, 0x50);
+ ScriptContext1_Stop();
+}
+
+s32 DoPoisonFieldEffect(void)
+{
+ struct Pokemon *pkmn = &gPlayerParty[0];
+ u32 numPoisoned = 0;
+ u32 numFainting = 0;
+ int i;
+
+ for (i = 0; i < 6; i++)
+ {
+ u32 hp;
+
+ // UB: Too few arguments for function 'GetMonData'
+ if (GetMonData(pkmn, MON_DATA_SANITY_BIT2) != 0
+ && pokemon_ailments_get_primary(GetMonData(pkmn, MON_DATA_STATUS)) == 1)
+ {
+ hp = GetMonData(pkmn, MON_DATA_HP);
+ if (hp != 0)
+ hp--;
+ if (hp == 0)
+ numFainting++; //Pokemon will now faint due to poison
+ SetMonData(pkmn, MON_DATA_HP, (u8 *)&hp);
+ numPoisoned++;
+ }
+ pkmn++;
+ }
+ if (numFainting != 0 || numPoisoned != 0)
+ DoFieldPoisonEffect();
+ if (numFainting != 0)
+ return 2;
+ if (numPoisoned != 0)
+ return 1;
+ return 0;
+}
diff --git a/src/field/field_region_map.c b/src/field/field_region_map.c
new file mode 100644
index 000000000..7cb22e5df
--- /dev/null
+++ b/src/field/field_region_map.c
@@ -0,0 +1,125 @@
+#include "global.h"
+#include "field_region_map.h"
+#include "main.h"
+#include "menu.h"
+#include "palette.h"
+#include "region_map.h"
+#include "sprite.h"
+#include "strings2.h"
+#include "text.h"
+
+struct RegionMapStruct
+{
+ u8 str[0x16];
+ u8 unk16;
+ u8 filler[0x869];
+};
+
+struct UnkStruct
+{
+ MainCallback callback;
+ u8 filler[4];
+ // This should be RegionMap, but I can't do that because it overlaps unk888.
+ struct RegionMapStruct unk8;
+ u16 unk888;
+};
+
+extern u8 ewram[];
+#define unk_2000000 (*(struct UnkStruct *)(ewram))
+
+void FieldInitRegionMap(MainCallback callback)
+{
+ SetVBlankCallback(NULL);
+ unk_2000000.unk888 = 0;
+ unk_2000000.callback = callback;
+ SetMainCallback2(CB2_FieldInitRegionMap);
+}
+
+void CB2_FieldInitRegionMap(void)
+{
+ REG_DISPCNT = 0;
+ REG_BG0HOFS = 0;
+ REG_BG0VOFS = 0;
+ REG_BG1HOFS = 0;
+ REG_BG1VOFS = 0;
+ REG_BG2HOFS = 0;
+ REG_BG2VOFS = 0;
+ REG_BG3HOFS = 0;
+ REG_BG3VOFS = 0;
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ // TODO: remove this cast
+ InitRegionMap((void *)&unk_2000000.unk8, 0);
+ CreateRegionMapPlayerIcon(0, 0);
+ CreateRegionMapCursor(1, 1);
+ SetUpWindowConfig(&gWindowConfig_81E709C);
+ InitMenuWindow(&gWindowConfig_81E709C);
+ MenuZeroFillScreen();
+ REG_BG0CNT = BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(31) | BGCNT_16COLOR | BGCNT_TXT256x256;
+ MenuDrawTextWindow(21, 0, 29, 3);
+ sub_8072BD8(gOtherText_Hoenn, 0x16, 1, 0x38);
+ MenuDrawTextWindow(16, 16, 29, 19);
+ sub_813F0C8();
+ SetMainCallback2(CB2_FieldRegionMap);
+ SetVBlankCallback(VBlankCB_FieldRegionMap);
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, 0);
+}
+
+void VBlankCB_FieldRegionMap(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+void CB2_FieldRegionMap(void)
+{
+ sub_813EFDC();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+}
+
+void sub_813EFDC(void)
+{
+ switch (unk_2000000.unk888)
+ {
+ case 0:
+ REG_DISPCNT = DISPCNT_MODE_1 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON | DISPCNT_BG2_ON | DISPCNT_OBJ_ON;
+ unk_2000000.unk888++;
+ break;
+ case 1:
+ if (!gPaletteFade.active)
+ unk_2000000.unk888++;
+ break;
+ case 2:
+ switch (sub_80FAB60())
+ {
+ case 3:
+ sub_813F0C8();
+ break;
+ case 4:
+ case 5:
+ unk_2000000.unk888++;
+ }
+ break;
+ case 3:
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, 0);
+ unk_2000000.unk888++;
+ break;
+ case 4:
+ if (!gPaletteFade.active)
+ {
+ FreeRegionMapIconResources();
+ SetMainCallback2(unk_2000000.callback);
+ }
+ break;
+ }
+}
+
+void sub_813F0C8(void)
+{
+ MenuFillWindowRectWithBlankTile(17, 17, 28, 18);
+ if (unk_2000000.unk8.unk16)
+ MenuPrint(unk_2000000.unk8.str, 17, 17);
+}
diff --git a/src/field/field_screen_effect.c b/src/field/field_screen_effect.c
new file mode 100644
index 000000000..0c76d254d
--- /dev/null
+++ b/src/field/field_screen_effect.c
@@ -0,0 +1,341 @@
+#include "global.h"
+#include "event_data.h"
+#include "field_camera.h"
+#include "menu.h"
+#include "palette.h"
+#include "overworld.h"
+#include "script.h"
+#include "task.h"
+#include "text.h"
+#include "unknown_task.h"
+
+struct UnknownStruct1
+{
+ u8 filler0[0x14];
+ u8 unk14;
+ u8 filler15[0xB];
+};
+extern struct UnknownStruct1 gUnknown_03004DC0;
+
+extern u16 gUnknown_03004DE0[][0x3C0];
+
+const static u16 gUnknown_0839ACDC[] = { 0xC8, 0x48, 0x38, 0x28, 0x18, 0x0 };
+
+const s32 gMaxFlashLevel = 4;
+
+const static struct UnknownTaskStruct gUnknown_0839ACEC =
+{
+ (void *)REG_ADDR_WIN0H,
+ ((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_DEST_RELOAD) << 16) | 1,
+ 1
+};
+
+static void sub_808136C(u16 *dest, u32 a2, s32 a3, s32 a4)
+{
+ if (a2 <= 0xA0)
+ {
+ if (a3 < 0)
+ a3 = 0;
+ if (a3 > 255)
+ a3 = 255;
+ if (a4 < 0)
+ a4 = 0;
+ if (a4 > 255)
+ a4 = 255;
+ dest[a2] = (a3 << 8) | a4;
+ }
+}
+
+static void sub_8081398(u16 *dest, s32 a2, s32 a3, s32 a4)
+{
+ s32 v1 = a4;
+ s32 v2 = a4;
+ s32 v3 = 0;
+ while (v1 >= v3)
+ {
+ sub_808136C(dest, a3 - v3, a2 - v1, a2 + v1);
+ sub_808136C(dest, a3 + v3, a2 - v1, a2 + v1);
+ sub_808136C(dest, a3 - v1, a2 - v3, a2 + v3);
+ sub_808136C(dest, a3 + v1, a2 - v3, a2 + v3);
+ v2 -= (v3 * 2) - 1;
+ v3++;
+ if (v2 < 0)
+ {
+ v2 += 2 * (v1 - 1);
+ v1--;
+ }
+ }
+}
+
+static void sub_8081424(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ switch (data[0])
+ {
+ case 0:
+ sub_8081398(&gUnknown_03004DE0[gUnknown_03004DC0.unk14][0], data[1], data[2], data[3]);
+ data[0] = 1;
+ break;
+ case 1:
+ sub_8081398(&gUnknown_03004DE0[gUnknown_03004DC0.unk14][0], data[1], data[2], data[3]);
+ data[0] = 0;
+ data[3] += data[5];
+ if (data[3] > data[4])
+ {
+ if (data[6] == 1)
+ {
+ remove_some_task();
+ data[0] = 2;
+ }
+ else
+ {
+ DestroyTask(taskId);
+ }
+ }
+ break;
+ case 2:
+ dp12_8087EA4();
+ DestroyTask(taskId);
+ break;
+ }
+}
+
+static void sub_80814E8(u8 taskId)
+{
+ if (!FuncIsActiveTask(sub_8081424))
+ {
+ EnableBothScriptContexts();
+ DestroyTask(taskId);
+ }
+}
+
+static void sub_8081510(void)
+{
+ if (!FuncIsActiveTask(sub_80814E8))
+ CreateTask(sub_80814E8, 80);
+}
+
+static u8 sub_8081534(s32 a1, s32 a2, s32 a3, s32 a4, s32 a5, u8 a6)
+{
+ u8 taskId = CreateTask(sub_8081424, 80);
+ s16 *data = gTasks[taskId].data;
+
+ data[3] = a3;
+ data[4] = a4;
+ data[1] = a1;
+ data[2] = a2;
+ data[6] = a5;
+
+ if (a3 < a4)
+ data[5] = a6;
+ else
+ data[5] = -a6;
+
+ return taskId;
+}
+
+void sub_8081594(u8 a1)
+{
+ u8 flashLevel = Overworld_GetFlashLevel();
+ u8 value = 0;
+ if (!a1)
+ value = 1;
+ sub_8081534(120, 80, gUnknown_0839ACDC[flashLevel], gUnknown_0839ACDC[a1], value, 1);
+ sub_8081510();
+ ScriptContext2_Enable();
+}
+
+void sub_80815E0(u8 a1)
+{
+ if (a1)
+ {
+ sub_8081398(&gUnknown_03004DE0[0][0], 120, 80, gUnknown_0839ACDC[a1]);
+ CpuFastSet(&gUnknown_03004DE0[0], &gUnknown_03004DE0[1], 480);
+ }
+}
+
+static void sub_808161C(u8 a1)
+{
+ int i;
+ u16 color[1];
+
+ if (!a1)
+ color[0] = 0x1F;
+ else
+ color[0] = 0x7C00;
+
+ for (i = 0; i < 16; i++)
+ {
+ LoadPalette(color, 0xF0 + i, 2);
+ }
+}
+
+static bool8 sub_8081658(u16 a1)
+{
+ u8 lo = REG_BLDALPHA & 0xFF;
+ u8 hi = REG_BLDALPHA >> 8;
+
+ if (a1)
+ {
+ if (lo)
+ {
+ lo--;
+ }
+ }
+ else
+ {
+ if (hi < 0x10)
+ {
+ hi++;
+ }
+ }
+
+ REG_BLDALPHA = (hi << 8) | lo;
+
+ if (lo == 0 && hi == 0x10)
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void sub_80816A8(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ switch (data[0])
+ {
+ case 0:
+ data[6] = REG_DISPCNT;
+ data[7] = REG_BLDCNT;
+ data[8] = REG_BLDALPHA;
+ data[9] = REG_WININ;
+ data[10] = REG_WINOUT;
+ REG_DISPCNT &= 0xBFFF;
+ REG_BLDCNT |= gUnknown_081E29E8[0];
+ REG_BLDALPHA = 1804;
+ REG_WININ = 63;
+ REG_WINOUT = 30;
+ sub_8081398(&gUnknown_03004DE0[0][0], data[2], data[3], 1);
+ CpuFastSet(&gUnknown_03004DE0[0], &gUnknown_03004DE0[1], 480);
+ //sub_80895F8(gUnknown_0839ACEC[0], gUnknown_0839ACEC[1], gUnknown_0839ACEC[2]);
+ sub_80895F8(gUnknown_0839ACEC);
+ data[0] = 1;
+ break;
+ case 1:
+ MenuFillWindowRectWithBlankTile(0, 0, 29, 19);
+ sub_808161C(data[1]);
+ sub_8081534(data[2], data[3], 1, 160, 1, 2);
+ data[0] = 2;
+ break;
+ case 2:
+ if (!FuncIsActiveTask(sub_8081424))
+ {
+ EnableBothScriptContexts();
+ data[0] = 3;
+ }
+ break;
+ case 3:
+ InstallCameraPanAheadCallback();
+ SetCameraPanningCallback(NULL);
+ data[5] = 0;
+ data[4] = 4;
+ data[0] = 4;
+ break;
+ case 4:
+ data[4]--;
+ if (!data[4])
+ {
+ s32 panning;
+ data[4] = 4;
+ data[5] ^= 1;
+ if (data[5])
+ panning = 4;
+ else
+ panning = -4;
+ SetCameraPanning(0, panning);
+ }
+ break;
+ case 6:
+ InstallCameraPanAheadCallback();
+ data[4] = 8;
+ data[0] = 7;
+ break;
+ case 7:
+ data[4]--;
+ if (!data[4])
+ {
+ data[4] = 8;
+ data[5] ^= 1;
+ if (sub_8081658(data[5]) == TRUE)
+ data[0] = 5;
+ }
+ break;
+ case 5:
+ MenuZeroFillWindowRect(0, 0, 29, 19);
+ LoadFontDefaultPalette(&gWindowConfig_81E6CE4);
+ REG_WIN0H = 255;
+ REG_DISPCNT = data[6];
+ REG_BLDCNT = data[7];
+ REG_BLDALPHA = data[8];
+ REG_WININ = data[9];
+ REG_WINOUT = data[10];
+ EnableBothScriptContexts();
+ DestroyTask(taskId);
+ break;
+ }
+}
+
+void sub_80818A4(void)
+{
+ u8 taskId = CreateTask(sub_80816A8, 80);
+ s16 *data = gTasks[taskId].data;
+
+ if (gScriptResult == 0)
+ {
+ data[1] = 0;
+ data[2] = 104;
+ }
+ else if (gScriptResult == 1)
+ {
+ data[1] = 1;
+ data[2] = 104;
+ }
+ else if (gScriptResult == 2)
+ {
+ data[1] = 0;
+ data[2] = 120;
+ }
+ else
+ {
+ data[1] = 1;
+ data[2] = 120;
+ }
+
+ data[3] = 80;
+}
+
+void sub_80818FC(void)
+{
+ u8 taskId = FindTaskIdByFunc(sub_80816A8);
+ gTasks[taskId].data[0] = 6;
+}
+
+static void task50_0807F0C8(u8);
+
+void sub_8081924(void)
+{
+ Overworld_FadeOutMapMusic();
+ CreateTask(task50_0807F0C8, 80);
+}
+
+static void task50_0807F0C8(u8 taskId)
+{
+ if (sub_8054034() == TRUE)
+ {
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+ }
+}
diff --git a/src/field/field_special_scene.c b/src/field/field_special_scene.c
new file mode 100644
index 000000000..d4b59c8a2
--- /dev/null
+++ b/src/field/field_special_scene.c
@@ -0,0 +1,349 @@
+#include "global.h"
+#include "field_special_scene.h"
+#include "event_data.h"
+#include "field_camera.h"
+#include "field_fadetransition.h"
+#include "field_map_obj.h"
+#include "field_specials.h"
+#include "fieldmap.h"
+#include "main.h"
+#include "palette.h"
+#include "overworld.h"
+#include "script.h"
+#include "script_movement.h"
+#include "songs.h"
+#include "sound.h"
+#include "sprite.h"
+#include "task.h"
+
+#define SECONDS(value) ((signed) (60.0 * value + 0.5))
+
+// porthole states
+enum
+{
+ INIT_PORTHOLE,
+ IDLE_CHECK,
+ EXECUTE_MOVEMENT,
+ EXIT_PORTHOLE,
+};
+
+extern s8 gTruckCamera_HorizontalTable[];
+
+extern u8 gUnknown_083D295F[];
+extern u8 gUnknown_083D2961[];
+
+s32 GetTruckCameraBobbingY(int a1)
+{
+ if (!(a1 % 120))
+ return -1;
+ else if ((a1 % 10) <= 4)
+ return 1;
+
+ return 0;
+}
+
+s32 GetTruckBoxMovement(int a1) // for the box movement?
+{
+ if (!((a1 + 120) % 180))
+ return -1;
+
+ return 0;
+}
+
+void Task_Truck1(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ s16 cameraYpan;
+ s16 box1 = 0;
+ s16 box2 = 0;
+ s16 box3 = 0;
+ u8 mapNum, mapGroup;
+ register s16 zero asm("r4");
+
+ box1 = GetTruckBoxMovement(data[0] + 30) * 4; // top box.
+ sub_805BD90(1, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup, 3, box1 + 3);
+ box2 = GetTruckBoxMovement(data[0]) * 2; // bottom left box.
+ sub_805BD90(2, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup, 0, box2 - 3);
+ box3 = GetTruckBoxMovement(data[0]) * 4; // bottom right box.
+ mapNum = gSaveBlock1.location.mapNum;
+ mapGroup = gSaveBlock1.location.mapGroup;
+ zero = 0;
+ sub_805BD90(3, mapNum, mapGroup, -3, box3);
+
+ if (++data[0] == SECONDS(500)) // this will never run
+ data[0] = zero; // reset the timer if it gets stuck.
+
+ cameraYpan = GetTruckCameraBobbingY(data[0]);
+ SetCameraPanning(0, cameraYpan);
+}
+
+void Task_Truck2(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ s16 cameraYpan;
+ s16 cameraXpan;
+ s16 box1;
+ s16 box2;
+ s16 box3;
+
+ data[0]++;
+ data[2]++;
+
+ if (data[0] > 5)
+ {
+ data[0] = 0;
+ data[1]++;
+ }
+ if ((u16)data[1] == 19)
+ {
+ DestroyTask(taskId);
+ }
+ else
+ {
+ if (gTruckCamera_HorizontalTable[data[1]] == 2)
+ gTasks[taskId].func = Task_Truck3;
+
+ cameraXpan = gTruckCamera_HorizontalTable[data[1]];
+ cameraYpan = GetTruckCameraBobbingY(data[2]);
+ SetCameraPanning(cameraXpan, cameraYpan);
+ box1 = GetTruckBoxMovement(data[2] + 30) * 4;
+ sub_805BD90(1, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup, 3 - cameraXpan, box1 + 3);
+ box2 = GetTruckBoxMovement(data[2]) * 2;
+ sub_805BD90(2, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup, -cameraXpan, box2 - 3);
+ box3 = GetTruckBoxMovement(data[2]) * 4;
+ sub_805BD90(3, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup, -3 - cameraXpan, box3);
+ }
+}
+
+void Task_Truck3(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ s16 cameraXpan;
+ s16 cameraYpan;
+
+ data[0]++;
+
+ if (data[0] > 5)
+ {
+ data[0] = 0;
+ data[1]++;
+ }
+
+ if ((u16)data[1] == 19)
+ {
+ DestroyTask(taskId);
+ }
+ else
+ {
+ cameraXpan = gTruckCamera_HorizontalTable[data[1]];
+ cameraYpan = 0;
+ SetCameraPanning(cameraXpan, 0);
+ sub_805BD90(1, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup, 3 - cameraXpan, cameraYpan + 3);
+ sub_805BD90(2, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup, -cameraXpan, cameraYpan - 3);
+ sub_805BD90(3, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup, -3 - cameraXpan, cameraYpan);
+ }
+}
+
+void Task_HandleTruckSequence(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ switch (data[0])
+ {
+ /*
+ Each case has a timer which is handled with data[1], incrementing
+ until it reaches the if function's condition, which sets the next task up.
+ */
+ case 0:
+ data[1]++;
+ if (data[1] == SECONDS(1.5))
+ {
+ SetCameraPanningCallback(0);
+ data[1] = 0; // reset the timer.
+ data[2] = CreateTask(Task_Truck1, 0xA);
+ data[0] = 1; // run the next case.
+ PlaySE(SE_TRACK_MOVE);
+ }
+ break;
+ case 1:
+ data[1]++;
+ if (data[1] == SECONDS(2.5))
+ {
+ pal_fill_black();
+ data[1] = 0;
+ data[0] = 2;
+ }
+ break;
+ case 2:
+ data[1]++;
+ if (!gPaletteFade.active && data[1] > SECONDS(5))
+ {
+ data[1] = 0;
+ DestroyTask(data[2]);
+ data[3] = CreateTask(Task_Truck2, 0xA);
+ data[0] = 3;
+ PlaySE(SE_TRACK_STOP);
+ }
+ break;
+ case 3:
+ if (!gTasks[data[3]].isActive) // is Truck2 no longer active (is Truck3 active?)
+ {
+ InstallCameraPanAheadCallback();
+ data[1] = 0;
+ data[0] = 4;
+ }
+ break;
+ case 4:
+ data[1]++;
+ if (data[1] == 90)
+ {
+ PlaySE(SE_TRACK_HAIK);
+ data[1] = 0;
+ data[0] = 5;
+ }
+ break;
+ case 5:
+ data[1]++;
+ if (data[1] == 120)
+ {
+ MapGridSetMetatileIdAt(11, 8, 520);
+ MapGridSetMetatileIdAt(11, 9, 528);
+ MapGridSetMetatileIdAt(11, 10, 536);
+ DrawWholeMapView();
+ PlaySE(SE_TRACK_DOOR);
+ DestroyTask(taskId);
+ ScriptContext2_Disable();
+ }
+ break;
+ }
+}
+
+void ExecuteTruckSequence(void)
+{
+ MapGridSetMetatileIdAt(11, 8, 525);
+ MapGridSetMetatileIdAt(11, 9, 533);
+ MapGridSetMetatileIdAt(11, 10, 541);
+ DrawWholeMapView();
+ ScriptContext2_Enable();
+ CpuFastFill(0, gPlttBufferFaded, 0x400);
+ CreateTask(Task_HandleTruckSequence, 0xA);
+}
+
+void EndTruckSequence(u8 taskId)
+{
+ if (!FuncIsActiveTask(Task_HandleTruckSequence))
+ {
+ sub_805BD90(1, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup, 3, 3);
+ sub_805BD90(2, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup, 0, -3);
+ sub_805BD90(3, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup, -3, 0);
+ }
+}
+
+bool8 sub_80C7754(void)
+{
+ s8 mapGroup, mapNum;
+ s16 x, y;
+
+ if (GetSSTidalLocation(&mapGroup, &mapNum, &x, &y))
+ {
+ return FALSE;
+ }
+ else
+ {
+ Overworld_SetWarpDestination(mapGroup, mapNum, -1, x, y);
+ return TRUE;
+ }
+}
+
+void Task_HandlePorthole(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+ u16 *var = GetVarPointer(VAR_PORTHOLE);
+ struct WarpData *location = &gSaveBlock1.location;
+
+ switch (data[0])
+ {
+ case INIT_PORTHOLE: // finish fading before making porthole finish.
+ if (!gPaletteFade.active)
+ {
+ data[1] = 0;
+ data[0] = EXECUTE_MOVEMENT; // execute movement before checking if should be exited. strange?
+ }
+ break;
+ case IDLE_CHECK: // idle and move.
+ if (gMain.newKeys & A_BUTTON)
+ data[1] = 1;
+ if (!ScriptMovement_IsObjectMovementFinished(0xFF, location->mapNum, location->mapGroup))
+ return;
+ if (CountSSTidalStep(1) == TRUE)
+ {
+ if (*var == 2)
+ *var = 9;
+ else
+ *var = 10;
+ data[0] = 3;
+ return;
+ }
+ data[0] = 2;
+ case EXECUTE_MOVEMENT: // execute movement.
+ if (data[1])
+ {
+ data[0] = EXIT_PORTHOLE; // exit porthole.
+ return;
+ }
+ // run this once.
+ if (*var == 2) // which direction?
+ {
+ ScriptMovement_StartObjectMovementScript(0xFF, location->mapNum, location->mapGroup, gUnknown_083D295F);
+ data[0] = IDLE_CHECK; // run case 1.
+ }
+ else
+ {
+ ScriptMovement_StartObjectMovementScript(0xFF, location->mapNum, location->mapGroup, gUnknown_083D2961);
+ data[0] = IDLE_CHECK; // run case 1.
+ }
+ break;
+ case EXIT_PORTHOLE: // exit porthole.
+ FlagClear(0x4001);
+ FlagClear(0x4000);
+ copy_saved_warp2_bank_and_enter_x_to_warp1(0);
+ sp13E_warp_to_last_warp();
+ DestroyTask(taskId);
+ break;
+ }
+}
+
+void sub_80C78A0(void)
+{
+ u8 spriteId = AddPseudoFieldObject(0x8C, SpriteCallbackDummy, 112, 80, 0);
+
+ gSprites[spriteId].coordOffsetEnabled = FALSE;
+
+ if (VarGet(0x40B4) == 2)
+ {
+ StartSpriteAnim(&gSprites[spriteId], FieldObjectDirectionToImageAnimId(4));
+ }
+ else
+ {
+ StartSpriteAnim(&gSprites[spriteId], FieldObjectDirectionToImageAnimId(3));
+ }
+}
+
+void sub_80C791C(void)
+{
+ sub_80C78A0();
+ gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_13 = TRUE;
+ pal_fill_black();
+ CreateTask(Task_HandlePorthole, 80);
+ ScriptContext2_Enable();
+}
+
+void sub_80C7958(void)
+{
+ FlagSet(SYS_CRUISE_MODE);
+ FlagSet(0x4001);
+ FlagSet(0x4000);
+ saved_warp2_set(0, gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum, -1);
+ sub_80C7754();
+ sub_8080F9C();
+}
diff --git a/src/field/field_specials.c b/src/field/field_specials.c
new file mode 100644
index 000000000..36362d098
--- /dev/null
+++ b/src/field/field_specials.c
@@ -0,0 +1,2383 @@
+#include "global.h"
+#include "field_specials.h"
+#include "diploma.h"
+#include "fieldmap.h"
+#include "event_data.h"
+#include "battle_tower.h"
+#include "field_map_obj.h"
+#include "region_map.h"
+#include "field_region_map.h"
+#include "field_message_box.h"
+#include "field_camera.h"
+#include "field_player_avatar.h"
+#include "main.h"
+#include "map_constants.h"
+#include "overworld.h"
+#include "script.h"
+#include "songs.h"
+#include "string_util.h"
+#include "strings.h"
+#include "pokeblock.h"
+#include "species.h"
+#include "abilities.h"
+#include "moves.h"
+#include "text.h"
+#include "wallclock.h"
+#include "tv.h"
+#include "rtc.h"
+#include "link.h"
+#include "songs.h"
+#include "sound.h"
+#include "menu.h"
+#include "starter_choose.h"
+#include "menu_helpers.h"
+#include "battle_tower.h"
+#include "field_weather.h"
+#include "pokemon_summary_screen.h"
+#include "rng.h"
+
+#if ENGLISH
+#define CHAR_DECIMAL_SEPARATOR CHAR_PERIOD
+#elif GERMAN
+#define CHAR_DECIMAL_SEPARATOR CHAR_COMMA
+#endif
+
+extern struct WarpData gUnknown_020297F0;
+extern u8 gBattleOutcome;
+extern u16 gSpecialVar_0x8004;
+extern u16 gSpecialVar_0x8005;
+extern u16 gScriptResult;
+
+EWRAM_DATA u8 gUnknown_02039250 = 0;
+EWRAM_DATA u8 gUnknown_02039251 = 0;
+EWRAM_DATA u32 gUnknown_02039254 = 0;
+EWRAM_DATA u8 gUnknown_02039258 = 0;
+EWRAM_DATA u8 gUnknown_02039259 = 0;
+EWRAM_DATA u8 gUnknown_0203925A = 0;
+EWRAM_DATA u8 gUnknown_0203925B = 0;
+EWRAM_DATA u8 gUnknown_0203925C = 0;
+
+static void RecordCyclingRoadResults(u32, u8);
+
+static struct ElevatorMenu gUnknown_03000760[20];
+
+void ScrSpecial_ShowDiploma(void)
+{
+ SetMainCallback2(CB2_ShowDiploma);
+ ScriptContext2_Enable();
+}
+
+void ScrSpecial_ViewWallClock(void)
+{
+ gMain.savedCallback = c2_exit_to_overworld_2_switch;
+ SetMainCallback2(CB2_ViewWallClock);
+ ScriptContext2_Enable();
+}
+
+void ResetCyclingRoadChallengeData(void)
+{
+ gUnknown_02039250 = 0;
+ gUnknown_02039251 = 0;
+ gUnknown_02039254 = 0;
+}
+
+void ScrSpecial_BeginCyclingRoadChallenge(void)
+{
+ gUnknown_02039250 = 1;
+ gUnknown_02039251 = 0;
+ gUnknown_02039254 = gMain.vblankCounter1;
+}
+
+u16 GetPlayerAvatarBike(void)
+{
+ if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_ACRO_BIKE))
+ return 1;
+ if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE))
+ return 2;
+ return 0;
+}
+
+static void DetermineCyclingRoadResults(u32 arg0, u8 arg1)
+{
+ u8 result;
+
+ if (arg1 <= 99)
+ {
+ ConvertIntToDecimalStringN(gStringVar1, arg1, STR_CONV_MODE_LEFT_ALIGN, 2);
+ StringAppend(gStringVar1, gOtherText_Times);
+ }
+ else
+ {
+ StringCopy(gStringVar1, gOtherText_99Times);
+ }
+
+ if (arg0 < 3600)
+ {
+ ConvertIntToDecimalStringN(gStringVar2, arg0 / 60, STR_CONV_MODE_RIGHT_ALIGN, 2);
+ gStringVar2[2] = CHAR_DECIMAL_SEPARATOR;
+ ConvertIntToDecimalStringN(&gStringVar2[3], ((arg0 % 60) * 100) / 60, STR_CONV_MODE_LEADING_ZEROS, 2);
+ StringAppend(gStringVar2, gOtherText_Seconds);
+ }
+ else
+ {
+ StringCopy(gStringVar2, gOtherText_1Minute);
+ }
+
+ result = 0;
+ if (arg1 == 0)
+ {
+ result = 5;
+ }
+ else if (arg1 < 4)
+ {
+ result = 4;
+ }
+ else if (arg1 < 10)
+ {
+ result = 3;
+ }
+ else if (arg1 < 20)
+ {
+ result = 2;
+ }
+ else if (arg1 < 100)
+ {
+ result = 1;
+ }
+
+ if (arg0 / 60 <= 10)
+ {
+ result += 5;
+ }
+ else if (arg0 / 60 <= 15)
+ {
+ result += 4;
+ }
+ else if (arg0 / 60 <= 20)
+ {
+ result += 3;
+ }
+ else if (arg0 / 60 <= 40)
+ {
+ result += 2;
+ }
+ else if (arg0 / 60 < 60)
+ {
+ result += 1;
+ }
+
+
+ gScriptResult = result;
+}
+
+void FinishCyclingRoadChallenge(void) {
+ const u32 time = gMain.vblankCounter1 - gUnknown_02039254;
+
+ DetermineCyclingRoadResults(time, gUnknown_02039251);
+ RecordCyclingRoadResults(time, gUnknown_02039251);
+}
+
+static void RecordCyclingRoadResults(u32 arg0, u8 arg1) {
+ u16 high = VarGet(0x4028);
+ u16 low = VarGet(0x4029);
+ u32 record = high + (low << 16);
+
+ if (record > arg0 || record == 0)
+ {
+ VarSet(0x4028, arg0);
+ VarSet(0x4029, arg0 >> 16);
+ VarSet(0x4027, arg1);
+ }
+}
+
+u16 GetRecordedCyclingRoadResults(void) {
+ u16 high = VarGet(0x4028);
+ u16 low = VarGet(0x4029);
+ u32 record = high + (low << 16);
+
+ if (record == 0)
+ {
+ return FALSE;
+ }
+
+ DetermineCyclingRoadResults(record, VarGet(0x4027));
+ return TRUE;
+}
+
+void UpdateCyclingRoadState(void) {
+ if (gUnknown_020297F0.mapNum == MAP_ID_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE && gUnknown_020297F0.mapGroup == MAP_GROUP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE)
+ {
+ return;
+ }
+
+ if (VarGet(0x40a9) == 2 || VarGet(0x40a9) == 3)
+ {
+ VarSet(0x40a9, 0);
+ Overworld_SetSavedMusic(SE_STOP);
+ }
+}
+
+void SetSSTidalFlag(void)
+{
+ FlagSet(SYS_CRUISE_MODE);
+ *GetVarPointer(VAR_CRUISE_STEP_COUNT) = 0;
+}
+
+void ResetSSTidalFlag(void)
+{
+ FlagClear(SYS_CRUISE_MODE);
+}
+
+bool32 CountSSTidalStep(u16 delta)
+{
+ if (!FlagGet(SYS_CRUISE_MODE) || (*GetVarPointer(VAR_CRUISE_STEP_COUNT) += delta) <= 0xcc)
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+u8 GetSSTidalLocation(s8 *mapGroup, s8 *mapNum, s16 *x, s16 *y)
+{
+ u16 *varCruiseStepCount = GetVarPointer(VAR_CRUISE_STEP_COUNT);
+ switch (*GetVarPointer(VAR_PORTHOLE))
+ {
+ case 1:
+ case 8:
+ return 1;
+ case 3:
+ case 9:
+ return 4;
+ case 4:
+ case 5:
+ return 2;
+ case 6:
+ case 10:
+ return 3;
+ case 2:
+ if (*varCruiseStepCount < 60)
+ {
+ *mapNum = MAP_ID_ROUTE134;
+ *x = *varCruiseStepCount + 19;
+ }
+ else if (*varCruiseStepCount < 140)
+ {
+ *mapNum = MAP_ID_ROUTE133;
+ *x = *varCruiseStepCount - 60;
+ }
+ else
+ {
+ *mapNum = MAP_ID_ROUTE132;
+ *x = *varCruiseStepCount - 140;
+ }
+ break;
+ case 7:
+ if (*varCruiseStepCount < 66)
+ {
+ *mapNum = MAP_ID_ROUTE132;
+ *x = 65 - *varCruiseStepCount;
+ }
+ else if (*varCruiseStepCount < 146) {
+ *mapNum = MAP_ID_ROUTE133;
+ *x = 145 - *varCruiseStepCount;
+ }
+ else
+ {
+ *mapNum = MAP_ID_ROUTE134;
+ *x = 224 - *varCruiseStepCount;
+ }
+ break;
+ }
+ *mapGroup = MAP_GROUP_ROUTE132;
+ *y = 20;
+ return 0;
+}
+
+u8 GetLinkPartnerNames(void)
+{
+ u8 i;
+ u8 j = 0;
+ u8 myLinkPlayerNumber = sub_8008218();
+ u8 nLinkPlayers = sub_800820C();
+ for (i=0; i<nLinkPlayers; i++)
+ {
+ if (myLinkPlayerNumber != i)
+ {
+ StringCopy(gUnknown_083D1464[j], gLinkPlayers[i].name);
+ j++;
+ }
+ }
+ return nLinkPlayers;
+}
+
+const u8 gUnknown_083F8358[4] = {7, 9, 8, 10};
+const s8 gUnknown_083F835C[4][2] = {
+ { 0, 1},
+ { 1, 0},
+ { 0, -1},
+ {-1, 0}
+};
+
+void SpawnBerryBlenderLinkPlayerSprites(void)
+{
+ u8 unknown_083F8358[4];
+ u8 unknown_083F835C[4][2];
+ u8 myLinkPlayerNumber;
+ u8 playerDirectionLowerNybble;
+ u8 rivalAvatarGraphicsId;
+ u8 i;
+ u8 j = 0;
+ s16 x = 0;
+ s16 y = 0;
+
+ memcpy(unknown_083F8358, gUnknown_083F8358, sizeof gUnknown_083F8358);
+ memcpy(unknown_083F835C, gUnknown_083F835C, sizeof gUnknown_083F835C);
+ myLinkPlayerNumber = sub_8008218();
+ playerDirectionLowerNybble = player_get_direction_lower_nybble();
+ switch (playerDirectionLowerNybble)
+ {
+ case DIR_WEST:
+ j = 2;
+ x = gSaveBlock1.pos.x - 1;
+ y = gSaveBlock1.pos.y;
+ break;
+ case DIR_NORTH:
+ j = 1;
+ x = gSaveBlock1.pos.x;
+ y = gSaveBlock1.pos.y - 1;
+ break;
+ case DIR_EAST:
+ x = gSaveBlock1.pos.x + 1;
+ y = gSaveBlock1.pos.y;
+ break;
+ case DIR_SOUTH:
+ j = 3;
+ x = gSaveBlock1.pos.x;
+ y = gSaveBlock1.pos.y + 1;
+ }
+ for (i=0; i<gSpecialVar_0x8004; i++)
+ {
+ if (myLinkPlayerNumber != i)
+ {
+ rivalAvatarGraphicsId = GetRivalAvatarGraphicsIdByStateIdAndGender(0, gLinkPlayers[i].gender);
+ SpawnSpecialFieldObjectParametrized(rivalAvatarGraphicsId, unknown_083F8358[j], 0xf0 - i, (s8)unknown_083F835C[j][0] + x + 7, (s8)unknown_083F835C[j][1] + y + 7, 0);
+ j++;
+ if (j == 4)
+ {
+ j = 0;
+ }
+ }
+ }
+}
+
+struct Coords8 {
+ u8 x;
+ u8 y;
+};
+
+const struct Coords8 gUnknown_083F8364[3] = {
+ { 7, 16},
+ {15, 18},
+ {11, 22}
+};
+
+void MauvilleGymSpecial1(void)
+{
+ u8 i;
+ for (i=0; i<3; i++)
+ {
+ if (i == gSpecialVar_0x8004)
+ {
+ MapGridSetMetatileIdAt(gUnknown_083F8364[i].x, gUnknown_083F8364[i].y, 0x206);
+ }
+ else
+ {
+ MapGridSetMetatileIdAt(gUnknown_083F8364[i].x, gUnknown_083F8364[i].y, 0x205);
+ }
+ }
+}
+
+void MauvilleGymSpecial2(void)
+{
+ int x, y;
+ for (y=12; y<24; y++)
+ {
+ for (x=7; x<16; x++)
+ {
+ switch (MapGridGetMetatileIdAt(x, y))
+ {
+ case 0x220:
+ MapGridSetMetatileIdAt(x, y, 0x230);
+ break;
+ case 0x221:
+ MapGridSetMetatileIdAt(x, y, 0x231);
+ break;
+ case 0x228:
+ MapGridSetMetatileIdAt(x, y, 0x238);
+ break;
+ case 0x229:
+ MapGridSetMetatileIdAt(x, y, 0x239);
+ break;
+ case 0x230:
+ MapGridSetMetatileIdAt(x, y, 0x220);
+ break;
+ case 0x231:
+ MapGridSetMetatileIdAt(x, y, 0x221);
+ break;
+ case 0x238:
+ MapGridSetMetatileIdAt(x, y, 0xe28);
+ break;
+ case 0x239:
+ MapGridSetMetatileIdAt(x, y, 0xe29);
+ break;
+ case 0x222:
+ MapGridSetMetatileIdAt(x, y, 0x232);
+ break;
+ case 0x223:
+ MapGridSetMetatileIdAt(x, y, 0x233);
+ break;
+ case 0x22a:
+ MapGridSetMetatileIdAt(x, y, 0x23a);
+ break;
+ case 0x22b:
+ MapGridSetMetatileIdAt(x, y, 0x23b);
+ break;
+ case 0x232:
+ MapGridSetMetatileIdAt(x, y, 0x222);
+ break;
+ case 0x233:
+ MapGridSetMetatileIdAt(x, y, 0x223);
+ break;
+ case 0x23a:
+ MapGridSetMetatileIdAt(x, y, 0xe2a);
+ break;
+ case 0x23b:
+ MapGridSetMetatileIdAt(x, y, 0xe2b);
+ break;
+ case 0x240:
+ MapGridSetMetatileIdAt(x, y, 0xe42);
+ break;
+ case 0x248:
+ MapGridSetMetatileIdAt(x, y, 0x21a);
+ break;
+ case 0x241:
+ MapGridSetMetatileIdAt(x, y, 0xe43);
+ break;
+ case 0x249:
+ MapGridSetMetatileIdAt(x, y, 0x21a);
+ break;
+ case 0x242:
+ MapGridSetMetatileIdAt(x, y, 0xe40);
+ break;
+ case 0x21a:
+ if (MapGridGetMetatileIdAt(x, y - 1) == 0x240)
+ {
+ MapGridSetMetatileIdAt(x, y, 0xe48);
+ }
+ else
+ {
+ MapGridSetMetatileIdAt(x, y, 0xe49);
+ }
+ break;
+ case 0x243:
+ MapGridSetMetatileIdAt(x, y, 0xe41);
+ break;
+ case 0x251:
+ MapGridSetMetatileIdAt(x, y, 0xe50);
+ break;
+ case 0x250:
+ MapGridSetMetatileIdAt(x, y, 0x251);
+ break;
+ }
+ }
+ }
+}
+
+void MauvilleGymSpecial3(void)
+{
+ int i, x, y;
+ const struct Coords8 *switchCoords = gUnknown_083F8364;
+ for (i=ARRAY_COUNT(gUnknown_083F8364)-1; i>=0; i--)
+ {
+ MapGridSetMetatileIdAt(switchCoords->x, switchCoords->y, 0x206);
+ switchCoords++;
+ }
+ for (y=12; y<24; y++)
+ {
+ for (x=7; x<16; x++)
+ {
+ switch (MapGridGetMetatileIdAt(x, y))
+ {
+ case 0x220:
+ MapGridSetMetatileIdAt(x, y, 0x230);
+ break;
+ case 0x221:
+ MapGridSetMetatileIdAt(x, y, 0x231);
+ break;
+ case 0x228:
+ MapGridSetMetatileIdAt(x, y, 0x238);
+ break;
+ case 0x229:
+ MapGridSetMetatileIdAt(x, y, 0x239);
+ break;
+ case 0x222:
+ MapGridSetMetatileIdAt(x, y, 0x232);
+ break;
+ case 0x223:
+ MapGridSetMetatileIdAt(x, y, 0x233);
+ break;
+ case 0x22a:
+ MapGridSetMetatileIdAt(x, y, 0x23a);
+ break;
+ case 0x22b:
+ MapGridSetMetatileIdAt(x, y, 0x23b);
+ break;
+ case 0x240:
+ MapGridSetMetatileIdAt(x, y, 0xe42);
+ break;
+ case 0x241:
+ MapGridSetMetatileIdAt(x, y, 0xe43);
+ break;
+ case 0x248:
+ case 0x249:
+ MapGridSetMetatileIdAt(x, y, 0x21a);
+ break;
+ case 0x250:
+ MapGridSetMetatileIdAt(x, y, 0x251);
+ break;
+ }
+ }
+ }
+}
+
+static void Task_PetalburgGym(u8);
+static void PetalburgGymFunc(u8, u16);
+const u8 gUnknown_083F8370[] = {0, 1, 1, 1, 1};
+const u16 gUnknown_083F8376[] = {0x218, 0x219, 0x21a, 0x21b, 0x21c};
+
+void PetalburgGymSpecial1(void)
+{
+ gUnknown_02039258 = 0;
+ gUnknown_02039259 = 0;
+ PlaySE(SE_KI_GASYAN);
+ CreateTask(Task_PetalburgGym, 8);
+}
+
+static void Task_PetalburgGym(u8 taskId)
+{
+ if (gUnknown_083F8370[gUnknown_02039259] == gUnknown_02039258)
+ {
+ PetalburgGymFunc(gSpecialVar_0x8004, gUnknown_083F8376[gUnknown_02039259]);
+ gUnknown_02039258 = 0;
+ if ((++gUnknown_02039259) == 5)
+ {
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+ }
+ }
+ else
+ {
+ gUnknown_02039258++;
+ }
+}
+
+static void PetalburgGymFunc(u8 a0, u16 a1)
+{
+ u16 x[4];
+ u16 y[4];
+ u8 i;
+ u8 nDoors = 0;
+ switch (a0)
+ {
+ case 1:
+ nDoors = 2;
+ x[0] = 1;
+ x[1] = 7;
+ y[0] = 0x68;
+ y[1] = 0x68;
+ break;
+ case 2:
+ nDoors = 2;
+ x[0] = 1;
+ x[1] = 7;
+ y[0] = 0x4e;
+ y[1] = 0x4e;
+ break;
+ case 3:
+ nDoors = 2;
+ x[0] = 1;
+ x[1] = 7;
+ y[0] = 0x5b;
+ y[1] = 0x5b;
+ break;
+ case 4:
+ nDoors = 1;
+ x[0] = 7;
+ y[0] = 0x27;
+ break;
+ case 5:
+ nDoors = 2;
+ x[0] = 1;
+ x[1] = 7;
+ y[0] = 0x34;
+ y[1] = 0x34;
+ break;
+ case 6:
+ nDoors = 1;
+ x[0] = 1;
+ y[0] = 0x41;
+ break;
+ case 7:
+ nDoors = 1;
+ x[0] = 7;
+ y[0] = 0xd;
+ break;
+ case 8:
+ nDoors = 1;
+ x[0] = 1;
+ y[0] = 0x1a;
+ break;
+ }
+ for (i=0; i<nDoors; i++)
+ {
+ MapGridSetMetatileIdAt(x[i] + 7, y[i] + 7, a1 | 0xc00);
+ MapGridSetMetatileIdAt(x[i] + 7, y[i] + 8, (a1 + 8) | 0xc00);
+ }
+ DrawWholeMapView();
+}
+
+void PetalburgGymSpecial2(void)
+{
+ PetalburgGymFunc(gSpecialVar_0x8004, gUnknown_083F8376[4]);
+}
+
+void ShowFieldMessageStringVar4(void)
+{
+ ShowFieldMessage(gStringVar4);
+}
+
+void StorePlayerCoordsInVars(void)
+{
+ gSpecialVar_0x8004 = gSaveBlock1.pos.x;
+ gSpecialVar_0x8005 = gSaveBlock1.pos.y;
+}
+
+u8 GetPlayerTrainerIdOnesDigit(void)
+{
+ return (u16)((gSaveBlock2.playerTrainerId[1] << 8) | gSaveBlock2.playerTrainerId[0]) % 10;
+}
+
+void GetPlayerBigGuyGirlString(void)
+{
+ if (gSaveBlock2.playerGender == MALE)
+ {
+ StringCopy(gStringVar1, gOtherText_BigGuy);
+ }
+ else
+ {
+ StringCopy(gStringVar1, gOtherText_BigGirl);
+ }
+}
+
+void GetRivalSonDaughterString(void)
+{
+ if (gSaveBlock2.playerGender == MALE)
+ {
+ StringCopy(gStringVar1, gOtherText_Daughter);
+ }
+ else
+ {
+ StringCopy(gStringVar1, gOtherText_Son);
+ }
+}
+
+u8 sub_810E300(void)
+{
+ return gBattleOutcome;
+}
+
+void CableCarWarp(void)
+{
+ if (gSpecialVar_0x8004 != 0)
+ {
+ Overworld_SetWarpDestination(MAP_GROUP_ROUTE112_CABLE_CAR_STATION, MAP_ID_ROUTE112_CABLE_CAR_STATION, -1, 6, 4);
+ }
+ else
+ {
+ Overworld_SetWarpDestination(MAP_GROUP_MT_CHIMNEY_CABLE_CAR_STATION, MAP_ID_MT_CHIMNEY_CABLE_CAR_STATION, -1, 6, 4);
+ }
+}
+
+void SetFlagInVar(void)
+{
+ FlagSet(gSpecialVar_0x8004);
+}
+
+u16 GetWeekCount(void)
+{
+ u16 weekCount = gLocalTime.days / 7;
+ if (weekCount > 9999)
+ {
+ weekCount = 9999;
+ }
+ return weekCount;
+}
+
+u8 GetLeadMonFriendshipScore(void)
+{
+ struct Pokemon *pokemon = &gPlayerParty[GetLeadMonIndex()];
+ if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) == 255)
+ {
+ return 6;
+ }
+ if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) >= 200)
+ {
+ return 5;
+ }
+ if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) >= 150)
+ {
+ return 4;
+ }
+ if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) >= 100)
+ {
+ return 3;
+ }
+ if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) >= 50)
+ {
+ return 2;
+ }
+ if (GetMonData(pokemon, MON_DATA_FRIENDSHIP) >= 1)
+ {
+ return 1;
+ }
+ return 0;
+}
+
+void CB2_FieldShowRegionMap(void)
+{
+ FieldInitRegionMap(c2_exit_to_overworld_1_continue_scripts_restart_music);
+}
+
+void FieldShowRegionMap(void)
+{
+ SetMainCallback2(CB2_FieldShowRegionMap);
+}
+
+static void Task_PCTurnOnEffect(u8);
+static void PCTurnOffEffect_0(struct Task *);
+static void PCTurnOffEffect_1(s16, s8, s8);
+static void PCTurnOffEffect(void);
+
+void DoPCTurnOnEffect(void)
+{
+ if (FuncIsActiveTask(Task_PCTurnOnEffect) != TRUE)
+ {
+ u8 taskId = CreateTask(Task_PCTurnOnEffect, 8);
+ gTasks[taskId].data[0] = 0;
+ gTasks[taskId].data[1] = taskId;
+ gTasks[taskId].data[2] = 0;
+ gTasks[taskId].data[3] = 0;
+ gTasks[taskId].data[4] = 0;
+ }
+}
+
+static void Task_PCTurnOnEffect(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ if (task->data[0] == 0)
+ {
+ PCTurnOffEffect_0(task);
+ }
+}
+
+static void PCTurnOffEffect_0(struct Task *task)
+{
+ u8 playerDirectionLowerNybble;
+ s8 dx = 0;
+ s8 dy = 0;
+ if (task->data[3] == 6)
+ {
+ task->data[3] = 0;
+ playerDirectionLowerNybble = player_get_direction_lower_nybble();
+ switch (playerDirectionLowerNybble)
+ {
+ case DIR_NORTH:
+ dx = 0;
+ dy = -1;
+ break;
+ case DIR_WEST:
+ dx = -1;
+ dy = -1;
+ break;
+ case DIR_EAST:
+ dx = 1;
+ dy = -1;
+ break;
+ }
+ PCTurnOffEffect_1(task->data[4], dx, dy);
+ DrawWholeMapView();
+ task->data[4] ^= 1;
+ if ((++task->data[2]) == 5)
+ {
+ DestroyTask(task->data[1]);
+ }
+ }
+ task->data[3]++;
+}
+
+static void PCTurnOffEffect_1(s16 flag, s8 dx, s8 dy)
+{
+ u16 tileId = 0;
+ if (flag != 0)
+ {
+ if (gSpecialVar_0x8004 == 0)
+ {
+ tileId = 0x4;
+ }
+ else if (gSpecialVar_0x8004 == 1)
+ {
+ tileId = 0x25a;
+ }
+ else if (gSpecialVar_0x8004 == 2)
+ {
+ tileId = 0x259;
+ }
+ }
+ else
+ {
+ if (gSpecialVar_0x8004 == 0)
+ {
+ tileId = 0x5;
+ }
+ else if (gSpecialVar_0x8004 == 1)
+ {
+ tileId = 0x27f;
+ }
+ else if (gSpecialVar_0x8004 == 2)
+ {
+ tileId = 0x27e;
+ }
+ }
+ MapGridSetMetatileIdAt(gSaveBlock1.pos.x + dx + 7, gSaveBlock1.pos.y + dy + 7, tileId | 0xc00);
+}
+
+void DoPCTurnOffEffect(void)
+{
+ PCTurnOffEffect();
+}
+
+static void PCTurnOffEffect(void)
+{
+ s8 dx = 0;
+ s8 dy = 0;
+ u16 tileId = 0;
+ u8 playerDirectionLowerNybble = player_get_direction_lower_nybble();
+ switch (playerDirectionLowerNybble)
+ {
+ case DIR_NORTH:
+ dx = 0;
+ dy = -1;
+ break;
+ case DIR_WEST:
+ dx = -1;
+ dy = -1;
+ break;
+ case DIR_EAST:
+ dx = 1;
+ dy = -1;
+ break;
+ }
+ if (gSpecialVar_0x8004 == 0)
+ {
+ tileId = 0x4;
+ }
+ else if (gSpecialVar_0x8004 == 1)
+ {
+ tileId = 0x25a;
+ }
+ else if (gSpecialVar_0x8004 == 2)
+ {
+ tileId = 0x259;
+ }
+ MapGridSetMetatileIdAt(gSaveBlock1.pos.x + dx + 7, gSaveBlock1.pos.y + dy + 7, tileId | 0xc00);
+ DrawWholeMapView();
+}
+
+static void Task_LotteryCornerComputerEffect(u8);
+static void LotteryCornerComputerEffect(struct Task *);
+
+void DoLotteryCornerComputerEffect(void)
+{
+ if (FuncIsActiveTask(Task_LotteryCornerComputerEffect) != TRUE)
+ {
+ u8 taskId = CreateTask(Task_LotteryCornerComputerEffect, 8);
+ gTasks[taskId].data[0] = 0;
+ gTasks[taskId].data[1] = taskId;
+ gTasks[taskId].data[2] = 0;
+ gTasks[taskId].data[3] = 0;
+ gTasks[taskId].data[4] = 0;
+ }
+}
+
+static void Task_LotteryCornerComputerEffect(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ if (task->data[0] == 0)
+ {
+ LotteryCornerComputerEffect(task);
+ }
+}
+
+static void LotteryCornerComputerEffect(struct Task *task)
+{
+ if (task->data[3] == 6)
+ {
+ task->data[3] = 0;
+ if (task->data[4] != 0)
+ {
+ MapGridSetMetatileIdAt(18, 8, 0xe9d);
+ MapGridSetMetatileIdAt(18, 9, 0xea5);
+ }
+ else
+ {
+ MapGridSetMetatileIdAt(18, 8, 0xe58);
+ MapGridSetMetatileIdAt(18, 9, 0xe60);
+ }
+ DrawWholeMapView();
+ task->data[4] ^= 1;
+ if ((++task->data[2]) == 5)
+ {
+ DestroyTask(task->data[1]);
+ }
+ }
+ task->data[3]++;
+}
+
+void EndLotteryCornerComputerEffect(void)
+{
+ MapGridSetMetatileIdAt(18, 8, 0xe9d);
+ MapGridSetMetatileIdAt(18, 9, 0xea5);
+ DrawWholeMapView();
+}
+
+static void sub_810E874(void);
+void sub_810E944(void);
+void sub_810E984(u8);
+bool8 sub_810EAC8(u8, u8);
+void sub_810EB90(u8, u8);
+void sub_810EBEC(void);
+void sub_810EC34(u8);
+void sub_810EC9C(u8);
+void sub_810ECB0(void);
+void sub_810ECD4(void);
+void sub_810ECFC(void);
+void sub_810ED40(u8);
+void sub_810ED60(struct Task *);
+void sub_810EEDC(void);
+
+const u8 *const gUnknown_083F8380[] = {
+ OtherText_1F,
+ OtherText_2F,
+ OtherText_3F,
+ OtherText_4F,
+ OtherText_5F,
+ OtherText_6F,
+ OtherText_7F,
+ OtherText_8F,
+ OtherText_9F,
+ OtherText_10F,
+ OtherText_11F,
+ OtherText_B1F,
+ OtherText_B2F,
+ OtherText_B3F,
+ OtherText_B4F,
+ OtherText_Rooftop
+};
+
+void SetDepartmentStoreFloorVar(void)
+{
+ u8 deptStoreFloor;
+ switch (gSaveBlock1.warp2.mapNum)
+ {
+ case MAP_ID_LILYCOVE_CITY_DEPARTMENT_STORE_1F:
+ deptStoreFloor = 0;
+ break;
+ case MAP_ID_LILYCOVE_CITY_DEPARTMENT_STORE_2F:
+ deptStoreFloor = 1;
+ break;
+ case MAP_ID_LILYCOVE_CITY_DEPARTMENT_STORE_3F:
+ deptStoreFloor = 2;
+ break;
+ case MAP_ID_LILYCOVE_CITY_DEPARTMENT_STORE_4F:
+ deptStoreFloor = 3;
+ break;
+ case MAP_ID_LILYCOVE_CITY_DEPARTMENT_STORE_5F:
+ deptStoreFloor = 4;
+ break;
+ case MAP_ID_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP:
+ deptStoreFloor = 15;
+ break;
+ default:
+ deptStoreFloor = 0;
+ break;
+ }
+ VarSet(VAR_DEPT_STORE_FLOOR, deptStoreFloor);
+}
+
+void ScriptAddElevatorMenuItem(u8 a0, u8 a1, u8 a2, u8 a3)
+{
+ u8 i;
+ if (gSpecialVar_0x8004 == 0)
+ {
+ for (i=0; i<20; i++)
+ {
+ gUnknown_03000760[i].var0 = 16;
+ }
+ }
+ gUnknown_03000760[gSpecialVar_0x8004].var0 = a0;
+ gUnknown_03000760[gSpecialVar_0x8004].var1 = a1;
+ gUnknown_03000760[gSpecialVar_0x8004].var2 = a2;
+ gUnknown_03000760[gSpecialVar_0x8004].var3 = a3;
+ gSpecialVar_0x8004++;
+}
+
+void ScriptShowElevatorMenu(void)
+{
+ u8 i = 0;
+ gUnknown_0203925A = 0;
+ gUnknown_0203925B = 0;
+ ScriptAddElevatorMenuItem(16, 0, 0, 0);
+ while (gUnknown_03000760[i].var0 != 16)
+ {
+ gUnknown_0203925A++;
+ i++;
+ }
+ sub_810E874();
+}
+
+static void sub_810E874(void)
+{
+ u8 i;
+ ScriptContext2_Enable();
+ if (gUnknown_0203925A > 5)
+ {
+ MenuDrawTextWindow(0, 0, 8, 11);
+ InitMenu(0, 1, 1, 5, 0, 7);
+ gUnknown_0203925C = 0;
+ sub_80F944C();
+ LoadScrollIndicatorPalette();
+ sub_810ECD4();
+ }
+ else
+ {
+ MenuDrawTextWindow(0, 0, 8, 2 * gUnknown_0203925A + 1);
+ InitMenu(0, 1, 1, gUnknown_0203925A, 0, 7);
+ }
+ for (i = 0; i < 5 && gUnknown_03000760[i].var0 != 16; i ++)
+ {
+ MenuPrint(gUnknown_083F8380[gUnknown_03000760[i].var0], 1, 2 * i + 1);
+ }
+ sub_810E944();
+ CreateTask(sub_810E984, 8);
+}
+
+void sub_810E944(void)
+{
+ MenuDrawTextWindow(20, 0, 29, 5);
+ sub_8072BD8(gOtherText_NowOn, 21, 1, 64);
+ sub_8072BD8(gUnknown_083F8380[gSpecialVar_0x8005], 21, 3, 64);
+}
+
+void sub_810E984(u8 taskId)
+{
+ u8 curMenuPos;
+ if (gMain.newKeys == DPAD_UP && gUnknown_0203925B != 0)
+ {
+ gUnknown_0203925B--;
+ curMenuPos = GetMenuCursorPos();
+ MoveMenuCursorNoWrap(-1);
+ sub_810EAC8(curMenuPos, DPAD_UP);
+ }
+ if (gMain.newKeys == DPAD_DOWN && gUnknown_0203925B != gUnknown_0203925A - 1)
+ {
+ gUnknown_0203925B++;
+ curMenuPos = GetMenuCursorPos();
+ MoveMenuCursorNoWrap(+1);
+ sub_810EAC8(curMenuPos, DPAD_DOWN);
+ }
+ if (gMain.newKeys & A_BUTTON)
+ {
+ saved_warp2_set_2(0, gUnknown_03000760[gUnknown_0203925B].var1, gUnknown_03000760[gUnknown_0203925B].var2, -1, 2, 1);
+ if (gSpecialVar_0x8005 == gUnknown_0203925B)
+ {
+ gScriptResult = 0;
+ PlaySE(SE_SELECT);
+ MenuZeroFillWindowRect(0, 0, 29, 12);
+ sub_810EC9C(taskId);
+ }
+ else
+ {
+ gScriptResult = 1;
+ gSpecialVar_0x8005 = gUnknown_0203925B;
+ sub_810EBEC();
+ FieldObjectTurnByLocalIdAndMap(gScriptLastTalked, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup, DIR_SOUTH);
+ sub_810EEDC();
+ MenuZeroFillScreen();
+ DestroyTask(taskId);
+ }
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ gScriptResult = 0;
+ PlaySE(SE_SELECT);
+ sub_810EEDC();
+ MenuZeroFillWindowRect(0, 0, 29, 12);
+ sub_810EC9C(taskId);
+ }
+}
+
+// This function, as written, swaps the roles of r4 and r5 throughout.
+#ifdef NONMATCHING
+bool8 sub_810EAC8(u8 prevMenuPos, u8 dpadInput)
+{
+ u8 i;
+ bool8 flag = 0;
+ u8 newPos = 0;
+ if (gUnknown_0203925A < 5)
+ {
+ return FALSE;
+ }
+ if (dpadInput == DPAD_UP)
+ {
+ if (prevMenuPos == 0)
+ {
+ newPos = gUnknown_0203925B;
+ flag = 1;
+ }
+ }
+ else if (dpadInput == DPAD_DOWN)
+ {
+ if (prevMenuPos == 4)
+ {
+ newPos = gUnknown_0203925B - 4;
+ flag = 1;
+ }
+ }
+ if (flag)
+ {
+ sub_810EB90(newPos, 5);
+ MenuFillWindowRectWithBlankTile(2, 1, 7, 10);
+ for (i=0; i<5 && gUnknown_03000760[newPos].var0 != 16; newPos++, i++)
+ {
+ MenuPrint(gUnknown_083F8380[gUnknown_03000760[newPos].var0], 1, i * 2 + 1);
+ }
+ }
+ return flag;
+}
+#else
+__attribute__((naked))
+bool8 sub_810EAC8(u8 prevMenuPos, u8 dpadInput)
+{
+ asm_unified("\tpush {r4-r7,lr}\n"
+ "\tmov r7, r8\n"
+ "\tpush {r7}\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r2, r0, 24\n"
+ "\tadds r5, r2, 0\n"
+ "\tlsls r1, 24\n"
+ "\tlsrs r1, 24\n"
+ "\tadds r3, r1, 0\n"
+ "\tmovs r7, 0\n"
+ "\tmovs r4, 0\n"
+ "\tldr r0, _0810EAEC @ =gUnknown_0203925A\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r0, 0x4\n"
+ "\tbhi _0810EAF0\n"
+ "\tmovs r0, 0\n"
+ "\tb _0810EB78\n"
+ "\t.align 2, 0\n"
+ "_0810EAEC: .4byte gUnknown_0203925A\n"
+ "_0810EAF0:\n"
+ "\tcmp r1, 0x40\n"
+ "\tbne _0810EB04\n"
+ "\tcmp r2, 0\n"
+ "\tbne _0810EB18\n"
+ "\tldr r0, _0810EB00 @ =gUnknown_0203925B\n"
+ "\tldrb r4, [r0]\n"
+ "\tmovs r7, 0x1\n"
+ "\tb _0810EB1C\n"
+ "\t.align 2, 0\n"
+ "_0810EB00: .4byte gUnknown_0203925B\n"
+ "_0810EB04:\n"
+ "\tcmp r3, 0x80\n"
+ "\tbne _0810EB18\n"
+ "\tcmp r5, 0x4\n"
+ "\tbne _0810EB18\n"
+ "\tldr r0, _0810EB84 @ =gUnknown_0203925B\n"
+ "\tldrb r0, [r0]\n"
+ "\tsubs r0, 0x4\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r4, r0, 24\n"
+ "\tmovs r7, 0x1\n"
+ "_0810EB18:\n"
+ "\tcmp r7, 0\n"
+ "\tbeq _0810EB76\n"
+ "_0810EB1C:\n"
+ "\tadds r0, r4, 0\n"
+ "\tmovs r1, 0x5\n"
+ "\tbl sub_810EB90\n"
+ "\tmovs r0, 0x2\n"
+ "\tmovs r1, 0x1\n"
+ "\tmovs r2, 0x7\n"
+ "\tmovs r3, 0xA\n"
+ "\tbl MenuFillWindowRectWithBlankTile\n"
+ "\tmovs r5, 0\n"
+ "\tldr r2, _0810EB88 @ =gUnknown_03000760\n"
+ "\tlsls r1, r4, 2\n"
+ "\tadds r0, r1, r2\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r0, 0x10\n"
+ "\tbeq _0810EB76\n"
+ "\tldr r0, _0810EB8C @ =gUnknown_083F8380\n"
+ "\tmov r8, r0\n"
+ "\tadds r6, r2, 0\n"
+ "_0810EB44:\n"
+ "\tadds r0, r1, r6\n"
+ "\tldrb r0, [r0]\n"
+ "\tlsls r0, 2\n"
+ "\tadd r0, r8\n"
+ "\tldr r0, [r0]\n"
+ "\tlsls r2, r5, 1\n"
+ "\tadds r2, 0x1\n"
+ "\tlsls r2, 24\n"
+ "\tlsrs r2, 24\n"
+ "\tmovs r1, 0x1\n"
+ "\tbl MenuPrint\n"
+ "\tadds r0, r4, 0x1\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r4, r0, 24\n"
+ "\tadds r0, r5, 0x1\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r5, r0, 24\n"
+ "\tcmp r5, 0x4\n"
+ "\tbhi _0810EB76\n"
+ "\tlsls r1, r4, 2\n"
+ "\tadds r0, r1, r6\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r0, 0x10\n"
+ "\tbne _0810EB44\n"
+ "_0810EB76:\n"
+ "\tadds r0, r7, 0\n"
+ "_0810EB78:\n"
+ "\tpop {r3}\n"
+ "\tmov r8, r3\n"
+ "\tpop {r4-r7}\n"
+ "\tpop {r1}\n"
+ "\tbx r1\n"
+ "\t.align 2, 0\n"
+ "_0810EB84: .4byte gUnknown_0203925B\n"
+ "_0810EB88: .4byte gUnknown_03000760\n"
+ "_0810EB8C: .4byte gUnknown_083F8380");
+}
+#endif
+
+void sub_810EB90(u8 newPos, u8 maxItems)
+{
+ if (newPos == 0)
+ {
+ gUnknown_0203925C ^= 0x02;
+ DestroyVerticalScrollIndicator(0);
+ }
+ else
+ {
+ sub_810ECB0();
+ }
+ if (newPos + maxItems < gUnknown_0203925A)
+ {
+ sub_810ECD4();
+ }
+ else if (newPos + maxItems == gUnknown_0203925A)
+ {
+ gUnknown_0203925C ^= 0x01;
+ DestroyVerticalScrollIndicator(1);
+ }
+}
+
+void sub_810EBEC(void)
+{
+ u8 taskId = CreateTask(sub_810EC34, 9);
+ gTasks[taskId].data[0] = 1;
+ gTasks[taskId].data[1] = 0;
+ gTasks[taskId].data[2] = 0;
+ gTasks[taskId].data[3] = 0;
+ gTasks[taskId].data[4] = 1;
+ gTasks[taskId].data[5] = 3;
+ SetCameraPanningCallback(NULL);
+ sub_810ECFC();
+ PlaySE(SE_ELEBETA);
+}
+
+void sub_810EC34(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ task->data[1] ++;
+ if (task->data[1] % task->data[5] == 0)
+ {
+ task->data[1] = 0;
+ task->data[2] ++;
+ if (task->data[3] == 0)
+ {
+ task->data[4] = -task->data[4];
+ SetCameraPanning(0, task->data[4]);
+ if (task->data[2] == 23)
+ {
+ PlaySE(SE_PINPON);
+ sub_810EC9C(taskId);
+ InstallCameraPanAheadCallback();
+ }
+ }
+ }
+}
+
+void sub_810EC9C(u8 taskId)
+{
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+}
+
+void sub_810ECB0(void)
+{
+ if (gUnknown_0203925C >> 1 != 1)
+ {
+ gUnknown_0203925C |= 0x2;
+ CreateVerticalScrollIndicators(0, 0x24, 0x08);
+ }
+}
+
+void sub_810ECD4(void)
+{
+ if ((gUnknown_0203925C & 1) == 0)
+ {
+ gUnknown_0203925C |= 0x1;
+ CreateVerticalScrollIndicators(1, 0x24, 0x48);
+ }
+}
+
+void sub_810ECFC(void)
+{
+ if (FuncIsActiveTask(sub_810ED40) != TRUE)
+ {
+ u8 taskId = CreateTask(sub_810ED40, 8);
+ gTasks[taskId].data[0] = 0;
+ gTasks[taskId].data[1] = taskId;
+ gTasks[taskId].data[2] = 0;
+ gTasks[taskId].data[3] = 0;
+ gTasks[taskId].data[4] = 0;
+ }
+}
+
+void sub_810ED40(u8 taskId)
+{
+ sub_810ED60(&gTasks[taskId]);
+}
+
+void sub_810ED60(struct Task *task)
+{
+ if (task->data[3] == 8)
+ {
+ task->data[3] = 0;
+ if (task->data[4] != 0)
+ {
+ MapGridSetMetatileIdAt( 7, 7, 0xe68);
+ MapGridSetMetatileIdAt( 8, 7, 0xe69);
+ MapGridSetMetatileIdAt( 9, 7, 0xe69);
+ MapGridSetMetatileIdAt(10, 7, 0xe6a);
+ MapGridSetMetatileIdAt( 7, 8, 0xe70);
+ MapGridSetMetatileIdAt( 8, 8, 0xe71);
+ MapGridSetMetatileIdAt( 9, 8, 0xe71);
+ MapGridSetMetatileIdAt(10, 8, 0xe72);
+ MapGridSetMetatileIdAt( 7, 9, 0xe78);
+ MapGridSetMetatileIdAt( 8, 9, 0xe79);
+ MapGridSetMetatileIdAt( 9, 9, 0xe79);
+ MapGridSetMetatileIdAt(10, 9, 0xe7a);
+ }
+ else
+ {
+ MapGridSetMetatileIdAt( 7, 7, 0xe6b);
+ MapGridSetMetatileIdAt( 8, 7, 0xe6c);
+ MapGridSetMetatileIdAt( 9, 7, 0xe6c);
+ MapGridSetMetatileIdAt(10, 7, 0xe6d);
+ MapGridSetMetatileIdAt( 7, 8, 0xe73);
+ MapGridSetMetatileIdAt( 8, 8, 0xe74);
+ MapGridSetMetatileIdAt( 9, 8, 0xe74);
+ MapGridSetMetatileIdAt(10, 8, 0xe75);
+ MapGridSetMetatileIdAt( 7, 9, 0xe7b);
+ MapGridSetMetatileIdAt( 8, 9, 0xe7c);
+ MapGridSetMetatileIdAt( 9, 9, 0xe7c);
+ MapGridSetMetatileIdAt(10, 9, 0xe7d);
+ }
+ DrawWholeMapView();
+ task->data[4] ^= 1;
+ task->data[2]++;
+ if (task->data[2] == 8)
+ {
+ DestroyTask(task->data[1]);
+ }
+ }
+ task->data[3]++;
+}
+
+void sub_810EEDC(void)
+{
+ if ((gUnknown_0203925C & 1) != 0)
+ {
+ DestroyVerticalScrollIndicator(1);
+ }
+ if ((gUnknown_0203925C >> 1) == 1)
+ {
+ DestroyVerticalScrollIndicator(0);
+ }
+ BuyMenuFreeMemory();
+}
+
+void SetTrickHouseEndRoomFlag(void)
+{
+ u16 *specVar = &gSpecialVar_0x8004;
+ u16 flag = 0x259;
+ *specVar = flag;
+ FlagSet(flag);
+}
+
+void ResetTrickHouseEndRoomFlag(void)
+{
+ u16 *specVar = &gSpecialVar_0x8004;
+ u16 flag = 0x259;
+ *specVar = flag;
+ FlagClear(flag);
+}
+
+bool8 CheckLeadMonCool(void)
+{
+ if (GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_COOL) < 200)
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool8 CheckLeadMonBeauty(void)
+{
+ if (GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_BEAUTY) < 200)
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool8 CheckLeadMonCute(void)
+{
+ if (GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_CUTE) < 200)
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool8 CheckLeadMonSmart(void)
+{
+ if (GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_SMART) < 200)
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool8 CheckLeadMonTough(void)
+{
+ if (GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_TOUGH) < 200)
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void IsGrassTypeInParty(void)
+{
+ u8 i;
+ u16 species;
+ struct Pokemon *pokemon;
+ for (i=0; i<PARTY_SIZE; i++)
+ {
+ pokemon = &gPlayerParty[i];
+ if (GetMonData(pokemon, MON_DATA_SANITY_BIT2) && !GetMonData(pokemon, MON_DATA_IS_EGG))
+ {
+ species = GetMonData(pokemon, MON_DATA_SPECIES);
+ if (gBaseStats[species].type1 == TYPE_GRASS || gBaseStats[species].type2 == TYPE_GRASS)
+ {
+ gScriptResult = TRUE;
+ return;
+ }
+ }
+ }
+ gScriptResult = FALSE;
+}
+
+const u8 *const gUnknown_083F83C0[] = {
+ OtherText_BlueFlute,
+ OtherText_YellowFlute,
+ OtherText_RedFlute,
+ OtherText_WhiteFlute,
+ OtherText_BlackFlute,
+ OtherText_PrettyChair,
+ OtherText_PrettyDesk,
+ gOtherText_CancelNoTerminator
+};
+
+void sub_810F118(u8);
+bool8 sub_810F1F4(u8, u8);
+void sub_810F2B4(void);
+void GlassWorkshopUpdateScrollIndicators(u8, u8);
+
+void ShowGlassWorkshopMenu(void)
+{
+ u8 i;
+ ScriptContext2_Enable();
+ MenuDrawTextWindow(0, 0, 10, 11);
+ InitMenu(0, 1, 1, 5, 0, 9);
+ gUnknown_0203925C = 0;
+ sub_80F944C();
+ LoadScrollIndicatorPalette();
+ sub_810F2B4();
+ for (i=0; i<5; i++)
+ {
+ MenuPrint(gUnknown_083F83C0[i], 1, 2 * i + 1);
+ }
+ gUnknown_0203925B = 0;
+ gUnknown_0203925A = ARRAY_COUNT(gUnknown_083F83C0);
+ CreateTask(sub_810F118, 8);
+}
+
+void sub_810F118(u8 taskId)
+{
+ u8 prevCursorPos;
+ if (gMain.newKeys == DPAD_UP && gUnknown_0203925B != 0)
+ {
+ gUnknown_0203925B--;
+ prevCursorPos = GetMenuCursorPos();
+ MoveMenuCursorNoWrap(-1);
+ sub_810F1F4(prevCursorPos, DPAD_UP);
+ }
+ if (gMain.newKeys == DPAD_DOWN && gUnknown_0203925B != gUnknown_0203925A - 1)
+ {
+ gUnknown_0203925B++;
+ prevCursorPos = GetMenuCursorPos();
+ MoveMenuCursorNoWrap(1);
+ sub_810F1F4(prevCursorPos, DPAD_DOWN);
+ }
+ if (gMain.newKeys & A_BUTTON)
+ {
+ HandleDestroyMenuCursors();
+ gScriptResult = gUnknown_0203925B;
+ PlaySE(SE_SELECT);
+ sub_810EEDC();
+ MenuZeroFillWindowRect(0, 0, 29, 12);
+ sub_810EC9C(taskId);
+ }
+ if (gMain.newKeys & B_BUTTON)
+ {
+ HandleDestroyMenuCursors();
+ gScriptResult = 0x7f;
+ PlaySE(SE_SELECT);
+ sub_810EEDC();
+ MenuZeroFillWindowRect(0, 0, 29, 12);
+ sub_810EC9C(taskId);
+ }
+}
+
+// Second verse, same as the first
+#ifdef NONMATCHING
+bool8 sub_810F1F4(u8 prevCursorPos, u8 dpadInput)
+{
+ u8 i;
+ u8 flag = 0;
+ u8 newPos = 0;
+ if (gUnknown_0203925A < 5)
+ {
+ return FALSE;
+ }
+ if (dpadInput == DPAD_UP)
+ {
+ if (prevCursorPos == 0)
+ {
+ newPos = gUnknown_0203925B;
+ flag = TRUE;
+ }
+ }
+ else if (dpadInput == DPAD_DOWN)
+ {
+ if (prevCursorPos == 4)
+ {
+ newPos = gUnknown_0203925B - 4;
+ flag = TRUE;
+ }
+ }
+ if (flag)
+ {
+ GlassWorkshopUpdateScrollIndicators(newPos, 5);
+ MenuFillWindowRectWithBlankTile(2, 1, 9, 10);
+ for (i=0; i<5; newPos++, i++)
+ {
+ MenuPrint(gUnknown_083F83C0[newPos], 1, 2 * i + 1);
+ }
+ }
+ return flag;
+}
+#else
+__attribute__((naked))
+bool8 sub_810F1F4(u8 prevCursorPos, u8 dpadInput)
+{
+ asm_unified("\tpush {r4-r7,lr}\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r2, r0, 24\n"
+ "\tadds r5, r2, 0\n"
+ "\tlsls r1, 24\n"
+ "\tlsrs r1, 24\n"
+ "\tadds r3, r1, 0\n"
+ "\tmovs r6, 0\n"
+ "\tmovs r4, 0\n"
+ "\tldr r0, _0810F214 @ =gUnknown_0203925A\n"
+ "\tldrb r0, [r0]\n"
+ "\tcmp r0, 0x4\n"
+ "\tbhi _0810F218\n"
+ "\tmovs r0, 0\n"
+ "\tb _0810F282\n"
+ "\t.align 2, 0\n"
+ "_0810F214: .4byte gUnknown_0203925A\n"
+ "_0810F218:\n"
+ "\tcmp r1, 0x40\n"
+ "\tbne _0810F22C\n"
+ "\tcmp r2, 0\n"
+ "\tbne _0810F240\n"
+ "\tldr r0, _0810F228 @ =gUnknown_0203925B\n"
+ "\tldrb r4, [r0]\n"
+ "\tmovs r6, 0x1\n"
+ "\tb _0810F244\n"
+ "\t.align 2, 0\n"
+ "_0810F228: .4byte gUnknown_0203925B\n"
+ "_0810F22C:\n"
+ "\tcmp r3, 0x80\n"
+ "\tbne _0810F240\n"
+ "\tcmp r5, 0x4\n"
+ "\tbne _0810F240\n"
+ "\tldr r0, _0810F288 @ =gUnknown_0203925B\n"
+ "\tldrb r0, [r0]\n"
+ "\tsubs r0, 0x4\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r4, r0, 24\n"
+ "\tmovs r6, 0x1\n"
+ "_0810F240:\n"
+ "\tcmp r6, 0\n"
+ "\tbeq _0810F280\n"
+ "_0810F244:\n"
+ "\tadds r0, r4, 0\n"
+ "\tmovs r1, 0x5\n"
+ "\tbl GlassWorkshopUpdateScrollIndicators\n"
+ "\tmovs r0, 0x2\n"
+ "\tmovs r1, 0x1\n"
+ "\tmovs r2, 0x9\n"
+ "\tmovs r3, 0xA\n"
+ "\tbl MenuFillWindowRectWithBlankTile\n"
+ "\tmovs r5, 0\n"
+ "\tldr r7, _0810F28C @ =gUnknown_083F83C0\n"
+ "_0810F25C:\n"
+ "\tlsls r0, r4, 2\n"
+ "\tadds r0, r7\n"
+ "\tldr r0, [r0]\n"
+ "\tlsls r2, r5, 1\n"
+ "\tadds r2, 0x1\n"
+ "\tlsls r2, 24\n"
+ "\tlsrs r2, 24\n"
+ "\tmovs r1, 0x1\n"
+ "\tbl MenuPrint\n"
+ "\tadds r0, r4, 0x1\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r4, r0, 24\n"
+ "\tadds r0, r5, 0x1\n"
+ "\tlsls r0, 24\n"
+ "\tlsrs r5, r0, 24\n"
+ "\tcmp r5, 0x4\n"
+ "\tbls _0810F25C\n"
+ "_0810F280:\n"
+ "\tadds r0, r6, 0\n"
+ "_0810F282:\n"
+ "\tpop {r4-r7}\n"
+ "\tpop {r1}\n"
+ "\tbx r1\n"
+ "\t.align 2, 0\n"
+ "_0810F288: .4byte gUnknown_0203925B\n"
+ "_0810F28C: .4byte gUnknown_083F83C0");
+}
+#endif
+
+void sub_810F290(void)
+{
+ if (gUnknown_0203925C >> 1 != 1)
+ {
+ gUnknown_0203925C |= 0x02;
+ CreateVerticalScrollIndicators(0, 0x2c, 0x08);
+ }
+}
+
+void sub_810F2B4(void)
+{
+ if (!(gUnknown_0203925C & 0x01))
+ {
+ gUnknown_0203925C |= 0x01;
+ CreateVerticalScrollIndicators(1, 0x2c, 0x58);
+ }
+}
+
+void GlassWorkshopUpdateScrollIndicators(u8 newPos, u8 maxItems)
+{
+ if (newPos == 0)
+ {
+ gUnknown_0203925C ^= 0x02;
+ DestroyVerticalScrollIndicator(0);
+ }
+ else
+ {
+ sub_810F290();
+ }
+ if (newPos + maxItems < gUnknown_0203925A)
+ {
+ sub_810F2B4();
+ }
+ else if (newPos + maxItems == gUnknown_0203925A)
+ {
+ gUnknown_0203925C ^= 0x01;
+ DestroyVerticalScrollIndicator(1);
+ }
+}
+
+void SpawnCameraDummy(void)
+{
+ u8 mapObjectId = SpawnSpecialFieldObjectParametrized(7, 8, 0x7f, gSaveBlock1.pos.x + 7, gSaveBlock1.pos.y + 7, 3);
+ gMapObjects[mapObjectId].mapobj_bit_13 = 1;
+ CameraObjectSetFollowedObjectId(gMapObjects[mapObjectId].spriteId);
+}
+
+void RemoveCameraDummy(void)
+{
+ CameraObjectSetFollowedObjectId(GetPlayerAvatarObjectId());
+ RemoveFieldObjectByLocalIdAndMap(0x7f, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup);
+}
+
+u8 GetPokeblockNameByMonNature(void)
+{
+ return sub_810CB68(GetNature(&gPlayerParty[GetLeadMonIndex()]), gStringVar1);
+}
+
+void GetSecretBaseNearbyMapName(void)
+{
+ GetMapSectionName(gStringVar1, VarGet(VAR_SECRET_BASE_MAP), 0);
+}
+
+u16 sub_810F404(void)
+{
+ return GetGameStat(GAME_STAT_BATTLE_TOWER_BEST_STREAK);
+}
+
+void sub_810F414(void)
+{
+ sub_8135FF4(gStringVar1);
+}
+
+const u8 gUnknown_083F83E0[] = {12, 2, 4, 5, 1, 8, 7, 11, 3, 10, 9, 6};
+const u8 gUnknown_083F83EC[] = {0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5};
+const u8 gUnknown_083F83F8[] = {3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5};
+
+u8 sub_810F424(void)
+{
+ u32 v0 = gSaveBlock1.easyChatPairs[0].unk0_0 + gSaveBlock1.easyChatPairs[0].unk2 + gUnknown_083F83E0[gSpecialVar_0x8004];
+ if (GetPriceReduction(2))
+ {
+ return gUnknown_083F83F8[v0 % 12];
+ }
+ return gUnknown_083F83EC[v0 % 12];
+}
+
+bool8 sub_810F488(void)
+{
+ u16 *specVar = &gSpecialVar_0x8004;
+ u16 flag = 0x277;
+ *specVar = flag;
+ if (!FlagGet(flag))
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool8 sub_810F4B0(void)
+{
+ u16 *specVar = &gSpecialVar_0x8004;
+ u16 flag = 0x278;
+ *specVar = flag;
+ if (!FlagGet(flag))
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool8 sub_810F4D4(void)
+{
+ u16 *specVar = &gSpecialVar_0x8004;
+ u16 flag = 0x279;
+ *specVar = flag;
+ if (!FlagGet(flag))
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool8 sub_810F4FC(void)
+{
+ u16 *specVar = &gSpecialVar_0x8004;
+ u16 flag = 0x27a;
+ *specVar = flag;
+ if (!FlagGet(flag))
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool8 LeadMonHasEffortRibbon(void)
+{
+ return GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_EFFORT_RIBBON, NULL);
+}
+
+void GivLeadMonEffortRibbon(void)
+{
+ bool8 ribbonSet;
+ IncrementGameStat(GAME_STAT_RECEIVED_RIBBONS);
+ FlagSet(SYS_RIBBON_GET);
+ ribbonSet = TRUE;
+ SetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_EFFORT_RIBBON, &ribbonSet);
+}
+
+bool8 ScrSpecial_AreLeadMonEVsMaxedOut(void)
+{
+ if (GetMonEVCount(&gPlayerParty[GetLeadMonIndex()]) >= 510)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+u8 sub_810F5BC(void)
+{
+ if (!FlagGet(0xc7) && gSaveBlock1.location.mapGroup == MAP_GROUP_RUSTURF_TUNNEL && gSaveBlock1.location.mapNum == MAP_ID_RUSTURF_TUNNEL)
+ {
+ if (FlagGet(0x3a3))
+ {
+ VarSet(VAR_0x409a, 4);
+ return TRUE;
+ }
+ else if (FlagGet(0x3a4))
+ {
+ VarSet(VAR_0x409a, 5);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void SetShoalItemFlag(u16 v0)
+{
+ FlagSet(0x85f);
+}
+
+void PutZigzagoonInPlayerParty(void)
+{
+ u16 monData;
+ CreateMon(&gPlayerParty[0], SPECIES_ZIGZAGOON, 7, 0x20, FALSE, 0, FALSE, 0);
+ monData = TRUE;
+ SetMonData(&gPlayerParty[0], MON_DATA_ALT_ABILITY, (u8 *)&monData);
+ monData = MOVE_TACKLE;
+ SetMonData(&gPlayerParty[0], MON_DATA_MOVE1, (u8 *)&monData);
+ monData = MOVE_NONE;
+ SetMonData(&gPlayerParty[0], MON_DATA_MOVE2, (u8 *)&monData);
+ SetMonData(&gPlayerParty[0], MON_DATA_MOVE3, (u8 *)&monData);
+ SetMonData(&gPlayerParty[0], MON_DATA_MOVE4, (u8 *)&monData);
+}
+
+bool8 IsStarterInParty(void)
+{
+ u8 i;
+ u16 starter = GetStarterPokemon(VarGet(VAR_FIRST_POKE));
+ u8 partyCount = CalculatePlayerPartyCount();
+ for (i = 0; i < partyCount; i++)
+ {
+ if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) == starter)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+bool8 CheckFreePokemonStorageSpace(void)
+{
+ u16 i, j;
+ for (i=0; i<14; i++)
+ {
+ for (j=0; j<30; j++)
+ {
+ if (GetBoxMonData(&gPokemonStorage.boxes[i][j], MON_DATA_SPECIES, NULL) == SPECIES_NONE)
+ {
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+bool8 IsPokerusInParty(void)
+{
+ if (!CheckPartyPokerus(gPlayerParty, 0x3f))
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void sub_810F7A8(u8);
+static void sub_810F814(u8);
+
+void sub_810F758(void)
+{
+ u8 taskId = CreateTask(sub_810F7A8, 9);
+ gTasks[taskId].data[0] = gSpecialVar_0x8005;
+ gTasks[taskId].data[1] = 0;
+ gTasks[taskId].data[2] = 0;
+ gTasks[taskId].data[3] = 0;
+ gTasks[taskId].data[4] = gSpecialVar_0x8004;
+ gTasks[taskId].data[5] = 5;
+ SetCameraPanningCallback(NULL);
+ PlaySE(SE_W070);
+}
+
+static void sub_810F7A8(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ task->data[1]++;
+ if ((task->data[1] % task->data[5]) == 0)
+ {
+ task->data[1] = 0;
+ task->data[2]++;
+ if (task->data[3] == 0)
+ {
+ task->data[0] = -task->data[0];
+ task->data[4] = -task->data[4];
+ SetCameraPanning(task->data[0], task->data[4]);
+ if (task->data[2] == 8)
+ {
+ sub_810F814(taskId);
+ InstallCameraPanAheadCallback();
+ }
+ }
+ }
+}
+
+static void sub_810F814(u8 taskId)
+{
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+}
+
+bool8 sub_810F828(void)
+{
+ return FlagGet(0x2b8);
+}
+
+void SetRoute119Weather(void)
+{
+ if (is_map_type_1_2_3_5_or_6(get_map_type_from_warp0()) != TRUE)
+ {
+ SetSav1Weather(0x14);
+ }
+}
+
+void SetRoute123Weather(void)
+{
+ if (is_map_type_1_2_3_5_or_6(get_map_type_from_warp0()) != TRUE)
+ {
+ SetSav1Weather(0x15);
+ }
+}
+
+u8 GetLeadMonIndex(void)
+{
+ u8 i;
+ u8 partyCount = CalculatePlayerPartyCount();
+ for (i=0; i<partyCount; i++)
+ {
+ if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) != SPECIES_EGG && GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) != 0)
+ {
+ return i;
+ }
+ }
+ return 0;
+}
+
+u16 ScriptGetPartyMonSpecies(void)
+{
+ return GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_SPECIES2, NULL);
+}
+
+void sub_810F8FC(void)
+{
+ sub_805ADDC(6);
+}
+
+u16 sub_810F908(void)
+{
+ u16 var40c2 = VarGet(VAR_0x40C2);
+ if (gLocalTime.days - var40c2 >= 7)
+ {
+ return 0;
+ }
+ else if (gLocalTime.days < 0)
+ {
+ return 8;
+ }
+ return 7 - (gLocalTime.days - var40c2);
+}
+
+u16 sub_810F950(void)
+{
+ VarSet(VAR_0x40C2, gLocalTime.days);
+ return gLocalTime.days;
+}
+
+bool8 sub_810F96C(void)
+{
+ GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_OT_NAME, gStringVar1);
+ if (!StringCompareWithoutExtCtrlCodes(gSaveBlock2.playerName, gStringVar1))
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void sub_810F9AC(void)
+{
+ if (gScriptResult >= 10000)
+ {
+ sub_80BF088(0, gScriptResult);
+ }
+ else if (gScriptResult >= 1000)
+ {
+ gStringVar1[0] = CHAR_0;
+ ConvertIntToDecimalStringN(gStringVar1 + 1, gScriptResult, 0, sub_80BF0B8(gScriptResult));
+ }
+ else if (gScriptResult >= 100)
+ {
+ gStringVar1[0] = CHAR_0;
+ gStringVar1[1] = CHAR_0;
+ ConvertIntToDecimalStringN(gStringVar1 + 2, gScriptResult, 0, sub_80BF0B8(gScriptResult));
+ }
+ else if (gScriptResult >= 10)
+ {
+ gStringVar1[0] = CHAR_0;
+ gStringVar1[1] = CHAR_0;
+ gStringVar1[2] = CHAR_0;
+ ConvertIntToDecimalStringN(gStringVar1 + 3, gScriptResult, 0, sub_80BF0B8(gScriptResult));
+ }
+ else
+ {
+ gStringVar1[0] = CHAR_0;
+ gStringVar1[1] = CHAR_0;
+ gStringVar1[2] = CHAR_0;
+ gStringVar1[3] = CHAR_0;
+ ConvertIntToDecimalStringN(gStringVar1 + 4, gScriptResult, 0, sub_80BF0B8(gScriptResult));
+ }
+}
+
+const u8 gUnknown_083F8404[] = {2, 1, 2, 1};
+const u8 gUnknown_083F8408[] = {8, 9, 10, 11, 12, 13, 14, 15};
+const u8 gUnknown_083F8410[] = {8, 13, 14, 11, 10, 12, 15, 9};
+
+bool8 sub_810FF30(void);
+void sub_810FCE8(void);
+void sub_810FF48(void);
+void sub_810FD80(void);
+u16 sub_810FCB0(void);
+int sub_810FB9C(void);
+
+void ResetFanClub(void)
+{
+ gSaveBlock1.vars[0x41] = 0;
+ gSaveBlock1.vars[0x42] = 0;
+}
+
+void sub_810FA74(void)
+{
+ if (sub_810FF30())
+ {
+ sub_810FCE8();
+ gSaveBlock1.vars[0x42] = gSaveBlock2.playTimeHours;
+ }
+}
+
+void sub_810FAA0(void)
+{
+ if (!((gSaveBlock1.vars[0x41] >> 7) & 1))
+ {
+ sub_810FF48();
+ sub_810FD80();
+ gSaveBlock1.vars[0x42] = gSaveBlock2.playTimeHours;
+ FlagClear(0x315);
+ FlagClear(0x316);
+ FlagClear(0x317);
+ FlagClear(0x318);
+ VarSet(VAR_0x4095, 1);
+ }
+}
+
+u8 sub_810FB10(u8 a0)
+{
+ if (VarGet(VAR_0x4095) == 2)
+ {
+ if ((gSaveBlock1.vars[0x41] & 0x7f) + gUnknown_083F8404[a0] >= 20)
+ {
+ if (sub_810FCB0() < 3)
+ {
+ sub_810FB9C();
+ gSaveBlock1.vars[0x41] &= 0xff80;
+ }
+ else
+ {
+ gSaveBlock1.vars[0x41] = (gSaveBlock1.vars[0x41] & 0xff80) | 20;
+ }
+ }
+ else
+ {
+ gSaveBlock1.vars[0x41] += gUnknown_083F8404[a0];
+ }
+ }
+ return gSaveBlock1.vars[0x41] & 0x7f;
+}
+
+int sub_810FB9C(void)
+{
+ u8 i;
+ int retval = 0;
+ for (i=0; i<8; i++)
+ {
+ if (!((gSaveBlock1.vars[0x41] >> gUnknown_083F8408[i]) & 0x01))
+ {
+ retval = i;
+ if (Random() & 1)
+ {
+ gSaveBlock1.vars[0x41] |= (1 << gUnknown_083F8408[i]);
+ return retval;
+ }
+ }
+ }
+ gSaveBlock1.vars[0x41] |= (1 << gUnknown_083F8408[retval]);
+ return retval;
+}
+
+int sub_810FC18(void)
+{
+ u8 i;
+ int retval = 0;
+ if (sub_810FCB0() == TRUE)
+ {
+ return 0;
+ }
+ for (i=0; i<8; i++)
+ {
+ if ((gSaveBlock1.vars[0x41] >> gUnknown_083F8410[i]) & 1)
+ {
+ retval = i;
+ if (Random() & 1)
+ {
+ gSaveBlock1.vars[0x41] ^= (1 << gUnknown_083F8410[i]);
+ return retval;
+ }
+ }
+ }
+ if ((gSaveBlock1.vars[0x41] >> gUnknown_083F8410[retval]) & 1)
+ {
+ gSaveBlock1.vars[0x41] ^= (1 << gUnknown_083F8410[retval]);
+ }
+ return retval;
+}
+
+u16 sub_810FCB0(void)
+{
+ u8 i;
+ u8 retval = 0;
+ for (i=0; i<8; i++)
+ {
+ if ((gSaveBlock1.vars[0x41] >> (i + 8)) & 1)
+ {
+ retval ++;
+ }
+ }
+ return retval;
+}
+
+void sub_810FCE8(void)
+{
+ u8 i = 0;
+ if (gSaveBlock2.playTimeHours < 999)
+ {
+ while (1)
+ {
+ if (sub_810FCB0() < 5)
+ {
+ gSaveBlock1.vars[0x42] = gSaveBlock2.playTimeHours;
+ break;
+ }
+ else if (i == 8)
+ {
+ break;
+ }
+ else if (gSaveBlock2.playTimeHours - gSaveBlock1.vars[0x42] < 12)
+ {
+ return;
+ }
+ sub_810FC18();
+ gSaveBlock1.vars[0x42] += 12;
+ i++;
+ }
+ }
+}
+
+bool8 sub_810FD60(void)
+{
+ return (gSaveBlock1.vars[0x41] >> gSpecialVar_0x8004) & 0x01;
+}
+
+void sub_810FD80(void)
+{
+ gSaveBlock1.vars[0x41] |= 0x2000;
+ gSaveBlock1.vars[0x41] |= 0x100;
+ gSaveBlock1.vars[0x41] |= 0x400;
+}
+
+void sub_810FE1C(void *, u8, u8);
+
+void sub_810FDAC(void)
+{
+ u8 a = 0;
+ u8 b = 0;
+ switch (gSpecialVar_0x8004)
+ {
+ case 8:
+ break;
+ case 9:
+ break;
+ case 10:
+ a = 0;
+ b = 3;
+ break;
+ case 11:
+ a = 0;
+ b = 1;
+ break;
+ case 12:
+ a = 1;
+ b = 0;
+ break;
+ case 13:
+ a = 0;
+ b = 4;
+ break;
+ case 14:
+ a = 1;
+ b = 5;
+ break;
+ case 15:
+ break;
+ }
+ sub_810FE1C(gSaveBlock1.linkBattleRecords, a, b);
+}
+
+void sub_810FE1C(void *linkRecords, u8 a, u8 b)
+{
+ u8 *curRecord = (linkRecords + 16 * a);
+ if (*curRecord == EOS)
+ {
+ switch (b)
+ {
+ case 0:
+ StringCopy(gStringVar1, gOtherText_Wallace);
+ break;
+ case 1:
+ StringCopy(gStringVar1, gOtherText_Steven);
+ break;
+ case 2:
+ StringCopy(gStringVar1, gOtherText_Brawly);
+ break;
+ case 3:
+ StringCopy(gStringVar1, gOtherText_Winona);
+ break;
+ case 4:
+ StringCopy(gStringVar1, gOtherText_Phoebe);
+ break;
+ case 5:
+ StringCopy(gStringVar1, gOtherText_Glacia);
+ break;
+ default:
+ StringCopy(gStringVar1, gOtherText_Wallace);
+ break;
+ }
+ }
+ else
+ {
+ StringCopyN(gStringVar1, curRecord, 7);
+ gStringVar1[7] = EOS;
+ if (gStringVar1[0] == 0xfc && gStringVar1[1] == 0x15)
+ {
+ ConvertInternationalString(gStringVar1, 1);
+ }
+ }
+}
+
+void sub_810FEFC(void)
+{
+ if (VarGet(VAR_0x4095) == 2)
+ {
+ sub_810FA74();
+ if (gBattleOutcome == 1)
+ {
+ sub_810FB9C();
+ }
+ else
+ {
+ sub_810FC18();
+ }
+ }
+}
+
+bool8 sub_810FF30(void)
+{
+ return (gSaveBlock1.vars[0x41] >> 7) & 0x01;
+}
+
+void sub_810FF48(void)
+{
+ gSaveBlock1.vars[0x41] |= 0x80;
+}
+
+u8 sub_810FF60(void)
+{
+ return sub_810FB10(gSpecialVar_0x8004);
+}
diff --git a/src/field/field_tasks.c b/src/field/field_tasks.c
new file mode 100644
index 000000000..da6f162c2
--- /dev/null
+++ b/src/field/field_tasks.c
@@ -0,0 +1,868 @@
+//
+
+//
+
+#include "global.h"
+#include "task.h"
+#include "main.h"
+#include "vars.h"
+#include "bike.h"
+#include "item.h"
+#include "items.h"
+#include "event_data.h"
+#include "overworld.h"
+#include "clock.h"
+#include "script.h"
+#include "field_special_scene.h"
+#include "field_effect_helpers.h"
+#include "secret_base.h"
+#include "metatile_behavior.h"
+#include "fieldmap.h"
+#include "field_player_avatar.h"
+#include "field_camera.h"
+#include "songs.h"
+#include "sound.h"
+#include "field_tasks.h"
+
+void DummyPerStepCallback(u8);
+void PerStepCallback_8069F64(u8);
+void PerStepCallback_8069AA0(u8);
+void PerStepCallback_8069864(u8);
+void PerStepCallback_8069DD4(u8);
+void PerStepCallback_806A07C(u8);
+
+void (*const gUnknown_08376364[])(u8) = {
+ DummyPerStepCallback,
+ PerStepCallback_8069F64,
+ PerStepCallback_8069AA0,
+ PerStepCallback_8069864,
+ PerStepCallback_8069DD4,
+ EndTruckSequence,
+ sub_80BCF1C,
+ PerStepCallback_806A07C
+};
+
+void Task_RunPerStepCallback(u8 taskId)
+{
+ int idx = gTasks[taskId].data[0];
+ gUnknown_08376364[idx](taskId);
+}
+
+#define tState data[0]
+#define tAmbientCryState data[1]
+#define tAmbientCryDelay data[2]
+
+static void RunTimeBasedEvents(s16 *data)
+{
+ switch (tState)
+ {
+ case 0:
+ if (gMain.vblankCounter1 & 0x1000)
+ {
+ DoTimeBasedEvents();
+ tState++;
+ }
+ break;
+ case 1:
+ if (!(gMain.vblankCounter1 & 0x1000))
+ {
+ tState--;
+ }
+ break;
+ }
+}
+
+void Task_RunTimeBasedEvents(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ if (!ScriptContext2_IsEnabled())
+ {
+ RunTimeBasedEvents(data);
+ UpdateAmbientCry(&tAmbientCryState, &tAmbientCryDelay);
+ }
+}
+
+#undef tState
+#undef tAmbientCryState
+#undef tAmbientCryDelay
+
+void Task_MuddySlope(u8);
+
+void SetUpFieldTasks(void)
+{
+ if (!FuncIsActiveTask(Task_RunPerStepCallback))
+ {
+ u8 taskId = CreateTask(Task_RunPerStepCallback, 0x50);
+ gTasks[taskId].data[0] = 0;
+ }
+ if (!FuncIsActiveTask(Task_MuddySlope))
+ {
+ CreateTask(Task_MuddySlope, 0x50);
+ }
+ if (!FuncIsActiveTask(Task_RunTimeBasedEvents))
+ {
+ CreateTask(Task_RunTimeBasedEvents, 0x50);
+ }
+}
+
+void ActivatePerStepCallback(u8 callback)
+{
+ s16 *dataPointer;
+ s16 *dataStart;
+ s16 zero;
+ u8 taskId = FindTaskIdByFunc(Task_RunPerStepCallback);
+ if (taskId != 0xff)
+ {
+ dataStart = gTasks[taskId].data;
+ zero = 0;
+ dataPointer = &dataStart[15];
+ do
+ {
+ *dataPointer-- = zero;
+ } while ((int)dataPointer >= (int)dataStart);
+ if (callback >= ARRAY_COUNT(gUnknown_08376364))
+ {
+ *dataStart = 0;
+ }
+ else
+ {
+ *dataStart = callback;
+ }
+ }
+}
+
+void ResetFieldTasksArgs(void)
+{
+ u8 taskId;
+ s16 *taskData;
+ taskId = FindTaskIdByFunc(Task_RunPerStepCallback);
+ if (taskId != 0xff)
+ {
+ taskData = gTasks[taskId].data;
+ }
+ taskId = FindTaskIdByFunc(Task_RunTimeBasedEvents);
+ if (taskId != 0xff)
+ {
+ taskData = gTasks[taskId].data;
+ taskData[1] = 0;
+ taskData[2] = 0;
+ }
+}
+
+const struct MetatileOffset gUnknown_08376384[][2] = {
+ {{ 0, 0,0x259}, { 0, 1,0x261}},
+ {{ 0, -1,0x259}, { 0, 0,0x261}},
+ {{ 0, 0,0x252}, { 1, 0,0x253}},
+ {{ -1, 0,0x252}, { 0, 0,0x253}}
+};
+
+const struct MetatileOffset gUnknown_083763A4[][2] = {
+ {{ 0, 0,0x25A}, { 0, 1,0x262}},
+ {{ 0, -1,0x25A}, { 0, 0,0x262}},
+ {{ 0, 0,0x254}, { 1, 0,0x255}},
+ {{ -1, 0,0x254}, { 0, 0,0x255}}
+};
+
+const struct MetatileOffset gUnknown_083763C4[][2] = {
+ {{ 0, 0,0x258}, { 0, 1,0x260}},
+ {{ 0, -1,0x258}, { 0, 0,0x260}},
+ {{ 0, 0,0x250}, { 1, 0,0x251}},
+ {{ -1, 0,0x250}, { 0, 0,0x251}}
+};
+
+void DummyPerStepCallback(u8 taskId) {}
+
+const struct MetatileOffset *sub_80695E0(const struct MetatileOffset a0[][2], s8 a1)
+{
+ if (sub_80576A0(a1))
+ {
+ return a0[0];
+ }
+ else if (sub_80576B4(a1))
+ {
+ return a0[1];
+ }
+ else if (sub_80576C8(a1))
+ {
+ return a0[2];
+ }
+ else if (sub_80576DC(a1))
+ {
+ return a0[3];
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+#ifdef NONMATCHING
+void sub_8069638(const struct MetatileOffset offsets[][2], s16 x, s16 y, bool32 flag)
+{
+ const struct MetatileOffset *offsetData = sub_80695E0(offsets, MapGridGetMetatileBehaviorAt(x, y));
+ const struct MetatileOffset *offsetData2 = offsetData;
+ if (offsetData != NULL)
+ {
+ MapGridSetMetatileIdAt(x + offsetData[0].x, y + offsetData[0].y, offsetData[0].tileId);
+ if (flag)
+ {
+ CurrentMapDrawMetatileAt(x + offsetData[0].x, y + offsetData[0].y);
+ }
+ MapGridSetMetatileIdAt(x + offsetData2[1].x, y + offsetData2[1].y, offsetData2[1].tileId);
+ if (flag)
+ {
+ CurrentMapDrawMetatileAt(x + offsetData2[1].x, y + offsetData2[1].y);
+ }
+ }
+}
+#else
+__attribute__((naked))
+void sub_8069638(const struct MetatileOffset offsets[][2], s16 x, s16 y, bool32 flag)
+{
+ asm_unified("\tpush {r4-r7,lr}\n"
+ "\tmov r7, r8\n"
+ "\tpush {r7}\n"
+ "\tadds r5, r0, 0\n"
+ "\tmov r8, r3\n"
+ "\tlsls r1, 16\n"
+ "\tasrs r6, r1, 16\n"
+ "\tlsls r2, 16\n"
+ "\tasrs r7, r2, 16\n"
+ "\tadds r0, r6, 0\n"
+ "\tadds r1, r7, 0\n"
+ "\tbl MapGridGetMetatileBehaviorAt\n"
+ "\tadds r1, r0, 0\n"
+ "\tlsls r1, 16\n"
+ "\tlsrs r1, 16\n"
+ "\tadds r0, r5, 0\n"
+ "\tbl sub_80695E0\n"
+ "\tadds r4, r0, 0\n"
+ "\tadds r5, r4, 0\n"
+ "\tcmp r4, 0\n"
+ "\tbeq _080696B6\n"
+ "\tmovs r0, 0\n"
+ "\tldrsb r0, [r4, r0]\n"
+ "\tadds r0, r6, r0\n"
+ "\tmovs r1, 0x1\n"
+ "\tldrsb r1, [r4, r1]\n"
+ "\tadds r1, r7, r1\n"
+ "\tldrh r2, [r4, 0x2]\n"
+ "\tbl MapGridSetMetatileIdAt\n"
+ "\tmov r0, r8\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _0806968E\n"
+ "\tmovs r0, 0\n"
+ "\tldrsb r0, [r4, r0]\n"
+ "\tadds r0, r6, r0\n"
+ "\tmovs r1, 0x1\n"
+ "\tldrsb r1, [r4, r1]\n"
+ "\tadds r1, r7, r1\n"
+ "\tbl CurrentMapDrawMetatileAt\n"
+ "_0806968E:\n"
+ "\tmovs r0, 0x4\n"
+ "\tldrsb r0, [r5, r0]\n"
+ "\tadds r0, r6, r0\n"
+ "\tmovs r1, 0x5\n"
+ "\tldrsb r1, [r5, r1]\n"
+ "\tadds r1, r7, r1\n"
+ "\tldrh r2, [r5, 0x6]\n"
+ "\tbl MapGridSetMetatileIdAt\n"
+ "\tmov r0, r8\n"
+ "\tcmp r0, 0\n"
+ "\tbeq _080696B6\n"
+ "\tmovs r0, 0x4\n"
+ "\tldrsb r0, [r5, r0]\n"
+ "\tadds r0, r6, r0\n"
+ "\tmovs r1, 0x5\n"
+ "\tldrsb r1, [r5, r1]\n"
+ "\tadds r1, r7, r1\n"
+ "\tbl CurrentMapDrawMetatileAt\n"
+ "_080696B6:\n"
+ "\tpop {r3}\n"
+ "\tmov r8, r3\n"
+ "\tpop {r4-r7}\n"
+ "\tpop {r0}\n"
+ "\tbx r0");
+}
+#endif
+
+void sub_80696C0(s16 x, s16 y, bool32 flag)
+{
+ sub_8069638(gUnknown_08376384, x, y, flag);
+}
+
+void sub_80696E4(s16 x, s16 y, bool32 flag)
+{
+ sub_8069638(gUnknown_083763A4, x, y, flag);
+}
+
+void sub_8069708(s16 x, s16 y, bool32 flag)
+{
+ sub_8069638(gUnknown_083763C4, x, y, flag);
+}
+
+bool32 sub_806972C(s16 x1, s16 y1, s16 x2, s16 y2)
+{
+ s8 metatileBehavior = MapGridGetMetatileBehaviorAt(x2, y2);
+ if (sub_80576A0(metatileBehavior))
+ {
+ if (y1 > y2)
+ {
+ return FALSE;
+ }
+ }
+ else if (sub_80576B4(metatileBehavior))
+ {
+ if (y1 < y2)
+ {
+ return FALSE;
+ }
+ }
+ else if (sub_80576C8(metatileBehavior))
+ {
+ if (x1 > x2)
+ {
+ return FALSE;
+ }
+ }
+ else if (sub_80576DC(metatileBehavior))
+ {
+ if (x1 < x2)
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+bool32 sub_80697C8(s16 x1, s16 y1, s16 x2, s16 y2)
+{
+ s8 metatileBehavior = MapGridGetMetatileBehaviorAt(x1, y1);
+ if (sub_80576A0(metatileBehavior))
+ {
+ if (y1 < y2)
+ {
+ return FALSE;
+ }
+ }
+ else if (sub_80576B4(metatileBehavior))
+ {
+ if (y1 > y2)
+ {
+ return FALSE;
+ }
+ }
+ else if (sub_80576C8(metatileBehavior))
+ {
+ if (x1 < x2)
+ {
+ return FALSE;
+ }
+ }
+ else if (sub_80576DC(metatileBehavior))
+ {
+ if (x1 > x2)
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+void PerStepCallback_8069864(u8 taskId)
+{
+ s16 *data;
+ s16 x, y;
+ data = gTasks[taskId].data;
+ PlayerGetDestCoords(&x, &y);
+ switch (data[1])
+ {
+ case 0:
+ data[2] = x;
+ data[3] = y;
+ sub_80696E4(x, y, TRUE);
+ data[1] = 1;
+ break;
+ case 1:
+ if (x != data[2] || y != data[3])
+ {
+ if (sub_806972C(x, y, data[2], data[3]))
+ {
+ sub_80696C0(data[2], data[3], TRUE);
+ sub_8069708(data[2], data[3], FALSE);
+ data[4] = data[2];
+ data[5] = data[3];
+ data[1] = 2;
+ data[6] = 8;
+ }
+ else
+ {
+ data[4] = -1;
+ data[5] = -1;
+ }
+ if (sub_80697C8(x, y, data[2], data[3]))
+ {
+ sub_80696C0(x, y, TRUE);
+ data[1] = 2;
+ data[6] = 8;
+ }
+ data[2] = x;
+ data[3] = y;
+ if (MetatileBehavior_IsPacifidlogLog(MapGridGetMetatileBehaviorAt(x, y)))
+ {
+ PlaySE(SE_MIZU);
+ }
+ }
+ break;
+ case 2:
+ if ((--data[6]) == 0)
+ {
+ sub_80696E4(x, y, TRUE);
+ if (data[4] != -1 && data[5] != -1)
+ {
+ sub_8069708(data[4], data[5], TRUE);
+ }
+ data[1] = 1;
+ }
+ break;
+ }
+}
+
+void sub_80699D8(s16 x, s16 y)
+{
+ u8 z = PlayerGetZCoord();
+ if (!(z & 0x01))
+ {
+ switch (MapGridGetMetatileIdAt(x, y))
+ {
+ case 0x24e:
+ MapGridSetMetatileIdAt(x, y, 0x24f);
+ break;
+ case 0x256:
+ MapGridSetMetatileIdAt(x, y, 0x257);
+ break;
+ }
+ }
+}
+
+void sub_8069A3C(s16 x, s16 y)
+{
+ u8 z = PlayerGetZCoord();
+ if (!(z & 0x01))
+ {
+ switch (MapGridGetMetatileIdAt(x, y))
+ {
+ case 0x24f:
+ MapGridSetMetatileIdAt(x, y, 0x24e);
+ break;
+ case 0x257:
+ MapGridSetMetatileIdAt(x, y, 0x256);
+ break;
+ }
+ }
+}
+
+void PerStepCallback_8069AA0(u8 taskId)
+{
+ bool8 isFortreeBridgeCur;
+ bool8 isFortreeBridgePrev;
+ u8 z, flag;
+ s16 x, y, x2, y2;
+ s16 *data = gTasks[taskId].data;
+ PlayerGetDestCoords(&x, &y);
+ switch (data[1])
+ {
+ default:
+ break;
+ case 0:
+ data[2] = x;
+ data[3] = y;
+ if (MetatileBehavior_IsFortreeBridge(MapGridGetMetatileBehaviorAt(x, y)))
+ {
+ sub_80699D8(x, y);
+ CurrentMapDrawMetatileAt(x, y);
+ }
+ data[1] = 1;
+ break;
+ case 1:
+ x2 = data[2];
+ y2 = data[3];
+ if (x == x2 && y == y2)
+ {
+ break;
+ }
+ isFortreeBridgeCur = MetatileBehavior_IsFortreeBridge(MapGridGetMetatileBehaviorAt(x, y));
+ isFortreeBridgePrev = MetatileBehavior_IsFortreeBridge(MapGridGetMetatileBehaviorAt(x2, y2));
+ z = PlayerGetZCoord();
+ flag = 0;
+ if ((u8)(z & 1) == 0)
+ {
+ flag = 1;
+ }
+ if (flag && (isFortreeBridgeCur == 1 || isFortreeBridgePrev == 1))
+ {
+ PlaySE(SE_HASHI);
+ }
+ if (isFortreeBridgePrev)
+ {
+ sub_8069A3C(x2, y2);
+ CurrentMapDrawMetatileAt(x2, y2);
+ sub_80699D8(x, y);
+ CurrentMapDrawMetatileAt(x, y);
+ }
+ data[4] = x2;
+ data[5] = y2;
+ data[2] = x;
+ data[3] = y;
+ if (!isFortreeBridgePrev)
+ {
+ break;
+ }
+ data[6] = 16;
+ data[1] = 2;
+ // fallthrough
+ case 2:
+ data[6]--;
+ x2 = data[4];
+ y2 = data[5];
+ switch (data[6] % 7)
+ {
+ case 0:
+ CurrentMapDrawMetatileAt(x2, y2);
+ case 1:
+ case 2:
+ case 3:
+ break;
+ case 4:
+ sub_80699D8(x2, y2);
+ CurrentMapDrawMetatileAt(x2, y2);
+ sub_8069A3C(x2, y2);
+ case 5:
+ case 6:
+ case 7:
+ break;
+ }
+ if (data[6] == 0)
+ {
+ data[1] = 1;
+ }
+ break;
+ }
+}
+
+const u16 gUnknown_083763E4[] = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ VAR_0x4001,
+ VAR_0x4002,
+ VAR_0x4003,
+ VAR_0x4004,
+ 0,
+ 0,
+ VAR_0x4005,
+ VAR_0x4006,
+ VAR_0x4007,
+ 0,
+ 0,
+ VAR_0x4008,
+ VAR_0x4009,
+ VAR_0x400A,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+bool32 sub_8069CB8(s16 x, s16 y)
+{
+ if ((u16)(x - 3) < 11 && (u16)(y - 6) < 14 && gUnknown_083763E4[y])
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void sub_8069CFC(s16 x, s16 y)
+{
+ if (sub_8069CB8(x, y))
+ {
+ *GetVarPointer(gUnknown_083763E4[y]) |= (1 << (x - 3));
+ }
+}
+
+bool32 sub_8069D34(s16 x, s16 y)
+{
+ u32 var;
+ if (!sub_8069CB8(x, y))
+ {
+ return FALSE;
+ }
+ var = VarGet(gUnknown_083763E4[y]) << 16;
+ if (((1 << 16) << (x - 3)) & var)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void sub_8069D78(void)
+{
+ s32 x, y;
+ s32 width = gMapHeader.mapData->width;
+ s32 height = gMapHeader.mapData->height;
+ for (x=0; x<width; x++)
+ {
+ for (y=0; y<height; y++)
+ {
+ if (sub_8069D34(x, y) == TRUE)
+ {
+ MapGridSetMetatileIdAt(x + 7, y + 7, 0x20e);
+ }
+ }
+ }
+}
+
+void PerStepCallback_8069DD4(u8 taskId)
+{
+ s16 x, y;
+ u16 tileBehavior;
+ u16 *var;
+ s16 *data = gTasks[taskId].data;
+ switch (data[1])
+ {
+ case 0:
+ PlayerGetDestCoords(&x, &y);
+ data[2] = x;
+ data[3] = y;
+ data[1] = 1;
+ break;
+ case 1:
+ PlayerGetDestCoords(&x, &y);
+ if (x != data[2] || y != data[3])
+ {
+ data[2] = x;
+ data[3] = y;
+ tileBehavior = MapGridGetMetatileBehaviorAt(x, y);
+ var = GetVarPointer(VAR_ICE_STEP_COUNT);
+ if (MetatileBehavior_IsThinIce(tileBehavior) == TRUE)
+ {
+ (*var)++;
+ data[6] = 4;
+ data[1] = 2;
+ data[4] = x;
+ data[5] = y;
+ }
+ else if (MetatileBehavior_IsCrackedIce(tileBehavior) == TRUE)
+ {
+ *var = 0;
+ data[6] = 4;
+ data[1] = 3;
+ data[4] = x;
+ data[5] = y;
+ }
+ }
+ break;
+ case 2:
+ if (data[6] != 0)
+ {
+ data[6]--;
+ }
+ else
+ {
+ x = data[4];
+ y = data[5];
+ PlaySE(SE_RU_BARI);
+ MapGridSetMetatileIdAt(x, y, 0x20e);
+ CurrentMapDrawMetatileAt(x, y);
+ sub_8069CFC(x - 7, y - 7);
+ data[1] = 1;
+ }
+ break;
+ case 3:
+ if (data[6] != 0)
+ {
+ data[6]--;
+ }
+ else
+ {
+ x = data[4];
+ y = data[5];
+ PlaySE(SE_RU_GASYAN);
+ MapGridSetMetatileIdAt(x, y, 0x206);
+ CurrentMapDrawMetatileAt(x, y);
+ data[1] = 1;
+ }
+ break;
+ }
+}
+
+void PerStepCallback_8069F64(u8 taskId)
+{
+ s16 x, y;
+ u16 *var;
+ s16 *data = gTasks[taskId].data;
+ PlayerGetDestCoords(&x, &y);
+ if (x != data[1] || y != data[2])
+ {
+ data[1] = x;
+ data[2] = y;
+ if (MetatileBehavior_IsAshGrass(MapGridGetMetatileBehaviorAt(x, y)))
+ {
+ if (MapGridGetMetatileIdAt(x, y) == 0x20a)
+ {
+ ash(x, y, 0x212, 4);
+ }
+ else
+ {
+ ash(x, y, 0x206, 4);
+ }
+ if (CheckBagHasItem(ITEM_SOOT_SACK, 1))
+ {
+ var = GetVarPointer(VAR_ASH_GATHER_COUNT);
+ if (*var < 9999)
+ {
+ (*var)++;
+ }
+ }
+ }
+ }
+}
+
+void sub_806A040(s16 x, s16 y)
+{
+ MapGridSetMetatileIdAt(x, y, MapGridGetMetatileIdAt(x, y) == 0x22f ? 0x206 : 0x237);
+ CurrentMapDrawMetatileAt(x, y);
+}
+
+void PerStepCallback_806A07C(u8 taskId)
+{
+ s16 x, y;
+ u16 behavior;
+ s16 *data = gTasks[taskId].data;
+ PlayerGetDestCoords(&x, &y);
+ behavior = MapGridGetMetatileBehaviorAt(x, y);
+ if (data[4] != 0 && (--data[4]) == 0)
+ {
+ sub_806A040(data[5], data[6]);
+ }
+ if (data[7] != 0 && (--data[7]) == 0)
+ {
+ sub_806A040(data[8], data[9]);
+ }
+ if (MetatileBehavior_IsCrackedFloorHole(behavior))
+ {
+ VarSet(VAR_ICE_STEP_COUNT, 0); // this var does double duty
+ }
+ if ((x != data[2] || y != data[3]))
+ {
+ data[2] = x;
+ data[3] = y;
+ if (MetatileBehavior_IsCrackedFloor(behavior))
+ {
+ if (GetPlayerSpeed() != 4)
+ {
+ VarSet(VAR_ICE_STEP_COUNT, 0); // this var does double duty
+ }
+ if (data[4] == 0)
+ {
+ data[4] = 3;
+ data[5] = x;
+ data[6] = y;
+ }
+ else if (data[7] == 0)
+ {
+ data[7] = 3;
+ data[8] = x;
+ data[9] = y;
+ }
+ }
+ }
+}
+
+const u16 gUnknown_08376418[] = {0xe8, 0xeb, 0xea, 0xe9};
+
+void sub_806A18C(s16 *data, s16 x, s16 y)
+{
+ u16 tile;
+ if ((--data[0]) == 0)
+ {
+ tile = 0xe8;
+ }
+ else
+ {
+ tile = gUnknown_08376418[data[0] / 8];
+ }
+ MapGridSetMetatileIdAt(x, y, tile);
+ CurrentMapDrawMetatileAt(x, y);
+ MapGridSetMetatileIdAt(x, y, 0xe8);
+}
+
+void Task_MuddySlope(u8 taskId)
+{
+ s16 x, y, x2, y2;
+ int i;
+ u16 mapIndices;
+ s16 *data = gTasks[taskId].data;
+ PlayerGetDestCoords(&x, &y);
+ mapIndices = (gSaveBlock1.location.mapGroup << 8) | gSaveBlock1.location.mapNum;
+ switch (data[1])
+ {
+ case 0:
+ data[0] = mapIndices;
+ data[2] = x;
+ data[3] = y;
+ data[1] = 1;
+ data[4] = 0;
+ data[7] = 0;
+ data[10] = 0;
+ data[13] = 0;
+ break;
+ case 1:
+ if (data[2] != x || data[3] != y)
+ {
+ data[2] = x;
+ data[3] = y;
+ if (MetatileBehavior_IsMuddySlope(MapGridGetMetatileBehaviorAt(x, y)))
+ {
+ for (i=4; i<14; i+=3)
+ {
+ if (data[i] == 0)
+ {
+ data[i] = 32;
+ data[i + 1] = x;
+ data[i + 2] = y;
+ break;
+ }
+ }
+ }
+ }
+ break;
+ }
+ if (gCamera.field_0 && mapIndices != data[0])
+ {
+ data[0] = mapIndices;
+ x2 = gCamera.x;
+ y2 = gCamera.y;
+ }
+ else
+ {
+ x2 = 0;
+ y2 = 0;
+ }
+ for (i=4; i<14; i+=3)
+ {
+ if (data[i])
+ {
+ data[i + 1] -= x2;
+ data[i + 2] -= y2;
+ sub_806A18C(&data[i], data[i + 1], data[i + 2]);
+ }
+ }
+}
diff --git a/src/field/field_weather.c b/src/field/field_weather.c
new file mode 100644
index 000000000..443a38357
--- /dev/null
+++ b/src/field/field_weather.c
@@ -0,0 +1,367 @@
+#include "global.h"
+#include "field_weather.h"
+#include "palette.h"
+#include "sprite.h"
+#include "task.h"
+
+struct Weather
+{
+ u8 filler_000[0x200];
+ u8 unknown_200[2][32];
+ u8 filler_240[0x480];
+ s8 unknown_6C0;
+ s8 unknown_6C1;
+ u8 unknown_6C2;
+ u8 unknown_6C3;
+ u16 unknown_6C4;
+ u8 unknown_6C6;
+ u8 unknown_6C7;
+ u8 unknown_6C8;
+ u8 unknown_6C9;
+ u8 unknown_6CA;
+ u8 unknown_6CB;
+ u8 filler_6CC[2];
+ u16 unknown_6CE;
+ u8 unknown_6D0;
+ u8 unknown_6D1;
+ u8 filler_6D2[1];
+ u8 unknown_6D3;
+ u8 unknown_6D4;
+ u8 unknown_6D5;
+ u8 filler_6D6[2];
+ u8 unknown_6D8;
+ u8 filler_6D9[1];
+ u8 unknown_6DA;
+ u8 filler_6DB[3];
+ u8 unknown_6DE;
+ u8 filler_6DF[5];
+ u8 unknown_6E4;
+ u8 filler_6E5[0x15];
+ u8 unknown_6FA;
+ u8 unknown_6FB;
+ u8 filler_6FC[4];
+ u8 unknown_700;
+ u8 filler_701[0x15];
+ u8 unknown_716;
+ u8 unknown_717;
+ u8 filler_718[0xc];
+ u8 unknown_724;
+ u8 filler_725[9];
+ u8 unknown_72E;
+};
+
+#define gWeather gUnknown_0202F7E8
+extern struct Weather gWeather;
+extern u8 *gUnknown_083970E8;
+extern u8 (*gUnknown_08396FC8[][4])(void);
+extern u8 (*gUnknown_083970B8[])(void);
+IWRAM_DATA u8 *gUnknown_030006DC;
+extern u8 gUnknown_083970C8;
+extern u8 (*gUnknown_0202FC48)[32];
+extern u8 gUnknown_0202F9E8[32];
+
+
+void sub_807C828(void)
+{
+ u8 index;
+ if (!FuncIsActiveTask(&sub_807CA34))
+ {
+ index = AllocSpritePalette(0x1200);
+ CpuCopy32(&gUnknown_083970E8, &gPlttBufferUnfaded[0x100 + index * 16], 32);
+ sub_807CB10();
+ gWeather.unknown_6D5 = index;
+ gWeather.unknown_6D4 = AllocSpritePalette(0x1201);
+ gWeather.unknown_6DA = 0;
+ gWeather.unknown_6D8 = 0;
+ gWeather.unknown_6DE = 0;
+ gWeather.unknown_6E4 = 0;
+ gWeather.unknown_700 = 0;
+ gWeather.unknown_6FB = 0;
+ gWeather.unknown_724 = 0;
+ gWeather.unknown_716 = 0;
+ gWeather.unknown_717 = 0;
+ gWeather.unknown_72E = 0;
+ gWeather.unknown_6FA = 0;
+ sub_807DB64(16, 0);
+ gWeather.unknown_6D0 = 0;
+ gWeather.unknown_6C6 = 3;
+ gWeather.unknown_6C8 = 0;
+ gWeather.unknown_6D3 = 1;
+ gWeather.unknown_6C9 = CreateTask(&sub_807C9E4, 80);
+ }
+}
+
+void DoWeatherEffect(u8 effect)
+{
+ if (effect != 3 && effect != 5 && effect != 13)
+ {
+ PlayRainSoundEffect();
+ }
+ if (gWeather.unknown_6D1 != effect && gWeather.unknown_6D0 == effect)
+ {
+ gUnknown_08396FC8[effect][0]();
+ }
+ gWeather.unknown_6D3 = 0;
+ gWeather.unknown_6D1 = effect;
+ gWeather.unknown_6CE = 0;
+}
+
+void sub_807C988(u8 effect)
+{
+ PlayRainSoundEffect();
+ gWeather.unknown_6D0 = effect;
+ gWeather.unknown_6D1 = effect;
+}
+
+void sub_807C9B4(u8 effect)
+{
+ PlayRainSoundEffect();
+ gWeather.unknown_6D0 = effect;
+ gWeather.unknown_6D1 = effect;
+ gWeather.unknown_6C8 = 1;
+}
+
+void sub_807C9E4(u8 task)
+{
+ if (gWeather.unknown_6C8)
+ {
+ gUnknown_08396FC8[gWeather.unknown_6D0][2]();
+ gTasks[task].func = &sub_807CA34;
+ }
+}
+
+void sub_807CA34(u8 task)
+{
+ u8 v1;
+ if (gWeather.unknown_6D0 != gWeather.unknown_6D1)
+ {
+ v1 = gUnknown_08396FC8[gWeather.unknown_6D0][3]();
+ if (!v1)
+ {
+ gUnknown_08396FC8[gWeather.unknown_6D1][0]();
+ gWeather.unknown_6C3 = 0; // compiler reuses v1
+ gWeather.unknown_6C6 = 0; // compiler reuses v1
+ gWeather.unknown_6D0 = gWeather.unknown_6D1;
+ gWeather.unknown_6D3 = 1;
+ }
+ }
+ else
+ {
+ gUnknown_08396FC8[gWeather.unknown_6D0][1]();
+ }
+ gUnknown_083970B8[gWeather.unknown_6C6]();
+}
+
+void sub_807CAE8(void)
+{
+ gWeather.unknown_6C1 = 0;
+ gWeather.unknown_6C2 = 0;
+}
+
+void nullsub_38(void)
+{
+}
+
+u32 sub_807CB0C(void)
+{
+ return 0;
+}
+
+void sub_807CB10(void)
+{
+ u16 v0;
+ u8(*v1)[32];
+ u16 v2;
+ u16 v4;
+ u16 v5;
+ u16 v6;
+ u16 v9;
+ u32 v10;
+ u16 v11;
+ s16 dunno;
+
+ gUnknown_030006DC = &gUnknown_083970C8;
+ for (v0 = 0; v0 <= 1; v0++)
+ {
+ if (v0 == 0)
+ {
+ v1 = &gUnknown_0202F9E8;
+ }
+ else
+ {
+ v1 = &gUnknown_0202F9E8 + 19;
+ }
+ for (v2 = 0; (u16)v2 <= 0x1f; v2++)
+ {
+ v4 = v2 << 8;
+ if (v0 == 0)
+ {
+ v5 = (v2 << 8) / 16;
+ }
+ else
+ {
+ v5 = 0;
+ }
+ v6 = 0;
+ for (; v6 <= 2; v6++)
+ {
+ v4 = (v4 - v5);
+ v1[v6][v2] = v4 >> 8;
+ }
+ v9 = v4;
+ v10 = 0x1f00 - v4;
+ if ((0x1f00 - v4) < 0)
+ {
+ v10 += 0xf;
+ }
+ v11 = v10 >> 4;
+ if (v2 <= 0xb)
+ {
+ for (; v6 <= 0x12; v6++)
+ {
+ v4 += v11;
+ dunno = v4 - v9;
+ if (dunno > 0)
+ {
+ v4 -= (dunno + ((u16)dunno >> 15)) >> 1;
+ }
+ v1[v6][v2] = v4 >> 8;
+ if (v1[v6][v2] > 0x1f)
+ {
+ v1[v6][v2] = 0x1f;
+ }
+ }
+ }
+ else
+ {
+ for (; v6 <= 0x12; v6++)
+ {
+ v4 += v11;
+ v1[v6][v2] = v4 >> 8;
+ if (v1[v6][v2] > 0x1f)
+ {
+ v1[v6][v2] = 0x1f;
+ }
+ }
+ }
+ }
+ }
+}
+
+void sub_807CC24(void)
+{
+ if (gWeather.unknown_6C0 == gWeather.unknown_6C1)
+ {
+ gWeather.unknown_6C6 = 3;
+ }
+ else
+ {
+ if (++gWeather.unknown_6C3 >= gWeather.unknown_6C2)
+ {
+ gWeather.unknown_6C3 = 0;
+ if (gWeather.unknown_6C0 < gWeather.unknown_6C1)
+ {
+ gWeather.unknown_6C0++;
+ }
+ else
+ {
+ gWeather.unknown_6C0--;
+ }
+ sub_807CEBC(0, 0x20, gWeather.unknown_6C0);
+ }
+ }
+}
+
+void sub_807CCAC(void)
+{
+ if (++gWeather.unknown_6CB > 1)
+ {
+ gWeather.unknown_6CA = 0;
+ }
+ switch (gWeather.unknown_6D0)
+ {
+ case 3:
+ case 4:
+ case 5:
+ case 11:
+ case 13:
+ if (sub_807CDC4() == 0)
+ {
+ gWeather.unknown_6C0 = 3;
+ gWeather.unknown_6C6 = 3;
+ }
+ break;
+ case 12:
+ if (sub_807CE24() == 0)
+ {
+ gWeather.unknown_6C0 = -6;
+ gWeather.unknown_6C6 = 3;
+ }
+ break;
+ case 6:
+ if (sub_807CE7C() == 0)
+ {
+ gWeather.unknown_6C0 = 0;
+ gWeather.unknown_6C6 = 3;
+ }
+ break;
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ default:
+ if (!gPaletteFade.active)
+ {
+ gWeather.unknown_6C0 = gWeather.unknown_6C1;
+ gWeather.unknown_6C6 = 3;
+ }
+ break;
+ }
+}
+
+u8 sub_807CDC4(void)
+{
+ if (gWeather.unknown_6C7 == 0x10)
+ {
+ return 0;
+ }
+ if (++gWeather.unknown_6C7 >= 0x10)
+ {
+ sub_807CEBC(0, 0x20, 3);
+ gWeather.unknown_6C7 = 0x10;
+ return 0;
+ }
+ sub_807D1BC(0, 0x20, 3, 0x10 - gWeather.unknown_6C7, gWeather.unknown_6C4);
+ return 1;
+}
+
+u8 sub_807CE24(void)
+{
+ if (gWeather.unknown_6C7 == 0x10)
+ {
+ return 0;
+ }
+ if (++gWeather.unknown_6C7 >= 0x10)
+ {
+ sub_807CEBC(0, 0x20, -6);
+ gWeather.unknown_6C7 = 0x10;
+ return 0;
+ }
+ sub_807D304(-6, 0x10 - gWeather.unknown_6C7, gWeather.unknown_6C4);
+ return 1;
+}
+
+u8 sub_807CE7C(void)
+{
+ if (gWeather.unknown_6C7 == 0x10)
+ {
+ return 0;
+ }
+ ++gWeather.unknown_6C7;
+ sub_807D424(0x10 - gWeather.unknown_6C7, gWeather.unknown_6C4);
+ return 1;
+}
+
+void nullsub_39(void)
+{
+}
diff --git a/src/field/fieldmap.c b/src/field/fieldmap.c
new file mode 100644
index 000000000..7a31ae720
--- /dev/null
+++ b/src/field/fieldmap.c
@@ -0,0 +1,955 @@
+#include "global.h"
+#include "fieldmap.h"
+#include "palette.h"
+#include "overworld.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;
+};
+
+struct Coords32
+{
+ s32 x;
+ s32 y;
+};
+
+EWRAM_DATA static u16 gUnknown_02029828[0x2800] = {0};
+EWRAM_DATA struct MapHeader gMapHeader = {0};
+EWRAM_DATA struct Camera gCamera = {0};
+EWRAM_DATA static struct ConnectionFlags gUnknown_0202E850 = {0};
+
+struct BackupMapData gUnknown_03004870;
+
+static const struct ConnectionFlags sDummyConnectionFlags = {0};
+
+struct MapHeader *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_80BB970(gMapHeader.events);
+ mapheader_run_script_with_tag_x1();
+}
+
+void sub_8055FC0(void)
+{
+ mapheader_copy_mapdata_with_padding(&gMapHeader);
+ sub_80BBCCC(0);
+ sub_80BB970(gMapHeader.events);
+ sub_8056670();
+ mapheader_run_script_with_tag_x1();
+ UpdateTVScreensOnMap(gUnknown_03004870.width, gUnknown_03004870.height);
+}
+
+void mapheader_copy_mapdata_with_padding(struct MapHeader *mapHeader)
+{
+ struct MapData *mapData;
+ int width;
+ int height;
+ mapData = mapHeader->mapData;
+ CpuFastFill16(0x03ff, gUnknown_02029828, sizeof(gUnknown_02029828));
+ gUnknown_03004870.map = gUnknown_02029828;
+ width = mapData->width + 15;
+ gUnknown_03004870.width = width;
+ height = mapData->height + 14;
+ gUnknown_03004870.height = height;
+ if (width * height <= 0x2800)
+ {
+ map_copy_with_padding(mapData->map, mapData->width, mapData->height);
+ sub_80560AC(mapHeader);
+ }
+}
+
+void map_copy_with_padding(u16 *map, u16 width, u16 height)
+{
+ u16 *dest;
+ int y;
+ dest = gUnknown_03004870.map;
+ dest += gUnknown_03004870.width * 7 + 7;
+ for (y = 0; y < height; y++)
+ {
+ CpuCopy16(map, dest, width * 2);
+ dest += width + 0xf;
+ map += width;
+ }
+}
+
+void sub_80560AC(struct MapHeader *mapHeader)
+{
+ int i;
+ struct MapConnection *connection;
+ struct MapHeader *cMap;
+ u32 offset;
+ int count;
+ count = mapHeader->connections->count;
+ connection = mapHeader->connections->connections;
+ gUnknown_0202E850 = sDummyConnectionFlags;
+ for (i = 0; i < count; i++, connection++)
+ {
+ cMap = mapconnection_get_mapheader(connection);
+ offset = connection->offset;
+ switch (connection->direction)
+ {
+ case CONNECTION_SOUTH:
+ fillSouthConnection(mapHeader, cMap, offset);
+ gUnknown_0202E850.south = 1;
+ break;
+ case CONNECTION_NORTH:
+ fillNorthConnection(mapHeader, cMap, offset);
+ gUnknown_0202E850.north = 1;
+ break;
+ case CONNECTION_WEST:
+ fillWestConnection(mapHeader, cMap, offset);
+ gUnknown_0202E850.west = 1;
+ break;
+ case CONNECTION_EAST:
+ fillEastConnection(mapHeader, cMap, offset);
+ gUnknown_0202E850.east = 1;
+ break;
+ }
+ }
+}
+
+void sub_8056134(int x, int y, struct MapHeader *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_03004870.map[gUnknown_03004870.width * y + x];
+
+ for (i = 0; i < height; i++)
+ {
+ CpuCopy16(src, dest, width * 2);
+ dest += gUnknown_03004870.width;
+ src += mapWidth;
+ }
+}
+
+void fillSouthConnection(struct MapHeader *mapHeader, struct MapHeader *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_03004870.width)
+ {
+ width = x;
+ }
+ else
+ {
+ width = gUnknown_03004870.width;
+ }
+ x = 0;
+ }
+ else
+ {
+ x2 = 0;
+ if (x + cWidth < gUnknown_03004870.width)
+ {
+ width = cWidth;
+ }
+ else
+ {
+ width = gUnknown_03004870.width - x;
+ }
+ }
+ sub_8056134(
+ x, y,
+ connectedMapHeader,
+ x2, /*y2*/ 0,
+ width, /*height*/ 7);
+ }
+}
+
+void fillNorthConnection(struct MapHeader *mapHeader, struct MapHeader *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_03004870.width)
+ {
+ width = x;
+ }
+ else
+ {
+ width = gUnknown_03004870.width;
+ }
+ x = 0;
+ }
+ else
+ {
+ x2 = 0;
+ if (x + cWidth < gUnknown_03004870.width)
+ {
+ width = cWidth;
+ }
+ else
+ {
+ width = gUnknown_03004870.width - x;
+ }
+ }
+
+ sub_8056134(
+ x, /*y*/ 0,
+ connectedMapHeader,
+ x2, y2,
+ width, /*height*/ 7);
+
+ }
+}
+
+
+void fillWestConnection(struct MapHeader *mapHeader, struct MapHeader *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_03004870.height)
+ {
+ height = y + cHeight;
+ }
+ else
+ {
+ height = gUnknown_03004870.height;
+ }
+ y = 0;
+ }
+ else
+ {
+ y2 = 0;
+ if (y + cHeight < gUnknown_03004870.height)
+ {
+ height = cHeight;
+ }
+ else
+ {
+ height = gUnknown_03004870.height - y;
+ }
+ }
+
+ sub_8056134(
+ /*x*/ 0, y,
+ connectedMapHeader,
+ x2, y2,
+ /*width*/ 7, height);
+ }
+}
+
+void fillEastConnection(struct MapHeader *mapHeader, struct MapHeader *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_03004870.height)
+ {
+ height = y + cHeight;
+ }
+ else
+ {
+ height = gUnknown_03004870.height;
+ }
+ y = 0;
+ }
+ else
+ {
+ y2 = 0;
+ if (y + cHeight < gUnknown_03004870.height)
+ {
+ height = cHeight;
+ }
+ else
+ {
+ height = gUnknown_03004870.height - y;
+ }
+ }
+
+ sub_8056134(
+ 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_03004870.width
+ && y >= 0 && y < gUnknown_03004870.height)
+ {
+ block = gUnknown_03004870.map[x + gUnknown_03004870.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_03004870.width
+ && y >= 0 && y < gUnknown_03004870.height)
+ {
+ block = gUnknown_03004870.map[x + gUnknown_03004870.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 *mapData;
+ u16 *border;
+ u16 block2;
+
+ if (x >= 0 && x < gUnknown_03004870.width
+ && y >= 0 && y < gUnknown_03004870.height)
+ {
+ block = gUnknown_03004870.map[x + gUnknown_03004870.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_03004870.width
+ && y >= 0 && y < gUnknown_03004870.height)
+ {
+ i = x + y * gUnknown_03004870.width;
+ gUnknown_03004870.map[i] = (gUnknown_03004870.map[i] & 0xf000) | (metatile & 0xfff);
+ }
+}
+
+void MapGridSetMetatileEntryAt(int x, int y, u16 metatile)
+{
+ int i;
+ if (x >= 0 && x < gUnknown_03004870.width
+ && y >= 0 && y < gUnknown_03004870.height)
+ {
+ i = x + gUnknown_03004870.width * y;
+ gUnknown_03004870.map[i] = metatile;
+ }
+}
+
+u32 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 = gSaveBlock1.mapView;
+ width = gUnknown_03004870.width;
+ x = gSaveBlock1.pos.x;
+ y = gSaveBlock1.pos.y;
+ for (i = y; i < y + 14; i++)
+ {
+ for (j = x; j < x + 15; j++)
+ {
+ *mapView++ = gUnknown_02029828[width * i + j];
+ }
+ }
+}
+
+int sub_8056618(void)
+{
+ u16 i;
+ u32 r2;
+ r2 = 0;
+ for (i = 0; i < 0x200; i++)
+ {
+ r2 |= gSaveBlock1.mapView[i];
+ }
+ if (r2 == 0)
+ {
+ return 1;
+ }
+ return 0;
+}
+
+void sav2_mapdata_clear(void)
+{
+ CpuFill16(0, gSaveBlock1.mapView, sizeof(gSaveBlock1.mapView));
+}
+
+void sub_8056670(void)
+{
+ int i, j;
+ int x, y;
+ u16 *mapView;
+ int width;
+ mapView = gSaveBlock1.mapView;
+ if (!sub_8056618())
+ {
+ width = gUnknown_03004870.width;
+ x = gSaveBlock1.pos.x;
+ y = gSaveBlock1.pos.y;
+ for (i = y; i < y + 14; i++)
+ {
+ for (j = x; j < x + 15; j++)
+ {
+ gUnknown_02029828[width * i + j] = *mapView++;
+ }
+ }
+ sav2_mapdata_clear();
+ }
+}
+
+void sub_80566F0(u8 a1)
+{
+ u16 *mapView;
+ int width;
+ int x0, y0;
+ int x2, y2;
+ u16 *src, *dest;
+ int srci, desti;
+ int r9, r8;
+ int x, y;
+ int i, j;
+ mapView = gSaveBlock1.mapView;
+ width = gUnknown_03004870.width;
+ r9 = 0;
+ r8 = 0;
+ x0 = gSaveBlock1.pos.x;
+ y0 = gSaveBlock1.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_02029828[x0 + desti + j];
+ *dest = *src;
+ i++;
+ j++;
+ }
+ }
+ sav2_mapdata_clear();
+}
+
+int GetMapBorderIdAt(int x, int y)
+{
+ struct MapData *mapData;
+ u16 block, block2;
+ int i, j;
+ if (x >= 0 && x < gUnknown_03004870.width
+ && y >= 0 && y < gUnknown_03004870.height)
+ {
+ i = gUnknown_03004870.width;
+ i *= y;
+ block = gUnknown_03004870.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_03004870.width - 8))
+ {
+ if (!gUnknown_0202E850.east)
+ {
+ return -1;
+ }
+ return CONNECTION_EAST;
+ }
+ else if (x < 7)
+ {
+ if (!gUnknown_0202E850.west)
+ {
+ return -1;
+ }
+ return CONNECTION_WEST;
+ }
+ else if (y >= (gUnknown_03004870.height - 7))
+ {
+ if (!gUnknown_0202E850.south)
+ {
+ return -1;
+ }
+ return CONNECTION_SOUTH;
+ }
+ else if (y < 7)
+ {
+ if (!gUnknown_0202E850.north)
+ {
+ return -1;
+ }
+ return CONNECTION_NORTH;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+int GetPostCameraMoveMapBorderId(int x, int y)
+{
+ return GetMapBorderIdAt(gSaveBlock1.pos.x + 7 + x, gSaveBlock1.pos.y + 7 + y);
+}
+
+int CanCameraMoveInDirection(int direction)
+{
+ int x, y;
+ x = gSaveBlock1.pos.x + 7 + gUnknown_0821664C[direction].x;
+ y = gSaveBlock1.pos.y + 7 + gUnknown_0821664C[direction].y;
+ if (GetMapBorderIdAt(x, y) == -1)
+ {
+ return 0;
+ }
+ return 1;
+}
+
+void sub_8056918(struct MapConnection *connection, int direction, int x, int y)
+{
+ struct MapHeader *mapHeader;
+ mapHeader = mapconnection_get_mapheader(connection);
+ switch (direction)
+ {
+ case CONNECTION_EAST:
+ gSaveBlock1.pos.x = -x;
+ gSaveBlock1.pos.y -= connection->offset;
+ break;
+ case CONNECTION_WEST:
+ gSaveBlock1.pos.x = mapHeader->mapData->width;
+ gSaveBlock1.pos.y -= connection->offset;
+ break;
+ case CONNECTION_SOUTH:
+ gSaveBlock1.pos.x -= connection->offset;
+ gSaveBlock1.pos.y = -y;
+ break;
+ case CONNECTION_NORTH:
+ gSaveBlock1.pos.x -= connection->offset;
+ gSaveBlock1.pos.y = mapHeader->mapData->height;
+ break;
+ }
+}
+
+bool8 CameraMove(int x, int y)
+{
+ unsigned int direction;
+ struct MapConnection *connection;
+ int old_x, old_y;
+ gCamera.field_0 = FALSE;
+ direction = GetPostCameraMoveMapBorderId(x, y);
+ if (direction + 1 <= 1)
+ {
+ gSaveBlock1.pos.x += x;
+ gSaveBlock1.pos.y += y;
+ }
+ else
+ {
+ save_serialize_map();
+ old_x = gSaveBlock1.pos.x;
+ old_y = gSaveBlock1.pos.y;
+ connection = sub_8056A64(direction, gSaveBlock1.pos.x, gSaveBlock1.pos.y);
+ sub_8056918(connection, direction, x, y);
+ sub_80538F0(connection->mapGroup, connection->mapNum);
+ gCamera.field_0 = TRUE;
+ gCamera.x = old_x - gSaveBlock1.pos.x;
+ gCamera.y = old_y - gSaveBlock1.pos.y;
+ gSaveBlock1.pos.x += x;
+ gSaveBlock1.pos.y += y;
+ sub_80566F0(direction);
+ }
+ return gCamera.field_0;
+}
+
+struct MapConnection *sub_8056A64(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)
+ {
+ if (sub_8056ABC(direction, x, y, connection) == TRUE)
+ {
+ return connection;
+ }
+ }
+ }
+ return NULL;
+}
+
+bool8 sub_8056ABC(u8 direction, int x, int y, struct MapConnection *connection)
+{
+ struct MapHeader *mapHeader;
+ mapHeader = mapconnection_get_mapheader(connection);
+ switch (direction)
+ {
+ case CONNECTION_SOUTH:
+ case CONNECTION_NORTH:
+ return sub_8056B20(x, gMapHeader.mapData->width, mapHeader->mapData->width, connection->offset);
+ case CONNECTION_WEST:
+ case CONNECTION_EAST:
+ return sub_8056B20(y, gMapHeader.mapData->height, mapHeader->mapData->height, connection->offset);
+ }
+ return FALSE;
+}
+
+bool8 sub_8056B20(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_8056B4C(int x, int width)
+{
+ if (x >= 0 && x < width)
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+int sub_8056B60(struct MapConnection *connection, int x, int y)
+{
+ struct MapHeader *mapHeader;
+ mapHeader = mapconnection_get_mapheader(connection);
+ switch (connection->direction)
+ {
+ case CONNECTION_SOUTH:
+ case CONNECTION_NORTH:
+ return sub_8056B4C(x - connection->offset, mapHeader->mapData->width);
+ case CONNECTION_WEST:
+ case CONNECTION_EAST:
+ return sub_8056B4C(y - connection->offset, mapHeader->mapData->height);
+ }
+ return FALSE;
+}
+
+struct MapConnection *sub_8056BA0(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_8056B60(connection, x - 7, y - 7) == TRUE)
+ {
+ return connection;
+ }
+ }
+ }
+ return NULL;
+}
+
+void sub_8056C50(u16 x, u16 y)
+{
+ gSaveBlock1.pos.x = x - 7;
+ gSaveBlock1.pos.y = y - 7;
+}
+
+void sav1_camera_get_focus_coords(u16 *x, u16 *y)
+{
+ *x = gSaveBlock1.pos.x + 7;
+ *y = gSaveBlock1.pos.y + 7;
+}
+
+void unref_sub_8056C7C(u16 x, u16 y)
+{
+ gSaveBlock1.pos.x = x;
+ gSaveBlock1.pos.y = y;
+}
+
+void GetCameraCoords(u16 *x, u16 *y)
+{
+ *x = gSaveBlock1.pos.x;
+ *y = gSaveBlock1.pos.y;
+}
+
+void sub_8056C98(struct Tileset *tileset, void *src)
+{
+ if (tileset)
+ {
+ if (!tileset->isCompressed)
+ {
+ CpuFastSet(tileset->tiles, src, 0x1000);
+ }
+ else
+ {
+ LZ77UnCompVram(tileset->tiles, src);
+ }
+ }
+}
+
+void sub_8056CBC(struct Tileset *tileset, int offset, int size)
+{
+ u16 black;
+ if (tileset)
+ {
+ if (tileset->isSecondary == FALSE)
+ {
+ black = 0;
+ LoadPalette(&black, offset, 2);
+ LoadPalette(tileset->palettes + 2, offset + 1, size - 2);
+ }
+ else if (tileset->isSecondary == TRUE)
+ {
+ LoadPalette(tileset->palettes + 0xc0, offset, size);
+ }
+ else
+ {
+ LZ77UnCompVram(tileset->palettes, (void*)0x2000000);
+ LoadPalette((void*)0x2000000, offset, size);
+ }
+ }
+}
+
+void sub_8056D28(struct MapData *mapData)
+{
+ void *src = (void*)(BG_VRAM);
+ sub_8056C98(mapData->primaryTileset, src);
+}
+
+void sub_8056D38(struct MapData *mapData)
+{
+ void *src = (void*)(BG_VRAM + 0x4000);
+ sub_8056C98(mapData->secondaryTileset, src);
+}
+
+void apply_map_tileset1_palette(struct MapData *mapData)
+{
+ sub_8056CBC(mapData->primaryTileset, 0, 0xc0);
+}
+
+void apply_map_tileset2_palette(struct MapData *mapData)
+{
+ sub_8056CBC(mapData->secondaryTileset, 0x60, 0xc0);
+}
+
+void copy_map_tileset1_tileset2_to_vram(struct MapData *mapData)
+{
+ if (mapData)
+ {
+ sub_8056D28(mapData);
+ sub_8056D38(mapData);
+ }
+}
+
+void apply_map_tileset1_tileset2_palette(struct MapData *mapData)
+{
+ if (mapData)
+ {
+ apply_map_tileset1_palette(mapData);
+ apply_map_tileset2_palette(mapData);
+ }
+}
diff --git a/src/field/fldeff_cut.c b/src/field/fldeff_cut.c
new file mode 100644
index 000000000..00643a979
--- /dev/null
+++ b/src/field/fldeff_cut.c
@@ -0,0 +1,287 @@
+#include "global.h"
+#include "fldeff_cut.h"
+#include "field_camera.h"
+#include "field_effect.h"
+#include "field_player_avatar.h"
+#include "fieldmap.h"
+#include "map_obj_lock.h"
+#include "metatile_behavior.h"
+#include "metatile_behaviors.h"
+#include "pokemon_menu.h"
+#include "overworld.h"
+#include "rom6.h"
+#include "script.h"
+#include "songs.h"
+#include "sound.h"
+#include "sprite.h"
+#include "task.h"
+#include "trig.h"
+
+extern u8 gCutGrassSpriteArray[8]; // seems to be an array of 8 sprite IDs
+
+extern void (*gFieldCallback)(void);
+extern void (*gUnknown_03005CE4)(void);
+
+extern struct SpriteTemplate gSpriteTemplate_CutGrass;
+
+extern struct MapPosition gUnknown_0203923C;
+
+extern u8 gLastFieldPokeMenuOpened;
+
+extern u8 S_UseCut[];
+
+bool8 SetUpFieldMove_Cut(void)
+{
+ s16 x, y;
+ u8 i, j;
+ u8 tileBehavior;
+
+ if(npc_before_player_of_type(0x52) == TRUE) // is in front of tree?
+ {
+ gFieldCallback = FieldCallback_Teleport;
+ gUnknown_03005CE4 = sub_80A2634;
+ return TRUE;
+ }
+ else // is in ash or grass to cut?
+ {
+ PlayerGetDestCoords(&gUnknown_0203923C.x, &gUnknown_0203923C.y);
+ for(i = 0; i < 3; i++)
+ {
+ y = i - 1 + gUnknown_0203923C.y;
+ for(j = 0; j < 3; j++)
+ {
+ x = j - 1 + gUnknown_0203923C.x;
+ if(MapGridGetZCoordAt(x, y) == (s8)gUnknown_0203923C.height)
+ {
+ tileBehavior = MapGridGetMetatileBehaviorAt(x, y);
+ if(MetatileBehavior_IsPokeGrass(tileBehavior) == TRUE
+ || MetatileBehavior_IsAshGrass(tileBehavior) == TRUE)
+ {
+ gFieldCallback = FieldCallback_Teleport;
+ gUnknown_03005CE4 = sub_80A25E8;
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE; // do not use cut
+ }
+}
+
+void sub_80A25E8(void)
+{
+ FieldEffectStart(FLDEFF_USE_CUT_ON_GRASS);
+ gFieldEffectArguments[0] = gLastFieldPokeMenuOpened;
+}
+
+bool8 FldEff_UseCutOnGrass(void)
+{
+ u8 taskId = oei_task_add();
+
+ gTasks[taskId].data[8] = (u32)sub_80A2684 >> 16;
+ gTasks[taskId].data[9] = (u32)sub_80A2684;
+ IncrementGameStat(0x12);
+ return FALSE;
+}
+
+void sub_80A2634(void)
+{
+ gFieldEffectArguments[0] = gLastFieldPokeMenuOpened;
+ ScriptContext1_SetupScript(S_UseCut);
+}
+
+bool8 FldEff_UseCutOnTree(void)
+{
+ u8 taskId = oei_task_add();
+
+ gTasks[taskId].data[8] = (u32)sub_80A2B00 >> 16;
+ gTasks[taskId].data[9] = (u32)sub_80A2B00;
+ IncrementGameStat(0x12);
+ return FALSE;
+}
+
+void sub_80A2684(void)
+{
+ FieldEffectActiveListRemove(FLDEFF_USE_CUT_ON_GRASS);
+ FieldEffectStart(FLDEFF_CUT_GRASS);
+}
+
+bool8 FldEff_CutGrass(void)
+{
+ s16 x, y;
+ u8 tileBehavior;
+ u8 i, j; // not in for loop?
+
+ for(i = 0, PlaySE(SE_W015), PlayerGetDestCoords(&gUnknown_0203923C.x, &gUnknown_0203923C.y); i < 3; i++)
+ {
+ y = i - 1 + gUnknown_0203923C.y;
+ for(j = 0; j < 3; j++)
+ {
+ x = j - 1 + gUnknown_0203923C.x;
+ if(MapGridGetZCoordAt(x, y) == (s8)gUnknown_0203923C.height)
+ {
+ tileBehavior = MapGridGetMetatileBehaviorAt(x, y);
+ if(MetatileBehavior_IsCuttableGrass(tileBehavior) == TRUE)
+ {
+ sub_80A27A8(x, y);
+ sub_805BCC0(x, y);
+ }
+ }
+ }
+ }
+ sub_80A28F4(gUnknown_0203923C.x - 1, gUnknown_0203923C.y - 2);
+ DrawWholeMapView();
+
+ // populate sprite ID array
+ for(i = 0; i < 8; i++)
+ {
+ gCutGrassSpriteArray[i] = CreateSprite((struct SpriteTemplate *)&gSpriteTemplate_CutGrass,
+ gSprites[gPlayerAvatar.spriteId].oam.x + 8, gSprites[gPlayerAvatar.spriteId].oam.y + 20, 0);
+ gSprites[gCutGrassSpriteArray[i]].data2 = 32 * i;
+ }
+ return 0;
+}
+
+// set map grid metatile depending on x, y
+// TODO: enum for metatile IDs
+void sub_80A27A8(s16 x, s16 y)
+{
+ int metatileId = MapGridGetMetatileIdAt(x, y);
+
+ switch(metatileId)
+ {
+ case 0x208:
+ case 0x15:
+ case 0xD:
+ MapGridSetMetatileIdAt(x, y, 0x1);
+ break;
+ case 0x1C6:
+ MapGridSetMetatileIdAt(x, y, 0x1CE);
+ break;
+ case 0x1C7:
+ MapGridSetMetatileIdAt(x, y, 0x1CF);
+ break;
+ case 0x281:
+ MapGridSetMetatileIdAt(x, y, 0x279);
+ break;
+ case 0x282:
+ MapGridSetMetatileIdAt(x, y, 0x27A);
+ break;
+ case 0x283:
+ MapGridSetMetatileIdAt(x, y, 0x27B);
+ break;
+ case 0x206:
+ case 0x207:
+ MapGridSetMetatileIdAt(x, y, 0x271);
+ break;
+ case 0x212:
+ case 0x20A:
+ MapGridSetMetatileIdAt(x, y, 0x218);
+ break;
+ case 0x25:
+ MapGridSetMetatileIdAt(x, y, 0xE);
+ break;
+ }
+}
+
+s32 sub_80A28A0(s16 x, s16 y)
+{
+ u16 metatileId = MapGridGetMetatileIdAt(x, y);
+
+ if(metatileId == 1)
+ return 1;
+ else if(metatileId == 633)
+ return 2;
+ else if(metatileId == 634)
+ return 3;
+ else if(metatileId == 635)
+ return 4;
+ else
+ return 0;
+}
+
+void sub_80A28F4(s16 x, s16 y)
+{
+ s16 i;
+ u16 lowerY = y + 3;
+
+ for(i = 0; i < 3; i++)
+ {
+ u16 currentX = x + i;
+ s16 currentXsigned = x + i;
+ if(MapGridGetMetatileIdAt(currentXsigned, y) == 21)
+ {
+ switch((u8)sub_80A28A0(currentXsigned, y + 1))
+ {
+ case 1:
+ MapGridSetMetatileIdAt(currentXsigned, y + 1, 0x208);
+ break;
+ case 2:
+ MapGridSetMetatileIdAt(currentXsigned, y + 1, 0x281);
+ break;
+ case 3:
+ MapGridSetMetatileIdAt(currentXsigned, y + 1, 0x282);
+ break;
+ case 4:
+ MapGridSetMetatileIdAt(currentXsigned, y + 1, 0x283);
+ break;
+ }
+ }
+ if(MapGridGetMetatileIdAt((s16)currentX, (s16)lowerY) == 1)
+ {
+ if(MapGridGetMetatileIdAt((s16)currentX, (s16)lowerY + 1) == 0x208)
+ MapGridSetMetatileIdAt((s16)currentX, (s16)lowerY + 1, 0x1);
+ if(MapGridGetMetatileIdAt((s16)currentX, (s16)lowerY + 1) == 0x281)
+ MapGridSetMetatileIdAt((s16)currentX, (s16)lowerY + 1, 0x279);
+ if(MapGridGetMetatileIdAt((s16)currentX, (s16)lowerY + 1) == 0x282)
+ MapGridSetMetatileIdAt((s16)currentX, (s16)lowerY + 1, 0x27A);
+ if(MapGridGetMetatileIdAt((s16)currentX, (s16)lowerY + 1) == 0x283)
+ MapGridSetMetatileIdAt((s16)currentX, (s16)lowerY + 1, 0x27B);
+ }
+ }
+}
+
+void sub_80A2A48(struct Sprite *sprite)
+{
+ sprite->data0 = 8;
+ sprite->data1 = 0;
+ sprite->data3 = 0;
+ sprite->callback = (void *)objc_8097BBC;
+}
+
+void objc_8097BBC(struct Sprite *sprite)
+{
+ u16 tempdata;
+ u16 tempdata2;
+
+ sprite->pos2.x = Sin(sprite->data2, sprite->data0);
+ sprite->pos2.y = Cos(sprite->data2, sprite->data0);
+
+ sprite->data2 = (sprite->data2 + 8) & 0xFF;
+ sprite->data0 += ((tempdata2 = sprite->data3) << 16 >> 18) + 1; // what?
+ sprite->data3 = tempdata2 + 1;
+
+ tempdata = sprite->data1;
+ if((s16)tempdata != 28) // done rotating the grass, execute clean up function
+ sprite->data1++;
+ else
+ sprite->callback = (void *)sub_80A2AB8;
+}
+
+void sub_80A2AB8(void)
+{
+ u8 i;
+
+ for (i = 1; i < 8; i++)
+ DestroySprite(&gSprites[gCutGrassSpriteArray[i]]);
+ FieldEffectStop(&gSprites[gCutGrassSpriteArray[0]], FLDEFF_CUT_GRASS);
+ sub_8064E2C();
+ ScriptContext2_Disable();
+}
+
+void sub_80A2B00(void)
+{
+ PlaySE(SE_W015);
+ FieldEffectActiveListRemove(FLDEFF_USE_CUT_ON_TREE);
+ EnableBothScriptContexts();
+}
diff --git a/src/field/fldeff_flash.c b/src/field/fldeff_flash.c
new file mode 100644
index 000000000..1ee8a8f05
--- /dev/null
+++ b/src/field/fldeff_flash.c
@@ -0,0 +1,306 @@
+#include "global.h"
+#include "event_data.h"
+#include "field_effect.h"
+#include "main.h"
+#include "palette.h"
+#include "pokemon_menu.h"
+#include "overworld.h"
+#include "rom6.h"
+#include "script.h"
+#include "songs.h"
+#include "sound.h"
+#include "sprite.h"
+#include "task.h"
+
+struct FlashStruct
+{
+ u8 unk0;
+ u8 unk1;
+ u8 unk2;
+ u8 unk3;
+ void (*func)(void);
+};
+
+extern struct FlashStruct gUnknown_083F7FC4[];
+extern u16 gCaveTransitionPalette_White[];
+extern u16 gCaveTransitionPalette_Black[];
+extern u16 gUnknown_083F808C[];
+extern u16 gUnknown_083F809C[];
+extern u16 gCaveTransitionTilemap[];
+extern u8 gCaveTransitionTiles[];
+
+extern u8 gLastFieldPokeMenuOpened;
+extern void (*gUnknown_03005CE4)(void);
+
+extern u8 gUnknown_081B694A[];
+
+void sub_810CBFC(void);
+void sub_810CC34(void);
+bool8 sub_810CD5C(void);
+void sub_810CE5C(u8);
+void sub_810CE78(u8);
+void sub_810CF18(u8);
+void sub_810CF5C(u8);
+void sub_810CFC4(u8);
+void sub_810D00C(u8);
+void sub_810D028(u8);
+void sub_810D0C4(u8);
+void sub_810D128(u8);
+
+bool8 SetUpFieldMove_Flash(void)
+{
+ if (gMapHeader.cave == TRUE && !FlagGet(SYS_USE_FLASH))
+ {
+ gFieldCallback = FieldCallback_Teleport;
+ gUnknown_03005CE4 = sub_810CBFC;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void sub_810CBFC(void)
+{
+ u8 taskId = oei_task_add();
+ gFieldEffectArguments[0] = gLastFieldPokeMenuOpened;
+ gTasks[taskId].data[8] = (uintptr_t)sub_810CC34 >> 16;
+ gTasks[taskId].data[9] = (uintptr_t)sub_810CC34;
+}
+
+void sub_810CC34(void)
+{
+ PlaySE(SE_W115);
+ FlagSet(SYS_USE_FLASH);
+ ScriptContext1_SetupScript(gUnknown_081B694A);
+}
+
+void sub_810CC54(void)
+{
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+}
+
+static void VBlankCB(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+void sub_810CC80(void)
+{
+ u16 ime;
+
+ SetVBlankCallback(NULL);
+ REG_DISPCNT = 0;
+ REG_BG2CNT = 0;
+ REG_BG1CNT = 0;
+ REG_BG0CNT = 0;
+ REG_BG2HOFS = 0;
+ REG_BG2VOFS = 0;
+ REG_BG1HOFS = 0;
+ REG_BG1VOFS = 0;
+ REG_BG0HOFS = 0;
+ REG_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(VBlankCB);
+ SetMainCallback2(sub_810CC54);
+ if (!sub_810CD5C())
+ SetMainCallback2(gMain.savedCallback);
+}
+
+bool8 sub_810CD5C(void)
+{
+ u8 i;
+ u8 v0 = get_map_type_from_warp0();
+ u8 v1 = Overworld_GetMapTypeOfSaveblockLocation();
+
+ for (i = 0; gUnknown_083F7FC4[i].unk0; i++)
+ {
+ if (gUnknown_083F7FC4[i].unk0 == v0 && gUnknown_083F7FC4[i].unk1 == v1)
+ {
+ gUnknown_083F7FC4[i].func();
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+u8 sub_810CDB8(u8 a1, u8 a2)
+{
+ u8 i;
+ u8 v0 = a1;
+ u8 v1 = a2;
+
+ for (i = 0; gUnknown_083F7FC4[i].unk0; i++)
+ {
+ if (gUnknown_083F7FC4[i].unk0 == v0 && gUnknown_083F7FC4[i].unk1 == v1)
+ {
+ return gUnknown_083F7FC4[i].unk2;
+ }
+ }
+
+ return FALSE;
+}
+
+u8 fade_type_for_given_maplight_pair(u8 a1, u8 a2)
+{
+ u8 i;
+ u8 v0 = a1;
+ u8 v1 = a2;
+
+ for (i = 0; gUnknown_083F7FC4[i].unk0; i++)
+ {
+ if (gUnknown_083F7FC4[i].unk0 == v0 && gUnknown_083F7FC4[i].unk1 == v1)
+ {
+ return gUnknown_083F7FC4[i].unk3;
+ }
+ }
+
+ return FALSE;
+}
+
+void sub_810CE48(void)
+{
+ CreateTask(sub_810CE5C, 0);
+}
+
+void sub_810CE5C(u8 taskId)
+{
+ gTasks[taskId].func = sub_810CE78;
+}
+
+void sub_810CE78(u8 taskId)
+{
+ REG_DISPCNT = 0;
+ LZ77UnCompVram(gCaveTransitionTiles, (void *)0x600C000);
+ LZ77UnCompVram(gCaveTransitionTilemap, (void *)0x600F800);
+ LoadPalette(gCaveTransitionPalette_White, 0xE0, 0x20);
+ LoadPalette(gUnknown_083F809C, 0xE0, 0x10);
+ REG_BLDCNT = 15937;
+ REG_BLDALPHA = 0;
+ REG_BLDY = 0;
+ REG_BG0CNT = 7948;
+ REG_DISPCNT = 4416;
+ gTasks[taskId].func = sub_810CF18;
+ gTasks[taskId].data[0] = 16;
+ gTasks[taskId].data[1] = 0;
+}
+
+void sub_810CF18(u8 taskId)
+{
+ u16 count = gTasks[taskId].data[1];
+ u16 blend = count + 0x1000;
+ REG_BLDALPHA = blend;
+ if (count <= 0x10)
+ {
+ gTasks[taskId].data[1]++;
+ }
+ else
+ {
+ gTasks[taskId].data[2] = 0;
+ gTasks[taskId].func = sub_810CF5C;
+ }
+}
+
+void sub_810CF5C(u8 taskId)
+{
+ u16 count;
+
+ REG_BLDALPHA = 4112;
+
+ count = gTasks[taskId].data[2];
+
+ if (count < 8)
+ {
+ gTasks[taskId].data[2]++;
+ LoadPalette(&gUnknown_083F809C[count], 0xE0, 16 - 2 * count);
+ }
+ else
+ {
+ LoadPalette(gCaveTransitionPalette_White, 0, 0x20);
+ gTasks[taskId].func = sub_810CFC4;
+ gTasks[taskId].data[2] = 8;
+ }
+}
+
+void sub_810CFC4(u8 taskId)
+{
+ if (gTasks[taskId].data[2])
+ gTasks[taskId].data[2]--;
+ else
+ SetMainCallback2(gMain.savedCallback);
+}
+
+void sub_810CFF8(void)
+{
+ CreateTask(sub_810D00C, 0);
+}
+
+void sub_810D00C(u8 taskId)
+{
+ gTasks[taskId].func = sub_810D028;
+}
+
+void sub_810D028(u8 taskId)
+{
+ REG_DISPCNT = 0;
+ LZ77UnCompVram(gCaveTransitionTiles, (void *)0x600C000);
+ LZ77UnCompVram(gCaveTransitionTilemap, (void *)0x600F800);
+ REG_BLDCNT = 0;
+ REG_BLDALPHA = 0;
+ REG_BLDY = 0;
+ REG_BG0CNT = 7948;
+ REG_DISPCNT = 4416;
+ LoadPalette(gCaveTransitionPalette_White, 0xE0, 0x20);
+ LoadPalette(gCaveTransitionPalette_Black, 0, 0x20);
+ gTasks[taskId].func = sub_810D0C4;
+ gTasks[taskId].data[0] = 16;
+ gTasks[taskId].data[1] = 0;
+ gTasks[taskId].data[2] = 0;
+}
+
+void sub_810D0C4(u8 taskId)
+{
+ u16 count = gTasks[taskId].data[2];
+ if (count < 16)
+ {
+ gTasks[taskId].data[2]++;
+ gTasks[taskId].data[2]++;
+ LoadPalette(&gUnknown_083F808C[15 - count], 0xE0, 2 * (count + 1));
+ }
+ else
+ {
+ REG_BLDALPHA = 4112;
+ REG_BLDCNT = 15937;
+ gTasks[taskId].func = sub_810D128;
+ }
+}
+
+void sub_810D128(u8 taskId)
+{
+ u16 count = 16 - gTasks[taskId].data[1];
+ u16 blend = count + 0x1000;
+ REG_BLDALPHA = blend;
+ if (count)
+ {
+ gTasks[taskId].data[1]++;
+ }
+ else
+ {
+ LoadPalette(gCaveTransitionPalette_Black, 0, 0x20);
+ SetMainCallback2(gMain.savedCallback);
+ }
+}
diff --git a/src/field/fldeff_softboiled.c b/src/field/fldeff_softboiled.c
new file mode 100644
index 000000000..cb26d9966
--- /dev/null
+++ b/src/field/fldeff_softboiled.c
@@ -0,0 +1,153 @@
+#include "global.h"
+#include "fldeff_softboiled.h"
+#include "menu.h"
+#include "party_menu.h"
+#include "pokemon.h"
+#include "pokemon_menu.h"
+#include "songs.h"
+#include "sound.h"
+#include "sprite.h"
+#include "strings.h"
+#include "task.h"
+
+struct Struct2001000 {
+ u8 unk0;
+ u8 unk1;
+ u8 unk2;
+ u8 filler3[9];
+ void *unkC;
+};
+
+struct Struct201C000 {
+ struct Pokemon *unk0;
+ u8 filler4[1];
+ u8 unk5;
+ u16 unk6;
+ u8 filler8[4];
+ s32 unkC;
+ void* unk10;
+ u8 filler14[26];
+ s16 unk2E;
+};
+
+#if ENGLISH
+#define WINDOW_LEFT 3
+#define WINDOW_RIGHT 26
+#elif GERMAN
+#define WINDOW_LEFT 0
+#define WINDOW_RIGHT 29
+#endif
+
+#define EWRAM_1000 (*(struct Struct2001000 *)(unk_2000000 + 0x1000))
+#define EWRAM_1B000_2 (*(struct Struct201B000 *)(unk_2000000 + 0x1B000))
+#define EWRAM_1C000 (*(struct Struct201C000 *)(unk_2000000 + 0x1C000))
+
+// extern
+extern u8 gUnknown_0202E8F6;
+extern u8 gLastFieldPokeMenuOpened;
+
+extern u8 unk_2000000[];
+extern u8 gUnknown_0202E8F4;
+
+// Static
+static void sub_8133D50(u8 taskId);
+static void sub_8133E74(u8 taskId);
+static void sub_8133EB8(u8 taskId);
+static void sub_8133EF8(void);
+
+bool8 SetUpFieldMove_SoftBoiled(void) {
+ u16 maxHp;
+ u16 hp;
+ u16 minHp;
+
+ maxHp = GetMonData(&gPlayerParty[gLastFieldPokeMenuOpened], MON_DATA_MAX_HP);
+ hp = GetMonData(&gPlayerParty[gLastFieldPokeMenuOpened], MON_DATA_HP);
+
+ minHp = (maxHp / 5);
+ if (hp >= minHp)
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void sub_8133D28(u8 taskid) {
+ EWRAM_1000.unkC = sub_8133D50;
+ EWRAM_1B000_2.unk272 = 3;
+ sub_808A004(taskid);
+}
+
+static void sub_8133D50(u8 taskId) {
+ u8 unk1, unk2;
+ u16 hp;
+ struct Pokemon *pokemon;
+ //struct Task *task;
+
+ struct Sprite *sprites = gSprites;
+
+
+ unk1 = sprites[EWRAM_1000.unk1].data0;
+ unk2 = sprites[EWRAM_1000.unk2].data0;
+
+ if (unk1 > 5 || unk2 > 5)
+ {
+ sub_806CD44(taskId);
+ return;
+ }
+
+ EWRAM_1C000.unk0 = &gPlayerParty[sprites[EWRAM_1000.unk2].data0];
+ hp = GetMonData(EWRAM_1C000.unk0, MON_DATA_HP);
+
+ if (hp == 0 || unk1 == unk2 || GetMonData(EWRAM_1C000.unk0, MON_DATA_MAX_HP) == hp)
+ {
+ sub_8133EB8(taskId);
+ return;
+ }
+
+ PlaySE(SE_KAIFUKU);
+
+ EWRAM_1C000.unk5 = gSprites[EWRAM_1000.unk1].data0;
+
+ pokemon = &gPlayerParty[EWRAM_1C000.unk5];
+ EWRAM_1C000.unk0 = pokemon;
+ EWRAM_1C000.unk6 = 0;
+ EWRAM_1C000.unkC = -0x8000;
+ EWRAM_1C000.unk10 = sub_8133EF8;
+
+
+ gTasks[taskId].data[10] = GetMonData(EWRAM_1C000.unk0, MON_DATA_MAX_HP);
+ gTasks[taskId].data[11] = GetMonData(EWRAM_1C000.unk0, MON_DATA_HP);
+ gTasks[taskId].data[12] = gTasks[taskId].data[10] / 5;
+
+ sub_806D5A4();
+ gTasks[taskId].func = sub_806FA18;
+ EWRAM_1B000_2.unk282 = gTasks[taskId].data[11];
+}
+
+static void sub_8133E74(u8 taskId) {
+ if (gUnknown_0202E8F6)
+ {
+ return;
+ }
+
+ MenuZeroFillWindowRect(WINDOW_LEFT, 14, WINDOW_RIGHT, 19);
+ sub_806D538(3, 0);
+ gTasks[taskId].func = sub_806CB74;
+}
+
+static void sub_8133EB8(u8 taskId) {
+ gUnknown_0202E8F4 = 0;
+ sub_806D5A4();
+ sub_806E834(gOtherText_CantUseOnPoke, 1);
+ gTasks[taskId].func = sub_8133E74;
+}
+
+static void sub_8133EF8(void) {
+ sub_806CCE4();
+ EWRAM_1B000_2.unk261 = 2;
+ DestroySprite(&gSprites[EWRAM_1000.unk1]);
+ MenuZeroFillWindowRect(WINDOW_LEFT, 14, WINDOW_RIGHT, 19);
+ sub_806D538(0, 0);
+ SwitchTaskToFollowupFunc(EWRAM_1000.unk0);
+}
diff --git a/src/field/fldeff_strength.c b/src/field/fldeff_strength.c
new file mode 100644
index 000000000..d9603d094
--- /dev/null
+++ b/src/field/fldeff_strength.c
@@ -0,0 +1,76 @@
+#include "global.h"
+#include "braille_puzzles.h"
+#include "field_effect.h"
+#include "party_menu.h"
+#include "pokemon.h"
+#include "pokemon_menu.h"
+#include "rom6.h"
+#include "script.h"
+#include "task.h"
+#include "text.h"
+
+static void sub_811AA18(void);
+static void sub_811AA38(void);
+static void sub_811AA9C(void);
+
+extern u8 gLastFieldPokeMenuOpened;
+extern u16 gScriptResult;
+extern void (*gFieldCallback)(void);
+extern void (*gUnknown_03005CE4)(void);
+
+extern u8 S_UseStrength[];
+
+bool8 SetUpFieldMove_Strength(void)
+{
+ if (ShouldDoBrailleStrengthEffect())
+ {
+ gScriptResult = gLastFieldPokeMenuOpened;
+ gFieldCallback = FieldCallback_Teleport;
+ gUnknown_03005CE4 = sub_811AA38;
+ }
+ else
+ {
+ if (npc_before_player_of_type(87) != TRUE)
+ return 0;
+ gScriptResult = gLastFieldPokeMenuOpened;
+ gFieldCallback = FieldCallback_Teleport;
+ gUnknown_03005CE4 = sub_811AA18;
+ }
+
+ return TRUE;
+}
+
+static void sub_811AA18(void)
+{
+ gFieldEffectArguments[0] = gLastFieldPokeMenuOpened;
+ ScriptContext1_SetupScript(S_UseStrength);
+}
+
+static void sub_811AA38(void)
+{
+ gFieldEffectArguments[0] = gLastFieldPokeMenuOpened;
+ FieldEffectStart(FLDEFF_USE_STRENGTH);
+}
+
+bool8 FldEff_UseStrength(void)
+{
+ u8 taskId = oei_task_add();
+
+ gTasks[taskId].data[8] = (u32)sub_811AA9C >> 16;
+ gTasks[taskId].data[9] = (u32)sub_811AA9C;
+ GetMonNickname(&gPlayerParty[gFieldEffectArguments[0]], gStringVar1);
+ return FALSE;
+}
+
+static void sub_811AA9C(void)
+{
+ if (ShouldDoBrailleStrengthEffect())
+ {
+ DoBrailleStrengthEffect();
+ }
+ else
+ {
+ FieldEffectActiveListRemove(40);
+ EnableBothScriptContexts();
+ }
+}
diff --git a/src/field/fldeff_sweetscent.c b/src/field/fldeff_sweetscent.c
new file mode 100644
index 000000000..b9dbf619d
--- /dev/null
+++ b/src/field/fldeff_sweetscent.c
@@ -0,0 +1,88 @@
+#include "global.h"
+#include "field_effect.h"
+#include "field_player_avatar.h"
+#include "palette.h"
+#include "pokemon_menu.h"
+#include "rom6.h"
+#include "script.h"
+#include "sound.h"
+#include "sprite.h"
+#include "task.h"
+#include "wild_encounter.h"
+
+static void sub_812BFD4(void);
+static void sub_812C01C(void);
+static void sub_812C084(u8);
+static void sub_812C118(u8);
+
+extern u8 gLastFieldPokeMenuOpened;
+extern void (*gFieldCallback)(void);
+extern void (*gUnknown_03005CE4)(void);
+
+extern u8 SweetScentNothingHereScript[];
+
+bool8 SetUpFieldMove_SweetScent(void)
+{
+ gFieldCallback = FieldCallback_Teleport;
+ gUnknown_03005CE4 = sub_812BFD4;
+ return TRUE;
+}
+
+static void sub_812BFD4(void)
+{
+ FieldEffectStart(FLDEFF_SWEET_SCENT);
+ gFieldEffectArguments[0] = gLastFieldPokeMenuOpened;
+}
+
+bool8 FldEff_SweetScent()
+{
+ u8 taskId = oei_task_add();
+
+ gTasks[taskId].data[8] = (u32)sub_812C01C >> 16;
+ gTasks[taskId].data[9] = (u32)sub_812C01C;
+ return FALSE;
+}
+
+static void sub_812C01C(void)
+{
+ u8 taskId;
+
+ PlaySE(0xEC);
+ BeginNormalPaletteFade(~(1 << (gSprites[GetPlayerAvatarObjectId()].oam.paletteNum + 16)), 4, 0, 8, 0x1F);
+ taskId = CreateTask(sub_812C084, 0);
+ gTasks[taskId].data[0] = 0;
+ FieldEffectActiveListRemove(FLDEFF_SWEET_SCENT);
+}
+
+static void sub_812C084(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ if (gTasks[taskId].data[0] == 64)
+ {
+ gTasks[taskId].data[0] = 0;
+ if (SweetScentWildEncounter() == TRUE)
+ {
+ DestroyTask(taskId);
+ }
+ else
+ {
+ gTasks[taskId].func = sub_812C118;
+ BeginNormalPaletteFade(~(1 << (gSprites[GetPlayerAvatarObjectId()].oam.paletteNum + 16)), 4, 8, 0, 0x1F);
+ }
+ }
+ else
+ {
+ gTasks[taskId].data[0]++;
+ }
+ }
+}
+
+static void sub_812C118(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ ScriptContext1_SetupScript(SweetScentNothingHereScript);
+ DestroyTask(taskId);
+ }
+}
diff --git a/src/field/fldeff_teleport.c b/src/field/fldeff_teleport.c
new file mode 100644
index 000000000..af48fb414
--- /dev/null
+++ b/src/field/fldeff_teleport.c
@@ -0,0 +1,46 @@
+#include "global.h"
+#include "fldeff_teleport.h"
+#include "field_effect.h"
+#include "field_player_avatar.h"
+#include "pokemon_menu.h"
+#include "overworld.h"
+#include "rom6.h"
+#include "task.h"
+
+extern void (*gFieldCallback)(void);
+extern u8 gLastFieldPokeMenuOpened;
+extern void (*gUnknown_03005CE4)(void);
+
+bool8 SetUpFieldMove_Teleport(void)
+{
+ if (Overworld_MapTypeAllowsTeleportAndFly(gMapHeader.mapType) == TRUE)
+ {
+ gFieldCallback = FieldCallback_Teleport;
+ gUnknown_03005CE4 = hm_teleport_run_dp02scr;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void hm_teleport_run_dp02scr(void)
+{
+ Overworld_ResetStateAfterTeleport();
+ FieldEffectStart(FLDEFF_USE_TELEPORT);
+ gFieldEffectArguments[0] = gLastFieldPokeMenuOpened;
+}
+
+bool8 FldEff_UseTeleport(void)
+{
+ u8 taskId = oei_task_add();
+ gTasks[taskId].data[8] = (u32)sub_814A404 >> 16;
+ gTasks[taskId].data[9] = (u32)sub_814A404;
+ SetPlayerAvatarTransitionFlags(1);
+ return 0;
+}
+
+void sub_814A404(void)
+{
+ FieldEffectActiveListRemove(FLDEFF_USE_TELEPORT);
+ sub_8087BA8();
+}
diff --git a/src/field/heal_location.c b/src/field/heal_location.c
new file mode 100644
index 000000000..42bc18567
--- /dev/null
+++ b/src/field/heal_location.c
@@ -0,0 +1,63 @@
+#include "global.h"
+#include "heal_location.h"
+#include "map_constants.h"
+
+#define NUM_HEAL_LOCATIONS 22
+
+static const struct HealLocation sHealLocations[] =
+{
+ {MAP_GROUP_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F, MAP_ID_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F, 4, 2},
+ {MAP_GROUP_LITTLEROOT_TOWN_MAYS_HOUSE_2F, MAP_ID_LITTLEROOT_TOWN_MAYS_HOUSE_2F, 4, 2},
+ {MAP_GROUP_PETALBURG_CITY, MAP_ID_PETALBURG_CITY, 20, 17},
+ {MAP_GROUP_SLATEPORT_CITY, MAP_ID_SLATEPORT_CITY, 19, 20},
+ {MAP_GROUP_MAUVILLE_CITY, MAP_ID_MAUVILLE_CITY, 22, 6},
+ {MAP_GROUP_RUSTBORO_CITY, MAP_ID_RUSTBORO_CITY, 16, 39},
+ {MAP_GROUP_FORTREE_CITY, MAP_ID_FORTREE_CITY, 5, 7},
+ {MAP_GROUP_LILYCOVE_CITY, MAP_ID_LILYCOVE_CITY, 24, 15},
+ {MAP_GROUP_MOSSDEEP_CITY, MAP_ID_MOSSDEEP_CITY, 28, 17},
+ {MAP_GROUP_SOOTOPOLIS_CITY, MAP_ID_SOOTOPOLIS_CITY, 43, 32},
+ {MAP_GROUP_EVER_GRANDE_CITY, MAP_ID_EVER_GRANDE_CITY, 27, 49},
+ {MAP_GROUP_LITTLEROOT_TOWN, MAP_ID_LITTLEROOT_TOWN, 5, 9},
+ {MAP_GROUP_LITTLEROOT_TOWN, MAP_ID_LITTLEROOT_TOWN, 14, 9},
+ {MAP_GROUP_OLDALE_TOWN, MAP_ID_OLDALE_TOWN, 6, 17},
+ {MAP_GROUP_DEWFORD_TOWN, MAP_ID_DEWFORD_TOWN, 2, 11},
+ {MAP_GROUP_LAVARIDGE_TOWN, MAP_ID_LAVARIDGE_TOWN, 9, 7},
+ {MAP_GROUP_FALLARBOR_TOWN, MAP_ID_FALLARBOR_TOWN, 14, 8},
+ {MAP_GROUP_VERDANTURF_TOWN, MAP_ID_VERDANTURF_TOWN, 16, 4},
+ {MAP_GROUP_PACIFIDLOG_TOWN, MAP_ID_PACIFIDLOG_TOWN, 8, 16},
+ {MAP_GROUP_EVER_GRANDE_CITY, MAP_ID_EVER_GRANDE_CITY, 18, 6},
+ {MAP_GROUP_BATTLE_TOWER_OUTSIDE, MAP_ID_BATTLE_TOWER_OUTSIDE, 14, 9},
+ {MAP_GROUP_SOUTHERN_ISLAND_EXTERIOR, MAP_ID_SOUTHERN_ISLAND_EXTERIOR, 15, 20},
+};
+
+u32 GetHealLocationIndexByMap(u16 mapGroup, u16 mapNum)
+{
+ u32 i;
+
+ for (i = 0; i < NUM_HEAL_LOCATIONS; i++)
+ {
+ if (sHealLocations[i].group == mapGroup && sHealLocations[i].map == mapNum)
+ return i + 1;
+ }
+ return 0;
+}
+
+const struct HealLocation *GetHealLocationByMap(u16 mapGroup, u16 mapNum)
+{
+ u32 index = GetHealLocationIndexByMap(mapGroup, mapNum);
+
+ if (index == 0)
+ return NULL;
+ else
+ return &sHealLocations[index - 1];
+}
+
+const struct HealLocation *GetHealLocation(u32 index)
+{
+ if (index == 0)
+ return NULL;
+ else if (index > NUM_HEAL_LOCATIONS)
+ return NULL;
+ else
+ return &sHealLocations[index - 1];
+}
diff --git a/src/field/hof_pc.c b/src/field/hof_pc.c
new file mode 100644
index 000000000..267ed4274
--- /dev/null
+++ b/src/field/hof_pc.c
@@ -0,0 +1,42 @@
+#include "global.h"
+#include "hall_of_fame.h"
+#include "main.h"
+#include "palette.h"
+#include "overworld.h"
+#include "script.h"
+#include "script_menu.h"
+#include "task.h"
+
+extern void (*gFieldCallback)(void);
+extern void (*gUnknown_0300485C)(void);
+
+static void ReshowPCMenuAfterHallOfFamePC(void);
+static void Task_WaitForPaletteFade(u8);
+
+void AccessHallOfFamePC(void)
+{
+ SetMainCallback2(sub_81428CC);
+ ScriptContext2_Enable();
+}
+
+void ReturnFromHallOfFamePC(void)
+{
+ SetMainCallback2(c2_exit_to_overworld_2_switch);
+ gFieldCallback = ReshowPCMenuAfterHallOfFamePC;
+}
+
+static void ReshowPCMenuAfterHallOfFamePC(void)
+{
+ ScriptContext2_Enable();
+ Overworld_PlaySpecialMapMusic();
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, 0);
+ ScrSpecial_CreatePCMenu();
+ ScriptMenu_DisplayPCStartupPrompt();
+ CreateTask(Task_WaitForPaletteFade, 10);
+}
+
+static void Task_WaitForPaletteFade(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ DestroyTask(taskId);
+}
diff --git a/src/field/item.c b/src/field/item.c
new file mode 100644
index 000000000..fd49f5c39
--- /dev/null
+++ b/src/field/item.c
@@ -0,0 +1,674 @@
+#include "global.h"
+#include "hold_effects.h"
+#include "item.h"
+#include "items.h"
+#include "item_use.h"
+#include "berry.h"
+#include "string_util.h"
+#include "strings.h"
+
+extern u8 gUnknown_02038560;
+
+// These constants are used in gItems
+enum
+{
+ POCKET_NONE,
+ POCKET_ITEMS,
+ POCKET_POKE_BALLS,
+ POCKET_TM_HM,
+ POCKET_BERRIES,
+ POCKET_KEY_ITEMS,
+};
+
+enum
+{
+ ITEMS_POCKET,
+ BALLS_POCKET,
+ TMHM_POCKET,
+ BERRIES_POCKET,
+ KEYITEMS_POCKET
+};
+
+#if ENGLISH
+#include "../data/item_descriptions_en.h"
+#include "../data/items_en.h"
+#elif GERMAN
+#include "../data/item_descriptions_de.h"
+#include "../data/items_de.h"
+#endif
+
+static void CompactPCItems(void);
+
+void CopyItemName(u16 itemId, u8 *string)
+{
+ if (itemId == ITEM_ENIGMA_BERRY)
+ {
+ StringCopy(string, GetBerryInfo(0x2B)->name); // berry 0x2b = enigma berry
+ StringAppend(string, gOtherText_Berry2);
+ }
+ else
+ StringCopy(string, ItemId_GetItem(itemId)->name);
+}
+
+//Unreferenced
+s8 CountUsedBagPocketSlots(u8 pocket)
+{
+ u8 i;
+
+ for (i = 0; i < gBagPockets[pocket].capacity; i++)
+ {
+ if (gBagPockets[pocket].itemSlots[i].itemId == 0)
+ return i;
+ }
+ return -1;
+}
+
+bool8 IsBagPocketNonEmpty(u8 pocket)
+{
+ u8 i;
+
+ for (i = 0; i < gBagPockets[pocket - 1].capacity; i++)
+ {
+ if (gBagPockets[pocket - 1].itemSlots[i].itemId != 0)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 CheckBagHasItem(u16 itemId, u16 count)
+{
+ u8 i;
+ u8 pocket;
+
+ if (ItemId_GetPocket(itemId) == 0)
+ return FALSE;
+ pocket = ItemId_GetPocket(itemId) - 1;
+ //Check for item slots that contain the item
+ for (i = 0; i < gBagPockets[pocket].capacity; i++)
+ {
+ if (gBagPockets[pocket].itemSlots[i].itemId == itemId)
+ {
+ //Does this item slot contain enough of the item?
+ if (gBagPockets[pocket].itemSlots[i].quantity >= count)
+ return TRUE;
+ count -= gBagPockets[pocket].itemSlots[i].quantity;
+ //Does this item slot and all previous slots contain enough of the item?
+ if (count == 0)
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+bool8 CheckBagHasSpace(u16 itemId, u16 count)
+{
+ u8 i;
+ u8 pocket;
+ u16 slotCapacity;
+
+ if (ItemId_GetPocket(itemId) == 0)
+ return FALSE;
+ 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)
+ {
+ if (gBagPockets[pocket].itemSlots[i].quantity + count <= slotCapacity)
+ return TRUE;
+ if (pocket == TMHM_POCKET || pocket == BERRIES_POCKET)
+ return FALSE;
+ count -= slotCapacity - gBagPockets[pocket].itemSlots[i].quantity;
+ 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;
+ else
+ count -= slotCapacity;
+ }
+ }
+ if (count > 0)
+ return FALSE; //No more item slots. The bag is full
+ }
+
+ return TRUE;
+}
+
+// This function matches if gBagPockets is declared non-const,
+// but it should be fixed anyway.
+#ifdef NONMATCHING
+bool8 AddBagItem(u16 itemId, u16 count)
+{
+ u8 i;
+ u8 pocket;
+ u16 slotCapacity;
+ struct ItemSlot newItems[64];
+
+ if (ItemId_GetPocket(itemId) == 0)
+ return FALSE;
+ pocket = ItemId_GetPocket(itemId) - 1;
+ //Copy the bag pocket
+ memcpy(newItems, gBagPockets[pocket].itemSlots, gBagPockets[pocket].capacity * sizeof(struct ItemSlot));
+ if (pocket != BERRIES_POCKET)
+ slotCapacity = 99;
+ else
+ slotCapacity = 999;
+
+ //Use any item slots that already contain this item
+ for (i = 0; i < gBagPockets[pocket].capacity; i++)
+ {
+ if (newItems[i].itemId == itemId)
+ {
+ if (newItems[i].quantity + count <= slotCapacity)
+ {
+ newItems[i].quantity += count;
+ //Copy pocket back into the bag.
+ memcpy(gBagPockets[pocket].itemSlots, newItems, gBagPockets[pocket].capacity * sizeof(struct ItemSlot));
+ return TRUE;
+ }
+ if (pocket == TMHM_POCKET || pocket == BERRIES_POCKET)
+ return FALSE;
+ count -= slotCapacity - newItems[i].quantity;
+ newItems[i].quantity = slotCapacity;
+ if (count == 0)
+ goto copy_items;
+ }
+ }
+
+ //Put any remaining items into new item slots.
+ if (count > 0)
+ {
+ for (i = 0; i < gBagPockets[pocket].capacity; i++)
+ {
+ if (newItems[i].itemId == 0)
+ {
+ newItems[i].itemId = itemId;
+ if (count <= slotCapacity)
+ {
+ newItems[i].quantity = count;
+ goto copy_items;
+ }
+ count -= slotCapacity;
+ newItems[i].quantity = slotCapacity;
+ }
+ }
+ if (count > 0)
+ return FALSE; //No more empty item slots. The bag is full.
+ }
+
+ copy_items:
+ //Copy pocket back into the bag.
+ memcpy(gBagPockets[pocket].itemSlots, newItems, gBagPockets[pocket].capacity * sizeof(struct ItemSlot));
+ return TRUE;
+}
+#else
+__attribute__((naked))
+bool8 AddBagItem(u16 itemId, u16 count)
+{
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ mov r7, r9\n\
+ mov r6, r8\n\
+ push {r6,r7}\n\
+ sub sp, 0x100\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ mov r8, r0\n\
+ lsls r1, 16\n\
+ lsrs r4, r1, 16\n\
+ bl ItemId_GetPocket\n\
+ lsls r0, 24\n\
+ cmp r0, 0\n\
+ beq _080A9510\n\
+ mov r0, r8\n\
+ bl ItemId_GetPocket\n\
+ subs r0, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r6, r0, 24\n\
+ ldr r1, _080A94F8 @ =gBagPockets\n\
+ lsls r0, r6, 3\n\
+ adds r5, r0, r1\n\
+ ldr r1, [r5]\n\
+ ldrb r2, [r5, 0x4]\n\
+ lsls r2, 2\n\
+ mov r0, sp\n\
+ bl memcpy\n\
+ ldr r7, _080A94FC @ =0x000003e7\n\
+ cmp r6, 0x3\n\
+ beq _080A9468\n\
+ movs r7, 0x63\n\
+_080A9468:\n\
+ movs r1, 0\n\
+ ldrb r0, [r5, 0x4]\n\
+ cmp r1, r0\n\
+ bcs _080A94B2\n\
+ subs r0, r6, 0x2\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ mov r12, r0\n\
+_080A9478:\n\
+ lsls r0, r1, 2\n\
+ mov r2, sp\n\
+ adds r3, r2, r0\n\
+ ldrh r0, [r3]\n\
+ cmp r0, r8\n\
+ bne _080A94A6\n\
+ ldrh r2, [r3, 0x2]\n\
+ adds r0, r2, r4\n\
+ cmp r0, r7\n\
+ ble _080A9500\n\
+ mov r0, r12\n\
+ cmp r0, 0x1\n\
+ bls _080A9510\n\
+ subs r0, r7, r2\n\
+ subs r0, r4, r0\n\
+ lsls r0, 16\n\
+ lsrs r4, r0, 16\n\
+ strh r7, [r3, 0x2]\n\
+ ldr r2, _080A94F8 @ =gBagPockets\n\
+ mov r9, r2\n\
+ lsls r3, r6, 3\n\
+ cmp r4, 0\n\
+ beq _080A9516\n\
+_080A94A6:\n\
+ adds r0, r1, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r1, r0, 24\n\
+ ldrb r0, [r5, 0x4]\n\
+ cmp r1, r0\n\
+ bcc _080A9478\n\
+_080A94B2:\n\
+ ldr r2, _080A94F8 @ =gBagPockets\n\
+ mov r9, r2\n\
+ lsls r3, r6, 3\n\
+ cmp r4, 0\n\
+ beq _080A9516\n\
+ movs r1, 0\n\
+ adds r0, r3, r2\n\
+ ldrb r0, [r0, 0x4]\n\
+ cmp r1, r0\n\
+ bcs _080A94F2\n\
+ mov r6, r9\n\
+ adds r5, r3, r6\n\
+_080A94CA:\n\
+ lsls r0, r1, 2\n\
+ mov r6, sp\n\
+ adds r2, r6, r0\n\
+ ldrh r0, [r2]\n\
+ cmp r0, 0\n\
+ bne _080A94E6\n\
+ mov r0, r8\n\
+ strh r0, [r2]\n\
+ cmp r4, r7\n\
+ bls _080A9514\n\
+ subs r0, r4, r7\n\
+ lsls r0, 16\n\
+ lsrs r4, r0, 16\n\
+ strh r7, [r2, 0x2]\n\
+_080A94E6:\n\
+ adds r0, r1, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r1, r0, 24\n\
+ ldrb r2, [r5, 0x4]\n\
+ cmp r1, r2\n\
+ bcc _080A94CA\n\
+_080A94F2:\n\
+ cmp r4, 0\n\
+ beq _080A9516\n\
+ b _080A9510\n\
+ .align 2, 0\n\
+_080A94F8: .4byte gBagPockets\n\
+_080A94FC: .4byte 0x000003e7\n\
+_080A9500:\n\
+ strh r0, [r3, 0x2]\n\
+ ldr r0, _080A950C @ =gBagPockets\n\
+ lsls r1, r6, 3\n\
+ adds r1, r0\n\
+ b _080A951A\n\
+ .align 2, 0\n\
+_080A950C: .4byte gBagPockets\n\
+_080A9510:\n\
+ movs r0, 0\n\
+ b _080A9528\n\
+_080A9514:\n\
+ strh r4, [r2, 0x2]\n\
+_080A9516:\n\
+ mov r6, r9\n\
+ adds r1, r3, r6\n\
+_080A951A:\n\
+ ldr r0, [r1]\n\
+ ldrb r2, [r1, 0x4]\n\
+ lsls r2, 2\n\
+ mov r1, sp\n\
+ bl memcpy\n\
+ movs r0, 0x1\n\
+_080A9528:\n\
+ add sp, 0x100\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\n");
+}
+#endif
+
+bool8 RemoveBagItem(u16 itemId, u16 count)
+{
+ u8 i;
+ u8 pocket;
+ u16 totalQuantity = 0;
+
+ if (ItemId_GetPocket(itemId) == 0 || itemId == 0)
+ return FALSE;
+ pocket = ItemId_GetPocket(itemId) - 1;
+
+ for (i = 0; i < gBagPockets[pocket].capacity; i++)
+ {
+ if (gBagPockets[pocket].itemSlots[i].itemId == itemId)
+ totalQuantity += gBagPockets[pocket].itemSlots[i].quantity;
+ }
+ if (totalQuantity < count)
+ return FALSE; //We don't have enough of the item
+
+ if (gBagPockets[pocket].capacity > gUnknown_02038560
+ && gBagPockets[pocket].itemSlots[gUnknown_02038560].itemId == itemId)
+ {
+ if (gBagPockets[pocket].itemSlots[gUnknown_02038560].quantity >= count)
+ {
+ gBagPockets[pocket].itemSlots[gUnknown_02038560].quantity -= count;
+ count = 0;
+ }
+ else
+ {
+ count -= gBagPockets[pocket].itemSlots[gUnknown_02038560].quantity;
+ gBagPockets[pocket].itemSlots[gUnknown_02038560].quantity = 0;
+ }
+ if (gBagPockets[pocket].itemSlots[gUnknown_02038560].quantity == 0)
+ gBagPockets[pocket].itemSlots[gUnknown_02038560].itemId = 0;
+ if (count == 0)
+ return TRUE;
+ }
+
+ for (i = 0; i < gBagPockets[pocket].capacity; i++)
+ {
+ if (gBagPockets[pocket].itemSlots[i].itemId == itemId)
+ {
+ if (gBagPockets[pocket].itemSlots[i].quantity >= count)
+ {
+ gBagPockets[pocket].itemSlots[i].quantity -= count;
+ count = 0;
+ }
+ else
+ {
+ count -= gBagPockets[pocket].itemSlots[i].quantity;
+ gBagPockets[pocket].itemSlots[i].quantity = 0;
+ }
+ if (gBagPockets[pocket].itemSlots[i].quantity == 0)
+ gBagPockets[pocket].itemSlots[i].itemId = 0;
+ if (count == 0)
+ return TRUE;
+ }
+ }
+ return TRUE;
+}
+
+u8 GetPocketByItemId(u16 itemId)
+{
+ return ItemId_GetPocket(itemId);
+}
+
+void ClearItemSlots(struct ItemSlot *itemSlots, u8 b)
+{
+ u16 i;
+
+ for (i = 0; i < b; i++)
+ {
+ itemSlots[i].itemId = 0;
+ itemSlots[i].quantity = 0;
+ }
+}
+
+static s32 FindFreePCItemSlot(void)
+{
+ s8 i;
+
+ for (i = 0; i < 50; i++)
+ {
+ if (gSaveBlock1.pcItems[i].itemId == 0)
+ return i;
+ }
+ return -1;
+}
+
+u8 CountUsedPCItemSlots(void)
+{
+ u8 usedSlots = 0;
+ u8 i;
+
+ for (i = 0; i < 50; i++)
+ {
+ if (gSaveBlock1.pcItems[i].itemId != 0)
+ usedSlots++;
+ }
+ return usedSlots;
+}
+
+bool8 CheckPCHasItem(u16 itemId, u16 count)
+{
+ u8 i;
+
+ for (i = 0; i < 50; i++)
+ {
+ if (gSaveBlock1.pcItems[i].itemId == itemId && gSaveBlock1.pcItems[i].quantity >= count)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 AddPCItem(u16 itemId, u16 count)
+{
+ u8 i;
+ s8 freeSlot;
+ struct ItemSlot newItems[50];
+
+ //Copy PC items
+ memcpy(newItems, gSaveBlock1.pcItems, sizeof(newItems));
+
+ //Use any item slots that already contain this item
+ for (i = 0; i < 50; i++)
+ {
+ if (newItems[i].itemId == itemId)
+ {
+ if (newItems[i].quantity + count <= 999)
+ {
+ newItems[i].quantity += count;
+ memcpy(gSaveBlock1.pcItems, newItems, sizeof(gSaveBlock1.pcItems));
+ return TRUE;
+ }
+ count += newItems[i].quantity - 999;
+ newItems[i].quantity = 999;
+ if (count == 0)
+ {
+ memcpy(gSaveBlock1.pcItems, newItems, sizeof(gSaveBlock1.pcItems));
+ return TRUE;
+ }
+ }
+ }
+
+ //Put any remaining items into a new item slot.
+ if (count > 0)
+ {
+ freeSlot = FindFreePCItemSlot();
+ if (freeSlot == -1)
+ return FALSE;
+ newItems[freeSlot].itemId = itemId;
+ newItems[freeSlot].quantity = count;
+ }
+
+ //Copy items back to the PC
+ memcpy(gSaveBlock1.pcItems, newItems, sizeof(gSaveBlock1.pcItems));
+ return TRUE;
+}
+
+void RemovePCItem(u8 index, u16 count)
+{
+ gSaveBlock1.pcItems[index].quantity -= count;
+ if (gSaveBlock1.pcItems[index].quantity == 0)
+ {
+ gSaveBlock1.pcItems[index].itemId = 0;
+ CompactPCItems();
+ }
+}
+
+static void CompactPCItems(void)
+{
+ u16 i;
+ u16 j;
+
+ for (i = 0; i < 49; i++)
+ {
+ for (j = i + 1; j <= 49; j++)
+ {
+ if (gSaveBlock1.pcItems[i].itemId == 0)
+ {
+ struct ItemSlot temp = gSaveBlock1.pcItems[i];
+ gSaveBlock1.pcItems[i] = gSaveBlock1.pcItems[j];
+ gSaveBlock1.pcItems[j] = temp;
+ }
+ }
+ }
+}
+
+void SwapRegisteredBike(void)
+{
+ switch (gSaveBlock1.registeredItem)
+ {
+ case 0x103:
+ gSaveBlock1.registeredItem = 0x110;
+ break;
+ case 0x110:
+ gSaveBlock1.registeredItem = 0x103;
+ break;
+ }
+}
+
+static u16 SanitizeItemId(u16 itemId)
+{
+ if (itemId > 0x15C)
+ return 0;
+ else
+ return itemId;
+}
+
+const struct Item *ItemId_GetItem(u16 itemId)
+{
+ return &gItems[SanitizeItemId(itemId)];
+}
+
+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;
+}
+
+bool32 ItemId_CopyDescription(u8 *a, u32 itemId, u32 c)
+{
+ u32 r5 = c + 1;
+ const u8 *description = gItems[SanitizeItemId(itemId)].description;
+ u8 *str = a;
+
+ for (;;)
+ {
+ if (*description == 0xFF || *description == 0xFE)
+ {
+ r5--;
+ if (r5 == 0)
+ {
+ *str = 0xFF;
+ return TRUE;
+ }
+ if (*description == 0xFF)
+ return FALSE;
+ str = a;
+ description++;
+ }
+ else
+ *(str++) = *(description++);
+ }
+}
+
+u8 ItemId_GetImportance(u16 itemId)
+{
+ return gItems[SanitizeItemId(itemId)].importance;
+}
+
+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/field/item_menu.c b/src/field/item_menu.c
new file mode 100644
index 000000000..c508bcacf
--- /dev/null
+++ b/src/field/item_menu.c
@@ -0,0 +1,4575 @@
+#include "global.h"
+#include "berry.h"
+#include "berry_tag_screen.h"
+#include "data2.h"
+#include "decompress.h"
+#include "field_effect.h"
+#include "field_map_obj_helpers.h"
+#include "field_player_avatar.h"
+#include "graphics.h"
+#include "item.h"
+#include "items.h"
+#include "item_menu.h"
+#include "item_use.h"
+#include "link.h"
+#include "mail_data.h"
+#include "main.h"
+#include "map_name_popup.h"
+#include "menu.h"
+#include "menu_cursor.h"
+#include "menu_helpers.h"
+#include "money.h"
+#include "palette.h"
+#include "party_menu.h"
+#include "player_pc.h"
+#include "pokemon_menu.h"
+#include "overworld.h"
+#include "script.h"
+#include "songs.h"
+#include "sound.h"
+#include "sprite.h"
+#include "strings.h"
+#include "strings2.h"
+#include "string_util.h"
+#include "task.h"
+#include "text.h"
+#include "unknown_task.h"
+
+// External stuff
+extern u8 ewram[];
+extern void gpu_pal_allocator_reset__manage_upper_four(void);
+extern void sub_80F9020(void);
+extern void sub_80F9988();
+extern void sub_809D104(u16 *, u16, u16, const u8 *, u16, u16, u16, u16);
+extern void PauseVerticalScrollIndicator();
+extern u8 sub_80F9284(void);
+extern void sub_808B5B4();
+extern u8 sub_80F92F4();
+extern void sub_80C9C7C(u8);
+extern void pal_fill_black(void);
+extern bool8 sub_807D770(void);
+extern u8 sub_80F931C();
+extern void sub_808A3F8(u8);
+extern void sub_80B3050(void);
+extern void sub_80546B8(u8);
+extern void sub_804E990(u8);
+extern void sub_802E424(u8);
+extern void sub_8064E2C(void);
+
+struct UnknownStruct2
+{
+ u8 unk0;
+ u8 textLine;
+ u8 unk2;
+};
+
+struct UnknownStruct3
+{
+ u8 unk0;
+ u8 unk1;
+ u8 unk2;
+};
+
+struct UnknownStruct4
+{
+ u8 unk0;
+ u8 unk1;
+ u16 unk2;
+ const u8 *unk4;
+ TaskFunc unk8;
+};
+
+struct UnknownStruct5
+{
+ u8 unk0;
+ u8 unk1;
+ u8 unk2;
+ u8 unk3;
+};
+
+struct UnknownStruct6
+{
+ u8 unk0;
+};
+
+enum
+{
+ BAG_POCKET_ITEMS, // 0
+ BAG_POCKET_POKE_BALLS, // 1
+ BAG_POCKET_TMs_HMs, // 2
+ BAG_POCKET_BERRIES, // 3
+ BAG_POCKET_KEY_ITEMS, // 4
+};
+
+enum
+{
+ RETURN_TO_FIELD_0,
+ RETURN_TO_BATTLE,
+ RETURN_TO_PKMN_LIST,
+ RETURN_TO_SHOP,
+ RETURN_TO_FIELD_4,
+ RETURN_TO_FIELD_5,
+ RETURN_TO_PC,
+ RETURN_TO_WALLY_BATTLE,
+};
+
+enum
+{
+ ITEM_ACTION_USE_0, // 0
+ ITEM_ACTION_TOSS, // 1
+ ITEM_ACTION_CANCEL_2, // 2
+ ITEM_ACTION_REGISTER, // 3
+ ITEM_ACTION_USE_4, // 4
+ ITEM_ACTION_CANCEL_5, // 5
+ ITEM_ACTION_GIVE, // 6
+ ITEM_ACTION_CHECK_TAG, // 7
+ ITEM_ACTION_NONE, // 8
+ ITEM_ACTION_CONFIRM, // 9
+};
+
+// ewram
+EWRAM_DATA static struct UnknownStruct2 gUnknown_0203853C = {0};
+EWRAM_DATA static struct UnknownStruct3 gUnknown_02038540 = {0};
+EWRAM_DATA static struct UnknownStruct4 gUnknown_02038544 = {0};
+EWRAM_DATA static struct UnknownStruct5 gUnknown_02038550 = {0};
+EWRAM_DATA static struct UnknownStruct6 gUnknown_02038554 = {0}; // There are 3 bytes of padding after this, so I assume it's a struct
+EWRAM_DATA static u8 gUnknown_02038558 = 0;
+EWRAM_DATA static s8 sCurrentBagPocket = 0;
+EWRAM_DATA static u8 gUnknown_0203855A = 0;
+EWRAM_DATA static s8 gUnknown_0203855B = 0;
+EWRAM_DATA static s8 gUnknown_0203855C = 0;
+EWRAM_DATA u16 gScriptItemId = 0;
+EWRAM_DATA u8 gUnknown_02038560 = 0;
+EWRAM_DATA u8 gUnknown_02038561 = 0;
+EWRAM_DATA static u8 gUnknown_02038562 = 0;
+EWRAM_DATA static u8 gUnknown_02038563 = 0;
+EWRAM_DATA static u8 gUnknown_02038564 = 0;
+EWRAM_DATA static u8 sPokeballSpriteId ALIGNED(4) = 0; // HACK: why is there a space before this variable?
+
+// bss
+static u8 sPopupMenuSelection;
+static u8 sReturnLocation;
+static const u8 *sPopupMenuActionList;
+
+// common
+void (*gFieldItemUseCallback)(u8) = NULL;
+extern u16 gUnknown_030041B4;
+extern struct PocketScrollState gBagPocketScrollStates[];
+extern struct ItemSlot *gCurrentBagPocketItemSlots; // selected pocket item slots
+extern const u8 Event_NoRegisteredItem[];
+
+#define ewramBerryPic (ewram + 0)
+#define ewramBerryPicTemp (ewram + 0x1000)
+#define ewramSavedItemsPocket ((struct ItemSlot *)(ewram + 0x1E000)) // saved items pocket (for Wally battle)
+#define ewramSavedPokeballsPocket ((struct ItemSlot *)(ewram + 0x1F000)) // saved Pokeballs pocket (for Wally battle)
+#define ewramBagSetupStep (ewram[0x1FFFF])
+
+extern const struct CompressedSpriteSheet sMaleBagSpriteSheet;
+extern const struct CompressedSpriteSheet sFemaleBagSpriteSheet;
+extern const struct CompressedSpritePalette sBagSpritePalette;
+
+const struct BagPocket gBagPockets[NUM_BAG_POCKETS] =
+{
+ {gSaveBlock1.bagPocket_Items, 20},
+ {gSaveBlock1.bagPocket_PokeBalls, 16},
+ {gSaveBlock1.bagPocket_TMHM, 64},
+ {gSaveBlock1.bagPocket_Berries, 46},
+ {gSaveBlock1.bagPocket_KeyItems, 20},
+};
+
+static void HandlePopupMenuAction_UseOnField(u8);
+static void HandlePopupMenuAction_Toss(u8);
+static void sub_80A5F80(u8);
+static void HandlePopupMenuAction_Register(u8);
+static void HandlePopupMenuAction_UseInBattle(u8);
+static void sub_80A7124(u8);
+static void HandlePopupMenuAction_Give(u8);
+static void HandlePopupMenuAction_CheckTag(u8);
+static void HandlePopupMenuAction_Confirm(u8);
+
+static const struct MenuAction2 sItemPopupMenuActions[] =
+{
+ {OtherText_Use, HandlePopupMenuAction_UseOnField},
+ {OtherText_Toss, HandlePopupMenuAction_Toss},
+ {gOtherText_CancelNoTerminator, sub_80A5F80},
+ {OtherText_Register, HandlePopupMenuAction_Register},
+ {OtherText_Use, HandlePopupMenuAction_UseInBattle},
+ {gOtherText_CancelNoTerminator, sub_80A7124},
+ {OtherText_Give2, HandlePopupMenuAction_Give},
+ {OtherText_CheckTag, HandlePopupMenuAction_CheckTag},
+ {gOtherText_CancelWithTerminator, NULL},
+ {OtherText_Confirm, HandlePopupMenuAction_Confirm},
+};
+
+static const u8 sItemPopupMenuChoicesTable[][6] =
+{
+ [BAG_POCKET_ITEMS] =
+ {
+ ITEM_ACTION_USE_0,
+ ITEM_ACTION_TOSS,
+ ITEM_ACTION_GIVE,
+ ITEM_ACTION_CANCEL_2,
+ },
+
+ [BAG_POCKET_POKE_BALLS] =
+ {
+ ITEM_ACTION_GIVE,
+ ITEM_ACTION_TOSS,
+ ITEM_ACTION_NONE,
+ ITEM_ACTION_CANCEL_2,
+ },
+
+ [BAG_POCKET_TMs_HMs] =
+ {
+ ITEM_ACTION_USE_0,
+ ITEM_ACTION_NONE,
+ ITEM_ACTION_GIVE,
+ ITEM_ACTION_CANCEL_2,
+ },
+
+ [BAG_POCKET_BERRIES] =
+ {
+ ITEM_ACTION_CHECK_TAG,
+ ITEM_ACTION_USE_0,
+ ITEM_ACTION_TOSS,
+ ITEM_ACTION_NONE,
+ ITEM_ACTION_GIVE,
+ ITEM_ACTION_CANCEL_2
+ },
+
+ [BAG_POCKET_KEY_ITEMS] =
+ {
+ ITEM_ACTION_USE_0,
+ ITEM_ACTION_NONE,
+ ITEM_ACTION_REGISTER,
+ ITEM_ACTION_CANCEL_2,
+ },
+};
+
+const u8 gUnknown_083C16AE[][2] =
+{
+ {6, 2},
+ {6, 2},
+ {6, 2},
+ {6, 2},
+ {2, 0},
+};
+
+const u8 gUnknown_083C16B8[] = {7, 9, 8, 2};
+
+static void OnItemSelect_Field05(u8);
+static void OnBagClose_Field0(u8);
+static void OnBagClose_PkmnList(u8);
+static void OnItemSelect_PkmnList(u8);
+static void OnBagClose_Shop(u8);
+static void OnItemSelect_Shop(u8);
+static void OnBagClose_Field4(u8);
+static void OnItemSelect_Field4(u8);
+static void OnBagClose_Field5(u8);
+static void OnBagClose_PC(u8);
+static void OnItemSelect_PC(u8);
+static void OnItemSelect_Battle(u8);
+static void OnBagClose_Battle(u8);
+
+static const struct {TaskFunc onItemSelect; TaskFunc onBagClose;} gUnknown_083C16BC[] =
+{
+ [RETURN_TO_FIELD_0] = {OnItemSelect_Field05, OnBagClose_Field0},
+ [RETURN_TO_BATTLE] = {OnItemSelect_Battle, OnBagClose_Battle},
+ [RETURN_TO_PKMN_LIST] = {OnItemSelect_PkmnList, OnBagClose_PkmnList},
+ [RETURN_TO_SHOP] = {OnItemSelect_Shop, OnBagClose_Shop},
+ [RETURN_TO_FIELD_4] = {OnItemSelect_Field4, OnBagClose_Field4},
+ [RETURN_TO_FIELD_5] = {OnItemSelect_Field05, OnBagClose_Field5},
+ [RETURN_TO_PC] = {OnItemSelect_PC, OnBagClose_PC},
+};
+
+static void sub_80A5E60(u8);
+static void sub_80A5E90(u8);
+
+static const struct YesNoFuncTable gUnknown_083C16F4 = {sub_80A5E60, sub_80A5E90};
+
+static void sub_80A65AC(u8);
+static void sub_80A6618(u8);
+
+const struct YesNoFuncTable gUnknown_083C16FC = {sub_80A65AC, sub_80A6618};
+
+void sub_80A34E8(void);
+static bool8 LoadBagGraphicsMultistep(void);
+static void sub_80A362C(void);
+static void sub_80A3740(void);
+static void sub_80A396C(u16 *, u8, u8, u8);
+static void sub_80A39B8(u16 *, u8);
+static void sub_80A39E4(u16 *, u8, u8, s8);
+static void DrawPocketIndicatorDots(u16 *, u8);
+static void SortItemSlots(struct BagPocket);
+static void UpdateAllBagPockets(void);
+static void sub_80A3D24(u8);
+static void sub_80A3D40(void);
+static void RemoveSelectIconFromRegisteredItem(void);
+static void sub_80A48E8(u16, int, int);
+static void ItemListMenu_InitDescription(s16);
+static void ItemListMenu_ChangeDescription(s16, int);
+static void sub_80A4F68(u8);
+static void sub_80A50C8(u8);
+static void sub_80A5AE4(u8);
+static void sub_80A5BF8(u8);
+static void Task_CallItemUseOnFieldCallback(u8);
+static void sub_80A6444(u8);
+static void sub_80A648C(u8);
+static void Task_BuyHowManyDialogueHandleInput(u8);
+static void BuyMenuPrintItemQuantityAndPrice(u8);
+static void BuyMenuDisplayMessage(u16, u16);
+static void sub_80A683C(void);
+static void sub_80A6870(u16, u8);
+static void sub_80A699C(void);
+static void sub_80A7230(u8);
+static void ItemListMenu_InitMenu(void);
+static void sub_80A73C0(void);
+static void sub_80A73F0(void);
+static void sub_80A73FC(void);
+static void sub_80A740C(void);
+static void sub_80A7420(void);
+static void sub_80A751C(void);
+static void sub_80A7528(u8);
+static void sub_80A7590(void);
+static void sub_80A75E4(void);
+static void sub_80A7630(void);
+static void sub_80A763C(void);
+static void sub_80A76A0(void);
+static void sub_80A770C(void);
+static void DisplayCannotUseItemMessage(int, const u8 *, TaskFunc, int);
+static void sub_80A7768(void);
+static void sub_80A7828(void);
+static void sub_80A7834(int, int);
+static bool32 sub_80A78A0(void);
+static void sub_80A78B8(void);
+static bool32 sub_80A78C4(void);
+static void sub_80A78E8(void);
+static int sub_80A78F4(void);
+static void sub_80A7918(void);
+static int sub_80A7924(void);
+static int sub_80A7958(void);
+static void sub_80A7970(void);
+static void sub_80A797C(void);
+static int sub_80A7988(void);
+static void sub_80A79B4(struct Sprite *);
+static void sub_80A79EC(struct Sprite *);
+static void sub_80A7A94(struct Sprite *);
+static void sub_80A7AE4(struct Sprite *);
+static void CreateBagSprite(void);
+static void sub_80A7B6C(struct Sprite *);
+static void CreateBagPokeballSprite(u8);
+static void sub_80A7C64(void);
+
+static void sub_80A3118(void)
+{
+ AnimateSprites();
+ BuildOamBuffer();
+ RunTasks();
+ sub_80A740C();
+ UpdatePaletteFade();
+}
+
+static void sub_80A3134(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+
+ {
+ const void *src = gBGTilemapBuffers[1];
+ void *dst = (void *)(VRAM + 0x2000);
+
+ DmaCopy16(3, src, dst, 0x800);
+ }
+
+ {
+ const void *src = gBGTilemapBuffers[2];
+ void *dst = (void *)(VRAM + 0x6000);
+
+ DmaCopy16(3, src, dst, 0x800);
+ }
+}
+
+static bool8 SetupBagMultistep(void)
+{
+ u32 index;
+ u16 savedIme;
+
+ switch (gMain.state)
+ {
+ case 0:
+ sub_80F9438();
+ sub_80A34E8();
+ gMain.state++;
+ break;
+ case 1:
+ remove_some_task();
+ gMain.state++;
+ break;
+ case 2:
+ gpu_pal_allocator_reset__manage_upper_four();
+ gMain.state++;
+ break;
+ case 3:
+ sub_80F9020();
+ ewramBagSetupStep = 0;
+ gMain.state++;
+ break;
+ case 4:
+ ResetPaletteFade();
+ gPaletteFade.bufferTransferDisabled = TRUE;
+ gMain.state++;
+ break;
+ case 5:
+ ResetSpriteData();
+ gMain.state++;
+ break;
+ case 6:
+ if (LoadBagGraphicsMultistep() == FALSE)
+ break;
+ gMain.state++;
+ break;
+ case 7:
+ SetUpWindowConfig(&gWindowConfig_81E6DFC);
+ gMain.state++;
+ break;
+ case 8:
+ MultistepInitMenuWindowBegin(&gWindowConfig_81E6DFC);
+ gMain.state++;
+ break;
+ case 9:
+ if (!MultistepInitMenuWindowContinue())
+ break;
+ gMain.state++;
+ break;
+ case 10:
+ sub_80F944C();
+ LoadScrollIndicatorPalette();
+ CreateVerticalScrollIndicators(0, 172, 12);
+ CreateVerticalScrollIndicators(1, 172, 148);
+ CreateVerticalScrollIndicators(2, 28, 88);
+ CreateVerticalScrollIndicators(3, 100, 88);
+ sub_80F9988(0, 2);
+ sub_80F9988(1, 2);
+ sub_80F9988(2, 2);
+ sub_80F9988(3, 2);
+ if (sReturnLocation == RETURN_TO_FIELD_4 || sReturnLocation == RETURN_TO_FIELD_5)
+ {
+ sub_80F979C(2, 1);
+ sub_80F979C(3, 1);
+ }
+ gMain.state++;
+ break;
+ case 11:
+ gUnknown_0203855A = 16;
+ sub_80A39B8(gBGTilemapBuffers[2], sCurrentBagPocket + 1);
+ DrawPocketIndicatorDots(gBGTilemapBuffers[2], sCurrentBagPocket);
+ UpdateAllBagPockets();
+ SortItemSlots(gBagPockets[2]);
+ SortItemSlots(gBagPockets[3]);
+ sub_80A3D40();
+ gCurrentBagPocketItemSlots = gBagPockets[sCurrentBagPocket].itemSlots;
+ sub_80A362C();
+ gMain.state++;
+ break;
+ case 12:
+ sub_80A48E8(0xFFFF, 0, 7);
+ index = gBagPocketScrollStates[sCurrentBagPocket].scrollTop + gBagPocketScrollStates[sCurrentBagPocket].cursorPos;
+ ItemListMenu_InitDescription(gCurrentBagPocketItemSlots[index].itemId);
+ ItemListMenu_InitMenu();
+ gUnknown_0203855B = sCurrentBagPocket + 1;
+ gUnknown_0203855C = 0;
+ gMain.state++;
+ break;
+ case 13:
+ CreateBagSprite();
+ CreateBagPokeballSprite(0);
+ sub_80A3740();
+ gMain.state++;
+ break;
+ case 14:
+ savedIme = REG_IME;
+ REG_IME = 0;
+ REG_IE |= INTR_FLAG_VBLANK;
+ REG_IME = savedIme;
+ REG_DISPSTAT |= DISPSTAT_VBLANK_INTR;
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, 0);
+ gPaletteFade.bufferTransferDisabled = FALSE;
+ gMain.state++;
+ break;
+ case 15:
+ if (sub_8055870() == TRUE)
+ break;
+ gMain.state++;
+ break;
+ case 16:
+ SetVBlankCallback(sub_80A3134);
+ SetMainCallback2(sub_80A3118);
+ sub_80A751C();
+ sub_80A7630();
+ sub_80A770C();
+ sub_80A7828();
+ sub_80A78B8();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool8 sub_80A34B4(void)
+{
+ while (1)
+ {
+ if (SetupBagMultistep() == TRUE)
+ {
+ sPopupMenuSelection = 0;
+ ResetTasks();
+ return TRUE;
+ }
+ if (sub_80F9344() == TRUE)
+ break;
+ }
+ return FALSE;
+}
+
+
+void sub_80A34E8(void)
+{
+ sub_80F9368();
+ REG_BG2CNT = BGCNT_PRIORITY(2) | BGCNT_CHARBASE(1) | BGCNT_SCREENBASE(12) | BGCNT_16COLOR | BGCNT_TXT256x256;
+ REG_BG1CNT = BGCNT_PRIORITY(1) | BGCNT_CHARBASE(1) | BGCNT_SCREENBASE(4) | BGCNT_16COLOR | BGCNT_TXT256x256;
+ REG_DISPCNT = DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON | DISPCNT_BG1_ON | DISPCNT_BG2_ON | DISPCNT_OBJ_ON;
+ REG_BLDCNT = 0;
+}
+
+static bool8 LoadBagGraphicsMultistep(void)
+{
+ switch (ewramBagSetupStep)
+ {
+ case 0:
+ LZDecompressVram(gBagScreen_Gfx, (void *)(VRAM + 0x4000));
+ ewramBagSetupStep++;
+ break;
+ case 1:
+ CpuCopy16(gUnknown_08E77004, gBGTilemapBuffers[2], 0x800);
+ ewramBagSetupStep++;
+ break;
+ case 2:
+ if (gSaveBlock2.playerGender == MALE || sReturnLocation == RETURN_TO_WALLY_BATTLE)
+ LoadCompressedPalette(gBagScreenMale_Pal, 0, 64);
+ else
+ LoadCompressedPalette(gBagScreenFemale_Pal, 0, 64);
+ ewramBagSetupStep++;
+ break;
+ case 3:
+ if (gSaveBlock2.playerGender == MALE || sReturnLocation == RETURN_TO_WALLY_BATTLE)
+ LoadCompressedObjectPic(&sMaleBagSpriteSheet);
+ else
+ LoadCompressedObjectPic(&sFemaleBagSpriteSheet);
+ ewramBagSetupStep++;
+ break;
+ case 4:
+ LoadCompressedObjectPalette(&sBagSpritePalette);
+ ewramBagSetupStep = 0;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void sub_80A362C(void)
+{
+ u8 i;
+
+ for (i = 0; i < 5; i++)
+ {
+ u8 r3;
+
+ if (sReturnLocation == RETURN_TO_FIELD_5)
+ r3 = gBagPocketScrollStates[i].numSlots - 1;
+ else
+ r3 = gBagPocketScrollStates[i].numSlots;
+
+ if (gBagPocketScrollStates[i].scrollTop != 0)
+ {
+ if (gBagPocketScrollStates[i].scrollTop + gBagPocketScrollStates[i].cursorMax > r3)
+ gBagPocketScrollStates[i].scrollTop = r3 - gBagPocketScrollStates[i].cursorMax;
+ }
+ else
+ {
+ if (gBagPocketScrollStates[i].cursorPos > r3)
+ gBagPocketScrollStates[i].cursorPos = r3;
+ }
+ }
+}
+
+void ResetBagScrollPositions(void)
+{
+ u16 i;
+
+ for (i = 0; i < NUM_BAG_POCKETS; i++)
+ {
+ gBagPocketScrollStates[i].cursorPos = 0;
+ gBagPocketScrollStates[i].scrollTop = 0;
+ gBagPocketScrollStates[i].numSlots = 0;
+ gBagPocketScrollStates[i].cursorMax = 0;
+ }
+ sCurrentBagPocket = 0;
+}
+
+static void sub_80A36B8(u16 *a, u8 b, u8 c, u8 d, u8 e)
+{
+ u16 i;
+ u16 j;
+
+ for (i = c; i <= c + e; i++)
+ {
+ for (j = b; j <= b + d; j++)
+ {
+ u32 index = j + i * 32;
+
+ a[index] = 0;
+ }
+ }
+}
+
+void ClearBag(void)
+{
+ u16 i;
+
+ for (i = 0; i < NUM_BAG_POCKETS; i++)
+ ClearItemSlots(gBagPockets[i].itemSlots, gBagPockets[i].capacity);
+ ResetBagScrollPositions();
+}
+
+static void sub_80A3740(void)
+{
+ const u16 colors[2] = {RGB(14, 15, 16), RGB_WHITE};
+
+ LoadPalette(&colors[1], 0xD1, sizeof(colors[1]));
+ LoadPalette(&colors[0], 0xD8, sizeof(colors[0]));
+}
+
+static void sub_80A3770(void)
+{
+ if (sReturnLocation == RETURN_TO_FIELD_0)
+ {
+ sPopupMenuActionList = sItemPopupMenuChoicesTable[sCurrentBagPocket];
+ if (sCurrentBagPocket != BAG_POCKET_BERRIES)
+ gUnknown_02038564 = 4;
+ else
+ gUnknown_02038564 = 6;
+ }
+}
+
+static void sub_80A37C0(u8 taskId)
+{
+ gTasks[taskId].func = sub_80A50C8;
+ StartVerticalScrollIndicators(0);
+ StartVerticalScrollIndicators(1);
+ StartVerticalScrollIndicators(2);
+ StartVerticalScrollIndicators(3);
+}
+
+static void sub_80A37F8(u8 taskId)
+{
+ u8 r5 = gUnknown_0203855A;
+
+ if (r5 < 16)
+ {
+ gUnknown_0203855A++;
+ sub_80A396C(gBGTilemapBuffers[2], r5, gUnknown_0203855A, 0x4F);
+ sub_80A39E4(gBGTilemapBuffers[2], sCurrentBagPocket + 1, gUnknown_0203855A / 2, gTasks[taskId].data[5]);
+ gUnknown_02038558 = 1;
+ sub_80A48E8(taskId, r5 / 2, gUnknown_0203855A / 2 - 1);
+ gUnknown_02038558 = 0;
+ return;
+ }
+
+ if (gLinkOpen == TRUE)
+ {
+ u32 index = gBagPocketScrollStates[sCurrentBagPocket].scrollTop + gBagPocketScrollStates[sCurrentBagPocket].cursorPos;
+
+ ItemListMenu_ChangeDescription(gCurrentBagPocketItemSlots[index].itemId, gUnknown_02038562);
+ gUnknown_02038562++;
+ }
+ else
+ {
+ while (gUnknown_02038562 < 3)
+ {
+ u32 index = gBagPocketScrollStates[sCurrentBagPocket].scrollTop + gBagPocketScrollStates[sCurrentBagPocket].cursorPos;
+
+ ItemListMenu_ChangeDescription(gCurrentBagPocketItemSlots[index].itemId, gUnknown_02038562);
+ gUnknown_02038562++;
+ }
+ }
+ if (gUnknown_02038562 == 3)
+ {
+ gUnknown_0203855A = 16;
+ gUnknown_0203855B = sCurrentBagPocket + 1;
+ sub_80A37C0(FindTaskIdByFunc(sub_80A4F68));
+ DestroyTask(taskId);
+ ItemListMenu_InitMenu();
+ sub_80F979C(2, 0);
+ sub_80F979C(3, 0);
+ }
+}
+
+static void sub_80A3954(u16 *a)
+{
+ CpuCopy16(gUnknown_08E77004, a, 0x800);
+}
+
+static void sub_80A396C(u16 *a, u8 b, u8 c, u8 d)
+{
+ u16 *dst = a + 14 + (b + 2) * 32;
+ u16 i;
+
+ while (c > b++)
+ {
+ for (i = 0; i < 15; i++)
+ dst[i] = d;
+ dst += 32;
+ }
+}
+
+static void sub_80A39B8(u16 *a, u8 b)
+{
+ u8 var = b * 2;
+
+ sub_809D104(a, 4, 10, gUnknown_08E96EC8, 0, var, 8, 2);
+}
+
+static void sub_80A39E4(u16 *a, u8 b, u8 c, s8 d)
+{
+ u16 r2 = b * 2;
+ u16 r7;
+
+ if (d == -1)
+ {
+ r7 = (b + 1) * 2;
+ if (b == 5)
+ r7 = 2;
+
+ sub_809D104(a, 4, 10, gUnknown_08E96EC8, 8 - c, r2, c, 2);
+ sub_809D104(a, c + 4, 10, gUnknown_08E96EC8, 0, r7, 8 - c, 2);
+ }
+ else if (d == 1)
+ {
+ r7 = (b - 1) * 2;
+ if (b == 1)
+ r7 = 10;
+
+ sub_809D104(a, 4, 10, gUnknown_08E96EC8, c, r7, 8 - c, 2);
+ sub_809D104(a, 12 - c, 10, gUnknown_08E96EC8, 0, r2, c, 2);
+ }
+}
+
+// Draws dots under the bag sprite, showing which pocket is selected
+static void DrawPocketIndicatorDots(u16 *tileMapBuffer, u8 selectedPocket)
+{
+ u8 i;
+
+ for (i = 0; i < NUM_BAG_POCKETS; i++)
+ {
+ if (i == selectedPocket)
+ tileMapBuffer[0x125 + i] = 0x107D;
+ else
+ tileMapBuffer[0x125 + i] = 0x107C;
+ }
+}
+
+static void ChangePocket(u16 *tileMapBuffer, s8 delta)
+{
+ u8 taskId;
+
+ sCurrentBagPocket += delta;
+ // Wrap around
+ if (sCurrentBagPocket >= NUM_BAG_POCKETS)
+ sCurrentBagPocket = 0;
+ if (sCurrentBagPocket < 0)
+ sCurrentBagPocket = NUM_BAG_POCKETS - 1;
+
+ sub_80A76A0();
+ sub_80A7590();
+ gCurrentBagPocketItemSlots = gBagPockets[sCurrentBagPocket].itemSlots;
+ sub_80A3D24(sCurrentBagPocket);
+ gUnknown_0203855A = 0;
+ sub_80A3954(tileMapBuffer);
+ sub_80A396C(tileMapBuffer, 0, 16, 3);
+ sub_80A39B8(tileMapBuffer, 0);
+ gUnknown_0203855B = 6;
+ gUnknown_02038562 = 0;
+ taskId = FindTaskIdByFunc(sub_80A37F8);
+ if (taskId == 0xFF)
+ taskId = CreateTask(sub_80A37F8, 8);
+ gTasks[taskId].data[5] = delta;
+}
+
+static void SwapItemSlots(struct ItemSlot *a, struct ItemSlot *b)
+{
+ struct ItemSlot temp = *a;
+
+ *a = *b;
+ *b = temp;
+}
+
+static void RemoveEmptyItemSlots(struct BagPocket pocket)
+{
+ u16 i;
+ u16 j;
+
+ for (i = 0; i < pocket.capacity - 1; i++)
+ {
+ for (j = i + 1; j < pocket.capacity; j++)
+ {
+ if (pocket.itemSlots[i].quantity == 0)
+ SwapItemSlots(&pocket.itemSlots[i], &pocket.itemSlots[j]);
+ }
+ }
+}
+
+static void SortItemSlots(struct BagPocket pocket)
+{
+ u16 i;
+ u16 j;
+
+ for (i = 0; i < pocket.capacity; i++)
+ {
+ for (j = i + 1; j < pocket.capacity; j++)
+ {
+ if (pocket.itemSlots[i].quantity != 0 && pocket.itemSlots[j].quantity != 0
+ && pocket.itemSlots[i].itemId > pocket.itemSlots[j].itemId)
+ SwapItemSlots(&pocket.itemSlots[i], &pocket.itemSlots[j]);
+ }
+ }
+}
+
+static void UpdateBagPocket(u8 pocketNum)
+{
+ u16 i;
+
+ gBagPocketScrollStates[pocketNum].numSlots = 0;
+ for (i = 0; i < gBagPockets[pocketNum].capacity; i++)
+ {
+ if (gBagPockets[pocketNum].itemSlots[i].quantity != 0)
+ gBagPocketScrollStates[pocketNum].numSlots++;
+ }
+ RemoveEmptyItemSlots(gBagPockets[pocketNum]);
+}
+
+static void UpdateAllBagPockets(void)
+{
+ u8 i;
+
+ for (i = 0; i < NUM_BAG_POCKETS; i++)
+ UpdateBagPocket(i);
+}
+
+static void sub_80A3D24(u8 pocketNum)
+{
+ if (gBagPocketScrollStates[pocketNum].numSlots >= 7)
+ gBagPocketScrollStates[pocketNum].cursorMax = 7;
+ else
+ gBagPocketScrollStates[pocketNum].cursorMax = gBagPocketScrollStates[pocketNum].numSlots;
+}
+
+static void sub_80A3D40(void)
+{
+ u8 i;
+
+ for (i = 0; i < NUM_BAG_POCKETS; i++)
+ sub_80A3D24(i);
+}
+
+static void sub_80A3D5C(u8 taskId)
+{
+ u32 index = gBagPocketScrollStates[sCurrentBagPocket].scrollTop + gBagPocketScrollStates[sCurrentBagPocket].cursorPos;
+
+ gCurrentBagPocketItemSlots[index].quantity -= gTasks[taskId].data[1];
+ if (gCurrentBagPocketItemSlots[index].quantity == 0) // item slot will be removed if the quantity is zero
+ {
+ // Un-register the item if registered
+ if (gSaveBlock1.registeredItem == gCurrentBagPocketItemSlots[index].itemId)
+ {
+ RemoveSelectIconFromRegisteredItem();
+ gSaveBlock1.registeredItem = ITEM_NONE;
+ }
+
+ gCurrentBagPocketItemSlots[index].itemId = ITEM_NONE;
+ if (gBagPocketScrollStates[sCurrentBagPocket].scrollTop + 7 == gBagPocketScrollStates[sCurrentBagPocket].numSlots
+ && gBagPocketScrollStates[sCurrentBagPocket].scrollTop != 0)
+ gBagPocketScrollStates[sCurrentBagPocket].scrollTop--;
+ UpdateBagPocket(sCurrentBagPocket);
+ }
+ sub_80A3D24(sCurrentBagPocket);
+}
+
+void sub_80A3E0C(void)
+{
+ u32 index = gBagPocketScrollStates[sCurrentBagPocket].scrollTop + gBagPocketScrollStates[sCurrentBagPocket].cursorPos;
+
+ if (gCurrentBagPocketItemSlots[index].quantity == 0)
+ {
+ gCurrentBagPocketItemSlots[index].itemId = 0;
+ if (gBagPocketScrollStates[sCurrentBagPocket].scrollTop + 7 == gBagPocketScrollStates[sCurrentBagPocket].numSlots
+ && gBagPocketScrollStates[sCurrentBagPocket].scrollTop != 0)
+ gBagPocketScrollStates[sCurrentBagPocket].scrollTop--;
+ UpdateBagPocket(sCurrentBagPocket);
+ }
+ sub_80A3D24(sCurrentBagPocket);
+}
+
+static void nullsub_16(void)
+{
+}
+
+static void sub_80A3E70(u8 a, u8 b)
+{
+ struct ItemSlot temp = gCurrentBagPocketItemSlots[a];
+
+ gCurrentBagPocketItemSlots[a] = gCurrentBagPocketItemSlots[b];
+ gCurrentBagPocketItemSlots[b] = temp;
+}
+
+static void sub_80A3E90(u8 taskId)
+{
+ PlaySE(SE_SELECT);
+ nullsub_16();
+ sub_80A3E70(
+ gTasks[taskId].data[10] - 1,
+ gBagPocketScrollStates[sCurrentBagPocket].cursorPos + gBagPocketScrollStates[sCurrentBagPocket].scrollTop);
+ gTasks[taskId].data[10] = 0;
+ sub_80A763C();
+ sub_80A7528(0);
+ ItemListMenu_InitMenu();
+}
+
+static void sub_80A3EF4(u8 taskId)
+{
+ u8 r2;
+
+ PlaySE(SE_SELECT);
+ nullsub_16();
+ r2 = gTasks[taskId].data[10] - gBagPocketScrollStates[sCurrentBagPocket].scrollTop - 1;
+ gTasks[taskId].data[10] = 0;
+ if (r2 < 8)
+ sub_80A48E8(taskId, r2, r2);
+ sub_80A7528(0);
+}
+
+static void sub_80A3F50(u8 taskId)
+{
+ gTasks[taskId].data[10] = gBagPocketScrollStates[sCurrentBagPocket].scrollTop + gBagPocketScrollStates[sCurrentBagPocket].cursorPos + 1;
+ sub_80A48E8(taskId, gBagPocketScrollStates[sCurrentBagPocket].cursorPos, gBagPocketScrollStates[sCurrentBagPocket].cursorPos);
+ sub_80A7528(1);
+}
+
+void sub_80A3FA0(u16 *a, u8 b, u8 c, u8 d, u8 e, u16 f)
+{
+ s16 i;
+ s16 j;
+
+ for (i = c; i < c + e; i++)
+ {
+ for (j = b; j < b + d; j++)
+ {
+ u32 index = j + i * 32;
+
+ a[index] = f;
+ }
+ }
+}
+
+static void sub_80A4008(u16 *a, u8 b, u8 c, u8 d, u8 e)
+{
+ sub_80A3FA0(a, b, c, d, e, 1);
+}
+
+static void DrawSelectIcon(u32 itemPos)
+{
+ u16 *ptr1 = gBGTilemapBuffers[2] + 0x5A;
+
+ ptr1 += itemPos * 64;
+ ptr1[0] = 0x5A;
+ ptr1[1] = 0x5B;
+ ptr1[2] = 0x5C;
+ ptr1[32] = 0x6A;
+ ptr1[33] = 0x6B;
+ ptr1[34] = 0x6C;
+}
+
+static void MoveSelectIcon(u8 itemPos)
+{
+ u16 i;
+ u16 *ptr;
+
+ ptr = gBGTilemapBuffers[2] + 0x5A;
+ for (i = 0; i < 16; i++)
+ {
+ ptr[0] = 0x4F;
+ ptr[1] = 0x4F;
+ ptr[2] = 0x4F;
+ ptr += 32;
+ }
+
+ ptr = gBGTilemapBuffers[2] + 0x5A + itemPos * 64;
+ ptr[0] = 0x5A;
+ ptr[1] = 0x5B;
+ ptr[2] = 0x5C;
+ ptr[32] = 0x6A;
+ ptr[33] = 0x6B;
+ ptr[34] = 0x6C;
+}
+
+static void EraseSelectIcon(u8 itemPos)
+{
+ u16 *ptr = gBGTilemapBuffers[2] + 0x5A;
+
+ ptr += itemPos * 64;
+ ptr[0] = 0x4F;
+ ptr[1] = 0x4F;
+ ptr[2] = 0x4F;
+ ptr[32] = 0x4F;
+ ptr[33] = 0x4F;
+ ptr[34] = 0x4F;
+}
+
+static void RemoveSelectIconFromRegisteredItem(void)
+{
+ u8 i;
+
+ for (i = 0; i < 8; i++)
+ {
+ if (gBagPocketScrollStates[sCurrentBagPocket].scrollTop + i == gBagPocketScrollStates[sCurrentBagPocket].numSlots)
+ break;
+ if (gCurrentBagPocketItemSlots[gBagPocketScrollStates[sCurrentBagPocket].scrollTop + i].itemId == gSaveBlock1.registeredItem)
+ {
+ EraseSelectIcon(i);
+ break;
+ }
+ }
+}
+
+static void AddSelectIconToRegisteredItem(void)
+{
+ RemoveSelectIconFromRegisteredItem();
+ MoveSelectIcon(gBagPocketScrollStates[sCurrentBagPocket].cursorPos);
+}
+
+void sub_80A4164(u8 *dest, u16 value, enum StringConvertMode mode, u8 digits)
+{
+ *dest++ = CHAR_MULT_SIGN;
+ dest[0] = EXT_CTRL_CODE_BEGIN;
+ dest[1] = 0x14;
+ dest[2] = 6;
+ dest += 3;
+ ConvertIntToDecimalStringN(dest, value, mode, digits);
+}
+
+void sub_80A418C(u16 value, enum StringConvertMode mode, u8 c, u8 d, u8 digits)
+{
+ sub_80A4164(gStringVar1, value, mode, digits);
+ MenuPrint(gStringVar1, c, d);
+}
+
+static void sub_80A41D4(u8 taskId)
+{
+ sub_80A763C();
+}
+
+static void sub_80A41E0(u8 *a, u16 b, const u8 *c, u16 d, u8 e)
+{
+ a[0] = EXT_CTRL_CODE_BEGIN;
+ a[1] = 0x13;
+ a[2] = 8;
+ a += 3;
+ a = ConvertIntToDecimalStringN(a, b, STR_CONV_MODE_LEADING_ZEROS, 2);
+ a[0] = EXT_CTRL_CODE_BEGIN;
+ a[1] = 0x13;
+ a[2] = 0x18;
+ a += 3;
+ a = sub_8072C74(a, c, 0x78 - (e + 1) * 6, 0);
+ *a++ = CHAR_MULT_SIGN;
+ sub_8072C14(a, d, 0x78, 1);
+}
+
+static u8 *sub_80A425C(u8 taskId, u8 *text, u8 c)
+{
+ if (gTasks[taskId].data[10] - gBagPocketScrollStates[sCurrentBagPocket].scrollTop - 1 == c)
+ {
+ text[0] = EXT_CTRL_CODE_BEGIN;
+ text[1] = 1;
+ text[2] = 2;
+ text += 3;
+ }
+ return text;
+}
+
+static bool8 sub_80A42B0(u8 itemPos, int b)
+{
+ u8 r5;
+ u16 *ptr;
+ struct UnknownStruct3 *r8 = &gUnknown_02038540;
+
+ if (gBagPocketScrollStates[sCurrentBagPocket].scrollTop + itemPos > gBagPocketScrollStates[sCurrentBagPocket].numSlots)
+ return TRUE;
+ if (gBagPocketScrollStates[sCurrentBagPocket].scrollTop + itemPos == gBagPocketScrollStates[sCurrentBagPocket].numSlots)
+ {
+ if (sReturnLocation == RETURN_TO_FIELD_5)
+ return TRUE;
+ r5 = itemPos * 2 + 2;
+ sub_8072C74(gStringVar1, gOtherText_CloseBag, 0x78, 0);
+ MenuPrint(gStringVar1, 14, r5);
+ ptr = gBGTilemapBuffers[2] + 14 + r5 * 32;
+ ptr[0] = 0x4F;
+ ptr[1] = 0x4F;
+ ptr[32] = 0x4F;
+ ptr[33] = 0x4F;
+ if (itemPos == 7)
+ return TRUE;
+ if ((b == 1 && r8->unk2 != 0) || b == 2)
+ MenuFillWindowRectWithBlankTile(14, r5 + 2, 29, 13);
+ else
+ MenuFillWindowRectWithBlankTile(14, r5 + 2, 29, 17);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void sub_80A4380(u16 a, int b, int c, int d)
+{
+ u8 i;
+
+ for (i = b; i <= c; i++)
+ {
+ u8 r4;
+ u8 r5;
+ u8 *text;
+
+ if (sub_80A42B0(i, d) == TRUE)
+ break;
+ r4 = gBagPocketScrollStates[sCurrentBagPocket].scrollTop + i;
+ r5 = i * 2 + 2;
+ text = gStringVar1;
+ text = sub_80A425C(a, text, i);
+ text = sub_8072C74(text, ItemId_GetItem(gCurrentBagPocketItemSlots[r4].itemId)->name, 0x66, 0);
+ *text++ = CHAR_MULT_SIGN;
+ sub_8072C14(text, gCurrentBagPocketItemSlots[r4].quantity, 0x78, 1);
+ MenuPrint(gStringVar1, 14, r5);
+ }
+}
+
+static void sub_80A444C(u16 a, int b, int c, int d)
+{
+ u8 i;
+
+ for (i = b; i <= c; i++)
+ {
+ u8 r4;
+ u8 r5;
+ u8 *text;
+
+ if (sub_80A42B0(i, d) == TRUE)
+ break;
+ r4 = gBagPocketScrollStates[sCurrentBagPocket].scrollTop + i;
+ r5 = i * 2 + 2;
+ text = gStringVar1;
+ text = sub_80A425C(a, text, i);
+#if ENGLISH
+ sub_8072C74(text, ItemId_GetItem(gCurrentBagPocketItemSlots[r4].itemId)->name, 0x60, 0);
+#else
+ sub_8072C74(text, ItemId_GetItem(gCurrentBagPocketItemSlots[r4].itemId)->name, 0x63, 0);
+#endif
+ MenuPrint(gStringVar1, 14, r5);
+ if (gUnknown_02038558 != 0)
+ {
+ if (gCurrentBagPocketItemSlots[r4].itemId == gSaveBlock1.registeredItem)
+ DrawSelectIcon(i);
+ }
+ else
+ {
+ if (gCurrentBagPocketItemSlots[r4].itemId == gSaveBlock1.registeredItem)
+ MoveSelectIcon(i);
+ else
+ EraseSelectIcon(i);
+ }
+ }
+}
+
+// more gBGTilemapBuffers shenanigans
+#ifdef NONMATCHING
+static void sub_80A4548(u16 a, int b, int c, int d)
+{
+ u8 i;
+
+ for (i = b; i <= c; i++)
+ {
+ u8 r4;
+ u8 sp10;
+ u32 r5;
+ u8 *text;
+
+ if (sub_80A42B0(i, d) == TRUE)
+ break;
+ r4 = gBagPocketScrollStates[sCurrentBagPocket].scrollTop + i;
+ sp10 = i * 2 + 2;
+ r5 = sp10 * 32 + 14;
+ text = gStringVar1;
+ text = sub_80A425C(a, text, i);
+ if (gCurrentBagPocketItemSlots[r4].itemId < 0x153)
+ {
+ const u8 *r2;
+
+ gBGTilemapBuffers[2][r5 + 0] = 0x59;
+ gBGTilemapBuffers[2][r5 + 1] = 0x4F;
+ gBGTilemapBuffers[2][r5 + 32] = 0x69;
+ gBGTilemapBuffers[2][r5 + 33] = 0x4F;
+ r2 = gMoveNames[ItemIdToBattleMoveId(gCurrentBagPocketItemSlots[r4].itemId)];
+ sub_80A41E0(text, gCurrentBagPocketItemSlots[r4].itemId - 288, r2, gCurrentBagPocketItemSlots[r4].quantity, 2);
+ }
+ else
+ {
+ const u8 *moveName;
+
+ gBGTilemapBuffers[2][r5 + 0] = 0x105D;
+ gBGTilemapBuffers[2][r5 + 1] = 0x105E;
+ gBGTilemapBuffers[2][r5 + 32] = 0x106D;
+ gBGTilemapBuffers[2][r5 + 33] = 0x106E;
+ text[0] = EXT_CTRL_CODE_BEGIN;
+ text[1] = 0x13;
+ text[2] = 0x11;
+ text += 3;
+ text = ConvertIntToDecimalString(text, gCurrentBagPocketItemSlots[r4].itemId);
+ text[0] = EXT_CTRL_CODE_BEGIN;
+ text[1] = 0x13;
+ text[2] = 0x18;
+ text += 3;
+ moveName = gMoveNames[ItemIdToBattleMoveId(gCurrentBagPocketItemSlots[r4].itemId)];
+ sub_8072C74(text, moveName, 0x78, 0);
+ }
+ MenuPrint(gStringVar1, 14, sp10);
+ }
+}
+#else
+__attribute__((naked))
+static void sub_80A4548(u16 a, int b, int c, int d)
+{
+ 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, 0x14\n\
+ str r2, [sp, 0x8]\n\
+ str r3, [sp, 0xC]\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ str r0, [sp, 0x4]\n\
+ lsls r1, 24\n\
+ lsrs r1, 24\n\
+ mov r8, r1\n\
+ ldr r0, _080A456C @ =gBGTilemapBuffers + 0x1000\n\
+ mov r9, r0\n\
+ b _080A46C2\n\
+ .align 2, 0\n\
+_080A456C: .4byte gBGTilemapBuffers + 0x1000\n\
+_080A4570:\n\
+ ldr r1, _080A461C @ =gBagPocketScrollStates\n\
+ ldr r0, _080A4620 @ =sCurrentBagPocket\n\
+ ldrb r0, [r0]\n\
+ lsls r0, 24\n\
+ asrs r0, 24\n\
+ lsls r0, 2\n\
+ adds r0, r1\n\
+ ldrb r4, [r0, 0x1]\n\
+ add r4, r8\n\
+ lsls r4, 24\n\
+ lsrs r4, 24\n\
+ mov r1, r8\n\
+ lsls r0, r1, 25\n\
+ movs r3, 0x80\n\
+ lsls r3, 18\n\
+ adds r0, r3\n\
+ lsrs r0, 24\n\
+ str r0, [sp, 0x10]\n\
+ lsls r0, 5\n\
+ adds r0, 0xE\n\
+ adds r5, r0, 0\n\
+ ldr r6, _080A4624 @ =gStringVar1\n\
+ ldr r1, [sp, 0x4]\n\
+ lsls r0, r1, 24\n\
+ lsrs r0, 24\n\
+ adds r1, r6, 0\n\
+ mov r2, r8\n\
+ bl sub_80A425C\n\
+ adds r6, r0, 0\n\
+ ldr r3, _080A4628 @ =gCurrentBagPocketItemSlots\n\
+ mov r10, r3\n\
+ ldr r0, [r3]\n\
+ lsls r7, r4, 2\n\
+ adds r3, r7, r0\n\
+ ldrh r1, [r3]\n\
+ movs r0, 0xA9\n\
+ lsls r0, 1\n\
+ cmp r1, r0\n\
+ bhi _080A4634\n\
+ lsls r0, r5, 1\n\
+ add r0, r9\n\
+ movs r1, 0x59\n\
+ strh r1, [r0]\n\
+ adds r0, r5, 0x1\n\
+ lsls r0, 1\n\
+ add r0, r9\n\
+ movs r2, 0x4F\n\
+ strh r2, [r0]\n\
+ adds r0, r5, 0\n\
+ adds r0, 0x20\n\
+ lsls r0, 1\n\
+ add r0, r9\n\
+ movs r1, 0x69\n\
+ strh r1, [r0]\n\
+ adds r0, r5, 0\n\
+ adds r0, 0x21\n\
+ lsls r0, 1\n\
+ add r0, r9\n\
+ strh r2, [r0]\n\
+ ldrh r0, [r3]\n\
+ bl ItemIdToBattleMoveId\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ movs r1, 0xD\n\
+ adds r2, r0, 0\n\
+ muls r2, r1\n\
+ ldr r0, _080A462C @ =gMoveNames\n\
+ adds r2, r0\n\
+ mov r1, r10\n\
+ ldr r0, [r1]\n\
+ adds r0, r7, r0\n\
+ ldr r3, _080A4630 @ =0xfffffee0\n\
+ adds r1, r3, 0\n\
+ ldrh r3, [r0]\n\
+ adds r1, r3\n\
+ lsls r1, 16\n\
+ lsrs r1, 16\n\
+ ldrh r3, [r0, 0x2]\n\
+ movs r0, 0x2\n\
+ str r0, [sp]\n\
+ adds r0, r6, 0\n\
+ bl sub_80A41E0\n\
+ b _080A46AE\n\
+ .align 2, 0\n\
+_080A461C: .4byte gBagPocketScrollStates\n\
+_080A4620: .4byte sCurrentBagPocket\n\
+_080A4624: .4byte gStringVar1\n\
+_080A4628: .4byte gCurrentBagPocketItemSlots\n\
+_080A462C: .4byte gMoveNames\n\
+_080A4630: .4byte 0xfffffee0\n\
+_080A4634:\n\
+ lsls r0, r5, 1\n\
+ add r0, r9\n\
+ ldr r1, _080A46EC @ =0x0000105d\n\
+ strh r1, [r0]\n\
+ adds r0, r5, 0x1\n\
+ lsls r0, 1\n\
+ add r0, r9\n\
+ adds r1, 0x1\n\
+ strh r1, [r0]\n\
+ adds r0, r5, 0\n\
+ adds r0, 0x20\n\
+ lsls r0, 1\n\
+ add r0, r9\n\
+ adds r1, 0xF\n\
+ strh r1, [r0]\n\
+ adds r0, r5, 0\n\
+ adds r0, 0x21\n\
+ lsls r0, 1\n\
+ add r0, r9\n\
+ adds r1, 0x1\n\
+ strh r1, [r0]\n\
+ movs r0, 0xFC\n\
+ strb r0, [r6]\n\
+ movs r4, 0x13\n\
+ strb r4, [r6, 0x1]\n\
+ movs r0, 0x11\n\
+ strb r0, [r6, 0x2]\n\
+ adds r6, 0x3\n\
+ mov r1, r10\n\
+ ldr r0, [r1]\n\
+ adds r0, r7, r0\n\
+ ldrh r1, [r0]\n\
+ ldr r3, _080A46F0 @ =0xfffffeae\n\
+ adds r1, r3\n\
+ adds r0, r6, 0\n\
+ bl ConvertIntToDecimalString\n\
+ adds r6, r0, 0\n\
+ movs r0, 0xFC\n\
+ strb r0, [r6]\n\
+ strb r4, [r6, 0x1]\n\
+ movs r0, 0x18\n\
+ strb r0, [r6, 0x2]\n\
+ adds r6, 0x3\n\
+ mov r1, r10\n\
+ ldr r0, [r1]\n\
+ adds r0, r7, r0\n\
+ ldrh r0, [r0]\n\
+ bl ItemIdToBattleMoveId\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ movs r1, 0xD\n\
+ muls r1, r0\n\
+ ldr r0, _080A46F4 @ =gMoveNames\n\
+ adds r1, r0\n\
+ adds r0, r6, 0\n\
+ movs r2, 0x78\n\
+ movs r3, 0\n\
+ bl sub_8072C74\n\
+_080A46AE:\n\
+ ldr r0, _080A46F8 @ =gStringVar1\n\
+ movs r1, 0xE\n\
+ ldr r2, [sp, 0x10]\n\
+ bl MenuPrint\n\
+ mov r0, r8\n\
+ adds r0, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ mov r8, r0\n\
+_080A46C2:\n\
+ ldr r3, [sp, 0x8]\n\
+ cmp r8, r3\n\
+ bgt _080A46DA\n\
+ mov r0, r8\n\
+ ldr r1, [sp, 0xC]\n\
+ bl sub_80A42B0\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ cmp r0, 0x1\n\
+ beq _080A46DA\n\
+ b _080A4570\n\
+_080A46DA:\n\
+ add sp, 0x14\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\
+ .align 2, 0\n\
+_080A46EC: .4byte 0x0000105d\n\
+_080A46F0: .4byte 0xfffffeae\n\
+_080A46F4: .4byte gMoveNames\n\
+_080A46F8: .4byte gStringVar1\n\
+ .syntax divided\n");
+}
+#endif
+
+static void sub_80A46FC(u16 a, int b, int c, int d)
+{
+ u8 i;
+
+ for (i = b; i <= c; i++)
+ {
+ u8 r4;
+ u8 r5;
+ u8 *text;
+ register int var asm("r0");
+
+ if (sub_80A42B0(i, d) == TRUE)
+ break;
+ r4 = gBagPocketScrollStates[sCurrentBagPocket].scrollTop + i;
+ r5 = i * 2 + 2;
+
+ var = 14 + r5 * 32;
+ gBGTilemapBuffers[2][var] = 0x59;
+ var += 32;
+ gBGTilemapBuffers[2][var] = 0x69;
+
+ text = gStringVar1;
+ text = sub_80A425C(a, text, i);
+ CopyItemName(gCurrentBagPocketItemSlots[r4].itemId, gStringVar2);
+ sub_80A41E0(text, gCurrentBagPocketItemSlots[r4].itemId - 0x84, gStringVar2, gCurrentBagPocketItemSlots[r4].quantity, 3);
+ MenuPrint(gStringVar1, 14, r5);
+ }
+}
+
+static void sub_80A47E8(u16 a, int b, int c, int d)
+{
+ switch (sCurrentBagPocket)
+ {
+ case BAG_POCKET_ITEMS:
+ case BAG_POCKET_POKE_BALLS:
+ sub_80A4380(a, b, c, d);
+ break;
+ case BAG_POCKET_KEY_ITEMS:
+ sub_80A444C(a, b, c, d);
+ break;
+ case BAG_POCKET_TMs_HMs:
+ sub_80A4548(a, b, c, d);
+ break;
+ case BAG_POCKET_BERRIES:
+ sub_80A46FC(a, b, c, d);
+ break;
+ }
+ if (gBagPocketScrollStates[sCurrentBagPocket].scrollTop != 0)
+ sub_80F979C(0, 0);
+ else
+ sub_80F979C(0, 1);
+ if ((sReturnLocation != RETURN_TO_FIELD_5 && gBagPocketScrollStates[sCurrentBagPocket].scrollTop + 8 < gBagPocketScrollStates[sCurrentBagPocket].numSlots + 1)
+ || (sReturnLocation == RETURN_TO_FIELD_5 && gBagPocketScrollStates[sCurrentBagPocket].scrollTop + 8 < gBagPocketScrollStates[sCurrentBagPocket].numSlots))
+ sub_80F979C(1, 0);
+ else
+ sub_80F979C(1, 1);
+}
+
+static void sub_80A48E8(u16 taskId, int b, int c)
+{
+ sub_80A47E8(taskId, b, c, 0);
+}
+
+static void sub_80A48F8(u16 taskId)
+{
+ sub_80A47E8(taskId, 0, 5, 2);
+}
+
+static void ItemListMenu_InitDescription(s16 itemId)
+{
+ u8 r5;
+
+ if (gBagPocketScrollStates[sCurrentBagPocket].scrollTop + gBagPocketScrollStates[sCurrentBagPocket].cursorPos == gBagPocketScrollStates[sCurrentBagPocket].numSlots)
+ {
+ r5 = sub_8072A18(gOtherText_ReturnTo, 4, 0x68, 0x68, 1);
+ r5 += sub_8072A18(gUnknown_0840E740[sReturnLocation], 4, 0x78, 0x68, 1);
+ }
+ else
+ {
+ r5 = sub_8072A18(ItemId_GetDescription(itemId), 4, 0x68, 0x68, 1);
+ }
+
+ if (r5 < 3)
+ MenuZeroFillWindowRect(0, 13 + r5 * 2, 13, 20);
+}
+
+static void ItemListMenu_ChangeDescription(s16 itemId, int b)
+{
+ u8 description[100];
+
+ if (gBagPocketScrollStates[sCurrentBagPocket].scrollTop + gBagPocketScrollStates[sCurrentBagPocket].cursorPos == gBagPocketScrollStates[sCurrentBagPocket].numSlots)
+ {
+ if (b == 0)
+ {
+ MenuZeroFillWindowRect(0, 13, 13, 20);
+ MenuPrint_PixelCoords(gOtherText_ReturnTo, 4, 0x68, 0);
+ }
+ else if (b == 1)
+ {
+ MenuPrint_PixelCoords(gUnknown_0840E740[sReturnLocation], 4, 0x78, 0);
+ }
+ }
+ else
+ {
+ if (b == 0)
+ MenuZeroFillWindowRect(0, 13, 13, 20);
+ if (ItemId_CopyDescription(description, itemId, b))
+ MenuPrint_PixelCoords(description, 4, 104 + b * 16, 0);
+ }
+}
+
+static bool32 CopyTextLine(u8 *destination, const u8 *source, u32 c)
+{
+ u32 r4 = c + 1;
+ const u8 *src = source;
+ u8 *dst = destination;
+
+ while (1)
+ {
+ if (*src == CHAR_NEWLINE || *src == EOS)
+ {
+ r4--;
+ if (r4 == 0)
+ {
+ *dst = EOS;
+ return TRUE;
+ }
+ if (*src == EOS)
+ return FALSE;
+ // got a new line - reset dst pointer
+ dst = destination;
+ src++;
+ }
+ else
+ {
+ *dst++ = *src++;
+ }
+ }
+}
+
+static void sub_80A4A98(const u8 *text, u32 line)
+{
+ u8 buffer[100];
+
+ if (line == 0)
+ MenuZeroFillWindowRect(0, 13, 13, 20);
+ if (CopyTextLine(buffer, text, line))
+ MenuPrint_PixelCoords(buffer, 4, 104 + line * 16, 0);
+}
+
+static void sub_80A4ADC(u8 taskId)
+{
+ if (gTasks[taskId].data[10] == 0)
+ sub_80A7528(0);
+ PlaySE(SE_SELECT);
+ gUnknown_0203855C = 1;
+}
+
+static void sub_80A4B14(s8 a, u8 b)
+{
+ gBagPocketScrollStates[sCurrentBagPocket].scrollTop += a;
+ MoveMenuCursor(0);
+ sub_80A73C0();
+ sub_80A763C();
+ sub_80A4ADC(b);
+}
+
+static void sub_80A4B58(s8 delta, u8 b)
+{
+ gBagPocketScrollStates[sCurrentBagPocket].cursorPos = MoveMenuCursor(delta);
+ sub_80A73C0();
+ sub_80A4ADC(b);
+}
+
+static const u8 *sub_80A4B90(u16 itemId)
+{
+ if (TestPlayerAvatarFlags(6))
+ {
+ if (itemId == ITEM_MACH_BIKE || itemId == ITEM_ACRO_BIKE)
+ return gOtherText_Walk;
+ }
+ if (ItemIsMail(itemId) == TRUE)
+ return gOtherText_Check;
+ return sItemPopupMenuActions[sPopupMenuActionList[0]].text;
+}
+
+static void sub_80A4BF0(u16 *a)
+{
+ u8 i;
+
+ if (gUnknown_02038564 == 4)
+ {
+ MenuDrawTextWindow(0, 7, 13, 12);
+ sub_80A4008(a, 1, 8, 12, 4);
+ if (sub_80F9344() == TRUE && sReturnLocation == RETURN_TO_FIELD_5)
+ {
+ sub_80A7834(1, 0);
+ }
+ else
+ {
+ for (i = 0; i < gUnknown_02038564; i++)
+ {
+ const u8 *text;
+
+ if (i == 0)
+ text = sub_80A4B90(gScriptItemId);
+ else
+ text = sItemPopupMenuActions[sPopupMenuActionList[i]].text;
+ MenuPrint(text, 1 + (i / 2) * 6, 8 + (i % 2) * 2);
+ }
+ }
+ if (sReturnLocation == RETURN_TO_FIELD_5)
+ InitMenu(0, 1, 8, gUnknown_02038564, sPopupMenuSelection, 1);
+ else
+ InitMenu(0, 1, 8, gUnknown_02038564, 0, 1);
+ sub_8072DCC(0x2F);
+ }
+ else
+ {
+ MenuDrawTextWindow(0, 5, 13, 12);
+ sub_80A4008(a, 1, 6, 12, 6);
+ for (i = 0; i < gUnknown_02038564; i++)
+ MenuPrint(sItemPopupMenuActions[sPopupMenuActionList[i]].text, 1 + (i / 3) * 6, 6 + (i % 3) * 2);
+ InitMenu(0, 1, 6, gUnknown_02038564, 0, 1);
+ sub_8072DCC(0x2F);
+ }
+ sub_80A7528(2);
+}
+
+static void sub_80A4DA4(u16 *a)
+{
+ sub_80A73FC();
+ sub_80A36B8(a, 0, 6, 13, 6);
+ MenuZeroFillWindowRect(0, 5, 13, 12);
+ sub_80A7590();
+}
+
+static void sub_80A4DD8(u8 taskId, u8 b, u8 c, u8 d, u8 e, u8 digits)
+{
+ gTasks[taskId].data[1] = 1;
+ gTasks[taskId].data[2] = b + 2;
+ gTasks[taskId].data[3] = c + 1;
+ MenuDrawTextWindow(b, c, b + d, c + e);
+ sub_80A4008(gBGTilemapBuffers[1], b + 1, c + 1, d - 1, e - 1);
+ sub_80A418C(1, 1, b + 2, c + 1, digits);
+}
+
+static void sub_80A4E8C(s8 delta, u8 b)
+{
+ PlaySE(SE_SELECT);
+ sub_80F979C(0, 1);
+ sub_80F979C(1, 1);
+ sub_80F979C(2, 1);
+ sub_80F979C(3, 1);
+ PauseVerticalScrollIndicator(0);
+ PauseVerticalScrollIndicator(1);
+ PauseVerticalScrollIndicator(2);
+ PauseVerticalScrollIndicator(3);
+ ChangePocket(gBGTilemapBuffers[2], delta);
+ DrawPocketIndicatorDots(gBGTilemapBuffers[2], sCurrentBagPocket);
+ sub_80A3770();
+ sub_80A7C64();
+ CreateBagPokeballSprite(b);
+}
+
+static bool8 sub_80A4F0C(void)
+{
+ if (sReturnLocation == RETURN_TO_FIELD_5 || sReturnLocation == RETURN_TO_FIELD_4)
+ return FALSE;
+ if (gMain.newKeys == DPAD_RIGHT || sub_80F9284() == 2)
+ {
+ sub_80A4E8C(1, 2);
+ return TRUE;
+ }
+ if (gMain.newKeys == DPAD_LEFT || sub_80F9284() == 1)
+ {
+ sub_80A4E8C(-1, 1);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void sub_80A4F68(u8 taskId)
+{
+ sub_80A4F0C();
+}
+
+static bool8 sub_80A4F74(u8 a)
+{
+ bool8 retVal = FALSE;
+
+ if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_UP)
+ {
+ if (gBagPocketScrollStates[sCurrentBagPocket].cursorPos != 0)
+ sub_80A4B58(-1, a);
+ else if (gBagPocketScrollStates[sCurrentBagPocket].scrollTop != 0)
+ sub_80A4B14(-1, a);
+ if (gLinkOpen == TRUE && gMain.keyRepeatCounter == 5)
+ gMain.keyRepeatCounter = 11;
+ retVal = TRUE;
+ }
+ else if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_DOWN)
+ {
+ if (sReturnLocation != RETURN_TO_FIELD_5)
+ {
+ if (gBagPocketScrollStates[sCurrentBagPocket].cursorPos == gBagPocketScrollStates[sCurrentBagPocket].cursorMax)
+ {
+ if (gBagPocketScrollStates[sCurrentBagPocket].scrollTop + gBagPocketScrollStates[sCurrentBagPocket].cursorPos != gBagPocketScrollStates[sCurrentBagPocket].numSlots)
+ sub_80A4B14(1, a);
+ }
+ else
+ {
+ sub_80A4B58(1, a);
+ }
+ }
+ else
+ {
+ if (gBagPocketScrollStates[sCurrentBagPocket].scrollTop + gBagPocketScrollStates[sCurrentBagPocket].cursorPos != gBagPocketScrollStates[sCurrentBagPocket].numSlots - 1)
+ {
+ if (gBagPocketScrollStates[sCurrentBagPocket].cursorPos != gBagPocketScrollStates[sCurrentBagPocket].cursorMax)
+ sub_80A4B58(1, a);
+ else
+ sub_80A4B14(1, a);
+ }
+ }
+ retVal = TRUE;
+ if (gLinkOpen == TRUE && gMain.keyRepeatCounter == 5)
+ gMain.keyRepeatCounter = 11;
+ }
+ else
+ {
+ if (gTasks[a].data[10] == 0 && sub_80A4F0C() == TRUE)
+ {
+ sub_80A73F0();
+ gTasks[a].func = sub_80A4F68;
+ retVal = TRUE;
+ }
+ else
+ {
+ sub_80A73C0();
+ }
+ }
+ return retVal;
+}
+
+static void sub_80A50C8(u8 taskId)
+{
+ s16 *r5 = gTasks[taskId].data;
+
+ if (!gPaletteFade.active)
+ {
+ if (sub_80A4F74(taskId) == TRUE)
+ {
+ sub_808B5B4(taskId);
+ return;
+ }
+
+ if ((gMain.newKeys & SELECT_BUTTON)
+ && !(sCurrentBagPocket == BAG_POCKET_BERRIES || sCurrentBagPocket == BAG_POCKET_TMs_HMs)
+ && (sReturnLocation == RETURN_TO_FIELD_0 || sReturnLocation == RETURN_TO_BATTLE))
+ {
+ if (r5[10] == 0)
+ {
+ if (gBagPocketScrollStates[sCurrentBagPocket].scrollTop + gBagPocketScrollStates[sCurrentBagPocket].cursorPos != gBagPocketScrollStates[sCurrentBagPocket].numSlots)
+ {
+ PlaySE(SE_SELECT);
+ sub_80A3F50(taskId);
+ }
+ sub_808B5B4(taskId);
+ }
+ else
+ {
+ if (gBagPocketScrollStates[sCurrentBagPocket].scrollTop + gBagPocketScrollStates[sCurrentBagPocket].cursorPos != gBagPocketScrollStates[sCurrentBagPocket].numSlots)
+ {
+ PlaySE(SE_SELECT);
+ sub_80A3E90(taskId);
+ }
+ else
+ {
+ sub_80A3EF4(taskId);
+ }
+ sub_808B5B4(taskId);
+ }
+ return;
+ }
+
+ if (gMain.newKeys & A_BUTTON)
+ {
+ if (gBagPocketScrollStates[sCurrentBagPocket].scrollTop + gBagPocketScrollStates[sCurrentBagPocket].cursorPos == gBagPocketScrollStates[sCurrentBagPocket].numSlots)
+ {
+ if (r5[10] == 0)
+ {
+ gScriptItemId = 0;
+ gUnknown_083C16BC[sReturnLocation].onBagClose(taskId);
+ }
+ else
+ {
+ sub_80A3EF4(taskId);
+ }
+ sub_808B5B4(taskId);
+ }
+ else
+ {
+ if (r5[10] == 0)
+ {
+ PlaySE(SE_SELECT);
+ gUnknown_02038560 = gBagPocketScrollStates[sCurrentBagPocket].scrollTop + gBagPocketScrollStates[sCurrentBagPocket].cursorPos;
+ gScriptItemId = gCurrentBagPocketItemSlots[gUnknown_02038560].itemId;
+ gUnknown_083C16BC[sReturnLocation].onItemSelect(taskId);
+ sub_80F98A4(0);
+ sub_80F98A4(1);
+ sub_80F98A4(2);
+ sub_80F98A4(3);
+ sub_80A797C();
+ }
+ else
+ {
+ sub_80A3E90(taskId);
+ }
+ sub_808B5B4(taskId);
+ }
+ return;
+ }
+
+ if (gMain.newKeys & B_BUTTON)
+ {
+ if (r5[10] == 0)
+ {
+ if (sReturnLocation != RETURN_TO_FIELD_5)
+ {
+ gScriptItemId = 0;
+ gUnknown_083C16BC[sReturnLocation].onBagClose(taskId);
+ }
+ }
+ else
+ {
+ sub_80A3EF4(taskId);
+ }
+ sub_808B5B4(taskId);
+ return;
+ }
+ }
+}
+
+bool8 sub_80A52C4(u8 taskId, u16 b)
+{
+ s16 *taskData = gTasks[taskId].data;
+
+ if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_UP)
+ {
+ if (taskData[1] != b)
+ taskData[1]++;
+ else
+ taskData[1] = 1;
+ return TRUE;
+ }
+
+ if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_DOWN)
+ {
+ if (taskData[1] != 1)
+ taskData[1]--;
+ else
+ taskData[1] = b;
+ return TRUE;
+ }
+
+ if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_RIGHT)
+ {
+ if (taskData[1] + 10 < b)
+ taskData[1] += 10;
+ else
+ taskData[1] = b;
+ return TRUE;
+ }
+
+ if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_LEFT)
+ {
+ if (taskData[1] > 10)
+ taskData[1] -= 10;
+ else
+ taskData[1] = 1;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static bool8 sub_80A5350(u8 taskId)
+{
+ s16 *taskData = gTasks[taskId].data;
+
+ if (sub_80A52C4(taskId, gCurrentBagPocketItemSlots[gUnknown_02038560].quantity) == TRUE)
+ {
+ // if (sCurrentBagPocket == BAG_POCKET_BERRIES) Can't get it to match this way
+ if (sCurrentBagPocket + 1 == BAG_POCKET_BERRIES + 1)
+ sub_80A418C(taskData[1], 1, taskData[2], taskData[3], 3);
+ else
+ sub_80A418C(taskData[1], 1, taskData[2], taskData[3], 2);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void sub_80A53CC(void)
+{
+ if (sub_80A34B4() == TRUE)
+ {
+ sub_80A3770();
+ gUnknown_02038563 = CreateTask(sub_80A50C8, 0);
+ }
+}
+
+void sub_80A53F8(void)
+{
+ sReturnLocation = RETURN_TO_FIELD_0;
+ SetMainCallback2(sub_80A53CC);
+}
+
+#ifdef NONMATCHING
+static void sub_80A5414(u8 taskId)
+{
+ TaskFunc r5 = NULL;
+
+ if (sub_80A78A0() != 0)
+ {
+ if ((gMain.newAndRepeatedKeys & DPAD_ANY) == 0x40)
+ {
+ if ((sPopupMenuSelection & 1) && sPopupMenuActionList[sPopupMenuSelection - 1] == 8)
+ {
+ PlaySE(SE_SELECT);
+ sPopupMenuSelection = MoveMenuCursor3(-1);
+ }
+ }
+ //_080A546C
+ else if ((gMain.newAndRepeatedKeys & DPAD_ANY) == 0x80)
+ {
+ if (!(sPopupMenuSelection & 1) && sPopupMenuActionList[sPopupMenuSelection + 1] != 8)
+ {
+ PlaySE(SE_SELECT);
+ sPopupMenuSelection = MoveMenuCursor3(1);
+ }
+ }
+ //_080A549C
+ else if ((gMain.newAndRepeatedKeys & DPAD_ANY) == 0x20)
+ {
+ if (sPopupMenuSelection > 1 && sPopupMenuActionList[sPopupMenuSelection - 2] != 8)
+ {
+ PlaySE(SE_SELECT);
+ sPopupMenuSelection = MoveMenuCursor3(-2);
+ }
+ }
+ //_080A54CC
+ else if ((gMain.newAndRepeatedKeys & DPAD_ANY) == 0x10)
+ {
+ if (sPopupMenuSelection <= 1 && sPopupMenuActionList[sPopupMenuSelection + 2] != 8)
+ {
+ PlaySE(SE_SELECT);
+ sPopupMenuSelection = MoveMenuCursor3(2);
+ }
+ }
+ //_080A5500
+ else if (!(gMain.newKeys & A_BUTTON))
+ {
+ if (gMain.newKeys & B_BUTTON)
+ {
+ gTasks[taskId].data[10] = 0;
+ sub_80A48E8(taskId, gBagPocketScrollStates[sCurrentBagPocket].cursorPos, gBagPocketScrollStates[sCurrentBagPocket].cursorPos);
+ sub_80A4DA4(gBGTilemapBuffers[1]);
+ r5 = sItemPopupMenuActions[sPopupMenuActionList[3]].func;
+ r5(taskId);
+ }
+ }
+ else
+ {
+ //_080A5590
+ gTasks[taskId].data[10] = 0;
+ sub_80A4DA4(gBGTilemapBuffers[1]);
+ r5 = sItemPopupMenuActions[sPopupMenuActionList[sPopupMenuSelection]].func;
+ r5(taskId);
+ }
+ }
+ //_080A5552
+ if (r5 == NULL)
+ {
+ if (sReturnLocation == RETURN_TO_FIELD_5)
+ {
+ if (sPopupMenuSelection == 0)
+ {
+ sub_8072DDC(12);
+ return;
+ }
+ //_080A55D4
+ //else
+ //{
+ if (sPopupMenuSelection == 0 || sPopupMenuSelection == 1)
+ sub_8072DCC(0x2F);
+ else
+ sub_8072DCC(0x30);
+ //}
+ }
+ //_080A55E0
+ else
+ {
+ if (sPopupMenuSelection == 0 || sPopupMenuSelection == 1)
+ sub_8072DCC(0x2F);
+ else
+ sub_8072DCC(0x30);
+ }
+ }
+}
+#else
+__attribute__((naked))
+static void sub_80A5414(u8 taskId)
+{
+ asm(".syntax unified\n\
+ push {r4,r5,lr}\n\
+ lsls r0, 24\n\
+ lsrs r4, r0, 24\n\
+ movs r5, 0\n\
+ bl sub_80A78A0\n\
+ cmp r0, 0\n\
+ bne _080A5426\n\
+ b _080A5552\n\
+_080A5426:\n\
+ ldr r2, _080A5460 @ =gMain\n\
+ ldrh r0, [r2, 0x30]\n\
+ movs r1, 0xF0\n\
+ ands r1, r0\n\
+ cmp r1, 0x40\n\
+ bne _080A546C\n\
+ ldr r4, _080A5464 @ =sPopupMenuSelection\n\
+ ldrb r1, [r4]\n\
+ movs r0, 0x1\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ bne _080A5440\n\
+ b _080A5552\n\
+_080A5440:\n\
+ ldrb r1, [r4]\n\
+ ldr r0, _080A5468 @ =sPopupMenuActionList\n\
+ ldr r0, [r0]\n\
+ adds r1, r0\n\
+ subs r1, 0x1\n\
+ ldrb r0, [r1]\n\
+ cmp r0, 0x8\n\
+ bne _080A5452\n\
+ b _080A5552\n\
+_080A5452:\n\
+ movs r0, 0x5\n\
+ bl PlaySE\n\
+ movs r0, 0x1\n\
+ negs r0, r0\n\
+ b _080A54EE\n\
+ .align 2, 0\n\
+_080A5460: .4byte gMain\n\
+_080A5464: .4byte sPopupMenuSelection\n\
+_080A5468: .4byte sPopupMenuActionList\n\
+_080A546C:\n\
+ cmp r1, 0x80\n\
+ bne _080A549C\n\
+ ldr r4, _080A5494 @ =sPopupMenuSelection\n\
+ ldrb r1, [r4]\n\
+ movs r0, 0x1\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ bne _080A5552\n\
+ ldrb r1, [r4]\n\
+ ldr r0, _080A5498 @ =sPopupMenuActionList\n\
+ ldr r0, [r0]\n\
+ adds r1, r0\n\
+ ldrb r0, [r1, 0x1]\n\
+ cmp r0, 0x8\n\
+ beq _080A5552\n\
+ movs r0, 0x5\n\
+ bl PlaySE\n\
+ movs r0, 0x1\n\
+ b _080A54EE\n\
+ .align 2, 0\n\
+_080A5494: .4byte sPopupMenuSelection\n\
+_080A5498: .4byte sPopupMenuActionList\n\
+_080A549C:\n\
+ cmp r1, 0x20\n\
+ bne _080A54CC\n\
+ ldr r4, _080A54C4 @ =sPopupMenuSelection\n\
+ ldrb r0, [r4]\n\
+ cmp r0, 0x1\n\
+ bls _080A5552\n\
+ adds r1, r0, 0\n\
+ ldr r0, _080A54C8 @ =sPopupMenuActionList\n\
+ ldr r0, [r0]\n\
+ adds r1, r0\n\
+ subs r1, 0x2\n\
+ ldrb r0, [r1]\n\
+ cmp r0, 0x8\n\
+ beq _080A5552\n\
+ movs r0, 0x5\n\
+ bl PlaySE\n\
+ movs r0, 0x2\n\
+ negs r0, r0\n\
+ b _080A54EE\n\
+ .align 2, 0\n\
+_080A54C4: .4byte sPopupMenuSelection\n\
+_080A54C8: .4byte sPopupMenuActionList\n\
+_080A54CC:\n\
+ cmp r1, 0x10\n\
+ bne _080A5500\n\
+ ldr r4, _080A54F8 @ =sPopupMenuSelection\n\
+ ldrb r0, [r4]\n\
+ cmp r0, 0x1\n\
+ bhi _080A5552\n\
+ adds r1, r0, 0\n\
+ ldr r0, _080A54FC @ =sPopupMenuActionList\n\
+ ldr r0, [r0]\n\
+ adds r1, r0\n\
+ ldrb r0, [r1, 0x2]\n\
+ cmp r0, 0x8\n\
+ beq _080A5552\n\
+ movs r0, 0x5\n\
+ bl PlaySE\n\
+ movs r0, 0x2\n\
+_080A54EE:\n\
+ bl MoveMenuCursor3\n\
+ strb r0, [r4]\n\
+ b _080A5552\n\
+ .align 2, 0\n\
+_080A54F8: .4byte sPopupMenuSelection\n\
+_080A54FC: .4byte sPopupMenuActionList\n\
+_080A5500:\n\
+ ldrh r1, [r2, 0x2E]\n\
+ movs r0, 0x1\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ bne _080A5590\n\
+ movs r0, 0x2\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ beq _080A5552\n\
+ ldr r1, _080A5570 @ =gTasks\n\
+ lsls r0, r4, 2\n\
+ adds r0, r4\n\
+ lsls r0, 3\n\
+ adds r0, r1\n\
+ strh r5, [r0, 0x1C]\n\
+ ldr r1, _080A5574 @ =gBagPocketScrollStates\n\
+ ldr r0, _080A5578 @ =sCurrentBagPocket\n\
+ ldrb r0, [r0]\n\
+ lsls r0, 24\n\
+ asrs r0, 24\n\
+ lsls r0, 2\n\
+ adds r0, r1\n\
+ ldrb r2, [r0]\n\
+ adds r0, r4, 0\n\
+ adds r1, r2, 0\n\
+ bl sub_80A48E8\n\
+ ldr r0, _080A557C @ =gBGTilemapBuffers + 0x800\n\
+ bl sub_80A4DA4\n\
+ ldr r1, _080A5580 @ =sItemPopupMenuActions\n\
+ ldr r0, _080A5584 @ =sPopupMenuActionList\n\
+ ldr r0, [r0]\n\
+ ldrb r0, [r0, 0x3]\n\
+ lsls r0, 3\n\
+ adds r1, 0x4\n\
+ adds r0, r1\n\
+ ldr r5, [r0]\n\
+ adds r0, r4, 0\n\
+ bl _call_via_r5\n\
+_080A5552:\n\
+ cmp r5, 0\n\
+ bne _080A55FA\n\
+ ldr r0, _080A5588 @ =sReturnLocation\n\
+ ldrb r0, [r0]\n\
+ cmp r0, 0x5\n\
+ bne _080A55E0\n\
+ ldr r0, _080A558C @ =sPopupMenuSelection\n\
+ ldrb r0, [r0]\n\
+ cmp r0, 0\n\
+ bne _080A55D4\n\
+ movs r0, 0xC\n\
+ bl sub_8072DDC\n\
+ b _080A55FA\n\
+ .align 2, 0\n\
+_080A5570: .4byte gTasks\n\
+_080A5574: .4byte gBagPocketScrollStates\n\
+_080A5578: .4byte sCurrentBagPocket\n\
+_080A557C: .4byte gBGTilemapBuffers + 0x800\n\
+_080A5580: .4byte sItemPopupMenuActions\n\
+_080A5584: .4byte sPopupMenuActionList\n\
+_080A5588: .4byte sReturnLocation\n\
+_080A558C: .4byte sPopupMenuSelection\n\
+_080A5590:\n\
+ ldr r1, _080A55C0 @ =gTasks\n\
+ lsls r0, r4, 2\n\
+ adds r0, r4\n\
+ lsls r0, 3\n\
+ adds r0, r1\n\
+ strh r5, [r0, 0x1C]\n\
+ ldr r0, _080A55C4 @ =gBGTilemapBuffers + 0x800\n\
+ bl sub_80A4DA4\n\
+ ldr r1, _080A55C8 @ =sItemPopupMenuActions\n\
+ ldr r0, _080A55CC @ =sPopupMenuSelection\n\
+ ldrb r2, [r0]\n\
+ ldr r0, _080A55D0 @ =sPopupMenuActionList\n\
+ ldr r0, [r0]\n\
+ adds r0, r2\n\
+ ldrb r0, [r0]\n\
+ lsls r0, 3\n\
+ adds r1, 0x4\n\
+ adds r0, r1\n\
+ ldr r5, [r0]\n\
+ adds r0, r4, 0\n\
+ bl _call_via_r5\n\
+ b _080A5552\n\
+ .align 2, 0\n\
+_080A55C0: .4byte gTasks\n\
+_080A55C4: .4byte gBGTilemapBuffers + 0x800\n\
+_080A55C8: .4byte sItemPopupMenuActions\n\
+_080A55CC: .4byte sPopupMenuSelection\n\
+_080A55D0: .4byte sPopupMenuActionList\n\
+_080A55D4:\n\
+ cmp r0, 0x1\n\
+ bls _080A55E8\n\
+ movs r0, 0x30\n\
+ bl sub_8072DCC\n\
+ b _080A55FA\n\
+_080A55E0:\n\
+ ldr r0, _080A55F0 @ =sPopupMenuSelection\n\
+ ldrb r0, [r0]\n\
+ cmp r0, 0x1\n\
+ bhi _080A55F4\n\
+_080A55E8:\n\
+ movs r0, 0x2F\n\
+ bl sub_8072DCC\n\
+ b _080A55FA\n\
+ .align 2, 0\n\
+_080A55F0: .4byte sPopupMenuSelection\n\
+_080A55F4:\n\
+ movs r0, 0x30\n\
+ bl sub_8072DCC\n\
+_080A55FA:\n\
+ pop {r4,r5}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .syntax divided\n");
+}
+#endif
+
+__attribute__((naked))
+static void sub_80A5600(u8 taskId)
+{
+ asm(".syntax unified\n\
+ push {r4,r5,lr}\n\
+ lsls r0, 24\n\
+ lsrs r4, r0, 24\n\
+ movs r5, 0\n\
+ ldr r2, _080A563C @ =gMain\n\
+ ldrh r0, [r2, 0x30]\n\
+ movs r1, 0xF0\n\
+ ands r1, r0\n\
+ cmp r1, 0x40\n\
+ bne _080A5648\n\
+ ldr r4, _080A5640 @ =sPopupMenuSelection\n\
+ ldrb r0, [r4]\n\
+ cmp r0, 0\n\
+ bne _080A561E\n\
+ b _080A5736\n\
+_080A561E:\n\
+ adds r1, r0, 0\n\
+ ldr r0, _080A5644 @ =sPopupMenuActionList\n\
+ ldr r0, [r0]\n\
+ adds r1, r0\n\
+ subs r1, 0x1\n\
+ ldrb r0, [r1]\n\
+ cmp r0, 0x8\n\
+ bne _080A5630\n\
+ b _080A5736\n\
+_080A5630:\n\
+ movs r0, 0x5\n\
+ bl PlaySE\n\
+ movs r0, 0x1\n\
+ negs r0, r0\n\
+ b _080A56D2\n\
+ .align 2, 0\n\
+_080A563C: .4byte gMain\n\
+_080A5640: .4byte sPopupMenuSelection\n\
+_080A5644: .4byte sPopupMenuActionList\n\
+_080A5648:\n\
+ cmp r1, 0x80\n\
+ bne _080A5680\n\
+ ldr r4, _080A5674 @ =sPopupMenuSelection\n\
+ ldrb r1, [r4]\n\
+ ldr r0, _080A5678 @ =gUnknown_02038564\n\
+ ldrb r0, [r0]\n\
+ subs r0, 0x1\n\
+ cmp r1, r0\n\
+ beq _080A5736\n\
+ cmp r1, 0x2\n\
+ beq _080A5736\n\
+ ldr r0, _080A567C @ =sPopupMenuActionList\n\
+ ldr r0, [r0]\n\
+ adds r0, r1, r0\n\
+ ldrb r0, [r0, 0x1]\n\
+ cmp r0, 0x8\n\
+ beq _080A5736\n\
+ movs r0, 0x5\n\
+ bl PlaySE\n\
+ movs r0, 0x1\n\
+ b _080A56D2\n\
+ .align 2, 0\n\
+_080A5674: .4byte sPopupMenuSelection\n\
+_080A5678: .4byte gUnknown_02038564\n\
+_080A567C: .4byte sPopupMenuActionList\n\
+_080A5680:\n\
+ cmp r1, 0x20\n\
+ bne _080A56B0\n\
+ ldr r4, _080A56A8 @ =sPopupMenuSelection\n\
+ ldrb r0, [r4]\n\
+ cmp r0, 0x2\n\
+ bls _080A5736\n\
+ adds r1, r0, 0\n\
+ ldr r0, _080A56AC @ =sPopupMenuActionList\n\
+ ldr r0, [r0]\n\
+ adds r1, r0\n\
+ subs r1, 0x3\n\
+ ldrb r0, [r1]\n\
+ cmp r0, 0x8\n\
+ beq _080A5736\n\
+ movs r0, 0x5\n\
+ bl PlaySE\n\
+ movs r0, 0x3\n\
+ negs r0, r0\n\
+ b _080A56D2\n\
+ .align 2, 0\n\
+_080A56A8: .4byte sPopupMenuSelection\n\
+_080A56AC: .4byte sPopupMenuActionList\n\
+_080A56B0:\n\
+ cmp r1, 0x10\n\
+ bne _080A56E4\n\
+ ldr r4, _080A56DC @ =sPopupMenuSelection\n\
+ ldrb r0, [r4]\n\
+ cmp r0, 0x2\n\
+ bhi _080A5736\n\
+ adds r1, r0, 0\n\
+ ldr r0, _080A56E0 @ =sPopupMenuActionList\n\
+ ldr r0, [r0]\n\
+ adds r1, r0\n\
+ ldrb r0, [r1, 0x3]\n\
+ cmp r0, 0x8\n\
+ beq _080A5736\n\
+ movs r0, 0x5\n\
+ bl PlaySE\n\
+ movs r0, 0x3\n\
+_080A56D2:\n\
+ bl MoveMenuCursor3\n\
+ strb r0, [r4]\n\
+ b _080A5736\n\
+ .align 2, 0\n\
+_080A56DC: .4byte sPopupMenuSelection\n\
+_080A56E0: .4byte sPopupMenuActionList\n\
+_080A56E4:\n\
+ ldrh r1, [r2, 0x2E]\n\
+ movs r0, 0x1\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ bne _080A5768\n\
+ movs r0, 0x2\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ beq _080A5736\n\
+ ldr r1, _080A574C @ =gTasks\n\
+ lsls r0, r4, 2\n\
+ adds r0, r4\n\
+ lsls r0, 3\n\
+ adds r0, r1\n\
+ strh r5, [r0, 0x1C]\n\
+ ldr r1, _080A5750 @ =gBagPocketScrollStates\n\
+ ldr r0, _080A5754 @ =sCurrentBagPocket\n\
+ ldrb r0, [r0]\n\
+ lsls r0, 24\n\
+ asrs r0, 24\n\
+ lsls r0, 2\n\
+ adds r0, r1\n\
+ ldrb r2, [r0]\n\
+ adds r0, r4, 0\n\
+ adds r1, r2, 0\n\
+ bl sub_80A48E8\n\
+ ldr r0, _080A5758 @ =gBGTilemapBuffers + 0x800\n\
+ bl sub_80A4DA4\n\
+ ldr r1, _080A575C @ =sItemPopupMenuActions\n\
+ ldr r0, _080A5760 @ =sPopupMenuActionList\n\
+ ldr r0, [r0]\n\
+ ldrb r0, [r0, 0x5]\n\
+ lsls r0, 3\n\
+ adds r1, 0x4\n\
+ adds r0, r1\n\
+ ldr r5, [r0]\n\
+ adds r0, r4, 0\n\
+ bl _call_via_r5\n\
+_080A5736:\n\
+ cmp r5, 0\n\
+ bne _080A57BE\n\
+ ldr r0, _080A5764 @ =sPopupMenuSelection\n\
+ ldrb r0, [r0]\n\
+ cmp r0, 0\n\
+ bne _080A57AC\n\
+ movs r0, 0xC\n\
+ bl sub_8072DDC\n\
+ b _080A57BE\n\
+ .align 2, 0\n\
+_080A574C: .4byte gTasks\n\
+_080A5750: .4byte gBagPocketScrollStates\n\
+_080A5754: .4byte sCurrentBagPocket\n\
+_080A5758: .4byte gBGTilemapBuffers + 0x800\n\
+_080A575C: .4byte sItemPopupMenuActions\n\
+_080A5760: .4byte sPopupMenuActionList\n\
+_080A5764: .4byte sPopupMenuSelection\n\
+_080A5768:\n\
+ ldr r1, _080A5798 @ =gTasks\n\
+ lsls r0, r4, 2\n\
+ adds r0, r4\n\
+ lsls r0, 3\n\
+ adds r0, r1\n\
+ strh r5, [r0, 0x1C]\n\
+ ldr r0, _080A579C @ =gBGTilemapBuffers + 0x800\n\
+ bl sub_80A4DA4\n\
+ ldr r1, _080A57A0 @ =sItemPopupMenuActions\n\
+ ldr r0, _080A57A4 @ =sPopupMenuSelection\n\
+ ldrb r2, [r0]\n\
+ ldr r0, _080A57A8 @ =sPopupMenuActionList\n\
+ ldr r0, [r0]\n\
+ adds r0, r2\n\
+ ldrb r0, [r0]\n\
+ lsls r0, 3\n\
+ adds r1, 0x4\n\
+ adds r0, r1\n\
+ ldr r5, [r0]\n\
+ adds r0, r4, 0\n\
+ bl _call_via_r5\n\
+ b _080A5736\n\
+ .align 2, 0\n\
+_080A5798: .4byte gTasks\n\
+_080A579C: .4byte gBGTilemapBuffers + 0x800\n\
+_080A57A0: .4byte sItemPopupMenuActions\n\
+_080A57A4: .4byte sPopupMenuSelection\n\
+_080A57A8: .4byte sPopupMenuActionList\n\
+_080A57AC:\n\
+ cmp r0, 0x2\n\
+ bhi _080A57B8\n\
+ movs r0, 0x2F\n\
+ bl sub_8072DCC\n\
+ b _080A57BE\n\
+_080A57B8:\n\
+ movs r0, 0x30\n\
+ bl sub_8072DCC\n\
+_080A57BE:\n\
+ pop {r4,r5}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .syntax divided\n");
+}
+
+static void sub_80A57C4(void)
+{
+ u8 r5;
+
+ sPopupMenuActionList = gUnknown_083C16AE[sCurrentBagPocket];
+ if (sCurrentBagPocket == BAG_POCKET_KEY_ITEMS)
+ {
+ gUnknown_02038564 = 1;
+ r5 = 9;
+ }
+ else if (sub_80F92F4(gScriptItemId) == 0)
+ {
+ sPopupMenuActionList = gUnknown_083C16AE[4];
+ gUnknown_02038564 = 1;
+ r5 = 9;
+ }
+ else
+ {
+ gUnknown_02038564 = 2;
+ r5 = 7;
+ }
+ sub_80A4008(gBGTilemapBuffers[1], 7, r5 + 1, 6, gUnknown_02038564 * 2);
+ MenuDrawTextWindow(6, r5, 13, gUnknown_02038564 * 2 + 1 + r5);
+ sub_80A7834(0, r5);
+ InitMenu(0, 7, r5 + 1, gUnknown_02038564, 0, 6);
+}
+
+static void sub_80A5888(u8 taskId)
+{
+ if (sub_80A78A0() != 0)
+ {
+ if (gMain.newAndRepeatedKeys & DPAD_UP)
+ {
+ if (sPopupMenuSelection != 0)
+ {
+ PlaySE(SE_SELECT);
+ sPopupMenuSelection = MoveMenuCursor(-1);
+ }
+ }
+ else if (gMain.newAndRepeatedKeys & DPAD_DOWN)
+ {
+ if (sPopupMenuSelection != gUnknown_02038564 - 1)
+ {
+ PlaySE(SE_SELECT);
+ sPopupMenuSelection = MoveMenuCursor(1);
+ }
+ }
+ else if (gMain.newKeys & A_BUTTON)
+ {
+ gTasks[taskId].data[10] = 0;
+ sub_80A48E8(taskId, gBagPocketScrollStates[sCurrentBagPocket].cursorPos, gBagPocketScrollStates[sCurrentBagPocket].cursorPos);
+ sub_80A4DA4(gBGTilemapBuffers[1]);
+ sItemPopupMenuActions[sPopupMenuActionList[sPopupMenuSelection]].func(taskId);
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ gTasks[taskId].data[10] = 0;
+ sub_80A4DA4(gBGTilemapBuffers[1]);
+ sItemPopupMenuActions[2].func(taskId);
+ }
+ }
+}
+
+static void OnBagClose_Field0(u8 taskId)
+{
+ gTasks[taskId].data[8] = (u32)sub_805469C >> 16;
+ gTasks[taskId].data[9] = (u32)sub_805469C;
+ gLastFieldPokeMenuOpened = 0;
+ sub_80A5AE4(taskId);
+}
+
+static void OnItemSelect_Field05(u8 taskId)
+{
+ sPopupMenuSelection = 0;
+ if (sReturnLocation == RETURN_TO_FIELD_5)
+ sPopupMenuSelection = 1;
+ gTasks[taskId].data[10] = gBagPocketScrollStates[sCurrentBagPocket].scrollTop + gBagPocketScrollStates[sCurrentBagPocket].cursorPos + 1;
+ sub_80A48E8(taskId, gBagPocketScrollStates[sCurrentBagPocket].cursorPos, gBagPocketScrollStates[sCurrentBagPocket].cursorPos);
+ sub_80A73FC();
+ if (sub_80F9344() == TRUE && sReturnLocation != RETURN_TO_FIELD_5)
+ {
+ sub_80A57C4();
+ gTasks[taskId].func = sub_80A5888;
+ }
+ else
+ {
+ sub_80A4BF0(gBGTilemapBuffers[1]);
+ if (sCurrentBagPocket != BAG_POCKET_BERRIES || sReturnLocation == RETURN_TO_FIELD_5)
+ gTasks[taskId].func = sub_80A5414;
+ else
+ gTasks[taskId].func = sub_80A5600;
+ }
+}
+
+static void sub_80A5AAC(u8 taskId)
+{
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0);
+ gTasks[taskId].func = HandleItemMenuPaletteFade;
+}
+
+static void sub_80A5AE4(u8 taskId)
+{
+ PlaySE(SE_SELECT);
+ sub_80A5AAC(taskId);
+}
+
+void HandleItemMenuPaletteFade(u8 taskId)
+{
+ s16 *taskData = gTasks[taskId].data;
+
+ if (!gPaletteFade.active)
+ {
+ MainCallback cb = (MainCallback)((u16)taskData[8] << 16 | (u16)taskData[9]);
+
+ SetMainCallback2(cb);
+ gpu_pal_allocator_reset__manage_upper_four();
+ DestroyTask(taskId);
+ }
+}
+
+void sub_80A5B40(void)
+{
+ while (1)
+ {
+ if (SetupBagMultistep() == TRUE)
+ {
+ ResetTasks();
+ gUnknown_02038563 = CreateTask(sub_80A50C8, 0);
+ break;
+ }
+ if (sub_80F9344() == TRUE)
+ break;
+ }
+}
+
+static void HandlePopupMenuAction_UseOnField(u8 taskId)
+{
+ if (ItemId_GetFieldFunc(gScriptItemId) != NULL)
+ {
+ PlaySE(SE_SELECT);
+ if (CalculatePlayerPartyCount() == 0 && ItemId_GetType(gScriptItemId) == 1)
+ {
+ sub_80A5BF8(taskId);
+ }
+ else
+ {
+ gTasks[taskId].data[2] = 0;
+ if (sCurrentBagPocket != BAG_POCKET_BERRIES)
+ ItemId_GetFieldFunc(gScriptItemId)(taskId);
+ else
+ sub_80C9C7C(taskId);
+ }
+ }
+}
+
+static void sub_80A5BF8(u8 taskId)
+{
+ sub_80A73FC();
+ sub_80A7590();
+ DisplayCannotUseItemMessage(taskId, gOtherText_NoPokemon, CleanUpItemMenuMessage, 1);
+}
+
+static void sub_80A5C24(u8 taskId)
+{
+ sub_80A7528(0);
+ sub_80A41D4(taskId);
+ ItemListMenu_InitMenu();
+ sub_80A37C0(taskId);
+}
+
+void CleanUpItemMenuMessage(u8 taskId)
+{
+ sub_80A36B8(gBGTilemapBuffers[1], 0, 0, 31, 31);
+ MenuZeroFillWindowRect(7, 7, 13, 12);
+ MenuZeroFillWindowRect(0, 14, 29, 19);
+ gTasks[taskId].func = sub_80A5C24;
+}
+
+void CleanUpOverworldMessage(u8 taskId)
+{
+ MenuZeroFillWindowRect(0, 13, 29, 19);
+ DestroyTask(taskId);
+ sub_8064E2C();
+ ScriptContext2_Disable();
+}
+
+void ExecuteItemUseFromBlackPalette(void)
+{
+ pal_fill_black();
+ CreateTask(Task_CallItemUseOnFieldCallback, 8);
+}
+
+static void Task_CallItemUseOnFieldCallback(u8 taskId)
+{
+ if (sub_807D770() == TRUE)
+ gFieldItemUseCallback(taskId);
+}
+
+void sub_80A5D04(void)
+{
+ while (1)
+ {
+ if (SetupBagMultistep() == TRUE)
+ {
+ gUnknown_02038563 = CreateTask(sub_80A50C8, 0);
+ break;
+ }
+ if (sub_80F9344() == TRUE)
+ break;
+ }
+}
+
+static void sub_80A5D38(u8 taskId)
+{
+ gTasks[taskId].data[1] = 0;
+ sub_80A4DA4(gBGTilemapBuffers[1]);
+ sub_80A7528(0);
+ sub_80A41D4(taskId);
+ ItemListMenu_InitMenu();
+ sub_80A37C0(taskId);
+}
+
+static void sub_80A5D78(void)
+{
+ sub_80A4008(gBGTilemapBuffers[1], 8, 8, 5, 4);
+ DisplayYesNoMenu(7, 7, 1);
+}
+
+static void sub_80A5DA0(u16 itemId, u16 quantity)
+{
+ CopyItemName(itemId, gStringVar1);
+ if (quantity >= 100)
+ ConvertIntToDecimalStringN(gStringVar2, quantity, STR_CONV_MODE_LEFT_ALIGN, 3);
+ else
+ ConvertIntToDecimalStringN(gStringVar2, quantity, STR_CONV_MODE_LEFT_ALIGN, 2);
+ sub_80A4DA4(gBGTilemapBuffers[1]);
+ sub_80A7528(5);
+ sub_80A5D78();
+}
+
+static void sub_80A5DF8(void)
+{
+ sub_80A4DA4(gBGTilemapBuffers[1]);
+ MenuZeroFillWindowRect(7, 6, 11, 13);
+ sub_80A7528(4);
+}
+
+static void sub_80A5E1C(u8 taskId)
+{
+ if ((gMain.newKeys & A_BUTTON) || (gMain.newKeys & B_BUTTON))
+ {
+ gTasks[taskId].data[10] = 0;
+ sub_80A41D4(taskId);
+ sub_80A5D38(taskId);
+ }
+}
+
+static void sub_80A5E60(u8 taskId)
+{
+ sub_80A5DF8();
+ sub_80A3D5C(taskId);
+ gTasks[taskId].func = sub_80A5E1C;
+}
+
+static void sub_80A5E90(u8 taskId)
+{
+ sub_80A5D38(taskId);
+}
+
+static void sub_80A5EA0(u8 taskId)
+{
+ if (sub_80A5350(taskId) == TRUE)
+ return;
+ if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ sub_80A5DA0(gScriptItemId, gTasks[taskId].data[1]);
+ DoYesNoFuncWithChoice(taskId, &gUnknown_083C16F4);
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ sub_80A5D38(taskId);
+ }
+}
+
+static void HandlePopupMenuAction_Toss(u8 taskId)
+{
+ PlaySE(SE_SELECT);
+ gTasks[taskId].func = sub_80A5EA0;
+ sub_80A7528(3);
+ // if (sCurrentBagPocket == BAG_POCKET_BERRIES) Can't get it to match this way
+ if (sCurrentBagPocket + 1 == BAG_POCKET_BERRIES + 1)
+ sub_80A4DD8(taskId, 6, 9, 7, 3, 3);
+ else
+ sub_80A4DD8(taskId, 7, 9, 6, 3, 2);
+}
+
+static void sub_80A5F80(u8 taskId)
+{
+ PlaySE(SE_SELECT);
+ sub_80A7528(0);
+ sub_80A41D4(taskId);
+ ItemListMenu_InitMenu();
+ sub_80A37C0(taskId);
+}
+
+static void HandlePopupMenuAction_Register(u8 taskId)
+{
+ PlaySE(SE_SELECT);
+ if (gSaveBlock1.registeredItem == gScriptItemId)
+ {
+ // Un-register the registered item
+ RemoveSelectIconFromRegisteredItem();
+ gSaveBlock1.registeredItem = 0;
+ }
+ else
+ {
+ AddSelectIconToRegisteredItem();
+ gSaveBlock1.registeredItem = gScriptItemId;
+ }
+ sub_80A7528(0);
+ sub_80A41D4(taskId);
+ ItemListMenu_InitMenu();
+ sub_80A37C0(taskId);
+}
+
+static void sub_80A6000(u8 taskId)
+{
+ sub_80A7528(0);
+ sub_80A41D4(taskId);
+ ItemListMenu_InitMenu();
+ sub_80A37C0(taskId);
+}
+
+static void sub_80A6024(u8 taskId)
+{
+ if (gMain.newKeys & A_BUTTON)
+ {
+ sub_80A36B8(gBGTilemapBuffers[1], 0, 0, 31, 31);
+ MenuZeroFillWindowRect(0, 14, 29, 19);
+ gTasks[taskId].func = sub_80A6000;
+ }
+}
+
+static void DisplayCannotBeHeldMessage(u8 taskId)
+{
+ sub_80A73FC();
+ CopyItemName(gScriptItemId, gStringVar1);
+ StringExpandPlaceholders(gStringVar4, gOtherText_CantBeHeld);
+ sub_80A7590();
+ DisplayCannotUseItemMessage(taskId, gStringVar4, sub_80A6024, 1);
+}
+
+static void HandlePopupMenuAction_Give(u8 taskId)
+{
+ PlaySE(SE_SELECT);
+ if (sub_80F931C(gScriptItemId) == 0)
+ {
+ sub_80A73FC();
+ sub_80A7590();
+ DisplayCannotUseItemMessage(taskId, gOtherText_CantWriteMail, sub_80A6024, 1);
+ }
+ else if (ItemId_GetImportance(gScriptItemId) == 0)
+ {
+ if (CalculatePlayerPartyCount() == 0)
+ {
+ sub_80A5BF8(taskId);
+ }
+ else
+ {
+ gTasks[taskId].data[8] = (u32)sub_808B020 >> 16;
+ gTasks[taskId].data[9] = (u32)sub_808B020;
+ gTasks[taskId].func = HandleItemMenuPaletteFade;
+ gUnknown_02038561 = 1;
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0);
+ }
+ }
+ else
+ {
+ DisplayCannotBeHeldMessage(taskId);
+ }
+}
+
+static void HandlePopupMenuAction_CheckTag(u8 taskId)
+{
+ sub_80A5AE4(taskId);
+ gTasks[taskId].data[8] = (u32)BerryTagScreen_814625C >> 16;
+ gTasks[taskId].data[9] = (u32)BerryTagScreen_814625C;
+}
+
+static void sub_80A61A8(void)
+{
+ if (sub_80A34B4() == TRUE)
+ gUnknown_02038563 = CreateTask(sub_80A50C8, 0);
+}
+
+void sub_80A61D0(void)
+{
+ sReturnLocation = RETURN_TO_PKMN_LIST;
+ SetMainCallback2(sub_80A61A8);
+}
+
+static void OnBagClose_PkmnList(u8 taskId)
+{
+ gTasks[taskId].data[8] = (u32)sub_808A3F8 >> 16;
+ gTasks[taskId].data[9] = (u32)sub_808A3F8;
+ sub_80A5AE4(taskId);
+}
+
+static void OnItemSelect_PkmnList(u8 taskId)
+{
+ u8 r6 = sCurrentBagPocket + 1;
+
+ if (sub_80F931C(gScriptItemId) == 0)
+ {
+ sub_80A73FC();
+ sub_80A7590();
+ DisplayCannotUseItemMessage(taskId, gOtherText_CantWriteMail, sub_80A6024, 1);
+ }
+ else if (sub_80F92F4(gScriptItemId) == 0)
+ {
+ sub_80A73FC();
+ CopyItemName(gScriptItemId, gStringVar1);
+ StringExpandPlaceholders(gStringVar4, gOtherText_CantBeHeldHere);
+ sub_80A7590();
+ DisplayCannotUseItemMessage(taskId, gStringVar4, sub_80A6024, 1);
+ }
+ else if (r6 != 5 && ItemId_GetImportance(gScriptItemId) == 0)
+ {
+ gTasks[taskId].data[8] = (u32)sub_808A3F8 >> 16;
+ gTasks[taskId].data[9] = (u32)sub_808A3F8;
+ sub_80A5AAC(taskId);
+ }
+ else
+ {
+ DisplayCannotBeHeldMessage(taskId);
+ }
+}
+
+static void sub_80A62D8(void)
+{
+ if (sub_80A34B4() == TRUE)
+ gUnknown_02038563 = CreateTask(sub_80A50C8, 0);
+}
+
+void sub_80A6300(void)
+{
+ sReturnLocation = RETURN_TO_SHOP;
+ SetMainCallback2(sub_80A62D8);
+}
+
+static void OnBagClose_Shop(u8 taskId)
+{
+ gFieldCallback = sub_80B3050;
+ gTasks[taskId].data[8] = (u32)c2_exit_to_overworld_2_switch >> 16;
+ gTasks[taskId].data[9] = (u32)c2_exit_to_overworld_2_switch;
+ sub_80A5AE4(taskId);
+}
+
+static void OnItemSelect_Shop(u8 taskId)
+{
+ sub_80A7590();
+ gTasks[taskId].data[10] = gBagPocketScrollStates[sCurrentBagPocket].scrollTop + gBagPocketScrollStates[sCurrentBagPocket].cursorPos + 1;
+ sub_80A48E8(taskId, gBagPocketScrollStates[sCurrentBagPocket].cursorPos, gBagPocketScrollStates[sCurrentBagPocket].cursorPos);
+ sub_80A73FC();
+ CopyItemName(gScriptItemId, gStringVar2);
+ if (ItemId_GetPrice(gScriptItemId) == 0)
+ {
+ StringExpandPlaceholders(gStringVar4, gOtherText_CantBuyThat);
+ DisplayCannotUseItemMessage(taskId, gStringVar4, sub_80A6444, 1);
+ }
+ else
+ {
+ StringExpandPlaceholders(gStringVar4, gOtherText_HowManyToSell);
+ DisplayCannotUseItemMessage(taskId, gStringVar4, sub_80A648C, 1);
+ }
+}
+
+static void sub_80A640C(u8 taskId)
+{
+ gTasks[taskId].data[10] = 0;
+ sub_80A7528(0);
+ sub_80A41D4(taskId);
+ ItemListMenu_InitMenu();
+ sub_80A37C0(taskId);
+}
+
+static void sub_80A6444(u8 taskId)
+{
+ sub_80A36B8(gBGTilemapBuffers[1], 0, 0, 31, 31);
+ MenuZeroFillWindowRect(0, 14, 29, 19);
+ gTasks[taskId].func = sub_80A640C;
+}
+
+static void sub_80A648C(u8 taskId)
+{
+ gTasks[taskId].func = Task_BuyHowManyDialogueHandleInput;
+ sub_80A4008(gBGTilemapBuffers[1], 1, 11, 12, 2);
+ MenuDrawTextWindow(0, 10, 13, 13);
+ gTasks[taskId].data[1] = 1;
+ gTasks[taskId].data[2] = 1;
+ gTasks[taskId].data[3] = 11;
+ // if (sCurrentBagPocket == BAG_POCKET_BERRIES) Can't get it to match this way
+ if (sCurrentBagPocket + 1 == BAG_POCKET_BERRIES + 1)
+ sub_80A418C(1, 1, 1, 11, 3);
+ else
+ sub_80A418C(1, 1, 1, 11, 2);
+ BuyMenuDisplayMessage(gScriptItemId, 1);
+ sub_80A683C();
+}
+
+static void sub_80A6520(u8 taskId)
+{
+ if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ BuyMenuPrintItemQuantityAndPrice(taskId);
+ }
+}
+
+static void sub_80A6548(u8 taskId)
+{
+ sub_80A48F8(taskId);
+ gTasks[taskId].func = sub_80A6520;
+}
+
+static void sub_80A6574(u8 taskId)
+{
+ PlaySE(SE_REGI);
+ sub_80A6870(gScriptItemId, gTasks[taskId].data[1]);
+ gTasks[taskId].func = sub_80A6548;
+}
+
+static void sub_80A65AC(u8 taskId)
+{
+ MenuZeroFillWindowRect(7, 6, 13, 12);
+ sub_80A36B8(gBGTilemapBuffers[1], 7, 6, 6, 6);
+ CopyItemName(gScriptItemId, gStringVar2);
+ StringExpandPlaceholders(gStringVar4, gOtherText_SoldItem);
+ DisplayCannotUseItemMessage(taskId, gStringVar4, sub_80A6574, 1);
+ sub_80A3D5C(taskId);
+}
+
+static void sub_80A6618(u8 taskId)
+{
+ MenuZeroFillWindowRect(7, 6, 13, 12);
+ sub_80A36B8(gBGTilemapBuffers[1], 7, 6, 6, 6);
+ BuyMenuPrintItemQuantityAndPrice(taskId);
+}
+
+static void sub_80A6650(u8 taskId)
+{
+ sub_80A5D78();
+ DoYesNoFuncWithChoice(taskId, &gUnknown_083C16FC);
+}
+
+static void Task_BuyHowManyDialogueHandleInput(u8 taskId)
+{
+ if (sub_80A5350(taskId) == TRUE)
+ {
+ MenuZeroFillWindowRect(6, 11, 12, 11);
+ BuyMenuDisplayMessage(gScriptItemId, gTasks[taskId].data[1]);
+ }
+ else if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ MenuZeroFillWindowRect(0, 10, 13, 13);
+ sub_80A36B8(gBGTilemapBuffers[1], 0, 10, 13, 3);
+ ConvertIntToDecimalStringN(gStringVar1, ItemId_GetPrice(gScriptItemId) / 2 * gTasks[taskId].data[1], STR_CONV_MODE_LEFT_ALIGN, 6);
+ StringExpandPlaceholders(gStringVar4, gOtherText_CanPay);
+ DisplayCannotUseItemMessage(taskId, gStringVar4, sub_80A6650, 1);
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ BuyMenuPrintItemQuantityAndPrice(taskId);
+ }
+}
+
+static void sub_80A6760(u8 taskId)
+{
+ gTasks[taskId].data[10] = 0;
+ sub_80A7528(0);
+ sub_80A41D4(taskId);
+ ItemListMenu_InitMenu();
+ sub_80A37C0(taskId);
+}
+
+static void BuyMenuPrintItemQuantityAndPrice(u8 taskId)
+{
+ sub_80A36B8(gBGTilemapBuffers[1], 0, 0, 31, 31);
+ CloseMoneyWindow(0, 0);
+ MenuZeroFillWindowRect(0, 4, 13, 13);
+ MenuZeroFillWindowRect(0, 14, 29, 19);
+ gTasks[taskId].func = sub_80A6760;
+}
+
+static void BuyMenuDisplayMessage(u16 itemId, u16 quantity)
+{
+ PrintMoneyAmount(ItemId_GetPrice(itemId) / 2 * quantity, 6, 6, 11);
+ ConvertIntToDecimalStringN(gStringVar1, ItemId_GetPrice(itemId) / 2 * quantity, STR_CONV_MODE_LEFT_ALIGN, 6);
+}
+
+static void sub_80A683C(void)
+{
+ OpenMoneyWindow(gSaveBlock1.money, 0, 0);
+ sub_80A4008(gBGTilemapBuffers[1], 1, 1, 12, 2);
+}
+
+static void sub_80A6870(u16 itemId, u8 quantity)
+{
+ AddMoney(&gSaveBlock1.money, ItemId_GetPrice(itemId) / 2 * quantity);
+ UpdateMoneyWindow(gSaveBlock1.money, 0, 0);
+}
+
+static void sub_80A68A4(void)
+{
+ if (sub_80A34B4() == TRUE)
+ gUnknown_02038563 = CreateTask(sub_80A50C8, 0);
+}
+
+void sub_80A68CC(void)
+{
+ sCurrentBagPocket = BAG_POCKET_BERRIES;
+ sReturnLocation = RETURN_TO_FIELD_4;
+ SetMainCallback2(sub_80A68A4);
+}
+
+static void OnBagClose_Field4(u8 taskId)
+{
+ gTasks[taskId].data[8] = (u32)sub_80546B8 >> 16;
+ gTasks[taskId].data[9] = (u32)sub_80546B8;
+ sub_80A5AE4(taskId);
+}
+
+static void OnItemSelect_Field4(u8 taskId)
+{
+ gTasks[taskId].data[8] = (u32)sub_80546B8 >> 16;
+ gTasks[taskId].data[9] = (u32)sub_80546B8;
+ sub_80A5AAC(taskId);
+}
+
+static void sub_80A6940(void)
+{
+ while (1)
+ {
+ if (SetupBagMultistep() == TRUE)
+ {
+ gUnknown_02038563 = CreateTask(sub_80A50C8, 0);
+ sub_80A699C();
+ break;
+ }
+ if (sub_80F9344() == TRUE)
+ break;
+ }
+}
+
+void sub_80A6978(void)
+{
+ sCurrentBagPocket = BAG_POCKET_BERRIES;
+ sReturnLocation = RETURN_TO_FIELD_5;
+ SetMainCallback2(sub_80A6940);
+}
+
+static void sub_80A699C(void)
+{
+ sPopupMenuActionList = gUnknown_083C16B8;
+ gUnknown_02038564 = 4;
+}
+
+static void OnBagClose_Field5(u8 taskId)
+{
+ gTasks[taskId].data[8] = (u32)sub_804E990 >> 16;
+ gTasks[taskId].data[9] = (u32)sub_804E990;
+ sub_80A5AE4(taskId);
+}
+
+static void HandlePopupMenuAction_Confirm(u8 taskId)
+{
+ gTasks[taskId].data[8] = (u32)sub_804E990 >> 16;
+ gTasks[taskId].data[9] = (u32)sub_804E990;
+ sub_80A5AAC(taskId);
+}
+
+static void sub_80A6A08(void)
+{
+ if (sub_80A34B4() == TRUE)
+ gUnknown_02038563 = CreateTask(sub_80A50C8, 0);
+}
+
+void sub_80A6A30(void)
+{
+ sReturnLocation = RETURN_TO_PC;
+ SetMainCallback2(sub_80A6A08);
+}
+
+static void OnBagClose_PC(u8 taskId)
+{
+ gFieldCallback = ItemStorage_ReturnToMenuAfterDeposit;
+ gTasks[taskId].data[8] = (u32)c2_exit_to_overworld_2_switch >> 16;
+ gTasks[taskId].data[9] = (u32)c2_exit_to_overworld_2_switch;
+ sub_80A5AE4(taskId);
+}
+
+static void sub_80A6A84(u8 taskId)
+{
+ s16 *taskData = gTasks[taskId].data;
+
+ sub_80A4DA4(gBGTilemapBuffers[1]);
+ CopyItemName(gScriptItemId, gStringVar1);
+ ConvertIntToDecimalStringN(gStringVar2, taskData[1], STR_CONV_MODE_LEFT_ALIGN, 3);
+ MenuZeroFillWindowRect(7, 6, 11, 13);
+ sub_80A7528(7);
+ sub_80A3D5C(taskId);
+ gTasks[taskId].func = sub_80A5E1C;
+}
+
+static void sub_80A6B00(u8 taskId)
+{
+ if ((gMain.newKeys & A_BUTTON) || (gMain.newKeys & B_BUTTON))
+ {
+ gTasks[taskId].data[10] = 0;
+ sub_80A48E8(taskId, gBagPocketScrollStates[sCurrentBagPocket].cursorPos, gBagPocketScrollStates[sCurrentBagPocket].cursorPos);
+ PlaySE(SE_SELECT);
+ sub_80A5D38(taskId);
+ }
+}
+
+static void sub_80A6B64(u8 taskId)
+{
+ s16 *taskData = gTasks[taskId].data;
+
+ if (ItemId_GetImportance(gScriptItemId) == 2)
+ {
+ gTasks[taskId].func = sub_80A6B00;
+ sub_80A7528(9);
+ }
+ else
+ {
+ if (AddPCItem(gScriptItemId, taskData[1]) == TRUE)
+ {
+ sub_80A6A84(taskId);
+ }
+ else
+ {
+ gTasks[taskId].func = sub_80A6B00;
+ sub_80A7528(8);
+ }
+ }
+}
+
+static void sub_80A6BE0(u8 taskId)
+{
+ if (sub_80A5350(taskId) == TRUE)
+ return;
+ if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ sub_80A4DA4(gBGTilemapBuffers[1]);
+ sub_80A6B64(taskId);
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ gTasks[taskId].data[10] = 0;
+ sub_80A48E8(taskId, gBagPocketScrollStates[sCurrentBagPocket].cursorPos, gBagPocketScrollStates[sCurrentBagPocket].cursorPos);
+ PlaySE(SE_SELECT);
+ sub_80A5D38(taskId);
+ }
+}
+
+static void OnItemSelect_PC(u8 taskId)
+{
+ gTasks[taskId].data[10] = gBagPocketScrollStates[sCurrentBagPocket].scrollTop + gBagPocketScrollStates[sCurrentBagPocket].cursorPos + 1;
+ sub_80A48E8(taskId, gBagPocketScrollStates[sCurrentBagPocket].cursorPos, gBagPocketScrollStates[sCurrentBagPocket].cursorPos);
+ sub_80A73FC();
+ PlaySE(SE_SELECT);
+ sub_80A7590();
+ if (sCurrentBagPocket != BAG_POCKET_KEY_ITEMS)
+ {
+ gTasks[taskId].func = sub_80A6BE0;
+ sub_80A7528(6);
+ // if (sCurrentBagPocket == BAG_POCKET_BERRIES) Can't get it to match this way
+ if (sCurrentBagPocket + 1 == BAG_POCKET_BERRIES + 1)
+ sub_80A4DD8(taskId, 6, 9, 7, 3, 3);
+ else
+ sub_80A4DD8(taskId, 7, 9, 6, 3, 2);
+ }
+ else
+ {
+ gTasks[taskId].data[1] = 1;
+ sub_80A6B64(taskId);
+ }
+}
+
+bool32 sub_80A6D1C(void)
+{
+ HideMapNamePopup();
+ if (gSaveBlock1.registeredItem != 0)
+ {
+ if (CheckBagHasItem(gSaveBlock1.registeredItem, 1) == TRUE)
+ {
+ u8 taskId;
+
+ ScriptContext2_Enable();
+ FreezeMapObjects();
+ sub_80594C0();
+ sub_80597F4();
+ gScriptItemId = gSaveBlock1.registeredItem;
+ taskId = CreateTask(ItemId_GetFieldFunc(gSaveBlock1.registeredItem), 8);
+ gTasks[taskId].data[2] = 1;
+ return TRUE;
+ }
+ gSaveBlock1.registeredItem = 0;
+ }
+ ScriptContext1_SetupScript(Event_NoRegisteredItem);
+ return TRUE;
+}
+
+static void sub_80A6D98(void)
+{
+ while (1)
+ {
+ if (SetupBagMultistep() == TRUE)
+ {
+ gUnknown_02038563 = CreateTask(sub_80A50C8, 0);
+ break;
+ }
+ if (sub_80F9344() == TRUE)
+ break;
+ }
+}
+
+void sub_80A6DCC(void)
+{
+ sPopupMenuSelection = 0;
+ sReturnLocation = RETURN_TO_BATTLE;
+ SetMainCallback2(sub_80A6D98);
+}
+
+static void sub_80A6DF0(u16 *a)
+{
+ u8 r6 = (gUnknown_02038564 - 1) * 2;
+
+ MenuDrawTextWindow(7, 9 - r6, 13, 12);
+ sub_80A4008(a, 8, 10 - r6, 5, r6 + 2);
+ if (gUnknown_02038564 == 1)
+ {
+ MenuPrint(sItemPopupMenuActions[sPopupMenuActionList[0]].text, 8, 10);
+ }
+ else
+ {
+ MenuPrint(sItemPopupMenuActions[sPopupMenuActionList[0]].text, 8, 8);
+ MenuPrint(sItemPopupMenuActions[sPopupMenuActionList[1]].text, 8, 10);
+ }
+ InitMenu(0, 8, 10 - r6, gUnknown_02038564, 0, 5);
+ sub_80A7528(2);
+}
+
+static void sub_80A6EB8(u8 taskId)
+{
+ if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_UP)
+ {
+ if (sPopupMenuSelection == 1)
+ {
+ PlaySE(SE_SELECT);
+ sPopupMenuSelection = MoveMenuCursor(-1);
+ }
+ }
+ else if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_DOWN)
+ {
+ if (sPopupMenuSelection + 1 < gUnknown_02038564)
+ {
+ PlaySE(SE_SELECT);
+ sPopupMenuSelection = MoveMenuCursor(1);
+ }
+ }
+ else if (gMain.newKeys & A_BUTTON)
+ {
+ gTasks[taskId].data[10] = 0;
+ sub_80A48E8(taskId, gBagPocketScrollStates[sCurrentBagPocket].cursorPos, gBagPocketScrollStates[sCurrentBagPocket].cursorPos);
+ sub_80A4DA4(gBGTilemapBuffers[1]);
+ sItemPopupMenuActions[sPopupMenuActionList[sPopupMenuSelection]].func(taskId);
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ gTasks[taskId].data[10] = 0;
+ sub_80A48E8(taskId, gBagPocketScrollStates[sCurrentBagPocket].cursorPos, gBagPocketScrollStates[sCurrentBagPocket].cursorPos);
+ sub_80A4DA4(gBGTilemapBuffers[1]);
+ sItemPopupMenuActions[5].func(taskId);
+ }
+}
+
+static const u8 gUnknown_083C1708[] = {4, 5};
+static const u8 gUnknown_083C170A[] = {5, 0};
+
+static void sub_80A6FDC(void)
+{
+ if (ItemId_GetBattleUsage(gScriptItemId) != 0)
+ {
+ sPopupMenuActionList = gUnknown_083C1708;
+ gUnknown_02038564 = 2;
+ }
+ else
+ {
+ sPopupMenuActionList = gUnknown_083C170A;
+ gUnknown_02038564 = 1;
+ }
+}
+
+static void OnItemSelect_Battle(u8 taskId)
+{
+ sPopupMenuSelection = 0;
+ sub_80A6FDC();
+ gTasks[taskId].data[10] = gBagPocketScrollStates[sCurrentBagPocket].scrollTop + gBagPocketScrollStates[sCurrentBagPocket].cursorPos + 1;
+ sub_80A48E8(taskId, gBagPocketScrollStates[sCurrentBagPocket].cursorPos, gBagPocketScrollStates[sCurrentBagPocket].cursorPos);
+ sub_80A73FC();
+ sub_80A6DF0(gBGTilemapBuffers[1]);
+ gTasks[taskId].func = sub_80A6EB8;
+}
+
+void sub_80A7094(u8 taskId)
+{
+ gTasks[taskId].data[8] = (u32)sub_802E424 >> 16;
+ gTasks[taskId].data[9] = (u32)sub_802E424;
+ gTasks[taskId].func = HandleItemMenuPaletteFade;
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0);
+}
+
+static void OnBagClose_Battle(u8 taskId)
+{
+ PlaySE(SE_SELECT);
+ sub_80A7094(taskId);
+}
+
+static void HandlePopupMenuAction_UseInBattle(u8 taskId)
+{
+ if (ItemId_GetBattleFunc(gScriptItemId) != NULL)
+ {
+ PlaySE(SE_SELECT);
+ ItemId_GetBattleFunc(gScriptItemId)(taskId);
+ }
+}
+
+static void sub_80A7124(u8 taskId)
+{
+ PlaySE(SE_SELECT);
+ sub_80A7528(0);
+ sub_80A41D4(taskId);
+ ItemListMenu_InitMenu();
+ sub_80A37C0(taskId);
+}
+
+static void sub_80A7150(void)
+{
+ while (1)
+ {
+ if (SetupBagMultistep() == TRUE)
+ {
+ gUnknown_02038563 = CreateTask(sub_80A7230, 0);
+ gTasks[gUnknown_02038563].data[15] = 0;
+ break;
+ }
+ if (sub_80F9344() == TRUE)
+ break;
+ }
+}
+
+void PrepareBagForWallyTutorial(void)
+{
+ u8 i;
+
+ sPopupMenuSelection = 0;
+ sCurrentBagPocket = BAG_POCKET_ITEMS;
+ for (i = 0; i < 5; i++)
+ {
+ gBagPocketScrollStates[i].cursorPos = 0;
+ gBagPocketScrollStates[i].scrollTop = 0;
+ }
+
+ // Save player's items
+ memcpy(ewramSavedItemsPocket, gSaveBlock1.bagPocket_Items, sizeof(gSaveBlock1.bagPocket_Items));
+ memcpy(ewramSavedPokeballsPocket, gSaveBlock1.bagPocket_PokeBalls, sizeof(gSaveBlock1.bagPocket_PokeBalls));
+
+ // Add Wally's items to the bag
+ ClearItemSlots(gSaveBlock1.bagPocket_Items, ARRAY_COUNT(gSaveBlock1.bagPocket_Items));
+ ClearItemSlots(gSaveBlock1.bagPocket_PokeBalls, ARRAY_COUNT(gSaveBlock1.bagPocket_PokeBalls));
+ AddBagItem(ITEM_POTION, 1);
+ AddBagItem(ITEM_POKE_BALL, 1);
+
+ sReturnLocation = RETURN_TO_WALLY_BATTLE;
+ SetMainCallback2(sub_80A7150);
+}
+
+static void sub_80A7230(u8 taskId)
+{
+ s16 *taskData = gTasks[taskId].data;
+
+ switch (taskData[15])
+ {
+ case 102:
+ PlaySE(SE_SELECT);
+ sub_80A4E8C(1, 2);
+ break;
+ case 204:
+ PlaySE(SE_SELECT);
+ sub_80F98A4(2);
+ sub_80F98A4(3);
+ gScriptItemId = ITEM_POKE_BALL;
+ sPopupMenuActionList = gUnknown_083C1708;
+ gUnknown_02038564 = 2;
+ gTasks[taskId].data[10] = gBagPocketScrollStates[sCurrentBagPocket].scrollTop + gBagPocketScrollStates[sCurrentBagPocket].cursorPos + 1;
+ sub_80A48E8(taskId, gBagPocketScrollStates[sCurrentBagPocket].cursorPos, gBagPocketScrollStates[sCurrentBagPocket].cursorPos);
+ sub_80A73FC();
+ sub_80A6DF0(gBGTilemapBuffers[1]);
+ break;
+ case 306:
+ PlaySE(SE_SELECT);
+ sub_80A4DA4(gBGTilemapBuffers[1]);
+
+ // Restore player's items
+ memcpy(gSaveBlock1.bagPocket_Items, ewramSavedItemsPocket, sizeof(gSaveBlock1.bagPocket_Items));
+ memcpy(gSaveBlock1.bagPocket_PokeBalls, ewramSavedPokeballsPocket, sizeof(gSaveBlock1.bagPocket_PokeBalls));
+
+ taskData[8] = (u32)sub_802E424 >> 16;
+ taskData[9] = (u32)sub_802E424;
+ gTasks[taskId].func = HandleItemMenuPaletteFade;
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0);
+ return;
+ }
+ taskData[15]++;
+}
+
+static void ItemListMenu_InitMenu(void)
+{
+ InitMenu(0, 14, 2, gBagPocketScrollStates[sCurrentBagPocket].cursorMax + 1, gBagPocketScrollStates[sCurrentBagPocket].cursorPos, 0);
+ CreateBlendedOutlineCursor(16, 0xFFFF, 12, 0x2D9F, 15);
+ sub_80A73C0();
+}
+
+static void sub_80A73C0(void)
+{
+ sub_814AD7C(0x70, gBagPocketScrollStates[sCurrentBagPocket].cursorPos * 16 + 16);
+}
+
+static void sub_80A73F0(void)
+{
+ sub_814ADC8();
+}
+
+static void sub_80A73FC(void)
+{
+ HandleDestroyMenuCursors();
+ sub_814AD44();
+}
+
+static void sub_80A740C(void)
+{
+ sub_80A75E4();
+ sub_80A7768();
+ sub_80A7420();
+}
+
+static void sub_80A7420(void)
+{
+ struct UnknownStruct2 *unkStruct = &gUnknown_0203853C;
+ int index;
+
+ switch (unkStruct->unk0)
+ {
+ case 3:
+ unkStruct->unk0 = 2;
+ break;
+ case 2:
+ switch (unkStruct->unk2)
+ {
+ case 0:
+ index = gBagPocketScrollStates[sCurrentBagPocket].scrollTop + gBagPocketScrollStates[sCurrentBagPocket].cursorPos;
+ ItemListMenu_ChangeDescription(gCurrentBagPocketItemSlots[index].itemId, unkStruct->textLine);
+ break;
+ case 1:
+ sub_80A4A98(gOtherText_SwitchWhichItem, unkStruct->textLine);
+ break;
+ case 2:
+ sub_80A4A98(gOtherText_WhatWillYouDo2, unkStruct->textLine);
+ break;
+ case 3:
+ sub_80A4A98(gOtherText_HowManyToToss, unkStruct->textLine);
+ break;
+ case 4:
+ sub_80A4A98(gOtherText_ThrewAwayItem, unkStruct->textLine);
+ break;
+ case 5:
+ sub_80A4A98(gOtherText_OkayToThrowAwayPrompt, unkStruct->textLine);
+ break;
+ case 6:
+ sub_80A4A98(gOtherText_HowManyToDeposit, unkStruct->textLine);
+ break;
+ case 7:
+ sub_80A4A98(gOtherText_DepositedItems, unkStruct->textLine);
+ break;
+ case 8:
+ sub_80A4A98(gOtherText_NoRoomForItems, unkStruct->textLine);
+ break;
+ case 9:
+ sub_80A4A98(gOtherText_CantStoreSomeoneItem, unkStruct->textLine);
+ break;
+ }
+ unkStruct->textLine++;
+ if (unkStruct->textLine == 3)
+ {
+ unkStruct->unk0 = 0;
+ sub_80A7918();
+ }
+ break;
+ }
+}
+
+static void sub_80A751C(void)
+{
+ gUnknown_0203853C.unk0 = 0;
+}
+
+static void sub_80A7528(u8 a)
+{
+ gUnknown_0203853C.textLine = 0;
+ gUnknown_0203853C.unk2 = a;
+ switch (sub_80A78F4())
+ {
+ case 0:
+ gUnknown_0203853C.unk0 = 2;
+ while (gUnknown_0203853C.unk0 != 0)
+ sub_80A7420();
+ break;
+ case 1:
+ gUnknown_0203853C.unk0 = 3;
+ break;
+ case 2:
+ gUnknown_0203853C.unk0 = 1;
+ break;
+ }
+}
+
+static void sub_80A756C(void)
+{
+ if (gUnknown_0203853C.unk0 == 2 || gUnknown_0203853C.unk0 == 3)
+ sub_80A7918();
+ gUnknown_0203853C.unk0 = 0;
+}
+
+static void sub_80A7590(void)
+{
+ MenuZeroFillWindowRect(0, 13, 13, 20);
+ sub_80A756C();
+}
+
+static void sub_80A75A8(void)
+{
+ if (gUnknown_0203853C.unk0 == 2 || gUnknown_0203853C.unk0 == 3)
+ gUnknown_0203853C.unk0 = 1;
+}
+
+static void sub_80A75C4(void)
+{
+ switch (gUnknown_0203853C.unk0)
+ {
+ case 1:
+ gUnknown_0203853C.unk0 = 3;
+ break;
+ case 0:
+ sub_80A7918();
+ break;
+ }
+}
+
+static void sub_80A75E4(void)
+{
+ if (gUnknown_02038540.unk0 == 1 && sub_80A7988() == 0)
+ {
+ int r1;
+
+ sub_80A47E8(gUnknown_02038563, gUnknown_02038540.unk1, gUnknown_02038540.unk1, 1);
+ gUnknown_02038540.unk1++;
+ if (gUnknown_02038540.unk2 != 0)
+ r1 = 5;
+ else
+ r1 = 7;
+ if (r1 < gUnknown_02038540.unk1)
+ {
+ gUnknown_02038540.unk0 = 0;
+ sub_80A78E8();
+ }
+ }
+}
+
+static void sub_80A7630(void)
+{
+ gUnknown_02038540.unk0 = 0;
+}
+
+static void sub_80A763C(void)
+{
+ struct UnknownStruct3 *r4 = &gUnknown_02038540;
+
+ switch (sub_80A78C4())
+ {
+ case FALSE:
+ sub_80A48E8(gUnknown_02038563, 0, 7);
+ break;
+ case TRUE:
+ r4->unk0 = 1;
+ r4->unk1 = 0;
+ r4->unk2 = 0;
+ break;
+ }
+}
+
+static void sub_80A7678(void)
+{
+ if (gUnknown_02038540.unk0 == 1)
+ sub_80A78E8();
+ gUnknown_02038540.unk0 = 0;
+}
+
+static void sub_80A7694(void)
+{
+ gUnknown_02038540.unk2 = 1;
+}
+
+static void sub_80A76A0(void)
+{
+ MenuZeroFillWindowRect(14, 2, 29, 18);
+ sub_80A7678();
+}
+
+static bool32 sub_80A76B8(void)
+{
+ struct UnknownStruct3 *s = &gUnknown_02038540;
+
+ return (s->unk0 == 0);
+}
+
+static bool32 sub_80A76D0(void)
+{
+ struct UnknownStruct3 *s = &gUnknown_02038540;
+
+ return (s->unk1 > 5);
+}
+
+static void sub_80A76E8(void)
+{
+ if (gUnknown_02038544.unk0 == 1)
+ {
+ DisplayItemMessageOnField(
+ gUnknown_02038544.unk1,
+ gUnknown_02038544.unk4,
+ gUnknown_02038544.unk8,
+ gUnknown_02038544.unk2);
+ gUnknown_02038544.unk0 = 0;
+ }
+}
+
+static void sub_80A770C(void)
+{
+ gUnknown_02038544.unk0 = 0;
+}
+
+static void DisplayCannotUseItemMessage(int a, const u8 *b, TaskFunc func, int d)
+{
+ struct UnknownStruct4 *r4 = &gUnknown_02038544;
+
+ switch (sub_80A7924())
+ {
+ case 0:
+ DisplayItemMessageOnField(a, b, func, d);
+ break;
+ case 2:
+ r4->unk0 = 1;
+ r4->unk1 = a;
+ r4->unk4 = b;
+ r4->unk8 = func;
+ r4->unk2 = d;
+ break;
+ }
+}
+
+static void sub_80A7768(void)
+{
+ struct UnknownStruct5 *r4 = &gUnknown_02038550;
+
+ if (r4->unk0 == 2)
+ {
+ if (r4->unk1 != 0)
+ {
+ if (r4->unk2 != 1)
+ {
+ const u8 *text = sItemPopupMenuActions[sPopupMenuActionList[r4->unk1 - 1]].text;
+ int var = r4->unk1 - 1;
+
+ MenuPrint(text, 7, var * 2 + 1 + r4->unk3);
+ }
+ else
+ {
+ const u8 *text;
+ int var;
+
+ if (r4->unk1 == 1)
+ text = sub_80A4B90(gScriptItemId);
+ else
+ text = sItemPopupMenuActions[sPopupMenuActionList[r4->unk1 - 1]].text;
+ var = r4->unk1 - 1;
+ MenuPrint(text, (var >> 1) * 6 + 1, (var & 1) * 2 + 8);
+ }
+ if (r4->unk1 == gUnknown_02038564)
+ {
+ r4->unk0 = 0;
+ sub_80A7970();
+ }
+ }
+ r4->unk1++;
+ }
+}
+
+static void sub_80A7828(void)
+{
+ gUnknown_02038550.unk0 = 0;
+}
+
+static void sub_80A7834(int a, int b)
+{
+ struct UnknownStruct5 *r4 = &gUnknown_02038550;
+
+ switch (sub_80A7958())
+ {
+ case 1:
+ r4->unk0 = 2;
+ r4->unk1 = 0;
+ r4->unk2 = a;
+ r4->unk3 = b;
+ break;
+ case 2:
+ r4->unk0 = 1;
+ r4->unk1 = 0;
+ r4->unk2 = a;
+ r4->unk3 = b;
+ break;
+ }
+}
+
+static void sub_80A7868(void)
+{
+ if (gUnknown_02038550.unk0 == 2)
+ gUnknown_02038550.unk0 = 1;
+}
+
+static void sub_80A7880(void)
+{
+ switch (gUnknown_02038550.unk0)
+ {
+ case 1:
+ gUnknown_02038550.unk0 = 2;
+ break;
+ case 0:
+ sub_80A7970();
+ break;
+ }
+}
+
+static bool32 sub_80A78A0(void)
+{
+ struct UnknownStruct5 *r0 = &gUnknown_02038550;
+
+ return (r0->unk0 == 0);
+}
+
+static void sub_80A78B8(void)
+{
+ gUnknown_02038554.unk0 = 0;
+}
+
+static bool32 sub_80A78C4(void)
+{
+ bool32 retVal;
+
+ if (gLinkOpen == TRUE)
+ {
+ sub_80A7868();
+ sub_80A75A8();
+ retVal = TRUE;
+ }
+ else
+ {
+ retVal = FALSE;
+ }
+ return retVal;
+}
+
+static void sub_80A78E8(void)
+{
+ sub_80A7880();
+}
+
+static int sub_80A78F4(void)
+{
+ int retVal;
+
+ if (gLinkOpen == TRUE)
+ {
+ if (sub_80A76B8() != 0)
+ retVal = 1;
+ else
+ retVal = 2;
+ }
+ else
+ {
+ retVal = 0;
+ }
+ return retVal;
+}
+
+static void sub_80A7918(void)
+{
+ sub_80A76E8();
+}
+
+static int sub_80A7924(void)
+{
+ if (gLinkOpen == TRUE && sub_80A76B8() == 0)
+ {
+ if (sub_80A76D0() != 0)
+ {
+ sub_80A7678();
+ return 0;
+ }
+ }
+ else
+ {
+ return 0;
+ }
+ sub_80A7694();
+ return 2;
+}
+
+static int sub_80A7958(void)
+{
+ if (sub_80A76B8() == 0)
+ return 2;
+ sub_80A75A8();
+ return 1;
+}
+
+static void sub_80A7970(void)
+{
+ sub_80A75C4();
+}
+
+static void sub_80A797C(void)
+{
+ gUnknown_02038554.unk0 = 1;
+}
+
+static int sub_80A7988(void)
+{
+ int val = gUnknown_02038554.unk0;
+
+ gUnknown_02038554.unk0 = 0;
+ return val;
+}
+
+static const u16 gPalette_83C170C[] = INCBIN_U16("graphics/unknown/83C170C.gbapal");
+static const u8 gSpriteImage_83C172C[] = INCBIN_U8("graphics/unknown_sprites/83C172C.4bpp");
+
+const u8 gSpriteImage_UnusedCherry[] = INCBIN_U8("graphics/unused/cherry.4bpp");
+const u16 gSpritePalette_UnusedCherry[] = INCBIN_U16("graphics/unused/cherry.gbapal");
+
+//------------------------------------------------------------------------------
+// Bag Sprite
+//------------------------------------------------------------------------------
+
+static const struct OamData sBagSpriteOamData =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 3,
+ .tileNum = 0,
+ .priority = 2,
+ .paletteNum = 7,
+ .affineParam = 0,
+};
+
+static const union AnimCmd sBagSpriteAnimSeq0[] =
+{
+ ANIMCMD_FRAME(0, 4),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd sBagSpriteAnimSeq1[] =
+{
+ ANIMCMD_FRAME(64, 4),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd sBagSpriteAnimSeq5[] =
+{
+ ANIMCMD_FRAME(128, 4),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd sBagSpriteAnimSeq2[] =
+{
+ ANIMCMD_FRAME(192, 4),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd sBagSpriteAnimSeq3[] =
+{
+ ANIMCMD_FRAME(256, 4),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd sBagSpriteAnimSeq4[] =
+{
+ ANIMCMD_FRAME(320, 4),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const sBagSpriteAnimTable[] =
+{
+ sBagSpriteAnimSeq0,
+ sBagSpriteAnimSeq1,
+ sBagSpriteAnimSeq2,
+ sBagSpriteAnimSeq3,
+ sBagSpriteAnimSeq4,
+ sBagSpriteAnimSeq5,
+};
+
+static const union AffineAnimCmd sBagSpriteAffineAnimSeq[] =
+{
+ AFFINEANIMCMD_FRAME(0, 0, -2, 2),
+ AFFINEANIMCMD_FRAME(0, 0, 2, 4),
+ AFFINEANIMCMD_FRAME(0, 0, -2, 4),
+ AFFINEANIMCMD_FRAME(0, 0, 2, 2),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const sBagSpriteAffineAnimTable[] =
+{
+ sBagSpriteAffineAnimSeq,
+};
+
+static const struct CompressedSpriteSheet sMaleBagSpriteSheet = {gBagMaleTiles, 0x3000, 30000};
+static const struct CompressedSpriteSheet sFemaleBagSpriteSheet = {gBagFemaleTiles, 0x3000, 30000};
+static const struct CompressedSpritePalette sBagSpritePalette = {gBagPalette, 30000};
+
+static void sub_80A7998(struct Sprite *sprite)
+{
+ sprite->animNum = 0;
+ sprite->data0 = 0;
+ sprite->data1 = 0;
+ sprite->data2 = 0;
+ sprite->data3 = 0;
+ sprite->data4 = 0;
+ sprite->callback = sub_80A79B4;
+}
+
+static void sub_80A79B4(struct Sprite *sprite)
+{
+ if (gUnknown_0203855B != -1)
+ sub_80A79EC(sprite);
+ if (gUnknown_0203855C != 0)
+ sub_80A7A94(sprite);
+}
+
+static void sub_80A79EC(struct Sprite *sprite)
+{
+ switch (sprite->data3)
+ {
+ case 0:
+ if (gUnknown_0203855B != 6)
+ {
+ sprite->animBeginning = TRUE;
+ sprite->animNum = gUnknown_0203855B;
+ gUnknown_0203855B = -1;
+ }
+ else
+ {
+ sprite->animBeginning = TRUE;
+ sprite->animNum = 0;
+ sprite->pos1.y -= 4;
+ sprite->data0 = 4;
+ sprite->data3 = 1;
+ sub_80A7AE4(sprite);
+ }
+ break;
+ case 1:
+ if (sprite->data0 != 0)
+ {
+ if (sprite->data1 != 0)
+ {
+ sprite->pos1.y++;
+ sprite->data0--;
+ }
+ sprite->data1 = (sprite->data1 + 1) & 1;
+ }
+ else
+ {
+ gUnknown_0203855B = -1;
+ sprite->data1 = 0;
+ sprite->data3 = 0;
+ }
+ break;
+ }
+}
+
+static void sub_80A7A94(struct Sprite *sprite)
+{
+ switch (sprite->data4)
+ {
+ case 0:
+ sprite->oam.affineMode = 1;
+ sprite->affineAnims = sBagSpriteAffineAnimTable;
+ InitSpriteAffineAnim(sprite);
+ sprite->data4 = 1;
+ break;
+ case 1:
+ sprite->data2++;
+ if (sprite->data2 == 12)
+ sub_80A7AE4(sprite);
+ break;
+ }
+}
+
+static void sub_80A7AE4(struct Sprite *sprite)
+{
+ gUnknown_0203855C = 0;
+ sprite->oam.affineMode = 0;
+ sprite->data2 = 0;
+ sprite->data4 = 0;
+ FreeOamMatrix(sprite->oam.matrixNum);
+}
+
+static const struct SpriteTemplate sBagSpriteTemplate =
+{
+ .tileTag = 30000,
+ .paletteTag = 30000,
+ .oam = &sBagSpriteOamData,
+ .anims = sBagSpriteAnimTable,
+ .images = NULL,
+ .affineAnims = sBagSpriteAffineAnimTable,
+ .callback = sub_80A7998,
+};
+
+static void CreateBagSprite(void)
+{
+ CreateSprite(&sBagSpriteTemplate, 58, 40, 0);
+}
+
+//------------------------------------------------------------------------------
+// Pokeball Sprite
+//------------------------------------------------------------------------------
+
+static const struct OamData gOamData_83C1CF8 =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 4,
+ .size = 1,
+ .tileNum = 0,
+ .priority = 2,
+ .paletteNum = 8,
+ .affineParam = 0,
+};
+
+static const union AffineAnimCmd gSpriteAffineAnim_83C1D00[] =
+{
+ AFFINEANIMCMD_FRAME(0, 0, 8, 32),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gSpriteAffineAnim_83C1D10[] =
+{
+ AFFINEANIMCMD_FRAME(0, 0, -8, 32),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gSpriteAffineAnimTable_83C1D20[] =
+{
+ gSpriteAffineAnim_83C1D00,
+ gSpriteAffineAnim_83C1D10,
+};
+
+static const struct SpriteFrameImage gSpriteImageTable_83C1D28[] =
+{
+ {gSpriteImage_83C172C, sizeof(gSpriteImage_83C172C)},
+};
+
+static const struct SpritePalette sPokeballSpritePalette = {gPalette_83C170C, 8};
+
+static void sub_80A7B28(struct Sprite *sprite)
+{
+ sprite->data3 = 0;
+ sprite->data0 = 0;
+ sub_80A7B6C(sprite);
+ sprite->callback = sub_80A7B6C;
+}
+
+static void sub_80A7B48(struct Sprite *sprite)
+{
+ sprite->centerToCornerVecX = sprite->data5 - ((sprite->data0 + 1) & 1);
+ sprite->centerToCornerVecY = sprite->data6 - ((sprite->data0 + 1) & 1);
+}
+
+static void sub_80A7B6C(struct Sprite *sprite)
+{
+ if (sprite->data7 != 0)
+ {
+ switch (sprite->data3)
+ {
+ case 0:
+ sprite->oam.affineMode = 1;
+ if (sprite->data7 == 1)
+ sprite->affineAnims = gSpriteAffineAnimTable_83C1D20;
+ else
+ sprite->affineAnims = gSpriteAffineAnimTable_83C1D20 + 1;
+ InitSpriteAffineAnim(sprite);
+ sprite->data3 = 1;
+ sprite->data5 = sprite->centerToCornerVecX;
+ sprite->data6 = sprite->centerToCornerVecY;
+ sub_80A7B48(sprite);
+ break;
+ case 1:
+ sprite->data0++;
+ sub_80A7B48(sprite);
+ if (sprite->data0 == 32)
+ {
+ sprite->data0 = 0;
+ sprite->data3 = 0;
+ sprite->centerToCornerVecX = sprite->data5;
+ sprite->centerToCornerVecY = sprite->data6;
+ FreeOamMatrix(sprite->oam.matrixNum);
+ sprite->oam.affineMode = 0;
+ sprite->callback = SpriteCallbackDummy;
+ }
+ break;
+ }
+ }
+}
+
+static const struct SpriteTemplate sPokeballSpriteTemplate =
+{
+ .tileTag = 0xFFFF,
+ .paletteTag = 8,
+ .oam = &gOamData_83C1CF8,
+ .anims = sBagSpriteAnimTable,
+ .images = gSpriteImageTable_83C1D28,
+ .affineAnims = gSpriteAffineAnimTable_83C1D20,
+ .callback = sub_80A7B28,
+};
+
+static void CreateBagPokeballSprite(u8 a)
+{
+ LoadSpritePalette(&sPokeballSpritePalette);
+ sPokeballSpriteId = CreateSprite(&sPokeballSpriteTemplate, 16, 88, 0);
+ gSprites[sPokeballSpriteId].data7 = a;
+}
+
+static void sub_80A7C64(void)
+{
+ FreeSpritePaletteByTag(8);
+ FreeOamMatrix(gSprites[sPokeballSpriteId].oam.matrixNum);
+ DestroySprite(&gSprites[sPokeballSpriteId]);
+}
+
+static const struct OamData sBerrySpriteOamData =
+{
+ .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 gOamData_83C1D58 =
+{
+ .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 sBerrySpriteAnimSeq[] =
+{
+ ANIMCMD_FRAME(0, 0),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const sBerrySpriteAnimTable[] =
+{
+ sBerrySpriteAnimSeq,
+};
+
+static const struct SpriteFrameImage sBerrySpriteImageTable[] =
+{
+ {ewramBerryPic, 0x800},
+};
+
+static void SpriteCB_BerrySprite(struct Sprite *);
+static const struct SpriteTemplate sBerrySpriteTemplate =
+{
+ .tileTag = 0xFFFF,
+ .paletteTag = 30020,
+ .oam = &sBerrySpriteOamData,
+ .anims = sBerrySpriteAnimTable,
+ .images = sBerrySpriteImageTable,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_BerrySprite,
+};
+
+static const union AffineAnimCmd gSpriteAffineAnim_83C1D8C[] =
+{
+ 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 gSpriteAffineAnim_83C1DC4[] =
+{
+ 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 gSpriteAffineAnimTable_83C1DFC[] =
+{
+ gSpriteAffineAnim_83C1D8C,
+ gSpriteAffineAnim_83C1DC4,
+};
+
+static const struct SpriteTemplate gSpriteTemplate_83C1E04 =
+{
+ .tileTag = 0xFFFF,
+ .paletteTag = 30020,
+ .oam = &gOamData_83C1D58,
+ .anims = sBerrySpriteAnimTable,
+ .images = sBerrySpriteImageTable,
+ .affineAnims = gSpriteAffineAnimTable_83C1DFC,
+ .callback = SpriteCallbackDummy,
+};
+
+static const struct {const u8 *lzPic; const u8 *lzPalette;} sBerryGraphicsTable[] =
+{
+ {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},
+};
+
+static void DrawBerryPic(const u8 *src, u8 *dst)
+{
+ u8 i;
+ u8 j;
+
+ memset(dst, 0, 0x800);
+ dst += 0x100;
+ for (i = 0; i < 6; i++)
+ {
+ dst += 32;
+ for (j = 0; j < 6; j++)
+ {
+ memcpy(dst, src, 32);
+ dst += 32;
+ src += 32;
+ }
+ if (i != 5)
+ dst += 32;
+ }
+}
+
+static void LoadBerryPic(u8 berryId)
+{
+ struct SpritePalette spritePal;
+
+ if (berryId == 0x2A && IsEnigmaBerryValid() == TRUE)
+ {
+ DrawBerryPic(gSaveBlock1.enigmaBerry.pic, ewramBerryPic);
+ spritePal.data = gSaveBlock1.enigmaBerry.palette;
+ spritePal.tag = 0x7544;
+ LoadSpritePalette(&spritePal);
+ }
+ else
+ {
+ spritePal.data = (u16 *)sBerryGraphicsTable[berryId].lzPalette;
+ spritePal.tag = 0x7544;
+ LoadCompressedObjectPalette((struct CompressedSpritePalette *)&spritePal);
+ LZDecompressWram(sBerryGraphicsTable[berryId].lzPic, ewramBerryPicTemp);
+ DrawBerryPic(ewramBerryPicTemp, ewramBerryPic);
+ }
+}
+
+u8 CreateBerrySprite(u8 berryId, s16 x, s16 y)
+{
+ LoadBerryPic(berryId);
+ return CreateSprite(&sBerrySpriteTemplate, x, y, 0);
+}
+
+static void SpriteCB_BerrySprite(struct Sprite *sprite)
+{
+ sprite->pos2.y = -gUnknown_030041B4;
+}
+
+void sub_80A7DD4(void)
+{
+ FreeSpritePaletteByTag(0x7544);
+ FreeSpritePaletteByTag(8);
+}
+
+u8 sub_80A7DEC(u8 berryId, u8 x, u8 y, bool8 animate)
+{
+ u8 spriteId;
+
+ FreeSpritePaletteByTag(0x7544);
+ LoadBerryPic(berryId);
+ spriteId = CreateSprite(&gSpriteTemplate_83C1E04, x, y, 0);
+ if (animate == TRUE)
+ StartSpriteAffineAnim(&gSprites[spriteId], 1);
+ return spriteId;
+}
+
+const struct CompressedSpriteSheet gUnknown_083C1F74 = {gBerryCheckCircle_Gfx, 2048, 0x2710};
+
+const struct CompressedSpritePalette gUnknown_083C1F7C = {gBerryCheck_Pal, 0x2710};
+
+static const struct OamData gOamData_83C1F84 =
+{
+ .y = 0,
+ .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 gSpriteAnim_83C1F8C[] =
+{
+ ANIMCMD_FRAME(0, 0),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gSpriteAnimTable_83C1F94[] =
+{
+ gSpriteAnim_83C1F8C,
+};
+
+static const struct SpriteTemplate gSpriteTemplate_83C1F98 =
+{
+ .tileTag = 10000,
+ .paletteTag = 10000,
+ .oam = &gOamData_83C1F84,
+ .anims = gSpriteAnimTable_83C1F94,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_BerrySprite,
+};
+
+u8 sub_80A7E5C(s16 x)
+{
+ return CreateSprite(&gSpriteTemplate_83C1F98, x, 99, 0);
+}
diff --git a/src/field/item_use.c b/src/field/item_use.c
new file mode 100644
index 000000000..68da27fdb
--- /dev/null
+++ b/src/field/item_use.c
@@ -0,0 +1,1200 @@
+#include "global.h"
+#include "item_use.h"
+#include "battle.h"
+#include "berry.h"
+#include "bike.h"
+#include "coins.h"
+#include "data2.h"
+#include "event_data.h"
+#include "field_effect.h"
+#include "field_fadetransition.h"
+#include "field_map_obj_helpers.h"
+#include "field_player_avatar.h"
+#include "field_weather.h"
+#include "fieldmap.h"
+#include "item.h"
+#include "item_menu.h"
+#include "items.h"
+#include "mail.h"
+#include "main.h"
+#include "map_obj_lock.h"
+#include "menu.h"
+#include "menu_helpers.h"
+#include "metatile_behavior.h"
+#include "palette.h"
+#include "party_menu.h"
+#include "pokeblock.h"
+#include "pokemon_item_effect.h"
+#include "pokemon_menu.h"
+#include "overworld.h"
+#include "rom_8094928.h"
+#include "script.h"
+#include "songs.h"
+#include "sound.h"
+#include "string_util.h"
+#include "strings.h"
+#include "task.h"
+#include "vars.h"
+
+extern void (*gFieldItemUseCallback)(u8);
+extern void (*gFieldCallback)(void);
+extern void (*gUnknown_0300485C)(void);
+extern void (*gUnknown_03004AE4)(u8, u16, TaskFunc);
+
+extern u8 gUnknown_02038561;
+extern u8 gLastFieldPokeMenuOpened;
+extern u8 gBankInMenu;
+
+extern u8 gUnknown_081A1654[];
+extern u8 gUnknown_081A168F[];
+
+extern u16 gBattlePartyID[];
+
+extern u16 gBattleTypeFlags;
+
+static const u8 gSSTidalBetaString[] = _("この チケットで ふねに のりほうだい\nはやく のってみたいな");
+static const u8 gSSTidalBetaString2[] = _("この チケットで ふねに のりほうだい\nはやく のってみたいな");
+
+static const u8 *const gUnknown_083D61DC[2] =
+{
+ gSSTidalBetaString,
+ gSSTidalBetaString2,
+};
+
+static const MainCallback gExitToOverworldFuncList[] =
+{
+ sub_808B020,
+ c2_exit_to_overworld_2_switch,
+ sub_810B96C,
+};
+
+static const u8 gItemFinderDirections[] = { DIR_NORTH, DIR_EAST, DIR_SOUTH, DIR_WEST };
+
+static const struct YesNoFuncTable gUnknown_083D61F4 =
+{
+ .yesFunc = sub_80C9FC0,
+ .noFunc = CleanUpItemMenuMessage,
+};
+
+void ExecuteSwitchToOverworldFromItemUse(u8 taskId)
+{
+ u8 taskData;
+
+ if (gScriptItemId == 0xAF)
+ taskData = gTasks[taskId].data[15] - 1;
+ else
+ taskData = ItemId_GetType(gScriptItemId) - 1;
+
+ gTasks[taskId].data[8] = (u32)gExitToOverworldFuncList[taskData] >> 16;
+ gTasks[taskId].data[9] = (u32)gExitToOverworldFuncList[taskData];
+ gTasks[taskId].func = HandleItemMenuPaletteFade;
+}
+
+void ItemMenu_ConfirmNormalFade(u8 var)
+{
+ ExecuteSwitchToOverworldFromItemUse(var);
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0);
+}
+
+void ItemMenu_ConfirmComplexFade(u8 var)
+{
+ ExecuteSwitchToOverworldFromItemUse(var);
+ fade_screen(1, 0);
+}
+
+void SetUpItemUseOnFieldCallback(u8 taskId)
+{
+ if (gTasks[taskId].data[2] != 1)
+ {
+ gFieldCallback = ExecuteItemUseFromBlackPalette;
+ ItemMenu_ConfirmNormalFade(taskId);
+ }
+ else
+ {
+ gFieldItemUseCallback(taskId);
+ }
+}
+
+void HandleDeniedItemUseMessage(u8 var1, u8 playerMenuStatus, const u8 *text)
+{
+ StringExpandPlaceholders(gStringVar4, text);
+
+ switch (playerMenuStatus)
+ {
+ case 0: // Item Menu
+ MenuZeroFillWindowRect(0, 13, 13, 20);
+ DisplayItemMessageOnField(var1, gStringVar4, CleanUpItemMenuMessage, 1);
+ break;
+ default: // Field
+ DisplayItemMessageOnField(var1, gStringVar4, CleanUpOverworldMessage, 0);
+ break;
+ }
+}
+
+void DisplayDadsAdviceCannotUseItemMessage(u8 var1, u8 playerMenuStatus)
+{
+ HandleDeniedItemUseMessage(var1, playerMenuStatus, gOtherText_DadsAdvice);
+}
+
+void DisplayCantGetOffBikeItemMessage(u8 var1, u8 playerMenuStatus)
+{
+ HandleDeniedItemUseMessage(var1, playerMenuStatus, gOtherText_CantGetOffBike);
+}
+
+u8 CheckIfItemIsTMHMOrEvolutionStone(u16 itemId)
+{
+ if (ItemId_GetFieldFunc(itemId) == ItemUseOutOfBattle_TMHM)
+ return 1;
+ else if (ItemId_GetFieldFunc(itemId) == ItemUseOutOfBattle_EvolutionStone)
+ return 2;
+ else
+ return 0;
+}
+
+void ItemMenu_ReadMail(u8 taskId)
+{
+ struct MailStruct mailStruct;
+
+ if (!gPaletteFade.active)
+ {
+ mailStruct.itemId = gScriptItemId;
+ HandleReadMail(&mailStruct, sub_80A5D04, 0);
+ DestroyTask(taskId);
+ }
+}
+
+void ItemUseOutOfBattle_Mail(u8 taskId)
+{
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0);
+ gTasks[taskId].func = ItemMenu_ReadMail;
+}
+
+void ItemUseOutOfBattle_Bike(u8 taskId)
+{
+ s16 x, y;
+ u8 tileBehavior;
+
+ PlayerGetDestCoords(&x, &y);
+ tileBehavior = MapGridGetMetatileBehaviorAt(x, y);
+
+ if (FlagGet(SYS_CYCLING_ROAD) == TRUE // on cycling road?
+ || MetatileBehavior_IsVerticalRail(tileBehavior) == TRUE
+ || MetatileBehavior_IsHorizontalRail(tileBehavior) == TRUE
+ || MetatileBehavior_IsIsolatedVerticalRail(tileBehavior) == TRUE
+ || MetatileBehavior_IsIsolatedHorizontalRail(tileBehavior) == TRUE)
+ {
+ DisplayCantGetOffBikeItemMessage(taskId, gTasks[taskId].data[2]);
+ }
+ else
+ {
+ if (Overworld_IsBikingAllowed() == TRUE && IsBikingDisallowedByPlayer() == FALSE)
+ {
+ gFieldItemUseCallback = (void *)ItemUseOnFieldCB_Bike;
+ SetUpItemUseOnFieldCallback(taskId);
+ }
+ else
+ DisplayDadsAdviceCannotUseItemMessage(taskId, gTasks[taskId].data[2]);
+ }
+}
+
+void ItemUseOnFieldCB_Bike(u8 taskId)
+{
+ if (ItemId_GetSecondaryId(gScriptItemId) == 0)
+ GetOnOffBike(2);
+ if (ItemId_GetSecondaryId(gScriptItemId) == 1)
+ GetOnOffBike(4);
+
+ sub_8064E2C();
+ ScriptContext2_Disable();
+ DestroyTask(taskId);
+}
+
+bool32 CanFish(void)
+{
+ s16 x, y;
+ u16 tileBehavior;
+
+ GetXYCoordsOneStepInFrontOfPlayer(&x, &y);
+ tileBehavior = MapGridGetMetatileBehaviorAt(x, y);
+
+ if (MetatileBehavior_IsWaterfall(tileBehavior))
+ return FALSE;
+
+ if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_4))
+ return FALSE;
+
+ if (!TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING))
+ {
+ if (IsPlayerFacingSurfableFishableWater())
+ return TRUE;
+ }
+ else
+ {
+ if (MetatileBehavior_IsSurfableWaterOrUnderwater(tileBehavior) && !MapGridIsImpassableAt(x, y))
+ return TRUE;
+ if (MetatileBehavior_IsBridge(tileBehavior) == TRUE)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void ItemUseOutOfBattle_Rod(u8 taskId)
+{
+ if (CanFish() == TRUE)
+ {
+ gFieldItemUseCallback = (void *)ItemUseOnFieldCB_Rod;
+ SetUpItemUseOnFieldCallback(taskId);
+ }
+ else
+ DisplayDadsAdviceCannotUseItemMessage(taskId, gTasks[taskId].data[2]);
+}
+
+void ItemUseOnFieldCB_Rod(u8 taskId)
+{
+ StartFishing(ItemId_GetSecondaryId(gScriptItemId));
+ DestroyTask(taskId);
+}
+
+void ItemUseOutOfBattle_Itemfinder(u8 var)
+{
+ IncrementGameStat(0x27);
+ gFieldItemUseCallback = (void *)ItemUseOnFieldCB_Itemfinder;
+ SetUpItemUseOnFieldCallback(var);
+}
+
+void ItemUseOnFieldCB_Itemfinder(u8 taskId)
+{
+ if (ItemfinderCheckForHiddenItems(gMapHeader.events, taskId) == TRUE)
+ gTasks[taskId].func = RunItemfinderResults;
+ else
+ DisplayItemMessageOnField(taskId, gOtherText_NoResponse, ExitItemfinder, 0);
+}
+
+void RunItemfinderResults(u8 taskId)
+{
+ u8 playerDir;
+ u8 playerDirToItem;
+ u8 i;
+ s16 *data = gTasks[taskId].data;
+
+ if (!data[3])
+ {
+ if (data[4] == 4)
+ {
+ playerDirToItem = GetPlayerDirectionTowardsHiddenItem(data[0], data[1]);
+ if (playerDirToItem)
+ {
+ SetPlayerDirectionTowardsItem(gItemFinderDirections[playerDirToItem - 1]);
+ gTasks[taskId].func = DisplayItemRespondingMessageAndExitItemfinder;
+ }
+ else // player is above hidden item.
+ {
+ playerDir = player_get_direction_lower_nybble();
+
+ // rotate player clockwise depending on current direction.
+ for (i = 0; i < 4; i++)
+ if (playerDir == gItemFinderDirections[i])
+ data[5] = (i + 1) & 3;
+
+ gTasks[taskId].func = RotatePlayerAndExitItemfinder;
+ data[3] = 0;
+ data[2] = 0;
+ }
+ return;
+ }
+ PlaySE(SE_DAUGI); // play the itemfinder jingle 4 times before executing the itemfinder.
+ data[4]++;
+ }
+ data[3] = (data[3] + 1) & 0x1F;
+}
+
+void ExitItemfinder(u8 taskId)
+{
+ MenuZeroFillWindowRect(0, 14, 29, 19);
+ sub_8064E2C();
+ ScriptContext2_Disable();
+ DestroyTask(taskId);
+}
+
+bool8 ItemfinderCheckForHiddenItems(struct MapEvents *events, u8 taskId)
+{
+ int distanceX, distanceY;
+ u16 x, y;
+ s16 newDistanceX, newDistanceY, i;
+
+ PlayerGetDestCoords(&x, &y);
+ gTasks[taskId].data[2] = FALSE;
+
+ for (i = 0; i < events->bgEventCount; i++)
+ {
+ if ((events -> bgEvents[i].kind == 7) && !FlagGet(events -> bgEvents[i].bgUnion.hiddenItem.hiddenItemId + 600))
+ {
+ // do a distance lookup of each item so long as the index remains less than the objects on the current map.
+ distanceX = (u16)events -> bgEvents[i].x + 7;
+ newDistanceX = distanceX - x;
+ distanceY = (u16)events -> bgEvents[i].y + 7;
+ newDistanceY = distanceY - y;
+
+ // is item in range?
+ if ((u16)(newDistanceX + 7) < 15 && (newDistanceY >= -5) && (newDistanceY < 6))
+ sub_80C9838(taskId, newDistanceX, newDistanceY); // send coordinates of the item relative to the player
+ }
+ }
+ sub_80C9720(taskId);
+
+ // hidden item detected?
+ if (gTasks[taskId].data[2] == TRUE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 HiddenItemAtPos(struct MapEvents *events, s16 x, s16 y)
+{
+ u8 bgEventCount = events->bgEventCount;
+ struct BgEvent *bgEvent = events->bgEvents;
+ int i;
+
+ for (i = 0; i < bgEventCount; i++)
+ {
+ if (bgEvent[i].kind == 7 && x == (u16)bgEvent[i].x && y == (u16)bgEvent[i].y) // hidden item and coordinates matches x and y passed?
+ {
+ if (!FlagGet(bgEvent[i].bgUnion.hiddenItem.hiddenItemId + 600))
+ return TRUE;
+ else
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+
+bool8 sub_80C9688(struct MapConnection *connection, int x, int y)
+{
+ struct MapHeader *mapHeader;
+ u16 localX, localY;
+ u32 localOffset;
+ s32 localLength;
+
+ mapHeader = mapconnection_get_mapheader(connection);
+
+ switch (connection->direction)
+ {
+ // same weird temp variable behavior seen in HiddenItemAtPos
+ case 2:
+ localOffset = connection->offset + 7;
+ localX = x - localOffset;
+ localLength = mapHeader->mapData->height - 7;
+ localY = localLength + y; // additions are reversed for some reason
+ break;
+ case 1:
+ localOffset = connection->offset + 7;
+ localX = x - localOffset;
+ localLength = gMapHeader.mapData->height + 7;
+ localY = y - localLength;
+ break;
+ case 3:
+ localLength = mapHeader->mapData->width - 7;
+ localX = localLength + x; // additions are reversed for some reason
+ localOffset = connection->offset + 7;
+ localY = y - localOffset;
+ break;
+ case 4:
+ localLength = gMapHeader.mapData->width + 7;
+ localX = x - localLength;
+ localOffset = connection->offset + 7;
+ localY = y - localOffset;
+ break;
+ default:
+ return FALSE;
+ }
+ return HiddenItemAtPos(mapHeader->events, localX, localY);
+}
+
+// weird math
+#ifdef NONMATCHING
+void sub_80C9720(u8 taskId)
+{
+ s16 x, y;
+ s16 curX, curY;
+ s16 width = gMapHeader.mapData->width + 7;
+ s16 height = gMapHeader.mapData->height + 7;
+
+ PlayerGetDestCoords(&x, &y);
+
+ for (curX = x - 7; curX <= x + 7; curX++)
+ {
+ for (curY = y - 5; curY <= y + 5; curY++)
+ {
+ if (7 > curX
+ || curX >= width
+ || 7 > curY
+ || curY >= height)
+ {
+ struct MapConnection *conn = sub_8056BA0(curX, curY);
+ if (conn && sub_80C9688(conn, curX, curY) == TRUE)
+ sub_80C9838(taskId, curX - x, curY - y);
+ }
+ }
+ }
+}
+#else
+__attribute__((naked))
+void sub_80C9720(u8 taskId)
+{
+ 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, 0x14\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ str r0, [sp, 0x4]\n\
+ ldr r0, _080C9834 @ =gMapHeader\n\
+ ldr r1, [r0]\n\
+ ldr r0, [r1]\n\
+ adds r0, 0x7\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ str r0, [sp, 0x8]\n\
+ ldr r0, [r1, 0x4]\n\
+ adds r0, 0x7\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ str r0, [sp, 0xC]\n\
+ mov r4, sp\n\
+ adds r4, 0x2\n\
+ mov r0, sp\n\
+ adds r1, r4, 0\n\
+ bl PlayerGetDestCoords\n\
+ mov r0, sp\n\
+ ldrh r0, [r0]\n\
+ subs r0, 0x7\n\
+ lsls r0, 16\n\
+ lsrs r3, r0, 16\n\
+ asrs r0, 16\n\
+ mov r1, sp\n\
+ movs r2, 0\n\
+ ldrsh r1, [r1, r2]\n\
+ adds r1, 0x7\n\
+ cmp r0, r1\n\
+ bgt _080C9824\n\
+_080C976E:\n\
+ mov r5, sp\n\
+ ldrh r0, [r5, 0x2]\n\
+ subs r0, 0x5\n\
+ lsls r0, 16\n\
+ lsrs r4, r0, 16\n\
+ lsls r2, r4, 16\n\
+ asrs r1, r2, 16\n\
+ movs r6, 0x2\n\
+ ldrsh r0, [r5, r6]\n\
+ adds r0, 0x5\n\
+ lsls r3, 16\n\
+ mov r8, r3\n\
+ cmp r1, r0\n\
+ bgt _080C980E\n\
+ movs r0, 0x7\n\
+ str r0, [sp, 0x10]\n\
+ mov r1, r8\n\
+ asrs r1, 16\n\
+ mov r9, r1\n\
+ mov r10, r0\n\
+_080C9796:\n\
+ ldr r3, [sp, 0x10]\n\
+ cmp r3, r9\n\
+ bgt _080C97B8\n\
+ ldr r5, [sp, 0x8]\n\
+ lsls r0, r5, 16\n\
+ asrs r0, 16\n\
+ cmp r9, r0\n\
+ bge _080C97B8\n\
+ asrs r1, r2, 16\n\
+ cmp r10, r1\n\
+ bgt _080C97B8\n\
+ ldr r6, [sp, 0xC]\n\
+ lsls r0, r6, 16\n\
+ asrs r0, 16\n\
+ lsls r7, r4, 16\n\
+ cmp r1, r0\n\
+ blt _080C97F6\n\
+_080C97B8:\n\
+ mov r0, r8\n\
+ asrs r5, r0, 16\n\
+ lsls r4, 16\n\
+ asrs r6, r4, 16\n\
+ adds r0, r5, 0\n\
+ adds r1, r6, 0\n\
+ bl sub_8056BA0\n\
+ adds r7, r4, 0\n\
+ cmp r0, 0\n\
+ beq _080C97F6\n\
+ adds r1, r5, 0\n\
+ adds r2, r6, 0\n\
+ bl sub_80C9688\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ cmp r0, 0x1\n\
+ bne _080C97F6\n\
+ mov r0, sp\n\
+ ldrh r1, [r0]\n\
+ subs r1, r5, r1\n\
+ lsls r1, 16\n\
+ asrs r1, 16\n\
+ ldrh r2, [r0, 0x2]\n\
+ subs r2, r6, r2\n\
+ lsls r2, 16\n\
+ asrs r2, 16\n\
+ ldr r0, [sp, 0x4]\n\
+ bl sub_80C9838\n\
+_080C97F6:\n\
+ movs r1, 0x80\n\
+ lsls r1, 9\n\
+ adds r0, r7, r1\n\
+ lsrs r4, r0, 16\n\
+ lsls r2, r4, 16\n\
+ asrs r1, r2, 16\n\
+ mov r3, sp\n\
+ movs r5, 0x2\n\
+ ldrsh r0, [r3, r5]\n\
+ adds r0, 0x5\n\
+ cmp r1, r0\n\
+ ble _080C9796\n\
+_080C980E:\n\
+ movs r1, 0x80\n\
+ lsls r1, 9\n\
+ add r1, r8\n\
+ lsrs r3, r1, 16\n\
+ asrs r1, 16\n\
+ mov r0, sp\n\
+ movs r6, 0\n\
+ ldrsh r0, [r0, r6]\n\
+ adds r0, 0x7\n\
+ cmp r1, r0\n\
+ ble _080C976E\n\
+_080C9824:\n\
+ add sp, 0x14\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\
+ .align 2, 0\n\
+_080C9834: .4byte gMapHeader\n\
+ .syntax divided");
+}
+#endif
+
+void sub_80C9838(u8 taskId, s16 x, s16 y)
+{
+ s16 *data = gTasks[taskId].data;
+ s16 var1, var2, var3, var4;
+
+ if (data[2] == FALSE)
+ {
+ data[0] = x;
+ data[1] = y;
+ data[2] = TRUE;
+ }
+ else
+ {
+ // data[0] and data[1] contain the player's coordinates.
+ // x and y contain the item's coordinates.
+ if (data[0] < 0)
+ var1 = data[0] * -1; // item is to the left
+ else
+ var1 = data[0]; // item is to the right
+
+ if (data[1] < 0)
+ var2 = data[1] * -1; // item is to the north
+ else
+ var2 = data[1]; // item is to the south
+
+ if (x < 0)
+ var3 = x * -1;
+ else
+ var3 = x;
+
+ if (y < 0)
+ var4 = y * -1;
+ else
+ var4 = y;
+
+ if (var1 + var2 > var3 + var4)
+ {
+ data[0] = x;
+ data[1] = y;
+ }
+ else
+ {
+ if (var1 + var2 == var3 + var4 && (var2 > var4 || (var2 == var4 && data[1] < y)))
+ {
+ data[0] = x;
+ data[1] = y;
+ }
+ }
+ }
+}
+
+u8 GetPlayerDirectionTowardsHiddenItem(s16 itemX, s16 itemY)
+{
+ s16 abX, abY;
+
+ if (itemX == 0 && itemY == 0)
+ return DIR_NONE; // player is standing on the item.
+
+ // get absolute X distance.
+ if (itemX < 0)
+ abX = itemX * -1;
+ else
+ abX = itemX;
+
+ // get absolute Y distance.
+ if (itemY < 0)
+ abY = itemY * -1;
+ else
+ abY = itemY;
+
+ if (abX > abY)
+ {
+ if (itemX < 0)
+ return DIR_EAST;
+ else
+ return DIR_NORTH;
+ }
+ else
+ {
+ if (abX < abY)
+ {
+ if (itemY < 0)
+ return DIR_SOUTH;
+ else
+ return DIR_WEST;
+ }
+ if (abX == abY)
+ {
+ if (itemY < 0)
+ return DIR_SOUTH;
+ else
+ return DIR_WEST;
+ }
+ return DIR_NONE; // should never get here. return something so it doesnt crash.
+ }
+}
+
+void SetPlayerDirectionTowardsItem(u8 direction)
+{
+ FieldObjectClearAnimIfSpecialAnimFinished(&gMapObjects[GetFieldObjectIdByLocalIdAndMap(0xFF, 0, 0)]);
+ FieldObjectClearAnim(&gMapObjects[GetFieldObjectIdByLocalIdAndMap(0xFF, 0, 0)]);
+ UnfreezeMapObject(&gMapObjects[GetFieldObjectIdByLocalIdAndMap(0xFF, 0, 0)]);
+ PlayerTurnInPlace(direction);
+}
+
+void DisplayItemRespondingMessageAndExitItemfinder(u8 taskId)
+{
+ if (FieldObjectCheckIfSpecialAnimFinishedOrInactive(&gMapObjects[GetFieldObjectIdByLocalIdAndMap(0xFF, 0, 0)]) == TRUE)
+ DisplayItemMessageOnField(taskId, gOtherText_ItemfinderResponding, ExitItemfinder, 0);
+}
+
+void RotatePlayerAndExitItemfinder(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ if (FieldObjectCheckIfSpecialAnimFinishedOrInactive(&gMapObjects[GetFieldObjectIdByLocalIdAndMap(0xFF, 0, 0)]) == TRUE
+ || data[2] == FALSE)
+ {
+ SetPlayerDirectionTowardsItem(gItemFinderDirections[data[5]]);
+ data[2] = 1;
+ data[5] = (data[5] + 1) & 3;
+ data[3]++;
+
+ if (data[3] == 4)
+ DisplayItemMessageOnField(taskId, gOtherText_ItemfinderItemUnderfoot, ExitItemfinder, 0);
+ }
+}
+
+void ItemUseOutOfBattle_PokeblockCase(u8 taskId)
+{
+ if (sub_80F9344() == TRUE)
+ {
+ DisplayDadsAdviceCannotUseItemMessage(taskId, gTasks[taskId].data[2]);
+ }
+ else if (gTasks[taskId].data[2] != TRUE)
+ {
+ sub_810BA7C(0);
+ ItemMenu_ConfirmNormalFade(taskId);
+ }
+ else
+ {
+ gFieldCallback = (void *)sub_8080E28;
+ sub_810BA7C(1);
+ ItemMenu_ConfirmComplexFade(taskId);
+ }
+}
+
+void ItemUseOutOfBattle_CoinCase(u8 taskId)
+{
+ ConvertIntToDecimalStringN(gStringVar1, GetCoins(), 0, 4);
+ StringExpandPlaceholders(gStringVar4, gOtherText_Coins3);
+
+ if (!gTasks[taskId].data[2])
+ {
+ MenuZeroFillWindowRect(0, 0xD, 0xD, 0x14);
+ DisplayItemMessageOnField(taskId, gStringVar4, CleanUpItemMenuMessage, 1);
+ }
+ else
+ {
+ DisplayItemMessageOnField(taskId, gStringVar4, CleanUpOverworldMessage, 0);
+ }
+}
+
+void sub_80C9BB8(u8 var)
+{
+ if (gMain.newKeys & A_BUTTON)
+ CleanUpItemMenuMessage(var);
+}
+
+void sub_80C9BD8(u8 var)
+{
+ if (gMain.newKeys & A_BUTTON)
+ CleanUpOverworldMessage(var);
+}
+
+// unused
+void ItemUseOutOfBattle_SSTicket(u8 taskId)
+{
+ if (gTasks[taskId].data[2] == 0)
+ {
+ MenuZeroFillWindowRect(0, 0xD, 0xD, 0x14);
+ DisplayItemMessageOnField(taskId, gUnknown_083D61DC[ItemId_GetSecondaryId(gScriptItemId)], sub_80C9BB8, 1);
+ }
+ else
+ {
+ DisplayItemMessageOnField(taskId, gUnknown_083D61DC[ItemId_GetSecondaryId(gScriptItemId)], sub_80C9BD8, 0);
+ }
+}
+
+void sub_80C9C7C(u8 taskId)
+{
+ if (IsPlayerFacingPlantedBerryTree() == TRUE)
+ {
+ gFieldItemUseCallback = sub_80C9D00;
+ gFieldCallback = ExecuteItemUseFromBlackPalette;
+ gTasks[taskId].data[8] = (u32)c2_exit_to_overworld_2_switch >> 16;
+ gTasks[taskId].data[9] = (u32)c2_exit_to_overworld_2_switch;
+ gTasks[taskId].func = HandleItemMenuPaletteFade;
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, 0);
+ }
+ else
+ {
+ ItemId_GetFieldFunc(gScriptItemId)(taskId);
+ }
+}
+
+void sub_80C9D00(u8 taskId)
+{
+ RemoveBagItem(gScriptItemId, 1);
+ ScriptContext2_Enable();
+ ScriptContext1_SetupScript(gUnknown_081A1654);
+ DestroyTask(taskId);
+}
+
+void ItemUseOutOfBattle_WailmerPail(u8 taskId)
+{
+ if (TryToWaterBerryTree() == TRUE)
+ {
+ gFieldItemUseCallback = sub_80C9D74;
+ SetUpItemUseOnFieldCallback(taskId);
+ }
+ else
+ {
+ DisplayDadsAdviceCannotUseItemMessage(taskId, gTasks[taskId].data[2]);
+ }
+}
+
+void sub_80C9D74(u8 taskId)
+{
+ ScriptContext2_Enable();
+ ScriptContext1_SetupScript(gUnknown_081A168F);
+ DestroyTask(taskId);
+}
+
+void sub_80C9D98(u8 taskId)
+{
+ gUnknown_02038561 = 0;
+ ItemMenu_ConfirmNormalFade(taskId);
+}
+
+void ItemUseOutOfBattle_Medicine(u8 taskId)
+{
+ gUnknown_03004AE4 = UseMedicine;
+ sub_80C9D98(taskId);
+}
+
+void ItemUseOutOfBattle_SacredAsh(u8 taskId)
+{
+ u8 i;
+
+ gLastFieldPokeMenuOpened = 0;
+
+ for (i = 0; i < 6; i++)
+ {
+ if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) != 0 && GetMonData(&gPlayerParty[i], MON_DATA_HP) == 0)
+ {
+ gLastFieldPokeMenuOpened = i;
+ break;
+ }
+ }
+ gUnknown_03004AE4 = sub_8070048;
+ gUnknown_02038561 = 4;
+ ItemMenu_ConfirmNormalFade(taskId);
+}
+
+void ItemUseOutOfBattle_PPRecovery(u8 taskId)
+{
+ gUnknown_03004AE4 = DoPPRecoveryItemEffect;
+ sub_80C9D98(taskId);
+}
+
+void ItemUseOutOfBattle_PPUp(u8 taskId)
+{
+ gUnknown_03004AE4 = DoPPUpItemEffect;
+ sub_80C9D98(taskId);
+}
+
+void ItemUseOutOfBattle_RareCandy(u8 taskId)
+{
+ gUnknown_03004AE4 = DoRareCandyItemEffect;
+ sub_80C9D98(taskId);
+}
+
+void ItemUseOutOfBattle_TMHM(u8 taskId)
+{
+ MenuZeroFillWindowRect(0, 0xD, 0xD, 0x14);
+
+ if (gScriptItemId >= ITEM_HM01)
+ DisplayItemMessageOnField(taskId, gOtherText_BootedHM, sub_80C9EE4, 1); // HM
+ else
+ DisplayItemMessageOnField(taskId, gOtherText_BootedTM, sub_80C9EE4, 1); // TM
+}
+
+void sub_80C9EE4(u8 taskId)
+{
+ PlaySE(SE_PC_LOGON);
+ gTasks[taskId].func = sub_80C9F10;
+}
+
+void sub_80C9F10(u8 taskId)
+{
+ if (gMain.newKeys & A_BUTTON || gMain.newKeys & B_BUTTON)
+ {
+ StringCopy(gStringVar1, gMoveNames[ItemIdToBattleMoveId(gScriptItemId)]);
+ StringExpandPlaceholders(gStringVar4, gOtherText_ContainsMove);
+ DisplayItemMessageOnField(taskId, gStringVar4, sub_80C9F80, 1);
+ }
+}
+
+void sub_80C9F80(u8 var)
+{
+ DisplayYesNoMenu(7, 7, 1);
+ sub_80A3FA0(gBGTilemapBuffers[1], 8, 8, 5, 4, 1);
+ DoYesNoFuncWithChoice(var, &gUnknown_083D61F4);
+}
+
+void sub_80C9FC0(u8 var)
+{
+ gUnknown_03004AE4 = TeachMonTMMove;
+ sub_80C9D98(var);
+}
+
+static void PrepareItemUseMessage(void)
+{
+ RemoveBagItem(gScriptItemId, 1);
+ sub_80A3E0C();
+ CopyItemName(gScriptItemId, gStringVar2);
+ StringExpandPlaceholders(gStringVar4, gOtherText_UsedItem);
+}
+
+void ItemUseOutOfBattle_Repel(u8 var)
+{
+ if (VarGet(VAR_REPEL_STEP_COUNT) == FALSE)
+ {
+ VarSet(VAR_REPEL_STEP_COUNT, ItemId_GetHoldEffectParam(gScriptItemId));
+ PrepareItemUseMessage();
+ DisplayItemMessageOnField(var, gStringVar4, CleanUpItemMenuMessage, 1);
+ }
+ else
+ {
+ DisplayItemMessageOnField(var, gOtherText_RepelLingers, CleanUpItemMenuMessage, 1);
+ }
+}
+
+void sub_80CA07C(void)
+{
+ sub_80A3E0C();
+ CopyItemName(gScriptItemId, gStringVar2);
+}
+
+void sub_80CA098(u8 taskId)
+{
+ if(++gTasks[taskId].data[15] > 7)
+ {
+ PlaySE(SE_BIDORO);
+ DisplayItemMessageOnField(taskId, gStringVar4, CleanUpItemMenuMessage, 1);
+ }
+}
+
+void ItemUseOutOfBattle_BlackWhiteFlute(u8 taskId)
+{
+ if (gScriptItemId == ITEM_WHITE_FLUTE)
+ {
+ FlagSet(SYS_ENC_UP_ITEM);
+ FlagClear(SYS_ENC_DOWN_ITEM);
+ sub_80CA07C();
+ StringExpandPlaceholders(gStringVar4, gOtherText_UsedFlute);
+ gTasks[taskId].func = sub_80CA098;
+ gTasks[taskId].data[15] = 0;
+ }
+ else if (gScriptItemId == ITEM_BLACK_FLUTE)
+ {
+ FlagSet(SYS_ENC_DOWN_ITEM);
+ FlagClear(SYS_ENC_UP_ITEM);
+ sub_80CA07C();
+ StringExpandPlaceholders(gStringVar4, gOtherText_UsedRepel);
+ gTasks[taskId].func = sub_80CA098;
+ gTasks[taskId].data[15] = 0;
+ }
+}
+
+void task08_080A1C44(u8 taskId)
+{
+ player_avatar_init_params_reset();
+ sub_80878A8();
+ DestroyTask(taskId);
+}
+
+void EscapeRopeCallback(u8 taskId)
+{
+ Overworld_ResetStateAfterDigEscRope();
+ PrepareItemUseMessage();
+ gTasks[taskId].data[0] = 0;
+ DisplayItemMessageOnField(taskId, gStringVar4, task08_080A1C44, 0);
+}
+
+bool8 CanUseEscapeRopeOnCurrMap(void)
+{
+ if (gMapHeader.mapType == MAP_TYPE_UNDERGROUND)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void ItemUseOutOfBattle_EscapeRope(u8 taskId)
+{
+ if (CanUseEscapeRopeOnCurrMap() == TRUE)
+ {
+ gFieldItemUseCallback = EscapeRopeCallback;
+ SetUpItemUseOnFieldCallback(taskId);
+ }
+ else
+ {
+ DisplayDadsAdviceCannotUseItemMessage(taskId, gTasks[taskId].data[2]);
+ }
+}
+
+void ItemUseOutOfBattle_EvolutionStone(u8 var)
+{
+ gUnknown_03004AE4 = DoEvolutionStoneItemEffect;
+ sub_80C9D98(var);
+}
+
+void ItemUseInBattle_PokeBall(u8 var)
+{
+ if (PlayerPartyAndPokemonStorageFull() == FALSE) // have room for mon?
+ {
+ RemoveBagItem(gScriptItemId, 1);
+ sub_80A7094(var);
+ }
+ else
+ {
+ MenuZeroFillWindowRect(0, 0xD, 0xD, 0x14);
+ DisplayItemMessageOnField(var, gOtherText_BoxIsFull, CleanUpItemMenuMessage, 1);
+ }
+}
+
+void sub_80CA294(u8 var)
+{
+ if (gMain.newKeys & A_BUTTON || gMain.newKeys & B_BUTTON)
+ sub_80A7094(var);
+}
+
+void sub_80CA2BC(u8 taskId)
+{
+ if(++gTasks[taskId].data[15] > 7)
+ {
+ PlaySE(SE_KAIFUKU);
+ RemoveBagItem(gScriptItemId, 1);
+ DisplayItemMessageOnField(taskId, sub_803F378(gScriptItemId), sub_80CA294, 1);
+ }
+}
+
+void ItemUseInBattle_StatIncrease(u8 taskId)
+{
+ u16 partyId = gBattlePartyID[gBankInMenu];
+
+ MenuZeroFillWindowRect(0, 0xD, 0xD, 0x14);
+
+ if (ExecuteTableBasedItemEffect_(&gPlayerParty[partyId], gScriptItemId, partyId, 0) != FALSE)
+ {
+ DisplayItemMessageOnField(taskId, gOtherText_WontHaveAnyEffect, CleanUpItemMenuMessage, 1);
+ }
+ else
+ {
+ gTasks[taskId].func = sub_80CA2BC;
+ gTasks[taskId].data[15] = 0;
+ }
+}
+
+void sub_80CA394(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ sub_8094E4C();
+ gpu_pal_allocator_reset__manage_upper_four();
+ DestroyTask(taskId);
+ }
+}
+
+void sub_80CA3C0(u8 taskId)
+{
+ gTasks[taskId].func = sub_80CA394;
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0);
+}
+
+void ItemUseInBattle_Medicine(u8 var)
+{
+ gUnknown_03004AE4 = UseMedicine;
+ sub_80CA3C0(var);
+}
+
+void unref_sub_80CA410(u8 var)
+{
+ gUnknown_03004AE4 = sub_8070048;
+ sub_80CA3C0(var);
+}
+
+void ItemUseInBattle_PPRecovery(u8 var)
+{
+ gUnknown_03004AE4 = DoPPRecoveryItemEffect;
+ sub_80CA3C0(var);
+}
+
+void unref_sub_80CA448(u8 var)
+{
+ MenuZeroFillWindowRect(0, 0xD, 0xD, 0x14);
+
+ if (ExecuteTableBasedItemEffect__(0, gScriptItemId, 0) == FALSE)
+ {
+ RemoveBagItem(gScriptItemId, 1);
+ GetMonNickname(&gPlayerParty[0], gStringVar1);
+ StringExpandPlaceholders(gStringVar4, gOtherText_SnapConfusion);
+ DisplayItemMessageOnField(var, gStringVar4, sub_80A7094, 1);
+ }
+ else
+ {
+ DisplayItemMessageOnField(var, gOtherText_WontHaveAnyEffect, CleanUpItemMenuMessage, 1);
+ }
+}
+
+void ItemUseInBattle_Escape(u8 taskId)
+{
+ MenuZeroFillWindowRect(0, 0xD, 0xD, 0x14);
+
+ if((gBattleTypeFlags & BATTLE_TYPE_TRAINER) == FALSE)
+ {
+ PrepareItemUseMessage();
+ DisplayItemMessageOnField(taskId, gStringVar4, sub_80A7094, 1);
+ }
+ else
+ {
+ DisplayDadsAdviceCannotUseItemMessage(taskId, gTasks[taskId].data[2]);
+ }
+}
+
+void ItemUseOutOfBattle_EnigmaBerry(u8 taskId)
+{
+ switch (GetItemEffectType(gScriptItemId) - 1)
+ {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 10:
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ case 16:
+ gTasks[taskId].data[15] = 1;
+ ItemUseOutOfBattle_Medicine(taskId);
+ break;
+ case 9:
+ gTasks[taskId].data[15] = 1;
+ ItemUseOutOfBattle_SacredAsh(taskId);
+ break;
+ case 0:
+ gTasks[taskId].data[15] = 1;
+ ItemUseOutOfBattle_RareCandy(taskId);
+ break;
+ case 18:
+ case 19:
+ gTasks[taskId].data[15] = 1;
+ ItemUseOutOfBattle_PPUp(taskId);
+ break;
+ case 20:
+ gTasks[taskId].data[15] = 1;
+ ItemUseOutOfBattle_PPRecovery(taskId);
+ break;
+ default:
+ gTasks[taskId].data[15] = 4;
+ ItemUseOutOfBattle_CannotUse(taskId);
+ }
+}
+
+void ItemUseInBattle_EnigmaBerry(u8 taskId)
+{
+ switch (GetItemEffectType(gScriptItemId))
+ {
+ case 0:
+ ItemUseInBattle_StatIncrease(taskId);
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 11:
+ ItemUseInBattle_Medicine(taskId);
+ break;
+ case 21:
+ ItemUseInBattle_PPRecovery(taskId);
+ break;
+ default:
+ ItemUseOutOfBattle_CannotUse(taskId);
+ }
+}
+
+void ItemUseOutOfBattle_CannotUse(u8 taskId)
+{
+ DisplayDadsAdviceCannotUseItemMessage(taskId, gTasks[taskId].data[2]);
+}
diff --git a/src/field/landmark.c b/src/field/landmark.c
new file mode 100644
index 000000000..6a53716bb
--- /dev/null
+++ b/src/field/landmark.c
@@ -0,0 +1,73 @@
+#include "global.h"
+#include "landmark.h"
+#include "event_data.h"
+
+#define MAPSEC_NONE 0x58
+
+struct Landmark
+{
+ u8 *name;
+ u16 flag;
+};
+
+struct LandmarkList
+{
+ u8 mapSection;
+ u8 id;
+ const struct Landmark **landmarks;
+};
+
+extern const struct LandmarkList gLandmarkLists[];
+
+static const struct Landmark **GetLandmarks(u8 mapSection, u8 id);
+
+u8 *GetLandmarkName(u8 mapSection, u8 id, u8 count)
+{
+ const struct Landmark **landmarks = GetLandmarks(mapSection, id);
+
+ if (!landmarks)
+ return NULL;
+
+ while (1)
+ {
+ const struct Landmark *landmark = *landmarks;
+
+ if (landmark->flag == 0xFFFF || FlagGet(landmark->flag) == TRUE)
+ {
+ if (count == 0)
+ break;
+ else
+ count--;
+ }
+
+ landmarks++;
+ if (!*landmarks)
+ return NULL;
+ }
+
+ return (*landmarks)->name;
+}
+
+static const struct Landmark **GetLandmarks(u8 mapSection, u8 id)
+{
+ u16 i = 0;
+
+ for (; gLandmarkLists[i].mapSection != MAPSEC_NONE; i++)
+ {
+ if (gLandmarkLists[i].mapSection > mapSection)
+ return NULL;
+ if (gLandmarkLists[i].mapSection == mapSection)
+ break;
+ }
+
+ if (gLandmarkLists[i].mapSection == MAPSEC_NONE)
+ return NULL;
+
+ for (; gLandmarkLists[i].mapSection == mapSection; i++)
+ {
+ if (gLandmarkLists[i].id == id)
+ return gLandmarkLists[i].landmarks;
+ }
+
+ return NULL;
+}
diff --git a/src/field/lottery_corner.c b/src/field/lottery_corner.c
new file mode 100644
index 000000000..c2c25b9ac
--- /dev/null
+++ b/src/field/lottery_corner.c
@@ -0,0 +1,174 @@
+#include "global.h"
+#include "lottery_corner.h"
+#include "event_data.h"
+#include "items.h"
+#include "rng.h"
+#include "species.h"
+#include "string_util.h"
+#include "text.h"
+
+extern u16 gScriptResult;
+extern u16 gSpecialVar_0x8004;
+extern struct PokemonStorage gPokemonStorage;
+extern u16 gSpecialVar_0x8005;
+extern u16 gSpecialVar_0x8006;
+static EWRAM_DATA u16 sWinNumberDigit = 0;
+static EWRAM_DATA u16 sOtIdDigit = 0;
+
+static const u16 sLotteryPrizes[] =
+{
+ ITEM_PP_UP,
+ ITEM_EXP_SHARE,
+ ITEM_MAX_REVIVE,
+ ITEM_MASTER_BALL,
+};
+
+static u8 GetMatchingDigits(u16, u16);
+
+void ResetLotteryCorner(void)
+{
+ u16 rand = Random();
+
+ SetLotteryNumber((Random() << 16) | rand);
+ VarSet(VAR_POKELOT_PRIZE, 0);
+}
+
+void SetRandomLotteryNumber(u16 i)
+{
+ u32 var = Random();
+
+ while (--i != 0xFFFF)
+ var = var * 1103515245 + 12345;
+
+ SetLotteryNumber(var);
+}
+
+void RetrieveLotteryNumber(void)
+{
+ u16 lottoNumber = GetLotteryNumber();
+ gScriptResult = lottoNumber;
+}
+
+void PickLotteryCornerTicket(void)
+{
+ u16 i;
+ u16 j;
+ u32 box;
+ u32 slot;
+
+ gSpecialVar_0x8004 = 0;
+ slot = 0;
+ box = 0;
+ for (i = 0; i < 6; i++)
+ {
+ struct Pokemon *pkmn = &gPlayerParty[i];
+
+ // UB: Too few arguments for function GetMonData
+ if (GetMonData(pkmn, MON_DATA_SPECIES) != SPECIES_NONE)
+ {
+ // do not calculate ticket values for eggs.
+ if (!GetMonData(pkmn, MON_DATA_IS_EGG))
+ {
+ u32 otId = GetMonData(pkmn, MON_DATA_OT_ID);
+ u8 numMatchingDigits = GetMatchingDigits(gScriptResult, otId);
+
+ if (numMatchingDigits > gSpecialVar_0x8004 && numMatchingDigits > 1)
+ {
+ gSpecialVar_0x8004 = numMatchingDigits - 1;
+ box = 14;
+ slot = i;
+ }
+ }
+ }
+ else // pokemon are always arranged from populated spots first to unpopulated, so the moment a NONE species is found, that's the end of the list.
+ break;
+ }
+
+ // player has 14 boxes.
+ for (i = 0; i < 14; i++)
+ {
+ // player has 30 slots per box.
+ for (j = 0; j < 30; j++)
+ {
+ struct BoxPokemon *pkmn = &gPokemonStorage.boxes[i][j];
+
+ // UB: Too few arguments for function GetMonData
+ if (GetBoxMonData(pkmn, MON_DATA_SPECIES) != SPECIES_NONE &&
+ !GetBoxMonData(pkmn, MON_DATA_IS_EGG))
+ {
+ u32 otId = GetBoxMonData(pkmn, MON_DATA_OT_ID);
+ u8 numMatchingDigits = GetMatchingDigits(gScriptResult, otId);
+
+ if (numMatchingDigits > gSpecialVar_0x8004 && numMatchingDigits > 1)
+ {
+ gSpecialVar_0x8004 = numMatchingDigits - 1;
+ box = i;
+ slot = j;
+ }
+ }
+ }
+ }
+
+ if (gSpecialVar_0x8004 != 0)
+ {
+ gSpecialVar_0x8005 = sLotteryPrizes[gSpecialVar_0x8004 - 1];
+
+ if (box == 14)
+ {
+ gSpecialVar_0x8006 = 0;
+ GetMonData(&gPlayerParty[slot], MON_DATA_NICKNAME, gStringVar1);
+ }
+ else
+ {
+ gSpecialVar_0x8006 = 1;
+ GetBoxMonData(&gPokemonStorage.boxes[box][slot], MON_DATA_NICKNAME, gStringVar1);
+ }
+ StringGetEnd10(gStringVar1);
+ }
+}
+
+static u8 GetMatchingDigits(u16 winNumber, u16 otId)
+{
+ u8 i;
+ u8 matchingDigits = 0;
+
+ for (i = 0; i < 5; i++)
+ {
+ sWinNumberDigit = winNumber % 10;
+ sOtIdDigit = otId % 10;
+
+ if (sWinNumberDigit == sOtIdDigit)
+ {
+ winNumber = winNumber / 10;
+ otId = otId / 10;
+ matchingDigits++;
+ }
+ else
+ break;
+ }
+ return matchingDigits;
+}
+
+// lottery numbers go from 0 to 99999, not 65535 (0xFFFF). interestingly enough, the function that calls GetLotteryNumber shifts to u16, so it cant be anything above 65535 anyway.
+void SetLotteryNumber(u32 lotteryNum)
+{
+ u16 lowNum = lotteryNum >> 16;
+ u16 highNum = lotteryNum;
+
+ VarSet(VAR_POKELOT_RND1, highNum);
+ VarSet(VAR_POKELOT_RND2, lowNum);
+}
+
+u32 GetLotteryNumber(void)
+{
+ u16 highNum = VarGet(VAR_POKELOT_RND1);
+ u16 lowNum = VarGet(VAR_POKELOT_RND2);
+
+ return (lowNum << 16) | highNum;
+}
+
+// interestingly, this may have been the original lottery number set function, but GF tried to change it to 32-bit later but didnt finish changing all calls as one GetLotteryNumber still shifts to u16.
+void SetLotteryNumber16_Unused(u16 lotteryNum)
+{
+ SetLotteryNumber(lotteryNum);
+}
diff --git a/src/field/map_name_popup.c b/src/field/map_name_popup.c
new file mode 100644
index 000000000..01105d0db
--- /dev/null
+++ b/src/field/map_name_popup.c
@@ -0,0 +1,107 @@
+#include "global.h"
+#include "map_name_popup.h"
+#include "event_data.h"
+#include "menu.h"
+#include "region_map.h"
+#include "task.h"
+
+EWRAM_DATA static u8 sTaskId = 0;
+
+static void Task_MapNamePopup(u8);
+static void DrawMapNamePopup(void);
+
+bool8 unref_sub_80A2F44(void)
+{
+ CloseMenu();
+ ShowMapNamePopup();
+ return 1;
+}
+
+void ShowMapNamePopup(void)
+{
+ if (FlagGet(0x4000) != TRUE)
+ {
+ if (!FuncIsActiveTask(Task_MapNamePopup))
+ {
+ sTaskId = CreateTask(Task_MapNamePopup, 90);
+ REG_BG0VOFS = 32;
+ DrawMapNamePopup();
+ gTasks[sTaskId].data[0] = 0;
+ gTasks[sTaskId].data[2] = 32;
+ }
+ else
+ {
+ if (gTasks[sTaskId].data[0] != 2)
+ gTasks[sTaskId].data[0] = 2;
+ gTasks[sTaskId].data[3] = 1;
+ }
+ }
+}
+
+void Task_MapNamePopup(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ task->data[2] -= 2;
+ if (task->data[2] <= 0 )
+ {
+ task->data[0] = 1;
+ gTasks[sTaskId].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] > 31)
+ {
+ if (task->data[3])
+ {
+ DrawMapNamePopup();
+ task->data[0] = 0;
+ task->data[3] = 0;
+ }
+ else
+ {
+ task->data[0] = 4;
+ return;
+ }
+ }
+ break;
+ case 4:
+ HideMapNamePopup();
+ return;
+ }
+
+ REG_BG0VOFS = task->data[2];
+}
+
+void HideMapNamePopup(void)
+{
+ if (FuncIsActiveTask(Task_MapNamePopup))
+ {
+ MenuLoadTextWindowGraphics();
+ MenuZeroFillWindowRect(0, 0, 13, 3);
+ REG_BG0VOFS = 0;
+ DestroyTask(sTaskId);
+ }
+}
+
+void DrawMapNamePopup(void)
+{
+ u8 name[20];
+
+ MenuLoadTextWindowGraphics_OverrideFrameType(0);
+ GetMapSectionName(name, gMapHeader.regionMapSectionId, 0);
+ MenuDrawTextWindow(0, 0, 13, 3);
+ sub_8072BD8(name, 1, 1, 0x60);
+}
diff --git a/src/field/map_obj_lock.c b/src/field/map_obj_lock.c
new file mode 100644
index 000000000..2856320b8
--- /dev/null
+++ b/src/field/map_obj_lock.c
@@ -0,0 +1,118 @@
+#include "global.h"
+#include "map_obj_lock.h"
+#include "field_map_obj.h"
+#include "field_map_obj_helpers.h"
+#include "field_player_avatar.h"
+#include "script_movement.h"
+#include "task.h"
+
+extern u16 gScriptFacing;
+
+bool8 walkrun_is_standing_still(void)
+{
+ if (gPlayerAvatar.running1 == 1)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+void sub_8064CDC(u8 taskId)
+{
+ if (walkrun_is_standing_still())
+ {
+ sub_80594C0();
+ DestroyTask(taskId);
+ }
+}
+
+bool8 sub_8064CFC(void)
+{
+ if (FuncIsActiveTask(sub_8064CDC))
+ {
+ return FALSE;
+ }
+ else
+ {
+ sub_80597F4();
+ return TRUE;
+ }
+}
+
+void ScriptFreezeMapObjects(void)
+{
+ FreezeMapObjects();
+ CreateTask(sub_8064CDC, 80);
+}
+
+void sub_8064D38(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ if (!task->data[0] && walkrun_is_standing_still() == TRUE)
+ {
+ sub_80594C0();
+ 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_8064DB4(void)
+{
+ if (FuncIsActiveTask(sub_8064D38))
+ {
+ return FALSE;
+ }
+ else
+ {
+ sub_80597F4();
+ return TRUE;
+ }
+}
+
+void LockSelectedMapObject(void)
+{
+ u8 taskId;
+ FreezeMapObjectsExceptOne(gSelectedMapObject);
+ taskId = CreateTask(sub_8064D38, 80);
+ if (!gMapObjects[gSelectedMapObject].mapobj_bit_1)
+ {
+ FreezeMapObject(&gMapObjects[gSelectedMapObject]);
+ gTasks[taskId].data[1] = 1;
+ }
+}
+
+void sub_8064E2C(void)
+{
+ u8 objectId = GetFieldObjectIdByLocalIdAndMap(0xFF, 0, 0);
+ FieldObjectClearAnimIfSpecialAnimFinished(&gMapObjects[objectId]);
+ sub_80A2178();
+ UnfreezeMapObjects();
+}
+
+void unref_sub_8064E5C(void)
+{
+ u8 objectId;
+
+ if (gMapObjects[gSelectedMapObject].active)
+ FieldObjectClearAnimIfSpecialAnimFinished(&gMapObjects[gSelectedMapObject]);
+ objectId = GetFieldObjectIdByLocalIdAndMap(0xFF, 0, 0);
+ FieldObjectClearAnimIfSpecialAnimFinished(&gMapObjects[objectId]);
+ sub_80A2178();
+ UnfreezeMapObjects();
+}
+
+void sub_8064EAC(void)
+{
+ FieldObjectFaceOppositeDirection(&gMapObjects[gSelectedMapObject], gScriptFacing);
+}
+
+void sub_8064ED4(void)
+{
+ FieldObjectClearAnimIfSpecialAnimActive(&gMapObjects[gSelectedMapObject]);
+}
diff --git a/src/field/mauville_man.c b/src/field/mauville_man.c
new file mode 100644
index 000000000..33bc39648
--- /dev/null
+++ b/src/field/mauville_man.c
@@ -0,0 +1,1311 @@
+#include "global.h"
+#include "bard_music.h"
+#include "mauville_man.h"
+#include "easy_chat.h"
+#include "event_data.h"
+#include "field_message_box.h"
+#include "m4a.h"
+#include "menu.h"
+#include "overworld.h"
+#include "rng.h"
+#include "script.h"
+#include "songs.h"
+#include "sound.h"
+#include "string_util.h"
+#include "strings.h"
+#include "task.h"
+#include "trader.h"
+
+#define MACRO1(a) (((a) % 4) + (((a) / 8) & 1))
+
+extern struct MusicPlayerInfo gMPlay_SE2;
+
+extern u16 gScriptResult;
+extern u16 gSpecialVar_0x8004;
+
+extern const u8 gTextStoryteller_Story1Title[];
+extern const u8 gTextStoryteller_Story1Action[];
+extern const u8 gTextStoryteller_Story1Text[];
+extern const u8 gTextStoryteller_Story2Title[];
+extern const u8 gTextStoryteller_Story2Action[];
+extern const u8 gTextStoryteller_Story2Text[];
+extern const u8 gTextStoryteller_Story3Title[];
+extern const u8 gTextStoryteller_Story3Action[];
+extern const u8 gTextStoryteller_Story3Text[];
+extern const u8 gTextStoryteller_Story4Title[];
+extern const u8 gTextStoryteller_Story4Action[];
+extern const u8 gTextStoryteller_Story4Text[];
+extern const u8 gTextStoryteller_Story5Title[];
+extern const u8 gTextStoryteller_Story5Action[];
+extern const u8 gTextStoryteller_Story5Text[];
+extern const u8 gTextStoryteller_Story6Title[];
+extern const u8 gTextStoryteller_Story6Action[];
+extern const u8 gTextStoryteller_Story6Text[];
+extern const u8 gTextStoryteller_Story7Title[];
+extern const u8 gTextStoryteller_Story7Action[];
+extern const u8 gTextStoryteller_Story7Text[];
+extern const u8 gTextStoryteller_Story8Title[];
+extern const u8 gTextStoryteller_Story8Action[];
+extern const u8 gTextStoryteller_Story8Text[];
+extern const u8 gTextStoryteller_Story9Title[];
+extern const u8 gTextStoryteller_Story9Action[];
+extern const u8 gTextStoryteller_Story9Text[];
+extern const u8 gTextStoryteller_Story10Title[];
+extern const u8 gTextStoryteller_Story10Action[];
+extern const u8 gTextStoryteller_Story10Text[];
+extern const u8 gTextStoryteller_Story11Title[];
+extern const u8 gTextStoryteller_Story11Action[];
+extern const u8 gTextStoryteller_Story11Text[];
+extern const u8 gTextStoryteller_Story12Title[];
+extern const u8 gTextStoryteller_Story12Action[];
+extern const u8 gTextStoryteller_Story12Text[];
+extern const u8 gTextStoryteller_Story13Title[];
+extern const u8 gTextStoryteller_Story13Action[];
+extern const u8 gTextStoryteller_Story13Text[];
+extern const u8 gTextStoryteller_Story14Title[];
+extern const u8 gTextStoryteller_Story14Action[];
+extern const u8 gTextStoryteller_Story14Text[];
+extern const u8 gTextStoryteller_Story15Title[];
+extern const u8 gTextStoryteller_Story15Action[];
+extern const u8 gTextStoryteller_Story15Text[];
+extern const u8 gTextStoryteller_Story16Title[];
+extern const u8 gTextStoryteller_Story16Action[];
+extern const u8 gTextStoryteller_Story16Text[];
+extern const u8 gTextStoryteller_Story17Title[];
+extern const u8 gTextStoryteller_Story17Action[];
+extern const u8 gTextStoryteller_Story17Text[];
+extern const u8 gTextStoryteller_Story18Title[];
+extern const u8 gTextStoryteller_Story18Action[];
+extern const u8 gTextStoryteller_Story18Text[];
+extern const u8 gTextStoryteller_Story19Title[];
+extern const u8 gTextStoryteller_Story19Action[];
+extern const u8 gTextStoryteller_Story19Text[];
+extern const u8 gTextStoryteller_Story20Title[];
+extern const u8 gTextStoryteller_Story20Action[];
+extern const u8 gTextStoryteller_Story20Text[];
+extern const u8 gTextStoryteller_Story21Title[];
+extern const u8 gTextStoryteller_Story21Action[];
+extern const u8 gTextStoryteller_Story21Text[];
+extern const u8 gTextStoryteller_Story22Title[];
+extern const u8 gTextStoryteller_Story22Action[];
+extern const u8 gTextStoryteller_Story22Text[];
+extern const u8 gTextStoryteller_Story23Title[];
+extern const u8 gTextStoryteller_Story23Action[];
+extern const u8 gTextStoryteller_Story23Text[];
+extern const u8 gTextStoryteller_Story24Title[];
+extern const u8 gTextStoryteller_Story24Action[];
+extern const u8 gTextStoryteller_Story24Text[];
+extern const u8 gTextStoryteller_Story25Title[];
+extern const u8 gTextStoryteller_Story25Action[];
+extern const u8 gTextStoryteller_Story25Text[];
+extern const u8 gTextStoryteller_Story26Title[];
+extern const u8 gTextStoryteller_Story26Action[];
+extern const u8 gTextStoryteller_Story26Text[];
+extern const u8 gTextStoryteller_Story27Title[];
+extern const u8 gTextStoryteller_Story27Action[];
+extern const u8 gTextStoryteller_Story27Text[];
+extern const u8 gTextStoryteller_Story28Title[];
+extern const u8 gTextStoryteller_Story28Action[];
+extern const u8 gTextStoryteller_Story28Text[];
+extern const u8 gTextStoryteller_Story29Title[];
+extern const u8 gTextStoryteller_Story29Action[];
+extern const u8 gTextStoryteller_Story29Text[];
+extern const u8 gTextStoryteller_Story30Title[];
+extern const u8 gTextStoryteller_Story30Action[];
+extern const u8 gTextStoryteller_Story30Text[];
+extern const u8 gTextStoryteller_Story31Title[];
+extern const u8 gTextStoryteller_Story31Action[];
+extern const u8 gTextStoryteller_Story31Text[];
+extern const u8 gTextStoryteller_Story32Title[];
+extern const u8 gTextStoryteller_Story32Action[];
+extern const u8 gTextStoryteller_Story32Text[];
+extern const u8 gTextStoryteller_Story33Title[];
+extern const u8 gTextStoryteller_Story33Action[];
+extern const u8 gTextStoryteller_Story33Text[];
+extern const u8 gTextStoryteller_Story34Title[];
+extern const u8 gTextStoryteller_Story34Action[];
+extern const u8 gTextStoryteller_Story34Text[];
+extern const u8 gTextStoryteller_Story35Title[];
+extern const u8 gTextStoryteller_Story35Action[];
+extern const u8 gTextStoryteller_Story35Text[];
+extern const u8 gTextStoryteller_Story36Title[];
+extern const u8 gTextStoryteller_Story36Action[];
+extern const u8 gTextStoryteller_Story36Text[];
+
+extern struct BardSong gUnknown_03005DA0;
+
+EWRAM_DATA static u16 gUnknown_020388BC = 0; // set but not used?
+
+static const u16 sDefaultBardSongLyrics[] =
+{
+#ifdef ENGLISH
+ EC_WORD_SISTER,
+ EC_WORD_EATS,
+ EC_WORD_SWEETS,
+ EC_WORD_VORACIOUS,
+ EC_WORD_AND,
+ EC_WORD_DROOLING,
+#else
+ EC_WORD_SISTER,
+ EC_WORD_MUST_BE,
+ EC_WORD_SWEETS,
+ EC_WORD_VORACIOUS,
+ EC_WORD_DROOLING,
+ EC_WORD_THICK,
+#endif
+};
+
+static const u8 *const sGiddyAdjectives[] =
+{
+ OtherText_SoPretty,
+ OtherText_SoDarling,
+ OtherText_SoRelaxed,
+ OtherText_SoSunny,
+ OtherText_SoDesirable,
+ OtherText_SoExciting,
+ OtherText_SoAmusing,
+ OtherText_SoMagical,
+};
+
+static const u8 *const sGiddyQuestions[] =
+{
+ OtherText_WantVacationNicePlace,
+ OtherText_BoughtCrayonsIsNice,
+ OtherText_IfWeCouldFloat,
+ OtherText_SandWashesAwayMakeSad,
+ OtherText_WhatsBottomSeaLike,
+ OtherText_SeeSettingSun,
+ OtherText_LyingInGreenGrass,
+ OtherText_SecretBasesWonderful,
+};
+
+static void sub_80F7DC0(void);
+static void Task_BardSong(u8);
+static void StartBardSong(u8);
+static void StorytellerSetup(void);
+static void sub_80F8428(void);
+
+static void SetupBard(void)
+{
+ u16 i;
+ struct MauvilleManBard *bard = &gSaveBlock1.mauvilleMan.bard;
+
+ bard->id = MAUVILLE_MAN_BARD;
+ bard->hasChangedSong = FALSE;
+ for (i = 0; i < 6; i++)
+ bard->songLyrics[i] = sDefaultBardSongLyrics[i];
+}
+
+static void SetupHipster(void)
+{
+ struct MauvilleManHipster *hipster = &gSaveBlock1.mauvilleMan.hipster;
+
+ hipster->id = MAUVILLE_MAN_HIPSTER;
+ hipster->alreadySpoken = FALSE;
+}
+
+static void SetupStoryteller(void)
+{
+ StorytellerSetup();
+}
+
+static void SetupGiddy(void)
+{
+ struct MauvilleManGiddy *giddy = &gSaveBlock1.mauvilleMan.giddy;
+
+ giddy->id = MAUVILLE_MAN_GIDDY;
+ giddy->taleCounter = 0;
+}
+
+static void SetupTrader(void)
+{
+ TraderSetup();
+}
+
+void SetupMauvilleOldMan(void)
+{
+ u16 trainerId = (gSaveBlock2.playerTrainerId[1] << 8) | gSaveBlock2.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;
+ }
+ sub_80F83D0();
+}
+
+static u8 GetCurrentMauvilleOldMan(void)
+{
+ struct MauvilleManCommon *common = &gSaveBlock1.mauvilleMan.common;
+
+ return common->id;
+}
+
+void ScrSpecial_GetCurrentMauvilleMan(void)
+{
+ gScriptResult = GetCurrentMauvilleOldMan();
+}
+
+void ScrSpecial_HasBardSongBeenChanged(void)
+{
+ u16 *scriptResult = &gScriptResult; // why??
+ struct MauvilleManBard *bard = &gSaveBlock1.mauvilleMan.bard;
+
+ *scriptResult = bard->hasChangedSong;
+}
+
+void ScrSpecial_SaveBardSongLyrics(void)
+{
+ u16 i;
+ struct MauvilleManBard *bard = &gSaveBlock1.mauvilleMan.bard;
+
+ StringCopy(bard->playerName, gSaveBlock2.playerName);
+
+ for (i = 0; i < 4; i++)
+ bard->playerTrainerId[i] = gSaveBlock2.playerTrainerId[i];
+
+ for (i = 0; i < 6; i++)
+ bard->songLyrics[i] = bard->temporaryLyrics[i];
+
+ bard->hasChangedSong = TRUE;
+}
+
+// Copies lyrics into gStringVar4
+void PrepareSongText(void)
+{
+ struct MauvilleManBard *bard = &gSaveBlock1.mauvilleMan.bard;
+ u16 specialVar = gSpecialVar_0x8004; // It's a bit odd to use this temp variable, but it seems needed to match.
+ u16 *lyrics;
+ u16 lineNum;
+ u8 *wordEnd;
+ u8 *str;
+
+ lyrics = bard->temporaryLyrics;
+ if (specialVar == 0)
+ lyrics = bard->songLyrics;
+ wordEnd = gStringVar4;
+ str = wordEnd;
+ // Put three words on each line
+ for (lineNum = 0; lineNum < 2; lineNum++)
+ {
+ wordEnd = EasyChat_GetWordText(wordEnd, *(lyrics++));
+ while (wordEnd != str)
+ {
+ if (*str == CHAR_SPACE)
+ *str = CHAR_SONG_WORD_SEPARATOR;
+ str++;
+ }
+
+ str++;
+ *(wordEnd++) = CHAR_SPACE;
+
+ wordEnd = EasyChat_GetWordText(wordEnd, *(lyrics++));
+ while (wordEnd != str)
+ {
+ if (*str == CHAR_SPACE)
+ *str = CHAR_SONG_WORD_SEPARATOR;
+ str++;
+ }
+
+ str++;
+ *(wordEnd++) = CHAR_NEWLINE;
+
+ wordEnd = EasyChat_GetWordText(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);
+ MenuDisplayMessageBox();
+ ScriptContext1_Stop();
+}
+
+void ScrSpecial_GetHipsterSpokenFlag(void)
+{
+ u16 *scriptResult = &gScriptResult; // again??
+ struct MauvilleManHipster *hipster = &gSaveBlock1.mauvilleMan.hipster;
+
+ *scriptResult = hipster->alreadySpoken;
+}
+
+void ScrSpecial_SetHipsterSpokenFlag(void)
+{
+ struct MauvilleManHipster *hipster = &gSaveBlock1.mauvilleMan.hipster;
+
+ hipster->alreadySpoken = TRUE;
+}
+
+void ScrSpecial_HipsterTeachWord(void)
+{
+ u16 var = sub_80EB8EC();
+
+ if (var == 0xFFFF)
+ {
+ gScriptResult = FALSE;
+ }
+ else
+ {
+ EasyChat_GetWordText(gStringVar1, var);
+ gScriptResult = TRUE;
+ }
+}
+
+void ScrSpecial_GiddyShouldTellAnotherTale(void)
+{
+ struct MauvilleManGiddy *giddy = &gSaveBlock1.mauvilleMan.giddy;
+
+ if (giddy->taleCounter == 10)
+ {
+ gScriptResult = FALSE;
+ giddy->taleCounter = 0;
+ }
+ else
+ {
+ gScriptResult = TRUE;
+ }
+}
+
+void ScrSpecial_GenerateGiddyLine(void)
+{
+ struct MauvilleManGiddy *giddy = &gSaveBlock1.mauvilleMan.giddy;
+
+ if (giddy->taleCounter == 0)
+ sub_80F7DC0();
+
+ if (giddy->randomWords[giddy->taleCounter] != 0xFFFF) // is not the last element of the array?
+ {
+ u8 *stringPtr;
+ u32 adjective = Random();
+
+ adjective %= 8;
+ stringPtr = EasyChat_GetWordText(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++;
+
+ gScriptResult = TRUE;
+}
+
+#ifdef NONMATCHING
+static void sub_80F7DC0(void)
+{
+ u16 arr[][2] =
+ {
+ { 0x0, 0},
+ { 0xC, 0},
+ { 0xD, 0},
+ {0x12, 0},
+ {0x13, 0},
+ {0x15, 0},
+ };
+ u16 i;
+ u16 r10;
+ u16 r7;
+
+ for (i = 0; i < 8; i++)
+ {
+ struct MauvilleManGiddy *giddy = &gSaveBlock1.mauvilleMan.giddy;
+
+ //gSaveBlock1.mauvilleMan.giddy.questionList[i] = i;
+ giddy->questionList[i] = i;
+ }
+
+ // Scramble questions
+ for (i = 0; i < 8; i++)
+ {
+ struct MauvilleManGiddy *giddy = &gSaveBlock1.mauvilleMan.giddy;
+
+ /*
+ u16 r1 = Random() % (i + 1);
+ u8 r7 = gSaveBlock1.mauvilleMan.giddy.questionList[i];
+ gSaveBlock1.mauvilleMan.giddy.questionList[i] = gSaveBlock1.mauvilleMan.giddy.questionList[r1];
+ gSaveBlock1.mauvilleMan.giddy.questionList[r1] = r7;
+ */
+ u16 r1 = Random() % (i + 1);
+ u8 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] = sub_80EAE88(arr[i][0]);
+ r10 += arr[i][1];
+ }
+
+ {
+ struct MauvilleManGiddy *giddy = &gSaveBlock1.mauvilleMan.giddy;
+ giddy->questionNum = 0;
+ }
+ //gSaveBlock1.mauvilleMan.giddy.questionNum = 0;
+
+ r7 = 0;
+ for (i = 0; i < 10; i++)
+ {
+ struct MauvilleManGiddy *giddy = &gSaveBlock1.mauvilleMan.giddy;
+
+ u16 var = Random() % 10;
+ if (var < 3 && r7 < 8)
+ {
+ //gSaveBlock1.mauvilleMan.giddy.randomWords[i] = 0xFFFF;
+ giddy->randomWords[i] = 0xFFFF;
+ r7++;
+ }
+ //_080F7E90
+ else
+ {
+ s16 r2 = Random() % r10;
+
+ u16 r1 = 0;
+
+ while (i < 6) // comparing the wrong variable
+ {
+ r2 = arr[r1][1] - r2;
+ if (r2 <= 0)
+ break;
+ r1++;
+ }
+
+ if (r1 == 6)
+ r1 = 0;
+ //gSaveBlock1.mauvilleMan.giddy.randomWords[i] = sub_80EB784(arr[r1][0]);
+ giddy->randomWords[i] = sub_80EB784(arr[r1][0]);
+ }
+ }
+}
+#else
+
+static const u16 gUnknown_083E53C8[][2] =
+{
+ { 0x0, 0},
+ { 0xC, 0},
+ { 0xD, 0},
+ {0x12, 0},
+ {0x13, 0},
+ {0x15, 0},
+};
+
+__attribute__((naked))
+static void sub_80F7DC0(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\
+ sub sp, 0x18\n\
+ ldr r1, _080F7E84 @ =gUnknown_083E53C8\n\
+ mov r0, sp\n\
+ movs r2, 0x18\n\
+ bl memcpy\n\
+ movs r5, 0\n\
+ movs r0, 0x2\n\
+ add r0, sp\n\
+ mov r8, r0\n\
+ ldr r1, _080F7E88 @ =gSaveBlock1 + 0x2D94\n\
+ adds r1, 0x18\n\
+ adds r3, r1, 0\n\
+_080F7DE4:\n\
+ adds r0, r3, r5\n\
+ strb r5, [r0]\n\
+ adds r0, r5, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r5, r0, 16\n\
+ cmp r5, 0x7\n\
+ bls _080F7DE4\n\
+ movs r5, 0\n\
+ ldr r2, _080F7E88 @ =gSaveBlock1 + 0x2D94\n\
+ adds r2, 0x4\n\
+ mov r9, r2\n\
+ adds r6, r1, 0\n\
+_080F7DFC:\n\
+ bl Random\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ adds r4, r5, 0x1\n\
+ adds r1, r4, 0\n\
+ bl __modsi3\n\
+ lsls r0, 16\n\
+ lsrs r1, r0, 16\n\
+ adds r2, r6, r5\n\
+ ldrb r7, [r2]\n\
+ adds r1, r6, r1\n\
+ ldrb r0, [r1]\n\
+ strb r0, [r2]\n\
+ strb r7, [r1]\n\
+ lsls r4, 16\n\
+ lsrs r5, r4, 16\n\
+ cmp r5, 0x7\n\
+ bls _080F7DFC\n\
+ movs r3, 0\n\
+ mov r10, r3\n\
+ movs r5, 0\n\
+_080F7E2A:\n\
+ lsls r4, r5, 2\n\
+ mov r1, sp\n\
+ adds r0, r1, r4\n\
+ ldrb r0, [r0]\n\
+ bl sub_80EAE88\n\
+ add r4, r8\n\
+ strh r0, [r4]\n\
+ add r0, r10\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ mov r10, r0\n\
+ adds r0, r5, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r5, r0, 16\n\
+ cmp r5, 0x5\n\
+ bls _080F7E2A\n\
+ movs r0, 0\n\
+ ldr r2, _080F7E88 @ =gSaveBlock1 + 0x2D94\n\
+ strb r0, [r2, 0x2]\n\
+ movs r7, 0\n\
+ movs r5, 0\n\
+_080F7E56:\n\
+ bl Random\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ movs r1, 0xA\n\
+ bl __umodsi3\n\
+ lsls r0, 16\n\
+ lsrs r1, r0, 16\n\
+ cmp r1, 0x2\n\
+ bhi _080F7E90\n\
+ cmp r7, 0x7\n\
+ bhi _080F7E90\n\
+ lsls r0, r5, 1\n\
+ add r0, r9\n\
+ ldr r1, _080F7E8C @ =0x0000ffff\n\
+ strh r1, [r0]\n\
+ adds r0, r7, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r7, r0, 16\n\
+ adds r4, r5, 0x1\n\
+ b _080F7EE2\n\
+ .align 2, 0\n\
+_080F7E84: .4byte gUnknown_083E53C8\n\
+_080F7E88: .4byte gSaveBlock1 + 0x2D94\n\
+_080F7E8C: .4byte 0x0000ffff\n\
+_080F7E90:\n\
+ bl Random\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ mov r1, r10\n\
+ bl __umodsi3\n\
+ lsls r0, 16\n\
+ lsrs r2, r0, 16\n\
+ movs r1, 0\n\
+ adds r4, r5, 0x1\n\
+ lsls r6, r5, 1\n\
+ cmp r5, 0x5\n\
+ bhi _080F7ECC\n\
+ mov r3, r8\n\
+ ldrh r0, [r3]\n\
+ b _080F7EC2\n\
+_080F7EB2:\n\
+ adds r0, r1, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r1, r0, 16\n\
+ cmp r5, 0x5\n\
+ bhi _080F7ECC\n\
+ lsls r0, r1, 2\n\
+ adds r0, r3, r0\n\
+ ldrh r0, [r0]\n\
+_080F7EC2:\n\
+ subs r0, r2, r0\n\
+ lsls r0, 16\n\
+ lsrs r2, r0, 16\n\
+ cmp r0, 0\n\
+ bgt _080F7EB2\n\
+_080F7ECC:\n\
+ cmp r1, 0x6\n\
+ bne _080F7ED2\n\
+ movs r1, 0\n\
+_080F7ED2:\n\
+ lsls r0, r1, 2\n\
+ add r0, sp\n\
+ ldrh r0, [r0]\n\
+ bl sub_80EB784\n\
+ mov r2, r9\n\
+ adds r1, r2, r6\n\
+ strh r0, [r1]\n\
+_080F7EE2:\n\
+ lsls r0, r4, 16\n\
+ lsrs r5, r0, 16\n\
+ cmp r5, 0x9\n\
+ bls _080F7E56\n\
+ add sp, 0x18\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\n");
+}
+#endif
+
+static void sub_80F7EFC(void)
+{
+ struct MauvilleManBard *bard = &gSaveBlock1.mauvilleMan.bard;
+
+ bard->hasChangedSong = FALSE;
+}
+
+static void sub_80F7F0C(void)
+{
+ struct MauvilleManHipster *hipster = &gSaveBlock1.mauvilleMan.hipster;
+
+ hipster->alreadySpoken = FALSE;
+}
+
+static void sub_80F7F18(void)
+{
+ sub_8109A20();
+}
+
+static void sub_80F7F24(void)
+{
+ sub_80F8428();
+}
+
+void sub_80F7F30(void)
+{
+ switch (GetCurrentMauvilleOldMan())
+ {
+ case MAUVILLE_MAN_BARD:
+ sub_80F7EFC();
+ break;
+ case MAUVILLE_MAN_HIPSTER:
+ sub_80F7F0C();
+ break;
+ case MAUVILLE_MAN_STORYTELLER:
+ sub_80F7F24();
+ break;
+ case MAUVILLE_MAN_TRADER:
+ sub_80F7F18();
+ break;
+ case MAUVILLE_MAN_GIDDY:
+ break;
+ }
+ sub_80F83D0();
+}
+
+#define tState data[0]
+#define tCharIndex data[3]
+#define tCurrWord data[4]
+#define tUseTemporaryLyrics data[5]
+
+static void StartBardSong(bool8 useTemporaryLyrics)
+{
+ u8 taskId = CreateTask(Task_BardSong, 0x50);
+
+ gTasks[taskId].tUseTemporaryLyrics = useTemporaryLyrics;
+}
+
+static void BardSing(struct Task *task, struct BardSong *song)
+{
+ switch (task->tState)
+ {
+ case 0: // Initialize song
+ {
+ struct MauvilleManBard *bard = &gSaveBlock1.mauvilleMan.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];
+
+ // Clear phonemes
+ for (i = 0; i < 6; i++)
+ {
+ song->phonemes[i].sound = 0xFFFF;
+ song->phonemes[i].length = 0;
+ song->phonemes[i].pitch = 0;
+ song->phonemes[i].volume = 0;
+ }
+ song->currWord = 0;
+ song->currPhoneme = 0;
+ song->var04 = 0;
+ }
+ break;
+ case 1: // Wait for BGM to end
+ break;
+ case 2: // Initialize word
+ {
+ u16 word = song->lyrics[song->currWord];
+ const struct BardSound *sounds = GetWordSounds(EC_GROUP(word), EC_INDEX(word));
+
+ song->var04 = 0;
+ GetWordPhonemes(song, sounds, MACRO1(word));
+ }
+ break;
+ case 3:
+ case 4:
+ {
+ struct BardPhoneme *phoneme = &song->phonemes[song->currPhoneme];
+
+ switch (song->state)
+ {
+ case 0:
+ if (song->phonemeTimer == 0) // Timer has expired. Move to next phoneme
+ {
+ if (song->currPhoneme == 6 || phoneme->sound == 0xFF)
+ {
+ song->state = 0xFE;
+ break;
+ }
+ song->phonemeTimer = phoneme->length;
+ if (phoneme->sound <= 50)
+ {
+ u16 num = phoneme->sound / 3;
+
+ m4aSongNumStart(249 + num * 3);
+ }
+ song->state = 1;
+ }
+ else
+ {
+ if (song->voiceInflection > 10)
+ song->volume -= 2;
+ if (song->voiceInflection & 1)
+ song->pitch += 64;
+ else
+ song->pitch -= 64;
+ m4aMPlayVolumeControl(&gMPlay_SE2, 0xFFFF, song->volume);
+ m4aMPlayPitchControl(&gMPlay_SE2, 0xFFFF, song->pitch);
+ song->voiceInflection++;
+ }
+ song->phonemeTimer--;
+ break;
+ case 1:
+ song->currPhoneme++;
+ song->state = 0;
+ if (phoneme->sound <= 50)
+ {
+ song->volume = 0x100 + phoneme->volume * 16;
+ m4aMPlayVolumeControl(&gMPlay_SE2, 0xFFFF, song->volume);
+ song->pitch = 0x200 + phoneme->pitch;
+ m4aMPlayPitchControl(&gMPlay_SE2, 0xFFFF, song->pitch);
+ }
+ break;
+ case 0xFE:
+ m4aMPlayStop(&gMPlay_SE2);
+ song->state = 0xFF;
+ break;
+ }
+ }
+ break;
+ case 5:
+ break;
+ }
+}
+
+static void Task_BardSong(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId]; // r5
+
+ BardSing(task, &gUnknown_03005DA0);
+ switch (task->tState)
+ {
+ case 0: // Initialize song
+ PrepareSongText();
+ InitWindowFromConfig(gMenuWindowPtr, &gWindowConfig_81E6CE4);
+ sub_8002EB0(gMenuWindowPtr, gStringVar4, 2, 4, 15);
+ 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 = &gSaveBlock1.mauvilleMan.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)
+ gUnknown_020388BC = MACRO1(bard->songLyrics[task->tCurrWord]);
+ else
+ gUnknown_020388BC = MACRO1(bard->temporaryLyrics[task->tCurrWord]);
+ temp = gUnknown_03005DA0.var04 / wordLen;
+ zero = 0;
+ gUnknown_03005DA0.var04 = temp;
+ if (gUnknown_03005DA0.var04 <= 0)
+ gUnknown_03005DA0.var04 = 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)
+ {
+ FadeInNewBGM(BGM_POKECEN, 6);
+ m4aMPlayFadeOutTemporarily(&gMPlay_SE2, 2);
+ EnableBothScriptContexts();
+ DestroyTask(taskId);
+ }
+ else if (gStringVar4[task->tCharIndex] == CHAR_SPACE)
+ {
+ sub_8003418(gMenuWindowPtr);
+ 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_8003418(gMenuWindowPtr);
+ task->tCharIndex++;
+ task->data[2] = 0;
+ }
+ else
+ {
+ switch (task->data[1])
+ {
+ case 0:
+ sub_8003418(gMenuWindowPtr);
+ task->data[1]++;
+ break;
+ case 1:
+ task->data[1]++;
+ break;
+ case 2:
+ task->tCharIndex++;
+ task->data[1] = 0;
+ task->data[2] = gUnknown_03005DA0.var04;
+ task->tState = 4;
+ break;
+ }
+ }
+ break;
+ case 4:
+ task->data[2]--;
+ if (task->data[2] == 0)
+ task->tState = 3;
+ break;
+ }
+}
+
+void sub_80F83D0(void)
+{
+ VarSet(0x4010, 0x45 + GetCurrentMauvilleOldMan());
+}
+
+struct Story
+{
+ u8 stat;
+ u8 minVal;
+ const u8 *title;
+ const u8 *action;
+ const u8 *fullText;
+};
+
+static const struct Story sStorytellerStories[] =
+{
+ {0x32, 1, gTextStoryteller_Story1Title, gTextStoryteller_Story1Action, gTextStoryteller_Story1Text},
+ {0x02, 1, gTextStoryteller_Story2Title, gTextStoryteller_Story2Action, gTextStoryteller_Story2Text},
+ {0x03, 1, gTextStoryteller_Story3Title, gTextStoryteller_Story3Action, gTextStoryteller_Story3Text},
+ {0x04, 1, gTextStoryteller_Story4Title, gTextStoryteller_Story4Action, gTextStoryteller_Story4Text},
+ {0x06, 1, gTextStoryteller_Story5Title, gTextStoryteller_Story5Action, gTextStoryteller_Story5Text},
+ {0x09, 1, gTextStoryteller_Story6Title, gTextStoryteller_Story6Action, gTextStoryteller_Story6Text},
+ {0x0B, 1, gTextStoryteller_Story7Title, gTextStoryteller_Story7Action, gTextStoryteller_Story7Text},
+ {0x0C, 1, gTextStoryteller_Story8Title, gTextStoryteller_Story8Action, gTextStoryteller_Story8Text},
+ {0x0D, 1, gTextStoryteller_Story9Title, gTextStoryteller_Story9Action, gTextStoryteller_Story9Text},
+ {0x0E, 1, gTextStoryteller_Story10Title, gTextStoryteller_Story10Action, gTextStoryteller_Story10Text},
+ {0x0F, 1, gTextStoryteller_Story11Title, gTextStoryteller_Story11Action, gTextStoryteller_Story11Text},
+ {0x10, 1, gTextStoryteller_Story12Title, gTextStoryteller_Story12Action, gTextStoryteller_Story12Text},
+ {0x11, 1, gTextStoryteller_Story13Title, gTextStoryteller_Story13Action, gTextStoryteller_Story13Text},
+ {0x12, 1, gTextStoryteller_Story14Title, gTextStoryteller_Story14Action, gTextStoryteller_Story14Text},
+ {0x13, 1, gTextStoryteller_Story15Title, gTextStoryteller_Story15Action, gTextStoryteller_Story15Text},
+ {0x14, 1, gTextStoryteller_Story16Title, gTextStoryteller_Story16Action, gTextStoryteller_Story16Text},
+ {0x1A, 1, gTextStoryteller_Story17Title, gTextStoryteller_Story17Action, gTextStoryteller_Story17Text},
+ {0x1B, 1, gTextStoryteller_Story18Title, gTextStoryteller_Story18Action, gTextStoryteller_Story18Text},
+ {0x1C, 1, gTextStoryteller_Story19Title, gTextStoryteller_Story19Action, gTextStoryteller_Story19Text},
+ {0x1D, 2, gTextStoryteller_Story20Title, gTextStoryteller_Story20Action, gTextStoryteller_Story20Text},
+ {0x1E, 1, gTextStoryteller_Story21Title, gTextStoryteller_Story21Action, gTextStoryteller_Story21Text},
+ {0x21, 1, gTextStoryteller_Story22Title, gTextStoryteller_Story22Action, gTextStoryteller_Story22Text},
+ {0x24, 1, gTextStoryteller_Story23Title, gTextStoryteller_Story23Action, gTextStoryteller_Story23Text},
+ {0x25, 1, gTextStoryteller_Story24Title, gTextStoryteller_Story24Action, gTextStoryteller_Story24Text},
+ {0x26, 1, gTextStoryteller_Story25Title, gTextStoryteller_Story25Action, gTextStoryteller_Story25Text},
+ {0x27, 1, gTextStoryteller_Story26Title, gTextStoryteller_Story26Action, gTextStoryteller_Story26Text},
+ {0x28, 1, gTextStoryteller_Story27Title, gTextStoryteller_Story27Action, gTextStoryteller_Story27Text},
+ {0x29, 1, gTextStoryteller_Story28Title, gTextStoryteller_Story28Action, gTextStoryteller_Story28Text},
+ {0x2A, 1, gTextStoryteller_Story29Title, gTextStoryteller_Story29Action, gTextStoryteller_Story29Text},
+ {0x2B, 1, gTextStoryteller_Story30Title, gTextStoryteller_Story30Action, gTextStoryteller_Story30Text},
+ {0x2C, 1, gTextStoryteller_Story31Title, gTextStoryteller_Story31Action, gTextStoryteller_Story31Text},
+ {0x2D, 1, gTextStoryteller_Story32Title, gTextStoryteller_Story32Action, gTextStoryteller_Story32Text},
+ {0x2E, 1, gTextStoryteller_Story33Title, gTextStoryteller_Story33Action, gTextStoryteller_Story33Text},
+ {0x2F, 1, gTextStoryteller_Story34Title, gTextStoryteller_Story34Action, gTextStoryteller_Story34Text},
+ {0x30, 1, gTextStoryteller_Story35Title, gTextStoryteller_Story35Action, gTextStoryteller_Story35Text},
+ {0x31, 1, gTextStoryteller_Story36Title, gTextStoryteller_Story36Action, gTextStoryteller_Story36Text},
+};
+
+static void StorytellerSetup(void)
+{
+ struct MauvilleManStoryteller *storyteller = &gSaveBlock1.mauvilleMan.storyteller;
+ s32 i;
+
+ storyteller->id = MAUVILLE_MAN_STORYTELLER;
+ storyteller->alreadyRecorded = FALSE;
+ for (i = 0; i < 4; i++)
+ {
+ storyteller->gameStatIDs[i] = 0;
+ storyteller->trainerNames[0][i] = EOS; // Maybe they meant storyteller->trainerNames[i][0] instead?
+ }
+}
+
+static void sub_80F8428(void)
+{
+ struct MauvilleManStoryteller *storyteller = &gSaveBlock1.mauvilleMan.storyteller;
+
+ storyteller->id = MAUVILLE_MAN_STORYTELLER;
+ storyteller->alreadyRecorded = FALSE;
+}
+
+static u32 StorytellerGetGameStat(u8 stat)
+{
+ if (stat == NUM_GAME_STATS)
+ 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++)
+ {
+ struct MauvilleManStoryteller *storyteller = &gSaveBlock1.mauvilleMan.storyteller;
+
+ if (storyteller->gameStatIDs[i] == 0)
+ break;
+ }
+ return i;
+}
+
+static u32 StorytellerGetRecordedTrainerStat(u32 trainer)
+{
+ u8 *ptr = gSaveBlock1.mauvilleMan.storyteller.statValues[trainer];
+
+ return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24);
+}
+
+static void StorytellerSetRecordedTrainerStat(u32 trainer, u32 val)
+{
+ u8 *ptr = gSaveBlock1.mauvilleMan.storyteller.statValues[trainer];
+
+ ptr[0] = val;
+ ptr[1] = val >> 8;
+ ptr[2] = val >> 16;
+ ptr[3] = val >> 24;
+}
+
+static bool32 HasTrainerStatIncreased(u32 trainer)
+{
+ struct MauvilleManStoryteller *storyteller = &gSaveBlock1.mauvilleMan.storyteller;
+
+ if (StorytellerGetGameStat(storyteller->gameStatIDs[trainer]) > StorytellerGetRecordedTrainerStat(trainer))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static void GetStoryByStattellerPlayerName(u32 player, void *dst)
+{
+ u8 *name = gSaveBlock1.mauvilleMan.storyteller.trainerNames[player];
+
+ memset(dst, EOS, 8);
+ memcpy(dst, name, 7);
+}
+
+static void StorytellerSetPlayerName(u32 player, const u8 *src)
+{
+ u8 *name = gSaveBlock1.mauvilleMan.storyteller.trainerNames[player];
+ u8 len = StringLength(src);
+
+ memset(name, EOS, 7);
+ StringCopyN(name, src, len);
+}
+
+static void StorytellerRecordNewStat(u32 player, u32 stat)
+{
+ struct MauvilleManStoryteller *storyteller = &gSaveBlock1.mauvilleMan.storyteller;
+
+ storyteller->gameStatIDs[player] = stat;
+ StorytellerSetPlayerName(player, gSaveBlock2.playerName);
+ StorytellerSetRecordedTrainerStat(player, StorytellerGetGameStat(stat));
+ ConvertIntToDecimalStringN(gStringVar1, StorytellerGetGameStat(stat), 0, 10);
+ StringCopy(gStringVar2, GetStoryActionByStat(stat));
+}
+
+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;
+ }
+}
+
+// What purpose does this struct even serve? Only the length field is used.
+static const struct {u32 length; struct MauvilleManStoryteller *unused1; u32 unused2;} sStorytellerStuff =
+{
+ 36,
+ &gSaveBlock1.mauvilleMan.storyteller, // unused
+ 12, // unused
+};
+
+static bool8 StorytellerInitializeRandomStat(void)
+{
+ u8 arr[sStorytellerStuff.length];
+ s32 i;
+ s32 j;
+
+ ScrambleStatList(arr, 36);
+ for (i = 0; i < 36; i++)
+ {
+ u8 stat = sStorytellerStories[arr[i]].stat;
+ u8 minVal = sStorytellerStories[arr[i]].minVal;
+ struct MauvilleManStoryteller *storyteller = &gSaveBlock1.mauvilleMan.storyteller;
+
+ for (j = 0; j < 4; j++)
+ {
+ if (gSaveBlock1.mauvilleMan.storyteller.gameStatIDs[j] == stat)
+ break;
+ }
+ if (j == 4 && StorytellerGetGameStat(stat) >= minVal)
+ {
+ storyteller->alreadyRecorded = TRUE;
+ StorytellerRecordNewStat(GetFreeStorySlot(), stat);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static void StorytellerDisplayStory(u32 player)
+{
+ struct MauvilleManStoryteller *storyteller = &gSaveBlock1.mauvilleMan.storyteller;
+ u8 stat = storyteller->gameStatIDs[player];
+
+ ConvertIntToDecimalStringN(gStringVar1, StorytellerGetRecordedTrainerStat(player), 0, 10);
+ StringCopy(gStringVar2, GetStoryActionByStat(stat));
+ GetStoryByStattellerPlayerName(player, gStringVar3);
+ ShowFieldMessage(GetStoryTextByStat(stat));
+}
+
+static void PrintStoryList(void)
+{
+ s32 i;
+
+ MenuDrawTextWindow(0, 0, 25, 4 + GetFreeStorySlot() * 2);
+ for (i = 0; i < 4; i++)
+ {
+ struct MauvilleManStoryteller *storyteller = &gSaveBlock1.mauvilleMan.storyteller;
+ u8 stat = storyteller->gameStatIDs[i];
+
+ if (stat == 0)
+ break;
+ MenuPrint(GetStoryTitleByStat(stat), 1, 2 + i * 2);
+ }
+ MenuPrint(gPCText_Cancel, 1, 2 + i * 2);
+}
+
+static u8 gUnknown_03000748;
+
+static void Task_StoryListMenu(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ s32 selection;
+
+ switch (task->data[0])
+ {
+ case 0:
+ PrintStoryList();
+ InitMenu(0, 1, 2, GetFreeStorySlot() + 1, 0, 24);
+ task->data[0]++;
+ break;
+ case 1:
+ selection = ProcessMenuInput();
+ if (selection == -2)
+ break;
+ if (selection == -1 || selection == GetFreeStorySlot())
+ {
+ gScriptResult = 0;
+ }
+ else
+ {
+ gScriptResult = 1;
+ gUnknown_03000748 = selection;
+ }
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(0, 0, 25, 12);
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+ break;
+ }
+}
+
+// Sets gScriptResult to TRUE if player selected a story
+void ScrSpecial_StorytellerStoryListMenu(void)
+{
+ CreateTask(Task_StoryListMenu, 0x50);
+}
+
+void ScrSpecial_StorytellerDisplayStory(void)
+{
+ StorytellerDisplayStory(gUnknown_03000748);
+}
+
+u8 ScrSpecial_StorytellerGetFreeStorySlot(void)
+{
+ return GetFreeStorySlot();
+}
+
+// Returns TRUE if stat has increased
+bool8 ScrSpecial_StorytellerUpdateStat(void)
+{
+ struct MauvilleManStoryteller *storyteller = &gSaveBlock1.mauvilleMan.storyteller;
+ u8 r4 = storyteller->gameStatIDs[gUnknown_03000748];
+
+ if (HasTrainerStatIncreased(gUnknown_03000748) == TRUE)
+ {
+ StorytellerRecordNewStat(gUnknown_03000748, r4);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 ScrSpecial_HasStorytellerAlreadyRecorded(void)
+{
+ struct MauvilleManStoryteller *storyteller = &gSaveBlock1.mauvilleMan.storyteller;
+
+ if (storyteller->alreadyRecorded == FALSE)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+bool8 ScrSpecial_StorytellerInitializeRandomStat(void)
+{
+ return StorytellerInitializeRandomStat();
+}
diff --git a/src/field/menu_helpers.c b/src/field/menu_helpers.c
new file mode 100644
index 000000000..14e823355
--- /dev/null
+++ b/src/field/menu_helpers.c
@@ -0,0 +1,572 @@
+#include "global.h"
+#include "item_menu.h"
+#include "items.h"
+#include "link.h"
+#include "mail_data.h"
+#include "main.h"
+#include "map_constants.h"
+#include "menu.h"
+#include "menu_helpers.h"
+#include "overworld.h"
+#include "songs.h"
+#include "sound.h"
+#include "sprite.h"
+#include "task.h"
+#include "text.h"
+
+#define SCROLL_INDICATOR_PAL_TAG 6
+
+static void sub_80F9834(struct Sprite *sprite);
+
+static EWRAM_DATA u8 gUnknown_020388C0[4] = {0};
+static EWRAM_DATA struct YesNoFuncTable gUnknown_020388C4 = {0};
+
+static TaskFunc gUnknown_0300074C;
+
+static const u8 gSpriteImage_83E5808[] = INCBIN_U8("graphics/unknown_sprites/83E59A0/0.4bpp");
+
+static const u8 gSpriteImage_83E5848[] = INCBIN_U8("graphics/unknown_sprites/83E59A0/1.4bpp");
+
+static const u8 gSpriteImage_83E5888[] = INCBIN_U8("graphics/unknown_sprites/83E59B0/0.4bpp");
+
+static const u8 gSpriteImage_83E58C8[] = INCBIN_U8("graphics/unknown_sprites/83E59B0/1.4bpp");
+
+static const u8 gSpriteImage_83E5908[] = INCBIN_U8("graphics/unknown_sprites/83E59C0/0.4bpp");
+
+static const u8 gSpriteImage_83E5928[] = INCBIN_U8("graphics/unknown_sprites/83E59C0/1.4bpp");
+
+static const u16 Palette_3E5948[] = INCBIN_U16("graphics/interface/83E5948.gbapal");
+
+static const struct SpritePalette gUnknown_083E5968 = { Palette_3E5948, SCROLL_INDICATOR_PAL_TAG };
+
+static const struct OamData gOamData_83E5970 =
+{
+ .tileNum = 1
+};
+
+static const struct OamData gOamData_83E5978 =
+{
+ .shape = ST_OAM_H_RECTANGLE,
+ .tileNum = 1
+};
+
+static const struct OamData gOamData_83E5980 =
+{
+ .shape = ST_OAM_V_RECTANGLE,
+ .tileNum = 1
+};
+
+static const union AnimCmd gSpriteAnim_83E5988[] =
+{
+ ANIMCMD_FRAME(0, 0),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gSpriteAnim_83E5990[] =
+{
+ ANIMCMD_FRAME(1, 0),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gSpriteAnimTable_83E5998[] =
+{
+ gSpriteAnim_83E5988,
+ gSpriteAnim_83E5990,
+};
+
+static const struct SpriteFrameImage gSpriteImageTable_83E59A0[] =
+{
+ { gSpriteImage_83E5808, 0x40 },
+ { gSpriteImage_83E5848, 0x40 },
+};
+
+static const struct SpriteFrameImage gSpriteImageTable_83E59B0[] =
+{
+ { gSpriteImage_83E5888, 0x40 },
+ { gSpriteImage_83E58C8, 0x40 },
+};
+
+static const struct SpriteFrameImage gSpriteImageTable_83E59C0[] =
+{
+ { gSpriteImage_83E5908, 0x20 },
+ { gSpriteImage_83E5928, 0x20 },
+};
+
+static const struct SpriteTemplate gSpriteTemplate_83E59D0 =
+{
+ .tileTag = 0xFFFF,
+ .paletteTag = SCROLL_INDICATOR_PAL_TAG,
+ .oam = &gOamData_83E5978,
+ .anims = gSpriteAnimTable_83E5998,
+ .images = gSpriteImageTable_83E59A0,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80F9834,
+};
+
+static const struct SpriteTemplate gSpriteTemplate_83E59E8 =
+{
+ .tileTag = 0xFFFF,
+ .paletteTag = SCROLL_INDICATOR_PAL_TAG,
+ .oam = &gOamData_83E5980,
+ .anims = gSpriteAnimTable_83E5998,
+ .images = gSpriteImageTable_83E59B0,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80F9834,
+};
+
+static const struct SpriteTemplate gSpriteTemplate_83E5A00 =
+{
+ .tileTag = 0xFFFF,
+ .paletteTag = SCROLL_INDICATOR_PAL_TAG,
+ .oam = &gOamData_83E5970,
+ .anims = gSpriteAnimTable_83E5998,
+ .images = gSpriteImageTable_83E59C0,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+void sub_80F9020(void)
+{
+ memset(&gBGTilemapBuffers[1], 0, 0x800);
+ memset(&gBGTilemapBuffers[2], 0, 0x800);
+ memset(&gBGTilemapBuffers[3], 0, 0x800);
+}
+
+// display message box, fill box with tile if tile is not zero, print string
+static void PrintMessage(const u8 *str, u16 tile)
+{
+ MenuDisplayMessageBox();
+ if (tile)
+ {
+ sub_80A3FA0(&gBGTilemapBuffers[1][0], 2, 15, 26, 4, tile);
+ }
+ MenuPrintMessageDefaultCoords(str);
+}
+
+static void sub_80F9090(u8 taskId)
+{
+ if (MenuUpdateWindowText() == TRUE)
+ {
+ gUnknown_0300074C(taskId);
+ }
+}
+
+void DisplayItemMessageOnField(u8 taskId, const u8 *str, TaskFunc callback, u16 tile)
+{
+ PrintMessage(str, tile);
+ gUnknown_0300074C = callback;
+ gTasks[taskId].func = sub_80F9090;
+}
+
+static void Task_CallYesOrNoCallback(u8 taskId)
+{
+ switch (ProcessMenuInputNoWrap_())
+ {
+ case 0:
+ PlaySE(SE_SELECT);
+ gUnknown_020388C4.yesFunc(taskId);
+ break;
+ case 1:
+ case -1:
+ PlaySE(SE_SELECT);
+ gUnknown_020388C4.noFunc(taskId);
+ }
+}
+
+void DoYesNoFuncWithChoice(u8 taskId, const struct YesNoFuncTable *funcTable)
+{
+ gUnknown_020388C4 = *funcTable;
+ gTasks[taskId].func = Task_CallYesOrNoCallback;
+}
+
+static void PrintStringWithPalette(const u8 *str, u8 paletteNum, u8 left, u8 top)
+{
+ u8 paletteStr[] = _("{PALETTE 0}");
+
+ if (paletteNum != 0xFF)
+ {
+ paletteStr[2] = paletteNum;
+ StringCopy(gStringVar4, paletteStr);
+ StringAppend(gStringVar4, str);
+ paletteStr[2] = gMenuWindowPtr->paletteNum;
+ StringAppend(gStringVar4, paletteStr);
+ }
+ else
+ {
+ StringCopy(gStringVar4, str);
+ }
+
+ MenuPrint(gStringVar4, left, top);
+}
+
+// unused
+void PrintNumberWithPalette(s32 value, u8 paletteNum, u8 n, u8 mode, u8 left, u8 top)
+{
+ ConvertIntToDecimalStringN(gStringVar1, value, mode, n);
+ if (paletteNum != 0xFF)
+ {
+ PrintStringWithPalette(gStringVar1, paletteNum, left, top);
+ }
+ else
+ {
+ MenuPrint(gStringVar1, left, top);
+ }
+}
+
+// unused
+void PrintTriangleCursorWithPalette(u8 left, u8 top, u8 paletteNum)
+{
+ u8 cursorStr[] = _("▶");
+ PrintStringWithPalette(cursorStr, paletteNum, left, top);
+}
+
+u8 sub_80F9284(void)
+{
+ if (gSaveBlock2.optionsButtonMode == OPTIONS_BUTTON_MODE_LR)
+ {
+ if (gMain.newKeys & L_BUTTON)
+ {
+ return 1;
+ }
+ if (gMain.newKeys & R_BUTTON)
+ {
+ return 2;
+ }
+ }
+
+ return 0;
+}
+
+u8 sub_80F92BC(void)
+{
+ if (gSaveBlock2.optionsButtonMode == OPTIONS_BUTTON_MODE_LR)
+ {
+ if (gMain.newAndRepeatedKeys & L_BUTTON)
+ {
+ return 1;
+ }
+ if (gMain.newAndRepeatedKeys & R_BUTTON)
+ {
+ return 2;
+ }
+ }
+
+ return 0;
+}
+
+bool8 sub_80F92F4(u16 itemId)
+{
+ if (itemId != ITEM_ENIGMA_BERRY)
+ {
+ return TRUE;
+ }
+
+ if (!(gSaveBlock1.location.mapGroup == MAP_GROUP_TRADE_CENTER && gSaveBlock1.location.mapNum == MAP_ID_TRADE_CENTER))
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+bool8 sub_80F931C(u16 itemId)
+{
+ if (is_c1_link_related_active() != TRUE)
+ {
+ return TRUE;
+ }
+
+ if (ItemIsMail(itemId) != TRUE)
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+bool8 sub_80F9344(void)
+{
+ if (is_c1_link_related_active() == TRUE || gReceivedRemoteLinkPlayers == 1)
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void sub_80F9368(void)
+{
+ u8 *addr;
+ u32 size;
+
+ REG_DISPCNT = 0;
+ REG_BG3CNT = 0;
+ REG_BG2CNT = 0;
+ REG_BG1CNT = 0;
+ REG_BG0CNT = 0;
+ REG_BG3HOFS = 0;
+ REG_BG3VOFS = 0;
+ REG_BG2HOFS = 0;
+ REG_BG2VOFS = 0;
+ REG_BG1HOFS = 0;
+ REG_BG1VOFS = 0;
+ REG_BG0HOFS = 0;
+ REG_BG0VOFS = 0;
+
+ 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;
+ }
+ }
+
+ DmaClear32(3, OAM, OAM_SIZE);
+ DmaClear16(3, PLTT, PLTT_SIZE);
+}
+
+void sub_80F9438(void)
+{
+ SetVBlankCallback(NULL);
+ SetHBlankCallback(NULL);
+}
+
+void sub_80F944C(void)
+{
+ u8 i;
+
+ for (i = 0; i < 4; i++)
+ {
+ gUnknown_020388C0[i] = 0xFF;
+ }
+
+ FreeSpritePaletteByTag(SCROLL_INDICATOR_PAL_TAG);
+ LoadSpritePalette(&gUnknown_083E5968);
+}
+
+void sub_80F9480(u8 *data, u8 n)
+{
+ u8 i;
+
+ for (i = 0; i < n; i++)
+ {
+ data[i] = 0xFF;
+ }
+}
+
+void sub_80F94A4(u8 animNum, u8 *spriteId, s16 x, s16 y)
+{
+ if (animNum <= 5)
+ {
+ if (*spriteId == 0xFF)
+ {
+ *spriteId = CreateSprite(&gSpriteTemplate_83E5A00, x, y, 0);
+ }
+ animNum -= 4;
+ StartSpriteAnim(&gSprites[*spriteId], animNum);
+ }
+}
+
+void sub_80F94F8(u8 *spriteId)
+{
+ if (*spriteId != 0xFF)
+ {
+ DestroySprite(&gSprites[*spriteId]);
+ *spriteId = 0xFF;
+ }
+}
+
+void sub_80F9520(u8 *data, u8 n)
+{
+ u8 i;
+
+ for (i = 0; i < 8; i++)
+ {
+ sub_80F94F8(&data[i]);
+ }
+}
+
+void CreateVerticalScrollIndicators(u8 id, u16 x, u16 y)
+{
+ if (id >= 4)
+ {
+ return;
+ }
+
+ switch (id)
+ {
+ case 0:
+ if (gUnknown_020388C0[0] == 0xFF)
+ {
+ gUnknown_020388C0[0] = CreateSprite(&gSpriteTemplate_83E59D0, x, y, 0);
+ gSprites[gUnknown_020388C0[0]].data2 = -1;
+ if (gUnknown_020388C0[1] != 0xFF)
+ {
+ gSprites[gUnknown_020388C0[0]].pos2.y = gSprites[gUnknown_020388C0[1]].pos2.y * -1;
+ gSprites[gUnknown_020388C0[0]].data3 = gSprites[gUnknown_020388C0[1]].data3;
+ }
+ else
+ {
+ gSprites[gUnknown_020388C0[0]].data3 = 0;
+ }
+ }
+ break;
+
+ case 1:
+ if (gUnknown_020388C0[1] == 0xFF)
+ {
+ gUnknown_020388C0[1] = CreateSprite(&gSpriteTemplate_83E59D0, x, y, 0);
+ gSprites[gUnknown_020388C0[1]].data2 = 1;
+ if (gUnknown_020388C0[0] != 0xFF)
+ {
+ gSprites[gUnknown_020388C0[1]].pos2.y = gSprites[gUnknown_020388C0[0]].pos2.y * -1;
+ gSprites[gUnknown_020388C0[1]].data3 = gSprites[gUnknown_020388C0[0]].data3;
+ }
+ else
+ {
+ gSprites[gUnknown_020388C0[1]].data3 = 0;
+ }
+ }
+ break;
+
+ case 2:
+ if (gUnknown_020388C0[2] == 0xFF)
+ {
+ gUnknown_020388C0[2] = CreateSprite(&gSpriteTemplate_83E59E8, x, y, 0);
+ gSprites[gUnknown_020388C0[2]].data0 = -1;
+ if (gUnknown_020388C0[3] != 0xFF)
+ {
+ gSprites[gUnknown_020388C0[2]].pos2.x = gSprites[gUnknown_020388C0[3]].pos2.x * -1;
+ gSprites[gUnknown_020388C0[2]].data1 = gSprites[gUnknown_020388C0[3]].data1;
+ }
+ else
+ {
+ gSprites[gUnknown_020388C0[2]].data1 = 0;
+ }
+ }
+ break;
+
+ case 3:
+ if (gUnknown_020388C0[3] == 0xFF)
+ {
+ gUnknown_020388C0[3] = CreateSprite(&gSpriteTemplate_83E59E8, x, y, 0);
+ gSprites[gUnknown_020388C0[3]].data0 = 1;
+ if (gUnknown_020388C0[2] != 0xFF)
+ {
+ gSprites[gUnknown_020388C0[3]].pos2.x = gSprites[gUnknown_020388C0[2]].pos2.x * -1;
+ gSprites[gUnknown_020388C0[3]].data1 = gSprites[gUnknown_020388C0[2]].data1;
+ }
+ else
+ {
+ gSprites[gUnknown_020388C0[3]].data1 = 0;
+ }
+ }
+ break;
+ }
+
+ StartSpriteAnim(&gSprites[gUnknown_020388C0[id]], id & 1);
+}
+
+void sub_80F979C(u8 id, bool8 invisible)
+{
+ if (id < 4 && gUnknown_020388C0[id] != 0xFF)
+ {
+ gSprites[gUnknown_020388C0[id]].invisible = invisible;
+ }
+}
+
+void DestroyVerticalScrollIndicator(u8 id)
+{
+ if (id < 4 && gUnknown_020388C0[id] != 0xFF)
+ {
+ DestroySprite(&gSprites[gUnknown_020388C0[id]]);
+ gUnknown_020388C0[id] = 0xFF;
+ }
+}
+
+void LoadScrollIndicatorPalette(void)
+{
+ LoadSpritePalette(&gUnknown_083E5968);
+}
+
+void BuyMenuFreeMemory(void)
+{
+ FreeSpritePaletteByTag(SCROLL_INDICATOR_PAL_TAG);
+}
+
+static void sub_80F9834(struct Sprite *sprite)
+{
+ if (sprite->data1 == 0)
+ {
+ sprite->pos2.x += sprite->data0;
+ }
+ if (sprite->data3 == 0)
+ {
+ sprite->pos2.y += sprite->data2;
+ }
+ sprite->data1++;
+ sprite->data3++;
+ if (sprite->data1 > 2)
+ {
+ sprite->data1 = 0;
+ }
+ if (sprite->data3 > 2)
+ {
+ sprite->data3 = 0;
+ }
+ if (sprite->pos2.x == 8 || sprite->pos2.x == -8)
+ {
+ sprite->pos2.x = 0;
+ }
+ if (sprite->pos2.y == 8 || sprite->pos2.y == -8)
+ {
+ sprite->pos2.y = 0;
+ }
+}
+
+void sub_80F98A4(u8 id)
+{
+ if (gUnknown_020388C0[id] != 0xFF && id < 4)
+ {
+ gSprites[gUnknown_020388C0[id]].callback = SpriteCallbackDummy;
+ }
+}
+
+void StartVerticalScrollIndicators(u8 id)
+{
+ if (gUnknown_020388C0[id] != 0xFF && id < 4)
+ {
+ gSprites[gUnknown_020388C0[id]].callback = sub_80F9834;
+ }
+}
+
+static void sub_80F9914(u8 id)
+{
+ if (gUnknown_020388C0[id] != 0xFF && id < 4)
+ {
+ gSprites[gUnknown_020388C0[id]].pos2.x = 0;
+ gSprites[gUnknown_020388C0[id]].pos2.y = 0;
+ gSprites[gUnknown_020388C0[id]].data1 = 0;
+ gSprites[gUnknown_020388C0[id]].data3 = 0;
+ }
+}
+
+void PauseVerticalScrollIndicator(u8 id)
+{
+ sub_80F98A4(id);
+ sub_80F9914(id);
+}
+
+void sub_80F9988(u8 id, u8 priority)
+{
+ if (gUnknown_020388C0[id] != 0xFF && id < 4)
+ {
+ gSprites[gUnknown_020388C0[id]].oam.priority = priority;
+ }
+}
diff --git a/src/field/metatile_behavior.c b/src/field/metatile_behavior.c
new file mode 100644
index 000000000..d05ba0b89
--- /dev/null
+++ b/src/field/metatile_behavior.c
@@ -0,0 +1,1308 @@
+#include "global.h"
+#include "metatile_behavior.h"
+#include "metatile_behaviors.h"
+
+#define TILE_ATTRIBUTES(three, two, one) (((one) ? 1 : 0) | ((two) ? 2 : 0) | ((three) ? 4 : 0))
+
+static const u8 sTileBitAttributes[] =
+{
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, TRUE),
+ TILE_ATTRIBUTES(TRUE, FALSE, TRUE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, TRUE),
+ TILE_ATTRIBUTES(TRUE, FALSE, TRUE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, TRUE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, TRUE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, TRUE, TRUE),
+ TILE_ATTRIBUTES(TRUE, TRUE, TRUE),
+ TILE_ATTRIBUTES(TRUE, TRUE, TRUE),
+ TILE_ATTRIBUTES(TRUE, TRUE, FALSE),
+ TILE_ATTRIBUTES(TRUE, TRUE, FALSE),
+ TILE_ATTRIBUTES(TRUE, TRUE, TRUE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, TRUE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, TRUE, TRUE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, TRUE),
+ TILE_ATTRIBUTES(TRUE, FALSE, TRUE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, TRUE, TRUE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, TRUE, FALSE),
+ TILE_ATTRIBUTES(TRUE, TRUE, FALSE),
+ TILE_ATTRIBUTES(TRUE, TRUE, FALSE),
+ TILE_ATTRIBUTES(TRUE, TRUE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, TRUE, FALSE),
+ TILE_ATTRIBUTES(TRUE, TRUE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, TRUE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(TRUE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE),
+ TILE_ATTRIBUTES(FALSE, FALSE, FALSE)
+};
+
+// only used as default case for checking jump landing in field_ground_effect.
+bool8 MetatileBehavior_IsATile(u8 var)
+{
+ return TRUE;
+}
+
+bool8 MetatileBehavior_IsEncounterTile(u8 var)
+{
+ if ((sTileBitAttributes[var] & 1) != 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsJumpEast(u8 var)
+{
+ if (var == MB_JUMP_EAST)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsJumpWest(u8 var)
+{
+ if (var == MB_JUMP_WEST)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsJumpNorth(u8 var)
+{
+ if (var == MB_JUMP_NORTH)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsJumpSouth(u8 var)
+{
+ if (var == MB_JUMP_SOUTH)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsPokeGrass(u8 var)
+{
+ if (var == MB_TALL_GRASS || var == MB_LONG_GRASS)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsSandOrDeepSand(u8 var)
+{
+ if (var == MB_SAND || var == MB_DEEP_SAND)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsDeepSand(u8 var)
+{
+ if (var == MB_DEEP_SAND)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsReflective(u8 var)
+{
+ if (var == MB_POND_WATER || var == MB_PUDDLE || var == MB_1A || var == MB_ICE || var == MB_SOOTOPOLIS_DEEP_WATER || var == MB_REFLECTION_UNDER_BRIDGE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsIce(u8 var)
+{
+ if (var == MB_ICE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsWarpDoor(u8 var)
+{
+ if (var == MB_ANIMATED_DOOR)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsDoor(u8 var)
+{
+ if (var == MB_8D || var == MB_ANIMATED_DOOR)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsEscalator(u8 var)
+{
+ if (var == MB_UP_ESCALATOR || var == MB_DOWN_ESCALATOR)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 unref_sub_8056EE0(u8 var)
+{
+ if (var == MB_04)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsLadder(u8 var)
+{
+ if (var == MB_LADDER)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsNonAnimDoor(u8 var)
+{
+ if (var == MB_NON_ANIMATED_DOOR || var == MB_WATER_DOOR || var == MB_DEEP_SOUTH_WARP)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsDeepSouthWarp(u8 var)
+{
+ if (var == MB_DEEP_SOUTH_WARP)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsSurfableWaterOrUnderwater(u8 var)
+{
+ if ((sTileBitAttributes[var] & 2) != 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsEastArrowWarp(u8 var)
+{
+ if (var == MB_EAST_ARROW_WARP)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsWestArrowWarp(u8 var)
+{
+ if (var == MB_WEST_ARROW_WARP)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsNorthArrowWarp(u8 var)
+{
+ if (var == MB_NORTH_ARROW_WARP || var == MB_STAIRS_OUTSIDE_ABANDONED_SHIP)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsSouthArrowWarp(u8 var)
+{
+ if (var == MB_SOUTH_ARROW_WARP || var == MB_WATER_SOUTH_ARROW_WARP || var == MB_SHOAL_CAVE_ENTRANCE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// unused
+bool8 MetatileBehavior_IsArrowWarp(u8 var)
+{
+ u8 var2 = 0;
+
+ if (MetatileBehavior_IsEastArrowWarp(var)
+ || MetatileBehavior_IsWestArrowWarp(var)
+ || MetatileBehavior_IsNorthArrowWarp(var)
+ || MetatileBehavior_IsSouthArrowWarp(var))
+ {
+ var2 = 1;
+ }
+ return var2;
+}
+
+bool8 MetatileBehavior_IsMoveTile(u8 var)
+{
+ if ((var >= MB_WALK_EAST && var <= MB_TRICK_HOUSE_PUZZLE_8_FLOOR) || (var >= MB_EASTWARD_CURRENT && var <= MB_SOUTHWARD_CURRENT)
+ || var == MB_MUDDY_SLOPE || var == MB_CRACKED_FLOOR || var == MB_WATERFALL || var == MB_ICE || var == MB_BB || var == MB_BC)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsIce_2(u8 var)
+{
+ if (var == MB_ICE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsTrickHouseSlipperyFloor(u8 var)
+{
+ if (var == MB_TRICK_HOUSE_PUZZLE_8_FLOOR)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_0x05(u8 var)
+{
+ if (var == MB_05)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsWalkNorth(u8 var)
+{
+ if (var == MB_WALK_NORTH)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsWalkSouth(u8 var)
+{
+ if (var == MB_WALK_SOUTH)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsWalkWest(u8 var)
+{
+ if (var == MB_WALK_WEST)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsWalkEast(u8 var)
+{
+ if (var == MB_WALK_EAST)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsNorthwardCurrent(u8 var)
+{
+ if (var == MB_NORTHWARD_CURRENT)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsSouthwardCurrent(u8 var)
+{
+ if (var == MB_SOUTHWARD_CURRENT)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsWestwardCurrent(u8 var)
+{
+ if (var == MB_WESTWARD_CURRENT)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsEastwardCurrent(u8 var)
+{
+ if (var == MB_EASTWARD_CURRENT)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsSlideNorth(u8 var)
+{
+ if (var == MB_SLIDE_NORTH)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsSlideSouth(u8 var)
+{
+ if (var == MB_SLIDE_SOUTH)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsSlideWest(u8 var)
+{
+ if (var == MB_SLIDE_WEST)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsSlideEast(u8 var)
+{
+ if (var == MB_SLIDE_EAST)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsCounter(u8 var)
+{
+ if (var == MB_COUNTER)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsPlayerFacingTVScreen(u8 tile, u8 playerDir)
+{
+ if (playerDir != CONNECTION_NORTH) // if the player isn't facing north, forget about it.
+ return FALSE;
+ else if (tile == MB_TELEVISION) // is the player's north tile a TV?
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsPC(u8 var)
+{
+ if (var == MB_PC)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 is_tile_x84(u8 var)
+{
+ if (var == MB_84)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_80571C0(u8 var)
+{
+ if (var == MB_91 || var == MB_93 || var == MB_95 || var == MB_97
+ || var == MB_99 || var == MB_9B || var == MB_9D)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsSecretBaseCave(u8 var)
+{
+ if (var == MB_SECRET_BASE_SPOT_RED_CAVE || var == MB_SECRET_BASE_SPOT_BROWN_CAVE || var == MB_SECRET_BASE_SPOT_YELLOW_CAVE || var == MB_SECRET_BASE_SPOT_BLUE_CAVE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsSecretBaseTree(u8 var)
+{
+ if (var == MB_SECRET_BASE_SPOT_TREE_1 || var == MB_SECRET_BASE_SPOT_TREE_2)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsSecretBaseShrub(u8 var)
+{
+ if (var == MB_SECRET_BASE_SPOT_SHRUB)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsSecretBasePC(u8 var)
+{
+ if (var == MB_SECRET_BASE_PC)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_805724C(u8 var)
+{
+ if (var == MB_B1)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 unref_sub_8057260(u8 var)
+{
+ if (var == MB_B2)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_8057274(u8 var)
+{
+ if (var == MB_B3)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_8057288(u8 var)
+{
+ if (var == MB_B9)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_805729C(u8 var)
+{
+ if (var == MB_NORMAL)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_80572B0(u8 var)
+{
+ if (var == MB_B7)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 unref_sub_80572C4(u8 var)
+{
+ if (var == MB_B2)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_80572D8(u8 var)
+{
+ if (var == MB_B5)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_80572EC(u8 var)
+{
+ if (var == MB_C3)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_8057300(u8 var)
+{
+ if (var == MB_C2)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_8057314(u8 var)
+{
+ if (var == MB_B8)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_8057328(u8 var)
+{
+ if (var == MB_BE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_805733C(u8 var)
+{
+ if (var == MB_BD)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_8057350(u8 var)
+{
+ if (var == MB_BA)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_8057364(u8 var)
+{
+ if (var == MB_BF)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_8057378(u8 var)
+{
+ if (var == MB_C4)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_805738C(u8 var)
+{
+ if (var == MB_C5)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_HasRipples(u8 var)
+{
+ if (var == MB_POND_WATER || var == MB_PUDDLE || var == MB_SOOTOPOLIS_DEEP_WATER)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsPuddle(u8 var)
+{
+ if (var == MB_PUDDLE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsTallGrass(u8 var)
+{
+ if (var == MB_TALL_GRASS)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsLongGrass(u8 var)
+{
+ if (var == MB_LONG_GRASS)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsBerryTreeSoil(u8 var)
+{
+ if (var == MB_BERRY_TREE_SOIL)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsAshGrass(u8 var)
+{
+ if (var == MB_ASHGRASS)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsUnusedFootprintMetatile(u8 var)
+{
+ if (var == MB_25)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsBridge(u8 var)
+{
+ if (var >= MB_WARP_OR_BRIDGE && var <= MB_ROUTE120_NORTH_BRIDGE_2)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+u8 sub_8057450(u8 var)
+{
+ u8 result = var - MB_WARP_OR_BRIDGE;
+
+ if (result > 3)
+ result = 0;
+
+ return result;
+}
+
+bool8 MetatileBehavior_IsLandWildEncounter(u8 var)
+{
+ if (MetatileBehavior_IsSurfableWaterOrUnderwater(var) == FALSE && MetatileBehavior_IsEncounterTile(var) == TRUE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsWaterWildEncounter(u8 var)
+{
+ if (MetatileBehavior_IsSurfableWaterOrUnderwater(var) == TRUE && MetatileBehavior_IsEncounterTile(var) == TRUE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_80574C4(u8 var)
+{
+ if (var == MB_0B)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_80574D8(u8 var)
+{
+ if (var == MB_MOUNTAIN_TOP)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_80574EC(u8 var)
+{
+ if (var == MB_SEMI_DEEP_WATER || var == MB_DEEP_WATER || var == MB_SOOTOPOLIS_DEEP_WATER)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_805750C(u8 var)
+{
+ if (var == MB_NO_SURFACING || var == MB_SEAWEED_NO_SURFACING)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsShallowFlowingWater(u8 var)
+{
+ if (var == MB_SHALLOW_WATER || var == MB_STAIRS_OUTSIDE_ABANDONED_SHIP || var == MB_SHOAL_CAVE_ENTRANCE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsThinIce(u8 var)
+{
+ if (var == MB_THIN_ICE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsCrackedIce(u8 var)
+{
+ if (var == MB_CRACKED_ICE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_8057568(u8 var)
+{
+ if (var == MB_OCEAN_WATER || var == MB_SEMI_DEEP_WATER || var == MB_DEEP_WATER)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 unref_sub_8057584(u8 var)
+{
+ if (var == MB_18 || var == MB_1A)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_805759C(u8 var)
+{
+ if (MetatileBehavior_IsSurfableWaterOrUnderwater(var) && MetatileBehavior_IsWaterfall(var) == FALSE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsEastBlocked(u8 var)
+{
+ if (var == MB_IMPASSABLE_EAST || var == MB_IMPASSABLE_NORTHEAST || var == MB_IMPASSABLE_SOUTHEAST || var == MB_C1 || var == MB_BE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsWestBlocked(u8 var)
+{
+ if (var == MB_IMPASSABLE_WEST || var == MB_IMPASSABLE_NORTHWEST || var == MB_IMPASSABLE_SOUTHWEST || var == MB_C1 || var == MB_BE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsNorthBlocked(u8 var)
+{
+ if (var == MB_IMPASSABLE_NORTH || var == MB_IMPASSABLE_NORTHEAST || var == MB_IMPASSABLE_NORTHWEST || var == MB_BED)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsSouthBlocked(u8 var)
+{
+ if (var == MB_IMPASSABLE_SOUTH || var == MB_IMPASSABLE_SOUTHEAST || var == MB_IMPASSABLE_SOUTHWEST || var == MB_BED)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsShortGrass(u8 var)
+{
+ if (var == MB_SHORT_GRASS)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsHotSprings(u8 var)
+{
+ if (var == MB_HOT_SPRINGS)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsWaterfall(u8 var)
+{
+ if (var == MB_WATERFALL)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsFortreeBridge(u8 var)
+{
+ if (var == MB_FORTREE_BRIDGE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_80576A0(u8 var)
+{
+ if (var == MB_PACIFIDLOG_VERTICAL_LOG_1)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_80576B4(u8 var)
+{
+ if (var == MB_PACIFIDLOG_VERTICAL_LOG_2)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_80576C8(u8 var)
+{
+ if (var == MB_PACIFIDLOG_HORIZONTAL_LOG_1)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_80576DC(u8 var)
+{
+ if (var == MB_PACIFIDLOG_HORIZONTAL_LOG_2)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsPacifidlogLog(u8 var)
+{
+ if (var >= MB_PACIFIDLOG_VERTICAL_LOG_1 && var <= MB_PACIFIDLOG_HORIZONTAL_LOG_2)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsTrickHousePuzzleDoor(u8 var)
+{
+ if (var == MB_TRICK_HOUSE_PUZZLE_DOOR)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsRegionMap(u8 var)
+{
+ if (var == MB_REGION_MAP)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsClosedSootopolisGymDoor(u8 var)
+{
+ if (var == MB_CLOSED_SOOTOPOLIS_GYM_DOOR)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsRoulette(u8 var)
+{
+ if (var == MB_ROULETTE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsPokeblockFeeder(u8 var)
+{
+ if (var == MB_POKEBLOCK_FEEDER)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_0xBB(u8 var)
+{
+ if (var == MB_BB)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_0xBC(u8 var)
+{
+ if (var == MB_BC)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsLavaridgeB1FWarp(u8 var)
+{
+ if (var == MB_LAVARIDGE_GYM_B1F_WARP)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsLavaridge1FWarp(u8 var)
+{
+ if (var == MB_LAVARIDGE_GYM_1F_WARP)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsAquaHideoutWarp(u8 var)
+{
+ if (var == MB_AQUA_HIDEOUT_WARP)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsSurfableFishableWater(u8 var)
+{
+ if (var == MB_POND_WATER || var == MB_OCEAN_WATER || var == MB_SEMI_DEEP_WATER || var == MB_DEEP_WATER || var == MB_SOOTOPOLIS_DEEP_WATER || (var >= MB_EASTWARD_CURRENT && var <= MB_SOUTHWARD_CURRENT))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsMtPyreHole(u8 var)
+{
+ if (var == MB_MT_PYRE_HOLE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsCrackedFloorHole(u8 var)
+{
+ if (var == MB_CRACKED_FLOOR_HOLE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsCrackedFloor(u8 var)
+{
+ if (var == MB_CRACKED_FLOOR)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsMuddySlope(u8 var)
+{
+ if (var == MB_MUDDY_SLOPE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsBumpySlope(u8 var)
+{
+ if (var == MB_BUMPY_SLOPE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsIsolatedVerticalRail(u8 var)
+{
+ if (var == MB_ISOLATED_VERTICAL_RAIL)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsIsolatedHorizontalRail(u8 var)
+{
+ if (var == MB_ISOLATED_HORIZONTAL_RAIL)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsVerticalRail(u8 var)
+{
+ if (var == MB_VERTICAL_RAIL)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsHorizontalRail(u8 var)
+{
+ if (var == MB_HORIZONTAL_RAIL)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsSeaweed(u8 var)
+{
+ if (var == MB_SEAWEED || var == MB_SEAWEED_NO_SURFACING)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsRunningDisallowed(u8 var)
+{
+ if (var == MB_NO_RUNNING || var == MB_LONG_GRASS || var == MB_HOT_SPRINGS || MetatileBehavior_IsPacifidlogLog(var) != FALSE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsCuttableGrass(u8 var)
+{
+ if (var == MB_TALL_GRASS || var == MB_LONG_GRASS || var == MB_ASHGRASS || var == MB_LONG_GRASS_SOUTH_EDGE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 sub_805791C(u8 var)
+{
+ if (var == MB_8E)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsPictureBookShelf(u8 var)
+{
+ if (var == MB_PICTURE_BOOK_SHELF)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsBookShelf(u8 var)
+{
+ if (var == MB_BOOKSHELF)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsPokeCenterBookShelf(u8 var)
+{
+ if (var == MB_POKEMON_CENTER_BOOKSHELF)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsVase(u8 var)
+{
+ if (var == MB_VASE)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsTrashCan(u8 var)
+{
+ if (var == MB_TRASH_CAN)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsShopShelf(u8 var)
+{
+ if (var == MB_SHOP_SHELF)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 MetatileBehavior_IsBlueprint(u8 var)
+{
+ if (var == MB_BLUEPRINT)
+ return TRUE;
+ else
+ return FALSE;
+}
diff --git a/src/field/money.c b/src/field/money.c
new file mode 100644
index 000000000..5d0f0ae8d
--- /dev/null
+++ b/src/field/money.c
@@ -0,0 +1,263 @@
+#include "global.h"
+#include "money.h"
+#include "decompress.h"
+#include "menu.h"
+#include "sprite.h"
+#include "string_util.h"
+
+#define SPRITE_TAG_MONEY (0x2722)
+
+extern u16 gSpecialVar_0x8005;
+
+static EWRAM_DATA u8 gUnknown_02038734 = 0;
+
+extern const struct CompressedSpriteSheet gUnknown_083CF584;
+extern const struct CompressedSpritePalette gUnknown_083CF58C;
+extern const struct SpriteTemplate gSpriteTemplate_83CF56C;
+
+bool8 IsEnoughMoney(u32 budget, u32 cost)
+{
+ if (budget >= cost)
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void AddMoney(u32 *arg0, u32 arg1)
+{
+ if (*arg0 > *arg0 + arg1)
+ {
+ *arg0 = 999999;
+ return;
+ }
+
+ *arg0 = *arg0 + arg1;
+ if (*arg0 > 999999)
+ {
+ *arg0 = 999999;
+ }
+}
+
+void RemoveMoney(u32 *arg0, u32 arg1)
+{
+ if (*arg0 < arg1)
+ {
+ *arg0 = 0;
+ }
+ else
+ {
+ *arg0 = *arg0 - arg1;
+ }
+}
+
+void GetMoneyAmountText(u8 *buffer, u32 amount, u8 arg2)
+{
+ u8 width;
+ u8 i;
+
+ if (amount > 999999)
+ width = 7;
+ else if (amount > 99999)
+ width = 6;
+ else if (amount > 10000)
+ width = 5;
+ else if (amount > 999)
+ width = 4;
+ else if (amount > 99)
+ width = 3;
+ else if (amount > 9)
+ width = 2;
+ else
+ width = 1;
+
+ buffer[0] = EXT_CTRL_CODE_BEGIN;
+ buffer[1] = 0x14;
+ buffer[2] = 0x06;
+ buffer += 3;
+
+ for (i = 0; i < arg2 - width; i++)
+ {
+ buffer[0] = CHAR_SPACE;
+ buffer += 1;
+ }
+
+ buffer[0] = CHAR_CURRENCY;
+ buffer += 1;
+
+ buffer = ConvertIntToDecimalString(buffer, amount);
+
+ buffer[0] = EXT_CTRL_CODE_BEGIN;
+ buffer[1] = 0x14;
+ buffer[2] = 0x00;
+ buffer[3] = EOS;
+}
+
+void PrintMoneyAmount(u32 amount, u8 size, u8 x, u8 y)
+{
+ u8 buffer[16];
+ u8 stringWidth;
+
+ GetMoneyAmountText(buffer, amount, size);
+ stringWidth = sub_8072CA4(buffer);
+
+ if (stringWidth >= (size + 1) * 8)
+ {
+ MenuPrint(buffer, x, y);
+ }
+ else
+ {
+ int xPlusOne = x + 1;
+ MenuPrint_PixelCoords(buffer, (xPlusOne + size) * 8 - stringWidth, y * 8, 1);
+ }
+}
+
+void sub_80B7AEC(u32 arg0, u8 left, u8 top)
+{
+ u8 buffer[32];
+ u8 *ptr;
+
+ ptr = &buffer[0];
+
+ ptr[0] = CHAR_CURRENCY;
+ ptr++;
+
+ ptr = ConvertIntToDecimalString(ptr, arg0);
+
+ MenuPrint_RightAligned(buffer, left, top);
+
+#ifdef ENGLISH
+ ptr[0] = 0xFC;
+ ptr[1] = 0x14;
+ ptr[2] = 0x00;
+ ptr[3] = 0xFF;
+#endif
+}
+
+__attribute__((naked))
+void sub_80B7B34(u8 var1, u8 var2, int var3)
+{
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ mov r7, r9\n\
+ mov r6, r8\n\
+ push {r6,r7}\n\
+ sub sp, 0x4\n\
+ mov r8, r0\n\
+ adds r5, r1, 0\n\
+ mov r9, r2\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ mov r8, r0\n\
+ lsls r5, 24\n\
+ lsrs r5, 24\n\
+ mov r1, r9\n\
+ lsls r1, 8\n\
+ mov r9, r1\n\
+ ldr r4, _080B7BD8 @ =gDecoration10000_Gfx\n\
+ adds r0, r1, r4\n\
+ lsls r6, r5, 4\n\
+ subs r6, r5\n\
+ lsls r1, r6, 6\n\
+ mov r3, r8\n\
+ adds r3, 0x1\n\
+ lsls r3, 5\n\
+ ldr r2, _080B7BDC @ =0x06008000\n\
+ adds r3, r2\n\
+ adds r1, r3\n\
+ movs r2, 0x20\n\
+ str r3, [sp]\n\
+ bl CpuFastSet\n\
+ adds r4, 0x80\n\
+ add r9, r4\n\
+ adds r0, r5, 0x1\n\
+ lsls r4, r0, 4\n\
+ subs r4, r0\n\
+ lsls r1, r4, 6\n\
+ ldr r3, [sp]\n\
+ adds r1, r3\n\
+ mov r0, r9\n\
+ movs r2, 0x20\n\
+ bl CpuFastSet\n\
+ movs r3, 0\n\
+ lsls r5, 5\n\
+ mov r0, r8\n\
+ adds r7, r5, r0\n\
+ lsls r6, 1\n\
+ adds r6, 0x1\n\
+ add r6, r8\n\
+ ldr r1, _080B7BE0 @ =0xfffff000\n\
+ adds r5, r1, 0\n\
+ ldr r0, _080B7BE4 @ =0x0600f800\n\
+ mov r12, r0\n\
+ ldr r1, _080B7BE8 @ =0x0600f840\n\
+ mov r9, r1\n\
+ lsls r4, 1\n\
+ adds r4, 0x1\n\
+ add r4, r8\n\
+_080B7BAA:\n\
+ adds r1, r7, r3\n\
+ lsls r1, 1\n\
+ mov r0, r12\n\
+ adds r2, r1, r0\n\
+ adds r0, r3, r6\n\
+ adds r0, r5\n\
+ strh r0, [r2]\n\
+ add r1, r9\n\
+ adds r0, r3, r4\n\
+ adds r0, r5\n\
+ strh r0, [r1]\n\
+ adds r0, r3, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r3, r0, 16\n\
+ cmp r3, 0x3\n\
+ bls _080B7BAA\n\
+ add sp, 0x4\n\
+ pop {r3,r4}\n\
+ mov r8, r3\n\
+ mov r9, r4\n\
+ pop {r4-r7}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .align 2, 0\n\
+_080B7BD8: .4byte gDecoration10000_Gfx\n\
+_080B7BDC: .4byte 0x06008000\n\
+_080B7BE0: .4byte 0xfffff000\n\
+_080B7BE4: .4byte 0x0600f800\n\
+_080B7BE8: .4byte 0x0600f840\n\
+ .syntax divided\n");
+}
+
+void UpdateMoneyWindow(u32 amount, u8 x, u8 y)
+{
+ PrintMoneyAmount(amount, 6, x + 6, y + 1);
+}
+
+void OpenMoneyWindow(u32 amount, u8 x, u8 y)
+{
+ MenuDrawTextWindow(x, y, x + 13, y + 3);
+ UpdateMoneyWindow(amount, x, y);
+
+ LoadCompressedObjectPic(&gUnknown_083CF584);
+ LoadCompressedObjectPalette(&gUnknown_083CF58C);
+
+ gUnknown_02038734 = CreateSprite(&gSpriteTemplate_83CF56C, x * 8 + 19, y * 8 + 11, 0);
+}
+
+void CloseMoneyWindow(u8 x, u8 y)
+{
+ DestroySpriteAndFreeResources(&gSprites[gUnknown_02038734]);
+ FreeSpritePaletteByTag(SPRITE_TAG_MONEY);
+ MenuZeroFillWindowRect(x, y, x + 13, y + 3);
+}
+
+bool8 sub_80B7CE8(void)
+{
+ return IsEnoughMoney(gSaveBlock1.money, gSpecialVar_0x8005);
+}
+
+void sub_80B7D0C(void)
+{
+ RemoveMoney(&gSaveBlock1.money, gSpecialVar_0x8005);
+}
diff --git a/src/field/overworld.c b/src/field/overworld.c
new file mode 100644
index 000000000..d6f255409
--- /dev/null
+++ b/src/field/overworld.c
@@ -0,0 +1,2674 @@
+#include "global.h"
+#include "overworld.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 "map_constants.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 "rng.h"
+#include "roamer.h"
+#include "rotating_gate.h"
+#include "safari_zone.h"
+#include "script.h"
+#include "script_pokemon_80C4.h"
+#include "secret_base.h"
+#include "songs.h"
+#include "sound.h"
+#include "species.h"
+#include "start_menu.h"
+#include "task.h"
+#include "tileset_anim.h"
+#include "time_events.h"
+#include "tv.h"
+#include "unknown_task.h"
+#include "wild_encounter.h"
+
+#ifdef SAPPHIRE
+#define LEGENDARY_MUSIC BGM_OOAME // Heavy Rain
+#else
+#define LEGENDARY_MUSIC BGM_HIDERI // Drought
+#endif
+
+struct UnkTVStruct
+{
+ u32 tv_field_0;
+ u32 tv_field_4;
+};
+
+extern u16 gUnknown_03004898;
+extern u16 gUnknown_0300489C;
+
+extern u8 S_WhiteOut[];
+extern u8 gUnknown_0819FC9F[];
+extern u8 SingleBattleColosseum_EventScript_1A436F[];
+extern u8 SingleBattleColosseum_EventScript_1A4379[];
+extern u8 DoubleBattleColosseum_EventScript_1A4383[];
+extern u8 DoubleBattleColosseum_EventScript_1A439E[];
+extern u8 DoubleBattleColosseum_EventScript_1A43B9[];
+extern u8 DoubleBattleColosseum_EventScript_1A43D4[];
+extern u8 TradeCenter_EventScript_1A43F0[];
+extern u8 TradeCenter_EventScript_1A43FA[];
+extern u8 RecordCorner_EventScript_1A4418[];
+extern u8 RecordCorner_EventScript_1A442D[];
+extern u8 RecordCorner_EventScript_1A4442[];
+extern u8 RecordCorner_EventScript_1A4457[];
+extern u8 TradeRoom_ReadTrainerCard1[];
+extern u8 TradeRoom_ReadTrainerCard2[];
+extern u8 TradeRoom_TooBusyToNotice[];
+extern u8 TradeRoom_PromptToCancelLink[];
+extern u8 TradeRoom_TerminateLink[];
+extern u8 gUnknown_081A4508[];
+
+extern struct MapData * const gMapAttributes[];
+extern struct MapHeader * const * const gMapGroups[];
+extern s32 gMaxFlashLevel;
+
+EWRAM_DATA struct WarpData gUnknown_020297F0 = {0};
+EWRAM_DATA struct WarpData gWarpDestination = {0}; // new warp position
+EWRAM_DATA struct WarpData gUnknown_02029800 = {0};
+EWRAM_DATA struct WarpData gUnknown_02029808 = {0};
+EWRAM_DATA struct UnkPlayerStruct gUnknown_02029810 = {0};
+EWRAM_DATA static u16 sAmbientCrySpecies = 0;
+EWRAM_DATA static bool8 sIsAmbientCryWaterMon = FALSE;
+EWRAM_DATA struct LinkPlayerMapObject gLinkPlayerMapObjects[4] = {0};
+
+static u8 gUnknown_03000580[4];
+static u16 (*gUnknown_03000584)(u32);
+static u8 gUnknown_03000588;
+
+u16 word_3004858;
+void (*gFieldCallback)(void);
+u8 gUnknown_03004860;
+u8 gFieldLinkPlayerCount;
+
+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_0821664C[] =
+{
+ { 0, 0},
+ { 0, 1},
+ { 0, -1},
+ {-1, 0},
+ { 1, 0},
+ {-1, 1},
+ { 1, 1},
+ {-1, -1},
+ { 1, -1},
+};
+
+const struct UnknownTaskStruct gUnknown_08216694 =
+{
+ (void *)REG_ADDR_WIN0H,
+ ((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_DEST_RELOAD) << 16) | 1,
+ 1,
+ 0,
+};
+
+static u8 sub_8055C68(struct LinkPlayerMapObject *, struct MapObject *, u8);
+static u8 sub_8055C88(struct LinkPlayerMapObject *, struct MapObject *, u8);
+static u8 sub_8055C8C(struct LinkPlayerMapObject *, struct MapObject *, u8);
+
+static u8 (*const gUnknown_082166A0[])(struct LinkPlayerMapObject *, struct MapObject *, u8) =
+{
+ sub_8055C68,
+ sub_8055C88,
+ sub_8055C8C,
+};
+
+static u8 sub_8055CAC(struct LinkPlayerMapObject *, struct MapObject *, u8);
+static u8 sub_8055CB0(struct LinkPlayerMapObject *, struct MapObject *, u8);
+static u8 sub_8055D18(struct LinkPlayerMapObject *, struct MapObject *, u8);
+
+static u8 (*const gUnknown_082166AC[])(struct LinkPlayerMapObject *, struct MapObject *, u8) =
+{
+ sub_8055CAC,
+ sub_8055CB0,
+ sub_8055CB0,
+ sub_8055CB0,
+ sub_8055CB0,
+ sub_8055CAC,
+ sub_8055CAC,
+ sub_8055D18,
+ sub_8055D18,
+ sub_8055D18,
+ sub_8055D18,
+};
+
+static void sub_8055D30(struct LinkPlayerMapObject *, struct MapObject *);
+static void sub_8055D38(struct LinkPlayerMapObject *, struct MapObject *);
+
+static void (*const gUnknown_082166D8[])(struct LinkPlayerMapObject *, struct MapObject *) =
+{
+ sub_8055D30,
+ sub_8055D38,
+};
+
+
+static void DoWhiteOut(void)
+{
+ ScriptContext2_RunNewScript(S_WhiteOut);
+ gSaveBlock1.money /= 2;
+ ScrSpecial_HealPlayerParty();
+ Overworld_ResetStateAfterWhiteOut();
+ Overworld_SetWarpDestToLastHealLoc();
+ warp_in();
+}
+
+void Overworld_ResetStateAfterFly(void)
+{
+ player_avatar_init_params_reset();
+ FlagClear(SYS_CYCLING_ROAD);
+ FlagClear(SYS_CRUISE_MODE);
+ FlagClear(SYS_SAFARI_MODE);
+ FlagClear(SYS_USE_STRENGTH);
+ FlagClear(SYS_USE_FLASH);
+}
+
+void Overworld_ResetStateAfterTeleport(void)
+{
+ player_avatar_init_params_reset();
+ FlagClear(SYS_CYCLING_ROAD);
+ FlagClear(SYS_CRUISE_MODE);
+ FlagClear(SYS_SAFARI_MODE);
+ FlagClear(SYS_USE_STRENGTH);
+ FlagClear(SYS_USE_FLASH);
+ ScriptContext2_RunNewScript(gUnknown_0819FC9F);
+}
+
+void Overworld_ResetStateAfterDigEscRope(void)
+{
+ player_avatar_init_params_reset();
+ FlagClear(SYS_CYCLING_ROAD);
+ FlagClear(SYS_CRUISE_MODE);
+ FlagClear(SYS_SAFARI_MODE);
+ FlagClear(SYS_USE_STRENGTH);
+ FlagClear(SYS_USE_FLASH);
+}
+
+void Overworld_ResetStateAfterWhiteOut(void)
+{
+ player_avatar_init_params_reset();
+ FlagClear(SYS_CYCLING_ROAD);
+ FlagClear(SYS_CRUISE_MODE);
+ FlagClear(SYS_SAFARI_MODE);
+ FlagClear(SYS_USE_STRENGTH);
+ FlagClear(SYS_USE_FLASH);
+}
+
+void sub_805308C(void)
+{
+ FlagClear(SYS_SAFARI_MODE);
+ ChooseAmbientCrySpecies();
+ ResetCyclingRoadChallengeData();
+ UpdateLocationHistoryForRoamer();
+ RoamerMoveToOtherLocationSet();
+}
+
+void ResetGameStats(void)
+{
+ s32 i;
+
+ for (i = 0; i < NUM_GAME_STATS; i++)
+ gSaveBlock1.gameStats[i] = 0;
+}
+
+void IncrementGameStat(u8 index)
+{
+ if (index < NUM_GAME_STATS)
+ {
+ if (gSaveBlock1.gameStats[index] < 0xFFFFFF)
+ gSaveBlock1.gameStats[index]++;
+ else
+ gSaveBlock1.gameStats[index] = 0xFFFFFF;
+ }
+}
+
+u32 GetGameStat(u8 index)
+{
+ if (index >= NUM_GAME_STATS)
+ return 0;
+
+ return gSaveBlock1.gameStats[index];
+}
+
+void SetGameStat(u8 index, u32 value)
+{
+ if (index < NUM_GAME_STATS)
+ gSaveBlock1.gameStats[index] = value;
+}
+
+void LoadMapObjTemplatesFromHeader(void)
+{
+ // Clear map object templates
+ CpuFill32(0, gSaveBlock1.mapObjectTemplates, sizeof(gSaveBlock1.mapObjectTemplates));
+
+ // Copy map header events to save block
+ CpuCopy32(gMapHeader.events->mapObjects,
+ gSaveBlock1.mapObjectTemplates,
+ gMapHeader.events->mapObjectCount * sizeof(struct MapObjectTemplate));
+}
+
+static void LoadSaveblockMapObjScripts(void)
+{
+ struct MapObjectTemplate *mapObjectTemplates = gSaveBlock1.mapObjectTemplates;
+ s32 i;
+
+ for (i = 0; i < 64; i++)
+ mapObjectTemplates[i].script = gMapHeader.events->mapObjects[i].script;
+}
+
+void Overworld_SetMapObjTemplateCoords(u8 localId, s16 x, s16 y)
+{
+ s32 i;
+ for (i = 0; i < 64; i++)
+ {
+ struct MapObjectTemplate *mapObjectTemplate = &gSaveBlock1.mapObjectTemplates[i];
+ if (mapObjectTemplate->localId == localId)
+ {
+ mapObjectTemplate->x = x;
+ mapObjectTemplate->y = y;
+ return;
+ }
+ }
+}
+
+void Overworld_SetMapObjTemplateMovementType(u8 localId, u8 movementType)
+{
+ s32 i;
+
+ for (i = 0; i < 64; i++)
+ {
+ struct MapObjectTemplate *mapObjectTemplate = &gSaveBlock1.mapObjectTemplates[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();
+}
+
+static struct MapData *get_mapdata_header(void)
+{
+ u16 mapDataId = gSaveBlock1.mapDataId;
+ if (mapDataId)
+ return gMapAttributes[mapDataId - 1];
+ return NULL;
+}
+
+static void ApplyCurrentWarp(void)
+{
+ gUnknown_020297F0 = gSaveBlock1.location;
+ gSaveBlock1.location = gWarpDestination;
+ gUnknown_02029800 = sDummyWarpData;
+ gUnknown_02029808 = sDummyWarpData;
+}
+
+static 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;
+}
+
+static bool32 warp_data_is_not_neg_1(struct WarpData *warp)
+{
+ if (warp->mapGroup != -1)
+ return FALSE;
+ if (warp->mapNum != -1)
+ return FALSE;
+ if (warp->warpId != -1)
+ return FALSE;
+ if (warp->x != -1)
+ return FALSE;
+ if (warp->y != -1)
+ return FALSE;
+ return TRUE;
+}
+
+struct MapHeader *const Overworld_GetMapHeaderByGroupAndId(u16 mapGroup, u16 mapNum)
+{
+ return gMapGroups[mapGroup][mapNum];
+}
+
+struct MapHeader *const warp1_get_mapheader(void)
+{
+ return Overworld_GetMapHeaderByGroupAndId(gWarpDestination.mapGroup, gWarpDestination.mapNum);
+}
+
+static void set_current_map_header_from_sav1_save_old_name(void)
+{
+ gMapHeader = *Overworld_GetMapHeaderByGroupAndId(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum);
+ gSaveBlock1.mapDataId = gMapHeader.mapDataId;
+ gMapHeader.mapData = get_mapdata_header();
+}
+
+static void LoadSaveblockMapHeader(void)
+{
+ gMapHeader = *Overworld_GetMapHeaderByGroupAndId(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum);
+ gMapHeader.mapData = get_mapdata_header();
+}
+
+void sub_80533CC(void)
+{
+ if (gSaveBlock1.location.warpId >= 0 && gSaveBlock1.location.warpId < gMapHeader.events->warpCount)
+ {
+ gSaveBlock1.pos.x = gMapHeader.events->warps[gSaveBlock1.location.warpId].x;
+ gSaveBlock1.pos.y = gMapHeader.events->warps[gSaveBlock1.location.warpId].y;
+ }
+ else if (gSaveBlock1.location.x >= 0 && gSaveBlock1.location.y >= 0)
+ {
+ gSaveBlock1.pos.x = gSaveBlock1.location.x;
+ gSaveBlock1.pos.y = gSaveBlock1.location.y;
+ }
+ else
+ {
+ gSaveBlock1.pos.x = gMapHeader.mapData->width / 2;
+ gSaveBlock1.pos.y = gMapHeader.mapData->height / 2;
+ }
+}
+
+void warp_in(void)
+{
+ ApplyCurrentWarp();
+ set_current_map_header_from_sav1_save_old_name();
+ sub_80533CC();
+}
+
+void Overworld_SetWarpDestination(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
+{
+ SetWarpData(&gWarpDestination, 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(int unused, s8 mapGroup, s8 mapNum, s8 warpId)
+{
+ SetWarpData(&gSaveBlock1.warp2, mapGroup, mapNum, warpId, gSaveBlock1.pos.x, gSaveBlock1.pos.y);
+}
+
+void saved_warp2_set_2(int unused, s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
+{
+ SetWarpData(&gSaveBlock1.warp2, mapGroup, mapNum, warpId, x, y);
+}
+
+void copy_saved_warp2_bank_and_enter_x_to_warp1(u8 unused)
+{
+ gWarpDestination = gSaveBlock1.warp2;
+}
+
+void sub_8053538(u8 a1)
+{
+ const struct HealLocation *warp = GetHealLocation(a1);
+
+ if (warp)
+ Overworld_SetWarpDestination(warp->group, warp->map, -1, warp->x, warp->y);
+}
+
+void Overworld_SetWarpDestToLastHealLoc(void)
+{
+ gWarpDestination = gSaveBlock1.lastHealLocation;
+}
+
+void Overworld_SetHealLocationWarp(u8 healLocationId)
+{
+ const struct HealLocation *healLocation = GetHealLocation(healLocationId);
+
+ if (healLocation != NULL)
+ SetWarpData(&gSaveBlock1.lastHealLocation, healLocation->group, healLocation->map, -1, healLocation->x, healLocation->y);
+}
+
+void sub_80535C4(s16 a1, s16 a2)
+{
+ u8 currMapType = Overworld_GetMapTypeOfSaveblockLocation();
+ u8 destMapType = GetMapTypeByGroupAndId(gWarpDestination.mapGroup, gWarpDestination.mapNum);
+ if (is_map_type_1_2_3_5_or_6(currMapType) && is_map_type_1_2_3_5_or_6(destMapType) != TRUE)
+ sub_805363C(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum, -1, a1 - 7, a2 - 6);
+}
+
+void sub_805363C(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
+{
+ SetWarpData(&gSaveBlock1.warp4, mapGroup, mapNum, warpId, x, y);
+}
+
+void sub_8053678(void)
+{
+ gWarpDestination = gSaveBlock1.warp4;
+}
+
+void sub_8053690(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
+{
+ SetWarpData(&gUnknown_02029800, mapGroup, mapNum, warpId, x, y);
+}
+
+static void warp1_set_to_warp2(void)
+{
+ gWarpDestination = gUnknown_02029800;
+}
+
+void sub_80536E4(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
+{
+ SetWarpData(&gUnknown_02029808, mapGroup, mapNum, warpId, x, y);
+}
+
+void sub_8053720(s16 x, s16 y)
+{
+ if (warp_data_is_not_neg_1(&gUnknown_02029808) == TRUE)
+ {
+ gWarpDestination = gUnknown_020297F0;
+ }
+ else
+ {
+ Overworld_SetWarpDestination(gUnknown_02029808.mapGroup, gUnknown_02029808.mapNum, -1, x, y);
+ }
+}
+
+void sub_8053778(void)
+{
+ gWarpDestination = gSaveBlock1.warp1;
+}
+
+void unref_sub_8053790(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
+{
+ SetWarpData(&gSaveBlock1.warp1, mapGroup, mapNum, warpId, x, y);
+}
+
+void sub_80537CC(u8 a1)
+{
+ const struct HealLocation *warp = GetHealLocation(a1);
+ if (warp)
+ SetWarpData(&gSaveBlock1.warp1, warp->group, warp->map, -1, warp->x, warp->y);
+}
+
+void gpu_sync_bg_hide()
+{
+ gSaveBlock1.warp1 = gSaveBlock1.warp2;
+}
+
+struct MapConnection *GetMapConnection(u8 dir)
+{
+ s32 i;
+ s32 count = gMapHeader.connections->count;
+ 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_8053850(u8 dir, u16 x, u16 y)
+{
+ 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(&gUnknown_02029800))
+ return FALSE;
+ warp1_set_to_warp2();
+ }
+ return TRUE;
+}
+
+bool8 sub_80538B0(u16 x, u16 y)
+{
+ return sub_8053850(CONNECTION_EMERGE, x, y);
+}
+
+bool8 sub_80538D0(u16 x, u16 y)
+{
+ return sub_8053850(CONNECTION_DIVE, x, y);
+}
+
+void sub_80538F0(u8 mapGroup, u8 mapNum)
+{
+ s32 i;
+
+ Overworld_SetWarpDestination(mapGroup, mapNum, -1, -1, -1);
+ sub_8053F0C();
+ ApplyCurrentWarp();
+ set_current_map_header_from_sav1_save_old_name();
+ LoadMapObjTemplatesFromHeader();
+ ClearTempFieldEventData();
+ ResetCyclingRoadChallengeData();
+ prev_quest_postbuffer_cursor_backup_reset();
+ sub_8082BD0(mapGroup, mapNum);
+ DoTimeBasedEvents();
+ sub_80806E4();
+ ChooseAmbientCrySpecies();
+ SetDefaultFlashLevel();
+ Overworld_ClearSavedMusic();
+ mapheader_run_script_with_tag_x3();
+ not_trainer_hill_battle_pyramid();
+ sub_8056D38(gMapHeader.mapData);
+ apply_map_tileset2_palette(gMapHeader.mapData);
+
+ for (i = 6; i < 12; i++)
+ sub_807D874(i);
+
+ sub_8072ED0();
+ UpdateLocationHistoryForRoamer();
+ RoamerMove();
+ DoCurrentWeather();
+ ResetFieldTasksArgs();
+ mapheader_run_script_with_tag_x5();
+ ShowMapNamePopup();
+}
+
+void sub_8053994(u32 a1)
+{
+ bool8 v2;
+ bool8 v3;
+
+ set_current_map_header_from_sav1_save_old_name();
+ LoadMapObjTemplatesFromHeader();
+ v2 = is_map_type_1_2_3_5_or_6(gMapHeader.mapType);
+ v3 = Overworld_MapTypeIsIndoors(gMapHeader.mapType);
+ ClearTempFieldEventData();
+ ResetCyclingRoadChallengeData();
+ prev_quest_postbuffer_cursor_backup_reset();
+ sub_8082BD0(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum);
+ if (a1 != 1)
+ DoTimeBasedEvents();
+ sub_80806E4();
+ ChooseAmbientCrySpecies();
+ if (v2)
+ FlagClear(SYS_USE_FLASH);
+ SetDefaultFlashLevel();
+ Overworld_ClearSavedMusic();
+ mapheader_run_script_with_tag_x3();
+ UpdateLocationHistoryForRoamer();
+ RoamerMoveToOtherLocationSet();
+ not_trainer_hill_battle_pyramid();
+ if (a1 != 1 && v3)
+ {
+ UpdateTVScreensOnMap(gUnknown_03004870.width, gUnknown_03004870.height);
+ sub_80BBCCC(1);
+ }
+}
+
+void player_avatar_init_params_reset(void)
+{
+ gUnknown_02029810.player_field_1 = 1;
+ gUnknown_02029810.player_field_0 = 1;
+}
+
+void walkrun_find_lowest_active_bit_in_bitfield(void)
+{
+ gUnknown_02029810.player_field_1 = player_get_direction_lower_nybble();
+
+ if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE))
+ gUnknown_02029810.player_field_0 = 2;
+ else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_ACRO_BIKE))
+ gUnknown_02029810.player_field_0 = 4;
+ else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING))
+ gUnknown_02029810.player_field_0 = 8;
+ else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_4))
+ gUnknown_02029810.player_field_0 = 16;
+ else
+ gUnknown_02029810.player_field_0 = 1;
+}
+
+struct UnkPlayerStruct *sub_8053AA8(void)
+{
+ struct UnkPlayerStruct playerStruct;
+ u8 mapType = Overworld_GetMapTypeOfSaveblockLocation();
+ u16 v2 = cur_mapdata_block_role_at_screen_center_acc_to_sav1();
+ u8 v4 = sub_8053B00(&gUnknown_02029810, v2, mapType);
+ playerStruct.player_field_0 = v4;
+ playerStruct.player_field_1 = sub_8053B60(&gUnknown_02029810, v4, v2, mapType);
+ gUnknown_02029810 = playerStruct;
+ return &gUnknown_02029810;
+}
+
+u8 sub_8053B00(struct UnkPlayerStruct *playerStruct, u16 a2, u8 a3)
+{
+ if (a3 != 8 && FlagGet(SYS_CRUISE_MODE))
+ return 1;
+ if (a3 == 5)
+ return 16;
+ if (MetatileBehavior_IsSurfableWaterOrUnderwater(a2) == 1)
+ return 8;
+ if (Overworld_IsBikingAllowed() != TRUE)
+ return 1;
+ if (playerStruct->player_field_0 == 2)
+ return 2;
+ if (playerStruct->player_field_0 != 4)
+ return 1;
+ return 4;
+}
+
+u8 sub_8053B60(struct UnkPlayerStruct *playerStruct, u8 a2, u16 a3, u8 a4)
+{
+ if (FlagGet(SYS_CRUISE_MODE) && a4 == 6)
+ return 4;
+ if (MetatileBehavior_IsDeepSouthWarp(a3) == TRUE)
+ return 2;
+ if (MetatileBehavior_IsNonAnimDoor(a3) == TRUE || MetatileBehavior_IsDoor(a3) == TRUE)
+ return 1;
+ if (MetatileBehavior_IsSouthArrowWarp(a3) == TRUE)
+ return 2;
+ if (MetatileBehavior_IsNorthArrowWarp(a3) == TRUE)
+ return 1;
+ if (MetatileBehavior_IsWestArrowWarp(a3) == TRUE)
+ return 4;
+ if (MetatileBehavior_IsEastArrowWarp(a3) == TRUE)
+ return 3;
+ if ((playerStruct->player_field_0 == 16 && a2 == 8)
+ || (playerStruct->player_field_0 == 8 && a2 == 16))
+ return playerStruct->player_field_1;
+ if (MetatileBehavior_IsLadder(a3) == TRUE)
+ return playerStruct->player_field_1;
+ return 1;
+}
+
+u16 cur_mapdata_block_role_at_screen_center_acc_to_sav1(void)
+{
+ return MapGridGetMetatileBehaviorAt(gSaveBlock1.pos.x + 7, gSaveBlock1.pos.y + 7);
+}
+
+bool32 Overworld_IsBikingAllowed(void)
+{
+ // is player in cycling road entrance?
+ if (gSaveBlock1.location.mapGroup == MAP_GROUP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE
+ && (gSaveBlock1.location.mapNum == MAP_ID_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE
+ || gSaveBlock1.location.mapNum == MAP_ID_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE))
+ return TRUE;
+
+ // is player indoor, in a secret base, or underwater?
+ if (gMapHeader.mapType == MAP_TYPE_INDOOR)
+ return FALSE;
+ if (gMapHeader.mapType == MAP_TYPE_SECRET_BASE)
+ return FALSE;
+ if (gMapHeader.mapType == MAP_TYPE_UNDERWATER)
+ return FALSE;
+
+ // Thou shalt not bike on the sacred resting grounds of Kyogre/Groudon.
+ if (gSaveBlock1.location.mapGroup == MAP_GROUP_SEAFLOOR_CAVERN_ROOM9
+ && gSaveBlock1.location.mapNum == MAP_ID_SEAFLOOR_CAVERN_ROOM9)
+ return FALSE;
+ if (gSaveBlock1.location.mapGroup == MAP_GROUP_CAVE_OF_ORIGIN_B4F
+ && gSaveBlock1.location.mapNum == MAP_ID_CAVE_OF_ORIGIN_B4F)
+ return FALSE;
+
+ return TRUE;
+}
+
+void SetDefaultFlashLevel(void)
+{
+ if (!gMapHeader.cave)
+ gSaveBlock1.flashLevel = 0;
+ else if (FlagGet(SYS_USE_FLASH))
+ gSaveBlock1.flashLevel = 1;
+ else
+ gSaveBlock1.flashLevel = gMaxFlashLevel;
+}
+
+void Overworld_SetFlashLevel(s32 flashLevel)
+{
+ if (flashLevel < 0 || flashLevel > gMaxFlashLevel)
+ flashLevel = 0;
+ gSaveBlock1.flashLevel = flashLevel;
+}
+
+u8 Overworld_GetFlashLevel(void)
+{
+ return gSaveBlock1.flashLevel;
+}
+
+void sub_8053D14(u16 mapDataId)
+{
+ gSaveBlock1.mapDataId = mapDataId;
+ gMapHeader.mapData = get_mapdata_header();
+}
+
+static bool16 ShouldLegendaryMusicPlayAtLocation(struct WarpData *warp)
+{
+ if (!FlagGet(SYS_WEATHER_CTRL))
+ return FALSE;
+ if (warp->mapGroup == 0)
+ {
+ switch (warp->mapNum)
+ {
+ case MAP_ID_LILYCOVE_CITY:
+ case MAP_ID_MOSSDEEP_CITY:
+ case MAP_ID_SOOTOPOLIS_CITY:
+ case MAP_ID_EVER_GRANDE_CITY:
+ return TRUE;
+ case MAP_ID_ROUTE124:
+ case MAP_ID_ROUTE125:
+ case MAP_ID_ROUTE126:
+ case MAP_ID_ROUTE127:
+ case MAP_ID_ROUTE128:
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static bool16 IsInfiltratedWeatherInstitute(struct WarpData *warp)
+{
+ if (VarGet(VAR_WEATHER_INSTITUTE_CLEARED))
+ return FALSE;
+ if (warp->mapGroup != MAP_GROUP_ROUTE119_WEATHER_INSTITUTE_1F)
+ return FALSE;
+ if (warp->mapNum == MAP_ID_ROUTE119_WEATHER_INSTITUTE_1F
+ || warp->mapNum == MAP_ID_ROUTE119_WEATHER_INSTITUTE_2F)
+ return TRUE;
+ return FALSE;
+}
+
+static u16 GetLocationMusic(struct WarpData *warp)
+{
+ if (ShouldLegendaryMusicPlayAtLocation(warp) == TRUE)
+ return LEGENDARY_MUSIC;
+ else if (IsInfiltratedWeatherInstitute(warp) == TRUE)
+ return BGM_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 (gSaveBlock1.location.mapGroup == MAP_GROUP_ROUTE111
+ && gSaveBlock1.location.mapNum == MAP_ID_ROUTE111
+ && GetSav1Weather() == 8)
+ return BGM_ASHROAD;
+
+ music = GetLocationMusic(&gSaveBlock1.location);
+ if (music != 0x7FFF)
+ {
+ return music;
+ }
+ else
+ {
+ if (gSaveBlock1.pos.x < 24)
+ return BGM_DOORO_X1;
+ else
+ return BGM_GRANROAD;
+ }
+}
+
+u16 GetWarpDestinationMusic(void)
+{
+ u16 music = GetLocationMusic(&gWarpDestination);
+ if (music != 0x7FFF)
+ {
+ return music;
+ }
+ else
+ {
+ if (gSaveBlock1.location.mapGroup == MAP_GROUP_MAUVILLE_CITY
+ && gSaveBlock1.location.mapNum == MAP_ID_MAUVILLE_CITY)
+ return BGM_DOORO_X1;
+ else
+ return BGM_GRANROAD;
+ }
+}
+
+void Overworld_ResetMapMusic(void)
+{
+ ResetMapMusic();
+}
+
+void Overworld_PlaySpecialMapMusic(void)
+{
+ u16 music = GetCurrLocationDefaultMusic();
+
+ if (music != LEGENDARY_MUSIC)
+ {
+ if (gSaveBlock1.savedMusic)
+ music = gSaveBlock1.savedMusic;
+ else if (Overworld_GetMapTypeOfSaveblockLocation() == MAP_TYPE_UNDERWATER)
+ music = BGM_DEEPDEEP;
+ else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING))
+ music = BGM_NAMINORI;
+ }
+
+ if (music != GetCurrentMapMusic())
+ PlayNewMapMusic(music);
+}
+
+void Overworld_SetSavedMusic(u16 songNum)
+{
+ gSaveBlock1.savedMusic = songNum;
+}
+
+void Overworld_ClearSavedMusic(void)
+{
+ gSaveBlock1.savedMusic = 0;
+}
+
+void sub_8053F0C(void)
+{
+ if (FlagGet(SPECIAL_FLAG_1) != TRUE)
+ {
+ u16 newMusic = GetWarpDestinationMusic();
+ u16 currentMusic = GetCurrentMapMusic();
+ if (newMusic != LEGENDARY_MUSIC)
+ {
+ if (currentMusic == BGM_DEEPDEEP || currentMusic == BGM_NAMINORI)
+ return;
+ if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING))
+ newMusic = BGM_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 != LEGENDARY_MUSIC)
+ FadeOutAndPlayNewMapMusic(newMusic, 8);
+}
+
+u8 GetMapMusicFadeoutSpeed(void)
+{
+ struct MapHeader *mapHeader = warp1_get_mapheader();
+ if (Overworld_MapTypeIsIndoors(mapHeader->mapType) == TRUE)
+ return 2;
+ else
+ return 4;
+}
+
+void sub_8053FF8(void)
+{
+ u16 music = GetWarpDestinationMusic();
+ if (FlagGet(SPECIAL_FLAG_1) != TRUE && music != GetCurrentMapMusic())
+ {
+ u8 speed = GetMapMusicFadeoutSpeed();
+ FadeOutMapMusic(speed);
+ }
+}
+
+bool8 sub_8054034(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)
+{
+ 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:
+ *delayCounter = (Random() % 1200) + 1200;
+ *state = 3;
+ break;
+ case 3:
+ (*delayCounter)--;
+ if (*delayCounter == 0)
+ {
+ PlayAmbientCry();
+ *state = 2;
+ }
+ break;
+ case 4:
+ break;
+ }
+}
+
+void ChooseAmbientCrySpecies(void)
+{
+ if ((gSaveBlock1.location.mapGroup == MAP_GROUP_ROUTE130
+ && gSaveBlock1.location.mapNum == MAP_ID_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(&gSaveBlock1.location);
+}
+
+u8 get_map_type_from_warp0(void)
+{
+ return GetMapTypeByWarpData(&gUnknown_020297F0);
+}
+
+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 unref_sub_8054260(void)
+{
+ return Overworld_GetMapHeaderByGroupAndId(gSaveBlock1.warp2.mapGroup, gSaveBlock1.warp2.mapNum)->regionMapSectionId;
+}
+
+u8 sav1_map_get_name(void)
+{
+ return Overworld_GetMapHeaderByGroupAndId(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum)->regionMapSectionId;
+}
+
+u8 sav1_map_get_battletype(void)
+{
+ return Overworld_GetMapHeaderByGroupAndId(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum)->battleType;
+}
+
+void ResetSafariZoneFlag_(void)
+{
+ ResetSafariZoneFlag();
+}
+
+bool32 is_c1_link_related_active(void)
+{
+ if (gMain.callback1 == sub_8055354)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void c1_overworld_normal(u16 newKeys, u16 heldKeys)
+{
+ struct FieldInput inputStruct;
+
+ sub_8059204();
+ FieldClearPlayerInput(&inputStruct);
+ FieldGetPlayerInput(&inputStruct, newKeys, heldKeys);
+ if (!ScriptContext2_IsEnabled())
+ {
+ if (sub_8068024(&inputStruct) == 1)
+ {
+ ScriptContext2_Enable();
+ HideMapNamePopup();
+ }
+ else
+ {
+ player_step(inputStruct.dpadDirection, newKeys, heldKeys);
+ }
+ }
+}
+
+void c1_overworld(void)
+{
+ if (gMain.callback2 == c2_overworld)
+ c1_overworld_normal(gMain.newKeys, gMain.heldKeys);
+}
+
+void OverworldBasic(void)
+{
+ ScriptContext2_RunScript();
+ RunTasks();
+ AnimateSprites();
+ CameraUpdate();
+ UpdateCameraPanning();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+ sub_8072EDC();
+}
+
+// This CB2 is used when starting
+void CB2_OverworldBasic(void)
+{
+ OverworldBasic();
+}
+
+void c2_overworld(void)
+{
+ int fading = (gPaletteFade.active != 0);
+ if (fading)
+ SetVBlankCallback(NULL);
+ OverworldBasic();
+ if (fading)
+ SetFieldVBlankCallback();
+}
+
+void set_callback1(MainCallback cb)
+{
+ gMain.callback1 = cb;
+}
+
+void sub_80543DC(u16 (*a1)(u32))
+{
+ gUnknown_03000584 = a1;
+}
+
+void sub_80543E8(void)
+{
+ if (gFieldCallback != NULL)
+ gFieldCallback();
+ else
+ mapldr_default();
+ gFieldCallback = NULL;
+}
+
+void CB2_NewGame(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ StopMapMusic();
+ ResetSafariZoneFlag_();
+ NewGameInitData();
+ player_avatar_init_params_reset();
+ PlayTimeCounter_Start();
+ ScriptContext1_Init();
+ ScriptContext2_Disable();
+ gFieldCallback = ExecuteTruckSequence;
+ do_load_map_stuff_loop(&gMain.state);
+ SetFieldVBlankCallback();
+ set_callback1(c1_overworld);
+ SetMainCallback2(c2_overworld);
+}
+
+void CB2_WhiteOut(void)
+{
+ u8 val;
+ gMain.state++;
+ if (gMain.state >= 120)
+ {
+ FieldClearVBlankHBlankCallbacks();
+ StopMapMusic();
+ ResetSafariZoneFlag_();
+ DoWhiteOut();
+ player_avatar_init_params_reset();
+ ScriptContext1_Init();
+ ScriptContext2_Disable();
+ gFieldCallback = sub_8080B60;
+ val = 0;
+ do_load_map_stuff_loop(&val);
+ SetFieldVBlankCallback();
+ set_callback1(c1_overworld);
+ SetMainCallback2(c2_overworld);
+ }
+}
+
+void CB2_LoadMap(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ ScriptContext1_Init();
+ ScriptContext2_Disable();
+ set_callback1(NULL);
+ SetMainCallback2(sub_810CC80);
+ gMain.savedCallback = CB2_LoadMap2;
+}
+
+void CB2_LoadMap2(void)
+{
+ do_load_map_stuff_loop(&gMain.state);
+ SetFieldVBlankCallback();
+ set_callback1(c1_overworld);
+ SetMainCallback2(c2_overworld);
+}
+
+void sub_8054534(void)
+{
+ if (!gMain.state)
+ {
+ FieldClearVBlankHBlankCallbacks();
+ ScriptContext1_Init();
+ ScriptContext2_Disable();
+ set_callback1(NULL);
+ }
+ if (sub_805493C(&gMain.state, 1))
+ {
+ SetFieldVBlankCallback();
+ set_callback1(c1_overworld);
+ SetMainCallback2(c2_overworld);
+ }
+}
+
+void sub_8054588(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ gFieldCallback = sub_8080AC4;
+ SetMainCallback2(c2_80567AC);
+}
+
+void c2_80567AC(void)
+{
+ if (sub_805483C(&gMain.state))
+ {
+ SetFieldVBlankCallback();
+ set_callback1(sub_8055354);
+ sub_80543DC(sub_8055390);
+ SetMainCallback2(c2_overworld);
+ }
+}
+
+void c2_exit_to_overworld_2_switch(void)
+{
+ if (is_c1_link_related_active() == TRUE)
+ {
+ SetMainCallback2(c2_exit_to_overworld_2_link);
+ }
+ else
+ {
+ FieldClearVBlankHBlankCallbacks();
+ SetMainCallback2(c2_exit_to_overworld_2_local);
+ }
+}
+
+void c2_exit_to_overworld_2_local(void)
+{
+ if (sub_8054A4C(&gMain.state))
+ {
+ SetFieldVBlankCallback();
+ SetMainCallback2(c2_overworld);
+ }
+}
+
+void c2_exit_to_overworld_2_link(void)
+{
+ if (!sub_8055870() && sub_8054A9C(&gMain.state))
+ SetMainCallback2(c2_overworld);
+}
+
+void sub_805465C(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ StopMapMusic();
+ sub_8054F70();
+ set_callback1(sub_8055354);
+ sub_80543DC(sub_8055390);
+ gFieldCallback = sub_8080A3C;
+ ScriptContext1_Init();
+ ScriptContext2_Disable();
+ c2_exit_to_overworld_2_switch();
+}
+
+void sub_805469C(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ gFieldCallback = atk17_seteffectuser;
+ c2_exit_to_overworld_2_switch();
+}
+
+void sub_80546B8(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ gFieldCallback = sub_80809B0;
+ c2_exit_to_overworld_2_switch();
+}
+
+void c2_exit_to_overworld_1_continue_scripts_restart_music(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ gFieldCallback = sub_8080990;
+ c2_exit_to_overworld_2_switch();
+}
+
+void sub_80546F0(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ gFieldCallback = sub_8080B60;
+ c2_exit_to_overworld_2_switch();
+}
+
+void sub_805470C(void)
+{
+ if (gMapHeader.flags == 1 && sub_80BBB24() == 1)
+ ShowMapNamePopup();
+ sub_8080B60();
+}
+
+void CB2_ContinueSavedGame(void)
+{
+ FieldClearVBlankHBlankCallbacks();
+ StopMapMusic();
+ ResetSafariZoneFlag_();
+ LoadSaveblockMapHeader();
+ LoadSaveblockMapObjScripts();
+ UnfreezeMapObjects();
+ DoTimeBasedEvents();
+ sub_805308C();
+ sub_8055FC0();
+ PlayTimeCounter_Start();
+ ScriptContext1_Init();
+ ScriptContext2_Disable();
+ if (GetSecretBase2Field_9() == 1)
+ {
+ ClearSecretBase2Field_9();
+ sub_8053778();
+ warp_in();
+ SetMainCallback2(CB2_LoadMap);
+ }
+ else
+ {
+ gFieldCallback = sub_805470C;
+ set_callback1(c1_overworld);
+ c2_exit_to_overworld_2_switch();
+ }
+}
+
+void FieldClearVBlankHBlankCallbacks(void)
+{
+ u16 savedIme = REG_IME;
+ REG_IME = 0;
+ REG_IE &= ~INTR_FLAG_HBLANK;
+ REG_IE |= INTR_FLAG_VBLANK;
+ REG_IME = savedIme;
+ SetVBlankCallback(NULL);
+ SetHBlankCallback(NULL);
+}
+
+void SetFieldVBlankCallback(void)
+{
+ SetVBlankCallback(VBlankCB_Field);
+}
+
+void VBlankCB_Field(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ sub_8089668();
+ sub_8057A58();
+ TransferPlttBuffer();
+ sub_8072E74();
+}
+
+void sub_8054814(void)
+{
+ u8 val = Overworld_GetFlashLevel();
+ if (val)
+ {
+ sub_80815E0(val);
+ sub_80895F8(gUnknown_08216694);
+ }
+}
+
+bool32 sub_805483C(u8 *a1)
+{
+ switch (*a1)
+ {
+ case 0:
+ FieldClearVBlankHBlankCallbacks();
+ ScriptContext1_Init();
+ ScriptContext2_Disable();
+ sub_8054F70();
+ sub_8054BA8();
+ (*a1)++;
+ break;
+ case 1:
+ sub_8053994(1);
+ (*a1)++;
+ break;
+ case 2:
+ sub_8054D4C(1);
+ (*a1)++;
+ break;
+ case 3:
+ sub_8054E98();
+ sub_8054D90();
+ sub_8054EC8();
+ sub_8054E60();
+ (*a1)++;
+ break;
+ case 4:
+ sub_8054814();
+ sub_8054C54();
+ SetUpWindowConfig(&gWindowConfig_81E6C3C);
+ InitMenuWindow(&gWindowConfig_81E6CE4);
+ (*a1)++;
+ break;
+ case 5:
+ move_tilemap_camera_to_upper_left_corner();
+ (*a1)++;
+ break;
+ case 6:
+ sub_8056D28(gMapHeader.mapData);
+ (*a1)++;
+ break;
+ case 7:
+ sub_8056D38(gMapHeader.mapData);
+ (*a1)++;
+ break;
+ case 8:
+ apply_map_tileset1_tileset2_palette(gMapHeader.mapData);
+ (*a1)++;
+ break;
+ case 9:
+ DrawWholeMapView();
+ (*a1)++;
+ break;
+ case 10:
+ cur_mapheader_run_tileset_funcs_after_some_cpuset();
+ (*a1)++;
+ break;
+ case 12:
+ sub_80543E8();
+ (*a1)++;
+ break;
+ case 11:
+ (*a1)++;
+ break;
+ case 13:
+ return 1;
+ }
+ return 0;
+}
+
+bool32 sub_805493C(u8 *a1, u32 a2)
+{
+ switch (*a1)
+ {
+ case 0:
+ FieldClearVBlankHBlankCallbacks();
+ sub_8053994(a2);
+ (*a1)++;
+ break;
+ case 1:
+ sub_8054BA8();
+ (*a1)++;
+ break;
+ case 2:
+ sub_8054D4C(a2);
+ (*a1)++;
+ break;
+ case 3:
+ mli4_mapscripts_and_other();
+ sub_8054E34();
+ (*a1)++;
+ break;
+ case 4:
+ sub_8054814();
+ sub_8054C54();
+ SetUpWindowConfig(&gWindowConfig_81E6C3C);
+ InitMenuWindow(&gWindowConfig_81E6CE4);
+ (*a1)++;
+ break;
+ case 5:
+ move_tilemap_camera_to_upper_left_corner();
+ (*a1)++;
+ break;
+ case 6:
+ sub_8056D28(gMapHeader.mapData);
+ (*a1)++;
+ break;
+ case 7:
+ sub_8056D38(gMapHeader.mapData);
+ (*a1)++;
+ break;
+ case 8:
+ apply_map_tileset1_tileset2_palette(gMapHeader.mapData);
+ (*a1)++;
+ break;
+ case 9:
+ DrawWholeMapView();
+ (*a1)++;
+ break;
+ case 10:
+ cur_mapheader_run_tileset_funcs_after_some_cpuset();
+ (*a1)++;
+ break;
+ case 11:
+ if (gMapHeader.flags == 1 && sub_80BBB24() == 1)
+ ShowMapNamePopup();
+ (*a1)++;
+ break;
+ case 12:
+ sub_80543E8();
+ (*a1)++;
+ break;
+ case 13:
+ return 1;
+ }
+ return 0;
+}
+
+bool32 sub_8054A4C(u8 *a1)
+{
+ switch (*a1)
+ {
+ case 0:
+ sub_8054BA8();
+ sub_8054D4C(0);
+ sub_8054E20();
+ sub_8054E34();
+ (*a1)++;
+ break;
+ case 1:
+ sub_8054C2C();
+ (*a1)++;
+ break;
+ case 2:
+ sub_80543E8();
+ (*a1)++;
+ break;
+ case 3:
+ return 1;
+ }
+ return 0;
+}
+
+bool32 sub_8054A9C(u8 *a1)
+{
+ switch (*a1)
+ {
+ case 0:
+ FieldClearVBlankHBlankCallbacks();
+ sub_8054BA8();
+ (*a1)++;
+ break;
+ case 1:
+ sub_8054D4C(1);
+ (*a1)++;
+ break;
+ case 2:
+ sub_8054F48();
+ sub_8054E20();
+ sub_8054E7C();
+ (*a1)++;
+ break;
+ case 3:
+ sub_8054814();
+ sub_8054C54();
+ SetUpWindowConfig(&gWindowConfig_81E6C3C);
+ InitMenuWindow(&gWindowConfig_81E6CE4);
+ (*a1)++;
+ break;
+ case 4:
+ move_tilemap_camera_to_upper_left_corner();
+ (*a1)++;
+ break;
+ case 5:
+ sub_8056D28(gMapHeader.mapData);
+ (*a1)++;
+ break;
+ case 6:
+ sub_8056D38(gMapHeader.mapData);
+ (*a1)++;
+ break;
+ case 7:
+ apply_map_tileset1_tileset2_palette(gMapHeader.mapData);
+ (*a1)++;
+ break;
+ case 8:
+ DrawWholeMapView();
+ (*a1)++;
+ break;
+ case 9:
+ cur_mapheader_run_tileset_funcs_after_some_cpuset();
+ (*a1)++;
+ break;
+ case 12:
+ sub_80543E8();
+ (*a1)++;
+ break;
+ case 10:
+ case 11:
+ (*a1)++;
+ break;
+ case 13:
+ SetFieldVBlankCallback();
+ (*a1)++;
+ return 1;
+ }
+ return 0;
+}
+
+void do_load_map_stuff_loop(u8 *a1)
+{
+ while (!sub_805493C(a1, 0))
+ ;
+}
+
+void sub_8054BA8(void)
+{
+ u8 *addr;
+ u32 size;
+
+ REG_DISPCNT = 0;
+
+ remove_some_task();
+
+ DmaClear16(3, PLTT + 2, PLTT_SIZE - 2);
+
+ addr = (void *)VRAM;
+ size = 0x18000;
+ while (1)
+ {
+ DmaFill16(3, 0, addr, 0x1000);
+ addr += 0x1000;
+ size -= 0x1000;
+ if (size <= 0x1000)
+ {
+ DmaFill16(3, 0, addr, size);
+ break;
+ }
+ }
+
+ ResetOamRange(0, 128);
+ LoadOam();
+}
+
+void sub_8054C2C(void)
+{
+ sub_8054814();
+ sub_8054C54();
+ SetUpWindowConfig(&gWindowConfig_81E6C3C);
+ InitMenuWindow(&gWindowConfig_81E6CE4);
+ mapdata_load_assets_to_gpu_and_full_redraw();
+}
+
+void sub_8054C54(void)
+{
+ REG_MOSAIC = 0;
+ REG_WININ = 7967;
+ REG_WINOUT = 257;
+ REG_WIN0H = 255;
+ REG_WIN0V = 255;
+ REG_WIN1H = -1;
+ REG_WIN1V = -1;
+ REG_BLDCNT = gUnknown_081E29E0[1] | gUnknown_081E29E0[2] | gUnknown_081E29E0[3] | 0x1040;
+ REG_BLDALPHA = 1805;
+ *gBGHOffsetRegs[0] = 0;
+ *gBGVOffsetRegs[0] = 0;
+ *gBGControlRegs[0] = 0;
+ *gBGHOffsetRegs[1] = 0;
+ *gBGVOffsetRegs[1] = 0;
+ *gBGControlRegs[1] = 7489;
+ *gBGHOffsetRegs[2] = 0;
+ *gBGVOffsetRegs[2] = 0;
+ *gBGControlRegs[2] = 7234;
+ *gBGHOffsetRegs[3] = 0;
+ *gBGVOffsetRegs[3] = 0;
+ *gBGControlRegs[3] = 7747;
+ REG_DISPCNT = gUnknown_081E29D8[1] | 0x7060 | gUnknown_081E29D8[2] | gUnknown_081E29D8[0] | gUnknown_081E29D8[3];
+}
+
+void sub_8054D4C(u32 a1)
+{
+ ResetTasks();
+ ResetSpriteData();
+ ResetPaletteFade();
+ dp12_8087EA4();
+ ResetCameraUpdateInfo();
+ InstallCameraPanAheadCallback();
+ sub_805C7C4(0);
+ FieldEffectActiveListClear();
+ InitFieldMessageBox();
+ sub_807C828();
+ sub_8080750();
+ if (!a1)
+ SetUpFieldTasks();
+ mapheader_run_script_with_tag_x5();
+}
+
+void sub_8054D90(void)
+{
+ gUnknown_0300489C = 0;
+ gUnknown_03004898 = 0;
+ sub_805AA98();
+ sub_805B55C(0, 0);
+ mapheader_run_first_tag4_script_list_match();
+}
+
+void mli4_mapscripts_and_other(void)
+{
+ s16 x, y;
+ struct UnkPlayerStruct *player;
+ gUnknown_0300489C = 0;
+ gUnknown_03004898 = 0;
+ sub_805AA98();
+ sav1_camera_get_focus_coords(&x, &y);
+ player = sub_8053AA8();
+ InitPlayerAvatar(x, y, player->player_field_1, gSaveBlock2.playerGender);
+ SetPlayerAvatarTransitionFlags(player->player_field_0);
+ player_avatar_init_params_reset();
+ sub_805B55C(0, 0);
+ ResetBerryTreeSparkleFlags();
+ mapheader_run_first_tag4_script_list_match();
+}
+
+void sub_8054E20(void)
+{
+ sub_805B710(0, 0);
+ RotatingGate_InitPuzzleAndGraphics();
+}
+
+void sub_8054E34(void)
+{
+ gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_15 = 1;
+ InitCameraUpdateCallback(gPlayerAvatar.spriteId);
+}
+
+void sub_8054E60(void)
+{
+ InitCameraUpdateCallback(sub_8055AE8(gUnknown_03004860));
+}
+
+void sub_8054E7C(void)
+{
+ InitCameraUpdateCallback(sub_8055AE8(gUnknown_03004860));
+}
+
+void sub_8054E98(void)
+{
+ u16 x, y;
+ sav1_camera_get_focus_coords(&x, &y);
+ sub_8056C50(x + gUnknown_03004860, y);
+}
+
+void sub_8054EC8(void)
+{
+ u16 i;
+ u16 x, y;
+
+ sav1_camera_get_focus_coords(&x, &y);
+ x -= gUnknown_03004860;
+
+ for (i = 0; i < gFieldLinkPlayerCount; i++)
+ {
+ SpawnLinkPlayerMapObject(i, i + x, y, gLinkPlayers[i].gender);
+ CreateLinkPlayerSprite(i);
+ }
+
+ sub_8055340(word_3002910);
+}
+
+void sub_8054F48(void)
+{
+ u16 i;
+ for (i = 0; i < gFieldLinkPlayerCount; i++)
+ CreateLinkPlayerSprite(i);
+}
+
+void sub_8054F70(void)
+{
+ int i;
+ for (i = 0; i < 4; i++)
+ gUnknown_03000580[i] = 0x80;
+}
+
+bool32 sub_8054F88(u16 a1)
+{
+ int i;
+ int count = gFieldLinkPlayerCount;
+
+ for (i = 0; i < count; i++)
+ if (gUnknown_03000580[i] != a1)
+ return FALSE;
+ return TRUE;
+}
+
+bool32 sub_8054FC0(u16 a1)
+{
+ int i;
+ int count = gFieldLinkPlayerCount;
+
+ for (i = 0; i < count; i++)
+ if (gUnknown_03000580[i] == a1)
+ return TRUE;
+ return FALSE;
+}
+
+void sub_8054FF8(u32 a1, u16 a2, struct UnkStruct_8054FF8 *a3, u16 *a4)
+{
+ u8 *script;
+
+ if (gUnknown_03000580[a1] == 0x80)
+ {
+ script = sub_8055648(a3);
+ if (script)
+ {
+ *a4 = sub_8055758(script);
+ gUnknown_03000580[a1] = 0x81;
+ if (a3->b)
+ {
+ sub_80543DC(sub_80553E4);
+ sub_8055808(script);
+ }
+ return;
+ }
+ if (sub_8054FC0(0x83) == 1)
+ {
+ gUnknown_03000580[a1] = 0x81;
+ if (a3->b)
+ {
+ sub_80543DC(sub_80553E4);
+ sub_805585C();
+ }
+ return;
+ }
+ switch (a2)
+ {
+ case 24:
+ if (sub_8055630(a3))
+ {
+ gUnknown_03000580[a1] = 0x81;
+ if (a3->b)
+ {
+ sub_80543DC(sub_80553E4);
+ sub_80557F4();
+ }
+ }
+ break;
+ case 18:
+ if (sub_8055660(a3) == 1)
+ {
+ gUnknown_03000580[a1] = 0x81;
+ if (a3->b)
+ {
+ sub_80543DC(sub_80553E4);
+ sub_8055824();
+ }
+ }
+ break;
+ case 25:
+ script = sub_805568C(a3);
+ if (script)
+ {
+ gUnknown_03000580[a1] = 0x81;
+ if (a3->b)
+ {
+ sub_80543DC(sub_80553E4);
+ sub_8055840(script);
+ }
+ }
+ break;
+ case 27:
+ if (sub_8055618(a3))
+ {
+ gUnknown_03000580[a1] = 0x81;
+ if (a3->b)
+ {
+ sub_80543DC(sub_8055408);
+ sub_80557E8();
+ }
+ }
+ break;
+ case 28:
+ if (sub_8055618(a3))
+ {
+ gUnknown_03000580[a1] = 0x81;
+ if (a3->b)
+ {
+ sub_80543DC(sub_8055438);
+ sub_80557E8();
+ }
+ }
+ break;
+ }
+ }
+
+ switch (a2)
+ {
+ case 23:
+ gUnknown_03000580[a1] = 0x83;
+ break;
+ case 22:
+ gUnknown_03000580[a1] = 0x82;
+ break;
+ case 26:
+ gUnknown_03000580[a1] = 0x80;
+ if (a3->b)
+ sub_80543DC(sub_8055390);
+ break;
+ case 29:
+ if (gUnknown_03000580[a1] == 0x82)
+ gUnknown_03000580[a1] = 0x81;
+ break;
+ }
+}
+
+void sub_8055218(u16 *a1, int a2)
+{
+ struct UnkStruct_8054FF8 st;
+ int i;
+ for (i = 0; i < 4; i++)
+ {
+ u16 v5 = a1[i];
+ u16 v8 = 0;
+ sub_80555B0(i, a2, &st);
+ sub_8054FF8(i, v5, &st, &v8);
+ if (gUnknown_03000580[i] == 0x80)
+ v8 = sub_805530C(v5);
+ sub_8055BFC(i, v8);
+ }
+}
+
+void sub_8055280(u16 a1)
+{
+ if (a1 >= 17 && a1 < 30)
+ word_3004858 = a1;
+ else
+ word_3004858 = 17;
+}
+
+u16 sub_80552B0(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;
+ }
+}
+
+u16 sub_805530C(u16 a1)
+{
+ switch (a1)
+ {
+ case 21:
+ return 4;
+ case 20:
+ return 3;
+ case 19:
+ return 1;
+ case 18:
+ return 2;
+ default:
+ return 0;
+ }
+}
+
+void sub_8055340(u16 *a1)
+{
+ int i;
+ for (i = 0; i < 4; i++)
+ a1[i] = 17;
+}
+
+void sub_8055354(void)
+{
+ u8 val = gUnknown_03004860;
+ sub_8055218(word_3002910, val);
+ sub_8055280(gUnknown_03000584(val));
+ sub_8055340(word_3002910);
+}
+
+u16 sub_8055390(u32 a1)
+{
+ if (ScriptContext2_IsEnabled() == 1)
+ return 17;
+ if (gLink.recvQueue.count > 4)
+ return 27;
+ if (gLink.sendQueue.count <= 4)
+ return sub_80552B0(a1);
+ return 28;
+}
+
+u16 sub_80553E0(u32 a1)
+{
+ return 17;
+}
+
+u16 sub_80553E4(u32 a1)
+{
+ u16 retVal;
+ if (ScriptContext2_IsEnabled() == 1)
+ {
+ retVal = 17;
+ }
+ else
+ {
+ retVal = 26;
+ sub_80543DC(sub_80553E0);
+ }
+ return retVal;
+}
+
+u16 sub_8055408(u32 a1)
+{
+ u16 retVal;
+ if (gLink.recvQueue.count > 2)
+ {
+ retVal = 17;
+ }
+ else
+ {
+ retVal = 26;
+ ScriptContext2_Disable();
+ sub_80543DC(sub_80553E0);
+ }
+ return retVal;
+}
+
+u16 sub_8055438(u32 a1)
+{
+ u16 retVal;
+ if (gLink.sendQueue.count > 2)
+ {
+ retVal = 17;
+ }
+ else
+ {
+ retVal = 26;
+ ScriptContext2_Disable();
+ sub_80543DC(sub_80553E0);
+ }
+ return retVal;
+}
+
+u16 sub_8055468(u32 a1)
+{
+ return 17;
+}
+
+u16 sub_805546C(u32 linkPlayerId)
+{
+ if (gUnknown_03000580[linkPlayerId] == 0x82 && (gMain.newKeys & B_BUTTON))
+ {
+ sub_80543DC(sub_8055468);
+ return 29;
+ }
+ else
+ {
+ return 17;
+ }
+}
+
+u16 sub_80554A4(u32 a1)
+{
+ sub_80543DC(sub_805546C);
+ return 22;
+}
+
+u16 sub_80554B8(u32 a1)
+{
+ return 17;
+}
+
+u16 sub_80554BC(u32 a1)
+{
+ if (sub_8054F88(0x83) == TRUE)
+ {
+ ScriptContext1_SetupScript(gUnknown_081A4508);
+ sub_80543DC(sub_80554B8);
+ }
+ return 17;
+}
+
+u16 sub_80554E4(u32 a1)
+{
+ sub_80543DC(sub_80554BC);
+ return 23;
+}
+
+u32 sub_80554F8(void)
+{
+ if (sub_8054FC0(0x83) == TRUE)
+ return 2;
+ if (gUnknown_03000584 == sub_805546C && gUnknown_03000580[gUnknown_03004860] != 0x82)
+ return 0;
+ if (gUnknown_03000584 == sub_8055468 && gUnknown_03000580[gUnknown_03004860] == 0x81)
+ return 2;
+ return sub_8054F88(0x82);
+}
+
+bool32 unref_sub_8055568(void)
+{
+ return sub_8054FC0(0x83);
+}
+
+u16 sub_8055574(void)
+{
+ sub_80543DC(sub_80554A4);
+ return 0;
+}
+
+u16 sub_8055588(void)
+{
+ sub_80543DC(sub_80553E4);
+ return 0;
+}
+
+u16 sub_805559C(void)
+{
+ sub_80543DC(sub_80554E4);
+ return 0;
+}
+
+void sub_80555B0(int linkPlayerId, int 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_8055B30(linkPlayerId);
+ sub_8055B08(linkPlayerId, &x, &y);
+ a3->sub.x = x;
+ a3->sub.y = y;
+ a3->sub.height = sub_8055B50(linkPlayerId);
+ a3->field_C = MapGridGetMetatileBehaviorAt(x, y);
+}
+
+bool32 sub_8055618(struct UnkStruct_8054FF8 *a1)
+{
+ u8 v1 = a1->c;
+ if (v1 == 2 || v1 == 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool32 sub_8055630(struct UnkStruct_8054FF8 *a1)
+{
+ u8 v1 = a1->c;
+ if (v1 == 2 || v1 == 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+u8 *sub_8055648(struct UnkStruct_8054FF8 *a1)
+{
+ if (a1->c != 2)
+ return 0;
+ return sub_8068E24(&a1->sub);
+}
+
+bool32 sub_8055660(struct UnkStruct_8054FF8 *a1)
+{
+ if (a1->c != 2 && a1->c != 0)
+ return FALSE;
+ if (!MetatileBehavior_IsSouthArrowWarp(a1->field_C))
+ return FALSE;
+ if (a1->d != 1)
+ return FALSE;
+ return TRUE;
+}
+
+u8 *sub_805568C(struct UnkStruct_8054FF8 *a1)
+{
+ struct MapPosition unkStruct;
+ u8 linkPlayerId;
+
+ if (a1->c && a1->c != 2)
+ return 0;
+
+ unkStruct = a1->sub;
+ unkStruct.x += gUnknown_0821664C[a1->d].x;
+ unkStruct.y += gUnknown_0821664C[a1->d].y;
+ unkStruct.height = 0;
+ linkPlayerId = GetLinkPlayerIdAt(unkStruct.x, unkStruct.y);
+
+ if (linkPlayerId != 4)
+ {
+ if (!a1->b)
+ return TradeRoom_TooBusyToNotice;
+ if (gUnknown_03000580[linkPlayerId] != 0x80)
+ return TradeRoom_TooBusyToNotice;
+ if (!sub_8083BF4(linkPlayerId))
+ return TradeRoom_ReadTrainerCard1;
+ else
+ return TradeRoom_ReadTrainerCard2;
+ }
+
+ return sub_80682A8(&unkStruct, a1->field_C, a1->d);
+}
+
+u16 sub_8055758(u8 *script)
+{
+ if (script == DoubleBattleColosseum_EventScript_1A4383)
+ return 10;
+ if (script == DoubleBattleColosseum_EventScript_1A439E)
+ return 9;
+ if (script == DoubleBattleColosseum_EventScript_1A43B9)
+ return 10;
+ if (script == DoubleBattleColosseum_EventScript_1A43D4)
+ return 9;
+ if (script == RecordCorner_EventScript_1A4418)
+ return 10;
+ if (script == RecordCorner_EventScript_1A442D)
+ return 9;
+ if (script == RecordCorner_EventScript_1A4442)
+ return 10;
+ if (script == RecordCorner_EventScript_1A4457)
+ return 9;
+ if (script == SingleBattleColosseum_EventScript_1A436F)
+ return 10;
+ if (script == SingleBattleColosseum_EventScript_1A4379)
+ return 9;
+ if (script == TradeCenter_EventScript_1A43F0)
+ return 10;
+ if (script == TradeCenter_EventScript_1A43FA)
+ return 9;
+ return 0;
+}
+
+void sub_80557E8(void)
+{
+ ScriptContext2_Enable();
+}
+
+void sub_80557F4(void)
+{
+ PlaySE(SE_WIN_OPEN);
+ sub_8071310();
+ ScriptContext2_Enable();
+}
+
+void sub_8055808(u8 *script)
+{
+ PlaySE(SE_SELECT);
+ ScriptContext1_SetupScript(script);
+ ScriptContext2_Enable();
+}
+
+void sub_8055824(void)
+{
+ PlaySE(SE_WIN_OPEN);
+ ScriptContext1_SetupScript(TradeRoom_PromptToCancelLink);
+ ScriptContext2_Enable();
+}
+
+void sub_8055840(u8 *script)
+{
+ PlaySE(SE_SELECT);
+ ScriptContext1_SetupScript(script);
+ ScriptContext2_Enable();
+}
+
+void sub_805585C(void)
+{
+ ScriptContext1_SetupScript(TradeRoom_TerminateLink);
+ ScriptContext2_Enable();
+}
+
+bool32 sub_8055870(void)
+{
+ if (!is_c1_link_related_active())
+ return 0;
+ if (gLink.recvQueue.count >= 3)
+ gUnknown_03000588 = 1;
+ else
+ gUnknown_03000588 = 0;
+ return gUnknown_03000588;
+}
+
+bool32 sub_80558AC(void)
+{
+ u8 temp;
+
+ if (is_c1_link_related_active() != TRUE)
+ return FALSE;
+
+ if (sub_8007B24() != TRUE)
+ return FALSE;
+
+ if (gUnknown_03000584 == sub_8055408)
+ return TRUE;
+
+ if (gUnknown_03000584 != sub_80553E4)
+ return FALSE;
+
+ temp = gUnknown_03000588;
+ gUnknown_03000588 = 0;
+
+ if (temp == TRUE)
+ return TRUE;
+
+ if (gPaletteFade.active && gPaletteFade.softwareFadeFinishing)
+ return TRUE;
+
+ return FALSE;
+}
+
+bool32 sub_8055910(void)
+{
+ if (is_c1_link_related_active() != TRUE)
+ return FALSE;
+
+ if (sub_8007B24() != TRUE)
+ return FALSE;
+
+ if (gUnknown_03000584 == sub_8055438)
+ return TRUE;
+
+ return FALSE;
+}
+
+bool32 sub_8055940(void)
+{
+ if (!sub_8007B24())
+ return FALSE;
+ return TRUE;
+}
+
+void ZeroLinkPlayerMapObject(struct LinkPlayerMapObject *linkPlayerMapObj)
+{
+ memset(linkPlayerMapObj, 0, sizeof(struct LinkPlayerMapObject));
+}
+
+void strange_npc_table_clear(void)
+{
+ memset(gLinkPlayerMapObjects, 0, sizeof(gLinkPlayerMapObjects));
+}
+
+void ZeroMapObject(struct MapObject *mapObj)
+{
+ memset(mapObj, 0, sizeof(struct MapObject));
+}
+
+void SpawnLinkPlayerMapObject(u8 linkPlayerId, s16 x, s16 y, u8 a4)
+{
+ u8 mapObjId = sub_805AB54();
+ 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->mapobj_unk_19 = 2;
+ mapObj->spriteId = 64;
+
+ InitLinkPlayerMapObjectPos(mapObj, x, y);
+}
+
+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_80603CC(x, y, &mapObj->coords1.x, &mapObj->coords1.y);
+ mapObj->coords1.x += 8;
+ FieldObjectUpdateZCoord(mapObj);
+}
+
+void unref_sub_8055A6C(u8 linkPlayerId, u8 a2)
+{
+ if (gLinkPlayerMapObjects[linkPlayerId].active)
+ {
+ u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+ mapObj->mapobj_unk_19 = a2;
+ }
+}
+
+void unref_sub_8055A9C(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;
+}
+
+u8 sub_8055AE8(u8 linkPlayerId)
+{
+ u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+ return mapObj->spriteId;
+}
+
+void sub_8055B08(u8 linkPlayerId, u16 *x, u16 *y)
+{
+ u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+ *x = mapObj->coords2.x;
+ *y = mapObj->coords2.y;
+}
+
+u8 sub_8055B30(u8 linkPlayerId)
+{
+ u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+ return mapObj->mapobj_unk_19;
+}
+
+u8 sub_8055B50(u8 linkPlayerId)
+{
+ u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+ return mapObj->mapobj_unk_0B_0;
+}
+
+s32 unref_sub_8055B74(u8 linkPlayerId)
+{
+ u8 mapObjId = gLinkPlayerMapObjects[linkPlayerId].mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+ return 16 - (s8)mapObj->mapobj_unk_21;
+}
+
+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;
+}
+
+void sub_8055BFC(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_082166D8[gUnknown_082166A0[linkPlayerMapObj->mode](linkPlayerMapObj, mapObj, a2)](linkPlayerMapObj, mapObj);
+ }
+}
+
+static u8 sub_8055C68(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3)
+{
+ return gUnknown_082166AC[a3](linkPlayerMapObj, mapObj, a3);
+}
+
+static u8 sub_8055C88(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3)
+{
+ return 1;
+}
+
+static u8 sub_8055C8C(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3)
+{
+ return gUnknown_082166AC[a3](linkPlayerMapObj, mapObj, a3);
+}
+
+static u8 sub_8055CAC(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3)
+{
+ return 0;
+}
+
+static u8 sub_8055CB0(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3)
+{
+ s16 x, y;
+
+ mapObj->mapobj_unk_19 = npc_something3(a3, mapObj->mapobj_unk_19);
+ FieldObjectMoveDestCoords(mapObj, mapObj->mapobj_unk_19, &x, &y);
+
+ if (LinkPlayerDetectCollision(linkPlayerMapObj->mapObjId, mapObj->mapobj_unk_19, x, y))
+ {
+ return 0;
+ }
+ else
+ {
+ mapObj->mapobj_unk_21 = 16;
+ npc_coords_shift(mapObj, x, y);
+ FieldObjectUpdateZCoord(mapObj);
+ return 1;
+ }
+}
+
+static u8 sub_8055D18(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj, u8 a3)
+{
+ mapObj->mapobj_unk_19 = npc_something3(a3, mapObj->mapobj_unk_19);
+ return 0;
+}
+
+static void sub_8055D30(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj)
+{
+ linkPlayerMapObj->mode = 0;
+}
+
+static void sub_8055D38(struct LinkPlayerMapObject *linkPlayerMapObj, struct MapObject *mapObj)
+{
+ mapObj->mapobj_unk_21--;
+ linkPlayerMapObj->mode = 1;
+ MoveCoords(mapObj->mapobj_unk_19, &mapObj->coords1.x, &mapObj->coords1.y);
+ if (!mapObj->mapobj_unk_21)
+ {
+ npc_coords_shift_still(mapObj);
+ linkPlayerMapObj->mode = 2;
+ }
+}
+
+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;
+}
+
+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);
+}
+
+void CreateLinkPlayerSprite(u8 linkPlayerId)
+{
+ struct LinkPlayerMapObject *linkPlayerMapObj = &gLinkPlayerMapObjects[linkPlayerId];
+ u8 mapObjId = linkPlayerMapObj->mapObjId;
+ struct MapObject *mapObj = &gMapObjects[mapObjId];
+ struct Sprite *sprite;
+
+ if (linkPlayerMapObj->active)
+ {
+ u8 val = GetRivalAvatarGraphicsIdByStateIdAndGender(0, mapObj->mapobj_bit_1);
+ mapObj->spriteId = AddPseudoFieldObject(val, SpriteCB_LinkPlayer, 0, 0, 0);
+ sprite = &gSprites[mapObj->spriteId];
+ sprite->coordOffsetEnabled = TRUE;
+ sprite->data0 = linkPlayerId;
+ mapObj->mapobj_bit_2 = 0;
+ }
+}
+
+void SpriteCB_LinkPlayer(struct Sprite *sprite)
+{
+ struct LinkPlayerMapObject *linkPlayerMapObj = &gLinkPlayerMapObjects[sprite->data0];
+ 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);
+ if (!linkPlayerMapObj->mode)
+ StartSpriteAnim(sprite, FieldObjectDirectionToImageAnimId(mapObj->mapobj_unk_19));
+ else
+ StartSpriteAnimIfDifferent(sprite, get_go_image_anim_num(mapObj->mapobj_unk_19));
+ sub_806487C(sprite, 0);
+ if (mapObj->mapobj_bit_2)
+ {
+ sprite->invisible = ((sprite->data7 & 4) >> 2);
+ sprite->data7++;
+ }
+}
diff --git a/src/field/party_menu.c b/src/field/party_menu.c
new file mode 100644
index 000000000..39477e293
--- /dev/null
+++ b/src/field/party_menu.c
@@ -0,0 +1,1494 @@
+#include "global.h"
+#include "party_menu.h"
+#include "battle.h"
+#include "battle_interface.h"
+#include "battle_party_menu.h"
+#include "data2.h"
+#include "event_data.h"
+#include "item.h"
+#include "item_use.h"
+#include "mail_data.h"
+#include "main.h"
+#include "menu.h"
+#include "palette.h"
+#include "pokemon.h"
+#include "pokemon_item_effect.h"
+#include "pokemon_menu.h"
+#include "pokemon_summary_screen.h"
+#include "rom_8077ABC.h"
+#include "rom_8094928.h"
+#include "songs.h"
+#include "sound.h"
+#include "species.h"
+#include "sprite.h"
+#include "string_util.h"
+#include "strings.h"
+#include "task.h"
+#include "sprite.h"
+#include "palette.h"
+#include "event_data.h"
+#include "main.h"
+#include "item.h"
+#include "battle_interface.h"
+#include "species.h"
+#include "party_menu.h"
+
+struct Unk201C000
+{
+ /*0x00*/ struct Pokemon *pokemon;
+ /*0x04*/ u8 unk4;
+ /*0x05*/ u8 unk5;
+ /*0x06*/ u16 unk6;
+ /*0x08*/ u16 unk8;
+ /*0x0A*/ u8 pad_0A[2];
+ /*0x0C*/ s32 unkC;
+ /*0x10*/ TaskFunc unk10;
+ /*0x14*/ TaskFunc unk14;
+};
+
+struct Unk201F000
+{
+ u8 filler0[0xE00];
+ u8 unkE00[3]; // not sure if this is an array or struct, or how big it is
+};
+
+struct UnknownStruct5
+{
+ u8 unk0;
+ u8 unk1;
+ u16 *unk4;
+};
+
+#define ewram1C000 (*(struct Unk201C000 *)(ewram + 0x1C000))
+#define ewram1F000 (*(struct Unk201F000 *)(ewram + 0x1F000))
+
+extern u8 gUnknown_0202E8F4;
+extern u8 gUnknown_0202E8F6;
+extern u16 gUnknown_0202E8F8;
+extern u8 gUnknown_0202E8FA;
+extern u8 gLastFieldPokeMenuOpened;
+extern u8 gPlayerPartyCount;
+extern s32 gBattleMoveDamage;
+
+//extern const u16 gUnknown_083769A8[][6];
+//extern const u8 gUnknown_083769A8[][12];
+extern void *const gUnknown_08376858[][6];
+extern const u8 gUnknown_083769A8[];
+extern const u8 gUnknown_08376D1C[DATA_COUNT];
+extern const u16 gUnknown_08376504[];
+extern void (*const gUnknown_08376B54[])(u8);
+extern const u8 *const gUnknown_08376D04[DATA_COUNT];
+extern const struct UnknownStruct5 gUnknown_08376BB4[][6];
+
+static void sub_806E884(u8 taskId);
+
+/*
+void sub_806AEDC(void)
+{
+ const struct UnknownStruct5 *r5;
+ s32 i;
+
+ AnimateSprites();
+ BuildOamBuffer();
+ r5 = gUnknown_08376BB4[gUnknown_0202E8FA];
+ for (i = 0; i < 6; i++)
+ sub_800142C(r5[i].unk0 * 8, r5[i].unk1 * 8, r5[i].unk4, 0, (i << 5) | 0x200);
+ RunTasks();
+ UpdatePaletteFade();
+}
+*/
+
+#if ENGLISH
+#define WINDOW_LEFT (3)
+#define WINDOW_RIGHT (26)
+#elif GERMAN
+#define WINDOW_LEFT (0)
+#define WINDOW_RIGHT (29)
+#endif
+
+u8 sub_806E834(const u8 *message, u8 arg1)
+{
+ u8 taskId;
+
+ gUnknown_0202E8F6 = 1;
+
+ MenuDrawTextWindow(WINDOW_LEFT, 14, WINDOW_RIGHT, 19);
+ MenuPrintMessage(message, WINDOW_LEFT + 1, 15);
+
+ taskId = CreateTask(sub_806E884, 1);
+ gTasks[taskId].data[0] = arg1;
+
+ return taskId;
+}
+
+static void sub_806E884(u8 taskId)
+{
+ if (MenuUpdateWindowText())
+ {
+ gUnknown_0202E8F6 = 0;
+ if (gTasks[taskId].data[0] == 0)
+ MenuZeroFillWindowRect(WINDOW_LEFT, 14, WINDOW_RIGHT, 19);
+ DestroyTask(taskId);
+ }
+}
+
+void sub_806E8D0(u8 taskId, u16 b, TaskFunc c)
+{
+ ewram1C000.unk10 = c;
+ ewram1C000.unk4 = taskId;
+ ewram1C000.unk5 = sub_806CA38(taskId);
+ ewram1C000.unk6 = b;
+ ewram1C000.pokemon = &gPlayerParty[ewram1C000.unk5];
+}
+
+bool8 PartyMenuUpdateMonHeldItem(struct Pokemon *pkmn, u16 item)
+{
+ u8 itemData[2];
+
+ if (ItemIsMail(item) == TRUE)
+ {
+ if (GiveMailToMon(pkmn, item) == 0xFF)
+ return TRUE;
+ gUnknown_0202E8F4 = 2;
+ }
+ else
+ {
+ gUnknown_0202E8F4 = 1;
+ }
+
+ itemData[0] = item;
+ itemData[1] = item >> 8;
+ SetMonData(pkmn, MON_DATA_HELD_ITEM, itemData);
+ return FALSE;
+}
+
+void PartyMenuTryGiveMonHeldItem(u8 taskId, u16 newItem, TaskFunc c)
+{
+ u16 currentItem;
+
+ gTasks[taskId].func = TaskDummy;
+ sub_806E8D0(taskId, newItem, c);
+ currentItem = GetMonData(ewram1C000.pokemon, MON_DATA_HELD_ITEM);
+ gUnknown_0202E8F4 = 0;
+ gUnknown_0202E8F8 = 0;
+ if (currentItem != 0)
+ {
+ if (ItemIsMail(currentItem) == TRUE)
+ {
+ sub_806E834(gOtherText_MailMustBeRemoved, 1);
+ CreateTask(party_menu_link_mon_held_item_object, 5);
+ }
+ else
+ {
+ GetMonNickname(ewram1C000.pokemon, gStringVar1);
+ CopyItemName(currentItem, gStringVar2);
+ StringExpandPlaceholders(gStringVar4, gOtherText_AlreadyHolding);
+ sub_806E834(gStringVar4, 1);
+ CreateTask(Task_ConfirmGiveHeldItem, 5);
+ if (ItemIsMail(newItem) == TRUE)
+ gUnknown_0202E8F8 = currentItem;
+ }
+ }
+ else
+ {
+ PartyMenuUpdateMonHeldItem(ewram1C000.pokemon, newItem);
+ RemoveBagItem(newItem, 1);
+ if (ItemIsMail(newItem))
+ {
+ gTasks[taskId].func = c;
+ }
+ else
+ {
+ DisplayGiveHeldItemMessage(ewram1C000.unk5, newItem, 1);
+ CreateTask(party_menu_link_mon_held_item_object, 5);
+ }
+ }
+}
+
+void party_menu_link_mon_held_item_object(u8 taskId)
+{
+ if (gUnknown_0202E8F6 == 0)
+ {
+ SetHeldItemIconVisibility(ewram1C000.unk4, ewram1C000.unk5);
+ gTasks[ewram1C000.unk4].func = ewram1C000.unk10;
+ DestroyTask(taskId);
+ }
+}
+
+void PartyMenuTryGiveMonHeldItem_806EACC(u8 taskId)
+{
+ s8 selection = ProcessMenuInputNoWrap_();
+
+ if (selection == 0)
+ {
+ u16 currentItem;
+
+ MenuZeroFillWindowRect(23, 8, 29, 13);
+ currentItem = GetMonData(ewram1C000.pokemon, MON_DATA_HELD_ITEM);
+ RemoveBagItem(ewram1C000.unk6, 1);
+ if (AddBagItem(currentItem, 1) == TRUE)
+ {
+ PartyMenuUpdateMonHeldItem(ewram1C000.pokemon, ewram1C000.unk6);
+ if (ItemIsMail(ewram1C000.unk6))
+ {
+ DisplayTakeHeldItemMessage(ewram1C000.unk5, currentItem, 1);
+ }
+ else
+ {
+ CopyItemName(ewram1C000.unk6, gStringVar1);
+ StringExpandPlaceholders(gStringVar4, gOtherText_TakenAndReplaced);
+ sub_806E834(gStringVar4, 1);
+ }
+ }
+ else
+ {
+ sub_806E834(gOtherText_BagFullCannotRemoveItem, 0);
+ AddBagItem(ewram1C000.unk6, 1);
+ }
+ }
+ else
+ {
+ if (selection != 1 && selection != -1)
+ return;
+ if (selection == -1)
+ PlaySE(SE_SELECT);
+ MenuZeroFillWindowRect(23, 8, 29, 13);
+ }
+ gTasks[taskId].func = party_menu_link_mon_held_item_object;
+}
+
+void Task_ConfirmGiveHeldItem(u8 taskId)
+{
+ if (gUnknown_0202E8F6 == 0)
+ {
+ DisplayYesNoMenu(23, 8, 1);
+ gTasks[taskId].func = PartyMenuTryGiveMonHeldItem_806EACC;
+ }
+}
+
+void DisplayGiveHeldItemMessage(u8 a, u16 b, u8 c)
+{
+ GetMonNickname(&gPlayerParty[a], gStringVar1);
+ CopyItemName(b, gStringVar2);
+ StringExpandPlaceholders(gStringVar4, gOtherText_WasGivenToHold);
+ sub_806E834(gStringVar4, c);
+}
+
+
+// Not sure about this one for now.
+/*
+void PartyMenuTryGiveMonMail(u8 taskId, TaskFunc func)
+{
+ u16 currentItem;
+ struct MailStruct *r4;
+
+ gTasks[taskId].func = TaskDummy;
+ sub_806E8D0(taskId, 0, func);
+ currentItem = GetMonData(ewram1C000.pokemon, MON_DATA_HELD_ITEM);
+ gUnknown_0202E8F4 = 0;
+ r4 = &gSaveBlock1.mail[ewram1F000.unkE00[0] + ewram1F000.unkE00[2]];
+ if (currentItem != 0)
+ {
+ sub_806E834(gOtherText_PokeHoldingItemCantMail, 1);
+ CreateTask(party_menu_link_mon_held_item_object, 5);
+ }
+ else
+ {
+ GiveMailToMon2(ewram1C000.pokemon, r4);
+ ClearMailStruct(r4);
+ sub_806E834(gOtherText_MailTransferredMailbox, 1);
+ CreateTask(party_menu_link_mon_held_item_object, 5);
+ }
+}
+*/
+__attribute__((naked))
+void PartyMenuTryGiveMonMail(u8 taskId, TaskFunc func)
+{
+ asm(".syntax unified\n\
+ push {r4,r5,lr}\n\
+ adds r2, r1, 0\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ ldr r3, _0806ECA0 @ =gTasks\n\
+ lsls r1, r0, 2\n\
+ adds r1, r0\n\
+ lsls r1, 3\n\
+ adds r1, r3\n\
+ ldr r3, _0806ECA4 @ =TaskDummy\n\
+ str r3, [r1]\n\
+ movs r1, 0\n\
+ bl sub_806E8D0\n\
+ ldr r5, _0806ECA8 @ =0x0201c000\n\
+ ldr r0, [r5]\n\
+ movs r1, 0xC\n\
+ bl GetMonData\n\
+ lsls r0, 16\n\
+ ldr r2, _0806ECAC @ =gUnknown_0202E8F4\n\
+ movs r1, 0\n\
+ strb r1, [r2]\n\
+ movs r1, 0xF8\n\
+ lsls r1, 6\n\
+ adds r2, r5, r1\n\
+ ldrb r1, [r2]\n\
+ adds r1, 0x6\n\
+ ldrb r2, [r2, 0x2]\n\
+ adds r1, r2\n\
+ lsls r2, r1, 3\n\
+ adds r2, r1\n\
+ lsls r2, 2\n\
+ ldr r1, _0806ECB0 @ =gSaveBlock1 + 0x2B4C\n\
+ adds r4, r2, r1\n\
+ cmp r0, 0\n\
+ beq _0806ECBC\n\
+ ldr r0, _0806ECB4 @ =gOtherText_PokeHoldingItemCantMail\n\
+ movs r1, 0x1\n\
+ bl sub_806E834\n\
+ ldr r0, _0806ECB8 @ =party_menu_link_mon_held_item_object\n\
+ movs r1, 0x5\n\
+ bl CreateTask\n\
+ b _0806ECDA\n\
+ .align 2, 0\n\
+_0806ECA0: .4byte gTasks\n\
+_0806ECA4: .4byte TaskDummy\n\
+_0806ECA8: .4byte 0x0201c000\n\
+_0806ECAC: .4byte gUnknown_0202E8F4\n\
+_0806ECB0: .4byte gSaveBlock1 + 0x2B4C\n\
+_0806ECB4: .4byte gOtherText_PokeHoldingItemCantMail\n\
+_0806ECB8: .4byte party_menu_link_mon_held_item_object\n\
+_0806ECBC:\n\
+ ldr r0, [r5]\n\
+ adds r1, r4, 0\n\
+ bl GiveMailToMon2\n\
+ adds r0, r4, 0\n\
+ bl ClearMailStruct\n\
+ ldr r0, _0806ECE0 @ =gOtherText_MailTransferredMailbox\n\
+ movs r1, 0x1\n\
+ bl sub_806E834\n\
+ ldr r0, _0806ECE4 @ =party_menu_link_mon_held_item_object\n\
+ movs r1, 0x5\n\
+ bl CreateTask\n\
+_0806ECDA:\n\
+ pop {r4,r5}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .align 2, 0\n\
+_0806ECE0: .4byte gOtherText_MailTransferredMailbox\n\
+_0806ECE4: .4byte party_menu_link_mon_held_item_object\n\
+ .syntax divided\n");
+}
+
+void PartyMenuTryGiveMonHeldItem_806ECE8(u8 taskId, TaskFunc func)
+{
+ u16 currentItem;
+
+ gTasks[taskId].func = TaskDummy;
+ sub_806E8D0(taskId, 0, func);
+ currentItem = GetMonData(ewram1C000.pokemon, MON_DATA_HELD_ITEM);
+ if (currentItem == 0)
+ {
+ StringExpandPlaceholders(gStringVar4, gOtherText_NotHoldingAnything);
+ sub_806E834(gStringVar4, 0);
+ CreateTask(party_menu_link_mon_held_item_object, 5);
+ }
+ else
+ {
+ u8 itemData[2];
+
+ itemData[0] = 0;
+ itemData[1] = 0;
+ if (AddBagItem(currentItem, 1) == TRUE)
+ {
+ if (ItemIsMail(currentItem) == TRUE)
+ TakeMailFromMon(ewram1C000.pokemon);
+ DisplayTakeHeldItemMessage(ewram1C000.unk5, currentItem, 0);
+ SetMonData(ewram1C000.pokemon, MON_DATA_HELD_ITEM, itemData);
+ }
+ else
+ {
+ sub_806E834(gOtherText_BagFullCannotRemoveItem, 0);
+ }
+ CreateTask(party_menu_link_mon_held_item_object, 5);
+ }
+}
+
+void DisplayTakeHeldItemMessage(u8 a, u16 b, u8 c)
+{
+ GetMonNickname(&gPlayerParty[a], gStringVar1);
+ CopyItemName(b, gStringVar2);
+ StringExpandPlaceholders(gStringVar4, gOtherText_ReceivedTheThingFrom);
+ sub_806E834(gStringVar4, c);
+}
+
+void DoTakeMail(u8 taskId, TaskFunc func)
+{
+ gTasks[taskId].func = TaskDummy;
+ sub_806E8D0(taskId, 0, func);
+ ewram1C000.unk6 = GetMonData(ewram1C000.pokemon, MON_DATA_HELD_ITEM);
+ sub_806E834(gOtherText_SendRemovedMailPrompt, 1);
+ CreateTask(Task_ConfirmTakeHeldMail, 5);
+}
+
+void Task_LoseMailMessage(u8 taskId)
+{
+ s8 selection = ProcessMenuInputNoWrap_();
+
+ if (selection == 0)
+ {
+ if (AddBagItem(ewram1C000.unk6, 1) == TRUE)
+ {
+ TakeMailFromMon(ewram1C000.pokemon);
+ sub_806E834(gOtherText_MailTaken, 0);
+ }
+ else
+ {
+ sub_806E834(gOtherText_BagFullCannotRemoveItem, 0);
+ }
+ MenuZeroFillWindowRect(23, 8, 29, 13);
+ gTasks[taskId].func = party_menu_link_mon_held_item_object;
+ }
+ else
+ {
+ if (selection != 1 && selection != -1)
+ return;
+ if (selection == -1)
+ PlaySE(SE_SELECT);
+ MenuZeroFillWindowRect(23, 8, 29, 13);
+ MenuZeroFillWindowRect(0, 14, 29, 19);
+ gTasks[taskId].func = party_menu_link_mon_held_item_object;
+ }
+}
+
+void Task_ConfirmLoseMailMessage(u8 taskId)
+{
+ if (gUnknown_0202E8F6 == 0)
+ {
+ DisplayYesNoMenu(23, 8, 1);
+ gTasks[taskId].func = Task_LoseMailMessage;
+ }
+}
+
+void Task_TakeHeldMail(u8 taskId)
+{
+ s8 selection = ProcessMenuInputNoWrap_();
+
+ if (selection == 0)
+ {
+ MenuZeroFillWindowRect(23, 8, 29, 13);
+ if (TakeMailFromMon2(ewram1C000.pokemon) != 0xFF)
+ sub_806E834(gOtherText_MailWasSent, 0);
+ else
+ sub_806E834(gOtherText_MailboxIsFull, 0);
+ gTasks[taskId].func = party_menu_link_mon_held_item_object;
+ }
+ else
+ {
+ if (selection != 1 && selection != -1)
+ return;
+ if (selection == -1)
+ PlaySE(SE_SELECT);
+ MenuZeroFillWindowRect(23, 8, 29, 13);
+ sub_806E834(gOtherText_MailRemovedMessageLost, 1);
+ gTasks[taskId].func = Task_ConfirmLoseMailMessage;
+ }
+}
+
+void Task_ConfirmTakeHeldMail(u8 taskId)
+{
+ if (gUnknown_0202E8F6 == 0)
+ {
+ DisplayYesNoMenu(23, 8, 1);
+ gTasks[taskId].func = Task_TakeHeldMail;
+ }
+}
+
+u16 ItemIdToBattleMoveId(u16 item)
+{
+ u16 moveId = item - 289;
+
+ return gUnknown_08376504[moveId];
+}
+
+bool8 pokemon_has_move(struct Pokemon *pkmn, u16 move)
+{
+ u8 i;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (GetMonData(pkmn, MON_DATA_MOVE1 + i) == move)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void TeachMonTMMove(u8 taskId, u16 move, TaskFunc func)
+{
+ PlaySE(SE_SELECT);
+ gTasks[taskId].func = TaskDummy;
+ sub_806E8D0(taskId, move, func);
+ CreateTask(Task_TeamMonTMMove, 5);
+}
+
+void Task_TeamMonTMMove(u8 taskId)
+{
+ GetMonNickname(ewram1C000.pokemon, gStringVar1);
+ ewram1C000.unk8 = ItemIdToBattleMoveId(ewram1C000.unk6);
+ StringCopy(gStringVar2, gMoveNames[ewram1C000.unk8]);
+ ewram1B000.unk282 = 0;
+ if (pokemon_has_move(ewram1C000.pokemon, ewram1C000.unk8))
+ {
+ StringExpandPlaceholders(gStringVar4, gOtherText_AlreadyKnows);
+ sub_806E834(gStringVar4, 1);
+ gTasks[taskId].func = party_menu_link_mon_held_item_object;
+ }
+ else
+ {
+ if (!CanMonLearnTMHM(ewram1C000.pokemon, ewram1C000.unk6 - 33))
+ {
+ StringExpandPlaceholders(gStringVar4, gOtherText_NotCompatible);
+ sub_806E834(gStringVar4, 1);
+ gTasks[taskId].func = party_menu_link_mon_held_item_object;
+ }
+ else
+ {
+ if (GiveMoveToMon(ewram1C000.pokemon, ewram1C000.unk8) != 0xFFFF)
+ {
+ Task_TeamMonTMMove2(taskId);
+ }
+ else
+ {
+ StringExpandPlaceholders(gStringVar4, gOtherText_WantsToLearn);
+ sub_806E834(gStringVar4, 1);
+ gTasks[taskId].func = sub_806F358;
+ }
+ }
+ }
+}
+
+void Task_TeamMonTMMove2(u8 taskId)
+{
+ StringCopy(gStringVar2, gMoveNames[ewram1C000.unk8]);
+ StringExpandPlaceholders(gStringVar4, gOtherText_LearnedMove);
+ sub_806E834(gStringVar4, 1);
+ AdjustFriendship(ewram1C000.pokemon, 4);
+ if (ewram1B000.unk282 == 0 && ewram1C000.unk6 <= 0x152)
+ RemoveBagItem(ewram1C000.unk6, 1);
+ gTasks[taskId].func = Task_TeamMonTMMove3;
+}
+
+void Task_TeamMonTMMove3(u8 taskId)
+{
+ if (gUnknown_0202E8F6 == 0)
+ {
+ PlayFanfare(BGM_FANFA1);
+ gTasks[taskId].func = Task_TeamMonTMMove4;
+ }
+}
+
+void Task_TeamMonTMMove4(u8 taskId)
+{
+ if (IsFanfareTaskInactive())
+ {
+ if ((gMain.newKeys & A_BUTTON) || (gMain.newKeys & B_BUTTON))
+ {
+ SetHeldItemIconVisibility(ewram1C000.unk4, ewram1C000.unk5);
+ if (ewram1B000.unk282 == 1)
+ {
+ sub_8070C54(taskId);
+ }
+ else
+ {
+ gTasks[ewram1C000.unk4].func = ewram1C000.unk10;
+ DestroyTask(taskId);
+ }
+ }
+ }
+}
+
+void sub_806F2FC(u8 taskId)
+{
+ if (gUnknown_0202E8F6 == 0)
+ {
+ SetHeldItemIconVisibility(ewram1C000.unk4, ewram1C000.unk5);
+ if (ewram1B000.unk282 == 1)
+ {
+ sub_8070C54(taskId);
+ }
+ else
+ {
+ gTasks[ewram1C000.unk4].func = ewram1C000.unk10;
+ DestroyTask(taskId);
+ }
+ }
+}
+
+void sub_806F358(u8 taskId)
+{
+ if (gUnknown_0202E8F6 == 0)
+ {
+ DisplayYesNoMenu(23, 8, 1);
+ gTasks[taskId].func = sub_806F390;
+ }
+}
+
+void sub_806F390(u8 taskId)
+{
+ s8 selection = ProcessMenuInputNoWrap_();
+
+ if (selection == 0)
+ {
+ MenuZeroFillWindowRect(23, 8, 29, 13);
+ sub_806E834(gOtherText_WhichMoveToForget2, 1);
+ gTasks[taskId].func = sub_806F44C;
+ }
+ else
+ {
+ if (selection != 1 && selection != -1)
+ return;
+ if (selection == -1)
+ PlaySE(SE_SELECT);
+ StopTryingToTeachMove_806F614(taskId);
+ }
+}
+
+void sub_806F3FC(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ sub_809D9F0(gPlayerParty, ewram1C000.unk5, gPlayerPartyCount - 1, sub_808B564, ewram1C000.unk8);
+ DestroyTask(taskId);
+ }
+}
+
+void sub_806F44C(u8 taskId)
+{
+ if (gUnknown_0202E8F6 == 0)
+ {
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0);
+ gTasks[taskId].func = sub_806F3FC;
+ }
+}
+
+void TaughtMove(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ u8 moveIndex;
+ u16 r4;
+
+ gTasks[taskId].func = TaskDummy;
+ sub_806E8D0(taskId, gScriptItemId, sub_808B508);
+ moveIndex = sub_809FA30();
+ r4 = GetMonData(ewram1C000.pokemon, MON_DATA_MOVE1 + moveIndex);
+ GetMonNickname(ewram1C000.pokemon, gStringVar1);
+ StringCopy(gStringVar2, gMoveNames[r4]);
+ StringExpandPlaceholders(gStringVar4, gOtherText_ForgetMove123_2);
+ sub_806E834(gStringVar4, 1);
+ CreateTask(TMMoveUpdateMoveSlot, 5);
+ }
+}
+
+void TMMoveUpdateMoveSlot(u8 taskId)
+{
+ if (gUnknown_0202E8F6 == 0)
+ {
+ RemoveMonPPBonus(ewram1C000.pokemon, sub_809FA30());
+ SetMonMoveSlot(ewram1C000.pokemon, ewram1C000.unk8, sub_809FA30());
+ Task_TeamMonTMMove2(taskId);
+ }
+}
+
+void StopTryingToTeachMove_806F588(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ gTasks[taskId].func = TaskDummy;
+ sub_806E8D0(taskId, gScriptItemId, sub_808B508);
+ StringCopy(gStringVar2, gMoveNames[ewram1C000.unk8]);
+ StringExpandPlaceholders(gStringVar4, gOtherText_StopTryingTo);
+ sub_806E834(gStringVar4, 1);
+ CreateTask(StopTryingToTeachMove_806F67C, 5);
+ }
+}
+
+void StopTryingToTeachMove_806F614(u8 taskId)
+{
+ MenuZeroFillWindowRect(23, 8, 29, 13);
+ StringCopy(gStringVar2, gMoveNames[ewram1C000.unk8]);
+ StringExpandPlaceholders(gStringVar4, gOtherText_StopTryingTo);
+ sub_806E834(gStringVar4, 1);
+ gTasks[taskId].func = StopTryingToTeachMove_806F67C;
+}
+
+void StopTryingToTeachMove_806F67C(u8 taskId)
+{
+ if (gUnknown_0202E8F6 == 0)
+ {
+ DisplayYesNoMenu(23, 8, 1);
+ gTasks[taskId].func = StopTryingToTeachMove_806F6B4;
+ }
+}
+
+void StopTryingToTeachMove_806F6B4(u8 taskId)
+{
+ s8 selection = ProcessMenuInputNoWrap_();
+
+ if (selection == 0)
+ {
+ MenuZeroFillWindowRect(23, 8, 29, 13);
+ GetMonNickname(ewram1C000.pokemon, gStringVar1);
+ StringCopy(gStringVar2, gMoveNames[ewram1C000.unk8]);
+ StringExpandPlaceholders(gStringVar4, gOtherText_DidNotLearnMove2);
+ sub_806E834(gStringVar4, 1);
+ gTasks[taskId].func = sub_806F2FC;
+ }
+ else
+ {
+ if (selection != 1 && selection != -1)
+ return;
+ if (selection == -1)
+ PlaySE(SE_SELECT);
+ MenuZeroFillWindowRect(23, 8, 29, 13);
+ GetMonNickname(ewram1C000.pokemon, gStringVar1);
+ StringCopy(gStringVar2, gMoveNames[ewram1C000.unk8]);
+ StringExpandPlaceholders(gStringVar4, gOtherText_WantsToLearn);
+ sub_806E834(gStringVar4, 1);
+ gTasks[taskId].func = sub_806F358;
+ }
+}
+
+bool8 IsHMMove(u16 move)
+{
+ u8 i;
+
+ for (i = 0; i < 8; i++)
+ {
+ if (gUnknown_08376504[50 + i] == move)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+s16 sub_806F7E8(u8 taskId, struct BattleInterfaceStruct1 *b, s8 c)
+{
+ s16 *taskData;
+ u8 hpBarLevel;
+ void *vramPtr;
+
+ taskData = gTasks[taskId].data;
+
+ b->unk0 = taskData[10];
+ b->unk4 = taskData[11];
+ b->unk8 = taskData[12] * c;
+ b->unk10 = 0x100;
+ hpBarLevel = GetHPBarLevel(ewram1B000.unk282, b->unk0);
+ if (hpBarLevel > 2)
+ b->unkC_0 = 4;
+ if (hpBarLevel == 2)
+ b->unkC_0 = 5;
+ if (hpBarLevel < 2)
+ b->unkC_0 = 6;
+ vramPtr = gUnknown_08376858[IsDoubleBattle()][ewram1C000.unk5];
+ return sub_80460C8(b, &ewram1C000.unkC, vramPtr, 0);
+}
+
+void sub_806F8AC(u8 taskId)
+{
+ struct BattleInterfaceStruct1 sp0;
+ u16 sp14;
+
+ ewram1B000.unk282 = sub_806F7E8(taskId, &sp0, -1);
+ if (ewram1B000.unk282 == -1)
+ {
+ ewram1C000.unkC = 0;
+ if (-sp0.unk8 + sp0.unk4 > sp0.unk0)
+ sp14 = sp0.unk0 - sp0.unk4;
+ else
+ sp14 = -sp0.unk8;
+ gBattleMoveDamage = -sp14;
+ GetMonNickname(ewram1C000.pokemon, gStringVar1);
+ ConvertIntToDecimalStringN(gStringVar2, sp14, 0, 3);
+ if (gTasks[taskId].data[14] == 0)
+ StringExpandPlaceholders(gStringVar4, gOtherText_HPRestoredBy);
+ else
+ StringExpandPlaceholders(gStringVar4, gOtherText_RegainedHealth);
+ SetMonIconAnim(GetMonIconSpriteId_maybe(ewram1C000.unk4, ewram1C000.unk5), ewram1C000.pokemon);
+ task_pc_turn_off(&gUnknown_083769A8[IsDoubleBattle() * 12 + ewram1C000.unk5 * 2], 7);
+ ewram1B000.unk261 = 2;
+ sub_806E834(gStringVar4, 1);
+ sp14 += sp0.unk4;
+ SetMonData(ewram1C000.pokemon, MON_DATA_HP, (u8 *)&sp14);
+ RemoveBagItem(ewram1C000.unk6, 1);
+ sub_8032638();
+ gTasks[taskId].func = sub_806FB44;
+ }
+ else
+ {
+ PartyMenuDoPrintHP(ewram1C000.unk5, IsDoubleBattle(), ewram1B000.unk282, sp0.unk0);
+ }
+}
+
+void sub_806FA18(u8 taskId)
+{
+ struct BattleInterfaceStruct1 sp0;
+
+ ewram1B000.unk282 = sub_806F7E8(taskId, &sp0, 1);
+ if (ewram1B000.unk282 == -1)
+ {
+ PlaySE(SE_KAIFUKU);
+ ewram1C000.unkC = 0;
+ gTasks[taskId].data[11] -= gTasks[taskId].data[12];
+ SetMonData(ewram1C000.pokemon, MON_DATA_HP, (u8 *)&gTasks[taskId].data[11]);
+ SetMonIconAnim(GetMonIconSpriteId_maybe(ewram1C000.unk4, ewram01000.unk1), ewram1C000.pokemon);
+ ewram1C000.unk5 = gSprites[ewram01000.unk2].data0;
+ ewram1C000.pokemon = &gPlayerParty[ewram1C000.unk5];
+ gTasks[taskId].data[10] = GetMonData(ewram1C000.pokemon, MON_DATA_MAX_HP);
+ gTasks[taskId].data[11] = GetMonData(ewram1C000.pokemon, MON_DATA_HP);
+ ewram1C000.unkC = -32768;
+ ewram1C000.unk14 = ewram1C000.unk10;
+ gTasks[taskId].func = sub_806F8AC;
+ ewram1B000.unk282 = gTasks[taskId].data[11];
+ }
+ else
+ {
+ PartyMenuDoPrintHP(ewram1C000.unk5, IsDoubleBattle(), ewram1B000.unk282, sp0.unk0);
+ }
+}
+
+void sub_806FB0C(u8 taskId)
+{
+ if (gUnknown_0202E8F6 == 0)
+ {
+ gTasks[ewram1C000.unk4].func = ewram1C000.unk10;
+ DestroyTask(taskId);
+ }
+}
+
+void sub_806FB44(u8 taskId)
+{
+ if (gUnknown_0202E8F6 == 0)
+ {
+ gTasks[ewram1C000.unk4].func = ewram1C000.unk14;
+ DestroyTask(taskId);
+ }
+}
+
+bool8 IsHPRecoveryItem(u16 item)
+{
+ const u8 *itemEffect;
+
+ if (item == 0xAF)
+ itemEffect = gSaveBlock1.enigmaBerry.itemEffect;
+ else
+ itemEffect = gItemEffectTable[item - 13];
+
+ if (itemEffect[4] & 4)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void PartyMenuUpdateLevelOrStatus(struct Pokemon *pkmn, u8 b)
+{
+ PartyMenuClearLevelStatusTilemap(b);
+ PartyMenuPrintMonLevelOrStatus(b, pkmn);
+}
+
+void GetMedicineItemEffectMessage(u16 item)
+{
+ switch (GetItemEffectType(item))
+ {
+ case 3:
+ StringExpandPlaceholders(gStringVar4, gOtherText_CuredPoisoning);
+ break;
+ case 4:
+ StringExpandPlaceholders(gStringVar4, gOtherText_WokeUp);
+ break;
+ case 5:
+ StringExpandPlaceholders(gStringVar4, gOtherText_BurnHealed);
+ break;
+ case 6:
+ StringExpandPlaceholders(gStringVar4, gOtherText_ThawedOut);
+ break;
+ case 7:
+ StringExpandPlaceholders(gStringVar4, gOtherText_CuredParalysis);
+ break;
+ case 8:
+ StringExpandPlaceholders(gStringVar4, gOtherText_SnapConfusion);
+ break;
+ case 9:
+ StringExpandPlaceholders(gStringVar4, gOtherText_GotOverLove);
+ break;
+ case 11:
+ StringExpandPlaceholders(gStringVar4, gOtherText_BecameHealthy);
+ break;
+ case 13:
+ StringCopy(gStringVar2, gOtherText_Hp2);
+ StringExpandPlaceholders(gStringVar4, gOtherText_WasRaised);
+ break;
+ case 12:
+ StringCopy(gStringVar2, gOtherText_Attack);
+ StringExpandPlaceholders(gStringVar4, gOtherText_WasRaised);
+ break;
+ case 17:
+ StringCopy(gStringVar2, gOtherText_Defense);
+ StringExpandPlaceholders(gStringVar4, gOtherText_WasRaised);
+ break;
+ case 16:
+ StringCopy(gStringVar2, gOtherText_Speed);
+ StringExpandPlaceholders(gStringVar4, gOtherText_WasRaised);
+ break;
+ case 14:
+ StringCopy(gStringVar2, gOtherText_SpAtk2);
+ StringExpandPlaceholders(gStringVar4, gOtherText_WasRaised);
+ break;
+ case 15:
+ StringCopy(gStringVar2, gOtherText_SpDef2);
+ StringExpandPlaceholders(gStringVar4, gOtherText_WasRaised);
+ break;
+ case 19:
+ case 20:
+ StringExpandPlaceholders(gStringVar4, gOtherText_PPIncreased);
+ break;
+ case 21:
+ StringExpandPlaceholders(gStringVar4, gOtherText_PPRestored);
+ break;
+ default:
+ StringExpandPlaceholders(gStringVar4, gOtherText_WontHaveAnyEffect);
+ break;
+ }
+}
+
+bool8 IsMedicineIneffective(struct Pokemon *pkmn, u16 item)
+{
+ if (GetItemEffectType(item) == 13
+ && GetMonData(pkmn, MON_DATA_SPECIES) == SPECIES_SHEDINJA)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 ExecuteTableBasedItemEffect__(u8 a, u16 b, u8 c)
+{
+ if (gMain.inBattle)
+ return ExecuteTableBasedItemEffect_(&gPlayerParty[a], b, sub_8094C20(a), c);
+ else
+ return ExecuteTableBasedItemEffect_(&gPlayerParty[a], b, a, c);
+}
+
+void UseMedicine(u8 taskId, u16 item, TaskFunc func)
+{
+ u8 r7;
+ bool8 r9 = FALSE;
+ bool8 r0;
+
+ gTasks[taskId].func = TaskDummy;
+ r7 = CreateTask(TaskDummy, 5);
+ sub_806E8D0(taskId, item, func);
+ if (!IsMedicineIneffective(ewram1C000.pokemon, item))
+ {
+ r9 = IsHPRecoveryItem(item);
+ if (r9 == TRUE)
+ {
+ gTasks[r7].data[10] = GetMonData(ewram1C000.pokemon, MON_DATA_MAX_HP);
+ gTasks[r7].data[11] = GetMonData(ewram1C000.pokemon, MON_DATA_HP);
+ if (gTasks[r7].data[10] == gTasks[r7].data[11])
+ {
+ r9 = FALSE;
+ gTasks[r7].data[10] = 0;
+ gTasks[r7].data[11] = 0;
+ }
+ }
+ r0 = ExecuteTableBasedItemEffect__(ewram1C000.unk5, item, 0);
+ }
+ else
+ {
+ r0 = TRUE;
+ }
+
+ if (r0)
+ {
+ gUnknown_0202E8F4 = 0;
+ PlaySE(SE_SELECT);
+ sub_806E834(gOtherText_WontHaveAnyEffect, 1);
+ gTasks[r7].func = sub_806FB0C;
+ }
+ else
+ {
+ u8 statusAndPkrs;
+
+ gUnknown_0202E8F4 = 1;
+ if (!IsBlueYellowRedFlute(item))
+ PlaySE(SE_KAIFUKU);
+ else
+ PlaySE(SE_BIDORO);
+ statusAndPkrs = GetMonStatusAndPokerus(ewram1C000.pokemon);
+ if (statusAndPkrs == 6 || statusAndPkrs == 0)
+ PartyMenuUpdateLevelOrStatus(ewram1C000.pokemon, ewram1C000.unk5);
+ if (r9 == TRUE)
+ {
+ gTasks[r7].data[12] = GetMonData(ewram1C000.pokemon, MON_DATA_HP) - gTasks[r7].data[11];
+ ewram1C000.unkC = -32768;
+ if (gTasks[r7].data[11] == 0)
+ gTasks[r7].data[14] = 1;
+ else
+ gTasks[r7].data[14] = 0;
+ ewram1C000.unk14 = ewram1C000.unk10;
+ gTasks[r7].func = sub_806F8AC;
+ ewram1B000.unk282 = gTasks[r7].data[11];
+ }
+ else
+ {
+ GetMonNickname(ewram1C000.pokemon, gStringVar1);
+ if (!IsBlueYellowRedFlute(item))
+ RemoveBagItem(item, 1);
+ GetMedicineItemEffectMessage(item);
+ TryPrintPartyMenuMonNickname(ewram1C000.unk5, ewram1C000.pokemon);
+ sub_806E834(gStringVar4, 1);
+ gTasks[r7].func = sub_806FB0C;
+ }
+ }
+}
+
+bool8 IsBlueYellowRedFlute(u16 item)
+{
+ if (item == 0x27
+ || item == 0x29
+ || item == 0x28)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void sub_8070048(u8 taskId, u16 item, TaskFunc func)
+{
+ ewram1C000.unk10 = func;
+ ewram1C000.unk4 = taskId;
+ ewram1C000.unk6 = item;
+ ewram1C000.unk5 = 0;
+ ewram1C000.unk14 = sub_80701DC;
+ ewram1B000.unk27E = 0;
+ ewram1B000.unk280 = 0;
+ sub_8070088(taskId);
+}
+
+void sub_8070088(u8 taskId)
+{
+ u8 taskId2;
+
+ gTasks[taskId].func = TaskDummy;
+ if (GetMonData(&gPlayerParty[ewram1C000.unk5], MON_DATA_SPECIES) == 0)
+ {
+ gTasks[taskId].func = sub_80701DC;
+ }
+ else
+ {
+ s16 *taskData;
+
+ taskId2 = CreateTask(TaskDummy, 5);
+ taskData = gTasks[taskId2].data;
+ ewram1C000.pokemon = &gPlayerParty[ewram1C000.unk5];
+ taskData[10] = GetMonData(ewram1C000.pokemon, MON_DATA_MAX_HP);
+ taskData[11] = GetMonData(ewram1C000.pokemon, MON_DATA_HP);
+ if (ExecuteTableBasedItemEffect__(ewram1C000.unk5, ewram1C000.unk6, 0))
+ {
+ DestroyTask(taskId2);
+ gTasks[taskId].func = sub_80701DC;
+ }
+ else
+ {
+ gUnknown_0202E8F4 = 1;
+ MenuZeroFillWindowRect(WINDOW_LEFT, 14, WINDOW_RIGHT, 19);
+ PlaySE(SE_KAIFUKU);
+ PartyMenuUpdateLevelOrStatus(ewram1C000.pokemon, ewram1C000.unk5);
+ task_pc_turn_off(&gUnknown_083769A8[IsDoubleBattle() * 12 + ewram1C000.unk5 * 2], 9);
+ ewram1B000.unk261 = 2;
+ taskData[12] = GetMonData(ewram1C000.pokemon, MON_DATA_HP) - taskData[11];
+ taskData[14] = 1;
+ ewram1B000.unk27E = 1;
+ ewram1B000.unk280 = 1;
+ ewram1B000.unk282 = taskData[11];
+ ewram1C000.unkC = -32768;
+ gTasks[taskId2].func = sub_806F8AC;
+ }
+ }
+}
+
+void sub_80701DC(u8 taskId)
+{
+ if (ewram1B000.unk27E == 1)
+ {
+ AddBagItem(ewram1C000.unk6, 1);
+ if (GetMonData(&gPlayerParty[ewram1C000.unk5], MON_DATA_SPECIES) != 0)
+ {
+ task_pc_turn_off(&gUnknown_083769A8[IsDoubleBattle() * 12 + ewram1C000.unk5 * 2], 3);
+ ewram1B000.unk261 = 2;
+ }
+ ewram1B000.unk27E = 0;
+ }
+ ewram1C000.unk5++;
+ if (ewram1C000.unk5 == 6)
+ {
+ gUnknown_0202E8F4 = 0;
+ if (ewram1B000.unk280 == 0)
+ {
+ gTasks[taskId].func = TaskDummy;
+ sub_806E834(gOtherText_WontHaveAnyEffect, 1);
+ CreateTask(sub_806FB0C, 8);
+ }
+ else
+ {
+ RemoveBagItem(ewram1C000.unk6, 1);
+ gTasks[taskId].func = ewram1C000.unk10;
+ }
+ gLastFieldPokeMenuOpened = 0;
+ }
+ else
+ {
+ sub_8070088(taskId);
+ }
+}
+
+void CreateItemUseMoveMenu(u8 partyMonIndex)
+{
+ u8 r6;
+ u8 i;
+
+ r6 = 0;
+ MenuDrawTextWindow(19, 10, 29, 19);
+ for (i = 0; i < 4; i++)
+ {
+ u16 move = GetMonData(&gPlayerParty[partyMonIndex], MON_DATA_MOVE1 + i);
+
+ MenuPrint(gMoveNames[move], 20, i * 2 + 11);
+ if (move != 0)
+ r6++;
+ }
+ InitMenu(0, 20, 11, r6, 0, 9);
+}
+
+void Task_HandleItemUseMoveMenuInput(u8 taskId)
+{
+ if (gMain.newKeys & DPAD_UP)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor(-1);
+ }
+ else if (gMain.newKeys & DPAD_DOWN)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor(1);
+ }
+ else if (gMain.newKeys & A_BUTTON)
+ {
+ gUnknown_08376B54[0](taskId);
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ gUnknown_08376B54[1](taskId);
+ }
+}
+
+void DoPPRecoveryItemEffect(u8 taskId, u16 b, TaskFunc c)
+{
+ const u8 *itemEffect;
+ u8 taskId2;
+
+ if (b == 0xAF)
+ itemEffect = gSaveBlock1.enigmaBerry.itemEffect;
+ else
+ itemEffect = gItemEffectTable[b - 13];
+ gTasks[taskId].func = TaskDummy;
+ taskId2 = CreateTask(TaskDummy, 5);
+ sub_806E8D0(taskId, b, c);
+ if (!(itemEffect[4] & 0x10))
+ {
+ gTasks[taskId2].data[11] = 0;
+ DoRecoverPP(taskId2);
+ }
+ else
+ {
+ PlaySE(SE_SELECT);
+ sub_806D538(10, 3);
+ CreateItemUseMoveMenu(ewram1C000.unk5);
+ gTasks[taskId2].func = Task_HandleItemUseMoveMenuInput;
+ gMain.newKeys = 0;
+ }
+}
+
+void ItemUseMoveMenu_HandleMoveSelection(u8 taskId)
+{
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(19, 10, 29, 19);
+ sub_806D5A4();
+ gTasks[taskId].data[11] = GetMenuCursorPos();
+ DoRecoverPP(taskId);
+}
+
+void ItemUseMoveMenu_HandleCancel(u8 taskId)
+{
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(19, 10, 29, 19);
+ if (gMain.inBattle)
+ gTasks[ewram1C000.unk4].func = SetUpBattlePokemonMenu;
+ else
+ gTasks[ewram1C000.unk4].func = sub_808B0C0;
+ sub_806D538(3, 0);
+ DestroyTask(taskId);
+}
+
+void DoRecoverPP(u8 taskId)
+{
+ u16 r5 = 0;
+
+ if (ExecuteTableBasedItemEffect__(ewram1C000.unk5, ewram1C000.unk6, gTasks[taskId].data[11]))
+ {
+ gUnknown_0202E8F4 = r5;
+ PlaySE(SE_SELECT);
+ sub_806E834(gOtherText_WontHaveAnyEffect, 1);
+ }
+ else
+ {
+ gUnknown_0202E8F4 = 1;
+ PlaySE(SE_KAIFUKU);
+ RemoveBagItem(ewram1C000.unk6, 1);
+ r5 = GetMonData(ewram1C000.pokemon, MON_DATA_MOVE1 + gTasks[taskId].data[11]);
+ StringCopy(gStringVar1, gMoveNames[r5]);
+ GetMedicineItemEffectMessage(ewram1C000.unk6);
+ sub_806E834(gStringVar4, 1);
+ }
+ gTasks[taskId].func = sub_806FB0C;
+}
+
+void DoPPUpItemEffect(u8 taskId, u16 b, TaskFunc c)
+{
+ gTasks[taskId].func = TaskDummy;
+ sub_806E8D0(taskId, b, c);
+ PlaySE(SE_SELECT);
+ sub_806D538(11, 3);
+ CreateItemUseMoveMenu(ewram1C000.unk5);
+ CreateTask(Task_HandleItemUseMoveMenuInput, 5);
+ gMain.newKeys = 0;
+}
+
+void DoRareCandyItemEffect(u8 taskId, u16 b, TaskFunc c)
+{
+ u8 i;
+ bool8 r0;
+
+ gTasks[taskId].func = TaskDummy;
+ sub_806E8D0(taskId, b, c);
+
+ if (GetMonData(ewram1C000.pokemon, MON_DATA_LEVEL) != 100)
+ {
+ for (i = 0; i < 6; i++)
+ ewram1B000.unk264[i] = GetMonData(ewram1C000.pokemon, gUnknown_08376D1C[i]);
+ r0 = ExecuteTableBasedItemEffect__(ewram1C000.unk5, b, 0);
+ }
+ else
+ r0 = TRUE;
+
+ if (r0)
+ {
+ gUnknown_0202E8F4 = 0;
+ PlaySE(SE_SELECT);
+ sub_806E834(gOtherText_WontHaveAnyEffect, 1);
+ CreateTask(sub_806FB0C, 5);
+ }
+ else
+ {
+ u8 level;
+
+ gUnknown_0202E8F4 = 1;
+ PlayFanfareByFanfareNum(0);
+ sub_8070A20(ewram1C000.unk5, ewram1C000.pokemon);
+ RemoveBagItem(b, 1);
+ GetMonNickname(ewram1C000.pokemon, gStringVar1);
+ level = GetMonData(ewram1C000.pokemon, MON_DATA_LEVEL);
+ ConvertIntToDecimalStringN(gStringVar2, level, 0, 3);
+ StringExpandPlaceholders(gStringVar4, gOtherText_ElevatedTo);
+ sub_806E834(gStringVar4, 1);
+ CreateTask(Task_RareCandy1, 5);
+ }
+}
+
+void Task_RareCandy1(u8 taskId)
+{
+ if (WaitFanfare(0) && gUnknown_0202E8F6 == 0)
+ {
+ if ((gMain.newKeys & A_BUTTON) || (gMain.newKeys & B_BUTTON))
+ {
+ PlaySE(SE_SELECT);
+ sub_8070848(taskId);
+ gTasks[taskId].func = Task_RareCandy2;
+ }
+ }
+}
+
+void Task_RareCandy2(u8 taskId)
+{
+ if ((gMain.newKeys & A_BUTTON) || (gMain.newKeys & B_BUTTON))
+ {
+ PlaySE(SE_SELECT);
+ sub_8070968(taskId);
+ gTasks[taskId].func = Task_RareCandy3;
+ }
+}
+
+#if ENGLISH
+void sub_8070848(u8 taskId)
+{
+ u8 i;
+
+ MenuDrawTextWindow(11, 0, 29, 7);
+
+ for (i = 0; i < DATA_COUNT; i++)
+ {
+ u8 x;
+ u8 y;
+ u32 stat;
+
+ stat = GetMonData(ewram1C000.pokemon, gUnknown_08376D1C[i]);
+
+ ewram1B000.unk264[i + DATA_COUNT] = stat;
+ ewram1B000.unk264[i] = stat - ewram1B000.unk264[i];
+
+ x = (i / 3) * 9 + 11;
+ y = ((i % 3) << 1) + 1;
+
+ MenuPrint_PixelCoords(gUnknown_08376D04[i], (x + 1) * 8, y * 8, 1);
+
+ if (i == 2)
+ MenuPrint_PixelCoords(gOtherText_TallPlusAndRightArrow, (x + 6) * 8 + 6, y * 8, 0);
+ else
+ MenuPrint_PixelCoords(gOtherText_TallPlusAndRightArrow, (x + 6) * 8 + 6, y * 8, 1);
+
+ gStringVar1[0] = EXT_CTRL_CODE_BEGIN;
+ gStringVar1[1] = 0x14;
+ gStringVar1[2] = 0x06;
+
+ ConvertIntToDecimalStringN(gStringVar1 + 3, ewram1B000.unk264[i], 1, 2);
+
+ MenuPrint_PixelCoords(gStringVar1, (x + 6) * 8 + 12, y * 8, 0);
+ }
+}
+#elif GERMAN
+__attribute__((naked))
+void sub_8070848(u8 taskId) {
+ 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\
+ movs r0, 0xB\n\
+ movs r1, 0\n\
+ movs r2, 0x1D\n\
+ movs r3, 0x7\n\
+ bl MenuDrawTextWindow\n\
+ movs r7, 0\n\
+ ldr r0, _0807092C @ =gStringVar1\n\
+ mov r10, r0\n\
+ movs r1, 0xFC\n\
+ mov r9, r1\n\
+ movs r2, 0x13\n\
+ mov r8, r2\n\
+_0807086C:\n\
+ ldr r1, _08070930 @ =0x0201c000\n\
+ ldr r0, [r1]\n\
+ ldr r1, _08070934 @ =gUnknown_08376D1C\n\
+ adds r1, r7, r1\n\
+ ldrb r1, [r1]\n\
+ bl GetMonData\n\
+ adds r1, r7, 0x6\n\
+ lsls r1, 1\n\
+ ldr r2, _08070938 @ =0x0201b264\n\
+ adds r1, r2, r1\n\
+ strh r0, [r1]\n\
+ lsls r6, r7, 1\n\
+ adds r6, r2, r6\n\
+ ldrh r1, [r6]\n\
+ subs r0, r1\n\
+ strh r0, [r6]\n\
+ adds r0, r7, 0\n\
+ movs r1, 0x3\n\
+ bl __udivsi3\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ lsls r4, r0, 3\n\
+ adds r4, r0\n\
+ adds r4, 0xB\n\
+ lsls r4, 24\n\
+ lsrs r4, 24\n\
+ adds r0, r7, 0\n\
+ movs r1, 0x3\n\
+ bl __umodsi3\n\
+ adds r5, r0, 0\n\
+ lsls r5, 1\n\
+ adds r5, 0x1\n\
+ lsls r5, 24\n\
+ lsrs r5, 24\n\
+ ldr r1, _0807093C @ =gUnknown_08376D04\n\
+ lsls r0, r7, 2\n\
+ adds r0, r1\n\
+ ldr r1, [r0]\n\
+ mov r0, r10\n\
+ bl StringCopy\n\
+ adds r2, r0, 0\n\
+ mov r0, r9\n\
+ strb r0, [r2]\n\
+ adds r2, 0x1\n\
+ mov r1, r8\n\
+ strb r1, [r2]\n\
+ adds r2, 0x1\n\
+ movs r0, 0x2E\n\
+ strb r0, [r2]\n\
+ adds r2, 0x1\n\
+ adds r0, r2, 0\n\
+ ldr r1, _08070940 @ =gOtherText_TallPlusAndRightArrow\n\
+ bl StringCopy\n\
+ adds r2, r0, 0\n\
+ mov r0, r9\n\
+ strb r0, [r2]\n\
+ adds r2, 0x1\n\
+ mov r1, r8\n\
+ strb r1, [r2]\n\
+ adds r2, 0x1\n\
+ movs r0, 0x34\n\
+ strb r0, [r2]\n\
+ adds r2, 0x1\n\
+ movs r0, 0\n\
+ ldrsh r1, [r6, r0]\n\
+ adds r0, r2, 0\n\
+ movs r2, 0x1\n\
+ movs r3, 0x2\n\
+ bl ConvertIntToDecimalStringN\n\
+ adds r4, 0x1\n\
+ lsls r4, 24\n\
+ lsrs r4, 24\n\
+ mov r0, r10\n\
+ adds r1, r4, 0\n\
+ adds r2, r5, 0\n\
+ bl MenuPrint\n\
+ adds r0, r7, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r7, r0, 24\n\
+ cmp r7, 0x5\n\
+ bls _0807086C\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\
+ .align 2, 0\n\
+_0807092C: .4byte gStringVar1\n\
+_08070930: .4byte 0x0201c000\n\
+_08070934: .4byte gUnknown_08376D1C\n\
+_08070938: .4byte 0x0201b264\n\
+_0807093C: .4byte gUnknown_08376D04\n\
+_08070940: .4byte gOtherText_TallPlusAndRightArrow\n\
+ .syntax divided\n");
+}
+#endif
diff --git a/src/field/player_pc.c b/src/field/player_pc.c
new file mode 100644
index 000000000..83e6dd221
--- /dev/null
+++ b/src/field/player_pc.c
@@ -0,0 +1,1368 @@
+#include "global.h"
+#include "player_pc.h"
+#include "decoration.h"
+#include "field_fadetransition.h"
+#include "field_weather.h"
+#include "item.h"
+#include "item_menu.h"
+#include "items.h"
+#include "main.h"
+#include "menu.h"
+#include "menu_helpers.h"
+#include "palette.h"
+#include "script.h"
+#include "sound.h"
+#include "string_util.h"
+#include "strings.h"
+#include "task.h"
+#include "songs.h"
+#include "name_string_util.h"
+#include "mail.h"
+#include "overworld.h"
+#include "player_pc.h"
+
+extern void DisplayItemMessageOnField(u8, const u8*, TaskFunc, u16);
+extern void DoPlayerPCDecoration(u8);
+extern void BuyMenuFreeMemory(void);
+extern void DestroyVerticalScrollIndicator(u8);
+extern void PauseVerticalScrollIndicator(u8);
+extern void LoadScrollIndicatorPalette(void);
+extern void ClearMailStruct(struct MailStruct *);
+extern u8 sub_807D770(void);
+extern void sub_808B020(void);
+extern void sub_80F944C(void);
+
+static EWRAM_DATA u8 *gPcItemMenuOptionOrder = NULL;
+
+static u8 gPcItemMenuOptionsNum;
+
+extern u8 gUnknown_02038561;
+
+// event scripts
+extern u8 gBrendanHouse_TurnPCOff[];
+extern u8 gMayHouse_TurnPCOff[];
+
+extern void (*gFieldCallback)(void);
+
+static void InitPlayerPCMenu(u8 taskId);
+static void PlayerPCProcessMenuInput(u8 taskId);
+static void InitItemStorageMenu(u8);
+static void ItemStorageMenuPrint(const u8 *);
+static void ItemStorageMenuProcessInput(u8);
+static void ItemStorage_ProcessInput(u8);
+static void ItemStorage_SetItemAndMailCount(u8);
+static void ItemStorage_DoItemAction(u8);
+static void ItemStorage_GoBackToPlayerPCMenu(u8);
+static void ItemStorage_HandleQuantityRolling(u8);
+static void ItemStorage_DoItemWithdraw(u8);
+static void ItemStorage_DoItemToss(u8);
+static void ItemStorage_HandleRemoveItem(u8);
+static void ItemStorage_WaitPressHandleResumeProcessInput(u8);
+static void ItemStorage_HandleResumeProcessInput(u8);
+static void ItemStorage_DoItemSwap(u8, bool8);
+static void ItemStorage_DrawItemList(u8);
+static void ItemStorage_PrintItemPcResponse(u16);
+static void ItemStorage_DrawBothListAndDescription(u8);
+static void ItemStorage_GoBackToItemPCMenu(u8, u8);
+static void ItemStorage_LoadPalette(void);
+static u8 GetMailboxMailCount(void);
+static void Mailbox_UpdateMailList(void);
+static void Mailbox_DrawMailboxMenu(u8);
+static void Mailbox_ProcessInput(u8);
+static void Mailbox_CloseScrollIndicators(void);
+static void Mailbox_PrintWhatToDoWithPlayerMailText(u8);
+static void Mailbox_TurnOff(u8);
+static void Mailbox_PrintMailOptions(u8);
+static void Mailbox_MailOptionsProcessInput(u8);
+static void Mailbox_FadeAndReadMail(u8);
+static void Mailbox_ReturnToFieldFromReadMail(void);
+static void Mailbox_DrawYesNoBeforeMove(u8);
+static void Mailbox_DoGiveMailPokeMenu(u8);
+static void Mailbox_NoPokemonForMail(u8);
+static void Mailbox_Cancel(u8);
+static void Mailbox_DrawMailMenuAndDoProcessInput(u8);
+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 ItemStorage_Withdraw(u8);
+static void ItemStorage_Deposit(u8);
+static void ItemStorage_Toss(u8);
+static void ItemStorage_Exit(u8);
+static void ItemStorage_ResumeInputFromYesToss(u8);
+static void ItemStorage_ResumeInputFromNoToss(u8);
+static void Mailbox_DoMailMoveToBag(u8);
+static void Mailbox_ReturnToInputAfterNo(u8);
+static void Mailbox_DoMailRead(u8);
+static void Mailbox_MoveToBag(u8);
+static void Mailbox_Give(u8);
+static void Mailbox_Cancel(u8);
+
+static const u8 *const gPCText_OptionDescList[] =
+{
+ PCText_TakeOutItems,
+ PCText_StoreItems,
+ PCText_ThrowAwayItems,
+ gMenuText_GoBackToPrev
+};
+
+static const struct MenuAction2 sPlayerPCMenuActions[] =
+{
+ { SecretBaseText_ItemStorage, PlayerPC_ItemStorage },
+ { gPCText_Mailbox, PlayerPC_Mailbox },
+ { SecretBaseText_Decoration, PlayerPC_Decoration },
+ { SecretBaseText_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 MenuAction2 gPCText_ItemPCOptionsText[] =
+{
+ { PCText_WithdrawItem, ItemStorage_Withdraw },
+ { PCText_DepositItem, ItemStorage_Deposit },
+ { PCText_TossItem, ItemStorage_Toss },
+ { gUnknownText_Exit, ItemStorage_Exit }
+};
+
+static const struct YesNoFuncTable ResumeFromTossYesNoFuncList[] = // ResumeFromTossYesNoFuncList
+{
+ ItemStorage_ResumeInputFromYesToss,
+ ItemStorage_ResumeInputFromNoToss
+};
+
+static const struct YesNoFuncTable ResumeFromWithdrawYesNoFuncList[] = // ResumeFromWithdrawYesNoFuncList
+{
+ Mailbox_DoMailMoveToBag,
+ Mailbox_ReturnToInputAfterNo
+};
+
+// the use of this struct is meant to be an ItemSlot struct, but NewGameInitPCItems refuses to match without a weird pointer access.
+static const struct ItemSlot gNewGamePCItems[] =
+{
+ { ITEM_POTION, 1 },
+ { ITEM_NONE, 0 }
+};
+
+static const struct MenuAction2 gMailboxMailOptions[] =
+{
+ { OtherText_Read, Mailbox_DoMailRead },
+ { gOtherText_MoveToBag, Mailbox_MoveToBag },
+ { OtherText_Give, Mailbox_Give },
+ { gOtherText_CancelNoTerminator, Mailbox_Cancel }
+};
+
+static const u8 gNonSelectedItemFormattedText[] = _("{STR_VAR_1}{CLEAR_TO 80}");
+static const u8 gSelectedItemFormattedText[] = _("{COLOR RED}{STR_VAR_1}{CLEAR_TO 80}");
+static const u8 gNonSelectedItemQuantityFormatText[] = _("{STR_VAR_1}");
+static const u8 gSelectedItemQuantityFormatText[] = _("{COLOR RED}{STR_VAR_1}");
+static const u8 gUnknown_08406330[] = _("{CLEAR_TO 32}");
+
+static const u16 gUnknown_08406334[3] =
+{
+ 0x5294,
+ 0x6B5A,
+ 0x7FFF
+};
+
+static const u8 gHighlightedMoveToBagFormatText[] = _("{COLOR RED}{STR_VAR_1}");
+
+extern u8 *gUnknown_02039314;
+extern struct MenuAction gUnknown_08406298[];
+
+extern u8 gUnknown_084062B8[];
+extern u8 gUnknown_084062BC[];
+extern u8 gUnknown_0840632A[];
+extern u8 gUnknown_08406327[];
+extern u8 gUnknown_0840631E[];
+extern u8 gUnknown_08406318[];
+
+extern u8 gUnknown_030007B4;
+extern u8 unk_201FE00[];
+
+extern u8 gUnknown_08152850;
+extern u8 gUnknown_08152C75;
+
+extern u32 gUnknown_08406288[];
+extern const struct MenuAction gUnknown_084062C0[];
+extern const struct YesNoFuncTable gUnknown_084062E0;
+
+void NewGameInitPCItems(void)
+{
+ u8 i;
+
+ // because Game Freak don't know how to use a struct or a 2d array
+ for(i = 0, ClearItemSlots(gSaveBlock1.pcItems, ARRAY_COUNT(gSaveBlock1.pcItems)); NEW_GAME_PC_ITEMS(i, ITEM_ID) && NEW_GAME_PC_ITEMS(i, QUANTITY) &&
+ AddPCItem(NEW_GAME_PC_ITEMS(i, ITEM_ID), NEW_GAME_PC_ITEMS(i, QUANTITY)) == TRUE; i++)
+ ;
+}
+
+void BedroomPC(void)
+{
+ gPcItemMenuOptionOrder = (u8 *)gBedroomPC_OptionOrder;
+ gPcItemMenuOptionsNum = 4;
+ DisplayItemMessageOnField(CreateTask(TaskDummy, 0), gOtherText_WhatWillYouDo, InitPlayerPCMenu, 0);
+}
+
+void PlayerPC(void)
+{
+ gPcItemMenuOptionOrder = (u8 *)gPlayerPC_OptionOrder;
+ gPcItemMenuOptionsNum = 3;
+ DisplayItemMessageOnField(CreateTask(TaskDummy, 0), gOtherText_WhatWillYouDo, InitPlayerPCMenu, 0);
+}
+
+static void InitPlayerPCMenu(u8 taskId)
+{
+ MenuDrawTextWindow(0, 0, 10, gPcItemMenuOptionsNum * 2 + 1);
+ PrintMenuItemsReordered(1, 1, gPcItemMenuOptionsNum, sPlayerPCMenuActions, gPcItemMenuOptionOrder);
+ InitMenu(0, 1, 1, gPcItemMenuOptionsNum, 0, 9);
+ TASK.FUNC = PlayerPCProcessMenuInput;
+}
+
+static void PlayerPCProcessMenuInput(u8 taskId)
+{
+ if (gMain.newAndRepeatedKeys & DPAD_UP)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor(-1);
+ }
+ else if (gMain.newAndRepeatedKeys & DPAD_DOWN)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor(1);
+ }
+ else if (gMain.newKeys & A_BUTTON)
+ {
+ HandleDestroyMenuCursors();
+ PlaySE(SE_SELECT);
+ sPlayerPCMenuActions[gPcItemMenuOptionOrder[GetMenuCursorPos()]].func(taskId);
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ HandleDestroyMenuCursors();
+ PlaySE(SE_SELECT);
+ sPlayerPCMenuActions[gPcItemMenuOptionsNum[gPcItemMenuOptionOrder - 1]].func(taskId); // run EXIT.
+ }
+}
+
+void ReshowPlayerPC(u8 var)
+{
+ DisplayItemMessageOnField(var, gOtherText_WhatWillYouDo, InitPlayerPCMenu, 0);
+}
+
+static void PlayerPC_ItemStorage(u8 taskId)
+{
+ InitItemStorageMenu(ITEMPC_MENU_WITHDRAW);
+ TASK.FUNC = ItemStorageMenuProcessInput;
+}
+
+static void PlayerPC_Mailbox(u8 taskId)
+{
+ MenuZeroFillWindowRect(0, 0, 10, 9);
+ gMailboxInfo.count = GetMailboxMailCount();
+
+ if (gMailboxInfo.count == 0)
+ DisplayItemMessageOnField(taskId, gOtherText_NoMailHere, ReshowPlayerPC, 0);
+ else
+ {
+ gMailboxInfo.cursorPos = 0;
+ gMailboxInfo.itemsAbove = 0;
+ Mailbox_UpdateMailList();
+ ItemStorage_SetItemAndMailCount(taskId);
+ Mailbox_DrawMailboxMenu(taskId);
+ TASK.FUNC = Mailbox_ProcessInput;
+ }
+}
+
+static void PlayerPC_Decoration(u8 var)
+{
+ MenuZeroFillWindowRect(0, 0, 10, 9);
+ 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.
+ {
+ MenuZeroFillWindowRect(0, 0, 0x1D, 0x13);
+
+ if (gSaveBlock2.playerGender == MALE)
+ ScriptContext1_SetupScript(gBrendanHouse_TurnPCOff);
+ else
+ ScriptContext1_SetupScript(gMayHouse_TurnPCOff);
+ }
+ else
+ {
+ MenuZeroFillWindowRect(0, 0, 10, 9);
+ EnableBothScriptContexts();
+ }
+ DestroyTask(taskId);
+}
+
+static void InitItemStorageMenu(u8 var)
+{
+ MenuZeroFillWindowRect(0, 0, 10, 9);
+ MenuDrawTextWindow(0, 0, 11, 9);
+ PrintMenuItems(1, 1, 4, (struct MenuAction *)gPCText_ItemPCOptionsText);
+ InitMenu(0, 1, 1, 4, var, 10);
+ ItemStorageMenuPrint(gPCText_OptionDescList[var]);
+}
+
+static void ItemStorageMenuPrint(const u8 *textPtr)
+{
+ MenuFillWindowRectWithBlankTile(2, 15, 27, 18);
+ MenuPrint(textPtr, 2, 15);
+}
+
+static void ItemStorageMenuProcessInput(u8 var)
+{
+ if (gMain.newAndRepeatedKeys & DPAD_UP)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor(-1);
+ ItemStorageMenuPrint(gPCText_OptionDescList[GetMenuCursorPos()]);
+ }
+ else if (gMain.newAndRepeatedKeys & DPAD_DOWN)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor(1);
+ ItemStorageMenuPrint(gPCText_OptionDescList[GetMenuCursorPos()]);
+ }
+ else if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ gPCText_ItemPCOptionsText[GetMenuCursorPos()].func(var);
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ HandleDestroyMenuCursors();
+ PlaySE(SE_SELECT);
+ gPCText_ItemPCOptionsText[ITEMPC_MENU_EXIT].func(var);
+ }
+}
+
+static void Task_ItemStorage_Deposit(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ sub_80A6A30();
+ DestroyTask(taskId);
+ }
+}
+
+static void ItemStorage_Deposit(u8 taskId)
+{
+ TASK.FUNC = Task_ItemStorage_Deposit;
+ fade_screen(1, 0);
+}
+
+static void ItemStorage_HandleReturnToProcessInput(u8 taskId)
+{
+ if (sub_807D770() == TRUE)
+ TASK.FUNC = ItemStorageMenuProcessInput;
+}
+
+void ItemStorage_ReturnToMenuAfterDeposit(void)
+{
+ MenuDisplayMessageBox();
+ InitItemStorageMenu(ITEMPC_MENU_DEPOSIT);
+ CreateTask(ItemStorage_HandleReturnToProcessInput, 0);
+ pal_fill_black();
+}
+
+static void ItemStorage_Withdraw(u8 taskId)
+{
+ s16 *data = TASK.data;
+
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(0, 0, 11, 9);
+ NUM_ITEMS = CountUsedPCItemSlots();
+
+ if (NUM_ITEMS != 0)
+ {
+ MenuZeroFillWindowRect(0, 14, 29, 19);
+ CURRENT_ITEM_STORAGE_MENU = ITEMPC_MENU_WITHDRAW;
+ PAGE_INDEX = 0;
+ ITEMS_ABOVE_TOP = 0;
+ ItemStorage_SetItemAndMailCount(taskId);
+ ItemStorage_GoBackToItemPCMenu(taskId, 0);
+ TASK.FUNC = ItemStorage_ProcessInput;
+ }
+ else
+ DisplayItemMessageOnField(taskId, gOtherText_NoItems, PlayerPC_ItemStorage, 0);
+}
+
+static void ItemStorage_Toss(u8 taskId)
+{
+ s16 *data = TASK.data;
+
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(0, 0, 11, 9);
+ NUM_ITEMS = CountUsedPCItemSlots();
+
+ if (NUM_ITEMS)
+ {
+ MenuZeroFillWindowRect(0, 14, 29, 19);
+ CURRENT_ITEM_STORAGE_MENU = ITEMPC_MENU_TOSS;
+ PAGE_INDEX = 0;
+ ITEMS_ABOVE_TOP = 0;
+ ItemStorage_SetItemAndMailCount(taskId);
+ ItemStorage_GoBackToItemPCMenu(taskId, 2);
+ TASK.FUNC = ItemStorage_ProcessInput;
+ }
+ else
+ DisplayItemMessageOnField(taskId, gOtherText_NoItems, PlayerPC_ItemStorage, 0);
+}
+
+static void ItemStorage_Exit(u8 var)
+{
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(0, 0, 11, 9);
+ ReshowPlayerPC(var);
+}
+
+static void ItemStorage_SetItemAndMailCount(u8 taskId)
+{
+ s16 *data = TASK.data;
+
+ if (NUM_ITEMS > 7) // we have a full page, so set the num of page items appropriately.
+ NUM_PAGE_ITEMS = 8;
+ else
+ NUM_PAGE_ITEMS = NUM_ITEMS + 1; // there are not enough items to fill a full page; take the # of items and add 1 for the cancel button.
+
+ if (gMailboxInfo.count > 7)
+ gMailboxInfo.pageItems = 8;
+ else
+ gMailboxInfo.pageItems = gMailboxInfo.count + 1;
+}
+
+static void ItemStorage_ProcessInput(u8 taskId)
+{
+ s16 *data = TASK.data;
+ s16 trueIndex;
+
+ if (gMain.newAndRepeatedKeys & DPAD_UP)
+ {
+ if(PAGE_INDEX != 0) // did the cursor move physically upwards?
+ {
+ PlaySE(SE_SELECT);
+ PAGE_INDEX = MoveMenuCursor(-1);
+ trueIndex = ITEMS_ABOVE_TOP + PAGE_INDEX;
+ if (SWITCH_MODE_ACTIVE == FALSE) // are we not currently switching items?
+ {
+ if (trueIndex == NUM_ITEMS) // if the cursor is on top of cancel, print the go back to prev description.
+ {
+ ItemStorage_PrintItemPcResponse(ITEMPC_GO_BACK_TO_PREV);
+ }
+ else
+ {
+ ItemStorage_PrintItemPcResponse(gSaveBlock1.pcItems[trueIndex].itemId);
+ }
+ }
+ }
+ else // the page cursor is at the top. but we may not be at the top of the true index list, so do another check.
+ {
+ if (ITEMS_ABOVE_TOP == 0) // did the cursor not move due to being at the top of the list?
+ return;
+
+ PlaySE(SE_SELECT);
+ ITEMS_ABOVE_TOP--;
+ ItemStorage_DrawBothListAndDescription(taskId);
+
+ if (SWITCH_MODE_ACTIVE != FALSE)
+ MoveMenuCursor(0); // don't move the cursor. it's at the top of the page index, but not the true index.
+ }
+ }
+ else if(gMain.newAndRepeatedKeys & DPAD_DOWN) // _0813A306
+ {
+ if(PAGE_INDEX != NUM_PAGE_ITEMS - 1)
+ {
+ PlaySE(SE_SELECT);
+ PAGE_INDEX = MoveMenuCursor(1);
+ trueIndex = ITEMS_ABOVE_TOP + PAGE_INDEX;
+
+ if(SWITCH_MODE_ACTIVE != FALSE)
+ return;
+
+ if (trueIndex == NUM_ITEMS)
+ ItemStorage_PrintItemPcResponse(ITEMPC_GO_BACK_TO_PREV); // probably further down
+ else
+ ItemStorage_PrintItemPcResponse(gSaveBlock1.pcItems[trueIndex].itemId);
+ }
+ else if(ITEMS_ABOVE_TOP + PAGE_INDEX != NUM_ITEMS)
+ {
+ PlaySE(SE_SELECT);
+ ITEMS_ABOVE_TOP++;
+ ItemStorage_DrawBothListAndDescription(taskId);
+
+ if (SWITCH_MODE_ACTIVE != FALSE)
+ MoveMenuCursor(0);
+ }
+ }
+ else if(gMain.newKeys & SELECT_BUTTON) // _0813A3A0
+ {
+ if (SWITCH_MODE_ACTIVE == FALSE)
+ {
+ if (PAGE_INDEX + ITEMS_ABOVE_TOP != NUM_ITEMS) // you cannot swap the Cancel button.
+ {
+ PlaySE(SE_SELECT);
+ SWITCH_MODE_ACTIVE = TRUE;
+ SWAP_ITEM_INDEX = ITEMS_ABOVE_TOP + PAGE_INDEX;
+ ItemStorage_PrintItemPcResponse(ITEMPC_SWITCH_WHICH_ITEM);
+ }
+ // _0813A3DC
+ ItemStorage_DrawItemList(taskId);
+ }
+ else // _0813A3E8
+ {
+ PlaySE(SE_SELECT);
+ ItemStorage_DoItemSwap(taskId, FALSE);
+ ItemStorage_DrawBothListAndDescription(taskId);
+ }
+ }
+ else if(gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ if(SWITCH_MODE_ACTIVE == FALSE)
+ {
+ if(ITEMS_ABOVE_TOP + PAGE_INDEX != NUM_ITEMS)
+ {
+ ItemStorage_DoItemAction(taskId);
+ }
+ else
+ {
+ ItemStorage_GoBackToPlayerPCMenu(taskId);
+ }
+ }
+ else
+ {
+ ItemStorage_DoItemSwap(taskId, FALSE);
+ ItemStorage_DrawBothListAndDescription(taskId);
+ }
+ }
+ else if(gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ if(SWITCH_MODE_ACTIVE == FALSE)
+ {
+ HandleDestroyMenuCursors();
+ ItemStorage_GoBackToPlayerPCMenu(taskId);
+ }
+ else
+ {
+ ItemStorage_DoItemSwap(taskId, TRUE);
+ ItemStorage_DrawBothListAndDescription(taskId);
+ }
+ }
+}
+
+static void ItemStorage_GoBackToPlayerPCMenu(u8 taskId)
+{
+ BuyMenuFreeMemory();
+ DestroyVerticalScrollIndicator(0);
+ DestroyVerticalScrollIndicator(1);
+ MenuZeroFillWindowRect(0, 0, 29, 19);
+ MenuDisplayMessageBox();
+ InitItemStorageMenu(TASK.CURRENT_ITEM_STORAGE_MENU);
+ TASK.FUNC = ItemStorageMenuProcessInput;
+}
+
+static void ItemStorage_DoItemAction(u8 taskId)
+{
+ s16 *data = TASK.data;
+ u8 trueIndex = PAGE_INDEX + ITEMS_ABOVE_TOP;
+
+ PauseVerticalScrollIndicator(0);
+ PauseVerticalScrollIndicator(1); // PauseVerticalScrollIndicator
+
+ if(CURRENT_ITEM_STORAGE_MENU == ITEMPC_MENU_WITHDRAW)
+ {
+ if(gSaveBlock1.pcItems[trueIndex].quantity == 1)
+ {
+ NUM_QUANTITY_ROLLER = 1;
+ ItemStorage_DoItemWithdraw(taskId);
+ return;
+ }
+ else // _0813A50C
+ {
+ ItemStorage_PrintItemPcResponse(ITEMPC_HOW_MANY_TO_WITHDRAW);
+ }
+ }
+ else if(gSaveBlock1.pcItems[trueIndex].quantity == 1) // _0813A518
+ {
+ NUM_QUANTITY_ROLLER = 1;
+ ItemStorage_DoItemToss(taskId);
+ return;
+ }
+ else
+ {
+ ItemStorage_PrintItemPcResponse(ITEMPC_HOW_MANY_TO_TOSS);
+ }
+ NUM_QUANTITY_ROLLER = 1;
+ MenuDrawTextWindow(6, 8, 13, 11);
+ sub_80A418C(NUM_QUANTITY_ROLLER, STR_CONV_MODE_RIGHT_ALIGN, 8, 9, 3);
+ TASK.FUNC = ItemStorage_HandleQuantityRolling;
+}
+
+static void ItemStorage_HandleQuantityRolling(u8 taskId)
+{
+ s16 *data = TASK.data;
+ u8 trueIndex = PAGE_INDEX + ITEMS_ABOVE_TOP;
+
+ if(gMain.newAndRepeatedKeys & DPAD_UP)
+ {
+ if(NUM_QUANTITY_ROLLER != gSaveBlock1.pcItems[trueIndex].quantity)
+ NUM_QUANTITY_ROLLER++;
+ else
+ NUM_QUANTITY_ROLLER = 1; // you are at the max amount of items you have when you press Up, set your quantity back to 1.
+
+ sub_80A418C(NUM_QUANTITY_ROLLER, STR_CONV_MODE_RIGHT_ALIGN, 8, 9, 3); // print quantity?
+ }
+ else if(gMain.newAndRepeatedKeys & DPAD_DOWN)
+ {
+ if(NUM_QUANTITY_ROLLER != 1)
+ NUM_QUANTITY_ROLLER--;
+ else
+ NUM_QUANTITY_ROLLER = gSaveBlock1.pcItems[trueIndex].quantity; // you are at 0 when you press down, set your quantity to the amount you have.
+
+ sub_80A418C(NUM_QUANTITY_ROLLER, STR_CONV_MODE_RIGHT_ALIGN, 8, 9, 3); // print quantity?
+ }
+ else if(gMain.newAndRepeatedKeys & DPAD_LEFT) // reduce by 10.
+ {
+ NUM_QUANTITY_ROLLER -= 10;
+
+ if(NUM_QUANTITY_ROLLER <= 0)
+ NUM_QUANTITY_ROLLER = 1; // dont underflow or allow 0!
+
+ sub_80A418C(NUM_QUANTITY_ROLLER, STR_CONV_MODE_RIGHT_ALIGN, 8, 9, 3); // print quantity?
+ }
+ else if(gMain.newAndRepeatedKeys & DPAD_RIGHT) // add 10.
+ {
+ NUM_QUANTITY_ROLLER += 10;
+
+ if(NUM_QUANTITY_ROLLER > gSaveBlock1.pcItems[trueIndex].quantity)
+ NUM_QUANTITY_ROLLER = gSaveBlock1.pcItems[trueIndex].quantity; // dont overflow!
+
+ sub_80A418C(NUM_QUANTITY_ROLLER, STR_CONV_MODE_RIGHT_ALIGN, 8, 9, 3); // print quantity?
+ }
+ else if(gMain.newKeys & A_BUTTON) // confirm quantity.
+ {
+ PlaySE(SE_SELECT);
+ MenuZeroFillWindowRect(6, 6, 0xD, 0xB);
+
+ if(CURRENT_ITEM_STORAGE_MENU == ITEMPC_MENU_WITHDRAW)
+ ItemStorage_DoItemWithdraw(taskId);
+ else
+ ItemStorage_DoItemToss(taskId);
+ }
+ else if(gMain.newKeys & B_BUTTON) // cancel quantity.
+ {
+ PlaySE(SE_SELECT);
+ MenuZeroFillWindowRect(6, 6, 0xD, 0xB);
+ StartVerticalScrollIndicators(0);
+ StartVerticalScrollIndicators(1);
+ ItemStorage_PrintItemPcResponse(gSaveBlock1.pcItems[ITEMS_ABOVE_TOP + PAGE_INDEX].itemId); // why not use trueIndex?
+ TASK.FUNC = ItemStorage_ProcessInput;
+ }
+}
+
+static void ItemStorage_DoItemWithdraw(u8 taskId)
+{
+ s16 *data = TASK.data;
+ u8 trueIndex = PAGE_INDEX + ITEMS_ABOVE_TOP;
+
+ if(AddBagItem(gSaveBlock1.pcItems[trueIndex].itemId, NUM_QUANTITY_ROLLER) == TRUE) // add item works.
+ {
+ CopyItemName(gSaveBlock1.pcItems[trueIndex].itemId, gStringVar1);
+ ConvertIntToDecimalStringN(gStringVar2, NUM_QUANTITY_ROLLER, 0, 3);
+ ItemStorage_PrintItemPcResponse(ITEMPC_WITHDREW_THING);
+ TASK.FUNC = ItemStorage_HandleRemoveItem;
+ }
+ else
+ {
+ NUM_QUANTITY_ROLLER = 0;
+ ItemStorage_PrintItemPcResponse(ITEMPC_NO_MORE_ROOM);
+ TASK.FUNC = ItemStorage_WaitPressHandleResumeProcessInput;
+ }
+}
+
+static void ItemStorage_DoItemToss(u8 taskId)
+{
+ s16 *data = TASK.data;
+ u8 var = PAGE_INDEX + ITEMS_ABOVE_TOP;
+
+ if(ItemId_GetImportance(gSaveBlock1.pcItems[var].itemId) == FALSE)
+ {
+ CopyItemName(gSaveBlock1.pcItems[var].itemId, gStringVar1);
+ ConvertIntToDecimalStringN(gStringVar2, NUM_QUANTITY_ROLLER, 0, 3);
+ ItemStorage_PrintItemPcResponse(ITEMPC_OKAY_TO_THROW_AWAY);
+ DisplayYesNoMenu(7, 6, 1);
+ DoYesNoFuncWithChoice(taskId, (struct YesNoFuncTable *)&ResumeFromTossYesNoFuncList);
+ }
+ else
+ {
+ NUM_QUANTITY_ROLLER = 0;
+ ItemStorage_PrintItemPcResponse(ITEMPC_TOO_IMPORTANT);
+ TASK.FUNC = ItemStorage_HandleRemoveItem;
+ }
+}
+
+static void ItemStorage_ResumeInputFromYesToss(u8 taskId)
+{
+ MenuZeroFillWindowRect(0x6, 0x6, 0xD, 0xB);
+ ItemStorage_PrintItemPcResponse(ITEMPC_THREW_AWAY_ITEM);
+ TASK.FUNC = ItemStorage_HandleRemoveItem;
+}
+
+static void ItemStorage_ResumeInputFromNoToss(u8 taskId)
+{
+ s16 *data = TASK.data;
+
+ MenuZeroFillWindowRect(0x6, 0x6, 0xD, 0xB);
+ InitMenu(0, 16, 2, NUM_PAGE_ITEMS, PAGE_INDEX, 0xD);
+ StartVerticalScrollIndicators(0);
+ StartVerticalScrollIndicators(1);
+ ItemStorage_PrintItemPcResponse(gSaveBlock1.pcItems[ITEMS_ABOVE_TOP + PAGE_INDEX].itemId);
+ TASK.FUNC = ItemStorage_ProcessInput;
+}
+
+static void ItemStorage_HandleRemoveItem(u8 taskId)
+{
+ s16 *data = TASK.data;
+ s16 oldNumItems;
+
+ if(gMain.newKeys & A_BUTTON || gMain.newKeys == B_BUTTON)
+ {
+ RemovePCItem(PAGE_INDEX + ITEMS_ABOVE_TOP, NUM_QUANTITY_ROLLER);
+ oldNumItems = NUM_ITEMS;
+ NUM_ITEMS = CountUsedPCItemSlots();
+
+ if(oldNumItems != NUM_ITEMS && oldNumItems < NUM_PAGE_ITEMS + ITEMS_ABOVE_TOP && ITEMS_ABOVE_TOP != 0)
+ ITEMS_ABOVE_TOP--;
+
+ ItemStorage_SetItemAndMailCount(taskId);
+ ItemStorage_HandleResumeProcessInput(taskId);
+ InitMenu(0, 16, 2, NUM_PAGE_ITEMS, PAGE_INDEX, 0xD);
+ }
+}
+
+static void ItemStorage_WaitPressHandleResumeProcessInput(u8 taskId)
+{
+ s16 *data = TASK.data;
+
+ if(gMain.newKeys & A_BUTTON || gMain.newKeys == B_BUTTON)
+ {
+ ItemStorage_PrintItemPcResponse(gSaveBlock1.pcItems[ITEMS_ABOVE_TOP + PAGE_INDEX].itemId);
+ StartVerticalScrollIndicators(0);
+ StartVerticalScrollIndicators(1);
+ TASK.FUNC = ItemStorage_ProcessInput;
+ }
+}
+
+static void ItemStorage_HandleResumeProcessInput(u8 taskId)
+{
+ MenuZeroFillWindowRect(0x6, 0x6, 0xD, 0xB);
+ StartVerticalScrollIndicators(0);
+ StartVerticalScrollIndicators(1);
+ ItemStorage_DrawBothListAndDescription(taskId);
+ TASK.FUNC = ItemStorage_ProcessInput;
+}
+
+static void ItemStorage_DoItemSwap(u8 taskId, bool8 switchModeDisabled)
+{
+ s16 *data = TASK.data;
+ u8 trueIndex = ITEMS_ABOVE_TOP + PAGE_INDEX;
+
+ SWITCH_MODE_ACTIVE = FALSE;
+
+ if((u8)NUM_ITEMS > trueIndex && (u8)SWAP_ITEM_INDEX != trueIndex && switchModeDisabled == FALSE)
+ {
+ struct ItemSlot itemSlot = gSaveBlock1.pcItems[SWAP_ITEM_INDEX]; // backup the itemSlot before swapping the two.
+
+ gSaveBlock1.pcItems[SWAP_ITEM_INDEX] = gSaveBlock1.pcItems[trueIndex];
+ gSaveBlock1.pcItems[trueIndex] = itemSlot;
+ return;
+ }
+ else if(trueIndex == NUM_ITEMS)
+ {
+ ItemStorage_PrintItemPcResponse(ITEMPC_GO_BACK_TO_PREV);
+ }
+ else
+ {
+ ItemStorage_PrintItemPcResponse(gSaveBlock1.pcItems[trueIndex].itemId);
+ }
+
+ /*
+ THEORY: This check produces essentially dead code, but it might have been working in an earlier build
+ in which case it allows a programmer to easily duplicate items without the use of a debug menu.
+ This gets the page index of the swap index for some reason. It is currently unknown what it would have been used
+ for, but perhaps it was used to increase the quantity of the item without a debug menu.
+ With the removal of a lot of the debug menus close to release, a programmer may have added this to
+ help test things with a low key (such as planting a lot of duplicated berries, which requires this lazy "cheat")
+ without bringing the relevent debug menus back. The commented out line is intentionally left in below to show
+ what it may have looked like.
+ */
+ if(SWAP_ITEM_INDEX - ITEMS_ABOVE_TOP <= 0) { // this check is arbitrary and used to generate the correct assembly using the subtraction, which is what matters. the 0 check doesn't.
+ //gSaveBlock1.pcItems[SWAP_ITEM_INDEX].quantity += 100;
+ gSaveBlock1.pcItems[SWAP_ITEM_INDEX].quantity += 0; // do not enforce item cap.
+ }
+}
+
+static void ItemStorage_DrawItemQuantity(u16 arg1, enum StringConvertMode arg2, u8 arg3, u8 arg4, int isSwapSelected)
+{
+ sub_80A4164(gStringVar1, arg1, arg2, arg4);
+
+ if(isSwapSelected != FALSE)
+ MenuPrint(gSelectedItemQuantityFormatText, 0x1A, arg3);
+ else
+ MenuPrint(gNonSelectedItemQuantityFormatText, 0x1A, arg3);
+}
+
+static void ItemStorage_DrawItemVoidQuantity(u8 var)
+{
+ MenuPrint(gUnknown_08406330, 0x19, var);
+}
+
+static void ItemStorage_DrawItemName(struct ItemSlot *itemSlot, u8 var, int isSwapSelected)
+{
+ CopyItemName(itemSlot->itemId, gStringVar1);
+
+ if(isSwapSelected != FALSE)
+ MenuPrint(gSelectedItemFormattedText, 16, var);
+ else
+ MenuPrint(gNonSelectedItemFormattedText, 16, var);
+}
+
+static void ItemStorage_DrawNormalItemEntry(struct ItemSlot *itemSlot, u8 var, int var2)
+{
+ ItemStorage_DrawItemName(itemSlot, var, var2);
+ ItemStorage_DrawItemQuantity(itemSlot->quantity, STR_CONV_MODE_RIGHT_ALIGN, var, 3, var2);
+}
+
+static void ItemStorage_DrawKeyItemEntry(struct ItemSlot *itemSlot, u8 var, int var2)
+{
+ ItemStorage_DrawItemName(itemSlot, var, var2);
+ ItemStorage_DrawItemVoidQuantity(var);
+}
+
+static void ItemStorage_DrawTMHMEntry(struct ItemSlot *itemSlot, u8 var, int var2)
+{
+ ItemStorage_DrawItemName(itemSlot, var, var2);
+
+ if(itemSlot->itemId < ITEM_HM01)
+ ItemStorage_DrawItemQuantity(itemSlot->quantity, STR_CONV_MODE_RIGHT_ALIGN, var, 3, var2);
+ else
+ ItemStorage_DrawItemVoidQuantity(var); // HMs do not have a quantity.
+}
+
+static void ItemStorage_DrawItemList(u8 taskId)
+{
+ s16 *data = TASK.data;
+ int tempArg;
+ u16 i;
+ u16 yCoord = 0;
+
+ // r5 is i and is unsigned 16-bit.
+
+ for(i = ITEMS_ABOVE_TOP; i < ITEMS_ABOVE_TOP + NUM_PAGE_ITEMS; i++)
+ {
+ yCoord = (i - ITEMS_ABOVE_TOP) * 2;
+
+ if(i != NUM_ITEMS)
+ {
+ tempArg = 0;
+
+ if(SWITCH_MODE_ACTIVE != FALSE && i == SWAP_ITEM_INDEX)
+ tempArg = 1;
+
+ switch(GetPocketByItemId(gSaveBlock1.pcItems[i].itemId) - 1)
+ {
+ case 0:
+ case 1:
+ case 3:
+ ItemStorage_DrawNormalItemEntry((struct ItemSlot *)&gSaveBlock1.pcItems[i], yCoord + 2, tempArg);
+ break;
+ case 4:
+ ItemStorage_DrawKeyItemEntry((struct ItemSlot *)&gSaveBlock1.pcItems[i], yCoord + 2, tempArg);
+ break;
+ case 2:
+ ItemStorage_DrawTMHMEntry((struct ItemSlot *)&gSaveBlock1.pcItems[i], yCoord + 2, tempArg);
+ break;
+ }
+ }
+ else
+ {
+ goto weirdCase; // what???
+ }
+ }
+
+beforeLabel:
+ if(i - ITEMS_ABOVE_TOP < 8)
+ MenuFillWindowRectWithBlankTile(16, yCoord + 4, 0x1C, 0x12);
+
+ switch(ITEMS_ABOVE_TOP)
+ {
+ default:
+ CreateVerticalScrollIndicators(0, 0xB8, 8);
+ break;
+weirdCase:
+ sub_8072A18(gOtherText_CancelNoTerminator, 0x80, (yCoord + 2) * 8, 0x68, 1);
+ goto beforeLabel;
+ case 0:
+ DestroyVerticalScrollIndicator(0);
+ break;
+ }
+
+ if(ITEMS_ABOVE_TOP + NUM_PAGE_ITEMS <= NUM_ITEMS)
+ CreateVerticalScrollIndicators(1, 0xB8, 0x98);
+ else
+ DestroyVerticalScrollIndicator(1);
+}
+
+static void ItemStorage_PrintItemPcResponse(u16 itemId)
+{
+ const u8 *string;
+
+ switch(itemId)
+ {
+ case ITEMPC_GO_BACK_TO_PREV:
+ string = gMenuText_GoBackToPrev;
+ break;
+ case ITEMPC_HOW_MANY_TO_WITHDRAW:
+ string = gOtherText_HowManyToWithdraw;
+ break;
+ case ITEMPC_WITHDREW_THING:
+ string = gOtherText_WithdrewThing;
+ break;
+ case ITEMPC_HOW_MANY_TO_TOSS:
+ string = gOtherText_HowManyToToss;
+ break;
+ case ITEMPC_THREW_AWAY_ITEM:
+ string = gOtherText_ThrewAwayItem;
+ break;
+ case ITEMPC_NO_MORE_ROOM:
+ string = gOtherText_NoMoreRoom;
+ break;
+ case ITEMPC_TOO_IMPORTANT:
+ string = gOtherText_TooImportant;
+ break;
+ case ITEMPC_OKAY_TO_THROW_AWAY:
+ string = gOtherText_OkayToThrowAwayPrompt;
+ break;
+ case ITEMPC_SWITCH_WHICH_ITEM:
+ string = gOtherText_SwitchWhichItem;
+ break;
+ default:
+ string = ItemId_GetDescription(itemId);
+ break;
+ }
+
+ sub_8072AB0(string, 8, 0x68, 0x68, 0x30, 1);
+}
+
+static void ItemStorage_DrawBothListAndDescription(u8 taskId)
+{
+ s16 *data = TASK.data;
+ s16 trueIndex = ITEMS_ABOVE_TOP + PAGE_INDEX;
+
+ ItemStorage_DrawItemList(taskId);
+
+ if(SWITCH_MODE_ACTIVE == FALSE)
+ {
+ if(trueIndex == NUM_ITEMS)
+ ItemStorage_PrintItemPcResponse(ITEMPC_GO_BACK_TO_PREV);
+ else
+ ItemStorage_PrintItemPcResponse(gSaveBlock1.pcItems[trueIndex].itemId);
+ }
+}
+
+static void ItemStorage_GoBackToItemPCMenu(u8 taskId, u8 var)
+{
+ s16 *data = TASK.data;
+
+ sub_80F944C();
+ LoadScrollIndicatorPalette();
+ ItemStorage_LoadPalette();
+ MenuDrawTextWindow(0xF, 0, 0x1D, 0x13);
+ MenuDrawTextWindow(0, 0xC, 0xE, 0x13);
+ MenuDrawTextWindow(0, 0, 0xB, 3);
+ ItemStorage_PrintItemPcResponse(gSaveBlock1.pcItems[0].itemId);
+ MenuPrint(gPCText_ItemPCOptionsText[var].text, 1, 1);
+ ItemStorage_DrawItemList(taskId);
+ InitMenu(0, 0x10, 2, NUM_PAGE_ITEMS, PAGE_INDEX, 0xD);
+}
+
+static void ItemStorage_LoadPalette(void)
+{
+ u16 arr[3];
+
+ memcpy(arr, gUnknown_08406334, sizeof(arr));
+ LoadPalette(&arr[2], 0xDF, 2);
+ LoadPalette(&arr[1], 0xD1, 2);
+ LoadPalette(&arr[0], 0xD8, 2);
+}
+
+static u8 GetMailboxMailCount(void)
+{
+ u8 i, j;
+
+ for(i = 0, j = 6; j < 16; j++)
+ if(gSaveBlock1.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 (gSaveBlock1.mail[i].itemId == 0)
+ {
+ mailBuffer = gSaveBlock1.mail[i];
+ gSaveBlock1.mail[i] = gSaveBlock1.mail[j];
+ gSaveBlock1.mail[j] = mailBuffer;
+ }
+ }
+ }
+}
+
+// WWHHHHHYYYYYYYY SOMEBODY PLEASE FIX THIS
+static void Mailbox_DrawMailList(u8 taskId) // taskId is unused
+{
+ u16 yCoord = 0;
+ u16 i = gMailboxInfo.itemsAbove;
+ register struct MailboxStruct *tempMailbox asm("r1") = &gMailboxInfo;
+ register struct MailboxStruct *mailbox asm("r6");
+
+ if(i < i + tempMailbox->pageItems)
+ {
+ mailbox = tempMailbox;
+ goto forJump;
+ for(; i < mailbox->itemsAbove + mailbox->pageItems; i++)
+ {
+ forJump:
+ yCoord = (i - mailbox->itemsAbove) * 2;
+ MenuFillWindowRectWithBlankTile(0x15, yCoord + 2, 0x1C, yCoord + 3);
+
+ if(i != mailbox->count)
+ {
+ StringCopy(gStringVar1, (u8 *)gSaveBlock1.mail[i + 6].playerName);
+ SanitizeNameString(gStringVar1);
+ MenuPrint(gStringVar1, 0x15, yCoord + 2);
+ }
+ else
+ {
+ goto weirdCase; // again, what???
+ }
+ }
+ }
+
+beforeLabel:
+ if(i - gMailboxInfo.itemsAbove != 8)
+ MenuFillWindowRectWithBlankTile(0x15, yCoord + 4, 0x1C, 0x12);
+
+ switch(gMailboxInfo.itemsAbove)
+ {
+ default:
+ CreateVerticalScrollIndicators(0, 0xC8, 8);
+ break;
+weirdCase:
+ MenuPrint(gOtherText_CancelNoTerminator, 0x15, yCoord + 2);
+ goto beforeLabel;
+ case 0:
+ DestroyVerticalScrollIndicator(0);
+ break;
+ }
+
+ if(gMailboxInfo.itemsAbove + gMailboxInfo.pageItems <= gMailboxInfo.count)
+ CreateVerticalScrollIndicators(1, 0xC8, 0x98);
+ else
+ DestroyVerticalScrollIndicator(1);
+}
+
+static void Mailbox_DrawMailboxMenu(u8 taskId)
+{
+ sub_80F944C();
+ LoadScrollIndicatorPalette();
+ MenuZeroFillWindowRect(0, 0, 0x1D, 0x13);
+ MenuDrawTextWindow(0, 0, 0x8, 0x3);
+ MenuPrint(gPCText_Mailbox, 1, 1);
+ MenuDrawTextWindow(0x14, 0, 0x1D, 0x13);
+ Mailbox_DrawMailList(taskId);
+ InitMenu(0, 0x15, 2, gMailboxInfo.pageItems, gMailboxInfo.cursorPos, 8);
+}
+
+// Mailbox_ProcessInput
+static void Mailbox_ProcessInput(u8 taskId)
+{
+ if(!gPaletteFade.active)
+ {
+ if(gMain.newAndRepeatedKeys & DPAD_UP)
+ {
+ if(gMailboxInfo.cursorPos != 0)
+ {
+ PlaySE(SE_SELECT);
+ gMailboxInfo.cursorPos = MoveMenuCursor(-1);
+ }
+ else if(gMailboxInfo.itemsAbove != 0)
+ {
+ PlaySE(SE_SELECT);
+ gMailboxInfo.itemsAbove--;
+ Mailbox_DrawMailList(taskId);
+ }
+ }
+ else if(gMain.newAndRepeatedKeys & DPAD_DOWN)
+ {
+ if(gMailboxInfo.cursorPos != gMailboxInfo.pageItems - 1)
+ {
+ PlaySE(SE_SELECT);
+ gMailboxInfo.cursorPos = MoveMenuCursor(1);
+ }
+ else if(gMailboxInfo.itemsAbove + gMailboxInfo.cursorPos != gMailboxInfo.count)
+ {
+ PlaySE(SE_SELECT);
+ gMailboxInfo.itemsAbove++;
+ Mailbox_DrawMailList(taskId);
+ }
+ }
+ else if(gMain.newKeys & A_BUTTON)
+ {
+ HandleDestroyMenuCursors();
+ PlaySE(SE_SELECT);
+
+ if(gMailboxInfo.itemsAbove + gMailboxInfo.cursorPos == gMailboxInfo.count)
+ {
+ Mailbox_TurnOff(taskId);
+ }
+ else
+ {
+ Mailbox_CloseScrollIndicators();
+ TASK.FUNC = Mailbox_PrintWhatToDoWithPlayerMailText;
+ }
+ }
+ else if(gMain.newKeys & B_BUTTON)
+ {
+ HandleDestroyMenuCursors();
+ PlaySE(SE_SELECT);
+ Mailbox_TurnOff(taskId);
+ }
+ }
+}
+
+static void Mailbox_CloseScrollIndicators(void)
+{
+ BuyMenuFreeMemory();
+ DestroyVerticalScrollIndicator(0);
+ DestroyVerticalScrollIndicator(1);
+}
+
+static void Mailbox_PrintWhatToDoWithPlayerMailText(u8 taskId)
+{
+ MenuZeroFillWindowRect(0, 0, 0x1D, 0x13);
+ StringCopy(gStringVar1, gSaveBlock1.mail[gMailboxInfo.itemsAbove + 6 + gMailboxInfo.cursorPos].playerName);
+ SanitizeNameString(gStringVar1);
+ StringExpandPlaceholders(gStringVar4, gOtherText_WhatWillYouDoMail);
+ DisplayItemMessageOnField(taskId, gStringVar4, Mailbox_PrintMailOptions, 0);
+}
+
+static void Mailbox_ReturnToPlayerPC(u8 taskId)
+{
+ MenuZeroFillWindowRect(0, 0, 0x1D, 0x13);
+ ReshowPlayerPC(taskId);
+}
+
+static void Mailbox_TurnOff(u8 taskId)
+{
+ Mailbox_CloseScrollIndicators();
+ TASK.FUNC = Mailbox_ReturnToPlayerPC;
+}
+
+static void Mailbox_PrintMailOptions(u8 taskId) // Mailbox_PrintMailOptions
+{
+ MenuDrawTextWindow(0, 0, 0xC, 0x9);
+ PrintMenuItems(1, 1, 4, (struct MenuAction *)gMailboxMailOptions);
+ InitMenu(0, 1, 1, 4, 0, 0xB);
+ TASK.FUNC = Mailbox_MailOptionsProcessInput;
+}
+
+static void Mailbox_MailOptionsProcessInput(u8 taskId)
+{
+ if(gMain.newAndRepeatedKeys & DPAD_UP)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor(-1);
+ }
+ else if(gMain.newAndRepeatedKeys & DPAD_DOWN)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor(1);
+ }
+ else if(gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ gMailboxMailOptions[GetMenuCursorPos()].func(taskId);
+ }
+ else if(gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ Mailbox_Cancel(taskId);
+ }
+}
+
+static void Mailbox_DoMailRead(u8 taskId)
+{
+ fade_screen(1, 0);
+ TASK.FUNC = Mailbox_FadeAndReadMail;
+}
+
+static void Mailbox_FadeAndReadMail(u8 taskId)
+{
+ if(!gPaletteFade.active)
+ {
+ HandleReadMail(&gSaveBlock1.mail[gMailboxInfo.itemsAbove + 6 + gMailboxInfo.cursorPos], Mailbox_ReturnToFieldFromReadMail, 1);
+ DestroyTask(taskId);
+ }
+}
+
+static void Mailbox_HandleReturnToProcessInput(u8 taskId) // Mailbox_HandleReturnToProcessInput
+{
+ if(sub_807D770() == TRUE) // is black fade finished? why not gPaletteFade.active?
+ TASK.FUNC = Mailbox_ProcessInput;
+}
+
+static void Mailbox_DoRedrawMailboxMenuAfterReturn(void)
+{
+ Mailbox_DrawMailboxMenu(CreateTask(Mailbox_HandleReturnToProcessInput, 0));
+ pal_fill_black();
+}
+
+static void Mailbox_ReturnToFieldFromReadMail(void)
+{
+ gFieldCallback = Mailbox_DoRedrawMailboxMenuAfterReturn;
+ SetMainCallback2(c2_exit_to_overworld_2_switch);
+}
+
+static void Mailbox_MoveToBag(u8 taskId)
+{
+ HandleDestroyMenuCursors();
+ StringCopy(gStringVar1, gOtherText_MoveToBag);
+ MenuPrint(gHighlightedMoveToBagFormatText, 1, 3); // gHighlightedMoveToBagFormatText
+ DisplayItemMessageOnField(taskId, gOtherText_MessageWillBeLost, Mailbox_DrawYesNoBeforeMove, 0);
+}
+
+static void Mailbox_DrawYesNoBeforeMove(u8 taskId)
+{
+ DisplayYesNoMenu(0x14, 0x8, 0x1);
+ DoYesNoFuncWithChoice(taskId, (struct YesNoFuncTable *)&ResumeFromWithdrawYesNoFuncList);
+}
+
+static void Mailbox_DoMailMoveToBag(u8 taskId)
+{
+ struct MailStruct *mail = &gSaveBlock1.mail[gMailboxInfo.itemsAbove + 6 + gMailboxInfo.cursorPos];
+
+ MenuZeroFillWindowRect(0x14, 8, 0x1A, 0xD);
+
+ if(AddBagItem(mail->itemId, 1) == FALSE)
+ {
+ DisplayItemMessageOnField(taskId, gOtherText_BagIsFull, Mailbox_DrawMailMenuAndDoProcessInput, 0);
+ }
+ else
+ {
+ DisplayItemMessageOnField(taskId, gOtherText_MailWasReturned, Mailbox_DrawMailMenuAndDoProcessInput, 0);
+ ClearMailStruct(mail);
+ Mailbox_UpdateMailList();
+
+ gMailboxInfo.count--;
+
+ if(gMailboxInfo.count < gMailboxInfo.pageItems + gMailboxInfo.itemsAbove && gMailboxInfo.itemsAbove != 0)
+ gMailboxInfo.itemsAbove--;
+
+ ItemStorage_SetItemAndMailCount(taskId);
+ }
+}
+
+static void Mailbox_ReturnToInputAfterNo(u8 taskId) // Mailbox_ReturnToInputAfterNo
+{
+ MenuZeroFillWindowRect(0x14, 0x8, 0x1A, 0xD);
+ Mailbox_DrawMailMenuAndDoProcessInput(taskId);
+}
+
+static void Mailbox_Give(u8 taskId)
+{
+ if(CalculatePlayerPartyCount() == 0)
+ Mailbox_NoPokemonForMail(taskId); // cannot be reached normally
+ else
+ {
+ fade_screen(1, 0);
+ TASK.FUNC = Mailbox_DoGiveMailPokeMenu;
+ }
+}
+
+static void Mailbox_DoGiveMailPokeMenu(u8 taskId) // Mailbox_DoGiveMailPokeMenu
+{
+ if(!gPaletteFade.active)
+ {
+ SetMainCallback2(sub_808B020);
+ gUnknown_02038561 = 3;
+ DestroyTask(taskId);
+ }
+}
+
+static void Mailbox_UpdateMailListAfterDeposit(void)
+{
+ u8 taskId = CreateTask(Mailbox_HandleReturnToProcessInput, 0);
+ u8 oldCount = gMailboxInfo.count;
+
+ gMailboxInfo.count = GetMailboxMailCount();
+ Mailbox_UpdateMailList();
+
+ if(oldCount != gMailboxInfo.count && gMailboxInfo.count < gMailboxInfo.pageItems + gMailboxInfo.itemsAbove && gMailboxInfo.itemsAbove != 0) // did the count update?
+ gMailboxInfo.itemsAbove--;
+
+ ItemStorage_SetItemAndMailCount(taskId);
+ Mailbox_DrawMailboxMenu(taskId);
+ pal_fill_black();
+}
+
+void Mailbox_ReturnToMailListAfterDeposit(void)
+{
+ gFieldCallback = Mailbox_UpdateMailListAfterDeposit;
+ SetMainCallback2(c2_exit_to_overworld_2_switch);
+}
+
+// you always have at least 1 POKeMON and you cannot receive mail before you leave Littleroot: therefore this function cannot be reached normally.
+static void Mailbox_NoPokemonForMail(u8 taskId)
+{
+ DisplayItemMessageOnField(taskId, gOtherText_NoPokemon, Mailbox_DrawMailMenuAndDoProcessInput, 0);
+}
+
+static void Mailbox_Cancel(u8 taskId)
+{
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(0, 0, 0xC, 0x9);
+ Mailbox_DrawMailMenuAndDoProcessInput(taskId);
+}
+
+static void Mailbox_DrawMailMenuAndDoProcessInput(u8 taskId)
+{
+ Mailbox_DrawMailboxMenu(taskId);
+ TASK.FUNC = Mailbox_ProcessInput;
+}
diff --git a/src/field/pokeblock.c b/src/field/pokeblock.c
new file mode 100644
index 000000000..34f4ffa35
--- /dev/null
+++ b/src/field/pokeblock.c
@@ -0,0 +1,1133 @@
+//
+
+//
+
+#include "global.h"
+#include "overworld.h"
+#include "sprite.h"
+#include "script.h"
+#include "strings.h"
+#include "task.h"
+#include "unknown_task.h"
+#include "text.h"
+#include "main.h"
+#include "menu.h"
+#include "field_fadetransition.h"
+#include "palette.h"
+#include "graphics.h"
+#include "decompress.h"
+#include "menu_helpers.h"
+#include "battle.h"
+#include "item_menu.h"
+#include "item_use.h"
+#include "item.h"
+#include "items.h"
+#include "sound.h"
+#include "songs.h"
+#include "safari_zone.h"
+#include "event_data.h"
+#include "pokeblock.h"
+
+struct UnkPokeblockStruct
+{
+ u8 unk0;
+ u8 unk1;
+ u8 unk2;
+ u8 unk3;
+};
+
+extern u8 ewram[];
+
+
+static EWRAM_DATA u8 gUnknown_02039244 = 0;
+static EWRAM_DATA struct UnkPokeblockStruct gUnknown_02039248 = {0};
+static EWRAM_DATA u8 gUnknown_0203924C = 0;
+
+// function declarations
+
+// gUnknown_083F7EF4
+static void sub_810C508(u8);
+static void sub_810C5C0(u8);
+static void sub_810C748(u8);
+static void sub_810C788(u8);
+static void sub_810C854(u8);
+
+// gUnknown_083F7F24
+static void sub_810C610(u8);
+static void sub_810C668(u8);
+
+// sub_810B6C0
+static bool8 sub_810B998(void);
+static void sub_810BC98(void);
+static void sub_810BD08(void);
+static void sub_810BB0C(void);
+static void sub_810BB30(void);
+static void sub_810BC84(u8);
+
+// sub_810B96C
+static void sub_810BF7C(u8);
+
+// sub_810BC84
+static void sub_810BDAC(bool8);
+
+// sub_810BF38
+static void sub_810C8D4(struct Sprite *);
+
+// sub_810BF7C
+static void sub_810C0C8(u8);
+static void sub_810C31C(u8);
+static void sub_810C368(u8);
+
+// sub_810C0C8
+static void sub_810C1C8(u8, u8);
+static void sub_810C23C(u8);
+
+// sub_810C368
+static void sub_810C40C(u8);
+
+// sub_810C540
+static void sub_810C5EC(u8);
+
+// sub_810C610
+static void sub_810C704(u8);
+
+static const u8 *gUnknown_03000758;
+
+// rodata
+
+#define GFX_TAG_POKEBLOCK_CASE 14800
+
+const s8 gPokeblockFlavorCompatibilityTable[] = {
+ // Cool, Beauty, Cute, Smart, Tough
+ 0, 0, 0, 0, 0, // Hardy
+ 1, 0, 0, 0, -1, // Lonely
+ 1, 0, -1, 0, 0, // Brave
+ 1, -1, 0, 0, 0, // Adamant
+ 1, 0, 0, -1, 0, // Naughty
+ -1, 0, 0, 0, 1, // Bold
+ 0, 0, 0, 0, 0, // Docile
+ 0, 0, -1, 0, 1, // Relaxed
+ 0, -1, 0, 0, 1, // Impish
+ 0, 0, 0, -1, 1, // Lax
+ -1, 0, 1, 0, 0, // Timid
+ 0, 0, 1, 0, -1, // Hasty
+ 0, 0, 0, 0, 0, // Serious
+ 0, -1, 1, 0, 0, // Jolly
+ 0, 0, 1, -1, 0, // Naive
+ -1, 1, 0, 0, 0, // Modest
+ 0, 1, 0, 0, -1, // Mild
+ 0, 1, -1, 0, 0, // Quiet
+ 0, 0, 0, 0, 0, // Bashful
+ 0, 1, 0, -1, 0, // Rash
+ -1, 0, 0, 1, 0, // Calm
+ 0, 0, 0, 1, -1, // Gentle
+ 0, 0, -1, 1, 0, // Sassy
+ 0, -1, 0, 1, 0, // Careful
+ 0, 0, 0, 0, 0 // Quirky
+};
+
+void (*const gUnknown_083F7EA8[])(void) = {
+ sub_80A5B40,
+ c2_exit_to_overworld_2_switch,
+ sub_802E424,
+ c2_exit_to_overworld_2_switch
+};
+
+const u8 *const gPokeblockNames[] = {
+ NULL,
+ ContestStatsText_RedPokeBlock,
+ ContestStatsText_BluePokeBlock,
+ ContestStatsText_PinkPokeBlock,
+ ContestStatsText_GreenPokeBlock,
+ ContestStatsText_YellowPokeBlock,
+ ContestStatsText_PurplePokeBlock,
+ ContestStatsText_IndigoPokeBlock,
+ ContestStatsText_BrownPokeBlock,
+ ContestStatsText_LiteBluePokeBlock,
+ ContestStatsText_OlivePokeBlock,
+ ContestStatsText_GrayPokeBlock,
+ ContestStatsText_BlackPokeBlock,
+ ContestStatsText_WhitePokeBlock,
+ ContestStatsText_GoldPokeBlock
+};
+
+const struct MenuAction2 gUnknown_083F7EF4[] = {
+ {OtherText_Use, sub_810C508},
+ {OtherText_Toss, sub_810C5C0},
+ {gOtherText_CancelNoTerminator, sub_810C748},
+ {OtherText_Use, sub_810C788},
+ {OtherText_Use, sub_810C854},
+};
+
+const u8 gUnknown_083F7F1C[] = {0, 1, 2};
+const u8 gUnknown_083F7F1F[] = {3, 2};
+const u8 gUnknown_083F7F21[] = {4, 2};
+
+const struct YesNoFuncTable gUnknown_083F7F24 = {sub_810C610, sub_810C668};
+
+const u8 UnreferencedData_083F7F2C[] = {0x16, 0x17, 0x18, 0x21, 0x2f};
+
+const struct OamData gOamData_83F7F34 = {
+ .size = 3,
+ .priority = 2
+};
+
+const union AnimCmd gSpriteAnim_83F7F3C[] = {
+ ANIMCMD_FRAME(.imageValue = 0, .duration = 0),
+ ANIMCMD_END
+};
+
+const union AnimCmd *const gSpriteAnimTable_83F7F44[] = {
+ gSpriteAnim_83F7F3C
+};
+
+const union AffineAnimCmd gSpriteAffineAnim_83F7F48[] = {
+ AFFINEANIMCMD_FRAME(0, 0, -2, 2),
+ AFFINEANIMCMD_FRAME(0, 0, 2, 4),
+ AFFINEANIMCMD_FRAME(0, 0, -2, 4),
+ AFFINEANIMCMD_FRAME(0, 0, 2, 2),
+ AFFINEANIMCMD_END
+};
+
+const union AffineAnimCmd *const gSpriteAffineAnimTable_83F7F70[] = {
+ gSpriteAffineAnim_83F7F48
+};
+
+const struct CompressedSpriteSheet gUnknown_083F7F74 = {
+ gMenuPokeblockDevice_Gfx,
+ 0x800,
+ GFX_TAG_POKEBLOCK_CASE
+};
+
+const struct CompressedSpritePalette gUnknown_083F7F7C = {
+ gMenuPokeblockDevice_Pal,
+ GFX_TAG_POKEBLOCK_CASE
+};
+
+const struct SpriteTemplate gSpriteTemplate_83F7F84 = {
+ GFX_TAG_POKEBLOCK_CASE,
+ GFX_TAG_POKEBLOCK_CASE,
+ &gOamData_83F7F34,
+ gSpriteAnimTable_83F7F44,
+ NULL,
+ gDummySpriteAffineAnimTable,
+ SpriteCallbackDummy
+};
+
+const struct Pokeblock gUnknown_083F7F9C[] = {
+ { PBLOCK_CLR_RED, 20, 0, 0, 0, 0, 20},
+ { PBLOCK_CLR_BLUE, 0, 20, 0, 0, 0, 20},
+ { PBLOCK_CLR_PINK, 0, 0, 20, 0, 0, 20},
+ { PBLOCK_CLR_GREEN, 0, 0, 0, 20, 0, 20},
+ { PBLOCK_CLR_YELLOW, 0, 0, 0, 0, 20, 20}
+};
+
+// text
+
+static void sub_810B674(void)
+{
+ AnimateSprites();
+ BuildOamBuffer();
+ RunTasks();
+ UpdatePaletteFade();
+}
+
+static void sub_810B68C(void)
+{
+ u16 *src;
+ vu16 *dest;
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+ src = gBGTilemapBuffers[2];
+ dest = (vu16 *)(VRAM + 0x7800);
+ DmaCopy16(3, src, dest, sizeof gBGTilemapBuffers[2]);
+}
+
+static bool8 sub_810B6C0(void)
+{
+ u16 ime;
+ switch (gMain.state)
+ {
+ case 0:
+ sub_80F9438();
+ sub_80F9368();
+ REG_BG2CNT = BGCNT_SCREENBASE(15) | BGCNT_CHARBASE(2) | BGCNT_PRIORITY(2);
+ REG_BLDCNT = 0;
+ gMain.state++;
+ break;
+ case 1:
+ remove_some_task();
+ gMain.state++;
+ break;
+ case 2:
+ ResetPaletteFade();
+ gPaletteFade.bufferTransferDisabled = TRUE;
+ gMain.state++;
+ break;
+ case 3:
+ ResetSpriteData();
+ gMain.state++;
+ break;
+ case 4:
+ if (gUnknown_02039244 != 2)
+ {
+ ResetTasks();
+ }
+ gMain.state++;
+ break;
+ case 5:
+ SetUpWindowConfig(&gWindowConfig_81E6E34);
+ gMain.state++;
+ break;
+ case 6:
+ SetUpWindowConfig(&gWindowConfig_81E6E50);
+ gMain.state++;
+ break;
+ case 7:
+ MultistepInitMenuWindowBegin(&gWindowConfig_81E6E34);
+ gMain.state++;
+ break;
+ case 8:
+ if (MultistepInitMenuWindowContinue())
+ {
+ gMain.state++;
+ }
+ break;
+ case 9:
+ MultistepInitMenuWindowBegin(&gWindowConfig_81E6E50);
+ gMain.state++;
+ break;
+ case 10:
+ if (MultistepInitMenuWindowContinue())
+ {
+ ewram[0x1ffff] = 0;
+ gMain.state++;
+ }
+ break;
+ case 11:
+ if (sub_810B998())
+ {
+ gMain.state++;
+ }
+ break;
+ case 12:
+ sub_80F944C();
+ LoadScrollIndicatorPalette();
+ CreateVerticalScrollIndicators(0, 0xb0, 0x08);
+ CreateVerticalScrollIndicators(1, 0xb0, 0x98);
+ gMain.state++;
+ break;
+ case 13:
+ ewram[0x1fffe] = sub_810BA50(0x38, 0x40, 0);
+ gMain.state++;
+ break;
+ case 14:
+ sub_810BC98();
+ sub_810BD08();
+ gMain.state++;
+ break;
+ case 15:
+ sub_810BB0C();
+ sub_810BB30();
+ sub_810BC84(gUnknown_02039248.unk1);
+ gMain.state++;
+ break;
+ case 16:
+ ime = REG_IME;
+ REG_IME = 0;
+ REG_IE |= INTR_FLAG_VBLANK;
+ REG_IME = ime;
+ REG_DISPSTAT |= DISPSTAT_VBLANK_INTR;
+ SetVBlankCallback(sub_810B68C);
+ REG_DISPCNT = DISPCNT_OBJ_ON | DISPCNT_BG2_ON | DISPCNT_BG1_ON | DISPCNT_BG0_ON | DISPCNT_OBJ_1D_MAP;
+ gMain.state++;
+ break;
+ case 17:
+ if (sub_8055870() != TRUE)
+ {
+ gMain.state++;
+ }
+ break;
+ case 18:
+ BeginNormalPaletteFade(-1, 0, 0x10, 0, 0);
+ gPaletteFade.bufferTransferDisabled = FALSE;
+ SetMainCallback2(sub_810B674);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void sub_810B96C(void)
+{
+ do {
+ if (sub_810B6C0() == TRUE)
+ {
+ CreateTask(sub_810BF7C, 0);
+ break;
+ }
+ } while (sub_80F9344() != TRUE);
+}
+
+static bool8 sub_810B998(void)
+{
+ switch (ewram[0x1ffff])
+ {
+ case 0:
+ LZDecompressVram(gMenuPokeblock_Gfx, (u8 *)BG_CHAR_ADDR(2));
+ ewram[0x1ffff]++;
+ break;
+ case 1:
+ LZDecompressWram(gMenuPokeblock_Tilemap, gBGTilemapBuffers[2]);
+ ewram[0x1ffff]++;
+ break;
+ case 2:
+ LoadCompressedPalette(gMenuPokeblock_Pal, 0, 0xc0);
+ ewram[0x1ffff]++;
+ break;
+ case 3:
+ LoadCompressedObjectPic(&gUnknown_083F7F74);
+ ewram[0x1ffff]++;
+ break;
+ case 4:
+ LoadCompressedObjectPalette(&gUnknown_083F7F7C);
+ ewram[0x1ffff] = 0;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+u8 sub_810BA50(s16 x, s16 y, u8 subpriority)
+{
+ return CreateSprite(&gSpriteTemplate_83F7F84, x, y, subpriority);
+}
+
+void sub_810BA7C(u8 a0)
+{
+ gUnknown_02039244 = a0;
+ switch (gUnknown_02039244)
+ {
+ default:
+ gUnknown_03000758 = gUnknown_083F7F1C;
+ gUnknown_0203924C = sizeof gUnknown_083F7F1C;
+ break;
+ case 2:
+ gUnknown_03000758 = gUnknown_083F7F1F;
+ gUnknown_0203924C = sizeof gUnknown_083F7F1F;
+ break;
+ case 3:
+ gUnknown_03000758 = gUnknown_083F7F21;
+ gUnknown_0203924C = sizeof gUnknown_083F7F21;
+ break;
+ }
+}
+
+void sub_810BADC(void)
+{
+ sub_810BA7C(2);
+ SetMainCallback2(sub_810B96C);
+}
+
+void sub_810BAF4(void)
+{
+ sub_810BA7C(3);
+ SetMainCallback2(sub_810B96C);
+}
+
+#ifdef DEBUG
+void debug_sub_8120F98(void)
+{
+ u8 i;
+ for (i=0; i<40 && gUnknown_083F7F9C[i].color != 0; i++)
+ {
+ gSaveBlock1.pokeblocks[i] = gUnknown_083F7F9C[i];
+ }
+}
+#endif
+
+static void sub_810BB0C(void)
+{
+ BasicInitMenuWindow(&gWindowConfig_81E6E34);
+ sub_8072BD8(ItemId_GetItem(ITEM_POKEBLOCK_CASE)->name, 2, 1, 0x48);
+}
+
+static void sub_810BB30(void)
+{
+ BasicInitMenuWindow(&gWindowConfig_81E6E34);
+ MenuPrint(gContestStatsText_Spicy, 2, 13);
+ MenuPrint(gContestStatsText_Dry, 2, 15);
+ MenuPrint(gContestStatsText_Sweet, 2, 17);
+ MenuPrint(gContestStatsText_Bitter, 8, 13);
+ MenuPrint(gContestStatsText_Sour, 8, 15);
+}
+
+static void sub_810BB88(u8 a0)
+{
+ u8 i;
+ u8 y;
+ u8 *buf;
+ BasicInitMenuWindow(&gWindowConfig_81E6E34);
+ for (i=a0; i<=a0+8; i++)
+ {
+ y = (i - a0) << 1;
+ if (i == gUnknown_02039248.unk2)
+ {
+ buf = sub_8072C74(gStringVar1, gContestStatsText_StowCase, 0x78, 0);
+ MenuPrint(gStringVar1, 15, y + 1);
+ if (i != a0 + 8)
+ {
+ MenuZeroFillWindowRect(15, y + 3, 29, 18);
+ }
+ break;
+ }
+ buf = sub_8072C74(gStringVar1, gPokeblockNames[gSaveBlock1.pokeblocks[i].color], 0x5e, 0);
+ buf[0] = EXT_CTRL_CODE_BEGIN;
+ buf[1] = 0x14;
+ buf[2] = 0x06;
+ buf += 3;
+ ConvertIntToDecimalStringN(buf, sub_810C9B0(&gSaveBlock1.pokeblocks[i]), STR_CONV_MODE_RIGHT_ALIGN, 3);
+ MenuPrint(gStringVar1, 15, y + 1);
+ }
+}
+
+static void sub_810BC84(u8 a0)
+{
+ sub_810BB88(a0);
+ sub_810BDAC(FALSE);
+}
+
+static void sub_810BC98(void)
+{
+ u16 i, j;
+ struct Pokeblock buf;
+ for (i=0; i<39; i++)
+ {
+ for (j=i+1; j<40; j++)
+ {
+ if (gSaveBlock1.pokeblocks[i].color == 0)
+ {
+ buf = gSaveBlock1.pokeblocks[i];
+ gSaveBlock1.pokeblocks[i] = gSaveBlock1.pokeblocks[j];
+ gSaveBlock1.pokeblocks[j] = buf;
+ }
+ }
+ }
+}
+
+static void sub_810BD08(void)
+{
+ u8 i;
+ gUnknown_02039248.unk2 = 0;
+ for (i=0; i<40; i++)
+ {
+ if (gSaveBlock1.pokeblocks[i].color != 0)
+ gUnknown_02039248.unk2++;
+ }
+ if (gUnknown_02039248.unk2 < 8)
+ {
+ gUnknown_02039248.unk3 = gUnknown_02039248.unk2;
+ }
+ else
+ {
+ gUnknown_02039248.unk3 = 8;
+ }
+ if (gUnknown_02039248.unk1 + 8 > gUnknown_02039248.unk2 && gUnknown_02039248.unk1 != 0)
+ {
+ gUnknown_02039248.unk1--;
+ }
+}
+
+static void sub_810BD64(u16 a0, u16 a1)
+{
+ u8 i;
+ int y;
+ for (i=0; i<14; i++)
+ {
+ gBGTilemapBuffers[2][(2 * gUnknown_02039248.unk0 + 1) * 32 + (y = i + 15)] = a0;
+ gBGTilemapBuffers[2][(2 * gUnknown_02039248.unk0 + 2) * 32 + y] = a0;
+ }
+}
+
+static void sub_810BDAC(bool8 flag)
+{
+ u8 i;
+ u16 v0;
+ if (!flag)
+ {
+ sub_810BD64(0x1005, 0x1014);
+ }
+ else
+ {
+ sub_810BD64(0x2005, 0x2014);
+ }
+ if (gUnknown_02039248.unk1)
+ {
+ sub_80F979C(0, 0);
+ }
+ else
+ {
+ sub_80F979C(0, 1);
+ }
+ if (gUnknown_02039248.unk2 > gUnknown_02039248.unk3 && gUnknown_02039248.unk1 + gUnknown_02039248.unk3 != gUnknown_02039248.unk2)
+ {
+ sub_80F979C(1, 0);
+ }
+ else
+ {
+ sub_80F979C(1, 1);
+ }
+ for (i=0; i<5; i++)
+ {
+ v0 = ((i % 3) << 6) + 0x1a1 + (i / 3) * 6;
+ if (gUnknown_02039248.unk0 + gUnknown_02039248.unk1 != gUnknown_02039248.unk2)
+ {
+ if (GetPokeblockData(&gSaveBlock1.pokeblocks[gUnknown_02039248.unk0 + gUnknown_02039248.unk1], i + 1) > 0)
+ {
+ gBGTilemapBuffers[2][v0] = (i << 12) + 23;
+ gBGTilemapBuffers[2][v0 + 32] = (i << 12) + 24;
+ }
+ else
+ {
+ gBGTilemapBuffers[2][v0] = 15;
+ gBGTilemapBuffers[2][v0 + 32] = 15;
+ }
+ }
+ else
+ {
+ gBGTilemapBuffers[2][v0] = 15;
+ gBGTilemapBuffers[2][v0 + 32] = 15;
+ }
+ }
+ BasicInitMenuWindow(&gWindowConfig_81E6E34);
+ if (gUnknown_02039248.unk0 + gUnknown_02039248.unk1 != gUnknown_02039248.unk2)
+ {
+ sub_8072C14(gStringVar1, sub_810C9E8(&gSaveBlock1.pokeblocks[gUnknown_02039248.unk0 + gUnknown_02039248.unk1]), 16, 1);
+ MenuPrint(gStringVar1, 11, 17);
+ }
+ else
+ {
+ MenuZeroFillWindowRect(11, 17, 12, 18);
+ }
+}
+
+static void sub_810BF38(bool8 flag)
+{
+ PlaySE(SE_SELECT);
+ gSprites[ewram[0x1fffe]].callback = sub_810C8D4;
+ sub_810BDAC(flag);
+}
+
+static void sub_810BF7C(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ if (gMain.newAndRepeatedKeys & DPAD_UP)
+ {
+ if (gUnknown_02039248.unk0 != 0)
+ {
+ sub_810BD64(5, 20);
+ gUnknown_02039248.unk0--;
+ sub_810BF38(FALSE);
+ }
+ else if (gUnknown_02039248.unk1 != 0)
+ {
+ gUnknown_02039248.unk1--;
+ sub_810BB88(gUnknown_02039248.unk1);
+ sub_810BF38(FALSE);
+ }
+ }
+ else if (gMain.newAndRepeatedKeys & DPAD_DOWN)
+ {
+ if (gUnknown_02039248.unk0 != gUnknown_02039248.unk3)
+ {
+ sub_810BD64(5, 20);
+ gUnknown_02039248.unk0++;
+ sub_810BF38(FALSE);
+ }
+ else if (gUnknown_02039248.unk1 + gUnknown_02039248.unk0 != gUnknown_02039248.unk2)
+ {
+ gUnknown_02039248.unk1++;
+ sub_810BB88(gUnknown_02039248.unk1);
+ sub_810BF38(FALSE);
+ }
+ }
+ else if (gMain.newKeys & SELECT_BUTTON)
+ {
+ if (gUnknown_02039248.unk1 + gUnknown_02039248.unk0 != gUnknown_02039248.unk2)
+ {
+ PlaySE(SE_SELECT);
+ sub_810BDAC(TRUE);
+ gTasks[taskId].data[0] = gUnknown_02039248.unk1 + gUnknown_02039248.unk0;
+ gTasks[taskId].func = sub_810C0C8;
+ }
+ }
+ else if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ if (gUnknown_02039248.unk1 + gUnknown_02039248.unk0 == gUnknown_02039248.unk2)
+ {
+ gScriptResult = 0xffff;
+ sub_810C31C(taskId);
+ }
+ else
+ {
+ sub_810C368(taskId);
+ }
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ gScriptResult = 0xffff;
+ sub_810C31C(taskId);
+ }
+ }
+}
+
+static void sub_810C0C8(u8 taskId)
+{
+ if (gMain.newAndRepeatedKeys & DPAD_UP)
+ {
+ if (gUnknown_02039248.unk0 != 0)
+ {
+ sub_810BD64(5, 20);
+ gUnknown_02039248.unk0--;
+ sub_810BF38(TRUE);
+ sub_810C1C8(taskId, 1);
+ }
+ else if (gUnknown_02039248.unk1 != 0)
+ {
+ sub_810C1C8(taskId, 0);
+ gUnknown_02039248.unk1--;
+ sub_810BB88(gUnknown_02039248.unk1);
+ sub_810BF38(TRUE);
+ sub_810C1C8(taskId, 1);
+ }
+ }
+ else if (gMain.newAndRepeatedKeys & DPAD_DOWN)
+ {
+ if (gUnknown_02039248.unk0 != gUnknown_02039248.unk3)
+ {
+ sub_810BD64(5, 20);
+ gUnknown_02039248.unk0++;
+ sub_810BF38(TRUE);
+ sub_810C1C8(taskId, 1);
+ }
+ else if (gUnknown_02039248.unk1 + gUnknown_02039248.unk0 != gUnknown_02039248.unk2)
+ {
+ sub_810C1C8(taskId, 0);
+ gUnknown_02039248.unk1++;
+ sub_810BB88(gUnknown_02039248.unk1);
+ sub_810BF38(TRUE);
+ sub_810C1C8(taskId, 1);
+ }
+ }
+ else if (gMain.newKeys & A_BUTTON || gMain.newKeys & SELECT_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ sub_810C1C8(taskId, 0);
+ sub_810C23C(taskId);
+ gTasks[taskId].func = sub_810BF7C;
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ sub_810C1C8(taskId, 0);
+ sub_810BDAC(0);
+ gTasks[taskId].func = sub_810BF7C;
+ }
+}
+
+static void sub_810C1C8(u8 taskId, u8 flag)
+{
+ u8 i;
+ u32 x;
+ s16 y;
+ u16 v0 = 0x1005;
+ if (!flag)
+ {
+ v0 = 0x0005;
+ }
+ y = gTasks[taskId].data[0] - gUnknown_02039248.unk1;
+ if ((u16)y <= 8 && y != gUnknown_02039248.unk0)
+ {
+ for (i=0; i<14; i++)
+ {
+ gBGTilemapBuffers[2][(2 * y + 1) * 32 + (x = i + 15)] = v0;
+ gBGTilemapBuffers[2][(2 * y + 2) * 32 + x] = v0;
+ }
+ }
+}
+
+static void sub_810C23C(u8 taskId)
+{
+ struct Pokeblock buf;
+ u8 selidx = gUnknown_02039248.unk1 + gUnknown_02039248.unk0;
+ if (selidx == gUnknown_02039248.unk2)
+ {
+ sub_810BDAC(FALSE);
+ }
+ else
+ {
+ buf = gSaveBlock1.pokeblocks[selidx];
+ gSaveBlock1.pokeblocks[selidx] = gSaveBlock1.pokeblocks[gTasks[taskId].data[0]];
+ gSaveBlock1.pokeblocks[gTasks[taskId].data[0]] = buf;
+ sub_810BB88(gUnknown_02039248.unk1);
+ sub_810BDAC(FALSE);
+ }
+}
+
+static void sub_810C2B0(void)
+{
+ DestroyVerticalScrollIndicator(0);
+ DestroyVerticalScrollIndicator(1);
+ BuyMenuFreeMemory();
+}
+
+static void sub_810C2C8(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ if (gUnknown_02039244 == 3)
+ {
+ gFieldCallback = sub_8080990;
+ }
+ sub_810C2B0();
+ SetMainCallback2(gUnknown_083F7EA8[gUnknown_02039244]);
+ DestroyTask(taskId);
+ }
+}
+
+static void sub_810C31C(u8 taskId)
+{
+ BeginNormalPaletteFade(-1, 0, 0, 16, 0);
+ if (gUnknown_02039244 > 1)
+ {
+ gScriptItemId = ITEM_NONE;
+ }
+ gTasks[taskId].func = sub_810C2C8;
+}
+
+static void sub_810C368(u8 taskId)
+{
+ int v0 = 0;
+ if (gUnknown_02039244 > 1)
+ v0 = 2;
+ sub_80F98A4(0);
+ sub_80F98A4(1);
+ BasicInitMenuWindow(&gWindowConfig_81E6E50);
+ MenuDrawTextWindow(7, v0 + 4, 13, 11);
+ PrintMenuItemsReordered(8, v0 + 5, gUnknown_0203924C, gUnknown_083F7EF4, gUnknown_03000758);
+ InitMenu(0, 8, v0 + 5, gUnknown_0203924C, 0, 5);
+ gScriptItemId = gUnknown_02039248.unk0 + gUnknown_02039248.unk1;
+ gTasks[taskId].func = sub_810C40C;
+}
+
+static void sub_810C40C(u8 taskId)
+{
+ if (gMain.newAndRepeatedKeys & DPAD_UP)
+ {
+ if (GetMenuCursorPos())
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor(-1);
+ }
+ }
+ else if (gMain.newAndRepeatedKeys & DPAD_DOWN)
+ {
+ if (GetMenuCursorPos() != gUnknown_0203924C - 1)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor(+1);
+ }
+ }
+ else if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ gUnknown_083F7EF4[gUnknown_03000758[GetMenuCursorPos()]].func(taskId);
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ sub_810C748(taskId);
+ }
+}
+
+static void sub_810C4C4(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ sub_810C2B0();
+ sub_8136130(&gSaveBlock1.pokeblocks[gScriptItemId], sub_810B96C);
+ DestroyTask(taskId);
+ }
+}
+
+static void sub_810C508(u8 taskId)
+{
+ BeginNormalPaletteFade(-1, 0, 0, 16, 0);
+ gTasks[taskId].func = sub_810C4C4;
+}
+
+static void sub_810C540(u8 taskId)
+{
+ BasicInitMenuWindow(&gWindowConfig_81E6E50);
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(7, 4, 13, 11);
+ StringCopy(gStringVar1, gPokeblockNames[gSaveBlock1.pokeblocks[gUnknown_02039248.unk0 + gUnknown_02039248.unk1].color]);
+ StringExpandPlaceholders(gStringVar4, gContestStatsText_ThrowAwayPrompt);
+ DisplayItemMessageOnField(taskId, gStringVar4, sub_810C5EC, 0);
+}
+
+static void sub_810C5C0(u8 taskId)
+{
+ sub_80F979C(1, 1);
+ gTasks[taskId].func = sub_810C540;
+}
+
+static void sub_810C5EC(u8 taskId)
+{
+ DisplayYesNoMenu(7, 6, 1);
+ DoYesNoFuncWithChoice(taskId, &gUnknown_083F7F24);
+}
+
+static void sub_810C610(u8 taskId)
+{
+ MenuZeroFillWindowRect(7, 6, 13, 11);
+ PokeblockClearIfExists((gUnknown_02039248.unk0 + gUnknown_02039248.unk1));
+ StringExpandPlaceholders(gStringVar4, gContestStatsText_WasThrownAway);
+ DisplayItemMessageOnField(taskId, gStringVar4, sub_810C704, 0);
+ sub_810BC98();
+ sub_810BD08();
+}
+
+static void sub_810C668(u8 taskId)
+{
+ StartVerticalScrollIndicators(0);
+ StartVerticalScrollIndicators(1);
+ if (gUnknown_02039248.unk2 > gUnknown_02039248.unk3 && gUnknown_02039248.unk1 + gUnknown_02039248.unk3 != gUnknown_02039248.unk2)
+ {
+ sub_80F979C(1, 0);
+ }
+ BasicInitMenuWindow(&gWindowConfig_81E6E50);
+ MenuZeroFillWindowRect(7, 6, 13, 11);
+ MenuZeroFillWindowRect(0, 14, 29, 19);
+ gTasks[taskId].func = sub_810BF7C;
+}
+
+static void sub_810C6DC(u8 taskId)
+{
+ if (gMain.newKeys & A_BUTTON || gMain.newKeys & B_BUTTON)
+ {
+ sub_810C668(taskId);
+ }
+}
+
+static void sub_810C704(u8 taskId)
+{
+ BasicInitMenuWindow(&gWindowConfig_81E6E34);
+ sub_810BC84(gUnknown_02039248.unk1);
+ sub_80F979C(1, 1);
+ gTasks[taskId].func = sub_810C6DC;
+}
+
+static void sub_810C748(u8 taskId)
+{
+ StartVerticalScrollIndicators(0);
+ StartVerticalScrollIndicators(1);
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(7, 4, 13, 11);
+ gTasks[taskId].func = sub_810BF7C;
+}
+
+static void sub_810C788(u8 taskId)
+{
+ s16 v0 = PokeblockGetGain(GetNature(&gEnemyParty[0]), &gSaveBlock1.pokeblocks[gScriptItemId]);
+ StringCopy(gBattleTextBuff1, gPokeblockNames[gSaveBlock1.pokeblocks[gScriptItemId].color]);
+ PokeblockClearIfExists(gScriptItemId);
+ gScriptItemId = gSaveBlock1.pokeblocks[gScriptItemId].color << 8;
+ if (v0 == 0)
+ {
+ gScriptItemId += 1;
+ }
+ if (v0 > 0)
+ {
+ gScriptItemId += 2;
+ }
+ if (v0 < 0)
+ {
+ gScriptItemId += 3;
+ }
+ BeginNormalPaletteFade(-1, 0, 0, 16, 0);
+ gTasks[taskId].func = sub_810C2C8;
+}
+
+static void sub_810C854(u8 taskId)
+{
+ SafariZoneActivatePokeblockFeeder(gScriptItemId);
+ StringCopy(gStringVar1, gPokeblockNames[gSaveBlock1.pokeblocks[gScriptItemId].color]);
+ gScriptResult = gScriptItemId;
+ PokeblockClearIfExists(gScriptItemId);
+ BeginNormalPaletteFade(-1, 0, 0, 16, 0);
+ gTasks[taskId].func = sub_810C2C8;
+}
+
+static void sub_810C8D4(struct Sprite *sprite)
+{
+ if (sprite->data0 > 1)
+ {
+ sprite->data0 = 0;
+ }
+ switch (sprite->data0)
+ {
+ case 0:
+ sprite->oam.affineMode = 1;
+ sprite->affineAnims = gSpriteAffineAnimTable_83F7F70;
+ InitSpriteAffineAnim(sprite);
+ sprite->data0 = 1;
+ sprite->data1 = 0;
+ break;
+ case 1:
+ if (++sprite->data1 > 11)
+ {
+ sprite->oam.affineMode = 0;
+ sprite->data0 = 0;
+ sprite->data1 = 0;
+ FreeOamMatrix(sprite->oam.matrixNum);
+ sprite->callback = SpriteCallbackDummy;
+ }
+ break;
+ }
+}
+
+static void ClearPokeblock(u8 pokeblockIdx)
+{
+ gSaveBlock1.pokeblocks[pokeblockIdx].color = 0;
+ gSaveBlock1.pokeblocks[pokeblockIdx].spicy = 0;
+ gSaveBlock1.pokeblocks[pokeblockIdx].dry = 0;
+ gSaveBlock1.pokeblocks[pokeblockIdx].sweet = 0;
+ gSaveBlock1.pokeblocks[pokeblockIdx].bitter = 0;
+ gSaveBlock1.pokeblocks[pokeblockIdx].sour = 0;
+ gSaveBlock1.pokeblocks[pokeblockIdx].feel = 0;
+}
+
+void ClearPokeblocks(void)
+{
+ u8 pokeblockIdx;
+ for (pokeblockIdx=0; pokeblockIdx<ARRAY_COUNT(gSaveBlock1.pokeblocks); pokeblockIdx++)
+ {
+ ClearPokeblock(pokeblockIdx);
+ }
+}
+
+u8 sub_810C9B0(struct Pokeblock *pokeblock)
+{
+ u8 contestStat;
+ u8 maxRating;
+ u8 rating = GetPokeblockData(pokeblock, 1);
+ for (contestStat=1; contestStat<5; contestStat++)
+ {
+ maxRating = GetPokeblockData(pokeblock, contestStat + 1);
+ if (rating < maxRating)
+ {
+ rating = maxRating;
+ }
+ }
+ return rating;
+}
+
+u8 sub_810C9E8(struct Pokeblock *pokeblock)
+{
+ u8 feel = GetPokeblockData(pokeblock, 6);
+ if (feel > 99)
+ feel = 99;
+ return feel;
+}
+
+s8 sub_810CA00(void)
+{
+ u8 i;
+ for (i=0; i<ARRAY_COUNT(gSaveBlock1.pokeblocks); i++)
+ {
+ if (gSaveBlock1.pokeblocks[i].color == 0)
+ {
+ return i;
+ }
+ }
+ return -1;
+}
+
+bool8 sub_810CA34(struct Pokeblock *pokeblock)
+{
+ s8 idx = sub_810CA00();
+ if (idx == -1)
+ {
+ return FALSE;
+ }
+ gSaveBlock1.pokeblocks[idx] = *pokeblock;
+ return TRUE;
+}
+
+bool8 PokeblockClearIfExists(u8 pokeblockIdx)
+{
+ if (gSaveBlock1.pokeblocks[pokeblockIdx].color == 0)
+ {
+ return FALSE;
+ }
+ ClearPokeblock(pokeblockIdx);
+ return TRUE;
+}
+
+s16 GetPokeblockData(const struct Pokeblock *pokeblock, u8 field)
+{
+ if (field == PBLOCK_COLOR)
+ return pokeblock->color;
+ if (field == PBLOCK_SPICY)
+ return pokeblock->spicy;
+ if (field == PBLOCK_DRY)
+ return pokeblock->dry;
+ if (field == PBLOCK_SWEET)
+ return pokeblock->sweet;
+ if (field == PBLOCK_BITTER)
+ return pokeblock->bitter;
+ if (field == PBLOCK_SOUR)
+ return pokeblock->sour;
+ if (field == PBLOCK_FEEL)
+ return pokeblock->feel;
+ return 0;
+}
+
+s16 PokeblockGetGain(u8 nature, const struct Pokeblock *pokeblock)
+{
+ u8 flavor;
+ s16 curGain;
+ s16 totalGain = 0;
+ for (flavor=0; flavor<5; flavor++)
+ {
+ curGain = GetPokeblockData(pokeblock, flavor + 1);
+ if (curGain > 0)
+ {
+ totalGain += curGain * gPokeblockFlavorCompatibilityTable[5 * nature + flavor];
+ }
+ }
+ return totalGain;
+}
+
+void PokeblockCopyName(struct Pokeblock *pokeblock, u8 *dest)
+{
+ u8 color = GetPokeblockData(pokeblock, PBLOCK_COLOR);
+ StringCopy(dest, gPokeblockNames[color]);
+}
+
+bool8 sub_810CB68(u8 nature, u8 *dest)
+{
+ u8 flavor;
+ for (flavor=0; flavor<5; flavor++)
+ {
+ if (PokeblockGetGain(nature, &gUnknown_083F7F9C[flavor]) > 0)
+ {
+ StringCopy(dest, gPokeblockNames[flavor + 1]);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
diff --git a/src/field/pokenav.c b/src/field/pokenav.c
new file mode 100644
index 000000000..21d7bb4e3
--- /dev/null
+++ b/src/field/pokenav.c
@@ -0,0 +1,42 @@
+#include "global.h"
+#include "main.h"
+#include "pokenav.h"
+#include "battle.h"
+#include "data2.h"
+#include "de_rom_8040FE0.h"
+#include "string_util.h"
+
+void sub_80F700C(u8 *arg0, u16 arg1) {
+ struct Trainer *trainer;
+ u8 *ptr;
+
+#if ENGLISH
+ trainer = (struct Trainer *) &gTrainers[gUnknown_083DFEC4->unkCEE8[arg1].unk0];
+#elif GERMAN
+ const u16 trainerIndex = gUnknown_083DFEC4->unkCEE8[arg1].unk0;
+ trainer = (struct Trainer *) &gTrainers[trainerIndex];
+#endif
+
+ ptr = arg0;
+ if (arg1 < gUnknown_083DFEC4->unkD158)
+ {
+#if ENGLISH
+ ptr = StringCopy(ptr, gTrainerClassNames[trainer->trainerClass]);
+#elif GERMAN
+ ptr = StringCopy(ptr, de_sub_8041024(0, trainerIndex));
+#endif
+
+ ptr[0] = 0xFC;
+ ptr[1] = 0x13;
+ ptr[2] = 0x4B;
+ ptr += 3;
+ ptr = StringCopy(ptr, trainer->trainerName);
+ }
+
+ ptr[0] = 0xFC;
+ ptr[1] = 0x13;
+ ptr[2] = 0x80;
+ ptr[3] = 0xFF;
+}
+
+IWRAM_DATA MainCallback gUnknown_03000744;
diff --git a/src/field/region_map.c b/src/field/region_map.c
new file mode 100644
index 000000000..bfd2729c2
--- /dev/null
+++ b/src/field/region_map.c
@@ -0,0 +1,1847 @@
+#include "global.h"
+#include "event_data.h"
+#include "field_effect.h"
+#include "field_specials.h"
+#include "m4a.h"
+#include "main.h"
+#include "map_constants.h"
+#include "menu.h"
+#include "palette.h"
+#include "pokemon_menu.h"
+#include "region_map.h"
+#include "overworld.h"
+#include "secret_base.h"
+#include "songs.h"
+#include "sprite.h"
+#include "strings.h"
+#include "string_util.h"
+#include "text.h"
+#include "trig.h"
+
+// Map Section IDs
+#define MAPSEC_LITTLEROOT_TOWN 0
+#define MAPSEC_OLDALE_TOWN 1
+#define MAPSEC_DEWFORD_TOWN 2
+#define MAPSEC_LAVARIDGE_TOWN 3
+#define MAPSEC_FALLARBOR_TOWN 4
+#define MAPSEC_VERDANTURF_TOWN 5
+#define MAPSEC_PACIFIDLOG_TOWN 6
+#define MAPSEC_PETALBURG_CITY 7
+#define MAPSEC_SLATEPORT_CITY 8
+#define MAPSEC_MAUVILLE_CITY 9
+#define MAPSEC_RUSTBORO_CITY 10
+#define MAPSEC_FORTREE_CITY 11
+#define MAPSEC_LILYCOVE_CITY 12
+#define MAPSEC_MOSSDEEP_CITY 13
+#define MAPSEC_SOOTOPOLIS_CITY 14
+#define MAPSEC_EVER_GRANDE_CITY 15
+#define MAPSEC_ROUTE_101 0x10
+#define MAPSEC_ROUTE_102 0x11
+#define MAPSEC_ROUTE_103 0x12
+#define MAPSEC_ROUTE_104 0x13
+#define MAPSEC_ROUTE_105 0x14
+#define MAPSEC_ROUTE_106 0x15
+#define MAPSEC_ROUTE_107 0x16
+#define MAPSEC_ROUTE_108 0x17
+#define MAPSEC_ROUTE_109 0x18
+#define MAPSEC_ROUTE_110 0x19
+#define MAPSEC_ROUTE_111 0x1A
+#define MAPSEC_ROUTE_112 0x1B
+#define MAPSEC_ROUTE_113 0x1C
+#define MAPSEC_ROUTE_114 0x1D
+#define MAPSEC_ROUTE_115 0x1E
+#define MAPSEC_ROUTE_116 0x1F
+#define MAPSEC_ROUTE_117 0x20
+#define MAPSEC_ROUTE_118 0x21
+#define MAPSEC_ROUTE_119 0x22
+#define MAPSEC_ROUTE_120 0x23
+#define MAPSEC_ROUTE_121 0x24
+#define MAPSEC_ROUTE_122 0x25
+#define MAPSEC_ROUTE_123 0x26
+#define MAPSEC_ROUTE_124 0x27
+#define MAPSEC_ROUTE_125 0x28
+#define MAPSEC_ROUTE_126 0x29
+#define MAPSEC_ROUTE_127 0x2A
+#define MAPSEC_ROUTE_128 0x2B
+#define MAPSEC_ROUTE_129 0x2C
+#define MAPSEC_ROUTE_130 0x2D
+#define MAPSEC_ROUTE_131 0x2E
+#define MAPSEC_ROUTE_132 0x2F
+#define MAPSEC_ROUTE_133 0x30
+#define MAPSEC_ROUTE_134 0x31
+#define MAPSEC_UNDERWATER1 0x32
+#define MAPSEC_UNDERWATER2 0x33
+#define MAPSEC_UNDERWATER3 0x34
+#define MAPSEC_UNDERWATER4 0x35
+#define MAPSEC_UNDERWATER5 0x36
+#define MAPSEC_GRANITE_CAVE 0x37
+#define MAPSEC_MT_CHIMNEY 0x38
+#define MAPSEC_SAFARI_ZONE 0x39
+#define MAPSEC_BATTLE_TOWER 0x3A
+#define MAPSEC_PETALBURG_WOODS 0x3B
+#define MAPSEC_RUSTURF_TUNNEL 0x3C
+#define MAPSEC_ABANDONED_SHIP 0x3D
+#define MAPSEC_NEW_MAUVILLE 0x3E
+#define MAPSEC_METEOR_FALLS_1 0x3F
+#define MAPSEC_METEOR_FALLS_2 0x40
+#define MAPSEC_MT_PYRE 0x41
+#define MAPSEC_EVIL_TEAM_HIDEOUT 0x42
+#define MAPSEC_SHOAL_CAVE 0x43
+#define MAPSEC_SEAFLOOR_CAVERN 0x44
+#define MAPSEC_UNDERWATER6 0x45
+#define MAPSEC_VICTORY_ROAD 0x46
+#define MAPSEC_MIRAGE_ISLAND 0x47
+#define MAPSEC_CAVE_OF_ORIGIN 0x48
+#define MAPSEC_SOUTHERN_ISLAND 0x49
+#define MAPSEC_FIERY_PATH_1 0x4A
+#define MAPSEC_FIERY_PATH_2 0x4B
+#define MAPSEC_JAGGED_PASS_1 0x4C
+#define MAPSEC_JAGGED_PASS_2 0x4D
+#define MAPSEC_SEALED_CHAMBER 0x4E
+#define MAPSEC_UNDERWATER7 0x4F
+#define MAPSEC_SCORCHED_SLAB 0x50
+#define MAPSEC_ISLAND_CAVE 0x51
+#define MAPSEC_DESERT_RUINS 0x52
+#define MAPSEC_ANCIENT_TOMB 0x53
+#define MAPSEC_INSIDE_OF_TRUCK 0x54
+#define MAPSEC_SKY_PILLAR 0x55
+#define MAPSEC_SECRET_BASE 0x56
+#define MAPSEC_UNK_0x57 0x57
+#define MAPSEC_NONE 0x58
+
+#define MAP_WIDTH 28
+#define MAP_HEIGHT 15
+#define MAPCURSOR_X_MIN 1
+#define MAPCURSOR_Y_MIN 2
+#define MAPCURSOR_X_MAX (MAPCURSOR_X_MIN + MAP_WIDTH - 1)
+#define MAPCURSOR_Y_MAX (MAPCURSOR_Y_MIN + MAP_HEIGHT - 1)
+
+// Input events
+enum
+{
+ INPUT_EVENT_NONE,
+ INPUT_EVENT_DPAD,
+ INPUT_EVENT_2,
+ INPUT_EVENT_3,
+ INPUT_EVENT_A_BUTTON,
+ INPUT_EVENT_B_BUTTON,
+};
+
+static EWRAM_DATA struct RegionMap *gRegionMap = NULL;
+
+static const u16 sRegionMapCursor_Pal[] = INCBIN_U16("graphics/pokenav/cursor.gbapal");
+static const u8 sRegionMapCursorSmall_ImageLZ[] = INCBIN_U8("graphics/pokenav/cursor_small.4bpp.lz");
+static const u8 sRegionMapCursorLarge_ImageLZ[] = INCBIN_U8("graphics/pokenav/cursor_large.4bpp.lz");
+static const u16 sRegionMapBrendanIcon_Pal[] = INCBIN_U16("graphics/pokenav/brendan_icon.gbapal");
+static const u8 sRegionMapBrendanIcon_Image[] = INCBIN_U8("graphics/pokenav/brendan_icon.4bpp");
+static const u16 sRegionMapMayIcon_Pal[] = INCBIN_U16("graphics/pokenav/may_icon.gbapal");
+static const u8 sRegionMapMayIcon_Image[] = INCBIN_U8("graphics/pokenav/may_icon.4bpp");
+static const u16 sRegionMapBkgnd_Pal[] = INCBIN_U16("graphics/pokenav/region_map.gbapal");
+static const u8 sRegionMapBkgnd_ImageLZ[] = INCBIN_U8("graphics/pokenav/region_map.8bpp.lz");
+static const u8 sRegionMapBkgnd_TilemapLZ[] = INCBIN_U8("graphics/pokenav/region_map_map.bin.lz");
+
+#include "../data/region_map_layout.h"
+
+#if ENGLISH
+#include "../data/region_map_names_en.h"
+#elif GERMAN
+#include "../data/region_map_names_de.h"
+#endif
+
+struct RegionMapLocation
+{
+ u8 x, y;
+ u8 width, height;
+ const u8 *regionMapSectionId;
+};
+
+const struct RegionMapLocation gRegionMapLocations[] =
+{
+ { 4, 11, 1, 1, gMapName_LittlerootTown},
+ { 4, 9, 1, 1, gMapName_OldaleTown},
+ { 2, 14, 1, 1, gMapName_DewfordTown},
+ { 5, 3, 1, 1, gMapName_LavaridgeTown},
+ { 3, 0, 1, 1, gMapName_FallarborTown},
+ { 4, 6, 1, 1, gMapName_VerdanturfTown},
+ {17, 10, 1, 1, gMapName_PacifidlogTown},
+ { 1, 9, 1, 1, gMapName_PetalburgCity},
+ { 8, 10, 1, 2, gMapName_SlateportCity},
+ { 8, 6, 2, 1, gMapName_MauvilleCity},
+ { 0, 5, 1, 2, gMapName_RustboroCity},
+ {12, 0, 1, 1, gMapName_FortreeCity},
+ {18, 3, 2, 1, gMapName_LilycoveCity},
+ {24, 5, 2, 1, gMapName_MossdeepCity},
+ {21, 7, 1, 1, gMapName_SootopolisCity},
+ {27, 8, 1, 2, gMapName_EverGrandeCity},
+ { 4, 10, 1, 1, gMapName_Route101},
+ { 2, 9, 2, 1, gMapName_Route102},
+ { 4, 8, 4, 1, gMapName_Route103},
+ { 0, 7, 1, 3, gMapName_Route104},
+ { 0, 10, 1, 3, gMapName_Route105},
+ { 0, 13, 2, 1, gMapName_Route106},
+ { 3, 14, 3, 1, gMapName_Route107},
+ { 6, 14, 2, 1, gMapName_Route108},
+ { 8, 12, 1, 3, gMapName_Route109},
+ { 8, 7, 1, 3, gMapName_Route110},
+ { 8, 0, 1, 6, gMapName_Route111},
+ { 6, 3, 2, 1, gMapName_Route112},
+ { 4, 0, 4, 1, gMapName_Route113},
+ { 1, 0, 2, 3, gMapName_Route114},
+ { 0, 2, 1, 3, gMapName_Route115},
+ { 1, 5, 4, 1, gMapName_Route116},
+ { 5, 6, 3, 1, gMapName_Route117},
+ {10, 6, 2, 1, gMapName_Route118},
+ {11, 0, 1, 6, gMapName_Route119},
+ {13, 0, 1, 4, gMapName_Route120},
+ {14, 3, 4, 1, gMapName_Route121},
+ {16, 4, 1, 2, gMapName_Route122},
+ {12, 6, 5, 1, gMapName_Route123},
+ {20, 3, 4, 3, gMapName_Route124},
+ {24, 3, 2, 2, gMapName_Route125},
+ {20, 6, 3, 3, gMapName_Route126},
+ {23, 6, 3, 3, gMapName_Route127},
+ {23, 9, 4, 1, gMapName_Route128},
+ {24, 10, 2, 1, gMapName_Route129},
+ {21, 10, 3, 1, gMapName_Route130},
+ {18, 10, 3, 1, gMapName_Route131},
+ {15, 10, 2, 1, gMapName_Route132},
+ {12, 10, 3, 1, gMapName_Route133},
+ { 9, 10, 3, 1, gMapName_Route134},
+ {20, 3, 4, 3, gMapName_Underwater},
+ {20, 6, 3, 3, gMapName_Underwater},
+ {23, 6, 3, 3, gMapName_Underwater},
+ {23, 9, 4, 1, gMapName_Underwater},
+ {21, 7, 1, 1, gMapName_Underwater},
+ { 1, 13, 1, 1, gMapName_GraniteCave},
+ { 6, 2, 1, 1, gMapName_MtChimney},
+ {16, 2, 1, 1, gMapName_SafariZone},
+ {22, 12, 1, 1, gMapName_BattleTower},
+ { 0, 8, 1, 1, gMapName_PetalburgWoods},
+ { 2, 5, 1, 1, gMapName_RusturfTunnel},
+ { 6, 14, 1, 1, gMapName_AbandonedShip},
+ { 8, 7, 1, 1, gMapName_NewMauville},
+ { 0, 3, 1, 1, gMapName_MeteorFalls},
+ { 1, 2, 1, 1, gMapName_MeteorFalls},
+ {16, 4, 1, 1, gMapName_MtPyre},
+ {19, 3, 1, 1, gMapName_EvilTeamHideout},
+ {24, 4, 1, 1, gMapName_ShoalCave},
+ {24, 9, 1, 1, gMapName_SeafloorCavern},
+ {24, 9, 1, 1, gMapName_Underwater},
+ {27, 9, 1, 1, gMapName_VictoryRoad},
+ {17, 10, 1, 1, gMapName_MirageIsland},
+ {21, 7, 1, 1, gMapName_CaveOfOrigin},
+ {12, 14, 1, 1, gMapName_SouthernIsland},
+ { 6, 3, 1, 1, gMapName_FieryPath},
+ { 7, 3, 1, 1, gMapName_FieryPath},
+ { 6, 3, 1, 1, gMapName_JaggedPass},
+ { 7, 2, 1, 1, gMapName_JaggedPass},
+ {11, 10, 1, 1, gMapName_SealedChamber},
+ {11, 10, 1, 1, gMapName_Underwater},
+ {13, 0, 1, 1, gMapName_ScorchedSlab},
+ {0, 10, 1, 1, gMapName_IslandCave},
+ { 8, 3, 1, 1, gMapName_DesertRuins},
+ {13, 2, 1, 1, gMapName_AncientTomb},
+ { 0, 0, 1, 1, gMapName_InsideOfTruck},
+ {19, 10, 1, 1, gMapName_SkyPillar},
+ { 0, 0, 1, 1, gMapName_SecretBase},
+ { 0, 0, 1, 1, gMapName_None},
+};
+
+static const u16 gUnknown_083E7684[][2] =
+{
+ {MAPSEC_UNDERWATER1, MAPSEC_ROUTE_124},
+ {MAPSEC_UNDERWATER2, MAPSEC_ROUTE_126},
+ {MAPSEC_UNDERWATER3, MAPSEC_ROUTE_127},
+ {MAPSEC_UNDERWATER4, MAPSEC_ROUTE_128},
+ {MAPSEC_UNDERWATER5, MAPSEC_SOOTOPOLIS_CITY},
+ {MAPSEC_UNDERWATER6, MAPSEC_ROUTE_128},
+ {MAPSEC_EVIL_TEAM_HIDEOUT, MAPSEC_LILYCOVE_CITY},
+ {MAPSEC_UNDERWATER7, MAPSEC_ROUTE_134},
+ {MAPSEC_PETALBURG_WOODS, MAPSEC_ROUTE_104},
+ {MAPSEC_JAGGED_PASS_1, MAPSEC_ROUTE_112},
+ {MAPSEC_MT_PYRE, MAPSEC_ROUTE_122},
+ {MAPSEC_SKY_PILLAR, MAPSEC_ROUTE_131},
+ {MAPSEC_NONE, MAPSEC_NONE},
+};
+
+static u8 sub_80FAB78(void);
+static u8 _swiopen(void);
+static u8 sub_80FAD04(void);
+static u8 sub_80FADE4(void);
+static void CalcZoomScrollParams(s16, s16, s16, s16, u16, u16, u8);
+static void sub_80FB238(s16, s16);
+void UpdateRegionMapVideoRegs(void);
+static u16 GetRegionMapSectionAt(u16, u16);
+static void InitializeCursorPosition(void);
+static void sub_80FB600(void);
+static u16 sub_80FB758(u16);
+static u16 sub_80FB9C0(u16);
+static void sub_80FBA18(void);
+static bool8 sub_80FBAA0(u16);
+void CreateRegionMapCursor(u16, u16);
+static void sub_80FBCA0(void);
+static void sub_80FBDF8(void);
+static void sub_80FBE24(void);
+static void SpriteCB_PlayerIconZoomedOut(struct Sprite *);
+static void UpdateIconBlink(struct Sprite *);
+static void SpriteCB_PlayerIconZoomedIn(struct Sprite *);
+const u8 *GetMapSectionName(u8 *, u16, u16);
+static void VBlankCB_FlyRegionMap(void);
+static void CB2_FlyRegionMap(void);
+static void sub_80FC244(void (*func)(void));
+static void PrintFlyTargetName(void);
+static void CreateFlyTargetGraphics(void);
+static void CreateCityTownFlyTargetIcons(void);
+static void CreateSpecialAreaFlyTargetIcons(void);
+static void SpriteCB_FlyTargetIcons(struct Sprite *);
+static void sub_80FC5B4(void);
+static void sub_80FC600(void);
+static void sub_80FC69C(void);
+
+void InitRegionMap(struct RegionMap *regionMap, bool8 zoomed)
+{
+ sub_80FA904(regionMap, zoomed);
+ while (sub_80FA940())
+ ;
+}
+
+void sub_80FA904(struct RegionMap *regionMap, bool8 zoomed)
+{
+ gRegionMap = regionMap;
+ gRegionMap->initStep = 0;
+ gRegionMap->zoomed = zoomed;
+ gRegionMap->inputCallback = (zoomed == 0) ? sub_80FAB78 : sub_80FAD04;
+}
+
+bool8 sub_80FA940(void)
+{
+ switch (gRegionMap->initStep)
+ {
+ case 0:
+ LZ77UnCompVram(sRegionMapBkgnd_ImageLZ, (void *)(VRAM + 0x8000));
+ break;
+ case 1:
+ LZ77UnCompVram(sRegionMapBkgnd_TilemapLZ, (void *)(VRAM + 0xE000));
+ break;
+ case 2:
+ LoadPalette(sRegionMapBkgnd_Pal, 0x70, 0x60); // Why isn't this the right size?
+ break;
+ case 3:
+ LZ77UnCompWram(sRegionMapCursorSmall_ImageLZ, gRegionMap->cursorSmallImage);
+ break;
+ case 4:
+ LZ77UnCompWram(sRegionMapCursorLarge_ImageLZ, gRegionMap->cursorLargeImage);
+ break;
+ case 5:
+ InitializeCursorPosition();
+ gRegionMap->unk74 = gRegionMap->cursorPosX;
+ gRegionMap->unk76 = gRegionMap->cursorPosY;
+ gRegionMap->unk16 = sub_80FB758(gRegionMap->mapSecId);
+ gRegionMap->mapSecId = sub_80FB9C0(gRegionMap->mapSecId);
+ GetMapSectionName(gRegionMap->mapSecName, gRegionMap->mapSecId, 16);
+ break;
+ case 6:
+ if (gRegionMap->zoomed == FALSE)
+ {
+ CalcZoomScrollParams(0, 0, 0, 0, 0x100, 0x100, 0);
+ }
+ else
+ {
+ gRegionMap->scrollX = gRegionMap->cursorPosX * 8 - 52;
+ gRegionMap->scrollY = gRegionMap->cursorPosY * 8 - 68;
+ gRegionMap->unk64 = gRegionMap->cursorPosX;
+ gRegionMap->unk66 = gRegionMap->cursorPosY;
+ CalcZoomScrollParams(gRegionMap->scrollX, gRegionMap->scrollY, 0x38, 0x48, 0x80, 0x80, 0);
+ }
+ break;
+ case 7:
+ sub_80FBA18();
+ UpdateRegionMapVideoRegs();
+ gRegionMap->cursorSprite = NULL;
+ gRegionMap->playerIconSprite = NULL;
+ gRegionMap->unk7A = 0;
+ gRegionMap->blinkPlayerIcon = FALSE;
+ REG_BG2CNT = 0xBC8A;
+ gRegionMap->initStep++;
+ default:
+ return FALSE;
+ }
+ gRegionMap->initStep++;
+ return TRUE;
+}
+
+void FreeRegionMapIconResources(void)
+{
+ if (gRegionMap->cursorSprite != NULL)
+ {
+ DestroySprite(gRegionMap->cursorSprite);
+ FreeSpriteTilesByTag(gRegionMap->cursorTileTag);
+ FreeSpritePaletteByTag(gRegionMap->cursorPaletteTag);
+ }
+ if (gRegionMap->playerIconSprite != NULL)
+ {
+ DestroySprite(gRegionMap->playerIconSprite);
+ FreeSpriteTilesByTag(gRegionMap->playerIconTileTag);
+ FreeSpritePaletteByTag(gRegionMap->playerIconPaletteTag);
+ }
+}
+
+u8 sub_80FAB60(void)
+{
+ return gRegionMap->inputCallback();
+}
+
+static u8 sub_80FAB78(void)
+{
+ u8 event = INPUT_EVENT_NONE;
+
+ gRegionMap->cursorDeltaX = 0;
+ gRegionMap->cursorDeltaY = 0;
+ if ((gMain.heldKeys & DPAD_UP) && gRegionMap->cursorPosY > MAPCURSOR_Y_MIN)
+ {
+ gRegionMap->cursorDeltaY = -1;
+ event = INPUT_EVENT_DPAD;
+ }
+ if ((gMain.heldKeys & DPAD_DOWN) && gRegionMap->cursorPosY < MAPCURSOR_Y_MAX)
+ {
+ gRegionMap->cursorDeltaY = 1;
+ event = INPUT_EVENT_DPAD;
+ }
+ if ((gMain.heldKeys & DPAD_LEFT) && gRegionMap->cursorPosX > MAPCURSOR_X_MIN)
+ {
+ gRegionMap->cursorDeltaX = -1;
+ event = INPUT_EVENT_DPAD;
+ }
+ if ((gMain.heldKeys & DPAD_RIGHT) && gRegionMap->cursorPosX < MAPCURSOR_X_MAX)
+ {
+ gRegionMap->cursorDeltaX = 1;
+ event = INPUT_EVENT_DPAD;
+ }
+
+ if (gMain.newKeys & A_BUTTON)
+ event = INPUT_EVENT_A_BUTTON;
+ else if (gMain.newKeys & B_BUTTON)
+ event = INPUT_EVENT_B_BUTTON;
+
+ if (event == INPUT_EVENT_DPAD)
+ {
+ gRegionMap->unk7A = 4;
+ gRegionMap->inputCallback = _swiopen;
+ }
+ return event;
+}
+
+static u8 _swiopen(void)
+{
+ u16 mapSecId;
+
+ if (gRegionMap->unk7A != 0)
+ return INPUT_EVENT_2;
+
+ if (gRegionMap->cursorDeltaX > 0)
+ gRegionMap->cursorPosX++;
+
+ if (gRegionMap->cursorDeltaX < 0)
+ gRegionMap->cursorPosX--;
+
+ if (gRegionMap->cursorDeltaY > 0)
+ gRegionMap->cursorPosY++;
+
+ if (gRegionMap->cursorDeltaY < 0)
+ gRegionMap->cursorPosY--;
+
+ mapSecId = GetRegionMapSectionAt(gRegionMap->cursorPosX, gRegionMap->cursorPosY);
+ gRegionMap->unk16 = sub_80FB758(mapSecId);
+ if (mapSecId != gRegionMap->mapSecId)
+ {
+ gRegionMap->mapSecId = mapSecId;
+ GetMapSectionName(gRegionMap->mapSecName, gRegionMap->mapSecId, 16);
+ }
+ sub_80FBA18();
+ gRegionMap->inputCallback = sub_80FAB78;
+ return INPUT_EVENT_3;
+}
+
+static u8 sub_80FAD04(void)
+{
+ u8 event = INPUT_EVENT_NONE;
+
+ gRegionMap->unk6A = 0;
+ gRegionMap->unk68 = 0;
+ if ((gMain.heldKeys & DPAD_UP) && gRegionMap->scrollY > -52)
+ {
+ gRegionMap->unk68 = -1;
+ event = INPUT_EVENT_DPAD;
+ }
+ if ((gMain.heldKeys & DPAD_DOWN) && gRegionMap->scrollY < 60)
+ {
+ gRegionMap->unk68 = 1;
+ event = INPUT_EVENT_DPAD;
+ }
+ if ((gMain.heldKeys & DPAD_LEFT) && gRegionMap->scrollX > -44)
+ {
+ gRegionMap->unk6A = -1;
+ event = INPUT_EVENT_DPAD;
+ }
+ if ((gMain.heldKeys & DPAD_RIGHT) && gRegionMap->scrollX < 172)
+ {
+ gRegionMap->unk6A = 1;
+ event = INPUT_EVENT_DPAD;
+ }
+
+ if (gMain.newKeys & A_BUTTON)
+ event = INPUT_EVENT_A_BUTTON;
+ if (gMain.newKeys & B_BUTTON)
+ event = INPUT_EVENT_B_BUTTON;
+
+ if (event == INPUT_EVENT_DPAD)
+ {
+ gRegionMap->inputCallback = sub_80FADE4;
+ gRegionMap->unk6C = 0;
+ }
+ return event;
+}
+
+static u8 sub_80FADE4(void)
+{
+ gRegionMap->scrollY += gRegionMap->unk68;
+ gRegionMap->scrollX += gRegionMap->unk6A;
+ sub_80FB238(gRegionMap->scrollX, gRegionMap->scrollY);
+ gRegionMap->unk6C++;
+ if (gRegionMap->unk6C == 8)
+ {
+ u16 r3 = (gRegionMap->scrollX + 44) / 8 + 1;
+ u16 r1 = (gRegionMap->scrollY + 52) / 8 + 2;
+
+ if (r3 != gRegionMap->unk64 || r1 != gRegionMap->unk66)
+ {
+ u16 mapSecId;
+
+ gRegionMap->unk64 = r3;
+ gRegionMap->unk66 = r1;
+ mapSecId = GetRegionMapSectionAt(r3, r1);
+ gRegionMap->unk16 = sub_80FB758(mapSecId);
+ if (mapSecId != gRegionMap->mapSecId)
+ {
+ gRegionMap->mapSecId = mapSecId;
+ GetMapSectionName(gRegionMap->mapSecName, gRegionMap->mapSecId, 16);
+ }
+ sub_80FBA18();
+ }
+ gRegionMap->unk6C = 0;
+ gRegionMap->inputCallback = sub_80FAD04;
+ return INPUT_EVENT_3;
+ }
+ return INPUT_EVENT_2;
+}
+
+void sub_80FAEC4(void)
+{
+ if (gRegionMap->zoomed == FALSE)
+ {
+ gRegionMap->scrollY = 0;
+ gRegionMap->scrollX = 0;
+ gRegionMap->unk40 = 0;
+ gRegionMap->unk3C = 0;
+ gRegionMap->unk60 = gRegionMap->cursorPosX * 8 - 52;
+ gRegionMap->unk62 = gRegionMap->cursorPosY * 8 - 68;
+ gRegionMap->unk44 = (gRegionMap->unk60 << 8) / 16;
+ gRegionMap->unk48 = (gRegionMap->unk62 << 8) / 16;
+ gRegionMap->unk64 = gRegionMap->cursorPosX;
+ gRegionMap->unk66 = gRegionMap->cursorPosY;
+ gRegionMap->unk4C = (256 << 8);
+ gRegionMap->unk50 = -0x800;
+ }
+ else
+ {
+ gRegionMap->unk3C = gRegionMap->scrollX * 256;
+ gRegionMap->unk40 = gRegionMap->scrollY * 256;
+ gRegionMap->unk60 = 0;
+ gRegionMap->unk62 = 0;
+ gRegionMap->unk44 = -(gRegionMap->unk3C / 16);
+ gRegionMap->unk48 = -(gRegionMap->unk40 / 16);
+ gRegionMap->cursorPosX = gRegionMap->unk64;
+ gRegionMap->cursorPosY = gRegionMap->unk66;
+ gRegionMap->unk4C = (128 << 8);
+ gRegionMap->unk50 = 0x800;
+ }
+ gRegionMap->unk6E = 0;
+ sub_80FBCA0();
+ sub_80FBDF8();
+}
+
+u8 sub_80FAFC0(void)
+{
+ u8 r4;
+
+ if (gRegionMap->unk6E >= 16)
+ return 0;
+ gRegionMap->unk6E++;
+ if (gRegionMap->unk6E == 16)
+ {
+ gRegionMap->unk44 = 0;
+ gRegionMap->unk48 = 0;
+ gRegionMap->scrollX = gRegionMap->unk60;
+ gRegionMap->scrollY = gRegionMap->unk62;
+ gRegionMap->unk4C = (gRegionMap->zoomed == FALSE) ? (128 << 8) : (256 << 8);
+ gRegionMap->zoomed = !gRegionMap->zoomed;
+ gRegionMap->inputCallback = (gRegionMap->zoomed == FALSE) ? sub_80FAB78 : sub_80FAD04;
+ CreateRegionMapCursor(gRegionMap->cursorTileTag, gRegionMap->cursorPaletteTag);
+ sub_80FBE24();
+ r4 = 0;
+ }
+ else
+ {
+ gRegionMap->unk3C += gRegionMap->unk44;
+ gRegionMap->unk40 += gRegionMap->unk48;
+ gRegionMap->scrollX = gRegionMap->unk3C >> 8;
+ gRegionMap->scrollY = gRegionMap->unk40 >> 8;
+ gRegionMap->unk4C += gRegionMap->unk50;
+ if ((gRegionMap->unk44 < 0 && gRegionMap->scrollX < gRegionMap->unk60)
+ || (gRegionMap->unk44 > 0 && gRegionMap->scrollX > gRegionMap->unk60))
+ {
+ gRegionMap->scrollX = gRegionMap->unk60;
+ gRegionMap->unk44 = 0;
+ }
+ if ((gRegionMap->unk48 < 0 && gRegionMap->scrollY < gRegionMap->unk62)
+ || (gRegionMap->unk48 > 0 && gRegionMap->scrollY > gRegionMap->unk62))
+ {
+ gRegionMap->scrollY = gRegionMap->unk62;
+ gRegionMap->unk48 = 0;
+ }
+ if (gRegionMap->zoomed == FALSE)
+ {
+ if (gRegionMap->unk4C < (128 << 8))
+ {
+ gRegionMap->unk4C = (128 << 8);
+ gRegionMap->unk50 = 0;
+ }
+ }
+ else
+ {
+ if (gRegionMap->unk4C > (256 << 8))
+ {
+ gRegionMap->unk4C = (256 << 8);
+ gRegionMap->unk50 = 0;
+ }
+ }
+ r4 = 1;
+ }
+ CalcZoomScrollParams(gRegionMap->scrollX, gRegionMap->scrollY, 0x38, 0x48, gRegionMap->unk4C >> 8, gRegionMap->unk4C >> 8, 0);
+ return r4;
+}
+
+static void CalcZoomScrollParams(s16 a, s16 b, s16 c, s16 d, u16 e, u16 f, u8 rotation)
+{
+ s32 var1;
+ s32 var2;
+ s32 var3;
+ s32 var4;
+
+ gRegionMap->unk2C = e * gSineTable[rotation + 64] >> 8;
+ gRegionMap->unk30 = e * -gSineTable[rotation] >> 8;
+ gRegionMap->unk34 = f * gSineTable[rotation] >> 8;
+ gRegionMap->unk38 = f * gSineTable[rotation + 64] >> 8;
+
+ var1 = (a << 8) + (c << 8);
+ var2 = d * gRegionMap->unk34 + gRegionMap->unk2C * c;
+ gRegionMap->bg2x = var1 - var2;
+
+ var3 = (b << 8) + (d << 8);
+ var4 = gRegionMap->unk38 * d + gRegionMap->unk30 * c;
+ gRegionMap->bg2y = var3 - var4;
+
+ gRegionMap->needUpdateVideoRegs = TRUE;
+}
+
+static void sub_80FB238(s16 x, s16 y)
+{
+ gRegionMap->bg2x = (0x1C << 8) + (x << 8);
+ gRegionMap->bg2y = (0x24 << 8) + (y << 8);
+ gRegionMap->needUpdateVideoRegs = TRUE;
+}
+
+void UpdateRegionMapVideoRegs(void)
+{
+ if (gRegionMap->needUpdateVideoRegs)
+ {
+ REG_BG2PA = gRegionMap->unk2C;
+ REG_BG2PB = gRegionMap->unk34;
+ REG_BG2PC = gRegionMap->unk30;
+ REG_BG2PD = gRegionMap->unk38;
+ REG_BG2X = gRegionMap->bg2x;
+ REG_BG2Y = gRegionMap->bg2y;
+ gRegionMap->needUpdateVideoRegs = FALSE;
+ }
+}
+
+void sub_80FB2A4(s16 a, s16 b)
+{
+ CalcZoomScrollParams(a, b, 0x38, 0x48, 0x100, 0x100, 0);
+ UpdateRegionMapVideoRegs();
+ if (gRegionMap->playerIconSprite != NULL)
+ {
+ gRegionMap->playerIconSprite->pos2.x = -a;
+ gRegionMap->playerIconSprite->pos2.y = -b;
+ }
+}
+
+static u16 GetRegionMapSectionAt(u16 x, u16 y)
+{
+ if (y < MAPCURSOR_Y_MIN || y > MAPCURSOR_Y_MAX || x < MAPCURSOR_X_MIN || x > MAPCURSOR_X_MAX)
+ return MAPSEC_NONE;
+ y -= MAPCURSOR_Y_MIN;
+ x -= MAPCURSOR_X_MIN;
+ return sRegionMapLayout[x + y * 28];
+}
+
+static void InitializeCursorPosition(void)
+{
+ struct MapHeader *mapHeader;
+ u16 mapWidth;
+ u16 mapHeight;
+ u16 x;
+ u16 y;
+ u16 r1;
+ u16 r9;
+
+ if (gSaveBlock1.location.mapGroup == 25
+ && (gSaveBlock1.location.mapNum == MAP_ID_SS_TIDAL_CORRIDOR
+ || gSaveBlock1.location.mapNum == MAP_ID_SS_TIDAL_LOWER_DECK
+ || gSaveBlock1.location.mapNum == MAP_ID_SS_TIDAL_ROOMS))
+ {
+ sub_80FB600();
+ return;
+ }
+
+ switch (GetMapTypeByGroupAndId(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum) - 1)
+ {
+ default:
+ case 0:
+ case 1:
+ case 2:
+ case 4:
+ case 5:
+ gRegionMap->mapSecId = gMapHeader.regionMapSectionId;
+ gRegionMap->playerIsInCave = FALSE;
+ mapWidth = gMapHeader.mapData->width;
+ mapHeight = gMapHeader.mapData->height;
+ x = gSaveBlock1.pos.x;
+ y = gSaveBlock1.pos.y;
+ if (gRegionMap->mapSecId == MAPSEC_UNDERWATER6)
+ gRegionMap->playerIsInCave = TRUE;
+ break;
+ case 3:
+ case 6:
+ mapHeader = Overworld_GetMapHeaderByGroupAndId(gSaveBlock1.warp4.mapGroup, gSaveBlock1.warp4.mapNum);
+ gRegionMap->mapSecId = mapHeader->regionMapSectionId;
+ gRegionMap->playerIsInCave = TRUE;
+ mapWidth = mapHeader->mapData->width;
+ mapHeight = mapHeader->mapData->height;
+ x = gSaveBlock1.warp4.x;
+ y = gSaveBlock1.warp4.y;
+ break;
+ case 8:
+ mapHeader = Overworld_GetMapHeaderByGroupAndId(gSaveBlock1.warp2.mapGroup, gSaveBlock1.warp2.mapNum);
+ gRegionMap->mapSecId = mapHeader->regionMapSectionId;
+ gRegionMap->playerIsInCave = TRUE;
+ mapWidth = mapHeader->mapData->width;
+ mapHeight = mapHeader->mapData->height;
+ x = gSaveBlock1.warp2.x;
+ y = gSaveBlock1.warp2.y;
+ break;
+ case 7:
+ {
+ struct WarpData *r4;
+
+ gRegionMap->mapSecId = gMapHeader.regionMapSectionId;
+ if (gRegionMap->mapSecId != MAPSEC_UNK_0x57)
+ {
+ r4 = &gSaveBlock1.warp4;
+ mapHeader = Overworld_GetMapHeaderByGroupAndId(r4->mapGroup, r4->mapNum);
+ }
+ else
+ {
+ r4 = &gSaveBlock1.warp2;
+ mapHeader = Overworld_GetMapHeaderByGroupAndId(r4->mapGroup, r4->mapNum);
+ gRegionMap->mapSecId = mapHeader->regionMapSectionId;
+ }
+ gRegionMap->playerIsInCave = FALSE;
+ mapWidth = mapHeader->mapData->width;
+ mapHeight = mapHeader->mapData->height;
+ x = r4->x;
+ y = r4->y;
+ }
+ break;
+ }
+
+ r9 = x;
+
+ r1 = mapWidth / gRegionMapLocations[gRegionMap->mapSecId].width;
+ if (r1 == 0)
+ r1 = 1;
+ x /= r1;
+ if (x >= gRegionMapLocations[gRegionMap->mapSecId].width)
+ x = gRegionMapLocations[gRegionMap->mapSecId].width - 1;
+
+ r1 = mapHeight / gRegionMapLocations[gRegionMap->mapSecId].height;
+ if (r1 == 0)
+ r1 = 1;
+ y /= r1;
+ if (y >= gRegionMapLocations[gRegionMap->mapSecId].height)
+ y = gRegionMapLocations[gRegionMap->mapSecId].height - 1;
+
+ switch (gRegionMap->mapSecId)
+ {
+ case MAPSEC_ROUTE_114:
+ if (y != 0)
+ x = 0;
+ break;
+ case MAPSEC_ROUTE_126:
+ case MAPSEC_UNDERWATER2:
+ x = 0;
+ if (gSaveBlock1.pos.x > 32)
+ x = 1;
+ if (gSaveBlock1.pos.x > 0x33)
+ x++;
+ y = 0;
+ if (gSaveBlock1.pos.y > 0x25)
+ y = 1;
+ if (gSaveBlock1.pos.y > 0x38)
+ y++;
+ break;
+ case MAPSEC_ROUTE_121:
+ x = 0;
+ if (r9 > 14)
+ x = 1;
+ if (r9 > 0x1C)
+ x++;
+ if (r9 > 0x36)
+ x++;
+ break;
+ }
+ gRegionMap->cursorPosX = gRegionMapLocations[gRegionMap->mapSecId].x + x + MAPCURSOR_X_MIN;
+ gRegionMap->cursorPosY = gRegionMapLocations[gRegionMap->mapSecId].y + y + MAPCURSOR_Y_MIN;
+}
+
+static void sub_80FB600(void)
+{
+ u16 y = 0;
+ u16 x = 0;
+ u8 mapGroup;
+ u8 mapNum;
+ s16 sp2;
+ s16 sp4;
+
+ switch (GetSSTidalLocation(&mapGroup, &mapNum, &sp2, &sp4))
+ {
+ case 1:
+ gRegionMap->mapSecId = MAPSEC_SLATEPORT_CITY;
+ break;
+ case 2:
+ gRegionMap->mapSecId = MAPSEC_LILYCOVE_CITY;
+ break;
+ case 3:
+ gRegionMap->mapSecId = MAPSEC_ROUTE_124;
+ break;
+ case 4:
+ gRegionMap->mapSecId = MAPSEC_ROUTE_131;
+ break;
+ default:
+ case 0:
+ {
+ struct MapHeader *mapHeader = Overworld_GetMapHeaderByGroupAndId(mapGroup, mapNum);
+ u16 r1;
+
+ gRegionMap->mapSecId = mapHeader->regionMapSectionId;
+ r1 = mapHeader->mapData->width / gRegionMapLocations[gRegionMap->mapSecId].width;
+ if (r1 == 0)
+ r1 = 1;
+ x = sp2 / r1;
+ if (x >= gRegionMapLocations[gRegionMap->mapSecId].width)
+ x = gRegionMapLocations[gRegionMap->mapSecId].width - 1;
+
+ r1 = mapHeader->mapData->height / gRegionMapLocations[gRegionMap->mapSecId].height;
+ if (r1 == 0)
+ r1 = 1;
+ y = sp4 / r1;
+ if (y >= gRegionMapLocations[gRegionMap->mapSecId].height)
+ y = gRegionMapLocations[gRegionMap->mapSecId].height - 1;
+ }
+ break;
+ }
+ gRegionMap->playerIsInCave = FALSE;
+ gRegionMap->cursorPosX = gRegionMapLocations[gRegionMap->mapSecId].x + x + MAPCURSOR_X_MIN;
+ gRegionMap->cursorPosY = gRegionMapLocations[gRegionMap->mapSecId].y + y + MAPCURSOR_Y_MIN;
+}
+
+static u16 sub_80FB758(u16 mapSecId)
+{
+ switch (mapSecId)
+ {
+ case MAPSEC_NONE:
+ return 0;
+ case MAPSEC_LITTLEROOT_TOWN:
+ return FlagGet(FLAG_VISITED_LITTLEROOT_TOWN) ? 2 : 3;
+ case MAPSEC_OLDALE_TOWN:
+ return FlagGet(FLAG_VISITED_OLDALE_TOWN) ? 2 : 3;
+ case MAPSEC_DEWFORD_TOWN:
+ return FlagGet(FLAG_VISITED_DEWFORD_TOWN) ? 2 : 3;
+ case MAPSEC_LAVARIDGE_TOWN:
+ return FlagGet(FLAG_VISITED_LAVARIDGE_TOWN) ? 2 : 3;
+ case MAPSEC_FALLARBOR_TOWN:
+ return FlagGet(FLAG_VISITED_FALLARBOR_TOWN) ? 2 : 3;
+ case MAPSEC_VERDANTURF_TOWN:
+ return FlagGet(FLAG_VISITED_VERDANTURF_TOWN) ? 2 : 3;
+ case MAPSEC_PACIFIDLOG_TOWN:
+ return FlagGet(FLAG_VISITED_PACIFIDLOG_TOWN) ? 2 : 3;
+ case MAPSEC_PETALBURG_CITY:
+ return FlagGet(FLAG_VISITED_PETALBURG_CITY) ? 2 : 3;
+ case MAPSEC_SLATEPORT_CITY:
+ return FlagGet(FLAG_VISITED_SLATEPORT_CITY) ? 2 : 3;
+ case MAPSEC_MAUVILLE_CITY:
+ return FlagGet(FLAG_VISITED_MAUVILLE_CITY) ? 2 : 3;
+ case MAPSEC_RUSTBORO_CITY:
+ return FlagGet(FLAG_VISITED_RUSTBORO_CITY) ? 2 : 3;
+ case MAPSEC_FORTREE_CITY:
+ return FlagGet(FLAG_VISITED_FORTREE_CITY) ? 2 : 3;
+ case MAPSEC_LILYCOVE_CITY:
+ return FlagGet(FLAG_VISITED_LILYCOVE_CITY) ? 2 : 3;
+ case MAPSEC_MOSSDEEP_CITY:
+ return FlagGet(FLAG_VISITED_MOSSDEEP_CITY) ? 2 : 3;
+ case MAPSEC_SOOTOPOLIS_CITY:
+ return FlagGet(FLAG_VISITED_SOOTOPOLIS_CITY) ? 2 : 3;
+ case MAPSEC_EVER_GRANDE_CITY:
+ return FlagGet(FLAG_VISITED_EVER_GRANDE_CITY) ? 2 : 3;
+
+ case MAPSEC_BATTLE_TOWER:
+ return FlagGet(FLAG_UNLOCK_BATTLE_TOWER) ? 4 : 0;
+ case MAPSEC_SOUTHERN_ISLAND:
+ return FlagGet(FLAG_UNLOCK_SOUTHERN_ISLAND) ? 1 : 0;
+ default:
+ return 1;
+ }
+}
+
+u16 GetRegionMapSectionAt_(u16 x, u16 y)
+{
+ return GetRegionMapSectionAt(x, y);
+}
+
+static u16 sub_80FB9C0(u16 mapSecId)
+{
+ u16 i;
+
+ for (i = 0; gUnknown_083E7684[i][0] != MAPSEC_NONE; i++)
+ {
+ if (gUnknown_083E7684[i][0] == mapSecId)
+ return gUnknown_083E7684[i][1];
+ }
+ return mapSecId;
+}
+
+u16 sub_80FBA04(u16 mapSecId)
+{
+ return sub_80FB9C0(mapSecId);
+}
+
+static void sub_80FBA18(void)
+{
+ u16 x;
+ u16 y;
+ u16 i;
+
+ if (gRegionMap->mapSecId == MAPSEC_NONE)
+ {
+ gRegionMap->everGrandeCityArea = 0;
+ return;
+ }
+
+ if (gRegionMap->zoomed == FALSE)
+ {
+ x = gRegionMap->cursorPosX;
+ y = gRegionMap->cursorPosY;
+ }
+ else
+ {
+ x = gRegionMap->unk64;
+ y = gRegionMap->unk66;
+ }
+
+ i = 0;
+ while (1)
+ {
+ if (x <= 1)
+ {
+ if (sub_80FBAA0(y))
+ {
+ y--;
+ x = 0x1D;
+ }
+ else
+ {
+ break;
+ }
+ }
+ else
+ {
+ x--;
+ if (GetRegionMapSectionAt(x, y) == gRegionMap->mapSecId)
+ i++;
+ }
+ }
+
+ gRegionMap->everGrandeCityArea = i;
+}
+
+static bool8 sub_80FBAA0(u16 a)
+{
+ u16 x;
+ u16 y;
+
+ y = a - 1;
+ if (y == 0xFFFF)
+ return FALSE;
+
+ for (x = MAPCURSOR_X_MIN; x <= MAPCURSOR_X_MAX; x++)
+ {
+ if (GetRegionMapSectionAt(x, y) == gRegionMap->mapSecId)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static const struct OamData sCursorOamData =
+{
+ .y = 0,
+ .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 sCursorAnimSeq0[] =
+{
+ ANIMCMD_FRAME(0, 20),
+ ANIMCMD_FRAME(4, 20),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd sCursorAnimSeq1[] =
+{
+ ANIMCMD_FRAME(0, 10),
+ ANIMCMD_FRAME(16, 10),
+ ANIMCMD_FRAME(32, 10),
+ ANIMCMD_FRAME(16, 10),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const sCursorAnimTable[] =
+{
+ sCursorAnimSeq0,
+ sCursorAnimSeq1,
+};
+
+static void SpriteCB_Cursor(struct Sprite *sprite)
+{
+ if (gRegionMap->unk7A != 0)
+ {
+ sprite->pos1.x += gRegionMap->cursorDeltaX * 2;
+ sprite->pos1.y += gRegionMap->cursorDeltaY * 2;
+ gRegionMap->unk7A--;
+ }
+}
+
+static void nullsub_66(struct Sprite *sprite)
+{
+}
+
+void CreateRegionMapCursor(u16 tileTag, u16 paletteTag)
+{
+ u8 spriteId;
+ struct SpriteSheet spriteSheet;
+ struct SpritePalette spritePalette =
+ {
+ .data = sRegionMapCursor_Pal,
+ };
+ struct SpriteTemplate spriteTemplate =
+ {
+ .oam = &sCursorOamData,
+ .anims = sCursorAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCB_Cursor,
+ };
+
+ spriteSheet.tag = tileTag;
+ spriteTemplate.tileTag = tileTag;
+ gRegionMap->cursorTileTag = tileTag;
+
+ spritePalette.tag = paletteTag;
+ spriteTemplate.paletteTag = paletteTag;
+ gRegionMap->cursorPaletteTag = paletteTag;
+
+ if (gRegionMap->zoomed == FALSE)
+ {
+ spriteSheet.data = gRegionMap->cursorSmallImage;
+ spriteSheet.size = 0x100;
+ spriteTemplate.callback = SpriteCB_Cursor;
+ }
+ else
+ {
+ spriteSheet.data = gRegionMap->cursorLargeImage;
+ spriteSheet.size = 0x600;
+ spriteTemplate.callback = nullsub_66;
+ }
+ LoadSpriteSheet(&spriteSheet);
+ LoadSpritePalette(&spritePalette);
+ spriteId = CreateSprite(&spriteTemplate, 0x38, 0x48, 0);
+ if (spriteId != 64)
+ {
+ gRegionMap->cursorSprite = &gSprites[spriteId];
+ if (gRegionMap->zoomed == TRUE)
+ {
+ gRegionMap->cursorSprite->oam.size = 2;
+ gRegionMap->cursorSprite->pos1.x -= 8;
+ gRegionMap->cursorSprite->pos1.y -= 8;
+ StartSpriteAnim(gRegionMap->cursorSprite, 1);
+ }
+ else
+ {
+ gRegionMap->cursorSprite->oam.size = 1;
+ gRegionMap->cursorSprite->pos1.x = gRegionMap->cursorPosX * 8 + 4;
+ gRegionMap->cursorSprite->pos1.y = gRegionMap->cursorPosY * 8 + 4;
+ }
+ gRegionMap->cursorSprite->data1 = 2;
+ gRegionMap->cursorSprite->data2 = IndexOfSpritePaletteTag(paletteTag) * 16 + 0x0101;
+ gRegionMap->cursorSprite->data3 = 1;
+ }
+}
+
+static void sub_80FBCA0(void)
+{
+ if (gRegionMap->cursorSprite != NULL)
+ {
+ DestroySprite(gRegionMap->cursorSprite);
+ FreeSpriteTilesByTag(gRegionMap->cursorTileTag);
+ FreeSpritePaletteByTag(gRegionMap->cursorPaletteTag);
+ }
+}
+
+void unref_sub_80FBCD0(void)
+{
+ gRegionMap->cursorSprite->data3 = 1;
+}
+
+void unref_sub_80FBCE0(void)
+{
+ gRegionMap->cursorSprite->data3 = 0;
+}
+
+static const struct OamData sPlayerIconOamData =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 1,
+ .tileNum = 0,
+ .priority = 2,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const union AnimCmd sPlayerIconAnimSeq0[] =
+{
+ ANIMCMD_FRAME(0, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const sPlayerIconAnimTable[] =
+{
+ sPlayerIconAnimSeq0,
+};
+
+void CreateRegionMapPlayerIcon(u16 tileTag, u16 paletteTag)
+{
+ u8 spriteId;
+ struct SpriteSheet playerIconSpriteSheet =
+ {
+ .data = sRegionMapBrendanIcon_Image,
+ .size = 128,
+ .tag = tileTag,
+ };
+ struct SpritePalette playerIconSpritePalette =
+ {
+ .data = sRegionMapBrendanIcon_Pal,
+ .tag = paletteTag,
+ };
+ struct SpriteTemplate playerIconSpriteTemplate =
+ {
+ .tileTag = tileTag,
+ .paletteTag = paletteTag,
+ .oam = &sPlayerIconOamData,
+ .anims = sPlayerIconAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+ };
+
+ if (gSaveBlock2.playerGender == FEMALE)
+ {
+ playerIconSpriteSheet.data = sRegionMapMayIcon_Image;
+ playerIconSpritePalette.data = sRegionMapMayIcon_Pal;
+ }
+ LoadSpriteSheet(&playerIconSpriteSheet);
+ LoadSpritePalette(&playerIconSpritePalette);
+ spriteId = CreateSprite(&playerIconSpriteTemplate, 0, 0, 1);
+ gRegionMap->playerIconSprite = &gSprites[spriteId];
+ if (gRegionMap->zoomed == FALSE)
+ {
+ gRegionMap->playerIconSprite->pos1.x = gRegionMap->unk74 * 8 + 4;
+ gRegionMap->playerIconSprite->pos1.y = gRegionMap->unk76 * 8 + 4;
+ gRegionMap->playerIconSprite->callback = SpriteCB_PlayerIconZoomedOut;
+ }
+ else
+ {
+ gRegionMap->playerIconSprite->pos1.x = gRegionMap->unk74 * 16 - 48;
+ gRegionMap->playerIconSprite->pos1.y = gRegionMap->unk76 * 16 - 66;
+ gRegionMap->playerIconSprite->callback = SpriteCB_PlayerIconZoomedIn;
+ }
+}
+
+static void sub_80FBDF8(void)
+{
+ if (gRegionMap->playerIconSprite != NULL)
+ {
+ gRegionMap->playerIconSprite->invisible = TRUE;
+ gRegionMap->playerIconSprite->callback = SpriteCallbackDummy;
+ }
+}
+
+static void sub_80FBE24(void)
+{
+ if (gRegionMap->playerIconSprite != NULL)
+ {
+ if (gRegionMap->zoomed == TRUE)
+ {
+ gRegionMap->playerIconSprite->pos1.x = gRegionMap->unk74 * 16 - 48;
+ gRegionMap->playerIconSprite->pos1.y = gRegionMap->unk76 * 16 - 66;
+ gRegionMap->playerIconSprite->callback = SpriteCB_PlayerIconZoomedIn;
+ gRegionMap->playerIconSprite->invisible = FALSE;
+ }
+ else
+ {
+ gRegionMap->playerIconSprite->pos1.x = gRegionMap->unk74 * 8 + 4;
+ gRegionMap->playerIconSprite->pos1.y = gRegionMap->unk76 * 8 + 4;
+ gRegionMap->playerIconSprite->pos2.x = 0;
+ gRegionMap->playerIconSprite->pos2.y = 0;
+ gRegionMap->playerIconSprite->callback = SpriteCB_PlayerIconZoomedOut;
+ gRegionMap->playerIconSprite->invisible = FALSE;
+ }
+ }
+}
+
+static void SpriteCB_PlayerIconZoomedIn(struct Sprite *sprite)
+{
+ sprite->pos2.x = -(gRegionMap->scrollX * 2);
+ sprite->pos2.y = -(gRegionMap->scrollY * 2);
+ sprite->data0 = sprite->pos1.y + sprite->pos2.y + sprite->centerToCornerVecY;
+ sprite->data1 = sprite->pos1.x + sprite->pos2.x + sprite->centerToCornerVecX;
+
+ // Determine if sprite is on screen
+ if (sprite->data0 < -8 || sprite->data0 > 0xA8 || sprite->data1 < -8 || sprite->data1 > 0xF8)
+ sprite->data2 = FALSE;
+ else
+ sprite->data2 = TRUE;
+
+ if (sprite->data2 == TRUE)
+ UpdateIconBlink(sprite);
+ else
+ sprite->invisible = TRUE;
+}
+
+static void SpriteCB_PlayerIconZoomedOut(struct Sprite *sprite)
+{
+ UpdateIconBlink(sprite);
+}
+
+static void UpdateIconBlink(struct Sprite *sprite)
+{
+ if (gRegionMap->blinkPlayerIcon)
+ {
+ // Toggle visibility every 16 frames
+ sprite->data7++;
+ if (sprite->data7 > 16)
+ {
+ sprite->data7 = 0;
+ sprite->invisible = !sprite->invisible;
+ }
+ }
+ else
+ {
+ sprite->invisible = FALSE;
+ }
+}
+
+void sub_80FBF94(void)
+{
+ if (gRegionMap->playerIsInCave)
+ gRegionMap->blinkPlayerIcon = TRUE;
+}
+
+const u8 *GetMapSectionName(u8 *dest, u16 mapSecId, u16 length)
+{
+ if (mapSecId == MAPSEC_SECRET_BASE)
+ return GetSecretBaseMapName(dest);
+ if (mapSecId < MAPSEC_NONE)
+ return StringCopy(dest, gRegionMapLocations[mapSecId].regionMapSectionId);
+ if (length == 0)
+ length = 18;
+ return StringFill(dest, CHAR_SPACE, length);
+}
+
+const u8 *CopyMapName(u8 *dest, u16 mapSecId)
+{
+ switch (mapSecId)
+ {
+ case MAPSEC_UNK_0x57:
+ return StringCopy(dest, gOtherText_Ferry);
+ case MAPSEC_SECRET_BASE:
+ return StringCopy(dest, gOtherText_SecretBase);
+ default:
+ return GetMapSectionName(dest, mapSecId, 0);
+ }
+}
+
+const u8 *CopyLocationName(u8 *dest, u16 mapSecId)
+{
+ if (mapSecId == MAPSEC_EVIL_TEAM_HIDEOUT)
+ return StringCopy(dest, gOtherText_Hideout);
+ else
+ return CopyMapName(dest, mapSecId);
+}
+
+static void GetRegionMapLocationPosition(u16 mapSecId, u16 *x, u16 *y, u16 *width, u16 *height)
+{
+ *x = gRegionMapLocations[mapSecId].x;
+ *y = gRegionMapLocations[mapSecId].y;
+ *width = gRegionMapLocations[mapSecId].width;
+ *height = gRegionMapLocations[mapSecId].height;
+}
+
+struct UnknownStruct3
+{
+ void (*unk0)(void);
+ u16 unk4;
+ u16 unk6;
+ struct RegionMap regionMap;
+};
+
+extern u8 ewram[];
+#define ewram0 (*(struct UnknownStruct3 *)(ewram + 0))
+#define ewram888 (ewram + 0x888)
+#define ewramA6E (ewram[0xA6E])
+#define ewramBlankMapName (ewram + 0xA48)
+
+static const u16 sFlyRegionMapFrame_Pal[] = INCBIN_U16("graphics/pokenav/map_frame.gbapal");
+static const u8 sFlyRegionMapFrame_ImageLZ[] = INCBIN_U8("graphics/pokenav/map_frame.4bpp.lz");
+static const u8 sFlyRegionMapFrame_TilemapLZ[] = INCBIN_U8("graphics/pokenav/map_frame.bin.lz");
+static const u16 sFlyTargetIcons_Pal[] = INCBIN_U16("graphics/pokenav/fly_target_icons.gbapal");
+static const u8 sFlyTargetIcons_ImageLZ[] = INCBIN_U8("graphics/pokenav/fly_target_icons.4bpp.lz");
+
+static const u8 sUnknown_083E7920[][3] =
+{
+ {0, 9, 1},
+ {0, 10, 14},
+ {0, 11, 15},
+ {0, 12, 16},
+ {0, 13, 17},
+ {0, 14, 18},
+ {0, 15, 19},
+ {0, 0, 3},
+ {0, 1, 4},
+ {0, 2, 5},
+ {0, 3, 6},
+ {0, 4, 7},
+ {0, 5, 8},
+ {0, 6, 9},
+ {0, 7, 10},
+ {0, 8, 11},
+ {0, 16, 0},
+ {0, 17, 0},
+ {0, 18, 0},
+ {0, 19, 0},
+ {0, 20, 0},
+ {0, 21, 0},
+ {0, 22, 0},
+ {0, 23, 0},
+ {0, 24, 0},
+ {0, 25, 0},
+ {0, 26, 0},
+ {0, 27, 0},
+ {0, 28, 0},
+ {0, 29, 0},
+ {0, 30, 0},
+ {0, 31, 0},
+ {0, 32, 0},
+ {0, 33, 0},
+ {0, 34, 0},
+ {0, 35, 0},
+ {0, 36, 0},
+ {0, 37, 0},
+ {0, 38, 0},
+ {0, 39, 0},
+ {0, 40, 0},
+ {0, 41, 0},
+ {0, 42, 0},
+ {0, 43, 0},
+ {0, 44, 0},
+ {0, 45, 0},
+ {0, 46, 0},
+ {0, 47, 0},
+ {0, 48, 0},
+ {0, 49, 0},
+};
+
+struct UnknownStruct4
+{
+ const u8 *const *unk0;
+ u16 mapSecId;
+ u16 flag;
+};
+
+static const u8 *const sEverGrandeCityAreaNames[] = {OtherText_PokeLeague, OtherText_PokeCenter};
+
+static const struct UnknownStruct4 sUnknown_083E79C0[1] =
+{
+ {sEverGrandeCityAreaNames, MAPSEC_EVER_GRANDE_CITY, SYS_POKEMON_LEAGUE_FLY},
+};
+
+// XXX: what is this?
+static u8 *const ewram_ = ewram;
+
+static const struct SpritePalette sFlyTargetIconSpritePalette = {sFlyTargetIcons_Pal, 2};
+
+// Fly targets that are not cities or towns
+static const u16 sSpecialFlyAreas[][2] =
+{
+ // flag, mapSecId
+ {0x848, MAPSEC_BATTLE_TOWER},
+ {0xFFFF, MAPSEC_NONE},
+};
+
+static const struct OamData sFlyTargetOamData =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 0,
+ .tileNum = 0,
+ .priority = 2,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const union AnimCmd sFlyTargetAnimSeq0[] =
+{
+ ANIMCMD_FRAME(0, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd sFlyTargetAnimSeq1[] =
+{
+ ANIMCMD_FRAME(1, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd sFlyTargetAnimSeq2[] =
+{
+ ANIMCMD_FRAME(3, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd sFlyTargetAnimSeq3[] =
+{
+ ANIMCMD_FRAME(5, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd sFlyTargetAnimSeq4[] =
+{
+ ANIMCMD_FRAME(6, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd sFlyTargetAnimSeq5[] =
+{
+ ANIMCMD_FRAME(8, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd sFlyTargetAnimSeq6[] =
+{
+ ANIMCMD_FRAME(10, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const sFlyTargetAnimTable[] =
+{
+ sFlyTargetAnimSeq0,
+ sFlyTargetAnimSeq1,
+ sFlyTargetAnimSeq2,
+ sFlyTargetAnimSeq3,
+ sFlyTargetAnimSeq4,
+ sFlyTargetAnimSeq5,
+ sFlyTargetAnimSeq6,
+};
+
+static const struct SpriteTemplate gFlyTargetSpriteTemplate =
+{
+ .tileTag = 2,
+ .paletteTag = 2,
+ .oam = &sFlyTargetOamData,
+ .anims = sFlyTargetAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+void CB2_InitFlyRegionMap(void)
+{
+ switch (gMain.state)
+ {
+ case 0:
+ SetVBlankCallback(NULL);
+ REG_DISPCNT = 0;
+ REG_BG0HOFS = 0;
+ REG_BG0VOFS = 0;
+ REG_BG1HOFS = 0;
+ REG_BG1VOFS = 0;
+ REG_BG2VOFS = 0;
+ REG_BG2HOFS = 0;
+ REG_BG3HOFS = 0;
+ REG_BG3VOFS = 0;
+ ResetPaletteFade();
+ ResetSpriteData();
+ FreeSpriteTileRanges();
+ FreeAllSpritePalettes();
+ break;
+ case 1:
+ SetUpWindowConfig(&gWindowConfig_81E7224);
+ break;
+ case 2:
+ InitMenuWindow(&gWindowConfig_81E7224);
+ MenuZeroFillScreen();
+ break;
+ case 3:
+ InitRegionMap(&ewram0.regionMap, 0);
+ CreateRegionMapCursor(0, 0);
+ CreateRegionMapPlayerIcon(1, 1);
+ ewram0.unk6 = ewram0.regionMap.mapSecId;
+ StringFill(ewramBlankMapName, CHAR_SPACE, 12);
+ PrintFlyTargetName();
+ break;
+ case 4:
+ LZ77UnCompVram(sFlyRegionMapFrame_ImageLZ, (void *)(VRAM + 0xC000));
+ break;
+ case 5:
+ LZ77UnCompVram(sFlyRegionMapFrame_TilemapLZ, (void *)(VRAM + 0xF000));
+ break;
+ case 6:
+ LoadPalette(sFlyRegionMapFrame_Pal, 16, 32);
+ MenuPrint_PixelCoords(gOtherText_FlyToWhere, 1, 0x90, 1);
+ break;
+ case 7:
+ CreateFlyTargetGraphics();
+ break;
+ case 8:
+ BlendPalettes(0xFFFFFFFF, 16, 0);
+ SetVBlankCallback(VBlankCB_FlyRegionMap);
+ break;
+ case 9:
+ REG_BLDCNT = 0;
+ REG_BG1CNT = 0x1E0D;
+ REG_DISPCNT = 0x1741;
+ sub_80FC244(sub_80FC5B4);
+ SetMainCallback2(CB2_FlyRegionMap);
+ break;
+ default:
+ return;
+ }
+ gMain.state++;
+}
+
+static void VBlankCB_FlyRegionMap(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+static void CB2_FlyRegionMap(void)
+{
+ ewram0.unk0();
+ AnimateSprites();
+ BuildOamBuffer();
+}
+
+static void sub_80FC244(void (*func)(void))
+{
+ ewram0.unk0 = func;
+ ewram0.unk4 = 0;
+}
+
+static void PrintFlyTargetName(void)
+{
+ if (ewram0.regionMap.unk16 == 2 || ewram0.regionMap.unk16 == 4)
+ {
+ u16 i = 0;
+ int zero;
+
+ for (i = 0; i < ARRAY_COUNT(sUnknown_083E79C0); i++)
+ {
+ const struct UnknownStruct4 *r4 = &sUnknown_083E79C0[i];
+
+ if (ewram0.regionMap.mapSecId == r4->mapSecId)
+ {
+ if (FlagGet(r4->flag))
+ {
+ MenuDrawTextWindow(16, 14, 29, 19);
+ MenuPrint(ewram0.regionMap.mapSecName, 17, 15);
+ MenuPrint_RightAligned(r4->unk0[ewram0.regionMap.everGrandeCityArea], 29, 17);
+ return;
+ }
+ break;
+ }
+ }
+ // This check is always true, but somehow the compiler still performed it.
+ asm("mov %0, #0\n":"=r"(zero)); // zero = 0
+ if (zero == 0)
+ {
+ MenuDrawTextWindow(16, 16, 29, 19);
+ MenuPrint(ewram0.regionMap.mapSecName, 17, 17);
+ MenuZeroFillWindowRect(16, 14, 29, 15);
+ }
+ }
+ else
+ {
+ MenuDrawTextWindow(16, 16, 29, 19);
+ MenuPrint(ewramBlankMapName, 17, 17);
+ MenuZeroFillWindowRect(16, 14, 29, 15);
+ }
+}
+
+static void CreateFlyTargetGraphics(void)
+{
+ struct SpriteSheet spriteSheet;
+
+ LZ77UnCompWram(sFlyTargetIcons_ImageLZ, ewram888);
+ spriteSheet.data = ewram888;
+ spriteSheet.size = 0x1C0;
+ spriteSheet.tag = 2;
+ LoadSpriteSheet(&spriteSheet);
+ LoadSpritePalette(&sFlyTargetIconSpritePalette);
+ CreateCityTownFlyTargetIcons();
+ CreateSpecialAreaFlyTargetIcons();
+}
+
+// Draws a light overlay on cities and towns that the player can fly to
+static void CreateCityTownFlyTargetIcons(void)
+{
+ u16 canFlyFlag = 0x80F;
+ u16 i;
+
+ for (i = 0; i < 16; i++)
+ {
+ u16 x;
+ u16 y;
+ u16 width;
+ u16 height;
+ u16 r7;
+ u8 spriteId;
+
+ GetRegionMapLocationPosition(i, &x, &y, &width, &height);
+ x = (x + 1) * 8 + 4;
+ y = (y + 2) * 8 + 4;
+ if (width == 2)
+ r7 = 1;
+ else if (height == 2)
+ r7 = 2;
+ else
+ r7 = 0;
+ spriteId = CreateSprite(&gFlyTargetSpriteTemplate, x, y, 10);
+ if (spriteId != 64)
+ {
+ gSprites[spriteId].oam.shape = r7;
+ if (FlagGet(canFlyFlag))
+ gSprites[spriteId].callback = SpriteCB_FlyTargetIcons;
+ else
+ r7 += 3;
+ StartSpriteAnim(&gSprites[spriteId], r7);
+ gSprites[spriteId].data0 = i;
+ }
+ canFlyFlag++;
+ }
+}
+
+// Draws a red box on other fly targets
+// The Battle Tower is the only one of these
+static void CreateSpecialAreaFlyTargetIcons(void)
+{
+ u16 i;
+
+ for (i = 0; sSpecialFlyAreas[i][1] != MAPSEC_NONE; i++)
+ {
+ u16 x;
+ u16 y;
+ u16 width;
+ u16 height;
+
+ if (FlagGet(sSpecialFlyAreas[i][0]))
+ {
+ u16 mapSecId = sSpecialFlyAreas[i][1];
+ u8 spriteId;
+
+ GetRegionMapLocationPosition(mapSecId, &x, &y, &width, &height);
+ x = (x + 1) * 8;
+ y = (y + 2) * 8;
+ spriteId = CreateSprite(&gFlyTargetSpriteTemplate, x, y, 10);
+ if (spriteId != 64)
+ {
+ gSprites[spriteId].oam.size = 1;
+ gSprites[spriteId].callback = SpriteCB_FlyTargetIcons;
+ StartSpriteAnim(&gSprites[spriteId], 6);
+ gSprites[spriteId].data0 = mapSecId;
+ }
+ }
+ }
+}
+
+static void SpriteCB_FlyTargetIcons(struct Sprite *sprite)
+{
+ // Blink if our mapSecId is the one selected on the map
+ if (ewram0.regionMap.mapSecId == sprite->data0)
+ {
+ // Toggle visibility every 16 frames
+ sprite->data1++;
+ if (sprite->data1 > 16)
+ {
+ sprite->data1 = 0;
+ sprite->invisible = !sprite->invisible;
+ }
+ }
+ else
+ {
+ sprite->data1 = 16;
+ sprite->invisible = FALSE;
+ }
+}
+
+static void sub_80FC5B4(void)
+{
+ switch (ewram0.unk4)
+ {
+ case 0:
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, 0);
+ ewram0.unk4++;
+ break;
+ case 1:
+ if (UpdatePaletteFade() != 0)
+ break;
+ sub_80FC244(sub_80FC600);
+ break;
+ }
+}
+
+static void sub_80FC600(void)
+{
+ if (ewram0.unk4 == 0)
+ {
+ switch (sub_80FAB60())
+ {
+ case INPUT_EVENT_NONE:
+ case INPUT_EVENT_DPAD:
+ case INPUT_EVENT_2:
+ break;
+ case INPUT_EVENT_3:
+ PrintFlyTargetName();
+ break;
+ case INPUT_EVENT_A_BUTTON:
+ if (ewram0.regionMap.unk16 == 2 || ewram0.regionMap.unk16 == 4)
+ {
+ m4aSongNumStart(SE_SELECT);
+ ewramA6E = 1;
+ sub_80FC244(sub_80FC69C);
+ }
+ break;
+ case INPUT_EVENT_B_BUTTON:
+ m4aSongNumStart(SE_SELECT);
+ ewramA6E = 0;
+ sub_80FC244(sub_80FC69C);
+ break;
+ }
+ }
+}
+
+static void sub_80FC69C(void)
+{
+ switch (ewram0.unk4)
+ {
+ case 0:
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0);
+ ewram0.unk4++;
+ break;
+ case 1:
+ if (UpdatePaletteFade() != 0)
+ break;
+ FreeRegionMapIconResources();
+ if (ewramA6E != 0)
+ {
+ switch (ewram0.regionMap.mapSecId)
+ {
+ case MAPSEC_SOUTHERN_ISLAND:
+ sub_8053538(22);
+ break;
+ case MAPSEC_BATTLE_TOWER:
+ sub_8053538(21);
+ break;
+ case MAPSEC_LITTLEROOT_TOWN:
+ sub_8053538((gSaveBlock2.playerGender == MALE) ? 12 : 13);
+ break;
+ case MAPSEC_EVER_GRANDE_CITY:
+ sub_8053538((FlagGet(0x854) && ewram0.regionMap.everGrandeCityArea == 0) ? 20 : 11);
+ break;
+ default:
+ if (sUnknown_083E7920[ewram0.regionMap.mapSecId][2] != 0)
+ sub_8053538(sUnknown_083E7920[ewram0.regionMap.mapSecId][2]);
+ else
+ warp1_set_2(sUnknown_083E7920[ewram0.regionMap.mapSecId][0], sUnknown_083E7920[ewram0.regionMap.mapSecId][1], -1);
+ break;
+ }
+ sub_80865BC();
+ }
+ else
+ {
+ SetMainCallback2(sub_808AD58);
+ }
+ break;
+ }
+}
diff --git a/src/field/roamer.c b/src/field/roamer.c
new file mode 100644
index 000000000..948828d5e
--- /dev/null
+++ b/src/field/roamer.c
@@ -0,0 +1,226 @@
+#include "global.h"
+#include "roamer.h"
+#include "pokemon.h"
+#include "rng.h"
+#include "species.h"
+
+#ifdef SAPPHIRE
+#define ROAMER_SPECIES SPECIES_LATIAS
+#else
+#define ROAMER_SPECIES SPECIES_LATIOS
+#endif
+
+enum
+{
+ MAP_GRP = 0, // map group
+ MAP_NUM = 1, // map number
+};
+
+EWRAM_DATA static u8 sLocationHistory[3][2] = {0};
+EWRAM_DATA static u8 sRoamerLocation[2] = {0};
+
+static const u8 sRoamerLocations[][6] =
+{
+ { 0x19, 0x1A, 0x20, 0x21, 0x31, 0xFF },
+ { 0x1A, 0x19, 0x20, 0x21, 0xFF, 0xFF },
+ { 0x20, 0x1A, 0x19, 0x21, 0xFF, 0xFF },
+ { 0x21, 0x20, 0x19, 0x1A, 0x22, 0x26 },
+ { 0x22, 0x21, 0x23, 0xFF, 0xFF, 0xFF },
+ { 0x23, 0x22, 0x24, 0xFF, 0xFF, 0xFF },
+ { 0x24, 0x23, 0x25, 0x26, 0xFF, 0xFF },
+ { 0x25, 0x24, 0x26, 0xFF, 0xFF, 0xFF },
+ { 0x26, 0x25, 0x21, 0xFF, 0xFF, 0xFF },
+ { 0x27, 0x24, 0x28, 0x29, 0xFF, 0xFF },
+ { 0x28, 0x27, 0x2A, 0xFF, 0xFF, 0xFF },
+ { 0x29, 0x27, 0x2A, 0xFF, 0xFF, 0xFF },
+ { 0x2A, 0x28, 0x29, 0x2B, 0xFF, 0xFF },
+ { 0x2B, 0x2A, 0x2C, 0xFF, 0xFF, 0xFF },
+ { 0x2C, 0x2B, 0x2D, 0xFF, 0xFF, 0xFF },
+ { 0x2D, 0x2C, 0x2E, 0xFF, 0xFF, 0xFF },
+ { 0x2E, 0x2D, 0x2F, 0xFF, 0xFF, 0xFF },
+ { 0x2F, 0x2E, 0x30, 0xFF, 0xFF, 0xFF },
+ { 0x30, 0x2F, 0x31, 0xFF, 0xFF, 0xFF },
+ { 0x31, 0x30, 0x19, 0xFF, 0xFF, 0xFF },
+ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
+};
+
+void ClearRoamerData(void)
+{
+ memset(&gSaveBlock1.roamer, 0, sizeof(gSaveBlock1.roamer));
+}
+
+void ClearRoamerLocationData(void)
+{
+ u8 i;
+
+ for (i = 0; i < 3; i++)
+ {
+ sLocationHistory[i][MAP_GRP] = 0;
+ sLocationHistory[i][MAP_NUM] = 0;
+ }
+
+ sRoamerLocation[MAP_GRP] = 0;
+ sRoamerLocation[MAP_NUM] = 0;
+}
+
+void CreateInitialRoamerMon(void)
+{
+ struct Roamer *roamer;
+ CreateMon(&gEnemyParty[0], ROAMER_SPECIES, 40, 0x20, 0, 0, 0, 0);
+ roamer = &gSaveBlock1.roamer;
+ roamer->species = ROAMER_SPECIES;
+ roamer->level = 40;
+ roamer->status = 0;
+ roamer->active = TRUE;
+ roamer->ivs = GetMonData(&gEnemyParty[0], MON_DATA_IVS);
+ roamer->personality = GetMonData(&gEnemyParty[0], MON_DATA_PERSONALITY);
+ roamer->hp = GetMonData(&gEnemyParty[0], MON_DATA_MAX_HP);
+ roamer->cool = GetMonData(&gEnemyParty[0], MON_DATA_COOL);
+ roamer->beauty = GetMonData(&gEnemyParty[0], MON_DATA_BEAUTY);
+ roamer->cute = GetMonData(&gEnemyParty[0], MON_DATA_CUTE);
+ roamer->smart = GetMonData(&gEnemyParty[0], MON_DATA_SMART);
+ roamer->tough = GetMonData(&gEnemyParty[0], MON_DATA_TOUGH);
+ sRoamerLocation[MAP_GRP] = 0;
+ sRoamerLocation[MAP_NUM] = sRoamerLocations[Random() % 20][0];
+}
+
+void InitRoamer(void)
+{
+ ClearRoamerData();
+ ClearRoamerLocationData();
+ CreateInitialRoamerMon();
+}
+
+void UpdateLocationHistoryForRoamer(void)
+{
+ sLocationHistory[2][MAP_GRP] = sLocationHistory[1][MAP_GRP];
+ sLocationHistory[2][MAP_NUM] = sLocationHistory[1][MAP_NUM];
+
+ sLocationHistory[1][MAP_GRP] = sLocationHistory[0][MAP_GRP];
+ sLocationHistory[1][MAP_NUM] = sLocationHistory[0][MAP_NUM];
+
+ sLocationHistory[0][MAP_GRP] = gSaveBlock1.location.mapGroup;
+ sLocationHistory[0][MAP_NUM] = gSaveBlock1.location.mapNum;
+}
+
+void RoamerMoveToOtherLocationSet(void)
+{
+ u8 val = 0;
+ struct Roamer *roamer = &gSaveBlock1.roamer;
+
+ if (!roamer->active)
+ return;
+
+ sRoamerLocation[MAP_GRP] = val;
+
+ while (1)
+ {
+ val = sRoamerLocations[Random() % 20][0];
+ if (sRoamerLocation[MAP_NUM] != val)
+ {
+ sRoamerLocation[MAP_NUM] = val;
+ return;
+ }
+ }
+}
+
+void RoamerMove(void)
+{
+ u8 locSet = 0;
+
+ if ((Random() % 16) == 0)
+ {
+ RoamerMoveToOtherLocationSet();
+ }
+ else
+ {
+ struct Roamer *roamer = &gSaveBlock1.roamer;
+
+ if (!roamer->active)
+ return;
+
+ while (locSet < 20)
+ {
+ if (sRoamerLocation[MAP_NUM] == sRoamerLocations[locSet][0])
+ {
+ u8 mapNum;
+ while (1)
+ {
+ mapNum = sRoamerLocations[locSet][(Random() % 5) + 1];
+ if (!(sLocationHistory[2][MAP_GRP] == 0 && sLocationHistory[2][MAP_NUM] == mapNum) && mapNum != 0xFF)
+ break;
+ }
+ sRoamerLocation[MAP_NUM] = mapNum;
+ return;
+ }
+ locSet++;
+ }
+ }
+}
+
+bool8 IsRoamerAt(u8 mapGroup, u8 mapNum)
+{
+ struct Roamer *roamer = &gSaveBlock1.roamer;
+
+ if (roamer->active && mapGroup == sRoamerLocation[MAP_GRP] && mapNum == sRoamerLocation[MAP_NUM])
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void CreateRoamerMonInstance(void)
+{
+ struct Pokemon *mon = &gEnemyParty[0];
+ struct Roamer *roamer = &gSaveBlock1.roamer;
+ CreateMonWithIVsPersonality(mon, roamer->species, roamer->level, roamer->ivs, roamer->personality);
+ SetMonData(mon, MON_DATA_STATUS, (u8 *)&roamer->status);
+ SetMonData(mon, MON_DATA_HP, (u8 *)&roamer->hp);
+ SetMonData(mon, MON_DATA_COOL, (u8 *)&roamer->cool);
+ SetMonData(mon, MON_DATA_BEAUTY, (u8 *)&roamer->beauty);
+ SetMonData(mon, MON_DATA_CUTE, (u8 *)&roamer->cute);
+ SetMonData(mon, MON_DATA_SMART, (u8 *)&roamer->smart);
+ SetMonData(mon, MON_DATA_TOUGH, (u8 *)&roamer->tough);
+}
+
+bool8 TryStartRoamerEncounter(void)
+{
+ if (IsRoamerAt(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum) == TRUE && (Random() % 4) == 0)
+ {
+ CreateRoamerMonInstance();
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+void UpdateRoamerHPStatus(struct Pokemon *mon)
+{
+ struct Roamer *roamer;
+ u16 hp;
+ u8 status;
+
+ hp = GetMonData(mon, MON_DATA_HP);
+
+ roamer = &gSaveBlock1.roamer;
+ roamer->hp = hp;
+
+ status = GetMonData(mon, MON_DATA_STATUS);
+
+ roamer->status = status;
+
+ RoamerMoveToOtherLocationSet();
+}
+
+void SetRoamerInactive(void)
+{
+ struct Roamer *roamer = &gSaveBlock1.roamer;
+ roamer->active = FALSE;
+}
+
+void GetRoamerLocation(u8 *mapGroup, u8 *mapNum)
+{
+ *mapGroup = sRoamerLocation[MAP_GRP];
+ *mapNum = sRoamerLocation[MAP_NUM];
+}
diff --git a/src/field/rotating_gate.c b/src/field/rotating_gate.c
new file mode 100644
index 000000000..e8ab7e1bf
--- /dev/null
+++ b/src/field/rotating_gate.c
@@ -0,0 +1,1155 @@
+#include "global.h"
+#include "bike.h"
+#include "event_data.h"
+#include "field_map_obj.h"
+#include "fieldmap.h"
+#include "map_constants.h"
+#include "songs.h"
+#include "sound.h"
+#include "sprite.h"
+
+#define ROTATING_GATE_TILE_TAG 0x1300
+#define ROTATING_GATE_PUZZLE_MAX 14
+#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 void SpriteCallback_RotatingGate(struct Sprite *sprite);
+static u8 RotatingGate_CreateGate(u8 gateId, s16 deltaX, s16 deltaY);
+static void RotatingGate_HideGatesOutsideViewport(struct Sprite *sprite);
+
+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,
+};
+
+struct RotatingGatePuzzle
+{
+ s16 x;
+ s16 y;
+ u8 shape;
+ u8 orientation;
+};
+
+struct Coords8
+{
+ s8 deltaX;
+ s8 deltaY;
+};
+
+// Fortree
+static const struct RotatingGatePuzzle sRotatingGate_FortreePuzzleConfig[] =
+{
+ {12, 5, GATE_SHAPE_L4, GATE_ORIENTATION_0},
+ {14, 7, GATE_SHAPE_L4, GATE_ORIENTATION_270},
+ {16, 4, GATE_SHAPE_T2, GATE_ORIENTATION_90},
+ {15, 14, GATE_SHAPE_L2, GATE_ORIENTATION_0},
+ {18, 13, GATE_SHAPE_T1, GATE_ORIENTATION_180},
+ { 8, 20, GATE_SHAPE_T1, GATE_ORIENTATION_180},
+ {16, 20, GATE_SHAPE_T4, GATE_ORIENTATION_90},
+};
+
+// Trickhouse
+static const struct RotatingGatePuzzle sRotatingGate_TrickHousePuzzleConfig[] =
+{
+ {13, 3, GATE_SHAPE_T1, GATE_ORIENTATION_270},
+ {12, 6, GATE_SHAPE_T1, GATE_ORIENTATION_180},
+ { 3, 6, GATE_SHAPE_T1, GATE_ORIENTATION_180},
+ { 3, 9, GATE_SHAPE_T2, GATE_ORIENTATION_270},
+ { 8, 8, GATE_SHAPE_L1, GATE_ORIENTATION_90},
+ { 2, 12, GATE_SHAPE_T3, GATE_ORIENTATION_180},
+ { 9, 13, GATE_SHAPE_L2, GATE_ORIENTATION_0},
+ { 3, 14, GATE_SHAPE_L3, GATE_ORIENTATION_90},
+ { 9, 15, GATE_SHAPE_L4, GATE_ORIENTATION_180},
+ { 3, 18, GATE_SHAPE_T2, GATE_ORIENTATION_180},
+ { 2, 19, GATE_SHAPE_T1, GATE_ORIENTATION_0},
+ { 5, 21, GATE_SHAPE_L1, GATE_ORIENTATION_0},
+ { 9, 19, GATE_SHAPE_L4, GATE_ORIENTATION_270},
+ {12, 20, GATE_SHAPE_T1, GATE_ORIENTATION_90},
+};
+
+static const u8 sRotatingGateTiles_1[] = INCBIN_U8("graphics/rotating_gates/1.4bpp");
+static const u8 sRotatingGateTiles_2[] = INCBIN_U8("graphics/rotating_gates/2.4bpp");
+static const u8 sRotatingGateTiles_3[] = INCBIN_U8("graphics/rotating_gates/3.4bpp");
+static const u8 sRotatingGateTiles_5[] = INCBIN_U8("graphics/rotating_gates/5.4bpp");
+static const u8 sRotatingGateTiles_6[] = INCBIN_U8("graphics/rotating_gates/6.4bpp");
+static const u8 sRotatingGateTiles_7[] = INCBIN_U8("graphics/rotating_gates/7.4bpp");
+static const u8 sRotatingGateTiles_0[] = INCBIN_U8("graphics/rotating_gates/0.4bpp");
+static const u8 sRotatingGateTiles_4[] = INCBIN_U8("graphics/rotating_gates/4.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 = 5,
+ .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 = 5,
+ .affineParam = 0,
+};
+
+static const struct SpriteSheet sRotatingGatesGraphicsTable[] =
+{
+ {sRotatingGateTiles_0, 0x200, ROTATING_GATE_TILE_TAG + GATE_SHAPE_L1},
+ {sRotatingGateTiles_1, 0x800, ROTATING_GATE_TILE_TAG + GATE_SHAPE_L2},
+ {sRotatingGateTiles_2, 0x800, ROTATING_GATE_TILE_TAG + GATE_SHAPE_L3},
+ {sRotatingGateTiles_3, 0x800, ROTATING_GATE_TILE_TAG + GATE_SHAPE_L4},
+ {sRotatingGateTiles_4, 0x200, ROTATING_GATE_TILE_TAG + GATE_SHAPE_T1},
+ {sRotatingGateTiles_5, 0x800, ROTATING_GATE_TILE_TAG + GATE_SHAPE_T2},
+ {sRotatingGateTiles_6, 0x800, ROTATING_GATE_TILE_TAG + GATE_SHAPE_T3},
+ {sRotatingGateTiles_7, 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,
+ },
+};
+
+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;
+
+static int GetCurrentMapRotatingGatePuzzleType(void)
+{
+ if (gSaveBlock1.location.mapGroup == MAP_GROUP_FORTREE_CITY_GYM &&
+ gSaveBlock1.location.mapNum == MAP_ID_FORTREE_CITY_GYM)
+ {
+ return PUZZLE_FORTREE_CITY_GYM;
+ }
+
+ if (gSaveBlock1.location.mapGroup == MAP_GROUP_ROUTE110_TRICK_HOUSE_PUZZLE6 &&
+ gSaveBlock1.location.mapNum == MAP_ID_ROUTE110_TRICK_HOUSE_PUZZLE6)
+ {
+ return PUZZLE_ROUTE110_TRICK_HOUSE_PUZZLE6;
+ }
+
+ return PUZZLE_NONE;
+}
+
+static void RotatingGate_ResetAllGateOrientations(void)
+{
+ int i;
+ u8 *ptr;
+
+ ptr = (u8 *)GetVarPointer(0x4000);
+
+ for (i = 0; i < gRotatingGate_PuzzleCount; i++)
+ {
+ ptr[i] = gRotatingGate_PuzzleConfig[i].orientation;
+ }
+}
+
+static int RotatingGate_GetGateOrientation(u8 gateId)
+{
+ return ((u8 *)GetVarPointer(0x4000))[gateId];
+}
+
+static void RotatingGate_SetGateOrientation(u8 gateId, u8 orientation)
+{
+ ((u8 *)GetVarPointer(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)
+{
+ int 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; 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 = gSaveBlock1.pos.x - 2;
+ s16 x2 = gSaveBlock1.pos.x + 0x11;
+ s16 y = gSaveBlock1.pos.y - 2;
+ s16 y2 = gSaveBlock1.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->data0 = gateId;
+ sprite->coordOffsetEnabled = 1;
+
+ sub_8060388(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->data1;
+ orientation = sprite->data2;
+
+ 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->data1 = 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;
+ int i;
+ struct Sprite *sprite;
+
+ // Same as RotatingGate_CreateGatesWithinViewport
+ x = gSaveBlock1.pos.x - 2;
+ x2 = gSaveBlock1.pos.x + 0x11;
+ y = gSaveBlock1.pos.y - 2;
+ y2 = gSaveBlock1.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
+static int RotatingGate_CanRotate(u8 gateId, int rotationDirection)
+{
+ const struct Coords8 *armPos;
+ u8 orientation;
+ s16 x;
+ s16 y;
+ int shape;
+ int i;
+ int j;
+ int armOrientation;
+ const u8 *gateArmCollisionData;
+ u8 armIndex;
+
+ if (rotationDirection == ROTATE_ANTICLOCKWISE)
+ armPos = sRotatingGate_ArmPositionsAntiClockwiseRotation;
+ else if (rotationDirection == ROTATE_CLOCKWISE)
+ armPos = sRotatingGate_ArmPositionsClockwiseRotation;
+ else
+ return 0;
+
+ 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; i <= GATE_ARM_WEST; i++)
+ {
+ armOrientation = orientation + i;
+ gateArmCollisionData = sRotatingGate_ArmLayout[shape][i];
+
+ // Ensure that no part of the arm collides with the map
+ for (j = 0; j < GATE_ARM_MAX_LENGTH; j++)
+ {
+ armIndex = 2 * (armOrientation % 4) + j;
+
+ if (*gateArmCollisionData)
+ {
+ if (MapGridIsImpassableAt(
+ armPos[armIndex].deltaX + x, armPos[armIndex].deltaY + y) == 1)
+ return 0;
+ }
+ gateArmCollisionData++;
+ }
+ }
+
+ return 1;
+}
+#else
+__attribute__((naked))
+static int RotatingGate_CanRotate(u8 a, int puzzleType)
+{
+ 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 _080C7EAC\n\
+ ldr r0, _080C7EA8 @ =sRotatingGate_ArmPositionsAntiClockwiseRotation\n\
+ mov r10, r0\n\
+ b _080C7EB8\n\
+ .align 2, 0\n\
+_080C7EA8: .4byte sRotatingGate_ArmPositionsAntiClockwiseRotation\n\
+_080C7EAC:\n\
+ cmp r1, 0x2\n\
+ beq _080C7EB4\n\
+_080C7EB0:\n\
+ movs r0, 0\n\
+ b _080C7F48\n\
+_080C7EB4:\n\
+ ldr r1, _080C7F58 @ =sRotatingGate_ArmPositionsClockwiseRotation\n\
+ mov r10, r1\n\
+_080C7EB8:\n\
+ adds r0, r4, 0\n\
+ bl RotatingGate_GetGateOrientation\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ str r0, [sp]\n\
+ ldr r0, _080C7F5C @ =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\
+_080C7EE8:\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, _080C7F60 @ =sRotatingGate_ArmLayout\n\
+ adds r4, r0, r2\n\
+_080C7EFA:\n\
+ adds r0, r5, 0\n\
+ cmp r5, 0\n\
+ bge _080C7F02\n\
+ adds r0, r7, 0x3\n\
+_080C7F02:\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 _080C7F38\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 _080C7EB0\n\
+_080C7F38:\n\
+ adds r4, 0x1\n\
+ adds r6, 0x1\n\
+ cmp r6, 0x1\n\
+ ble _080C7EFA\n\
+ adds r3, 0x1\n\
+ cmp r3, 0x3\n\
+ ble _080C7EE8\n\
+ movs r0, 0x1\n\
+_080C7F48:\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\
+ .align 2, 0\n\
+_080C7F58: .4byte sRotatingGate_ArmPositionsClockwiseRotation\n\
+_080C7F5C: .4byte gRotatingGate_PuzzleConfig\n\
+_080C7F60: .4byte sRotatingGate_ArmLayout\n\
+.syntax divided\n");
+}
+#endif
+
+static int RotatingGate_HasArm(u8 gateId, u8 armInfo)
+{
+ int isLongArm;
+ s8 armOrientation;
+ int arm;
+ int 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, int rotationDirection)
+{
+ struct Sprite *sprite;
+
+ if (gRotatingGate_GateSpriteIds[gateId] != MAX_SPRITES)
+ {
+ sprite = &gSprites[gRotatingGate_GateSpriteIds[gateId]];
+ sprite->data1 = rotationDirection;
+ sprite->data2 = 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)
+{
+ int 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;
+}
diff --git a/src/field/safari_zone.c b/src/field/safari_zone.c
new file mode 100644
index 000000000..14fd1ddc4
--- /dev/null
+++ b/src/field/safari_zone.c
@@ -0,0 +1,253 @@
+#include "global.h"
+#include "safari_zone.h"
+#include "event_data.h"
+#include "field_fadetransition.h"
+#include "field_player_avatar.h"
+#include "main.h"
+#include "overworld.h"
+#include "script.h"
+#include "string_util.h"
+#include "text.h"
+
+struct PokeblockFeeder
+{
+ /*0x00*/ s16 x;
+ /*0x02*/ s16 y;
+ /*0x04*/ s8 mapNum;
+ /*0x05*/ u8 stepCounter;
+ /*0x08*/ struct Pokeblock pokeblock;
+};
+
+#define NUM_POKEBLOCK_FEEDERS 10
+
+static void ClearAllPokeblockFeeders(void);
+static void DecrementFeederStepCounters(void);
+
+extern u8 gBattleOutcome;
+
+EWRAM_DATA u8 gNumSafariBalls = 0;
+EWRAM_DATA static u16 gSafariZoneStepCounter = 0;
+EWRAM_DATA static struct PokeblockFeeder gPokeblockFeeders[NUM_POKEBLOCK_FEEDERS] = {0};
+
+extern void (*gFieldCallback)(void);
+
+extern u8 gUnknown_081C340A;
+extern u8 gUnknown_081C342D;
+extern u8 gUnknown_081C3448;
+extern u8 gUnknown_081C3459;
+extern u8 *gPokeblockNames[];
+
+extern u16 gScriptResult;
+
+bool32 GetSafariZoneFlag(void)
+{
+ return FlagGet(SYS_SAFARI_MODE);
+}
+
+void SetSafariZoneFlag(void)
+{
+ FlagSet(SYS_SAFARI_MODE);
+}
+
+void ResetSafariZoneFlag(void)
+{
+ FlagClear(SYS_SAFARI_MODE);
+}
+
+void EnterSafariMode(void)
+{
+ IncrementGameStat(0x11);
+ SetSafariZoneFlag();
+ ClearAllPokeblockFeeders();
+ gNumSafariBalls = 30;
+ gSafariZoneStepCounter = 500;
+}
+
+void ExitSafariMode(void)
+{
+ ResetSafariZoneFlag();
+ ClearAllPokeblockFeeders();
+ gNumSafariBalls = 0;
+ gSafariZoneStepCounter = 0;
+}
+
+bool8 SafariZoneTakeStep(void)
+{
+ if (GetSafariZoneFlag() == FALSE)
+ {
+ return FALSE;
+ }
+
+ DecrementFeederStepCounters();
+ gSafariZoneStepCounter--;
+ if (gSafariZoneStepCounter == 0)
+ {
+ ScriptContext1_SetupScript(&gUnknown_081C3448);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void SafariZoneRetirePrompt(void)
+{
+ ScriptContext1_SetupScript(&gUnknown_081C342D);
+}
+
+void sub_80C824C(void)
+{
+ if (gNumSafariBalls != 0)
+ {
+ SetMainCallback2(c2_exit_to_overworld_2_switch);
+ }
+ else if (gBattleOutcome == 8)
+ {
+ ScriptContext2_RunNewScript(&gUnknown_081C340A);
+ warp_in();
+ gFieldCallback = sub_8080E44;
+ SetMainCallback2(CB2_LoadMap);
+ }
+ else if (gBattleOutcome == 7)
+ {
+ ScriptContext1_SetupScript(&gUnknown_081C3459);
+ ScriptContext1_Stop();
+ SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
+ }
+}
+
+static void ClearPokeblockFeeder(u8 index)
+{
+ memset(&gPokeblockFeeders[index], 0, sizeof(struct PokeblockFeeder));
+}
+
+static void ClearAllPokeblockFeeders(void)
+{
+ memset(gPokeblockFeeders, 0, sizeof(gPokeblockFeeders));
+}
+
+void SafariZoneGetPokeblockNameInFeeder(void)
+{
+ s16 x, y;
+ u16 i;
+
+ GetXYCoordsOneStepInFrontOfPlayer(&x, &y);
+
+ for (i = 0; i < NUM_POKEBLOCK_FEEDERS; i++)
+ {
+ if (gSaveBlock1.location.mapNum == gPokeblockFeeders[i].mapNum
+ && gPokeblockFeeders[i].x == x
+ && gPokeblockFeeders[i].y == y)
+ {
+ gScriptResult = i;
+ StringCopy(gStringVar1, gPokeblockNames[gPokeblockFeeders[i].pokeblock.color]);
+ return;
+ }
+ }
+
+ gScriptResult = -1;
+}
+
+static void GetPokeblockFeederWithinRange(void)
+{
+ s16 x, y;
+ u16 i;
+
+ PlayerGetDestCoords(&x, &y);
+
+ for (i = 0; i < NUM_POKEBLOCK_FEEDERS; i++)
+ {
+ if (gSaveBlock1.location.mapNum == gPokeblockFeeders[i].mapNum)
+ {
+ //Get absolute value of x and y distance from Pokeblock feeder on current map
+ x -= gPokeblockFeeders[i].x;
+ y -= gPokeblockFeeders[i].y;
+ if (x < 0)
+ x *= -1;
+ if (y < 0)
+ y *= -1;
+ if ((x + y) <= 5)
+ {
+ gScriptResult = i;
+ return;
+ }
+ }
+ }
+
+ gScriptResult = -1;
+}
+
+struct Pokeblock *unref_sub_80C8418(void)
+{
+ SafariZoneGetPokeblockNameInFeeder();
+
+ if (gScriptResult == 0xFFFF)
+ return NULL;
+ else
+ return &gPokeblockFeeders[gScriptResult].pokeblock;
+}
+
+
+struct Pokeblock *SafariZoneGetActivePokeblock(void)
+{
+ GetPokeblockFeederWithinRange();
+
+ if (gScriptResult == 0xFFFF)
+ return NULL;
+ else
+ return &gPokeblockFeeders[gScriptResult].pokeblock;
+}
+
+
+void SafariZoneActivatePokeblockFeeder(u8 pokeblock_index)
+{
+ s16 x, y;
+ u8 i;
+
+ for (i = 0; i < NUM_POKEBLOCK_FEEDERS; i++)
+ {
+ //Find free entry in gPokeblockFeeders
+ if (gPokeblockFeeders[i].mapNum == 0
+ && gPokeblockFeeders[i].x == 0
+ && gPokeblockFeeders[i].y == 0)
+ {
+ //Initialize Pokeblock feeder
+ GetXYCoordsOneStepInFrontOfPlayer(&x, &y);
+ gPokeblockFeeders[i].mapNum = gSaveBlock1.location.mapNum;
+ gPokeblockFeeders[i].pokeblock = gSaveBlock1.pokeblocks[pokeblock_index];
+ gPokeblockFeeders[i].stepCounter = 100;
+ gPokeblockFeeders[i].x = x;
+ gPokeblockFeeders[i].y = y;
+ break;
+ }
+ }
+}
+
+static void DecrementFeederStepCounters(void)
+{
+ u8 i;
+
+ for (i = 0; i < NUM_POKEBLOCK_FEEDERS; i++)
+ {
+ if (gPokeblockFeeders[i].stepCounter != 0)
+ {
+ gPokeblockFeeders[i].stepCounter--;
+ if (gPokeblockFeeders[i].stepCounter == 0)
+ ClearPokeblockFeeder(i);
+ }
+ }
+}
+
+bool8 unref_sub_80C853C(void)
+{
+ SafariZoneGetPokeblockNameInFeeder();
+
+ if (gScriptResult == 0xFFFF)
+ {
+ return FALSE;
+ }
+
+ ConvertIntToDecimalStringN(gStringVar2,
+ gPokeblockFeeders[gScriptResult].stepCounter,
+ STR_CONV_MODE_LEADING_ZEROS, 3);
+
+ return TRUE;
+}
diff --git a/src/field/scrcmd.c b/src/field/scrcmd.c
new file mode 100644
index 000000000..28584d4d0
--- /dev/null
+++ b/src/field/scrcmd.c
@@ -0,0 +1,2020 @@
+#include "global.h"
+#include "battle_setup.h"
+#include "berry.h"
+#include "clock.h"
+#include "coins.h"
+#include "contest_link_80C2020.h"
+#include "contest_painting.h"
+#include "data2.h"
+#include "decoration.h"
+#include "decoration_inventory.h"
+#include "event_data.h"
+#include "field_door.h"
+#include "field_effect.h"
+#include "field_fadetransition.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_specials.h"
+#include "field_tasks.h"
+#include "field_weather.h"
+#include "fieldmap.h"
+#include "item.h"
+#include "main.h"
+#include "map_obj_lock.h"
+#include "menu.h"
+#include "money.h"
+#include "mystery_event_script.h"
+#include "palette.h"
+#include "party_menu.h"
+#include "pokemon.h"
+#include "rng.h"
+#include "overworld.h"
+#include "rtc.h"
+#include "script.h"
+#include "script_menu.h"
+#include "script_movement.h"
+#include "script_pokemon_80C4.h"
+#include "script_pokemon_80F9.h"
+#include "shop.h"
+#include "slot_machine.h"
+#include "sound.h"
+#include "string_util.h"
+#include "tv.h"
+
+typedef u16 (*SpecialFunc)(void);
+typedef void (*NativeFunc)(void);
+
+extern u32 gUnknown_0202E8AC;
+
+static EWRAM_DATA u32 gUnknown_0202E8B0 = 0;
+static EWRAM_DATA u16 sPauseCounter = 0;
+static EWRAM_DATA u16 sMovingNpcId = 0;
+static EWRAM_DATA u16 sMovingNpcMapBank = 0;
+static EWRAM_DATA u16 sMovingNpcMapId = 0;
+static EWRAM_DATA u16 sFieldEffectScriptId = 0;
+
+extern u16 gSpecialVar_0x8000;
+extern u16 gSpecialVar_0x8001;
+extern u16 gSpecialVar_0x8002;
+extern u16 gSpecialVar_0x8004;
+
+extern u16 gScriptResult;
+
+extern u16 gScriptContestCategory;
+
+extern SpecialFunc gSpecials[];
+extern u8 *gStdScripts[];
+extern u8 *gStdScripts_End[];
+
+// This is defined in here so the optimizer can't see its value when compiling
+// script.c.
+void * const gNullScriptPtr = NULL;
+
+static const u8 sScriptConditionTable[6][3] =
+{
+// < = >
+ 1, 0, 0, // <
+ 0, 1, 0, // =
+ 0, 0, 1, // >
+ 1, 1, 0, // <=
+ 0, 1, 1, // >=
+ 1, 0, 1, // !=
+};
+
+static u8 * const sScriptStringVars[] =
+{
+ gStringVar1,
+ gStringVar2,
+ gStringVar3,
+};
+
+bool8 ScrCmd_nop(struct ScriptContext *ctx)
+{
+ return FALSE;
+}
+
+bool8 ScrCmd_nop1(struct ScriptContext *ctx)
+{
+ return FALSE;
+}
+
+bool8 ScrCmd_end(struct ScriptContext *ctx)
+{
+ StopScript(ctx);
+ return FALSE;
+}
+
+bool8 ScrCmd_gotonative(struct ScriptContext *ctx)
+{
+ bool8 (*addr)(void) = (bool8 (*)(void))ScriptReadWord(ctx);
+
+ SetupNativeScript(ctx, addr);
+ return TRUE;
+}
+
+bool8 ScrCmd_special(struct ScriptContext *ctx)
+{
+ u16 index = ScriptReadHalfword(ctx);
+
+ gSpecials[index]();
+ return FALSE;
+}
+
+bool8 ScrCmd_specialvar(struct ScriptContext *ctx)
+{
+ u16 *var = GetVarPointer(ScriptReadHalfword(ctx));
+
+ *var = gSpecials[ScriptReadHalfword(ctx)]();
+ return FALSE;
+}
+
+bool8 ScrCmd_callnative(struct ScriptContext *ctx)
+{
+ NativeFunc func = (NativeFunc)ScriptReadWord(ctx);
+
+ func();
+ return FALSE;
+}
+
+bool8 ScrCmd_waitstate(struct ScriptContext *ctx)
+{
+ ScriptContext1_Stop();
+ return TRUE;
+}
+
+bool8 ScrCmd_goto(struct ScriptContext *ctx)
+{
+ u8 *ptr = (u8 *)ScriptReadWord(ctx);
+
+ ScriptJump(ctx, ptr);
+ return FALSE;
+}
+
+bool8 ScrCmd_return(struct ScriptContext *ctx)
+{
+ ScriptReturn(ctx);
+ return FALSE;
+}
+
+bool8 ScrCmd_call(struct ScriptContext *ctx)
+{
+ u8 *ptr = (u8 *)ScriptReadWord(ctx);
+
+ ScriptCall(ctx, ptr);
+ return FALSE;
+}
+
+bool8 ScrCmd_goto_if(struct ScriptContext *ctx)
+{
+ u8 condition = ScriptReadByte(ctx);
+ u8 *ptr = (u8 *)ScriptReadWord(ctx);
+
+ if (sScriptConditionTable[condition][ctx->comparisonResult] == 1)
+ ScriptJump(ctx, ptr);
+ return FALSE;
+}
+
+bool8 ScrCmd_call_if(struct ScriptContext *ctx)
+{
+ u8 condition = ScriptReadByte(ctx);
+ u8 *ptr = (u8 *)ScriptReadWord(ctx);
+
+ if (sScriptConditionTable[condition][ctx->comparisonResult] == 1)
+ ScriptCall(ctx, ptr);
+ return FALSE;
+}
+
+bool8 ScrCmd_setvaddress(struct ScriptContext *ctx)
+{
+ u32 addr1 = (u32)ctx->scriptPtr - 1;
+ u32 addr2 = ScriptReadWord(ctx);
+
+ gUnknown_0202E8B0 = addr2 - addr1;
+ return FALSE;
+}
+
+bool8 ScrCmd_vgoto(struct ScriptContext *ctx)
+{
+ u32 addr = ScriptReadWord(ctx);
+
+ ScriptJump(ctx, (u8 *)(addr - gUnknown_0202E8B0));
+ return FALSE;
+}
+
+bool8 ScrCmd_vcall(struct ScriptContext *ctx)
+{
+ u32 addr = ScriptReadWord(ctx);
+
+ ScriptCall(ctx, (u8 *)(addr - gUnknown_0202E8B0));
+ return FALSE;
+}
+
+bool8 ScrCmd_vgoto_if(struct ScriptContext *ctx)
+{
+ u8 condition = ScriptReadByte(ctx);
+ u8 *ptr = (u8 *)(ScriptReadWord(ctx) - gUnknown_0202E8B0);
+
+ if (sScriptConditionTable[condition][ctx->comparisonResult] == 1)
+ ScriptJump(ctx, ptr);
+ return FALSE;
+}
+
+bool8 ScrCmd_vcall_if(struct ScriptContext *ctx)
+{
+ u8 condition = ScriptReadByte(ctx);
+ u8 *ptr = (u8 *)(ScriptReadWord(ctx) - gUnknown_0202E8B0);
+
+ if (sScriptConditionTable[condition][ctx->comparisonResult] == 1)
+ ScriptCall(ctx, ptr);
+ return FALSE;
+}
+
+bool8 ScrCmd_gotostd(struct ScriptContext *ctx)
+{
+ u8 index = ScriptReadByte(ctx);
+ u8 **ptr = &gStdScripts[index];
+
+ if (ptr < gStdScripts_End)
+ ScriptJump(ctx, *ptr);
+ return FALSE;
+}
+
+bool8 ScrCmd_callstd(struct ScriptContext *ctx)
+{
+ u8 index = ScriptReadByte(ctx);
+ u8 **ptr = &gStdScripts[index];
+
+ if (ptr < gStdScripts_End)
+ ScriptCall(ctx, *ptr);
+ return FALSE;
+}
+
+bool8 ScrCmd_gotostd_if(struct ScriptContext *ctx)
+{
+ u8 condition = ScriptReadByte(ctx);
+ u8 index = ScriptReadByte(ctx);
+
+ if (sScriptConditionTable[condition][ctx->comparisonResult] == 1)
+ {
+ u8 **ptr = &gStdScripts[index];
+ if (ptr < gStdScripts_End)
+ ScriptJump(ctx, *ptr);
+ }
+ return FALSE;
+}
+
+bool8 ScrCmd_callstd_if(struct ScriptContext *ctx)
+{
+ u8 condition = ScriptReadByte(ctx);
+ u8 index = ScriptReadByte(ctx);
+
+ if (sScriptConditionTable[condition][ctx->comparisonResult] == 1)
+ {
+ u8 **ptr = &gStdScripts[index];
+ if (ptr < gStdScripts_End)
+ ScriptCall(ctx, *ptr);
+ }
+ return FALSE;
+}
+
+bool8 ScrCmd_gotoram(struct ScriptContext *ctx)
+{
+ ScriptJump(ctx, (u8 *)gUnknown_0202E8AC);
+ return FALSE;
+}
+
+bool8 ScrCmd_killscript(struct ScriptContext *ctx)
+{
+ ClearRamScript();
+ StopScript(ctx);
+ return TRUE;
+}
+
+bool8 ScrCmd_setmysteryeventstatus(struct ScriptContext *ctx)
+{
+ u8 value = ScriptReadByte(ctx);
+
+ SetMysteryEventScriptStatus(value);
+ return FALSE;
+}
+
+bool8 ScrCmd_loadword(struct ScriptContext *ctx)
+{
+ u8 index = ScriptReadByte(ctx);
+
+ ctx->data[index] = ScriptReadWord(ctx);
+ return FALSE;
+}
+
+bool8 ScrCmd_loadbytefromaddr(struct ScriptContext *ctx)
+{
+ u8 index = ScriptReadByte(ctx);
+
+ ctx->data[index] = *(u8 *)ScriptReadWord(ctx);
+ return FALSE;
+}
+
+bool8 ScrCmd_writebytetoaddr(struct ScriptContext *ctx)
+{
+ u8 value = ScriptReadByte(ctx);
+
+ *(u8 *)ScriptReadWord(ctx) = value;
+ return FALSE;
+}
+
+bool8 ScrCmd_loadbyte(struct ScriptContext *ctx)
+{
+ u8 index = ScriptReadByte(ctx);
+
+ ctx->data[index] = ScriptReadByte(ctx);
+ return FALSE;
+}
+
+bool8 ScrCmd_setptrbyte(struct ScriptContext *ctx)
+{
+ u8 index = ScriptReadByte(ctx);
+
+ *(u8 *)ScriptReadWord(ctx) = ctx->data[index];
+ return FALSE;
+}
+
+bool8 ScrCmd_copylocal(struct ScriptContext *ctx)
+{
+ u8 destIndex = ScriptReadByte(ctx);
+ u8 srcIndex = ScriptReadByte(ctx);
+
+ ctx->data[destIndex] = ctx->data[srcIndex];
+ return FALSE;
+}
+
+bool8 ScrCmd_copybyte(struct ScriptContext *ctx)
+{
+ u8 *ptr = (u8 *)ScriptReadWord(ctx);
+ *ptr = *(u8 *)ScriptReadWord(ctx);
+ return FALSE;
+}
+
+bool8 ScrCmd_setvar(struct ScriptContext *ctx)
+{
+ u16 *ptr = GetVarPointer(ScriptReadHalfword(ctx));
+ *ptr = ScriptReadHalfword(ctx);
+ return FALSE;
+}
+
+bool8 ScrCmd_copyvar(struct ScriptContext *ctx)
+{
+ u16 *ptr = GetVarPointer(ScriptReadHalfword(ctx));
+ *ptr = *GetVarPointer(ScriptReadHalfword(ctx));
+ return FALSE;
+}
+
+bool8 ScrCmd_setorcopyvar(struct ScriptContext *ctx)
+{
+ u16 *ptr = GetVarPointer(ScriptReadHalfword(ctx));
+ *ptr = VarGet(ScriptReadHalfword(ctx));
+ return FALSE;
+}
+
+u8 compare_012(u16 a1, u16 a2)
+{
+ if (a1 < a2)
+ return 0;
+ if (a1 == a2)
+ return 1;
+ return 2;
+}
+
+// comparelocaltolocal
+bool8 ScrCmd_compare_local_to_local(struct ScriptContext *ctx)
+{
+ u8 value1 = ctx->data[ScriptReadByte(ctx)];
+ u8 value2 = ctx->data[ScriptReadByte(ctx)];
+
+ ctx->comparisonResult = compare_012(value1, value2);
+ return FALSE;
+}
+
+// comparelocaltoimm
+bool8 ScrCmd_compare_local_to_value(struct ScriptContext *ctx)
+{
+ u8 value1 = ctx->data[ScriptReadByte(ctx)];
+ u8 value2 = ScriptReadByte(ctx);
+
+ ctx->comparisonResult = compare_012(value1, value2);
+ return FALSE;
+}
+
+bool8 ScrCmd_compare_local_to_addr(struct ScriptContext *ctx)
+{
+ u8 value1 = ctx->data[ScriptReadByte(ctx)];
+ u8 value2 = *(u8 *)ScriptReadWord(ctx);
+
+ ctx->comparisonResult = compare_012(value1, value2);
+ return FALSE;
+}
+
+bool8 ScrCmd_compare_addr_to_local(struct ScriptContext *ctx)
+{
+ u8 value1 = *(u8 *)ScriptReadWord(ctx);
+ u8 value2 = ctx->data[ScriptReadByte(ctx)];
+
+ ctx->comparisonResult = compare_012(value1, value2);
+ return FALSE;
+}
+
+bool8 ScrCmd_compare_addr_to_value(struct ScriptContext *ctx)
+{
+ u8 value1 = *(u8 *)ScriptReadWord(ctx);
+ u8 value2 = ScriptReadByte(ctx);
+
+ ctx->comparisonResult = compare_012(value1, value2);
+ return FALSE;
+}
+
+bool8 ScrCmd_compare_addr_to_addr(struct ScriptContext *ctx)
+{
+ u8 value1 = *(u8 *)ScriptReadWord(ctx);
+ u8 value2 = *(u8 *)ScriptReadWord(ctx);
+
+ ctx->comparisonResult = compare_012(value1, value2);
+ return FALSE;
+}
+
+bool8 ScrCmd_compare_var_to_value(struct ScriptContext *ctx)
+{
+ u16 value1 = *GetVarPointer(ScriptReadHalfword(ctx));
+ u16 value2 = ScriptReadHalfword(ctx);
+
+ ctx->comparisonResult = compare_012(value1, value2);
+ return FALSE;
+}
+
+bool8 ScrCmd_compare_var_to_var(struct ScriptContext *ctx)
+{
+ u16 *ptr1 = GetVarPointer(ScriptReadHalfword(ctx));
+ u16 *ptr2 = GetVarPointer(ScriptReadHalfword(ctx));
+
+ ctx->comparisonResult = compare_012(*ptr1, *ptr2);
+ return FALSE;
+}
+
+bool8 ScrCmd_addvar(struct ScriptContext *ctx)
+{
+ u16 *ptr = GetVarPointer(ScriptReadHalfword(ctx));
+ *ptr += ScriptReadHalfword(ctx);
+ return FALSE;
+}
+
+bool8 ScrCmd_subvar(struct ScriptContext *ctx)
+{
+ u16 *ptr = GetVarPointer(ScriptReadHalfword(ctx));
+ *ptr -= VarGet(ScriptReadHalfword(ctx));
+ return FALSE;
+}
+
+bool8 ScrCmd_random(struct ScriptContext *ctx)
+{
+ u16 max = VarGet(ScriptReadHalfword(ctx));
+
+ gScriptResult = Random() % max;
+ return FALSE;
+}
+
+bool8 ScrCmd_additem(struct ScriptContext *ctx)
+{
+ u16 itemId = VarGet(ScriptReadHalfword(ctx));
+ u32 quantity = VarGet(ScriptReadHalfword(ctx));
+
+ gScriptResult = AddBagItem(itemId, (u8)quantity);
+ return FALSE;
+}
+
+bool8 ScrCmd_removeitem(struct ScriptContext *ctx)
+{
+ u16 itemId = VarGet(ScriptReadHalfword(ctx));
+ u32 quantity = VarGet(ScriptReadHalfword(ctx));
+
+ gScriptResult = RemoveBagItem(itemId, (u8)quantity);
+ return FALSE;
+}
+
+bool8 ScrCmd_checkitemspace(struct ScriptContext *ctx)
+{
+ u16 itemId = VarGet(ScriptReadHalfword(ctx));
+ u32 quantity = VarGet(ScriptReadHalfword(ctx));
+
+ gScriptResult = CheckBagHasSpace(itemId, (u8)quantity);
+ return FALSE;
+}
+
+bool8 ScrCmd_checkitem(struct ScriptContext *ctx)
+{
+ u16 itemId = VarGet(ScriptReadHalfword(ctx));
+ u32 quantity = VarGet(ScriptReadHalfword(ctx));
+
+ gScriptResult = CheckBagHasItem(itemId, (u8)quantity);
+ return FALSE;
+}
+
+bool8 ScrCmd_checkitemtype(struct ScriptContext *ctx)
+{
+ u16 itemId = VarGet(ScriptReadHalfword(ctx));
+
+ gScriptResult = GetPocketByItemId(itemId);
+ return FALSE;
+}
+
+bool8 ScrCmd_addpcitem(struct ScriptContext *ctx)
+{
+ u16 itemId = VarGet(ScriptReadHalfword(ctx));
+ u16 quantity = VarGet(ScriptReadHalfword(ctx));
+
+ gScriptResult = AddPCItem(itemId, quantity);
+ return FALSE;
+}
+
+bool8 ScrCmd_checkpcitem(struct ScriptContext *ctx)
+{
+ u16 itemId = VarGet(ScriptReadHalfword(ctx));
+ u16 quantity = VarGet(ScriptReadHalfword(ctx));
+
+ gScriptResult = CheckPCHasItem(itemId, quantity);
+ return FALSE;
+}
+
+bool8 ScrCmd_adddecor(struct ScriptContext *ctx)
+{
+ u32 decorId = VarGet(ScriptReadHalfword(ctx));
+
+ gScriptResult = IsThereStorageSpaceForDecoration(decorId);
+ return FALSE;
+}
+
+bool8 ScrCmd_removedecor(struct ScriptContext *ctx)
+{
+ u32 decorId = VarGet(ScriptReadHalfword(ctx));
+
+ gScriptResult = sub_81340A8(decorId);
+ return FALSE;
+}
+
+bool8 ScrCmd_checkdecor(struct ScriptContext *ctx)
+{
+ u32 decorId = VarGet(ScriptReadHalfword(ctx));
+
+ gScriptResult = sub_8134074(decorId);
+ return FALSE;
+}
+
+bool8 ScrCmd_hasdecor(struct ScriptContext *ctx)
+{
+ u32 decorId = VarGet(ScriptReadHalfword(ctx));
+
+ gScriptResult = sub_8133FE4(decorId);
+ return FALSE;
+}
+
+bool8 ScrCmd_setflag(struct ScriptContext *ctx)
+{
+ FlagSet(ScriptReadHalfword(ctx));
+ return FALSE;
+}
+
+bool8 ScrCmd_clearflag(struct ScriptContext *ctx)
+{
+ FlagClear(ScriptReadHalfword(ctx));
+ return FALSE;
+}
+
+bool8 ScrCmd_checkflag(struct ScriptContext *ctx)
+{
+ ctx->comparisonResult = FlagGet(ScriptReadHalfword(ctx));
+ return FALSE;
+}
+
+bool8 ScrCmd_incrementgamestat(struct ScriptContext *ctx)
+{
+ IncrementGameStat(ScriptReadByte(ctx));
+ return FALSE;
+}
+
+bool8 ScrCmd_animdarklevel(struct ScriptContext *ctx)
+{
+ sub_8081594(ScriptReadByte(ctx));
+ ScriptContext1_Stop();
+ return TRUE;
+}
+
+bool8 ScrCmd_setdarklevel(struct ScriptContext *ctx)
+{
+ u16 flashLevel = VarGet(ScriptReadHalfword(ctx));
+
+ Overworld_SetFlashLevel(flashLevel);
+ return FALSE;
+}
+
+bool8 IsPaletteNotActive(void)
+{
+ if (!gPaletteFade.active)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 ScrCmd_fadescreen(struct ScriptContext *ctx)
+{
+ fade_screen(ScriptReadByte(ctx), 0);
+ SetupNativeScript(ctx, IsPaletteNotActive);
+ return TRUE;
+}
+
+bool8 ScrCmd_fadescreendelay(struct ScriptContext *ctx)
+{
+ u8 duration = ScriptReadByte(ctx);
+ u8 delay = ScriptReadByte(ctx);
+
+ fade_screen(duration, delay);
+ SetupNativeScript(ctx, IsPaletteNotActive);
+ return TRUE;
+}
+
+bool8 s28_pause_asm()
+{
+ sPauseCounter--;
+
+ if (sPauseCounter == 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 ScrCmd_delay(struct ScriptContext *ctx)
+{
+ sPauseCounter = ScriptReadHalfword(ctx);
+ SetupNativeScript(ctx, s28_pause_asm);
+ return TRUE;
+}
+
+bool8 ScrCmd_initclock(struct ScriptContext *ctx)
+{
+ u8 hour = VarGet(ScriptReadHalfword(ctx));
+ u8 minute = VarGet(ScriptReadHalfword(ctx));
+
+ RtcInitLocalTimeOffset(hour, minute);
+ return FALSE;
+}
+
+bool8 ScrCmd_dodailyevents(struct ScriptContext *ctx)
+{
+ DoTimeBasedEvents();
+ return FALSE;
+}
+
+bool8 ScrCmd_gettime(struct ScriptContext *ctx)
+{
+ RtcCalcLocalTime();
+ gSpecialVar_0x8000 = gLocalTime.hours;
+ gSpecialVar_0x8001 = gLocalTime.minutes;
+ gSpecialVar_0x8002 = gLocalTime.seconds;
+ return FALSE;
+}
+
+bool8 ScrCmd_setweather(struct ScriptContext *ctx)
+{
+ u16 weather = VarGet(ScriptReadHalfword(ctx));
+
+ SetSav1Weather(weather);
+ return FALSE;
+}
+
+bool8 ScrCmd_resetweather(struct ScriptContext *ctx)
+{
+ sub_80806E4();
+ return FALSE;
+}
+
+bool8 ScrCmd_doweather(struct ScriptContext *ctx)
+{
+ DoCurrentWeather();
+ return FALSE;
+}
+
+bool8 ScrCmd_tileeffect(struct ScriptContext *ctx)
+{
+ ActivatePerStepCallback(ScriptReadByte(ctx));
+ return FALSE;
+}
+
+bool8 ScrCmd_setmaplayoutindex(struct ScriptContext *ctx)
+{
+ u16 value = VarGet(ScriptReadHalfword(ctx));
+
+ sub_8053D14(value);
+ return FALSE;
+}
+
+bool8 ScrCmd_warp(struct ScriptContext *ctx)
+{
+ u8 mapGroup = ScriptReadByte(ctx);
+ u8 mapNum = ScriptReadByte(ctx);
+ u8 warpId = ScriptReadByte(ctx);
+ u16 x = VarGet(ScriptReadHalfword(ctx));
+ u16 y = VarGet(ScriptReadHalfword(ctx));
+
+ Overworld_SetWarpDestination(mapGroup, mapNum, warpId, x, y);
+ sub_8080E88();
+ player_avatar_init_params_reset();
+ return TRUE;
+}
+
+bool8 ScrCmd_warpsilent(struct ScriptContext *ctx)
+{
+ u8 mapGroup = ScriptReadByte(ctx);
+ u8 mapNum = ScriptReadByte(ctx);
+ u8 warpId = ScriptReadByte(ctx);
+ u16 x = VarGet(ScriptReadHalfword(ctx));
+ u16 y = VarGet(ScriptReadHalfword(ctx));
+
+ Overworld_SetWarpDestination(mapGroup, mapNum, warpId, x, y);
+ sp13E_warp_to_last_warp();
+ player_avatar_init_params_reset();
+ return TRUE;
+}
+
+bool8 ScrCmd_warpdoor(struct ScriptContext *ctx)
+{
+ u8 mapGroup = ScriptReadByte(ctx);
+ u8 mapNum = ScriptReadByte(ctx);
+ u8 warpId = ScriptReadByte(ctx);
+ u16 x = VarGet(ScriptReadHalfword(ctx));
+ u16 y = VarGet(ScriptReadHalfword(ctx));
+
+ Overworld_SetWarpDestination(mapGroup, mapNum, warpId, x, y);
+ sub_8080EF0();
+ player_avatar_init_params_reset();
+ return TRUE;
+}
+
+bool8 ScrCmd_warphole(struct ScriptContext *ctx)
+{
+ u8 mapGroup = ScriptReadByte(ctx);
+ u8 mapNum = ScriptReadByte(ctx);
+ u16 x;
+ u16 y;
+
+ PlayerGetDestCoords(&x, &y);
+ if (mapGroup == 0xFF && mapNum == 0xFF)
+ sub_8053720(x - 7, y - 7);
+ else
+ Overworld_SetWarpDestination(mapGroup, mapNum, -1, x - 7, y - 7);
+ sp13F_fall_to_last_warp();
+ player_avatar_init_params_reset();
+ return TRUE;
+}
+
+bool8 ScrCmd_warpteleport(struct ScriptContext *ctx)
+{
+ u8 mapGroup = ScriptReadByte(ctx);
+ u8 mapNum = ScriptReadByte(ctx);
+ u8 warpId = ScriptReadByte(ctx);
+ u16 x = VarGet(ScriptReadHalfword(ctx));
+ u16 y = VarGet(ScriptReadHalfword(ctx));
+
+ Overworld_SetWarpDestination(mapGroup, mapNum, warpId, x, y);
+ sub_8080F68();
+ player_avatar_init_params_reset();
+ return TRUE;
+}
+
+bool8 ScrCmd_setwarp(struct ScriptContext *ctx)
+{
+ u8 mapGroup = ScriptReadByte(ctx);
+ u8 mapNum = ScriptReadByte(ctx);
+ u8 warpId = ScriptReadByte(ctx);
+ u16 x = VarGet(ScriptReadHalfword(ctx));
+ u16 y = VarGet(ScriptReadHalfword(ctx));
+
+ Overworld_SetWarpDestination(mapGroup, mapNum, warpId, x, y);
+ return FALSE;
+}
+
+bool8 ScrCmd_setdynamicwarp(struct ScriptContext *ctx)
+{
+ u8 mapGroup = ScriptReadByte(ctx);
+ u8 mapNum = ScriptReadByte(ctx);
+ u8 warpId = ScriptReadByte(ctx);
+ u16 x = VarGet(ScriptReadHalfword(ctx));
+ u16 y = VarGet(ScriptReadHalfword(ctx));
+
+ saved_warp2_set_2(0, mapGroup, mapNum, warpId, x, y);
+ return FALSE;
+}
+
+bool8 ScrCmd_setdivewarp(struct ScriptContext *ctx)
+{
+ u8 mapGroup = ScriptReadByte(ctx);
+ u8 mapNum = ScriptReadByte(ctx);
+ u8 warpId = ScriptReadByte(ctx);
+ u16 x = VarGet(ScriptReadHalfword(ctx));
+ u16 y = VarGet(ScriptReadHalfword(ctx));
+
+ sub_8053690(mapGroup, mapNum, warpId, x, y);
+ return FALSE;
+}
+
+bool8 ScrCmd_setholewarp(struct ScriptContext *ctx)
+{
+ u8 mapGroup = ScriptReadByte(ctx);
+ u8 mapNum = ScriptReadByte(ctx);
+ u8 warpId = ScriptReadByte(ctx);
+ u16 x = VarGet(ScriptReadHalfword(ctx));
+ u16 y = VarGet(ScriptReadHalfword(ctx));
+
+ sub_80536E4(mapGroup, mapNum, warpId, x, y);
+ return FALSE;
+}
+
+bool8 ScrCmd_setescapewarp(struct ScriptContext *ctx)
+{
+ u8 mapGroup = ScriptReadByte(ctx);
+ u8 mapNum = ScriptReadByte(ctx);
+ u8 warpId = ScriptReadByte(ctx);
+ u16 x = VarGet(ScriptReadHalfword(ctx));
+ u16 y = VarGet(ScriptReadHalfword(ctx));
+
+ sub_805363C(mapGroup, mapNum, warpId, x, y);
+ return FALSE;
+}
+
+bool8 ScrCmd_getplayerxy(struct ScriptContext *ctx)
+{
+ u16 *pX = GetVarPointer(ScriptReadHalfword(ctx));
+ u16 *pY = GetVarPointer(ScriptReadHalfword(ctx));
+
+ *pX = gSaveBlock1.pos.x;
+ *pY = gSaveBlock1.pos.y;
+ return FALSE;
+}
+
+bool8 ScrCmd_countpokemon(struct ScriptContext *ctx)
+{
+ gScriptResult = CalculatePlayerPartyCount();
+ return FALSE;
+}
+
+bool8 ScrCmd_playse(struct ScriptContext *ctx)
+{
+ PlaySE(ScriptReadHalfword(ctx));
+ return FALSE;
+}
+
+static bool8 WaitForSoundEffectFinish()
+{
+ if (!IsSEPlaying())
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 ScrCmd_waitse(struct ScriptContext *ctx)
+{
+ SetupNativeScript(ctx, WaitForSoundEffectFinish);
+ return TRUE;
+}
+
+bool8 ScrCmd_playfanfare(struct ScriptContext *ctx)
+{
+ PlayFanfare(ScriptReadHalfword(ctx));
+ return FALSE;
+}
+
+static bool8 WaitForFanfareFinish()
+{
+ return IsFanfareTaskInactive();
+}
+
+bool8 ScrCmd_waitfanfare(struct ScriptContext *ctx)
+{
+ SetupNativeScript(ctx, WaitForFanfareFinish);
+ return TRUE;
+}
+
+bool8 ScrCmd_playbgm(struct ScriptContext *ctx)
+{
+ u16 songId = ScriptReadHalfword(ctx);
+ bool8 val = ScriptReadByte(ctx);
+
+ if (val == TRUE)
+ Overworld_SetSavedMusic(songId);
+ PlayNewMapMusic(songId);
+ return FALSE;
+}
+
+bool8 ScrCmd_savebgm(struct ScriptContext *ctx)
+{
+ Overworld_SetSavedMusic(ScriptReadHalfword(ctx));
+ return FALSE;
+}
+
+bool8 ScrCmd_fadedefaultbgm(struct ScriptContext *ctx)
+{
+ Overworld_ChangeMusicToDefault();
+ return FALSE;
+}
+
+bool8 ScrCmd_fadenewbgm(struct ScriptContext *ctx)
+{
+ Overworld_ChangeMusicTo(ScriptReadHalfword(ctx));
+ return FALSE;
+}
+
+bool8 ScrCmd_fadeoutbgm(struct ScriptContext *ctx)
+{
+ u8 speed = ScriptReadByte(ctx);
+
+ if (speed != 0)
+ FadeOutBGMTemporarily(4 * speed);
+ else
+ FadeOutBGMTemporarily(4);
+ SetupNativeScript(ctx, IsBGMPausedOrStopped);
+ return TRUE;
+}
+
+bool8 ScrCmd_fadeinbgm(struct ScriptContext *ctx)
+{
+ u8 speed = ScriptReadByte(ctx);
+
+ if (speed != 0)
+ FadeInBGM(4 * speed);
+ else
+ FadeInBGM(4);
+ return FALSE;
+}
+
+bool8 ScrCmd_applymovement(struct ScriptContext *ctx)
+{
+ u16 localId = VarGet(ScriptReadHalfword(ctx));
+ void *movementScript = (void *)ScriptReadWord(ctx);
+
+ ScriptMovement_StartObjectMovementScript(localId, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup, movementScript);
+ sMovingNpcId = localId;
+ return FALSE;
+}
+
+bool8 ScrCmd_applymovement_at(struct ScriptContext *ctx)
+{
+ u16 localId = VarGet(ScriptReadHalfword(ctx));
+ void *movementScript = (void *)ScriptReadWord(ctx);
+ u8 mapGroup = ScriptReadByte(ctx);
+ u8 mapNum = ScriptReadByte(ctx);
+
+ ScriptMovement_StartObjectMovementScript(localId, mapNum, mapGroup, movementScript);
+ sMovingNpcId = localId;
+ return FALSE;
+}
+
+static bool8 WaitForMovementFinish(void)
+{
+ return ScriptMovement_IsObjectMovementFinished(sMovingNpcId, sMovingNpcMapId, sMovingNpcMapBank);
+}
+
+bool8 ScrCmd_waitmovement(struct ScriptContext *ctx)
+{
+ u16 localId = VarGet(ScriptReadHalfword(ctx));
+
+ if (localId != 0)
+ sMovingNpcId = localId;
+ sMovingNpcMapBank = gSaveBlock1.location.mapGroup;
+ sMovingNpcMapId = gSaveBlock1.location.mapNum;
+ SetupNativeScript(ctx, WaitForMovementFinish);
+ return TRUE;
+}
+
+bool8 ScrCmd_waitmovement_at(struct ScriptContext *ctx)
+{
+ u16 localId = VarGet(ScriptReadHalfword(ctx));
+ u8 mapBank;
+ u8 mapId;
+
+ if (localId != 0)
+ sMovingNpcId = localId;
+ mapBank = ScriptReadByte(ctx);
+ mapId = ScriptReadByte(ctx);
+ sMovingNpcMapBank = mapBank;
+ sMovingNpcMapId = mapId;
+ SetupNativeScript(ctx, WaitForMovementFinish);
+ return TRUE;
+}
+
+bool8 ScrCmd_removeobject(struct ScriptContext *ctx)
+{
+ u16 localId = VarGet(ScriptReadHalfword(ctx));
+
+ RemoveFieldObjectByLocalIdAndMap(localId, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup);
+ return FALSE;
+}
+
+bool8 ScrCmd_removeobject_at(struct ScriptContext *ctx)
+{
+ u16 objectId = VarGet(ScriptReadHalfword(ctx));
+ u8 mapGroup = ScriptReadByte(ctx);
+ u8 mapNum = ScriptReadByte(ctx);
+
+ RemoveFieldObjectByLocalIdAndMap(objectId, mapNum, mapGroup);
+ return FALSE;
+}
+
+bool8 ScrCmd_addobject(struct ScriptContext *ctx)
+{
+ u16 objectId = VarGet(ScriptReadHalfword(ctx));
+
+ show_sprite(objectId, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup);
+ return FALSE;
+}
+
+bool8 ScrCmd_addobject_at(struct ScriptContext *ctx)
+{
+ u16 objectId = VarGet(ScriptReadHalfword(ctx));
+ u8 mapGroup = ScriptReadByte(ctx);
+ u8 mapNum = ScriptReadByte(ctx);
+
+ show_sprite(objectId, mapNum, mapGroup);
+ return FALSE;
+}
+
+bool8 ScrCmd_setobjectxy(struct ScriptContext *ctx)
+{
+ u16 localId = VarGet(ScriptReadHalfword(ctx));
+ u16 x = VarGet(ScriptReadHalfword(ctx));
+ u16 y = VarGet(ScriptReadHalfword(ctx));
+
+ sub_805C0F8(localId, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup, x, y);
+ return FALSE;
+}
+
+bool8 ScrCmd_setobjectxyperm(struct ScriptContext *ctx)
+{
+ u16 localId = VarGet(ScriptReadHalfword(ctx));
+ u16 x = VarGet(ScriptReadHalfword(ctx));
+ u16 y = VarGet(ScriptReadHalfword(ctx));
+
+ Overworld_SetMapObjTemplateCoords(localId, x, y);
+ return FALSE;
+}
+
+bool8 ScrCmd_moveobjectoffscreen(struct ScriptContext *ctx)
+{
+ u16 localId = VarGet(ScriptReadHalfword(ctx));
+
+ sub_805C78C(localId, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup);
+ return FALSE;
+}
+
+bool8 ScrCmd_showobject(struct ScriptContext *ctx)
+{
+ u16 localId = VarGet(ScriptReadHalfword(ctx));
+ u8 mapGroup = ScriptReadByte(ctx);
+ u8 mapNum = ScriptReadByte(ctx);
+
+ npc_by_local_id_and_map_set_field_1_bit_x20(localId, mapNum, mapGroup, 0);
+ return FALSE;
+}
+
+bool8 ScrCmd_hideobject(struct ScriptContext *ctx)
+{
+ u16 localId = VarGet(ScriptReadHalfword(ctx));
+ u8 mapGroup = ScriptReadByte(ctx);
+ u8 mapNum = ScriptReadByte(ctx);
+
+ npc_by_local_id_and_map_set_field_1_bit_x20(localId, mapNum, mapGroup, 1);
+ return FALSE;
+}
+
+bool8 ScrCmd_setobjectpriority(struct ScriptContext *ctx)
+{
+ u16 localId = VarGet(ScriptReadHalfword(ctx));
+ u8 mapGroup = ScriptReadByte(ctx);
+ u8 mapNum = ScriptReadByte(ctx);
+ u8 priority = ScriptReadByte(ctx);
+
+ sub_805BCF0(localId, mapNum, mapGroup, priority + 83);
+ return FALSE;
+}
+
+bool8 ScrCmd_resetobjectpriority(struct ScriptContext *ctx)
+{
+ u16 localId = VarGet(ScriptReadHalfword(ctx));
+ u8 mapGroup = ScriptReadByte(ctx);
+ u8 mapNum = ScriptReadByte(ctx);
+
+ sub_805BD48(localId, mapNum, mapGroup);
+ return FALSE;
+}
+
+bool8 ScrCmd_faceplayer(struct ScriptContext *ctx)
+{
+ if (gMapObjects[gSelectedMapObject].active)
+ {
+ FieldObjectFaceOppositeDirection(&gMapObjects[gSelectedMapObject],
+ player_get_direction_lower_nybble());
+ }
+ return FALSE;
+}
+
+bool8 ScrCmd_turnobject(struct ScriptContext *ctx)
+{
+ u16 localId = VarGet(ScriptReadHalfword(ctx));
+ u8 direction = ScriptReadByte(ctx);
+
+ FieldObjectTurnByLocalIdAndMap(localId, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup, direction);
+ return FALSE;
+}
+
+bool8 ScrCmd_setobjectmovementtype(struct ScriptContext *ctx)
+{
+ u16 localId = VarGet(ScriptReadHalfword(ctx));
+ u8 movementType = ScriptReadByte(ctx);
+
+ Overworld_SetMapObjTemplateMovementType(localId, movementType);
+ return FALSE;
+}
+
+bool8 ScrCmd_createvobject(struct ScriptContext *ctx)
+{
+ u8 graphicsId = ScriptReadByte(ctx);
+ u8 v2 = ScriptReadByte(ctx);
+ u16 x = VarGet(ScriptReadHalfword(ctx));
+ u32 y = VarGet(ScriptReadHalfword(ctx));
+ u8 elevation = ScriptReadByte(ctx);
+ u8 direction = ScriptReadByte(ctx);
+
+ sub_805B410(graphicsId, v2, x, y, elevation, direction);
+ return FALSE;
+}
+
+bool8 ScrCmd_turnvobject(struct ScriptContext *ctx)
+{
+ u8 v1 = ScriptReadByte(ctx);
+ u8 direction = ScriptReadByte(ctx);
+
+ sub_8064990(v1, direction);
+ return FALSE;
+}
+
+bool8 ScrCmd_lockall(struct ScriptContext *ctx)
+{
+ if (is_c1_link_related_active())
+ {
+ return FALSE;
+ }
+ else
+ {
+ ScriptFreezeMapObjects();
+ SetupNativeScript(ctx, sub_8064CFC);
+ return TRUE;
+ }
+}
+
+bool8 ScrCmd_lock(struct ScriptContext *ctx)
+{
+ if (is_c1_link_related_active())
+ {
+ return FALSE;
+ }
+ else
+ {
+ if (gMapObjects[gSelectedMapObject].active)
+ {
+ LockSelectedMapObject();
+ SetupNativeScript(ctx, sub_8064DB4);
+ }
+ else
+ {
+ ScriptFreezeMapObjects();
+ SetupNativeScript(ctx, sub_8064CFC);
+ }
+ return TRUE;
+ }
+}
+
+bool8 ScrCmd_releaseall(struct ScriptContext *ctx)
+{
+ u8 objectId;
+
+ HideFieldMessageBox();
+ objectId = GetFieldObjectIdByLocalIdAndMap(0xFF, 0, 0);
+ FieldObjectClearAnimIfSpecialAnimFinished(&gMapObjects[objectId]);
+ sub_80A2178();
+ UnfreezeMapObjects();
+ return FALSE;
+}
+
+bool8 ScrCmd_release(struct ScriptContext *ctx)
+{
+ u8 objectId;
+
+ HideFieldMessageBox();
+ if (gMapObjects[gSelectedMapObject].active)
+ FieldObjectClearAnimIfSpecialAnimFinished(&gMapObjects[gSelectedMapObject]);
+ objectId = GetFieldObjectIdByLocalIdAndMap(0xFF, 0, 0);
+ FieldObjectClearAnimIfSpecialAnimFinished(&gMapObjects[objectId]);
+ sub_80A2178();
+ UnfreezeMapObjects();
+ return FALSE;
+}
+
+bool8 ScrCmd_message(struct ScriptContext *ctx)
+{
+ u8 *msg = (u8 *)ScriptReadWord(ctx);
+
+ if (msg == NULL)
+ msg = (u8 *)ctx->data[0];
+ ShowFieldMessage(msg);
+ return FALSE;
+}
+
+bool8 ScrCmd_messageautoscroll(struct ScriptContext *ctx)
+{
+ u8 *msg = (u8 *)ScriptReadWord(ctx);
+
+ if (msg == NULL)
+ msg = (u8 *)ctx->data[0];
+ ShowFieldAutoScrollMessage(msg);
+ return FALSE;
+}
+
+bool8 ScrCmd_waitmessage(struct ScriptContext *ctx)
+{
+ SetupNativeScript(ctx, IsFieldMessageBoxHidden);
+ return TRUE;
+}
+
+bool8 ScrCmd_closemessage(struct ScriptContext *ctx)
+{
+ HideFieldMessageBox();
+ return FALSE;
+}
+
+static bool8 WaitForAorBPress(void)
+{
+ if (gMain.newKeys & A_BUTTON)
+ return TRUE;
+ if (gMain.newKeys & B_BUTTON)
+ return TRUE;
+ return FALSE;
+}
+
+bool8 ScrCmd_waitbutton(struct ScriptContext *ctx)
+{
+ SetupNativeScript(ctx, WaitForAorBPress);
+ return TRUE;
+}
+
+bool8 ScrCmd_yesnobox(struct ScriptContext *ctx)
+{
+ u8 left = ScriptReadByte(ctx);
+ u8 top = ScriptReadByte(ctx);
+
+ if (ScriptMenu_YesNo(left, top) == TRUE)
+ {
+ ScriptContext1_Stop();
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+bool8 ScrCmd_multichoice(struct ScriptContext *ctx)
+{
+ u8 left = ScriptReadByte(ctx);
+ u8 top = ScriptReadByte(ctx);
+ u8 multichoiceId = ScriptReadByte(ctx);
+ u8 ignoreBPress = ScriptReadByte(ctx);
+
+ if (ScriptMenu_Multichoice(left, top, multichoiceId, ignoreBPress) == TRUE)
+ {
+ ScriptContext1_Stop();
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+bool8 ScrCmd_multichoicedefault(struct ScriptContext *ctx)
+{
+ u8 left = ScriptReadByte(ctx);
+ u8 top = ScriptReadByte(ctx);
+ u8 multichoiceId = ScriptReadByte(ctx);
+ u8 defaultChoice = ScriptReadByte(ctx);
+ u8 ignoreBPress = ScriptReadByte(ctx);
+
+ if (ScriptMenu_MultichoiceWithDefault(left, top, multichoiceId, ignoreBPress, defaultChoice) == TRUE)
+ {
+ ScriptContext1_Stop();
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+bool8 ScrCmd_drawbox(struct ScriptContext *ctx)
+{
+ u8 left = ScriptReadByte(ctx);
+ u8 top = ScriptReadByte(ctx);
+ u8 right = ScriptReadByte(ctx);
+ u8 bottom = ScriptReadByte(ctx);
+
+ MenuDrawTextWindow(left, top, right, bottom);
+ return FALSE;
+}
+
+bool8 ScrCmd_multichoicegrid(struct ScriptContext *ctx)
+{
+ u8 left = ScriptReadByte(ctx);
+ u8 top = ScriptReadByte(ctx);
+ u8 multichoiceId = ScriptReadByte(ctx);
+ u8 numColumns = ScriptReadByte(ctx);
+ u8 ignoreBPress = ScriptReadByte(ctx);
+
+ if (ScriptMenu_MultichoiceGrid(left, top, multichoiceId, ignoreBPress, numColumns) == TRUE)
+ {
+ ScriptContext1_Stop();
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+bool8 ScrCmd_erasebox(struct ScriptContext *ctx)
+{
+ u8 left = ScriptReadByte(ctx);
+ u8 top = ScriptReadByte(ctx);
+ u8 right = ScriptReadByte(ctx);
+ u8 bottom = ScriptReadByte(ctx);
+
+ MenuZeroFillWindowRect(left, top, right, bottom);
+ return FALSE;
+}
+
+// unused
+bool8 ScrCmd_drawboxtext(struct ScriptContext *ctx)
+{
+ u8 left = ScriptReadByte(ctx);
+ u8 top = ScriptReadByte(ctx);
+ u8 multichoiceId = ScriptReadByte(ctx);
+ u8 ignoreBPress = ScriptReadByte(ctx);
+
+ if (Multichoice(left, top, multichoiceId, ignoreBPress) == TRUE)
+ {
+ ScriptContext1_Stop();
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+bool8 ScrCmd_drawpokepic(struct ScriptContext *ctx)
+{
+ u16 species = VarGet(ScriptReadHalfword(ctx));
+ u8 x = ScriptReadByte(ctx);
+ u8 y = ScriptReadByte(ctx);
+
+ ScriptMenu_ShowPokemonPic(species, x, y);
+ return FALSE;
+}
+
+bool8 ScrCmd_erasepokepic(struct ScriptContext *ctx)
+{
+ bool8 (*func)(void) = ScriptMenu_GetPicboxWaitFunc();
+
+ if (func == NULL)
+ return FALSE;
+ SetupNativeScript(ctx, func);
+ return TRUE;
+}
+
+bool8 ScrCmd_drawcontestwinner(struct ScriptContext *ctx)
+{
+ u8 v1 = ScriptReadByte(ctx);
+
+ if (v1)
+ sub_8106630(v1);
+ ShowContestWinner();
+ ScriptContext1_Stop();
+ return TRUE;
+}
+
+bool8 ScrCmd_braillemessage(struct ScriptContext *ctx)
+{
+ u8 *ptr = (u8 *)ScriptReadWord(ctx);
+
+ u8 v2 = ptr[0];
+ u8 v3 = ptr[1];
+ u8 v4 = ptr[2];
+ u8 v5 = ptr[3];
+ u8 v6 = ptr[4];
+ u8 v7 = ptr[5];
+ StringBraille(gStringVar4, ptr + 6);
+ MenuDrawTextWindow(v2, v3, v4, v5);
+ MenuPrint(gStringVar4, v6, v7);
+ return FALSE;
+}
+
+bool8 ScrCmd_vmessage(struct ScriptContext *ctx)
+{
+ u32 v1 = ScriptReadWord(ctx);
+
+ ShowFieldMessage((u8 *)(v1 - gUnknown_0202E8B0));
+ return FALSE;
+}
+
+bool8 ScrCmd_getspeciesname(struct ScriptContext *ctx)
+{
+ u8 stringVarIndex = ScriptReadByte(ctx);
+ u16 species = VarGet(ScriptReadHalfword(ctx));
+
+ StringCopy(sScriptStringVars[stringVarIndex], gSpeciesNames[species]);
+ return FALSE;
+}
+
+bool8 ScrCmd_getfirstpartypokename(struct ScriptContext *ctx)
+{
+ u8 stringVarIndex = ScriptReadByte(ctx);
+
+ u8 *dest = sScriptStringVars[stringVarIndex];
+ u8 partyIndex = GetLeadMonIndex();
+ u32 species = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPECIES, NULL);
+ StringCopy(dest, gSpeciesNames[species]);
+ return FALSE;
+}
+
+bool8 ScrCmd_getpartypokename(struct ScriptContext *ctx)
+{
+ u8 stringVarIndex = ScriptReadByte(ctx);
+ u16 partyIndex = VarGet(ScriptReadHalfword(ctx));
+
+ GetMonData(&gPlayerParty[partyIndex], MON_DATA_NICKNAME, sScriptStringVars[stringVarIndex]);
+ StringGetEnd10(sScriptStringVars[stringVarIndex]);
+ return FALSE;
+}
+
+bool8 ScrCmd_getitemname(struct ScriptContext *ctx)
+{
+ u8 stringVarIndex = ScriptReadByte(ctx);
+ u16 itemId = VarGet(ScriptReadHalfword(ctx));
+
+ CopyItemName(itemId, sScriptStringVars[stringVarIndex]);
+ return FALSE;
+}
+
+bool8 ScrCmd_getdecorname(struct ScriptContext *ctx)
+{
+ u8 stringVarIndex = ScriptReadByte(ctx);
+ u16 decorId = VarGet(ScriptReadHalfword(ctx));
+
+ StringCopy(sScriptStringVars[stringVarIndex], gDecorations[decorId].name);
+ return FALSE;
+}
+
+bool8 ScrCmd_getmovename(struct ScriptContext *ctx)
+{
+ u8 stringVarIndex = ScriptReadByte(ctx);
+ u16 moveId = VarGet(ScriptReadHalfword(ctx));
+
+ StringCopy(sScriptStringVars[stringVarIndex], gMoveNames[moveId]);
+ return FALSE;
+}
+
+bool8 ScrCmd_getnumberstring(struct ScriptContext *ctx)
+{
+ u8 stringVarIndex = ScriptReadByte(ctx);
+ u16 v1 = VarGet(ScriptReadHalfword(ctx));
+ u8 v2 = sub_80BF0B8(v1);
+
+ ConvertIntToDecimalStringN(sScriptStringVars[stringVarIndex], v1, 0, v2);
+ return FALSE;
+}
+
+bool8 ScrCmd_getstdstring(struct ScriptContext *ctx)
+{
+ u8 stringVarIndex = ScriptReadByte(ctx);
+ u16 index = VarGet(ScriptReadHalfword(ctx));
+
+ StringCopy(sScriptStringVars[stringVarIndex], gUnknown_083CE048[index]);
+ return FALSE;
+}
+
+bool8 ScrCmd_getstring(struct ScriptContext *ctx)
+{
+ u8 stringVarIndex = ScriptReadByte(ctx);
+ u8 *text = (u8 *)ScriptReadWord(ctx);
+
+ StringCopy(sScriptStringVars[stringVarIndex], text);
+ return FALSE;
+}
+
+bool8 ScrCmd_vloadword(struct ScriptContext *ctx)
+{
+ u8 *ptr = (u8 *)(ScriptReadWord(ctx) - gUnknown_0202E8B0);
+
+ StringExpandPlaceholders(gStringVar4, ptr);
+ return FALSE;
+}
+
+bool8 ScrCmd_vgetstring(struct ScriptContext *ctx)
+{
+ u8 stringVarIndex = ScriptReadByte(ctx);
+ u32 addr = ScriptReadWord(ctx);
+
+ u8 *src = (u8 *)(addr - gUnknown_0202E8B0);
+ u8 *dest = sScriptStringVars[stringVarIndex];
+ StringCopy(dest, src);
+ return FALSE;
+}
+
+bool8 ScrCmd_givepoke(struct ScriptContext *ctx)
+{
+ u16 species = VarGet(ScriptReadHalfword(ctx));
+ u8 level = ScriptReadByte(ctx);
+ u16 item = VarGet(ScriptReadHalfword(ctx));
+ u32 unkParam1 = ScriptReadWord(ctx);
+ u32 unkParam2 = ScriptReadWord(ctx);
+ u8 unkParam3 = ScriptReadByte(ctx);
+
+ gScriptResult = ScriptGiveMon(species, level, item, unkParam1, unkParam2, unkParam3);
+ return FALSE;
+}
+
+bool8 ScrCmd_giveegg(struct ScriptContext *ctx)
+{
+ u16 species = VarGet(ScriptReadHalfword(ctx));
+
+ gScriptResult = ScriptGiveEgg(species);
+ return FALSE;
+}
+
+bool8 ScrCmd_setpokemove(struct ScriptContext *ctx)
+{
+ u8 partyIndex = ScriptReadByte(ctx);
+ u8 slot = ScriptReadByte(ctx);
+ u16 move = ScriptReadHalfword(ctx);
+
+ ScriptSetMonMoveSlot(partyIndex, move, slot);
+ return FALSE;
+}
+
+bool8 ScrCmd_checkpokemove(struct ScriptContext *ctx)
+{
+ u8 i;
+ u16 moveId = ScriptReadHalfword(ctx);
+
+ gScriptResult = 6;
+ for (i = 0; i < 6; i++)
+ {
+ u16 species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL);
+ if (!species)
+ break;
+ // UB: GetMonData() arguments don't match function definition
+ if (!GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG) && pokemon_has_move(&gPlayerParty[i], moveId) == TRUE)
+ {
+ gScriptResult = i;
+ gSpecialVar_0x8004 = species;
+ break;
+ }
+ }
+ return FALSE;
+}
+
+bool8 ScrCmd_givemoney(struct ScriptContext *ctx)
+{
+ u32 amount = ScriptReadWord(ctx);
+ u8 ignore = ScriptReadByte(ctx);
+
+ if (!ignore)
+ AddMoney(&gSaveBlock1.money, amount);
+ return FALSE;
+}
+
+bool8 ScrCmd_takemoney(struct ScriptContext *ctx)
+{
+ u32 amount = ScriptReadWord(ctx);
+ u8 ignore = ScriptReadByte(ctx);
+
+ if (!ignore)
+ RemoveMoney(&gSaveBlock1.money, amount);
+ return FALSE;
+}
+
+bool8 ScrCmd_checkmoney(struct ScriptContext *ctx)
+{
+ u32 amount = ScriptReadWord(ctx);
+ u8 ignore = ScriptReadByte(ctx);
+
+ if (!ignore)
+ gScriptResult = IsEnoughMoney(gSaveBlock1.money, amount);
+ return FALSE;
+}
+
+bool8 ScrCmd_showmoneybox(struct ScriptContext *ctx)
+{
+ u8 x = ScriptReadByte(ctx);
+ u8 y = ScriptReadByte(ctx);
+ u8 ignore = ScriptReadByte(ctx);
+
+ if (!ignore)
+ OpenMoneyWindow(gSaveBlock1.money, x, y);
+ return FALSE;
+}
+
+bool8 ScrCmd_hidemoneybox(struct ScriptContext *ctx)
+{
+ u8 x = ScriptReadByte(ctx);
+ u8 y = ScriptReadByte(ctx);
+
+ CloseMoneyWindow(x, y);
+ return FALSE;
+}
+
+bool8 ScrCmd_updatemoneybox(struct ScriptContext *ctx)
+{
+ u8 x = ScriptReadByte(ctx);
+ u8 y = ScriptReadByte(ctx);
+ u8 ignore = ScriptReadByte(ctx);
+
+ if (!ignore)
+ UpdateMoneyWindow(gSaveBlock1.money, x, y);
+ return FALSE;
+}
+
+bool8 ScrCmd_showcoinsbox(struct ScriptContext *ctx)
+{
+ u8 x = ScriptReadByte(ctx);
+ u8 y = ScriptReadByte(ctx);
+
+ ShowCoinsWindow(gSaveBlock1.coins, x, y);
+ return FALSE;
+}
+
+bool8 ScrCmd_hidecoinsbox(struct ScriptContext *ctx)
+{
+ u8 x = ScriptReadByte(ctx);
+ u8 y = ScriptReadByte(ctx);
+
+ HideCoinsWindow(x, y);
+ return FALSE;
+}
+
+bool8 ScrCmd_updatecoinsbox(struct ScriptContext *ctx)
+{
+ u8 x = ScriptReadByte(ctx);
+ u8 y = ScriptReadByte(ctx);
+
+ UpdateCoinsWindow(gSaveBlock1.coins, x, y);
+ return FALSE;
+}
+
+bool8 ScrCmd_trainerbattle(struct ScriptContext *ctx)
+{
+ ctx->scriptPtr = BattleSetup_ConfigureTrainerBattle(ctx->scriptPtr);
+ return FALSE;
+}
+
+bool8 ScrCmd_battlebegin(struct ScriptContext *ctx)
+{
+ BattleSetup_StartTrainerBattle();
+ return TRUE;
+}
+
+bool8 ScrCmd_ontrainerbattleend(struct ScriptContext *ctx)
+{
+ ctx->scriptPtr = BattleSetup_GetScriptAddrAfterBattle();
+ return FALSE;
+}
+
+bool8 ScrCmd_ontrainerbattleendgoto(struct ScriptContext *ctx)
+{
+ ctx->scriptPtr = BattleSetup_GetTrainerPostBattleScript();
+ return FALSE;
+}
+
+bool8 ScrCmd_checktrainerflag(struct ScriptContext *ctx)
+{
+ u16 index = VarGet(ScriptReadHalfword(ctx));
+
+ ctx->comparisonResult = HasTrainerAlreadyBeenFought(index);
+ return FALSE;
+}
+
+bool8 ScrCmd_settrainerflag(struct ScriptContext *ctx)
+{
+ u16 index = VarGet(ScriptReadHalfword(ctx));
+
+ trainer_flag_set(index);
+ return FALSE;
+}
+
+bool8 ScrCmd_cleartrainerflag(struct ScriptContext *ctx)
+{
+ u16 index = VarGet(ScriptReadHalfword(ctx));
+
+ trainer_flag_clear(index);
+ return FALSE;
+}
+
+bool8 ScrCmd_setwildbattle(struct ScriptContext *ctx)
+{
+ u16 species = ScriptReadHalfword(ctx);
+ u8 level = ScriptReadByte(ctx);
+ u16 item = ScriptReadHalfword(ctx);
+
+ CreateScriptedWildMon(species, level, item);
+ return FALSE;
+}
+
+bool8 ScrCmd_dowildbattle(struct ScriptContext *ctx)
+{
+ BattleSetup_StartScriptedWildBattle();
+ ScriptContext1_Stop();
+ return TRUE;
+}
+
+bool8 ScrCmd_pokemart(struct ScriptContext *ctx)
+{
+ void *ptr = (void *)ScriptReadWord(ctx);
+
+ CreatePokemartMenu(ptr);
+ ScriptContext1_Stop();
+ return TRUE;
+}
+
+bool8 ScrCmd_pokemartdecor(struct ScriptContext *ctx)
+{
+ void *ptr = (void *)ScriptReadWord(ctx);
+
+ CreateDecorationShop1Menu(ptr);
+ ScriptContext1_Stop();
+ return TRUE;
+}
+
+bool8 ScrCmd_pokemartbp(struct ScriptContext *ctx)
+{
+ void *ptr = (void *)ScriptReadWord(ctx);
+
+ CreateDecorationShop2Menu(ptr);
+ ScriptContext1_Stop();
+ return TRUE;
+}
+
+bool8 ScrCmd_playslotmachine(struct ScriptContext *ctx)
+{
+ u8 v2 = VarGet(ScriptReadHalfword(ctx));
+
+ PlaySlotMachine(v2, c2_exit_to_overworld_1_continue_scripts_restart_music);
+ ScriptContext1_Stop();
+ return TRUE;
+}
+
+bool8 ScrCmd_plantberrytree(struct ScriptContext *ctx)
+{
+ u8 treeId = ScriptReadByte(ctx);
+ u8 berry = ScriptReadByte(ctx);
+ u8 growthStage = ScriptReadByte(ctx);
+
+ if (berry == 0)
+ PlantBerryTree(treeId, 0, growthStage, FALSE);
+ else
+ PlantBerryTree(treeId, berry, growthStage, FALSE);
+ return FALSE;
+}
+
+bool8 ScrCmd_getpricereduction(struct ScriptContext *ctx)
+{
+ u16 value = VarGet(ScriptReadHalfword(ctx));
+
+ gScriptResult = GetPriceReduction(value);
+ return FALSE;
+}
+
+bool8 ScrCmd_choosecontestpkmn(struct ScriptContext *ctx)
+{
+ sub_80F99CC();
+ ScriptContext1_Stop();
+ return TRUE;
+}
+
+bool8 ScrCmd_startcontest(struct ScriptContext *ctx)
+{
+ sub_80C48C8();
+ ScriptContext1_Stop();
+ return TRUE;
+}
+
+bool8 ScrCmd_showcontestresults(struct ScriptContext *ctx)
+{
+ sub_80C4940();
+ ScriptContext1_Stop();
+ return TRUE;
+}
+
+bool8 ScrCmd_contestlinktransfer(struct ScriptContext *ctx)
+{
+ sub_80C4980(gScriptContestCategory);
+ ScriptContext1_Stop();
+ return TRUE;
+}
+
+bool8 ScrCmd_dofieldeffect(struct ScriptContext *ctx)
+{
+ u16 effectId = VarGet(ScriptReadHalfword(ctx));
+
+ sFieldEffectScriptId = effectId;
+ FieldEffectStart(sFieldEffectScriptId);
+ return FALSE;
+}
+
+bool8 ScrCmd_setfieldeffect(struct ScriptContext *ctx)
+{
+ u8 argNum = ScriptReadByte(ctx);
+
+ gFieldEffectArguments[argNum] = (s16)VarGet(ScriptReadHalfword(ctx));
+ return FALSE;
+}
+
+static bool8 sub_8067B48()
+{
+ if (!FieldEffectActiveListContains(sFieldEffectScriptId))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 ScrCmd_waitfieldeffect(struct ScriptContext *ctx)
+{
+ sFieldEffectScriptId = VarGet(ScriptReadHalfword(ctx));
+ SetupNativeScript(ctx, sub_8067B48);
+ return TRUE;
+}
+
+bool8 ScrCmd_sethealplace(struct ScriptContext *ctx)
+{
+ u16 healLocationId = VarGet(ScriptReadHalfword(ctx));
+
+ Overworld_SetHealLocationWarp(healLocationId);
+ return FALSE;
+}
+
+bool8 ScrCmd_checkplayergender(struct ScriptContext *ctx)
+{
+ gScriptResult = gSaveBlock2.playerGender;
+ return FALSE;
+}
+
+bool8 ScrCmd_playpokecry(struct ScriptContext *ctx)
+{
+ u16 species = VarGet(ScriptReadHalfword(ctx));
+ u16 mode = VarGet(ScriptReadHalfword(ctx));
+
+ PlayCry5(species, mode);
+ return FALSE;
+}
+
+bool8 ScrCmd_waitpokecry(struct ScriptContext *ctx)
+{
+ SetupNativeScript(ctx, IsCryFinished);
+ return TRUE;
+}
+
+bool8 ScrCmd_setmaptile(struct ScriptContext *ctx)
+{
+ u16 x = VarGet(ScriptReadHalfword(ctx));
+ u16 y = VarGet(ScriptReadHalfword(ctx));
+ u16 tileId = VarGet(ScriptReadHalfword(ctx));
+ u16 v8 = VarGet(ScriptReadHalfword(ctx));
+
+ x += 7;
+ y += 7;
+ if (!v8)
+ MapGridSetMetatileIdAt(x, y, tileId);
+ else
+ MapGridSetMetatileIdAt(x, y, tileId | 0xC00);
+ return FALSE;
+}
+
+bool8 ScrCmd_opendoor(struct ScriptContext *ctx)
+{
+ u16 x = VarGet(ScriptReadHalfword(ctx));
+ u16 y = VarGet(ScriptReadHalfword(ctx));
+
+ x += 7;
+ y += 7;
+ PlaySE(GetDoorSoundEffect(x, y));
+ FieldAnimateDoorOpen(x, y);
+ return FALSE;
+}
+
+bool8 ScrCmd_closedoor(struct ScriptContext *ctx)
+{
+ u16 x = VarGet(ScriptReadHalfword(ctx));
+ u16 y = VarGet(ScriptReadHalfword(ctx));
+
+ x += 7;
+ y += 7;
+ FieldAnimateDoorClose(x, y);
+ return FALSE;
+}
+
+static bool8 IsDoorAnimationStopped()
+{
+ if (!FieldIsDoorAnimationRunning())
+ return TRUE;
+ else
+ return FALSE;
+}
+
+bool8 ScrCmd_waitdooranim(struct ScriptContext *ctx)
+{
+ SetupNativeScript(ctx, IsDoorAnimationStopped);
+ return TRUE;
+}
+
+bool8 ScrCmd_setdooropen(struct ScriptContext *ctx)
+{
+ u16 x = VarGet(ScriptReadHalfword(ctx));
+ u16 y = VarGet(ScriptReadHalfword(ctx));
+
+ x += 7;
+ y += 7;
+ FieldSetDoorOpened(x, y);
+ return FALSE;
+}
+
+bool8 ScrCmd_setdoorclosed(struct ScriptContext *ctx)
+{
+ u16 x = VarGet(ScriptReadHalfword(ctx));
+ u16 y = VarGet(ScriptReadHalfword(ctx));
+
+ x += 7;
+ y += 7;
+ FieldSetDoorClosed(x, y);
+ return FALSE;
+}
+
+bool8 ScrCmd_addelevmenuitem(struct ScriptContext *ctx)
+{
+ u8 v3 = ScriptReadByte(ctx);
+ u16 v5 = VarGet(ScriptReadHalfword(ctx));
+ u16 v7 = VarGet(ScriptReadHalfword(ctx));
+ u16 v9 = VarGet(ScriptReadHalfword(ctx));
+
+ ScriptAddElevatorMenuItem(v3, v5, v7, v9);
+ return FALSE;
+}
+
+bool8 ScrCmd_showelevmenu(struct ScriptContext *ctx)
+{
+ ScriptShowElevatorMenu();
+ ScriptContext1_Stop();
+ return TRUE;
+}
+
+bool8 ScrCmd_checkcoins(struct ScriptContext *ctx)
+{
+ u16 *ptr = GetVarPointer(ScriptReadHalfword(ctx));
+ *ptr = GetCoins();
+ return FALSE;
+}
+
+bool8 ScrCmd_givecoins(struct ScriptContext *ctx)
+{
+ u16 coins = VarGet(ScriptReadHalfword(ctx));
+
+ if (GiveCoins(coins) == TRUE)
+ gScriptResult = 0;
+ else
+ gScriptResult = 1;
+ return FALSE;
+}
+
+bool8 ScrCmd_takecoins(struct ScriptContext *ctx)
+{
+ u16 coins = VarGet(ScriptReadHalfword(ctx));
+
+ if (TakeCoins(coins) == TRUE)
+ gScriptResult = 0;
+ else
+ gScriptResult = 1;
+ return FALSE;
+}
diff --git a/src/field/script_menu.c b/src/field/script_menu.c
new file mode 100644
index 000000000..e25e74d8c
--- /dev/null
+++ b/src/field/script_menu.c
@@ -0,0 +1,1178 @@
+#include "global.h"
+#include "script.h"
+#include "script_menu.h"
+#include "event_data.h"
+#include "field_effect.h"
+#include "menu.h"
+#include "palette.h"
+#include "script.h"
+#include "songs.h"
+#include "sound.h"
+#include "sprite.h"
+#include "strings.h"
+#include "task.h"
+
+// multichoice lists
+const struct MenuAction MultichoiceList_00[] =
+{
+ {OtherText_Petalburg, NULL},
+ {OtherText_Slateport, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_02[] =
+{
+ {OtherText_Enter, NULL},
+ {OtherText_Info3, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_03[] =
+{
+ {OtherText_WhatsAContest, NULL},
+ {OtherText_TypesOfContest, NULL},
+ {OtherText_Ranks, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_04[] =
+{
+ {OtherText_CoolContest, NULL},
+ {OtherText_BeautyContest, NULL},
+ {OtherText_CuteContest, NULL},
+ {OtherText_SmartContest, NULL},
+ {OtherText_ToughContest, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_06[] =
+{
+ {OtherText_Decoration, NULL},
+ {OtherText_PackUp, NULL},
+ {OtherText_Registry, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_05[] =
+{
+ {OtherText_Decoration, NULL},
+ {OtherText_PackUp, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_07[] =
+{
+ {OtherText_Register, NULL},
+ {OtherText_Registry, NULL},
+ {OtherText_Information, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_12[] =
+{
+ {OtherText_Mach, NULL},
+ {OtherText_Acro, NULL},
+};
+
+const struct MenuAction MultichoiceList_13[] =
+{
+ {OtherText_Poison, NULL},
+ {OtherText_Paralysis, NULL},
+ {OtherText_Sleep, NULL},
+ {OtherText_Burn, NULL},
+ {OtherText_Frozen, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_14[] =
+{
+ {OtherText_Dewford, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_16[] =
+{
+ {OtherText_SawIt, NULL},
+ {OtherText_NotYet, NULL},
+};
+
+const struct MenuAction MultichoiceList_17[] =
+{
+ {OtherText_Yes, NULL},
+ {OtherText_No, NULL},
+ {OtherText_Info3, NULL},
+};
+
+const struct MenuAction MultichoiceList_18[] =
+{
+ {OtherText_SingleBattle, NULL},
+ {OtherText_DoubleBattle, NULL},
+ {OtherText_MultiBattle, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_19[] =
+{
+ {OtherText_Littleroot, NULL},
+ {OtherText_Slateport, NULL},
+ {OtherText_Lilycove, NULL},
+};
+
+const struct MenuAction MultichoiceList_20[] =
+{
+ {OtherText_Yes, NULL},
+ {OtherText_No, NULL},
+ {OtherText_Info3, NULL},
+};
+
+const struct MenuAction MultichoiceList_23[] =
+{
+ {OtherText_MakeAChallenge, NULL},
+ {OtherText_ObtainInformation, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_24[] =
+{
+ {OtherText_Lv50_2, NULL},
+ {OtherText_Lv100_2, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_25[] =
+{
+ {OtherText_Zigzagoon, NULL},
+ {OtherText_Nincada, NULL},
+ {OtherText_Poochyena, NULL},
+};
+
+const struct MenuAction MultichoiceList_26[] =
+{
+ {OtherText_Nincada2, NULL},
+ {OtherText_Lotad, NULL},
+ {OtherText_Roselia, NULL},
+};
+
+const struct MenuAction MultichoiceList_27[] =
+{
+ {OtherText_Shroomish, NULL},
+ {OtherText_Nincada3, NULL},
+ {OtherText_Surskit, NULL},
+};
+
+const struct MenuAction MultichoiceList_28[] =
+{
+ {OtherText_Treecko, NULL},
+ {OtherText_Torchic, NULL},
+ {OtherText_Mudkip, NULL},
+};
+
+const struct MenuAction MultichoiceList_29[] =
+{
+ {OtherText_Seedot, NULL},
+ {OtherText_Shroomish2, NULL},
+ {OtherText_Spinda, NULL},
+};
+
+const struct MenuAction MultichoiceList_30[] =
+{
+ {OtherText_Shroomish3, NULL},
+ {OtherText_Zigzagoon2, NULL},
+ {OtherText_Wurmple, NULL},
+};
+
+const struct MenuAction MultichoiceList_31[] =
+{
+ {OtherText_PokeBall, NULL},
+ {OtherText_SuperPotion, NULL},
+ {OtherText_SamePrice, NULL},
+};
+
+const struct MenuAction MultichoiceList_32[] =
+{
+ {OtherText_Yen135, NULL},
+ {OtherText_Yen155, NULL},
+ {OtherText_Yen175, NULL},
+};
+
+const struct MenuAction MultichoiceList_33[] =
+{
+ {OtherText_CostMore, NULL},
+ {OtherText_CostLess, NULL},
+ {OtherText_SamePrice2, NULL},
+};
+
+const struct MenuAction MultichoiceList_34[] =
+{
+ {OtherText_MaleSymbol, NULL},
+ {OtherText_FemaleSymbol, NULL},
+ {OtherText_Neither, NULL},
+};
+
+const struct MenuAction MultichoiceList_35[] =
+{
+ {OtherText_Males, NULL},
+ {OtherText_Females, NULL},
+ {OtherText_SameNumber, NULL},
+};
+
+const struct MenuAction MultichoiceList_36[] =
+{
+ {OtherText_Male, NULL},
+ {OtherText_Female, NULL},
+ {OtherText_ItDepends, NULL},
+};
+
+const struct MenuAction MultichoiceList_37[] =
+{
+ {OtherText_Six2, NULL},
+ {OtherText_Eight2, NULL},
+ {OtherText_Ten, NULL},
+};
+
+const struct MenuAction MultichoiceList_38[] =
+{
+ {OtherText_One, NULL},
+ {OtherText_Two, NULL},
+ {OtherText_Three, NULL},
+};
+
+const struct MenuAction MultichoiceList_39[] =
+{
+ {OtherText_Six, NULL},
+ {OtherText_Seven, NULL},
+ {OtherText_Eight, NULL},
+};
+
+const struct MenuAction MultichoiceList_42[] =
+{
+ {OtherText_FreshWater, NULL},
+ {OtherText_SodaPop, NULL},
+ {OtherText_Lemonade, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_43[] =
+{
+ {OtherText_HowToRide, NULL},
+ {OtherText_HowToTurn, NULL},
+ {OtherText_SandySlopes, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_44[] =
+{
+ {OtherText_Wheelies, NULL},
+ {OtherText_BunnyHops, NULL},
+ {OtherText_Jumping, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_45[] =
+{
+ {OtherText_Satisfied, NULL},
+ {OtherText_Dissatisfied, NULL},
+};
+
+const struct MenuAction MultichoiceList_46[] =
+{
+ {OtherText_Deepseatooth, NULL},
+ {OtherText_Deepseascale, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_47[] =
+{
+ {OtherText_BlueFlute2, NULL},
+ {OtherText_YellowFlute2, NULL},
+ {OtherText_RedFlute2, NULL},
+ {OtherText_WhiteFlute2, NULL},
+ {OtherText_BlackFlute2, NULL},
+ {OtherText_GlassChair, NULL},
+ {OtherText_GlassDesk, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_48[] =
+{
+ {OtherText_TreeckoDoll, NULL},
+ {OtherText_TorchicDoll, NULL},
+ {OtherText_MudkipDoll, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_55[] =
+{
+ {OtherText_TM32, NULL},
+ {OtherText_TM29, NULL},
+ {OtherText_TM35, NULL},
+ {OtherText_TM24, NULL},
+ {OtherText_TM13, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_49[] =
+{
+ {OtherText_50Coins, NULL},
+ {OtherText_500Coins, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_50[] =
+{
+ {OtherText_Excellent, NULL},
+ {OtherText_NotSoHot, NULL},
+};
+
+const struct MenuAction MultichoiceList_52[] =
+{
+ {OtherText_Lilycove, NULL},
+ {OtherText_BattleTower, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_53[] =
+{
+ {OtherText_Slateport, NULL},
+ {OtherText_Lilycove, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_54[] =
+{
+ {OtherText_Right, NULL},
+ {OtherText_Left, NULL},
+};
+
+const struct MenuAction MultichoiceList_56[] =
+{
+ {OtherText_Slateport, NULL},
+ {OtherText_BattleTower, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_57[] =
+{
+ {OtherText_1F_2, NULL},
+ {OtherText_2F_2, NULL},
+ {OtherText_3F_2, NULL},
+ {OtherText_4F_2, NULL},
+ {OtherText_5F_2, NULL},
+};
+
+const struct MenuAction MultichoiceList_58[] =
+{
+ {OtherText_RedShard, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_59[] =
+{
+ {OtherText_YellowShard, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_60[] =
+{
+ {OtherText_RedShard, NULL},
+ {OtherText_YellowShard, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_61[] =
+{
+ {OtherText_BlueShard, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_62[] =
+{
+ {OtherText_RedShard, NULL},
+ {OtherText_BlueShard, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_63[] =
+{
+ {OtherText_YellowShard, NULL},
+ {OtherText_BlueShard, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_64[] =
+{
+ {OtherText_RedShard, NULL},
+ {OtherText_YellowShard, NULL},
+ {OtherText_BlueShard, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_65[] =
+{
+ {OtherText_GreenShard, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_66[] =
+{
+ {OtherText_RedShard, NULL},
+ {OtherText_GreenShard, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_67[] =
+{
+ {OtherText_YellowShard, NULL},
+ {OtherText_GreenShard, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_68[] =
+{
+ {OtherText_RedShard, NULL},
+ {OtherText_YellowShard, NULL},
+ {OtherText_GreenShard, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_69[] =
+{
+ {OtherText_BlueShard, NULL},
+ {OtherText_GreenShard, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_70[] =
+{
+ {OtherText_RedShard, NULL},
+ {OtherText_BlueShard, NULL},
+ {OtherText_GreenShard, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_71[] =
+{
+ {OtherText_YellowShard, NULL},
+ {OtherText_BlueShard, NULL},
+ {OtherText_GreenShard, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_72[] =
+{
+ {OtherText_RedShard, NULL},
+ {OtherText_YellowShard, NULL},
+ {OtherText_BlueShard, NULL},
+ {OtherText_GreenShard, NULL},
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+const struct MenuAction MultichoiceList_01[] =
+{
+ {gOtherText_CancelNoTerminator, NULL},
+};
+
+struct MultichoiceListStruct
+{
+ const struct MenuAction *list;
+ u8 count;
+};
+
+const struct MultichoiceListStruct gMultichoiceLists[] =
+{
+ {MultichoiceList_00, ARRAY_COUNT(MultichoiceList_00)},
+ {MultichoiceList_01, ARRAY_COUNT(MultichoiceList_01)},
+ {MultichoiceList_02, ARRAY_COUNT(MultichoiceList_02)},
+ {MultichoiceList_03, ARRAY_COUNT(MultichoiceList_03)},
+ {MultichoiceList_04, ARRAY_COUNT(MultichoiceList_04)},
+ {MultichoiceList_05, ARRAY_COUNT(MultichoiceList_05)},
+ {MultichoiceList_06, ARRAY_COUNT(MultichoiceList_06)},
+ {MultichoiceList_07, ARRAY_COUNT(MultichoiceList_07)},
+ {MultichoiceList_01, ARRAY_COUNT(MultichoiceList_01)},
+ {MultichoiceList_01, ARRAY_COUNT(MultichoiceList_01)},
+ {MultichoiceList_01, ARRAY_COUNT(MultichoiceList_01)},
+ {MultichoiceList_01, ARRAY_COUNT(MultichoiceList_01)},
+ {MultichoiceList_12, ARRAY_COUNT(MultichoiceList_12)},
+ {MultichoiceList_13, ARRAY_COUNT(MultichoiceList_13)},
+ {MultichoiceList_14, ARRAY_COUNT(MultichoiceList_14)},
+ {MultichoiceList_01, ARRAY_COUNT(MultichoiceList_01)},
+ {MultichoiceList_16, ARRAY_COUNT(MultichoiceList_16)},
+ {MultichoiceList_17, ARRAY_COUNT(MultichoiceList_17)},
+ {MultichoiceList_18, ARRAY_COUNT(MultichoiceList_18)},
+ {MultichoiceList_19, ARRAY_COUNT(MultichoiceList_19)},
+ {MultichoiceList_20, ARRAY_COUNT(MultichoiceList_20)},
+ {MultichoiceList_01, ARRAY_COUNT(MultichoiceList_01)},
+ {MultichoiceList_01, ARRAY_COUNT(MultichoiceList_01)},
+ {MultichoiceList_23, ARRAY_COUNT(MultichoiceList_23)},
+ {MultichoiceList_24, ARRAY_COUNT(MultichoiceList_24)},
+ {MultichoiceList_25, ARRAY_COUNT(MultichoiceList_25)},
+ {MultichoiceList_26, ARRAY_COUNT(MultichoiceList_26)},
+ {MultichoiceList_27, ARRAY_COUNT(MultichoiceList_27)},
+ {MultichoiceList_28, ARRAY_COUNT(MultichoiceList_28)},
+ {MultichoiceList_29, ARRAY_COUNT(MultichoiceList_29)},
+ {MultichoiceList_30, ARRAY_COUNT(MultichoiceList_30)},
+ {MultichoiceList_31, ARRAY_COUNT(MultichoiceList_31)},
+ {MultichoiceList_32, ARRAY_COUNT(MultichoiceList_32)},
+ {MultichoiceList_33, ARRAY_COUNT(MultichoiceList_33)},
+ {MultichoiceList_34, ARRAY_COUNT(MultichoiceList_34)},
+ {MultichoiceList_35, ARRAY_COUNT(MultichoiceList_35)},
+ {MultichoiceList_36, ARRAY_COUNT(MultichoiceList_36)},
+ {MultichoiceList_37, ARRAY_COUNT(MultichoiceList_37)},
+ {MultichoiceList_38, ARRAY_COUNT(MultichoiceList_38)},
+ {MultichoiceList_39, ARRAY_COUNT(MultichoiceList_39)},
+ {MultichoiceList_01, ARRAY_COUNT(MultichoiceList_01)},
+ {MultichoiceList_01, ARRAY_COUNT(MultichoiceList_01)},
+ {MultichoiceList_42, ARRAY_COUNT(MultichoiceList_42)},
+ {MultichoiceList_43, ARRAY_COUNT(MultichoiceList_43)},
+ {MultichoiceList_44, ARRAY_COUNT(MultichoiceList_44)},
+ {MultichoiceList_45, ARRAY_COUNT(MultichoiceList_45)},
+ {MultichoiceList_46, ARRAY_COUNT(MultichoiceList_46)},
+ {MultichoiceList_47, ARRAY_COUNT(MultichoiceList_47)},
+ {MultichoiceList_48, ARRAY_COUNT(MultichoiceList_48)},
+ {MultichoiceList_49, ARRAY_COUNT(MultichoiceList_49)},
+ {MultichoiceList_50, ARRAY_COUNT(MultichoiceList_50)},
+ {MultichoiceList_01, ARRAY_COUNT(MultichoiceList_01)},
+ {MultichoiceList_52, ARRAY_COUNT(MultichoiceList_52)},
+ {MultichoiceList_53, ARRAY_COUNT(MultichoiceList_53)},
+ {MultichoiceList_54, ARRAY_COUNT(MultichoiceList_54)},
+ {MultichoiceList_55, ARRAY_COUNT(MultichoiceList_55)},
+ {MultichoiceList_56, ARRAY_COUNT(MultichoiceList_56)},
+ {MultichoiceList_57, ARRAY_COUNT(MultichoiceList_57)},
+ {MultichoiceList_58, ARRAY_COUNT(MultichoiceList_58)},
+ {MultichoiceList_59, ARRAY_COUNT(MultichoiceList_59)},
+ {MultichoiceList_60, ARRAY_COUNT(MultichoiceList_60)},
+ {MultichoiceList_61, ARRAY_COUNT(MultichoiceList_61)},
+ {MultichoiceList_62, ARRAY_COUNT(MultichoiceList_62)},
+ {MultichoiceList_63, ARRAY_COUNT(MultichoiceList_63)},
+ {MultichoiceList_64, ARRAY_COUNT(MultichoiceList_64)},
+ {MultichoiceList_65, ARRAY_COUNT(MultichoiceList_65)},
+ {MultichoiceList_66, ARRAY_COUNT(MultichoiceList_66)},
+ {MultichoiceList_67, ARRAY_COUNT(MultichoiceList_67)},
+ {MultichoiceList_68, ARRAY_COUNT(MultichoiceList_68)},
+ {MultichoiceList_69, ARRAY_COUNT(MultichoiceList_69)},
+ {MultichoiceList_70, ARRAY_COUNT(MultichoiceList_70)},
+ {MultichoiceList_71, ARRAY_COUNT(MultichoiceList_71)},
+ {MultichoiceList_72, ARRAY_COUNT(MultichoiceList_72)},
+};
+
+const u8 *const gUnknown_083CE048[] =
+{
+ OtherText_Cool2,
+ OtherText_Beauty3,
+ OtherText_Cute2,
+ OtherText_Smart2,
+ OtherText_Tough2,
+ OtherText_Normal,
+ OtherText_Super,
+ OtherText_Hyper,
+ OtherText_Master,
+ OtherText_Cool3,
+ OtherText_Beauty4,
+ OtherText_Cute3,
+ OtherText_Smart3,
+ OtherText_Tough3,
+ OtherText_Items,
+ OtherText_KeyItems,
+ OtherText_Balls,
+ OtherText_TMsHMs,
+ OtherText_Berries,
+};
+
+extern u8 gPCText_WhichPCShouldBeAccessed[];
+
+extern u16 gScriptResult;
+
+static void Task_HandleMultichoiceInput(u8);
+static void Task_HandleYesNoInput(u8);
+static void Task_HandleMultichoiceGridInput(u8);
+static u16 GetStringWidthInTilesForScriptMenu(const u8 *str);
+static void DrawMultichoiceMenu(u8, u8, u8, const struct MenuAction *list, u8, u8);
+static void StartScriptMenuTask(u8, u8, u8, u8, u8, u8);
+static void sub_80B53B4(u8, u8, u8, const struct MenuAction *list, u8);
+static bool8 IsPicboxClosed(void);
+
+bool8 ScriptMenu_Multichoice(u8 left, u8 top, u8 multichoiceId, u8 ignoreBPress)
+{
+ if (FuncIsActiveTask(Task_HandleMultichoiceInput) == TRUE)
+ {
+ return FALSE;
+ }
+ else
+ {
+ gScriptResult = 0xFF;
+ DrawMultichoiceMenu(left, top, gMultichoiceLists[multichoiceId].count, gMultichoiceLists[multichoiceId].list, ignoreBPress, 0);
+ return TRUE;
+ }
+}
+
+bool8 ScriptMenu_MultichoiceWithDefault(u8 left, u8 top, u8 multichoiceId, u8 ignoreBPress, u8 defaultChoice)
+{
+ if (FuncIsActiveTask(Task_HandleMultichoiceInput) == TRUE)
+ {
+ return FALSE;
+ }
+ else
+ {
+ gScriptResult = 0xFF;
+ DrawMultichoiceMenu(left, top, gMultichoiceLists[multichoiceId].count, gMultichoiceLists[multichoiceId].list, ignoreBPress, defaultChoice);
+ return TRUE;
+ }
+}
+
+static u16 GetStringWidthInTilesForScriptMenu(const u8 *str)
+{
+ // each tile on screen is 8x8, so it needs the number of tiles and not pixels, hence the division by 8.
+ return (GetStringWidthGivenWindowConfig((struct WindowConfig *)&gWindowConfig_81E6CE4, str) + 7) / 8;
+}
+
+static void DrawMultichoiceMenu(u8 left, u8 top, u8 count, const struct MenuAction *list, u8 ignoreBPress, u8 cursorPos)
+{
+ u16 width = GetStringWidthInTilesForScriptMenu(list[0].text);
+ u16 newWidth;
+ u8 i;
+ u8 right;
+ u8 bottom;
+
+ for (i = 1; i < count; i++)
+ {
+ newWidth = GetStringWidthInTilesForScriptMenu(list[i].text);
+ if (width < newWidth)
+ width = newWidth;
+ }
+
+ right = width;
+ right = (right + left) + 1;
+
+ if (right > 29)
+ {
+ left = left + (29 - right);
+ right = 29;
+ }
+
+ bottom = top + (2 * count + 1);
+
+ MenuDrawTextWindow(left, top, right, bottom);
+ PrintMenuItems(left + 1, top + 1, count, list);
+ InitMenu(0, left + 1, top + 1, count, cursorPos, right - left - 1);
+ StartScriptMenuTask(left, top, right, bottom, ignoreBPress, count);
+}
+
+#define tLeft data[0]
+#define tTop data[1]
+#define tRight data[2]
+#define tBottom data[3]
+#define tIgnoreBPress data[4]
+#define tDoWrap data[5]
+
+static void StartScriptMenuTask(u8 left, u8 top, u8 right, u8 bottom, u8 ignoreBPress, u8 count)
+{
+ u8 taskId = CreateTask(Task_HandleMultichoiceInput, 80);
+
+ gTasks[taskId].tLeft = left;
+ gTasks[taskId].tTop = top;
+ gTasks[taskId].tRight = right;
+ gTasks[taskId].tBottom = bottom;
+ gTasks[taskId].tIgnoreBPress = ignoreBPress;
+
+ if (count > 3)
+ gTasks[taskId].tDoWrap = TRUE;
+ else
+ gTasks[taskId].tDoWrap = FALSE;
+}
+
+static void Task_HandleMultichoiceInput(u8 taskId)
+{
+ s8 selection;
+
+ if (!gPaletteFade.active)
+ {
+ if (!gTasks[taskId].tDoWrap)
+ selection = ProcessMenuInputNoWrap();
+ else
+ selection = ProcessMenuInput();
+
+ if (selection != -2)
+ {
+ if (selection == -1)
+ {
+ if (gTasks[taskId].tIgnoreBPress)
+ return;
+ PlaySE(SE_SELECT);
+ gScriptResult = 127;
+ }
+ else
+ {
+ gScriptResult = selection;
+ }
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(gTasks[taskId].tLeft, gTasks[taskId].tTop, gTasks[taskId].tRight, gTasks[taskId].tBottom);
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+ }
+ }
+}
+
+bool8 Multichoice(u8 left, u8 top, u8 multichoiceId, u8 ignoreBPress)
+{
+ if (FuncIsActiveTask(Task_HandleMultichoiceInput) == TRUE)
+ {
+ return FALSE;
+ }
+ else
+ {
+ gScriptResult = 0xFF;
+ sub_80B53B4(left, top, gMultichoiceLists[multichoiceId].count, gMultichoiceLists[multichoiceId].list, ignoreBPress);
+ return TRUE;
+ }
+}
+
+static void sub_80B53B4(u8 left, u8 top, u8 count, const struct MenuAction *list, u8 ignoreBPress)
+{
+ u16 width = GetStringWidthInTilesForScriptMenu(list[0].text);
+ u16 newWidth;
+ u8 i;
+ u8 right;
+ u8 bottom;
+
+ for (i = 1; i < count; i++)
+ {
+ newWidth = GetStringWidthInTilesForScriptMenu(list[i].text);
+ if (width < newWidth)
+ width = newWidth;
+ }
+
+ right = width;
+ right = (right + left) + 2;
+ bottom = top + (2 * count + 1);
+
+ PrintMenuItems(left, top, count, list);
+ InitMenu(0, left, top, count, 0, right - left - 1);
+ StartScriptMenuTask(left, top, right, bottom, ignoreBPress, count);
+}
+
+bool8 ScriptMenu_YesNo(u8 left, u8 top)
+{
+ u8 taskId;
+
+ if (FuncIsActiveTask(Task_HandleYesNoInput) == TRUE)
+ {
+ return FALSE;
+ }
+ else
+ {
+ gScriptResult = 0xFF;
+ DisplayYesNoMenu(left, top, 1);
+ taskId = CreateTask(Task_HandleYesNoInput, 0x50);
+ gTasks[taskId].tLeft = left;
+ gTasks[taskId].tTop = top;
+ return TRUE;
+ }
+}
+
+// unused
+bool8 IsScriptActive(void)
+{
+ if (gScriptResult == 0xFF)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+static void Task_HandleYesNoInput(u8 taskId)
+{
+ u8 left, top;
+
+ if (gTasks[taskId].tRight < 5)
+ {
+ gTasks[taskId].tRight++;
+ return;
+ }
+
+ switch (ProcessMenuInputNoWrap())
+ {
+ case -2:
+ return;
+ case -1:
+ case 1:
+ PlaySE(SE_SELECT);
+ gScriptResult = 0;
+ break;
+ case 0:
+ gScriptResult = 1;
+ break;
+ }
+
+ left = gTasks[taskId].tLeft;
+ top = gTasks[taskId].tTop;
+
+ MenuZeroFillWindowRect(left, top, left + 6, top + 5);
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+}
+
+bool8 ScriptMenu_MultichoiceGrid(u8 left, u8 top, u8 multichoiceId, u8 ignoreBPress, u8 columnCount)
+{
+ u8 bottom = 0;
+
+ if (FuncIsActiveTask(Task_HandleMultichoiceGridInput) == TRUE)
+ {
+ return FALSE;
+ }
+ else
+ {
+ u8 taskId;
+ u8 width;
+
+ gScriptResult = 0xFF;
+
+ sub_807274C(left, top, gMultichoiceLists[multichoiceId].count, 0, gMultichoiceLists[multichoiceId].list, columnCount, 0);
+
+ taskId = CreateTask(Task_HandleMultichoiceGridInput, 80);
+
+ if (!((gMultichoiceLists[multichoiceId].count >> 1) < columnCount || (gMultichoiceLists[multichoiceId].count & 1))
+ || columnCount == 1 || gMultichoiceLists[multichoiceId].count == columnCount)
+ {
+ bottom = (2 * (gMultichoiceLists[multichoiceId].count / columnCount)) + 1 + top;
+ }
+ else
+ {
+ bottom = (2 * (gMultichoiceLists[multichoiceId].count / columnCount)) + 3 + top;
+ }
+
+ width = sub_807288C(columnCount);
+ gTasks[taskId].tLeft = left;
+ gTasks[taskId].tTop = top;
+ gTasks[taskId].tRight = width + left + 2;
+ gTasks[taskId].tBottom = bottom;
+ gTasks[taskId].tIgnoreBPress = ignoreBPress;
+ return TRUE;
+ }
+}
+
+static void Task_HandleMultichoiceGridInput(u8 taskId)
+{
+ s8 selection = sub_80727CC();
+
+ if (selection != -2)
+ {
+ if (selection == -1)
+ {
+ if (gTasks[taskId].tIgnoreBPress)
+ return;
+ PlaySE(SE_SELECT);
+ gScriptResult = 127;
+ }
+ else
+ {
+ gScriptResult = selection;
+ }
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(gTasks[taskId].tLeft, gTasks[taskId].tTop, gTasks[taskId].tRight, gTasks[taskId].tBottom);
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+ }
+}
+
+#undef tLeft
+#undef tTop
+#undef tRight
+#undef tBottom
+#undef tIgnoreBPress
+#undef tDoWrap
+
+bool8 ScrSpecial_CreatePCMenu(void)
+{
+ if (FuncIsActiveTask(Task_HandleMultichoiceInput) == TRUE)
+ {
+ return FALSE;
+ }
+ else
+ {
+ gScriptResult = 0xFF;
+ ScriptMenu_CreatePCMenu();
+ return TRUE;
+ }
+}
+
+#if ENGLISH
+void ScriptMenu_CreatePCMenu(void)
+{
+ u16 playersPCWidth = GetStringWidthInTilesForScriptMenu(gPCText_PlayersPC);
+ u8 width;
+ u8 numChoices;
+
+ if (playersPCWidth > GetStringWidthInTilesForScriptMenu(gPCText_SomeonesPC))
+ width = playersPCWidth;
+ else
+ width = 8;
+
+ if (FlagGet(SYS_GAME_CLEAR)) // player has cleared game?
+ {
+ numChoices = 4;
+ MenuDrawTextWindow(0, 0, width + 2, 9);
+ MenuPrint(gPCText_HallOfFame, 1, 5);
+ MenuPrint(gPCText_LogOff, 1, 7);
+ }
+ else
+ {
+ numChoices = 3;
+ MenuDrawTextWindow(0, 0, width + 2, 7);
+ MenuPrint(gPCText_LogOff, 1, 5);
+ }
+
+ if (FlagGet(SYS_PC_LANETTE)) // player met lanette?
+ MenuPrint(gPCText_LanettesPC, 1, 1);
+ else
+ MenuPrint(gPCText_SomeonesPC, 1, 1);
+
+ MenuPrint(gPCText_PlayersPC, 1, 3);
+ InitMenu(0, 1, 1, numChoices, 0, width + 1);
+ StartScriptMenuTask(0, 0, width + 2, 2 * numChoices + 1, 0, numChoices);
+}
+#elif GERMAN
+__attribute__((naked))
+void ScriptMenu_CreatePCMenu(void) {
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ sub sp, 0x18\n\
+ ldr r0, _080B5748 @ =0x0000084b\n\
+ bl FlagGet\n\
+ lsls r0, 24\n\
+ cmp r0, 0\n\
+ beq _080B5750\n\
+ ldr r0, _080B574C @ =gPCText_LanettesPC\n\
+ b _080B5752\n\
+ .align 2, 0\n\
+_080B5748: .4byte 0x0000084b\n\
+_080B574C: .4byte gPCText_LanettesPC\n\
+_080B5750:\n\
+ ldr r0, _080B57E8 @ =gPCText_SomeonesPC\n\
+_080B5752:\n\
+ bl GetStringWidthInTilesForScriptMenu\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ str r0, [sp, 0x8]\n\
+ movs r4, 0x1\n\
+ ldr r0, _080B57EC @ =gPCText_PlayersPC\n\
+ bl GetStringWidthInTilesForScriptMenu\n\
+ lsls r1, r4, 2\n\
+ add r1, sp\n\
+ adds r1, 0x8\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ str r0, [r1]\n\
+ ldr r0, _080B57F0 @ =gPCText_LogOff\n\
+ bl GetStringWidthInTilesForScriptMenu\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ str r0, [sp, 0x10]\n\
+ movs r4, 0x3\n\
+ ldr r0, _080B57F4 @ =0x00000804\n\
+ bl FlagGet\n\
+ lsls r0, 24\n\
+ cmp r0, 0\n\
+ beq _080B5798\n\
+ ldr r0, _080B57F8 @ =gPCText_HallOfFame\n\
+ bl GetStringWidthInTilesForScriptMenu\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ str r0, [sp, 0x14]\n\
+ movs r4, 0x4\n\
+_080B5798:\n\
+ movs r5, 0\n\
+ cmp r5, r4\n\
+ bge _080B57B4\n\
+ add r2, sp, 0x8\n\
+ adds r1, r4, 0\n\
+_080B57A2:\n\
+ ldr r0, [r2]\n\
+ cmp r5, r0\n\
+ bge _080B57AC\n\
+ lsls r0, 24\n\
+ lsrs r5, r0, 24\n\
+_080B57AC:\n\
+ adds r2, 0x4\n\
+ subs r1, 0x1\n\
+ cmp r1, 0\n\
+ bne _080B57A2\n\
+_080B57B4:\n\
+ ldr r0, _080B57F4 @ =0x00000804\n\
+ bl FlagGet\n\
+ lsls r0, 24\n\
+ cmp r0, 0\n\
+ beq _080B57FC\n\
+ movs r7, 0x4\n\
+ adds r4, r5, 0x2\n\
+ lsls r2, r4, 24\n\
+ lsrs r2, 24\n\
+ movs r0, 0\n\
+ movs r1, 0\n\
+ movs r3, 0x9\n\
+ bl MenuDrawTextWindow\n\
+ ldr r0, _080B57F8 @ =gPCText_HallOfFame\n\
+ movs r1, 0x1\n\
+ movs r2, 0x5\n\
+ bl MenuPrint\n\
+ ldr r0, _080B57F0 @ =gPCText_LogOff\n\
+ movs r1, 0x1\n\
+ movs r2, 0x7\n\
+ bl MenuPrint\n\
+ b _080B5818\n\
+ .align 2, 0\n\
+_080B57E8: .4byte gPCText_SomeonesPC\n\
+_080B57EC: .4byte gPCText_PlayersPC\n\
+_080B57F0: .4byte gPCText_LogOff\n\
+_080B57F4: .4byte 0x00000804\n\
+_080B57F8: .4byte gPCText_HallOfFame\n\
+_080B57FC:\n\
+ movs r7, 0x3\n\
+ adds r4, r5, 0x2\n\
+ lsls r2, r4, 24\n\
+ lsrs r2, 24\n\
+ movs r0, 0\n\
+ movs r1, 0\n\
+ movs r3, 0x7\n\
+ bl MenuDrawTextWindow\n\
+ ldr r0, _080B5834 @ =gPCText_LogOff\n\
+ movs r1, 0x1\n\
+ movs r2, 0x5\n\
+ bl MenuPrint\n\
+_080B5818:\n\
+ adds r6, r4, 0\n\
+ ldr r0, _080B5838 @ =0x0000084b\n\
+ bl FlagGet\n\
+ lsls r0, 24\n\
+ cmp r0, 0\n\
+ beq _080B5840\n\
+ ldr r0, _080B583C @ =gPCText_LanettesPC\n\
+ movs r1, 0x1\n\
+ movs r2, 0x1\n\
+ bl MenuPrint\n\
+ b _080B584A\n\
+ .align 2, 0\n\
+_080B5834: .4byte gPCText_LogOff\n\
+_080B5838: .4byte 0x0000084b\n\
+_080B583C: .4byte gPCText_LanettesPC\n\
+_080B5840:\n\
+ ldr r0, _080B5888 @ =gPCText_SomeonesPC\n\
+ movs r1, 0x1\n\
+ movs r2, 0x1\n\
+ bl MenuPrint\n\
+_080B584A:\n\
+ ldr r0, _080B588C @ =gPCText_PlayersPC\n\
+ movs r1, 0x1\n\
+ movs r2, 0x3\n\
+ bl MenuPrint\n\
+ movs r4, 0\n\
+ str r4, [sp]\n\
+ adds r0, r5, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ str r0, [sp, 0x4]\n\
+ movs r0, 0\n\
+ movs r1, 0x1\n\
+ movs r2, 0x1\n\
+ adds r3, r7, 0\n\
+ bl InitMenu\n\
+ lsls r2, r6, 24\n\
+ lsrs r2, 24\n\
+ lsls r3, r7, 1\n\
+ adds r3, 0x1\n\
+ str r4, [sp]\n\
+ str r7, [sp, 0x4]\n\
+ movs r0, 0\n\
+ movs r1, 0\n\
+ bl StartScriptMenuTask\n\
+ add sp, 0x18\n\
+ pop {r4-r7}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .align 2, 0\n\
+_080B5888: .4byte gPCText_SomeonesPC\n\
+_080B588C: .4byte gPCText_PlayersPC\n\
+ .syntax divided\n");
+}
+#endif
+
+void ScriptMenu_DisplayPCStartupPrompt(void)
+{
+ MenuDisplayMessageBox();
+ MenuPrint(gPCText_WhichPCShouldBeAccessed, 2, 15);
+}
+
+#define tState data[0]
+#define tMonSpecies data[1]
+#define tMonSpriteId data[2]
+#define tWindowX data[3]
+#define tWindowY data[4]
+
+static void Task_PokemonPicWindow(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->tState)
+ {
+ case 0:
+ task->tState++;
+ break;
+ case 1:
+ break;
+ case 2:
+ FreeResourcesAndDestroySprite(&gSprites[task->tMonSpriteId]);
+ task->tState++;
+ break;
+ case 3:
+ MenuZeroFillWindowRect(task->tWindowX, task->tWindowY, task->tWindowX + 9, task->tWindowY + 10);
+ DestroyTask(taskId);
+ break;
+ }
+}
+
+bool8 ScriptMenu_ShowPokemonPic(u16 species, u8 x, u8 y)
+{
+ u8 taskId;
+ u8 spriteId;
+
+ if (FindTaskIdByFunc(Task_PokemonPicWindow) != 0xFF)
+ {
+ return FALSE;
+ }
+ else
+ {
+ MenuDrawTextWindow(x, y, x + 9, y + 10);
+ taskId = CreateTask(Task_PokemonPicWindow, 0x50);
+ gTasks[taskId].tState = 0;
+ gTasks[taskId].tMonSpecies = species;
+ spriteId = CreateMonSprite_PicBox(species, x * 8 + 40, y * 8 + 40, 0);
+ gTasks[taskId].tMonSpriteId = spriteId;
+ gTasks[taskId].tWindowX = x;
+ gTasks[taskId].tWindowY = y;
+ gSprites[spriteId].callback = SpriteCallbackDummy;
+ gSprites[spriteId].oam.priority = 0;
+ return TRUE;
+ }
+}
+
+bool8 (*ScriptMenu_GetPicboxWaitFunc(void))(void)
+{
+ u8 taskId = FindTaskIdByFunc(Task_PokemonPicWindow);
+
+ if (taskId == 0xFF)
+ return NULL;
+ gTasks[taskId].tState++;
+ return IsPicboxClosed;
+}
+
+static bool8 IsPicboxClosed(void)
+{
+ if (FindTaskIdByFunc(Task_PokemonPicWindow) == 0xFF)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+#undef tState
+#undef tMonSpecies
+#undef tMonSpriteId
+#undef tWindowX
+#undef tWindowY
diff --git a/src/field/script_movement.c b/src/field/script_movement.c
new file mode 100644
index 000000000..30e10b451
--- /dev/null
+++ b/src/field/script_movement.c
@@ -0,0 +1,228 @@
+#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 EWRAM_DATA u8 *gUnknown_020384F8[16] = {0};
+
+static void sub_80A2198(u8);
+static u8 sub_80A21E0(void);
+static bool8 sub_80A21F4(u8, u8, u8 *);
+static u8 sub_80A2260(u8, u8);
+static bool8 sub_80A2370(u8, u8);
+static void sub_80A23C8(u8, u8, u8, u8 *);
+static void UnfreezeObjects(u8);
+static void Task_80A244C(u8);
+static void sub_80A2490(u8, u8, u8, u8 *);
+
+bool8 ScriptMovement_StartObjectMovementScript(u8 localId, u8 mapNum, u8 mapGroup, u8 *movementScript)
+{
+ u8 mapObjId;
+
+ if (TryGetFieldObjectIdByLocalIdAndMap(localId, mapNum, mapGroup, &mapObjId))
+ return TRUE;
+ if (!FuncIsActiveTask(Task_80A244C))
+ sub_80A2198(50);
+ return sub_80A21F4(sub_80A21E0(), 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_80A21E0();
+ r1 = sub_80A2260(r4, mapObjId);
+ if (r1 == 16)
+ return TRUE;
+ return sub_80A2370(r4, r1);
+}
+
+void sub_80A2178(void)
+{
+ u8 taskId;
+
+ taskId = sub_80A21E0();
+ if (taskId != 0xFF)
+ {
+ UnfreezeObjects(taskId);
+ DestroyTask(taskId);
+ }
+}
+
+static void sub_80A2198(u8 priority)
+{
+ u8 taskId;
+ u8 i;
+
+ taskId = CreateTask(Task_80A244C, priority);
+ for (i = 1; i < 16; i++)
+ gTasks[taskId].data[i] = 0xFFFF;
+}
+
+static u8 sub_80A21E0(void)
+{
+ return FindTaskIdByFunc(Task_80A244C);
+}
+
+static bool8 sub_80A21F4(u8 taskId, u8 mapObjId, u8 *movementScript)
+{
+ u8 r4;
+
+ r4 = sub_80A2260(taskId, mapObjId);
+ if (r4 != 16)
+ {
+ if (sub_80A2370(taskId, r4) == 0)
+ {
+ return TRUE;
+ }
+ else
+ {
+ sub_80A23C8(taskId, r4, mapObjId, movementScript);
+ return FALSE;
+ }
+ }
+ r4 = sub_80A2260(taskId, 0xFF);
+ if (r4 == 16)
+ {
+ return TRUE;
+ }
+ else
+ {
+ sub_80A23C8(taskId, r4, mapObjId, movementScript);
+ return FALSE;
+ }
+}
+
+static u8 sub_80A2260(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_80A229C(u8 taskId, u8 b, u8 **c)
+{
+ u8 i;
+
+ *c = (u8 *)&gTasks[taskId].data[1];
+ for (i = 0; i < b; i++, (*c)++)
+ ;
+}
+
+static void sub_80A22D0(u8 taskId, u8 b, u8 c)
+{
+ u8 *ptr;
+
+ sub_80A229C(taskId, b, &ptr);
+ *ptr = c; //what is this supposed to do?
+}
+
+static void sub_80A22F4(u8 taskId, u8 b, u8 *c)
+{
+ u8 *ptr;
+
+ sub_80A229C(taskId, b, &ptr);
+ *c = *ptr;
+}
+
+static void sub_80A2318(u8 a, u8 b)
+{
+ u16 var = ~gBitTable[b];
+
+ gTasks[a].data[0] &= var;
+}
+
+static void sub_80A2348(u8 taskId, u8 b)
+{
+ gTasks[taskId].data[0] |= gBitTable[b];
+}
+
+static bool8 sub_80A2370(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, u8 *movementScript)
+{
+ gUnknown_020384F8[a] = movementScript;
+}
+
+static u8 *sub_80A23B8(u8 a)
+{
+ return gUnknown_020384F8[a];
+}
+
+static void sub_80A23C8(u8 taskId, u8 b, u8 mapObjId, u8 *movementScript)
+{
+ sub_80A2318(taskId, b);
+ npc_obj_offscreen_culling_and_flag_update(b, movementScript);
+ sub_80A22D0(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)
+ UnfreezeMapObject(&gMapObjects[*pMapObjId]);
+ }
+}
+
+static void Task_80A244C(u8 taskId)
+{
+ u8 i;
+ u8 var;
+
+ for (i = 0; i < 16; i++)
+ {
+ sub_80A22F4(taskId, i, &var);
+ if (var != 0xFF)
+ sub_80A2490(taskId, i, var, sub_80A23B8(i));
+ }
+}
+
+static void sub_80A2490(u8 taskId, u8 b, u8 mapObjId, u8 *d)
+{
+ u8 var;
+
+ if (FieldObjectIsSpecialAnimActive(&gMapObjects[mapObjId])
+ && !FieldObjectClearAnimIfSpecialAnimFinished(&gMapObjects[mapObjId]))
+ return;
+
+ var = *d;
+ if (var == 0xFE)
+ {
+ sub_80A2348(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/field/secret_base.c b/src/field/secret_base.c
new file mode 100644
index 000000000..f221d7f16
--- /dev/null
+++ b/src/field/secret_base.c
@@ -0,0 +1,1075 @@
+#include "global.h"
+#include "secret_base.h"
+#include "decoration.h"
+#include "event_data.h"
+#include "field_camera.h"
+#include "field_fadetransition.h"
+#include "field_player_avatar.h"
+#include "field_weather.h"
+#include "fieldmap.h"
+#include "main.h"
+#include "map_constants.h"
+#include "map_name_popup.h"
+#include "menu.h"
+#include "metatile_behavior.h"
+#include "palette.h"
+#include "pokemon.h"
+#include "overworld.h"
+#include "script.h"
+#include "string_util.h"
+#include "strings.h"
+#include "task.h"
+#include "text.h"
+#include "vars.h"
+
+extern u8 gUnknown_020387DC;
+extern u16 gSpecialVar_0x8004;
+extern u16 gSpecialVar_0x8005;
+extern u16 gSpecialVar_0x8006;
+extern u16 gSpecialVar_0x8007;
+extern u16 gScriptResult;
+extern const struct
+{
+ u16 unk_083D1358_0;
+ u16 unk_083D1358_1;
+} gUnknown_083D1358[7];
+extern const u8 gUnknown_083D1374[4 * 16];
+extern void *gUnknown_0300485C;
+extern const u8 gUnknown_083D13EC[12];
+extern u8 gUnknown_081A2E14[];
+
+
+void sub_80BB4AC(struct SecretBaseRecord *record) // 080bb4ac
+{
+ u16 i;
+ u16 j;
+ record->sbr_field_0 = 0;
+ for (i=0; i<7; i++)
+ record->sbr_field_2[i] = 0xff;
+ for (i=0; i<4; i++)
+ record->trainerId[i] = 0x00;
+ record->sbr_field_e = 0;
+ record->sbr_field_10 = 0;
+ record->sbr_field_11 = 0;
+ record->sbr_field_1_0 = 0;
+ record->gender = 0;
+ record->sbr_field_1_5 = 0;
+ record->sbr_field_1_6 = 0;
+ for (i=0; i<16; i++) {
+ record->decorations[i] = 0;
+ record->decorationPos[i] = 0;
+ }
+ for (i=0; i<6; i++) {
+ for (j=0; j<4; j++) {
+ record->partyMoves[i * 4 + j] = 0;
+ }
+ record->partyPersonality[i] = 0;
+ record->partyEVs[i] = 0;
+ record->partySpecies[i] = 0;
+ record->partyHeldItems[i] = 0;
+ record->partyLevels[i] = 0;
+ }
+}
+
+void ResetSecretBase(u8 idx) // 80bb594
+{
+ sub_80BB4AC(&(gSaveBlock1.secretBases[idx]));
+}
+
+void ResetSecretBases(void) // 080bb5b4
+{
+ u16 i;
+ for (i=0; i<20; i++)
+ ResetSecretBase(i);
+}
+
+void sub_80BB5D0(void) // 080bb5d0
+{
+ gUnknown_020387DC = gSpecialVar_0x8004;
+}
+
+void sub_80BB5E4(void) // 80bb5e4
+{
+ u16 idx;
+ gScriptResult = 0;
+ for (idx=0; idx<20; idx++) {
+ if (gUnknown_020387DC != gSaveBlock1.secretBases[idx].sbr_field_0)
+ continue;
+ gScriptResult = 1;
+ VarSet(VAR_0x4054, idx);
+ break;
+ }
+}
+
+void sub_80BB63C(void) // 80bb63c
+{
+ if (gSaveBlock1.secretBases[0].sbr_field_0)
+ gScriptResult = 1;
+ else
+ gScriptResult = 0;
+}
+
+u8 sub_80BB66C(void) // 80bb66c
+{
+ s16 x, y;
+ s16 v0;
+ GetXYCoordsOneStepInFrontOfPlayer(&x, &y);
+ v0 = MapGridGetMetatileBehaviorAt(x, y) & 0xFFF;
+ if (v0 == 0x90 || v0 == 0x91)
+ return 1;
+ else if (v0 == 0x92 || v0 == 0x93)
+ return 2;
+ else if (v0 == 0x9a || v0 == 0x9b)
+ return 3;
+ else if (v0 == 0x94 || v0 == 0x95)
+ return 4;
+ else if (v0 == 0x96 || v0 == 0x97 || v0 == 0x9c || v0 == 0x9d)
+ return 5;
+ else if (v0 == 0x98 || v0 == 0x99)
+ return 6;
+ return 0;
+}
+
+void sub_80BB70C(void) // 80bb70c
+{
+ gSpecialVar_0x8007 = sub_80BB66C();
+}
+
+s16 unref_sub_80BB724(u16 *a0, u8 a1)
+{
+ u16 v2;
+ for (v2=0; v2<0x200; v2++) {
+ if ((a0[v2] & 0xFFF) == a1)
+ return (s16)v2;
+ }
+ return -1;
+}
+
+void sub_80BB764(s16 *arg1, s16 *arg2, u16 arg3)
+{
+ s16 x, y;
+ for (y=0; y<gMapHeader.mapData->height; y++) {
+ for (x=0; x<gMapHeader.mapData->width; x++) {
+ if ((gMapHeader.mapData->map[y * gMapHeader.mapData->width + x] & 0x3ff) == arg3) {
+ *arg1 = x;
+ *arg2 = y;
+ return;
+ }
+ }
+ }
+}
+
+void sub_80BB800(void)
+{
+ s16 x, y;
+ s16 tile_id;
+ u16 idx;
+ GetXYCoordsOneStepInFrontOfPlayer(&x, &y);
+ tile_id = MapGridGetMetatileIdAt(x, y);
+ for (idx=0; idx<7; idx++) {
+ if (gUnknown_083D1358[idx].unk_083D1358_0 == tile_id) {
+ MapGridSetMetatileIdAt(x, y, gUnknown_083D1358[idx].unk_083D1358_1 | 0xc00);
+ CurrentMapDrawMetatileAt(x, y);
+ return;
+ }
+ }
+ for (idx=0; idx<7; idx++) {
+ if (gUnknown_083D1358[idx].unk_083D1358_1 == tile_id) {
+ MapGridSetMetatileIdAt(x, y, gUnknown_083D1358[idx].unk_083D1358_0 | 0xc00);
+ CurrentMapDrawMetatileAt(x, y);
+ return;
+ }
+ }
+}
+
+u8 sub_80BB8A8(u8 *arg1)
+{
+ u8 idx;
+ for (idx=0; idx<7; idx++) {
+ if (arg1[idx] == EOS)
+ return idx;
+ }
+ return 7;
+}
+
+void sub_80BB8CC(void)
+{
+ u8 nameLength;
+ u16 idx;
+ gSaveBlock1.secretBases[0].sbr_field_0 = gUnknown_020387DC;
+ for (idx=0; idx<4; idx++) {
+ gSaveBlock1.secretBases[0].trainerId[idx] = gSaveBlock2.playerTrainerId[idx];
+ }
+ VarSet(VAR_0x4054, 0);
+ nameLength = sub_80BB8A8(gSaveBlock2.playerName);
+ memset(gSaveBlock1.secretBases[0].sbr_field_2, 0xFF, 7);
+ StringCopyN(gSaveBlock1.secretBases[0].sbr_field_2, gSaveBlock2.playerName, nameLength);
+ gSaveBlock1.secretBases[0].gender = gSaveBlock2.playerGender;
+ VarSet(VAR_SECRET_BASE_MAP, gMapHeader.regionMapSectionId);
+}
+
+void sub_80BB970(struct MapEvents *events)
+{
+ u16 bgevidx, idx, jdx;
+ s16 tile_id;
+ for (bgevidx=0; bgevidx<events->bgEventCount; bgevidx++) {
+ if (events->bgEvents[bgevidx].kind == 8) {
+ for (jdx=0; jdx<20; jdx++) {
+ if (gSaveBlock1.secretBases[jdx].sbr_field_0 == events->bgEvents[bgevidx].bgUnion.secretBaseId) {
+ tile_id = MapGridGetMetatileIdAt(events->bgEvents[bgevidx].x + 7, events->bgEvents[bgevidx].y + 7);
+ for (idx=0; idx<7; idx++) {
+ if (gUnknown_083D1358[idx].unk_083D1358_0 == tile_id) {
+ MapGridSetMetatileIdAt(events->bgEvents[bgevidx].x + 7, events->bgEvents[bgevidx].y + 7, gUnknown_083D1358[idx].unk_083D1358_1 | 0xc00);
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+}
+
+void sub_80BBA14(void)
+{
+ s8 idx = 4 * (gUnknown_020387DC / 10);
+ warp1_set_2(MAP_GROUP_SECRET_BASE_RED_CAVE1, gUnknown_083D1374[idx], gUnknown_083D1374[idx + 1]);
+}
+
+void sub_80BBA48(u8 taskid)
+{
+ u16 curbaseid;
+ switch (gTasks[taskid].data[0]) {
+ case 0:
+ gTasks[taskid].data[0] = 1;
+ break;
+ case 1:
+ if (!gPaletteFade.active) {
+ gTasks[taskid].data[0] = 2;
+ }
+ break;
+ case 2:
+ curbaseid = VarGet(VAR_0x4054);
+ if (gSaveBlock1.secretBases[curbaseid].sbr_field_10 < 0xff)
+ gSaveBlock1.secretBases[curbaseid].sbr_field_10 ++;
+ sub_80BBA14();
+ warp_in();
+ gFieldCallback = sub_8080990;
+ SetMainCallback2(CB2_LoadMap);
+ DestroyTask(taskid);
+ break;
+ }
+}
+
+void sub_80BBAF0(void)
+{
+ CreateTask(sub_80BBA48, 0);
+ fade_screen(1, 0);
+ saved_warp2_set(0, gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum, -1);
+}
+
+bool8 sub_80BBB24(void)
+{
+ if (gMapHeader.mapType == MAP_TYPE_SECRET_BASE && VarGet(VAR_0x4097) == 0)
+ return FALSE;
+ return TRUE;
+}
+
+void sub_80BBB50(u8 taskid)
+{
+ FieldObjectTurn(&(gMapObjects[gPlayerAvatar.mapObjectId]), 2);
+ if (sub_807D770() == 1) {
+ EnableBothScriptContexts();
+ DestroyTask(taskid);
+ }
+}
+
+void sub_80BBB90(void)
+{
+ s16 x, y;
+ ScriptContext2_Enable();
+ HideMapNamePopup();
+ sub_80BB764(&x, &y, 0x220);
+ MapGridSetMetatileIdAt(x + 7, y + 7, 0xe20);
+ CurrentMapDrawMetatileAt(x + 7, y + 7);
+ pal_fill_black();
+ CreateTask(sub_80BBB50, 0);
+}
+
+void sub_80BBBEC(u8 taskid)
+{
+ s8 idx;
+ if (!gPaletteFade.active) {
+ idx = 4 * (gUnknown_020387DC / 10);
+ Overworld_SetWarpDestination(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum, -1, gUnknown_083D1374[idx + 2], gUnknown_083D1374[idx + 3]);
+ warp_in();
+ gFieldCallback = sub_80BBB90;
+ SetMainCallback2(CB2_LoadMap);
+ DestroyTask(taskid);
+ }
+}
+
+void sub_80BBC78(void)
+{
+ u8 taskid = CreateTask(sub_80BBBEC, 0);
+ gTasks[taskid].data[0] = 0;
+ fade_screen(1, 0);
+}
+
+bool8 CurrentMapIsSecretBase(void)
+{
+ if (gSaveBlock1.location.mapGroup == MAP_GROUP_SECRET_BASE_SHRUB4 && (u8)(gSaveBlock1.location.mapNum) <= MAP_ID_SECRET_BASE_SHRUB4)
+ return TRUE;
+ return FALSE;
+}
+
+#ifdef NONMATCHING
+void sub_80BBCCC(u8 flagIn)
+{
+ u16 curBaseId;
+ u16 x, y;
+ if (CurrentMapIsSecretBase()) {
+ curBaseId = VarGet(VAR_0x4054);
+ for (x=0; x<16; x++) {
+ if ((u8)(gSaveBlock1.secretBases[curBaseId].decorations[x] - 1) <= 0x77 && gDecorations[gSaveBlock1.secretBases[curBaseId].decorations[x]].decor_field_11 != 4) {
+ sub_80FF394((gSaveBlock1.secretBases[0].decorationPos[x] >> 4) + 7, (gSaveBlock1.secretBases[0].decorationPos[x] & 0xF) + 7, gSaveBlock1.secretBases[curBaseId].decorations[x]);
+ }
+ }
+ if (curBaseId != 0) {
+ sub_80BB764(&x, &y, 0x220);
+ MapGridSetMetatileIdAt(x + 7, y + 7, 0xe21);
+ } else if (flagIn == 1 && VarGet(VAR_0x4089) == 1) {
+ sub_80BB764(&x, &y, 0x220);
+ MapGridSetMetatileIdAt(x + 7, y + 7, 0xe0a);
+ }
+ }
+}
+
+void sub_80BBDD0(void)
+{
+ u8 *roomdecor;
+ u8 *roomdecorpos;
+ u8 ndecor;
+ u8 decidx;
+ u8 objid = 0;
+ u8 metatile;
+ u16 curBase = VarGet(VAR_0x4054);
+ if (!CurrentMapIsSecretBase()) {
+ roomdecor = gSaveBlock1.playerRoomDecor;
+ roomdecorpos = gSaveBlock1.playerRoomDecorPos;
+ ndecor = 12;
+ } else {
+ roomdecor = gSaveBlock1.secretBases[curBase].decorations;
+ roomdecorpos = gSaveBlock1.secretBases[curBase].decorationPos;
+ ndecor = 16;
+ }
+ for (decidx=0; decidx<ndecor; decidx++) {
+ if (roomdecor[decidx] == 0)
+ continue;
+ if (gDecorations[roomdecor[decidx]].decor_field_11 != 4)
+ continue;
+ for (objid=0; objid<gMapHeader.events->mapObjectCount; objid++) {
+ if (gMapHeader.events->mapObjects[objid].flagId == gSpecialVar_0x8004 + 0xAE)
+ break;
+ }
+ if (objid != gMapHeader.events->mapObjectCount) {
+ gSpecialVar_0x8006 = roomdecorpos[decidx] >> 4;
+ gSpecialVar_0x8007 = roomdecorpos[decidx] & 0xF;
+ metatile = MapGridGetMetatileBehaviorAt(gSpecialVar_0x8006 + 7, gSpecialVar_0x8007 + 7);
+ if (sub_80572D8(metatile) == 1 || sub_80572EC(metatile) == 1) {
+ gScriptResult = gMapHeader.events->mapObjects[objid].graphicsId + 0x3f20;
+ VarSet(gScriptResult, gDecorations[roomdecor[decidx]].tiles[0]);
+ gScriptResult = gMapHeader.events->mapObjects[objid].localId;
+ FlagClear(gSpecialVar_0x8004 + 0xAE);
+ show_sprite(gScriptResult, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup);
+ sub_805C0F8(gScriptResult, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup, gSpecialVar_0x8006, gSpecialVar_0x8007);
+ sub_805C78C(gScriptResult, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup);
+ gSpecialVar_0x8004 ++;
+ }
+ }
+ }
+}
+
+#else
+__attribute__((naked))
+void sub_80BBCCC(u8 flagIn)
+{
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ mov r7, r8\n\
+ push {r7}\n\
+ sub sp, 0x4\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ mov r8, r0\n\
+ bl CurrentMapIsSecretBase\n\
+ lsls r0, 24\n\
+ cmp r0, 0\n\
+ beq _080BBDBC\n\
+ ldr r0, _080BBD70 @ =0x00004054\n\
+ bl VarGet\n\
+ lsls r0, 16\n\
+ lsrs r5, r0, 16\n\
+ movs r1, 0\n\
+ mov r0, sp\n\
+ strh r1, [r0]\n\
+ ldr r6, _080BBD74 @ =gSaveBlock1\n\
+ mov r4, sp\n\
+ ldr r0, _080BBD78 @ =0x00001a2a\n\
+ adds r7, r6, r0\n\
+_080BBCFC:\n\
+ lsls r0, r5, 2\n\
+ adds r0, r5\n\
+ lsls r0, 5\n\
+ ldrh r1, [r4]\n\
+ adds r2, r0, r1\n\
+ ldr r1, _080BBD7C @ =0x00001a1a\n\
+ adds r0, r6, r1\n\
+ adds r1, r2, r0\n\
+ ldrb r0, [r1]\n\
+ subs r0, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ cmp r0, 0x77\n\
+ bhi _080BBD3A\n\
+ ldr r0, _080BBD80 @ =gDecorations\n\
+ ldrb r3, [r1]\n\
+ lsls r1, r3, 5\n\
+ adds r1, r0\n\
+ ldrb r0, [r1, 0x11]\n\
+ cmp r0, 0x4\n\
+ beq _080BBD3A\n\
+ adds r0, r2, r7\n\
+ ldrb r2, [r0]\n\
+ lsrs r0, r2, 4\n\
+ adds r0, 0x7\n\
+ movs r1, 0xF\n\
+ ands r1, r2\n\
+ adds r1, 0x7\n\
+ adds r2, r3, 0\n\
+ bl sub_80FF394\n\
+_080BBD3A:\n\
+ ldrh r0, [r4]\n\
+ adds r0, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ strh r0, [r4]\n\
+ cmp r0, 0xF\n\
+ bls _080BBCFC\n\
+ cmp r5, 0\n\
+ beq _080BBD88\n\
+ mov r4, sp\n\
+ adds r4, 0x2\n\
+ movs r2, 0x88\n\
+ lsls r2, 2\n\
+ mov r0, sp\n\
+ adds r1, r4, 0\n\
+ bl sub_80BB764\n\
+ mov r0, sp\n\
+ ldrh r0, [r0]\n\
+ adds r0, 0x7\n\
+ ldrh r1, [r4]\n\
+ adds r1, 0x7\n\
+ ldr r2, _080BBD84 @ =0x00000e21\n\
+ bl MapGridSetMetatileIdAt\n\
+ b _080BBDBC\n\
+ .align 2, 0\n\
+_080BBD70: .4byte 0x00004054\n\
+_080BBD74: .4byte gSaveBlock1\n\
+_080BBD78: .4byte 0x00001a2a\n\
+_080BBD7C: .4byte 0x00001a1a\n\
+_080BBD80: .4byte gDecorations\n\
+_080BBD84: .4byte 0x00000e21\n\
+_080BBD88:\n\
+ mov r0, r8\n\
+ cmp r0, 0x1\n\
+ bne _080BBDBC\n\
+ ldr r0, _080BBDC8 @ =0x00004089\n\
+ bl VarGet\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ cmp r0, 0x1\n\
+ bne _080BBDBC\n\
+ mov r4, sp\n\
+ adds r4, 0x2\n\
+ movs r2, 0x88\n\
+ lsls r2, 2\n\
+ mov r0, sp\n\
+ adds r1, r4, 0\n\
+ bl sub_80BB764\n\
+ mov r0, sp\n\
+ ldrh r0, [r0]\n\
+ adds r0, 0x7\n\
+ ldrh r1, [r4]\n\
+ adds r1, 0x7\n\
+ ldr r2, _080BBDCC @ =0x00000e0a\n\
+ bl MapGridSetMetatileIdAt\n\
+_080BBDBC:\n\
+ add sp, 0x4\n\
+ pop {r3}\n\
+ mov r8, r3\n\
+ pop {r4-r7}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .align 2, 0\n\
+_080BBDC8: .4byte 0x00004089\n\
+_080BBDCC: .4byte 0x00000e0a\n\
+.syntax divided\n");
+}
+
+__attribute__((naked))
+void sub_80BBDD0(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\
+ sub sp, 0x14\n\
+ ldr r0, _080BBE00 @ =0x00004054\n\
+ bl VarGet\n\
+ lsls r0, 16\n\
+ lsrs r4, r0, 16\n\
+ bl CurrentMapIsSecretBase\n\
+ lsls r0, 24\n\
+ cmp r0, 0\n\
+ bne _080BBE08\n\
+ ldr r0, _080BBE04 @ =gSaveBlock1 + 0x2688\n\
+ str r0, [sp, 0x4]\n\
+ adds r0, 0xC\n\
+ str r0, [sp, 0x8]\n\
+ movs r1, 0xC\n\
+ str r1, [sp, 0xC]\n\
+ b _080BBE1E\n\
+ .align 2, 0\n\
+_080BBE00: .4byte 0x00004054\n\
+_080BBE04: .4byte gSaveBlock1 + 0x2688\n\
+_080BBE08:\n\
+ lsls r1, r4, 2\n\
+ adds r1, r4\n\
+ lsls r1, 5\n\
+ ldr r0, _080BBF7C @ =gSaveBlock1 + 0x1A1A\n\
+ adds r2, r1, r0\n\
+ str r2, [sp, 0x4]\n\
+ adds r0, 0x10\n\
+ adds r1, r0\n\
+ str r1, [sp, 0x8]\n\
+ movs r3, 0x10\n\
+ str r3, [sp, 0xC]\n\
+_080BBE1E:\n\
+ movs r6, 0\n\
+ ldr r4, [sp, 0xC]\n\
+ cmp r6, r4\n\
+ bcc _080BBE28\n\
+ b _080BBF6C\n\
+_080BBE28:\n\
+ ldr r5, _080BBF80 @ =gSaveBlock1\n\
+ mov r10, r5\n\
+_080BBE2C:\n\
+ ldr r1, [sp, 0x4]\n\
+ adds r0, r1, r6\n\
+ ldrb r1, [r0]\n\
+ mov r9, r0\n\
+ adds r2, r6, 0x1\n\
+ str r2, [sp, 0x10]\n\
+ cmp r1, 0\n\
+ bne _080BBE3E\n\
+ b _080BBF5E\n\
+_080BBE3E:\n\
+ ldrb r0, [r0]\n\
+ lsls r0, 5\n\
+ ldr r3, _080BBF84 @ =gDecorations\n\
+ adds r0, r3\n\
+ ldrb r0, [r0, 0x11]\n\
+ cmp r0, 0x4\n\
+ beq _080BBE4E\n\
+ b _080BBF5E\n\
+_080BBE4E:\n\
+ movs r5, 0\n\
+ ldr r0, _080BBF88 @ =gMapHeader\n\
+ ldr r2, [r0, 0x4]\n\
+ ldrb r3, [r2]\n\
+ mov r8, r0\n\
+ cmp r5, r3\n\
+ bcs _080BBE8E\n\
+ ldr r0, [r2, 0x4]\n\
+ ldrh r1, [r0, 0x14]\n\
+ ldr r4, _080BBF8C @ =gSpecialVar_0x8004\n\
+ ldrh r0, [r4]\n\
+ adds r0, 0xAE\n\
+ adds r7, r4, 0\n\
+ cmp r1, r0\n\
+ beq _080BBE8E\n\
+ adds r4, r2, 0\n\
+ adds r2, r3, 0\n\
+_080BBE70:\n\
+ adds r0, r5, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r5, r0, 24\n\
+ cmp r5, r2\n\
+ bcs _080BBE8E\n\
+ ldr r1, [r4, 0x4]\n\
+ lsls r0, r5, 1\n\
+ adds r0, r5\n\
+ lsls r0, 3\n\
+ adds r0, r1\n\
+ ldrh r1, [r0, 0x14]\n\
+ ldrh r0, [r7]\n\
+ adds r0, 0xAE\n\
+ cmp r1, r0\n\
+ bne _080BBE70\n\
+_080BBE8E:\n\
+ mov r1, r8\n\
+ ldr r0, [r1, 0x4]\n\
+ ldrb r0, [r0]\n\
+ cmp r5, r0\n\
+ beq _080BBF5E\n\
+ ldr r7, _080BBF90 @ =gSpecialVar_0x8006\n\
+ ldr r2, [sp, 0x8]\n\
+ adds r1, r2, r6\n\
+ ldrb r0, [r1]\n\
+ lsrs r0, 4\n\
+ strh r0, [r7]\n\
+ ldr r6, _080BBF94 @ =gSpecialVar_0x8007\n\
+ ldrb r1, [r1]\n\
+ movs r0, 0xF\n\
+ ands r0, r1\n\
+ strh r0, [r6]\n\
+ ldrh r0, [r7]\n\
+ adds r0, 0x7\n\
+ ldrh r1, [r6]\n\
+ adds r1, 0x7\n\
+ bl MapGridGetMetatileBehaviorAt\n\
+ lsls r0, 24\n\
+ lsrs r4, r0, 24\n\
+ adds r0, r4, 0\n\
+ bl sub_80572D8\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ cmp r0, 0x1\n\
+ beq _080BBEDA\n\
+ adds r0, r4, 0\n\
+ bl sub_80572EC\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ cmp r0, 0x1\n\
+ bne _080BBF5E\n\
+_080BBEDA:\n\
+ mov r3, r8\n\
+ ldr r0, [r3, 0x4]\n\
+ ldr r1, [r0, 0x4]\n\
+ lsls r4, r5, 1\n\
+ adds r4, r5\n\
+ lsls r4, 3\n\
+ adds r1, r4, r1\n\
+ ldr r5, _080BBF98 @ =0x00003f20\n\
+ adds r0, r5, 0\n\
+ ldrb r1, [r1, 0x1]\n\
+ adds r0, r1\n\
+ ldr r1, _080BBF9C @ =gScriptResult\n\
+ strh r0, [r1]\n\
+ ldrh r0, [r1]\n\
+ mov r2, r9\n\
+ ldrb r1, [r2]\n\
+ lsls r1, 5\n\
+ ldr r3, _080BBFA0 @ =gDecorations + 0x1C\n\
+ adds r1, r3\n\
+ ldr r1, [r1]\n\
+ ldrh r1, [r1]\n\
+ bl VarSet\n\
+ mov r5, r8\n\
+ ldr r0, [r5, 0x4]\n\
+ ldr r0, [r0, 0x4]\n\
+ adds r4, r0\n\
+ ldrb r0, [r4]\n\
+ ldr r1, _080BBF9C @ =gScriptResult\n\
+ strh r0, [r1]\n\
+ ldr r2, _080BBF8C @ =gSpecialVar_0x8004\n\
+ ldrh r0, [r2]\n\
+ adds r0, 0xAE\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ bl FlagClear\n\
+ ldr r3, _080BBF9C @ =gScriptResult\n\
+ ldrb r0, [r3]\n\
+ mov r4, r10\n\
+ ldrb r1, [r4, 0x5]\n\
+ ldrb r2, [r4, 0x4]\n\
+ bl show_sprite\n\
+ ldr r5, _080BBF9C @ =gScriptResult\n\
+ ldrb r0, [r5]\n\
+ ldrb r1, [r4, 0x5]\n\
+ ldrb r2, [r4, 0x4]\n\
+ movs r4, 0\n\
+ ldrsh r3, [r7, r4]\n\
+ movs r5, 0\n\
+ ldrsh r4, [r6, r5]\n\
+ str r4, [sp]\n\
+ bl sub_805C0F8\n\
+ ldr r1, _080BBF9C @ =gScriptResult\n\
+ ldrb r0, [r1]\n\
+ mov r2, r10\n\
+ ldrb r1, [r2, 0x5]\n\
+ ldrb r2, [r2, 0x4]\n\
+ bl sub_805C78C\n\
+ ldr r3, _080BBF8C @ =gSpecialVar_0x8004\n\
+ ldrh r0, [r3]\n\
+ adds r0, 0x1\n\
+ strh r0, [r3]\n\
+_080BBF5E:\n\
+ ldr r4, [sp, 0x10]\n\
+ lsls r0, r4, 24\n\
+ lsrs r6, r0, 24\n\
+ ldr r5, [sp, 0xC]\n\
+ cmp r6, r5\n\
+ bcs _080BBF6C\n\
+ b _080BBE2C\n\
+_080BBF6C:\n\
+ add sp, 0x14\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\
+ .align 2, 0\n\
+_080BBF7C: .4byte gSaveBlock1 + 0x1A1A\n\
+_080BBF80: .4byte gSaveBlock1\n\
+_080BBF84: .4byte gDecorations\n\
+_080BBF88: .4byte gMapHeader\n\
+_080BBF8C: .4byte gSpecialVar_0x8004\n\
+_080BBF90: .4byte gSpecialVar_0x8006\n\
+_080BBF94: .4byte gSpecialVar_0x8007\n\
+_080BBF98: .4byte 0x00003f20\n\
+_080BBF9C: .4byte gScriptResult\n\
+_080BBFA0: .4byte gDecorations + 0x1C\n\
+.syntax divided\n");
+}
+#endif
+
+void sub_80BBFA4(void)
+{
+ int curBase = VarGet(VAR_0x4054);
+ VarSet(VAR_0x401F, gUnknown_083D13EC[sub_80BCCA4(curBase)]);
+}
+
+void sub_80BBFD8(s16 *position, struct MapEvents *events)
+{
+ s16 bgevtidx;
+ for (bgevtidx=0; bgevtidx<events->bgEventCount; bgevtidx++) {
+ if (events->bgEvents[bgevtidx].kind == 8 && position[0] == events->bgEvents[bgevtidx].x + 7 && position[1] == events->bgEvents[bgevtidx].y + 7) {
+ gUnknown_020387DC = events->bgEvents[bgevtidx].bgUnion.secretBaseId;
+ break;
+ }
+ }
+}
+
+void sub_80BC038(s16 *position, struct MapEvents *events)
+{
+ sub_80BBFD8(position, events);
+ sub_80BB5E4();
+ ScriptContext1_SetupScript(gUnknown_081A2E14);
+}
+
+bool8 sub_80BC050(void)
+{
+ sub_80BB5D0();
+ sub_80BB5E4();
+ if (gScriptResult == 1)
+ return FALSE;
+ return TRUE;
+}
+
+void sub_80BC074(u8 taskid)
+{
+ switch (gTasks[taskid].data[0]) {
+ case 0:
+ ScriptContext2_Enable();
+ gTasks[taskid].data[0] = 1;
+ break;
+ case 1:
+ if (!gPaletteFade.active) {
+ gTasks[taskid].data[0] = 2;
+ }
+ break;
+ case 2:
+ copy_saved_warp2_bank_and_enter_x_to_warp1(0x7E);
+ warp_in();
+ gFieldCallback = mapldr_default;
+ SetMainCallback2(CB2_LoadMap);
+ ScriptContext2_Disable();
+ DestroyTask(taskid);
+ break;
+ }
+}
+
+void sub_80BC0F8(void) {
+ CreateTask(sub_80BC074, 0);
+ fade_screen(1, 0);
+}
+
+void sub_80BC114(void) {
+ if (gSaveBlock1.secretBases[0].sbr_field_0 != gUnknown_020387DC)
+ gScriptResult = 1;
+ else
+ gScriptResult = 0;
+}
+
+u8 sub_80BC14C(u8 sbid)
+{
+ s16 idx;
+ for (idx=0; idx<20; idx++) {
+ if (gSaveBlock1.secretBases[idx].sbr_field_0 == sbid)
+ return idx;
+ }
+ return 0;
+}
+
+u8 *sub_80BC190(u8 *dest, u8 arg1) { // 80bc190
+ u8 local1;
+ u8 *str;
+
+ local1 = sub_80BB8A8(gSaveBlock1.secretBases[arg1].sbr_field_2);
+
+ str = StringCopyN(dest, gSaveBlock1.secretBases[arg1].sbr_field_2, local1);
+ str[0] = EOS;
+
+#if ENGLISH
+ return StringAppend(dest, gOtherText_PlayersBase);
+#elif GERMAN
+ return de_sub_8073174(dest, gOtherText_PlayersBase);
+#endif
+}
+
+u8 *GetSecretBaseMapName(u8 *dest) {
+ gUnknown_020387DC = gSaveBlock1.secretBases[VarGet(VAR_0x4054)].sbr_field_0;
+ return sub_80BC190(dest, VarGet(VAR_0x4054));
+}
+
+void sub_80BC224(void) {
+ u8 *var0 = gSaveBlock1.secretBases[(u8)VarGet(VAR_0x4054)].sbr_field_2;
+ u8 *var1 = gStringVar1;
+ u8 var2 = sub_80BB8A8(var0);
+ u8 *var3 = StringCopyN(var1, var0, var2);
+ *var3 = EOS;
+}
+
+u8 sub_80BC268(u8 foo) { // 80bc268
+ if (gSaveBlock1.secretBases[foo].sbr_field_1_6)
+ return 1;
+ return 0;
+}
+
+u8 sub_80BC298(struct Pokemon *mon) { // 80bc298
+ u16 evsum = GetMonData(mon, MON_DATA_HP_EV);
+ evsum += GetMonData(mon, MON_DATA_ATK_EV);
+ evsum += GetMonData(mon, MON_DATA_DEF_EV);
+ evsum += GetMonData(mon, MON_DATA_SPD_EV);
+ evsum += GetMonData(mon, MON_DATA_SPATK_EV);
+ evsum += GetMonData(mon, MON_DATA_SPDEF_EV);
+ return (u8)(evsum / 6);
+}
+
+#ifdef NONMATCHING
+void sub_80BC300(void)
+{
+ u16 moveidx;
+ u16 sbpartyidx = 0;
+ int resetVal = 0;
+ u16 partyidx = 0;
+ while (partyidx < 6) {
+ partyidx ++;
+ for (moveidx=0; moveidx<4; moveidx++) {
+ gSaveBlock1.secretBases[0].partyMoves[(partyidx - 1) * 6 + moveidx] = resetVal;
+ }
+ gSaveBlock1.secretBases[0].partySpecies[partyidx - 1] = resetVal;
+ gSaveBlock1.secretBases[0].partyHeldItems[partyidx - 1] = resetVal;
+ gSaveBlock1.secretBases[0].partyLevels[partyidx - 1] = resetVal;
+ gSaveBlock1.secretBases[0].partyPersonality[partyidx - 1] = resetVal;
+ gSaveBlock1.secretBases[0].partyEVs[partyidx - 1] = resetVal;
+ if (GetMonData(&(gPlayerParty[partyidx - 1]), MON_DATA_SPECIES) != 0 && !GetMonData(&(gPlayerParty[partyidx - 1]), MON_DATA_IS_EGG)) {
+ sbpartyidx ++;
+ for (moveidx=0; moveidx<4; moveidx++) {
+ gSaveBlock1.secretBases[0].partyMoves[(sbpartyidx - 1) * 6 + moveidx] = GetMonData(&(gPlayerParty[partyidx - 1]), MON_DATA_MOVE1 + moveidx);
+ }
+ gSaveBlock1.secretBases[0].partySpecies[sbpartyidx - 1] = GetMonData(&(gPlayerParty[partyidx - 1]), MON_DATA_SPECIES);
+ gSaveBlock1.secretBases[0].partyHeldItems[sbpartyidx - 1] = GetMonData(&(gPlayerParty[partyidx - 1]), MON_DATA_HELD_ITEM);
+ gSaveBlock1.secretBases[0].partyLevels[sbpartyidx - 1] = GetMonData(&(gPlayerParty[partyidx - 1]), MON_DATA_LEVEL);
+ gSaveBlock1.secretBases[0].partyPersonality[sbpartyidx - 1] = GetMonData(&(gPlayerParty[partyidx - 1]), MON_DATA_PERSONALITY);
+ gSaveBlock1.secretBases[0].partyEVs[sbpartyidx - 1] = sub_80BC298(&(gPlayerParty[partyidx - 1]));
+ }
+ }
+}
+#else
+__attribute__((naked))
+void sub_80BC300(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\
+ sub sp, 0xC\n\
+ movs r0, 0\n\
+ mov r10, r0\n\
+ movs r6, 0\n\
+ mov r9, r6\n\
+_080BC314:\n\
+ movs r4, 0\n\
+ lsls r3, r6, 2\n\
+ lsls r2, r6, 1\n\
+ ldr r7, _080BC424 @ =gPlayerParty\n\
+ adds r1, r6, 0x1\n\
+ str r1, [sp]\n\
+ adds r1, r3, 0\n\
+_080BC322:\n\
+ adds r0, r1, r4\n\
+ lsls r0, 1\n\
+ ldr r5, _080BC428 @ =gSaveBlock1 + 0x1A54\n\
+ adds r0, r5, r0\n\
+ mov r5, r9\n\
+ strh r5, [r0]\n\
+ adds r0, r4, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r4, r0, 16\n\
+ cmp r4, 0x3\n\
+ bls _080BC322\n\
+ ldr r1, _080BC42C @ =gSaveBlock1 + 0x1A84\n\
+ adds r0, r1, r2\n\
+ strh r5, [r0]\n\
+ ldr r5, _080BC430 @ =gSaveBlock1 + 0x1A90\n\
+ adds r0, r5, r2\n\
+ mov r1, r9\n\
+ strh r1, [r0]\n\
+ ldr r2, _080BC434 @ =gSaveBlock1 + 0x1A9C\n\
+ adds r0, r2, r6\n\
+ mov r5, r9\n\
+ strb r5, [r0]\n\
+ ldr r1, _080BC438 @ =gSaveBlock1 + 0x1A3C\n\
+ adds r0, r1, r3\n\
+ mov r2, r9\n\
+ str r2, [r0]\n\
+ ldr r3, _080BC43C @ =gSaveBlock1 + 0x1AA2\n\
+ adds r0, r3, r6\n\
+ strb r2, [r0]\n\
+ movs r0, 0x64\n\
+ adds r5, r6, 0\n\
+ muls r5, r0\n\
+ adds r4, r5, r7\n\
+ adds r0, r4, 0\n\
+ movs r1, 0xB\n\
+ bl GetMonData\n\
+ cmp r0, 0\n\
+ beq _080BC408\n\
+ adds r0, r4, 0\n\
+ movs r1, 0x2D\n\
+ bl GetMonData\n\
+ cmp r0, 0\n\
+ bne _080BC408\n\
+ movs r4, 0\n\
+ mov r0, r10\n\
+ lsls r0, 2\n\
+ mov r8, r0\n\
+ mov r1, r10\n\
+ lsls r7, r1, 1\n\
+ adds r1, 0x1\n\
+ str r1, [sp, 0x4]\n\
+ ldr r2, _080BC424 @ =gPlayerParty\n\
+_080BC38E:\n\
+ adds r1, r4, 0\n\
+ adds r1, 0xD\n\
+ adds r0, r5, r2\n\
+ str r2, [sp, 0x8]\n\
+ bl GetMonData\n\
+ mov r3, r8\n\
+ adds r1, r3, r4\n\
+ lsls r1, 1\n\
+ ldr r3, _080BC428 @ =gSaveBlock1 + 0x1A54\n\
+ adds r1, r3, r1\n\
+ strh r0, [r1]\n\
+ adds r0, r4, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r4, r0, 16\n\
+ ldr r2, [sp, 0x8]\n\
+ cmp r4, 0x3\n\
+ bls _080BC38E\n\
+ movs r0, 0x64\n\
+ adds r4, r6, 0\n\
+ muls r4, r0\n\
+ ldr r0, _080BC424 @ =gPlayerParty\n\
+ adds r4, r0\n\
+ adds r0, r4, 0\n\
+ movs r1, 0xB\n\
+ bl GetMonData\n\
+ ldr r5, _080BC42C @ =gSaveBlock1 + 0x1A84\n\
+ adds r1, r5, r7\n\
+ strh r0, [r1]\n\
+ adds r0, r4, 0\n\
+ movs r1, 0xC\n\
+ bl GetMonData\n\
+ ldr r2, _080BC430 @ =gSaveBlock1 + 0x1A90\n\
+ adds r1, r2, r7\n\
+ strh r0, [r1]\n\
+ adds r0, r4, 0\n\
+ movs r1, 0x38\n\
+ bl GetMonData\n\
+ ldr r1, _080BC434 @ =gSaveBlock1 + 0x1A9C\n\
+ add r1, r10\n\
+ strb r0, [r1]\n\
+ adds r0, r4, 0\n\
+ movs r1, 0\n\
+ bl GetMonData\n\
+ ldr r1, _080BC438 @ =gSaveBlock1 + 0x1A3C\n\
+ add r1, r8\n\
+ str r0, [r1]\n\
+ adds r0, r4, 0\n\
+ bl sub_80BC298\n\
+ ldr r1, _080BC43C @ =gSaveBlock1 + 0x1AA2\n\
+ add r1, r10\n\
+ strb r0, [r1]\n\
+ ldr r3, [sp, 0x4]\n\
+ lsls r0, r3, 16\n\
+ lsrs r0, 16\n\
+ mov r10, r0\n\
+_080BC408:\n\
+ ldr r5, [sp]\n\
+ lsls r0, r5, 16\n\
+ lsrs r6, r0, 16\n\
+ cmp r6, 0x5\n\
+ bls _080BC314\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 {r0}\n\
+ bx r0\n\
+ .align 2, 0\n\
+_080BC424: .4byte gPlayerParty\n\
+_080BC428: .4byte gSaveBlock1 + 0x1A54\n\
+_080BC42C: .4byte gSaveBlock1 + 0x1A84\n\
+_080BC430: .4byte gSaveBlock1 + 0x1A90\n\
+_080BC434: .4byte gSaveBlock1 + 0x1A9C\n\
+_080BC438: .4byte gSaveBlock1 + 0x1A3C\n\
+_080BC43C: .4byte gSaveBlock1 + 0x1AA2\n\
+.syntax divided\n");
+}
+#endif
+
+void sub_80BC440(void)
+{
+ u16 backupValue = gSaveBlock1.secretBases[0].sbr_field_e;
+ ResetSecretBase(0);
+ gSaveBlock1.secretBases[0].sbr_field_e = backupValue;
+ sub_80BC0F8();
+}
+
+void SecretBasePC_PackUp(void)
+{
+ IncrementGameStat(20);
+ sub_80BC440();
+}
diff --git a/src/field/shop.c b/src/field/shop.c
new file mode 100644
index 000000000..375205935
--- /dev/null
+++ b/src/field/shop.c
@@ -0,0 +1,1351 @@
+#include "global.h"
+#include "shop.h"
+#include "decompress.h"
+#include "field_fadetransition.h"
+#include "field_weather.h"
+#include "item_menu.h"
+#include "main.h"
+#include "menu.h"
+#include "menu_helpers.h"
+#include "money.h"
+#include "palette.h"
+#include "script.h"
+#include "sound.h"
+#include "sprite.h"
+#include "strings.h"
+#include "task.h"
+#include "tv.h"
+#include "unknown_task.h"
+#include "field_map_obj.h"
+#include "field_player_avatar.h"
+#include "fieldmap.h"
+#include "item.h"
+#include "decoration.h"
+#include "items.h"
+#include "songs.h"
+#include "overworld.h"
+#include "decoration_inventory.h"
+#include "field_camera.h"
+
+#define ewram18000 ((u16 *)(ewram + 0x18000))
+#define ewram18300 ((u16 *)(ewram + 0x18300))
+
+extern bool8 sub_80A52C4(u8, u8);
+
+extern u8 ewram[];
+extern u8 gBuyMenuFrame_Gfx[];
+extern u16 gBuyMenuFrame_Tilemap[];
+extern u16 gMenuMoneyPal[16];
+
+void sub_80B39D0(int var1, int var2, bool32 hasControlCode);
+void sub_80B3A70(void);
+void sub_80B4378(u8);
+void sub_80B43F0(u8);
+void Task_ExitBuyMenu(u8);
+void sub_80B4470(u8);
+void sub_80B2EFC(u8 taskId);
+void sub_80B2F30(u8 taskId);
+void HandleShopMenuQuit(u8 taskId);
+void sub_80B3BF4(u8 taskId);
+void sub_80B3D7C(u8 taskId);
+
+// iwram
+static struct MartInfo gMartInfo;
+
+// ewram
+EWRAM_DATA u32 gMartTotalCost = 0;
+EWRAM_DATA s16 gUnknown_020386A4[16][4] = {0}; // game freak barely uses 2d arrays wtf?
+EWRAM_DATA struct ItemSlot gUnknown_02038724[3] = {0}; // tv.c uses this, so it cant be static
+EWRAM_DATA u8 gUnknown_02038730 = 0;
+EWRAM_DATA u8 gUnknown_02038731 = 0;
+
+// rodata
+static const struct MenuAction2 sBuySellQuitMenuActions[] =
+{
+ { MartText_Buy, sub_80B2EFC },
+ { MartText_Sell, sub_80B2F30 },
+ { MartText_Quit2, HandleShopMenuQuit },
+};
+
+static const u8 gUnknown_083CC6E8[] = {0, 1, 2}; // BUY SELL EXIT
+static const u8 gUnknown_083CC6EB[] = {0, 2}; // BUY EXIT
+
+static const u16 gUnusedMartArray[] = {0x2, 0x3, 0x4, 0xD, 0x121, 0xE, 0xE, 0xE, 0xE, 0xE, 0xE, 0x0, 0x0};
+
+static const struct YesNoFuncTable gUnknown_083CC708[] =
+{
+ sub_80B3BF4,
+ sub_80B3D7C
+};
+
+u8 CreateShopMenu(u8 martType)
+{
+ ScriptContext2_Enable();
+ gMartInfo.martType = martType;
+ gMartInfo.cursor = 0;
+
+ if (martType == MART_TYPE_0)
+ {
+ gMartInfo.numChoices = 2;
+ MenuDrawTextWindow(0, 0, 10, 7);
+ PrintMenuItemsReordered(1, 1, 3, sBuySellQuitMenuActions, gUnknown_083CC6E8);
+ }
+ else
+ {
+ gMartInfo.numChoices = 1;
+ MenuDrawTextWindow(0, 0, 10, 5);
+ PrintMenuItemsReordered(1, 1, 2, sBuySellQuitMenuActions, gUnknown_083CC6EB);
+ }
+ InitMenu(0, 1, 1, gMartInfo.numChoices + 1, 0, 9); // add 1 for cancel
+
+ return CreateTask(sub_80B2E38, 8);
+}
+
+void SetShopMenuCallback(void *callbackPtr)
+{
+ gMartInfo.callback = callbackPtr;
+}
+
+void SetShopItemsForSale(u16 *items)
+{
+ u16 i = 0;
+
+ gMartInfo.itemList = items;
+ gMartInfo.itemCount = 0;
+
+ while (gMartInfo.itemList[i])
+ {
+ gMartInfo.itemCount++;
+ i++;
+ }
+}
+
+void sub_80B2E38(u8 var)
+{
+ const u8 local = var;
+
+ if (gMain.newAndRepeatedKeys & DPAD_UP)
+ {
+ if (gMartInfo.cursor) // can move cursor up?
+ {
+ PlaySE(SE_SELECT);
+ gMartInfo.cursor = MoveMenuCursor(-1);
+ }
+ }
+ else if (gMain.newAndRepeatedKeys & DPAD_DOWN)
+ {
+ if (gMartInfo.cursor != gMartInfo.numChoices) // can move cursor down?
+ {
+ PlaySE(SE_SELECT);
+ gMartInfo.cursor = MoveMenuCursor(1);
+ }
+ }
+ else if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ if (gMartInfo.martType == MART_TYPE_0)
+ {
+ sBuySellQuitMenuActions[gUnknown_083CC6E8[gMartInfo.cursor]].func(local);
+ }
+ else
+ {
+ sBuySellQuitMenuActions[gUnknown_083CC6EB[gMartInfo.cursor]].func(local);
+ }
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ HandleShopMenuQuit(local);
+ }
+}
+
+void sub_80B2EFC(u8 taskId)
+{
+ gTasks[taskId].data[8] = (u32)BuyMenuDrawGraphics >> 16;
+ gTasks[taskId].data[9] = (u32)BuyMenuDrawGraphics;
+ gTasks[taskId].func = sub_80B2FA0;
+ fade_screen(1, 0);
+}
+
+void sub_80B2F30(u8 taskId)
+{
+ gTasks[taskId].data[8] = (u32)sub_80A6300 >> 16;
+ gTasks[taskId].data[9] = (u32)sub_80A6300;
+ gTasks[taskId].func = sub_80B2FA0;
+ fade_screen(1, 0);
+}
+
+void HandleShopMenuQuit(u8 taskId)
+{
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(0, 0, 11, 8);
+ sub_80BE3BC();
+ ScriptContext2_Disable();
+ DestroyTask(taskId);
+
+ if (gMartInfo.callback)
+ gMartInfo.callback(); // run the callback if it exists.
+}
+
+void sub_80B2FA0(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ SetMainCallback2((void *)((u16)gTasks[taskId].data[8] << 16 | (u16)gTasks[taskId].data[9]));
+ DestroyTask(taskId);
+ }
+}
+
+void ReturnToShopMenuAfterExitingSellMenu(u8 taskId)
+{
+ CreateShopMenu(gMartInfo.martType);
+ DestroyTask(taskId);
+}
+
+void Task_ExitSellMenu(u8 taskId)
+{
+ if (sub_807D770() == 1)
+ {
+ if (gMartInfo.martType == MART_TYPE_2)
+ DisplayItemMessageOnField(taskId, gOtherText_CanIHelpYou, ReturnToShopMenuAfterExitingSellMenu, 0);
+ else
+ DisplayItemMessageOnField(taskId, gOtherText_AnythingElse, ReturnToShopMenuAfterExitingSellMenu, 0);
+ }
+}
+
+void sub_80B3050(void)
+{
+ pal_fill_black();
+ CreateTask(Task_ExitSellMenu, 0x8);
+}
+
+void sub_80B3068(u8 taskId)
+{
+ Task_ExitSellMenu(taskId);
+}
+
+void unref_sub_80B3078(u8 taskId)
+{
+ gTasks[taskId].func = Task_ExitSellMenu;
+}
+
+void sub_80B3094(void)
+{
+ AnimateSprites();
+ BuildOamBuffer();
+ RunTasks();
+ UpdatePaletteFade();
+}
+
+void sub_80B30AC(void)
+{
+ void *addr;
+ void *addr2;
+ void *addr3;
+ u16 *tempArr;
+ u16 *tempArr2;
+ u16 *tempArr3;
+
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+
+ // temp vars needed to match for some dumb reason
+ tempArr = gBGTilemapBuffers[1];
+ addr = (void *)(VRAM + 0xE800);
+ DmaCopy16(3, tempArr, addr, 0x800);
+ tempArr2 = gBGTilemapBuffers[2];
+ addr2 = (void *)(VRAM + 0xE000);
+ DmaCopy16(3, tempArr2, addr2, 0x800);
+ tempArr3 = gBGTilemapBuffers[3];
+ addr3 = (void *)(VRAM + 0xF000);
+ DmaCopy16(3, tempArr3, addr3, 0x800);
+}
+
+// this function is fugly. pls fix
+void BuyMenuDrawGraphics(void)
+{
+ void *addr;
+ register u16 zero2 asm("r5");
+
+ sub_80F9438();
+ remove_some_task();
+ REG_BG1HOFS = (zero2 = 0);
+ REG_BG1VOFS = zero2;
+ REG_BG2HOFS = zero2;
+ REG_BG2VOFS = zero2;
+ REG_BG3HOFS = zero2;
+ REG_BG3VOFS = zero2;
+ gPaletteFade.bufferTransferDisabled = 1;
+ addr = (void*)OAM;
+ {
+ register const u32 zero asm("r6") = 0;
+ DmaFill32(3, zero, addr, OAM_SIZE);
+ LZDecompressVram(gBuyMenuFrame_Gfx, (void*)(VRAM + 0x7C00));
+ LZDecompressWram(gBuyMenuFrame_Tilemap, (void *)0x02018000);
+ LoadCompressedPalette(gMenuMoneyPal, 0xC0, sizeof(gMenuMoneyPal));
+ FreeAllSpritePalettes();
+ ResetPaletteFade();
+ ResetSpriteData();
+ ResetTasks();
+ SetUpWindowConfig(&gWindowConfig_81E6DFC);
+ InitMenuWindow(&gWindowConfig_81E6DFC);
+ BuyMenuDrawMapGraphics();
+ gMartInfo.cursor = zero;
+ gMartInfo.choicesAbove = zero2;
+ MenuZeroFillWindowRect(0, 0, 0x20, 0x20);
+ OpenMoneyWindow(gSaveBlock1.money, 0, 0);
+ sub_80B3764(0, 7);
+ sub_80B37EC();
+ sub_80B3270();
+ CreateTask(sub_80B40E8, 0x8);
+ sub_80B3240();
+ asm("":::"r4"); // what??
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, zero);
+ gPaletteFade.bufferTransferDisabled = 0;
+ SetVBlankCallback(sub_80B30AC);
+ SetMainCallback2(sub_80B3094);
+ }
+}
+
+void sub_80B3240(void)
+{
+ u16 tempArr[2] = {0x41EE, 0x7FFF};
+
+ LoadPalette(&tempArr[1], 0xD1, 2);
+ LoadPalette(&tempArr[0], 0xD8, 2);
+}
+
+void sub_80B3270(void)
+{
+ sub_80F944C();
+
+ if (gMartInfo.itemCount > 7)
+ {
+ CreateVerticalScrollIndicators(0, 172, 12);
+ CreateVerticalScrollIndicators(1, 172, 148);
+ sub_80F979C(0, 1);
+ }
+}
+
+void sub_80B32A4(void)
+{
+ if (gMartInfo.choicesAbove == 0)
+ sub_80F979C(0, 1);
+ else
+ sub_80F979C(0, 0);
+
+ if (gMartInfo.choicesAbove + 7 >= gMartInfo.itemCount)
+ sub_80F979C(1, 1);
+ else
+ sub_80F979C(1, 0);
+}
+
+void sub_80B32EC(u16 *array, s16 offset1, s16 offset2)
+{
+ array[offset1 + offset2] = 0xC3E1;
+ array[offset1 + offset2 + 1] = 0xC3E1;
+}
+
+void BuyMenuDrawMapMetatileLayer(u16 *array, s16 offset1, s16 offset2, u16 *array2)
+{
+ array[offset1 + offset2] = array2[0];
+ array[offset1 + offset2 + 1] = array2[1];
+ array[offset1 + offset2 + 32] = array2[2];
+ array[offset1 + offset2 + 33] = array2[3];
+}
+
+void BuyMenuDrawMapMetatile(int var1, int var2, u16 *var3, s32 var4)
+{
+ u8 tempVar4 = var4;
+ s16 offset1 = var1 * 2;
+ s16 offset2 = (var2 * 0x40) + 0x40;
+
+ switch (tempVar4)
+ {
+ case 0: // _080B335C
+ BuyMenuDrawMapMetatileLayer(gBGTilemapBuffers[2], offset1, offset2, var3);
+ BuyMenuDrawMapMetatileLayer(gBGTilemapBuffers[1], offset1, offset2, var3 + 4);
+ break;
+ case 1: // _080B3364
+ BuyMenuDrawMapMetatileLayer(gBGTilemapBuffers[3], offset1, offset2, var3);
+ BuyMenuDrawMapMetatileLayer(gBGTilemapBuffers[2], offset1, offset2, var3 + 4);
+ break;
+ case 2: // _080B3398
+ BuyMenuDrawMapMetatileLayer(gBGTilemapBuffers[3], offset1, offset2, var3);
+ BuyMenuDrawMapMetatileLayer(gBGTilemapBuffers[1], offset1, offset2, var3 + 4);
+ break;
+ }
+}
+
+void sub_80B33D0(s16 var1, int var2, u16 *var3)
+{
+ s16 offset1 = var1 * 2;
+ s16 offset2 = (var2 * 0x40) + 0x40;
+
+ BuyMenuDrawMapMetatileLayer(gBGTilemapBuffers[3], offset1, offset2, var3);
+ BuyMenuDrawMapMetatileLayer(gBGTilemapBuffers[2], offset1, offset2, var3 + 4);
+}
+
+void sub_80B3420(void)
+{
+ s16 facingX;
+ s16 facingY;
+ s16 x;
+ s16 y;
+
+ GetXYCoordsOneStepInFrontOfPlayer(&facingX, &facingY);
+ facingX -= 3;
+ facingY -= 3;
+
+ for (y = 0; y < 6; y++)
+ {
+ for (x = 0; x < 7; x++)
+ {
+ u16 metatileId = MapGridGetMetatileIdAt(facingX + x, facingY + y);
+
+ if (y != 5 && x != 6)
+ {
+ s32 r3 = MapGridGetMetatileLayerTypeAt(facingX + x, facingY + y);
+
+ if (metatileId < 512)
+ BuyMenuDrawMapMetatile(x, y, (u16 *)gMapHeader.mapData->primaryTileset->metatiles + metatileId * 8, r3);
+ else
+ BuyMenuDrawMapMetatile(x, y, (u16 *)gMapHeader.mapData->secondaryTileset->metatiles + (metatileId - 512) * 8, r3);
+ }
+ else
+ {
+ if (metatileId < 512)
+ sub_80B33D0(x, y, (u16 *)gMapHeader.mapData->primaryTileset->metatiles + metatileId * 8);
+ else
+ sub_80B33D0(x, y, (u16 *)gMapHeader.mapData->secondaryTileset->metatiles + (metatileId - 512) * 8);
+ }
+
+ if (y == 0 && x != 0 && x != 6)
+ sub_80B32EC(gBGTilemapBuffers[1], x * 2, 64);
+ }
+ }
+}
+
+void BuyMenuDrawMapGraphics(void)
+{
+ sub_80F9020();
+ sub_80B356C();
+ sub_80B368C();
+ sub_80B3420();
+}
+
+void sub_80B356C(void)
+{
+ s16 facingX;
+ s16 facingY;
+ u8 playerHeight;
+ u8 y;
+ u8 x;
+ u8 r8 = 0;
+
+ GetXYCoordsOneStepInFrontOfPlayer(&facingX, &facingY);
+ playerHeight = PlayerGetZCoord();
+ for (y = 0; y < 16; y++)
+ gUnknown_020386A4[y][MAP_OBJ_ID] = 16;
+ for (y = 0; y < 5; y++)
+ {
+ for (x = 0; x < 7; x++)
+ {
+ u8 mapObjId = GetFieldObjectIdByXYZ(facingX - 3 + x, facingY - 2 + y, playerHeight);
+
+ if (mapObjId != 16)
+ {
+ gUnknown_020386A4[r8][MAP_OBJ_ID] = mapObjId;
+ gUnknown_020386A4[r8][X_COORD] = x;
+ gUnknown_020386A4[r8][Y_COORD] = y;
+ if (gMapObjects[mapObjId].mapobj_unk_18 == 1)
+ gUnknown_020386A4[r8][ANIM_NUM] = 0;
+ if (gMapObjects[mapObjId].mapobj_unk_18 == 2)
+ gUnknown_020386A4[r8][ANIM_NUM] = 1;
+ if (gMapObjects[mapObjId].mapobj_unk_18 == 3)
+ gUnknown_020386A4[r8][ANIM_NUM] = 2;
+ if (gMapObjects[mapObjId].mapobj_unk_18 == 4)
+ gUnknown_020386A4[r8][ANIM_NUM] = 3;
+ r8++;
+ }
+ }
+ }
+}
+
+void sub_80B368C(void)
+{
+ u8 i;
+
+ for (i = 0; i < 16; i++) // max objects?
+ {
+ if (gUnknown_020386A4[i][MAP_OBJ_ID] == 16)
+ continue;
+
+ StartSpriteAnim(&gSprites[AddPseudoFieldObject(
+ gMapObjects[gUnknown_020386A4[i][MAP_OBJ_ID]].graphicsId,
+ SpriteCallbackDummy,
+ (u16)gUnknown_020386A4[i][X_COORD] * 16 + 8,
+ (u16)gUnknown_020386A4[i][Y_COORD] * 16 + 32,
+ 2)],
+ gUnknown_020386A4[i][ANIM_NUM]);
+ }
+}
+
+void sub_80B3720(void)
+{
+ s16 i;
+
+ for (i = 0; i < 0x400; i++)
+ {
+ if (ewram18000[i] != 0)
+ gBGTilemapBuffers[1][i] = ewram18000[i] + 0xC3E0;
+ }
+}
+
+void sub_80B3764(int var1, int var2)
+{
+ sub_80B3720();
+ sub_80B39D0(var1, var2, 0);
+ InitMenu(0, 0xE, 0x2, 0x8, gMartInfo.cursor, 0xF);
+}
+
+void sub_80B379C(void)
+{
+ u16 i, j;
+
+ for (i = 0; i < 8; i++)
+ for (j = 0; j < 14; j++)
+ gBGTilemapBuffers[1][32 * (i + 12) + j] = ewram18300[32 * i + j] + 0xC3E0;
+}
+
+void sub_80B37EC(void)
+{
+ sub_80B3A70();
+}
+
+void sub_80B37F8(u8 taskId)
+{
+ u16 itemListIndex = gMartInfo.choicesAbove + gMartInfo.cursor;
+ u16 itemId = gMartInfo.itemList[itemListIndex];
+ u32 price = (ItemId_GetPrice(itemId) >> GetPriceReduction(1));
+
+ PrintMoneyAmount(gTasks[taskId].data[1] * price, 6, 6, 11);
+ gStringVar1[0] = EXT_CTRL_CODE_BEGIN;
+ gStringVar1[1] = 0x14;
+ gStringVar1[2] = 0x6;
+ ConvertIntToDecimalStringN(&gStringVar1[3], gTasks[taskId].data[1], 1, 2);
+ MenuPrint(gOtherText_xString1, 1, 11);
+ sub_80A3FA0(gBGTilemapBuffers[1], 1, 11, 12, 2, 0xC3E1);
+}
+
+void sub_80B389C(u16 itemId, u8 var2, bool32 hasControlCode)
+{
+ u8 *stringPtr = gStringVar1;
+
+ if (hasControlCode != FALSE)
+ {
+ stringPtr[0] = EXT_CTRL_CODE_BEGIN;
+ stringPtr[1] = 0x1;
+ stringPtr[2] = 0x2;
+ stringPtr += 3;
+ }
+
+ CopyItemName(itemId, stringPtr);
+
+ sub_8072A18(&gStringVar1[0], 0x70, var2 << 3, 0x58, 0x1);
+ stringPtr = gStringVar1;
+
+ if (hasControlCode != FALSE)
+ stringPtr = &gStringVar1[3];
+
+ GetMoneyAmountText(stringPtr, (ItemId_GetPrice(itemId) >> GetPriceReduction(1)), 0x4);
+ MenuPrint_PixelCoords(&gStringVar1[0], 0xCA, var2 << 3, 1);
+}
+
+void sub_80B3930(u16 itemId, u8 var2, bool32 hasControlCode)
+{
+ u8 *stringPtr = gStringVar1;
+
+ if (hasControlCode != FALSE)
+ {
+ stringPtr[0] = EXT_CTRL_CODE_BEGIN;
+ stringPtr[1] = 0x1;
+ stringPtr[2] = 0x2;
+ stringPtr += 3;
+ }
+
+ StringCopy(stringPtr, gDecorations[itemId].name);
+ sub_8072A18(&gStringVar1[0], 0x70, var2 << 3, 0x58, 0x1);
+ stringPtr = gStringVar1;
+
+ if (hasControlCode != FALSE)
+ stringPtr = &gStringVar1[3];
+
+ if (gDecorations[itemId].price == 10000)
+ {
+ sub_80B7B34(0x19, var2, hasControlCode); // huh???
+ }
+ else
+ {
+ GetMoneyAmountText(stringPtr, gDecorations[itemId].price, 0x4);
+ MenuPrint_PixelCoords(&gStringVar1[0], 0xCA, var2 << 3, 0x1);
+ }
+}
+
+void sub_80B39D0(int var1, int var2, bool32 hasControlCode)
+{
+ u8 i;
+
+ for (i = var1; i <= var2 && gMartInfo.choicesAbove + i < gMartInfo.itemCount; i++)
+ {
+ if (gMartInfo.martType == MART_TYPE_0)
+ sub_80B389C(gMartInfo.itemList[gMartInfo.choicesAbove + i], (i << 1) + 2, hasControlCode);
+ else
+ sub_80B3930(gMartInfo.itemList[gMartInfo.choicesAbove + i], (i << 1) + 2, hasControlCode);
+ }
+
+ if (i != 8 && gMartInfo.choicesAbove + i == gMartInfo.itemCount)
+ {
+ MenuFillWindowRectWithBlankTile(0xE, (i << 1) + 2, 0x1C, (i << 1) + 3);
+ MenuPrint(gOtherText_CancelNoTerminator, 0xE, (i << 1) + 2);
+ }
+}
+
+void sub_80B3A70(void)
+{
+ if (gMartInfo.choicesAbove + gMartInfo.cursor != gMartInfo.itemCount)
+ {
+ if (gMartInfo.martType == MART_TYPE_0)
+ {
+ sub_8072AB0(ItemId_GetDescription(gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor]),
+ 0x4, 0x68, 0x68, 0x30, 0);
+ }
+ else
+ sub_8072AB0(gDecorations[gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor]].description,
+ 0x4, 0x68, 0x68, 0x30, 0);
+ }
+ else
+ {
+ sub_8072AB0(gOtherText_QuitShopping, 0x4, 0x68, 0x68, 0x30, 0);
+ }
+}
+
+void sub_80B3AEC(u8 taskId)
+{
+ if (gMain.newKeys & A_BUTTON || gMain.newKeys & B_BUTTON)
+ {
+ sub_80B39D0(gMartInfo.cursor, gMartInfo.cursor, 0); // huh???
+ PlaySE(SE_SELECT);
+
+ if (gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor] == ITEM_POKE_BALL && gTasks[taskId].data[1] >= 10 && AddBagItem(ITEM_PREMIER_BALL, 1) == TRUE)
+ DisplayItemMessageOnField(taskId, gOtherText_FreePremierBall, sub_80B4378, 0xC3E1);
+ else
+ sub_80B4378(taskId);
+ }
+}
+
+void sub_80B3B80(u8 taskId)
+{
+ IncrementGameStat(0x26);
+ RemoveMoney(&gSaveBlock1.money, gMartTotalCost);
+ PlaySE(SE_REGI);
+ UpdateMoneyWindow(gSaveBlock1.money, 0, 0);
+ gTasks[taskId].func = sub_80B3AEC;
+}
+
+void sub_80B3BD0(u8 taskId)
+{
+ sub_80B39D0(gMartInfo.cursor, gMartInfo.cursor, 0); // same thing as above?
+ sub_80B4378(taskId);
+}
+
+void sub_80B3BF4(u8 taskId)
+{
+ MenuZeroFillWindowRect(0x7, 0x8, 0xD, 0xD);
+ sub_80A3FA0(gBGTilemapBuffers[1], 8, 9, 4, 4, 0);
+ sub_80B379C();
+ sub_80B3420();
+
+ if (IsEnoughMoney(gSaveBlock1.money, gMartTotalCost))
+ {
+ if (gMartInfo.martType == MART_TYPE_0)
+ {
+ if (AddBagItem(gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor], gTasks[taskId].data[1]))
+ {
+ DisplayItemMessageOnField(taskId, gOtherText_HereYouGo, sub_80B3B80, 0xC3E1);
+ sub_80B4470(taskId);
+ }
+ else
+ DisplayItemMessageOnField(taskId, gOtherText_NoRoomFor, sub_80B3BD0, 0xC3E1);
+ }
+ else // a normal mart is only type 0, so types 1 and 2 are decoration marts.
+ {
+ if (IsThereStorageSpaceForDecoration(gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor]))
+ {
+ if (gMartInfo.martType == MART_TYPE_1)
+ DisplayItemMessageOnField(taskId, gOtherText_HereYouGo2, sub_80B3B80, 0xC3E1);
+ else
+ DisplayItemMessageOnField(taskId, gOtherText_HereYouGo3, sub_80B3B80, 0xC3E1);
+ }
+ else
+ {
+ StringExpandPlaceholders(gStringVar4, gOtherText_SpaceForIsFull);
+ DisplayItemMessageOnField(taskId, gStringVar4, sub_80B3BD0, 0xC3E1);
+ }
+ }
+ }
+ else
+ DisplayItemMessageOnField(taskId, gOtherText_NotEnoughMoney, sub_80B3BD0, 0xC3E1);
+}
+
+void sub_80B3D38(u8 taskId)
+{
+ DisplayYesNoMenu(7, 8, 1);
+ sub_80A3FA0(gBGTilemapBuffers[1], 8, 9, 4, 4, 0xC3E1);
+ DoYesNoFuncWithChoice(taskId, gUnknown_083CC708);
+}
+
+void sub_80B3D7C(u8 taskId)
+{
+ sub_80B39D0(gMartInfo.cursor, gMartInfo.cursor, 0);
+ MenuZeroFillWindowRect(0x7, 0x8, 0xD, 0xD);
+ sub_80A3FA0(gBGTilemapBuffers[1], 0x8, 0x9, 0x4, 0x4, 0);
+ sub_80B4378(taskId);
+}
+
+void sub_80B3DC8(u8 taskId)
+{
+ if (sub_80A52C4(taskId, gMartInfo.curItemCount) == TRUE)
+ sub_80B37F8(taskId);
+
+ if (gMain.newKeys & A_BUTTON)
+ {
+ gMartTotalCost = (ItemId_GetPrice(gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor]) >> GetPriceReduction(1)) * gTasks[taskId].data[1]; // set total cost of your purchase.
+ MenuZeroFillWindowRect(0, 0xA, 0xD, 0xD);
+ sub_80A3FA0(gBGTilemapBuffers[1], 0x1, 0xB, 0xC, 0x2, 0);
+ sub_80B379C();
+ sub_80B3420();
+ CopyItemName(gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor], gStringVar1);
+ ConvertIntToDecimalStringN(gStringVar2, gTasks[taskId].data[1], 0, 0x2);
+ ConvertIntToDecimalStringN(gStringVar3, gMartTotalCost, 0, 0x8);
+ StringExpandPlaceholders(gStringVar4, gOtherText_ThatWillBe);
+ DisplayItemMessageOnField(taskId, gStringVar4, sub_80B3D38, 0xC3E1);
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ sub_80B39D0(gMartInfo.cursor, gMartInfo.cursor, 0);
+ sub_80B4378(taskId);
+ }
+}
+
+void sub_80B3EFC(u8 taskId)
+{
+ u16 var;
+
+ gTasks[taskId].data[1] = 1;
+ MenuDrawTextWindow(0, 0xA, 0xD, 0xD);
+ sub_80B37F8(taskId);
+
+ var = gSaveBlock1.money / (ItemId_GetPrice(gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor]) >> GetPriceReduction(1));
+ if (var > 99)
+ gMartInfo.curItemCount = 99;
+ else
+ gMartInfo.curItemCount = var;
+
+ gTasks[taskId].func = sub_80B3DC8;
+}
+
+#ifdef NONMATCHING
+void sub_80B3F88(void)
+{
+ u16 *r1;
+ u16 *r2;
+ register u8 *r10 asm("r10");
+ s32 i;
+ s32 j;
+ struct Window *r8 = &gMenuWindow;
+
+ r1 = r8->tilemap;
+ r1 += 0x1EF;
+ r2 = r1;
+ r2 += 64;
+ r10 = r8->tileData;
+
+ for (i = 0; i < 14; i++)
+ {
+ for (j = 0; j < 15; j++)
+ {
+ if ((r1[j] & 0x3FF) <= r8->tileDataStartOffset + 1)
+ r2[j] = r8->tileDataStartOffset + 1;
+ else
+ r2[j] = r1[j] + 0x3C;
+ }
+
+ r1 -= 32;
+ r2 -= 32;
+ }
+
+ {
+ u8 *r1 = r10 + 0x3A20;
+ u8 *r2 = r1 + 0x780;
+ for (i = 0; i < 14; i++)
+ {
+ DmaCopy16(3, r1, r2, 0x1E0);
+ r2 -= 0x3C0;
+ r1 -= 0x3C0;
+ }
+ }
+}
+#else
+__attribute__((naked))
+void sub_80B3F88(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\
+ sub sp, 0x4\n\
+ ldr r0, _080B4020 @ =gMenuWindow\n\
+ mov r8, r0\n\
+ ldr r1, [r0, 0x28]\n\
+ ldr r3, _080B4024 @ =0x000003de\n\
+ adds r1, r3\n\
+ adds r2, r1, 0\n\
+ adds r2, 0x80\n\
+ ldr r7, [r0, 0x24]\n\
+ mov r10, r7\n\
+ ldr r0, _080B4028 @ =0x000003ff\n\
+ mov r9, r0\n\
+ movs r6, 0xD\n\
+_080B3FAC:\n\
+ adds r3, r2, 0\n\
+ subs r3, 0x40\n\
+ str r3, [sp]\n\
+ movs r7, 0x40\n\
+ negs r7, r7\n\
+ adds r7, r1\n\
+ mov r12, r7\n\
+ adds r3, r2, 0\n\
+ adds r4, r1, 0\n\
+ movs r5, 0xE\n\
+_080B3FC0:\n\
+ ldrh r2, [r4]\n\
+ mov r1, r9\n\
+ ands r1, r2\n\
+ mov r7, r8\n\
+ ldrh r0, [r7, 0x1A]\n\
+ adds r0, 0x1\n\
+ cmp r1, r0\n\
+ ble _080B3FD4\n\
+ adds r0, r2, 0\n\
+ adds r0, 0x3C\n\
+_080B3FD4:\n\
+ strh r0, [r3]\n\
+ adds r3, 0x2\n\
+ adds r4, 0x2\n\
+ subs r5, 0x1\n\
+ cmp r5, 0\n\
+ bge _080B3FC0\n\
+ ldr r2, [sp]\n\
+ mov r1, r12\n\
+ subs r6, 0x1\n\
+ cmp r6, 0\n\
+ bge _080B3FAC\n\
+ ldr r1, _080B402C @ =0x00003a20\n\
+ add r1, r10\n\
+ movs r0, 0xF0\n\
+ lsls r0, 3\n\
+ adds r2, r1, r0\n\
+ ldr r3, _080B4030 @ =0x040000d4\n\
+ ldr r5, _080B4034 @ =0x800000f0\n\
+ ldr r4, _080B4038 @ =0xfffffc40\n\
+ movs r6, 0xD\n\
+_080B3FFC:\n\
+ str r1, [r3]\n\
+ str r2, [r3, 0x4]\n\
+ str r5, [r3, 0x8]\n\
+ ldr r0, [r3, 0x8]\n\
+ adds r2, r4\n\
+ adds r1, r4\n\
+ subs r6, 0x1\n\
+ cmp r6, 0\n\
+ bge _080B3FFC\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\
+ .align 2, 0\n\
+_080B4020: .4byte gMenuWindow\n\
+_080B4024: .4byte 0x000003de\n\
+_080B4028: .4byte 0x000003ff\n\
+_080B402C: .4byte 0x00003a20\n\
+_080B4030: .4byte 0x040000d4\n\
+_080B4034: .4byte 0x800000f0\n\
+_080B4038: .4byte 0xfffffc40\n\
+ .syntax divided");
+}
+#endif
+
+#ifdef NONMATCHING
+void sub_80B403C(void)
+{
+ u16 *r1;
+ u16 *r2;
+ u8 *r10;
+ s32 i;
+ s32 j;
+ struct Window *r8 = &gMenuWindow;
+
+ r1 = r8->tilemap;
+ r1 += 0x4F;
+ r2 = r1;
+ r2 += 64;
+ r10 = r8->tileData;
+
+ for (i = 0; i < 14; i++)
+ {
+ for (j = 0; j < 15; j++)
+ {
+ if ((r1[j] & 0x3FF) <= r8->tileDataStartOffset + 1)
+ r2[j] = r8->tileDataStartOffset + 1;
+ else
+ r2[j] = r1[j] + 0x3C;
+ }
+
+ r1 += 32;
+ r2 += 32;
+ }
+
+ {
+ register u8 *r1 asm("r1") = r10 + 0x960;
+ register u8 *r2 asm("r2") = r1;
+
+ r1 += 0x780;
+ for (i = 0; i < 14; i++)
+ {
+ DmaCopy16(3, r1, r2, 0x1E0);
+ r1 += 0x3C0;
+ r2 += 0x3C0;
+ }
+ }
+}
+#else
+__attribute__((naked))
+void sub_80B403C(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\
+ sub sp, 0x4\n\
+ ldr r0, _080B40D8 @ =gMenuWindow\n\
+ mov r8, r0\n\
+ ldr r2, [r0, 0x28]\n\
+ adds r1, r2, 0\n\
+ adds r1, 0x9E\n\
+ adds r2, r1, 0\n\
+ adds r1, 0x80\n\
+ ldr r3, [r0, 0x24]\n\
+ mov r10, r3\n\
+ ldr r7, _080B40DC @ =0x000003ff\n\
+ mov r9, r7\n\
+ movs r6, 0xD\n\
+_080B4060:\n\
+ adds r0, r2, 0\n\
+ adds r0, 0x40\n\
+ str r0, [sp]\n\
+ movs r3, 0x40\n\
+ adds r3, r1\n\
+ mov r12, r3\n\
+ adds r3, r2, 0\n\
+ adds r4, r1, 0\n\
+ movs r5, 0xE\n\
+_080B4072:\n\
+ ldrh r2, [r4]\n\
+ mov r1, r9\n\
+ ands r1, r2\n\
+ mov r7, r8\n\
+ ldrh r0, [r7, 0x1A]\n\
+ adds r0, 0x1\n\
+ cmp r1, r0\n\
+ ble _080B4086\n\
+ adds r0, r2, 0\n\
+ subs r0, 0x3C\n\
+_080B4086:\n\
+ strh r0, [r3]\n\
+ adds r3, 0x2\n\
+ adds r4, 0x2\n\
+ subs r5, 0x1\n\
+ cmp r5, 0\n\
+ bge _080B4072\n\
+ ldr r2, [sp]\n\
+ mov r1, r12\n\
+ subs r6, 0x1\n\
+ cmp r6, 0\n\
+ bge _080B4060\n\
+ movs r1, 0x96\n\
+ lsls r1, 4\n\
+ add r1, r10\n\
+ adds r2, r1, 0\n\
+ movs r0, 0xF0\n\
+ lsls r0, 3\n\
+ adds r1, r0\n\
+ ldr r3, _080B40E0 @ =0x040000d4\n\
+ ldr r5, _080B40E4 @ =0x800000f0\n\
+ movs r4, 0xF0\n\
+ lsls r4, 2\n\
+ movs r6, 0xD\n\
+_080B40B4:\n\
+ str r1, [r3]\n\
+ str r2, [r3, 0x4]\n\
+ str r5, [r3, 0x8]\n\
+ ldr r0, [r3, 0x8]\n\
+ adds r2, r4\n\
+ adds r1, r4\n\
+ subs r6, 0x1\n\
+ cmp r6, 0\n\
+ bge _080B40B4\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\
+ .align 2, 0\n\
+_080B40D8: .4byte gMenuWindow\n\
+_080B40DC: .4byte 0x000003ff\n\
+_080B40E0: .4byte 0x040000d4\n\
+_080B40E4: .4byte 0x800000f0\n\
+ .syntax divided");
+}
+#endif
+
+void sub_80B40E8(u8 taskId) // Mart_DoCursorAction
+{
+ if (!gPaletteFade.active)
+ {
+ if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_UP) // only up can be pressed
+ {
+ if (gMartInfo.cursor == 0)
+ {
+ if (gMartInfo.choicesAbove == 0) // if there are no choices above, dont bother
+ return;
+
+ PlaySE(SE_SELECT);
+ gMartInfo.choicesAbove--; // since cursor is at the top and there are choices above the top, scroll the menu up by updating choicesAbove.
+ sub_80B3F88();
+ sub_80B39D0(0, 0, 0);
+ sub_80B3A70();
+ sub_80B32A4();
+ }
+ else // if the cursor is not 0, choicesAbove cannot be updated yet since the cursor is at the top of the menu, so update cursor.
+ {
+ PlaySE(SE_SELECT);
+ gMartInfo.cursor = MoveMenuCursor(-1); // move cursor up
+ sub_80B3A70();
+ }
+ }
+ else if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_DOWN) // only down can be pressed
+ {
+ if (gMartInfo.cursor == 7) // are you at the bottom of the menu?
+ {
+ if (gMartInfo.choicesAbove + gMartInfo.cursor == gMartInfo.itemCount) // are you at cancel?
+ return;
+
+ PlaySE(SE_SELECT);
+ gMartInfo.choicesAbove++;
+ sub_80B403C();
+ sub_80B39D0(7, 7, 0);
+ sub_80B3A70();
+ sub_80B32A4();
+ }
+ else if (gMartInfo.cursor != gMartInfo.itemCount)
+ {
+ PlaySE(SE_SELECT);
+ gMartInfo.cursor = MoveMenuCursor(1);
+ sub_80B3A70();
+ }
+ }
+ else if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+
+ if (gMartInfo.choicesAbove + gMartInfo.cursor != gMartInfo.itemCount) // did you not hit CANCEL?
+ {
+ PauseVerticalScrollIndicator(0);
+ PauseVerticalScrollIndicator(1);
+ sub_80F979C(1, 1);
+ sub_80B39D0(gMartInfo.cursor, gMartInfo.cursor, 1);
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(0, 0xC, 0xD, 0x13);
+
+ if (gMartInfo.martType == MART_TYPE_0)
+ {
+ gMartTotalCost = (ItemId_GetPrice(gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor]) >> GetPriceReduction(1)); // set 1x price
+ if (!IsEnoughMoney(gSaveBlock1.money, gMartTotalCost))
+ {
+ DisplayItemMessageOnField(taskId, gOtherText_NotEnoughMoney, sub_80B3BD0, 0xC3E1); // tail merge
+ }
+ else // _080B42BA
+ {
+ CopyItemName(gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor], gStringVar1);
+ StringExpandPlaceholders(gStringVar4, gOtherText_HowManyYouWant);
+ DisplayItemMessageOnField(taskId, gStringVar4, sub_80B3EFC, 0xC3E1);
+ }
+ }
+ else // _080B428C
+ {
+ gMartTotalCost = gDecorations[gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor]].price;
+
+ if (!IsEnoughMoney(gSaveBlock1.money, gMartTotalCost))
+ {
+ DisplayItemMessageOnField(taskId, gOtherText_NotEnoughMoney, sub_80B3BD0, 0xC3E1); // tail merge
+ }
+ else
+ {
+ StringCopy(gStringVar1, gDecorations[gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor]].name);
+ ConvertIntToDecimalStringN(gStringVar2, gMartTotalCost, 0, 0x8);
+
+ if (gMartInfo.martType == MART_TYPE_1)
+ {
+ StringExpandPlaceholders(gStringVar4, gOtherText_ThatWillBe2);
+ }
+ else
+ {
+ StringExpandPlaceholders(gStringVar4, gOtherText_ThatWillBe3);
+ }
+ DisplayItemMessageOnField(taskId, gStringVar4, sub_80B3D38, 0xC3E1);
+ }
+ }
+ }
+ else
+ sub_80B43F0(taskId);
+ }
+ else if (gMain.newKeys & B_BUTTON) // go back to buy/sell/exit menu
+ {
+ PlaySE(SE_SELECT);
+ sub_80B43F0(taskId);
+ }
+ }
+}
+
+void sub_80B4378(u8 taskId)
+{
+ MenuZeroFillWindowRect(0, 0xE, 0x1D, 0x13);
+ MenuZeroFillWindowRect(0, 0xA, 0xD, 0xD);
+ sub_80A3FA0(gBGTilemapBuffers[1], 0x1, 0xB, 0xC, 0x2, 0);
+ sub_80B3420();
+ sub_80B3764(6, 7);
+ sub_80B37EC();
+ StartVerticalScrollIndicators(0);
+ StartVerticalScrollIndicators(1);
+ sub_80B32A4();
+ gTasks[taskId].func = sub_80B40E8;
+}
+
+void sub_80B43F0(u8 taskId)
+{
+ gFieldCallback = sub_80B3050;
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ gTasks[taskId].func = Task_ExitBuyMenu;
+}
+
+void Task_ExitBuyMenu(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ CloseMoneyWindow(0, 0);
+ BuyMenuFreeMemory();
+ SetMainCallback2(c2_exit_to_overworld_2_switch);
+ DestroyTask(taskId);
+ }
+}
+
+void sub_80B4470(u8 taskId)
+{
+ u16 i;
+
+ for (i = 0; i < 3; i++)
+ {
+ if (gUnknown_02038724[i].itemId == gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor]
+ && gUnknown_02038724[i].quantity != 0)
+ {
+ if (gUnknown_02038724[i].quantity + gTasks[taskId].data[1] > 255)
+ gUnknown_02038724[i].quantity = 255;
+ else
+ gUnknown_02038724[i].quantity += gTasks[taskId].data[1];
+ return;
+ }
+ }
+
+ if (gUnknown_02038730 < 3)
+ {
+ gUnknown_02038724[gUnknown_02038730].itemId = gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor];
+ gUnknown_02038724[gUnknown_02038730].quantity = gTasks[taskId].data[1];
+ gUnknown_02038730++;
+ }
+}
+
+void ClearItemPurchases(void)
+{
+ gUnknown_02038730 = 0;
+ ClearItemSlots(gUnknown_02038724, 3);
+}
+
+void CreatePokemartMenu(u16 *itemList)
+{
+ CreateShopMenu(MART_TYPE_0);
+ SetShopItemsForSale(itemList);
+ ClearItemPurchases();
+ SetShopMenuCallback(EnableBothScriptContexts);
+}
+
+void CreateDecorationShop1Menu(u16 *itemList)
+{
+ CreateShopMenu(MART_TYPE_1);
+ SetShopItemsForSale(itemList);
+ SetShopMenuCallback(EnableBothScriptContexts);
+}
+
+void CreateDecorationShop2Menu(u16 *itemList)
+{
+ CreateShopMenu(MART_TYPE_2);
+ SetShopItemsForSale(itemList);
+ SetShopMenuCallback(EnableBothScriptContexts);
+}
+
+void sub_80B45B4(u8 taskId, const s16 *list, u16 c)
+{
+ s16 r5 = gTasks[taskId].data[4] - 1;
+ s16 r3 = gTasks[taskId].data[5] - 1;
+ s16 r4 = gTasks[taskId].data[1];
+ s16 y;
+ s16 x;
+
+ if (gTasks[taskId].data[2] == 0)
+ {
+ for (y = 0; y < 3; y++)
+ {
+ for (x = 0; x < 3; x++)
+ {
+ s16 metatileId = MapGridGetMetatileIdAt(r5 + x, r3 + y);
+
+ if (list[r4] == metatileId)
+ {
+ if (r4 != 2)
+ MapGridSetMetatileIdAt(r5 + x, r3 + y, c | list[r4 + 1]);
+ else
+ MapGridSetMetatileIdAt(r5 + x, r3 + y, c | list[0]);
+ }
+ }
+ }
+ }
+ else
+ {
+ for (y = 0; y < 3; y++)
+ {
+ for (x = 0; x < 3; x++)
+ {
+ s16 metatileId = MapGridGetMetatileIdAt(r5 + x, r3 + y);
+
+ if (list[2 - r4] == metatileId)
+ {
+ if (r4 != 2)
+ MapGridSetMetatileIdAt(r5 + x, r3 + y, c | list[1 - r4]);
+ else
+ MapGridSetMetatileIdAt(r5 + x, r3 + y, c | list[2]);
+ }
+ }
+ }
+ }
+}
+
+static const u16 gUnknown_083CC714[] = {0x284, 0x282, 0x280};
+static const u16 gUnknown_083CC71A[] = {0x285, 0x283, 0x281};
+static const u16 gUnknown_083CC720[] = {0x28C, 0x28A, 0x288};
+static const u16 gUnknown_083CC726[] = {0x28D, 0x28B, 0x289};
+static const u16 gUnknown_083CC72C[] = {0x2A0, 0x2A2, 0x2A4};
+static const u16 gUnknown_083CC732[] = {0x2A1, 0x2A3, 0x2A5};
+static const u16 gUnknown_083CC738[] = {0x2A8, 0x2AA, 0x2AC};
+
+void sub_80B4710(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ data[3] = 1;
+
+ switch (data[0])
+ {
+ case 0:
+ sub_80B45B4(taskId, gUnknown_083CC714, 0);
+ break;
+ case 1:
+ sub_80B45B4(taskId, gUnknown_083CC71A, 0);
+ break;
+ case 2:
+ sub_80B45B4(taskId, gUnknown_083CC720, 0xC00);
+ break;
+ case 3:
+ sub_80B45B4(taskId, gUnknown_083CC726, 0);
+ break;
+ case 4:
+ sub_80B45B4(taskId, gUnknown_083CC72C, 0xC00);
+ break;
+ case 5:
+ sub_80B45B4(taskId, gUnknown_083CC732, 0);
+ break;
+ case 6:
+ sub_80B45B4(taskId, gUnknown_083CC738, 0);
+ break;
+ }
+
+ data[0] = (data[0] + 1) & 7;
+ if (!data[0])
+ {
+ DrawWholeMapView();
+ data[1] = (data[1] + 1) % 3;
+ data[3] = 0;
+ }
+}
+
+u8 sub_80B47D8(u16 var)
+{
+ u8 taskId = CreateTask(sub_80B4710, 0);
+ s16 *data = gTasks[taskId].data;
+
+ PlayerGetDestCoords(&data[4], &data[5]);
+ data[0] = 0;
+ data[1] = 0;
+ data[2] = var;
+ sub_80B4710(taskId);
+ return taskId;
+}
+
+void sub_80B4824(u8 var)
+{
+ gUnknown_02038731 = sub_80B47D8(var);
+}
+
+void sub_80B483C(void)
+{
+ DestroyTask(gUnknown_02038731);
+}
+
+bool8 sub_80B4850(void)
+{
+ if (gTasks[gUnknown_02038731].data[3] == 0 && gTasks[gUnknown_02038731].data[1] == 2)
+ return FALSE;
+ else
+ return TRUE;
+}
diff --git a/src/field/slot_machine.c b/src/field/slot_machine.c
new file mode 100644
index 000000000..e8e4f271b
--- /dev/null
+++ b/src/field/slot_machine.c
@@ -0,0 +1,150 @@
+#include "global.h"
+#include "slot_machine.h"
+#include "decompress.h"
+#include "palette.h"
+#include "task.h"
+
+struct UnkStruct2000000 {
+ /*0x00*/ u8 filler00[61];
+ /*0x3D*/ u8 unk3D;
+};
+
+struct UnkStruct1 {
+ /*0x00*/ u8 unk00;
+ /*0x01*/ u8 unk01;
+ /*0x02*/ s16 unk02;
+};
+
+extern struct UnkStruct2000000 unk_2000000;
+
+extern struct UnkStruct1 *gUnknown_083ED048[];
+extern const u16 gPalette_83EDE24[];
+
+extern const u8 gSlotMachine_Gfx[];
+#if ENGLISH
+#define SLOTMACHINE_GFX_TILES 233
+#elif GERMAN
+#define SLOTMACHINE_GFX_TILES 236
+#endif
+
+extern const u16 gUnknown_08E95A18[];
+
+extern u16 gUnknown_08E95AB8[];
+extern u16 gUnknown_08E95FB8[];
+
+static void LoadSlotMachineWheelOverlay(void);
+
+void sub_8104CAC(u8 arg0) {
+ u8 i;
+ struct Task *task;
+
+ sub_8104DA4();
+
+ task = &gTasks[unk_2000000.unk3D];
+ task->data[1] = arg0;
+
+ i = 0;
+ while (gUnknown_083ED048[arg0][i].unk00 != 0xFF)
+ {
+ u8 spriteId;
+ spriteId = sub_8105BB4(
+ gUnknown_083ED048[arg0][i].unk00,
+ gUnknown_083ED048[arg0][i].unk01,
+ gUnknown_083ED048[arg0][i].unk02
+ );
+ task->data[4 + i] = spriteId;
+
+#ifdef GERMAN
+ if (arg0 == 5 && i <= 2)
+ {
+ gSprites[spriteId].invisible = TRUE;
+ }
+#endif
+
+ i += 1;
+ }
+}
+
+asm(".section .text_b");
+
+void sub_8106448(void) {
+ u32 offsetRead, offsetWrite;
+ u32 size;
+
+ LZDecompressWram(gSlotMachine_Gfx, (void *) 0x02010000);
+
+ offsetRead = 0x02010000;
+ offsetWrite = BG_VRAM;
+ size = SLOTMACHINE_GFX_TILES * 32;
+ while (TRUE)
+ {
+ DmaCopy16(3, offsetRead, (void *) (offsetWrite), 0x1000);
+ offsetRead += 0x1000;
+ offsetWrite += 0x1000;
+ size -= 0x1000;
+ if (size <= 0x1000)
+ {
+ DmaCopy16(3, offsetRead, (void *) (offsetWrite), size);
+ break;
+ }
+ }
+
+ LoadPalette(gUnknown_08E95A18, 0, 160);
+ LoadPalette(gPalette_83EDE24, 208, 32);
+}
+
+void sub_81064B8(void) {
+ CpuCopy16(gUnknown_08E95AB8, (void *) BG_SCREEN_ADDR(29), 20 * 32 * 2);
+ LoadSlotMachineWheelOverlay();
+}
+
+static void LoadSlotMachineWheelOverlay(void) {
+ s16 x, y, dx;
+ u16 *screen;
+
+ screen = (u16 *) BG_SCREEN_ADDR(30);
+
+ for (x = 4; x < 18; x += 5)
+ {
+ for (dx = 0; dx < 4; dx++)
+ {
+ screen[5 * 32 + dx + x] = 0x2051;
+ screen[13 * 32 + dx + x] = 0x2851;
+ screen[6 * 32 + dx + x] = 0x2061;
+ screen[12 * 32 + dx + x] = 0x2861;
+ }
+
+ screen[6 * 32 + x] = 0x20BE;
+ screen[12 * 32 + x] = 0x28BE;
+
+ for (y = 7; y <= 11; y++)
+ {
+ screen[y * 32 + x] = 0x20BF;
+ }
+ }
+}
+
+void sub_81065A8(s16 arg0, u16 arg1, u16 arg2, u16 arg3, u16 arg4) {
+ u16 *vram = (u16 *) BG_SCREEN_ADDR(29);
+
+ vram[15 * 32 + arg0] = arg1;
+ vram[15 * 32 + 1 + arg0] = arg2;
+ vram[16 * 32 + arg0] = arg3;
+ vram[16 * 32 + 1 + arg0] = arg4;
+}
+
+void sub_81065DC(void) {
+ s16 y, x;
+ u16 *screen;
+
+ CpuCopy16(gUnknown_08E95FB8, (void *) BG_SCREEN_ADDR(29), 20 * 32 * 2);
+
+ screen = (u16 *) BG_SCREEN_ADDR(30);
+ for (y = 0; y < 20; y++)
+ {
+ for (x = 0; x < 30; x++)
+ {
+ screen[x + y * 32] = 0;
+ }
+ }
+}
diff --git a/src/field/start_menu.c b/src/field/start_menu.c
new file mode 100644
index 000000000..6e44090df
--- /dev/null
+++ b/src/field/start_menu.c
@@ -0,0 +1,850 @@
+#include "global.h"
+#include "start_menu.h"
+#include "event_data.h"
+#include "field_map_obj_helpers.h"
+#include "field_player_avatar.h"
+#include "field_weather.h"
+#include "fieldmap.h"
+#include "item_menu.h"
+#include "load_save.h"
+#include "main.h"
+#include "map_obj_lock.h"
+#include "menu.h"
+#include "option_menu.h"
+#include "palette.h"
+#include "pokedex.h"
+#include "pokemon_menu.h"
+#include "pokenav.h"
+#include "overworld.h"
+#include "safari_zone.h"
+#include "save.h"
+#include "save_menu_util.h"
+#include "script.h"
+#include "songs.h"
+#include "sound.h"
+#include "sprite.h"
+#include "string_util.h"
+#include "strings.h"
+#include "strings2.h"
+#include "task.h"
+#include "trainer_card.h"
+#include "unknown_task.h"
+
+//Menu actions
+enum {
+ MENU_ACTION_POKEDEX,
+ MENU_ACTION_POKEMON,
+ MENU_ACTION_BAG,
+ MENU_ACTION_POKENAV,
+ MENU_ACTION_PLAYER,
+ MENU_ACTION_SAVE,
+ MENU_ACTION_OPTION,
+ MENU_ACTION_EXIT,
+ MENU_ACTION_RETIRE,
+ MENU_ACTION_PLAYER_LINK
+};
+
+static u8 (*saveDialogCallback)(void);
+static u8 saveDialogTimer; //Number of frames to keep the window on screen after save was completed
+static bool8 savingComplete;
+
+extern bool8 gDifferentSaveFile;
+extern u16 gSaveFileStatus;
+extern u16 gScriptResult;
+
+extern u8 gUnknown_03004860;
+
+u8 (*gCallback_03004AE8)(void);
+
+EWRAM_DATA static u8 sStartMenuCursorPos = 0;
+EWRAM_DATA static u8 sNumStartMenuActions = 0;
+EWRAM_DATA static u8 sCurrentStartMenuActions[10] = {0};
+
+//Text strings
+extern u8 gSaveText_PlayerSavedTheGame[];
+extern u8 gSaveText_DontTurnOff[];
+extern u8 gSaveText_ThereIsAlreadyAFile[];
+extern u8 gSaveText_ThereIsADifferentFile[];
+extern u8 gSaveText_WouldYouLikeToSave[];
+
+static u8 StartMenu_PokedexCallback(void);
+static u8 StartMenu_PokemonCallback(void);
+static u8 StartMenu_BagCallback(void);
+static u8 StartMenu_PokenavCallback(void);
+static u8 StartMenu_PlayerCallback(void);
+static u8 StartMenu_SaveCallback(void);
+static u8 StartMenu_OptionCallback(void);
+static u8 StartMenu_ExitCallback(void);
+static u8 StartMenu_RetireCallback(void);
+static u8 StartMenu_PlayerLinkCallback(void);
+
+static const struct MenuAction sStartMenuItems[] =
+{
+ { SystemText_Pokedex, StartMenu_PokedexCallback },
+ { SystemText_Pokemon, StartMenu_PokemonCallback },
+ { SystemText_BAG, StartMenu_BagCallback },
+ { SystemText_Pokenav, StartMenu_PokenavCallback },
+ { SystemText_Player, StartMenu_PlayerCallback },
+ { SystemText_Save, StartMenu_SaveCallback },
+ { SystemText_Option, StartMenu_OptionCallback },
+ { SystemText_Exit, StartMenu_ExitCallback },
+ { SystemText_Retire, StartMenu_RetireCallback },
+ { SystemText_Player, StartMenu_PlayerLinkCallback },
+};
+
+//Private functions
+static void BuildStartMenuActions(void);
+static void AddStartMenuAction(u8 action);
+static void BuildStartMenuActions_Normal(void);
+static void BuildStartMenuActions_SafariZone(void);
+static void BuildStartMenuActions_Link(void);
+static void DisplaySafariBallsWindow(void);
+static bool32 PrintStartMenuItemsMultistep(s16 *a, u32 b);
+static bool32 InitStartMenuMultistep(s16 *a, s16 *b);
+static void Task_StartMenu(u8 taskId);
+static u8 StartMenu_InputProcessCallback(void);
+static u8 SaveCallback1(void);
+static u8 SaveCallback2(void);
+static void sub_807160C(void);
+static u8 RunSaveDialogCallback(void);
+static void DisplaySaveMessageWithCallback(const u8 *ptr, u8 (*func)(void));
+static void Task_SaveDialog(u8 taskId);
+static void sub_8071700(void);
+static void HideSaveDialog(void);
+static void SaveDialogStartTimeout(void);
+static u8 SaveDialogCheckForTimeoutOrKeypress(void);
+static u8 SaveDialogCheckForTimeoutAndKeypress(void);
+static u8 SaveDialogCheckForTimeoutAndKeypress(void);
+static u8 SaveDialogCB_DisplayConfirmMessage(void);
+static u8 SaveDialogCB_DisplayConfirmYesNoMenu(void);
+static u8 SaveDialogCB_ProcessConfirmYesNoMenu(void);
+static u8 SaveDialogCB_SaveFileExists(void);
+static u8 SaveDialogCB_DisplayOverwriteYesNoMenu(void);
+static u8 SaveDialogCB_ProcessOverwriteYesNoMenu(void);
+static u8 SaveDialogCB_DisplaySavingMessage(void);
+static u8 SaveDialogCB_DoSave(void);
+static u8 SaveDialogCB_SaveSuccess(void);
+static u8 SaveDialogCB_ReturnSuccess(void);
+static u8 SaveDialogCB_SaveError(void);
+static u8 SaveDialogCB_ReturnError(void);
+static void sub_80719F0(void);
+static bool32 sub_80719FC(u8 *ptr);
+static void sub_8071B54(void);
+static void Task_8071B64(u8 taskId);
+
+
+static void BuildStartMenuActions(void)
+{
+ sNumStartMenuActions = 0;
+ if (is_c1_link_related_active() == TRUE)
+ BuildStartMenuActions_Link();
+ else
+ {
+ if (GetSafariZoneFlag() == TRUE)
+ BuildStartMenuActions_SafariZone();
+ else
+ BuildStartMenuActions_Normal();
+ }
+}
+
+static void AddStartMenuAction(u8 action)
+{
+ AppendToList(sCurrentStartMenuActions, &sNumStartMenuActions, action);
+}
+
+static void BuildStartMenuActions_Normal(void)
+{
+ if (FlagGet(SYS_POKEDEX_GET) == TRUE)
+ AddStartMenuAction(MENU_ACTION_POKEDEX);
+ if (FlagGet(SYS_POKEMON_GET) == TRUE)
+ AddStartMenuAction(MENU_ACTION_POKEMON);
+ AddStartMenuAction(MENU_ACTION_BAG);
+ if (FlagGet(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)
+{
+ AddStartMenuAction(MENU_ACTION_RETIRE);
+ AddStartMenuAction(MENU_ACTION_POKEDEX);
+ AddStartMenuAction(MENU_ACTION_POKEMON);
+ AddStartMenuAction(MENU_ACTION_BAG);
+ AddStartMenuAction(MENU_ACTION_PLAYER);
+ AddStartMenuAction(MENU_ACTION_OPTION);
+ AddStartMenuAction(MENU_ACTION_EXIT);
+}
+
+static void BuildStartMenuActions_Link(void)
+{
+ AddStartMenuAction(MENU_ACTION_POKEMON);
+ AddStartMenuAction(MENU_ACTION_BAG);
+ if (FlagGet(SYS_POKENAV_GET) == TRUE)
+ AddStartMenuAction(MENU_ACTION_POKENAV);
+ AddStartMenuAction(MENU_ACTION_PLAYER_LINK);
+ AddStartMenuAction(MENU_ACTION_OPTION);
+ AddStartMenuAction(MENU_ACTION_EXIT);
+}
+
+//Show number of safari balls left
+static void DisplaySafariBallsWindow(void)
+{
+ sub_8072C44(gStringVar1, gNumSafariBalls, 12, 1);
+ MenuDrawTextWindow(0, 0, 10, 5);
+ MenuPrint(gOtherText_SafariStock, 1, 1);
+}
+
+//Prints n menu items starting at *index
+static bool32 PrintStartMenuItemsMultistep(s16 *index, u32 n)
+{
+ int _index = *index;
+
+ do
+ {
+ MenuPrint(sStartMenuItems[sCurrentStartMenuActions[_index]].text, 23, 2 + _index * 2);
+ _index++;
+ if (_index >= sNumStartMenuActions)
+ {
+ *index = _index;
+ return TRUE;
+ }
+ }
+ while (--n != 0);
+ *index = _index;
+ return FALSE;
+}
+
+static bool32 InitStartMenuMultistep(s16 *step, s16 *index)
+{
+ switch (*step)
+ {
+ case 1:
+ BuildStartMenuActions();
+ (*step)++;
+ break;
+ case 2:
+ MenuDrawTextWindow(22, 0, 29, sNumStartMenuActions * 2 + 3);
+ *index = 0;
+ (*step)++;
+ break;
+ case 3:
+ if (GetSafariZoneFlag())
+ DisplaySafariBallsWindow();
+ (*step)++;
+ break;
+ case 4:
+ if (PrintStartMenuItemsMultistep(index, 2))
+ (*step)++;
+ break;
+ case 0:
+ (*step)++;
+ break;
+ case 5:
+ sStartMenuCursorPos = InitMenu(0, 0x17, 2, sNumStartMenuActions, sStartMenuCursorPos, 6);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void InitStartMenu(void)
+{
+ s16 step = 0;
+ s16 index = 0;
+
+ while (InitStartMenuMultistep(&step, &index) == FALSE)
+ ;
+}
+
+static void Task_StartMenu(u8 taskId)
+{
+ if (InitStartMenuMultistep(gTasks[taskId].data, gTasks[taskId].data + 1) == TRUE)
+ {
+ *gTasks[taskId].data = 0;
+ SwitchTaskToFollowupFunc(taskId);
+ }
+}
+
+void CreateStartMenuTask(void (*func)(u8))
+{
+ u8 taskId;
+
+ InitMenuWindow(&gWindowConfig_81E6CE4);
+ taskId = CreateTask(Task_StartMenu, 0x50);
+ SetTaskFuncWithFollowupFunc(taskId, Task_StartMenu, func);
+}
+
+void sub_80712B4(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ gCallback_03004AE8 = StartMenu_InputProcessCallback;
+ task->data[0]++;
+ break;
+ case 1:
+ if (gCallback_03004AE8() == 1)
+ DestroyTask(taskId);
+ break;
+ }
+}
+
+void sub_8071310(void)
+{
+ if (!is_c1_link_related_active())
+ {
+ FreezeMapObjects();
+ sub_80594C0();
+ sub_80597F4();
+ }
+ CreateStartMenuTask(sub_80712B4);
+ ScriptContext2_Enable();
+}
+
+static u8 StartMenu_InputProcessCallback(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 == StartMenu_PokedexCallback)
+ {
+ if (GetNationalPokedexCount(0) == 0)
+ return 0;
+ }
+ gCallback_03004AE8 = sStartMenuItems[sCurrentStartMenuActions[sStartMenuCursorPos]].func;
+ if (gCallback_03004AE8 != StartMenu_SaveCallback &&
+ gCallback_03004AE8 != StartMenu_ExitCallback &&
+ gCallback_03004AE8 != StartMenu_RetireCallback)
+ fade_screen(1, 0);
+ return 0;
+ }
+ if (gMain.newKeys & (START_BUTTON | B_BUTTON))
+ {
+ CloseMenu();
+ return 1;
+ }
+ return 0;
+}
+
+//When player selects POKEDEX
+static u8 StartMenu_PokedexCallback(void)
+{
+ if (!gPaletteFade.active)
+ {
+ IncrementGameStat(0x29);
+ PlayRainSoundEffect();
+ SetMainCallback2(CB2_InitPokedex);
+ return 1;
+ }
+ return 0;
+}
+
+//When player selects POKEMON
+static u8 StartMenu_PokemonCallback(void)
+{
+ if (!gPaletteFade.active)
+ {
+ PlayRainSoundEffect();
+ SetMainCallback2(sub_8089A70);
+ return 1;
+ }
+ return 0;
+}
+
+//When player selects BAG
+static u8 StartMenu_BagCallback(void)
+{
+ if (!gPaletteFade.active)
+ {
+ PlayRainSoundEffect();
+ SetMainCallback2(sub_80A53F8);
+ return 1;
+ }
+ return 0;
+}
+
+//When player selects POKENAV
+static u8 StartMenu_PokenavCallback(void)
+{
+ if (!gPaletteFade.active)
+ {
+ PlayRainSoundEffect();
+ SetMainCallback2(sub_80EBA5C);
+ return 1;
+ }
+ return 0;
+}
+
+//When player selects his/her name
+static u8 StartMenu_PlayerCallback(void)
+{
+ if (!gPaletteFade.active)
+ {
+ PlayRainSoundEffect();
+ sub_8093110(sub_805469C);
+ return 1;
+ }
+ return 0;
+}
+
+//When player selects SAVE
+static u8 StartMenu_SaveCallback(void)
+{
+ HandleDestroyMenuCursors();
+ gCallback_03004AE8 = SaveCallback1;
+ return 0;
+}
+
+//When player selects OPTION
+static u8 StartMenu_OptionCallback(void)
+{
+ if (!gPaletteFade.active)
+ {
+ PlayRainSoundEffect();
+ SetMainCallback2(CB2_InitOptionMenu);
+ gMain.savedCallback = sub_805469C;
+ return 1;
+ }
+ return 0;
+}
+
+//When player selects EXIT
+static u8 StartMenu_ExitCallback(void)
+{
+ CloseMenu();
+ return 1;
+}
+
+//When player selects RETIRE
+static u8 StartMenu_RetireCallback(void)
+{
+ CloseMenu();
+ SafariZoneRetirePrompt();
+ return 1;
+}
+
+//When player selects their name in multiplayer mode
+static u8 StartMenu_PlayerLinkCallback(void)
+{
+ if (!gPaletteFade.active)
+ {
+ PlayRainSoundEffect();
+ sub_8093130(gUnknown_03004860, sub_805469C);
+ return 1;
+ }
+ return 0;
+}
+
+//Save dialog status
+enum
+{
+ SAVE_IN_PROGRESS,
+ SAVE_SUCCESS,
+ SAVE_CANCELED,
+ SAVE_ERROR,
+};
+
+static u8 SaveCallback1(void)
+{
+ sub_807160C();
+ gCallback_03004AE8 = SaveCallback2;
+ return FALSE;
+}
+
+static u8 SaveCallback2(void)
+{
+ switch (RunSaveDialogCallback())
+ {
+ case SAVE_IN_PROGRESS:
+ return FALSE;
+ case SAVE_CANCELED:
+ //Go back to start menu
+ MenuZeroFillScreen();
+ InitStartMenu();
+ gCallback_03004AE8 = StartMenu_InputProcessCallback;
+ return FALSE;
+ case SAVE_SUCCESS:
+ case SAVE_ERROR:
+ MenuZeroFillScreen();
+ sub_8064E2C();
+ ScriptContext2_Disable();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void sub_807160C(void)
+{
+ save_serialize_map();
+ saveDialogCallback = SaveDialogCB_DisplayConfirmMessage;
+ savingComplete = FALSE;
+}
+
+static u8 RunSaveDialogCallback(void)
+{
+ if (savingComplete)
+ {
+ if (!MenuUpdateWindowText())
+ return 0;
+ }
+ savingComplete = FALSE;
+ return saveDialogCallback();
+}
+
+void ScrSpecial_DoSaveDialog(void)
+{
+ sub_807160C();
+ CreateTask(Task_SaveDialog, 0x50);
+}
+
+static void DisplaySaveMessageWithCallback(const u8 *ptr, u8 (*func)(void))
+{
+ StringExpandPlaceholders(gStringVar4, ptr);
+ MenuDisplayMessageBox();
+ MenuPrintMessageDefaultCoords(gStringVar4);
+ savingComplete = TRUE;
+ saveDialogCallback = func;
+}
+
+static void Task_SaveDialog(u8 taskId)
+{
+ u8 status = RunSaveDialogCallback();
+
+ switch (status)
+ {
+ case SAVE_CANCELED:
+ case SAVE_ERROR:
+ gScriptResult = 0;
+ break;
+ case SAVE_SUCCESS:
+ gScriptResult = status;
+ break;
+ case SAVE_IN_PROGRESS:
+ return;
+ }
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+}
+
+static void sub_8071700(void)
+{
+ HandleCloseSaveWindow(0, 0);
+}
+
+static void HideSaveDialog(void)
+{
+ MenuZeroFillWindowRect(20, 8, 26, 13);
+}
+
+static void SaveDialogStartTimeout(void)
+{
+ saveDialogTimer = 60;
+}
+
+static bool8 SaveDialogCheckForTimeoutOrKeypress(void)
+{
+ saveDialogTimer--;
+ if (gMain.heldKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ return TRUE;
+ }
+ else if (saveDialogTimer == 0)
+ return TRUE;
+ return FALSE;
+}
+
+static bool8 SaveDialogCheckForTimeoutAndKeypress(void)
+{
+ if (saveDialogTimer != 0)
+ saveDialogTimer--;
+ else if (gMain.heldKeys & A_BUTTON)
+ return TRUE;
+ return FALSE;
+}
+
+static u8 SaveDialogCB_DisplayConfirmMessage(void)
+{
+ MenuZeroFillScreen();
+ HandleDrawSaveWindowInfo(0, 0);
+ DisplaySaveMessageWithCallback(gSaveText_WouldYouLikeToSave, SaveDialogCB_DisplayConfirmYesNoMenu);
+ return SAVE_IN_PROGRESS;
+}
+
+static u8 SaveDialogCB_DisplayConfirmYesNoMenu(void)
+{
+ DisplayYesNoMenu(20, 8, 1);
+ saveDialogCallback = SaveDialogCB_ProcessConfirmYesNoMenu;
+ return SAVE_IN_PROGRESS;
+}
+
+static u8 SaveDialogCB_ProcessConfirmYesNoMenu(void)
+{
+ switch (ProcessMenuInputNoWrap_())
+ {
+ case 0: //YES
+ HideSaveDialog();
+ switch (gSaveFileStatus)
+ {
+ case 0:
+ case 2:
+ if (gDifferentSaveFile == FALSE)
+ {
+ saveDialogCallback = SaveDialogCB_SaveFileExists;
+ return SAVE_IN_PROGRESS;
+ }
+ saveDialogCallback = SaveDialogCB_DisplaySavingMessage;
+ return SAVE_IN_PROGRESS;
+ default:
+ saveDialogCallback = SaveDialogCB_SaveFileExists;
+ return SAVE_IN_PROGRESS;
+ }
+ break;
+ case -1: //B button
+ case 1: //NO
+ HideSaveDialog();
+ sub_8071700();
+ return SAVE_CANCELED;
+ }
+ return SAVE_IN_PROGRESS;
+}
+
+static u8 SaveDialogCB_SaveFileExists(void)
+{
+ DisplaySaveMessageWithCallback(
+ gDifferentSaveFile == TRUE ? gSaveText_ThereIsADifferentFile : gSaveText_ThereIsAlreadyAFile,
+ SaveDialogCB_DisplayOverwriteYesNoMenu);
+ return SAVE_IN_PROGRESS;
+}
+
+static u8 SaveDialogCB_DisplayOverwriteYesNoMenu(void)
+{
+ DisplayYesNoMenu(20, 8, 1);
+ saveDialogCallback = SaveDialogCB_ProcessOverwriteYesNoMenu;
+ return SAVE_IN_PROGRESS;
+}
+
+static u8 SaveDialogCB_ProcessOverwriteYesNoMenu(void)
+{
+ switch (ProcessMenuInputNoWrap_())
+ {
+ case 0: //YES
+ HideSaveDialog();
+ saveDialogCallback = SaveDialogCB_DisplaySavingMessage;
+ break;
+ case -1: //B button
+ case 1: //NO
+ HideSaveDialog();
+ sub_8071700();
+ return SAVE_CANCELED;
+ }
+ return SAVE_IN_PROGRESS;
+}
+
+static u8 SaveDialogCB_DisplaySavingMessage(void)
+{
+ //"SAVING... DON'T TURN OFF THE POWER."
+ DisplaySaveMessageWithCallback(gSaveText_DontTurnOff, SaveDialogCB_DoSave);
+ return SAVE_IN_PROGRESS;
+}
+
+static u8 SaveDialogCB_DoSave(void)
+{
+ bool8 saveSucceeded;
+
+ IncrementGameStat(0);
+ if (gDifferentSaveFile == TRUE)
+ {
+ saveSucceeded = TrySavingData(DIFFERENT_FILE_SAVE);
+ gDifferentSaveFile = FALSE;
+ }
+ else
+ {
+ saveSucceeded = TrySavingData(NORMAL_SAVE);
+ }
+
+ if (saveSucceeded == TRUE)
+ {
+ //"(Player) saved the game."
+ DisplaySaveMessageWithCallback(gSaveText_PlayerSavedTheGame, SaveDialogCB_SaveSuccess);
+ }
+ else
+ {
+ //"Save error. Please exchange the backup memory."
+ DisplaySaveMessageWithCallback(gSystemText_SaveErrorExchangeBackup, SaveDialogCB_SaveError);
+ }
+
+ SaveDialogStartTimeout();
+ return SAVE_IN_PROGRESS;
+}
+
+static u8 SaveDialogCB_SaveSuccess(void)
+{
+ if (MenuUpdateWindowText())
+ {
+ PlaySE(SE_SAVE);
+ saveDialogCallback = SaveDialogCB_ReturnSuccess;
+ }
+ return SAVE_IN_PROGRESS;
+}
+
+static u8 SaveDialogCB_ReturnSuccess(void)
+{
+ if (!IsSEPlaying() && SaveDialogCheckForTimeoutOrKeypress())
+ {
+ sub_8071700();
+ return SAVE_SUCCESS;
+ }
+ else
+ return SAVE_IN_PROGRESS;
+}
+
+static u8 SaveDialogCB_SaveError(void)
+{
+ if (MenuUpdateWindowText())
+ {
+ PlaySE(SE_BOO);
+ saveDialogCallback = SaveDialogCB_ReturnError;
+ }
+ return SAVE_IN_PROGRESS;
+}
+
+static u8 SaveDialogCB_ReturnError(void)
+{
+ if (!SaveDialogCheckForTimeoutAndKeypress())
+ return SAVE_IN_PROGRESS;
+ else
+ {
+ sub_8071700();
+ return SAVE_ERROR;
+ }
+}
+
+static void sub_80719F0(void)
+{
+ TransferPlttBuffer();
+}
+
+static bool32 sub_80719FC(u8 *step)
+{
+ switch (*step)
+ {
+ case 0:
+ {
+ u8 *addr;
+ u32 size;
+
+ REG_DISPCNT = 0;
+ SetVBlankCallback(NULL);
+ remove_some_task();
+ DmaClear16(3, PLTT, PLTT_SIZE);
+ addr = (void *)VRAM;
+ size = 0x18000;
+ while (1)
+ {
+ DmaFill16(3, 0, addr, 0x1000);
+ addr += 0x1000;
+ size -= 0x1000;
+ if (size <= 0x1000)
+ {
+ DmaFill16(3, 0, addr, size);
+ break;
+ }
+ }
+ break;
+ }
+ case 1:
+ ResetSpriteData();
+ ResetTasks();
+ ResetPaletteFade();
+ dp12_8087EA4();
+ break;
+ case 2:
+ SetUpWindowConfig(&gWindowConfig_81E6CE4);
+ InitMenuWindow(&gWindowConfig_81E6CE4);
+ REG_DISPCNT = DISPCNT_MODE_0 | DISPCNT_BG0_ON;
+ break;
+ case 3:
+ {
+ u32 savedIme;
+
+ BlendPalettes(-1, 0x10, 0);
+ SetVBlankCallback(sub_80719F0);
+ savedIme = REG_IME;
+ REG_IME = 0;
+ REG_IE |= 1;
+ REG_IME = savedIme;
+ break;
+ }
+ case 4:
+ return TRUE;
+ }
+ (*step)++;
+ return FALSE;
+}
+
+void sub_8071B28(void)
+{
+ if (sub_80719FC(&gMain.state))
+ {
+ CreateTask(Task_8071B64, 0x50);
+ SetMainCallback2(sub_8071B54);
+ }
+}
+
+static void sub_8071B54(void)
+{
+ RunTasks();
+ UpdatePaletteFade();
+}
+
+static void Task_8071B64(u8 taskId)
+{
+ s16 *step = gTasks[taskId].data;
+
+ if (!gPaletteFade.active)
+ {
+ switch (*step)
+ {
+ case 0:
+ MenuDisplayMessageBox();
+ MenuPrint(gSystemText_Saving, 2, 15);
+ BeginNormalPaletteFade(-1, 0, 0x10, 0, 0);
+ (*step)++;
+ break;
+ case 1:
+ SetSecretBase2Field_9_AndHideBG();
+ sub_8125E2C();
+ (*step)++;
+ break;
+ case 2:
+ if (!sub_8125E6C())
+ break;
+ ClearSecretBase2Field_9_2();
+ (*step)++;
+ break;
+ case 3:
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ (*step)++;
+ break;
+ case 4:
+ SetMainCallback2(gMain.savedCallback);
+ DestroyTask(taskId);
+ break;
+ }
+ }
+}
diff --git a/src/field/starter_choose.c b/src/field/starter_choose.c
new file mode 100644
index 000000000..2b28df4f0
--- /dev/null
+++ b/src/field/starter_choose.c
@@ -0,0 +1,757 @@
+#include "global.h"
+#include "starter_choose.h"
+#include "data2.h"
+#include "decompress.h"
+#include "main.h"
+#include "menu.h"
+#include "palette.h"
+#include "pokedex.h"
+#include "songs.h"
+#include "sound.h"
+#include "species.h"
+#include "sprite.h"
+#include "string_util.h"
+#include "strings.h"
+#include "task.h"
+#include "trig.h"
+#include "unknown_task.h"
+
+extern u16 gScriptResult;
+extern struct SpriteTemplate gUnknown_02024E8C;
+
+//--------------------------------------------------
+// Graphics Data
+//--------------------------------------------------
+
+const u16 gBirchBagGrassPal[2][16] =
+{
+ INCBIN_U16("graphics/misc/birch_bag.gbapal"),
+ INCBIN_U16("graphics/misc/birch_grass.gbapal"),
+};
+static const u16 gBirchBallarrow_Pal[] = INCBIN_U16("graphics/misc/birch_ballarrow.gbapal");
+static const u16 gBirchCircle_Pal[] = INCBIN_U16("graphics/misc/birch_circle.gbapal");
+const u8 gBirchBagTilemap[] = INCBIN_U8("graphics/misc/birch_bag_map.bin.lz");
+const u8 gBirchGrassTilemap[] = INCBIN_U8("graphics/misc/birch_grass_map.bin.lz");
+const u8 gBirchHelpGfx[] = INCBIN_U8("graphics/misc/birch_help.4bpp.lz");
+static const u8 gBirchBallarrow_Gfx[] = INCBIN_U8("graphics/misc/birch_ballarrow.4bpp.lz");
+static const u8 gBirchCircle_Gfx[] = INCBIN_U8("graphics/misc/birch_circle.4bpp.lz");
+static const u8 gStarterChoose_PokeballCoords[][2] =
+{
+ {60, 64},
+ {120, 88},
+ {180, 64},
+};
+static const u8 gStarterChoose_LabelCoords[][2] =
+{
+ {0, 9},
+ {16, 10},
+ {8, 4},
+};
+static const u16 sStarterMons[] = {SPECIES_TREECKO, SPECIES_TORCHIC, SPECIES_MUDKIP};
+static const struct OamData gOamData_83F76CC =
+{
+ .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 struct OamData gOamData_83F76D4 =
+{
+ .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 struct OamData gOamData_83F76DC =
+{
+ .y = 160,
+ .affineMode = 3,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 3,
+ .tileNum = 0,
+ .priority = 1,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+static const u8 gUnknown_083F76E4[][2] =
+{
+ {60, 32},
+ {120, 56},
+ {180, 32},
+ {0, 0},
+};
+static const union AnimCmd gSpriteAnim_83F76EC[] =
+{
+ ANIMCMD_FRAME(48, 30),
+ ANIMCMD_END,
+};
+static const union AnimCmd gSpriteAnim_83F76F4[] =
+{
+ ANIMCMD_FRAME(0, 30),
+ ANIMCMD_END,
+};
+static const union AnimCmd gSpriteAnim_83F76FC[] =
+{
+ ANIMCMD_FRAME(16, 4),
+ ANIMCMD_FRAME(0, 4),
+ ANIMCMD_FRAME(32, 4),
+ ANIMCMD_FRAME(0, 4),
+ ANIMCMD_FRAME(16, 4),
+ ANIMCMD_FRAME(0, 4),
+ ANIMCMD_FRAME(32, 4),
+ ANIMCMD_FRAME(0, 4),
+ ANIMCMD_FRAME(0, 32),
+ ANIMCMD_FRAME(16, 8),
+ ANIMCMD_FRAME(0, 8),
+ ANIMCMD_FRAME(32, 8),
+ ANIMCMD_FRAME(0, 8),
+ ANIMCMD_FRAME(16, 8),
+ ANIMCMD_FRAME(0, 8),
+ ANIMCMD_FRAME(32, 8),
+ ANIMCMD_FRAME(0, 8),
+ ANIMCMD_JUMP(0),
+};
+static const union AnimCmd gSpriteAnim_83F7744[] =
+{
+ ANIMCMD_FRAME(0, 8),
+ ANIMCMD_END,
+};
+static const union AnimCmd *const gSpriteAnimTable_83F774C[] =
+{
+ gSpriteAnim_83F76EC,
+};
+static const union AnimCmd *const gSpriteAnimTable_83F7750[] =
+{
+ gSpriteAnim_83F76F4,
+ gSpriteAnim_83F76FC,
+};
+static const union AnimCmd *const gSpriteAnimTable_83F7758[] =
+{
+ gSpriteAnim_83F7744,
+};
+static const union AffineAnimCmd gSpriteAffineAnim_83F775C[] =
+{
+ AFFINEANIMCMD_FRAME(16, 16, 0, 0),
+ AFFINEANIMCMD_FRAME(16, 16, 0, 15),
+ AFFINEANIMCMD_END,
+};
+static const union AffineAnimCmd gSpriteAffineAnim_83F7774[] =
+{
+ AFFINEANIMCMD_FRAME(20, 20, 0, 0),
+ AFFINEANIMCMD_FRAME(20, 20, 0, 15),
+ AFFINEANIMCMD_END,
+};
+static const union AffineAnimCmd *const gSpriteAffineAnimTable_83F778C[] =
+{
+ gSpriteAffineAnim_83F775C,
+};
+static const union AffineAnimCmd *const gSpriteAffineAnimTable_83F7790[] =
+{
+ gSpriteAffineAnim_83F7774,
+};
+static const struct CompressedSpriteSheet gUnknown_083F7794[] =
+{
+ {gBirchBallarrow_Gfx, 0x0800, 0x1000},
+ {NULL},
+};
+static const struct CompressedSpriteSheet gUnknown_083F77A4[] =
+{
+ {gBirchCircle_Gfx, 0x0800, 0x1001},
+ {NULL},
+};
+const struct SpritePalette gUnknown_083F77B4[] =
+{
+ {gBirchBallarrow_Pal, 0x1000},
+ {gBirchCircle_Pal, 0x1001},
+ {NULL},
+};
+static void sub_810A62C(struct Sprite *sprite);
+static const struct SpriteTemplate gSpriteTemplate_83F77CC =
+{
+ .tileTag = 4096,
+ .paletteTag = 4096,
+ .oam = &gOamData_83F76CC,
+ .anims = gSpriteAnimTable_83F774C,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_810A62C,
+};
+static void sub_810A68C(struct Sprite *sprite);
+static const struct SpriteTemplate gSpriteTemplate_83F77E4 =
+{
+ .tileTag = 4096,
+ .paletteTag = 4096,
+ .oam = &gOamData_83F76D4,
+ .anims = gSpriteAnimTable_83F7750,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_810A68C,
+};
+static void StarterPokemonSpriteAnimCallback(struct Sprite *sprite);
+static const struct SpriteTemplate gSpriteTemplate_83F77FC =
+{
+ .tileTag = 4097,
+ .paletteTag = 4097,
+ .oam = &gOamData_83F76DC,
+ .anims = gSpriteAnimTable_83F7758,
+ .images = NULL,
+ .affineAnims = gSpriteAffineAnimTable_83F7790,
+ .callback = StarterPokemonSpriteAnimCallback,
+};
+
+static void MainCallback2(void);
+static void Task_StarterChoose1(u8 taskId);
+static void Task_StarterChoose2(u8 taskId);
+static void Task_StarterChoose3(u8 taskId);
+static void Task_StarterChoose4(u8 taskId);
+static void Task_StarterChoose5(u8 taskId);
+static void Task_StarterChoose6(u8 taskId);
+
+static void CreateStarterPokemonLabel(u8, u8);
+static u8 CreatePokemonFrontSprite(u16, u8, u8);
+
+//Position of the sprite of the selected starter Pokemon
+#define STARTER_PKMN_POS_X 120
+#define STARTER_PKMN_POS_Y 64
+
+//Retrieves one of the available starter Pokemon
+u16 GetStarterPokemon(u16 n)
+{
+ if (n > 3)
+ n = 0;
+ return sStarterMons[n];
+}
+
+static void VblankCallback(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+#define tStarterSelection data[0]
+#define tPkmnSpriteId data[1]
+#define tCircleSpriteId data[2]
+
+void CB2_ChooseStarter(void)
+{
+ u16 savedIme;
+ u8 taskId;
+ u8 spriteId;
+
+ SetVBlankCallback(NULL);
+
+ REG_DISPCNT = 0;
+ REG_BG3CNT = 0;
+ REG_BG2CNT = 0;
+ REG_BG1CNT = 0;
+ REG_BG0CNT = 0;
+ REG_BG3HOFS = 0;
+ REG_BG3VOFS = 0;
+ REG_BG2HOFS = 0;
+ REG_BG2VOFS = 0;
+ REG_BG1HOFS = 0;
+ REG_BG1VOFS = 0;
+ REG_BG0HOFS = 0;
+ REG_BG0VOFS = 0;
+
+ DmaFill16(3, 0, VRAM, VRAM_SIZE);
+ DmaFill32(3, 0, OAM, OAM_SIZE);
+ DmaFill16(3, 0, PLTT, PLTT_SIZE);
+
+ LZ77UnCompVram(&gBirchHelpGfx, (void *)VRAM);
+ LZ77UnCompVram(&gBirchBagTilemap, (void *)(VRAM + 0x3000));
+ LZ77UnCompVram(&gBirchGrassTilemap, (void *)(VRAM + 0x3800));
+ remove_some_task();
+ ResetTasks();
+ ResetSpriteData();
+ ResetPaletteFade();
+ FreeAllSpritePalettes();
+ LoadPalette(gBirchBagGrassPal, 0, sizeof(gBirchBagGrassPal));
+ LoadCompressedObjectPic(&gUnknown_083F7794[0]);
+ LoadCompressedObjectPic(&gUnknown_083F77A4[0]);
+ LoadSpritePalettes(gUnknown_083F77B4);
+ SetUpWindowConfig(&gWindowConfig_81E6C3C);
+ InitMenuWindow(&gWindowConfig_81E6CE4);
+ BeginNormalPaletteFade(-1, 0, 0x10, 0, 0);
+
+ savedIme = REG_IME;
+ REG_IME = 0;
+ REG_IE |= INTR_FLAG_VBLANK;
+ REG_IME = savedIme;
+ REG_DISPSTAT |= DISPSTAT_VBLANK_INTR;
+
+ SetVBlankCallback(VblankCallback);
+ SetMainCallback2(MainCallback2);
+
+ REG_WININ = 0x3F;
+ REG_WINOUT = 0x1F;
+ REG_WIN0H = 0;
+ REG_WIN0V = 0;
+ REG_BLDCNT = 0xFE;
+ REG_BLDALPHA = 0;
+ REG_BLDY = 0x7;
+ REG_BG3CNT = BGCNT_PRIORITY(3) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(7) | BGCNT_16COLOR | BGCNT_TXT256x256;
+ REG_BG2CNT = BGCNT_PRIORITY(2) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(6) | BGCNT_16COLOR | BGCNT_TXT256x256;
+ REG_BG0CNT = BGCNT_PRIORITY(0) | BGCNT_CHARBASE(2) | BGCNT_SCREENBASE(31) | BGCNT_16COLOR | BGCNT_TXT256x256;
+ REG_DISPCNT = DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON | DISPCNT_BG2_ON | DISPCNT_BG3_ON | DISPCNT_OBJ_ON | DISPCNT_WIN0_ON;
+
+ taskId = CreateTask(Task_StarterChoose1, 0);
+ gTasks[taskId].tStarterSelection = 1;
+
+ //Create hand sprite
+ spriteId = CreateSprite(&gSpriteTemplate_83F77CC, 120, 56, 2);
+ gSprites[spriteId].data0 = taskId;
+
+ //Create three Pokeball sprites
+ spriteId = CreateSprite(
+ &gSpriteTemplate_83F77E4,
+ gStarterChoose_PokeballCoords[0][0], gStarterChoose_PokeballCoords[0][1], 2);
+ gSprites[spriteId].data0 = taskId;
+ gSprites[spriteId].data1 = 0;
+ spriteId = CreateSprite(
+ &gSpriteTemplate_83F77E4,
+ gStarterChoose_PokeballCoords[1][0], gStarterChoose_PokeballCoords[1][1], 2);
+ gSprites[spriteId].data0 = taskId;
+ gSprites[spriteId].data1 = 1;
+ spriteId = CreateSprite(
+ &gSpriteTemplate_83F77E4,
+ gStarterChoose_PokeballCoords[2][0], gStarterChoose_PokeballCoords[2][1], 2);
+ gSprites[spriteId].data0 = taskId;
+ gSprites[spriteId].data1 = 2;
+}
+
+static void MainCallback2(void)
+{
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+}
+
+static void Task_StarterChoose1(u8 taskId)
+{
+ CreateStarterPokemonLabel(0xFF, gTasks[taskId].tStarterSelection);
+ MenuDrawTextWindow(2, 14, 27, 19);
+ MenuPrint(gOtherText_BirchInTrouble, 3, 15);
+ gTasks[taskId].func = Task_StarterChoose2;
+}
+
+static void Task_StarterChoose2(u8 taskId)
+{
+ u8 selection = gTasks[taskId].tStarterSelection;
+
+ if (gMain.newKeys & A_BUTTON)
+ {
+ u8 spriteId;
+
+ MenuZeroFillWindowRect(
+ gStarterChoose_LabelCoords[selection][0],
+ gStarterChoose_LabelCoords[selection][1],
+ gStarterChoose_LabelCoords[selection][0] + 13,
+ gStarterChoose_LabelCoords[selection][1] + 3);
+
+ REG_WIN0H = 0;
+ REG_WIN0V = 0;
+
+ //Create white circle background
+ spriteId = CreateSprite(
+ &gSpriteTemplate_83F77FC,
+ gStarterChoose_PokeballCoords[selection][0],
+ gStarterChoose_PokeballCoords[selection][1],
+ 1);
+ gTasks[taskId].tCircleSpriteId = spriteId;
+
+ //Create Pokemon sprite
+ spriteId = CreatePokemonFrontSprite(
+ GetStarterPokemon(gTasks[taskId].tStarterSelection),
+ gStarterChoose_PokeballCoords[selection][0],
+ gStarterChoose_PokeballCoords[selection][1]);
+ gSprites[spriteId].affineAnims = gSpriteAffineAnimTable_83F778C;
+ gSprites[spriteId].callback = StarterPokemonSpriteAnimCallback;
+ gTasks[taskId].tPkmnSpriteId = spriteId;
+
+ gTasks[taskId].func = Task_StarterChoose3;
+ }
+ else
+ {
+ if ((gMain.newKeys & DPAD_LEFT) && selection > 0)
+ {
+ gTasks[taskId].tStarterSelection--;
+ CreateStarterPokemonLabel(selection, gTasks[taskId].tStarterSelection);
+ }
+ else if ((gMain.newKeys & DPAD_RIGHT) && selection < 2)
+ {
+ gTasks[taskId].tStarterSelection++;
+ CreateStarterPokemonLabel(selection, gTasks[taskId].tStarterSelection);
+ }
+ }
+}
+
+static void Task_StarterChoose3(u8 taskId)
+{
+ if (gSprites[gTasks[taskId].tCircleSpriteId].affineAnimEnded &&
+ gSprites[gTasks[taskId].tCircleSpriteId].pos1.x == STARTER_PKMN_POS_X &&
+ gSprites[gTasks[taskId].tCircleSpriteId].pos1.y == STARTER_PKMN_POS_Y)
+ {
+ gTasks[taskId].func = Task_StarterChoose4;
+ }
+}
+
+static void Task_StarterChoose4(u8 taskId)
+{
+ PlayCry1(GetStarterPokemon(gTasks[taskId].tStarterSelection), 0);
+ MenuDrawTextWindow(2, 14, 27, 19);
+ //"Do you choose this POKEMON?"
+ MenuPrint(gOtherText_DoYouChoosePoke, 3, 15);
+ DisplayYesNoMenu(21, 7, 1);
+ gTasks[taskId].func = Task_StarterChoose5;
+}
+
+static void Task_StarterChoose5(u8 taskId)
+{
+ u8 spriteId;
+
+ switch (ProcessMenuInputNoWrap_())
+ {
+ case 0: // YES
+ //Return the starter choice and exit.
+ gScriptResult = gTasks[taskId].tStarterSelection;
+ SetMainCallback2(gMain.savedCallback);
+ break;
+ case 1: // NO
+ case -1: // B button
+ PlaySE(SE_SELECT);
+ MenuZeroFillWindowRect(21, 7, 27, 12);
+
+ spriteId = gTasks[taskId].tPkmnSpriteId;
+ FreeSpritePaletteByTag(GetSpritePaletteTagByPaletteNum(gSprites[spriteId].oam.paletteNum));
+ FreeOamMatrix(gSprites[spriteId].oam.matrixNum);
+ DestroySprite(&gSprites[spriteId]);
+
+ spriteId = gTasks[taskId].tCircleSpriteId;
+ FreeOamMatrix(gSprites[spriteId].oam.matrixNum);
+ DestroySprite(&gSprites[spriteId]);
+ gTasks[taskId].func = Task_StarterChoose6;
+ break;
+ }
+}
+
+static void Task_StarterChoose6(u8 taskId)
+{
+ gTasks[taskId].func = Task_StarterChoose1;
+}
+
+void AddTextColorCtrlCode(u8 *string, u8 bgColor, u8 textColor, u8 shadowColor)
+{
+ *(string++) = EXT_CTRL_CODE_BEGIN;
+ *(string++) = 4;
+ *(string++) = textColor;
+ *(string++) = bgColor;
+ *(string++) = shadowColor;
+}
+
+#define SET_CHAR(str, index, c) \
+{ \
+ u8 *p = str + index; \
+ *p = c; \
+}
+
+
+#if ENGLISH
+static void CreateStarterPokemonLabel(u8 prevSelection, u8 selection)
+{
+ u8 labelText[72];
+ const u8 *category;
+ u8 srcIndex;
+ u8 dstIndex;
+ u16 species;
+
+ u8 labelLeft;
+ u8 labelRight;
+ u8 labelTop;
+ u8 labelBottom;
+
+ if (prevSelection != 0xFF)
+ {
+ //Remove the old Pokemon label
+ MenuZeroFillWindowRect(
+ gStarterChoose_LabelCoords[prevSelection][0],
+ gStarterChoose_LabelCoords[prevSelection][1],
+ gStarterChoose_LabelCoords[prevSelection][0] + 13,
+ gStarterChoose_LabelCoords[prevSelection][1] + 3);
+ REG_WIN0H = 0;
+ REG_WIN0V = 0;
+ }
+ species = GetStarterPokemon(selection);
+ category = GetPokemonCategory(SpeciesToNationalPokedexNum(species));
+ AddTextColorCtrlCode(labelText, 0, 15, 8);
+ dstIndex = 5;
+ SET_CHAR(labelText, 5, EXT_CTRL_CODE_BEGIN);
+ SET_CHAR(labelText, 6, 0x11);
+ SET_CHAR(labelText, 7, dstIndex);
+
+ //Copy category string to label
+ dstIndex = 8;
+ srcIndex = 0;
+ while (category[srcIndex] != EOS && srcIndex <= 10)
+ {
+ labelText[dstIndex] = category[srcIndex];
+ srcIndex++;
+ dstIndex++;
+ }
+ labelText[dstIndex++] = CHAR_SPACE;
+
+ //Copy POKEMON string to label
+ StringCopy(labelText + dstIndex, gOtherText_Poke);
+ MenuPrint(
+ labelText,
+ gStarterChoose_LabelCoords[selection][0],
+ gStarterChoose_LabelCoords[selection][1]);
+ AddTextColorCtrlCode(labelText, 0, 15, 8);
+
+ //Copy Pokemon name to label
+ sub_8072C74(labelText + 5, gSpeciesNames[species], 0x6B, 1);
+ MenuPrint(
+ labelText,
+ gStarterChoose_LabelCoords[selection][0],
+ gStarterChoose_LabelCoords[selection][1] + 2);
+
+ labelLeft = gStarterChoose_LabelCoords[selection][0] * 8 + 4;
+ labelRight = (gStarterChoose_LabelCoords[selection][0] + 13) * 8 + 4;
+ labelTop = gStarterChoose_LabelCoords[selection][1] * 8;
+ labelBottom = (gStarterChoose_LabelCoords[selection][1] + 4) * 8;
+ REG_WIN0H = WIN_RANGE(labelLeft, labelRight);
+ REG_WIN0V = WIN_RANGE(labelTop, labelBottom);
+}
+#elif GERMAN
+__attribute__((naked))
+static void CreateStarterPokemonLabel(u8 prevSelection, u8 selection)
+{
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ sub sp, 0x48\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ lsls r1, 24\n\
+ lsrs r5, r1, 24\n\
+ cmp r0, 0xFF\n\
+ beq _0810A872\n\
+ ldr r1, _0810A960 @ =gStarterChoose_LabelCoords\n\
+ lsls r2, r0, 1\n\
+ adds r0, r2, r1\n\
+ ldrb r0, [r0]\n\
+ adds r1, 0x1\n\
+ adds r2, r1\n\
+ ldrb r1, [r2]\n\
+ adds r2, r0, 0\n\
+ adds r2, 0xD\n\
+ lsls r2, 24\n\
+ lsrs r2, 24\n\
+ adds r3, r1, 0x3\n\
+ lsls r3, 24\n\
+ lsrs r3, 24\n\
+ bl MenuZeroFillWindowRect\n\
+ ldr r0, _0810A964 @ =0x04000040\n\
+ movs r1, 0\n\
+ strh r1, [r0]\n\
+ adds r0, 0x4\n\
+ strh r1, [r0]\n\
+_0810A872:\n\
+ adds r0, r5, 0\n\
+ bl GetStarterPokemon\n\
+ lsls r0, 16\n\
+ lsrs r6, r0, 16\n\
+ adds r0, r6, 0\n\
+ bl SpeciesToNationalPokedexNum\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ bl GetPokemonCategory\n\
+ adds r4, r0, 0\n\
+ mov r0, sp\n\
+ movs r1, 0\n\
+ movs r2, 0xF\n\
+ movs r3, 0x8\n\
+ bl AddTextColorCtrlCode\n\
+ movs r2, 0x8\n\
+ movs r3, 0\n\
+ ldrb r0, [r4]\n\
+ lsls r5, 1\n\
+ mov r7, sp\n\
+ adds r7, 0x5\n\
+ cmp r0, 0xFF\n\
+ beq _0810A8CA\n\
+_0810A8A8:\n\
+ mov r0, sp\n\
+ adds r1, r0, r2\n\
+ adds r0, r4, r3\n\
+ ldrb r0, [r0]\n\
+ strb r0, [r1]\n\
+ adds r0, r3, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r3, r0, 24\n\
+ adds r0, r2, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r2, r0, 24\n\
+ adds r0, r4, r3\n\
+ ldrb r0, [r0]\n\
+ cmp r0, 0xFF\n\
+ beq _0810A8CA\n\
+ cmp r3, 0xA\n\
+ bls _0810A8A8\n\
+_0810A8CA:\n\
+ mov r0, sp\n\
+ adds r1, r0, r2\n\
+ movs r0, 0xFF\n\
+ strb r0, [r1]\n\
+ mov r1, sp\n\
+ movs r0, 0xFC\n\
+ strb r0, [r1, 0x5]\n\
+ movs r0, 0x11\n\
+ strb r0, [r1, 0x6]\n\
+ mov r2, sp\n\
+ lsls r1, r3, 1\n\
+ adds r1, r3\n\
+ lsls r1, 1\n\
+ movs r0, 0x70\n\
+ subs r0, r1\n\
+ asrs r0, 1\n\
+ strb r0, [r2, 0x7]\n\
+ ldr r0, _0810A960 @ =gStarterChoose_LabelCoords\n\
+ adds r1, r5, r0\n\
+ ldrb r4, [r1]\n\
+ adds r0, 0x1\n\
+ adds r0, r5, r0\n\
+ ldrb r5, [r0]\n\
+ mov r0, sp\n\
+ adds r1, r4, 0\n\
+ adds r2, r5, 0\n\
+ bl MenuPrint\n\
+ mov r0, sp\n\
+ movs r1, 0\n\
+ movs r2, 0xF\n\
+ movs r3, 0x8\n\
+ bl AddTextColorCtrlCode\n\
+ movs r0, 0xB\n\
+ adds r1, r6, 0\n\
+ muls r1, r0\n\
+ ldr r0, _0810A968 @ =gSpeciesNames\n\
+ adds r1, r0\n\
+ adds r0, r7, 0\n\
+ movs r2, 0x70\n\
+ movs r3, 0x2\n\
+ bl sub_8072C74\n\
+ adds r2, r5, 0x2\n\
+ lsls r2, 24\n\
+ lsrs r2, 24\n\
+ mov r0, sp\n\
+ adds r1, r4, 0\n\
+ bl MenuPrint\n\
+ lsls r0, r4, 3\n\
+ adds r0, 0x4\n\
+ lsls r0, 24\n\
+ adds r4, 0xD\n\
+ lsls r4, 3\n\
+ adds r4, 0x4\n\
+ lsls r4, 24\n\
+ lsrs r4, 24\n\
+ lsls r1, r5, 27\n\
+ adds r5, 0x4\n\
+ lsls r5, 27\n\
+ lsrs r5, 24\n\
+ ldr r2, _0810A964 @ =0x04000040\n\
+ lsrs r0, 16\n\
+ orrs r0, r4\n\
+ strh r0, [r2]\n\
+ ldr r0, _0810A96C @ =0x04000044\n\
+ lsrs r1, 16\n\
+ orrs r1, r5\n\
+ strh r1, [r0]\n\
+ add sp, 0x48\n\
+ pop {r4-r7}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .align 2, 0\n\
+_0810A960: .4byte gStarterChoose_LabelCoords\n\
+_0810A964: .4byte 0x04000040\n\
+_0810A968: .4byte gSpeciesNames\n\
+_0810A96C: .4byte 0x04000044\n\
+ .syntax divided\n");
+}
+#endif
+
+static void nullsub_72(struct Sprite *sprite)
+{
+}
+
+static u8 CreatePokemonFrontSprite(u16 species, u8 x, u8 y)
+{
+ u8 spriteId;
+
+ DecompressPicFromTable_2(
+ &gMonFrontPicTable[species],
+ gMonFrontPicCoords[species].coords, gMonFrontPicCoords[species].y_offset,
+ gUnknown_081FAF4C[0], gUnknown_081FAF4C[1],
+ species);
+ LoadCompressedObjectPalette(&gMonPaletteTable[species]);
+ GetMonSpriteTemplate_803C56C(species, 1);
+ spriteId = CreateSprite(&gUnknown_02024E8C, x, y, 0);
+ gSprites[spriteId].callback = nullsub_72;
+ gSprites[spriteId].oam.priority = 0;
+ return spriteId;
+}
+
+//Sprite callback
+static void sub_810A62C(struct Sprite *sprite)
+{
+ sprite->pos1.x = gUnknown_083F76E4[gTasks[sprite->data0].tStarterSelection][0];
+ sprite->pos1.y = gUnknown_083F76E4[gTasks[sprite->data0].tStarterSelection][1];
+ sprite->pos2.y = Sin(sprite->data1, 8);
+ sprite->data1 = (u8)sprite->data1 + 4;
+}
+
+//Sprite callback
+static void sub_810A68C(struct Sprite *sprite)
+{
+ if (gTasks[sprite->data0].tStarterSelection == sprite->data1)
+ StartSpriteAnimIfDifferent(sprite, 1);
+ else
+ StartSpriteAnimIfDifferent(sprite, 0);
+}
+
+//Sprite callback
+static void StarterPokemonSpriteAnimCallback(struct Sprite *sprite)
+{
+ //Move sprite to upper center of screen
+ if (sprite->pos1.x > STARTER_PKMN_POS_X)
+ sprite->pos1.x -= 4;
+ if (sprite->pos1.x < STARTER_PKMN_POS_X)
+ sprite->pos1.x += 4;
+ if (sprite->pos1.y > STARTER_PKMN_POS_Y)
+ sprite->pos1.y -= 2;
+ if (sprite->pos1.y < STARTER_PKMN_POS_Y)
+ sprite->pos1.y += 2;
+}
diff --git a/src/field/trader.c b/src/field/trader.c
new file mode 100644
index 000000000..61f48fad8
--- /dev/null
+++ b/src/field/trader.c
@@ -0,0 +1,262 @@
+#include "global.h"
+#include "decoration.h"
+#include "decoration_inventory.h"
+#include "event_data.h"
+#include "main.h"
+#include "mauville_man.h"
+#include "menu.h"
+#include "menu_helpers.h"
+#include "script.h"
+#include "songs.h"
+#include "sound.h"
+#include "string_util.h"
+#include "strings.h"
+#include "task.h"
+
+extern u16 gSpecialVar_0x8004;
+extern u16 gSpecialVar_0x8005;
+extern u16 gSpecialVar_0x8006;
+
+static const u8 * const gUnknown_083F62D8[] =
+{
+ SecretBaseText_Tristan,
+ SecretBaseText_Philip,
+ SecretBaseText_Dennis,
+ SecretBaseText_Roberto,
+};
+
+static const u8 gTraderDecorations[] =
+{
+ DECOR_DUSKULL_DOLL,
+ DECOR_BALL_CUSHION,
+ DECOR_TIRE,
+ DECOR_PRETTY_FLOWERS,
+};
+
+void sub_810993C(void)
+{
+ u8 i, j;
+ u8 buffer[12];
+ struct MauvilleManTrader *trader = &gSaveBlock1.mauvilleMan.trader;
+
+ for (i = 0; i < 3; i++)
+ {
+ for (j = i + 1; j < 4; j++)
+ {
+ if (trader->unk1[i] == 0)
+ {
+ u8 temp = trader->unk1[i];
+ trader->unk1[i] = trader->unk1[j];
+ trader->unk1[j] = temp;
+ StringCopy(buffer, trader->unk5[i]);
+ StringCopy(trader->unk5[i], trader->unk5[j]);
+ StringCopy(trader->unk5[j], buffer);
+ }
+ }
+ }
+}
+
+void TraderSetup(void)
+{
+ u8 i;
+ struct MauvilleManTrader *trader = &gSaveBlock1.mauvilleMan.trader;
+
+ trader->id = MAUVILLE_MAN_TRADER;
+ trader->alreadyTraded = FALSE;
+
+ for (i = 0; i < 4; i++)
+ {
+ StringCopy(trader->unk5[i], gUnknown_083F62D8[i]);
+ trader->unk1[i] = gTraderDecorations[i];
+ }
+
+ sub_810993C();
+}
+
+void sub_8109A20(void)
+{
+ struct MauvilleManTrader *trader = &gSaveBlock1.mauvilleMan.trader;
+ trader->alreadyTraded = FALSE;
+}
+
+void sub_8109A30(u8 value)
+{
+ VarSet(VAR_RECYCLE_GOODS, value);
+}
+
+void CreateAvailableDecorationsMenu(u8 taskId)
+{
+ u8 i;
+ u8 numChoices = 1;
+ u8 numDecorations = 0;
+ struct MauvilleManTrader *trader = &gSaveBlock1.mauvilleMan.trader;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (trader->unk1[i])
+ {
+ numChoices++;
+ }
+ }
+
+ MenuDrawTextWindow(0, 1, 12, numChoices * 2 + 2);
+
+ for (i = 0; i < 4; i++)
+ {
+ if (trader->unk1[i])
+ {
+ if (trader->unk1[i] > DECOR_REGISTEEL_DOLL)
+ {
+ MenuPrint(gOtherText_FiveQuestionsAndSlash, 1, numDecorations * 2 + 2);
+ }
+ else
+ {
+ MenuPrint(gDecorations[trader->unk1[i]].name, 1, numDecorations * 2 + 2);
+ }
+
+ numDecorations++;
+ }
+ }
+
+ MenuPrint(gOtherText_CancelNoTerminator, 1, numDecorations * 2 + 2);
+ InitMenu(0, 1, 2, numChoices, 0, 11);
+ gTasks[taskId].data[1] = numDecorations;
+}
+
+void sub_8109B34(u8 taskId, u8 decorationId)
+{
+ if (decorationId > DECOR_REGISTEEL_DOLL)
+ {
+ gSpecialVar_0x8004 = 0xFFFF;
+ }
+ else
+ {
+ gSpecialVar_0x8004 = decorationId;
+ }
+
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(0, 1, 12, 12);
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+}
+
+void Task_HandleGetDecorationMenuInput(u8 taskId)
+{
+ struct MauvilleManTrader *trader = &gSaveBlock1.mauvilleMan.trader;
+
+ if (gMain.newKeys & DPAD_UP)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor(-1);
+ }
+ else if (gMain.newKeys & DPAD_DOWN)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor(1);
+ }
+ else if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ gSpecialVar_0x8005 = GetMenuCursorPos();
+ if (gTasks[taskId].data[1] == gSpecialVar_0x8005)
+ {
+ sub_8109B34(taskId, 0);
+ }
+ else
+ {
+ StringCopy(gStringVar1, trader->unk5[gSpecialVar_0x8005]);
+ sub_8109B34(taskId, trader->unk1[gSpecialVar_0x8005]);
+ }
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ sub_8109B34(taskId, 0);
+ }
+}
+
+void ScrSpecial_GetTraderTradedFlag(void)
+{
+ struct MauvilleManTrader *trader = &gSaveBlock1.mauvilleMan.trader;
+ gScriptResult = trader->alreadyTraded;
+}
+
+void ScrSpecial_DoesPlayerHaveNoDecorations(void)
+{
+ u8 i;
+
+ for (i = 0; i < 8; i++)
+ {
+ if (sub_8134194(i))
+ {
+ gScriptResult = FALSE;
+ return;
+ }
+ }
+ gScriptResult = TRUE;
+}
+
+void ScrSpecial_IsDecorationFull(void)
+{
+ gScriptResult = FALSE;
+ if (gDecorations[gSpecialVar_0x8004].category != gDecorations[gSpecialVar_0x8006].category
+ && sub_8133F9C(gDecorations[gSpecialVar_0x8004].category) == -1)
+ {
+ sub_80FE7D4(gStringVar2, gDecorations[gSpecialVar_0x8004].category);
+ gScriptResult = TRUE;
+ }
+}
+
+void ScrSpecial_TraderMenuGiveDecoration(void)
+{
+ CreateTask(sub_80FE7A8, 0);
+}
+
+void sub_8109D04(u8 taskId)
+{
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(0, 0, 29, 19);
+ DestroyVerticalScrollIndicator(0);
+ DestroyVerticalScrollIndicator(1);
+ sub_80F9520(gUnknown_020388F7, 8);
+ BuyMenuFreeMemory();
+ if (sub_80FEFA4() == TRUE)
+ {
+ gSpecialVar_0x8006 = gUnknown_020388D0[gUnknown_020388F5];
+ StringCopy(gStringVar3, gDecorations[gSpecialVar_0x8004].name);
+ StringCopy(gStringVar2, gDecorations[gSpecialVar_0x8006].name);
+ }
+ else
+ {
+ gSpecialVar_0x8006 = 0xFFFF;
+ }
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+}
+
+void sub_8109DAC(u8 taskId)
+{
+ HandleDestroyMenuCursors();
+ MenuZeroFillWindowRect(0, 0, 29, 19);
+ gSpecialVar_0x8006 = 0;
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+}
+
+void ScrSpecial_TraderDoDecorationTrade(void)
+{
+ struct MauvilleManTrader *trader = &gSaveBlock1.mauvilleMan.trader;
+
+ sub_81340A8(gSpecialVar_0x8006);
+ IsThereStorageSpaceForDecoration(gSpecialVar_0x8004);
+ StringCopy(trader->unk5[gSpecialVar_0x8005], gSaveBlock2.playerName);
+ trader->unk1[gSpecialVar_0x8005] = gSpecialVar_0x8006;
+ sub_810993C();
+ trader->alreadyTraded = TRUE;
+}
+
+void ScrSpecial_TraderMenuGetDecoration(void)
+{
+ u8 taskId = CreateTask(Task_HandleGetDecorationMenuInput, 0);
+ CreateAvailableDecorationsMenu(taskId);
+}
diff --git a/src/field/trainer_see.c b/src/field/trainer_see.c
new file mode 100644
index 000000000..5a8ebbafc
--- /dev/null
+++ b/src/field/trainer_see.c
@@ -0,0 +1,519 @@
+#include "global.h"
+#include "trainer_see.h"
+#include "battle_setup.h"
+#include "field_effect.h"
+#include "field_map_obj.h"
+#include "field_player_avatar.h"
+#include "script.h"
+#include "sprite.h"
+#include "task.h"
+#include "util.h"
+
+const u8 gSpriteImage_839B308[] = INCBIN_U8("graphics/unknown_sprites/839B4E0/0.4bpp");
+const u8 gSpriteImage_839B388[] = INCBIN_U8("graphics/unknown_sprites/839B4E0/1.4bpp");
+const u8 gSpriteImage_839B408[] = INCBIN_U8("graphics/unknown_sprites/839B408.4bpp");
+
+u8 GetTrainerApproachDistanceSouth(struct MapObject *trainerObj, s16 range, s16 x, s16 y);
+u8 GetTrainerApproachDistanceNorth(struct MapObject *trainerObj, s16 range, s16 x, s16 y);
+u8 GetTrainerApproachDistanceWest(struct MapObject *trainerObj, s16 range, s16 x, s16 y);
+u8 GetTrainerApproachDistanceEast(struct MapObject *trainerObj, s16 range, s16 x, s16 y);
+
+static u8 (*const sDirectionalApproachDistanceFuncs[])(struct MapObject *, s16, s16, s16) =
+{
+ GetTrainerApproachDistanceSouth,
+ GetTrainerApproachDistanceNorth,
+ GetTrainerApproachDistanceWest,
+ GetTrainerApproachDistanceEast,
+};
+
+extern struct SpriteTemplate gSpriteTemplate_839B510;
+extern struct SpriteTemplate gSpriteTemplate_839B528;
+
+bool8 CheckTrainers(void)
+{
+ u8 mapObjId;
+
+ for (mapObjId = 0; mapObjId < 16; mapObjId++)
+ {
+ if (gMapObjects[mapObjId].active
+ && (gMapObjects[mapObjId].trainerType == 1 || gMapObjects[mapObjId].trainerType == 3)
+ && CheckTrainer(mapObjId))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 CheckTrainer(u8 mapObjId)
+{
+ u8 *scriptPtr = GetFieldObjectScriptPointerByFieldObjectId(mapObjId);
+
+ if (GetTrainerFlagFromScriptPointer(scriptPtr))
+ {
+ return FALSE;
+ }
+ else
+ {
+ struct MapObject *trainerObj = &gMapObjects[mapObjId];
+ bool8 canApproach = TrainerCanApproachPlayer(trainerObj);
+
+ if (canApproach)
+ {
+ TrainerWantsBattle(mapObjId, scriptPtr);
+ sub_80842C8(trainerObj, (canApproach - 1));
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+}
+
+bool8 TrainerCanApproachPlayer(struct MapObject *trainerObj)
+{
+ s16 x, y;
+ u8 i;
+ u8 approachDistance;
+
+ PlayerGetDestCoords(&x, &y);
+ if (trainerObj->trainerType == 1) // can only see in one direction
+ {
+ approachDistance = sDirectionalApproachDistanceFuncs[trainerObj->mapobj_unk_18 - 1](trainerObj, trainerObj->trainerRange_berryTreeId, x, y);
+ return CheckPathBetweenTrainerAndPlayer((struct MapObject2 *)trainerObj, approachDistance, trainerObj->mapobj_unk_18);
+ }
+ else // can see in all directions
+ {
+ for (i = 0; i < 4; i++)
+ {
+ approachDistance = sDirectionalApproachDistanceFuncs[i](trainerObj, trainerObj->trainerRange_berryTreeId, x, y);
+ if (CheckPathBetweenTrainerAndPlayer((struct MapObject2 *)trainerObj, approachDistance, i + 1)) // directions are 1-4 instead of 0-3. south north west east
+ return approachDistance;
+ }
+ }
+ return FALSE;
+}
+
+// Returns how far south the player is from trainer. 0 if out of trainer's sight.
+u8 GetTrainerApproachDistanceSouth(struct MapObject *trainerObj, s16 range, s16 x, s16 y)
+{
+ if (trainerObj->coords2.x == x
+ && y > trainerObj->coords2.y
+ && y <= trainerObj->coords2.y + range)
+ return (y - trainerObj->coords2.y);
+ else
+ return 0;
+}
+
+// Returns how far north the player is from trainer. 0 if out of trainer's sight.
+u8 GetTrainerApproachDistanceNorth(struct MapObject *trainerObj, s16 range, s16 x, s16 y)
+{
+ if (trainerObj->coords2.x == x
+ && y < trainerObj->coords2.y
+ && y >= trainerObj->coords2.y - range)
+ return (trainerObj->coords2.y - y);
+ else
+ return 0;
+}
+
+// Returns how far west the player is from trainer. 0 if out of trainer's sight.
+u8 GetTrainerApproachDistanceWest(struct MapObject *trainerObj, s16 range, s16 x, s16 y)
+{
+ if (trainerObj->coords2.y == y
+ && x < trainerObj->coords2.x
+ && x >= trainerObj->coords2.x - range)
+ return (trainerObj->coords2.x - x);
+ else
+ return 0;
+}
+
+// Returns how far east the player is from trainer. 0 if out of trainer's sight.
+u8 GetTrainerApproachDistanceEast(struct MapObject *trainerObj, s16 range, s16 x, s16 y)
+{
+ if (trainerObj->coords2.y == y
+ && x > trainerObj->coords2.x
+ && x <= trainerObj->coords2.x + range)
+ return (x - trainerObj->coords2.x);
+ else
+ return 0;
+}
+
+#ifdef BUGFIX_TRAINERAPPROACH
+#define COLLISION_MASK ~1
+#else
+#define COLLISION_MASK 1
+#endif
+
+bool8 CheckPathBetweenTrainerAndPlayer(struct MapObject2 *trainerObj, u8 approachDistance, u8 direction)
+{
+ s16 x, y;
+ u8 unk19_temp;
+ u8 unk19b_temp;
+ u8 i;
+ u8 collision;
+
+ if (approachDistance == 0)
+ return FALSE;
+
+ x = trainerObj->coords2.x;
+ y = trainerObj->coords2.y;
+
+ for (i = 0; i <= approachDistance - 1; i++, MoveCoords(direction, &x, &y))
+ {
+ collision = sub_8060024((struct MapObject *)trainerObj, x, y, direction);
+ if (collision != 0 && (collision & COLLISION_MASK))
+ return FALSE;
+ }
+
+ // preserve mapobj_unk_19 before clearing.
+ unk19_temp = trainerObj->mapobj_unk_19;
+ unk19b_temp = trainerObj->mapobj_unk_19b;
+ trainerObj->mapobj_unk_19 = 0;
+ trainerObj->mapobj_unk_19b = 0;
+
+ collision = npc_block_way((struct MapObject *)trainerObj, x, y, direction);
+
+ trainerObj->mapobj_unk_19 = unk19_temp;
+ trainerObj->mapobj_unk_19b = unk19b_temp;
+ if (collision == 4)
+ return approachDistance;
+
+ return FALSE;
+}
+
+#define tTrainerObjHi data[1]
+#define tTrainerObjLo data[2]
+
+void sub_80842C8(struct MapObject *trainerObj, u8 b)
+{
+ u8 taskId = CreateTask(RunTrainerSeeFuncList, 0x50);
+ struct Task *task = &gTasks[taskId];
+
+ task->tTrainerObjHi = (u32)(trainerObj) >> 16;
+ task->tTrainerObjLo = (u32)(trainerObj);
+ task->data[3] = b;
+}
+
+void sub_80842FC(TaskFunc followupFunc)
+{
+ TaskFunc taskFunc = RunTrainerSeeFuncList;
+ u8 taskId = FindTaskIdByFunc(taskFunc);
+
+ SetTaskFuncWithFollowupFunc(taskId, taskFunc, followupFunc);
+ gTasks[taskId].data[0] = 1;
+ taskFunc(taskId);
+}
+
+static bool8 sub_8084394(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+static bool8 sub_8084398(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+static bool8 sub_80843DC(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+static bool8 sub_808441C(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+static bool8 sub_8084478(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+static bool8 sub_8084534(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+static bool8 sub_8084578(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+static bool8 sub_80845AC(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+static bool8 sub_80845C8(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+static bool8 sub_80845FC(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+static bool8 sub_8084654(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+static bool8 sub_80846C8(u8 taskId, struct Task *task, struct MapObject *trainerObj);
+
+static bool8 (*const gTrainerSeeFuncList[])(u8 taskId, struct Task *task, struct MapObject *trainerObj) =
+{
+ sub_8084394,
+ sub_8084398,
+ sub_80843DC,
+ sub_808441C,
+ sub_8084478,
+ sub_8084534,
+ sub_8084578,
+ sub_80845AC,
+ sub_80845C8,
+ sub_80845FC,
+ sub_8084654,
+ sub_80846C8,
+};
+
+void RunTrainerSeeFuncList(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ struct MapObject *trainerObj = (struct MapObject *)((task->tTrainerObjHi << 16) | (task->tTrainerObjLo));
+
+ if (!trainerObj->active)
+ {
+ SwitchTaskToFollowupFunc(taskId);
+ }
+ else
+ {
+ while (gTrainerSeeFuncList[task->data[0]](taskId, task, trainerObj))
+ ;
+ }
+}
+
+static bool8 sub_8084394(u8 taskId, struct Task *task, struct MapObject *trainerObj) // cant be void because it is called with RunTrainerSeeFuncList with arguments.
+{
+ return FALSE;
+}
+
+static bool8 sub_8084398(u8 taskId, struct Task *task, struct MapObject *trainerObj)
+{
+ u8 direction;
+
+ FieldObjectGetLocalIdAndMap(trainerObj, (u8 *)&gFieldEffectArguments[0], (u8 *)&gFieldEffectArguments[1], (u8 *)&gFieldEffectArguments[2]);
+ FieldEffectStart(FLDEFF_EXCLAMATION_MARK_ICON_1);
+ direction = GetFaceDirectionAnimId(trainerObj->mapobj_unk_18);
+ FieldObjectSetSpecialAnim(trainerObj, direction);
+ task->data[0]++;
+ return TRUE;
+}
+
+static bool8 sub_80843DC(u8 taskId, struct Task *task, struct MapObject *trainerObj)
+{
+ if (FieldEffectActiveListContains(0))
+ {
+ return FALSE;
+ }
+ else
+ {
+ task->data[0]++;
+ if (trainerObj->animPattern == 57 || trainerObj->animPattern == 58)
+ task->data[0] = 6;
+ if (trainerObj->animPattern == 63)
+ task->data[0] = 8;
+ return TRUE;
+ }
+}
+
+static bool8 sub_808441C(u8 taskId, struct Task *task, struct MapObject *trainerObj)
+{
+ if (!(FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(trainerObj)) || FieldObjectClearAnimIfSpecialAnimFinished(trainerObj))
+ {
+ if (task->data[3])
+ {
+ FieldObjectSetSpecialAnim(trainerObj, GetGoSpeed0AnimId(trainerObj->mapobj_unk_18));
+ task->data[3]--;
+ }
+ else
+ {
+ FieldObjectSetSpecialAnim(trainerObj, 0x3E);
+ task->data[0]++;
+ }
+ }
+ return FALSE;
+}
+
+static bool8 sub_8084478(u8 taskId, struct Task *task, struct MapObject *trainerObj)
+{
+ struct MapObject *playerObj;
+
+ if (FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(trainerObj) && !FieldObjectClearAnimIfSpecialAnimFinished(trainerObj))
+ return FALSE;
+
+ npc_set_running_behaviour_etc(trainerObj, npc_running_behaviour_by_direction(trainerObj->mapobj_unk_18));
+ sub_805C774(trainerObj, npc_running_behaviour_by_direction(trainerObj->mapobj_unk_18));
+ sub_805C754(trainerObj);
+
+ playerObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+ if (FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(playerObj) && !FieldObjectClearAnimIfSpecialAnimFinished(playerObj))
+ return FALSE;
+
+ sub_80597E8();
+ FieldObjectSetSpecialAnim(&gMapObjects[gPlayerAvatar.mapObjectId], GetFaceDirectionAnimId(GetOppositeDirection(trainerObj->mapobj_unk_18)));
+ task->data[0]++;
+ return FALSE;
+}
+
+static bool8 sub_8084534(u8 taskId, struct Task *task, struct MapObject *trainerObj) // technically only 1 parameter, but needs all 3 for TrainerSeeFuncList call.
+{
+ struct MapObject *playerObj = &gMapObjects[gPlayerAvatar.mapObjectId];
+
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(playerObj)
+ || FieldObjectClearAnimIfSpecialAnimFinished(playerObj))
+ SwitchTaskToFollowupFunc(taskId);
+ return FALSE;
+}
+
+static bool8 sub_8084578(u8 taskId, struct Task *task, struct MapObject *trainerObj)
+{
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(trainerObj)
+ || FieldObjectClearAnimIfSpecialAnimFinished(trainerObj))
+ {
+ FieldObjectSetSpecialAnim(trainerObj, 0x59);
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+static bool8 sub_80845AC(u8 taskId, struct Task *task, struct MapObject *trainerObj)
+{
+ if (FieldObjectClearAnimIfSpecialAnimFinished(trainerObj))
+ task->data[0] = 3;
+
+ return FALSE;
+}
+
+static bool8 sub_80845C8(u8 taskId, struct Task *task, struct MapObject *trainerObj)
+{
+ if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(trainerObj)
+ || FieldObjectClearAnimIfSpecialAnimFinished(trainerObj))
+ {
+ FieldObjectSetSpecialAnim(trainerObj, 0x3E);
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+static bool8 sub_80845FC(u8 taskId, struct Task *task, struct MapObject *trainerObj)
+{
+ if (FieldObjectCheckIfSpecialAnimFinishedOrInactive(trainerObj))
+ {
+ gFieldEffectArguments[0] = trainerObj->coords2.x;
+ gFieldEffectArguments[1] = trainerObj->coords2.y;
+ gFieldEffectArguments[2] = gSprites[trainerObj->spriteId].subpriority - 1;
+ gFieldEffectArguments[3] = 2;
+ task->data[4] = FieldEffectStart(FLDEFF_POP_OUT_OF_ASH);
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+static bool8 sub_8084654(u8 taskId, struct Task *task, struct MapObject *trainerObj)
+{
+ struct Sprite *sprite;
+
+ if (gSprites[task->data[4]].animCmdIndex == 2)
+ {
+ trainerObj->mapobj_bit_26 = 0;
+ trainerObj->mapobj_bit_2 = 1;
+
+ sprite = &gSprites[trainerObj->spriteId];
+ sprite->oam.priority = 2;
+ FieldObjectClearAnimIfSpecialAnimFinished(trainerObj);
+ FieldObjectSetSpecialAnim(trainerObj, sub_806084C(trainerObj->mapobj_unk_18));
+ task->data[0]++;
+ }
+ return FALSE;
+}
+
+static bool8 sub_80846C8(u8 taskId, struct Task *task, struct MapObject *trainerObj)
+{
+ if (!FieldEffectActiveListContains(49))
+ task->data[0] = 3;
+
+ return FALSE;
+}
+
+static bool8 (*const gTrainerSeeFuncList2[])(u8, struct Task *, struct MapObject *) =
+{
+ sub_80845C8,
+ sub_80845FC,
+ sub_8084654,
+ sub_80846C8,
+};
+
+void sub_80846E4(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+ struct MapObject *mapObj;
+
+ // another mapObj loaded into by loadword?
+ LoadWordFromTwoHalfwords(&task->data[1], (u32 *)&mapObj);
+ if (!task->data[7])
+ {
+ FieldObjectClearAnim(mapObj);
+ task->data[7]++;
+ }
+ gTrainerSeeFuncList2[task->data[0]](taskId, task, mapObj);
+ if (task->data[0] == 3 && !FieldEffectActiveListContains(49))
+ {
+ npc_set_running_behaviour_etc(mapObj, npc_running_behaviour_by_direction(mapObj->mapobj_unk_18));
+ sub_805C774(mapObj, npc_running_behaviour_by_direction(mapObj->mapobj_unk_18));
+ DestroyTask(taskId);
+ }
+ else
+ mapObj->mapobj_bit_7 = 0;
+}
+
+void sub_8084794(struct MapObject *var)
+{
+ StoreWordInTwoHalfwords(&gTasks[CreateTask(sub_80846E4, 0)].data[1], (u32)var);
+}
+
+static void Task_DestroyTrainerApproachTask(u8);
+
+void ScrSpecial_EndTrainerApproach(void)
+{
+ sub_80842FC(Task_DestroyTrainerApproachTask);
+}
+
+static void Task_DestroyTrainerApproachTask(u8 taskId)
+{
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+}
+
+u8 FldEff_ExclamationMarkIcon1(void)
+{
+ u8 spriteId = CreateSpriteAtEnd(&gSpriteTemplate_839B510, 0, 0, 0x53);
+
+ if (spriteId != 64)
+ sub_8084894(&gSprites[spriteId], 0, 0);
+
+ return 0;
+}
+
+u8 FldEff_ExclamationMarkIcon2(void)
+{
+ u8 spriteId = CreateSpriteAtEnd(&gSpriteTemplate_839B510, 0, 0, 0x52);
+
+ if (spriteId != 64)
+ sub_8084894(&gSprites[spriteId], 33, 1);
+
+ return 0;
+}
+
+u8 FldEff_HeartIcon(void)
+{
+ u8 spriteId = CreateSpriteAtEnd(&gSpriteTemplate_839B528, 0, 0, 0x52);
+
+ if (spriteId != 64)
+ sub_8084894(&gSprites[spriteId], 46, 0);
+
+ return 0;
+}
+
+void sub_8084894(struct Sprite *sprite, u16 a2, u8 a3)
+{
+ sprite->oam.priority = 1;
+ sprite->coordOffsetEnabled = 1;
+
+ sprite->data0 = gFieldEffectArguments[0];
+ sprite->data1 = gFieldEffectArguments[1];
+ sprite->data2 = gFieldEffectArguments[2];
+ sprite->data3 = -5;
+ sprite->data7 = a2;
+
+ StartSpriteAnim(sprite, a3);
+}
+
+void objc_exclamation_mark_probably(struct Sprite *sprite)
+{
+ u8 mapObjId;
+
+ if (TryGetFieldObjectIdByLocalIdAndMap(sprite->data0, sprite->data1, sprite->data2, &mapObjId)
+ || sprite->animEnded)
+ {
+ FieldEffectStop(sprite, (u8)sprite->data7);
+ }
+ else
+ {
+ struct Sprite *mapObjSprite = &gSprites[gMapObjects[mapObjId].spriteId];
+ sprite->data4 += sprite->data3;
+ sprite->pos1.x = mapObjSprite->pos1.x;
+ sprite->pos1.y = mapObjSprite->pos1.y - 16;
+ sprite->pos2.x = mapObjSprite->pos2.x;
+ sprite->pos2.y = mapObjSprite->pos2.y + sprite->data4;
+ if (sprite->data4)
+ sprite->data3++;
+ else
+ sprite->data3 = 0;
+ }
+}
diff --git a/src/field/tv.c b/src/field/tv.c
new file mode 100644
index 000000000..e9b5e850d
--- /dev/null
+++ b/src/field/tv.c
@@ -0,0 +1,3259 @@
+#include "global.h"
+#include "tv.h"
+#include "battle_tower.h"
+#include "contest_painting.h"
+#include "data2.h"
+#include "easy_chat.h"
+#include "event_data.h"
+#include "fieldmap.h"
+#include "field_message_box.h"
+#include "field_camera.h"
+#include "flags.h"
+#include "rng.h"
+#include "string_util.h"
+#include "text.h"
+#include "species.h"
+#include "pokedex.h"
+#include "naming_screen.h"
+#include "overworld.h"
+#include "map_constants.h"
+#include "strings.h"
+#include "battle.h"
+#include "link.h"
+#include "easy_chat.h"
+#include "field_map_obj.h"
+#include "field_specials.h"
+#include "item.h"
+#include "items.h"
+#include "link.h"
+#include "map_constants.h"
+#include "naming_screen.h"
+#include "pokedex.h"
+#include "region_map.h"
+#include "rng.h"
+#include "overworld.h"
+#include "rtc.h"
+#include "script_menu.h"
+#include "species.h"
+#include "string_util.h"
+#include "strings.h"
+#include "text.h"
+
+struct UnkTvStruct
+{
+ s8 var0;
+};
+
+extern u8 gUnknown_0300430A[11];
+
+struct OutbreakPokemon
+{
+ /*0x00*/ u16 species;
+ /*0x02*/ u16 moves[4];
+ /*0x0A*/ u8 level;
+ /*0x0B*/ u8 location;
+};
+
+struct TVSaleItem {
+ u16 item_id;
+ u16 item_amount;
+};
+
+extern u8 gUnknown_02038694;
+
+extern struct TVSaleItem gUnknown_02038724[3];
+
+struct UnkTvStruct gUnknown_03005D38;
+
+extern u8 *gTVBravoTrainerTextGroup[];
+extern u8 *gTVBravoTrainerBattleTowerTextGroup[];
+extern u8 *gTVSmartShopperTextGroup[];
+extern u8 *gTVNameRaterTextGroup[];
+extern u8 *gTVPokemonTodayTextGroup[];
+extern u8 *gTVPokemonTodayFailedCaptureTextGroup[];
+extern u8 *gTVFanClubTextGroup[];
+extern u8 *gTVRecentHappeningsTextGroup[];
+extern u8 *gTVFanClubOpinionsTextGroup[];
+extern u8 *gTVPokemonOutbreakTextGroup[];
+extern u8 *gTVGabbyAndTyTextGroup[];
+extern u8 *gTVFishingGuruAdviceTextGroup[];
+extern u8 *gTVWorldOfMastersTextGroup[];
+extern struct OutbreakPokemon gPokeOutbreakSpeciesList[5];
+
+
+
+extern const u8 *gTVNewsTextGroup1[];
+extern const u8 *gTVNewsTextGroup2[];
+extern const u8 *gTVNewsTextGroup3[];
+
+extern u16 gScriptLastTalked;
+
+extern u8 gScriptContestCategory;
+extern u8 gScriptContestRank;
+extern u8 gUnknown_03004316[11];
+extern u8 gBattleOutcome;
+
+extern u16 gLastUsedItem;
+
+extern u8 ewram[];
+#define gUnknown_02007000 (*(ewramStruct_02007000 *)(ewram + 0x7000))
+
+static EWRAM_DATA u16 gUnknown_020387E0 = 0;
+static EWRAM_DATA u16 gUnknown_020387E2 = 0;
+static EWRAM_DATA u8 gUnknown_020387E4 = 0;
+static EWRAM_DATA ALIGNED(4) u8 gUnknown_020387E8 = 0; // why is this aligned to a 4-byte boundary?
+
+static u8 gUnknown_03000720;
+static u8 gUnknown_03000721;
+static s8 gUnknown_03000722;
+
+void ClearTVShowData(void)
+{
+ u8 showidx;
+ u8 extradataidx;
+ for (showidx=0; showidx<25; showidx++) {
+ gSaveBlock1.tvShows[showidx].common.var00 = 0;
+ gSaveBlock1.tvShows[showidx].common.var01 = 0;
+ for (extradataidx=0; extradataidx<34; extradataidx++) {
+ gSaveBlock1.tvShows[showidx].common.pad02[extradataidx] = 0;
+ }
+ }
+ sub_80BEBF4();
+}
+
+bool8 sub_80BF1B4(u8);
+void sub_80BF20C(void);
+extern u16 sub_8135D3C(u8);
+extern u8 gScriptContestCategory;
+extern u8 gScriptContestRank;
+extern u8 gUnknown_03004316[11];
+extern u8 gBattleOutcome;
+
+void sub_80BF334(void);
+void sub_80BF3A4(void);
+void sub_80BF3DC(void);
+void sub_80BF46C(void);
+void sub_80BF478(void);
+void sub_80BF484(void);
+void sub_80BF4BC(void);
+
+void sub_80BE028(void);
+void sub_80BE074(void);
+void sub_80BE778(void);
+void sub_80BEB20(void);
+
+u8 sub_80BFB54(u8);
+
+s8 sub_80BF74C(TVShow tvShow[]);
+
+void sub_80BF55C(TVShow tvShow[], u8 showidx);
+void sub_80BEA88(void);
+
+void sub_80BE138(TVShow *show);
+void sub_80BE160(TVShow *show);
+extern u16 gLastUsedItem;
+
+void sub_80BE5FC(void);
+void sub_80BE65C(void);
+void sub_80BE6A0(void);
+void nullsub_21(void);
+void sub_80BE188(void);
+void sub_80BE320(void);
+
+u8 special_0x44(void)
+{
+ u8 i;
+ u8 j;
+
+#ifndef NONMATCHING
+ asm("":::"r5");
+#endif
+
+ for (i = 5; i < 24; i++)
+ {
+ if (gSaveBlock1.tvShows[i].common.var00 == 0)
+ break;
+ }
+ i = Random() % i;
+ j = i;
+ do
+ {
+ if (sub_80BFB54(gSaveBlock1.tvShows[i].common.var00) != 4)
+ {
+ if (gSaveBlock1.tvShows[i].common.var01 == 1)
+ return i;
+ }
+ else
+ {
+ struct TVShowMassOutbreak *massOutbreak = &gSaveBlock1.tvShows[i].massOutbreak;
+
+ if (massOutbreak->var16 == 0 && massOutbreak->var01 == 1)
+ return i;
+ }
+
+ if (i == 0)
+ i = 23;
+ else
+ i--;
+ } while (i != j);
+ return 0xFF;
+}
+
+u8 sub_80BDA30(void);
+
+u8 sub_80BD8B8(void)
+{
+ u8 retval = special_0x44();
+
+ if (retval == 0xff)
+ return 0xff;
+ if (gSaveBlock1.outbreakPokemonSpecies != 0 && gSaveBlock1.tvShows[retval].common.var00 == TVSHOW_MASS_OUTBREAK)
+ return sub_80BDA30();
+ return retval;
+}
+
+u8 CheckForBigMovieOrEmergencyNewsOnTV(void);
+void SetTVMetatilesOnMap(int, int, u16);
+bool8 sub_80BECA0(void);
+bool8 IsTVShowInSearchOfTrainersAiring(void);
+
+void UpdateTVScreensOnMap(int width, int height)
+{
+ FlagSet(SYS_TV_WATCH);
+ switch (CheckForBigMovieOrEmergencyNewsOnTV())
+ {
+ case 1:
+ SetTVMetatilesOnMap(width, height, 0x3);
+ break;
+ case 2:
+ break;
+ default:
+ if (gSaveBlock1.location.mapGroup == MAP_GROUP_LILYCOVE_CITY_COVE_LILY_MOTEL_1F
+ && gSaveBlock1.location.mapNum == MAP_ID_LILYCOVE_CITY_COVE_LILY_MOTEL_1F)
+ {
+ SetTVMetatilesOnMap(width, height, 0x3);
+ }
+ else if (FlagGet(SYS_TV_START) && (sub_80BD8B8() != 0xff || sub_80BECA0() != 0xff || IsTVShowInSearchOfTrainersAiring()))
+ {
+ FlagClear(SYS_TV_WATCH);
+ SetTVMetatilesOnMap(width, height, 0x3);
+ }
+ break;
+ }
+}
+
+void SetTVMetatilesOnMap(int width, int height, u16 tileId)
+{
+ int x;
+ int y;
+
+ for (y=0; y<height; y++)
+ {
+ for (x=0; x<width; x++)
+ {
+ if (MapGridGetMetatileBehaviorAt(x, y) == 0x86)
+ MapGridSetMetatileIdAt(x, y, tileId | 0xc00);
+ }
+ }
+}
+
+void TurnOffTVScreen(void)
+{
+ SetTVMetatilesOnMap(gUnknown_03004870.width, gUnknown_03004870.height, 0x2);
+ DrawWholeMapView();
+}
+
+u8 sub_80BDA0C(void)
+{
+ return gSaveBlock1.tvShows[gSpecialVar_0x8004].common.var00;
+}
+
+u8 sub_80BDA30(void)
+{
+ u8 showIdx;
+ for (showIdx=0; showIdx<24; showIdx++)
+ {
+ if (gSaveBlock1.tvShows[showIdx].common.var00 != 0 && gSaveBlock1.tvShows[showIdx].common.var00 != TVSHOW_MASS_OUTBREAK && gSaveBlock1.tvShows[showIdx].common.var01 == 1)
+ return showIdx;
+ }
+ return 0xff;
+}
+
+u8 special_0x4a(void)
+{
+ TVShow *tvShow;
+ tvShow = &gSaveBlock1.tvShows[gSpecialVar_0x8004];
+ if (tvShow->common.var00 == TVSHOW_MASS_OUTBREAK && gSaveBlock1.outbreakPokemonSpecies)
+ return sub_80BDA30();
+ return gSpecialVar_0x8004;
+}
+
+void ResetGabbyAndTy(void)
+{
+ gSaveBlock1.gabbyAndTyData.mon1 = 0;
+ gSaveBlock1.gabbyAndTyData.mon2 = 0;
+ gSaveBlock1.gabbyAndTyData.lastMove = 0;
+ gSaveBlock1.gabbyAndTyData.quote = 0xffff;
+ gSaveBlock1.gabbyAndTyData.valA_0 = 0;
+ gSaveBlock1.gabbyAndTyData.valA_1 = 0;
+ gSaveBlock1.gabbyAndTyData.valA_2 = 0;
+ gSaveBlock1.gabbyAndTyData.valA_3 = 0;
+ gSaveBlock1.gabbyAndTyData.valA_4 = 0;
+ gSaveBlock1.gabbyAndTyData.valA_5 = 0;
+ gSaveBlock1.gabbyAndTyData.valB_0 = 0;
+ gSaveBlock1.gabbyAndTyData.valB_1 = 0;
+ gSaveBlock1.gabbyAndTyData.valB_2 = 0;
+ gSaveBlock1.gabbyAndTyData.valB_3 = 0;
+ gSaveBlock1.gabbyAndTyData.valB_4 = 0;
+ gSaveBlock1.gabbyAndTyData.valB_5 = 0;
+ gSaveBlock1.gabbyAndTyData.mapnum = 0;
+ gSaveBlock1.gabbyAndTyData.battleNum = 0;
+}
+
+void TakeTVShowInSearchOfTrainersOffTheAir(void);
+
+void GabbyAndTyBeforeInterview(void)
+{
+ u8 i;
+
+ gSaveBlock1.gabbyAndTyData.mon1 = gBattleResults.poke1Species;
+ gSaveBlock1.gabbyAndTyData.mon2 = gBattleResults.opponentSpecies;
+ gSaveBlock1.gabbyAndTyData.lastMove = gBattleResults.lastUsedMove;
+ if (gSaveBlock1.gabbyAndTyData.battleNum != 0xff)
+ gSaveBlock1.gabbyAndTyData.battleNum ++;
+ gSaveBlock1.gabbyAndTyData.valA_0 = gBattleResults.unk5_0;
+
+ if (gBattleResults.playerFaintCounter)
+ gSaveBlock1.gabbyAndTyData.valA_1 = 1;
+ else
+ gSaveBlock1.gabbyAndTyData.valA_1 = 0;
+
+ if (gBattleResults.unk3)
+ gSaveBlock1.gabbyAndTyData.valA_2 = 1;
+ else
+ gSaveBlock1.gabbyAndTyData.valA_2 = 0;
+
+ if (!gBattleResults.unk5_1)
+ {
+ for (i=0; i<11; i++)
+ {
+ if (gBattleResults.unk36[i] != 0)
+ {
+ gSaveBlock1.gabbyAndTyData.valA_3 = 1;
+ break;
+ }
+ }
+ }
+ else
+ {
+ gSaveBlock1.gabbyAndTyData.valA_3 = 1;
+ }
+
+ TakeTVShowInSearchOfTrainersOffTheAir();
+ if (gSaveBlock1.gabbyAndTyData.lastMove == 0)
+ FlagSet(1);
+}
+
+void sub_80BDC14(void)
+{
+ gSaveBlock1.gabbyAndTyData.valB_0 = gSaveBlock1.gabbyAndTyData.valA_0;
+ gSaveBlock1.gabbyAndTyData.valB_1 = gSaveBlock1.gabbyAndTyData.valA_1;
+ gSaveBlock1.gabbyAndTyData.valB_2 = gSaveBlock1.gabbyAndTyData.valA_2;
+ gSaveBlock1.gabbyAndTyData.valB_3 = gSaveBlock1.gabbyAndTyData.valA_3;
+ gSaveBlock1.gabbyAndTyData.valA_4 = 1;
+ gSaveBlock1.gabbyAndTyData.mapnum = gMapHeader.regionMapSectionId;
+ IncrementGameStat(GAME_STAT_GOT_INTERVIEWED);
+}
+
+void TakeTVShowInSearchOfTrainersOffTheAir(void)
+{
+ gSaveBlock1.gabbyAndTyData.valA_4 = 0;
+}
+
+u8 GabbyAndTyGetBattleNum(void)
+{
+ if (gSaveBlock1.gabbyAndTyData.battleNum >= 6)
+ return (gSaveBlock1.gabbyAndTyData.battleNum % 3) + 6;
+ else
+ return gSaveBlock1.gabbyAndTyData.battleNum;
+}
+
+bool8 IsTVShowInSearchOfTrainersAiring(void)
+{
+ return gSaveBlock1.gabbyAndTyData.valA_4;
+}
+
+bool8 GabbyAndTyGetLastQuote(void)
+{
+ if (gSaveBlock1.gabbyAndTyData.quote == 0xffff)
+ return FALSE;
+
+ EasyChat_GetWordText(gStringVar1, gSaveBlock1.gabbyAndTyData.quote);
+ gSaveBlock1.gabbyAndTyData.quote |= 0xffff;
+ return TRUE;
+}
+
+u8 sub_80BDD18(void)
+{
+ if (!gSaveBlock1.gabbyAndTyData.valB_0)
+ return 1;
+ if (gSaveBlock1.gabbyAndTyData.valB_3)
+ return 2;
+ if (gSaveBlock1.gabbyAndTyData.valB_2)
+ return 3;
+ if (gSaveBlock1.gabbyAndTyData.valB_1)
+ return 4;
+ return 0;
+}
+
+void GabbyAndTySetScriptVarsToFieldObjectLocalIds(void)
+{
+ switch (GabbyAndTyGetBattleNum())
+ {
+ case 1:
+ gSpecialVar_0x8004 = 0xE;
+ gSpecialVar_0x8005 = 0xD;
+ break;
+ case 2:
+ gSpecialVar_0x8004 = 0x5;
+ gSpecialVar_0x8005 = 0x6;
+ break;
+ case 3:
+ gSpecialVar_0x8004 = 0x12;
+ gSpecialVar_0x8005 = 0x11;
+ break;
+ case 4:
+ gSpecialVar_0x8004 = 0x15;
+ gSpecialVar_0x8005 = 0x16;
+ break;
+ case 5:
+ gSpecialVar_0x8004 = 0x8;
+ gSpecialVar_0x8005 = 0x9;
+ break;
+ case 6:
+ gSpecialVar_0x8004 = 0x13;
+ gSpecialVar_0x8005 = 0x14;
+ break;
+ case 7:
+ gSpecialVar_0x8004 = 0x17;
+ gSpecialVar_0x8005 = 0x18;
+ break;
+ case 8:
+ gSpecialVar_0x8004 = 0xA;
+ gSpecialVar_0x8005 = 0xB;
+ break;
+ }
+}
+
+void sub_80BDE48(void)
+{
+ switch (gSpecialVar_0x8005)
+ {
+ case TVSHOW_FAN_CLUB_LETTER:
+ sub_80BE5FC();
+ break;
+ case TVSHOW_RECENT_HAPPENINGS:
+ sub_80BE65C();
+ break;
+ case TVSHOW_PKMN_FAN_CLUB_OPINIONS:
+ sub_80BE6A0();
+ break;
+ case TVSHOW_UNKN_SHOWTYPE_04:
+ nullsub_21();
+ break;
+ case TVSHOW_BRAVO_TRAINER_POKEMON_PROFILE:
+ sub_80BE188();
+ break;
+ case TVSHOW_BRAVO_TRAINER_BATTLE_TOWER_PROFILE:
+ sub_80BE320();
+ break;
+ }
+}
+
+u8 sub_80BDEAC(u8 *a0)
+{
+ u8 lang = GAME_LANGUAGE;
+
+ if (a0[0] == EXT_CTRL_CODE_BEGIN && a0[1] == 0x15)
+ lang = LANGUAGE_JAPANESE;
+ return lang;
+}
+
+void sub_80BDEC8(void)
+{
+ u8 i;
+ u16 total;
+ u16 item;
+
+ total = 0;
+ sub_80BEB20();
+ sub_80BE778();
+
+ if (gBattleResults.caughtPoke == 0)
+ {
+ sub_80BE074();
+ }
+ else
+ {
+ sub_80BE028();
+ if (sub_80BF77C(0xffff) == 0 && StringCompareWithoutExtCtrlCodes(gSpeciesNames[gBattleResults.caughtPoke], gBattleResults.caughtNick) != 0)
+ {
+ gUnknown_03005D38.var0 = sub_80BF74C(gSaveBlock1.tvShows);
+ if (gUnknown_03005D38.var0 != -1 && sub_80BF1B4(TVSHOW_POKEMON_TODAY_CAUGHT) != 1)
+ {
+ for (i = 0; i < 11; i++)
+ total += gBattleResults.unk36[i];
+ if (total != 0 || gBattleResults.unk5_1 != 0)
+ {
+ struct TVShowPokemonToday *pokemonToday;
+
+ total = 0;
+ pokemonToday = &gSaveBlock1.tvShows[gUnknown_03005D38.var0].pokemonToday;
+ pokemonToday->var00 = TVSHOW_POKEMON_TODAY_CAUGHT;
+ pokemonToday->var01 = total;
+ if (gBattleResults.unk5_1 != 0)
+ {
+ total = 1;
+ item = ITEM_MASTER_BALL;
+ }
+ else
+ {
+ for (i = 0; i < 11; i++)
+ total += gBattleResults.unk36[i];
+ if (total > 0xff)
+ total = 0xff;
+ item = gLastUsedItem;
+ }
+ pokemonToday->var12 = total;
+ pokemonToday->ball = item;
+ StringCopy(pokemonToday->playerName, gSaveBlock2.playerName);
+ StringCopy(pokemonToday->nickname, gBattleResults.caughtNick);
+ pokemonToday->species = gBattleResults.caughtPoke;
+ sub_80BE138((TVShow *)pokemonToday);
+ pokemonToday->language = GAME_LANGUAGE;
+ pokemonToday->language2 = sub_80BDEAC(pokemonToday->nickname);
+ StripExtCtrlCodes(pokemonToday->nickname);
+ }
+ }
+ }
+ }
+}
+
+void sub_80BE028(void)
+{
+ struct TVShowWorldOfMasters *worldOfMasters = &gSaveBlock1.tvShows[24].worldOfMasters;
+
+ if (worldOfMasters->var00 != TVSHOW_WORLD_OF_MASTERS)
+ {
+ sub_80BF55C(gSaveBlock1.tvShows, 24);
+ worldOfMasters->var06 = GetGameStat(GAME_STAT_STEPS);
+ worldOfMasters->var00 = TVSHOW_WORLD_OF_MASTERS;
+ }
+ worldOfMasters->var02++;
+ worldOfMasters->var04 = gBattleResults.caughtPoke;
+ worldOfMasters->var08 = gBattleResults.poke1Species;
+ worldOfMasters->var0a = gMapHeader.regionMapSectionId;
+}
+
+void sub_80BE074(void)
+{
+ u8 i;
+ u16 total;
+ u8 zero = 0;
+
+ if (sub_80BF77C(0xffff) == 0)
+ {
+ for (i = 0, total = 0; i < ARRAY_COUNT(gUnknown_03004316); i++)
+ total += gUnknown_03004316[i];
+ if (total > 0xff)
+ total = 0xff;
+ if (total > 2 && gBattleOutcome == 1)
+ {
+ gUnknown_03005D38.var0 = sub_80BF74C(gSaveBlock1.tvShows);
+ if (gUnknown_03005D38.var0 != -1 && sub_80BF1B4(TVSHOW_POKEMON_TODAY_FAILED) != 1)
+ {
+ struct TVShowPokemonTodayFailed *pokemonTodayFailed = &gSaveBlock1.tvShows[gUnknown_03005D38.var0].pokemonTodayFailed;
+
+ zero = 0;
+ pokemonTodayFailed->var00 = TVSHOW_POKEMON_TODAY_FAILED;
+ pokemonTodayFailed->var01 = zero;
+ pokemonTodayFailed->species = gBattleResults.poke1Species;
+ pokemonTodayFailed->species2 = gBattleResults.lastOpponentSpecies;
+ pokemonTodayFailed->var10 = total;
+ pokemonTodayFailed->var11 = gBattleOutcome;
+ pokemonTodayFailed->var12 = gMapHeader.regionMapSectionId;
+ StringCopy(pokemonTodayFailed->playerName, gSaveBlock2.playerName);
+ sub_80BE138((TVShow *)pokemonTodayFailed);
+ pokemonTodayFailed->language = GAME_LANGUAGE;
+ }
+ }
+ }
+}
+
+
+void sub_80BE138(TVShow *show)
+{
+ u32 playerId = GetPlayerTrainerId();
+
+ show->common.srcTrainerId2Lo = playerId & 0xFF;
+ show->common.srcTrainerId2Hi = playerId >> 8;
+ show->common.srcTrainerIdLo = playerId & 0xFF;
+ show->common.srcTrainerIdHi = playerId >> 8;
+ show->common.trainerIdLo = playerId & 0xFF;
+ show->common.trainerIdHi = playerId >> 8;
+}
+
+void sub_80BE160(TVShow *show)
+{
+ u32 playerId = GetPlayerTrainerId();
+
+ show->common.srcTrainerIdLo = playerId & 0xFF;
+ show->common.srcTrainerIdHi = playerId >> 8;
+ show->common.trainerIdLo = playerId & 0xFF;
+ show->common.trainerIdHi = playerId >> 8;
+}
+
+void sub_80BE188(void)
+{
+ struct TVShowBravoTrainerPokemonProfiles *bravoTrainerSrc = &gSaveBlock1.tvShows[24].bravoTrainer;
+
+ if (bravoTrainerSrc->var00 == TVSHOW_BRAVO_TRAINER_POKEMON_PROFILE)
+ {
+ struct TVShowBravoTrainerPokemonProfiles *bravoTrainerNew = &gSaveBlock1.tvShows[gUnknown_03005D38.var0].bravoTrainer;
+
+ bravoTrainerNew->var00 = TVSHOW_BRAVO_TRAINER_POKEMON_PROFILE;
+ bravoTrainerNew->var01 = 1;
+ bravoTrainerNew->species = bravoTrainerSrc->species;
+ StringCopy(bravoTrainerNew->playerName, gSaveBlock2.playerName);
+ StringCopy(bravoTrainerNew->pokemonNickname, bravoTrainerSrc->pokemonNickname);
+ bravoTrainerNew->contestCategory = bravoTrainerSrc->contestCategory;
+ bravoTrainerNew->contestRank = bravoTrainerSrc->contestRank;
+ bravoTrainerNew->var14 = bravoTrainerSrc->var14;
+ bravoTrainerNew->contestResult = bravoTrainerSrc->contestResult;
+ bravoTrainerNew->contestCategory = bravoTrainerSrc->contestCategory;
+ sub_80BE160((TVShow *)bravoTrainerNew);
+ bravoTrainerNew->language = GAME_LANGUAGE;
+ bravoTrainerNew->var1f = sub_80BDEAC(bravoTrainerNew->pokemonNickname);
+ StripExtCtrlCodes(bravoTrainerNew->pokemonNickname);
+ }
+}
+
+void sub_80BE23C(u16 a0)
+{
+ struct TVShowBravoTrainerPokemonProfiles *bravoTrainer = &gSaveBlock1.tvShows[24].bravoTrainer;
+
+ sub_80BF484();
+ gUnknown_03005D38.var0 = sub_80BF720(gSaveBlock1.tvShows);
+ if (gUnknown_03005D38.var0 != -1)
+ {
+ sub_80BF55C(gSaveBlock1.tvShows, 24);
+ bravoTrainer->var14 = a0;
+ bravoTrainer->var00 = TVSHOW_BRAVO_TRAINER_POKEMON_PROFILE;
+ }
+}
+
+void sub_80BE284(u8 a0)
+{
+ struct TVShowBravoTrainerPokemonProfiles *bravoTrainer = &gSaveBlock1.tvShows[24].bravoTrainer;
+
+ gUnknown_03005D38.var0 = sub_80BF720(gSaveBlock1.tvShows);
+ if (gUnknown_03005D38.var0 != -1)
+ {
+ bravoTrainer->contestResult = a0;
+ bravoTrainer->contestCategory = gScriptContestCategory;
+ bravoTrainer->contestRank = gScriptContestRank;
+ bravoTrainer->species = GetMonData(&gPlayerParty[gUnknown_02038694], MON_DATA_SPECIES, NULL);
+ GetMonData(&gPlayerParty[gUnknown_02038694], MON_DATA_NICKNAME, bravoTrainer->pokemonNickname);
+ }
+}
+
+void sub_80BE320(void)
+{
+ struct TVShowBravoTrainerBattleTowerSpotlight *bravoTrainerTower = &gSaveBlock1.tvShows[gUnknown_03005D38.var0].bravoTrainerTower;
+
+ bravoTrainerTower->var00 = TVSHOW_BRAVO_TRAINER_BATTLE_TOWER_PROFILE;
+ bravoTrainerTower->var01 = 1;
+ StringCopy(bravoTrainerTower->trainerName, gSaveBlock2.playerName);
+ StringCopy(bravoTrainerTower->pokemonName, gSaveBlock2.filler_A8.filler_3DC);
+ bravoTrainerTower->species = gSaveBlock2.filler_A8.var_480;
+ bravoTrainerTower->defeatedSpecies = gSaveBlock2.filler_A8.var_482;
+ bravoTrainerTower->var16 = sub_8135D3C(gSaveBlock2.filler_A8.var_4D0);
+ bravoTrainerTower->var1c = gSaveBlock2.filler_A8.var_4AD;
+ if (gSaveBlock2.filler_A8.var_4D0 == 0)
+ bravoTrainerTower->btLevel = 50;
+ else
+ bravoTrainerTower->btLevel = 100;
+ bravoTrainerTower->var1b = gSpecialVar_0x8004;
+ sub_80BE160((TVShow *)bravoTrainerTower);
+ bravoTrainerTower->language = GAME_LANGUAGE;
+}
+
+void sub_80BE3BC(void)
+{
+ u8 rval;
+ u8 i;
+
+ rval = sub_80BF77C(0x5555);
+ if (rval == 0)
+ {
+ gUnknown_03005D38.var0 = sub_80BF74C(gSaveBlock1.tvShows);
+ if (gUnknown_03005D38.var0 != -1 && sub_80BF1B4(TVSHOW_SMART_SHOPPER) != 1)
+ {
+ sub_80BF20C();
+ if (gUnknown_02038724[0].item_amount >= 20)
+ {
+ struct TVShowSmartShopper *smartShopper = &gSaveBlock1.tvShows[gUnknown_03005D38.var0].smartshopperShow;
+
+ smartShopper->var00 = TVSHOW_SMART_SHOPPER;
+ smartShopper->var01 = rval;
+ smartShopper->shopLocation = gMapHeader.regionMapSectionId;
+ for (i=0; i<3; i++)
+ {
+ smartShopper->itemIds[i] = gUnknown_02038724[i].item_id;
+ smartShopper->itemAmounts[i] = gUnknown_02038724[i].item_amount;
+ }
+ smartShopper->priceReduced = GetPriceReduction(1);
+ StringCopy(smartShopper->playerName, gSaveBlock2.playerName);
+ sub_80BE138((TVShow *)smartShopper);
+ smartShopper->language = GAME_LANGUAGE;
+ }
+ }
+ }
+}
+
+void sub_80BE478(void)
+{
+ sub_80BF478();
+ if (gScriptResult == 1)
+ return;
+
+ GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar1);
+ if (StringLength(gSaveBlock2.playerName) > 1 && StringLength(gStringVar1) > 1)
+ {
+ struct TVShowNameRaterShow *nameRaterShow = &gSaveBlock1.tvShows[gUnknown_03005D38.var0].nameRaterShow;
+
+ nameRaterShow->var00 = TVSHOW_NAME_RATER_SHOW;
+ nameRaterShow->var01 = 1;
+ nameRaterShow->species = GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_SPECIES, NULL);
+ nameRaterShow->random = Random() % 3;
+ nameRaterShow->random2 = Random() % 2;
+ nameRaterShow->var1C = sub_80BF674(nameRaterShow->species);
+ StringCopy(nameRaterShow->trainerName, gSaveBlock2.playerName);
+ GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, nameRaterShow->pokemonName);
+ sub_80BE160((TVShow *)nameRaterShow);
+ nameRaterShow->language = GAME_LANGUAGE;
+ nameRaterShow->pokemonNameLanguage = sub_80BDEAC(nameRaterShow->pokemonName);
+ StripExtCtrlCodes(nameRaterShow->pokemonName);
+ }
+}
+
+void StartMassOutbreak(void)
+{
+ struct TVShowMassOutbreak *massOutbreak = &gSaveBlock1.tvShows[gSpecialVar_0x8004].massOutbreak;
+
+ gSaveBlock1.outbreakPokemonSpecies = massOutbreak->species;
+ gSaveBlock1.outbreakLocationMapNum = massOutbreak->locationMapNum;
+ gSaveBlock1.outbreakLocationMapGroup = massOutbreak->locationMapGroup;
+ gSaveBlock1.outbreakPokemonLevel = massOutbreak->level;
+ gSaveBlock1.outbreakUnk1 = massOutbreak->var02;
+ gSaveBlock1.outbreakUnk2 = massOutbreak->var0E;
+ gSaveBlock1.outbreakPokemonMoves[0] = massOutbreak->moves[0];
+ gSaveBlock1.outbreakPokemonMoves[1] = massOutbreak->moves[1];
+ gSaveBlock1.outbreakPokemonMoves[2] = massOutbreak->moves[2];
+ gSaveBlock1.outbreakPokemonMoves[3] = massOutbreak->moves[3];
+ gSaveBlock1.outbreakUnk4 = massOutbreak->var03;
+ gSaveBlock1.outbreakPokemonProbability = massOutbreak->probability;
+ gSaveBlock1.outbreakUnk5 = 2;
+}
+
+void sub_80BE5FC(void)
+{
+ struct TVShowFanClubLetter *fanclubLetter = &gSaveBlock1.tvShows[gUnknown_03005D38.var0].fanclubLetter;
+
+ fanclubLetter->var00 = TVSHOW_FAN_CLUB_LETTER;
+ fanclubLetter->var01 = 1;
+ StringCopy(fanclubLetter->playerName, gSaveBlock2.playerName);
+ fanclubLetter->species = GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_SPECIES, NULL);
+ sub_80BE160((TVShow *)fanclubLetter);
+ fanclubLetter->language = GAME_LANGUAGE;
+}
+
+void sub_80BE65C(void)
+{
+ struct TVShowRecentHappenings *recentHappenings = &gSaveBlock1.tvShows[gUnknown_03005D38.var0].recentHappenings;
+
+ recentHappenings->var00 = TVSHOW_RECENT_HAPPENINGS;
+ recentHappenings->var01 = 1;
+ StringCopy(recentHappenings->playerName, gSaveBlock2.playerName);
+ recentHappenings->var02 = 0;
+ sub_80BE160((TVShow *)recentHappenings);
+ recentHappenings->language = GAME_LANGUAGE;
+}
+
+void sub_80BE6A0(void)
+{
+ u8 monIndex;
+ struct TVShowFanclubOpinions *fanclubOpinions = &gSaveBlock1.tvShows[gUnknown_03005D38.var0].fanclubOpinions;
+
+ fanclubOpinions->var00 = TVSHOW_PKMN_FAN_CLUB_OPINIONS;
+ fanclubOpinions->var01 = 1;
+ monIndex = GetLeadMonIndex();
+ fanclubOpinions->var04A = GetMonData(&gPlayerParty[monIndex], MON_DATA_FRIENDSHIP, NULL) / 16;
+ fanclubOpinions->var04B = gSpecialVar_0x8007;
+ StringCopy(fanclubOpinions->playerName, gSaveBlock2.playerName);
+ GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_NICKNAME, fanclubOpinions->var10);
+ fanclubOpinions->var02 = GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_SPECIES, NULL);
+ sub_80BE160((TVShow *)fanclubOpinions);
+ fanclubOpinions->language = GAME_LANGUAGE;
+ fanclubOpinions->var0E = sub_80BDEAC(fanclubOpinions->var10);
+ StripExtCtrlCodes(fanclubOpinions->var10);
+}
+
+void nullsub_21(void)
+{
+}
+
+void sub_80BE778(void)
+{
+ if (FlagGet(SYS_GAME_CLEAR))
+ {
+ u8 i;
+
+ for (i = 0; i < 24; i++)
+ {
+ if (gSaveBlock1.tvShows[i].massOutbreak.var00 == TVSHOW_MASS_OUTBREAK)
+ return;
+ }
+ if (sub_80BF77C(0x147))
+ return;
+
+ gUnknown_03005D38.var0 = sub_80BF720(gSaveBlock1.tvShows);
+ if (gUnknown_03005D38.var0 != -1)
+ {
+ u16 rand = Random();
+ u16 val = rand % 5;
+ s32 val2 = gUnknown_03005D38.var0;
+ struct TVShowMassOutbreak *massOutbreak = &gSaveBlock1.tvShows[val2].massOutbreak;
+
+ massOutbreak->var00 = TVSHOW_MASS_OUTBREAK;
+ massOutbreak->var01 = 1;
+ massOutbreak->level = gPokeOutbreakSpeciesList[val].level;
+ massOutbreak->var02 = 0;
+ massOutbreak->var03 = 0;
+ massOutbreak->species = gPokeOutbreakSpeciesList[val].species;
+ massOutbreak->var0E = 0;
+ massOutbreak->moves[0] = gPokeOutbreakSpeciesList[val].moves[0];
+ massOutbreak->moves[1] = gPokeOutbreakSpeciesList[val].moves[1];
+ massOutbreak->moves[2] = gPokeOutbreakSpeciesList[val].moves[2];
+ massOutbreak->moves[3] = gPokeOutbreakSpeciesList[val].moves[3];
+ massOutbreak->locationMapNum = gPokeOutbreakSpeciesList[val].location;
+ massOutbreak->locationMapGroup = 0;
+ massOutbreak->var12 = 0;
+ massOutbreak->probability = 0x32;
+ massOutbreak->var15 = 0;
+ massOutbreak->var16 = 0x01;
+ sub_80BE160((TVShow *)massOutbreak);
+ massOutbreak->language = GAME_LANGUAGE;
+ }
+ }
+}
+
+void EndMassOutbreak(void)
+{
+ gSaveBlock1.outbreakPokemonSpecies = 0;
+ gSaveBlock1.outbreakLocationMapNum = 0;
+ gSaveBlock1.outbreakLocationMapGroup = 0;
+ gSaveBlock1.outbreakPokemonLevel = 0;
+ gSaveBlock1.outbreakUnk1 = 0;
+ gSaveBlock1.outbreakUnk2 = 0;
+ gSaveBlock1.outbreakPokemonMoves[0] = 0;
+ gSaveBlock1.outbreakPokemonMoves[1] = 0;
+ gSaveBlock1.outbreakPokemonMoves[2] = 0;
+ gSaveBlock1.outbreakPokemonMoves[3] = 0;
+ gSaveBlock1.outbreakUnk4 = 0;
+ gSaveBlock1.outbreakPokemonProbability = 0;
+ gSaveBlock1.outbreakUnk5 = 0;
+}
+
+void UpdateTVShowsPerDay(u16 arg0)
+{
+ sub_80BE8EC(arg0);
+ UpdateMassOutbreakTimeLeft(arg0);
+ sub_80BEE84(arg0);
+ sub_80BEA5C(arg0);
+}
+
+void sub_80BE8EC(u16 arg0)
+{
+ u8 showidx;
+
+ if (gSaveBlock1.outbreakPokemonSpecies == 0)
+ {
+ for (showidx=0; showidx<24; showidx++)
+ {
+ if (gSaveBlock1.tvShows[showidx].massOutbreak.var00 == TVSHOW_MASS_OUTBREAK
+ && gSaveBlock1.tvShows[showidx].massOutbreak.var01 == 0x01)
+ {
+ struct TVShowMassOutbreak *massOutbreak = &gSaveBlock1.tvShows[showidx].massOutbreak;
+
+ if (massOutbreak->var16 < arg0)
+ massOutbreak->var16 = 0;
+ else
+ massOutbreak->var16 -= arg0;
+ break;
+ }
+ }
+ }
+}
+
+void UpdateMassOutbreakTimeLeft(u16 arg0)
+{
+ if (gSaveBlock1.outbreakUnk5 <= arg0)
+ EndMassOutbreak();
+ else
+ gSaveBlock1.outbreakUnk5 -= arg0;
+}
+
+void sub_80BE97C(bool8 flag)
+{
+ u8 var0, var1;
+
+ if (flag)
+ {
+ var0 = gUnknown_020387E2 >> 8;
+ if (var0 > 4)
+ sub_80BE9D4();
+ gUnknown_020387E2 &= 0xFF;
+ var1 = gUnknown_020387E2 & 0xFF;
+ if (var1 != 0xFF)
+ gUnknown_020387E2++;
+ }
+ else
+ {
+ var0 = gUnknown_020387E2 & 0xFF;
+ if (var0 > 4)
+ sub_80BE9D4();
+ gUnknown_020387E2 &= 0xFF00;
+ var1 = gUnknown_020387E2 >> 8;
+ if (var1 != 0xFF)
+ gUnknown_020387E2 += 0x100;
+ }
+}
+
+void sub_80BE9D4(void)
+{
+ gUnknown_03005D38.var0 = sub_80BF74C(gSaveBlock1.tvShows);
+ if (gUnknown_03005D38.var0 != -1 && sub_80BF1B4(TVSHOW_FISHING_ADVICE) != 1)
+ {
+ struct TVShowPokemonAngler *pokemonAngler = &gSaveBlock1.tvShows[gUnknown_03005D38.var0].pokemonAngler;
+ register u8 zero asm("r1") = 0;
+
+ asm(""::"r"(zero));
+ pokemonAngler->var00 = TVSHOW_FISHING_ADVICE;
+ pokemonAngler->var01 = zero;
+ pokemonAngler->var02 = gUnknown_020387E2 & 0xFF;
+ pokemonAngler->var03 = gUnknown_020387E2 >> 8;
+ pokemonAngler->var04 = gUnknown_020387E0;
+ StringCopy(pokemonAngler->playerName, gSaveBlock2.playerName);
+ sub_80BE138((TVShow *)pokemonAngler);
+ pokemonAngler->language = GAME_LANGUAGE;
+ }
+}
+
+void sub_80BEA50(u16 var)
+{
+ gUnknown_020387E0 = var;
+}
+
+void sub_80BEA88(void);
+
+void sub_80BEA5C(u16 arg0)
+{
+ struct TVShowWorldOfMasters *worldOfMasters = &gSaveBlock1.tvShows[24].worldOfMasters;
+
+ if (worldOfMasters->var00 == TVSHOW_WORLD_OF_MASTERS)
+ {
+ if (worldOfMasters->var02 < 20)
+ sub_80BF55C(gSaveBlock1.tvShows, 0x18);
+ else
+ sub_80BEA88();
+ }
+}
+void sub_80BEA88(void)
+{
+ struct TVShowWorldOfMasters *worldOfMastersSrc = &gSaveBlock1.tvShows[24].worldOfMasters;
+
+ if (sub_80BF77C(0xFFFF) == 0)
+ {
+ gUnknown_03005D38.var0 = sub_80BF74C(gSaveBlock1.tvShows);
+ if (gUnknown_03005D38.var0 != -1 && sub_80BF1B4(TVSHOW_WORLD_OF_MASTERS) != 1)
+ {
+ struct TVShowWorldOfMasters *worldOfMastersDst = &gSaveBlock1.tvShows[gUnknown_03005D38.var0].worldOfMasters;
+
+ worldOfMastersDst->var00 = TVSHOW_WORLD_OF_MASTERS;
+ worldOfMastersDst->var01 = 0;
+ worldOfMastersDst->var02 = worldOfMastersSrc->var02;
+ worldOfMastersDst->var06 = GetGameStat(GAME_STAT_STEPS) - worldOfMastersSrc->var06;
+ worldOfMastersDst->var04 = worldOfMastersSrc->var04;
+ worldOfMastersDst->var08 = worldOfMastersSrc->var08;
+ worldOfMastersDst->var0a = worldOfMastersSrc->var0a;
+ StringCopy(worldOfMastersDst->playerName, gSaveBlock2.playerName);
+ sub_80BE138((TVShow *)worldOfMastersDst);
+ worldOfMastersDst->language = GAME_LANGUAGE;
+ }
+ }
+}
+
+void sub_80BEB20(void)
+{
+ u16 rval;
+
+ if (FlagGet(SYS_GAME_CLEAR) != 0)
+ {
+ gUnknown_03005D38.var0 = sub_80BEBC8(gSaveBlock1.unknown_2ABC);
+ if (gUnknown_03005D38.var0 != -1 && sub_80BF77C(0x28f) != 1)
+ {
+ rval = (Random() % 3) + 1;
+ if (sub_80BEE48(rval) != 1)
+ {
+ gSaveBlock1.unknown_2ABC[gUnknown_03005D38.var0].val0 = rval;
+ gSaveBlock1.unknown_2ABC[gUnknown_03005D38.var0].val2 = 4;
+ gSaveBlock1.unknown_2ABC[gUnknown_03005D38.var0].val1 = 1;
+ }
+ }
+ }
+}
+
+int sub_80BEBC8(struct UnknownSaveStruct2ABC *arg0)
+{
+ s8 i;
+
+ for (i = 0; i < 16; i++)
+ {
+ if (arg0[i].val0 == 0)
+ return i;
+ }
+ return -1;
+}
+
+void sub_80BEBF4(void)
+{
+ u8 i;
+
+ for (i = 0; i < 16; i++)
+ sub_80BEC10(i);
+}
+
+void sub_80BEC10(u8 arg0)
+{
+ gSaveBlock1.unknown_2ABC[arg0].val0 = 0;
+ gSaveBlock1.unknown_2ABC[arg0].val1 = 0;
+ gSaveBlock1.unknown_2ABC[arg0].val2 = 0;
+}
+
+void sub_80BEC40(void)
+{
+ u8 i, j;
+
+ for (i = 0; i < 15; i++)
+ {
+ if (gSaveBlock1.unknown_2ABC[i].val0 == 0)
+ {
+ for (j = i + 1; j < 16; j++)
+ {
+ if (gSaveBlock1.unknown_2ABC[j].val0 != 0)
+ {
+ gSaveBlock1.unknown_2ABC[i] = gSaveBlock1.unknown_2ABC[j];
+ sub_80BEC10(j);
+ break;
+ }
+ }
+ }
+ }
+}
+
+u8 sub_80BECA0(void)
+{
+ u8 i;
+ for (i = 0; i < 16; i++)
+ {
+ if (gSaveBlock1.unknown_2ABC[i].val0 != 0
+ && gSaveBlock1.unknown_2ABC[i].val1 == 1
+ && gSaveBlock1.unknown_2ABC[i].val2 < 3)
+ return i;
+ }
+ return 0xFF;
+}
+
+void sub_80BECE8(void)
+{
+ u8 arg0;
+ arg0 = sub_80BECA0();
+ if (arg0 == 0xff)
+ {
+ gScriptResult = 0;
+ return;
+ }
+ if (gSaveBlock1.unknown_2ABC[arg0].val2 == 0)
+ {
+ gSaveBlock1.unknown_2ABC[arg0].val1 = 2;
+ if (gLocalTime.hours < 20)
+ ShowFieldMessage(gTVNewsTextGroup2[gSaveBlock1.unknown_2ABC[arg0].val0]);
+ else
+ ShowFieldMessage(gTVNewsTextGroup3[gSaveBlock1.unknown_2ABC[arg0].val0]);
+ }
+ else
+ {
+ u16 value = gSaveBlock1.unknown_2ABC[arg0].val2;
+
+ ConvertIntToDecimalStringN(gStringVar1, value, 0, 1);
+ gSaveBlock1.unknown_2ABC[arg0].val1 = 0;
+ ShowFieldMessage(gTVNewsTextGroup1[gSaveBlock1.unknown_2ABC[arg0].val0]);
+ }
+ gScriptResult = 1;
+}
+
+bool8 GetPriceReduction(u8 arg0)
+{
+ u8 i;
+
+ if (arg0 == 0)
+ return FALSE;
+ for (i=0; i<16; i++)
+ {
+ if (gSaveBlock1.unknown_2ABC[i].val0 == arg0)
+ {
+ if (gSaveBlock1.unknown_2ABC[i].val1 == 2 && IsPriceDiscounted(arg0) != 0)
+ return TRUE;
+ else
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+
+bool8 IsPriceDiscounted(u8 arg0)
+{
+ switch (arg0)
+ {
+ case 1:
+ if (gSaveBlock1.location.mapGroup == MAP_GROUP_SLATEPORT_CITY
+ && gSaveBlock1.location.mapNum == MAP_ID_SLATEPORT_CITY
+ && gScriptLastTalked == 0x1a)
+ return TRUE;
+ else
+ return FALSE;
+ break;
+ case 3:
+ if (gSaveBlock1.location.mapGroup == MAP_GROUP_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP
+ && gSaveBlock1.location.mapNum == MAP_ID_LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP)
+ return TRUE;
+ else
+ return FALSE;
+ break;
+ default:
+ return TRUE;
+ }
+}
+
+bool8 sub_80BEE48(u8 arg0)
+{
+ u8 i;
+
+ if (arg0 == 0)
+ return TRUE;
+ for (i=0; i<16; i++)
+ {
+ if (gSaveBlock1.unknown_2ABC[i].val0 == arg0)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void sub_80BEE84(u16 var0)
+{
+ u8 i;
+
+ for (i=0; i<16; i++)
+ {
+ if (gSaveBlock1.unknown_2ABC[i].val0)
+ {
+ if (gSaveBlock1.unknown_2ABC[i].val2 < var0)
+ {
+ sub_80BEC10(i);
+ }
+ else
+ {
+ if (!gSaveBlock1.unknown_2ABC[i].val1 && FlagGet(SYS_GAME_CLEAR) == 1)
+ gSaveBlock1.unknown_2ABC[i].val1 = 1;
+ gSaveBlock1.unknown_2ABC[i].val2 -= var0;
+ }
+ }
+ }
+ sub_80BEC40();
+}
+
+void sub_80BEF10(u8 strvaridx, u8 rank)
+{
+ switch (rank)
+ {
+ case NORMAL_RANK:
+ StringCopy(gUnknown_083D1464[strvaridx], gUnknown_083CE048[NORMAL_RANK + 5]);
+ break;
+ case SUPER_RANK:
+ StringCopy(gUnknown_083D1464[strvaridx], gUnknown_083CE048[SUPER_RANK + 5]);
+ break;
+ case HYPER_RANK:
+ StringCopy(gUnknown_083D1464[strvaridx], gUnknown_083CE048[HYPER_RANK + 5]);
+ break;
+ case MASTER_RANK:
+ StringCopy(gUnknown_083D1464[strvaridx], gUnknown_083CE048[MASTER_RANK + 5]);
+ break;
+ }
+}
+
+void CopyContestCategoryToStringVar(u8 strvaridx, u8 category)
+{
+ switch (category)
+ {
+ case CONTEST_COOL:
+ StringCopy(gUnknown_083D1464[strvaridx], gUnknown_083CE048[CONTEST_COOL]);
+ break;
+ case CONTEST_BEAUTY:
+ StringCopy(gUnknown_083D1464[strvaridx], gUnknown_083CE048[CONTEST_BEAUTY]);
+ break;
+ case CONTEST_CUTE:
+ StringCopy(gUnknown_083D1464[strvaridx], gUnknown_083CE048[CONTEST_CUTE]);
+ break;
+ case CONTEST_SMART:
+ StringCopy(gUnknown_083D1464[strvaridx], gUnknown_083CE048[CONTEST_SMART]);
+ break;
+ case CONTEST_TOUGH:
+ StringCopy(gUnknown_083D1464[strvaridx], gUnknown_083CE048[CONTEST_TOUGH]);
+ break;
+ }
+}
+
+void SetContestCategoryStringVarForInterview(void)
+{
+ struct TVShowBravoTrainerPokemonProfiles *bravoTrainer = &gSaveBlock1.tvShows[gSpecialVar_0x8004].bravoTrainer;
+
+ CopyContestCategoryToStringVar(1, bravoTrainer->contestCategory);
+}
+
+void sub_80BF088(u8 arg0, s32 price)
+{
+ size_t log10val = sub_80BF0B8(price);
+
+ ConvertIntToDecimalStringN(gUnknown_083D1464[arg0], price, 0, log10val);
+}
+
+size_t sub_80BF0B8(int value)
+{
+ if (value / 10 == 0)
+ return 1;
+ else if (value / 100 == 0)
+ return 2;
+ else if (value / 1000 == 0)
+ return 3;
+ else if (value / 10000 == 0)
+ return 4;
+ else if (value / 100000 == 0)
+ return 5;
+ else if (value / 1000000 == 0)
+ return 6;
+ else if (value / 10000000 == 0)
+ return 7;
+ else if (value / 100000000 == 0)
+ return 8;
+ else
+ return 1;
+}
+
+void sub_80BF154(u8 arg0, struct TVShowSmartShopper *arg1)
+{
+ u8 i;
+ s32 price;
+ price = 0;
+
+ for (i = 0; i < 3; i++)
+ {
+ if (arg1->itemIds[i])
+ price += ItemId_GetPrice(arg1->itemIds[i]) * arg1->itemAmounts[i];
+ }
+ if (arg1->priceReduced == 1)
+ sub_80BF088(arg0, price >> 1);
+ else
+ sub_80BF088(arg0, price);
+}
+
+bool8 sub_80BF1B4(u8 showIdx)
+{
+ u8 i;
+ //TVShow *tvShows;
+ TVShow *tvShows = gSaveBlock1.tvShows;
+ u32 trainerId = GetPlayerTrainerId();
+
+ for (i = 5; i < 24; i++)
+ {
+ if (tvShows[i].common.var00 == showIdx)
+ {
+ if ((trainerId & 0xFF) == tvShows[i].common.trainerIdLo && ((trainerId >> 8) & 0xFF) == tvShows[i].common.trainerIdHi)
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void sub_80BF20C(void)
+{
+ u8 i, j;
+ u16 tmpId, tmpAmount;
+
+ for (i = 0; i < 2; i++)
+ {
+ for (j = i + 1; j < 3; j++)
+ {
+ if (gUnknown_02038724[i].item_amount < gUnknown_02038724[j].item_amount)
+ {
+ tmpId = gUnknown_02038724[i].item_id;
+ tmpAmount = gUnknown_02038724[i].item_amount;
+ gUnknown_02038724[i].item_id = gUnknown_02038724[j].item_id;
+ gUnknown_02038724[i].item_amount = gUnknown_02038724[j].item_amount;
+ gUnknown_02038724[j].item_id = tmpId;
+ gUnknown_02038724[j].item_amount = tmpAmount;
+ }
+ }
+ }
+}
+
+void sub_80BF25C(u8 showType)
+{
+ u8 i;
+
+ for (i = 0; i < 5; i++)
+ {
+ if (gSaveBlock1.tvShows[i].common.var00 == showType)
+ {
+ if(gSaveBlock1.tvShows[i].common.var01 == 1)
+ {
+ gScriptResult = 1;
+ }
+ else
+ {
+ sub_80BF55C(gSaveBlock1.tvShows, i);
+ sub_80BF588(gSaveBlock1.tvShows);
+ sub_80BF6D8();
+ }
+ return;
+ }
+ }
+ sub_80BF6D8();
+}
+
+void sub_80BF2C4(void)
+{
+ gScriptResult = 0;
+ switch (gSpecialVar_0x8005)
+ {
+ case TVSHOW_FAN_CLUB_LETTER:
+ sub_80BF334();
+ break;
+ case TVSHOW_RECENT_HAPPENINGS:
+ sub_80BF3A4();
+ break;
+ case TVSHOW_PKMN_FAN_CLUB_OPINIONS:
+ sub_80BF3DC();
+ break;
+ case TVSHOW_UNKN_SHOWTYPE_04:
+ sub_80BF46C();
+ break;
+ case TVSHOW_NAME_RATER_SHOW:
+ sub_80BF478();
+ break;
+ case TVSHOW_BRAVO_TRAINER_POKEMON_PROFILE:
+ sub_80BF484();
+ break;
+ case TVSHOW_BRAVO_TRAINER_BATTLE_TOWER_PROFILE:
+ sub_80BF4BC();
+ break;
+ }
+}
+
+void sub_80BF334(void)
+{
+ struct TVShowFanClubLetter *fanclubLetter;
+
+ sub_80BF25C(TVSHOW_FAN_CLUB_LETTER);
+ if (gScriptResult == 0)
+ {
+ StringCopy(gStringVar1, gSpeciesNames[GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_SPECIES, 0)]);
+ fanclubLetter = &gSaveBlock1.tvShows[gUnknown_03005D38.var0].fanclubLetter;
+ sub_80EB6FC(fanclubLetter->pad04, 6);
+ }
+}
+
+void sub_80BF3A4(void)
+{
+ struct TVShowRecentHappenings *recentHappenings;
+
+ sub_80BF25C(TVSHOW_RECENT_HAPPENINGS);
+ if (gScriptResult == 0)
+ {
+ recentHappenings = &gSaveBlock1.tvShows[gUnknown_03005D38.var0].recentHappenings;
+ sub_80EB6FC(recentHappenings->var04, 6);
+ }
+}
+
+void sub_80BF3DC(void)
+{
+ struct TVShowFanclubOpinions *fanclubOpinions;
+
+ sub_80BF25C(TVSHOW_PKMN_FAN_CLUB_OPINIONS);
+ if (gScriptResult == 0)
+ {
+ StringCopy(gStringVar1, gSpeciesNames[GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_SPECIES, 0)]);
+ GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_NICKNAME, gStringVar2);
+ StringGetEnd10(gStringVar2);
+ fanclubOpinions = &gSaveBlock1.tvShows[gUnknown_03005D38.var0].fanclubOpinions;
+ sub_80EB6FC(fanclubOpinions->var1C, 2);
+ }
+}
+
+void sub_80BF46C(void)
+{
+ gScriptResult = 1;
+}
+
+void sub_80BF478(void)
+{
+ sub_80BF25C(TVSHOW_NAME_RATER_SHOW);
+}
+
+void sub_80BF484(void)
+{
+ struct TVShowBravoTrainerPokemonProfiles *bravoTrainer;
+
+ sub_80BF25C(TVSHOW_BRAVO_TRAINER_POKEMON_PROFILE);
+ if (gScriptResult == 0)
+ {
+ bravoTrainer = &gSaveBlock1.tvShows[gUnknown_03005D38.var0].bravoTrainer;
+ sub_80EB6FC(bravoTrainer->var04, 2);
+ }
+}
+
+void sub_80BF4BC(void)
+{
+ struct TVShowBravoTrainerBattleTowerSpotlight *bravoTrainerTower;
+
+ sub_80BF25C(TVSHOW_BRAVO_TRAINER_BATTLE_TOWER_PROFILE);
+ if (gScriptResult == 0)
+ {
+ bravoTrainerTower = &gSaveBlock1.tvShows[gUnknown_03005D38.var0].bravoTrainerTower;
+ sub_80EB6FC(bravoTrainerTower->var18, 1); // wrong struct ident, fix later
+ }
+}
+
+#if ENGLISH
+u8 sub_80BF4F4(u8 arg0)
+{
+ u32 species;
+
+ GetMonData(&gPlayerParty[arg0], MON_DATA_NICKNAME, &gStringVar1);
+ species = GetMonData(&gPlayerParty[arg0], MON_DATA_SPECIES, NULL);
+ if (StringCompareWithoutExtCtrlCodes(gSpeciesNames[species], gStringVar1) == FALSE)
+ return FALSE;
+
+ return TRUE;
+}
+#elif GERMAN
+u8 sub_80BF4F4(u8 arg0)
+{
+ u8 langData[4];
+ u32 species;
+ u8 *tmp;
+
+ GetMonData(&gPlayerParty[arg0], MON_DATA_NICKNAME, &gStringVar1);
+
+ tmp = langData;
+ tmp[0] = GetMonData(&gPlayerParty[arg0], MON_DATA_LANGUAGE, &langData);
+ if (tmp[0] != GAME_LANGUAGE)
+ return TRUE;
+
+ species = GetMonData(&gPlayerParty[arg0], MON_DATA_SPECIES, NULL);
+ if (StringCompareWithoutExtCtrlCodes(gSpeciesNames[species], gStringVar1))
+ return TRUE;
+
+ return FALSE;
+}
+#endif
+
+u8 sub_80BF544(void)
+{
+ return sub_80BF4F4(GetLeadMonIndex());
+}
+
+void sub_80BF55C(TVShow tvShow[], u8 showidx)
+{
+ u8 idx;
+
+ tvShow[showidx].common.var00 = 0;
+ tvShow[showidx].common.var01 = 0;
+ for (idx = 0; idx < 34; idx++)
+ tvShow[showidx].common.pad02[idx] = 0;
+}
+
+void sub_80BF588(TVShow tvShow[])
+{
+ u8 showidx;
+ u8 showidx2;
+
+ for (showidx = 0; showidx < 4; showidx++)
+ {
+ if (tvShow[showidx].common.var00 == 0)
+ {
+ for (showidx2 = showidx + 1; showidx2 < 5; showidx2++)
+ {
+ if (tvShow[showidx2].common.var00 != 0)
+ {
+ tvShow[showidx] = tvShow[showidx2];
+ sub_80BF55C(tvShow, showidx2);
+ break;
+ }
+ }
+ }
+ }
+ for (showidx = 5; showidx < 24; showidx++)
+ {
+ if (tvShow[showidx].common.var00 == 0)
+ {
+ for (showidx2 = showidx + 1; showidx2 < 24; showidx2++)
+ {
+ if (tvShow[showidx2].common.var00 != 0)
+ {
+ tvShow[showidx] = tvShow[showidx2];
+ sub_80BF55C(gSaveBlock1.tvShows, showidx2);
+ break;
+ }
+ }
+ }
+ }
+}
+
+u16 sub_80BF638(u8 arg0, u16 arg1)
+{
+ u16 retval = sub_80BF674(arg1);
+
+ StringCopy(gUnknown_083D1464[arg0], gSpeciesNames[retval]);
+ return retval;
+}
+
+u16 sub_80BF674(u16 species)
+{
+ u16 rspecies;
+ u16 cspecies;
+
+ rspecies = (Random() % (NUM_SPECIES - 1)) + 1;
+ cspecies = rspecies;
+ while (GetSetPokedexFlag(SpeciesToNationalPokedexNum(cspecies), 0) != 1 || cspecies == species)
+ {
+ if (cspecies == SPECIES_BULBASAUR)
+ cspecies = NUM_SPECIES - 1;
+ else
+ cspecies --;
+ if (cspecies == rspecies)
+ {
+ cspecies = species;
+ return cspecies;
+ }
+ }
+ return cspecies;
+}
+
+void sub_80BF6D8(void)
+{
+ gUnknown_03005D38.var0 = sub_80BF720(gSaveBlock1.tvShows);
+ gSpecialVar_0x8006 = gUnknown_03005D38.var0;
+ if (gUnknown_03005D38.var0 == -1)
+ gScriptResult = 1;
+ else
+ gScriptResult = 0;
+}
+
+s8 sub_80BF720(TVShow tvShow[])
+{
+ u8 idx;
+
+ for (idx = 0; idx < 5; idx++)
+ {
+ if (tvShow[idx].common.var00 == 0)
+ return idx;
+ }
+ return -1;
+}
+
+s8 sub_80BF74C(TVShow tvShow[])
+{
+ s8 idx;
+
+ for (idx = 5; idx < 24; idx++)
+ {
+ if (tvShow[idx].common.var00 == 0)
+ return idx;
+ }
+ return -1;
+}
+
+bool8 sub_80BF77C(u16 value)
+{
+ if (Random() <= value)
+ return FALSE;
+ return TRUE;
+}
+
+void sub_80BF79C(TVShow *arg0)
+{
+ u8 i = Random() % 6;
+
+ while (1)
+ {
+ if (i == 6)
+ i = 0;
+ if (arg0->recentHappenings.var04[i] != 0xFFFF)
+ break;
+ i++;
+ }
+ EasyChat_GetWordText(gStringVar3, arg0->recentHappenings.var04[i]);
+}
+
+u8 sub_80BF7E8(struct TVShowNameRaterShow *arg0)
+{
+ u16 flagsum = 0;
+ u8 i = 0;
+
+ if (arg0->pokemonName[0] != 0xFF)
+ {
+ while (i < 11 && arg0->pokemonName[i] != 0xFF)
+ {
+ flagsum += arg0->pokemonName[i];
+ i++;
+ }
+ }
+ return flagsum & 0x7;
+}
+
+
+void sub_80BF820(u8 arg0, u8 arg1, u8 arg2, u16 arg3, u16 arg4, struct TVShowNameRaterShow *tvShow)
+{
+ u8 flags[3];
+ u16 nameLength;
+ u8 i;
+
+ for (i = 0; i < 3; i++)
+ flags[i] = EOS;
+
+ if (arg3 == 0)
+ {
+ nameLength = StringLength(tvShow->trainerName);
+ if (arg2 == 0)
+ {
+ flags[0] = tvShow->trainerName[arg1];
+ }
+ else if (arg2 == 1)
+ {
+ flags[0] = tvShow->trainerName[nameLength - arg1];
+ }
+ else if (arg2 == 2) {
+ flags[0] = tvShow->trainerName[arg1];
+ flags[1] = tvShow->trainerName[arg1 + 1];
+ }
+ else
+ {
+ flags[0] = tvShow->trainerName[nameLength - (arg1 + 2)];
+ flags[1] = tvShow->trainerName[nameLength - (arg1 + 1)];
+ }
+ }
+ else if (arg3 == 1)
+ {
+ nameLength = StringLength(tvShow->pokemonName);
+ if (arg2 == 0)
+ {
+ flags[0] = tvShow->pokemonName[arg1];
+ }
+ else if (arg2 == 1)
+ {
+ flags[0] = tvShow->pokemonName[nameLength - arg1];
+ }
+ else if (arg2 == 2)
+ {
+ flags[0] = tvShow->pokemonName[arg1];
+ flags[1] = tvShow->pokemonName[arg1 + 1];
+ }
+ else
+ {
+ flags[0] = tvShow->pokemonName[nameLength - (arg1 + 2)];
+ flags[1] = tvShow->pokemonName[nameLength - (arg1 + 1)];
+ }
+ }
+ else
+ {
+ nameLength = StringLength(gSpeciesNames[arg4]);
+ if (arg2 == 0)
+ {
+ flags[0] = gSpeciesNames[arg4][arg1];
+ }
+ else if (arg2 == 1)
+ {
+ flags[0] = gSpeciesNames[arg4][nameLength - arg1];
+ }
+ else if (arg2 == 2)
+ {
+ flags[0] = gSpeciesNames[arg4][arg1];
+ flags[1] = gSpeciesNames[arg4][arg1 + 1];
+ }
+ else
+ {
+ flags[0] = gSpeciesNames[arg4][nameLength - (arg1 + 2)];
+ flags[1] = gSpeciesNames[arg4][nameLength - (arg1 + 1)];
+ }
+ }
+ StringCopy(gUnknown_083D1464[arg0], flags);
+}
+
+bool8 sub_80BF974(void)
+{
+ u8 i;
+
+ for (i = 0; i < 5; i++)
+ {
+ if (gSaveBlock1.tvShows[i].common.var00 == gSpecialVar_0x8004)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool8 sub_80BF9B4(void)
+{
+ GetMonData(&(gPlayerParty[gSpecialVar_0x8004]), MON_DATA_NICKNAME, &gStringVar1);
+ if (!StringCompareWithoutExtCtrlCodes(gStringVar3, gStringVar1))
+ return FALSE;
+ sub_80BE478();
+ return TRUE;
+}
+
+void c2_080CC144(void);
+
+void sub_80BF9F8(void)
+{
+ u16 spec;
+ u16 gender;
+ u32 pval;
+
+ GetMonData(&(gPlayerParty[gSpecialVar_0x8004]), MON_DATA_NICKNAME, &gStringVar3);
+ GetMonData(&(gPlayerParty[gSpecialVar_0x8004]), MON_DATA_NICKNAME, &gStringVar2);
+ spec = GetMonData(&(gPlayerParty[gSpecialVar_0x8004]), MON_DATA_SPECIES, 0);
+ gender = GetMonGender(&(gPlayerParty[gSpecialVar_0x8004]));
+ pval = GetMonData(&(gPlayerParty[gSpecialVar_0x8004]), MON_DATA_PERSONALITY, 0);
+ DoNamingScreen(3, gStringVar2, spec, gender, pval, c2_080CC144);
+}
+
+void c2_080CC144(void)
+{
+ SetMonData(&(gPlayerParty[gSpecialVar_0x8004]), MON_DATA_NICKNAME, gStringVar2);
+ c2_exit_to_overworld_1_continue_scripts_restart_music();
+}
+
+void sub_80BFAE0(void)
+{
+ GetMonData(&(gPlayerParty[gSpecialVar_0x8004]), MON_DATA_NICKNAME, &gStringVar1);
+ StringGetEnd10(gStringVar1);
+}
+
+void sub_80BFB10(void)
+{
+ if (GetPlayerTrainerId() == GetMonData(&(gPlayerParty[gSpecialVar_0x8004]), MON_DATA_OT_ID, 0))
+ gScriptResult = 0;
+ else
+ gScriptResult = 1;
+}
+
+u8 sub_80BFB54(u8 arg0)
+{
+ if (arg0 == 0)
+ return 0;
+ else if (arg0 > 0 && arg0 <= 20)
+ return 2;
+ else if (arg0 > 20 && arg0 <= 40)
+ return 3;
+ else if (arg0 > 40 && arg0 <= 60)
+ return 4;
+ else
+ return 0;
+}
+
+u32 GetPlayerTrainerId(void)
+{
+ return (gSaveBlock2.playerTrainerId[3] << 24) | (gSaveBlock2.playerTrainerId[2] << 16) | (gSaveBlock2.playerTrainerId[1] << 8) | (gSaveBlock2.playerTrainerId[0]);
+}
+
+u8 CheckForBigMovieOrEmergencyNewsOnTV(void)
+{
+ if (gSaveBlock1.location.mapGroup != MAP_GROUP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F)
+ return 0;
+ if (gSaveBlock2.playerGender == MALE)
+ {
+ if (gSaveBlock1.location.mapNum != MAP_ID_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F)
+ return 0;
+ }
+ else
+ {
+ if (gSaveBlock1.location.mapNum != MAP_ID_LITTLEROOT_TOWN_MAYS_HOUSE_1F)
+ return 0;
+ }
+ if (FlagGet(SYS_TV_LATI) == 1)
+ return 1;
+ if (FlagGet(SYS_TV_HOME) == 1)
+ return 2;
+ return 1;
+}
+
+void GetMomOrDadStringForTVMessage(void)
+{
+ if (gSaveBlock1.location.mapGroup == MAP_GROUP_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F)
+ {
+ if (gSaveBlock2.playerGender == MALE)
+ {
+ if (gSaveBlock1.location.mapNum == MAP_ID_LITTLEROOT_TOWN_BRENDANS_HOUSE_1F)
+ {
+ StringCopy(gStringVar1, gOtherText_Mom);
+ VarSet(VAR_0x4003, 1);
+ }
+ }
+ else
+ {
+ if (gSaveBlock1.location.mapNum == MAP_ID_LITTLEROOT_TOWN_MAYS_HOUSE_1F)
+ {
+ StringCopy(gStringVar1, gOtherText_Mom);
+ VarSet(VAR_0x4003, 1);
+ }
+ }
+ }
+ if (VarGet(VAR_0x4003) == 1)
+ {
+ StringCopy(gStringVar1, gOtherText_Mom);
+ }
+ else if (VarGet(VAR_0x4003) == 2)
+ {
+ StringCopy(gStringVar1, gOtherText_Dad);
+ }
+ else if (VarGet(VAR_0x4003) > 2)
+ {
+ if (VarGet(VAR_0x4003) % 2 == 0)
+ StringCopy(gStringVar1, gOtherText_Mom);
+ else
+ StringCopy(gStringVar1, gOtherText_Dad);
+ }
+ else
+ {
+ if (Random() % 2 != 0)
+ {
+ StringCopy(gStringVar1, gOtherText_Mom);
+ VarSet(VAR_0x4003, 1);
+ }
+ else
+ {
+ StringCopy(gStringVar1, gOtherText_Dad);
+ VarSet(VAR_0x4003, 2);
+ }
+ }
+}
+
+void sub_80BFD20(void)
+{
+ VarSet(VAR_0x40BC, 0);
+ RemoveFieldObjectByLocalIdAndMap(5, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup);
+}
+
+typedef union ewramStruct_02007000
+{
+ TVShow tvshows[4][25];
+ struct UnknownSaveStruct2ABC unknown_2abc[4][16];
+} ewramStruct_02007000;
+
+void sub_80BFE24(TVShow arg0[25], TVShow arg1[25], TVShow arg2[25], TVShow arg3[25]);
+
+void sub_80C04A0(void);
+void sub_80C01D4(void);
+void sub_80C0408(void);
+
+void sub_80BFD44(u8 *arg0, u32 arg1, u8 arg2)
+{
+ u8 i;
+ ewramStruct_02007000 *ewramTVShows;
+
+ for (i = 0; i < 4; i++)
+ memcpy(&gUnknown_02007000.tvshows[i], &arg0[i * arg1], 25 * sizeof(TVShow));
+ ewramTVShows = &gUnknown_02007000;
+ switch (arg2)
+ {
+ case 0:
+ sub_80BFE24(gSaveBlock1.tvShows, ewramTVShows->tvshows[1], ewramTVShows->tvshows[2], ewramTVShows->tvshows[3]);
+ break;
+ case 1:
+ sub_80BFE24(ewramTVShows->tvshows[0], gSaveBlock1.tvShows, ewramTVShows->tvshows[2], ewramTVShows->tvshows[3]);
+ break;
+ case 2:
+ sub_80BFE24(ewramTVShows->tvshows[0], ewramTVShows->tvshows[1], gSaveBlock1.tvShows, ewramTVShows->tvshows[3]);
+ break;
+ case 3:
+ sub_80BFE24(ewramTVShows->tvshows[0], ewramTVShows->tvshows[1], ewramTVShows->tvshows[2], gSaveBlock1.tvShows);
+ break;
+ }
+ sub_80BF588(gSaveBlock1.tvShows);
+ sub_80C04A0();
+ sub_80BF588(gSaveBlock1.tvShows);
+ sub_80C01D4();
+ sub_80C0408();
+}
+
+s8 sub_80C019C(TVShow tvShows[]);
+bool8 sub_80BFF68(TVShow * tv1[25], TVShow * tv2[25], u8 idx);
+u8 sub_80C004C(TVShow *tv1, TVShow *tv2, u8 idx);
+u8 sub_80C00B4(TVShow *tv1, TVShow *tv2, u8 idx);
+u8 sub_80C0134(TVShow *tv1, TVShow *tv2, u8 idx);
+
+void sub_80BFE24(TVShow arg0[25], TVShow arg1[25], TVShow arg2[25], TVShow arg3[25])
+{
+ u8 i, j;
+ TVShow **argslist[4];
+
+ argslist[0] = &arg0;
+ argslist[1] = &arg1;
+ argslist[2] = &arg2;
+ argslist[3] = &arg3;
+ gUnknown_03000720 = GetLinkPlayerCount();
+ while (1)
+ {
+ for (i=0; i<gUnknown_03000720; i++)
+ {
+ if (i == 0)
+ gUnknown_020387E4 = i;
+ gUnknown_03000722 = sub_80C019C(argslist[i][0]);
+ if (gUnknown_03000722 == -1)
+ {
+ gUnknown_020387E4++;
+ if (gUnknown_020387E4 == gUnknown_03000720)
+ return;
+ }
+ else
+ {
+ for (j=0; j<gUnknown_03000720-1; j++)
+ {
+ gUnknown_03005D38.var0 = sub_80BF74C(argslist[(i + j + 1) % gUnknown_03000720][0]);
+ if (gUnknown_03005D38.var0 != -1
+ && sub_80BFF68(&argslist[(i + j + 1) % gUnknown_03000720][0], &argslist[i][0], (i + j + 1) % gUnknown_03000720) == 1)
+ break;
+ }
+ if (j == gUnknown_03000720 - 1)
+ sub_80BF55C(argslist[i][0], gUnknown_03000722);
+ }
+ }
+ }
+}
+
+bool8 sub_80BFF68(TVShow * arg1[25], TVShow * arg2[25], u8 idx)
+{
+ u8 value;
+ u8 switchval;
+ TVShow *tv1;
+ TVShow *tv2;
+
+ tv1 = *arg1;
+ tv2 = *arg2;
+ value = FALSE;
+ switchval = sub_80BFB54(tv2[gUnknown_03000722].common.var00);
+ switch (switchval)
+ {
+ case 2:
+ value = sub_80C004C(&tv1[gUnknown_03005D38.var0], &tv2[gUnknown_03000722], idx);
+ break;
+ case 3:
+ value = sub_80C00B4(&tv1[gUnknown_03005D38.var0], &tv2[gUnknown_03000722], idx);
+ break;
+ case 4:
+ value = sub_80C0134(&tv1[gUnknown_03005D38.var0], &tv2[gUnknown_03000722], idx);
+ break;
+ }
+ if (value == TRUE)
+ {
+ sub_80BF55C(tv2, gUnknown_03000722);
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+u8 sub_80C004C(TVShow *tv1, TVShow *tv2, u8 idx)
+{
+ u32 linkTrainerId = GetLinkPlayerTrainerId(idx);
+
+ if ((linkTrainerId & 0xFF) == tv2->common.trainerIdLo && ((linkTrainerId >> 8) & 0xFF) == tv2->common.trainerIdHi)
+ return FALSE;
+ tv2->common.trainerIdLo = tv2->common.srcTrainerIdLo;
+ tv2->common.trainerIdHi = tv2->common.srcTrainerIdHi;
+ tv2->common.srcTrainerIdLo = linkTrainerId & 0xFF;
+ tv2->common.srcTrainerIdHi = linkTrainerId >> 8;
+ *tv1 = *tv2;
+ tv1->common.var01 = 1;
+ return TRUE;
+}
+
+u8 sub_80C00B4(TVShow *tv1, TVShow *tv2, u8 idx)
+{
+ u32 linkTrainerId = GetLinkPlayerTrainerId(idx);
+ if ((linkTrainerId & 0xFF) == tv2->common.srcTrainerIdLo && ((linkTrainerId >> 8) & 0xFF) == tv2->common.srcTrainerIdHi)
+ return FALSE;
+ if ((linkTrainerId & 0xFF) == tv2->common.trainerIdLo && ((linkTrainerId >> 8) & 0xFF) == tv2->common.trainerIdHi)
+ return FALSE;
+ tv2->common.srcTrainerIdLo = tv2->common.srcTrainerId2Lo;
+ tv2->common.srcTrainerIdHi = tv2->common.srcTrainerId2Hi;
+ tv2->common.srcTrainerId2Lo = linkTrainerId & 0xFF;
+ tv2->common.srcTrainerId2Hi = linkTrainerId >> 8;
+ *tv1 = *tv2;
+ tv1->common.var01 = 1;
+ return TRUE;
+}
+
+u8 sub_80C0134(TVShow *tv1, TVShow *tv2, u8 idx)
+{
+ u32 linkTrainerId = GetLinkPlayerTrainerId(idx);
+ if ((linkTrainerId & 0xFF) == tv2->common.trainerIdLo && ((linkTrainerId >> 8) & 0xFF) == tv2->common.trainerIdHi)
+ return FALSE;
+ tv2->common.trainerIdLo = tv2->common.srcTrainerIdLo;
+ tv2->common.trainerIdHi = tv2->common.srcTrainerIdHi;
+ tv2->common.srcTrainerIdLo = linkTrainerId & 0xFF;
+ tv2->common.srcTrainerIdHi = linkTrainerId >> 8;
+ *tv1 = *tv2;
+ tv1->common.var01 = 1;
+ tv1->common.var16[0] = 1;
+ return TRUE;
+}
+
+s8 sub_80C019C(TVShow tvShows[])
+{
+ u8 i;
+ for (i = 0; i < 24; i++)
+ {
+ if (tvShows[i].common.var01 == 0 && (u8)(tvShows[i].common.var00 - 1) < 60)
+ return i;
+ }
+ return -1;
+}
+
+#ifdef NONMATCHING
+void sub_80C01D4(void)
+{
+ u16 i;
+ for (i=0; i<24; i++)
+ {
+ switch (gSaveBlock1.tvShows[i].common.var00)
+ {
+ case 0:
+ case TVSHOW_RECENT_HAPPENINGS:
+ case TVSHOW_SMART_SHOPPER:
+ case TVSHOW_MASS_OUTBREAK:
+ break;
+ case TVSHOW_FAN_CLUB_LETTER:
+ sub_80C03C8((&gSaveBlock1.tvShows[i])->fanclubLetter.species, i);
+ break;
+ case TVSHOW_PKMN_FAN_CLUB_OPINIONS:
+ sub_80C03C8((&gSaveBlock1.tvShows[i])->fanclubOpinions.var02, i);
+ break;
+ case TVSHOW_UNKN_SHOWTYPE_04:
+ sub_80C03C8((&gSaveBlock1.tvShows[i])->unkShow04.var06, i);
+ break;
+ case TVSHOW_NAME_RATER_SHOW:
+ sub_80C03C8((&gSaveBlock1.tvShows[i])->nameRaterShow.species, i);
+ sub_80C03C8((&gSaveBlock1.tvShows[i])->nameRaterShow.var1C, i);
+ break;
+ case TVSHOW_BRAVO_TRAINER_POKEMON_PROFILE:
+ sub_80C03C8((&gSaveBlock1.tvShows[i])->bravoTrainer.species, i);
+ break;
+ case TVSHOW_BRAVO_TRAINER_BATTLE_TOWER_PROFILE:
+ sub_80C03C8((&gSaveBlock1.tvShows[i])->bravoTrainerTower.species, i);
+ sub_80C03C8((&gSaveBlock1.tvShows[i])->bravoTrainerTower.defeatedSpecies, i);
+ break;
+ case TVSHOW_POKEMON_TODAY_CAUGHT:
+ sub_80C03C8((&gSaveBlock1.tvShows[i])->pokemonToday.species, i);
+ break;
+ case TVSHOW_POKEMON_TODAY_FAILED:
+ sub_80C03C8((&gSaveBlock1.tvShows[i])->pokemonTodayFailed.species, i);
+ sub_80C03C8((&gSaveBlock1.tvShows[i])->pokemonTodayFailed.species2, i);
+ break;
+ case TVSHOW_FISHING_ADVICE:
+ sub_80C03C8((&gSaveBlock1.tvShows[i])->pokemonAngler.var04, i);
+ break;
+ case TVSHOW_WORLD_OF_MASTERS:
+ sub_80C03C8((&gSaveBlock1.tvShows[i])->worldOfMasters.var08, i);
+ sub_80C03C8((&gSaveBlock1.tvShows[i])->worldOfMasters.var04, i);
+ break;
+ default:
+ sub_80C03A8(i);
+ }
+ }
+}
+#else
+__attribute__((naked))
+void sub_80C01D4(void) {
+ asm(".syntax unified\n\
+ push {r4-r6,lr}\n\
+ movs r6, 0\n\
+_080C01D8:\n\
+ ldr r0, _080C01F8 @ =gSaveBlock1\n\
+ lsls r2, r6, 3\n\
+ adds r1, r2, r6\n\
+ lsls r1, 2\n\
+ adds r1, r0\n\
+ ldr r0, _080C01FC @ =0x00002738\n\
+ adds r1, r0\n\
+ ldrb r0, [r1]\n\
+ cmp r0, 0x29\n\
+ bls _080C01EE\n\
+ b _default\n\
+_080C01EE:\n\
+ lsls r0, 2\n\
+ ldr r1, _080C0200 @ =_080C0204\n\
+ adds r0, r1\n\
+ ldr r0, [r0]\n\
+ mov pc, r0\n\
+ .align 2, 0\n\
+_080C01F8: .4byte gSaveBlock1\n\
+_080C01FC: .4byte 0x00002738\n\
+_080C0200: .4byte _080C0204\n\
+ .align 2, 0\n\
+_080C0204:\n\
+ .4byte _break\n\
+ .4byte _fanclubLetter @ TVSHOW_FAN_CLUB_LETTER\n\
+ .4byte _break @ TVSHOW_RECENT_HAPPENINGS\n\
+ .4byte _fanclubOpinions @ TVSHOW_PKMN_FAN_CLUB_OPINIONS\n\
+ .4byte _showtype4 @ TVSHOW_UNKN_SHOWTYPE_04\n\
+ .4byte _nameRater @ TVSHOW_NAME_RATER_SHOW\n\
+ .4byte _bravoTrainerContest @ TVSHOW_BRAVO_TRAINER_POKEMON_PROFILE\n\
+ .4byte _bravoTrainerTower @ TVSHOW_BRAVO_TRAINER_BATTLE_TOWER_PROFILE\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _pokemonTodayS @ TVSHOW_POKEMON_TODAY_CAUGHT\n\
+ .4byte _break @ TVSHOW_SMART_SHOPPER\n\
+ .4byte _pokemonTodayF @ TVSHOW_POKEMON_TODAY_FAILED\n\
+ .4byte _fishing @ TVSHOW_FISHING_ADVICE\n\
+ .4byte _worldOfMasters @ TVSHOW_WORLD_OF_MASTERS\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _default\n\
+ .4byte _break @ TVSHOW_MASS_OUTBREAK\n\
+_fanclubLetter:\n\
+ adds r0, r2, r6\n\
+ lsls r0, 2\n\
+ ldr r1, _080C02B8 @ =gSaveBlock1 + 0x2738\n\
+ adds r0, r1\n\
+ ldrh r0, [r0, 0x2]\n\
+ b _checkSpecies1 @ sub_80C03C8(r0, i)\n\
+ .align 2, 0\n\
+_080C02B8: .4byte gSaveBlock1 + 0x2738\n\
+_fanclubOpinions:\n\
+ adds r0, r2, r6\n\
+ lsls r0, 2\n\
+ ldr r1, _080C02C8 @ =gSaveBlock1 + 0x2738\n\
+ adds r0, r1\n\
+ ldrh r0, [r0, 0x2]\n\
+ b _checkSpecies1 @ sub_80C03C8(r0, i)\n\
+ .align 2, 0\n\
+_080C02C8: .4byte gSaveBlock1 + 0x2738\n\
+_showtype4:\n\
+ adds r0, r2, r6\n\
+ lsls r0, 2\n\
+ ldr r1, _080C02D8 @ =gSaveBlock1 + 0x2738\n\
+ adds r0, r1\n\
+ ldrh r0, [r0, 0x6]\n\
+ b _checkSpecies1 @ sub_80C03C8(r0, i)\n\
+ .align 2, 0\n\
+_080C02D8: .4byte gSaveBlock1 + 0x2738\n\
+_nameRater:\n\
+ adds r4, r2, r6\n\
+ lsls r4, 2\n\
+ ldr r0, _080C02F4 @ =gSaveBlock1 + 0x2738\n\
+ adds r4, r0\n\
+ ldrh r0, [r4, 0x2]\n\
+ lsls r5, r6, 24\n\
+ lsrs r5, 24\n\
+ adds r1, r5, 0\n\
+ bl sub_80C03C8\n\
+ ldrh r0, [r4, 0x1C]\n\
+ b _checkSpecies2 @ sub_80C03C8(r0, i)\n\
+ .align 2, 0\n\
+_080C02F4: .4byte gSaveBlock1 + 0x2738\n\
+_bravoTrainerContest:\n\
+ adds r0, r2, r6\n\
+ lsls r0, 2\n\
+ ldr r1, _080C0304 @ =gSaveBlock1 + 0x2738\n\
+ adds r0, r1\n\
+ ldrh r0, [r0, 0x2]\n\
+ b _checkSpecies1 @ sub_80C03C8(r0, i)\n\
+ .align 2, 0\n\
+_080C0304: .4byte gSaveBlock1 + 0x2738\n\
+_bravoTrainerTower:\n\
+ adds r4, r2, r6\n\
+ lsls r4, 2\n\
+ ldr r0, _080C0320 @ =gSaveBlock1 + 0x2738\n\
+ adds r4, r0\n\
+ ldrh r0, [r4, 0xA]\n\
+ lsls r5, r6, 24\n\
+ lsrs r5, 24\n\
+ adds r1, r5, 0\n\
+ bl sub_80C03C8\n\
+ ldrh r0, [r4, 0x14]\n\
+ b _checkSpecies2 @ sub_80C03C8(r0, i)\n\
+ .align 2, 0\n\
+_080C0320: .4byte gSaveBlock1 + 0x2738\n\
+_pokemonTodayS:\n\
+ adds r0, r2, r6\n\
+ lsls r0, 2\n\
+ ldr r1, _080C0330 @ =gSaveBlock1 + 0x2738\n\
+ adds r0, r1\n\
+ ldrh r0, [r0, 0x10]\n\
+ b _checkSpecies1 @ sub_80C03C8(r0, i)\n\
+ .align 2, 0\n\
+_080C0330: .4byte gSaveBlock1 + 0x2738\n\
+_pokemonTodayF:\n\
+ adds r4, r2, r6\n\
+ lsls r4, 2\n\
+ ldr r0, _080C034C @ =gSaveBlock1 + 0x2738\n\
+ adds r4, r0\n\
+ ldrh r0, [r4, 0xC]\n\
+ lsls r5, r6, 24\n\
+ lsrs r5, 24\n\
+ adds r1, r5, 0\n\
+ bl sub_80C03C8\n\
+ ldrh r0, [r4, 0xE]\n\
+ b _checkSpecies2 @ sub_80C03C8(r0, i)\n\
+ .align 2, 0\n\
+_080C034C: .4byte gSaveBlock1 + 0x2738\n\
+_fishing:\n\
+ adds r0, r2, r6\n\
+ lsls r0, 2\n\
+ ldr r1, _080C0364 @ =gSaveBlock1 + 0x2738\n\
+ adds r0, r1\n\
+ ldrh r0, [r0, 0x4]\n\
+_checkSpecies1:\n\
+ lsls r1, r6, 24\n\
+ lsrs r1, 24\n\
+ bl sub_80C03C8\n\
+ b _break\n\
+ .align 2, 0\n\
+_080C0364: .4byte gSaveBlock1 + 0x2738\n\
+_worldOfMasters:\n\
+ adds r4, r2, r6\n\
+ lsls r4, 2\n\
+ ldr r0, _080C0388 @ =gSaveBlock1 + 0x2738\n\
+ adds r4, r0\n\
+ ldrh r0, [r4, 0x8]\n\
+ lsls r5, r6, 24\n\
+ lsrs r5, 24\n\
+ adds r1, r5, 0\n\
+ bl sub_80C03C8\n\
+ ldrh r0, [r4, 0x4]\n\
+_checkSpecies2:\n\
+ adds r1, r5, 0\n\
+ bl sub_80C03C8\n\
+ b _break\n\
+ .align 2, 0\n\
+_080C0388: .4byte gSaveBlock1 + 0x2738\n\
+_default:\n\
+ lsls r0, r6, 24\n\
+ lsrs r0, 24\n\
+ bl sub_80C03A8\n\
+_break:\n\
+ adds r0, r6, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r6, r0, 16\n\
+ cmp r6, 0x17\n\
+ bhi _080C03A0\n\
+ b _080C01D8\n\
+_080C03A0:\n\
+ pop {r4-r6}\n\
+ pop {r0}\n\
+ bx r0\n\
+.syntax divided\n");
+}
+#endif
+
+void sub_80C03A8(u8 showidx)
+{
+ gSaveBlock1.tvShows[showidx].common.var01 = 0;
+}
+
+void sub_80C03C8(u16 species, u8 showidx)
+{
+ if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), 0) == 0)
+ gSaveBlock1.tvShows[showidx].common.var01 = 0;
+}
+
+void sub_80C0408(void)
+{
+ u16 i;
+
+ if (FlagGet(SYS_GAME_CLEAR) == TRUE)
+ return;
+ for (i = 0; i < 24; i++)
+ {
+ if (gSaveBlock1.tvShows[i].common.var00 == TVSHOW_BRAVO_TRAINER_BATTLE_TOWER_PROFILE)
+ gSaveBlock1.tvShows[i].common.var01 = 0;
+ else if (gSaveBlock1.tvShows[i].common.var00 == TVSHOW_MASS_OUTBREAK)
+ gSaveBlock1.tvShows[i].common.var01 = 0;
+ }
+}
+
+void sub_80C045C(void)
+{
+ u8 i;
+
+ for (i = 0; i < 5; i++)
+ {
+ if (sub_80BFB54(gSaveBlock1.tvShows[i].common.var00) == 2)
+ gSaveBlock1.tvShows[i].common.var01 = 0;
+ }
+}
+
+void sub_80C04A0(void)
+{
+ s8 showIdx;
+ s8 count;
+ count = 0;
+
+ for (showIdx = 5; showIdx < 24; showIdx++)
+ {
+ if (gSaveBlock1.tvShows[showIdx].common.var00 == 0)
+ count++;
+ }
+ for (showIdx = 0; showIdx < 5 - count; showIdx++)
+ sub_80BF55C(gSaveBlock1.tvShows, showIdx+5);
+}
+
+void sub_80C05C4(struct UnknownSaveStruct2ABC[16], struct UnknownSaveStruct2ABC[16], struct UnknownSaveStruct2ABC[16], struct UnknownSaveStruct2ABC[16]);
+void sub_80C0750(void);
+void sub_80C0788(void);
+s8 sub_80C0730(struct UnknownSaveStruct2ABC[16], u8);
+void sub_80C06BC(struct UnknownSaveStruct2ABC *[16], struct UnknownSaveStruct2ABC *[16]);
+
+void sub_80C0514(void *a0, u32 a1, u8 a2)
+{
+ ewramStruct_02007000 *struct02007000;
+ u8 i;
+
+ for (i = 0; i < 4; i++)
+ memcpy(gUnknown_02007000.unknown_2abc[i], a0 + i * a1, 64);
+ struct02007000 = &gUnknown_02007000;
+ switch (a2)
+ {
+ case 0:
+ sub_80C05C4(gSaveBlock1.unknown_2ABC, struct02007000->unknown_2abc[1], struct02007000->unknown_2abc[2], struct02007000->unknown_2abc[3]);
+ break;
+ case 1:
+ sub_80C05C4(struct02007000->unknown_2abc[0], gSaveBlock1.unknown_2ABC, struct02007000->unknown_2abc[2], struct02007000->unknown_2abc[3]);
+ break;
+ case 2:
+ sub_80C05C4(struct02007000->unknown_2abc[0], struct02007000->unknown_2abc[1], gSaveBlock1.unknown_2ABC, struct02007000->unknown_2abc[3]);
+ break;
+ case 3:
+ sub_80C05C4(struct02007000->unknown_2abc[0], struct02007000->unknown_2abc[1], struct02007000->unknown_2abc[2], gSaveBlock1.unknown_2ABC);
+ break;
+ }
+ sub_80C0750();
+ sub_80C0788();
+}
+
+void sub_80C05C4(struct UnknownSaveStruct2ABC a0[16], struct UnknownSaveStruct2ABC a1[16], struct UnknownSaveStruct2ABC a2[16], struct UnknownSaveStruct2ABC a3[16])
+{
+ u8 i;
+ u8 j;
+ u8 k;
+ struct UnknownSaveStruct2ABC ** arglist[4];
+
+ arglist[0] = &a0;
+ arglist[1] = &a1;
+ arglist[2] = &a2;
+ arglist[3] = &a3;
+ gUnknown_03000721 = GetLinkPlayerCount();
+ for (i = 0; i < 16; i++)
+ {
+ for (j = 0; j < gUnknown_03000721; j++)
+ {
+ gUnknown_03000722 = sub_80C0730(*arglist[j], i);
+ if (gUnknown_03000722 != -1)
+ {
+ for (k = 0; k < gUnknown_03000721-1; k++)
+ {
+ gUnknown_03005D38.var0 = sub_80BEBC8(*arglist[(j + k + 1) % gUnknown_03000721]);
+ if (gUnknown_03005D38.var0 != -1)
+ sub_80C06BC(arglist[(j + k + 1) % gUnknown_03000721], arglist[j]);
+ }
+ }
+ }
+ }
+}
+
+void sub_80C06BC(struct UnknownSaveStruct2ABC *arg0[16], struct UnknownSaveStruct2ABC *arg1[16])
+{
+ struct UnknownSaveStruct2ABC *str0;
+ struct UnknownSaveStruct2ABC *str1;
+
+ str0 = arg0[0];
+ str1 = arg1[0];
+ str1 += gUnknown_03000722;
+ sub_80C06E8(str0, str1, gUnknown_03005D38.var0);
+}
+
+bool8 sub_80C06E8(struct UnknownSaveStruct2ABC *arg0, struct UnknownSaveStruct2ABC *arg1, s8 arg2)
+{
+ u8 i;
+
+ if (arg1->val0 == 0)
+ return FALSE;
+ for (i = 0; i < 16; i++)
+ {
+ if (arg0[i].val0 == arg1->val0)
+ return FALSE;
+ }
+ arg0[arg2].val0 = arg1->val0;
+ arg0[arg2].val1 = 1;
+ arg0[arg2].val2 = arg1->val2;
+ return TRUE;
+}
+
+s8 sub_80C0730(struct UnknownSaveStruct2ABC *arg0, u8 arg1)
+{
+ if (arg0[arg1].val0 == 0)
+ return -1;
+ return arg1;
+}
+
+void sub_80C0750(void)
+{
+ u8 i;
+
+ for (i = 0; i < 16; i++)
+ {
+ if (gSaveBlock1.unknown_2ABC[i].val0 > 3)
+ sub_80BEC10(i);
+ }
+ sub_80BEC40();
+}
+
+void sub_80C0788(void)
+{
+ u8 i;
+
+ if (FlagGet(SYS_GAME_CLEAR) != 1)
+ {
+ for (i = 0; i < 16; i++)
+ gSaveBlock1.unknown_2ABC[i].val1 = 0;
+ }
+}
+
+void DoTVShow(void)
+{
+ if (gSaveBlock1.tvShows[gSpecialVar_0x8004].common.var01 != 0)
+ {
+ switch (gSaveBlock1.tvShows[gSpecialVar_0x8004].common.var00)
+ {
+ case TVSHOW_FAN_CLUB_LETTER:
+ DoTVShowPokemonFanClubLetter();
+ break;
+ case TVSHOW_RECENT_HAPPENINGS:
+ DoTVShowRecentHappenings();
+ break;
+ case TVSHOW_PKMN_FAN_CLUB_OPINIONS:
+ DoTVShowPokemonFanClubOpinions();
+ break;
+ case TVSHOW_UNKN_SHOWTYPE_04:
+ nullsub_22();
+ break;
+ case TVSHOW_MASS_OUTBREAK:
+ DoTVShowPokemonNewsMassOutbreak();
+ break;
+ case TVSHOW_BRAVO_TRAINER_POKEMON_PROFILE:
+ DoTVShowBravoTrainerPokemonProfile();
+ break;
+ case TVSHOW_BRAVO_TRAINER_BATTLE_TOWER_PROFILE:
+ DoTVShowBravoTrainerBattleTowerProfile();
+ break;
+ case TVSHOW_POKEMON_TODAY_CAUGHT:
+ DoTVShowPokemonTodaySuccessfulCapture();
+ break;
+ case TVSHOW_SMART_SHOPPER:
+ DoTVShowTodaysSmartShopper();
+ break;
+ case TVSHOW_NAME_RATER_SHOW:
+ DoTVShowTheNameRaterShow();
+ break;
+ case TVSHOW_POKEMON_TODAY_FAILED:
+ DoTVShowPokemonTodayFailedCapture();
+ break;
+ case TVSHOW_FISHING_ADVICE:
+ DoTVShowPokemonAngler();
+ break;
+ case TVSHOW_WORLD_OF_MASTERS:
+ DoTVShowTheWorldOfMasters();
+ break;
+ }
+ }
+}
+
+void TVShowConvertInternationalString(u8 *dest, u8 *src, u8 language)
+{
+ StringCopy(dest, src);
+ if (language < LANGUAGE_ENGLISH)
+ ConvertInternationalString(dest, LANGUAGE_JAPANESE);
+}
+
+void DoTVShowBravoTrainerPokemonProfile(void)
+{
+ struct TVShowBravoTrainerPokemonProfiles *bravoTrainer = &gSaveBlock1.tvShows[gSpecialVar_0x8004].bravoTrainer;
+ u8 state;
+
+ gScriptResult = 0;
+ state = gUnknown_020387E8;
+ switch(state)
+ {
+ case 0:
+ TVShowConvertInternationalString(gStringVar1, bravoTrainer->playerName, bravoTrainer->language);
+ CopyContestCategoryToStringVar(1, bravoTrainer->contestCategory);
+ sub_80BEF10(2, bravoTrainer->contestRank);
+ if (!StringCompareWithoutExtCtrlCodes(gSpeciesNames[bravoTrainer->species], bravoTrainer->pokemonNickname))
+ gUnknown_020387E8 = 8;
+ else
+ gUnknown_020387E8 = 1;
+ break;
+ case 1:
+ StringCopy(gStringVar1, gSpeciesNames[bravoTrainer->species]);
+ TVShowConvertInternationalString(gStringVar2, bravoTrainer->pokemonNickname, bravoTrainer->var1f);
+ CopyContestCategoryToStringVar(2, bravoTrainer->contestCategory);
+ gUnknown_020387E8 = 2;
+ break;
+ case 2:
+ TVShowConvertInternationalString(gStringVar1, bravoTrainer->playerName, bravoTrainer->language);
+ if (bravoTrainer->contestResult == 0) // placed first
+ gUnknown_020387E8 = 3;
+ else
+ gUnknown_020387E8 = 4;
+ break;
+ case 3:
+ TVShowConvertInternationalString(gStringVar1, bravoTrainer->playerName, bravoTrainer->language);
+ EasyChat_GetWordText(gStringVar2, bravoTrainer->var04[0]);
+ sub_80BF088(2, bravoTrainer->contestResult + 1);
+ gUnknown_020387E8 = 5;
+ break;
+ case 4:
+ TVShowConvertInternationalString(gStringVar1, bravoTrainer->playerName, bravoTrainer->language);
+ EasyChat_GetWordText(gStringVar2, bravoTrainer->var04[0]);
+ sub_80BF088(2, bravoTrainer->contestResult + 1);
+ gUnknown_020387E8 = 5;
+ break;
+ case 5:
+ TVShowConvertInternationalString(gStringVar1, bravoTrainer->playerName, bravoTrainer->language);
+ CopyContestCategoryToStringVar(1, bravoTrainer->contestCategory);
+ EasyChat_GetWordText(gStringVar3, bravoTrainer->var04[1]);
+ if (bravoTrainer->var14)
+ gUnknown_020387E8 = 6;
+ else
+ gUnknown_020387E8 = 7;
+ break;
+ case 6:
+ StringCopy(gStringVar1, gSpeciesNames[bravoTrainer->species]);
+ StringCopy(gStringVar2, gMoveNames[bravoTrainer->var14]);
+ EasyChat_GetWordText(gStringVar3, bravoTrainer->var04[1]);
+ gUnknown_020387E8 = 7;
+ break;
+ case 7:
+ TVShowConvertInternationalString(gStringVar1, bravoTrainer->playerName, bravoTrainer->language);
+ StringCopy(gStringVar2, gSpeciesNames[bravoTrainer->species]);
+ TVShowDone();
+ break;
+ case 8:
+ StringCopy(gStringVar1, gSpeciesNames[bravoTrainer->species]);
+ gUnknown_020387E8 = 2;
+ break;
+ }
+ ShowFieldMessage(gTVBravoTrainerTextGroup[state]);
+}
+
+void DoTVShowBravoTrainerBattleTowerProfile(void)
+{
+ struct TVShowBravoTrainerBattleTowerSpotlight *bravoTrainerTower = &gSaveBlock1.tvShows[gSpecialVar_0x8004].bravoTrainerTower;
+ u8 state;
+
+ gScriptResult = 0;
+ state = gUnknown_020387E8;
+ switch(state)
+ {
+ case 0:
+ TVShowConvertInternationalString(gStringVar1, bravoTrainerTower->trainerName, bravoTrainerTower->language);
+ StringCopy(gStringVar2, gSpeciesNames[bravoTrainerTower->species]);
+ if (bravoTrainerTower->var16 >= 7)
+ gUnknown_020387E8 = 1;
+ else
+ gUnknown_020387E8 = 2;
+ break;
+ case 1:
+ sub_80BF088(0, bravoTrainerTower->btLevel);
+ sub_80BF088(1, bravoTrainerTower->var16);
+ if (bravoTrainerTower->var1c == 1)
+ gUnknown_020387E8 = 3;
+ else
+ gUnknown_020387E8 = 4;
+ break;
+ case 2:
+ TVShowConvertInternationalString(gStringVar1, bravoTrainerTower->pokemonName, bravoTrainerTower->language);
+ sub_80BF088(1, bravoTrainerTower->var16 + 1);
+ if (bravoTrainerTower->var1b == 0)
+ gUnknown_020387E8 = 5;
+ else
+ gUnknown_020387E8 = 6;
+ break;
+ case 3:
+ TVShowConvertInternationalString(gStringVar1, bravoTrainerTower->pokemonName, bravoTrainerTower->language);
+ StringCopy(gStringVar2, gSpeciesNames[bravoTrainerTower->defeatedSpecies]);
+ if (bravoTrainerTower->var1b == 0)
+ gUnknown_020387E8 = 5;
+ else
+ gUnknown_020387E8 = 6;
+ break;
+ case 4:
+ TVShowConvertInternationalString(gStringVar1, bravoTrainerTower->pokemonName, bravoTrainerTower->language);
+ StringCopy(gStringVar2, gSpeciesNames[bravoTrainerTower->defeatedSpecies]);
+ if (bravoTrainerTower->var1b == 0)
+ gUnknown_020387E8 = 5;
+ else
+ gUnknown_020387E8 = 6;
+ break;
+ case 5:
+ TVShowConvertInternationalString(gStringVar1, bravoTrainerTower->pokemonName, bravoTrainerTower->language);
+ gUnknown_020387E8 = 11;
+ break;
+ case 6:
+ TVShowConvertInternationalString(gStringVar1, bravoTrainerTower->pokemonName, bravoTrainerTower->language);
+ gUnknown_020387E8 = 11;
+ break;
+ case 7:
+ gUnknown_020387E8 = 11;
+ break;
+ case 8:
+ case 9:
+ case 10:
+ TVShowConvertInternationalString(gStringVar1, bravoTrainerTower->trainerName, bravoTrainerTower->language);
+ gUnknown_020387E8 = 11;
+ break;
+ case 11:
+ EasyChat_GetWordText(gStringVar1, bravoTrainerTower->var18[0]);
+ if (bravoTrainerTower->var1b == 0)
+ gUnknown_020387E8 = 12;
+ else
+ gUnknown_020387E8 = 13;
+ break;
+ case 12:
+ case 13:
+ EasyChat_GetWordText(gStringVar1, bravoTrainerTower->var18[0]);
+ TVShowConvertInternationalString(gStringVar2, bravoTrainerTower->trainerName, bravoTrainerTower->language);
+ TVShowConvertInternationalString(gStringVar3, bravoTrainerTower->pokemonName, bravoTrainerTower->language);
+ gUnknown_020387E8 = 14;
+ break;
+ case 14:
+ TVShowConvertInternationalString(gStringVar1, bravoTrainerTower->trainerName, bravoTrainerTower->language);
+ StringCopy(gStringVar2, gSpeciesNames[bravoTrainerTower->species]);
+ TVShowDone();
+ break;
+ }
+ ShowFieldMessage(gTVBravoTrainerBattleTowerTextGroup[state]);
+}
+
+void DoTVShowTodaysSmartShopper(void)
+{
+ struct TVShowSmartShopper *smartShopper = &gSaveBlock1.tvShows[gSpecialVar_0x8004].smartshopperShow;
+ u8 state;
+
+ gScriptResult = 0;
+ state = gUnknown_020387E8;
+ switch(state)
+ {
+ case 0:
+ TVShowConvertInternationalString(gStringVar1, smartShopper->playerName, smartShopper->language);
+ GetMapSectionName(gStringVar2, smartShopper->shopLocation, 0);
+ if (smartShopper->itemAmounts[0] >= 0xff)
+ gUnknown_020387E8 = 11;
+ else
+ gUnknown_020387E8 = 1;
+ break;
+ case 1:
+ TVShowConvertInternationalString(gStringVar1, smartShopper->playerName, smartShopper->language);
+ StringCopy(gStringVar2, ItemId_GetItem(smartShopper->itemIds[0])->name);
+ sub_80BF088(2, smartShopper->itemAmounts[0]);
+ gUnknown_020387E8 += (Random() % 4) + 1;
+ break;
+ case 2:
+ case 4:
+ case 5:
+ if (smartShopper->itemIds[1] != 0)
+ gUnknown_020387E8 = 6;
+ else
+ gUnknown_020387E8 = 10;
+ break;
+ case 3:
+ sub_80BF088(2, smartShopper->itemAmounts[0] + 1);
+ if (smartShopper->itemIds[1] != 0)
+ gUnknown_020387E8 = 6;
+ else
+ gUnknown_020387E8 = 10;
+ break;
+ case 6:
+ StringCopy(gStringVar2, ItemId_GetItem(smartShopper->itemIds[1])->name);
+ sub_80BF088(2, smartShopper->itemAmounts[1]);
+ if (smartShopper->itemIds[2] != 0)
+ gUnknown_020387E8 = 7;
+ else if (smartShopper->priceReduced == 1)
+ gUnknown_020387E8 = 8;
+ else
+ gUnknown_020387E8 = 9;
+ break;
+ case 7:
+ StringCopy(gStringVar2, ItemId_GetItem(smartShopper->itemIds[2])->name);
+ sub_80BF088(2, smartShopper->itemAmounts[2]);
+ if (smartShopper->priceReduced == 1)
+ gUnknown_020387E8 = 8;
+ else
+ gUnknown_020387E8 = 9;
+ break;
+ case 8:
+ if (smartShopper->itemAmounts[0] < 0xff)
+ gUnknown_020387E8 = 9;
+ else
+ gUnknown_020387E8 = 12;
+ break;
+ case 9:
+ sub_80BF154(1, smartShopper);
+ TVShowDone();
+ break;
+ case 10:
+ if (smartShopper->priceReduced == 1)
+ gUnknown_020387E8 = 8;
+ else
+ gUnknown_020387E8 = 9;
+ break;
+ case 11:
+ TVShowConvertInternationalString(gStringVar1, smartShopper->playerName, smartShopper->language);
+ StringCopy(gStringVar2, ItemId_GetItem(smartShopper->itemIds[0])->name);
+ if (smartShopper->priceReduced == 1)
+ gUnknown_020387E8 = 8;
+ else
+ gUnknown_020387E8 = 12;
+ break;
+ case 12:
+ TVShowConvertInternationalString(gStringVar1, smartShopper->playerName, smartShopper->language);
+ TVShowDone();
+ break;
+ }
+ ShowFieldMessage(gTVSmartShopperTextGroup[state]);
+}
+
+void DoTVShowTheNameRaterShow(void)
+{
+ struct TVShowNameRaterShow *nameRaterShow = &gSaveBlock1.tvShows[gSpecialVar_0x8004].nameRaterShow;
+ u8 state;
+
+ gScriptResult = 0;
+ state = gUnknown_020387E8;
+ switch (state)
+ {
+ case 0:
+ TVShowConvertInternationalString(gStringVar1, nameRaterShow->trainerName, nameRaterShow->language);
+ StringCopy(gStringVar2, gSpeciesNames[nameRaterShow->species]);
+ TVShowConvertInternationalString(gStringVar3, nameRaterShow->pokemonName, nameRaterShow->pokemonNameLanguage);
+ gUnknown_020387E8 = sub_80BF7E8(nameRaterShow) + 1;
+ break;
+ case 1:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ if (nameRaterShow->random == 0)
+ gUnknown_020387E8 = 9;
+ else if (nameRaterShow->random == 1)
+ gUnknown_020387E8 = 10;
+ else if (nameRaterShow->random == 2)
+ gUnknown_020387E8 = 11;
+ break;
+ case 2:
+ TVShowConvertInternationalString(gStringVar1, nameRaterShow->trainerName, nameRaterShow->language);
+ if (nameRaterShow->random == 0)
+ gUnknown_020387E8 = 9;
+ else if (nameRaterShow->random == 1)
+ gUnknown_020387E8 = 10;
+ else if (nameRaterShow->random == 2)
+ gUnknown_020387E8 = 11;
+ break;
+ case 9:
+ case 10:
+ case 11:
+ sub_80BF820(0, 1, 0, 1, 0, nameRaterShow);
+ TVShowConvertInternationalString(gStringVar3, gStringVar1, nameRaterShow->pokemonNameLanguage);
+ sub_80BF820(0, 0, 0, 1, 0, nameRaterShow);
+ TVShowConvertInternationalString(gStringVar2, gStringVar1, nameRaterShow->pokemonNameLanguage);
+ TVShowConvertInternationalString(gStringVar1, nameRaterShow->pokemonName, nameRaterShow->pokemonNameLanguage);
+ gUnknown_020387E8 = 12;
+ break;
+ case 13:
+ sub_80BF820(0, 0, 3, 1, 0, nameRaterShow);
+ TVShowConvertInternationalString(gStringVar3, gStringVar1, nameRaterShow->pokemonNameLanguage);
+ sub_80BF820(0, 0, 2, 0, 0, nameRaterShow);
+ TVShowConvertInternationalString(gStringVar2, gStringVar1, nameRaterShow->language);
+ TVShowConvertInternationalString(gStringVar1, nameRaterShow->trainerName, nameRaterShow->language);
+ gUnknown_020387E8 = 14;
+ break;
+ case 14:
+ sub_80BF820(0, 0, 3, 0, 0, nameRaterShow);
+ TVShowConvertInternationalString(gStringVar3, gStringVar1, nameRaterShow->language);
+ sub_80BF820(0, 0, 2, 1, 0, nameRaterShow);
+ TVShowConvertInternationalString(gStringVar2, gStringVar1, nameRaterShow->pokemonNameLanguage);
+ TVShowConvertInternationalString(gStringVar1, nameRaterShow->trainerName, nameRaterShow->language);
+ gUnknown_020387E8 = 18;
+ break;
+ case 15:
+ sub_80BF820(1, 0, 2, 1, 0, nameRaterShow);
+ TVShowConvertInternationalString(gStringVar1, gStringVar2, nameRaterShow->pokemonNameLanguage);
+ StringCopy(gStringVar2, gSpeciesNames[nameRaterShow->species]);
+ sub_80BF820(2, 0, 3, 2, nameRaterShow->species, nameRaterShow);
+ gUnknown_020387E8 = 16;
+ break;
+ case 16:
+ sub_80BF820(0, 0, 3, 1, 0, nameRaterShow);
+ TVShowConvertInternationalString(gStringVar3, gStringVar1, nameRaterShow->pokemonNameLanguage);
+ sub_80BF820(0, 0, 2, 2, nameRaterShow->species, nameRaterShow);
+ gUnknown_020387E8 = 17;
+ break;
+ case 17:
+ sub_80BF820(1, 0, 2, 1, 0, nameRaterShow);
+ TVShowConvertInternationalString(gStringVar1, gStringVar2, nameRaterShow->pokemonNameLanguage);
+ sub_80BF820(2, 0, 3, 2, nameRaterShow->var1C, nameRaterShow);
+ StringCopy(gStringVar2, gSpeciesNames[nameRaterShow->var1C]);
+ gUnknown_020387E8 = 18;
+ break;
+ case 12:
+ state = 18;
+ gUnknown_020387E8 = 18;
+ case 18:
+ TVShowConvertInternationalString(gStringVar1, nameRaterShow->pokemonName, nameRaterShow->pokemonNameLanguage);
+ TVShowConvertInternationalString(gStringVar2, nameRaterShow->trainerName, nameRaterShow->language);
+ TVShowDone();
+ break;
+ }
+ ShowFieldMessage(gTVNameRaterTextGroup[state]);
+}
+
+void DoTVShowPokemonTodaySuccessfulCapture(void)
+{
+ struct TVShowPokemonToday *pokemonToday = &gSaveBlock1.tvShows[gSpecialVar_0x8004].pokemonToday;
+ u8 state;
+
+ gScriptResult = 0;
+ state = gUnknown_020387E8;
+ switch (state)
+ {
+ case 0:
+ TVShowConvertInternationalString(gStringVar1, pokemonToday->playerName, pokemonToday->language);
+ StringCopy(gStringVar2, gSpeciesNames[pokemonToday->species]);
+ TVShowConvertInternationalString(gStringVar3, pokemonToday->nickname, pokemonToday->language2);
+ if (pokemonToday->ball == ITEM_MASTER_BALL)
+ gUnknown_020387E8 = 5;
+ else
+ gUnknown_020387E8 = 1;
+ break;
+ case 1:
+ gUnknown_020387E8 = 2;
+ break;
+ case 2:
+ StringCopy(gStringVar2, ItemId_GetItem(pokemonToday->ball)->name);
+ sub_80BF088(2, pokemonToday->var12);
+ if (pokemonToday->var12 < 4)
+ gUnknown_020387E8 = 3;
+ else
+ gUnknown_020387E8 = 4;
+ break;
+ case 3:
+ TVShowConvertInternationalString(gStringVar1, pokemonToday->playerName, pokemonToday->language);
+ StringCopy(gStringVar2, gSpeciesNames[pokemonToday->species]);
+ TVShowConvertInternationalString(gStringVar3, pokemonToday->nickname, pokemonToday->language2);
+ gUnknown_020387E8 = 6;
+ break;
+ case 4:
+ gUnknown_020387E8 = 6;
+ break;
+ case 5:
+ TVShowConvertInternationalString(gStringVar1, pokemonToday->playerName, pokemonToday->language);
+ StringCopy(gStringVar2, gSpeciesNames[pokemonToday->species]);
+ gUnknown_020387E8 = 6;
+ break;
+ case 6:
+ TVShowConvertInternationalString(gStringVar1, pokemonToday->playerName, pokemonToday->language);
+ StringCopy(gStringVar2, gSpeciesNames[pokemonToday->species]);
+ TVShowConvertInternationalString(gStringVar3, pokemonToday->nickname, pokemonToday->language2);
+ gUnknown_020387E8 += (Random() % 4) + 1;
+ break;
+ case 7:
+ case 8:
+ StringCopy(gStringVar1, gSpeciesNames[pokemonToday->species]);
+ TVShowConvertInternationalString(gStringVar2, pokemonToday->nickname, pokemonToday->language2);
+ sub_80BF638(2, pokemonToday->species);
+ gUnknown_020387E8 = 11;
+ break;
+ case 9:
+ case 10:
+ StringCopy(gStringVar1, gSpeciesNames[pokemonToday->species]);
+ TVShowConvertInternationalString(gStringVar2, pokemonToday->nickname, pokemonToday->language2);
+ gUnknown_020387E8 = 11;
+ break;
+ case 11:
+ TVShowDone();
+ break;
+ }
+ ShowFieldMessage(gTVPokemonTodayTextGroup[state]);
+}
+
+void DoTVShowPokemonTodayFailedCapture(void)
+{
+ struct TVShowPokemonTodayFailed *pokemonTodayFailed = &gSaveBlock1.tvShows[gSpecialVar_0x8004].pokemonTodayFailed;
+ u8 state;
+
+ gScriptResult = 0;
+ state = gUnknown_020387E8;
+ switch (state)
+ {
+ case 0:
+ TVShowConvertInternationalString(gStringVar1, pokemonTodayFailed->playerName, pokemonTodayFailed->language);
+ StringCopy(gStringVar2, gSpeciesNames[pokemonTodayFailed->species]);
+ gUnknown_020387E8 = 1;
+ break;
+ case 1:
+ TVShowConvertInternationalString(gStringVar1, pokemonTodayFailed->playerName, pokemonTodayFailed->language);
+ GetMapSectionName(gStringVar2, pokemonTodayFailed->var12, 0);
+ StringCopy(gStringVar3, gSpeciesNames[pokemonTodayFailed->species2]);
+ if (pokemonTodayFailed->var11 == 1)
+ gUnknown_020387E8 = 3;
+ else
+ gUnknown_020387E8 = 2;
+ break;
+ case 2:
+ case 3:
+ TVShowConvertInternationalString(gStringVar1, pokemonTodayFailed->playerName, pokemonTodayFailed->language);
+ sub_80BF088(1, pokemonTodayFailed->var10);
+ if ((Random() % 3) == 0)
+ gUnknown_020387E8 = 5;
+ else
+ gUnknown_020387E8 = 4;
+ break;
+ case 4:
+ case 5:
+ TVShowConvertInternationalString(gStringVar1, pokemonTodayFailed->playerName, pokemonTodayFailed->language);
+ gUnknown_020387E8 = 6;
+ break;
+ case 6:
+ TVShowDone();
+ break;
+ }
+ ShowFieldMessage(gTVPokemonTodayFailedCaptureTextGroup[state]);
+}
+
+void DoTVShowPokemonFanClubLetter(void)
+{
+ struct TVShowFanClubLetter *fanclubLetter = &gSaveBlock1.tvShows[gSpecialVar_0x8004].fanclubLetter;
+ u8 state;
+ u16 rval;
+
+ gScriptResult = 0;
+ state = gUnknown_020387E8;
+ switch (state)
+ {
+ case 0:
+ TVShowConvertInternationalString(gStringVar1, fanclubLetter->playerName, fanclubLetter->language);
+ StringCopy(gStringVar2, gSpeciesNames[fanclubLetter->species]);
+ gUnknown_020387E8 = 50;
+ break;
+ case 1:
+ rval = (Random() % 4) + 1;
+ if (rval == 1)
+ gUnknown_020387E8 = 2;
+ else
+ gUnknown_020387E8 = rval + 2;
+ break;
+ case 2:
+ gUnknown_020387E8 = 51;
+ break;
+ case 3:
+ gUnknown_020387E8 += (Random() % 3) + 1;
+ break;
+ case 4:
+ case 5:
+ case 6:
+ sub_80BF79C((TVShow *)fanclubLetter);
+ gUnknown_020387E8 = 7;
+ break;
+ case 7:
+ rval = (Random() % 0x1f) + 0x46;
+ sub_80BF088(2, rval);
+ TVShowDone();
+ break;
+ case 50:
+ ConvertEasyChatWordsToString(gStringVar4, fanclubLetter->pad04, 2, 2);
+ ShowFieldMessage(gStringVar4);
+ gUnknown_020387E8 = 1;
+ return;
+ case 51:
+ ConvertEasyChatWordsToString(gStringVar4, fanclubLetter->pad04, 2, 2);
+ ShowFieldMessage(gStringVar4);
+ gUnknown_020387E8 = 3;
+ return;
+ }
+ ShowFieldMessage(gTVFanClubTextGroup[state]);
+}
+
+void DoTVShowRecentHappenings(void)
+{
+ struct TVShowRecentHappenings *recentHappenings = &gSaveBlock1.tvShows[gSpecialVar_0x8004].recentHappenings;
+ u8 state;
+
+ gScriptResult = 0;
+ state = gUnknown_020387E8;
+ switch (state)
+ {
+ case 0:
+ TVShowConvertInternationalString(gStringVar1, recentHappenings->playerName, recentHappenings->language);
+ sub_80BF79C((TVShow *)recentHappenings);
+ gUnknown_020387E8 = 50;
+ break;
+ case 1:
+ gUnknown_020387E8 += 1 + (Random() % 3);
+ break;
+ case 2:
+ case 3:
+ case 4:
+ gUnknown_020387E8 = 5;
+ break;
+ case 5:
+ TVShowDone();
+ break;
+ case 50:
+ ConvertEasyChatWordsToString(gStringVar4, recentHappenings->var04, 2, 2);
+ ShowFieldMessage(gStringVar4);
+ gUnknown_020387E8 = 1;
+ return;
+ }
+ ShowFieldMessage(gTVRecentHappeningsTextGroup[state]);
+}
+
+void DoTVShowPokemonFanClubOpinions(void)
+{
+ struct TVShowFanclubOpinions *fanclubOpinions = &gSaveBlock1.tvShows[gSpecialVar_0x8004].fanclubOpinions;
+ u8 state;
+
+ gScriptResult = 0;
+ state = gUnknown_020387E8;
+ switch (state)
+ {
+ case 0:
+ TVShowConvertInternationalString(gStringVar1, fanclubOpinions->playerName, fanclubOpinions->language);
+ StringCopy(gStringVar2, gSpeciesNames[fanclubOpinions->var02]);
+ TVShowConvertInternationalString(gStringVar3, fanclubOpinions->var10, fanclubOpinions->var0E);
+ gUnknown_020387E8 = fanclubOpinions->var04B + 1;
+ break;
+ case 1:
+ case 2:
+ case 3:
+ TVShowConvertInternationalString(gStringVar1, fanclubOpinions->playerName, fanclubOpinions->language);
+ StringCopy(gStringVar2, gSpeciesNames[fanclubOpinions->var02]);
+ EasyChat_GetWordText(gStringVar3, fanclubOpinions->var1C[0]);
+ gUnknown_020387E8 = 4;
+ break;
+ case 4:
+ TVShowConvertInternationalString(gStringVar1, fanclubOpinions->playerName, fanclubOpinions->language);
+ EasyChat_GetWordText(gStringVar3, fanclubOpinions->var1C[1]);
+ TVShowDone();
+ break;
+ }
+ ShowFieldMessage(gTVFanClubOpinionsTextGroup[state]);
+}
+
+void nullsub_22(void)
+{
+}
+
+void DoTVShowPokemonNewsMassOutbreak(void)
+{
+ struct TVShowMassOutbreak *massOutbreak = &gSaveBlock1.tvShows[gSpecialVar_0x8004].massOutbreak;
+
+ GetMapSectionName(gStringVar1, massOutbreak->locationMapNum, 0);
+ StringCopy(gStringVar2, gSpeciesNames[massOutbreak->species]);
+ TVShowDone();
+ StartMassOutbreak();
+ ShowFieldMessage(gTVPokemonOutbreakTextGroup[gUnknown_020387E8]);
+}
+
+void DoTVShowInSearchOfTrainers(void)
+{
+ u8 state;
+
+ gScriptResult = 0;
+ state = gUnknown_020387E8;
+ switch (state)
+ {
+ case 0:
+ GetMapSectionName(gStringVar1, gSaveBlock1.gabbyAndTyData.mapnum, 0);
+ if (gSaveBlock1.gabbyAndTyData.battleNum > 1)
+ gUnknown_020387E8 = 1;
+ else
+ gUnknown_020387E8 = 2;
+ break;
+ case 1:
+ gUnknown_020387E8 = 2;
+ break;
+ case 2:
+ if (gSaveBlock1.gabbyAndTyData.valA_0 == 0)
+ gUnknown_020387E8 = 4;
+ else if (gSaveBlock1.gabbyAndTyData.valA_3 != 0)
+ gUnknown_020387E8 = 5;
+ else if (gSaveBlock1.gabbyAndTyData.valA_2 != 0)
+ gUnknown_020387E8 = 6;
+ else if (gSaveBlock1.gabbyAndTyData.valA_1 != 0)
+ gUnknown_020387E8 = 7;
+ else
+ gUnknown_020387E8 = 3;
+ break;
+ case 3:
+ StringCopy(gStringVar1, gSpeciesNames[gSaveBlock1.gabbyAndTyData.mon1]);
+ StringCopy(gStringVar2, gMoveNames[gSaveBlock1.gabbyAndTyData.lastMove]);
+ StringCopy(gStringVar3, gSpeciesNames[gSaveBlock1.gabbyAndTyData.mon2]);
+ gUnknown_020387E8 = 8;
+ break;
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ gUnknown_020387E8 = 8;
+ break;
+ case 8:
+ EasyChat_GetWordText(gStringVar1, gSaveBlock1.gabbyAndTyData.quote);
+ StringCopy(gStringVar2, gSpeciesNames[gSaveBlock1.gabbyAndTyData.mon1]);
+ StringCopy(gStringVar3, gSpeciesNames[gSaveBlock1.gabbyAndTyData.mon2]);
+ gScriptResult = 1;
+ gUnknown_020387E8 = 0;;
+ TakeTVShowInSearchOfTrainersOffTheAir();
+ break;
+ }
+ ShowFieldMessage(gTVGabbyAndTyTextGroup[state]);
+}
+
+void DoTVShowPokemonAngler(void)
+{
+ struct TVShowPokemonAngler *pokemonAngler = &gSaveBlock1.tvShows[gSpecialVar_0x8004].pokemonAngler;
+ u8 state;
+
+ gScriptResult = 0;
+ if (pokemonAngler->var02 < pokemonAngler->var03)
+ gUnknown_020387E8 = 0;
+ else
+ gUnknown_020387E8 = 1;
+ state = gUnknown_020387E8;
+ switch (state)
+ {
+ case 0:
+ TVShowConvertInternationalString(gStringVar1, pokemonAngler->playerName, pokemonAngler->language);
+ StringCopy(gStringVar2, gSpeciesNames[pokemonAngler->var04]);
+ sub_80BF088(2, pokemonAngler->var03);
+ TVShowDone();
+ break;
+ case 1:
+ TVShowConvertInternationalString(gStringVar1, pokemonAngler->playerName, pokemonAngler->language);
+ StringCopy(gStringVar2, gSpeciesNames[pokemonAngler->var04]);
+ sub_80BF088(2, pokemonAngler->var02);
+ TVShowDone();
+ break;
+ }
+ ShowFieldMessage(gTVFishingGuruAdviceTextGroup[state]);
+}
+
+void DoTVShowTheWorldOfMasters(void)
+{
+ struct TVShowWorldOfMasters *worldOfMasters = &gSaveBlock1.tvShows[gSpecialVar_0x8004].worldOfMasters;
+ u8 state;
+
+ gScriptResult = 0;
+ state = gUnknown_020387E8;
+ switch (state)
+ {
+ case 0:
+ TVShowConvertInternationalString(gStringVar1, worldOfMasters->playerName,
+ worldOfMasters->language);
+ sub_80BF088(1, worldOfMasters->var06);
+ sub_80BF088(2, worldOfMasters->var02);
+ gUnknown_020387E8 = 1;
+ break;
+ case 1:
+ StringCopy(gStringVar1, gSpeciesNames[worldOfMasters->var08]);
+ gUnknown_020387E8 = 2;
+ break;
+ case 2:
+ TVShowConvertInternationalString(gStringVar1, worldOfMasters->playerName,
+ worldOfMasters->language);
+ GetMapSectionName(gStringVar2, worldOfMasters->var0a, 0);
+ StringCopy(gStringVar3, gSpeciesNames[worldOfMasters->var04]);
+ TVShowDone();
+ break;
+ }
+ ShowFieldMessage(gTVWorldOfMastersTextGroup[state]);
+}
+
+void TVShowDone(void)
+{
+ gScriptResult = 1;
+ gUnknown_020387E8 = 0;
+ gSaveBlock1.tvShows[gSpecialVar_0x8004].common.var01 = 0;
+}
+
+void sub_80C2014(void)
+{
+ gUnknown_020387E8 = 0;
+}
diff --git a/src/field/use_pokeblock.c b/src/field/use_pokeblock.c
new file mode 100644
index 000000000..e946a9cfc
--- /dev/null
+++ b/src/field/use_pokeblock.c
@@ -0,0 +1,905 @@
+//
+
+// Modified by Dizzy Egg on 8/15/17.
+//
+
+#include "global.h"
+#include "main.h"
+#include "overworld.h"
+#include "string_util.h"
+#include "strings.h"
+#include "sprite.h"
+#include "pokemon.h"
+#include "pokenav.h"
+#include "palette.h"
+#include "text.h"
+#include "menu.h"
+#include "sound.h"
+#include "songs.h"
+#include "pokeblock.h"
+
+#define GFX_TAG_CONDITIONUPDOWN 0
+
+#ifdef GERMAN
+extern const u16 ConditionUpDownPalette[16];
+extern const u32 ConditionUpDownTiles[0x80];
+#else
+const u16 ConditionUpDownPalette[] = INCBIN_U16("graphics/misc/condition_up_down.gbapal");
+const u32 ConditionUpDownTiles[] = INCBIN_U32("graphics/misc/condition_up_down.4bpp");
+#endif
+
+static const u32 sContestStatsMonData[] = {
+ MON_DATA_COOL,
+ MON_DATA_TOUGH,
+ MON_DATA_SMART,
+ MON_DATA_CUTE,
+ MON_DATA_BEAUTY
+};
+
+static const u8 gUnknown_0840612C[] = {
+ 0, 4, 3, 2, 1
+};
+
+static const u8 *const sContextStatNames[] = {
+ OtherText_Coolness,
+ OtherText_Toughness,
+ OtherText_Smartness,
+ OtherText_Cuteness,
+ OtherText_Beauty
+};
+
+static const struct SpriteSheet gSpriteSheet_ConditionUpDown = {
+ (u8 *)ConditionUpDownTiles,
+ sizeof ConditionUpDownTiles,
+ GFX_TAG_CONDITIONUPDOWN
+};
+
+static const struct SpritePalette gSpritePalette_ConditionUpDown = {
+ ConditionUpDownPalette,
+ GFX_TAG_CONDITIONUPDOWN
+};
+
+static const s16 gUnknown_08406158[][2] = {
+ {0x9c, 0x1e},
+ {0x75, 0x35},
+ {0x75, 0x70},
+ {0xc5, 0x70},
+ {0xc5, 0x35}
+};
+
+static const struct OamData gOamData_840616C = {
+ .shape = 1,
+ .size = 2,
+ .priority = 1
+};
+
+static const union AnimCmd gSpriteAnim_8406174[] = {
+ ANIMCMD_FRAME(0, 5),
+ ANIMCMD_END
+};
+
+static const union AnimCmd gSpriteAnim_840617C[] = {
+ ANIMCMD_FRAME(8, 5),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const gSpriteAnimTable_8406184[] = {
+ gSpriteAnim_8406174,
+ gSpriteAnim_840617C
+};
+
+static const struct SpriteTemplate gSpriteTemplate_840618C = {
+ GFX_TAG_CONDITIONUPDOWN,
+ GFX_TAG_CONDITIONUPDOWN,
+ &gOamData_840616C,
+ gSpriteAnimTable_8406184,
+ NULL,
+ gDummySpriteAffineAnimTable,
+ SpriteCallbackDummy
+};
+
+static EWRAM_DATA struct UnkPokenavStruct_Sub1 *gUnknown_02039304 = NULL;
+static EWRAM_DATA MainCallback gUnknown_02039308 = NULL;
+static EWRAM_DATA struct Pokeblock *gUnknown_0203930C = NULL;
+EWRAM_DATA u8 gPokeblockMonID = 0;
+EWRAM_DATA s16 gPokeblockGain = 0;
+
+extern u16 gKeyRepeatStartDelay;
+extern u16 gScriptItemId; // FIXME: remove after merge of #349 Pokeblock
+
+static void launch_c3_walk_stairs_and_run_once(void (*const)(void));
+static void sub_81361E4(void);
+static void sub_813622C(void);
+static void sub_8136244(void);
+static void sub_8136264(void);
+static void sub_8136294(void);
+static void sub_81365A0(void);
+static void sub_81365C8(void);
+static void sub_8136638(void);
+static void sub_81368A4(void);
+void sub_8089668(void);
+static void sub_8136B44(void);
+static u8 sub_81370E4(u8);
+static void sub_8136BB8(void);
+static s8 sub_8136C40(void);
+static bool8 sub_8137058(void);
+static void sub_8136D60(void);
+static void sub_8136808(void);
+static void sub_8136D8C(void);
+static u8 sub_81370A4(u8);
+static void sub_81369CC(void);
+static void sub_8136EF0(void);
+static void sub_8137138(void);
+static void sub_8136C6C(void);
+static bool8 sub_8136D00(void);
+static void Pokeblock_BufferEnhancedStatText(u8 *, u8, s16);
+static void Pokeblock_MenuWindowTextPrint(const u8 *);
+static void sub_8136F74(struct Pokeblock *, struct Pokemon *);
+static void sub_81371DC(struct Sprite *);
+
+void sub_8136130(struct Pokeblock *pokeblock, MainCallback callback)
+{
+ gUnknown_02039304 = &gUnknown_083DFEC4->unkD164;
+ gUnknown_02039304->pokeblock = pokeblock;
+ gUnknown_02039304->callback = callback;
+ gUnknown_083DFEC4->unkD162[0] = 2;
+ launch_c3_walk_stairs_and_run_once(sub_8136294);
+ SetMainCallback2(sub_8136244);
+}
+
+static void sub_8136174(void)
+{
+ gUnknown_02039304->pokeblock = gUnknown_0203930C;
+ gUnknown_02039304->callback = gUnknown_02039308;
+ gPokeblockMonID = sub_81370E4(gPokeblockMonID);
+ gUnknown_02039304->unk56 = gPokeblockMonID < 4 ? 0 : 1;
+ gUnknown_083DFEC4->unkD162[0] = 2;
+ launch_c3_walk_stairs_and_run_once(sub_8136294);
+ SetMainCallback2(sub_81361E4);
+}
+
+static void sub_81361E4(void)
+{
+ gUnknown_02039304->unk0();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+ if (gUnknown_02039304->unk0 == sub_81365C8)
+ {
+ REG_DISPCNT = 0;
+ gUnknown_02039304->unk50 = 0;
+ SetMainCallback2(sub_813622C);
+ }
+}
+
+static void sub_813622C(void)
+{
+ sub_81368A4();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+}
+
+static void sub_8136244(void)
+{
+ gUnknown_02039304->unk0();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+}
+
+static void sub_8136264(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+ sub_80F5CDC(6);
+ sub_8089668();
+}
+
+static void launch_c3_walk_stairs_and_run_once(void (*const func)(void))
+{
+ gUnknown_02039304->unk0 = func;
+ gUnknown_02039304->unk50 = 0;
+}
+
+static void sub_8136294(void)
+{
+ bool32 c1LinkRelatedActive;
+ switch (gUnknown_02039304->unk50)
+ {
+ case 0:
+ c1LinkRelatedActive = is_c1_link_related_active();
+ gUnknown_083DFEC4->unk6DAC = c1LinkRelatedActive;
+ if ((bool8)c1LinkRelatedActive == FALSE)
+ {
+ gUnknown_02039304->unk55 = 0;
+ launch_c3_walk_stairs_and_run_once(sub_81365A0);
+ gUnknown_02039304->unk50++;
+ }
+ break;
+ case 1:
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ gUnknown_02039304->unk50++;
+ break;
+ case 2:
+ SetVBlankCallback(NULL);
+ gUnknown_02039304->unk50++;
+ break;
+ case 3:
+ SetUpWindowConfig(&gWindowConfig_81E7080);
+ gUnknown_02039304->unk50++;
+ break;
+ case 4:
+ MultistepInitMenuWindowBegin(&gWindowConfig_81E7080);
+ gUnknown_02039304->unk50++;
+ break;
+ case 5:
+ if (MultistepInitMenuWindowContinue())
+ {
+ gUnknown_02039304->unk50++;
+ }
+ break;
+ case 6:
+ gUnknown_083DFEC4->unk76AA = 0;
+ gUnknown_083DFEC4->unk87E0 = NULL;
+ gUnknown_083DFEC4->unk030C = 0x20;
+ gUnknown_02039304->unk50++;
+ break;
+ case 7:
+ sub_80F2688();
+ gUnknown_02039304->unk50++;
+ // fallthrough
+ case 8:
+ if (!sub_80F26BC())
+ {
+ gUnknown_02039304->unk50++;
+ }
+ break;
+ case 9:
+ sub_80F2C80(1);
+ gUnknown_02039304->unk50++;
+ // fallthrough
+ case 10:
+ if (!sub_80F2CBC(1))
+ {
+ gUnknown_02039304->unk50++;
+ }
+ break;
+ case 11:
+ gKeyRepeatStartDelay = 20;
+ gUnknown_083DFEC4->unk8828 = CalculatePlayerPartyCount();
+ gUnknown_083DFEC4->unk9344 = 0;
+ gUnknown_083DFEC4->unk8768 = NULL;
+ sub_80F4BD0();
+ gUnknown_083DFEC4->unkD160 = 0;
+ gUnknown_02039304->unk50++;
+ break;
+ case 12:
+ if (!sub_80F1778())
+ {
+ REG_BG2VOFS = 6;
+ REG_BG3VOFS = 6;
+ gUnknown_02039304->unk50++;
+ }
+ break;
+ case 13:
+ sub_80F2E18(0);
+ gUnknown_083DFEC4->unk8768->unk26 = 0xffd8;
+ gUnknown_02039304->unk50++;
+ break;
+ case 14:
+ if (!sub_80F170C())
+ {
+ gUnknown_02039304->unk50++;
+ }
+ break;
+ case 15:
+ sub_80F33A8();
+ gUnknown_02039304->unk50++;
+ break;
+ case 16:
+ DmaClear32(3, BG_SCREEN_ADDR(31), 0x800);
+ REG_BG1VOFS = 0;
+ REG_BG1HOFS = 0;
+ REG_BG1CNT = BGCNT_SCREENBASE(31);
+ gUnknown_02039304->unk50++;
+ break;
+ case 17:
+ sub_80F567C(&gUnknown_083DFEC4->unk8ff0, gUnknown_083DFEC4->unk9004);
+ sub_80F5B38();
+ gUnknown_02039304->unk50++;
+ break;
+ case 18:
+ if (!sub_80F5B50())
+ {
+ gUnknown_02039304->unk50++;
+ }
+ break;
+ case 19:
+ sub_80F556C(gUnknown_083DFEC4->unk9004);
+ gUnknown_02039304->unk50++;
+ break;
+ case 20:
+ sub_80F1934();
+ gUnknown_02039304->unk50++;
+ break;
+ case 21:
+ REG_WIN0H = 0xf0;
+ REG_WIN1H = 0x9b;
+ REG_WIN0V = 0x3273;
+ REG_WIN1V = 0x3273;
+ REG_WININ = 0x3f3f;
+ REG_WINOUT = 0x1b;
+ REG_BG0VOFS = 0x28;
+ REG_DISPCNT = DISPCNT_OBJ_1D_MAP | DISPCNT_BG_ALL_ON | DISPCNT_OBJ_ON | DISPCNT_WIN0_ON | DISPCNT_WIN1_ON;
+ // fallthrough
+ case 22:
+ gUnknown_02039304->unk55 = 1;
+ launch_c3_walk_stairs_and_run_once(sub_81365C8);
+ break;
+ }
+}
+
+static void sub_81365A0(void)
+{
+ while (!gUnknown_02039304->unk55)
+ {
+ sub_8136294();
+ }
+}
+
+static void sub_81365C8(void)
+{
+ switch (gUnknown_02039304->unk50)
+ {
+ case 0:
+ BeginNormalPaletteFade(-1, 0, 16, 0, 0);
+ SetVBlankCallback(sub_8136264);
+ gUnknown_02039304->unk50++;
+ break;
+ case 1:
+ if (!gPaletteFade.active)
+ {
+ sub_80F3C94();
+ sub_80F3D00();
+ launch_c3_walk_stairs_and_run_once(sub_8136638);
+ }
+ break;
+ }
+}
+
+static void sub_8136638(void)
+{
+ switch (gUnknown_02039304->unk50)
+ {
+ case 0:
+ if (gMain.heldKeys & DPAD_UP)
+ {
+ PlaySE(SE_SELECT);
+ sub_80F5060(TRUE);
+ move_anim_execute();
+ gUnknown_02039304->unk50 = 1;
+ }
+ else if (gMain.heldKeys & DPAD_DOWN)
+ {
+ PlaySE(SE_SELECT);
+ sub_80F5060(FALSE);
+ move_anim_execute();
+ gUnknown_02039304->unk50 = 1;
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ gUnknown_02039304->unk50 = 3;
+ }
+ else if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ if (gUnknown_083DFEC4->unk87DC == gUnknown_083DFEC4->unk87DA - 1)
+ {
+ gUnknown_02039304->unk50 = 3;
+ }
+ else
+ {
+ gUnknown_02039304->unk50 = 5;
+ }
+ }
+ break;
+ case 1:
+ if (!gpu_sync_bg_show())
+ {
+ gUnknown_02039304->unk50++;
+ }
+ break;
+ case 2:
+ if (!sub_8055870())
+ {
+ sub_80F1934();
+ sub_80F3D00();
+ gUnknown_02039304->unk50 = 0;
+ }
+ break;
+ case 3:
+ launch_c3_walk_stairs_and_run_once(sub_8136B44);
+ break;
+ case 4:
+ break;
+ case 5:
+ sub_8136BB8();
+ gUnknown_02039304->unk50++;
+ break;
+ case 6:
+ switch (sub_8136C40())
+ {
+ case 1:
+ case -1:
+ gUnknown_02039304->unk50 = 0;
+ break;
+ case 0:
+ if (sub_8137058())
+ {
+ sub_8136D60();
+ gUnknown_02039304->unk50 = 7;
+ }
+ else
+ {
+ launch_c3_walk_stairs_and_run_once(sub_8136808);
+ }
+ break;
+ }
+ break;
+ case 7:
+ if (gMain.newKeys & (A_BUTTON | B_BUTTON))
+ {
+ sub_8136D8C();
+ gUnknown_02039304->unk50 = 0;
+ }
+ break;
+ }
+}
+
+static void sub_8136808(void)
+{
+ switch (gUnknown_02039304->unk50)
+ {
+ case 0:
+ gPokeblockMonID = sub_81370A4(gUnknown_083DFEC4->unk87DC);
+ gUnknown_02039308 = gUnknown_02039304->callback;
+ gUnknown_0203930C = gUnknown_02039304->pokeblock;
+ BeginNormalPaletteFade(-1, 0, 0, 16, 0);
+ gUnknown_02039304->unk50++;
+ break;
+ case 1:
+ if (!gPaletteFade.active)
+ {
+ gMain.savedCallback = sub_8136174;
+ SetMainCallback2(CB2_PreparePokeblockFeedScene);
+ }
+ break;
+ }
+}
+
+static void sub_81368A4(void)
+{
+ switch (gUnknown_02039304->unk50)
+ {
+ case 0:
+ if (gUnknown_083DFEC4->unk87DC != gPokeblockMonID)
+ {
+ sub_80F5060(gUnknown_02039304->unk56);
+ gUnknown_02039304->unk50++;
+ }
+ else
+ {
+ gUnknown_02039304->unk50 = 3;
+ }
+ break;
+ case 1:
+ if (!gpu_sync_bg_show())
+ {
+ gUnknown_02039304->unk50++;
+ }
+ break;
+ case 2:
+ if (!sub_8055870())
+ {
+ sub_80F1934();
+ gUnknown_02039304->unk50 = 0;
+ }
+ break;
+ case 3:
+ BlendPalettes(-1, 16, 0);
+ gUnknown_02039304->unk50++;
+ break;
+ case 4:
+ REG_DISPCNT = DISPCNT_OBJ_1D_MAP | DISPCNT_BG_ALL_ON | DISPCNT_OBJ_ON | DISPCNT_WIN0_ON | DISPCNT_WIN1_ON;
+ gUnknown_02039304->unk50++;
+ break;
+ case 5:
+ SetVBlankCallback(sub_8136264);
+ BeginNormalPaletteFade(-1, 0, 16, 0, 0);
+ gUnknown_02039304->unk50++;
+ break;
+ case 6:
+ if (!gPaletteFade.active)
+ {
+ sub_80F3C94();
+ sub_80F3D00();
+ launch_c3_walk_stairs_and_run_once(sub_81369CC);
+ SetMainCallback2(sub_8136244);
+ }
+ break;
+ }
+}
+
+static void sub_81369CC(void)
+{
+ switch (gUnknown_02039304->unk50)
+ {
+ case 0:
+ gUnknown_02039304->pokemon = &gPlayerParty[0];
+ gUnknown_02039304->pokemon = &gPlayerParty[gUnknown_083DFEC4->unk893c[gUnknown_083DFEC4->unk87DC].partyIdx];
+ move_anim_execute();
+ gUnknown_02039304->unk50++;
+ break;
+ case 1:
+ if (gMain.newKeys & (A_BUTTON | B_BUTTON))
+ gUnknown_02039304->unk50++;
+ break;
+ case 2:
+ sub_8136EF0();
+ sub_80F567C(gUnknown_02039304->unk5c, gUnknown_083DFEC4->unk9040);
+ sub_80F5550(gUnknown_083DFEC4->unk9004[gUnknown_083DFEC4->unk8fe9], gUnknown_083DFEC4->unk9040);
+ sub_8137138();
+ gUnknown_02039304->unk50++;
+ break;
+ case 3:
+ if (!sub_80F555C())
+ {
+ sub_80F7224(sub_81370A4(gUnknown_083DFEC4->unk87DC));
+ sub_80F3D00();
+ gUnknown_02039304->unk52 = 0;
+ gUnknown_02039304->unk50++;
+ }
+ break;
+ case 4:
+ if ((++gUnknown_02039304->unk52) > 16)
+ {
+ sub_8136C6C();
+ gUnknown_02039304->unk50++;
+ }
+ break;
+ case 5:
+ if (gMain.newKeys & (A_BUTTON | B_BUTTON) && !sub_8136D00())
+ {
+ PokeblockClearIfExists((u8)gScriptItemId);
+ launch_c3_walk_stairs_and_run_once(sub_8136B44);
+ }
+ break;
+ }
+}
+
+static void sub_8136B44(void)
+{
+ switch (gUnknown_02039304->unk50)
+ {
+ case 0:
+ BeginNormalPaletteFade(-1, 0, 0, 16, 0);
+ gUnknown_02039304->unk50++;
+ break;
+ case 1:
+ if (!gPaletteFade.active)
+ {
+ gUnknown_02039304->unk50 = 2;
+ }
+ break;
+ case 2:
+ sub_80F5BDC();
+ gUnknown_02039304->unk50++;
+ break;
+ case 3:
+ SetMainCallback2(gUnknown_02039304->callback);
+ break;
+ }
+}
+
+static void sub_8136BB8(void)
+{
+ GetMonData(&gPlayerParty[sub_81370A4(gUnknown_083DFEC4->unk87DC)], MON_DATA_NICKNAME, gUnknown_02039304->stringBuffer);
+ StringGetEnd10(gUnknown_02039304->stringBuffer);
+ StringAppend(gUnknown_02039304->stringBuffer, gOtherText_GetsAPokeBlock);
+ BasicInitMenuWindow(&gWindowConfig_81E709C);
+ MenuDrawTextWindow(0, 16, 29, 19);
+ MenuPrint(gUnknown_02039304->stringBuffer, 1, 17);
+ DisplayYesNoMenu(23, 10, 1);
+ MoveMenuCursor(0);
+}
+
+static s8 sub_8136C40(void)
+{
+ s8 retval = ProcessMenuInputNoWrap();
+ if ((u8)(retval + 1) < 3)
+ {
+ MenuZeroFillScreen();
+ BasicInitMenuWindow(&gWindowConfig_81E7080);
+ }
+ return retval;
+}
+
+static void sub_8136C6C(void)
+{
+ BasicInitMenuWindow(&gWindowConfig_81E709C);
+ MenuDrawTextWindow(0, 16, 29, 19);
+ for (gUnknown_02039304->unk53 = 0; gUnknown_02039304->unk53 < 5 && gUnknown_02039304->unk61[gUnknown_02039304->unk53] == 0; gUnknown_02039304->unk53++);
+ if (gUnknown_02039304->unk53 < 5)
+ {
+ Pokeblock_BufferEnhancedStatText(gUnknown_02039304->stringBuffer, gUnknown_02039304->unk53, gUnknown_02039304->unk61[gUnknown_02039304->unk53]);
+ }
+ else
+ {
+ Pokeblock_BufferEnhancedStatText(gUnknown_02039304->stringBuffer, gUnknown_02039304->unk53, 0);
+ }
+ Pokeblock_MenuWindowTextPrint(gUnknown_02039304->stringBuffer);
+}
+
+static bool8 sub_8136D00(void)
+{
+ while (1)
+ {
+ gUnknown_02039304->unk53++;
+ if (gUnknown_02039304->unk53 < 5)
+ {
+ if (gUnknown_02039304->unk61[gUnknown_02039304->unk53] != 0)
+ break;
+ }
+ else
+ {
+ gUnknown_02039304->unk53 = 5;
+ return FALSE;
+ }
+ }
+ Pokeblock_BufferEnhancedStatText(gUnknown_02039304->stringBuffer, gUnknown_02039304->unk53, gUnknown_02039304->unk61[gUnknown_02039304->unk53]);
+ Pokeblock_MenuWindowTextPrint(gUnknown_02039304->stringBuffer);
+ return TRUE;
+}
+
+static void sub_8136D60(void)
+{
+ BasicInitMenuWindow(&gWindowConfig_81E709C);
+ MenuDrawTextWindow(0, 16, 29, 19);
+ MenuPrint(gOtherText_WontEat, 1, 17);
+}
+
+static void sub_8136D8C(void)
+{
+ MenuZeroFillScreen();
+ BasicInitMenuWindow(&gWindowConfig_81E7080);
+}
+
+static void Pokeblock_MenuWindowTextPrint(const u8 *message)
+{
+ MenuDrawTextWindow(0, 16, 29, 19);
+ MenuPrint(message, 1, 17);
+}
+
+#ifdef NONMATCHING
+static void Pokeblock_BufferEnhancedStatText(u8 *dest, u8 statID, s16 a2)
+{
+ if (a2 != 0)
+ {
+ StringCopy(dest, sContextStatNames[statID]);
+ StringAppend(dest, gOtherText_WasEnhanced);
+ }
+ else
+ {
+ StringCopy(dest, gOtherText_NothingChanged);
+ }
+}
+#else
+__attribute__((naked))
+static void Pokeblock_BufferEnhancedStatText(u8 *dest, u8 a1, s16 a2)
+{
+ asm_unified("\tpush {r4,lr}\n"
+ "\tadds r4, r0, 0\n"
+ "\tlsls r1, 24\n"
+ "\tlsrs r3, r1, 24\n"
+ "\tlsls r2, 16\n"
+ "\tlsrs r0, r2, 16\n"
+ "\tasrs r2, 16\n"
+ "\tcmp r2, 0\n"
+ "\tbeq _08136DFC\n"
+ "\tcmp r2, 0\n"
+ "\tble _08136DD8\n"
+ "\tmovs r0, 0\n"
+ "_08136DD8:\n"
+ "\tlsls r0, 16\n"
+ "\tldr r1, _08136DF4 @ =sContextStatNames\n"
+ "\tlsls r0, r3, 2\n"
+ "\tadds r0, r1\n"
+ "\tldr r1, [r0]\n"
+ "\tadds r0, r4, 0\n"
+ "\tbl StringCopy\n"
+ "\tldr r1, _08136DF8 @ =gOtherText_WasEnhanced\n"
+ "\tadds r0, r4, 0\n"
+ "\tbl StringAppend\n"
+ "\tb _08136E04\n"
+ "\t.align 2, 0\n"
+ "_08136DF4: .4byte sContextStatNames\n"
+ "_08136DF8: .4byte gOtherText_WasEnhanced\n"
+ "_08136DFC:\n"
+ "\tldr r1, _08136E0C @ =gOtherText_NothingChanged\n"
+ "\tadds r0, r4, 0\n"
+ "\tbl StringCopy\n"
+ "_08136E04:\n"
+ "\tpop {r4}\n"
+ "\tpop {r0}\n"
+ "\tbx r0\n"
+ "\t.align 2, 0\n"
+ "_08136E0C: .4byte gOtherText_NothingChanged");
+}
+#endif
+
+static void Pokeblock_GetMonContestStats(struct Pokemon *pokemon, u8 *data)
+{
+ u16 i;
+ for (i=0; i<5; i++)
+ {
+ data[i] = GetMonData(pokemon, sContestStatsMonData[i]);
+ }
+}
+
+static void sub_8136E40(struct Pokeblock *pokeblock, struct Pokemon *pokemon)
+{
+ u16 i;
+ s16 cstat;
+ u8 data;
+ if (GetMonData(pokemon, MON_DATA_SHEEN) != 255)
+ {
+ sub_8136F74(pokeblock, pokemon);
+ for (i=0; i<5; i++)
+ {
+ data = GetMonData(pokemon, sContestStatsMonData[i]);
+ cstat = data + gUnknown_02039304->unk66[i];
+ if (cstat < 0)
+ cstat = 0;
+ if (cstat > 255)
+ cstat = 255;
+ data = cstat;
+ SetMonData(pokemon, sContestStatsMonData[i], &data);
+ }
+ cstat = (u8)GetMonData(pokemon, MON_DATA_SHEEN);
+ cstat = cstat + pokeblock->feel;
+ if (cstat > 255)
+ cstat = 255;
+ data = cstat;
+ SetMonData(pokemon, MON_DATA_SHEEN, &data);
+ }
+}
+
+static void sub_8136EF0(void)
+{
+ u16 i;
+ struct Pokemon *pokemon = gPlayerParty;
+ pokemon += gUnknown_083DFEC4->unk893c[gUnknown_083DFEC4->unk87DC].partyIdx;
+ Pokeblock_GetMonContestStats(pokemon, gUnknown_02039304->unk57);
+ sub_8136E40(gUnknown_02039304->pokeblock, pokemon);
+ Pokeblock_GetMonContestStats(pokemon, gUnknown_02039304->unk5c);
+ for (i=0; i<5; i++)
+ {
+ gUnknown_02039304->unk61[i] = gUnknown_02039304->unk5c[i] - gUnknown_02039304->unk57[i];
+ }
+}
+
+static void sub_8136F74(struct Pokeblock *pokeblock, struct Pokemon *pokemon)
+{
+ s8 direction;
+ s8 i;
+ s16 amount;
+ s8 boost;
+ s8 taste;
+ gUnknown_02039304->unk66[0] = pokeblock->spicy;
+ gUnknown_02039304->unk66[1] = pokeblock->sour;
+ gUnknown_02039304->unk66[2] = pokeblock->bitter;
+ gUnknown_02039304->unk66[3] = pokeblock->sweet;
+ gUnknown_02039304->unk66[4] = pokeblock->dry;
+ if (gPokeblockGain > 0)
+ direction = 1;
+ else if (gPokeblockGain < 0)
+ direction = -1;
+ else
+ return;
+ for (i=0; i<5; i++)
+ {
+ amount = gUnknown_02039304->unk66[i];
+ boost = amount / 10;
+ if (amount % 10 >= 5) // round to the nearest
+ boost++;
+ taste = sub_8040A54(pokemon, gUnknown_0840612C[i]);
+ if (taste == direction)
+ {
+ gUnknown_02039304->unk66[i] += boost * taste;
+ }
+ }
+}
+
+static bool8 sub_8137058(void)
+{
+ struct Pokemon *pokemon = gPlayerParty;
+ pokemon += gUnknown_083DFEC4->unk893c[gUnknown_083DFEC4->unk87DC].partyIdx;
+ if (GetMonData(pokemon, MON_DATA_SHEEN) == 255)
+ return TRUE;
+ return FALSE;
+}
+
+static u8 sub_81370A4(u8 a0)
+{
+ u8 i;
+ for (i=0; i<PARTY_SIZE; i++)
+ {
+ if (!GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG))
+ {
+ if (a0 == 0)
+ return i;
+ a0--;
+ }
+ }
+ return 0;
+}
+
+static u8 sub_81370E4(u8 a0)
+{
+ u8 ct;
+ u8 i;
+ for (i=0, ct=0; i<a0; i++)
+ {
+ if (GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG))
+ {
+ ct++;
+ }
+ }
+ return a0 - ct;
+}
+
+u8 sub_8137124(u8 a0)
+{
+ return sub_81370A4(a0);
+}
+
+static void sub_8137138(void)
+{
+ u16 flavor;
+ u8 spriteidx;
+ LoadSpriteSheet(&gSpriteSheet_ConditionUpDown);
+ LoadSpritePalette(&gSpritePalette_ConditionUpDown);
+ gUnknown_02039304->unk54 = 0;
+ for (flavor=0; flavor<5; flavor++)
+ {
+ if (gUnknown_02039304->unk61[flavor] != 0)
+ {
+ spriteidx = CreateSprite(&gSpriteTemplate_840618C, gUnknown_08406158[flavor][0], gUnknown_08406158[flavor][1], 0);
+ if (spriteidx != MAX_SPRITES)
+ {
+ if (gUnknown_02039304->unk61[flavor] != 0)
+ {
+ gSprites[spriteidx].callback = sub_81371DC;
+ }
+ gUnknown_02039304->unk54++;
+ }
+ }
+ }
+}
+
+static void sub_81371DC(struct Sprite *sprite)
+{
+ if (sprite->data0 <= 5)
+ sprite->pos2.y -= 2;
+ else if (sprite->data0 <= 11)
+ sprite->pos2.y += 2;
+ if ((++sprite->data0) > 60)
+ {
+ DestroySprite(sprite);
+ gUnknown_02039304->unk54--;
+ }
+}
diff --git a/src/field/wallclock.c b/src/field/wallclock.c
new file mode 100644
index 000000000..8db13dc2d
--- /dev/null
+++ b/src/field/wallclock.c
@@ -0,0 +1,1061 @@
+#include "global.h"
+#include "wallclock.h"
+#include "decompress.h"
+#include "main.h"
+#include "menu.h"
+#include "palette.h"
+#include "rtc.h"
+#include "songs.h"
+#include "sound.h"
+#include "strings2.h"
+#include "task.h"
+#include "trig.h"
+#include "unknown_task.h"
+
+extern u16 gSpecialVar_0x8004;
+extern u8 gMiscClock_Gfx[];
+extern u8 gUnknown_08E95774[];
+extern u8 gUnknown_08E954B0[];
+extern u16 gMiscClockMale_Pal[];
+extern u16 gMiscClockFemale_Pal[];
+
+//--------------------------------------------------
+// Graphics Data
+//--------------------------------------------------
+
+static const u8 ClockGfx_Misc[] = INCBIN_U8("graphics/misc/clock_misc.4bpp.lz");
+static const struct CompressedSpriteSheet gUnknown_083F7A90[] =
+{
+ {ClockGfx_Misc, 0x2000, 0x1000},
+ {NULL},
+};
+static const struct SpritePalette gUnknown_083F7AA0[] =
+{
+ {gMiscClockMale_Pal, 0x1000},
+ {gMiscClockFemale_Pal, 0x1001},
+ {NULL},
+};
+static const struct OamData gOamData_83F7AB8 =
+{
+ .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 gSpriteAnim_83F7AC0[] =
+{
+ ANIMCMD_FRAME(0, 30),
+ ANIMCMD_END,
+};
+static const union AnimCmd gSpriteAnim_83F7AC8[] =
+{
+ ANIMCMD_FRAME(64, 30),
+ ANIMCMD_END,
+};
+static const union AnimCmd *const gSpriteAnimTable_83F7AD0[] =
+{
+ gSpriteAnim_83F7AC0,
+};
+static const union AnimCmd *const gSpriteAnimTable_83F7AD4[] =
+{
+ gSpriteAnim_83F7AC8,
+};
+static void sub_810B05C(struct Sprite *sprite);
+static const struct SpriteTemplate gSpriteTemplate_83F7AD8 =
+{
+ .tileTag = 0x1000,
+ .paletteTag = 0x1000,
+ .oam = &gOamData_83F7AB8,
+ .anims = gSpriteAnimTable_83F7AD0,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_810B05C,
+};
+static void sub_810B0F4(struct Sprite *sprite);
+static const struct SpriteTemplate gSpriteTemplate_83F7AF0 =
+{
+ .tileTag = 0x1000,
+ .paletteTag = 0x1000,
+ .oam = &gOamData_83F7AB8,
+ .anims = gSpriteAnimTable_83F7AD4,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_810B0F4,
+};
+static const struct OamData gOamData_83F7B08 =
+{
+ .y = 160,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 1,
+ .tileNum = 0,
+ .priority = 2,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+static const union AnimCmd gSpriteAnim_83F7B10[] =
+{
+ ANIMCMD_FRAME(132, 30),
+ ANIMCMD_END,
+};
+static const union AnimCmd gSpriteAnim_83F7B18[] =
+{
+ ANIMCMD_FRAME(128, 30),
+ ANIMCMD_END,
+};
+static const union AnimCmd *const gSpriteAnimTable_83F7B20[] =
+{
+ gSpriteAnim_83F7B10,
+};
+static const union AnimCmd *const gSpriteAnimTable_83F7B24[] =
+{
+ gSpriteAnim_83F7B18,
+};
+static void sub_810B18C(struct Sprite *sprite);
+static const struct SpriteTemplate gSpriteTemplate_83F7B28 =
+{
+ .tileTag = 0x1000,
+ .paletteTag = 0x1000,
+ .oam = &gOamData_83F7B08,
+ .anims = gSpriteAnimTable_83F7B20,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_810B18C,
+};
+static void sub_810B230(struct Sprite *sprite);
+static const struct SpriteTemplate gSpriteTemplate_83F7B40 =
+{
+ .tileTag = 0x1000,
+ .paletteTag = 0x1000,
+ .oam = &gOamData_83F7B08,
+ .anims = gSpriteAnimTable_83F7B24,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_810B230,
+};
+
+static void WallClockVblankCallback(void);
+static void LoadWallClockGraphics(void);
+static void WallClockMainCallback(void);
+static void WallClockInit(void);
+static void Task_SetClock1(u8 taskId);
+static void Task_SetClock2(u8 taskId);
+static void Task_SetClock3(u8 taskId);
+static void Task_SetClock4(u8 taskId);
+static void Task_SetClock5(u8 taskId);
+static void Task_SetClock6(u8 taskId);
+static void Task_ViewClock1(u8 taskId);
+static void Task_ViewClock2(u8 taskId);
+static void Task_ViewClock3(u8 taskId);
+static void Task_ViewClock4(u8 taskId);
+static u8 CalcMinHandDelta(u16 speed);
+static u16 CalcNewMinHandAngle(u16 angle, u8 direction, u8 speed);
+static u8 AdvanceClock(u8 taskId, u8 direction);
+static void UpdateClockPeriod(u8 taskId, u8 direction);
+static void InitClockWithRtc(u8 taskId);
+
+enum
+{
+ PERIOD_AM,
+ PERIOD_PM,
+};
+
+enum
+{
+ MVMT_NONE,
+ MVMT_BACKWARD,
+ MVMT_FORWARD,
+};
+
+static void WallClockVblankCallback(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+static void LoadWallClockGraphics(void)
+{
+ u8 *addr;
+ u32 size;
+
+ SetVBlankCallback(0);
+ REG_DISPCNT = 0;
+ REG_BG3CNT = 0;
+ REG_BG2CNT = 0;
+ REG_BG1CNT = 0;
+ REG_BG0CNT = 0;
+ REG_BG3HOFS = 0;
+ REG_BG3VOFS = 0;
+ REG_BG2HOFS = 0;
+ REG_BG2VOFS = 0;
+ REG_BG1HOFS = 0;
+ REG_BG1VOFS = 0;
+ REG_BG0HOFS = 0;
+ REG_BG0VOFS = 0;
+
+ addr = (void *)VRAM;
+ size = 0x18000;
+ while (1)
+ {
+ DmaFill16(3, 0, addr, 0x1000);
+ addr += 0x1000;
+ size -= 0x1000;
+ if (size <= 0x1000)
+ {
+ DmaFill16(3, 0, addr, size);
+ break;
+ }
+ }
+ DmaClear32(3, OAM, OAM_SIZE);
+ DmaClear16(3, PLTT, PLTT_SIZE);
+
+ LZ77UnCompVram(gMiscClock_Gfx, (void *)VRAM);
+ if (gSpecialVar_0x8004 == MALE)
+ LoadPalette(gMiscClockMale_Pal, 0, 32);
+ else
+ LoadPalette(gMiscClockFemale_Pal, 0, 32);
+ remove_some_task();
+ ResetTasks();
+ ResetSpriteData();
+ ResetPaletteFade();
+ FreeAllSpritePalettes();
+ LoadCompressedObjectPic(&gUnknown_083F7A90[0]);
+ LoadSpritePalettes(gUnknown_083F7AA0);
+ SetUpWindowConfig(&gWindowConfig_81E6C3C);
+ InitMenuWindow(&gWindowConfig_81E6CE4);
+}
+
+static void WallClockInit(void)
+{
+ u16 ime;
+
+ BeginNormalPaletteFade(-1, 0, 0x10, 0, 0);
+ ime = REG_IME;
+ REG_IME = 0;
+ REG_IE |= INTR_FLAG_VBLANK;
+ REG_IME = ime;
+ REG_DISPSTAT |= DISPSTAT_VBLANK_INTR;
+ SetVBlankCallback(WallClockVblankCallback);
+ SetMainCallback2(WallClockMainCallback);
+ REG_BLDCNT = 0;
+ REG_BLDALPHA = 0;
+ REG_BLDY = 0;
+ REG_BG3CNT = BGCNT_PRIORITY(1) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(7) | BGCNT_16COLOR | BGCNT_TXT256x256;
+ REG_BG0CNT = BGCNT_PRIORITY(0) | BGCNT_CHARBASE(2) | BGCNT_SCREENBASE(31) | BGCNT_16COLOR | BGCNT_TXT256x256;
+ REG_DISPCNT = DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON |
+ DISPCNT_BG3_ON | DISPCNT_OBJ_ON;
+}
+
+#define tMinuteHandAngle data[0]
+#define tHourHandAngle data[1]
+#define tHours data[2]
+#define tMinutes data[3]
+#define tMvmtDir data[4]
+#define tPeriod data[5]
+#define tMvmtSpeed data[6]
+
+//Allow player to set the clock
+void CB2_StartWallClock(void)
+{
+ u8 taskId;
+ u8 spriteId;
+
+ LoadWallClockGraphics();
+ LZ77UnCompVram(&gUnknown_08E954B0, (void *)(VRAM + 0x3800));
+
+ taskId = CreateTask(Task_SetClock1, 0);
+ gTasks[taskId].tHours = 10;
+ gTasks[taskId].tMinutes = 0;
+ gTasks[taskId].tMvmtDir = MVMT_NONE;
+ gTasks[taskId].tPeriod = PERIOD_AM;
+ gTasks[taskId].tMvmtSpeed = 0;
+ gTasks[taskId].tMinuteHandAngle = 0;
+ gTasks[taskId].tHourHandAngle = 300;
+
+ spriteId = CreateSprite(&gSpriteTemplate_83F7AD8, DISPLAY_WIDTH / 2, DISPLAY_HEIGHT / 2, 1);
+ gSprites[spriteId].data0 = taskId;
+ gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL;
+ gSprites[spriteId].oam.matrixNum = 0;
+
+ spriteId = CreateSprite(&gSpriteTemplate_83F7AF0, DISPLAY_WIDTH / 2, DISPLAY_HEIGHT / 2, 0);
+ gSprites[spriteId].data0 = taskId;
+ gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL;
+ gSprites[spriteId].oam.matrixNum = 1;
+
+ spriteId = CreateSprite(&gSpriteTemplate_83F7B28, DISPLAY_WIDTH / 2, DISPLAY_HEIGHT / 2, 2);
+ gSprites[spriteId].data0 = taskId;
+ gSprites[spriteId].data1 = 45;
+
+ spriteId = CreateSprite(&gSpriteTemplate_83F7B40, DISPLAY_WIDTH / 2, DISPLAY_HEIGHT / 2, 2);
+ gSprites[spriteId].data0 = taskId;
+ gSprites[spriteId].data1 = 90;
+
+ WallClockInit();
+}
+
+//View, but don't set, the clock
+void CB2_ViewWallClock(void)
+{
+ u8 taskId;
+ s16 angle1;
+ s16 angle2;
+ u8 spriteId;
+
+ LoadWallClockGraphics();
+ LZ77UnCompVram(gUnknown_08E95774, (void *)(VRAM + 0x3800));
+
+ taskId = CreateTask(Task_ViewClock1, 0);
+ InitClockWithRtc(taskId);
+ if (gTasks[taskId].tPeriod == PERIOD_AM)
+ {
+ angle1 = 45;
+ angle2 = 90;
+ }
+ else
+ {
+ angle1 = 90;
+ angle2 = 135;
+ }
+
+ spriteId = CreateSprite(&gSpriteTemplate_83F7AD8, 120, 80, 1);
+ gSprites[spriteId].data0 = taskId;
+ gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL;
+ gSprites[spriteId].oam.matrixNum = 0;
+
+ spriteId = CreateSprite(&gSpriteTemplate_83F7AF0, 120, 80, 0);
+ gSprites[spriteId].data0 = taskId;
+ gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL;
+ gSprites[spriteId].oam.matrixNum = 1;
+
+ spriteId = CreateSprite(&gSpriteTemplate_83F7B28, 120, 80, 2);
+ gSprites[spriteId].data0 = taskId;
+ gSprites[spriteId].data1 = angle1;
+
+ spriteId = CreateSprite(&gSpriteTemplate_83F7B40, 120, 80, 2);
+ gSprites[spriteId].data0 = taskId;
+ gSprites[spriteId].data1 = angle2;
+
+ WallClockInit();
+}
+
+static void WallClockMainCallback(void)
+{
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+}
+
+static void Task_SetClock1(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ gTasks[taskId].func = Task_SetClock2;
+}
+
+//Handle keypresses when setting clock
+static void Task_SetClock2(u8 taskId)
+{
+ if (gTasks[taskId].tMinuteHandAngle % 6)
+ {
+ gTasks[taskId].tMinuteHandAngle = CalcNewMinHandAngle(
+ gTasks[taskId].tMinuteHandAngle,
+ gTasks[taskId].tMvmtDir,
+ gTasks[taskId].tMvmtSpeed);
+ }
+ else
+ {
+ gTasks[taskId].tMinuteHandAngle = gTasks[taskId].tMinutes * 6;
+ gTasks[taskId].tHourHandAngle = (gTasks[taskId].tHours % 12) * 30 + (gTasks[taskId].tMinutes / 10) * 5;
+ if (gMain.newKeys & A_BUTTON)
+ {
+ gTasks[taskId].func = Task_SetClock3;
+ return;
+ }
+ else
+ {
+ gTasks[taskId].tMvmtDir = gMain.newKeys & A_BUTTON;
+ if (gMain.heldKeys & DPAD_LEFT)
+ gTasks[taskId].tMvmtDir = MVMT_BACKWARD;
+ if (gMain.heldKeys & DPAD_RIGHT)
+ gTasks[taskId].tMvmtDir = MVMT_FORWARD;
+ if (gTasks[taskId].tMvmtDir)
+ {
+ if (gTasks[taskId].tMvmtSpeed < 0xFF)
+ gTasks[taskId].tMvmtSpeed++;
+ gTasks[taskId].tMinuteHandAngle = CalcNewMinHandAngle(
+ gTasks[taskId].tMinuteHandAngle,
+ gTasks[taskId].tMvmtDir,
+ gTasks[taskId].tMvmtSpeed);
+ AdvanceClock(taskId, gTasks[taskId].tMvmtDir);
+ }
+ else
+ {
+ gTasks[taskId].tMvmtSpeed = 0;
+ }
+ }
+ }
+}
+
+//Ask player "Is this the correct time?"
+static void Task_SetClock3(u8 taskId)
+{
+ MenuDrawTextWindow(2, 16, 27, 19);
+ MenuPrint(gOtherText_CorrectTimePrompt, 3, 17);
+ MenuDrawTextWindow(23, 8, 29, 13);
+ PrintMenuItems(24, 9, 2, gMenuYesNoItems);
+ InitMenu(0, 24, 9, 2, 1, 5);
+ gTasks[taskId].func = Task_SetClock4;
+}
+
+//Get menu selection
+static void Task_SetClock4(u8 taskId)
+{
+ switch (ProcessMenuInputNoWrap_())
+ {
+ case 0: //YES
+ PlaySE(SE_SELECT);
+ gTasks[taskId].func = Task_SetClock5; //Move on
+ return;
+ case -1: //B button
+ case 1: //NO
+ HandleDestroyMenuCursors();
+ PlaySE(SE_SELECT);
+ MenuZeroFillWindowRect(23, 8, 29, 13);
+ MenuZeroFillWindowRect(2, 16, 27, 19);
+ gTasks[taskId].func = Task_SetClock2; //Go back and let player adjust clock
+ }
+}
+
+//Set the time offset based on the wall clock's time
+static void Task_SetClock5(u8 taskId)
+{
+ RtcInitLocalTimeOffset(gTasks[taskId].tHours, gTasks[taskId].tMinutes);
+ BeginNormalPaletteFade(-1, 0, 0, 16, 0);
+ gTasks[taskId].func = Task_SetClock6;
+}
+
+static void Task_SetClock6(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ SetMainCallback2((MainCallback)gMain.savedCallback);
+}
+
+static void Task_ViewClock1(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ gTasks[taskId].func = Task_ViewClock2;
+}
+
+//Wait for A or B press
+static void Task_ViewClock2(u8 taskId)
+{
+ InitClockWithRtc(taskId);
+ if (gMain.newKeys & (A_BUTTON | B_BUTTON))
+ gTasks[taskId].func = Task_ViewClock3;
+}
+
+static void Task_ViewClock3(u8 taskId)
+{
+ BeginNormalPaletteFade(-1, 0, 0, 16, 0);
+ gTasks[taskId].func = Task_ViewClock4;
+}
+
+static void Task_ViewClock4(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ SetMainCallback2((MainCallback)gMain.savedCallback);
+}
+
+static u8 CalcMinHandDelta(u16 speed)
+{
+ if (speed > 60)
+ return 6;
+ else if (speed > 30)
+ return 3;
+ else if (speed > 10)
+ return 2;
+ else
+ return 1;
+}
+
+//Calculates the new angle of the minute hand when setting the clock
+static u16 CalcNewMinHandAngle(u16 angle, u8 direction, u8 speed)
+{
+ u8 delta = CalcMinHandDelta(speed);
+
+ switch (direction)
+ {
+ case MVMT_BACKWARD:
+ if (angle)
+ angle = angle - delta;
+ else
+ angle = 360 - delta;
+ break;
+ case MVMT_FORWARD:
+ if (angle < 360 - delta)
+ angle = angle + delta;
+ else
+ angle = 0;
+ break;
+ }
+ return angle;
+}
+
+//Advances clock forward or backward by 1 minute
+static u8 AdvanceClock(u8 taskId, u8 direction)
+{
+ switch (direction)
+ {
+ case MVMT_BACKWARD:
+ if (gTasks[taskId].tMinutes > 0)
+ gTasks[taskId].tMinutes--;
+ else
+ {
+ gTasks[taskId].tMinutes = 59;
+ if (gTasks[taskId].tHours > 0)
+ gTasks[taskId].tHours--;
+ else
+ gTasks[taskId].tHours = 23;
+ UpdateClockPeriod(taskId, direction);
+ }
+ break;
+ case MVMT_FORWARD:
+ if (gTasks[taskId].tMinutes < 59)
+ gTasks[taskId].tMinutes++;
+ else
+ {
+ gTasks[taskId].tMinutes = 0;
+ if (gTasks[taskId].tHours < 23)
+ gTasks[taskId].tHours++;
+ else
+ gTasks[taskId].tHours = 0;
+ UpdateClockPeriod(taskId, direction);
+ }
+ break;
+ }
+ return 0;
+}
+
+//Updates the clock period (AM/PM) if it needs to change
+static void UpdateClockPeriod(u8 taskId, u8 direction)
+{
+ u8 hours = gTasks[taskId].tHours;
+
+ switch (direction)
+ {
+ case MVMT_BACKWARD:
+ switch (hours)
+ {
+ case 11:
+ gTasks[taskId].tPeriod = PERIOD_AM;
+ break;
+ case 23:
+ gTasks[taskId].tPeriod = PERIOD_PM;
+ break;
+ }
+ break;
+ case MVMT_FORWARD:
+ switch (hours)
+ {
+ case 0:
+ gTasks[taskId].tPeriod = PERIOD_AM;
+ break;
+ case 12:
+ gTasks[taskId].tPeriod = PERIOD_PM;
+ break;
+ }
+ break;
+ }
+}
+
+static void InitClockWithRtc(u8 taskId)
+{
+ RtcCalcLocalTime();
+ gTasks[taskId].tHours = gLocalTime.hours;
+ gTasks[taskId].tMinutes = gLocalTime.minutes;
+ gTasks[taskId].tMinuteHandAngle = gTasks[taskId].tMinutes * 6;
+ gTasks[taskId].tHourHandAngle = (gTasks[taskId].tHours % 12) * 30 + (gTasks[taskId].tMinutes / 10) * 5;
+ if (gLocalTime.hours <= 11)
+ gTasks[taskId].tPeriod = PERIOD_AM;
+ else
+ gTasks[taskId].tPeriod = PERIOD_PM;
+}
+
+static const s8 gClockHandCoords[][2] =
+{
+ { 0, -24},
+ { 1, -25},
+ { 1, -25},
+ { 2, -25},
+ { 2, -25},
+ { 2, -25},
+ { 3, -24},
+ { 3, -25},
+ { 4, -25},
+ { 4, -25},
+ { 4, -25},
+ { 5, -25},
+ { 5, -25},
+ { 6, -24},
+ { 6, -24},
+ { 6, -24},
+ { 7, -24},
+ { 7, -24},
+ { 7, -24},
+ { 8, -24},
+ { 8, -24},
+ { 9, -24},
+ { 9, -24},
+ { 10, -23},
+ { 10, -23},
+ { 11, -22},
+ { 11, -22},
+ { 11, -22},
+ { 12, -22},
+ { 12, -21},
+ { 13, -21},
+ { 13, -21},
+ { 13, -21},
+ { 14, -21},
+ { 14, -21},
+ { 14, -20},
+ { 14, -20},
+ { 15, -20},
+ { 15, -19},
+ { 16, -19},
+ { 16, -19},
+ { 16, -19},
+ { 16, -18},
+ { 16, -18},
+ { 17, -18},
+ { 17, -17},
+ { 17, -17},
+ { 18, -17},
+ { 18, -17},
+ { 18, -16},
+ { 18, -16},
+ { 19, -16},
+ { 19, -15},
+ { 19, -15},
+ { 20, -15},
+ { 20, -14},
+ { 20, -14},
+ { 20, -13},
+ { 20, -13},
+ { 21, -13},
+ { 21, -13},
+ { 21, -12},
+ { 22, -12},
+ { 22, -12},
+ { 22, -11},
+ { 22, -11},
+ { 22, -10},
+ { 23, -10},
+ { 23, -9},
+ { 23, -9},
+ { 23, -9},
+ { 23, -9},
+ { 23, -8},
+ { 23, -8},
+ { 23, -7},
+ { 23, -7},
+ { 23, -6},
+ { 24, -6},
+ { 24, -6},
+ { 25, -5},
+ { 25, -5},
+ { 24, -4},
+ { 25, -4},
+ { 24, -3},
+ { 25, -3},
+ { 25, -3},
+ { 25, -2},
+ { 25, -2},
+ { 24, -1},
+ { 25, -1},
+ { 24, 0},
+ { 24, 0},
+ { 24, 0},
+ { 24, 1},
+ { 24, 1},
+ { 25, 2},
+ { 24, 2},
+ { 25, 2},
+ { 24, 3},
+ { 24, 3},
+ { 25, 4},
+ { 24, 4},
+ { 24, 5},
+ { 24, 5},
+ { 24, 5},
+ { 24, 6},
+ { 23, 6},
+ { 23, 6},
+ { 23, 7},
+ { 23, 8},
+ { 23, 8},
+ { 23, 8},
+ { 23, 9},
+ { 23, 9},
+ { 23, 10},
+ { 22, 10},
+ { 22, 10},
+ { 22, 11},
+ { 22, 11},
+ { 22, 11},
+ { 22, 12},
+ { 21, 12},
+ { 21, 12},
+ { 21, 13},
+ { 20, 13},
+ { 20, 13},
+ { 19, 13},
+ { 19, 13},
+ { 19, 14},
+ { 19, 14},
+ { 19, 15},
+ { 19, 15},
+ { 18, 15},
+ { 18, 16},
+ { 17, 16},
+ { 17, 16},
+ { 17, 17},
+ { 17, 17},
+ { 16, 17},
+ { 16, 18},
+ { 16, 18},
+ { 15, 18},
+ { 14, 18},
+ { 15, 19},
+ { 14, 19},
+ { 14, 19},
+ { 13, 19},
+ { 13, 20},
+ { 13, 20},
+ { 13, 20},
+ { 12, 20},
+ { 12, 20},
+ { 12, 21},
+ { 11, 21},
+ { 11, 21},
+ { 11, 21},
+ { 10, 21},
+ { 10, 22},
+ { 10, 22},
+ { 9, 22},
+ { 9, 22},
+ { 8, 22},
+ { 7, 22},
+ { 7, 23},
+ { 7, 23},
+ { 6, 23},
+ { 6, 23},
+ { 5, 23},
+ { 5, 23},
+ { 5, 24},
+ { 4, 24},
+ { 4, 24},
+ { 4, 24},
+ { 3, 24},
+ { 2, 24},
+ { 2, 24},
+ { 1, 24},
+ { 1, 24},
+ { 0, 24},
+ { 0, 24},
+ { -1, 23},
+ { 0, 24},
+ { 0, 24},
+ { -1, 24},
+ { -1, 24},
+ { -2, 24},
+ { -2, 24},
+ { -3, 24},
+ { -3, 24},
+ { -4, 24},
+ { -4, 24},
+ { -5, 24},
+ { -5, 23},
+ { -5, 23},
+ { -6, 23},
+ { -6, 23},
+ { -7, 23},
+ { -7, 23},
+ { -7, 23},
+ { -8, 23},
+ { -8, 22},
+ { -9, 22},
+ { -9, 22},
+ {-10, 22},
+ {-10, 22},
+ {-10, 21},
+ {-11, 21},
+ {-11, 21},
+ {-11, 21},
+ {-11, 20},
+ {-12, 20},
+ {-12, 20},
+ {-13, 20},
+ {-13, 20},
+ {-13, 19},
+ {-14, 19},
+ {-14, 19},
+ {-14, 19},
+ {-14, 18},
+ {-15, 18},
+ {-15, 18},
+ {-15, 17},
+ {-16, 17},
+ {-16, 17},
+ {-17, 17},
+ {-17, 16},
+ {-17, 16},
+ {-18, 16},
+ {-17, 15},
+ {-18, 15},
+ {-18, 15},
+ {-19, 15},
+ {-19, 14},
+ {-19, 14},
+ {-19, 13},
+ {-19, 13},
+ {-20, 13},
+ {-20, 12},
+ {-20, 12},
+ {-21, 12},
+ {-21, 12},
+ {-21, 11},
+ {-21, 11},
+ {-21, 10},
+ {-21, 10},
+ {-21, 9},
+ {-22, 9},
+ {-22, 9},
+ {-22, 8},
+ {-22, 8},
+ {-22, 7},
+ {-23, 7},
+ {-23, 7},
+ {-23, 6},
+ {-23, 6},
+ {-23, 5},
+ {-24, 5},
+ {-23, 4},
+ {-23, 4},
+ {-24, 4},
+ {-24, 4},
+ {-24, 3},
+ {-24, 3},
+ {-24, 2},
+ {-24, 2},
+ {-24, 1},
+ {-24, 1},
+ {-24, 1},
+ {-24, 0},
+ {-25, 0},
+ {-24, -1},
+ {-25, -1},
+ {-24, -1},
+ {-24, -2},
+ {-24, -2},
+ {-24, -3},
+ {-24, -3},
+ {-24, -4},
+ {-24, -4},
+ {-24, -4},
+ {-24, -5},
+ {-24, -5},
+ {-24, -6},
+ {-24, -6},
+ {-23, -6},
+ {-23, -7},
+ {-23, -7},
+ {-23, -8},
+ {-23, -8},
+ {-23, -9},
+ {-23, -9},
+ {-22, -9},
+ {-22, -9},
+ {-22, -10},
+ {-22, -10},
+ {-21, -10},
+ {-21, -11},
+ {-22, -11},
+ {-22, -12},
+ {-21, -12},
+ {-21, -13},
+ {-21, -13},
+ {-20, -13},
+ {-21, -14},
+ {-20, -14},
+ {-20, -14},
+ {-19, -14},
+ {-19, -15},
+ {-19, -15},
+ {-18, -16},
+ {-18, -16},
+ {-18, -16},
+ {-18, -17},
+ {-18, -17},
+ {-17, -17},
+ {-17, -18},
+ {-17, -18},
+ {-16, -18},
+ {-16, -18},
+ {-16, -19},
+ {-16, -19},
+ {-15, -19},
+ {-15, -19},
+ {-15, -20},
+ {-14, -20},
+ {-14, -20},
+ {-14, -21},
+ {-13, -21},
+ {-13, -21},
+ {-13, -21},
+ {-12, -21},
+ {-12, -22},
+ {-11, -22},
+ {-11, -22},
+ {-11, -22},
+ {-10, -22},
+ {-10, -22},
+ { -9, -22},
+ { -9, -23},
+ { -9, -23},
+ { -8, -23},
+ { -8, -23},
+ { -7, -23},
+ { -7, -23},
+ { -7, -24},
+ { -6, -24},
+ { -6, -24},
+ { -5, -24},
+ { -5, -24},
+ { -4, -24},
+ { -4, -24},
+ { -4, -24},
+ { -4, -25},
+ { -3, -25},
+ { -2, -25},
+ { -2, -24},
+ { -2, -24},
+ { -1, -25},
+ { -1, -25},
+ { 0, -25},
+};
+
+static void sub_810B05C(struct Sprite *sprite)
+{
+ u16 angle;
+ s16 sin;
+ s16 cos;
+ u16 x;
+ u16 y;
+
+ angle = gTasks[sprite->data0].tMinuteHandAngle;
+ sin = Sin2(angle) / 16;
+ cos = Cos2(angle) / 16;
+ SetOamMatrix(0, cos, sin, -sin, cos);
+ x = gClockHandCoords[angle][0];
+ y = gClockHandCoords[angle][1];
+
+ //Manual sign extension
+ if (x > 0x80)
+ x |= 0xFF00;
+ if (y > 0x80)
+ y |= 0xFF00;
+
+ sprite->pos2.x = x;
+ sprite->pos2.y = y;
+}
+
+static void sub_810B0F4(struct Sprite *sprite)
+{
+ u16 angle;
+ s16 sin;
+ s16 cos;
+ u16 x;
+ u16 y;
+
+ angle = gTasks[sprite->data0].tHourHandAngle;
+ sin = Sin2(angle) / 16;
+ cos = Cos2(angle) / 16;
+ SetOamMatrix(1, cos, sin, -sin, cos);
+ x = gClockHandCoords[angle][0];
+ y = gClockHandCoords[angle][1];
+
+ //Manual sign extension
+ if (x > 0x80)
+ x |= 0xFF00;
+ if (y > 0x80)
+ y |= 0xFF00;
+
+ sprite->pos2.x = x;
+ sprite->pos2.y = y;
+}
+
+static void sub_810B18C(struct Sprite *sprite)
+{
+ s16 sin;
+ s16 cos;
+
+ if (gTasks[sprite->data0].tPeriod != PERIOD_AM)
+ {
+ if (sprite->data1 >= 60 && sprite->data1 < 90)
+ sprite->data1 += 5;
+ if (sprite->data1 < 60)
+ sprite->data1++;
+ }
+ else
+ {
+ if (sprite->data1 > 45 && sprite->data1 <= 75)
+ sprite->data1 -= 5;
+ if (sprite->data1 > 75)
+ sprite->data1--;
+ }
+ cos = Cos2((u16)sprite->data1);
+ sprite->pos2.x = cos * 30 / 4096;
+ sin = Sin2((u16)sprite->data1);
+ sprite->pos2.y = sin * 30 / 4096;
+}
+
+static void sub_810B230(struct Sprite *sprite)
+{
+ s16 sin;
+ s16 cos;
+
+ if (gTasks[sprite->data0].tPeriod != PERIOD_AM)
+ {
+ if (sprite->data1 >= 105 && sprite->data1 < 135)
+ sprite->data1 += 5;
+ if (sprite->data1 < 105)
+ sprite->data1++;
+ }
+ else
+ {
+ if (sprite->data1 > 90 && sprite->data1 <= 120)
+ sprite->data1 -= 5;
+ if (sprite->data1 > 120)
+ sprite->data1--;
+ }
+ cos = Cos2((u16)sprite->data1);
+ sprite->pos2.x = cos * 30 / 4096;
+ sin = Sin2((u16)sprite->data1);
+ sprite->pos2.y = sin * 30 / 4096;
+}
diff --git a/src/field/wild_encounter.c b/src/field/wild_encounter.c
new file mode 100644
index 000000000..390898917
--- /dev/null
+++ b/src/field/wild_encounter.c
@@ -0,0 +1,3573 @@
+#include "global.h"
+#include "wild_encounter.h"
+#include "abilities.h"
+#include "battle_setup.h"
+#include "event_data.h"
+#include "field_player_avatar.h"
+#include "fieldmap.h"
+#include "map_constants.h"
+#include "metatile_behavior.h"
+#include "pokeblock.h"
+#include "rng.h"
+#include "roamer.h"
+#include "overworld.h"
+#include "safari_zone.h"
+#include "script.h"
+#include "species.h"
+#include "tv.h"
+
+const struct WildPokemon PetalburgCity_WaterMons [] =
+{
+ {20, 30, SPECIES_MARILL},
+ {10, 20, SPECIES_MARILL},
+ {30, 35, SPECIES_MARILL},
+ {5, 10, SPECIES_MARILL},
+ {5, 10, SPECIES_MARILL},
+};
+const struct WildPokemonInfo PetalburgCity_WaterMonsInfo = {1, PetalburgCity_WaterMons};
+
+const struct WildPokemon PetalburgCity_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_CORPHISH},
+ {25, 30, SPECIES_CORPHISH},
+ {30, 35, SPECIES_CORPHISH},
+ {20, 25, SPECIES_CORPHISH},
+ {35, 40, SPECIES_CORPHISH},
+ {40, 45, SPECIES_CORPHISH},
+};
+const struct WildPokemonInfo PetalburgCity_FishingMonsInfo = {10, PetalburgCity_FishingMons};
+
+const struct WildPokemon SlateportCity_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo SlateportCity_WaterMonsInfo = {4, SlateportCity_WaterMons};
+
+const struct WildPokemon SlateportCity_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_WAILMER},
+ {20, 25, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo SlateportCity_FishingMonsInfo = {10, SlateportCity_FishingMons};
+
+const struct WildPokemon LilycoveCity_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo LilycoveCity_WaterMonsInfo = {4, LilycoveCity_WaterMons};
+
+const struct WildPokemon LilycoveCity_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_WAILMER},
+ {25, 30, SPECIES_STARYU},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo LilycoveCity_FishingMonsInfo = {10, LilycoveCity_FishingMons};
+
+const struct WildPokemon MossdeepCity_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo MossdeepCity_WaterMonsInfo = {4, MossdeepCity_WaterMons};
+
+const struct WildPokemon MossdeepCity_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_SHARPEDO},
+ {30, 35, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo MossdeepCity_FishingMonsInfo = {10, MossdeepCity_FishingMons};
+
+const struct WildPokemon SootopolisCity_WaterMons [] =
+{
+ {5, 35, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_MAGIKARP},
+ {15, 25, SPECIES_MAGIKARP},
+ {25, 30, SPECIES_MAGIKARP},
+ {25, 30, SPECIES_MAGIKARP},
+};
+const struct WildPokemonInfo SootopolisCity_WaterMonsInfo = {1, SootopolisCity_WaterMons};
+
+const struct WildPokemon SootopolisCity_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+#ifdef SAPPHIRE
+ {5, 10, SPECIES_TENTACOOL},
+#else
+ {10, 15, SPECIES_MAGIKARP},
+#endif
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_MAGIKARP},
+ {30, 35, SPECIES_MAGIKARP},
+ {30, 35, SPECIES_MAGIKARP},
+ {35, 40, SPECIES_GYARADOS},
+ {35, 45, SPECIES_GYARADOS},
+ {5, 45, SPECIES_GYARADOS},
+};
+const struct WildPokemonInfo SootopolisCity_FishingMonsInfo = {10, SootopolisCity_FishingMons};
+
+const struct WildPokemon EverGrandeCity_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo EverGrandeCity_WaterMonsInfo = {4, EverGrandeCity_WaterMons};
+
+const struct WildPokemon EverGrandeCity_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_LUVDISC},
+ {10, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_LUVDISC},
+ {30, 35, SPECIES_WAILMER},
+ {30, 35, SPECIES_CORSOLA},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo EverGrandeCity_FishingMonsInfo = {10, EverGrandeCity_FishingMons};
+
+const struct WildPokemon MeteorFalls_1F_1R_LandMons [] =
+{
+ {16, 16, SPECIES_ZUBAT},
+ {17, 17, SPECIES_ZUBAT},
+ {18, 18, SPECIES_ZUBAT},
+ {15, 15, SPECIES_ZUBAT},
+ {14, 14, SPECIES_ZUBAT},
+#ifdef SAPPHIRE
+ {16, 16, SPECIES_LUNATONE},
+ {18, 18, SPECIES_LUNATONE},
+ {14, 14, SPECIES_LUNATONE},
+#else
+ {16, 16, SPECIES_SOLROCK},
+ {18, 18, SPECIES_SOLROCK},
+ {14, 14, SPECIES_SOLROCK},
+#endif
+ {19, 19, SPECIES_ZUBAT},
+ {20, 20, SPECIES_ZUBAT},
+ {19, 19, SPECIES_ZUBAT},
+ {20, 20, SPECIES_ZUBAT},
+};
+const struct WildPokemonInfo MeteorFalls_1F_1R_LandMonsInfo = {10, MeteorFalls_1F_1R_LandMons};
+
+const struct WildPokemon MeteorFalls_1F_1R_WaterMons [] =
+{
+ {5, 35, SPECIES_ZUBAT},
+ {30, 35, SPECIES_ZUBAT},
+#ifdef SAPPHIRE
+ {25, 35, SPECIES_LUNATONE},
+ {15, 25, SPECIES_LUNATONE},
+ {5, 15, SPECIES_LUNATONE},
+#else
+ {25, 35, SPECIES_SOLROCK},
+ {15, 25, SPECIES_SOLROCK},
+ {5, 15, SPECIES_SOLROCK},
+#endif
+};
+const struct WildPokemonInfo MeteorFalls_1F_1R_WaterMonsInfo = {4, MeteorFalls_1F_1R_WaterMons};
+
+const struct WildPokemon MeteorFalls_1F_1R_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_BARBOACH},
+ {25, 30, SPECIES_BARBOACH},
+ {30, 35, SPECIES_BARBOACH},
+ {20, 25, SPECIES_BARBOACH},
+ {35, 40, SPECIES_BARBOACH},
+ {40, 45, SPECIES_BARBOACH},
+};
+const struct WildPokemonInfo MeteorFalls_1F_1R_FishingMonsInfo = {30, MeteorFalls_1F_1R_FishingMons};
+
+const struct WildPokemon MeteorFalls_1F_2R_LandMons [] =
+{
+ {33, 33, SPECIES_GOLBAT},
+ {35, 35, SPECIES_GOLBAT},
+ {33, 33, SPECIES_GOLBAT},
+#ifdef SAPPHIRE
+ {35, 35, SPECIES_LUNATONE},
+ {33, 33, SPECIES_LUNATONE},
+ {37, 37, SPECIES_LUNATONE},
+#else
+ {35, 35, SPECIES_SOLROCK},
+ {33, 33, SPECIES_SOLROCK},
+ {37, 37, SPECIES_SOLROCK},
+#endif
+ {35, 35, SPECIES_GOLBAT},
+#ifdef SAPPHIRE
+ {39, 39, SPECIES_LUNATONE},
+#else
+ {39, 39, SPECIES_SOLROCK},
+#endif
+ {38, 38, SPECIES_GOLBAT},
+ {40, 40, SPECIES_GOLBAT},
+ {38, 38, SPECIES_GOLBAT},
+ {40, 40, SPECIES_GOLBAT},
+};
+const struct WildPokemonInfo MeteorFalls_1F_2R_LandMonsInfo = {10, MeteorFalls_1F_2R_LandMons};
+
+const struct WildPokemon MeteorFalls_1F_2R_WaterMons [] =
+{
+ {30, 35, SPECIES_GOLBAT},
+ {30, 35, SPECIES_GOLBAT},
+#ifdef SAPPHIRE
+ {25, 35, SPECIES_LUNATONE},
+ {15, 25, SPECIES_LUNATONE},
+ {5, 15, SPECIES_LUNATONE},
+#else
+ {25, 35, SPECIES_SOLROCK},
+ {15, 25, SPECIES_SOLROCK},
+ {5, 15, SPECIES_SOLROCK},
+#endif
+};
+const struct WildPokemonInfo MeteorFalls_1F_2R_WaterMonsInfo = {4, MeteorFalls_1F_2R_WaterMons};
+
+const struct WildPokemon MeteorFalls_1F_2R_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_BARBOACH},
+ {25, 30, SPECIES_BARBOACH},
+ {30, 35, SPECIES_BARBOACH},
+ {30, 35, SPECIES_WHISCASH},
+ {35, 40, SPECIES_WHISCASH},
+ {40, 45, SPECIES_WHISCASH},
+};
+const struct WildPokemonInfo MeteorFalls_1F_2R_FishingMonsInfo = {30, MeteorFalls_1F_2R_FishingMons};
+
+const struct WildPokemon MeteorFalls_B1F_1R_LandMons [] =
+{
+ {33, 33, SPECIES_GOLBAT},
+ {35, 35, SPECIES_GOLBAT},
+ {33, 33, SPECIES_GOLBAT},
+#ifdef SAPPHIRE
+ {35, 35, SPECIES_LUNATONE},
+ {33, 33, SPECIES_LUNATONE},
+ {37, 37, SPECIES_LUNATONE},
+#else
+ {35, 35, SPECIES_SOLROCK},
+ {33, 33, SPECIES_SOLROCK},
+ {37, 37, SPECIES_SOLROCK},
+#endif
+ {35, 35, SPECIES_GOLBAT},
+#ifdef SAPPHIRE
+ {39, 39, SPECIES_LUNATONE},
+#else
+ {39, 39, SPECIES_SOLROCK},
+#endif
+ {38, 38, SPECIES_GOLBAT},
+ {40, 40, SPECIES_GOLBAT},
+ {38, 38, SPECIES_GOLBAT},
+ {40, 40, SPECIES_GOLBAT},
+};
+const struct WildPokemonInfo MeteorFalls_B1F_1R_LandMonsInfo = {10, MeteorFalls_B1F_1R_LandMons};
+
+const struct WildPokemon MeteorFalls_B1F_1R_WaterMons [] =
+{
+ {30, 35, SPECIES_GOLBAT},
+ {30, 35, SPECIES_GOLBAT},
+#ifdef SAPPHIRE
+ {25, 35, SPECIES_LUNATONE},
+ {15, 25, SPECIES_LUNATONE},
+ {5, 15, SPECIES_LUNATONE},
+#else
+ {25, 35, SPECIES_SOLROCK},
+ {15, 25, SPECIES_SOLROCK},
+ {5, 15, SPECIES_SOLROCK},
+#endif
+};
+const struct WildPokemonInfo MeteorFalls_B1F_1R_WaterMonsInfo = {4, MeteorFalls_B1F_1R_WaterMons};
+
+const struct WildPokemon MeteorFalls_B1F_1R_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_BARBOACH},
+ {25, 30, SPECIES_BARBOACH},
+ {30, 35, SPECIES_BARBOACH},
+ {30, 35, SPECIES_WHISCASH},
+ {35, 40, SPECIES_WHISCASH},
+ {40, 45, SPECIES_WHISCASH},
+};
+const struct WildPokemonInfo MeteorFalls_B1F_1R_FishingMonsInfo = {30, MeteorFalls_B1F_1R_FishingMons};
+
+const struct WildPokemon MeteorFalls_B1F_2R_LandMons [] =
+{
+ {33, 33, SPECIES_GOLBAT},
+ {35, 35, SPECIES_GOLBAT},
+ {30, 30, SPECIES_BAGON},
+#ifdef SAPPHIRE
+ {35, 35, SPECIES_LUNATONE},
+#else
+ {35, 35, SPECIES_SOLROCK},
+#endif
+ {35, 35, SPECIES_BAGON},
+#ifdef SAPPHIRE
+ {37, 37, SPECIES_LUNATONE},
+#else
+ {37, 37, SPECIES_SOLROCK},
+#endif
+ {25, 25, SPECIES_BAGON},
+#ifdef SAPPHIRE
+ {39, 39, SPECIES_LUNATONE},
+#else
+ {39, 39, SPECIES_SOLROCK},
+#endif
+ {38, 38, SPECIES_GOLBAT},
+ {40, 40, SPECIES_GOLBAT},
+ {38, 38, SPECIES_GOLBAT},
+ {40, 40, SPECIES_GOLBAT},
+};
+const struct WildPokemonInfo MeteorFalls_B1F_2R_LandMonsInfo = {10, MeteorFalls_B1F_2R_LandMons};
+
+const struct WildPokemon MeteorFalls_B1F_2R_WaterMons [] =
+{
+ {30, 35, SPECIES_GOLBAT},
+ {30, 35, SPECIES_GOLBAT},
+#ifdef SAPPHIRE
+ {25, 35, SPECIES_LUNATONE},
+ {15, 25, SPECIES_LUNATONE},
+ {5, 15, SPECIES_LUNATONE},
+#else
+ {25, 35, SPECIES_SOLROCK},
+ {15, 25, SPECIES_SOLROCK},
+ {5, 15, SPECIES_SOLROCK},
+#endif
+};
+const struct WildPokemonInfo MeteorFalls_B1F_2R_WaterMonsInfo = {4, MeteorFalls_B1F_2R_WaterMons};
+
+const struct WildPokemon MeteorFalls_B1F_2R_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_BARBOACH},
+ {25, 30, SPECIES_BARBOACH},
+ {30, 35, SPECIES_BARBOACH},
+ {30, 35, SPECIES_WHISCASH},
+ {35, 40, SPECIES_WHISCASH},
+ {40, 45, SPECIES_WHISCASH},
+};
+const struct WildPokemonInfo MeteorFalls_B1F_2R_FishingMonsInfo = {30, MeteorFalls_B1F_2R_FishingMons};
+
+const struct WildPokemon RusturfTunnel_LandMons [] =
+{
+ {6, 6, SPECIES_WHISMUR},
+ {7, 7, SPECIES_WHISMUR},
+ {6, 6, SPECIES_WHISMUR},
+ {6, 6, SPECIES_WHISMUR},
+ {7, 7, SPECIES_WHISMUR},
+ {7, 7, SPECIES_WHISMUR},
+ {5, 5, SPECIES_WHISMUR},
+ {8, 8, SPECIES_WHISMUR},
+ {5, 5, SPECIES_WHISMUR},
+ {8, 8, SPECIES_WHISMUR},
+ {5, 5, SPECIES_WHISMUR},
+ {8, 8, SPECIES_WHISMUR},
+};
+const struct WildPokemonInfo RusturfTunnel_LandMonsInfo = {10, RusturfTunnel_LandMons};
+
+const struct WildPokemon GraniteCave_1F_LandMons [] =
+{
+ {7, 7, SPECIES_ZUBAT},
+ {8, 8, SPECIES_MAKUHITA},
+ {7, 7, SPECIES_MAKUHITA},
+ {8, 8, SPECIES_ZUBAT},
+ {9, 9, SPECIES_MAKUHITA},
+ {8, 8, SPECIES_ABRA},
+ {10, 10, SPECIES_MAKUHITA},
+ {6, 6, SPECIES_MAKUHITA},
+ {7, 7, SPECIES_GEODUDE},
+ {8, 8, SPECIES_GEODUDE},
+ {6, 6, SPECIES_GEODUDE},
+ {9, 9, SPECIES_GEODUDE},
+};
+const struct WildPokemonInfo GraniteCave_1F_LandMonsInfo = {10, GraniteCave_1F_LandMons};
+
+const struct WildPokemon GraniteCave_B1F_LandMons [] =
+{
+ {9, 9, SPECIES_ZUBAT},
+ {10, 10, SPECIES_ARON},
+ {9, 9, SPECIES_ARON},
+ {11, 11, SPECIES_ARON},
+ {10, 10, SPECIES_ZUBAT},
+ {9, 9, SPECIES_ABRA},
+ {10, 10, SPECIES_MAKUHITA},
+ {11, 11, SPECIES_MAKUHITA},
+#ifdef SAPPHIRE
+ {10, 10, SPECIES_SABLEYE},
+ {10, 10, SPECIES_SABLEYE},
+ {9, 9, SPECIES_SABLEYE},
+ {11, 11, SPECIES_SABLEYE},
+#else
+ {10, 10, SPECIES_MAWILE},
+ {10, 10, SPECIES_MAWILE},
+ {9, 9, SPECIES_MAWILE},
+ {11, 11, SPECIES_MAWILE},
+#endif
+};
+const struct WildPokemonInfo GraniteCave_B1F_LandMonsInfo = {10, GraniteCave_B1F_LandMons};
+
+const struct WildPokemon GraniteCave_B2F_LandMons [] =
+{
+ {10, 10, SPECIES_ZUBAT},
+ {11, 11, SPECIES_ARON},
+ {10, 10, SPECIES_ARON},
+ {11, 11, SPECIES_ZUBAT},
+ {12, 12, SPECIES_ARON},
+ {10, 10, SPECIES_ABRA},
+#ifdef SAPPHIRE
+ {10, 10, SPECIES_SABLEYE},
+ {11, 11, SPECIES_SABLEYE},
+ {12, 12, SPECIES_SABLEYE},
+ {10, 10, SPECIES_SABLEYE},
+ {12, 12, SPECIES_SABLEYE},
+ {10, 10, SPECIES_SABLEYE},
+#else
+ {10, 10, SPECIES_MAWILE},
+ {11, 11, SPECIES_MAWILE},
+ {12, 12, SPECIES_MAWILE},
+ {10, 10, SPECIES_MAWILE},
+ {12, 12, SPECIES_MAWILE},
+ {10, 10, SPECIES_MAWILE},
+#endif
+};
+const struct WildPokemonInfo GraniteCave_B2F_LandMonsInfo = {10, GraniteCave_B2F_LandMons};
+
+const struct WildPokemon GraniteCave_B2F_RockSmashMons [] =
+{
+ {10, 15, SPECIES_GEODUDE},
+ {10, 20, SPECIES_NOSEPASS},
+ {5, 10, SPECIES_GEODUDE},
+ {15, 20, SPECIES_GEODUDE},
+ {15, 20, SPECIES_GEODUDE},
+};
+const struct WildPokemonInfo GraniteCave_B2F_RockSmashMonsInfo = {20, GraniteCave_B2F_RockSmashMons};
+
+const struct WildPokemon GraniteCave_StevensRoom_LandMons [] =
+{
+ {7, 7, SPECIES_ZUBAT},
+ {8, 8, SPECIES_MAKUHITA},
+ {7, 7, SPECIES_MAKUHITA},
+ {8, 8, SPECIES_ZUBAT},
+ {9, 9, SPECIES_MAKUHITA},
+ {8, 8, SPECIES_ABRA},
+ {10, 10, SPECIES_MAKUHITA},
+ {6, 6, SPECIES_MAKUHITA},
+ {7, 7, SPECIES_ARON},
+ {8, 8, SPECIES_ARON},
+ {7, 7, SPECIES_ARON},
+ {8, 8, SPECIES_ARON},
+};
+const struct WildPokemonInfo GraniteCave_StevensRoom_LandMonsInfo = {10, GraniteCave_StevensRoom_LandMons};
+
+const struct WildPokemon PetalburgWoods_LandMons [] =
+{
+ {5, 5, SPECIES_ZIGZAGOON},
+ {5, 5, SPECIES_WURMPLE},
+ {5, 5, SPECIES_SHROOMISH},
+ {6, 6, SPECIES_ZIGZAGOON},
+ {5, 5, SPECIES_SILCOON},
+ {5, 5, SPECIES_CASCOON},
+ {6, 6, SPECIES_WURMPLE},
+ {6, 6, SPECIES_SHROOMISH},
+ {5, 5, SPECIES_TAILLOW},
+ {5, 5, SPECIES_SLAKOTH},
+ {6, 6, SPECIES_TAILLOW},
+ {6, 6, SPECIES_SLAKOTH},
+};
+const struct WildPokemonInfo PetalburgWoods_LandMonsInfo = {20, PetalburgWoods_LandMons};
+
+//Jagged Pass Pokemon are 2 levels higher on Sapphire
+#ifdef SAPPHIRE
+#define JAGGED_PASS_LEVEL_DIFF 2
+#else
+#define JAGGED_PASS_LEVEL_DIFF 0
+#endif
+
+const struct WildPokemon JaggedPass_LandMons [] =
+{
+ {19 + JAGGED_PASS_LEVEL_DIFF, 19 + JAGGED_PASS_LEVEL_DIFF, SPECIES_NUMEL},
+ {19 + JAGGED_PASS_LEVEL_DIFF, 19 + JAGGED_PASS_LEVEL_DIFF, SPECIES_NUMEL},
+ {19 + JAGGED_PASS_LEVEL_DIFF, 19 + JAGGED_PASS_LEVEL_DIFF, SPECIES_MACHOP},
+ {18 + JAGGED_PASS_LEVEL_DIFF, 18 + JAGGED_PASS_LEVEL_DIFF, SPECIES_NUMEL},
+ {18 + JAGGED_PASS_LEVEL_DIFF, 18 + JAGGED_PASS_LEVEL_DIFF, SPECIES_SPOINK},
+ {18 + JAGGED_PASS_LEVEL_DIFF, 18 + JAGGED_PASS_LEVEL_DIFF, SPECIES_MACHOP},
+ {19 + JAGGED_PASS_LEVEL_DIFF, 19 + JAGGED_PASS_LEVEL_DIFF, SPECIES_SPOINK},
+ {20 + JAGGED_PASS_LEVEL_DIFF, 20 + JAGGED_PASS_LEVEL_DIFF, SPECIES_MACHOP},
+ {20 + JAGGED_PASS_LEVEL_DIFF, 20 + JAGGED_PASS_LEVEL_DIFF, SPECIES_NUMEL},
+ {20 + JAGGED_PASS_LEVEL_DIFF, 20 + JAGGED_PASS_LEVEL_DIFF, SPECIES_SPOINK},
+ {20 + JAGGED_PASS_LEVEL_DIFF, 20 + JAGGED_PASS_LEVEL_DIFF, SPECIES_NUMEL},
+ {20 + JAGGED_PASS_LEVEL_DIFF, 20 + JAGGED_PASS_LEVEL_DIFF, SPECIES_SPOINK},
+};
+const struct WildPokemonInfo JaggedPass_LandMonsInfo = {20, JaggedPass_LandMons};
+
+const struct WildPokemon FieryPath_LandMons [] =
+{
+ {15, 15, SPECIES_NUMEL},
+#ifdef SAPPHIRE
+ {15, 15, SPECIES_GRIMER},
+#else
+ {15, 15, SPECIES_KOFFING},
+#endif
+ {16, 16, SPECIES_NUMEL},
+ {15, 15, SPECIES_MACHOP},
+ {15, 15, SPECIES_TORKOAL},
+ {15, 15, SPECIES_SLUGMA},
+#ifdef SAPPHIRE
+ {16, 16, SPECIES_GRIMER},
+#else
+ {16, 16, SPECIES_KOFFING},
+#endif
+ {16, 16, SPECIES_MACHOP},
+ {14, 14, SPECIES_TORKOAL},
+ {16, 16, SPECIES_TORKOAL},
+#ifdef SAPPHIRE
+ {14, 14, SPECIES_KOFFING},
+ {14, 14, SPECIES_KOFFING},
+#else
+ {14, 14, SPECIES_GRIMER},
+ {14, 14, SPECIES_GRIMER},
+#endif
+};
+const struct WildPokemonInfo FieryPath_LandMonsInfo = {10, FieryPath_LandMons};
+
+const struct WildPokemon MtPyre_1F_LandMons [] =
+{
+#ifdef SAPPHIRE
+ {27, 27, SPECIES_SHUPPET},
+ {28, 28, SPECIES_SHUPPET},
+ {26, 26, SPECIES_SHUPPET},
+ {25, 25, SPECIES_SHUPPET},
+ {29, 29, SPECIES_SHUPPET},
+ {24, 24, SPECIES_SHUPPET},
+ {23, 23, SPECIES_SHUPPET},
+ {22, 22, SPECIES_SHUPPET},
+ {29, 29, SPECIES_SHUPPET},
+ {24, 24, SPECIES_SHUPPET},
+ {29, 29, SPECIES_SHUPPET},
+ {24, 24, SPECIES_SHUPPET},
+#else
+ {27, 27, SPECIES_DUSKULL},
+ {28, 28, SPECIES_DUSKULL},
+ {26, 26, SPECIES_DUSKULL},
+ {25, 25, SPECIES_DUSKULL},
+ {29, 29, SPECIES_DUSKULL},
+ {24, 24, SPECIES_DUSKULL},
+ {23, 23, SPECIES_DUSKULL},
+ {22, 22, SPECIES_DUSKULL},
+ {29, 29, SPECIES_DUSKULL},
+ {24, 24, SPECIES_DUSKULL},
+ {29, 29, SPECIES_DUSKULL},
+ {24, 24, SPECIES_DUSKULL},
+#endif
+};
+const struct WildPokemonInfo MtPyre_1F_LandMonsInfo = {10, MtPyre_1F_LandMons};
+
+const struct WildPokemon MtPyre_2F_LandMons [] =
+{
+#ifdef SAPPHIRE
+ {27, 27, SPECIES_SHUPPET},
+ {28, 28, SPECIES_SHUPPET},
+ {26, 26, SPECIES_SHUPPET},
+ {25, 25, SPECIES_SHUPPET},
+ {29, 29, SPECIES_SHUPPET},
+ {24, 24, SPECIES_SHUPPET},
+ {23, 23, SPECIES_SHUPPET},
+ {22, 22, SPECIES_SHUPPET},
+ {29, 29, SPECIES_SHUPPET},
+ {24, 24, SPECIES_SHUPPET},
+ {29, 29, SPECIES_SHUPPET},
+ {24, 24, SPECIES_SHUPPET},
+#else
+ {27, 27, SPECIES_DUSKULL},
+ {28, 28, SPECIES_DUSKULL},
+ {26, 26, SPECIES_DUSKULL},
+ {25, 25, SPECIES_DUSKULL},
+ {29, 29, SPECIES_DUSKULL},
+ {24, 24, SPECIES_DUSKULL},
+ {23, 23, SPECIES_DUSKULL},
+ {22, 22, SPECIES_DUSKULL},
+ {29, 29, SPECIES_DUSKULL},
+ {24, 24, SPECIES_DUSKULL},
+ {29, 29, SPECIES_DUSKULL},
+ {24, 24, SPECIES_DUSKULL},
+#endif
+};
+const struct WildPokemonInfo MtPyre_2F_LandMonsInfo = {10, MtPyre_2F_LandMons};
+
+const struct WildPokemon MtPyre_3F_LandMons [] =
+{
+#ifdef SAPPHIRE
+ {27, 27, SPECIES_SHUPPET},
+ {28, 28, SPECIES_SHUPPET},
+ {26, 26, SPECIES_SHUPPET},
+ {25, 25, SPECIES_SHUPPET},
+ {29, 29, SPECIES_SHUPPET},
+ {24, 24, SPECIES_SHUPPET},
+ {23, 23, SPECIES_SHUPPET},
+ {22, 22, SPECIES_SHUPPET},
+ {29, 29, SPECIES_SHUPPET},
+ {24, 24, SPECIES_SHUPPET},
+ {29, 29, SPECIES_SHUPPET},
+ {24, 24, SPECIES_SHUPPET},
+#else
+ {27, 27, SPECIES_DUSKULL},
+ {28, 28, SPECIES_DUSKULL},
+ {26, 26, SPECIES_DUSKULL},
+ {25, 25, SPECIES_DUSKULL},
+ {29, 29, SPECIES_DUSKULL},
+ {24, 24, SPECIES_DUSKULL},
+ {23, 23, SPECIES_DUSKULL},
+ {22, 22, SPECIES_DUSKULL},
+ {29, 29, SPECIES_DUSKULL},
+ {24, 24, SPECIES_DUSKULL},
+ {29, 29, SPECIES_DUSKULL},
+ {24, 24, SPECIES_DUSKULL},
+#endif
+};
+const struct WildPokemonInfo MtPyre_3F_LandMonsInfo = {10, MtPyre_3F_LandMons};
+
+const struct WildPokemon MtPyre_4F_LandMons [] =
+{
+#ifdef SAPPHIRE
+ {27, 27, SPECIES_SHUPPET},
+ {28, 28, SPECIES_SHUPPET},
+ {26, 26, SPECIES_SHUPPET},
+ {25, 25, SPECIES_SHUPPET},
+ {29, 29, SPECIES_SHUPPET},
+ {24, 24, SPECIES_SHUPPET},
+ {23, 23, SPECIES_SHUPPET},
+ {22, 22, SPECIES_SHUPPET},
+ {27, 27, SPECIES_DUSKULL},
+ {27, 27, SPECIES_DUSKULL},
+ {25, 25, SPECIES_DUSKULL},
+ {29, 29, SPECIES_DUSKULL},
+#else
+ {27, 27, SPECIES_DUSKULL},
+ {28, 28, SPECIES_DUSKULL},
+ {26, 26, SPECIES_DUSKULL},
+ {25, 25, SPECIES_DUSKULL},
+ {29, 29, SPECIES_DUSKULL},
+ {24, 24, SPECIES_DUSKULL},
+ {23, 23, SPECIES_DUSKULL},
+ {22, 22, SPECIES_DUSKULL},
+ {27, 27, SPECIES_SHUPPET},
+ {27, 27, SPECIES_SHUPPET},
+ {25, 25, SPECIES_SHUPPET},
+ {29, 29, SPECIES_SHUPPET},
+#endif
+};
+const struct WildPokemonInfo MtPyre_4F_LandMonsInfo = {10, MtPyre_4F_LandMons};
+
+const struct WildPokemon MtPyre_5F_LandMons [] =
+{
+#ifdef SAPPHIRE
+ {27, 27, SPECIES_SHUPPET},
+ {28, 28, SPECIES_SHUPPET},
+ {26, 26, SPECIES_SHUPPET},
+ {25, 25, SPECIES_SHUPPET},
+ {29, 29, SPECIES_SHUPPET},
+ {24, 24, SPECIES_SHUPPET},
+ {23, 23, SPECIES_SHUPPET},
+ {22, 22, SPECIES_SHUPPET},
+ {27, 27, SPECIES_DUSKULL},
+ {27, 27, SPECIES_DUSKULL},
+ {25, 25, SPECIES_DUSKULL},
+ {29, 29, SPECIES_DUSKULL},
+#else
+ {27, 27, SPECIES_DUSKULL},
+ {28, 28, SPECIES_DUSKULL},
+ {26, 26, SPECIES_DUSKULL},
+ {25, 25, SPECIES_DUSKULL},
+ {29, 29, SPECIES_DUSKULL},
+ {24, 24, SPECIES_DUSKULL},
+ {23, 23, SPECIES_DUSKULL},
+ {22, 22, SPECIES_DUSKULL},
+ {27, 27, SPECIES_SHUPPET},
+ {27, 27, SPECIES_SHUPPET},
+ {25, 25, SPECIES_SHUPPET},
+ {29, 29, SPECIES_SHUPPET},
+#endif
+};
+const struct WildPokemonInfo MtPyre_5F_LandMonsInfo = {10, MtPyre_5F_LandMons};
+
+const struct WildPokemon MtPyre_6F_LandMons [] =
+{
+#ifdef SAPPHIRE
+ {27, 27, SPECIES_SHUPPET},
+ {28, 28, SPECIES_SHUPPET},
+ {26, 26, SPECIES_SHUPPET},
+ {25, 25, SPECIES_SHUPPET},
+ {29, 29, SPECIES_SHUPPET},
+ {24, 24, SPECIES_SHUPPET},
+ {23, 23, SPECIES_SHUPPET},
+ {22, 22, SPECIES_SHUPPET},
+ {27, 27, SPECIES_DUSKULL},
+ {27, 27, SPECIES_DUSKULL},
+ {25, 25, SPECIES_DUSKULL},
+ {29, 29, SPECIES_DUSKULL},
+#else
+ {27, 27, SPECIES_DUSKULL},
+ {28, 28, SPECIES_DUSKULL},
+ {26, 26, SPECIES_DUSKULL},
+ {25, 25, SPECIES_DUSKULL},
+ {29, 29, SPECIES_DUSKULL},
+ {24, 24, SPECIES_DUSKULL},
+ {23, 23, SPECIES_DUSKULL},
+ {22, 22, SPECIES_DUSKULL},
+ {27, 27, SPECIES_SHUPPET},
+ {27, 27, SPECIES_SHUPPET},
+ {25, 25, SPECIES_SHUPPET},
+ {29, 29, SPECIES_SHUPPET},
+#endif
+};
+const struct WildPokemonInfo MtPyre_6F_LandMonsInfo = {10, MtPyre_6F_LandMons};
+
+const struct WildPokemon MtPyre_Exterior_LandMons [] =
+{
+#ifdef SAPPHIRE
+ {27, 27, SPECIES_SHUPPET},
+#else
+ {27, 27, SPECIES_DUSKULL},
+#endif
+ {27, 27, SPECIES_MEDITITE},
+#ifdef SAPPHIRE
+ {28, 28, SPECIES_SHUPPET},
+#else
+ {28, 28, SPECIES_DUSKULL},
+#endif
+ {29, 29, SPECIES_MEDITITE},
+#ifdef SAPPHIRE
+ {29, 29, SPECIES_SHUPPET},
+#else
+ {29, 29, SPECIES_DUSKULL},
+#endif
+ {27, 27, SPECIES_VULPIX},
+ {29, 29, SPECIES_VULPIX},
+ {25, 25, SPECIES_VULPIX},
+ {27, 27, SPECIES_WINGULL},
+ {27, 27, SPECIES_WINGULL},
+ {26, 26, SPECIES_WINGULL},
+ {28, 28, SPECIES_WINGULL},
+};
+const struct WildPokemonInfo MtPyre_Exterior_LandMonsInfo = {10, MtPyre_Exterior_LandMons};
+
+const struct WildPokemon MtPyre_Summit_LandMons [] =
+{
+#ifdef SAPPHIRE
+ {28, 28, SPECIES_SHUPPET},
+ {29, 29, SPECIES_SHUPPET},
+ {27, 27, SPECIES_SHUPPET},
+ {26, 26, SPECIES_SHUPPET},
+ {30, 30, SPECIES_SHUPPET},
+ {25, 25, SPECIES_SHUPPET},
+ {24, 24, SPECIES_SHUPPET},
+ {28, 28, SPECIES_DUSKULL},
+ {26, 26, SPECIES_DUSKULL},
+ {30, 30, SPECIES_DUSKULL},
+#else
+ {28, 28, SPECIES_DUSKULL},
+ {29, 29, SPECIES_DUSKULL},
+ {27, 27, SPECIES_DUSKULL},
+ {26, 26, SPECIES_DUSKULL},
+ {30, 30, SPECIES_DUSKULL},
+ {25, 25, SPECIES_DUSKULL},
+ {24, 24, SPECIES_DUSKULL},
+ {28, 28, SPECIES_SHUPPET},
+ {26, 26, SPECIES_SHUPPET},
+ {30, 30, SPECIES_SHUPPET},
+#endif
+ {28, 28, SPECIES_CHIMECHO},
+ {28, 28, SPECIES_CHIMECHO},
+};
+const struct WildPokemonInfo MtPyre_Summit_LandMonsInfo = {10, MtPyre_Summit_LandMons};
+
+const struct WildPokemon SeafloorCavern_Entrance_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {5, 35, SPECIES_ZUBAT},
+ {30, 35, SPECIES_ZUBAT},
+ {30, 35, SPECIES_GOLBAT},
+ {30, 35, SPECIES_GOLBAT},
+};
+const struct WildPokemonInfo SeafloorCavern_Entrance_WaterMonsInfo = {4, SeafloorCavern_Entrance_WaterMons};
+
+const struct WildPokemon SeafloorCavern_Entrance_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_WAILMER},
+ {20, 25, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo SeafloorCavern_Entrance_FishingMonsInfo = {10, SeafloorCavern_Entrance_FishingMons};
+
+const struct WildPokemon SeafloorCavern_Room1_LandMons [] =
+{
+ {30, 30, SPECIES_ZUBAT},
+ {31, 31, SPECIES_ZUBAT},
+ {32, 32, SPECIES_ZUBAT},
+ {33, 33, SPECIES_ZUBAT},
+ {28, 28, SPECIES_ZUBAT},
+ {29, 29, SPECIES_ZUBAT},
+ {34, 34, SPECIES_ZUBAT},
+ {35, 35, SPECIES_ZUBAT},
+ {34, 34, SPECIES_GOLBAT},
+ {35, 35, SPECIES_GOLBAT},
+ {33, 33, SPECIES_GOLBAT},
+ {36, 36, SPECIES_GOLBAT},
+};
+const struct WildPokemonInfo SeafloorCavern_Room1_LandMonsInfo = {4, SeafloorCavern_Room1_LandMons};
+
+const struct WildPokemon SeafloorCavern_Room2_LandMons [] =
+{
+ {30, 30, SPECIES_ZUBAT},
+ {31, 31, SPECIES_ZUBAT},
+ {32, 32, SPECIES_ZUBAT},
+ {33, 33, SPECIES_ZUBAT},
+ {28, 28, SPECIES_ZUBAT},
+ {29, 29, SPECIES_ZUBAT},
+ {34, 34, SPECIES_ZUBAT},
+ {35, 35, SPECIES_ZUBAT},
+ {34, 34, SPECIES_GOLBAT},
+ {35, 35, SPECIES_GOLBAT},
+ {33, 33, SPECIES_GOLBAT},
+ {36, 36, SPECIES_GOLBAT},
+};
+const struct WildPokemonInfo SeafloorCavern_Room2_LandMonsInfo = {4, SeafloorCavern_Room2_LandMons};
+
+const struct WildPokemon SeafloorCavern_Room3_LandMons [] =
+{
+ {30, 30, SPECIES_ZUBAT},
+ {31, 31, SPECIES_ZUBAT},
+ {32, 32, SPECIES_ZUBAT},
+ {33, 33, SPECIES_ZUBAT},
+ {28, 28, SPECIES_ZUBAT},
+ {29, 29, SPECIES_ZUBAT},
+ {34, 34, SPECIES_ZUBAT},
+ {35, 35, SPECIES_ZUBAT},
+ {34, 34, SPECIES_GOLBAT},
+ {35, 35, SPECIES_GOLBAT},
+ {33, 33, SPECIES_GOLBAT},
+ {36, 36, SPECIES_GOLBAT},
+};
+const struct WildPokemonInfo SeafloorCavern_Room3_LandMonsInfo = {4, SeafloorCavern_Room3_LandMons};
+
+const struct WildPokemon SeafloorCavern_Room4_LandMons [] =
+{
+ {30, 30, SPECIES_ZUBAT},
+ {31, 31, SPECIES_ZUBAT},
+ {32, 32, SPECIES_ZUBAT},
+ {33, 33, SPECIES_ZUBAT},
+ {28, 28, SPECIES_ZUBAT},
+ {29, 29, SPECIES_ZUBAT},
+ {34, 34, SPECIES_ZUBAT},
+ {35, 35, SPECIES_ZUBAT},
+ {34, 34, SPECIES_GOLBAT},
+ {35, 35, SPECIES_GOLBAT},
+ {33, 33, SPECIES_GOLBAT},
+ {36, 36, SPECIES_GOLBAT},
+};
+const struct WildPokemonInfo SeafloorCavern_Room4_LandMonsInfo = {4, SeafloorCavern_Room4_LandMons};
+
+const struct WildPokemon SeafloorCavern_Room5_LandMons [] =
+{
+ {30, 30, SPECIES_ZUBAT},
+ {31, 31, SPECIES_ZUBAT},
+ {32, 32, SPECIES_ZUBAT},
+ {33, 33, SPECIES_ZUBAT},
+ {28, 28, SPECIES_ZUBAT},
+ {29, 29, SPECIES_ZUBAT},
+ {34, 34, SPECIES_ZUBAT},
+ {35, 35, SPECIES_ZUBAT},
+ {34, 34, SPECIES_GOLBAT},
+ {35, 35, SPECIES_GOLBAT},
+ {33, 33, SPECIES_GOLBAT},
+ {36, 36, SPECIES_GOLBAT},
+};
+const struct WildPokemonInfo SeafloorCavern_Room5_LandMonsInfo = {4, SeafloorCavern_Room5_LandMons};
+
+const struct WildPokemon SeafloorCavern_Room6_LandMons [] =
+{
+ {30, 30, SPECIES_ZUBAT},
+ {31, 31, SPECIES_ZUBAT},
+ {32, 32, SPECIES_ZUBAT},
+ {33, 33, SPECIES_ZUBAT},
+ {28, 28, SPECIES_ZUBAT},
+ {29, 29, SPECIES_ZUBAT},
+ {34, 34, SPECIES_ZUBAT},
+ {35, 35, SPECIES_ZUBAT},
+ {34, 34, SPECIES_GOLBAT},
+ {35, 35, SPECIES_GOLBAT},
+ {33, 33, SPECIES_GOLBAT},
+ {36, 36, SPECIES_GOLBAT},
+};
+const struct WildPokemonInfo SeafloorCavern_Room6_LandMonsInfo = {4, SeafloorCavern_Room6_LandMons};
+
+const struct WildPokemon SeafloorCavern_Room6_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {5, 35, SPECIES_ZUBAT},
+ {30, 35, SPECIES_ZUBAT},
+ {30, 35, SPECIES_GOLBAT},
+ {30, 35, SPECIES_GOLBAT},
+};
+const struct WildPokemonInfo SeafloorCavern_Room6_WaterMonsInfo = {4, SeafloorCavern_Room6_WaterMons};
+
+const struct WildPokemon SeafloorCavern_Room6_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_WAILMER},
+ {20, 25, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo SeafloorCavern_Room6_FishingMonsInfo = {10, SeafloorCavern_Room6_FishingMons};
+
+const struct WildPokemon SeafloorCavern_Room7_LandMons [] =
+{
+ {30, 30, SPECIES_ZUBAT},
+ {31, 31, SPECIES_ZUBAT},
+ {32, 32, SPECIES_ZUBAT},
+ {33, 33, SPECIES_ZUBAT},
+ {28, 28, SPECIES_ZUBAT},
+ {29, 29, SPECIES_ZUBAT},
+ {34, 34, SPECIES_ZUBAT},
+ {35, 35, SPECIES_ZUBAT},
+ {34, 34, SPECIES_GOLBAT},
+ {35, 35, SPECIES_GOLBAT},
+ {33, 33, SPECIES_GOLBAT},
+ {36, 36, SPECIES_GOLBAT},
+};
+const struct WildPokemonInfo SeafloorCavern_Room7_LandMonsInfo = {4, SeafloorCavern_Room7_LandMons};
+
+const struct WildPokemon SeafloorCavern_Room7_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {5, 35, SPECIES_ZUBAT},
+ {30, 35, SPECIES_ZUBAT},
+ {30, 35, SPECIES_GOLBAT},
+ {30, 35, SPECIES_GOLBAT},
+};
+const struct WildPokemonInfo SeafloorCavern_Room7_WaterMonsInfo = {4, SeafloorCavern_Room7_WaterMons};
+
+const struct WildPokemon SeafloorCavern_Room7_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_WAILMER},
+ {20, 25, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo SeafloorCavern_Room7_FishingMonsInfo = {10, SeafloorCavern_Room7_FishingMons};
+
+const struct WildPokemon SeafloorCavern_Room8_LandMons [] =
+{
+ {30, 30, SPECIES_ZUBAT},
+ {31, 31, SPECIES_ZUBAT},
+ {32, 32, SPECIES_ZUBAT},
+ {33, 33, SPECIES_ZUBAT},
+ {28, 28, SPECIES_ZUBAT},
+ {29, 29, SPECIES_ZUBAT},
+ {34, 34, SPECIES_ZUBAT},
+ {35, 35, SPECIES_ZUBAT},
+ {34, 34, SPECIES_GOLBAT},
+ {35, 35, SPECIES_GOLBAT},
+ {33, 33, SPECIES_GOLBAT},
+ {36, 36, SPECIES_GOLBAT},
+};
+const struct WildPokemonInfo SeafloorCavern_Room8_LandMonsInfo = {4, SeafloorCavern_Room8_LandMons};
+
+const struct WildPokemon CaveOfOrigin_Entrance_LandMons [] =
+{
+ {30, 30, SPECIES_ZUBAT},
+ {31, 31, SPECIES_ZUBAT},
+ {32, 32, SPECIES_ZUBAT},
+ {33, 33, SPECIES_ZUBAT},
+ {28, 28, SPECIES_ZUBAT},
+ {29, 29, SPECIES_ZUBAT},
+ {34, 34, SPECIES_ZUBAT},
+ {35, 35, SPECIES_ZUBAT},
+ {34, 34, SPECIES_GOLBAT},
+ {35, 35, SPECIES_GOLBAT},
+ {33, 33, SPECIES_GOLBAT},
+ {36, 36, SPECIES_GOLBAT},
+};
+const struct WildPokemonInfo CaveOfOrigin_Entrance_LandMonsInfo = {4, CaveOfOrigin_Entrance_LandMons};
+
+const struct WildPokemon CaveOfOrigin_1F_LandMons [] =
+{
+ {30, 30, SPECIES_ZUBAT},
+ {31, 31, SPECIES_ZUBAT},
+ {32, 32, SPECIES_ZUBAT},
+#ifdef SAPPHIRE
+ {30, 30, SPECIES_SABLEYE},
+ {32, 32, SPECIES_SABLEYE},
+ {34, 34, SPECIES_SABLEYE},
+#else
+ {30, 30, SPECIES_MAWILE},
+ {32, 32, SPECIES_MAWILE},
+ {34, 34, SPECIES_MAWILE},
+#endif
+ {33, 33, SPECIES_ZUBAT},
+ {34, 34, SPECIES_ZUBAT},
+ {34, 34, SPECIES_GOLBAT},
+ {35, 35, SPECIES_GOLBAT},
+ {33, 33, SPECIES_GOLBAT},
+ {36, 36, SPECIES_GOLBAT},
+};
+const struct WildPokemonInfo CaveOfOrigin_1F_LandMonsInfo = {4, CaveOfOrigin_1F_LandMons};
+
+const struct WildPokemon CaveOfOrigin_B1F_LandMons [] =
+{
+ {30, 30, SPECIES_ZUBAT},
+ {31, 31, SPECIES_ZUBAT},
+ {32, 32, SPECIES_ZUBAT},
+#ifdef SAPPHIRE
+ {30, 30, SPECIES_SABLEYE},
+ {32, 32, SPECIES_SABLEYE},
+ {34, 34, SPECIES_SABLEYE},
+#else
+ {30, 30, SPECIES_MAWILE},
+ {32, 32, SPECIES_MAWILE},
+ {34, 34, SPECIES_MAWILE},
+#endif
+ {33, 33, SPECIES_ZUBAT},
+ {34, 34, SPECIES_ZUBAT},
+ {34, 34, SPECIES_GOLBAT},
+ {35, 35, SPECIES_GOLBAT},
+ {33, 33, SPECIES_GOLBAT},
+ {36, 36, SPECIES_GOLBAT},
+};
+const struct WildPokemonInfo CaveOfOrigin_B1F_LandMonsInfo = {4, CaveOfOrigin_B1F_LandMons};
+
+const struct WildPokemon CaveOfOrigin_B2F_LandMons [] =
+{
+ {30, 30, SPECIES_ZUBAT},
+ {31, 31, SPECIES_ZUBAT},
+ {32, 32, SPECIES_ZUBAT},
+#ifdef SAPPHIRE
+ {30, 30, SPECIES_SABLEYE},
+ {32, 32, SPECIES_SABLEYE},
+ {34, 34, SPECIES_SABLEYE},
+#else
+ {30, 30, SPECIES_MAWILE},
+ {32, 32, SPECIES_MAWILE},
+ {34, 34, SPECIES_MAWILE},
+#endif
+ {33, 33, SPECIES_ZUBAT},
+ {34, 34, SPECIES_ZUBAT},
+ {34, 34, SPECIES_GOLBAT},
+ {35, 35, SPECIES_GOLBAT},
+ {33, 33, SPECIES_GOLBAT},
+ {36, 36, SPECIES_GOLBAT},
+};
+const struct WildPokemonInfo CaveOfOrigin_B2F_LandMonsInfo = {4, CaveOfOrigin_B2F_LandMons};
+
+const struct WildPokemon CaveOfOrigin_B3F_LandMons [] =
+{
+ {30, 30, SPECIES_ZUBAT},
+ {31, 31, SPECIES_ZUBAT},
+ {32, 32, SPECIES_ZUBAT},
+#ifdef SAPPHIRE
+ {30, 30, SPECIES_SABLEYE},
+ {32, 32, SPECIES_SABLEYE},
+ {34, 34, SPECIES_SABLEYE},
+#else
+ {30, 30, SPECIES_MAWILE},
+ {32, 32, SPECIES_MAWILE},
+ {34, 34, SPECIES_MAWILE},
+#endif
+ {33, 33, SPECIES_ZUBAT},
+ {34, 34, SPECIES_ZUBAT},
+ {34, 34, SPECIES_GOLBAT},
+ {35, 35, SPECIES_GOLBAT},
+ {33, 33, SPECIES_GOLBAT},
+ {36, 36, SPECIES_GOLBAT},
+};
+const struct WildPokemonInfo CaveOfOrigin_B3F_LandMonsInfo = {4, CaveOfOrigin_B3F_LandMons};
+
+const struct WildPokemon VictoryRoad_1F_LandMons [] =
+{
+ {40, 40, SPECIES_GOLBAT},
+ {40, 40, SPECIES_HARIYAMA},
+ {40, 40, SPECIES_LAIRON},
+ {40, 40, SPECIES_LOUDRED},
+ {36, 36, SPECIES_ZUBAT},
+ {36, 36, SPECIES_MAKUHITA},
+ {38, 38, SPECIES_GOLBAT},
+ {38, 38, SPECIES_HARIYAMA},
+ {36, 36, SPECIES_ARON},
+ {36, 36, SPECIES_WHISMUR},
+ {36, 36, SPECIES_ARON},
+ {36, 36, SPECIES_WHISMUR},
+};
+const struct WildPokemonInfo VictoryRoad_1F_LandMonsInfo = {10, VictoryRoad_1F_LandMons};
+
+const struct WildPokemon VictoryRoad_B1F_LandMons [] =
+{
+ {40, 40, SPECIES_GOLBAT},
+ {40, 40, SPECIES_HARIYAMA},
+ {40, 40, SPECIES_LAIRON},
+ {40, 40, SPECIES_MEDICHAM},
+ {38, 38, SPECIES_GOLBAT},
+ {38, 38, SPECIES_HARIYAMA},
+ {42, 42, SPECIES_GOLBAT},
+ {42, 42, SPECIES_HARIYAMA},
+ {42, 42, SPECIES_LAIRON},
+ {38, 38, SPECIES_MEDITITE},
+ {42, 42, SPECIES_LAIRON},
+ {38, 38, SPECIES_MEDITITE},
+};
+const struct WildPokemonInfo VictoryRoad_B1F_LandMonsInfo = {10, VictoryRoad_B1F_LandMons};
+
+const struct WildPokemon VictoryRoad_B1F_RockSmashMons [] =
+{
+ {30, 40, SPECIES_GRAVELER},
+ {30, 40, SPECIES_GEODUDE},
+ {35, 40, SPECIES_GRAVELER},
+ {35, 40, SPECIES_GRAVELER},
+ {35, 40, SPECIES_GRAVELER},
+};
+const struct WildPokemonInfo VictoryRoad_B1F_RockSmashMonsInfo = {20, VictoryRoad_B1F_RockSmashMons};
+
+const struct WildPokemon VictoryRoad_B2F_LandMons [] =
+{
+ {40, 40, SPECIES_GOLBAT},
+#ifdef SAPPHIRE
+ {40, 40, SPECIES_SABLEYE},
+#else
+ {40, 40, SPECIES_MAWILE},
+#endif
+ {40, 40, SPECIES_LAIRON},
+ {40, 40, SPECIES_MEDICHAM},
+ {42, 42, SPECIES_GOLBAT},
+#ifdef SAPPHIRE
+ {42, 42, SPECIES_SABLEYE},
+#else
+ {42, 42, SPECIES_MAWILE},
+#endif
+ {44, 44, SPECIES_GOLBAT},
+#ifdef SAPPHIRE
+ {44, 44, SPECIES_SABLEYE},
+#else
+ {44, 44, SPECIES_MAWILE},
+#endif
+ {42, 42, SPECIES_LAIRON},
+ {42, 42, SPECIES_MEDICHAM},
+ {44, 44, SPECIES_LAIRON},
+ {44, 44, SPECIES_MEDICHAM},
+};
+const struct WildPokemonInfo VictoryRoad_B2F_LandMonsInfo = {10, VictoryRoad_B2F_LandMons};
+
+const struct WildPokemon VictoryRoad_B2F_WaterMons [] =
+{
+ {30, 35, SPECIES_GOLBAT},
+ {25, 30, SPECIES_GOLBAT},
+ {35, 40, SPECIES_GOLBAT},
+ {35, 40, SPECIES_GOLBAT},
+ {35, 40, SPECIES_GOLBAT},
+};
+const struct WildPokemonInfo VictoryRoad_B2F_WaterMonsInfo = {4, VictoryRoad_B2F_WaterMons};
+
+const struct WildPokemon VictoryRoad_B2F_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_BARBOACH},
+ {25, 30, SPECIES_BARBOACH},
+ {30, 35, SPECIES_BARBOACH},
+ {30, 35, SPECIES_WHISCASH},
+ {35, 40, SPECIES_WHISCASH},
+ {40, 45, SPECIES_WHISCASH},
+};
+const struct WildPokemonInfo VictoryRoad_B2F_FishingMonsInfo = {30, VictoryRoad_B2F_FishingMons};
+
+const struct WildPokemon ShoalCave_LowTideEntranceRoom_LandMons [] =
+{
+ {26, 26, SPECIES_ZUBAT},
+ {26, 26, SPECIES_SPHEAL},
+ {28, 28, SPECIES_ZUBAT},
+ {28, 28, SPECIES_SPHEAL},
+ {30, 30, SPECIES_ZUBAT},
+ {30, 30, SPECIES_SPHEAL},
+ {32, 32, SPECIES_ZUBAT},
+ {32, 32, SPECIES_SPHEAL},
+ {32, 32, SPECIES_GOLBAT},
+ {32, 32, SPECIES_SPHEAL},
+ {32, 32, SPECIES_GOLBAT},
+ {32, 32, SPECIES_SPHEAL},
+};
+const struct WildPokemonInfo ShoalCave_LowTideEntranceRoom_LandMonsInfo = {10, ShoalCave_LowTideEntranceRoom_LandMons};
+
+const struct WildPokemon ShoalCave_LowTideEntranceRoom_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {5, 35, SPECIES_ZUBAT},
+ {25, 30, SPECIES_SPHEAL},
+ {25, 30, SPECIES_SPHEAL},
+ {25, 35, SPECIES_SPHEAL},
+};
+const struct WildPokemonInfo ShoalCave_LowTideEntranceRoom_WaterMonsInfo = {4, ShoalCave_LowTideEntranceRoom_WaterMons};
+
+const struct WildPokemon ShoalCave_LowTideEntranceRoom_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_WAILMER},
+ {20, 25, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo ShoalCave_LowTideEntranceRoom_FishingMonsInfo = {10, ShoalCave_LowTideEntranceRoom_FishingMons};
+
+const struct WildPokemon ShoalCave_LowTideInnerRoom_LandMons [] =
+{
+ {26, 26, SPECIES_ZUBAT},
+ {26, 26, SPECIES_SPHEAL},
+ {28, 28, SPECIES_ZUBAT},
+ {28, 28, SPECIES_SPHEAL},
+ {30, 30, SPECIES_ZUBAT},
+ {30, 30, SPECIES_SPHEAL},
+ {32, 32, SPECIES_ZUBAT},
+ {32, 32, SPECIES_SPHEAL},
+ {32, 32, SPECIES_GOLBAT},
+ {32, 32, SPECIES_SPHEAL},
+ {32, 32, SPECIES_GOLBAT},
+ {32, 32, SPECIES_SPHEAL},
+};
+const struct WildPokemonInfo ShoalCave_LowTideInnerRoom_LandMonsInfo = {10, ShoalCave_LowTideInnerRoom_LandMons};
+
+const struct WildPokemon ShoalCave_LowTideInnerRoom_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {5, 35, SPECIES_ZUBAT},
+ {25, 30, SPECIES_SPHEAL},
+ {25, 30, SPECIES_SPHEAL},
+ {25, 35, SPECIES_SPHEAL},
+};
+const struct WildPokemonInfo ShoalCave_LowTideInnerRoom_WaterMonsInfo = {4, ShoalCave_LowTideInnerRoom_WaterMons};
+
+const struct WildPokemon ShoalCave_LowTideInnerRoom_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_WAILMER},
+ {20, 25, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo ShoalCave_LowTideInnerRoom_FishingMonsInfo = {10, ShoalCave_LowTideInnerRoom_FishingMons};
+
+const struct WildPokemon ShoalCave_LowTideStairsRoom_LandMons [] =
+{
+ {26, 26, SPECIES_ZUBAT},
+ {26, 26, SPECIES_SPHEAL},
+ {28, 28, SPECIES_ZUBAT},
+ {28, 28, SPECIES_SPHEAL},
+ {30, 30, SPECIES_ZUBAT},
+ {30, 30, SPECIES_SPHEAL},
+ {32, 32, SPECIES_ZUBAT},
+ {32, 32, SPECIES_SPHEAL},
+ {32, 32, SPECIES_GOLBAT},
+ {32, 32, SPECIES_SPHEAL},
+ {32, 32, SPECIES_GOLBAT},
+ {32, 32, SPECIES_SPHEAL},
+};
+const struct WildPokemonInfo ShoalCave_LowTideStairsRoom_LandMonsInfo = {10, ShoalCave_LowTideStairsRoom_LandMons};
+
+const struct WildPokemon ShoalCave_LowTideLowerRoom_LandMons [] =
+{
+ {26, 26, SPECIES_ZUBAT},
+ {26, 26, SPECIES_SPHEAL},
+ {28, 28, SPECIES_ZUBAT},
+ {28, 28, SPECIES_SPHEAL},
+ {30, 30, SPECIES_ZUBAT},
+ {30, 30, SPECIES_SPHEAL},
+ {32, 32, SPECIES_ZUBAT},
+ {32, 32, SPECIES_SPHEAL},
+ {32, 32, SPECIES_GOLBAT},
+ {32, 32, SPECIES_SPHEAL},
+ {32, 32, SPECIES_GOLBAT},
+ {32, 32, SPECIES_SPHEAL},
+};
+const struct WildPokemonInfo ShoalCave_LowTideLowerRoom_LandMonsInfo = {10, ShoalCave_LowTideLowerRoom_LandMons};
+
+const struct WildPokemon ShoalCave_LowTideIceRoom_LandMons [] =
+{
+ {26, 26, SPECIES_ZUBAT},
+ {26, 26, SPECIES_SPHEAL},
+ {28, 28, SPECIES_ZUBAT},
+ {28, 28, SPECIES_SPHEAL},
+ {30, 30, SPECIES_ZUBAT},
+ {30, 30, SPECIES_SPHEAL},
+ {26, 26, SPECIES_SNORUNT},
+ {32, 32, SPECIES_SPHEAL},
+ {30, 30, SPECIES_GOLBAT},
+ {28, 28, SPECIES_SNORUNT},
+ {32, 32, SPECIES_GOLBAT},
+ {30, 30, SPECIES_SNORUNT},
+};
+const struct WildPokemonInfo ShoalCave_LowTideIceRoom_LandMonsInfo = {10, ShoalCave_LowTideIceRoom_LandMons};
+
+const struct WildPokemon NewMauville_Entrance_LandMons [] =
+{
+ {24, 24, SPECIES_VOLTORB},
+ {24, 24, SPECIES_MAGNEMITE},
+ {25, 25, SPECIES_VOLTORB},
+ {25, 25, SPECIES_MAGNEMITE},
+ {23, 23, SPECIES_VOLTORB},
+ {23, 23, SPECIES_MAGNEMITE},
+ {26, 26, SPECIES_VOLTORB},
+ {26, 26, SPECIES_MAGNEMITE},
+ {22, 22, SPECIES_VOLTORB},
+ {22, 22, SPECIES_MAGNEMITE},
+ {22, 22, SPECIES_VOLTORB},
+ {22, 22, SPECIES_MAGNEMITE},
+};
+const struct WildPokemonInfo NewMauville_Entrance_LandMonsInfo = {10, NewMauville_Entrance_LandMons};
+
+const struct WildPokemon NewMauville_Inside_LandMons [] =
+{
+ {24, 24, SPECIES_VOLTORB},
+ {24, 24, SPECIES_MAGNEMITE},
+ {25, 25, SPECIES_VOLTORB},
+ {25, 25, SPECIES_MAGNEMITE},
+ {23, 23, SPECIES_VOLTORB},
+ {23, 23, SPECIES_MAGNEMITE},
+ {26, 26, SPECIES_VOLTORB},
+ {26, 26, SPECIES_MAGNEMITE},
+ {22, 22, SPECIES_VOLTORB},
+ {22, 22, SPECIES_MAGNEMITE},
+ {26, 26, SPECIES_ELECTRODE},
+ {26, 26, SPECIES_MAGNETON},
+};
+const struct WildPokemonInfo NewMauville_Inside_LandMonsInfo = {10, NewMauville_Inside_LandMons};
+
+const struct WildPokemon AbandonedShip_Rooms_B1F_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {5, 35, SPECIES_TENTACOOL},
+ {5, 35, SPECIES_TENTACOOL},
+ {5, 35, SPECIES_TENTACOOL},
+ {30, 35, SPECIES_TENTACRUEL},
+};
+const struct WildPokemonInfo AbandonedShip_Rooms_B1F_WaterMonsInfo = {4, AbandonedShip_Rooms_B1F_WaterMons};
+
+const struct WildPokemon AbandonedShip_Rooms_B1F_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_TENTACOOL},
+ {25, 30, SPECIES_TENTACOOL},
+ {30, 35, SPECIES_TENTACOOL},
+ {30, 35, SPECIES_TENTACRUEL},
+ {25, 30, SPECIES_TENTACRUEL},
+ {20, 25, SPECIES_TENTACRUEL},
+};
+const struct WildPokemonInfo AbandonedShip_Rooms_B1F_FishingMonsInfo = {20, AbandonedShip_Rooms_B1F_FishingMons};
+
+const struct WildPokemon AbandonedShip_HiddenFloorCorridors_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {5, 35, SPECIES_TENTACOOL},
+ {5, 35, SPECIES_TENTACOOL},
+ {5, 35, SPECIES_TENTACOOL},
+ {30, 35, SPECIES_TENTACRUEL},
+};
+const struct WildPokemonInfo AbandonedShip_HiddenFloorCorridors_WaterMonsInfo = {4, AbandonedShip_HiddenFloorCorridors_WaterMons};
+
+const struct WildPokemon AbandonedShip_HiddenFloorCorridors_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_TENTACOOL},
+ {25, 30, SPECIES_TENTACOOL},
+ {30, 35, SPECIES_TENTACOOL},
+ {30, 35, SPECIES_TENTACRUEL},
+ {25, 30, SPECIES_TENTACRUEL},
+ {20, 25, SPECIES_TENTACRUEL},
+};
+const struct WildPokemonInfo AbandonedShip_HiddenFloorCorridors_FishingMonsInfo = {20, AbandonedShip_HiddenFloorCorridors_FishingMons};
+
+const struct WildPokemon SkyPillar_1F_LandMons [] =
+{
+#ifdef SAPPHIRE
+ {48, 48, SPECIES_SABLEYE},
+#else
+ {48, 48, SPECIES_MAWILE},
+#endif
+ {48, 48, SPECIES_GOLBAT},
+ {50, 50, SPECIES_GOLBAT},
+#ifdef SAPPHIRE
+ {50, 50, SPECIES_SABLEYE},
+#else
+ {50, 50, SPECIES_MAWILE},
+#endif
+ {48, 48, SPECIES_CLAYDOL},
+#ifdef SAPPHIRE
+ {48, 48, SPECIES_BANETTE},
+ {50, 50, SPECIES_BANETTE},
+#else
+ {48, 48, SPECIES_DUSCLOPS},
+ {50, 50, SPECIES_DUSCLOPS},
+#endif
+ {49, 49, SPECIES_CLAYDOL},
+ {47, 47, SPECIES_CLAYDOL},
+ {50, 50, SPECIES_CLAYDOL},
+ {47, 47, SPECIES_CLAYDOL},
+ {50, 50, SPECIES_CLAYDOL},
+};
+const struct WildPokemonInfo SkyPillar_1F_LandMonsInfo = {10, SkyPillar_1F_LandMons};
+
+const struct WildPokemon SkyPillar_3F_LandMons [] =
+{
+#ifdef SAPPHIRE
+ {51, 51, SPECIES_SABLEYE},
+#else
+ {51, 51, SPECIES_MAWILE},
+#endif
+ {51, 51, SPECIES_GOLBAT},
+ {53, 53, SPECIES_GOLBAT},
+#ifdef SAPPHIRE
+ {53, 53, SPECIES_SABLEYE},
+#else
+ {53, 53, SPECIES_MAWILE},
+#endif
+ {51, 51, SPECIES_CLAYDOL},
+#ifdef SAPPHIRE
+ {51, 51, SPECIES_BANETTE},
+ {53, 53, SPECIES_BANETTE},
+#else
+ {51, 51, SPECIES_DUSCLOPS},
+ {53, 53, SPECIES_DUSCLOPS},
+#endif
+ {52, 52, SPECIES_CLAYDOL},
+ {50, 50, SPECIES_CLAYDOL},
+ {53, 53, SPECIES_CLAYDOL},
+ {50, 50, SPECIES_CLAYDOL},
+ {53, 53, SPECIES_CLAYDOL},
+};
+const struct WildPokemonInfo SkyPillar_3F_LandMonsInfo = {10, SkyPillar_3F_LandMons};
+
+const struct WildPokemon SkyPillar_5F_LandMons [] =
+{
+#ifdef SAPPHIRE
+ {54, 54, SPECIES_SABLEYE},
+#else
+ {54, 54, SPECIES_MAWILE},
+#endif
+ {54, 54, SPECIES_GOLBAT},
+ {56, 56, SPECIES_GOLBAT},
+#ifdef SAPPHIRE
+ {56, 56, SPECIES_SABLEYE},
+#else
+ {56, 56, SPECIES_MAWILE},
+#endif
+ {54, 54, SPECIES_CLAYDOL},
+#ifdef SAPPHIRE
+ {54, 54, SPECIES_BANETTE},
+ {56, 56, SPECIES_BANETTE},
+#else
+ {54, 54, SPECIES_DUSCLOPS},
+ {56, 56, SPECIES_DUSCLOPS},
+#endif
+ {55, 55, SPECIES_CLAYDOL},
+ {56, 56, SPECIES_CLAYDOL},
+ {57, 57, SPECIES_ALTARIA},
+ {54, 54, SPECIES_ALTARIA},
+ {60, 60, SPECIES_ALTARIA},
+};
+const struct WildPokemonInfo SkyPillar_5F_LandMonsInfo = {10, SkyPillar_5F_LandMons};
+
+const struct WildPokemon Route101_LandMons [] =
+{
+ {2, 2, SPECIES_WURMPLE},
+ {2, 2, SPECIES_ZIGZAGOON},
+ {2, 2, SPECIES_WURMPLE},
+ {3, 3, SPECIES_WURMPLE},
+ {3, 3, SPECIES_ZIGZAGOON},
+ {3, 3, SPECIES_ZIGZAGOON},
+ {3, 3, SPECIES_WURMPLE},
+ {3, 3, SPECIES_ZIGZAGOON},
+ {2, 2, SPECIES_POOCHYENA},
+ {2, 2, SPECIES_POOCHYENA},
+ {3, 3, SPECIES_POOCHYENA},
+ {3, 3, SPECIES_POOCHYENA},
+};
+const struct WildPokemonInfo Route101_LandMonsInfo = {20, Route101_LandMons};
+
+const struct WildPokemon Route102_LandMons [] =
+{
+ {3, 3, SPECIES_ZIGZAGOON},
+ {3, 3, SPECIES_WURMPLE},
+ {4, 4, SPECIES_ZIGZAGOON},
+ {4, 4, SPECIES_WURMPLE},
+#ifdef SAPPHIRE
+ {3, 3, SPECIES_LOTAD},
+ {4, 4, SPECIES_LOTAD},
+#else
+ {3, 3, SPECIES_SEEDOT},
+ {4, 4, SPECIES_SEEDOT},
+#endif
+ {3, 3, SPECIES_POOCHYENA},
+ {3, 3, SPECIES_POOCHYENA},
+ {4, 4, SPECIES_POOCHYENA},
+ {4, 4, SPECIES_RALTS},
+ {4, 4, SPECIES_POOCHYENA},
+ {3, 3, SPECIES_SURSKIT},
+};
+const struct WildPokemonInfo Route102_LandMonsInfo = {20, Route102_LandMons};
+
+const struct WildPokemon Route102_WaterMons [] =
+{
+ {20, 30, SPECIES_MARILL},
+ {10, 20, SPECIES_MARILL},
+ {30, 35, SPECIES_MARILL},
+ {5, 10, SPECIES_MARILL},
+ {20, 30, SPECIES_SURSKIT},
+};
+const struct WildPokemonInfo Route102_WaterMonsInfo = {4, Route102_WaterMons};
+
+const struct WildPokemon Route102_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_CORPHISH},
+ {25, 30, SPECIES_CORPHISH},
+ {30, 35, SPECIES_CORPHISH},
+ {20, 25, SPECIES_CORPHISH},
+ {35, 40, SPECIES_CORPHISH},
+ {40, 45, SPECIES_CORPHISH},
+};
+const struct WildPokemonInfo Route102_FishingMonsInfo = {30, Route102_FishingMons};
+
+const struct WildPokemon Route103_LandMons [] =
+{
+ {2, 2, SPECIES_ZIGZAGOON},
+ {3, 3, SPECIES_ZIGZAGOON},
+ {3, 3, SPECIES_ZIGZAGOON},
+ {4, 4, SPECIES_ZIGZAGOON},
+ {2, 2, SPECIES_POOCHYENA},
+ {3, 3, SPECIES_POOCHYENA},
+ {3, 3, SPECIES_POOCHYENA},
+ {4, 4, SPECIES_POOCHYENA},
+ {3, 3, SPECIES_WINGULL},
+ {3, 3, SPECIES_WINGULL},
+ {2, 2, SPECIES_WINGULL},
+ {4, 4, SPECIES_WINGULL},
+};
+const struct WildPokemonInfo Route103_LandMonsInfo = {20, Route103_LandMons};
+
+const struct WildPokemon Route103_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route103_WaterMonsInfo = {4, Route103_WaterMons};
+
+const struct WildPokemon Route103_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_SHARPEDO},
+ {30, 35, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo Route103_FishingMonsInfo = {30, Route103_FishingMons};
+
+const struct WildPokemon Route104_LandMons [] =
+{
+ {4, 4, SPECIES_ZIGZAGOON},
+ {4, 4, SPECIES_WURMPLE},
+ {5, 5, SPECIES_ZIGZAGOON},
+ {5, 5, SPECIES_WURMPLE},
+ {4, 4, SPECIES_ZIGZAGOON},
+ {5, 5, SPECIES_ZIGZAGOON},
+ {4, 4, SPECIES_TAILLOW},
+ {5, 5, SPECIES_TAILLOW},
+ {4, 4, SPECIES_WINGULL},
+ {4, 4, SPECIES_WINGULL},
+ {3, 3, SPECIES_WINGULL},
+ {5, 5, SPECIES_WINGULL},
+};
+const struct WildPokemonInfo Route104_LandMonsInfo = {20, Route104_LandMons};
+
+const struct WildPokemon Route104_WaterMons [] =
+{
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route104_WaterMonsInfo = {4, Route104_WaterMons};
+
+const struct WildPokemon Route104_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_MAGIKARP},
+ {25, 30, SPECIES_MAGIKARP},
+ {30, 35, SPECIES_MAGIKARP},
+ {20, 25, SPECIES_MAGIKARP},
+ {35, 40, SPECIES_MAGIKARP},
+ {40, 45, SPECIES_MAGIKARP},
+};
+const struct WildPokemonInfo Route104_FishingMonsInfo = {30, Route104_FishingMons};
+
+const struct WildPokemon Route105_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route105_WaterMonsInfo = {4, Route105_WaterMons};
+
+const struct WildPokemon Route105_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_WAILMER},
+ {20, 25, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo Route105_FishingMonsInfo = {30, Route105_FishingMons};
+
+const struct WildPokemon Route106_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route106_WaterMonsInfo = {4, Route106_WaterMons};
+
+const struct WildPokemon Route106_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_WAILMER},
+ {20, 25, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo Route106_FishingMonsInfo = {30, Route106_FishingMons};
+
+const struct WildPokemon Route107_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route107_WaterMonsInfo = {4, Route107_WaterMons};
+
+const struct WildPokemon Route107_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_WAILMER},
+ {20, 25, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo Route107_FishingMonsInfo = {30, Route107_FishingMons};
+
+const struct WildPokemon Route108_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route108_WaterMonsInfo = {4, Route108_WaterMons};
+
+const struct WildPokemon Route108_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_WAILMER},
+ {20, 25, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo Route108_FishingMonsInfo = {30, Route108_FishingMons};
+
+const struct WildPokemon Route109_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route109_WaterMonsInfo = {4, Route109_WaterMons};
+
+const struct WildPokemon Route109_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_WAILMER},
+ {20, 25, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo Route109_FishingMonsInfo = {30, Route109_FishingMons};
+
+const struct WildPokemon Route110_LandMons [] =
+{
+ {12, 12, SPECIES_ZIGZAGOON},
+ {12, 12, SPECIES_ELECTRIKE},
+ {12, 12, SPECIES_GULPIN},
+ {13, 13, SPECIES_ELECTRIKE},
+#ifdef SAPPHIRE
+ {13, 13, SPECIES_PLUSLE},
+#else
+ {13, 13, SPECIES_MINUN},
+#endif
+ {13, 13, SPECIES_ODDISH},
+#ifdef SAPPHIRE
+ {13, 13, SPECIES_PLUSLE},
+#else
+ {13, 13, SPECIES_MINUN},
+#endif
+ {13, 13, SPECIES_GULPIN},
+ {12, 12, SPECIES_WINGULL},
+ {12, 12, SPECIES_WINGULL},
+#ifdef SAPPHIRE
+ {12, 12, SPECIES_MINUN},
+ {13, 13, SPECIES_MINUN},
+#else
+ {12, 12, SPECIES_PLUSLE},
+ {13, 13, SPECIES_PLUSLE},
+#endif
+};
+const struct WildPokemonInfo Route110_LandMonsInfo = {20, Route110_LandMons};
+
+const struct WildPokemon Route110_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route110_WaterMonsInfo = {4, Route110_WaterMons};
+
+const struct WildPokemon Route110_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_WAILMER},
+ {20, 25, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo Route110_FishingMonsInfo = {30, Route110_FishingMons};
+
+const struct WildPokemon Route111_LandMons [] =
+{
+ {20, 20, SPECIES_SANDSHREW},
+ {20, 20, SPECIES_TRAPINCH},
+ {21, 21, SPECIES_SANDSHREW},
+ {21, 21, SPECIES_TRAPINCH},
+ {19, 19, SPECIES_CACNEA},
+ {21, 21, SPECIES_CACNEA},
+ {19, 19, SPECIES_SANDSHREW},
+ {19, 19, SPECIES_TRAPINCH},
+ {20, 20, SPECIES_BALTOY},
+ {20, 20, SPECIES_BALTOY},
+ {22, 22, SPECIES_BALTOY},
+ {22, 22, SPECIES_BALTOY},
+};
+const struct WildPokemonInfo Route111_LandMonsInfo = {10, Route111_LandMons};
+
+const struct WildPokemon Route111_WaterMons [] =
+{
+ {20, 30, SPECIES_MARILL},
+ {10, 20, SPECIES_MARILL},
+ {30, 35, SPECIES_MARILL},
+ {5, 10, SPECIES_MARILL},
+ {20, 30, SPECIES_SURSKIT},
+};
+const struct WildPokemonInfo Route111_WaterMonsInfo = {4, Route111_WaterMons};
+
+const struct WildPokemon Route111_RockSmashMons [] =
+{
+ {10, 15, SPECIES_GEODUDE},
+ {5, 10, SPECIES_GEODUDE},
+ {15, 20, SPECIES_GEODUDE},
+ {15, 20, SPECIES_GEODUDE},
+ {15, 20, SPECIES_GEODUDE},
+};
+const struct WildPokemonInfo Route111_RockSmashMonsInfo = {20, Route111_RockSmashMons};
+
+const struct WildPokemon Route111_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_BARBOACH},
+ {25, 30, SPECIES_BARBOACH},
+ {30, 35, SPECIES_BARBOACH},
+ {20, 25, SPECIES_BARBOACH},
+ {35, 40, SPECIES_BARBOACH},
+ {40, 45, SPECIES_BARBOACH},
+};
+const struct WildPokemonInfo Route111_FishingMonsInfo = {30, Route111_FishingMons};
+
+const struct WildPokemon Route112_LandMons [] =
+{
+ {15, 15, SPECIES_NUMEL},
+ {15, 15, SPECIES_NUMEL},
+ {15, 15, SPECIES_MACHOP},
+ {14, 14, SPECIES_NUMEL},
+ {14, 14, SPECIES_NUMEL},
+ {14, 14, SPECIES_MACHOP},
+ {16, 16, SPECIES_NUMEL},
+ {16, 16, SPECIES_MACHOP},
+ {16, 16, SPECIES_NUMEL},
+ {16, 16, SPECIES_NUMEL},
+ {16, 16, SPECIES_NUMEL},
+ {16, 16, SPECIES_NUMEL},
+};
+const struct WildPokemonInfo Route112_LandMonsInfo = {20, Route112_LandMons};
+
+const struct WildPokemon Route113_LandMons [] =
+{
+ {15, 15, SPECIES_SPINDA},
+ {15, 15, SPECIES_SPINDA},
+ {15, 15, SPECIES_SANDSHREW},
+ {14, 14, SPECIES_SPINDA},
+ {14, 14, SPECIES_SPINDA},
+ {14, 14, SPECIES_SANDSHREW},
+ {16, 16, SPECIES_SPINDA},
+ {16, 16, SPECIES_SANDSHREW},
+ {16, 16, SPECIES_SPINDA},
+ {16, 16, SPECIES_SKARMORY},
+ {16, 16, SPECIES_SPINDA},
+ {16, 16, SPECIES_SKARMORY},
+};
+const struct WildPokemonInfo Route113_LandMonsInfo = {20, Route113_LandMons};
+
+const struct WildPokemon Route114_LandMons [] =
+{
+ {16, 16, SPECIES_SWABLU},
+#ifdef SAPPHIRE
+ {16, 16, SPECIES_LOTAD},
+#else
+ {16, 16, SPECIES_SEEDOT},
+#endif
+ {17, 17, SPECIES_SWABLU},
+ {15, 15, SPECIES_SWABLU},
+#ifdef SAPPHIRE
+ {15, 15, SPECIES_LOTAD},
+ {16, 16, SPECIES_SEVIPER},
+ {16, 16, SPECIES_LOMBRE},
+ {18, 18, SPECIES_LOMBRE},
+ {17, 17, SPECIES_SEVIPER},
+ {15, 15, SPECIES_SEVIPER},
+ {17, 17, SPECIES_SEVIPER},
+#else
+ {15, 15, SPECIES_SEEDOT},
+ {16, 16, SPECIES_ZANGOOSE},
+ {16, 16, SPECIES_NUZLEAF},
+ {18, 18, SPECIES_NUZLEAF},
+ {17, 17, SPECIES_ZANGOOSE},
+ {15, 15, SPECIES_ZANGOOSE},
+ {17, 17, SPECIES_ZANGOOSE},
+#endif
+ {15, 15, SPECIES_SURSKIT},
+};
+const struct WildPokemonInfo Route114_LandMonsInfo = {20, Route114_LandMons};
+
+const struct WildPokemon Route114_WaterMons [] =
+{
+ {20, 30, SPECIES_MARILL},
+ {10, 20, SPECIES_MARILL},
+ {30, 35, SPECIES_MARILL},
+ {5, 10, SPECIES_MARILL},
+ {20, 30, SPECIES_SURSKIT},
+};
+const struct WildPokemonInfo Route114_WaterMonsInfo = {4, Route114_WaterMons};
+
+const struct WildPokemon Route114_RockSmashMons [] =
+{
+ {10, 15, SPECIES_GEODUDE},
+ {5, 10, SPECIES_GEODUDE},
+ {15, 20, SPECIES_GEODUDE},
+ {15, 20, SPECIES_GEODUDE},
+ {15, 20, SPECIES_GEODUDE},
+};
+const struct WildPokemonInfo Route114_RockSmashMonsInfo = {20, Route114_RockSmashMons};
+
+const struct WildPokemon Route114_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_BARBOACH},
+ {25, 30, SPECIES_BARBOACH},
+ {30, 35, SPECIES_BARBOACH},
+ {20, 25, SPECIES_BARBOACH},
+ {35, 40, SPECIES_BARBOACH},
+ {40, 45, SPECIES_BARBOACH},
+};
+const struct WildPokemonInfo Route114_FishingMonsInfo = {30, Route114_FishingMons};
+
+const struct WildPokemon Route115_LandMons [] =
+{
+ {23, 23, SPECIES_SWABLU},
+ {23, 23, SPECIES_TAILLOW},
+ {25, 25, SPECIES_SWABLU},
+ {24, 24, SPECIES_TAILLOW},
+ {25, 25, SPECIES_TAILLOW},
+ {25, 25, SPECIES_SWELLOW},
+ {24, 24, SPECIES_JIGGLYPUFF},
+ {25, 25, SPECIES_JIGGLYPUFF},
+ {24, 24, SPECIES_WINGULL},
+ {24, 24, SPECIES_WINGULL},
+ {26, 26, SPECIES_WINGULL},
+ {25, 25, SPECIES_WINGULL},
+};
+const struct WildPokemonInfo Route115_LandMonsInfo = {20, Route115_LandMons};
+
+const struct WildPokemon Route115_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route115_WaterMonsInfo = {4, Route115_WaterMons};
+
+const struct WildPokemon Route115_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_WAILMER},
+ {20, 25, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo Route115_FishingMonsInfo = {30, Route115_FishingMons};
+
+const struct WildPokemon Route116_LandMons [] =
+{
+ {6, 6, SPECIES_ZIGZAGOON},
+ {6, 6, SPECIES_WHISMUR},
+ {6, 6, SPECIES_NINCADA},
+ {7, 7, SPECIES_WHISMUR},
+ {7, 7, SPECIES_NINCADA},
+ {6, 6, SPECIES_TAILLOW},
+ {7, 7, SPECIES_TAILLOW},
+ {8, 8, SPECIES_TAILLOW},
+ {7, 7, SPECIES_ZIGZAGOON},
+ {8, 8, SPECIES_ZIGZAGOON},
+ {7, 7, SPECIES_SKITTY},
+ {8, 8, SPECIES_SKITTY},
+};
+const struct WildPokemonInfo Route116_LandMonsInfo = {20, Route116_LandMons};
+
+const struct WildPokemon Route117_LandMons [] =
+{
+ {13, 13, SPECIES_ZIGZAGOON},
+ {13, 13, SPECIES_ROSELIA},
+ {14, 14, SPECIES_ZIGZAGOON},
+ {14, 14, SPECIES_ROSELIA},
+ {13, 13, SPECIES_MARILL},
+ {13, 13, SPECIES_ODDISH},
+#ifdef SAPPHIRE
+ {13, 13, SPECIES_VOLBEAT},
+ {13, 13, SPECIES_VOLBEAT},
+ {14, 14, SPECIES_VOLBEAT},
+ {14, 14, SPECIES_VOLBEAT},
+ {13, 13, SPECIES_ILLUMISE},
+#else
+ {13, 13, SPECIES_ILLUMISE},
+ {13, 13, SPECIES_ILLUMISE},
+ {14, 14, SPECIES_ILLUMISE},
+ {14, 14, SPECIES_ILLUMISE},
+ {13, 13, SPECIES_VOLBEAT},
+#endif
+ {13, 13, SPECIES_SURSKIT},
+};
+const struct WildPokemonInfo Route117_LandMonsInfo = {20, Route117_LandMons};
+
+const struct WildPokemon Route117_WaterMons [] =
+{
+ {20, 30, SPECIES_MARILL},
+ {10, 20, SPECIES_MARILL},
+ {30, 35, SPECIES_MARILL},
+ {5, 10, SPECIES_MARILL},
+ {20, 30, SPECIES_SURSKIT},
+};
+const struct WildPokemonInfo Route117_WaterMonsInfo = {4, Route117_WaterMons};
+
+const struct WildPokemon Route117_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_CORPHISH},
+ {25, 30, SPECIES_CORPHISH},
+ {30, 35, SPECIES_CORPHISH},
+ {20, 25, SPECIES_CORPHISH},
+ {35, 40, SPECIES_CORPHISH},
+ {40, 45, SPECIES_CORPHISH},
+};
+const struct WildPokemonInfo Route117_FishingMonsInfo = {30, Route117_FishingMons};
+
+const struct WildPokemon Route118_LandMons [] =
+{
+ {24, 24, SPECIES_ZIGZAGOON},
+ {24, 24, SPECIES_ELECTRIKE},
+ {26, 26, SPECIES_ZIGZAGOON},
+ {26, 26, SPECIES_ELECTRIKE},
+ {26, 26, SPECIES_LINOONE},
+ {26, 26, SPECIES_MANECTRIC},
+ {25, 25, SPECIES_WINGULL},
+ {25, 25, SPECIES_WINGULL},
+ {26, 26, SPECIES_WINGULL},
+ {26, 26, SPECIES_WINGULL},
+ {27, 27, SPECIES_WINGULL},
+ {25, 25, SPECIES_KECLEON},
+};
+const struct WildPokemonInfo Route118_LandMonsInfo = {20, Route118_LandMons};
+
+const struct WildPokemon Route118_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route118_WaterMonsInfo = {4, Route118_WaterMons};
+
+const struct WildPokemon Route118_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_CARVANHA},
+ {30, 35, SPECIES_SHARPEDO},
+ {30, 35, SPECIES_CARVANHA},
+ {20, 25, SPECIES_CARVANHA},
+ {35, 40, SPECIES_CARVANHA},
+ {40, 45, SPECIES_CARVANHA},
+};
+const struct WildPokemonInfo Route118_FishingMonsInfo = {30, Route118_FishingMons};
+
+const struct WildPokemon Route119_LandMons [] =
+{
+ {25, 25, SPECIES_ZIGZAGOON},
+ {25, 25, SPECIES_LINOONE},
+ {27, 27, SPECIES_ZIGZAGOON},
+ {25, 25, SPECIES_ODDISH},
+ {27, 27, SPECIES_LINOONE},
+ {26, 26, SPECIES_ODDISH},
+ {27, 27, SPECIES_ODDISH},
+ {24, 24, SPECIES_ODDISH},
+ {25, 25, SPECIES_TROPIUS},
+ {26, 26, SPECIES_TROPIUS},
+ {27, 27, SPECIES_TROPIUS},
+ {25, 25, SPECIES_KECLEON},
+};
+const struct WildPokemonInfo Route119_LandMonsInfo = {15, Route119_LandMons};
+
+const struct WildPokemon Route119_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route119_WaterMonsInfo = {4, Route119_WaterMons};
+
+const struct WildPokemon Route119_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_CARVANHA},
+ {25, 30, SPECIES_CARVANHA},
+ {30, 35, SPECIES_CARVANHA},
+ {20, 25, SPECIES_CARVANHA},
+ {35, 40, SPECIES_CARVANHA},
+ {40, 45, SPECIES_CARVANHA},
+};
+const struct WildPokemonInfo Route119_FishingMonsInfo = {30, Route119_FishingMons};
+
+const struct WildPokemon Route120_LandMons [] =
+{
+ {25, 25, SPECIES_ZIGZAGOON},
+ {25, 25, SPECIES_LINOONE},
+ {27, 27, SPECIES_LINOONE},
+ {25, 25, SPECIES_ODDISH},
+ {25, 25, SPECIES_MARILL},
+ {26, 26, SPECIES_ODDISH},
+ {27, 27, SPECIES_ODDISH},
+ {27, 27, SPECIES_MARILL},
+ {25, 25, SPECIES_ABSOL},
+ {27, 27, SPECIES_ABSOL},
+ {25, 25, SPECIES_KECLEON},
+ {25, 25, SPECIES_SURSKIT},
+};
+const struct WildPokemonInfo Route120_LandMonsInfo = {20, Route120_LandMons};
+
+const struct WildPokemon Route120_WaterMons [] =
+{
+ {20, 30, SPECIES_MARILL},
+ {10, 20, SPECIES_MARILL},
+ {30, 35, SPECIES_MARILL},
+ {5, 10, SPECIES_MARILL},
+ {20, 30, SPECIES_SURSKIT},
+};
+const struct WildPokemonInfo Route120_WaterMonsInfo = {4, Route120_WaterMons};
+
+const struct WildPokemon Route120_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_BARBOACH},
+ {25, 30, SPECIES_BARBOACH},
+ {30, 35, SPECIES_BARBOACH},
+ {20, 25, SPECIES_BARBOACH},
+ {35, 40, SPECIES_BARBOACH},
+ {40, 45, SPECIES_BARBOACH},
+};
+const struct WildPokemonInfo Route120_FishingMonsInfo = {30, Route120_FishingMons};
+
+const struct WildPokemon Route121_LandMons [] =
+{
+ {26, 26, SPECIES_ZIGZAGOON},
+#ifdef SAPPHIRE
+ {26, 26, SPECIES_SHUPPET},
+#else
+ {26, 26, SPECIES_DUSKULL},
+#endif
+ {26, 26, SPECIES_LINOONE},
+#ifdef SAPPHIRE
+ {28, 28, SPECIES_SHUPPET},
+#else
+ {28, 28, SPECIES_DUSKULL},
+#endif
+ {28, 28, SPECIES_LINOONE},
+ {26, 26, SPECIES_ODDISH},
+ {28, 28, SPECIES_ODDISH},
+ {28, 28, SPECIES_GLOOM},
+ {26, 26, SPECIES_WINGULL},
+ {27, 27, SPECIES_WINGULL},
+ {28, 28, SPECIES_WINGULL},
+ {25, 25, SPECIES_KECLEON},
+};
+const struct WildPokemonInfo Route121_LandMonsInfo = {20, Route121_LandMons};
+
+const struct WildPokemon Route121_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route121_WaterMonsInfo = {4, Route121_WaterMons};
+
+const struct WildPokemon Route121_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_WAILMER},
+ {20, 25, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo Route121_FishingMonsInfo = {30, Route121_FishingMons};
+
+const struct WildPokemon Route122_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route122_WaterMonsInfo = {4, Route122_WaterMons};
+
+const struct WildPokemon Route122_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_SHARPEDO},
+ {30, 35, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo Route122_FishingMonsInfo = {30, Route122_FishingMons};
+
+const struct WildPokemon Route123_LandMons [] =
+{
+ {26, 26, SPECIES_ZIGZAGOON},
+#ifdef SAPPHIRE
+ {26, 26, SPECIES_SHUPPET},
+#else
+ {26, 26, SPECIES_DUSKULL},
+#endif
+ {26, 26, SPECIES_LINOONE},
+#ifdef SAPPHIRE
+ {28, 28, SPECIES_SHUPPET},
+#else
+ {28, 28, SPECIES_DUSKULL},
+#endif
+ {28, 28, SPECIES_LINOONE},
+ {26, 26, SPECIES_ODDISH},
+ {28, 28, SPECIES_ODDISH},
+ {28, 28, SPECIES_GLOOM},
+ {26, 26, SPECIES_WINGULL},
+ {27, 27, SPECIES_WINGULL},
+ {28, 28, SPECIES_WINGULL},
+ {25, 25, SPECIES_KECLEON},
+};
+const struct WildPokemonInfo Route123_LandMonsInfo = {20, Route123_LandMons};
+
+const struct WildPokemon Route123_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route123_WaterMonsInfo = {4, Route123_WaterMons};
+
+const struct WildPokemon Route123_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_WAILMER},
+ {20, 25, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo Route123_FishingMonsInfo = {30, Route123_FishingMons};
+
+const struct WildPokemon Route124_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route124_WaterMonsInfo = {4, Route124_WaterMons};
+
+const struct WildPokemon Route124_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_SHARPEDO},
+ {30, 35, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo Route124_FishingMonsInfo = {30, Route124_FishingMons};
+
+const struct WildPokemon Route125_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route125_WaterMonsInfo = {4, Route125_WaterMons};
+
+const struct WildPokemon Route125_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_SHARPEDO},
+ {30, 35, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo Route125_FishingMonsInfo = {30, Route125_FishingMons};
+
+const struct WildPokemon Route126_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route126_WaterMonsInfo = {4, Route126_WaterMons};
+
+const struct WildPokemon Route126_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_SHARPEDO},
+ {30, 35, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo Route126_FishingMonsInfo = {30, Route126_FishingMons};
+
+const struct WildPokemon Route127_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route127_WaterMonsInfo = {4, Route127_WaterMons};
+
+const struct WildPokemon Route127_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_SHARPEDO},
+ {30, 35, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo Route127_FishingMonsInfo = {30, Route127_FishingMons};
+
+const struct WildPokemon Route128_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route128_WaterMonsInfo = {4, Route128_WaterMons};
+
+const struct WildPokemon Route128_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_LUVDISC},
+ {10, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_LUVDISC},
+ {30, 35, SPECIES_WAILMER},
+ {30, 35, SPECIES_CORSOLA},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo Route128_FishingMonsInfo = {30, Route128_FishingMons};
+
+const struct WildPokemon Route129_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+#ifdef SAPPHIRE
+ {25, 30, SPECIES_WAILORD},
+#else
+ {35, 40, SPECIES_WAILORD},
+#endif
+};
+const struct WildPokemonInfo Route129_WaterMonsInfo = {4, Route129_WaterMons};
+
+const struct WildPokemon Route129_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_SHARPEDO},
+ {30, 35, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo Route129_FishingMonsInfo = {30, Route129_FishingMons};
+
+const struct WildPokemon Route130_LandMons [] =
+{
+ {30, 30, SPECIES_WYNAUT},
+ {35, 35, SPECIES_WYNAUT},
+ {25, 25, SPECIES_WYNAUT},
+ {40, 40, SPECIES_WYNAUT},
+ {20, 20, SPECIES_WYNAUT},
+ {45, 45, SPECIES_WYNAUT},
+ {15, 15, SPECIES_WYNAUT},
+ {50, 50, SPECIES_WYNAUT},
+ {10, 10, SPECIES_WYNAUT},
+ {5, 5, SPECIES_WYNAUT},
+ {10, 10, SPECIES_WYNAUT},
+ {5, 5, SPECIES_WYNAUT},
+};
+const struct WildPokemonInfo Route130_LandMonsInfo = {20, Route130_LandMons};
+
+const struct WildPokemon Route130_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route130_WaterMonsInfo = {4, Route130_WaterMons};
+
+const struct WildPokemon Route130_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_SHARPEDO},
+ {30, 35, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo Route130_FishingMonsInfo = {30, Route130_FishingMons};
+
+const struct WildPokemon Route131_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route131_WaterMonsInfo = {4, Route131_WaterMons};
+
+const struct WildPokemon Route131_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_SHARPEDO},
+ {30, 35, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo Route131_FishingMonsInfo = {30, Route131_FishingMons};
+
+const struct WildPokemon Route132_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route132_WaterMonsInfo = {4, Route132_WaterMons};
+
+const struct WildPokemon Route132_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_SHARPEDO},
+ {30, 35, SPECIES_WAILMER},
+ {25, 30, SPECIES_HORSEA},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo Route132_FishingMonsInfo = {30, Route132_FishingMons};
+
+const struct WildPokemon Route133_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route133_WaterMonsInfo = {4, Route133_WaterMons};
+
+const struct WildPokemon Route133_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_SHARPEDO},
+ {30, 35, SPECIES_WAILMER},
+ {25, 30, SPECIES_HORSEA},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo Route133_FishingMonsInfo = {30, Route133_FishingMons};
+
+const struct WildPokemon Route134_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo Route134_WaterMonsInfo = {4, Route134_WaterMons};
+
+const struct WildPokemon Route134_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_SHARPEDO},
+ {30, 35, SPECIES_WAILMER},
+ {25, 30, SPECIES_HORSEA},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo Route134_FishingMonsInfo = {30, Route134_FishingMons};
+
+const struct WildPokemon SafariZone_Northwest_LandMons [] =
+{
+ {27, 27, SPECIES_RHYHORN},
+ {27, 27, SPECIES_ODDISH},
+ {29, 29, SPECIES_RHYHORN},
+ {29, 29, SPECIES_ODDISH},
+ {27, 27, SPECIES_DODUO},
+ {29, 29, SPECIES_GLOOM},
+ {31, 31, SPECIES_GLOOM},
+ {29, 29, SPECIES_DODUO},
+ {29, 29, SPECIES_DODRIO},
+ {27, 27, SPECIES_PINSIR},
+ {31, 31, SPECIES_DODRIO},
+ {29, 29, SPECIES_PINSIR},
+};
+const struct WildPokemonInfo SafariZone_Northwest_LandMonsInfo = {25, SafariZone_Northwest_LandMons};
+
+const struct WildPokemon SafariZone_Northwest_WaterMons [] =
+{
+ {20, 30, SPECIES_PSYDUCK},
+ {20, 30, SPECIES_PSYDUCK},
+ {30, 35, SPECIES_PSYDUCK},
+ {30, 35, SPECIES_GOLDUCK},
+ {25, 40, SPECIES_GOLDUCK},
+};
+const struct WildPokemonInfo SafariZone_Northwest_WaterMonsInfo = {9, SafariZone_Northwest_WaterMons};
+
+const struct WildPokemon SafariZone_Northwest_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 25, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_GOLDEEN},
+ {25, 30, SPECIES_GOLDEEN},
+ {30, 35, SPECIES_GOLDEEN},
+ {30, 35, SPECIES_SEAKING},
+ {35, 40, SPECIES_SEAKING},
+ {25, 30, SPECIES_SEAKING},
+};
+const struct WildPokemonInfo SafariZone_Northwest_FishingMonsInfo = {35, SafariZone_Northwest_FishingMons};
+
+const struct WildPokemon SafariZone_Northeast_LandMons [] =
+{
+ {27, 27, SPECIES_PHANPY},
+ {27, 27, SPECIES_ODDISH},
+ {29, 29, SPECIES_PHANPY},
+ {29, 29, SPECIES_ODDISH},
+ {27, 27, SPECIES_NATU},
+ {29, 29, SPECIES_GLOOM},
+ {31, 31, SPECIES_GLOOM},
+ {29, 29, SPECIES_NATU},
+ {29, 29, SPECIES_XATU},
+ {27, 27, SPECIES_HERACROSS},
+ {31, 31, SPECIES_XATU},
+ {29, 29, SPECIES_HERACROSS},
+};
+const struct WildPokemonInfo SafariZone_Northeast_LandMonsInfo = {25, SafariZone_Northeast_LandMons};
+
+const struct WildPokemon SafariZone_Northeast_RockSmashMons [] =
+{
+ {10, 15, SPECIES_GEODUDE},
+ {5, 10, SPECIES_GEODUDE},
+ {15, 20, SPECIES_GEODUDE},
+ {20, 25, SPECIES_GEODUDE},
+ {25, 30, SPECIES_GEODUDE},
+};
+const struct WildPokemonInfo SafariZone_Northeast_RockSmashMonsInfo = {25, SafariZone_Northeast_RockSmashMons};
+
+const struct WildPokemon SafariZone_Southwest_LandMons [] =
+{
+ {25, 25, SPECIES_ODDISH},
+ {27, 27, SPECIES_ODDISH},
+ {25, 25, SPECIES_GIRAFARIG},
+ {27, 27, SPECIES_GIRAFARIG},
+ {25, 25, SPECIES_NATU},
+#ifdef SAPPHIRE
+ {27, 27, SPECIES_DODUO},
+#else
+ {25, 25, SPECIES_DODUO},
+#endif
+ {25, 25, SPECIES_GLOOM},
+ {27, 27, SPECIES_WOBBUFFET},
+ {25, 25, SPECIES_PIKACHU},
+ {27, 27, SPECIES_WOBBUFFET},
+ {27, 27, SPECIES_PIKACHU},
+ {29, 29, SPECIES_WOBBUFFET},
+};
+const struct WildPokemonInfo SafariZone_Southwest_LandMonsInfo = {25, SafariZone_Southwest_LandMons};
+
+const struct WildPokemon SafariZone_Southwest_WaterMons [] =
+{
+ {20, 30, SPECIES_PSYDUCK},
+ {20, 30, SPECIES_PSYDUCK},
+ {30, 35, SPECIES_PSYDUCK},
+ {30, 35, SPECIES_PSYDUCK},
+ {30, 35, SPECIES_PSYDUCK},
+};
+const struct WildPokemonInfo SafariZone_Southwest_WaterMonsInfo = {9, SafariZone_Southwest_WaterMons};
+
+const struct WildPokemon SafariZone_Southwest_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 25, SPECIES_GOLDEEN},
+ {10, 30, SPECIES_GOLDEEN},
+ {25, 30, SPECIES_GOLDEEN},
+ {30, 35, SPECIES_GOLDEEN},
+ {30, 35, SPECIES_SEAKING},
+ {35, 40, SPECIES_SEAKING},
+ {25, 30, SPECIES_SEAKING},
+};
+const struct WildPokemonInfo SafariZone_Southwest_FishingMonsInfo = {35, SafariZone_Southwest_FishingMons};
+
+const struct WildPokemon SafariZone_Southeast_LandMons [] =
+{
+ {25, 25, SPECIES_ODDISH},
+ {27, 27, SPECIES_ODDISH},
+ {25, 25, SPECIES_GIRAFARIG},
+ {27, 27, SPECIES_GIRAFARIG},
+ {25, 25, SPECIES_NATU},
+ {25, 25, SPECIES_DODUO},
+ {25, 25, SPECIES_GLOOM},
+ {27, 27, SPECIES_WOBBUFFET},
+ {25, 25, SPECIES_PIKACHU},
+ {27, 27, SPECIES_WOBBUFFET},
+ {27, 27, SPECIES_PIKACHU},
+ {29, 29, SPECIES_WOBBUFFET},
+};
+const struct WildPokemonInfo SafariZone_Southeast_LandMonsInfo = {25, SafariZone_Southeast_LandMons};
+
+const struct WildPokemon DewfordTown_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo DewfordTown_WaterMonsInfo = {4, DewfordTown_WaterMons};
+
+const struct WildPokemon DewfordTown_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_WAILMER},
+ {20, 25, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo DewfordTown_FishingMonsInfo = {10, DewfordTown_FishingMons};
+
+const struct WildPokemon PacifidlogTown_WaterMons [] =
+{
+ {5, 35, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WINGULL},
+ {15, 25, SPECIES_WINGULL},
+ {25, 30, SPECIES_PELIPPER},
+ {25, 30, SPECIES_PELIPPER},
+};
+const struct WildPokemonInfo PacifidlogTown_WaterMonsInfo = {4, PacifidlogTown_WaterMons};
+
+const struct WildPokemon PacifidlogTown_FishingMons [] =
+{
+ {5, 10, SPECIES_MAGIKARP},
+ {5, 10, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_MAGIKARP},
+ {10, 30, SPECIES_TENTACOOL},
+ {10, 30, SPECIES_WAILMER},
+ {30, 35, SPECIES_SHARPEDO},
+ {30, 35, SPECIES_WAILMER},
+ {25, 30, SPECIES_WAILMER},
+ {35, 40, SPECIES_WAILMER},
+ {40, 45, SPECIES_WAILMER},
+};
+const struct WildPokemonInfo PacifidlogTown_FishingMonsInfo = {10, PacifidlogTown_FishingMons};
+
+const struct WildPokemon Underwater1_WaterMons [] =
+{
+ {20, 30, SPECIES_CLAMPERL},
+ {20, 30, SPECIES_CHINCHOU},
+ {30, 35, SPECIES_CLAMPERL},
+ {30, 35, SPECIES_RELICANTH},
+ {30, 35, SPECIES_RELICANTH},
+};
+const struct WildPokemonInfo Underwater1_WaterMonsInfo = {4, Underwater1_WaterMons};
+
+const struct WildPokemon Underwater2_WaterMons [] =
+{
+ {20, 30, SPECIES_CLAMPERL},
+ {20, 30, SPECIES_CHINCHOU},
+ {30, 35, SPECIES_CLAMPERL},
+ {30, 35, SPECIES_RELICANTH},
+ {30, 35, SPECIES_RELICANTH},
+};
+const struct WildPokemonInfo Underwater2_WaterMonsInfo = {4, Underwater2_WaterMons};
+
+
+extern u16 gRoute119WaterTileData[];
+extern u16 gScriptResult;
+extern struct WildPokemon gWildFeebasRoute119Data;
+extern u8 S_RepelWoreOff[];
+
+EWRAM_DATA static u8 sWildEncountersDisabled = 0;
+EWRAM_DATA static u32 sFeebasRngValue = 0;
+
+#define NUM_FEEBAS_SPOTS 6
+
+static u16 FeebasRandom(void);
+static void FeebasSeedRng(u16 seed);
+
+static bool8 IsWildLevelAllowedByRepel(u8 level);
+static void ApplyFluteEncounterRateMod(u32 *encRate);
+static void ApplyCleanseTagEncounterRateMod(u32 *encRate);
+
+void DisableWildEncounters(bool8 disabled)
+{
+ sWildEncountersDisabled = disabled;
+}
+
+static u16 GetRoute119WaterTileNum(s16 x, s16 y, u8 section)
+{
+ u16 xCur;
+ u16 yCur;
+ u16 yMin = gRoute119WaterTileData[section * 3 + 0];
+ u16 yMax = gRoute119WaterTileData[section * 3 + 1];
+ u16 tileNum = gRoute119WaterTileData[section * 3 + 2];
+
+ for (yCur = yMin; yCur <= yMax; yCur++)
+ {
+ for (xCur = 0; xCur < gMapHeader.mapData->width; xCur++)
+ {
+ if (sub_805759C(MapGridGetMetatileBehaviorAt(xCur + 7, yCur + 7)) == TRUE)
+ {
+ tileNum++;
+ if (x == xCur && y == yCur)
+ return tileNum;
+ }
+ }
+ }
+ return tileNum + 1;
+}
+
+static bool8 CheckFeebas(void)
+{
+ u8 i;
+ u16 feebasSpots[6];
+ s16 x;
+ s16 y;
+ u8 route119section = 0;
+ u16 waterTileNum;
+
+ if (gSaveBlock1.location.mapGroup == MAP_GROUP_ROUTE119
+ && gSaveBlock1.location.mapNum == MAP_ID_ROUTE119)
+ {
+ GetXYCoordsOneStepInFrontOfPlayer(&x, &y);
+ x -= 7;
+ y -= 7;
+
+#ifdef NONMATCHING
+ if (y >= gRoute119WaterTileData[3 * 1 + 0] && y <= gRoute119WaterTileData[3 * 1 + 1])
+ route119section = 1;
+ if (y >= gRoute119WaterTileData[3 * 2 + 0] && y <= gRoute119WaterTileData[3 * 2 + 1])
+ route119section = 2;
+#else
+ {
+ register u16 *arr asm("r0");
+ if (y >= (arr = gRoute119WaterTileData)[3 * 1 + 0] && y <= arr[3 * 1 + 1])
+ route119section = 1;
+ if (y >= arr[3 * 2 + 0] && y <= arr[3 * 2 + 1])
+ route119section = 2;
+ }
+#endif
+
+ if (Random() % 100 > 49) //50% chance of encountering Feebas
+ return FALSE;
+
+ FeebasSeedRng(gSaveBlock1.easyChatPairs[0].unk2);
+ for (i = 0; i != NUM_FEEBAS_SPOTS;)
+ {
+ feebasSpots[i] = FeebasRandom() % 447;
+ if (feebasSpots[i] == 0)
+ feebasSpots[i] = 447;
+ if (feebasSpots[i] < 1 || feebasSpots[i] >= 4)
+ i++;
+ }
+ waterTileNum = GetRoute119WaterTileNum(x, y, route119section);
+ for (i = 0; i < NUM_FEEBAS_SPOTS; i++)
+ {
+ if (waterTileNum == feebasSpots[i])
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static u16 FeebasRandom(void)
+{
+ sFeebasRngValue = 12345 + 0x41C64E6D * sFeebasRngValue;
+ return sFeebasRngValue >> 16;
+}
+
+static void FeebasSeedRng(u16 seed)
+{
+ sFeebasRngValue = seed;
+}
+
+static u8 ChooseWildMonIndex_Land(void)
+{
+ u8 rand = Random() % 100;
+
+ if (rand < 20) //20% chance
+ return 0;
+ if (rand >= 20 && rand < 40) //20% chance
+ return 1;
+ if (rand >= 40 && rand < 50) //10% chance
+ return 2;
+ if (rand >= 50 && rand < 60) //10% chance
+ return 3;
+ if (rand >= 60 && rand < 70) //10% chance
+ return 4;
+ if (rand >= 70 && rand < 80) //10% chance
+ return 5;
+ if (rand >= 80 && rand < 85) //5% chance
+ return 6;
+ if (rand >= 85 && rand < 90) //5% chance
+ return 7;
+ if (rand >= 90 && rand < 94) //4% chance
+ return 8;
+ if (rand >= 94 && rand < 98) //4% chance
+ return 9;
+ if (rand == 98) //1% chance
+ return 10;
+ else //1% chance
+ return 11;
+}
+
+static u8 ChooseWildMonIndex_Water(void)
+{
+ u8 rand = Random() % 100;
+
+ if (rand < 60) //60% chance
+ return 0;
+ if (rand >= 60 && rand < 90) //30% chance
+ return 1;
+ if (rand >= 90 && rand < 95) //5% chance
+ return 2;
+ if (rand >= 95 && rand < 99) //4% chance
+ return 3;
+ else //1% chance
+ return 4;
+}
+
+enum
+{
+ OLD_ROD,
+ GOOD_ROD,
+ SUPER_ROD
+};
+
+static u8 ChooseWildMonIndex_Fishing(u8 rod)
+{
+ u8 wildMonIndex = 0;
+ u8 rand = Random() % 100;
+
+ switch (rod)
+ {
+ case OLD_ROD:
+ if (rand < 70) //70% chance
+ wildMonIndex = 0;
+ else //30% chance
+ wildMonIndex = 1;
+ break;
+ case GOOD_ROD:
+ if (rand < 60) //60% chance
+ wildMonIndex = 2;
+ if (rand >= 60 && rand < 80) //20% chance
+ wildMonIndex = 3;
+ if (rand >= 80 && rand < 100) //20% chance
+ wildMonIndex = 4;
+ break;
+ case SUPER_ROD:
+ if (rand < 40) //40% chance
+ wildMonIndex = 5;
+ if (rand >= 40 && rand < 80) //40% chance
+ wildMonIndex = 6;
+ if (rand >= 80 && rand < 95) //15% chance
+ wildMonIndex = 7;
+ if (rand >= 95 && rand < 99) //4% chance
+ wildMonIndex = 8;
+ if (rand == 99) //1% chance
+ wildMonIndex = 9;
+ break;
+ }
+ return wildMonIndex;
+}
+
+static u8 ChooseWildMonLevel(const struct WildPokemon *wildPokemon)
+{
+ u8 min;
+ u8 max;
+ u8 range;
+ u8 rand;
+
+ //Make sure minimum level is less than maximum level
+ if (wildPokemon->maxLevel >= wildPokemon->minLevel)
+ {
+ min = wildPokemon->minLevel;
+ max = wildPokemon->maxLevel;
+ }
+ else
+ {
+ min = wildPokemon->maxLevel;
+ max = wildPokemon->minLevel;
+ }
+ range = max - min + 1;
+ rand = Random() % range;
+ return min + rand;
+}
+
+static u16 GetCurrentMapWildMonHeader(void)
+{
+ u16 i;
+
+ for (i = 0; gWildMonHeaders[i].mapGroup != 0xFF; i++)
+ {
+ if (gWildMonHeaders[i].mapGroup == gSaveBlock1.location.mapGroup &&
+ gWildMonHeaders[i].mapNum == gSaveBlock1.location.mapNum)
+ return i;
+ }
+ return -1;
+}
+
+static u8 PickWildMonNature(void)
+{
+ u8 i;
+ u8 j;
+ struct Pokeblock *safariPokeblock;
+ u8 natures[25];
+
+ if (GetSafariZoneFlag() == TRUE && Random() % 100 < 80)
+ {
+ safariPokeblock = SafariZoneGetActivePokeblock();
+ if (safariPokeblock != NULL)
+ {
+ for (i = 0; i < 25; i++)
+ natures[i] = i;
+ for (i = 0; i < 24; i++)
+ {
+ for (j = i + 1; j < 25; j++)
+ {
+ if (Random() & 1)
+ {
+ u8 temp = natures[i];
+
+ natures[i] = natures[j];
+ natures[j] = temp;
+ }
+ }
+ }
+ for (i = 0; i < 25; i++)
+ {
+ if (PokeblockGetGain(natures[i], safariPokeblock) > 0)
+ return natures[i];
+ }
+ }
+ }
+ return Random() % 25;
+}
+
+static void CreateWildMon(u16 species, u8 b)
+{
+ ZeroEnemyPartyMons();
+ CreateMonWithNature(&gEnemyParty[0], species, b, 0x20, PickWildMonNature());
+}
+
+static bool8 GenerateWildMon(struct WildPokemonInfo *wildMonInfo, u8 area, bool8 checkRepel)
+{
+ u8 wildMonIndex = 0;
+ u8 level;
+
+ switch (area)
+ {
+ case 0:
+ wildMonIndex = ChooseWildMonIndex_Land();
+ break;
+ case 1:
+ wildMonIndex = ChooseWildMonIndex_Water();
+ break;
+ case 2:
+ wildMonIndex = ChooseWildMonIndex_Water();
+ break;
+ }
+ level = ChooseWildMonLevel(&wildMonInfo->wildPokemon[wildMonIndex]);
+ if (checkRepel == TRUE && IsWildLevelAllowedByRepel(level) == FALSE)
+ return FALSE;
+ else
+ {
+ CreateWildMon(wildMonInfo->wildPokemon[wildMonIndex].species, level);
+ return TRUE;
+ }
+}
+
+static u16 GenerateFishingWildMon(struct WildPokemonInfo *wildMonInfo, u8 rod)
+{
+ u8 wildMonIndex = ChooseWildMonIndex_Fishing(rod);
+ u8 level = ChooseWildMonLevel(&wildMonInfo->wildPokemon[wildMonIndex]);
+
+ CreateWildMon(wildMonInfo->wildPokemon[wildMonIndex].species, level);
+ return wildMonInfo->wildPokemon[wildMonIndex].species;
+}
+
+static bool8 SetUpMassOutbreakEncounter(bool8 checkRepel)
+{
+ u16 i;
+
+ if (checkRepel == TRUE && IsWildLevelAllowedByRepel(gSaveBlock1.outbreakPokemonLevel) == FALSE)
+ return FALSE;
+ else
+ {
+ CreateWildMon(gSaveBlock1.outbreakPokemonSpecies, gSaveBlock1.outbreakPokemonLevel);
+ for (i = 0; i < 4; i++)
+ SetMonMoveSlot(&gEnemyParty[0], gSaveBlock1.outbreakPokemonMoves[i], i);
+ return TRUE;
+ }
+}
+
+static bool8 DoMassOutbreakEncounterTest(void)
+{
+ if (gSaveBlock1.outbreakPokemonSpecies != 0
+ && gSaveBlock1.location.mapNum == gSaveBlock1.outbreakLocationMapNum
+ && gSaveBlock1.location.mapGroup == gSaveBlock1.outbreakLocationMapGroup)
+ {
+ if (Random() % 100 < gSaveBlock1.outbreakPokemonProbability)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool8 DoWildEncounterRateDiceRoll(u16 encounterRate)
+{
+ if (Random() % 2880 < encounterRate)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static bool8 DoWildEncounterTest(u32 encounterRate, bool8 ignoreAbility)
+{
+ encounterRate *= 16;
+ if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE))
+ encounterRate = encounterRate * 80 / 100;
+ ApplyFluteEncounterRateMod(&encounterRate);
+ ApplyCleanseTagEncounterRateMod(&encounterRate);
+ if (!ignoreAbility)
+ {
+ // UB: Too few arguments for function 'GetMonData'
+ if (!GetMonData(&gPlayerParty[0], MON_DATA_SANITY_BIT3))
+ {
+ u32 ability = GetMonAbility(&gPlayerParty[0]);
+ if (ability == ABILITY_STENCH)
+ encounterRate /= 2;
+ if (ability == ABILITY_ILLUMINATE)
+ encounterRate *= 2;
+ }
+ }
+ if (encounterRate > 2880)
+ encounterRate = 2880;
+ return DoWildEncounterRateDiceRoll(encounterRate);
+}
+
+static bool8 DoGlobalWildEncounterDiceRoll(void)
+{
+ if (Random() % 100 >= 60)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+bool8 StandardWildEncounter(u16 a, u16 b)
+{
+ u16 headerNum;
+ struct Roamer *roamer;
+
+ if (sWildEncountersDisabled == TRUE)
+ return 0;
+ else
+ {
+ headerNum = GetCurrentMapWildMonHeader();
+ if (headerNum != 0xFFFF)
+ {
+ if (MetatileBehavior_IsLandWildEncounter(a) == TRUE)
+ {
+ if (gWildMonHeaders[headerNum].landMonsInfo)
+ {
+ if (b != a && !DoGlobalWildEncounterDiceRoll())
+ return 0;
+
+ if (DoWildEncounterTest(gWildMonHeaders[headerNum].landMonsInfo->encounterRate, 0) == TRUE)
+ {
+ if (TryStartRoamerEncounter() == TRUE)
+ {
+ roamer = &gSaveBlock1.roamer;
+ if (IsWildLevelAllowedByRepel(roamer->level))
+ {
+ BattleSetup_StartRoamerBattle();
+ return 1;
+ }
+ }
+ else
+ {
+ if (DoMassOutbreakEncounterTest() == TRUE && SetUpMassOutbreakEncounter(1) == TRUE)
+ {
+ BattleSetup_StartWildBattle();
+ return 1;
+ }
+ if (GenerateWildMon(gWildMonHeaders[headerNum].landMonsInfo, 0, TRUE) == TRUE)
+ {
+ goto label;
+ }
+ }
+ }
+ }
+ }
+ else if (MetatileBehavior_IsWaterWildEncounter(a) == TRUE
+ || (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING) && MetatileBehavior_IsBridge(a) == TRUE))
+ {
+ if (gWildMonHeaders[headerNum].waterMonsInfo)
+ {
+ if (b != a && !DoGlobalWildEncounterDiceRoll())
+ return 0;
+
+ if (DoWildEncounterTest(gWildMonHeaders[headerNum].waterMonsInfo->encounterRate, 0) == TRUE)
+ {
+ if (TryStartRoamerEncounter() == TRUE)
+ {
+ roamer = &gSaveBlock1.roamer;
+ if (IsWildLevelAllowedByRepel(roamer->level))
+ {
+ BattleSetup_StartRoamerBattle();
+ return 1;
+ }
+ }
+ else
+ {
+ //_08085268
+ if (GenerateWildMon(gWildMonHeaders[headerNum].waterMonsInfo, 1, TRUE) == TRUE)
+ {
+ label:
+ //_0808527A
+ BattleSetup_StartWildBattle();
+ return 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+void ScrSpecial_RockSmashWildEncounter(void)
+{
+ u16 headerNum = GetCurrentMapWildMonHeader();
+
+ if (headerNum != 0xFFFF)
+ {
+ struct WildPokemonInfo *wildPokemonInfo = gWildMonHeaders[headerNum].rockSmashMonsInfo;
+
+ if (wildPokemonInfo == NULL)
+ {
+ gScriptResult = 0;
+ return;
+ }
+ else if (DoWildEncounterTest(wildPokemonInfo->encounterRate, 1) == TRUE
+ && GenerateWildMon(wildPokemonInfo, 2, TRUE) == TRUE)
+ {
+ BattleSetup_StartWildBattle();
+ gScriptResult = 1;
+ return;
+ }
+ }
+ gScriptResult = 0;
+ return;
+}
+
+bool8 SweetScentWildEncounter(void)
+{
+ s16 x;
+ s16 y;
+ u16 headerNum;
+ struct WildPokemonInfo *wildPokemonInfo;
+
+ PlayerGetDestCoords(&x, &y);
+ if ((headerNum = GetCurrentMapWildMonHeader()) != 0xFFFF)
+ {
+ if (MetatileBehavior_IsLandWildEncounter(MapGridGetMetatileBehaviorAt(x, y)) == 1)
+ {
+ wildPokemonInfo = gWildMonHeaders[headerNum].landMonsInfo;
+ if (wildPokemonInfo == NULL)
+ return FALSE;
+ if (TryStartRoamerEncounter() == TRUE)
+ {
+ BattleSetup_StartRoamerBattle();
+ return TRUE;
+ }
+ if (DoMassOutbreakEncounterTest() == TRUE)
+ SetUpMassOutbreakEncounter(FALSE);
+ else
+ GenerateWildMon(wildPokemonInfo, 0, FALSE);
+ BattleSetup_StartWildBattle();
+ return TRUE;
+ }
+ else if (MetatileBehavior_IsWaterWildEncounter(MapGridGetMetatileBehaviorAt(x, y)) == 1)
+ {
+ wildPokemonInfo = gWildMonHeaders[headerNum].waterMonsInfo;
+ if (wildPokemonInfo == NULL)
+ return FALSE;
+ if (TryStartRoamerEncounter() == TRUE)
+ {
+ BattleSetup_StartRoamerBattle();
+ return TRUE;
+ }
+ GenerateWildMon(wildPokemonInfo, 1, FALSE);
+ BattleSetup_StartWildBattle();
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+bool8 DoesCurrentMapHaveFishingMons(void)
+{
+ u16 headerNum = GetCurrentMapWildMonHeader();
+
+ if (headerNum != 0xFFFF && gWildMonHeaders[headerNum].fishingMonsInfo != NULL)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void FishingWildEncounter(u8 rod)
+{
+ u16 species;
+
+ if (CheckFeebas() == TRUE)
+ {
+ u8 level = ChooseWildMonLevel(&gWildFeebasRoute119Data);
+
+ species = gWildFeebasRoute119Data.species;
+ CreateWildMon(species, level);
+ }
+ else
+ {
+ species = GenerateFishingWildMon(
+ gWildMonHeaders[GetCurrentMapWildMonHeader()].fishingMonsInfo,
+ rod);
+ }
+ IncrementGameStat(12);
+ sub_80BEA50(species);
+ BattleSetup_StartWildBattle();
+}
+
+u16 GetLocalWildMon(bool8 *isWaterMon)
+{
+ u16 headerNum;
+ struct WildPokemonInfo *landMonsInfo;
+ struct WildPokemonInfo *waterMonsInfo;
+
+ *isWaterMon = FALSE;
+ headerNum = GetCurrentMapWildMonHeader();
+ if (headerNum == 0xFFFF)
+ return 0;
+ landMonsInfo = gWildMonHeaders[headerNum].landMonsInfo;
+ waterMonsInfo = gWildMonHeaders[headerNum].waterMonsInfo;
+ //Neither
+ if (landMonsInfo == NULL && waterMonsInfo == NULL)
+ return 0;
+ //Land Pokemon
+ if (landMonsInfo != NULL && waterMonsInfo == NULL)
+ return landMonsInfo->wildPokemon[ChooseWildMonIndex_Land()].species;
+ //Water Pokemon
+ if (landMonsInfo == NULL && waterMonsInfo != NULL)
+ {
+ *isWaterMon = TRUE;
+ return waterMonsInfo->wildPokemon[ChooseWildMonIndex_Water()].species;
+ }
+ //Either land or water Pokemon
+ if ((Random() % 100) < 80)
+ return landMonsInfo->wildPokemon[ChooseWildMonIndex_Land()].species;
+ else
+ {
+ *isWaterMon = TRUE;
+ return waterMonsInfo->wildPokemon[ChooseWildMonIndex_Water()].species;
+ }
+}
+
+u16 GetLocalWaterMon(void)
+{
+ u16 headerNum = GetCurrentMapWildMonHeader();
+
+ if (headerNum != 0xFFFF)
+ {
+ struct WildPokemonInfo *waterMonsInfo = gWildMonHeaders[headerNum].waterMonsInfo;
+
+ if (waterMonsInfo)
+ return waterMonsInfo->wildPokemon[ChooseWildMonIndex_Water()].species;
+ }
+ return 0;
+}
+
+bool8 UpdateRepelCounter(void)
+{
+ u16 steps = VarGet(VAR_REPEL_STEP_COUNT);
+
+ if (steps != 0)
+ {
+ steps--;
+ VarSet(VAR_REPEL_STEP_COUNT, steps);
+ if (steps == 0)
+ {
+ ScriptContext1_SetupScript(S_RepelWoreOff);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static bool8 IsWildLevelAllowedByRepel(u8 wildLevel)
+{
+ u8 i;
+
+ if (!VarGet(VAR_REPEL_STEP_COUNT))
+ {
+ return TRUE;
+ }
+ else
+ {
+ for (i = 0; i < 6; i++)
+ {
+ // UB: Too few arguments for function 'GetMonData'
+ if (GetMonData(&gPlayerParty[i], MON_DATA_HP) && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG))
+ {
+ u8 ourLevel = GetMonData(&gPlayerParty[i], MON_DATA_LEVEL);
+
+ if (wildLevel < ourLevel)
+ return FALSE;
+ else
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+}
+
+static void ApplyFluteEncounterRateMod(u32 *encRate)
+{
+ if (FlagGet(SYS_ENC_UP_ITEM) == TRUE)
+ *encRate += *encRate / 2;
+ else if (FlagGet(SYS_ENC_DOWN_ITEM) == TRUE)
+ *encRate = *encRate / 2;
+}
+
+static void ApplyCleanseTagEncounterRateMod(u32 *encRate)
+{
+ // UB: Too few arguments for function 'GetMonData'
+ if (GetMonData(&gPlayerParty[0], MON_DATA_HELD_ITEM) == 0xBE)
+ *encRate = *encRate * 2 / 3;
+}