remove almost all usage of active battler

This commit is contained in:
DizzyEggg 2023-08-30 11:21:10 +02:00
parent 4683783a92
commit a7615f9649
12 changed files with 376 additions and 378 deletions

View File

@ -3,40 +3,40 @@
void AllocateBattleSpritesData(void);
void FreeBattleSpritesData(void);
u16 ChooseMoveAndTargetInBattlePalace(void);
u16 ChooseMoveAndTargetInBattlePalace(u32 battler);
void SpriteCB_WaitForBattlerBallReleaseAnim(struct Sprite *sprite);
void SpriteCB_TrainerSlideIn(struct Sprite *sprite);
void InitAndLaunchChosenStatusAnimation(bool8 isStatus2, u32 status);
void InitAndLaunchChosenStatusAnimation(u32 battler, bool32 isStatus2, u32 status);
bool8 TryHandleLaunchBattleTableAnimation(u8 activeBattlerId, u8 attacker, u8 target, u8 tableId, u16 argument);
void InitAndLaunchSpecialAnimation(u8 activeBattlerId, u8 attacker, u8 target, u8 tableId);
bool8 IsBattleSEPlaying(u8 battlerId);
void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battlerId);
bool8 IsBattleSEPlaying(u8 battler);
void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battler);
void BattleGfxSfxDummy2(u16 species);
void DecompressTrainerFrontPic(u16 frontPicId, u8 battlerId);
void DecompressTrainerBackPic(u16 backPicId, u8 battlerId);
void DecompressTrainerFrontPic(u16 frontPicId, u8 battler);
void DecompressTrainerBackPic(u16 backPicId, u8 battler);
void FreeTrainerFrontPicPalette(u16 frontPicId);
bool8 BattleLoadAllHealthBoxesGfx(u8 state);
void LoadBattleBarGfx(u8 unused);
bool8 BattleInitAllSprites(u8 *state1, u8 *battlerId);
bool8 BattleInitAllSprites(u8 *state1, u8 *battler);
void ClearSpritesHealthboxAnimData(void);
void CopyAllBattleSpritesInvisibilities(void);
void CopyBattleSpriteInvisibility(u8 battlerId);
void CopyBattleSpriteInvisibility(u8 battler);
void HandleSpeciesGfxDataChange(u8 attacker, u8 target, bool32 megaEvo, bool8 trackEnemyPersonality);
void BattleLoadSubstituteOrMonSpriteGfx(u8 battlerId, bool8 loadMonSprite);
void LoadBattleMonGfxAndAnimate(u8 battlerId, bool8 loadMonSprite, u8 spriteId);
void TrySetBehindSubstituteSpriteBit(u8 battlerId, u16 move);
void ClearBehindSubstituteBit(u8 battlerId);
void HandleLowHpMusicChange(struct Pokemon *mon, u8 battlerId);
void BattleLoadSubstituteOrMonSpriteGfx(u8 battler, bool8 loadMonSprite);
void LoadBattleMonGfxAndAnimate(u8 battler, bool8 loadMonSprite, u8 spriteId);
void TrySetBehindSubstituteSpriteBit(u8 battler, u16 move);
void ClearBehindSubstituteBit(u8 battler);
void HandleLowHpMusicChange(struct Pokemon *mon, u8 battler);
void BattleStopLowHpSound(void);
u8 GetMonHPBarLevel(struct Pokemon *mon);
void HandleBattleLowHpMusicChange(void);
void SetBattlerSpriteAffineMode(u8 affineMode);
void LoadAndCreateEnemyShadowSprites(void);
void SpriteCB_SetInvisible(struct Sprite *sprite);
void SetBattlerShadowSpriteCallback(u8 battlerId, u16 species);
void HideBattlerShadowSprite(u8 battlerId);
void SetBattlerShadowSpriteCallback(u8 battler, u16 species);
void HideBattlerShadowSprite(u8 battler);
void FillAroundBattleWindows(void);
void ClearTemporarySpeciesSpriteData(u8 battlerId, bool8 dontClearSubstitute);
void ClearTemporarySpeciesSpriteData(u8 battler, bool8 dontClearSubstitute);
void AllocateMonSpritesGfx(void);
void FreeMonSpritesGfx(void);
bool32 ShouldPlayNormalMonCry(struct Pokemon *mon);

View File

@ -305,7 +305,7 @@
// - Unown has 1 frame, presumably to avoid the work of animating all 28 of its forms
#define MAX_MON_PIC_FRAMES 2
#define BATTLE_ALIVE_EXCEPT_ACTIVE 0
#define BATTLE_ALIVE_EXCEPT_BATTLER 0
#define BATTLE_ALIVE_ATK_SIDE 1
#define BATTLE_ALIVE_DEF_SIDE 2
#define BATTLE_ALIVE_EXCEPT_ATTACKER 3

View File

@ -490,7 +490,7 @@ void GiveBoxMonInitialMoveset_Fast(struct BoxPokemon *boxMon);
u16 MonTryLearningNewMove(struct Pokemon *mon, bool8 firstMove);
void DeleteFirstMoveAndGiveMoveToMon(struct Pokemon *mon, u16 move);
void DeleteFirstMoveAndGiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move);
u8 CountAliveMonsInBattle(u8 caseId);
u8 CountAliveMonsInBattle(u8 caseId, u32 battler);
u8 GetDefaultMoveTarget(u8 battlerId);
u8 GetMonGender(struct Pokemon *mon);
u8 GetBoxMonGender(struct BoxPokemon *boxMon);
@ -538,7 +538,7 @@ void CopyPlayerPartyMonToBattleData(u8 battlerId, u8 partyIndex);
bool8 ExecuteTableBasedItemEffect(struct Pokemon *mon, u16 item, u8 partyIndex, u8 moveIndex);
bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 moveIndex, u8 e);
bool8 HealStatusConditions(struct Pokemon *mon, u32 battlePartyId, u32 healMask, u8 battlerId);
u8 GetItemEffectParamOffset(u16 itemId, u8 effectByte, u8 effectBit);
u8 GetItemEffectParamOffset(u32 battler, u16 itemId, u8 effectByte, u8 effectBit);
u8 *UseStatIncreaseItem(u16 itemId);
u8 GetNature(struct Pokemon *mon);
u8 GetNatureFromPersonality(u32 personality);

View File

@ -205,7 +205,7 @@ void BattleAI_SetupAIData(u8 defaultScoreMoves, u32 battler)
defaultScoreMoves >>= 1;
}
moveLimitations = AI_DATA->moveLimitations[gActiveBattler];
moveLimitations = AI_DATA->moveLimitations[battler];
// Ignore moves that aren't possible to use.
for (i = 0; i < MAX_MON_MOVES; i++)
@ -214,7 +214,7 @@ void BattleAI_SetupAIData(u8 defaultScoreMoves, u32 battler)
AI_THINKING_STRUCT->score[i] = 0;
}
//sBattler_AI = gActiveBattler;
//sBattler_AI = battler;
gBattlerTarget = SetRandomTarget(sBattler_AI);
gBattleStruct->aiChosenTarget[sBattler_AI] = gBattlerTarget;
}
@ -241,7 +241,7 @@ u8 BattleAI_ChooseMoveOrAction(void)
u8 ComputeBattleAiScores(u8 battler)
{
sBattler_AI = battler;
BattleAI_SetupAIData(0xF);
BattleAI_SetupAIData(0xF, sBattler_AI);
return BattleAI_ChooseMoveOrAction();
}
@ -339,15 +339,15 @@ void Ai_UpdateFaintData(u32 battler)
aiMon->isFainted = TRUE;
}
static void SetBattlerAiData(u8 battlerId)
static void SetBattlerAiData(u8 battler)
{
AI_DATA->abilities[battlerId] = AI_GetAbility(battlerId);
AI_DATA->items[battlerId] = gBattleMons[battlerId].item;
AI_DATA->holdEffects[battlerId] = AI_GetHoldEffect(battlerId);
AI_DATA->holdEffectParams[battlerId] = GetBattlerHoldEffectParam(battlerId);
AI_DATA->predictedMoves[battlerId] = gLastMoves[battlerId];
AI_DATA->hpPercents[battlerId] = GetHealthPercentage(battlerId);
AI_DATA->moveLimitations[battlerId] = CheckMoveLimitations(battlerId, 0, MOVE_LIMITATIONS_ALL);
AI_DATA->abilities[battler] = AI_GetAbility(battler);
AI_DATA->items[battler] = gBattleMons[battler].item;
AI_DATA->holdEffects[battler] = AI_GetHoldEffect(battler);
AI_DATA->holdEffectParams[battler] = GetBattlerHoldEffectParam(battler);
AI_DATA->predictedMoves[battler] = gLastMoves[battler];
AI_DATA->hpPercents[battler] = GetHealthPercentage(battler);
AI_DATA->moveLimitations[battler] = CheckMoveLimitations(battler, 0, MOVE_LIMITATIONS_ALL);
}
void GetAiLogicData(void)
@ -523,9 +523,9 @@ static u8 ChooseMoveOrAction_Doubles(void)
else
{
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
BattleAI_SetupAIData(gBattleStruct->palaceFlags >> 4);
BattleAI_SetupAIData(gBattleStruct->palaceFlags >> 4, sBattler_AI);
else
BattleAI_SetupAIData(0xF);
BattleAI_SetupAIData(0xF, sBattler_AI);
gBattlerTarget = i;
if ((i & BIT_SIDE) != (sBattler_AI & BIT_SIDE))

View File

@ -1072,7 +1072,7 @@ static bool8 ShouldUseItem(u32 battler)
shouldUse = AI_ShouldHeal(battler, 0);
break;
case EFFECT_ITEM_RESTORE_HP:
shouldUse = AI_ShouldHeal(battler, itemEffects[GetItemEffectParamOffset(item, 4, 4)]);
shouldUse = AI_ShouldHeal(battler, itemEffects[GetItemEffectParamOffset(battler, item, 4, 4)]);
break;
case EFFECT_ITEM_CURE_STATUS:
if (itemEffects[3] & ITEM3_SLEEP && gBattleMons[battler].status1 & STATUS1_SLEEP)

View File

@ -2552,14 +2552,11 @@ enum {
bool32 ShouldPivot(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u8 moveIndex)
{
bool8 hasStatBoost = AnyUsefulStatIsRaised(battlerAtk) || gBattleMons[battlerDef].statStages[STAT_EVASION] >= 9; //Significant boost in evasion for any class
u8 backupBattler = gActiveBattler;
bool32 shouldSwitch;
u8 battlerToSwitch;
gActiveBattler = battlerAtk;
shouldSwitch = ShouldSwitch(battlerAtk);
battlerToSwitch = *(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler);
gActiveBattler = backupBattler;
battlerToSwitch = *(gBattleStruct->AI_monToSwitchIntoId + battlerAtk);
if (PartyBattlerShouldAvoidHazards(battlerAtk, battlerToSwitch))
return DONT_PIVOT;
@ -3311,7 +3308,7 @@ bool32 ShouldUseWishAromatherapy(u8 battlerAtk, u8 battlerDef, u16 move)
GetAIPartyIndexes(battlerAtk, &firstId, &lastId);
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
if (GetBattlerSide(battlerAtk) == B_SIDE_PLAYER)
party = gPlayerParty;
else
party = gEnemyParty;

View File

@ -704,7 +704,7 @@ static void HandleInputChooseMove(u32 battler)
{
canSelectTarget = 0;
}
else if (!(moveTarget & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED)) && CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_ACTIVE) <= 1)
else if (!(moveTarget & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED)) && CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_BATTLER, battler) <= 1)
{
gMultiUsePlayerCursor = GetDefaultMoveTarget(battler);
canSelectTarget = 0;
@ -1927,7 +1927,7 @@ static void PlayerChooseMoveInBattlePalace(u32 battler)
if (--*(gBattleStruct->arenaMindPoints + battler) == 0)
{
gBattlePalaceMoveSelectionRngValue = gRngValue;
BtlController_EmitTwoReturnValues(battler, BUFFER_B, 10, ChooseMoveAndTargetInBattlePalace());
BtlController_EmitTwoReturnValues(battler, BUFFER_B, 10, ChooseMoveAndTargetInBattlePalace(battler));
PlayerBufferExecCompleted(battler);
}
}

View File

@ -2724,7 +2724,7 @@ void BtlController_HandleStatusAnimation(u32 battler)
{
if (!IsBattleSEPlaying(battler))
{
InitAndLaunchChosenStatusAnimation(gBattleResources->bufferA[battler][1],
InitAndLaunchChosenStatusAnimation(battler, gBattleResources->bufferA[battler][1],
gBattleResources->bufferA[battler][2] | (gBattleResources->bufferA[battler][3] << 8) | (gBattleResources->bufferA[battler][4] << 16) | (gBattleResources->bufferA[battler][5] << 24));
gBattlerControllerFuncs[battler] = Controller_WaitForStatusAnimation;
}

View File

@ -31,8 +31,8 @@ extern const struct CompressedSpriteSheet gSpriteSheet_EnemyShadow;
extern const struct SpriteTemplate gSpriteTemplate_EnemyShadow;
// this file's functions
static u8 GetBattlePalaceMoveGroup(u8 battlerId, u16 move);
static u16 GetBattlePalaceTarget(void);
static u8 GetBattlePalaceMoveGroup(u8 battler, u16 move);
static u16 GetBattlePalaceTarget(u32 battler);
static void SpriteCB_TrainerSlideVertical(struct Sprite *sprite);
static bool8 ShouldAnimBeDoneRegardlessOfSubstitute(u8 animId);
static void Task_ClearBitWhenBattleTableAnimDone(u8 taskId);
@ -104,12 +104,12 @@ void FreeBattleSpritesData(void)
}
// Pokemon chooses move to use in Battle Palace rather than player
u16 ChooseMoveAndTargetInBattlePalace(void)
u16 ChooseMoveAndTargetInBattlePalace(u32 battler)
{
s32 i, var1, var2;
s32 chosenMoveId = -1;
struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[gActiveBattler][4]);
u8 unusableMovesBits = CheckMoveLimitations(gActiveBattler, 0, MOVE_LIMITATIONS_ALL);
struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battler][4]);
u8 unusableMovesBits = CheckMoveLimitations(battler, 0, MOVE_LIMITATIONS_ALL);
s32 percent = Random() % 100;
// Heavy variable re-use here makes this hard to read without defines
@ -125,7 +125,7 @@ u16 ChooseMoveAndTargetInBattlePalace(void)
// If battler is < 50% HP and not asleep, use second set of move group likelihoods
// otherwise use first set
i = (gBattleStruct->palaceFlags & gBitTable[gActiveBattler]) ? 2 : 0;
i = (gBattleStruct->palaceFlags & gBitTable[battler]) ? 2 : 0;
minGroupNum = i;
maxGroupNum = i + 2; // + 2 because there are two percentages per set of likelihoods
@ -136,7 +136,7 @@ u16 ChooseMoveAndTargetInBattlePalace(void)
// Otherwise use move from "Support" group
for (; i < maxGroupNum; i++)
{
if (gBattlePalaceNatureToMoveGroupLikelihood[GetNatureFromPersonality(gBattleMons[gActiveBattler].personality)][i] > percent)
if (gBattlePalaceNatureToMoveGroupLikelihood[GetNatureFromPersonality(gBattleMons[battler].personality)][i] > percent)
break;
}
selectedGroup = i - minGroupNum;
@ -148,7 +148,7 @@ u16 ChooseMoveAndTargetInBattlePalace(void)
{
if (moveInfo->moves[i] == MOVE_NONE)
break;
if (selectedGroup == GetBattlePalaceMoveGroup(gActiveBattler, moveInfo->moves[i]) && moveInfo->currentPp[i] != 0)
if (selectedGroup == GetBattlePalaceMoveGroup(battler, moveInfo->moves[i]) && moveInfo->currentPp[i] != 0)
selectedMoves |= gBitTable[i];
}
@ -157,8 +157,7 @@ u16 ChooseMoveAndTargetInBattlePalace(void)
{
gBattleStruct->palaceFlags &= 0xF;
gBattleStruct->palaceFlags |= (selectedMoves << 4);
sBattler_AI = gActiveBattler;
BattleAI_SetupAIData(selectedMoves);
BattleAI_SetupAIData(selectedMoves, battler);
chosenMoveId = BattleAI_ChooseMoveOrAction();
}
@ -176,11 +175,11 @@ u16 ChooseMoveAndTargetInBattlePalace(void)
{
// validMoveFlags is used here as a bitfield for which moves can be used for each move group type
// first 4 bits are for attack (1 for each move), then 4 bits for defense, and 4 for support
if (GetBattlePalaceMoveGroup(gActiveBattler, moveInfo->moves[i]) == PALACE_MOVE_GROUP_ATTACK && !(gBitTable[i] & unusableMovesBits))
if (GetBattlePalaceMoveGroup(battler, moveInfo->moves[i]) == PALACE_MOVE_GROUP_ATTACK && !(gBitTable[i] & unusableMovesBits))
validMoveFlags += (1 << 0);
if (GetBattlePalaceMoveGroup(gActiveBattler, moveInfo->moves[i]) == PALACE_MOVE_GROUP_DEFENSE && !(gBitTable[i] & unusableMovesBits))
if (GetBattlePalaceMoveGroup(battler, moveInfo->moves[i]) == PALACE_MOVE_GROUP_DEFENSE && !(gBitTable[i] & unusableMovesBits))
validMoveFlags += (1 << 4);
if (GetBattlePalaceMoveGroup(gActiveBattler, moveInfo->moves[i]) == PALACE_MOVE_GROUP_SUPPORT && !(gBitTable[i] & unusableMovesBits))
if (GetBattlePalaceMoveGroup(battler, moveInfo->moves[i]) == PALACE_MOVE_GROUP_SUPPORT && !(gBitTable[i] & unusableMovesBits))
validMoveFlags += (1 << 8);
}
@ -217,7 +216,7 @@ u16 ChooseMoveAndTargetInBattlePalace(void)
do
{
i = Random() % MAX_MON_MOVES;
if (!(gBitTable[i] & unusableMovesBits) && validMoveGroup == GetBattlePalaceMoveGroup(gActiveBattler, moveInfo->moves[i]))
if (!(gBitTable[i] & unusableMovesBits) && validMoveGroup == GetBattlePalaceMoveGroup(battler, moveInfo->moves[i]))
chosenMoveId = i;
} while (chosenMoveId == -1);
}
@ -226,13 +225,13 @@ u16 ChooseMoveAndTargetInBattlePalace(void)
// then there's a 50% chance it won't be used anyway
if (Random() % 100 > 49)
{
gProtectStructs[gActiveBattler].palaceUnableToUseMove = TRUE;
gProtectStructs[battler].palaceUnableToUseMove = TRUE;
return 0;
}
}
else
{
gProtectStructs[gActiveBattler].palaceUnableToUseMove = TRUE;
gProtectStructs[battler].palaceUnableToUseMove = TRUE;
return 0;
}
}
@ -246,15 +245,15 @@ u16 ChooseMoveAndTargetInBattlePalace(void)
}
else
{
moveTarget = GetBattlerMoveTargetType(gActiveBattler, moveInfo->moves[chosenMoveId]);
moveTarget = GetBattlerMoveTargetType(battler, moveInfo->moves[chosenMoveId]);
}
if (moveTarget & MOVE_TARGET_USER)
chosenMoveId |= (gActiveBattler << 8);
chosenMoveId |= (battler << 8);
else if (moveTarget == MOVE_TARGET_SELECTED)
chosenMoveId |= GetBattlePalaceTarget();
chosenMoveId |= GetBattlePalaceTarget(battler);
else
chosenMoveId |= (GetBattlerAtPosition(BATTLE_OPPOSITE(GET_BATTLER_SIDE(gActiveBattler))) << 8);
chosenMoveId |= (GetBattlerAtPosition(BATTLE_OPPOSITE(GET_BATTLER_SIDE(battler))) << 8);
return chosenMoveId;
}
@ -268,9 +267,9 @@ u16 ChooseMoveAndTargetInBattlePalace(void)
#undef numValidMoveGroups
#undef validMoveGroup
static u8 GetBattlePalaceMoveGroup(u8 battlerId, u16 move)
static u8 GetBattlePalaceMoveGroup(u8 battler, u16 move)
{
switch (GetBattlerMoveTargetType(battlerId, move))
switch (GetBattlerMoveTargetType(battler, move))
{
case MOVE_TARGET_SELECTED:
case MOVE_TARGET_USER_OR_SELECTED:
@ -292,13 +291,13 @@ static u8 GetBattlePalaceMoveGroup(u8 battlerId, u16 move)
}
}
static u16 GetBattlePalaceTarget(void)
static u16 GetBattlePalaceTarget(u32 battler)
{
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
u8 opposing1, opposing2;
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
if (GetBattlerSide(battler) == B_SIDE_PLAYER)
{
opposing1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
opposing2 = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
@ -310,9 +309,9 @@ static u16 GetBattlePalaceTarget(void)
}
if (gBattleMons[opposing1].hp == gBattleMons[opposing2].hp)
return (BATTLE_OPPOSITE(gActiveBattler & BIT_SIDE) + (Random() & 2)) << 8;
return (BATTLE_OPPOSITE(battler & BIT_SIDE) + (Random() & 2)) << 8;
switch (gBattlePalaceNatureToMoveTarget[GetNatureFromPersonality(gBattleMons[gActiveBattler].personality)])
switch (gBattlePalaceNatureToMoveTarget[GetNatureFromPersonality(gBattleMons[battler].personality)])
{
case PALACE_TARGET_STRONGER:
if (gBattleMons[opposing1].hp > gBattleMons[opposing2].hp)
@ -325,11 +324,11 @@ static u16 GetBattlePalaceTarget(void)
else
return opposing2 << 8;
case PALACE_TARGET_RANDOM:
return (BATTLE_OPPOSITE(gActiveBattler & BIT_SIDE) + (Random() & 2)) << 8;
return (BATTLE_OPPOSITE(battler & BIT_SIDE) + (Random() & 2)) << 8;
}
}
return BATTLE_OPPOSITE(gActiveBattler) << 8;
return BATTLE_OPPOSITE(battler) << 8;
}
// Wait for the pokemon to finish appearing out from the pokeball on send out
@ -393,38 +392,38 @@ static void SpriteCB_TrainerSlideVertical(struct Sprite *sprite)
#undef sSpeedX
void InitAndLaunchChosenStatusAnimation(bool8 isStatus2, u32 status)
void InitAndLaunchChosenStatusAnimation(u32 battler, bool32 isStatus2, u32 status)
{
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].statusAnimActive = 1;
gBattleSpritesDataPtr->healthBoxesData[battler].statusAnimActive = 1;
if (!isStatus2)
{
if (status == STATUS1_FREEZE || status == STATUS1_FROSTBITE)
LaunchStatusAnimation(gActiveBattler, B_ANIM_STATUS_FRZ);
LaunchStatusAnimation(battler, B_ANIM_STATUS_FRZ);
else if (status == STATUS1_POISON || status & STATUS1_TOXIC_POISON)
LaunchStatusAnimation(gActiveBattler, B_ANIM_STATUS_PSN);
LaunchStatusAnimation(battler, B_ANIM_STATUS_PSN);
else if (status == STATUS1_BURN)
LaunchStatusAnimation(gActiveBattler, B_ANIM_STATUS_BRN);
LaunchStatusAnimation(battler, B_ANIM_STATUS_BRN);
else if (status & STATUS1_SLEEP)
LaunchStatusAnimation(gActiveBattler, B_ANIM_STATUS_SLP);
LaunchStatusAnimation(battler, B_ANIM_STATUS_SLP);
else if (status == STATUS1_PARALYSIS)
LaunchStatusAnimation(gActiveBattler, B_ANIM_STATUS_PRZ);
LaunchStatusAnimation(battler, B_ANIM_STATUS_PRZ);
else // no animation
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].statusAnimActive = 0;
gBattleSpritesDataPtr->healthBoxesData[battler].statusAnimActive = 0;
}
else
{
if (status & STATUS2_INFATUATION)
LaunchStatusAnimation(gActiveBattler, B_ANIM_STATUS_INFATUATION);
LaunchStatusAnimation(battler, B_ANIM_STATUS_INFATUATION);
else if (status & STATUS2_CONFUSION)
LaunchStatusAnimation(gActiveBattler, B_ANIM_STATUS_CONFUSION);
LaunchStatusAnimation(battler, B_ANIM_STATUS_CONFUSION);
else if (status & STATUS2_CURSED)
LaunchStatusAnimation(gActiveBattler, B_ANIM_STATUS_CURSED);
LaunchStatusAnimation(battler, B_ANIM_STATUS_CURSED);
else if (status & STATUS2_NIGHTMARE)
LaunchStatusAnimation(gActiveBattler, B_ANIM_STATUS_NIGHTMARE);
LaunchStatusAnimation(battler, B_ANIM_STATUS_NIGHTMARE);
else if (status & STATUS2_WRAPPED)
LaunchStatusAnimation(gActiveBattler, B_ANIM_STATUS_WRAPPED); // this animation doesn't actually exist
LaunchStatusAnimation(battler, B_ANIM_STATUS_WRAPPED); // this animation doesn't actually exist
else // no animation
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].statusAnimActive = 0;
gBattleSpritesDataPtr->healthBoxesData[battler].statusAnimActive = 0;
}
}
@ -521,14 +520,14 @@ static void Task_ClearBitWhenSpecialAnimDone(u8 taskId)
#undef tBattlerId
// Check if SE has finished or 30 calls, whichever comes first
bool8 IsBattleSEPlaying(u8 battlerId)
bool8 IsBattleSEPlaying(u8 battler)
{
u8 zero = 0;
if (IsSEPlaying())
{
gBattleSpritesDataPtr->healthBoxesData[battlerId].soundTimer++;
if (gBattleSpritesDataPtr->healthBoxesData[battlerId].soundTimer < 30)
gBattleSpritesDataPtr->healthBoxesData[battler].soundTimer++;
if (gBattleSpritesDataPtr->healthBoxesData[battler].soundTimer < 30)
return TRUE;
m4aMPlayStop(&gMPlayInfo_SE1);
@ -536,7 +535,7 @@ bool8 IsBattleSEPlaying(u8 battlerId)
}
if (zero == 0)
{
gBattleSpritesDataPtr->healthBoxesData[battlerId].soundTimer = 0;
gBattleSpritesDataPtr->healthBoxesData[battler].soundTimer = 0;
return FALSE;
}
@ -544,11 +543,11 @@ bool8 IsBattleSEPlaying(u8 battlerId)
return TRUE;
}
void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battlerId)
void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battler)
{
u32 monsPersonality, currentPersonality, otId, currentOtId, species, paletteOffset, position;
const void *lzPaletteData;
struct Pokemon *illusionMon = GetIllusionMonPtr(battlerId);
struct Pokemon *illusionMon = GetIllusionMonPtr(battler);
if (illusionMon != NULL)
mon = illusionMon;
@ -558,7 +557,7 @@ void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battlerId)
monsPersonality = GetMonData(mon, MON_DATA_PERSONALITY);
otId = GetMonData(mon, MON_DATA_OT_ID);
if (gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies == SPECIES_NONE)
if (gBattleSpritesDataPtr->battlerData[battler].transformSpecies == SPECIES_NONE)
{
species = GetMonData(mon, MON_DATA_SPECIES);
currentPersonality = monsPersonality;
@ -566,18 +565,18 @@ void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battlerId)
}
else
{
species = gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies;
species = gBattleSpritesDataPtr->battlerData[battler].transformSpecies;
#if B_TRANSFORM_SHINY >= GEN_4
currentPersonality = gTransformedPersonalities[battlerId];
currentOtId = gTransformedOtIds[battlerId];
currentPersonality = gTransformedPersonalities[battler];
currentOtId = gTransformedOtIds[battler];
#else
currentPersonality = monsPersonality;
currentOtId = otId;
#endif
}
position = GetBattlerPosition(battlerId);
if (GetBattlerSide(battlerId) == B_SIDE_OPPONENT)
position = GetBattlerPosition(battler);
if (GetBattlerSide(battler) == B_SIDE_OPPONENT)
{
HandleLoadSpecialPokePic(TRUE,
gMonSpritesGfxPtr->sprites.ptr[position],
@ -590,19 +589,19 @@ void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battlerId)
species, currentPersonality);
}
paletteOffset = OBJ_PLTT_ID(battlerId);
paletteOffset = OBJ_PLTT_ID(battler);
if (gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies == SPECIES_NONE)
if (gBattleSpritesDataPtr->battlerData[battler].transformSpecies == SPECIES_NONE)
lzPaletteData = GetMonFrontSpritePal(mon);
else
lzPaletteData = GetMonSpritePalFromSpeciesAndPersonality(species, currentOtId, currentPersonality);
LZDecompressWram(lzPaletteData, gDecompressionBuffer);
LoadPalette(gDecompressionBuffer, paletteOffset, PLTT_SIZE_4BPP);
LoadPalette(gDecompressionBuffer, BG_PLTT_ID(8) + BG_PLTT_ID(battlerId), PLTT_SIZE_4BPP);
LoadPalette(gDecompressionBuffer, BG_PLTT_ID(8) + BG_PLTT_ID(battler), PLTT_SIZE_4BPP);
// transform's pink color
if (gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies != SPECIES_NONE)
if (gBattleSpritesDataPtr->battlerData[battler].transformSpecies != SPECIES_NONE)
{
BlendPalette(paletteOffset, 16, 6, RGB_WHITE);
CpuCopy32(&gPlttBufferFaded[paletteOffset], &gPlttBufferUnfaded[paletteOffset], PLTT_SIZEOF(16));
@ -613,23 +612,23 @@ void BattleGfxSfxDummy2(u16 species)
{
}
void DecompressTrainerFrontPic(u16 frontPicId, u8 battlerId)
void DecompressTrainerFrontPic(u16 frontPicId, u8 battler)
{
u8 position = GetBattlerPosition(battlerId);
u8 position = GetBattlerPosition(battler);
DecompressPicFromTable(&gTrainerFrontPicTable[frontPicId],
gMonSpritesGfxPtr->sprites.ptr[position],
SPECIES_NONE);
LoadCompressedSpritePalette(&gTrainerFrontPicPaletteTable[frontPicId]);
}
void DecompressTrainerBackPic(u16 backPicId, u8 battlerId)
void DecompressTrainerBackPic(u16 backPicId, u8 battler)
{
u8 position = GetBattlerPosition(battlerId);
u8 position = GetBattlerPosition(battler);
DecompressPicFromTable(&gTrainerBackPicTable[backPicId],
gMonSpritesGfxPtr->sprites.ptr[position],
SPECIES_NONE);
LoadCompressedPalette(gTrainerBackPicPaletteTable[backPicId].data,
OBJ_PLTT_ID(battlerId), PLTT_SIZE_4BPP);
OBJ_PLTT_ID(battler), PLTT_SIZE_4BPP);
}
void FreeTrainerFrontPicPalette(u16 frontPicId)
@ -729,7 +728,7 @@ void LoadBattleBarGfx(u8 unused)
LZDecompressWram(gBattleInterfaceGfx_BattleBar, gMonSpritesGfxPtr->barFontGfx);
}
bool8 BattleInitAllSprites(u8 *state1, u8 *battlerId)
bool8 BattleInitAllSprites(u8 *state1, u8 *battler)
{
bool8 retVal = FALSE;
@ -740,13 +739,13 @@ bool8 BattleInitAllSprites(u8 *state1, u8 *battlerId)
(*state1)++;
break;
case 1:
if (!BattleLoadAllHealthBoxesGfx(*battlerId))
if (!BattleLoadAllHealthBoxesGfx(*battler))
{
(*battlerId)++;
(*battler)++;
}
else
{
*battlerId = 0;
*battler = 0;
(*state1)++;
}
break;
@ -754,47 +753,47 @@ bool8 BattleInitAllSprites(u8 *state1, u8 *battlerId)
(*state1)++;
break;
case 3:
if ((gBattleTypeFlags & BATTLE_TYPE_SAFARI) && *battlerId == 0)
gHealthboxSpriteIds[*battlerId] = CreateSafariPlayerHealthboxSprites();
if ((gBattleTypeFlags & BATTLE_TYPE_SAFARI) && *battler == 0)
gHealthboxSpriteIds[*battler] = CreateSafariPlayerHealthboxSprites();
else
gHealthboxSpriteIds[*battlerId] = CreateBattlerHealthboxSprites(*battlerId);
gHealthboxSpriteIds[*battler] = CreateBattlerHealthboxSprites(*battler);
(*battlerId)++;
if (*battlerId == gBattlersCount)
(*battler)++;
if (*battler == gBattlersCount)
{
*battlerId = 0;
*battler = 0;
(*state1)++;
}
break;
case 4:
InitBattlerHealthboxCoords(*battlerId);
if (gBattlerPositions[*battlerId] <= B_POSITION_OPPONENT_LEFT)
DummyBattleInterfaceFunc(gHealthboxSpriteIds[*battlerId], FALSE);
InitBattlerHealthboxCoords(*battler);
if (gBattlerPositions[*battler] <= B_POSITION_OPPONENT_LEFT)
DummyBattleInterfaceFunc(gHealthboxSpriteIds[*battler], FALSE);
else
DummyBattleInterfaceFunc(gHealthboxSpriteIds[*battlerId], TRUE);
DummyBattleInterfaceFunc(gHealthboxSpriteIds[*battler], TRUE);
(*battlerId)++;
if (*battlerId == gBattlersCount)
(*battler)++;
if (*battler == gBattlersCount)
{
*battlerId = 0;
*battler = 0;
(*state1)++;
}
break;
case 5:
if (GetBattlerSide(*battlerId) == B_SIDE_PLAYER)
if (GetBattlerSide(*battler) == B_SIDE_PLAYER)
{
if (!(gBattleTypeFlags & BATTLE_TYPE_SAFARI))
UpdateHealthboxAttribute(gHealthboxSpriteIds[*battlerId], &gPlayerParty[gBattlerPartyIndexes[*battlerId]], HEALTHBOX_ALL);
UpdateHealthboxAttribute(gHealthboxSpriteIds[*battler], &gPlayerParty[gBattlerPartyIndexes[*battler]], HEALTHBOX_ALL);
}
else
{
UpdateHealthboxAttribute(gHealthboxSpriteIds[*battlerId], &gEnemyParty[gBattlerPartyIndexes[*battlerId]], HEALTHBOX_ALL);
UpdateHealthboxAttribute(gHealthboxSpriteIds[*battler], &gEnemyParty[gBattlerPartyIndexes[*battler]], HEALTHBOX_ALL);
}
SetHealthboxSpriteInvisible(gHealthboxSpriteIds[*battlerId]);
(*battlerId)++;
if (*battlerId == gBattlersCount)
SetHealthboxSpriteInvisible(gHealthboxSpriteIds[*battler]);
(*battler)++;
if (*battler == gBattlersCount)
{
*battlerId = 0;
*battler = 0;
(*state1)++;
}
break;
@ -828,9 +827,9 @@ void CopyAllBattleSpritesInvisibilities(void)
gBattleSpritesDataPtr->battlerData[i].invisible = gSprites[gBattlerSpriteIds[i]].invisible;
}
void CopyBattleSpriteInvisibility(u8 battlerId)
void CopyBattleSpriteInvisibility(u8 battler)
{
gBattleSpritesDataPtr->battlerData[battlerId].invisible = gSprites[gBattlerSpriteIds[battlerId]].invisible;
gBattleSpritesDataPtr->battlerData[battler].invisible = gSprites[gBattlerSpriteIds[battler]].invisible;
}
void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bool8 trackEnemyPersonality)
@ -925,7 +924,7 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bo
StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerAtk]], 0);
}
void BattleLoadSubstituteOrMonSpriteGfx(u8 battlerId, bool8 loadMonSprite)
void BattleLoadSubstituteOrMonSpriteGfx(u8 battler, bool8 loadMonSprite)
{
s32 i, position, palOffset;
@ -934,11 +933,11 @@ void BattleLoadSubstituteOrMonSpriteGfx(u8 battlerId, bool8 loadMonSprite)
if (IsContest())
position = B_POSITION_PLAYER_LEFT;
else
position = GetBattlerPosition(battlerId);
position = GetBattlerPosition(battler);
if (IsContest())
LZDecompressVram(gSubstituteDollBackGfx, gMonSpritesGfxPtr->sprites.ptr[position]);
else if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
else if (GetBattlerSide(battler) != B_SIDE_PLAYER)
LZDecompressVram(gSubstituteDollFrontGfx, gMonSpritesGfxPtr->sprites.ptr[position]);
else
LZDecompressVram(gSubstituteDollBackGfx, gMonSpritesGfxPtr->sprites.ptr[position]);
@ -948,61 +947,61 @@ void BattleLoadSubstituteOrMonSpriteGfx(u8 battlerId, bool8 loadMonSprite)
Dma3CopyLarge32_(gMonSpritesGfxPtr->sprites.ptr[position], &gMonSpritesGfxPtr->sprites.byte[position][MON_PIC_SIZE * i], MON_PIC_SIZE);
}
palOffset = OBJ_PLTT_ID(battlerId);
palOffset = OBJ_PLTT_ID(battler);
LoadCompressedPalette(gSubstituteDollPal, palOffset, PLTT_SIZE_4BPP);
}
else
{
if (!IsContest())
BattleLoadMonSpriteGfx(&GetBattlerParty(battlerId)[gBattlerPartyIndexes[battlerId]], battlerId);
BattleLoadMonSpriteGfx(&GetBattlerParty(battler)[gBattlerPartyIndexes[battler]], battler);
}
}
void LoadBattleMonGfxAndAnimate(u8 battlerId, bool8 loadMonSprite, u8 spriteId)
void LoadBattleMonGfxAndAnimate(u8 battler, bool8 loadMonSprite, u8 spriteId)
{
BattleLoadSubstituteOrMonSpriteGfx(battlerId, loadMonSprite);
BattleLoadSubstituteOrMonSpriteGfx(battler, loadMonSprite);
StartSpriteAnim(&gSprites[spriteId], 0);
if (!loadMonSprite)
gSprites[spriteId].y = GetSubstituteSpriteDefault_Y(battlerId);
gSprites[spriteId].y = GetSubstituteSpriteDefault_Y(battler);
else
gSprites[spriteId].y = GetBattlerSpriteDefault_Y(battlerId);
gSprites[spriteId].y = GetBattlerSpriteDefault_Y(battler);
}
void TrySetBehindSubstituteSpriteBit(u8 battlerId, u16 move)
void TrySetBehindSubstituteSpriteBit(u8 battler, u16 move)
{
if (move == MOVE_SUBSTITUTE)
gBattleSpritesDataPtr->battlerData[battlerId].behindSubstitute = 1;
gBattleSpritesDataPtr->battlerData[battler].behindSubstitute = 1;
}
void ClearBehindSubstituteBit(u8 battlerId)
void ClearBehindSubstituteBit(u8 battler)
{
gBattleSpritesDataPtr->battlerData[battlerId].behindSubstitute = 0;
gBattleSpritesDataPtr->battlerData[battler].behindSubstitute = 0;
}
void HandleLowHpMusicChange(struct Pokemon *mon, u8 battlerId)
void HandleLowHpMusicChange(struct Pokemon *mon, u8 battler)
{
u16 hp = GetMonData(mon, MON_DATA_HP);
u16 maxHP = GetMonData(mon, MON_DATA_MAX_HP);
if (GetHPBarLevel(hp, maxHP) == HP_BAR_RED)
{
if (!gBattleSpritesDataPtr->battlerData[battlerId].lowHpSong)
if (!gBattleSpritesDataPtr->battlerData[battler].lowHpSong)
{
if (!gBattleSpritesDataPtr->battlerData[BATTLE_PARTNER(battlerId)].lowHpSong)
if (!gBattleSpritesDataPtr->battlerData[BATTLE_PARTNER(battler)].lowHpSong)
PlaySE(SE_LOW_HEALTH);
gBattleSpritesDataPtr->battlerData[battlerId].lowHpSong = 1;
gBattleSpritesDataPtr->battlerData[battler].lowHpSong = 1;
}
}
else
{
gBattleSpritesDataPtr->battlerData[battlerId].lowHpSong = 0;
gBattleSpritesDataPtr->battlerData[battler].lowHpSong = 0;
if (!IsDoubleBattle())
{
m4aSongNumStop(SE_LOW_HEALTH);
return;
}
if (IsDoubleBattle() && !gBattleSpritesDataPtr->battlerData[BATTLE_PARTNER(battlerId)].lowHpSong)
if (IsDoubleBattle() && !gBattleSpritesDataPtr->battlerData[BATTLE_PARTNER(battler)].lowHpSong)
{
m4aSongNumStop(SE_LOW_HEALTH);
return;
@ -1071,46 +1070,46 @@ void SetBattlerSpriteAffineMode(u8 affineMode)
void LoadAndCreateEnemyShadowSprites(void)
{
u8 battlerId;
u8 battler;
LoadCompressedSpriteSheet(&gSpriteSheet_EnemyShadow);
battlerId = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
gBattleSpritesDataPtr->healthBoxesData[battlerId].shadowSpriteId = CreateSprite(&gSpriteTemplate_EnemyShadow,
GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X),
GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y) + 29,
battler = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
gBattleSpritesDataPtr->healthBoxesData[battler].shadowSpriteId = CreateSprite(&gSpriteTemplate_EnemyShadow,
GetBattlerSpriteCoord(battler, BATTLER_COORD_X),
GetBattlerSpriteCoord(battler, BATTLER_COORD_Y) + 29,
0xC8);
gSprites[gBattleSpritesDataPtr->healthBoxesData[battlerId].shadowSpriteId].data[0] = battlerId;
gSprites[gBattleSpritesDataPtr->healthBoxesData[battler].shadowSpriteId].data[0] = battler;
if (IsDoubleBattle())
{
battlerId = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
gBattleSpritesDataPtr->healthBoxesData[battlerId].shadowSpriteId = CreateSprite(&gSpriteTemplate_EnemyShadow,
GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X),
GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y) + 29,
battler = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
gBattleSpritesDataPtr->healthBoxesData[battler].shadowSpriteId = CreateSprite(&gSpriteTemplate_EnemyShadow,
GetBattlerSpriteCoord(battler, BATTLER_COORD_X),
GetBattlerSpriteCoord(battler, BATTLER_COORD_Y) + 29,
0xC8);
gSprites[gBattleSpritesDataPtr->healthBoxesData[battlerId].shadowSpriteId].data[0] = battlerId;
gSprites[gBattleSpritesDataPtr->healthBoxesData[battler].shadowSpriteId].data[0] = battler;
}
}
void SpriteCB_EnemyShadow(struct Sprite *shadowSprite)
{
bool8 invisible = FALSE;
u8 battlerId = shadowSprite->tBattlerId;
struct Sprite *battlerSprite = &gSprites[gBattlerSpriteIds[battlerId]];
u8 battler = shadowSprite->tBattlerId;
struct Sprite *battlerSprite = &gSprites[gBattlerSpriteIds[battler]];
if (!battlerSprite->inUse || !IsBattlerSpritePresent(battlerId))
if (!battlerSprite->inUse || !IsBattlerSpritePresent(battler))
{
shadowSprite->callback = SpriteCB_SetInvisible;
return;
}
if (gAnimScriptActive || battlerSprite->invisible)
invisible = TRUE;
else if (gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies != SPECIES_NONE
&& gEnemyMonElevation[gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies] == 0)
else if (gBattleSpritesDataPtr->battlerData[battler].transformSpecies != SPECIES_NONE
&& gEnemyMonElevation[gBattleSpritesDataPtr->battlerData[battler].transformSpecies] == 0)
invisible = TRUE;
if (gBattleSpritesDataPtr->battlerData[battlerId].behindSubstitute)
if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute)
invisible = TRUE;
shadowSprite->x = battlerSprite->x;
@ -1125,24 +1124,24 @@ void SpriteCB_SetInvisible(struct Sprite *sprite)
sprite->invisible = TRUE;
}
void SetBattlerShadowSpriteCallback(u8 battlerId, u16 species)
void SetBattlerShadowSpriteCallback(u8 battler, u16 species)
{
// The player's shadow is never seen.
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER || gBattleScripting.monCaught)
if (GetBattlerSide(battler) == B_SIDE_PLAYER || gBattleScripting.monCaught)
return;
if (gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies != SPECIES_NONE)
species = gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies;
if (gBattleSpritesDataPtr->battlerData[battler].transformSpecies != SPECIES_NONE)
species = gBattleSpritesDataPtr->battlerData[battler].transformSpecies;
if (gEnemyMonElevation[species] != 0)
gSprites[gBattleSpritesDataPtr->healthBoxesData[battlerId].shadowSpriteId].callback = SpriteCB_EnemyShadow;
gSprites[gBattleSpritesDataPtr->healthBoxesData[battler].shadowSpriteId].callback = SpriteCB_EnemyShadow;
else
gSprites[gBattleSpritesDataPtr->healthBoxesData[battlerId].shadowSpriteId].callback = SpriteCB_SetInvisible;
gSprites[gBattleSpritesDataPtr->healthBoxesData[battler].shadowSpriteId].callback = SpriteCB_SetInvisible;
}
void HideBattlerShadowSprite(u8 battlerId)
void HideBattlerShadowSprite(u8 battler)
{
gSprites[gBattleSpritesDataPtr->healthBoxesData[battlerId].shadowSpriteId].callback = SpriteCB_SetInvisible;
gSprites[gBattleSpritesDataPtr->healthBoxesData[battler].shadowSpriteId].callback = SpriteCB_SetInvisible;
}
// Color the background tiles surrounding the action selection and move windows
@ -1169,11 +1168,11 @@ void FillAroundBattleWindows(void)
}
}
void ClearTemporarySpeciesSpriteData(u8 battlerId, bool8 dontClearSubstitute)
void ClearTemporarySpeciesSpriteData(u8 battler, bool8 dontClearSubstitute)
{
gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies = SPECIES_NONE;
gBattleSpritesDataPtr->battlerData[battler].transformSpecies = SPECIES_NONE;
if (!dontClearSubstitute)
ClearBehindSubstituteBit(battlerId);
ClearBehindSubstituteBit(battler);
}
void AllocateMonSpritesGfx(void)

View File

@ -2999,9 +2999,11 @@ void BeginBattleIntro(void)
static void BattleMainCB1(void)
{
u32 battler;
gBattleMainFunc();
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
gBattlerControllerFuncs[gActiveBattler](gActiveBattler);
for (battler = 0; battler < gBattlersCount; battler++)
gBattlerControllerFuncs[battler](battler);
}
static void BattleStartClearSetData(void)
@ -4069,47 +4071,47 @@ enum
static void HandleTurnActionSelectionState(void)
{
s32 i;
s32 i, battler;
gBattleCommunication[ACTIONS_CONFIRMED_COUNT] = 0;
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
for (battler = 0; battler < gBattlersCount; battler++)
{
u8 position = GetBattlerPosition(gActiveBattler);
switch (gBattleCommunication[gActiveBattler])
u8 position = GetBattlerPosition(battler);
switch (gBattleCommunication[battler])
{
case STATE_TURN_START_RECORD: // Recorded battle related action on start of every turn.
RecordedBattle_CopyBattlerMoves(gActiveBattler);
gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN;
RecordedBattle_CopyBattlerMoves(battler);
gBattleCommunication[battler] = STATE_BEFORE_ACTION_CHOSEN;
// Do AI score computations here so we can use them in AI_TrySwitchOrUseItem
if ((gBattleTypeFlags & BATTLE_TYPE_HAS_AI || IsWildMonSmart())
&& (BattlerHasAi(gActiveBattler) && !(gBattleTypeFlags & BATTLE_TYPE_PALACE)))
&& (BattlerHasAi(battler) && !(gBattleTypeFlags & BATTLE_TYPE_PALACE)))
{
gBattleStruct->aiMoveOrAction[gActiveBattler] = ComputeBattleAiScores(gActiveBattler);
gBattleStruct->aiMoveOrAction[battler] = ComputeBattleAiScores(battler);
}
break;
case STATE_BEFORE_ACTION_CHOSEN: // Choose an action.
*(gBattleStruct->monToSwitchIntoId + gActiveBattler) = PARTY_SIZE;
*(gBattleStruct->monToSwitchIntoId + battler) = PARTY_SIZE;
if (gBattleTypeFlags & BATTLE_TYPE_MULTI
|| (position & BIT_FLANK) == B_FLANK_LEFT
|| gBattleStruct->absentBattlerFlags & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(position))]
|| gBattleCommunication[GetBattlerAtPosition(BATTLE_PARTNER(position))] == STATE_WAIT_ACTION_CONFIRMED)
{
if (gBattleStruct->absentBattlerFlags & gBitTable[gActiveBattler])
if (gBattleStruct->absentBattlerFlags & gBitTable[battler])
{
gChosenActionByBattler[gActiveBattler] = B_ACTION_NOTHING_FAINTED;
gChosenActionByBattler[battler] = B_ACTION_NOTHING_FAINTED;
if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI))
gBattleCommunication[gActiveBattler] = STATE_WAIT_ACTION_CONFIRMED;
gBattleCommunication[battler] = STATE_WAIT_ACTION_CONFIRMED;
else
gBattleCommunication[gActiveBattler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY;
gBattleCommunication[battler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY;
}
else
{
if (gBattleMons[gActiveBattler].status2 & STATUS2_MULTIPLETURNS
|| gBattleMons[gActiveBattler].status2 & STATUS2_RECHARGE)
if (gBattleMons[battler].status2 & STATUS2_MULTIPLETURNS
|| gBattleMons[battler].status2 & STATUS2_RECHARGE)
{
gChosenActionByBattler[gActiveBattler] = B_ACTION_USE_MOVE;
gBattleCommunication[gActiveBattler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY;
gChosenActionByBattler[battler] = B_ACTION_USE_MOVE;
gBattleCommunication[battler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY;
}
else if (WILD_DOUBLE_BATTLE
&& position == B_POSITION_PLAYER_RIGHT
@ -4117,41 +4119,41 @@ static void HandleTurnActionSelectionState(void)
&& gChosenActionByBattler[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)] != B_ACTION_NOTHING_FAINTED)
{
gBattleStruct->throwingPokeBall = FALSE;
gChosenActionByBattler[gActiveBattler] = B_ACTION_NOTHING_FAINTED; // Not fainted, but it cannot move, because of the throwing ball.
gBattleCommunication[gActiveBattler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY;
gChosenActionByBattler[battler] = B_ACTION_NOTHING_FAINTED; // Not fainted, but it cannot move, because of the throwing ball.
gBattleCommunication[battler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY;
}
else
{
gBattleStruct->itemPartyIndex[gActiveBattler] = PARTY_SIZE;
BtlController_EmitChooseAction(gActiveBattler, BUFFER_A, gChosenActionByBattler[0], gBattleResources->bufferB[0][1] | (gBattleResources->bufferB[0][2] << 8));
MarkBattlerForControllerExec(gActiveBattler);
gBattleCommunication[gActiveBattler]++;
gBattleStruct->itemPartyIndex[battler] = PARTY_SIZE;
BtlController_EmitChooseAction(battler, BUFFER_A, gChosenActionByBattler[0], gBattleResources->bufferB[0][1] | (gBattleResources->bufferB[0][2] << 8));
MarkBattlerForControllerExec(battler);
gBattleCommunication[battler]++;
}
}
}
break;
case STATE_WAIT_ACTION_CHOSEN: // Try to perform an action.
if (!(gBattleControllerExecFlags & ((gBitTable[gActiveBattler]) | (0xF << 28) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 12))))
if (!(gBattleControllerExecFlags & ((gBitTable[battler]) | (0xF << 28) | (gBitTable[battler] << 4) | (gBitTable[battler] << 8) | (gBitTable[battler] << 12))))
{
RecordedBattle_SetBattlerAction(gActiveBattler, gBattleResources->bufferB[gActiveBattler][1]);
gChosenActionByBattler[gActiveBattler] = gBattleResources->bufferB[gActiveBattler][1];
RecordedBattle_SetBattlerAction(battler, gBattleResources->bufferB[battler][1]);
gChosenActionByBattler[battler] = gBattleResources->bufferB[battler][1];
switch (gBattleResources->bufferB[gActiveBattler][1])
switch (gBattleResources->bufferB[battler][1])
{
case B_ACTION_USE_MOVE:
if (AreAllMovesUnusable(gActiveBattler))
if (AreAllMovesUnusable(battler))
{
gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT;
*(gBattleStruct->selectionScriptFinished + gActiveBattler) = FALSE;
*(gBattleStruct->stateIdAfterSelScript + gActiveBattler) = STATE_WAIT_ACTION_CONFIRMED_STANDBY;
*(gBattleStruct->moveTarget + gActiveBattler) = gBattleResources->bufferB[gActiveBattler][3];
gBattleCommunication[battler] = STATE_SELECTION_SCRIPT;
*(gBattleStruct->selectionScriptFinished + battler) = FALSE;
*(gBattleStruct->stateIdAfterSelScript + battler) = STATE_WAIT_ACTION_CONFIRMED_STANDBY;
*(gBattleStruct->moveTarget + battler) = gBattleResources->bufferB[battler][3];
return;
}
else if (gDisableStructs[gActiveBattler].encoredMove != 0)
else if (gDisableStructs[battler].encoredMove != 0)
{
gChosenMoveByBattler[gActiveBattler] = gDisableStructs[gActiveBattler].encoredMove;
*(gBattleStruct->chosenMovePositions + gActiveBattler) = gDisableStructs[gActiveBattler].encoredMovePos;
gBattleCommunication[gActiveBattler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY;
gChosenMoveByBattler[battler] = gDisableStructs[battler].encoredMove;
*(gBattleStruct->chosenMovePositions + battler) = gDisableStructs[battler].encoredMovePos;
gBattleCommunication[battler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY;
return;
}
else
@ -4160,33 +4162,33 @@ static void HandleTurnActionSelectionState(void)
moveInfo.zmove = gBattleStruct->zmove;
moveInfo.mega = gBattleStruct->mega;
moveInfo.species = gBattleMons[gActiveBattler].species;
moveInfo.monType1 = gBattleMons[gActiveBattler].type1;
moveInfo.monType2 = gBattleMons[gActiveBattler].type2;
moveInfo.monType3 = gBattleMons[gActiveBattler].type3;
moveInfo.species = gBattleMons[battler].species;
moveInfo.monType1 = gBattleMons[battler].type1;
moveInfo.monType2 = gBattleMons[battler].type2;
moveInfo.monType3 = gBattleMons[battler].type3;
for (i = 0; i < MAX_MON_MOVES; i++)
{
moveInfo.moves[i] = gBattleMons[gActiveBattler].moves[i];
moveInfo.currentPp[i] = gBattleMons[gActiveBattler].pp[i];
moveInfo.moves[i] = gBattleMons[battler].moves[i];
moveInfo.currentPp[i] = gBattleMons[battler].pp[i];
moveInfo.maxPp[i] = CalculatePPWithBonus(
gBattleMons[gActiveBattler].moves[i],
gBattleMons[gActiveBattler].ppBonuses,
gBattleMons[battler].moves[i],
gBattleMons[battler].ppBonuses,
i);
}
BtlController_EmitChooseMove(gActiveBattler, BUFFER_A, (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) != 0, FALSE, &moveInfo);
MarkBattlerForControllerExec(gActiveBattler);
BtlController_EmitChooseMove(battler, BUFFER_A, (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) != 0, FALSE, &moveInfo);
MarkBattlerForControllerExec(battler);
}
break;
case B_ACTION_USE_ITEM:
if (FlagGet(B_FLAG_NO_BAG_USE))
{
RecordedBattle_ClearBattlerAction(gActiveBattler, 1);
gSelectionBattleScripts[gActiveBattler] = BattleScript_ActionSelectionItemsCantBeUsed;
gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT;
*(gBattleStruct->selectionScriptFinished + gActiveBattler) = FALSE;
*(gBattleStruct->stateIdAfterSelScript + gActiveBattler) = STATE_BEFORE_ACTION_CHOSEN;
RecordedBattle_ClearBattlerAction(battler, 1);
gSelectionBattleScripts[battler] = BattleScript_ActionSelectionItemsCantBeUsed;
gBattleCommunication[battler] = STATE_SELECTION_SCRIPT;
*(gBattleStruct->selectionScriptFinished + battler) = FALSE;
*(gBattleStruct->stateIdAfterSelScript + battler) = STATE_BEFORE_ACTION_CHOSEN;
return;
}
@ -4196,144 +4198,144 @@ static void HandleTurnActionSelectionState(void)
| BATTLE_TYPE_RECORDED_LINK))
&& !gTestRunnerEnabled)
// Or if currently held by Sky Drop
|| gStatuses3[gActiveBattler] & STATUS3_SKY_DROPPED)
|| gStatuses3[battler] & STATUS3_SKY_DROPPED)
{
RecordedBattle_ClearBattlerAction(gActiveBattler, 1);
gSelectionBattleScripts[gActiveBattler] = BattleScript_ActionSelectionItemsCantBeUsed;
gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT;
*(gBattleStruct->selectionScriptFinished + gActiveBattler) = FALSE;
*(gBattleStruct->stateIdAfterSelScript + gActiveBattler) = STATE_BEFORE_ACTION_CHOSEN;
RecordedBattle_ClearBattlerAction(battler, 1);
gSelectionBattleScripts[battler] = BattleScript_ActionSelectionItemsCantBeUsed;
gBattleCommunication[battler] = STATE_SELECTION_SCRIPT;
*(gBattleStruct->selectionScriptFinished + battler) = FALSE;
*(gBattleStruct->stateIdAfterSelScript + battler) = STATE_BEFORE_ACTION_CHOSEN;
return;
}
else
{
BtlController_EmitChooseItem(gActiveBattler, BUFFER_A, gBattleStruct->battlerPartyOrders[gActiveBattler]);
MarkBattlerForControllerExec(gActiveBattler);
BtlController_EmitChooseItem(battler, BUFFER_A, gBattleStruct->battlerPartyOrders[battler]);
MarkBattlerForControllerExec(battler);
}
break;
case B_ACTION_SWITCH:
*(gBattleStruct->battlerPartyIndexes + gActiveBattler) = gBattlerPartyIndexes[gActiveBattler];
*(gBattleStruct->battlerPartyIndexes + battler) = gBattlerPartyIndexes[battler];
if (gBattleTypeFlags & BATTLE_TYPE_ARENA
|| !CanBattlerEscape(gActiveBattler))
|| !CanBattlerEscape(battler))
{
BtlController_EmitChoosePokemon(gActiveBattler, BUFFER_A, PARTY_ACTION_CANT_SWITCH, PARTY_SIZE, ABILITY_NONE, gBattleStruct->battlerPartyOrders[gActiveBattler]);
BtlController_EmitChoosePokemon(battler, BUFFER_A, PARTY_ACTION_CANT_SWITCH, PARTY_SIZE, ABILITY_NONE, gBattleStruct->battlerPartyOrders[battler]);
}
else if (ItemId_GetHoldEffect(gBattleMons[gActiveBattler].item) != HOLD_EFFECT_SHED_SHELL
&& (i = IsAbilityPreventingEscape(gActiveBattler))) // must be last to keep i value integrity
else if (ItemId_GetHoldEffect(gBattleMons[battler].item) != HOLD_EFFECT_SHED_SHELL
&& (i = IsAbilityPreventingEscape(battler))) // must be last to keep i value integrity
{
BtlController_EmitChoosePokemon(gActiveBattler, BUFFER_A, ((i - 1) << 4) | PARTY_ACTION_ABILITY_PREVENTS, PARTY_SIZE, gBattleMons[i - 1].ability, gBattleStruct->battlerPartyOrders[gActiveBattler]);
BtlController_EmitChoosePokemon(battler, BUFFER_A, ((i - 1) << 4) | PARTY_ACTION_ABILITY_PREVENTS, PARTY_SIZE, gBattleMons[i - 1].ability, gBattleStruct->battlerPartyOrders[battler]);
}
else
{
if (gActiveBattler == 2 && gChosenActionByBattler[0] == B_ACTION_SWITCH)
BtlController_EmitChoosePokemon(gActiveBattler, BUFFER_A, PARTY_ACTION_CHOOSE_MON, *(gBattleStruct->monToSwitchIntoId + 0), ABILITY_NONE, gBattleStruct->battlerPartyOrders[gActiveBattler]);
else if (gActiveBattler == 3 && gChosenActionByBattler[1] == B_ACTION_SWITCH)
BtlController_EmitChoosePokemon(gActiveBattler, BUFFER_A, PARTY_ACTION_CHOOSE_MON, *(gBattleStruct->monToSwitchIntoId + 1), ABILITY_NONE, gBattleStruct->battlerPartyOrders[gActiveBattler]);
if (battler == 2 && gChosenActionByBattler[0] == B_ACTION_SWITCH)
BtlController_EmitChoosePokemon(battler, BUFFER_A, PARTY_ACTION_CHOOSE_MON, *(gBattleStruct->monToSwitchIntoId + 0), ABILITY_NONE, gBattleStruct->battlerPartyOrders[battler]);
else if (battler == 3 && gChosenActionByBattler[1] == B_ACTION_SWITCH)
BtlController_EmitChoosePokemon(battler, BUFFER_A, PARTY_ACTION_CHOOSE_MON, *(gBattleStruct->monToSwitchIntoId + 1), ABILITY_NONE, gBattleStruct->battlerPartyOrders[battler]);
else
BtlController_EmitChoosePokemon(gActiveBattler, BUFFER_A, PARTY_ACTION_CHOOSE_MON, PARTY_SIZE, ABILITY_NONE, gBattleStruct->battlerPartyOrders[gActiveBattler]);
BtlController_EmitChoosePokemon(battler, BUFFER_A, PARTY_ACTION_CHOOSE_MON, PARTY_SIZE, ABILITY_NONE, gBattleStruct->battlerPartyOrders[battler]);
}
MarkBattlerForControllerExec(gActiveBattler);
MarkBattlerForControllerExec(battler);
break;
case B_ACTION_SAFARI_BALL:
if (IsPlayerPartyAndPokemonStorageFull())
{
gSelectionBattleScripts[gActiveBattler] = BattleScript_PrintFullBox;
gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT;
*(gBattleStruct->selectionScriptFinished + gActiveBattler) = FALSE;
*(gBattleStruct->stateIdAfterSelScript + gActiveBattler) = STATE_BEFORE_ACTION_CHOSEN;
gSelectionBattleScripts[battler] = BattleScript_PrintFullBox;
gBattleCommunication[battler] = STATE_SELECTION_SCRIPT;
*(gBattleStruct->selectionScriptFinished + battler) = FALSE;
*(gBattleStruct->stateIdAfterSelScript + battler) = STATE_BEFORE_ACTION_CHOSEN;
return;
}
break;
case B_ACTION_SAFARI_POKEBLOCK:
BtlController_EmitChooseItem(gActiveBattler, BUFFER_A, gBattleStruct->battlerPartyOrders[gActiveBattler]);
MarkBattlerForControllerExec(gActiveBattler);
BtlController_EmitChooseItem(battler, BUFFER_A, gBattleStruct->battlerPartyOrders[battler]);
MarkBattlerForControllerExec(battler);
break;
case B_ACTION_CANCEL_PARTNER:
gBattleCommunication[gActiveBattler] = STATE_WAIT_SET_BEFORE_ACTION;
gBattleCommunication[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))] = STATE_BEFORE_ACTION_CHOSEN;
RecordedBattle_ClearBattlerAction(gActiveBattler, 1);
if (gBattleMons[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))].status2 & STATUS2_MULTIPLETURNS
|| gBattleMons[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))].status2 & STATUS2_RECHARGE)
gBattleCommunication[battler] = STATE_WAIT_SET_BEFORE_ACTION;
gBattleCommunication[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))] = STATE_BEFORE_ACTION_CHOSEN;
RecordedBattle_ClearBattlerAction(battler, 1);
if (gBattleMons[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))].status2 & STATUS2_MULTIPLETURNS
|| gBattleMons[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))].status2 & STATUS2_RECHARGE)
{
BtlController_EmitEndBounceEffect(gActiveBattler, BUFFER_A);
MarkBattlerForControllerExec(gActiveBattler);
BtlController_EmitEndBounceEffect(battler, BUFFER_A);
MarkBattlerForControllerExec(battler);
return;
}
else if (gChosenActionByBattler[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))] == B_ACTION_SWITCH)
else if (gChosenActionByBattler[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))] == B_ACTION_SWITCH)
{
RecordedBattle_ClearBattlerAction(GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler))), 2);
RecordedBattle_ClearBattlerAction(GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler))), 2);
}
else if (gChosenActionByBattler[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))] == B_ACTION_RUN)
else if (gChosenActionByBattler[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))] == B_ACTION_RUN)
{
RecordedBattle_ClearBattlerAction(GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler))), 1);
RecordedBattle_ClearBattlerAction(GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler))), 1);
}
else if (gChosenActionByBattler[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))] == B_ACTION_USE_MOVE
&& (gProtectStructs[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))].noValidMoves
|| gDisableStructs[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))].encoredMove))
else if (gChosenActionByBattler[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))] == B_ACTION_USE_MOVE
&& (gProtectStructs[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))].noValidMoves
|| gDisableStructs[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))].encoredMove))
{
RecordedBattle_ClearBattlerAction(GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler))), 1);
RecordedBattle_ClearBattlerAction(GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler))), 1);
}
else if (gBattleTypeFlags & BATTLE_TYPE_PALACE
&& gChosenActionByBattler[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))] == B_ACTION_USE_MOVE)
&& gChosenActionByBattler[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))] == B_ACTION_USE_MOVE)
{
gRngValue = gBattlePalaceMoveSelectionRngValue;
RecordedBattle_ClearBattlerAction(GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler))), 1);
RecordedBattle_ClearBattlerAction(GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler))), 1);
}
else
{
RecordedBattle_ClearBattlerAction(GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler))), 3);
RecordedBattle_ClearBattlerAction(GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler))), 3);
}
gBattleStruct->mega.toEvolve &= ~(gBitTable[BATTLE_PARTNER(GetBattlerPosition(gActiveBattler))]);
gBattleStruct->zmove.toBeUsed[BATTLE_PARTNER(GetBattlerPosition(gActiveBattler))] = MOVE_NONE;
BtlController_EmitEndBounceEffect(gActiveBattler, BUFFER_A);
MarkBattlerForControllerExec(gActiveBattler);
gBattleStruct->mega.toEvolve &= ~(gBitTable[BATTLE_PARTNER(GetBattlerPosition(battler))]);
gBattleStruct->zmove.toBeUsed[BATTLE_PARTNER(GetBattlerPosition(battler))] = MOVE_NONE;
BtlController_EmitEndBounceEffect(battler, BUFFER_A);
MarkBattlerForControllerExec(battler);
return;
case B_ACTION_DEBUG:
BtlController_EmitDebugMenu(gActiveBattler, BUFFER_A);
MarkBattlerForControllerExec(gActiveBattler);
BtlController_EmitDebugMenu(battler, BUFFER_A);
MarkBattlerForControllerExec(battler);
break;
}
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER
&& gBattleTypeFlags & (BATTLE_TYPE_FRONTIER | BATTLE_TYPE_TRAINER_HILL)
&& gBattleResources->bufferB[gActiveBattler][1] == B_ACTION_RUN)
&& gBattleResources->bufferB[battler][1] == B_ACTION_RUN)
{
gSelectionBattleScripts[gActiveBattler] = BattleScript_AskIfWantsToForfeitMatch;
gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT_MAY_RUN;
*(gBattleStruct->selectionScriptFinished + gActiveBattler) = FALSE;
*(gBattleStruct->stateIdAfterSelScript + gActiveBattler) = STATE_BEFORE_ACTION_CHOSEN;
gSelectionBattleScripts[battler] = BattleScript_AskIfWantsToForfeitMatch;
gBattleCommunication[battler] = STATE_SELECTION_SCRIPT_MAY_RUN;
*(gBattleStruct->selectionScriptFinished + battler) = FALSE;
*(gBattleStruct->stateIdAfterSelScript + battler) = STATE_BEFORE_ACTION_CHOSEN;
return;
}
else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER
&& !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED_LINK))
&& gBattleResources->bufferB[gActiveBattler][1] == B_ACTION_RUN)
&& gBattleResources->bufferB[battler][1] == B_ACTION_RUN)
{
BattleScriptExecute(BattleScript_PrintCantRunFromTrainer);
gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN;
gBattleCommunication[battler] = STATE_BEFORE_ACTION_CHOSEN;
}
else if (IsRunningFromBattleImpossible(gActiveBattler) != BATTLE_RUN_SUCCESS
&& gBattleResources->bufferB[gActiveBattler][1] == B_ACTION_RUN)
else if (IsRunningFromBattleImpossible(battler) != BATTLE_RUN_SUCCESS
&& gBattleResources->bufferB[battler][1] == B_ACTION_RUN)
{
gSelectionBattleScripts[gActiveBattler] = BattleScript_PrintCantEscapeFromBattle;
gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT;
*(gBattleStruct->selectionScriptFinished + gActiveBattler) = FALSE;
*(gBattleStruct->stateIdAfterSelScript + gActiveBattler) = STATE_BEFORE_ACTION_CHOSEN;
gSelectionBattleScripts[battler] = BattleScript_PrintCantEscapeFromBattle;
gBattleCommunication[battler] = STATE_SELECTION_SCRIPT;
*(gBattleStruct->selectionScriptFinished + battler) = FALSE;
*(gBattleStruct->stateIdAfterSelScript + battler) = STATE_BEFORE_ACTION_CHOSEN;
return;
}
else
{
gBattleCommunication[gActiveBattler]++;
gBattleCommunication[battler]++;
}
}
break;
case STATE_WAIT_ACTION_CASE_CHOSEN:
if (!(gBattleControllerExecFlags & ((gBitTable[gActiveBattler]) | (0xF << 28) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 12))))
if (!(gBattleControllerExecFlags & ((gBitTable[battler]) | (0xF << 28) | (gBitTable[battler] << 4) | (gBitTable[battler] << 8) | (gBitTable[battler] << 12))))
{
switch (gChosenActionByBattler[gActiveBattler])
switch (gChosenActionByBattler[battler])
{
case B_ACTION_USE_MOVE:
switch (gBattleResources->bufferB[gActiveBattler][1])
switch (gBattleResources->bufferB[battler][1])
{
case 3:
case 4:
@ -4342,112 +4344,112 @@ static void HandleTurnActionSelectionState(void)
case 7:
case 8:
case 9:
gChosenActionByBattler[gActiveBattler] = gBattleResources->bufferB[gActiveBattler][1];
gChosenActionByBattler[battler] = gBattleResources->bufferB[battler][1];
return;
case 15:
gChosenActionByBattler[gActiveBattler] = B_ACTION_SWITCH;
UpdateBattlerPartyOrdersOnSwitch(gActiveBattler);
gChosenActionByBattler[battler] = B_ACTION_SWITCH;
UpdateBattlerPartyOrdersOnSwitch(battler);
return;
default:
RecordedBattle_CheckMovesetChanges(B_RECORD_MODE_PLAYBACK);
if ((gBattleResources->bufferB[gActiveBattler][2] | (gBattleResources->bufferB[gActiveBattler][3] << 8)) == 0xFFFF)
if ((gBattleResources->bufferB[battler][2] | (gBattleResources->bufferB[battler][3] << 8)) == 0xFFFF)
{
gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN;
RecordedBattle_ClearBattlerAction(gActiveBattler, 1);
gBattleCommunication[battler] = STATE_BEFORE_ACTION_CHOSEN;
RecordedBattle_ClearBattlerAction(battler, 1);
}
else if (TrySetCantSelectMoveBattleScript(gActiveBattler))
else if (TrySetCantSelectMoveBattleScript(battler))
{
RecordedBattle_ClearBattlerAction(gActiveBattler, 1);
gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT;
*(gBattleStruct->selectionScriptFinished + gActiveBattler) = FALSE;
gBattleResources->bufferB[gActiveBattler][1] = B_ACTION_USE_MOVE;
*(gBattleStruct->stateIdAfterSelScript + gActiveBattler) = STATE_WAIT_ACTION_CHOSEN;
RecordedBattle_ClearBattlerAction(battler, 1);
gBattleCommunication[battler] = STATE_SELECTION_SCRIPT;
*(gBattleStruct->selectionScriptFinished + battler) = FALSE;
gBattleResources->bufferB[battler][1] = B_ACTION_USE_MOVE;
*(gBattleStruct->stateIdAfterSelScript + battler) = STATE_WAIT_ACTION_CHOSEN;
return;
}
else
{
if (!(gBattleTypeFlags & BATTLE_TYPE_PALACE))
{
RecordedBattle_SetBattlerAction(gActiveBattler, gBattleResources->bufferB[gActiveBattler][2]);
RecordedBattle_SetBattlerAction(gActiveBattler, gBattleResources->bufferB[gActiveBattler][3]);
RecordedBattle_SetBattlerAction(battler, gBattleResources->bufferB[battler][2]);
RecordedBattle_SetBattlerAction(battler, gBattleResources->bufferB[battler][3]);
}
*(gBattleStruct->chosenMovePositions + gActiveBattler) = gBattleResources->bufferB[gActiveBattler][2] & ~RET_MEGA_EVOLUTION;
gChosenMoveByBattler[gActiveBattler] = gBattleMons[gActiveBattler].moves[*(gBattleStruct->chosenMovePositions + gActiveBattler)];
*(gBattleStruct->moveTarget + gActiveBattler) = gBattleResources->bufferB[gActiveBattler][3];
if (gBattleResources->bufferB[gActiveBattler][2] & RET_MEGA_EVOLUTION)
gBattleStruct->mega.toEvolve |= gBitTable[gActiveBattler];
gBattleCommunication[gActiveBattler]++;
*(gBattleStruct->chosenMovePositions + battler) = gBattleResources->bufferB[battler][2] & ~RET_MEGA_EVOLUTION;
gChosenMoveByBattler[battler] = gBattleMons[battler].moves[*(gBattleStruct->chosenMovePositions + battler)];
*(gBattleStruct->moveTarget + battler) = gBattleResources->bufferB[battler][3];
if (gBattleResources->bufferB[battler][2] & RET_MEGA_EVOLUTION)
gBattleStruct->mega.toEvolve |= gBitTable[battler];
gBattleCommunication[battler]++;
}
break;
}
break;
case B_ACTION_USE_ITEM:
if ((gBattleResources->bufferB[gActiveBattler][1] | (gBattleResources->bufferB[gActiveBattler][2] << 8)) == 0)
if ((gBattleResources->bufferB[battler][1] | (gBattleResources->bufferB[battler][2] << 8)) == 0)
{
gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN;
gBattleCommunication[battler] = STATE_BEFORE_ACTION_CHOSEN;
}
else
{
gLastUsedItem = (gBattleResources->bufferB[gActiveBattler][1] | (gBattleResources->bufferB[gActiveBattler][2] << 8));
gLastUsedItem = (gBattleResources->bufferB[battler][1] | (gBattleResources->bufferB[battler][2] << 8));
if (ItemId_GetPocket(gLastUsedItem) == POCKET_POKE_BALLS)
gBattleStruct->throwingPokeBall = TRUE;
gBattleCommunication[gActiveBattler]++;
gBattleCommunication[battler]++;
}
break;
case B_ACTION_SWITCH:
if (gBattleResources->bufferB[gActiveBattler][1] == PARTY_SIZE)
if (gBattleResources->bufferB[battler][1] == PARTY_SIZE)
{
gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN;
RecordedBattle_ClearBattlerAction(gActiveBattler, 1);
gBattleCommunication[battler] = STATE_BEFORE_ACTION_CHOSEN;
RecordedBattle_ClearBattlerAction(battler, 1);
}
else
{
UpdateBattlerPartyOrdersOnSwitch(gActiveBattler);
gBattleCommunication[gActiveBattler]++;
UpdateBattlerPartyOrdersOnSwitch(battler);
gBattleCommunication[battler]++;
}
break;
case B_ACTION_RUN:
gHitMarker |= HITMARKER_RUN;
gBattleCommunication[gActiveBattler]++;
gBattleCommunication[battler]++;
break;
case B_ACTION_SAFARI_WATCH_CAREFULLY:
gBattleCommunication[gActiveBattler]++;
gBattleCommunication[battler]++;
break;
case B_ACTION_SAFARI_BALL:
gBattleCommunication[gActiveBattler]++;
gBattleCommunication[battler]++;
break;
case B_ACTION_THROW_BALL:
gBattleStruct->throwingPokeBall = TRUE;
gBattleCommunication[gActiveBattler]++;
gBattleCommunication[battler]++;
break;
case B_ACTION_SAFARI_POKEBLOCK:
if ((gBattleResources->bufferB[gActiveBattler][1] | (gBattleResources->bufferB[gActiveBattler][2] << 8)) != 0)
gBattleCommunication[gActiveBattler]++;
if ((gBattleResources->bufferB[battler][1] | (gBattleResources->bufferB[battler][2] << 8)) != 0)
gBattleCommunication[battler]++;
else
gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN;
gBattleCommunication[battler] = STATE_BEFORE_ACTION_CHOSEN;
break;
case B_ACTION_SAFARI_GO_NEAR:
gBattleCommunication[gActiveBattler]++;
gBattleCommunication[battler]++;
break;
case B_ACTION_SAFARI_RUN:
gHitMarker |= HITMARKER_RUN;
gBattleCommunication[gActiveBattler]++;
gBattleCommunication[battler]++;
break;
case B_ACTION_WALLY_THROW:
gBattleCommunication[gActiveBattler]++;
gBattleCommunication[battler]++;
break;
case B_ACTION_DEBUG:
gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN;
gBattleCommunication[battler] = STATE_BEFORE_ACTION_CHOSEN;
break;
}
}
break;
case STATE_WAIT_ACTION_CONFIRMED_STANDBY:
if (!(gBattleControllerExecFlags & ((gBitTable[gActiveBattler])
if (!(gBattleControllerExecFlags & ((gBitTable[battler])
| (0xF << 28)
| (gBitTable[gActiveBattler] << 4)
| (gBitTable[gActiveBattler] << 8)
| (gBitTable[gActiveBattler] << 12))))
| (gBitTable[battler] << 4)
| (gBitTable[battler] << 8)
| (gBitTable[battler] << 12))))
{
if (AllAtActionConfirmed())
i = TRUE;
@ -4458,68 +4460,68 @@ static void HandleTurnActionSelectionState(void)
|| (position & BIT_FLANK) != B_FLANK_LEFT
|| (*(&gBattleStruct->absentBattlerFlags) & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(position))]))
{
BtlController_EmitLinkStandbyMsg(gActiveBattler, BUFFER_A, LINK_STANDBY_MSG_STOP_BOUNCE, i);
BtlController_EmitLinkStandbyMsg(battler, BUFFER_A, LINK_STANDBY_MSG_STOP_BOUNCE, i);
}
else
{
BtlController_EmitLinkStandbyMsg(gActiveBattler, BUFFER_A, LINK_STANDBY_STOP_BOUNCE_ONLY, i);
BtlController_EmitLinkStandbyMsg(battler, BUFFER_A, LINK_STANDBY_STOP_BOUNCE_ONLY, i);
}
MarkBattlerForControllerExec(gActiveBattler);
gBattleCommunication[gActiveBattler]++;
MarkBattlerForControllerExec(battler);
gBattleCommunication[battler]++;
}
break;
case STATE_WAIT_ACTION_CONFIRMED:
if (!(gBattleControllerExecFlags & ((gBitTable[gActiveBattler]) | (0xF << 28) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 12))))
if (!(gBattleControllerExecFlags & ((gBitTable[battler]) | (0xF << 28) | (gBitTable[battler] << 4) | (gBitTable[battler] << 8) | (gBitTable[battler] << 12))))
{
gBattleCommunication[ACTIONS_CONFIRMED_COUNT]++;
}
break;
case STATE_SELECTION_SCRIPT:
if (*(gBattleStruct->selectionScriptFinished + gActiveBattler))
if (*(gBattleStruct->selectionScriptFinished + battler))
{
gBattleCommunication[gActiveBattler] = *(gBattleStruct->stateIdAfterSelScript + gActiveBattler);
gBattleCommunication[battler] = *(gBattleStruct->stateIdAfterSelScript + battler);
}
else
{
gBattlerAttacker = gActiveBattler;
gBattlescriptCurrInstr = gSelectionBattleScripts[gActiveBattler];
if (!(gBattleControllerExecFlags & ((gBitTable[gActiveBattler]) | (0xF << 28) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 12))))
gBattlerAttacker = battler;
gBattlescriptCurrInstr = gSelectionBattleScripts[battler];
if (!(gBattleControllerExecFlags & ((gBitTable[battler]) | (0xF << 28) | (gBitTable[battler] << 4) | (gBitTable[battler] << 8) | (gBitTable[battler] << 12))))
{
gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]]();
}
gSelectionBattleScripts[gActiveBattler] = gBattlescriptCurrInstr;
gSelectionBattleScripts[battler] = gBattlescriptCurrInstr;
}
break;
case STATE_WAIT_SET_BEFORE_ACTION:
if (!(gBattleControllerExecFlags & ((gBitTable[gActiveBattler]) | (0xF << 28) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 12))))
if (!(gBattleControllerExecFlags & ((gBitTable[battler]) | (0xF << 28) | (gBitTable[battler] << 4) | (gBitTable[battler] << 8) | (gBitTable[battler] << 12))))
{
gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN;
gBattleCommunication[battler] = STATE_BEFORE_ACTION_CHOSEN;
}
break;
case STATE_SELECTION_SCRIPT_MAY_RUN:
if (*(gBattleStruct->selectionScriptFinished + gActiveBattler))
if (*(gBattleStruct->selectionScriptFinished + battler))
{
if (gBattleResources->bufferB[gActiveBattler][1] == B_ACTION_NOTHING_FAINTED)
if (gBattleResources->bufferB[battler][1] == B_ACTION_NOTHING_FAINTED)
{
gHitMarker |= HITMARKER_RUN;
gChosenActionByBattler[gActiveBattler] = B_ACTION_RUN;
gBattleCommunication[gActiveBattler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY;
gChosenActionByBattler[battler] = B_ACTION_RUN;
gBattleCommunication[battler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY;
}
else
{
RecordedBattle_ClearBattlerAction(gActiveBattler, 1);
gBattleCommunication[gActiveBattler] = *(gBattleStruct->stateIdAfterSelScript + gActiveBattler);
RecordedBattle_ClearBattlerAction(battler, 1);
gBattleCommunication[battler] = *(gBattleStruct->stateIdAfterSelScript + battler);
}
}
else
{
gBattlerAttacker = gActiveBattler;
gBattlescriptCurrInstr = gSelectionBattleScripts[gActiveBattler];
if (!(gBattleControllerExecFlags & ((gBitTable[gActiveBattler]) | (0xF << 28) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 12))))
gBattlerAttacker = battler;
gBattlescriptCurrInstr = gSelectionBattleScripts[battler];
if (!(gBattleControllerExecFlags & ((gBitTable[battler]) | (0xF << 28) | (gBitTable[battler] << 4) | (gBitTable[battler] << 8) | (gBitTable[battler] << 12))))
{
gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]]();
}
gSelectionBattleScripts[gActiveBattler] = gBattlescriptCurrInstr;
gSelectionBattleScripts[battler] = gBattlescriptCurrInstr;
}
break;
}
@ -5007,12 +5009,12 @@ static bool32 TryDoMegaEvosBeforeMoves(void)
if (gBattleStruct->mega.toEvolve & gBitTable[megaOrder[i]]
&& !(gProtectStructs[megaOrder[i]].noValidMoves))
{
gActiveBattler = gBattlerAttacker = megaOrder[i];
gBattleStruct->mega.toEvolve &= ~(gBitTable[gActiveBattler]);
gLastUsedItem = gBattleMons[gActiveBattler].item;
party = GetBattlerParty(gActiveBattler);
mon = &party[gBattlerPartyIndexes[gActiveBattler]];
if (GetBattleFormChangeTargetSpecies(gActiveBattler, FORM_CHANGE_BATTLE_MEGA_EVOLUTION_MOVE) != SPECIES_NONE)
gBattlerAttacker = megaOrder[i];
gBattleStruct->mega.toEvolve &= ~(gBitTable[gBattlerAttacker]);
gLastUsedItem = gBattleMons[gBattlerAttacker].item;
party = GetBattlerParty(gBattlerAttacker);
mon = &party[gBattlerPartyIndexes[gBattlerAttacker]];
if (GetBattleFormChangeTargetSpecies(gBattlerAttacker, FORM_CHANGE_BATTLE_MEGA_EVOLUTION_MOVE) != SPECIES_NONE)
BattleScriptExecute(BattleScript_WishMegaEvolution);
else
BattleScriptExecute(BattleScript_MegaEvolution);

View File

@ -547,7 +547,7 @@ void HandleAction_Switch(void)
void HandleAction_UseItem(void)
{
gActiveBattler = gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
gBattle_BG0_X = 0;
gBattle_BG0_Y = 0;
ClearFuryCutterDestinyBondGrudge(gBattlerAttacker);

View File

@ -4408,17 +4408,17 @@ void DeleteFirstMoveAndGiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move)
SetBoxMonData(boxMon, MON_DATA_PP_BONUSES, &ppBonuses);
}
u8 CountAliveMonsInBattle(u8 caseId)
u8 CountAliveMonsInBattle(u8 caseId, u32 battler)
{
s32 i;
u8 retVal = 0;
switch (caseId)
{
case BATTLE_ALIVE_EXCEPT_ACTIVE:
case BATTLE_ALIVE_EXCEPT_BATTLER:
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
{
if (i != gActiveBattler && !(gAbsentBattlerFlags & gBitTable[i]))
if (i != battler && !(gAbsentBattlerFlags & gBitTable[i]))
retVal++;
}
break;
@ -4454,7 +4454,7 @@ u8 GetDefaultMoveTarget(u8 battlerId)
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
return GetBattlerAtPosition(opposing);
if (CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_ACTIVE) > 1)
if (CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_BATTLER, battlerId) > 1)
{
u8 position;
@ -6230,7 +6230,7 @@ bool8 HealStatusConditions(struct Pokemon *mon, u32 battlePartyId, u32 healMask,
}
}
u8 GetItemEffectParamOffset(u16 itemId, u8 effectByte, u8 effectBit)
u8 GetItemEffectParamOffset(u32 battler, u16 itemId, u8 effectByte, u8 effectBit)
{
const u8 *temp;
const u8 *itemEffect;
@ -6248,7 +6248,7 @@ u8 GetItemEffectParamOffset(u16 itemId, u8 effectByte, u8 effectBit)
if (itemId == ITEM_ENIGMA_BERRY_E_READER)
{
temp = gEnigmaBerries[gActiveBattler].itemEffect;
temp = gEnigmaBerries[battler].itemEffect;
}
itemEffect = temp;