summaryrefslogtreecommitdiff
path: root/src/mystery_gift.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mystery_gift.c')
-rwxr-xr-x[-rw-r--r--]src/mystery_gift.c1966
1 files changed, 478 insertions, 1488 deletions
diff --git a/src/mystery_gift.c b/src/mystery_gift.c
index 6ae6a9534..1df6533d9 100644..100755
--- a/src/mystery_gift.c
+++ b/src/mystery_gift.c
@@ -1,1672 +1,662 @@
#include "global.h"
+#include "util.h"
#include "main.h"
-#include "text.h"
-#include "task.h"
-#include "malloc.h"
-#include "gpu_regs.h"
-#include "scanline_effect.h"
-#include "text_window.h"
-#include "bg.h"
-#include "window.h"
-#include "strings.h"
-#include "text_window.h"
-#include "menu.h"
-#include "palette.h"
-#include "constants/songs.h"
-#include "sound.h"
-#include "mystery_gift.h"
-#include "union_room.h"
-#include "title_screen.h"
-#include "ereader_screen.h"
-#include "international_string_util.h"
-#include "list_menu.h"
-#include "string_util.h"
-#include "mevent.h"
-#include "mevent_801BAAC.h"
-#include "save.h"
-#include "link.h"
-#include "mevent_client.h"
#include "event_data.h"
-#include "link_rfu.h"
-#include "mevent_news.h"
-#include "mevent_server.h"
-#include "constants/cable_club.h"
+#include "easy_chat.h"
+#include "script.h"
+#include "battle_tower.h"
+#include "wonder_news.h"
+#include "string_util.h"
+#include "new_game.h"
+#include "mystery_gift.h"
+#include "constants/mystery_gift.h"
-void bgid_upload_textbox_1(u8 bgId);
-void task_add_00_mystery_gift(void);
-void task00_mystery_gift(u8 taskId);
+static EWRAM_DATA bool32 sStatsEnabled = FALSE;
-EWRAM_DATA u8 sDownArrowCounterAndYCoordIdx[8] = {};
-EWRAM_DATA bool8 gGiftIsFromEReader = FALSE;
+static void ClearSavedWonderNewsMetadata(void);
+static void ClearSavedWonderNews(void);
+static void ClearSavedWonderCard(void);
+static bool32 ValidateWonderNews(const struct WonderNews *);
+static bool32 ValidateWonderCard(const struct WonderCard *);
+static void ClearSavedWonderCardMetadata(void);
+static void ClearSavedTrainerIds(void);
+static void IncrementCardStatForNewTrainer(u32, u32, u32 *, int);
-static const u16 gUnkTextboxBorderPal[] = INCBIN_U16("graphics/interface/unk_textbox_border.gbapal");
-static const u32 gUnkTextboxBorderGfx[] = INCBIN_U32("graphics/interface/unk_textbox_border.4bpp.lz");
+#define CALC_CRC(data) CalcCRC16WithTable((void *)&(data), sizeof(data))
-struct MysteryGiftTaskData
+void ClearMysteryGift(void)
{
- u16 curPromptWindowId;
- u16 unk2;
- u16 unk4;
- u16 unk6;
- u8 state;
- u8 textState;
- u8 unkA;
- u8 unkB;
- u8 IsCardOrNews;
- u8 source;
- u8 prevPromptWindowId;
- u8 * buffer;
-};
-
-static const struct BgTemplate sBGTemplates[] = {
- {
- .bg = 0,
- .charBaseIndex = 2,
- .mapBaseIndex = 15,
- .screenSize = 0,
- .paletteMode = 0,
- .priority = 0,
- .baseTile = 0x000
- }, {
- .bg = 1,
- .charBaseIndex = 0,
- .mapBaseIndex = 14,
- .screenSize = 0,
- .paletteMode = 0,
- .priority = 1,
- .baseTile = 0x000
- }, {
- .bg = 2,
- .charBaseIndex = 0,
- .mapBaseIndex = 13,
- .screenSize = 0,
- .paletteMode = 0,
- .priority = 2,
- .baseTile = 0x000
- }, {
- .bg = 3,
- .charBaseIndex = 0,
- .mapBaseIndex = 12,
- .screenSize = 0,
- .paletteMode = 0,
- .priority = 3,
- .baseTile = 0x000
- }
-};
-
-static const struct WindowTemplate sMainWindows[] = {
- {
- .bg = 0x00,
- .tilemapLeft = 0x00,
- .tilemapTop = 0x00,
- .width = 0x1e,
- .height = 0x02,
- .paletteNum = 0x0c,
- .baseBlock = 0x0013
- }, {
- .bg = 0x00,
- .tilemapLeft = 0x01,
- .tilemapTop = 0x0f,
- .width = 0x1c,
- .height = 0x04,
- .paletteNum = 0x0c,
- .baseBlock = 0x004f
- }, {
- .bg = 0x00,
- .tilemapLeft = 0x00,
- .tilemapTop = 0x0f,
- .width = 0x1e,
- .height = 0x05,
- .paletteNum = 0x0d,
- .baseBlock = 0x004f
- }, {
- 0xFF
- }
-};
-
-static const struct WindowTemplate sWindowTemplate_PromptYesOrNo_Width28 = {
- .bg = 0x00,
- .tilemapLeft = 0x01,
- .tilemapTop = 0x0f,
- .width = 0x1c,
- .height = 0x04,
- .paletteNum = 0x0c,
- .baseBlock = 0x00e5
-};
-
-static const struct WindowTemplate sWindowTemplate_PromptYesOrNo_Width20 = {
- .bg = 0x00,
- .tilemapLeft = 0x01,
- .tilemapTop = 0x0f,
- .width = 0x14,
- .height = 0x04,
- .paletteNum = 0x0c,
- .baseBlock = 0x00e5
-};
-
-static const struct WindowTemplate sMysteryGiftMenuWindowTemplate = {
- .bg = 0x00,
- .tilemapLeft = 0x01,
- .tilemapTop = 0x0f,
- .width = 0x13,
- .height = 0x04,
- .paletteNum = 0x0c,
- .baseBlock = 0x00e5
-};
-
-static const struct WindowTemplate sWindowTemplate_ThreeOptions = {
- .bg = 0x00,
- .tilemapLeft = 0x08,
- .tilemapTop = 0x06,
- .width = 0x0e,
- .height = 0x06,
- .paletteNum = 0x0c,
- .baseBlock = 0x0155
-};
-
-static const struct WindowTemplate sWindowTemplate_YesNoBox = {
- .bg = 0x00,
- .tilemapLeft = 0x17,
- .tilemapTop = 0x0f,
- .width = 0x06,
- .height = 0x04,
- .paletteNum = 0x0c,
- .baseBlock = 0x0155
-};
-
-static const struct WindowTemplate sWindowTemplate_7by8 = {
- .bg = 0x00,
- .tilemapLeft = 0x16,
- .tilemapTop = 0x0b,
- .width = 0x07,
- .height = 0x08,
- .paletteNum = 0x0c,
- .baseBlock = 0x0155
-};
-
-static const struct WindowTemplate sWindowTemplate_7by6 = {
- .bg = 0x00,
- .tilemapLeft = 0x16,
- .tilemapTop = 0x0d,
- .width = 0x07,
- .height = 0x06,
- .paletteNum = 0x0c,
- .baseBlock = 0x0155
-};
+ CpuFill32(0, &gSaveBlock1Ptr->mysteryGift, sizeof(gSaveBlock1Ptr->mysteryGift));
+ ClearSavedWonderNewsMetadata(); // Clear is redundant, InitSavedWonderNews would be sufficient
+ InitQuestionnaireWords();
+}
-static const struct WindowTemplate sWindowTemplate_7by4 = {
- .bg = 0x00,
- .tilemapLeft = 0x16,
- .tilemapTop = 0x0f,
- .width = 0x07,
- .height = 0x04,
- .paletteNum = 0x0c,
- .baseBlock = 0x0155
-};
+struct WonderNews *GetSavedWonderNews(void)
+{
+ return &gSaveBlock1Ptr->mysteryGift.news;
+}
-static const struct ListMenuItem sListMenuItems_CardsOrNews[] = {
- { gText_WonderCards, 0 },
- { gText_WonderNews, 1 },
- { gText_Exit3, -2 }
-};
+struct WonderCard *GetSavedWonderCard(void)
+{
+ return &gSaveBlock1Ptr->mysteryGift.card;
+}
-static const struct ListMenuItem sListMenuItems_WirelessOrFriend[] = {
- { gText_WirelessCommunication, 0 },
- { gText_Friend2, 1 },
- { gText_Cancel2, -2 }
-};
+struct WonderCardMetadata *GetSavedWonderCardMetadata(void)
+{
+ return &gSaveBlock1Ptr->mysteryGift.cardMetadata;
+}
-static const struct ListMenuTemplate sListMenuTemplate_ThreeOptions = {
- .items = NULL,
- .moveCursorFunc = ListMenuDefaultCursorMoveFunc,
- .itemPrintFunc = NULL,
- .totalItems = 3,
- .maxShowed = 3,
- .windowId = 0,
- .header_X = 0,
- .item_X = 8,
- .cursor_X = 0,
- .upText_Y = 1,
- .cursorPal = 2,
- .fillValue = 1,
- .cursorShadowPal = 3,
- .lettersSpacing = 0,
- .itemVerticalPadding = 0,
- .scrollMultiple = 0,
- .fontId = 1,
- .cursorKind = 0
-};
+struct WonderNewsMetadata *GetSavedWonderNewsMetadata(void)
+{
+ return &gSaveBlock1Ptr->mysteryGift.newsMetadata;
+}
-static const struct ListMenuItem sListMenuItems_ReceiveSendToss[] = {
- { gText_Receive, 0 },
- { gText_Send, 1 },
- { gText_Toss, 2 },
- { gText_Cancel2, -2 }
-};
+u16 *GetQuestionnaireWordsPtr(void)
+{
+ return gSaveBlock1Ptr->mysteryGift.questionnaireWords;
+}
-static const struct ListMenuItem sListMenuItems_ReceiveToss[] = {
- { gText_Receive, 0 },
- { gText_Toss, 2 },
- { gText_Cancel2, -2 }
-};
+// Equivalent to ClearSavedWonderCardAndRelated, but nothing else to clear
+void ClearSavedWonderNewsAndRelated(void)
+{
+ ClearSavedWonderNews();
+}
-static const struct ListMenuItem sListMenuItems_ReceiveSend[] = {
- { gText_Receive, 0 },
- { gText_Send, 1 },
- { gText_Cancel2, -2 }
-};
+bool32 SaveWonderNews(const struct WonderNews *news)
+{
+ if (!ValidateWonderNews(news))
+ return FALSE;
-static const struct ListMenuItem sListMenuItems_Receive[] = {
- { gText_Receive, 0 },
- { gText_Cancel2, -2 }
-};
+ ClearSavedWonderNews();
+ gSaveBlock1Ptr->mysteryGift.news = *news;
+ gSaveBlock1Ptr->mysteryGift.newsCrc = CALC_CRC(gSaveBlock1Ptr->mysteryGift.news);
+ return TRUE;
+}
-static const struct ListMenuTemplate sListMenu_ReceiveSendToss = {
- .items = sListMenuItems_ReceiveSendToss,
- .moveCursorFunc = ListMenuDefaultCursorMoveFunc,
- .itemPrintFunc = NULL,
- .totalItems = 4,
- .maxShowed = 4,
- .windowId = 0,
- .header_X = 0,
- .item_X = 8,
- .cursor_X = 0,
- .upText_Y = 1,
- .cursorPal = 2,
- .fillValue = 1,
- .cursorShadowPal = 3,
- .lettersSpacing = 0,
- .itemVerticalPadding = 0,
- .scrollMultiple = 0,
- .fontId = 1,
- .cursorKind = 0
-};
+bool32 ValidateSavedWonderNews(void)
+{
+ if (CALC_CRC(gSaveBlock1Ptr->mysteryGift.news) != gSaveBlock1Ptr->mysteryGift.newsCrc)
+ return FALSE;
+ if (!ValidateWonderNews(&gSaveBlock1Ptr->mysteryGift.news))
+ return FALSE;
-static const struct ListMenuTemplate sListMenu_ReceiveToss = {
- .items = sListMenuItems_ReceiveToss,
- .moveCursorFunc = ListMenuDefaultCursorMoveFunc,
- .itemPrintFunc = NULL,
- .totalItems = 3,
- .maxShowed = 3,
- .windowId = 0,
- .header_X = 0,
- .item_X = 8,
- .cursor_X = 0,
- .upText_Y = 1,
- .cursorPal = 2,
- .fillValue = 1,
- .cursorShadowPal = 3,
- .lettersSpacing = 0,
- .itemVerticalPadding = 0,
- .scrollMultiple = 0,
- .fontId = 1,
- .cursorKind = 0
-};
+ return TRUE;
+}
-static const struct ListMenuTemplate sListMenu_ReceiveSend = {
- .items = sListMenuItems_ReceiveSend,
- .moveCursorFunc = ListMenuDefaultCursorMoveFunc,
- .itemPrintFunc = NULL,
- .totalItems = 3,
- .maxShowed = 3,
- .windowId = 0,
- .header_X = 0,
- .item_X = 8,
- .cursor_X = 0,
- .upText_Y = 1,
- .cursorPal = 2,
- .fillValue = 1,
- .cursorShadowPal = 3,
- .lettersSpacing = 0,
- .itemVerticalPadding = 0,
- .scrollMultiple = 0,
- .fontId = 1,
- .cursorKind = 0
-};
+static bool32 ValidateWonderNews(const struct WonderNews *news)
+{
+ if (news->id == 0)
+ return FALSE;
-static const struct ListMenuTemplate sListMenu_Receive = {
- .items = sListMenuItems_Receive,
- .moveCursorFunc = ListMenuDefaultCursorMoveFunc,
- .itemPrintFunc = NULL,
- .totalItems = 2,
- .maxShowed = 2,
- .windowId = 0,
- .header_X = 0,
- .item_X = 8,
- .cursor_X = 0,
- .upText_Y = 1,
- .cursorPal = 2,
- .fillValue = 1,
- .cursorShadowPal = 3,
- .lettersSpacing = 0,
- .itemVerticalPadding = 0,
- .scrollMultiple = 0,
- .fontId = 1,
- .cursorKind = 0
-};
+ return TRUE;
+}
-static const u8 *const Unref_082F0710[] = {
- gText_VarietyOfEventsImportedWireless,
- gText_WonderCardsInPossession,
- gText_ReadNewsThatArrived,
- gText_ReturnToTitle
-};
+bool32 IsSendingSavedWonderNewsAllowed(void)
+{
+ const struct WonderNews *news = &gSaveBlock1Ptr->mysteryGift.news;
+ if (news->sendType == SEND_TYPE_DISALLOWED)
+ return FALSE;
-ALIGNED(2) const u8 sMG_Ereader_TextColor_1[] = { 0, 1, 2 };
-ALIGNED(2) const u8 sMG_Ereader_TextColor_1_Copy[] = { 0, 1, 2 };
-ALIGNED(2) const u8 sMG_Ereader_TextColor_2[] = { 1, 2, 3 };
+ return TRUE;
+}
-void vblankcb_mystery_gift_e_reader_run(void)
+static void ClearSavedWonderNews(void)
{
- ProcessSpriteCopyRequests();
- LoadOam();
- TransferPlttBuffer();
+ CpuFill32(0, GetSavedWonderNews(), sizeof(gSaveBlock1Ptr->mysteryGift.news));
+ gSaveBlock1Ptr->mysteryGift.newsCrc = 0;
}
-void c2_mystery_gift_e_reader_run(void)
+static void ClearSavedWonderNewsMetadata(void)
{
- RunTasks();
- RunTextPrinters();
- AnimateSprites();
- BuildOamBuffer();
+ CpuFill32(0, GetSavedWonderNewsMetadata(), sizeof(gSaveBlock1Ptr->mysteryGift.newsMetadata));
+ InitSavedWonderNews();
}
-bool32 HandleMysteryGiftOrEReaderSetup(s32 mg_or_ereader)
+bool32 IsWonderNewsSameAsSaved(const u8 *news)
{
- switch (gMain.state)
+ const u8 *savedNews = (const u8 *)&gSaveBlock1Ptr->mysteryGift.news;
+ u32 i;
+ if (!ValidateSavedWonderNews())
+ return FALSE;
+
+ for (i = 0; i < sizeof(gSaveBlock1Ptr->mysteryGift.news); i++)
{
- case 0:
- SetVBlankCallback(NULL);
- ResetPaletteFade();
- ResetSpriteData();
- FreeAllSpritePalettes();
- ResetTasks();
- ScanlineEffect_Stop();
- ResetBgsAndClearDma3BusyFlags(0);
-
- InitBgsFromTemplates(0, sBGTemplates, ARRAY_COUNT(sBGTemplates));
- ChangeBgX(0, 0, 0);
- ChangeBgY(0, 0, 0);
- ChangeBgX(1, 0, 0);
- ChangeBgY(1, 0, 0);
- ChangeBgX(2, 0, 0);
- ChangeBgY(2, 0, 0);
- ChangeBgX(3, 0, 0);
- ChangeBgY(3, 0, 0);
-
- SetBgTilemapBuffer(3, Alloc(BG_SCREEN_SIZE));
- SetBgTilemapBuffer(2, Alloc(BG_SCREEN_SIZE));
- SetBgTilemapBuffer(1, Alloc(BG_SCREEN_SIZE));
- SetBgTilemapBuffer(0, Alloc(BG_SCREEN_SIZE));
-
- bgid_upload_textbox_1(3);
- InitWindows(sMainWindows);
- DeactivateAllTextPrinters();
- ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON | DISPCNT_WIN1_ON);
- SetGpuReg(REG_OFFSET_BLDCNT, 0);
- SetGpuReg(REG_OFFSET_BLDALPHA, 0);
- SetGpuReg(REG_OFFSET_BLDY, 0);
- gMain.state++;
- break;
- case 1:
- LoadPalette(gUnkTextboxBorderPal, 0, 0x20);
- LoadPalette(GetTextWindowPalette(2), 0xd0, 0x20);
- Menu_LoadStdPalAt(0xC0);
- LoadUserWindowBorderGfx(0, 0xA, 0xE0);
- LoadUserWindowBorderGfx_(0, 0x1, 0xF0);
- FillBgTilemapBufferRect(0, 0x000, 0, 0, 32, 32, 0x11);
- FillBgTilemapBufferRect(1, 0x000, 0, 0, 32, 32, 0x11);
- FillBgTilemapBufferRect(2, 0x000, 0, 0, 32, 32, 0x11);
- MG_DrawCheckerboardPattern(3);
- PrintMysteryGiftOrEReaderTopMenu(mg_or_ereader, 0);
- gMain.state++;
- break;
- case 2:
- CopyBgTilemapBufferToVram(3);
- CopyBgTilemapBufferToVram(2);
- CopyBgTilemapBufferToVram(1);
- CopyBgTilemapBufferToVram(0);
- gMain.state++;
- break;
- case 3:
- ShowBg(0);
- ShowBg(3);
- PlayBGM(MUS_RG_MYSTERY_GIFT);
- SetVBlankCallback(vblankcb_mystery_gift_e_reader_run);
- EnableInterrupts(INTR_FLAG_VBLANK | INTR_FLAG_VCOUNT | INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL);
- return TRUE;
+ if (savedNews[i] != news[i])
+ return FALSE;
}
- return FALSE;
+ return TRUE;
}
-void c2_mystery_gift(void)
+void ClearSavedWonderCardAndRelated(void)
{
- if (HandleMysteryGiftOrEReaderSetup(0))
- {
- SetMainCallback2(c2_mystery_gift_e_reader_run);
- gGiftIsFromEReader = FALSE;
- task_add_00_mystery_gift();
- }
- RunTasks();
+ ClearSavedWonderCard();
+ ClearSavedWonderCardMetadata();
+ ClearSavedTrainerIds();
+ ClearRamScript();
+ ClearMysteryGiftFlags();
+ ClearMysteryGiftVars();
+ ClearEReaderTrainer(&gSaveBlock2Ptr->frontier.ereaderTrainer);
}
-void c2_ereader(void)
+bool32 SaveWonderCard(const struct WonderCard *card)
{
- if (HandleMysteryGiftOrEReaderSetup(1))
- {
- SetMainCallback2(c2_mystery_gift_e_reader_run);
- gGiftIsFromEReader = TRUE;
- task_add_00_ereader();
- }
-}
+ struct WonderCardMetadata *metadata;
+ if (!ValidateWonderCard(card))
+ return FALSE;
-void MainCB_FreeAllBuffersAndReturnToInitTitleScreen(void)
-{
- gGiftIsFromEReader = FALSE;
- FreeAllWindowBuffers();
- Free(GetBgTilemapBuffer(0));
- Free(GetBgTilemapBuffer(1));
- Free(GetBgTilemapBuffer(2));
- Free(GetBgTilemapBuffer(3));
- SetMainCallback2(CB2_InitTitleScreen);
+ ClearSavedWonderCardAndRelated();
+ memcpy(&gSaveBlock1Ptr->mysteryGift.card, card, sizeof(struct WonderCard));
+ gSaveBlock1Ptr->mysteryGift.cardCrc = CALC_CRC(gSaveBlock1Ptr->mysteryGift.card);
+ metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata;
+ metadata->iconSpecies = (&gSaveBlock1Ptr->mysteryGift.card)->iconSpecies;
+ return TRUE;
}
-void PrintMysteryGiftOrEReaderTopMenu(bool8 mg_or_ereader, bool32 usePickOkCancel)
+bool32 ValidateSavedWonderCard(void)
{
- const u8 * header;
- const u8 * options;
- FillWindowPixelBuffer(0, 0);
- if (mg_or_ereader == 0)
- {
- header = gText_MysteryGift;
- options = !usePickOkCancel ? gText_PickOKExit : gText_PickOKCancel;
- }
- else
- {
- header = gJPText_MysteryGift;
- options = gJPText_DecideStop;
- }
+ if (gSaveBlock1Ptr->mysteryGift.cardCrc != CALC_CRC(gSaveBlock1Ptr->mysteryGift.card))
+ return FALSE;
+ if (!ValidateWonderCard(&gSaveBlock1Ptr->mysteryGift.card))
+ return FALSE;
+ if (!ValidateSavedRamScript())
+ return FALSE;
- AddTextPrinterParameterized4(0, 1, 4, 1, 0, 0, sMG_Ereader_TextColor_1, -1, header);
- AddTextPrinterParameterized4(0, 0, GetStringRightAlignXOffset(0, options, 0xDE), 1, 0, 0, sMG_Ereader_TextColor_1, -1, options);
- CopyWindowToVram(0, 2);
- PutWindowTilemap(0);
+ return TRUE;
}
-void MG_DrawTextBorder(u8 windowId)
+static bool32 ValidateWonderCard(const struct WonderCard *card)
{
- DrawTextBorderOuter(windowId, 0x01, 0xF);
+ if (card->flagId == 0)
+ return FALSE;
+ if (card->type >= CARD_TYPE_COUNT)
+ return FALSE;
+ if (!(card->sendType == SEND_TYPE_DISALLOWED
+ || card->sendType == SEND_TYPE_ALLOWED
+ || card->sendType == SEND_TYPE_ALLOWED_ALWAYS))
+ return FALSE;
+ if (card->bgType >= NUM_WONDER_BGS)
+ return FALSE;
+ if (card->maxStamps > MAX_STAMP_CARD_STAMPS)
+ return FALSE;
+
+ return TRUE;
}
-void MG_DrawCheckerboardPattern(u32 bg)
+bool32 IsSendingSavedWonderCardAllowed(void)
{
- s32 i = 0, j;
+ const struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
+ if (card->sendType == SEND_TYPE_DISALLOWED)
+ return FALSE;
- FillBgTilemapBufferRect(bg, 0x003, 0, 0, 32, 2, 0x11);
+ return TRUE;
+}
- for (i = 0; i < 18; i++)
- {
- for (j = 0; j < 32; j++)
- {
- if ((i & 1) != (j & 1))
- FillBgTilemapBufferRect(bg, 1, j, i + 2, 1, 1, 0x11);
- else
- FillBgTilemapBufferRect(bg, 2, j, i + 2, 1, 1, 0x11);
- }
- }
+static void ClearSavedWonderCard(void)
+{
+ CpuFill32(0, &gSaveBlock1Ptr->mysteryGift.card, sizeof(gSaveBlock1Ptr->mysteryGift.card));
+ gSaveBlock1Ptr->mysteryGift.cardCrc = 0;
}
-void ClearScreenInBg0(bool32 ignoreTopTwoRows)
+static void ClearSavedWonderCardMetadata(void)
{
- switch (ignoreTopTwoRows)
- {
- case 0:
- FillBgTilemapBufferRect(0, 0, 0, 0, 32, 32, 0x11);
- break;
- case 1:
- FillBgTilemapBufferRect(0, 0, 0, 2, 32, 30, 0x11);
- break;
- }
- CopyBgTilemapBufferToVram(0);
+ CpuFill32(0, GetSavedWonderCardMetadata(), sizeof(gSaveBlock1Ptr->mysteryGift.cardMetadata));
+ gSaveBlock1Ptr->mysteryGift.cardMetadataCrc = 0;
}
-void AddTextPrinterToWindow1(const u8 *str)
+u16 GetWonderCardFlagID(void)
{
- StringExpandPlaceholders(gStringVar4, str);
- FillWindowPixelBuffer(1, 0x11);
- AddTextPrinterParameterized4(1, 1, 0, 1, 0, 0, sMG_Ereader_TextColor_2, 0, gStringVar4);
- DrawTextBorderOuter(1, 0x001, 0xF);
- PutWindowTilemap(1);
- CopyWindowToVram(1, 3);
+ if (ValidateSavedWonderCard())
+ return gSaveBlock1Ptr->mysteryGift.card.flagId;
+
+ return 0;
}
-static void ClearTextWindow(void)
+void DisableWonderCardSending(struct WonderCard *card)
{
- rbox_fill_rectangle(1);
- ClearWindowTilemap(1);
- CopyWindowToVram(1, 1);
+ if (card->sendType == SEND_TYPE_ALLOWED)
+ card->sendType = SEND_TYPE_DISALLOWED;
}
-bool32 MG_PrintTextOnWindow1AndWaitButton(u8 *textState, const u8 *str)
+static bool32 IsWonderCardFlagIDInValidRange(u16 flagId)
{
- switch (*textState)
- {
- case 0:
- AddTextPrinterToWindow1(str);
- (*textState)++;
- break;
- case 1:
- DrawDownArrow(1, 0xD0, 0x14, 1, FALSE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]);
- if (({JOY_NEW(A_BUTTON | B_BUTTON);}))
- (*textState)++;
- break;
- case 2:
- DrawDownArrow(1, 0xD0, 0x14, 1, TRUE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]);
- *textState = 0;
- ClearTextWindow();
+ if (flagId >= WONDER_CARD_FLAG_OFFSET && flagId < WONDER_CARD_FLAG_OFFSET + NUM_WONDER_CARD_FLAGS)
return TRUE;
- case 0xFF:
- *textState = 2;
- return FALSE;
- }
+
return FALSE;
}
-static void HideDownArrow(void)
+static const u16 sReceivedGiftFlags[] =
+{
+ FLAG_RECEIVED_AURORA_TICKET,
+ FLAG_RECEIVED_MYSTIC_TICKET,
+ FLAG_RECEIVED_OLD_SEA_MAP,
+ FLAG_WONDER_CARD_UNUSED_1,
+ FLAG_WONDER_CARD_UNUSED_2,
+ FLAG_WONDER_CARD_UNUSED_3,
+ FLAG_WONDER_CARD_UNUSED_4,
+ FLAG_WONDER_CARD_UNUSED_5,
+ FLAG_WONDER_CARD_UNUSED_6,
+ FLAG_WONDER_CARD_UNUSED_7,
+ FLAG_WONDER_CARD_UNUSED_8,
+ FLAG_WONDER_CARD_UNUSED_9,
+ FLAG_WONDER_CARD_UNUSED_10,
+ FLAG_WONDER_CARD_UNUSED_11,
+ FLAG_WONDER_CARD_UNUSED_12,
+ FLAG_WONDER_CARD_UNUSED_13,
+ FLAG_WONDER_CARD_UNUSED_14,
+ FLAG_WONDER_CARD_UNUSED_15,
+ FLAG_WONDER_CARD_UNUSED_16,
+ FLAG_WONDER_CARD_UNUSED_17,
+};
+
+bool32 IsSavedWonderCardGiftNotReceived(void)
{
- DrawDownArrow(1, 0xD0, 0x14, 1, FALSE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]);
+ u16 value = GetWonderCardFlagID();
+ if (!IsWonderCardFlagIDInValidRange(value))
+ return FALSE;
+
+ // If flag is set, player has received gift from this card
+ if (FlagGet(sReceivedGiftFlags[value - WONDER_CARD_FLAG_OFFSET]) == TRUE)
+ return FALSE;
+
+ return TRUE;
}
-static void ShowDownArrow(void)
+static int GetNumStampsInMetadata(const struct WonderCardMetadata *data, int size)
{
- DrawDownArrow(1, 0xD0, 0x14, 1, TRUE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]);
+ int numStamps = 0;
+ int i;
+ for (i = 0; i < size; i++)
+ {
+ if (data->stampData[STAMP_ID][i] && data->stampData[STAMP_SPECIES][i] != SPECIES_NONE)
+ numStamps++;
+ }
+
+ return numStamps;
}
-bool32 unref_HideDownArrowAndWaitButton(u8 * textState)
+static bool32 IsStampInMetadata(const struct WonderCardMetadata *metadata, const u16 *stamp, int maxStamps)
{
- switch (*textState)
+ int i;
+ for (i = 0; i < maxStamps; i++)
{
- case 0:
- HideDownArrow();
- if (JOY_NEW(A_BUTTON | B_BUTTON))
- (*textState)++;
- break;
- case 1:
- ShowDownArrow();
- *textState = 0;
- return TRUE;
+ if (metadata->stampData[STAMP_ID][i] == stamp[STAMP_ID])
+ return TRUE;
+ if (metadata->stampData[STAMP_SPECIES][i] == stamp[STAMP_SPECIES])
+ return TRUE;
}
+
return FALSE;
}
-static bool32 PrintStringAndWait2Seconds(u8 * counter, const u8 * str)
+static bool32 ValidateStamp(const u16 *stamp)
{
- if (*counter == 0)
- AddTextPrinterToWindow1(str);
-
- if (++(*counter) > 120)
- {
- *counter = 0;
- ClearTextWindow();
- return TRUE;
- }
- else
- {
+ if (stamp[STAMP_ID] == 0)
return FALSE;
- }
+ if (stamp[STAMP_SPECIES] == SPECIES_NONE)
+ return FALSE;
+ if (stamp[STAMP_SPECIES] >= NUM_SPECIES)
+ return FALSE;
+ return TRUE;
}
-static u32 MysteryGift_HandleThreeOptionMenu(u8 * unused0, u16 * unused1, u8 whichMenu)
+static int GetNumStampsInSavedCard(void)
{
- struct ListMenuTemplate listMenuTemplate = sListMenuTemplate_ThreeOptions;
- struct WindowTemplate windowTemplate = sWindowTemplate_ThreeOptions;
- s32 width;
- s32 response;
+ struct WonderCard *card;
+ if (!ValidateSavedWonderCard())
+ return 0;
- if (whichMenu == 0)
- listMenuTemplate.items = sListMenuItems_CardsOrNews;
- else
- listMenuTemplate.items = sListMenuItems_WirelessOrFriend;
-
- width = Intl_GetListMenuWidth(&listMenuTemplate);
- if (width & 1)
- width++;
-
- windowTemplate.width = width;
- if (width < 30)
- windowTemplate.tilemapLeft = (30 - width) / 2;
- else
- windowTemplate.tilemapLeft = 0;
+ card = &gSaveBlock1Ptr->mysteryGift.card;
+ if (card->type != CARD_TYPE_STAMP)
+ return 0;
- response = DoMysteryGiftListMenu(&windowTemplate, &listMenuTemplate, 1, 0x00A, 0xE0);
- if (response != -1)
- {
- ClearWindowTilemap(2);
- CopyWindowToVram(2, 1);
- }
- return response;
+ return GetNumStampsInMetadata(&gSaveBlock1Ptr->mysteryGift.cardMetadata, card->maxStamps);
}
-s8 mevent_message_print_and_prompt_yes_no(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, const u8 * str)
+bool32 MysteryGift_TrySaveStamp(const u16 *stamp)
{
- struct WindowTemplate windowTemplate;
- s8 input;
+ struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
+ int maxStamps = card->maxStamps;
+ int i;
+ if (!ValidateStamp(stamp))
+ return FALSE;
+
+ if (IsStampInMetadata(&gSaveBlock1Ptr->mysteryGift.cardMetadata, stamp, maxStamps))
+ return FALSE;
- switch (*textState)
+ for (i = 0; i < maxStamps; i++)
{
- case 0:
- StringExpandPlaceholders(gStringVar4, str);
- if (yesNoBoxPlacement == 0)
- *windowId = AddWindow(&sWindowTemplate_PromptYesOrNo_Width28);
- else
- *windowId = AddWindow(&sWindowTemplate_PromptYesOrNo_Width20);
- FillWindowPixelBuffer(*windowId, 0x11);
- AddTextPrinterParameterized4(*windowId, 1, 0, 1, 0, 0, sMG_Ereader_TextColor_2, 0, gStringVar4);
- DrawTextBorderOuter(*windowId, 0x001, 0x0F);
- CopyWindowToVram(*windowId, 2);
- PutWindowTilemap(*windowId);
- (*textState)++;
- break;
- case 1:
- windowTemplate = sWindowTemplate_YesNoBox;
- if (yesNoBoxPlacement == 0)
- windowTemplate.tilemapTop = 9;
- else
- windowTemplate.tilemapTop = 15;
- CreateYesNoMenu(&windowTemplate, 10, 14, 0);
- (*textState)++;
- break;
- case 2:
- input = Menu_ProcessInputNoWrapClearOnChoose();
- if (input == MENU_B_PRESSED || input == 0 || input == 1)
+ if (gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[STAMP_ID][i] == 0
+ && gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[STAMP_SPECIES][i] == SPECIES_NONE)
{
- *textState = 0;
- rbox_fill_rectangle(*windowId);
- ClearWindowTilemap(*windowId);
- CopyWindowToVram(*windowId, 1);
- RemoveWindow(*windowId);
- return input;
+ gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[STAMP_ID][i] = stamp[STAMP_ID];
+ gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[STAMP_SPECIES][i] = stamp[STAMP_SPECIES];
+ return TRUE;
}
- break;
- case (u8)MENU_B_PRESSED:
- *textState = 0;
- rbox_fill_rectangle(*windowId);
- ClearWindowTilemap(*windowId);
- CopyWindowToVram(*windowId, 1);
- RemoveWindow(*windowId);
- return MENU_B_PRESSED;
}
- return MENU_NOTHING_CHOSEN;
+ return FALSE;
}
-static s32 HandleMysteryGiftListMenu(u8 * textState, u16 * windowId, bool32 cannotToss, bool32 cannotSend)
+#define GAME_DATA_VALID_VAR 0x101
+#define GAME_DATA_VALID_GIFT_TYPE_1 (1 << 2)
+#define GAME_DATA_VALID_GIFT_TYPE_2 (1 << 9)
+
+void MysteryGift_LoadLinkGameData(struct MysteryGiftLinkGameData *data, bool32 isWonderNews)
{
- struct WindowTemplate windowTemplate;
- s32 input;
+ int i;
+ CpuFill32(0, data, sizeof(*data));
+ data->validationVar = GAME_DATA_VALID_VAR;
+ data->validationFlag1 = 1;
+ data->validationFlag2 = 1;
- switch (*textState)
+ if (isWonderNews)
{
- case 0:
- if (cannotToss == 0)
- {
- StringExpandPlaceholders(gStringVar4, gText_WhatToDoWithCards);
- }
- else
- {
- StringExpandPlaceholders(gStringVar4, gText_WhatToDoWithNews);
- }
- *windowId = AddWindow(&sMysteryGiftMenuWindowTemplate);
- FillWindowPixelBuffer(*windowId, 0x11);
- AddTextPrinterParameterized4(*windowId, 1, 0, 1, 0, 0, sMG_Ereader_TextColor_2, 0, gStringVar4);
- DrawTextBorderOuter(*windowId, 0x001, 0x0F);
- CopyWindowToVram(*windowId, 2);
- PutWindowTilemap(*windowId);
- (*textState)++;
- break;
- case 1:
- windowTemplate = sWindowTemplate_YesNoBox;
- if (cannotSend)
- {
- if (cannotToss == 0)
- {
- input = DoMysteryGiftListMenu(&sWindowTemplate_7by6, &sListMenu_ReceiveToss, 1, 0x00A, 0xE0);
- }
- else
- {
- input = DoMysteryGiftListMenu(&sWindowTemplate_7by4, &sListMenu_Receive, 1, 0x00A, 0xE0);
- }
- }
- else
- {
- if (cannotToss == 0)
- {
- input = DoMysteryGiftListMenu(&sWindowTemplate_7by8, &sListMenu_ReceiveSendToss, 1, 0x00A, 0xE0);
- }
- else
- {
- input = DoMysteryGiftListMenu(&sWindowTemplate_7by6, &sListMenu_ReceiveSend, 1, 0x00A, 0xE0);
- }
- }
- if (input != -1)
- {
- *textState = 0;
- rbox_fill_rectangle(*windowId);
- ClearWindowTilemap(*windowId);
- CopyWindowToVram(*windowId, 1);
- RemoveWindow(*windowId);
- return input;
- }
- break;
- case 0xFF:
- *textState = 0;
- rbox_fill_rectangle(*windowId);
- ClearWindowTilemap(*windowId);
- CopyWindowToVram(*windowId, 1);
- RemoveWindow(*windowId);
- return -2;
+ // Despite setting these for News, they are
+ // only ever checked for Cards
+ data->validationGiftType1 = GAME_DATA_VALID_GIFT_TYPE_1 | 1;
+ data->validationGiftType2 = GAME_DATA_VALID_GIFT_TYPE_2 | 1;
+ }
+ else // Wonder Card
+ {
+ data->validationGiftType1 = GAME_DATA_VALID_GIFT_TYPE_1;
+ data->validationGiftType2 = GAME_DATA_VALID_GIFT_TYPE_2;
}
- return -1;
-}
-
-static bool32 ValidateCardOrNews(bool32 cardOrNews)
-{
- if (cardOrNews == 0)
+ if (ValidateSavedWonderCard())
{
- return ValidateReceivedWonderCard();
+ data->flagId = GetSavedWonderCard()->flagId;
+ data->cardMetadata = *GetSavedWonderCardMetadata();
+ data->maxStamps = GetSavedWonderCard()->maxStamps;
}
else
{
- return ValidateReceivedWonderNews();
+ data->flagId = 0;
}
+
+ for (i = 0; i < NUM_QUESTIONNAIRE_WORDS; i++)
+ data->questionnaireWords[i] = gSaveBlock1Ptr->mysteryGift.questionnaireWords[i];
+
+ CopyTrainerId(data->playerTrainerId, gSaveBlock2Ptr->playerTrainerId);
+ StringCopy(data->playerName, gSaveBlock2Ptr->playerName);
+ for (i = 0; i < EASY_CHAT_BATTLE_WORDS_COUNT; i++)
+ data->easyChatProfile[i] = gSaveBlock1Ptr->easyChatProfile[i];
+
+ memcpy(data->romHeaderGameCode, RomHeaderGameCode, GAME_CODE_LENGTH);
+ data->romHeaderSoftwareVersion = RomHeaderSoftwareVersion;
}
-static bool32 HandleLoadWonderCardOrNews(u8 * state, bool32 cardOrNews)
+bool32 MysteryGift_ValidateLinkGameData(const struct MysteryGiftLinkGameData *data, bool32 isWonderNews)
{
- switch (*state)
+ if (data->validationVar != GAME_DATA_VALID_VAR)
+ return FALSE;
+
+ if (!(data->validationFlag1 & 1))
+ return FALSE;
+
+ if (!(data->validationFlag2 & 1))
+ return FALSE;
+
+ if (!isWonderNews)
{
- case 0:
- if (cardOrNews == 0)
- {
- InitWonderCardResources(GetSavedWonderCard(), sav1_get_mevent_buffer_2());
- }
- else
- {
- InitWonderNewsResources(GetSavedWonderNews());
- }
- (*state)++;
- break;
- case 1:
- if (cardOrNews == 0)
- {
- if (!FadeToWonderCardMenu())
- {
- return FALSE;
- }
- }
- else
- {
- if (!FadeToWonderNewsMenu())
- {
- return FALSE;
- }
- }
- *state = 0;
- return TRUE;
+ if (!(data->validationGiftType1 & GAME_DATA_VALID_GIFT_TYPE_1))
+ return FALSE;
+
+ if (!(data->validationGiftType2 & (GAME_DATA_VALID_GIFT_TYPE_2 | 0x180)))
+ return FALSE;
}
- return FALSE;
+ return TRUE;
}
-static bool32 DestroyNewsOrCard(bool32 cardOrNews)
+u32 MysteryGift_CompareCardFlags(const u16 *flagId, const struct MysteryGiftLinkGameData *data, const void *unused)
{
- if (cardOrNews == 0)
- {
- DestroyWonderCard();
- }
- else
- {
- DestroyWonderNews();
- }
- return TRUE;
+ // Has a Wonder Card already?
+ if (data->flagId == 0)
+ return HAS_NO_CARD;
+
+ // Has this Wonder Card already?
+ if (*flagId == data->flagId)
+ return HAS_SAME_CARD;
+
+ // Player has a different Wonder Card
+ return HAS_DIFF_CARD;
}
-static bool32 TearDownCardOrNews_ReturnToTopMenu(bool32 cardOrNews, bool32 arg1)
+// This is referenced by the Mystery Gift server, but the instruction it's referenced in is never used,
+// so the return values here are never checked by anything.
+u32 MysteryGift_CheckStamps(const u16 *stamp, const struct MysteryGiftLinkGameData *data, const void *unused)
{
- if (cardOrNews == 0)
- {
- if (FadeOutFromWonderCard(arg1) != 0)
- {
- DestroyWonderCardResources();
- return TRUE;
- }
- else
- {
- return FALSE;
- }
- }
- else
+ int stampsMissing = data->maxStamps - GetNumStampsInMetadata(&data->cardMetadata, data->maxStamps);
+
+ // Has full stamp card?
+ if (stampsMissing == 0)
+ return 1;
+
+ // Already has stamp?
+ if (IsStampInMetadata(&data->cardMetadata, stamp, data->maxStamps))
+ return 3;
+
+ // Only 1 empty stamp left?
+ if (stampsMissing == 1)
+ return 4;
+
+ // This is a new stamp
+ return 2;
+}
+
+bool32 MysteryGift_DoesQuestionnaireMatch(const struct MysteryGiftLinkGameData *data, const u16 *words)
+{
+ int i;
+ for (i = 0; i < NUM_QUESTIONNAIRE_WORDS; i++)
{
- if (FadeOutFromWonderNews(arg1) != 0)
- {
- DestroyWonderNewsResources();
- return TRUE;
- }
- else
- {
+ if (data->questionnaireWords[i] != words[i])
return FALSE;
- }
}
+
+ return TRUE;
}
-static s32 mevent_message_prompt_discard(u8 * textState, u16 * windowId, bool32 cardOrNews)
+static int GetNumStampsInLinkData(const struct MysteryGiftLinkGameData *data)
{
- if (cardOrNews == 0)
- {
- return mevent_message_print_and_prompt_yes_no(textState, windowId, TRUE, gText_IfThrowAwayCardEventWontHappen);
- }
- else
- {
- return mevent_message_print_and_prompt_yes_no(textState, windowId, TRUE, gText_OkayToDiscardNews);
- }
+ return GetNumStampsInMetadata(&data->cardMetadata, data->maxStamps);
}
-static bool32 mevent_message_was_thrown_away(u8 * textState, bool32 cardOrNews)
+u16 MysteryGift_GetCardStatFromLinkData(const struct MysteryGiftLinkGameData *data, u32 stat)
{
- if (cardOrNews == 0)
- {
- return MG_PrintTextOnWindow1AndWaitButton(textState, gText_WonderCardThrownAway);
- }
- else
+ switch (stat)
{
- return MG_PrintTextOnWindow1AndWaitButton(textState, gText_WonderNewsThrownAway);
+ case CARD_STAT_BATTLES_WON:
+ return data->cardMetadata.battlesWon;
+ case CARD_STAT_BATTLES_LOST:
+ return data->cardMetadata.battlesLost;
+ case CARD_STAT_NUM_TRADES:
+ return data->cardMetadata.numTrades;
+ case CARD_STAT_NUM_STAMPS:
+ return GetNumStampsInLinkData(data);
+ case CARD_STAT_MAX_STAMPS:
+ return data->maxStamps;
+ default:
+ AGB_ASSERT(0);
+ return 0;
}
}
-static bool32 mevent_save_game(u8 * state)
+static void IncrementCardStat(u32 statType)
{
- switch (*state)
+ struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
+ if (card->type == CARD_TYPE_LINK_STAT)
{
- case 0:
- AddTextPrinterToWindow1(gText_DataWillBeSaved);
- (*state)++;
- break;
- case 1:
- TrySavingData(SAVE_NORMAL);
- (*state)++;
- break;
- case 2:
- AddTextPrinterToWindow1(gText_SaveCompletedPressA);
- (*state)++;
- break;
- case 3:
- if (({JOY_NEW(A_BUTTON | B_BUTTON);}))
+ u16 *stat = NULL;
+ switch (statType)
{
- (*state)++;
+ case CARD_STAT_BATTLES_WON:
+ stat = &gSaveBlock1Ptr->mysteryGift.cardMetadata.battlesWon;
+ break;
+ case CARD_STAT_BATTLES_LOST:
+ stat = &gSaveBlock1Ptr->mysteryGift.cardMetadata.battlesLost;
+ break;
+ case CARD_STAT_NUM_TRADES:
+ stat = &gSaveBlock1Ptr->mysteryGift.cardMetadata.numTrades;
+ break;
+ case CARD_STAT_NUM_STAMPS: // Unused
+ case CARD_STAT_MAX_STAMPS: // Unused
+ break;
}
- break;
- case 4:
- *state = 0;
- ClearTextWindow();
- return TRUE;
- }
-
- return FALSE;
-}
-
-static const u8 * mevent_message(u32 * a0, u8 a1, u8 cardOrNews, u32 msgId)
-{
- const u8 * msg = NULL;
- *a0 = 0;
- switch (msgId)
- {
- case 0:
- *a0 = 0;
- msg = gText_NothingSentOver;
- break;
- case 1:
- *a0 = 0;
- msg = gText_RecordUploadedViaWireless;
- break;
- case 2:
- *a0 = 1;
- msg = cardOrNews == 0 ? gText_WonderCardReceived : gText_WonderCardReceivedFrom;
- break;
- case 3:
- *a0 = 1;
- msg = cardOrNews == 0 ? gText_WonderNewsReceived : gText_WonderNewsReceivedFrom;
- break;
- case 4:
- *a0 = 1;
- msg = gText_NewStampReceived;
- break;
- case 5:
- *a0 = 0;
- msg = gText_AlreadyHadCard;
- break;
- case 6:
- *a0 = 0;
- msg = gText_AlreadyHadStamp;
- break;
- case 7:
- *a0 = 0;
- msg = gText_AlreadyHadNews;
- break;
- case 8:
- *a0 = 0;
- msg = gText_NoMoreRoomForStamps;
- break;
- case 9:
- *a0 = 0;
- msg = gText_CommunicationCanceled;
- break;
- case 10:
- *a0 = 0;
- msg = a1 == 0 ? gText_CantAcceptCardFromTrainer : gText_CantAcceptNewsFromTrainer;
- break;
- case 11:
- *a0 = 0;
- msg = gText_CommunicationError;
- break;
- case 12:
- *a0 = 1;
- msg = gText_NewTrainerReceived;
- break;
- case 13:
- *a0 = 1;
- break;
- case 14:
- *a0 = 0;
- break;
+ if (stat == NULL)
+ AGB_ASSERT(0);
+ else if (++(*stat) > MAX_WONDER_CARD_STAT)
+ *stat = MAX_WONDER_CARD_STAT;
}
-
- return msg;
}
-static bool32 PrintMGSuccessMessage(u8 * state, const u8 * arg1, u16 * arg2)
+u16 MysteryGift_GetCardStat(u32 stat)
{
- switch (*state)
+ switch (stat)
{
- case 0:
- if (arg1 != NULL)
+ case CARD_STAT_BATTLES_WON:
+ {
+ struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
+ if (card->type == CARD_TYPE_LINK_STAT)
{
- AddTextPrinterToWindow1(arg1);
+ struct WonderCardMetadata *metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata;
+ return metadata->battlesWon;
}
- PlayFanfare(MUS_OBTAIN_ITEM);
- *arg2 = 0;
- (*state)++;
break;
- case 1:
- if (++(*arg2) > 0xF0)
+ }
+ case CARD_STAT_BATTLES_LOST:
+ {
+ struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
+ if (card->type == CARD_TYPE_LINK_STAT)
{
- (*state)++;
+ struct WonderCardMetadata *metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata;
+ return metadata->battlesLost;
}
break;
- case 2:
- if (IsFanfareTaskInactive())
+ }
+ case CARD_STAT_NUM_TRADES:
+ {
+ struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
+ if (card->type == CARD_TYPE_LINK_STAT)
{
- *state = 0;
- ClearTextWindow();
- return TRUE;
+ struct WonderCardMetadata *metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata;
+ return metadata->numTrades;
}
break;
}
- return FALSE;
-}
-
-static const u8 * mevent_message_stamp_card_etc_send_status(u32 * a0, u8 unused, u32 msgId)
-{
- const u8 * result = gText_CommunicationError;
- *a0 = 0;
- switch (msgId)
+ case CARD_STAT_NUM_STAMPS:
{
- case 0:
- result = gText_NothingSentOver;
- break;
- case 1:
- result = gText_RecordUploadedViaWireless;
- break;
- case 2:
- result = gText_WonderCardSentTo;
- *a0 = 1;
- break;
- case 3:
- result = gText_WonderNewsSentTo;
- *a0 = 1;
- break;
- case 4:
- result = gText_StampSentTo;
- break;
- case 5:
- result = gText_OtherTrainerHasCard;
- break;
- case 6:
- result = gText_OtherTrainerHasStamp;
- break;
- case 7:
- result = gText_OtherTrainerHasNews;
- break;
- case 8:
- result = gText_NoMoreRoomForStamps;
- break;
- case 9:
- result = gText_OtherTrainerCanceled;
- break;
- case 10:
- result = gText_CantSendGiftToTrainer;
- break;
- case 11:
- result = gText_CommunicationError;
- break;
- case 12:
- result = gText_GiftSentTo;
- break;
- case 13:
- result = gText_GiftSentTo;
- break;
- case 14:
- result = gText_CantSendGiftToTrainer;
+ struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
+ if (card->type == CARD_TYPE_STAMP)
+ return GetNumStampsInSavedCard();
break;
}
- return result;
-}
-
-static bool32 PrintMGSendStatus(u8 * state, u16 * arg1, u8 arg2, u32 msgId)
-{
- u32 flag;
- const u8 * str = mevent_message_stamp_card_etc_send_status(&flag, arg2, msgId);
- if (flag)
+ case CARD_STAT_MAX_STAMPS:
{
- return PrintMGSuccessMessage(state, str, arg1);
+ struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
+ if (card->type == CARD_TYPE_STAMP)
+ return card->maxStamps;
+ break;
}
- else
- {
- return MG_PrintTextOnWindow1AndWaitButton(state, str);
}
+
+ AGB_ASSERT(0);
+ return 0;
}
-void task_add_00_mystery_gift(void)
+void MysteryGift_DisableStats(void)
{
- u8 taskId = CreateTask(task00_mystery_gift, 0);
- struct MysteryGiftTaskData * data = (void *)gTasks[taskId].data;
- data->state = 0;
- data->textState = 0;
- data->unkA = 0;
- data->unkB = 0;
- data->IsCardOrNews = 0;
- data->source = 0;
- data->curPromptWindowId = 0;
- data->unk2 = 0;
- data->unk4 = 0;
- data->unk6 = 0;
- data->prevPromptWindowId = 0;
- data->buffer = AllocZeroed(0x40);
+ sStatsEnabled = FALSE;
}
-void task00_mystery_gift(u8 taskId)
+bool32 MysteryGift_TryEnableStatsByFlagId(u16 flagId)
{
- struct MysteryGiftTaskData *data = (void *)gTasks[taskId].data;
- u32 sp0, flag;
- const u8 *r1;
+ sStatsEnabled = FALSE;
+ if (flagId == 0)
+ return FALSE;
+
+ if (!ValidateSavedWonderCard())
+ return FALSE;
+
+ if (gSaveBlock1Ptr->mysteryGift.card.flagId != flagId)
+ return FALSE;
- switch (data->state)
+ sStatsEnabled = TRUE;
+ return TRUE;
+}
+
+void MysteryGift_TryIncrementStat(u32 stat, u32 trainerId)
+{
+ if (sStatsEnabled)
{
- case 0:
- data->state = 1;
- break;
- case 1:
- switch (MysteryGift_HandleThreeOptionMenu(&data->textState, &data->curPromptWindowId, FALSE))
+ switch (stat)
{
- case 0:
- data->IsCardOrNews = 0;
- if (ValidateReceivedWonderCard() == TRUE)
- {
- data->state = 18;
- }
- else
- {
- data->state = 2;
- }
- break;
- case 1:
- data->IsCardOrNews = 1;
- if (ValidateReceivedWonderNews() == TRUE)
- {
- data->state = 18;
- }
- else
- {
- data->state = 2;
- }
- break;
- case -2u:
- data->state = 37;
+ case CARD_STAT_NUM_TRADES:
+ IncrementCardStatForNewTrainer(CARD_STAT_NUM_TRADES,
+ trainerId,
+ gSaveBlock1Ptr->mysteryGift.trainerIds[1],
+ ARRAY_COUNT(gSaveBlock1Ptr->mysteryGift.trainerIds[1]));
break;
- }
- break;
- case 2:
- {
- if (data->IsCardOrNews == 0)
- {
- if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_DontHaveCardNewOneInput))
- {
- data->state = 3;
- PrintMysteryGiftOrEReaderTopMenu(0, 1);
- }
- }
- else
- {
- if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_DontHaveNewsNewOneInput))
- {
- data->state = 3;
- PrintMysteryGiftOrEReaderTopMenu(0, 1);
- }
- }
- break;
- }
- case 3:
- if (data->IsCardOrNews == 0)
- {
- AddTextPrinterToWindow1(gText_WhereShouldCardBeAccessed);
- }
- else
- {
- AddTextPrinterToWindow1(gText_WhereShouldNewsBeAccessed);
- }
- data->state = 4;
- break;
- case 4:
- switch (MysteryGift_HandleThreeOptionMenu(&data->textState, &data->curPromptWindowId, TRUE))
- {
- case 0:
- ClearTextWindow();
- data->state = 5;
- data->source = 0;
+ case CARD_STAT_BATTLES_WON:
+ IncrementCardStatForNewTrainer(CARD_STAT_BATTLES_WON,
+ trainerId,
+ gSaveBlock1Ptr->mysteryGift.trainerIds[0],
+ ARRAY_COUNT(gSaveBlock1Ptr->mysteryGift.trainerIds[0]));
break;
- case 1:
- ClearTextWindow();
- data->state = 5;
- data->source = 1;
+ case CARD_STAT_BATTLES_LOST:
+ IncrementCardStatForNewTrainer(CARD_STAT_BATTLES_LOST,
+ trainerId,
+ gSaveBlock1Ptr->mysteryGift.trainerIds[0],
+ ARRAY_COUNT(gSaveBlock1Ptr->mysteryGift.trainerIds[0]));
break;
- case -2u:
- ClearTextWindow();
- if (ValidateCardOrNews(data->IsCardOrNews))
- {
- data->state = 18;
- }
- else
- {
- data->state = 0;
- PrintMysteryGiftOrEReaderTopMenu(0, 0);
- }
+ default:
+ AGB_ASSERT(0);
break;
}
- break;
- case 5:
- *gStringVar1 = EOS;
- *gStringVar2 = EOS;
- *gStringVar3 = EOS;
+ }
+}
- switch (data->IsCardOrNews)
- {
- case 0:
- if (data->source == 1)
- {
- MEvent_CreateTask_CardOrNewsWithFriend(ACTIVITY_WONDER_CARD);
- }
- else if (data->source == 0)
- {
- MEvent_CreateTask_CardOrNewsOverWireless(ACTIVITY_WONDER_CARD);
- }
- break;
- case 1:
- if (data->source == 1)
- {
- MEvent_CreateTask_CardOrNewsWithFriend(ACTIVITY_WONDER_NEWS);
- }
- else if (data->source == 0)
- {
- MEvent_CreateTask_CardOrNewsOverWireless(ACTIVITY_WONDER_NEWS);
- }
- break;
- }
- data->state = 6;
- break;
- case 6:
- if (gReceivedRemoteLinkPlayers != 0)
- {
- ClearScreenInBg0(TRUE);
- data->state = 7;
- mevent_client_do_init(data->IsCardOrNews);
- }
- else if (gSpecialVar_Result == LINKUP_FAILED)
- {
- ClearScreenInBg0(TRUE);
- data->state = 3;
- }
- break;
- case 7:
- AddTextPrinterToWindow1(gText_Communicating);
- data->state = 8;
- break;
- case 8:
- switch (mevent_client_do_exec(&data->curPromptWindowId))
- {
- case 6:
- Rfu_SetCloseLinkCallback();
- data->prevPromptWindowId = data->curPromptWindowId;
- data->state = 13;
- break;
- case 5:
- memcpy(data->buffer, mevent_client_get_buffer(), 0x40);
- mevent_client_inc_flag();
- break;
- case 3:
- data->state = 10;
- break;
- case 2:
- data->state = 9;
- break;
- case 4:
- data->state = 11;
- StringCopy(gStringVar1, gLinkPlayers[0].name);
- break;
- }
- break;
- case 9:
- flag = mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, FALSE, mevent_client_get_buffer());
- switch (flag)
- {
- case 0:
- mevent_client_set_param(0);
- mevent_client_inc_flag();
- data->state = 7;
- break;
- case 1:
- mevent_client_set_param(1);
- mevent_client_inc_flag();
- data->state = 7;
- break;
- case -1u:
- mevent_client_set_param(1);
- mevent_client_inc_flag();
- data->state = 7;
- break;
- }
- break;
- case 10:
- if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, mevent_client_get_buffer()))
- {
- mevent_client_inc_flag();
- data->state = 7;
- }
- break;
- case 11:
- flag = mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, FALSE, gText_ThrowAwayWonderCard);
- switch (flag)
- {
- case 0:
- if (CheckReceivedGiftFromWonderCard() == TRUE)
- {
- data->state = 12;
- }
- else
- {
- mevent_client_set_param(0);
- mevent_client_inc_flag();
- data->state = 7;
- }
- break;
- case 1:
- mevent_client_set_param(1);
- mevent_client_inc_flag();
- data->state = 7;
- break;
- case -1u:
- mevent_client_set_param(1);
- mevent_client_inc_flag();
- data->state = 7;
- break;
- }
- break;
- case 12:
- flag = mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, FALSE, gText_HaventReceivedCardsGift);
- switch (flag)
- {
- case 0:
- mevent_client_set_param(0);
- mevent_client_inc_flag();
- data->state = 7;
- break;
- case 1:
- mevent_client_set_param(1);
- mevent_client_inc_flag();
- data->state = 7;
- break;
- case -1u:
- mevent_client_set_param(1);
- mevent_client_inc_flag();
- data->state = 7;
- break;
- }
- break;
- case 13:
- if (gReceivedRemoteLinkPlayers == 0)
- {
- DestroyWirelessStatusIndicatorSprite();
- data->state = 14;
- }
- break;
- case 14:
- if (PrintStringAndWait2Seconds(&data->textState, gText_CommunicationCompleted))
- {
- if (data->source == 1)
- {
- StringCopy(gStringVar1, gLinkPlayers[0].name);
- }
- data->state = 15;
- }
- break;
- case 15:
- r1 = mevent_message(&sp0, data->IsCardOrNews, data->source, data->prevPromptWindowId);
- if (r1 == NULL)
- {
- r1 = data->buffer;
- }
- if (sp0)
- {
- flag = PrintMGSuccessMessage(&data->textState, r1, &data->curPromptWindowId);
- }
- else
- {
- flag = MG_PrintTextOnWindow1AndWaitButton(&data->textState, r1);
- }
- if (flag)
- {
- if (data->prevPromptWindowId == 3)
- {
- if (data->source == 1)
- {
- GenerateRandomNews(1);
- }
- else
- {
- GenerateRandomNews(2);
- }
- }
- if (!sp0)
- {
- data->state = 0;
- PrintMysteryGiftOrEReaderTopMenu(0, 0);
- }
- else
- {
- data->state = 17;
- }
- }
- break;
- case 16:
- if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_CommunicationError))
- {
- data->state = 0;
- PrintMysteryGiftOrEReaderTopMenu(0, 0);
- }
- break;
- case 17:
- if (mevent_save_game(&data->textState))
- {
- data->state = 18;
- }
- break;
- case 18:
- if (HandleLoadWonderCardOrNews(&data->textState, data->IsCardOrNews))
- {
- data->state = 20;
- }
- break;
- case 20:
- if (data->IsCardOrNews == 0)
- {
- if (({JOY_NEW(A_BUTTON);}))
- {
- data->state = 21;
- }
- if (({JOY_NEW(B_BUTTON);}))
- {
- data->state = 27;
- }
- }
- else
- {
- switch (MENews_GetInput(gMain.newKeys))
- {
- case 0:
- MENews_RemoveScrollIndicatorArrowPair();
- data->state = 21;
- break;
- case 1:
- data->state = 27;
- break;
- }
- }
- break;
- case 21:
+static void ClearSavedTrainerIds(void)
+{
+ CpuFill32(0, gSaveBlock1Ptr->mysteryGift.trainerIds, sizeof(gSaveBlock1Ptr->mysteryGift.trainerIds));
+}
+
+// Returns TRUE if it's a new trainer id, FALSE if an existing one.
+// In either case the given trainerId is saved in element 0
+static bool32 RecordTrainerId(u32 trainerId, u32 *trainerIds, int size)
+{
+ int i, j;
+
+ for (i = 0; i < size; i++)
{
- u32 result;
- if (data->IsCardOrNews == 0)
- {
- if (WonderCard_Test_Unk_08_6())
- {
- result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->IsCardOrNews, FALSE);
- }
- else
- {
- result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->IsCardOrNews, TRUE);
- }
- }
- else
- {
- if (WonderNews_Test_Unk_02())
- {
- result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->IsCardOrNews, FALSE);
- }
- else
- {
- result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->IsCardOrNews, TRUE);
- }
- }
- switch (result)
- {
- case 0:
- data->state = 28;
- break;
- case 1:
- data->state = 29;
+ if (trainerIds[i] == trainerId)
break;
- case 2:
- data->state = 22;
- break;
- case -2u:
- if (data->IsCardOrNews == 1)
- {
- MENews_AddScrollIndicatorArrowPair();
- }
- data->state = 20;
- break;
- }
- break;
}
- case 22:
- switch (mevent_message_prompt_discard(&data->textState, &data->curPromptWindowId, data->IsCardOrNews))
- {
- case 0:
- if (data->IsCardOrNews == 0 && CheckReceivedGiftFromWonderCard() == TRUE)
- {
- data->state = 23;
- }
- else
- {
- data->state = 24;
- }
- break;
- case 1:
- data->state = 21;
- break;
- case -1:
- data->state = 21;
- break;
- }
- break;
- case 23:
- switch ((u32)mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, TRUE, gText_HaventReceivedGiftOkayToDiscard))
- {
- case 0:
- data->state = 24;
- break;
- case 1:
- data->state = 21;
- break;
- case -1u:
- data->state = 21;
- break;
- }
- break;
- case 24:
- if (TearDownCardOrNews_ReturnToTopMenu(data->IsCardOrNews, 1))
- {
- DestroyNewsOrCard(data->IsCardOrNews);
- data->state = 25;
- }
- break;
- case 25:
- if (mevent_save_game(&data->textState))
- {
- data->state = 26;
- }
- break;
- case 26:
- if (mevent_message_was_thrown_away(&data->textState, data->IsCardOrNews))
- {
- data->state = 0;
- PrintMysteryGiftOrEReaderTopMenu(0, 0);
- }
- break;
- case 27:
- if (TearDownCardOrNews_ReturnToTopMenu(data->IsCardOrNews, 0))
- {
- data->state = 0;
- }
- break;
- case 28:
- if (TearDownCardOrNews_ReturnToTopMenu(data->IsCardOrNews, 1))
- {
- data->state = 3;
- }
- break;
- case 29:
- if (TearDownCardOrNews_ReturnToTopMenu(data->IsCardOrNews, 1))
- {
- switch (data->IsCardOrNews)
- {
- case 0:
- MEvent_CreateTask_Leader(ACTIVITY_WONDER_CARD);
- break;
- case 1:
- MEvent_CreateTask_Leader(ACTIVITY_WONDER_NEWS);
- break;
- }
- data->source = 1;
- data->state = 30;
- }
- break;
- case 30:
- if (gReceivedRemoteLinkPlayers != 0)
- {
- ClearScreenInBg0(1);
- data->state = 31;
- }
- else if (gSpecialVar_Result == LINKUP_FAILED)
- {
- ClearScreenInBg0(1);
- data->state = 18;
- }
- break;
- case 31:
- *gStringVar1 = EOS;
- *gStringVar2 = EOS;
- *gStringVar3 = EOS;
- if (data->IsCardOrNews == 0)
- {
- AddTextPrinterToWindow1(gText_SendingWonderCard);
- mevent_srv_new_wcard();
- }
- else
- {
- AddTextPrinterToWindow1(gText_SendingWonderNews);
- mevent_srv_init_wnews();
- }
- data->state = 32;
- break;
- case 32:
- if (mevent_srv_common_do_exec(&data->curPromptWindowId) == 3)
- {
- data->prevPromptWindowId = data->curPromptWindowId;
- data->state = 33;
- }
- break;
- case 33:
- Rfu_SetCloseLinkCallback();
- StringCopy(gStringVar1, gLinkPlayers[1].name);
- data->state = 34;
- break;
- case 34:
- if (gReceivedRemoteLinkPlayers == 0)
- {
- DestroyWirelessStatusIndicatorSprite();
- data->state = 35;
- }
- break;
- case 35:
- if (PrintMGSendStatus(&data->textState, &data->curPromptWindowId, data->source, data->prevPromptWindowId))
- {
- if (data->source == 1 && data->prevPromptWindowId == 3)
- {
- GenerateRandomNews(3);
- data->state = 17;
- }
- else
- {
- data->state = 0;
- PrintMysteryGiftOrEReaderTopMenu(0, 0);
- }
- }
- break;
- case 36:
- if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_CommunicationError))
- {
- data->state = 0;
- PrintMysteryGiftOrEReaderTopMenu(0, 0);
- }
- break;
- case 37:
- CloseLink();
- Free(data->buffer);
- DestroyTask(taskId);
- SetMainCallback2(MainCB_FreeAllBuffersAndReturnToInitTitleScreen);
- break;
+ if (i == size)
+ {
+ // New trainer, shift array and insert new id at front
+ for (j = size - 1; j > 0; j--)
+ trainerIds[j] = trainerIds[j - 1];
+
+ trainerIds[0] = trainerId;
+ return TRUE;
}
-}
+ else
+ {
+ // Existing trainer, shift back to old slot and move id to front
+ for (j = i; j > 0; j--)
+ trainerIds[j] = trainerIds[j - 1];
-u16 GetMysteryGiftBaseBlock(void)
-{
- return 0x1A9;
+ trainerIds[0] = trainerId;
+ return FALSE;
+ }
}
-void bgid_upload_textbox_1(u8 bgId)
+static void IncrementCardStatForNewTrainer(u32 stat, u32 trainerId, u32 *trainerIds, int size)
{
- DecompressAndLoadBgGfxUsingHeap(bgId, gUnkTextboxBorderGfx, 0x100, 0, 0);
+ if (RecordTrainerId(trainerId, trainerIds, size))
+ IncrementCardStat(stat);
}