summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/battle.h22
-rw-r--r--src/battle_main.c124
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)