mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2025-02-05 02:40:56 +01:00
Allow one mon double battles
This commit is contained in:
parent
339f297949
commit
4b29ae39ad
@ -185,6 +185,7 @@ extern struct UnusedControllerStruct gUnusedControllerStruct;
|
|||||||
void HandleLinkBattleSetup(void);
|
void HandleLinkBattleSetup(void);
|
||||||
void SetUpBattleVarsAndBirchZigzagoon(void);
|
void SetUpBattleVarsAndBirchZigzagoon(void);
|
||||||
void InitBattleControllers(void);
|
void InitBattleControllers(void);
|
||||||
|
bool32 IsValidForBattle(struct Pokemon *mon);
|
||||||
void TryReceiveLinkBattleData(void);
|
void TryReceiveLinkBattleData(void);
|
||||||
void PrepareBufferDataTransferLink(u8 bufferId, u16 size, u8 *data);
|
void PrepareBufferDataTransferLink(u8 bufferId, u16 size, u8 *data);
|
||||||
|
|
||||||
|
@ -1034,20 +1034,25 @@ static void Intro_DelayAndEnd(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool32 TwoIntroMons(u32 battlerId) // Double battle with both player pokemon active.
|
||||||
|
{
|
||||||
|
return (IsDoubleBattle() && IsValidForBattle(&gPlayerParty[gBattlerPartyIndexes[battlerId ^ BIT_FLANK]]));
|
||||||
|
}
|
||||||
|
|
||||||
static void Intro_WaitForShinyAnimAndHealthbox(void)
|
static void Intro_WaitForShinyAnimAndHealthbox(void)
|
||||||
{
|
{
|
||||||
bool8 healthboxAnimDone = FALSE;
|
bool8 healthboxAnimDone = FALSE;
|
||||||
|
|
||||||
// Check if healthbox has finished sliding in
|
// Check if healthbox has finished sliding in
|
||||||
if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI)))
|
if (TwoIntroMons(gActiveBattler) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI))
|
||||||
{
|
{
|
||||||
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy)
|
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy
|
||||||
|
&& gSprites[gHealthboxSpriteIds[gActiveBattler ^ BIT_FLANK]].callback == SpriteCallbackDummy)
|
||||||
healthboxAnimDone = TRUE;
|
healthboxAnimDone = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy
|
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy)
|
||||||
&& gSprites[gHealthboxSpriteIds[gActiveBattler ^ BIT_FLANK]].callback == SpriteCallbackDummy)
|
|
||||||
healthboxAnimDone = TRUE;
|
healthboxAnimDone = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1065,7 +1070,7 @@ static void Intro_WaitForShinyAnimAndHealthbox(void)
|
|||||||
|
|
||||||
HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler);
|
HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler);
|
||||||
|
|
||||||
if (IsDoubleBattle())
|
if (TwoIntroMons(gActiveBattler))
|
||||||
HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]], gActiveBattler ^ BIT_FLANK);
|
HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]], gActiveBattler ^ BIT_FLANK);
|
||||||
|
|
||||||
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 3;
|
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 3;
|
||||||
@ -1094,7 +1099,7 @@ static void Intro_TryShinyAnimShowHealthbox(void)
|
|||||||
{
|
{
|
||||||
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted)
|
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted)
|
||||||
{
|
{
|
||||||
if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI))
|
if (TwoIntroMons(gActiveBattler) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI))
|
||||||
{
|
{
|
||||||
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler ^ BIT_FLANK], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]], HEALTHBOX_ALL);
|
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler ^ BIT_FLANK], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]], HEALTHBOX_ALL);
|
||||||
StartHealthboxSlideIn(gActiveBattler ^ BIT_FLANK);
|
StartHealthboxSlideIn(gActiveBattler ^ BIT_FLANK);
|
||||||
@ -1125,15 +1130,7 @@ static void Intro_TryShinyAnimShowHealthbox(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Wait for battler anims
|
// Wait for battler anims
|
||||||
if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI)))
|
if (TwoIntroMons(gActiveBattler) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI))
|
||||||
{
|
|
||||||
if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy
|
|
||||||
&& gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy)
|
|
||||||
{
|
|
||||||
battlerAnimsDone = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy
|
if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy
|
||||||
&& gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy
|
&& gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy
|
||||||
@ -1143,11 +1140,19 @@ static void Intro_TryShinyAnimShowHealthbox(void)
|
|||||||
battlerAnimsDone = TRUE;
|
battlerAnimsDone = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy
|
||||||
|
&& gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy)
|
||||||
|
{
|
||||||
|
battlerAnimsDone = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Clean up
|
// Clean up
|
||||||
if (bgmRestored && battlerAnimsDone)
|
if (bgmRestored && battlerAnimsDone)
|
||||||
{
|
{
|
||||||
if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI))
|
if (TwoIntroMons(gActiveBattler) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI))
|
||||||
DestroySprite(&gSprites[gBattleControllerData[gActiveBattler ^ BIT_FLANK]]);
|
DestroySprite(&gSprites[gBattleControllerData[gActiveBattler ^ BIT_FLANK]]);
|
||||||
DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]);
|
DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]);
|
||||||
|
|
||||||
@ -3114,12 +3119,7 @@ static void Task_StartSendOutAnim(u8 taskId)
|
|||||||
u8 savedActiveBattler = gActiveBattler;
|
u8 savedActiveBattler = gActiveBattler;
|
||||||
|
|
||||||
gActiveBattler = gTasks[taskId].tBattlerId;
|
gActiveBattler = gTasks[taskId].tBattlerId;
|
||||||
if (!IsDoubleBattle() || (gBattleTypeFlags & BATTLE_TYPE_MULTI))
|
if (TwoIntroMons(gActiveBattler) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI))
|
||||||
{
|
|
||||||
gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler];
|
|
||||||
StartSendOutAnim(gActiveBattler, FALSE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler];
|
gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler];
|
||||||
StartSendOutAnim(gActiveBattler, FALSE);
|
StartSendOutAnim(gActiveBattler, FALSE);
|
||||||
@ -3129,6 +3129,11 @@ static void Task_StartSendOutAnim(u8 taskId)
|
|||||||
StartSendOutAnim(gActiveBattler, FALSE);
|
StartSendOutAnim(gActiveBattler, FALSE);
|
||||||
gActiveBattler ^= BIT_FLANK;
|
gActiveBattler ^= BIT_FLANK;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler];
|
||||||
|
StartSendOutAnim(gActiveBattler, FALSE);
|
||||||
|
}
|
||||||
gBattlerControllerFuncs[gActiveBattler] = Intro_TryShinyAnimShowHealthbox;
|
gBattlerControllerFuncs[gActiveBattler] = Intro_TryShinyAnimShowHealthbox;
|
||||||
gActiveBattler = savedActiveBattler;
|
gActiveBattler = savedActiveBattler;
|
||||||
DestroyTask(taskId);
|
DestroyTask(taskId);
|
||||||
|
@ -588,6 +588,14 @@ static void InitLinkBtlControllers(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool32 IsValidForBattle(struct Pokemon *mon)
|
||||||
|
{
|
||||||
|
u32 species = GetMonData(mon, MON_DATA_SPECIES2);
|
||||||
|
return (species != SPECIES_NONE && species != SPECIES_EGG
|
||||||
|
&& GetMonData(mon, MON_DATA_HP) != 0
|
||||||
|
&& GetMonData(mon, MON_DATA_IS_EGG) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
static void SetBattlePartyIds(void)
|
static void SetBattlePartyIds(void)
|
||||||
{
|
{
|
||||||
s32 i, j;
|
s32 i, j;
|
||||||
@ -602,10 +610,7 @@ static void SetBattlePartyIds(void)
|
|||||||
{
|
{
|
||||||
if (GET_BATTLER_SIDE2(i) == B_SIDE_PLAYER)
|
if (GET_BATTLER_SIDE2(i) == B_SIDE_PLAYER)
|
||||||
{
|
{
|
||||||
if (GetMonData(&gPlayerParty[j], MON_DATA_HP) != 0
|
if (IsValidForBattle(&gPlayerParty[j]))
|
||||||
&& GetMonData(&gPlayerParty[j], MON_DATA_SPECIES2) != SPECIES_NONE
|
|
||||||
&& GetMonData(&gPlayerParty[j], MON_DATA_SPECIES2) != SPECIES_EGG
|
|
||||||
&& GetMonData(&gPlayerParty[j], MON_DATA_IS_EGG) == 0)
|
|
||||||
{
|
{
|
||||||
gBattlerPartyIndexes[i] = j;
|
gBattlerPartyIndexes[i] = j;
|
||||||
break;
|
break;
|
||||||
@ -613,10 +618,7 @@ static void SetBattlePartyIds(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (GetMonData(&gEnemyParty[j], MON_DATA_HP) != 0
|
if (IsValidForBattle(&gEnemyParty[j]))
|
||||||
&& GetMonData(&gEnemyParty[j], MON_DATA_SPECIES2) != SPECIES_NONE
|
|
||||||
&& GetMonData(&gEnemyParty[j], MON_DATA_SPECIES2) != SPECIES_EGG
|
|
||||||
&& GetMonData(&gEnemyParty[j], MON_DATA_IS_EGG) == 0)
|
|
||||||
{
|
{
|
||||||
gBattlerPartyIndexes[i] = j;
|
gBattlerPartyIndexes[i] = j;
|
||||||
break;
|
break;
|
||||||
@ -627,11 +629,7 @@ static void SetBattlePartyIds(void)
|
|||||||
{
|
{
|
||||||
if (GET_BATTLER_SIDE2(i) == B_SIDE_PLAYER)
|
if (GET_BATTLER_SIDE2(i) == B_SIDE_PLAYER)
|
||||||
{
|
{
|
||||||
if (GetMonData(&gPlayerParty[j], MON_DATA_HP) != 0
|
if (IsValidForBattle(&gPlayerParty[j]) && gBattlerPartyIndexes[i - 2] != j)
|
||||||
&& GetMonData(&gPlayerParty[j], MON_DATA_SPECIES) != SPECIES_NONE // Probably a typo by Game Freak. The rest use SPECIES2.
|
|
||||||
&& GetMonData(&gPlayerParty[j], MON_DATA_SPECIES2) != SPECIES_EGG
|
|
||||||
&& GetMonData(&gPlayerParty[j], MON_DATA_IS_EGG) == 0
|
|
||||||
&& gBattlerPartyIndexes[i - 2] != j)
|
|
||||||
{
|
{
|
||||||
gBattlerPartyIndexes[i] = j;
|
gBattlerPartyIndexes[i] = j;
|
||||||
break;
|
break;
|
||||||
@ -639,16 +637,18 @@ static void SetBattlePartyIds(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (GetMonData(&gEnemyParty[j], MON_DATA_HP) != 0
|
if (IsValidForBattle(&gEnemyParty[j]) && gBattlerPartyIndexes[i - 2] != j)
|
||||||
&& GetMonData(&gEnemyParty[j], MON_DATA_SPECIES2) != SPECIES_NONE
|
|
||||||
&& GetMonData(&gEnemyParty[j], MON_DATA_SPECIES2) != SPECIES_EGG
|
|
||||||
&& GetMonData(&gEnemyParty[j], MON_DATA_IS_EGG) == 0
|
|
||||||
&& gBattlerPartyIndexes[i - 2] != j)
|
|
||||||
{
|
{
|
||||||
gBattlerPartyIndexes[i] = j;
|
gBattlerPartyIndexes[i] = j;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No valid mons were found. Add the empty slot.
|
||||||
|
if (gBattlerPartyIndexes[i - 2] == 0)
|
||||||
|
gBattlerPartyIndexes[i] = 1;
|
||||||
|
else
|
||||||
|
gBattlerPartyIndexes[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3454,6 +3454,13 @@ static void TryDoEventsBeforeFirstTurn(void)
|
|||||||
if (gBattleControllerExecFlags)
|
if (gBattleControllerExecFlags)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Set invalid mons as absent(for example when starting a double battle with only one pokemon).
|
||||||
|
for (i = 0; i < gBattlersCount; i++)
|
||||||
|
{
|
||||||
|
if (gBattleMons[i].hp == 0 || gBattleMons[i].species == SPECIES_NONE)
|
||||||
|
gAbsentBattlerFlags |= gBitTable[i];
|
||||||
|
}
|
||||||
|
|
||||||
if (gBattleStruct->switchInAbilitiesCounter == 0)
|
if (gBattleStruct->switchInAbilitiesCounter == 0)
|
||||||
{
|
{
|
||||||
for (i = 0; i < gBattlersCount; i++)
|
for (i = 0; i < gBattlersCount; i++)
|
||||||
@ -4080,10 +4087,10 @@ static void HandleTurnActionSelectionState(void)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATE_WAIT_ACTION_CONFIRMED_STANDBY:
|
case STATE_WAIT_ACTION_CONFIRMED_STANDBY:
|
||||||
if (!(gBattleControllerExecFlags & ((gBitTable[gActiveBattler])
|
if (!(gBattleControllerExecFlags & ((gBitTable[gActiveBattler])
|
||||||
| (0xF << 28)
|
| (0xF << 28)
|
||||||
| (gBitTable[gActiveBattler] << 4)
|
| (gBitTable[gActiveBattler] << 4)
|
||||||
| (gBitTable[gActiveBattler] << 8)
|
| (gBitTable[gActiveBattler] << 8)
|
||||||
| (gBitTable[gActiveBattler] << 12))))
|
| (gBitTable[gActiveBattler] << 12))))
|
||||||
{
|
{
|
||||||
if (AllAtActionConfirmed())
|
if (AllAtActionConfirmed())
|
||||||
@ -4646,7 +4653,7 @@ static void CheckQuickClaw_CustapBerryActivation(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup stuff before turns/actions
|
// setup stuff before turns/actions
|
||||||
TryClearRageAndFuryCutter();
|
TryClearRageAndFuryCutter();
|
||||||
gCurrentTurnActionNumber = 0;
|
gCurrentTurnActionNumber = 0;
|
||||||
|
@ -2560,7 +2560,7 @@ void BufferStringBattle(u16 stringID)
|
|||||||
case STRINGID_INTROSENDOUT: // poke first send-out
|
case STRINGID_INTROSENDOUT: // poke first send-out
|
||||||
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
|
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
|
||||||
{
|
{
|
||||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && IsValidForBattle(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]]))
|
||||||
{
|
{
|
||||||
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
|
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
|
||||||
stringPtr = sText_InGamePartnerSentOutZGoN;
|
stringPtr = sText_InGamePartnerSentOutZGoN;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user