Merge branch 'master' into doc-miscbattle

This commit is contained in:
GriffinR
2021-10-15 22:46:43 -04:00
committed by GitHub
46 changed files with 2863 additions and 2829 deletions

View File

@@ -789,7 +789,7 @@ static void Task_HandleSendLinkBuffersData(u8 taskId)
gTasks[taskId].data[15] = 0;
}
blockSize = (gLinkBattleSendBuffer[gTasks[taskId].data[15] + LINK_BUFF_SIZE_LO] | (gLinkBattleSendBuffer[gTasks[taskId].data[15] + LINK_BUFF_SIZE_HI] << 8)) + LINK_BUFF_DATA;
SendBlock(bitmask_all_link_players_but_self(), &gLinkBattleSendBuffer[gTasks[taskId].data[15]], blockSize);
SendBlock(BitmaskAllOtherLinkPlayers(), &gLinkBattleSendBuffer[gTasks[taskId].data[15]], blockSize);
gTasks[taskId].data[11]++;
}
else

View File

@@ -984,7 +984,7 @@ static void CB2_HandleStartBattle(void)
gLinkPlayers[1].id = 1;
}
SendBlock(bitmask_all_link_players_but_self(), &gBattleStruct->multiBuffer.linkBattlerHeader, sizeof(gBattleStruct->multiBuffer.linkBattlerHeader));
SendBlock(BitmaskAllOtherLinkPlayers(), &gBattleStruct->multiBuffer.linkBattlerHeader, sizeof(gBattleStruct->multiBuffer.linkBattlerHeader));
gBattleCommunication[MULTIUSE_STATE] = 2;
}
if (gWirelessCommType)
@@ -1024,7 +1024,7 @@ static void CB2_HandleStartBattle(void)
if (IsLinkTaskFinished())
{
// Send Pokémon 1-2
SendBlock(bitmask_all_link_players_but_self(), gPlayerParty, sizeof(struct Pokemon) * 2);
SendBlock(BitmaskAllOtherLinkPlayers(), gPlayerParty, sizeof(struct Pokemon) * 2);
gBattleCommunication[MULTIUSE_STATE]++;
}
break;
@@ -1041,7 +1041,7 @@ static void CB2_HandleStartBattle(void)
if (IsLinkTaskFinished())
{
// Send Pokémon 3-4
SendBlock(bitmask_all_link_players_but_self(), &gPlayerParty[2], sizeof(struct Pokemon) * 2);
SendBlock(BitmaskAllOtherLinkPlayers(), &gPlayerParty[2], sizeof(struct Pokemon) * 2);
gBattleCommunication[MULTIUSE_STATE]++;
}
break;
@@ -1058,7 +1058,7 @@ static void CB2_HandleStartBattle(void)
if (IsLinkTaskFinished())
{
// Send Pokémon 5-6
SendBlock(bitmask_all_link_players_but_self(), &gPlayerParty[4], sizeof(struct Pokemon) * 2);
SendBlock(BitmaskAllOtherLinkPlayers(), &gPlayerParty[4], sizeof(struct Pokemon) * 2);
gBattleCommunication[MULTIUSE_STATE]++;
}
break;
@@ -1105,7 +1105,7 @@ static void CB2_HandleStartBattle(void)
// Both players are using Emerald, send rng seed for recorded battle
if (IsLinkTaskFinished())
{
SendBlock(bitmask_all_link_players_but_self(), &gRecordedBattleRngSeed, sizeof(gRecordedBattleRngSeed));
SendBlock(BitmaskAllOtherLinkPlayers(), &gRecordedBattleRngSeed, sizeof(gRecordedBattleRngSeed));
gBattleCommunication[MULTIUSE_STATE]++;
}
break;
@@ -1198,7 +1198,7 @@ static void CB2_HandleStartMultiPartnerBattle(void)
*(&gBattleStruct->multiBuffer.linkBattlerHeader.versionSignatureHi) = 3;
BufferPartyVsScreenHealth_AtStart();
SetPlayerBerryDataInBattleStruct();
SendBlock(bitmask_all_link_players_but_self(), &gBattleStruct->multiBuffer.linkBattlerHeader, sizeof(gBattleStruct->multiBuffer.linkBattlerHeader));
SendBlock(BitmaskAllOtherLinkPlayers(), &gBattleStruct->multiBuffer.linkBattlerHeader, sizeof(gBattleStruct->multiBuffer.linkBattlerHeader));
gBattleCommunication[MULTIUSE_STATE] = 2;
}
@@ -1236,7 +1236,7 @@ static void CB2_HandleStartMultiPartnerBattle(void)
if (IsLinkTaskFinished())
{
// Send Pokémon 1-2
SendBlock(bitmask_all_link_players_but_self(), gPlayerParty, sizeof(struct Pokemon) * 2);
SendBlock(BitmaskAllOtherLinkPlayers(), gPlayerParty, sizeof(struct Pokemon) * 2);
gBattleCommunication[MULTIUSE_STATE]++;
}
break;
@@ -1262,7 +1262,7 @@ static void CB2_HandleStartMultiPartnerBattle(void)
if (IsLinkTaskFinished())
{
// Send Pokémon 3
SendBlock(bitmask_all_link_players_but_self(), &gPlayerParty[2], sizeof(struct Pokemon));
SendBlock(BitmaskAllOtherLinkPlayers(), &gPlayerParty[2], sizeof(struct Pokemon));
gBattleCommunication[MULTIUSE_STATE]++;
}
break;
@@ -1288,7 +1288,7 @@ static void CB2_HandleStartMultiPartnerBattle(void)
if (IsLinkTaskFinished())
{
// Send enemy Pokémon 1-2 to partner
SendBlock(bitmask_all_link_players_but_self(), gEnemyParty, sizeof(struct Pokemon) * 2);
SendBlock(BitmaskAllOtherLinkPlayers(), gEnemyParty, sizeof(struct Pokemon) * 2);
gBattleCommunication[MULTIUSE_STATE]++;
}
break;
@@ -1306,7 +1306,7 @@ static void CB2_HandleStartMultiPartnerBattle(void)
if (IsLinkTaskFinished())
{
// Send enemy Pokémon 3-4 to partner
SendBlock(bitmask_all_link_players_but_self(), &gEnemyParty[2], sizeof(struct Pokemon) * 2);
SendBlock(BitmaskAllOtherLinkPlayers(), &gEnemyParty[2], sizeof(struct Pokemon) * 2);
gBattleCommunication[MULTIUSE_STATE]++;
}
break;
@@ -1324,7 +1324,7 @@ static void CB2_HandleStartMultiPartnerBattle(void)
if (IsLinkTaskFinished())
{
// Send enemy Pokémon 5-6 to partner
SendBlock(bitmask_all_link_players_but_self(), &gEnemyParty[4], sizeof(struct Pokemon) * 2);
SendBlock(BitmaskAllOtherLinkPlayers(), &gEnemyParty[4], sizeof(struct Pokemon) * 2);
gBattleCommunication[MULTIUSE_STATE]++;
}
break;
@@ -1365,7 +1365,7 @@ static void CB2_HandleStartMultiPartnerBattle(void)
// Send rng seed for recorded battle
if (IsLinkTaskFinished())
{
SendBlock(bitmask_all_link_players_but_self(), &gRecordedBattleRngSeed, sizeof(gRecordedBattleRngSeed));
SendBlock(BitmaskAllOtherLinkPlayers(), &gRecordedBattleRngSeed, sizeof(gRecordedBattleRngSeed));
gBattleCommunication[MULTIUSE_STATE]++;
}
break;
@@ -1447,7 +1447,7 @@ static void CB2_PreInitMultiBattle(void)
{
sMultiPartnerPartyBuffer = Alloc(sizeof(gMultiPartnerParty));
SetMultiPartnerMenuParty(0);
SendBlock(bitmask_all_link_players_but_self(), sMultiPartnerPartyBuffer, sizeof(gMultiPartnerParty));
SendBlock(BitmaskAllOtherLinkPlayers(), sMultiPartnerPartyBuffer, sizeof(gMultiPartnerParty));
gBattleCommunication[MULTIUSE_STATE]++;
}
break;
@@ -1592,7 +1592,7 @@ static void CB2_HandleStartMultiBattle(void)
BufferPartyVsScreenHealth_AtStart();
SetPlayerBerryDataInBattleStruct();
SendBlock(bitmask_all_link_players_but_self(), &gBattleStruct->multiBuffer.linkBattlerHeader, sizeof(gBattleStruct->multiBuffer.linkBattlerHeader));
SendBlock(BitmaskAllOtherLinkPlayers(), &gBattleStruct->multiBuffer.linkBattlerHeader, sizeof(gBattleStruct->multiBuffer.linkBattlerHeader));
gBattleCommunication[MULTIUSE_STATE]++;
}
if (gWirelessCommType)
@@ -1649,7 +1649,7 @@ static void CB2_HandleStartMultiBattle(void)
case 3:
if (IsLinkTaskFinished())
{
SendBlock(bitmask_all_link_players_but_self(), gPlayerParty, sizeof(struct Pokemon) * 2);
SendBlock(BitmaskAllOtherLinkPlayers(), gPlayerParty, sizeof(struct Pokemon) * 2);
gBattleCommunication[MULTIUSE_STATE]++;
}
break;
@@ -1712,7 +1712,7 @@ static void CB2_HandleStartMultiBattle(void)
case 5:
if (IsLinkTaskFinished())
{
SendBlock(bitmask_all_link_players_but_self(), gPlayerParty + 2, sizeof(struct Pokemon));
SendBlock(BitmaskAllOtherLinkPlayers(), gPlayerParty + 2, sizeof(struct Pokemon));
gBattleCommunication[MULTIUSE_STATE]++;
}
break;
@@ -1811,7 +1811,7 @@ static void CB2_HandleStartMultiBattle(void)
u32* ptr = gBattleStruct->multiBuffer.battleVideo;
ptr[0] = gBattleTypeFlags;
ptr[1] = gRecordedBattleRngSeed; // UB: overwrites berry data
SendBlock(bitmask_all_link_players_but_self(), ptr, sizeof(gBattleStruct->multiBuffer.battleVideo));
SendBlock(BitmaskAllOtherLinkPlayers(), ptr, sizeof(gBattleStruct->multiBuffer.battleVideo));
gBattleCommunication[MULTIUSE_STATE]++;
}
break;

View File

@@ -2575,7 +2575,7 @@ static void LoadLinkMultiOpponentsData(void)
challengeNum = gSaveBlock2Ptr->frontier.towerWinStreaks[battleMode][lvlMode] / 7;
if (IsLinkTaskFinished())
{
SendBlock(bitmask_all_link_players_but_self(), &challengeNum, sizeof(challengeNum));
SendBlock(BitmaskAllOtherLinkPlayers(), &challengeNum, sizeof(challengeNum));
gSpecialVar_Result = 1;
}
}
@@ -2612,7 +2612,7 @@ static void LoadLinkMultiOpponentsData(void)
case 2:
if (IsLinkTaskFinished())
{
SendBlock(bitmask_all_link_players_but_self(), &gSaveBlock2Ptr->frontier.trainerIds, sizeof(gSaveBlock2Ptr->frontier.trainerIds));
SendBlock(BitmaskAllOtherLinkPlayers(), &gSaveBlock2Ptr->frontier.trainerIds, sizeof(gSaveBlock2Ptr->frontier.trainerIds));
gSpecialVar_Result = 3;
}
break;

View File

@@ -1355,7 +1355,7 @@ static void CB2_StartBlenderLink(void)
{
ResetBlockReceivedFlags();
if (GetMultiplayerId() == 0)
SendBlockRequest(4);
SendBlockRequest(BLOCK_REQ_SIZE_40);
sBerryBlender->mainState++;
}
break;
@@ -2069,7 +2069,7 @@ static bool32 CheckRecvCmdMatches(u16 recvCmd, u16 linkCmd, u16 rfuCmd)
{
if (gReceivedRemoteLinkPlayers && gWirelessCommType)
{
if ((recvCmd & 0xFF00) == rfuCmd)
if ((recvCmd & RFUCMD_MASK) == rfuCmd)
return TRUE;
}
else
@@ -3135,7 +3135,7 @@ static void UpdateBlenderCenter(void)
}
else
{
if ((gRecvCmds[0][BLENDER_COMM_INPUT_STATE] & 0xFF00) == RFUCMD_BLENDER_SEND_KEYS)
if ((gRecvCmds[0][BLENDER_COMM_INPUT_STATE] & RFUCMD_MASK) == RFUCMD_BLENDER_SEND_KEYS)
{
sBerryBlender->progressBarValue = gRecvCmds[0][BLENDER_COMM_PROGRESS_BAR];
sBerryBlender->arrowPos = gRecvCmds[0][BLENDER_COMM_ARROW_POS];

View File

@@ -984,12 +984,12 @@ static u32 QuitBerryCrush(MainCallback exitCallback)
return 0;
}
#define ERROR_EXIT(exitCallback) \
{ \
SetMainCallback2(exitCallback); \
Rfu.unk_10 = 0; \
Rfu.unk_12 = 0; \
Rfu.errorState = 1; \
#define ERROR_EXIT(exitCallback) \
{ \
SetMainCallback2(exitCallback); \
gRfu.errorParam0 = 0; \
gRfu.errorParam1 = 0; \
gRfu.errorState = RFU_ERROR_STATE_OCCURRED; \
}
void StartBerryCrush(MainCallback exitCallback)
@@ -2565,7 +2565,7 @@ static void HandlePartnerInput(struct BerryCrushGame *game)
linkState = (struct BerryCrushGame_LinkState *)gRecvCmds[i];
// Skip player if we have not received a packet from them
if ((linkState->rfuCmd & 0xFF00) != RFUCMD_SEND_PACKET)
if ((linkState->rfuCmd & RFUCMD_MASK) != RFUCMD_SEND_PACKET)
continue;
if (linkState->sendFlag != SEND_GAME_STATE)
continue;
@@ -2805,7 +2805,7 @@ static void RecvLinkData(struct BerryCrushGame *game)
for (i = 0; i < game->playerCount; i++)
game->players[i].inputState = INPUT_STATE_NONE;
if ((gRecvCmds[0][0] & 0xFF00) != RFUCMD_SEND_PACKET)
if ((gRecvCmds[0][0] & RFUCMD_MASK) != RFUCMD_SEND_PACKET)
{
game->playedSound = FALSE;
return;

View File

@@ -185,9 +185,9 @@ static bool32 CheckLinkCanceled(u8 taskId)
return FALSE;
}
static bool32 sub_80B25CC(u8 taskId)
static bool32 CheckSioErrored(u8 taskId)
{
if (GetSioMultiSI() == 1)
if (GetSioMultiSI() == TRUE)
{
gTasks[taskId].func = Task_LinkupConnectionError;
return TRUE;
@@ -196,12 +196,12 @@ static bool32 sub_80B25CC(u8 taskId)
}
// Unused
static void sub_80B2600(u8 taskId)
static void Task_DelayedBlockRequest(u8 taskId)
{
gTasks[taskId].data[0]++;
if (gTasks[taskId].data[0] == 10)
{
SendBlockRequest(2);
SendBlockRequest(BLOCK_REQ_SIZE_100);
DestroyTask(taskId);
}
}
@@ -252,7 +252,7 @@ static void Task_LinkupAwaitConnection(u8 taskId)
static void Task_LinkupConfirmWhenReady(u8 taskId)
{
if (CheckLinkCanceledBeforeConnection(taskId) == TRUE
|| sub_80B25CC(taskId) == TRUE
|| CheckSioErrored(taskId) == TRUE
|| CheckLinkErrored(taskId) == TRUE)
return;
@@ -269,7 +269,7 @@ static void Task_LinkupAwaitConfirmation(u8 taskId)
s32 linkPlayerCount = GetLinkPlayerCount_2();
if (CheckLinkCanceledBeforeConnection(taskId) == TRUE
|| sub_80B25CC(taskId) == TRUE
|| CheckSioErrored(taskId) == TRUE
|| CheckLinkErrored(taskId) == TRUE)
return;
@@ -291,7 +291,7 @@ static void Task_LinkupAwaitConfirmation(u8 taskId)
static void Task_LinkupTryConfirmation(u8 taskId)
{
if (CheckLinkCanceledBeforeConnection(taskId) == TRUE
|| sub_80B25CC(taskId) == TRUE
|| CheckSioErrored(taskId) == TRUE
|| CheckLinkErrored(taskId) == TRUE)
return;
@@ -424,7 +424,7 @@ static void Task_LinkupCheckStatusAfterConfirm(u8 taskId)
card->monSpecies[0] = GetMonData(&gPlayerParty[gSelectedOrderFromParty[0] - 1], MON_DATA_SPECIES, NULL);
card->monSpecies[1] = GetMonData(&gPlayerParty[gSelectedOrderFromParty[1] - 1], MON_DATA_SPECIES, NULL);
gTasks[taskId].func = Task_LinkupAwaitTrainerCardData;
SendBlockRequest(2);
SendBlockRequest(BLOCK_REQ_SIZE_100);
}
}
@@ -1172,9 +1172,11 @@ static void CreateTask_StartWiredTrade(void)
CreateTask(Task_StartWiredTrade, 80);
}
void nullsub_37(void)
// Unused, implemented in Ruby/Sapphire
void Script_StartWiredTrade(void)
{
// CreateTask_StartWiredTrade();
// ScriptContext1_Stop();
}
void ColosseumPlayerSpotTriggered(void)
@@ -1251,7 +1253,7 @@ void Task_WaitForLinkPlayerConnection(u8 taskId)
#undef tTimer
static void sub_80B3AAC(u8 taskId)
static void Task_WaitExitToScript(u8 taskId)
{
if (!gReceivedRemoteLinkPlayers)
{
@@ -1261,10 +1263,10 @@ static void sub_80B3AAC(u8 taskId)
}
// Unused
static void sub_80B3AD0(u8 taskId)
static void ExitLinkToScript(u8 taskId)
{
SetCloseLinkCallback();
gTasks[taskId].func = sub_80B3AAC;
gTasks[taskId].func = Task_WaitExitToScript;
}
#define tTimer data[1]

View File

@@ -22,7 +22,7 @@ static void Task_LinkContest_InitFlags(u8);
bool32 LinkContest_SendBlock(void *src, u16 size)
{
memcpy(gDecompressionBuffer, src, size);
if (SendBlock(bitmask_all_link_players_but_self(), gDecompressionBuffer, size))
if (SendBlock(BitmaskAllOtherLinkPlayers(), gDecompressionBuffer, size))
return TRUE;
else
return FALSE;
@@ -162,7 +162,7 @@ void Task_LinkContest_CommunicateMonsRS(u8 taskId)
// Only if leader. Request other players data
if (++gTasks[taskId].tTimer > 300)
{
SendBlockRequest(2);
SendBlockRequest(BLOCK_REQ_SIZE_100);
gTasks[taskId].tState = 1;
}
break;
@@ -238,7 +238,7 @@ void Task_LinkContest_CommunicateCategoryRS(u8 taskId)
case 10:
if (++gTasks[taskId].tTimer > 10)
{
SendBlockRequest(2);
SendBlockRequest(BLOCK_REQ_SIZE_100);
gTasks[taskId].tState = 1;
}
break;
@@ -491,7 +491,7 @@ void Task_LinkContest_CommunicateLeaderIdsRS(u8 taskId)
case 10:
if (++gTasks[taskId].tTimer > 10)
{
SendBlockRequest(2);
SendBlockRequest(BLOCK_REQ_SIZE_100);
gTasks[taskId].tState = 1;
}
break;

File diff suppressed because it is too large Load Diff

View File

@@ -3106,7 +3106,7 @@ static u32 RecvPacket_ReadyToStart(u32 playerId)
{
struct ReadyToStartPacket *packet;
if ((gRecvCmds[0][0] & 0xFF00) != RFUCMD_SEND_PACKET)
if ((gRecvCmds[0][0] & RFUCMD_MASK) != RFUCMD_SEND_PACKET)
return FALSE;
packet = (void *)&gRecvCmds[playerId][1];
@@ -3233,7 +3233,7 @@ static bool32 RecvPacket_GameState(u32 playerId,
struct GameStatePacket *packet;
struct DodrioGame_Berries *berries = &player->berries;
if ((gRecvCmds[0][0] & 0xFF00) != RFUCMD_SEND_PACKET)
if ((gRecvCmds[0][0] & RFUCMD_MASK) != RFUCMD_SEND_PACKET)
return FALSE;
packet = (void *)&gRecvCmds[0][1];
@@ -3310,7 +3310,7 @@ static bool32 RecvPacket_PickState(u32 playerId, u8 *pickState)
{
struct PickStatePacket *packet;
if ((gRecvCmds[0][0] & 0xFF00) != RFUCMD_SEND_PACKET)
if ((gRecvCmds[0][0] & RFUCMD_MASK) != RFUCMD_SEND_PACKET)
return FALSE;
packet = (void *)&gRecvCmds[playerId][1];
@@ -3341,7 +3341,7 @@ static bool32 RecvPacket_ReadyToEnd(u32 playerId)
{
struct ReadyToEndPacket *packet;
if ((gRecvCmds[0][0] & 0xFF00) != RFUCMD_SEND_PACKET)
if ((gRecvCmds[0][0] & RFUCMD_MASK) != RFUCMD_SEND_PACKET)
return FALSE;
packet = (void *)&gRecvCmds[playerId][1];

View File

@@ -1138,22 +1138,22 @@ u8 player_get_pos_including_state_based_drift(s16 *x, s16 *y)
switch (object->movementActionId)
{
case MOVEMENT_ACTION_WALK_NORMAL_DOWN:
case MOVEMENT_ACTION_PLAYER_RUN_DOWN:
(*y)++;
return TRUE;
case MOVEMENT_ACTION_WALK_NORMAL_UP:
case MOVEMENT_ACTION_PLAYER_RUN_UP:
(*y)--;
return TRUE;
case MOVEMENT_ACTION_WALK_NORMAL_LEFT:
case MOVEMENT_ACTION_PLAYER_RUN_LEFT:
(*x)--;
return TRUE;
case MOVEMENT_ACTION_WALK_NORMAL_RIGHT:
case MOVEMENT_ACTION_PLAYER_RUN_RIGHT:
(*x)++;
return TRUE;
case MOVEMENT_ACTION_WALK_NORMAL_DOWN:
case MOVEMENT_ACTION_PLAYER_RUN_DOWN:
(*y)++;
return TRUE;
case MOVEMENT_ACTION_WALK_NORMAL_UP:
case MOVEMENT_ACTION_PLAYER_RUN_UP:
(*y)--;
return TRUE;
case MOVEMENT_ACTION_WALK_NORMAL_LEFT:
case MOVEMENT_ACTION_PLAYER_RUN_LEFT:
(*x)--;
return TRUE;
case MOVEMENT_ACTION_WALK_NORMAL_RIGHT:
case MOVEMENT_ACTION_PLAYER_RUN_RIGHT:
(*x)++;
return TRUE;
}
}

View File

@@ -204,7 +204,7 @@ static void Task_ReturnToFieldWirelessLink(u8 taskId)
if (!IsLinkTaskFinished())
{
if (++task->data[1] > 1800)
GetLinkmanErrorParams(0x6000);
RfuSetErrorParams(F_RFU_ERROR_6 | F_RFU_ERROR_7);
}
else
{

View File

@@ -3779,7 +3779,7 @@ static void Task_LinkRetireStatusWithBattleTowerPartner(u8 taskId)
{
// Send value of gSpecialVar_0x8004 to leader
// Will either be BATTLE_TOWER_LINK_CONTINUE or BATTLE_TOWER_LINK_RETIRE
SendBlock(bitmask_all_link_players_but_self(), &gSpecialVar_0x8004, sizeof(gSpecialVar_0x8004));
SendBlock(BitmaskAllOtherLinkPlayers(), &gSpecialVar_0x8004, sizeof(gSpecialVar_0x8004));
gTasks[taskId].tState++;
}
}
@@ -3828,7 +3828,7 @@ static void Task_LinkRetireStatusWithBattleTowerPartner(u8 taskId)
else
{
// Send whether or not play should continue
SendBlock(bitmask_all_link_players_but_self(), &gSpecialVar_Result, sizeof(gSpecialVar_Result));
SendBlock(BitmaskAllOtherLinkPlayers(), &gSpecialVar_Result, sizeof(gSpecialVar_Result));
gTasks[taskId].tState++;
}
}

View File

@@ -1142,7 +1142,7 @@ void CB2_InitCopyrightScreenAfterBootup(void)
{
if (!SetUpCopyrightScreen())
{
SetSaveBlocksPointers(sub_815355C());
SetSaveBlocksPointers(GetSaveBlocksPointersBaseOffset());
ResetMenuAndMonGlobals();
Save_ResetSaveCounters();
Save_LoadGameData(SAVE_NORMAL);

View File

@@ -1,6 +1,14 @@
#include <limits.h>
#include "librfu.h"
// If expanding the length of the player name and wireless link functionality is
// desired, ensure that the name string is limited in size when it's copied from the
// saveblock to any Rfu-related fields (e.g. in SetHostRfuUsername).
// If wireless link functionality is not desired ignore or delete this warning.
#if RFU_USER_NAME_LENGTH < (PLAYER_NAME_LENGTH + 1)
#warning "The Wireless Adapter hardware expects a username of no more than 8 bytes."
#endif
struct LLSFStruct
{
u8 frameSize;

View File

@@ -1,7 +1,7 @@
#include "global.h"
#include "m4a.h"
#include "malloc.h"
#include "reset_save_heap.h"
#include "reload_save.h"
#include "save.h"
#include "bg.h"
#include "window.h"
@@ -108,7 +108,7 @@ static EWRAM_DATA u16 sTimeOutCounter = 0;
EWRAM_DATA struct LinkPlayer gLocalLinkPlayer = {};
EWRAM_DATA struct LinkPlayer gLinkPlayers[MAX_RFU_PLAYERS] = {};
static EWRAM_DATA struct LinkPlayer sSavedLinkPlayers[MAX_RFU_PLAYERS] = {};
EWRAM_DATA struct {
static EWRAM_DATA struct {
u32 status;
u8 lastRecvQueueCount;
u8 lastSendQueueCount;
@@ -140,7 +140,7 @@ static void LinkCB_WaitCloseLinkWithJP(void);
static void LinkCB_Standby(void);
static void LinkCB_StandbyForAll(void);
static void CheckErrorStatus(void);
static void TrySetLinkErrorBuffer(void);
static void CB2_PrintErrorMessage(void);
static bool8 IsSioMultiMaster(void);
static void SetWirelessCommType0_Internal(void);
@@ -166,11 +166,11 @@ static const u16 sLinkTestDigitsGfx[] = INCBIN_U16("graphics/interface/link_test
static const u8 sUnusedTransparentWhite[] = _("{HIGHLIGHT TRANSPARENT}{COLOR WHITE}");
static const u16 sCommErrorBg_Gfx[] = INCBIN_U16("graphics/interface/comm_error_bg.4bpp");
static const struct BlockRequest sBlockRequests[] = {
{gBlockSendBuffer, 200},
{gBlockSendBuffer, 200},
{gBlockSendBuffer, 100},
{gBlockSendBuffer, 220},
{gBlockSendBuffer, 40}
[BLOCK_REQ_SIZE_NONE] = {gBlockSendBuffer, 200},
[BLOCK_REQ_SIZE_200] = {gBlockSendBuffer, 200},
[BLOCK_REQ_SIZE_100] = {gBlockSendBuffer, 100},
[BLOCK_REQ_SIZE_220] = {gBlockSendBuffer, 220},
[BLOCK_REQ_SIZE_40] = {gBlockSendBuffer, 40}
};
static const u8 sBGControlRegs[] = {
REG_OFFSET_BG0CNT,
@@ -394,9 +394,7 @@ void CloseLink(void)
{
gReceivedRemoteLinkPlayers = FALSE;
if (gWirelessCommType)
{
LinkRfu_Shutdown();
}
sLinkOpen = FALSE;
DisableSerial();
}
@@ -485,22 +483,18 @@ u16 LinkMain2(const u16 *heldKeys)
u8 i;
if (!sLinkOpen)
{
return 0;
}
for (i = 0; i < CMD_LENGTH; i++)
{
gSendCmd[i] = 0;
}
gLinkHeldKeys = *heldKeys;
if (gLinkStatus & LINK_STAT_CONN_ESTABLISHED)
{
ProcessRecvCmds(SIO_MULTI_CNT->id);
if (gLinkCallback != NULL)
{
gLinkCallback();
}
CheckErrorStatus();
TrySetLinkErrorBuffer();
}
return gLinkStatus;
}
@@ -1029,7 +1023,7 @@ u8 GetMultiplayerId(void)
return SIO_MULTI_CNT->id;
}
u8 bitmask_all_link_players_but_self(void)
u8 BitmaskAllOtherLinkPlayers(void)
{
u8 mpId;
@@ -1563,10 +1557,13 @@ static void LinkCB_StandbyForAll(void)
}
}
static void CheckErrorStatus(void)
static void TrySetLinkErrorBuffer(void)
{
// Check if a link error has occurred
if (sLinkOpen && EXTRACT_LINK_ERRORS(gLinkStatus))
{
// Link error has occurred, handle message details if
// necessary, then stop the link.
if (!gSuppressLinkErrorMessage)
{
sLinkErrorBuffer.status = gLinkStatus;
@@ -1579,7 +1576,7 @@ static void CheckErrorStatus(void)
}
}
void BufferLinkErrorInfo(u32 status, u8 lastSendQueueCount, u8 lastRecvQueueCount, bool8 disconnected)
void SetLinkErrorBuffer(u32 status, u8 lastSendQueueCount, u8 lastRecvQueueCount, bool8 disconnected)
{
sLinkErrorBuffer.status = status;
sLinkErrorBuffer.lastSendQueueCount = lastSendQueueCount;
@@ -1709,7 +1706,7 @@ static void CB2_PrintErrorMessage(void)
PlaySE(SE_PIN);
gWirelessCommType = 0;
sLinkErrorBuffer.disconnected = FALSE;
sub_81700F8();
ReloadSave();
}
}
else if (gWirelessCommType == 2)
@@ -1731,12 +1728,12 @@ static void CB2_PrintErrorMessage(void)
bool8 GetSioMultiSI(void)
{
return (REG_SIOCNT & 0x04) != 0;
return (REG_SIOCNT & SIO_MULTI_SI) != 0;
}
static bool8 IsSioMultiMaster(void)
{
return (REG_SIOCNT & 0x8) && !(REG_SIOCNT & 0x04);
return (REG_SIOCNT & SIO_MULTI_SD) && (REG_SIOCNT & SIO_MULTI_SI) == 0;
}
bool8 IsLinkConnectionEstablished(void)
@@ -1782,10 +1779,10 @@ void LinkPlayerFromBlock(u32 who)
SetMainCallback2(CB2_LinkError);
}
// When this function returns TRUE the callbacks are skipped
bool8 HandleLinkConnection(void)
{
bool32 r4;
bool32 r5;
bool32 main1Failed, main2Failed;
if (gWirelessCommType == 0)
{
@@ -1796,11 +1793,13 @@ bool8 HandleLinkConnection(void)
}
else
{
r4 = sub_8010EC0();
r5 = sub_8010F1C();
main1Failed = RfuMain1(); // Always returns FALSE
main2Failed = RfuMain2();
if (IsSendingKeysOverCable() == TRUE)
{
if (r4 == TRUE || IsRfuRecvQueueEmpty() || r5)
// This will never be reached.
// IsSendingKeysOverCable is always FALSE for wireless communication
if (main1Failed == TRUE || IsRfuRecvQueueEmpty() || main2Failed)
return TRUE;
}
}
@@ -1916,9 +1915,7 @@ u32 LinkMain1(u8 *shouldAdvanceLinkState, u16 *sendCmd, u16 (*recvCmds)[CMD_LENG
break;
case 1:
if (gLink.isMaster == LINK_MASTER && gLink.playerCount > 1)
{
gLink.handshakeAsMaster = TRUE;
}
break;
case 2:
gLink.state = LINK_STATE_START0;
@@ -1974,20 +1971,14 @@ u32 LinkMain1(u8 *shouldAdvanceLinkState, u16 *sendCmd, u16 (*recvCmds)[CMD_LENG
}
if (gLink.lag == LAG_MASTER)
{
retVal |= LINK_STAT_ERROR_LAG_MASTER;
}
if (gLink.localId >= MAX_LINK_PLAYERS)
{
retVal |= LINK_STAT_ERROR_INVALID_ID;
}
retVal2 = retVal;
if (gLink.lag == LAG_SLAVE)
{
retVal2 |= LINK_STAT_ERROR_LAG_SLAVE;
}
return retVal2;
}

File diff suppressed because it is too large Load Diff

View File

@@ -15,6 +15,9 @@ enum {
WIRELESS_STATUS_ANIM_ERROR,
};
#define TAG_GFX_STATUS_INDICATOR 0xD431
#define TAG_PAL_STATUS_INDICATOR 0xD432
#define UNUSED_QUEUE_NUM_SLOTS 2
#define UNUSED_QUEUE_SLOT_LENGTH 256
@@ -29,7 +32,7 @@ struct RfuUnusedQueue
EWRAM_DATA u8 gWirelessStatusIndicatorSpriteId = 0;
static u8 sUnknown_03000D74;
static u8 sSequenceArrayValOffset;
static const u16 sWirelessLinkIconPalette[] = INCBIN_U16("graphics/interface/wireless_link_icon.gbapal");
static const u32 sWirelessLinkIconPic[] = INCBIN_U32("graphics/interface/wireless_link_icon.4bpp.lz");
@@ -290,16 +293,16 @@ static const union AnimCmd *const sWirelessStatusIndicatorAnims[] = {
};
static const struct CompressedSpriteSheet sWirelessStatusIndicatorSpriteSheet = {
sWirelessLinkIconPic, 0x0380, 0xD431
sWirelessLinkIconPic, 0x0380, TAG_GFX_STATUS_INDICATOR
};
static const struct SpritePalette sWirelessStatusIndicatorSpritePalette = {
sWirelessLinkIconPalette, 0xD432
sWirelessLinkIconPalette, TAG_PAL_STATUS_INDICATOR
};
static const struct SpriteTemplate sWirelessStatusIndicatorSpriteTemplate = {
.tileTag = 0xD431,
.paletteTag = 0xD432,
.tileTag = TAG_GFX_STATUS_INDICATOR,
.paletteTag = TAG_PAL_STATUS_INDICATOR,
.oam = &sWirelessStatusIndicatorOamData,
.anims = sWirelessStatusIndicatorAnims,
.images = NULL,
@@ -314,10 +317,8 @@ void RfuRecvQueue_Reset(struct RfuRecvQueue *queue)
for (i = 0; i < RECV_QUEUE_NUM_SLOTS; i++)
{
for (j = 0; j < RECV_QUEUE_SLOT_LENGTH; j++)
{
for (j = 0; j < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; j++)
queue->slots[i][j] = 0;
}
}
queue->sendSlot = 0;
queue->recvSlot = 0;
@@ -332,10 +333,8 @@ void RfuSendQueue_Reset(struct RfuSendQueue *queue)
for (i = 0; i < SEND_QUEUE_NUM_SLOTS; i++)
{
for (j = 0; j < SEND_QUEUE_SLOT_LENGTH; j++)
{
for (j = 0; j < COMM_SLOT_LENGTH; j++)
queue->slots[i][j] = 0;
}
}
queue->sendSlot = 0;
queue->recvSlot = 0;
@@ -351,9 +350,7 @@ static void RfuUnusedQueue_Reset(struct RfuUnusedQueue *queue)
for (i = 0; i < UNUSED_QUEUE_NUM_SLOTS; i++)
{
for (j = 0; j < UNUSED_QUEUE_SLOT_LENGTH; j++)
{
queue->slots[i][j] = 0;
}
}
queue->sendSlot = 0;
queue->recvSlot = 0;
@@ -372,21 +369,21 @@ void RfuRecvQueue_Enqueue(struct RfuRecvQueue *queue, u8 *data)
imeBak = REG_IME;
REG_IME = 0;
count = 0;
for (i = 0; i < RECV_QUEUE_SLOT_LENGTH; i += RECV_QUEUE_SLOT_LENGTH / MAX_RFU_PLAYERS)
for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i += COMM_SLOT_LENGTH)
{
if (data[i] == 0 && data[i + 1] == 0)
count++;
}
if (count != MAX_RFU_PLAYERS)
{
for (i = 0; i < RECV_QUEUE_SLOT_LENGTH; i++)
for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++)
queue->slots[queue->recvSlot][i] = data[i];
queue->recvSlot++;
queue->recvSlot %= RECV_QUEUE_NUM_SLOTS;
queue->count++;
for (i = 0; i < RECV_QUEUE_SLOT_LENGTH; i++)
for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++)
data[i] = 0;
}
REG_IME = imeBak;
@@ -406,22 +403,20 @@ void RfuSendQueue_Enqueue(struct RfuSendQueue *queue, u8 *data)
{
imeBak = REG_IME;
REG_IME = 0;
for (i = 0; i < SEND_QUEUE_SLOT_LENGTH; i++)
for (i = 0; i < COMM_SLOT_LENGTH; i++)
{
if (data[i] != 0)
break;
}
if (i != SEND_QUEUE_SLOT_LENGTH)
if (i != COMM_SLOT_LENGTH)
{
for (i = 0; i < SEND_QUEUE_SLOT_LENGTH; i++)
{
for (i = 0; i < COMM_SLOT_LENGTH; i++)
queue->slots[queue->recvSlot][i] = data[i];
}
queue->recvSlot++;
queue->recvSlot %= SEND_QUEUE_NUM_SLOTS;
queue->count++;
for (i = 0; i < SEND_QUEUE_SLOT_LENGTH; i++)
for (i = 0; i < COMM_SLOT_LENGTH; i++)
data[i] = 0;
}
REG_IME = imeBak;
@@ -441,13 +436,13 @@ bool8 RfuRecvQueue_Dequeue(struct RfuRecvQueue *queue, u8 *src)
REG_IME = 0;
if (queue->recvSlot == queue->sendSlot || queue->full)
{
for (i = 0; i < RECV_QUEUE_SLOT_LENGTH; i++)
for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++)
src[i] = 0;
REG_IME = imeBak;
return FALSE;
}
for (i = 0; i < RECV_QUEUE_SLOT_LENGTH; i++)
for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++)
{
src[i] = queue->slots[queue->sendSlot][i];
}
@@ -468,7 +463,7 @@ bool8 RfuSendQueue_Dequeue(struct RfuSendQueue *queue, u8 *src)
imeBak = REG_IME;
REG_IME = 0;
for (i = 0; i < SEND_QUEUE_SLOT_LENGTH; i++)
for (i = 0; i < COMM_SLOT_LENGTH; i++)
src[i] = queue->slots[queue->sendSlot][i];
queue->sendSlot++;
@@ -488,7 +483,7 @@ void RfuBackupQueue_Enqueue(struct RfuBackupQueue *queue, const u8 *data)
}
else
{
for (i = 0; i < BACKUP_QUEUE_SLOT_LENGTH; i++)
for (i = 0; i < COMM_SLOT_LENGTH; i++)
queue->slots[queue->recvSlot][i] = data[i];
queue->recvSlot++;
@@ -510,7 +505,7 @@ bool8 RfuBackupQueue_Dequeue(struct RfuBackupQueue *queue, u8 *src)
if (src != NULL)
{
for (i = 0; i < BACKUP_QUEUE_SLOT_LENGTH; i++)
for (i = 0; i < COMM_SLOT_LENGTH; i++)
src[i] = queue->slots[queue->sendSlot][i];
}
queue->sendSlot++;
@@ -555,46 +550,57 @@ static bool8 RfuUnusedQueue_Dequeue(struct RfuUnusedQueue *queue, u8 *dest)
}
// Unused
static void sub_800DBF8(u8 *q1, u8 mode)
// Populates an array with a sequence of numbers (which numbers depends on the mode)
// and sets the final element to the total of the other elements
#define SEQ_ARRAY_MAX_SIZE 200
static void PopulateArrayWithSequence(u8 *arr, u8 mode)
{
s32 i;
u8 rval;
u16 r5 = 0;
u16 total = 0;
switch (mode)
{
case 0:
for (i = 0; i < 200; i++)
// Populate with numbers 1-200
// Total will be 20100
for (i = 0; i < SEQ_ARRAY_MAX_SIZE; i++)
{
q1[i] = i + 1;
r5 += i + 1;
arr[i] = i + 1;
total += i + 1;
}
*((u16 *)(q1 + i)) = r5;
*((u16 *)(arr + i)) = total;
break;
case 1:
// Populate with numbers 1-100
// Total will be 5050
for (i = 0; i < 100; i++)
{
q1[i] = i + 1;
r5 += i + 1;
arr[i] = i + 1;
total += i + 1;
}
*((u16 *)(q1 + 200)) = r5;
*((u16 *)(arr + SEQ_ARRAY_MAX_SIZE)) = total;
break;
case 2:
for (i = 0; i < 200; i++)
// Populate with random numbers 0-255
// Total will be a number 0-51000
for (i = 0; i < SEQ_ARRAY_MAX_SIZE; i++)
{
rval = Random();
q1[i] = rval;
r5 += rval;
arr[i] = rval;
total += rval;
}
*((u16 *)(q1 + i)) = r5;
*((u16 *)(arr + i)) = total;
break;
case 3:
for (i = 0; i < 200; i++)
// Populate with numbers 1-200 + sSequenceArrayValOffset
// Total will be a number 20100-51000
for (i = 0; i < SEQ_ARRAY_MAX_SIZE; i++)
{
q1[i] = i + 1 + sUnknown_03000D74;
r5 += (i + 1 + sUnknown_03000D74) & 0xFF;
arr[i] = i + 1 + sSequenceArrayValOffset;
total += (i + 1 + sSequenceArrayValOffset) & 0xFF;
}
*((u16 *)(q1 + i)) = r5;
sUnknown_03000D74++;
*((u16 *)(arr + i)) = total;
sSequenceArrayValOffset++;
break;
}
}
@@ -606,9 +612,7 @@ static void PkmnStrToASCII(u8 *asciiStr, const u8 *pkmnStr)
s32 i;
for (i = 0; pkmnStr[i] != EOS; i++)
{
asciiStr[i] = sWireless_RSEtoASCIITable[pkmnStr[i]];
}
asciiStr[i] = 0;
}
@@ -617,9 +621,7 @@ static void ASCIIToPkmnStr(u8 *pkmnStr, const u8 *asciiStr)
s32 i;
for (i = 0; asciiStr[i] != 0; i++)
{
pkmnStr[i] = sWireless_ASCIItoRSETable[asciiStr[i]];
}
pkmnStr[i] = EOS;
}
@@ -655,33 +657,32 @@ static u8 GetConnectedChildStrength(u8 maxFlags)
return 0;
}
void InitHostRFUtgtGname(struct GFtgtGname *data, u8 activity, bool32 started, s32 child_sprite_genders)
void InitHostRfuGameData(struct RfuGameData *data, u8 activity, bool32 startedActivity, s32 partnerInfo)
{
s32 i;
for (i = 0; i < 2; i++)
{
data->unk_00.playerTrainerId[i] = gSaveBlock2Ptr->playerTrainerId[i];
}
for (i = 0; i < (s32)ARRAY_COUNT(data->compatibility.playerTrainerId); i++)
data->compatibility.playerTrainerId[i] = gSaveBlock2Ptr->playerTrainerId[i];
for (i = 0; i < RFU_CHILD_MAX; i++)
{
data->child_sprite_gender[i] = child_sprite_genders;
child_sprite_genders >>= 8;
data->partnerInfo[i] = partnerInfo;
partnerInfo >>= 8; // Each element is 1 byte
}
data->playerGender = gSaveBlock2Ptr->playerGender;
data->activity = activity;
data->started = started;
data->unk_00.language = GAME_LANGUAGE;
data->unk_00.version = GAME_VERSION;
data->unk_00.hasNews = FALSE;
data->unk_00.hasCard = FALSE;
data->unk_00.unknown = FALSE;
data->unk_00.isChampion = FlagGet(FLAG_IS_CHAMPION);
data->unk_00.hasNationalDex = IsNationalPokedexEnabled();
data->unk_00.gameClear = FlagGet(FLAG_SYS_GAME_CLEAR);
data->startedActivity = startedActivity;
data->compatibility.language = GAME_LANGUAGE;
data->compatibility.version = GAME_VERSION;
data->compatibility.hasNews = FALSE;
data->compatibility.hasCard = FALSE;
data->compatibility.unknown = FALSE;
data->compatibility.isChampion = FlagGet(FLAG_IS_CHAMPION);
data->compatibility.hasNationalDex = IsNationalPokedexEnabled();
data->compatibility.gameClear = FlagGet(FLAG_SYS_GAME_CLEAR);
}
bool8 LinkRfu_GetNameIfCompatible(struct GFtgtGname *buff1, u8 *buff2, u8 idx)
bool8 Rfu_GetCompatiblePlayerData(struct RfuGameData *gameData, u8 *username, u8 idx)
{
bool8 retVal;
@@ -690,13 +691,13 @@ bool8 LinkRfu_GetNameIfCompatible(struct GFtgtGname *buff1, u8 *buff2, u8 idx)
retVal = TRUE;
if (IsRfuSerialNumberValid(gRfuLinkStatus->partner[idx].serialNo) && ((gRfuLinkStatus->getNameFlag >> idx) & 1))
{
memcpy(buff1, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH);
memcpy(buff2, gRfuLinkStatus->partner[idx].uname, PLAYER_NAME_LENGTH + 1);
memcpy(gameData, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH);
memcpy(username, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH);
}
else
{
memset(buff1, 0, RFU_GAME_NAME_LENGTH);
memset(buff2, 0, PLAYER_NAME_LENGTH + 1);
memset(gameData, 0, RFU_GAME_NAME_LENGTH);
memset(username, 0, RFU_USER_NAME_LENGTH);
}
}
else
@@ -704,39 +705,39 @@ bool8 LinkRfu_GetNameIfCompatible(struct GFtgtGname *buff1, u8 *buff2, u8 idx)
retVal = FALSE;
if (IsRfuSerialNumberValid(gRfuLinkStatus->partner[idx].serialNo))
{
memcpy(buff1, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH);
memcpy(buff2, gRfuLinkStatus->partner[idx].uname, PLAYER_NAME_LENGTH + 1);
memcpy(gameData, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH);
memcpy(username, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH);
}
else
{
memset(buff1, 0, RFU_GAME_NAME_LENGTH);
memset(buff2, 0, PLAYER_NAME_LENGTH + 1);
memset(gameData, 0, RFU_GAME_NAME_LENGTH);
memset(username, 0, RFU_USER_NAME_LENGTH);
}
}
return retVal;
}
bool8 LinkRfu_GetNameIfSerial7F7D(struct GFtgtGname *buff1, u8 *buff2, u8 idx)
bool8 Rfu_GetWonderDistributorPlayerData(struct RfuGameData *gameData, u8 *username, u8 idx)
{
bool8 retVal = FALSE;
if (gRfuLinkStatus->partner[idx].serialNo == RFU_SERIAL_7F7D)
if (gRfuLinkStatus->partner[idx].serialNo == RFU_SERIAL_WONDER_DISTRIBUTOR)
{
memcpy(buff1, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH);
memcpy(buff2, gRfuLinkStatus->partner[idx].uname, PLAYER_NAME_LENGTH + 1);
memcpy(gameData, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH);
memcpy(username, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH);
retVal = TRUE;
}
else
{
memset(buff1, 0, RFU_GAME_NAME_LENGTH);
memset(buff2, 0, PLAYER_NAME_LENGTH + 1);
memset(gameData, 0, RFU_GAME_NAME_LENGTH);
memset(username, 0, RFU_USER_NAME_LENGTH);
}
return retVal;
}
void LinkRfu3_SetGnameUnameFromStaticBuffers(struct GFtgtGname *buff1, u8 *buff2)
void CopyHostRfuGameDataAndUsername(struct RfuGameData *gameData, u8 *username)
{
memcpy(buff1, &gHostRFUtgtGnameBuffer, RFU_GAME_NAME_LENGTH);
memcpy(buff2, gHostRFUtgtUnameBuffer, PLAYER_NAME_LENGTH + 1);
memcpy(gameData, &gHostRfuGameData, RFU_GAME_NAME_LENGTH);
memcpy(username, gHostRfuUsername, RFU_USER_NAME_LENGTH);
}
#define sNextAnimNum data[0]
@@ -754,8 +755,8 @@ void CreateWirelessStatusIndicatorSprite(u8 x, u8 y)
if (x == 0 && y == 0)
{
x = 0xE7;
y = 0x08;
x = 231;
y = 8;
}
if (gRfuLinkStatus->parentChild == MODE_PARENT)
{
@@ -788,9 +789,7 @@ void DestroyWirelessStatusIndicatorSprite(void)
void LoadWirelessStatusIndicatorSpriteGfx(void)
{
if (GetSpriteTileStartByTag(sWirelessStatusIndicatorSpriteSheet.tag) == 0xFFFF)
{
LoadCompressedSpriteSheet(&sWirelessStatusIndicatorSpriteSheet);
}
LoadSpritePalette(&sWirelessStatusIndicatorSpritePalette);
gWirelessStatusIndicatorSpriteId = SPRITE_NONE;
}
@@ -802,9 +801,7 @@ static u8 GetParentSignalStrength(void)
for (i = 0; i < RFU_CHILD_MAX; i++)
{
if (flags & 1)
{
return gRfuLinkStatus->strength[i];
}
flags >>= 1;
}
return 0;
@@ -827,40 +824,33 @@ void UpdateWirelessStatusIndicatorSprite(void)
struct Sprite *sprite = &gSprites[gWirelessStatusIndicatorSpriteId];
u8 signalStrength = RFU_LINK_ICON_LEVEL4_MAX;
u8 i = 0;
// Get weakest signal strength
if (gRfuLinkStatus->parentChild == MODE_PARENT)
{
for (i = 0; i < GetLinkPlayerCount() - 1; i++)
{
if (signalStrength >= GetConnectedChildStrength(i + 1))
{
signalStrength = GetConnectedChildStrength(i + 1);
}
}
}
else
{
signalStrength = GetParentSignalStrength();
}
// Set signal strength sprite anim number
if (IsRfuRecoveringFromLinkLoss() == TRUE)
{
sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_ERROR;
}
else if (signalStrength <= RFU_LINK_ICON_LEVEL1_MAX)
{
sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_SEARCHING;
}
else if (signalStrength >= RFU_LINK_ICON_LEVEL2_MIN && signalStrength <= RFU_LINK_ICON_LEVEL2_MAX)
{
sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_1_BAR;
}
else if (signalStrength >= RFU_LINK_ICON_LEVEL3_MIN && signalStrength <= RFU_LINK_ICON_LEVEL3_MAX)
{
sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_2_BARS;
}
else if (signalStrength >= RFU_LINK_ICON_LEVEL4_MIN)
{
sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_3_BARS;
}
if (sprite->sNextAnimNum != sprite->sSavedAnimNum)
{
SetWirelessStatusIndicatorAnim(sprite, sprite->sNextAnimNum);
@@ -871,9 +861,7 @@ void UpdateWirelessStatusIndicatorSprite(void)
sprite->sFrameIdx++;
sprite->sFrameDelay = 0;
if (sprite->anims[sprite->sCurrAnimNum][sprite->sFrameIdx].type == -2)
{
sprite->sFrameIdx = 0;
}
}
else
{
@@ -884,11 +872,9 @@ void UpdateWirelessStatusIndicatorSprite(void)
gMain.oamBuffer[125].y = sprite->y + sprite->centerToCornerVecY;
gMain.oamBuffer[125].paletteNum = sprite->oam.paletteNum;
gMain.oamBuffer[125].tileNum = sprite->sTileStart + sprite->anims[sprite->sCurrAnimNum][sprite->sFrameIdx].frame.imageValue;
CpuCopy16(gMain.oamBuffer + 125, (struct OamData *)OAM + 125, sizeof(struct OamData));
CpuCopy16(&gMain.oamBuffer[125], (struct OamData *)OAM + 125, sizeof(struct OamData));
if (RfuGetStatus() == RFU_STATUS_FATAL_ERROR)
{
DestroyWirelessStatusIndicatorSprite();
}
}
}
@@ -919,14 +905,14 @@ static bool32 NameIsNotEmpty(const u8 *name)
}
// Save the currently connected players into the trainer records, shifting all previous records down.
void RecordMixTrainerNames(void)
void SaveLinkTrainerNames(void)
{
if (gWirelessCommType != 0)
{
s32 i;
s32 j;
s32 nextSpace;
s32 connectedTrainerRecordIndices[5];
s32 connectedTrainerRecordIndices[MAX_RFU_PLAYERS];
struct TrainerNameRecord *newRecords = calloc(ARRAY_COUNT(gSaveBlock1Ptr->trainerNameRecords), sizeof(struct TrainerNameRecord));
// Check if we already have a record saved for connected trainers.
@@ -936,9 +922,7 @@ void RecordMixTrainerNames(void)
for (j = 0; j < (int)ARRAY_COUNT(gSaveBlock1Ptr->trainerNameRecords); j++)
{
if ((u16)gLinkPlayers[i].trainerId == gSaveBlock1Ptr->trainerNameRecords[j].trainerId && StringCompare(gLinkPlayers[i].name, gSaveBlock1Ptr->trainerNameRecords[j].trainerName) == 0)
{
connectedTrainerRecordIndices[i] = j;
}
}
}
@@ -952,9 +936,7 @@ void RecordMixTrainerNames(void)
// If we already had a record for this trainer, wipe it so that the next step doesn't duplicate it.
if (connectedTrainerRecordIndices[i] >= 0)
{
memset(gSaveBlock1Ptr->trainerNameRecords[connectedTrainerRecordIndices[i]].trainerName, 0, 8);
}
memset(gSaveBlock1Ptr->trainerNameRecords[connectedTrainerRecordIndices[i]].trainerName, 0, PLAYER_NAME_LENGTH + 1);
nextSpace++;
}
}
@@ -967,9 +949,7 @@ void RecordMixTrainerNames(void)
{
CopyTrainerRecord(&newRecords[nextSpace], gSaveBlock1Ptr->trainerNameRecords[i].trainerId, gSaveBlock1Ptr->trainerNameRecords[i].trainerName);
if (++nextSpace >= (int)ARRAY_COUNT(gSaveBlock1Ptr->trainerNameRecords))
{
break;
}
}
}
@@ -1001,6 +981,6 @@ void WipeTrainerNameRecords(void)
for (i = 0; i < (int)ARRAY_COUNT(gSaveBlock1Ptr->trainerNameRecords); i++)
{
gSaveBlock1Ptr->trainerNameRecords[i].trainerId = 0;
CpuFill16(0, gSaveBlock1Ptr->trainerNameRecords[i].trainerName, 8);
CpuFill16(0, gSaveBlock1Ptr->trainerNameRecords[i].trainerName, PLAYER_NAME_LENGTH + 1);
}
}

View File

@@ -71,6 +71,7 @@ void ClearSav1(void)
CpuFill16(0, &gSaveblock1, sizeof(struct SaveBlock1) + sizeof(gSaveblock1_DMA));
}
// Offset is the sum of the trainer id bytes
void SetSaveBlocksPointers(u16 offset)
{
struct SaveBlock1** sav1_LocalVar = &gSaveBlock1Ptr;

View File

@@ -510,13 +510,9 @@ void MG_DrawCheckerboardPattern(u32 bg)
for (j = 0; j < 32; j++)
{
if ((i & 1) != (j & 1))
{
FillBgTilemapBufferRect(bg, 1, j, i + 2, 1, 1, 0x11);
}
else
{
FillBgTilemapBufferRect(bg, 2, j, i + 2, 1, 1, 0x11);
}
}
}
}
@@ -593,10 +589,8 @@ bool32 unref_HideDownArrowAndWaitButton(u8 * textState)
{
case 0:
HideDownArrow();
if (({JOY_NEW(A_BUTTON | B_BUTTON);}))
{
if (JOY_NEW(A_BUTTON | B_BUTTON))
(*textState)++;
}
break;
case 1:
ShowDownArrow();
@@ -609,9 +603,8 @@ bool32 unref_HideDownArrowAndWaitButton(u8 * textState)
static bool32 PrintStringAndWait2Seconds(u8 * counter, const u8 * str)
{
if (*counter == 0)
{
AddTextPrinterToWindow1(str);
}
if (++(*counter) > 120)
{
*counter = 0;
@@ -632,27 +625,20 @@ static u32 MysteryGift_HandleThreeOptionMenu(u8 * unused0, u16 * unused1, u8 whi
s32 response;
if (whichMenu == 0)
{
listMenuTemplate.items = sListMenuItems_CardsOrNews;
}
else
{
listMenuTemplate.items = sListMenuItems_WirelessOrFriend;
}
width = Intl_GetListMenuWidth(&listMenuTemplate);
if (width & 1)
{
width++;
}
windowTemplate.width = width;
if (width < 30)
{
windowTemplate.tilemapLeft = (30 - width) / 2;
}
else
{
windowTemplate.tilemapLeft = 0;
}
response = DoMysteryGiftListMenu(&windowTemplate, &listMenuTemplate, 1, 0x00A, 0xE0);
if (response != -1)
{
@@ -672,13 +658,9 @@ s8 mevent_message_print_and_prompt_yes_no(u8 * textState, u16 * windowId, bool8
case 0:
StringExpandPlaceholders(gStringVar4, str);
if (yesNoBoxPlacement == 0)
{
*windowId = AddWindow(&sWindowTemplate_PromptYesOrNo_Width28);
}
else
{
*windowId = AddWindow(&sWindowTemplate_PromptYesOrNo_Width20);
}
FillWindowPixelBuffer(*windowId, 0x11);
AddTextPrinterParameterized4(*windowId, 1, 0, 1, 0, 0, sMG_Ereader_TextColor_2, 0, gStringVar4);
DrawTextBorderOuter(*windowId, 0x001, 0x0F);
@@ -689,19 +671,15 @@ s8 mevent_message_print_and_prompt_yes_no(u8 * textState, u16 * windowId, bool8
case 1:
windowTemplate = sWindowTemplate_YesNoBox;
if (yesNoBoxPlacement == 0)
{
windowTemplate.tilemapTop = 9;
}
else
{
windowTemplate.tilemapTop = 15;
}
CreateYesNoMenu(&windowTemplate, 10, 14, 0);
(*textState)++;
break;
case 2:
input = Menu_ProcessInputNoWrapClearOnChoose();
if (input == -1 || input == 0 || input == 1)
if (input == MENU_B_PRESSED || input == 0 || input == 1)
{
*textState = 0;
rbox_fill_rectangle(*windowId);
@@ -711,16 +689,16 @@ s8 mevent_message_print_and_prompt_yes_no(u8 * textState, u16 * windowId, bool8
return input;
}
break;
case 0xFF:
case (u8)MENU_B_PRESSED:
*textState = 0;
rbox_fill_rectangle(*windowId);
ClearWindowTilemap(*windowId);
CopyWindowToVram(*windowId, 1);
RemoveWindow(*windowId);
return -1;
return MENU_B_PRESSED;
}
return -2;
return MENU_NOTHING_CHOSEN;
}
static s32 HandleMysteryGiftListMenu(u8 * textState, u16 * windowId, bool32 cannotToss, bool32 cannotSend)
@@ -1237,21 +1215,21 @@ void task00_mystery_gift(u8 taskId)
case 0:
if (data->source == 1)
{
MEvent_CreateTask_CardOrNewsWithFriend(ACTIVITY_WONDER_CARD2);
MEvent_CreateTask_CardOrNewsWithFriend(ACTIVITY_WONDER_CARD);
}
else if (data->source == 0)
{
MEvent_CreateTask_CardOrNewsOverWireless(ACTIVITY_WONDER_CARD2);
MEvent_CreateTask_CardOrNewsOverWireless(ACTIVITY_WONDER_CARD);
}
break;
case 1:
if (data->source == 1)
{
MEvent_CreateTask_CardOrNewsWithFriend(ACTIVITY_WONDER_NEWS2);
MEvent_CreateTask_CardOrNewsWithFriend(ACTIVITY_WONDER_NEWS);
}
else if (data->source == 0)
{
MEvent_CreateTask_CardOrNewsOverWireless(ACTIVITY_WONDER_NEWS2);
MEvent_CreateTask_CardOrNewsOverWireless(ACTIVITY_WONDER_NEWS);
}
break;
}
@@ -1594,10 +1572,10 @@ void task00_mystery_gift(u8 taskId)
switch (data->IsCardOrNews)
{
case 0:
MEvent_CreateTask_Leader(ACTIVITY_WONDER_CARD2);
MEvent_CreateTask_Leader(ACTIVITY_WONDER_CARD);
break;
case 1:
MEvent_CreateTask_Leader(ACTIVITY_WONDER_NEWS2);
MEvent_CreateTask_Leader(ACTIVITY_WONDER_NEWS);
break;
}
data->source = 1;

View File

@@ -286,19 +286,26 @@ static const struct WindowTemplate sWindowTemplates[WIN_COUNT + 1] =
// This handles what characters get inserted when a key is pressed
// The keys shown on the keyboard are handled separately by sNamingScreenKeyboardText
static const u8 sKeyboardChars[KBPAGE_COUNT * KBROW_COUNT * KBCOL_COUNT] = __(
"abcdef ."
"ghijkl ,"
"mnopqrs "
"tuvwxyz "
"ABCDEF ."
"GHIJKL ,"
"MNOPQRS "
"TUVWXYZ "
"01234 "
"56789 "
"!?♂♀/- "
"…“”‘' ");
static const u8 sKeyboardChars[KBPAGE_COUNT][KBROW_COUNT][KBCOL_COUNT] = {
[KEYBOARD_LETTERS_LOWER] = {
__("abcdef ."),
__("ghijkl ,"),
__("mnopqrs "),
__("tuvwxyz "),
},
[KEYBOARD_LETTERS_UPPER] = {
__("ABCDEF ."),
__("GHIJKL ,"),
__("MNOPQRS "),
__("TUVWXYZ "),
},
[KEYBOARD_SYMBOLS] = {
__("01234 "),
__("56789 "),
__("!?♂♀/- "),
__("…“”‘' "),
}
};
static const u8 sPageColumnCounts[KBPAGE_COUNT] = {
[KEYBOARD_LETTERS_LOWER] = KBCOL_COUNT,
@@ -1780,7 +1787,7 @@ static void DrawGenderIcon(void)
static u8 GetCharAtKeyboardPos(s16 x, s16 y)
{
return sKeyboardChars[x + y * KBCOL_COUNT + CurrentPageToKeyboardId() * KBCOL_COUNT * KBROW_COUNT];
return sKeyboardChars[CurrentPageToKeyboardId()][y][x];
}

View File

@@ -2898,7 +2898,7 @@ bool32 IsSendingKeysOverCable(void)
static u32 GetLinkSendQueueLength(void)
{
if (gWirelessCommType != 0)
return Rfu.sendQueue.count;
return gRfu.sendQueue.count;
else
return gLink.sendQueue.count;
}

View File

@@ -3522,7 +3522,7 @@ static void CursorCb_Register(u8 taskId)
u16 species = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES);
u8 isEventLegal = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_EVENT_LEGAL);
switch (CanRegisterMonForTradingBoard(*(struct GFtgtGnameSub *)GetHostRFUtgtGname(), species2, species, isEventLegal))
switch (CanRegisterMonForTradingBoard(*(struct RfuGameCompatibilityData *)GetHostRfuGameData(), species2, species, isEventLegal))
{
case CANT_REGISTER_MON:
StringExpandPlaceholders(gStringVar4, gText_PkmnCantBeTradedNow);
@@ -3548,7 +3548,7 @@ static void CursorCb_Trade1(u8 taskId)
u16 species2 = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES2);
u16 species = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES);
u8 isEventLegal = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_EVENT_LEGAL);
u32 stringId = GetUnionRoomTradeMessageId(*(struct GFtgtGnameSub *)GetHostRFUtgtGname(), gPartnerTgtGnameSub, species2, gUnionRoomOfferedSpecies, gUnionRoomRequestedMonType, species, isEventLegal);
u32 stringId = GetUnionRoomTradeMessageId(*(struct RfuGameCompatibilityData *)GetHostRfuGameData(), gRfuPartnerCompatibilityData, species2, gUnionRoomOfferedSpecies, gUnionRoomRequestedMonType, species, isEventLegal);
if (stringId != UR_TRADE_MSG_NONE)
{

View File

@@ -2202,7 +2202,7 @@ static int GetPlayersAtJumpPeak(void)
static bool32 AreLinkQueuesEmpty(void)
{
return !Rfu.recvQueue.count && !Rfu.sendQueue.count;
return !gRfu.recvQueue.count && !gRfu.sendQueue.count;
}
static int GetNumPlayersForBonus(u8 *arg0)
@@ -3945,7 +3945,7 @@ static bool32 RecvPacket_MonInfo(int multiplayerId, struct PokemonJump_MonInfo *
{
struct MonInfoPacket packet;
if ((gRecvCmds[multiplayerId][0] & 0xFF00) != RFUCMD_SEND_PACKET)
if ((gRecvCmds[multiplayerId][0] & RFUCMD_MASK) != RFUCMD_SEND_PACKET)
return FALSE;
memcpy(&packet, &gRecvCmds[multiplayerId][1], sizeof(packet));
@@ -4010,7 +4010,7 @@ static bool32 RecvPacket_LeaderState(struct PokemonJump_Player *player, struct P
{
struct LeaderStatePacket packet;
if ((gRecvCmds[0][0] & 0xFF00) != RFUCMD_SEND_PACKET)
if ((gRecvCmds[0][0] & RFUCMD_MASK) != RFUCMD_SEND_PACKET)
return FALSE;
memcpy(&packet, &gRecvCmds[0][1], sizeof(packet));
@@ -4057,7 +4057,7 @@ static bool32 RecvPacket_MemberStateToLeader(struct PokemonJump_Player *player,
{
struct MemberStatePacket packet;
if ((gRecvCmds[multiplayerId][0] & 0xFF00) != RFUCMD_SEND_PACKET)
if ((gRecvCmds[multiplayerId][0] & RFUCMD_MASK) != RFUCMD_SEND_PACKET)
return FALSE;
memcpy(&packet, &gRecvCmds[multiplayerId][1], sizeof(packet));
@@ -4078,7 +4078,7 @@ static bool32 RecvPacket_MemberStateToMember(struct PokemonJump_Player *player,
{
struct MemberStatePacket packet;
if ((gRecvCmds[multiplayerId][0] & 0xFF00) != RFUCMD_SEND_PACKET)
if ((gRecvCmds[multiplayerId][0] & RFUCMD_MASK) != RFUCMD_SEND_PACKET)
return FALSE;
memcpy(&packet, &gRecvCmds[multiplayerId][1], sizeof(packet));

View File

@@ -499,7 +499,7 @@ static void Task_SendPacket(u8 taskId)
break;
case 1:
if (GetMultiplayerId() == 0)
SendBlockRequest(1);
SendBlockRequest(BLOCK_REQ_SIZE_200);
task->data[0]++;
break;
case 2:
@@ -981,7 +981,7 @@ static void Task_DoRecordMixing(u8 taskId)
// Mixing Emerald records.
case 6:
if (!sub_801048C(FALSE))
if (!Rfu_SetLinkRecovery(FALSE))
{
CreateTask(Task_LinkSave, 5);
task->data[0]++;
@@ -992,7 +992,7 @@ static void Task_DoRecordMixing(u8 taskId)
{
if (gWirelessCommType)
{
sub_801048C(TRUE);
Rfu_SetLinkRecovery(TRUE);
task->data[0] = 8;
}
else

View File

@@ -8,17 +8,17 @@
#include "overworld.h"
#include "malloc.h"
void sub_81700F8(void)
// Reloads the game, continuing from the point of the last save
// Used to gracefully exit after a link connection error
void ReloadSave(void)
{
u16 imeBackup;
imeBackup = REG_IME;
u16 imeBackup = REG_IME;
REG_IME = 0;
RegisterRamReset(RESET_EWRAM);
ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_FORCED_BLANK);
REG_IME = imeBackup;
gMain.inBattle = FALSE;
SetSaveBlocksPointers(sub_815355C());
SetSaveBlocksPointers(GetSaveBlocksPointersBaseOffset());
ResetMenuAndMonGlobals();
Save_ResetSaveCounters();
Save_LoadGameData(SAVE_NORMAL);

View File

@@ -43,11 +43,12 @@ static u8 HandleWriteSector(u16 a1, const struct SaveSectionLocation *location);
// (u8 *)structure was removed from the first statement of the macro in Emerald.
// This is because malloc is used to allocate addresses so storing the raw
// addresses should not be done in the offsets information.
#define SAVEBLOCK_CHUNK(structure, chunkNum) \
{ \
chunkNum * SECTOR_DATA_SIZE, \
min(sizeof(structure) - chunkNum * SECTOR_DATA_SIZE, SECTOR_DATA_SIZE) \
} \
#define SAVEBLOCK_CHUNK(structure, chunkNum) \
{ \
chunkNum * SECTOR_DATA_SIZE, \
sizeof(structure) >= chunkNum * SECTOR_DATA_SIZE ? \
min(sizeof(structure) - chunkNum * SECTOR_DATA_SIZE, SECTOR_DATA_SIZE) : 0 \
}
static const struct SaveSectionOffsets sSaveSectionOffsets[] =
{
@@ -126,16 +127,16 @@ static bool32 SetDamagedSectorBits(u8 op, u8 bit)
return retVal;
}
static u8 SaveWriteToFlash(u16 a1, const struct SaveSectionLocation *location)
static u8 SaveWriteToFlash(u16 sectorId, const struct SaveSectionLocation *location)
{
u32 status;
u16 i;
gFastSaveSection = &gSaveDataBuffer;
if (a1 != 0xFFFF) // for link
if (sectorId != 0xFFFF) // for link
{
status = HandleWriteSector(a1, location);
status = HandleWriteSector(sectorId, location);
}
else
{
@@ -169,7 +170,7 @@ static u8 HandleWriteSector(u16 sectorId, const struct SaveSectionLocation *loca
sector = sectorId + gLastWrittenSector;
sector %= SECTOR_SAVE_SLOT_LENGTH;
sector += SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % 2);
sector += SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % NUM_SAVE_SLOTS);
data = location[sectorId].data;
size = location[sectorId].size;
@@ -292,7 +293,7 @@ static u8 ClearSaveData_2(u16 sectorId, const struct SaveSectionLocation *locati
sector = sectorId + gLastWrittenSector;
sector %= SECTOR_SAVE_SLOT_LENGTH;
sector += SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % 2);
sector += SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % NUM_SAVE_SLOTS);
data = location[sectorId].data;
size = location[sectorId].size;
@@ -362,7 +363,7 @@ static u8 sav12_xor_get(u16 sectorId, const struct SaveSectionLocation *location
sector = sectorId + gLastWrittenSector; // no sub 1?
sector %= SECTOR_SAVE_SLOT_LENGTH;
sector += SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % 2);
sector += SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % NUM_SAVE_SLOTS);
if (ProgramFlashByte(sector, sizeof(struct UnkSaveSection), 0x25))
{
@@ -385,7 +386,7 @@ static u8 sub_8152CAC(u16 sectorId, const struct SaveSectionLocation *location)
sector = sectorId + gLastWrittenSector - 1;
sector %= SECTOR_SAVE_SLOT_LENGTH;
sector += SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % 2);
sector += SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % NUM_SAVE_SLOTS);
if (ProgramFlashByte(sector, sizeof(struct UnkSaveSection), ((u8 *)gFastSaveSection)[sizeof(struct UnkSaveSection)]))
{
@@ -408,7 +409,7 @@ static u8 sub_8152D44(u16 sectorId, const struct SaveSectionLocation *location)
sector = sectorId + gLastWrittenSector - 1; // no sub 1?
sector %= SECTOR_SAVE_SLOT_LENGTH;
sector += SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % 2);
sector += SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % NUM_SAVE_SLOTS);
if (ProgramFlashByte(sector, sizeof(struct UnkSaveSection), 0x25))
{
@@ -446,12 +447,12 @@ static u8 sub_8152E10(u16 a1, const struct SaveSectionLocation *location)
{
u16 i;
u16 checksum;
u16 v3 = SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % 2);
u16 slotOffset = SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % NUM_SAVE_SLOTS);
u16 id;
for (i = 0; i < SECTOR_SAVE_SLOT_LENGTH; i++)
{
DoReadFlashWholeSection(i + v3, gFastSaveSection);
DoReadFlashWholeSection(i + slotOffset, gFastSaveSection);
id = gFastSaveSection->id;
if (id == 0)
gLastWrittenSector = i;
@@ -824,27 +825,29 @@ u8 Save_LoadGameData(u8 saveType)
return status;
}
u16 sub_815355C(void)
u16 GetSaveBlocksPointersBaseOffset(void)
{
u16 i, v3;
u16 i, slotOffset;
struct SaveSection* savSection;
savSection = gFastSaveSection = &gSaveDataBuffer;
if (gFlashMemoryPresent != TRUE)
return SAVE_STATUS_EMPTY;
return 0;
UpdateSaveAddresses();
GetSaveValidStatus(gRamSaveSectionLocations);
v3 = SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % 2);
slotOffset = SECTOR_SAVE_SLOT_LENGTH * (gSaveCounter % NUM_SAVE_SLOTS);
for (i = 0; i < SECTOR_SAVE_SLOT_LENGTH; i++)
{
DoReadFlashWholeSection(i + v3, gFastSaveSection);
if (gFastSaveSection->id == 0)
return savSection->data[10] +
savSection->data[11] +
savSection->data[12] +
savSection->data[13];
DoReadFlashWholeSection(i + slotOffset, gFastSaveSection);
// Base offset for SaveBlock2 is calculated using the trainer id
if (gFastSaveSection->id == SECTOR_ID_SAVEBLOCK2)
return savSection->data[offsetof(struct SaveBlock2, playerTrainerId[0])] +
savSection->data[offsetof(struct SaveBlock2, playerTrainerId[1])] +
savSection->data[offsetof(struct SaveBlock2, playerTrainerId[2])] +
savSection->data[offsetof(struct SaveBlock2, playerTrainerId[3])];
}
return SAVE_STATUS_EMPTY;
return 0;
}
u32 TryReadSpecialSaveSection(u8 sector, u8* dst)

View File

@@ -274,7 +274,7 @@ static bool32 IsLinkTradeTaskFinished(void)
{
if (gPlayerCurrActivity == ACTIVITY_29)
{
if (gRfuSlotStatusNI[sub_800E87C(lman.acceptSlot_flag)]->send.state == 0)
if (gRfuSlotStatusNI[Rfu_GetIndexOfNewestChild(lman.acceptSlot_flag)]->send.state == 0)
return TRUE;
else
return FALSE;
@@ -459,7 +459,7 @@ static void CB2_CreateTradeMenu(void)
sTradeMenuData->timer = 0;
if (gWirelessCommType)
{
sub_801048C(TRUE);
Rfu_SetLinkRecovery(TRUE);
SetLinkStandbyCallback();
}
}
@@ -1008,9 +1008,7 @@ static bool8 BufferTradeParties(void)
break;
case 3:
if (id == 0)
{
RequestLinkData(1);
}
RequestLinkData(BLOCK_REQ_SIZE_200);
sTradeMenuData->bufferPartyState++;
break;
case 4:
@@ -1027,9 +1025,7 @@ static bool8 BufferTradeParties(void)
break;
case 7:
if (id == 0)
{
RequestLinkData(1);
}
RequestLinkData(BLOCK_REQ_SIZE_200);
sTradeMenuData->bufferPartyState++;
break;
case 8:
@@ -1046,9 +1042,7 @@ static bool8 BufferTradeParties(void)
break;
case 11:
if (id == 0)
{
RequestLinkData(1);
}
RequestLinkData(BLOCK_REQ_SIZE_200);
sTradeMenuData->bufferPartyState++;
break;
case 12:
@@ -1065,9 +1059,7 @@ static bool8 BufferTradeParties(void)
break;
case 15:
if (id == 0)
{
RequestLinkData(3);
}
RequestLinkData(BLOCK_REQ_SIZE_220);
sTradeMenuData->bufferPartyState++;
break;
case 16:
@@ -1084,9 +1076,7 @@ static bool8 BufferTradeParties(void)
break;
case 19:
if (id == 0)
{
RequestLinkData(4);
}
RequestLinkData(BLOCK_REQ_SIZE_40);
sTradeMenuData->bufferPartyState++;
break;
case 20:
@@ -1719,7 +1709,7 @@ static void CancelTrade_2(void)
static void LinkTradeWaitForQueue(void)
{
if (!sub_801048C(FALSE) && GetNumQueuedActions() == 0)
if (!Rfu_SetLinkRecovery(FALSE) && GetNumQueuedActions() == 0)
{
SetLinkStandbyCallback();
sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_START_LINK_TRADE;
@@ -2448,80 +2438,70 @@ static bool32 IsDeoxysOrMewUntradable(u16 species, bool8 isEventLegal)
return FALSE;
}
int GetUnionRoomTradeMessageId(struct GFtgtGnameSub rfuPlayer, struct GFtgtGnameSub rfuPartner, u16 playerSpecies2, u16 partnerSpecies, u8 requestedType, u16 playerSpecies, u8 isEventLegal)
int GetUnionRoomTradeMessageId(struct RfuGameCompatibilityData player, struct RfuGameCompatibilityData partner, u16 playerSpecies2, u16 partnerSpecies, u8 requestedType, u16 playerSpecies, u8 isEventLegal)
{
bool8 playerHasNationalDex = rfuPlayer.hasNationalDex;
bool8 playerIsChampion = rfuPlayer.isChampion;
bool8 partnerHasNationalDex = rfuPartner.hasNationalDex;
bool8 partnerIsChampion = rfuPartner.isChampion;
u8 r1 = rfuPartner.version;
bool8 playerHasNationalDex = player.hasNationalDex;
bool8 playerIsChampion = player.isChampion;
bool8 partnerHasNationalDex = partner.hasNationalDex;
bool8 partnerIsChampion = partner.isChampion;
u8 partnerVersion = partner.version;
if (r1 != VERSION_EMERALD)
// If partner is not using Emerald, both players must be champion
if (partnerVersion != VERSION_EMERALD)
{
if (!playerIsChampion)
{
return UR_TRADE_MSG_CANT_TRADE_WITH_PARTNER_1;
}
else if (!partnerIsChampion)
{
return UR_TRADE_MSG_CANT_TRADE_WITH_PARTNER_2;
}
}
// Cannot trade illegitimate Deoxys/Mew
if (IsDeoxysOrMewUntradable(playerSpecies, isEventLegal))
{
return UR_TRADE_MSG_MON_CANT_BE_TRADED_2;
}
if (partnerSpecies == SPECIES_EGG)
{
// If partner is trading an Egg then the player must also be trading an Egg
if (playerSpecies2 != partnerSpecies)
{
return UR_TRADE_MSG_NOT_EGG;
}
}
else
{
if (gBaseStats[playerSpecies2].type1 != requestedType && gBaseStats[playerSpecies2].type2 != requestedType)
{
// Player's Pokémon must be of the type the partner requested
if (gBaseStats[playerSpecies2].type1 != requestedType
&& gBaseStats[playerSpecies2].type2 != requestedType)
return UR_TRADE_MSG_NOT_MON_PARTNER_WANTS;
}
}
// If the player is trading an Egg then the partner must also be trading an Egg
// Odd that this wasn't checked earlier, as by this point we know either the partner doesn't have an Egg or that both do.
if (playerSpecies2 == SPECIES_EGG && playerSpecies2 != partnerSpecies)
{
return UR_TRADE_MSG_MON_CANT_BE_TRADED_1;
}
// If the player doesn't have the National Dex then Eggs and non-Hoenn Pokémon can't be traded
if (!playerHasNationalDex)
{
if (playerSpecies2 == SPECIES_EGG)
{
return UR_TRADE_MSG_EGG_CANT_BE_TRADED;
}
if (!IsSpeciesInHoennDex(playerSpecies2))
{
return UR_TRADE_MSG_MON_CANT_BE_TRADED_2;
}
if (!IsSpeciesInHoennDex(partnerSpecies))
{
return UR_TRADE_MSG_PARTNERS_MON_CANT_BE_TRADED;
}
}
// If the partner doesn't have the National Dex then the player's offer has to be a Hoenn Pokémon
if (!partnerHasNationalDex && !IsSpeciesInHoennDex(playerSpecies2))
{
return UR_TRADE_MSG_PARTNER_CANT_ACCEPT_MON;
}
// Trade is allowed
return UR_TRADE_MSG_NONE;
}
int CanRegisterMonForTradingBoard(struct GFtgtGnameSub rfuPlayer, u16 species2, u16 species, u8 isEventLegal)
int CanRegisterMonForTradingBoard(struct RfuGameCompatibilityData player, u16 species2, u16 species, u8 isEventLegal)
{
bool8 hasNationalDex = rfuPlayer.hasNationalDex;
bool8 hasNationalDex = player.hasNationalDex;
if (IsDeoxysOrMewUntradable(species, isEventLegal))
return CANT_REGISTER_MON;
@@ -2551,9 +2531,7 @@ int CanSpinTradeMon(struct Pokemon *mon, u16 monIdx)
{
speciesArray[i] = GetMonData(&mon[i], MON_DATA_SPECIES2);
if (speciesArray[i] == SPECIES_EGG)
{
speciesArray[i] = SPECIES_NONE;
}
}
versions = 0;
@@ -2563,13 +2541,9 @@ int CanSpinTradeMon(struct Pokemon *mon, u16 monIdx)
version = gLinkPlayers[i].version & 0xFF;
if (version == VERSION_FIRE_RED ||
version == VERSION_LEAF_GREEN)
{
versions = 0;
}
else
{
versions |= 1;
}
}
for (i = 0; i < GetLinkPlayerCount(); i++)
@@ -2600,9 +2574,7 @@ int CanSpinTradeMon(struct Pokemon *mon, u16 monIdx)
for (i = 0; i < gPlayerPartyCount; i++)
{
if (monIdx != i)
{
numMonsLeft += speciesArray[i];
}
}
if (!numMonsLeft)
@@ -3096,7 +3068,7 @@ static void TrySendTradeFinishData(void)
case 1:
if (IsLinkTaskFinished())
{
SendBlock(bitmask_all_link_players_but_self(), sTradeData->linkData, sizeof(sTradeData->linkData));
SendBlock(BitmaskAllOtherLinkPlayers(), sTradeData->linkData, sizeof(sTradeData->linkData));
sTradeData->sendTradeFinishState++;
}
// fallthrough
@@ -4632,7 +4604,7 @@ static void CB2_TryFinishTrade(void)
&& sTradeData->partnerLinkFlagFinishTrade == READY_FINISH_TRADE)
{
sTradeData->linkData[0] = LINKCMD_CONFIRM_FINISH_TRADE;
SendBlock(bitmask_all_link_players_but_self(), sTradeData->linkData, sizeof(sTradeData->linkData));
SendBlock(BitmaskAllOtherLinkPlayers(), sTradeData->linkData, sizeof(sTradeData->linkData));
sTradeData->playerLinkFlagFinishTrade = FINISH_TRADE;
sTradeData->partnerLinkFlagFinishTrade = FINISH_TRADE;
}

File diff suppressed because it is too large Load Diff

View File

@@ -997,7 +997,7 @@ static void Chat_Join(void)
sChat->funcState++;
// fall through
case 1:
if (IsLinkTaskFinished() && !sub_8011A9C())
if (IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive())
{
if (SendBlock(0, sChat->sendMessageBuffer, sizeof(sChat->sendMessageBuffer)))
sChat->funcState++;
@@ -1198,7 +1198,7 @@ static void Chat_AskQuitChatting(void)
sChat->funcState = 3;
break;
case 0:
sub_80104B0();
Rfu_StopPartnerSearch();
PrepareSendBuffer_Disband(sChat->sendMessageBuffer);
sChat->funcState = 4;
sChat->tryQuitAgainTimer = 0;
@@ -1206,7 +1206,7 @@ static void Chat_AskQuitChatting(void)
}
break;
case 4:
if (IsLinkTaskFinished() && !sub_8011A9C() && SendBlock(0, sChat->sendMessageBuffer, sizeof(sChat->sendMessageBuffer)))
if (IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive() && SendBlock(0, sChat->sendMessageBuffer, sizeof(sChat->sendMessageBuffer)))
{
if (!sChat->multiplayerId)
sChat->funcState = 6;
@@ -1257,15 +1257,15 @@ static void Chat_Exit(void)
}
break;
case 3:
if (IsLinkTaskFinished() && !sub_8011A9C() && SendBlock(0, sChat->sendMessageBuffer, sizeof(sChat->sendMessageBuffer)))
if (IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive() && SendBlock(0, sChat->sendMessageBuffer, sizeof(sChat->sendMessageBuffer)))
sChat->funcState++;
break;
case 4:
if ((GetBlockReceivedStatus() & 1) && !sub_8011A9C())
if ((GetBlockReceivedStatus() & 1) && !Rfu_IsPlayerExchangeActive())
sChat->funcState++;
break;
case 5:
if (IsLinkTaskFinished() && !sub_8011A9C())
if (IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive())
{
SetCloseLinkCallback();
sChat->exitDelayTimer = 0;
@@ -1300,7 +1300,7 @@ static void Chat_Drop(void)
}
break;
case 1:
if (!IsDisplaySubtaskActive(0) && IsLinkTaskFinished() && !sub_8011A9C())
if (!IsDisplaySubtaskActive(0) && IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive())
{
SetCloseLinkCallback();
sChat->exitDelayTimer = 0;
@@ -1346,7 +1346,7 @@ static void Chat_Disbanded(void)
}
break;
case 2:
if (IsDisplaySubtaskActive(0) != TRUE && IsLinkTaskFinished() && !sub_8011A9C())
if (IsDisplaySubtaskActive(0) != TRUE && IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive())
{
SetCloseLinkCallback();
sChat->exitDelayTimer = 0;
@@ -1384,7 +1384,7 @@ static void Chat_SendMessage(void)
sChat->funcState++;
// fall through
case 1:
if (IsLinkTaskFinished() == TRUE && !sub_8011A9C() && SendBlock(0, sChat->sendMessageBuffer, sizeof(sChat->sendMessageBuffer)))
if (IsLinkTaskFinished() == TRUE && !Rfu_IsPlayerExchangeActive() && SendBlock(0, sChat->sendMessageBuffer, sizeof(sChat->sendMessageBuffer)))
sChat->funcState++;
break;
case 2:
@@ -1819,7 +1819,7 @@ static void PrepareSendBuffer_Leave(u8 *buffer)
buffer[0] = CHAT_MESSAGE_LEAVE;
StringCopy(&buffer[1], gSaveBlock2Ptr->playerName);
buffer[1 + (PLAYER_NAME_LENGTH + 1)] = sChat->multiplayerId;
sub_8011A50();
RfuSetNormalDisconnectMode();
}
static void PrepareSendBuffer_Drop(u8 *buffer)
@@ -2028,7 +2028,7 @@ static void Task_ReceiveChatMessage(u8 taskId)
}
tBlockReceivedStatus = GetBlockReceivedStatus();
if (!tBlockReceivedStatus && sub_8011A9C())
if (!tBlockReceivedStatus && Rfu_IsPlayerExchangeActive())
return;
tI = 0;
@@ -2079,13 +2079,12 @@ static void Task_ReceiveChatMessage(u8 taskId)
{
if (GetLinkPlayerCount() == 2)
{
sub_80104B0();
Rfu_StopPartnerSearch();
sChat->exitType = 1;
DestroyTask(taskId);
return;
}
sub_8011DE0(tCurrLinkPlayer);
Rfu_DisconnectPlayerById(tCurrLinkPlayer);
}
tState = 3;
@@ -2101,10 +2100,10 @@ static void Task_ReceiveChatMessage(u8 taskId)
DestroyTask(taskId);
break;
case 2:
if (!sub_8011A9C())
if (!Rfu_IsPlayerExchangeActive())
{
if (!sChat->multiplayerId)
sub_80110B8(sChat->linkPlayerCount);
SetUnionRoomChatPlayerData(sChat->linkPlayerCount);
tState = 1;
}

View File

@@ -9,8 +9,12 @@
#include "constants/event_objects.h"
#include "constants/event_object_movement.h"
#define UR_SPRITE_START_ID (MAX_SPRITES - MAX_UNION_ROOM_PLAYERS)
#define UR_PLAYER_SPRITE_ID(playerIdx, facingDir)(5 * playerIdx + facingDir)
#define UR_SPRITE_START_ID (MAX_SPRITES - MAX_UNION_ROOM_LEADERS)
// Each parent player can lead a group of up to MAX_RFU_PLAYERS (including themselves).
// Multiply the leader's id by MAX_RFU_PLAYERS and add the member's id (0 if the leader) to
// get the sprite index of that player.
#define UR_PLAYER_SPRITE_ID(leaderId, memberId)(MAX_RFU_PLAYERS * leaderId + memberId)
static EWRAM_DATA struct UnionRoomObject * sUnionObjWork = NULL;
static EWRAM_DATA u32 sUnionObjRefreshTimer = 0;
@@ -19,7 +23,8 @@ static u8 CreateTask_AnimateUnionRoomPlayers(void);
static u32 IsUnionRoomPlayerInvisible(u32, u32);
static void SetUnionRoomObjectFacingDirection(s32, s32, u8);
static const u8 sUnionRoomObjGfxIds[GENDER_COUNT][MAX_UNION_ROOM_PLAYERS + 2] = {
// + 2 is just to match, those elements are empty and never read
static const u8 sUnionRoomObjGfxIds[GENDER_COUNT][MAX_UNION_ROOM_LEADERS + 2] = {
[MALE] = {
OBJ_EVENT_GFX_MAN_3,
OBJ_EVENT_GFX_BLACK_BELT,
@@ -42,7 +47,7 @@ static const u8 sUnionRoomObjGfxIds[GENDER_COUNT][MAX_UNION_ROOM_PLAYERS + 2] =
}
};
static const s16 sUnionRoomPlayerCoords[MAX_UNION_ROOM_PLAYERS][2] = {
static const s16 sUnionRoomPlayerCoords[MAX_UNION_ROOM_LEADERS][2] = {
{ 4, 6},
{13, 8},
{10, 6},
@@ -53,12 +58,16 @@ static const s16 sUnionRoomPlayerCoords[MAX_UNION_ROOM_PLAYERS][2] = {
{ 7, 8}
};
static const s8 sFacingDirectionOffsets[][2] = {
[DIR_NONE] = { 0, 0},
[DIR_SOUTH] = { 1, 0},
[DIR_NORTH] = { 0, -1},
[DIR_WEST] = {-1, 0},
[DIR_EAST] = { 0, 1}
// If there's a group of players interacting in the Union Room, the group
// leader will be at one of the positions above and each member in the group
// will be at one of the offsets from that position below. The leader will
// be at the first offset (0,0), as they're at the center.
static const s8 sUnionRoomGroupOffsets[MAX_RFU_PLAYERS][2] = {
{ 0, 0}, // Center
{ 1, 0}, // Left
{ 0, -1}, // Top
{-1, 0}, // Right
{ 0, 1} // Bottom
};
static const u8 sOppositeFacingDirection[] = {
@@ -69,12 +78,14 @@ static const u8 sOppositeFacingDirection[] = {
[DIR_EAST] = DIR_WEST
};
static const u8 sNextFacingDirection[] = {
[DIR_NONE] = DIR_SOUTH,
[DIR_SOUTH] = DIR_WEST,
[DIR_NORTH] = DIR_SOUTH,
[DIR_WEST] = DIR_EAST,
[DIR_EAST] = DIR_NORTH
// Compare to sUnionRoomGroupOffsets, the direction each group member
// needs to be facing in order to face the group leader in the center.
static const u8 sMemberFacingDirections[MAX_RFU_PLAYERS] = {
DIR_SOUTH, // Leader, but never read
DIR_WEST,
DIR_SOUTH,
DIR_EAST,
DIR_NORTH
};
static const u8 sUnionRoomLocalIds[] = {
@@ -118,21 +129,22 @@ static bool32 IsPlayerStandingStill(void)
return FALSE;
}
// Gender and trainer id are used to determine which sprite a player appears as
static u8 GetUnionRoomPlayerGraphicsId(u32 gender, u32 id)
{
return sUnionRoomObjGfxIds[gender][id % MAX_UNION_ROOM_PLAYERS];
return sUnionRoomObjGfxIds[gender][id % MAX_UNION_ROOM_LEADERS];
}
static void GetUnionRoomPlayerFacingCoords(u32 playerIdx, u32 direction, s32 * x, s32 * y)
static void GetUnionRoomPlayerCoords(u32 leaderId, u32 memberId, s32 * x, s32 * y)
{
*x = sUnionRoomPlayerCoords[playerIdx][0] + sFacingDirectionOffsets[direction][0] + 7;
*y = sUnionRoomPlayerCoords[playerIdx][1] + sFacingDirectionOffsets[direction][1] + 7;
*x = sUnionRoomPlayerCoords[leaderId][0] + sUnionRoomGroupOffsets[memberId][0] + 7;
*y = sUnionRoomPlayerCoords[leaderId][1] + sUnionRoomGroupOffsets[memberId][1] + 7;
}
static bool32 IsUnionRoomPlayerFacingTileAt(u32 playerIdx, u32 direction, s32 x, s32 y)
static bool32 IsUnionRoomPlayerAt(u32 leaderId, u32 memberId, s32 x, s32 y)
{
if ((sUnionRoomPlayerCoords[playerIdx][0] + sFacingDirectionOffsets[direction][0] + 7 == x)
&& (sUnionRoomPlayerCoords[playerIdx][1] + sFacingDirectionOffsets[direction][1] + 7 == y))
if ((sUnionRoomPlayerCoords[leaderId][0] + sUnionRoomGroupOffsets[memberId][0] + 7 == x)
&& (sUnionRoomPlayerCoords[leaderId][1] + sUnionRoomGroupOffsets[memberId][1] + 7 == y))
return TRUE;
else
return FALSE;
@@ -153,62 +165,50 @@ static void ShowUnionRoomPlayer(u32 player_idx)
FlagClear(FLAG_HIDE_UNION_ROOM_PLAYER_1 + player_idx);
}
static void SetUnionRoomPlayerGfx(u32 playerIdx, u32 gfxId)
static void SetUnionRoomPlayerGfx(u32 leaderId, u32 gfxId)
{
VarSet(VAR_OBJ_GFX_ID_0 + playerIdx, gfxId);
VarSet(VAR_OBJ_GFX_ID_0 + leaderId, gfxId);
}
static void CreateUnionRoomPlayerObjectEvent(u32 playerIdx)
static void CreateUnionRoomPlayerObjectEvent(u32 leaderId)
{
TrySpawnObjectEvent(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
TrySpawnObjectEvent(sUnionRoomLocalIds[leaderId], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
}
static void RemoveUnionRoomPlayerObjectEvent(u32 playerIdx)
static void RemoveUnionRoomPlayerObjectEvent(u32 leaderId)
{
RemoveObjectEventByLocalIdAndMap(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
RemoveObjectEventByLocalIdAndMap(sUnionRoomLocalIds[leaderId], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
}
static bool32 SetUnionRoomPlayerEnterExitMovement(u32 playerIdx, const u8 * movement)
static bool32 SetUnionRoomPlayerEnterExitMovement(u32 leaderId, const u8 * movement)
{
u8 objectId;
struct ObjectEvent * object;
if (TryGetObjectEventIdByLocalIdAndMap(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectId))
{
if (TryGetObjectEventIdByLocalIdAndMap(sUnionRoomLocalIds[leaderId], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectId))
return FALSE;
}
object = &gObjectEvents[objectId];
if (ObjectEventIsMovementOverridden(object))
{
return FALSE;
}
if (ObjectEventSetHeldMovement(object, *movement))
{
return FALSE;
}
return TRUE;
}
static bool32 TryReleaseUnionRoomPlayerObjectEvent(u32 playerIdx)
static bool32 TryReleaseUnionRoomPlayerObjectEvent(u32 leaderId)
{
u8 objectId;
struct ObjectEvent * object;
if (TryGetObjectEventIdByLocalIdAndMap(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectId))
{
if (TryGetObjectEventIdByLocalIdAndMap(sUnionRoomLocalIds[leaderId], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectId))
return TRUE;
}
object = &gObjectEvents[objectId];
if (!ObjectEventClearHeldMovementIfFinished(object))
{
return FALSE;
}
if (!ScriptContext2_IsEnabled())
{
UnfreezeObjectEvent(object);
}
else
{
FreezeObjectEvent(object);
}
return TRUE;
}
@@ -218,7 +218,7 @@ u8 InitUnionRoomPlayerObjects(struct UnionRoomObject * players)
sUnionObjRefreshTimer = 0;
sUnionObjWork = players;
for (i = 0; i < MAX_UNION_ROOM_PLAYERS; i++)
for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++)
{
players[i].state = 0;
players[i].gfxId = 0;
@@ -228,22 +228,22 @@ u8 InitUnionRoomPlayerObjects(struct UnionRoomObject * players)
return CreateTask_AnimateUnionRoomPlayers();
}
static bool32 AnimateUnionRoomPlayerDespawn(s8 * state, u32 playerIdx, struct UnionRoomObject * ptr)
static bool32 AnimateUnionRoomPlayerDespawn(s8 * state, u32 leaderId, struct UnionRoomObject * object)
{
switch (*state)
{
case 0:
if (SetUnionRoomPlayerEnterExitMovement(playerIdx, sMovement_UnionPlayerExit) == TRUE)
if (SetUnionRoomPlayerEnterExitMovement(leaderId, sMovement_UnionPlayerExit) == TRUE)
{
HideUnionRoomPlayer(playerIdx);
HideUnionRoomPlayer(leaderId);
(*state)++;
}
break;
case 1:
if (TryReleaseUnionRoomPlayerObjectEvent(playerIdx))
if (TryReleaseUnionRoomPlayerObjectEvent(leaderId))
{
RemoveUnionRoomPlayerObjectEvent(playerIdx);
HideUnionRoomPlayer(playerIdx);
RemoveUnionRoomPlayerObjectEvent(leaderId);
HideUnionRoomPlayer(leaderId);
*state = 0;
return TRUE;
}
@@ -252,7 +252,7 @@ static bool32 AnimateUnionRoomPlayerDespawn(s8 * state, u32 playerIdx, struct Un
return FALSE;
}
static bool32 AnimateUnionRoomPlayerSpawn(s8 * state, u32 playerIdx, struct UnionRoomObject * ptr)
static bool32 AnimateUnionRoomPlayerSpawn(s8 * state, u32 leaderId, struct UnionRoomObject * object)
{
s16 x, y;
@@ -260,32 +260,24 @@ static bool32 AnimateUnionRoomPlayerSpawn(s8 * state, u32 playerIdx, struct Unio
{
case 0:
if (!IsPlayerStandingStill())
{
break;
}
PlayerGetDestCoords(&x, &y);
if (IsUnionRoomPlayerFacingTileAt(playerIdx, 0, x, y) == TRUE)
{
if (IsUnionRoomPlayerAt(leaderId, 0, x, y) == TRUE)
break;
}
player_get_pos_including_state_based_drift(&x, &y);
if (IsUnionRoomPlayerFacingTileAt(playerIdx, 0, x, y) == TRUE)
{
if (IsUnionRoomPlayerAt(leaderId, 0, x, y) == TRUE)
break;
}
SetUnionRoomPlayerGfx(playerIdx, ptr->gfxId);
CreateUnionRoomPlayerObjectEvent(playerIdx);
ShowUnionRoomPlayer(playerIdx);
SetUnionRoomPlayerGfx(leaderId, object->gfxId);
CreateUnionRoomPlayerObjectEvent(leaderId);
ShowUnionRoomPlayer(leaderId);
(*state)++;
// fallthrough
case 3: // incorrect?
if (SetUnionRoomPlayerEnterExitMovement(playerIdx, sMovement_UnionPlayerEnter) == TRUE)
{
if (SetUnionRoomPlayerEnterExitMovement(leaderId, sMovement_UnionPlayerEnter) == TRUE)
(*state)++;
}
break;
case 2:
if (TryReleaseUnionRoomPlayerObjectEvent(playerIdx))
if (TryReleaseUnionRoomPlayerObjectEvent(leaderId))
{
*state = 0;
return TRUE;
@@ -295,38 +287,38 @@ static bool32 AnimateUnionRoomPlayerSpawn(s8 * state, u32 playerIdx, struct Unio
return FALSE;
}
static bool32 SpawnGroupLeader(u32 playerIdx, u32 gender, u32 id)
static bool32 SpawnGroupLeader(u32 leaderId, u32 gender, u32 id)
{
struct UnionRoomObject * ptr = &sUnionObjWork[playerIdx];
ptr->schedAnim = UNION_ROOM_SPAWN_IN;
ptr->gfxId = GetUnionRoomPlayerGraphicsId(gender, id);
struct UnionRoomObject * object = &sUnionObjWork[leaderId];
object->schedAnim = UNION_ROOM_SPAWN_IN;
object->gfxId = GetUnionRoomPlayerGraphicsId(gender, id);
if (ptr->state == 0)
if (object->state == 0)
return TRUE;
else
return FALSE;
}
static bool32 DespawnGroupLeader(u32 playerIdx)
static bool32 DespawnGroupLeader(u32 leaderId)
{
struct UnionRoomObject * ptr = &sUnionObjWork[playerIdx];
ptr->schedAnim = UNION_ROOM_SPAWN_OUT;
struct UnionRoomObject * object = &sUnionObjWork[leaderId];
object->schedAnim = UNION_ROOM_SPAWN_OUT;
if (ptr->state == 1)
if (object->state == 1)
return TRUE;
else
return FALSE;
}
static void AnimateUnionRoomPlayer(u32 playerIdx, struct UnionRoomObject * ptr)
static void AnimateUnionRoomPlayer(u32 leaderId, struct UnionRoomObject * object)
{
switch (ptr->state)
switch (object->state)
{
case 0:
if (ptr->schedAnim == UNION_ROOM_SPAWN_IN)
if (object->schedAnim == UNION_ROOM_SPAWN_IN)
{
ptr->state = 2;
ptr->animState = 0;
object->state = 2;
object->animState = 0;
}
else
{
@@ -334,23 +326,23 @@ static void AnimateUnionRoomPlayer(u32 playerIdx, struct UnionRoomObject * ptr)
}
// fallthrough
case 2:
if (!IsUnionRoomPlayerInvisible(playerIdx, 0) && ptr->schedAnim == UNION_ROOM_SPAWN_OUT)
if (!IsUnionRoomPlayerInvisible(leaderId, 0) && object->schedAnim == UNION_ROOM_SPAWN_OUT)
{
ptr->state = 0;
ptr->animState = 0;
RemoveUnionRoomPlayerObjectEvent(playerIdx);
HideUnionRoomPlayer(playerIdx);
object->state = 0;
object->animState = 0;
RemoveUnionRoomPlayerObjectEvent(leaderId);
HideUnionRoomPlayer(leaderId);
}
else if (AnimateUnionRoomPlayerSpawn(&ptr->animState, playerIdx, ptr) == TRUE)
else if (AnimateUnionRoomPlayerSpawn(&object->animState, leaderId, object) == TRUE)
{
ptr->state = 1;
object->state = 1;
}
break;
case 1:
if (ptr->schedAnim == UNION_ROOM_SPAWN_OUT)
if (object->schedAnim == UNION_ROOM_SPAWN_OUT)
{
ptr->state = 3;
ptr->animState = 0;
object->state = 3;
object->animState = 0;
}
else
{
@@ -358,19 +350,17 @@ static void AnimateUnionRoomPlayer(u32 playerIdx, struct UnionRoomObject * ptr)
}
// fallthrough
case 3:
if (AnimateUnionRoomPlayerDespawn(&ptr->animState, playerIdx, ptr) == 1)
{
ptr->state = 0;
}
if (AnimateUnionRoomPlayerDespawn(&object->animState, leaderId, object) == 1)
object->state = 0;
break;
}
ptr->schedAnim = UNION_ROOM_SPAWN_NONE;
object->schedAnim = UNION_ROOM_SPAWN_NONE;
}
static void Task_AnimateUnionRoomPlayers(u8 taskId)
{
s32 i;
for (i = 0; i < MAX_UNION_ROOM_PLAYERS; i++)
for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++)
AnimateUnionRoomPlayer(i, &sUnionObjWork[i]);
}
@@ -386,15 +376,13 @@ static void DestroyTask_AnimateUnionRoomPlayers(void)
{
u8 taskId = FindTaskIdByFunc(Task_AnimateUnionRoomPlayers);
if (taskId < NUM_TASKS)
{
DestroyTask(taskId);
}
}
void DestroyUnionRoomPlayerObjects(void)
{
s32 i;
for (i = 0; i < MAX_UNION_ROOM_PLAYERS; i++)
for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++)
{
if (!IsUnionRoomPlayerHidden(i))
{
@@ -406,120 +394,119 @@ void DestroyUnionRoomPlayerObjects(void)
DestroyTask_AnimateUnionRoomPlayers();
}
void CreateGroupMemberSpritesInvisible(u8 * spriteIds, s32 playerIdx)
void CreateUnionRoomPlayerSprites(u8 * spriteIds, s32 leaderId)
{
s32 direction;
for (direction = DIR_NONE; direction <= DIR_EAST; direction++)
s32 memberId;
for (memberId = 0; memberId < MAX_RFU_PLAYERS; memberId++)
{
s32 id = UR_PLAYER_SPRITE_ID(playerIdx, direction);
s32 id = UR_PLAYER_SPRITE_ID(leaderId, memberId);
spriteIds[id] = CreateObjectSprite(OBJ_EVENT_GFX_MAN_4,
id - UR_SPRITE_START_ID,
sUnionRoomPlayerCoords[playerIdx][0] + sFacingDirectionOffsets[direction][0],
sUnionRoomPlayerCoords[playerIdx][1] + sFacingDirectionOffsets[direction][1],
sUnionRoomPlayerCoords[leaderId][0] + sUnionRoomGroupOffsets[memberId][0],
sUnionRoomPlayerCoords[leaderId][1] + sUnionRoomGroupOffsets[memberId][1],
3, 1);
SetObjectEventSpriteInvisibility(id - UR_SPRITE_START_ID, TRUE);
}
}
void DestroyGroupMemberSprites(u8 * spriteIds)
void DestroyUnionRoomPlayerSprites(u8 * spriteIds)
{
s32 i;
for (i = 0; i < UR_PLAYER_SPRITE_ID(MAX_UNION_ROOM_PLAYERS, 0); i++)
for (i = 0; i < NUM_UNION_ROOM_SPRITES; i++)
DestroySprite(&gSprites[spriteIds[i]]);
}
// Clear the impassable metatiles around the group leaders that get set
// to prevent the player from walking through the group member sprites.
void SetTilesAroundUnionRoomPlayersPassable(void)
{
s32 i, direction, x, y;
for (i = 0; i < MAX_UNION_ROOM_PLAYERS; i++)
s32 i, memberId, x, y;
for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++)
{
for (direction = DIR_NONE; direction <= DIR_EAST; direction++)
for (memberId = 0; memberId < MAX_RFU_PLAYERS; memberId++)
{
GetUnionRoomPlayerFacingCoords(i, direction, &x, &y);
GetUnionRoomPlayerCoords(i, memberId, &x, &y);
MapGridSetMetatileImpassabilityAt(x, y, FALSE);
}
}
}
static u8 GetNewFacingDirectionForUnionRoomPlayer(u32 direction, u32 playerIdx, struct GFtgtGname * gname)
static u8 GetNewFacingDirectionForUnionRoomPlayer(u32 memberId, u32 leaderId, struct RfuGameData * gameData)
{
if (direction != DIR_NONE)
return sNextFacingDirection[direction];
else if (gname->activity == (ACTIVITY_CHAT | IN_UNION_ROOM))
if (memberId) // If not leader
return sMemberFacingDirections[memberId];
else if (gameData->activity == (ACTIVITY_CHAT | IN_UNION_ROOM))
return DIR_SOUTH;
else
return DIR_EAST;
}
static bool32 IsUnionRoomPlayerInvisible(u32 playerIdx, u32 direction)
static bool32 IsUnionRoomPlayerInvisible(u32 leaderId, u32 memberId)
{
return IsObjectEventSpriteInvisible(UR_PLAYER_SPRITE_ID(playerIdx, direction) - UR_SPRITE_START_ID);
return IsObjectEventSpriteInvisible(UR_PLAYER_SPRITE_ID(leaderId, memberId) - UR_SPRITE_START_ID);
}
static void SpawnGroupMember(u32 playerIdx, u32 direction, u8 graphicsId, struct GFtgtGname * gname)
static void SpawnGroupMember(u32 leaderId, u32 memberId, u8 graphicsId, struct RfuGameData * gameData)
{
s32 x, y;
s32 id = UR_PLAYER_SPRITE_ID(playerIdx, direction);
if (IsUnionRoomPlayerInvisible(playerIdx, direction) == TRUE)
s32 id = UR_PLAYER_SPRITE_ID(leaderId, memberId);
if (IsUnionRoomPlayerInvisible(leaderId, memberId) == TRUE)
{
SetObjectEventSpriteInvisibility(id - UR_SPRITE_START_ID, FALSE);
SetObjectEventSpriteAnim(id - UR_SPRITE_START_ID, UNION_ROOM_SPAWN_IN);
}
SetObjectEventSpriteGraphics(id - UR_SPRITE_START_ID, graphicsId);
SetUnionRoomObjectFacingDirection(direction, playerIdx, GetNewFacingDirectionForUnionRoomPlayer(direction, playerIdx, gname));
GetUnionRoomPlayerFacingCoords(playerIdx, direction, &x, &y);
SetUnionRoomObjectFacingDirection(memberId, leaderId, GetNewFacingDirectionForUnionRoomPlayer(memberId, leaderId, gameData));
GetUnionRoomPlayerCoords(leaderId, memberId, &x, &y);
MapGridSetMetatileImpassabilityAt(x, y, TRUE);
}
static void DespawnGroupMember(u32 playerIdx, u32 direction)
static void DespawnGroupMember(u32 leaderId, u32 memberId)
{
s32 x, y;
SetObjectEventSpriteAnim(UR_PLAYER_SPRITE_ID(playerIdx, direction) - UR_SPRITE_START_ID, UNION_ROOM_SPAWN_OUT);
GetUnionRoomPlayerFacingCoords(playerIdx, direction, &x, &y);
SetObjectEventSpriteAnim(UR_PLAYER_SPRITE_ID(leaderId, memberId) - UR_SPRITE_START_ID, UNION_ROOM_SPAWN_OUT);
GetUnionRoomPlayerCoords(leaderId, memberId, &x, &y);
MapGridSetMetatileImpassabilityAt(x, y, FALSE);
}
static void AssembleGroup(u32 playerIdx, struct GFtgtGname * gname)
static void AssembleGroup(u32 leaderId, struct RfuGameData * gameData)
{
s16 x, y, x2, y2;
s32 i;
PlayerGetDestCoords(&x, &y);
player_get_pos_including_state_based_drift(&x2, &y2);
if (IsObjectEventSpriteInvisible(UR_PLAYER_SPRITE_ID(playerIdx, 0) - UR_SPRITE_START_ID) == TRUE)
if (IsObjectEventSpriteInvisible(UR_PLAYER_SPRITE_ID(leaderId, 0) - UR_SPRITE_START_ID) == TRUE)
{
if (IsUnionRoomPlayerFacingTileAt(playerIdx, 0, x, y) == TRUE || IsUnionRoomPlayerFacingTileAt(playerIdx, 0, x2, y2) == TRUE)
{
if (IsUnionRoomPlayerAt(leaderId, 0, x, y) == TRUE || IsUnionRoomPlayerAt(leaderId, 0, x2, y2) == TRUE)
return;
}
SpawnGroupMember(playerIdx, 0, GetUnionRoomPlayerGraphicsId(gname->playerGender, gname->unk_00.playerTrainerId[0]), gname);
SpawnGroupMember(leaderId, 0, GetUnionRoomPlayerGraphicsId(gameData->playerGender, gameData->compatibility.playerTrainerId[0]), gameData);
}
for (i = 1; i < 5; i++)
for (i = 1; i < MAX_RFU_PLAYERS; i++)
{
if (gname->child_sprite_gender[i - 1] == 0)
if (gameData->partnerInfo[i - 1] == 0)
{
DespawnGroupMember(playerIdx, i);
DespawnGroupMember(leaderId, i);
}
else if (IsUnionRoomPlayerFacingTileAt(playerIdx, i, x, y) == FALSE && IsUnionRoomPlayerFacingTileAt(playerIdx, i, x2, y2) == FALSE)
else if (IsUnionRoomPlayerAt(leaderId, i, x, y) == FALSE && IsUnionRoomPlayerAt(leaderId, i, x2, y2) == FALSE)
{
SpawnGroupMember(playerIdx, i, GetUnionRoomPlayerGraphicsId((gname->child_sprite_gender[i - 1] >> 3) & 1, gname->child_sprite_gender[i - 1] & 7), gname);
SpawnGroupMember(leaderId, i, GetUnionRoomPlayerGraphicsId((gameData->partnerInfo[i - 1] >> PINFO_GENDER_SHIFT) & 1,
gameData->partnerInfo[i - 1] & PINFO_TID_MASK),
gameData);
}
}
}
static void SpawnGroupLeaderAndMembers(u32 playerIdx, struct GFtgtGname * gname)
static void SpawnGroupLeaderAndMembers(u32 leaderId, struct RfuGameData * gameData)
{
u32 i;
switch (gname->activity)
switch (gameData->activity)
{
case ACTIVITY_NONE | IN_UNION_ROOM:
case ACTIVITY_PLYRTALK | IN_UNION_ROOM:
SpawnGroupLeader(playerIdx, gname->playerGender, gname->unk_00.playerTrainerId[0]);
for (i = 0; i < 5; i++)
{
DespawnGroupMember(playerIdx, i);
}
SpawnGroupLeader(leaderId, gameData->playerGender, gameData->compatibility.playerTrainerId[0]);
for (i = 0; i < MAX_RFU_PLAYERS; i++)
DespawnGroupMember(leaderId, i);
break;
case ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM:
case ACTIVITY_TRADE | IN_UNION_ROOM:
@@ -528,37 +515,31 @@ static void SpawnGroupLeaderAndMembers(u32 playerIdx, struct GFtgtGname * gname)
case ACTIVITY_ACCEPT | IN_UNION_ROOM:
case ACTIVITY_DECLINE | IN_UNION_ROOM:
case ACTIVITY_NPCTALK | IN_UNION_ROOM:
DespawnGroupLeader(playerIdx);
AssembleGroup(playerIdx, gname);
DespawnGroupLeader(leaderId);
AssembleGroup(leaderId, gameData);
break;
}
}
static void DespawnGroupLeaderAndMembers(u32 r5, struct GFtgtGname *gname)
static void DespawnGroupLeaderAndMembers(u32 leaderId, struct RfuGameData *gameData)
{
s32 i;
DespawnGroupLeader(r5);
for (i = 0; i < 5; i++)
{
DespawnGroupMember(r5, i);
}
DespawnGroupLeader(leaderId);
for (i = 0; i < MAX_RFU_PLAYERS; i++)
DespawnGroupMember(leaderId, i);
}
static void UpdateUnionRoomPlayerSprites(struct WirelessLink_URoom *uroom)
{
s32 i;
struct UnkStruct_x20 * r4;
struct RfuPlayer * leaders;
sUnionObjRefreshTimer = 0;
for (i = 0, r4 = uroom->field_0->arr; i < MAX_UNION_ROOM_PLAYERS; i++)
for (i = 0, leaders = uroom->playerList->players; i < MAX_UNION_ROOM_LEADERS; i++)
{
if (r4[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN)
{
SpawnGroupLeaderAndMembers(i, &r4[i].gname_uname.gname);
}
else if (r4[i].groupScheduledAnim == UNION_ROOM_SPAWN_OUT)
{
DespawnGroupLeaderAndMembers(i, &r4[i].gname_uname.gname);
}
if (leaders[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN)
SpawnGroupLeaderAndMembers(i, &leaders[i].rfu.data);
else if (leaders[i].groupScheduledAnim == UNION_ROOM_SPAWN_OUT)
DespawnGroupLeaderAndMembers(i, &leaders[i].rfu.data);
}
}
@@ -570,64 +551,56 @@ void ScheduleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom)
void HandleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom)
{
if (++sUnionObjRefreshTimer > 300)
{
UpdateUnionRoomPlayerSprites(uroom);
}
}
bool32 TryInteractWithUnionRoomMember(struct UnkStruct_Main0 *main0, s16 *directionPtr, s16 *playerIdxPtr, u8 *spriteIds)
bool32 TryInteractWithUnionRoomMember(struct RfuPlayerList *list, s16 *memberIdPtr, s16 *leaderIdPtr, u8 *spriteIds)
{
s16 x, y;
s32 i, direction;
struct UnkStruct_x20 * r4;
s32 i, memberId;
struct RfuPlayer * leaders;
if (!IsPlayerStandingStill())
{
return FALSE;
}
GetXYCoordsOneStepInFrontOfPlayer(&x, &y);
for (i = 0, r4 = main0->arr; i < MAX_UNION_ROOM_PLAYERS; i++)
for (i = 0, leaders = list->players; i < MAX_UNION_ROOM_LEADERS; i++)
{
for (direction = DIR_NONE; direction <= DIR_EAST; direction++)
for (memberId = 0; memberId < MAX_RFU_PLAYERS; memberId++)
{
s32 id = UR_PLAYER_SPRITE_ID(i, direction);
if (x != sUnionRoomPlayerCoords[i][0] + sFacingDirectionOffsets[direction][0] + 7)
{
s32 id = UR_PLAYER_SPRITE_ID(i, memberId);
// Is the player in front of a group member position?
if (x != sUnionRoomPlayerCoords[i][0] + sUnionRoomGroupOffsets[memberId][0] + 7)
continue;
}
if (y != sUnionRoomPlayerCoords[i][1] + sFacingDirectionOffsets[direction][1] + 7)
{
if (y != sUnionRoomPlayerCoords[i][1] + sUnionRoomGroupOffsets[memberId][1] + 7)
continue;
}
// Has a group member spawned at this position?
if (IsObjectEventSpriteInvisible(id - UR_SPRITE_START_ID))
{
continue;
}
if (IsObjectEventSpriteAnimating(id - UR_SPRITE_START_ID))
{
continue;
}
if (r4[i].groupScheduledAnim != UNION_ROOM_SPAWN_IN)
{
if (leaders[i].groupScheduledAnim != UNION_ROOM_SPAWN_IN)
continue;
}
// Face player
SetUnionRoomObjectFacingDirection(direction, i, sOppositeFacingDirection[GetPlayerFacingDirection()]);
*directionPtr = direction;
*playerIdxPtr = i;
// Interaction attempt successful, face player
SetUnionRoomObjectFacingDirection(memberId, i, sOppositeFacingDirection[GetPlayerFacingDirection()]);
*memberIdPtr = memberId;
*leaderIdPtr = i;
return TRUE;
}
}
return FALSE;
}
static void SetUnionRoomObjectFacingDirection(s32 currDirection, s32 playerIdx, u8 newDirection)
static void SetUnionRoomObjectFacingDirection(s32 memberId, s32 leaderId, u8 newDirection)
{
TurnObjectEventSprite(5 * playerIdx - UR_SPRITE_START_ID + currDirection, newDirection);
TurnObjectEventSprite(MAX_RFU_PLAYERS * leaderId - UR_SPRITE_START_ID + memberId, newDirection);
// should be line below, but order is swapped here
// TurnObjectEventSprite(UR_PLAYER_SPRITE_ID(playerIdx, currDirection) - UR_SPRITE_START_ID, newDirection);
// TurnObjectEventSprite(UR_PLAYER_SPRITE_ID(leaderId, memberId) - UR_SPRITE_START_ID, newDirection);
}
void UpdateUnionRoomMemberFacing(u32 currDirection, u32 playerIdx, struct UnkStruct_Main0 *main0)
void UpdateUnionRoomMemberFacing(u32 memberId, u32 leaderId, struct RfuPlayerList *list)
{
return SetUnionRoomObjectFacingDirection(currDirection, playerIdx, GetNewFacingDirectionForUnionRoomPlayer(currDirection, playerIdx, &main0->arr[playerIdx].gname_uname.gname));
return SetUnionRoomObjectFacingDirection(memberId, leaderId, GetNewFacingDirectionForUnionRoomPlayer(memberId, leaderId, &list->players[leaderId].rfu.data));
}

View File

@@ -114,8 +114,8 @@ static const u8 sActivityGroupInfo[][3] = {
{ACTIVITY_BATTLE_DOUBLE, GROUPTYPE_BATTLE, 2},
{ACTIVITY_BATTLE_MULTI, GROUPTYPE_BATTLE, 4},
{ACTIVITY_TRADE, GROUPTYPE_TRADE, 2},
{ACTIVITY_WONDER_CARD, GROUPTYPE_TOTAL, 2},
{ACTIVITY_WONDER_NEWS, GROUPTYPE_TOTAL, 2},
{ACTIVITY_WONDER_CARD_DUP, GROUPTYPE_TOTAL, 2},
{ACTIVITY_WONDER_NEWS_DUP, GROUPTYPE_TOTAL, 2},
{ACTIVITY_POKEMON_JUMP, GROUPTYPE_TOTAL, 0},
{ACTIVITY_BERRY_CRUSH, GROUPTYPE_TOTAL, 0},
{ACTIVITY_BERRY_PICK, GROUPTYPE_TOTAL, 0},
@@ -132,8 +132,8 @@ static const u8 sActivityGroupInfo[][3] = {
{ACTIVITY_NPCTALK | IN_UNION_ROOM, GROUPTYPE_UNION, 2},
{ACTIVITY_ACCEPT | IN_UNION_ROOM, GROUPTYPE_UNION, 1},
{ACTIVITY_DECLINE | IN_UNION_ROOM, GROUPTYPE_UNION, 1},
{ACTIVITY_WONDER_CARD2, GROUPTYPE_TOTAL, 2},
{ACTIVITY_WONDER_NEWS2, GROUPTYPE_TOTAL, 2},
{ACTIVITY_WONDER_CARD, GROUPTYPE_TOTAL, 2},
{ACTIVITY_WONDER_NEWS, GROUPTYPE_TOTAL, 2},
{ACTIVITY_CONTEST_COOL, GROUPTYPE_TOTAL, 0},
{ACTIVITY_CONTEST_BEAUTY, GROUPTYPE_TOTAL, 0},
{ACTIVITY_CONTEST_CUTE, GROUPTYPE_TOTAL, 0},
@@ -347,10 +347,10 @@ static void WCSS_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 *
AddTextPrinterParameterized4(windowId, fontId, x, y, 0, 0, color, -1, str);
}
static u32 CountPlayersInGroupAndGetActivity(struct UnkStruct_x20 * unk20, u32 * groupCounts)
static u32 CountPlayersInGroupAndGetActivity(struct RfuPlayer * player, u32 * groupCounts)
{
int i, j, k;
u32 activity = unk20->gname_uname.gname.activity;
u32 activity = player->rfu.data.activity;
#define group_activity(i) (sActivityGroupInfo[(i)][0])
#define group_type(i) (sActivityGroupInfo[(i)][1])
@@ -358,15 +358,13 @@ static u32 CountPlayersInGroupAndGetActivity(struct UnkStruct_x20 * unk20, u32 *
for (i = 0; i < ARRAY_COUNT(sActivityGroupInfo); i++)
{
if (activity == group_activity(i) && unk20->groupScheduledAnim == UNION_ROOM_SPAWN_IN)
if (activity == group_activity(i) && player->groupScheduledAnim == UNION_ROOM_SPAWN_IN)
{
if (group_players(i) == 0)
{
k = 0;
for (j = 0; j < RFU_CHILD_MAX; j++)
{
if (unk20->gname_uname.gname.child_sprite_gender[j] != 0) k++;
}
if (player->rfu.data.partnerInfo[j] != 0) k++;
k++;
groupCounts[group_type(i)] += k;
}
@@ -398,12 +396,12 @@ static bool32 UpdateCommunicationCounts(u32 * groupCounts, u32 * prevGroupCounts
{
bool32 activitiesChanged = FALSE;
u32 groupCountBuffer[NUM_GROUPTYPES] = {0, 0, 0, 0};
struct UnkStruct_x20 ** data = (void *)gTasks[taskId].data;
struct RfuPlayer ** players = (void *)gTasks[taskId].data;
s32 i;
for (i = 0; i < NUM_TASK_DATA; i++)
{
u32 activity = CountPlayersInGroupAndGetActivity(&(*data)[i], groupCountBuffer);
u32 activity = CountPlayersInGroupAndGetActivity(&(*players)[i], groupCountBuffer);
if (activity != activities[i])
{
activities[i] = activity;