diff options
-rw-r--r-- | include/battle.h | 22 | ||||
-rw-r--r-- | src/battle_main.c | 124 |
2 files changed, 84 insertions, 62 deletions
diff --git a/include/battle.h b/include/battle.h index 43f4c5115..636889f46 100644 --- a/include/battle.h +++ b/include/battle.h @@ -357,6 +357,15 @@ struct BattleResults extern struct BattleResults gBattleResults; +struct MultiPartnerEnigmaBerry +{ + u8 versionSignatureLo; + u8 versionSignatureHi; + u8 vsScreenHealthFlagsLo; + u8 vsScreenHealthFlagsHi; + struct BattleEnigmaBerry battleEnigmaBerry; +}; + struct BattleStruct { u8 turnEffectsTracker; @@ -440,13 +449,12 @@ struct BattleStruct u8 wishPerishSongState; u8 wishPerishSongBattlerId; u8 field_182; - u8 field_183; - u8 field_184; - u8 field_185; - u8 field_186; - u8 field_187; - struct BattleEnigmaBerry battleEnigmaBerry; - u8 field_1A4[0x5C]; // currently unknown + // align 4 + union { + struct MultiPartnerEnigmaBerry multiPartnerEnigmaBerry; + struct UnknownPokemonStruct4 multiBattleMons[3]; + } multiBuffer; + u8 padding_1E4[0x1C]; }; // size == 0x200 bytes extern struct BattleStruct *gBattleStruct; diff --git a/src/battle_main.c b/src/battle_main.c index 08bf6e345..df1324f83 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -705,41 +705,50 @@ static void CB2_InitBattleInternal(void) gBattleCommunication[MULTIUSE_STATE] = 0; } -static void sub_800FFEC(void) +#define BUFFER_PARTY_VS_SCREEN_STATUS(party, flags, i) \ + for ((i) = 0; (i) < PARTY_SIZE; (i)++) \ + { \ + u16 species = GetMonData(&(party)[(i)], MON_DATA_SPECIES2); \ + u16 hp = GetMonData(&(party)[(i)], MON_DATA_HP); \ + u32 status = GetMonData(&(party)[(i)], MON_DATA_STATUS); \ + \ + if (species == SPECIES_NONE) \ + continue; \ + \ + /* Is healthy mon? */ \ + if (species != SPECIES_EGG && hp != 0 && status == 0) \ + (flags) |= 1 << (i) * 2; \ + \ + if (species == SPECIES_NONE) /* Redundant */ \ + continue; \ + \ + /* Is Egg or statused? */ \ + if (hp != 0 && (species == SPECIES_EGG || status != 0)) \ + (flags) |= 2 << (i) * 2; \ + \ + if (species == SPECIES_NONE) /* Redundant */ \ + continue; \ + \ + /* Is fainted? */ \ + if (species != SPECIES_EGG && hp == 0) \ + (flags) |= 3 << (i) * 2; \ + } + +static void BufferPartyVsScreenHealth_AtStart(void) { - u16 r6 = 0; - u16 species = SPECIES_NONE; - u16 hp = 0; - u32 status = 0; + u16 flags = 0; s32 i; - for (i = 0; i < PARTY_SIZE; ++i) - { - species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); - hp = GetMonData(&gPlayerParty[i], MON_DATA_HP); - status = GetMonData(&gPlayerParty[i], MON_DATA_STATUS); - if (species == SPECIES_NONE) - continue; - if (species != SPECIES_EGG && hp != 0 && status == 0) - r6 |= 1 << i * 2; - if (species == SPECIES_NONE) - continue; - if (hp != 0 && (species == SPECIES_EGG || status != 0)) - r6 |= 2 << i * 2; - if (species == SPECIES_NONE) - continue; - if (species != SPECIES_EGG && hp == 0) - r6 |= 3 << i * 2; - } - gBattleStruct->field_186 = r6; - *(&gBattleStruct->field_187) = r6 >> 8; + BUFFER_PARTY_VS_SCREEN_STATUS(gPlayerParty, flags, i); + gBattleStruct->multiBuffer.multiPartnerEnigmaBerry.vsScreenHealthFlagsLo = flags; + *(&gBattleStruct->multiBuffer.multiPartnerEnigmaBerry.vsScreenHealthFlagsHi) = flags >> 8; } static void SetPlayerBerryDataInBattleStruct(void) { s32 i; struct BattleStruct *battleStruct = gBattleStruct; - struct BattleEnigmaBerry *battleBerry = &battleStruct->battleEnigmaBerry; + struct BattleEnigmaBerry *battleBerry = &battleStruct->multiBuffer.multiPartnerEnigmaBerry.battleEnigmaBerry; if (IsEnigmaBerryValid() == TRUE) { @@ -859,44 +868,47 @@ static void SetAllPlayersBerryData(void) } } -static void sub_8010414(u8 arg0, u8 arg1) +static void sub_8010414(u8 numPlayers, u8 multiPlayerId) { - u8 var = 0; + u8 found = 0; - if (gBlockRecvBuffer[0][0] == 256) + // If player 1 is playing the minimum version, player 1 is master. + if (gBlockRecvBuffer[0][0] == 0x100) { - if (arg1 == 0) + if (multiPlayerId == 0) gBattleTypeFlags |= BATTLE_TYPE_IS_MASTER | BATTLE_TYPE_TRAINER; else gBattleTypeFlags |= BATTLE_TYPE_TRAINER; - ++var; + ++found; } - if (var == 0) + if (found == 0) { + // If multiple different versions are being used, player 1 is master. s32 i; - for (i = 0; i < arg0; ++i) + for (i = 0; i < numPlayers; ++i) if (gBlockRecvBuffer[0][0] != gBlockRecvBuffer[i][0]) break; - if (i == arg0) + if (i == numPlayers) { - if (arg1 == 0) + if (multiPlayerId == 0) gBattleTypeFlags |= BATTLE_TYPE_IS_MASTER | BATTLE_TYPE_TRAINER; else gBattleTypeFlags |= BATTLE_TYPE_TRAINER; - ++var; + ++found; } - if (var == 0) + if (found == 0) { - for (i = 0; i < arg0; ++i) + // Lowest index player with the highest game version is master. + for (i = 0; i < numPlayers; ++i) { - if (gBlockRecvBuffer[i][0] == 0x201) - if (i != arg1 && i < arg1) + if (gBlockRecvBuffer[i][0] == 0x201 && i != multiPlayerId) + if (i < multiPlayerId) break; - if (gBlockRecvBuffer[i][0] > 0x201 && i != arg1) + if (gBlockRecvBuffer[i][0] > 0x201 && i != multiPlayerId) break; } - if (i == arg0) + if (i == numPlayers) gBattleTypeFlags |= BATTLE_TYPE_IS_MASTER | BATTLE_TYPE_TRAINER; else gBattleTypeFlags |= BATTLE_TYPE_TRAINER; @@ -937,11 +949,12 @@ static void CB2_HandleStartBattle(void) { if (IsLinkTaskFinished()) { - *(&gBattleStruct->field_184) = 1; - *(&gBattleStruct->field_185) = 2; - sub_800FFEC(); + // 0x201 + *(&gBattleStruct->multiBuffer.multiPartnerEnigmaBerry.versionSignatureLo) = 1; + *(&gBattleStruct->multiBuffer.multiPartnerEnigmaBerry.versionSignatureHi) = 2; + BufferPartyVsScreenHealth_AtStart(); SetPlayerBerryDataInBattleStruct(); - SendBlock(bitmask_all_link_players_but_self(), &gBattleStruct->field_184, 32); + SendBlock(bitmask_all_link_players_but_self(), &gBattleStruct->multiBuffer.multiPartnerEnigmaBerry, sizeof(gBattleStruct->multiBuffer.multiPartnerEnigmaBerry)); gBattleCommunication[MULTIUSE_STATE] = 2; } if (gWirelessCommType != 0) @@ -967,7 +980,7 @@ static void CB2_HandleStartBattle(void) gTasks[taskId].data[1] = 270; gTasks[taskId].data[2] = 90; gTasks[taskId].data[5] = 0; - gTasks[taskId].data[3] = gBattleStruct->field_186 | (gBattleStruct->field_187 << 8); + gTasks[taskId].data[3] = gBattleStruct->multiBuffer.multiPartnerEnigmaBerry.vsScreenHealthFlagsLo | (gBattleStruct->multiBuffer.multiPartnerEnigmaBerry.vsScreenHealthFlagsHi << 8); gTasks[taskId].data[4] = gBlockRecvBuffer[enemyMultiplayerId][1]; SetDeoxysStats(); ++gBattleCommunication[MULTIUSE_STATE]; @@ -1056,7 +1069,7 @@ static void CB2_HandleStartBattle(void) } } -static void sub_80108C4(void) +static void PrepareOwnMultiPartnerBuffer(void) { s32 i, j; u8 *nick, *cur; @@ -1083,7 +1096,7 @@ static void sub_80108C4(void) cur[j] = EOS; } } - memcpy(&gBattleStruct->field_184, gMultiPartnerParty, sizeof(gMultiPartnerParty)); + memcpy(gBattleStruct->multiBuffer.multiBattleMons, gMultiPartnerParty, sizeof(gMultiPartnerParty)); } static void CB2_PreInitMultiBattle(void) @@ -1107,8 +1120,8 @@ static void CB2_PreInitMultiBattle(void) case 0: if (gReceivedRemoteLinkPlayers && IsLinkTaskFinished()) { - sub_80108C4(); - SendBlock(bitmask_all_link_players_but_self(), &gBattleStruct->field_184, sizeof(gMultiPartnerParty)); + PrepareOwnMultiPartnerBuffer(); + SendBlock(bitmask_all_link_players_but_self(), gBattleStruct->multiBuffer.multiBattleMons, sizeof(gBattleStruct->multiBuffer.multiBattleMons)); ++gBattleCommunication[MULTIUSE_STATE]; } break; @@ -1192,11 +1205,12 @@ static void CB2_HandleStartMultiBattle(void) { if (IsLinkTaskFinished()) { - *(&gBattleStruct->field_184) = 1; - *(&gBattleStruct->field_185) = 2; - sub_800FFEC(); + // 0x201 + *(&gBattleStruct->multiBuffer.multiPartnerEnigmaBerry.versionSignatureLo) = 1; + *(&gBattleStruct->multiBuffer.multiPartnerEnigmaBerry.versionSignatureHi) = 2; + BufferPartyVsScreenHealth_AtStart(); SetPlayerBerryDataInBattleStruct(); - SendBlock(bitmask_all_link_players_but_self(), &gBattleStruct->field_184, 32); + SendBlock(bitmask_all_link_players_but_self(), &gBattleStruct->multiBuffer.multiPartnerEnigmaBerry, sizeof(gBattleStruct->multiBuffer.multiPartnerEnigmaBerry)); ++gBattleCommunication[MULTIUSE_STATE]; } if (gWirelessCommType) |