mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-11-16 11:37:40 +01:00
Merge branch 'upcoming' into ultraburst
This commit is contained in:
commit
d540eccbb1
3
common_syms/battle_controllers.txt
Normal file
3
common_syms/battle_controllers.txt
Normal file
@ -0,0 +1,3 @@
|
||||
gBattlerControllerFuncs
|
||||
gBattleControllerData
|
||||
gBattlerControllerEndFuncs
|
@ -2,8 +2,6 @@ gPreBattleCallback1
|
||||
gBattleMainFunc
|
||||
gBattleResults
|
||||
gLeveledUpInBattle
|
||||
gBattlerControllerFuncs
|
||||
gHealthboxSpriteIds
|
||||
gMultiUsePlayerCursor
|
||||
gNumberOfMovesToChoose
|
||||
gBattleControllerData
|
||||
|
@ -292,6 +292,8 @@ struct AiLogicData
|
||||
s32 simulatedDmg[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT][MAX_MON_MOVES]; // attacker, target, moveIndex
|
||||
u8 effectiveness[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT][MAX_MON_MOVES]; // attacker, target, moveIndex
|
||||
u8 moveLimitations[MAX_BATTLERS_COUNT];
|
||||
bool8 shouldSwitchMon; // Because all available moves have no/little effect. Each bit per battler.
|
||||
u8 monToSwitchId[MAX_BATTLERS_COUNT]; // ID of the mon to switch.
|
||||
};
|
||||
|
||||
struct AI_ThinkingStruct
|
||||
@ -304,8 +306,7 @@ struct AI_ThinkingStruct
|
||||
u32 aiFlags;
|
||||
u8 aiAction;
|
||||
u8 aiLogicId;
|
||||
struct AI_SavedBattleMon saved[4];
|
||||
bool8 switchMon; // Because all available moves have no/little effect.
|
||||
struct AI_SavedBattleMon saved[MAX_BATTLERS_COUNT];
|
||||
};
|
||||
|
||||
#define AI_MOVE_HISTORY_COUNT 3
|
||||
@ -1012,11 +1013,9 @@ extern void (*gPreBattleCallback1)(void);
|
||||
extern void (*gBattleMainFunc)(void);
|
||||
extern struct BattleResults gBattleResults;
|
||||
extern u8 gLeveledUpInBattle;
|
||||
extern void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(void);
|
||||
extern u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT];
|
||||
extern u8 gMultiUsePlayerCursor;
|
||||
extern u8 gNumberOfMovesToChoose;
|
||||
extern u8 gBattleControllerData[MAX_BATTLERS_COUNT];
|
||||
extern bool8 gHasFetchedBall;
|
||||
extern u8 gLastUsedBall;
|
||||
extern u16 gLastThrownBall;
|
||||
|
@ -199,6 +199,9 @@ enum
|
||||
};
|
||||
|
||||
extern struct UnusedControllerStruct gUnusedControllerStruct;
|
||||
extern void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(u32 battler);
|
||||
extern void (*gBattlerControllerEndFuncs[MAX_BATTLERS_COUNT])(u32 battler);
|
||||
extern u8 gBattleControllerData[MAX_BATTLERS_COUNT];
|
||||
|
||||
// general functions
|
||||
void HandleLinkBattleSetup(void);
|
||||
@ -253,43 +256,88 @@ void BtlController_EmitResetActionMoveSelection(u8 bufferId, u8 caseId);
|
||||
void BtlController_EmitEndLinkBattle(u8 bufferId, u8 battleOutcome);
|
||||
void BtlController_EmitDebugMenu(u8 bufferId);
|
||||
|
||||
void BattleControllerComplete(u32 battler); // Can be used for all the controllers.
|
||||
void BtlController_Empty(u32 battler); // Empty command, does nothing, only completes the execution.
|
||||
void BtlController_TerminatorNop(u32 battler); // Dummy function at the end of the table.
|
||||
void BattleControllerDummy(u32 battler);
|
||||
void StartSendOutAnim(u32 battler, bool32 dontClearSubstituteBit);
|
||||
void Controller_WaitForString(u32 battler);
|
||||
void Controller_WaitForHealthBar(u32 battler);
|
||||
|
||||
// handlers
|
||||
void BtlController_HandleGetMonData(u32 battler);
|
||||
void BtlController_HandleGetRawMonData(u32 battler);
|
||||
void BtlController_HandleSetMonData(u32 battler);
|
||||
void BtlController_HandleSetRawMonData(u32 battler);
|
||||
void BtlController_HandleLoadMonSprite(u32 battler, void (*controllerCallback)(u32 battler));
|
||||
void BtlController_HandleSwitchInAnim(u32 battler, bool32 isPlayerSide, void (*controllerCallback)(u32 battler));
|
||||
void BtlController_HandleReturnMonToBall(u32 battler);
|
||||
void BtlController_HandleDrawTrainerPic(u32 battlerId, u32 trainerPicId, bool32 isFrontPic, s16 xPos, s16 yPos, s32 subpriority);
|
||||
void BtlController_HandleTrainerSlide(u32 battler, u32 trainerPicId);
|
||||
void BtlController_HandleTrainerSlideBack(u32 battlerId, s16 data0, bool32 startAnim);
|
||||
void BtlController_HandleFaintAnimation(u32 battler);
|
||||
void BtlController_HandleSuccessBallThrowAnim(u32 battler, u32 target, u32 animId, bool32 allowCriticalCapture);
|
||||
void BtlController_HandleBallThrowAnim(u32 battler, u32 target, u32 animId, bool32 allowCriticalCapture);
|
||||
void BtlController_HandleMoveAnimation(u32 battler, bool32 updateTvData);
|
||||
void BtlController_HandlePrintString(u32 battler, bool32 updateTvData, bool32 arenaPtsDeduct);
|
||||
void BtlController_HandleHealthBarUpdate(u32 battler, bool32 updateHpText);
|
||||
void DoStatusIconUpdate(u32 battler);
|
||||
void BtlController_HandleStatusIconUpdate(u32 battler);
|
||||
void BtlController_HandleStatusAnimation(u32 battler);
|
||||
void BtlController_HandleClearUnkVar(u32 battler);
|
||||
void BtlController_HandleSetUnkVar(u32 battler);
|
||||
void BtlController_HandleClearUnkFlag(u32 battler);
|
||||
void BtlController_HandleToggleUnkFlag(u32 battler);
|
||||
void BtlController_HandleHitAnimation(u32 battler);
|
||||
void BtlController_HandlePlaySE(u32 battler);
|
||||
void BtlController_HandlePlayFanfareOrBGM(u32 battler);
|
||||
void BtlController_HandleFaintingCry(u32 battler);
|
||||
void BtlController_HandleIntroSlide(u32 battler);
|
||||
void BtlController_HandleSpriteInvisibility(u32 battler);
|
||||
bool32 TwoPlayerIntroMons(u32 battlerId); // Double battle with both player pokemon active.
|
||||
bool32 TwoOpponentIntroMons(u32 battlerId); // Double battle with both opponent pokemon active.
|
||||
void BtlController_HandleIntroTrainerBallThrow(u32 battler, u16 tagTrainerPal, const u32 *trainerPal, s16 framesToWait, void (*controllerCallback)(u32 battler));
|
||||
void BtlController_HandleDrawPartyStatusSummary(u32 battler, u32 side, bool32 considerDelay);
|
||||
void BtlController_HandleHidePartyStatusSummary(u32 battler);
|
||||
void BtlController_HandleBattleAnimation(u32 battler, bool32 ignoreSE, bool32 updateTvData);
|
||||
|
||||
// player controller
|
||||
void SetControllerToPlayer(void);
|
||||
void BattleControllerDummy(void);
|
||||
void PlayerHandleGetRawMonData(void);
|
||||
void SetBattleEndCallbacks(void);
|
||||
void SpriteCB_FreePlayerSpriteLoadMonSprite(struct Sprite *sprite);
|
||||
void SetControllerToPlayer(u32 battler);
|
||||
void SetBattleEndCallbacks(u32 battler);
|
||||
void PlayerHandleExpUpdate(u32 battler);
|
||||
u32 LinkPlayerGetTrainerPicId(u32 multiplayerId);
|
||||
void CB2_SetUpReshowBattleScreenAfterMenu(void);
|
||||
void CB2_SetUpReshowBattleScreenAfterMenu2(void);
|
||||
void Task_PlayerController_RestoreBgmAfterCry(u8 taskId);
|
||||
void ActionSelectionCreateCursorAt(u8 cursorPos, u8 unused);
|
||||
void ActionSelectionDestroyCursorAt(u8 cursorPos);
|
||||
void InitMoveSelectionsVarsAndStrings(void);
|
||||
void InitMoveSelectionsVarsAndStrings(u32 battler);
|
||||
void MoveSelectionCreateCursorAt(u8 cursorPos, u8 arg1);
|
||||
void MoveSelectionDestroyCursorAt(u8 cursorPosition);
|
||||
|
||||
// recorded player controller
|
||||
void SetControllerToRecordedPlayer(void);
|
||||
void SetControllerToRecordedPlayer(u32 battler);
|
||||
|
||||
// opponent controller
|
||||
void SetControllerToOpponent(void);
|
||||
void SetControllerToOpponent(u32 battler);
|
||||
|
||||
// player partner controller
|
||||
void SetControllerToPlayerPartner(void);
|
||||
void Controller_PlayerPartnerShowIntroHealthbox(u32 battler); // Also used by the link partner.
|
||||
void SetControllerToPlayerPartner(u32 battler);
|
||||
|
||||
// safari controller
|
||||
void SetControllerToSafari(void);
|
||||
void SetControllerToSafari(u32 battler);
|
||||
|
||||
// wally controller
|
||||
void SetControllerToWally(void);
|
||||
void SetControllerToWally(u32 battler);
|
||||
|
||||
// recorded opponent controller
|
||||
void SetControllerToRecordedOpponent(void);
|
||||
void SetControllerToRecordedOpponent(u32 battler);
|
||||
|
||||
// link opponent
|
||||
void SetControllerToLinkOpponent(void);
|
||||
void SetControllerToLinkOpponent(u32 battler);
|
||||
|
||||
// link partner
|
||||
void SetControllerToLinkPartner(void);
|
||||
void SetControllerToLinkPartner(u32 battler);
|
||||
|
||||
#endif // GUARD_BATTLE_CONTROLLERS_H
|
||||
|
@ -1,8 +1,6 @@
|
||||
#ifndef GUARD_BATTLE_DOME_H
|
||||
#define GUARD_BATTLE_DOME_H
|
||||
|
||||
extern u32 gPlayerPartyLostHP;
|
||||
|
||||
int GetDomeTrainerSelectedMons(u16 tournamentTrainerId);
|
||||
int TrainerIdToDomeTournamentId(u16 trainerId);
|
||||
|
||||
|
@ -10,12 +10,10 @@ void InitAndLaunchChosenStatusAnimation(bool8 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 BattleLoadOpponentMonSpriteGfx(struct Pokemon *mon, u8 battlerId);
|
||||
void BattleLoadPlayerMonSpriteGfx(struct Pokemon *mon, u8 battlerId);
|
||||
void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battlerId);
|
||||
void BattleGfxSfxDummy2(u16 species);
|
||||
void DecompressTrainerFrontPic(u16 frontPicId, u8 battlerId);
|
||||
void DecompressTrainerBackPic(u16 backPicId, u8 battlerId);
|
||||
void BattleGfxSfxDummy3(u8 gender);
|
||||
void FreeTrainerFrontPicPalette(u16 frontPicId);
|
||||
bool8 BattleLoadAllHealthBoxesGfx(u8 state);
|
||||
void LoadBattleBarGfx(u8 unused);
|
||||
|
@ -403,6 +403,78 @@ void GetAiLogicData(void)
|
||||
}
|
||||
}
|
||||
|
||||
static bool32 AI_SwitchMonIfSuitable(u32 battlerId)
|
||||
{
|
||||
u32 monToSwitchId = GetMostSuitableMonToSwitchInto();
|
||||
if (monToSwitchId != PARTY_SIZE)
|
||||
{
|
||||
AI_DATA->shouldSwitchMon |= gBitTable[battlerId];
|
||||
AI_DATA->monToSwitchId[battlerId] = monToSwitchId;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bool32 AI_ShouldSwitchIfBadMoves(u32 battlerId, bool32 doubleBattle)
|
||||
{
|
||||
u32 i, j;
|
||||
// If can switch.
|
||||
if (CountUsablePartyMons(battlerId) > 0
|
||||
&& !IsBattlerTrapped(battlerId, TRUE)
|
||||
&& !(gBattleTypeFlags & (BATTLE_TYPE_ARENA | BATTLE_TYPE_PALACE))
|
||||
&& AI_THINKING_STRUCT->aiFlags & (AI_FLAG_CHECK_VIABILITY | AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_PREFER_BATON_PASS))
|
||||
{
|
||||
// Consider switching if all moves are worthless to use.
|
||||
if (GetTotalBaseStat(gBattleMons[battlerId].species) >= 310 // Mon is not weak.
|
||||
&& gBattleMons[battlerId].hp >= gBattleMons[battlerId].maxHP / 2) // Mon has more than 50% of its HP
|
||||
{
|
||||
s32 cap = AI_THINKING_STRUCT->aiFlags & (AI_FLAG_CHECK_VIABILITY) ? 95 : 93;
|
||||
if (doubleBattle)
|
||||
{
|
||||
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
||||
{
|
||||
if (i != battlerId && IsBattlerAlive(i))
|
||||
{
|
||||
for (j = 0; j < MAX_MON_MOVES; j++)
|
||||
{
|
||||
if (gBattleStruct->aiFinalScore[battlerId][i][j] > cap)
|
||||
break;
|
||||
}
|
||||
if (j != MAX_MON_MOVES)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == MAX_BATTLERS_COUNT && AI_SwitchMonIfSuitable(battlerId))
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (AI_THINKING_STRUCT->score[i] > cap)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == MAX_MON_MOVES && AI_SwitchMonIfSuitable(battlerId))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Consider switching if your mon with truant is bodied by Protect spam.
|
||||
// Or is using a double turn semi invulnerable move(such as Fly) and is faster.
|
||||
if (GetBattlerAbility(battlerId) == ABILITY_TRUANT
|
||||
&& IsTruantMonVulnerable(battlerId, gBattlerTarget)
|
||||
&& gDisableStructs[battlerId].truantCounter
|
||||
&& gBattleMons[battlerId].hp >= gBattleMons[battlerId].maxHP / 2
|
||||
&& AI_SwitchMonIfSuitable(battlerId))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static u8 ChooseMoveOrAction_Singles(void)
|
||||
{
|
||||
u8 currentMoveArray[MAX_MON_MOVES];
|
||||
@ -436,46 +508,9 @@ static u8 ChooseMoveOrAction_Singles(void)
|
||||
|
||||
gActiveBattler = sBattler_AI;
|
||||
|
||||
// If can switch.
|
||||
if (CountUsablePartyMons(sBattler_AI) > 0
|
||||
&& !IsAbilityPreventingEscape(sBattler_AI)
|
||||
&& !(gBattleMons[gActiveBattler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION))
|
||||
&& !(gStatuses3[gActiveBattler] & STATUS3_ROOTED)
|
||||
&& !(gBattleTypeFlags & (BATTLE_TYPE_ARENA | BATTLE_TYPE_PALACE))
|
||||
&& AI_THINKING_STRUCT->aiFlags & (AI_FLAG_CHECK_VIABILITY | AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_PREFER_BATON_PASS))
|
||||
{
|
||||
// Consider switching if all moves are worthless to use.
|
||||
if (GetTotalBaseStat(gBattleMons[sBattler_AI].species) >= 310 // Mon is not weak.
|
||||
&& gBattleMons[sBattler_AI].hp >= gBattleMons[sBattler_AI].maxHP / 2)
|
||||
{
|
||||
s32 cap = AI_THINKING_STRUCT->aiFlags & (AI_FLAG_CHECK_VIABILITY) ? 95 : 93;
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (AI_THINKING_STRUCT->score[i] > cap)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == MAX_MON_MOVES && GetMostSuitableMonToSwitchInto() != PARTY_SIZE)
|
||||
{
|
||||
AI_THINKING_STRUCT->switchMon = TRUE;
|
||||
return AI_CHOICE_SWITCH;
|
||||
}
|
||||
}
|
||||
|
||||
// Consider switching if your mon with truant is bodied by Protect spam.
|
||||
// Or is using a double turn semi invulnerable move(such as Fly) and is faster.
|
||||
if (GetBattlerAbility(sBattler_AI) == ABILITY_TRUANT
|
||||
&& IsTruantMonVulnerable(sBattler_AI, gBattlerTarget)
|
||||
&& gDisableStructs[sBattler_AI].truantCounter
|
||||
&& gBattleMons[sBattler_AI].hp >= gBattleMons[sBattler_AI].maxHP / 2)
|
||||
{
|
||||
if (GetMostSuitableMonToSwitchInto() != PARTY_SIZE)
|
||||
{
|
||||
AI_THINKING_STRUCT->switchMon = TRUE;
|
||||
return AI_CHOICE_SWITCH;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Switch mon if there are no good moves to use.
|
||||
if (AI_ShouldSwitchIfBadMoves(sBattler_AI, FALSE))
|
||||
return AI_CHOICE_SWITCH;
|
||||
|
||||
numOfBestMoves = 1;
|
||||
currentMoveArray[0] = AI_THINKING_STRUCT->score[0];
|
||||
@ -590,7 +625,6 @@ static u8 ChooseMoveOrAction_Doubles(void)
|
||||
if (i == BATTLE_PARTNER(sBattler_AI) && bestMovePointsForTarget[i] < 100)
|
||||
{
|
||||
bestMovePointsForTarget[i] = -1;
|
||||
mostViableMovesScores[0] = mostViableMovesScores[0]; // Needed to match.
|
||||
}
|
||||
}
|
||||
|
||||
@ -600,6 +634,10 @@ static u8 ChooseMoveOrAction_Doubles(void)
|
||||
}
|
||||
}
|
||||
|
||||
// Switch mon if all of the moves are bad to use against any of the target.
|
||||
if (AI_ShouldSwitchIfBadMoves(sBattler_AI, TRUE))
|
||||
return AI_CHOICE_SWITCH;
|
||||
|
||||
mostMovePoints = bestMovePointsForTarget[0];
|
||||
mostViableTargetsArray[0] = 0;
|
||||
mostViableTargetsNo = 1;
|
||||
@ -1647,18 +1685,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
break;
|
||||
case EFFECT_FAKE_OUT:
|
||||
if (!gDisableStructs[battlerAtk].isFirstTurn)
|
||||
{
|
||||
score -= 10;
|
||||
}
|
||||
else if (move == MOVE_FAKE_OUT) // filter out first impression
|
||||
{
|
||||
if ((AI_DATA->holdEffects[battlerAtk] == HOLD_EFFECT_CHOICE_BAND || AI_DATA->abilities[battlerAtk] == ABILITY_GORILLA_TACTICS)
|
||||
&& (CountUsablePartyMons(battlerDef) > 0 || !CanIndexMoveFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)))
|
||||
{
|
||||
if (CountUsablePartyMons(battlerAtk) == 0)
|
||||
score -= 10; // Don't lock the attacker into Fake Out if they can't switch out afterwards.
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EFFECT_STOCKPILE:
|
||||
if (gDisableStructs[battlerAtk].stockpileCounter >= 3)
|
||||
@ -3094,7 +3121,7 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
|| IS_BATTLER_OF_TYPE(battlerAtkPartner, TYPE_POISON)
|
||||
|| IS_BATTLER_OF_TYPE(battlerAtkPartner, TYPE_ROCK))
|
||||
score -= 10; // partner will be hit by earthquake and is weak to it
|
||||
else
|
||||
else if (IsBattlerAlive(battlerAtkPartner))
|
||||
score -= 3;
|
||||
break;
|
||||
}
|
||||
@ -4137,9 +4164,13 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
|
||||
IncreaseStatUpScore(battlerAtk, battlerDef, STAT_DEF, &score);
|
||||
break;
|
||||
case EFFECT_FAKE_OUT:
|
||||
if (move == MOVE_FAKE_OUT // filter out first impression
|
||||
&& ShouldFakeOut(battlerAtk, battlerDef, move))
|
||||
score += 8;
|
||||
if (move == MOVE_FAKE_OUT) // filter out first impression
|
||||
{
|
||||
if (ShouldFakeOut(battlerAtk, battlerDef, move))
|
||||
score += 4;
|
||||
else
|
||||
score -= 10;
|
||||
}
|
||||
break;
|
||||
case EFFECT_STOCKPILE:
|
||||
if (AI_DATA->abilities[battlerAtk] == ABILITY_CONTRARY)
|
||||
|
@ -60,10 +60,10 @@ void GetAIPartyIndexes(u32 battlerId, s32 *firstId, s32 *lastId)
|
||||
|
||||
static bool8 ShouldSwitchIfAllBadMoves(void)
|
||||
{
|
||||
if (gBattleResources->ai->switchMon)
|
||||
if (AI_DATA->shouldSwitchMon & gBitTable[gActiveBattler])
|
||||
{
|
||||
gBattleResources->ai->switchMon = 0;
|
||||
*(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler) = PARTY_SIZE;
|
||||
AI_DATA->shouldSwitchMon &= ~(gBitTable[gActiveBattler]);
|
||||
gBattleStruct->AI_monToSwitchIntoId[gActiveBattler] = AI_DATA->monToSwitchId[gActiveBattler];
|
||||
BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_SWITCH, 0);
|
||||
return TRUE;
|
||||
}
|
||||
@ -142,11 +142,12 @@ static bool8 ShouldSwitchIfWonderGuard(void)
|
||||
static bool8 FindMonThatAbsorbsOpponentsMove(void)
|
||||
{
|
||||
u8 battlerIn1, battlerIn2;
|
||||
u16 absorbingTypeAbility;
|
||||
u8 numAbsorbingAbilities = 0;
|
||||
u16 absorbingTypeAbilities[3]; // Array size is maximum number of absorbing abilities for a single type
|
||||
s32 firstId;
|
||||
s32 lastId; // + 1
|
||||
struct Pokemon *party;
|
||||
s32 i;
|
||||
s32 i, j;
|
||||
|
||||
if (HasSuperEffectiveMoveAgainstOpponents(TRUE) && Random() % 3 != 0)
|
||||
return FALSE;
|
||||
@ -171,17 +172,42 @@ static bool8 FindMonThatAbsorbsOpponentsMove(void)
|
||||
battlerIn2 = gActiveBattler;
|
||||
}
|
||||
|
||||
// Create an array of possible absorb abilities so the AI considers all of them
|
||||
if (gBattleMoves[gLastLandedMoves[gActiveBattler]].type == TYPE_FIRE)
|
||||
absorbingTypeAbility = ABILITY_FLASH_FIRE;
|
||||
{
|
||||
absorbingTypeAbilities[0] = ABILITY_FLASH_FIRE;
|
||||
numAbsorbingAbilities = 1;
|
||||
}
|
||||
else if (gBattleMoves[gLastLandedMoves[gActiveBattler]].type == TYPE_WATER)
|
||||
absorbingTypeAbility = ABILITY_WATER_ABSORB;
|
||||
{
|
||||
absorbingTypeAbilities[0] = ABILITY_WATER_ABSORB;
|
||||
absorbingTypeAbilities[1] = ABILITY_STORM_DRAIN;
|
||||
absorbingTypeAbilities[2] = ABILITY_DRY_SKIN;
|
||||
numAbsorbingAbilities = 3;
|
||||
}
|
||||
else if (gBattleMoves[gLastLandedMoves[gActiveBattler]].type == TYPE_ELECTRIC)
|
||||
absorbingTypeAbility = ABILITY_VOLT_ABSORB;
|
||||
{
|
||||
absorbingTypeAbilities[0] = ABILITY_VOLT_ABSORB;
|
||||
absorbingTypeAbilities[1] = ABILITY_MOTOR_DRIVE;
|
||||
absorbingTypeAbilities[2] = ABILITY_LIGHTNING_ROD;
|
||||
numAbsorbingAbilities = 3;
|
||||
}
|
||||
else if (gBattleMoves[gLastLandedMoves[gActiveBattler]].type == TYPE_GRASS)
|
||||
{
|
||||
absorbingTypeAbilities[0] = ABILITY_SAP_SIPPER;
|
||||
numAbsorbingAbilities = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (AI_DATA->abilities[gActiveBattler] == absorbingTypeAbility)
|
||||
return FALSE;
|
||||
// Check current mon for all absorbing abilities
|
||||
for (i = 0; i < numAbsorbingAbilities; i++)
|
||||
{
|
||||
if (AI_DATA->abilities[gActiveBattler] == absorbingTypeAbilities[i])
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GetAIPartyIndexes(gActiveBattler, &firstId, &lastId);
|
||||
|
||||
@ -208,15 +234,18 @@ static bool8 FindMonThatAbsorbsOpponentsMove(void)
|
||||
continue;
|
||||
|
||||
monAbility = GetMonAbility(&party[i]);
|
||||
if (absorbingTypeAbility == monAbility && Random() & 1)
|
||||
|
||||
for (j = 0; j < numAbsorbingAbilities; j++)
|
||||
{
|
||||
// we found a mon.
|
||||
*(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler) = i;
|
||||
BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_SWITCH, 0);
|
||||
return TRUE;
|
||||
if (absorbingTypeAbilities[j] == monAbility && Random() & 1)
|
||||
{
|
||||
// we found a mon.
|
||||
*(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler) = i;
|
||||
BtlController_EmitTwoReturnValues(1, B_ACTION_SWITCH, 0);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -2964,24 +2964,23 @@ bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility)
|
||||
|
||||
u32 ShouldTryToFlinch(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u16 move)
|
||||
{
|
||||
if (defAbility == ABILITY_INNER_FOCUS
|
||||
if (((AI_DATA->abilities[battlerAtk] != ABILITY_MOLD_BREAKER && (defAbility == ABILITY_SHIELD_DUST || defAbility == ABILITY_INNER_FOCUS))
|
||||
|| AI_GetHoldEffect(battlerDef) == HOLD_EFFECT_COVERT_CLOAK
|
||||
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
||||
|| AI_WhoStrikesFirst(battlerAtk, battlerDef, move) == AI_IS_SLOWER) // Opponent goes first
|
||||
|| AI_WhoStrikesFirst(battlerAtk, battlerDef, move) == AI_IS_SLOWER)) // Opponent goes first
|
||||
{
|
||||
return 0; // don't try to flinch
|
||||
return 0;
|
||||
}
|
||||
else if ((gBattleMons[battlerDef].status1 & STATUS1_SLEEP) && !HasMoveEffect(battlerDef, EFFECT_SLEEP_TALK) && !HasMoveEffect(battlerDef, EFFECT_SNORE))
|
||||
{
|
||||
return 0; // don't try to flinch sleeping pokemon
|
||||
}
|
||||
else if (atkAbility == ABILITY_SERENE_GRACE
|
||||
else if ((atkAbility == ABILITY_SERENE_GRACE
|
||||
|| gBattleMons[battlerDef].status1 & STATUS1_PARALYSIS
|
||||
|| gBattleMons[battlerDef].status2 & STATUS2_INFATUATION
|
||||
|| gBattleMons[battlerDef].status2 & STATUS2_CONFUSION)
|
||||
|| ((AI_WhoStrikesFirst(battlerAtk, battlerDef, move) == AI_IS_FASTER) && CanTargetFaintAi(battlerDef, battlerAtk)))
|
||||
{
|
||||
return 2; // good idea to flinch
|
||||
}
|
||||
return 1; // decent idea to flinch
|
||||
|
||||
return 0; // don't try to flinch
|
||||
}
|
||||
|
||||
bool32 ShouldTrap(u8 battlerAtk, u8 battlerDef, u16 move)
|
||||
@ -3000,15 +2999,16 @@ bool32 ShouldTrap(u8 battlerAtk, u8 battlerDef, u16 move)
|
||||
|
||||
bool32 ShouldFakeOut(u8 battlerAtk, u8 battlerDef, u16 move)
|
||||
{
|
||||
if (AI_DATA->holdEffects[battlerAtk] == HOLD_EFFECT_CHOICE_BAND && CountUsablePartyMons(battlerAtk) == 0)
|
||||
return FALSE; // don't lock attacker into fake out if can't switch out
|
||||
if (!gDisableStructs[battlerAtk].isFirstTurn
|
||||
|| AI_DATA->abilities[battlerAtk] == ABILITY_GORILLA_TACTICS
|
||||
|| AI_DATA->holdEffects[battlerAtk] == HOLD_EFFECT_CHOICE_BAND
|
||||
|| AI_GetHoldEffect(battlerDef) == HOLD_EFFECT_COVERT_CLOAK
|
||||
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
||||
|| (AI_DATA->abilities[battlerAtk] != ABILITY_MOLD_BREAKER
|
||||
&& (AI_DATA->abilities[battlerDef] == ABILITY_SHIELD_DUST || AI_DATA->abilities[battlerDef] == ABILITY_INNER_FOCUS)))
|
||||
return FALSE;
|
||||
|
||||
if (gDisableStructs[battlerAtk].isFirstTurn
|
||||
&& ShouldTryToFlinch(battlerAtk, battlerDef, AI_DATA->abilities[battlerAtk], AI_DATA->abilities[battlerDef], move)
|
||||
&& !DoesSubstituteBlockMove(battlerAtk, battlerDef, move))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static u32 FindMoveUsedXTurnsAgo(u32 battlerId, u32 x)
|
||||
@ -3676,7 +3676,8 @@ void IncreaseStatUpScore(u8 battlerAtk, u8 battlerDef, u8 statId, s16 *score)
|
||||
|
||||
void IncreasePoisonScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
{
|
||||
if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
if (((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
|| AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_PSN || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS)
|
||||
return;
|
||||
|
||||
if (AI_CanPoison(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef], move, AI_DATA->partnerMove) && AI_DATA->hpPercents[battlerDef] > 20)
|
||||
@ -3699,7 +3700,8 @@ void IncreasePoisonScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
|
||||
void IncreaseBurnScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
{
|
||||
if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
if (((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
|| AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_BRN || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS)
|
||||
return;
|
||||
|
||||
if (AI_CanBurn(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef], BATTLE_PARTNER(battlerAtk), move, AI_DATA->partnerMove))
|
||||
@ -3718,7 +3720,8 @@ void IncreaseBurnScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
|
||||
void IncreaseParalyzeScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
{
|
||||
if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
if (((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
|| AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_PAR || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS)
|
||||
return;
|
||||
|
||||
if (AI_CanParalyze(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef], move, AI_DATA->partnerMove))
|
||||
@ -3739,7 +3742,8 @@ void IncreaseParalyzeScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
|
||||
void IncreaseSleepScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
{
|
||||
if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
if (((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
|| AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_SLP || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS)
|
||||
return;
|
||||
|
||||
if (AI_CanPutToSleep(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef], move, AI_DATA->partnerMove))
|
||||
@ -3757,7 +3761,8 @@ void IncreaseSleepScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
|
||||
void IncreaseConfusionScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score)
|
||||
{
|
||||
if ((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
if (((AI_THINKING_STRUCT->aiFlags & AI_FLAG_TRY_TO_FAINT) && CanAIFaintTarget(battlerAtk, battlerDef, 0))
|
||||
|| AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_CONFUSION || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_CURE_STATUS)
|
||||
return;
|
||||
|
||||
if (AI_CanConfuse(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef], BATTLE_PARTNER(battlerAtk), move, AI_DATA->partnerMove)
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -22,160 +22,112 @@
|
||||
#include "window.h"
|
||||
#include "constants/battle_anim.h"
|
||||
#include "constants/songs.h"
|
||||
#include "constants/trainers.h"
|
||||
#include "constants/rgb.h"
|
||||
|
||||
static void SafariHandleGetMonData(void);
|
||||
static void SafariHandleGetRawMonData(void);
|
||||
static void SafariHandleSetMonData(void);
|
||||
static void SafariHandleSetRawMonData(void);
|
||||
static void SafariHandleLoadMonSprite(void);
|
||||
static void SafariHandleSwitchInAnim(void);
|
||||
static void SafariHandleReturnMonToBall(void);
|
||||
static void SafariHandleDrawTrainerPic(void);
|
||||
static void SafariHandleTrainerSlide(void);
|
||||
static void SafariHandleTrainerSlideBack(void);
|
||||
static void SafariHandleFaintAnimation(void);
|
||||
static void SafariHandlePaletteFade(void);
|
||||
static void SafariHandleSuccessBallThrowAnim(void);
|
||||
static void SafariHandleBallThrowAnim(void);
|
||||
static void SafariHandlePause(void);
|
||||
static void SafariHandleMoveAnimation(void);
|
||||
static void SafariHandlePrintString(void);
|
||||
static void SafariHandlePrintSelectionString(void);
|
||||
static void SafariHandleChooseAction(void);
|
||||
static void SafariHandleYesNoBox(void);
|
||||
static void SafariHandleChooseMove(void);
|
||||
static void SafariHandleChooseItem(void);
|
||||
static void SafariHandleChoosePokemon(void);
|
||||
static void SafariHandleCmd23(void);
|
||||
static void SafariHandleHealthBarUpdate(void);
|
||||
static void SafariHandleExpUpdate(void);
|
||||
static void SafariHandleStatusIconUpdate(void);
|
||||
static void SafariHandleStatusAnimation(void);
|
||||
static void SafariHandleStatusXor(void);
|
||||
static void SafariHandleDataTransfer(void);
|
||||
static void SafariHandleDMA3Transfer(void);
|
||||
static void SafariHandlePlayBGM(void);
|
||||
static void SafariHandleCmd32(void);
|
||||
static void SafariHandleTwoReturnValues(void);
|
||||
static void SafariHandleChosenMonReturnValue(void);
|
||||
static void SafariHandleOneReturnValue(void);
|
||||
static void SafariHandleOneReturnValue_Duplicate(void);
|
||||
static void SafariHandleClearUnkVar(void);
|
||||
static void SafariHandleSetUnkVar(void);
|
||||
static void SafariHandleClearUnkFlag(void);
|
||||
static void SafariHandleToggleUnkFlag(void);
|
||||
static void SafariHandleHitAnimation(void);
|
||||
static void SafariHandleCantSwitch(void);
|
||||
static void SafariHandlePlaySE(void);
|
||||
static void SafariHandlePlayFanfareOrBGM(void);
|
||||
static void SafariHandleFaintingCry(void);
|
||||
static void SafariHandleIntroSlide(void);
|
||||
static void SafariHandleIntroTrainerBallThrow(void);
|
||||
static void SafariHandleDrawPartyStatusSummary(void);
|
||||
static void SafariHandleHidePartyStatusSummary(void);
|
||||
static void SafariHandleEndBounceEffect(void);
|
||||
static void SafariHandleSpriteInvisibility(void);
|
||||
static void SafariHandleBattleAnimation(void);
|
||||
static void SafariHandleLinkStandbyMsg(void);
|
||||
static void SafariHandleResetActionMoveSelection(void);
|
||||
static void SafariHandleEndLinkBattle(void);
|
||||
static void SafariHandleBattleDebug(void);
|
||||
static void SafariCmdEnd(void);
|
||||
static void SafariHandleDrawTrainerPic(u32 battler);
|
||||
static void SafariHandleSuccessBallThrowAnim(u32 battler);
|
||||
static void SafariHandleBallThrowAnim(u32 battler);
|
||||
static void SafariHandlePrintString(u32 battler);
|
||||
static void SafariHandlePrintSelectionString(u32 battler);
|
||||
static void SafariHandleChooseAction(u32 battler);
|
||||
static void SafariHandleChooseItem(u32 battler);
|
||||
static void SafariHandleStatusIconUpdate(u32 battler);
|
||||
static void SafariHandleFaintingCry(u32 battler);
|
||||
static void SafariHandleIntroTrainerBallThrow(u32 battler);
|
||||
static void SafariHandleBattleAnimation(u32 battler);
|
||||
static void SafariHandleEndLinkBattle(u32 battler);
|
||||
|
||||
static void SafariBufferRunCommand(void);
|
||||
static void SafariBufferExecCompleted(void);
|
||||
static void CompleteWhenChosePokeblock(void);
|
||||
static void SafariBufferRunCommand(u32 battler);
|
||||
static void SafariBufferExecCompleted(u32 battler);
|
||||
static void CompleteWhenChosePokeblock(u32 battler);
|
||||
|
||||
static void (*const sSafariBufferCommands[CONTROLLER_CMDS_COUNT])(void) =
|
||||
static void (*const sSafariBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
|
||||
{
|
||||
[CONTROLLER_GETMONDATA] = SafariHandleGetMonData,
|
||||
[CONTROLLER_GETRAWMONDATA] = SafariHandleGetRawMonData,
|
||||
[CONTROLLER_SETMONDATA] = SafariHandleSetMonData,
|
||||
[CONTROLLER_SETRAWMONDATA] = SafariHandleSetRawMonData,
|
||||
[CONTROLLER_LOADMONSPRITE] = SafariHandleLoadMonSprite,
|
||||
[CONTROLLER_SWITCHINANIM] = SafariHandleSwitchInAnim,
|
||||
[CONTROLLER_RETURNMONTOBALL] = SafariHandleReturnMonToBall,
|
||||
[CONTROLLER_GETMONDATA] = BtlController_Empty,
|
||||
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty,
|
||||
[CONTROLLER_SETMONDATA] = BtlController_Empty,
|
||||
[CONTROLLER_SETRAWMONDATA] = BtlController_Empty,
|
||||
[CONTROLLER_LOADMONSPRITE] = BtlController_Empty,
|
||||
[CONTROLLER_SWITCHINANIM] = BtlController_Empty,
|
||||
[CONTROLLER_RETURNMONTOBALL] = BtlController_Empty,
|
||||
[CONTROLLER_DRAWTRAINERPIC] = SafariHandleDrawTrainerPic,
|
||||
[CONTROLLER_TRAINERSLIDE] = SafariHandleTrainerSlide,
|
||||
[CONTROLLER_TRAINERSLIDEBACK] = SafariHandleTrainerSlideBack,
|
||||
[CONTROLLER_FAINTANIMATION] = SafariHandleFaintAnimation,
|
||||
[CONTROLLER_PALETTEFADE] = SafariHandlePaletteFade,
|
||||
[CONTROLLER_TRAINERSLIDE] = BtlController_Empty,
|
||||
[CONTROLLER_TRAINERSLIDEBACK] = BtlController_Empty,
|
||||
[CONTROLLER_FAINTANIMATION] = BtlController_Empty,
|
||||
[CONTROLLER_PALETTEFADE] = BtlController_Empty,
|
||||
[CONTROLLER_SUCCESSBALLTHROWANIM] = SafariHandleSuccessBallThrowAnim,
|
||||
[CONTROLLER_BALLTHROWANIM] = SafariHandleBallThrowAnim,
|
||||
[CONTROLLER_PAUSE] = SafariHandlePause,
|
||||
[CONTROLLER_MOVEANIMATION] = SafariHandleMoveAnimation,
|
||||
[CONTROLLER_PAUSE] = BtlController_Empty,
|
||||
[CONTROLLER_MOVEANIMATION] = BtlController_Empty,
|
||||
[CONTROLLER_PRINTSTRING] = SafariHandlePrintString,
|
||||
[CONTROLLER_PRINTSTRINGPLAYERONLY] = SafariHandlePrintSelectionString,
|
||||
[CONTROLLER_CHOOSEACTION] = SafariHandleChooseAction,
|
||||
[CONTROLLER_YESNOBOX] = SafariHandleYesNoBox,
|
||||
[CONTROLLER_CHOOSEMOVE] = SafariHandleChooseMove,
|
||||
[CONTROLLER_YESNOBOX] = BtlController_Empty,
|
||||
[CONTROLLER_CHOOSEMOVE] = BtlController_Empty,
|
||||
[CONTROLLER_OPENBAG] = SafariHandleChooseItem,
|
||||
[CONTROLLER_CHOOSEPOKEMON] = SafariHandleChoosePokemon,
|
||||
[CONTROLLER_23] = SafariHandleCmd23,
|
||||
[CONTROLLER_HEALTHBARUPDATE] = SafariHandleHealthBarUpdate,
|
||||
[CONTROLLER_EXPUPDATE] = SafariHandleExpUpdate,
|
||||
[CONTROLLER_CHOOSEPOKEMON] = BtlController_Empty,
|
||||
[CONTROLLER_23] = BtlController_Empty,
|
||||
[CONTROLLER_HEALTHBARUPDATE] = BtlController_Empty,
|
||||
[CONTROLLER_EXPUPDATE] = BtlController_Empty,
|
||||
[CONTROLLER_STATUSICONUPDATE] = SafariHandleStatusIconUpdate,
|
||||
[CONTROLLER_STATUSANIMATION] = SafariHandleStatusAnimation,
|
||||
[CONTROLLER_STATUSXOR] = SafariHandleStatusXor,
|
||||
[CONTROLLER_DATATRANSFER] = SafariHandleDataTransfer,
|
||||
[CONTROLLER_DMA3TRANSFER] = SafariHandleDMA3Transfer,
|
||||
[CONTROLLER_PLAYBGM] = SafariHandlePlayBGM,
|
||||
[CONTROLLER_32] = SafariHandleCmd32,
|
||||
[CONTROLLER_TWORETURNVALUES] = SafariHandleTwoReturnValues,
|
||||
[CONTROLLER_CHOSENMONRETURNVALUE] = SafariHandleChosenMonReturnValue,
|
||||
[CONTROLLER_ONERETURNVALUE] = SafariHandleOneReturnValue,
|
||||
[CONTROLLER_ONERETURNVALUE_DUPLICATE] = SafariHandleOneReturnValue_Duplicate,
|
||||
[CONTROLLER_CLEARUNKVAR] = SafariHandleClearUnkVar,
|
||||
[CONTROLLER_SETUNKVAR] = SafariHandleSetUnkVar,
|
||||
[CONTROLLER_CLEARUNKFLAG] = SafariHandleClearUnkFlag,
|
||||
[CONTROLLER_TOGGLEUNKFLAG] = SafariHandleToggleUnkFlag,
|
||||
[CONTROLLER_HITANIMATION] = SafariHandleHitAnimation,
|
||||
[CONTROLLER_CANTSWITCH] = SafariHandleCantSwitch,
|
||||
[CONTROLLER_PLAYSE] = SafariHandlePlaySE,
|
||||
[CONTROLLER_PLAYFANFAREORBGM] = SafariHandlePlayFanfareOrBGM,
|
||||
[CONTROLLER_STATUSANIMATION] = BtlController_Empty,
|
||||
[CONTROLLER_STATUSXOR] = BtlController_Empty,
|
||||
[CONTROLLER_DATATRANSFER] = BtlController_Empty,
|
||||
[CONTROLLER_DMA3TRANSFER] = BtlController_Empty,
|
||||
[CONTROLLER_PLAYBGM] = BtlController_Empty,
|
||||
[CONTROLLER_32] = BtlController_Empty,
|
||||
[CONTROLLER_TWORETURNVALUES] = BtlController_Empty,
|
||||
[CONTROLLER_CHOSENMONRETURNVALUE] = BtlController_Empty,
|
||||
[CONTROLLER_ONERETURNVALUE] = BtlController_Empty,
|
||||
[CONTROLLER_ONERETURNVALUE_DUPLICATE] = BtlController_Empty,
|
||||
[CONTROLLER_CLEARUNKVAR] = BtlController_Empty,
|
||||
[CONTROLLER_SETUNKVAR] = BtlController_Empty,
|
||||
[CONTROLLER_CLEARUNKFLAG] = BtlController_Empty,
|
||||
[CONTROLLER_TOGGLEUNKFLAG] = BtlController_Empty,
|
||||
[CONTROLLER_HITANIMATION] = BtlController_Empty,
|
||||
[CONTROLLER_CANTSWITCH] = BtlController_Empty,
|
||||
[CONTROLLER_PLAYSE] = BtlController_HandlePlaySE,
|
||||
[CONTROLLER_PLAYFANFAREORBGM] = BtlController_HandlePlayFanfareOrBGM,
|
||||
[CONTROLLER_FAINTINGCRY] = SafariHandleFaintingCry,
|
||||
[CONTROLLER_INTROSLIDE] = SafariHandleIntroSlide,
|
||||
[CONTROLLER_INTROSLIDE] = BtlController_HandleIntroSlide,
|
||||
[CONTROLLER_INTROTRAINERBALLTHROW] = SafariHandleIntroTrainerBallThrow,
|
||||
[CONTROLLER_DRAWPARTYSTATUSSUMMARY] = SafariHandleDrawPartyStatusSummary,
|
||||
[CONTROLLER_HIDEPARTYSTATUSSUMMARY] = SafariHandleHidePartyStatusSummary,
|
||||
[CONTROLLER_ENDBOUNCE] = SafariHandleEndBounceEffect,
|
||||
[CONTROLLER_SPRITEINVISIBILITY] = SafariHandleSpriteInvisibility,
|
||||
[CONTROLLER_DRAWPARTYSTATUSSUMMARY] = BtlController_Empty,
|
||||
[CONTROLLER_HIDEPARTYSTATUSSUMMARY] = BtlController_Empty,
|
||||
[CONTROLLER_ENDBOUNCE] = BtlController_Empty,
|
||||
[CONTROLLER_SPRITEINVISIBILITY] = BtlController_Empty,
|
||||
[CONTROLLER_BATTLEANIMATION] = SafariHandleBattleAnimation,
|
||||
[CONTROLLER_LINKSTANDBYMSG] = SafariHandleLinkStandbyMsg,
|
||||
[CONTROLLER_RESETACTIONMOVESELECTION] = SafariHandleResetActionMoveSelection,
|
||||
[CONTROLLER_LINKSTANDBYMSG] = BtlController_Empty,
|
||||
[CONTROLLER_RESETACTIONMOVESELECTION] = BtlController_Empty,
|
||||
[CONTROLLER_ENDLINKBATTLE] = SafariHandleEndLinkBattle,
|
||||
[CONTROLLER_DEBUGMENU] = SafariHandleBattleDebug,
|
||||
[CONTROLLER_TERMINATOR_NOP] = SafariCmdEnd
|
||||
[CONTROLLER_DEBUGMENU] = BtlController_Empty,
|
||||
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop
|
||||
};
|
||||
|
||||
static void SpriteCB_Null4(void)
|
||||
void SetControllerToSafari(u32 battler)
|
||||
{
|
||||
gBattlerControllerEndFuncs[battler] = SafariBufferExecCompleted;
|
||||
gBattlerControllerFuncs[battler] = SafariBufferRunCommand;
|
||||
}
|
||||
|
||||
void SetControllerToSafari(void)
|
||||
static void SafariBufferRunCommand(u32 battler)
|
||||
{
|
||||
gBattlerControllerFuncs[gActiveBattler] = SafariBufferRunCommand;
|
||||
}
|
||||
|
||||
static void SafariBufferRunCommand(void)
|
||||
{
|
||||
if (gBattleControllerExecFlags & gBitTable[gActiveBattler])
|
||||
if (gBattleControllerExecFlags & gBitTable[battler])
|
||||
{
|
||||
if (gBattleResources->bufferA[gActiveBattler][0] < ARRAY_COUNT(sSafariBufferCommands))
|
||||
sSafariBufferCommands[gBattleResources->bufferA[gActiveBattler][0]]();
|
||||
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sSafariBufferCommands))
|
||||
sSafariBufferCommands[gBattleResources->bufferA[battler][0]](battler);
|
||||
else
|
||||
SafariBufferExecCompleted();
|
||||
SafariBufferExecCompleted(battler);
|
||||
}
|
||||
}
|
||||
|
||||
static void HandleInputChooseAction(void)
|
||||
static void HandleInputChooseAction(u32 battler)
|
||||
{
|
||||
if (JOY_NEW(A_BUTTON))
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
|
||||
switch (gActionSelectionCursor[gActiveBattler])
|
||||
switch (gActionSelectionCursor[battler])
|
||||
{
|
||||
case 0:
|
||||
BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_SAFARI_BALL, 0);
|
||||
@ -190,69 +142,57 @@ static void HandleInputChooseAction(void)
|
||||
BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_SAFARI_RUN, 0);
|
||||
break;
|
||||
}
|
||||
SafariBufferExecCompleted();
|
||||
SafariBufferExecCompleted(battler);
|
||||
}
|
||||
else if (JOY_NEW(DPAD_LEFT))
|
||||
{
|
||||
if (gActionSelectionCursor[gActiveBattler] & 1)
|
||||
if (gActionSelectionCursor[battler] & 1)
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
ActionSelectionDestroyCursorAt(gActionSelectionCursor[gActiveBattler]);
|
||||
gActionSelectionCursor[gActiveBattler] ^= 1;
|
||||
ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0);
|
||||
ActionSelectionDestroyCursorAt(gActionSelectionCursor[battler]);
|
||||
gActionSelectionCursor[battler] ^= 1;
|
||||
ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0);
|
||||
}
|
||||
}
|
||||
else if (JOY_NEW(DPAD_RIGHT))
|
||||
{
|
||||
if (!(gActionSelectionCursor[gActiveBattler] & 1))
|
||||
if (!(gActionSelectionCursor[battler] & 1))
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
ActionSelectionDestroyCursorAt(gActionSelectionCursor[gActiveBattler]);
|
||||
gActionSelectionCursor[gActiveBattler] ^= 1;
|
||||
ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0);
|
||||
ActionSelectionDestroyCursorAt(gActionSelectionCursor[battler]);
|
||||
gActionSelectionCursor[battler] ^= 1;
|
||||
ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0);
|
||||
}
|
||||
}
|
||||
else if (JOY_NEW(DPAD_UP))
|
||||
{
|
||||
if (gActionSelectionCursor[gActiveBattler] & 2)
|
||||
if (gActionSelectionCursor[battler] & 2)
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
ActionSelectionDestroyCursorAt(gActionSelectionCursor[gActiveBattler]);
|
||||
gActionSelectionCursor[gActiveBattler] ^= 2;
|
||||
ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0);
|
||||
ActionSelectionDestroyCursorAt(gActionSelectionCursor[battler]);
|
||||
gActionSelectionCursor[battler] ^= 2;
|
||||
ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0);
|
||||
}
|
||||
}
|
||||
else if (JOY_NEW(DPAD_DOWN))
|
||||
{
|
||||
if (!(gActionSelectionCursor[gActiveBattler] & 2))
|
||||
if (!(gActionSelectionCursor[battler] & 2))
|
||||
{
|
||||
PlaySE(SE_SELECT);
|
||||
ActionSelectionDestroyCursorAt(gActionSelectionCursor[gActiveBattler]);
|
||||
gActionSelectionCursor[gActiveBattler] ^= 2;
|
||||
ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0);
|
||||
ActionSelectionDestroyCursorAt(gActionSelectionCursor[battler]);
|
||||
gActionSelectionCursor[battler] ^= 2;
|
||||
ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void CompleteOnBattlerSpriteCallbackDummy(void)
|
||||
static void Controller_WaitForHealthbox(u32 battler)
|
||||
{
|
||||
if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy)
|
||||
SafariBufferExecCompleted();
|
||||
if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy)
|
||||
SafariBufferExecCompleted(battler);
|
||||
}
|
||||
|
||||
static void CompleteOnInactiveTextPrinter(void)
|
||||
{
|
||||
if (!IsTextPrinterActive(B_WIN_MSG))
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void CompleteOnHealthboxSpriteCallbackDummy(void)
|
||||
{
|
||||
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy)
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariSetBattleEndCallbacks(void)
|
||||
static void SafariSetBattleEndCallbacks(u32 battler)
|
||||
{
|
||||
if (!gPaletteFade.active)
|
||||
{
|
||||
@ -262,437 +202,141 @@ static void SafariSetBattleEndCallbacks(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void CompleteOnSpecialAnimDone(void)
|
||||
{
|
||||
if (!gDoingBattleAnim || !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive)
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariOpenPokeblockCase(void)
|
||||
static void SafariOpenPokeblockCase(u32 battler)
|
||||
{
|
||||
if (!gPaletteFade.active)
|
||||
{
|
||||
gBattlerControllerFuncs[gActiveBattler] = CompleteWhenChosePokeblock;
|
||||
gBattlerControllerFuncs[battler] = CompleteWhenChosePokeblock;
|
||||
FreeAllWindowBuffers();
|
||||
OpenPokeblockCaseInBattle();
|
||||
}
|
||||
}
|
||||
|
||||
static void CompleteWhenChosePokeblock(void)
|
||||
static void CompleteWhenChosePokeblock(u32 battler)
|
||||
{
|
||||
if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active)
|
||||
{
|
||||
BtlController_EmitOneReturnValue(BUFFER_B, gSpecialVar_ItemId);
|
||||
SafariBufferExecCompleted();
|
||||
SafariBufferExecCompleted(battler);
|
||||
}
|
||||
}
|
||||
|
||||
static void CompleteOnFinishedBattleAnimation(void)
|
||||
static void SafariBufferExecCompleted(u32 battler)
|
||||
{
|
||||
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animFromTableActive)
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariBufferExecCompleted(void)
|
||||
{
|
||||
gBattlerControllerFuncs[gActiveBattler] = SafariBufferRunCommand;
|
||||
gBattlerControllerFuncs[battler] = SafariBufferRunCommand;
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
|
||||
{
|
||||
u8 playerId = GetMultiplayerId();
|
||||
|
||||
PrepareBufferDataTransferLink(2, 4, &playerId);
|
||||
gBattleResources->bufferA[gActiveBattler][0] = CONTROLLER_TERMINATOR_NOP;
|
||||
gBattleResources->bufferA[battler][0] = CONTROLLER_TERMINATOR_NOP;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleControllerExecFlags &= ~gBitTable[gActiveBattler];
|
||||
gBattleControllerExecFlags &= ~gBitTable[battler];
|
||||
}
|
||||
}
|
||||
|
||||
static void CompleteOnFinishedStatusAnimation(void)
|
||||
static void SafariHandleDrawTrainerPic(u32 battler)
|
||||
{
|
||||
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].statusAnimActive)
|
||||
SafariBufferExecCompleted();
|
||||
u32 trainerPicId = gSaveBlock2Ptr->playerGender + TRAINER_BACK_PIC_BRENDAN;
|
||||
|
||||
BtlController_HandleDrawTrainerPic(battler, trainerPicId, FALSE,
|
||||
80, 80 + 4 * (8 - gTrainerBackPicCoords[trainerPicId].size),
|
||||
30);
|
||||
}
|
||||
|
||||
static void SafariHandleGetMonData(void)
|
||||
static void SafariHandleSuccessBallThrowAnim(u32 battler)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
BtlController_HandleSuccessBallThrowAnim(battler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW_WITH_TRAINER, FALSE);
|
||||
}
|
||||
|
||||
static void SafariHandleGetRawMonData(void)
|
||||
static void SafariHandleBallThrowAnim(u32 battler)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
BtlController_HandleBallThrowAnim(battler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW_WITH_TRAINER, FALSE);
|
||||
}
|
||||
|
||||
static void SafariHandleSetMonData(void)
|
||||
static void SafariHandlePrintString(u32 battler)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
BtlController_HandlePrintString(battler, FALSE, FALSE);
|
||||
}
|
||||
|
||||
static void SafariHandleSetRawMonData(void)
|
||||
static void SafariHandlePrintSelectionString(u32 battler)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleLoadMonSprite(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleSwitchInAnim(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleReturnMonToBall(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
#define sSpeedX data[0]
|
||||
|
||||
static void SafariHandleDrawTrainerPic(void)
|
||||
{
|
||||
DecompressTrainerBackPic(gSaveBlock2Ptr->playerGender, gActiveBattler);
|
||||
SetMultiuseSpriteTemplateToTrainerBack(gSaveBlock2Ptr->playerGender, GetBattlerPosition(gActiveBattler));
|
||||
gBattlerSpriteIds[gActiveBattler] = CreateSprite(
|
||||
&gMultiuseSpriteTemplate,
|
||||
80,
|
||||
(8 - gTrainerBackPicCoords[gSaveBlock2Ptr->playerGender].size) * 4 + 80,
|
||||
30);
|
||||
gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler;
|
||||
gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = DISPLAY_WIDTH;
|
||||
gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedX = -2;
|
||||
gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_TrainerSlideIn;
|
||||
gBattlerControllerFuncs[gActiveBattler] = CompleteOnBattlerSpriteCallbackDummy;
|
||||
}
|
||||
|
||||
#undef sSpeedX
|
||||
|
||||
static void SafariHandleTrainerSlide(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleTrainerSlideBack(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleFaintAnimation(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandlePaletteFade(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleSuccessBallThrowAnim(void)
|
||||
{
|
||||
gBattleSpritesDataPtr->animationData->ballThrowCaseId = BALL_3_SHAKES_SUCCESS;
|
||||
gDoingBattleAnim = TRUE;
|
||||
InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW_WITH_TRAINER);
|
||||
gBattlerControllerFuncs[gActiveBattler] = CompleteOnSpecialAnimDone;
|
||||
}
|
||||
|
||||
static void SafariHandleBallThrowAnim(void)
|
||||
{
|
||||
u8 ballThrowCaseId = gBattleResources->bufferA[gActiveBattler][1];
|
||||
|
||||
gBattleSpritesDataPtr->animationData->ballThrowCaseId = ballThrowCaseId;
|
||||
gDoingBattleAnim = TRUE;
|
||||
InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW_WITH_TRAINER);
|
||||
gBattlerControllerFuncs[gActiveBattler] = CompleteOnSpecialAnimDone;
|
||||
}
|
||||
|
||||
static void SafariHandlePause(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleMoveAnimation(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandlePrintString(void)
|
||||
{
|
||||
u16 *stringId;
|
||||
|
||||
gBattle_BG0_X = 0;
|
||||
gBattle_BG0_Y = 0;
|
||||
stringId = (u16 *)(&gBattleResources->bufferA[gActiveBattler][2]);
|
||||
BufferStringBattle(*stringId);
|
||||
BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MSG);
|
||||
gBattlerControllerFuncs[gActiveBattler] = CompleteOnInactiveTextPrinter;
|
||||
}
|
||||
|
||||
static void SafariHandlePrintSelectionString(void)
|
||||
{
|
||||
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
|
||||
SafariHandlePrintString();
|
||||
if (GetBattlerSide(battler) == B_SIDE_PLAYER)
|
||||
SafariHandlePrintString(battler);
|
||||
else
|
||||
SafariBufferExecCompleted();
|
||||
SafariBufferExecCompleted(battler);
|
||||
}
|
||||
|
||||
static void HandleChooseActionAfterDma3(void)
|
||||
static void HandleChooseActionAfterDma3(u32 battler)
|
||||
{
|
||||
if (!IsDma3ManagerBusyWithBgCopy())
|
||||
{
|
||||
gBattle_BG0_X = 0;
|
||||
gBattle_BG0_Y = DISPLAY_HEIGHT;
|
||||
gBattlerControllerFuncs[gActiveBattler] = HandleInputChooseAction;
|
||||
gBattlerControllerFuncs[battler] = HandleInputChooseAction;
|
||||
}
|
||||
}
|
||||
|
||||
static void SafariHandleChooseAction(void)
|
||||
static void SafariHandleChooseAction(u32 battler)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
gBattlerControllerFuncs[gActiveBattler] = HandleChooseActionAfterDma3;
|
||||
gBattlerControllerFuncs[battler] = HandleChooseActionAfterDma3;
|
||||
BattlePutTextOnWindow(gText_SafariZoneMenu, B_WIN_ACTION_MENU);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
ActionSelectionDestroyCursorAt(i);
|
||||
|
||||
ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0);
|
||||
ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0);
|
||||
BattleStringExpandPlaceholdersToDisplayedString(gText_WhatWillPkmnDo2);
|
||||
BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_ACTION_PROMPT);
|
||||
}
|
||||
|
||||
static void SafariHandleYesNoBox(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleChooseMove(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleChooseItem(void)
|
||||
static void SafariHandleChooseItem(u32 battler)
|
||||
{
|
||||
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK);
|
||||
gBattlerControllerFuncs[gActiveBattler] = SafariOpenPokeblockCase;
|
||||
gBattlerInMenuId = gActiveBattler;
|
||||
gBattlerControllerFuncs[battler] = SafariOpenPokeblockCase;
|
||||
gBattlerInMenuId = battler;
|
||||
}
|
||||
|
||||
static void SafariHandleChoosePokemon(void)
|
||||
static void SafariHandleStatusIconUpdate(u32 battler)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gPlayerParty[gBattlerPartyIndexes[battler]], HEALTHBOX_SAFARI_BALLS_TEXT);
|
||||
SafariBufferExecCompleted(battler);
|
||||
}
|
||||
|
||||
static void SafariHandleCmd23(void)
|
||||
// All of the other controllers(except Wally's) use CRY_MODE_FAINT.
|
||||
// Player is not a pokemon, so it can't really faint in the Safari anyway.
|
||||
static void SafariHandleFaintingCry(u32 battler)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleHealthBarUpdate(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleExpUpdate(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleStatusIconUpdate(void)
|
||||
{
|
||||
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_SAFARI_BALLS_TEXT);
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleStatusAnimation(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleStatusXor(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleDataTransfer(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleDMA3Transfer(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandlePlayBGM(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleCmd32(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleTwoReturnValues(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleChosenMonReturnValue(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleOneReturnValue(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleOneReturnValue_Duplicate(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleClearUnkVar(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleSetUnkVar(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleClearUnkFlag(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleToggleUnkFlag(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleHitAnimation(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleCantSwitch(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandlePlaySE(void)
|
||||
{
|
||||
s8 pan;
|
||||
|
||||
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
|
||||
pan = SOUND_PAN_ATTACKER;
|
||||
else
|
||||
pan = SOUND_PAN_TARGET;
|
||||
|
||||
PlaySE12WithPanning(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8), pan);
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandlePlayFanfareOrBGM(void)
|
||||
{
|
||||
if (gBattleResources->bufferA[gActiveBattler][3])
|
||||
{
|
||||
BattleStopLowHpSound();
|
||||
PlayBGM(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayFanfare(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8));
|
||||
}
|
||||
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleFaintingCry(void)
|
||||
{
|
||||
u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES);
|
||||
u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES);
|
||||
|
||||
PlayCry_Normal(species, 25);
|
||||
SafariBufferExecCompleted();
|
||||
SafariBufferExecCompleted(battler);
|
||||
SafariBufferExecCompleted(battler);
|
||||
}
|
||||
|
||||
static void SafariHandleIntroSlide(void)
|
||||
static void SafariHandleIntroTrainerBallThrow(u32 battler)
|
||||
{
|
||||
HandleIntroSlide(gBattleResources->bufferA[gActiveBattler][1]);
|
||||
gIntroSlideFlags |= 1;
|
||||
SafariBufferExecCompleted();
|
||||
UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gPlayerParty[gBattlerPartyIndexes[battler]], HEALTHBOX_SAFARI_ALL_TEXT);
|
||||
StartHealthboxSlideIn(battler);
|
||||
SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]);
|
||||
gBattlerControllerFuncs[battler] = Controller_WaitForHealthbox;
|
||||
}
|
||||
|
||||
static void SafariHandleIntroTrainerBallThrow(void)
|
||||
static void SafariHandleBattleAnimation(u32 battler)
|
||||
{
|
||||
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_SAFARI_ALL_TEXT);
|
||||
StartHealthboxSlideIn(gActiveBattler);
|
||||
SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]);
|
||||
gBattlerControllerFuncs[gActiveBattler] = CompleteOnHealthboxSpriteCallbackDummy;
|
||||
BtlController_HandleBattleAnimation(battler, TRUE, FALSE);
|
||||
}
|
||||
|
||||
static void SafariHandleDrawPartyStatusSummary(void)
|
||||
static void SafariHandleEndLinkBattle(u32 battler)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleHidePartyStatusSummary(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleEndBounceEffect(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleSpriteInvisibility(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleBattleAnimation(void)
|
||||
{
|
||||
u8 animationId = gBattleResources->bufferA[gActiveBattler][1];
|
||||
u16 argument = gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8);
|
||||
|
||||
if (TryHandleLaunchBattleTableAnimation(gActiveBattler, gActiveBattler, gActiveBattler, animationId, argument))
|
||||
SafariBufferExecCompleted();
|
||||
else
|
||||
gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedBattleAnimation;
|
||||
}
|
||||
|
||||
static void SafariHandleLinkStandbyMsg(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleResetActionMoveSelection(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariHandleEndLinkBattle(void)
|
||||
{
|
||||
gBattleOutcome = gBattleResources->bufferA[gActiveBattler][1];
|
||||
gBattleOutcome = gBattleResources->bufferA[battler][1];
|
||||
FadeOutMapMusic(5);
|
||||
BeginFastPaletteFade(3);
|
||||
SafariBufferExecCompleted();
|
||||
SafariBufferExecCompleted(battler);
|
||||
if ((gBattleTypeFlags & BATTLE_TYPE_LINK) && !(gBattleTypeFlags & BATTLE_TYPE_IS_MASTER))
|
||||
gBattlerControllerFuncs[gActiveBattler] = SafariSetBattleEndCallbacks;
|
||||
}
|
||||
|
||||
static void SafariHandleBattleDebug(void)
|
||||
{
|
||||
SafariBufferExecCompleted();
|
||||
}
|
||||
|
||||
static void SafariCmdEnd(void)
|
||||
{
|
||||
gBattlerControllerFuncs[battler] = SafariSetBattleEndCallbacks;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -157,8 +157,6 @@ static void BufferLastDomeWinnerName(void);
|
||||
static void InitRandomTourneyTreeResults(void);
|
||||
static void InitDomeTrainers(void);
|
||||
|
||||
EWRAM_DATA u32 gPlayerPartyLostHP = 0; // never read
|
||||
static EWRAM_DATA u32 sPlayerPartyMaxHP = 0; // never read
|
||||
static EWRAM_DATA struct TourneyTreeInfoCard *sInfoCard = {0};
|
||||
static EWRAM_DATA u8 *sTilemapBuffer = NULL;
|
||||
|
||||
@ -2544,9 +2542,6 @@ static void BufferDomeOpponentName(void)
|
||||
|
||||
static void InitDomeOpponentParty(void)
|
||||
{
|
||||
gPlayerPartyLostHP = 0;
|
||||
sPlayerPartyMaxHP = GetMonData(&gPlayerParty[0], MON_DATA_MAX_HP, NULL);
|
||||
sPlayerPartyMaxHP += GetMonData(&gPlayerParty[1], MON_DATA_MAX_HP, NULL);
|
||||
CalculatePlayerPartyCount();
|
||||
CreateDomeOpponentMons(TrainerIdToTournamentId(gTrainerBattleOpponent_A));
|
||||
}
|
||||
|
@ -528,7 +528,7 @@ bool8 IsBattleSEPlaying(u8 battlerId)
|
||||
if (IsSEPlaying())
|
||||
{
|
||||
gBattleSpritesDataPtr->healthBoxesData[battlerId].soundTimer++;
|
||||
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].soundTimer < 30)
|
||||
if (gBattleSpritesDataPtr->healthBoxesData[battlerId].soundTimer < 30)
|
||||
return TRUE;
|
||||
|
||||
m4aMPlayStop(&gMPlayInfo_SE1);
|
||||
@ -544,7 +544,7 @@ bool8 IsBattleSEPlaying(u8 battlerId)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battlerId, bool32 opponent)
|
||||
void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battlerId)
|
||||
{
|
||||
u32 monsPersonality, currentPersonality, otId, currentOtId, species, paletteOffset, position;
|
||||
const void *lzPaletteData;
|
||||
@ -577,7 +577,7 @@ static void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battlerId, bool32 op
|
||||
}
|
||||
|
||||
position = GetBattlerPosition(battlerId);
|
||||
if (opponent)
|
||||
if (GetBattlerSide(battlerId) == B_SIDE_OPPONENT)
|
||||
{
|
||||
HandleLoadSpecialPokePic(TRUE,
|
||||
gMonSpritesGfxPtr->sprites.ptr[position],
|
||||
@ -609,16 +609,6 @@ static void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battlerId, bool32 op
|
||||
}
|
||||
}
|
||||
|
||||
void BattleLoadOpponentMonSpriteGfx(struct Pokemon *mon, u8 battlerId)
|
||||
{
|
||||
BattleLoadMonSpriteGfx(mon, battlerId, TRUE);
|
||||
}
|
||||
|
||||
void BattleLoadPlayerMonSpriteGfx(struct Pokemon *mon, u8 battlerId)
|
||||
{
|
||||
BattleLoadMonSpriteGfx(mon, battlerId, FALSE);
|
||||
}
|
||||
|
||||
void BattleGfxSfxDummy2(u16 species)
|
||||
{
|
||||
}
|
||||
@ -642,10 +632,6 @@ void DecompressTrainerBackPic(u16 backPicId, u8 battlerId)
|
||||
OBJ_PLTT_ID(battlerId), PLTT_SIZE_4BPP);
|
||||
}
|
||||
|
||||
void BattleGfxSfxDummy3(u8 gender)
|
||||
{
|
||||
}
|
||||
|
||||
void FreeTrainerFrontPicPalette(u16 frontPicId)
|
||||
{
|
||||
FreeSpritePaletteByTag(gTrainerFrontPicPaletteTable[frontPicId].tag);
|
||||
@ -968,12 +954,7 @@ void BattleLoadSubstituteOrMonSpriteGfx(u8 battlerId, bool8 loadMonSprite)
|
||||
else
|
||||
{
|
||||
if (!IsContest())
|
||||
{
|
||||
if (GetBattlerSide(battlerId) != B_SIDE_PLAYER)
|
||||
BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[battlerId]], battlerId);
|
||||
else
|
||||
BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[battlerId]], battlerId);
|
||||
}
|
||||
BattleLoadMonSpriteGfx(&GetBattlerParty(battlerId)[gBattlerPartyIndexes[battlerId]], battlerId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -251,11 +251,9 @@ void (*gPreBattleCallback1)(void);
|
||||
void (*gBattleMainFunc)(void);
|
||||
struct BattleResults gBattleResults;
|
||||
u8 gLeveledUpInBattle;
|
||||
void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(void);
|
||||
u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT];
|
||||
u8 gMultiUsePlayerCursor;
|
||||
u8 gNumberOfMovesToChoose;
|
||||
u8 gBattleControllerData[MAX_BATTLERS_COUNT]; // Used by the battle controllers to store misc sprite/task IDs for each battler
|
||||
|
||||
static const struct ScanlineEffectParams sIntroScanlineParams16Bit =
|
||||
{
|
||||
@ -567,8 +565,8 @@ static void CB2_InitBattleInternal(void)
|
||||
gBattle_BG3_X = 0;
|
||||
gBattle_BG3_Y = 0;
|
||||
|
||||
#if DEBUG_OVERWORLD_MENU == FALSE
|
||||
|
||||
#if DEBUG_OVERWORLD_MENU == FALSE
|
||||
|
||||
gBattleTerrain = BattleSetup_GetTerrainId();
|
||||
#else
|
||||
if (!gIsDebugBattle)
|
||||
@ -596,7 +594,7 @@ static void CB2_InitBattleInternal(void)
|
||||
else
|
||||
SetMainCallback2(CB2_HandleStartBattle);
|
||||
|
||||
#if DEBUG_OVERWORLD_MENU == FALSE
|
||||
#if DEBUG_OVERWORLD_MENU == FALSE
|
||||
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED)))
|
||||
{
|
||||
CreateNPCTrainerParty(&gEnemyParty[0], gTrainerBattleOpponent_A, TRUE);
|
||||
@ -2743,8 +2741,6 @@ void SpriteCB_FaintOpponentMon(struct Sprite *sprite)
|
||||
else
|
||||
species = sprite->sSpeciesId;
|
||||
|
||||
GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_PERSONALITY); // Unused return value.
|
||||
|
||||
if (species == SPECIES_UNOWN)
|
||||
{
|
||||
species = GetUnownSpeciesId(personality);
|
||||
@ -3006,7 +3002,7 @@ static void BattleMainCB1(void)
|
||||
gBattleMainFunc();
|
||||
|
||||
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
|
||||
gBattlerControllerFuncs[gActiveBattler]();
|
||||
gBattlerControllerFuncs[gActiveBattler](gActiveBattler);
|
||||
}
|
||||
|
||||
static void BattleStartClearSetData(void)
|
||||
|
@ -9974,13 +9974,13 @@ static void Cmd_various(void)
|
||||
if (IsBattlerAlive(gActiveBattler))
|
||||
{
|
||||
SetBattlerShadowSpriteCallback(gActiveBattler, gBattleMons[gActiveBattler].species);
|
||||
BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler);
|
||||
BattleLoadMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler);
|
||||
}
|
||||
i = BATTLE_PARTNER(gActiveBattler);
|
||||
if (IsBattlerAlive(i))
|
||||
{
|
||||
SetBattlerShadowSpriteCallback(i, gBattleMons[i].species);
|
||||
BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[i]], i);
|
||||
BattleLoadMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[i]], i);
|
||||
}
|
||||
}
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
|
@ -1884,7 +1884,7 @@ u8 CheckMoveLimitations(u8 battlerId, u8 unusableMoves, u16 check)
|
||||
else if (check & MOVE_LIMITATION_THROAT_CHOP && gDisableStructs[battlerId].throatChopTimer && gBattleMoves[gBattleMons[battlerId].moves[i]].soundMove)
|
||||
unusableMoves |= gBitTable[i];
|
||||
// Stuff Cheeks
|
||||
else if (check & MOVE_LIMITATION_STUFF_CHEEKS && gBattleMons[battlerId].moves[i] == MOVE_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[gActiveBattler].item) != POCKET_BERRIES)
|
||||
else if (check & MOVE_LIMITATION_STUFF_CHEEKS && gBattleMons[battlerId].moves[i] == MOVE_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[battlerId].item) != POCKET_BERRIES)
|
||||
unusableMoves |= gBitTable[i];
|
||||
// Gorilla Tactics
|
||||
else if (check & MOVE_LIMITATION_CHOICE_ITEM && GetBattlerAbility(battlerId) == ABILITY_GORILLA_TACTICS && *choicedMove != MOVE_NONE && *choicedMove != MOVE_UNAVAILABLE && *choicedMove != gBattleMons[battlerId].moves[i])
|
||||
@ -4879,7 +4879,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
&& gBattleResults.catchAttempts[gLastUsedBall - ITEM_ULTRA_BALL] >= 1
|
||||
&& !gHasFetchedBall)
|
||||
{
|
||||
gBattleScripting.battler = battler;
|
||||
gBattleScripting.battler = gActiveBattler = battler;
|
||||
BtlController_EmitSetMonData(BUFFER_A, REQUEST_HELDITEM_BATTLE, 0, 2, &gLastUsedBall);
|
||||
MarkBattlerForControllerExec(battler);
|
||||
gHasFetchedBall = TRUE;
|
||||
@ -10823,7 +10823,7 @@ void TrySaveExchangedItem(u8 battlerId, u16 stolenItem)
|
||||
bool32 IsBattlerAffectedByHazards(u8 battlerId, bool32 toxicSpikes)
|
||||
{
|
||||
bool32 ret = TRUE;
|
||||
u32 holdEffect = GetBattlerHoldEffect(gActiveBattler, TRUE);
|
||||
u32 holdEffect = GetBattlerHoldEffect(battlerId, TRUE);
|
||||
if (toxicSpikes && holdEffect == HOLD_EFFECT_HEAVY_DUTY_BOOTS && !IS_BATTLER_OF_TYPE(battlerId, TYPE_POISON))
|
||||
{
|
||||
ret = FALSE;
|
||||
|
@ -187,7 +187,7 @@ static bool8 LoadBattlerSpriteGfx(u8 battler)
|
||||
if (GetBattlerSide(battler) != B_SIDE_PLAYER)
|
||||
{
|
||||
if (!gBattleSpritesDataPtr->battlerData[battler].behindSubstitute)
|
||||
BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[battler]], battler);
|
||||
BattleLoadMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[battler]], battler);
|
||||
else
|
||||
BattleLoadSubstituteOrMonSpriteGfx(battler, FALSE);
|
||||
}
|
||||
@ -196,7 +196,7 @@ static bool8 LoadBattlerSpriteGfx(u8 battler)
|
||||
else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL && battler == B_POSITION_PLAYER_LEFT) // Should be checking position, not battler.
|
||||
DecompressTrainerBackPic(TRAINER_BACK_PIC_WALLY, battler);
|
||||
else if (!gBattleSpritesDataPtr->battlerData[battler].behindSubstitute)
|
||||
BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[battler]], battler);
|
||||
BattleLoadMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[battler]], battler);
|
||||
else
|
||||
BattleLoadSubstituteOrMonSpriteGfx(battler, FALSE);
|
||||
|
||||
|
@ -37,6 +37,7 @@ gReservedSpritePaletteCount:
|
||||
.include "link_rfu_2.o"
|
||||
.include "rtc.o"
|
||||
.include "battle_main.o"
|
||||
.include "battle_controllers.o"
|
||||
.include "random.o"
|
||||
.include "load_save.o"
|
||||
.include "berry_blender.o"
|
||||
|
Loading…
Reference in New Issue
Block a user