Merge pull request #49 from cawtds/battle-controller-sync

update battle controllers
This commit is contained in:
cawtds
2025-01-07 23:29:49 +01:00
committed by GitHub
67 changed files with 2470 additions and 787 deletions

View File

@@ -45,6 +45,7 @@ SUPER_ER = 2C
LV = 34
'=' = 35
';' = 36
V_D_ARROW = 38
'¿' = 51
'¡' = 52
PK = 53

View File

@@ -0,0 +1,15 @@
JASC-PAL
0100
12
120 152 128
49 49 49
255 255 255
164 82 57
172 189 32
184 160 90
213 180 90
98 98 180
180 90 164
172 164 148
172 172 197
152 172 246

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 B

View File

@@ -0,0 +1,15 @@
JASC-PAL
0100
12
120 152 128
49 49 49
255 255 255
240 82 48
120 200 80
248 197 49
80 120 136
123 98 230
248 115 164
57 156 255
90 205 230
246 180 246

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

BIN
graphics/types/bug.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 B

BIN
graphics/types/dark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

BIN
graphics/types/dragon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

BIN
graphics/types/electric.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 B

BIN
graphics/types/fairy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 B

BIN
graphics/types/fight.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 B

BIN
graphics/types/fire.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 B

BIN
graphics/types/flying.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 B

BIN
graphics/types/ghost.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 B

BIN
graphics/types/grass.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

BIN
graphics/types/ground.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 B

BIN
graphics/types/ice.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

View File

@@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
255 213 49
246 131 49
197 49 41
230 197 106
189 164 57
139 106 49
255 255 123
172 172 123
222 222 197
115 90 74
74 65 57
189 189 213
0 0 0
131 123 115
255 255 255

View File

@@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
205 197 255
172 148 246
115 90 156
106 148 246
156 222 222
213 255 238
74 57 82
255 90 139
255 197 180
148 98 98
164 65 164
222 131 189
148 148 164
131 123 115
255 255 255

View File

@@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
197 255 98
123 205 82
90 131 65
115 57 255
74 57 148
189 164 255
172 189 32
222 230 49
123 148 16
106 164 148
115 205 180
32 106 98
0 0 0
131 123 115
255 255 255

BIN
graphics/types/mystery.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

BIN
graphics/types/none.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

BIN
graphics/types/normal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

BIN
graphics/types/poison.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

BIN
graphics/types/psychic.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 B

BIN
graphics/types/rock.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

BIN
graphics/types/steel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

BIN
graphics/types/stellar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
graphics/types/water.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

View File

@@ -158,7 +158,7 @@ enum
CONTROLLER_PRINTSTRING,
CONTROLLER_PRINTSTRINGPLAYERONLY,
CONTROLLER_CHOOSEACTION,
CONTROLLER_UNKNOWNYESNOBOX,
CONTROLLER_YESNOBOX,
CONTROLLER_CHOOSEMOVE,
CONTROLLER_OPENBAG,
CONTROLLER_CHOOSEPOKEMON,
@@ -307,17 +307,23 @@ void SetBattleEndCallbacks(u32 battler);
void SetControllerToPlayer(u32 battler);
void PlayerHandleBallThrowAnim(u32 battler);
void SpriteCB_FreePlayerSpriteLoadMonSpriteOld(struct Sprite *sprite);
void SetCB2ToReshowScreenAfterMenu(void);
void SetCB2ToReshowScreenAfterMenu2(void);
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(u32 battler);
void MoveSelectionCreateCursorAt(u8 cursorPos, u8 arg1);
void MoveSelectionDestroyCursorAt(u8 cursorPos);
void HandleInputChooseMove(u32 battler);
u32 LinkPlayerGetTrainerPicId(u32 multiplayerId);
void PlayerHandleExpUpdate(u32 battler);
void PlayerHandleChooseMove(u32 battler);
void HandleInputChooseMove(u32 battler);
void HandleInputChooseTarget(u32 battler);
void HandleInputShowEntireFieldTargets(u32 battler);
void HandleInputShowTargets(u32 battler);
void HandleMoveSwitching(u32 battler);
void HandleChooseMoveAfterDma3(u32 battler);
// recorded player controller
void SetControllerToRecordedPlayer(u32 battler);

View File

@@ -5,6 +5,7 @@ void AllocateBattleSpritesData(void);
void FreeBattleSpritesData(void);
void SpriteCB_WaitForBattlerBallReleaseAnim(struct Sprite *sprite);
void SpriteCB_TrainerSlideIn(struct Sprite *sprite);
void SpriteCB_TrainerSpawn(struct Sprite *sprite);
void InitAndLaunchChosenStatusAnimation(u32 battler, bool8 isStatus2, u32 status);
bool8 TryHandleLaunchBattleTableAnimation(u8 activeBattler, u8 atkBattler, u8 defBattler, u8 tableId, u16 argument);
void InitAndLaunchSpecialAnimation(u8 activeBattler, u8 atkBattler, u8 defBattler, u8 tableId);

View File

@@ -96,6 +96,7 @@ s8 GetChosenMovePriority(u32 battlerId);
u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, u32 holdEffect);
u32 GetBattlerTotalSpeedStat(u32 battler);
void SpecialStatusesClear(void);
u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, u8 *ateBoost);
s32 GetWhichBattlerFasterArgs(u32 battler1, u32 battler2, bool32 ignoreChosenMoves, u32 ability1, u32 ability2,
u32 holdEffectBattler1, u32 holdEffectBattler2, u32 speedBattler1, u32 speedBattler2, s32 priority1, s32 priority2);
s32 GetWhichBattlerFasterOrTies(u32 battler1, u32 battler2, bool32 ignoreChosenMoves);

View File

@@ -256,7 +256,7 @@ enum
TRAINER_SLIDE_DYNAMAX,
};
void BufferStringBattle(u32 battler, u16 stringID);
void BufferStringBattle(u16 stringID, u32 battler);
u32 BattleStringExpandPlaceholdersToDisplayedString(const u8 *src);
u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize);
void BattleHandleAddTextPrinter(const u8 *text, u8 arg1);

View File

@@ -6523,4 +6523,9 @@ extern const u32 gBattleAnimBgImage_Swamp[];
extern const u32 gBattleAnimBGPalette_Swamp[];
extern const u32 gBattleAnimBgTilemap_Swamp[];
extern const u32 gBattleIcons_Gfx1[];
extern const u32 gBattleIcons_Gfx2[];
extern const u32 gBattleIcons_Pal1[];
extern const u32 gBattleIcons_Pal2[];
#endif //GUARD_GRAPHICS_H

View File

@@ -18,7 +18,9 @@ struct Item
u8 pluralName[ITEM_NAME_PLURAL_LENGTH];
u8 holdEffect;
u8 holdEffectParam;
u8 importance;
u8 importance:2;
u8 notConsumed:1;
u8 padding:5;
u8 pocket;
u8 type;
u8 battleUsage;
@@ -57,6 +59,7 @@ u8 ItemId_GetHoldEffectParam(u16 itemId);
const u8 *ItemId_GetDescription(u16 itemId);
bool32 ItemId_CopyDescription(u8 *a, u32 itemId, u32 c);
u8 ItemId_GetImportance(u16 itemId);
u8 ItemId_GetConsumability(u16 itemId);
u8 ItemId_GetUnknownValue(u16 itemId);
u8 ItemId_GetPocket(u16 itemId);
u8 ItemId_GetType(u16 itemId);

View File

@@ -24,7 +24,7 @@ extern struct BagStruct gBagMenuState;
extern u16 gSpecialVar_ItemId;
// Exported ROM declarations
void CB2_SetUpReshowBattleScreenAfterMenu(void);
void SetBagOpenFalse(void);
void ResetBagCursorPositions(void);
void InitPokedudeBag(u8);
void CB2_BagMenuFromStartMenu(void);

33
include/line_break.h Normal file
View File

@@ -0,0 +1,33 @@
#ifndef GUARD_LINE_BREAK_H
#define GUARD_LINE_BREAK_H
#define BADNESS_UNFILLED 1 // Badness added per pixel diff from max width
#define BADNESS_JAGGED 1 // Badness added per pixel diff from longest, squared per line
#define BADNESS_RUNT 100 // Badness added if there's a runt
#define BADNESS_OVERFLOW 100 // Badness added per pixel overflow, squared per line (not used)
#define BADNESS_WIDE_SPACE 1 // Badness added per extra pixel width (not used)
#define MAX_SPACE_WIDTH 5
struct StringWord {
u32 startIndex:16;
u32 length:8;
u32 width:8;
};
struct StringLine {
struct StringWord *words;
u16 numWords;
u8 spaceWidth;
u8 extraSpaceWidth;
};
void StripLineBreaks(u8 *src);
void BreakStringAutomatic(u8 *src, u32 maxWidth, u32 screenLines, u8 fontId);
void BreakSubStringAutomatic(u8 *src, u32 maxWidth, u32 screenLines, u8 fontId);
bool32 IsWordSplittingChar(const u8 *src, u32 index);
u32 GetStringBadness(struct StringLine *stringLines, u32 numLines, u32 maxWidth);
void BuildNewString(struct StringLine *stringLines, u32 numLines, u32 maxLines, u8 *str);
bool32 StringHasManualBreaks(u8 *src);
#endif // GUARD_LINE_BREAK_H

View File

@@ -78,7 +78,7 @@ void ClearSelectedPartyOrder(void);
void ChooseMonForTradingBoard(u8 menuType, MainCallback callback);
void ChooseMonForMoveTutor(void);
void ChooseMonForWirelessMinigame(void);
void OpenPartyMenuInTutorialBattle(u8 partyAction);
void OpenPartyMenuInBattle(u8 partyAction);
void Pokedude_OpenPartyMenuInBattle(void);
void Pokedude_ChooseMonForInBattleItem(void);
void EnterPartyFromItemMenuInBattle(void);

View File

@@ -782,5 +782,6 @@ u16 HoennNumToSpecies(u16 hoennNum);
u8 CopyMonToPC(struct Pokemon *mon);
void UpdateDaysPassedSinceFormChange(u16 days);
void TrySetDayLimitToFormChange(struct Pokemon *mon);
u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler);
#endif // GUARD_POKEMON_H

18
include/type_icons.h Normal file
View File

@@ -0,0 +1,18 @@
#ifndef GUARD_TYPE_ICONS_H
#define GUARD_TYPE_ICONS_H
void LoadTypeIcons(u32);
#define TYPE_ICON_TAG 0x2720
#define TYPE_ICON_TAG_2 0x2721
#define NUM_FRAMES_HIDE_TYPE_ICON 10
#define tMonPosition data[0]
#define tBattlerId data[1]
#define tHideIconTimer data[2]
#define tVerticalPosition data[3]
#define TYPE_ICON_1_FRAME(monType) ((monType - 1) * 2)
#define TYPE_ICON_2_FRAME(monType) ((monType - 11) * 2)
#endif // GUARD_TYPE_ICONS_H

View File

@@ -1,30 +1,46 @@
#include "global.h"
#include "battle.h"
#include "battle_ai_main.h"
#include "battle_anim.h"
#include "battle_controllers.h"
#include "battle_interface.h"
#include "battle_message.h"
#include "battle_setup.h"
#include "gflib.h"
#include "battle_tower.h"
#include "bg.h"
#include "data.h"
#include "link.h"
#include "main.h"
#include "m4a.h"
#include "palette.h"
#include "pokeball.h"
#include "pokemon.h"
#include "recorded_battle.h"
#include "reshow_battle_screen.h"
#include "sound.h"
#include "string_util.h"
#include "task.h"
#include "text.h"
#include "util.h"
#include "window.h"
#include "constants/battle_anim.h"
#include "constants/songs.h"
#include "constants/sound.h"
#include "constants/trainers.h"
#include "recorded_battle.h"
#include "random.h"
static void LinkOpponentHandleLoadMonSprite(u32 battler);
static void LinkOpponentHandleSwitchInAnim(u32 battler);
static void LinkOpponentHandleDrawTrainerPic(u32 battler);
static void LinkOpponentHandleTrainerSlide(u32 battler);
static void LinkOpponentHandleTrainerSlideBack(u32 battler);
static void LinkOpponentHandleMoveAnimation(u32 battler);
static void LinkOpponentHandlePrintString(u32 battler);
static void LinkOpponentHandleHealthBarUpdate(u32 battler);
static void LinkOpponentHandleIntroTrainerBallThrow(u32 battler);
static void LinkOpponentHandleDrawPartyStatusSummary(u32 battler);
static void LinkOpponentHandleBattleAnimation(u32 battler);
static void LinkOpponentHandleLinkStandbyMsg(u32 battler);
static void LinkOpponentHandleEndLinkBattle(u32 battler);
static void LinkOpponentBufferRunCommand(u32 battler);
@@ -33,64 +49,64 @@ static void SwitchIn_HandleSoundAndEnd(u32 battler);
static void (*const sLinkOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
{
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData, // done
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty, // done
[CONTROLLER_SETMONDATA] = BtlController_HandleSetMonData, // done
[CONTROLLER_SETRAWMONDATA] = BtlController_HandleSetRawMonData, // done
[CONTROLLER_LOADMONSPRITE] = LinkOpponentHandleLoadMonSprite, // done
[CONTROLLER_SWITCHINANIM] = LinkOpponentHandleSwitchInAnim, // done
[CONTROLLER_RETURNMONTOBALL] = BtlController_HandleReturnMonToBall, // done
[CONTROLLER_DRAWTRAINERPIC] = LinkOpponentHandleDrawTrainerPic, // done
[CONTROLLER_TRAINERSLIDE] = BtlController_Empty, // done
[CONTROLLER_TRAINERSLIDEBACK] = LinkOpponentHandleTrainerSlideBack, // done
[CONTROLLER_FAINTANIMATION] = BtlController_HandleFaintAnimation, // done
[CONTROLLER_PALETTEFADE] = BtlController_Empty, // done
[CONTROLLER_SUCCESSBALLTHROWANIM] = BtlController_Empty, // done
[CONTROLLER_BALLTHROWANIM] = BtlController_Empty, // done
[CONTROLLER_PAUSE] = BtlController_Empty, // done
[CONTROLLER_MOVEANIMATION] = BtlController_HandleMoveAnimation, // done
[CONTROLLER_PRINTSTRING] = BtlController_HandlePrintString, // done
[CONTROLLER_PRINTSTRINGPLAYERONLY] = BtlController_Empty, // done
[CONTROLLER_CHOOSEACTION] = BtlController_Empty, // done
[CONTROLLER_UNKNOWNYESNOBOX] = BtlController_Empty, // done
[CONTROLLER_CHOOSEMOVE] = BtlController_Empty, // done
[CONTROLLER_OPENBAG] = BtlController_Empty, // done
[CONTROLLER_CHOOSEPOKEMON] = BtlController_Empty, // done
[CONTROLLER_23] = BtlController_Empty, // done
[CONTROLLER_HEALTHBARUPDATE] = LinkOpponentHandleHealthBarUpdate, // done
[CONTROLLER_EXPUPDATE] = BtlController_Empty, // done
[CONTROLLER_STATUSICONUPDATE] = BtlController_HandleStatusIconUpdate, // done
[CONTROLLER_STATUSANIMATION] = BtlController_HandleStatusAnimation, // done
[CONTROLLER_STATUSXOR] = BtlController_Empty, // done
[CONTROLLER_DATATRANSFER] = BtlController_Empty, // done
[CONTROLLER_DMA3TRANSFER] = BtlController_Empty, // done
[CONTROLLER_PLAYBGM] = BtlController_Empty, // done
[CONTROLLER_32] = BtlController_Empty, // done
[CONTROLLER_TWORETURNVALUES] = BtlController_Empty, // done
[CONTROLLER_CHOSENMONRETURNVALUE] = BtlController_Empty, // done
[CONTROLLER_ONERETURNVALUE] = BtlController_Empty, // done
[CONTROLLER_ONERETURNVALUE_DUPLICATE] = BtlController_Empty, // done
[CONTROLLER_CLEARUNKVAR] = BtlController_HandleClearUnkVar, // done
[CONTROLLER_SETUNKVAR] = BtlController_HandleSetUnkVar, // done
[CONTROLLER_CLEARUNKFLAG] = BtlController_HandleClearUnkFlag, // done
[CONTROLLER_TOGGLEUNKFLAG] = BtlController_HandleToggleUnkFlag, // done
[CONTROLLER_HITANIMATION] = BtlController_HandleHitAnimation, // done
[CONTROLLER_CANTSWITCH] = BtlController_Empty, // done
[CONTROLLER_PLAYSE] = BtlController_HandlePlaySE, // done
[CONTROLLER_PLAYFANFAREORBGM] = BtlController_HandlePlayFanfareOrBGM, // done
[CONTROLLER_FAINTINGCRY] = BtlController_HandleFaintingCry, // done
[CONTROLLER_INTROSLIDE] = BtlController_HandleIntroSlide, // done
[CONTROLLER_INTROTRAINERBALLTHROW] = LinkOpponentHandleIntroTrainerBallThrow, // done
[CONTROLLER_DRAWPARTYSTATUSSUMMARY] = LinkOpponentHandleDrawPartyStatusSummary, // done
[CONTROLLER_HIDEPARTYSTATUSSUMMARY] = BtlController_HandleHidePartyStatusSummary, // done
[CONTROLLER_ENDBOUNCE] = BtlController_Empty, // done
[CONTROLLER_SPRITEINVISIBILITY] = BtlController_HandleSpriteInvisibility, // done
[CONTROLLER_BATTLEANIMATION] = LinkOpponentHandleBattleAnimation, // done
[CONTROLLER_LINKSTANDBYMSG] = BtlController_Empty, // done
[CONTROLLER_RESETACTIONMOVESELECTION] = BtlController_Empty, // done
[CONTROLLER_ENDLINKBATTLE] = LinkOpponentHandleEndLinkBattle, // done
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData,
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty,
[CONTROLLER_SETMONDATA] = BtlController_HandleSetMonData,
[CONTROLLER_SETRAWMONDATA] = BtlController_HandleSetRawMonData,
[CONTROLLER_LOADMONSPRITE] = LinkOpponentHandleLoadMonSprite,
[CONTROLLER_SWITCHINANIM] = LinkOpponentHandleSwitchInAnim,
[CONTROLLER_RETURNMONTOBALL] = BtlController_HandleReturnMonToBall,
[CONTROLLER_DRAWTRAINERPIC] = LinkOpponentHandleDrawTrainerPic,
[CONTROLLER_TRAINERSLIDE] = LinkOpponentHandleTrainerSlide,
[CONTROLLER_TRAINERSLIDEBACK] = LinkOpponentHandleTrainerSlideBack,
[CONTROLLER_FAINTANIMATION] = BtlController_HandleFaintAnimation,
[CONTROLLER_PALETTEFADE] = BtlController_Empty,
[CONTROLLER_SUCCESSBALLTHROWANIM] = BtlController_Empty,
[CONTROLLER_BALLTHROWANIM] = BtlController_Empty,
[CONTROLLER_PAUSE] = BtlController_Empty,
[CONTROLLER_MOVEANIMATION] = LinkOpponentHandleMoveAnimation,
[CONTROLLER_PRINTSTRING] = LinkOpponentHandlePrintString,
[CONTROLLER_PRINTSTRINGPLAYERONLY] = BtlController_Empty,
[CONTROLLER_CHOOSEACTION] = BtlController_Empty,
[CONTROLLER_YESNOBOX] = BtlController_Empty,
[CONTROLLER_CHOOSEMOVE] = BtlController_Empty,
[CONTROLLER_OPENBAG] = BtlController_Empty,
[CONTROLLER_CHOOSEPOKEMON] = BtlController_Empty,
[CONTROLLER_23] = BtlController_Empty,
[CONTROLLER_HEALTHBARUPDATE] = LinkOpponentHandleHealthBarUpdate,
[CONTROLLER_EXPUPDATE] = BtlController_Empty,
[CONTROLLER_STATUSICONUPDATE] = BtlController_HandleStatusIconUpdate,
[CONTROLLER_STATUSANIMATION] = BtlController_HandleStatusAnimation,
[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_HandleClearUnkVar,
[CONTROLLER_SETUNKVAR] = BtlController_HandleSetUnkVar,
[CONTROLLER_CLEARUNKFLAG] = BtlController_HandleClearUnkFlag,
[CONTROLLER_TOGGLEUNKFLAG] = BtlController_HandleToggleUnkFlag,
[CONTROLLER_HITANIMATION] = BtlController_HandleHitAnimation,
[CONTROLLER_CANTSWITCH] = BtlController_Empty,
[CONTROLLER_PLAYSE] = BtlController_HandlePlaySE,
[CONTROLLER_PLAYFANFAREORBGM] = BtlController_HandlePlayFanfareOrBGM,
[CONTROLLER_FAINTINGCRY] = BtlController_HandleFaintingCry,
[CONTROLLER_INTROSLIDE] = BtlController_HandleIntroSlide,
[CONTROLLER_INTROTRAINERBALLTHROW] = LinkOpponentHandleIntroTrainerBallThrow,
[CONTROLLER_DRAWPARTYSTATUSSUMMARY] = LinkOpponentHandleDrawPartyStatusSummary,
[CONTROLLER_HIDEPARTYSTATUSSUMMARY] = BtlController_HandleHidePartyStatusSummary,
[CONTROLLER_ENDBOUNCE] = BtlController_Empty,
[CONTROLLER_SPRITEINVISIBILITY] = BtlController_HandleSpriteInvisibility,
[CONTROLLER_BATTLEANIMATION] = LinkOpponentHandleBattleAnimation,
[CONTROLLER_LINKSTANDBYMSG] = LinkOpponentHandleLinkStandbyMsg,
[CONTROLLER_RESETACTIONMOVESELECTION] = BtlController_Empty,
[CONTROLLER_ENDLINKBATTLE] = LinkOpponentHandleEndLinkBattle,
[CONTROLLER_DEBUGMENU] = BtlController_Empty,
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop // done
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop
};
void SetControllerToLinkOpponent(u32 battler)
@@ -101,7 +117,7 @@ void SetControllerToLinkOpponent(u32 battler)
static void LinkOpponentBufferRunCommand(u32 battler)
{
if (gBattleControllerExecFlags & gBitTable[battler])
if (gBattleControllerExecFlags & (1u << battler))
{
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sLinkOpponentBufferCommands))
sLinkOpponentBufferCommands[gBattleResources->bufferA[battler][0]](battler);
@@ -267,7 +283,7 @@ static void Intro_TryShinyAnimShowHealthbox(u32 battler)
static void TryShinyAnimAfterMonAnim(u32 battler)
{
if (gSprites[gBattlerSpriteIds[battler]].animEnded == TRUE
if (gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy
&& gSprites[gBattlerSpriteIds[battler]].x2 == 0)
{
if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim)
@@ -300,14 +316,19 @@ static void SwitchIn_HandleSoundAndEnd(u32 battler)
{
if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive && !IsCryPlayingOrClearCrySongs())
{
m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100);
LinkOpponentBufferExecCompleted(battler);
if (gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy
|| gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy_2)
{
m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100);
LinkOpponentBufferExecCompleted(battler);
}
}
}
static void SwitchIn_ShowHealthbox(u32 battler)
{
if (gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim)
if (gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim
&& gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy)
{
gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
@@ -354,7 +375,7 @@ static void LinkOpponentBufferExecCompleted(u32 battler)
}
else
{
gBattleControllerExecFlags &= ~gBitTable[battler];
gBattleControllerExecFlags &= ~(1u << battler);
}
}
@@ -426,11 +447,34 @@ static void LinkOpponentHandleDrawTrainerPic(u32 battler)
BtlController_HandleDrawTrainerPic(battler, trainerPicId, TRUE, xPos, 40, -1);
}
static void LinkOpponentHandleTrainerSlide(u32 battler)
{
u32 trainerPicId;
if (battler == B_POSITION_OPPONENT_LEFT)
trainerPicId = GetBattleTowerTrainerFrontSpriteId(gTrainerBattleOpponent_A);
else
trainerPicId = GetBattleTowerTrainerFrontSpriteId(gTrainerBattleOpponent_B);
BtlController_HandleTrainerSlide(battler, trainerPicId);
LinkOpponentBufferExecCompleted(battler); // Possibly a bug, because execution should be completed after the slide in finishes. See Controller_WaitForTrainerPic.
}
static void LinkOpponentHandleTrainerSlideBack(u32 battler)
{
BtlController_HandleTrainerSlideBack(battler, 35, FALSE);
}
static void LinkOpponentHandleMoveAnimation(u32 battler)
{
BtlController_HandleMoveAnimation(battler);
}
static void LinkOpponentHandlePrintString(u32 battler)
{
BtlController_HandlePrintString(battler);
}
static void LinkOpponentHandleHealthBarUpdate(u32 battler)
{
BtlController_HandleHealthBarUpdate(battler, FALSE);
@@ -451,13 +495,22 @@ static void LinkOpponentHandleBattleAnimation(u32 battler)
BtlController_HandleBattleAnimation(battler, FALSE);
}
static void LinkOpponentHandleLinkStandbyMsg(u32 battler)
{
// RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][2]);
LinkOpponentBufferExecCompleted(battler);
}
static void LinkOpponentHandleEndLinkBattle(u32 battler)
{
// RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][4]);
if (gBattleResources->bufferA[battler][1] == B_OUTCOME_DREW)
gBattleOutcome = gBattleResources->bufferA[battler][1];
else
gBattleOutcome = gBattleResources->bufferA[battler][1] ^ B_OUTCOME_DREW;
// gSaveBlock2Ptr->frontier.disableRecordBattle = gBattleResources->bufferA[battler][2];
FadeOutMapMusic(5);
BeginFastPaletteFade(3);
LinkOpponentBufferExecCompleted(battler);

View File

@@ -1,27 +1,45 @@
#include "global.h"
#include "gflib.h"
#include "data.h"
#include "link.h"
#include "pokeball.h"
#include "task.h"
#include "util.h"
#include "battle.h"
#include "battle_ai_main.h"
#include "battle_anim.h"
#include "battle_controllers.h"
#include "battle_interface.h"
#include "battle_message.h"
#include "battle_setup.h"
#include "battle_tower.h"
#include "bg.h"
#include "data.h"
#include "link.h"
#include "main.h"
#include "m4a.h"
#include "palette.h"
#include "pokeball.h"
#include "pokemon.h"
#include "recorded_battle.h"
#include "reshow_battle_screen.h"
#include "sound.h"
#include "string_util.h"
#include "task.h"
#include "text.h"
#include "util.h"
#include "window.h"
#include "constants/battle_anim.h"
#include "constants/songs.h"
#include "constants/sound.h"
#include "constants/trainers.h"
#include "recorded_battle.h"
#include "random.h"
static void LinkPartnerHandleLoadMonSprite(u32 battler);
static void LinkPartnerHandleSwitchInAnim(u32 battler);
static void LinkPartnerHandleDrawTrainerPic(u32 battler);
static void LinkPartnerHandleTrainerSlideBack(u32 battler);
static void LinkPartnerHandleMoveAnimation(u32 battler);
static void LinkPartnerHandlePrintString(u32 battler);
static void LinkPartnerHandleHealthBarUpdate(u32 battler);
static void LinkPartnerHandleIntroTrainerBallThrow(u32 battler);
static void LinkPartnerHandleDrawPartyStatusSummary(u32 battler);
static void LinkPartnerHandleBattleAnimation(u32 battler);
static void LinkPartnerHandleLinkStandbyMsg(u32 battler);
static void LinkPartnerHandleEndLinkBattle(u32 battler);
static void LinkPartnerBufferRunCommand(u32 battler);
@@ -30,64 +48,64 @@ static void SwitchIn_WaitAndEnd(u32 battler);
static void (*const sLinkPartnerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
{
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData, // done
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty, // done
[CONTROLLER_SETMONDATA] = BtlController_HandleSetMonData, // done
[CONTROLLER_SETRAWMONDATA] = BtlController_HandleSetRawMonData, // done
[CONTROLLER_LOADMONSPRITE] = LinkPartnerHandleLoadMonSprite, // done
[CONTROLLER_SWITCHINANIM] = LinkPartnerHandleSwitchInAnim, // done
[CONTROLLER_RETURNMONTOBALL] = BtlController_HandleReturnMonToBall, // done
[CONTROLLER_DRAWTRAINERPIC] = LinkPartnerHandleDrawTrainerPic, // done
[CONTROLLER_TRAINERSLIDE] = BtlController_Empty, // done
[CONTROLLER_TRAINERSLIDEBACK] = LinkPartnerHandleTrainerSlideBack, // done
[CONTROLLER_FAINTANIMATION] = BtlController_HandleFaintAnimation, // done
[CONTROLLER_PALETTEFADE] = BtlController_Empty, // done
[CONTROLLER_SUCCESSBALLTHROWANIM] = BtlController_Empty, // done
[CONTROLLER_BALLTHROWANIM] = BtlController_Empty, // done
[CONTROLLER_PAUSE] = BtlController_Empty, // done
[CONTROLLER_MOVEANIMATION] = BtlController_HandleMoveAnimation, // done
[CONTROLLER_PRINTSTRING] = BtlController_HandlePrintString, // done
[CONTROLLER_PRINTSTRINGPLAYERONLY] = BtlController_Empty, // done
[CONTROLLER_CHOOSEACTION] = BtlController_Empty, // done
[CONTROLLER_UNKNOWNYESNOBOX] = BtlController_Empty, // done
[CONTROLLER_CHOOSEMOVE] = BtlController_Empty, // done
[CONTROLLER_OPENBAG] = BtlController_Empty, // done
[CONTROLLER_CHOOSEPOKEMON] = BtlController_Empty, // done
[CONTROLLER_23] = BtlController_Empty, // done
[CONTROLLER_HEALTHBARUPDATE] = LinkPartnerHandleHealthBarUpdate, // done
[CONTROLLER_EXPUPDATE] = BtlController_Empty, // done
[CONTROLLER_STATUSICONUPDATE] = BtlController_HandleStatusIconUpdate, // done
[CONTROLLER_STATUSANIMATION] = BtlController_HandleStatusAnimation, // done
[CONTROLLER_STATUSXOR] = BtlController_Empty, // done
[CONTROLLER_DATATRANSFER] = BtlController_Empty, // done
[CONTROLLER_DMA3TRANSFER] = BtlController_Empty, // done
[CONTROLLER_PLAYBGM] = BtlController_Empty, // done
[CONTROLLER_32] = BtlController_Empty, // done
[CONTROLLER_TWORETURNVALUES] = BtlController_Empty, // done
[CONTROLLER_CHOSENMONRETURNVALUE] = BtlController_Empty, // done
[CONTROLLER_ONERETURNVALUE] = BtlController_Empty, // done
[CONTROLLER_ONERETURNVALUE_DUPLICATE] = BtlController_Empty, // done
[CONTROLLER_CLEARUNKVAR] = BtlController_HandleClearUnkVar, // done
[CONTROLLER_SETUNKVAR] = BtlController_HandleSetUnkVar, // done
[CONTROLLER_CLEARUNKFLAG] = BtlController_HandleClearUnkFlag, // done
[CONTROLLER_TOGGLEUNKFLAG] = BtlController_HandleToggleUnkFlag, // done
[CONTROLLER_HITANIMATION] = BtlController_HandleHitAnimation, // done
[CONTROLLER_CANTSWITCH] = BtlController_Empty, // done
[CONTROLLER_PLAYSE] = BtlController_HandlePlaySE, // done
[CONTROLLER_PLAYFANFAREORBGM] = BtlController_HandlePlayFanfareOrBGM, // done
[CONTROLLER_FAINTINGCRY] = BtlController_HandleFaintingCry, // done
[CONTROLLER_INTROSLIDE] = BtlController_HandleIntroSlide, // done
[CONTROLLER_INTROTRAINERBALLTHROW] = LinkPartnerHandleIntroTrainerBallThrow, // done
[CONTROLLER_DRAWPARTYSTATUSSUMMARY] = LinkPartnerHandleDrawPartyStatusSummary, // done
[CONTROLLER_HIDEPARTYSTATUSSUMMARY] = BtlController_HandleHidePartyStatusSummary, // done
[CONTROLLER_ENDBOUNCE] = BtlController_Empty, // done
[CONTROLLER_SPRITEINVISIBILITY] = BtlController_HandleSpriteInvisibility, // done
[CONTROLLER_BATTLEANIMATION] = LinkPartnerHandleBattleAnimation, // done
[CONTROLLER_LINKSTANDBYMSG] = BtlController_Empty, // done
[CONTROLLER_RESETACTIONMOVESELECTION] = BtlController_Empty, // done
[CONTROLLER_ENDLINKBATTLE] = LinkPartnerHandleEndLinkBattle, // done
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData,
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty,
[CONTROLLER_SETMONDATA] = BtlController_HandleSetMonData,
[CONTROLLER_SETRAWMONDATA] = BtlController_HandleSetRawMonData,
[CONTROLLER_LOADMONSPRITE] = LinkPartnerHandleLoadMonSprite,
[CONTROLLER_SWITCHINANIM] = LinkPartnerHandleSwitchInAnim,
[CONTROLLER_RETURNMONTOBALL] = BtlController_HandleReturnMonToBall,
[CONTROLLER_DRAWTRAINERPIC] = LinkPartnerHandleDrawTrainerPic,
[CONTROLLER_TRAINERSLIDE] = BtlController_Empty,
[CONTROLLER_TRAINERSLIDEBACK] = LinkPartnerHandleTrainerSlideBack,
[CONTROLLER_FAINTANIMATION] = BtlController_HandleFaintAnimation,
[CONTROLLER_PALETTEFADE] = BtlController_Empty,
[CONTROLLER_SUCCESSBALLTHROWANIM] = BtlController_Empty,
[CONTROLLER_BALLTHROWANIM] = BtlController_Empty,
[CONTROLLER_PAUSE] = BtlController_Empty,
[CONTROLLER_MOVEANIMATION] = LinkPartnerHandleMoveAnimation,
[CONTROLLER_PRINTSTRING] = LinkPartnerHandlePrintString,
[CONTROLLER_PRINTSTRINGPLAYERONLY] = BtlController_Empty,
[CONTROLLER_CHOOSEACTION] = BtlController_Empty,
[CONTROLLER_YESNOBOX] = BtlController_Empty,
[CONTROLLER_CHOOSEMOVE] = BtlController_Empty,
[CONTROLLER_OPENBAG] = BtlController_Empty,
[CONTROLLER_CHOOSEPOKEMON] = BtlController_Empty,
[CONTROLLER_23] = BtlController_Empty,
[CONTROLLER_HEALTHBARUPDATE] = LinkPartnerHandleHealthBarUpdate,
[CONTROLLER_EXPUPDATE] = BtlController_Empty,
[CONTROLLER_STATUSICONUPDATE] = BtlController_HandleStatusIconUpdate,
[CONTROLLER_STATUSANIMATION] = BtlController_HandleStatusAnimation,
[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_HandleClearUnkVar,
[CONTROLLER_SETUNKVAR] = BtlController_HandleSetUnkVar,
[CONTROLLER_CLEARUNKFLAG] = BtlController_HandleClearUnkFlag,
[CONTROLLER_TOGGLEUNKFLAG] = BtlController_HandleToggleUnkFlag,
[CONTROLLER_HITANIMATION] = BtlController_HandleHitAnimation,
[CONTROLLER_CANTSWITCH] = BtlController_Empty,
[CONTROLLER_PLAYSE] = BtlController_HandlePlaySE,
[CONTROLLER_PLAYFANFAREORBGM] = BtlController_HandlePlayFanfareOrBGM,
[CONTROLLER_FAINTINGCRY] = BtlController_HandleFaintingCry,
[CONTROLLER_INTROSLIDE] = BtlController_HandleIntroSlide,
[CONTROLLER_INTROTRAINERBALLTHROW] = LinkPartnerHandleIntroTrainerBallThrow,
[CONTROLLER_DRAWPARTYSTATUSSUMMARY] = LinkPartnerHandleDrawPartyStatusSummary,
[CONTROLLER_HIDEPARTYSTATUSSUMMARY] = BtlController_HandleHidePartyStatusSummary,
[CONTROLLER_ENDBOUNCE] = BtlController_Empty,
[CONTROLLER_SPRITEINVISIBILITY] = BtlController_HandleSpriteInvisibility,
[CONTROLLER_BATTLEANIMATION] = LinkPartnerHandleBattleAnimation,
[CONTROLLER_LINKSTANDBYMSG] = LinkPartnerHandleLinkStandbyMsg,
[CONTROLLER_RESETACTIONMOVESELECTION] = BtlController_Empty,
[CONTROLLER_ENDLINKBATTLE] = LinkPartnerHandleEndLinkBattle,
[CONTROLLER_DEBUGMENU] = BtlController_Empty,
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop // done
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop
};
void SetControllerToLinkPartner(u32 battler)
@@ -98,7 +116,7 @@ void SetControllerToLinkPartner(u32 battler)
static void LinkPartnerBufferRunCommand(u32 battler)
{
if (gBattleControllerExecFlags & gBitTable[battler])
if (gBattleControllerExecFlags & (1u << battler))
{
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sLinkPartnerBufferCommands))
sLinkPartnerBufferCommands[gBattleResources->bufferA[battler][0]](battler);
@@ -117,6 +135,7 @@ static void SwitchIn_ShowSubstitute(u32 battler)
{
if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy)
{
CopyBattleSpriteInvisibility(battler);
if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute)
InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_MON_TO_SUBSTITUTE);
@@ -126,7 +145,8 @@ static void SwitchIn_ShowSubstitute(u32 battler)
static void SwitchIn_WaitAndEnd(u32 battler)
{
if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive)
if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive
&& gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy)
{
LinkPartnerBufferExecCompleted(battler);
}
@@ -148,7 +168,7 @@ static void SwitchIn_ShowHealthbox(u32 battler)
UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gPlayerParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL);
StartHealthboxSlideIn(battler);
SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]);
CopyBattleSpriteInvisibility(battler);
gBattlerControllerFuncs[battler] = SwitchIn_ShowSubstitute;
}
}
@@ -181,7 +201,7 @@ static void LinkPartnerBufferExecCompleted(u32 battler)
}
else
{
gBattleControllerExecFlags &= ~gBitTable[battler];
gBattleControllerExecFlags &= ~(1u << battler);
}
}
@@ -223,6 +243,16 @@ static void LinkPartnerHandleTrainerSlideBack(u32 battler)
BtlController_HandleTrainerSlideBack(battler, 35, FALSE);
}
static void LinkPartnerHandleMoveAnimation(u32 battler)
{
BtlController_HandleMoveAnimation(battler);
}
static void LinkPartnerHandlePrintString(u32 battler)
{
BtlController_HandlePrintString(battler);
}
static void LinkPartnerHandleHealthBarUpdate(u32 battler)
{
BtlController_HandleHealthBarUpdate(battler, FALSE);
@@ -246,9 +276,17 @@ static void LinkPartnerHandleBattleAnimation(u32 battler)
BtlController_HandleBattleAnimation(battler, FALSE);
}
static void LinkPartnerHandleLinkStandbyMsg(u32 battler)
{
// RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][2]);
LinkPartnerBufferExecCompleted(battler);
}
static void LinkPartnerHandleEndLinkBattle(u32 battler)
{
// RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][4]);
gBattleOutcome = gBattleResources->bufferA[battler][1];
// gSaveBlock2Ptr->frontier.disableRecordBattle = gBattleResources->bufferA[battler][2];
FadeOutMapMusic(5);
BeginFastPaletteFade(3);
LinkPartnerBufferExecCompleted(battler);

View File

@@ -51,64 +51,64 @@ static void HandleInputChooseAction(u32 battler);
static void (*const sOakOldManBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
{
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData, // done
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty, // done
[CONTROLLER_SETMONDATA] = BtlController_HandleSetMonData, // done
[CONTROLLER_SETRAWMONDATA] = BtlController_Empty, // done
[CONTROLLER_LOADMONSPRITE] = BtlController_Empty, // done
[CONTROLLER_SWITCHINANIM] = BtlController_Empty, // done
[CONTROLLER_RETURNMONTOBALL] = BtlController_HandleReturnMonToBall, // done
[CONTROLLER_DRAWTRAINERPIC] = OakOldManHandleDrawTrainerPic, // done
[CONTROLLER_TRAINERSLIDE] = OakOldManHandleTrainerSlide, // done
[CONTROLLER_TRAINERSLIDEBACK] = BtlController_Empty, // done
[CONTROLLER_FAINTANIMATION] = BtlController_HandleFaintAnimation, // done
[CONTROLLER_PALETTEFADE] = BtlController_Empty, // done
[CONTROLLER_SUCCESSBALLTHROWANIM] = OakOldManHandleSuccessBallThrowAnim, // done
[CONTROLLER_BALLTHROWANIM] = OakOldManHandleBallThrowAnim, // done
[CONTROLLER_PAUSE] = BtlController_Empty, // done
[CONTROLLER_MOVEANIMATION] = BtlController_HandleMoveAnimation, // done
[CONTROLLER_PRINTSTRING] = OakOldManHandlePrintString, // done
[CONTROLLER_PRINTSTRINGPLAYERONLY] = OakOldManHandlePrintSelectionString, // done
[CONTROLLER_CHOOSEACTION] = OakOldManHandleChooseAction, // done
[CONTROLLER_UNKNOWNYESNOBOX] = BtlController_Empty, // done
[CONTROLLER_CHOOSEMOVE] = OakOldManHandleChooseMove, // done
[CONTROLLER_OPENBAG] = OakOldManHandleChooseItem, // done
[CONTROLLER_CHOOSEPOKEMON] = OakOldManHandleChoosePokemon, // done
[CONTROLLER_23] = BtlController_Empty, // done
[CONTROLLER_HEALTHBARUPDATE] = OakOldManHandleHealthBarUpdate, // done
[CONTROLLER_EXPUPDATE] = PlayerHandleExpUpdate, // done
[CONTROLLER_STATUSICONUPDATE] = BtlController_HandleStatusIconUpdate, // done
[CONTROLLER_STATUSANIMATION] = BtlController_HandleStatusAnimation, // done
[CONTROLLER_STATUSXOR] = BtlController_Empty, // done
[CONTROLLER_DATATRANSFER] = BtlController_Empty, // done
[CONTROLLER_DMA3TRANSFER] = BtlController_Empty, // done
[CONTROLLER_PLAYBGM] = BtlController_Empty, // done
[CONTROLLER_32] = BtlController_Empty, // done
[CONTROLLER_TWORETURNVALUES] = BtlController_Empty, // done
[CONTROLLER_CHOSENMONRETURNVALUE] = BtlController_Empty, // done
[CONTROLLER_ONERETURNVALUE] = BtlController_Empty, // done
[CONTROLLER_ONERETURNVALUE_DUPLICATE] = BtlController_Empty, // done
[CONTROLLER_CLEARUNKVAR] = BtlController_Empty, // done
[CONTROLLER_SETUNKVAR] = BtlController_Empty, // done
[CONTROLLER_CLEARUNKFLAG] = BtlController_Empty, // done
[CONTROLLER_TOGGLEUNKFLAG] = BtlController_Empty, // done
[CONTROLLER_HITANIMATION] = BtlController_HandleHitAnimation, // done
[CONTROLLER_CANTSWITCH] = BtlController_Empty, // done
[CONTROLLER_PLAYSE] = OakOldManHandlePlaySE, // done
[CONTROLLER_PLAYFANFAREORBGM] = BtlController_HandlePlayFanfareOrBGM, // done
[CONTROLLER_FAINTINGCRY] = OakOldManHandleFaintingCry, // done
[CONTROLLER_INTROSLIDE] = BtlController_HandleIntroSlide, // done
[CONTROLLER_INTROTRAINERBALLTHROW] = OakOldManHandleIntroTrainerBallThrow, // done
[CONTROLLER_DRAWPARTYSTATUSSUMMARY] = OakOldManHandleDrawPartyStatusSummary, // done
[CONTROLLER_HIDEPARTYSTATUSSUMMARY] = BtlController_Empty, // done
[CONTROLLER_ENDBOUNCE] = OakOldManHandleEndBounceEffect, // done
[CONTROLLER_SPRITEINVISIBILITY] = BtlController_Empty, // done
[CONTROLLER_BATTLEANIMATION] = OakOldManHandleBattleAnimation, // done
[CONTROLLER_LINKSTANDBYMSG] = OakOldManHandleLinkStandbyMsg, // done
[CONTROLLER_RESETACTIONMOVESELECTION] = BtlController_Empty, // done
[CONTROLLER_ENDLINKBATTLE] = OakOldManHandleEndLinkBattle, // done
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData,
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty,
[CONTROLLER_SETMONDATA] = BtlController_HandleSetMonData,
[CONTROLLER_SETRAWMONDATA] = BtlController_Empty,
[CONTROLLER_LOADMONSPRITE] = BtlController_Empty,
[CONTROLLER_SWITCHINANIM] = BtlController_Empty,
[CONTROLLER_RETURNMONTOBALL] = BtlController_HandleReturnMonToBall,
[CONTROLLER_DRAWTRAINERPIC] = OakOldManHandleDrawTrainerPic,
[CONTROLLER_TRAINERSLIDE] = OakOldManHandleTrainerSlide,
[CONTROLLER_TRAINERSLIDEBACK] = BtlController_Empty,
[CONTROLLER_FAINTANIMATION] = BtlController_HandleFaintAnimation,
[CONTROLLER_PALETTEFADE] = BtlController_Empty,
[CONTROLLER_SUCCESSBALLTHROWANIM] = OakOldManHandleSuccessBallThrowAnim,
[CONTROLLER_BALLTHROWANIM] = OakOldManHandleBallThrowAnim,
[CONTROLLER_PAUSE] = BtlController_Empty,
[CONTROLLER_MOVEANIMATION] = BtlController_HandleMoveAnimation,
[CONTROLLER_PRINTSTRING] = OakOldManHandlePrintString,
[CONTROLLER_PRINTSTRINGPLAYERONLY] = OakOldManHandlePrintSelectionString,
[CONTROLLER_CHOOSEACTION] = OakOldManHandleChooseAction,
[CONTROLLER_YESNOBOX] = BtlController_Empty,
[CONTROLLER_CHOOSEMOVE] = OakOldManHandleChooseMove,
[CONTROLLER_OPENBAG] = OakOldManHandleChooseItem,
[CONTROLLER_CHOOSEPOKEMON] = OakOldManHandleChoosePokemon,
[CONTROLLER_23] = BtlController_Empty,
[CONTROLLER_HEALTHBARUPDATE] = OakOldManHandleHealthBarUpdate,
[CONTROLLER_EXPUPDATE] = PlayerHandleExpUpdate,
[CONTROLLER_STATUSICONUPDATE] = BtlController_HandleStatusIconUpdate,
[CONTROLLER_STATUSANIMATION] = BtlController_HandleStatusAnimation,
[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_HandleHitAnimation,
[CONTROLLER_CANTSWITCH] = BtlController_Empty,
[CONTROLLER_PLAYSE] = OakOldManHandlePlaySE,
[CONTROLLER_PLAYFANFAREORBGM] = BtlController_HandlePlayFanfareOrBGM,
[CONTROLLER_FAINTINGCRY] = OakOldManHandleFaintingCry,
[CONTROLLER_INTROSLIDE] = BtlController_HandleIntroSlide,
[CONTROLLER_INTROTRAINERBALLTHROW] = OakOldManHandleIntroTrainerBallThrow,
[CONTROLLER_DRAWPARTYSTATUSSUMMARY] = OakOldManHandleDrawPartyStatusSummary,
[CONTROLLER_HIDEPARTYSTATUSSUMMARY] = BtlController_Empty,
[CONTROLLER_ENDBOUNCE] = OakOldManHandleEndBounceEffect,
[CONTROLLER_SPRITEINVISIBILITY] = BtlController_Empty,
[CONTROLLER_BATTLEANIMATION] = OakOldManHandleBattleAnimation,
[CONTROLLER_LINKSTANDBYMSG] = OakOldManHandleLinkStandbyMsg,
[CONTROLLER_RESETACTIONMOVESELECTION] = BtlController_Empty,
[CONTROLLER_ENDLINKBATTLE] = OakOldManHandleEndLinkBattle,
[CONTROLLER_DEBUGMENU] = BtlController_Empty,
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop, // done
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop,
};
void SetControllerToOakOrOldMan(u32 battler)
@@ -123,9 +123,9 @@ void SetControllerToOakOrOldMan(u32 battler)
static void OakOldManBufferRunCommand(u32 battler)
{
if (gBattleControllerExecFlags & gBitTable[battler])
if (gBattleControllerExecFlags & (1u << battler))
{
if (gBattleResources->bufferA[battler][0] < NELEMS(sOakOldManBufferCommands))
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sOakOldManBufferCommands))
sOakOldManBufferCommands[gBattleResources->bufferA[battler][0]](battler);
else
OakOldManBufferExecCompleted(battler);
@@ -277,7 +277,7 @@ static void OakOldManSetBattleEndCallbacks(u32 battler)
void OakOldManHandleInputChooseMove(u32 battler)
{
HandleInputChooseMove(battler);
if (!(gBattleControllerExecFlags & gBitTable[battler]))
if (!(gBattleControllerExecFlags & (1u << battler)))
OakOldManBufferExecCompleted(battler);
}
@@ -291,7 +291,7 @@ static void OpenPartyMenuToChooseMon(u32 battler)
caseId = gTasks[gBattleControllerData[battler]].data[0];
DestroyTask(gBattleControllerData[battler]);
FreeAllWindowBuffers();
OpenPartyMenuInTutorialBattle(caseId);
OpenPartyMenuInBattle(caseId);
}
}
@@ -660,7 +660,7 @@ static void OakOldManBufferExecCompleted(u32 battler)
}
else
{
gBattleControllerExecFlags &= ~gBitTable[battler];
gBattleControllerExecFlags &= ~(1u << battler);
}
}
@@ -699,7 +699,7 @@ static void OakOldManHandlePrintString(u32 battler)
}
else
{
BufferStringBattle(battler, *stringId);
BufferStringBattle(*stringId, battler);
if (BattleStringShouldBeColored(*stringId))
BattlePutTextOnWindow(gDisplayedStringBattle, (B_WIN_MSG | B_TEXT_FLAG_NPC_CONTEXT_FONT));
else

View File

@@ -1,38 +1,49 @@
#include "global.h"
#include "gflib.h"
#include "data.h"
#include "m4a.h"
#include "task.h"
#include "util.h"
#include "pokeball.h"
#include "random.h"
#include "battle.h"
#include "battle_ai_main.h"
#include "battle_ai_switch_items.h"
#include "battle_ai_util.h"
#include "constants/battle_ai.h"
#include "battle_anim.h"
#include "battle_controllers.h"
#include "battle_gfx_sfx_util.h"
#include "battle_interface.h"
#include "battle_message.h"
#include "battle_interface.h"
#include "battle_setup.h"
#include "battle_tower.h"
#include "battle_z_move.h"
#include "bg.h"
#include "data.h"
#include "item.h"
#include "link.h"
#include "main.h"
#include "m4a.h"
#include "palette.h"
#include "party_menu.h"
#include "pokeball.h"
#include "pokemon.h"
#include "random.h"
#include "reshow_battle_screen.h"
#include "sound.h"
#include "string_util.h"
#include "task.h"
#include "text.h"
#include "trainer_tower.h"
#include "constants/battle_ai.h"
#include "util.h"
#include "window.h"
#include "constants/battle_anim.h"
#include "constants/items.h"
#include "constants/moves.h"
#include "constants/party_menu.h"
#include "constants/songs.h"
#include "constants/sound.h"
#include "constants/trainers.h"
#include "test_runner.h"
static void OpponentHandleLoadMonSprite(u32 battler);
static void OpponentHandleSwitchInAnim(u32 battler);
static void OpponentHandleDrawTrainerPic(u32 battler);
static void OpponentHandleTrainerSlide(u32 battler);
static void OpponentHandleTrainerSlideBack(u32 battler);
static void OpponentHandleMoveAnimation(u32 battler);
static void OpponentHandlePrintString(u32 battler);
static void OpponentHandleChooseAction(u32 battler);
static void OpponentHandleChooseMove(u32 battler);
static void OpponentHandleChooseItem(u32 battler);
@@ -49,64 +60,64 @@ static void SwitchIn_HandleSoundAndEnd(u32 battler);
static void (*const sOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
{
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData, // done
[CONTROLLER_GETRAWMONDATA] = BtlController_HandleGetRawMonData, // done
[CONTROLLER_SETMONDATA] = BtlController_HandleSetMonData, // done
[CONTROLLER_SETRAWMONDATA] = BtlController_HandleSetRawMonData, // done
[CONTROLLER_LOADMONSPRITE] = OpponentHandleLoadMonSprite, // done
[CONTROLLER_SWITCHINANIM] = OpponentHandleSwitchInAnim, // done
[CONTROLLER_RETURNMONTOBALL] = BtlController_HandleReturnMonToBall, // done
[CONTROLLER_DRAWTRAINERPIC] = OpponentHandleDrawTrainerPic, // done
[CONTROLLER_TRAINERSLIDE] = OpponentHandleTrainerSlide, // done
[CONTROLLER_TRAINERSLIDEBACK] = OpponentHandleTrainerSlideBack, // done
[CONTROLLER_FAINTANIMATION] = BtlController_HandleFaintAnimation, // done
[CONTROLLER_PALETTEFADE] = BtlController_Empty, // done
[CONTROLLER_SUCCESSBALLTHROWANIM] = BtlController_Empty, // done
[CONTROLLER_BALLTHROWANIM] = BtlController_Empty, // done
[CONTROLLER_PAUSE] = BtlController_Empty, // done
[CONTROLLER_MOVEANIMATION] = BtlController_HandleMoveAnimation, // done
[CONTROLLER_PRINTSTRING] = BtlController_HandlePrintString, // done
[CONTROLLER_PRINTSTRINGPLAYERONLY] = BtlController_Empty, // done
[CONTROLLER_CHOOSEACTION] = OpponentHandleChooseAction, // done
[CONTROLLER_UNKNOWNYESNOBOX] = BtlController_Empty, // done
[CONTROLLER_CHOOSEMOVE] = OpponentHandleChooseMove, // done
[CONTROLLER_OPENBAG] = OpponentHandleChooseItem, // done
[CONTROLLER_CHOOSEPOKEMON] = OpponentHandleChoosePokemon, // done
[CONTROLLER_23] = BtlController_Empty, // done
[CONTROLLER_HEALTHBARUPDATE] = OpponentHandleHealthBarUpdate, // done
[CONTROLLER_EXPUPDATE] = BtlController_Empty, // done
[CONTROLLER_STATUSICONUPDATE] = BtlController_HandleStatusIconUpdate, // done
[CONTROLLER_STATUSANIMATION] = BtlController_HandleStatusAnimation, // done
[CONTROLLER_STATUSXOR] = BtlController_Empty, // done
[CONTROLLER_DATATRANSFER] = BtlController_Empty, // done
[CONTROLLER_DMA3TRANSFER] = BtlController_Empty, // done
[CONTROLLER_PLAYBGM] = BtlController_Empty, // done
[CONTROLLER_32] = BtlController_Empty, // done
[CONTROLLER_TWORETURNVALUES] = BtlController_Empty, // done
[CONTROLLER_CHOSENMONRETURNVALUE] = BtlController_Empty, // done
[CONTROLLER_ONERETURNVALUE] = BtlController_Empty, // done
[CONTROLLER_ONERETURNVALUE_DUPLICATE] = BtlController_Empty, // done
[CONTROLLER_CLEARUNKVAR] = BtlController_HandleClearUnkVar, // done
[CONTROLLER_SETUNKVAR] = BtlController_HandleSetUnkVar, // done
[CONTROLLER_CLEARUNKFLAG] = BtlController_HandleClearUnkFlag, // done
[CONTROLLER_TOGGLEUNKFLAG] = BtlController_HandleToggleUnkFlag, // done
[CONTROLLER_HITANIMATION] = BtlController_HandleHitAnimation, // done
[CONTROLLER_CANTSWITCH] = BtlController_Empty, // done
[CONTROLLER_PLAYSE] = BtlController_HandlePlaySE, // done
[CONTROLLER_PLAYFANFAREORBGM] = BtlController_HandlePlayFanfareOrBGM, // done
[CONTROLLER_FAINTINGCRY] = BtlController_HandleFaintingCry, // done
[CONTROLLER_INTROSLIDE] = BtlController_HandleIntroSlide, // done
[CONTROLLER_INTROTRAINERBALLTHROW] = OpponentHandleIntroTrainerBallThrow, // done
[CONTROLLER_DRAWPARTYSTATUSSUMMARY] = OpponentHandleDrawPartyStatusSummary, // done
[CONTROLLER_HIDEPARTYSTATUSSUMMARY] = BtlController_HandleHidePartyStatusSummary, // done
[CONTROLLER_ENDBOUNCE] = BtlController_Empty, // done
[CONTROLLER_SPRITEINVISIBILITY] = BtlController_HandleSpriteInvisibility, // done
[CONTROLLER_BATTLEANIMATION] = OpponentHandleBattleAnimation, // done
[CONTROLLER_LINKSTANDBYMSG] = BtlController_Empty, // done
[CONTROLLER_RESETACTIONMOVESELECTION] = BtlController_Empty, // done
[CONTROLLER_ENDLINKBATTLE] = OpponentHandleEndLinkBattle, // done
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData,
[CONTROLLER_GETRAWMONDATA] = BtlController_HandleGetRawMonData,
[CONTROLLER_SETMONDATA] = BtlController_HandleSetMonData,
[CONTROLLER_SETRAWMONDATA] = BtlController_HandleSetRawMonData,
[CONTROLLER_LOADMONSPRITE] = OpponentHandleLoadMonSprite,
[CONTROLLER_SWITCHINANIM] = OpponentHandleSwitchInAnim,
[CONTROLLER_RETURNMONTOBALL] = BtlController_HandleReturnMonToBall,
[CONTROLLER_DRAWTRAINERPIC] = OpponentHandleDrawTrainerPic,
[CONTROLLER_TRAINERSLIDE] = OpponentHandleTrainerSlide,
[CONTROLLER_TRAINERSLIDEBACK] = OpponentHandleTrainerSlideBack,
[CONTROLLER_FAINTANIMATION] = BtlController_HandleFaintAnimation,
[CONTROLLER_PALETTEFADE] = BtlController_Empty,
[CONTROLLER_SUCCESSBALLTHROWANIM] = BtlController_Empty,
[CONTROLLER_BALLTHROWANIM] = BtlController_Empty,
[CONTROLLER_PAUSE] = BtlController_Empty,
[CONTROLLER_MOVEANIMATION] = OpponentHandleMoveAnimation,
[CONTROLLER_PRINTSTRING] = OpponentHandlePrintString,
[CONTROLLER_PRINTSTRINGPLAYERONLY] = BtlController_Empty,
[CONTROLLER_CHOOSEACTION] = OpponentHandleChooseAction,
[CONTROLLER_YESNOBOX] = BtlController_Empty,
[CONTROLLER_CHOOSEMOVE] = OpponentHandleChooseMove,
[CONTROLLER_OPENBAG] = OpponentHandleChooseItem,
[CONTROLLER_CHOOSEPOKEMON] = OpponentHandleChoosePokemon,
[CONTROLLER_23] = BtlController_Empty,
[CONTROLLER_HEALTHBARUPDATE] = OpponentHandleHealthBarUpdate,
[CONTROLLER_EXPUPDATE] = BtlController_Empty,
[CONTROLLER_STATUSICONUPDATE] = BtlController_HandleStatusIconUpdate,
[CONTROLLER_STATUSANIMATION] = BtlController_HandleStatusAnimation,
[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_HandleClearUnkVar,
[CONTROLLER_SETUNKVAR] = BtlController_HandleSetUnkVar,
[CONTROLLER_CLEARUNKFLAG] = BtlController_HandleClearUnkFlag,
[CONTROLLER_TOGGLEUNKFLAG] = BtlController_HandleToggleUnkFlag,
[CONTROLLER_HITANIMATION] = BtlController_HandleHitAnimation,
[CONTROLLER_CANTSWITCH] = BtlController_Empty,
[CONTROLLER_PLAYSE] = BtlController_HandlePlaySE,
[CONTROLLER_PLAYFANFAREORBGM] = BtlController_HandlePlayFanfareOrBGM,
[CONTROLLER_FAINTINGCRY] = BtlController_HandleFaintingCry,
[CONTROLLER_INTROSLIDE] = BtlController_HandleIntroSlide,
[CONTROLLER_INTROTRAINERBALLTHROW] = OpponentHandleIntroTrainerBallThrow,
[CONTROLLER_DRAWPARTYSTATUSSUMMARY] = OpponentHandleDrawPartyStatusSummary,
[CONTROLLER_HIDEPARTYSTATUSSUMMARY] = BtlController_HandleHidePartyStatusSummary,
[CONTROLLER_ENDBOUNCE] = BtlController_Empty,
[CONTROLLER_SPRITEINVISIBILITY] = BtlController_HandleSpriteInvisibility,
[CONTROLLER_BATTLEANIMATION] = OpponentHandleBattleAnimation,
[CONTROLLER_LINKSTANDBYMSG] = BtlController_Empty,
[CONTROLLER_RESETACTIONMOVESELECTION] = BtlController_Empty,
[CONTROLLER_ENDLINKBATTLE] = OpponentHandleEndLinkBattle,
[CONTROLLER_DEBUGMENU] = BtlController_Empty,
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop // done
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop
};
void SetControllerToOpponent(u32 battler)
@@ -117,9 +128,9 @@ void SetControllerToOpponent(u32 battler)
static void OpponentBufferRunCommand(u32 battler)
{
if (gBattleControllerExecFlags & gBitTable[battler])
if (gBattleControllerExecFlags & (1u << battler))
{
if (gBattleResources->bufferA[battler][0] < NELEMS(sOpponentBufferCommands))
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sOpponentBufferCommands))
sOpponentBufferCommands[gBattleResources->bufferA[battler][0]](battler);
else
OpponentBufferExecCompleted(battler);
@@ -170,7 +181,9 @@ static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
}
else
{
return;
}
}
else if (gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim)
{
@@ -183,13 +196,17 @@ static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
}
else
{
return;
}
}
gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
}
else
{
return;
}
gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 3;
gBattlerControllerFuncs[battler] = Intro_DelayAndEnd;
@@ -259,7 +276,9 @@ static void Intro_TryShinyAnimShowHealthbox(u32 battler)
m4aMPlayContinue(&gMPlayInfo_BGM);
}
else
{
m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100);
}
}
gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored = TRUE;
bgmRestored = TRUE;
@@ -337,8 +356,12 @@ static void SwitchIn_HandleSoundAndEnd(u32 battler)
{
if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive && !IsCryPlayingOrClearCrySongs())
{
m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100);
OpponentBufferExecCompleted(battler);
if (gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy
|| gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy_2)
{
m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100);
OpponentBufferExecCompleted(battler);
}
}
}
@@ -362,14 +385,12 @@ static void SwitchIn_ShowHealthbox(u32 battler)
static void SwitchIn_TryShinyAnim(u32 battler)
{
if (!gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive
&& !gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim)
{
if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim
&& !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive)
TryShinyAnimation(battler, &gEnemyParty[gBattlerPartyIndexes[battler]]);
}
if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy
&& !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive)
&& !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive)
{
DestroySprite(&gSprites[gBattleControllerData[battler]]);
SetBattlerShadowSpriteCallback(battler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES));
@@ -389,7 +410,7 @@ void OpponentBufferExecCompleted(u32 battler)
}
else
{
gBattleControllerExecFlags &= ~gBitTable[battler];
gBattleControllerExecFlags &= ~(1u << battler);
}
}
@@ -404,11 +425,11 @@ static void OpponentHandleSwitchInAnim(u32 battler)
BtlController_HandleSwitchInAnim(battler, FALSE, SwitchIn_TryShinyAnim);
}
static u32 OpponentGetTrainerPicId(u32 battlerId) // TODO: trainer refactoring
static u32 OpponentGetTrainerPicId(u32 battlerId)
{
u32 trainerPicId;
if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER)
if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
{
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_TOWER_LINK_MULTI))
{
@@ -423,9 +444,13 @@ static u32 OpponentGetTrainerPicId(u32 battlerId) // TODO: trainer refactoring
}
}
else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_TOWER)
{
trainerPicId = GetTrainerTowerTrainerFrontSpriteId();
}
else if (gBattleTypeFlags & BATTLE_TYPE_EREADER_TRAINER)
{
trainerPicId = GetEreaderTrainerFrontSpriteId();
}
else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
{
if (battlerId != 1)
@@ -434,7 +459,9 @@ static u32 OpponentGetTrainerPicId(u32 battlerId) // TODO: trainer refactoring
trainerPicId = GetTrainerPicFromId(gTrainerBattleOpponent_A);
}
else
{
trainerPicId = GetTrainerPicFromId(gTrainerBattleOpponent_A);
}
return trainerPicId;
}
@@ -470,6 +497,16 @@ static void OpponentHandleTrainerSlideBack(u32 battler)
BtlController_HandleTrainerSlideBack(battler, 35, FALSE);
}
static void OpponentHandleMoveAnimation(u32 battler)
{
BtlController_HandleMoveAnimation(battler);
}
static void OpponentHandlePrintString(u32 battler)
{
BtlController_HandlePrintString(battler);
}
static void OpponentHandleChooseAction(u32 battler)
{
AI_TrySwitchOrUseItem(battler);
@@ -484,43 +521,50 @@ static void OpponentHandleChooseMove(u32 battler)
if (gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_SAFARI | BATTLE_TYPE_ROAMER)
|| IsWildMonSmart())
{
chosenMoveId = gBattleStruct->aiMoveOrAction[battler];
gBattlerTarget = gBattleStruct->aiChosenTarget[battler];
switch (chosenMoveId)
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
{
case AI_CHOICE_WATCH:
BtlController_EmitTwoReturnValues(battler, BUFFER_B, B_ACTION_SAFARI_WATCH_CAREFULLY, 0);
break;
case AI_CHOICE_FLEE:
BtlController_EmitTwoReturnValues(battler, BUFFER_B, B_ACTION_RUN, 0);
break;
case 6:
BtlController_EmitTwoReturnValues(battler, BUFFER_B, 15, gBattlerTarget);
break;
default:
// BtlController_EmitTwoReturnValues(battler, BUFFER_B, 10, ChooseMoveAndTargetInBattlePalace(battler));
}
else
{
chosenMoveId = gBattleStruct->aiMoveOrAction[battler];
gBattlerTarget = gBattleStruct->aiChosenTarget[battler];
switch (chosenMoveId)
{
u16 chosenMove = moveInfo->moves[chosenMoveId];
if (GetBattlerMoveTargetType(battler, chosenMove) & (MOVE_TARGET_USER_OR_SELECTED | MOVE_TARGET_USER))
gBattlerTarget = battler;
if (GetBattlerMoveTargetType(battler, chosenMove) & MOVE_TARGET_BOTH)
case AI_CHOICE_WATCH:
BtlController_EmitTwoReturnValues(battler, BUFFER_B, B_ACTION_SAFARI_WATCH_CAREFULLY, 0);
break;
case AI_CHOICE_FLEE:
BtlController_EmitTwoReturnValues(battler, BUFFER_B, B_ACTION_RUN, 0);
break;
case 6:
BtlController_EmitTwoReturnValues(battler, BUFFER_B, 15, gBattlerTarget);
break;
default:
{
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
if (gAbsentBattlerFlags & (1u << gBattlerTarget))
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
}
// If opponent can and should use a gimmick (considering trainer data), do it
if (gBattleStruct->gimmick.usableGimmick[battler] != GIMMICK_NONE
&& !(gBattleStruct->gimmick.usableGimmick[battler] == GIMMICK_Z_MOVE
&& !ShouldUseZMove(battler, gBattlerTarget, moveInfo->moves[chosenMoveId])))
{
BtlController_EmitTwoReturnValues(battler, BUFFER_B, 10, (chosenMoveId) | (RET_GIMMICK) | (gBattlerTarget << 8));
}
else
{
BtlController_EmitTwoReturnValues(battler, BUFFER_B, 10, (chosenMoveId) | (gBattlerTarget << 8));
u16 chosenMove = moveInfo->moves[chosenMoveId];
if (GetBattlerMoveTargetType(battler, chosenMove) & (MOVE_TARGET_USER_OR_SELECTED | MOVE_TARGET_USER))
gBattlerTarget = battler;
if (GetBattlerMoveTargetType(battler, chosenMove) & MOVE_TARGET_BOTH)
{
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
if (gAbsentBattlerFlags & (1u << gBattlerTarget))
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
}
// If opponent can and should use a gimmick (considering trainer data), do it
if (gBattleStruct->gimmick.usableGimmick[battler] != GIMMICK_NONE
&& !(gBattleStruct->gimmick.usableGimmick[battler] == GIMMICK_Z_MOVE
&& !ShouldUseZMove(battler, gBattlerTarget, moveInfo->moves[chosenMoveId])))
{
BtlController_EmitTwoReturnValues(battler, BUFFER_B, 10, (chosenMoveId) | (RET_GIMMICK) | (gBattlerTarget << 8));
}
else
{
BtlController_EmitTwoReturnValues(battler, BUFFER_B, 10, (chosenMoveId) | (gBattlerTarget << 8));
}
}
break;
}
break;
}
OpponentBufferExecCompleted(battler);
}
@@ -543,7 +587,7 @@ static void OpponentHandleChooseMove(u32 battler)
} while (!CanTargetBattler(battler, target, move));
// Don't bother to loop through table if the move can't attack ally
if (B_WILD_NATURAL_ENEMIES == TRUE && !(gMovesInfo[move].target & MOVE_TARGET_BOTH))
if (B_WILD_NATURAL_ENEMIES == TRUE && !(GetBattlerMoveTargetType(battler, move) & MOVE_TARGET_BOTH))
{
u16 i, speciesAttacker, speciesTarget, isPartnerEnemy = FALSE;
static const u16 naturalEnemies[][2] =
@@ -590,6 +634,22 @@ static void OpponentHandleChooseItem(u32 battler)
OpponentBufferExecCompleted(battler);
}
static inline bool32 IsAcePokemon(u32 chosenMonId, u32 pokemonInBattle, u32 battler)
{
return AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_ACE_POKEMON
&& (chosenMonId == CalculateEnemyPartyCountInSide(battler) - 1)
&& CountAIAliveNonEggMonsExcept(PARTY_SIZE) != pokemonInBattle;
}
static inline bool32 IsDoubleAcePokemon(u32 chosenMonId, u32 pokemonInBattle, u32 battler)
{
return AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_DOUBLE_ACE_POKEMON
&& (chosenMonId == CalculateEnemyPartyCountInSide(battler) - 1)
&& (chosenMonId == CalculateEnemyPartyCountInSide(battler) - 2)
&& CountAIAliveNonEggMonsExcept(PARTY_SIZE) != pokemonInBattle
&& CountAIAliveNonEggMonsExcept(PARTY_SIZE-1) != pokemonInBattle;
}
static void OpponentHandleChoosePokemon(u32 battler)
{
s32 chosenMonId;
@@ -601,14 +661,14 @@ static void OpponentHandleChoosePokemon(u32 battler)
chosenMonId = gSelectedMonPartyId = GetFirstFaintedPartyIndex(battler);
}
// Switching out
else if (*(gBattleStruct->AI_monToSwitchIntoId + battler) == PARTY_SIZE)
else if (gBattleStruct->AI_monToSwitchIntoId[battler] == PARTY_SIZE)
{
chosenMonId = GetMostSuitableMonToSwitchInto(battler, TRUE);
if (chosenMonId == PARTY_SIZE)
{
s32 battler1, battler2, firstId, lastId;
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
if (!IsDoubleBattle())
{
battler2 = battler1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
}
@@ -620,27 +680,25 @@ static void OpponentHandleChoosePokemon(u32 battler)
}
GetAIPartyIndexes(battler, &firstId, &lastId);
for (chosenMonId = (lastId-1); chosenMonId >= firstId; chosenMonId--)
{
if (IsValidForBattle(&gEnemyParty[chosenMonId])
&& chosenMonId != gBattlerPartyIndexes[battler1]
&& chosenMonId != gBattlerPartyIndexes[battler2]
&& (!(AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_ACE_POKEMON)
|| chosenMonId != CalculateEnemyPartyCount() - 1
|| CountAIAliveNonEggMonsExcept(PARTY_SIZE) == pokemonInBattle))
{
if (!IsValidForBattle(&gEnemyParty[chosenMonId])
|| chosenMonId == gBattlerPartyIndexes[battler1]
|| chosenMonId == gBattlerPartyIndexes[battler2])
continue;
if (!IsAcePokemon(chosenMonId, pokemonInBattle, battler)
&& !IsDoubleAcePokemon(chosenMonId, pokemonInBattle, battler))
break;
}
}
}
*(gBattleStruct->monToSwitchIntoId + battler) = chosenMonId;
gBattleStruct->monToSwitchIntoId[battler] = chosenMonId;
}
else
{
chosenMonId = *(gBattleStruct->AI_monToSwitchIntoId + battler);
*(gBattleStruct->AI_monToSwitchIntoId + battler) = PARTY_SIZE;
*(gBattleStruct->monToSwitchIntoId + battler) = chosenMonId;
chosenMonId = gBattleStruct->AI_monToSwitchIntoId[battler];
gBattleStruct->AI_monToSwitchIntoId[battler] = PARTY_SIZE;
gBattleStruct->monToSwitchIntoId[battler] = chosenMonId;
}
#if TESTING
TestRunner_Battle_CheckSwitch(battler, chosenMonId);

File diff suppressed because it is too large Load Diff

View File

@@ -36,6 +36,8 @@ static void PlayerPartnerHandleLoadMonSprite(u32 battler);
static void PlayerPartnerHandleSwitchInAnim(u32 battler);
static void PlayerPartnerHandleDrawTrainerPic(u32 battler);
static void PlayerPartnerHandleTrainerSlideBack(u32 battler);
static void PlayerPartnerHandleMoveAnimation(u32 battler);
static void PlayerPartnerHandlePrintString(u32 battler);
static void PlayerPartnerHandleChooseAction(u32 battler);
static void PlayerPartnerHandleChooseMove(u32 battler);
static void PlayerPartnerHandleChoosePokemon(u32 battler);
@@ -66,11 +68,11 @@ static void (*const sPlayerPartnerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 bat
[CONTROLLER_SUCCESSBALLTHROWANIM] = BtlController_Empty,
[CONTROLLER_BALLTHROWANIM] = BtlController_Empty,
[CONTROLLER_PAUSE] = BtlController_Empty,
[CONTROLLER_MOVEANIMATION] = BtlController_HandleMoveAnimation,
[CONTROLLER_PRINTSTRING] = BtlController_HandlePrintString,
[CONTROLLER_MOVEANIMATION] = PlayerPartnerHandleMoveAnimation,
[CONTROLLER_PRINTSTRING] = PlayerPartnerHandlePrintString,
[CONTROLLER_PRINTSTRINGPLAYERONLY] = BtlController_Empty,
[CONTROLLER_CHOOSEACTION] = PlayerPartnerHandleChooseAction,
[CONTROLLER_UNKNOWNYESNOBOX] = BtlController_Empty,
[CONTROLLER_YESNOBOX] = BtlController_Empty,
[CONTROLLER_CHOOSEMOVE] = PlayerPartnerHandleChooseMove,
[CONTROLLER_OPENBAG] = BtlController_Empty,
[CONTROLLER_CHOOSEPOKEMON] = PlayerPartnerHandleChoosePokemon,
@@ -119,7 +121,7 @@ void SetControllerToPlayerPartner(u32 battler)
static void PlayerPartnerBufferRunCommand(u32 battler)
{
if (gBattleControllerExecFlags & gBitTable[battler])
if (gBattleControllerExecFlags & (1u << battler))
{
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sPlayerPartnerBufferCommands))
sPlayerPartnerBufferCommands[gBattleResources->bufferA[battler][0]](battler);
@@ -272,7 +274,7 @@ static void PlayerPartnerBufferExecCompleted(u32 battler)
}
else
{
gBattleControllerExecFlags &= ~gBitTable[battler];
gBattleControllerExecFlags &= ~(1u << battler);
}
}
@@ -328,6 +330,16 @@ static void PlayerPartnerHandleTrainerSlideBack(u32 battler)
BtlController_HandleTrainerSlideBack(battler, 35, FALSE);
}
static void PlayerPartnerHandleMoveAnimation(u32 battler)
{
BtlController_HandleMoveAnimation(battler);
}
static void PlayerPartnerHandlePrintString(u32 battler)
{
BtlController_HandlePrintString(battler);
}
static void PlayerPartnerHandleChooseAction(u32 battler)
{
AI_TrySwitchOrUseItem(battler);
@@ -341,10 +353,11 @@ static void PlayerPartnerHandleChooseMove(u32 battler)
chosenMoveId = gBattleStruct->aiMoveOrAction[battler];
gBattlerTarget = gBattleStruct->aiChosenTarget[battler];
u32 moveTarget = GetBattlerMoveTargetType(battler, moveInfo->moves[chosenMoveId]);
if (gMovesInfo[moveInfo->moves[chosenMoveId]].target & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED))
if (moveTarget & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED))
gBattlerTarget = battler;
else if (gMovesInfo[moveInfo->moves[chosenMoveId]].target & MOVE_TARGET_BOTH)
else if (moveTarget & MOVE_TARGET_BOTH)
{
gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
if (gAbsentBattlerFlags & (1u << gBattlerTarget))
@@ -365,7 +378,6 @@ static void PlayerPartnerHandleChooseMove(u32 battler)
PlayerPartnerBufferExecCompleted(battler);
}
static void PlayerPartnerHandleChoosePokemon(u32 battler)
{
s32 chosenMonId;
@@ -419,9 +431,9 @@ static void PlayerPartnerHandleIntroTrainerBallThrow(u32 battler)
if (gPartnerTrainerId > TRAINER_PARTNER(PARTNER_NONE))
trainerPal = gTrainerBacksprites[gBattlePartners[gPartnerTrainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerPic].palette.data;
else if (IsAiVsAiBattle())
trainerPal = gTrainerBacksprites[GetTrainerPicFromId(gPartnerTrainerId)].palette.data;
trainerPal = gTrainerSprites[GetTrainerPicFromId(gPartnerTrainerId)].palette.data;
else
trainerPal = gTrainerBacksprites[GetBattleTowerTrainerFrontSpriteId(gPartnerTrainerId)].palette.data; // 2 vs 2 multi battle in Battle Frontier, load front sprite and pal.
trainerPal = gTrainerSprites[GetBattleTowerTrainerFrontSpriteId(gPartnerTrainerId)].palette.data; // 2 vs 2 multi battle in Battle Frontier, load front sprite and pal.
BtlController_HandleIntroTrainerBallThrow(battler, 0xD6F9, trainerPal, 24, Controller_PlayerPartnerShowIntroHealthbox, StartAnimLinearTranslation);
}

View File

@@ -76,64 +76,64 @@ static const u8 *GetPokedudeText(void);
static void (*const sPokedudeBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
{
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData, // done
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty, // done
[CONTROLLER_SETMONDATA] = BtlController_HandleSetMonData, // done
[CONTROLLER_SETRAWMONDATA] = BtlController_Empty, // done
[CONTROLLER_LOADMONSPRITE] = PokedudeHandleLoadMonSprite, // done
[CONTROLLER_SWITCHINANIM] = PokedudeHandleSwitchInAnim, // done
[CONTROLLER_RETURNMONTOBALL] = BtlController_HandleReturnMonToBall, // done
[CONTROLLER_DRAWTRAINERPIC] = PokedudeHandleDrawTrainerPic, // done
[CONTROLLER_TRAINERSLIDE] = PokedudeHandleTrainerSlide, // done
[CONTROLLER_TRAINERSLIDEBACK] = BtlController_Empty, // done
[CONTROLLER_FAINTANIMATION] = BtlController_HandleFaintAnimation, // done
[CONTROLLER_PALETTEFADE] = BtlController_Empty, // done
[CONTROLLER_SUCCESSBALLTHROWANIM] = PokedudeHandleSuccessBallThrowAnim, // done
[CONTROLLER_BALLTHROWANIM] = PokedudeHandleBallThrowAnim, // done
[CONTROLLER_PAUSE] = BtlController_Empty, // done
[CONTROLLER_MOVEANIMATION] = BtlController_HandleMoveAnimation, // done
[CONTROLLER_PRINTSTRING] = BtlController_HandlePrintString, // done
[CONTROLLER_PRINTSTRINGPLAYERONLY] = PokedudeHandlePrintSelectionString, // done
[CONTROLLER_CHOOSEACTION] = PokedudeHandleChooseAction, // done
[CONTROLLER_UNKNOWNYESNOBOX] = BtlController_Empty, // done
[CONTROLLER_CHOOSEMOVE] = PokedudeHandleChooseMove, // done
[CONTROLLER_OPENBAG] = PokedudeHandleChooseItem, // done
[CONTROLLER_CHOOSEPOKEMON] = PokedudeHandleChoosePokemon, // done
[CONTROLLER_23] = BtlController_Empty, // done
[CONTROLLER_HEALTHBARUPDATE] = PokedudeHandleHealthBarUpdate, // done
[CONTROLLER_EXPUPDATE] = PlayerHandleExpUpdate, // done
[CONTROLLER_STATUSICONUPDATE] = BtlController_HandleStatusIconUpdate, // done
[CONTROLLER_STATUSANIMATION] = BtlController_HandleStatusAnimation, // done
[CONTROLLER_STATUSXOR] = PokedudeHandleStatusXor, // done
[CONTROLLER_DATATRANSFER] = BtlController_Empty, // done
[CONTROLLER_DMA3TRANSFER] = BtlController_Empty, // done
[CONTROLLER_PLAYBGM] = BtlController_Empty, // done
[CONTROLLER_32] = BtlController_Empty, // done
[CONTROLLER_TWORETURNVALUES] = BtlController_Empty, // done
[CONTROLLER_CHOSENMONRETURNVALUE] = BtlController_Empty, // done
[CONTROLLER_ONERETURNVALUE] = BtlController_Empty, // done
[CONTROLLER_ONERETURNVALUE_DUPLICATE] = BtlController_Empty, // done
[CONTROLLER_CLEARUNKVAR] = BtlController_Empty, // done
[CONTROLLER_SETUNKVAR] = BtlController_Empty, // done
[CONTROLLER_CLEARUNKFLAG] = BtlController_Empty, // done
[CONTROLLER_TOGGLEUNKFLAG] = BtlController_Empty, // done
[CONTROLLER_HITANIMATION] = BtlController_HandleHitAnimation, // done
[CONTROLLER_CANTSWITCH] = BtlController_Empty, // done
[CONTROLLER_PLAYSE] = PokedudeHandlePlaySE, // done
[CONTROLLER_PLAYFANFAREORBGM] = BtlController_HandlePlayFanfareOrBGM, // done
[CONTROLLER_FAINTINGCRY] = BtlController_HandleFaintingCry, // done
[CONTROLLER_INTROSLIDE] = BtlController_HandleIntroSlide, // done
[CONTROLLER_INTROTRAINERBALLTHROW] = PokedudeHandleIntroTrainerBallThrow, // done
[CONTROLLER_DRAWPARTYSTATUSSUMMARY] = PokedudeHandleDrawPartyStatusSummary, // done
[CONTROLLER_HIDEPARTYSTATUSSUMMARY] = BtlController_Empty, // done
[CONTROLLER_ENDBOUNCE] = PokedudeHandleEndBounceEffect, // done
[CONTROLLER_SPRITEINVISIBILITY] = BtlController_Empty, // done
[CONTROLLER_BATTLEANIMATION] = PokedudeHandleBattleAnimation, // done
[CONTROLLER_LINKSTANDBYMSG] = PokedudeHandleLinkStandbyMsg, // done
[CONTROLLER_RESETACTIONMOVESELECTION] = BtlController_Empty, // done
[CONTROLLER_ENDLINKBATTLE] = PokedudeHandleEndLinkBattle, // done
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData,
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty,
[CONTROLLER_SETMONDATA] = BtlController_HandleSetMonData,
[CONTROLLER_SETRAWMONDATA] = BtlController_Empty,
[CONTROLLER_LOADMONSPRITE] = PokedudeHandleLoadMonSprite,
[CONTROLLER_SWITCHINANIM] = PokedudeHandleSwitchInAnim,
[CONTROLLER_RETURNMONTOBALL] = BtlController_HandleReturnMonToBall,
[CONTROLLER_DRAWTRAINERPIC] = PokedudeHandleDrawTrainerPic,
[CONTROLLER_TRAINERSLIDE] = PokedudeHandleTrainerSlide,
[CONTROLLER_TRAINERSLIDEBACK] = BtlController_Empty,
[CONTROLLER_FAINTANIMATION] = BtlController_HandleFaintAnimation,
[CONTROLLER_PALETTEFADE] = BtlController_Empty,
[CONTROLLER_SUCCESSBALLTHROWANIM] = PokedudeHandleSuccessBallThrowAnim,
[CONTROLLER_BALLTHROWANIM] = PokedudeHandleBallThrowAnim,
[CONTROLLER_PAUSE] = BtlController_Empty,
[CONTROLLER_MOVEANIMATION] = BtlController_HandleMoveAnimation,
[CONTROLLER_PRINTSTRING] = BtlController_HandlePrintString,
[CONTROLLER_PRINTSTRINGPLAYERONLY] = PokedudeHandlePrintSelectionString,
[CONTROLLER_CHOOSEACTION] = PokedudeHandleChooseAction,
[CONTROLLER_YESNOBOX] = BtlController_Empty,
[CONTROLLER_CHOOSEMOVE] = PokedudeHandleChooseMove,
[CONTROLLER_OPENBAG] = PokedudeHandleChooseItem,
[CONTROLLER_CHOOSEPOKEMON] = PokedudeHandleChoosePokemon,
[CONTROLLER_23] = BtlController_Empty,
[CONTROLLER_HEALTHBARUPDATE] = PokedudeHandleHealthBarUpdate,
[CONTROLLER_EXPUPDATE] = PlayerHandleExpUpdate,
[CONTROLLER_STATUSICONUPDATE] = BtlController_HandleStatusIconUpdate,
[CONTROLLER_STATUSANIMATION] = BtlController_HandleStatusAnimation,
[CONTROLLER_STATUSXOR] = PokedudeHandleStatusXor,
[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_HandleHitAnimation,
[CONTROLLER_CANTSWITCH] = BtlController_Empty,
[CONTROLLER_PLAYSE] = PokedudeHandlePlaySE,
[CONTROLLER_PLAYFANFAREORBGM] = BtlController_HandlePlayFanfareOrBGM,
[CONTROLLER_FAINTINGCRY] = BtlController_HandleFaintingCry,
[CONTROLLER_INTROSLIDE] = BtlController_HandleIntroSlide,
[CONTROLLER_INTROTRAINERBALLTHROW] = PokedudeHandleIntroTrainerBallThrow,
[CONTROLLER_DRAWPARTYSTATUSSUMMARY] = PokedudeHandleDrawPartyStatusSummary,
[CONTROLLER_HIDEPARTYSTATUSSUMMARY] = BtlController_Empty,
[CONTROLLER_ENDBOUNCE] = PokedudeHandleEndBounceEffect,
[CONTROLLER_SPRITEINVISIBILITY] = BtlController_Empty,
[CONTROLLER_BATTLEANIMATION] = PokedudeHandleBattleAnimation,
[CONTROLLER_LINKSTANDBYMSG] = PokedudeHandleLinkStandbyMsg,
[CONTROLLER_RESETACTIONMOVESELECTION] = BtlController_Empty,
[CONTROLLER_ENDLINKBATTLE] = PokedudeHandleEndLinkBattle,
[CONTROLLER_DEBUGMENU] = BtlController_Empty,
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop, // done
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop,
};
#define pdHealthboxPal1 simulatedInputState[0]
@@ -151,9 +151,9 @@ void SetControllerToPokedude(u32 battler)
static void PokedudeBufferRunCommand(u32 battler)
{
if (gBattleControllerExecFlags & gBitTable[battler])
if (gBattleControllerExecFlags & (1u << battler))
{
if (gBattleResources->bufferA[battler][0] < NELEMS(sPokedudeBufferCommands))
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sPokedudeBufferCommands))
{
if (!HandlePokedudeVoiceoverEtc(battler))
sPokedudeBufferCommands[gBattleResources->bufferA[battler][0]](battler);
@@ -377,7 +377,7 @@ static void PokedudeBufferExecCompleted(u32 battler)
}
else
{
gBattleControllerExecFlags &= ~gBitTable[battler];
gBattleControllerExecFlags &= ~(1u << battler);
}
}
@@ -1219,7 +1219,7 @@ static void PokedudeAction_PrintMessageWithHealthboxPals(u32 battler)
case 1:
if (!gPaletteFade.active)
{
u32 mask = (gBitTable[gBattleStruct->pdHealthboxPal2] | gBitTable[gBattleStruct->pdHealthboxPal1]) << 16;
u32 mask = ((1u << gBattleStruct->pdHealthboxPal2) | (1u << gBattleStruct->pdHealthboxPal1)) << 16;
++mask; // It's possible that this is influenced by other functions, as
--mask; // this also striked in battle_controller_oak_old_man.c but was naturally fixed.
@@ -1245,7 +1245,7 @@ static void PokedudeAction_PrintMessageWithHealthboxPals(u32 battler)
u32 mask;
PlaySE(SE_SELECT);
mask = (gBitTable[gBattleStruct->pdHealthboxPal2] | gBitTable[gBattleStruct->pdHealthboxPal1]) << 16;
mask = ((1u << gBattleStruct->pdHealthboxPal2) | (1u << gBattleStruct->pdHealthboxPal1)) << 16;
++mask;
--mask;
BeginNormalPaletteFade(mask, 4, 0, 8, RGB_BLACK);

View File

@@ -74,7 +74,7 @@ static void (*const sRecordedOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(u32
[CONTROLLER_PRINTSTRING] = RecordedOpponentHandlePrintString,
[CONTROLLER_PRINTSTRINGPLAYERONLY] = BtlController_Empty,
[CONTROLLER_CHOOSEACTION] = RecordedOpponentHandleChooseAction,
[CONTROLLER_UNKNOWNYESNOBOX] = BtlController_Empty,
[CONTROLLER_YESNOBOX] = BtlController_Empty,
[CONTROLLER_CHOOSEMOVE] = RecordedOpponentHandleChooseMove,
[CONTROLLER_OPENBAG] = RecordedOpponentHandleChooseItem,
[CONTROLLER_CHOOSEPOKEMON] = RecordedOpponentHandleChoosePokemon,
@@ -460,9 +460,16 @@ static void RecordedOpponentHandleChooseAction(u32 battler)
static void RecordedOpponentHandleChooseMove(u32 battler)
{
u8 moveId = RecordedBattle_GetBattlerAction(RECORDED_MOVE_SLOT, battler);
u8 target = RecordedBattle_GetBattlerAction(RECORDED_MOVE_TARGET, battler);
BtlController_EmitTwoReturnValues(battler, BUFFER_B, 10, moveId | (target << 8));
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
{
// BtlController_EmitTwoReturnValues(battler, BUFFER_B, 10, ChooseMoveAndTargetInBattlePalace(battler));
}
else
{
u8 moveId = RecordedBattle_GetBattlerAction(RECORDED_MOVE_SLOT, battler);
u8 target = RecordedBattle_GetBattlerAction(RECORDED_MOVE_TARGET, battler);
BtlController_EmitTwoReturnValues(battler, BUFFER_B, 10, moveId | (target << 8));
}
RecordedOpponentBufferExecCompleted(battler);
}

View File

@@ -72,7 +72,7 @@ static void (*const sRecordedPlayerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 ba
[CONTROLLER_PRINTSTRING] = RecordedPlayerHandlePrintString,
[CONTROLLER_PRINTSTRINGPLAYERONLY] = BtlController_Empty,
[CONTROLLER_CHOOSEACTION] = RecordedPlayerHandleChooseAction,
[CONTROLLER_UNKNOWNYESNOBOX] = BtlController_Empty,
[CONTROLLER_YESNOBOX] = BtlController_Empty,
[CONTROLLER_CHOOSEMOVE] = RecordedPlayerHandleChooseMove,
[CONTROLLER_OPENBAG] = RecordedPlayerHandleChooseItem,
[CONTROLLER_CHOOSEPOKEMON] = RecordedPlayerHandleChoosePokemon,
@@ -121,7 +121,7 @@ void SetControllerToRecordedPlayer(u32 battler)
static void RecordedPlayerBufferRunCommand(u32 battler)
{
if (gBattleControllerExecFlags & gBitTable[battler])
if (gBattleControllerExecFlags & (1u << battler))
{
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sRecordedPlayerBufferCommands))
sRecordedPlayerBufferCommands[gBattleResources->bufferA[battler][0]](battler);
@@ -351,7 +351,7 @@ static void RecordedPlayerBufferExecCompleted(u32 battler)
}
else
{
gBattleControllerExecFlags &= ~gBitTable[battler];
gBattleControllerExecFlags &= ~(1u << battler);
}
}
@@ -430,17 +430,40 @@ static void RecordedPlayerHandlePrintString(u32 battler)
BtlController_HandlePrintString(battler);
}
// static void ChooseActionInBattlePalace(u32 battler)
// {
// if (gBattleCommunication[4] >= gBattlersCount / 2)
// {
// BtlController_EmitTwoReturnValues(battler, BUFFER_B, RecordedBattle_GetBattlerAction(RECORDED_BATTLE_PALACE_ACTION, battler), 0);
// RecordedPlayerBufferExecCompleted(battler);
// }
// }
static void RecordedPlayerHandleChooseAction(u32 battler)
{
BtlController_EmitTwoReturnValues(battler, BUFFER_B, RecordedBattle_GetBattlerAction(RECORDED_ACTION_TYPE, battler), 0);
RecordedPlayerBufferExecCompleted(battler);
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
{
// gBattlerControllerFuncs[battler] = ChooseActionInBattlePalace;
}
else
{
BtlController_EmitTwoReturnValues(battler, BUFFER_B, RecordedBattle_GetBattlerAction(RECORDED_ACTION_TYPE, battler), 0);
RecordedPlayerBufferExecCompleted(battler);
}
}
static void RecordedPlayerHandleChooseMove(u32 battler)
{
u8 moveId = RecordedBattle_GetBattlerAction(RECORDED_MOVE_SLOT, battler);
u8 target = RecordedBattle_GetBattlerAction(RECORDED_MOVE_TARGET, battler);
BtlController_EmitTwoReturnValues(battler, BUFFER_B, 10, moveId | (target << 8));
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
{
// BtlController_EmitTwoReturnValues(battler, BUFFER_B, 10, ChooseMoveAndTargetInBattlePalace(battler));
}
else
{
u8 moveId = RecordedBattle_GetBattlerAction(RECORDED_MOVE_SLOT, battler);
u8 target = RecordedBattle_GetBattlerAction(RECORDED_MOVE_TARGET, battler);
BtlController_EmitTwoReturnValues(battler, BUFFER_B, 10, moveId | (target << 8));
}
RecordedPlayerBufferExecCompleted(battler);
}

View File

@@ -1,23 +1,35 @@
#include "global.h"
#include "gflib.h"
#include "battle.h"
#include "battle_anim.h"
#include "battle_controllers.h"
#include "battle_interface.h"
#include "battle_message.h"
#include "bg.h"
#include "data.h"
#include "item_menu.h"
#include "link.h"
#include "main.h"
#include "m4a.h"
#include "palette.h"
#include "pokeball.h"
#include "util.h"
#include "pokemon.h"
#include "reshow_battle_screen.h"
#include "sound.h"
#include "strings.h"
#include "constants/songs.h"
#include "task.h"
#include "text.h"
#include "util.h"
#include "window.h"
#include "line_break.h"
#include "constants/battle_anim.h"
#include "constants/songs.h"
#include "constants/trainers.h"
#include "constants/rgb.h"
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);
@@ -33,64 +45,64 @@ static void CompleteWhenChosePokeblock(u32 battler);
static void (*const sSafariBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
{
[CONTROLLER_GETMONDATA] = BtlController_Empty, // done
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty, // done
[CONTROLLER_SETMONDATA] = BtlController_Empty, // done
[CONTROLLER_SETRAWMONDATA] = BtlController_Empty, // done
[CONTROLLER_LOADMONSPRITE] = BtlController_Empty, // done
[CONTROLLER_SWITCHINANIM] = BtlController_Empty, // done
[CONTROLLER_RETURNMONTOBALL] = BtlController_Empty, // done
[CONTROLLER_DRAWTRAINERPIC] = SafariHandleDrawTrainerPic, // done
[CONTROLLER_TRAINERSLIDE] = BtlController_Empty, // done
[CONTROLLER_TRAINERSLIDEBACK] = BtlController_Empty, // done
[CONTROLLER_FAINTANIMATION] = BtlController_Empty, // done
[CONTROLLER_PALETTEFADE] = BtlController_Empty, // done
[CONTROLLER_SUCCESSBALLTHROWANIM] = SafariHandleSuccessBallThrowAnim, // done
[CONTROLLER_BALLTHROWANIM] = SafariHandleBallThrowAnim, // done
[CONTROLLER_PAUSE] = BtlController_Empty, // done
[CONTROLLER_MOVEANIMATION] = BtlController_Empty, // done
[CONTROLLER_PRINTSTRING] = BtlController_HandlePrintString, // done
[CONTROLLER_PRINTSTRINGPLAYERONLY] = SafariHandlePrintSelectionString, // done
[CONTROLLER_CHOOSEACTION] = SafariHandleChooseAction, // done
[CONTROLLER_UNKNOWNYESNOBOX] = BtlController_Empty, // done
[CONTROLLER_CHOOSEMOVE] = BtlController_Empty, // done
[CONTROLLER_OPENBAG] = SafariHandleChooseItem, // done
[CONTROLLER_CHOOSEPOKEMON] = BtlController_Empty, // done
[CONTROLLER_23] = BtlController_Empty, // done
[CONTROLLER_HEALTHBARUPDATE] = BtlController_Empty, // done
[CONTROLLER_EXPUPDATE] = BtlController_Empty, // done
[CONTROLLER_STATUSICONUPDATE] = SafariHandleStatusIconUpdate, // done
[CONTROLLER_STATUSANIMATION] = BtlController_Empty, // done
[CONTROLLER_STATUSXOR] = BtlController_Empty, // done
[CONTROLLER_DATATRANSFER] = BtlController_Empty, // done
[CONTROLLER_DMA3TRANSFER] = BtlController_Empty, // done
[CONTROLLER_PLAYBGM] = BtlController_Empty, // done
[CONTROLLER_32] = BtlController_Empty, // done
[CONTROLLER_TWORETURNVALUES] = BtlController_Empty, // done
[CONTROLLER_CHOSENMONRETURNVALUE] = BtlController_Empty, // done
[CONTROLLER_ONERETURNVALUE] = BtlController_Empty, // done
[CONTROLLER_ONERETURNVALUE_DUPLICATE] = BtlController_Empty, // done
[CONTROLLER_CLEARUNKVAR] = BtlController_Empty, // done
[CONTROLLER_SETUNKVAR] = BtlController_Empty, // done
[CONTROLLER_CLEARUNKFLAG] = BtlController_Empty, // done
[CONTROLLER_TOGGLEUNKFLAG] = BtlController_Empty, // done
[CONTROLLER_HITANIMATION] = BtlController_Empty, // done
[CONTROLLER_CANTSWITCH] = BtlController_Empty, // done
[CONTROLLER_PLAYSE] = BtlController_HandlePlaySE, // done
[CONTROLLER_PLAYFANFAREORBGM] = BtlController_HandlePlayFanfareOrBGM, // done
[CONTROLLER_FAINTINGCRY] = SafariHandleFaintingCry, // done
[CONTROLLER_INTROSLIDE] = BtlController_HandleIntroSlide, // done
[CONTROLLER_INTROTRAINERBALLTHROW] = SafariHandleIntroTrainerBallThrow, // done
[CONTROLLER_DRAWPARTYSTATUSSUMMARY] = BtlController_Empty, // done
[CONTROLLER_HIDEPARTYSTATUSSUMMARY] = BtlController_Empty, // done
[CONTROLLER_ENDBOUNCE] = BtlController_Empty, // done
[CONTROLLER_SPRITEINVISIBILITY] = BtlController_Empty, // done
[CONTROLLER_BATTLEANIMATION] = SafariHandleBattleAnimation, // done
[CONTROLLER_LINKSTANDBYMSG] = BtlController_Empty, // done
[CONTROLLER_RESETACTIONMOVESELECTION] = BtlController_Empty, // done
[CONTROLLER_ENDLINKBATTLE] = SafariHandleEndLinkBattle, // done
[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] = BtlController_Empty,
[CONTROLLER_TRAINERSLIDEBACK] = BtlController_Empty,
[CONTROLLER_FAINTANIMATION] = BtlController_Empty,
[CONTROLLER_PALETTEFADE] = BtlController_Empty,
[CONTROLLER_SUCCESSBALLTHROWANIM] = SafariHandleSuccessBallThrowAnim,
[CONTROLLER_BALLTHROWANIM] = SafariHandleBallThrowAnim,
[CONTROLLER_PAUSE] = BtlController_Empty,
[CONTROLLER_MOVEANIMATION] = BtlController_Empty,
[CONTROLLER_PRINTSTRING] = SafariHandlePrintString,
[CONTROLLER_PRINTSTRINGPLAYERONLY] = SafariHandlePrintSelectionString,
[CONTROLLER_CHOOSEACTION] = SafariHandleChooseAction,
[CONTROLLER_YESNOBOX] = BtlController_Empty,
[CONTROLLER_CHOOSEMOVE] = BtlController_Empty,
[CONTROLLER_OPENBAG] = SafariHandleChooseItem,
[CONTROLLER_CHOOSEPOKEMON] = BtlController_Empty,
[CONTROLLER_23] = BtlController_Empty,
[CONTROLLER_HEALTHBARUPDATE] = BtlController_Empty,
[CONTROLLER_EXPUPDATE] = BtlController_Empty,
[CONTROLLER_STATUSICONUPDATE] = SafariHandleStatusIconUpdate,
[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] = BtlController_HandleIntroSlide,
[CONTROLLER_INTROTRAINERBALLTHROW] = SafariHandleIntroTrainerBallThrow,
[CONTROLLER_DRAWPARTYSTATUSSUMMARY] = BtlController_Empty,
[CONTROLLER_HIDEPARTYSTATUSSUMMARY] = BtlController_Empty,
[CONTROLLER_ENDBOUNCE] = BtlController_Empty,
[CONTROLLER_SPRITEINVISIBILITY] = BtlController_Empty,
[CONTROLLER_BATTLEANIMATION] = SafariHandleBattleAnimation,
[CONTROLLER_LINKSTANDBYMSG] = BtlController_Empty,
[CONTROLLER_RESETACTIONMOVESELECTION] = BtlController_Empty,
[CONTROLLER_ENDLINKBATTLE] = SafariHandleEndLinkBattle,
[CONTROLLER_DEBUGMENU] = BtlController_Empty,
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop, // done
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop
};
void SetControllerToSafari(u32 battler)
@@ -101,9 +113,9 @@ void SetControllerToSafari(u32 battler)
static void SafariBufferRunCommand(u32 battler)
{
if (gBattleControllerExecFlags & gBitTable[battler])
if (gBattleControllerExecFlags & (1u << battler))
{
if (gBattleResources->bufferA[battler][0] < NELEMS(sSafariBufferCommands))
if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sSafariBufferCommands))
sSafariBufferCommands[gBattleResources->bufferA[battler][0]](battler);
else
SafariBufferExecCompleted(battler);
@@ -119,16 +131,16 @@ static void HandleInputChooseAction(u32 battler)
switch (gActionSelectionCursor[battler])
{
case 0:
BtlController_EmitTwoReturnValues(battler, 1, B_ACTION_SAFARI_BALL, 0);
BtlController_EmitTwoReturnValues(battler, BUFFER_B, B_ACTION_SAFARI_BALL, 0);
break;
case 1:
BtlController_EmitTwoReturnValues(battler, 1, B_ACTION_SAFARI_BAIT, 0);
BtlController_EmitTwoReturnValues(battler, BUFFER_B, B_ACTION_SAFARI_BAIT, 0);
break;
case 2:
BtlController_EmitTwoReturnValues(battler, 1, B_ACTION_SAFARI_GO_NEAR, 0);
BtlController_EmitTwoReturnValues(battler, BUFFER_B, B_ACTION_SAFARI_GO_NEAR, 0);
break;
case 3:
BtlController_EmitTwoReturnValues(battler, 1, B_ACTION_SAFARI_RUN, 0);
BtlController_EmitTwoReturnValues(battler, BUFFER_B, B_ACTION_SAFARI_RUN, 0);
break;
}
SafariBufferExecCompleted(battler);
@@ -188,7 +200,7 @@ static void Controller_WaitForHealthbox(u32 battler)
SafariBufferExecCompleted(battler);
}
static void Safari_SetBattleEndCallbacks(u32 battler)
static void SafariSetBattleEndCallbacks(u32 battler)
{
if (!gPaletteFade.active)
{
@@ -201,14 +213,16 @@ static void Safari_SetBattleEndCallbacks(u32 battler)
static void SafariOpenPokeblockCase(u32 battler)
{
if (!gPaletteFade.active)
{
gBattlerControllerFuncs[battler] = CompleteWhenChosePokeblock;
}
}
static void CompleteWhenChosePokeblock(u32 battler)
{
if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active)
{
BtlController_EmitOneReturnValue(battler, 1, gSpecialVar_ItemId);
BtlController_EmitOneReturnValue(battler, BUFFER_B, gSpecialVar_ItemId);
SafariBufferExecCompleted(battler);
}
}
@@ -225,7 +239,7 @@ static void SafariBufferExecCompleted(u32 battler)
}
else
{
gBattleControllerExecFlags &= ~gBitTable[battler];
gBattleControllerExecFlags &= ~(1u << battler);
}
}
@@ -248,10 +262,15 @@ static void SafariHandleBallThrowAnim(u32 battler)
BtlController_HandleBallThrowAnim(battler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW_WITH_TRAINER, FALSE);
}
static void SafariHandlePrintString(u32 battler)
{
BtlController_HandlePrintString(battler);
}
static void SafariHandlePrintSelectionString(u32 battler)
{
if (GetBattlerSide(battler) == B_SIDE_PLAYER)
BtlController_HandlePrintString(battler);
SafariHandlePrintString(battler);
else
SafariBufferExecCompleted(battler);
}
@@ -261,7 +280,7 @@ static void HandleChooseActionAfterDma3(u32 battler)
if (!IsDma3ManagerBusyWithBgCopy())
{
gBattle_BG0_X = 0;
gBattle_BG0_Y = 160;
gBattle_BG0_Y = DISPLAY_HEIGHT;
gBattlerControllerFuncs[battler] = HandleInputChooseAction;
}
}
@@ -273,10 +292,13 @@ static void SafariHandleChooseAction(u32 battler)
gBattlerControllerFuncs[battler] = HandleChooseActionAfterDma3;
BattlePutTextOnWindow(gText_EmptyString3, B_WIN_MSG);
BattlePutTextOnWindow(gText_SafariZoneMenu, B_WIN_ACTION_MENU);
for (i = 0; i < 4; ++i)
for (i = 0; i < 4; i++)
ActionSelectionDestroyCursorAt(i);
ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0);
BattleStringExpandPlaceholdersToDisplayedString(gText_WhatWillPlayerThrow);
BreakStringAutomatic(gDisplayedStringBattle, WindowWidthPx(B_WIN_ACTION_PROMPT), 2, FONT_NORMAL);
BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_ACTION_PROMPT);
}
@@ -321,5 +343,5 @@ static void SafariHandleEndLinkBattle(u32 battler)
BeginFastPaletteFade(3);
SafariBufferExecCompleted(battler);
if ((gBattleTypeFlags & BATTLE_TYPE_LINK) && !(gBattleTypeFlags & BATTLE_TYPE_IS_MASTER))
gBattlerControllerFuncs[battler] = Safari_SetBattleEndCallbacks;
gBattlerControllerFuncs[battler] = SafariSetBattleEndCallbacks;
}

View File

@@ -4,6 +4,7 @@
#include "battle_ai_util.h"
#include "battle_anim.h"
#include "battle_controllers.h"
#include "battle_gfx_sfx_util.h"
#include "battle_interface.h"
#include "battle_message.h"
#include "battle_setup.h"
@@ -13,14 +14,13 @@
#include "link_rfu.h"
#include "palette.h"
#include "party_menu.h"
#include "pokeball.h"
#include "recorded_battle.h"
#include "sound.h"
#include "string_util.h"
#include "sound.h"
#include "task.h"
#include "test_runner.h"
#include "text.h"
#include "util.h"
#include "text.h"
#include "constants/abilities.h"
#include "constants/battle_string_ids.h"
#include "constants/songs.h"
@@ -28,12 +28,11 @@
static EWRAM_DATA u8 sLinkSendTaskId = 0;
static EWRAM_DATA u8 sLinkReceiveTaskId = 0;
static EWRAM_DATA u8 sUnused = 0; // Debug? Never read
EWRAM_DATA struct UnusedControllerStruct gUnusedControllerStruct = {}; // Debug? Unused code that writes to it, never read
void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(u32 battler);
u8 gBattleControllerData[MAX_BATTLERS_COUNT];
void (*gBattlerControllerEndFuncs[MAX_BATTLERS_COUNT])(u32 battler); // Controller's buffer complete function for each battler
COMMON_DATA void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(u32 battler) = {0};
COMMON_DATA u8 gBattleControllerData[MAX_BATTLERS_COUNT] = {0}; // Used by the battle controllers to store misc sprite/task IDs for each battler
COMMON_DATA void (*gBattlerControllerEndFuncs[MAX_BATTLERS_COUNT])(u32 battler) = {0}; // Controller's buffer complete function for each battler
static void CreateTasksForSendRecvLinkBuffers(void);
static void InitLinkBtlControllers(void);
@@ -103,6 +102,12 @@ void InitBattleControllers(void)
for (i = 0; i < gBattlersCount; i++)
BufferBattlePartyCurrentOrderBySide(i, 0);
}
// for (i = 0; i < sizeof(gBattleStruct->tvMovePoints); i++)
// *((u8 *)(&gBattleStruct->tvMovePoints) + i) = 0;
// for (i = 0; i < sizeof(gBattleStruct->tv); i++)
// *((u8 *)(&gBattleStruct->tv) + i) = 0;
}
static void InitSinglePlayerBtlControllers(void)
@@ -180,7 +185,7 @@ static void InitSinglePlayerBtlControllers(void)
gBattlerPartyIndexes[3] = 3;
}
}
else if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
else if (!IsDoubleBattle())
{
gBattleMainFunc = BeginBattleIntro;
@@ -422,7 +427,7 @@ static void InitLinkBtlControllers(void)
s32 i;
u8 multiplayerId;
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
if (!IsDoubleBattle())
{
if (gBattleTypeFlags & BATTLE_TYPE_IS_MASTER)
{
@@ -447,7 +452,7 @@ static void InitLinkBtlControllers(void)
gBattlersCount = 2;
}
}
else if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) && gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
else if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) && IsDoubleBattle())
{
if (gBattleTypeFlags & BATTLE_TYPE_IS_MASTER)
{
@@ -484,6 +489,52 @@ static void InitLinkBtlControllers(void)
gBattlersCount = MAX_BATTLERS_COUNT;
}
}
else if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER)
{
if (gBattleTypeFlags & BATTLE_TYPE_IS_MASTER)
{
gBattleMainFunc = BeginBattleIntro;
gBattlerControllerFuncs[0] = SetControllerToPlayer;
gBattlerPositions[0] = B_POSITION_PLAYER_LEFT;
gBattlerControllerFuncs[1] = SetControllerToOpponent;
gBattlerPositions[1] = B_POSITION_OPPONENT_LEFT;
gBattlerControllerFuncs[2] = SetControllerToLinkPartner;
gBattlerPositions[2] = B_POSITION_PLAYER_RIGHT;
gBattlerControllerFuncs[3] = SetControllerToOpponent;
gBattlerPositions[3] = B_POSITION_OPPONENT_RIGHT;
gBattlersCount = MAX_BATTLERS_COUNT;
}
else
{
gBattlerControllerFuncs[0] = SetControllerToLinkPartner;
gBattlerPositions[0] = B_POSITION_PLAYER_LEFT;
gBattlerControllerFuncs[1] = SetControllerToLinkOpponent;
gBattlerPositions[1] = B_POSITION_OPPONENT_LEFT;
gBattlerControllerFuncs[2] = SetControllerToPlayer;
gBattlerPositions[2] = B_POSITION_PLAYER_RIGHT;
gBattlerControllerFuncs[3] = SetControllerToLinkOpponent;
gBattlerPositions[3] = B_POSITION_OPPONENT_RIGHT;
gBattlersCount = MAX_BATTLERS_COUNT;
}
BufferBattlePartyCurrentOrderBySide(0, 0);
BufferBattlePartyCurrentOrderBySide(1, 0);
BufferBattlePartyCurrentOrderBySide(2, 1);
BufferBattlePartyCurrentOrderBySide(3, 1);
gBattlerPartyIndexes[0] = 0;
gBattlerPartyIndexes[1] = 0;
gBattlerPartyIndexes[2] = 3;
gBattlerPartyIndexes[3] = 3;
}
else
{
multiplayerId = GetMultiplayerId();
@@ -513,7 +564,7 @@ static void InitLinkBtlControllers(void)
case 0:
case 3:
gBattlerPositions[gLinkPlayers[i].id] = B_POSITION_PLAYER_LEFT;
gBattlerPartyIndexes[gLinkPlayers[i].id] = B_POSITION_PLAYER_LEFT;
gBattlerPartyIndexes[gLinkPlayers[i].id] = 0;
break;
case 1:
case 2:
@@ -533,12 +584,12 @@ static void InitLinkBtlControllers(void)
case 0:
case 3:
gBattlerPositions[gLinkPlayers[i].id] = B_POSITION_PLAYER_LEFT;
gBattlerPartyIndexes[gLinkPlayers[i].id] = B_POSITION_PLAYER_LEFT;
gBattlerPartyIndexes[gLinkPlayers[i].id] = 0;
break;
case 1:
case 2:
gBattlerPositions[gLinkPlayers[i].id] = B_POSITION_PLAYER_RIGHT;
gBattlerPartyIndexes[gLinkPlayers[i].id] = B_POSITION_OPPONENT_RIGHT;
gBattlerPartyIndexes[gLinkPlayers[i].id] = 3;
break;
}
}
@@ -550,12 +601,12 @@ static void InitLinkBtlControllers(void)
case 0:
case 3:
gBattlerPositions[gLinkPlayers[i].id] = B_POSITION_OPPONENT_LEFT;
gBattlerPartyIndexes[gLinkPlayers[i].id] = B_POSITION_PLAYER_LEFT;
gBattlerPartyIndexes[gLinkPlayers[i].id] = 0;
break;
case 1:
case 2:
gBattlerPositions[gLinkPlayers[i].id] = B_POSITION_OPPONENT_RIGHT;
gBattlerPartyIndexes[gLinkPlayers[i].id] = B_POSITION_OPPONENT_RIGHT;
gBattlerPartyIndexes[gLinkPlayers[i].id] = 3;
break;
}
}
@@ -569,9 +620,10 @@ static void InitLinkBtlControllers(void)
bool32 IsValidForBattle(struct Pokemon *mon)
{
u32 species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG);
return (species != SPECIES_NONE && species != SPECIES_EGG
&& GetMonData(mon, MON_DATA_HP) != 0
&& GetMonData(mon, MON_DATA_IS_EGG) == FALSE);
return (species != SPECIES_NONE
&& species != SPECIES_EGG
&& GetMonData(mon, MON_DATA_HP) != 0
&& GetMonData(mon, MON_DATA_IS_EGG) == FALSE);
}
static void SetBattlePartyIds(void)
@@ -674,8 +726,6 @@ static void CreateTasksForSendRecvLinkBuffers(void)
gTasks[sLinkReceiveTaskId].data[13] = 0;
gTasks[sLinkReceiveTaskId].data[14] = 0;
gTasks[sLinkReceiveTaskId].data[15] = 0;
sUnused = 0;
}
enum
@@ -804,7 +854,7 @@ void TryReceiveLinkBattleData(void)
DestroyTask_RfuIdle();
for (i = 0; i < GetLinkPlayerCount(); i++)
{
if (GetBlockReceivedStatus() & gBitTable[i])
if (GetBlockReceivedStatus() & (1 << (i)))
{
ResetBlockReceivedFlag(i);
recvBuffer = (u8 *)gBlockRecvBuffer[i];
@@ -834,7 +884,7 @@ void TryReceiveLinkBattleData(void)
static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId)
{
u16 blockSize;
u8 battlerId;
u8 battler;
u8 var;
if (gTasks[taskId].data[15] != gTasks[taskId].data[14])
@@ -845,17 +895,17 @@ static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId)
gTasks[taskId].data[12] = 0;
gTasks[taskId].data[15] = 0;
}
battlerId = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_ACTIVE_BATTLER];
battler = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_ACTIVE_BATTLER];
blockSize = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_SIZE_LO] | (gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_SIZE_HI] << 8);
switch (gLinkBattleRecvBuffer[gTasks[taskId].data[15] + 0])
{
case 0:
if (gBattleControllerExecFlags & gBitTable[battlerId])
if (gBattleControllerExecFlags & (1u << battler))
return;
memcpy(gBattleResources->bufferA[battlerId], &gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_DATA], blockSize);
MarkBattlerReceivedLinkData(battlerId);
memcpy(gBattleResources->bufferA[battler], &gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_DATA], blockSize);
MarkBattlerReceivedLinkData(battler);
if (!(gBattleTypeFlags & BATTLE_TYPE_IS_MASTER))
{
@@ -866,11 +916,11 @@ static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId)
}
break;
case 1:
memcpy(gBattleResources->bufferB[battlerId], &gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_DATA], blockSize);
memcpy(gBattleResources->bufferB[battler], &gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_DATA], blockSize);
break;
case 2:
var = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_DATA];
gBattleControllerExecFlags &= ~(gBitTable[battlerId] << (var * 4));
gBattleControllerExecFlags &= ~(1u << (battler + var * 4));
break;
}
@@ -887,6 +937,15 @@ void BtlController_EmitGetMonData(u32 battler, u32 bufferId, u8 requestId, u8 mo
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
static void UNUSED BtlController_EmitGetRawMonData(u32 battler, u32 bufferId, u8 monId, u8 bytes)
{
gBattleResources->transferBuffer[0] = CONTROLLER_GETRAWMONDATA;
gBattleResources->transferBuffer[1] = monId;
gBattleResources->transferBuffer[2] = bytes;
gBattleResources->transferBuffer[3] = 0;
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
void BtlController_EmitSetMonData(u32 battler, u32 bufferId, u8 requestId, u8 monToCheck, u8 bytes, void *data)
{
s32 i;
@@ -899,6 +958,18 @@ void BtlController_EmitSetMonData(u32 battler, u32 bufferId, u8 requestId, u8 mo
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 3 + bytes);
}
static void UNUSED BtlController_EmitSetRawMonData(u32 battler, u32 bufferId, u8 monId, u8 bytes, void *data)
{
s32 i;
gBattleResources->transferBuffer[0] = CONTROLLER_SETRAWMONDATA;
gBattleResources->transferBuffer[1] = monId;
gBattleResources->transferBuffer[2] = bytes;
for (i = 0; i < bytes; i++)
gBattleResources->transferBuffer[3 + i] = *(u8 *)(data++);
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, bytes + 3);
}
void BtlController_EmitLoadMonSprite(u32 battler, u32 bufferId)
{
gBattleResources->transferBuffer[0] = CONTROLLER_LOADMONSPRITE;
@@ -960,6 +1031,24 @@ void BtlController_EmitFaintAnimation(u32 battler, u32 bufferId)
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
static void UNUSED BtlController_EmitPaletteFade(u32 battler, u32 bufferId)
{
gBattleResources->transferBuffer[0] = CONTROLLER_PALETTEFADE;
gBattleResources->transferBuffer[1] = CONTROLLER_PALETTEFADE;
gBattleResources->transferBuffer[2] = CONTROLLER_PALETTEFADE;
gBattleResources->transferBuffer[3] = CONTROLLER_PALETTEFADE;
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
static void UNUSED BtlController_EmitSuccessBallThrowAnim(u32 battler, u32 bufferId)
{
gBattleResources->transferBuffer[0] = CONTROLLER_SUCCESSBALLTHROWANIM;
gBattleResources->transferBuffer[1] = CONTROLLER_SUCCESSBALLTHROWANIM;
gBattleResources->transferBuffer[2] = CONTROLLER_SUCCESSBALLTHROWANIM;
gBattleResources->transferBuffer[3] = CONTROLLER_SUCCESSBALLTHROWANIM;
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
void BtlController_EmitBallThrowAnim(u32 battler, u32 bufferId, u8 caseId)
{
gBattleResources->transferBuffer[0] = CONTROLLER_BALLTHROWANIM;
@@ -967,6 +1056,17 @@ void BtlController_EmitBallThrowAnim(u32 battler, u32 bufferId, u8 caseId)
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 2);
}
static void UNUSED BtlController_EmitPause(u32 battler, u32 bufferId, u8 toWait, void *data)
{
s32 i;
gBattleResources->transferBuffer[0] = CONTROLLER_PAUSE;
gBattleResources->transferBuffer[1] = toWait;
for (i = 0; i < toWait * 3; i++)
gBattleResources->transferBuffer[2 + i] = *(u8 *)(data++);
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, toWait * 3 + 2);
}
void BtlController_EmitMoveAnimation(u32 battler, u32 bufferId, u16 move, u8 turnOfMove, u16 movePower, s32 dmg, u8 friendship, struct DisableStruct *disableStructPtr, u8 multihit)
{
gBattleResources->transferBuffer[0] = CONTROLLER_MOVEANIMATION;
@@ -980,7 +1080,7 @@ void BtlController_EmitMoveAnimation(u32 battler, u32 bufferId, u16 move, u8 tur
gBattleResources->transferBuffer[8] = (dmg & 0x00FF0000) >> 16;
gBattleResources->transferBuffer[9] = (dmg & 0xFF000000) >> 24;
gBattleResources->transferBuffer[10] = friendship;
gBattleResources->transferBuffer[11] = multihit; // multihit in pokeem
gBattleResources->transferBuffer[11] = multihit;
if (WEATHER_HAS_EFFECT)
{
gBattleResources->transferBuffer[12] = gBattleWeather;
@@ -1016,7 +1116,7 @@ void BtlController_EmitPrintString(u32 battler, u32 bufferId, u16 stringID)
stringInfo->bakScriptPartyIdx = gBattleStruct->scriptPartyIdx;
stringInfo->hpScale = gBattleStruct->hpScale;
stringInfo->itemEffectBattler = gPotentialItemEffectBattler;
stringInfo->moveType = gMovesInfo[gCurrentMove].type;
stringInfo->moveType = GetMoveType(gCurrentMove);
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
stringInfo->abilities[i] = gBattleMons[i].ability;
@@ -1068,6 +1168,17 @@ void BtlController_EmitChooseAction(u32 battler, u32 bufferId, u8 action, u16 it
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
// Only used by the forfeit prompt in the Battle Frontier
// For other Yes/No boxes in battle, see Cmd_yesnobox
void BtlController_EmitYesNoBox(u32 battler, u32 bufferId)
{
gBattleResources->transferBuffer[0] = CONTROLLER_YESNOBOX;
gBattleResources->transferBuffer[1] = CONTROLLER_YESNOBOX;
gBattleResources->transferBuffer[2] = CONTROLLER_YESNOBOX;
gBattleResources->transferBuffer[3] = CONTROLLER_YESNOBOX;
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
void BtlController_EmitChooseMove(u32 battler, u32 bufferId, bool8 isDoubleBattle, bool8 NoPpNumber, struct ChooseMoveStruct *movePpData)
{
s32 i;
@@ -1102,9 +1213,19 @@ void BtlController_EmitChoosePokemon(u32 battler, u32 bufferId, u8 caseId, u8 sl
gBattleResources->transferBuffer[7] = (abilityId >> 8) & 0xFF;
for (i = 0; i < 3; i++)
gBattleResources->transferBuffer[4 + i] = data[i];
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 8);
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 8); // Only 7 bytes were written.
}
static void UNUSED BtlController_EmitCmd23(u32 battler, u32 bufferId)
{
gBattleResources->transferBuffer[0] = CONTROLLER_23;
gBattleResources->transferBuffer[1] = CONTROLLER_23;
gBattleResources->transferBuffer[2] = CONTROLLER_23;
gBattleResources->transferBuffer[3] = CONTROLLER_23;
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
// why is the argument u16 if it's being cast to s16 anyway?
void BtlController_EmitHealthBarUpdate(u32 battler, u32 bufferId, u16 hpValue)
{
gBattleResources->transferBuffer[0] = CONTROLLER_HEALTHBARUPDATE;
@@ -1150,6 +1271,13 @@ void BtlController_EmitStatusAnimation(u32 battler, u32 bufferId, bool8 status2,
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 6);
}
static void UNUSED BtlController_EmitStatusXor(u32 battler, u32 bufferId, u8 b)
{
gBattleResources->transferBuffer[0] = CONTROLLER_STATUSXOR;
gBattleResources->transferBuffer[1] = b;
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 2);
}
void BtlController_EmitDataTransfer(u32 battler, u32 bufferId, u16 size, void *data)
{
s32 i;
@@ -1163,14 +1291,57 @@ void BtlController_EmitDataTransfer(u32 battler, u32 bufferId, u16 size, void *d
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, size + 4);
}
static void UNUSED BtlController_EmitDMA3Transfer(u32 battler, u32 bufferId, void *dst, u16 size, void *data)
{
s32 i;
gBattleResources->transferBuffer[0] = CONTROLLER_DMA3TRANSFER;
gBattleResources->transferBuffer[1] = (u32)(dst);
gBattleResources->transferBuffer[2] = ((u32)(dst) & 0x0000FF00) >> 8;
gBattleResources->transferBuffer[3] = ((u32)(dst) & 0x00FF0000) >> 16;
gBattleResources->transferBuffer[4] = ((u32)(dst) & 0xFF000000) >> 24;
gBattleResources->transferBuffer[5] = size;
gBattleResources->transferBuffer[6] = (size & 0xFF00) >> 8;
for (i = 0; i < size; i++)
gBattleResources->transferBuffer[7 + i] = *(u8 *)(data++);
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, size + 7);
}
static void UNUSED BtlController_EmitPlayBGM(u32 battler, u32 bufferId, u16 songId, void *data)
{
s32 i;
gBattleResources->transferBuffer[0] = CONTROLLER_PLAYBGM;
gBattleResources->transferBuffer[1] = songId;
gBattleResources->transferBuffer[2] = (songId & 0xFF00) >> 8;
// Nonsense loop using songId as a size
// Would go out of bounds for any song id after SE_RG_BAG_POCKET (253)
for (i = 0; i < songId; i++)
gBattleResources->transferBuffer[3 + i] = *(u8 *)(data++);
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, songId + 3);
}
static void UNUSED BtlController_EmitCmd32(u32 battler, u32 bufferId, u16 size, void *data)
{
s32 i;
gBattleResources->transferBuffer[0] = CONTROLLER_32;
gBattleResources->transferBuffer[1] = size;
gBattleResources->transferBuffer[2] = (size & 0xFF00) >> 8;
for (i = 0; i < size; i++)
gBattleResources->transferBuffer[3 + i] = *(u8 *)(data++);
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, size + 3);
}
void BtlController_EmitTwoReturnValues(u32 battler, u32 bufferId, u8 ret8, u32 ret32)
{
gBattleResources->transferBuffer[0] = CONTROLLER_TWORETURNVALUES;
gBattleResources->transferBuffer[1] = ret8;
gBattleResources->transferBuffer[2] = ret32;
gBattleResources->transferBuffer[3] = (ret32 & 0x0000FF00) >> 8;
gBattleResources->transferBuffer[4] = (ret32 & 0x0000FF00) >> 16;
gBattleResources->transferBuffer[5] = (ret32 & 0x0000FF00) >> 24;
gBattleResources->transferBuffer[4] = (ret32 & 0x00FF0000) >> 16;
gBattleResources->transferBuffer[5] = (ret32 & 0xFF000000) >> 24;
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 6);
}
@@ -1203,6 +1374,40 @@ void BtlController_EmitOneReturnValue_Duplicate(u32 battler, u32 bufferId, u16 r
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
static void UNUSED BtlController_EmitClearUnkVar(u32 battler, u32 bufferId)
{
gBattleResources->transferBuffer[0] = CONTROLLER_CLEARUNKVAR;
gBattleResources->transferBuffer[1] = CONTROLLER_CLEARUNKVAR;
gBattleResources->transferBuffer[2] = CONTROLLER_CLEARUNKVAR;
gBattleResources->transferBuffer[3] = CONTROLLER_CLEARUNKVAR;
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
static void UNUSED BtlController_EmitSetUnkVar(u32 battler, u32 bufferId, u8 b)
{
gBattleResources->transferBuffer[0] = CONTROLLER_SETUNKVAR;
gBattleResources->transferBuffer[1] = b;
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 2);
}
static void UNUSED BtlController_EmitClearUnkFlag(u32 battler, u32 bufferId)
{
gBattleResources->transferBuffer[0] = CONTROLLER_CLEARUNKFLAG;
gBattleResources->transferBuffer[1] = CONTROLLER_CLEARUNKFLAG;
gBattleResources->transferBuffer[2] = CONTROLLER_CLEARUNKFLAG;
gBattleResources->transferBuffer[3] = CONTROLLER_CLEARUNKFLAG;
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
static void UNUSED BtlController_EmitToggleUnkFlag(u32 battler, u32 bufferId)
{
gBattleResources->transferBuffer[0] = CONTROLLER_TOGGLEUNKFLAG;
gBattleResources->transferBuffer[1] = CONTROLLER_TOGGLEUNKFLAG;
gBattleResources->transferBuffer[2] = CONTROLLER_TOGGLEUNKFLAG;
gBattleResources->transferBuffer[3] = CONTROLLER_TOGGLEUNKFLAG;
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
void BtlController_EmitHitAnimation(u32 battler, u32 bufferId)
{
gBattleResources->transferBuffer[0] = CONTROLLER_HITANIMATION;
@@ -1339,6 +1544,9 @@ void BtlController_EmitEndLinkBattle(u32 battler, u32 bufferId, u8 battleOutcome
{
gBattleResources->transferBuffer[0] = CONTROLLER_ENDLINKBATTLE;
gBattleResources->transferBuffer[1] = battleOutcome;
// gBattleResources->transferBuffer[2] = gSaveBlock2Ptr->frontier.disableRecordBattle;
// gBattleResources->transferBuffer[3] = gSaveBlock2Ptr->frontier.disableRecordBattle;
// gBattleResources->transferBuffer[5] = gBattleResources->transferBuffer[4] = RecordedBattle_BufferNewBattlerData(&gBattleResources->transferBuffer[6]);
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 2);
}
@@ -1398,12 +1606,22 @@ static u32 GetBattlerMonData(u32 battler, struct Pokemon *party, u32 monId, u8 *
battleMon.abilityNum = GetMonData(&party[monId], MON_DATA_ABILITY_NUM);
battleMon.otId = GetMonData(&party[monId], MON_DATA_OT_ID);
battleMon.metLevel = GetMonData(&party[monId], MON_DATA_MET_LEVEL);
battleMon.isShiny = GetMonData(&party[monId], MON_DATA_IS_SHINY);
GetMonData(&party[monId], MON_DATA_NICKNAME, nickname);
StringCopy_Nickname(battleMon.nickname, nickname);
GetMonData(&party[monId], MON_DATA_OT_NAME, battleMon.otName);
src = (u8 *)&battleMon;
for (size = 0; size < sizeof(battleMon); size++)
dst[size] = src[size];
#if TESTING
if (gTestRunnerEnabled)
{
u32 side = GetBattlerSide(battler);
u32 partyIndex = gBattlerPartyIndexes[battler];
if (TestRunner_Battle_GetForcedAbility(side, partyIndex))
gBattleMons[battler].ability = gDisableStructs[battler].overwrittenAbility = TestRunner_Battle_GetForcedAbility(side, partyIndex);
}
#endif
break;
case REQUEST_SPECIES_BATTLE:
data16 = GetMonData(&party[monId], MON_DATA_SPECIES);
@@ -1890,7 +2108,7 @@ static bool8 ShouldDoSlideInAnim(void)
if (gBattleTypeFlags & (
BATTLE_TYPE_LINK | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_FRONTIER | BATTLE_TYPE_FIRST_BATTLE |
BATTLE_TYPE_SAFARI | BATTLE_TYPE_OLD_MAN_TUTORIAL | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_TWO_OPPONENTS |
BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_RECORDED | BATTLE_TYPE_POKEDUDE | BATTLE_TYPE_TRAINER_TOWER)
BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_RECORDED | BATTLE_TYPE_TRAINER_HILL | BATTLE_TYPE_POKEDUDE)
)
return FALSE;
return TRUE;
@@ -2348,7 +2566,10 @@ void BtlController_HandleDrawTrainerPic(u32 battler, u32 trainerPicId, bool32 is
gSprites[gBattlerSpriteIds[battler]].x2 = DISPLAY_WIDTH;
gSprites[gBattlerSpriteIds[battler]].sSpeedX = -2;
}
gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_TrainerSlideIn;
if (B_FAST_INTRO_NO_SLIDE || gTestRunnerHeadless)
gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_TrainerSpawn;
else
gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_TrainerSlideIn;
gBattlerControllerFuncs[battler] = Controller_WaitForTrainerPic;
}
@@ -2486,7 +2707,7 @@ void BtlController_HandlePrintString(u32 battler)
gBattle_BG0_X = 0;
gBattle_BG0_Y = 0;
stringId = (u16 *)(&gBattleResources->bufferA[battler][2]);
BufferStringBattle(battler, *stringId);
BufferStringBattle(*stringId, battler);
if (gTestRunnerEnabled)
{
@@ -2550,7 +2771,7 @@ void DoStatusIconUpdate(u32 battler)
struct Pokemon *party = GetBattlerParty(battler);
UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &party[gBattlerPartyIndexes[battler]], HEALTHBOX_STATUS_ICON);
gBattleSpritesDataPtr->healthBoxesData[battler].statusAnimActive = FALSE;
gBattleSpritesDataPtr->healthBoxesData[battler].statusAnimActive = 0;
gBattlerControllerFuncs[battler] = Controller_WaitForStatusAnimation;
}
@@ -2717,7 +2938,7 @@ void BtlController_HandleIntroTrainerBallThrow(u32 battler, u16 tagTrainerPal, c
if (side == B_SIDE_PLAYER)
{
StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[battler]], SpriteCB_FreePlayerSpriteLoadMonSprite);
StartSpriteAnim(&gSprites[gBattlerSpriteIds[battler]], 1);
StartSpriteAnim(&gSprites[gBattlerSpriteIds[battler]], ShouldDoSlideInAnim() ? 2 : 1);
paletteNum = AllocSpritePalette(tagTrainerPal);
LoadCompressedPalette(trainerPal, OBJ_PLTT_ID(paletteNum), PLTT_SIZE_4BPP);
@@ -2778,7 +2999,7 @@ static void Task_StartSendOutAnim(u8 taskId)
gBattleResources->bufferA[battler][1] = gBattlerPartyIndexes[battler];
StartSendOutAnim(battler, FALSE, ShouldDoSlideInAnim());
battlerPartner = BATTLE_PARTNER(battler);
battlerPartner = battler ^ BIT_FLANK;
gBattleResources->bufferA[battlerPartner][1] = gBattlerPartyIndexes[battlerPartner];
BattleLoadMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[battlerPartner]], battlerPartner);
StartSendOutAnim(battlerPartner, FALSE, ShouldDoSlideInAnim());
@@ -2830,7 +3051,7 @@ void BtlController_HandleDrawPartyStatusSummary(u32 battler, u32 side, bool32 co
}
else
{
gBattleSpritesDataPtr->healthBoxesData[battler].partyStatusSummaryShown = TRUE;
gBattleSpritesDataPtr->healthBoxesData[battler].partyStatusSummaryShown = 1;
if (side == B_SIDE_OPPONENT && gBattleResources->bufferA[battler][2] != 0)
{
@@ -2878,6 +3099,3 @@ void BtlController_HandleBattleAnimation(u32 battler, bool32 ignoreSE)
gBattlerControllerFuncs[battler] = Controller_WaitForBattleAnimation;
}
}

View File

@@ -213,6 +213,18 @@ void SpriteCB_TrainerSlideIn(struct Sprite *sprite)
}
}
void SpriteCB_TrainerSpawn(struct Sprite *sprite)
{
if (!(gIntroSlideFlags & 1))
{
sprite->x2 = 0;
if (sprite->y2 != 0)
sprite->callback = SpriteCB_TrainerSlideVertical;
else
sprite->callback = SpriteCallbackDummy;
}
}
// Slide up to 0 if necessary (used by multi battle intro)
static void SpriteCB_TrainerSlideVertical(struct Sprite *sprite)
{

View File

@@ -2423,7 +2423,7 @@ static const u16 sGrammarMoveUsedTable[] =
static const u8 sRecordedBattleTextSpeeds[] = {8, 4, 1, 0};
void BufferStringBattle(u32 battler, u16 stringId)
void BufferStringBattle(u16 stringId, u32 battler)
{
s32 i;
const u8 *stringPtr = NULL;

View File

@@ -2052,6 +2052,7 @@ const struct Item gItemsInfo[] =
"A glass flute that "
"awakens\nsleeping "
"Pokémon."),
.notConsumed = TRUE,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_Medicine,
@@ -2070,6 +2071,7 @@ const struct Item gItemsInfo[] =
"A glass flute that "
"snaps Pokémon\n"
"out of confusion."),
.notConsumed = TRUE,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
@@ -2088,6 +2090,7 @@ const struct Item gItemsInfo[] =
"A glass flute that "
"snaps Pokémon\n"
"out of attraction."),
.notConsumed = TRUE,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
@@ -2109,6 +2112,7 @@ const struct Item gItemsInfo[] =
"A glass flute that "
"keeps away\nwild "
"Pokémon."),
.notConsumed = TRUE,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_BlackWhiteFlute,
@@ -2125,6 +2129,7 @@ const struct Item gItemsInfo[] =
.description = COMPOUND_STRING(
"A glass flute that "
"lures wild\nPokémon."),
.notConsumed = TRUE,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_BlackWhiteFlute,

View File

@@ -1937,3 +1937,8 @@ const u32 gBattleAnimBgPalette_ZMoveMountain[] = INCBIN_U32("graphics/battle_ani
const u32 gBattleAnimBgTilemap_ZMoveMountain[] = INCBIN_U32("graphics/battle_anims/backgrounds/zmove_mountain.bin.lz");
const u32 gBattleAnimBgPalette_SteelBeam[] = INCBIN_U32("graphics/battle_anims/backgrounds/steel_beam.gbapal.lz");
const u32 gBattleIcons_Gfx1[] = INCBIN_U32("graphics/types/battle_icons1.4bpp.lz");
const u32 gBattleIcons_Gfx2[] = INCBIN_U32("graphics/types/battle_icons2.4bpp.lz");
const u32 gBattleIcons_Pal1[] = INCBIN_U32("graphics/types/battle_icons1.gbapal.lz");
const u32 gBattleIcons_Pal2[] = INCBIN_U32("graphics/types/battle_icons2.gbapal.lz");

View File

@@ -662,6 +662,11 @@ u8 ItemId_GetImportance(u16 itemId)
return gItemsInfo[SanitizeItemId(itemId)].importance;
}
u8 ItemId_GetConsumability(u16 itemId)
{
return !gItemsInfo[SanitizeItemId(itemId)].notConsumed;
}
u8 ItemId_GetPocket(u16 itemId)
{
return gItemsInfo[SanitizeItemId(itemId)].pocket;

View File

@@ -351,7 +351,7 @@ void CB2_BagMenuFromStartMenu(void)
void CB2_BagMenuFromBattle(void)
{
GoToBagMenu(ITEMMENULOCATION_BATTLE, OPEN_BAG_LAST, SetCB2ToReshowScreenAfterMenu2);
GoToBagMenu(ITEMMENULOCATION_BATTLE, OPEN_BAG_LAST, CB2_SetUpReshowBattleScreenAfterMenu2);
}
static void CB2_BagMenuRun(void)
@@ -949,7 +949,7 @@ void Bag_BeginCloseWin0Animation(void)
gBagMenuState.bagOpen = FALSE;
}
void CB2_SetUpReshowBattleScreenAfterMenu(void)
void SetBagOpenFalse(void)
{
gBagMenuState.bagOpen = FALSE;
}
@@ -2101,7 +2101,7 @@ void InitOldManBag(void)
BackUpPlayerBag();
AddBagItem(ITEM_POTION, 1);
AddBagItem(ITEM_POKE_BALL, 1);
GoToBagMenu(ITEMMENULOCATION_OLD_MAN, OPEN_BAG_ITEMS, SetCB2ToReshowScreenAfterMenu2);
GoToBagMenu(ITEMMENULOCATION_OLD_MAN, OPEN_BAG_ITEMS, CB2_SetUpReshowBattleScreenAfterMenu2);
}
#define tFrameCounter data[8]
@@ -2183,11 +2183,11 @@ void InitPokedudeBag(u8 a0)
location = a0;
break;
case ITEMMENULOCATION_TTVSCR_STATUS:
cb2 = SetCB2ToReshowScreenAfterMenu2;
cb2 = CB2_SetUpReshowBattleScreenAfterMenu2;
location = ITEMMENULOCATION_TTVSCR_STATUS;
break;
case ITEMMENULOCATION_TTVSCR_CATCHING:
cb2 = SetCB2ToReshowScreenAfterMenu2;
cb2 = CB2_SetUpReshowBattleScreenAfterMenu2;
location = ITEMMENULOCATION_TTVSCR_CATCHING;
break;
}

281
src/line_break.c Normal file
View File

@@ -0,0 +1,281 @@
#include "global.h"
#include "line_break.h"
#include "text.h"
#include "malloc.h"
void StripLineBreaks(u8 *src)
{
u32 currIndex = 0;
while (src[currIndex] != EOS)
{
if (src[currIndex] == CHAR_PROMPT_SCROLL || src[currIndex] == CHAR_NEWLINE)
src[currIndex] = CHAR_SPACE;
currIndex++;
}
}
void BreakStringAutomatic(u8 *src, u32 maxWidth, u32 screenLines, u8 fontId)
{
u32 currIndex = 0;
u8 *currSrc = src;
while (src[currIndex] != EOS)
{
if (src[currIndex] == CHAR_PROMPT_CLEAR)
{
u8 replacedChar = src[currIndex + 1];
src[currIndex + 1] = EOS;
BreakSubStringAutomatic(currSrc, maxWidth, screenLines, fontId);
src[currIndex + 1] = replacedChar;
currSrc = &src[currIndex + 1];
}
currIndex++;
}
BreakSubStringAutomatic(currSrc, maxWidth, screenLines, fontId);
}
void BreakSubStringAutomatic(u8 *src, u32 maxWidth, u32 screenLines, u8 fontId)
{
// If the string already has line breaks, don't interfere with them
if (StringHasManualBreaks(src))
return;
// Sanity check
if (src[0] == EOS)
return;
u32 numChars = 1;
u32 numWords = 1;
u32 currWordIndex = 0;
u32 currWordLength = 1;
bool32 isPrevCharSplitting = FALSE;
bool32 isCurrCharSplitting;
// Get numbers of chars in string and count words
while (src[numChars] != EOS)
{
isCurrCharSplitting = IsWordSplittingChar(src, numChars);
if (isCurrCharSplitting && !isPrevCharSplitting)
numWords++;
isPrevCharSplitting = isCurrCharSplitting;
numChars++;
}
// Allocate enough space for word data
struct StringWord *allWords = Alloc(numWords*sizeof(struct StringWord));
allWords[currWordIndex].startIndex = 0;
allWords[currWordIndex].width = 0;
isPrevCharSplitting = FALSE;
// Fill in word begin index and lengths
for (u32 i = 1; i < numChars; i++)
{
isCurrCharSplitting = IsWordSplittingChar(src, i);
if (isCurrCharSplitting && !isPrevCharSplitting)
{
allWords[currWordIndex].length = currWordLength;
currWordIndex++;
currWordLength = 0;
}
else if (!isCurrCharSplitting && isPrevCharSplitting)
{
allWords[currWordIndex].startIndex = i;
allWords[currWordIndex].width = 0;
currWordLength++;
}
else
{
currWordLength++;
}
isPrevCharSplitting = isCurrCharSplitting;
}
allWords[currWordIndex].length = currWordLength;
// Fill in individual word widths
for (u32 i = 0; i < numWords; i++)
{
for (u32 j = 0; j < allWords[i].length; j++)
allWords[i].width += GetGlyphWidth(src[allWords[i].startIndex + j], FALSE, fontId);
}
// Step 1: Does it all fit one one line? Then no break
// Step 2: Try to split across minimum number of lines
u32 spaceWidth = GetGlyphWidth(0, FALSE, fontId);
u32 totalWidth = allWords[0].width;
// Calculate total widths without any line breaks
for (u32 i = 1; i < numWords; i++)
totalWidth += allWords[i].width + spaceWidth;
// If it doesn't fit on 1 line, do fancy line break calculation
// NOTE: Currently the line break calculation isn't fancy
if (totalWidth > maxWidth)
{
// Figure out how many lines are needed with naive method
u32 currLineWidth = 0;
u32 totalLines = 1;
bool32 shouldTryAgain;
for (currWordIndex = 0; currWordIndex < numWords; currWordIndex++)
{
if (currLineWidth + allWords[currWordIndex].length > maxWidth)
{
totalLines++;
currLineWidth = allWords[currWordIndex].width;
}
else
{
currLineWidth += allWords[currWordIndex].width + spaceWidth;
}
}
// LINE LAYOUT STARTS HERE
struct StringLine *stringLines;
do
{
shouldTryAgain = FALSE;
u16 targetLineWidth = totalWidth/totalLines;
stringLines = Alloc(totalLines*sizeof(struct StringLine));
for (u32 lineIndex = 0; lineIndex < totalLines; lineIndex++)
{
stringLines[lineIndex].numWords = 0;
stringLines[lineIndex].spaceWidth = spaceWidth;
stringLines[lineIndex].extraSpaceWidth = 0;
}
currWordIndex = 0;
u16 currLineIndex = 0;
stringLines[currLineIndex].words = &allWords[currWordIndex];
stringLines[currLineIndex].numWords = 1;
currLineWidth = allWords[currWordIndex].width;
currWordIndex++;
while (currWordIndex < numWords)
{
if (currLineWidth + spaceWidth + allWords[currWordIndex].width > maxWidth)
{
// go to next line
currLineIndex++;
if (currLineIndex == totalLines)
{
totalLines++;
Free(stringLines);
shouldTryAgain = TRUE;
break;
}
stringLines[currLineIndex].words = &allWords[currWordIndex];
stringLines[currLineIndex].numWords = 1;
currLineWidth = allWords[currWordIndex].width;
currWordIndex++;
}
else if (currLineWidth > targetLineWidth)
{
// go to next line
currLineIndex++;
if (currLineIndex == totalLines)
{
totalLines++;
Free(stringLines);
shouldTryAgain = TRUE;
break;
}
stringLines[currLineIndex].words = &allWords[currWordIndex];
stringLines[currLineIndex].numWords = 1;
currLineWidth = allWords[currWordIndex].width;
currWordIndex++;
}
else
{
// continue on current line
// add word and space width
currLineWidth += spaceWidth + allWords[currWordIndex].width;
stringLines[currLineIndex].numWords++;
currWordIndex++;
}
}
} while (shouldTryAgain);
//u32 currBadness = GetStringBadness(stringLines, totalLines, maxWidth);
BuildNewString(stringLines, totalLines, screenLines, src);
Free(stringLines);
}
Free(allWords);
}
// Only allow word splitting on allowed chars
bool32 IsWordSplittingChar(const u8 *src, u32 index)
{
switch (src[index])
{
case CHAR_SPACE:
return TRUE;
default:
return FALSE;
}
}
// Badness calculation
// unfilled lines scale linerarly
// jagged lines scales by the square
// runts scale linearly
// numbers not final
// ISN'T ACTUALLY USED RIGHT NOW
u32 GetStringBadness(struct StringLine *stringLines, u32 numLines, u32 maxWidth)
{
u32 badness = 0;
u32 *lineWidths = Alloc(numLines*4);
u32 widestWidth = 0;
for (u32 i = 0; i < numLines; i++)
{
lineWidths[i] = 0;
for (u32 j = 0; j < stringLines[i].numWords; j++)
lineWidths[i] += stringLines[i].words[j].width;
lineWidths[i] += (stringLines[i].numWords-1)*stringLines[i].spaceWidth;
if (lineWidths[i] > widestWidth)
widestWidth = lineWidths[i];
if (stringLines[i].numWords == 1)
badness += BADNESS_RUNT;
}
for (u32 i = 0; i < numLines; i++)
{
u32 extraSpaceWidth = 0;
if (lineWidths[i] != widestWidth)
{
// Not the best way to do this, ideally a line should be allowed to get longer than current widest
// line. But then the widest line has to be recalculated.
while (lineWidths[i] + (extraSpaceWidth + 1) * (stringLines[i].numWords - 1) < widestWidth && extraSpaceWidth < MAX_SPACE_WIDTH)
extraSpaceWidth++;
lineWidths[i] += extraSpaceWidth*(stringLines[i].numWords-1);
}
badness += (maxWidth - lineWidths[i]) * BADNESS_UNFILLED;
u32 baseBadness = (widestWidth - lineWidths[i]) * BADNESS_JAGGED;
badness += baseBadness*baseBadness;
stringLines[i].extraSpaceWidth = extraSpaceWidth;
}
Free(lineWidths);
return badness;
}
// Build the new string from the data stored in the StringLine structs
void BuildNewString(struct StringLine *stringLines, u32 numLines, u32 maxLines, u8 *str)
{
u32 srcCharIndex = 0;
for (u32 lineIndex = 0; lineIndex < numLines; lineIndex++)
{
srcCharIndex += stringLines[lineIndex].words[0].length;
for (u32 wordIndex = 1; wordIndex < stringLines[lineIndex].numWords; wordIndex++)
// Add length of word and a space
srcCharIndex += stringLines[lineIndex].words[wordIndex].length + 1;
if (lineIndex + 1 < numLines)
{
// Add the appropriate line break depending on line number
if (lineIndex >= maxLines - 1 && numLines > maxLines)
str[srcCharIndex] = CHAR_PROMPT_SCROLL;
else
str[srcCharIndex] = CHAR_NEWLINE;
srcCharIndex++;
}
}
}
bool32 StringHasManualBreaks(u8 *src)
{
u32 charIndex = 0;
while (src[charIndex] != EOS)
{
if (src[charIndex] == CHAR_PROMPT_SCROLL || src[charIndex] == CHAR_NEWLINE)
return TRUE;
charIndex++;
}
return FALSE;
}

View File

@@ -6562,7 +6562,7 @@ static u8 GetPartyLayoutFromBattleType(void)
return PARTY_LAYOUT_DOUBLE;
}
void OpenPartyMenuInTutorialBattle(u8 partyAction)
void OpenPartyMenuInBattle(u8 partyAction)
{
if (!BtlCtrl_OakOldMan_TestState2Flag(FIRST_BATTLE_MSG_FLAG_PARTY_MENU) && (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE))
{
@@ -6572,7 +6572,7 @@ void OpenPartyMenuInTutorialBattle(u8 partyAction)
FALSE,
PARTY_MSG_NONE,
Task_FirstBattleEnterParty_WaitFadeIn,
SetCB2ToReshowScreenAfterMenu);
CB2_SetUpReshowBattleScreenAfterMenu);
BtlCtrl_OakOldMan_SetState2Flag(FIRST_BATTLE_MSG_FLAG_PARTY_MENU);
}
else
@@ -6583,7 +6583,7 @@ void OpenPartyMenuInTutorialBattle(u8 partyAction)
FALSE,
PARTY_MSG_CHOOSE_MON,
Task_HandleChooseMonInput,
SetCB2ToReshowScreenAfterMenu);
CB2_SetUpReshowBattleScreenAfterMenu);
}
ReshowBattleScreenDummy();
UpdatePartyToBattleOrder();
@@ -6591,7 +6591,7 @@ void OpenPartyMenuInTutorialBattle(u8 partyAction)
void Pokedude_OpenPartyMenuInBattle(void)
{
InitPartyMenu(PARTY_MENU_TYPE_IN_BATTLE, GetPartyLayoutFromBattleType(), PARTY_ACTION_CHOOSE_MON, FALSE, PARTY_MSG_CHOOSE_MON, Task_PartyMenu_Pokedude, SetCB2ToReshowScreenAfterMenu);
InitPartyMenu(PARTY_MENU_TYPE_IN_BATTLE, GetPartyLayoutFromBattleType(), PARTY_ACTION_CHOOSE_MON, FALSE, PARTY_MSG_CHOOSE_MON, Task_PartyMenu_Pokedude, CB2_SetUpReshowBattleScreenAfterMenu);
ReshowBattleScreenDummy();
UpdatePartyToBattleOrder();
}
@@ -6948,8 +6948,8 @@ static void UpdatePartyToFieldOrder(void)
static void CB2_SetUpExitToBattleScreen(void)
{
CB2_SetUpReshowBattleScreenAfterMenu();
SetMainCallback2(SetCB2ToReshowScreenAfterMenu);
SetBagOpenFalse();
SetMainCallback2(CB2_SetUpReshowBattleScreenAfterMenu);
}
void ShowPartyMenuToShowcaseMultiBattleParty(void)

View File

@@ -6561,3 +6561,11 @@ void UpdateDaysPassedSinceFormChange(u16 days)
}
}
}
u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler)
{
u32 moveType = GetDynamicMoveType(mon, move, battler, NULL);
if (moveType != TYPE_NONE)
return moveType;
return GetMoveType(move);
}

View File

@@ -1466,7 +1466,7 @@ static void Task_Pokedude_Run(u8 taskId)
sTMCaseStaticResources.scrollOffset = sPokedudeBagBackup->scrollOffset;
Free(sPokedudeBagBackup);
CpuFastCopy(gPlttBufferFaded, gPlttBufferUnfaded, PLTT_SIZE);
CB2_SetUpReshowBattleScreenAfterMenu();
SetBagOpenFalse();
BeginNormalPaletteFade(PALETTES_ALL, -2, 0, 16, 0);
tPokedudeState++;
}

552
src/type_icons.c Normal file
View File

@@ -0,0 +1,552 @@
#include "global.h"
#include "battle.h"
#include "battle_anim.h"
#include "battle_controllers.h"
#include "battle_gimmick.h"
#include "decompress.h"
#include "graphics.h"
#include "pokedex.h"
#include "sprite.h"
#include "type_icons.h"
static void LoadTypeSpritesAndPalettes(void);
static void LoadTypeIconsPerBattler(u32, u32);
static bool32 UseDoubleBattleCoords(u32);
static u32 GetMonPublicType(u32, u32);
static bool32 ShouldHideUncaughtType(u32);
static u32 GetMonDefensiveTeraType(struct Pokemon *, struct Pokemon*, u32, u32, u32, u32);
static u32 IsIllusionActiveAndTypeUnchanged(struct Pokemon*, u32, u32);
static void CreateSpriteFromType(u32, bool32, u32[], u32, u32);
static bool32 ShouldSkipSecondType(u32[], u32);
static void SetTypeIconXY(s32*, s32*, u32, bool32, u32);
static void CreateSpriteAndSetTypeSpriteAttributes(u32, u32 x, u32 y, u32, u32, bool32);
static bool32 ShouldFlipTypeIcon(bool32, u32, u32);
static void SpriteCB_TypeIcon(struct Sprite*);
static void DestroyTypeIcon(struct Sprite*);
static void FreeAllTypeIconResources(void);
static bool32 ShouldHideTypeIcon(u32);
static s32 GetTypeIconHideMovement(bool32, u32);
static s32 GetTypeIconSlideMovement(bool32, u32, s32);
static s32 GetTypeIconBounceMovement(s32, u32);
const struct Coords16 sTypeIconPositions[][2] =
{
[B_POSITION_PLAYER_LEFT] =
{
[FALSE] = {221, 86},
[TRUE] = {144, 71},
},
[B_POSITION_OPPONENT_LEFT] =
{
[FALSE] = {20, 26},
[TRUE] = {97, 14},
},
[B_POSITION_PLAYER_RIGHT] =
{
[TRUE] = {156, 96},
},
[B_POSITION_OPPONENT_RIGHT] =
{
[TRUE] = {85, 39},
},
};
const union AnimCmd sSpriteAnim_TypeIcon_Normal[] =
{
ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_NORMAL), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Fighting[] =
{
ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_FIGHTING), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Flying[] =
{
ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_FLYING), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Poison[] =
{
ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_POISON), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Ground[] =
{
ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_GROUND), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Rock[] =
{
ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_ROCK), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Bug[] =
{
ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_BUG), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Ghost[] =
{
ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_GHOST), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Steel[] =
{
ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_STEEL), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Mystery[] =
{
ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_MYSTERY), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Fire[] =
{
ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_FIRE), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Water[] =
{
ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_WATER), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Grass[] =
{
ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_GRASS), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Electric[] =
{
ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_ELECTRIC), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Psychic[] =
{
ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_PSYCHIC), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Ice[] =
{
ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_ICE), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Dragon[] =
{
ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_DRAGON), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Dark[] =
{
ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_DARK), 0),
ANIMCMD_END
};
const union AnimCmd sSpriteAnim_TypeIcon_Fairy[] =
{
ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_FAIRY), 0),
ANIMCMD_END
};
const union AnimCmd *const sSpriteAnimTable_TypeIcons[] =
{
[TYPE_NONE] = sSpriteAnim_TypeIcon_Mystery,
[TYPE_NORMAL] = sSpriteAnim_TypeIcon_Normal,
[TYPE_FIGHTING] = sSpriteAnim_TypeIcon_Fighting,
[TYPE_FLYING] = sSpriteAnim_TypeIcon_Flying,
[TYPE_POISON] = sSpriteAnim_TypeIcon_Poison,
[TYPE_GROUND] = sSpriteAnim_TypeIcon_Ground,
[TYPE_ROCK] = sSpriteAnim_TypeIcon_Rock,
[TYPE_BUG] = sSpriteAnim_TypeIcon_Bug,
[TYPE_GHOST] = sSpriteAnim_TypeIcon_Ghost,
[TYPE_STEEL] = sSpriteAnim_TypeIcon_Steel,
[TYPE_MYSTERY] = sSpriteAnim_TypeIcon_Mystery,
[TYPE_FIRE] = sSpriteAnim_TypeIcon_Fire,
[TYPE_WATER] = sSpriteAnim_TypeIcon_Water,
[TYPE_GRASS] = sSpriteAnim_TypeIcon_Grass,
[TYPE_ELECTRIC] = sSpriteAnim_TypeIcon_Electric,
[TYPE_PSYCHIC] = sSpriteAnim_TypeIcon_Psychic,
[TYPE_ICE] = sSpriteAnim_TypeIcon_Ice,
[TYPE_DRAGON] = sSpriteAnim_TypeIcon_Dragon,
[TYPE_DARK] = sSpriteAnim_TypeIcon_Dark,
[TYPE_FAIRY] = sSpriteAnim_TypeIcon_Fairy,
[TYPE_STELLAR] = sSpriteAnim_TypeIcon_Mystery,
};
const struct CompressedSpritePalette sTypeIconPal1 =
{
.data = gBattleIcons_Pal1,
.tag = TYPE_ICON_TAG
};
const struct CompressedSpritePalette sTypeIconPal2 =
{
.data = gBattleIcons_Pal2,
.tag = TYPE_ICON_TAG_2
};
const struct OamData sOamData_TypeIcons =
{
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
.shape = SPRITE_SHAPE(8x16),
.size = SPRITE_SIZE(8x16),
.priority = 1,
};
const struct CompressedSpriteSheet sSpriteSheet_TypeIcons2 =
{
.data = gBattleIcons_Gfx2,
.size = (8*16) * 9,
.tag = TYPE_ICON_TAG_2,
};
const struct CompressedSpriteSheet sSpriteSheet_TypeIcons1 =
{
.data = gBattleIcons_Gfx1,
.size = (8*16) * 10,
.tag = TYPE_ICON_TAG,
};
const struct SpriteTemplate sSpriteTemplate_TypeIcons1 =
{
.tileTag = TYPE_ICON_TAG,
.paletteTag = TYPE_ICON_TAG,
.oam = &sOamData_TypeIcons,
.anims = sSpriteAnimTable_TypeIcons,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCB_TypeIcon
};
const struct SpriteTemplate sSpriteTemplate_TypeIcons2 =
{
.tileTag = TYPE_ICON_TAG_2,
.paletteTag = TYPE_ICON_TAG_2,
.oam = &sOamData_TypeIcons,
.anims = sSpriteAnimTable_TypeIcons,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCB_TypeIcon
};
void LoadTypeIcons(u32 battler)
{
u32 position;
if (B_SHOW_TYPES == SHOW_TYPES_NEVER)
return;
LoadTypeSpritesAndPalettes();
for (position = 0; position < gBattlersCount; ++position)
LoadTypeIconsPerBattler(battler, position);
}
static void LoadTypeSpritesAndPalettes(void)
{
if (IndexOfSpritePaletteTag(TYPE_ICON_TAG) != UCHAR_MAX)
return;
LoadCompressedSpriteSheet(&sSpriteSheet_TypeIcons1);
LoadCompressedSpriteSheet(&sSpriteSheet_TypeIcons2);
LoadCompressedSpritePalette(&sTypeIconPal1);
LoadCompressedSpritePalette(&sTypeIconPal2);
}
static void LoadTypeIconsPerBattler(u32 battler, u32 position)
{
u32 typeNum, types[2];
u32 battlerId = GetBattlerAtPosition(position);
bool32 useDoubleBattleCoords = UseDoubleBattleCoords(battlerId);
if (!IsBattlerAlive(battlerId))
return;
for (typeNum = 0; typeNum < 2; ++typeNum)
types[typeNum] = GetMonPublicType(battlerId, typeNum);
for (typeNum = 0; typeNum < 2; ++typeNum)
CreateSpriteFromType(position, useDoubleBattleCoords, types, typeNum, battler);
}
static bool32 UseDoubleBattleCoords(u32 position)
{
if (!IsDoubleBattle())
return FALSE;
if ((position == B_POSITION_PLAYER_LEFT) && (gBattleMons[B_POSITION_PLAYER_RIGHT].species == SPECIES_NONE))
return FALSE;
if ((position == B_POSITION_OPPONENT_LEFT) && (gBattleMons[B_POSITION_OPPONENT_RIGHT].species == SPECIES_NONE))
return FALSE;
return TRUE;
}
static u32 GetMonPublicType(u32 battlerId, u32 typeNum)
{
struct Pokemon* mon = GetPartyBattlerData(battlerId);
u32 monSpecies = GetMonData(mon,MON_DATA_SPECIES,NULL);
struct Pokemon* monIllusion;
u32 illusionSpecies;
if (ShouldHideUncaughtType(monSpecies))
return TYPE_MYSTERY;
monIllusion = GetIllusionMonPtr(battlerId);
illusionSpecies = GetMonData(monIllusion,MON_DATA_SPECIES,NULL);
if (GetActiveGimmick(battlerId) == GIMMICK_TERA)
return GetMonDefensiveTeraType(mon,monIllusion,battlerId,typeNum,illusionSpecies,monSpecies);
if (IsIllusionActiveAndTypeUnchanged(monIllusion,monSpecies, battlerId))
return gSpeciesInfo[illusionSpecies].types[typeNum];
return gBattleMons[battlerId].types[typeNum];
}
static bool32 ShouldHideUncaughtType(u32 species)
{
if (B_SHOW_TYPES != SHOW_TYPES_CAUGHT)
return FALSE;
if (GetSetPokedexFlag(SpeciesToNationalDexNum(species),FLAG_GET_CAUGHT))
return FALSE;
return TRUE;
}
static u32 GetMonDefensiveTeraType(struct Pokemon * mon, struct Pokemon* monIllusion, u32 battlerId, u32 typeNum, u32 illusionSpecies, u32 monSpecies)
{
u32 teraType = GetBattlerTeraType(battlerId);
u32 targetSpecies;
if (teraType != TYPE_STELLAR)
return teraType;
targetSpecies = (monIllusion != NULL) ? illusionSpecies : monSpecies;
return gSpeciesInfo[targetSpecies].types[typeNum];
}
static u32 IsIllusionActiveAndTypeUnchanged(struct Pokemon* monIllusion, u32 monSpecies, u32 battlerId)
{
u32 typeNum;
if (monIllusion == NULL)
return FALSE;
for (typeNum = 0; typeNum < 2; typeNum++)
if (gSpeciesInfo[monSpecies].types[typeNum] != gBattleMons[battlerId].types[typeNum])
return FALSE;
return TRUE;
}
static void CreateSpriteFromType(u32 position, bool32 useDoubleBattleCoords, u32 types[], u32 typeNum, u32 battler)
{
s32 x = 0, y = 0;
if (ShouldSkipSecondType(types, typeNum))
return;
SetTypeIconXY(&x, &y, position, useDoubleBattleCoords, typeNum);
CreateSpriteAndSetTypeSpriteAttributes(types[typeNum], x, y, position, battler, useDoubleBattleCoords);
}
static bool32 ShouldSkipSecondType(u32 types[], u32 typeNum)
{
if (!typeNum)
return FALSE;
if (types[0] != types[1])
return FALSE;
return TRUE;
}
static void SetTypeIconXY(s32* x, s32* y, u32 position, bool32 useDoubleBattleCoords, u32 typeNum)
{
*x = sTypeIconPositions[position][useDoubleBattleCoords].x;
*y = sTypeIconPositions[position][useDoubleBattleCoords].y + (11 * typeNum);
}
static void CreateSpriteAndSetTypeSpriteAttributes(u32 type, u32 x, u32 y, u32 position, u32 battler, bool32 useDoubleBattleCoords)
{
struct Sprite* sprite;
const struct SpriteTemplate* spriteTemplate = gTypesInfo[type].useSecondTypeIconPalette ? &sSpriteTemplate_TypeIcons2 : &sSpriteTemplate_TypeIcons1;
u32 spriteId = CreateSpriteAtEnd(spriteTemplate, x, y, UCHAR_MAX);
if (spriteId == MAX_SPRITES)
return;
sprite = &gSprites[spriteId];
sprite->tMonPosition = position;
sprite->tBattlerId = battler;
sprite->tVerticalPosition = y;
sprite->hFlip = ShouldFlipTypeIcon(useDoubleBattleCoords, position, type);
StartSpriteAnim(sprite, type);
}
static bool32 ShouldFlipTypeIcon(bool32 useDoubleBattleCoords, u32 position, u32 typeId)
{
bool32 side = (useDoubleBattleCoords) ? B_SIDE_OPPONENT : B_SIDE_PLAYER;
if (GetBattlerSide(GetBattlerAtPosition(position)) != side)
return FALSE;
return !gTypesInfo[typeId].isSpecialCaseType;
}
static void SpriteCB_TypeIcon(struct Sprite* sprite)
{
u32 position = sprite->tMonPosition;
u32 battlerId = sprite->tBattlerId;
bool32 useDoubleBattleCoords = UseDoubleBattleCoords(GetBattlerAtPosition(position));
if (sprite->tHideIconTimer == NUM_FRAMES_HIDE_TYPE_ICON)
{
DestroyTypeIcon(sprite);
return;
}
if (ShouldHideTypeIcon(battlerId))
{
sprite->x += GetTypeIconHideMovement(useDoubleBattleCoords, position);
++sprite->tHideIconTimer;
return;
}
sprite->x += GetTypeIconSlideMovement(useDoubleBattleCoords,position, sprite->x);
sprite->y = GetTypeIconBounceMovement(sprite->tVerticalPosition,position);
}
static const u32 typeIconTags[] =
{
TYPE_ICON_TAG,
TYPE_ICON_TAG_2
};
static void DestroyTypeIcon(struct Sprite* sprite)
{
u32 spriteId, tag;
DestroySpriteAndFreeResources(sprite);
for (spriteId = 0; spriteId < MAX_SPRITES; ++spriteId)
{
if (!gSprites[spriteId].inUse)
continue;
for (tag = 0; tag < 2; tag++)
{
if (gSprites[spriteId].template->paletteTag == typeIconTags[tag])
return;
if (gSprites[spriteId].template->tileTag == typeIconTags[tag])
return;
}
}
FreeAllTypeIconResources();
}
static void FreeAllTypeIconResources(void)
{
u32 tag;
for (tag = 0; tag < 2; tag++)
{
FreeSpriteTilesByTag(typeIconTags[tag]);
FreeSpritePaletteByTag(typeIconTags[tag]);
}
}
static void (* const sShowTypesControllerFuncs[])(u32 battler) =
{
PlayerHandleChooseMove,
HandleChooseMoveAfterDma3,
HandleInputChooseTarget,
HandleInputShowTargets,
HandleInputShowEntireFieldTargets,
HandleMoveSwitching,
HandleInputChooseMove,
};
static bool32 ShouldHideTypeIcon(u32 battlerId)
{
u32 funcIndex;
for (funcIndex = 0; funcIndex < ARRAY_COUNT(sShowTypesControllerFuncs); funcIndex++)
if (gBattlerControllerFuncs[battlerId] == sShowTypesControllerFuncs[funcIndex])
return FALSE;
return TRUE;
}
static s32 GetTypeIconHideMovement(bool32 useDoubleBattleCoords, u32 position)
{
if (useDoubleBattleCoords)
{
if (position == B_POSITION_PLAYER_LEFT || position == B_POSITION_PLAYER_RIGHT)
return 1;
else
return -1;
}
if (position == B_POSITION_PLAYER_LEFT)
return -1;
else
return 1;
}
static s32 GetTypeIconSlideMovement(bool32 useDoubleBattleCoords, u32 position, s32 xPos)
{
if (useDoubleBattleCoords)
{
switch (position)
{
case B_POSITION_PLAYER_LEFT:
case B_POSITION_PLAYER_RIGHT:
if (xPos > sTypeIconPositions[position][useDoubleBattleCoords].x - 10)
return -1;
break;
default:
case B_POSITION_OPPONENT_LEFT:
case B_POSITION_OPPONENT_RIGHT:
if (xPos < sTypeIconPositions[position][useDoubleBattleCoords].x + 10)
return 1;
break;
}
return 0;
}
if (position == B_POSITION_PLAYER_LEFT)
{
if (xPos < sTypeIconPositions[position][useDoubleBattleCoords].x + 10)
return 1;
}
else
{
if (xPos > sTypeIconPositions[position][useDoubleBattleCoords].x - 10)
return -1;
}
return 0;
}
static s32 GetTypeIconBounceMovement(s32 originalY, u32 position)
{
struct Sprite* healthbox = &gSprites[gHealthboxSpriteIds[GetBattlerAtPosition(position)]];
return originalY + healthbox->y2;
}