New feature - battle 2 vs 1 opponent

This commit is contained in:
DizzyEggg 2019-01-27 20:54:34 +01:00
parent abd518b668
commit 736826e863
11 changed files with 125 additions and 102 deletions

View File

@ -48,7 +48,7 @@ EverGrandeCity_PokemonLeague_1F_Pokemart_229624: @ 8229624
EverGrandeCity_PokemonLeague_1F_EventScript_229636:: @ 8229636
special SavePlayerParty
trainerbattle 10, TRAINER_ALBERT, 0, NULL, EverGrandeCity_PokemonLeague_1F_Text_2296E8
trainerbattle 10, TRAINER_WALLACE, 0, NULL, EverGrandeCity_PokemonLeague_1F_Text_2296E8
trainerbattle 11, TRAINER_ALEXA, 0, NULL, EverGrandeCity_PokemonLeague_1F_Text_2297EF
setvar VAR_0x8004, SPECIAL_BATTLE_MULTI

View File

@ -11,6 +11,7 @@ enum
AI_ITEM_NOT_RECOGNIZABLE
};
void GetAIPartyIndexes(u32 battlerId, s32 *firstId, s32 *lastId);
void AI_TrySwitchOrUseItem(void);
u8 GetMostSuitableMonToSwitchInto(void);

View File

@ -80,6 +80,7 @@
#define BATTLE_TYPE_FRONTIER_NO_PYRAMID (BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_DOME | BATTLE_TYPE_PALACE | BATTLE_TYPE_ARENA | BATTLE_TYPE_FACTORY | BATTLE_TYPE_PIKE)
#define WILD_DOUBLE_BATTLE ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_TRAINER))))
#define BATTLE_TWO_VS_ONE_OPPONENT ((gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gTrainerBattleOpponent_B == 0xFFFF))
// Battle Outcome defines
#define B_OUTCOME_WON 0x1

View File

@ -2,6 +2,7 @@
#include "battle.h"
#include "battle_ai_script_commands.h"
#include "battle_controllers.h"
#include "battle_setup.h"
#include "pokemon.h"
#include "random.h"
#include "util.h"
@ -15,6 +16,25 @@ static bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng);
static bool8 FindMonWithFlagsAndSuperEffective(u16 flags, u8 moduloPercent);
static bool8 ShouldUseItem(void);
void GetAIPartyIndexes(u32 battlerId, s32 *firstId, s32 *lastId)
{
if (BATTLE_TWO_VS_ONE_OPPONENT && (battlerId & BIT_SIDE) == B_SIDE_OPPONENT)
{
*firstId = 0, *lastId = 6;
}
else if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_x800000))
{
if ((battlerId & BIT_FLANK) == B_FLANK_LEFT)
*firstId = 0, *lastId = 3;
else
*firstId = 3, *lastId = 6;
}
else
{
*firstId = 0, *lastId = 6;
}
}
static bool8 ShouldSwitchIfPerishSong(void)
{
if (gStatuses3[gActiveBattler] & STATUS3_PERISH_SONG
@ -60,17 +80,7 @@ static bool8 ShouldSwitchIfWonderGuard(void)
}
// Get party information.
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000))
{
if ((gActiveBattler & BIT_FLANK) == B_FLANK_LEFT)
firstId = 0, lastId = 3;
else
firstId = 3, lastId = 6;
}
else
{
firstId = 0, lastId = 6;
}
GetAIPartyIndexes(gActiveBattler, &firstId, &lastId);
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
party = gPlayerParty;
@ -152,17 +162,7 @@ static bool8 FindMonThatAbsorbsOpponentsMove(void)
if (gBattleMons[gActiveBattler].ability == absorbingTypeAbility)
return FALSE;
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000))
{
if ((gActiveBattler & BIT_FLANK) == B_FLANK_LEFT)
firstId = 0, lastId = 3;
else
firstId = 3, lastId = 6;
}
else
{
firstId = 0, lastId = 6;
}
GetAIPartyIndexes(gActiveBattler, &firstId, &lastId);
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
party = gPlayerParty;
@ -343,17 +343,7 @@ static bool8 FindMonWithFlagsAndSuperEffective(u16 flags, u8 moduloPercent)
battlerIn2 = gActiveBattler;
}
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000))
{
if ((gActiveBattler & BIT_FLANK) == 0)
firstId = 0, lastId = 3;
else
firstId = 3, lastId = 6;
}
else
{
firstId = 0, lastId = 6;
}
GetAIPartyIndexes(gActiveBattler, &firstId, &lastId);
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
party = gPlayerParty;
@ -453,17 +443,7 @@ static bool8 ShouldSwitch(void)
battlerIn2 = *activeBattlerPtr;
}
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000))
{
if ((gActiveBattler & BIT_FLANK) == B_FLANK_LEFT)
firstId = 0, lastId = 3;
else
firstId = 3, lastId = 6;
}
else
{
firstId = 0, lastId = 6;
}
GetAIPartyIndexes(gActiveBattler, &firstId, &lastId);
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
party = gPlayerParty;
@ -544,17 +524,7 @@ void AI_TrySwitchOrUseItem(void)
battlerIn2 = GetBattlerAtPosition(battlerIdentity ^ BIT_FLANK);
}
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000))
{
if ((gActiveBattler & BIT_FLANK) == B_FLANK_LEFT)
firstId = 0, lastId = 3;
else
firstId = 3, lastId = 6;
}
else
{
firstId = 0, lastId = 6;
}
GetAIPartyIndexes(gActiveBattler, &firstId, &lastId);
for (monToSwitchId = firstId; monToSwitchId < lastId; monToSwitchId++)
{
@ -626,17 +596,7 @@ u8 GetMostSuitableMonToSwitchInto(void)
battlerIn2 = gActiveBattler;
}
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000))
{
if ((gActiveBattler & BIT_FLANK) == B_FLANK_LEFT)
firstId = 0, lastId = 3;
else
firstId = 3, lastId = 6;
}
else
{
firstId = 0, lastId = 6;
}
GetAIPartyIndexes(gActiveBattler, &firstId, &lastId);
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
party = gPlayerParty;

View File

@ -234,7 +234,7 @@ static void sub_805F2F0(void)
bool8 var = FALSE;
bool8 var2;
if (!IsDoubleBattle() || ((IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI)) || (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)))
if (!IsDoubleBattle() || ((IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI) && !BATTLE_TWO_VS_ONE_OPPONENT) || (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)))
{
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy)
var = TRUE;
@ -297,13 +297,13 @@ static void sub_805F560(void)
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x1)
sub_8172EF0(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]);
if (!(gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI) && IsDoubleBattle() && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].field_1_x1)
if (!(gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) && (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) || BATTLE_TWO_VS_ONE_OPPONENT) && IsDoubleBattle() && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].field_1_x1)
sub_8172EF0(gActiveBattler ^ BIT_FLANK, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]]);
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].ballAnimActive)
{
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x80)
{
if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI))
if (IsDoubleBattle() && (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) || BATTLE_TWO_VS_ONE_OPPONENT))
{
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler ^ BIT_FLANK], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]], HEALTHBOX_ALL);
sub_8076918(gActiveBattler ^ BIT_FLANK);
@ -335,7 +335,7 @@ static void sub_805F560(void)
sp = TRUE;
}
if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI)))
if (!IsDoubleBattle() || (IsDoubleBattle() && gBattleTypeFlags & BATTLE_TYPE_MULTI && !BATTLE_TWO_VS_ONE_OPPONENT))
{
if (gSprites[gUnknown_03005D7C[gActiveBattler]].callback == SpriteCallbackDummy
&& gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy)
@ -356,7 +356,7 @@ static void sub_805F560(void)
if (sp && r10)
{
if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI))
if (IsDoubleBattle() && (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) || BATTLE_TWO_VS_ONE_OPPONENT))
{
DestroySprite(&gSprites[gUnknown_03005D7C[gActiveBattler ^ BIT_FLANK]]);
SetBattlerShadowSpriteCallback(gActiveBattler ^ BIT_FLANK, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]], MON_DATA_SPECIES));
@ -1278,7 +1278,7 @@ static void OpponentHandleDrawTrainerPic(void)
trainerPicId = gTrainers[gTrainerBattleOpponent_A].trainerPic;
}
if (gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS))
if (gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS) && !BATTLE_TWO_VS_ONE_OPPONENT)
{
if ((GetBattlerPosition(gActiveBattler) & BIT_FLANK) != 0) // second mon
xPos = 152;
@ -1624,17 +1624,7 @@ static void OpponentHandleChoosePokemon(void)
battler2 = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
}
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000))
{
if (gActiveBattler == 1)
firstId = 0, lastId = 3;
else
firstId = 3, lastId = 6;
}
else
{
firstId = 0, lastId = 6;
}
GetAIPartyIndexes(gActiveBattler, &firstId, &lastId);
for (chosenMonId = firstId; chosenMonId < lastId; chosenMonId++)
{
@ -1884,7 +1874,7 @@ static void sub_8062828(u8 taskId)
u8 savedActiveBank = gActiveBattler;
gActiveBattler = gTasks[taskId].data[0];
if (!IsDoubleBattle() || (gBattleTypeFlags & BATTLE_TYPE_MULTI))
if ((!IsDoubleBattle() || (gBattleTypeFlags & BATTLE_TYPE_MULTI)) && !BATTLE_TWO_VS_ONE_OPPONENT)
{
gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler];
sub_80613DC(gActiveBattler, FALSE);

View File

@ -4,6 +4,7 @@
#include "battle_anim.h"
#include "battle_controllers.h"
#include "battle_message.h"
#include "battle_setup.h"
#include "cable_club.h"
#include "link.h"
#include "party_menu.h"
@ -153,8 +154,16 @@ static void InitSinglePlayerBtlControllers(void)
gBattlerPartyIndexes[0] = 0;
gBattlerPartyIndexes[1] = 0;
gBattlerPartyIndexes[2] = 3;
gBattlerPartyIndexes[3] = 3;
if (BATTLE_TWO_VS_ONE_OPPONENT)
{
gBattlerPartyIndexes[2] = 3;
gBattlerPartyIndexes[3] = 1;
}
else
{
gBattlerPartyIndexes[2] = 3;
gBattlerPartyIndexes[3] = 3;
}
}
else if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
{

View File

@ -573,7 +573,7 @@ static void CB2_InitBattleInternal(void)
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED)))
{
CreateNPCTrainerParty(&gEnemyParty[0], gTrainerBattleOpponent_A, TRUE);
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS && !BATTLE_TWO_VS_ONE_OPPONENT)
CreateNPCTrainerParty(&gEnemyParty[3], gTrainerBattleOpponent_B, FALSE);
SetWildMonHeldItem();
}
@ -3245,7 +3245,7 @@ static void DoBattleIntro(void)
case B_POSITION_OPPONENT_RIGHT:
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
{
if (gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS)) // opponent 2 if exists
if (gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS) && !BATTLE_TWO_VS_ONE_OPPONENT) // opponent 2 if exists
{
BtlController_EmitDrawTrainerPic(0);
MarkBattlerForControllerExec(gActiveBattler);
@ -3373,7 +3373,7 @@ static void DoBattleIntro(void)
case 12: // nothing
(*state)++;
case 13: // second opponent's mon send out
if (gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS))
if (gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS) && !BATTLE_TWO_VS_ONE_OPPONENT)
{
if (gBattleTypeFlags & BATTLE_TYPE_x2000000 && !(gBattleTypeFlags & BATTLE_TYPE_x80000000))
gActiveBattler = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);

View File

@ -2302,7 +2302,9 @@ void BufferStringBattle(u16 stringID)
}
else
{
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
if (BATTLE_TWO_VS_ONE_OPPONENT)
stringPtr = sText_Trainer1WantsToBattle;
else if (gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER))
stringPtr = sText_TwoTrainersWantToBattle;
else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
stringPtr = sText_TwoTrainersWantToBattle;
@ -2345,7 +2347,9 @@ void BufferStringBattle(u16 stringID)
{
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
if (BATTLE_TWO_VS_ONE_OPPONENT)
stringPtr = sText_Trainer1SentOutTwoPkmn;
else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
stringPtr = sText_TwoTrainersSentPkmn;
else if (gBattleTypeFlags & BATTLE_TYPE_x800000)
stringPtr = sText_TwoTrainersSentPkmn;
@ -2659,7 +2663,7 @@ static const u8 *BattleStringGetOpponentName(u8 *text, u8 multiplayerId, u8 batt
toCpy = BattleStringGetOpponentNameByTrainerId(gTrainerBattleOpponent_A, text, multiplayerId, battlerId);
break;
case B_POSITION_OPPONENT_RIGHT:
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_MULTI))
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_MULTI) && !BATTLE_TWO_VS_ONE_OPPONENT)
toCpy = BattleStringGetOpponentNameByTrainerId(gTrainerBattleOpponent_B, text, multiplayerId, battlerId);
else
toCpy = BattleStringGetOpponentNameByTrainerId(gTrainerBattleOpponent_A, text, multiplayerId, battlerId);
@ -3098,7 +3102,7 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst)
toCpy = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A);
break;
case B_POSITION_OPPONENT_RIGHT:
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS && !BATTLE_TWO_VS_ONE_OPPONENT)
toCpy = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_B);
else
toCpy = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A);

View File

@ -4541,6 +4541,7 @@ static void atk4F_jumpifcantswitch(void)
{
s32 i;
s32 lastMonId;
u8 battlerIn1, battlerIn2;
struct Pokemon *party;
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1] & ~(ATK4F_DONT_CHECK_STATUSES));
@ -4551,11 +4552,28 @@ static void atk4F_jumpifcantswitch(void)
{
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
}
else if (BATTLE_TWO_VS_ONE_OPPONENT && GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT)
{
battlerIn1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
battlerIn2 = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
party = gEnemyParty;
for (i = 0; i < PARTY_SIZE; i++)
{
if (GetMonData(&party[i], MON_DATA_HP) != 0
&& GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE
&& !GetMonData(&party[i], MON_DATA_IS_EGG)
&& i != gBattlerPartyIndexes[battlerIn1] && i != gBattlerPartyIndexes[battlerIn2])
break;
}
if (i == PARTY_SIZE)
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
else
gBattlescriptCurrInstr += 6;
}
else if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
{
#ifndef NONMATCHING
asm("":::"r5");
#endif // NONMATCHING
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT)
party = gEnemyParty;
else
@ -4651,8 +4669,6 @@ static void atk4F_jumpifcantswitch(void)
}
else
{
u8 battlerIn1, battlerIn2;
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT)
{
battlerIn1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
@ -7952,7 +7968,16 @@ static void atk8F_forcerandomswitch(void)
else
party = gEnemyParty;
if ((gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER && gBattleTypeFlags & BATTLE_TYPE_LINK)
if (BATTLE_TWO_VS_ONE_OPPONENT && (gBattlerTarget & BIT_SIDE) == B_SIDE_OPPONENT)
{
firstMonId = 0;
lastMonId = 6;
monsCount = 6;
minNeeded = 2;
battler2PartyId = gBattlerPartyIndexes[gBattlerTarget];
battler1PartyId = gBattlerPartyIndexes[gBattlerTarget ^ BIT_FLANK];
}
else if ((gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER && gBattleTypeFlags & BATTLE_TYPE_LINK)
|| (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER && gBattleTypeFlags & BATTLE_TYPE_x2000000)
|| (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER))
{

View File

@ -2374,10 +2374,20 @@ void DoSpecialTrainerBattle(void)
BattleTransition_StartOnField(B_TRANSITION_MAGMA);
break;
case SPECIAL_BATTLE_MULTI:
if (gSpecialVar_0x8005 & 1)
if (gSpecialVar_0x8005 & 1) // Player + AI against wild mon
{
gBattleTypeFlags = BATTLE_TYPE_DOUBLE | BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER;
}
else if (gSpecialVar_0x8005 & 2) // Player + AI against one trainer
{
gTrainerBattleOpponent_B = 0xFFFF;
gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER;
}
else
{
gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER;
}
gPartnerSpriteId = gSpecialVar_0x8007;
FillPartnerParty(gSpecialVar_0x8006 + TRAINER_CUSTOM_PARTNER);
gPartnerTrainerId = gSpecialVar_0x8006 + TRAINER_CUSTOM_PARTNER;

View File

@ -2,6 +2,7 @@
#include "battle.h"
#include "battle_controllers.h"
#include "battle_interface.h"
#include "battle_setup.h"
#include "constants/battle_script_commands.h"
#include "constants/abilities.h"
#include "constants/moves.h"
@ -2333,7 +2334,29 @@ bool8 HasNoMonsToSwitch(u8 battler, u8 partyIdBattlerOn1, u8 partyIdBattlerOn2)
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
return FALSE;
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
if (BATTLE_TWO_VS_ONE_OPPONENT && GetBattlerSide(battler) == B_SIDE_OPPONENT)
{
id2 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
id1 = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
party = gEnemyParty;
if (partyIdBattlerOn1 == PARTY_SIZE)
partyIdBattlerOn1 = gBattlerPartyIndexes[id2];
if (partyIdBattlerOn2 == PARTY_SIZE)
partyIdBattlerOn2 = gBattlerPartyIndexes[id1];
for (i = 0; i < PARTY_SIZE; i++)
{
if (GetMonData(&party[i], MON_DATA_HP) != 0
&& GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_NONE
&& GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_EGG
&& i != partyIdBattlerOn1 && i != partyIdBattlerOn2
&& i != *(gBattleStruct->monToSwitchIntoId + id2) && i != id1[gBattleStruct->monToSwitchIntoId])
break;
}
return (i == PARTY_SIZE);
}
else if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
{
if (GetBattlerSide(battler) == B_SIDE_PLAYER)
party = gPlayerParty;