Merge branch 'master' into sync-text
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
gEReaderData
|
||||||
@@ -1 +0,0 @@
|
|||||||
sMEventSendToEReaderManager
|
|
||||||
@@ -36,6 +36,7 @@
|
|||||||
#include "constants/easy_chat.h"
|
#include "constants/easy_chat.h"
|
||||||
#include "constants/trainer_card.h"
|
#include "constants/trainer_card.h"
|
||||||
#include "constants/help_system.h"
|
#include "constants/help_system.h"
|
||||||
|
#include "constants/mystery_gift.h"
|
||||||
.include "asm/macros.inc"
|
.include "asm/macros.inc"
|
||||||
.include "asm/macros/event.inc"
|
.include "asm/macros/event.inc"
|
||||||
.set FALSE, 0
|
.set FALSE, 0
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
.set LOCALID_WONDER_NEWS_BERRY_MAN, 1
|
.set LOCALID_WONDER_NEWS_BERRY_MAN, 1
|
||||||
|
|
||||||
|
.set REWARD_TYPE, VAR_0x8004
|
||||||
|
.set REWARD_ITEM, VAR_0x8008
|
||||||
|
|
||||||
CeruleanCity_House4_MapScripts::
|
CeruleanCity_House4_MapScripts::
|
||||||
.byte 0
|
.byte 0
|
||||||
|
|
||||||
@@ -7,62 +10,69 @@ CeruleanCity_House4_EventScript_WonderNewsBerryMan::
|
|||||||
goto_if_questlog EventScript_ReleaseEnd
|
goto_if_questlog EventScript_ReleaseEnd
|
||||||
special QuestLog_CutRecording
|
special QuestLog_CutRecording
|
||||||
lock
|
lock
|
||||||
specialvar VAR_0x8004, GetMENewsJisanItemAndState
|
specialvar REWARD_TYPE, WonderNews_GetRewardInfo
|
||||||
copyvar VAR_0x8008, VAR_RESULT
|
copyvar REWARD_ITEM, VAR_RESULT
|
||||||
goto_if_eq VAR_0x8004, 0, CeruleanCity_House4_EventScript_NoNews
|
goto_if_eq REWARD_TYPE, NEWS_REWARD_NONE, CeruleanCity_House4_EventScript_NoNews
|
||||||
goto_if_eq VAR_0x8004, 1, CeruleanCity_House4_EventScript_News1
|
goto_if_eq REWARD_TYPE, NEWS_REWARD_RECV_SMALL, CeruleanCity_House4_EventScript_Reward_RecvSmall
|
||||||
goto_if_eq VAR_0x8004, 2, CeruleanCity_House4_EventScript_News2
|
goto_if_eq REWARD_TYPE, NEWS_REWARD_RECV_BIG, CeruleanCity_House4_EventScript_Reward_RecvBig
|
||||||
goto_if_eq VAR_0x8004, 3, CeruleanCity_House4_EventScript_NewsNotSpread
|
goto_if_eq REWARD_TYPE, NEWS_REWARD_WAITING, CeruleanCity_House4_EventScript_Waiting
|
||||||
goto_if_eq VAR_0x8004, 4, CeruleanCity_House4_EventScript_NewsSpread1
|
goto_if_eq REWARD_TYPE, NEWS_REWARD_SENT_SMALL, CeruleanCity_House4_EventScript_Reward_SentSmall
|
||||||
goto_if_eq VAR_0x8004, 5, CeruleanCity_House4_EventScript_NewsSpread2
|
goto_if_eq REWARD_TYPE, NEWS_REWARD_SENT_BIG, CeruleanCity_House4_EventScript_Reward_SentBig
|
||||||
goto_if_eq VAR_0x8004, 6, CeruleanCity_House4_EventScript_NewsDone
|
goto_if_eq REWARD_TYPE, NEWS_REWARD_AT_MAX, CeruleanCity_House4_EventScript_AtMax
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ Mystery Gift is not enabled, or the player has no saved Wonder News
|
||||||
CeruleanCity_House4_EventScript_NoNews::
|
CeruleanCity_House4_EventScript_NoNews::
|
||||||
msgbox CeruleanCity_House4_Text_NothingEntertaining
|
msgbox CeruleanCity_House4_Text_NothingEntertaining
|
||||||
release
|
release
|
||||||
end
|
end
|
||||||
|
|
||||||
CeruleanCity_House4_EventScript_News1::
|
@ Small reward for receiving Wonder News from friend
|
||||||
|
CeruleanCity_House4_EventScript_Reward_RecvSmall::
|
||||||
call CeruleanCity_House4_EventScript_MovementReactionToNews
|
call CeruleanCity_House4_EventScript_MovementReactionToNews
|
||||||
msgbox CeruleanCity_House4_Text_NewNewsInformativeHaveThis
|
msgbox CeruleanCity_House4_Text_NewNewsInformativeHaveThis
|
||||||
giveitem VAR_0x8008
|
giveitem REWARD_ITEM
|
||||||
goto_if_eq VAR_RESULT, FALSE, CeruleanCity_House4_EventScript_NoRoomForBerries
|
goto_if_eq VAR_RESULT, FALSE, CeruleanCity_House4_EventScript_NoRoomForBerries
|
||||||
release
|
release
|
||||||
end
|
end
|
||||||
|
|
||||||
CeruleanCity_House4_EventScript_News2::
|
@ Big reward for receiving Wonder News from non-friend source
|
||||||
|
CeruleanCity_House4_EventScript_Reward_RecvBig::
|
||||||
call CeruleanCity_House4_EventScript_MovementReactionToNews
|
call CeruleanCity_House4_EventScript_MovementReactionToNews
|
||||||
msgbox CeruleanCity_House4_Text_IncredibleNewsHaveBerries
|
msgbox CeruleanCity_House4_Text_IncredibleNewsHaveBerries
|
||||||
giveitem VAR_0x8008, 4
|
giveitem REWARD_ITEM, 4
|
||||||
goto_if_eq VAR_RESULT, FALSE, CeruleanCity_House4_EventScript_NoRoomForBerries
|
goto_if_eq VAR_RESULT, FALSE, CeruleanCity_House4_EventScript_NoRoomForBerries
|
||||||
release
|
release
|
||||||
end
|
end
|
||||||
|
|
||||||
CeruleanCity_House4_EventScript_NewsNotSpread::
|
@ Player has not recently sent Wonder News
|
||||||
|
CeruleanCity_House4_EventScript_Waiting::
|
||||||
applymovement LOCALID_WONDER_NEWS_BERRY_MAN, Common_Movement_FacePlayer
|
applymovement LOCALID_WONDER_NEWS_BERRY_MAN, Common_Movement_FacePlayer
|
||||||
waitmovement 0
|
waitmovement 0
|
||||||
msgbox CeruleanCity_House4_Text_WishCouldShareNewsWithOthers
|
msgbox CeruleanCity_House4_Text_WishCouldShareNewsWithOthers
|
||||||
release
|
release
|
||||||
end
|
end
|
||||||
|
|
||||||
CeruleanCity_House4_EventScript_NewsSpread1::
|
@ Small reward for sending Wonder News every 1-3 times
|
||||||
|
CeruleanCity_House4_EventScript_Reward_SentSmall::
|
||||||
call CeruleanCity_House4_EventScript_MovementReactionToNews
|
call CeruleanCity_House4_EventScript_MovementReactionToNews
|
||||||
msgbox CeruleanCity_House4_Text_ThanksForSpreadingNewsTakeThis
|
msgbox CeruleanCity_House4_Text_ThanksForSpreadingNewsTakeThis
|
||||||
giveitem VAR_0x8008
|
giveitem REWARD_ITEM
|
||||||
goto_if_eq VAR_RESULT, FALSE, CeruleanCity_House4_EventScript_NoRoomForBerries
|
goto_if_eq VAR_RESULT, FALSE, CeruleanCity_House4_EventScript_NoRoomForBerries
|
||||||
release
|
release
|
||||||
end
|
end
|
||||||
|
|
||||||
CeruleanCity_House4_EventScript_NewsSpread2::
|
@ Big reward for sending Wonder News every 4th time
|
||||||
|
CeruleanCity_House4_EventScript_Reward_SentBig::
|
||||||
call CeruleanCity_House4_EventScript_MovementReactionToNews
|
call CeruleanCity_House4_EventScript_MovementReactionToNews
|
||||||
msgbox CeruleanCity_House4_Text_MagnificentNewsSpreadHaveBerries
|
msgbox CeruleanCity_House4_Text_MagnificentNewsSpreadHaveBerries
|
||||||
giveitem VAR_0x8008, 4
|
giveitem REWARD_ITEM, 4
|
||||||
goto_if_eq VAR_RESULT, FALSE, CeruleanCity_House4_EventScript_NoRoomForBerries
|
goto_if_eq VAR_RESULT, FALSE, CeruleanCity_House4_EventScript_NoRoomForBerries
|
||||||
release
|
release
|
||||||
end
|
end
|
||||||
|
|
||||||
CeruleanCity_House4_EventScript_NewsDone::
|
@ Player has hit reward limit and must wait to receive new rewards
|
||||||
|
CeruleanCity_House4_EventScript_AtMax::
|
||||||
applymovement LOCALID_WONDER_NEWS_BERRY_MAN, Common_Movement_FacePlayer
|
applymovement LOCALID_WONDER_NEWS_BERRY_MAN, Common_Movement_FacePlayer
|
||||||
waitmovement 0
|
waitmovement 0
|
||||||
msgbox CeruleanCity_House4_Text_EnjoyingMyselfWithAllSortsOfNews
|
msgbox CeruleanCity_House4_Text_EnjoyingMyselfWithAllSortsOfNews
|
||||||
|
|||||||
@@ -17,9 +17,9 @@
|
|||||||
MysteryEventScript_StampCard::
|
MysteryEventScript_StampCard::
|
||||||
setvaddress MysteryEventScript_StampCard
|
setvaddress MysteryEventScript_StampCard
|
||||||
setorcopyvar VAR_RESULT, 1
|
setorcopyvar VAR_RESULT, 1
|
||||||
specialvar VAR_0x8008, BattleCardAction
|
specialvar VAR_0x8008, GetMysteryGiftCardStat
|
||||||
setorcopyvar VAR_RESULT, 0
|
setorcopyvar VAR_RESULT, 0
|
||||||
specialvar VAR_0x8009, BattleCardAction
|
specialvar VAR_0x8009, GetMysteryGiftCardStat
|
||||||
subvar VAR_0x8008, VAR_0x8009
|
subvar VAR_0x8008, VAR_0x8009
|
||||||
buffernumberstring STR_VAR_1, VAR_0x8008
|
buffernumberstring STR_VAR_1, VAR_0x8008
|
||||||
lock
|
lock
|
||||||
@@ -162,7 +162,7 @@ MysteryEventScript_BattleCard::
|
|||||||
setvaddress MysteryEventScript_BattleCard
|
setvaddress MysteryEventScript_BattleCard
|
||||||
vgoto_if_set FLAG_MYSTERY_GIFT_DONE, MysteryEventScript_BattleCardInfo
|
vgoto_if_set FLAG_MYSTERY_GIFT_DONE, MysteryEventScript_BattleCardInfo
|
||||||
setorcopyvar VAR_RESULT, 2
|
setorcopyvar VAR_RESULT, 2
|
||||||
specialvar VAR_0x8008, BattleCardAction
|
specialvar VAR_0x8008, GetMysteryGiftCardStat
|
||||||
vgoto_if_ne VAR_0x8008, 3, MysteryEventScript_BattleCardInfo
|
vgoto_if_ne VAR_0x8008, 3, MysteryEventScript_BattleCardInfo
|
||||||
lock
|
lock
|
||||||
faceplayer
|
faceplayer
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
+3
-3
@@ -392,16 +392,16 @@ 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
|
||||||
def_special QuestLog_StartRecordingInputsAfterDeferredEvent
|
def_special QuestLog_StartRecordingInputsAfterDeferredEvent
|
||||||
def_special GetMartClerkObjectId
|
def_special GetMartClerkObjectId
|
||||||
def_special BattleCardAction
|
def_special GetMysteryGiftCardStat
|
||||||
def_special GetQuestLogState
|
def_special GetQuestLogState
|
||||||
def_special QuestLog_CutRecording
|
def_special QuestLog_CutRecording
|
||||||
def_special GetMENewsJisanItemAndState
|
def_special WonderNews_GetRewardInfo
|
||||||
def_special GetPCBoxToSendMon
|
def_special GetPCBoxToSendMon
|
||||||
def_special OpenMuseumFossilPic
|
def_special OpenMuseumFossilPic
|
||||||
def_special CloseMuseumFossilPic
|
def_special CloseMuseumFossilPic
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 141 B After Width: | Height: | Size: 141 B |
+22
-20
@@ -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
|
||||||
|
|||||||
@@ -44,4 +44,12 @@
|
|||||||
|
|
||||||
#define WONDER_CARD_FLAG_OFFSET 1000
|
#define WONDER_CARD_FLAG_OFFSET 1000
|
||||||
|
|
||||||
|
#define NEWS_REWARD_NONE 0
|
||||||
|
#define NEWS_REWARD_RECV_SMALL 1
|
||||||
|
#define NEWS_REWARD_RECV_BIG 2
|
||||||
|
#define NEWS_REWARD_WAITING 3
|
||||||
|
#define NEWS_REWARD_SENT_SMALL 4
|
||||||
|
#define NEWS_REWARD_SENT_BIG 5
|
||||||
|
#define NEWS_REWARD_AT_MAX 6
|
||||||
|
|
||||||
#endif //GUARD_CONSTANTS_MYSTERY_GIFT_H
|
#endif //GUARD_CONSTANTS_MYSTERY_GIFT_H
|
||||||
|
|||||||
@@ -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
@@ -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);
|
||||||
|
|||||||
@@ -14,17 +14,20 @@ enum {
|
|||||||
#define EREADER_XFER_EXE 1
|
#define EREADER_XFER_EXE 1
|
||||||
#define EREADER_XFER_CHK 2
|
#define EREADER_XFER_CHK 2
|
||||||
#define EREADER_XFER_SHIFT 0
|
#define EREADER_XFER_SHIFT 0
|
||||||
#define EREADER_XFER_MASK 3
|
#define EREADER_XFER_MASK ((EREADER_XFER_EXE | EREADER_XFER_CHK) << EREADER_XFER_SHIFT)
|
||||||
|
|
||||||
#define EREADER_CANCEL_TIMEOUT 1
|
#define EREADER_CANCEL_TIMEOUT 1
|
||||||
#define EREADER_CANCEL_KEY 2
|
#define EREADER_CANCEL_KEY 2
|
||||||
#define EREADER_CANCEL_MASK 0xC
|
|
||||||
#define EREADER_CANCEL_SHIFT 2
|
#define EREADER_CANCEL_SHIFT 2
|
||||||
|
#define EREADER_CANCEL_TIMEOUT_MASK (EREADER_CANCEL_TIMEOUT << EREADER_CANCEL_SHIFT)
|
||||||
|
#define EREADER_CANCEL_KEY_MASK (EREADER_CANCEL_KEY << EREADER_CANCEL_SHIFT)
|
||||||
|
#define EREADER_CANCEL_MASK ((EREADER_CANCEL_TIMEOUT | EREADER_CANCEL_KEY) << EREADER_CANCEL_SHIFT)
|
||||||
|
|
||||||
#define EREADER_CHECKSUM_OK 1
|
#define EREADER_CHECKSUM_OK 1
|
||||||
#define EREADER_CHECKSUM_ERR 2
|
#define EREADER_CHECKSUM_ERR 2
|
||||||
#define EREADER_CHECKSUM_MASK 0x30
|
|
||||||
#define EREADER_CHECKSUM_SHIFT 4
|
#define EREADER_CHECKSUM_SHIFT 4
|
||||||
|
#define EREADER_CHECKSUM_OK_MASK (EREADER_CHECKSUM_OK << EREADER_CHECKSUM_SHIFT)
|
||||||
|
#define EREADER_CHECKSUM_MASK ((EREADER_CHECKSUM_OK | EREADER_CHECKSUM_ERR) << EREADER_CHECKSUM_SHIFT)
|
||||||
|
|
||||||
void EReaderHelper_SerialCallback(void);
|
void EReaderHelper_SerialCallback(void);
|
||||||
void EReaderHelper_Timer3Callback(void);
|
void EReaderHelper_Timer3Callback(void);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
+4
-4
@@ -627,15 +627,15 @@ struct FameCheckerSaveData
|
|||||||
|
|
||||||
struct WonderNewsMetadata
|
struct WonderNewsMetadata
|
||||||
{
|
{
|
||||||
u8 unk_0_0:2;
|
u8 newsType:2;
|
||||||
u8 unk_0_2:3;
|
u8 sentRewardCounter:3;
|
||||||
u8 unk_0_5:3;
|
u8 rewardCounter:3;
|
||||||
u8 berry;
|
u8 berry;
|
||||||
};
|
};
|
||||||
|
|
||||||
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];
|
||||||
|
|||||||
+12
-6
@@ -85,12 +85,12 @@
|
|||||||
#define LINKCMD_PARTNER_CANCEL_TRADE 0xEECC
|
#define LINKCMD_PARTNER_CANCEL_TRADE 0xEECC
|
||||||
#define LINKCMD_NONE 0xEFFF
|
#define LINKCMD_NONE 0xEFFF
|
||||||
|
|
||||||
#define LINKTYPE_TRADE 0x1111 // trade
|
#define LINKTYPE_TRADE 0x1111
|
||||||
#define LINKTYPE_0x1122 0x1122 // trade
|
#define LINKTYPE_TRADE_CONNECTING 0x1122
|
||||||
#define LINKTYPE_TRADE_SETUP 0x1133
|
#define LINKTYPE_TRADE_SETUP 0x1133
|
||||||
#define LINKTYPE_0x1144 0x1144 // trade
|
#define LINKTYPE_TRADE_DISCONNECTED 0x1144
|
||||||
#define LINKTYPE_BATTLE 0x2211
|
#define LINKTYPE_BATTLE 0x2211
|
||||||
#define LINKTYPE_0x2222 0x2222 // unused battle?
|
#define LINKTYPE_UNUSED_BATTLE 0x2222 // Unused, inferred from gap
|
||||||
#define LINKTYPE_SINGLE_BATTLE 0x2233
|
#define LINKTYPE_SINGLE_BATTLE 0x2233
|
||||||
#define LINKTYPE_DOUBLE_BATTLE 0x2244
|
#define LINKTYPE_DOUBLE_BATTLE 0x2244
|
||||||
#define LINKTYPE_MULTI_BATTLE 0x2255
|
#define LINKTYPE_MULTI_BATTLE 0x2255
|
||||||
@@ -100,7 +100,12 @@
|
|||||||
#define LINKTYPE_RECORD_MIX_BEFORE 0x3311
|
#define LINKTYPE_RECORD_MIX_BEFORE 0x3311
|
||||||
#define LINKTYPE_RECORD_MIX_AFTER 0x3322
|
#define LINKTYPE_RECORD_MIX_AFTER 0x3322
|
||||||
#define LINKTYPE_BERRY_BLENDER_SETUP 0x4411
|
#define LINKTYPE_BERRY_BLENDER_SETUP 0x4411
|
||||||
|
#define LINKTYPE_BERRY_BLENDER 0x4422
|
||||||
|
#define LINKTYPE_MYSTERY_EVENT 0x5501
|
||||||
|
#define LINKTYPE_EREADER_FRLG 0x5502
|
||||||
|
#define LINKTYPE_EREADER_EM 0x5503
|
||||||
#define LINKTYPE_CONTEST_GMODE 0x6601
|
#define LINKTYPE_CONTEST_GMODE 0x6601
|
||||||
|
#define LINKTYPE_CONTEST_EMODE 0x6602
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
BLOCK_REQ_SIZE_NONE, // Identical to 200
|
BLOCK_REQ_SIZE_NONE, // Identical to 200
|
||||||
@@ -110,8 +115,9 @@ enum {
|
|||||||
BLOCK_REQ_SIZE_40,
|
BLOCK_REQ_SIZE_40,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MASTER_HANDSHAKE 0x8FFF
|
#define MASTER_HANDSHAKE 0x8FFF
|
||||||
#define SLAVE_HANDSHAKE 0xB9A0
|
#define SLAVE_HANDSHAKE 0xB9A0
|
||||||
|
#define EREADER_HANDSHAKE 0xCCD0
|
||||||
|
|
||||||
#define IsSendCmdComplete() (gSendCmd[0] == 0)
|
#define IsSendCmdComplete() (gSendCmd[0] == 0)
|
||||||
|
|
||||||
|
|||||||
+2
-4
@@ -233,8 +233,6 @@ extern struct RfuGameData gHostRfuGameData;
|
|||||||
extern u8 gHostRfuUsername[];
|
extern u8 gHostRfuUsername[];
|
||||||
extern struct RfuManager gRfu;
|
extern struct RfuManager gRfu;
|
||||||
|
|
||||||
void AddTextPrinterToWindow1(const u8 *str);
|
|
||||||
bool32 PrintMysteryGiftMenuMessage(u8 * cmdPtr, const u8 * src);
|
|
||||||
void LinkRfu_FatalError(void);
|
void LinkRfu_FatalError(void);
|
||||||
void MG_DrawCheckerboardPattern(void);
|
void MG_DrawCheckerboardPattern(void);
|
||||||
void Rfu_SetCloseLinkCallback(void);
|
void Rfu_SetCloseLinkCallback(void);
|
||||||
@@ -324,7 +322,7 @@ void RfuSetNormalDisconnectMode(void);
|
|||||||
void SetUnionRoomChatPlayerData(u32 numPlayers);
|
void SetUnionRoomChatPlayerData(u32 numPlayers);
|
||||||
void ClearRecvCommands(void);
|
void ClearRecvCommands(void);
|
||||||
|
|
||||||
#include "mevent_server.h"
|
#include "mystery_gift_server.h"
|
||||||
extern const struct mevent_server_cmd gServerScript_ClientCanceledCard[];
|
extern const struct MysteryGiftServerCmd gServerScript_ClientCanceledCard[];
|
||||||
|
|
||||||
#endif //GUARD_LINK_RFU_H
|
#endif //GUARD_LINK_RFU_H
|
||||||
|
|||||||
+2
-1
@@ -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;
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
#ifndef GUARD_MENEWS_JISAN_H
|
|
||||||
#define GUARD_MENEWS_JISAN_H
|
|
||||||
|
|
||||||
#include "global.h"
|
|
||||||
|
|
||||||
void MENewsJisan_SetRandomReward(u32 a0);
|
|
||||||
void MENewsJisanReset(void);
|
|
||||||
void MENewsJisanStepCounter(void);
|
|
||||||
|
|
||||||
#endif //GUARD_MENEWS_JISAN_H
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
#ifndef GUARD_MEVENT_H
|
|
||||||
#define GUARD_MEVENT_H
|
|
||||||
|
|
||||||
#include "global.h"
|
|
||||||
|
|
||||||
#define CARD_STAT_BATTLES_WON 0
|
|
||||||
#define CARD_STAT_BATTLES_LOST 1
|
|
||||||
#define CARD_STAT_NUM_TRADES 2
|
|
||||||
#define CARD_STAT_NUM_STAMPS 3
|
|
||||||
#define CARD_STAT_MAX_STAMPS 4
|
|
||||||
|
|
||||||
enum {
|
|
||||||
NEWS_INPUT_A,
|
|
||||||
NEWS_INPUT_B,
|
|
||||||
NEWS_INPUT_SCROLL_UP,
|
|
||||||
NEWS_INPUT_SCROLL_DOWN,
|
|
||||||
NEWS_INPUT_NONE = 0xFF
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MEventClientHeaderStruct
|
|
||||||
{
|
|
||||||
u32 unk_00;
|
|
||||||
u16 unk_04;
|
|
||||||
u32 unk_08;
|
|
||||||
u16 unk_0C;
|
|
||||||
u32 unk_10;
|
|
||||||
u16 id;
|
|
||||||
u16 unk_16[4];
|
|
||||||
struct WonderCardMetadata unk_20;
|
|
||||||
u8 maxDistributionMons;
|
|
||||||
u8 playerName[7];
|
|
||||||
u8 playerTrainerId[4];
|
|
||||||
u16 easyChatProfile[6];
|
|
||||||
u8 gameCode[4];
|
|
||||||
u8 version;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MEvent_Str_1
|
|
||||||
{
|
|
||||||
u16 status;
|
|
||||||
size_t size;
|
|
||||||
const void *data;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MEvent_Str_2
|
|
||||||
{
|
|
||||||
u8 fill_00[0x40];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct WonderGraphics
|
|
||||||
{
|
|
||||||
u8 titleTextPal:4;
|
|
||||||
u8 bodyTextPal:4;
|
|
||||||
u8 footerTextPal:4;
|
|
||||||
u8 stampShadowPal:4;
|
|
||||||
const u8 * tiles;
|
|
||||||
const u8 * map;
|
|
||||||
const u16 * pal;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern const u16 gCard1Pal[];
|
|
||||||
extern const u16 gCard2Pal[];
|
|
||||||
extern const u16 gCard3Pal[];
|
|
||||||
extern const u16 gCard4Pal[];
|
|
||||||
extern const u16 gCard5Pal[];
|
|
||||||
|
|
||||||
struct WonderNews * GetSavedWonderNews(void);
|
|
||||||
struct WonderCard * GetSavedWonderCard(void);
|
|
||||||
struct WonderCardMetadata * sav1_get_mevent_buffer_2(void);
|
|
||||||
struct WonderNewsMetadata * GetMENewsJisanStructPtr(void);
|
|
||||||
bool32 OverwriteSavedWonderNewsWithReceivedNews(const struct WonderNews * src);
|
|
||||||
bool32 ValidateReceivedWonderNews(void);
|
|
||||||
bool32 ValidateReceivedWonderCard(void);
|
|
||||||
bool32 MEvent_HaveAlreadyReceivedWonderNews(const u8 * src);
|
|
||||||
bool32 OverwriteSavedWonderCardWithReceivedCard(const struct WonderCard * data);
|
|
||||||
void MEvent_WonderCardResetUnk08_6(struct WonderCard * buffer);
|
|
||||||
bool32 MEvent_ReceiveDistributionMon(const u16 * data);
|
|
||||||
void BuildMEventClientHeader(struct MEventClientHeaderStruct * data);
|
|
||||||
bool32 ValidateMEventClientHeader(const struct MEventClientHeaderStruct * data);
|
|
||||||
u32 sub_8144418(const u16 * a0, const struct MEventClientHeaderStruct * a1, void *unused);
|
|
||||||
u32 MEvent_CanPlayerReceiveDistributionMon(const u16 * a0, const struct MEventClientHeaderStruct * a1, void *unused);
|
|
||||||
bool32 sub_8144474(const struct MEventClientHeaderStruct * a0, const u16 * a1);
|
|
||||||
u16 sub_81444B0(const struct MEventClientHeaderStruct * a0, u32 command);
|
|
||||||
bool32 WonderCard_Init(struct WonderCard * card, struct WonderCardMetadata * metadata);
|
|
||||||
bool32 WonderNews_Init(const struct WonderNews * news);
|
|
||||||
s32 WonderCard_Enter(void);
|
|
||||||
s32 WonderNews_Enter(void);
|
|
||||||
void DestroyWonderCard(void);
|
|
||||||
void DestroyWonderNews(void);
|
|
||||||
void WonderCard_Destroy(void);
|
|
||||||
void WonderNews_Destroy(void);
|
|
||||||
s32 WonderCard_Exit(bool32 flag);
|
|
||||||
s32 WonderNews_Exit(bool32 flag);
|
|
||||||
bool32 CheckReceivedGiftFromWonderCard(void);
|
|
||||||
void WonderNews_AddScrollIndicatorArrowPair(void);
|
|
||||||
void WonderNews_RemoveScrollIndicatorArrowPair(void);
|
|
||||||
bool32 WonderNews_Test_Unk_02(void);
|
|
||||||
bool32 WonderCard_Test_Unk_08_6(void);
|
|
||||||
u32 WonderNews_GetInput(u16 input);
|
|
||||||
void InitMEventData(void);
|
|
||||||
u16 MEvent_GetBattleCardCount(u32 command);
|
|
||||||
void MysteryGift_TryIncrementStat(u32 eventId, u32 trainerId);
|
|
||||||
u16 *GetMEventProfileECWordsMaybe(void);
|
|
||||||
void MysteryGift_DisableStats(void);
|
|
||||||
bool32 MysteryGift_TryEnableStatsByFlagId(u16 flagId);
|
|
||||||
u16 GetWonderCardFlagId(void);
|
|
||||||
|
|
||||||
#endif //GUARD_MEVENT_H
|
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
#ifndef GUARD_MEVENT_SERVER_H
|
|
||||||
#define GUARD_MEVENT_SERVER_H
|
|
||||||
|
|
||||||
#include "global.h"
|
|
||||||
|
|
||||||
#define ME_SEND_BUF_SIZE 0x400
|
|
||||||
|
|
||||||
struct mevent_srv_sub
|
|
||||||
{
|
|
||||||
s32 seqno;
|
|
||||||
u8 sendPlayerNo;
|
|
||||||
u8 recvPlayerNo;
|
|
||||||
u16 recvIdent;
|
|
||||||
u16 recvCounter;
|
|
||||||
u16 recvCRC;
|
|
||||||
u16 recvSize;
|
|
||||||
u16 sendIdent;
|
|
||||||
u16 sendCounter;
|
|
||||||
u16 sendCRC;
|
|
||||||
u16 sendSize;
|
|
||||||
void *recvBfr;
|
|
||||||
const void *sendBfr;
|
|
||||||
u32 (*recvFunc)(struct mevent_srv_sub *);
|
|
||||||
u32 (*sendFunc)(struct mevent_srv_sub *);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct send_recv_header
|
|
||||||
{
|
|
||||||
u16 ident;
|
|
||||||
u16 crc;
|
|
||||||
u16 size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct mevent_client_cmd
|
|
||||||
{
|
|
||||||
u32 instr;
|
|
||||||
u32 parameter;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Client commands
|
|
||||||
#define CLI_RETURN(x) {.instr = 1, .parameter = x}
|
|
||||||
#define CLI_RECEIVE(x) {.instr = 2, .parameter = x}
|
|
||||||
#define CLI_WAITSND {.instr = 3, .parameter = 0}
|
|
||||||
#define CLI_JUMPBUF {.instr = 4, .parameter = 0}
|
|
||||||
#define CLI_SNDHEAD {.instr = 8, .parameter = 0}
|
|
||||||
#define CLI_VLDNEWS {.instr = 9, .parameter = 0}
|
|
||||||
#define CLI_RECVSAV {.instr = 10, .parameter = 0}
|
|
||||||
#define CLI_RECVBUF {.instr = 12, .parameter = 0}
|
|
||||||
#define CLI_REQWORD {.instr = 13, .parameter = 0}
|
|
||||||
#define CLI_SNDWORD {.instr = 14, .parameter = 0}
|
|
||||||
#define CLI_RECVMON {.instr = 16, .parameter = 0}
|
|
||||||
#define CLI_RECVRAM {.instr = 17, .parameter = 0}
|
|
||||||
#define CLI_SENDALL {.instr = 20, .parameter = 0}
|
|
||||||
|
|
||||||
struct mevent_client
|
|
||||||
{
|
|
||||||
u32 unk_00;
|
|
||||||
u32 param;
|
|
||||||
u32 mainseqno;
|
|
||||||
u32 flag;
|
|
||||||
u32 cmdidx;
|
|
||||||
void *sendBuffer;
|
|
||||||
void *recvBuffer;
|
|
||||||
struct mevent_client_cmd * cmdBuffer;
|
|
||||||
void *buffer;
|
|
||||||
struct mevent_srv_sub manager;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct mevent_server_cmd
|
|
||||||
{
|
|
||||||
u32 instr;
|
|
||||||
bool32 flag;
|
|
||||||
void *parameter;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Server commands
|
|
||||||
#define SRV_RETURN(x) {.instr = 0, .flag = x}
|
|
||||||
#define SRV_WAITSND {.instr = 1}
|
|
||||||
#define SRV_RECV(x) {.instr = 2, .flag = x}
|
|
||||||
#define SRV_BRANCH(y) {.instr = 3, .parameter = (void *)y}
|
|
||||||
#define SRV_BRANCHIF(x, y) {.instr = 4, .flag = x, .parameter = (void *)y}
|
|
||||||
#define SRV_READ_1442CC {.instr = 5}
|
|
||||||
#define SRV_VALID_1442CC {.instr = 6}
|
|
||||||
#define SRV_CHECK_1442CC_14 {.instr = 7}
|
|
||||||
#define SRV_READWORD {.instr = 8}
|
|
||||||
#define SRV_SEND_CARD {.instr = 13}
|
|
||||||
#define SRV_SEND_NEWS {.instr = 14}
|
|
||||||
#define SRV_BUFFER_SEND {.instr = 15}
|
|
||||||
#define SRV_SEND(x, y) {.instr = 18, .flag = x, .parameter = (void *)y}
|
|
||||||
#define SRV_SENDSTR(x, y) {.instr = 20, .flag = x, .parameter = (void *)y}
|
|
||||||
#define SRV_BUFFER_CARD {.instr = 26}
|
|
||||||
#define SRV_BUFFER_NEWS {.instr = 27}
|
|
||||||
#define SRV_RAM_SCRIPT_IF_VALID {.instr = 28}
|
|
||||||
|
|
||||||
struct mevent_srv_common
|
|
||||||
{
|
|
||||||
u32 unk_00;
|
|
||||||
u32 param;
|
|
||||||
u32 mainseqno;
|
|
||||||
u32 cmdidx;
|
|
||||||
const struct mevent_server_cmd * cmdBuffer;
|
|
||||||
void *recvBuffer;
|
|
||||||
struct WonderCard * card;
|
|
||||||
struct WonderNews * news;
|
|
||||||
struct MEventClientHeaderStruct * mevent_unk1442cc;
|
|
||||||
void *sendBuffer1;
|
|
||||||
u32 sendBuffer1Size;
|
|
||||||
void *sendBuffer2;
|
|
||||||
u32 sendBuffer2Size;
|
|
||||||
u32 sendWord;
|
|
||||||
struct mevent_srv_sub manager;
|
|
||||||
};
|
|
||||||
|
|
||||||
u32 mevent_srv_sub_recv(struct mevent_srv_sub * svr);
|
|
||||||
u32 mevent_srv_sub_send(struct mevent_srv_sub * svr);
|
|
||||||
void mevent_srv_sub_init(struct mevent_srv_sub * svr, u32 sendPlayerNo, u32 recvPlayerNo);
|
|
||||||
void mevent_srv_sub_init_send(struct mevent_srv_sub * svr, u32 ident, const void *src, u32 size);
|
|
||||||
void mevent_srv_sub_init_recv(struct mevent_srv_sub * svr, u32 ident, void *dest);
|
|
||||||
|
|
||||||
void mevent_client_do_init(void);
|
|
||||||
u32 mevent_client_do_exec(u16 * a0);
|
|
||||||
void mevent_client_inc_flag(void);
|
|
||||||
void *mevent_client_get_buffer(void);
|
|
||||||
void mevent_client_set_param(u32 a0);
|
|
||||||
void mevent_srv_init_wnews(void);
|
|
||||||
void mevent_srv_new_wcard(void);
|
|
||||||
u32 mevent_srv_common_do_exec(u16 * a0);
|
|
||||||
|
|
||||||
#endif //GUARD_MEVENT_SERVER_H
|
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
#ifndef GUARD_MYSTERY_GIFT_H
|
||||||
|
#define GUARD_MYSTERY_GIFT_H
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "constants/mystery_gift.h"
|
||||||
|
|
||||||
|
#define CARD_STAT_BATTLES_WON 0
|
||||||
|
#define CARD_STAT_BATTLES_LOST 1
|
||||||
|
#define CARD_STAT_NUM_TRADES 2
|
||||||
|
#define CARD_STAT_NUM_STAMPS 3
|
||||||
|
#define CARD_STAT_MAX_STAMPS 4
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NEWS_INPUT_A,
|
||||||
|
NEWS_INPUT_B,
|
||||||
|
NEWS_INPUT_SCROLL_UP,
|
||||||
|
NEWS_INPUT_SCROLL_DOWN,
|
||||||
|
NEWS_INPUT_NONE = 0xFF
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MysteryGiftLinkGameData
|
||||||
|
{
|
||||||
|
u32 unk_00;
|
||||||
|
u16 unk_04;
|
||||||
|
u32 unk_08;
|
||||||
|
u16 unk_0C;
|
||||||
|
u32 unk_10;
|
||||||
|
u16 flagId;
|
||||||
|
u16 questionnaireWords[NUM_QUESTIONNAIRE_WORDS];
|
||||||
|
struct WonderCardMetadata cardMetadata;
|
||||||
|
u8 maxStamps;
|
||||||
|
u8 playerName[PLAYER_NAME_LENGTH];
|
||||||
|
u8 playerTrainerId[TRAINER_ID_LENGTH];
|
||||||
|
u16 easyChatProfile[EASY_CHAT_BATTLE_WORDS_COUNT];
|
||||||
|
u8 gameCode[GAME_CODE_LENGTH];
|
||||||
|
u8 version;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WonderGraphics
|
||||||
|
{
|
||||||
|
u8 titleTextPal:4;
|
||||||
|
u8 bodyTextPal:4;
|
||||||
|
u8 footerTextPal:4;
|
||||||
|
u8 stampShadowPal:4;
|
||||||
|
const u8 * tiles;
|
||||||
|
const u8 * map;
|
||||||
|
const u16 * pal;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const u16 gCard1Pal[];
|
||||||
|
extern const u16 gCard2Pal[];
|
||||||
|
extern const u16 gCard3Pal[];
|
||||||
|
extern const u16 gCard4Pal[];
|
||||||
|
extern const u16 gCard5Pal[];
|
||||||
|
|
||||||
|
struct WonderNews * GetSavedWonderNews(void);
|
||||||
|
struct WonderCard * GetSavedWonderCard(void);
|
||||||
|
struct WonderCardMetadata * GetSavedWonderCardMetadata(void);
|
||||||
|
struct WonderNewsMetadata * GetSavedWonderNewsMetadata(void);
|
||||||
|
bool32 SaveWonderNews(const struct WonderNews * news);
|
||||||
|
bool32 ValidateSavedWonderNews(void);
|
||||||
|
bool32 ValidateSavedWonderCard(void);
|
||||||
|
bool32 IsWonderNewsSameAsSaved(const u8 * news);
|
||||||
|
bool32 SaveWonderCard(const struct WonderCard * card);
|
||||||
|
void DisableWonderCardSending(struct WonderCard * card);
|
||||||
|
bool32 MysteryGift_TrySaveStamp(const u16 * stamp);
|
||||||
|
void MysteryGift_LoadLinkGameData(struct MysteryGiftLinkGameData * data);
|
||||||
|
bool32 MysteryGift_ValidateLinkGameData(const struct MysteryGiftLinkGameData * data);
|
||||||
|
u32 MysteryGift_CompareCardFlags(const u16 * flagId, const struct MysteryGiftLinkGameData * data, const void *unused);
|
||||||
|
u32 MysteryGift_CheckStamps(const u16 * stamp, const struct MysteryGiftLinkGameData * data, const void *unused);
|
||||||
|
bool32 MysteryGift_DoesQuestionnaireMatch(const struct MysteryGiftLinkGameData * data, const u16 * words);
|
||||||
|
u16 MysteryGift_GetCardStatFromLinkData(const struct MysteryGiftLinkGameData * data, u32 stat);
|
||||||
|
bool32 WonderCard_Init(struct WonderCard * card, struct WonderCardMetadata * metadata);
|
||||||
|
bool32 WonderNews_Init(const struct WonderNews * news);
|
||||||
|
s32 WonderCard_Enter(void);
|
||||||
|
s32 WonderNews_Enter(void);
|
||||||
|
void ClearSavedWonderCardAndRelated(void);
|
||||||
|
void ClearSavedWonderNewsAndRelated(void);
|
||||||
|
void WonderCard_Destroy(void);
|
||||||
|
void WonderNews_Destroy(void);
|
||||||
|
s32 WonderCard_Exit(bool32 flag);
|
||||||
|
s32 WonderNews_Exit(bool32 flag);
|
||||||
|
bool32 IsSavedWonderCardGiftNotReceived(void);
|
||||||
|
void WonderNews_AddScrollIndicatorArrowPair(void);
|
||||||
|
void WonderNews_RemoveScrollIndicatorArrowPair(void);
|
||||||
|
bool32 IsSendingSavedWonderNewsAllowed(void);
|
||||||
|
bool32 IsSendingSavedWonderCardAllowed(void);
|
||||||
|
u32 WonderNews_GetInput(u16 input);
|
||||||
|
void ClearMysteryGift(void);
|
||||||
|
u16 MysteryGift_GetCardStat(u32 stat);
|
||||||
|
void MysteryGift_TryIncrementStat(u32 stat, u32 trainerId);
|
||||||
|
u16 *GetQuestionnaireWordsPtr(void);
|
||||||
|
void MysteryGift_DisableStats(void);
|
||||||
|
bool32 MysteryGift_TryEnableStatsByFlagId(u16 flagId);
|
||||||
|
u16 GetWonderCardFlagId(void);
|
||||||
|
|
||||||
|
#endif // GUARD_MYSTERY_GIFT_H
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
#ifndef GUARD_MYSTERY_GIFT_CLIENT_H
|
||||||
|
#define GUARD_MYSTERY_GIFT_CLIENT_H
|
||||||
|
|
||||||
|
#include "mystery_gift_link.h"
|
||||||
|
|
||||||
|
// Return values for client functions called by MysteryGiftClient_Run
|
||||||
|
enum {
|
||||||
|
CLI_RET_INIT,
|
||||||
|
CLI_RET_ACTIVE,
|
||||||
|
CLI_RET_YES_NO,
|
||||||
|
CLI_RET_PRINT_MSG,
|
||||||
|
CLI_RET_ASK_TOSS,
|
||||||
|
CLI_RET_COPY_MSG,
|
||||||
|
CLI_RET_END,
|
||||||
|
};
|
||||||
|
|
||||||
|
// IDs for client script instructions
|
||||||
|
enum {
|
||||||
|
CLI_NONE,
|
||||||
|
CLI_RETURN,
|
||||||
|
CLI_RECV,
|
||||||
|
CLI_SEND_LOADED,
|
||||||
|
CLI_COPY_RECV,
|
||||||
|
CLI_YES_NO,
|
||||||
|
CLI_COPY_RECV_IF_N,
|
||||||
|
CLI_COPY_RECV_IF,
|
||||||
|
CLI_LOAD_GAME_DATA,
|
||||||
|
CLI_SAVE_NEWS,
|
||||||
|
CLI_SAVE_CARD,
|
||||||
|
CLI_PRINT_MSG,
|
||||||
|
CLI_COPY_MSG,
|
||||||
|
CLI_ASK_TOSS,
|
||||||
|
CLI_LOAD_TOSS_RESPONSE,
|
||||||
|
CLI_RUN_MEVENT_SCRIPT,
|
||||||
|
CLI_SAVE_STAMP,
|
||||||
|
CLI_SAVE_RAM_SCRIPT,
|
||||||
|
CLI_RECV_EREADER_TRAINER,
|
||||||
|
CLI_SEND_STAT,
|
||||||
|
CLI_SEND_READY_END,
|
||||||
|
CLI_RUN_BUFFER_SCRIPT,
|
||||||
|
};
|
||||||
|
|
||||||
|
// IDs for client messages when ending a script.
|
||||||
|
// Given as the parameter to CLI_RETURN, and resolved to text in GetClientResultMessage
|
||||||
|
enum {
|
||||||
|
CLI_MSG_NOTHING_SENT,
|
||||||
|
CLI_MSG_RECORD_UPLOADED,
|
||||||
|
CLI_MSG_CARD_RECEIVED,
|
||||||
|
CLI_MSG_NEWS_RECEIVED,
|
||||||
|
CLI_MSG_STAMP_RECEIVED,
|
||||||
|
CLI_MSG_HAD_CARD,
|
||||||
|
CLI_MSG_HAD_STAMP,
|
||||||
|
CLI_MSG_HAD_NEWS,
|
||||||
|
CLI_MSG_NO_ROOM_STAMPS,
|
||||||
|
CLI_MSG_COMM_CANCELED,
|
||||||
|
CLI_MSG_CANT_ACCEPT,
|
||||||
|
CLI_MSG_COMM_ERROR,
|
||||||
|
CLI_MSG_TRAINER_RECEIVED,
|
||||||
|
CLI_MSG_BUFFER_SUCCESS,
|
||||||
|
CLI_MSG_BUFFER_FAILURE,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CLIENT_MAX_MSG_SIZE 64
|
||||||
|
|
||||||
|
struct MysteryGiftClientCmd
|
||||||
|
{
|
||||||
|
u32 instr;
|
||||||
|
u32 parameter;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MysteryGiftClient
|
||||||
|
{
|
||||||
|
u32 unused;
|
||||||
|
u32 param;
|
||||||
|
u32 funcId;
|
||||||
|
u32 funcState;
|
||||||
|
u32 cmdidx;
|
||||||
|
void *sendBuffer;
|
||||||
|
void *recvBuffer;
|
||||||
|
struct MysteryGiftClientCmd * script;
|
||||||
|
void *msg;
|
||||||
|
struct MysteryGiftLink link;
|
||||||
|
};
|
||||||
|
|
||||||
|
void MysteryGiftClient_Create(void);
|
||||||
|
u32 MysteryGiftClient_Run(u16 * endVal);
|
||||||
|
void MysteryGiftClient_AdvanceState(void);
|
||||||
|
void * MysteryGiftClient_GetMsg(void);
|
||||||
|
void MysteryGiftClient_SetParam(u32 value);
|
||||||
|
|
||||||
|
#endif //GUARD_MYSTERY_GIFT_CLIENT_H
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
#ifndef GUARD_MYSTERY_GIFT_LINK_H
|
||||||
|
#define GUARD_MYSTERY_GIFT_LINK_H
|
||||||
|
|
||||||
|
#define MG_LINK_BUFFER_SIZE 0x400
|
||||||
|
|
||||||
|
// Send/receive ids for the Client/Server to make sure
|
||||||
|
// they're sending/receiving the same thing
|
||||||
|
enum {
|
||||||
|
MG_LINKID_CLIENT_SCRIPT = 16,
|
||||||
|
MG_LINKID_GAME_DATA,
|
||||||
|
MG_LINKID_GAME_STAT,
|
||||||
|
MG_LINKID_RESPONSE,
|
||||||
|
MG_LINKID_READY_END,
|
||||||
|
MG_LINKID_DYNAMIC_MSG,
|
||||||
|
MG_LINKID_CARD,
|
||||||
|
MG_LINKID_NEWS,
|
||||||
|
MG_LINKID_STAMP,
|
||||||
|
MG_LINKID_RAM_SCRIPT,
|
||||||
|
MG_LINKID_EREADER_TRAINER,
|
||||||
|
MG_LINKID_UNK_1,
|
||||||
|
MG_LINKID_UNK_2,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MysteryGiftLink
|
||||||
|
{
|
||||||
|
s32 state;
|
||||||
|
u8 sendPlayerId;
|
||||||
|
u8 recvPlayerId;
|
||||||
|
u16 recvIdent;
|
||||||
|
u16 recvCounter;
|
||||||
|
u16 recvCRC;
|
||||||
|
u16 recvSize;
|
||||||
|
u16 sendIdent;
|
||||||
|
u16 sendCounter;
|
||||||
|
u16 sendCRC;
|
||||||
|
u16 sendSize;
|
||||||
|
void * recvBuffer;
|
||||||
|
const void * sendBuffer;
|
||||||
|
u32 (*recvFunc)(struct MysteryGiftLink *);
|
||||||
|
u32 (*sendFunc)(struct MysteryGiftLink *);
|
||||||
|
};
|
||||||
|
|
||||||
|
void MysteryGiftLink_Init(struct MysteryGiftLink * link, u32 sendPlayerId, u32 recvPlayerId);
|
||||||
|
void MysteryGiftLink_InitSend(struct MysteryGiftLink * link, u32 ident, const void * src, u32 size);
|
||||||
|
bool32 MysteryGiftLink_Recv(struct MysteryGiftLink * link);
|
||||||
|
bool32 MysteryGiftLink_Send(struct MysteryGiftLink * link);
|
||||||
|
void MysteryGiftLink_InitRecv(struct MysteryGiftLink * link, u32 ident, void * dest);
|
||||||
|
|
||||||
|
#endif //GUARD_MYSTERY_GIFT_LINK_H
|
||||||
@@ -3,9 +3,11 @@
|
|||||||
|
|
||||||
extern bool8 gGiftIsFromEReader;
|
extern bool8 gGiftIsFromEReader;
|
||||||
|
|
||||||
|
bool32 PrintMysteryGiftMenuMessage(u8 * cmdPtr, const u8 * src);
|
||||||
|
void AddTextPrinterToWindow1(const u8 *str);
|
||||||
void MainCB_FreeAllBuffersAndReturnToInitTitleScreen(void);
|
void MainCB_FreeAllBuffersAndReturnToInitTitleScreen(void);
|
||||||
void PrintMysteryGiftOrEReaderTopMenu(bool8, bool32);
|
void PrintMysteryGiftOrEReaderTopMenu(bool8, bool32);
|
||||||
void c2_mystery_gift(void);
|
void CB2_InitMysteryGift(void);
|
||||||
void CB2_MysteryGiftEReader(void);
|
void CB2_MysteryGiftEReader(void);
|
||||||
s8 DoMysteryGiftYesNo(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, const u8 * str);
|
s8 DoMysteryGiftYesNo(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, const u8 * str);
|
||||||
void MG_DrawTextBorder(u8 windowId);
|
void MG_DrawTextBorder(u8 windowId);
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
#ifndef GUARD_MYSTERY_GIFT_SERVER_H
|
||||||
|
#define GUARD_MYSTERY_GIFT_SERVER_H
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
#include "mystery_gift_link.h"
|
||||||
|
|
||||||
|
// Return values for Server_* functions.
|
||||||
|
// Other than SVR_RET_END, effectively useless (not checked for).
|
||||||
|
enum {
|
||||||
|
SVR_RET_INIT,
|
||||||
|
SVR_RET_ACTIVE,
|
||||||
|
SVR_RET_UNUSED,
|
||||||
|
SVR_RET_END
|
||||||
|
};
|
||||||
|
|
||||||
|
// IDs for server script instructions
|
||||||
|
enum {
|
||||||
|
SVR_RETURN,
|
||||||
|
SVR_SEND,
|
||||||
|
SVR_RECV,
|
||||||
|
SVR_GOTO,
|
||||||
|
SVR_GOTO_IF_EQ,
|
||||||
|
SVR_COPY_GAME_DATA,
|
||||||
|
SVR_CHECK_GAME_DATA, // In Emerald, this was separated into SVR_CHECK_GAME_DATA_CARD and SVR_CHECK_GAME_DATA_NEWS
|
||||||
|
SVR_CHECK_EXISTING_CARD,
|
||||||
|
SVR_READ_RESPONSE,
|
||||||
|
SVR_CHECK_EXISTING_STAMPS,
|
||||||
|
SVR_GET_CARD_STAT,
|
||||||
|
SVR_CHECK_QUESTIONNAIRE,
|
||||||
|
SVR_COMPARE,
|
||||||
|
SVR_LOAD_CARD,
|
||||||
|
SVR_LOAD_NEWS,
|
||||||
|
SVR_LOAD_RAM_SCRIPT,
|
||||||
|
SVR_LOAD_STAMP,
|
||||||
|
SVR_LOAD_UNK_2,
|
||||||
|
SVR_LOAD_CLIENT_SCRIPT,
|
||||||
|
SVR_LOAD_EREADER_TRAINER,
|
||||||
|
SVR_LOAD_MSG,
|
||||||
|
SVR_COPY_STAMP,
|
||||||
|
SVR_COPY_CARD,
|
||||||
|
SVR_COPY_NEWS,
|
||||||
|
SVR_SET_RAM_SCRIPT,
|
||||||
|
SVR_SET_CLIENT_SCRIPT,
|
||||||
|
SVR_COPY_SAVED_CARD,
|
||||||
|
SVR_COPY_SAVED_NEWS,
|
||||||
|
SVR_COPY_SAVED_RAM_SCRIPT,
|
||||||
|
SVR_LOAD_UNK_1,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create arguments for SVR_LOAD_CLIENT_SCRIPT or SVR_LOAD_MSG
|
||||||
|
// (a script/text size and pointer to send to the client)
|
||||||
|
#define PTR_ARG(pointer) .param = sizeof(pointer), .ptr = pointer
|
||||||
|
|
||||||
|
// IDs for server messages when ending a script.
|
||||||
|
// Given as the parameter to SVR_RETURN, and resolved to text in GetServerResultMessage
|
||||||
|
enum {
|
||||||
|
SVR_MSG_NOTHING_SENT,
|
||||||
|
SVR_MSG_RECORD_UPLOADED,
|
||||||
|
SVR_MSG_CARD_SENT,
|
||||||
|
SVR_MSG_NEWS_SENT,
|
||||||
|
SVR_MSG_STAMP_SENT,
|
||||||
|
SVR_MSG_HAS_CARD,
|
||||||
|
SVR_MSG_HAS_STAMP,
|
||||||
|
SVR_MSG_HAS_NEWS,
|
||||||
|
SVR_MSG_NO_ROOM_STAMPS,
|
||||||
|
SVR_MSG_CLIENT_CANCELED,
|
||||||
|
SVR_MSG_CANT_SEND_GIFT_1,
|
||||||
|
SVR_MSG_COMM_ERROR,
|
||||||
|
SVR_MSG_GIFT_SENT_1,
|
||||||
|
SVR_MSG_GIFT_SENT_2,
|
||||||
|
SVR_MSG_CANT_SEND_GIFT_2,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MysteryGiftServerCmd
|
||||||
|
{
|
||||||
|
u32 instr;
|
||||||
|
bool32 param;
|
||||||
|
const void *ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MysteryGiftServer
|
||||||
|
{
|
||||||
|
u32 unused;
|
||||||
|
u32 param;
|
||||||
|
u32 funcId;
|
||||||
|
u32 cmdidx;
|
||||||
|
const struct MysteryGiftServerCmd * script;
|
||||||
|
void *recvBuffer;
|
||||||
|
struct WonderCard * card;
|
||||||
|
struct WonderNews * news;
|
||||||
|
struct MysteryGiftLinkGameData * linkGameData;
|
||||||
|
const void *ramScript;
|
||||||
|
u32 ramScriptSize;
|
||||||
|
const void *clientScript;
|
||||||
|
u32 clientScriptSize;
|
||||||
|
u32 stamp;
|
||||||
|
struct MysteryGiftLink manager;
|
||||||
|
};
|
||||||
|
|
||||||
|
void MysterGiftServer_CreateForNews(void);
|
||||||
|
void MysterGiftServer_CreateForCard(void);
|
||||||
|
u32 MysterGiftServer_Run(u16 * endVal);
|
||||||
|
|
||||||
|
#endif //GUARD_MYSTERY_GIFT_SERVER_H
|
||||||
@@ -15,6 +15,90 @@ enum
|
|||||||
FLAG_SET_CAUGHT
|
FLAG_SET_CAUGHT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// IDs for the pokedex area markers
|
||||||
|
enum {
|
||||||
|
DEX_AREA_NONE,
|
||||||
|
DEX_AREA_PALLET_TOWN,
|
||||||
|
DEX_AREA_VIRIDIAN_CITY,
|
||||||
|
DEX_AREA_PEWTER_CITY,
|
||||||
|
DEX_AREA_CERULEAN_CITY,
|
||||||
|
DEX_AREA_LAVENDER_TOWN,
|
||||||
|
DEX_AREA_VERMILION_CITY,
|
||||||
|
DEX_AREA_CELADON_CITY,
|
||||||
|
DEX_AREA_FUCHSIA_CITY,
|
||||||
|
DEX_AREA_CINNABAR_ISLAND,
|
||||||
|
DEX_AREA_INDIGO_PLATEAU,
|
||||||
|
DEX_AREA_SAFFRON_CITY,
|
||||||
|
DEX_AREA_ROUTE_1,
|
||||||
|
DEX_AREA_ROUTE_2,
|
||||||
|
DEX_AREA_ROUTE_3,
|
||||||
|
DEX_AREA_ROUTE_4,
|
||||||
|
DEX_AREA_ROUTE_5,
|
||||||
|
DEX_AREA_ROUTE_6,
|
||||||
|
DEX_AREA_ROUTE_7,
|
||||||
|
DEX_AREA_ROUTE_8,
|
||||||
|
DEX_AREA_ROUTE_9,
|
||||||
|
DEX_AREA_ROUTE_10,
|
||||||
|
DEX_AREA_ROUTE_11,
|
||||||
|
DEX_AREA_ROUTE_12,
|
||||||
|
DEX_AREA_ROUTE_13,
|
||||||
|
DEX_AREA_ROUTE_14,
|
||||||
|
DEX_AREA_ROUTE_15,
|
||||||
|
DEX_AREA_ROUTE_16,
|
||||||
|
DEX_AREA_ROUTE_17,
|
||||||
|
DEX_AREA_ROUTE_18,
|
||||||
|
DEX_AREA_ROUTE_19,
|
||||||
|
DEX_AREA_ROUTE_20,
|
||||||
|
DEX_AREA_ROUTE_21,
|
||||||
|
DEX_AREA_ROUTE_22,
|
||||||
|
DEX_AREA_ROUTE_23,
|
||||||
|
DEX_AREA_ROUTE_24,
|
||||||
|
DEX_AREA_ROUTE_25,
|
||||||
|
DEX_AREA_VIRIDIAN_FOREST,
|
||||||
|
DEX_AREA_DIGLETTS_CAVE,
|
||||||
|
DEX_AREA_MT_MOON,
|
||||||
|
DEX_AREA_CERULEAN_CAVE,
|
||||||
|
DEX_AREA_ROCK_TUNNEL,
|
||||||
|
DEX_AREA_POWER_PLANT,
|
||||||
|
DEX_AREA_POKEMON_TOWER,
|
||||||
|
DEX_AREA_SAFARI_ZONE,
|
||||||
|
DEX_AREA_SEAFOAM_ISLANDS,
|
||||||
|
DEX_AREA_POKEMON_MANSION,
|
||||||
|
DEX_AREA_VICTORY_ROAD,
|
||||||
|
DEX_AREA_ONE_ISLAND,
|
||||||
|
DEX_AREA_TWO_ISLAND,
|
||||||
|
DEX_AREA_THREE_ISLAND,
|
||||||
|
DEX_AREA_FOUR_ISLAND,
|
||||||
|
DEX_AREA_FIVE_ISLAND,
|
||||||
|
DEX_AREA_SIX_ISLAND, // Not associated with any MAPSEC
|
||||||
|
DEX_AREA_SEVEN_ISLAND, // Not associated with any MAPSEC
|
||||||
|
DEX_AREA_KINDLE_ROAD,
|
||||||
|
DEX_AREA_TREASURE_BEACH,
|
||||||
|
DEX_AREA_CAPE_BRINK,
|
||||||
|
DEX_AREA_BOND_BRIDGE,
|
||||||
|
DEX_AREA_THREE_ISLE_PATH,
|
||||||
|
DEX_AREA_RESORT_GORGEOUS,
|
||||||
|
DEX_AREA_WATER_LABYRINTH,
|
||||||
|
DEX_AREA_FIVE_ISLE_MEADOW,
|
||||||
|
DEX_AREA_MEMORIAL_PILLAR,
|
||||||
|
DEX_AREA_OUTCAST_ISLAND,
|
||||||
|
DEX_AREA_GREEN_PATH,
|
||||||
|
DEX_AREA_WATER_PATH,
|
||||||
|
DEX_AREA_RUIN_VALLEY,
|
||||||
|
DEX_AREA_TRAINER_TOWER,
|
||||||
|
DEX_AREA_CANYON_ENTRANCE,
|
||||||
|
DEX_AREA_SEVAULT_CANYON,
|
||||||
|
DEX_AREA_TANOBY_RUINS,
|
||||||
|
DEX_AREA_MT_EMBER,
|
||||||
|
DEX_AREA_BERRY_FOREST,
|
||||||
|
DEX_AREA_ICEFALL_CAVE,
|
||||||
|
DEX_AREA_LOST_CAVE,
|
||||||
|
DEX_AREA_ALTERING_CAVE,
|
||||||
|
DEX_AREA_PATTERN_BUSH,
|
||||||
|
DEX_AREA_DOTTED_HOLE,
|
||||||
|
DEX_AREA_TANOBY_CHAMBER,
|
||||||
|
};
|
||||||
|
|
||||||
struct PokedexEntry
|
struct PokedexEntry
|
||||||
{
|
{
|
||||||
/*0x00*/ u8 categoryName[12];
|
/*0x00*/ u8 categoryName[12];
|
||||||
|
|||||||
@@ -1,19 +1,9 @@
|
|||||||
#ifndef GUARD_POKEDEX_AREA_MARKERS_H
|
#ifndef GUARD_POKEDEX_AREA_MARKERS_H
|
||||||
#define GUARD_POKEDEX_AREA_MARKERS_H
|
#define GUARD_POKEDEX_AREA_MARKERS_H
|
||||||
|
|
||||||
struct PAM_TaskData
|
void GetAreaMarkerSubsprite(s32 i, s32 dexArea, struct Subsprite * subsprites);
|
||||||
{
|
void DestroyPokedexAreaMarkers(u8 taskId);
|
||||||
struct SubspriteTable subsprites;
|
u8 CreatePokedexAreaMarkers(u16 species, u16 tilesTag, u8 palIdx, u8 y);
|
||||||
void *buffer;
|
u8 GetNumPokedexAreaMarkers(u8 taskId);
|
||||||
u8 unk_0C;
|
|
||||||
u8 spr_id;
|
|
||||||
u16 tilesTag;
|
|
||||||
u16 unk_10;
|
|
||||||
};
|
|
||||||
|
|
||||||
void SetAreaSubsprite(s32 i, s32 whichArea, struct Subsprite * subsprites);
|
|
||||||
void Dtor_PokedexAreaMarkers(u8 taskId);
|
|
||||||
u8 Ctor_PokedexAreaMarkers(u16 species, u16 tilesTag, u8 palIdx, u8 y);
|
|
||||||
u8 PokedexAreaMarkers_Any(u8 taskId);
|
|
||||||
|
|
||||||
#endif //GUARD_POKEDEX_AREA_MARKERS_H
|
#endif //GUARD_POKEDEX_AREA_MARKERS_H
|
||||||
|
|||||||
+1
-1
@@ -1141,7 +1141,7 @@ extern const u8 gText_PeopleBattling[];
|
|||||||
extern const u8 gText_PeopleInUnionRoom[];
|
extern const u8 gText_PeopleInUnionRoom[];
|
||||||
extern const u8 gText_PeopleCommunicating[];
|
extern const u8 gText_PeopleCommunicating[];
|
||||||
|
|
||||||
// mevent
|
// mystery_gift
|
||||||
extern const u8 gJPText_ReceiveMysteryGiftWithEReader[];
|
extern const u8 gJPText_ReceiveMysteryGiftWithEReader[];
|
||||||
extern const u8 gJPText_SelectConnectFromEReaderMenu[];
|
extern const u8 gJPText_SelectConnectFromEReaderMenu[];
|
||||||
extern const u8 gJPText_SelectConnectWithGBA[];
|
extern const u8 gJPText_SelectConnectWithGBA[];
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
#define ROCK_WILD_COUNT 5
|
#define ROCK_WILD_COUNT 5
|
||||||
#define FISH_WILD_COUNT 10
|
#define FISH_WILD_COUNT 10
|
||||||
|
|
||||||
|
#define NUM_ALTERING_CAVE_TABLES 9
|
||||||
|
|
||||||
struct WildPokemon
|
struct WildPokemon
|
||||||
{
|
{
|
||||||
u8 minLevel;
|
u8 minLevel;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#ifndef GUARD_WILD_POKEMON_AREA_H
|
#ifndef GUARD_WILD_POKEMON_AREA_H
|
||||||
#define GUARD_WILD_POKEMON_AREA_H
|
#define GUARD_WILD_POKEMON_AREA_H
|
||||||
|
|
||||||
s32 BuildPokedexAreaSubspriteBuffer(u16 species, struct Subsprite * subsprites);
|
s32 GetSpeciesPokedexAreaMarkers(u16 species, struct Subsprite * subsprites);
|
||||||
|
|
||||||
#endif //GUARD_WILD_POKEMON_AREA_H
|
#endif //GUARD_WILD_POKEMON_AREA_H
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#ifndef GUARD_WONDER_NEWS_H
|
||||||
|
#define GUARD_WONDER_NEWS_H
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
WONDER_NEWS_NONE,
|
||||||
|
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
|
||||||
+14
-12
@@ -275,13 +275,14 @@ SECTIONS {
|
|||||||
src/slot_machine.o(.text);
|
src/slot_machine.o(.text);
|
||||||
src/roamer.o(.text);
|
src/roamer.o(.text);
|
||||||
src/mystery_gift_menu.o(.text);
|
src/mystery_gift_menu.o(.text);
|
||||||
src/mevent.o(.text);
|
src/ereader_screen.o(.text);
|
||||||
src/mevent_server_helpers.o(.text);
|
src/mystery_gift.o(.text);
|
||||||
src/mevent_client.o(.text);
|
src/mystery_gift_link.o(.text);
|
||||||
src/mevent_server.o(.text);
|
src/mystery_gift_client.o(.text);
|
||||||
|
src/mystery_gift_server.o(.text);
|
||||||
src/mystery_gift_show_card.o(.text);
|
src/mystery_gift_show_card.o(.text);
|
||||||
src/mystery_gift_show_news.o(.text);
|
src/mystery_gift_show_news.o(.text);
|
||||||
src/menews_jisan.o(.text);
|
src/wonder_news.o(.text);
|
||||||
src/seagallop.o(.text);
|
src/seagallop.o(.text);
|
||||||
src/pokemon_jump.o(.text);
|
src/pokemon_jump.o(.text);
|
||||||
src/berry_crush.o(.text);
|
src/berry_crush.o(.text);
|
||||||
@@ -568,15 +569,16 @@ SECTIONS {
|
|||||||
src/slot_machine.o(.rodata);
|
src/slot_machine.o(.rodata);
|
||||||
src/roamer.o(.rodata);
|
src/roamer.o(.rodata);
|
||||||
src/mystery_gift_menu.o(.rodata);
|
src/mystery_gift_menu.o(.rodata);
|
||||||
src/mevent.o(.rodata);
|
src/ereader_screen.o(.rodata);
|
||||||
src/mevent_server_helpers.o(.rodata);
|
src/mystery_gift.o(.rodata);
|
||||||
src/mevent_client.o(.rodata);
|
src/mystery_gift_link.o(.rodata);
|
||||||
src/mevent_server.o(.rodata);
|
src/mystery_gift_client.o(.rodata);
|
||||||
|
src/mystery_gift_server.o(.rodata);
|
||||||
src/mystery_gift_show_card.o(.rodata);
|
src/mystery_gift_show_card.o(.rodata);
|
||||||
src/mystery_gift_show_news.o(.rodata);
|
src/mystery_gift_show_news.o(.rodata);
|
||||||
src/mevent_scripts.o(.rodata);
|
src/mystery_gift_scripts.o(.rodata);
|
||||||
src/menews_jisan.o(.rodata);
|
src/wonder_news.o(.rodata);
|
||||||
src/menews_jisan.o(.rodata.str1.4);
|
src/wonder_news.o(.rodata.str1.4);
|
||||||
src/seagallop.o(.rodata);
|
src/seagallop.o(.rodata);
|
||||||
src/pokemon_jump.o(.rodata);
|
src/pokemon_jump.o(.rodata);
|
||||||
src/berry_crush.o(.rodata);
|
src/berry_crush.o(.rodata);
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@
|
|||||||
#include "link.h"
|
#include "link.h"
|
||||||
#include "load_save.h"
|
#include "load_save.h"
|
||||||
#include "m4a.h"
|
#include "m4a.h"
|
||||||
#include "mevent.h"
|
#include "mystery_gift.h"
|
||||||
#include "new_menu_helpers.h"
|
#include "new_menu_helpers.h"
|
||||||
#include "overworld.h"
|
#include "overworld.h"
|
||||||
#include "quest_log.h"
|
#include "quest_log.h"
|
||||||
|
|||||||
+4
-4
@@ -4,7 +4,7 @@
|
|||||||
#include "easy_chat.h"
|
#include "easy_chat.h"
|
||||||
#include "event_data.h"
|
#include "event_data.h"
|
||||||
#include "field_message_box.h"
|
#include "field_message_box.h"
|
||||||
#include "mevent.h"
|
#include "mystery_gift.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "mail.h"
|
#include "mail.h"
|
||||||
#include "pokedex.h"
|
#include "pokedex.h"
|
||||||
@@ -472,11 +472,11 @@ 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 < NUM_QUESTIONNAIRE_WORDS; i++)
|
||||||
ptr[i] = EC_WORD_UNDEFINED;
|
ptr[i] = EC_WORD_UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -3,7 +3,7 @@
|
|||||||
#include "easy_chat.h"
|
#include "easy_chat.h"
|
||||||
#include "event_data.h"
|
#include "event_data.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "mevent.h"
|
#include "mystery_gift.h"
|
||||||
#include "overworld.h"
|
#include "overworld.h"
|
||||||
#include "strings.h"
|
#include "strings.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -0,0 +1,520 @@
|
|||||||
|
#include "global.h"
|
||||||
|
#include "malloc.h"
|
||||||
|
#include "decompress.h"
|
||||||
|
#include "ereader_helpers.h"
|
||||||
|
#include "link.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "mystery_gift_menu.h"
|
||||||
|
#include "mystery_gift_client.h"
|
||||||
|
#include "save.h"
|
||||||
|
#include "sound.h"
|
||||||
|
#include "sprite.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "strings.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "cereader_tool.h"
|
||||||
|
#include "help_system.h"
|
||||||
|
#include "constants/songs.h"
|
||||||
|
|
||||||
|
struct EReaderTaskData
|
||||||
|
{
|
||||||
|
u16 timer;
|
||||||
|
u16 unused1;
|
||||||
|
u16 unused2;
|
||||||
|
u16 unused3;
|
||||||
|
u8 state;
|
||||||
|
u8 textState;
|
||||||
|
u8 unused4;
|
||||||
|
u8 unused5;
|
||||||
|
u8 unused6;
|
||||||
|
u8 unused7;
|
||||||
|
u8 status;
|
||||||
|
u8 *unusedBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EReaderData
|
||||||
|
{
|
||||||
|
u16 status;
|
||||||
|
size_t size;
|
||||||
|
const void *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Task_EReader(u8);
|
||||||
|
|
||||||
|
struct EReaderData gEReaderData;
|
||||||
|
|
||||||
|
extern const u8 gMultiBootProgram_EReader_Start[];
|
||||||
|
extern const u8 gMultiBootProgram_EReader_End[];
|
||||||
|
|
||||||
|
static void EReader_Load(struct EReaderData *eReader, size_t size, const void *data)
|
||||||
|
{
|
||||||
|
vu16 imeBak = REG_IME;
|
||||||
|
REG_IME = 0;
|
||||||
|
gIntrTable[1] = EReaderHelper_SerialCallback;
|
||||||
|
gIntrTable[2] = EReaderHelper_Timer3Callback;
|
||||||
|
EReaderHelper_SaveRegsState();
|
||||||
|
EReaderHelper_ClearsSendRecvMgr();
|
||||||
|
REG_IE |= INTR_FLAG_VCOUNT;
|
||||||
|
REG_IME = imeBak;
|
||||||
|
eReader->status = 0;
|
||||||
|
eReader->size = size;
|
||||||
|
eReader->data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void EReader_Reset(struct EReaderData *eReader)
|
||||||
|
{
|
||||||
|
vu16 imeBak = REG_IME;
|
||||||
|
REG_IME = 0;
|
||||||
|
EReaderHelper_ClearsSendRecvMgr();
|
||||||
|
EReaderHelper_RestoreRegsState();
|
||||||
|
RestoreSerialTimer3IntrHandlers();
|
||||||
|
REG_IME = imeBak;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return values for EReader_Transfer
|
||||||
|
enum {
|
||||||
|
TRANSFER_ACTIVE,
|
||||||
|
TRANSFER_SUCCESS,
|
||||||
|
TRANSFER_CANCELED,
|
||||||
|
TRANSFER_TIMEOUT,
|
||||||
|
};
|
||||||
|
|
||||||
|
static u8 EReader_Transfer(struct EReaderData *eReader)
|
||||||
|
{
|
||||||
|
u8 transferStatus = TRANSFER_ACTIVE;
|
||||||
|
eReader->status = EReaderHandleTransfer(TRUE, eReader->size, eReader->data, NULL);
|
||||||
|
|
||||||
|
if ((eReader->status & EREADER_XFER_MASK) == 0 && eReader->status & EREADER_CHECKSUM_OK_MASK)
|
||||||
|
transferStatus = TRANSFER_SUCCESS;
|
||||||
|
|
||||||
|
if (eReader->status & EREADER_CANCEL_KEY_MASK)
|
||||||
|
transferStatus = TRANSFER_CANCELED;
|
||||||
|
|
||||||
|
if (eReader->status & EREADER_CANCEL_TIMEOUT_MASK)
|
||||||
|
transferStatus = TRANSFER_TIMEOUT;
|
||||||
|
|
||||||
|
gShouldAdvanceLinkState = 0;
|
||||||
|
return transferStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void OpenEReaderLink(void)
|
||||||
|
{
|
||||||
|
memset(gDecompressionBuffer, 0, 0x2000);
|
||||||
|
gLinkType = LINKTYPE_EREADER_FRLG;
|
||||||
|
OpenLink();
|
||||||
|
SetSuppressLinkErrorMessage(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32 ValidateEReaderConnection(void)
|
||||||
|
{
|
||||||
|
vu16 imeBak = REG_IME;
|
||||||
|
u16 handshakes[MAX_LINK_PLAYERS];
|
||||||
|
|
||||||
|
REG_IME = 0;
|
||||||
|
*(u64 *)handshakes = *(u64 *)gLink.tempRecvBuffer;
|
||||||
|
REG_IME = imeBak;
|
||||||
|
|
||||||
|
// Validate that we are player 1, the EReader is player 2,
|
||||||
|
// and that players 3 and 4 are empty.
|
||||||
|
if (handshakes[0] == SLAVE_HANDSHAKE
|
||||||
|
&& handshakes[1] == EREADER_HANDSHAKE
|
||||||
|
&& handshakes[2] == 0xFFFF
|
||||||
|
&& handshakes[3] == 0xFFFF)
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32 IsEReaderConnectionSane(void)
|
||||||
|
{
|
||||||
|
if (IsLinkMaster() && GetLinkPlayerCount_2() == 2)
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// States for TryReceiveCard
|
||||||
|
enum {
|
||||||
|
RECV_STATE_INIT,
|
||||||
|
RECV_STATE_WAIT_START,
|
||||||
|
RECV_STATE_START,
|
||||||
|
RECV_STATE_EXCHANGE,
|
||||||
|
RECV_STATE_START_DISCONNECT,
|
||||||
|
RECV_STATE_WAIT_DISCONNECT,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Return values for TryReceiveCard
|
||||||
|
enum {
|
||||||
|
RECV_ACTIVE,
|
||||||
|
RECV_CANCELED,
|
||||||
|
RECV_SUCCESS,
|
||||||
|
RECV_ERROR,
|
||||||
|
RECV_DISCONNECTED,
|
||||||
|
RECV_TIMEOUT,
|
||||||
|
};
|
||||||
|
|
||||||
|
static u32 TryReceiveCard(u8 * state, u16 * timer)
|
||||||
|
{
|
||||||
|
if ((*state == RECV_STATE_EXCHANGE
|
||||||
|
|| *state == RECV_STATE_START_DISCONNECT
|
||||||
|
|| *state == RECV_STATE_WAIT_DISCONNECT)
|
||||||
|
&& HasLinkErrorOccurred())
|
||||||
|
{
|
||||||
|
// Return error status if an error occurs
|
||||||
|
// during the link exchange.
|
||||||
|
*state = 0;
|
||||||
|
return RECV_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (*state)
|
||||||
|
{
|
||||||
|
case RECV_STATE_INIT:
|
||||||
|
if (IsLinkMaster() && GetLinkPlayerCount_2() > 1)
|
||||||
|
{
|
||||||
|
*state = RECV_STATE_WAIT_START;
|
||||||
|
}
|
||||||
|
else if (JOY_NEW(B_BUTTON))
|
||||||
|
{
|
||||||
|
*state = 0;
|
||||||
|
return RECV_CANCELED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RECV_STATE_WAIT_START:
|
||||||
|
if (++(*timer) > 5)
|
||||||
|
{
|
||||||
|
*timer = 0;
|
||||||
|
*state = RECV_STATE_START;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RECV_STATE_START:
|
||||||
|
if (GetLinkPlayerCount_2() == 2)
|
||||||
|
{
|
||||||
|
PlaySE(SE_DING_DONG);
|
||||||
|
CheckShouldAdvanceLinkState();
|
||||||
|
*timer = 0;
|
||||||
|
*state = RECV_STATE_EXCHANGE;
|
||||||
|
}
|
||||||
|
else if (JOY_NEW(B_BUTTON))
|
||||||
|
{
|
||||||
|
*state = 0;
|
||||||
|
return RECV_CANCELED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RECV_STATE_EXCHANGE:
|
||||||
|
if (++(*timer) > 30)
|
||||||
|
{
|
||||||
|
*state = 0;
|
||||||
|
return RECV_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsLinkConnectionEstablished())
|
||||||
|
{
|
||||||
|
if (gReceivedRemoteLinkPlayers)
|
||||||
|
{
|
||||||
|
if (IsLinkPlayerDataExchangeComplete())
|
||||||
|
{
|
||||||
|
*state = 0;
|
||||||
|
return RECV_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*state = RECV_STATE_START_DISCONNECT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*state = RECV_STATE_EXCHANGE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RECV_STATE_START_DISCONNECT:
|
||||||
|
SetCloseLinkCallbackAndType(0);
|
||||||
|
*state = RECV_STATE_WAIT_DISCONNECT;
|
||||||
|
break;
|
||||||
|
case RECV_STATE_WAIT_DISCONNECT:
|
||||||
|
if (!gReceivedRemoteLinkPlayers)
|
||||||
|
{
|
||||||
|
*state = 0;
|
||||||
|
return RECV_DISCONNECTED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return RECV_ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateEReaderTask(void)
|
||||||
|
{
|
||||||
|
u8 taskId = CreateTask(Task_EReader, 0);
|
||||||
|
struct EReaderTaskData *data = (struct EReaderTaskData *)gTasks[taskId].data;
|
||||||
|
data->state = 0;
|
||||||
|
data->textState = 0;
|
||||||
|
data->unused4 = 0;
|
||||||
|
data->unused5 = 0;
|
||||||
|
data->unused6 = 0;
|
||||||
|
data->unused7 = 0;
|
||||||
|
data->timer = 0;
|
||||||
|
data->unused1 = 0;
|
||||||
|
data->unused2 = 0;
|
||||||
|
data->unused3 = 0;
|
||||||
|
data->status = 0;
|
||||||
|
data->unusedBuffer = AllocZeroed(CLIENT_MAX_MSG_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ResetTimer(u16 *timer)
|
||||||
|
{
|
||||||
|
*timer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32 UpdateTimer(u16 * timer, u16 time)
|
||||||
|
{
|
||||||
|
if (++(*timer) > time)
|
||||||
|
{
|
||||||
|
// Timer has finished
|
||||||
|
*timer = 0;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// States for Task_EReader
|
||||||
|
enum {
|
||||||
|
ER_STATE_START,
|
||||||
|
ER_STATE_INIT_LINK,
|
||||||
|
ER_STATE_INIT_LINK_WAIT,
|
||||||
|
ER_STATE_INIT_LINK_CHECK,
|
||||||
|
ER_STATE_MSG_SELECT_CONNECT,
|
||||||
|
ER_STATE_MSG_SELECT_CONNECT_WAIT,
|
||||||
|
ER_STATE_TRY_LINK,
|
||||||
|
ER_STATE_INCORRECT_LINK,
|
||||||
|
ER_STATE_CONNECTING,
|
||||||
|
ER_STATE_TRANSFER,
|
||||||
|
ER_STATE_TRANSFER_END,
|
||||||
|
ER_STATE_TRANSFER_SUCCESS,
|
||||||
|
ER_STATE_LOAD_CARD_START,
|
||||||
|
ER_STATE_LOAD_CARD,
|
||||||
|
ER_STATE_WAIT_RECV_CARD,
|
||||||
|
ER_STATE_VALIDATE_CARD,
|
||||||
|
ER_STATE_WAIT_DISCONNECT,
|
||||||
|
ER_STATE_SAVE,
|
||||||
|
ER_STATE_SUCCESS_MSG,
|
||||||
|
ER_STATE_SUCCESS_END,
|
||||||
|
ER_STATE_LINK_ERROR,
|
||||||
|
ER_STATE_LINK_ERROR_TRY_AGAIN,
|
||||||
|
ER_STATE_SAVE_FAILED,
|
||||||
|
ER_STATE_CANCELED_CARD_READ,
|
||||||
|
ER_STATE_UNUSED_1,
|
||||||
|
ER_STATE_UNUSED_2,
|
||||||
|
ER_STATE_END,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void Task_EReader(u8 taskId)
|
||||||
|
{
|
||||||
|
struct EReaderTaskData *data = (struct EReaderTaskData *)gTasks[taskId].data;
|
||||||
|
switch (data->state)
|
||||||
|
{
|
||||||
|
case ER_STATE_START:
|
||||||
|
if (PrintMysteryGiftMenuMessage(&data->textState, gJPText_ReceiveMysteryGiftWithEReader))
|
||||||
|
data->state = ER_STATE_INIT_LINK;
|
||||||
|
break;
|
||||||
|
case ER_STATE_INIT_LINK:
|
||||||
|
OpenEReaderLink();
|
||||||
|
ResetTimer(&data->timer);
|
||||||
|
data->state = ER_STATE_INIT_LINK_WAIT;
|
||||||
|
break;
|
||||||
|
case ER_STATE_INIT_LINK_WAIT:
|
||||||
|
if (UpdateTimer(&data->timer, 10))
|
||||||
|
data->state = ER_STATE_INIT_LINK_CHECK;
|
||||||
|
break;
|
||||||
|
case ER_STATE_INIT_LINK_CHECK:
|
||||||
|
if (!IsEReaderConnectionSane())
|
||||||
|
{
|
||||||
|
CloseLink();
|
||||||
|
data->state = ER_STATE_MSG_SELECT_CONNECT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
data->state = ER_STATE_LOAD_CARD;
|
||||||
|
break;
|
||||||
|
case ER_STATE_MSG_SELECT_CONNECT:
|
||||||
|
if (PrintMysteryGiftMenuMessage(&data->textState, gJPText_SelectConnectFromEReaderMenu))
|
||||||
|
{
|
||||||
|
AddTextPrinterToWindow1(gJPText_SelectConnectWithGBA);
|
||||||
|
ResetTimer(&data->timer);
|
||||||
|
data->state = ER_STATE_MSG_SELECT_CONNECT_WAIT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ER_STATE_MSG_SELECT_CONNECT_WAIT:
|
||||||
|
if (UpdateTimer(&data->timer, 90))
|
||||||
|
{
|
||||||
|
OpenEReaderLink();
|
||||||
|
data->state = ER_STATE_TRY_LINK;
|
||||||
|
}
|
||||||
|
else if (JOY_NEW(B_BUTTON))
|
||||||
|
{
|
||||||
|
ResetTimer(&data->timer);
|
||||||
|
PlaySE(SE_SELECT);
|
||||||
|
data->state = ER_STATE_CANCELED_CARD_READ;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ER_STATE_TRY_LINK:
|
||||||
|
if (JOY_NEW(B_BUTTON))
|
||||||
|
{
|
||||||
|
// Canceled
|
||||||
|
PlaySE(SE_SELECT);
|
||||||
|
CloseLink();
|
||||||
|
ResetTimer(&data->timer);
|
||||||
|
data->state = ER_STATE_CANCELED_CARD_READ;
|
||||||
|
}
|
||||||
|
else if (GetLinkPlayerCount_2() > 1)
|
||||||
|
{
|
||||||
|
ResetTimer(&data->timer);
|
||||||
|
CloseLink();
|
||||||
|
data->state = ER_STATE_INCORRECT_LINK;
|
||||||
|
}
|
||||||
|
else if (ValidateEReaderConnection())
|
||||||
|
{
|
||||||
|
// Successful connection
|
||||||
|
PlaySE(SE_SELECT);
|
||||||
|
CloseLink();
|
||||||
|
ResetTimer(&data->timer);
|
||||||
|
data->state = ER_STATE_CONNECTING;
|
||||||
|
}
|
||||||
|
else if (UpdateTimer(&data->timer, 10))
|
||||||
|
{
|
||||||
|
// Retry connection
|
||||||
|
CloseLink();
|
||||||
|
OpenEReaderLink();
|
||||||
|
ResetTimer(&data->timer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ER_STATE_INCORRECT_LINK:
|
||||||
|
if (PrintMysteryGiftMenuMessage(&data->textState, gJPText_LinkIsIncorrect))
|
||||||
|
data->state = ER_STATE_MSG_SELECT_CONNECT;
|
||||||
|
break;
|
||||||
|
case ER_STATE_CONNECTING:
|
||||||
|
AddTextPrinterToWindow1(gJPText_Connecting);
|
||||||
|
EReader_Load(&gEReaderData, gMultiBootProgram_EReader_End - gMultiBootProgram_EReader_Start, gMultiBootProgram_EReader_Start);
|
||||||
|
data->state = ER_STATE_TRANSFER;
|
||||||
|
break;
|
||||||
|
case ER_STATE_TRANSFER:
|
||||||
|
data->status = EReader_Transfer(&gEReaderData);
|
||||||
|
if (data->status != TRANSFER_ACTIVE)
|
||||||
|
data->state = ER_STATE_TRANSFER_END;
|
||||||
|
break;
|
||||||
|
case ER_STATE_TRANSFER_END:
|
||||||
|
EReader_Reset(&gEReaderData);
|
||||||
|
if (data->status == TRANSFER_TIMEOUT)
|
||||||
|
{
|
||||||
|
data->state = ER_STATE_LINK_ERROR;
|
||||||
|
}
|
||||||
|
else if (data->status == TRANSFER_SUCCESS)
|
||||||
|
{
|
||||||
|
ResetTimer(&data->timer);
|
||||||
|
AddTextPrinterToWindow1(gJPText_PleaseWaitAMoment);
|
||||||
|
data->state = ER_STATE_TRANSFER_SUCCESS;
|
||||||
|
}
|
||||||
|
else // TRANSFER_CANCELED
|
||||||
|
{
|
||||||
|
data->state = ER_STATE_START;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ER_STATE_TRANSFER_SUCCESS:
|
||||||
|
if (UpdateTimer(&data->timer, 840))
|
||||||
|
data->state = ER_STATE_LOAD_CARD_START;
|
||||||
|
break;
|
||||||
|
case ER_STATE_LOAD_CARD_START:
|
||||||
|
OpenEReaderLink();
|
||||||
|
AddTextPrinterToWindow1(gJPText_AllowEReaderToLoadCard);
|
||||||
|
data->state = ER_STATE_LOAD_CARD;
|
||||||
|
break;
|
||||||
|
case ER_STATE_LOAD_CARD:
|
||||||
|
switch (TryReceiveCard(&data->textState, &data->timer))
|
||||||
|
{
|
||||||
|
case RECV_ACTIVE:
|
||||||
|
// Running
|
||||||
|
break;
|
||||||
|
case RECV_SUCCESS:
|
||||||
|
AddTextPrinterToWindow1(gJPText_Connecting);
|
||||||
|
data->state = ER_STATE_WAIT_RECV_CARD;
|
||||||
|
break;
|
||||||
|
case RECV_CANCELED:
|
||||||
|
PlaySE(SE_SELECT);
|
||||||
|
CloseLink();
|
||||||
|
data->state = ER_STATE_CANCELED_CARD_READ;
|
||||||
|
break;
|
||||||
|
case RECV_TIMEOUT:
|
||||||
|
CloseLink();
|
||||||
|
data->state = ER_STATE_LINK_ERROR_TRY_AGAIN;
|
||||||
|
break;
|
||||||
|
case RECV_ERROR:
|
||||||
|
case RECV_DISCONNECTED:
|
||||||
|
CloseLink();
|
||||||
|
data->state = ER_STATE_LINK_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ER_STATE_WAIT_RECV_CARD:
|
||||||
|
if (HasLinkErrorOccurred())
|
||||||
|
{
|
||||||
|
CloseLink();
|
||||||
|
data->state = ER_STATE_LINK_ERROR;
|
||||||
|
}
|
||||||
|
else if (GetBlockReceivedStatus())
|
||||||
|
{
|
||||||
|
ResetBlockReceivedFlags();
|
||||||
|
data->state = ER_STATE_VALIDATE_CARD;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ER_STATE_VALIDATE_CARD:
|
||||||
|
data->status = ValidateTrainerTowerData((struct EReaderTrainerTowerSet *)gDecompressionBuffer);
|
||||||
|
SetCloseLinkCallbackAndType(data->status);
|
||||||
|
data->state = ER_STATE_WAIT_DISCONNECT;
|
||||||
|
break;
|
||||||
|
case ER_STATE_WAIT_DISCONNECT:
|
||||||
|
if (!gReceivedRemoteLinkPlayers)
|
||||||
|
{
|
||||||
|
if (data->status == TRUE) // Was data valid?
|
||||||
|
data->state = ER_STATE_SAVE;
|
||||||
|
else
|
||||||
|
data->state = ER_STATE_LINK_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ER_STATE_SAVE:
|
||||||
|
if (CEReaderTool_SaveTrainerTower((struct EReaderTrainerTowerSet *)gDecompressionBuffer))
|
||||||
|
{
|
||||||
|
AddTextPrinterToWindow1(gJPText_ConnectionComplete);
|
||||||
|
ResetTimer(&data->timer);
|
||||||
|
data->state = ER_STATE_SUCCESS_MSG;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
data->state = ER_STATE_SAVE_FAILED;
|
||||||
|
break;
|
||||||
|
case ER_STATE_SUCCESS_MSG:
|
||||||
|
if (UpdateTimer(&data->timer, 120))
|
||||||
|
{
|
||||||
|
AddTextPrinterToWindow1(gJPText_NewTrainerHasComeToSevii);
|
||||||
|
PlayFanfare(MUS_OBTAIN_ITEM);
|
||||||
|
data->state = ER_STATE_SUCCESS_END;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ER_STATE_SUCCESS_END:
|
||||||
|
if (IsFanfareTaskInactive() && JOY_NEW(A_BUTTON | B_BUTTON))
|
||||||
|
data->state = ER_STATE_END;
|
||||||
|
break;
|
||||||
|
case ER_STATE_CANCELED_CARD_READ:
|
||||||
|
if (PrintMysteryGiftMenuMessage(&data->textState, gJPText_CardReadingHasBeenHalted))
|
||||||
|
data->state = ER_STATE_END;
|
||||||
|
break;
|
||||||
|
case ER_STATE_LINK_ERROR:
|
||||||
|
if (PrintMysteryGiftMenuMessage(&data->textState, gJPText_ConnectionErrorCheckLink))
|
||||||
|
data->state = ER_STATE_START;
|
||||||
|
break;
|
||||||
|
case ER_STATE_LINK_ERROR_TRY_AGAIN:
|
||||||
|
if (PrintMysteryGiftMenuMessage(&data->textState, gJPText_ConnectionErrorTryAgain))
|
||||||
|
data->state = ER_STATE_START;
|
||||||
|
break;
|
||||||
|
case ER_STATE_SAVE_FAILED:
|
||||||
|
if (PrintMysteryGiftMenuMessage(&data->textState, gJPText_WriteErrorUnableToSaveData))
|
||||||
|
data->state = ER_STATE_START;
|
||||||
|
break;
|
||||||
|
case ER_STATE_END:
|
||||||
|
HelpSystem_Enable();
|
||||||
|
Free(data->unusedBuffer);
|
||||||
|
DestroyTask(taskId);
|
||||||
|
SetMainCallback2(MainCB_FreeAllBuffersAndReturnToInitTitleScreen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -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);
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
#include "field_specials.h"
|
#include "field_specials.h"
|
||||||
#include "item_menu.h"
|
#include "item_menu.h"
|
||||||
#include "link.h"
|
#include "link.h"
|
||||||
#include "menews_jisan.h"
|
#include "wonder_news.h"
|
||||||
#include "metatile_behavior.h"
|
#include "metatile_behavior.h"
|
||||||
#include "overworld.h"
|
#include "overworld.h"
|
||||||
#include "renewable_hidden_items.h"
|
#include "renewable_hidden_items.h"
|
||||||
@@ -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();
|
||||||
|
|||||||
+12
-12
@@ -28,7 +28,7 @@
|
|||||||
#include "pokedex.h"
|
#include "pokedex.h"
|
||||||
#include "text_window.h"
|
#include "text_window.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "mevent.h"
|
#include "mystery_gift.h"
|
||||||
#include "naming_screen.h"
|
#include "naming_screen.h"
|
||||||
#include "party_menu.h"
|
#include "party_menu.h"
|
||||||
#include "dynamic_placeholder_text_util.h"
|
#include "dynamic_placeholder_text_util.h"
|
||||||
@@ -1950,20 +1950,20 @@ void QuestLog_TryRecordDepartedLocation(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 BattleCardAction(void)
|
u16 GetMysteryGiftCardStat(void)
|
||||||
{
|
{
|
||||||
switch (gSpecialVar_Result)
|
switch (gSpecialVar_Result)
|
||||||
{
|
{
|
||||||
case 0:
|
case GET_NUM_STAMPS:
|
||||||
return MEvent_GetBattleCardCount(3);
|
return MysteryGift_GetCardStat(CARD_STAT_NUM_STAMPS);
|
||||||
case 1:
|
case GET_MAX_STAMPS:
|
||||||
return MEvent_GetBattleCardCount(4);
|
return MysteryGift_GetCardStat(CARD_STAT_MAX_STAMPS);
|
||||||
case 2:
|
case GET_CARD_BATTLES_WON:
|
||||||
return MEvent_GetBattleCardCount(0);
|
return MysteryGift_GetCardStat(CARD_STAT_BATTLES_WON);
|
||||||
case 3:
|
case GET_CARD_BATTLES_LOST:
|
||||||
return MEvent_GetBattleCardCount(1);
|
return MysteryGift_GetCardStat(CARD_STAT_BATTLES_LOST);
|
||||||
case 4:
|
case GET_CARD_NUM_TRADES:
|
||||||
return MEvent_GetBattleCardCount(2);
|
return MysteryGift_GetCardStat(CARD_STAT_NUM_TRADES);
|
||||||
default:
|
default:
|
||||||
AGB_ASSERT_EX(0, ABSPATH("scr_tool.c"), 3873);
|
AGB_ASSERT_EX(0, ABSPATH("scr_tool.c"), 3873);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+1
-1
@@ -481,7 +481,7 @@ static void Task_ExecuteMainMenuSelection(u8 taskId)
|
|||||||
TrySetUpQuestLogScenes_ElseContinueFromSave(taskId);
|
TrySetUpQuestLogScenes_ElseContinueFromSave(taskId);
|
||||||
break;
|
break;
|
||||||
case MAIN_MENU_MYSTERYGIFT:
|
case MAIN_MENU_MYSTERYGIFT:
|
||||||
SetMainCallback2(c2_mystery_gift);
|
SetMainCallback2(CB2_InitMysteryGift);
|
||||||
HelpSystem_Disable();
|
HelpSystem_Disable();
|
||||||
FreeAllWindowBuffers();
|
FreeAllWindowBuffers();
|
||||||
DestroyTask(taskId);
|
DestroyTask(taskId);
|
||||||
|
|||||||
@@ -1,148 +0,0 @@
|
|||||||
#include "global.h"
|
|
||||||
#include "mevent.h"
|
|
||||||
#include "random.h"
|
|
||||||
#include "event_data.h"
|
|
||||||
#include "menews_jisan.h"
|
|
||||||
#include "constants/items.h"
|
|
||||||
|
|
||||||
static u32 GetMENewsJisanRewardItem(struct WonderNewsMetadata *);
|
|
||||||
static void MENewsJisanIncrementCounterUnk0_5(struct WonderNewsMetadata *);
|
|
||||||
static u32 GetMENewsJisanState(struct WonderNewsMetadata *);
|
|
||||||
static void MENewsJisanIncrementCounterUnk0_2(struct WonderNewsMetadata *);
|
|
||||||
static void MENewsJisanResetCounterUnk0_2(struct WonderNewsMetadata *);
|
|
||||||
|
|
||||||
void MENewsJisan_SetRandomReward(u32 a0)
|
|
||||||
{
|
|
||||||
struct WonderNewsMetadata *r5 = GetMENewsJisanStructPtr();
|
|
||||||
|
|
||||||
r5->unk_0_0 = a0;
|
|
||||||
switch (a0)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
case 2:
|
|
||||||
r5->berry = (Random() % 15) + ITEM_TO_BERRY(ITEM_RAZZ_BERRY);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
r5->berry = (Random() % 15) + ITEM_TO_BERRY(ITEM_CHERI_BERRY);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MENewsJisanReset(void)
|
|
||||||
{
|
|
||||||
struct WonderNewsMetadata *r5 = GetMENewsJisanStructPtr();
|
|
||||||
|
|
||||||
r5->unk_0_0 = 0;
|
|
||||||
r5->unk_0_2 = 0;
|
|
||||||
r5->unk_0_5 = 0;
|
|
||||||
r5->berry = 0;
|
|
||||||
VarSet(VAR_MENEWS_JISAN_STEP_COUNTER, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MENewsJisanStepCounter(void)
|
|
||||||
{
|
|
||||||
u16 *r4 = GetVarPointer(VAR_MENEWS_JISAN_STEP_COUNTER);
|
|
||||||
struct WonderNewsMetadata *r2 = GetMENewsJisanStructPtr();
|
|
||||||
struct WonderNewsMetadata r0 = *r2;
|
|
||||||
|
|
||||||
if ((u8)r0.unk_0_5 > 4 && ++(*r4) >= 500)
|
|
||||||
{
|
|
||||||
r2->unk_0_5 = 0;
|
|
||||||
*r4 = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
u16 GetMENewsJisanItemAndState(void)
|
|
||||||
{
|
|
||||||
u16 *r6 = &gSpecialVar_Result;
|
|
||||||
struct WonderNewsMetadata *r4 = GetMENewsJisanStructPtr();
|
|
||||||
u16 r5;
|
|
||||||
|
|
||||||
if (!IsMysteryGiftEnabled() || !ValidateReceivedWonderNews())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
r5 = GetMENewsJisanState(r4);
|
|
||||||
|
|
||||||
switch (r5)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
*r6 = GetMENewsJisanRewardItem(r4);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
*r6 = GetMENewsJisanRewardItem(r4);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
*r6 = GetMENewsJisanRewardItem(r4);
|
|
||||||
MENewsJisanIncrementCounterUnk0_2(r4);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
*r6 = GetMENewsJisanRewardItem(r4);
|
|
||||||
MENewsJisanResetCounterUnk0_2(r4);
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return r5;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 GetMENewsJisanRewardItem(struct WonderNewsMetadata *a0)
|
|
||||||
{
|
|
||||||
u32 r4;
|
|
||||||
|
|
||||||
a0->unk_0_0 = 0;
|
|
||||||
r4 = a0->berry + FIRST_BERRY_INDEX - 1;
|
|
||||||
a0->berry = 0;
|
|
||||||
MENewsJisanIncrementCounterUnk0_5(a0);
|
|
||||||
return r4;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void MENewsJisanResetCounterUnk0_2(struct WonderNewsMetadata *a0)
|
|
||||||
{
|
|
||||||
a0->unk_0_2 = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void MENewsJisanIncrementCounterUnk0_2(struct WonderNewsMetadata *a0)
|
|
||||||
{
|
|
||||||
a0->unk_0_2++;
|
|
||||||
if ((u8)a0->unk_0_2 > 4)
|
|
||||||
a0->unk_0_2 = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void MENewsJisanIncrementCounterUnk0_5(struct WonderNewsMetadata *a0)
|
|
||||||
{
|
|
||||||
a0->unk_0_5++;
|
|
||||||
if ((u8)a0->unk_0_5 > 5)
|
|
||||||
a0->unk_0_5 = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 GetMENewsJisanState(struct WonderNewsMetadata *a0)
|
|
||||||
{
|
|
||||||
struct WonderNewsMetadata r0;
|
|
||||||
if ((u8)a0->unk_0_5 == 5)
|
|
||||||
return 6;
|
|
||||||
|
|
||||||
r0 = *a0;
|
|
||||||
switch (r0.unk_0_0)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
return 3;
|
|
||||||
case 1:
|
|
||||||
return 1;
|
|
||||||
case 2:
|
|
||||||
return 2;
|
|
||||||
case 3:
|
|
||||||
if ((u8)r0.unk_0_2 < 3)
|
|
||||||
return 4;
|
|
||||||
return 5;
|
|
||||||
default:
|
|
||||||
AGB_ASSERT_EX(0, ABSPATH("menews_jisan.c"), 383);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-1029
File diff suppressed because it is too large
Load Diff
@@ -1,290 +0,0 @@
|
|||||||
#include "global.h"
|
|
||||||
#include "gflib.h"
|
|
||||||
#include "decompress.h"
|
|
||||||
#include "overworld.h"
|
|
||||||
#include "script.h"
|
|
||||||
#include "battle_tower.h"
|
|
||||||
#include "mystery_event_script.h"
|
|
||||||
#include "mevent.h"
|
|
||||||
#include "mevent_server.h"
|
|
||||||
|
|
||||||
static EWRAM_DATA struct mevent_client * s_mevent_client_ptr = NULL;
|
|
||||||
|
|
||||||
static void mevent_client_init(struct mevent_client *, u32, u32);
|
|
||||||
static u32 mevent_client_exec(struct mevent_client *);
|
|
||||||
static void mevent_client_free_resources(struct mevent_client *);
|
|
||||||
|
|
||||||
extern const struct mevent_client_cmd gMEventClientScript_InitialListen[];
|
|
||||||
|
|
||||||
void mevent_client_do_init(void)
|
|
||||||
{
|
|
||||||
s_mevent_client_ptr = AllocZeroed(sizeof(struct mevent_client));
|
|
||||||
mevent_client_init(s_mevent_client_ptr, 1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 mevent_client_do_exec(u16 * a0)
|
|
||||||
{
|
|
||||||
u32 result;
|
|
||||||
if (s_mevent_client_ptr == NULL)
|
|
||||||
return 6;
|
|
||||||
result = mevent_client_exec(s_mevent_client_ptr);
|
|
||||||
if (result == 6)
|
|
||||||
{
|
|
||||||
*a0 = s_mevent_client_ptr->param;
|
|
||||||
mevent_client_free_resources(s_mevent_client_ptr);
|
|
||||||
Free(s_mevent_client_ptr);
|
|
||||||
s_mevent_client_ptr = NULL;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mevent_client_inc_flag(void)
|
|
||||||
{
|
|
||||||
s_mevent_client_ptr->flag++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *mevent_client_get_buffer(void)
|
|
||||||
{
|
|
||||||
return s_mevent_client_ptr->buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mevent_client_set_param(u32 a0)
|
|
||||||
{
|
|
||||||
s_mevent_client_ptr->param = a0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mevent_client_init(struct mevent_client * svr, u32 sendPlayerNo, u32 recvPlayerNo)
|
|
||||||
{
|
|
||||||
svr->unk_00 = 0;
|
|
||||||
svr->mainseqno = 0;
|
|
||||||
svr->flag = 0;
|
|
||||||
svr->sendBuffer = AllocZeroed(ME_SEND_BUF_SIZE);
|
|
||||||
svr->recvBuffer = AllocZeroed(ME_SEND_BUF_SIZE);
|
|
||||||
svr->cmdBuffer = AllocZeroed(ME_SEND_BUF_SIZE);
|
|
||||||
svr->buffer = AllocZeroed(0x40);
|
|
||||||
mevent_srv_sub_init(&svr->manager, sendPlayerNo, recvPlayerNo);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mevent_client_free_resources(struct mevent_client * svr)
|
|
||||||
{
|
|
||||||
Free(svr->sendBuffer);
|
|
||||||
Free(svr->recvBuffer);
|
|
||||||
Free(svr->cmdBuffer);
|
|
||||||
Free(svr->buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mevent_client_jmp_buffer(struct mevent_client * svr)
|
|
||||||
{
|
|
||||||
memcpy(svr->cmdBuffer, svr->recvBuffer, ME_SEND_BUF_SIZE);
|
|
||||||
svr->cmdidx = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mevent_client_send_word(struct mevent_client * svr, u32 ident, u32 word)
|
|
||||||
{
|
|
||||||
CpuFill32(0, svr->sendBuffer, ME_SEND_BUF_SIZE);
|
|
||||||
*(u32 *)svr->sendBuffer = word;
|
|
||||||
mevent_srv_sub_init_send(&svr->manager, ident, svr->sendBuffer, sizeof(u32));
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 client_mainseq_0(struct mevent_client * svr)
|
|
||||||
{
|
|
||||||
// init
|
|
||||||
memcpy(svr->cmdBuffer, gMEventClientScript_InitialListen, ME_SEND_BUF_SIZE);
|
|
||||||
svr->cmdidx = 0;
|
|
||||||
svr->mainseqno = 4;
|
|
||||||
svr->flag = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 client_mainseq_1(struct mevent_client * svr)
|
|
||||||
{
|
|
||||||
// done
|
|
||||||
return 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 client_mainseq_2(struct mevent_client * svr)
|
|
||||||
{
|
|
||||||
// do recv
|
|
||||||
if (mevent_srv_sub_recv(&svr->manager))
|
|
||||||
{
|
|
||||||
svr->mainseqno = 4;
|
|
||||||
svr->flag = 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 client_mainseq_3(struct mevent_client * svr)
|
|
||||||
{
|
|
||||||
// do send
|
|
||||||
if (mevent_srv_sub_send(&svr->manager))
|
|
||||||
{
|
|
||||||
svr->mainseqno = 4;
|
|
||||||
svr->flag = 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 client_mainseq_4(struct mevent_client * svr)
|
|
||||||
{
|
|
||||||
// process command
|
|
||||||
struct mevent_client_cmd * cmd = &svr->cmdBuffer[svr->cmdidx];
|
|
||||||
++svr->cmdidx;
|
|
||||||
switch (cmd->instr)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
svr->param = cmd->parameter;
|
|
||||||
svr->mainseqno = 1;
|
|
||||||
svr->flag = 0;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
mevent_srv_sub_init_recv(&svr->manager, cmd->parameter, svr->recvBuffer);
|
|
||||||
svr->mainseqno = 2;
|
|
||||||
svr->flag = 0;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
svr->mainseqno = 3;
|
|
||||||
svr->flag = 0;
|
|
||||||
break;
|
|
||||||
case 20:
|
|
||||||
mevent_srv_sub_init_send(&svr->manager, 0x14, svr->sendBuffer, 0);
|
|
||||||
svr->mainseqno = 3;
|
|
||||||
svr->flag = 0;
|
|
||||||
break;
|
|
||||||
case 19:
|
|
||||||
mevent_client_send_word(svr, 0x12, GetGameStat(cmd->parameter));
|
|
||||||
svr->mainseqno = 3;
|
|
||||||
svr->flag = 0;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
if (svr->param == 0)
|
|
||||||
mevent_client_jmp_buffer(svr);
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
if (svr->param == 1)
|
|
||||||
mevent_client_jmp_buffer(svr);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
mevent_client_jmp_buffer(svr);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
memcpy(svr->buffer, svr->recvBuffer, 0x40);
|
|
||||||
svr->mainseqno = 5;
|
|
||||||
svr->flag = 0;
|
|
||||||
return 2;
|
|
||||||
case 11:
|
|
||||||
memcpy(svr->buffer, svr->recvBuffer, 0x40);
|
|
||||||
svr->mainseqno = 5;
|
|
||||||
svr->flag = 0;
|
|
||||||
return 3;
|
|
||||||
case 12:
|
|
||||||
memcpy(svr->buffer, svr->recvBuffer, 0x40);
|
|
||||||
svr->mainseqno = 5;
|
|
||||||
svr->flag = 0;
|
|
||||||
return 5;
|
|
||||||
case 13:
|
|
||||||
svr->mainseqno = 5;
|
|
||||||
svr->flag = 0;
|
|
||||||
return 4;
|
|
||||||
case 8:
|
|
||||||
BuildMEventClientHeader(svr->sendBuffer);
|
|
||||||
mevent_srv_sub_init_send(&svr->manager, 0x11, svr->sendBuffer, sizeof(struct MEventClientHeaderStruct));
|
|
||||||
break;
|
|
||||||
case 14:
|
|
||||||
mevent_client_send_word(svr, 0x13, svr->param);
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
OverwriteSavedWonderCardWithReceivedCard(svr->recvBuffer);
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
if (!MEvent_HaveAlreadyReceivedWonderNews(svr->recvBuffer))
|
|
||||||
{
|
|
||||||
OverwriteSavedWonderNewsWithReceivedNews(svr->recvBuffer);
|
|
||||||
mevent_client_send_word(svr, 0x13, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
// Other trainer already has news
|
|
||||||
mevent_client_send_word(svr, 0x13, 1);
|
|
||||||
break;
|
|
||||||
case 15:
|
|
||||||
svr->mainseqno = 6;
|
|
||||||
svr->flag = 0;
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
MEvent_ReceiveDistributionMon(svr->recvBuffer);
|
|
||||||
break;
|
|
||||||
case 17:
|
|
||||||
InitRamScript_NoObjectEvent(svr->recvBuffer, 1000);
|
|
||||||
break;
|
|
||||||
case 18:
|
|
||||||
memcpy(&gSaveBlock2Ptr->battleTower.ereaderTrainer, svr->recvBuffer, sizeof(struct BattleTowerEReaderTrainer));
|
|
||||||
ValidateEReaderTrainer();
|
|
||||||
break;
|
|
||||||
case 21:
|
|
||||||
memcpy(gDecompressionBuffer, svr->recvBuffer, ME_SEND_BUF_SIZE);
|
|
||||||
svr->mainseqno = 7;
|
|
||||||
svr->flag = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 client_mainseq_5(struct mevent_client * svr)
|
|
||||||
{
|
|
||||||
// wait flag
|
|
||||||
if (svr->flag)
|
|
||||||
{
|
|
||||||
svr->mainseqno = 4;
|
|
||||||
svr->flag = 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 client_mainseq_6(struct mevent_client * svr)
|
|
||||||
{
|
|
||||||
// Run mevent buffer script
|
|
||||||
switch (svr->flag)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
MEventScript_InitContext(svr->recvBuffer);
|
|
||||||
++svr->flag;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if (!MEventScript_Run(&svr->param))
|
|
||||||
{
|
|
||||||
svr->mainseqno = 4;
|
|
||||||
svr->flag = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 client_mainseq_7(struct mevent_client * svr)
|
|
||||||
{
|
|
||||||
// exec arbitrary code
|
|
||||||
u32 (*func)(u32 *, struct SaveBlock2 *, struct SaveBlock1 *) = (void *)gDecompressionBuffer;
|
|
||||||
if (func(&svr->param, gSaveBlock2Ptr, gSaveBlock1Ptr) == 1)
|
|
||||||
{
|
|
||||||
svr->mainseqno = 4;
|
|
||||||
svr->flag = 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 mevent_client_exec(struct mevent_client * svr)
|
|
||||||
{
|
|
||||||
u32 (*funcs[])(struct mevent_client *) = {
|
|
||||||
client_mainseq_0,
|
|
||||||
client_mainseq_1,
|
|
||||||
client_mainseq_2,
|
|
||||||
client_mainseq_3,
|
|
||||||
client_mainseq_4,
|
|
||||||
client_mainseq_5,
|
|
||||||
client_mainseq_6,
|
|
||||||
client_mainseq_7
|
|
||||||
};
|
|
||||||
return funcs[svr->mainseqno](svr);
|
|
||||||
}
|
|
||||||
@@ -1,192 +0,0 @@
|
|||||||
#include "global.h"
|
|
||||||
#include "mevent_server.h"
|
|
||||||
|
|
||||||
extern const struct mevent_server_cmd gServerScript_ClientCanceledCard[];
|
|
||||||
|
|
||||||
// Unreferenced
|
|
||||||
const u8 gUnknown_84687A0[] = _("You have collected all STAMPs!\nWant to input a CARD as a prize?");
|
|
||||||
|
|
||||||
/* CLIENT SCRIPTS */
|
|
||||||
|
|
||||||
const struct mevent_client_cmd gMEventClientScript_InitialListen[] = { // 84687E0
|
|
||||||
CLI_RECEIVE(0x10),
|
|
||||||
CLI_JUMPBUF
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct mevent_client_cmd gMEventClientScript_Send1442CC[] = {
|
|
||||||
CLI_SNDHEAD,
|
|
||||||
CLI_WAITSND,
|
|
||||||
CLI_RECEIVE(0x10),
|
|
||||||
CLI_JUMPBUF
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct mevent_client_cmd gMEventClientScript_UnableToRecv[] = { // can't accept card or news
|
|
||||||
CLI_SENDALL,
|
|
||||||
CLI_RETURN(0x0a)
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct mevent_client_cmd gMEventClientScript_CommError[] = { // comm error
|
|
||||||
CLI_SENDALL,
|
|
||||||
CLI_RETURN(0x0b)
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct mevent_client_cmd gMEventClientScript_NothingSentOver[] = { // nothing sent
|
|
||||||
CLI_SENDALL,
|
|
||||||
CLI_RETURN(0x00)
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct mevent_client_cmd gMEventClientScript_ReceiveCardAndReturnSuccess[] = { // card success
|
|
||||||
CLI_RECEIVE(0x16),
|
|
||||||
CLI_RECVSAV,
|
|
||||||
CLI_RECEIVE(0x19),
|
|
||||||
CLI_RECVRAM,
|
|
||||||
CLI_SENDALL,
|
|
||||||
CLI_RETURN(0x02)
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct mevent_client_cmd gMEventClientScript_ReceiveNewsAndValidate[] = {
|
|
||||||
CLI_RECEIVE(0x17),
|
|
||||||
CLI_VLDNEWS,
|
|
||||||
CLI_WAITSND,
|
|
||||||
CLI_RECEIVE(0x10),
|
|
||||||
CLI_JUMPBUF
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct mevent_client_cmd gMEventClientScript_AlreadyHadNews[] = { // already had news
|
|
||||||
CLI_SENDALL,
|
|
||||||
CLI_RETURN(0x07)
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct mevent_client_cmd gMEventClientScript_RecvNewsSuccess[] = { // news success
|
|
||||||
CLI_SENDALL,
|
|
||||||
CLI_RETURN(0x03)
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct mevent_client_cmd gMEventClientScript_AskWouldLikeToTossCard[] = {
|
|
||||||
CLI_REQWORD,
|
|
||||||
CLI_SNDWORD,
|
|
||||||
CLI_WAITSND,
|
|
||||||
CLI_RECEIVE(0x10),
|
|
||||||
CLI_JUMPBUF
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct mevent_client_cmd gMEventClientScript_OtherTrainerCanceled[] = { // comm canceled
|
|
||||||
CLI_SENDALL,
|
|
||||||
CLI_RETURN(0x09)
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct mevent_client_cmd gMEventClientScript_AlreadyHadCard[] = { // already had card
|
|
||||||
CLI_SENDALL,
|
|
||||||
CLI_RETURN(0x05)
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct mevent_client_cmd gMEventClientScript_SuccessFromBuffer[] = { // success from buffer
|
|
||||||
CLI_RECEIVE(0x15),
|
|
||||||
CLI_RECVBUF,
|
|
||||||
CLI_SENDALL,
|
|
||||||
CLI_RETURN(0x0d)
|
|
||||||
};
|
|
||||||
|
|
||||||
/* SERVER SCRIPTS */
|
|
||||||
|
|
||||||
const struct mevent_server_cmd gMEventSrvScript_UnableToSend[] = {
|
|
||||||
SRV_SEND(0x10, gMEventClientScript_UnableToRecv),
|
|
||||||
SRV_WAITSND,
|
|
||||||
SRV_RECV(0x14),
|
|
||||||
SRV_RETURN(0x0a)
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct mevent_server_cmd gUnknown_8468950[] = {
|
|
||||||
SRV_SEND(0x10, gMEventClientScript_CommError),
|
|
||||||
SRV_WAITSND,
|
|
||||||
SRV_RECV(0x14),
|
|
||||||
SRV_RETURN(0x0b)
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct mevent_server_cmd gUnknown_8468980[] = {
|
|
||||||
SRV_SEND(0x10, gMEventClientScript_OtherTrainerCanceled),
|
|
||||||
SRV_WAITSND,
|
|
||||||
SRV_RECV(0x14),
|
|
||||||
SRV_RETURN(0x09)
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct mevent_server_cmd gMEventSrvScript_OtherTrnHasNews[] = {
|
|
||||||
SRV_SEND(0x10, gMEventClientScript_AlreadyHadNews),
|
|
||||||
SRV_WAITSND,
|
|
||||||
SRV_RECV(0x14),
|
|
||||||
SRV_RETURN(0x07)
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct mevent_server_cmd gMEventSrvScript_SentNewsSuccess[] = {
|
|
||||||
SRV_SEND(0x28, gMEventClientScript_ReceiveNewsAndValidate),
|
|
||||||
SRV_WAITSND,
|
|
||||||
SRV_SEND_NEWS,
|
|
||||||
SRV_WAITSND,
|
|
||||||
SRV_RECV(0x13),
|
|
||||||
SRV_READWORD,
|
|
||||||
SRV_BRANCHIF(0x01, gMEventSrvScript_OtherTrnHasNews),
|
|
||||||
SRV_SEND(0x10, gMEventClientScript_RecvNewsSuccess),
|
|
||||||
SRV_WAITSND,
|
|
||||||
SRV_RECV(0x14),
|
|
||||||
SRV_RETURN(0x03)
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct mevent_server_cmd gMEventSrvScript_SendCardSuccess[] = {
|
|
||||||
SRV_SEND(0x30, gMEventClientScript_ReceiveCardAndReturnSuccess),
|
|
||||||
SRV_WAITSND,
|
|
||||||
SRV_SEND_CARD,
|
|
||||||
SRV_WAITSND,
|
|
||||||
SRV_BUFFER_SEND,
|
|
||||||
SRV_WAITSND,
|
|
||||||
SRV_RECV(0x14),
|
|
||||||
SRV_RETURN(0x02)
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct mevent_server_cmd gMEventSrvScript_AskClientToOverwriteCard[] = {
|
|
||||||
SRV_SEND(0x28, gMEventClientScript_AskWouldLikeToTossCard),
|
|
||||||
SRV_WAITSND,
|
|
||||||
SRV_RECV(0x13),
|
|
||||||
SRV_READWORD,
|
|
||||||
SRV_BRANCHIF(0x00, gMEventSrvScript_SendCardSuccess),
|
|
||||||
SRV_BRANCH(gServerScript_ClientCanceledCard)
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct mevent_server_cmd gMEventSrvScript_OtherTrnHasCard[] = {
|
|
||||||
SRV_SEND(0x10, gMEventClientScript_AlreadyHadCard),
|
|
||||||
SRV_WAITSND,
|
|
||||||
SRV_RECV(0x14),
|
|
||||||
SRV_RETURN(0x05)
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct mevent_server_cmd gUnknown_8468B3C[] = {
|
|
||||||
SRV_SEND(0x10, gMEventClientScript_NothingSentOver),
|
|
||||||
SRV_WAITSND,
|
|
||||||
SRV_RECV(0x14),
|
|
||||||
SRV_RETURN(0x00)
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct mevent_server_cmd gMEventSrvScript_SendNews[] = {
|
|
||||||
SRV_BUFFER_NEWS,
|
|
||||||
SRV_SEND(0x20, gMEventClientScript_Send1442CC),
|
|
||||||
SRV_WAITSND,
|
|
||||||
SRV_RECV(0x11),
|
|
||||||
SRV_READ_1442CC,
|
|
||||||
SRV_VALID_1442CC,
|
|
||||||
SRV_BRANCHIF(0x00, gMEventSrvScript_UnableToSend),
|
|
||||||
SRV_BRANCH(gMEventSrvScript_SentNewsSuccess)
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct mevent_server_cmd gMEventSrvScript_SendCard[] = {
|
|
||||||
SRV_BUFFER_CARD,
|
|
||||||
SRV_RAM_SCRIPT_IF_VALID,
|
|
||||||
SRV_SEND(0x20, gMEventClientScript_Send1442CC),
|
|
||||||
SRV_WAITSND,
|
|
||||||
SRV_RECV(0x11),
|
|
||||||
SRV_READ_1442CC,
|
|
||||||
SRV_VALID_1442CC,
|
|
||||||
SRV_BRANCHIF(0x00, gMEventSrvScript_UnableToSend),
|
|
||||||
SRV_CHECK_1442CC_14,
|
|
||||||
SRV_BRANCHIF(0x02, gMEventSrvScript_AskClientToOverwriteCard),
|
|
||||||
SRV_BRANCHIF(0x00, gMEventSrvScript_SendCardSuccess),
|
|
||||||
SRV_BRANCH(gMEventSrvScript_OtherTrnHasCard)
|
|
||||||
};
|
|
||||||
@@ -1,279 +0,0 @@
|
|||||||
#include "global.h"
|
|
||||||
#include "gflib.h"
|
|
||||||
#include "script.h"
|
|
||||||
#include "mevent.h"
|
|
||||||
#include "mevent_server.h"
|
|
||||||
|
|
||||||
EWRAM_DATA struct mevent_srv_common * s_mevent_srv_common_ptr = NULL;
|
|
||||||
|
|
||||||
static void mevent_srv_init_common(struct mevent_srv_common *, const void *, u32, u32);
|
|
||||||
static void mevent_srv_free_resources(struct mevent_srv_common *);
|
|
||||||
static u32 mevent_srv_exec_common(struct mevent_srv_common *);
|
|
||||||
|
|
||||||
extern const struct mevent_server_cmd gMEventSrvScript_SendNews[];
|
|
||||||
extern const struct mevent_server_cmd gMEventSrvScript_SendCard[];
|
|
||||||
|
|
||||||
void mevent_srv_init_wnews(void)
|
|
||||||
{
|
|
||||||
s_mevent_srv_common_ptr = AllocZeroed(sizeof(struct mevent_srv_common));
|
|
||||||
mevent_srv_init_common(s_mevent_srv_common_ptr, gMEventSrvScript_SendNews, 0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mevent_srv_new_wcard(void)
|
|
||||||
{
|
|
||||||
s_mevent_srv_common_ptr = AllocZeroed(sizeof(struct mevent_srv_common));
|
|
||||||
mevent_srv_init_common(s_mevent_srv_common_ptr, gMEventSrvScript_SendCard, 0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 mevent_srv_common_do_exec(u16 * a0)
|
|
||||||
{
|
|
||||||
u32 result;
|
|
||||||
if (s_mevent_srv_common_ptr == NULL)
|
|
||||||
return 3;
|
|
||||||
result = mevent_srv_exec_common(s_mevent_srv_common_ptr);
|
|
||||||
if (result == 3)
|
|
||||||
{
|
|
||||||
*a0 = s_mevent_srv_common_ptr->param;
|
|
||||||
mevent_srv_free_resources(s_mevent_srv_common_ptr);
|
|
||||||
Free(s_mevent_srv_common_ptr);
|
|
||||||
s_mevent_srv_common_ptr = NULL;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mevent_srv_init_common(struct mevent_srv_common * svr, const void *cmdBuffer, u32 sendPlayerNo, u32 recvPlayerNo)
|
|
||||||
{
|
|
||||||
svr->unk_00 = 0;
|
|
||||||
svr->mainseqno = 0;
|
|
||||||
svr->card = AllocZeroed(sizeof(struct WonderCard));
|
|
||||||
svr->news = AllocZeroed(sizeof(struct WonderNews));
|
|
||||||
svr->recvBuffer = AllocZeroed(ME_SEND_BUF_SIZE);
|
|
||||||
svr->mevent_unk1442cc = AllocZeroed(sizeof(struct MEventClientHeaderStruct));
|
|
||||||
svr->cmdBuffer = cmdBuffer;
|
|
||||||
svr->cmdidx = 0;
|
|
||||||
mevent_srv_sub_init(&svr->manager, sendPlayerNo, recvPlayerNo);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mevent_srv_free_resources(struct mevent_srv_common * svr)
|
|
||||||
{
|
|
||||||
Free(svr->card);
|
|
||||||
Free(svr->news);
|
|
||||||
Free(svr->recvBuffer);
|
|
||||||
Free(svr->mevent_unk1442cc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mevent_srv_common_init_send(struct mevent_srv_common * svr, u32 ident, const void *src, u32 size)
|
|
||||||
{
|
|
||||||
AGB_ASSERT_EX(size <= ME_SEND_BUF_SIZE, ABSPATH("mevent_server.c"), 257);
|
|
||||||
mevent_srv_sub_init_send(&svr->manager, ident, src, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *mevent_first_if_not_null_else_second(void *a0, void *a1)
|
|
||||||
{
|
|
||||||
if (a0 != NULL)
|
|
||||||
return a0;
|
|
||||||
else
|
|
||||||
return a1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 mevent_compare_pointers(void *a0, void *a1)
|
|
||||||
{
|
|
||||||
if (a1 < a0)
|
|
||||||
return 0;
|
|
||||||
else if (a1 == a0)
|
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 common_mainseq_0(struct mevent_srv_common * svr)
|
|
||||||
{
|
|
||||||
// start
|
|
||||||
svr->mainseqno = 4;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 common_mainseq_1(struct mevent_srv_common * svr)
|
|
||||||
{
|
|
||||||
// done
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 common_mainseq_2(struct mevent_srv_common * svr)
|
|
||||||
{
|
|
||||||
// do recv
|
|
||||||
if (mevent_srv_sub_recv(&svr->manager))
|
|
||||||
svr->mainseqno = 4;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 common_mainseq_3(struct mevent_srv_common * svr)
|
|
||||||
{
|
|
||||||
// do send
|
|
||||||
if (mevent_srv_sub_send(&svr->manager))
|
|
||||||
svr->mainseqno = 4;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 common_mainseq_4(struct mevent_srv_common * svr)
|
|
||||||
{
|
|
||||||
// process command
|
|
||||||
const struct mevent_server_cmd * cmd = &svr->cmdBuffer[svr->cmdidx];
|
|
||||||
void *ptr;
|
|
||||||
svr->cmdidx++;
|
|
||||||
|
|
||||||
switch (cmd->instr)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 354);
|
|
||||||
svr->mainseqno = 1;
|
|
||||||
svr->param = cmd->flag;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
svr->mainseqno = 3;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 364);
|
|
||||||
mevent_srv_sub_init_recv(&svr->manager, cmd->flag, svr->recvBuffer);
|
|
||||||
svr->mainseqno = 2;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 370);
|
|
||||||
svr->cmdidx = 0;
|
|
||||||
svr->cmdBuffer = cmd->parameter;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 376);
|
|
||||||
AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 377);
|
|
||||||
memcpy(svr->mevent_unk1442cc, svr->recvBuffer, sizeof(struct MEventClientHeaderStruct));
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 382);
|
|
||||||
AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 383);
|
|
||||||
svr->param = ValidateMEventClientHeader(svr->mevent_unk1442cc);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
if (svr->param == cmd->flag)
|
|
||||||
{
|
|
||||||
svr->cmdidx = 0;
|
|
||||||
svr->cmdBuffer = cmd->parameter;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 396);
|
|
||||||
ptr = mevent_first_if_not_null_else_second(cmd->parameter, svr->card);
|
|
||||||
svr->param = sub_8144418(ptr, svr->mevent_unk1442cc, ptr);
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 402);
|
|
||||||
AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 403);
|
|
||||||
svr->param = *(u32 *)svr->recvBuffer;
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 408);
|
|
||||||
ptr = mevent_first_if_not_null_else_second(cmd->parameter, &svr->sendWord);
|
|
||||||
svr->param = MEvent_CanPlayerReceiveDistributionMon(ptr, svr->mevent_unk1442cc, ptr);
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
AGB_ASSERT_EX(cmd->parameter == NULL, ABSPATH("mevent_server.c"), 415);
|
|
||||||
svr->param = sub_81444B0(svr->mevent_unk1442cc, cmd->flag);
|
|
||||||
break;
|
|
||||||
case 11:
|
|
||||||
AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 420);
|
|
||||||
svr->param = sub_8144474(svr->mevent_unk1442cc, cmd->parameter);
|
|
||||||
break;
|
|
||||||
case 12:
|
|
||||||
AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 426);
|
|
||||||
svr->param = mevent_compare_pointers(cmd->parameter, *(void **)svr->recvBuffer);
|
|
||||||
break;
|
|
||||||
case 14:
|
|
||||||
AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 432);
|
|
||||||
mevent_srv_common_init_send(svr, 0x17, mevent_first_if_not_null_else_second(cmd->parameter, svr->news), sizeof(struct WonderNews));
|
|
||||||
break;
|
|
||||||
case 13:
|
|
||||||
AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 438);
|
|
||||||
mevent_srv_common_init_send(svr, 0x16, mevent_first_if_not_null_else_second(cmd->parameter, svr->card), sizeof(struct WonderCard));
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 444);
|
|
||||||
mevent_srv_common_init_send(svr, 0x18, mevent_first_if_not_null_else_second(cmd->parameter, &svr->sendWord), 4);
|
|
||||||
break;
|
|
||||||
case 15:
|
|
||||||
if (cmd->parameter == NULL)
|
|
||||||
mevent_srv_common_init_send(svr, 0x19, svr->sendBuffer1, svr->sendBuffer1Size);
|
|
||||||
else
|
|
||||||
mevent_srv_common_init_send(svr, 0x19, cmd->parameter, cmd->flag);
|
|
||||||
break;
|
|
||||||
case 18:
|
|
||||||
if (cmd->parameter == NULL)
|
|
||||||
mevent_srv_common_init_send(svr, 0x10, svr->sendBuffer2, svr->sendBuffer2Size);
|
|
||||||
else
|
|
||||||
mevent_srv_common_init_send(svr, 0x10, cmd->parameter, cmd->flag);
|
|
||||||
break;
|
|
||||||
case 19:
|
|
||||||
AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 466);
|
|
||||||
mevent_srv_common_init_send(svr, 0x1a, cmd->parameter, 188);
|
|
||||||
break;
|
|
||||||
case 20:
|
|
||||||
mevent_srv_common_init_send(svr, 0x15, cmd->parameter, cmd->flag);
|
|
||||||
break;
|
|
||||||
case 17:
|
|
||||||
mevent_srv_common_init_send(svr, 0x1c, cmd->parameter, cmd->flag);
|
|
||||||
break;
|
|
||||||
case 22:
|
|
||||||
AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 481);
|
|
||||||
memcpy(svr->card, cmd->parameter, 332);
|
|
||||||
break;
|
|
||||||
case 23:
|
|
||||||
AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 486);
|
|
||||||
memcpy(svr->news, cmd->parameter, 444);
|
|
||||||
break;
|
|
||||||
case 21:
|
|
||||||
AGB_ASSERT_EX(cmd->flag == FALSE, ABSPATH("mevent_server.c"), 491);
|
|
||||||
svr->sendWord = *(u32 *)cmd->parameter;
|
|
||||||
break;
|
|
||||||
case 24:
|
|
||||||
svr->sendBuffer1 = cmd->parameter;
|
|
||||||
svr->sendBuffer1Size = cmd->flag;
|
|
||||||
break;
|
|
||||||
case 25:
|
|
||||||
svr->sendBuffer2 = cmd->parameter;
|
|
||||||
svr->sendBuffer2Size = cmd->flag;
|
|
||||||
break;
|
|
||||||
case 26:
|
|
||||||
AGB_ASSERT_EX(cmd->flag == FALSE && cmd->parameter == NULL, ABSPATH("mevent_server.c"), 506);
|
|
||||||
memcpy(svr->card, GetSavedWonderCard(), 332);
|
|
||||||
MEvent_WonderCardResetUnk08_6(svr->card);
|
|
||||||
break;
|
|
||||||
case 27:
|
|
||||||
AGB_ASSERT_EX(cmd->flag == FALSE && cmd->parameter == NULL, ABSPATH("mevent_server.c"), 512);
|
|
||||||
memcpy(svr->news, GetSavedWonderNews(), 444);
|
|
||||||
break;
|
|
||||||
case 28:
|
|
||||||
AGB_ASSERT_EX(cmd->flag == FALSE && cmd->parameter == NULL, ABSPATH("mevent_server.c"), 517);
|
|
||||||
svr->sendBuffer1 = GetSavedRamScriptIfValid();
|
|
||||||
break;
|
|
||||||
case 29:
|
|
||||||
mevent_srv_common_init_send(svr, 0x1b, cmd->parameter, cmd->flag);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 (*const func_tbl[])(struct mevent_srv_common *) = {
|
|
||||||
common_mainseq_0,
|
|
||||||
common_mainseq_1,
|
|
||||||
common_mainseq_2,
|
|
||||||
common_mainseq_3,
|
|
||||||
common_mainseq_4
|
|
||||||
};
|
|
||||||
|
|
||||||
static u32 mevent_srv_exec_common(struct mevent_srv_common * svr)
|
|
||||||
{
|
|
||||||
u32 response;
|
|
||||||
AGB_ASSERT_EX(svr->mainseqno < NELEMS(func_tbl), ABSPATH("mevent_server.c"), 546);
|
|
||||||
response = func_tbl[svr->mainseqno](svr);
|
|
||||||
AGB_ASSERT_EX(svr->mainseqno < NELEMS(func_tbl), ABSPATH("mevent_server.c"), 548);
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
@@ -1,204 +0,0 @@
|
|||||||
#include "global.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "link.h"
|
|
||||||
#include "link_rfu.h"
|
|
||||||
#include "mevent_server.h"
|
|
||||||
|
|
||||||
static u32 mevent_receive_func(struct mevent_srv_sub *);
|
|
||||||
static u32 mevent_send_func(struct mevent_srv_sub *);
|
|
||||||
|
|
||||||
u32 mevent_srv_sub_recv(struct mevent_srv_sub * svr)
|
|
||||||
{
|
|
||||||
return svr->recvFunc(svr);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 mevent_srv_sub_send(struct mevent_srv_sub * svr)
|
|
||||||
{
|
|
||||||
return svr->sendFunc(svr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mevent_srv_sub_init(struct mevent_srv_sub * svr, u32 sendPlayerNo, u32 recvPlayerNo)
|
|
||||||
{
|
|
||||||
svr->sendPlayerNo = sendPlayerNo;
|
|
||||||
svr->recvPlayerNo = recvPlayerNo;
|
|
||||||
svr->seqno = 0;
|
|
||||||
svr->sendCRC = 0;
|
|
||||||
svr->sendSize = 0;
|
|
||||||
svr->sendCounter = 0;
|
|
||||||
svr->recvCRC = 0;
|
|
||||||
svr->recvSize = 0;
|
|
||||||
svr->recvCounter = 0;
|
|
||||||
svr->sendBfr = NULL;
|
|
||||||
svr->recvBfr = NULL;
|
|
||||||
svr->sendFunc = mevent_send_func;
|
|
||||||
svr->recvFunc = mevent_receive_func;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mevent_srv_sub_init_send(struct mevent_srv_sub * svr, u32 ident, const void *src, u32 size)
|
|
||||||
{
|
|
||||||
svr->seqno = 0;
|
|
||||||
svr->sendIdent = ident;
|
|
||||||
svr->sendCounter = 0;
|
|
||||||
svr->sendCRC = 0;
|
|
||||||
if (size != 0)
|
|
||||||
svr->sendSize = size;
|
|
||||||
else
|
|
||||||
svr->sendSize = ME_SEND_BUF_SIZE;
|
|
||||||
svr->sendBfr = src;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mevent_srv_sub_init_recv(struct mevent_srv_sub * svr, u32 ident, void *dest)
|
|
||||||
{
|
|
||||||
svr->seqno = 0;
|
|
||||||
svr->recvIdent = ident;
|
|
||||||
svr->recvCounter = 0;
|
|
||||||
svr->recvCRC = 0;
|
|
||||||
svr->recvSize = 0;
|
|
||||||
svr->recvBfr = dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mevent_recv_block(u32 recv_idx, void *dest, size_t size)
|
|
||||||
{
|
|
||||||
memcpy(dest, gBlockRecvBuffer[recv_idx], size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool32 mevent_has_received(u32 recv_idx)
|
|
||||||
{
|
|
||||||
if ((GetBlockReceivedStatus() >> recv_idx) & 1)
|
|
||||||
return TRUE;
|
|
||||||
else
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mevent_reset_recv(u32 recv_idx)
|
|
||||||
{
|
|
||||||
ResetBlockReceivedFlag(recv_idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool32 mevent_receive_func(struct mevent_srv_sub * svr)
|
|
||||||
{
|
|
||||||
struct send_recv_header header;
|
|
||||||
|
|
||||||
switch (svr->seqno)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
if (mevent_has_received(svr->recvPlayerNo))
|
|
||||||
{
|
|
||||||
mevent_recv_block(svr->recvPlayerNo, &header, sizeof(header));
|
|
||||||
svr->recvSize = header.size;
|
|
||||||
svr->recvCRC = header.crc;
|
|
||||||
if (svr->recvSize > ME_SEND_BUF_SIZE)
|
|
||||||
{
|
|
||||||
LinkRfu_FatalError();
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
else if (svr->recvIdent != header.ident)
|
|
||||||
{
|
|
||||||
LinkRfu_FatalError();
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
svr->recvCounter = 0;
|
|
||||||
mevent_reset_recv(svr->recvPlayerNo);
|
|
||||||
++svr->seqno;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if (mevent_has_received(svr->recvPlayerNo))
|
|
||||||
{
|
|
||||||
size_t blocksiz = svr->recvCounter * 252;
|
|
||||||
if (svr->recvSize - blocksiz <= 252)
|
|
||||||
{
|
|
||||||
mevent_recv_block(svr->recvPlayerNo, svr->recvBfr + blocksiz, svr->recvSize - blocksiz);
|
|
||||||
++svr->recvCounter;
|
|
||||||
++svr->seqno;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mevent_recv_block(svr->recvPlayerNo, svr->recvBfr + blocksiz, 252);
|
|
||||||
++svr->recvCounter;
|
|
||||||
}
|
|
||||||
mevent_reset_recv(svr->recvPlayerNo);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (CalcCRC16WithTable(svr->recvBfr, svr->recvSize) != svr->recvCRC)
|
|
||||||
{
|
|
||||||
LinkRfu_FatalError();
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
svr->seqno = 0;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool32 mevent_send_func(struct mevent_srv_sub * svr)
|
|
||||||
{
|
|
||||||
struct send_recv_header header;
|
|
||||||
|
|
||||||
switch (svr->seqno)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
if (IsLinkTaskFinished())
|
|
||||||
{
|
|
||||||
header.ident = svr->sendIdent;
|
|
||||||
header.size = svr->sendSize;
|
|
||||||
header.crc = CalcCRC16WithTable(svr->sendBfr, svr->sendSize);
|
|
||||||
svr->sendCRC = header.crc;
|
|
||||||
svr->sendCounter = 0;
|
|
||||||
SendBlock(0, &header, sizeof(header));
|
|
||||||
++svr->seqno;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if (IsLinkTaskFinished())
|
|
||||||
{
|
|
||||||
if (mevent_has_received(svr->sendPlayerNo))
|
|
||||||
{
|
|
||||||
size_t blocksiz;
|
|
||||||
mevent_reset_recv(svr->sendPlayerNo);
|
|
||||||
blocksiz = 252 * svr->sendCounter;
|
|
||||||
if (svr->sendSize - blocksiz <= 252)
|
|
||||||
{
|
|
||||||
SendBlock(0, svr->sendBfr + blocksiz, svr->sendSize - blocksiz);
|
|
||||||
++svr->sendCounter;
|
|
||||||
++svr->seqno;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SendBlock(0, svr->sendBfr + blocksiz, 252);
|
|
||||||
++svr->sendCounter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (IsLinkTaskFinished())
|
|
||||||
{
|
|
||||||
if (CalcCRC16WithTable(svr->sendBfr, svr->sendSize) != svr->sendCRC)
|
|
||||||
LinkRfu_FatalError();
|
|
||||||
else
|
|
||||||
++svr->seqno;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
if (mevent_has_received(svr->sendPlayerNo))
|
|
||||||
{
|
|
||||||
mevent_reset_recv(svr->sendPlayerNo);
|
|
||||||
svr->seqno = 0;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,634 @@
|
|||||||
|
#include "global.h"
|
||||||
|
#include "gflib.h"
|
||||||
|
#include "constants/songs.h"
|
||||||
|
#include "easy_chat.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "link.h"
|
||||||
|
#include "link_rfu.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "script.h"
|
||||||
|
#include "event_data.h"
|
||||||
|
#include "battle_tower.h"
|
||||||
|
#include "new_game.h"
|
||||||
|
#include "wonder_news.h"
|
||||||
|
#include "mystery_gift_menu.h"
|
||||||
|
#include "help_system.h"
|
||||||
|
#include "mystery_gift.h"
|
||||||
|
#include "strings.h"
|
||||||
|
|
||||||
|
#define CALC_CRC(data) CalcCRC16WithTable((void *)&(data), sizeof(data))
|
||||||
|
|
||||||
|
static bool32 ValidateWonderNews(const struct WonderNews * src);
|
||||||
|
static void ClearSavedWonderNews(void);
|
||||||
|
static void ClearSavedWonderNewsMetadata(void);
|
||||||
|
static bool32 ValidateWonderCard(const struct WonderCard * src);
|
||||||
|
static void ClearSavedWonderCard(void);
|
||||||
|
static void ClearSavedWonderCardMetadata(void);
|
||||||
|
static void IncrementCardStatForNewTrainer(u32 eventId, u32 trainerId, u32 *idsList, s32 count);
|
||||||
|
static void ClearSavedTrainerIds(void);
|
||||||
|
|
||||||
|
static const u16 sReceivedGiftFlags[] = {
|
||||||
|
FLAG_RECEIVED_AURORA_TICKET,
|
||||||
|
FLAG_RECEIVED_MYSTIC_TICKET,
|
||||||
|
FLAG_RECEIVED_OLD_SEA_MAP, // Not used until Emerald
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
static EWRAM_DATA bool32 sStatsEnabled = FALSE;
|
||||||
|
|
||||||
|
void ClearMysteryGift(void)
|
||||||
|
{
|
||||||
|
CpuFill32(0, &gSaveBlock1Ptr->mysteryGift, sizeof(gSaveBlock1Ptr->mysteryGift));
|
||||||
|
ClearSavedWonderNewsMetadata();
|
||||||
|
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));
|
||||||
|
WonderNews_Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
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->battleTower.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 (!ValidateRamScript())
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 s32 GetNumStampsInMetadata(const struct WonderCardMetadata * data, s32 size)
|
||||||
|
{
|
||||||
|
s32 numStamps = 0;
|
||||||
|
s32 i;
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
if (data->stampData[STAMP_ID][i] && data->stampData[STAMP_SPECIES][i])
|
||||||
|
numStamps++;
|
||||||
|
}
|
||||||
|
return numStamps;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32 IsStampInMetadata(const struct WonderCardMetadata * metadata, const u16 * stamp, s32 maxStamps)
|
||||||
|
{
|
||||||
|
s32 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 s32 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;
|
||||||
|
s32 maxStamps = card->maxStamps;
|
||||||
|
s32 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
|
||||||
|
|
||||||
|
#if defined(FIRERED)
|
||||||
|
#define VERSION_CODE 1
|
||||||
|
#elif defined(LEAFGREEN)
|
||||||
|
#define VERSION_CODE 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void MysteryGift_LoadLinkGameData(struct MysteryGiftLinkGameData * data)
|
||||||
|
{
|
||||||
|
s32 i;
|
||||||
|
CpuFill32(0, data, sizeof(*data));
|
||||||
|
// Magic
|
||||||
|
data->unk_00 = GAME_DATA_VALID_VAR;
|
||||||
|
data->unk_04 = 1;
|
||||||
|
data->unk_08 = 1;
|
||||||
|
data->unk_0C = 1;
|
||||||
|
data->unk_10 = VERSION_CODE;
|
||||||
|
|
||||||
|
// Check whether a card already exists
|
||||||
|
if (ValidateSavedWonderCard())
|
||||||
|
{
|
||||||
|
// Populate fields
|
||||||
|
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->gameCode, RomHeaderGameCode, GAME_CODE_LENGTH);
|
||||||
|
data->version = RomHeaderSoftwareVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool32 MysteryGift_ValidateLinkGameData(const struct MysteryGiftLinkGameData * data)
|
||||||
|
{
|
||||||
|
if (data->unk_00 != GAME_DATA_VALID_VAR)
|
||||||
|
return FALSE;
|
||||||
|
if (!(data->unk_04 & 1))
|
||||||
|
return FALSE;
|
||||||
|
if (!(data->unk_08 & 1))
|
||||||
|
return FALSE;
|
||||||
|
if (!(data->unk_0C & 1))
|
||||||
|
return FALSE;
|
||||||
|
if (!(data->unk_10 & 0x0F))
|
||||||
|
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 0;
|
||||||
|
|
||||||
|
// Has this Wonder Card already?
|
||||||
|
if (*flagId == data->flagId)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// Player has a different Wonder Card
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 MysteryGift_CheckStamps(const u16 * stamp, const struct MysteryGiftLinkGameData * data, const void *unused)
|
||||||
|
{
|
||||||
|
s32 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)
|
||||||
|
{
|
||||||
|
s32 i;
|
||||||
|
for (i = 0; i < NUM_QUESTIONNAIRE_WORDS; i++)
|
||||||
|
{
|
||||||
|
if (data->questionnaireWords[i] != words[i])
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static s32 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_EX(0, ABSPATH("mevent.c"), 825);
|
||||||
|
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:
|
||||||
|
case CARD_STAT_MAX_STAMPS:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (stat == NULL)
|
||||||
|
{
|
||||||
|
AGB_ASSERT_EX(0, ABSPATH("mevent.c"), 868);
|
||||||
|
}
|
||||||
|
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_EX(0, ABSPATH("mevent.c"), 913);
|
||||||
|
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_EX(0, ABSPATH("mevent.c"), 988);
|
||||||
|
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, s32 size)
|
||||||
|
{
|
||||||
|
s32 i;
|
||||||
|
s32 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, s32 size)
|
||||||
|
{
|
||||||
|
if (RecordTrainerId(trainerId, trainerIds, size))
|
||||||
|
IncrementCardStat(stat);
|
||||||
|
}
|
||||||
@@ -0,0 +1,300 @@
|
|||||||
|
#include "global.h"
|
||||||
|
#include "gflib.h"
|
||||||
|
#include "decompress.h"
|
||||||
|
#include "overworld.h"
|
||||||
|
#include "script.h"
|
||||||
|
#include "battle_tower.h"
|
||||||
|
#include "mystery_event_script.h"
|
||||||
|
#include "mystery_gift.h"
|
||||||
|
#include "mystery_gift_client.h"
|
||||||
|
#include "mystery_gift_server.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
FUNC_INIT,
|
||||||
|
FUNC_DONE,
|
||||||
|
FUNC_RECV,
|
||||||
|
FUNC_SEND,
|
||||||
|
FUNC_RUN,
|
||||||
|
FUNC_WAIT,
|
||||||
|
FUNC_RUN_MEVENT,
|
||||||
|
FUNC_RUN_BUFFER,
|
||||||
|
};
|
||||||
|
|
||||||
|
static EWRAM_DATA struct MysteryGiftClient * sClient = NULL;
|
||||||
|
|
||||||
|
static void MysteryGiftClient_Init(struct MysteryGiftClient *, u32, u32);
|
||||||
|
static u32 MysteryGiftClient_CallFunc(struct MysteryGiftClient *);
|
||||||
|
static void MysteryGiftClient_Free(struct MysteryGiftClient *);
|
||||||
|
|
||||||
|
extern const struct MysteryGiftClientCmd gMysteryGiftClientScript_Init[];
|
||||||
|
|
||||||
|
void MysteryGiftClient_Create(void)
|
||||||
|
{
|
||||||
|
sClient = AllocZeroed(sizeof(*sClient));
|
||||||
|
MysteryGiftClient_Init(sClient, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 MysteryGiftClient_Run(u16 * endVal)
|
||||||
|
{
|
||||||
|
u32 result;
|
||||||
|
if (sClient == NULL)
|
||||||
|
return CLI_RET_END;
|
||||||
|
result = MysteryGiftClient_CallFunc(sClient);
|
||||||
|
if (result == CLI_RET_END)
|
||||||
|
{
|
||||||
|
*endVal = sClient->param;
|
||||||
|
MysteryGiftClient_Free(sClient);
|
||||||
|
FREE_AND_SET_NULL(sClient);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MysteryGiftClient_AdvanceState(void)
|
||||||
|
{
|
||||||
|
sClient->funcState++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *MysteryGiftClient_GetMsg(void)
|
||||||
|
{
|
||||||
|
return sClient->msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MysteryGiftClient_SetParam(u32 val)
|
||||||
|
{
|
||||||
|
sClient->param = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MysteryGiftClient_Init(struct MysteryGiftClient * client, u32 sendPlayerId, u32 recvPlayerId)
|
||||||
|
{
|
||||||
|
client->unused = 0;
|
||||||
|
client->funcId = FUNC_INIT;
|
||||||
|
client->funcState = 0;
|
||||||
|
client->sendBuffer = AllocZeroed(MG_LINK_BUFFER_SIZE);
|
||||||
|
client->recvBuffer = AllocZeroed(MG_LINK_BUFFER_SIZE);
|
||||||
|
client->script = AllocZeroed(MG_LINK_BUFFER_SIZE);
|
||||||
|
client->msg = AllocZeroed(CLIENT_MAX_MSG_SIZE);
|
||||||
|
MysteryGiftLink_Init(&client->link, sendPlayerId, recvPlayerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MysteryGiftClient_Free(struct MysteryGiftClient * client)
|
||||||
|
{
|
||||||
|
Free(client->sendBuffer);
|
||||||
|
Free(client->recvBuffer);
|
||||||
|
Free(client->script);
|
||||||
|
Free(client->msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MysteryGiftClient_CopyRecvScript(struct MysteryGiftClient * client)
|
||||||
|
{
|
||||||
|
memcpy(client->script, client->recvBuffer, MG_LINK_BUFFER_SIZE);
|
||||||
|
client->cmdidx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MysteryGiftClient_InitSendWord(struct MysteryGiftClient * client, u32 ident, u32 word)
|
||||||
|
{
|
||||||
|
CpuFill32(0, client->sendBuffer, MG_LINK_BUFFER_SIZE);
|
||||||
|
*(u32 *)client->sendBuffer = word;
|
||||||
|
MysteryGiftLink_InitSend(&client->link, ident, client->sendBuffer, sizeof(word));
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 Client_Init(struct MysteryGiftClient * client)
|
||||||
|
{
|
||||||
|
memcpy(client->script, gMysteryGiftClientScript_Init, MG_LINK_BUFFER_SIZE);
|
||||||
|
client->cmdidx = 0;
|
||||||
|
client->funcId = FUNC_RUN;
|
||||||
|
client->funcState = 0;
|
||||||
|
return CLI_RET_INIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 Client_Done(struct MysteryGiftClient * client)
|
||||||
|
{
|
||||||
|
return CLI_RET_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 Client_Recv(struct MysteryGiftClient * client)
|
||||||
|
{
|
||||||
|
if (MysteryGiftLink_Recv(&client->link))
|
||||||
|
{
|
||||||
|
client->funcId = FUNC_RUN;
|
||||||
|
client->funcState = 0;
|
||||||
|
}
|
||||||
|
return CLI_RET_ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 Client_Send(struct MysteryGiftClient * client)
|
||||||
|
{
|
||||||
|
if (MysteryGiftLink_Send(&client->link))
|
||||||
|
{
|
||||||
|
client->funcId = FUNC_RUN;
|
||||||
|
client->funcState = 0;
|
||||||
|
}
|
||||||
|
return CLI_RET_ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 Client_Run(struct MysteryGiftClient * client)
|
||||||
|
{
|
||||||
|
// process command
|
||||||
|
struct MysteryGiftClientCmd * cmd = &client->script[client->cmdidx];
|
||||||
|
client->cmdidx++;
|
||||||
|
switch (cmd->instr)
|
||||||
|
{
|
||||||
|
case CLI_NONE:
|
||||||
|
break;
|
||||||
|
case CLI_RETURN:
|
||||||
|
client->param = cmd->parameter; // Set for endVal in MysteryGiftClient_Run
|
||||||
|
client->funcId = FUNC_DONE;
|
||||||
|
client->funcState = 0;
|
||||||
|
break;
|
||||||
|
case CLI_RECV:
|
||||||
|
MysteryGiftLink_InitRecv(&client->link, cmd->parameter, client->recvBuffer);
|
||||||
|
client->funcId = FUNC_RECV;
|
||||||
|
client->funcState = 0;
|
||||||
|
break;
|
||||||
|
case CLI_SEND_LOADED:
|
||||||
|
// Send without a MysteryGiftLink_InitSend
|
||||||
|
// Sends whatever has been loaded already
|
||||||
|
client->funcId = FUNC_SEND;
|
||||||
|
client->funcState = 0;
|
||||||
|
break;
|
||||||
|
case CLI_SEND_READY_END:
|
||||||
|
MysteryGiftLink_InitSend(&client->link, MG_LINKID_READY_END, client->sendBuffer, 0);
|
||||||
|
client->funcId = FUNC_SEND;
|
||||||
|
client->funcState = 0;
|
||||||
|
break;
|
||||||
|
case CLI_SEND_STAT:
|
||||||
|
MysteryGiftClient_InitSendWord(client, MG_LINKID_GAME_STAT, GetGameStat(cmd->parameter));
|
||||||
|
client->funcId = FUNC_SEND;
|
||||||
|
client->funcState = 0;
|
||||||
|
break;
|
||||||
|
case CLI_COPY_RECV_IF_N:
|
||||||
|
if (client->param == FALSE)
|
||||||
|
MysteryGiftClient_CopyRecvScript(client);
|
||||||
|
break;
|
||||||
|
case CLI_COPY_RECV_IF:
|
||||||
|
if (client->param == TRUE)
|
||||||
|
MysteryGiftClient_CopyRecvScript(client);
|
||||||
|
break;
|
||||||
|
case CLI_COPY_RECV:
|
||||||
|
MysteryGiftClient_CopyRecvScript(client);
|
||||||
|
break;
|
||||||
|
case CLI_YES_NO:
|
||||||
|
memcpy(client->msg, client->recvBuffer, CLIENT_MAX_MSG_SIZE);
|
||||||
|
client->funcId = FUNC_WAIT;
|
||||||
|
client->funcState = 0;
|
||||||
|
return CLI_RET_YES_NO;
|
||||||
|
case CLI_PRINT_MSG:
|
||||||
|
memcpy(client->msg, client->recvBuffer, CLIENT_MAX_MSG_SIZE);
|
||||||
|
client->funcId = FUNC_WAIT;
|
||||||
|
client->funcState = 0;
|
||||||
|
return CLI_RET_PRINT_MSG;
|
||||||
|
case CLI_COPY_MSG:
|
||||||
|
memcpy(client->msg, client->recvBuffer, CLIENT_MAX_MSG_SIZE);
|
||||||
|
client->funcId = FUNC_WAIT;
|
||||||
|
client->funcState = 0;
|
||||||
|
return CLI_RET_COPY_MSG;
|
||||||
|
case CLI_ASK_TOSS:
|
||||||
|
client->funcId = FUNC_WAIT;
|
||||||
|
client->funcState = 0;
|
||||||
|
return CLI_RET_ASK_TOSS;
|
||||||
|
case CLI_LOAD_GAME_DATA:
|
||||||
|
MysteryGift_LoadLinkGameData(client->sendBuffer);
|
||||||
|
MysteryGiftLink_InitSend(&client->link, MG_LINKID_GAME_DATA, client->sendBuffer, sizeof(struct MysteryGiftLinkGameData));
|
||||||
|
break;
|
||||||
|
case CLI_LOAD_TOSS_RESPONSE:
|
||||||
|
// param here is set by MG_STATE_CLIENT_ASK_TOSS or MG_STATE_CLIENT_ASK_TOSS_UNRECEIVED
|
||||||
|
MysteryGiftClient_InitSendWord(client, MG_LINKID_RESPONSE, client->param);
|
||||||
|
break;
|
||||||
|
case CLI_SAVE_CARD:
|
||||||
|
SaveWonderCard(client->recvBuffer);
|
||||||
|
break;
|
||||||
|
case CLI_SAVE_NEWS:
|
||||||
|
if (!IsWonderNewsSameAsSaved(client->recvBuffer))
|
||||||
|
{
|
||||||
|
SaveWonderNews(client->recvBuffer);
|
||||||
|
MysteryGiftClient_InitSendWord(client, MG_LINKID_RESPONSE, FALSE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Wonder News has already been saved (or is invalid).
|
||||||
|
// Prepare a signal to indicate it was not saved.
|
||||||
|
MysteryGiftClient_InitSendWord(client, MG_LINKID_RESPONSE, TRUE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CLI_RUN_MEVENT_SCRIPT:
|
||||||
|
client->funcId = FUNC_RUN_MEVENT;
|
||||||
|
client->funcState = 0;
|
||||||
|
break;
|
||||||
|
case CLI_SAVE_STAMP:
|
||||||
|
MysteryGift_TrySaveStamp(client->recvBuffer);
|
||||||
|
break;
|
||||||
|
case CLI_SAVE_RAM_SCRIPT:
|
||||||
|
InitRamScript_NoObjectEvent(client->recvBuffer, sizeof(struct RamScriptData));
|
||||||
|
break;
|
||||||
|
case CLI_RECV_EREADER_TRAINER:
|
||||||
|
memcpy(&gSaveBlock2Ptr->battleTower.ereaderTrainer, client->recvBuffer, sizeof(gSaveBlock2Ptr->battleTower.ereaderTrainer));
|
||||||
|
ValidateEReaderTrainer();
|
||||||
|
break;
|
||||||
|
case CLI_RUN_BUFFER_SCRIPT:
|
||||||
|
memcpy(gDecompressionBuffer, client->recvBuffer, MG_LINK_BUFFER_SIZE);
|
||||||
|
client->funcId = FUNC_RUN_BUFFER;
|
||||||
|
client->funcState = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CLI_RET_ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 Client_Wait(struct MysteryGiftClient * client)
|
||||||
|
{
|
||||||
|
if (client->funcState)
|
||||||
|
{
|
||||||
|
client->funcId = FUNC_RUN;
|
||||||
|
client->funcState = 0;
|
||||||
|
}
|
||||||
|
return CLI_RET_ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 Client_RunMysteryEventScript(struct MysteryGiftClient * client)
|
||||||
|
{
|
||||||
|
switch (client->funcState)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
MEventScript_InitContext(client->recvBuffer);
|
||||||
|
client->funcState++;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (!MEventScript_Run(&client->param))
|
||||||
|
{
|
||||||
|
client->funcId = FUNC_RUN;
|
||||||
|
client->funcState = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return CLI_RET_ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 Client_RunBufferScript(struct MysteryGiftClient * client)
|
||||||
|
{
|
||||||
|
u32 (*func)(u32 *, struct SaveBlock2 *, struct SaveBlock1 *) = (void *)gDecompressionBuffer;
|
||||||
|
if (func(&client->param, gSaveBlock2Ptr, gSaveBlock1Ptr) == 1)
|
||||||
|
{
|
||||||
|
client->funcId = FUNC_RUN;
|
||||||
|
client->funcState = 0;
|
||||||
|
}
|
||||||
|
return CLI_RET_ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 MysteryGiftClient_CallFunc(struct MysteryGiftClient * client)
|
||||||
|
{
|
||||||
|
u32 (*funcs[])(struct MysteryGiftClient *) = {
|
||||||
|
[FUNC_INIT] = Client_Init,
|
||||||
|
[FUNC_DONE] = Client_Done,
|
||||||
|
[FUNC_RECV] = Client_Recv,
|
||||||
|
[FUNC_SEND] = Client_Send,
|
||||||
|
[FUNC_RUN] = Client_Run,
|
||||||
|
[FUNC_WAIT] = Client_Wait,
|
||||||
|
[FUNC_RUN_MEVENT] = Client_RunMysteryEventScript,
|
||||||
|
[FUNC_RUN_BUFFER] = Client_RunBufferScript
|
||||||
|
};
|
||||||
|
return funcs[client->funcId](client);
|
||||||
|
}
|
||||||
@@ -0,0 +1,215 @@
|
|||||||
|
#include "global.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "link.h"
|
||||||
|
#include "link_rfu.h"
|
||||||
|
#include "mystery_gift_server.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Handles the link connection functions used by the Mystery Gift client/server.
|
||||||
|
Note: MysteryGiftLink is shortened to MGL for internal functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct SendRecvHeader
|
||||||
|
{
|
||||||
|
u16 ident;
|
||||||
|
u16 crc;
|
||||||
|
u16 size;
|
||||||
|
};
|
||||||
|
|
||||||
|
static u32 MGL_Receive(struct MysteryGiftLink *);
|
||||||
|
static u32 MGL_Send(struct MysteryGiftLink *);
|
||||||
|
|
||||||
|
u32 MysteryGiftLink_Recv(struct MysteryGiftLink * link)
|
||||||
|
{
|
||||||
|
return link->recvFunc(link);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 MysteryGiftLink_Send(struct MysteryGiftLink * link)
|
||||||
|
{
|
||||||
|
return link->sendFunc(link);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MysteryGiftLink_Init(struct MysteryGiftLink * link, u32 sendPlayerId, u32 recvPlayerId)
|
||||||
|
{
|
||||||
|
link->sendPlayerId = sendPlayerId;
|
||||||
|
link->recvPlayerId = recvPlayerId;
|
||||||
|
link->state = 0;
|
||||||
|
link->sendCRC = 0;
|
||||||
|
link->sendSize = 0;
|
||||||
|
link->sendCounter = 0;
|
||||||
|
link->recvCRC = 0;
|
||||||
|
link->recvSize = 0;
|
||||||
|
link->recvCounter = 0;
|
||||||
|
link->sendBuffer = NULL;
|
||||||
|
link->recvBuffer = NULL;
|
||||||
|
link->sendFunc = MGL_Send;
|
||||||
|
link->recvFunc = MGL_Receive;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MysteryGiftLink_InitSend(struct MysteryGiftLink * link, u32 ident, const void *src, u32 size)
|
||||||
|
{
|
||||||
|
link->state = 0;
|
||||||
|
link->sendIdent = ident;
|
||||||
|
link->sendCounter = 0;
|
||||||
|
link->sendCRC = 0;
|
||||||
|
if (size != 0)
|
||||||
|
link->sendSize = size;
|
||||||
|
else
|
||||||
|
link->sendSize = MG_LINK_BUFFER_SIZE;
|
||||||
|
link->sendBuffer = src;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MysteryGiftLink_InitRecv(struct MysteryGiftLink * link, u32 ident, void *dest)
|
||||||
|
{
|
||||||
|
link->state = 0;
|
||||||
|
link->recvIdent = ident;
|
||||||
|
link->recvCounter = 0;
|
||||||
|
link->recvCRC = 0;
|
||||||
|
link->recvSize = 0;
|
||||||
|
link->recvBuffer = dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MGL_ReceiveBlock(u32 playerId, void *dest, size_t size)
|
||||||
|
{
|
||||||
|
memcpy(dest, gBlockRecvBuffer[playerId], size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32 MGL_HasReceived(u32 playerId)
|
||||||
|
{
|
||||||
|
if ((GetBlockReceivedStatus() >> playerId) & 1)
|
||||||
|
return TRUE;
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MGL_ResetReceived(u32 playerId)
|
||||||
|
{
|
||||||
|
ResetBlockReceivedFlag(playerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32 MGL_Receive(struct MysteryGiftLink * link)
|
||||||
|
{
|
||||||
|
struct SendRecvHeader header;
|
||||||
|
|
||||||
|
switch (link->state)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if (MGL_HasReceived(link->recvPlayerId))
|
||||||
|
{
|
||||||
|
MGL_ReceiveBlock(link->recvPlayerId, &header, sizeof(header));
|
||||||
|
link->recvSize = header.size;
|
||||||
|
link->recvCRC = header.crc;
|
||||||
|
if (link->recvSize > MG_LINK_BUFFER_SIZE)
|
||||||
|
{
|
||||||
|
LinkRfu_FatalError();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else if (link->recvIdent != header.ident)
|
||||||
|
{
|
||||||
|
LinkRfu_FatalError();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
link->recvCounter = 0;
|
||||||
|
MGL_ResetReceived(link->recvPlayerId);
|
||||||
|
link->state++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (MGL_HasReceived(link->recvPlayerId))
|
||||||
|
{
|
||||||
|
size_t blocksize = link->recvCounter * 252;
|
||||||
|
if (link->recvSize - blocksize <= 252)
|
||||||
|
{
|
||||||
|
MGL_ReceiveBlock(link->recvPlayerId, link->recvBuffer + blocksize, link->recvSize - blocksize);
|
||||||
|
link->recvCounter++;
|
||||||
|
link->state++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MGL_ReceiveBlock(link->recvPlayerId, link->recvBuffer + blocksize, 252);
|
||||||
|
link->recvCounter++;
|
||||||
|
}
|
||||||
|
MGL_ResetReceived(link->recvPlayerId);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (CalcCRC16WithTable(link->recvBuffer, link->recvSize) != link->recvCRC)
|
||||||
|
{
|
||||||
|
LinkRfu_FatalError();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
link->state = 0;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool32 MGL_Send(struct MysteryGiftLink * link)
|
||||||
|
{
|
||||||
|
struct SendRecvHeader header;
|
||||||
|
|
||||||
|
switch (link->state)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if (IsLinkTaskFinished())
|
||||||
|
{
|
||||||
|
header.ident = link->sendIdent;
|
||||||
|
header.size = link->sendSize;
|
||||||
|
header.crc = CalcCRC16WithTable(link->sendBuffer, link->sendSize);
|
||||||
|
link->sendCRC = header.crc;
|
||||||
|
link->sendCounter = 0;
|
||||||
|
SendBlock(0, &header, sizeof(header));
|
||||||
|
link->state++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (IsLinkTaskFinished())
|
||||||
|
{
|
||||||
|
if (MGL_HasReceived(link->sendPlayerId))
|
||||||
|
{
|
||||||
|
size_t blocksize;
|
||||||
|
MGL_ResetReceived(link->sendPlayerId);
|
||||||
|
blocksize = 252 * link->sendCounter;
|
||||||
|
if (link->sendSize - blocksize <= 252)
|
||||||
|
{
|
||||||
|
SendBlock(0, link->sendBuffer + blocksize, link->sendSize - blocksize);
|
||||||
|
link->sendCounter++;
|
||||||
|
link->state++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SendBlock(0, link->sendBuffer + blocksize, 252);
|
||||||
|
link->sendCounter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (IsLinkTaskFinished())
|
||||||
|
{
|
||||||
|
if (CalcCRC16WithTable(link->sendBuffer, link->sendSize) != link->sendCRC)
|
||||||
|
LinkRfu_FatalError();
|
||||||
|
else
|
||||||
|
link->state++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if (MGL_HasReceived(link->sendPlayerId))
|
||||||
|
{
|
||||||
|
MGL_ResetReceived(link->sendPlayerId);
|
||||||
|
link->state = 0;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
+548
-600
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,198 @@
|
|||||||
|
#include "global.h"
|
||||||
|
#include "mystery_gift_server.h"
|
||||||
|
#include "mystery_gift_client.h"
|
||||||
|
#include "constants/mystery_gift.h"
|
||||||
|
|
||||||
|
extern const struct MysteryGiftServerCmd gServerScript_ClientCanceledCard[];
|
||||||
|
|
||||||
|
// Unreferenced
|
||||||
|
static const u8 sText_CollectedAllStamps[] = _("You have collected all STAMPs!\nWant to input a CARD as a prize?");
|
||||||
|
|
||||||
|
//==================
|
||||||
|
// Client scripts
|
||||||
|
//==================
|
||||||
|
|
||||||
|
const struct MysteryGiftClientCmd gMysteryGiftClientScript_Init[] = {
|
||||||
|
{CLI_RECV, MG_LINKID_CLIENT_SCRIPT},
|
||||||
|
{CLI_COPY_RECV}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct MysteryGiftClientCmd sClientScript_SendGameData[] = {
|
||||||
|
{CLI_LOAD_GAME_DATA},
|
||||||
|
{CLI_SEND_LOADED},
|
||||||
|
{CLI_RECV, MG_LINKID_CLIENT_SCRIPT},
|
||||||
|
{CLI_COPY_RECV}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct MysteryGiftClientCmd sClientScript_CantAccept[] = {
|
||||||
|
{CLI_SEND_READY_END},
|
||||||
|
{CLI_RETURN, CLI_MSG_CANT_ACCEPT}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct MysteryGiftClientCmd sClientScript_CommError[] = {
|
||||||
|
{CLI_SEND_READY_END},
|
||||||
|
{CLI_RETURN, CLI_MSG_COMM_ERROR}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct MysteryGiftClientCmd sClientScript_NothingSent[] = {
|
||||||
|
{CLI_SEND_READY_END},
|
||||||
|
{CLI_RETURN, CLI_MSG_NOTHING_SENT}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct MysteryGiftClientCmd sClientScript_SaveCard[] = {
|
||||||
|
{CLI_RECV, MG_LINKID_CARD},
|
||||||
|
{CLI_SAVE_CARD},
|
||||||
|
{CLI_RECV, MG_LINKID_RAM_SCRIPT},
|
||||||
|
{CLI_SAVE_RAM_SCRIPT},
|
||||||
|
{CLI_SEND_READY_END},
|
||||||
|
{CLI_RETURN, CLI_MSG_CARD_RECEIVED}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct MysteryGiftClientCmd sClientScript_SaveNews[] = {
|
||||||
|
{CLI_RECV, MG_LINKID_NEWS},
|
||||||
|
{CLI_SAVE_NEWS},
|
||||||
|
{CLI_SEND_LOADED}, // Send whether or not the News was saved (read by sServerScript_SendNews)
|
||||||
|
{CLI_RECV, MG_LINKID_CLIENT_SCRIPT},
|
||||||
|
{CLI_COPY_RECV}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct MysteryGiftClientCmd sClientScript_HadNews[] = {
|
||||||
|
{CLI_SEND_READY_END},
|
||||||
|
{CLI_RETURN, CLI_MSG_HAD_NEWS}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct MysteryGiftClientCmd sClientScript_NewsReceived[] = {
|
||||||
|
{CLI_SEND_READY_END},
|
||||||
|
{CLI_RETURN, CLI_MSG_NEWS_RECEIVED}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct MysteryGiftClientCmd sClientScript_AskToss[] = {
|
||||||
|
{CLI_ASK_TOSS},
|
||||||
|
{CLI_LOAD_TOSS_RESPONSE},
|
||||||
|
{CLI_SEND_LOADED},
|
||||||
|
{CLI_RECV, MG_LINKID_CLIENT_SCRIPT},
|
||||||
|
{CLI_COPY_RECV}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct MysteryGiftClientCmd sClientScript_Canceled[] = {
|
||||||
|
{CLI_SEND_READY_END},
|
||||||
|
{CLI_RETURN, CLI_MSG_COMM_CANCELED}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct MysteryGiftClientCmd sClientScript_HadCard[] = {
|
||||||
|
{CLI_SEND_READY_END},
|
||||||
|
{CLI_RETURN, CLI_MSG_HAD_CARD}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct MysteryGiftClientCmd sClientScript_DynamicSuccess[] = {
|
||||||
|
{CLI_RECV, MG_LINKID_DYNAMIC_MSG},
|
||||||
|
{CLI_COPY_MSG},
|
||||||
|
{CLI_SEND_READY_END},
|
||||||
|
{CLI_RETURN, CLI_MSG_BUFFER_SUCCESS}
|
||||||
|
};
|
||||||
|
|
||||||
|
//==================
|
||||||
|
// Server scripts
|
||||||
|
//==================
|
||||||
|
|
||||||
|
static const struct MysteryGiftServerCmd sServerScript_CantSend[] = {
|
||||||
|
{SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_CantAccept)},
|
||||||
|
{SVR_SEND},
|
||||||
|
{SVR_RECV, MG_LINKID_READY_END},
|
||||||
|
{SVR_RETURN, SVR_MSG_CANT_SEND_GIFT_1}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct MysteryGiftServerCmd sServerScript_CommError[] = {
|
||||||
|
{SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_CommError)},
|
||||||
|
{SVR_SEND},
|
||||||
|
{SVR_RECV, MG_LINKID_READY_END},
|
||||||
|
{SVR_RETURN, SVR_MSG_COMM_ERROR}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct MysteryGiftServerCmd sServerScript_ClientCanceledNews[] = {
|
||||||
|
{SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_Canceled)},
|
||||||
|
{SVR_SEND},
|
||||||
|
{SVR_RECV, MG_LINKID_READY_END},
|
||||||
|
{SVR_RETURN, SVR_MSG_CLIENT_CANCELED}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct MysteryGiftServerCmd sServerScript_HasNews[] = {
|
||||||
|
{SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_HadNews)},
|
||||||
|
{SVR_SEND},
|
||||||
|
{SVR_RECV, MG_LINKID_READY_END},
|
||||||
|
{SVR_RETURN, SVR_MSG_HAS_NEWS}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct MysteryGiftServerCmd sServerScript_SendNews[] = {
|
||||||
|
{SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_SaveNews)},
|
||||||
|
{SVR_SEND},
|
||||||
|
{SVR_LOAD_NEWS},
|
||||||
|
{SVR_SEND},
|
||||||
|
{SVR_RECV, MG_LINKID_RESPONSE},
|
||||||
|
{SVR_READ_RESPONSE},
|
||||||
|
{SVR_GOTO_IF_EQ, TRUE, sServerScript_HasNews}, // Wonder News was not saved
|
||||||
|
{SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_NewsReceived)},
|
||||||
|
{SVR_SEND},
|
||||||
|
{SVR_RECV, MG_LINKID_READY_END},
|
||||||
|
{SVR_RETURN, SVR_MSG_NEWS_SENT}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct MysteryGiftServerCmd sServerScript_SendCard[] = {
|
||||||
|
{SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_SaveCard)},
|
||||||
|
{SVR_SEND},
|
||||||
|
{SVR_LOAD_CARD},
|
||||||
|
{SVR_SEND},
|
||||||
|
{SVR_LOAD_RAM_SCRIPT},
|
||||||
|
{SVR_SEND},
|
||||||
|
{SVR_RECV, MG_LINKID_READY_END},
|
||||||
|
{SVR_RETURN, SVR_MSG_CARD_SENT}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct MysteryGiftServerCmd sServerScript_TossPrompt[] = {
|
||||||
|
{SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_AskToss)},
|
||||||
|
{SVR_SEND},
|
||||||
|
{SVR_RECV, MG_LINKID_RESPONSE},
|
||||||
|
{SVR_READ_RESPONSE},
|
||||||
|
{SVR_GOTO_IF_EQ, FALSE, sServerScript_SendCard}, // Tossed old card, send new one
|
||||||
|
{SVR_GOTO, .ptr = gServerScript_ClientCanceledCard} // Kept old card, cancel new one
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct MysteryGiftServerCmd sServerScript_HasCard[] = {
|
||||||
|
{SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_HadCard)},
|
||||||
|
{SVR_SEND},
|
||||||
|
{SVR_RECV, MG_LINKID_READY_END},
|
||||||
|
{SVR_RETURN, SVR_MSG_HAS_CARD}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct MysteryGiftServerCmd sServerScript_NothingSent[] = {
|
||||||
|
{SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_NothingSent)},
|
||||||
|
{SVR_SEND},
|
||||||
|
{SVR_RECV, MG_LINKID_READY_END},
|
||||||
|
{SVR_RETURN, SVR_MSG_NOTHING_SENT}
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct MysteryGiftServerCmd gMysteryGiftServerScript_SendWonderNews[] = {
|
||||||
|
{SVR_COPY_SAVED_NEWS},
|
||||||
|
{SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_SendGameData)},
|
||||||
|
{SVR_SEND},
|
||||||
|
{SVR_RECV, MG_LINKID_GAME_DATA},
|
||||||
|
{SVR_COPY_GAME_DATA},
|
||||||
|
{SVR_CHECK_GAME_DATA},
|
||||||
|
{SVR_GOTO_IF_EQ, FALSE, sServerScript_CantSend},
|
||||||
|
{SVR_GOTO, .ptr = sServerScript_SendNews},
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct MysteryGiftServerCmd gMysteryGiftServerScript_SendWonderCard[] = {
|
||||||
|
{SVR_COPY_SAVED_CARD},
|
||||||
|
{SVR_COPY_SAVED_RAM_SCRIPT},
|
||||||
|
{SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_SendGameData)},
|
||||||
|
{SVR_SEND},
|
||||||
|
{SVR_RECV, MG_LINKID_GAME_DATA},
|
||||||
|
{SVR_COPY_GAME_DATA},
|
||||||
|
{SVR_CHECK_GAME_DATA},
|
||||||
|
{SVR_GOTO_IF_EQ, FALSE, sServerScript_CantSend},
|
||||||
|
{SVR_CHECK_EXISTING_CARD},
|
||||||
|
{SVR_GOTO_IF_EQ, HAS_DIFF_CARD, sServerScript_TossPrompt},
|
||||||
|
{SVR_GOTO_IF_EQ, HAS_NO_CARD, sServerScript_SendCard},
|
||||||
|
{SVR_GOTO, .ptr = sServerScript_HasCard} // HAS_SAME_CARD
|
||||||
|
};
|
||||||
@@ -0,0 +1,302 @@
|
|||||||
|
#include "global.h"
|
||||||
|
#include "gflib.h"
|
||||||
|
#include "script.h"
|
||||||
|
#include "mystery_gift.h"
|
||||||
|
#include "mystery_gift_server.h"
|
||||||
|
|
||||||
|
// Assert statements use the original GF names, which are defined below.
|
||||||
|
// Note that their name "flag" is especially misleading,
|
||||||
|
// as it's not a boolean (for example it can contain a size argument).
|
||||||
|
// 'parameter' is shortened to param explicitly to avoid a collision with
|
||||||
|
// the original name for a different field.
|
||||||
|
#define mainseqno funcId
|
||||||
|
#define func_tbl sFuncTable
|
||||||
|
#define parameter ptr
|
||||||
|
#define flag param
|
||||||
|
#define ME_SEND_BUF_SIZE MG_LINK_BUFFER_SIZE
|
||||||
|
#define FILE ABSPATH("mevent_server.c")
|
||||||
|
|
||||||
|
#define ASSERT_PTR_EMPTY(lineNum) AGB_ASSERT_EX(cmd->parameter == NULL, FILE, (lineNum));
|
||||||
|
#define ASSERT_PARAM_EMPTY(lineNum) AGB_ASSERT_EX(cmd->flag == FALSE, FILE, (lineNum));
|
||||||
|
#define ASSERT_PTR_PARAM_EMPTY(lineNum) AGB_ASSERT_EX(cmd->flag == FALSE && cmd->parameter == NULL, FILE, (lineNum));
|
||||||
|
#define ASSERT_VALID_FUNC(lineNum) AGB_ASSERT_EX(svr->mainseqno < NELEMS(func_tbl), FILE, (lineNum));
|
||||||
|
#define ASSERT_SIZE_OK(lineNum) AGB_ASSERT_EX(size <= ME_SEND_BUF_SIZE, FILE, (lineNum));
|
||||||
|
|
||||||
|
enum {
|
||||||
|
FUNC_INIT,
|
||||||
|
FUNC_DONE,
|
||||||
|
FUNC_RECV,
|
||||||
|
FUNC_SEND,
|
||||||
|
FUNC_RUN,
|
||||||
|
};
|
||||||
|
|
||||||
|
static EWRAM_DATA struct MysteryGiftServer * sServer = NULL;
|
||||||
|
|
||||||
|
static void MysteryGiftServer_Init(struct MysteryGiftServer *, const void *, u32, u32);
|
||||||
|
static void MysteryGiftServer_Free(struct MysteryGiftServer *);
|
||||||
|
static u32 MysteryGiftServer_CallFunc(struct MysteryGiftServer *);
|
||||||
|
|
||||||
|
extern const struct MysteryGiftServerCmd gMysteryGiftServerScript_SendWonderNews[];
|
||||||
|
extern const struct MysteryGiftServerCmd gMysteryGiftServerScript_SendWonderCard[];
|
||||||
|
|
||||||
|
void MysterGiftServer_CreateForNews(void)
|
||||||
|
{
|
||||||
|
sServer = AllocZeroed(sizeof(*sServer));
|
||||||
|
MysteryGiftServer_Init(sServer, gMysteryGiftServerScript_SendWonderNews, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MysterGiftServer_CreateForCard(void)
|
||||||
|
{
|
||||||
|
sServer = AllocZeroed(sizeof(*sServer));
|
||||||
|
MysteryGiftServer_Init(sServer, gMysteryGiftServerScript_SendWonderCard, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 MysterGiftServer_Run(u16 * endVal)
|
||||||
|
{
|
||||||
|
u32 result;
|
||||||
|
if (sServer == NULL)
|
||||||
|
return SVR_RET_END;
|
||||||
|
result = MysteryGiftServer_CallFunc(sServer);
|
||||||
|
if (result == SVR_RET_END)
|
||||||
|
{
|
||||||
|
*endVal = sServer->param;
|
||||||
|
MysteryGiftServer_Free(sServer);
|
||||||
|
FREE_AND_SET_NULL(sServer);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MysteryGiftServer_Init(struct MysteryGiftServer * svr, const void *script, u32 sendPlayerId, u32 recvPlayerId)
|
||||||
|
{
|
||||||
|
svr->unused = 0;
|
||||||
|
svr->funcId = FUNC_INIT;
|
||||||
|
svr->card = AllocZeroed(sizeof(*svr->card));
|
||||||
|
svr->news = AllocZeroed(sizeof(*svr->news));
|
||||||
|
svr->recvBuffer = AllocZeroed(MG_LINK_BUFFER_SIZE);
|
||||||
|
svr->linkGameData = AllocZeroed(sizeof(*svr->linkGameData));
|
||||||
|
svr->script = script;
|
||||||
|
svr->cmdidx = 0;
|
||||||
|
MysteryGiftLink_Init(&svr->manager, sendPlayerId, recvPlayerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MysteryGiftServer_Free(struct MysteryGiftServer * svr)
|
||||||
|
{
|
||||||
|
Free(svr->card);
|
||||||
|
Free(svr->news);
|
||||||
|
Free(svr->recvBuffer);
|
||||||
|
Free(svr->linkGameData);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MysteryGiftServer_InitSend(struct MysteryGiftServer * svr, u32 ident, const void *src, u32 size)
|
||||||
|
{
|
||||||
|
ASSERT_SIZE_OK(257);
|
||||||
|
MysteryGiftLink_InitSend(&svr->manager, ident, src, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Given the command pointer parameter and the 'default' normal data.
|
||||||
|
// If the command's pointer is not empty use that as the send data, otherwise use the default.
|
||||||
|
static const void *MysteryGiftServer_GetSendData(const void *dynamicData, const void *defaultData)
|
||||||
|
{
|
||||||
|
if (dynamicData != NULL)
|
||||||
|
return dynamicData;
|
||||||
|
else
|
||||||
|
return defaultData;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 MysteryGiftServer_Compare(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
if (b < a)
|
||||||
|
return 0;
|
||||||
|
else if (b == a)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 Server_Init(struct MysteryGiftServer * svr)
|
||||||
|
{
|
||||||
|
svr->funcId = FUNC_RUN;
|
||||||
|
return SVR_RET_INIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 Server_Done(struct MysteryGiftServer * svr)
|
||||||
|
{
|
||||||
|
return SVR_RET_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 Server_Recv(struct MysteryGiftServer * svr)
|
||||||
|
{
|
||||||
|
if (MysteryGiftLink_Recv(&svr->manager))
|
||||||
|
svr->funcId = FUNC_RUN;
|
||||||
|
return SVR_RET_ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 Server_Send(struct MysteryGiftServer * svr)
|
||||||
|
{
|
||||||
|
if (MysteryGiftLink_Send(&svr->manager))
|
||||||
|
svr->funcId = FUNC_RUN;
|
||||||
|
return SVR_RET_ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 Server_Run(struct MysteryGiftServer * svr)
|
||||||
|
{
|
||||||
|
// process command
|
||||||
|
const struct MysteryGiftServerCmd * cmd = &svr->script[svr->cmdidx];
|
||||||
|
const void *ptr;
|
||||||
|
svr->cmdidx++;
|
||||||
|
|
||||||
|
switch (cmd->instr)
|
||||||
|
{
|
||||||
|
case SVR_RETURN:
|
||||||
|
ASSERT_PTR_EMPTY(354);
|
||||||
|
svr->funcId = FUNC_DONE;
|
||||||
|
svr->param = cmd->param; // Set for endVal in MysteryGiftServer_Run
|
||||||
|
break;
|
||||||
|
case SVR_SEND:
|
||||||
|
svr->funcId = FUNC_SEND;
|
||||||
|
break;
|
||||||
|
case SVR_RECV:
|
||||||
|
ASSERT_PTR_EMPTY(364);
|
||||||
|
MysteryGiftLink_InitRecv(&svr->manager, cmd->param, svr->recvBuffer);
|
||||||
|
svr->funcId = FUNC_RECV;
|
||||||
|
break;
|
||||||
|
case SVR_GOTO:
|
||||||
|
ASSERT_PARAM_EMPTY(370);
|
||||||
|
svr->cmdidx = 0;
|
||||||
|
svr->script = cmd->ptr;
|
||||||
|
break;
|
||||||
|
case SVR_COPY_GAME_DATA:
|
||||||
|
ASSERT_PARAM_EMPTY(376);
|
||||||
|
ASSERT_PTR_EMPTY(377);
|
||||||
|
memcpy(svr->linkGameData, svr->recvBuffer, sizeof(*svr->linkGameData));
|
||||||
|
break;
|
||||||
|
case SVR_CHECK_GAME_DATA:
|
||||||
|
ASSERT_PARAM_EMPTY(382);
|
||||||
|
ASSERT_PTR_EMPTY(383);
|
||||||
|
svr->param = MysteryGift_ValidateLinkGameData(svr->linkGameData);
|
||||||
|
break;
|
||||||
|
case SVR_GOTO_IF_EQ:
|
||||||
|
if (svr->param == cmd->param)
|
||||||
|
{
|
||||||
|
svr->cmdidx = 0;
|
||||||
|
svr->script = cmd->ptr;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SVR_CHECK_EXISTING_CARD:
|
||||||
|
ASSERT_PARAM_EMPTY(396);
|
||||||
|
ptr = MysteryGiftServer_GetSendData(cmd->ptr, svr->card);
|
||||||
|
svr->param = MysteryGift_CompareCardFlags(ptr, svr->linkGameData, ptr);
|
||||||
|
break;
|
||||||
|
case SVR_READ_RESPONSE:
|
||||||
|
ASSERT_PARAM_EMPTY(402);
|
||||||
|
ASSERT_PTR_EMPTY(403);
|
||||||
|
svr->param = *(u32 *)svr->recvBuffer;
|
||||||
|
break;
|
||||||
|
case SVR_CHECK_EXISTING_STAMPS:
|
||||||
|
ASSERT_PARAM_EMPTY(408);
|
||||||
|
ptr = MysteryGiftServer_GetSendData(cmd->ptr, &svr->stamp);
|
||||||
|
svr->param = MysteryGift_CheckStamps(ptr, svr->linkGameData, ptr);
|
||||||
|
break;
|
||||||
|
case SVR_GET_CARD_STAT:
|
||||||
|
ASSERT_PTR_EMPTY(415);
|
||||||
|
svr->param = MysteryGift_GetCardStatFromLinkData(svr->linkGameData, cmd->param);
|
||||||
|
break;
|
||||||
|
case SVR_CHECK_QUESTIONNAIRE:
|
||||||
|
ASSERT_PARAM_EMPTY(420);
|
||||||
|
svr->param = MysteryGift_DoesQuestionnaireMatch(svr->linkGameData, cmd->ptr);
|
||||||
|
break;
|
||||||
|
case SVR_COMPARE:
|
||||||
|
ASSERT_PARAM_EMPTY(426);
|
||||||
|
svr->param = MysteryGiftServer_Compare(cmd->ptr, *(void **)svr->recvBuffer);
|
||||||
|
break;
|
||||||
|
case SVR_LOAD_NEWS:
|
||||||
|
ASSERT_PARAM_EMPTY(432);
|
||||||
|
MysteryGiftServer_InitSend(svr, MG_LINKID_NEWS, MysteryGiftServer_GetSendData(cmd->ptr, svr->news), sizeof(struct WonderNews));
|
||||||
|
break;
|
||||||
|
case SVR_LOAD_CARD:
|
||||||
|
ASSERT_PARAM_EMPTY(438);
|
||||||
|
MysteryGiftServer_InitSend(svr, MG_LINKID_CARD, MysteryGiftServer_GetSendData(cmd->ptr, svr->card), sizeof(struct WonderCard));
|
||||||
|
break;
|
||||||
|
case SVR_LOAD_STAMP:
|
||||||
|
ASSERT_PARAM_EMPTY(444);
|
||||||
|
MysteryGiftServer_InitSend(svr, MG_LINKID_STAMP, MysteryGiftServer_GetSendData(cmd->ptr, &svr->stamp), sizeof(svr->stamp));
|
||||||
|
break;
|
||||||
|
case SVR_LOAD_RAM_SCRIPT:
|
||||||
|
if (cmd->ptr == NULL)
|
||||||
|
MysteryGiftServer_InitSend(svr, MG_LINKID_RAM_SCRIPT, svr->ramScript, svr->ramScriptSize);
|
||||||
|
else
|
||||||
|
MysteryGiftServer_InitSend(svr, MG_LINKID_RAM_SCRIPT, cmd->ptr, cmd->param);
|
||||||
|
break;
|
||||||
|
case SVR_LOAD_CLIENT_SCRIPT:
|
||||||
|
if (cmd->ptr == NULL)
|
||||||
|
MysteryGiftServer_InitSend(svr, MG_LINKID_CLIENT_SCRIPT, svr->clientScript, svr->clientScriptSize);
|
||||||
|
else
|
||||||
|
MysteryGiftServer_InitSend(svr, MG_LINKID_CLIENT_SCRIPT, cmd->ptr, cmd->param);
|
||||||
|
break;
|
||||||
|
case SVR_LOAD_EREADER_TRAINER:
|
||||||
|
ASSERT_PARAM_EMPTY(466);
|
||||||
|
MysteryGiftServer_InitSend(svr, MG_LINKID_EREADER_TRAINER, cmd->ptr, sizeof(struct BattleTowerEReaderTrainer));
|
||||||
|
break;
|
||||||
|
case SVR_LOAD_MSG:
|
||||||
|
MysteryGiftServer_InitSend(svr, MG_LINKID_DYNAMIC_MSG, cmd->ptr, cmd->param);
|
||||||
|
break;
|
||||||
|
case SVR_LOAD_UNK_2:
|
||||||
|
MysteryGiftServer_InitSend(svr, MG_LINKID_UNK_2, cmd->ptr, cmd->param);
|
||||||
|
break;
|
||||||
|
case SVR_COPY_CARD:
|
||||||
|
ASSERT_PARAM_EMPTY(481);
|
||||||
|
memcpy(svr->card, cmd->ptr, sizeof(*svr->card));
|
||||||
|
break;
|
||||||
|
case SVR_COPY_NEWS:
|
||||||
|
ASSERT_PARAM_EMPTY(486);
|
||||||
|
memcpy(svr->news, cmd->ptr, sizeof(*svr->news));
|
||||||
|
break;
|
||||||
|
case SVR_COPY_STAMP:
|
||||||
|
ASSERT_PARAM_EMPTY(491);
|
||||||
|
svr->stamp = *(u32 *)cmd->ptr;
|
||||||
|
break;
|
||||||
|
case SVR_SET_RAM_SCRIPT:
|
||||||
|
svr->ramScript = cmd->ptr;
|
||||||
|
svr->ramScriptSize = cmd->param;
|
||||||
|
break;
|
||||||
|
case SVR_SET_CLIENT_SCRIPT:
|
||||||
|
svr->clientScript = cmd->ptr;
|
||||||
|
svr->clientScriptSize = cmd->param;
|
||||||
|
break;
|
||||||
|
case SVR_COPY_SAVED_CARD:
|
||||||
|
ASSERT_PTR_PARAM_EMPTY(506);
|
||||||
|
memcpy(svr->card, GetSavedWonderCard(), sizeof(*svr->card));
|
||||||
|
DisableWonderCardSending(svr->card);
|
||||||
|
break;
|
||||||
|
case SVR_COPY_SAVED_NEWS:
|
||||||
|
ASSERT_PTR_PARAM_EMPTY(512);
|
||||||
|
memcpy(svr->news, GetSavedWonderNews(), sizeof(*svr->news));
|
||||||
|
break;
|
||||||
|
case SVR_COPY_SAVED_RAM_SCRIPT:
|
||||||
|
ASSERT_PTR_PARAM_EMPTY(517);
|
||||||
|
svr->ramScript = GetSavedRamScriptIfValid();
|
||||||
|
break;
|
||||||
|
case SVR_LOAD_UNK_1:
|
||||||
|
MysteryGiftServer_InitSend(svr, MG_LINKID_UNK_1, cmd->ptr, cmd->param);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SVR_RET_ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 (*const sFuncTable[])(struct MysteryGiftServer *) = {
|
||||||
|
[FUNC_INIT] = Server_Init,
|
||||||
|
[FUNC_DONE] = Server_Done,
|
||||||
|
[FUNC_RECV] = Server_Recv,
|
||||||
|
[FUNC_SEND] = Server_Send,
|
||||||
|
[FUNC_RUN] = Server_Run
|
||||||
|
};
|
||||||
|
|
||||||
|
static u32 MysteryGiftServer_CallFunc(struct MysteryGiftServer * svr)
|
||||||
|
{
|
||||||
|
u32 response;
|
||||||
|
ASSERT_VALID_FUNC(546)
|
||||||
|
response = sFuncTable[svr->funcId](svr);
|
||||||
|
ASSERT_VALID_FUNC(548)
|
||||||
|
return response;
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
#include "new_menu_helpers.h"
|
#include "new_menu_helpers.h"
|
||||||
#include "pokemon_icon.h"
|
#include "pokemon_icon.h"
|
||||||
#include "mystery_gift_menu.h"
|
#include "mystery_gift_menu.h"
|
||||||
#include "mevent.h"
|
#include "mystery_gift.h"
|
||||||
#include "battle_anim.h"
|
#include "battle_anim.h"
|
||||||
#include "constants/mystery_gift.h"
|
#include "constants/mystery_gift.h"
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#include "gflib.h"
|
#include "gflib.h"
|
||||||
#include "menu_indicators.h"
|
#include "menu_indicators.h"
|
||||||
#include "new_menu_helpers.h"
|
#include "new_menu_helpers.h"
|
||||||
#include "mevent.h"
|
#include "mystery_gift.h"
|
||||||
#include "mystery_gift_menu.h"
|
#include "mystery_gift_menu.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "link_rfu.h"
|
#include "link_rfu.h"
|
||||||
|
|||||||
+2
-2
@@ -22,7 +22,7 @@
|
|||||||
#include "berry.h"
|
#include "berry.h"
|
||||||
#include "easy_chat.h"
|
#include "easy_chat.h"
|
||||||
#include "union_room_chat.h"
|
#include "union_room_chat.h"
|
||||||
#include "mevent.h"
|
#include "mystery_gift.h"
|
||||||
#include "renewable_hidden_items.h"
|
#include "renewable_hidden_items.h"
|
||||||
#include "trainer_tower.h"
|
#include "trainer_tower.h"
|
||||||
#include "script.h"
|
#include "script.h"
|
||||||
@@ -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);
|
||||||
|
|||||||
+170
-131
@@ -4,160 +4,191 @@
|
|||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "wild_pokemon_area.h"
|
#include "wild_pokemon_area.h"
|
||||||
#include "pokedex_area_markers.h"
|
#include "pokedex_area_markers.h"
|
||||||
|
#include "pokedex.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Controls the red ellipse markers that appear on the pokedex maps to show where a species is found.
|
||||||
|
All of the markers together are a single sprite, with each individual marker being represented by
|
||||||
|
a subsprite of the necessary size and shape.
|
||||||
|
|
||||||
|
The data about each area marker is in sAreaMarkers, each specified by a DEX_AREA constant.
|
||||||
|
A MAPSEC is associated with a DEX_AREA constant by a series of arrays in wild_pokemon_area.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct PAM_TaskData
|
||||||
|
{
|
||||||
|
struct SubspriteTable subsprites;
|
||||||
|
void *buffer;
|
||||||
|
u8 unused;
|
||||||
|
u8 spriteId;
|
||||||
|
u16 tilesTag;
|
||||||
|
u16 paletteTag; // Never read
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MARKER_CIRCULAR,
|
||||||
|
MARKER_SMALL_H,
|
||||||
|
MARKER_SMALL_V,
|
||||||
|
MARKER_MED_H,
|
||||||
|
MARKER_MED_V,
|
||||||
|
MARKER_LARGE_H,
|
||||||
|
MARKER_LARGE_V,
|
||||||
|
};
|
||||||
|
|
||||||
static const u16 sMarkerPal[] = INCBIN_U16("graphics/pokedex/area_markers/marker.gbapal");
|
static const u16 sMarkerPal[] = INCBIN_U16("graphics/pokedex/area_markers/marker.gbapal");
|
||||||
static const u32 sMarkerTiles[] = INCBIN_U32("graphics/pokedex/area_markers/marker.4bpp.lz");
|
static const u32 sMarkerTiles[] = INCBIN_U32("graphics/pokedex/area_markers/marker.4bpp.lz");
|
||||||
|
|
||||||
static const struct Subsprite sSubsprite0 = {
|
static const struct Subsprite sSubsprite_Circular = {
|
||||||
.size = ST_OAM_SIZE_0,
|
.size = SPRITE_SIZE(8x8),
|
||||||
.shape = ST_OAM_SQUARE,
|
.shape = SPRITE_SHAPE(8x8),
|
||||||
.priority = 1,
|
.priority = 1,
|
||||||
.tileOffset = 0
|
.tileOffset = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct Subsprite sSubsprite1 = {
|
static const struct Subsprite sSubsprite_SmallHorizontal = {
|
||||||
.size = ST_OAM_SIZE_0,
|
.size = SPRITE_SIZE(16x8),
|
||||||
.shape = ST_OAM_H_RECTANGLE,
|
.shape = SPRITE_SHAPE(16x8),
|
||||||
.priority = 1,
|
.priority = 1,
|
||||||
.tileOffset = 1
|
.tileOffset = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct Subsprite sSubsprite2 = {
|
static const struct Subsprite sSubsprite_SmallVertical = {
|
||||||
.size = ST_OAM_SIZE_0,
|
.size = SPRITE_SIZE(8x16),
|
||||||
.shape = ST_OAM_V_RECTANGLE,
|
.shape = SPRITE_SHAPE(8x16),
|
||||||
.priority = 1,
|
.priority = 1,
|
||||||
.tileOffset = 3
|
.tileOffset = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct Subsprite sSubsprite3 = {
|
static const struct Subsprite sSubsprite_MediumHorizontal = {
|
||||||
.size = ST_OAM_SIZE_2,
|
.size = SPRITE_SIZE(32x16),
|
||||||
.shape = ST_OAM_H_RECTANGLE,
|
.shape = SPRITE_SHAPE(32x16),
|
||||||
.priority = 1,
|
.priority = 1,
|
||||||
.tileOffset = 5
|
.tileOffset = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct Subsprite sSubsprite4 = {
|
static const struct Subsprite sSubsprite_MediumVertical = {
|
||||||
.size = ST_OAM_SIZE_2,
|
.size = SPRITE_SIZE(16x32),
|
||||||
.shape = ST_OAM_V_RECTANGLE,
|
.shape = SPRITE_SHAPE(16x32),
|
||||||
.priority = 1,
|
.priority = 1,
|
||||||
.tileOffset = 13
|
.tileOffset = 13
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct Subsprite sSubsprite5 = {
|
static const struct Subsprite sSubsprite_LargeHorizontal = {
|
||||||
.size = ST_OAM_SIZE_2,
|
.size = SPRITE_SIZE(32x16),
|
||||||
.shape = ST_OAM_H_RECTANGLE,
|
.shape = SPRITE_SHAPE(32x16),
|
||||||
.priority = 1,
|
.priority = 1,
|
||||||
.tileOffset = 21
|
.tileOffset = 21
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct Subsprite sSubsprite6 = {
|
static const struct Subsprite sSubsprite_LargeVertical = {
|
||||||
.size = ST_OAM_SIZE_2,
|
.size = SPRITE_SIZE(16x32),
|
||||||
.shape = ST_OAM_V_RECTANGLE,
|
.shape = SPRITE_SHAPE(16x32),
|
||||||
.priority = 1,
|
.priority = 1,
|
||||||
.tileOffset = 29
|
.tileOffset = 29
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static const struct Subsprite *const sSubsprites[] = {
|
static const struct Subsprite *const sSubsprites[] = {
|
||||||
&sSubsprite0,
|
[MARKER_CIRCULAR] = &sSubsprite_Circular,
|
||||||
&sSubsprite1,
|
[MARKER_SMALL_H] = &sSubsprite_SmallHorizontal,
|
||||||
&sSubsprite2,
|
[MARKER_SMALL_V] = &sSubsprite_SmallVertical,
|
||||||
&sSubsprite3,
|
[MARKER_MED_H] = &sSubsprite_MediumHorizontal,
|
||||||
&sSubsprite4,
|
[MARKER_MED_V] = &sSubsprite_MediumVertical,
|
||||||
&sSubsprite5,
|
[MARKER_LARGE_H] = &sSubsprite_LargeHorizontal,
|
||||||
&sSubsprite6
|
[MARKER_LARGE_V] = &sSubsprite_LargeVertical
|
||||||
};
|
};
|
||||||
|
|
||||||
static const s8 sSubspriteLookupTable[][4] = {
|
static const s8 sAreaMarkers[][4] = {
|
||||||
{ 0, 0x00, 0x00 },
|
// Marker, x, y
|
||||||
{ 0, 0x36, 0x2c },
|
[DEX_AREA_NONE] = {},
|
||||||
{ 0, 0x36, 0x1c },
|
[DEX_AREA_PALLET_TOWN] = { MARKER_CIRCULAR, 54, 44 },
|
||||||
{ 0, 0x36, 0x0c },
|
[DEX_AREA_VIRIDIAN_CITY] = { MARKER_CIRCULAR, 54, 28 },
|
||||||
{ 0, 0x5c, 0x0c },
|
[DEX_AREA_PEWTER_CITY] = { MARKER_CIRCULAR, 54, 12 },
|
||||||
{ 0, 0x6e, 0x18 },
|
[DEX_AREA_CERULEAN_CITY] = { MARKER_CIRCULAR, 92, 12 },
|
||||||
{ 0, 0x5c, 0x24 },
|
[DEX_AREA_LAVENDER_TOWN] = { MARKER_CIRCULAR, 110, 24 },
|
||||||
{ 0, 0x4c, 0x18 },
|
[DEX_AREA_VERMILION_CITY] = { MARKER_CIRCULAR, 92, 36 },
|
||||||
{ 0, 0x4e, 0x34 },
|
[DEX_AREA_CELADON_CITY] = { MARKER_CIRCULAR, 76, 24 },
|
||||||
{ 0, 0x36, 0x3e },
|
[DEX_AREA_FUCHSIA_CITY] = { MARKER_CIRCULAR, 78, 52 },
|
||||||
{ 0, 0x2a, 0x02 },
|
[DEX_AREA_CINNABAR_ISLAND] = { MARKER_CIRCULAR, 54, 62 },
|
||||||
{ 0, 0x5c, 0x18 },
|
[DEX_AREA_INDIGO_PLATEAU] = { MARKER_CIRCULAR, 42, 2 },
|
||||||
{ 2, 0x36, 0x20 },
|
[DEX_AREA_SAFFRON_CITY] = { MARKER_CIRCULAR, 92, 24 },
|
||||||
{ 2, 0x36, 0x10 },
|
[DEX_AREA_ROUTE_1] = { MARKER_SMALL_V, 54, 32 },
|
||||||
{ 1, 0x3d, 0x0c },
|
[DEX_AREA_ROUTE_2] = { MARKER_SMALL_V, 54, 16 },
|
||||||
{ 1, 0x4d, 0x0c },
|
[DEX_AREA_ROUTE_3] = { MARKER_SMALL_H, 61, 12 },
|
||||||
{ 0, 0x5c, 0x12 },
|
[DEX_AREA_ROUTE_4] = { MARKER_SMALL_H, 77, 12 },
|
||||||
{ 0, 0x5c, 0x1e },
|
[DEX_AREA_ROUTE_5] = { MARKER_CIRCULAR, 92, 18 },
|
||||||
{ 0, 0x54, 0x18 },
|
[DEX_AREA_ROUTE_6] = { MARKER_CIRCULAR, 92, 30 },
|
||||||
{ 1, 0x62, 0x18 },
|
[DEX_AREA_ROUTE_7] = { MARKER_CIRCULAR, 84, 24 },
|
||||||
{ 1, 0x62, 0x0c },
|
[DEX_AREA_ROUTE_8] = { MARKER_SMALL_H, 98, 24 },
|
||||||
{ 2, 0x6e, 0x0c },
|
[DEX_AREA_ROUTE_9] = { MARKER_SMALL_H, 98, 12 },
|
||||||
{ 1, 0x62, 0x24 },
|
[DEX_AREA_ROUTE_10] = { MARKER_SMALL_V, 110, 12 },
|
||||||
{ 4, 0x6a, 0x19 },
|
[DEX_AREA_ROUTE_11] = { MARKER_SMALL_H, 98, 36 },
|
||||||
{ 1, 0x64, 0x2e },
|
[DEX_AREA_ROUTE_12] = { MARKER_MED_V, 106, 25 },
|
||||||
{ 2, 0x5e, 0x2d },
|
[DEX_AREA_ROUTE_13] = { MARKER_SMALL_H, 100, 46 },
|
||||||
{ 1, 0x55, 0x34 },
|
[DEX_AREA_ROUTE_14] = { MARKER_SMALL_V, 94, 45 },
|
||||||
{ 0, 0x44, 0x18 },
|
[DEX_AREA_ROUTE_15] = { MARKER_SMALL_H, 85, 52 },
|
||||||
{ 4, 0x3e, 0x1a },
|
[DEX_AREA_ROUTE_16] = { MARKER_CIRCULAR, 68, 24 },
|
||||||
{ 1, 0x40, 0x34 },
|
[DEX_AREA_ROUTE_17] = { MARKER_MED_V, 62, 26 },
|
||||||
{ 0, 0x4e, 0x3c },
|
[DEX_AREA_ROUTE_18] = { MARKER_SMALL_H, 64, 52 },
|
||||||
{ 3, 0x37, 0x3a },
|
[DEX_AREA_ROUTE_19] = { MARKER_CIRCULAR, 78, 60 },
|
||||||
{ 2, 0x36, 0x32 },
|
[DEX_AREA_ROUTE_20] = { MARKER_MED_H, 55, 58 },
|
||||||
{ 1, 0x28, 0x1c },
|
[DEX_AREA_ROUTE_21] = { MARKER_SMALL_V, 54, 50 },
|
||||||
{ 4, 0x26, 0x04 },
|
[DEX_AREA_ROUTE_22] = { MARKER_SMALL_H, 40, 28 },
|
||||||
{ 0, 0x5c, 0x04 },
|
[DEX_AREA_ROUTE_23] = { MARKER_MED_V, 38, 4 },
|
||||||
{ 3, 0x5a, 0xfe },
|
[DEX_AREA_ROUTE_24] = { MARKER_CIRCULAR, 92, 4 },
|
||||||
{ 0, 0x33, 0x14 },
|
[DEX_AREA_ROUTE_25] = { MARKER_MED_H, 90, -2 },
|
||||||
{ 1, 0x3d, 0x12 },
|
[DEX_AREA_VIRIDIAN_FOREST] = { MARKER_CIRCULAR, 51, 20 },
|
||||||
{ 0, 0x48, 0x08 },
|
[DEX_AREA_DIGLETTS_CAVE] = { MARKER_SMALL_H, 61, 18 },
|
||||||
{ 0, 0x57, 0x08 },
|
[DEX_AREA_MT_MOON] = { MARKER_CIRCULAR, 72, 8 },
|
||||||
{ 0, 0x70, 0x0e },
|
[DEX_AREA_CERULEAN_CAVE] = { MARKER_CIRCULAR, 87, 8 },
|
||||||
{ 0, 0x71, 0x14 },
|
[DEX_AREA_ROCK_TUNNEL] = { MARKER_CIRCULAR, 112, 14 },
|
||||||
{ 0, 0x71, 0x19 },
|
[DEX_AREA_POWER_PLANT] = { MARKER_CIRCULAR, 113, 20 },
|
||||||
{ 1, 0x4e, 0x2c },
|
[DEX_AREA_POKEMON_TOWER] = { MARKER_CIRCULAR, 113, 25 },
|
||||||
{ 0, 0x41, 0x3c },
|
[DEX_AREA_SAFARI_ZONE] = { MARKER_SMALL_H, 78, 44 },
|
||||||
{ 0, 0x34, 0x3e },
|
[DEX_AREA_SEAFOAM_ISLANDS] = { MARKER_CIRCULAR, 65, 60 },
|
||||||
{ 0, 0x2d, 0x07 },
|
[DEX_AREA_POKEMON_MANSION] = { MARKER_CIRCULAR, 52, 62 },
|
||||||
{ 0, 0x0a, 0x0a },
|
[DEX_AREA_VICTORY_ROAD] = { MARKER_CIRCULAR, 45, 7 },
|
||||||
{ 0, 0x0c, 0x23 },
|
[DEX_AREA_ONE_ISLAND] = { MARKER_CIRCULAR, 10, 10 },
|
||||||
{ 0, 0x0e, 0x34 },
|
[DEX_AREA_TWO_ISLAND] = { MARKER_CIRCULAR, 12, 35 },
|
||||||
{ 0, 0x0c, 0x54 },
|
[DEX_AREA_THREE_ISLAND] = { MARKER_CIRCULAR, 14, 52 },
|
||||||
{ 0, 0x2d, 0x51 },
|
[DEX_AREA_FOUR_ISLAND] = { MARKER_CIRCULAR, 12, 84 },
|
||||||
{ 0, 0x4c, 0x54 },
|
[DEX_AREA_FIVE_ISLAND] = { MARKER_CIRCULAR, 45, 81 },
|
||||||
{ 0, 0x68, 0x52 },
|
[DEX_AREA_SIX_ISLAND] = { MARKER_CIRCULAR, 76, 84 },
|
||||||
{ 2, 0x0e, 0x02 },
|
[DEX_AREA_SEVEN_ISLAND] = { MARKER_CIRCULAR, 104, 82 },
|
||||||
{ 0, 0x0a, 0x0f },
|
[DEX_AREA_KINDLE_ROAD] = { MARKER_SMALL_V, 14, 2 },
|
||||||
{ 0, 0x0c, 0x1d },
|
[DEX_AREA_TREASURE_BEACH] = { MARKER_CIRCULAR, 10, 15 },
|
||||||
{ 1, 0x02, 0x34 },
|
[DEX_AREA_CAPE_BRINK] = { MARKER_CIRCULAR, 12, 29 },
|
||||||
{ 1, 0x0c, 0x38 },
|
[DEX_AREA_BOND_BRIDGE] = { MARKER_SMALL_H, 2, 52 },
|
||||||
{ 1, 0x2c, 0x4a },
|
[DEX_AREA_THREE_ISLE_PATH] = { MARKER_SMALL_H, 12, 56 },
|
||||||
{ 1, 0x24, 0x4e },
|
[DEX_AREA_RESORT_GORGEOUS] = { MARKER_SMALL_H, 44, 74 },
|
||||||
{ 2, 0x30, 0x50 },
|
[DEX_AREA_WATER_LABYRINTH] = { MARKER_SMALL_H, 36, 78 },
|
||||||
{ 2, 0x34, 0x56 },
|
[DEX_AREA_FIVE_ISLE_MEADOW] = { MARKER_SMALL_V, 48, 80 },
|
||||||
{ 0, 0x48, 0x4a },
|
[DEX_AREA_MEMORIAL_PILLAR] = { MARKER_SMALL_V, 52, 86 },
|
||||||
{ 1, 0x48, 0x4e },
|
[DEX_AREA_OUTCAST_ISLAND] = { MARKER_CIRCULAR, 72, 74 },
|
||||||
{ 2, 0x51, 0x50 },
|
[DEX_AREA_GREEN_PATH] = { MARKER_SMALL_H, 72, 78 },
|
||||||
{ 0, 0x4c, 0x5c },
|
[DEX_AREA_WATER_PATH] = { MARKER_SMALL_V, 81, 80 },
|
||||||
{ 0, 0x68, 0x4b },
|
[DEX_AREA_RUIN_VALLEY] = { MARKER_CIRCULAR, 76, 92 },
|
||||||
{ 0, 0x68, 0x56 },
|
[DEX_AREA_TRAINER_TOWER] = { MARKER_CIRCULAR, 104, 75 },
|
||||||
{ 2, 0x6c, 0x53 },
|
[DEX_AREA_CANYON_ENTRANCE] = { MARKER_CIRCULAR, 104, 86 },
|
||||||
{ 3, 0x60, 0x5a },
|
[DEX_AREA_SEVAULT_CANYON] = { MARKER_SMALL_V, 108, 83 },
|
||||||
{ 0, 0x0e, 0x01 },
|
[DEX_AREA_TANOBY_RUINS] = { MARKER_MED_H, 96, 90 },
|
||||||
{ 0, 0x05, 0x34 },
|
[DEX_AREA_MT_EMBER] = { MARKER_CIRCULAR, 14, 1 },
|
||||||
{ 0, 0x0d, 0x50 },
|
[DEX_AREA_BERRY_FOREST] = { MARKER_CIRCULAR, 5, 52 },
|
||||||
{ 0, 0x36, 0x4a },
|
[DEX_AREA_ICEFALL_CAVE] = { MARKER_CIRCULAR, 13, 80 },
|
||||||
{ 0, 0x45, 0x49 },
|
[DEX_AREA_LOST_CAVE] = { MARKER_CIRCULAR, 54, 74 },
|
||||||
{ 0, 0x4c, 0x4d },
|
[DEX_AREA_ALTERING_CAVE] = { MARKER_CIRCULAR, 69, 73 },
|
||||||
{ 0, 0x49, 0x5f },
|
[DEX_AREA_PATTERN_BUSH] = { MARKER_CIRCULAR, 76, 77 },
|
||||||
{ 3, 0x60, 0x5a }
|
[DEX_AREA_DOTTED_HOLE] = { MARKER_CIRCULAR, 73, 95 },
|
||||||
|
[DEX_AREA_TANOBY_CHAMBER] = { MARKER_MED_H, 96, 90 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void Task_ShowAreaMarkers(u8 taskId)
|
static void Task_ShowAreaMarkers(u8 taskId)
|
||||||
{
|
{
|
||||||
struct PAM_TaskData * data = (void *)gTasks[taskId].data;
|
struct PAM_TaskData * data = (void *)gTasks[taskId].data;
|
||||||
gSprites[data->spr_id].invisible = FALSE;
|
gSprites[data->spriteId].invisible = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 Ctor_PokedexAreaMarkers(u16 species, u16 tilesTag, u8 palIdx, u8 y)
|
u8 CreatePokedexAreaMarkers(u16 species, u16 tilesTag, u8 palIdx, u8 y)
|
||||||
{
|
{
|
||||||
struct SpriteTemplate spriteTemplate;
|
struct SpriteTemplate spriteTemplate;
|
||||||
struct CompressedSpriteSheet spriteSheet;
|
struct CompressedSpriteSheet spriteSheet;
|
||||||
@@ -165,34 +196,42 @@ u8 Ctor_PokedexAreaMarkers(u16 species, u16 tilesTag, u8 palIdx, u8 y)
|
|||||||
struct PAM_TaskData * data;
|
struct PAM_TaskData * data;
|
||||||
struct Subsprite * subsprites;
|
struct Subsprite * subsprites;
|
||||||
|
|
||||||
|
// Load gfx
|
||||||
spriteSheet.data = sMarkerTiles;
|
spriteSheet.data = sMarkerTiles;
|
||||||
spriteSheet.size = 0x4A0;
|
spriteSheet.size = 0x4A0;
|
||||||
spriteSheet.tag = tilesTag;
|
spriteSheet.tag = tilesTag;
|
||||||
LoadCompressedSpriteSheet(&spriteSheet);
|
LoadCompressedSpriteSheet(&spriteSheet);
|
||||||
LoadPalette(sMarkerPal, 0x100 + 16 * palIdx, 0x20);
|
LoadPalette(sMarkerPal, 0x100 + 16 * palIdx, 0x20);
|
||||||
|
|
||||||
|
// Get marker subsprites
|
||||||
taskId = CreateTask(Task_ShowAreaMarkers, 0);
|
taskId = CreateTask(Task_ShowAreaMarkers, 0);
|
||||||
data = (void *)gTasks[taskId].data;
|
data = (void *)gTasks[taskId].data;
|
||||||
data->unk_0C = 0;
|
data->unused = 0;
|
||||||
data->tilesTag = tilesTag;
|
data->tilesTag = tilesTag;
|
||||||
data->unk_10 = 0xFFFF;
|
data->paletteTag = TAG_NONE;
|
||||||
subsprites = Alloc(120 * sizeof(struct Subsprite));
|
subsprites = Alloc(120 * sizeof(struct Subsprite));
|
||||||
data->buffer = subsprites;
|
data->buffer = subsprites;
|
||||||
data->subsprites.subsprites = subsprites;
|
data->subsprites.subsprites = subsprites;
|
||||||
data->subsprites.subspriteCount = BuildPokedexAreaSubspriteBuffer(species, subsprites);
|
data->subsprites.subspriteCount = GetSpeciesPokedexAreaMarkers(species, subsprites);
|
||||||
|
|
||||||
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON);
|
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON);
|
||||||
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG0 | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_BD);
|
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG0 | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_BD);
|
||||||
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(12, 8));
|
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(12, 8));
|
||||||
SetGpuReg(REG_OFFSET_BLDY, 0);
|
SetGpuReg(REG_OFFSET_BLDY, 0);
|
||||||
SetGpuReg(REG_OFFSET_WININ, 0x1F1F);
|
SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ);
|
||||||
SetGpuReg(REG_OFFSET_WINOUT, 0x2F3D);
|
SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG0 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_CLR);
|
||||||
|
|
||||||
|
// Set marker subsprites on full sprite
|
||||||
spriteTemplate = gDummySpriteTemplate;
|
spriteTemplate = gDummySpriteTemplate;
|
||||||
spriteTemplate.tileTag = tilesTag;
|
spriteTemplate.tileTag = tilesTag;
|
||||||
data->spr_id = CreateSprite(&spriteTemplate, 104, y + 32, 0);
|
data->spriteId = CreateSprite(&spriteTemplate, 104, y + 32, 0);
|
||||||
SetSubspriteTables(&gSprites[data->spr_id], &data->subsprites);
|
SetSubspriteTables(&gSprites[data->spriteId], &data->subsprites);
|
||||||
gSprites[data->spr_id].oam.objMode = ST_OAM_OBJ_WINDOW;
|
gSprites[data->spriteId].oam.objMode = ST_OAM_OBJ_WINDOW;
|
||||||
gSprites[data->spr_id].oam.paletteNum = palIdx;
|
gSprites[data->spriteId].oam.paletteNum = palIdx;
|
||||||
gSprites[data->spr_id].subspriteTableNum = 0;
|
gSprites[data->spriteId].subspriteTableNum = 0;
|
||||||
gSprites[data->spr_id].invisible = TRUE;
|
gSprites[data->spriteId].invisible = TRUE;
|
||||||
|
|
||||||
|
// Show markers
|
||||||
HideBg(1);
|
HideBg(1);
|
||||||
SetBgAttribute(1, BG_ATTR_CHARBASEINDEX, 0);
|
SetBgAttribute(1, BG_ATTR_CHARBASEINDEX, 0);
|
||||||
FillBgTilemapBufferRect_Palette0(1, 0x00F, 0, 0, 30, 20);
|
FillBgTilemapBufferRect_Palette0(1, 0x00F, 0, 0, 30, 20);
|
||||||
@@ -201,17 +240,17 @@ u8 Ctor_PokedexAreaMarkers(u16 species, u16 tilesTag, u8 palIdx, u8 y)
|
|||||||
return taskId;
|
return taskId;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dtor_PokedexAreaMarkers(u8 taskId)
|
void DestroyPokedexAreaMarkers(u8 taskId)
|
||||||
{
|
{
|
||||||
struct PAM_TaskData * data = (void *)gTasks[taskId].data;
|
struct PAM_TaskData * data = (void *)gTasks[taskId].data;
|
||||||
FreeSpriteTilesByTag(data->tilesTag);
|
FreeSpriteTilesByTag(data->tilesTag);
|
||||||
DestroySprite(&gSprites[data->spr_id]);
|
DestroySprite(&gSprites[data->spriteId]);
|
||||||
Free(data->buffer);
|
Free(data->buffer);
|
||||||
SetGpuReg(REG_OFFSET_BLDCNT, 0);
|
SetGpuReg(REG_OFFSET_BLDCNT, 0);
|
||||||
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
|
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
|
||||||
SetGpuReg(REG_OFFSET_BLDY, 0);
|
SetGpuReg(REG_OFFSET_BLDY, 0);
|
||||||
SetGpuReg(REG_OFFSET_WININ, 0x1F1F);
|
SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ);
|
||||||
SetGpuReg(REG_OFFSET_WINOUT, 0x1F1F);
|
SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ);
|
||||||
ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON);
|
ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON);
|
||||||
HideBg(1);
|
HideBg(1);
|
||||||
SetBgAttribute(1, BG_ATTR_CHARBASEINDEX, 2);
|
SetBgAttribute(1, BG_ATTR_CHARBASEINDEX, 2);
|
||||||
@@ -221,14 +260,14 @@ void Dtor_PokedexAreaMarkers(u8 taskId)
|
|||||||
DestroyTask(taskId);
|
DestroyTask(taskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetAreaSubsprite(s32 i, s32 whichArea, struct Subsprite * subsprites)
|
void GetAreaMarkerSubsprite(s32 i, s32 dexArea, struct Subsprite * subsprites)
|
||||||
{
|
{
|
||||||
subsprites[i] = *sSubsprites[sSubspriteLookupTable[whichArea][0]];
|
subsprites[i] = *sSubsprites[sAreaMarkers[dexArea][0]];
|
||||||
subsprites[i].x = sSubspriteLookupTable[whichArea][1];
|
subsprites[i].x = sAreaMarkers[dexArea][1];
|
||||||
subsprites[i].y = sSubspriteLookupTable[whichArea][2];
|
subsprites[i].y = sAreaMarkers[dexArea][2];
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 PokedexAreaMarkers_Any(u8 taskId)
|
u8 GetNumPokedexAreaMarkers(u8 taskId)
|
||||||
{
|
{
|
||||||
struct PAM_TaskData * data = (void *)gTasks[taskId].data;
|
struct PAM_TaskData * data = (void *)gTasks[taskId].data;
|
||||||
return data->subsprites.subspriteCount;
|
return data->subsprites.subspriteCount;
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
#include "pokedex_area_markers.h"
|
#include "pokedex_area_markers.h"
|
||||||
#include "field_specials.h"
|
#include "field_specials.h"
|
||||||
|
|
||||||
|
#define TAG_AREA_MARKERS 2001
|
||||||
|
|
||||||
enum TextMode {
|
enum TextMode {
|
||||||
TEXT_LEFT,
|
TEXT_LEFT,
|
||||||
TEXT_CENTER,
|
TEXT_CENTER,
|
||||||
@@ -31,7 +33,8 @@ struct PokedexScreenData
|
|||||||
{
|
{
|
||||||
u8 taskId;
|
u8 taskId;
|
||||||
u8 state;
|
u8 state;
|
||||||
u8 data[4];
|
u8 data[2];
|
||||||
|
u8 areaMarkersTaskId;
|
||||||
u32 unlockedCategories;
|
u32 unlockedCategories;
|
||||||
u32 modeSelectInput;
|
u32 modeSelectInput;
|
||||||
u16 modeSelectItemsAbove;
|
u16 modeSelectItemsAbove;
|
||||||
@@ -3123,9 +3126,10 @@ u8 DexScreen_DrawMonAreaPage(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the area markers
|
// Create the area markers
|
||||||
sPokedexScreenData->data[2] = Ctor_PokedexAreaMarkers(species, 2001, 3, kantoMapVoff * 8);
|
sPokedexScreenData->areaMarkersTaskId = CreatePokedexAreaMarkers(species, TAG_AREA_MARKERS, 3, kantoMapVoff * 8);
|
||||||
if (!(PokedexAreaMarkers_Any(sPokedexScreenData->data[2])))
|
if (GetNumPokedexAreaMarkers(sPokedexScreenData->areaMarkersTaskId) == 0)
|
||||||
{
|
{
|
||||||
|
// No markers, display "Area Unknown"
|
||||||
BlitBitmapRectToWindow(sPokedexScreenData->windowIds[0], (void *)sBlitTiles_WideEllipse, 0, 0, 88, 16, 4, 28, 88, 16);
|
BlitBitmapRectToWindow(sPokedexScreenData->windowIds[0], (void *)sBlitTiles_WideEllipse, 0, 0, 88, 16, 4, 28, 88, 16);
|
||||||
{
|
{
|
||||||
s32 strWidth = GetStringWidth(FONT_SMALL, gText_AreaUnknown, 0);
|
s32 strWidth = GetStringWidth(FONT_SMALL, gText_AreaUnknown, 0);
|
||||||
@@ -3149,7 +3153,7 @@ u8 DexScreen_DestroyAreaScreenResources(void)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
Dtor_PokedexAreaMarkers(sPokedexScreenData->data[2]);
|
DestroyPokedexAreaMarkers(sPokedexScreenData->areaMarkersTaskId);
|
||||||
|
|
||||||
for (i = 0; i < 13; i++)
|
for (i = 0; i < 13; i++)
|
||||||
DexScreen_RemoveWindow(&sPokedexScreenData->windowIds[i]);
|
DexScreen_RemoveWindow(&sPokedexScreenData->windowIds[i]);
|
||||||
|
|||||||
+2
-2
@@ -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); // mevent
|
|
||||||
|
|
||||||
#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;
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
#include "trade.h"
|
#include "trade.h"
|
||||||
#include "link.h"
|
#include "link.h"
|
||||||
#include "link_rfu.h"
|
#include "link_rfu.h"
|
||||||
#include "mevent.h"
|
#include "mystery_gift.h"
|
||||||
#include "graphics.h"
|
#include "graphics.h"
|
||||||
#include "strings.h"
|
#include "strings.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@
|
|||||||
#include "list_menu.h"
|
#include "list_menu.h"
|
||||||
#include "load_save.h"
|
#include "load_save.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "mevent.h"
|
#include "mystery_gift.h"
|
||||||
#include "mystery_gift_menu.h"
|
#include "mystery_gift_menu.h"
|
||||||
#include "new_menu_helpers.h"
|
#include "new_menu_helpers.h"
|
||||||
#include "overworld.h"
|
#include "overworld.h"
|
||||||
|
|||||||
+14
-13
@@ -1,6 +1,7 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "link_rfu.h"
|
#include "link_rfu.h"
|
||||||
#include "mevent_server.h"
|
#include "mystery_gift_server.h"
|
||||||
|
#include "mystery_gift_client.h"
|
||||||
#include "constants/union_room.h"
|
#include "constants/union_room.h"
|
||||||
|
|
||||||
ALIGNED(4) const u8 gText_UR_EmptyString[] = _("");
|
ALIGNED(4) const u8 gText_UR_EmptyString[] = _("");
|
||||||
@@ -558,18 +559,18 @@ const u8 *const gTexts_UR_GladToMeetYou[GENDER_COUNT] = {
|
|||||||
ALIGNED(4) const u8 gText_UR_FinishedCheckingPlayersTrainerCard[] = _("Finished checking {SPECIAL_F7 0x01}'s\nTRAINER CARD.{PAUSE 60}");
|
ALIGNED(4) const u8 gText_UR_FinishedCheckingPlayersTrainerCard[] = _("Finished checking {SPECIAL_F7 0x01}'s\nTRAINER CARD.{PAUSE 60}");
|
||||||
ALIGNED(4) static const u8 sText_CanceledReadingCard[] = _("Canceled reading the Card.");
|
ALIGNED(4) static const u8 sText_CanceledReadingCard[] = _("Canceled reading the Card.");
|
||||||
|
|
||||||
static const struct mevent_client_cmd sClientScript_DynamicError[] = {
|
static const struct MysteryGiftClientCmd sClientScript_DynamicError[] = {
|
||||||
CLI_RECEIVE(0x15),
|
{CLI_RECV, MG_LINKID_DYNAMIC_MSG},
|
||||||
CLI_RECVBUF,
|
{CLI_COPY_MSG},
|
||||||
CLI_SENDALL,
|
{CLI_SEND_READY_END},
|
||||||
CLI_RETURN(0x0e)
|
{CLI_RETURN, CLI_MSG_BUFFER_FAILURE}
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct mevent_server_cmd gServerScript_ClientCanceledCard[] = {
|
const struct MysteryGiftServerCmd gServerScript_ClientCanceledCard[] = {
|
||||||
SRV_SEND(0x20, sClientScript_DynamicError),
|
{SVR_LOAD_CLIENT_SCRIPT, PTR_ARG(sClientScript_DynamicError)},
|
||||||
SRV_WAITSND,
|
{SVR_SEND},
|
||||||
SRV_SENDSTR(0x1b, sText_CanceledReadingCard),
|
{SVR_LOAD_MSG, PTR_ARG(sText_CanceledReadingCard)},
|
||||||
SRV_WAITSND,
|
{SVR_SEND},
|
||||||
SRV_RECV(0x14),
|
{SVR_RECV, MG_LINKID_READY_END},
|
||||||
SRV_RETURN(0x09)
|
{SVR_RETURN, SVR_MSG_CLIENT_CANCELED}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ static u16 GetCurrentMapWildMonHeaderId(void)
|
|||||||
gSaveBlock1Ptr->location.mapNum == MAP_NUM(SIX_ISLAND_ALTERING_CAVE))
|
gSaveBlock1Ptr->location.mapNum == MAP_NUM(SIX_ISLAND_ALTERING_CAVE))
|
||||||
{
|
{
|
||||||
u16 alteringCaveId = VarGet(VAR_ALTERING_CAVE_WILD_SET);
|
u16 alteringCaveId = VarGet(VAR_ALTERING_CAVE_WILD_SET);
|
||||||
if (alteringCaveId > 8)
|
if (alteringCaveId >= NUM_ALTERING_CAVE_TABLES)
|
||||||
alteringCaveId = 0;
|
alteringCaveId = 0;
|
||||||
|
|
||||||
i += alteringCaveId;
|
i += alteringCaveId;
|
||||||
|
|||||||
+164
-154
@@ -4,16 +4,11 @@
|
|||||||
#include "wild_encounter.h"
|
#include "wild_encounter.h"
|
||||||
#include "roamer.h"
|
#include "roamer.h"
|
||||||
#include "overworld.h"
|
#include "overworld.h"
|
||||||
|
#include "pokedex.h"
|
||||||
#include "pokedex_area_markers.h"
|
#include "pokedex_area_markers.h"
|
||||||
#include "constants/region_map_sections.h"
|
#include "constants/region_map_sections.h"
|
||||||
#include "constants/maps.h"
|
#include "constants/maps.h"
|
||||||
|
|
||||||
struct SeviiDexArea
|
|
||||||
{
|
|
||||||
const u16 (*lut)[2];
|
|
||||||
s32 count;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RoamerPair
|
struct RoamerPair
|
||||||
{
|
{
|
||||||
u16 roamer;
|
u16 roamer;
|
||||||
@@ -21,137 +16,141 @@ struct RoamerPair
|
|||||||
};
|
};
|
||||||
|
|
||||||
static s32 GetRoamerIndex(u16 species);
|
static s32 GetRoamerIndex(u16 species);
|
||||||
static s32 CountRoamerNests(u16 species, struct Subsprite * subsprites);
|
static s32 GetRoamerPokedexAreaMarkers(u16 species, struct Subsprite * subsprites);
|
||||||
static bool32 PokemonInAnyEncounterTableInMap(const struct WildPokemonHeader * data, s32 species);
|
static bool32 IsSpeciesOnMap(const struct WildPokemonHeader * data, s32 species);
|
||||||
static bool32 PokemonInEncounterTable(const struct WildPokemonInfo * pokemon, s32 species, s32 count);
|
static bool32 IsSpeciesInEncounterTable(const struct WildPokemonInfo * pokemon, s32 species, s32 count);
|
||||||
static u16 GetMapSecIdFromWildMonHeader(const struct WildPokemonHeader * header);
|
static u16 GetMapSecIdFromWildMonHeader(const struct WildPokemonHeader * header);
|
||||||
static bool32 TryGetMapSecPokedexAreaEntry(u16 mapSecId, const u16 (*lut)[2], s32 count, s32 * lutIdx_p, u16 * tableIdx_p);
|
static bool32 FindDexAreaByMapSec(u16 mapSecId, const u16 (*lut)[2], s32 count, s32 * lutIdx_p, u16 * tableIdx_p);
|
||||||
|
|
||||||
static const u16 sDexAreas_Kanto[][2] = {
|
static const u16 sDexAreas_Kanto[][2] = {
|
||||||
{ MAPSEC_PALLET_TOWN, 1 },
|
{ MAPSEC_PALLET_TOWN, DEX_AREA_PALLET_TOWN },
|
||||||
{ MAPSEC_VIRIDIAN_CITY, 2 },
|
{ MAPSEC_VIRIDIAN_CITY, DEX_AREA_VIRIDIAN_CITY },
|
||||||
{ MAPSEC_PEWTER_CITY, 3 },
|
{ MAPSEC_PEWTER_CITY, DEX_AREA_PEWTER_CITY },
|
||||||
{ MAPSEC_CERULEAN_CITY, 4 },
|
{ MAPSEC_CERULEAN_CITY, DEX_AREA_CERULEAN_CITY },
|
||||||
{ MAPSEC_LAVENDER_TOWN, 5 },
|
{ MAPSEC_LAVENDER_TOWN, DEX_AREA_LAVENDER_TOWN },
|
||||||
{ MAPSEC_VERMILION_CITY, 6 },
|
{ MAPSEC_VERMILION_CITY, DEX_AREA_VERMILION_CITY },
|
||||||
{ MAPSEC_CELADON_CITY, 7 },
|
{ MAPSEC_CELADON_CITY, DEX_AREA_CELADON_CITY },
|
||||||
{ MAPSEC_FUCHSIA_CITY, 8 },
|
{ MAPSEC_FUCHSIA_CITY, DEX_AREA_FUCHSIA_CITY },
|
||||||
{ MAPSEC_CINNABAR_ISLAND, 9 },
|
{ MAPSEC_CINNABAR_ISLAND, DEX_AREA_CINNABAR_ISLAND },
|
||||||
{ MAPSEC_INDIGO_PLATEAU, 10 },
|
{ MAPSEC_INDIGO_PLATEAU, DEX_AREA_INDIGO_PLATEAU },
|
||||||
{ MAPSEC_SAFFRON_CITY, 11 },
|
{ MAPSEC_SAFFRON_CITY, DEX_AREA_SAFFRON_CITY },
|
||||||
{ MAPSEC_ROUTE_4_POKECENTER, 15 },
|
{ MAPSEC_ROUTE_4_POKECENTER, DEX_AREA_ROUTE_4 },
|
||||||
{ MAPSEC_ROUTE_10_POKECENTER, 21 },
|
{ MAPSEC_ROUTE_10_POKECENTER, DEX_AREA_ROUTE_10 },
|
||||||
{ MAPSEC_ROUTE_1, 12 },
|
{ MAPSEC_ROUTE_1, DEX_AREA_ROUTE_1 },
|
||||||
{ MAPSEC_ROUTE_2, 13 },
|
{ MAPSEC_ROUTE_2, DEX_AREA_ROUTE_2 },
|
||||||
{ MAPSEC_ROUTE_3, 14 },
|
{ MAPSEC_ROUTE_3, DEX_AREA_ROUTE_3 },
|
||||||
{ MAPSEC_ROUTE_4, 15 },
|
{ MAPSEC_ROUTE_4, DEX_AREA_ROUTE_4 },
|
||||||
{ MAPSEC_ROUTE_5, 16 },
|
{ MAPSEC_ROUTE_5, DEX_AREA_ROUTE_5 },
|
||||||
{ MAPSEC_ROUTE_6, 17 },
|
{ MAPSEC_ROUTE_6, DEX_AREA_ROUTE_6 },
|
||||||
{ MAPSEC_ROUTE_7, 18 },
|
{ MAPSEC_ROUTE_7, DEX_AREA_ROUTE_7 },
|
||||||
{ MAPSEC_ROUTE_8, 19 },
|
{ MAPSEC_ROUTE_8, DEX_AREA_ROUTE_8 },
|
||||||
{ MAPSEC_ROUTE_9, 20 },
|
{ MAPSEC_ROUTE_9, DEX_AREA_ROUTE_9 },
|
||||||
{ MAPSEC_ROUTE_10, 21 },
|
{ MAPSEC_ROUTE_10, DEX_AREA_ROUTE_10 },
|
||||||
{ MAPSEC_ROUTE_11, 22 },
|
{ MAPSEC_ROUTE_11, DEX_AREA_ROUTE_11 },
|
||||||
{ MAPSEC_ROUTE_12, 23 },
|
{ MAPSEC_ROUTE_12, DEX_AREA_ROUTE_12 },
|
||||||
{ MAPSEC_ROUTE_13, 24 },
|
{ MAPSEC_ROUTE_13, DEX_AREA_ROUTE_13 },
|
||||||
{ MAPSEC_ROUTE_14, 25 },
|
{ MAPSEC_ROUTE_14, DEX_AREA_ROUTE_14 },
|
||||||
{ MAPSEC_ROUTE_15, 26 },
|
{ MAPSEC_ROUTE_15, DEX_AREA_ROUTE_15 },
|
||||||
{ MAPSEC_ROUTE_16, 27 },
|
{ MAPSEC_ROUTE_16, DEX_AREA_ROUTE_16 },
|
||||||
{ MAPSEC_ROUTE_17, 28 },
|
{ MAPSEC_ROUTE_17, DEX_AREA_ROUTE_17 },
|
||||||
{ MAPSEC_ROUTE_18, 29 },
|
{ MAPSEC_ROUTE_18, DEX_AREA_ROUTE_18 },
|
||||||
{ MAPSEC_ROUTE_19, 30 },
|
{ MAPSEC_ROUTE_19, DEX_AREA_ROUTE_19 },
|
||||||
{ MAPSEC_ROUTE_20, 31 },
|
{ MAPSEC_ROUTE_20, DEX_AREA_ROUTE_20 },
|
||||||
{ MAPSEC_ROUTE_21, 32 },
|
{ MAPSEC_ROUTE_21, DEX_AREA_ROUTE_21 },
|
||||||
{ MAPSEC_ROUTE_22, 33 },
|
{ MAPSEC_ROUTE_22, DEX_AREA_ROUTE_22 },
|
||||||
{ MAPSEC_ROUTE_23, 34 },
|
{ MAPSEC_ROUTE_23, DEX_AREA_ROUTE_23 },
|
||||||
{ MAPSEC_ROUTE_24, 35 },
|
{ MAPSEC_ROUTE_24, DEX_AREA_ROUTE_24 },
|
||||||
{ MAPSEC_ROUTE_25, 36 },
|
{ MAPSEC_ROUTE_25, DEX_AREA_ROUTE_25 },
|
||||||
{ MAPSEC_VIRIDIAN_FOREST, 37 },
|
{ MAPSEC_VIRIDIAN_FOREST, DEX_AREA_VIRIDIAN_FOREST },
|
||||||
{ MAPSEC_MT_MOON, 39 },
|
{ MAPSEC_MT_MOON, DEX_AREA_MT_MOON },
|
||||||
{ MAPSEC_S_S_ANNE, 6 },
|
{ MAPSEC_S_S_ANNE, DEX_AREA_VERMILION_CITY },
|
||||||
{ MAPSEC_UNDERGROUND_PATH, 11 },
|
{ MAPSEC_UNDERGROUND_PATH, DEX_AREA_SAFFRON_CITY },
|
||||||
{ MAPSEC_UNDERGROUND_PATH_2, 11 },
|
{ MAPSEC_UNDERGROUND_PATH_2, DEX_AREA_SAFFRON_CITY },
|
||||||
{ MAPSEC_DIGLETTS_CAVE, 38 },
|
{ MAPSEC_DIGLETTS_CAVE, DEX_AREA_DIGLETTS_CAVE },
|
||||||
{ MAPSEC_KANTO_VICTORY_ROAD, 47 },
|
{ MAPSEC_KANTO_VICTORY_ROAD, DEX_AREA_VICTORY_ROAD },
|
||||||
{ MAPSEC_ROCKET_HIDEOUT, 7 },
|
{ MAPSEC_ROCKET_HIDEOUT, DEX_AREA_CELADON_CITY },
|
||||||
{ MAPSEC_SILPH_CO, 11 },
|
{ MAPSEC_SILPH_CO, DEX_AREA_SAFFRON_CITY },
|
||||||
{ MAPSEC_POKEMON_MANSION, 46 },
|
{ MAPSEC_POKEMON_MANSION, DEX_AREA_POKEMON_MANSION },
|
||||||
{ MAPSEC_KANTO_SAFARI_ZONE, 44 },
|
{ MAPSEC_KANTO_SAFARI_ZONE, DEX_AREA_SAFARI_ZONE },
|
||||||
{ MAPSEC_POKEMON_LEAGUE, 47 },
|
{ MAPSEC_POKEMON_LEAGUE, DEX_AREA_VICTORY_ROAD },
|
||||||
{ MAPSEC_ROCK_TUNNEL, 41 },
|
{ MAPSEC_ROCK_TUNNEL, DEX_AREA_ROCK_TUNNEL },
|
||||||
{ MAPSEC_SEAFOAM_ISLANDS, 45 },
|
{ MAPSEC_SEAFOAM_ISLANDS, DEX_AREA_SEAFOAM_ISLANDS },
|
||||||
{ MAPSEC_POKEMON_TOWER, 43 },
|
{ MAPSEC_POKEMON_TOWER, DEX_AREA_POKEMON_TOWER },
|
||||||
{ MAPSEC_CERULEAN_CAVE, 40 },
|
{ MAPSEC_CERULEAN_CAVE, DEX_AREA_CERULEAN_CAVE },
|
||||||
{ MAPSEC_POWER_PLANT, 42 }
|
{ MAPSEC_POWER_PLANT, DEX_AREA_POWER_PLANT }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u16 sDexAreas_Sevii1[][2] = {
|
static const u16 sDexAreas_Sevii1[][2] = {
|
||||||
{ MAPSEC_KINDLE_ROAD, 55 },
|
{ MAPSEC_KINDLE_ROAD, DEX_AREA_KINDLE_ROAD },
|
||||||
{ MAPSEC_TREASURE_BEACH, 56 },
|
{ MAPSEC_TREASURE_BEACH, DEX_AREA_TREASURE_BEACH },
|
||||||
{ MAPSEC_ONE_ISLAND, 48 },
|
{ MAPSEC_ONE_ISLAND, DEX_AREA_ONE_ISLAND },
|
||||||
{ MAPSEC_MT_EMBER, 72 }
|
{ MAPSEC_MT_EMBER, DEX_AREA_MT_EMBER }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u16 sDexAreas_Sevii2[][2] = {
|
static const u16 sDexAreas_Sevii2[][2] = {
|
||||||
{ MAPSEC_CAPE_BRINK, 57 },
|
{ MAPSEC_CAPE_BRINK, DEX_AREA_CAPE_BRINK },
|
||||||
{ MAPSEC_TWO_ISLAND, 49 }
|
{ MAPSEC_TWO_ISLAND, DEX_AREA_TWO_ISLAND }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u16 sDexAreas_Sevii3[][2] = {
|
static const u16 sDexAreas_Sevii3[][2] = {
|
||||||
{ MAPSEC_BOND_BRIDGE, 58 },
|
{ MAPSEC_BOND_BRIDGE, DEX_AREA_BOND_BRIDGE },
|
||||||
{ MAPSEC_THREE_ISLE_PORT, 59 },
|
{ MAPSEC_THREE_ISLE_PORT, DEX_AREA_THREE_ISLE_PATH },
|
||||||
{ MAPSEC_THREE_ISLAND, 50 },
|
{ MAPSEC_THREE_ISLAND, DEX_AREA_THREE_ISLAND },
|
||||||
{ MAPSEC_BERRY_FOREST, 73 },
|
{ MAPSEC_BERRY_FOREST, DEX_AREA_BERRY_FOREST },
|
||||||
{ MAPSEC_THREE_ISLE_PATH, 59 }
|
{ MAPSEC_THREE_ISLE_PATH, DEX_AREA_THREE_ISLE_PATH }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u16 sDexAreas_Sevii4[][2] = {
|
static const u16 sDexAreas_Sevii4[][2] = {
|
||||||
{ MAPSEC_FOUR_ISLAND, 51 },
|
{ MAPSEC_FOUR_ISLAND, DEX_AREA_FOUR_ISLAND },
|
||||||
{ MAPSEC_ICEFALL_CAVE, 74 }
|
{ MAPSEC_ICEFALL_CAVE, DEX_AREA_ICEFALL_CAVE }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u16 sDexAreas_Sevii5[][2] = {
|
static const u16 sDexAreas_Sevii5[][2] = {
|
||||||
{ MAPSEC_RESORT_GORGEOUS, 60 },
|
{ MAPSEC_RESORT_GORGEOUS, DEX_AREA_RESORT_GORGEOUS },
|
||||||
{ MAPSEC_WATER_LABYRINTH, 61 },
|
{ MAPSEC_WATER_LABYRINTH, DEX_AREA_WATER_LABYRINTH },
|
||||||
{ MAPSEC_FIVE_ISLE_MEADOW, 62 },
|
{ MAPSEC_FIVE_ISLE_MEADOW, DEX_AREA_FIVE_ISLE_MEADOW },
|
||||||
{ MAPSEC_MEMORIAL_PILLAR, 63 },
|
{ MAPSEC_MEMORIAL_PILLAR, DEX_AREA_MEMORIAL_PILLAR },
|
||||||
{ MAPSEC_FIVE_ISLAND, 52 },
|
{ MAPSEC_FIVE_ISLAND, DEX_AREA_FIVE_ISLAND },
|
||||||
{ MAPSEC_ROCKET_WAREHOUSE, 62 },
|
{ MAPSEC_ROCKET_WAREHOUSE, DEX_AREA_FIVE_ISLE_MEADOW },
|
||||||
{ MAPSEC_LOST_CAVE, 75 }
|
{ MAPSEC_LOST_CAVE, DEX_AREA_LOST_CAVE }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u16 sDexAreas_Sevii6[][2] = {
|
static const u16 sDexAreas_Sevii6[][2] = {
|
||||||
{ MAPSEC_OUTCAST_ISLAND, 64 },
|
{ MAPSEC_OUTCAST_ISLAND, DEX_AREA_OUTCAST_ISLAND },
|
||||||
{ MAPSEC_GREEN_PATH, 65 },
|
{ MAPSEC_GREEN_PATH, DEX_AREA_GREEN_PATH },
|
||||||
{ MAPSEC_WATER_PATH, 66 },
|
{ MAPSEC_WATER_PATH, DEX_AREA_WATER_PATH },
|
||||||
{ MAPSEC_RUIN_VALLEY, 67 },
|
{ MAPSEC_RUIN_VALLEY, DEX_AREA_RUIN_VALLEY },
|
||||||
{ MAPSEC_DOTTED_HOLE, 78 },
|
{ MAPSEC_DOTTED_HOLE, DEX_AREA_DOTTED_HOLE },
|
||||||
{ MAPSEC_PATTERN_BUSH, 77 },
|
{ MAPSEC_PATTERN_BUSH, DEX_AREA_PATTERN_BUSH },
|
||||||
{ MAPSEC_ALTERING_CAVE, 76 }
|
{ MAPSEC_ALTERING_CAVE, DEX_AREA_ALTERING_CAVE }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u16 sDexAreas_Sevii7[][2] = {
|
static const u16 sDexAreas_Sevii7[][2] = {
|
||||||
{ MAPSEC_TRAINER_TOWER, 68 },
|
{ MAPSEC_TRAINER_TOWER, DEX_AREA_TRAINER_TOWER },
|
||||||
{ MAPSEC_CANYON_ENTRANCE, 69 },
|
{ MAPSEC_CANYON_ENTRANCE, DEX_AREA_CANYON_ENTRANCE },
|
||||||
{ MAPSEC_SEVAULT_CANYON, 70 },
|
{ MAPSEC_SEVAULT_CANYON, DEX_AREA_SEVAULT_CANYON },
|
||||||
{ MAPSEC_TANOBY_RUINS, 71 },
|
{ MAPSEC_TANOBY_RUINS, DEX_AREA_TANOBY_RUINS },
|
||||||
{ MAPSEC_MONEAN_CHAMBER, 79 },
|
{ MAPSEC_MONEAN_CHAMBER, DEX_AREA_TANOBY_CHAMBER },
|
||||||
{ MAPSEC_LIPTOO_CHAMBER, 79 },
|
{ MAPSEC_LIPTOO_CHAMBER, DEX_AREA_TANOBY_CHAMBER },
|
||||||
{ MAPSEC_WEEPTH_CHAMBER, 79 },
|
{ MAPSEC_WEEPTH_CHAMBER, DEX_AREA_TANOBY_CHAMBER },
|
||||||
{ MAPSEC_DILFORD_CHAMBER, 79 },
|
{ MAPSEC_DILFORD_CHAMBER, DEX_AREA_TANOBY_CHAMBER },
|
||||||
{ MAPSEC_SCUFIB_CHAMBER, 79 },
|
{ MAPSEC_SCUFIB_CHAMBER, DEX_AREA_TANOBY_CHAMBER },
|
||||||
{ MAPSEC_RIXY_CHAMBER, 79 },
|
{ MAPSEC_RIXY_CHAMBER, DEX_AREA_TANOBY_CHAMBER },
|
||||||
{ MAPSEC_VIAPOIS_CHAMBER, 79 }
|
{ MAPSEC_VIAPOIS_CHAMBER, DEX_AREA_TANOBY_CHAMBER }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct SeviiDexArea sSeviiDexAreas[] = {
|
static const struct
|
||||||
{ sDexAreas_Sevii1, 4 },
|
{
|
||||||
{ sDexAreas_Sevii2, 2 },
|
const u16 (*table)[2];
|
||||||
{ sDexAreas_Sevii3, 5 },
|
s32 count;
|
||||||
{ sDexAreas_Sevii4, 2 },
|
} sSeviiDexAreas[] = {
|
||||||
{ sDexAreas_Sevii5, 7 },
|
{ sDexAreas_Sevii1, ARRAY_COUNT(sDexAreas_Sevii1) },
|
||||||
{ sDexAreas_Sevii6, 7 },
|
{ sDexAreas_Sevii2, ARRAY_COUNT(sDexAreas_Sevii2) },
|
||||||
{ sDexAreas_Sevii7, 11 }
|
{ sDexAreas_Sevii3, ARRAY_COUNT(sDexAreas_Sevii3) },
|
||||||
|
{ sDexAreas_Sevii4, ARRAY_COUNT(sDexAreas_Sevii4) },
|
||||||
|
{ sDexAreas_Sevii5, ARRAY_COUNT(sDexAreas_Sevii5) },
|
||||||
|
{ sDexAreas_Sevii6, ARRAY_COUNT(sDexAreas_Sevii6) },
|
||||||
|
{ sDexAreas_Sevii7, ARRAY_COUNT(sDexAreas_Sevii7) }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct RoamerPair sRoamerPairs[] = {
|
static const struct RoamerPair sRoamerPairs[] = {
|
||||||
@@ -160,27 +159,27 @@ static const struct RoamerPair sRoamerPairs[] = {
|
|||||||
{ SPECIES_RAIKOU, SPECIES_SQUIRTLE }
|
{ SPECIES_RAIKOU, SPECIES_SQUIRTLE }
|
||||||
};
|
};
|
||||||
|
|
||||||
s32 BuildPokedexAreaSubspriteBuffer(u16 species, struct Subsprite * subsprites)
|
// Scans for the given species and populates 'subsprites' with the area markers.
|
||||||
|
// Returns the number of areas where the species was found.
|
||||||
|
s32 GetSpeciesPokedexAreaMarkers(u16 species, struct Subsprite * subsprites)
|
||||||
{
|
{
|
||||||
s32 areaCount;
|
s32 areaCount;
|
||||||
s32 j;
|
s32 j;
|
||||||
s32 mapSecId;
|
s32 mapSecId;
|
||||||
u16 dexAreaSubspriteIdx;
|
u16 dexArea;
|
||||||
s32 dexAreaEntryLUTidx;
|
s32 tableIndex;
|
||||||
s32 seviiAreas;
|
s32 seviiAreas;
|
||||||
s32 alteringCaveCount;
|
s32 alteringCaveCount;
|
||||||
s32 alteringCaveNum;
|
s32 alteringCaveNum;
|
||||||
s32 i;
|
s32 i;
|
||||||
|
|
||||||
if (GetRoamerIndex(species) >= SPECIES_NONE)
|
if (GetRoamerIndex(species) >= 0)
|
||||||
{
|
return GetRoamerPokedexAreaMarkers(species, subsprites);
|
||||||
return CountRoamerNests(species, subsprites);
|
|
||||||
}
|
|
||||||
|
|
||||||
seviiAreas = GetUnlockedSeviiAreas();
|
seviiAreas = GetUnlockedSeviiAreas();
|
||||||
alteringCaveCount = 0;
|
alteringCaveCount = 0;
|
||||||
alteringCaveNum = VarGet(VAR_ALTERING_CAVE_WILD_SET);
|
alteringCaveNum = VarGet(VAR_ALTERING_CAVE_WILD_SET);
|
||||||
if (alteringCaveNum > 8)
|
if (alteringCaveNum >= NUM_ALTERING_CAVE_TABLES)
|
||||||
alteringCaveNum = 0;
|
alteringCaveNum = 0;
|
||||||
for (i = 0, areaCount = 0; gWildMonHeaders[i].mapGroup != MAP_GROUP(UNDEFINED); i++)
|
for (i = 0, areaCount = 0; gWildMonHeaders[i].mapGroup != MAP_GROUP(UNDEFINED); i++)
|
||||||
{
|
{
|
||||||
@@ -191,27 +190,27 @@ s32 BuildPokedexAreaSubspriteBuffer(u16 species, struct Subsprite * subsprites)
|
|||||||
if (alteringCaveNum != alteringCaveCount - 1)
|
if (alteringCaveNum != alteringCaveCount - 1)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (PokemonInAnyEncounterTableInMap(&gWildMonHeaders[i], species))
|
if (IsSpeciesOnMap(&gWildMonHeaders[i], species))
|
||||||
{
|
{
|
||||||
dexAreaEntryLUTidx = 0;
|
// Search for all dex areas associated with this MAPSEC.
|
||||||
while (TryGetMapSecPokedexAreaEntry(mapSecId, sDexAreas_Kanto, 55, &dexAreaEntryLUTidx, &dexAreaSubspriteIdx))
|
// In the vanilla game each MAPSEC only has at most one DEX_AREA.
|
||||||
|
tableIndex = 0;
|
||||||
|
while (FindDexAreaByMapSec(mapSecId, sDexAreas_Kanto, ARRAY_COUNT(sDexAreas_Kanto), &tableIndex, &dexArea))
|
||||||
{
|
{
|
||||||
if (dexAreaSubspriteIdx != 0)
|
if (dexArea != DEX_AREA_NONE)
|
||||||
{
|
GetAreaMarkerSubsprite(areaCount++, dexArea, subsprites);
|
||||||
SetAreaSubsprite(areaCount++, dexAreaSubspriteIdx, subsprites);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (j = 0; j < NELEMS(sSeviiDexAreas); j++)
|
|
||||||
|
for (j = 0; j < ARRAY_COUNT(sSeviiDexAreas); j++)
|
||||||
{
|
{
|
||||||
if ((seviiAreas >> j) & 1)
|
if ((seviiAreas >> j) & 1)
|
||||||
{
|
{
|
||||||
dexAreaEntryLUTidx = 0;
|
// Search for all dex areas associated with this MAPSEC in this unlocked Sevii Island
|
||||||
while (TryGetMapSecPokedexAreaEntry(mapSecId, sSeviiDexAreas[j].lut, sSeviiDexAreas[j].count, &dexAreaEntryLUTidx, &dexAreaSubspriteIdx))
|
tableIndex = 0;
|
||||||
|
while (FindDexAreaByMapSec(mapSecId, sSeviiDexAreas[j].table, sSeviiDexAreas[j].count, &tableIndex, &dexArea))
|
||||||
{
|
{
|
||||||
if (dexAreaSubspriteIdx != 0)
|
if (dexArea != DEX_AREA_NONE)
|
||||||
{
|
GetAreaMarkerSubsprite(areaCount++, dexArea, subsprites);
|
||||||
SetAreaSubsprite(areaCount++, dexAreaSubspriteIdx, subsprites);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -224,7 +223,7 @@ s32 BuildPokedexAreaSubspriteBuffer(u16 species, struct Subsprite * subsprites)
|
|||||||
static s32 GetRoamerIndex(u16 species)
|
static s32 GetRoamerIndex(u16 species)
|
||||||
{
|
{
|
||||||
s32 i;
|
s32 i;
|
||||||
for (i = 0; i < NELEMS(sRoamerPairs); i++)
|
for (i = 0; i < ARRAY_COUNT(sRoamerPairs); i++)
|
||||||
{
|
{
|
||||||
if (sRoamerPairs[i].roamer == species)
|
if (sRoamerPairs[i].roamer == species)
|
||||||
return i;
|
return i;
|
||||||
@@ -233,46 +232,54 @@ static s32 GetRoamerIndex(u16 species)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static s32 CountRoamerNests(u16 species, struct Subsprite * subsprites)
|
static s32 GetRoamerPokedexAreaMarkers(u16 species, struct Subsprite * subsprites)
|
||||||
{
|
{
|
||||||
u16 roamerLocation;
|
u16 mapSecId;
|
||||||
s32 roamerIdx;
|
s32 roamerIdx;
|
||||||
u16 dexAreaSubspriteIdx;
|
u16 dexArea;
|
||||||
s32 dexAreaEntryLUTidx;
|
s32 tableIndex;
|
||||||
|
|
||||||
|
// Make sure that this is a roamer species, and that it corresponds to the player's starter.
|
||||||
roamerIdx = GetRoamerIndex(species);
|
roamerIdx = GetRoamerIndex(species);
|
||||||
if (roamerIdx < 0)
|
if (roamerIdx < 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (sRoamerPairs[roamerIdx].starter != GetStarterSpecies())
|
if (sRoamerPairs[roamerIdx].starter != GetStarterSpecies())
|
||||||
return 0;
|
return 0;
|
||||||
roamerLocation = GetRoamerLocationMapSectionId();
|
|
||||||
dexAreaEntryLUTidx = 0;
|
mapSecId = GetRoamerLocationMapSectionId();
|
||||||
if (TryGetMapSecPokedexAreaEntry(roamerLocation, sDexAreas_Kanto, 55, &dexAreaEntryLUTidx, &dexAreaSubspriteIdx))
|
tableIndex = 0;
|
||||||
|
if (FindDexAreaByMapSec(mapSecId, sDexAreas_Kanto, ARRAY_COUNT(sDexAreas_Kanto), &tableIndex, &dexArea))
|
||||||
{
|
{
|
||||||
if (dexAreaSubspriteIdx != 0)
|
if (dexArea != DEX_AREA_NONE)
|
||||||
{
|
{
|
||||||
SetAreaSubsprite(0, dexAreaSubspriteIdx, subsprites);
|
GetAreaMarkerSubsprite(0, dexArea, subsprites);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool32 PokemonInAnyEncounterTableInMap(const struct WildPokemonHeader * data, s32 species)
|
static bool32 IsSpeciesOnMap(const struct WildPokemonHeader * data, s32 species)
|
||||||
{
|
{
|
||||||
if (PokemonInEncounterTable(data->landMonsInfo, species, 12))
|
if (IsSpeciesInEncounterTable(data->landMonsInfo, species, LAND_WILD_COUNT))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
if (PokemonInEncounterTable(data->waterMonsInfo, species, 5))
|
if (IsSpeciesInEncounterTable(data->waterMonsInfo, species, WATER_WILD_COUNT))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
if (PokemonInEncounterTable(data->fishingMonsInfo, species, 12)) // 10
|
// When searching the fishing encounters, this incorrectly uses the size of the land encounters.
|
||||||
|
// As a result it's reading out of bounds of the fishing encounters tables.
|
||||||
|
#ifdef BUGFIX
|
||||||
|
if (IsSpeciesInEncounterTable(data->fishingMonsInfo, species, FISH_WILD_COUNT))
|
||||||
|
#else
|
||||||
|
if (IsSpeciesInEncounterTable(data->fishingMonsInfo, species, LAND_WILD_COUNT))
|
||||||
|
#endif
|
||||||
return TRUE;
|
return TRUE;
|
||||||
if (PokemonInEncounterTable(data->rockSmashMonsInfo, species, 5))
|
if (IsSpeciesInEncounterTable(data->rockSmashMonsInfo, species, ROCK_WILD_COUNT))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool32 PokemonInEncounterTable(const struct WildPokemonInfo * info, s32 species, s32 count)
|
static bool32 IsSpeciesInEncounterTable(const struct WildPokemonInfo * info, s32 species, s32 count)
|
||||||
{
|
{
|
||||||
s32 i;
|
s32 i;
|
||||||
if (info != NULL)
|
if (info != NULL)
|
||||||
@@ -291,15 +298,18 @@ static u16 GetMapSecIdFromWildMonHeader(const struct WildPokemonHeader * header)
|
|||||||
return Overworld_GetMapHeaderByGroupAndId(header->mapGroup, header->mapNum)->regionMapSectionId;
|
return Overworld_GetMapHeaderByGroupAndId(header->mapGroup, header->mapNum)->regionMapSectionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool32 TryGetMapSecPokedexAreaEntry(u16 mapSecId, const u16 (*lut)[2], s32 count, s32 * lutIdx_p, u16 * tableIdx_p)
|
// Search a MAPSEC -> DEX_AREA table for the given mapsec.
|
||||||
|
// Assigns the DEX_AREA (if found) to 'dexArea', and the first unread table index to 'index'.
|
||||||
|
// Returns TRUE if DEX_AREA was found, FALSE otherwise.
|
||||||
|
static bool32 FindDexAreaByMapSec(u16 mapSecId, const u16 (*table)[2], s32 count, s32 * index, u16 * dexArea)
|
||||||
{
|
{
|
||||||
s32 i;
|
s32 i;
|
||||||
for (i = *lutIdx_p; i < count; i++)
|
for (i = *index; i < count; i++)
|
||||||
{
|
{
|
||||||
if (lut[i][0] == mapSecId)
|
if (table[i][0] == mapSecId)
|
||||||
{
|
{
|
||||||
*tableIdx_p = lut[i][1];
|
*dexArea = table[i][1];
|
||||||
*lutIdx_p = i + 1;
|
*index = i + 1;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,154 @@
|
|||||||
|
#include "global.h"
|
||||||
|
#include "mystery_gift.h"
|
||||||
|
#include "random.h"
|
||||||
|
#include "event_data.h"
|
||||||
|
#include "wonder_news.h"
|
||||||
|
#include "constants/items.h"
|
||||||
|
|
||||||
|
// Every 4th reward for sending Wonder News to a link partner is a "big" reward.
|
||||||
|
#define MAX_SENT_REWARD 4
|
||||||
|
|
||||||
|
// Only up to 5 rewards can be received in a short period. After this the player
|
||||||
|
// must take 500 steps before any more rewards can be received.
|
||||||
|
#define MAX_REWARD 5
|
||||||
|
|
||||||
|
static u32 GetRewardItem(struct WonderNewsMetadata *);
|
||||||
|
static u32 GetRewardType(struct WonderNewsMetadata *);
|
||||||
|
static void IncrementRewardCounter(struct WonderNewsMetadata *);
|
||||||
|
static void IncrementSentRewardCounter(struct WonderNewsMetadata *);
|
||||||
|
static void ResetSentRewardCounter(struct WonderNewsMetadata *);
|
||||||
|
|
||||||
|
void WonderNews_SetReward(u32 newsType)
|
||||||
|
{
|
||||||
|
struct WonderNewsMetadata *data = GetSavedWonderNewsMetadata();
|
||||||
|
|
||||||
|
data->newsType = newsType;
|
||||||
|
switch (newsType)
|
||||||
|
{
|
||||||
|
case WONDER_NEWS_NONE:
|
||||||
|
break;
|
||||||
|
case WONDER_NEWS_RECV_FRIEND:
|
||||||
|
case WONDER_NEWS_RECV_WIRELESS:
|
||||||
|
// Random berry between ITEM_RAZZ_BERRY and ITEM_NOMEL_BERRY
|
||||||
|
data->berry = (Random() % 15) + ITEM_TO_BERRY(ITEM_RAZZ_BERRY);
|
||||||
|
break;
|
||||||
|
case WONDER_NEWS_SENT:
|
||||||
|
// Random berry between ITEM_CHERI_BERRY and ITEM_IAPAPA_BERRY
|
||||||
|
data->berry = (Random() % 15) + ITEM_TO_BERRY(ITEM_CHERI_BERRY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WonderNews_Reset(void)
|
||||||
|
{
|
||||||
|
struct WonderNewsMetadata *data = GetSavedWonderNewsMetadata();
|
||||||
|
|
||||||
|
data->newsType = WONDER_NEWS_NONE;
|
||||||
|
data->sentRewardCounter = 0;
|
||||||
|
data->rewardCounter = 0;
|
||||||
|
data->berry = 0;
|
||||||
|
VarSet(VAR_WONDER_NEWS_STEP_COUNTER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WonderNews_IncrementStepCounter(void)
|
||||||
|
{
|
||||||
|
u16 *stepCounter = GetVarPointer(VAR_WONDER_NEWS_STEP_COUNTER);
|
||||||
|
struct WonderNewsMetadata *data = GetSavedWonderNewsMetadata();
|
||||||
|
|
||||||
|
// If the player has reached the reward limit, start counting steps.
|
||||||
|
// When they reach 500 steps reset the reward counter to allow them to
|
||||||
|
// receive rewards again.
|
||||||
|
if (data->rewardCounter >= MAX_REWARD && ++(*stepCounter) >= 500)
|
||||||
|
{
|
||||||
|
data->rewardCounter = 0;
|
||||||
|
*stepCounter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 WonderNews_GetRewardInfo(void)
|
||||||
|
{
|
||||||
|
u16 *result = &gSpecialVar_Result;
|
||||||
|
struct WonderNewsMetadata *data = GetSavedWonderNewsMetadata();
|
||||||
|
u16 rewardType;
|
||||||
|
|
||||||
|
if (!IsMysteryGiftEnabled() || !ValidateSavedWonderNews())
|
||||||
|
return NEWS_REWARD_NONE;
|
||||||
|
|
||||||
|
rewardType = GetRewardType(data);
|
||||||
|
|
||||||
|
switch (rewardType)
|
||||||
|
{
|
||||||
|
case NEWS_REWARD_RECV_SMALL:
|
||||||
|
case NEWS_REWARD_RECV_BIG:
|
||||||
|
*result = GetRewardItem(data);
|
||||||
|
break;
|
||||||
|
case NEWS_REWARD_SENT_SMALL:
|
||||||
|
*result = GetRewardItem(data);
|
||||||
|
IncrementSentRewardCounter(data);
|
||||||
|
break;
|
||||||
|
case NEWS_REWARD_SENT_BIG:
|
||||||
|
*result = GetRewardItem(data);
|
||||||
|
ResetSentRewardCounter(data);
|
||||||
|
break;
|
||||||
|
case NEWS_REWARD_NONE:
|
||||||
|
case NEWS_REWARD_WAITING:
|
||||||
|
case NEWS_REWARD_AT_MAX:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rewardType;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 GetRewardItem(struct WonderNewsMetadata *data)
|
||||||
|
{
|
||||||
|
u32 itemId;
|
||||||
|
|
||||||
|
data->newsType = WONDER_NEWS_NONE;
|
||||||
|
itemId = data->berry + FIRST_BERRY_INDEX - 1;
|
||||||
|
data->berry = 0;
|
||||||
|
IncrementRewardCounter(data);
|
||||||
|
return itemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ResetSentRewardCounter(struct WonderNewsMetadata *data)
|
||||||
|
{
|
||||||
|
data->sentRewardCounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Track number of times a reward was received (or attmepted to receive) for sending Wonder News to a link partner.
|
||||||
|
static void IncrementSentRewardCounter(struct WonderNewsMetadata *data)
|
||||||
|
{
|
||||||
|
data->sentRewardCounter++;
|
||||||
|
if (data->sentRewardCounter > MAX_SENT_REWARD)
|
||||||
|
data->sentRewardCounter = MAX_SENT_REWARD;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void IncrementRewardCounter(struct WonderNewsMetadata *data)
|
||||||
|
{
|
||||||
|
data->rewardCounter++;
|
||||||
|
if (data->rewardCounter > MAX_REWARD)
|
||||||
|
data->rewardCounter = MAX_REWARD;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 GetRewardType(struct WonderNewsMetadata *data)
|
||||||
|
{
|
||||||
|
if (data->rewardCounter == MAX_REWARD)
|
||||||
|
return NEWS_REWARD_AT_MAX;
|
||||||
|
|
||||||
|
switch (data->newsType)
|
||||||
|
{
|
||||||
|
case WONDER_NEWS_NONE:
|
||||||
|
return NEWS_REWARD_WAITING;
|
||||||
|
case WONDER_NEWS_RECV_FRIEND:
|
||||||
|
return NEWS_REWARD_RECV_SMALL;
|
||||||
|
case WONDER_NEWS_RECV_WIRELESS:
|
||||||
|
return NEWS_REWARD_RECV_BIG;
|
||||||
|
case WONDER_NEWS_SENT:
|
||||||
|
if (data->sentRewardCounter < MAX_SENT_REWARD - 1)
|
||||||
|
return NEWS_REWARD_SENT_SMALL;
|
||||||
|
return NEWS_REWARD_SENT_BIG;
|
||||||
|
default:
|
||||||
|
AGB_ASSERT_EX(0, ABSPATH("menews_jisan.c"), 383);
|
||||||
|
return NEWS_REWARD_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -40,7 +40,7 @@
|
|||||||
.include "fame_checker.o"
|
.include "fame_checker.o"
|
||||||
.include "help_system_util.o"
|
.include "help_system_util.o"
|
||||||
.align 4
|
.align 4
|
||||||
.include "mevent.o"
|
.include "ereader_screen.o"
|
||||||
.align 4
|
.align 4
|
||||||
.include "battle_controller_pokedude.o"
|
.include "battle_controller_pokedude.o"
|
||||||
.align 4
|
.align 4
|
||||||
|
|||||||
+4
-4
@@ -121,10 +121,10 @@
|
|||||||
.include "src/slot_machine.o"
|
.include "src/slot_machine.o"
|
||||||
.include "src/roamer.o"
|
.include "src/roamer.o"
|
||||||
.include "src/mystery_gift_menu.o"
|
.include "src/mystery_gift_menu.o"
|
||||||
.include "src/mevent.o"
|
.include "src/mystery_gift.o"
|
||||||
.include "src/mevent_server_helpers.o"
|
.include "src/mystery_gift_link.o"
|
||||||
.include "src/mevent_client.o"
|
.include "src/mystery_gift_client.o"
|
||||||
.include "src/mevent_server.o"
|
.include "src/mystery_gift_server.o"
|
||||||
.include "src/mystery_gift_show_card.o"
|
.include "src/mystery_gift_show_card.o"
|
||||||
.include "src/mystery_gift_show_news.o"
|
.include "src/mystery_gift_show_news.o"
|
||||||
.include "src/seagallop.o"
|
.include "src/seagallop.o"
|
||||||
|
|||||||
Reference in New Issue
Block a user