Initial mystery gift sync

This commit is contained in:
GriffinR
2022-11-19 18:52:29 -05:00
parent 3c3101b72c
commit 6d6f207eb4
24 changed files with 488 additions and 461 deletions
+4 -4
View File
@@ -208,7 +208,7 @@ MysteryEventScript_AuroraTicket::
setvaddress MysteryEventScript_AuroraTicket setvaddress MysteryEventScript_AuroraTicket
lock lock
faceplayer faceplayer
vgoto_if_set FLAG_GOT_AURORA_TICKET, AuroraTicket_Obtained vgoto_if_set FLAG_RECEIVED_AURORA_TICKET, AuroraTicket_Obtained
vgoto_if_set FLAG_FOUGHT_DEOXYS, AuroraTicket_Obtained vgoto_if_set FLAG_FOUGHT_DEOXYS, AuroraTicket_Obtained
checkitem ITEM_AURORA_TICKET, 1 checkitem ITEM_AURORA_TICKET, 1
vgoto_if_eq VAR_RESULT, TRUE, AuroraTicket_Obtained vgoto_if_eq VAR_RESULT, TRUE, AuroraTicket_Obtained
@@ -219,7 +219,7 @@ MysteryEventScript_AuroraTicket::
vgoto_if_eq VAR_RESULT, FALSE, AuroraTicket_NoBagSpace vgoto_if_eq VAR_RESULT, FALSE, AuroraTicket_NoBagSpace
giveitem ITEM_AURORA_TICKET giveitem ITEM_AURORA_TICKET
setflag FLAG_ENABLE_SHIP_BIRTH_ISLAND setflag FLAG_ENABLE_SHIP_BIRTH_ISLAND
setflag FLAG_GOT_AURORA_TICKET setflag FLAG_RECEIVED_AURORA_TICKET
vmessage sText_AuroraTicket2 vmessage sText_AuroraTicket2
waitmessage waitmessage
waitbuttonpress waitbuttonpress
@@ -266,7 +266,7 @@ MysteryEventScript_MysticTicket::
setvaddress MysteryEventScript_MysticTicket setvaddress MysteryEventScript_MysticTicket
lock lock
faceplayer faceplayer
vgoto_if_set FLAG_GOT_MYSTIC_TICKET, MysticTicket_Obtained vgoto_if_set FLAG_RECEIVED_MYSTIC_TICKET, MysticTicket_Obtained
vgoto_if_set FLAG_FOUGHT_LUGIA, MysticTicket_Obtained vgoto_if_set FLAG_FOUGHT_LUGIA, MysticTicket_Obtained
vgoto_if_set FLAG_FOUGHT_HO_OH, MysticTicket_Obtained vgoto_if_set FLAG_FOUGHT_HO_OH, MysticTicket_Obtained
checkitem ITEM_MYSTIC_TICKET, 1 checkitem ITEM_MYSTIC_TICKET, 1
@@ -278,7 +278,7 @@ MysteryEventScript_MysticTicket::
vgoto_if_eq VAR_RESULT, FALSE, MysticTicket_NoBagSpace vgoto_if_eq VAR_RESULT, FALSE, MysticTicket_NoBagSpace
giveitem ITEM_MYSTIC_TICKET giveitem ITEM_MYSTIC_TICKET
setflag FLAG_ENABLE_SHIP_NAVEL_ROCK setflag FLAG_ENABLE_SHIP_NAVEL_ROCK
setflag FLAG_GOT_MYSTIC_TICKET setflag FLAG_RECEIVED_MYSTIC_TICKET
vmessage sText_MysticTicket1 vmessage sText_MysticTicket1
waitmessage waitmessage
waitbuttonpress waitbuttonpress
+1 -1
View File
@@ -3,7 +3,7 @@ CableClub_OnTransition::
end end
CableClub_EventScript_HideOrShowMysteryGiftMan:: CableClub_EventScript_HideOrShowMysteryGiftMan::
specialvar VAR_RESULT, ValidateReceivedWonderCard specialvar VAR_RESULT, ValidateSavedWonderCard
goto_if_eq VAR_RESULT, FALSE, EventScript_HideMysteryGiftMan goto_if_eq VAR_RESULT, FALSE, EventScript_HideMysteryGiftMan
clearflag FLAG_HIDE_MG_DELIVERYMEN clearflag FLAG_HIDE_MG_DELIVERYMEN
return return
+1 -1
View File
@@ -392,7 +392,7 @@ gSpecials::
def_special Script_SetHelpContext def_special Script_SetHelpContext
def_special BackupHelpContext def_special BackupHelpContext
def_special RestoreHelpContext def_special RestoreHelpContext
def_special ValidateReceivedWonderCard def_special ValidateSavedWonderCard
def_special SetUnlockedPokedexFlags def_special SetUnlockedPokedexFlags
def_special InitUnionRoom def_special InitUnionRoom
def_special BufferUnionRoomPlayerName def_special BufferUnionRoomPlayerName
+22 -20
View File
@@ -701,26 +701,28 @@
#define FLAG_0x2A4 0x2A4 #define FLAG_0x2A4 0x2A4
#define FLAG_CAN_USE_ROCKET_HIDEOUT_LIFT 0x2A5 #define FLAG_CAN_USE_ROCKET_HIDEOUT_LIFT 0x2A5
#define FLAG_GOT_TEA 0x2A6 #define FLAG_GOT_TEA 0x2A6
#define FLAG_GOT_AURORA_TICKET 0x2A7 #define FLAG_RECEIVED_AURORA_TICKET 0x2A7
#define FLAG_GOT_MYSTIC_TICKET 0x2A8 #define FLAG_RECEIVED_MYSTIC_TICKET 0x2A8
#define FLAG_0x2A9 0x2A9 #define FLAG_RECEIVED_OLD_SEA_MAP 0x2A9
#define FLAG_0x2AA 0x2AA #define FLAG_WONDER_CARD_UNUSED_1 0x2AA
#define FLAG_0x2AB 0x2AB #define FLAG_WONDER_CARD_UNUSED_2 0x2AB
#define FLAG_0x2AC 0x2AC #define FLAG_WONDER_CARD_UNUSED_3 0x2AC
#define FLAG_0x2AD 0x2AD #define FLAG_WONDER_CARD_UNUSED_4 0x2AD
#define FLAG_0x2AE 0x2AE #define FLAG_WONDER_CARD_UNUSED_5 0x2AE
#define FLAG_0x2AF 0x2AF #define FLAG_WONDER_CARD_UNUSED_6 0x2AF
#define FLAG_0x2B0 0x2B0 #define FLAG_WONDER_CARD_UNUSED_7 0x2B0
#define FLAG_0x2B1 0x2B1 #define FLAG_WONDER_CARD_UNUSED_8 0x2B1
#define FLAG_0x2B2 0x2B2 #define FLAG_WONDER_CARD_UNUSED_9 0x2B2
#define FLAG_0x2B3 0x2B3 #define FLAG_WONDER_CARD_UNUSED_10 0x2B3
#define FLAG_0x2B4 0x2B4 #define FLAG_WONDER_CARD_UNUSED_11 0x2B4
#define FLAG_0x2B5 0x2B5 #define FLAG_WONDER_CARD_UNUSED_12 0x2B5
#define FLAG_0x2B6 0x2B6 #define FLAG_WONDER_CARD_UNUSED_13 0x2B6
#define FLAG_0x2B7 0x2B7 #define FLAG_WONDER_CARD_UNUSED_14 0x2B7
#define FLAG_0x2B8 0x2B8 #define FLAG_WONDER_CARD_UNUSED_15 0x2B8
#define FLAG_0x2B9 0x2B9 #define FLAG_WONDER_CARD_UNUSED_16 0x2B9
#define FLAG_0x2BA 0x2BA #define FLAG_WONDER_CARD_UNUSED_17 0x2BA
#define NUM_WONDER_CARD_FLAGS (1 + FLAG_WONDER_CARD_UNUSED_17 - FLAG_RECEIVED_AURORA_TICKET)
#define FLAG_GOT_POWDER_JAR 0x2BB #define FLAG_GOT_POWDER_JAR 0x2BB
#define FLAG_FOUGHT_MEWTWO 0x2BC #define FLAG_FOUGHT_MEWTWO 0x2BC
#define FLAG_FOUGHT_MOLTRES 0x2BD #define FLAG_FOUGHT_MOLTRES 0x2BD
+1 -1
View File
@@ -84,7 +84,7 @@
// Bits 12-15 are the same for the player's party. // Bits 12-15 are the same for the player's party.
// Used by Quest Log. // Used by Quest Log.
#define VAR_QUEST_LOG_MON_COUNTS 0x4027 #define VAR_QUEST_LOG_MON_COUNTS 0x4027
#define VAR_MENEWS_JISAN_STEP_COUNTER 0x4028 #define VAR_WONDER_NEWS_STEP_COUNTER 0x4028
#define VAR_0x4029 0x4029 #define VAR_0x4029 0x4029
#define VAR_0x402A 0x402A #define VAR_0x402A 0x402A
#define VAR_0x402B 0x402B #define VAR_0x402B 0x402B
+1 -1
View File
@@ -36,7 +36,7 @@ struct EasyChatWordsByLetter
u8 *CopyEasyChatWord(u8 *dest, u16 word); u8 *CopyEasyChatWord(u8 *dest, u16 word);
u8 *ConvertEasyChatWordsToString(u8 *dest, const u16 *src, u16 columns, u16 rows); u8 *ConvertEasyChatWordsToString(u8 *dest, const u16 *src, u16 columns, u16 rows);
bool8 EC_DoesEasyChatStringFitOnLine(const u16 *easyChatWords, u8 columns, u8 rows, u16 maxLength); bool8 EC_DoesEasyChatStringFitOnLine(const u16 *easyChatWords, u8 columns, u8 rows, u16 maxLength);
void EC_ResetMEventProfileMaybe(void); void InitQuestionnaireWords(void);
void InitEasyChatPhrases(void); void InitEasyChatPhrases(void);
void EnableRareWord(u8); void EnableRareWord(u8);
bool8 InitEasyChatSelection(void); bool8 InitEasyChatSelection(void);
+2 -2
View File
@@ -49,8 +49,8 @@ bool8 FlagGet(u16 id);
u16 * GetVarPointer(u16 id); u16 * GetVarPointer(u16 id);
bool32 IsMysteryGiftEnabled(void); bool32 IsMysteryGiftEnabled(void);
void ResetSpecialVars(void); void ResetSpecialVars(void);
void ResetMysteryEventFlags(void); void ClearMysteryGiftFlags(void);
void ResetMysteryEventVars(void); void ClearMysteryGiftVars(void);
bool32 IsNationalPokedexEnabled(void); bool32 IsNationalPokedexEnabled(void);
void EnableNationalPokedex_RSE(void); void EnableNationalPokedex_RSE(void);
void ClearTempFieldEventData(void); void ClearTempFieldEventData(void);
+2 -2
View File
@@ -627,7 +627,7 @@ struct FameCheckerSaveData
struct WonderNewsMetadata struct WonderNewsMetadata
{ {
u8 unk_0_0:2; u8 newsType:2;
u8 unk_0_2:3; u8 unk_0_2:3;
u8 unk_0_5:3; u8 unk_0_5:3;
u8 berry; u8 berry;
@@ -635,7 +635,7 @@ struct WonderNewsMetadata
struct WonderNews struct WonderNews
{ {
u16 newsId; u16 id;
u8 sendType; // SEND_TYPE_* u8 sendType; // SEND_TYPE_*
u8 bgType; u8 bgType;
u8 titleText[WONDER_NEWS_TEXT_LENGTH]; u8 titleText[WONDER_NEWS_TEXT_LENGTH];
+2 -1
View File
@@ -69,7 +69,8 @@ void StartTimer1(void);
void SeedRngAndSetTrainerId(void); void SeedRngAndSetTrainerId(void);
u16 GetGeneratedTrainerIdLower(void); u16 GetGeneratedTrainerIdLower(void);
extern const char RomHeaderGameCode[4]; #define GAME_CODE_LENGTH 4
extern const char RomHeaderGameCode[GAME_CODE_LENGTH];
extern const char RomHeaderSoftwareVersion; extern const char RomHeaderSoftwareVersion;
extern u8 gLinkTransferringData; extern u8 gLinkTransferringData;
+35 -33
View File
@@ -2,6 +2,8 @@
#define GUARD_MYSTERY_GIFT_H #define GUARD_MYSTERY_GIFT_H
#include "global.h" #include "global.h"
#include "main.h"
#include "constants/mystery_gift.h"
#define CARD_STAT_BATTLES_WON 0 #define CARD_STAT_BATTLES_WON 0
#define CARD_STAT_BATTLES_LOST 1 #define CARD_STAT_BATTLES_LOST 1
@@ -17,21 +19,21 @@ enum {
NEWS_INPUT_NONE = 0xFF NEWS_INPUT_NONE = 0xFF
}; };
struct MEventClientHeaderStruct struct MysteryGiftLinkGameData
{ {
u32 unk_00; u32 unk_00;
u16 unk_04; u16 unk_04;
u32 unk_08; u32 unk_08;
u16 unk_0C; u16 unk_0C;
u32 unk_10; u32 unk_10;
u16 id; u16 flagId;
u16 unk_16[4]; u16 questionnaireWords[NUM_QUESTIONNAIRE_WORDS];
struct WonderCardMetadata unk_20; struct WonderCardMetadata cardMetadata;
u8 maxDistributionMons; u8 maxStamps;
u8 playerName[7]; u8 playerName[PLAYER_NAME_LENGTH];
u8 playerTrainerId[4]; u8 playerTrainerId[TRAINER_ID_LENGTH];
u16 easyChatProfile[6]; u16 easyChatProfile[EASY_CHAT_BATTLE_WORDS_COUNT];
u8 gameCode[4]; u8 gameCode[GAME_CODE_LENGTH];
u8 version; u8 version;
}; };
@@ -66,41 +68,41 @@ extern const u16 gCard5Pal[];
struct WonderNews * GetSavedWonderNews(void); struct WonderNews * GetSavedWonderNews(void);
struct WonderCard * GetSavedWonderCard(void); struct WonderCard * GetSavedWonderCard(void);
struct WonderCardMetadata * sav1_get_mevent_buffer_2(void); struct WonderCardMetadata * GetSavedWonderCardMetadata(void);
struct WonderNewsMetadata * GetMENewsJisanStructPtr(void); struct WonderNewsMetadata * GetSavedWonderNewsMetadata(void);
bool32 OverwriteSavedWonderNewsWithReceivedNews(const struct WonderNews * src); bool32 SaveWonderNews(const struct WonderNews * news);
bool32 ValidateReceivedWonderNews(void); bool32 ValidateSavedWonderNews(void);
bool32 ValidateReceivedWonderCard(void); bool32 ValidateSavedWonderCard(void);
bool32 MEvent_HaveAlreadyReceivedWonderNews(const u8 * src); bool32 IsWonderNewsSameAsSaved(const u8 * news);
bool32 OverwriteSavedWonderCardWithReceivedCard(const struct WonderCard * data); bool32 SaveWonderCard(const struct WonderCard * card);
void MEvent_WonderCardResetUnk08_6(struct WonderCard * buffer); void DisableWonderCardSending(struct WonderCard * card);
bool32 MEvent_ReceiveDistributionMon(const u16 * data); bool32 MysteryGift_TrySaveStamp(const u16 * stamp);
void BuildMEventClientHeader(struct MEventClientHeaderStruct * data); void MysteryGift_LoadLinkGameData(struct MysteryGiftLinkGameData * data);
bool32 ValidateMEventClientHeader(const struct MEventClientHeaderStruct * data); bool32 MysteryGift_ValidateLinkGameData(const struct MysteryGiftLinkGameData * data);
u32 sub_8144418(const u16 * a0, const struct MEventClientHeaderStruct * a1, void *unused); u32 MysteryGift_CompareCardFlags(const u16 * flagId, const struct MysteryGiftLinkGameData * data, void *unused);
u32 MEvent_CanPlayerReceiveDistributionMon(const u16 * a0, const struct MEventClientHeaderStruct * a1, void *unused); u32 MysteryGift_CheckStamps(const u16 * stamp, const struct MysteryGiftLinkGameData * data, void *unused);
bool32 sub_8144474(const struct MEventClientHeaderStruct * a0, const u16 * a1); bool32 MysteryGift_DoesQuestionnaireMatch(const struct MysteryGiftLinkGameData * data, const u16 * words);
u16 sub_81444B0(const struct MEventClientHeaderStruct * a0, u32 command); u16 MysteryGift_GetCardStatFromLinkData(const struct MysteryGiftLinkGameData * data, u32 stat);
bool32 WonderCard_Init(struct WonderCard * card, struct WonderCardMetadata * metadata); bool32 WonderCard_Init(struct WonderCard * card, struct WonderCardMetadata * metadata);
bool32 WonderNews_Init(const struct WonderNews * news); bool32 WonderNews_Init(const struct WonderNews * news);
s32 WonderCard_Enter(void); s32 WonderCard_Enter(void);
s32 WonderNews_Enter(void); s32 WonderNews_Enter(void);
void DestroyWonderCard(void); void ClearSavedWonderCardAndRelated(void);
void DestroyWonderNews(void); void ClearSavedWonderNewsAndRelated(void);
void WonderCard_Destroy(void); void WonderCard_Destroy(void);
void WonderNews_Destroy(void); void WonderNews_Destroy(void);
s32 WonderCard_Exit(bool32 flag); s32 WonderCard_Exit(bool32 flag);
s32 WonderNews_Exit(bool32 flag); s32 WonderNews_Exit(bool32 flag);
bool32 CheckReceivedGiftFromWonderCard(void); bool32 IsSavedWonderCardGiftNotReceived(void);
void WonderNews_AddScrollIndicatorArrowPair(void); void WonderNews_AddScrollIndicatorArrowPair(void);
void WonderNews_RemoveScrollIndicatorArrowPair(void); void WonderNews_RemoveScrollIndicatorArrowPair(void);
bool32 WonderNews_Test_Unk_02(void); bool32 IsSendingSavedWonderNewsAllowed(void);
bool32 WonderCard_Test_Unk_08_6(void); bool32 IsSendingSavedWonderCardAllowed(void);
u32 WonderNews_GetInput(u16 input); u32 WonderNews_GetInput(u16 input);
void InitMEventData(void); void ClearMysteryGift(void);
u16 MEvent_GetBattleCardCount(u32 command); u16 MysteryGift_GetCardStat(u32 stat);
void MysteryGift_TryIncrementStat(u32 eventId, u32 trainerId); void MysteryGift_TryIncrementStat(u32 stat, u32 trainerId);
u16 *GetMEventProfileECWordsMaybe(void); u16 *GetQuestionnaireWordsPtr(void);
void MysteryGift_DisableStats(void); void MysteryGift_DisableStats(void);
bool32 MysteryGift_TryEnableStatsByFlagId(u16 flagId); bool32 MysteryGift_TryEnableStatsByFlagId(u16 flagId);
u16 GetWonderCardFlagId(void); u16 GetWonderCardFlagId(void);
+1 -1
View File
@@ -102,7 +102,7 @@ struct mevent_srv_common
void *recvBuffer; void *recvBuffer;
struct WonderCard * card; struct WonderCard * card;
struct WonderNews * news; struct WonderNews * news;
struct MEventClientHeaderStruct * mevent_unk1442cc; struct MysteryGiftLinkGameData * mevent_unk1442cc;
void *sendBuffer1; void *sendBuffer1;
u32 sendBuffer1Size; u32 sendBuffer1Size;
void *sendBuffer2; void *sendBuffer2;
+10 -3
View File
@@ -3,8 +3,15 @@
#include "global.h" #include "global.h"
void MENewsJisan_SetRandomReward(u32 a0); enum {
void MENewsJisanReset(void); WONDER_NEWS_NONE,
void MENewsJisanStepCounter(void); WONDER_NEWS_RECV_FRIEND,
WONDER_NEWS_RECV_WIRELESS,
WONDER_NEWS_SENT,
};
void WonderNews_SetReward(u32 newsType);
void WonderNews_Reset(void);
void WonderNews_IncrementStepCounter(void);
#endif //GUARD_WONDER_NEWS_H #endif //GUARD_WONDER_NEWS_H
+2 -2
View File
@@ -472,10 +472,10 @@ void InitEasyChatPhrases(void)
#endif #endif
} }
void EC_ResetMEventProfileMaybe(void) void InitQuestionnaireWords(void)
{ {
s32 i; s32 i;
u16 *ptr = GetMEventProfileECWordsMaybe(); u16 *ptr = GetQuestionnaireWordsPtr();
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
ptr[i] = EC_WORD_UNDEFINED; ptr[i] = EC_WORD_UNDEFINED;
} }
+1 -1
View File
@@ -271,7 +271,7 @@ void ShowEasyChatScreen(void)
words = gSaveBlock1Ptr->easyChatBattleLost; words = gSaveBlock1Ptr->easyChatBattleLost;
break; break;
case EASY_CHAT_TYPE_QUESTIONNAIRE: case EASY_CHAT_TYPE_QUESTIONNAIRE:
words = GetMEventProfileECWordsMaybe(); words = GetQuestionnaireWordsPtr();
break; break;
case EASY_CHAT_TYPE_MAIL: case EASY_CHAT_TYPE_MAIL:
words = gSaveBlock1Ptr->mail[gSpecialVar_0x8005].words; words = gSaveBlock1Ptr->mail[gSpecialVar_0x8005].words;
+2 -2
View File
@@ -129,7 +129,7 @@ bool32 IsMysteryGiftEnabled(void)
return FlagGet(FLAG_SYS_MYSTERY_GIFT_ENABLED); return FlagGet(FLAG_SYS_MYSTERY_GIFT_ENABLED);
} }
void ResetMysteryEventFlags(void) void ClearMysteryGiftFlags(void)
{ {
FlagClear(FLAG_MYSTERY_GIFT_DONE); FlagClear(FLAG_MYSTERY_GIFT_DONE);
FlagClear(FLAG_MYSTERY_GIFT_1); FlagClear(FLAG_MYSTERY_GIFT_1);
@@ -149,7 +149,7 @@ void ResetMysteryEventFlags(void)
FlagClear(FLAG_MYSTERY_GIFT_15); FlagClear(FLAG_MYSTERY_GIFT_15);
} }
void ResetMysteryEventVars(void) void ClearMysteryGiftVars(void)
{ {
VarSet(VAR_EVENT_PICHU_SLOT, 0); VarSet(VAR_EVENT_PICHU_SLOT, 0);
VarSet(VAR_MYSTERY_GIFT_1, 0); VarSet(VAR_MYSTERY_GIFT_1, 0);
+1 -1
View File
@@ -215,7 +215,7 @@ int ProcessPlayerFieldInput(struct FieldInput *input)
if (input->tookStep) if (input->tookStep)
{ {
IncrementGameStat(GAME_STAT_STEPS); IncrementGameStat(GAME_STAT_STEPS);
MENewsJisanStepCounter(); WonderNews_IncrementStepCounter();
IncrementRenewableHiddenItemStepCounter(); IncrementRenewableHiddenItemStepCounter();
RunMassageCooldownStepCounter(); RunMassageCooldownStepCounter();
IncrementResortGorgeousStepCounter(); IncrementResortGorgeousStepCounter();
+5 -5
View File
@@ -1955,15 +1955,15 @@ u16 BattleCardAction(void)
switch (gSpecialVar_Result) switch (gSpecialVar_Result)
{ {
case 0: case 0:
return MEvent_GetBattleCardCount(3); return MysteryGift_GetCardStat(3);
case 1: case 1:
return MEvent_GetBattleCardCount(4); return MysteryGift_GetCardStat(4);
case 2: case 2:
return MEvent_GetBattleCardCount(0); return MysteryGift_GetCardStat(0);
case 3: case 3:
return MEvent_GetBattleCardCount(1); return MysteryGift_GetCardStat(1);
case 4: case 4:
return MEvent_GetBattleCardCount(2); return MysteryGift_GetCardStat(2);
default: default:
AGB_ASSERT_EX(0, ABSPATH("scr_tool.c"), 3873); AGB_ASSERT_EX(0, ABSPATH("scr_tool.c"), 3873);
return 0; return 0;
+282 -252
View File
@@ -19,6 +19,8 @@
#include "mystery_gift.h" #include "mystery_gift.h"
#include "strings.h" #include "strings.h"
#define CALC_CRC(data) CalcCRC16WithTable((void *)&(data), sizeof(data))
struct MEventTaskData1 struct MEventTaskData1
{ {
u16 stateAdvanceDelay; u16 stateAdvanceDelay;
@@ -36,44 +38,44 @@ struct MEventTaskData1
}; };
static void Task_EReaderComm(u8 taskId); static void Task_EReaderComm(u8 taskId);
static bool32 IsReceivedWonderNewsHeaderValid(const struct WonderNews * src); static bool32 ValidateWonderNews(const struct WonderNews * src);
static void BlankWonderNews(void); static void ClearSavedWonderNews(void);
static void BlankMENewsJisan(void); static void ClearSavedWonderNewsMetadata(void);
static bool32 IsReceivedWonderCardHeaderValid(const struct WonderCard * src); static bool32 ValidateWonderCard(const struct WonderCard * src);
static void BlankSavedWonderCard(void); static void ClearSavedWonderCard(void);
static void BlankMEventBuffer2(void); static void ClearSavedWonderCardMetadata(void);
static void RecordIdOfWonderCardSender(u32 eventId, u32 trainerId, u32 *idsList, s32 count); static void IncrementCardStatForNewTrainer(u32 eventId, u32 trainerId, u32 *idsList, s32 count);
static void BlankBuffer344(void); static void ClearSavedTrainerIds(void);
extern const u8 gMultiBootProgram_EReader_Start[]; extern const u8 gMultiBootProgram_EReader_Start[];
extern const u8 gMultiBootProgram_EReader_End[]; extern const u8 gMultiBootProgram_EReader_End[];
static const u16 sGiftItemFlagIds[] = { static const u16 sReceivedGiftFlags[] = {
FLAG_GOT_AURORA_TICKET, FLAG_RECEIVED_AURORA_TICKET,
FLAG_GOT_MYSTIC_TICKET, FLAG_RECEIVED_MYSTIC_TICKET,
FLAG_0x2A9, FLAG_RECEIVED_OLD_SEA_MAP, // Not used until Emerald
FLAG_0x2AA, FLAG_WONDER_CARD_UNUSED_1,
FLAG_0x2AB, FLAG_WONDER_CARD_UNUSED_2,
FLAG_0x2AC, FLAG_WONDER_CARD_UNUSED_3,
FLAG_0x2AD, FLAG_WONDER_CARD_UNUSED_4,
FLAG_0x2AE, FLAG_WONDER_CARD_UNUSED_5,
FLAG_0x2AF, FLAG_WONDER_CARD_UNUSED_6,
FLAG_0x2B0, FLAG_WONDER_CARD_UNUSED_7,
FLAG_0x2B1, FLAG_WONDER_CARD_UNUSED_8,
FLAG_0x2B2, FLAG_WONDER_CARD_UNUSED_9,
FLAG_0x2B3, FLAG_WONDER_CARD_UNUSED_10,
FLAG_0x2B4, FLAG_WONDER_CARD_UNUSED_11,
FLAG_0x2B5, FLAG_WONDER_CARD_UNUSED_12,
FLAG_0x2B6, FLAG_WONDER_CARD_UNUSED_13,
FLAG_0x2B7, FLAG_WONDER_CARD_UNUSED_14,
FLAG_0x2B8, FLAG_WONDER_CARD_UNUSED_15,
FLAG_0x2B9, FLAG_WONDER_CARD_UNUSED_16,
FLAG_0x2BA FLAG_WONDER_CARD_UNUSED_17
}; };
struct MEvent_Str_1 sMEventSendToEReaderManager; struct MEvent_Str_1 sMEventSendToEReaderManager;
static EWRAM_DATA bool32 sReceivedWonderCardIsValid = FALSE; static EWRAM_DATA bool32 sStatsEnabled = FALSE;
void SendUnknownSerialData_Init(struct MEvent_Str_1 *mgr, size_t size, const void *data) void SendUnknownSerialData_Init(struct MEvent_Str_1 *mgr, size_t size, const void *data)
{ {
@@ -475,11 +477,11 @@ static void Task_EReaderComm(u8 taskId)
} }
} }
void InitMEventData(void) void ClearMysteryGift(void)
{ {
CpuFill32(0, &gSaveBlock1Ptr->mysteryGift, sizeof(gSaveBlock1Ptr->mysteryGift)); CpuFill32(0, &gSaveBlock1Ptr->mysteryGift, sizeof(gSaveBlock1Ptr->mysteryGift));
BlankMENewsJisan(); ClearSavedWonderNewsMetadata();
EC_ResetMEventProfileMaybe(); InitQuestionnaireWords();
} }
struct WonderNews * GetSavedWonderNews(void) struct WonderNews * GetSavedWonderNews(void)
@@ -492,301 +494,310 @@ struct WonderCard * GetSavedWonderCard(void)
return &gSaveBlock1Ptr->mysteryGift.card; return &gSaveBlock1Ptr->mysteryGift.card;
} }
struct WonderCardMetadata * sav1_get_mevent_buffer_2(void) struct WonderCardMetadata * GetSavedWonderCardMetadata(void)
{ {
return &gSaveBlock1Ptr->mysteryGift.cardMetadata; return &gSaveBlock1Ptr->mysteryGift.cardMetadata;
} }
struct WonderNewsMetadata * GetMENewsJisanStructPtr(void) struct WonderNewsMetadata * GetSavedWonderNewsMetadata(void)
{ {
return &gSaveBlock1Ptr->mysteryGift.newsMetadata; return &gSaveBlock1Ptr->mysteryGift.newsMetadata;
} }
u16 * GetMEventProfileECWordsMaybe(void) u16 * GetQuestionnaireWordsPtr(void)
{ {
return gSaveBlock1Ptr->mysteryGift.questionnaireWords; return gSaveBlock1Ptr->mysteryGift.questionnaireWords;
} }
void DestroyWonderNews(void) // Equivalent to ClearSavedWonderCardAndRelated, but nothing else to clear
void ClearSavedWonderNewsAndRelated(void)
{ {
BlankWonderNews(); ClearSavedWonderNews();
} }
bool32 OverwriteSavedWonderNewsWithReceivedNews(const struct WonderNews * src) bool32 SaveWonderNews(const struct WonderNews * news)
{ {
if (!IsReceivedWonderNewsHeaderValid(src)) if (!ValidateWonderNews(news))
return FALSE; return FALSE;
BlankWonderNews();
gSaveBlock1Ptr->mysteryGift.news = *src; ClearSavedWonderNews();
gSaveBlock1Ptr->mysteryGift.newsCrc = CalcCRC16WithTable((void *)&gSaveBlock1Ptr->mysteryGift.news, sizeof(struct WonderNews)); gSaveBlock1Ptr->mysteryGift.news = *news;
gSaveBlock1Ptr->mysteryGift.newsCrc = CALC_CRC(gSaveBlock1Ptr->mysteryGift.news);
return TRUE; return TRUE;
} }
bool32 ValidateReceivedWonderNews(void) bool32 ValidateSavedWonderNews(void)
{ {
if (CalcCRC16WithTable((void *)&gSaveBlock1Ptr->mysteryGift.news, sizeof(struct WonderNews)) != gSaveBlock1Ptr->mysteryGift.newsCrc) if (CALC_CRC(gSaveBlock1Ptr->mysteryGift.news) != gSaveBlock1Ptr->mysteryGift.newsCrc)
return FALSE; return FALSE;
if (!IsReceivedWonderNewsHeaderValid(&gSaveBlock1Ptr->mysteryGift.news)) if (!ValidateWonderNews(&gSaveBlock1Ptr->mysteryGift.news))
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
static bool32 IsReceivedWonderNewsHeaderValid(const struct WonderNews * data) static bool32 ValidateWonderNews(const struct WonderNews * news)
{ {
if (data->newsId == 0) if (news->id == 0)
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
bool32 WonderNews_Test_Unk_02(void) bool32 IsSendingSavedWonderNewsAllowed(void)
{ {
const struct WonderNews * data = &gSaveBlock1Ptr->mysteryGift.news; const struct WonderNews * news = &gSaveBlock1Ptr->mysteryGift.news;
if (data->sendType == 0) if (news->sendType == SEND_TYPE_DISALLOWED)
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
static void BlankWonderNews(void) static void ClearSavedWonderNews(void)
{ {
CpuFill32(0, GetSavedWonderNews(), sizeof(gSaveBlock1Ptr->mysteryGift.news)); CpuFill32(0, GetSavedWonderNews(), sizeof(gSaveBlock1Ptr->mysteryGift.news));
gSaveBlock1Ptr->mysteryGift.newsCrc = 0; gSaveBlock1Ptr->mysteryGift.newsCrc = 0;
} }
static void BlankMENewsJisan(void) static void ClearSavedWonderNewsMetadata(void)
{ {
CpuFill32(0, GetMENewsJisanStructPtr(), sizeof(struct WonderNewsMetadata)); CpuFill32(0, GetSavedWonderNewsMetadata(), sizeof(gSaveBlock1Ptr->mysteryGift.newsMetadata));
MENewsJisanReset(); WonderNews_Reset();
} }
bool32 MEvent_HaveAlreadyReceivedWonderNews(const u8 * src) bool32 IsWonderNewsSameAsSaved(const u8 * news)
{ {
const u8 * r5 = (const u8 *)&gSaveBlock1Ptr->mysteryGift.news; const u8 * savedNews = (const u8 *)&gSaveBlock1Ptr->mysteryGift.news;
u32 i; u32 i;
if (!ValidateReceivedWonderNews()) if (!ValidateSavedWonderNews())
return FALSE; return FALSE;
for (i = 0; i < sizeof(struct WonderNews); i++)
for (i = 0; i < sizeof(gSaveBlock1Ptr->mysteryGift.news); i++)
{ {
if (r5[i] != src[i]) if (savedNews[i] != news[i])
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
void DestroyWonderCard(void) void ClearSavedWonderCardAndRelated(void)
{ {
BlankSavedWonderCard(); ClearSavedWonderCard();
BlankMEventBuffer2(); ClearSavedWonderCardMetadata();
BlankBuffer344(); ClearSavedTrainerIds();
ClearRamScript(); ClearRamScript();
ResetMysteryEventFlags(); ClearMysteryGiftFlags();
ResetMysteryEventVars(); ClearMysteryGiftVars();
ClearEReaderTrainer(&gSaveBlock2Ptr->battleTower.ereaderTrainer); ClearEReaderTrainer(&gSaveBlock2Ptr->battleTower.ereaderTrainer);
} }
bool32 OverwriteSavedWonderCardWithReceivedCard(const struct WonderCard * data) bool32 SaveWonderCard(const struct WonderCard * card)
{ {
struct WonderCardMetadata * r2; struct WonderCardMetadata * metadata;
struct WonderCard * r1; if (!ValidateWonderCard(card))
if (!IsReceivedWonderCardHeaderValid(data))
return FALSE; return FALSE;
DestroyWonderCard();
memcpy(&gSaveBlock1Ptr->mysteryGift.card, data, sizeof(struct WonderCard)); ClearSavedWonderCardAndRelated();
gSaveBlock1Ptr->mysteryGift.cardCrc = CalcCRC16WithTable((void *)&gSaveBlock1Ptr->mysteryGift.card, sizeof(struct WonderCard)); memcpy(&gSaveBlock1Ptr->mysteryGift.card, card, sizeof(struct WonderCard));
// Annoying hack to match gSaveBlock1Ptr->mysteryGift.cardCrc = CALC_CRC(gSaveBlock1Ptr->mysteryGift.card);
r2 = &gSaveBlock1Ptr->mysteryGift.cardMetadata; metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata;
r1 = &gSaveBlock1Ptr->mysteryGift.card; metadata->iconSpecies = (&gSaveBlock1Ptr->mysteryGift.card)->iconSpecies;
r2->iconSpecies = r1->iconSpecies;
return TRUE; return TRUE;
} }
bool32 ValidateReceivedWonderCard(void) bool32 ValidateSavedWonderCard(void)
{ {
if (gSaveBlock1Ptr->mysteryGift.cardCrc != CalcCRC16WithTable((void *)&gSaveBlock1Ptr->mysteryGift.card, sizeof(struct WonderCard))) if (gSaveBlock1Ptr->mysteryGift.cardCrc != CALC_CRC(gSaveBlock1Ptr->mysteryGift.card))
return FALSE; return FALSE;
if (!IsReceivedWonderCardHeaderValid(&gSaveBlock1Ptr->mysteryGift.card)) if (!ValidateWonderCard(&gSaveBlock1Ptr->mysteryGift.card))
return FALSE; return FALSE;
if (!ValidateRamScript()) if (!ValidateRamScript())
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
static bool32 IsReceivedWonderCardHeaderValid(const struct WonderCard * data) static bool32 ValidateWonderCard(const struct WonderCard * card)
{ {
if (data->flagId == 0) if (card->flagId == 0)
return FALSE; return FALSE;
if (data->type > 2) if (card->type >= CARD_TYPE_COUNT)
return FALSE; return FALSE;
if (!(data->sendType == 0 || data->sendType == 1 || data->sendType == 2)) if (!(card->sendType == SEND_TYPE_DISALLOWED
|| card->sendType == SEND_TYPE_ALLOWED
|| card->sendType == SEND_TYPE_ALLOWED_ALWAYS))
return FALSE; return FALSE;
if (data->bgType > 7) if (card->bgType >= NUM_WONDER_BGS)
return FALSE; return FALSE;
if (data->maxStamps > 7) if (card->maxStamps > MAX_STAMP_CARD_STAMPS)
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
bool32 WonderCard_Test_Unk_08_6(void) bool32 IsSendingSavedWonderCardAllowed(void)
{ {
const struct WonderCard * data = &gSaveBlock1Ptr->mysteryGift.card; const struct WonderCard * card = &gSaveBlock1Ptr->mysteryGift.card;
if (data->sendType == 0) if (card->sendType == SEND_TYPE_DISALLOWED)
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
static void BlankSavedWonderCard(void) static void ClearSavedWonderCard(void)
{ {
CpuFill32(0, &gSaveBlock1Ptr->mysteryGift.card, sizeof(struct WonderCard)); CpuFill32(0, &gSaveBlock1Ptr->mysteryGift.card, sizeof(gSaveBlock1Ptr->mysteryGift.card));
gSaveBlock1Ptr->mysteryGift.cardCrc = 0; gSaveBlock1Ptr->mysteryGift.cardCrc = 0;
} }
static void BlankMEventBuffer2(void) static void ClearSavedWonderCardMetadata(void)
{ {
CpuFill32(0, sav1_get_mevent_buffer_2(), 18 * sizeof(u16)); CpuFill32(0, GetSavedWonderCardMetadata(), sizeof(gSaveBlock1Ptr->mysteryGift.cardMetadata));
gSaveBlock1Ptr->mysteryGift.cardMetadataCrc = 0; gSaveBlock1Ptr->mysteryGift.cardMetadataCrc = 0;
} }
u16 GetWonderCardFlagId(void) u16 GetWonderCardFlagId(void)
{ {
if (ValidateReceivedWonderCard()) if (ValidateSavedWonderCard())
return gSaveBlock1Ptr->mysteryGift.card.flagId; return gSaveBlock1Ptr->mysteryGift.card.flagId;
return 0; return 0;
} }
void MEvent_WonderCardResetUnk08_6(struct WonderCard * buffer) void DisableWonderCardSending(struct WonderCard * card)
{ {
if (buffer->sendType == 1) if (card->sendType == SEND_TYPE_ALLOWED)
buffer->sendType = 0; card->sendType = SEND_TYPE_DISALLOWED;
} }
static bool32 IsCardIdInValidRange(u16 a0) static bool32 IsWonderCardFlagIDInValidRange(u16 flagId)
{ {
if (a0 >= 1000 && a0 < 1020) if (flagId >= WONDER_CARD_FLAG_OFFSET && flagId < WONDER_CARD_FLAG_OFFSET + NUM_WONDER_CARD_FLAGS)
return TRUE; return TRUE;
return FALSE; return FALSE;
} }
bool32 CheckReceivedGiftFromWonderCard(void) bool32 IsSavedWonderCardGiftNotReceived(void)
{ {
u16 value = GetWonderCardFlagId(); u16 value = GetWonderCardFlagId();
if (!IsCardIdInValidRange(value)) if (!IsWonderCardFlagIDInValidRange(value))
return FALSE; return FALSE;
if (FlagGet(sGiftItemFlagIds[value - 1000]) == TRUE)
// If flag is set, player has received gift from this card
if (FlagGet(sReceivedGiftFlags[value - WONDER_CARD_FLAG_OFFSET]) == TRUE)
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
static s32 CountReceivedDistributionMons(const struct WonderCardMetadata * data, s32 size) static s32 GetNumStampsInMetadata(const struct WonderCardMetadata * data, s32 size)
{ {
s32 r3 = 0; s32 numStamps = 0;
s32 i; s32 i;
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
{ {
if (data->stampData[1][i] && data->stampData[0][i]) if (data->stampData[STAMP_ID][i] && data->stampData[STAMP_SPECIES][i])
r3++; numStamps++;
} }
return r3; return numStamps;
} }
static bool32 HasPlayerAlreadyReceivedDistributedMon(const struct WonderCardMetadata * data1, const u16 * data2, s32 size) static bool32 IsStampInMetadata(const struct WonderCardMetadata * metadata, const u16 * stamp, s32 maxStamps)
{ {
s32 i; s32 i;
for (i = 0; i < size; i++) for (i = 0; i < maxStamps; i++)
{ {
if (data1->stampData[1][i] == data2[1]) if (metadata->stampData[STAMP_ID][i] == stamp[STAMP_ID])
return TRUE; return TRUE;
if (data1->stampData[0][i] == data2[0]) if (metadata->stampData[STAMP_SPECIES][i] == stamp[STAMP_SPECIES])
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
} }
static bool32 IsWonderCardSpeciesValid(const u16 * data) static bool32 ValidateStamp(const u16 * stamp)
{ {
if (data[1] == 0) if (stamp[STAMP_ID] == 0)
return FALSE; return FALSE;
if (data[0] == SPECIES_NONE) if (stamp[STAMP_SPECIES] == SPECIES_NONE)
return FALSE; return FALSE;
if (data[0] >= NUM_SPECIES) if (stamp[STAMP_SPECIES] >= NUM_SPECIES)
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
static s32 ValidateCardAndCountMonsReceived(void) static s32 GetNumStampsInSavedCard(void)
{ {
struct WonderCard * data; struct WonderCard * card;
if (!ValidateReceivedWonderCard()) if (!ValidateSavedWonderCard())
return 0; return 0;
data = &gSaveBlock1Ptr->mysteryGift.card; card = &gSaveBlock1Ptr->mysteryGift.card;
if (data->type != 1) if (card->type != CARD_TYPE_STAMP)
return 0; return 0;
return CountReceivedDistributionMons(&gSaveBlock1Ptr->mysteryGift.cardMetadata, data->maxStamps); return GetNumStampsInMetadata(&gSaveBlock1Ptr->mysteryGift.cardMetadata, card->maxStamps);
} }
bool32 MEvent_ReceiveDistributionMon(const u16 * data) bool32 MysteryGift_TrySaveStamp(const u16 * stamp)
{ {
struct WonderCard * buffer = &gSaveBlock1Ptr->mysteryGift.card; struct WonderCard * card = &gSaveBlock1Ptr->mysteryGift.card;
s32 capacity = buffer->maxStamps; s32 maxStamps = card->maxStamps;
s32 i; s32 i;
if (!IsWonderCardSpeciesValid(data)) if (!ValidateStamp(stamp))
return FALSE; return FALSE;
if (HasPlayerAlreadyReceivedDistributedMon(&gSaveBlock1Ptr->mysteryGift.cardMetadata, data, capacity)) if (IsStampInMetadata(&gSaveBlock1Ptr->mysteryGift.cardMetadata, stamp, maxStamps))
return FALSE; return FALSE;
for (i = 0; i < capacity; i++) for (i = 0; i < maxStamps; i++)
{ {
if (gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[1][i] == 0 && gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[0][i] == 0) if (gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[STAMP_ID][i] == 0
&& gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[STAMP_SPECIES][i] == SPECIES_NONE)
{ {
gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[1][i] = data[1]; gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[STAMP_ID][i] = stamp[STAMP_ID];
gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[0][i] = data[0]; gSaveBlock1Ptr->mysteryGift.cardMetadata.stampData[STAMP_SPECIES][i] = stamp[STAMP_SPECIES];
return TRUE; return TRUE;
} }
} }
return FALSE; return FALSE;
} }
#define GAME_DATA_VALID_VAR 0x101
#if defined(FIRERED) #if defined(FIRERED)
#define MEVENT_HEADER_VERSION_CODE 1 #define VERSION_CODE 1
#elif defined(LEAFGREEN) #elif defined(LEAFGREEN)
#define MEVENT_HEADER_VERSION_CODE 2 #define VERSION_CODE 2
#endif #endif
void BuildMEventClientHeader(struct MEventClientHeaderStruct * data) void MysteryGift_LoadLinkGameData(struct MysteryGiftLinkGameData * data)
{ {
s32 i; s32 i;
CpuFill32(0, data, sizeof(struct MEventClientHeaderStruct)); CpuFill32(0, data, sizeof(*data));
// Magic // Magic
data->unk_00 = 0x101; data->unk_00 = GAME_DATA_VALID_VAR;
data->unk_04 = 1; data->unk_04 = 1;
data->unk_08 = 1; data->unk_08 = 1;
data->unk_0C = 1; data->unk_0C = 1;
data->unk_10 = MEVENT_HEADER_VERSION_CODE; data->unk_10 = VERSION_CODE;
// Check whether a card already exists // Check whether a card already exists
if (ValidateReceivedWonderCard()) if (ValidateSavedWonderCard())
{ {
// Populate fields // Populate fields
data->id = GetSavedWonderCard()->flagId; data->flagId = GetSavedWonderCard()->flagId;
data->unk_20 = *sav1_get_mevent_buffer_2(); data->cardMetadata = *GetSavedWonderCardMetadata();
data->maxDistributionMons = GetSavedWonderCard()->maxStamps; data->maxStamps = GetSavedWonderCard()->maxStamps;
} }
else else
data->id = 0; {
data->flagId = 0;
}
// Get something for (i = 0; i < NUM_QUESTIONNAIRE_WORDS; i++)
for (i = 0; i < 4; i++) data->questionnaireWords[i] = gSaveBlock1Ptr->mysteryGift.questionnaireWords[i];
data->unk_16[i] = gSaveBlock1Ptr->mysteryGift.questionnaireWords[i];
// Get player ID
CopyTrainerId(data->playerTrainerId, gSaveBlock2Ptr->playerTrainerId); CopyTrainerId(data->playerTrainerId, gSaveBlock2Ptr->playerTrainerId);
StringCopy(data->playerName, gSaveBlock2Ptr->playerName); StringCopy(data->playerName, gSaveBlock2Ptr->playerName);
for (i = 0; i < 6; i++) for (i = 0; i < EASY_CHAT_BATTLE_WORDS_COUNT; i++)
data->easyChatProfile[i] = gSaveBlock1Ptr->easyChatProfile[i]; data->easyChatProfile[i] = gSaveBlock1Ptr->easyChatProfile[i];
memcpy(data->gameCode, RomHeaderGameCode, 4);
memcpy(data->gameCode, RomHeaderGameCode, GAME_CODE_LENGTH);
data->version = RomHeaderSoftwareVersion; data->version = RomHeaderSoftwareVersion;
} }
bool32 ValidateMEventClientHeader(const struct MEventClientHeaderStruct * data) bool32 MysteryGift_ValidateLinkGameData(const struct MysteryGiftLinkGameData * data)
{ {
if (data->unk_00 != 0x101) if (data->unk_00 != GAME_DATA_VALID_VAR)
return FALSE; return FALSE;
if (!(data->unk_04 & 1)) if (!(data->unk_04 & 1))
return FALSE; return FALSE;
@@ -799,143 +810,154 @@ bool32 ValidateMEventClientHeader(const struct MEventClientHeaderStruct * data)
return TRUE; return TRUE;
} }
u32 sub_8144418(const u16 * a0, const struct MEventClientHeaderStruct * a1, void *unused) u32 MysteryGift_CompareCardFlags(const u16 * flagId, const struct MysteryGiftLinkGameData * data, void *unused)
{ {
if (a1->id == 0) // Has a Wonder Card already?
if (data->flagId == 0)
return 0; return 0;
if (*a0 == a1->id)
// Has this Wonder Card already?
if (*flagId == data->flagId)
return 1; return 1;
// Player has a different Wonder Card
return 2; return 2;
} }
u32 MEvent_CanPlayerReceiveDistributionMon(const u16 * a0, const struct MEventClientHeaderStruct * a1, void *unused) u32 MysteryGift_CheckStamps(const u16 * stamp, const struct MysteryGiftLinkGameData * data, void *unused)
{ {
s32 numSpaces = a1->maxDistributionMons - CountReceivedDistributionMons(&a1->unk_20, a1->maxDistributionMons); s32 stampsMissing = data->maxStamps - GetNumStampsInMetadata(&data->cardMetadata, data->maxStamps);
if (numSpaces == 0)
// Has full stamp card?
if (stampsMissing == 0)
return 1; return 1;
if (HasPlayerAlreadyReceivedDistributedMon(&a1->unk_20, a0, a1->maxDistributionMons))
// Already has stamp?
if (IsStampInMetadata(&data->cardMetadata, stamp, data->maxStamps))
return 3; return 3;
if (numSpaces == 1)
// Only 1 empty stamp left?
if (stampsMissing == 1)
return 4; return 4;
// This is a new stamp
return 2; return 2;
} }
bool32 sub_8144474(const struct MEventClientHeaderStruct * a0, const u16 * a1) bool32 MysteryGift_DoesQuestionnaireMatch(const struct MysteryGiftLinkGameData * data, const u16 * words)
{ {
s32 i; s32 i;
for (i = 0; i < 4; i++) for (i = 0; i < NUM_QUESTIONNAIRE_WORDS; i++)
{ {
if (a0->unk_16[i] != a1[i]) if (data->questionnaireWords[i] != words[i])
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
static s32 GetNumReceivedDistributionMons(const struct MEventClientHeaderStruct * a0) static s32 GetNumStampsInLinkData(const struct MysteryGiftLinkGameData * data)
{ {
return CountReceivedDistributionMons(&a0->unk_20, a0->maxDistributionMons); return GetNumStampsInMetadata(&data->cardMetadata, data->maxStamps);
} }
u16 sub_81444B0(const struct MEventClientHeaderStruct * a0, u32 command) u16 MysteryGift_GetCardStatFromLinkData(const struct MysteryGiftLinkGameData * data, u32 stat)
{ {
switch (command) switch (stat)
{ {
case 0: case CARD_STAT_BATTLES_WON:
return a0->unk_20.battlesWon; return data->cardMetadata.battlesWon;
case 1: case CARD_STAT_BATTLES_LOST:
return a0->unk_20.battlesLost; return data->cardMetadata.battlesLost;
case 2: case CARD_STAT_NUM_TRADES:
return a0->unk_20.numTrades; return data->cardMetadata.numTrades;
case 3: case CARD_STAT_NUM_STAMPS:
return GetNumReceivedDistributionMons(a0); return GetNumStampsInLinkData(data);
case 4: case CARD_STAT_MAX_STAMPS:
return a0->maxDistributionMons; return data->maxStamps;
default: default:
AGB_ASSERT_EX(0, ABSPATH("mevent.c"), 825); AGB_ASSERT_EX(0, ABSPATH("mevent.c"), 825);
return 0; return 0;
} }
} }
// Increments an interaction count in the save block static void IncrementCardStat(u32 statType)
static void IncrementBattleCardCount(u32 command)
{ {
struct WonderCard * data = &gSaveBlock1Ptr->mysteryGift.card; struct WonderCard * card = &gSaveBlock1Ptr->mysteryGift.card;
if (data->type == 2) if (card->type == CARD_TYPE_LINK_STAT)
{ {
u16 * dest = NULL; u16 * stat = NULL;
switch (command) switch (statType)
{ {
case 0: case CARD_STAT_BATTLES_WON:
dest = &gSaveBlock1Ptr->mysteryGift.cardMetadata.battlesWon; stat = &gSaveBlock1Ptr->mysteryGift.cardMetadata.battlesWon;
break; break;
case 1: case CARD_STAT_BATTLES_LOST:
dest = &gSaveBlock1Ptr->mysteryGift.cardMetadata.battlesLost; stat = &gSaveBlock1Ptr->mysteryGift.cardMetadata.battlesLost;
break; break;
case 2: case CARD_STAT_NUM_TRADES:
dest = &gSaveBlock1Ptr->mysteryGift.cardMetadata.numTrades; stat = &gSaveBlock1Ptr->mysteryGift.cardMetadata.numTrades;
break; break;
case 3: case CARD_STAT_NUM_STAMPS:
break; case CARD_STAT_MAX_STAMPS:
case 4:
break; break;
} }
if (dest == NULL) if (stat == NULL)
{ {
AGB_ASSERT_EX(0, ABSPATH("mevent.c"), 868); AGB_ASSERT_EX(0, ABSPATH("mevent.c"), 868);
} }
else if (++(*dest) > 999) else if (++(*stat) > MAX_WONDER_CARD_STAT)
{ {
*dest = 999; *stat = MAX_WONDER_CARD_STAT;
} }
} }
} }
u16 MEvent_GetBattleCardCount(u32 command) u16 MysteryGift_GetCardStat(u32 stat)
{ {
switch (command) switch (stat)
{ {
case 0: case CARD_STAT_BATTLES_WON:
{ {
struct WonderCard * data = &gSaveBlock1Ptr->mysteryGift.card; struct WonderCard * card = &gSaveBlock1Ptr->mysteryGift.card;
if (data->type == 2) if (card->type == CARD_TYPE_LINK_STAT)
{ {
struct WonderCardMetadata * buffer = &gSaveBlock1Ptr->mysteryGift.cardMetadata; struct WonderCardMetadata * metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata;
return buffer->battlesWon; return metadata->battlesWon;
} }
break; break;
} }
case 1: case CARD_STAT_BATTLES_LOST:
{ {
struct WonderCard * data = &gSaveBlock1Ptr->mysteryGift.card; struct WonderCard * card = &gSaveBlock1Ptr->mysteryGift.card;
if (data->type == 2) if (card->type == CARD_TYPE_LINK_STAT)
{ {
struct WonderCardMetadata * buffer = &gSaveBlock1Ptr->mysteryGift.cardMetadata; struct WonderCardMetadata * metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata;
return buffer->battlesLost; return metadata->battlesLost;
} }
break; break;
} }
case 2: case CARD_STAT_NUM_TRADES:
{ {
struct WonderCard * data = &gSaveBlock1Ptr->mysteryGift.card; struct WonderCard * card = &gSaveBlock1Ptr->mysteryGift.card;
if (data->type == 2) if (card->type == CARD_TYPE_LINK_STAT)
{ {
struct WonderCardMetadata * buffer = &gSaveBlock1Ptr->mysteryGift.cardMetadata; struct WonderCardMetadata * metadata = &gSaveBlock1Ptr->mysteryGift.cardMetadata;
return buffer->numTrades; return metadata->numTrades;
} }
break; break;
} }
case 3: case CARD_STAT_NUM_STAMPS:
{ {
struct WonderCard * data = &gSaveBlock1Ptr->mysteryGift.card; struct WonderCard * card = &gSaveBlock1Ptr->mysteryGift.card;
if (data->type == 1) if (card->type == CARD_TYPE_STAMP)
return ValidateCardAndCountMonsReceived(); return GetNumStampsInSavedCard();
break; break;
} }
case 4: case CARD_STAT_MAX_STAMPS:
{ {
struct WonderCard * data = &gSaveBlock1Ptr->mysteryGift.card; struct WonderCard * card = &gSaveBlock1Ptr->mysteryGift.card;
if (data->type == 1) if (card->type == CARD_TYPE_STAMP)
return data->maxStamps; return card->maxStamps;
break; break;
} }
} }
@@ -945,85 +967,93 @@ u16 MEvent_GetBattleCardCount(u32 command)
void MysteryGift_DisableStats(void) void MysteryGift_DisableStats(void)
{ {
sReceivedWonderCardIsValid = FALSE; sStatsEnabled = FALSE;
} }
bool32 MysteryGift_TryEnableStatsByFlagId(u16 flagId) bool32 MysteryGift_TryEnableStatsByFlagId(u16 flagId)
{ {
sReceivedWonderCardIsValid = FALSE; sStatsEnabled = FALSE;
if (flagId == 0) if (flagId == 0)
return FALSE; return FALSE;
if (!ValidateReceivedWonderCard()) if (!ValidateSavedWonderCard())
return FALSE; return FALSE;
if (gSaveBlock1Ptr->mysteryGift.card.flagId != flagId) if (gSaveBlock1Ptr->mysteryGift.card.flagId != flagId)
return FALSE; return FALSE;
sReceivedWonderCardIsValid = TRUE; sStatsEnabled = TRUE;
return TRUE; return TRUE;
} }
void MysteryGift_TryIncrementStat(u32 eventId, u32 trainerId) void MysteryGift_TryIncrementStat(u32 stat, u32 trainerId)
{ {
if (sReceivedWonderCardIsValid) if (sStatsEnabled)
{ {
switch (eventId) switch (stat)
{ {
case 2: // trade case CARD_STAT_NUM_TRADES:
RecordIdOfWonderCardSender(2, trainerId, gSaveBlock1Ptr->mysteryGift.trainerIds[1], 5); IncrementCardStatForNewTrainer(CARD_STAT_NUM_TRADES,
trainerId,
gSaveBlock1Ptr->mysteryGift.trainerIds[1],
ARRAY_COUNT(gSaveBlock1Ptr->mysteryGift.trainerIds[1]));
break; break;
case 0: // link win case CARD_STAT_BATTLES_WON:
RecordIdOfWonderCardSender(0, trainerId, gSaveBlock1Ptr->mysteryGift.trainerIds[0], 5); IncrementCardStatForNewTrainer(CARD_STAT_BATTLES_WON,
trainerId,
gSaveBlock1Ptr->mysteryGift.trainerIds[0],
ARRAY_COUNT(gSaveBlock1Ptr->mysteryGift.trainerIds[0]));
break; break;
case 1: // link loss case CARD_STAT_BATTLES_LOST:
RecordIdOfWonderCardSender(1, trainerId, gSaveBlock1Ptr->mysteryGift.trainerIds[0], 5); IncrementCardStatForNewTrainer(CARD_STAT_BATTLES_LOST,
trainerId,
gSaveBlock1Ptr->mysteryGift.trainerIds[0],
ARRAY_COUNT(gSaveBlock1Ptr->mysteryGift.trainerIds[0]));
break; break;
default: default:
AGB_ASSERT_EX(0, ABSPATH("mevent.c"), 988); AGB_ASSERT_EX(0, ABSPATH("mevent.c"), 988);
break;
} }
} }
} }
static void BlankBuffer344(void) static void ClearSavedTrainerIds(void)
{ {
CpuFill32(0, gSaveBlock1Ptr->mysteryGift.trainerIds, sizeof(gSaveBlock1Ptr->mysteryGift.trainerIds)); CpuFill32(0, gSaveBlock1Ptr->mysteryGift.trainerIds, sizeof(gSaveBlock1Ptr->mysteryGift.trainerIds));
} }
// Looks up trainerId in an array idsList with count elements. // Returns TRUE if it's a new trainer id, FALSE if an existing one.
// If trainerId is found, rearranges idsList to put it in the front. // In either case the given trainerId is saved in element 0
// Otherwise, drops the last element of the list and inserts static bool32 RecordTrainerId(u32 trainerId, u32 * trainerIds, s32 size)
// trainerId at the front.
// Returns TRUE in the latter case.
static bool32 PlaceTrainerIdAtFrontOfList(u32 trainerId, u32 * idsList, s32 count)
{ {
s32 i; s32 i;
s32 j; s32 j;
for (i = 0; i < count; i++) for (i = 0; i < size; i++)
{ {
if (idsList[i] == trainerId) if (trainerIds[i] == trainerId)
break; break;
} }
if (i == count)
if (i == size)
{ {
for (j = count - 1; j > 0; j--) // New trainer, shift array and insert new id at front
{ for (j = size - 1; j > 0; j--)
idsList[j] = idsList[j - 1]; trainerIds[j] = trainerIds[j - 1];
}
idsList[0] = trainerId; trainerIds[0] = trainerId;
return TRUE; return TRUE;
} }
else else
{ {
// Existing trainer, shift back to old slot and move id to front
for (j = i; j > 0; j--) for (j = i; j > 0; j--)
{ trainerIds[j] = trainerIds[j - 1];
idsList[j] = idsList[j - 1];
} trainerIds[0] = trainerId;
idsList[0] = trainerId;
return FALSE; return FALSE;
} }
} }
static void RecordIdOfWonderCardSender(u32 eventId, u32 trainerId, u32 * idsList, s32 count) static void IncrementCardStatForNewTrainer(u32 stat, u32 trainerId, u32 * trainerIds, s32 size)
{ {
if (PlaceTrainerIdAtFrontOfList(trainerId, idsList, count)) if (RecordTrainerId(trainerId, trainerIds, size))
IncrementBattleCardCount(eventId); IncrementCardStat(stat);
} }
+6 -6
View File
@@ -188,19 +188,19 @@ static u32 client_mainseq_4(struct mevent_client * svr)
svr->flag = 0; svr->flag = 0;
return 4; return 4;
case 8: case 8:
BuildMEventClientHeader(svr->sendBuffer); MysteryGift_LoadLinkGameData(svr->sendBuffer);
mevent_srv_sub_init_send(&svr->manager, 0x11, svr->sendBuffer, sizeof(struct MEventClientHeaderStruct)); mevent_srv_sub_init_send(&svr->manager, 0x11, svr->sendBuffer, sizeof(struct MysteryGiftLinkGameData));
break; break;
case 14: case 14:
mevent_client_send_word(svr, 0x13, svr->param); mevent_client_send_word(svr, 0x13, svr->param);
break; break;
case 10: case 10:
OverwriteSavedWonderCardWithReceivedCard(svr->recvBuffer); SaveWonderCard(svr->recvBuffer);
break; break;
case 9: case 9:
if (!MEvent_HaveAlreadyReceivedWonderNews(svr->recvBuffer)) if (!IsWonderNewsSameAsSaved(svr->recvBuffer))
{ {
OverwriteSavedWonderNewsWithReceivedNews(svr->recvBuffer); SaveWonderNews(svr->recvBuffer);
mevent_client_send_word(svr, 0x13, 0); mevent_client_send_word(svr, 0x13, 0);
} }
else else
@@ -212,7 +212,7 @@ static u32 client_mainseq_4(struct mevent_client * svr)
svr->flag = 0; svr->flag = 0;
break; break;
case 16: case 16:
MEvent_ReceiveDistributionMon(svr->recvBuffer); MysteryGift_TrySaveStamp(svr->recvBuffer);
break; break;
case 17: case 17:
InitRamScript_NoObjectEvent(svr->recvBuffer, 1000); InitRamScript_NoObjectEvent(svr->recvBuffer, 1000);
+14 -42
View File
@@ -784,13 +784,9 @@ s32 HandleMysteryGiftListMenu(u8 * textState, u16 * windowId, bool32 cannotToss,
bool32 ValidateCardOrNews(bool32 cardOrNews) bool32 ValidateCardOrNews(bool32 cardOrNews)
{ {
if (cardOrNews == 0) if (cardOrNews == 0)
{ return ValidateSavedWonderCard();
return ValidateReceivedWonderCard();
}
else else
{ return ValidateSavedWonderNews();
return ValidateReceivedWonderNews();
}
} }
bool32 HandleLoadWonderCardOrNews(u8 * state, bool32 cardOrNews) bool32 HandleLoadWonderCardOrNews(u8 * state, bool32 cardOrNews)
@@ -802,7 +798,7 @@ bool32 HandleLoadWonderCardOrNews(u8 * state, bool32 cardOrNews)
case 0: case 0:
if (cardOrNews == 0) if (cardOrNews == 0)
{ {
WonderCard_Init(GetSavedWonderCard(), sav1_get_mevent_buffer_2()); WonderCard_Init(GetSavedWonderCard(), GetSavedWonderCardMetadata());
} }
else else
{ {
@@ -837,13 +833,9 @@ bool32 HandleLoadWonderCardOrNews(u8 * state, bool32 cardOrNews)
bool32 DestroyNewsOrCard(bool32 cardOrNews) bool32 DestroyNewsOrCard(bool32 cardOrNews)
{ {
if (cardOrNews == 0) if (cardOrNews == 0)
{ ClearSavedWonderCardAndRelated();
DestroyWonderCard();
}
else else
{ ClearSavedWonderNewsAndRelated();
DestroyWonderNews();
}
return TRUE; return TRUE;
} }
@@ -1128,25 +1120,17 @@ void task00_mystery_gift(u8 taskId)
{ {
case 0: case 0:
data->IsCardOrNews = 0; data->IsCardOrNews = 0;
if (ValidateReceivedWonderCard() == TRUE) if (ValidateSavedWonderCard() == TRUE)
{
data->state = 18; data->state = 18;
}
else else
{
data->state = 2; data->state = 2;
}
break; break;
case 1: case 1:
data->IsCardOrNews = 1; data->IsCardOrNews = 1;
if (ValidateReceivedWonderNews() == TRUE) if (ValidateSavedWonderNews() == TRUE)
{
data->state = 18; data->state = 18;
}
else else
{
data->state = 2; data->state = 2;
}
break; break;
case -2u: case -2u:
data->state = 37; data->state = 37;
@@ -1307,7 +1291,7 @@ void task00_mystery_gift(u8 taskId)
switch (flag) switch (flag)
{ {
case 0: case 0:
if (CheckReceivedGiftFromWonderCard() == TRUE) if (IsSavedWonderCardGiftNotReceived() == TRUE)
{ {
data->state = 12; data->state = 12;
} }
@@ -1382,13 +1366,9 @@ void task00_mystery_gift(u8 taskId)
if (data->prevPromptWindowId == 3) if (data->prevPromptWindowId == 3)
{ {
if (data->source == 1) if (data->source == 1)
{ WonderNews_SetReward(1);
MENewsJisan_SetRandomReward(1);
}
else else
{ WonderNews_SetReward(2);
MENewsJisan_SetRandomReward(2);
}
} }
if (sp0 == 0) if (sp0 == 0)
{ {
@@ -1452,26 +1432,18 @@ void task00_mystery_gift(u8 taskId)
u32 result; u32 result;
if (data->IsCardOrNews == 0) if (data->IsCardOrNews == 0)
{ {
if (WonderCard_Test_Unk_08_6()) if (IsSendingSavedWonderCardAllowed())
{
result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->IsCardOrNews, FALSE); result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->IsCardOrNews, FALSE);
}
else else
{
result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->IsCardOrNews, TRUE); result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->IsCardOrNews, TRUE);
} }
}
else else
{ {
if (WonderNews_Test_Unk_02()) if (IsSendingSavedWonderNewsAllowed())
{
result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->IsCardOrNews, FALSE); result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->IsCardOrNews, FALSE);
}
else else
{
result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->IsCardOrNews, TRUE); result = HandleMysteryGiftListMenu(&data->textState, &data->curPromptWindowId, data->IsCardOrNews, TRUE);
} }
}
switch (result) switch (result)
{ {
case 0: case 0:
@@ -1497,7 +1469,7 @@ void task00_mystery_gift(u8 taskId)
switch (mevent_message_prompt_discard(&data->textState, &data->curPromptWindowId, data->IsCardOrNews)) switch (mevent_message_prompt_discard(&data->textState, &data->curPromptWindowId, data->IsCardOrNews))
{ {
case 0: case 0:
if (data->IsCardOrNews == 0 && CheckReceivedGiftFromWonderCard() == TRUE) if (data->IsCardOrNews == 0 && IsSavedWonderCardGiftNotReceived() == TRUE)
{ {
data->state = 23; data->state = 23;
} }
@@ -1628,7 +1600,7 @@ void task00_mystery_gift(u8 taskId)
{ {
if (data->source == 1 && data->prevPromptWindowId == 3) if (data->source == 1 && data->prevPromptWindowId == 3)
{ {
MENewsJisan_SetRandomReward(3); WonderNews_SetReward(3);
data->state = 17; data->state = 17;
} }
else else
+8 -8
View File
@@ -48,7 +48,7 @@ static void mevent_srv_init_common(struct mevent_srv_common * svr, const void *c
svr->card = AllocZeroed(sizeof(struct WonderCard)); svr->card = AllocZeroed(sizeof(struct WonderCard));
svr->news = AllocZeroed(sizeof(struct WonderNews)); svr->news = AllocZeroed(sizeof(struct WonderNews));
svr->recvBuffer = AllocZeroed(ME_SEND_BUF_SIZE); svr->recvBuffer = AllocZeroed(ME_SEND_BUF_SIZE);
svr->mevent_unk1442cc = AllocZeroed(sizeof(struct MEventClientHeaderStruct)); svr->mevent_unk1442cc = AllocZeroed(sizeof(struct MysteryGiftLinkGameData));
svr->cmdBuffer = cmdBuffer; svr->cmdBuffer = cmdBuffer;
svr->cmdidx = 0; svr->cmdidx = 0;
mevent_srv_sub_init(&svr->manager, sendPlayerNo, recvPlayerNo); mevent_srv_sub_init(&svr->manager, sendPlayerNo, recvPlayerNo);
@@ -145,12 +145,12 @@ static u32 common_mainseq_4(struct mevent_srv_common * svr)
case 5: case 5:
AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 376); AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 376);
AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 377); AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 377);
memcpy(svr->mevent_unk1442cc, svr->recvBuffer, sizeof(struct MEventClientHeaderStruct)); memcpy(svr->mevent_unk1442cc, svr->recvBuffer, sizeof(struct MysteryGiftLinkGameData));
break; break;
case 6: case 6:
AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 382); AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 382);
AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 383); AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 383);
svr->param = ValidateMEventClientHeader(svr->mevent_unk1442cc); svr->param = MysteryGift_ValidateLinkGameData(svr->mevent_unk1442cc);
break; break;
case 4: case 4:
if (svr->param == cmd->flag) if (svr->param == cmd->flag)
@@ -162,7 +162,7 @@ static u32 common_mainseq_4(struct mevent_srv_common * svr)
case 7: case 7:
AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 396); AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 396);
ptr = mevent_first_if_not_null_else_second(cmd->parameter, svr->card); ptr = mevent_first_if_not_null_else_second(cmd->parameter, svr->card);
svr->param = sub_8144418(ptr, svr->mevent_unk1442cc, ptr); svr->param = MysteryGift_CompareCardFlags(ptr, svr->mevent_unk1442cc, ptr);
break; break;
case 8: case 8:
AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 402); AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 402);
@@ -172,15 +172,15 @@ static u32 common_mainseq_4(struct mevent_srv_common * svr)
case 9: case 9:
AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 408); AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 408);
ptr = mevent_first_if_not_null_else_second(cmd->parameter, &svr->sendWord); ptr = mevent_first_if_not_null_else_second(cmd->parameter, &svr->sendWord);
svr->param = MEvent_CanPlayerReceiveDistributionMon(ptr, svr->mevent_unk1442cc, ptr); svr->param = MysteryGift_CheckStamps(ptr, svr->mevent_unk1442cc, ptr);
break; break;
case 10: case 10:
AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 415); AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 415);
svr->param = sub_81444B0(svr->mevent_unk1442cc, cmd->flag); svr->param = MysteryGift_GetCardStatFromLinkData(svr->mevent_unk1442cc, cmd->flag);
break; break;
case 11: case 11:
AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 420); AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 420);
svr->param = sub_8144474(svr->mevent_unk1442cc, cmd->parameter); svr->param = MysteryGift_DoesQuestionnaireMatch(svr->mevent_unk1442cc, cmd->parameter);
break; break;
case 12: case 12:
AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 426); AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 426);
@@ -243,7 +243,7 @@ static u32 common_mainseq_4(struct mevent_srv_common * svr)
case 26: case 26:
AGB_ASSERT_EX(cmd->flag == FALSE && cmd->parameter == NULL, ABSPATH("mevent_server.c"), 506); AGB_ASSERT_EX(cmd->flag == FALSE && cmd->parameter == NULL, ABSPATH("mevent_server.c"), 506);
memcpy(svr->card, GetSavedWonderCard(), 332); memcpy(svr->card, GetSavedWonderCard(), 332);
MEvent_WonderCardResetUnk08_6(svr->card); DisableWonderCardSending(svr->card);
break; break;
case 27: case 27:
AGB_ASSERT_EX(cmd->flag == FALSE && cmd->parameter == NULL, ABSPATH("mevent_server.c"), 512); AGB_ASSERT_EX(cmd->flag == FALSE && cmd->parameter == NULL, ABSPATH("mevent_server.c"), 512);
+1 -1
View File
@@ -143,7 +143,7 @@ void NewGameInitData(void)
ResetTrainerFanClub(); ResetTrainerFanClub();
UnionRoomChat_InitializeRegisteredTexts(); UnionRoomChat_InitializeRegisteredTexts();
ResetMiniGamesResults(); ResetMiniGamesResults();
InitMEventData(); ClearMysteryGift();
SetAllRenewableItemFlags(); SetAllRenewableItemFlags();
WarpToPlayersRoom(); WarpToPlayersRoom();
RunScriptImmediately(EventScript_ResetAllMapFlags); RunScriptImmediately(EventScript_ResetAllMapFlags);
+2 -2
View File
@@ -2,12 +2,12 @@
#include "script.h" #include "script.h"
#include "event_data.h" #include "event_data.h"
#include "quest_log.h" #include "quest_log.h"
#include "mystery_gift.h"
#include "constants/maps.h" #include "constants/maps.h"
#include "constants/map_scripts.h" #include "constants/map_scripts.h"
extern void ResetContextNpcTextColor(void); // field_specials extern void ResetContextNpcTextColor(void); // field_specials
extern u16 CalcCRC16WithTable(u8 *data, int length); // util extern u16 CalcCRC16WithTable(u8 *data, int length); // util
extern bool32 ValidateReceivedWonderCard(void);
#define RAM_SCRIPT_MAGIC 51 #define RAM_SCRIPT_MAGIC 51
@@ -554,7 +554,7 @@ bool32 ValidateRamScript(void)
u8 *GetSavedRamScriptIfValid(void) u8 *GetSavedRamScriptIfValid(void)
{ {
struct RamScriptData *scriptData = &gSaveBlock1Ptr->ramScript.data; struct RamScriptData *scriptData = &gSaveBlock1Ptr->ramScript.data;
if (!ValidateReceivedWonderCard()) if (!ValidateSavedWonderCard())
return NULL; return NULL;
if (scriptData->magic != RAM_SCRIPT_MAGIC) if (scriptData->magic != RAM_SCRIPT_MAGIC)
return NULL; return NULL;
+55 -42
View File
@@ -5,85 +5,100 @@
#include "wonder_news.h" #include "wonder_news.h"
#include "constants/items.h" #include "constants/items.h"
/*
Wonder News related functions.
Because this feature is largely unused, the names in here are
mostly nebulous and without a real indication of purpose.
*/
enum {
NEWS_VAL_INVALID,
NEWS_VAL_RECV_FRIEND,
NEWS_VAL_RECV_WIRELESS,
NEWS_VAL_NONE,
NEWS_VAL_SENT,
NEWS_VAL_SENT_MAX,
NEWS_VAL_GET_MAX,
};
static u32 GetMENewsJisanRewardItem(struct WonderNewsMetadata *); static u32 GetMENewsJisanRewardItem(struct WonderNewsMetadata *);
static void MENewsJisanIncrementCounterUnk0_5(struct WonderNewsMetadata *); static void MENewsJisanIncrementCounterUnk0_5(struct WonderNewsMetadata *);
static u32 GetMENewsJisanState(struct WonderNewsMetadata *); static u32 GetMENewsJisanState(struct WonderNewsMetadata *);
static void MENewsJisanIncrementCounterUnk0_2(struct WonderNewsMetadata *); static void MENewsJisanIncrementCounterUnk0_2(struct WonderNewsMetadata *);
static void MENewsJisanResetCounterUnk0_2(struct WonderNewsMetadata *); static void MENewsJisanResetCounterUnk0_2(struct WonderNewsMetadata *);
void MENewsJisan_SetRandomReward(u32 a0) void WonderNews_SetReward(u32 newsType)
{ {
struct WonderNewsMetadata *r5 = GetMENewsJisanStructPtr(); struct WonderNewsMetadata *data = GetSavedWonderNewsMetadata();
r5->unk_0_0 = a0; data->newsType = newsType;
switch (a0) switch (newsType)
{ {
case 0: case WONDER_NEWS_NONE:
break; break;
case 1: case WONDER_NEWS_RECV_FRIEND:
case 2: case WONDER_NEWS_RECV_WIRELESS:
r5->berry = (Random() % 15) + ITEM_TO_BERRY(ITEM_RAZZ_BERRY); data->berry = (Random() % 15) + ITEM_TO_BERRY(ITEM_RAZZ_BERRY);
break; break;
case 3: case WONDER_NEWS_SENT:
r5->berry = (Random() % 15) + ITEM_TO_BERRY(ITEM_CHERI_BERRY); data->berry = (Random() % 15) + ITEM_TO_BERRY(ITEM_CHERI_BERRY);
break; break;
} }
} }
void MENewsJisanReset(void) void WonderNews_Reset(void)
{ {
struct WonderNewsMetadata *r5 = GetMENewsJisanStructPtr(); struct WonderNewsMetadata *r5 = GetSavedWonderNewsMetadata();
r5->unk_0_0 = 0; r5->newsType = 0;
r5->unk_0_2 = 0; r5->unk_0_2 = 0;
r5->unk_0_5 = 0; r5->unk_0_5 = 0;
r5->berry = 0; r5->berry = 0;
VarSet(VAR_MENEWS_JISAN_STEP_COUNTER, 0); VarSet(VAR_WONDER_NEWS_STEP_COUNTER, 0);
} }
void MENewsJisanStepCounter(void) void WonderNews_IncrementStepCounter(void)
{ {
u16 *r4 = GetVarPointer(VAR_MENEWS_JISAN_STEP_COUNTER); u16 *stepCounter = GetVarPointer(VAR_WONDER_NEWS_STEP_COUNTER);
struct WonderNewsMetadata *r2 = GetMENewsJisanStructPtr(); struct WonderNewsMetadata *data = GetSavedWonderNewsMetadata();
struct WonderNewsMetadata r0 = *r2;
if ((u8)r0.unk_0_5 > 4 && ++(*r4) >= 500) if (data->unk_0_5 > 4 && ++(*stepCounter) >= 500)
{ {
r2->unk_0_5 = 0; data->unk_0_5 = 0;
*r4 = 0; *stepCounter = 0;
} }
} }
u16 GetMENewsJisanItemAndState(void) u16 GetMENewsJisanItemAndState(void)
{ {
u16 *r6 = &gSpecialVar_Result; u16 *result = &gSpecialVar_Result;
struct WonderNewsMetadata *r4 = GetMENewsJisanStructPtr(); struct WonderNewsMetadata *data = GetSavedWonderNewsMetadata();
u16 r5; u16 r5;
if (!IsMysteryGiftEnabled() || !ValidateReceivedWonderNews()) if (!IsMysteryGiftEnabled() || !ValidateSavedWonderNews())
return 0; return 0;
r5 = GetMENewsJisanState(r4); r5 = GetMENewsJisanState(data);
switch (r5) switch (r5)
{ {
case 0: case 0:
break; break;
case 1: case 1:
*r6 = GetMENewsJisanRewardItem(r4); *result = GetMENewsJisanRewardItem(data);
break; break;
case 2: case 2:
*r6 = GetMENewsJisanRewardItem(r4); *result = GetMENewsJisanRewardItem(data);
break; break;
case 3: case 3:
break; break;
case 4: case 4:
*r6 = GetMENewsJisanRewardItem(r4); *result = GetMENewsJisanRewardItem(data);
MENewsJisanIncrementCounterUnk0_2(r4); MENewsJisanIncrementCounterUnk0_2(data);
break; break;
case 5: case 5:
*r6 = GetMENewsJisanRewardItem(r4); *result = GetMENewsJisanRewardItem(data);
MENewsJisanResetCounterUnk0_2(r4); MENewsJisanResetCounterUnk0_2(data);
break; break;
case 6: case 6:
break; break;
@@ -96,7 +111,7 @@ static u32 GetMENewsJisanRewardItem(struct WonderNewsMetadata *a0)
{ {
u32 r4; u32 r4;
a0->unk_0_0 = 0; a0->newsType = 0;
r4 = a0->berry + FIRST_BERRY_INDEX - 1; r4 = a0->berry + FIRST_BERRY_INDEX - 1;
a0->berry = 0; a0->berry = 0;
MENewsJisanIncrementCounterUnk0_5(a0); MENewsJisanIncrementCounterUnk0_5(a0);
@@ -122,23 +137,21 @@ static void MENewsJisanIncrementCounterUnk0_5(struct WonderNewsMetadata *a0)
a0->unk_0_5 = 5; a0->unk_0_5 = 5;
} }
static u32 GetMENewsJisanState(struct WonderNewsMetadata *a0) static u32 GetMENewsJisanState(struct WonderNewsMetadata *data)
{ {
struct WonderNewsMetadata r0; if (data->unk_0_5 == 5)
if ((u8)a0->unk_0_5 == 5)
return 6; return 6;
r0 = *a0; switch (data->newsType)
switch (r0.unk_0_0)
{ {
case 0: case WONDER_NEWS_NONE:
return 3; return 3;
case 1: case WONDER_NEWS_RECV_FRIEND:
return 1; return 1;
case 2: case WONDER_NEWS_RECV_WIRELESS:
return 2; return 2;
case 3: case WONDER_NEWS_SENT:
if ((u8)r0.unk_0_2 < 3) if (data->unk_0_2 < 3)
return 4; return 4;
return 5; return 5;
default: default: