mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2025-02-05 02:40:56 +01:00
New feature - battle 2 vs 1 opponent
This commit is contained in:
parent
abd518b668
commit
736826e863
@ -48,7 +48,7 @@ EverGrandeCity_PokemonLeague_1F_Pokemart_229624: @ 8229624
|
|||||||
EverGrandeCity_PokemonLeague_1F_EventScript_229636:: @ 8229636
|
EverGrandeCity_PokemonLeague_1F_EventScript_229636:: @ 8229636
|
||||||
special SavePlayerParty
|
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
|
trainerbattle 11, TRAINER_ALEXA, 0, NULL, EverGrandeCity_PokemonLeague_1F_Text_2297EF
|
||||||
|
|
||||||
setvar VAR_0x8004, SPECIAL_BATTLE_MULTI
|
setvar VAR_0x8004, SPECIAL_BATTLE_MULTI
|
||||||
|
@ -11,6 +11,7 @@ enum
|
|||||||
AI_ITEM_NOT_RECOGNIZABLE
|
AI_ITEM_NOT_RECOGNIZABLE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void GetAIPartyIndexes(u32 battlerId, s32 *firstId, s32 *lastId);
|
||||||
void AI_TrySwitchOrUseItem(void);
|
void AI_TrySwitchOrUseItem(void);
|
||||||
u8 GetMostSuitableMonToSwitchInto(void);
|
u8 GetMostSuitableMonToSwitchInto(void);
|
||||||
|
|
||||||
|
@ -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 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 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
|
// Battle Outcome defines
|
||||||
#define B_OUTCOME_WON 0x1
|
#define B_OUTCOME_WON 0x1
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "battle.h"
|
#include "battle.h"
|
||||||
#include "battle_ai_script_commands.h"
|
#include "battle_ai_script_commands.h"
|
||||||
#include "battle_controllers.h"
|
#include "battle_controllers.h"
|
||||||
|
#include "battle_setup.h"
|
||||||
#include "pokemon.h"
|
#include "pokemon.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@ -15,6 +16,25 @@ static bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng);
|
|||||||
static bool8 FindMonWithFlagsAndSuperEffective(u16 flags, u8 moduloPercent);
|
static bool8 FindMonWithFlagsAndSuperEffective(u16 flags, u8 moduloPercent);
|
||||||
static bool8 ShouldUseItem(void);
|
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)
|
static bool8 ShouldSwitchIfPerishSong(void)
|
||||||
{
|
{
|
||||||
if (gStatuses3[gActiveBattler] & STATUS3_PERISH_SONG
|
if (gStatuses3[gActiveBattler] & STATUS3_PERISH_SONG
|
||||||
@ -60,17 +80,7 @@ static bool8 ShouldSwitchIfWonderGuard(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get party information.
|
// Get party information.
|
||||||
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000))
|
GetAIPartyIndexes(gActiveBattler, &firstId, &lastId);
|
||||||
{
|
|
||||||
if ((gActiveBattler & BIT_FLANK) == B_FLANK_LEFT)
|
|
||||||
firstId = 0, lastId = 3;
|
|
||||||
else
|
|
||||||
firstId = 3, lastId = 6;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
firstId = 0, lastId = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
|
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
|
||||||
party = gPlayerParty;
|
party = gPlayerParty;
|
||||||
@ -152,17 +162,7 @@ static bool8 FindMonThatAbsorbsOpponentsMove(void)
|
|||||||
if (gBattleMons[gActiveBattler].ability == absorbingTypeAbility)
|
if (gBattleMons[gActiveBattler].ability == absorbingTypeAbility)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000))
|
GetAIPartyIndexes(gActiveBattler, &firstId, &lastId);
|
||||||
{
|
|
||||||
if ((gActiveBattler & BIT_FLANK) == B_FLANK_LEFT)
|
|
||||||
firstId = 0, lastId = 3;
|
|
||||||
else
|
|
||||||
firstId = 3, lastId = 6;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
firstId = 0, lastId = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
|
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
|
||||||
party = gPlayerParty;
|
party = gPlayerParty;
|
||||||
@ -343,17 +343,7 @@ static bool8 FindMonWithFlagsAndSuperEffective(u16 flags, u8 moduloPercent)
|
|||||||
battlerIn2 = gActiveBattler;
|
battlerIn2 = gActiveBattler;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000))
|
GetAIPartyIndexes(gActiveBattler, &firstId, &lastId);
|
||||||
{
|
|
||||||
if ((gActiveBattler & BIT_FLANK) == 0)
|
|
||||||
firstId = 0, lastId = 3;
|
|
||||||
else
|
|
||||||
firstId = 3, lastId = 6;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
firstId = 0, lastId = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
|
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
|
||||||
party = gPlayerParty;
|
party = gPlayerParty;
|
||||||
@ -453,17 +443,7 @@ static bool8 ShouldSwitch(void)
|
|||||||
battlerIn2 = *activeBattlerPtr;
|
battlerIn2 = *activeBattlerPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000))
|
GetAIPartyIndexes(gActiveBattler, &firstId, &lastId);
|
||||||
{
|
|
||||||
if ((gActiveBattler & BIT_FLANK) == B_FLANK_LEFT)
|
|
||||||
firstId = 0, lastId = 3;
|
|
||||||
else
|
|
||||||
firstId = 3, lastId = 6;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
firstId = 0, lastId = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
|
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
|
||||||
party = gPlayerParty;
|
party = gPlayerParty;
|
||||||
@ -544,17 +524,7 @@ void AI_TrySwitchOrUseItem(void)
|
|||||||
battlerIn2 = GetBattlerAtPosition(battlerIdentity ^ BIT_FLANK);
|
battlerIn2 = GetBattlerAtPosition(battlerIdentity ^ BIT_FLANK);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000))
|
GetAIPartyIndexes(gActiveBattler, &firstId, &lastId);
|
||||||
{
|
|
||||||
if ((gActiveBattler & BIT_FLANK) == B_FLANK_LEFT)
|
|
||||||
firstId = 0, lastId = 3;
|
|
||||||
else
|
|
||||||
firstId = 3, lastId = 6;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
firstId = 0, lastId = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (monToSwitchId = firstId; monToSwitchId < lastId; monToSwitchId++)
|
for (monToSwitchId = firstId; monToSwitchId < lastId; monToSwitchId++)
|
||||||
{
|
{
|
||||||
@ -626,17 +596,7 @@ u8 GetMostSuitableMonToSwitchInto(void)
|
|||||||
battlerIn2 = gActiveBattler;
|
battlerIn2 = gActiveBattler;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000))
|
GetAIPartyIndexes(gActiveBattler, &firstId, &lastId);
|
||||||
{
|
|
||||||
if ((gActiveBattler & BIT_FLANK) == B_FLANK_LEFT)
|
|
||||||
firstId = 0, lastId = 3;
|
|
||||||
else
|
|
||||||
firstId = 3, lastId = 6;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
firstId = 0, lastId = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
|
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
|
||||||
party = gPlayerParty;
|
party = gPlayerParty;
|
||||||
|
@ -234,7 +234,7 @@ static void sub_805F2F0(void)
|
|||||||
bool8 var = FALSE;
|
bool8 var = FALSE;
|
||||||
bool8 var2;
|
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)
|
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy)
|
||||||
var = TRUE;
|
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)
|
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x1)
|
||||||
sub_8172EF0(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]);
|
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]]);
|
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].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].ballAnimActive)
|
||||||
{
|
{
|
||||||
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x80)
|
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);
|
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler ^ BIT_FLANK], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]], HEALTHBOX_ALL);
|
||||||
sub_8076918(gActiveBattler ^ BIT_FLANK);
|
sub_8076918(gActiveBattler ^ BIT_FLANK);
|
||||||
@ -335,7 +335,7 @@ static void sub_805F560(void)
|
|||||||
sp = TRUE;
|
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
|
if (gSprites[gUnknown_03005D7C[gActiveBattler]].callback == SpriteCallbackDummy
|
||||||
&& gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy)
|
&& gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy)
|
||||||
@ -356,7 +356,7 @@ static void sub_805F560(void)
|
|||||||
|
|
||||||
if (sp && r10)
|
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]]);
|
DestroySprite(&gSprites[gUnknown_03005D7C[gActiveBattler ^ BIT_FLANK]]);
|
||||||
SetBattlerShadowSpriteCallback(gActiveBattler ^ BIT_FLANK, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]], MON_DATA_SPECIES));
|
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;
|
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
|
if ((GetBattlerPosition(gActiveBattler) & BIT_FLANK) != 0) // second mon
|
||||||
xPos = 152;
|
xPos = 152;
|
||||||
@ -1624,17 +1624,7 @@ static void OpponentHandleChoosePokemon(void)
|
|||||||
battler2 = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
|
battler2 = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000))
|
GetAIPartyIndexes(gActiveBattler, &firstId, &lastId);
|
||||||
{
|
|
||||||
if (gActiveBattler == 1)
|
|
||||||
firstId = 0, lastId = 3;
|
|
||||||
else
|
|
||||||
firstId = 3, lastId = 6;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
firstId = 0, lastId = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (chosenMonId = firstId; chosenMonId < lastId; chosenMonId++)
|
for (chosenMonId = firstId; chosenMonId < lastId; chosenMonId++)
|
||||||
{
|
{
|
||||||
@ -1884,7 +1874,7 @@ static void sub_8062828(u8 taskId)
|
|||||||
u8 savedActiveBank = gActiveBattler;
|
u8 savedActiveBank = gActiveBattler;
|
||||||
|
|
||||||
gActiveBattler = gTasks[taskId].data[0];
|
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];
|
gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler];
|
||||||
sub_80613DC(gActiveBattler, FALSE);
|
sub_80613DC(gActiveBattler, FALSE);
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "battle_anim.h"
|
#include "battle_anim.h"
|
||||||
#include "battle_controllers.h"
|
#include "battle_controllers.h"
|
||||||
#include "battle_message.h"
|
#include "battle_message.h"
|
||||||
|
#include "battle_setup.h"
|
||||||
#include "cable_club.h"
|
#include "cable_club.h"
|
||||||
#include "link.h"
|
#include "link.h"
|
||||||
#include "party_menu.h"
|
#include "party_menu.h"
|
||||||
@ -153,8 +154,16 @@ static void InitSinglePlayerBtlControllers(void)
|
|||||||
|
|
||||||
gBattlerPartyIndexes[0] = 0;
|
gBattlerPartyIndexes[0] = 0;
|
||||||
gBattlerPartyIndexes[1] = 0;
|
gBattlerPartyIndexes[1] = 0;
|
||||||
gBattlerPartyIndexes[2] = 3;
|
if (BATTLE_TWO_VS_ONE_OPPONENT)
|
||||||
gBattlerPartyIndexes[3] = 3;
|
{
|
||||||
|
gBattlerPartyIndexes[2] = 3;
|
||||||
|
gBattlerPartyIndexes[3] = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gBattlerPartyIndexes[2] = 3;
|
||||||
|
gBattlerPartyIndexes[3] = 3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
|
else if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
|
||||||
{
|
{
|
||||||
|
@ -573,7 +573,7 @@ static void CB2_InitBattleInternal(void)
|
|||||||
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED)))
|
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED)))
|
||||||
{
|
{
|
||||||
CreateNPCTrainerParty(&gEnemyParty[0], gTrainerBattleOpponent_A, TRUE);
|
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);
|
CreateNPCTrainerParty(&gEnemyParty[3], gTrainerBattleOpponent_B, FALSE);
|
||||||
SetWildMonHeldItem();
|
SetWildMonHeldItem();
|
||||||
}
|
}
|
||||||
@ -3245,7 +3245,7 @@ static void DoBattleIntro(void)
|
|||||||
case B_POSITION_OPPONENT_RIGHT:
|
case B_POSITION_OPPONENT_RIGHT:
|
||||||
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
|
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);
|
BtlController_EmitDrawTrainerPic(0);
|
||||||
MarkBattlerForControllerExec(gActiveBattler);
|
MarkBattlerForControllerExec(gActiveBattler);
|
||||||
@ -3373,7 +3373,7 @@ static void DoBattleIntro(void)
|
|||||||
case 12: // nothing
|
case 12: // nothing
|
||||||
(*state)++;
|
(*state)++;
|
||||||
case 13: // second opponent's mon send out
|
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))
|
if (gBattleTypeFlags & BATTLE_TYPE_x2000000 && !(gBattleTypeFlags & BATTLE_TYPE_x80000000))
|
||||||
gActiveBattler = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
|
gActiveBattler = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
|
||||||
|
@ -2302,7 +2302,9 @@ void BufferStringBattle(u16 stringID)
|
|||||||
}
|
}
|
||||||
else
|
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;
|
stringPtr = sText_TwoTrainersWantToBattle;
|
||||||
else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
|
else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
|
||||||
stringPtr = sText_TwoTrainersWantToBattle;
|
stringPtr = sText_TwoTrainersWantToBattle;
|
||||||
@ -2345,7 +2347,9 @@ void BufferStringBattle(u16 stringID)
|
|||||||
{
|
{
|
||||||
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
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;
|
stringPtr = sText_TwoTrainersSentPkmn;
|
||||||
else if (gBattleTypeFlags & BATTLE_TYPE_x800000)
|
else if (gBattleTypeFlags & BATTLE_TYPE_x800000)
|
||||||
stringPtr = sText_TwoTrainersSentPkmn;
|
stringPtr = sText_TwoTrainersSentPkmn;
|
||||||
@ -2659,7 +2663,7 @@ static const u8 *BattleStringGetOpponentName(u8 *text, u8 multiplayerId, u8 batt
|
|||||||
toCpy = BattleStringGetOpponentNameByTrainerId(gTrainerBattleOpponent_A, text, multiplayerId, battlerId);
|
toCpy = BattleStringGetOpponentNameByTrainerId(gTrainerBattleOpponent_A, text, multiplayerId, battlerId);
|
||||||
break;
|
break;
|
||||||
case B_POSITION_OPPONENT_RIGHT:
|
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);
|
toCpy = BattleStringGetOpponentNameByTrainerId(gTrainerBattleOpponent_B, text, multiplayerId, battlerId);
|
||||||
else
|
else
|
||||||
toCpy = BattleStringGetOpponentNameByTrainerId(gTrainerBattleOpponent_A, text, multiplayerId, battlerId);
|
toCpy = BattleStringGetOpponentNameByTrainerId(gTrainerBattleOpponent_A, text, multiplayerId, battlerId);
|
||||||
@ -3098,7 +3102,7 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst)
|
|||||||
toCpy = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A);
|
toCpy = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A);
|
||||||
break;
|
break;
|
||||||
case B_POSITION_OPPONENT_RIGHT:
|
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);
|
toCpy = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_B);
|
||||||
else
|
else
|
||||||
toCpy = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A);
|
toCpy = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A);
|
||||||
|
@ -4541,6 +4541,7 @@ static void atk4F_jumpifcantswitch(void)
|
|||||||
{
|
{
|
||||||
s32 i;
|
s32 i;
|
||||||
s32 lastMonId;
|
s32 lastMonId;
|
||||||
|
u8 battlerIn1, battlerIn2;
|
||||||
struct Pokemon *party;
|
struct Pokemon *party;
|
||||||
|
|
||||||
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1] & ~(ATK4F_DONT_CHECK_STATUSES));
|
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1] & ~(ATK4F_DONT_CHECK_STATUSES));
|
||||||
@ -4551,11 +4552,28 @@ static void atk4F_jumpifcantswitch(void)
|
|||||||
{
|
{
|
||||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
|
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)
|
else if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
|
||||||
{
|
{
|
||||||
#ifndef NONMATCHING
|
|
||||||
asm("":::"r5");
|
|
||||||
#endif // NONMATCHING
|
|
||||||
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT)
|
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT)
|
||||||
party = gEnemyParty;
|
party = gEnemyParty;
|
||||||
else
|
else
|
||||||
@ -4651,8 +4669,6 @@ static void atk4F_jumpifcantswitch(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
u8 battlerIn1, battlerIn2;
|
|
||||||
|
|
||||||
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT)
|
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT)
|
||||||
{
|
{
|
||||||
battlerIn1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
|
battlerIn1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
|
||||||
@ -7952,7 +7968,16 @@ static void atk8F_forcerandomswitch(void)
|
|||||||
else
|
else
|
||||||
party = gEnemyParty;
|
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_BATTLE_TOWER && gBattleTypeFlags & BATTLE_TYPE_x2000000)
|
||||||
|| (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER))
|
|| (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER))
|
||||||
{
|
{
|
||||||
|
@ -2374,10 +2374,20 @@ void DoSpecialTrainerBattle(void)
|
|||||||
BattleTransition_StartOnField(B_TRANSITION_MAGMA);
|
BattleTransition_StartOnField(B_TRANSITION_MAGMA);
|
||||||
break;
|
break;
|
||||||
case SPECIAL_BATTLE_MULTI:
|
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;
|
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
|
else
|
||||||
|
{
|
||||||
gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER;
|
gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER;
|
||||||
|
}
|
||||||
|
|
||||||
gPartnerSpriteId = gSpecialVar_0x8007;
|
gPartnerSpriteId = gSpecialVar_0x8007;
|
||||||
FillPartnerParty(gSpecialVar_0x8006 + TRAINER_CUSTOM_PARTNER);
|
FillPartnerParty(gSpecialVar_0x8006 + TRAINER_CUSTOM_PARTNER);
|
||||||
gPartnerTrainerId = gSpecialVar_0x8006 + TRAINER_CUSTOM_PARTNER;
|
gPartnerTrainerId = gSpecialVar_0x8006 + TRAINER_CUSTOM_PARTNER;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "battle.h"
|
#include "battle.h"
|
||||||
#include "battle_controllers.h"
|
#include "battle_controllers.h"
|
||||||
#include "battle_interface.h"
|
#include "battle_interface.h"
|
||||||
|
#include "battle_setup.h"
|
||||||
#include "constants/battle_script_commands.h"
|
#include "constants/battle_script_commands.h"
|
||||||
#include "constants/abilities.h"
|
#include "constants/abilities.h"
|
||||||
#include "constants/moves.h"
|
#include "constants/moves.h"
|
||||||
@ -2333,7 +2334,29 @@ bool8 HasNoMonsToSwitch(u8 battler, u8 partyIdBattlerOn1, u8 partyIdBattlerOn2)
|
|||||||
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
|
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
|
||||||
return FALSE;
|
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)
|
if (GetBattlerSide(battler) == B_SIDE_PLAYER)
|
||||||
party = gPlayerParty;
|
party = gPlayerParty;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user