summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGriffinR <griffin.g.richards@gmail.com>2021-10-17 03:00:48 -0400
committerGriffinR <griffin.g.richards@gmail.com>2021-10-17 03:00:48 -0400
commitece7ef3410eb9b114cf328426c4fc16c972f71c6 (patch)
tree1a6b3b96d60ccb13e4695e4c8ad1f9b56e9a3971 /src
parentd0455485c3ea862d4089b2b4bb02bb00f3005599 (diff)
Correct usage of MysteryEvent to MysteryGift
Diffstat (limited to 'src')
-rw-r--r--src/cable_club.c2
-rw-r--r--src/easy_chat.c2
-rwxr-xr-xsrc/ereader_screen.c2
-rw-r--r--src/field_specials.c4
-rw-r--r--src/link_rfu_2.c2
-rw-r--r--src/main_menu.c2
-rwxr-xr-xsrc/mevent2.c662
-rw-r--r--src/mystery_event_msg.c22
-rw-r--r--src/mystery_event_script.c24
-rwxr-xr-x[-rw-r--r--]src/mystery_gift.c1924
-rw-r--r--src/mystery_gift_client.c (renamed from src/mevent_client.c)24
-rw-r--r--src/mystery_gift_link.c (renamed from src/mevent_server_helpers.c)4
-rw-r--r--src/mystery_gift_menu.c1618
-rw-r--r--src/mystery_gift_scripts.c (renamed from src/mevent_scripts.c)6
-rw-r--r--src/mystery_gift_server.c (renamed from src/mevent_server.c)6
-rw-r--r--src/mystery_gift_view.c (renamed from src/wonder_transfer.c)6
-rw-r--r--src/new_game.c2
-rw-r--r--src/script.c2
-rw-r--r--src/trade.c2
-rw-r--r--src/union_room.c2
-rw-r--r--src/wonder_news.c (renamed from src/mevent_news.c)4
21 files changed, 2161 insertions, 2161 deletions
diff --git a/src/cable_club.c b/src/cable_club.c
index 69fcb660b..3083ed9c0 100644
--- a/src/cable_club.c
+++ b/src/cable_club.c
@@ -18,7 +18,7 @@
#include "overworld.h"
#include "palette.h"
#include "union_room.h"
-#include "mevent.h"
+#include "mystery_gift.h"
#include "script.h"
#include "script_pokemon_util.h"
#include "sound.h"
diff --git a/src/easy_chat.c b/src/easy_chat.c
index 79300bd52..b18d09b83 100644
--- a/src/easy_chat.c
+++ b/src/easy_chat.c
@@ -15,7 +15,7 @@
#include "graphics.h"
#include "international_string_util.h"
#include "main.h"
-#include "mevent.h"
+#include "mystery_gift.h"
#include "menu.h"
#include "overworld.h"
#include "palette.h"
diff --git a/src/ereader_screen.c b/src/ereader_screen.c
index a76fb09c8..73a1b870e 100755
--- a/src/ereader_screen.c
+++ b/src/ereader_screen.c
@@ -4,7 +4,7 @@
#include "ereader_helpers.h"
#include "link.h"
#include "main.h"
-#include "mystery_gift.h"
+#include "mystery_gift_menu.h"
#include "save.h"
#include "sound.h"
#include "sprite.h"
diff --git a/src/field_specials.c b/src/field_specials.c
index 5d7829d12..2789411a5 100644
--- a/src/field_specials.c
+++ b/src/field_specials.c
@@ -22,7 +22,7 @@
#include "link.h"
#include "list_menu.h"
#include "main.h"
-#include "mevent.h"
+#include "mystery_gift.h"
#include "match_call.h"
#include "menu.h"
#include "overworld.h"
@@ -56,7 +56,7 @@
#include "constants/heal_locations.h"
#include "constants/map_types.h"
#include "constants/maps.h"
-#include "constants/mevent.h"
+#include "constants/mystery_gift.h"
#include "constants/script_menu.h"
#include "constants/slot_machine.h"
#include "constants/songs.h"
diff --git a/src/link_rfu_2.c b/src/link_rfu_2.c
index 0ab452a8d..87e9f8e9d 100644
--- a/src/link_rfu_2.c
+++ b/src/link_rfu_2.c
@@ -16,7 +16,7 @@
#include "task.h"
#include "text.h"
#include "save.h"
-#include "mystery_gift.h"
+#include "mystery_gift_menu.h"
enum {
RFUSTATE_INIT,
diff --git a/src/main_menu.c b/src/main_menu.c
index 8fd25abe1..b245a1666 100644
--- a/src/main_menu.c
+++ b/src/main_menu.c
@@ -35,7 +35,7 @@
#include "text_window.h"
#include "title_screen.h"
#include "window.h"
-#include "mystery_gift.h"
+#include "mystery_gift_menu.h"
/*
* Main menu state machine
diff --git a/src/mevent2.c b/src/mevent2.c
deleted file mode 100755
index ce41a0fcd..000000000
--- a/src/mevent2.c
+++ /dev/null
@@ -1,662 +0,0 @@
-#include "global.h"
-#include "util.h"
-#include "main.h"
-#include "event_data.h"
-#include "easy_chat.h"
-#include "script.h"
-#include "battle_tower.h"
-#include "mevent_news.h"
-#include "string_util.h"
-#include "new_game.h"
-#include "mevent.h"
-#include "constants/mevent.h"
-
-static EWRAM_DATA bool32 sStatsEnabled = 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);
-
-#define CALC_CRC(data) CalcCRC16WithTable((void *)&(data), sizeof(data))
-
-void ClearMysteryGift(void)
-{
- CpuFill32(0, &gSaveBlock1Ptr->mysteryGift, sizeof(gSaveBlock1Ptr->mysteryGift));
- ClearSavedWonderNewsMetadata(); // Clear is redundant, InitSavedWonderNews would be sufficient
- InitQuestionnaireWords();
-}
-
-struct WonderNews *GetSavedWonderNews(void)
-{
- return &gSaveBlock1Ptr->mysteryGift.news;
-}
-
-struct WonderCard *GetSavedWonderCard(void)
-{
- return &gSaveBlock1Ptr->mysteryGift.card;
-}
-
-struct WonderCardMetadata *GetSavedWonderCardMetadata(void)
-{
- return &gSaveBlock1Ptr->mysteryGift.cardMetadata;
-}
-
-struct WonderNewsMetadata *GetSavedWonderNewsMetadata(void)
-{
- return &gSaveBlock1Ptr->mysteryGift.newsMetadata;
-}
-
-u16 *GetQuestionnaireWordsPtr(void)
-{
- return gSaveBlock1Ptr->mysteryGift.questionnaireWords;
-}
-
-// Equivalent to ClearSavedWonderCardAndRelated, but nothing else to clear
-void ClearSavedWonderNewsAndRelated(void)
-{
- ClearSavedWonderNews();
-}
-
-bool32 SaveWonderNews(const struct WonderNews *news)
-{
- if (!ValidateWonderNews(news))
- return FALSE;
-
- ClearSavedWonderNews();
- gSaveBlock1Ptr->mysteryGift.news = *news;
- gSaveBlock1Ptr->mysteryGift.newsCrc = CALC_CRC(gSaveBlock1Ptr->mysteryGift.news);
- return TRUE;
-}
-
-bool32 ValidateSavedWonderNews(void)
-{
- if (CALC_CRC(gSaveBlock1Ptr->mysteryGift.news) != gSaveBlock1Ptr->mysteryGift.newsCrc)
- return FALSE;
- if (!ValidateWonderNews(&gSaveBlock1Ptr->mysteryGift.news))
- return FALSE;
-
- return TRUE;
-}
-
-static bool32 ValidateWonderNews(const struct WonderNews *news)
-{
- if (news->id == 0)
- return FALSE;
-
- return TRUE;
-}
-
-bool32 IsSendingSavedWonderNewsAllowed(void)
-{
- const struct WonderNews *news = &gSaveBlock1Ptr->mysteryGift.news;
- if (news->sendType == SEND_TYPE_DISALLOWED)
- return FALSE;
-
- return TRUE;
-}
-
-static void ClearSavedWonderNews(void)
-{
- CpuFill32(0, GetSavedWonderNews(), sizeof(gSaveBlock1Ptr->mysteryGift.news));
- gSaveBlock1Ptr->mysteryGift.newsCrc = 0;
-}
-
-static void ClearSavedWonderNewsMetadata(void)
-{
- CpuFill32(0, GetSavedWonderNewsMetadata(), sizeof(gSaveBlock1Ptr->mysteryGift.newsMetadata));
- InitSavedWonderNews();
-}
-
-bool32 IsWonderNewsSameAsSaved(const u8 *news)
-{
- const u8 *savedNews = (const u8 *)&gSaveBlock1Ptr->mysteryGift.news;
- u32 i;
- if (!ValidateSavedWonderNews())
- return FALSE;
-
- for (i = 0; i < sizeof(gSaveBlock1Ptr->mysteryGift.news); i++)
- {
- if (savedNews[i] != news[i])
- return FALSE;
- }
-
- return TRUE;
-}
-
-void ClearSavedWonderCardAndRelated(void)
-{
- ClearSavedWonderCard();
- ClearSavedWonderCardMetadata();
- ClearSavedTrainerIds();
- ClearRamScript();
- ClearMysteryGiftFlags();
- ClearMysteryGiftVars();
- ClearEReaderTrainer(&gSaveBlock2Ptr->frontier.ereaderTrainer);
-}
-
-bool32 SaveWonderCard(const struct WonderCard *card)
-{
- struct WonderCardMetadata *metadata;
- if (!ValidateWonderCard(card))
- return FALSE;
-
- 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;
-}
-
-bool32 ValidateSavedWonderCard(void)
-{
- if (gSaveBlock1Ptr->mysteryGift.cardCrc != CALC_CRC(gSaveBlock1Ptr->mysteryGift.card))
- return FALSE;
- if (!ValidateWonderCard(&gSaveBlock1Ptr->mysteryGift.card))
- return FALSE;
- if (!ValidateSavedRamScript())
- return FALSE;
-
- return TRUE;
-}
-
-static bool32 ValidateWonderCard(const struct WonderCard *card)
-{
- 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;
-}
-
-bool32 IsSendingSavedWonderCardAllowed(void)
-{
- const struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
- if (card->sendType == SEND_TYPE_DISALLOWED)
- return FALSE;
-
- return TRUE;
-}
-
-static void ClearSavedWonderCard(void)
-{
- CpuFill32(0, &gSaveBlock1Ptr->mysteryGift.card, sizeof(gSaveBlock1Ptr->mysteryGift.card));
- gSaveBlock1Ptr->mysteryGift.cardCrc = 0;
-}
-
-static void ClearSavedWonderCardMetadata(void)
-{
- CpuFill32(0, GetSavedWonderCardMetadata(), sizeof(gSaveBlock1Ptr->mysteryGift.cardMetadata));
- gSaveBlock1Ptr->mysteryGift.cardMetadataCrc = 0;
-}
-
-u16 GetWonderCardFlagID(void)
-{
- if (ValidateSavedWonderCard())
- return gSaveBlock1Ptr->mysteryGift.card.flagId;
-
- return 0;
-}
-
-void DisableWonderCardSending(struct WonderCard *card)
-{
- if (card->sendType == SEND_TYPE_ALLOWED)
- card->sendType = SEND_TYPE_DISALLOWED;
-}
-
-static bool32 IsWonderCardFlagIDInValidRange(u16 flagId)
-{
- if (flagId >= WONDER_CARD_FLAG_OFFSET && flagId < WONDER_CARD_FLAG_OFFSET + NUM_WONDER_CARD_FLAGS)
- return TRUE;
-
- return FALSE;
-}
-
-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)
-{
- 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 int GetNumStampsInMetadata(const struct WonderCardMetadata *data, int size)
-{
- 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;
-}
-
-static bool32 IsStampInMetadata(const struct WonderCardMetadata *metadata, const u16 *stamp, int maxStamps)
-{
- int i;
- for (i = 0; i < maxStamps; i++)
- {
- 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 ValidateStamp(const u16 *stamp)
-{
- 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 int GetNumStampsInSavedCard(void)
-{
- struct WonderCard *card;
- if (!ValidateSavedWonderCard())
- return 0;
-
- card = &gSaveBlock1Ptr->mysteryGift.card;
- if (card->type != CARD_TYPE_STAMP)
- return 0;
-
- return GetNumStampsInMetadata(&gSaveBlock1Ptr->mysteryGift.cardMetadata, card->maxStamps);
-}
-
-bool32 MysteryGift_TrySaveStamp(const u16 *stamp)
-{
- 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;
-
- for (i = 0; i < maxStamps; i++)
- {
- if (gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[STAMP_ID][i] == 0
- && gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[STAMP_SPECIES][i] == SPECIES_NONE)
- {
- gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[STAMP_ID][i] = stamp[STAMP_ID];
- gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[STAMP_SPECIES][i] = stamp[STAMP_SPECIES];
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-#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)
-{
- int i;
- CpuFill32(0, data, sizeof(*data));
- data->validationVar = GAME_DATA_VALID_VAR;
- data->validationFlag1 = 1;
- data->validationFlag2 = 1;
-
- if (isWonderNews)
- {
- // 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;
- }
-
- if (ValidateSavedWonderCard())
- {
- data->flagId = GetSavedWonderCard()->flagId;
- data->cardMetadata = *GetSavedWonderCardMetadata();
- data->maxStamps = GetSavedWonderCard()->maxStamps;
- }
- else
- {
- 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;
-}
-
-bool32 MysteryGift_ValidateLinkGameData(const struct MysteryGiftLinkGameData *data, bool32 isWonderNews)
-{
- if (data->validationVar != GAME_DATA_VALID_VAR)
- return FALSE;
-
- if (!(data->validationFlag1 & 1))
- return FALSE;
-
- if (!(data->validationFlag2 & 1))
- return FALSE;
-
- if (!isWonderNews)
- {
- if (!(data->validationGiftType1 & GAME_DATA_VALID_GIFT_TYPE_1))
- return FALSE;
-
- if (!(data->validationGiftType2 & (GAME_DATA_VALID_GIFT_TYPE_2 | 0x180)))
- return FALSE;
- }
-
- return TRUE;
-}
-
-u32 MysteryGift_CompareCardFlags(const u16 *flagId, const struct MysteryGiftLinkGameData *data, const void *unused)
-{
- // 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;
-}
-
-// 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)
-{
- 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 (data->questionnaireWords[i] != words[i])
- return FALSE;
- }
-
- return TRUE;
-}
-
-static int GetNumStampsInLinkData(const struct MysteryGiftLinkGameData *data)
-{
- return GetNumStampsInMetadata(&data->cardMetadata, data->maxStamps);
-}
-
-u16 MysteryGift_GetCardStatFromLinkData(const struct MysteryGiftLinkGameData *data, u32 stat)
-{
- switch (stat)
- {
- 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 void IncrementCardStat(u32 statType)
-{
- struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
- if (card->type == CARD_TYPE_LINK_STAT)
- {
- u16 *stat = NULL;
- switch (statType)
- {
- 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;
- }
-
- if (stat == NULL)
- AGB_ASSERT(0);
- else if (++(*stat) > MAX_WONDER_CARD_STAT)
- *stat = MAX_WONDER_CARD_STAT;
- }
-}
-
-u16 MysteryGift_GetCardStat(u32 stat)
-{
- switch (stat)
- {
- case CARD_STAT_BATTLES_WON:
- {
- struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
- if (card->type == CARD_TYPE_LINK_STAT)
- {
- struct WonderCardMetadata *metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata;
- return metadata->battlesWon;
- }
- break;
- }
- case CARD_STAT_BATTLES_LOST:
- {
- struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
- if (card->type == CARD_TYPE_LINK_STAT)
- {
- struct WonderCardMetadata *metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata;
- return metadata->battlesLost;
- }
- break;
- }
- case CARD_STAT_NUM_TRADES:
- {
- struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
- if (card->type == CARD_TYPE_LINK_STAT)
- {
- struct WonderCardMetadata *metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata;
- return metadata->numTrades;
- }
- break;
- }
- case CARD_STAT_NUM_STAMPS:
- {
- struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
- if (card->type == CARD_TYPE_STAMP)
- return GetNumStampsInSavedCard();
- break;
- }
- case CARD_STAT_MAX_STAMPS:
- {
- struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
- if (card->type == CARD_TYPE_STAMP)
- return card->maxStamps;
- break;
- }
- }
-
- AGB_ASSERT(0);
- return 0;
-}
-
-void MysteryGift_DisableStats(void)
-{
- sStatsEnabled = FALSE;
-}
-
-bool32 MysteryGift_TryEnableStatsByFlagId(u16 flagId)
-{
- sStatsEnabled = FALSE;
- if (flagId == 0)
- return FALSE;
-
- if (!ValidateSavedWonderCard())
- return FALSE;
-
- if (gSaveBlock1Ptr->mysteryGift.card.flagId != flagId)
- return FALSE;
-
- sStatsEnabled = TRUE;
- return TRUE;
-}
-
-void MysteryGift_TryIncrementStat(u32 stat, u32 trainerId)
-{
- if (sStatsEnabled)
- {
- switch (stat)
- {
- case CARD_STAT_NUM_TRADES:
- IncrementCardStatForNewTrainer(CARD_STAT_NUM_TRADES,
- trainerId,
- gSaveBlock1Ptr->mysteryGift.trainerIds[1],
- ARRAY_COUNT(gSaveBlock1Ptr->mysteryGift.trainerIds[1]));
- break;
- case CARD_STAT_BATTLES_WON:
- IncrementCardStatForNewTrainer(CARD_STAT_BATTLES_WON,
- trainerId,
- gSaveBlock1Ptr->mysteryGift.trainerIds[0],
- ARRAY_COUNT(gSaveBlock1Ptr->mysteryGift.trainerIds[0]));
- break;
- case CARD_STAT_BATTLES_LOST:
- IncrementCardStatForNewTrainer(CARD_STAT_BATTLES_LOST,
- trainerId,
- gSaveBlock1Ptr->mysteryGift.trainerIds[0],
- ARRAY_COUNT(gSaveBlock1Ptr->mysteryGift.trainerIds[0]));
- break;
- default:
- AGB_ASSERT(0);
- break;
- }
- }
-}
-
-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++)
- {
- if (trainerIds[i] == trainerId)
- 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];
-
- trainerIds[0] = trainerId;
- return FALSE;
- }
-}
-
-static void IncrementCardStatForNewTrainer(u32 stat, u32 trainerId, u32 *trainerIds, int size)
-{
- if (RecordTrainerId(trainerId, trainerIds, size))
- IncrementCardStat(stat);
-}
diff --git a/src/mystery_event_msg.c b/src/mystery_event_msg.c
index e0e70a218..51141bb77 100644
--- a/src/mystery_event_msg.c
+++ b/src/mystery_event_msg.c
@@ -1,13 +1,13 @@
#include "global.h"
-const u8 gText_MysteryGiftBerry[] = _("Obtained a {STR_VAR_2} BERRY!\nDad has it at PETALBURG GYM.");
-const u8 gText_MysteryGiftBerryTransform[] = _("The {STR_VAR_1} BERRY transformed into\none {STR_VAR_2} BERRY.");
-const u8 gText_MysteryGiftBerryObtained[] = _("The {STR_VAR_1} BERRY has already been\nobtained.");
-const u8 gText_MysteryGiftSpecialRibbon[] = _("A special RIBBON was awarded to\nyour party POKéMON.");
-const u8 gText_MysteryGiftNationalDex[] = _("The POKéDEX has been upgraded\nwith the NATIONAL MODE.");
-const u8 gText_MysteryGiftRareWord[] = _("A rare word has been added.");
-const u8 gText_MysteryGiftSentOver[] = _("{STR_VAR_1} was sent over!");
-const u8 gText_MysteryGiftFullParty[] = _("Your party is full.\n{STR_VAR_1} could not be sent over.");
-const u8 gText_MysteryGiftNewTrainer[] = _("A new TRAINER has arrived in\nHOENN.");
-const u8 gText_MysteryGiftNewAdversaryInBattleTower[] = _("A new adversary has arrived in the\nBATTLE TOWER.");
-const u8 gText_MysteryGiftCantBeUsed[] = _("This data can't be used in\nthis version.");
+const u8 gText_MysteryEventBerry[] = _("Obtained a {STR_VAR_2} BERRY!\nDad has it at PETALBURG GYM.");
+const u8 gText_MysteryEventBerryTransform[] = _("The {STR_VAR_1} BERRY transformed into\none {STR_VAR_2} BERRY.");
+const u8 gText_MysteryEventBerryObtained[] = _("The {STR_VAR_1} BERRY has already been\nobtained.");
+const u8 gText_MysteryEventSpecialRibbon[] = _("A special RIBBON was awarded to\nyour party POKéMON.");
+const u8 gText_MysteryEventNationalDex[] = _("The POKéDEX has been upgraded\nwith the NATIONAL MODE.");
+const u8 gText_MysteryEventRareWord[] = _("A rare word has been added.");
+const u8 gText_MysteryEventSentOver[] = _("{STR_VAR_1} was sent over!");
+const u8 gText_MysteryEventFullParty[] = _("Your party is full.\n{STR_VAR_1} could not be sent over.");
+const u8 gText_MysteryEventNewTrainer[] = _("A new TRAINER has arrived in\nHOENN.");
+const u8 gText_MysteryEventNewAdversaryInBattleTower[] = _("A new adversary has arrived in the\nBATTLE TOWER.");
+const u8 gText_MysteryEventCantBeUsed[] = _("This data can't be used in\nthis version.");
diff --git a/src/mystery_event_script.c b/src/mystery_event_script.c
index 7b5e8ebe5..f80240006 100644
--- a/src/mystery_event_script.c
+++ b/src/mystery_event_script.c
@@ -43,7 +43,7 @@ static bool32 CheckCompatibility(u16 a1, u32 a2, u16 a3, u32 a4)
static void SetIncompatible(void)
{
- StringExpandPlaceholders(gStringVar4, gText_MysteryGiftCantBeUsed);
+ StringExpandPlaceholders(gStringVar4, gText_MysteryEventCantBeUsed);
SetMysteryEventScriptStatus(3);
}
@@ -65,12 +65,12 @@ static bool32 RunMysteryEventScriptCommand(struct ScriptContext *ctx)
return FALSE;
}
-void InitMysteryGiftScriptContext(u8 *script)
+void InitMysteryEventScriptContext(u8 *script)
{
InitMysteryEventScript(&sMysteryEventScriptContext, script);
}
-bool32 RunMysteryGiftScriptContextCommand(u32 *script)
+bool32 RunMysteryEventScriptContextCommand(u32 *script)
{
bool32 ret = RunMysteryEventScriptCommand(&sMysteryEventScriptContext);
*script = sMysteryEventScriptContext.data[2];
@@ -229,17 +229,17 @@ bool8 MEScrCmd_setenigmaberry(struct ScriptContext *ctx)
if (!haveBerry)
{
str = gStringVar4;
- message = gText_MysteryGiftBerry;
+ message = gText_MysteryEventBerry;
}
else if (StringCompare(gStringVar1, gStringVar2))
{
str = gStringVar4;
- message = gText_MysteryGiftBerryTransform;
+ message = gText_MysteryEventBerryTransform;
}
else
{
str = gStringVar4;
- message = gText_MysteryGiftBerryObtained;
+ message = gText_MysteryEventBerryObtained;
}
StringExpandPlaceholders(str, message);
@@ -259,7 +259,7 @@ bool8 MEScrCmd_giveribbon(struct ScriptContext *ctx)
u8 index = ScriptReadByte(ctx);
u8 ribbonId = ScriptReadByte(ctx);
GiveGiftRibbonToParty(index, ribbonId);
- StringExpandPlaceholders(gStringVar4, gText_MysteryGiftSpecialRibbon);
+ StringExpandPlaceholders(gStringVar4, gText_MysteryEventSpecialRibbon);
ctx->data[2] = 2;
return FALSE;
}
@@ -278,7 +278,7 @@ bool8 MEScrCmd_initramscript(struct ScriptContext *ctx)
bool8 MEScrCmd_givenationaldex(struct ScriptContext *ctx)
{
EnableNationalPokedex();
- StringExpandPlaceholders(gStringVar4, gText_MysteryGiftNationalDex);
+ StringExpandPlaceholders(gStringVar4, gText_MysteryEventNationalDex);
ctx->data[2] = 2;
return FALSE;
}
@@ -286,7 +286,7 @@ bool8 MEScrCmd_givenationaldex(struct ScriptContext *ctx)
bool8 MEScrCmd_addrareword(struct ScriptContext *ctx)
{
UnlockAdditionalPhrase(ScriptReadByte(ctx));
- StringExpandPlaceholders(gStringVar4, gText_MysteryGiftRareWord);
+ StringExpandPlaceholders(gStringVar4, gText_MysteryEventRareWord);
ctx->data[2] = 2;
return FALSE;
}
@@ -320,7 +320,7 @@ bool8 MEScrCmd_givepokemon(struct ScriptContext *ctx)
if (gPlayerPartyCount == PARTY_SIZE)
{
- StringExpandPlaceholders(gStringVar4, gText_MysteryGiftFullParty);
+ StringExpandPlaceholders(gStringVar4, gText_MysteryEventFullParty);
ctx->data[2] = 3;
}
else
@@ -340,7 +340,7 @@ bool8 MEScrCmd_givepokemon(struct ScriptContext *ctx)
GiveMailToMon2(&gPlayerParty[PARTY_SIZE - 1], &mail);
CompactPartySlots();
CalculatePlayerPartyCount();
- StringExpandPlaceholders(gStringVar4, gText_MysteryGiftSentOver);
+ StringExpandPlaceholders(gStringVar4, gText_MysteryEventSentOver);
ctx->data[2] = 2;
}
@@ -352,7 +352,7 @@ bool8 MEScrCmd_addtrainer(struct ScriptContext *ctx)
u32 data = ScriptReadWord(ctx) - ctx->data[1] + ctx->data[0];
memcpy(&gSaveBlock2Ptr->frontier.ereaderTrainer, (void *)data, sizeof(gSaveBlock2Ptr->frontier.ereaderTrainer));
ValidateEReaderTrainer();
- StringExpandPlaceholders(gStringVar4, gText_MysteryGiftNewTrainer);
+ StringExpandPlaceholders(gStringVar4, gText_MysteryEventNewTrainer);
ctx->data[2] = 2;
return FALSE;
}
diff --git a/src/mystery_gift.c b/src/mystery_gift.c
index bc6e8c44b..1df6533d9 100644..100755
--- a/src/mystery_gift.c
+++ b/src/mystery_gift.c
@@ -1,1618 +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 "wonder_transfer.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"
-
-#define LIST_MENU_TILE_NUM 10
-#define LIST_MENU_PAL_NUM 224
+#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"
-static void LoadMysteryGiftTextboxBorder(u8 bgId);
-static void CreateMysteryGiftTask(void);
-static void Task_MysteryGift(u8 taskId);
+static EWRAM_DATA bool32 sStatsEnabled = FALSE;
-EWRAM_DATA static 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 sTextboxBorder_Pal[] = INCBIN_U16("graphics/interface/mystery_gift_textbox_border.gbapal");
-static const u32 sTextboxBorder_Gfx[] = INCBIN_U32("graphics/interface/mystery_gift_textbox_border.4bpp.lz");
+#define CALC_CRC(data) CalcCRC16WithTable((void *)&(data), sizeof(data))
-struct MysteryGiftTaskData
+void ClearMysteryGift(void)
{
- u16 var; // Multipurpose
- u16 unused1;
- u16 unused2;
- u16 unused3;
- u8 state;
- u8 textState;
- u8 unused4;
- u8 unused5;
- bool8 isWonderNews;
- bool8 sourceIsFriend;
- u8 msgId;
- u8 * clientMsg;
-};
-
-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 = 0,
- .tilemapLeft = 0,
- .tilemapTop = 0,
- .width = 30,
- .height = 2,
- .paletteNum = 12,
- .baseBlock = 0x0013
- }, {
- .bg = 0,
- .tilemapLeft = 1,
- .tilemapTop = 15,
- .width = 28,
- .height = 4,
- .paletteNum = 12,
- .baseBlock = 0x004f
- }, {
- .bg = 0,
- .tilemapLeft = 0,
- .tilemapTop = 15,
- .width = 30,
- .height = 5,
- .paletteNum = 13,
- .baseBlock = 0x004f
- },
- DUMMY_WIN_TEMPLATE
-};
-
-static const struct WindowTemplate sWindowTemplate_YesNoMsg_Wide = {
- .bg = 0,
- .tilemapLeft = 1,
- .tilemapTop = 15,
- .width = 28,
- .height = 4,
- .paletteNum = 12,
- .baseBlock = 0x00e5
-};
-
-static const struct WindowTemplate sWindowTemplate_YesNoMsg = {
- .bg = 0,
- .tilemapLeft = 1,
- .tilemapTop = 15,
- .width = 20,
- .height = 4,
- .paletteNum = 12,
- .baseBlock = 0x00e5
-};
-
-static const struct WindowTemplate sWindowTemplate_GiftSelect = {
- .bg = 0,
- .tilemapLeft = 1,
- .tilemapTop = 15,
- .width = 19,
- .height = 4,
- .paletteNum = 12,
- .baseBlock = 0x00e5
-};
-
-static const struct WindowTemplate sWindowTemplate_ThreeOptions = {
- .bg = 0,
- .tilemapLeft = 8,
- .tilemapTop = 6,
- .width = 14,
- .height = 6,
- .paletteNum = 12,
- .baseBlock = 0x0155
-};
-
-static const struct WindowTemplate sWindowTemplate_YesNoBox = {
- .bg = 0,
- .tilemapLeft = 23,
- .tilemapTop = 15,
- .width = 6,
- .height = 4,
- .paletteNum = 12,
- .baseBlock = 0x0155
-};
-
-static const struct WindowTemplate sWindowTemplate_GiftSelect_3Options = {
- .bg = 0,
- .tilemapLeft = 22,
- .tilemapTop = 11,
- .width = 7,
- .height = 8,
- .paletteNum = 12,
- .baseBlock = 0x0155
-};
-
-static const struct WindowTemplate sWindowTemplate_GiftSelect_2Options = {
- .bg = 0,
- .tilemapLeft = 22,
- .tilemapTop = 13,
- .width = 7,
- .height = 6,
- .paletteNum = 12,
- .baseBlock = 0x0155
-};
+ CpuFill32(0, &gSaveBlock1Ptr->mysteryGift, sizeof(gSaveBlock1Ptr->mysteryGift));
+ ClearSavedWonderNewsMetadata(); // Clear is redundant, InitSavedWonderNews would be sufficient
+ InitQuestionnaireWords();
+}
-static const struct WindowTemplate sWindowTemplate_GiftSelect_1Option = {
- .bg = 0,
- .tilemapLeft = 22,
- .tilemapTop = 15,
- .width = 7,
- .height = 4,
- .paletteNum = 12,
- .baseBlock = 0x0155
-};
+struct WonderNews *GetSavedWonderNews(void)
+{
+ return &gSaveBlock1Ptr->mysteryGift.news;
+}
-static const struct ListMenuItem sListMenuItems_CardsOrNews[] = {
- { gText_WonderCards, 0 },
- { gText_WonderNews, 1 },
- { gText_Exit3, LIST_CANCEL }
-};
+struct WonderCard *GetSavedWonderCard(void)
+{
+ return &gSaveBlock1Ptr->mysteryGift.card;
+}
-static const struct ListMenuItem sListMenuItems_WirelessOrFriend[] = {
- { gText_WirelessCommunication, 0 },
- { gText_Friend2, 1 },
- { gText_Cancel2, LIST_CANCEL }
-};
+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, LIST_CANCEL }
-};
+u16 *GetQuestionnaireWordsPtr(void)
+{
+ return gSaveBlock1Ptr->mysteryGift.questionnaireWords;
+}
-static const struct ListMenuItem sListMenuItems_ReceiveToss[] = {
- { gText_Receive, 0 },
- { gText_Toss, 2 },
- { gText_Cancel2, LIST_CANCEL }
-};
+// 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, LIST_CANCEL }
-};
+bool32 SaveWonderNews(const struct WonderNews *news)
+{
+ if (!ValidateWonderNews(news))
+ return FALSE;
-static const struct ListMenuItem sListMenuItems_Receive[] = {
- { gText_Receive, 0 },
- { gText_Cancel2, LIST_CANCEL }
-};
+ 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) static const u8 sTextColors_TopMenu[] = { TEXT_COLOR_TRANSPARENT, TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY };
-ALIGNED(2) static const u8 sTextColors_TopMenu_Copy[] = { TEXT_COLOR_TRANSPARENT, TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY };
-ALIGNED(2) static const u8 sMG_Ereader_TextColor_2[] = { TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_GRAY };
+ return TRUE;
+}
-static void VBlankCB_MysteryGiftEReader(void)
+static void ClearSavedWonderNews(void)
{
- ProcessSpriteCopyRequests();
- LoadOam();
- TransferPlttBuffer();
+ CpuFill32(0, GetSavedWonderNews(), sizeof(gSaveBlock1Ptr->mysteryGift.news));
+ gSaveBlock1Ptr->mysteryGift.newsCrc = 0;
}
-void CB2_MysteryGiftEReader(void)
+static void ClearSavedWonderNewsMetadata(void)
{
- RunTasks();
- RunTextPrinters();
- AnimateSprites();
- BuildOamBuffer();
+ CpuFill32(0, GetSavedWonderNewsMetadata(), sizeof(gSaveBlock1Ptr->mysteryGift.newsMetadata));
+ InitSavedWonderNews();
}
-static bool32 HandleMysteryGiftOrEReaderSetup(s32 isEReader)
+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));
-
- LoadMysteryGiftTextboxBorder(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(sTextboxBorder_Pal, 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(isEReader, FALSE);
- 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_MysteryGiftEReader);
- 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 CB2_InitMysteryGift(void)
+void ClearSavedWonderCardAndRelated(void)
{
- if (HandleMysteryGiftOrEReaderSetup(FALSE))
- {
- SetMainCallback2(CB2_MysteryGiftEReader);
- gGiftIsFromEReader = FALSE;
- CreateMysteryGiftTask();
- }
- RunTasks();
+ ClearSavedWonderCard();
+ ClearSavedWonderCardMetadata();
+ ClearSavedTrainerIds();
+ ClearRamScript();
+ ClearMysteryGiftFlags();
+ ClearMysteryGiftVars();
+ ClearEReaderTrainer(&gSaveBlock2Ptr->frontier.ereaderTrainer);
}
-void CB2_InitEReader(void)
+bool32 SaveWonderCard(const struct WonderCard *card)
{
- if (HandleMysteryGiftOrEReaderSetup(TRUE))
- {
- SetMainCallback2(CB2_MysteryGiftEReader);
- gGiftIsFromEReader = TRUE;
- CreateEReaderTask();
- }
-}
+ 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 isEReader, bool32 useCancel)
+bool32 ValidateSavedWonderCard(void)
{
- const u8 * header;
- const u8 * options;
- FillWindowPixelBuffer(0, 0);
- if (!isEReader)
- {
- header = gText_MysteryGift;
- options = !useCancel ? 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, sTextColors_TopMenu, TEXT_SPEED_FF, header);
- AddTextPrinterParameterized4(0, 0, GetStringRightAlignXOffset(0, options, 0xDE), 1, 0, 0, sTextColors_TopMenu, TEXT_SPEED_FF, 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;
-
- FillBgTilemapBufferRect(bg, 0x003, 0, 0, 32, 2, 0x11);
+ const struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
+ if (card->sendType == SEND_TYPE_DISALLOWED)
+ return FALSE;
- 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);
- }
- }
+ return TRUE;
}
-static void ClearScreenInBg0(bool32 ignoreTopTwoRows)
+static void ClearSavedWonderCard(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, &gSaveBlock1Ptr->mysteryGift.card, sizeof(gSaveBlock1Ptr->mysteryGift.card));
+ gSaveBlock1Ptr->mysteryGift.cardCrc = 0;
}
-void AddTextPrinterToWindow1(const u8 *str)
+static void ClearSavedWonderCardMetadata(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);
+ CpuFill32(0, GetSavedWonderCardMetadata(), sizeof(gSaveBlock1Ptr->mysteryGift.cardMetadata));
+ gSaveBlock1Ptr->mysteryGift.cardMetadataCrc = 0;
}
-static void ClearTextWindow(void)
+u16 GetWonderCardFlagID(void)
{
- rbox_fill_rectangle(1);
- ClearWindowTilemap(1);
- CopyWindowToVram(1, 1);
+ if (ValidateSavedWonderCard())
+ return gSaveBlock1Ptr->mysteryGift.card.flagId;
+
+ return 0;
}
-#define DOWN_ARROW_X 208
-#define DOWN_ARROW_Y 20
+void DisableWonderCardSending(struct WonderCard *card)
+{
+ if (card->sendType == SEND_TYPE_ALLOWED)
+ card->sendType = SEND_TYPE_DISALLOWED;
+}
-bool32 PrintMysteryGiftMenuMessage(u8 *textState, const u8 *str)
+static bool32 IsWonderCardFlagIDInValidRange(u16 flagId)
{
- switch (*textState)
- {
- case 0:
- AddTextPrinterToWindow1(str);
- (*textState)++;
- break;
- case 1:
- DrawDownArrow(1, DOWN_ARROW_X, DOWN_ARROW_Y, 1, FALSE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]);
- if (({JOY_NEW(A_BUTTON | B_BUTTON);}))
- (*textState)++;
- break;
- case 2:
- DrawDownArrow(1, DOWN_ARROW_X, DOWN_ARROW_Y, 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, DOWN_ARROW_X, DOWN_ARROW_Y, 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, DOWN_ARROW_X, DOWN_ARROW_Y, 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;
}
-// Unused
-static bool32 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, LIST_MENU_TILE_NUM, LIST_MENU_PAL_NUM);
- if (response != LIST_NOTHING_CHOSEN)
- {
- ClearWindowTilemap(2);
- CopyWindowToVram(2, 1);
- }
- return response;
+ return GetNumStampsInMetadata(&gSaveBlock1Ptr->mysteryGift.cardMetadata, card->maxStamps);
}
-s8 DoMysteryGiftYesNo(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;
- switch (*textState)
+ if (IsStampInMetadata(&gSaveBlock1Ptr->mysteryGift.cardMetadata, stamp, maxStamps))
+ return FALSE;
+
+ for (i = 0; i < maxStamps; i++)
{
- case 0:
- // Print question message
- StringExpandPlaceholders(gStringVar4, str);
- if (yesNoBoxPlacement == 0)
- *windowId = AddWindow(&sWindowTemplate_YesNoMsg_Wide);
- else
- *windowId = AddWindow(&sWindowTemplate_YesNoMsg);
- 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:
- // Create Yes/No
- windowTemplate = sWindowTemplate_YesNoBox;
- if (yesNoBoxPlacement == 0)
- windowTemplate.tilemapTop = 9;
- else
- windowTemplate.tilemapTop = 15;
- CreateYesNoMenu(&windowTemplate, 10, 14, 0);
- (*textState)++;
- break;
- case 2:
- // Handle Yes/No input
- 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 0xFF:
- *textState = 0;
- rbox_fill_rectangle(*windowId);
- ClearWindowTilemap(*windowId);
- CopyWindowToVram(*windowId, 1);
- RemoveWindow(*windowId);
- return MENU_B_PRESSED;
}
- return MENU_NOTHING_CHOSEN;
+ return FALSE;
}
-// Handle the "Receive/Send/Toss" menu that appears when selecting Wonder Card/News
-static s32 HandleGiftSelectMenu(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:
- // Print menu message
- if (!cannotToss)
- StringExpandPlaceholders(gStringVar4, gText_WhatToDoWithCards);
- else
- StringExpandPlaceholders(gStringVar4, gText_WhatToDoWithNews);
- *windowId = AddWindow(&sWindowTemplate_GiftSelect);
- 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)
- input = DoMysteryGiftListMenu(&sWindowTemplate_GiftSelect_2Options, &sListMenu_ReceiveToss, 1, LIST_MENU_TILE_NUM, LIST_MENU_PAL_NUM);
- else
- input = DoMysteryGiftListMenu(&sWindowTemplate_GiftSelect_1Option, &sListMenu_Receive, 1, LIST_MENU_TILE_NUM, LIST_MENU_PAL_NUM);
- }
- else
- {
- if (!cannotToss)
- input = DoMysteryGiftListMenu(&sWindowTemplate_GiftSelect_3Options, &sListMenu_ReceiveSendToss, 1, LIST_MENU_TILE_NUM, LIST_MENU_PAL_NUM);
- else
- input = DoMysteryGiftListMenu(&sWindowTemplate_GiftSelect_2Options, &sListMenu_ReceiveSend, 1, LIST_MENU_TILE_NUM, LIST_MENU_PAL_NUM);
- }
- if (input != LIST_NOTHING_CHOSEN)
- {
- *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 LIST_CANCEL;
+ // 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 LIST_NOTHING_CHOSEN;
-}
-
-static bool32 ValidateCardOrNews(bool32 isWonderNews)
-{
- if (!isWonderNews)
- return ValidateSavedWonderCard();
+ if (ValidateSavedWonderCard())
+ {
+ data->flagId = GetSavedWonderCard()->flagId;
+ data->cardMetadata = *GetSavedWonderCardMetadata();
+ data->maxStamps = GetSavedWonderCard()->maxStamps;
+ }
else
- return ValidateSavedWonderNews();
-}
-
-static bool32 HandleLoadWonderCardOrNews(u8 * state, bool32 isWonderNews)
-{
- switch (*state)
{
- case 0:
- if (!isWonderNews)
- WonderCard_Init(GetSavedWonderCard(), GetSavedWonderCardMetadata());
- else
- WonderNews_Init(GetSavedWonderNews());
- (*state)++;
- break;
- case 1:
- if (!isWonderNews)
- {
- if (!WonderCard_Enter())
- return FALSE;
- }
- else
- {
- if (!WonderNews_Enter())
- return FALSE;
- }
- *state = 0;
- return TRUE;
+ data->flagId = 0;
}
- return FALSE;
-}
+ for (i = 0; i < NUM_QUESTIONNAIRE_WORDS; i++)
+ data->questionnaireWords[i] = gSaveBlock1Ptr->mysteryGift.questionnaireWords[i];
-static bool32 ClearSavedNewsOrCard(bool32 isWonderNews)
-{
- if (!isWonderNews)
- ClearSavedWonderCardAndRelated();
- else
- ClearSavedWonderNewsAndRelated();
- return TRUE;
+ 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 ExitWonderCardOrNews(bool32 isWonderNews, bool32 useCancel)
+bool32 MysteryGift_ValidateLinkGameData(const struct MysteryGiftLinkGameData *data, bool32 isWonderNews)
{
+ if (data->validationVar != GAME_DATA_VALID_VAR)
+ return FALSE;
+
+ if (!(data->validationFlag1 & 1))
+ return FALSE;
+
+ if (!(data->validationFlag2 & 1))
+ return FALSE;
+
if (!isWonderNews)
{
- if (WonderCard_Exit(useCancel))
- {
- WonderCard_Destroy();
- return TRUE;
- }
- else
- {
+ if (!(data->validationGiftType1 & GAME_DATA_VALID_GIFT_TYPE_1))
return FALSE;
- }
- }
- else
- {
- if (WonderNews_Exit(useCancel))
- {
- WonderNews_Destroy();
- return TRUE;
- }
- else
- {
+
+ if (!(data->validationGiftType2 & (GAME_DATA_VALID_GIFT_TYPE_2 | 0x180)))
return FALSE;
- }
}
+
+ return TRUE;
}
-static s32 AskDiscardGift(u8 * textState, u16 * windowId, bool32 isWonderNews)
+u32 MysteryGift_CompareCardFlags(const u16 *flagId, const struct MysteryGiftLinkGameData *data, const void *unused)
{
- if (!isWonderNews)
- return DoMysteryGiftYesNo(textState, windowId, TRUE, gText_IfThrowAwayCardEventWontHappen);
- else
- return DoMysteryGiftYesNo(textState, windowId, TRUE, gText_OkayToDiscardNews);
+ // 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 PrintThrownAway(u8 * textState, bool32 isWonderNews)
+// 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 (!isWonderNews)
- return PrintMysteryGiftMenuMessage(textState, gText_WonderCardThrownAway);
- else
- return PrintMysteryGiftMenuMessage(textState, gText_WonderNewsThrownAway);
+ 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;
}
-static bool32 SaveOnMysteryGiftMenu(u8 * state)
+bool32 MysteryGift_DoesQuestionnaireMatch(const struct MysteryGiftLinkGameData *data, const u16 *words)
{
- switch (*state)
+ int i;
+ for (i = 0; i < NUM_QUESTIONNAIRE_WORDS; i++)
{
- 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))
- (*state)++;
- break;
- case 4:
- *state = 0;
- ClearTextWindow();
- return TRUE;
+ if (data->questionnaireWords[i] != words[i])
+ return FALSE;
}
- return FALSE;
+ return TRUE;
}
-static const u8 * GetClientResultMessage(bool32 * successMsg, bool8 isWonderNews, bool8 sourceIsFriend, u32 msgId)
+static int GetNumStampsInLinkData(const struct MysteryGiftLinkGameData *data)
{
- const u8 * msg = NULL;
- *successMsg = FALSE;
+ return GetNumStampsInMetadata(&data->cardMetadata, data->maxStamps);
+}
- switch (msgId)
+u16 MysteryGift_GetCardStatFromLinkData(const struct MysteryGiftLinkGameData *data, u32 stat)
+{
+ switch (stat)
{
- case CLI_MSG_NOTHING_SENT:
- *successMsg = FALSE;
- msg = gText_NothingSentOver;
- break;
- case CLI_MSG_RECORD_UPLOADED:
- *successMsg = FALSE;
- msg = gText_RecordUploadedViaWireless;
- break;
- case CLI_MSG_CARD_RECEIVED:
- *successMsg = TRUE;
- msg = !sourceIsFriend ? gText_WonderCardReceived : gText_WonderCardReceivedFrom;
- break;
- case CLI_MSG_NEWS_RECEIVED:
- *successMsg = TRUE;
- msg = !sourceIsFriend ? gText_WonderNewsReceived : gText_WonderNewsReceivedFrom;
- break;
- case CLI_MSG_STAMP_RECEIVED:
- *successMsg = TRUE;
- msg = gText_NewStampReceived;
- break;
- case CLI_MSG_HAD_CARD:
- *successMsg = FALSE;
- msg = gText_AlreadyHadCard;
- break;
- case CLI_MSG_HAD_STAMP:
- *successMsg = FALSE;
- msg = gText_AlreadyHadStamp;
- break;
- case CLI_MSG_HAD_NEWS:
- *successMsg = FALSE;
- msg = gText_AlreadyHadNews;
- break;
- case CLI_MSG_NO_ROOM_STAMPS:
- *successMsg = FALSE;
- msg = gText_NoMoreRoomForStamps;
- break;
- case CLI_MSG_COMM_CANCELED:
- *successMsg = FALSE;
- msg = gText_CommunicationCanceled;
- break;
- case CLI_MSG_CANT_ACCEPT:
- *successMsg = FALSE;
- msg = !isWonderNews ? gText_CantAcceptCardFromTrainer : gText_CantAcceptNewsFromTrainer;
- break;
- case CLI_MSG_COMM_ERROR:
- *successMsg = FALSE;
- msg = gText_CommunicationError;
- break;
- case CLI_MSG_TRAINER_RECEIVED:
- *successMsg = TRUE;
- msg = gText_NewTrainerReceived;
- break;
- case CLI_MSG_BUFFER_SUCCESS:
- *successMsg = TRUE;
- // msg is NULL, use buffer
- break;
- case CLI_MSG_BUFFER_FAILURE:
- *successMsg = FALSE;
- // msg is NULL, use buffer
- break;
+ 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;
}
-
- return msg;
}
-static bool32 PrintSuccessMessage(u8 * state, const u8 * msg, u16 * timer)
+static void IncrementCardStat(u32 statType)
{
- switch (*state)
+ struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
+ if (card->type == CARD_TYPE_LINK_STAT)
{
- case 0:
- if (msg != NULL)
- AddTextPrinterToWindow1(msg);
- PlayFanfare(MUS_OBTAIN_ITEM);
- *timer = 0;
- (*state)++;
- break;
- case 1:
- if (++(*timer) > 240)
- (*state)++;
- break;
- case 2:
- if (IsFanfareTaskInactive())
+ u16 *stat = NULL;
+ switch (statType)
{
- *state = 0;
- ClearTextWindow();
- return TRUE;
+ 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;
+
+ if (stat == NULL)
+ AGB_ASSERT(0);
+ else if (++(*stat) > MAX_WONDER_CARD_STAT)
+ *stat = MAX_WONDER_CARD_STAT;
}
- return FALSE;
}
-static const u8 * GetServerResultMessage(bool32 * wonderSuccess, bool8 sourceIsFriend, u32 msgId)
+u16 MysteryGift_GetCardStat(u32 stat)
{
- const u8 * result = gText_CommunicationError;
- *wonderSuccess = FALSE;
- switch (msgId)
+ switch (stat)
{
- case SVR_MSG_NOTHING_SENT:
- result = gText_NothingSentOver;
- break;
- case SVR_MSG_RECORD_UPLOADED:
- result = gText_RecordUploadedViaWireless;
- break;
- case SVR_MSG_CARD_SENT:
- result = gText_WonderCardSentTo;
- *wonderSuccess = TRUE;
- break;
- case SVR_MSG_NEWS_SENT:
- result = gText_WonderNewsSentTo;
- *wonderSuccess = TRUE;
- break;
- case SVR_MSG_STAMP_SENT:
- result = gText_StampSentTo;
- break;
- case SVR_MSG_HAS_CARD:
- result = gText_OtherTrainerHasCard;
- break;
- case SVR_MSG_HAS_STAMP:
- result = gText_OtherTrainerHasStamp;
- break;
- case SVR_MSG_HAS_NEWS:
- result = gText_OtherTrainerHasNews;
- break;
- case SVR_MSG_NO_ROOM_STAMPS:
- result = gText_NoMoreRoomForStamps;
- break;
- case SVR_MSG_CLIENT_CANCELED:
- result = gText_OtherTrainerCanceled;
- break;
- case SVR_MSG_CANT_SEND_GIFT_1:
- result = gText_CantSendGiftToTrainer;
+ case CARD_STAT_BATTLES_WON:
+ {
+ struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
+ if (card->type == CARD_TYPE_LINK_STAT)
+ {
+ struct WonderCardMetadata *metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata;
+ return metadata->battlesWon;
+ }
break;
- case SVR_MSG_COMM_ERROR:
- result = gText_CommunicationError;
+ }
+ case CARD_STAT_BATTLES_LOST:
+ {
+ struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
+ if (card->type == CARD_TYPE_LINK_STAT)
+ {
+ struct WonderCardMetadata *metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata;
+ return metadata->battlesLost;
+ }
break;
- case SVR_MSG_GIFT_SENT_1:
- result = gText_GiftSentTo;
+ }
+ case CARD_STAT_NUM_TRADES:
+ {
+ struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
+ if (card->type == CARD_TYPE_LINK_STAT)
+ {
+ struct WonderCardMetadata *metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata;
+ return metadata->numTrades;
+ }
break;
- case SVR_MSG_GIFT_SENT_2:
- result = gText_GiftSentTo;
+ }
+ case CARD_STAT_NUM_STAMPS:
+ {
+ struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
+ if (card->type == CARD_TYPE_STAMP)
+ return GetNumStampsInSavedCard();
break;
- case SVR_MSG_CANT_SEND_GIFT_2:
- result = gText_CantSendGiftToTrainer;
+ }
+ case CARD_STAT_MAX_STAMPS:
+ {
+ struct WonderCard *card = &gSaveBlock1Ptr->mysteryGift.card;
+ if (card->type == CARD_TYPE_STAMP)
+ return card->maxStamps;
break;
}
- return result;
+ }
+
+ AGB_ASSERT(0);
+ return 0;
}
-static bool32 PrintServerResultMessage(u8 * state, u16 * timer, bool8 sourceIsFriend, u32 msgId)
+void MysteryGift_DisableStats(void)
{
- bool32 wonderSuccess;
- const u8 * str = GetServerResultMessage(&wonderSuccess, sourceIsFriend, msgId);
- if (wonderSuccess)
- return PrintSuccessMessage(state, str, timer);
- else
- return PrintMysteryGiftMenuMessage(state, str);
+ sStatsEnabled = FALSE;
}
-// States for Task_MysteryGift.
-// CLIENT states are for when the player is receiving a gift, and use mevent_client.c link functions.
-// SERVER states are for when the player is sending a gift, and use mevent_server.c link functions.
-// Other states handle the general Mystery Gift menu usage.
-enum {
- MG_STATE_TO_MAIN_MENU,
- MG_STATE_MAIN_MENU,
- MG_STATE_DONT_HAVE_ANY,
- MG_STATE_SOURCE_PROMPT,
- MG_STATE_SOURCE_PROMPT_INPUT,
- MG_STATE_CLIENT_LINK_START,
- MG_STATE_CLIENT_LINK_WAIT,
- MG_STATE_CLIENT_COMMUNICATING,
- MG_STATE_CLIENT_LINK,
- MG_STATE_CLIENT_YES_NO,
- MG_STATE_CLIENT_MESSAGE,
- MG_STATE_CLIENT_ASK_TOSS,
- MG_STATE_CLIENT_ASK_TOSS_UNRECEIVED,
- MG_STATE_CLIENT_LINK_END,
- MG_STATE_CLIENT_COMM_COMPLETED,
- MG_STATE_CLIENT_RESULT_MSG,
- MG_STATE_CLIENT_ERROR,
- MG_STATE_SAVE_LOAD_GIFT,
- MG_STATE_LOAD_GIFT,
- MG_STATE_UNUSED,
- MG_STATE_HANDLE_GIFT_INPUT,
- MG_STATE_HANDLE_GIFT_SELECT,
- MG_STATE_ASK_TOSS,
- MG_STATE_ASK_TOSS_UNRECEIVED,
- MG_STATE_TOSS,
- MG_STATE_TOSS_SAVE,
- MG_STATE_TOSSED,
- MG_STATE_GIFT_INPUT_EXIT,
- MG_STATE_RECEIVE,
- MG_STATE_SEND,
- MG_STATE_SERVER_LINK_WAIT,
- MG_STATE_SERVER_LINK_START,
- MG_STATE_SERVER_LINK,
- MG_STATE_SERVER_LINK_END,
- MG_STATE_SERVER_LINK_END_WAIT,
- MG_STATE_SERVER_RESULT_MSG,
- MG_STATE_SERVER_ERROR,
- MG_STATE_EXIT,
-};
-
-static void CreateMysteryGiftTask(void)
+bool32 MysteryGift_TryEnableStatsByFlagId(u16 flagId)
{
- u8 taskId = CreateTask(Task_MysteryGift, 0);
- struct MysteryGiftTaskData * data = (void *)gTasks[taskId].data;
- data->state = MG_STATE_TO_MAIN_MENU;
- data->textState = 0;
- data->unused4 = 0;
- data->unused5 = 0;
- data->isWonderNews = 0;
- data->sourceIsFriend = 0;
- data->var = 0;
- data->unused1 = 0;
- data->unused2 = 0;
- data->unused3 = 0;
- data->msgId = 0;
- data->clientMsg = AllocZeroed(CLIENT_MAX_MSG_SIZE);
+ sStatsEnabled = FALSE;
+ if (flagId == 0)
+ return FALSE;
+
+ if (!ValidateSavedWonderCard())
+ return FALSE;
+
+ if (gSaveBlock1Ptr->mysteryGift.card.flagId != flagId)
+ return FALSE;
+
+ sStatsEnabled = TRUE;
+ return TRUE;
}
-static void Task_MysteryGift(u8 taskId)
+void MysteryGift_TryIncrementStat(u32 stat, u32 trainerId)
{
- struct MysteryGiftTaskData *data = (void *)gTasks[taskId].data;
- u32 successMsg, input;
- const u8 *msg;
-
- switch (data->state)
+ if (sStatsEnabled)
{
- case MG_STATE_TO_MAIN_MENU:
- data->state = MG_STATE_MAIN_MENU;
- break;
- case MG_STATE_MAIN_MENU:
- // Main Mystery Gift menu, player can select Wonder Cards or News (or exit)
- switch (MysteryGift_HandleThreeOptionMenu(&data->textState, &data->var, FALSE))
+ switch (stat)
{
- case 0: // "Wonder Cards"
- data->isWonderNews = FALSE;
- if (ValidateSavedWonderCard() == TRUE)
- data->state = MG_STATE_LOAD_GIFT;
- else
- data->state = MG_STATE_DONT_HAVE_ANY;
+ case CARD_STAT_NUM_TRADES:
+ IncrementCardStatForNewTrainer(CARD_STAT_NUM_TRADES,
+ trainerId,
+ gSaveBlock1Ptr->mysteryGift.trainerIds[1],
+ ARRAY_COUNT(gSaveBlock1Ptr->mysteryGift.trainerIds[1]));
break;
- case 1: // "Wonder News"
- data->isWonderNews = TRUE;
- if (ValidateSavedWonderNews() == TRUE)
- data->state = MG_STATE_LOAD_GIFT;
- else
- data->state = MG_STATE_DONT_HAVE_ANY;
+ case CARD_STAT_BATTLES_WON:
+ IncrementCardStatForNewTrainer(CARD_STAT_BATTLES_WON,
+ trainerId,
+ gSaveBlock1Ptr->mysteryGift.trainerIds[0],
+ ARRAY_COUNT(gSaveBlock1Ptr->mysteryGift.trainerIds[0]));
break;
- case LIST_CANCEL:
- data->state = MG_STATE_EXIT;
+ case CARD_STAT_BATTLES_LOST:
+ IncrementCardStatForNewTrainer(CARD_STAT_BATTLES_LOST,
+ trainerId,
+ gSaveBlock1Ptr->mysteryGift.trainerIds[0],
+ ARRAY_COUNT(gSaveBlock1Ptr->mysteryGift.trainerIds[0]));
break;
- }
- break;
- case MG_STATE_DONT_HAVE_ANY:
- {
- // Player doesn't have any Wonder Card/News
- // Start prompt to ask where to read one from
- if (!data->isWonderNews)
- {
- if (PrintMysteryGiftMenuMessage(&data->textState, gText_DontHaveCardNewOneInput))
- {
- data->state = MG_STATE_SOURCE_PROMPT;
- PrintMysteryGiftOrEReaderTopMenu(FALSE, TRUE);
- }
- }
- else
- {
- if (PrintMysteryGiftMenuMessage(&data->textState, gText_DontHaveNewsNewOneInput))
- {
- data->state = MG_STATE_SOURCE_PROMPT;
- PrintMysteryGiftOrEReaderTopMenu(FALSE, TRUE);
- }
- }
- break;
- }
- case MG_STATE_SOURCE_PROMPT:
- if (!data->isWonderNews)
- AddTextPrinterToWindow1(gText_WhereShouldCardBeAccessed);
- else
- AddTextPrinterToWindow1(gText_WhereShouldNewsBeAccessed);
- data->state = MG_STATE_SOURCE_PROMPT_INPUT;
- break;
- case MG_STATE_SOURCE_PROMPT_INPUT:
- // Choose where to access the Wonder Card/News from
- switch (MysteryGift_HandleThreeOptionMenu(&data->textState, &data->var, TRUE))
- {
- case 0: // "Wireless Communication"
- ClearTextWindow();
- data->state = MG_STATE_CLIENT_LINK_START;
- data->sourceIsFriend = FALSE;
- break;
- case 1: // "Friend"
- ClearTextWindow();
- data->state = MG_STATE_CLIENT_LINK_START;
- data->sourceIsFriend = TRUE;
- break;
- case LIST_CANCEL:
- ClearTextWindow();
- if (ValidateCardOrNews(data->isWonderNews))
- {
- data->state = MG_STATE_LOAD_GIFT;
- }
- else
- {
- data->state = MG_STATE_TO_MAIN_MENU;
- PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE);
- }
+ default:
+ AGB_ASSERT(0);
break;
}
- break;
- case MG_STATE_CLIENT_LINK_START:
- *gStringVar1 = EOS;
- *gStringVar2 = EOS;
- *gStringVar3 = EOS;
+ }
+}
- switch (data->isWonderNews)
- {
- case FALSE:
- if (data->sourceIsFriend == TRUE)
- CreateTask_LinkMysteryGiftWithFriend(ACTIVITY_WONDER_CARD);
- else if (data->sourceIsFriend == FALSE)
- CreateTask_LinkMysteryGiftOverWireless(ACTIVITY_WONDER_CARD);
- break;
- case TRUE:
- if (data->sourceIsFriend == TRUE)
- CreateTask_LinkMysteryGiftWithFriend(ACTIVITY_WONDER_NEWS);
- else if (data->sourceIsFriend == FALSE)
- CreateTask_LinkMysteryGiftOverWireless(ACTIVITY_WONDER_NEWS);
- break;
- }
- data->state = MG_STATE_CLIENT_LINK_WAIT;
- break;
- case MG_STATE_CLIENT_LINK_WAIT:
- if (gReceivedRemoteLinkPlayers != 0)
- {
- ClearScreenInBg0(TRUE);
- data->state = MG_STATE_CLIENT_COMMUNICATING;
- MysteryGiftClient_Create(data->isWonderNews);
- }
- else if (gSpecialVar_Result == LINKUP_FAILED)
- {
- // Link failed, return to link start menu
- ClearScreenInBg0(TRUE);
- data->state = MG_STATE_SOURCE_PROMPT;
- }
- break;
- case MG_STATE_CLIENT_COMMUNICATING:
- AddTextPrinterToWindow1(gText_Communicating);
- data->state = MG_STATE_CLIENT_LINK;
- break;
- case MG_STATE_CLIENT_LINK:
- switch (MysteryGiftClient_Run(&data->var))
- {
- case CLI_RET_END:
- Rfu_SetCloseLinkCallback();
- data->msgId = data->var;
- data->state = MG_STATE_CLIENT_LINK_END;
- break;
- case CLI_RET_COPY_MSG:
- memcpy(data->clientMsg, MysteryGiftClient_GetMsg(), 0x40);
- MysteryGiftClient_AdvanceState();
- break;
- case CLI_RET_PRINT_MSG:
- data->state = MG_STATE_CLIENT_MESSAGE;
- break;
- case CLI_RET_YES_NO:
- data->state = MG_STATE_CLIENT_YES_NO;
- break;
- case CLI_RET_ASK_TOSS:
- data->state = MG_STATE_CLIENT_ASK_TOSS;
- StringCopy(gStringVar1, gLinkPlayers[0].name);
- break;
- }
- break;
- case MG_STATE_CLIENT_YES_NO:
- input = DoMysteryGiftYesNo(&data->textState, &data->var, FALSE, MysteryGiftClient_GetMsg());
- switch (input)
- {
- case 0: // Yes
- MysteryGiftClient_SetParam(FALSE);
- MysteryGiftClient_AdvanceState();
- data->state = MG_STATE_CLIENT_COMMUNICATING;
- break;
- case 1: // No
- case MENU_B_PRESSED:
- MysteryGiftClient_SetParam(TRUE);
- MysteryGiftClient_AdvanceState();
- data->state = MG_STATE_CLIENT_COMMUNICATING;
- break;
- }
- break;
- case MG_STATE_CLIENT_MESSAGE:
- if (PrintMysteryGiftMenuMessage(&data->textState, MysteryGiftClient_GetMsg()))
- {
- MysteryGiftClient_AdvanceState();
- data->state = MG_STATE_CLIENT_COMMUNICATING;
- }
- break;
- case MG_STATE_CLIENT_ASK_TOSS:
- // Player is receiving a new Wonder Card/News but needs to toss an existing one to make room.
- // Ask for confirmation.
- input = DoMysteryGiftYesNo(&data->textState, &data->var, FALSE, gText_ThrowAwayWonderCard);
- switch (input)
- {
- case 0: // Yes
- if (IsSavedWonderCardGiftNotReceived() == TRUE)
- {
- data->state = MG_STATE_CLIENT_ASK_TOSS_UNRECEIVED;
- }
- else
- {
- MysteryGiftClient_SetParam(FALSE);
- MysteryGiftClient_AdvanceState();
- data->state = MG_STATE_CLIENT_COMMUNICATING;
- }
- break;
- case 1: // No
- case MENU_B_PRESSED:
- MysteryGiftClient_SetParam(TRUE);
- MysteryGiftClient_AdvanceState();
- data->state = MG_STATE_CLIENT_COMMUNICATING;
- break;
- }
- break;
- case MG_STATE_CLIENT_ASK_TOSS_UNRECEIVED:
- // Player has selected to toss a Wonder Card that they haven't received the gift for.
- // Ask for confirmation again.
- input = DoMysteryGiftYesNo(&data->textState, &data->var, FALSE, gText_HaventReceivedCardsGift);
- switch (input)
- {
- case 0: // Yes
- MysteryGiftClient_SetParam(FALSE);
- MysteryGiftClient_AdvanceState();
- data->state = MG_STATE_CLIENT_COMMUNICATING;
- break;
- case 1: // No
- case MENU_B_PRESSED:
- MysteryGiftClient_SetParam(TRUE);
- MysteryGiftClient_AdvanceState();
- data->state = MG_STATE_CLIENT_COMMUNICATING;
- break;
- }
- break;
- case MG_STATE_CLIENT_LINK_END:
- if (gReceivedRemoteLinkPlayers == 0)
- {
- DestroyWirelessStatusIndicatorSprite();
- data->state = MG_STATE_CLIENT_COMM_COMPLETED;
- }
- break;
- case MG_STATE_CLIENT_COMM_COMPLETED:
- if (PrintStringAndWait2Seconds(&data->textState, gText_CommunicationCompleted))
- {
- if (data->sourceIsFriend == TRUE)
- StringCopy(gStringVar1, gLinkPlayers[0].name);
- data->state = MG_STATE_CLIENT_RESULT_MSG;
- }
- break;
- case MG_STATE_CLIENT_RESULT_MSG:
- msg = GetClientResultMessage(&successMsg, data->isWonderNews, data->sourceIsFriend, data->msgId);
- if (msg == NULL)
- msg = data->clientMsg;
- if (successMsg)
- input = PrintSuccessMessage(&data->textState, msg, &data->var);
- else
- input = PrintMysteryGiftMenuMessage(&data->textState, msg);
- // input var re-used, here it is TRUE if the message is finished
- if (input)
- {
- if (data->msgId == CLI_MSG_NEWS_RECEIVED)
- {
- if (data->sourceIsFriend == TRUE)
- GenerateRandomWonderNews(WONDER_NEWS_RECV_FRIEND);
- else
- GenerateRandomWonderNews(WONDER_NEWS_RECV_WIRELESS);
- }
- if (!successMsg)
- {
- // Did not receive card/news, return to main menu
- data->state = MG_STATE_TO_MAIN_MENU;
- PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE);
- }
- else
- {
- data->state = MG_STATE_SAVE_LOAD_GIFT;
- }
- }
- break;
- case MG_STATE_SAVE_LOAD_GIFT:
- if (SaveOnMysteryGiftMenu(&data->textState))
- data->state = MG_STATE_LOAD_GIFT;
- break;
- case MG_STATE_LOAD_GIFT:
- if (HandleLoadWonderCardOrNews(&data->textState, data->isWonderNews))
- data->state = MG_STATE_HANDLE_GIFT_INPUT;
- break;
- case MG_STATE_HANDLE_GIFT_INPUT:
- if (!data->isWonderNews)
- {
- // Handle Wonder Card input
- if (JOY_NEW(A_BUTTON))
- data->state = MG_STATE_HANDLE_GIFT_SELECT;
- if (JOY_NEW(B_BUTTON))
- data->state = MG_STATE_GIFT_INPUT_EXIT;
- }
- else
- {
- switch (WonderNews_GetInput(gMain.newKeys))
- {
- case NEWS_INPUT_A:
- WonderNews_RemoveScrollIndicatorArrowPair();
- data->state = MG_STATE_HANDLE_GIFT_SELECT;
- break;
- case NEWS_INPUT_B:
- data->state = MG_STATE_GIFT_INPUT_EXIT;
- break;
- }
- }
- break;
- case MG_STATE_HANDLE_GIFT_SELECT:
+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++)
{
- // A Wonder Card/News has been selected, handle its menu
- u32 result;
- if (!data->isWonderNews)
- {
- if (IsSendingSavedWonderCardAllowed())
- result = HandleGiftSelectMenu(&data->textState, &data->var, data->isWonderNews, FALSE);
- else
- result = HandleGiftSelectMenu(&data->textState, &data->var, data->isWonderNews, TRUE);
- }
- else
- {
- if (IsSendingSavedWonderNewsAllowed())
- result = HandleGiftSelectMenu(&data->textState, &data->var, data->isWonderNews, FALSE);
- else
- result = HandleGiftSelectMenu(&data->textState, &data->var, data->isWonderNews, TRUE);
- }
- switch (result)
- {
- case 0: // Receive
- data->state = MG_STATE_RECEIVE;
- break;
- case 1: // Send
- data->state = MG_STATE_SEND;
- break;
- case 2: // Toss
- data->state = MG_STATE_ASK_TOSS;
+ if (trainerIds[i] == trainerId)
break;
- case LIST_CANCEL:
- if (data->isWonderNews == TRUE)
- WonderNews_AddScrollIndicatorArrowPair();
- data->state = MG_STATE_HANDLE_GIFT_INPUT;
- break;
- }
- break;
}
- case MG_STATE_ASK_TOSS:
- // Player is attempting to discard a saved Wonder Card/News
- switch (AskDiscardGift(&data->textState, &data->var, data->isWonderNews))
- {
- case 0: // Yes
- if (!data->isWonderNews && IsSavedWonderCardGiftNotReceived() == TRUE)
- data->state = MG_STATE_ASK_TOSS_UNRECEIVED;
- else
- data->state = MG_STATE_TOSS;
- break;
- case 1: // No
- case MENU_B_PRESSED:
- data->state = MG_STATE_HANDLE_GIFT_SELECT;
- break;
- }
- break;
- case MG_STATE_ASK_TOSS_UNRECEIVED:
- // Player has selected to toss a Wonder Card that they haven't received the gift for.
- // Ask for confirmation again.
- switch ((u32)DoMysteryGiftYesNo(&data->textState, &data->var, TRUE, gText_HaventReceivedGiftOkayToDiscard))
- {
- case 0: // Yes
- data->state = MG_STATE_TOSS;
- break;
- case 1: // No
- case MENU_B_PRESSED:
- data->state = MG_STATE_HANDLE_GIFT_SELECT;
- break;
- }
- break;
- case MG_STATE_TOSS:
- if (ExitWonderCardOrNews(data->isWonderNews, TRUE))
- {
- ClearSavedNewsOrCard(data->isWonderNews);
- data->state = MG_STATE_TOSS_SAVE;
- }
- break;
- case MG_STATE_TOSS_SAVE:
- if (SaveOnMysteryGiftMenu(&data->textState))
- data->state = MG_STATE_TOSSED;
- break;
- case MG_STATE_TOSSED:
- if (PrintThrownAway(&data->textState, data->isWonderNews))
- {
- data->state = MG_STATE_TO_MAIN_MENU;
- PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE);
- }
- break;
- case MG_STATE_GIFT_INPUT_EXIT:
- if (ExitWonderCardOrNews(data->isWonderNews, FALSE))
- data->state = MG_STATE_TO_MAIN_MENU;
- break;
- case MG_STATE_RECEIVE:
- if (ExitWonderCardOrNews(data->isWonderNews, TRUE))
- data->state = MG_STATE_SOURCE_PROMPT;
- break;
- case MG_STATE_SEND:
- if (ExitWonderCardOrNews(data->isWonderNews, TRUE))
- {
- switch (data->isWonderNews)
- {
- case FALSE:
- CreateTask_SendMysteryGift(ACTIVITY_WONDER_CARD);
- break;
- case TRUE:
- CreateTask_SendMysteryGift(ACTIVITY_WONDER_NEWS);
- break;
- }
- data->sourceIsFriend = TRUE;
- data->state = MG_STATE_SERVER_LINK_WAIT;
- }
- break;
- case MG_STATE_SERVER_LINK_WAIT:
- if (gReceivedRemoteLinkPlayers != 0)
- {
- ClearScreenInBg0(TRUE);
- data->state = MG_STATE_SERVER_LINK_START;
- }
- else if (gSpecialVar_Result == LINKUP_FAILED)
- {
- ClearScreenInBg0(TRUE);
- data->state = MG_STATE_LOAD_GIFT;
- }
- break;
- case MG_STATE_SERVER_LINK_START:
- *gStringVar1 = EOS;
- *gStringVar2 = EOS;
- *gStringVar3 = EOS;
- if (!data->isWonderNews)
- {
- AddTextPrinterToWindow1(gText_SendingWonderCard);
- MysterGiftServer_CreateForCard();
- }
- else
- {
- AddTextPrinterToWindow1(gText_SendingWonderNews);
- MysterGiftServer_CreateForNews();
- }
- data->state = MG_STATE_SERVER_LINK;
- break;
- case MG_STATE_SERVER_LINK:
- if (MysterGiftServer_Run(&data->var) == SVR_RET_END)
- {
- data->msgId = data->var;
- data->state = MG_STATE_SERVER_LINK_END;
- }
- break;
- case MG_STATE_SERVER_LINK_END:
- Rfu_SetCloseLinkCallback();
- StringCopy(gStringVar1, gLinkPlayers[1].name);
- data->state = MG_STATE_SERVER_LINK_END_WAIT;
- break;
- case MG_STATE_SERVER_LINK_END_WAIT:
- if (gReceivedRemoteLinkPlayers == 0)
- {
- DestroyWirelessStatusIndicatorSprite();
- data->state = MG_STATE_SERVER_RESULT_MSG;
- }
- break;
- case MG_STATE_SERVER_RESULT_MSG:
- if (PrintServerResultMessage(&data->textState, &data->var, data->sourceIsFriend, data->msgId))
- {
- if (data->sourceIsFriend == TRUE && data->msgId == SVR_MSG_NEWS_SENT)
- {
- GenerateRandomWonderNews(WONDER_NEWS_SENT);
- data->state = MG_STATE_SAVE_LOAD_GIFT;
- }
- else
- {
- data->state = MG_STATE_TO_MAIN_MENU;
- PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE);
- }
- }
- break;
- case MG_STATE_CLIENT_ERROR:
- case MG_STATE_SERVER_ERROR:
- if (PrintMysteryGiftMenuMessage(&data->textState, gText_CommunicationError))
- {
- data->state = MG_STATE_TO_MAIN_MENU;
- PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE);
- }
- break;
- case MG_STATE_EXIT:
- CloseLink();
- Free(data->clientMsg);
- 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;
+ }
}
-static void LoadMysteryGiftTextboxBorder(u8 bgId)
+static void IncrementCardStatForNewTrainer(u32 stat, u32 trainerId, u32 *trainerIds, int size)
{
- DecompressAndLoadBgGfxUsingHeap(bgId, sTextboxBorder_Gfx, 0x100, 0, 0);
+ if (RecordTrainerId(trainerId, trainerIds, size))
+ IncrementCardStat(stat);
}
diff --git a/src/mevent_client.c b/src/mystery_gift_client.c
index e260f073f..adf3ce8a6 100644
--- a/src/mevent_client.c
+++ b/src/mystery_gift_client.c
@@ -4,9 +4,9 @@
#include "overworld.h"
#include "script.h"
#include "battle_tower.h"
-#include "mevent.h"
+#include "mystery_gift.h"
#include "mystery_event_script.h"
-#include "mevent_client.h"
+#include "mystery_gift_client.h"
enum {
FUNC_INIT,
@@ -15,8 +15,8 @@ enum {
FUNC_SEND,
FUNC_RUN,
FUNC_WAIT,
- FUNC_RUN_GIFT_SCRIPT,
- FUNC_RUN_BUFF_SCRIPT,
+ FUNC_RUN_MEVENT,
+ FUNC_RUN_BUFFER,
};
EWRAM_DATA static struct MysteryGiftClient * sClient = NULL;
@@ -222,8 +222,8 @@ static u32 Client_Run(struct MysteryGiftClient * client)
MysteryGiftClient_InitSendWord(client, MG_LINKID_RESPONSE, TRUE);
}
break;
- case CLI_RUN_GIFT_SCRIPT:
- client->funcId = FUNC_RUN_GIFT_SCRIPT;
+ case CLI_RUN_MEVENT_SCRIPT:
+ client->funcId = FUNC_RUN_MEVENT;
client->funcState = 0;
break;
case CLI_SAVE_STAMP:
@@ -238,7 +238,7 @@ static u32 Client_Run(struct MysteryGiftClient * client)
break;
case CLI_RUN_BUFFER_SCRIPT:
memcpy(gDecompressionBuffer, client->recvBuffer, MG_LINK_BUFFER_SIZE);
- client->funcId = FUNC_RUN_BUFF_SCRIPT;
+ client->funcId = FUNC_RUN_BUFFER;
client->funcState = 0;
break;
}
@@ -256,16 +256,16 @@ static u32 Client_Wait(struct MysteryGiftClient * client)
return CLI_RET_ACTIVE;
}
-static u32 Client_RunGiftScript(struct MysteryGiftClient * client)
+static u32 Client_RunMysteryEventScript(struct MysteryGiftClient * client)
{
switch (client->funcState)
{
case 0:
- InitMysteryGiftScriptContext(client->recvBuffer);
+ InitMysteryEventScriptContext(client->recvBuffer);
client->funcState++;
break;
case 1:
- if (!RunMysteryGiftScriptContextCommand(&client->param))
+ if (!RunMysteryEventScriptContextCommand(&client->param))
{
client->funcId = FUNC_RUN;
client->funcState = 0;
@@ -296,8 +296,8 @@ static u32 MysteryGiftClient_CallFunc(struct MysteryGiftClient * client)
[FUNC_SEND] = Client_Send,
[FUNC_RUN] = Client_Run,
[FUNC_WAIT] = Client_Wait,
- [FUNC_RUN_GIFT_SCRIPT] = Client_RunGiftScript,
- [FUNC_RUN_BUFF_SCRIPT] = Client_RunBufferScript
+ [FUNC_RUN_MEVENT] = Client_RunMysteryEventScript,
+ [FUNC_RUN_BUFFER] = Client_RunBufferScript
};
return funcs[client->funcId](client);
}
diff --git a/src/mevent_server_helpers.c b/src/mystery_gift_link.c
index c1fe88368..55f4b7852 100644
--- a/src/mevent_server_helpers.c
+++ b/src/mystery_gift_link.c
@@ -8,8 +8,8 @@
#include "script.h"
#include "battle_tower.h"
#include "mystery_event_script.h"
-#include "mevent.h"
-#include "mevent_server_helpers.h"
+#include "mystery_gift.h"
+#include "mystery_gift_link.h"
/*
Handles the link connection functions used by the Mystery Gift client/server.
diff --git a/src/mystery_gift_menu.c b/src/mystery_gift_menu.c
new file mode 100644
index 000000000..e1236adfd
--- /dev/null
+++ b/src/mystery_gift_menu.c
@@ -0,0 +1,1618 @@
+#include "global.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_menu.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 "mystery_gift.h"
+#include "mystery_gift_view.h"
+#include "save.h"
+#include "link.h"
+#include "mystery_gift_client.h"
+#include "mystery_gift_server.h"
+#include "event_data.h"
+#include "link_rfu.h"
+#include "wonder_news.h"
+#include "constants/cable_club.h"
+
+#define LIST_MENU_TILE_NUM 10
+#define LIST_MENU_PAL_NUM 224
+
+static void LoadMysteryGiftTextboxBorder(u8 bgId);
+static void CreateMysteryGiftTask(void);
+static void Task_MysteryGift(u8 taskId);
+
+EWRAM_DATA static u8 sDownArrowCounterAndYCoordIdx[8] = {};
+EWRAM_DATA bool8 gGiftIsFromEReader = FALSE;
+
+static const u16 sTextboxBorder_Pal[] = INCBIN_U16("graphics/interface/mystery_gift_textbox_border.gbapal");
+static const u32 sTextboxBorder_Gfx[] = INCBIN_U32("graphics/interface/mystery_gift_textbox_border.4bpp.lz");
+
+struct MysteryGiftTaskData
+{
+ u16 var; // Multipurpose
+ u16 unused1;
+ u16 unused2;
+ u16 unused3;
+ u8 state;
+ u8 textState;
+ u8 unused4;
+ u8 unused5;
+ bool8 isWonderNews;
+ bool8 sourceIsFriend;
+ u8 msgId;
+ u8 * clientMsg;
+};
+
+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 = 0,
+ .tilemapLeft = 0,
+ .tilemapTop = 0,
+ .width = 30,
+ .height = 2,
+ .paletteNum = 12,
+ .baseBlock = 0x0013
+ }, {
+ .bg = 0,
+ .tilemapLeft = 1,
+ .tilemapTop = 15,
+ .width = 28,
+ .height = 4,
+ .paletteNum = 12,
+ .baseBlock = 0x004f
+ }, {
+ .bg = 0,
+ .tilemapLeft = 0,
+ .tilemapTop = 15,
+ .width = 30,
+ .height = 5,
+ .paletteNum = 13,
+ .baseBlock = 0x004f
+ },
+ DUMMY_WIN_TEMPLATE
+};
+
+static const struct WindowTemplate sWindowTemplate_YesNoMsg_Wide = {
+ .bg = 0,
+ .tilemapLeft = 1,
+ .tilemapTop = 15,
+ .width = 28,
+ .height = 4,
+ .paletteNum = 12,
+ .baseBlock = 0x00e5
+};
+
+static const struct WindowTemplate sWindowTemplate_YesNoMsg = {
+ .bg = 0,
+ .tilemapLeft = 1,
+ .tilemapTop = 15,
+ .width = 20,
+ .height = 4,
+ .paletteNum = 12,
+ .baseBlock = 0x00e5
+};
+
+static const struct WindowTemplate sWindowTemplate_GiftSelect = {
+ .bg = 0,
+ .tilemapLeft = 1,
+ .tilemapTop = 15,
+ .width = 19,
+ .height = 4,
+ .paletteNum = 12,
+ .baseBlock = 0x00e5
+};
+
+static const struct WindowTemplate sWindowTemplate_ThreeOptions = {
+ .bg = 0,
+ .tilemapLeft = 8,
+ .tilemapTop = 6,
+ .width = 14,
+ .height = 6,
+ .paletteNum = 12,
+ .baseBlock = 0x0155
+};
+
+static const struct WindowTemplate sWindowTemplate_YesNoBox = {
+ .bg = 0,
+ .tilemapLeft = 23,
+ .tilemapTop = 15,
+ .width = 6,
+ .height = 4,
+ .paletteNum = 12,
+ .baseBlock = 0x0155
+};
+
+static const struct WindowTemplate sWindowTemplate_GiftSelect_3Options = {
+ .bg = 0,
+ .tilemapLeft = 22,
+ .tilemapTop = 11,
+ .width = 7,
+ .height = 8,
+ .paletteNum = 12,
+ .baseBlock = 0x0155
+};
+
+static const struct WindowTemplate sWindowTemplate_GiftSelect_2Options = {
+ .bg = 0,
+ .tilemapLeft = 22,
+ .tilemapTop = 13,
+ .width = 7,
+ .height = 6,
+ .paletteNum = 12,
+ .baseBlock = 0x0155
+};
+
+static const struct WindowTemplate sWindowTemplate_GiftSelect_1Option = {
+ .bg = 0,
+ .tilemapLeft = 22,
+ .tilemapTop = 15,
+ .width = 7,
+ .height = 4,
+ .paletteNum = 12,
+ .baseBlock = 0x0155
+};
+
+static const struct ListMenuItem sListMenuItems_CardsOrNews[] = {
+ { gText_WonderCards, 0 },
+ { gText_WonderNews, 1 },
+ { gText_Exit3, LIST_CANCEL }
+};
+
+static const struct ListMenuItem sListMenuItems_WirelessOrFriend[] = {
+ { gText_WirelessCommunication, 0 },
+ { gText_Friend2, 1 },
+ { gText_Cancel2, LIST_CANCEL }
+};
+
+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
+};
+
+static const struct ListMenuItem sListMenuItems_ReceiveSendToss[] = {
+ { gText_Receive, 0 },
+ { gText_Send, 1 },
+ { gText_Toss, 2 },
+ { gText_Cancel2, LIST_CANCEL }
+};
+
+static const struct ListMenuItem sListMenuItems_ReceiveToss[] = {
+ { gText_Receive, 0 },
+ { gText_Toss, 2 },
+ { gText_Cancel2, LIST_CANCEL }
+};
+
+static const struct ListMenuItem sListMenuItems_ReceiveSend[] = {
+ { gText_Receive, 0 },
+ { gText_Send, 1 },
+ { gText_Cancel2, LIST_CANCEL }
+};
+
+static const struct ListMenuItem sListMenuItems_Receive[] = {
+ { gText_Receive, 0 },
+ { gText_Cancel2, LIST_CANCEL }
+};
+
+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
+};
+
+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
+};
+
+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 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
+};
+
+static const u8 *const Unref_082F0710[] = {
+ gText_VarietyOfEventsImportedWireless,
+ gText_WonderCardsInPossession,
+ gText_ReadNewsThatArrived,
+ gText_ReturnToTitle
+};
+
+ALIGNED(2) static const u8 sTextColors_TopMenu[] = { TEXT_COLOR_TRANSPARENT, TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY };
+ALIGNED(2) static const u8 sTextColors_TopMenu_Copy[] = { TEXT_COLOR_TRANSPARENT, TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY };
+ALIGNED(2) static const u8 sMG_Ereader_TextColor_2[] = { TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_GRAY };
+
+static void VBlankCB_MysteryGiftEReader(void)
+{
+ ProcessSpriteCopyRequests();
+ LoadOam();
+ TransferPlttBuffer();
+}
+
+void CB2_MysteryGiftEReader(void)
+{
+ RunTasks();
+ RunTextPrinters();
+ AnimateSprites();
+ BuildOamBuffer();
+}
+
+static bool32 HandleMysteryGiftOrEReaderSetup(s32 isEReader)
+{
+ switch (gMain.state)
+ {
+ 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));
+
+ LoadMysteryGiftTextboxBorder(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(sTextboxBorder_Pal, 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(isEReader, FALSE);
+ 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_MysteryGiftEReader);
+ EnableInterrupts(INTR_FLAG_VBLANK | INTR_FLAG_VCOUNT | INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void CB2_InitMysteryGift(void)
+{
+ if (HandleMysteryGiftOrEReaderSetup(FALSE))
+ {
+ SetMainCallback2(CB2_MysteryGiftEReader);
+ gGiftIsFromEReader = FALSE;
+ CreateMysteryGiftTask();
+ }
+ RunTasks();
+}
+
+void CB2_InitEReader(void)
+{
+ if (HandleMysteryGiftOrEReaderSetup(TRUE))
+ {
+ SetMainCallback2(CB2_MysteryGiftEReader);
+ gGiftIsFromEReader = TRUE;
+ CreateEReaderTask();
+ }
+}
+
+void MainCB_FreeAllBuffersAndReturnToInitTitleScreen(void)
+{
+ gGiftIsFromEReader = FALSE;
+ FreeAllWindowBuffers();
+ Free(GetBgTilemapBuffer(0));
+ Free(GetBgTilemapBuffer(1));
+ Free(GetBgTilemapBuffer(2));
+ Free(GetBgTilemapBuffer(3));
+ SetMainCallback2(CB2_InitTitleScreen);
+}
+
+void PrintMysteryGiftOrEReaderTopMenu(bool8 isEReader, bool32 useCancel)
+{
+ const u8 * header;
+ const u8 * options;
+ FillWindowPixelBuffer(0, 0);
+ if (!isEReader)
+ {
+ header = gText_MysteryGift;
+ options = !useCancel ? gText_PickOKExit : gText_PickOKCancel;
+ }
+ else
+ {
+ header = gJPText_MysteryGift;
+ options = gJPText_DecideStop;
+ }
+
+ AddTextPrinterParameterized4(0, 1, 4, 1, 0, 0, sTextColors_TopMenu, TEXT_SPEED_FF, header);
+ AddTextPrinterParameterized4(0, 0, GetStringRightAlignXOffset(0, options, 0xDE), 1, 0, 0, sTextColors_TopMenu, TEXT_SPEED_FF, options);
+ CopyWindowToVram(0, 2);
+ PutWindowTilemap(0);
+}
+
+void MG_DrawTextBorder(u8 windowId)
+{
+ DrawTextBorderOuter(windowId, 0x01, 0xF);
+}
+
+void MG_DrawCheckerboardPattern(u32 bg)
+{
+ s32 i = 0, j;
+
+ FillBgTilemapBufferRect(bg, 0x003, 0, 0, 32, 2, 0x11);
+
+ 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 ClearScreenInBg0(bool32 ignoreTopTwoRows)
+{
+ 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);
+}
+
+void AddTextPrinterToWindow1(const u8 *str)
+{
+ 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);
+}
+
+static void ClearTextWindow(void)
+{
+ rbox_fill_rectangle(1);
+ ClearWindowTilemap(1);
+ CopyWindowToVram(1, 1);
+}
+
+#define DOWN_ARROW_X 208
+#define DOWN_ARROW_Y 20
+
+bool32 PrintMysteryGiftMenuMessage(u8 *textState, const u8 *str)
+{
+ switch (*textState)
+ {
+ case 0:
+ AddTextPrinterToWindow1(str);
+ (*textState)++;
+ break;
+ case 1:
+ DrawDownArrow(1, DOWN_ARROW_X, DOWN_ARROW_Y, 1, FALSE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]);
+ if (({JOY_NEW(A_BUTTON | B_BUTTON);}))
+ (*textState)++;
+ break;
+ case 2:
+ DrawDownArrow(1, DOWN_ARROW_X, DOWN_ARROW_Y, 1, TRUE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]);
+ *textState = 0;
+ ClearTextWindow();
+ return TRUE;
+ case 0xFF:
+ *textState = 2;
+ return FALSE;
+ }
+ return FALSE;
+}
+
+static void HideDownArrow(void)
+{
+ DrawDownArrow(1, DOWN_ARROW_X, DOWN_ARROW_Y, 1, FALSE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]);
+}
+
+static void ShowDownArrow(void)
+{
+ DrawDownArrow(1, DOWN_ARROW_X, DOWN_ARROW_Y, 1, TRUE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]);
+}
+
+// Unused
+static bool32 HideDownArrowAndWaitButton(u8 * textState)
+{
+ switch (*textState)
+ {
+ case 0:
+ HideDownArrow();
+ if (JOY_NEW(A_BUTTON | B_BUTTON))
+ (*textState)++;
+ break;
+ case 1:
+ ShowDownArrow();
+ *textState = 0;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool32 PrintStringAndWait2Seconds(u8 * counter, const u8 * str)
+{
+ if (*counter == 0)
+ AddTextPrinterToWindow1(str);
+
+ if (++(*counter) > 120)
+ {
+ *counter = 0;
+ ClearTextWindow();
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+static u32 MysteryGift_HandleThreeOptionMenu(u8 * unused0, u16 * unused1, u8 whichMenu)
+{
+ struct ListMenuTemplate listMenuTemplate = sListMenuTemplate_ThreeOptions;
+ struct WindowTemplate windowTemplate = sWindowTemplate_ThreeOptions;
+ s32 width;
+ s32 response;
+
+ 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;
+
+ response = DoMysteryGiftListMenu(&windowTemplate, &listMenuTemplate, 1, LIST_MENU_TILE_NUM, LIST_MENU_PAL_NUM);
+ if (response != LIST_NOTHING_CHOSEN)
+ {
+ ClearWindowTilemap(2);
+ CopyWindowToVram(2, 1);
+ }
+ return response;
+}
+
+s8 DoMysteryGiftYesNo(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, const u8 * str)
+{
+ struct WindowTemplate windowTemplate;
+ s8 input;
+
+ switch (*textState)
+ {
+ case 0:
+ // Print question message
+ StringExpandPlaceholders(gStringVar4, str);
+ if (yesNoBoxPlacement == 0)
+ *windowId = AddWindow(&sWindowTemplate_YesNoMsg_Wide);
+ else
+ *windowId = AddWindow(&sWindowTemplate_YesNoMsg);
+ 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:
+ // Create Yes/No
+ windowTemplate = sWindowTemplate_YesNoBox;
+ if (yesNoBoxPlacement == 0)
+ windowTemplate.tilemapTop = 9;
+ else
+ windowTemplate.tilemapTop = 15;
+ CreateYesNoMenu(&windowTemplate, 10, 14, 0);
+ (*textState)++;
+ break;
+ case 2:
+ // Handle Yes/No input
+ input = Menu_ProcessInputNoWrapClearOnChoose();
+ if (input == MENU_B_PRESSED || input == 0 || 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 MENU_B_PRESSED;
+ }
+
+ return MENU_NOTHING_CHOSEN;
+}
+
+// Handle the "Receive/Send/Toss" menu that appears when selecting Wonder Card/News
+static s32 HandleGiftSelectMenu(u8 * textState, u16 * windowId, bool32 cannotToss, bool32 cannotSend)
+{
+ struct WindowTemplate windowTemplate;
+ s32 input;
+
+ switch (*textState)
+ {
+ case 0:
+ // Print menu message
+ if (!cannotToss)
+ StringExpandPlaceholders(gStringVar4, gText_WhatToDoWithCards);
+ else
+ StringExpandPlaceholders(gStringVar4, gText_WhatToDoWithNews);
+ *windowId = AddWindow(&sWindowTemplate_GiftSelect);
+ 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)
+ input = DoMysteryGiftListMenu(&sWindowTemplate_GiftSelect_2Options, &sListMenu_ReceiveToss, 1, LIST_MENU_TILE_NUM, LIST_MENU_PAL_NUM);
+ else
+ input = DoMysteryGiftListMenu(&sWindowTemplate_GiftSelect_1Option, &sListMenu_Receive, 1, LIST_MENU_TILE_NUM, LIST_MENU_PAL_NUM);
+ }
+ else
+ {
+ if (!cannotToss)
+ input = DoMysteryGiftListMenu(&sWindowTemplate_GiftSelect_3Options, &sListMenu_ReceiveSendToss, 1, LIST_MENU_TILE_NUM, LIST_MENU_PAL_NUM);
+ else
+ input = DoMysteryGiftListMenu(&sWindowTemplate_GiftSelect_2Options, &sListMenu_ReceiveSend, 1, LIST_MENU_TILE_NUM, LIST_MENU_PAL_NUM);
+ }
+ if (input != LIST_NOTHING_CHOSEN)
+ {
+ *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 LIST_CANCEL;
+ }
+
+ return LIST_NOTHING_CHOSEN;
+}
+
+static bool32 ValidateCardOrNews(bool32 isWonderNews)
+{
+ if (!isWonderNews)
+ return ValidateSavedWonderCard();
+ else
+ return ValidateSavedWonderNews();
+}
+
+static bool32 HandleLoadWonderCardOrNews(u8 * state, bool32 isWonderNews)
+{
+ switch (*state)
+ {
+ case 0:
+ if (!isWonderNews)
+ WonderCard_Init(GetSavedWonderCard(), GetSavedWonderCardMetadata());
+ else
+ WonderNews_Init(GetSavedWonderNews());
+ (*state)++;
+ break;
+ case 1:
+ if (!isWonderNews)
+ {
+ if (!WonderCard_Enter())
+ return FALSE;
+ }
+ else
+ {
+ if (!WonderNews_Enter())
+ return FALSE;
+ }
+ *state = 0;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static bool32 ClearSavedNewsOrCard(bool32 isWonderNews)
+{
+ if (!isWonderNews)
+ ClearSavedWonderCardAndRelated();
+ else
+ ClearSavedWonderNewsAndRelated();
+ return TRUE;
+}
+
+static bool32 ExitWonderCardOrNews(bool32 isWonderNews, bool32 useCancel)
+{
+ if (!isWonderNews)
+ {
+ if (WonderCard_Exit(useCancel))
+ {
+ WonderCard_Destroy();
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (WonderNews_Exit(useCancel))
+ {
+ WonderNews_Destroy();
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+}
+
+static s32 AskDiscardGift(u8 * textState, u16 * windowId, bool32 isWonderNews)
+{
+ if (!isWonderNews)
+ return DoMysteryGiftYesNo(textState, windowId, TRUE, gText_IfThrowAwayCardEventWontHappen);
+ else
+ return DoMysteryGiftYesNo(textState, windowId, TRUE, gText_OkayToDiscardNews);
+}
+
+static bool32 PrintThrownAway(u8 * textState, bool32 isWonderNews)
+{
+ if (!isWonderNews)
+ return PrintMysteryGiftMenuMessage(textState, gText_WonderCardThrownAway);
+ else
+ return PrintMysteryGiftMenuMessage(textState, gText_WonderNewsThrownAway);
+}
+
+static bool32 SaveOnMysteryGiftMenu(u8 * state)
+{
+ switch (*state)
+ {
+ 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))
+ (*state)++;
+ break;
+ case 4:
+ *state = 0;
+ ClearTextWindow();
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static const u8 * GetClientResultMessage(bool32 * successMsg, bool8 isWonderNews, bool8 sourceIsFriend, u32 msgId)
+{
+ const u8 * msg = NULL;
+ *successMsg = FALSE;
+
+ switch (msgId)
+ {
+ case CLI_MSG_NOTHING_SENT:
+ *successMsg = FALSE;
+ msg = gText_NothingSentOver;
+ break;
+ case CLI_MSG_RECORD_UPLOADED:
+ *successMsg = FALSE;
+ msg = gText_RecordUploadedViaWireless;
+ break;
+ case CLI_MSG_CARD_RECEIVED:
+ *successMsg = TRUE;
+ msg = !sourceIsFriend ? gText_WonderCardReceived : gText_WonderCardReceivedFrom;
+ break;
+ case CLI_MSG_NEWS_RECEIVED:
+ *successMsg = TRUE;
+ msg = !sourceIsFriend ? gText_WonderNewsReceived : gText_WonderNewsReceivedFrom;
+ break;
+ case CLI_MSG_STAMP_RECEIVED:
+ *successMsg = TRUE;
+ msg = gText_NewStampReceived;
+ break;
+ case CLI_MSG_HAD_CARD:
+ *successMsg = FALSE;
+ msg = gText_AlreadyHadCard;
+ break;
+ case CLI_MSG_HAD_STAMP:
+ *successMsg = FALSE;
+ msg = gText_AlreadyHadStamp;
+ break;
+ case CLI_MSG_HAD_NEWS:
+ *successMsg = FALSE;
+ msg = gText_AlreadyHadNews;
+ break;
+ case CLI_MSG_NO_ROOM_STAMPS:
+ *successMsg = FALSE;
+ msg = gText_NoMoreRoomForStamps;
+ break;
+ case CLI_MSG_COMM_CANCELED:
+ *successMsg = FALSE;
+ msg = gText_CommunicationCanceled;
+ break;
+ case CLI_MSG_CANT_ACCEPT:
+ *successMsg = FALSE;
+ msg = !isWonderNews ? gText_CantAcceptCardFromTrainer : gText_CantAcceptNewsFromTrainer;
+ break;
+ case CLI_MSG_COMM_ERROR:
+ *successMsg = FALSE;
+ msg = gText_CommunicationError;
+ break;
+ case CLI_MSG_TRAINER_RECEIVED:
+ *successMsg = TRUE;
+ msg = gText_NewTrainerReceived;
+ break;
+ case CLI_MSG_BUFFER_SUCCESS:
+ *successMsg = TRUE;
+ // msg is NULL, use buffer
+ break;
+ case CLI_MSG_BUFFER_FAILURE:
+ *successMsg = FALSE;
+ // msg is NULL, use buffer
+ break;
+ }
+
+ return msg;
+}
+
+static bool32 PrintSuccessMessage(u8 * state, const u8 * msg, u16 * timer)
+{
+ switch (*state)
+ {
+ case 0:
+ if (msg != NULL)
+ AddTextPrinterToWindow1(msg);
+ PlayFanfare(MUS_OBTAIN_ITEM);
+ *timer = 0;
+ (*state)++;
+ break;
+ case 1:
+ if (++(*timer) > 240)
+ (*state)++;
+ break;
+ case 2:
+ if (IsFanfareTaskInactive())
+ {
+ *state = 0;
+ ClearTextWindow();
+ return TRUE;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static const u8 * GetServerResultMessage(bool32 * wonderSuccess, bool8 sourceIsFriend, u32 msgId)
+{
+ const u8 * result = gText_CommunicationError;
+ *wonderSuccess = FALSE;
+ switch (msgId)
+ {
+ case SVR_MSG_NOTHING_SENT:
+ result = gText_NothingSentOver;
+ break;
+ case SVR_MSG_RECORD_UPLOADED:
+ result = gText_RecordUploadedViaWireless;
+ break;
+ case SVR_MSG_CARD_SENT:
+ result = gText_WonderCardSentTo;
+ *wonderSuccess = TRUE;
+ break;
+ case SVR_MSG_NEWS_SENT:
+ result = gText_WonderNewsSentTo;
+ *wonderSuccess = TRUE;
+ break;
+ case SVR_MSG_STAMP_SENT:
+ result = gText_StampSentTo;
+ break;
+ case SVR_MSG_HAS_CARD:
+ result = gText_OtherTrainerHasCard;
+ break;
+ case SVR_MSG_HAS_STAMP:
+ result = gText_OtherTrainerHasStamp;
+ break;
+ case SVR_MSG_HAS_NEWS:
+ result = gText_OtherTrainerHasNews;
+ break;
+ case SVR_MSG_NO_ROOM_STAMPS:
+ result = gText_NoMoreRoomForStamps;
+ break;
+ case SVR_MSG_CLIENT_CANCELED:
+ result = gText_OtherTrainerCanceled;
+ break;
+ case SVR_MSG_CANT_SEND_GIFT_1:
+ result = gText_CantSendGiftToTrainer;
+ break;
+ case SVR_MSG_COMM_ERROR:
+ result = gText_CommunicationError;
+ break;
+ case SVR_MSG_GIFT_SENT_1:
+ result = gText_GiftSentTo;
+ break;
+ case SVR_MSG_GIFT_SENT_2:
+ result = gText_GiftSentTo;
+ break;
+ case SVR_MSG_CANT_SEND_GIFT_2:
+ result = gText_CantSendGiftToTrainer;
+ break;
+ }
+ return result;
+}
+
+static bool32 PrintServerResultMessage(u8 * state, u16 * timer, bool8 sourceIsFriend, u32 msgId)
+{
+ bool32 wonderSuccess;
+ const u8 * str = GetServerResultMessage(&wonderSuccess, sourceIsFriend, msgId);
+ if (wonderSuccess)
+ return PrintSuccessMessage(state, str, timer);
+ else
+ return PrintMysteryGiftMenuMessage(state, str);
+}
+
+// States for Task_MysteryGift.
+// CLIENT states are for when the player is receiving a gift, and use mystery_gift_client.c link functions.
+// SERVER states are for when the player is sending a gift, and use mystery_gift_server.c link functions.
+// Other states handle the general Mystery Gift menu usage.
+enum {
+ MG_STATE_TO_MAIN_MENU,
+ MG_STATE_MAIN_MENU,
+ MG_STATE_DONT_HAVE_ANY,
+ MG_STATE_SOURCE_PROMPT,
+ MG_STATE_SOURCE_PROMPT_INPUT,
+ MG_STATE_CLIENT_LINK_START,
+ MG_STATE_CLIENT_LINK_WAIT,
+ MG_STATE_CLIENT_COMMUNICATING,
+ MG_STATE_CLIENT_LINK,
+ MG_STATE_CLIENT_YES_NO,
+ MG_STATE_CLIENT_MESSAGE,
+ MG_STATE_CLIENT_ASK_TOSS,
+ MG_STATE_CLIENT_ASK_TOSS_UNRECEIVED,
+ MG_STATE_CLIENT_LINK_END,
+ MG_STATE_CLIENT_COMM_COMPLETED,
+ MG_STATE_CLIENT_RESULT_MSG,
+ MG_STATE_CLIENT_ERROR,
+ MG_STATE_SAVE_LOAD_GIFT,
+ MG_STATE_LOAD_GIFT,
+ MG_STATE_UNUSED,
+ MG_STATE_HANDLE_GIFT_INPUT,
+ MG_STATE_HANDLE_GIFT_SELECT,
+ MG_STATE_ASK_TOSS,
+ MG_STATE_ASK_TOSS_UNRECEIVED,
+ MG_STATE_TOSS,
+ MG_STATE_TOSS_SAVE,
+ MG_STATE_TOSSED,
+ MG_STATE_GIFT_INPUT_EXIT,
+ MG_STATE_RECEIVE,
+ MG_STATE_SEND,
+ MG_STATE_SERVER_LINK_WAIT,
+ MG_STATE_SERVER_LINK_START,
+ MG_STATE_SERVER_LINK,
+ MG_STATE_SERVER_LINK_END,
+ MG_STATE_SERVER_LINK_END_WAIT,
+ MG_STATE_SERVER_RESULT_MSG,
+ MG_STATE_SERVER_ERROR,
+ MG_STATE_EXIT,
+};
+
+static void CreateMysteryGiftTask(void)
+{
+ u8 taskId = CreateTask(Task_MysteryGift, 0);
+ struct MysteryGiftTaskData * data = (void *)gTasks[taskId].data;
+ data->state = MG_STATE_TO_MAIN_MENU;
+ data->textState = 0;
+ data->unused4 = 0;
+ data->unused5 = 0;
+ data->isWonderNews = 0;
+ data->sourceIsFriend = 0;
+ data->var = 0;
+ data->unused1 = 0;
+ data->unused2 = 0;
+ data->unused3 = 0;
+ data->msgId = 0;
+ data->clientMsg = AllocZeroed(CLIENT_MAX_MSG_SIZE);
+}
+
+static void Task_MysteryGift(u8 taskId)
+{
+ struct MysteryGiftTaskData *data = (void *)gTasks[taskId].data;
+ u32 successMsg, input;
+ const u8 *msg;
+
+ switch (data->state)
+ {
+ case MG_STATE_TO_MAIN_MENU:
+ data->state = MG_STATE_MAIN_MENU;
+ break;
+ case MG_STATE_MAIN_MENU:
+ // Main Mystery Gift menu, player can select Wonder Cards or News (or exit)
+ switch (MysteryGift_HandleThreeOptionMenu(&data->textState, &data->var, FALSE))
+ {
+ case 0: // "Wonder Cards"
+ data->isWonderNews = FALSE;
+ if (ValidateSavedWonderCard() == TRUE)
+ data->state = MG_STATE_LOAD_GIFT;
+ else
+ data->state = MG_STATE_DONT_HAVE_ANY;
+ break;
+ case 1: // "Wonder News"
+ data->isWonderNews = TRUE;
+ if (ValidateSavedWonderNews() == TRUE)
+ data->state = MG_STATE_LOAD_GIFT;
+ else
+ data->state = MG_STATE_DONT_HAVE_ANY;
+ break;
+ case LIST_CANCEL:
+ data->state = MG_STATE_EXIT;
+ break;
+ }
+ break;
+ case MG_STATE_DONT_HAVE_ANY:
+ {
+ // Player doesn't have any Wonder Card/News
+ // Start prompt to ask where to read one from
+ if (!data->isWonderNews)
+ {
+ if (PrintMysteryGiftMenuMessage(&data->textState, gText_DontHaveCardNewOneInput))
+ {
+ data->state = MG_STATE_SOURCE_PROMPT;
+ PrintMysteryGiftOrEReaderTopMenu(FALSE, TRUE);
+ }
+ }
+ else
+ {
+ if (PrintMysteryGiftMenuMessage(&data->textState, gText_DontHaveNewsNewOneInput))
+ {
+ data->state = MG_STATE_SOURCE_PROMPT;
+ PrintMysteryGiftOrEReaderTopMenu(FALSE, TRUE);
+ }
+ }
+ break;
+ }
+ case MG_STATE_SOURCE_PROMPT:
+ if (!data->isWonderNews)
+ AddTextPrinterToWindow1(gText_WhereShouldCardBeAccessed);
+ else
+ AddTextPrinterToWindow1(gText_WhereShouldNewsBeAccessed);
+ data->state = MG_STATE_SOURCE_PROMPT_INPUT;
+ break;
+ case MG_STATE_SOURCE_PROMPT_INPUT:
+ // Choose where to access the Wonder Card/News from
+ switch (MysteryGift_HandleThreeOptionMenu(&data->textState, &data->var, TRUE))
+ {
+ case 0: // "Wireless Communication"
+ ClearTextWindow();
+ data->state = MG_STATE_CLIENT_LINK_START;
+ data->sourceIsFriend = FALSE;
+ break;
+ case 1: // "Friend"
+ ClearTextWindow();
+ data->state = MG_STATE_CLIENT_LINK_START;
+ data->sourceIsFriend = TRUE;
+ break;
+ case LIST_CANCEL:
+ ClearTextWindow();
+ if (ValidateCardOrNews(data->isWonderNews))
+ {
+ data->state = MG_STATE_LOAD_GIFT;
+ }
+ else
+ {
+ data->state = MG_STATE_TO_MAIN_MENU;
+ PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE);
+ }
+ break;
+ }
+ break;
+ case MG_STATE_CLIENT_LINK_START:
+ *gStringVar1 = EOS;
+ *gStringVar2 = EOS;
+ *gStringVar3 = EOS;
+
+ switch (data->isWonderNews)
+ {
+ case FALSE:
+ if (data->sourceIsFriend == TRUE)
+ CreateTask_LinkMysteryGiftWithFriend(ACTIVITY_WONDER_CARD);
+ else if (data->sourceIsFriend == FALSE)
+ CreateTask_LinkMysteryGiftOverWireless(ACTIVITY_WONDER_CARD);
+ break;
+ case TRUE:
+ if (data->sourceIsFriend == TRUE)
+ CreateTask_LinkMysteryGiftWithFriend(ACTIVITY_WONDER_NEWS);
+ else if (data->sourceIsFriend == FALSE)
+ CreateTask_LinkMysteryGiftOverWireless(ACTIVITY_WONDER_NEWS);
+ break;
+ }
+ data->state = MG_STATE_CLIENT_LINK_WAIT;
+ break;
+ case MG_STATE_CLIENT_LINK_WAIT:
+ if (gReceivedRemoteLinkPlayers != 0)
+ {
+ ClearScreenInBg0(TRUE);
+ data->state = MG_STATE_CLIENT_COMMUNICATING;
+ MysteryGiftClient_Create(data->isWonderNews);
+ }
+ else if (gSpecialVar_Result == LINKUP_FAILED)
+ {
+ // Link failed, return to link start menu
+ ClearScreenInBg0(TRUE);
+ data->state = MG_STATE_SOURCE_PROMPT;
+ }
+ break;
+ case MG_STATE_CLIENT_COMMUNICATING:
+ AddTextPrinterToWindow1(gText_Communicating);
+ data->state = MG_STATE_CLIENT_LINK;
+ break;
+ case MG_STATE_CLIENT_LINK:
+ switch (MysteryGiftClient_Run(&data->var))
+ {
+ case CLI_RET_END:
+ Rfu_SetCloseLinkCallback();
+ data->msgId = data->var;
+ data->state = MG_STATE_CLIENT_LINK_END;
+ break;
+ case CLI_RET_COPY_MSG:
+ memcpy(data->clientMsg, MysteryGiftClient_GetMsg(), 0x40);
+ MysteryGiftClient_AdvanceState();
+ break;
+ case CLI_RET_PRINT_MSG:
+ data->state = MG_STATE_CLIENT_MESSAGE;
+ break;
+ case CLI_RET_YES_NO:
+ data->state = MG_STATE_CLIENT_YES_NO;
+ break;
+ case CLI_RET_ASK_TOSS:
+ data->state = MG_STATE_CLIENT_ASK_TOSS;
+ StringCopy(gStringVar1, gLinkPlayers[0].name);
+ break;
+ }
+ break;
+ case MG_STATE_CLIENT_YES_NO:
+ input = DoMysteryGiftYesNo(&data->textState, &data->var, FALSE, MysteryGiftClient_GetMsg());
+ switch (input)
+ {
+ case 0: // Yes
+ MysteryGiftClient_SetParam(FALSE);
+ MysteryGiftClient_AdvanceState();
+ data->state = MG_STATE_CLIENT_COMMUNICATING;
+ break;
+ case 1: // No
+ case MENU_B_PRESSED:
+ MysteryGiftClient_SetParam(TRUE);
+ MysteryGiftClient_AdvanceState();
+ data->state = MG_STATE_CLIENT_COMMUNICATING;
+ break;
+ }
+ break;
+ case MG_STATE_CLIENT_MESSAGE:
+ if (PrintMysteryGiftMenuMessage(&data->textState, MysteryGiftClient_GetMsg()))
+ {
+ MysteryGiftClient_AdvanceState();
+ data->state = MG_STATE_CLIENT_COMMUNICATING;
+ }
+ break;
+ case MG_STATE_CLIENT_ASK_TOSS:
+ // Player is receiving a new Wonder Card/News but needs to toss an existing one to make room.
+ // Ask for confirmation.
+ input = DoMysteryGiftYesNo(&data->textState, &data->var, FALSE, gText_ThrowAwayWonderCard);
+ switch (input)
+ {
+ case 0: // Yes
+ if (IsSavedWonderCardGiftNotReceived() == TRUE)
+ {
+ data->state = MG_STATE_CLIENT_ASK_TOSS_UNRECEIVED;
+ }
+ else
+ {
+ MysteryGiftClient_SetParam(FALSE);
+ MysteryGiftClient_AdvanceState();
+ data->state = MG_STATE_CLIENT_COMMUNICATING;
+ }
+ break;
+ case 1: // No
+ case MENU_B_PRESSED:
+ MysteryGiftClient_SetParam(TRUE);
+ MysteryGiftClient_AdvanceState();
+ data->state = MG_STATE_CLIENT_COMMUNICATING;
+ break;
+ }
+ break;
+ case MG_STATE_CLIENT_ASK_TOSS_UNRECEIVED:
+ // Player has selected to toss a Wonder Card that they haven't received the gift for.
+ // Ask for confirmation again.
+ input = DoMysteryGiftYesNo(&data->textState, &data->var, FALSE, gText_HaventReceivedCardsGift);
+ switch (input)
+ {
+ case 0: // Yes
+ MysteryGiftClient_SetParam(FALSE);
+ MysteryGiftClient_AdvanceState();
+ data->state = MG_STATE_CLIENT_COMMUNICATING;
+ break;
+ case 1: // No
+ case MENU_B_PRESSED:
+ MysteryGiftClient_SetParam(TRUE);
+ MysteryGiftClient_AdvanceState();
+ data->state = MG_STATE_CLIENT_COMMUNICATING;
+ break;
+ }
+ break;
+ case MG_STATE_CLIENT_LINK_END:
+ if (gReceivedRemoteLinkPlayers == 0)
+ {
+ DestroyWirelessStatusIndicatorSprite();
+ data->state = MG_STATE_CLIENT_COMM_COMPLETED;
+ }
+ break;
+ case MG_STATE_CLIENT_COMM_COMPLETED:
+ if (PrintStringAndWait2Seconds(&data->textState, gText_CommunicationCompleted))
+ {
+ if (data->sourceIsFriend == TRUE)
+ StringCopy(gStringVar1, gLinkPlayers[0].name);
+ data->state = MG_STATE_CLIENT_RESULT_MSG;
+ }
+ break;
+ case MG_STATE_CLIENT_RESULT_MSG:
+ msg = GetClientResultMessage(&successMsg, data->isWonderNews, data->sourceIsFriend, data->msgId);
+ if (msg == NULL)
+ msg = data->clientMsg;
+ if (successMsg)
+ input = PrintSuccessMessage(&data->textState, msg, &data->var);
+ else
+ input = PrintMysteryGiftMenuMessage(&data->textState, msg);
+ // input var re-used, here it is TRUE if the message is finished
+ if (input)
+ {
+ if (data->msgId == CLI_MSG_NEWS_RECEIVED)
+ {
+ if (data->sourceIsFriend == TRUE)
+ GenerateRandomWonderNews(WONDER_NEWS_RECV_FRIEND);
+ else
+ GenerateRandomWonderNews(WONDER_NEWS_RECV_WIRELESS);
+ }
+ if (!successMsg)
+ {
+ // Did not receive card/news, return to main menu
+ data->state = MG_STATE_TO_MAIN_MENU;
+ PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE);
+ }
+ else
+ {
+ data->state = MG_STATE_SAVE_LOAD_GIFT;
+ }
+ }
+ break;
+ case MG_STATE_SAVE_LOAD_GIFT:
+ if (SaveOnMysteryGiftMenu(&data->textState))
+ data->state = MG_STATE_LOAD_GIFT;
+ break;
+ case MG_STATE_LOAD_GIFT:
+ if (HandleLoadWonderCardOrNews(&data->textState, data->isWonderNews))
+ data->state = MG_STATE_HANDLE_GIFT_INPUT;
+ break;
+ case MG_STATE_HANDLE_GIFT_INPUT:
+ if (!data->isWonderNews)
+ {
+ // Handle Wonder Card input
+ if (JOY_NEW(A_BUTTON))
+ data->state = MG_STATE_HANDLE_GIFT_SELECT;
+ if (JOY_NEW(B_BUTTON))
+ data->state = MG_STATE_GIFT_INPUT_EXIT;
+ }
+ else
+ {
+ switch (WonderNews_GetInput(gMain.newKeys))
+ {
+ case NEWS_INPUT_A:
+ WonderNews_RemoveScrollIndicatorArrowPair();
+ data->state = MG_STATE_HANDLE_GIFT_SELECT;
+ break;
+ case NEWS_INPUT_B:
+ data->state = MG_STATE_GIFT_INPUT_EXIT;
+ break;
+ }
+ }
+ break;
+ case MG_STATE_HANDLE_GIFT_SELECT:
+ {
+ // A Wonder Card/News has been selected, handle its menu
+ u32 result;
+ if (!data->isWonderNews)
+ {
+ if (IsSendingSavedWonderCardAllowed())
+ result = HandleGiftSelectMenu(&data->textState, &data->var, data->isWonderNews, FALSE);
+ else
+ result = HandleGiftSelectMenu(&data->textState, &data->var, data->isWonderNews, TRUE);
+ }
+ else
+ {
+ if (IsSendingSavedWonderNewsAllowed())
+ result = HandleGiftSelectMenu(&data->textState, &data->var, data->isWonderNews, FALSE);
+ else
+ result = HandleGiftSelectMenu(&data->textState, &data->var, data->isWonderNews, TRUE);
+ }
+ switch (result)
+ {
+ case 0: // Receive
+ data->state = MG_STATE_RECEIVE;
+ break;
+ case 1: // Send
+ data->state = MG_STATE_SEND;
+ break;
+ case 2: // Toss
+ data->state = MG_STATE_ASK_TOSS;
+ break;
+ case LIST_CANCEL:
+ if (data->isWonderNews == TRUE)
+ WonderNews_AddScrollIndicatorArrowPair();
+ data->state = MG_STATE_HANDLE_GIFT_INPUT;
+ break;
+ }
+ break;
+ }
+ case MG_STATE_ASK_TOSS:
+ // Player is attempting to discard a saved Wonder Card/News
+ switch (AskDiscardGift(&data->textState, &data->var, data->isWonderNews))
+ {
+ case 0: // Yes
+ if (!data->isWonderNews && IsSavedWonderCardGiftNotReceived() == TRUE)
+ data->state = MG_STATE_ASK_TOSS_UNRECEIVED;
+ else
+ data->state = MG_STATE_TOSS;
+ break;
+ case 1: // No
+ case MENU_B_PRESSED:
+ data->state = MG_STATE_HANDLE_GIFT_SELECT;
+ break;
+ }
+ break;
+ case MG_STATE_ASK_TOSS_UNRECEIVED:
+ // Player has selected to toss a Wonder Card that they haven't received the gift for.
+ // Ask for confirmation again.
+ switch ((u32)DoMysteryGiftYesNo(&data->textState, &data->var, TRUE, gText_HaventReceivedGiftOkayToDiscard))
+ {
+ case 0: // Yes
+ data->state = MG_STATE_TOSS;
+ break;
+ case 1: // No
+ case MENU_B_PRESSED:
+ data->state = MG_STATE_HANDLE_GIFT_SELECT;
+ break;
+ }
+ break;
+ case MG_STATE_TOSS:
+ if (ExitWonderCardOrNews(data->isWonderNews, TRUE))
+ {
+ ClearSavedNewsOrCard(data->isWonderNews);
+ data->state = MG_STATE_TOSS_SAVE;
+ }
+ break;
+ case MG_STATE_TOSS_SAVE:
+ if (SaveOnMysteryGiftMenu(&data->textState))
+ data->state = MG_STATE_TOSSED;
+ break;
+ case MG_STATE_TOSSED:
+ if (PrintThrownAway(&data->textState, data->isWonderNews))
+ {
+ data->state = MG_STATE_TO_MAIN_MENU;
+ PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE);
+ }
+ break;
+ case MG_STATE_GIFT_INPUT_EXIT:
+ if (ExitWonderCardOrNews(data->isWonderNews, FALSE))
+ data->state = MG_STATE_TO_MAIN_MENU;
+ break;
+ case MG_STATE_RECEIVE:
+ if (ExitWonderCardOrNews(data->isWonderNews, TRUE))
+ data->state = MG_STATE_SOURCE_PROMPT;
+ break;
+ case MG_STATE_SEND:
+ if (ExitWonderCardOrNews(data->isWonderNews, TRUE))
+ {
+ switch (data->isWonderNews)
+ {
+ case FALSE:
+ CreateTask_SendMysteryGift(ACTIVITY_WONDER_CARD);
+ break;
+ case TRUE:
+ CreateTask_SendMysteryGift(ACTIVITY_WONDER_NEWS);
+ break;
+ }
+ data->sourceIsFriend = TRUE;
+ data->state = MG_STATE_SERVER_LINK_WAIT;
+ }
+ break;
+ case MG_STATE_SERVER_LINK_WAIT:
+ if (gReceivedRemoteLinkPlayers != 0)
+ {
+ ClearScreenInBg0(TRUE);
+ data->state = MG_STATE_SERVER_LINK_START;
+ }
+ else if (gSpecialVar_Result == LINKUP_FAILED)
+ {
+ ClearScreenInBg0(TRUE);
+ data->state = MG_STATE_LOAD_GIFT;
+ }
+ break;
+ case MG_STATE_SERVER_LINK_START:
+ *gStringVar1 = EOS;
+ *gStringVar2 = EOS;
+ *gStringVar3 = EOS;
+
+ if (!data->isWonderNews)
+ {
+ AddTextPrinterToWindow1(gText_SendingWonderCard);
+ MysterGiftServer_CreateForCard();
+ }
+ else
+ {
+ AddTextPrinterToWindow1(gText_SendingWonderNews);
+ MysterGiftServer_CreateForNews();
+ }
+ data->state = MG_STATE_SERVER_LINK;
+ break;
+ case MG_STATE_SERVER_LINK:
+ if (MysterGiftServer_Run(&data->var) == SVR_RET_END)
+ {
+ data->msgId = data->var;
+ data->state = MG_STATE_SERVER_LINK_END;
+ }
+ break;
+ case MG_STATE_SERVER_LINK_END:
+ Rfu_SetCloseLinkCallback();
+ StringCopy(gStringVar1, gLinkPlayers[1].name);
+ data->state = MG_STATE_SERVER_LINK_END_WAIT;
+ break;
+ case MG_STATE_SERVER_LINK_END_WAIT:
+ if (gReceivedRemoteLinkPlayers == 0)
+ {
+ DestroyWirelessStatusIndicatorSprite();
+ data->state = MG_STATE_SERVER_RESULT_MSG;
+ }
+ break;
+ case MG_STATE_SERVER_RESULT_MSG:
+ if (PrintServerResultMessage(&data->textState, &data->var, data->sourceIsFriend, data->msgId))
+ {
+ if (data->sourceIsFriend == TRUE && data->msgId == SVR_MSG_NEWS_SENT)
+ {
+ GenerateRandomWonderNews(WONDER_NEWS_SENT);
+ data->state = MG_STATE_SAVE_LOAD_GIFT;
+ }
+ else
+ {
+ data->state = MG_STATE_TO_MAIN_MENU;
+ PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE);
+ }
+ }
+ break;
+ case MG_STATE_CLIENT_ERROR:
+ case MG_STATE_SERVER_ERROR:
+ if (PrintMysteryGiftMenuMessage(&data->textState, gText_CommunicationError))
+ {
+ data->state = MG_STATE_TO_MAIN_MENU;
+ PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE);
+ }
+ break;
+ case MG_STATE_EXIT:
+ CloseLink();
+ Free(data->clientMsg);
+ DestroyTask(taskId);
+ SetMainCallback2(MainCB_FreeAllBuffersAndReturnToInitTitleScreen);
+ break;
+ }
+}
+
+u16 GetMysteryGiftBaseBlock(void)
+{
+ return 0x1A9;
+}
+
+static void LoadMysteryGiftTextboxBorder(u8 bgId)
+{
+ DecompressAndLoadBgGfxUsingHeap(bgId, sTextboxBorder_Gfx, 0x100, 0, 0);
+}
diff --git a/src/mevent_scripts.c b/src/mystery_gift_scripts.c
index 23e0d97a5..fcd7f568d 100644
--- a/src/mevent_scripts.c
+++ b/src/mystery_gift_scripts.c
@@ -1,7 +1,7 @@
#include "global.h"
-#include "mevent_client.h"
-#include "mevent_server.h"
-#include "mevent.h"
+#include "mystery_gift_client.h"
+#include "mystery_gift_server.h"
+#include "mystery_gift.h"
static const u8 sText_CanceledReadingCard[] = _("Canceled reading\nthe Card.");
diff --git a/src/mevent_server.c b/src/mystery_gift_server.c
index 5313e02f7..0e0acb642 100644
--- a/src/mevent_server.c
+++ b/src/mystery_gift_server.c
@@ -1,9 +1,9 @@
#include "global.h"
#include "malloc.h"
#include "script.h"
-#include "mevent.h"
-#include "mevent_server.h"
-#include "mevent_server_helpers.h"
+#include "mystery_gift.h"
+#include "mystery_gift_server.h"
+#include "mystery_gift_link.h"
enum {
FUNC_INIT,
diff --git a/src/wonder_transfer.c b/src/mystery_gift_view.c
index c1fc69ca7..1bd3e2a21 100644
--- a/src/wonder_transfer.c
+++ b/src/mystery_gift_view.c
@@ -11,11 +11,11 @@
#include "text_window.h"
#include "string_util.h"
#include "link_rfu.h"
-#include "mevent.h"
#include "mystery_gift.h"
-#include "wonder_transfer.h"
+#include "mystery_gift_menu.h"
+#include "mystery_gift_view.h"
#include "constants/rgb.h"
-#include "constants/mevent.h"
+#include "constants/mystery_gift.h"
struct WonderGraphics
{
diff --git a/src/new_game.c b/src/new_game.c
index c4622820c..1362c492d 100644
--- a/src/new_game.c
+++ b/src/new_game.c
@@ -43,7 +43,7 @@
#include "player_pc.h"
#include "field_specials.h"
#include "berry_powder.h"
-#include "mevent.h"
+#include "mystery_gift.h"
#include "union_room_chat.h"
extern const u8 EventScript_ResetAllMapFlags[];
diff --git a/src/script.c b/src/script.c
index a3e223768..b10e0db49 100644
--- a/src/script.c
+++ b/src/script.c
@@ -1,7 +1,7 @@
#include "global.h"
#include "script.h"
#include "event_data.h"
-#include "mevent.h"
+#include "mystery_gift.h"
#include "util.h"
#include "constants/maps.h"
#include "constants/map_scripts.h"
diff --git a/src/trade.c b/src/trade.c
index acae292e5..3fdb15c45 100644
--- a/src/trade.c
+++ b/src/trade.c
@@ -19,8 +19,8 @@
#include "load_save.h"
#include "mail.h"
#include "main.h"
-#include "mevent.h"
#include "mystery_gift.h"
+#include "mystery_gift_menu.h"
#include "overworld.h"
#include "palette.h"
#include "party_menu.h"
diff --git a/src/union_room.c b/src/union_room.c
index 1a7ccc8e3..881a1d58e 100644
--- a/src/union_room.c
+++ b/src/union_room.c
@@ -23,8 +23,8 @@
#include "load_save.h"
#include "menu.h"
#include "menu_helpers.h"
-#include "mevent.h"
#include "mystery_gift.h"
+#include "mystery_gift_menu.h"
#include "overworld.h"
#include "palette.h"
#include "party_menu.h"
diff --git a/src/mevent_news.c b/src/wonder_news.c
index 27b22566d..ec93d293e 100644
--- a/src/mevent_news.c
+++ b/src/wonder_news.c
@@ -1,8 +1,8 @@
#include "global.h"
-#include "mevent.h"
+#include "mystery_gift.h"
#include "random.h"
#include "event_data.h"
-#include "mevent_news.h"
+#include "wonder_news.h"
/*
Wonder News related functions.