diff options
author | golem galvanize <golemgalvanize@github.com> | 2018-02-13 22:12:02 -0500 |
---|---|---|
committer | golem galvanize <golemgalvanize@github.com> | 2018-02-13 22:12:02 -0500 |
commit | e5b6d15f9163cca8688cd67ca5a0563ce6667601 (patch) | |
tree | 5492d50f51f51acca9cf1861c7b5936182649364 /src | |
parent | 42cfbcb197bb271e675a4b2b9e70a2647bd65532 (diff) | |
parent | 398e775d906ff4f1e5aaad3d8a9eee530c7b122d (diff) |
move data to c
Diffstat (limited to 'src')
59 files changed, 17668 insertions, 6038 deletions
diff --git a/src/battle_ai_script_commands.c b/src/battle_ai_script_commands.c index 355d81d2c..d6ccf9305 100644 --- a/src/battle_ai_script_commands.c +++ b/src/battle_ai_script_commands.c @@ -2,6 +2,7 @@ #include "battle_ai_script_commands.h" #include "pokemon.h" #include "battle.h" +#include "battle_setup.h" #include "constants/species.h" #include "constants/abilities.h" #include "random.h" @@ -44,26 +45,7 @@ in order to read the next command correctly. refer to battle_ai_scripts.s for th AI scripts. */ -extern u32 gBattleTypeFlags; -extern u8 gActiveBattler; -extern struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT]; -extern u16 gCurrentMove; -extern u8 gBattlerTarget; -extern u8 gAbsentBattlerFlags; -extern u16 gLastMoves[MAX_BATTLERS_COUNT]; -extern u16 gTrainerBattleOpponent_A; -extern u16 gTrainerBattleOpponent_B; -extern u32 gStatuses3[MAX_BATTLERS_COUNT]; -extern u16 gSideStatuses[2]; -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; -extern u16 gDynamicBasePower; -extern u8 gMoveResultFlags; -extern s32 gBattleMoveDamage; -extern u8 gCritMultiplier; -extern u16 gBattleWeather; - extern const struct BattleMove gBattleMoves[]; -extern const struct BaseStats gBaseStats[]; extern const u8 * const gBattleAI_ScriptsTable[]; extern u32 GetAiScriptsInRecordedBattle(); diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 23d223308..c3bb0d422 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -8,23 +8,8 @@ #include "random.h" #include "util.h" #include "constants/items.h" -#include "pokemon_item_effects.h" - -extern u8 gActiveBattler; -extern u8 gAbsentBattlerFlags; -extern u32 gBattleTypeFlags; -extern u32 gStatuses3[MAX_BATTLERS_COUNT]; -extern struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT]; -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; -extern u16 gLastLandedMoves[MAX_BATTLERS_COUNT]; -extern u8 gLastHitBy[MAX_BATTLERS_COUNT]; -extern u16 gDynamicBasePower; -extern u8 gMoveResultFlags; -extern u8 gCritMultiplier; -extern s32 gBattleMoveDamage; extern const struct BattleMove gBattleMoves[]; -extern const struct BaseStats gBaseStats[]; extern const u8 gTypeEffectiveness[]; extern const u8 * const gItemEffectTable[]; // todo: fix once struct is declared diff --git a/src/battle_anim.c b/src/battle_anim.c index 34b7a7476..7606f701d 100644 --- a/src/battle_anim.c +++ b/src/battle_anim.c @@ -25,8 +25,6 @@ #define ANIM_SPRITE_INDEX_COUNT 8 -extern u8 gBattlerAttacker; -extern u8 gBattlerTarget; extern u16 gBattle_WIN0H; extern u16 gBattle_WIN0V; extern u16 gBattle_WIN1H; @@ -35,12 +33,9 @@ extern u16 gBattle_BG1_X; extern u16 gBattle_BG1_Y; extern u16 gBattle_BG2_X; extern u16 gBattle_BG2_Y; -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; -extern u8 gBattlerSpriteIds[MAX_BATTLERS_COUNT]; extern struct MusicPlayerInfo gMPlayInfo_BGM; extern struct MusicPlayerInfo gMPlayInfo_SE1; extern struct MusicPlayerInfo gMPlayInfo_SE2; -extern u8 gDecompressionBuffer[]; extern const u16 gUnknown_082C8D64[]; extern const u8 * const gBattleAnims_Moves[]; diff --git a/src/battle_bg.c b/src/battle_bg.c index 51c54f0a3..f493bafea 100644 --- a/src/battle_bg.c +++ b/src/battle_bg.c @@ -18,6 +18,7 @@ #include "window.h" #include "text_window.h" #include "menu.h" +#include "battle_setup.h" struct BattleBackground { @@ -35,13 +36,10 @@ extern const struct BgTemplate gUnknown_0831AA08[4]; extern const struct WindowTemplate *gUnknown_0831ABA0[]; extern const struct BattleBackground gBattleTerrainTable[]; -extern u8 gBattleTerrain; -extern u16 gTrainerBattleOpponent_A; extern u16 gBattle_BG1_X; extern u16 gBattle_BG1_Y; extern u16 gBattle_BG2_X; extern u16 gBattle_BG2_Y; -extern u16 gPartnerTrainerId; extern u8 GetCurrentMapBattleScene(void); diff --git a/src/battle_controller_link_opponent.c b/src/battle_controller_link_opponent.c index 1b12a7a80..a399adf25 100644 --- a/src/battle_controller_link_opponent.c +++ b/src/battle_controller_link_opponent.c @@ -24,47 +24,21 @@ #include "reshow_battle_screen.h" #include "pokeball.h" #include "data2.h" +#include "battle_setup.h" -extern u32 gBattleControllerExecFlags; -extern u8 gActiveBattler; -extern u8 gBattlerSpriteIds[MAX_BATTLERS_COUNT]; -extern u8 gActionSelectionCursor[MAX_BATTLERS_COUNT]; -extern u8 gBattlersCount; -extern bool8 gDoingBattleAnim; -extern void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(void); -extern void (*gPreBattleCallback1)(void); -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; -extern u8 gBattleBufferA[MAX_BATTLERS_COUNT][0x200]; -extern u8 gBattleBufferB[MAX_BATTLERS_COUNT][0x200]; -extern struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT]; -extern struct SpriteTemplate gUnknown_0202499C; -extern u16 gSpecialVar_ItemId; -extern u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT]; -extern u8 gBattleOutcome; extern u16 gBattle_BG0_X; extern u16 gBattle_BG0_Y; -extern u16 gUnknown_020243FC; -extern u8 gUnknown_03005D7C[MAX_BATTLERS_COUNT]; -extern u8 gBattleMonForms[MAX_BATTLERS_COUNT]; -extern u16 gPartnerTrainerId; -extern u8 GetFrontierTrainerFrontSpriteId(u16 trainerId); -extern u8 gBattlerTarget; -extern u8 gAbsentBattlerFlags; -extern u8 gUnknown_020244B4[]; -extern u32 gTransformedPersonalities[MAX_BATTLERS_COUNT]; extern struct MusicPlayerInfo gMPlayInfo_BGM; extern struct UnusedControllerStruct gUnknown_02022D0C; -extern u16 gTrainerBattleOpponent_A; -extern u16 gTrainerBattleOpponent_B; extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[]; extern const struct BattleMove gBattleMoves[]; -extern const u8 gFacilityClassToPicIndex[]; extern void sub_8172EF0(u8 bank, struct Pokemon *mon); extern void sub_806A068(u16, u8); extern void sub_81851A8(u8 *); extern u16 sub_8068B48(void); +extern u8 GetFrontierTrainerFrontSpriteId(u16 trainerId); // this file's functions static void LinkOpponentHandleGetMonData(void); @@ -1270,7 +1244,7 @@ static void LinkOpponentHandleDrawTrainerPic(void) if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) { - if (gActiveBattler == 1) + if (gActiveBattler == B_POSITION_OPPONENT_LEFT) trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_A); else trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_B); @@ -1280,18 +1254,18 @@ static void LinkOpponentHandleDrawTrainerPic(void) if ((gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_FIRE_RED || (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_LEAF_GREEN) { - if (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].gender != 0) - trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_10]; + if (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].gender != MALE) + trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_LEAF]; else - trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_9]; + trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_RED]; } else if ((gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_RUBY || (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_SAPPHIRE) { - if (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].gender != 0) - trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_12]; + if (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].gender != MALE) + trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_RS_MAY]; else - trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_11]; + trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_RS_BRENDAN]; } else { @@ -1310,17 +1284,17 @@ static void LinkOpponentHandleDrawTrainerPic(void) || (gLinkPlayers[GetMultiplayerId() ^ BIT_SIDE].version & 0xFF) == VERSION_LEAF_GREEN) { if (gLinkPlayers[GetMultiplayerId() ^ BIT_SIDE].gender != 0) - trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_10]; + trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_LEAF]; else - trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_9]; + trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_RED]; } else if ((gLinkPlayers[GetMultiplayerId() ^ BIT_SIDE].version & 0xFF) == VERSION_RUBY || (gLinkPlayers[GetMultiplayerId() ^ BIT_SIDE].version & 0xFF) == VERSION_SAPPHIRE) { if (gLinkPlayers[GetMultiplayerId() ^ BIT_SIDE].gender != 0) - trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_12]; + trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_RS_MAY]; else - trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_11]; + trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_RS_BRENDAN]; } else { @@ -1722,7 +1696,7 @@ static void LinkOpponentHandleFaintingCry(void) static void LinkOpponentHandleIntroSlide(void) { HandleIntroSlide(gBattleBufferA[gActiveBattler][1]); - gUnknown_020243FC |= 1; + gIntroSlideFlags |= 1; LinkOpponentBufferExecCompleted(); } @@ -1744,7 +1718,7 @@ static void LinkOpponentHandleIntroTrainerBallThrow(void) gTasks[taskId].data[0] = gActiveBattler; if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x1) - gTasks[gUnknown_020244B4[gActiveBattler]].func = sub_8073C30; + gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = sub_8073C30; gBattleSpritesDataPtr->animationData->field_9_x1 = 1; gBattlerControllerFuncs[gActiveBattler] = nullsub_28; @@ -1804,7 +1778,7 @@ static void LinkOpponentHandleDrawPartyStatusSummary(void) } } - gUnknown_020244B4[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleBufferA[gActiveBattler][4], gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][2]); + gBattlerStatusSummaryTaskId[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleBufferA[gActiveBattler][4], gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][2]); gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_5 = 0; if (gBattleBufferA[gActiveBattler][2] != 0) @@ -1826,7 +1800,7 @@ static void sub_806782C(void) static void LinkOpponentHandleCmd49(void) { if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x1) - gTasks[gUnknown_020244B4[gActiveBattler]].func = sub_8073C30; + gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = sub_8073C30; LinkOpponentBufferExecCompleted(); } diff --git a/src/battle_controller_link_partner.c b/src/battle_controller_link_partner.c index 340a2b566..1734abe62 100644 --- a/src/battle_controller_link_partner.c +++ b/src/battle_controller_link_partner.c @@ -23,34 +23,10 @@ #include "reshow_battle_screen.h" #include "pokeball.h" #include "data2.h" +#include "battle_setup.h" -extern u32 gBattleControllerExecFlags; -extern u8 gActiveBattler; -extern u8 gBattlerSpriteIds[MAX_BATTLERS_COUNT]; -extern u8 gActionSelectionCursor[MAX_BATTLERS_COUNT]; -extern u8 gBattlersCount; -extern bool8 gDoingBattleAnim; -extern void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(void); -extern void (*gPreBattleCallback1)(void); -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; -extern u8 gBattleBufferA[MAX_BATTLERS_COUNT][0x200]; -extern u8 gBattleBufferB[MAX_BATTLERS_COUNT][0x200]; -extern struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT]; -extern struct SpriteTemplate gUnknown_0202499C; -extern u16 gSpecialVar_ItemId; -extern u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT]; -extern u8 gBattleOutcome; extern u16 gBattle_BG0_X; extern u16 gBattle_BG0_Y; -extern u16 gUnknown_020243FC; -extern u8 gUnknown_03005D7C[MAX_BATTLERS_COUNT]; -extern u8 gBattleMonForms[MAX_BATTLERS_COUNT]; -extern u16 gPartnerTrainerId; -extern u8 GetFrontierTrainerFrontSpriteId(u16 trainerId); -extern u8 gBattlerTarget; -extern u8 gAbsentBattlerFlags; -extern u8 gUnknown_020244B4[]; -extern u32 gTransformedPersonalities[MAX_BATTLERS_COUNT]; extern struct UnusedControllerStruct gUnknown_02022D0C; extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[]; @@ -60,6 +36,7 @@ extern const struct BattleMove gBattleMoves[]; extern void sub_8172EF0(u8 bank, struct Pokemon *mon); extern void sub_806A068(u16, u8); extern void sub_81851A8(u8 *); +extern u8 GetFrontierTrainerFrontSpriteId(u16 trainerId); // this file's functions static void LinkPartnerHandleGetMonData(void); @@ -1543,7 +1520,7 @@ static void LinkPartnerHandleFaintingCry(void) static void LinkPartnerHandleIntroSlide(void) { HandleIntroSlide(gBattleBufferA[gActiveBattler][1]); - gUnknown_020243FC |= 1; + gIntroSlideFlags |= 1; LinkPartnerBufferExecCompleted(); } @@ -1589,7 +1566,7 @@ static void LinkPartnerHandleIntroTrainerBallThrow(void) gTasks[taskId].data[0] = gActiveBattler; if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x1) - gTasks[gUnknown_020244B4[gActiveBattler]].func = sub_8073C30; + gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = sub_8073C30; gBattleSpritesDataPtr->animationData->field_9_x1 = 1; gBattlerControllerFuncs[gActiveBattler] = nullsub_112; @@ -1636,7 +1613,7 @@ static void LinkPartnerHandleDrawPartyStatusSummary(void) else { gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x1 = 1; - gUnknown_020244B4[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleBufferA[gActiveBattler][4], gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][2]); + gBattlerStatusSummaryTaskId[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleBufferA[gActiveBattler][4], gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][2]); gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_5 = 0; if (gBattleBufferA[gActiveBattler][2] != 0) @@ -1658,7 +1635,7 @@ static void sub_814DE9C(void) static void LinkPartnerHandleCmd49(void) { if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x1) - gTasks[gUnknown_020244B4[gActiveBattler]].func = sub_8073C30; + gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = sub_8073C30; LinkPartnerBufferExecCompleted(); } diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c index 760205d90..26e0191cb 100644 --- a/src/battle_controller_opponent.c +++ b/src/battle_controller_opponent.c @@ -27,33 +27,12 @@ #include "random.h" #include "pokeball.h" #include "data2.h" +#include "battle_setup.h" -extern u32 gBattleControllerExecFlags; -extern u8 gActiveBattler; -extern u8 gBattlerTarget; -extern u8 gAbsentBattlerFlags; -extern bool8 gDoingBattleAnim; -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; -extern u8 gBattlerSpriteIds[MAX_BATTLERS_COUNT]; -extern u8 gBattleBufferA[MAX_BATTLERS_COUNT][0x200]; -extern u8 gBattleBufferB[MAX_BATTLERS_COUNT][0x200]; -extern u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT]; -extern struct MusicPlayerInfo gMPlayInfo_BGM; -extern u8 gUnknown_03005D7C[MAX_BATTLERS_COUNT]; -extern void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(void); -extern void *gUnknown_020244D8; -extern void *gUnknown_020244DC; -extern u8 gBattleMonForms[MAX_BATTLERS_COUNT]; -extern struct SpriteTemplate gUnknown_0202499C; -extern struct UnusedControllerStruct gUnknown_02022D0C; -extern u16 gTrainerBattleOpponent_A; -extern u16 gTrainerBattleOpponent_B; -extern u32 gTransformedPersonalities[MAX_BATTLERS_COUNT]; extern u16 gBattle_BG0_X; extern u16 gBattle_BG0_Y; -extern u16 gUnknown_020243FC; -extern u8 gUnknown_020244B4[]; -extern void (*gPreBattleCallback1)(void); +extern struct MusicPlayerInfo gMPlayInfo_BGM; +extern struct UnusedControllerStruct gUnknown_02022D0C; extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[]; extern const struct BattleMove gBattleMoves[]; @@ -1866,7 +1845,7 @@ static void OpponentHandleFaintingCry(void) static void OpponentHandleIntroSlide(void) { HandleIntroSlide(gBattleBufferA[gActiveBattler][1]); - gUnknown_020243FC |= 1; + gIntroSlideFlags |= 1; OpponentBufferExecCompleted(); } @@ -1888,7 +1867,7 @@ static void OpponentHandleIntroTrainerBallThrow(void) gTasks[taskId].data[0] = gActiveBattler; if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x1) - gTasks[gUnknown_020244B4[gActiveBattler]].func = sub_8073C30; + gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = sub_8073C30; gBattleSpritesDataPtr->animationData->field_9_x1 = 1; gBattlerControllerFuncs[gActiveBattler] = nullsub_26; @@ -1953,7 +1932,7 @@ static void OpponentHandleDrawPartyStatusSummary(void) } } - gUnknown_020244B4[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleBufferA[gActiveBattler][4], gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][2]); + gBattlerStatusSummaryTaskId[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleBufferA[gActiveBattler][4], gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][2]); gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_5 = 0; if (gBattleBufferA[gActiveBattler][2] != 0) @@ -1975,7 +1954,7 @@ static void sub_8062A2C(void) static void OpponentHandleCmd49(void) { if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x1) - gTasks[gUnknown_020244B4[gActiveBattler]].func = sub_8073C30; + gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = sub_8073C30; OpponentBufferExecCompleted(); } diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 08af2e902..8847715f6 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -26,44 +26,19 @@ #include "random.h" #include "pokeball.h" #include "data2.h" +#include "battle_setup.h" +#include "item_use.h" +#include "recorded_battle.h" -extern u32 gBattleControllerExecFlags; -extern u8 gActiveBattler; -extern u8 gBattlerSpriteIds[MAX_BATTLERS_COUNT]; -extern u8 gActionSelectionCursor[MAX_BATTLERS_COUNT]; -extern u8 gMoveSelectionCursor[MAX_BATTLERS_COUNT]; -extern u8 gAbsentBattlerFlags; -extern u8 gBattlersCount; -extern bool8 gDoingBattleAnim; -extern u8 gPlayerDpadHoldFrames; -extern void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(void); -extern void (*gPreBattleCallback1)(void); -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; -extern u8 gBattleBufferA[MAX_BATTLERS_COUNT][0x200]; -extern u8 gBattleBufferB[MAX_BATTLERS_COUNT][0x200]; -extern u8 gMultiUsePlayerCursor; -extern struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT]; -extern struct MusicPlayerInfo gMPlayInfo_BGM; -extern u16 gPartnerTrainerId; -extern struct SpriteTemplate gUnknown_0202499C; -extern u8 gBattleMonForms[MAX_BATTLERS_COUNT]; -extern u16 gSpecialVar_ItemId; extern u8 gUnknown_0203CEE8; extern u8 gUnknown_0203CEE9; extern u8 gUnknown_0203CF00[]; -extern u8 gUnknown_03005D7C[MAX_BATTLERS_COUNT]; -extern u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT]; -extern u8 gBattleOutcome; -extern u8 gNumberOfMovesToChoose; extern u16 gBattle_BG0_X; extern u16 gBattle_BG0_Y; extern s32 gUnknown_0203CD70; -extern u8 gBankInMenu; -extern u32 gBattlePalaceMoveSelectionRngValue; -extern u32 gTransformedPersonalities[MAX_BATTLERS_COUNT]; -extern u8 gUnknown_020244B4[]; -extern u16 gUnknown_020243FC; extern struct UnusedControllerStruct gUnknown_02022D0C; +extern struct MusicPlayerInfo gMPlayInfo_BGM; +extern struct SpriteTemplate gUnknown_0202499C; extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[]; extern const struct CompressedSpritePalette gTrainerBackPicPaletteTable[]; @@ -897,7 +872,7 @@ static void HandleMoveSwitchting(void) static void sub_80586F8(void) { - if (gLinkVSyncDisabled == 0) + if (gWirelessCommType == 0) { if (gReceivedRemoteLinkPlayers == 0) { @@ -933,7 +908,7 @@ void sub_80587B0(void) { if (sub_800A520()) { - if (gLinkVSyncDisabled == 0) + if (gWirelessCommType == 0) sub_800AC34(); else sub_800ADF8(); @@ -2677,7 +2652,7 @@ static void PlayerHandleChooseItem(void) BeginNormalPaletteFade(-1, 0, 0, 0x10, 0); gBattlerControllerFuncs[gActiveBattler] = OpenBagAndChooseItem; - gBankInMenu = gActiveBattler; + gBattlerInMenuId = gActiveBattler; for (i = 0; i < 3; i++) gUnknown_0203CF00[i] = gBattleBufferA[gActiveBattler][1 + i]; @@ -2704,7 +2679,7 @@ static void PlayerHandleChoosePokemon(void) *(&gBattleStruct->field_B0) = gBattleBufferA[gActiveBattler][3]; BeginNormalPaletteFade(-1, 0, 0, 16, 0); gBattlerControllerFuncs[gActiveBattler] = sub_80597CC; - gBankInMenu = gActiveBattler; + gBattlerInMenuId = gActiveBattler; } } @@ -2953,7 +2928,7 @@ static void PlayerHandleFaintingCry(void) static void PlayerHandleIntroSlide(void) { HandleIntroSlide(gBattleBufferA[gActiveBattler][1]); - gUnknown_020243FC |= 1; + gIntroSlideFlags |= 1; PlayerBufferExecCompleted(); } @@ -2981,7 +2956,7 @@ static void PlayerHandleIntroTrainerBallThrow(void) gTasks[taskId].data[0] = gActiveBattler; if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x1) - gTasks[gUnknown_020244B4[gActiveBattler]].func = sub_8073C30; + gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = sub_8073C30; gBattleSpritesDataPtr->animationData->field_9_x1 = 1; gBattlerControllerFuncs[gActiveBattler] = nullsub_21; @@ -3039,7 +3014,7 @@ static void PlayerHandleDrawPartyStatusSummary(void) else { gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x1 = 1; - gUnknown_020244B4[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleBufferA[gActiveBattler][4], gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][2]); + gBattlerStatusSummaryTaskId[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleBufferA[gActiveBattler][4], gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][2]); gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_5 = 0; if (gBattleBufferA[gActiveBattler][2] != 0) @@ -3061,7 +3036,7 @@ static void sub_805CE38(void) static void PlayerHandleCmd49(void) { if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x1) - gTasks[gUnknown_020244B4[gActiveBattler]].func = sub_8073C30; + gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = sub_8073C30; PlayerBufferExecCompleted(); } diff --git a/src/battle_controller_player_partner.c b/src/battle_controller_player_partner.c index b2b6baa0a..d2f85f85e 100644 --- a/src/battle_controller_player_partner.c +++ b/src/battle_controller_player_partner.c @@ -22,35 +22,11 @@ #include "reshow_battle_screen.h" #include "pokeball.h" #include "data2.h" +#include "battle_setup.h" +#include "item_use.h" -extern u32 gBattleControllerExecFlags; -extern u8 gActiveBattler; -extern u8 gBattlerSpriteIds[MAX_BATTLERS_COUNT]; -extern u8 gActionSelectionCursor[MAX_BATTLERS_COUNT]; -extern u8 gBattlersCount; -extern bool8 gDoingBattleAnim; -extern void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(void); -extern void (*gPreBattleCallback1)(void); -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; -extern u8 gBattleBufferA[MAX_BATTLERS_COUNT][0x200]; -extern u8 gBattleBufferB[MAX_BATTLERS_COUNT][0x200]; -extern struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT]; -extern struct SpriteTemplate gUnknown_0202499C; -extern u16 gSpecialVar_ItemId; -extern u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT]; -extern u8 gBattleOutcome; extern u16 gBattle_BG0_X; extern u16 gBattle_BG0_Y; -extern u8 gBankInMenu; -extern u16 gUnknown_020243FC; -extern u8 gUnknown_03005D7C[MAX_BATTLERS_COUNT]; -extern u8 gBattleMonForms[MAX_BATTLERS_COUNT]; -extern u16 gPartnerTrainerId; -extern u8 GetFrontierTrainerFrontSpriteId(u16 trainerId); -extern u8 gBattlerTarget; -extern u8 gAbsentBattlerFlags; -extern u8 gUnknown_020244B4[]; -extern u32 gTransformedPersonalities[MAX_BATTLERS_COUNT]; extern struct UnusedControllerStruct gUnknown_02022D0C; extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[]; @@ -60,6 +36,7 @@ extern const struct BattleMove gBattleMoves[]; extern void sub_81358F4(void); extern void sub_8172EF0(u8 bank, struct Pokemon *mon); extern void sub_806A068(u16, u8); +extern u8 GetFrontierTrainerFrontSpriteId(u16 trainerId); // this file's functions static void PlayerPartnerHandleGetMonData(void); @@ -1796,7 +1773,7 @@ static void PlayerPartnerHandleFaintingCry(void) static void PlayerPartnerHandleIntroSlide(void) { HandleIntroSlide(gBattleBufferA[gActiveBattler][1]); - gUnknown_020243FC |= 1; + gIntroSlideFlags |= 1; PlayerPartnerBufferExecCompleted(); } @@ -1835,7 +1812,7 @@ static void PlayerPartnerHandleIntroTrainerBallThrow(void) gTasks[taskId].data[0] = gActiveBattler; if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x1) - gTasks[gUnknown_020244B4[gActiveBattler]].func = sub_8073C30; + gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = sub_8073C30; gBattleSpritesDataPtr->animationData->field_9_x1 = 1; gBattlerControllerFuncs[gActiveBattler] = nullsub_77; @@ -1882,7 +1859,7 @@ static void PlayerPartnerHandleDrawPartyStatusSummary(void) else { gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x1 = 1; - gUnknown_020244B4[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleBufferA[gActiveBattler][4], gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][2]); + gBattlerStatusSummaryTaskId[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleBufferA[gActiveBattler][4], gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][2]); gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_5 = 0; if (gBattleBufferA[gActiveBattler][2] != 0) @@ -1904,7 +1881,7 @@ static void sub_81BE498(void) static void PlayerPartnerHandleCmd49(void) { if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x1) - gTasks[gUnknown_020244B4[gActiveBattler]].func = sub_8073C30; + gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = sub_8073C30; PlayerPartnerBufferExecCompleted(); } diff --git a/src/battle_controller_recorded_opponent.c b/src/battle_controller_recorded_opponent.c index 8078d0af2..2295c4a75 100644 --- a/src/battle_controller_recorded_opponent.c +++ b/src/battle_controller_recorded_opponent.c @@ -24,38 +24,13 @@ #include "reshow_battle_screen.h" #include "pokeball.h" #include "data2.h" +#include "item_use.h" +#include "battle_setup.h" -extern u32 gBattleControllerExecFlags; -extern u8 gActiveBattler; -extern u8 gBattlerSpriteIds[MAX_BATTLERS_COUNT]; -extern u8 gActionSelectionCursor[MAX_BATTLERS_COUNT]; -extern u8 gBattlersCount; -extern bool8 gDoingBattleAnim; -extern void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(void); -extern void (*gPreBattleCallback1)(void); -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; -extern u8 gBattleBufferA[MAX_BATTLERS_COUNT][0x200]; -extern u8 gBattleBufferB[MAX_BATTLERS_COUNT][0x200]; -extern struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT]; -extern struct SpriteTemplate gUnknown_0202499C; -extern u16 gSpecialVar_ItemId; -extern u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT]; -extern u8 gBattleOutcome; extern u16 gBattle_BG0_X; extern u16 gBattle_BG0_Y; -extern u16 gUnknown_020243FC; -extern u8 gUnknown_03005D7C[MAX_BATTLERS_COUNT]; -extern u8 gBattleMonForms[MAX_BATTLERS_COUNT]; -extern u16 gPartnerTrainerId; -extern u8 GetFrontierTrainerFrontSpriteId(u16 trainerId); -extern u8 gBattlerTarget; -extern u8 gAbsentBattlerFlags; -extern u8 gUnknown_020244B4[]; -extern u32 gTransformedPersonalities[MAX_BATTLERS_COUNT]; extern struct MusicPlayerInfo gMPlayInfo_BGM; extern struct UnusedControllerStruct gUnknown_02022D0C; -extern u16 gTrainerBattleOpponent_A; -extern u16 gTrainerBattleOpponent_B; extern u8 gUnknown_0203C7B4; extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[]; @@ -63,6 +38,7 @@ extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[]; extern void sub_8172EF0(u8 bank, struct Pokemon *mon); extern void sub_806A068(u16, u8); extern u16 sub_8068B48(void); +extern u8 GetFrontierTrainerFrontSpriteId(u16 trainerId); // this file's functions static void RecordedOpponentHandleGetMonData(void); @@ -1258,7 +1234,7 @@ static void RecordedOpponentHandleDrawTrainerPic(void) } else { - trainerPicId = PlayerGenderToFrontTrainerPicId(GetActiveBankLinkPlayerGender()); + trainerPicId = PlayerGenderToFrontTrainerPicId(GetActiveBattlerLinkPlayerGender()); } } else @@ -1661,7 +1637,7 @@ static void RecordedOpponentHandleFaintingCry(void) static void RecordedOpponentHandleIntroSlide(void) { HandleIntroSlide(gBattleBufferA[gActiveBattler][1]); - gUnknown_020243FC |= 1; + gIntroSlideFlags |= 1; RecordedOpponentBufferExecCompleted(); } @@ -1683,7 +1659,7 @@ static void RecordedOpponentHandleIntroTrainerBallThrow(void) gTasks[taskId].data[0] = gActiveBattler; if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x1) - gTasks[gUnknown_020244B4[gActiveBattler]].func = sub_8073C30; + gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = sub_8073C30; gBattleSpritesDataPtr->animationData->field_9_x1 = 1; gBattlerControllerFuncs[gActiveBattler] = nullsub_70; @@ -1743,7 +1719,7 @@ static void RecordedOpponentHandleDrawPartyStatusSummary(void) } } - gUnknown_020244B4[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleBufferA[gActiveBattler][4], gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][2]); + gBattlerStatusSummaryTaskId[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleBufferA[gActiveBattler][4], gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][2]); gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_5 = 0; if (gBattleBufferA[gActiveBattler][2] != 0) @@ -1765,7 +1741,7 @@ static void sub_818975C(void) static void RecordedOpponentHandleCmd49(void) { if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x1) - gTasks[gUnknown_020244B4[gActiveBattler]].func = sub_8073C30; + gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = sub_8073C30; RecordedOpponentBufferExecCompleted(); } diff --git a/src/battle_controller_recorded_player.c b/src/battle_controller_recorded_player.c index 953f989e9..0d06e26eb 100644 --- a/src/battle_controller_recorded_player.c +++ b/src/battle_controller_recorded_player.c @@ -23,36 +23,11 @@ #include "reshow_battle_screen.h" #include "pokeball.h" #include "data2.h" +#include "item_use.h" -extern u32 gBattleControllerExecFlags; -extern u8 gActiveBattler; -extern u8 gBattlerSpriteIds[MAX_BATTLERS_COUNT]; -extern u8 gActionSelectionCursor[MAX_BATTLERS_COUNT]; -extern u8 gBattlersCount; -extern bool8 gDoingBattleAnim; -extern void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(void); -extern void (*gPreBattleCallback1)(void); -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; -extern u8 gBattleBufferA[MAX_BATTLERS_COUNT][0x200]; -extern u8 gBattleBufferB[MAX_BATTLERS_COUNT][0x200]; -extern struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT]; -extern struct SpriteTemplate gUnknown_0202499C; -extern u16 gSpecialVar_ItemId; -extern u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT]; -extern u8 gBattleOutcome; extern u16 gBattle_BG0_X; extern u16 gBattle_BG0_Y; -extern u8 gBankInMenu; -extern u16 gUnknown_020243FC; -extern u8 gUnknown_03005D7C[MAX_BATTLERS_COUNT]; -extern u8 gBattleMonForms[MAX_BATTLERS_COUNT]; -extern u16 gPartnerTrainerId; -extern u8 GetFrontierTrainerFrontSpriteId(u16 trainerId); -extern u8 gBattlerTarget; -extern u8 gAbsentBattlerFlags; -extern u8 gUnknown_020244B4[]; extern u32 gTransformedPersonalities[MAX_BATTLERS_COUNT]; -extern u8 gBattleCommunication[]; extern u8 gUnknown_0203C7B4; extern struct MusicPlayerInfo gMPlayInfo_BGM; extern struct UnusedControllerStruct gUnknown_02022D0C; @@ -63,6 +38,7 @@ extern const struct BattleMove gBattleMoves[]; extern void sub_8172EF0(u8 bank, struct Pokemon *mon); extern void sub_806A068(u16, u8); +extern u8 GetFrontierTrainerFrontSpriteId(u16 trainerId); // this file's functions static void RecordedPlayerHandleGetMonData(void); @@ -1230,7 +1206,7 @@ static void RecordedPlayerHandleDrawTrainerPic(void) if (gBattleTypeFlags & BATTLE_TYPE_x2000000) { if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - trainerPicId = GetActiveBankLinkPlayerGender(); + trainerPicId = GetActiveBattlerLinkPlayerGender(); else trainerPicId = gLinkPlayers[gUnknown_0203C7B4].gender; } @@ -1684,7 +1660,7 @@ static void RecordedPlayerHandleFaintingCry(void) static void RecordedPlayerHandleIntroSlide(void) { HandleIntroSlide(gBattleBufferA[gActiveBattler][1]); - gUnknown_020243FC |= 1; + gIntroSlideFlags |= 1; RecordedPlayerBufferExecCompleted(); } @@ -1719,7 +1695,7 @@ static void RecordedPlayerHandleIntroTrainerBallThrow(void) gTasks[taskId].data[0] = gActiveBattler; if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x1) - gTasks[gUnknown_020244B4[gActiveBattler]].func = sub_8073C30; + gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = sub_8073C30; gBattleSpritesDataPtr->animationData->field_9_x1 = 1; gBattlerControllerFuncs[gActiveBattler] = nullsub_120; @@ -1766,7 +1742,7 @@ static void RecordedPlayerHandleDrawPartyStatusSummary(void) else { gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x1 = 1; - gUnknown_020244B4[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleBufferA[gActiveBattler][4], gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][2]); + gBattlerStatusSummaryTaskId[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleBufferA[gActiveBattler][4], gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][2]); gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_5 = 0; if (gBattleBufferA[gActiveBattler][2] != 0) @@ -1788,7 +1764,7 @@ static void sub_818CDF4(void) static void RecordedPlayerHandleCmd49(void) { if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x1) - gTasks[gUnknown_020244B4[gActiveBattler]].func = sub_8073C30; + gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = sub_8073C30; RecordedPlayerBufferExecCompleted(); } diff --git a/src/battle_controller_safari.c b/src/battle_controller_safari.c index 608d59418..39eab24ee 100644 --- a/src/battle_controller_safari.c +++ b/src/battle_controller_safari.c @@ -21,27 +21,11 @@ #include "pokeball.h" #include "data2.h" #include "pokeblock.h" +#include "item_use.h" -extern u32 gBattleControllerExecFlags; -extern u8 gActiveBattler; -extern u8 gBattlerSpriteIds[MAX_BATTLERS_COUNT]; -extern u8 gActionSelectionCursor[MAX_BATTLERS_COUNT]; -extern u8 gBattlersCount; -extern bool8 gDoingBattleAnim; -extern void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(void); -extern void (*gPreBattleCallback1)(void); -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; -extern u8 gBattleBufferA[MAX_BATTLERS_COUNT][0x200]; -extern u8 gBattleBufferB[MAX_BATTLERS_COUNT][0x200]; extern struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT]; -extern struct SpriteTemplate gUnknown_0202499C; -extern u16 gSpecialVar_ItemId; -extern u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT]; -extern u8 gBattleOutcome; extern u16 gBattle_BG0_X; extern u16 gBattle_BG0_Y; -extern u8 gBankInMenu; -extern u16 gUnknown_020243FC; extern const struct CompressedSpritePalette gTrainerBackPicPaletteTable[]; @@ -500,7 +484,7 @@ static void SafariHandleChooseItem(void) BeginNormalPaletteFade(-1, 0, 0, 0x10, 0); gBattlerControllerFuncs[gActiveBattler] = SafariOpenPokeblockCase; - gBankInMenu = gActiveBattler; + gBattlerInMenuId = gActiveBattler; } static void SafariHandleChoosePokemon(void) @@ -648,7 +632,7 @@ static void SafariHandleFaintingCry(void) static void SafariHandleIntroSlide(void) { HandleIntroSlide(gBattleBufferA[gActiveBattler][1]); - gUnknown_020243FC |= 1; + gIntroSlideFlags |= 1; SafariBufferExecCompleted(); } diff --git a/src/battle_controller_wally.c b/src/battle_controller_wally.c index dd01e5996..445feaf7a 100644 --- a/src/battle_controller_wally.c +++ b/src/battle_controller_wally.c @@ -27,38 +27,12 @@ #include "pokeball.h" #include "data2.h" #include "party_menu.h" +#include "battle_setup.h" +#include "item_use.h" -extern u32 gBattleControllerExecFlags; -extern u8 gActiveBattler; -extern u8 gBattlerSpriteIds[MAX_BATTLERS_COUNT]; -extern u8 gActionSelectionCursor[MAX_BATTLERS_COUNT]; -extern u8 gMoveSelectionCursor[MAX_BATTLERS_COUNT]; -extern u8 gAbsentBattlerFlags; -extern u8 gBattlersCount; -extern bool8 gDoingBattleAnim; -extern void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(void); -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; -extern u8 gBattleBufferA[MAX_BATTLERS_COUNT][0x200]; -extern u8 gBattleBufferB[MAX_BATTLERS_COUNT][0x200]; -extern u8 gMultiUsePlayerCursor; -extern struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT]; -extern struct MusicPlayerInfo gMPlayInfo_BGM; -extern u16 gPartnerTrainerId; -extern struct SpriteTemplate gUnknown_0202499C; -extern u8 gBattleMonForms[MAX_BATTLERS_COUNT]; -extern u16 gSpecialVar_ItemId; -extern u8 gUnknown_03005D7C[MAX_BATTLERS_COUNT]; -extern u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT]; -extern u8 gBattleOutcome; -extern u8 gNumberOfMovesToChoose; extern u16 gBattle_BG0_X; extern u16 gBattle_BG0_Y; extern s32 gUnknown_0203CD70; -extern u8 gBankInMenu; -extern u32 gBattlePalaceMoveSelectionRngValue; -extern u32 gTransformedPersonalities[MAX_BATTLERS_COUNT]; -extern u8 gUnknown_020244B4[]; -extern u16 gUnknown_020243FC; extern struct UnusedControllerStruct gUnknown_02022D0C; extern const struct CompressedSpritePalette gTrainerBackPicPaletteTable[]; @@ -1282,7 +1256,7 @@ static void WallyHandleChooseItem(void) { BeginNormalPaletteFade(-1, 0, 0, 0x10, 0); gBattlerControllerFuncs[gActiveBattler] = OpenBagAfterPaletteFade; - gBankInMenu = gActiveBattler; + gBattlerInMenuId = gActiveBattler; } static void WallyHandleChoosePokemon(void) @@ -1452,7 +1426,7 @@ static void WallyHandleFaintingCry(void) static void WallyHandleIntroSlide(void) { HandleIntroSlide(gBattleBufferA[gActiveBattler][1]); - gUnknown_020243FC |= 1; + gIntroSlideFlags |= 1; WallyBufferExecCompleted(); } @@ -1480,7 +1454,7 @@ static void WallyHandleIntroTrainerBallThrow(void) gTasks[taskId].data[0] = gActiveBattler; if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x1) - gTasks[gUnknown_020244B4[gActiveBattler]].func = sub_8073C30; + gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = sub_8073C30; gBattleSpritesDataPtr->animationData->field_9_x1 = 1; gBattlerControllerFuncs[gActiveBattler] = nullsub_21; @@ -1541,7 +1515,7 @@ static void WallyHandleDrawPartyStatusSummary(void) else { gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x1 = 1; - gUnknown_020244B4[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleBufferA[gActiveBattler][4], gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][2]); + gBattlerStatusSummaryTaskId[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleBufferA[gActiveBattler][4], gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][2]); WallyBufferExecCompleted(); } } diff --git a/src/battle_controllers.c b/src/battle_controllers.c index 4f523cfa0..3c8b1563f 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -12,37 +12,29 @@ #include "constants/abilities.h" #include "battle_message.h" -extern u32 gBattleTypeFlags; -extern u32 gBattleControllerExecFlags; -extern void (*gBattleMainFunc)(void); -extern void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(void); -extern u8 gBattlerPositions[MAX_BATTLERS_COUNT]; -extern u8 gActionSelectionCursor[MAX_BATTLERS_COUNT]; -extern u8 gMoveSelectionCursor[MAX_BATTLERS_COUNT]; -extern u8 gBattlersCount; -extern u8 gActiveBattler; -extern u8 gUnknown_0202428C; -extern u32 gUnknown_02022FF4; -extern u8 gUnknown_0203C7B4; -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; -extern u8 gBattleBufferA[MAX_BATTLERS_COUNT][0x200]; -extern u8 gBattleBufferB[MAX_BATTLERS_COUNT][0x200]; -extern u8 gBattleBuffersTransferData[0x100]; +extern u32 gBattleExecBuffer; +extern void (*gBattleBankFunc[4])(void); +extern u8 gBanksByIdentity[4]; +extern u8 gActionSelectionCursor[4]; +extern u8 gMoveSelectionCursor[4]; +extern u8 gNoOfAllBanks; +extern u8 gActiveBank; +extern u16 gBattlePartyID[4]; +extern u8 gBattleBufferA[4][0x200]; +extern u8 gBattleBufferB[4][0x200]; extern u8 gUnknown_02022D08; extern u8 gUnknown_02022D09; extern u8 gUnknown_02022D0A; -extern u8 gBattlerAttacker; -extern u8 gBattlerTarget; -extern u8 gAbsentBattlerFlags; +extern u8 gBankAttacker; +extern u8 gBankTarget; +extern u8 gAbsentBankFlags; extern u8 gEffectBank; -extern u16 gBattleWeather; -extern struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT]; -extern u16 gCurrentMove; -extern u16 gChosenMove; -extern u16 gLastUsedItem; -extern u8 gBattleOutcome; -extern u8 gLastUsedAbility; -extern u8 gStringBattler; +extern struct BattlePokemon gBattleMons[4]; +extern u16 gLastUsedMove; +extern u8 gStringBank; +extern u8 gBattleBuffersTransferData[0x100]; + +static EWRAM_DATA u8 sBattleBuffersTransferData[0x100] = {}; extern const struct BattleMove gBattleMoves[]; @@ -61,7 +53,7 @@ void HandleLinkBattleSetup(void) { if (gBattleTypeFlags & BATTLE_TYPE_LINK) { - if (gLinkVSyncDisabled) + if (gWirelessCommType) sub_800B488(); if (!gReceivedRemoteLinkPlayers) OpenLink(); @@ -757,7 +749,7 @@ void PrepareBufferDataTransferLink(u8 bufferId, u16 size, u8 *data) gLinkBattleSendBuffer[gTasks[gUnknown_02022D08].data[14] + LINK_BUFF_SIZE_LO] = alignedSize; gLinkBattleSendBuffer[gTasks[gUnknown_02022D08].data[14] + LINK_BUFF_SIZE_HI] = (alignedSize & 0x0000FF00) >> 8; gLinkBattleSendBuffer[gTasks[gUnknown_02022D08].data[14] + LINK_BUFF_ABSENT_BANK_FLAGS] = gAbsentBattlerFlags; - gLinkBattleSendBuffer[gTasks[gUnknown_02022D08].data[14] + LINK_BUFF_EFFECT_BANK] = gEffectBank; + gLinkBattleSendBuffer[gTasks[gUnknown_02022D08].data[14] + LINK_BUFF_EFFECT_BANK] = gEffectBattler; for (i = 0; i < size; i++) gLinkBattleSendBuffer[gTasks[gUnknown_02022D08].data[14] + LINK_BUFF_DATA + i] = data[i]; @@ -782,7 +774,7 @@ static void Task_HandleSendLinkBuffersData(u8 taskId) gTasks[taskId].data[11]++; break; case 2: - if (gLinkVSyncDisabled) + if (gWirelessCommType) { gTasks[taskId].data[11]++; } @@ -923,7 +915,7 @@ static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId) gBattlerAttacker = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + 2]; gBattlerTarget = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + 3]; gAbsentBattlerFlags = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + 6]; - gEffectBank = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + 7]; + gEffectBattler = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + 7]; } break; case 1: @@ -941,171 +933,171 @@ static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId) void BtlController_EmitGetMonData(u8 bufferId, u8 requestId, u8 monToCheck) { - gBattleBuffersTransferData[0] = CONTROLLER_GETMONDATA; - gBattleBuffersTransferData[1] = requestId; - gBattleBuffersTransferData[2] = monToCheck; - gBattleBuffersTransferData[3] = 0; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_GETMONDATA; + sBattleBuffersTransferData[1] = requestId; + sBattleBuffersTransferData[2] = monToCheck; + sBattleBuffersTransferData[3] = 0; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitGetRawMonData(u8 bufferId, u8 monId, u8 bytes) { - gBattleBuffersTransferData[0] = CONTROLLER_GETRAWMONDATA; - gBattleBuffersTransferData[1] = monId; - gBattleBuffersTransferData[2] = bytes; - gBattleBuffersTransferData[3] = 0; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_GETRAWMONDATA; + sBattleBuffersTransferData[1] = monId; + sBattleBuffersTransferData[2] = bytes; + sBattleBuffersTransferData[3] = 0; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitSetMonData(u8 bufferId, u8 requestId, u8 monToCheck, u8 bytes, void *data) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_SETMONDATA; - gBattleBuffersTransferData[1] = requestId; - gBattleBuffersTransferData[2] = monToCheck; + sBattleBuffersTransferData[0] = CONTROLLER_SETMONDATA; + sBattleBuffersTransferData[1] = requestId; + sBattleBuffersTransferData[2] = monToCheck; for (i = 0; i < bytes; i++) - gBattleBuffersTransferData[3 + i] = *(u8*)(data++); - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 3 + bytes); + sBattleBuffersTransferData[3 + i] = *(u8*)(data++); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 3 + bytes); } void BtlController_EmitSetRawMonData(u8 bufferId, u8 monId, u8 bytes, void *data) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_SETRAWMONDATA; - gBattleBuffersTransferData[1] = monId; - gBattleBuffersTransferData[2] = bytes; + sBattleBuffersTransferData[0] = CONTROLLER_SETRAWMONDATA; + sBattleBuffersTransferData[1] = monId; + sBattleBuffersTransferData[2] = bytes; for (i = 0; i < bytes; i++) - gBattleBuffersTransferData[3 + i] = *(u8*)(data++); - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, bytes + 3); + sBattleBuffersTransferData[3 + i] = *(u8*)(data++); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, bytes + 3); } void BtlController_EmitLoadMonSprite(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_LOADMONSPRITE; - gBattleBuffersTransferData[1] = CONTROLLER_LOADMONSPRITE; - gBattleBuffersTransferData[2] = CONTROLLER_LOADMONSPRITE; - gBattleBuffersTransferData[3] = CONTROLLER_LOADMONSPRITE; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_LOADMONSPRITE; + sBattleBuffersTransferData[1] = CONTROLLER_LOADMONSPRITE; + sBattleBuffersTransferData[2] = CONTROLLER_LOADMONSPRITE; + sBattleBuffersTransferData[3] = CONTROLLER_LOADMONSPRITE; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitSwitchInAnim(u8 bufferId, u8 partyId, bool8 dontClearSubstituteBit) { - gBattleBuffersTransferData[0] = CONTROLLER_SWITCHINANIM; - gBattleBuffersTransferData[1] = partyId; - gBattleBuffersTransferData[2] = dontClearSubstituteBit; - gBattleBuffersTransferData[3] = 5; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_SWITCHINANIM; + sBattleBuffersTransferData[1] = partyId; + sBattleBuffersTransferData[2] = dontClearSubstituteBit; + sBattleBuffersTransferData[3] = 5; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitReturnMonToBall(u8 bufferId, u8 arg1) { - gBattleBuffersTransferData[0] = CONTROLLER_RETURNMONTOBALL; - gBattleBuffersTransferData[1] = arg1; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 2); + sBattleBuffersTransferData[0] = CONTROLLER_RETURNMONTOBALL; + sBattleBuffersTransferData[1] = arg1; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 2); } void BtlController_EmitDrawTrainerPic(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_DRAWTRAINERPIC; - gBattleBuffersTransferData[1] = CONTROLLER_DRAWTRAINERPIC; - gBattleBuffersTransferData[2] = CONTROLLER_DRAWTRAINERPIC; - gBattleBuffersTransferData[3] = CONTROLLER_DRAWTRAINERPIC; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_DRAWTRAINERPIC; + sBattleBuffersTransferData[1] = CONTROLLER_DRAWTRAINERPIC; + sBattleBuffersTransferData[2] = CONTROLLER_DRAWTRAINERPIC; + sBattleBuffersTransferData[3] = CONTROLLER_DRAWTRAINERPIC; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitTrainerSlide(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_TRAINERSLIDE; - gBattleBuffersTransferData[1] = CONTROLLER_TRAINERSLIDE; - gBattleBuffersTransferData[2] = CONTROLLER_TRAINERSLIDE; - gBattleBuffersTransferData[3] = CONTROLLER_TRAINERSLIDE; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_TRAINERSLIDE; + sBattleBuffersTransferData[1] = CONTROLLER_TRAINERSLIDE; + sBattleBuffersTransferData[2] = CONTROLLER_TRAINERSLIDE; + sBattleBuffersTransferData[3] = CONTROLLER_TRAINERSLIDE; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitTrainerSlideBack(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_TRAINERSLIDEBACK; - gBattleBuffersTransferData[1] = CONTROLLER_TRAINERSLIDEBACK; - gBattleBuffersTransferData[2] = CONTROLLER_TRAINERSLIDEBACK; - gBattleBuffersTransferData[3] = CONTROLLER_TRAINERSLIDEBACK; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_TRAINERSLIDEBACK; + sBattleBuffersTransferData[1] = CONTROLLER_TRAINERSLIDEBACK; + sBattleBuffersTransferData[2] = CONTROLLER_TRAINERSLIDEBACK; + sBattleBuffersTransferData[3] = CONTROLLER_TRAINERSLIDEBACK; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitFaintAnimation(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_FAINTANIMATION; - gBattleBuffersTransferData[1] = CONTROLLER_FAINTANIMATION; - gBattleBuffersTransferData[2] = CONTROLLER_FAINTANIMATION; - gBattleBuffersTransferData[3] = CONTROLLER_FAINTANIMATION; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_FAINTANIMATION; + sBattleBuffersTransferData[1] = CONTROLLER_FAINTANIMATION; + sBattleBuffersTransferData[2] = CONTROLLER_FAINTANIMATION; + sBattleBuffersTransferData[3] = CONTROLLER_FAINTANIMATION; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitPaletteFade(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_PALETTEFADE; - gBattleBuffersTransferData[1] = CONTROLLER_PALETTEFADE; - gBattleBuffersTransferData[2] = CONTROLLER_PALETTEFADE; - gBattleBuffersTransferData[3] = CONTROLLER_PALETTEFADE; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_PALETTEFADE; + sBattleBuffersTransferData[1] = CONTROLLER_PALETTEFADE; + sBattleBuffersTransferData[2] = CONTROLLER_PALETTEFADE; + sBattleBuffersTransferData[3] = CONTROLLER_PALETTEFADE; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitSuccessBallThrowAnim(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_SUCCESSBALLTHROWANIM; - gBattleBuffersTransferData[1] = CONTROLLER_SUCCESSBALLTHROWANIM; - gBattleBuffersTransferData[2] = CONTROLLER_SUCCESSBALLTHROWANIM; - gBattleBuffersTransferData[3] = CONTROLLER_SUCCESSBALLTHROWANIM; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_SUCCESSBALLTHROWANIM; + sBattleBuffersTransferData[1] = CONTROLLER_SUCCESSBALLTHROWANIM; + sBattleBuffersTransferData[2] = CONTROLLER_SUCCESSBALLTHROWANIM; + sBattleBuffersTransferData[3] = CONTROLLER_SUCCESSBALLTHROWANIM; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitBallThrowAnim(u8 bufferId, u8 caseId) { - gBattleBuffersTransferData[0] = CONTROLLER_BALLTHROWANIM; - gBattleBuffersTransferData[1] = caseId; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 2); + sBattleBuffersTransferData[0] = CONTROLLER_BALLTHROWANIM; + sBattleBuffersTransferData[1] = caseId; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 2); } void BtlController_EmitPause(u8 bufferId, u8 toWait, void *data) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_PAUSE; - gBattleBuffersTransferData[1] = toWait; + sBattleBuffersTransferData[0] = CONTROLLER_PAUSE; + sBattleBuffersTransferData[1] = toWait; for (i = 0; i < toWait * 3; i++) - gBattleBuffersTransferData[2 + i] = *(u8*)(data++); - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, toWait * 3 + 2); + sBattleBuffersTransferData[2 + i] = *(u8*)(data++); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, toWait * 3 + 2); } void BtlController_EmitMoveAnimation(u8 bufferId, u16 move, u8 turnOfMove, u16 movePower, s32 dmg, u8 friendship, struct DisableStruct *disableStructPtr, u8 multihit) { - gBattleBuffersTransferData[0] = CONTROLLER_MOVEANIMATION; - gBattleBuffersTransferData[1] = move; - gBattleBuffersTransferData[2] = (move & 0xFF00) >> 8; - gBattleBuffersTransferData[3] = turnOfMove; - gBattleBuffersTransferData[4] = movePower; - gBattleBuffersTransferData[5] = (movePower & 0xFF00) >> 8; - gBattleBuffersTransferData[6] = dmg; - gBattleBuffersTransferData[7] = (dmg & 0x0000FF00) >> 8; - gBattleBuffersTransferData[8] = (dmg & 0x00FF0000) >> 16; - gBattleBuffersTransferData[9] = (dmg & 0xFF000000) >> 24; - gBattleBuffersTransferData[10] = friendship; - gBattleBuffersTransferData[11] = multihit; + sBattleBuffersTransferData[0] = CONTROLLER_MOVEANIMATION; + sBattleBuffersTransferData[1] = move; + sBattleBuffersTransferData[2] = (move & 0xFF00) >> 8; + sBattleBuffersTransferData[3] = turnOfMove; + sBattleBuffersTransferData[4] = movePower; + sBattleBuffersTransferData[5] = (movePower & 0xFF00) >> 8; + sBattleBuffersTransferData[6] = dmg; + sBattleBuffersTransferData[7] = (dmg & 0x0000FF00) >> 8; + sBattleBuffersTransferData[8] = (dmg & 0x00FF0000) >> 16; + sBattleBuffersTransferData[9] = (dmg & 0xFF000000) >> 24; + sBattleBuffersTransferData[10] = friendship; + sBattleBuffersTransferData[11] = multihit; if (WEATHER_HAS_EFFECT2) { - gBattleBuffersTransferData[12] = gBattleWeather; - gBattleBuffersTransferData[13] = (gBattleWeather & 0xFF00) >> 8; + sBattleBuffersTransferData[12] = gBattleWeather; + sBattleBuffersTransferData[13] = (gBattleWeather & 0xFF00) >> 8; } else { - gBattleBuffersTransferData[12] = 0; - gBattleBuffersTransferData[13] = 0; + sBattleBuffersTransferData[12] = 0; + sBattleBuffersTransferData[13] = 0; } - gBattleBuffersTransferData[14] = 0; - gBattleBuffersTransferData[15] = 0; - memcpy(&gBattleBuffersTransferData[16], disableStructPtr, sizeof(struct DisableStruct)); - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 16 + sizeof(struct DisableStruct)); + sBattleBuffersTransferData[14] = 0; + sBattleBuffersTransferData[15] = 0; + memcpy(&sBattleBuffersTransferData[16], disableStructPtr, sizeof(struct DisableStruct)); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 16 + sizeof(struct DisableStruct)); } void BtlController_EmitPrintString(u8 bufferId, u16 stringID) @@ -1113,12 +1105,12 @@ void BtlController_EmitPrintString(u8 bufferId, u16 stringID) s32 i; struct StringInfoBattle* stringInfo; - gBattleBuffersTransferData[0] = CONTROLLER_PRINTSTRING; - gBattleBuffersTransferData[1] = gBattleOutcome; - gBattleBuffersTransferData[2] = stringID; - gBattleBuffersTransferData[3] = (stringID & 0xFF00) >> 8; + sBattleBuffersTransferData[0] = CONTROLLER_PRINTSTRING; + sBattleBuffersTransferData[1] = gBattleOutcome; + sBattleBuffersTransferData[2] = stringID; + sBattleBuffersTransferData[3] = (stringID & 0xFF00) >> 8; - stringInfo = (struct StringInfoBattle*)(&gBattleBuffersTransferData[4]); + stringInfo = (struct StringInfoBattle*)(&sBattleBuffersTransferData[4]); stringInfo->currentMove = gCurrentMove; stringInfo->originallyUsedMove = gChosenMove; stringInfo->lastItem = gLastUsedItem; @@ -1126,7 +1118,7 @@ void BtlController_EmitPrintString(u8 bufferId, u16 stringID) stringInfo->scrActive = gBattleScripting.battler; stringInfo->unk1605E = gBattleStruct->field_52; stringInfo->hpScale = gBattleStruct->hpScale; - stringInfo->StringBank = gStringBattler; + stringInfo->StringBank = gPotentialItemEffectBattler; stringInfo->moveType = gBattleMoves[gCurrentMove].type; for (i = 0; i < MAX_BATTLERS_COUNT; i++) @@ -1137,7 +1129,7 @@ void BtlController_EmitPrintString(u8 bufferId, u16 stringID) stringInfo->textBuffs[1][i] = gBattleTextBuff2[i]; stringInfo->textBuffs[2][i] = gBattleTextBuff3[i]; } - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, sizeof(struct StringInfoBattle) + 4); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, sizeof(struct StringInfoBattle) + 4); } void BtlController_EmitPrintSelectionString(u8 bufferId, u16 stringID) @@ -1145,12 +1137,12 @@ void BtlController_EmitPrintSelectionString(u8 bufferId, u16 stringID) s32 i; struct StringInfoBattle *stringInfo; - gBattleBuffersTransferData[0] = CONTROLLER_PRINTSTRINGPLAYERONLY; - gBattleBuffersTransferData[1] = CONTROLLER_PRINTSTRINGPLAYERONLY; - gBattleBuffersTransferData[2] = stringID; - gBattleBuffersTransferData[3] = (stringID & 0xFF00) >> 8; + sBattleBuffersTransferData[0] = CONTROLLER_PRINTSTRINGPLAYERONLY; + sBattleBuffersTransferData[1] = CONTROLLER_PRINTSTRINGPLAYERONLY; + sBattleBuffersTransferData[2] = stringID; + sBattleBuffersTransferData[3] = (stringID & 0xFF00) >> 8; - stringInfo = (struct StringInfoBattle*)(&gBattleBuffersTransferData[4]); + stringInfo = (struct StringInfoBattle*)(&sBattleBuffersTransferData[4]); stringInfo->currentMove = gCurrentMove; stringInfo->originallyUsedMove = gChosenMove; stringInfo->lastItem = gLastUsedItem; @@ -1166,386 +1158,386 @@ void BtlController_EmitPrintSelectionString(u8 bufferId, u16 stringID) stringInfo->textBuffs[1][i] = gBattleTextBuff2[i]; stringInfo->textBuffs[2][i] = gBattleTextBuff3[i]; } - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, sizeof(struct StringInfoBattle) + 4); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, sizeof(struct StringInfoBattle) + 4); } void BtlController_EmitChooseAction(u8 bufferId, u8 arg1, u16 arg2) { - gBattleBuffersTransferData[0] = CONTROLLER_CHOOSEACTION; - gBattleBuffersTransferData[1] = arg1; - gBattleBuffersTransferData[2] = arg2; - gBattleBuffersTransferData[3] = (arg2 & 0xFF00) >> 8; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_CHOOSEACTION; + sBattleBuffersTransferData[1] = arg1; + sBattleBuffersTransferData[2] = arg2; + sBattleBuffersTransferData[3] = (arg2 & 0xFF00) >> 8; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitUnknownYesNoBox(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_UNKNOWNYESNOBOX; - gBattleBuffersTransferData[1] = CONTROLLER_UNKNOWNYESNOBOX; - gBattleBuffersTransferData[2] = CONTROLLER_UNKNOWNYESNOBOX; - gBattleBuffersTransferData[3] = CONTROLLER_UNKNOWNYESNOBOX; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_UNKNOWNYESNOBOX; + sBattleBuffersTransferData[1] = CONTROLLER_UNKNOWNYESNOBOX; + sBattleBuffersTransferData[2] = CONTROLLER_UNKNOWNYESNOBOX; + sBattleBuffersTransferData[3] = CONTROLLER_UNKNOWNYESNOBOX; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitChooseMove(u8 bufferId, bool8 isDoubleBattle, bool8 NoPpNumber, struct ChooseMoveStruct *movePpData) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_CHOOSEMOVE; - gBattleBuffersTransferData[1] = isDoubleBattle; - gBattleBuffersTransferData[2] = NoPpNumber; - gBattleBuffersTransferData[3] = 0; + sBattleBuffersTransferData[0] = CONTROLLER_CHOOSEMOVE; + sBattleBuffersTransferData[1] = isDoubleBattle; + sBattleBuffersTransferData[2] = NoPpNumber; + sBattleBuffersTransferData[3] = 0; for (i = 0; i < sizeof(*movePpData); i++) - gBattleBuffersTransferData[4 + i] = *((u8*)(movePpData) + i); - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, sizeof(*movePpData) + 4); + sBattleBuffersTransferData[4 + i] = *((u8*)(movePpData) + i); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, sizeof(*movePpData) + 4); } void BtlController_EmitChooseItem(u8 bufferId, u8 *arg1) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_OPENBAG; + sBattleBuffersTransferData[0] = CONTROLLER_OPENBAG; for (i = 0; i < 3; i++) - gBattleBuffersTransferData[1 + i] = arg1[i]; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[1 + i] = arg1[i]; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitChoosePokemon(u8 bufferId, u8 caseId, u8 arg2, u8 abilityId, u8* arg4) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_CHOOSEPOKEMON; - gBattleBuffersTransferData[1] = caseId; - gBattleBuffersTransferData[2] = arg2; - gBattleBuffersTransferData[3] = abilityId; + sBattleBuffersTransferData[0] = CONTROLLER_CHOOSEPOKEMON; + sBattleBuffersTransferData[1] = caseId; + sBattleBuffersTransferData[2] = arg2; + sBattleBuffersTransferData[3] = abilityId; for (i = 0; i < 3; i++) - gBattleBuffersTransferData[4 + i] = arg4[i]; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 8); // but only 7 bytes were written + sBattleBuffersTransferData[4 + i] = arg4[i]; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 8); // but only 7 bytes were written } void BtlController_EmitCmd23(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_23; - gBattleBuffersTransferData[1] = CONTROLLER_23; - gBattleBuffersTransferData[2] = CONTROLLER_23; - gBattleBuffersTransferData[3] = CONTROLLER_23; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_23; + sBattleBuffersTransferData[1] = CONTROLLER_23; + sBattleBuffersTransferData[2] = CONTROLLER_23; + sBattleBuffersTransferData[3] = CONTROLLER_23; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } // why is the argument u16 if it's being cast to s16 anyway? void BtlController_EmitHealthBarUpdate(u8 bufferId, u16 hpValue) { - gBattleBuffersTransferData[0] = CONTROLLER_HEALTHBARUPDATE; - gBattleBuffersTransferData[1] = 0; - gBattleBuffersTransferData[2] = (s16)hpValue; - gBattleBuffersTransferData[3] = ((s16)hpValue & 0xFF00) >> 8; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_HEALTHBARUPDATE; + sBattleBuffersTransferData[1] = 0; + sBattleBuffersTransferData[2] = (s16)hpValue; + sBattleBuffersTransferData[3] = ((s16)hpValue & 0xFF00) >> 8; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } // why is the argument u16 if it's being cast to s16 anyway? void BtlController_EmitExpUpdate(u8 bufferId, u8 partyId, u16 expPoints) { - gBattleBuffersTransferData[0] = CONTROLLER_EXPUPDATE; - gBattleBuffersTransferData[1] = partyId; - gBattleBuffersTransferData[2] = (s16)expPoints; - gBattleBuffersTransferData[3] = ((s16)expPoints & 0xFF00) >> 8; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_EXPUPDATE; + sBattleBuffersTransferData[1] = partyId; + sBattleBuffersTransferData[2] = (s16)expPoints; + sBattleBuffersTransferData[3] = ((s16)expPoints & 0xFF00) >> 8; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitStatusIconUpdate(u8 bufferId, u32 status1, u32 status2) { - gBattleBuffersTransferData[0] = CONTROLLER_STATUSICONUPDATE; - gBattleBuffersTransferData[1] = status1; - gBattleBuffersTransferData[2] = (status1 & 0x0000FF00) >> 8; - gBattleBuffersTransferData[3] = (status1 & 0x00FF0000) >> 16; - gBattleBuffersTransferData[4] = (status1 & 0xFF000000) >> 24; - gBattleBuffersTransferData[5] = status2; - gBattleBuffersTransferData[6] = (status2 & 0x0000FF00) >> 8; - gBattleBuffersTransferData[7] = (status2 & 0x00FF0000) >> 16; - gBattleBuffersTransferData[8] = (status2 & 0xFF000000) >> 24; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 9); + sBattleBuffersTransferData[0] = CONTROLLER_STATUSICONUPDATE; + sBattleBuffersTransferData[1] = status1; + sBattleBuffersTransferData[2] = (status1 & 0x0000FF00) >> 8; + sBattleBuffersTransferData[3] = (status1 & 0x00FF0000) >> 16; + sBattleBuffersTransferData[4] = (status1 & 0xFF000000) >> 24; + sBattleBuffersTransferData[5] = status2; + sBattleBuffersTransferData[6] = (status2 & 0x0000FF00) >> 8; + sBattleBuffersTransferData[7] = (status2 & 0x00FF0000) >> 16; + sBattleBuffersTransferData[8] = (status2 & 0xFF000000) >> 24; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 9); } void BtlController_EmitStatusAnimation(u8 bufferId, bool8 status2, u32 status) { - gBattleBuffersTransferData[0] = CONTROLLER_STATUSANIMATION; - gBattleBuffersTransferData[1] = status2; - gBattleBuffersTransferData[2] = status; - gBattleBuffersTransferData[3] = (status & 0x0000FF00) >> 8; - gBattleBuffersTransferData[4] = (status & 0x00FF0000) >> 16; - gBattleBuffersTransferData[5] = (status & 0xFF000000) >> 24; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 6); + sBattleBuffersTransferData[0] = CONTROLLER_STATUSANIMATION; + sBattleBuffersTransferData[1] = status2; + sBattleBuffersTransferData[2] = status; + sBattleBuffersTransferData[3] = (status & 0x0000FF00) >> 8; + sBattleBuffersTransferData[4] = (status & 0x00FF0000) >> 16; + sBattleBuffersTransferData[5] = (status & 0xFF000000) >> 24; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 6); } void BtlController_EmitStatusXor(u8 bufferId, u8 b) { - gBattleBuffersTransferData[0] = CONTROLLER_STATUSXOR; - gBattleBuffersTransferData[1] = b; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 2); + sBattleBuffersTransferData[0] = CONTROLLER_STATUSXOR; + sBattleBuffersTransferData[1] = b; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 2); } void BtlController_EmitDataTransfer(u8 bufferId, u16 size, void *data) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_DATATRANSFER; - gBattleBuffersTransferData[1] = CONTROLLER_DATATRANSFER; - gBattleBuffersTransferData[2] = size; - gBattleBuffersTransferData[3] = (size & 0xFF00) >> 8; + sBattleBuffersTransferData[0] = CONTROLLER_DATATRANSFER; + sBattleBuffersTransferData[1] = CONTROLLER_DATATRANSFER; + sBattleBuffersTransferData[2] = size; + sBattleBuffersTransferData[3] = (size & 0xFF00) >> 8; for (i = 0; i < size; i++) - gBattleBuffersTransferData[4 + i] = *(u8*)(data++); - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, size + 4); + sBattleBuffersTransferData[4 + i] = *(u8*)(data++); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, size + 4); } void BtlController_EmitDMA3Transfer(u8 bufferId, void *dst, u16 size, void *data) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_DMA3TRANSFER; - gBattleBuffersTransferData[1] = (u32)(dst); - gBattleBuffersTransferData[2] = ((u32)(dst) & 0x0000FF00) >> 8; - gBattleBuffersTransferData[3] = ((u32)(dst) & 0x00FF0000) >> 16; - gBattleBuffersTransferData[4] = ((u32)(dst) & 0xFF000000) >> 24; - gBattleBuffersTransferData[5] = size; - gBattleBuffersTransferData[6] = (size & 0xFF00) >> 8; + sBattleBuffersTransferData[0] = CONTROLLER_DMA3TRANSFER; + sBattleBuffersTransferData[1] = (u32)(dst); + sBattleBuffersTransferData[2] = ((u32)(dst) & 0x0000FF00) >> 8; + sBattleBuffersTransferData[3] = ((u32)(dst) & 0x00FF0000) >> 16; + sBattleBuffersTransferData[4] = ((u32)(dst) & 0xFF000000) >> 24; + sBattleBuffersTransferData[5] = size; + sBattleBuffersTransferData[6] = (size & 0xFF00) >> 8; for (i = 0; i < size; i++) - gBattleBuffersTransferData[7 + i] = *(u8*)(data++); - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, size + 7); + sBattleBuffersTransferData[7 + i] = *(u8*)(data++); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, size + 7); } void BtlController_EmitPlayBGM(u8 bufferId, u16 songId, void *unusedDumbDataParameter) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_31; - gBattleBuffersTransferData[1] = songId; - gBattleBuffersTransferData[2] = (songId & 0xFF00) >> 8; + sBattleBuffersTransferData[0] = CONTROLLER_31; + sBattleBuffersTransferData[1] = songId; + sBattleBuffersTransferData[2] = (songId & 0xFF00) >> 8; for (i = 0; i < songId; i++) // ???? - gBattleBuffersTransferData[3 + i] = *(u8*)(unusedDumbDataParameter++); - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, songId + 3); + sBattleBuffersTransferData[3 + i] = *(u8*)(unusedDumbDataParameter++); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, songId + 3); } void BtlController_EmitCmd32(u8 bufferId, u16 size, void *data) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_32; - gBattleBuffersTransferData[1] = size; - gBattleBuffersTransferData[2] = (size & 0xFF00) >> 8; + sBattleBuffersTransferData[0] = CONTROLLER_32; + sBattleBuffersTransferData[1] = size; + sBattleBuffersTransferData[2] = (size & 0xFF00) >> 8; for (i = 0; i < size; i++) - gBattleBuffersTransferData[3 + i] = *(u8*)(data++); - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, size + 3); + sBattleBuffersTransferData[3 + i] = *(u8*)(data++); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, size + 3); } void BtlController_EmitTwoReturnValues(u8 bufferId, u8 arg1, u16 arg2) { - gBattleBuffersTransferData[0] = CONTROLLER_TWORETURNVALUES; - gBattleBuffersTransferData[1] = arg1; - gBattleBuffersTransferData[2] = arg2; - gBattleBuffersTransferData[3] = (arg2 & 0xFF00) >> 8; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_TWORETURNVALUES; + sBattleBuffersTransferData[1] = arg1; + sBattleBuffersTransferData[2] = arg2; + sBattleBuffersTransferData[3] = (arg2 & 0xFF00) >> 8; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitChosenMonReturnValue(u8 bufferId, u8 b, u8 *c) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_CHOSENMONRETURNVALUE; - gBattleBuffersTransferData[1] = b; + sBattleBuffersTransferData[0] = CONTROLLER_CHOSENMONRETURNVALUE; + sBattleBuffersTransferData[1] = b; for (i = 0; i < 3; i++) - gBattleBuffersTransferData[2 + i] = c[i]; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 5); + sBattleBuffersTransferData[2 + i] = c[i]; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 5); } void BtlController_EmitOneReturnValue(u8 bufferId, u16 arg1) { - gBattleBuffersTransferData[0] = CONTROLLER_ONERETURNVALUE; - gBattleBuffersTransferData[1] = arg1; - gBattleBuffersTransferData[2] = (arg1 & 0xFF00) >> 8; - gBattleBuffersTransferData[3] = 0; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_ONERETURNVALUE; + sBattleBuffersTransferData[1] = arg1; + sBattleBuffersTransferData[2] = (arg1 & 0xFF00) >> 8; + sBattleBuffersTransferData[3] = 0; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitOneReturnValue_Duplicate(u8 bufferId, u16 b) { - gBattleBuffersTransferData[0] = CONTROLLER_ONERETURNVALUE_DUPLICATE; - gBattleBuffersTransferData[1] = b; - gBattleBuffersTransferData[2] = (b & 0xFF00) >> 8; - gBattleBuffersTransferData[3] = 0; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_ONERETURNVALUE_DUPLICATE; + sBattleBuffersTransferData[1] = b; + sBattleBuffersTransferData[2] = (b & 0xFF00) >> 8; + sBattleBuffersTransferData[3] = 0; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitCmd37(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_37; - gBattleBuffersTransferData[1] = CONTROLLER_37; - gBattleBuffersTransferData[2] = CONTROLLER_37; - gBattleBuffersTransferData[3] = CONTROLLER_37; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_37; + sBattleBuffersTransferData[1] = CONTROLLER_37; + sBattleBuffersTransferData[2] = CONTROLLER_37; + sBattleBuffersTransferData[3] = CONTROLLER_37; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitCmd38(u8 bufferId, u8 b) { - gBattleBuffersTransferData[0] = CONTROLLER_38; - gBattleBuffersTransferData[1] = b; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 2); + sBattleBuffersTransferData[0] = CONTROLLER_38; + sBattleBuffersTransferData[1] = b; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 2); } void BtlController_EmitCmd39(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_39; - gBattleBuffersTransferData[1] = CONTROLLER_39; - gBattleBuffersTransferData[2] = CONTROLLER_39; - gBattleBuffersTransferData[3] = CONTROLLER_39; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_39; + sBattleBuffersTransferData[1] = CONTROLLER_39; + sBattleBuffersTransferData[2] = CONTROLLER_39; + sBattleBuffersTransferData[3] = CONTROLLER_39; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitCmd40(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_40; - gBattleBuffersTransferData[1] = CONTROLLER_40; - gBattleBuffersTransferData[2] = CONTROLLER_40; - gBattleBuffersTransferData[3] = CONTROLLER_40; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_40; + sBattleBuffersTransferData[1] = CONTROLLER_40; + sBattleBuffersTransferData[2] = CONTROLLER_40; + sBattleBuffersTransferData[3] = CONTROLLER_40; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitHitAnimation(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_HITANIMATION; - gBattleBuffersTransferData[1] = CONTROLLER_HITANIMATION; - gBattleBuffersTransferData[2] = CONTROLLER_HITANIMATION; - gBattleBuffersTransferData[3] = CONTROLLER_HITANIMATION; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_HITANIMATION; + sBattleBuffersTransferData[1] = CONTROLLER_HITANIMATION; + sBattleBuffersTransferData[2] = CONTROLLER_HITANIMATION; + sBattleBuffersTransferData[3] = CONTROLLER_HITANIMATION; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitCmd42(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_42; - gBattleBuffersTransferData[1] = CONTROLLER_42; - gBattleBuffersTransferData[2] = CONTROLLER_42; - gBattleBuffersTransferData[3] = CONTROLLER_42; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_42; + sBattleBuffersTransferData[1] = CONTROLLER_42; + sBattleBuffersTransferData[2] = CONTROLLER_42; + sBattleBuffersTransferData[3] = CONTROLLER_42; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitPlaySE(u8 bufferId, u16 songId) { - gBattleBuffersTransferData[0] = CONTROLLER_EFFECTIVENESSSOUND; - gBattleBuffersTransferData[1] = songId; - gBattleBuffersTransferData[2] = (songId & 0xFF00) >> 8; - gBattleBuffersTransferData[3] = 0; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_EFFECTIVENESSSOUND; + sBattleBuffersTransferData[1] = songId; + sBattleBuffersTransferData[2] = (songId & 0xFF00) >> 8; + sBattleBuffersTransferData[3] = 0; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitPlayFanfareOrBGM(u8 bufferId, u16 songId, bool8 playBGM) { - gBattleBuffersTransferData[0] = CONTROLLER_PLAYFANFAREORBGM; - gBattleBuffersTransferData[1] = songId; - gBattleBuffersTransferData[2] = (songId & 0xFF00) >> 8; - gBattleBuffersTransferData[3] = playBGM; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_PLAYFANFAREORBGM; + sBattleBuffersTransferData[1] = songId; + sBattleBuffersTransferData[2] = (songId & 0xFF00) >> 8; + sBattleBuffersTransferData[3] = playBGM; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitFaintingCry(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_FAINTINGCRY; - gBattleBuffersTransferData[1] = CONTROLLER_FAINTINGCRY; - gBattleBuffersTransferData[2] = CONTROLLER_FAINTINGCRY; - gBattleBuffersTransferData[3] = CONTROLLER_FAINTINGCRY; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_FAINTINGCRY; + sBattleBuffersTransferData[1] = CONTROLLER_FAINTINGCRY; + sBattleBuffersTransferData[2] = CONTROLLER_FAINTINGCRY; + sBattleBuffersTransferData[3] = CONTROLLER_FAINTINGCRY; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitIntroSlide(u8 bufferId, u8 terrainId) { - gBattleBuffersTransferData[0] = CONTROLLER_INTROSLIDE; - gBattleBuffersTransferData[1] = terrainId; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 2); + sBattleBuffersTransferData[0] = CONTROLLER_INTROSLIDE; + sBattleBuffersTransferData[1] = terrainId; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 2); } void BtlController_EmitIntroTrainerBallThrow(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_INTROTRAINERBALLTHROW; - gBattleBuffersTransferData[1] = CONTROLLER_INTROTRAINERBALLTHROW; - gBattleBuffersTransferData[2] = CONTROLLER_INTROTRAINERBALLTHROW; - gBattleBuffersTransferData[3] = CONTROLLER_INTROTRAINERBALLTHROW; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_INTROTRAINERBALLTHROW; + sBattleBuffersTransferData[1] = CONTROLLER_INTROTRAINERBALLTHROW; + sBattleBuffersTransferData[2] = CONTROLLER_INTROTRAINERBALLTHROW; + sBattleBuffersTransferData[3] = CONTROLLER_INTROTRAINERBALLTHROW; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitDrawPartyStatusSummary(u8 bufferId, struct HpAndStatus* hpAndStatus, u8 arg2) { s32 i; - gBattleBuffersTransferData[0] = CONTROLLER_DRAWPARTYSTATUSSUMMARY; - gBattleBuffersTransferData[1] = arg2 & 0x7F; - gBattleBuffersTransferData[2] = (arg2 & 0x80) >> 7; - gBattleBuffersTransferData[3] = CONTROLLER_DRAWPARTYSTATUSSUMMARY; + sBattleBuffersTransferData[0] = CONTROLLER_DRAWPARTYSTATUSSUMMARY; + sBattleBuffersTransferData[1] = arg2 & 0x7F; + sBattleBuffersTransferData[2] = (arg2 & 0x80) >> 7; + sBattleBuffersTransferData[3] = CONTROLLER_DRAWPARTYSTATUSSUMMARY; for (i = 0; i < (s32)(sizeof(struct HpAndStatus) * 6); i++) - gBattleBuffersTransferData[4 + i] = *(i + (u8*)(hpAndStatus)); - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, sizeof(struct HpAndStatus) * 6 + 4); + sBattleBuffersTransferData[4 + i] = *(i + (u8*)(hpAndStatus)); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, sizeof(struct HpAndStatus) * 6 + 4); } void BtlController_EmitCmd49(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_49; - gBattleBuffersTransferData[1] = CONTROLLER_49; - gBattleBuffersTransferData[2] = CONTROLLER_49; - gBattleBuffersTransferData[3] = CONTROLLER_49; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_49; + sBattleBuffersTransferData[1] = CONTROLLER_49; + sBattleBuffersTransferData[2] = CONTROLLER_49; + sBattleBuffersTransferData[3] = CONTROLLER_49; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitCmd50(u8 bufferId) { - gBattleBuffersTransferData[0] = CONTROLLER_50; - gBattleBuffersTransferData[1] = CONTROLLER_50; - gBattleBuffersTransferData[2] = CONTROLLER_50; - gBattleBuffersTransferData[3] = CONTROLLER_50; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_50; + sBattleBuffersTransferData[1] = CONTROLLER_50; + sBattleBuffersTransferData[2] = CONTROLLER_50; + sBattleBuffersTransferData[3] = CONTROLLER_50; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitSpriteInvisibility(u8 bufferId, bool8 isInvisible) { - gBattleBuffersTransferData[0] = CONTROLLER_SPRITEINVISIBILITY; - gBattleBuffersTransferData[1] = isInvisible; - gBattleBuffersTransferData[2] = CONTROLLER_SPRITEINVISIBILITY; - gBattleBuffersTransferData[3] = CONTROLLER_SPRITEINVISIBILITY; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_SPRITEINVISIBILITY; + sBattleBuffersTransferData[1] = isInvisible; + sBattleBuffersTransferData[2] = CONTROLLER_SPRITEINVISIBILITY; + sBattleBuffersTransferData[3] = CONTROLLER_SPRITEINVISIBILITY; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitBattleAnimation(u8 bufferId, u8 animationId, u16 argument) { - gBattleBuffersTransferData[0] = CONTROLLER_BATTLEANIMATION; - gBattleBuffersTransferData[1] = animationId; - gBattleBuffersTransferData[2] = argument; - gBattleBuffersTransferData[3] = (argument & 0xFF00) >> 8; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 4); + sBattleBuffersTransferData[0] = CONTROLLER_BATTLEANIMATION; + sBattleBuffersTransferData[1] = animationId; + sBattleBuffersTransferData[2] = argument; + sBattleBuffersTransferData[3] = (argument & 0xFF00) >> 8; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 4); } void BtlController_EmitLinkStandbyMsg(u8 bufferId, u8 arg1, bool32 arg2) { bool8 arg2_ = arg2; - gBattleBuffersTransferData[0] = CONTROLLER_LINKSTANDBYMSG; - gBattleBuffersTransferData[1] = arg1; + sBattleBuffersTransferData[0] = CONTROLLER_LINKSTANDBYMSG; + sBattleBuffersTransferData[1] = arg1; if (arg2_) - gBattleBuffersTransferData[3] = gBattleBuffersTransferData[2] = sub_81850DC(&gBattleBuffersTransferData[4]); + sBattleBuffersTransferData[3] = sBattleBuffersTransferData[2] = sub_81850DC(&sBattleBuffersTransferData[4]); else - gBattleBuffersTransferData[3] = gBattleBuffersTransferData[2] = 0; + sBattleBuffersTransferData[3] = sBattleBuffersTransferData[2] = 0; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, gBattleBuffersTransferData[2] + 4); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, sBattleBuffersTransferData[2] + 4); } void BtlController_EmitResetActionMoveSelection(u8 bufferId, u8 caseId) { - gBattleBuffersTransferData[0] = CONTROLLER_RESETACTIONMOVESELECTION; - gBattleBuffersTransferData[1] = caseId; - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, 2); + sBattleBuffersTransferData[0] = CONTROLLER_RESETACTIONMOVESELECTION; + sBattleBuffersTransferData[1] = caseId; + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 2); } void BtlController_EmitCmd55(u8 bufferId, u8 arg1) { - gBattleBuffersTransferData[0] = CONTROLLER_55; - gBattleBuffersTransferData[1] = arg1; - gBattleBuffersTransferData[2] = gSaveBlock2Ptr->field_CA9_b; - gBattleBuffersTransferData[3] = gSaveBlock2Ptr->field_CA9_b; - gBattleBuffersTransferData[5] = gBattleBuffersTransferData[4] = sub_81850DC(&gBattleBuffersTransferData[6]); - PrepareBufferDataTransfer(bufferId, gBattleBuffersTransferData, gBattleBuffersTransferData[4] + 6); + sBattleBuffersTransferData[0] = CONTROLLER_55; + sBattleBuffersTransferData[1] = arg1; + sBattleBuffersTransferData[2] = gSaveBlock2Ptr->field_CA9_b; + sBattleBuffersTransferData[3] = gSaveBlock2Ptr->field_CA9_b; + sBattleBuffersTransferData[5] = sBattleBuffersTransferData[4] = sub_81850DC(&sBattleBuffersTransferData[6]); + PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, sBattleBuffersTransferData[4] + 6); } diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c index 7958d07b3..4dc88ab6a 100644 --- a/src/battle_gfx_sfx_util.c +++ b/src/battle_gfx_sfx_util.c @@ -22,18 +22,8 @@ #include "blend_palette.h" #include "contest.h" #include "constants/songs.h" +#include "constants/rgb.h" -extern u8 gBattleBufferA[MAX_BATTLERS_COUNT][0x200]; -extern u8 gActiveBattler; -extern u8 gBattlersCount; -extern u16 gUnknown_020243FC; -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; -extern struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT]; -extern u8 gBattlerPositions[MAX_BATTLERS_COUNT]; -extern u8 gBattlerSpriteIds[MAX_BATTLERS_COUNT]; -extern u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT]; -extern u8 gBattleMonForms[MAX_BATTLERS_COUNT]; -extern u32 gTransformedPersonalities[MAX_BATTLERS_COUNT]; extern struct MusicPlayerInfo gMPlayInfo_SE1; extern struct MusicPlayerInfo gMPlayInfo_SE2; extern struct MusicPlayerInfo gMPlayInfo_BGM; @@ -49,7 +39,6 @@ extern const struct CompressedSpriteSheet gTrainerBackPicTable[]; extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[]; extern const struct CompressedSpritePalette gTrainerBackPicPaletteTable[]; extern const union AnimCmd* const * const gMonAnimationsSpriteAnimsPtrTable[]; -extern const struct SpriteTemplate gUnknown_08329D98[4]; extern const struct CompressedSpriteSheet gSpriteSheet_EnemyShadow; extern const struct SpriteTemplate gSpriteTemplate_EnemyShadow; extern const u8 gEnemyMonElevation[]; @@ -68,7 +57,7 @@ extern const u8 gBlankGfxCompressed[]; extern const u16 gBattleInterface_BallStatusBarPal[]; extern const u16 gBattleInterface_BallDisplayPal[]; -extern u8 sub_80688F8(u8, u8 bank); +extern u8 sub_80688F8(u8, u8 battlerId); extern u8 pokemon_order_func(u8); // party menu extern void sub_81B8C68(void); @@ -366,7 +355,7 @@ void sub_805D770(struct Sprite *sprite, bool8 arg1) void sub_805D7AC(struct Sprite *sprite) { - if (!(gUnknown_020243FC & 1)) + if (!(gIntroSlideFlags & 1)) { sprite->pos2.x += sprite->data[0]; if (sprite->pos2.x == 0) @@ -421,7 +410,7 @@ void InitAndLaunchChosenStatusAnimation(bool8 isStatus2, u32 status) } } -#define tBank data[0] +#define tBattlerId data[0] bool8 TryHandleLaunchBattleTableAnimation(u8 activeBank, u8 atkBank, u8 defBank, u8 tableId, u16 argument) { @@ -451,8 +440,8 @@ bool8 TryHandleLaunchBattleTableAnimation(u8 activeBank, u8 atkBank, u8 defBank, gBattleSpritesDataPtr->animationData->animArg = argument; LaunchBattleAnimation(gBattleAnims_VariousTable, tableId, FALSE); taskId = CreateTask(Task_ClearBitWhenBattleTableAnimDone, 10); - gTasks[taskId].tBank = activeBank; - gBattleSpritesDataPtr->healthBoxesData[gTasks[taskId].tBank].animFromTableActive = 1; + gTasks[taskId].tBattlerId = activeBank; + gBattleSpritesDataPtr->healthBoxesData[gTasks[taskId].tBattlerId].animFromTableActive = 1; return FALSE; } @@ -462,12 +451,12 @@ static void Task_ClearBitWhenBattleTableAnimDone(u8 taskId) gAnimScriptCallback(); if (!gAnimScriptActive) { - gBattleSpritesDataPtr->healthBoxesData[gTasks[taskId].tBank].animFromTableActive = 0; + gBattleSpritesDataPtr->healthBoxesData[gTasks[taskId].tBattlerId].animFromTableActive = 0; DestroyTask(taskId); } } -#undef tBank +#undef tBattlerId static bool8 ShouldAnimBeDoneRegardlessOfSubsitute(u8 animId) { @@ -485,7 +474,7 @@ static bool8 ShouldAnimBeDoneRegardlessOfSubsitute(u8 animId) } } -#define tBank data[0] +#define tBattlerId data[0] void InitAndLaunchSpecialAnimation(u8 activeBank, u8 atkBank, u8 defBank, u8 tableId) { @@ -495,8 +484,8 @@ void InitAndLaunchSpecialAnimation(u8 activeBank, u8 atkBank, u8 defBank, u8 tab gBattleAnimTarget = defBank; LaunchBattleAnimation(gBattleAnims_Special, tableId, FALSE); taskId = CreateTask(Task_ClearBitWhenSpecialAnimDone, 10); - gTasks[taskId].tBank = activeBank; - gBattleSpritesDataPtr->healthBoxesData[gTasks[taskId].tBank].specialAnimActive = 1; + gTasks[taskId].tBattlerId = activeBank; + gBattleSpritesDataPtr->healthBoxesData[gTasks[taskId].tBattlerId].specialAnimActive = 1; } static void Task_ClearBitWhenSpecialAnimDone(u8 taskId) @@ -504,12 +493,12 @@ static void Task_ClearBitWhenSpecialAnimDone(u8 taskId) gAnimScriptCallback(); if (!gAnimScriptActive) { - gBattleSpritesDataPtr->healthBoxesData[gTasks[taskId].tBank].specialAnimActive = 0; + gBattleSpritesDataPtr->healthBoxesData[gTasks[taskId].tBattlerId].specialAnimActive = 0; DestroyTask(taskId); } } -#undef tBank +#undef tBattlerId // great function to include newly added moves that don't have animation yet bool8 IsMoveWithoutAnimation(u16 moveId, u8 animationTurn) @@ -517,13 +506,13 @@ bool8 IsMoveWithoutAnimation(u16 moveId, u8 animationTurn) return FALSE; } -bool8 mplay_80342A4(u8 bank) +bool8 mplay_80342A4(u8 battlerId) { u8 zero = 0; if (IsSEPlaying()) { - gBattleSpritesDataPtr->healthBoxesData[bank].field_8++; + gBattleSpritesDataPtr->healthBoxesData[battlerId].field_8++; if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_8 < 30) return TRUE; @@ -532,14 +521,14 @@ bool8 mplay_80342A4(u8 bank) } if (zero == 0) { - gBattleSpritesDataPtr->healthBoxesData[bank].field_8 = 0; + gBattleSpritesDataPtr->healthBoxesData[battlerId].field_8 = 0; return FALSE; } return TRUE; } -void BattleLoadOpponentMonSpriteGfx(struct Pokemon *mon, u8 bank) +void BattleLoadOpponentMonSpriteGfx(struct Pokemon *mon, u8 battlerId) { u32 monsPersonality, currentPersonality, otId; u16 species; @@ -549,50 +538,50 @@ void BattleLoadOpponentMonSpriteGfx(struct Pokemon *mon, u8 bank) monsPersonality = GetMonData(mon, MON_DATA_PERSONALITY); - if (gBattleSpritesDataPtr->battlerData[bank].transformSpecies == SPECIES_NONE) + if (gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies == SPECIES_NONE) { species = GetMonData(mon, MON_DATA_SPECIES); currentPersonality = monsPersonality; } else { - species = gBattleSpritesDataPtr->battlerData[bank].transformSpecies; - currentPersonality = gTransformedPersonalities[bank]; + species = gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies; + currentPersonality = gTransformedPersonalities[battlerId]; } otId = GetMonData(mon, MON_DATA_OT_ID); - position = GetBattlerPosition(bank); + position = GetBattlerPosition(battlerId); HandleLoadSpecialPokePic_DontHandleDeoxys(&gMonFrontPicTable[species], gMonSpritesGfxPtr->sprites[position], species, currentPersonality); - paletteOffset = 0x100 + bank * 16; + paletteOffset = 0x100 + battlerId * 16; - if (gBattleSpritesDataPtr->battlerData[bank].transformSpecies == SPECIES_NONE) + if (gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies == SPECIES_NONE) lzPaletteData = GetMonFrontSpritePal(mon); else lzPaletteData = GetFrontSpritePalFromSpeciesAndPersonality(species, otId, monsPersonality); LZDecompressWram(lzPaletteData, gDecompressionBuffer); LoadPalette(gDecompressionBuffer, paletteOffset, 0x20); - LoadPalette(gDecompressionBuffer, 0x80 + bank * 16, 0x20); + LoadPalette(gDecompressionBuffer, 0x80 + battlerId * 16, 0x20); if (species == SPECIES_CASTFORM) { - paletteOffset = 0x100 + bank * 16; + paletteOffset = 0x100 + battlerId * 16; LZDecompressWram(lzPaletteData, gBattleStruct->castformPalette[0]); - LoadPalette(gBattleStruct->castformPalette[gBattleMonForms[bank]], paletteOffset, 0x20); + LoadPalette(gBattleStruct->castformPalette[gBattleMonForms[battlerId]], paletteOffset, 0x20); } // transform's pink color - if (gBattleSpritesDataPtr->battlerData[bank].transformSpecies != SPECIES_NONE) + if (gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies != SPECIES_NONE) { - BlendPalette(paletteOffset, 16, 6, 0x7FFF); + BlendPalette(paletteOffset, 16, 6, RGB_WHITE); CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, 32); } } -void BattleLoadPlayerMonSpriteGfx(struct Pokemon *mon, u8 bank) +void BattleLoadPlayerMonSpriteGfx(struct Pokemon *mon, u8 battlerId) { u32 monsPersonality, currentPersonality, otId; u16 species; @@ -602,21 +591,21 @@ void BattleLoadPlayerMonSpriteGfx(struct Pokemon *mon, u8 bank) monsPersonality = GetMonData(mon, MON_DATA_PERSONALITY); - if (gBattleSpritesDataPtr->battlerData[bank].transformSpecies == SPECIES_NONE) + if (gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies == SPECIES_NONE) { species = GetMonData(mon, MON_DATA_SPECIES); currentPersonality = monsPersonality; } else { - species = gBattleSpritesDataPtr->battlerData[bank].transformSpecies; - currentPersonality = gTransformedPersonalities[bank]; + species = gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies; + currentPersonality = gTransformedPersonalities[battlerId]; } otId = GetMonData(mon, MON_DATA_OT_ID); - position = GetBattlerPosition(bank); + position = GetBattlerPosition(battlerId); - if (sub_80688F8(1, bank) == 1 || gBattleSpritesDataPtr->battlerData[bank].transformSpecies != SPECIES_NONE) + if (sub_80688F8(1, battlerId) == 1 || gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies != SPECIES_NONE) { HandleLoadSpecialPokePic_DontHandleDeoxys(&gMonBackPicTable[species], gMonSpritesGfxPtr->sprites[position], @@ -629,28 +618,28 @@ void BattleLoadPlayerMonSpriteGfx(struct Pokemon *mon, u8 bank) species, currentPersonality); } - paletteOffset = 0x100 + bank * 16; + paletteOffset = 0x100 + battlerId * 16; - if (gBattleSpritesDataPtr->battlerData[bank].transformSpecies == SPECIES_NONE) + if (gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies == SPECIES_NONE) lzPaletteData = GetMonFrontSpritePal(mon); else lzPaletteData = GetFrontSpritePalFromSpeciesAndPersonality(species, otId, monsPersonality); LZDecompressWram(lzPaletteData, gDecompressionBuffer); LoadPalette(gDecompressionBuffer, paletteOffset, 0x20); - LoadPalette(gDecompressionBuffer, 0x80 + bank * 16, 0x20); + LoadPalette(gDecompressionBuffer, 0x80 + battlerId * 16, 0x20); if (species == SPECIES_CASTFORM) { - paletteOffset = 0x100 + bank * 16; + paletteOffset = 0x100 + battlerId * 16; LZDecompressWram(lzPaletteData, gBattleStruct->castformPalette[0]); - LoadPalette(gBattleStruct->castformPalette[gBattleMonForms[bank]], paletteOffset, 0x20); + LoadPalette(gBattleStruct->castformPalette[gBattleMonForms[battlerId]], paletteOffset, 0x20); } // transform's pink color - if (gBattleSpritesDataPtr->battlerData[bank].transformSpecies != SPECIES_NONE) + if (gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies != SPECIES_NONE) { - BlendPalette(paletteOffset, 16, 6, 0x7FFF); + BlendPalette(paletteOffset, 16, 6, RGB_WHITE); CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, 32); } } @@ -663,23 +652,23 @@ void nullsub_24(u16 species) { } -void DecompressTrainerFrontPic(u16 frontPicId, u8 bank) +void DecompressTrainerFrontPic(u16 frontPicId, u8 battlerId) { - u8 position = GetBattlerPosition(bank); + u8 position = GetBattlerPosition(battlerId); DecompressPicFromTable_2(&gTrainerFrontPicTable[frontPicId], gMonSpritesGfxPtr->sprites[position], SPECIES_NONE); LoadCompressedObjectPalette(&gTrainerFrontPicPaletteTable[frontPicId]); } -void DecompressTrainerBackPic(u16 backPicId, u8 bank) +void DecompressTrainerBackPic(u16 backPicId, u8 battlerId) { - u8 position = GetBattlerPosition(bank); + u8 position = GetBattlerPosition(battlerId); DecompressPicFromTable_2(&gTrainerBackPicTable[backPicId], gMonSpritesGfxPtr->sprites[position], SPECIES_NONE); LoadCompressedPalette(gTrainerBackPicPaletteTable[backPicId].data, - 0x100 + 16 * bank, 0x20); + 0x100 + 16 * battlerId, 0x20); } void nullsub_25(u8 arg0) @@ -776,7 +765,7 @@ void LoadBattleBarGfx(u8 arg0) LZDecompressWram(gUnknown_08C093F0, gMonSpritesGfxPtr->barFontGfx); } -bool8 BattleInitAllSprites(u8 *state1, u8 *bank) +bool8 BattleInitAllSprites(u8 *state1, u8 *battlerId) { bool8 retVal = FALSE; @@ -787,13 +776,13 @@ bool8 BattleInitAllSprites(u8 *state1, u8 *bank) (*state1)++; break; case 1: - if (!BattleLoadAllHealthBoxesGfx(*bank)) + if (!BattleLoadAllHealthBoxesGfx(*battlerId)) { - (*bank)++; + (*battlerId)++; } else { - *bank = 0; + *battlerId = 0; (*state1)++; } break; @@ -801,47 +790,47 @@ bool8 BattleInitAllSprites(u8 *state1, u8 *bank) (*state1)++; break; case 3: - if ((gBattleTypeFlags & BATTLE_TYPE_SAFARI) && *bank == 0) - gHealthboxSpriteIds[*bank] = CreateSafariPlayerHealthboxSprites(); + if ((gBattleTypeFlags & BATTLE_TYPE_SAFARI) && *battlerId == 0) + gHealthboxSpriteIds[*battlerId] = CreateSafariPlayerHealthboxSprites(); else - gHealthboxSpriteIds[*bank] = CreateBattlerHealthboxSprites(*bank); + gHealthboxSpriteIds[*battlerId] = CreateBattlerHealthboxSprites(*battlerId); - (*bank)++; - if (*bank == gBattlersCount) + (*battlerId)++; + if (*battlerId == gBattlersCount) { - *bank = 0; + *battlerId = 0; (*state1)++; } break; case 4: - InitBattlerHealthboxCoords(*bank); - if (gBattlerPositions[*bank] <= 1) - DummyBattleInterfaceFunc(gHealthboxSpriteIds[*bank], FALSE); + InitBattlerHealthboxCoords(*battlerId); + if (gBattlerPositions[*battlerId] <= 1) + DummyBattleInterfaceFunc(gHealthboxSpriteIds[*battlerId], FALSE); else - DummyBattleInterfaceFunc(gHealthboxSpriteIds[*bank], TRUE); + DummyBattleInterfaceFunc(gHealthboxSpriteIds[*battlerId], TRUE); - (*bank)++; - if (*bank == gBattlersCount) + (*battlerId)++; + if (*battlerId == gBattlersCount) { - *bank = 0; + *battlerId = 0; (*state1)++; } break; case 5: - if (GetBattlerSide(*bank) == B_SIDE_PLAYER) + if (GetBattlerSide(*battlerId) == B_SIDE_PLAYER) { if (!(gBattleTypeFlags & BATTLE_TYPE_SAFARI)) - UpdateHealthboxAttribute(gHealthboxSpriteIds[*bank], &gPlayerParty[gBattlerPartyIndexes[*bank]], HEALTHBOX_ALL); + UpdateHealthboxAttribute(gHealthboxSpriteIds[*battlerId], &gPlayerParty[gBattlerPartyIndexes[*battlerId]], HEALTHBOX_ALL); } else { - UpdateHealthboxAttribute(gHealthboxSpriteIds[*bank], &gEnemyParty[gBattlerPartyIndexes[*bank]], HEALTHBOX_ALL); + UpdateHealthboxAttribute(gHealthboxSpriteIds[*battlerId], &gEnemyParty[gBattlerPartyIndexes[*battlerId]], HEALTHBOX_ALL); } - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[*bank]); - (*bank)++; - if (*bank == gBattlersCount) + SetHealthboxSpriteInvisible(gHealthboxSpriteIds[*battlerId]); + (*battlerId)++; + if (*battlerId == gBattlersCount) { - *bank = 0; + *battlerId = 0; (*state1)++; } break; @@ -875,9 +864,9 @@ void CopyAllBattleSpritesInvisibilities(void) gBattleSpritesDataPtr->battlerData[i].invisible = gSprites[gBattlerSpriteIds[i]].invisible; } -void CopyBattleSpriteInvisibility(u8 bank) +void CopyBattleSpriteInvisibility(u8 battlerId) { - gBattleSpritesDataPtr->battlerData[bank].invisible = gSprites[gBattlerSpriteIds[bank]].invisible; + gBattleSpritesDataPtr->battlerData[battlerId].invisible = gSprites[gBattlerSpriteIds[battlerId]].invisible; } void HandleSpeciesGfxDataChange(u8 bankAtk, u8 bankDef, bool8 notTransform) @@ -896,7 +885,7 @@ void HandleSpeciesGfxDataChange(u8 bankAtk, u8 bankDef, bool8 notTransform) gBattleMonForms[bankAtk] = gBattleSpritesDataPtr->animationData->animArg; if (gBattleSpritesDataPtr->battlerData[bankAtk].transformSpecies != SPECIES_NONE) { - BlendPalette(paletteOffset, 16, 6, 0x7FFF); + BlendPalette(paletteOffset, 16, 6, RGB_WHITE); CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, 32); } gSprites[gBattlerSpriteIds[bankAtk]].pos1.y = GetBattlerSpriteDefault_Y(bankAtk); @@ -965,7 +954,7 @@ void HandleSpeciesGfxDataChange(u8 bankAtk, u8 bankDef, bool8 notTransform) LoadPalette(gBattleStruct->castformPalette[0] + gBattleMonForms[bankDef] * 16, paletteOffset, 32); } - BlendPalette(paletteOffset, 16, 6, 0x7FFF); + BlendPalette(paletteOffset, 16, 6, RGB_WHITE); CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, 32); if (!IsContest()) @@ -979,7 +968,7 @@ void HandleSpeciesGfxDataChange(u8 bankAtk, u8 bankDef, bool8 notTransform) } } -void BattleLoadSubstituteOrMonSpriteGfx(u8 bank, bool8 loadMonSprite) +void BattleLoadSubstituteOrMonSpriteGfx(u8 battlerId, bool8 loadMonSprite) { u8 position; s32 i; @@ -991,17 +980,17 @@ void BattleLoadSubstituteOrMonSpriteGfx(u8 bank, bool8 loadMonSprite) if (IsContest()) position = 0; else - position = GetBattlerPosition(bank); + position = GetBattlerPosition(battlerId); if (IsContest()) LZDecompressVram(gSubstituteDollTilemap, gMonSpritesGfxPtr->sprites[position]); - else if (GetBattlerSide(bank) != B_SIDE_PLAYER) + else if (GetBattlerSide(battlerId) != B_SIDE_PLAYER) LZDecompressVram(gSubstituteDollGfx, gMonSpritesGfxPtr->sprites[position]); else LZDecompressVram(gSubstituteDollTilemap, gMonSpritesGfxPtr->sprites[position]); i = 1; - var = bank * 16; + var = battlerId * 16; substitutePal = gSubstituteDollPal; for (; i < 4; i++) { @@ -1018,59 +1007,59 @@ void BattleLoadSubstituteOrMonSpriteGfx(u8 bank, bool8 loadMonSprite) { if (!IsContest()) { - if (GetBattlerSide(bank) != B_SIDE_PLAYER) - BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[bank]], bank); + if (GetBattlerSide(battlerId) != B_SIDE_PLAYER) + BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[battlerId]], battlerId); else - BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[bank]], bank); + BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[battlerId]], battlerId); } } } -void LoadBattleMonGfxAndAnimate(u8 bank, bool8 loadMonSprite, u8 spriteId) +void LoadBattleMonGfxAndAnimate(u8 battlerId, bool8 loadMonSprite, u8 spriteId) { - BattleLoadSubstituteOrMonSpriteGfx(bank, loadMonSprite); - StartSpriteAnim(&gSprites[spriteId], gBattleMonForms[bank]); + BattleLoadSubstituteOrMonSpriteGfx(battlerId, loadMonSprite); + StartSpriteAnim(&gSprites[spriteId], gBattleMonForms[battlerId]); if (!loadMonSprite) - gSprites[spriteId].pos1.y = GetSubstituteSpriteDefault_Y(bank); + gSprites[spriteId].pos1.y = GetSubstituteSpriteDefault_Y(battlerId); else - gSprites[spriteId].pos1.y = GetBattlerSpriteDefault_Y(bank); + gSprites[spriteId].pos1.y = GetBattlerSpriteDefault_Y(battlerId); } -void TrySetBehindSubstituteSpriteBit(u8 bank, u16 move) +void TrySetBehindSubstituteSpriteBit(u8 battlerId, u16 move) { if (move == MOVE_SUBSTITUTE) - gBattleSpritesDataPtr->battlerData[bank].behindSubstitute = 1; + gBattleSpritesDataPtr->battlerData[battlerId].behindSubstitute = 1; } -void ClearBehindSubstituteBit(u8 bank) +void ClearBehindSubstituteBit(u8 battlerId) { - gBattleSpritesDataPtr->battlerData[bank].behindSubstitute = 0; + gBattleSpritesDataPtr->battlerData[battlerId].behindSubstitute = 0; } -void HandleLowHpMusicChange(struct Pokemon *mon, u8 bank) +void HandleLowHpMusicChange(struct Pokemon *mon, u8 battlerId) { u16 hp = GetMonData(mon, MON_DATA_HP); u16 maxHP = GetMonData(mon, MON_DATA_MAX_HP); if (GetHPBarLevel(hp, maxHP) == HP_BAR_RED) { - if (!gBattleSpritesDataPtr->battlerData[bank].lowHpSong) + if (!gBattleSpritesDataPtr->battlerData[battlerId].lowHpSong) { - if (!gBattleSpritesDataPtr->battlerData[bank ^ BIT_FLANK].lowHpSong) + if (!gBattleSpritesDataPtr->battlerData[battlerId ^ BIT_FLANK].lowHpSong) PlaySE(SE_HINSI); - gBattleSpritesDataPtr->battlerData[bank].lowHpSong = 1; + gBattleSpritesDataPtr->battlerData[battlerId].lowHpSong = 1; } } else { - gBattleSpritesDataPtr->battlerData[bank].lowHpSong = 0; + gBattleSpritesDataPtr->battlerData[battlerId].lowHpSong = 0; if (!IsDoubleBattle()) { m4aSongNumStop(SE_HINSI); return; } - if (IsDoubleBattle() && !gBattleSpritesDataPtr->battlerData[bank ^ BIT_FLANK].lowHpSong) + if (IsDoubleBattle() && !gBattleSpritesDataPtr->battlerData[battlerId ^ BIT_FLANK].lowHpSong) { m4aSongNumStop(SE_HINSI); return; @@ -1135,44 +1124,44 @@ void sub_805EB9C(u8 affineMode) } } -#define tBank data[0] +#define tBattlerId data[0] void LoadAndCreateEnemyShadowSprites(void) { - u8 bank; + u8 battlerId; LoadCompressedObjectPic(&gSpriteSheet_EnemyShadow); - bank = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); - gBattleSpritesDataPtr->healthBoxesData[bank].shadowSpriteId = CreateSprite(&gSpriteTemplate_EnemyShadow, GetBattlerSpriteCoord(bank, 0), GetBattlerSpriteCoord(bank, 1) + 29, 0xC8); - gSprites[gBattleSpritesDataPtr->healthBoxesData[bank].shadowSpriteId].data[0] = bank; + battlerId = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); + gBattleSpritesDataPtr->healthBoxesData[battlerId].shadowSpriteId = CreateSprite(&gSpriteTemplate_EnemyShadow, GetBattlerSpriteCoord(battlerId, 0), GetBattlerSpriteCoord(battlerId, 1) + 29, 0xC8); + gSprites[gBattleSpritesDataPtr->healthBoxesData[battlerId].shadowSpriteId].data[0] = battlerId; if (IsDoubleBattle()) { - bank = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); - gBattleSpritesDataPtr->healthBoxesData[bank].shadowSpriteId = CreateSprite(&gSpriteTemplate_EnemyShadow, GetBattlerSpriteCoord(bank, 0), GetBattlerSpriteCoord(bank, 1) + 29, 0xC8); - gSprites[gBattleSpritesDataPtr->healthBoxesData[bank].shadowSpriteId].data[0] = bank; + battlerId = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); + gBattleSpritesDataPtr->healthBoxesData[battlerId].shadowSpriteId = CreateSprite(&gSpriteTemplate_EnemyShadow, GetBattlerSpriteCoord(battlerId, 0), GetBattlerSpriteCoord(battlerId, 1) + 29, 0xC8); + gSprites[gBattleSpritesDataPtr->healthBoxesData[battlerId].shadowSpriteId].data[0] = battlerId; } } void SpriteCB_EnemyShadow(struct Sprite *shadowSprite) { bool8 invisible = FALSE; - u8 bank = shadowSprite->tBank; - struct Sprite *bankSprite = &gSprites[gBattlerSpriteIds[bank]]; + u8 battlerId = shadowSprite->tBattlerId; + struct Sprite *bankSprite = &gSprites[gBattlerSpriteIds[battlerId]]; - if (!bankSprite->inUse || !IsBattlerSpritePresent(bank)) + if (!bankSprite->inUse || !IsBattlerSpritePresent(battlerId)) { shadowSprite->callback = SpriteCB_SetInvisible; return; } if (gAnimScriptActive || bankSprite->invisible) invisible = TRUE; - else if (gBattleSpritesDataPtr->battlerData[bank].transformSpecies != SPECIES_NONE - && gEnemyMonElevation[gBattleSpritesDataPtr->battlerData[bank].transformSpecies] == 0) + else if (gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies != SPECIES_NONE + && gEnemyMonElevation[gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies] == 0) invisible = TRUE; - if (gBattleSpritesDataPtr->battlerData[bank].behindSubstitute) + if (gBattleSpritesDataPtr->battlerData[battlerId].behindSubstitute) invisible = TRUE; shadowSprite->pos1.x = bankSprite->pos1.x; @@ -1180,31 +1169,31 @@ void SpriteCB_EnemyShadow(struct Sprite *shadowSprite) shadowSprite->invisible = invisible; } -#undef tBank +#undef tBattlerId void SpriteCB_SetInvisible(struct Sprite *sprite) { sprite->invisible = 1; } -void SetBattlerShadowSpriteCallback(u8 bank, u16 species) +void SetBattlerShadowSpriteCallback(u8 battlerId, u16 species) { // The player's shadow is never seen - if (GetBattlerSide(bank) == B_SIDE_PLAYER) + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) return; - if (gBattleSpritesDataPtr->battlerData[bank].transformSpecies != SPECIES_NONE) - species = gBattleSpritesDataPtr->battlerData[bank].transformSpecies; + if (gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies != SPECIES_NONE) + species = gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies; if (gEnemyMonElevation[species] != 0) - gSprites[gBattleSpritesDataPtr->healthBoxesData[bank].shadowSpriteId].callback = SpriteCB_EnemyShadow; + gSprites[gBattleSpritesDataPtr->healthBoxesData[battlerId].shadowSpriteId].callback = SpriteCB_EnemyShadow; else - gSprites[gBattleSpritesDataPtr->healthBoxesData[bank].shadowSpriteId].callback = SpriteCB_SetInvisible; + gSprites[gBattleSpritesDataPtr->healthBoxesData[battlerId].shadowSpriteId].callback = SpriteCB_SetInvisible; } -void HideBattlerShadowSprite(u8 bank) +void HideBattlerShadowSprite(u8 battlerId) { - gSprites[gBattleSpritesDataPtr->healthBoxesData[bank].shadowSpriteId].callback = SpriteCB_SetInvisible; + gSprites[gBattleSpritesDataPtr->healthBoxesData[battlerId].shadowSpriteId].callback = SpriteCB_SetInvisible; } void sub_805EF14(void) @@ -1230,12 +1219,12 @@ void sub_805EF14(void) } } -void ClearTemporarySpeciesSpriteData(u8 bank, bool8 dontClearSubstitute) +void ClearTemporarySpeciesSpriteData(u8 battlerId, bool8 dontClearSubstitute) { - gBattleSpritesDataPtr->battlerData[bank].transformSpecies = SPECIES_NONE; - gBattleMonForms[bank] = 0; + gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies = SPECIES_NONE; + gBattleMonForms[battlerId] = 0; if (!dontClearSubstitute) - ClearBehindSubstituteBit(bank); + ClearBehindSubstituteBit(battlerId); } void AllocateMonSpritesGfx(void) diff --git a/src/battle_interface.c b/src/battle_interface.c index ce37564b7..96462ec04 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -153,11 +153,6 @@ enum HEALTHBOX_GFX_117, }; -extern u8 gBattlerPositions[MAX_BATTLERS_COUNT]; -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; -extern u8 gBattlersCount; -extern u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT]; - extern const u8 * const gNatureNamePointers[]; extern const u8 gSpeciesNames[][POKEMON_NAME_LENGTH + 1]; @@ -177,9 +172,6 @@ extern const u16 gBattleInterface_BallStatusBarPal[]; extern const u16 gBattleInterface_BallDisplayPal[]; extern const u8 gHealthboxElementsGfxTable[][32]; -// functions -extern void LoadBattleBarGfx(u8 arg0); - // this file's functions static const u8 *GetHealthboxElementGfxPtr(u8 elementId); @@ -658,7 +650,7 @@ static void sub_8072308(s16 arg0, u16 *arg1, u8 arg2) } #else -__attribute__((naked)) +ASM_DIRECT static void sub_8072308(s16 arg0, u16 *arg1, u8 arg2) { asm(".syntax unified\n\ @@ -1536,7 +1528,7 @@ u8 CreatePartyStatusSummarySprites(u8 bank, struct HpAndStatus *partyInfo, u8 ar gSprites[barSpriteId].pos1.x += 96; } - for (i = 0; i < 6; i++) + for (i = 0; i < PARTY_SIZE; i++) { ballIconSpritesIds[i] = CreateSpriteAtEnd(&sStatusSummaryBallsSpriteTemplates[isOpponent], bar_X, bar_Y - 4, 9); diff --git a/src/battle_main.c b/src/battle_main.c index 3704ff3b4..78b69212d 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -7,6 +7,7 @@ #include "scanline_effect.h" #include "battle_setup.h" #include "battle_scripts.h" +#include "battle_interface.h" #include "pokemon.h" #include "palette.h" #include "task.h" @@ -19,6 +20,7 @@ #include "constants/hold_effects.h" #include "constants/trainers.h" #include "link.h" +#include "link_rfu.h" #include "bg.h" #include "dma3.h" #include "string_util.h" @@ -43,10 +45,13 @@ #include "roamer.h" #include "tv.h" #include "safari_zone.h" -#include "battle_string_ids.h" +#include "constants/battle_string_ids.h" #include "data2.h" +#include "decompress.h" +#include "international_string_util.h" +#include "pokeball.h" -struct UnknownPokemonStruct2 +struct UnknownPokemonStruct4 { /*0x00*/ u16 species; /*0x02*/ u16 heldItem; @@ -60,8 +65,6 @@ struct UnknownPokemonStruct2 /*0x1D*/ u8 language; }; -extern u8 gBattleCommunication[]; -extern u8 gBattleTerrain; extern u16 gBattle_BG0_X; extern u16 gBattle_BG0_Y; extern u16 gBattle_BG1_X; @@ -70,84 +73,19 @@ extern u16 gBattle_BG2_X; extern u16 gBattle_BG2_Y; extern u16 gBattle_BG3_X; extern u16 gBattle_BG3_Y; -extern u16 gPartnerTrainerId; extern u16 gBattle_WIN0H; extern u16 gBattle_WIN0V; extern u16 gBattle_WIN1H; extern u16 gBattle_WIN1V; -extern u16 gTrainerBattleOpponent_A; -extern u16 gTrainerBattleOpponent_B; -extern struct BattleEnigmaBerry gEnigmaBerries[MAX_BATTLERS_COUNT]; -extern void (*gPreBattleCallback1)(void); -extern void (*gBattleMainFunc)(void); -extern void (*gCB2_AfterEvolution)(void); -extern struct UnknownPokemonStruct2 gUnknown_02022FF8[3]; // what is it used for? -extern struct UnknownPokemonStruct2* gUnknown_02023058; // what is it used for? extern struct MusicPlayerInfo gMPlayInfo_SE1; extern struct MusicPlayerInfo gMPlayInfo_SE2; -extern u8 gDecompressionBuffer[]; -extern u16 gUnknown_020243FC; -extern u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT]; -extern void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(void); -extern u8 gBattleBufferA[MAX_BATTLERS_COUNT][0x200]; -extern u8 gBattleBufferB[MAX_BATTLERS_COUNT][0x200]; -extern u8 gStringBattler; -extern u32 gUnknown_02022F88; -extern u32 gHitMarker; -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; -extern u8 gBattleMonForms[MAX_BATTLERS_COUNT]; -extern u8 gBattlerSpriteIds[MAX_BATTLERS_COUNT]; -extern u16 gPaydayMoney; -extern u16 gBattleWeather; -extern u16 gPauseCounterBattle; -extern u16 gRandomTurnNumber; -extern u8 gActiveBattler; -extern u8 gBattlersCount; -extern u8 gBattlerAttacker; -extern u8 gBattlerTarget; -extern u8 gLeveledUpInBattle; -extern u8 gAbsentBattlerFlags; -extern u32 gBattleControllerExecFlags; -extern u8 gMultiHitCounter; -extern u8 gMoveResultFlags; -extern s32 gBattleMoveDamage; -extern const u8* gPalaceSelectionBattleScripts[MAX_BATTLERS_COUNT]; -extern u16 gLastPrintedMoves[MAX_BATTLERS_COUNT]; -extern u16 gLastMoves[MAX_BATTLERS_COUNT]; -extern u16 gLastLandedMoves[MAX_BATTLERS_COUNT]; -extern u16 gLastHitByType[MAX_BATTLERS_COUNT]; -extern u16 gLastResultingMoves[MAX_BATTLERS_COUNT]; -extern u16 gLockedMoves[MAX_BATTLERS_COUNT]; -extern u8 gLastHitBy[MAX_BATTLERS_COUNT]; -extern u8 gUnknown_02024284[MAX_BATTLERS_COUNT]; -extern u32 gStatuses3[MAX_BATTLERS_COUNT]; -extern u16 gSideStatuses[2]; -extern u16 gCurrentMove; -extern u8 gActionSelectionCursor[MAX_BATTLERS_COUNT]; -extern u8 gMoveSelectionCursor[MAX_BATTLERS_COUNT]; -extern struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT]; -extern u8 gBattleTurnOrder[MAX_BATTLERS_COUNT]; -extern u8 gChosenActionByBattler[MAX_BATTLERS_COUNT]; -extern u16 gChosenMoveByBattler[MAX_BATTLERS_COUNT]; -extern u8 gCurrentActionFuncId; -extern u8 gLastUsedAbility; extern u8 gUnknown_0203CF00[]; -extern const u8* gSelectionBattleScripts[MAX_BATTLERS_COUNT]; -extern const u8* gBattlescriptCurrInstr; -extern u8 gActionsByTurnOrder[MAX_BATTLERS_COUNT]; -extern u8 gCurrentTurnActionNumber; -extern u16 gDynamicBasePower; -extern u8 gCritMultiplier; -extern u8 gCurrMovePos; -extern u8 gUnknown_020241E9; -extern u16 gChosenMove; extern const struct BattleMove gBattleMoves[]; extern const u16 gBattleTextboxPalette[]; // battle textbox palette extern const struct BgTemplate gUnknown_0831AA08[]; extern const struct WindowTemplate * const gUnknown_0831ABA0[]; extern const u8 gUnknown_0831ACE0[]; -extern const u8 gStatStageRatios[][2]; extern const u8 * const gBattleScriptsForMoveEffects[]; extern const u8 * const gBattlescriptsForBallThrow[]; extern const u8 * const gBattlescriptsForRunningByItem[]; @@ -172,20 +110,14 @@ extern const u8 gText_Confusion[]; extern const u8 gText_Love[]; // functions -extern void ScanlineEffect_Clear(void); -extern void sub_80356D0(void); extern void GetFrontierTrainerName(u8* dst, u16 trainerId); // battle tower extern void sub_8166188(void); // battle tower, sets link battle mons level but why? extern void sub_8165B88(u8* dst, u16 trainerId); // battle tower, gets language -extern void PadNameString(u8* dst, u8 arg2); // extern void sub_81B9150(void); -extern void sub_800AC34(void); extern void sub_80B3AF8(u8 taskId); // cable club -extern void sub_8076918(u8 bank); -extern void SetHealthboxSpriteVisible(u8 healthoxSpriteId); extern void sub_81A56B4(void); // battle frontier 2 extern u8 sub_81A9E28(void); // battle frontier 2 -extern void sub_81A56E8(u8 bank); // battle frontier 2 +extern void sub_81A56E8(u8 battlerId); // battle frontier 2 extern void sub_81B8FB0(u8, u8); // party menu extern u8 pokemon_order_func(u8); // party menu extern bool8 InBattlePyramid(void); @@ -233,7 +165,7 @@ static void BattleIntroPlayer1SendsOutMonAnimation(void); static void TryDoEventsBeforeFirstTurn(void); static void HandleTurnActionSelectionState(void); static void RunTurnActionsFunctions(void); -static void SetActionsAndBanksTurnOrder(void); +static void SetActionsAndBattlersTurnOrder(void); static void sub_803CDF8(void); static bool8 sub_803CDB8(void); static void CheckFocusPunch_ClearVarsBeforeTurnStarts(void); @@ -261,6 +193,113 @@ static void HandleAction_Action11(void); static void HandleAction_NothingIsFainted(void); static void HandleAction_ActionFinished(void); +// EWRAM vars +EWRAM_DATA static u32 sUnusedUnknownArray[25] = {0}; +EWRAM_DATA u32 gBattleTypeFlags = 0; +EWRAM_DATA u8 gBattleTerrain = 0; +EWRAM_DATA u32 gUnknown_02022FF4 = 0; +EWRAM_DATA struct UnknownPokemonStruct4 gUnknown_02022FF8[3] = {0}; // what is it used for? +EWRAM_DATA struct UnknownPokemonStruct4* gUnknown_02023058 = NULL; // what is it used for? +EWRAM_DATA u8 *gUnknown_0202305C = NULL; +EWRAM_DATA u8 *gUnknown_02023060 = NULL; +EWRAM_DATA u8 gBattleBufferA[MAX_BATTLERS_COUNT][0x200] = {0}; +EWRAM_DATA u8 gBattleBufferB[MAX_BATTLERS_COUNT][0x200] = {0}; +EWRAM_DATA u8 gActiveBattler = 0; +EWRAM_DATA u32 gBattleControllerExecFlags = 0; +EWRAM_DATA u8 gBattlersCount = 0; +EWRAM_DATA u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gBattlerPositions[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gActionsByTurnOrder[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gBattleTurnOrder[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gCurrentTurnActionNumber = 0; +EWRAM_DATA u8 gCurrentActionFuncId = 0; +EWRAM_DATA struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gBattlerSpriteIds[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gCurrMovePos = 0; +EWRAM_DATA u8 gChosenMovePos = 0; +EWRAM_DATA u16 gCurrentMove = 0; +EWRAM_DATA u16 gChosenMove = 0; +EWRAM_DATA u16 gRandomMove = 0; +EWRAM_DATA s32 gBattleMoveDamage = 0; +EWRAM_DATA s32 gHpDealt = 0; +EWRAM_DATA s32 gTakenDmg[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u16 gLastUsedItem = 0; +EWRAM_DATA u8 gLastUsedAbility = 0; +EWRAM_DATA u8 gBattlerAttacker = 0; +EWRAM_DATA u8 gBattlerTarget = 0; +EWRAM_DATA u8 gBattlerFainted = 0; +EWRAM_DATA u8 gEffectBattler = 0; +EWRAM_DATA u8 gPotentialItemEffectBattler = 0; +EWRAM_DATA u8 gAbsentBattlerFlags = 0; +EWRAM_DATA u8 gCritMultiplier = 0; +EWRAM_DATA u8 gMultiHitCounter = 0; +EWRAM_DATA const u8 *gBattlescriptCurrInstr = NULL; +EWRAM_DATA u32 gUnusedBattleMainVar = 0; +EWRAM_DATA u8 gChosenActionByBattler[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA const u8 *gSelectionBattleScripts[MAX_BATTLERS_COUNT] = {NULL}; +EWRAM_DATA const u8 *gPalaceSelectionBattleScripts[MAX_BATTLERS_COUNT] = {NULL}; +EWRAM_DATA u16 gLastPrintedMoves[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u16 gLastMoves[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u16 gLastLandedMoves[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u16 gLastHitByType[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u16 gLastResultingMoves[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u16 gLockedMoves[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gLastHitBy[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u16 gChosenMoveByBattler[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gMoveResultFlags = 0; +EWRAM_DATA u32 gHitMarker = 0; +EWRAM_DATA static u8 sUnusedBattlersArray[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gTakenDmgByBattler[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gUnknown_0202428C = 0; +EWRAM_DATA u16 gSideStatuses[2] = {0}; +EWRAM_DATA struct SideTimer gSideTimers[2] = {0}; +EWRAM_DATA u32 gStatuses3[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA struct DisableStruct gDisableStructs[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u16 gPauseCounterBattle = 0; +EWRAM_DATA u16 gPaydayMoney = 0; +EWRAM_DATA u16 gRandomTurnNumber = 0; +EWRAM_DATA u8 gBattleCommunication[BATTLE_COMMUNICATION_ENTRIES_COUNT] = {0}; +EWRAM_DATA u8 gBattleOutcome = 0; +EWRAM_DATA struct ProtectStruct gProtectStructs[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA struct SpecialStatus gSpecialStatuses[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u16 gBattleWeather = 0; +EWRAM_DATA struct WishFutureKnock gWishFutureKnock = {0}; +EWRAM_DATA u16 gIntroSlideFlags = 0; +EWRAM_DATA u8 gSentPokesToOpponent[2] = {0}; +EWRAM_DATA u16 gDynamicBasePower = 0; +EWRAM_DATA u16 gExpShareExp = 0; +EWRAM_DATA struct BattleEnigmaBerry gEnigmaBerries[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA struct BattleScripting gBattleScripting = {0}; +EWRAM_DATA struct BattleStruct *gBattleStruct = NULL; +EWRAM_DATA u8 *gLinkBattleSendBuffer = NULL; +EWRAM_DATA u8 *gLinkBattleRecvBuffer = NULL; +EWRAM_DATA struct BattleResources *gBattleResources = NULL; +EWRAM_DATA u8 gActionSelectionCursor[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gMoveSelectionCursor[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gBattlerStatusSummaryTaskId[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gBattlerInMenuId = 0; +EWRAM_DATA bool8 gDoingBattleAnim = FALSE; +EWRAM_DATA u32 gTransformedPersonalities[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gPlayerDpadHoldFrames = 0; +EWRAM_DATA struct BattleSpriteData *gBattleSpritesDataPtr = NULL; +EWRAM_DATA struct MonSpritesGfx *gMonSpritesGfxPtr = NULL; +EWRAM_DATA struct BattleHealthboxInfo *gUnknown_020244D8 = NULL; +EWRAM_DATA struct BattleHealthboxInfo *gUnknown_020244DC = NULL; +EWRAM_DATA u16 gBattleMovePower = 0; +EWRAM_DATA u16 gMoveToLearn = 0; +EWRAM_DATA u8 gBattleMonForms[MAX_BATTLERS_COUNT] = {0}; + +// IWRAM common vars +void (*gPreBattleCallback1)(void); +void (*gBattleMainFunc)(void); +struct BattleResults gBattleResults; +u8 gLeveledUpInBattle; +void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(void); +u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT]; +u8 gMultiUsePlayerCursor; +u8 gNumberOfMovesToChoose; +u8 gUnknown_03005D7C[MAX_BATTLERS_COUNT]; + // rom const data static void (* const sTurnActionsFuncsTable[])(void) = { @@ -288,11 +327,11 @@ static void (* const sEndTurnFuncsTable[])(void) = HandleEndTurn_BattleLost, // B_OUTCOME_DREW HandleEndTurn_RanFromBattle, // B_OUTCOME_RAN HandleEndTurn_FinishBattle, // B_OUTCOME_PLAYER_TELEPORTED - HandleEndTurn_MonFled, // B_OUTCOME_POKE_FLED - HandleEndTurn_FinishBattle, // B_OUTCOME_CAUGHT_POKE + HandleEndTurn_MonFled, // B_OUTCOME_MON_FLED + HandleEndTurn_FinishBattle, // B_OUTCOME_CAUGHT HandleEndTurn_FinishBattle, // battle outcome 8 HandleEndTurn_FinishBattle, // B_OUTCOME_FORFEITED - HandleEndTurn_FinishBattle, // B_OUTCOME_POKE_TELEPORTED + HandleEndTurn_FinishBattle, // B_OUTCOME_MON_TELEPORTED }; const u8 gStatusConditionString_PoisonJpn[8] = _("どく$$$$$"); @@ -699,7 +738,7 @@ static void CB2_HandleStartBattle(void) sub_805EF14(); gBattleCommunication[MULTIUSE_STATE] = 1; } - if (gLinkVSyncDisabled) + if (gWirelessCommType) sub_800E0E8(); break; case 1: @@ -723,8 +762,8 @@ static void CB2_HandleStartBattle(void) SendBlock(bitmask_all_link_players_but_self(), &gBattleStruct->field_180, 32); gBattleCommunication[MULTIUSE_STATE] = 2; } - if (gLinkVSyncDisabled) - sub_800DFB4(0, 0); + if (gWirelessCommType) + CreateWirelessStatusIndicatorSprite(0, 0); } } else @@ -751,7 +790,7 @@ static void CB2_HandleStartBattle(void) gTasks[taskId].data[4] = gBlockRecvBuffer[enemyMultiplayerId][1]; sub_8185F90(gBlockRecvBuffer[playerMultiplayerId][1]); sub_8185F90(gBlockRecvBuffer[enemyMultiplayerId][1]); - sub_8068AA4(); + SetDeoxysStats(); gBattleCommunication[MULTIUSE_STATE]++; } break; @@ -894,7 +933,7 @@ static void CB2_HandleStartMultiPartnerBattle(void) sub_805EF14(); gBattleCommunication[MULTIUSE_STATE] = 1; } - if (gLinkVSyncDisabled) + if (gWirelessCommType) sub_800E0E8(); // fall through case 1: @@ -925,8 +964,8 @@ static void CB2_HandleStartMultiPartnerBattle(void) gBattleCommunication[MULTIUSE_STATE] = 2; } - if (gLinkVSyncDisabled) - sub_800DFB4(0, 0); + if (gWirelessCommType) + CreateWirelessStatusIndicatorSprite(0, 0); } } else @@ -1163,9 +1202,9 @@ static void CB2_PreInitMultiBattle(void) case 0: if (gReceivedRemoteLinkPlayers != 0 && sub_800A520()) { - gUnknown_02023058 = Alloc(sizeof(struct UnknownPokemonStruct2) * 3); + gUnknown_02023058 = Alloc(sizeof(struct UnknownPokemonStruct4) * 3); sub_80379F8(0); - SendBlock(bitmask_all_link_players_but_self(), gUnknown_02023058, sizeof(struct UnknownPokemonStruct2) * 3); + SendBlock(bitmask_all_link_players_but_self(), gUnknown_02023058, sizeof(struct UnknownPokemonStruct4) * 3); gBattleCommunication[MULTIUSE_STATE]++; } break; @@ -1183,12 +1222,12 @@ static void CB2_PreInitMultiBattle(void) if ((!(gLinkPlayers[i].lp_field_18 & 1) && !(gLinkPlayers[playerMultiplierId].lp_field_18 & 1)) || (gLinkPlayers[i].lp_field_18 & 1 && gLinkPlayers[playerMultiplierId].lp_field_18 & 1)) { - memcpy(gUnknown_02022FF8, gBlockRecvBuffer[i], sizeof(struct UnknownPokemonStruct2) * 3); + memcpy(gUnknown_02022FF8, gBlockRecvBuffer[i], sizeof(struct UnknownPokemonStruct4) * 3); } } else { - memcpy(gUnknown_02022FF8, gBlockRecvBuffer[i], sizeof(struct UnknownPokemonStruct2) * 3); + memcpy(gUnknown_02022FF8, gBlockRecvBuffer[i], sizeof(struct UnknownPokemonStruct4) * 3); } } gBattleCommunication[MULTIUSE_STATE]++; @@ -1202,14 +1241,14 @@ static void CB2_PreInitMultiBattle(void) if (sub_800A520() && !gPaletteFade.active) { gBattleCommunication[MULTIUSE_STATE]++; - if (gLinkVSyncDisabled) + if (gWirelessCommType) sub_800ADF8(); else sub_800AC34(); } break; case 3: - if (gLinkVSyncDisabled) + if (gWirelessCommType) { if (sub_8010500()) { @@ -1247,7 +1286,7 @@ static void CB2_PreInitIngamePlayerPartnerBattle(void) switch (gBattleCommunication[MULTIUSE_STATE]) { case 0: - gUnknown_02023058 = Alloc(sizeof(struct UnknownPokemonStruct2) * 3); + gUnknown_02023058 = Alloc(sizeof(struct UnknownPokemonStruct4) * 3); sub_80379F8(3); gBattleCommunication[MULTIUSE_STATE]++; *savedCallback = gMain.savedCallback; @@ -1294,7 +1333,7 @@ static void CB2_HandleStartMultiBattle(void) sub_805EF14(); gBattleCommunication[MULTIUSE_STATE] = 1; } - if (gLinkVSyncDisabled) + if (gWirelessCommType) sub_800E0E8(); break; case 1: @@ -1312,8 +1351,8 @@ static void CB2_HandleStartMultiBattle(void) SendBlock(bitmask_all_link_players_but_self(), &gBattleStruct->field_180, 32); gBattleCommunication[MULTIUSE_STATE]++; } - if (gLinkVSyncDisabled) - sub_800DFB4(0, 0); + if (gWirelessCommType) + CreateWirelessStatusIndicatorSprite(0, 0); } } else @@ -1330,7 +1369,7 @@ static void CB2_HandleStartMultiBattle(void) ResetBlockReceivedFlags(); sub_8036EB8(4, playerMultiplayerId); SetAllPlayersBerryData(); - sub_8068AA4(); + SetDeoxysStats(); var = CreateTask(sub_8035D74, 0); gTasks[var].data[1] = 0x10E; gTasks[var].data[2] = 0x5A; @@ -1698,7 +1737,7 @@ static u8 CreateNPCTrainerParty(struct Pokemon *party, u16 trainerNum, bool8 fir else personalityValue = 0x88; - for (j = 0; gTrainers[trainerNum].trainerName[j] != 0xFF; j++) + for (j = 0; gTrainers[trainerNum].trainerName[j] != EOS; j++) nameHash += gTrainers[trainerNum].trainerName[j]; switch (gTrainers[trainerNum].partyFlags) @@ -2097,12 +2136,12 @@ static void sub_8038F34(void) } break; case 8: - if (!gLinkVSyncDisabled) + if (!gWirelessCommType) sub_800AC34(); gBattleCommunication[MULTIUSE_STATE]++; break; case 9: - if (!gMain.field_439_x4 || gLinkVSyncDisabled || gReceivedRemoteLinkPlayers != 1) + if (!gMain.field_439_x4 || gWirelessCommType || gReceivedRemoteLinkPlayers != 1) { gMain.field_439_x4 = 0; SetMainCallback2(gMain.savedCallback); @@ -2281,13 +2320,13 @@ static void sub_803939C(void) case 8: if (--gBattleCommunication[1] == 0) { - if (gMain.field_439_x4 && !gLinkVSyncDisabled) + if (gMain.field_439_x4 && !gWirelessCommType) sub_800AC34(); gBattleCommunication[MULTIUSE_STATE]++; } break; case 9: - if (!gMain.field_439_x4 || gLinkVSyncDisabled || gReceivedRemoteLinkPlayers != 1) + if (!gMain.field_439_x4 || gWirelessCommType || gReceivedRemoteLinkPlayers != 1) { gMain.field_439_x4 = 0; if (!gPaletteFade.active) @@ -2383,7 +2422,7 @@ void oac_poke_opponent(struct Sprite *sprite) static void sub_803980C(struct Sprite *sprite) { - if ((gUnknown_020243FC & 1) == 0) + if ((gIntroSlideFlags & 1) == 0) { sprite->pos2.x += 2; if (sprite->pos2.x == 0) @@ -2437,7 +2476,7 @@ static void sub_80398D0(struct Sprite *sprite) { sprite->invisible = FALSE; sprite->callback = SpriteCallbackDummy_2; - gUnknown_02022F88 = 0; + sUnusedUnknownArray[0] = 0; } } } @@ -2560,7 +2599,7 @@ void sub_8039BB4(struct Sprite *sprite) static void oac_poke_ally_(struct Sprite *sprite) { - if ((gUnknown_020243FC & 1) == 0) + if ((gIntroSlideFlags & 1) == 0) { sprite->pos2.x -= 2; if (sprite->pos2.x == 0) @@ -2582,7 +2621,7 @@ static void SpriteCallbackDummy_3(struct Sprite *sprite) void sub_8039C00(struct Sprite *sprite) { - if (!(gUnknown_020243FC & 1)) + if (!(gIntroSlideFlags & 1)) { sprite->pos2.x += sprite->data[1]; sprite->pos2.y += sprite->data[2]; @@ -2731,7 +2770,7 @@ static void BattleStartClearSetData(void) dataPtr[j] = 0; gDisableStructs[i].isFirstTurn = 2; - gUnknown_02024284[i] = 0; + sUnusedBattlersArray[i] = 0; gLastMoves[i] = 0; gLastLandedMoves[i] = 0; gLastHitByType[i] = 0; @@ -2784,7 +2823,7 @@ static void BattleStartClearSetData(void) gPauseCounterBattle = 0; gBattleMoveDamage = 0; - gUnknown_020243FC = 0; + gIntroSlideFlags = 0; gBattleScripting.animTurn = 0; gBattleScripting.animTargetsHit = 0; gLeveledUpInBattle = 0; @@ -3350,7 +3389,7 @@ static void BattleIntroOpponent1SendsOutMonAnimation(void) } #else -__attribute__((naked)) +ASM_DIRECT static void BattleIntroOpponent1SendsOutMonAnimation(void) { asm(".syntax unified\n\ @@ -3656,12 +3695,12 @@ static void TryDoEventsBeforeFirstTurn(void) gBattleMons[i].status2 &= ~(STATUS2_FLINCHED); *(&gBattleStruct->turnEffectsTracker) = 0; - *(&gBattleStruct->turnEffectsBank) = 0; + *(&gBattleStruct->turnEffectsBattlerId) = 0; *(&gBattleStruct->wishPerishSongState) = 0; - *(&gBattleStruct->wishPerishSongBank) = 0; + *(&gBattleStruct->wishPerishSongBattlerId) = 0; gBattleScripting.atk49_state = 0; gBattleStruct->faintedActionsState = 0; - gBattleStruct->turncountersTracker = 0; + gBattleStruct->turnCountersTracker = 0; gMoveResultFlags = 0; gRandomTurnNumber = Random(); @@ -3689,10 +3728,10 @@ static void HandleEndTurn_ContinueBattle(void) CancelMultiTurnMoves(i); } gBattleStruct->turnEffectsTracker = 0; - gBattleStruct->turnEffectsBank = 0; + gBattleStruct->turnEffectsBattlerId = 0; gBattleStruct->wishPerishSongState = 0; - gBattleStruct->wishPerishSongBank = 0; - gBattleStruct->turncountersTracker = 0; + gBattleStruct->wishPerishSongBattlerId = 0; + gBattleStruct->turnCountersTracker = 0; gMoveResultFlags = 0; } } @@ -3773,7 +3812,7 @@ u8 IsRunningFromBattleImpossible(void) else holdEffect = ItemId_GetHoldEffect(gBattleMons[gActiveBattler].item); - gStringBattler = gActiveBattler; + gPotentialItemEffectBattler = gActiveBattler; if (holdEffect == HOLD_EFFECT_CAN_ALWAYS_RUN) return 0; @@ -3884,7 +3923,7 @@ static void HandleTurnActionSelectionState(void) switch (gBattleCommunication[gActiveBattler]) { case STATE_TURN_START_RECORD: // recorded battle related on start of every turn - RecordedBattle_CopyBankMoves(); + RecordedBattle_CopyBattlerMoves(); gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN; break; case STATE_BEFORE_ACTION_CHOSEN: // choose an action @@ -4288,7 +4327,7 @@ static void HandleTurnActionSelectionState(void) if (gBattleCommunication[ACTIONS_CONFIRMED_COUNT] == gBattlersCount) { sub_818603C(1); - gBattleMainFunc = SetActionsAndBanksTurnOrder; + gBattleMainFunc = SetActionsAndBattlersTurnOrder; if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) { @@ -4345,162 +4384,162 @@ void SwapTurnOrder(u8 id1, u8 id2) gBattleTurnOrder[id2] = temp; } -u8 GetWhoStrikesFirst(u8 bank1, u8 bank2, bool8 ignoreChosenMoves) +u8 GetWhoStrikesFirst(u8 battler1, u8 battler2, bool8 ignoreChosenMoves) { u8 strikesFirst = 0; - u8 speedMultiplierBank1 = 0, speedMultiplierBank2 = 0; - u32 speedBank1 = 0, speedBank2 = 0; + u8 speedMultiplierBattler1 = 0, speedMultiplierBattler2 = 0; + u32 speedBattler1 = 0, speedBattler2 = 0; u8 holdEffect = 0; u8 holdEffectParam = 0; - u16 moveBank1 = 0, moveBank2 = 0; + u16 moveBattler1 = 0, moveBattler2 = 0; if (WEATHER_HAS_EFFECT) { - if ((gBattleMons[bank1].ability == ABILITY_SWIFT_SWIM && gBattleWeather & WEATHER_RAIN_ANY) - || (gBattleMons[bank1].ability == ABILITY_CHLOROPHYLL && gBattleWeather & WEATHER_SUN_ANY)) - speedMultiplierBank1 = 2; + if ((gBattleMons[battler1].ability == ABILITY_SWIFT_SWIM && gBattleWeather & WEATHER_RAIN_ANY) + || (gBattleMons[battler1].ability == ABILITY_CHLOROPHYLL && gBattleWeather & WEATHER_SUN_ANY)) + speedMultiplierBattler1 = 2; else - speedMultiplierBank1 = 1; + speedMultiplierBattler1 = 1; - if ((gBattleMons[bank2].ability == ABILITY_SWIFT_SWIM && gBattleWeather & WEATHER_RAIN_ANY) - || (gBattleMons[bank2].ability == ABILITY_CHLOROPHYLL && gBattleWeather & WEATHER_SUN_ANY)) - speedMultiplierBank2 = 2; + if ((gBattleMons[battler2].ability == ABILITY_SWIFT_SWIM && gBattleWeather & WEATHER_RAIN_ANY) + || (gBattleMons[battler2].ability == ABILITY_CHLOROPHYLL && gBattleWeather & WEATHER_SUN_ANY)) + speedMultiplierBattler2 = 2; else - speedMultiplierBank2 = 1; + speedMultiplierBattler2 = 1; } else { - speedMultiplierBank1 = 1; - speedMultiplierBank2 = 1; + speedMultiplierBattler1 = 1; + speedMultiplierBattler2 = 1; } - speedBank1 = (gBattleMons[bank1].speed * speedMultiplierBank1) - * (gStatStageRatios[gBattleMons[bank1].statStages[STAT_STAGE_SPEED]][0]) - / (gStatStageRatios[gBattleMons[bank1].statStages[STAT_STAGE_SPEED]][1]); + speedBattler1 = (gBattleMons[battler1].speed * speedMultiplierBattler1) + * (gStatStageRatios[gBattleMons[battler1].statStages[STAT_SPEED]][0]) + / (gStatStageRatios[gBattleMons[battler1].statStages[STAT_SPEED]][1]); - if (gBattleMons[bank1].item == ITEM_ENIGMA_BERRY) + if (gBattleMons[battler1].item == ITEM_ENIGMA_BERRY) { - holdEffect = gEnigmaBerries[bank1].holdEffect; - holdEffectParam = gEnigmaBerries[bank1].holdEffectParam; + holdEffect = gEnigmaBerries[battler1].holdEffect; + holdEffectParam = gEnigmaBerries[battler1].holdEffectParam; } else { - holdEffect = ItemId_GetHoldEffect(gBattleMons[bank1].item); - holdEffectParam = ItemId_GetHoldEffectParam(gBattleMons[bank1].item); + holdEffect = ItemId_GetHoldEffect(gBattleMons[battler1].item); + holdEffectParam = ItemId_GetHoldEffectParam(gBattleMons[battler1].item); } // badge boost if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000 | BATTLE_TYPE_FRONTIER)) && FlagGet(FLAG_BADGE03_GET) - && GetBattlerSide(bank1) == B_SIDE_PLAYER) + && GetBattlerSide(battler1) == B_SIDE_PLAYER) { - speedBank1 = (speedBank1 * 110) / 100; + speedBattler1 = (speedBattler1 * 110) / 100; } if (holdEffect == HOLD_EFFECT_MACHO_BRACE) - speedBank1 /= 2; + speedBattler1 /= 2; - if (gBattleMons[bank1].status1 & STATUS1_PARALYSIS) - speedBank1 /= 4; + if (gBattleMons[battler1].status1 & STATUS1_PARALYSIS) + speedBattler1 /= 4; if (holdEffect == HOLD_EFFECT_QUICK_CLAW && gRandomTurnNumber < (0xFFFF * holdEffectParam) / 100) - speedBank1 = UINT_MAX; + speedBattler1 = UINT_MAX; - // check second bank's speed + // check second battlerId's speed - speedBank2 = (gBattleMons[bank2].speed * speedMultiplierBank2) - * (gStatStageRatios[gBattleMons[bank2].statStages[STAT_STAGE_SPEED]][0]) - / (gStatStageRatios[gBattleMons[bank2].statStages[STAT_STAGE_SPEED]][1]); + speedBattler2 = (gBattleMons[battler2].speed * speedMultiplierBattler2) + * (gStatStageRatios[gBattleMons[battler2].statStages[STAT_SPEED]][0]) + / (gStatStageRatios[gBattleMons[battler2].statStages[STAT_SPEED]][1]); - if (gBattleMons[bank2].item == ITEM_ENIGMA_BERRY) + if (gBattleMons[battler2].item == ITEM_ENIGMA_BERRY) { - holdEffect = gEnigmaBerries[bank2].holdEffect; - holdEffectParam = gEnigmaBerries[bank2].holdEffectParam; + holdEffect = gEnigmaBerries[battler2].holdEffect; + holdEffectParam = gEnigmaBerries[battler2].holdEffectParam; } else { - holdEffect = ItemId_GetHoldEffect(gBattleMons[bank2].item); - holdEffectParam = ItemId_GetHoldEffectParam(gBattleMons[bank2].item); + holdEffect = ItemId_GetHoldEffect(gBattleMons[battler2].item); + holdEffectParam = ItemId_GetHoldEffectParam(gBattleMons[battler2].item); } // badge boost if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000 | BATTLE_TYPE_FRONTIER)) && FlagGet(FLAG_BADGE03_GET) - && GetBattlerSide(bank2) == B_SIDE_PLAYER) + && GetBattlerSide(battler2) == B_SIDE_PLAYER) { - speedBank2 = (speedBank2 * 110) / 100; + speedBattler2 = (speedBattler2 * 110) / 100; } if (holdEffect == HOLD_EFFECT_MACHO_BRACE) - speedBank2 /= 2; + speedBattler2 /= 2; - if (gBattleMons[bank2].status1 & STATUS1_PARALYSIS) - speedBank2 /= 4; + if (gBattleMons[battler2].status1 & STATUS1_PARALYSIS) + speedBattler2 /= 4; if (holdEffect == HOLD_EFFECT_QUICK_CLAW && gRandomTurnNumber < (0xFFFF * holdEffectParam) / 100) - speedBank2 = UINT_MAX; + speedBattler2 = UINT_MAX; if (ignoreChosenMoves) { - moveBank1 = MOVE_NONE; - moveBank2 = MOVE_NONE; + moveBattler1 = MOVE_NONE; + moveBattler2 = MOVE_NONE; } else { - if (gChosenActionByBattler[bank1] == B_ACTION_USE_MOVE) + if (gChosenActionByBattler[battler1] == B_ACTION_USE_MOVE) { - if (gProtectStructs[bank1].onlyStruggle) - moveBank1 = MOVE_STRUGGLE; + if (gProtectStructs[battler1].onlyStruggle) + moveBattler1 = MOVE_STRUGGLE; else - moveBank1 = gBattleMons[bank1].moves[*(gBattleStruct->chosenMovePositions + bank1)]; + moveBattler1 = gBattleMons[battler1].moves[*(gBattleStruct->chosenMovePositions + battler1)]; } else - moveBank1 = MOVE_NONE; + moveBattler1 = MOVE_NONE; - if (gChosenActionByBattler[bank2] == B_ACTION_USE_MOVE) + if (gChosenActionByBattler[battler2] == B_ACTION_USE_MOVE) { - if (gProtectStructs[bank2].onlyStruggle) - moveBank2 = MOVE_STRUGGLE; + if (gProtectStructs[battler2].onlyStruggle) + moveBattler2 = MOVE_STRUGGLE; else - moveBank2 = gBattleMons[bank2].moves[*(gBattleStruct->chosenMovePositions + bank2)]; + moveBattler2 = gBattleMons[battler2].moves[*(gBattleStruct->chosenMovePositions + battler2)]; } else - moveBank2 = MOVE_NONE; + moveBattler2 = MOVE_NONE; } // both move priorities are different than 0 - if (gBattleMoves[moveBank1].priority != 0 || gBattleMoves[moveBank2].priority != 0) + if (gBattleMoves[moveBattler1].priority != 0 || gBattleMoves[moveBattler2].priority != 0) { // both priorities are the same - if (gBattleMoves[moveBank1].priority == gBattleMoves[moveBank2].priority) + if (gBattleMoves[moveBattler1].priority == gBattleMoves[moveBattler2].priority) { - if (speedBank1 == speedBank2 && Random() & 1) + if (speedBattler1 == speedBattler2 && Random() & 1) strikesFirst = 2; // same speeds, same priorities - else if (speedBank1 < speedBank2) - strikesFirst = 1; // bank2 has more speed + else if (speedBattler1 < speedBattler2) + strikesFirst = 1; // battler2 has more speed - // else bank1 has more speed + // else battler1 has more speed } - else if (gBattleMoves[moveBank1].priority < gBattleMoves[moveBank2].priority) - strikesFirst = 1; // bank2's move has greater priority + else if (gBattleMoves[moveBattler1].priority < gBattleMoves[moveBattler2].priority) + strikesFirst = 1; // battler2's move has greater priority - // else bank1's move has greater priority + // else battler1's move has greater priority } // both priorities are equal to 0 else { - if (speedBank1 == speedBank2 && Random() & 1) + if (speedBattler1 == speedBattler2 && Random() & 1) strikesFirst = 2; // same speeds, same priorities - else if (speedBank1 < speedBank2) - strikesFirst = 1; // bank2 has more speed + else if (speedBattler1 < speedBattler2) + strikesFirst = 1; // battler2 has more speed - // else bank1 has more speed + // else battler1 has more speed } return strikesFirst; } -static void SetActionsAndBanksTurnOrder(void) +static void SetActionsAndBattlersTurnOrder(void) { s32 var = 0; s32 i, j; @@ -4556,7 +4595,7 @@ static void SetActionsAndBanksTurnOrder(void) } } gBattleMainFunc = CheckFocusPunch_ClearVarsBeforeTurnStarts; - gBattleStruct->focusPunchBank = 0; + gBattleStruct->focusPunchBattlerId = 0; return; } else @@ -4583,14 +4622,14 @@ static void SetActionsAndBanksTurnOrder(void) { for (j = i + 1; j < gBattlersCount; j++) { - u8 bank1 = gBattleTurnOrder[i]; - u8 bank2 = gBattleTurnOrder[j]; + u8 battler1 = gBattleTurnOrder[i]; + u8 battler2 = gBattleTurnOrder[j]; if (gActionsByTurnOrder[i] != B_ACTION_USE_ITEM && gActionsByTurnOrder[j] != B_ACTION_USE_ITEM && gActionsByTurnOrder[i] != B_ACTION_SWITCH && gActionsByTurnOrder[j] != B_ACTION_SWITCH) { - if (GetWhoStrikesFirst(bank1, bank2, FALSE)) + if (GetWhoStrikesFirst(battler1, battler2, FALSE)) SwapTurnOrder(i, j); } } @@ -4598,7 +4637,7 @@ static void SetActionsAndBanksTurnOrder(void) } } gBattleMainFunc = CheckFocusPunch_ClearVarsBeforeTurnStarts; - gBattleStruct->focusPunchBank = 0; + gBattleStruct->focusPunchBattlerId = 0; } static void TurnValuesCleanUp(bool8 var0) @@ -4654,10 +4693,10 @@ static void CheckFocusPunch_ClearVarsBeforeTurnStarts(void) { if (!(gHitMarker & HITMARKER_RUN)) { - while (gBattleStruct->focusPunchBank < gBattlersCount) + while (gBattleStruct->focusPunchBattlerId < gBattlersCount) { - gActiveBattler = gBattlerAttacker = gBattleStruct->focusPunchBank; - gBattleStruct->focusPunchBank++; + gActiveBattler = gBattlerAttacker = gBattleStruct->focusPunchBattlerId; + gBattleStruct->focusPunchBattlerId++; if (gChosenMoveByBattler[gActiveBattler] == MOVE_FOCUS_PUNCH && !(gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP) && !(gDisableStructs[gBattlerAttacker].truantCounter) @@ -4700,7 +4739,7 @@ static void RunTurnActionsFunctions(void) } else { - if (gBattleStruct->savedTurnActionNumber != gCurrentTurnActionNumber) // action turn has been done, clear hitmarker bits for another bank + if (gBattleStruct->savedTurnActionNumber != gCurrentTurnActionNumber) // action turn has been done, clear hitmarker bits for another battlerId { gHitMarker &= ~(HITMARKER_NO_ATTACKSTRING); gHitMarker &= ~(HITMARKER_UNABLE_TO_USE_MOVE); @@ -4934,7 +4973,7 @@ static void TryEvolvePokemon(void) while (gLeveledUpInBattle != 0) { - for (i = 0; i < 6; i++) + for (i = 0; i < PARTY_SIZE; i++) { if (gLeveledUpInBattle & gBitTable[i]) { @@ -4983,7 +5022,7 @@ static void ReturnFromBattleToOverworld(void) if (gBattleTypeFlags & BATTLE_TYPE_ROAMER) { UpdateRoamerHPStatus(&gEnemyParty[0]); - if ((gBattleOutcome & B_OUTCOME_WON) || gBattleOutcome == B_OUTCOME_CAUGHT_POKE) + if ((gBattleOutcome & B_OUTCOME_WON) || gBattleOutcome == B_OUTCOME_CAUGHT) SetRoamerInactive(); } @@ -5031,7 +5070,7 @@ static void HandleAction_UseMove(void) gMoveResultFlags = 0; gMultiHitCounter = 0; gBattleCommunication[6] = 0; - gCurrMovePos = gUnknown_020241E9 = *(gBattleStruct->chosenMovePositions + gBattlerAttacker); + gCurrMovePos = gChosenMovePos = *(gBattleStruct->chosenMovePositions + gBattlerAttacker); // choose move if (gProtectStructs[gBattlerAttacker].onlyStruggle) @@ -5050,14 +5089,14 @@ static void HandleAction_UseMove(void) && gDisableStructs[gBattlerAttacker].encoredMove == gBattleMons[gBattlerAttacker].moves[gDisableStructs[gBattlerAttacker].encoredMovePos]) { gCurrentMove = gChosenMove = gDisableStructs[gBattlerAttacker].encoredMove; - gCurrMovePos = gUnknown_020241E9 = gDisableStructs[gBattlerAttacker].encoredMovePos; + gCurrMovePos = gChosenMovePos = gDisableStructs[gBattlerAttacker].encoredMovePos; *(gBattleStruct->moveTarget + gBattlerAttacker) = GetMoveTarget(gCurrentMove, 0); } // check if the encored move wasn't overwritten else if (gDisableStructs[gBattlerAttacker].encoredMove != MOVE_NONE && gDisableStructs[gBattlerAttacker].encoredMove != gBattleMons[gBattlerAttacker].moves[gDisableStructs[gBattlerAttacker].encoredMovePos]) { - gCurrMovePos = gUnknown_020241E9 = gDisableStructs[gBattlerAttacker].encoredMovePos; + gCurrMovePos = gChosenMovePos = gDisableStructs[gBattlerAttacker].encoredMovePos; gCurrentMove = gChosenMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos]; gDisableStructs[gBattlerAttacker].encoredMove = MOVE_NONE; gDisableStructs[gBattlerAttacker].encoredMovePos = 0; @@ -5338,7 +5377,7 @@ bool8 TryRunFromBattle(u8 battler) else holdEffect = ItemId_GetHoldEffect(gBattleMons[battler].item); - gStringBattler = battler; + gPotentialItemEffectBattler = battler; if (holdEffect == HOLD_EFFECT_CAN_ALWAYS_RUN) { @@ -5454,7 +5493,7 @@ static void HandleAction_Run(void) else { gCurrentTurnActionNumber = gBattlersCount; - gBattleOutcome = B_OUTCOME_POKE_FLED; + gBattleOutcome = B_OUTCOME_MON_FLED; } } } diff --git a/src/battle_message.c b/src/battle_message.c index 181ad9d9e..9a4a062ad 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -1,7 +1,7 @@ #include "global.h" #include "battle.h" #include "battle_message.h" -#include "battle_string_ids.h" +#include "constants/battle_string_ids.h" #include "constants/moves.h" #include "text.h" #include "string_util.h" @@ -13,23 +13,11 @@ #include "palette.h" #include "battle_controllers.h" #include "battle_setup.h" +#include "menu.h" +#include "recorded_battle.h" +#include "international_string_util.h" -extern u16 gLastUsedItem; -extern u8 gLastUsedAbility; -extern u8 gActiveBattler; -extern u8 gBattlerAttacker; -extern u8 gBattlerTarget; -extern u8 gStringBattler; -extern u8 gEffectBank; extern u8 gBattlerAbilities[MAX_BATTLERS_COUNT]; -extern u32 gBattleTypeFlags; -extern u16 gTrainerBattleOpponent_A; -extern u16 gTrainerBattleOpponent_B; -extern u16 gPartnerTrainerId; -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; -extern struct BattleEnigmaBerry gEnigmaBerries[MAX_BATTLERS_COUNT]; -extern u8 gBattleBufferA[MAX_BATTLERS_COUNT][0x200]; -extern u8 gMoveSelectionCursor[MAX_BATTLERS_COUNT]; extern u8 gUnknown_0203C7B4; extern struct StringInfoBattle *gStringInfo; @@ -56,9 +44,6 @@ extern void GetEreaderTrainerName(u8 *txtPtr); extern void sub_81A36D0(u8 arg0, u16 trainerId); // battle_frontier_2 extern void sub_81D572C(u8 arg0, u16 trainerId); // pokenav extern void GetFrontierTrainerName(u8 *dst, u16 trainerId); -extern s32 GetStringCenterAlignXOffsetWithLetterSpacing(u8 fontId, const u8 *str, s32 totalWidth, s16 letterSpacing); -extern u8 GetTextSpeedInRecordedBattle(void); -extern u8 GetPlayerTextSpeed(void); // this file's functions static void sub_814F8F8(u8 *textPtr); @@ -1436,7 +1421,7 @@ void BufferStringBattle(u16 stringID) gBattleScripting.battler = gStringInfo->scrActive; *(&gBattleStruct->field_52) = gStringInfo->unk1605E; *(&gBattleStruct->hpScale) = gStringInfo->hpScale; - gStringBattler = gStringInfo->StringBank; + gPotentialItemEffectBattler = gStringInfo->StringBank; *(&gBattleStruct->stringMoveType) = gStringInfo->moveType; for (i = 0; i < MAX_BATTLERS_COUNT; i++) @@ -1903,7 +1888,7 @@ u32 BattleStringExpandPlaceholders(const u8* src, u8* dst) HANDLE_NICKNAME_STRING_CASE(gBattlerTarget, gBattlerPartyIndexes[gBattlerTarget]) break; case B_TXT_EFF_NAME_WITH_PREFIX: // effect bank name with prefix - HANDLE_NICKNAME_STRING_CASE(gEffectBank, gBattlerPartyIndexes[gEffectBank]) + HANDLE_NICKNAME_STRING_CASE(gEffectBattler, gBattlerPartyIndexes[gEffectBattler]) break; case B_TXT_ACTIVE_NAME_WITH_PREFIX: // active bank name with prefix HANDLE_NICKNAME_STRING_CASE(gActiveBattler, gBattlerPartyIndexes[gActiveBattler]) @@ -1930,10 +1915,10 @@ u32 BattleStringExpandPlaceholders(const u8* src, u8* dst) { if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI)) { - if ((gBattleScripting.multiplayerId != 0 && (gStringBattler & BIT_SIDE)) - || (gBattleScripting.multiplayerId == 0 && !(gStringBattler & BIT_SIDE))) + if ((gBattleScripting.multiplayerId != 0 && (gPotentialItemEffectBattler & BIT_SIDE)) + || (gBattleScripting.multiplayerId == 0 && !(gPotentialItemEffectBattler & BIT_SIDE))) { - StringCopy(text, gEnigmaBerries[gStringBattler].name); + StringCopy(text, gEnigmaBerries[gPotentialItemEffectBattler].name); StringAppend(text, gText_BerrySuffix); toCpy = text; } @@ -1944,9 +1929,9 @@ u32 BattleStringExpandPlaceholders(const u8* src, u8* dst) } else { - if (gLinkPlayers[gBattleScripting.multiplayerId].lp_field_18 == gStringBattler) + if (gLinkPlayers[gBattleScripting.multiplayerId].lp_field_18 == gPotentialItemEffectBattler) { - StringCopy(text, gEnigmaBerries[gStringBattler].name); + StringCopy(text, gEnigmaBerries[gPotentialItemEffectBattler].name); StringAppend(text, gText_BerrySuffix); toCpy = text; } @@ -1979,11 +1964,11 @@ u32 BattleStringExpandPlaceholders(const u8* src, u8* dst) toCpy = gAbilityNames[gBattlerAbilities[gBattleScripting.battler]]; break; case B_TXT_EFF_ABILITY: // effect bank ability - toCpy = gAbilityNames[gBattlerAbilities[gEffectBank]]; + toCpy = gAbilityNames[gBattlerAbilities[gEffectBattler]]; break; case B_TXT_TRAINER1_CLASS: // trainer class name if (gBattleTypeFlags & BATTLE_TYPE_SECRET_BASE) - toCpy = gTrainerClassNames[GetSecretBaseTrainerNameIndex()]; + toCpy = gTrainerClassNames[GetSecretBaseTrainerClass()]; else if (gTrainerBattleOpponent_A == TRAINER_OPPONENT_C00) toCpy = gTrainerClassNames[sub_8068BB0()]; else if (gTrainerBattleOpponent_A == TRAINER_OPPONENT_3FE) @@ -2313,9 +2298,9 @@ static void ExpandBattleTextBuffPlaceholders(const u8 *src, u8 *dst) { if (hword == ITEM_ENIGMA_BERRY) { - if (gLinkPlayers[gBattleScripting.multiplayerId].lp_field_18 == gStringBattler) + if (gLinkPlayers[gBattleScripting.multiplayerId].lp_field_18 == gPotentialItemEffectBattler) { - StringCopy(dst, gEnigmaBerries[gStringBattler].name); + StringCopy(dst, gEnigmaBerries[gPotentialItemEffectBattler].name); StringAppend(dst, gText_BerrySuffix); } else @@ -2360,20 +2345,20 @@ static void sub_814F8F8(u8* textBuff) // Appends "!" to the text buffer `dst`. In the original Japanese this looked // into the table of moves at sUnknownMoveTable and varied the line accordingly. -// +// // gText_ExclamationMark was a plain "!", used for any attack not on the list. // It resulted in the translation "<NAME>'s <ATTACK>!". -// +// // gText_ExclamationMark2 was "を つかった!". This resulted in the translation // "<NAME> used <ATTACK>!", which was used for all attacks in English. -// +// // gText_ExclamationMark3 was "した!". This was used for those moves whose // names were verbs, such as Recover, and resulted in translations like "<NAME> // recovered itself!". -// +// // gText_ExclamationMark4 was "を した!" This resulted in a translation of // "<NAME> did an <ATTACK>!". -// +// // gText_ExclamationMark5 was " こうげき!" This resulted in a translation of // "<NAME>'s <ATTACK> attack!". static void sub_814F950(u8* dst) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index fab1c18bb..75f05e86f 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1,6 +1,7 @@ #include "global.h" #include "battle.h" #include "constants/battle_move_effects.h" +#include "constants/battle_script_commands.h" #include "battle_message.h" #include "battle_ai_script_commands.h" #include "battle_scripts.h" @@ -11,7 +12,6 @@ #include "constants/hold_effects.h" #include "util.h" #include "pokemon.h" -#include "calculate_base_damage.h" #include "random.h" #include "battle_controllers.h" #include "battle_interface.h" @@ -31,75 +31,16 @@ #include "bg.h" #include "string_util.h" #include "pokemon_icon.h" -#include "pokemon_item_effects.h" #include "m4a.h" #include "mail.h" #include "event_data.h" #include "pokemon_storage_system.h" #include "task.h" #include "naming_screen.h" -#include "battle_string_ids.h" - -// variables - -extern u8 gCritMultiplier; -extern s32 gBattleMoveDamage; -extern struct BattleEnigmaBerry gEnigmaBerries[MAX_BATTLERS_COUNT]; -extern struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT]; -extern u8 gActiveBattler; -extern u32 gBattleControllerExecFlags; -extern u8 gBattlersCount; -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; -extern u8 gBattleTurnOrder[MAX_BATTLERS_COUNT]; -extern u8 gActionsByTurnOrder[MAX_BATTLERS_COUNT]; -extern u16 gCurrentMove; -extern u8 gLastUsedAbility; -extern u8 gStringBattler; -extern u8 gEffectBank; -extern u8 gAbsentBattlerFlags; -extern u8 gMultiHitCounter; -extern u16 gChosenMoveByBattler[MAX_BATTLERS_COUNT]; -extern u16 gPauseCounterBattle; -extern u16 gPaydayMoney; -extern u16 gRandomTurnNumber; -extern u8 gBattlerAttacker; -extern u8 gBattlerTarget; -extern const u8* gBattlescriptCurrInstr; -extern u8 gCurrMovePos; -extern u8 gCurrentActionFuncId; -extern u8 gMoveResultFlags; -extern u8 gBattleCommunication[]; -extern u16 gLastLandedMoves[4]; -extern u16 gLastHitByType[4]; -extern u16 gLastResultingMoves[4]; -extern u8 gLastHitBy[4]; -extern u8 gStringBattler; -extern u16 gDynamicBasePower; -extern u16 gLastUsedItem; -extern u16 gBattleMovePower; -extern s32 gHpDealt; -extern s32 gTakenDmg[MAX_BATTLERS_COUNT]; -extern u8 gTakenDmgBanks[MAX_BATTLERS_COUNT]; -extern u8 gSentPokesToOpponent[2]; -extern u8 gBank1; -extern u16 gExpShareExp; -extern u8 gLeveledUpInBattle; -extern void (*gBattleMainFunc)(void); -extern u8 gPlayerPartyCount; -extern u16 gMoveToLearn; -extern u16 gRandomMove; -extern u8 gBankInMenu; -extern u8 gChosenActionByBattler[MAX_BATTLERS_COUNT]; -extern u8 gCurrentTurnActionNumber; -extern u8 gBattleBufferB[MAX_BATTLERS_COUNT][0x200]; -extern u16 gLockedMoves[MAX_BATTLERS_COUNT]; -extern u16 gPartnerTrainerId; -extern u16 gChosenMove; -extern u16 gLastPrintedMoves[MAX_BATTLERS_COUNT]; -extern u16 gLastMoves[MAX_BATTLERS_COUNT]; -extern u16 gTrainerBattleOpponent_A; -extern u16 gTrainerBattleOpponent_B; -extern u8 gUnknown_020241E9; +#include "constants/battle_string_ids.h" +#include "battle_setup.h" +#include "overworld.h" + extern u16 gBattle_BG1_X; extern u16 gBattle_BG1_Y; extern u16 gBattle_BG2_X; @@ -114,17 +55,15 @@ struct TrainerMoney }; extern const struct BattleMove gBattleMoves[]; -extern const struct BaseStats gBaseStats[]; extern const u8 gTypeEffectiveness[336]; extern const struct TrainerMoney gTrainerMoneyTable[]; extern const u8* const gBattleScriptsForMoveEffects[]; // functions -extern void sub_81A5718(u8 bank); // battle frontier 2 +extern void sub_81A5718(u8 battlerId); // battle frontier 2 extern void sub_81A56B4(void); // battle frontier 2 extern void sub_81BFA38(struct Pokemon* party, u8 monPartyId, u8 monCount, void (*callback)(void), u16 move); // pokemon summary screen extern u8 sub_81C1B94(void); // pokemon summary screen -extern void IncrementGameStat(u8 statId); // rom_4 extern void sub_81D388C(struct Pokemon* mon, void* statStoreLocation); // pokenav.s extern void sub_81D3640(u8 arg0, void* statStoreLocation1, void* statStoreLocation2, u8 arg3, u8 arg4, u8 arg5); // pokenav.s extern void sub_81D3784(u8 arg0, void* statStoreLocation1, u8 arg2, u8 arg3, u8 arg4); // pokenav.s @@ -132,7 +71,7 @@ extern u8* GetMonNickname(struct Pokemon* mon, u8* dst); // party_menu extern u8 sub_81A5258(u8* arg0); // battle frontier 2 extern void sub_81A5BF8(void); // battle frontier 2 extern void sub_81A5D44(void); // battle frontier 2 -extern void sub_81B8E80(u8 bank, u8, u8); // party menu +extern void sub_81B8E80(u8 battlerId, u8, u8); // party menu extern bool8 sub_81B1250(void); // ? extern bool8 InBattlePike(void); extern bool8 InBattlePyramid(void); @@ -140,7 +79,6 @@ extern u16 GetBattlePyramidPickupItemId(void); extern u8 sav1_map_get_light_level(void); extern u8 sub_813B21C(void); extern u16 get_unknown_box_id(void); -extern void sub_80356D0(void); // strings extern const u8 gText_BattleYesNoChoice[]; @@ -157,13 +95,13 @@ extern const u8 gText_BattleYesNoChoice[]; #define DEFENDER_IS_PROTECTED ((gProtectStructs[gBattlerTarget].protected) && (gBattleMoves[gCurrentMove].flags & FLAG_PROTECT_AFFECTED)) -#define TARGET_TURN_DAMAGED (gSpecialStatuses[gBattlerTarget].moveturnLostHP_physical != 0 \ - || gSpecialStatuses[gBattlerTarget].moveturnLostHP_special != 0) +#define TARGET_TURN_DAMAGED (gSpecialStatuses[gBattlerTarget].physicalDmg != 0 \ + || gSpecialStatuses[gBattlerTarget].specialDmg != 0) // this file's functions static bool8 IsTwoTurnsMove(u16 move); static void TrySetDestinyBondToHappen(void); -static u8 AttacksThisTurn(u8 bank, u16 move); // Note: returns 1 if it's a charging turn, otherwise 2. +static u8 AttacksThisTurn(u8 battlerId, u16 move); // Note: returns 1 if it's a charging turn, otherwise 2. static void CheckWonderGuardAndLevitate(void); static u8 ChangeStatBuffs(s8 statValue, u8 statId, u8, const u8* BS_ptr); static bool32 IsMonGettingExpSentOut(void); @@ -1217,7 +1155,7 @@ static void atk01_accuracycheck(void) } else { - u8 type, moveAcc, holdEffect, quality; + u8 type, moveAcc, holdEffect, param; s8 buff; u16 calc; @@ -1233,13 +1171,13 @@ static void atk01_accuracycheck(void) if (gBattleMons[gBattlerTarget].status2 & STATUS2_FORESIGHT) { - u8 acc = gBattleMons[gBattlerAttacker].statStages[STAT_STAGE_ACC]; + u8 acc = gBattleMons[gBattlerAttacker].statStages[STAT_ACC]; buff = acc; } else { - u8 acc = gBattleMons[gBattlerAttacker].statStages[STAT_STAGE_ACC]; - buff = acc + 6 - gBattleMons[gBattlerTarget].statStages[STAT_STAGE_EVASION]; + u8 acc = gBattleMons[gBattlerAttacker].statStages[STAT_ACC]; + buff = acc + 6 - gBattleMons[gBattlerTarget].statStages[STAT_EVASION]; } if (buff < 0) @@ -1265,18 +1203,18 @@ static void atk01_accuracycheck(void) if (gBattleMons[gBattlerTarget].item == ITEM_ENIGMA_BERRY) { holdEffect = gEnigmaBerries[gBattlerTarget].holdEffect; - quality = gEnigmaBerries[gBattlerTarget].holdEffectParam; + param = gEnigmaBerries[gBattlerTarget].holdEffectParam; } else { holdEffect = ItemId_GetHoldEffect(gBattleMons[gBattlerTarget].item); - quality = ItemId_GetHoldEffectParam(gBattleMons[gBattlerTarget].item); + param = ItemId_GetHoldEffectParam(gBattleMons[gBattlerTarget].item); } - gStringBattler = gBattlerTarget; + gPotentialItemEffectBattler = gBattlerTarget; if (holdEffect == HOLD_EFFECT_EVASION_UP) - calc = (calc * (100 - quality)) / 100; + calc = (calc * (100 - param)) / 100; // final calculation if ((Random() % 100 + 1) > calc) @@ -1366,7 +1304,7 @@ static void atk04_critcalc(void) else holdEffect = ItemId_GetHoldEffect(item); - gStringBattler = gBattlerAttacker; + gPotentialItemEffectBattler = gBattlerAttacker; critChance = 2 * ((gBattleMons[gBattlerAttacker].status2 & STATUS2_FOCUS_ENERGY) != 0) + (gBattleMoves[gCurrentMove].effect == EFFECT_HIGH_CRITICAL) @@ -1760,23 +1698,24 @@ static void Unused_ApplyRandomDmgMultiplier(void) static void atk07_adjustnormaldamage(void) { - u8 holdEffect, quality; + u8 holdEffect, param; ApplyRandomDmgMultiplier(); if (gBattleMons[gBattlerTarget].item == ITEM_ENIGMA_BERRY) { - holdEffect = gEnigmaBerries[gBattlerTarget].holdEffect, quality = gEnigmaBerries[gBattlerTarget].holdEffectParam; + holdEffect = gEnigmaBerries[gBattlerTarget].holdEffect; + param = gEnigmaBerries[gBattlerTarget].holdEffectParam; } else { holdEffect = ItemId_GetHoldEffect(gBattleMons[gBattlerTarget].item); - quality = ItemId_GetHoldEffectParam(gBattleMons[gBattlerTarget].item); + param = ItemId_GetHoldEffectParam(gBattleMons[gBattlerTarget].item); } - gStringBattler = gBattlerTarget; + gPotentialItemEffectBattler = gBattlerTarget; - if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < quality) + if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < param) { RecordItemEffectBattle(gBattlerTarget, holdEffect); gSpecialStatuses[gBattlerTarget].focusBanded = 1; @@ -1808,23 +1747,24 @@ static void atk07_adjustnormaldamage(void) static void atk08_adjustnormaldamage2(void) // The same as 0x7 except it doesn't check for false swipe move effect. { - u8 holdEffect, quality; + u8 holdEffect, param; ApplyRandomDmgMultiplier(); if (gBattleMons[gBattlerTarget].item == ITEM_ENIGMA_BERRY) { - holdEffect = gEnigmaBerries[gBattlerTarget].holdEffect, quality = gEnigmaBerries[gBattlerTarget].holdEffectParam; + holdEffect = gEnigmaBerries[gBattlerTarget].holdEffect; + param = gEnigmaBerries[gBattlerTarget].holdEffectParam; } else { holdEffect = ItemId_GetHoldEffect(gBattleMons[gBattlerTarget].item); - quality = ItemId_GetHoldEffectParam(gBattleMons[gBattlerTarget].item); + param = ItemId_GetHoldEffectParam(gBattleMons[gBattlerTarget].item); } - gStringBattler = gBattlerTarget; + gPotentialItemEffectBattler = gBattlerTarget; - if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < quality) + if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < param) { RecordItemEffectBattle(gBattlerTarget, holdEffect); gSpecialStatuses[gBattlerTarget].focusBanded = 1; @@ -1919,7 +1859,7 @@ static void atk0B_healthbarupdate(void) if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); if (gBattleMons[gActiveBattler].status2 & STATUS2_SUBSTITUTE && gDisableStructs[gActiveBattler].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE)) { @@ -1964,20 +1904,20 @@ static void atk0C_datahpupdate(void) if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); if (gBattleMons[gActiveBattler].status2 & STATUS2_SUBSTITUTE && gDisableStructs[gActiveBattler].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE)) { if (gDisableStructs[gActiveBattler].substituteHP >= gBattleMoveDamage) { - if (gSpecialStatuses[gActiveBattler].moveturnLostHP == 0) - gSpecialStatuses[gActiveBattler].moveturnLostHP = gBattleMoveDamage; + if (gSpecialStatuses[gActiveBattler].dmg == 0) + gSpecialStatuses[gActiveBattler].dmg = gBattleMoveDamage; gDisableStructs[gActiveBattler].substituteHP -= gBattleMoveDamage; gHpDealt = gBattleMoveDamage; } else { - if (gSpecialStatuses[gActiveBattler].moveturnLostHP == 0) - gSpecialStatuses[gActiveBattler].moveturnLostHP = gDisableStructs[gActiveBattler].substituteHP; + if (gSpecialStatuses[gActiveBattler].dmg == 0) + gSpecialStatuses[gActiveBattler].dmg = gDisableStructs[gActiveBattler].substituteHP; gHpDealt = gDisableStructs[gActiveBattler].substituteHP; gDisableStructs[gActiveBattler].substituteHP = 0; } @@ -2009,10 +1949,10 @@ static void atk0C_datahpupdate(void) else { gTakenDmg[gActiveBattler] += gBattleMoveDamage; - if (gBattlescriptCurrInstr[1] == BS_GET_TARGET) - gTakenDmgBanks[gActiveBattler] = gBattlerAttacker; + if (gBattlescriptCurrInstr[1] == BS_TARGET) + gTakenDmgByBattler[gActiveBattler] = gBattlerAttacker; else - gTakenDmgBanks[gActiveBattler] = gBattlerTarget; + gTakenDmgByBattler[gActiveBattler] = gBattlerTarget; } if (gBattleMons[gActiveBattler].hp > gBattleMoveDamage) @@ -2026,37 +1966,37 @@ static void atk0C_datahpupdate(void) gBattleMons[gActiveBattler].hp = 0; } - if (!gSpecialStatuses[gActiveBattler].moveturnLostHP && !(gHitMarker & HITMARKER_x100000)) - gSpecialStatuses[gActiveBattler].moveturnLostHP = gHpDealt; + if (!gSpecialStatuses[gActiveBattler].dmg && !(gHitMarker & HITMARKER_x100000)) + gSpecialStatuses[gActiveBattler].dmg = gHpDealt; - if (moveType <= 8 && !(gHitMarker & HITMARKER_x100000) && gCurrentMove != MOVE_PAIN_SPLIT) + if (IS_MOVE_PHYSICAL(moveType) && !(gHitMarker & HITMARKER_x100000) && gCurrentMove != MOVE_PAIN_SPLIT) { gProtectStructs[gActiveBattler].physicalDmg = gHpDealt; - gSpecialStatuses[gActiveBattler].moveturnLostHP_physical = gHpDealt; - if (gBattlescriptCurrInstr[1] == BS_GET_TARGET) + gSpecialStatuses[gActiveBattler].physicalDmg = gHpDealt; + if (gBattlescriptCurrInstr[1] == BS_TARGET) { - gProtectStructs[gActiveBattler].physicalBank = gBattlerAttacker; - gSpecialStatuses[gActiveBattler].moveturnPhysicalBank = gBattlerAttacker; + gProtectStructs[gActiveBattler].physicalBattlerId = gBattlerAttacker; + gSpecialStatuses[gActiveBattler].physicalBattlerId = gBattlerAttacker; } else { - gProtectStructs[gActiveBattler].physicalBank = gBattlerTarget; - gSpecialStatuses[gActiveBattler].moveturnPhysicalBank = gBattlerTarget; + gProtectStructs[gActiveBattler].physicalBattlerId = gBattlerTarget; + gSpecialStatuses[gActiveBattler].physicalBattlerId = gBattlerTarget; } } - else if (moveType > 8 && !(gHitMarker & HITMARKER_x100000)) + else if (!IS_MOVE_PHYSICAL(moveType) && !(gHitMarker & HITMARKER_x100000)) { gProtectStructs[gActiveBattler].specialDmg = gHpDealt; - gSpecialStatuses[gActiveBattler].moveturnLostHP_special = gHpDealt; - if (gBattlescriptCurrInstr[1] == BS_GET_TARGET) + gSpecialStatuses[gActiveBattler].specialDmg = gHpDealt; + if (gBattlescriptCurrInstr[1] == BS_TARGET) { - gProtectStructs[gActiveBattler].specialBank = gBattlerAttacker; - gSpecialStatuses[gActiveBattler].moveturnSpecialBank = gBattlerAttacker; + gProtectStructs[gActiveBattler].specialBattlerId = gBattlerAttacker; + gSpecialStatuses[gActiveBattler].specialBattlerId = gBattlerAttacker; } else { - gProtectStructs[gActiveBattler].specialBank = gBattlerTarget; - gSpecialStatuses[gActiveBattler].moveturnSpecialBank = gBattlerTarget; + gProtectStructs[gActiveBattler].specialBattlerId = gBattlerTarget; + gSpecialStatuses[gActiveBattler].specialBattlerId = gBattlerTarget; } } } @@ -2067,9 +2007,9 @@ static void atk0C_datahpupdate(void) } else { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); - if (gSpecialStatuses[gActiveBattler].moveturnLostHP == 0) - gSpecialStatuses[gActiveBattler].moveturnLostHP = 0xFFFF; + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + if (gSpecialStatuses[gActiveBattler].dmg == 0) + gSpecialStatuses[gActiveBattler].dmg = 0xFFFF; } gBattlescriptCurrInstr += 2; } @@ -2171,7 +2111,7 @@ static void atk0F_resultmessage(void) break; case MOVE_RESULT_FOE_HUNG_ON: gLastUsedItem = gBattleMons[gBattlerTarget].item; - gStringBattler = gBattlerTarget; + gPotentialItemEffectBattler = gBattlerTarget; gMoveResultFlags &= ~(MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON); BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_HangedOnMsg; @@ -2200,7 +2140,7 @@ static void atk0F_resultmessage(void) else if (gMoveResultFlags & MOVE_RESULT_FOE_HUNG_ON) { gLastUsedItem = gBattleMons[gBattlerTarget].item; - gStringBattler = gBattlerTarget; + gPotentialItemEffectBattler = gBattlerTarget; gMoveResultFlags &= ~(MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON); BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_HangedOnMsg; @@ -2296,12 +2236,12 @@ static void atk14_printselectionstringfromtable(void) } } -u8 GetBattlerTurnOrderNum(u8 bank) +u8 GetBattlerTurnOrderNum(u8 battlerId) { s32 i; for (i = 0; i < gBattlersCount; i++) { - if (gBattleTurnOrder[i] == bank) + if (gBattleTurnOrder[i] == battlerId) break; } return i; @@ -2328,31 +2268,31 @@ void SetMoveEffect(bool8 primary, u8 certain) if (gBattleCommunication[MOVE_EFFECT_BYTE] & MOVE_EFFECT_AFFECTS_USER) { - gEffectBank = gBattlerAttacker; // bank that effects get applied on + gEffectBattler = gBattlerAttacker; // battlerId that effects get applied on gBattleCommunication[MOVE_EFFECT_BYTE] &= ~(MOVE_EFFECT_AFFECTS_USER); affectsUser = MOVE_EFFECT_AFFECTS_USER; gBattleScripting.battler = gBattlerTarget; // theoretically the attacker } else { - gEffectBank = gBattlerTarget; + gEffectBattler = gBattlerTarget; gBattleScripting.battler = gBattlerAttacker; } - if (gBattleMons[gEffectBank].ability == ABILITY_SHIELD_DUST && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + if (gBattleMons[gEffectBattler].ability == ABILITY_SHIELD_DUST && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) && !primary && gBattleCommunication[MOVE_EFFECT_BYTE] <= 9) INCREMENT_RESET_RETURN - if (gSideStatuses[GET_BATTLER_SIDE(gEffectBank)] & SIDE_STATUS_SAFEGUARD && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + if (gSideStatuses[GET_BATTLER_SIDE(gEffectBattler)] & SIDE_STATUS_SAFEGUARD && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) && !primary && gBattleCommunication[MOVE_EFFECT_BYTE] <= 7) INCREMENT_RESET_RETURN - if (gBattleMons[gEffectBank].hp == 0 + if (gBattleMons[gEffectBattler].hp == 0 && gBattleCommunication[MOVE_EFFECT_BYTE] != MOVE_EFFECT_PAYDAY && gBattleCommunication[MOVE_EFFECT_BYTE] != MOVE_EFFECT_STEAL_ITEM) INCREMENT_RESET_RETURN - if (gBattleMons[gEffectBank].status2 & STATUS2_SUBSTITUTE && affectsUser != MOVE_EFFECT_AFFECTS_USER) + if (gBattleMons[gEffectBattler].status2 & STATUS2_SUBSTITUTE && affectsUser != MOVE_EFFECT_AFFECTS_USER) INCREMENT_RESET_RETURN if (gBattleCommunication[MOVE_EFFECT_BYTE] <= 6) // status change @@ -2361,7 +2301,7 @@ void SetMoveEffect(bool8 primary, u8 certain) { case STATUS1_SLEEP: // check active uproar - if (gBattleMons[gEffectBank].ability != ABILITY_SOUNDPROOF) + if (gBattleMons[gEffectBattler].ability != ABILITY_SOUNDPROOF) { for (gActiveBattler = 0; gActiveBattler < gBattlersCount && !(gBattleMons[gActiveBattler].status2 & STATUS2_UPROAR); @@ -2371,24 +2311,24 @@ void SetMoveEffect(bool8 primary, u8 certain) else gActiveBattler = gBattlersCount; - if (gBattleMons[gEffectBank].status1) + if (gBattleMons[gEffectBattler].status1) break; if (gActiveBattler != gBattlersCount) break; - if (gBattleMons[gEffectBank].ability == ABILITY_VITAL_SPIRIT) + if (gBattleMons[gEffectBattler].ability == ABILITY_VITAL_SPIRIT) break; - if (gBattleMons[gEffectBank].ability == ABILITY_INSOMNIA) + if (gBattleMons[gEffectBattler].ability == ABILITY_INSOMNIA) break; - CancelMultiTurnMoves(gEffectBank); + CancelMultiTurnMoves(gEffectBattler); statusChanged = TRUE; break; case STATUS1_POISON: - if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY + if (gBattleMons[gEffectBattler].ability == ABILITY_IMMUNITY && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) { gLastUsedAbility = ABILITY_IMMUNITY; - RecordAbilityBattle(gEffectBank, ABILITY_IMMUNITY); + RecordAbilityBattle(gEffectBattler, ABILITY_IMMUNITY); BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_PSNPrevention; @@ -2404,8 +2344,8 @@ void SetMoveEffect(bool8 primary, u8 certain) } RESET_RETURN } - if ((gBattleMons[gEffectBank].type1 == TYPE_POISON || gBattleMons[gEffectBank].type2 == TYPE_POISON - || gBattleMons[gEffectBank].type1 == TYPE_STEEL || gBattleMons[gEffectBank].type2 == TYPE_STEEL) + if ((gBattleMons[gEffectBattler].type1 == TYPE_POISON || gBattleMons[gEffectBattler].type2 == TYPE_POISON + || gBattleMons[gEffectBattler].type1 == TYPE_STEEL || gBattleMons[gEffectBattler].type2 == TYPE_STEEL) && (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) { @@ -2415,27 +2355,27 @@ void SetMoveEffect(bool8 primary, u8 certain) gBattleCommunication[MULTISTRING_CHOOSER] = 2; RESET_RETURN } - if (gBattleMons[gEffectBank].type1 == TYPE_POISON) + if (gBattleMons[gEffectBattler].type1 == TYPE_POISON) break; - if (gBattleMons[gEffectBank].type2 == TYPE_POISON) + if (gBattleMons[gEffectBattler].type2 == TYPE_POISON) break; - if (gBattleMons[gEffectBank].type1 == TYPE_STEEL) + if (gBattleMons[gEffectBattler].type1 == TYPE_STEEL) break; - if (gBattleMons[gEffectBank].type2 == TYPE_STEEL) + if (gBattleMons[gEffectBattler].type2 == TYPE_STEEL) break; - if (gBattleMons[gEffectBank].status1) + if (gBattleMons[gEffectBattler].status1) break; - if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY) + if (gBattleMons[gEffectBattler].ability == ABILITY_IMMUNITY) break; statusChanged = TRUE; break; case STATUS1_BURN: - if (gBattleMons[gEffectBank].ability == ABILITY_WATER_VEIL + if (gBattleMons[gEffectBattler].ability == ABILITY_WATER_VEIL && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) { gLastUsedAbility = ABILITY_WATER_VEIL; - RecordAbilityBattle(gEffectBank, ABILITY_WATER_VEIL); + RecordAbilityBattle(gEffectBattler, ABILITY_WATER_VEIL); BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_BRNPrevention; @@ -2450,8 +2390,8 @@ void SetMoveEffect(bool8 primary, u8 certain) } RESET_RETURN } - if ((gBattleMons[gEffectBank].type1 == TYPE_FIRE - || gBattleMons[gEffectBank].type2 == TYPE_FIRE) + if ((gBattleMons[gEffectBattler].type1 == TYPE_FIRE + || gBattleMons[gEffectBattler].type2 == TYPE_FIRE) && (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) { @@ -2461,13 +2401,13 @@ void SetMoveEffect(bool8 primary, u8 certain) gBattleCommunication[MULTISTRING_CHOOSER] = 2; RESET_RETURN } - if (gBattleMons[gEffectBank].type1 == TYPE_FIRE) + if (gBattleMons[gEffectBattler].type1 == TYPE_FIRE) break; - if (gBattleMons[gEffectBank].type2 == TYPE_FIRE) + if (gBattleMons[gEffectBattler].type2 == TYPE_FIRE) break; - if (gBattleMons[gEffectBank].ability == ABILITY_WATER_VEIL) + if (gBattleMons[gEffectBattler].ability == ABILITY_WATER_VEIL) break; - if (gBattleMons[gEffectBank].status1) + if (gBattleMons[gEffectBattler].status1) break; statusChanged = TRUE; @@ -2475,27 +2415,27 @@ void SetMoveEffect(bool8 primary, u8 certain) case STATUS1_FREEZE: if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SUN_ANY) noSunCanFreeze = FALSE; - if (gBattleMons[gEffectBank].type1 == TYPE_ICE) + if (gBattleMons[gEffectBattler].type1 == TYPE_ICE) break; - if (gBattleMons[gEffectBank].type2 == TYPE_ICE) + if (gBattleMons[gEffectBattler].type2 == TYPE_ICE) break; - if (gBattleMons[gEffectBank].status1) + if (gBattleMons[gEffectBattler].status1) break; if (noSunCanFreeze == 0) break; - if (gBattleMons[gEffectBank].ability == ABILITY_MAGMA_ARMOR) + if (gBattleMons[gEffectBattler].ability == ABILITY_MAGMA_ARMOR) break; - CancelMultiTurnMoves(gEffectBank); + CancelMultiTurnMoves(gEffectBattler); statusChanged = TRUE; break; case STATUS1_PARALYSIS: - if (gBattleMons[gEffectBank].ability == ABILITY_LIMBER) + if (gBattleMons[gEffectBattler].ability == ABILITY_LIMBER) { if (primary == TRUE || certain == MOVE_EFFECT_CERTAIN) { gLastUsedAbility = ABILITY_LIMBER; - RecordAbilityBattle(gEffectBank, ABILITY_LIMBER); + RecordAbilityBattle(gEffectBattler, ABILITY_LIMBER); BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_PRLZPrevention; @@ -2514,16 +2454,16 @@ void SetMoveEffect(bool8 primary, u8 certain) else break; } - if (gBattleMons[gEffectBank].status1) + if (gBattleMons[gEffectBattler].status1) break; statusChanged = TRUE; break; case STATUS1_TOXIC_POISON: - if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) + if (gBattleMons[gEffectBattler].ability == ABILITY_IMMUNITY && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) { gLastUsedAbility = ABILITY_IMMUNITY; - RecordAbilityBattle(gEffectBank, ABILITY_IMMUNITY); + RecordAbilityBattle(gEffectBattler, ABILITY_IMMUNITY); BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_PSNPrevention; @@ -2539,8 +2479,8 @@ void SetMoveEffect(bool8 primary, u8 certain) } RESET_RETURN } - if ((gBattleMons[gEffectBank].type1 == TYPE_POISON || gBattleMons[gEffectBank].type2 == TYPE_POISON - || gBattleMons[gEffectBank].type1 == TYPE_STEEL || gBattleMons[gEffectBank].type2 == TYPE_STEEL) + if ((gBattleMons[gEffectBattler].type1 == TYPE_POISON || gBattleMons[gEffectBattler].type2 == TYPE_POISON + || gBattleMons[gEffectBattler].type1 == TYPE_STEEL || gBattleMons[gEffectBattler].type2 == TYPE_STEEL) && (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) && (primary == TRUE || certain == MOVE_EFFECT_CERTAIN)) { @@ -2550,19 +2490,19 @@ void SetMoveEffect(bool8 primary, u8 certain) gBattleCommunication[MULTISTRING_CHOOSER] = 2; RESET_RETURN } - if (gBattleMons[gEffectBank].status1) + if (gBattleMons[gEffectBattler].status1) break; - if (gBattleMons[gEffectBank].type1 != TYPE_POISON - && gBattleMons[gEffectBank].type2 != TYPE_POISON - && gBattleMons[gEffectBank].type1 != TYPE_STEEL - && gBattleMons[gEffectBank].type2 != TYPE_STEEL) + if (gBattleMons[gEffectBattler].type1 != TYPE_POISON + && gBattleMons[gEffectBattler].type2 != TYPE_POISON + && gBattleMons[gEffectBattler].type1 != TYPE_STEEL + && gBattleMons[gEffectBattler].type2 != TYPE_STEEL) { - if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY) + if (gBattleMons[gEffectBattler].ability == ABILITY_IMMUNITY) break; // It's redundant, because at this point we know the status1 value is 0. - gBattleMons[gEffectBank].status1 &= ~(STATUS1_TOXIC_POISON); - gBattleMons[gEffectBank].status1 &= ~(STATUS1_POISON); + gBattleMons[gEffectBattler].status1 &= ~(STATUS1_TOXIC_POISON); + gBattleMons[gEffectBattler].status1 &= ~(STATUS1_POISON); statusChanged = TRUE; break; } @@ -2577,14 +2517,14 @@ void SetMoveEffect(bool8 primary, u8 certain) BattleScriptPush(gBattlescriptCurrInstr + 1); if (sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]] == STATUS1_SLEEP) - gBattleMons[gEffectBank].status1 |= ((Random() & 3) + 2); + gBattleMons[gEffectBattler].status1 |= ((Random() & 3) + 2); else - gBattleMons[gEffectBank].status1 |= sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]; + gBattleMons[gEffectBattler].status1 |= sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]; gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; - gActiveBattler = gEffectBank; - BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gEffectBank].status1); + gActiveBattler = gEffectBattler; + BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gEffectBattler].status1); MarkBattlerForControllerExec(gActiveBattler); if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) @@ -2620,7 +2560,7 @@ void SetMoveEffect(bool8 primary, u8 certain) } else { - if (gBattleMons[gEffectBank].status2 & sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]) + if (gBattleMons[gEffectBattler].status2 & sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]) { gBattlescriptCurrInstr++; } @@ -2630,26 +2570,26 @@ void SetMoveEffect(bool8 primary, u8 certain) switch (gBattleCommunication[MOVE_EFFECT_BYTE]) { case MOVE_EFFECT_CONFUSION: - if (gBattleMons[gEffectBank].ability == ABILITY_OWN_TEMPO - || gBattleMons[gEffectBank].status2 & STATUS2_CONFUSION) + if (gBattleMons[gEffectBattler].ability == ABILITY_OWN_TEMPO + || gBattleMons[gEffectBattler].status2 & STATUS2_CONFUSION) { gBattlescriptCurrInstr++; } else { - gBattleMons[gEffectBank].status2 |= (((Random()) % 0x4)) + 2; + gBattleMons[gEffectBattler].status2 |= (((Random()) % 0x4)) + 2; BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; } break; case MOVE_EFFECT_FLINCH: - if (gBattleMons[gEffectBank].ability == ABILITY_INNER_FOCUS) + if (gBattleMons[gEffectBattler].ability == ABILITY_INNER_FOCUS) { if (primary == TRUE || certain == MOVE_EFFECT_CERTAIN) { gLastUsedAbility = ABILITY_INNER_FOCUS; - RecordAbilityBattle(gEffectBank, ABILITY_INNER_FOCUS); + RecordAbilityBattle(gEffectBattler, ABILITY_INNER_FOCUS); gBattlescriptCurrInstr = BattleScript_FlinchPrevention; } else @@ -2659,18 +2599,18 @@ void SetMoveEffect(bool8 primary, u8 certain) } else { - if (GetBattlerTurnOrderNum(gEffectBank) > gCurrentTurnActionNumber) - gBattleMons[gEffectBank].status2 |= sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]; + if (GetBattlerTurnOrderNum(gEffectBattler) > gCurrentTurnActionNumber) + gBattleMons[gEffectBattler].status2 |= sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]; gBattlescriptCurrInstr++; } break; case MOVE_EFFECT_UPROAR: - if (!(gBattleMons[gEffectBank].status2 & STATUS2_UPROAR)) + if (!(gBattleMons[gEffectBattler].status2 & STATUS2_UPROAR)) { - gBattleMons[gEffectBank].status2 |= STATUS2_MULTIPLETURNS; - gLockedMoves[gEffectBank] = gCurrentMove; - gBattleMons[gEffectBank].status2 |= ((Random() & 3) + 2) << 4; + gBattleMons[gEffectBattler].status2 |= STATUS2_MULTIPLETURNS; + gLockedMoves[gEffectBattler] = gCurrentMove; + gBattleMons[gEffectBattler].status2 |= ((Random() & 3) + 2) << 4; BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; @@ -2692,7 +2632,7 @@ void SetMoveEffect(bool8 primary, u8 certain) gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; break; case MOVE_EFFECT_TRI_ATTACK: - if (gBattleMons[gEffectBank].status1) + if (gBattleMons[gEffectBattler].status1) { gBattlescriptCurrInstr++; } @@ -2703,23 +2643,23 @@ void SetMoveEffect(bool8 primary, u8 certain) } break; case MOVE_EFFECT_CHARGING: - gBattleMons[gEffectBank].status2 |= STATUS2_MULTIPLETURNS; - gLockedMoves[gEffectBank] = gCurrentMove; - gProtectStructs[gEffectBank].chargingTurn = 1; + gBattleMons[gEffectBattler].status2 |= STATUS2_MULTIPLETURNS; + gLockedMoves[gEffectBattler] = gCurrentMove; + gProtectStructs[gEffectBattler].chargingTurn = 1; gBattlescriptCurrInstr++; break; case MOVE_EFFECT_WRAP: - if (gBattleMons[gEffectBank].status2 & STATUS2_WRAPPED) + if (gBattleMons[gEffectBattler].status2 & STATUS2_WRAPPED) { gBattlescriptCurrInstr++; } else { - gBattleMons[gEffectBank].status2 |= ((Random() & 3) + 3) << 0xD; + gBattleMons[gEffectBattler].status2 |= ((Random() & 3) + 3) << 0xD; - *(gBattleStruct->wrappedMove + gEffectBank * 2 + 0) = gCurrentMove; - *(gBattleStruct->wrappedMove + gEffectBank * 2 + 1) = gCurrentMove >> 8; - *(gBattleStruct->wrappedBy + gEffectBank) = gBattlerAttacker; + *(gBattleStruct->wrappedMove + gEffectBattler * 2 + 0) = gCurrentMove; + *(gBattleStruct->wrappedMove + gEffectBattler * 2 + 1) = gCurrentMove >> 8; + *(gBattleStruct->wrappedBy + gEffectBattler) = gBattlerAttacker; BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; @@ -2826,9 +2766,9 @@ void SetMoveEffect(bool8 primary, u8 certain) } break; case MOVE_EFFECT_RECHARGE: - gBattleMons[gEffectBank].status2 |= STATUS2_RECHARGE; - gDisableStructs[gEffectBank].rechargeCounter = 2; - gLockedMoves[gEffectBank] = gCurrentMove; + gBattleMons[gEffectBattler].status2 |= STATUS2_RECHARGE; + gDisableStructs[gEffectBattler].rechargeCounter = 2; + gLockedMoves[gEffectBattler] = gCurrentMove; gBattlescriptCurrInstr++; break; case MOVE_EFFECT_RAGE: @@ -2950,21 +2890,21 @@ void SetMoveEffect(bool8 primary, u8 certain) gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; break; case MOVE_EFFECT_THRASH: - if (gBattleMons[gEffectBank].status2 & STATUS2_LOCK_CONFUSE) + if (gBattleMons[gEffectBattler].status2 & STATUS2_LOCK_CONFUSE) { gBattlescriptCurrInstr++; } else { - gBattleMons[gEffectBank].status2 |= STATUS2_MULTIPLETURNS; - gLockedMoves[gEffectBank] = gCurrentMove; - gBattleMons[gEffectBank].status2 |= (((Random() & 1) + 2) << 0xA); + gBattleMons[gEffectBattler].status2 |= STATUS2_MULTIPLETURNS; + gLockedMoves[gEffectBattler] = gCurrentMove; + gBattleMons[gEffectBattler].status2 |= (((Random() & 1) + 2) << 0xA); } break; case MOVE_EFFECT_KNOCK_OFF: - if (gBattleMons[gEffectBank].ability == ABILITY_STICKY_HOLD) + if (gBattleMons[gEffectBattler].ability == ABILITY_STICKY_HOLD) { - if (gBattleMons[gEffectBank].item == 0) + if (gBattleMons[gEffectBattler].item == 0) { gBattlescriptCurrInstr++; } @@ -2972,23 +2912,23 @@ void SetMoveEffect(bool8 primary, u8 certain) { gLastUsedAbility = ABILITY_STICKY_HOLD; gBattlescriptCurrInstr = BattleScript_StickyHoldActivates; - RecordAbilityBattle(gEffectBank, ABILITY_STICKY_HOLD); + RecordAbilityBattle(gEffectBattler, ABILITY_STICKY_HOLD); } break; } - if (gBattleMons[gEffectBank].item) + if (gBattleMons[gEffectBattler].item) { - side = GetBattlerSide(gEffectBank); + side = GetBattlerSide(gEffectBattler); - gLastUsedItem = gBattleMons[gEffectBank].item; - gBattleMons[gEffectBank].item = 0; - gWishFutureKnock.knockedOffPokes[side] |= gBitTable[gBattlerPartyIndexes[gEffectBank]]; + gLastUsedItem = gBattleMons[gEffectBattler].item; + gBattleMons[gEffectBattler].item = 0; + gWishFutureKnock.knockedOffPokes[side] |= gBitTable[gBattlerPartyIndexes[gEffectBattler]]; BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_KnockedOff; - *(u8*)((u8*)(&gBattleStruct->choicedMove[gEffectBank]) + 0) = 0; - *(u8*)((u8*)(&gBattleStruct->choicedMove[gEffectBank]) + 1) = 0; + *(u8*)((u8*)(&gBattleStruct->choicedMove[gEffectBattler]) + 0) = 0; + *(u8*)((u8*)(&gBattleStruct->choicedMove[gEffectBattler]) + 1) = 0; } else { @@ -3051,7 +2991,7 @@ static void atk17_seteffectsecondary(void) static void atk18_clearstatusfromeffect(void) { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); if (gBattleCommunication[MOVE_EFFECT_BYTE] <= MOVE_EFFECT_TOXIC) gBattleMons[gActiveBattler].status1 &= (~sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]); @@ -3069,7 +3009,7 @@ static void atk19_tryfaintmon(void) if (gBattlescriptCurrInstr[2] != 0) { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); if (gHitMarker & HITMARKER_FAINTED(gActiveBattler)) { BS_ptr = BSScriptReadPtr(gBattlescriptCurrInstr + 3); @@ -3085,18 +3025,18 @@ static void atk19_tryfaintmon(void) } else { - u8 bank; + u8 battlerId; - if (gBattlescriptCurrInstr[1] == BS_GET_ATTACKER) + if (gBattlescriptCurrInstr[1] == BS_ATTACKER) { gActiveBattler = gBattlerAttacker; - bank = gBattlerTarget; + battlerId = gBattlerTarget; BS_ptr = BattleScript_FaintAttacker; } else { gActiveBattler = gBattlerTarget; - bank = gBattlerAttacker; + battlerId = gBattlerAttacker; BS_ptr = BattleScript_FaintTarget; } if (!(gAbsentBattlerFlags & gBitTable[gActiveBattler]) @@ -3122,7 +3062,7 @@ static void atk19_tryfaintmon(void) { gHitMarker &= ~(HITMARKER_DESTINYBOND); BattleScriptPush(gBattlescriptCurrInstr); - gBattleMoveDamage = gBattleMons[bank].hp; + gBattleMoveDamage = gBattleMons[battlerId].hp; gBattlescriptCurrInstr = BattleScript_DestinyBondTakesLife; } if ((gStatuses3[gBattlerTarget] & STATUS3_GRUDGE) @@ -3154,7 +3094,7 @@ static void atk1A_dofaintanimation(void) { if (gBattleControllerExecFlags == 0) { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); BtlController_EmitFaintAnimation(0); MarkBattlerForControllerExec(gActiveBattler); gBattlescriptCurrInstr += 2; @@ -3165,7 +3105,7 @@ static void atk1B_cleareffectsonfaint(void) { if (gBattleControllerExecFlags == 0) { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); if (!(gBattleTypeFlags & BATTLE_TYPE_ARENA) || gBattleMons[gActiveBattler].hp == 0) { @@ -3181,11 +3121,11 @@ static void atk1B_cleareffectsonfaint(void) static void atk1C_jumpifstatus(void) { - u8 bank = GetBattleBank(gBattlescriptCurrInstr[1]); + u8 battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); u32 flags = BS2ScriptRead32(gBattlescriptCurrInstr + 2); const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 6); - if (gBattleMons[bank].status1 & flags && gBattleMons[bank].hp) + if (gBattleMons[battlerId].status1 & flags && gBattleMons[battlerId].hp) gBattlescriptCurrInstr = jumpPtr; else gBattlescriptCurrInstr += 10; @@ -3193,11 +3133,11 @@ static void atk1C_jumpifstatus(void) static void atk1D_jumpifstatus2(void) { - u8 bank = GetBattleBank(gBattlescriptCurrInstr[1]); + u8 battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); u32 flags = BS2ScriptRead32(gBattlescriptCurrInstr + 2); const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 6); - if (gBattleMons[bank].status2 & flags && gBattleMons[bank].hp) + if (gBattleMons[battlerId].status2 & flags && gBattleMons[battlerId].hp) gBattlescriptCurrInstr = jumpPtr; else gBattlescriptCurrInstr += 10; @@ -3205,45 +3145,45 @@ static void atk1D_jumpifstatus2(void) static void atk1E_jumpifability(void) { - u8 bank; + u8 battlerId; u8 ability = gBattlescriptCurrInstr[2]; const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 3); - if (gBattlescriptCurrInstr[1] == BS_GET_ATTACKER_SIDE) + if (gBattlescriptCurrInstr[1] == BS_ATTACKER_SIDE) { - bank = AbilityBattleEffects(ABILITYEFFECT_CHECK_BANK_SIDE, gBattlerAttacker, ability, 0, 0); - if (bank) + battlerId = AbilityBattleEffects(ABILITYEFFECT_CHECK_BANK_SIDE, gBattlerAttacker, ability, 0, 0); + if (battlerId) { gLastUsedAbility = ability; gBattlescriptCurrInstr = jumpPtr; - RecordAbilityBattle(bank - 1, gLastUsedAbility); - gBattleScripting.battlerWithAbility = bank - 1; + RecordAbilityBattle(battlerId - 1, gLastUsedAbility); + gBattleScripting.battlerWithAbility = battlerId - 1; } else gBattlescriptCurrInstr += 7; } - else if (gBattlescriptCurrInstr[1] == BS_GET_NOT_ATTACKER_SIDE) + else if (gBattlescriptCurrInstr[1] == BS_NOT_ATTACKER_SIDE) { - bank = AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, gBattlerAttacker, ability, 0, 0); - if (bank) + battlerId = AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, gBattlerAttacker, ability, 0, 0); + if (battlerId) { gLastUsedAbility = ability; gBattlescriptCurrInstr = jumpPtr; - RecordAbilityBattle(bank - 1, gLastUsedAbility); - gBattleScripting.battlerWithAbility = bank - 1; + RecordAbilityBattle(battlerId - 1, gLastUsedAbility); + gBattleScripting.battlerWithAbility = battlerId - 1; } else gBattlescriptCurrInstr += 7; } else { - bank = GetBattleBank(gBattlescriptCurrInstr[1]); - if (gBattleMons[bank].ability == ability) + battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + if (gBattleMons[battlerId].ability == ability) { gLastUsedAbility = ability; gBattlescriptCurrInstr = jumpPtr; - RecordAbilityBattle(bank, gLastUsedAbility); - gBattleScripting.battlerWithAbility = bank; + RecordAbilityBattle(battlerId, gLastUsedAbility); + gBattleScripting.battlerWithAbility = battlerId; } else gBattlescriptCurrInstr += 7; @@ -3256,7 +3196,7 @@ static void atk1F_jumpifsideaffecting(void) u16 flags; const u8* jumpPtr; - if (gBattlescriptCurrInstr[1] == BS_GET_ATTACKER) + if (gBattlescriptCurrInstr[1] == BS_ATTACKER) side = GET_BATTLER_SIDE(gBattlerAttacker); else side = GET_BATTLER_SIDE(gBattlerTarget); @@ -3273,8 +3213,8 @@ static void atk1F_jumpifsideaffecting(void) static void atk20_jumpifstat(void) { u8 ret = 0; - u8 bank = GetBattleBank(gBattlescriptCurrInstr[1]); - u8 value = gBattleMons[bank].statStages[gBattlescriptCurrInstr[3]]; + u8 battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + u8 value = gBattleMons[battlerId].statStages[gBattlescriptCurrInstr[3]]; switch (gBattlescriptCurrInstr[2]) { @@ -3315,7 +3255,7 @@ static void atk21_jumpifstatus3condition(void) u32 flags; const u8 *jumpPtr; - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); flags = BS2ScriptRead32(gBattlescriptCurrInstr + 2); jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 7); @@ -3337,11 +3277,11 @@ static void atk21_jumpifstatus3condition(void) static void atk22_jumpiftype(void) { - u8 bank = GetBattleBank(gBattlescriptCurrInstr[1]); + u8 battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); u8 type = gBattlescriptCurrInstr[2]; const u8* jumpPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 3); - if (gBattleMons[bank].type1 == type || gBattleMons[bank].type2 == type) + if (gBattleMons[battlerId].type1 == type || gBattleMons[battlerId].type2 == type) gBattlescriptCurrInstr = jumpPtr; else gBattlescriptCurrInstr += 7; @@ -3357,13 +3297,13 @@ static void atk23_getexp(void) s32 viaExpShare = 0; u16* exp = &gBattleStruct->expValue; - gBank1 = GetBattleBank(gBattlescriptCurrInstr[1]); - sentIn = gSentPokesToOpponent[(gBank1 & 2) >> 1]; + gBattlerFainted = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + sentIn = gSentPokesToOpponent[(gBattlerFainted & 2) >> 1]; switch (gBattleScripting.atk23_state) { case 0: // check if should receive exp at all - if (GetBattlerSide(gBank1) != B_SIDE_OPPONENT || (gBattleTypeFlags & + if (GetBattlerSide(gBattlerFainted) != B_SIDE_OPPONENT || (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000 | BATTLE_TYPE_x4000000 @@ -3377,7 +3317,7 @@ static void atk23_getexp(void) else { gBattleScripting.atk23_state++; - gBattleStruct->field_DF |= gBitTable[gBattlerPartyIndexes[gBank1]]; + gBattleStruct->field_DF |= gBitTable[gBattlerPartyIndexes[gBattlerFainted]]; } break; case 1: // calculate experience points to redistribute @@ -3403,7 +3343,7 @@ static void atk23_getexp(void) viaExpShare++; } - calculatedExp = gBaseStats[gBattleMons[gBank1].species].expYield * gBattleMons[gBank1].level / 7; + calculatedExp = gBaseStats[gBattleMons[gBattlerFainted].species].expYield * gBattleMons[gBattlerFainted].level / 7; if (viaExpShare) // at least one mon is getting exp via exp share { @@ -3424,14 +3364,14 @@ static void atk23_getexp(void) } gBattleScripting.atk23_state++; - gBattleStruct->expGetterId = 0; + gBattleStruct->expGetterMonId = 0; gBattleStruct->sentInPokes = sentIn; } // fall through case 2: // set exp value to the poke in expgetter_id and print message if (gBattleControllerExecFlags == 0) { - item = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_HELD_ITEM); + item = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_HELD_ITEM); if (item == ITEM_ENIGMA_BERRY) holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect; @@ -3444,7 +3384,7 @@ static void atk23_getexp(void) gBattleScripting.atk23_state = 5; gBattleMoveDamage = 0; // used for exp } - else if (GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL) == MAX_MON_LEVEL) + else if (GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_LEVEL) == MAX_MON_LEVEL) { *(&gBattleStruct->sentInPokes) >>= 1; gBattleScripting.atk23_state = 5; @@ -3460,7 +3400,7 @@ static void atk23_getexp(void) gBattleStruct->wildVictorySong++; } - if (GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_HP)) + if (GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_HP)) { if (gBattleStruct->sentInPokes & 1) gBattleMoveDamage = *exp; @@ -3474,10 +3414,10 @@ static void atk23_getexp(void) if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) gBattleMoveDamage = (gBattleMoveDamage * 150) / 100; - if (IsTradedMon(&gPlayerParty[gBattleStruct->expGetterId])) + if (IsTradedMon(&gPlayerParty[gBattleStruct->expGetterMonId])) { // check if the pokemon doesn't belong to the player - if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gBattleStruct->expGetterId >= 3) + if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gBattleStruct->expGetterMonId >= 3) { i = 0x149; } @@ -3492,31 +3432,31 @@ static void atk23_getexp(void) i = 0x149; } - // get exp getter bank + // get exp getter battlerId if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) { - if (!(gBattlerPartyIndexes[2] != gBattleStruct->expGetterId) && !(gAbsentBattlerFlags & gBitTable[2])) - gBattleStruct->expGetterBank = 2; + if (!(gBattlerPartyIndexes[2] != gBattleStruct->expGetterMonId) && !(gAbsentBattlerFlags & gBitTable[2])) + gBattleStruct->expGetterBattlerId = 2; else { if (!(gAbsentBattlerFlags & gBitTable[0])) - gBattleStruct->expGetterBank = 0; + gBattleStruct->expGetterBattlerId = 0; else - gBattleStruct->expGetterBank = 2; + gBattleStruct->expGetterBattlerId = 2; } } else - gBattleStruct->expGetterBank = 0; + gBattleStruct->expGetterBattlerId = 0; - PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattleStruct->expGetterBank, gBattleStruct->expGetterId) + PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattleStruct->expGetterBattlerId, gBattleStruct->expGetterMonId) // buffer 'gained' or 'gained a boosted' PREPARE_STRING_BUFFER(gBattleTextBuff2, i) PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff3, 5, gBattleMoveDamage) - PrepareStringBattle(STRINGID_PKMNGAINEDEXP, gBattleStruct->expGetterBank); - MonGainEVs(&gPlayerParty[gBattleStruct->expGetterId], gBattleMons[gBank1].species); + PrepareStringBattle(STRINGID_PKMNGAINEDEXP, gBattleStruct->expGetterBattlerId); + MonGainEVs(&gPlayerParty[gBattleStruct->expGetterMonId], gBattleMons[gBattlerFainted].species); } gBattleStruct->sentInPokes >>= 1; gBattleScripting.atk23_state++; @@ -3526,18 +3466,18 @@ static void atk23_getexp(void) case 3: // Set stats and give exp if (gBattleControllerExecFlags == 0) { - gBattleBufferB[gBattleStruct->expGetterBank][0] = 0; - if (GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_HP) && GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL) != MAX_MON_LEVEL) + gBattleBufferB[gBattleStruct->expGetterBattlerId][0] = 0; + if (GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_HP) && GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_LEVEL) != MAX_MON_LEVEL) { - gBattleResources->statsBeforeLvlUp->hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_MAX_HP); - gBattleResources->statsBeforeLvlUp->atk = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_ATK); - gBattleResources->statsBeforeLvlUp->def = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_DEF); - gBattleResources->statsBeforeLvlUp->spd = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPEED); - gBattleResources->statsBeforeLvlUp->spAtk = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPATK); - gBattleResources->statsBeforeLvlUp->spDef = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPDEF); + gBattleResources->statsBeforeLvlUp->hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_MAX_HP); + gBattleResources->statsBeforeLvlUp->atk = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_ATK); + gBattleResources->statsBeforeLvlUp->def = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_DEF); + gBattleResources->statsBeforeLvlUp->spd = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_SPEED); + gBattleResources->statsBeforeLvlUp->spAtk = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_SPATK); + gBattleResources->statsBeforeLvlUp->spDef = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_SPDEF); - gActiveBattler = gBattleStruct->expGetterBank; - BtlController_EmitExpUpdate(0, gBattleStruct->expGetterId, gBattleMoveDamage); + gActiveBattler = gBattleStruct->expGetterBattlerId; + BtlController_EmitExpUpdate(0, gBattleStruct->expGetterMonId, gBattleMoveDamage); MarkBattlerForControllerExec(gActiveBattler); } gBattleScripting.atk23_state++; @@ -3546,50 +3486,50 @@ static void atk23_getexp(void) case 4: // lvl up if necessary if (gBattleControllerExecFlags == 0) { - gActiveBattler = gBattleStruct->expGetterBank; + gActiveBattler = gBattleStruct->expGetterBattlerId; if (gBattleBufferB[gActiveBattler][0] == CONTROLLER_TWORETURNVALUES && gBattleBufferB[gActiveBattler][1] == RET_VALUE_LEVELLED_UP) { - if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && gBattlerPartyIndexes[gActiveBattler] == gBattleStruct->expGetterId) + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && gBattlerPartyIndexes[gActiveBattler] == gBattleStruct->expGetterMonId) HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gActiveBattler, gBattleStruct->expGetterId) + PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gActiveBattler, gBattleStruct->expGetterMonId) - PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff2, 3, GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL)) + PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff2, 3, GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_LEVEL)) BattleScriptPushCursor(); - gLeveledUpInBattle |= gBitTable[gBattleStruct->expGetterId]; + gLeveledUpInBattle |= gBitTable[gBattleStruct->expGetterMonId]; gBattlescriptCurrInstr = BattleScript_LevelUp; gBattleMoveDamage = (gBattleBufferB[gActiveBattler][2] | (gBattleBufferB[gActiveBattler][3] << 8)); - AdjustFriendship(&gPlayerParty[gBattleStruct->expGetterId], 0); + AdjustFriendship(&gPlayerParty[gBattleStruct->expGetterMonId], 0); // update battle mon structure after level up - if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterId && gBattleMons[0].hp) + if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterMonId && gBattleMons[0].hp) { - gBattleMons[0].level = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL); - gBattleMons[0].hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_HP); - gBattleMons[0].maxHP = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_MAX_HP); - gBattleMons[0].attack = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_ATK); - gBattleMons[0].defense = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_DEF); + gBattleMons[0].level = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_LEVEL); + gBattleMons[0].hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_HP); + gBattleMons[0].maxHP = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_MAX_HP); + gBattleMons[0].attack = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_ATK); + gBattleMons[0].defense = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_DEF); // Why is this duplicated? - gBattleMons[0].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPEED); - gBattleMons[0].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPEED); + gBattleMons[0].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_SPEED); + gBattleMons[0].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_SPEED); - gBattleMons[0].spAttack = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPATK); - gBattleMons[0].spDefense = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPDEF); + gBattleMons[0].spAttack = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_SPATK); + gBattleMons[0].spDefense = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_SPDEF); } // What is else if? - if (gBattlerPartyIndexes[2] == gBattleStruct->expGetterId && gBattleMons[2].hp && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + if (gBattlerPartyIndexes[2] == gBattleStruct->expGetterMonId && gBattleMons[2].hp && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) { - gBattleMons[2].level = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL); - gBattleMons[2].hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_HP); - gBattleMons[2].maxHP = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_MAX_HP); - gBattleMons[2].attack = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_ATK); - gBattleMons[2].defense = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_DEF); + gBattleMons[2].level = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_LEVEL); + gBattleMons[2].hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_HP); + gBattleMons[2].maxHP = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_MAX_HP); + gBattleMons[2].attack = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_ATK); + gBattleMons[2].defense = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_DEF); // Duplicated again, but this time there's no Sp Defense - gBattleMons[2].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPEED); - gBattleMons[2].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPEED); + gBattleMons[2].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_SPEED); + gBattleMons[2].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_SPEED); - gBattleMons[2].spAttack = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPATK); + gBattleMons[2].spAttack = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_SPATK); } gBattleScripting.atk23_state = 5; } @@ -3605,8 +3545,8 @@ static void atk23_getexp(void) gBattleScripting.atk23_state = 3; else { - gBattleStruct->expGetterId++; - if (gBattleStruct->expGetterId <= 5) + gBattleStruct->expGetterMonId++; + if (gBattleStruct->expGetterMonId <= 5) gBattleScripting.atk23_state = 2; // loop again else gBattleScripting.atk23_state = 6; // we're done @@ -3616,8 +3556,8 @@ static void atk23_getexp(void) if (gBattleControllerExecFlags == 0) { // not sure why gf clears the item and ability here - gBattleMons[gBank1].item = 0; - gBattleMons[gBank1].ability = 0; + gBattleMons[gBattlerFainted].item = 0; + gBattleMons[gBattlerFainted].ability = 0; gBattlescriptCurrInstr += 2; } break; @@ -3707,7 +3647,7 @@ static void atk24(void) } } #else -__attribute__((naked)) +ASM_DIRECT static void atk24(void) { asm("\n\ @@ -4322,7 +4262,7 @@ static void atk3A_waitstate(void) static void atk3B_healthbar_update(void) { - if (gBattlescriptCurrInstr[1] == BS_GET_TARGET) + if (gBattlescriptCurrInstr[1] == BS_TARGET) gActiveBattler = gBattlerTarget; else gActiveBattler = gBattlerAttacker; @@ -4369,9 +4309,9 @@ static void atk41_call(void) static void atk42_jumpiftype2(void) { - u8 bank = GetBattleBank(gBattlescriptCurrInstr[1]); + u8 battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); - if (gBattlescriptCurrInstr[2] == gBattleMons[bank].type1 || gBattlescriptCurrInstr[2] == gBattleMons[bank].type2) + if (gBattlescriptCurrInstr[2] == gBattleMons[battlerId].type1 || gBattlescriptCurrInstr[2] == gBattleMons[battlerId].type2) gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 3); else gBattlescriptCurrInstr += 7; @@ -4394,7 +4334,7 @@ static void atk45_playanimation(void) { const u16* argumentPtr; - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); argumentPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 3); if (gBattlescriptCurrInstr[2] == B_ANIM_STATS_CHANGE @@ -4436,7 +4376,7 @@ static void atk46_playanimation2(void) // animation Id is stored in the first po const u16* argumentPtr; const u8* animationIdPtr; - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); animationIdPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 2); argumentPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 6); @@ -4505,7 +4445,7 @@ static void atk48_playstatchangeanimation(void) s32 changeableStats = 0; u32 statsToCheck = 0; - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); statsToCheck = gBattlescriptCurrInstr[2]; if (gBattlescriptCurrInstr[3] & ATK48_STAT_NEGATIVE) // goes down @@ -4526,8 +4466,8 @@ static void atk48_playstatchangeanimation(void) else if (!gSideTimers[GET_BATTLER_SIDE(gActiveBattler)].mistTimer && gBattleMons[gActiveBattler].ability != ABILITY_CLEAR_BODY && gBattleMons[gActiveBattler].ability != ABILITY_WHITE_SMOKE - && !(gBattleMons[gActiveBattler].ability == ABILITY_KEEN_EYE && currStat == STAT_STAGE_ACC) - && !(gBattleMons[gActiveBattler].ability == ABILITY_HYPER_CUTTER && currStat == STAT_STAGE_ATK)) + && !(gBattleMons[gActiveBattler].ability == ABILITY_KEEN_EYE && currStat == STAT_ACC) + && !(gBattleMons[gActiveBattler].ability == ABILITY_HYPER_CUTTER && currStat == STAT_ATK)) { if (gBattleMons[gActiveBattler].statStages[currStat] > 0) { @@ -4587,7 +4527,7 @@ static void atk48_playstatchangeanimation(void) } } #else -__attribute__((naked)) +ASM_DIRECT static void atk48_playstatchangeanimation(void) { asm("\n\ @@ -4606,7 +4546,7 @@ static void atk48_playstatchangeanimation(void) ldr r0, [r5]\n\ ldrb r0, [r0, 0x1]\n\ str r3, [sp]\n\ - bl GetBattleBank\n\ + bl GetBattlerForBattleScript\n\ ldr r2, =gActiveBattler\n\ strb r0, [r2]\n\ ldr r0, [r5]\n\ @@ -4870,7 +4810,6 @@ static void atk49_moveend(void) holdEffectAtk = ItemId_GetHoldEffect(gBattleMons[gBattlerAttacker].item); choicedMoveAtk = &gBattleStruct->choicedMove[gBattlerAttacker]; - GET_MOVE_TYPE(gCurrentMove, moveType); do @@ -4882,9 +4821,9 @@ static void atk49_moveend(void) && gBattleMons[gBattlerTarget].hp != 0 && gBattlerAttacker != gBattlerTarget && GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget) && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && TARGET_TURN_DAMAGED - && gBattleMoves[gCurrentMove].power && gBattleMons[gBattlerTarget].statStages[STAT_STAGE_ATK] <= 0xB) + && gBattleMoves[gCurrentMove].power && gBattleMons[gBattlerTarget].statStages[STAT_ATK] <= 0xB) { - gBattleMons[gBattlerTarget].statStages[STAT_STAGE_ATK]++; + gBattleMons[gBattlerTarget].statStages[STAT_ATK]++; BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_RageIsBuilding; effect = TRUE; @@ -4894,7 +4833,7 @@ static void atk49_moveend(void) case 1: // defrosting check if (gBattleMons[gBattlerTarget].status1 & STATUS1_FREEZE && gBattleMons[gBattlerTarget].hp != 0 && gBattlerAttacker != gBattlerTarget - && gSpecialStatuses[gBattlerTarget].moveturnLostHP_special + && gSpecialStatuses[gBattlerTarget].specialDmg && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && moveType == TYPE_FIRE) { gBattleMons[gBattlerTarget].status1 &= ~(STATUS1_FREEZE); @@ -4919,7 +4858,7 @@ static void atk49_moveend(void) break; case 4: // status immunities if (AbilityBattleEffects(ABILITYEFFECT_IMMUNITY, 0, 0, 0, 0)) - effect = TRUE; // it loops through all banks, so we increment after its done with all banks + effect = TRUE; // it loops through all battlers, so we increment after its done with all battlers else gBattleScripting.atk49_state++; break; @@ -4963,7 +4902,7 @@ static void atk49_moveend(void) } gBattleScripting.atk49_state++; break; - case 11: // item effects for all banks + case 11: // item effects for all battlers if (ItemBattleEffects(3, 0, FALSE)) effect = TRUE; else @@ -5097,10 +5036,10 @@ static void atk49_moveend(void) && !gProtectStructs[gBattlerAttacker].chargingTurn && gBattleMoves[gCurrentMove].target == MOVE_TARGET_BOTH && !(gHitMarker & HITMARKER_NO_ATTACKSTRING)) { - u8 bank = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerTarget))); - if (gBattleMons[bank].hp != 0) + u8 battlerId = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerTarget))); + if (gBattleMons[battlerId].hp != 0) { - gBattlerTarget = bank; + gBattlerTarget = battlerId; gHitMarker |= HITMARKER_NO_ATTACKSTRING; gBattleScripting.atk49_state = 0; MoveValuesCleanUp(); @@ -5241,7 +5180,7 @@ static void atk4C_getswitchedmondata(void) if (gBattleControllerExecFlags) return; - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); gBattlerPartyIndexes[gActiveBattler] = *(gBattleStruct->monToSwitchIntoId + gActiveBattler); @@ -5260,7 +5199,7 @@ static void atk4D_switchindataupdate(void) if (gBattleControllerExecFlags) return; - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); oldData = gBattleMons[gActiveBattler]; monData = (u8*)(&gBattleMons[gActiveBattler]); @@ -5309,7 +5248,7 @@ static void atk4E_switchinanim(void) if (gBattleControllerExecFlags) return; - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT && !(gBattleTypeFlags & (BATTLE_TYPE_LINK @@ -5337,7 +5276,7 @@ static void atk4F_jumpifcantswitch(void) struct Pokemon *party = NULL; s32 r7 = 0; - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1] & ~(ATK4F_DONT_CHECK_STATUSES)); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1] & ~(ATK4F_DONT_CHECK_STATUSES)); if (!(gBattlescriptCurrInstr[1] & ATK4F_DONT_CHECK_STATUSES) && ((gBattleMons[gActiveBattler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION)) @@ -5498,10 +5437,10 @@ static void atk50_openpartyscreen(void) { u32 flags; u8 hitmarkerFaintBits; - u8 bank; + u8 battlerId; const u8 *jumpPtr; - bank = 0; + battlerId = 0; flags = 0; jumpPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); @@ -5713,17 +5652,17 @@ static void atk50_openpartyscreen(void) hitmarkerFaintBits = gHitMarker >> 0x1C; - gBank1 = 0; + gBattlerFainted = 0; while (1) { - if (gBitTable[gBank1] & hitmarkerFaintBits) + if (gBitTable[gBattlerFainted] & hitmarkerFaintBits) break; - if (gBank1 >= gBattlersCount) + if (gBattlerFainted >= gBattlersCount) break; - gBank1++; + gBattlerFainted++; } - if (gBank1 == gBattlersCount) + if (gBattlerFainted == gBattlersCount) gBattlescriptCurrInstr = jumpPtr; } else @@ -5733,21 +5672,21 @@ static void atk50_openpartyscreen(void) else hitmarkerFaintBits = 1; - bank = GetBattleBank(gBattlescriptCurrInstr[1] & ~(0x80)); - if (gSpecialStatuses[bank].flag40) + battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1] & ~(0x80)); + if (gSpecialStatuses[battlerId].flag40) { gBattlescriptCurrInstr += 6; } - else if (sub_80423F4(bank, 6, 6)) + else if (sub_80423F4(battlerId, 6, 6)) { - gActiveBattler = bank; + gActiveBattler = battlerId; gAbsentBattlerFlags |= gBitTable[gActiveBattler]; gHitMarker &= ~(HITMARKER_FAINTED(gActiveBattler)); gBattlescriptCurrInstr = jumpPtr; } else { - gActiveBattler = bank; + gActiveBattler = battlerId; *(gBattleStruct->field_58 + gActiveBattler) = gBattlerPartyIndexes[gActiveBattler]; *(gBattleStruct->monToSwitchIntoId + gActiveBattler) = 6; gBattleStruct->field_93 &= ~(gBitTable[gActiveBattler]); @@ -5764,7 +5703,7 @@ static void atk50_openpartyscreen(void) { for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) { - if (gActiveBattler != bank) + if (gActiveBattler != battlerId) { BtlController_EmitLinkStandbyMsg(0, 2, 0); MarkBattlerForControllerExec(gActiveBattler); @@ -5773,7 +5712,7 @@ static void atk50_openpartyscreen(void) } else { - gActiveBattler = GetBattlerAtPosition(GetBattlerPosition(bank) ^ BIT_SIDE); + gActiveBattler = GetBattlerAtPosition(GetBattlerPosition(battlerId) ^ BIT_SIDE); if (gAbsentBattlerFlags & gBitTable[gActiveBattler]) gActiveBattler ^= BIT_FLANK; @@ -5790,7 +5729,7 @@ static void atk51_switchhandleorder(void) if (gBattleControllerExecFlags) return; - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); switch (gBattlescriptCurrInstr[2]) { @@ -5855,7 +5794,7 @@ static void atk52_switchineffects(void) { s32 i; - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); sub_803FA70(gActiveBattler); gHitMarker &= ~(HITMARKER_FAINTED(gActiveBattler)); @@ -5882,12 +5821,12 @@ static void atk52_switchineffects(void) gBattleScripting.battler = gActiveBattler; BattleScriptPushCursor(); - if (gBattlescriptCurrInstr[1] == BS_GET_TARGET) + if (gBattlescriptCurrInstr[1] == BS_TARGET) gBattlescriptCurrInstr = BattleScript_SpikesOnTarget; - else if (gBattlescriptCurrInstr[1] == BS_GET_ATTACKER) + else if (gBattlescriptCurrInstr[1] == BS_ATTACKER) gBattlescriptCurrInstr = BattleScript_SpikesOnAttacker; else - gBattlescriptCurrInstr = BattleScript_SpikesOngBank1; + gBattlescriptCurrInstr = BattleScript_SpikesOnFaintedBattler; } else { @@ -5917,14 +5856,14 @@ static void atk52_switchineffects(void) { u32 hitmarkerFaintBits = gHitMarker >> 0x1C; - gBank1++; + gBattlerFainted++; while (1) { - if (hitmarkerFaintBits & gBitTable[gBank1] && !(gAbsentBattlerFlags & gBitTable[gBank1])) + if (hitmarkerFaintBits & gBitTable[gBattlerFainted] && !(gAbsentBattlerFlags & gBitTable[gBattlerFainted])) break; - if (gBank1 >= gBattlersCount) + if (gBattlerFainted >= gBattlersCount) break; - gBank1++; + gBattlerFainted++; } } gBattlescriptCurrInstr += 2; @@ -5961,7 +5900,7 @@ static void atk55_fanfare(void) static void atk56_playfaintcry(void) { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); BtlController_EmitFaintingCry(0); MarkBattlerForControllerExec(gActiveBattler); @@ -5979,7 +5918,7 @@ static void atk57(void) static void atk58_returntoball(void) { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); BtlController_EmitReturnMonToBall(0, 1); MarkBattlerForControllerExec(gActiveBattler); @@ -5991,9 +5930,9 @@ static void atk59_handlelearnnewmove(void) const u8 *jumpPtr1 = BSScriptReadPtr(gBattlescriptCurrInstr + 1); const u8 *jumpPtr2 = BSScriptReadPtr(gBattlescriptCurrInstr + 5); - u16 ret = MonTryLearningNewMove(&gPlayerParty[gBattleStruct->expGetterId], gBattlescriptCurrInstr[9]); + u16 ret = MonTryLearningNewMove(&gPlayerParty[gBattleStruct->expGetterMonId], gBattlescriptCurrInstr[9]); while (ret == 0xFFFE) - ret = MonTryLearningNewMove(&gPlayerParty[gBattleStruct->expGetterId], 0); + ret = MonTryLearningNewMove(&gPlayerParty[gBattleStruct->expGetterMonId], 0); if (ret == 0) { @@ -6007,7 +5946,7 @@ static void atk59_handlelearnnewmove(void) { gActiveBattler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); - if (gBattlerPartyIndexes[gActiveBattler] == gBattleStruct->expGetterId + if (gBattlerPartyIndexes[gActiveBattler] == gBattleStruct->expGetterMonId && !(gBattleMons[gActiveBattler].status2 & STATUS2_TRANSFORMED)) { GiveMoveToBattleMon(&gBattleMons[gActiveBattler], ret); @@ -6015,7 +5954,7 @@ static void atk59_handlelearnnewmove(void) if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) { gActiveBattler = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT); - if (gBattlerPartyIndexes[gActiveBattler] == gBattleStruct->expGetterId + if (gBattlerPartyIndexes[gActiveBattler] == gBattleStruct->expGetterMonId && !(gBattleMons[gActiveBattler].status2 & STATUS2_TRANSFORMED)) { GiveMoveToBattleMon(&gBattleMons[gActiveBattler], ret); @@ -6078,7 +6017,7 @@ static void atk5A_yesnoboxlearnmove(void) if (!gPaletteFade.active) { FreeAllWindowBuffers(); - sub_81BFA38(gPlayerParty, gBattleStruct->expGetterId, gPlayerPartyCount - 1, ReshowBattleScreenAfterMenu, gMoveToLearn); + sub_81BFA38(gPlayerParty, gBattleStruct->expGetterMonId, gPlayerPartyCount - 1, ReshowBattleScreenAfterMenu, gMoveToLearn); gBattleScripting.learnMoveState++; } break; @@ -6098,7 +6037,7 @@ static void atk5A_yesnoboxlearnmove(void) } else { - u16 moveId = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_MOVE1 + movePosition); + u16 moveId = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_MOVE1 + movePosition); if (IsHMMove2(moveId)) { PrepareStringBattle(STRINGID_HMMOVESCANTBEFORGOTTEN, gActiveBattler); @@ -6110,10 +6049,10 @@ static void atk5A_yesnoboxlearnmove(void) PREPARE_MOVE_BUFFER(gBattleTextBuff2, moveId) - RemoveMonPPBonus(&gPlayerParty[gBattleStruct->expGetterId], movePosition); - SetMonMoveSlot(&gPlayerParty[gBattleStruct->expGetterId], gMoveToLearn, movePosition); + RemoveMonPPBonus(&gPlayerParty[gBattleStruct->expGetterMonId], movePosition); + SetMonMoveSlot(&gPlayerParty[gBattleStruct->expGetterMonId], gMoveToLearn, movePosition); - if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterId + if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterMonId && !(gBattleMons[0].status2 & STATUS2_TRANSFORMED) && !(gDisableStructs[0].unk18_b & gBitTable[movePosition])) { @@ -6121,7 +6060,7 @@ static void atk5A_yesnoboxlearnmove(void) SetBattleMonMoveSlot(&gBattleMons[0], gMoveToLearn, movePosition); } if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE - && gBattlerPartyIndexes[2] == gBattleStruct->expGetterId + && gBattlerPartyIndexes[2] == gBattleStruct->expGetterMonId && !(gBattleMons[2].status2 & STATUS2_TRANSFORMED) && !(gDisableStructs[2].unk18_b & gBitTable[movePosition])) { @@ -6194,7 +6133,7 @@ static void atk5B_yesnoboxstoplearningmove(void) static void atk5C_hitanimation(void) { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT) { @@ -6284,7 +6223,7 @@ static void atk5D_getmoneyreward(void) static void atk5E(void) { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); switch (gBattleCommunication[0]) { @@ -6340,7 +6279,7 @@ static void atk61_drawpartystatussummary(void) if (gBattleControllerExecFlags) return; - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) party = gPlayerParty; @@ -6370,7 +6309,7 @@ static void atk61_drawpartystatussummary(void) static void atk62(void) { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); BtlController_EmitCmd49(0); MarkBattlerForControllerExec(gActiveBattler); @@ -6391,7 +6330,7 @@ static void atk64_statusanimation(void) { if (gBattleControllerExecFlags == 0) { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); if (!(gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE) && gDisableStructs[gActiveBattler].substituteHP == 0 && !(gHitMarker & HITMARKER_NO_ANIMATIONS)) @@ -6409,7 +6348,7 @@ static void atk65_status2animation(void) if (gBattleControllerExecFlags == 0) { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); wantedToAnimate = BSScriptRead32(gBattlescriptCurrInstr + 2); if (!(gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE) && gDisableStructs[gActiveBattler].substituteHP == 0 @@ -6428,7 +6367,7 @@ static void atk66_chosenstatusanimation(void) if (gBattleControllerExecFlags == 0) { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); wantedStatus = BSScriptRead32(gBattlescriptCurrInstr + 3); if (!(gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE) && gDisableStructs[gActiveBattler].substituteHP == 0 @@ -6496,21 +6435,22 @@ static void atk68_cancelallactions(void) static void atk69_adjustsetdamage(void) // The same as 0x7, except there's no random damage multiplier. { - u8 holdEffect, quality; + u8 holdEffect, param; if (gBattleMons[gBattlerTarget].item == ITEM_ENIGMA_BERRY) { - holdEffect = gEnigmaBerries[gBattlerTarget].holdEffect, quality = gEnigmaBerries[gBattlerTarget].holdEffectParam; + holdEffect = gEnigmaBerries[gBattlerTarget].holdEffect; + param = gEnigmaBerries[gBattlerTarget].holdEffectParam; } else { holdEffect = ItemId_GetHoldEffect(gBattleMons[gBattlerTarget].item); - quality = ItemId_GetHoldEffectParam(gBattleMons[gBattlerTarget].item); + param = ItemId_GetHoldEffectParam(gBattleMons[gBattlerTarget].item); } - gStringBattler = gBattlerTarget; + gPotentialItemEffectBattler = gBattlerTarget; - if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < quality) + if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < param) { RecordItemEffectBattle(gBattlerTarget, holdEffect); gSpecialStatuses[gBattlerTarget].focusBanded = 1; @@ -6544,7 +6484,7 @@ static void atk6A_removeitem(void) { u16* usedHeldItem; - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); usedHeldItem = &gBattleStruct->usedHeldItems[gActiveBattler]; *usedHeldItem = gBattleMons[gActiveBattler].item; @@ -6659,7 +6599,7 @@ static void sub_804F100(void) { struct StatsArray currentStats; - sub_81D388C(&gPlayerParty[gBattleStruct->expGetterId], ¤tStats); + sub_81D388C(&gPlayerParty[gBattleStruct->expGetterMonId], ¤tStats); sub_81D3640(0xD, gBattleResources->statsBeforeLvlUp, ¤tStats, 0xE, 0xD, 0xF); } @@ -6667,7 +6607,7 @@ static void sub_804F144(void) { struct StatsArray currentStats; - sub_81D388C(&gPlayerParty[gBattleStruct->expGetterId], ¤tStats); + sub_81D388C(&gPlayerParty[gBattleStruct->expGetterMonId], ¤tStats); sub_81D3784(0xD, ¤tStats, 0xE, 0xD, 0xF); } @@ -6710,9 +6650,9 @@ static void PutLevelAndGenderOnLvlUpBox(void) u8 *txtPtr; u32 var; - monLevel = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_LEVEL); - monGender = GetMonGender(&gPlayerParty[gBattleStruct->expGetterId]); - GetMonNickname(&gPlayerParty[gBattleStruct->expGetterId], gStringVar4); + monLevel = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_LEVEL); + monGender = GetMonGender(&gPlayerParty[gBattleStruct->expGetterMonId]); + GetMonNickname(&gPlayerParty[gBattleStruct->expGetterMonId], gStringVar4); subPrinter.current_text_offset = gStringVar4; subPrinter.windowId = 14; @@ -6788,8 +6728,8 @@ static void PutMonIconOnLvlUpBox(void) struct SpriteSheet iconSheet; struct SpritePalette iconPalSheet; - u16 species = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_SPECIES); - u32 personality = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_PERSONALITY); + u16 species = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_SPECIES); + u32 personality = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_PERSONALITY); const u8* iconPtr = GetMonIconPtr(species, personality, 1); iconSheet.data = iconPtr; @@ -6829,9 +6769,9 @@ static void SpriteCB_MonIconOnLvlUpBox(struct Sprite* sprite) static bool32 IsMonGettingExpSentOut(void) { - if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterId) + if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterMonId) return TRUE; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gBattlerPartyIndexes[2] == gBattleStruct->expGetterId) + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gBattlerPartyIndexes[2] == gBattleStruct->expGetterMonId) return TRUE; return FALSE; @@ -6851,7 +6791,7 @@ static void atk6E_setatktoplayer0(void) static void atk6F_makevisible(void) { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); BtlController_EmitSpriteInvisibility(0, FALSE); MarkBattlerForControllerExec(gActiveBattler); @@ -6860,9 +6800,9 @@ static void atk6F_makevisible(void) static void atk70_recordlastability(void) { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); RecordAbilityBattle(gActiveBattler, gLastUsedAbility); - gBattlescriptCurrInstr += 1; // UB: Should be + 2, one byte for command and one byte for bank argument. + gBattlescriptCurrInstr += 1; // UB: Should be + 2, one byte for command and one byte for battlerId argument. } void BufferMoveToLearnIntoBattleTextBuff2(void) @@ -6878,7 +6818,7 @@ static void atk71_buffermovetolearn(void) static void atk72_jumpifplayerran(void) { - if (TryRunFromBattle(gBank1)) + if (TryRunFromBattle(gBattlerFainted)) gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); else gBattlescriptCurrInstr += 5; @@ -6891,7 +6831,7 @@ static void atk73_hpthresholds(void) if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); opposingBank = gActiveBattler ^ BIT_SIDE; result = gBattleMons[opposingBank].hp * 100 / gBattleMons[opposingBank].maxHP; @@ -6919,7 +6859,7 @@ static void atk74_hpthresholds2(void) if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); opposingBank = gActiveBattler ^ BIT_SIDE; hpSwitchout = *(gBattleStruct->hpOnSwitchout + GetBattlerSide(opposingBank)); result = (hpSwitchout - gBattleMons[opposingBank].hp) * 100 / hpSwitchout; @@ -6939,9 +6879,8 @@ static void atk74_hpthresholds2(void) static void atk75_useitemonopponent(void) { - gBankInMenu = gBattlerAttacker; - ExecuteTableBasedItemEffect(&gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker]], gLastUsedItem, gBattlerPartyIndexes[gBattlerAttacker], 0, 1); - + gBattlerInMenuId = gBattlerAttacker; + PokemonUseItemEffects(&gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker]], gLastUsedItem, gBattlerPartyIndexes[gBattlerAttacker], 0, 1); gBattlescriptCurrInstr += 1; } @@ -6950,7 +6889,7 @@ static void atk76_various(void) u8 side; s32 i; - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); switch (gBattlescriptCurrInstr[2]) { @@ -6982,11 +6921,11 @@ static void atk76_various(void) gSpecialStatuses[gActiveBattler].traced = 0; break; case VARIOUS_UPDATE_CHOICE_MOVE_ON_LVL_UP: - if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterId || gBattlerPartyIndexes[2] == gBattleStruct->expGetterId) + if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterMonId || gBattlerPartyIndexes[2] == gBattleStruct->expGetterMonId) { u16 *choicedMove; - if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterId) + if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterMonId) gActiveBattler = 0; else gActiveBattler = 2; @@ -7113,7 +7052,7 @@ static void atk76_various(void) if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) gBattleOutcome = B_OUTCOME_PLAYER_TELEPORTED; else - gBattleOutcome = B_OUTCOME_POKE_TELEPORTED; + gBattleOutcome = B_OUTCOME_MON_TELEPORTED; break; case VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC: BtlController_EmitPlayFanfareOrBGM(0, MUS_KACHI1, TRUE); @@ -7236,7 +7175,7 @@ static void atk7B_tryhealhalfhealth(void) { const u8* failPtr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); - if (gBattlescriptCurrInstr[5] == BS_GET_ATTACKER) + if (gBattlescriptCurrInstr[5] == BS_ATTACKER) gBattlerTarget = gBattlerAttacker; gBattleMoveDamage = gBattleMons[gBattlerTarget].maxHP / 2; @@ -7327,7 +7266,7 @@ static void atk7E_setreflect(void) { gSideStatuses[GET_BATTLER_SIDE(gBattlerAttacker)] |= SIDE_STATUS_REFLECT; gSideTimers[GET_BATTLER_SIDE(gBattlerAttacker)].reflectTimer = 5; - gSideTimers[GET_BATTLER_SIDE(gBattlerAttacker)].reflectBank = gBattlerAttacker; + gSideTimers[GET_BATTLER_SIDE(gBattlerAttacker)].reflectBattlerId = gBattlerAttacker; if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && CountAliveMonsInBattle(BATTLE_ALIVE_ATK_SIDE) == 2) gBattleCommunication[MULTISTRING_CHOOSER] = 2; @@ -7420,13 +7359,13 @@ static void atk83_nop(void) gBattlescriptCurrInstr++; } -bool8 UproarWakeUpCheck(u8 bank) +bool8 UproarWakeUpCheck(u8 battlerId) { s32 i; for (i = 0; i < gBattlersCount; i++) { - if (!(gBattleMons[i].status2 & STATUS2_UPROAR) || gBattleMons[bank].ability == ABILITY_SOUNDPROOF) + if (!(gBattleMons[i].status2 & STATUS2_UPROAR) || gBattleMons[battlerId].ability == ABILITY_SOUNDPROOF) continue; gBattleScripting.battler = i; @@ -7626,7 +7565,7 @@ static u8 ChangeStatBuffs(s8 statValue, u8 statId, u8 flags, const u8 *BS_ptr) return STAT_CHANGE_DIDNT_WORK; } else if (gBattleMons[gActiveBattler].ability == ABILITY_KEEN_EYE - && !certain && statId == STAT_STAGE_ACC) + && !certain && statId == STAT_ACC) { if (flags == STAT_CHANGE_BS_PTR) { @@ -7639,7 +7578,7 @@ static u8 ChangeStatBuffs(s8 statValue, u8 statId, u8 flags, const u8 *BS_ptr) return STAT_CHANGE_DIDNT_WORK; } else if (gBattleMons[gActiveBattler].ability == ABILITY_HYPER_CUTTER - && !certain && statId == STAT_STAGE_ATK) + && !certain && statId == STAT_ATK) { if (flags == STAT_CHANGE_BS_PTR) { @@ -7810,8 +7749,8 @@ static bool8 TryDoForceSwitchOut(void) static void atk8F_forcerandomswitch(void) { s32 i; - s32 bank1PartyId = 0; - s32 bank2PartyId = 0; + s32 battler1PartyId = 0; + s32 battler2PartyId = 0; #ifdef NONMATCHING s32 lastMonId = 0; // + 1 @@ -7848,8 +7787,8 @@ static void atk8F_forcerandomswitch(void) } monsCount = 3; minNeeded = 1; - bank2PartyId = gBattlerPartyIndexes[gBattlerTarget]; - bank1PartyId = gBattlerPartyIndexes[gBattlerTarget ^ BIT_FLANK]; + battler2PartyId = gBattlerPartyIndexes[gBattlerTarget]; + battler1PartyId = gBattlerPartyIndexes[gBattlerTarget ^ BIT_FLANK]; } else if ((gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_LINK) || (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_x2000000)) @@ -7866,8 +7805,8 @@ static void atk8F_forcerandomswitch(void) } monsCount = 3; minNeeded = 1; - bank2PartyId = gBattlerPartyIndexes[gBattlerTarget]; - bank1PartyId = gBattlerPartyIndexes[gBattlerTarget ^ BIT_FLANK]; + battler2PartyId = gBattlerPartyIndexes[gBattlerTarget]; + battler1PartyId = gBattlerPartyIndexes[gBattlerTarget ^ BIT_FLANK]; } else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) { @@ -7893,8 +7832,8 @@ static void atk8F_forcerandomswitch(void) monsCount = 3; minNeeded = 1; } - bank2PartyId = gBattlerPartyIndexes[gBattlerTarget]; - bank1PartyId = gBattlerPartyIndexes[gBattlerTarget ^ BIT_FLANK]; + battler2PartyId = gBattlerPartyIndexes[gBattlerTarget]; + battler1PartyId = gBattlerPartyIndexes[gBattlerTarget ^ BIT_FLANK]; } else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) { @@ -7902,8 +7841,8 @@ static void atk8F_forcerandomswitch(void) lastMonId = 6; monsCount = 6; minNeeded = 2; - bank2PartyId = gBattlerPartyIndexes[gBattlerTarget]; - bank1PartyId = gBattlerPartyIndexes[gBattlerTarget ^ BIT_FLANK]; + battler2PartyId = gBattlerPartyIndexes[gBattlerTarget]; + battler1PartyId = gBattlerPartyIndexes[gBattlerTarget ^ BIT_FLANK]; } else { @@ -7911,8 +7850,8 @@ static void atk8F_forcerandomswitch(void) lastMonId = 6; monsCount = 6; minNeeded = 1; - bank2PartyId = gBattlerPartyIndexes[gBattlerTarget]; // there is only one pokemon out in single battles - bank1PartyId = gBattlerPartyIndexes[gBattlerTarget]; + battler2PartyId = gBattlerPartyIndexes[gBattlerTarget]; // there is only one pokemon out in single battles + battler1PartyId = gBattlerPartyIndexes[gBattlerTarget]; } for (i = firstMonId; i < lastMonId; i++) @@ -7938,8 +7877,8 @@ static void atk8F_forcerandomswitch(void) i = Random() % monsCount; i += firstMonId; } - while (i == bank2PartyId - || i == bank1PartyId + while (i == battler2PartyId + || i == battler1PartyId || GetMonData(&party[i], MON_DATA_SPECIES) == SPECIES_NONE || GetMonData(&party[i], MON_DATA_IS_EGG) == TRUE || GetMonData(&party[i], MON_DATA_HP) == 0); @@ -8061,7 +8000,7 @@ static void atk92_setlightscreen(void) { gSideStatuses[GET_BATTLER_SIDE(gBattlerAttacker)] |= SIDE_STATUS_LIGHTSCREEN; gSideTimers[GET_BATTLER_SIDE(gBattlerAttacker)].lightscreenTimer = 5; - gSideTimers[GET_BATTLER_SIDE(gBattlerAttacker)].lightscreenBank = gBattlerAttacker; + gSideTimers[GET_BATTLER_SIDE(gBattlerAttacker)].lightscreenBattlerId = gBattlerAttacker; if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && CountAliveMonsInBattle(BATTLE_ALIVE_ATK_SIDE) == 2) gBattleCommunication[MULTISTRING_CHOOSER] = 4; @@ -8087,7 +8026,7 @@ static void atk93_tryKO(void) param = ItemId_GetHoldEffectParam(gBattleMons[gBattlerTarget].item); } - gStringBattler = gBattlerTarget; + gPotentialItemEffectBattler = gBattlerTarget; if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < param) { @@ -8288,7 +8227,7 @@ static void atk98_updatestatusicon(void) if (gBattlescriptCurrInstr[1] != BS_ATTACKER_WITH_PARTNER) { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); BtlController_EmitStatusIconUpdate(0, gBattleMons[gActiveBattler].status1, gBattleMons[gActiveBattler].status2); MarkBattlerForControllerExec(gActiveBattler); gBattlescriptCurrInstr += 2; @@ -8324,7 +8263,7 @@ static void atk99_setmist(void) else { gSideTimers[GET_BATTLER_SIDE(gBattlerAttacker)].mistTimer = 5; - gSideTimers[GET_BATTLER_SIDE(gBattlerAttacker)].mistBank = gBattlerAttacker; + gSideTimers[GET_BATTLER_SIDE(gBattlerAttacker)].mistBattlerId = gBattlerAttacker; gSideStatuses[GET_BATTLER_SIDE(gBattlerAttacker)] |= SIDE_STATUS_MIST; gBattleCommunication[MULTISTRING_CHOOSER] = 0; } @@ -8520,18 +8459,18 @@ static void atkA0_psywavedamageeffect(void) static void atkA1_counterdamagecalculator(void) { u8 sideAttacker = GetBattlerSide(gBattlerAttacker); - u8 sideTarget = GetBattlerSide(gProtectStructs[gBattlerAttacker].physicalBank); + u8 sideTarget = GetBattlerSide(gProtectStructs[gBattlerAttacker].physicalBattlerId); if (gProtectStructs[gBattlerAttacker].physicalDmg && sideAttacker != sideTarget - && gBattleMons[gProtectStructs[gBattlerAttacker].physicalBank].hp) + && gBattleMons[gProtectStructs[gBattlerAttacker].physicalBattlerId].hp) { gBattleMoveDamage = gProtectStructs[gBattlerAttacker].physicalDmg * 2; if (gSideTimers[sideTarget].followmeTimer && gBattleMons[gSideTimers[sideTarget].followmeTarget].hp) gBattlerTarget = gSideTimers[sideTarget].followmeTarget; else - gBattlerTarget = gProtectStructs[gBattlerAttacker].physicalBank; + gBattlerTarget = gProtectStructs[gBattlerAttacker].physicalBattlerId; gBattlescriptCurrInstr += 5; } @@ -8545,16 +8484,16 @@ static void atkA1_counterdamagecalculator(void) static void atkA2_mirrorcoatdamagecalculator(void) // a copy of atkA1 with the physical -> special field changes { u8 sideAttacker = GetBattlerSide(gBattlerAttacker); - u8 sideTarget = GetBattlerSide(gProtectStructs[gBattlerAttacker].specialBank); + u8 sideTarget = GetBattlerSide(gProtectStructs[gBattlerAttacker].specialBattlerId); - if (gProtectStructs[gBattlerAttacker].specialDmg && sideAttacker != sideTarget && gBattleMons[gProtectStructs[gBattlerAttacker].specialBank].hp) + if (gProtectStructs[gBattlerAttacker].specialDmg && sideAttacker != sideTarget && gBattleMons[gProtectStructs[gBattlerAttacker].specialBattlerId].hp) { gBattleMoveDamage = gProtectStructs[gBattlerAttacker].specialDmg * 2; if (gSideTimers[sideTarget].followmeTimer && gBattleMons[gSideTimers[sideTarget].followmeTarget].hp) gBattlerTarget = gSideTimers[sideTarget].followmeTarget; else - gBattlerTarget = gProtectStructs[gBattlerAttacker].specialBank; + gBattlerTarget = gProtectStructs[gBattlerAttacker].specialBattlerId; gBattlescriptCurrInstr += 5; } @@ -8636,7 +8575,7 @@ static void atkA5_painsplitdmgcalc(void) storeLoc[3] = (painSplitHp & 0xFF000000) >> 24; gBattleMoveDamage = gBattleMons[gBattlerAttacker].hp - hpDiff; - gSpecialStatuses[gBattlerTarget].moveturnLostHP = 0xFFFF; + gSpecialStatuses[gBattlerTarget].dmg = 0xFFFF; gBattlescriptCurrInstr += 5; } @@ -8795,7 +8734,7 @@ static bool8 IsInvalidForSleepTalkOrAssist(u16 move) return FALSE; } -static u8 AttacksThisTurn(u8 bank, u16 move) // Note: returns 1 if it's a charging turn, otherwise 2 +static u8 AttacksThisTurn(u8 battlerId, u16 move) // Note: returns 1 if it's a charging turn, otherwise 2 { // first argument is unused if (gBattleMoves[move].effect == EFFECT_SOLARBEAM @@ -9224,7 +9163,7 @@ static void atkB8_setsafeguard(void) { gSideStatuses[GET_BATTLER_SIDE(gBattlerAttacker)] |= SIDE_STATUS_SAFEGUARD; gSideTimers[GET_BATTLER_SIDE(gBattlerAttacker)].safeguardTimer = 5; - gSideTimers[GET_BATTLER_SIDE(gBattlerAttacker)].safeguardBank = gBattlerAttacker; + gSideTimers[GET_BATTLER_SIDE(gBattlerAttacker)].safeguardBattlerId = gBattlerAttacker; gBattleCommunication[MULTISTRING_CHOOSER] = 5; } @@ -9318,7 +9257,7 @@ static void atkBA_jumpifnopursuitswitchdmg(void) } gCurrentMove = MOVE_PURSUIT; - gCurrMovePos = gUnknown_020241E9 = *(gBattleStruct->chosenMovePositions + gBattlerTarget); + gCurrMovePos = gChosenMovePos = *(gBattleStruct->chosenMovePositions + gBattlerTarget); gBattlescriptCurrInstr += 5; gBattleScripting.animTurn = 1; gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); @@ -9353,10 +9292,10 @@ static void atkBC_maxattackhalvehp(void) // belly drum if (!(gBattleMons[gBattlerAttacker].maxHP / 2)) halfHp = 1; - if (gBattleMons[gBattlerAttacker].statStages[STAT_STAGE_ATK] < 12 + if (gBattleMons[gBattlerAttacker].statStages[STAT_ATK] < 12 && gBattleMons[gBattlerAttacker].hp > halfHp) { - gBattleMons[gBattlerAttacker].statStages[STAT_STAGE_ATK] = 12; + gBattleMons[gBattlerAttacker].statStages[STAT_ATK] = 12; gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 2; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; @@ -9480,7 +9419,7 @@ static void atkC1_hiddenpowercalc(void) } #else -__attribute__((naked)) +ASM_DIRECT static void atkC1_hiddenpowercalc(void) { asm(".syntax unified\n\ @@ -9776,8 +9715,8 @@ static void atkC8_sethail(void) static void atkC9_jumpifattackandspecialattackcannotfall(void) // memento { - if (gBattleMons[gBattlerTarget].statStages[STAT_STAGE_ATK] == 0 - && gBattleMons[gBattlerTarget].statStages[STAT_STAGE_SPATK] == 0 + if (gBattleMons[gBattlerTarget].statStages[STAT_ATK] == 0 + && gBattleMons[gBattlerTarget].statStages[STAT_SPATK] == 0 && gBattleCommunication[6] != 1) { gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); @@ -9995,7 +9934,7 @@ static void atkD4_trywish(void) if (gWishFutureKnock.wishCounter[gBattlerAttacker] == 0) { gWishFutureKnock.wishCounter[gBattlerAttacker] = 2; - gWishFutureKnock.wishUserID[gBattlerAttacker] = gBattlerPartyIndexes[gBattlerAttacker]; + gWishFutureKnock.wishMonId[gBattlerAttacker] = gBattlerPartyIndexes[gBattlerAttacker]; gBattlescriptCurrInstr += 6; } else @@ -10004,7 +9943,7 @@ static void atkD4_trywish(void) } break; case 1: // heal effect - PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattlerTarget, gWishFutureKnock.wishUserID[gBattlerTarget]) + PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattlerTarget, gWishFutureKnock.wishMonId[gBattlerTarget]) gBattleMoveDamage = gBattleMons[gBattlerTarget].maxHP / 2; if (gBattleMoveDamage == 0) @@ -10036,9 +9975,9 @@ static void atkD5_trysetroots(void) // ingrain static void atkD6_doubledamagedealtifdamaged(void) { if ((gProtectStructs[gBattlerAttacker].physicalDmg - && gProtectStructs[gBattlerAttacker].physicalBank == gBattlerTarget) + && gProtectStructs[gBattlerAttacker].physicalBattlerId == gBattlerTarget) || (gProtectStructs[gBattlerAttacker].specialDmg - && gProtectStructs[gBattlerAttacker].specialBank == gBattlerTarget)) + && gProtectStructs[gBattlerAttacker].specialBattlerId == gBattlerTarget)) { gBattleScripting.dmgMultiplier = 2; } @@ -10113,13 +10052,13 @@ static void atkDB_tryimprision(void) } else { - u8 bank, sideAttacker; + u8 battlerId, sideAttacker; sideAttacker = GetBattlerSide(gBattlerAttacker); PressurePPLoseOnUsingImprision(gBattlerAttacker); - for (bank = 0; bank < gBattlersCount; bank++) + for (battlerId = 0; battlerId < gBattlersCount; battlerId++) { - if (sideAttacker != GetBattlerSide(bank)) + if (sideAttacker != GetBattlerSide(battlerId)) { s32 attackerMoveId; for (attackerMoveId = 0; attackerMoveId < 4; attackerMoveId++) @@ -10127,7 +10066,7 @@ static void atkDB_tryimprision(void) s32 i; for (i = 0; i < 4; i++) { - if (gBattleMons[gBattlerAttacker].moves[attackerMoveId] == gBattleMons[bank].moves[i] + if (gBattleMons[gBattlerAttacker].moves[attackerMoveId] == gBattleMons[battlerId].moves[i] && gBattleMons[gBattlerAttacker].moves[attackerMoveId] != MOVE_NONE) break; } @@ -10142,7 +10081,7 @@ static void atkDB_tryimprision(void) } } } - if (bank == gBattlersCount) // In Generation 3 games, Imprison fails if the user doesn't share any moves with any of the foes + if (battlerId == gBattlersCount) // In Generation 3 games, Imprison fails if the user doesn't share any moves with any of the foes gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1); } } @@ -10284,7 +10223,7 @@ static void atkE1_trygetintimidatetarget(void) static void atkE2_switchoutabilities(void) { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); switch (gBattleMons[gActiveBattler].ability) { @@ -10300,7 +10239,7 @@ static void atkE2_switchoutabilities(void) static void atkE3_jumpifhasnohp(void) { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); if (gBattleMons[gActiveBattler].hp == 0) gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 2); @@ -10560,14 +10499,14 @@ static void atkEC_pursuitrelated(void) static void atkEF_snatchsetbanks(void) { - gEffectBank = gBattlerAttacker; + gEffectBattler = gBattlerAttacker; if (gBattlerAttacker == gBattlerTarget) gBattlerAttacker = gBattlerTarget = gBattleScripting.battler; else gBattlerTarget = gBattleScripting.battler; - gBattleScripting.battler = gEffectBank; + gBattleScripting.battler = gEffectBattler; gBattlescriptCurrInstr++; } diff --git a/src/battle_setup.c b/src/battle_setup.c index 96af536fe..fdf6e77b6 100644 --- a/src/battle_setup.c +++ b/src/battle_setup.c @@ -5,7 +5,6 @@ #include "battle_transition.h" #include "main.h" #include "task.h" -#include "pokemon_3.h" #include "safari_zone.h" #include "script.h" #include "constants/game_stat.h" @@ -30,6 +29,8 @@ #include "strings.h" #include "secret_base.h" #include "string_util.h" +#include "overworld.h" +#include "field_weather.h" enum { @@ -59,14 +60,11 @@ extern void sub_81BE72C(void); extern void FreezeMapObjects(void); extern void sub_808BCF4(void); extern void sub_80EECC8(void); -extern void c2_exit_to_overworld_1_continue_scripts_restart_music(void); -extern void c2_exit_to_overworld_2_switch(void); extern void Overworld_ClearSavedMusic(void); extern void CB2_WhiteOut(void); extern void sub_80AF6F0(void); extern void PlayBattleBGM(void); extern void sub_81DA57C(void); -extern u8 GetSav1Weather(void); extern u8 Overworld_GetFlashLevel(void); extern u16 sub_81A9AA8(u8 localId); extern u16 sub_81D6180(u8 localId); @@ -82,12 +80,6 @@ extern void sub_81D61E8(void); extern void sub_80982B8(void); extern void sub_81A9EDC(u16 a0); extern void sub_81D572C(u8 a0, u16 arg1); -extern void IncrementGameStat(u8 statId); -extern u32 GetGameStat(u8 statId); - -extern u32 gBattleTypeFlags; -extern u8 gBattleOutcome; -extern void (*gFieldCallback)(void); // this file's functions static void DoBattlePikeWildBattle(void); @@ -996,8 +988,8 @@ static bool32 IsPlayerDefeated(u32 battleOutcome) case B_OUTCOME_WON: case B_OUTCOME_RAN: case B_OUTCOME_PLAYER_TELEPORTED: - case B_OUTCOME_POKE_FLED: - case B_OUTCOME_CAUGHT_POKE: + case B_OUTCOME_MON_FLED: + case B_OUTCOME_CAUGHT: return FALSE; default: return FALSE; diff --git a/src/battle_transition.c b/src/battle_transition.c index 0ff8cd903..e0d208f23 100644 --- a/src/battle_transition.c +++ b/src/battle_transition.c @@ -61,9 +61,7 @@ extern u16 gBattle_BG0_Y; extern const struct OamData gFieldObjectBaseOam_32x32; -extern void c2_exit_to_overworld_2_switch(void); extern void sub_80AC3D0(void); -extern void ScanlineEffect_Clear(void); // this file's functions static void LaunchBattleTransitionTask(u8 transitionId); diff --git a/src/battle_util.c b/src/battle_util.c index bbb4bf41d..a457ce15d 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1,5 +1,6 @@ #include "global.h" #include "battle.h" +#include "constants/battle_script_commands.h" #include "constants/abilities.h" #include "constants/moves.h" #include "constants/hold_effects.h" @@ -15,53 +16,13 @@ #include "text.h" #include "string_util.h" #include "battle_message.h" -#include "battle_string_ids.h" +#include "constants/battle_string_ids.h" #include "battle_ai_script_commands.h" #include "battle_controllers.h" #include "event_data.h" -#include "calculate_base_damage.h" #include "link.h" #include "berry.h" -extern const u8* gBattlescriptCurrInstr; -extern const u8* gSelectionBattleScripts[MAX_BATTLERS_COUNT]; -extern const u8* gPalaceSelectionBattleScripts[MAX_BATTLERS_COUNT]; -extern struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT]; -extern u8 gActiveBattler; -extern u8 gStringBattler; -extern u16 gCurrentMove; -extern u16 gLastUsedItem; -extern u8 gBattlersCount; -extern u32 gStatuses3[MAX_BATTLERS_COUNT]; -extern u8 gBattlerAttacker; -extern u8 gBattlerTarget; -extern u8 gAbsentBattlerFlags; -extern u16 gBattleWeather; -extern u8 gBattleTurnOrder[MAX_BATTLERS_COUNT]; -extern u16 gSideStatuses[2]; -extern u8 gBattleCommunication[]; -extern void (*gBattleMainFunc)(void); -extern s32 gBattleMoveDamage; -extern struct BattleEnigmaBerry gEnigmaBerries[MAX_BATTLERS_COUNT]; -extern u8 gBattleBufferB[MAX_BATTLERS_COUNT][0x200]; -extern u32 gBattleTypeFlags; -extern u16 gLastMoves[MAX_BATTLERS_COUNT]; -extern u32 gHitMarker; -extern u8 gEffectBank; -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; -extern u8 gBank1; -extern u16 gChosenMoveByBattler[MAX_BATTLERS_COUNT]; -extern u8 gMoveResultFlags; -extern s32 gTakenDmg[MAX_BATTLERS_COUNT]; -extern u8 gTakenDmgBanks[MAX_BATTLERS_COUNT]; -extern u8 gLastUsedAbility; -extern u8 gCurrentActionFuncId; -extern u32 gBattleControllerExecFlags; -extern u16 gRandomMove; -extern u8 gCurrMovePos; -extern u8 gUnknown_020241E9; -extern u8 gSentPokesToOpponent[2]; - extern const struct BattleMove gBattleMoves[]; extern u8 weather_get_current(void); @@ -73,46 +34,46 @@ static const u16 sSoundMovesTable[] = MOVE_UPROAR, MOVE_METAL_SOUND, MOVE_GRASS_WHISTLE, MOVE_HYPER_VOICE, 0xFFFF }; -u8 GetBattleBank(u8 caseId) +u8 GetBattlerForBattleScript(u8 caseId) { u8 ret = 0; switch (caseId) { - case BS_GET_TARGET: + case BS_TARGET: ret = gBattlerTarget; break; - case BS_GET_ATTACKER: + case BS_ATTACKER: ret = gBattlerAttacker; break; - case BS_GET_EFFECT_BANK: - ret = gEffectBank; + case BS_EFFECT_BATTLER: + ret = gEffectBattler; break; - case BS_GET_BANK_0: + case BS_BANK_0: ret = 0; break; - case BS_GET_SCRIPTING_BANK: + case BS_SCRIPTING: ret = gBattleScripting.battler; break; - case BS_GET_gBank1: - ret = gBank1; + case BS_FAINTED: + ret = gBattlerFainted; break; case 5: - ret = gBank1; + ret = gBattlerFainted; break; case 4: case 6: case 8: case 9: - case BS_GET_PLAYER1: + case BS_PLAYER1: ret = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); break; - case BS_GET_OPPONENT1: + case BS_OPPONENT1: ret = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); break; - case BS_GET_PLAYER2: + case BS_PLAYER2: ret = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT); break; - case BS_GET_OPPONENT2: + case BS_OPPONENT2: ret = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); break; } @@ -421,7 +382,7 @@ u8 TrySetCantSelectMoveBattleScript(void) else holdEffect = ItemId_GetHoldEffect(gBattleMons[gActiveBattler].item); - gStringBattler = gActiveBattler; + gPotentialItemEffectBattler = gActiveBattler; if (holdEffect == HOLD_EFFECT_CHOICE_BAND && *choicedMove != 0 && *choicedMove != 0xFFFF && *choicedMove != move) { @@ -454,36 +415,36 @@ u8 TrySetCantSelectMoveBattleScript(void) return limitations; } -u8 CheckMoveLimitations(u8 bank, u8 unusableMoves, u8 check) +u8 CheckMoveLimitations(u8 battlerId, u8 unusableMoves, u8 check) { u8 holdEffect; - u16 *choicedMove = &gBattleStruct->choicedMove[bank]; + u16 *choicedMove = &gBattleStruct->choicedMove[battlerId]; s32 i; - if (gBattleMons[bank].item == ITEM_ENIGMA_BERRY) - holdEffect = gEnigmaBerries[bank].holdEffect; + if (gBattleMons[battlerId].item == ITEM_ENIGMA_BERRY) + holdEffect = gEnigmaBerries[battlerId].holdEffect; else - holdEffect = ItemId_GetHoldEffect(gBattleMons[bank].item); + holdEffect = ItemId_GetHoldEffect(gBattleMons[battlerId].item); - gStringBattler = bank; + gPotentialItemEffectBattler = battlerId; for (i = 0; i < MAX_BATTLERS_COUNT; i++) { - if (gBattleMons[bank].moves[i] == 0 && check & MOVE_LIMITATION_ZEROMOVE) + if (gBattleMons[battlerId].moves[i] == 0 && check & MOVE_LIMITATION_ZEROMOVE) unusableMoves |= gBitTable[i]; - if (gBattleMons[bank].pp[i] == 0 && check & MOVE_LIMITATION_PP) + if (gBattleMons[battlerId].pp[i] == 0 && check & MOVE_LIMITATION_PP) unusableMoves |= gBitTable[i]; - if (gBattleMons[bank].moves[i] == gDisableStructs[bank].disabledMove && check & MOVE_LIMITATION_DISABLED) + if (gBattleMons[battlerId].moves[i] == gDisableStructs[battlerId].disabledMove && check & MOVE_LIMITATION_DISABLED) unusableMoves |= gBitTable[i]; - if (gBattleMons[bank].moves[i] == gLastMoves[bank] && check & MOVE_LIMITATION_TORMENTED && gBattleMons[bank].status2 & STATUS2_TORMENT) + if (gBattleMons[battlerId].moves[i] == gLastMoves[battlerId] && check & MOVE_LIMITATION_TORMENTED && gBattleMons[battlerId].status2 & STATUS2_TORMENT) unusableMoves |= gBitTable[i]; - if (gDisableStructs[bank].tauntTimer1 && check & MOVE_LIMITATION_TAUNT && gBattleMoves[gBattleMons[bank].moves[i]].power == 0) + if (gDisableStructs[battlerId].tauntTimer1 && check & MOVE_LIMITATION_TAUNT && gBattleMoves[gBattleMons[battlerId].moves[i]].power == 0) unusableMoves |= gBitTable[i]; - if (GetImprisonedMovesCount(bank, gBattleMons[bank].moves[i]) && check & MOVE_LIMITATION_IMPRISION) + if (GetImprisonedMovesCount(battlerId, gBattleMons[battlerId].moves[i]) && check & MOVE_LIMITATION_IMPRISION) unusableMoves |= gBitTable[i]; - if (gDisableStructs[bank].encoreTimer1 && gDisableStructs[bank].encoredMove != gBattleMons[bank].moves[i]) + if (gDisableStructs[battlerId].encoreTimer1 && gDisableStructs[battlerId].encoredMove != gBattleMons[battlerId].moves[i]) unusableMoves |= gBitTable[i]; - if (holdEffect == HOLD_EFFECT_CHOICE_BAND && *choicedMove != 0 && *choicedMove != 0xFFFF && *choicedMove != gBattleMons[bank].moves[i]) + if (holdEffect == HOLD_EFFECT_CHOICE_BAND && *choicedMove != 0 && *choicedMove != 0xFFFF && *choicedMove != gBattleMons[battlerId].moves[i]) unusableMoves |= gBitTable[i]; } return unusableMoves; @@ -507,11 +468,11 @@ bool8 AreAllMovesUnusable(void) return (unusable == 0xF); } -u8 GetImprisonedMovesCount(u8 bank, u16 move) +u8 GetImprisonedMovesCount(u8 battlerId, u16 move) { s32 i; u8 imprisionedMoves = 0; - u8 bankSide = GetBattlerSide(bank); + u8 bankSide = GetBattlerSide(battlerId); for (i = 0; i < gBattlersCount; i++) { @@ -547,7 +508,7 @@ u8 UpdateTurnCounters(void) { u8 sideBank; - switch (gBattleStruct->turncountersTracker) + switch (gBattleStruct->turnCountersTracker) { case 0: for (i = 0; i < gBattlersCount; i++) @@ -566,7 +527,7 @@ u8 UpdateTurnCounters(void) // It's stupid, but won't match without it { - u8* var = &gBattleStruct->turncountersTracker; + u8* var = &gBattleStruct->turnCountersTracker; (*var)++; gBattleStruct->turnSideTracker = 0; } @@ -575,7 +536,7 @@ u8 UpdateTurnCounters(void) while (gBattleStruct->turnSideTracker < 2) { sideBank = gBattleStruct->turnSideTracker; - gActiveBattler = gBattlerAttacker = gSideTimers[sideBank].reflectBank; + gActiveBattler = gBattlerAttacker = gSideTimers[sideBank].reflectBattlerId; if (gSideStatuses[sideBank] & SIDE_STATUS_REFLECT) { if (--gSideTimers[sideBank].reflectTimer == 0) @@ -592,7 +553,7 @@ u8 UpdateTurnCounters(void) } if (!effect) { - gBattleStruct->turncountersTracker++; + gBattleStruct->turnCountersTracker++; gBattleStruct->turnSideTracker = 0; } break; @@ -600,7 +561,7 @@ u8 UpdateTurnCounters(void) while (gBattleStruct->turnSideTracker < 2) { sideBank = gBattleStruct->turnSideTracker; - gActiveBattler = gBattlerAttacker = gSideTimers[sideBank].lightscreenBank; + gActiveBattler = gBattlerAttacker = gSideTimers[sideBank].lightscreenBattlerId; if (gSideStatuses[sideBank] & SIDE_STATUS_LIGHTSCREEN) { if (--gSideTimers[sideBank].lightscreenTimer == 0) @@ -618,7 +579,7 @@ u8 UpdateTurnCounters(void) } if (!effect) { - gBattleStruct->turncountersTracker++; + gBattleStruct->turnCountersTracker++; gBattleStruct->turnSideTracker = 0; } break; @@ -626,7 +587,7 @@ u8 UpdateTurnCounters(void) while (gBattleStruct->turnSideTracker < 2) { sideBank = gBattleStruct->turnSideTracker; - gActiveBattler = gBattlerAttacker = gSideTimers[sideBank].mistBank; + gActiveBattler = gBattlerAttacker = gSideTimers[sideBank].mistBattlerId; if (gSideTimers[sideBank].mistTimer != 0 && --gSideTimers[sideBank].mistTimer == 0) { @@ -642,7 +603,7 @@ u8 UpdateTurnCounters(void) } if (!effect) { - gBattleStruct->turncountersTracker++; + gBattleStruct->turnCountersTracker++; gBattleStruct->turnSideTracker = 0; } break; @@ -650,7 +611,7 @@ u8 UpdateTurnCounters(void) while (gBattleStruct->turnSideTracker < 2) { sideBank = gBattleStruct->turnSideTracker; - gActiveBattler = gBattlerAttacker = gSideTimers[sideBank].safeguardBank; + gActiveBattler = gBattlerAttacker = gSideTimers[sideBank].safeguardBattlerId; if (gSideStatuses[sideBank] & SIDE_STATUS_SAFEGUARD) { if (--gSideTimers[sideBank].safeguardTimer == 0) @@ -666,7 +627,7 @@ u8 UpdateTurnCounters(void) } if (!effect) { - gBattleStruct->turncountersTracker++; + gBattleStruct->turnCountersTracker++; gBattleStruct->turnSideTracker = 0; } break; @@ -688,7 +649,7 @@ u8 UpdateTurnCounters(void) } if (!effect) { - gBattleStruct->turncountersTracker++; + gBattleStruct->turnCountersTracker++; } break; case 6: @@ -719,7 +680,7 @@ u8 UpdateTurnCounters(void) BattleScriptExecute(BattleScript_RainContinuesOrEnds); effect++; } - gBattleStruct->turncountersTracker++; + gBattleStruct->turnCountersTracker++; break; case 7: if (gBattleWeather & WEATHER_SANDSTORM_ANY) @@ -739,7 +700,7 @@ u8 UpdateTurnCounters(void) BattleScriptExecute(gBattlescriptCurrInstr); effect++; } - gBattleStruct->turncountersTracker++; + gBattleStruct->turnCountersTracker++; break; case 8: if (gBattleWeather & WEATHER_SUN_ANY) @@ -757,7 +718,7 @@ u8 UpdateTurnCounters(void) BattleScriptExecute(gBattlescriptCurrInstr); effect++; } - gBattleStruct->turncountersTracker++; + gBattleStruct->turnCountersTracker++; break; case 9: if (gBattleWeather & WEATHER_HAIL) @@ -777,7 +738,7 @@ u8 UpdateTurnCounters(void) BattleScriptExecute(gBattlescriptCurrInstr); effect++; } - gBattleStruct->turncountersTracker++; + gBattleStruct->turnCountersTracker++; break; case 10: effect++; @@ -794,12 +755,12 @@ u8 TurnBasedEffects(void) u8 effect = 0; gHitMarker |= (HITMARKER_GRUDGE | HITMARKER_x20); - while (gBattleStruct->turnEffectsBank < gBattlersCount && gBattleStruct->turnEffectsTracker <= TURNBASED_MAX_CASE) + while (gBattleStruct->turnEffectsBattlerId < gBattlersCount && gBattleStruct->turnEffectsTracker <= TURNBASED_MAX_CASE) { - gActiveBattler = gBattlerAttacker = gBattleTurnOrder[gBattleStruct->turnEffectsBank]; + gActiveBattler = gBattlerAttacker = gBattleTurnOrder[gBattleStruct->turnEffectsBattlerId]; if (gAbsentBattlerFlags & gBitTable[gActiveBattler]) { - gBattleStruct->turnEffectsBank++; + gBattleStruct->turnEffectsBattlerId++; } else { @@ -839,7 +800,7 @@ u8 TurnBasedEffects(void) && gBattleMons[gStatuses3[gActiveBattler] & STATUS3_LEECHSEED_BANK].hp != 0 && gBattleMons[gActiveBattler].hp != 0) { - gBattlerTarget = gStatuses3[gActiveBattler] & STATUS3_LEECHSEED_BANK; //funny how the 'target' is actually the bank that receives HP + gBattlerTarget = gStatuses3[gActiveBattler] & STATUS3_LEECHSEED_BANK; //funny how the 'target' is actually the battlerId that receives HP gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 8; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; @@ -1090,7 +1051,7 @@ u8 TurnBasedEffects(void) gBattleMons[gActiveBattler].status1 |= (Random() & 3) + 2; BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1); MarkBattlerForControllerExec(gActiveBattler); - gEffectBank = gActiveBattler; + gEffectBattler = gActiveBattler; BattleScriptExecute(BattleScript_YawnMakesAsleep); effect++; } @@ -1099,7 +1060,7 @@ u8 TurnBasedEffects(void) break; case 19: // done gBattleStruct->turnEffectsTracker = 0; - gBattleStruct->turnEffectsBank++; + gBattleStruct->turnEffectsBattlerId++; break; } if (effect != 0) @@ -1117,16 +1078,16 @@ bool8 HandleWishPerishSongOnTurnEnd(void) switch (gBattleStruct->wishPerishSongState) { case 0: - while (gBattleStruct->wishPerishSongBank < gBattlersCount) + while (gBattleStruct->wishPerishSongBattlerId < gBattlersCount) { - gActiveBattler = gBattleStruct->wishPerishSongBank; + gActiveBattler = gBattleStruct->wishPerishSongBattlerId; if (gAbsentBattlerFlags & gBitTable[gActiveBattler]) { - gBattleStruct->wishPerishSongBank++; + gBattleStruct->wishPerishSongBattlerId++; continue; } - gBattleStruct->wishPerishSongBank++; + gBattleStruct->wishPerishSongBattlerId++; if (gWishFutureKnock.futureSightCounter[gActiveBattler] != 0 && --gWishFutureKnock.futureSightCounter[gActiveBattler] == 0 && gBattleMons[gActiveBattler].hp != 0) @@ -1141,7 +1102,7 @@ bool8 HandleWishPerishSongOnTurnEnd(void) gBattlerTarget = gActiveBattler; gBattlerAttacker = gWishFutureKnock.futureSightAttacker[gActiveBattler]; gBattleMoveDamage = gWishFutureKnock.futureSightDmg[gActiveBattler]; - gSpecialStatuses[gBattlerTarget].moveturnLostHP = 0xFFFF; + gSpecialStatuses[gBattlerTarget].dmg = 0xFFFF; BattleScriptExecute(BattleScript_MonTookFutureAttack); if (gWishFutureKnock.futureSightCounter[gActiveBattler] == 0 @@ -1156,19 +1117,19 @@ bool8 HandleWishPerishSongOnTurnEnd(void) { u8 *state = &gBattleStruct->wishPerishSongState; *state = 1; - gBattleStruct->wishPerishSongBank = 0; + gBattleStruct->wishPerishSongBattlerId = 0; } // fall through case 1: - while (gBattleStruct->wishPerishSongBank < gBattlersCount) + while (gBattleStruct->wishPerishSongBattlerId < gBattlersCount) { - gActiveBattler = gBattlerAttacker = gBattleTurnOrder[gBattleStruct->wishPerishSongBank]; + gActiveBattler = gBattlerAttacker = gBattleTurnOrder[gBattleStruct->wishPerishSongBattlerId]; if (gAbsentBattlerFlags & gBitTable[gActiveBattler]) { - gBattleStruct->wishPerishSongBank++; + gBattleStruct->wishPerishSongBattlerId++; continue; } - gBattleStruct->wishPerishSongBank++; + gBattleStruct->wishPerishSongBattlerId++; if (gStatuses3[gActiveBattler] & STATUS3_PERISH_SONG) { PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff1, 1, gDisableStructs[gActiveBattler].perishSongTimer1); @@ -1191,7 +1152,7 @@ bool8 HandleWishPerishSongOnTurnEnd(void) { u8 *state = &gBattleStruct->wishPerishSongState; *state = 2; - gBattleStruct->wishPerishSongBank = 0; + gBattleStruct->wishPerishSongBattlerId = 0; } // fall through case 2: @@ -1229,7 +1190,7 @@ bool8 HandleFaintedMonActions(void) switch (gBattleStruct->faintedActionsState) { case 0: - gBattleStruct->faintedActionsBank = 0; + gBattleStruct->faintedActionsBattlerId = 0; gBattleStruct->faintedActionsState++; for (i = 0; i < gBattlersCount; i++) { @@ -1240,45 +1201,45 @@ bool8 HandleFaintedMonActions(void) case 1: do { - gBank1 = gBattlerTarget = gBattleStruct->faintedActionsBank; - if (gBattleMons[gBattleStruct->faintedActionsBank].hp == 0 - && !(gBattleStruct->field_DF & gBitTable[gBattlerPartyIndexes[gBattleStruct->faintedActionsBank]]) - && !(gAbsentBattlerFlags & gBitTable[gBattleStruct->faintedActionsBank])) + gBattlerFainted = gBattlerTarget = gBattleStruct->faintedActionsBattlerId; + if (gBattleMons[gBattleStruct->faintedActionsBattlerId].hp == 0 + && !(gBattleStruct->field_DF & gBitTable[gBattlerPartyIndexes[gBattleStruct->faintedActionsBattlerId]]) + && !(gAbsentBattlerFlags & gBitTable[gBattleStruct->faintedActionsBattlerId])) { BattleScriptExecute(BattleScript_GiveExp); gBattleStruct->faintedActionsState = 2; return TRUE; } - } while (++gBattleStruct->faintedActionsBank != gBattlersCount); + } while (++gBattleStruct->faintedActionsBattlerId != gBattlersCount); gBattleStruct->faintedActionsState = 3; break; case 2: - sub_803F9EC(gBank1); - if (++gBattleStruct->faintedActionsBank == gBattlersCount) + sub_803F9EC(gBattlerFainted); + if (++gBattleStruct->faintedActionsBattlerId == gBattlersCount) gBattleStruct->faintedActionsState = 3; else gBattleStruct->faintedActionsState = 1; break; case 3: - gBattleStruct->faintedActionsBank = 0; + gBattleStruct->faintedActionsBattlerId = 0; gBattleStruct->faintedActionsState++; // fall through case 4: do { - gBank1 = gBattlerTarget = gBattleStruct->faintedActionsBank; - if (gBattleMons[gBattleStruct->faintedActionsBank].hp == 0 - && !(gAbsentBattlerFlags & gBitTable[gBattleStruct->faintedActionsBank])) + gBattlerFainted = gBattlerTarget = gBattleStruct->faintedActionsBattlerId; + if (gBattleMons[gBattleStruct->faintedActionsBattlerId].hp == 0 + && !(gAbsentBattlerFlags & gBitTable[gBattleStruct->faintedActionsBattlerId])) { BattleScriptExecute(BattleScript_HandleFaintedMon); gBattleStruct->faintedActionsState = 5; return TRUE; } - } while (++gBattleStruct->faintedActionsBank != gBattlersCount); + } while (++gBattleStruct->faintedActionsBattlerId != gBattlersCount); gBattleStruct->faintedActionsState = 6; break; case 5: - if (++gBattleStruct->faintedActionsBank == gBattlersCount) + if (++gBattleStruct->faintedActionsBattlerId == gBattlersCount) gBattleStruct->faintedActionsState = 6; else gBattleStruct->faintedActionsState = 4; @@ -1535,7 +1496,7 @@ u8 AtkCanceller_UnableToUseMove(void) { gCurrentMove = MOVE_BIDE; *bideDmg = gTakenDmg[gBattlerAttacker] * 2; - gBattlerTarget = gTakenDmgBanks[gBattlerAttacker]; + gBattlerTarget = gTakenDmgByBattler[gBattlerAttacker]; if (gAbsentBattlerFlags & gBitTable[gBattlerTarget]) gBattlerTarget = GetMoveTarget(MOVE_BIDE, 1); gBattlescriptCurrInstr = BattleScript_BideAttack; @@ -1950,9 +1911,9 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA } break; case ABILITY_SPEED_BOOST: - if (gBattleMons[battler].statStages[STAT_STAGE_SPEED] < 0xC && gDisableStructs[battler].isFirstTurn != 2) + if (gBattleMons[battler].statStages[STAT_SPEED] < 0xC && gDisableStructs[battler].isFirstTurn != 2) { - gBattleMons[battler].statStages[STAT_STAGE_SPEED]++; + gBattleMons[battler].statStages[STAT_SPEED]++; gBattleScripting.animArg1 = 0x11; gBattleScripting.animArg2 = 0; BattleScriptPushCursorAndCallback(BattleScript_SpeedBoostActivates); @@ -2063,7 +2024,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && move != MOVE_STRUGGLE && gBattleMoves[move].power != 0 - && (gSpecialStatuses[gBattlerTarget].moveturnLostHP_physical || gSpecialStatuses[gBattlerTarget].moveturnLostHP_special) + && (gSpecialStatuses[gBattlerTarget].physicalDmg || gSpecialStatuses[gBattlerTarget].specialDmg) && gBattleMons[battler].type1 != moveType && gBattleMons[battler].type2 != moveType && gBattleMons[battler].hp != 0) @@ -2080,7 +2041,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && gBattleMons[gBattlerAttacker].hp != 0 && !gProtectStructs[gBattlerAttacker].confusionSelfDmg - && (gSpecialStatuses[gBattlerTarget].moveturnLostHP_physical || gSpecialStatuses[gBattlerTarget].moveturnLostHP_special) + && (gSpecialStatuses[gBattlerTarget].physicalDmg || gSpecialStatuses[gBattlerTarget].specialDmg) && (gBattleMoves[move].flags & FLAG_MAKES_CONTACT)) { gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP / 16; @@ -2095,7 +2056,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && gBattleMons[gBattlerAttacker].hp != 0 && !gProtectStructs[gBattlerAttacker].confusionSelfDmg - && (gSpecialStatuses[gBattlerTarget].moveturnLostHP_physical || gSpecialStatuses[gBattlerTarget].moveturnLostHP_special) + && (gSpecialStatuses[gBattlerTarget].physicalDmg || gSpecialStatuses[gBattlerTarget].specialDmg) && (gBattleMoves[move].flags & FLAG_MAKES_CONTACT) && (Random() % 10) == 0) { @@ -2118,7 +2079,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && gBattleMons[gBattlerAttacker].hp != 0 && !gProtectStructs[gBattlerAttacker].confusionSelfDmg - && (gSpecialStatuses[gBattlerTarget].moveturnLostHP_physical || gSpecialStatuses[gBattlerTarget].moveturnLostHP_special) + && (gSpecialStatuses[gBattlerTarget].physicalDmg || gSpecialStatuses[gBattlerTarget].specialDmg) && (gBattleMoves[move].flags & FLAG_MAKES_CONTACT) && (Random() % 3) == 0) { @@ -2133,7 +2094,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && gBattleMons[gBattlerAttacker].hp != 0 && !gProtectStructs[gBattlerAttacker].confusionSelfDmg - && (gSpecialStatuses[gBattlerTarget].moveturnLostHP_physical || gSpecialStatuses[gBattlerTarget].moveturnLostHP_special) + && (gSpecialStatuses[gBattlerTarget].physicalDmg || gSpecialStatuses[gBattlerTarget].specialDmg) && (gBattleMoves[move].flags & FLAG_MAKES_CONTACT) && (Random() % 3) == 0) { @@ -2149,7 +2110,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA && gBattleMons[gBattlerAttacker].hp != 0 && !gProtectStructs[gBattlerAttacker].confusionSelfDmg && (gBattleMoves[move].flags & FLAG_MAKES_CONTACT) - && (gSpecialStatuses[gBattlerTarget].moveturnLostHP_physical || gSpecialStatuses[gBattlerTarget].moveturnLostHP_special) + && (gSpecialStatuses[gBattlerTarget].physicalDmg || gSpecialStatuses[gBattlerTarget].specialDmg) && (Random() % 3) == 0) { gBattleCommunication[MOVE_EFFECT_BYTE] = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_BURN; @@ -2164,7 +2125,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA && gBattleMons[gBattlerAttacker].hp != 0 && !gProtectStructs[gBattlerAttacker].confusionSelfDmg && (gBattleMoves[move].flags & FLAG_MAKES_CONTACT) - && (gSpecialStatuses[gBattlerTarget].moveturnLostHP_physical || gSpecialStatuses[gBattlerTarget].moveturnLostHP_special) + && (gSpecialStatuses[gBattlerTarget].physicalDmg || gSpecialStatuses[gBattlerTarget].specialDmg) && gBattleMons[gBattlerTarget].hp != 0 && (Random() % 3) == 0 && gBattleMons[gBattlerAttacker].ability != ABILITY_OBLIVIOUS @@ -2535,7 +2496,7 @@ enum ITEM_STATS_CHANGE, // 5 }; -u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) +u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn) { int i = 0; u8 effect = ITEM_NO_EFFECT; @@ -2544,11 +2505,11 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) u8 bankQuality, atkQuality, defQuality; u16 atkItem, defItem; - gLastUsedItem = gBattleMons[bank].item; + gLastUsedItem = gBattleMons[battlerId].item; if (gLastUsedItem == ITEM_ENIGMA_BERRY) { - bankHoldEffect = gEnigmaBerries[bank].holdEffect; - bankQuality = gEnigmaBerries[bank].holdEffectParam; + bankHoldEffect = gEnigmaBerries[battlerId].holdEffect; + bankQuality = gEnigmaBerries[battlerId].holdEffectParam; } else { @@ -2587,39 +2548,39 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) switch (bankHoldEffect) { case HOLD_EFFECT_DOUBLE_PRIZE: - if (GetBattlerSide(bank) == B_SIDE_PLAYER) + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) gBattleStruct->moneyMultiplier = 2; break; case HOLD_EFFECT_RESTORE_STATS: for (i = 0; i < BATTLE_STATS_NO; i++) { - if (gBattleMons[bank].statStages[i] < 6) + if (gBattleMons[battlerId].statStages[i] < 6) { - gBattleMons[bank].statStages[i] = 6; + gBattleMons[battlerId].statStages[i] = 6; effect = ITEM_STATS_CHANGE; } } if (effect) { - gBattleScripting.battler = bank; - gStringBattler = bank; - gActiveBattler = gBattlerAttacker = bank; + gBattleScripting.battler = battlerId; + gPotentialItemEffectBattler = battlerId; + gActiveBattler = gBattlerAttacker = battlerId; BattleScriptExecute(BattleScript_WhiteHerbEnd2); } break; } break; case 1: - if (gBattleMons[bank].hp) + if (gBattleMons[battlerId].hp) { switch (bankHoldEffect) { case HOLD_EFFECT_RESTORE_HP: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) + if (gBattleMons[battlerId].hp <= gBattleMons[battlerId].maxHP / 2 && !moveTurn) { gBattleMoveDamage = bankQuality; - if (gBattleMons[bank].hp + bankQuality > gBattleMons[bank].maxHP) - gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; + if (gBattleMons[battlerId].hp + bankQuality > gBattleMons[battlerId].maxHP) + gBattleMoveDamage = gBattleMons[battlerId].maxHP - gBattleMons[battlerId].hp; gBattleMoveDamage *= -1; BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); effect = 4; @@ -2632,10 +2593,10 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) u8 ppBonuses; u16 move; - if (GetBattlerSide(bank) == B_SIDE_PLAYER) - mon = &gPlayerParty[gBattlerPartyIndexes[bank]]; + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) + mon = &gPlayerParty[gBattlerPartyIndexes[battlerId]]; else - mon = &gEnemyParty[gBattlerPartyIndexes[bank]]; + mon = &gEnemyParty[gBattlerPartyIndexes[battlerId]]; for (i = 0; i < 4; i++) { move = GetMonData(mon, MON_DATA_MOVE1 + i); @@ -2664,47 +2625,47 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) case HOLD_EFFECT_RESTORE_STATS: for (i = 0; i < BATTLE_STATS_NO; i++) { - if (gBattleMons[bank].statStages[i] < 6) + if (gBattleMons[battlerId].statStages[i] < 6) { - gBattleMons[bank].statStages[i] = 6; + gBattleMons[battlerId].statStages[i] = 6; effect = ITEM_STATS_CHANGE; } } if (effect) { - gBattleScripting.battler = bank; - gStringBattler = bank; - gActiveBattler = gBattlerAttacker = bank; + gBattleScripting.battler = battlerId; + gPotentialItemEffectBattler = battlerId; + gActiveBattler = gBattlerAttacker = battlerId; BattleScriptExecute(BattleScript_WhiteHerbEnd2); } break; case HOLD_EFFECT_LEFTOVERS: - if (gBattleMons[bank].hp < gBattleMons[bank].maxHP && !moveTurn) + if (gBattleMons[battlerId].hp < gBattleMons[battlerId].maxHP && !moveTurn) { - gBattleMoveDamage = gBattleMons[bank].maxHP / 16; + gBattleMoveDamage = gBattleMons[battlerId].maxHP / 16; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; - if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) - gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; + if (gBattleMons[battlerId].hp + gBattleMoveDamage > gBattleMons[battlerId].maxHP) + gBattleMoveDamage = gBattleMons[battlerId].maxHP - gBattleMons[battlerId].hp; gBattleMoveDamage *= -1; BattleScriptExecute(BattleScript_ItemHealHP_End2); effect = ITEM_HP_CHANGE; - RecordItemEffectBattle(bank, bankHoldEffect); + RecordItemEffectBattle(battlerId, bankHoldEffect); } break; // nice copy/paste there gamefreak, making a function for confuse berries was too much eh? case HOLD_EFFECT_CONFUSE_SPICY: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) + if (gBattleMons[battlerId].hp <= gBattleMons[battlerId].maxHP / 2 && !moveTurn) { PREPARE_FLAVOR_BUFFER(gBattleTextBuff1, FLAVOR_SPICY); - gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality; + gBattleMoveDamage = gBattleMons[battlerId].maxHP / bankQuality; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; - if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) - gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; + if (gBattleMons[battlerId].hp + gBattleMoveDamage > gBattleMons[battlerId].maxHP) + gBattleMoveDamage = gBattleMons[battlerId].maxHP - gBattleMons[battlerId].hp; gBattleMoveDamage *= -1; - if (GetFlavorRelationByPersonality(gBattleMons[bank].personality, FLAVOR_SPICY) < 0) + if (GetFlavorRelationByPersonality(gBattleMons[battlerId].personality, FLAVOR_SPICY) < 0) BattleScriptExecute(BattleScript_BerryConfuseHealEnd2); else BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); @@ -2712,17 +2673,17 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) } break; case HOLD_EFFECT_CONFUSE_DRY: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) + if (gBattleMons[battlerId].hp <= gBattleMons[battlerId].maxHP / 2 && !moveTurn) { PREPARE_FLAVOR_BUFFER(gBattleTextBuff1, FLAVOR_DRY); - gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality; + gBattleMoveDamage = gBattleMons[battlerId].maxHP / bankQuality; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; - if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) - gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; + if (gBattleMons[battlerId].hp + gBattleMoveDamage > gBattleMons[battlerId].maxHP) + gBattleMoveDamage = gBattleMons[battlerId].maxHP - gBattleMons[battlerId].hp; gBattleMoveDamage *= -1; - if (GetFlavorRelationByPersonality(gBattleMons[bank].personality, FLAVOR_DRY) < 0) + if (GetFlavorRelationByPersonality(gBattleMons[battlerId].personality, FLAVOR_DRY) < 0) BattleScriptExecute(BattleScript_BerryConfuseHealEnd2); else BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); @@ -2730,17 +2691,17 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) } break; case HOLD_EFFECT_CONFUSE_SWEET: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) + if (gBattleMons[battlerId].hp <= gBattleMons[battlerId].maxHP / 2 && !moveTurn) { PREPARE_FLAVOR_BUFFER(gBattleTextBuff1, FLAVOR_SWEET); - gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality; + gBattleMoveDamage = gBattleMons[battlerId].maxHP / bankQuality; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; - if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) - gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; + if (gBattleMons[battlerId].hp + gBattleMoveDamage > gBattleMons[battlerId].maxHP) + gBattleMoveDamage = gBattleMons[battlerId].maxHP - gBattleMons[battlerId].hp; gBattleMoveDamage *= -1; - if (GetFlavorRelationByPersonality(gBattleMons[bank].personality, FLAVOR_SWEET) < 0) + if (GetFlavorRelationByPersonality(gBattleMons[battlerId].personality, FLAVOR_SWEET) < 0) BattleScriptExecute(BattleScript_BerryConfuseHealEnd2); else BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); @@ -2748,17 +2709,17 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) } break; case HOLD_EFFECT_CONFUSE_BITTER: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) + if (gBattleMons[battlerId].hp <= gBattleMons[battlerId].maxHP / 2 && !moveTurn) { PREPARE_FLAVOR_BUFFER(gBattleTextBuff1, FLAVOR_BITTER); - gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality; + gBattleMoveDamage = gBattleMons[battlerId].maxHP / bankQuality; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; - if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) - gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; + if (gBattleMons[battlerId].hp + gBattleMoveDamage > gBattleMons[battlerId].maxHP) + gBattleMoveDamage = gBattleMons[battlerId].maxHP - gBattleMons[battlerId].hp; gBattleMoveDamage *= -1; - if (GetFlavorRelationByPersonality(gBattleMons[bank].personality, FLAVOR_BITTER) < 0) + if (GetFlavorRelationByPersonality(gBattleMons[battlerId].personality, FLAVOR_BITTER) < 0) BattleScriptExecute(BattleScript_BerryConfuseHealEnd2); else BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); @@ -2766,17 +2727,17 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) } break; case HOLD_EFFECT_CONFUSE_SOUR: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) + if (gBattleMons[battlerId].hp <= gBattleMons[battlerId].maxHP / 2 && !moveTurn) { PREPARE_FLAVOR_BUFFER(gBattleTextBuff1, FLAVOR_SOUR); - gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality; + gBattleMoveDamage = gBattleMons[battlerId].maxHP / bankQuality; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; - if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) - gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; + if (gBattleMons[battlerId].hp + gBattleMoveDamage > gBattleMons[battlerId].maxHP) + gBattleMoveDamage = gBattleMons[battlerId].maxHP - gBattleMons[battlerId].hp; gBattleMoveDamage *= -1; - if (GetFlavorRelationByPersonality(gBattleMons[bank].personality, FLAVOR_SOUR) < 0) + if (GetFlavorRelationByPersonality(gBattleMons[battlerId].personality, FLAVOR_SOUR) < 0) BattleScriptExecute(BattleScript_BerryConfuseHealEnd2); else BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); @@ -2785,85 +2746,85 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) break; // copy/paste again, smh case HOLD_EFFECT_ATTACK_UP: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_ATK] < 0xC) + if (gBattleMons[battlerId].hp <= gBattleMons[battlerId].maxHP / bankQuality && !moveTurn && gBattleMons[battlerId].statStages[STAT_ATK] < 0xC) { - PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_STAGE_ATK); + PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK); PREPARE_STRING_BUFFER(gBattleTextBuff2, STRINGID_STATROSE); - gEffectBank = bank; - SET_STATCHANGER(STAT_STAGE_ATK, 1, FALSE); - gBattleScripting.animArg1 = 0xE + STAT_STAGE_ATK; + gEffectBattler = battlerId; + SET_STATCHANGER(STAT_ATK, 1, FALSE); + gBattleScripting.animArg1 = 0xE + STAT_ATK; gBattleScripting.animArg2 = 0; BattleScriptExecute(BattleScript_BerryStatRaiseEnd2); effect = ITEM_STATS_CHANGE; } break; case HOLD_EFFECT_DEFENSE_UP: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_DEF] < 0xC) + if (gBattleMons[battlerId].hp <= gBattleMons[battlerId].maxHP / bankQuality && !moveTurn && gBattleMons[battlerId].statStages[STAT_DEF] < 0xC) { - PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_STAGE_DEF); + PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_DEF); - gEffectBank = bank; - SET_STATCHANGER(STAT_STAGE_DEF, 1, FALSE); - gBattleScripting.animArg1 = 0xE + STAT_STAGE_DEF; + gEffectBattler = battlerId; + SET_STATCHANGER(STAT_DEF, 1, FALSE); + gBattleScripting.animArg1 = 0xE + STAT_DEF; gBattleScripting.animArg2 = 0; BattleScriptExecute(BattleScript_BerryStatRaiseEnd2); effect = ITEM_STATS_CHANGE; } break; case HOLD_EFFECT_SPEED_UP: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_SPEED] < 0xC) + if (gBattleMons[battlerId].hp <= gBattleMons[battlerId].maxHP / bankQuality && !moveTurn && gBattleMons[battlerId].statStages[STAT_SPEED] < 0xC) { - PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_STAGE_SPEED); + PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_SPEED); - gEffectBank = bank; - SET_STATCHANGER(STAT_STAGE_SPEED, 1, FALSE); - gBattleScripting.animArg1 = 0xE + STAT_STAGE_SPEED; + gEffectBattler = battlerId; + SET_STATCHANGER(STAT_SPEED, 1, FALSE); + gBattleScripting.animArg1 = 0xE + STAT_SPEED; gBattleScripting.animArg2 = 0; BattleScriptExecute(BattleScript_BerryStatRaiseEnd2); effect = ITEM_STATS_CHANGE; } break; case HOLD_EFFECT_SP_ATTACK_UP: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_SPATK] < 0xC) + if (gBattleMons[battlerId].hp <= gBattleMons[battlerId].maxHP / bankQuality && !moveTurn && gBattleMons[battlerId].statStages[STAT_SPATK] < 0xC) { - PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_STAGE_SPATK); + PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_SPATK); - gEffectBank = bank; - SET_STATCHANGER(STAT_STAGE_SPATK, 1, FALSE); - gBattleScripting.animArg1 = 0xE + STAT_STAGE_SPATK; + gEffectBattler = battlerId; + SET_STATCHANGER(STAT_SPATK, 1, FALSE); + gBattleScripting.animArg1 = 0xE + STAT_SPATK; gBattleScripting.animArg2 = 0; BattleScriptExecute(BattleScript_BerryStatRaiseEnd2); effect = ITEM_STATS_CHANGE; } break; case HOLD_EFFECT_SP_DEFENSE_UP: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_SPDEF] < 0xC) + if (gBattleMons[battlerId].hp <= gBattleMons[battlerId].maxHP / bankQuality && !moveTurn && gBattleMons[battlerId].statStages[STAT_SPDEF] < 0xC) { - PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_STAGE_SPDEF); + PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_SPDEF); - gEffectBank = bank; - SET_STATCHANGER(STAT_STAGE_SPDEF, 1, FALSE); - gBattleScripting.animArg1 = 0xE + STAT_STAGE_SPDEF; + gEffectBattler = battlerId; + SET_STATCHANGER(STAT_SPDEF, 1, FALSE); + gBattleScripting.animArg1 = 0xE + STAT_SPDEF; gBattleScripting.animArg2 = 0; BattleScriptExecute(BattleScript_BerryStatRaiseEnd2); effect = ITEM_STATS_CHANGE; } break; case HOLD_EFFECT_CRITICAL_UP: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && !(gBattleMons[bank].status2 & STATUS2_FOCUS_ENERGY)) + if (gBattleMons[battlerId].hp <= gBattleMons[battlerId].maxHP / bankQuality && !moveTurn && !(gBattleMons[battlerId].status2 & STATUS2_FOCUS_ENERGY)) { - gBattleMons[bank].status2 |= STATUS2_FOCUS_ENERGY; + gBattleMons[battlerId].status2 |= STATUS2_FOCUS_ENERGY; BattleScriptExecute(BattleScript_BerryFocusEnergyEnd2); effect = ITEM_EFFECT_OTHER; } break; case HOLD_EFFECT_RANDOM_STAT_UP: - if (!moveTurn && gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality) + if (!moveTurn && gBattleMons[battlerId].hp <= gBattleMons[battlerId].maxHP / bankQuality) { for (i = 0; i < 5; i++) { - if (gBattleMons[bank].statStages[STAT_STAGE_ATK + i] < 0xC) + if (gBattleMons[battlerId].statStages[STAT_ATK + i] < 0xC) break; } if (i != 5) @@ -2871,7 +2832,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) do { i = Random() % 5; - } while (gBattleMons[bank].statStages[STAT_STAGE_ATK + i] == 0xC); + } while (gBattleMons[battlerId].statStages[STAT_ATK + i] == 0xC); PREPARE_STAT_BUFFER(gBattleTextBuff1, i + 1); @@ -2884,7 +2845,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) gBattleTextBuff2[6] = STRINGID_STATROSE >> 8; gBattleTextBuff2[7] = EOS; - gEffectBank = bank; + gEffectBattler = battlerId; SET_STATCHANGER(i + 1, 2, FALSE); gBattleScripting.animArg1 = 0x21 + i + 6; gBattleScripting.animArg2 = 0; @@ -2894,85 +2855,85 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) } break; case HOLD_EFFECT_CURE_PAR: - if (gBattleMons[bank].status1 & STATUS1_PARALYSIS) + if (gBattleMons[battlerId].status1 & STATUS1_PARALYSIS) { - gBattleMons[bank].status1 &= ~(STATUS1_PARALYSIS); + gBattleMons[battlerId].status1 &= ~(STATUS1_PARALYSIS); BattleScriptExecute(BattleScript_BerryCurePrlzEnd2); effect = ITEM_STATUS_CHANGE; } break; case HOLD_EFFECT_CURE_PSN: - if (gBattleMons[bank].status1 & STATUS1_PSN_ANY) + if (gBattleMons[battlerId].status1 & STATUS1_PSN_ANY) { - gBattleMons[bank].status1 &= ~(STATUS1_PSN_ANY | STATUS1_TOXIC_COUNTER); + gBattleMons[battlerId].status1 &= ~(STATUS1_PSN_ANY | STATUS1_TOXIC_COUNTER); BattleScriptExecute(BattleScript_BerryCurePsnEnd2); effect = ITEM_STATUS_CHANGE; } break; case HOLD_EFFECT_CURE_BRN: - if (gBattleMons[bank].status1 & STATUS1_BURN) + if (gBattleMons[battlerId].status1 & STATUS1_BURN) { - gBattleMons[bank].status1 &= ~(STATUS1_BURN); + gBattleMons[battlerId].status1 &= ~(STATUS1_BURN); BattleScriptExecute(BattleScript_BerryCureBrnEnd2); effect = ITEM_STATUS_CHANGE; } break; case HOLD_EFFECT_CURE_FRZ: - if (gBattleMons[bank].status1 & STATUS1_FREEZE) + if (gBattleMons[battlerId].status1 & STATUS1_FREEZE) { - gBattleMons[bank].status1 &= ~(STATUS1_FREEZE); + gBattleMons[battlerId].status1 &= ~(STATUS1_FREEZE); BattleScriptExecute(BattleScript_BerryCureFrzEnd2); effect = ITEM_STATUS_CHANGE; } break; case HOLD_EFFECT_CURE_SLP: - if (gBattleMons[bank].status1 & STATUS1_SLEEP) + if (gBattleMons[battlerId].status1 & STATUS1_SLEEP) { - gBattleMons[bank].status1 &= ~(STATUS1_SLEEP); - gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); + gBattleMons[battlerId].status1 &= ~(STATUS1_SLEEP); + gBattleMons[battlerId].status2 &= ~(STATUS2_NIGHTMARE); BattleScriptExecute(BattleScript_BerryCureSlpEnd2); effect = ITEM_STATUS_CHANGE; } break; case HOLD_EFFECT_CURE_CONFUSION: - if (gBattleMons[bank].status2 & STATUS2_CONFUSION) + if (gBattleMons[battlerId].status2 & STATUS2_CONFUSION) { - gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION); + gBattleMons[battlerId].status2 &= ~(STATUS2_CONFUSION); BattleScriptExecute(BattleScript_BerryCureConfusionEnd2); effect = ITEM_EFFECT_OTHER; } break; case HOLD_EFFECT_CURE_STATUS: - if (gBattleMons[bank].status1 & STATUS1_ANY || gBattleMons[bank].status2 & STATUS2_CONFUSION) + if (gBattleMons[battlerId].status1 & STATUS1_ANY || gBattleMons[battlerId].status2 & STATUS2_CONFUSION) { i = 0; - if (gBattleMons[bank].status1 & STATUS1_PSN_ANY) + if (gBattleMons[battlerId].status1 & STATUS1_PSN_ANY) { StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn); i++; } - if (gBattleMons[bank].status1 & STATUS1_SLEEP) + if (gBattleMons[battlerId].status1 & STATUS1_SLEEP) { - gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); + gBattleMons[battlerId].status2 &= ~(STATUS2_NIGHTMARE); StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn); i++; } - if (gBattleMons[bank].status1 & STATUS1_PARALYSIS) + if (gBattleMons[battlerId].status1 & STATUS1_PARALYSIS) { StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn); i++; } - if (gBattleMons[bank].status1 & STATUS1_BURN) + if (gBattleMons[battlerId].status1 & STATUS1_BURN) { StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn); i++; } - if (gBattleMons[bank].status1 & STATUS1_FREEZE) + if (gBattleMons[battlerId].status1 & STATUS1_FREEZE) { StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn); i++; } - if (gBattleMons[bank].status2 & STATUS2_CONFUSION) + if (gBattleMons[battlerId].status2 & STATUS2_CONFUSION) { StringCopy(gBattleTextBuff1, gStatusConditionString_ConfusionJpn); i++; @@ -2981,16 +2942,16 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) gBattleCommunication[MULTISTRING_CHOOSER] = 0; else gBattleCommunication[MULTISTRING_CHOOSER] = 1; - gBattleMons[bank].status1 = 0; - gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION); + gBattleMons[battlerId].status1 = 0; + gBattleMons[battlerId].status2 &= ~(STATUS2_CONFUSION); BattleScriptExecute(BattleScript_BerryCureChosenStatusEnd2); effect = ITEM_STATUS_CHANGE; } break; case HOLD_EFFECT_CURE_ATTRACT: - if (gBattleMons[bank].status2 & STATUS2_INFATUATION) + if (gBattleMons[battlerId].status2 & STATUS2_INFATUATION) { - gBattleMons[bank].status2 &= ~(STATUS2_INFATUATION); + gBattleMons[battlerId].status2 &= ~(STATUS2_INFATUATION); StringCopy(gBattleTextBuff1, gStatusConditionString_LoveJpn); BattleScriptExecute(BattleScript_BerryCureChosenStatusEnd2); gBattleCommunication[MULTISTRING_CHOOSER] = 0; @@ -3000,18 +2961,18 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) } if (effect) { - gBattleScripting.battler = bank; - gStringBattler = bank; - gActiveBattler = gBattlerAttacker = bank; + gBattleScripting.battler = battlerId; + gPotentialItemEffectBattler = battlerId; + gActiveBattler = gBattlerAttacker = battlerId; switch (effect) { case ITEM_STATUS_CHANGE: - BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[bank].status1); + BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[battlerId].status1); MarkBattlerForControllerExec(gActiveBattler); break; case ITEM_PP_CHANGE: - if (!(gBattleMons[bank].status2 & STATUS2_TRANSFORMED) && !(gDisableStructs[bank].unk18_b & gBitTable[i])) - gBattleMons[bank].pp[i] = changedPP; + if (!(gBattleMons[battlerId].status2 & STATUS2_TRANSFORMED) && !(gDisableStructs[battlerId].unk18_b & gBitTable[i])) + gBattleMons[battlerId].pp[i] = changedPP; break; } } @@ -3020,13 +2981,13 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) case 2: break; case 3: - for (bank = 0; bank < gBattlersCount; bank++) + for (battlerId = 0; battlerId < gBattlersCount; battlerId++) { - gLastUsedItem = gBattleMons[bank].item; - if (gBattleMons[bank].item == ITEM_ENIGMA_BERRY) + gLastUsedItem = gBattleMons[battlerId].item; + if (gBattleMons[battlerId].item == ITEM_ENIGMA_BERRY) { - bankHoldEffect = gEnigmaBerries[bank].holdEffect; - bankQuality = gEnigmaBerries[bank].holdEffectParam; + bankHoldEffect = gEnigmaBerries[battlerId].holdEffect; + bankQuality = gEnigmaBerries[battlerId].holdEffectParam; } else { @@ -3036,64 +2997,64 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) switch (bankHoldEffect) { case HOLD_EFFECT_CURE_PAR: - if (gBattleMons[bank].status1 & STATUS1_PARALYSIS) + if (gBattleMons[battlerId].status1 & STATUS1_PARALYSIS) { - gBattleMons[bank].status1 &= ~(STATUS1_PARALYSIS); + gBattleMons[battlerId].status1 &= ~(STATUS1_PARALYSIS); BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_BerryCureParRet; effect = ITEM_STATUS_CHANGE; } break; case HOLD_EFFECT_CURE_PSN: - if (gBattleMons[bank].status1 & STATUS1_PSN_ANY) + if (gBattleMons[battlerId].status1 & STATUS1_PSN_ANY) { - gBattleMons[bank].status1 &= ~(STATUS1_PSN_ANY | STATUS1_TOXIC_COUNTER); + gBattleMons[battlerId].status1 &= ~(STATUS1_PSN_ANY | STATUS1_TOXIC_COUNTER); BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_BerryCurePsnRet; effect = ITEM_STATUS_CHANGE; } break; case HOLD_EFFECT_CURE_BRN: - if (gBattleMons[bank].status1 & STATUS1_BURN) + if (gBattleMons[battlerId].status1 & STATUS1_BURN) { - gBattleMons[bank].status1 &= ~(STATUS1_BURN); + gBattleMons[battlerId].status1 &= ~(STATUS1_BURN); BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_BerryCureBrnRet; effect = ITEM_STATUS_CHANGE; } break; case HOLD_EFFECT_CURE_FRZ: - if (gBattleMons[bank].status1 & STATUS1_FREEZE) + if (gBattleMons[battlerId].status1 & STATUS1_FREEZE) { - gBattleMons[bank].status1 &= ~(STATUS1_FREEZE); + gBattleMons[battlerId].status1 &= ~(STATUS1_FREEZE); BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_BerryCureFrzRet; effect = ITEM_STATUS_CHANGE; } break; case HOLD_EFFECT_CURE_SLP: - if (gBattleMons[bank].status1 & STATUS1_SLEEP) + if (gBattleMons[battlerId].status1 & STATUS1_SLEEP) { - gBattleMons[bank].status1 &= ~(STATUS1_SLEEP); - gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); + gBattleMons[battlerId].status1 &= ~(STATUS1_SLEEP); + gBattleMons[battlerId].status2 &= ~(STATUS2_NIGHTMARE); BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_BerryCureSlpRet; effect = ITEM_STATUS_CHANGE; } break; case HOLD_EFFECT_CURE_CONFUSION: - if (gBattleMons[bank].status2 & STATUS2_CONFUSION) + if (gBattleMons[battlerId].status2 & STATUS2_CONFUSION) { - gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION); + gBattleMons[battlerId].status2 &= ~(STATUS2_CONFUSION); BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_BerryCureConfusionRet; effect = ITEM_EFFECT_OTHER; } break; case HOLD_EFFECT_CURE_ATTRACT: - if (gBattleMons[bank].status2 & STATUS2_INFATUATION) + if (gBattleMons[battlerId].status2 & STATUS2_INFATUATION) { - gBattleMons[bank].status2 &= ~(STATUS2_INFATUATION); + gBattleMons[battlerId].status2 &= ~(STATUS2_INFATUATION); StringCopy(gBattleTextBuff1, gStatusConditionString_LoveJpn); BattleScriptPushCursor(); gBattleCommunication[MULTISTRING_CHOOSER] = 0; @@ -3102,35 +3063,35 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) } break; case HOLD_EFFECT_CURE_STATUS: - if (gBattleMons[bank].status1 & STATUS1_ANY || gBattleMons[bank].status2 & STATUS2_CONFUSION) + if (gBattleMons[battlerId].status1 & STATUS1_ANY || gBattleMons[battlerId].status2 & STATUS2_CONFUSION) { - if (gBattleMons[bank].status1 & STATUS1_PSN_ANY) + if (gBattleMons[battlerId].status1 & STATUS1_PSN_ANY) { StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn); } - if (gBattleMons[bank].status1 & STATUS1_SLEEP) + if (gBattleMons[battlerId].status1 & STATUS1_SLEEP) { - gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); + gBattleMons[battlerId].status2 &= ~(STATUS2_NIGHTMARE); StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn); } - if (gBattleMons[bank].status1 & STATUS1_PARALYSIS) + if (gBattleMons[battlerId].status1 & STATUS1_PARALYSIS) { StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn); } - if (gBattleMons[bank].status1 & STATUS1_BURN) + if (gBattleMons[battlerId].status1 & STATUS1_BURN) { StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn); } - if (gBattleMons[bank].status1 & STATUS1_FREEZE) + if (gBattleMons[battlerId].status1 & STATUS1_FREEZE) { StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn); } - if (gBattleMons[bank].status2 & STATUS2_CONFUSION) + if (gBattleMons[battlerId].status2 & STATUS2_CONFUSION) { StringCopy(gBattleTextBuff1, gStatusConditionString_ConfusionJpn); } - gBattleMons[bank].status1 = 0; - gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION); + gBattleMons[battlerId].status1 = 0; + gBattleMons[battlerId].status2 &= ~(STATUS2_CONFUSION); BattleScriptPushCursor(); gBattleCommunication[MULTISTRING_CHOOSER] = 0; gBattlescriptCurrInstr = BattleScript_BerryCureChosenStatusRet; @@ -3140,16 +3101,16 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) case HOLD_EFFECT_RESTORE_STATS: for (i = 0; i < BATTLE_STATS_NO; i++) { - if (gBattleMons[bank].statStages[i] < 6) + if (gBattleMons[battlerId].statStages[i] < 6) { - gBattleMons[bank].statStages[i] = 6; + gBattleMons[battlerId].statStages[i] = 6; effect = ITEM_STATS_CHANGE; } } if (effect) { - gBattleScripting.battler = bank; - gStringBattler = bank; + gBattleScripting.battler = battlerId; + gPotentialItemEffectBattler = battlerId; BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_WhiteHerbRet; return effect; // unnecessary return @@ -3158,9 +3119,9 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) } if (effect) { - gBattleScripting.battler = bank; - gStringBattler = bank; - gActiveBattler = bank; + gBattleScripting.battler = battlerId; + gPotentialItemEffectBattler = battlerId; + gActiveBattler = battlerId; BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1); MarkBattlerForControllerExec(gActiveBattler); break; @@ -3174,7 +3135,7 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) { case HOLD_EFFECT_FLINCH: if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - && (gSpecialStatuses[gBattlerTarget].moveturnLostHP_physical || gSpecialStatuses[gBattlerTarget].moveturnLostHP_special) + && (gSpecialStatuses[gBattlerTarget].physicalDmg || gSpecialStatuses[gBattlerTarget].specialDmg) && (Random() % 100) < atkQuality && gBattleMoves[gCurrentMove].flags & FLAG_KINGSROCK_AFFECTED && gBattleMons[gBattlerTarget].hp) @@ -3187,19 +3148,19 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) break; case HOLD_EFFECT_SHELL_BELL: if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - && gSpecialStatuses[gBattlerTarget].moveturnLostHP != 0 - && gSpecialStatuses[gBattlerTarget].moveturnLostHP != 0xFFFF + && gSpecialStatuses[gBattlerTarget].dmg != 0 + && gSpecialStatuses[gBattlerTarget].dmg != 0xFFFF && gBattlerAttacker != gBattlerTarget && gBattleMons[gBattlerAttacker].hp != gBattleMons[gBattlerAttacker].maxHP && gBattleMons[gBattlerAttacker].hp != 0) { gLastUsedItem = atkItem; - gStringBattler = gBattlerAttacker; + gPotentialItemEffectBattler = gBattlerAttacker; gBattleScripting.battler = gBattlerAttacker; - gBattleMoveDamage = (gSpecialStatuses[gBattlerTarget].moveturnLostHP / atkQuality) * -1; + gBattleMoveDamage = (gSpecialStatuses[gBattlerTarget].dmg / atkQuality) * -1; if (gBattleMoveDamage == 0) gBattleMoveDamage = -1; - gSpecialStatuses[gBattlerTarget].moveturnLostHP = 0; + gSpecialStatuses[gBattlerTarget].dmg = 0; BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_ItemHealHP_Ret; effect++; @@ -3213,11 +3174,11 @@ u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) return effect; } -void ClearFuryCutterDestinyBondGrudge(u8 bank) +void ClearFuryCutterDestinyBondGrudge(u8 battlerId) { - gDisableStructs[bank].furyCutterCounter = 0; - gBattleMons[bank].status2 &= ~(STATUS2_DESTINY_BOND); - gStatuses3[bank] &= ~(STATUS3_GRUDGE); + gDisableStructs[battlerId].furyCutterCounter = 0; + gBattleMons[battlerId].status2 &= ~(STATUS2_DESTINY_BOND); + gStatuses3[battlerId] &= ~(STATUS3_GRUDGE); } void HandleAction_RunBattleScript(void) // identical to RunBattleScriptCommands @@ -3305,14 +3266,14 @@ u8 GetMoveTarget(u16 move, u8 useMoveTarget) return targetBank; } -static bool32 HasObedientBitSet(u8 bank) +static bool32 HasObedientBitSet(u8 battlerId) { - if (GetBattlerSide(bank) == B_SIDE_OPPONENT) + if (GetBattlerSide(battlerId) == B_SIDE_OPPONENT) return TRUE; - if (GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_SPECIES, NULL) != SPECIES_DEOXYS - && GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_SPECIES, NULL) != SPECIES_MEW) + if (GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES, NULL) != SPECIES_DEOXYS + && GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES, NULL) != SPECIES_MEW) return TRUE; - return GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_OBEDIENCE, NULL); + return GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_OBEDIENCE, NULL); } u8 IsMonDisobedient(void) @@ -3380,7 +3341,7 @@ u8 IsMonDisobedient(void) { do { - gCurrMovePos = gUnknown_020241E9 = Random() & 3; + gCurrMovePos = gChosenMovePos = Random() & 3; } while (gBitTable[gCurrMovePos] & calc); gRandomMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos]; diff --git a/src/battle_util2.c b/src/battle_util2.c index ba42d4ea9..c1bbabc85 100644 --- a/src/battle_util2.c +++ b/src/battle_util2.c @@ -8,12 +8,7 @@ #include "random.h" #include "battle_scripts.h" -extern struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT]; -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; extern u8 gUnknown_0203CF00[]; -extern const u8 *gBattlescriptCurrInstr; -extern u8 gBattleCommunication[]; -extern u8 gActiveBattler; extern void sub_81D55D0(void); extern void sub_81D5694(void); @@ -79,7 +74,7 @@ void FreeBattleResources(void) } } -void AdjustFriendshipOnBattleFaint(u8 bank) +void AdjustFriendshipOnBattleFaint(u8 battlerId) { u8 opposingBank; @@ -98,22 +93,22 @@ void AdjustFriendshipOnBattleFaint(u8 bank) opposingBank = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); } - if (gBattleMons[opposingBank].level > gBattleMons[bank].level) + if (gBattleMons[opposingBank].level > gBattleMons[battlerId].level) { - if (gBattleMons[opposingBank].level - gBattleMons[bank].level > 29) - AdjustFriendship(&gPlayerParty[gBattlerPartyIndexes[bank]], 8); + if (gBattleMons[opposingBank].level - gBattleMons[battlerId].level > 29) + AdjustFriendship(&gPlayerParty[gBattlerPartyIndexes[battlerId]], 8); else - AdjustFriendship(&gPlayerParty[gBattlerPartyIndexes[bank]], 6); + AdjustFriendship(&gPlayerParty[gBattlerPartyIndexes[battlerId]], 6); } else { - AdjustFriendship(&gPlayerParty[gBattlerPartyIndexes[bank]], 6); + AdjustFriendship(&gPlayerParty[gBattlerPartyIndexes[battlerId]], 6); } } -void sub_80571DC(u8 bank, u8 arg1) +void sub_80571DC(u8 battlerId, u8 arg1) { - if (GetBattlerSide(bank) != B_SIDE_OPPONENT) + if (GetBattlerSide(battlerId) != B_SIDE_OPPONENT) { s32 i; @@ -122,14 +117,14 @@ void sub_80571DC(u8 bank, u8 arg1) for (i = 0; i < 3; i++) gUnknown_0203CF00[i] = *(0 * 3 + i + (u8*)(gBattleStruct->field_60)); - sub_81B8FB0(pokemon_order_func(gBattlerPartyIndexes[bank]), pokemon_order_func(arg1)); + sub_81B8FB0(pokemon_order_func(gBattlerPartyIndexes[battlerId]), pokemon_order_func(arg1)); for (i = 0; i < 3; i++) *(0 * 3 + i + (u8*)(gBattleStruct->field_60)) = gUnknown_0203CF00[i]; } } -u32 sub_805725C(u8 bank) +u32 sub_805725C(u8 battlerId) { u32 effect = 0; @@ -138,12 +133,12 @@ u32 sub_805725C(u8 bank) switch (gBattleCommunication[MULTIUSE_STATE]) { case 0: - if (gBattleMons[bank].status1 & STATUS1_SLEEP) + if (gBattleMons[battlerId].status1 & STATUS1_SLEEP) { - if (UproarWakeUpCheck(bank)) + if (UproarWakeUpCheck(battlerId)) { - gBattleMons[bank].status1 &= ~(STATUS1_SLEEP); - gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); + gBattleMons[battlerId].status1 &= ~(STATUS1_SLEEP); + gBattleMons[battlerId].status2 &= ~(STATUS2_NIGHTMARE); BattleScriptPushCursor(); gBattleCommunication[MULTISTRING_CHOOSER] = 1; gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp; @@ -153,24 +148,24 @@ u32 sub_805725C(u8 bank) { u32 toSub; - if (gBattleMons[bank].ability == ABILITY_EARLY_BIRD) + if (gBattleMons[battlerId].ability == ABILITY_EARLY_BIRD) toSub = 2; else toSub = 1; - if ((gBattleMons[bank].status1 & STATUS1_SLEEP) < toSub) - gBattleMons[bank].status1 &= ~(STATUS1_SLEEP); + if ((gBattleMons[battlerId].status1 & STATUS1_SLEEP) < toSub) + gBattleMons[battlerId].status1 &= ~(STATUS1_SLEEP); else - gBattleMons[bank].status1 -= toSub; + gBattleMons[battlerId].status1 -= toSub; - if (gBattleMons[bank].status1 & STATUS1_SLEEP) + if (gBattleMons[battlerId].status1 & STATUS1_SLEEP) { gBattlescriptCurrInstr = BattleScript_MoveUsedIsAsleep; effect = 2; } else { - gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); + gBattleMons[battlerId].status2 &= ~(STATUS2_NIGHTMARE); BattleScriptPushCursor(); gBattleCommunication[MULTISTRING_CHOOSER] = 0; gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp; @@ -181,7 +176,7 @@ u32 sub_805725C(u8 bank) gBattleCommunication[MULTIUSE_STATE]++; break; case 1: - if (gBattleMons[bank].status1 & STATUS1_FREEZE) + if (gBattleMons[battlerId].status1 & STATUS1_FREEZE) { if (Random() % 5 != 0) { @@ -189,7 +184,7 @@ u32 sub_805725C(u8 bank) } else { - gBattleMons[bank].status1 &= ~(STATUS1_FREEZE); + gBattleMons[battlerId].status1 &= ~(STATUS1_FREEZE); BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze; gBattleCommunication[MULTISTRING_CHOOSER] = 0; @@ -206,7 +201,7 @@ u32 sub_805725C(u8 bank) if (effect == 2) { - gActiveBattler = bank; + gActiveBattler = battlerId; BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1); MarkBattlerForControllerExec(gActiveBattler); } diff --git a/src/berry_blender.c b/src/berry_blender.c index 45e3acd24..23594ba46 100644 --- a/src/berry_blender.c +++ b/src/berry_blender.c @@ -160,7 +160,7 @@ extern void sub_809882C(u8, u16, u8); extern void copy_textbox_border_tile_patterns_to_vram(u8, u16, u8); extern void sub_81AABF0(void (*callback)(void)); extern void sub_800B4C0(void); -extern void sub_8009F8C(void); +extern void ClearLinkCallback(void); extern void c2_exit_to_overworld_1_continue_scripts_restart_music(void); extern void sub_8153430(void); extern bool8 sub_8153474(void); @@ -952,10 +952,10 @@ static void sub_807FAC8(void) sBerryBlenderData->syncArrowSpriteIds[i] = CreateSprite(&sBlenderSyncArrow_SpriteTemplate, sBlenderSyncArrowsPos[i][0], sBlenderSyncArrowsPos[i][1], 1); StartSpriteAnim(&gSprites[sBerryBlenderData->syncArrowSpriteIds[i]], i + 8); } - if (gReceivedRemoteLinkPlayers != 0 && gLinkVSyncDisabled) + if (gReceivedRemoteLinkPlayers != 0 && gWirelessCommType) { sub_800E0E8(); - sub_800DFB4(0, 0); + CreateWirelessStatusIndicatorSprite(0, 0); } SetVBlankCallback(VBlankCB0_BerryBlender); sBerryBlenderData->mainState++; @@ -1158,10 +1158,10 @@ static void sub_8080018(void) sBerryBlenderData->syncArrowSprite2Ids[i] = CreateSprite(&sBlenderSyncArrow_SpriteTemplate, sBlenderSyncArrowsPos[i][0], sBlenderSyncArrowsPos[i][1], 1); StartSpriteAnim(&gSprites[sBerryBlenderData->syncArrowSprite2Ids[i]], i + 8); } - if (gReceivedRemoteLinkPlayers != 0 && gLinkVSyncDisabled) + if (gReceivedRemoteLinkPlayers != 0 && gWirelessCommType) { sub_800E0E8(); - sub_800DFB4(0, 0); + CreateWirelessStatusIndicatorSprite(0, 0); } sBerryBlenderData->mainState++; break; @@ -1874,7 +1874,7 @@ static void sub_8081370(u16 a0) static bool32 sub_80814B0(u16 arg0, u16 arg1, u16 arg2) { - if (gReceivedRemoteLinkPlayers != 0 && gLinkVSyncDisabled) + if (gReceivedRemoteLinkPlayers != 0 && gWirelessCommType) { if ((arg0 & 0xFF00) == arg2) return TRUE; @@ -2316,7 +2316,7 @@ static void sub_8081E20(void) static void sub_8081F94(u16 *a0) { - if (gReceivedRemoteLinkPlayers != 0 && gLinkVSyncDisabled) + if (gReceivedRemoteLinkPlayers != 0 && gWirelessCommType) *a0 = 0x2F00; else *a0 = 0x2FFF; @@ -2345,7 +2345,7 @@ static void CB2_HandleBlenderEndGame(void) sBerryBlenderData->field_4C -= 32; if (sBerryBlenderData->field_4C <= 0) { - sub_8009F8C(); + ClearLinkCallback(); sBerryBlenderData->field_4C = 0; if (gReceivedRemoteLinkPlayers != 0) @@ -2365,7 +2365,7 @@ static void CB2_HandleBlenderEndGame(void) } else if (sub_800A520()) { - if (gReceivedRemoteLinkPlayers != 0 && gLinkVSyncDisabled) + if (gReceivedRemoteLinkPlayers != 0 && gWirelessCommType) { sBerryBlenderData->gameBlock.timeRPM.time = sBerryBlenderData->gameFrameTime; sBerryBlenderData->gameBlock.timeRPM.max_RPM = sBerryBlenderData->max_RPM; @@ -2394,7 +2394,7 @@ static void CB2_HandleBlenderEndGame(void) ResetBlockReceivedFlags(); sBerryBlenderData->gameEndState++; - if (gReceivedRemoteLinkPlayers != 0 && gLinkVSyncDisabled) + if (gReceivedRemoteLinkPlayers != 0 && gWirelessCommType) { struct BlenderGameBlock *receivedBlock = (struct BlenderGameBlock*)(&gBlockRecvBuffer); @@ -2871,7 +2871,7 @@ static void sub_8082D28(void) if (gReceivedRemoteLinkPlayers != 0) playerId = GetMultiplayerId(); - if (gLinkVSyncDisabled && gReceivedRemoteLinkPlayers != 0) + if (gWirelessCommType && gReceivedRemoteLinkPlayers != 0) { if (playerId == 0) { @@ -463,7 +463,7 @@ bool8 IsDma3ManagerBusyWithBgCopy(void) return FALSE; } #else -__attribute__((naked)) +ASM_DIRECT bool8 IsDma3ManagerBusyWithBgCopy(void) { asm("push {r4-r7,lr}\n\ @@ -1048,7 +1048,7 @@ void CopyRectToBgTilemapBufferRect(u8 bg, const void* src, u8 srcX, u8 srcY, u8 } } }*/ -__attribute__((naked)) +ASM_DIRECT void CopyRectToBgTilemapBufferRect(u8 bg, const void* src, u8 srcX, u8 srcY, u8 srcWidth, u8 srcHeight, u8 destX, u8 destY, u8 rectWidth, u8 rectHeight, u8 palette1, u16 tileOffset, u16 palette2) { asm("push {r4-r7,lr}\n\ @@ -1495,7 +1495,7 @@ void CopyTileMapEntry(u16 *src, u16 *dest, s32 palette1, u32 tileOffset, u32 pal *dest = test; } #else -__attribute__((naked)) +ASM_DIRECT void CopyTileMapEntry(u16 *src, u16 *dest, s32 palette1, u32 tileOffset, u32 palette2) { asm("push {r4-r6,lr}\n\ diff --git a/src/braille_puzzles.c b/src/braille_puzzles.c index d6924de9f..55e75bfbf 100644 --- a/src/braille_puzzles.c +++ b/src/braille_puzzles.c @@ -421,7 +421,7 @@ bool8 ShouldDoBrailleRegicePuzzle(void) return FALSE; } #else -__attribute__((naked)) +ASM_DIRECT bool8 ShouldDoBrailleRegicePuzzle(void) { asm(".syntax unified\n\ diff --git a/src/calculate_base_damage.c b/src/calculate_base_damage.c deleted file mode 100644 index b6b83086b..000000000 --- a/src/calculate_base_damage.c +++ /dev/null @@ -1,283 +0,0 @@ -#include "global.h" -#include "constants/abilities.h" -#include "battle.h" -#include "constants/hold_effects.h" -#include "event_data.h" -#include "item.h" -#include "constants/items.h" -#include "pokemon.h" -#include "constants/species.h" -#include "constants/moves.h" -#include "constants/battle_move_effects.h" - -extern u32 gBattleTypeFlags; -extern struct BattlePokemon gBattleMons[4]; -extern u16 gCurrentMove; -extern u8 gCritMultiplier; -extern u16 gBattleWeather; -extern struct BattleEnigmaBerry gEnigmaBerries[]; -extern u16 gBattleMovePower; -extern u16 gTrainerBattleOpponent_A; - -bool8 ShouldGetStatBadgeBoost(u16 flagId, u8 bank); - -extern const struct BattleMove gBattleMoves[]; -extern const u8 gHoldEffectToType[][2]; -extern const u8 gStatStageRatios[][2]; - -#define APPLY_STAT_MOD(var, mon, stat, statIndex) \ -{ \ - (var) = (stat) * (gStatStageRatios)[(mon)->statStages[(statIndex)]][0]; \ - (var) /= (gStatStageRatios)[(mon)->statStages[(statIndex)]][1]; \ -} - -s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *defender, u32 move, u16 sideStatus, u16 powerOverride, u8 typeOverride, u8 bankAtk, u8 bankDef) -{ - u32 i; - s32 damage = 0; - s32 damageHelper; - u8 type; - u16 attack, defense; - u16 spAttack, spDefense; - u8 defenderHoldEffect; - u8 defenderHoldEffectParam; - u8 attackerHoldEffect; - u8 attackerHoldEffectParam; - - if (!powerOverride) - gBattleMovePower = gBattleMoves[move].power; - else - gBattleMovePower = powerOverride; - - if (!typeOverride) - type = gBattleMoves[move].type; - else - type = typeOverride & 0x3F; - - attack = attacker->attack; - defense = defender->defense; - spAttack = attacker->spAttack; - spDefense = defender->spDefense; - - if (attacker->item == ITEM_ENIGMA_BERRY) - { - attackerHoldEffect = gEnigmaBerries[bankAtk].holdEffect; - attackerHoldEffectParam = gEnigmaBerries[bankAtk].holdEffectParam; - } - else - { - attackerHoldEffect = ItemId_GetHoldEffect(attacker->item); - attackerHoldEffectParam = ItemId_GetHoldEffectParam(attacker->item); - } - - if (defender->item == ITEM_ENIGMA_BERRY) - { - defenderHoldEffect = gEnigmaBerries[bankDef].holdEffect; - defenderHoldEffectParam = gEnigmaBerries[bankDef].holdEffectParam; - } - else - { - defenderHoldEffect = ItemId_GetHoldEffect(defender->item); - defenderHoldEffectParam = ItemId_GetHoldEffectParam(defender->item); - } - - if (attacker->ability == ABILITY_HUGE_POWER || attacker->ability == ABILITY_PURE_POWER) - attack *= 2; - - if (ShouldGetStatBadgeBoost(FLAG_BADGE01_GET, bankAtk)) - attack = (110 * attack) / 100; - if (ShouldGetStatBadgeBoost(FLAG_BADGE05_GET, bankDef)) - defense = (110 * defense) / 100; - if (ShouldGetStatBadgeBoost(FLAG_BADGE07_GET, bankAtk)) - spAttack = (110 * spAttack) / 100; - if (ShouldGetStatBadgeBoost(FLAG_BADGE07_GET, bankDef)) - spDefense = (110 * spDefense) / 100; - - for (i = 0; i < 17; i++) - { - if (attackerHoldEffect == gHoldEffectToType[i][0] - && type == gHoldEffectToType[i][1]) - { - if (type <= 8) - attack = (attack * (attackerHoldEffectParam + 100)) / 100; - else - spAttack = (spAttack * (attackerHoldEffectParam + 100)) / 100; - break; - } - } - - if (attackerHoldEffect == HOLD_EFFECT_CHOICE_BAND) - attack = (150 * attack) / 100; - if (attackerHoldEffect == HOLD_EFFECT_SOUL_DEW && !(gBattleTypeFlags & (BATTLE_TYPE_FRONTIER)) && (attacker->species == SPECIES_LATIAS || attacker->species == SPECIES_LATIOS)) - spAttack = (150 * spAttack) / 100; - if (defenderHoldEffect == HOLD_EFFECT_SOUL_DEW && !(gBattleTypeFlags & (BATTLE_TYPE_FRONTIER)) && (defender->species == SPECIES_LATIAS || defender->species == SPECIES_LATIOS)) - spDefense = (150 * spDefense) / 100; - if (attackerHoldEffect == HOLD_EFFECT_DEEP_SEA_TOOTH && attacker->species == SPECIES_CLAMPERL) - spAttack *= 2; - if (defenderHoldEffect == HOLD_EFFECT_DEEP_SEA_SCALE && defender->species == SPECIES_CLAMPERL) - spDefense *= 2; - if (attackerHoldEffect == HOLD_EFFECT_LIGHT_BALL && attacker->species == SPECIES_PIKACHU) - spAttack *= 2; - if (defenderHoldEffect == HOLD_EFFECT_METAL_POWDER && defender->species == SPECIES_DITTO) - defense *= 2; - if (attackerHoldEffect == HOLD_EFFECT_THICK_CLUB && (attacker->species == SPECIES_CUBONE || attacker->species == SPECIES_MAROWAK)) - attack *= 2; - if (defender->ability == ABILITY_THICK_FAT && (type == TYPE_FIRE || type == TYPE_ICE)) - spAttack /= 2; - if (attacker->ability == ABILITY_HUSTLE) - attack = (150 * attack) / 100; - if (attacker->ability == ABILITY_PLUS && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_MINUS, 0, 0)) - spAttack = (150 * spAttack) / 100; - if (attacker->ability == ABILITY_MINUS && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_PLUS, 0, 0)) - spAttack = (150 * spAttack) / 100; - if (attacker->ability == ABILITY_GUTS && attacker->status1) - attack = (150 * attack) / 100; - if (defender->ability == ABILITY_MARVEL_SCALE && defender->status1) - defense = (150 * defense) / 100; - if (type == TYPE_ELECTRIC && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, 0, 0xFD, 0)) - gBattleMovePower /= 2; - if (type == TYPE_FIRE && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, 0, 0xFE, 0)) - gBattleMovePower /= 2; - if (type == TYPE_GRASS && attacker->ability == ABILITY_OVERGROW && attacker->hp <= (attacker->maxHP / 3)) - gBattleMovePower = (150 * gBattleMovePower) / 100; - if (type == TYPE_FIRE && attacker->ability == ABILITY_BLAZE && attacker->hp <= (attacker->maxHP / 3)) - gBattleMovePower = (150 * gBattleMovePower) / 100; - if (type == TYPE_WATER && attacker->ability == ABILITY_TORRENT && attacker->hp <= (attacker->maxHP / 3)) - gBattleMovePower = (150 * gBattleMovePower) / 100; - if (type == TYPE_BUG && attacker->ability == ABILITY_SWARM && attacker->hp <= (attacker->maxHP / 3)) - gBattleMovePower = (150 * gBattleMovePower) / 100; - if (gBattleMoves[gCurrentMove].effect == EFFECT_EXPLOSION) - defense /= 2; - - if (type < TYPE_MYSTERY) // is physical - { - if (gCritMultiplier == 2) - { - if (attacker->statStages[STAT_STAGE_ATK] > 6) - APPLY_STAT_MOD(damage, attacker, attack, STAT_STAGE_ATK) - else - damage = attack; - } - else - APPLY_STAT_MOD(damage, attacker, attack, STAT_STAGE_ATK) - - damage = damage * gBattleMovePower; - damage *= (2 * attacker->level / 5 + 2); - - if (gCritMultiplier == 2) - { - if (defender->statStages[STAT_STAGE_DEF] < 6) - APPLY_STAT_MOD(damageHelper, defender, defense, STAT_STAGE_DEF) - else - damageHelper = defense; - } - else - APPLY_STAT_MOD(damageHelper, defender, defense, STAT_STAGE_DEF) - - damage = damage / damageHelper; - damage /= 50; - - if ((attacker->status1 & STATUS1_BURN) && attacker->ability != ABILITY_GUTS) - damage /= 2; - - if ((sideStatus & SIDE_STATUS_REFLECT) && gCritMultiplier == 1) - { - if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && CountAliveMonsInBattle(2) == 2) - damage = 2 * (damage / 3); - else - damage /= 2; - } - - if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gBattleMoves[move].target == 8 && CountAliveMonsInBattle(2) == 2) - damage /= 2; - - // moves always do at least 1 damage. - if (damage == 0) - damage = 1; - } - - if (type == TYPE_MYSTERY) - damage = 0; // is ??? type. does 0 damage. - - if (type > TYPE_MYSTERY) // is special? - { - if (gCritMultiplier == 2) - { - if (attacker->statStages[STAT_STAGE_SPATK] > 6) - APPLY_STAT_MOD(damage, attacker, spAttack, STAT_STAGE_SPATK) - else - damage = spAttack; - } - else - APPLY_STAT_MOD(damage, attacker, spAttack, STAT_STAGE_SPATK) - - damage = damage * gBattleMovePower; - damage *= (2 * attacker->level / 5 + 2); - - if (gCritMultiplier == 2) - { - if (defender->statStages[STAT_STAGE_SPDEF] < 6) - APPLY_STAT_MOD(damageHelper, defender, spDefense, STAT_STAGE_SPDEF) - else - damageHelper = spDefense; - } - else - APPLY_STAT_MOD(damageHelper, defender, spDefense, STAT_STAGE_SPDEF) - - damage = (damage / damageHelper); - damage /= 50; - - if ((sideStatus & SIDE_STATUS_LIGHTSCREEN) && gCritMultiplier == 1) - { - if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && CountAliveMonsInBattle(2) == 2) - damage = 2 * (damage / 3); - else - damage /= 2; - } - - if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gBattleMoves[move].target == 8 && CountAliveMonsInBattle(2) == 2) - damage /= 2; - - // are effects of weather negated with cloud nine or air lock - if (!AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_CLOUD_NINE, 0, 0) - && !AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_AIR_LOCK, 0, 0)) - { - if (gBattleWeather & WEATHER_RAIN_TEMPORARY) - { - switch (type) - { - case TYPE_FIRE: - damage /= 2; - break; - case TYPE_WATER: - damage = (15 * damage) / 10; - break; - } - } - - // any weather except sun weakens solar beam - if ((gBattleWeather & (WEATHER_RAIN_ANY | WEATHER_SANDSTORM_ANY | WEATHER_HAIL)) && gCurrentMove == MOVE_SOLAR_BEAM) - damage /= 2; - - // sunny - if (gBattleWeather & WEATHER_SUN_ANY) - { - switch (type) - { - case TYPE_FIRE: - damage = (15 * damage) / 10; - break; - case TYPE_WATER: - damage /= 2; - break; - } - } - } - - // flash fire triggered - if ((gBattleResources->flags->flags[bankAtk] & UNKNOWN_FLAG_FLASH_FIRE) && type == TYPE_FIRE) - damage = (15 * damage) / 10; - } - - return damage + 2; -} diff --git a/src/clear_save_data_screen.c b/src/clear_save_data_screen.c index 6d6a1545b..ca2037d2f 100644 --- a/src/clear_save_data_screen.c +++ b/src/clear_save_data_screen.c @@ -14,8 +14,6 @@ extern u8 gText_ClearAllSaveData[]; extern u8 gText_ClearingData[]; -extern u16 gUnknown_0860F074[]; - static void Task_DoClearSaveDataScreenYesNo(u8); static void Task_ClearSaveDataScreenYesNoChoice(u8); static void Task_ClearSaveData(u8); diff --git a/src/decompress.c b/src/decompress.c index 8e8827194..fb288bf4a 100644 --- a/src/decompress.c +++ b/src/decompress.c @@ -117,7 +117,7 @@ void Unused_LZDecompressWramIndirect(const void **src, void *dest) } // This one (unused) function is really challenging, won't even try to decompile it. -__attribute__((naked)) +ASM_DIRECT void sub_803471C() { asm(".syntax unified\n\ diff --git a/src/decoration.c b/src/decoration.c index db19ff4c6..8eb875560 100644 --- a/src/decoration.c +++ b/src/decoration.c @@ -2542,7 +2542,7 @@ void sub_812A0E8(u8 taskId) } } #else -__attribute__((naked)) void sub_812A0E8(u8 taskId) +ASM_DIRECT void sub_812A0E8(u8 taskId) { asm_unified("\tpush {r4-r7,lr}\n" "\tlsls r0, 24\n" diff --git a/src/egg_hatch.c b/src/egg_hatch.c index 5a2fe5ca2..b78b9433e 100644 --- a/src/egg_hatch.c +++ b/src/egg_hatch.c @@ -44,7 +44,6 @@ struct EggHatchData u8 textColor[3]; }; -extern struct SpriteTemplate gUnknown_0202499C; extern void (*gFieldCallback)(void); extern const struct CompressedSpriteSheet gMonFrontPicTable[]; @@ -58,20 +57,14 @@ extern const u8 gText_HatchedFromEgg[]; extern const u8 gText_NickHatchPrompt[]; extern u8 sav1_map_get_name(void); -extern s8 ProcessMenuInputNoWrap_(void); extern void TVShowConvertInternationalString(u8* str1, u8* str2, u8); extern void sub_806A068(u16, u8); extern void FadeScreen(u8, u8); extern void overworld_free_bg_tilemaps(void); extern void sub_80AF168(void); -extern void AllocateMonSpritesGfx(void); -extern void FreeMonSpritesGfx(void); extern void ScanlineEffect_Stop(void); -extern void reset_temp_tile_data_buffers(void); extern void c2_exit_to_overworld_2_switch(void); extern void play_some_sound(void); -extern void copy_decompressed_tile_data_to_vram_autofree(u8 bg_id, const void* src, u16 size, u16 offset, u8 mode); -extern void CreateYesNoMenu(const struct WindowTemplate*, u16, u8, u8); extern void DoNamingScreen(u8, const u8*, u16, u8, u32, MainCallback); extern u16 sub_80D22D0(void); extern u8 CountPartyAliveNonEggMonsExcept(u8); @@ -440,12 +433,12 @@ static u8 EggHatchCreateMonSprite(u8 a0, u8 switchID, u8 pokeID, u16* speciesLoc HandleLoadSpecialPokePic_DontHandleDeoxys(&gMonFrontPicTable[species], gMonSpritesGfxPtr->sprites[(a0 * 2) + 1], species, pid); - LoadCompressedObjectPalette(sub_806E794(mon)); + LoadCompressedObjectPalette(GetMonSpritePalStruct(mon)); *speciesLoc = species; } break; case 1: - sub_806A068(sub_806E794(mon)->tag, r5); + sub_806A068(GetMonSpritePalStruct(mon)->tag, r5); spriteID = CreateSprite(&gUnknown_0202499C, 120, 75, 6); gSprites[spriteID].invisible = 1; gSprites[spriteID].callback = SpriteCallbackDummy; diff --git a/src/evolution_scene.c b/src/evolution_scene.c index ec99fb030..1b929c9bd 100644 --- a/src/evolution_scene.c +++ b/src/evolution_scene.c @@ -21,7 +21,7 @@ #include "constants/songs.h" #include "overworld.h" #include "battle_message.h" -#include "battle_string_ids.h" +#include "constants/battle_string_ids.h" #include "gpu_regs.h" #include "bg.h" #include "link.h" @@ -48,13 +48,10 @@ extern u16 gBattle_BG2_X; extern u16 gBattle_BG2_Y; extern u16 gBattle_BG3_X; extern u16 gBattle_BG3_Y; -extern u8 gBattleTerrain; -extern struct SpriteTemplate gUnknown_0202499C; extern bool8 gAffineAnimsDisabled; extern u16 gMoveToLearn; extern const u8 gSpeciesNames[][11]; -extern u8 gBattleCommunication[]; #define sEvoCursorPos gBattleCommunication[1] // when learning a new move #define sEvoGraphicsTaskID gBattleCommunication[2] @@ -69,9 +66,6 @@ extern const u8 gText_PkmnStoppedEvolving[]; extern const u8 gText_EllipsisQuestionMark[]; extern const u8 gText_CommunicationStandby5[]; -extern void copy_decompressed_tile_data_to_vram_autofree(u8 arg0, const void *arg1, bool32 arg2, u16 arg3, u8 arg4); -extern u32 sub_80391E0(u8, u8); -extern void SpriteCallbackDummy_2(struct Sprite *sprite); extern void sub_80356D0(void); extern void sub_807B154(void); extern void sub_806A068(u16, u8); @@ -473,10 +467,10 @@ static void CB2_TradeEvolutionSceneLoadGraphics(void) } break; case 6: - if (gLinkVSyncDisabled) + if (gWirelessCommType) { sub_800E0E8(); - sub_800DFB4(0, 0); + CreateWirelessStatusIndicatorSprite(0, 0); } BlendPalettes(-1,0x10, 0); gMain.state++; @@ -1257,7 +1251,7 @@ static void Task_TradeEvolutionScene(u8 taskID) case 5: if (!gPaletteFade.active) { - if (gLinkVSyncDisabled) + if (gWirelessCommType) sub_800E084(); Free(GetBgTilemapBuffer(3)); diff --git a/src/item_menu.c b/src/item_menu.c new file mode 100755 index 000000000..ecd910b65 --- /dev/null +++ b/src/item_menu.c @@ -0,0 +1,2448 @@ +#include "global.h" +#include "battle.h" +#include "battle_controllers.h" +#include "battle_frontier_2.h" +#include "berry_tag_screen.h" +#include "bg.h" +#include "constants/items.h" +#include "constants/songs.h" +#include "decompress.h" +#include "event_data.h" +#include "field_map_obj_helpers.h" +#include "field_player_avatar.h" +#include "field_specials.h" +#include "graphics.h" +#include "gpu_regs.h" +#include "international_string_util.h" +#include "item.h" +#include "item_menu_icons.h" +#include "item_use.h" +#include "lilycove_lady.h" +#include "list_menu.h" +#include "link.h" +#include "mail.h" +#include "main.h" +#include "malloc.h" +#include "map_name_popup.h" +#include "menu.h" +#include "menu_indicators.h" +#include "money.h" +#include "overworld.h" +#include "palette.h" +#include "party_menu.h" +#include "player_pc.h" +#include "pokemon.h" +#include "pokemon_summary_screen.h" +#include "rom_818CFC8.h" +#include "scanline_effect.h" +#include "script.h" +#include "shop.h" +#include "sound.h" +#include "sprite.h" +#include "string.h" +#include "strings.h" +#include "string_util.h" +#include "task.h" +#include "text_window.h" +#include "menu_helpers.h" +#include "window.h" + +void GoToBagMenu(u8 bagMenuType, u8 pocketId, void ( *postExitMenuMainCallback2)()); +void CB2_Bag(void); +bool8 setup_bag_menu(void); +void bag_menu_init_bgs(void); +bool8 load_bag_menu_graphics(void); +void setup_bag_menu_textboxes(void); +void allocate_bag_item_list_buffers(void); +void load_bag_item_list_buffers(u8); +void bag_menu_print_pocket_names(u8*, u8*); +void bag_menu_copy_pocket_name_to_window(u32); +void bag_menu_draw_pocket_indicator_square(u8, u8); +void AddBagVisualObject(u8); +void bag_menu_add_pocket_scroll_arrow_indicators_maybe(void); +void bag_menu_add_list_scroll_arrow_indicators_maybe(void); +void bag_menu_prepare_tmhm_move_window(void); +bool8 IsWallysBag(void); +void Task_WallyTutorialBagMenu(u8); +void Task_BagMenu(u8); +void get_name(s8*, u16); +u16 ItemIdToBattleMoveId(u16); +void ShakeBagVisual(void); +u16 BagGetItemIdByPocketPosition(u8, u16); +void AddBagItemIconObject(u16, u8); +void bag_menu_print_description_box_text(int); +void bag_menu_print_cursor(u8, u8); +void bag_menu_print(u8, u8, const u8*, u8, u8, u8, u8, u8, u8); +bool8 itemid_is_unique(u16); +u16 BagGetQuantityByPocketPosition(u8, u16); +void sub_81AB89C(void); +void task_close_bag_menu_2(u8); +u8 AddItemMessageWindow(u8); +void bag_menu_RemoveBagItem_message_window(u8); +void set_callback3_to_bag(u8); +void sub_81ABC54(u8, s16); +u8 bag_menu_add_window(u8); +u8 GetSwitchBagPocketDirection(void); +void SwitchBagPocket(u8, s16, u16); +bool8 sub_81AC2C0(void); +void bag_menu_swap_items(u8); +void SetBagVisualPocketId(u8, u8); +void RemoveBagObject(u8); +void AddSwitchPocketRotatingBallObject(s16); +void sub_81AC10C(u8); +void sub_81AC3C0(u8); +void sub_81AC498(u8); +void sub_81AC590(u8); +void PrintTMHMMoveData(u16); +void sub_81ACAF8(u8); +void sub_81ACB54(u8, u8, u8); +void Task_HandleInBattleItemMenuInput(u8); +void Task_HandleOutOfBattleItemMenuInput(u8); +bool8 sub_81ACDFC(s8); +void bag_menu_remove_window(u8); +void bag_menu_print_there_is_no_pokemon(u8); +void Task_ChooseHowManyToToss(u8); +void BagMenuConfirmToss(u8); +void bag_menu_yes_no(u8, u8, const struct YesNoFuncTable*); +void Task_ActuallyToss(u8); +void ItemMenu_Cancel(u8); +void sub_81AD350(u8); +void bag_menu_print_cant_be_held_msg(u8); +void bag_menu_AddMoney_window(void); +void sub_81AD680(u8); +void sub_81AD730(u8); +void sub_81AD6E4(u8); +void bag_menu_remove_money_window(void); +void bag_menu_RemoveBagItem_message_window(u8); +void sub_81AD794(u8); +void sub_81AD8C8(u8); +void sub_81AD9C0(u8); +void sub_81ADB14(u8); +void sub_81ADA7C(u8); +void sub_81ADC0C(u8); +void bag_menu_leave_maybe_3(void); +void bag_menu_leave_maybe_2(void); +void bag_menu_leave_maybe(void); +void sub_81ABA6C(void); +void sub_81ABAC4(void); +void sub_81ABAE0(void); +u8 sub_81AB1F0(u8); +void sub_81AC23C(u8); +void bag_menu_change_item_callback(u32 a, bool8 b, struct ListMenu*); +void sub_81AB520(u8 rboxId, int item_index_in_pocket, u8 a); +void ItemMenu_UseOutOfBattle(u8 taskId); +void ItemMenu_Toss(u8 taskId); +void ItemMenu_Register(u8 taskId); +void ItemMenu_Give(u8 taskId); +void ItemMenu_Cancel(u8 taskId); +void ItemMenu_UseInBattle(u8 taskId); +void ItemMenu_CheckTag(u8 taskId); +void unknown_ItemMenu_Confirm(u8 taskId); +void unknown_ItemMenu_Show(u8 taskId); +void unknown_ItemMenu_Give2(u8 taskId); +void unknown_ItemMenu_Confirm2(u8 taskId); +void unknown_item_menu_type(u8 taskId); +void item_menu_type_2(u8 taskId); +void display_sell_item_ask_str(u8 taskId); +void unknown_ItemMenu_Confirm(u8 taskId); +void display_deposit_item_ask_str(u8 taskId); +void item_menu_type_b(u8 taskId); +void BagMenuActuallyToss(u8 taskId); +void BagMenuCancelToss(u8 taskId); +void sub_81AD84C(u8 taskId); +void sub_81AD6FC(u8 taskId); + +// .rodata + +const struct BgTemplate gUnknown_08613F90[3] = { + {0, 0, 31, 0, 0, 1, 0}, + {1, 0, 30, 0, 0, 0, 0}, + {2, 3, 29, 0, 0, 2, 0} +}; + +const struct ListMenuTemplate gUnknown_08613F9C = { + NULL, bag_menu_change_item_callback, sub_81AB520, 0, 0, 0, 0, 8, 0, 1, 1, 0, 3, 0, 0, 0, 7, 0 +}; + +const struct MenuAction gUnknown_08613FB4[] = { + {gMenuText_Use, ItemMenu_UseOutOfBattle}, + {gMenuText_Toss, ItemMenu_Toss}, + {gMenuText_Register, ItemMenu_Register}, + {gMenuText_Give, ItemMenu_Give}, + {gText_Cancel2, ItemMenu_Cancel}, + {gMenuText_Use, ItemMenu_UseInBattle}, + {gMenuText_Check, ItemMenu_UseOutOfBattle}, + {gMenuText_Walk, ItemMenu_UseOutOfBattle}, + {gMenuText_Deselect, ItemMenu_Register}, + {gMenuText_CheckTag, ItemMenu_CheckTag}, + {gMenuText_Confirm, unknown_ItemMenu_Confirm}, + {gMenuText_Show, unknown_ItemMenu_Show}, + {gMenuText_Give2, unknown_ItemMenu_Give2}, + {gMenuText_Confirm, unknown_ItemMenu_Confirm2}, + {gText_EmptyString2, NULL} +}; + +const u8 gUnknown_0861402C[] = {0, 3, 1, 4}; +const u8 gUnknown_08614030[] = {0, 2, 14, 4}; +const u8 gUnknown_08614034[] = {3, 14, 1, 4}; +const u8 gUnknown_08614038[] = {0, 3, 14, 4}; +const u8 gUnknown_0861403C[] = {9, 14, 0, 3, 1, 4}; +const u8 gUnknown_08614042[] = {5, 4}; +const u8 gUnknown_08614044[] = {3, 4}; +const u8 gUnknown_08614046 = 4; +const u8 gUnknown_08614047[] = {10, 9, 14, 4}; +const u8 gUnknown_0861404B[] = {11, 4}; +const u8 gUnknown_0861404D[] = {12, 4}; +const u8 gUnknown_0861404F[] = {13, 4}; + +const TaskFunc gUnknown_08614054[] = { + unknown_item_menu_type, + unknown_item_menu_type, + item_menu_type_2, + display_sell_item_ask_str, + unknown_ItemMenu_Confirm, + unknown_item_menu_type, + display_deposit_item_ask_str, + unknown_item_menu_type, + unknown_item_menu_type, + unknown_item_menu_type, + NULL, + item_menu_type_b +}; + +const struct YesNoFuncTable gUnknown_08614084 = {BagMenuActuallyToss, BagMenuCancelToss}; + +const struct YesNoFuncTable gUnknown_0861408C = {sub_81AD84C, sub_81AD6FC}; + +const struct ArrowStruct gUnknown_08614094 = {0, 0x1C, 16, 1, 100, 16, -1, -1, 0x6F, 0x6F, 0}; + +const u8 gUnknown_086140A4[] = INCBIN_U8("graphics/interface/select_button.4bpp"); + +const u8 gUnknown_08614164[][3] = { + {0, 1, 3}, + {0, 1, 4}, + {0, 3, 6}, + {2, 1, 3}, + {0, 14, 10} +}; + +const struct WindowTemplate gUnknown_08614174[] = { + {0, 14, 2, 15, 16, 1, 0x27}, + {0, 0, 13, 14, 6, 1, 0x117}, + {0, 4, 1, 8, 2, 1, 0x1A1}, + {0, 1, 13, 5, 6, 12, 0x16B}, + {0, 7, 13, 4, 6, 12, 0x189}, + {1, 2, 15, 27, 4, 15, 0x1B1}, + {0xFF, 0, 0, 0, 0, 0, 0} +}; + +const struct WindowTemplate gUnknown_086141AC[] = { + {1, 22, 17, 7, 2, 15, 0x21D}, + {1, 22, 15, 7, 4, 15, 0x21D}, + {1, 15, 15, 14, 4, 15, 0x21D}, + {1, 15, 13, 14, 6, 15, 0x21D}, + {1, 2, 15, 27, 4, 15, 0x1B1}, + {1, 24, 15, 5, 4, 15, 0x21D}, + {1, 21, 9, 5, 4, 15, 0x21D}, + {1, 24, 17, 5, 2, 15, 0x21D}, + {1, 18, 11, 10, 2, 15, 0x245}, + {1, 1, 1, 10, 2, 15, 0x231} +}; + +// .text + +struct BagStruct { + void (*bagCallback)(void); + u8 location; + u8 pocket; + u8 unk6[2]; + u16 cursorPosition[5]; + u16 scrollPosition[5]; +}; + +struct UnkBagStruct { + MainCallback unk0; + u8 unk4[0x800]; + u8 unk804; + u8 unk805; + u8 unk806[10]; + u8 unk810[7]; + u8 unk817; + u8 unk818; + u8 unk819; + u8 unk81A; + u8 unk81B:4; + u8 unk81B_1:2; + u8 unk81B_3:1; + u8 unk81B_2:1; + u8 filler3[2]; + u8 unk81E; + u8 unk81F; + const u8* unk820; + u8 unk824; + u8 unk825; + u8 filler[2]; + u8 unk828; + u8 unk829[5]; + u8 unk82E[6]; + s16 unk834; + u8 filler4[0xE]; + u8 unk844[32][32]; + u8 filler2[4]; +}; + +struct ListBuffer1 { + struct ListMenuItem subBuffers[65]; +}; + +struct ListBuffer2 { + s8 name[65][24]; +}; + +struct TempWallyStruct { + struct ItemSlot bagPocket_Items[30]; + struct ItemSlot bagPocket_PokeBalls[16]; + u16 cursorPosition[5]; + u16 scrollPosition[5]; + u8 filler[0x2]; + u16 pocket; +}; + +EWRAM_DATA struct UnkBagStruct *gUnknown_0203CE54 = 0; +EWRAM_DATA struct BagStruct gUnknown_0203CE58 = {0, 0, 0, {0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}}; +EWRAM_DATA struct ListBuffer1 *gUnknown_0203CE74 = 0; +EWRAM_DATA struct ListBuffer2 *gUnknown_0203CE78 = 0; +EWRAM_DATA u16 gSpecialVar_ItemId = 0; +EWRAM_DATA struct TempWallyStruct *gUnknown_0203CE80 = 0; + +void (*gFieldCallback)(void); + +extern u8 *gPocketNamesStringsTable[]; +extern u8 gUnknown_08D9A88C[]; +extern struct CompressedSpriteSheet gUnknown_0857FB34; +extern struct CompressedSpriteSheet gUnknown_0857FB3C; +extern struct CompressedSpritePalette gUnknown_0857FB44; +extern struct ListMenuTemplate gUnknown_08613F9C; +extern u8 gMoveNames[][0xD]; +extern u8* gReturnToXStringsTable[]; +extern u32 gUnknown_0203CE5E[]; +extern u8 EventScript_2736B3[]; +extern const u16 gUnknown_0860F074[]; +extern struct BattleMove gBattleMoves[]; + +void ResetBagScrollPositions(void) +{ + gUnknown_0203CE58.pocket = 0; + memset(gUnknown_0203CE58.cursorPosition, 0, 10); + memset(gUnknown_0203CE58.scrollPosition, 0, 10); +} + +void CB2_BagMenuFromStartMenu(void) +{ + GoToBagMenu(0, 5, sub_8086194); +} + +void sub_81AABB0(void) +{ + if (!InBattlePyramid()) + GoToBagMenu(1, 5, SetCB2ToReshowScreenAfterMenu2); + else + sub_81C4F98(1, SetCB2ToReshowScreenAfterMenu2); +} + +void CB2_ChooseBerry(void) +{ + GoToBagMenu(4, 3, sub_80861B0); +} + +void sub_81AABF0(void(*callback)(void)) +{ + GoToBagMenu(5, 3, callback); +} + +void CB2_GoToSellMenu(void) +{ + GoToBagMenu(3, 5, CB2_ExitSellMenu); +} + +void sub_81AAC14(void) +{ + GoToBagMenu(6, 5, sub_816B31C); +} + +void sub_81AAC28(void) +{ + GoToBagMenu(9, 5, bag_menu_leave_maybe_3); + gSpecialVar_0x8005 = 0; + gSpecialVar_Result = 0; +} + +void sub_81AAC50(void) +{ + GoToBagMenu(7, 5, bag_menu_leave_maybe_2); + gSpecialVar_Result = 0; +} + +void sub_81AAC70(void) +{ + GoToBagMenu(8, 5, bag_menu_leave_maybe); + gSpecialVar_Result = 0; +} + +void GoToBagMenu(u8 bagMenuType, u8 pocketId, void ( *postExitMenuMainCallback2)()) +{ + u8 temp; + gUnknown_0203CE54 = AllocZeroed(sizeof(struct UnkBagStruct)); + if (gUnknown_0203CE54 == 0) + { + SetMainCallback2(postExitMenuMainCallback2); + } + else + { + if (bagMenuType != 12) + gUnknown_0203CE58.location = bagMenuType; + if (postExitMenuMainCallback2) + gUnknown_0203CE58.bagCallback = postExitMenuMainCallback2; + if (pocketId <= 4) + gUnknown_0203CE58.pocket = pocketId; + temp = gUnknown_0203CE58.location - 4; + if (temp <= 1) + gUnknown_0203CE54->unk81B = 1; + gUnknown_0203CE54->unk0 = 0; + gUnknown_0203CE54->unk81A = 0xFF; + gUnknown_0203CE54->unk81E = -1; + gUnknown_0203CE54->unk81F = -1; + memset(&gUnknown_0203CE54->unk804, 0xFF, 12); + memset(gUnknown_0203CE54->unk810, 0xFF, 10); + SetMainCallback2(CB2_Bag); + } +} + +void c2_bag_3(void) +{ + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + do_scheduled_bg_tilemap_copies_to_vram(); + UpdatePaletteFade(); +} + +void vblank_cb_bag_menu(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +void CB2_Bag(void) +{ + while(sub_81221EC() != TRUE && setup_bag_menu() != TRUE && sub_81221AC() != TRUE) {}; +} + +bool8 setup_bag_menu(void) +{ + u32 index; + u8 taskId; + + switch (gMain.state) + { + case 0: + SetVBlankHBlankCallbacksToNull(); + clear_scheduled_bg_copies_to_vram(); + gMain.state++; + break; + case 1: + ScanlineEffect_Stop(); + gMain.state++; + break; + case 2: + FreeAllSpritePalettes(); + gMain.state++; + break; + case 3: + ResetPaletteFade(); + gPaletteFade.bufferTransferDisabled = TRUE; + gMain.state++; + break; + case 4: + ResetSpriteData(); + gMain.state++; + break; + case 5: + gMain.state++; + break; + case 6: + if (sub_81221AC() == FALSE) + ResetTasks(); + gMain.state++; + break; + case 7: + bag_menu_init_bgs(); + gUnknown_0203CE54->unk834 = 0; + gMain.state++; + break; + case 8: + if (!load_bag_menu_graphics()) + break; + gMain.state++; + break; + case 9: + setup_bag_menu_textboxes(); + gMain.state++; + break; + case 10: + sub_81ABA6C(); + sub_81ABAC4(); + sub_81ABAE0(); + gMain.state++; + break; + case 11: + allocate_bag_item_list_buffers(); + gMain.state++; + break; + case 12: + load_bag_item_list_buffers(gUnknown_0203CE58.pocket); + gMain.state++; + break; + case 13: + bag_menu_print_pocket_names(gPocketNamesStringsTable[gUnknown_0203CE58.pocket], 0); + bag_menu_copy_pocket_name_to_window(0); + bag_menu_draw_pocket_indicator_square(gUnknown_0203CE58.pocket, 1); + gMain.state++; + break; + case 14: + taskId = sub_81AB1F0(gUnknown_0203CE58.location); + gTasks[taskId].data[0] = ListMenuInit(&gMultiuseListMenuTemplate, gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket], gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]); + gTasks[taskId].data[3] = 0; + gTasks[taskId].data[8] = 0; + gMain.state++; + break; + case 15: + AddBagVisualObject(gUnknown_0203CE58.pocket); + gMain.state++; + break; + case 16: + sub_80D4FAC(); + gMain.state++; + break; + case 17: + bag_menu_add_pocket_scroll_arrow_indicators_maybe(); + bag_menu_add_list_scroll_arrow_indicators_maybe(); + gMain.state++; + break; + case 18: + bag_menu_prepare_tmhm_move_window(); + gMain.state++; + break; + case 19: + BlendPalettes(-1, 16, 0); + gMain.state++; + break; + case 20: + BeginNormalPaletteFade(-1, 0, 16, 0, 0); + gPaletteFade.bufferTransferDisabled = FALSE; + gMain.state++; + break; + default: + SetVBlankCallback(vblank_cb_bag_menu); + SetMainCallback2(c2_bag_3); + return TRUE; + } + return FALSE; +} + +void bag_menu_init_bgs(void) +{ + ResetVramOamAndBgCntRegs(); + memset(gUnknown_0203CE54->unk4, 0, 0x800); + ResetBgsAndClearDma3BusyFlags(0); + InitBgsFromTemplates(0, gUnknown_08613F90, 3); + SetBgTilemapBuffer(2, gUnknown_0203CE54->unk4); + ResetAllBgsCoordinates(); + schedule_bg_copy_tilemap_to_vram(2); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); + ShowBg(0); + ShowBg(1); + ShowBg(2); + SetGpuReg(REG_OFFSET_BLDCNT, 0); +} + +bool8 load_bag_menu_graphics(void) +{ + switch (gUnknown_0203CE54->unk834) + { + case 0: + reset_temp_tile_data_buffers(); + decompress_and_copy_tile_data_to_vram(2, gBagScreen_Gfx, 0, 0, 0); + gUnknown_0203CE54->unk834++; + break; + case 1: + if (free_temp_tile_data_buffers_if_possible() != TRUE) + { + LZDecompressWram(gUnknown_08D9A88C, gUnknown_0203CE54->unk4); + gUnknown_0203CE54->unk834++; + } + break; + case 2: + if (!IsWallysBag() && gSaveBlock2Ptr->playerGender != MALE) + LoadCompressedPalette(gBagScreenFemale_Pal, 0, 0x40); + else + LoadCompressedPalette(gBagScreenMale_Pal, 0, 0x40); + gUnknown_0203CE54->unk834++; + break; + case 3: + if (IsWallysBag() == TRUE || gSaveBlock2Ptr->playerGender == MALE) + LoadCompressedObjectPic(&gUnknown_0857FB34); + else + LoadCompressedObjectPic(&gUnknown_0857FB3C); + gUnknown_0203CE54->unk834++; + break; + case 4: + LoadCompressedObjectPalette(&gUnknown_0857FB44); + gUnknown_0203CE54->unk834++; + break; + default: + LoadListMenuArrowsGfx(); + gUnknown_0203CE54->unk834 = 0; + return TRUE; + } + return FALSE; +} + +u8 sub_81AB1F0(u8 a) +{ + u8 taskId; + if (a == 10) + taskId = CreateTask(Task_WallyTutorialBagMenu, 0); + else + taskId = CreateTask(Task_BagMenu, 0); + return taskId; +} + +void allocate_bag_item_list_buffers(void) +{ + gUnknown_0203CE74 = Alloc(sizeof(struct ListBuffer1)); + gUnknown_0203CE78 = Alloc(sizeof(struct ListBuffer2)); +} + +void load_bag_item_list_buffers(u8 pocketId) +{ + u16 i; + struct BagPocket *pocket = &gBagPockets[pocketId]; + struct ListMenuItem *subBuffer; + + if (!gUnknown_0203CE54->unk81B_2) + { + for (i = 0; i < gUnknown_0203CE54->unk829[pocketId] - 1; i++) + { + get_name(gUnknown_0203CE78->name[i], pocket->itemSlots[i].itemId); + subBuffer = gUnknown_0203CE74->subBuffers; + subBuffer[i].name = gUnknown_0203CE78->name[i]; + subBuffer[i].id = i; + } + StringCopy(gUnknown_0203CE78->name[i], gText_CloseBag); + subBuffer = gUnknown_0203CE74->subBuffers; + subBuffer[i].name = gUnknown_0203CE78->name[i]; + subBuffer[i].id = -2; + } + else + { + for (i = 0; i < gUnknown_0203CE54->unk829[pocketId]; i++) + { + get_name(gUnknown_0203CE78->name[i], pocket->itemSlots[i].itemId); + subBuffer = gUnknown_0203CE74->subBuffers; + subBuffer[i].name = gUnknown_0203CE78->name[i]; + subBuffer[i].id = i; + } + } + gMultiuseListMenuTemplate = gUnknown_08613F9C; + gMultiuseListMenuTemplate.totalItems = gUnknown_0203CE54->unk829[pocketId]; + gMultiuseListMenuTemplate.items = gUnknown_0203CE74->subBuffers; + gMultiuseListMenuTemplate.maxShowed = gUnknown_0203CE54->unk82E[pocketId]; +} + +void get_name(s8 *dest, u16 itemId) +{ + switch (gUnknown_0203CE58.pocket) + { + case 2: + StringCopy(gStringVar2, gMoveNames[ItemIdToBattleMoveId(itemId)]); + if (itemId >= ITEM_HM01) + { + ConvertIntToDecimalStringN(gStringVar1, itemId - ITEM_HM01 + 1, 2, 1); + StringExpandPlaceholders(dest, gText_ClearTo11Var1Clear5Var2); + } + else + { + ConvertIntToDecimalStringN(gStringVar1, itemId - ITEM_TM01 + 1, 2, 2); + StringExpandPlaceholders(dest, gText_UnkF908Var1Clear7Var2); + } + break; + case 3: + ConvertIntToDecimalStringN(gStringVar1, itemId - ITEM_CHERI_BERRY + 1, 2, 2); + CopyItemName(itemId, gStringVar2); + StringExpandPlaceholders(dest, gText_UnkF908Var1Clear7Var2); + break; + default: + CopyItemName(itemId, dest); + break; + } +} + +void bag_menu_change_item_callback(u32 a, bool8 b, struct ListMenu *unused) +{ + if (b != 1) + { + PlaySE(SE_SELECT); + ShakeBagVisual(); + } + if (gUnknown_0203CE54->unk81A == 0xFF) + { + RemoveBagItemIconObject(1 ^ gUnknown_0203CE54->unk81B_1); + if (a != -2) + AddBagItemIconObject(BagGetItemIdByPocketPosition(gUnknown_0203CE58.pocket + 1, a), gUnknown_0203CE54->unk81B_1); + else + AddBagItemIconObject(-1, gUnknown_0203CE54->unk81B_1); + gUnknown_0203CE54->unk81B_1 ^= 1; + if (!gUnknown_0203CE54->unk81B_3) + bag_menu_print_description_box_text(a); + } +} + +void sub_81AB520(u8 rboxId, int item_index_in_pocket, u8 a) +{ + u16 itemId; + u16 itemQuantity; + bool8 unique; + int offset; + if (item_index_in_pocket != -2) + { + if (gUnknown_0203CE54->unk81A != 0xFF) + { + if (gUnknown_0203CE54->unk81A == (u8)item_index_in_pocket) + bag_menu_print_cursor(a, 2); + else + bag_menu_print_cursor(a, -1); + } + itemId = BagGetItemIdByPocketPosition(gUnknown_0203CE58.pocket + 1, item_index_in_pocket); + itemQuantity = BagGetQuantityByPocketPosition(gUnknown_0203CE58.pocket + 1, item_index_in_pocket); + if ((u16)(itemId - ITEM_HM01) <= 7) + BlitBitmapToWindow(rboxId, gBagMenuHMIcon_Gfx, 8, a - 1, 16, 16); + if (gUnknown_0203CE58.pocket == 3) + { + ConvertIntToDecimalStringN(gStringVar1, itemQuantity, 1, 3); + StringExpandPlaceholders(gStringVar4, gText_xVar1); + offset = GetStringRightAlignXOffset(7, gStringVar4, 0x77); + bag_menu_print(rboxId, 7, gStringVar4, offset, a, 0, 0, -1, 0); + } + else if (gUnknown_0203CE58.pocket != 4 && (unique = itemid_is_unique(itemId)) == FALSE) + { + ConvertIntToDecimalStringN(gStringVar1, itemQuantity, 1, 2); + StringExpandPlaceholders(gStringVar4, gText_xVar1); + offset = GetStringRightAlignXOffset(7, gStringVar4, 0x77); + bag_menu_print(rboxId, 7, gStringVar4, offset, a, unique, unique, -1, unique); + } + else + { + if (gSaveBlock1Ptr->registeredItem && gSaveBlock1Ptr->registeredItem == itemId) + BlitBitmapToWindow(rboxId, gUnknown_086140A4, 0x60, a - 1, 0x18, 16); + } + } +} + +void bag_menu_print_description_box_text(int a) +{ + u8* str; + if (a != -2) + { + str = (u8*)ItemId_GetDescription(BagGetItemIdByPocketPosition(gUnknown_0203CE58.pocket + 1, a)); + } + else + { + StringCopy(gStringVar1, gReturnToXStringsTable[gUnknown_0203CE58.location]); + StringExpandPlaceholders(gStringVar4, gText_ReturnToVar1); + str = gStringVar4; + } + FillWindowPixelBuffer(1, 0); + bag_menu_print(1, 1, str, 3, 1, 0, 0, 0, 0); +} + +void bag_menu_print_cursor_(u8 a, u8 b) +{ + bag_menu_print_cursor(ListMenuGetYCoordForPrintingArrowCursor(a), b); +} + +void bag_menu_print_cursor(u8 a, u8 b) +{ + if (b == 0xFF) + FillWindowPixelRect(0, 0, 0, a, GetMenuCursorDimensionByFont(1, 0), GetMenuCursorDimensionByFont(1, 1)); + else + bag_menu_print(0, 1, gText_SelectorArrow2, 0, a, 0, 0, 0, b); + +} + +void bag_menu_add_pocket_scroll_arrow_indicators_maybe(void) +{ + if (gUnknown_0203CE54->unk81E == 0xFF) + gUnknown_0203CE54->unk81E = AddScrollIndicatorArrowPairParametrized(2, 0xAC, 12, 0x94, gUnknown_0203CE54->unk829[gUnknown_0203CE58.pocket] - gUnknown_0203CE54->unk82E[gUnknown_0203CE58.pocket], 0x6E, 0x6E, &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket]); +} + +void sub_81AB824(void) +{ + if (gUnknown_0203CE54->unk81E != 0xFF) + { + RemoveScrollIndicatorArrowPair(gUnknown_0203CE54->unk81E); + gUnknown_0203CE54->unk81E = 0xFF; + } + sub_81AB89C(); +} + +void bag_menu_add_list_scroll_arrow_indicators_maybe(void) +{ + if (gUnknown_0203CE54->unk81B != 1 && gUnknown_0203CE54->unk81F == 0xFF) + gUnknown_0203CE54->unk81F = AddScrollIndicatorArrowPair(&gUnknown_08614094, gUnknown_0203CE58.unk6); +} + +void sub_81AB89C(void) +{ + if (gUnknown_0203CE54->unk81F != 0xFF) + { + RemoveScrollIndicatorArrowPair(gUnknown_0203CE54->unk81F); + gUnknown_0203CE54->unk81F = 0xFF; + } +} + +void free_bag_item_list_buffers(void) +{ + Free(gUnknown_0203CE78); + Free(gUnknown_0203CE74); + FreeAllWindowBuffers(); + Free(gUnknown_0203CE54); +} + +void unknown_ItemMenu_Confirm(u8 taskId) +{ + BeginNormalPaletteFade(-1, 0, 0, 16, 0); + gTasks[taskId].func = task_close_bag_menu_2; +} + +void task_close_bag_menu_2(u8 taskId) +{ + s16* data = gTasks[taskId].data; + if (!gPaletteFade.active) + { + sub_81AE6C8(data[0], &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket], &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]); + if (gUnknown_0203CE54->unk0 != 0) + SetMainCallback2(gUnknown_0203CE54->unk0); + else + SetMainCallback2(gUnknown_0203CE58.bagCallback); + sub_81AB824(); + ResetSpriteData(); + FreeAllSpritePalettes(); + free_bag_item_list_buffers(); + DestroyTask(taskId); + } +} + +void sub_81AB9A8(u8 pocketId) +{ + u16 i; + struct BagPocket *pocket = &gBagPockets[pocketId]; + switch (pocketId) + { + case 2: + case 3: + sub_80D6FB4(pocket); + break; + default: + sub_80D6F64(pocket); + break; + } + gUnknown_0203CE54->unk829[pocketId] = 0; + for (i = 0; i < pocket->capacity && pocket->itemSlots[i].itemId; i++) + gUnknown_0203CE54->unk829[pocketId]++; + if (!gUnknown_0203CE54->unk81B_2) + gUnknown_0203CE54->unk829[pocketId]++; + if (gUnknown_0203CE54->unk829[pocketId] > 8) + gUnknown_0203CE54->unk82E[pocketId] = 8; + else + gUnknown_0203CE54->unk82E[pocketId] = gUnknown_0203CE54->unk829[pocketId]; +} + +void sub_81ABA6C(void) +{ + u8 i; + for (i = 0; i < 5; i++) + sub_81AB9A8(i); +} + +void sub_81ABA88(u8 a) +{ + sub_812225C(&gUnknown_0203CE58.scrollPosition[a], &gUnknown_0203CE58.cursorPosition[a], gUnknown_0203CE54->unk82E[a], gUnknown_0203CE54->unk829[a]); +} + +void sub_81ABAC4(void) +{ + u8 i; + for (i = 0; i < 5; i++) + sub_81ABA88(i); +} + +void sub_81ABAE0(void) +{ + u8 i; + for (i = 0; i < 5; i++) + sub_8122298(&gUnknown_0203CE58.scrollPosition[i], &gUnknown_0203CE58.cursorPosition[i], gUnknown_0203CE54->unk82E[i], gUnknown_0203CE54->unk829[i], 8); +} + +u8 sub_81ABB2C(u8 a) +{ + return gUnknown_0203CE58.scrollPosition[a] + gUnknown_0203CE58.cursorPosition[a]; +} + +void DisplayItemMessage(u8 taskId, u8 fontId, const u8 *str, void ( *callback)(u8 taskId)) +{ + s16* data = gTasks[taskId].data; + + data[10] = AddItemMessageWindow(4); + FillWindowPixelBuffer(data[10], 17); + DisplayMessageAndContinueTask(taskId, data[10], 10, 13, fontId, GetPlayerTextSpeed(), str, callback); + schedule_bg_copy_tilemap_to_vram(1); +} + +void bag_menu_inits_lists_menu(u8 taskId) +{ + s16* data = gTasks[taskId].data; + u16* scrollPos = &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket]; + u16* cursorPos = &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]; + bag_menu_RemoveBagItem_message_window(4); + sub_81AE6C8(data[0], scrollPos, cursorPos); + sub_81AB9A8(gUnknown_0203CE58.pocket); + sub_81ABA88(gUnknown_0203CE58.pocket); + load_bag_item_list_buffers(gUnknown_0203CE58.pocket); + data[0] = ListMenuInit(&gMultiuseListMenuTemplate, *scrollPos, *cursorPos); + schedule_bg_copy_tilemap_to_vram(0); + set_callback3_to_bag(taskId); +} + +void sub_81ABC3C(u8 a) +{ + sub_81ABC54(bag_menu_add_window(a), 1); +} + +void sub_81ABC54(u8 a, s16 b) +{ + u8 r3 = (gUnknown_0203CE58.pocket == 3) ? 3 : 2; + ConvertIntToDecimalStringN(gStringVar1, b, 2, r3); + StringExpandPlaceholders(gStringVar4, gText_xVar1); + PrintTextOnWindow(a, 1, gStringVar4, GetStringCenterAlignXOffset(1, gStringVar4, 0x28), 2, 0, 0); +} + +void sub_81ABCC0(int a, int b, int c) +{ + u8 r3 = (gUnknown_0203CE58.pocket == 3) ? 3 : 2; + ConvertIntToDecimalStringN(gStringVar1, b, 2, r3); + StringExpandPlaceholders(gStringVar4, gText_xVar1); + PrintTextOnWindow(a, 1, gStringVar4, 0, 1, -1, 0); + PrintMoneyAmount(a, 0x26, 1, c, 0); +} + +void Task_BagMenu(u8 taskId) +{ + s16* data = gTasks[taskId].data; + u16* scrollPos = &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket]; + u16* cursorPos = &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]; + u16 select; + if (sub_81221EC() != TRUE && !gPaletteFade.active) + { + switch (GetSwitchBagPocketDirection()) + { + case 1: + SwitchBagPocket(taskId, -1, 0); + return; + case 2: + SwitchBagPocket(taskId, 1, 0); + return; + } + if ((select = (gMain.newKeys & SELECT_BUTTON))) + { + if (sub_81AC2C0() == 1) + { + sub_81AE860(data[0], scrollPos, cursorPos); + if ((*scrollPos + *cursorPos) != gUnknown_0203CE54->unk829[gUnknown_0203CE58.pocket] - 1) + { + PlaySE(SE_SELECT); + bag_menu_swap_items(taskId); + } + } + return; + } + else + { + int r4 = ListMenuHandleInputGetItemId(data[0]); + sub_81AE860(data[0], scrollPos, cursorPos); + switch (r4) + { + case -1: + break; + case -2: + if (gUnknown_0203CE58.location == 5) + { + PlaySE(SE_HAZURE); + break; + } + PlaySE(SE_SELECT); + gSpecialVar_ItemId = select; + gTasks[taskId].func = unknown_ItemMenu_Confirm; + break; + default: + PlaySE(SE_SELECT); + sub_81AB824(); + bag_menu_print_cursor_(data[0], 2); + data[1] = r4; + data[2] = BagGetQuantityByPocketPosition(gUnknown_0203CE58.pocket + 1, r4); + gSpecialVar_ItemId = BagGetItemIdByPocketPosition(gUnknown_0203CE58.pocket + 1, r4); + gUnknown_08614054[gUnknown_0203CE58.location](taskId); + break; + } + } + } +} + +void set_callback3_to_bag(u8 taskId) +{ + bag_menu_add_pocket_scroll_arrow_indicators_maybe(); + bag_menu_add_list_scroll_arrow_indicators_maybe(); + ClearWindowTilemap(3); + ClearWindowTilemap(4); + PutWindowTilemap(1); + schedule_bg_copy_tilemap_to_vram(0); + gTasks[taskId].func = Task_BagMenu; +} + +u8 GetSwitchBagPocketDirection(void) +{ + u8 LRKeys; + if (gUnknown_0203CE54->unk81B != 0) + return 0; + LRKeys = GetLRKeysState(); + if ((gMain.newKeys & DPAD_LEFT) || LRKeys == 1) + { + PlaySE(SE_SELECT); + return 1; + } + if ((gMain.newKeys & DPAD_RIGHT) || LRKeys == 2) + { + PlaySE(SE_SELECT); + return 2; + } + return 0; +} + + +void ChangeBagPocketId(u8 *bagPocketId, s8 deltaBagPocketId) +{ + if (deltaBagPocketId == 1 && *bagPocketId == 4) + *bagPocketId = 0; + else if (deltaBagPocketId == -1 && *bagPocketId == 0) + *bagPocketId = 4; + else + *bagPocketId += deltaBagPocketId; +} + +#ifdef NONMATCHING +void SwitchBagPocket(u8 taskId, s16 deltaBagPocketId, u16 a3) +{ + s16* data = gTasks[taskId].data; + u8 pocketId; + + + data[13] = 0; + data[12] = 0; + data[11] = deltaBagPocketId; + if (a3 == 0) + { + ClearWindowTilemap(0); + ClearWindowTilemap(1); + sub_81AE6C8(data[0], &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket], &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]); + schedule_bg_copy_tilemap_to_vram(0); + gSprites[gUnknown_0203CE54->unk806[gUnknown_0203CE54->unk81B_1 ^ 1]].invisible = 1; + sub_81AB824(); + } + pocketId = gUnknown_0203CE58.pocket; + ChangeBagPocketId(&pocketId, deltaBagPocketId); + if (deltaBagPocketId == 1) + { + bag_menu_print_pocket_names(gPocketNamesStringsTable[gUnknown_0203CE58.pocket], gPocketNamesStringsTable[pocketId]); + bag_menu_copy_pocket_name_to_window(0); + } + else + { + bag_menu_print_pocket_names(gPocketNamesStringsTable[pocketId], gPocketNamesStringsTable[gUnknown_0203CE58.pocket]); + bag_menu_copy_pocket_name_to_window(8); + } + bag_menu_draw_pocket_indicator_square(gUnknown_0203CE58.pocket, 0); + bag_menu_draw_pocket_indicator_square(pocketId, 1); + FillBgTilemapBufferRect_Palette0(2, 11, 14, 2, 15, 16); + schedule_bg_copy_tilemap_to_vram(2); + SetBagVisualPocketId(pocketId, 1); + RemoveBagObject(1); + AddSwitchPocketRotatingBallObject(deltaBagPocketId); + SetTaskFuncWithFollowupFunc(taskId, sub_81AC10C, gTasks[taskId].func); +} +#else +__attribute__((naked)) +void SwitchBagPocket(u8 taskId, s16 deltaBagPocketId, u16 a3) +{ + asm(".syntax unified\n\ + push {r4-r6,lr}\n\ + sub sp, 0xC\n\ + lsls r0, 24\n\ + lsrs r6, r0, 24\n\ + lsls r1, 16\n\ + lsrs r5, r1, 16\n\ + lsls r2, 16\n\ + lsls r0, r6, 2\n\ + adds r0, r6\n\ + lsls r0, 3\n\ + ldr r1, =gTasks + 0x8\n\ + adds r4, r0, r1\n\ + movs r0, 0\n\ + strh r0, [r4, 0x1A]\n\ + strh r0, [r4, 0x18]\n\ + strh r5, [r4, 0x16]\n\ + cmp r2, 0\n\ + bne _081AC026\n\ + movs r0, 0\n\ + bl ClearWindowTilemap\n\ + movs r0, 0x1\n\ + bl ClearWindowTilemap\n\ + ldrb r0, [r4]\n\ + ldr r3, =gUnknown_0203CE58\n\ + ldrb r2, [r3, 0x5]\n\ + lsls r2, 1\n\ + adds r1, r3, 0\n\ + adds r1, 0x12\n\ + adds r1, r2, r1\n\ + adds r3, 0x8\n\ + adds r2, r3\n\ + bl sub_81AE6C8\n\ + movs r0, 0\n\ + bl schedule_bg_copy_tilemap_to_vram\n\ + ldr r3, =gSprites\n\ + ldr r0, =gUnknown_0203CE54\n\ + ldr r2, [r0]\n\ + ldr r1, =0x0000081b\n\ + adds r0, r2, r1\n\ + ldrb r1, [r0]\n\ + lsls r1, 26\n\ + lsrs r1, 30\n\ + movs r0, 0x1\n\ + eors r0, r1\n\ + adds r2, r0\n\ + ldr r0, =0x00000806\n\ + adds r2, r0\n\ + ldrb r1, [r2]\n\ + lsls r0, r1, 4\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r3\n\ + adds r0, 0x3E\n\ + ldrb r1, [r0]\n\ + movs r2, 0x4\n\ + orrs r1, r2\n\ + strb r1, [r0]\n\ + bl sub_81AB824\n\ +_081AC026:\n\ + ldr r4, =gUnknown_0203CE58\n\ + ldrb r1, [r4, 0x5]\n\ + add r0, sp, 0x8\n\ + strb r1, [r0]\n\ + lsls r1, r5, 24\n\ + asrs r1, 24\n\ + bl ChangeBagPocketId\n\ + lsls r0, r5, 16\n\ + asrs r1, r0, 16\n\ + adds r5, r0, 0\n\ + cmp r1, 0x1\n\ + bne _081AC07C\n\ + ldr r2, =gPocketNamesStringsTable\n\ + ldrb r0, [r4, 0x5]\n\ + lsls r0, 2\n\ + adds r0, r2\n\ + ldr r0, [r0]\n\ + add r1, sp, 0x8\n\ + ldrb r1, [r1]\n\ + lsls r1, 2\n\ + adds r1, r2\n\ + ldr r1, [r1]\n\ + bl bag_menu_print_pocket_names\n\ + movs r0, 0\n\ + bl bag_menu_copy_pocket_name_to_window\n\ + b _081AC09A\n\ + .pool\n\ +_081AC07C:\n\ + ldr r2, =gPocketNamesStringsTable\n\ + add r0, sp, 0x8\n\ + ldrb r0, [r0]\n\ + lsls r0, 2\n\ + adds r0, r2\n\ + ldr r0, [r0]\n\ + ldrb r1, [r4, 0x5]\n\ + lsls r1, 2\n\ + adds r1, r2\n\ + ldr r1, [r1]\n\ + bl bag_menu_print_pocket_names\n\ + movs r0, 0x8\n\ + bl bag_menu_copy_pocket_name_to_window\n\ +_081AC09A:\n\ + ldr r0, =gUnknown_0203CE58\n\ + ldrb r0, [r0, 0x5]\n\ + movs r1, 0\n\ + bl bag_menu_draw_pocket_indicator_square\n\ + add r0, sp, 0x8\n\ + ldrb r0, [r0]\n\ + movs r1, 0x1\n\ + bl bag_menu_draw_pocket_indicator_square\n\ + movs r0, 0xF\n\ + str r0, [sp]\n\ + movs r0, 0x10\n\ + str r0, [sp, 0x4]\n\ + movs r0, 0x2\n\ + movs r1, 0xB\n\ + movs r2, 0xE\n\ + movs r3, 0x2\n\ + bl FillBgTilemapBufferRect_Palette0\n\ + movs r0, 0x2\n\ + bl schedule_bg_copy_tilemap_to_vram\n\ + add r0, sp, 0x8\n\ + ldrb r0, [r0]\n\ + movs r1, 0x1\n\ + bl SetBagVisualPocketId\n\ + movs r0, 0x1\n\ + bl RemoveBagObject\n\ + asrs r0, r5, 16\n\ + bl AddSwitchPocketRotatingBallObject\n\ + ldr r1, =sub_81AC10C\n\ + ldr r2, =gTasks\n\ + lsls r0, r6, 2\n\ + adds r0, r6\n\ + lsls r0, 3\n\ + adds r0, r2\n\ + ldr r2, [r0]\n\ + adds r0, r6, 0\n\ + bl SetTaskFuncWithFollowupFunc\n\ + add sp, 0xC\n\ + pop {r4-r6}\n\ + pop {r0}\n\ + bx r0\n\ + .pool\n\ + .syntax divided\n"); +} +#endif + +void sub_81AC10C(u8 taskId) +{ + s16* data = gTasks[taskId].data; + + if (!sub_81221AC() && !IsWallysBag()) + { + switch (GetSwitchBagPocketDirection()) + { + case 1: + ChangeBagPocketId(&gUnknown_0203CE58.pocket, data[11]); + SwitchTaskToFollowupFunc(taskId); + SwitchBagPocket(taskId, -1, 1); + return; + case 2: + ChangeBagPocketId(&gUnknown_0203CE58.pocket, data[11]); + SwitchTaskToFollowupFunc(taskId); + SwitchBagPocket(taskId, 1, 1); + return; + } + } + switch (data[13]) + { + case 0: + sub_81AC23C(data[12]); + if (!(++data[12] & 1)) + { + if (data[11] == 1) + bag_menu_copy_pocket_name_to_window((u8)(data[12] >> 1)); + else + bag_menu_copy_pocket_name_to_window((u8)(8 - (data[12] >> 1))); + } + if (data[12] == 16) + data[13]++; + break; + case 1: + ChangeBagPocketId(&gUnknown_0203CE58.pocket, data[11]); + load_bag_item_list_buffers(gUnknown_0203CE58.pocket); + data[0] = ListMenuInit(&gMultiuseListMenuTemplate, gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket], gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]); + PutWindowTilemap(1); + PutWindowTilemap(2); + schedule_bg_copy_tilemap_to_vram(0); + bag_menu_add_pocket_scroll_arrow_indicators_maybe(); + bag_menu_add_list_scroll_arrow_indicators_maybe(); + SwitchTaskToFollowupFunc(taskId); + } +} + +void sub_81AC23C(u8 a) +{ + FillBgTilemapBufferRect_Palette0(2, 17, 14, a + 2, 15, 1); + schedule_bg_copy_tilemap_to_vram(2); +} + +void bag_menu_draw_pocket_indicator_square(u8 x, u8 is_current_bag) +{ + if (is_current_bag == 0) + FillBgTilemapBufferRect_Palette0(2, 0x1017, x + 5, 3, 1, 1); + else + FillBgTilemapBufferRect_Palette0(2, 0x102B, x + 5, 3, 1, 1); + schedule_bg_copy_tilemap_to_vram(2); +} + +bool8 sub_81AC2C0(void) +{ + if (gUnknown_0203CE58.location <= 1) + { + u8 temp = gUnknown_0203CE58.pocket - 2; + if (temp > 1) + return TRUE; + } + return FALSE; +} + +void bag_menu_swap_items(u8 taskId) +{ + s16* data = gTasks[taskId].data; + + sub_81AF15C(data[0], 16, 1); + data[1] = gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket] + gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]; + gUnknown_0203CE54->unk81A = data[1]; + CopyItemName(BagGetItemIdByPocketPosition(gUnknown_0203CE58.pocket + 1, data[1]), gStringVar1); + StringExpandPlaceholders(gStringVar4, gText_MoveVar1Where); + FillWindowPixelBuffer(1, 0); + bag_menu_print(1, 1, gStringVar4, 3, 1, 0, 0, 0, 0); + sub_80D4FEC(data[1]); + sub_81AB89C(); + bag_menu_print_cursor_(data[0], 2); + gTasks[taskId].func = sub_81AC3C0; +} + +void sub_81AC3C0(u8 taskId) +{ + s16* data = gTasks[taskId].data; + int r7; + + if (sub_81221EC() != TRUE) + { + if (gMain.newKeys & SELECT_BUTTON) + { + PlaySE(SE_SELECT); + sub_81AE860(data[0], &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket], &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]); + sub_81AC498(taskId); + } + else + { + r7 = ListMenuHandleInputGetItemId(data[0]); + sub_81AE860(data[0], &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket], &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]); + sub_80D4FC8(0); + sub_80D4FEC(gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]); + switch (r7) + { + case -1: + break; + case -2: + PlaySE(SE_SELECT); + if (gMain.newKeys & A_BUTTON) + sub_81AC498(taskId); + else + sub_81AC590(taskId); + break; + default: + PlaySE(SE_SELECT); + sub_81AC498(taskId); + } + } + } +} + +void sub_81AC498(u8 taskId) +{ + s16* data = gTasks[taskId].data; + u16* scrollPos = &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket]; + u16* cursorPos = &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]; + u16 realPos = (*scrollPos + *cursorPos); + + if (data[1] == realPos || data[1] == (realPos - 1)) + sub_81AC590(taskId); + else + { + sub_80D702C(gBagPockets[gUnknown_0203CE58.pocket].itemSlots, data[1], realPos); + gUnknown_0203CE54->unk81A = -1; + sub_81AE6C8(data[0], scrollPos, cursorPos); + if (data[1] < realPos) + gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]--; + load_bag_item_list_buffers(gUnknown_0203CE58.pocket); + data[0] = ListMenuInit(&gMultiuseListMenuTemplate, *scrollPos, *cursorPos); + sub_80D4FC8(1); + bag_menu_add_list_scroll_arrow_indicators_maybe(); + gTasks[taskId].func = Task_BagMenu; + } +} + +void sub_81AC590(u8 taskId) +{ + s16* data = gTasks[taskId].data; + u16* scrollPos = &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket]; + u16* cursorPos = &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]; + + gUnknown_0203CE54->unk81A = -1; + sub_81AE6C8(data[0], scrollPos, cursorPos); + if (data[1] < (*scrollPos + *cursorPos)) + gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]--; + load_bag_item_list_buffers(gUnknown_0203CE58.pocket); + data[0] = ListMenuInit(&gMultiuseListMenuTemplate, *scrollPos, *cursorPos); + sub_80D4FC8(1); + bag_menu_add_list_scroll_arrow_indicators_maybe(); + gTasks[taskId].func = Task_BagMenu; +} + +void sub_81AC644(u8 unused) +{ + switch (gUnknown_0203CE58.location - 1) + { + case 0: + case 9: + if (ItemId_GetBattleUsage(gSpecialVar_ItemId)) + { + gUnknown_0203CE54->unk820 = gUnknown_08614042; + gUnknown_0203CE54->unk828 = 2; + } + else + { + gUnknown_0203CE54->unk820 = &gUnknown_08614046; + gUnknown_0203CE54->unk828 = 1; + } + break; + case 4: + gUnknown_0203CE54->unk820 = gUnknown_08614047; + gUnknown_0203CE54->unk828 = 4; + break; + case 8: + if (!itemid_is_unique(gSpecialVar_ItemId) && gSpecialVar_ItemId != ITEM_ENIGMA_BERRY) + { + gUnknown_0203CE54->unk820 = gUnknown_0861404B; + gUnknown_0203CE54->unk828 = 2; + } + else + { + gUnknown_0203CE54->unk820 = &gUnknown_08614046; + gUnknown_0203CE54->unk828 = 1; + } + break; + case 6: + if (!itemid_is_unique(gSpecialVar_ItemId) && gSpecialVar_ItemId != ITEM_ENIGMA_BERRY) + { + gUnknown_0203CE54->unk820 = gUnknown_0861404D; + gUnknown_0203CE54->unk828 = 2; + } + else + { + gUnknown_0203CE54->unk820 = &gUnknown_08614046; + gUnknown_0203CE54->unk828 = 1; + } + break; + case 7: + if (!itemid_is_unique(gSpecialVar_ItemId) && gSpecialVar_ItemId != ITEM_ENIGMA_BERRY) + { + gUnknown_0203CE54->unk820 = gUnknown_0861404F; + gUnknown_0203CE54->unk828 = 2; + } + else + { + gUnknown_0203CE54->unk820 = &gUnknown_08614046; + gUnknown_0203CE54->unk828 = 1; + } + break; + case 1: + case 2: + case 3: + case 5: + default: + if (sub_81221AC() == TRUE || InUnionRoom() == TRUE) + { + if (gUnknown_0203CE58.pocket == 4 || !sub_8122148(gSpecialVar_ItemId)) + { + gUnknown_0203CE54->unk820 = &gUnknown_08614046; + gUnknown_0203CE54->unk828 = 1; + } + else + { + gUnknown_0203CE54->unk820 = gUnknown_08614044; + gUnknown_0203CE54->unk828 = 2; + } + } + else + { + switch (gUnknown_0203CE58.pocket) + { + case 0: + gUnknown_0203CE54->unk820 = &gUnknown_0203CE54->unk824; + gUnknown_0203CE54->unk828 = 4; + memcpy(&gUnknown_0203CE54->unk824, &gUnknown_0861402C, 4); + if (ItemIsMail(gSpecialVar_ItemId) == TRUE) + gUnknown_0203CE54->unk824 = 6; + break; + case 4: + gUnknown_0203CE54->unk820 = &gUnknown_0203CE54->unk824; + gUnknown_0203CE54->unk828 = 4; + memcpy(&gUnknown_0203CE54->unk824, &gUnknown_08614030, 4); + if (gSaveBlock1Ptr->registeredItem == gSpecialVar_ItemId) + gUnknown_0203CE54->unk825 = 8; + if (gSpecialVar_ItemId == ITEM_MACH_BIKE || gSpecialVar_ItemId == ITEM_ACRO_BIKE) + { + if (TestPlayerAvatarFlags(6)) + gUnknown_0203CE54->unk824 = 7; + } + break; + case 1: + gUnknown_0203CE54->unk820 = gUnknown_08614034; + gUnknown_0203CE54->unk828 = 4; + break; + case 2: + gUnknown_0203CE54->unk820 = gUnknown_08614038; + gUnknown_0203CE54->unk828 = 4; + break; + case 3: + gUnknown_0203CE54->unk820 = gUnknown_0861403C; + gUnknown_0203CE54->unk828 = 6; + break; + } + } + } + if (gUnknown_0203CE58.pocket == 2) + { + ClearWindowTilemap(1); + PrintTMHMMoveData(gSpecialVar_ItemId); + PutWindowTilemap(3); + PutWindowTilemap(4); + schedule_bg_copy_tilemap_to_vram(0); + } + else + { + CopyItemName(gSpecialVar_ItemId, gStringVar1); + StringExpandPlaceholders(gStringVar4, gText_Var1IsSelected); + FillWindowPixelBuffer(1, 0); + bag_menu_print(1, 1, gStringVar4, 3, 1, 0, 0, 0, 0); + } + if (gUnknown_0203CE54->unk828 == 1) + sub_81ACAF8(bag_menu_add_window(0)); + else if (gUnknown_0203CE54->unk828 == 2) + sub_81ACAF8(bag_menu_add_window(1)); + else if (gUnknown_0203CE54->unk828 == 4) + sub_81ACB54(bag_menu_add_window(2), 2, 2); + else + sub_81ACB54(bag_menu_add_window(3), 2, 3); +} + +void sub_81ACAF8(u8 a) +{ + AddItemMenuActionTextPrinters(a, 7, 8, 1, 0, 16, gUnknown_0203CE54->unk828, gUnknown_08613FB4, gUnknown_0203CE54->unk820); + InitMenuInUpperLeftCornerPlaySoundWhenAPressed(a, gUnknown_0203CE54->unk828, 0); +} + +void sub_81ACB54(u8 a, u8 b, u8 c) +{ + sub_8198DBC(a, 7, 8, 1, 0x38, b, c, gUnknown_08613FB4, gUnknown_0203CE54->unk820); + sub_8199944(a, 0x38, b, c, 0); +} + +void unknown_item_menu_type(u8 taskId) +{ + sub_81AC644(taskId); + if (gUnknown_0203CE54->unk828 <= 2) + gTasks[taskId].func = Task_HandleInBattleItemMenuInput; + else + gTasks[taskId].func = Task_HandleOutOfBattleItemMenuInput; +} + +void Task_HandleInBattleItemMenuInput(u8 taskId) +{ + if (sub_81221EC() != TRUE) + { + s8 r4 = ProcessMenuInputNoWrapAround(); + switch (r4) + { + case -2: + break; + case -1: + PlaySE(SE_SELECT); + gUnknown_08613FB4[4].func.void_u8(taskId); + break; + default: + PlaySE(SE_SELECT); + gUnknown_08613FB4[gUnknown_0203CE54->unk820[r4]].func.void_u8(taskId); + break; + } + } +} + +void Task_HandleOutOfBattleItemMenuInput(u8 taskId) +{ + if (sub_81221EC() != TRUE) + { + s8 cursorPos = GetMenuCursorPos(); + if (gMain.newKeys & DPAD_UP) + { + if (cursorPos > 0 && sub_81ACDFC(cursorPos - 2)) + { + PlaySE(SE_SELECT); + sub_8199134(0, -1); + } + } + else if (gMain.newKeys & DPAD_DOWN) + { + if (cursorPos < (gUnknown_0203CE54->unk828 - 2) && sub_81ACDFC(cursorPos + 2)) + { + PlaySE(SE_SELECT); + sub_8199134(0, 1); + } + } + else if ((gMain.newKeys & DPAD_LEFT) || GetLRKeysState() == 1) + { + if ((cursorPos & 1) && sub_81ACDFC(cursorPos - 1)) + { + PlaySE(SE_SELECT); + sub_8199134(-1, 0); + } + } + else if ((gMain.newKeys & DPAD_RIGHT) || GetLRKeysState() == 2) + { + if (!(cursorPos & 1) && sub_81ACDFC(cursorPos + 1)) + { + PlaySE(SE_SELECT); + sub_8199134(1, 0); + } + } + else if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + gUnknown_08613FB4[gUnknown_0203CE54->unk820[cursorPos]].func.void_u8(taskId); + } + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + gUnknown_08613FB4[4].func.void_u8(taskId); + } + } +} + +bool8 sub_81ACDFC(s8 a) +{ + if (a < 0) + return FALSE; + if (a > gUnknown_0203CE54->unk828) + return FALSE; + if (gUnknown_0203CE54->unk820[a] == 14) + return FALSE; + return TRUE; +} + +void bag_menu_remove_some_window(void) +{ + if (gUnknown_0203CE54->unk828 == 1) + bag_menu_remove_window(0); + else if (gUnknown_0203CE54->unk828 == 2) + { + bag_menu_remove_window(1); + } + else if (gUnknown_0203CE54->unk828 == 4) + { + bag_menu_remove_window(2); + } + else + bag_menu_remove_window(3); +} + +void ItemMenu_UseOutOfBattle(u8 taskId) +{ + if (ItemId_GetFieldFunc(gSpecialVar_ItemId)) + { + bag_menu_remove_some_window(); + if (CalculatePlayerPartyCount() == 0 && ItemId_GetType(gSpecialVar_ItemId) == 1) + bag_menu_print_there_is_no_pokemon(taskId); + else + { + FillWindowPixelBuffer(1, 0); + schedule_bg_copy_tilemap_to_vram(0); + if (gUnknown_0203CE58.pocket != 3) + ItemId_GetFieldFunc(gSpecialVar_ItemId)(taskId); + else + sub_80FDD10(taskId); + } + } +} + +void ItemMenu_Toss(u8 taskId) +{ + s16* data = gTasks[taskId].data; + + bag_menu_remove_some_window(); + data[8] = 1; + if (data[2] == 1) + { + BagMenuConfirmToss(taskId); + } + else + { + CopyItemName(gSpecialVar_ItemId, gStringVar1); + StringExpandPlaceholders(gStringVar4, gText_TossHowManyVar1s); + FillWindowPixelBuffer(1, 0); + bag_menu_print(1, 1, gStringVar4, 3, 1, 0, 0, 0, 0); + sub_81ABC3C(7); + gTasks[taskId].func = Task_ChooseHowManyToToss; + } +} + +void BagMenuConfirmToss(u8 taskId) +{ + s16* data = gTasks[taskId].data; + + CopyItemName(gSpecialVar_ItemId, gStringVar1); + ConvertIntToDecimalStringN(gStringVar2, data[8], 0, 3); + StringExpandPlaceholders(gStringVar4, gText_ConfirmTossItems); + FillWindowPixelBuffer(1, 0); + bag_menu_print(1, 1, gStringVar4, 3, 1, 0, 0, 0, 0); + bag_menu_yes_no(taskId, 5, &gUnknown_08614084); +} + +void BagMenuCancelToss(u8 taskId) +{ + s16* data = gTasks[taskId].data; + + bag_menu_print_description_box_text(data[1]); + bag_menu_print_cursor_(data[0], 0); + set_callback3_to_bag(taskId); +} + +void Task_ChooseHowManyToToss(u8 taskId) +{ + s16* data = gTasks[taskId].data; + + if (AdjustQuantityAccordingToDPadInput(&data[8], data[2]) == TRUE) + { + sub_81ABC54(gUnknown_0203CE54->unk817, data[8]); + } + else if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + bag_menu_remove_window(7); + BagMenuConfirmToss(taskId); + } + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + bag_menu_remove_window(7); + BagMenuCancelToss(taskId); + } +} + +void BagMenuActuallyToss(u8 taskId) +{ + s16* data = gTasks[taskId].data; + + CopyItemName(gSpecialVar_ItemId, gStringVar1); + ConvertIntToDecimalStringN(gStringVar2, data[8], 0, 3); + StringExpandPlaceholders(gStringVar4, gText_ThrewAwayVar2Var1s); + FillWindowPixelBuffer(1, 0); + bag_menu_print(1, 1, gStringVar4, 3, 1, 0, 0, 0, 0); + gTasks[taskId].func = Task_ActuallyToss; +} + +void Task_ActuallyToss(u8 taskId) +{ + s16* data = gTasks[taskId].data; + u16* scrollPos = &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket]; + u16* cursorPos = &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]; + + if (gMain.newKeys & (A_BUTTON | B_BUTTON)) + { + PlaySE(SE_SELECT); + RemoveBagItem(gSpecialVar_ItemId, data[8]); + sub_81AE6C8(data[0], scrollPos, cursorPos); + sub_81AB9A8(gUnknown_0203CE58.pocket); + sub_81ABA88(gUnknown_0203CE58.pocket); + load_bag_item_list_buffers(gUnknown_0203CE58.pocket); + data[0] = ListMenuInit(&gMultiuseListMenuTemplate, *scrollPos, *cursorPos); + schedule_bg_copy_tilemap_to_vram(0); + set_callback3_to_bag(taskId); + } +} + +void ItemMenu_Register(u8 taskId) +{ + s16* data = gTasks[taskId].data; + u16* scrollPos = &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket]; + u16* cursorPos = &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]; + + if (gSaveBlock1Ptr->registeredItem == gSpecialVar_ItemId) + gSaveBlock1Ptr->registeredItem = 0; + else + gSaveBlock1Ptr->registeredItem = gSpecialVar_ItemId; + sub_81AE6C8(data[0], scrollPos, cursorPos); + load_bag_item_list_buffers(gUnknown_0203CE58.pocket); + data[0] = ListMenuInit(&gMultiuseListMenuTemplate, *scrollPos, *cursorPos); + schedule_bg_copy_tilemap_to_vram(0); + ItemMenu_Cancel(taskId); +} + +void ItemMenu_Give(u8 taskId) +{ + bag_menu_remove_some_window(); + if (!itemid_80BF6D8_mail_related(gSpecialVar_ItemId)) + { + DisplayItemMessage(taskId, 1, gText_CantWriteMail, sub_81AD350); + } + else if (!itemid_is_unique(gSpecialVar_ItemId)) + { + if (CalculatePlayerPartyCount() == 0) + bag_menu_print_there_is_no_pokemon(taskId); + else + { + gUnknown_0203CE54->unk0 = sub_81B7F60; + unknown_ItemMenu_Confirm(taskId); + } + } + else + { + bag_menu_print_cant_be_held_msg(taskId); + } +} + +void bag_menu_print_there_is_no_pokemon(u8 taskId) +{ + DisplayItemMessage(taskId, 1, gText_NoPokemon, sub_81AD350); +} + +void bag_menu_print_cant_be_held_msg(u8 taskId) +{ + CopyItemName(gSpecialVar_ItemId, gStringVar1); + StringExpandPlaceholders(gStringVar4, gText_Var1CantBeHeld); + DisplayItemMessage(taskId, 1, gStringVar4, sub_81AD350); +} + +void sub_81AD350(u8 taskId) +{ + if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + bag_menu_inits_lists_menu(taskId); + } +} + +void ItemMenu_CheckTag(u8 taskId) +{ + gUnknown_0203CE54->unk0 = DoBerryTagScreen; + unknown_ItemMenu_Confirm(taskId); +} + +void ItemMenu_Cancel(u8 taskId) +{ + s16* data = gTasks[taskId].data; + + bag_menu_remove_some_window(); + bag_menu_print_description_box_text(data[1]); + schedule_bg_copy_tilemap_to_vram(0); + schedule_bg_copy_tilemap_to_vram(1); + bag_menu_print_cursor_(data[0], 0); + set_callback3_to_bag(taskId); +} + +void ItemMenu_UseInBattle(u8 taskId) +{ + if (ItemId_GetBattleFunc(gSpecialVar_ItemId)) + { + bag_menu_remove_some_window(); + ItemId_GetBattleFunc(gSpecialVar_ItemId)(taskId); + } +} + +void bag_menu_mail_related(void) +{ + GoToBagMenu(12, 5, NULL); +} + +void item_menu_type_2(u8 taskId) +{ + if (!itemid_80BF6D8_mail_related(gSpecialVar_ItemId)) + { + DisplayItemMessage(taskId, 1, gText_CantWriteMail, sub_81AD350); + } + else if (!sub_8122148(gSpecialVar_ItemId)) + { + CopyItemName(gSpecialVar_ItemId, gStringVar1); + StringExpandPlaceholders(gStringVar4, gText_Var1CantBeHeldHere); + DisplayItemMessage(taskId, 1, gStringVar4, sub_81AD350); + } + else if (gUnknown_0203CE58.pocket != 4 && !itemid_is_unique(gSpecialVar_ItemId)) + { + unknown_ItemMenu_Confirm(taskId); + } + else + { + bag_menu_print_cant_be_held_msg(taskId); + } +} + +void item_menu_type_b(u8 taskId) +{ + if (ItemIsMail(gSpecialVar_ItemId) == TRUE) + DisplayItemMessage(taskId, 1, gText_CantWriteMail, sub_81AD350); + else if (gUnknown_0203CE58.pocket != 4 && !itemid_is_unique(gSpecialVar_ItemId)) + gTasks[taskId].func = unknown_ItemMenu_Confirm; + else + bag_menu_print_cant_be_held_msg(taskId); +} + +bool8 UseRegisteredKeyItemOnField(void) +{ + u8 taskId; + + if (InUnionRoom() == TRUE || InBattlePyramid() || InBattlePike() || InMultiBattleRoom() == TRUE) + return FALSE; + HideMapNamePopUpWindow(); + ChangeBgY_ScreenOff(0, 0, 0); + if (gSaveBlock1Ptr->registeredItem != ITEM_NONE) + { + if (CheckBagHasItem(gSaveBlock1Ptr->registeredItem, 1) == TRUE) + { + ScriptContext2_Enable(); + FreezeMapObjects(); + sub_808B864(); + sub_808BCF4(); + gSpecialVar_ItemId = gSaveBlock1Ptr->registeredItem; + taskId = CreateTask(ItemId_GetFieldFunc(gSaveBlock1Ptr->registeredItem), 8); + gTasks[taskId].data[3] = 1; + return TRUE; + } + else + gSaveBlock1Ptr->registeredItem = ITEM_NONE; + } + ScriptContext1_SetupScript(EventScript_2736B3); + return TRUE; +} + +void display_sell_item_ask_str(u8 taskId) +{ + s16* data = gTasks[taskId].data; + + if (itemid_get_market_price(gSpecialVar_ItemId) == 0) + { + CopyItemName(gSpecialVar_ItemId, gStringVar2); + StringExpandPlaceholders(gStringVar4, gText_CantBuyKeyItem); + DisplayItemMessage(taskId, 1, gStringVar4, bag_menu_inits_lists_menu); + } + else + { + data[8] = 1; + if (data[2] == 1) + { + bag_menu_AddMoney_window(); + sub_81AD680(taskId); + } + else + { + CopyItemName(gSpecialVar_ItemId, gStringVar2); + StringExpandPlaceholders(gStringVar4, gText_HowManyToSell); + DisplayItemMessage(taskId, 1, gStringVar4, sub_81AD730); + } + } +} + +void sub_81AD680(u8 taskId) +{ + s16* data = gTasks[taskId].data; + + ConvertIntToDecimalStringN(gStringVar1, (itemid_get_market_price(gSpecialVar_ItemId) / 2) * data[8], 0, 6); + StringExpandPlaceholders(gStringVar4, gText_ICanPayVar1); + DisplayItemMessage(taskId, 1, gStringVar4, sub_81AD6E4); +} + +void sub_81AD6E4(u8 taskId) +{ + bag_menu_yes_no(taskId, 6, &gUnknown_0861408C); +} + +void sub_81AD6FC(u8 taskId) +{ + s16* data = gTasks[taskId].data; + + bag_menu_remove_money_window(); + bag_menu_RemoveBagItem_message_window(4); + bag_menu_print_cursor_(data[0], 0); + set_callback3_to_bag(taskId); +} + +void sub_81AD730(u8 taskId) +{ + s16* data = gTasks[taskId].data; + u8 windowId = bag_menu_add_window(8); + + sub_81ABCC0(windowId, 1, (itemid_get_market_price(gSpecialVar_ItemId) / 2) * data[8]); + bag_menu_AddMoney_window(); + gTasks[taskId].func = sub_81AD794; +} + +void sub_81AD794(u8 taskId) +{ + s16* data = gTasks[taskId].data; + + if (AdjustQuantityAccordingToDPadInput(&data[8], data[2]) == TRUE) + { + sub_81ABCC0(gUnknown_0203CE54->unk818, data[8], (itemid_get_market_price(gSpecialVar_ItemId) / 2) * data[8]); + } + else if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + bag_menu_remove_window(8); + sub_81AD680(taskId); + } + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + bag_menu_print_cursor_(data[0], 0); + bag_menu_remove_money_window(); + bag_menu_remove_window(8); + bag_menu_RemoveBagItem_message_window(4); + set_callback3_to_bag(taskId); + } +} + +void sub_81AD84C(u8 taskId) +{ + s16* data = gTasks[taskId].data; + + CopyItemName(gSpecialVar_ItemId, gStringVar2); + ConvertIntToDecimalStringN(gStringVar1, (itemid_get_market_price(gSpecialVar_ItemId) / 2) * data[8], 0, 6); + StringExpandPlaceholders(gStringVar4, gText_TurnedOverVar1ForVar2); + DisplayItemMessage(taskId, 1, gStringVar4, sub_81AD8C8); +} + +void sub_81AD8C8(u8 taskId) +{ + s16* data = gTasks[taskId].data; + u16* scrollPos = &gUnknown_0203CE58.scrollPosition[gUnknown_0203CE58.pocket]; + u16* cursorPos = &gUnknown_0203CE58.cursorPosition[gUnknown_0203CE58.pocket]; + + PlaySE(SE_REGI); + RemoveBagItem(gSpecialVar_ItemId, data[8]); + AddMoney(&gSaveBlock1Ptr->money, (itemid_get_market_price(gSpecialVar_ItemId) / 2) * data[8]); + sub_81AE6C8(data[0], scrollPos, cursorPos); + sub_81AB9A8(gUnknown_0203CE58.pocket); + sub_81ABA88(gUnknown_0203CE58.pocket); + load_bag_item_list_buffers(gUnknown_0203CE58.pocket); + data[0] = ListMenuInit(&gMultiuseListMenuTemplate, *scrollPos, *cursorPos); + bag_menu_print_cursor_(data[0], 2); + PrintMoneyAmountInMoneyBox(gUnknown_0203CE54->unk819, GetMoney(&gSaveBlock1Ptr->money), 0); + gTasks[taskId].func = sub_81AD9C0; +} + +void sub_81AD9C0(u8 taskId) +{ + if (gMain.newKeys & (A_BUTTON | B_BUTTON)) + { + PlaySE(SE_SELECT); + bag_menu_remove_money_window(); + bag_menu_inits_lists_menu(taskId); + } +} + +void display_deposit_item_ask_str(u8 taskId) +{ + s16* data = gTasks[taskId].data; + + data[8] = 1; + if (data[2] == 1) + { + sub_81ADB14(taskId); + } + else + { + CopyItemName(gSpecialVar_ItemId, gStringVar1); + StringExpandPlaceholders(gStringVar4, gText_DepositHowManyVar1); + FillWindowPixelBuffer(1, 0); + bag_menu_print(1, 1, gStringVar4, 3, 1, 0, 0, 0, 0); + sub_81ABC3C(7); + gTasks[taskId].func = sub_81ADA7C; + } +} + +void sub_81ADA7C(u8 taskId) +{ + s16* data = gTasks[taskId].data; + + if (AdjustQuantityAccordingToDPadInput(&data[8], data[2]) == TRUE) + { + sub_81ABC54(gUnknown_0203CE54->unk817, data[8]); + } + else if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + bag_menu_remove_window(7); + sub_81ADB14(taskId); + } + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + bag_menu_print_description_box_text(data[1]); + bag_menu_print_cursor_(data[0], 0); + bag_menu_remove_window(7); + set_callback3_to_bag(taskId); + } +} + +void sub_81ADB14(u8 taskId) +{ + s16* data = gTasks[taskId].data; + + FillWindowPixelBuffer(1, 0); + if (itemid_is_unique(gSpecialVar_ItemId)) + { + bag_menu_print(1, 1, gText_CantStoreImportantItems, 3, 1, 0, 0, 0, 0); + gTasks[taskId].func = sub_81ADC0C; + } + else if (AddPCItem(gSpecialVar_ItemId, data[8]) == TRUE) + { + CopyItemName(gSpecialVar_ItemId, gStringVar1); + ConvertIntToDecimalStringN(gStringVar2, data[8], 0, 3); + StringExpandPlaceholders(gStringVar4, gText_DepositedVar2Var1s); + bag_menu_print(1, 1, gStringVar4, 3, 1, 0, 0, 0, 0); + gTasks[taskId].func = Task_ActuallyToss; + } + else + { + bag_menu_print(1, 1, gText_NoRoomForItems, 3, 1, 0, 0, 0, 0); + gTasks[taskId].func = sub_81ADC0C; + } +} + +void sub_81ADC0C(u8 taskId) +{ + s16* data = gTasks[taskId].data; + + if (gMain.newKeys & (A_BUTTON | B_BUTTON)) + { + PlaySE(SE_SELECT); + bag_menu_print_description_box_text(data[1]); + bag_menu_print_cursor_(data[0], 0); + set_callback3_to_bag(taskId); + } +} + +bool8 IsWallysBag(void) +{ + if (gUnknown_0203CE58.location == 10) + return TRUE; + return FALSE; +} + +void PrepareBagForWallyTutorial(void) +{ + u32 i; + + gUnknown_0203CE80 = AllocZeroed(sizeof(struct TempWallyStruct)); + memcpy(gUnknown_0203CE80->bagPocket_Items, gSaveBlock1Ptr->bagPocket_Items, sizeof(gSaveBlock1Ptr->bagPocket_Items)); + memcpy(gUnknown_0203CE80->bagPocket_PokeBalls, gSaveBlock1Ptr->bagPocket_PokeBalls, sizeof(gSaveBlock1Ptr->bagPocket_PokeBalls)); + gUnknown_0203CE80->pocket = gUnknown_0203CE58.pocket; + for (i = 0; i <= 4; i++) + { + gUnknown_0203CE80->cursorPosition[i] = gUnknown_0203CE58.cursorPosition[i]; + gUnknown_0203CE80->scrollPosition[i] = gUnknown_0203CE58.scrollPosition[i]; + } + ClearItemSlots(gSaveBlock1Ptr->bagPocket_Items, 30); + ClearItemSlots(gSaveBlock1Ptr->bagPocket_PokeBalls, 16); + ResetBagScrollPositions(); +} + +void RestoreBagAfterWallyTutorial(void) +{ + u32 i; + + memcpy(gSaveBlock1Ptr->bagPocket_Items, gUnknown_0203CE80->bagPocket_Items, sizeof(gUnknown_0203CE80->bagPocket_Items)); + memcpy(gSaveBlock1Ptr->bagPocket_PokeBalls, gUnknown_0203CE80->bagPocket_PokeBalls, sizeof(gUnknown_0203CE80->bagPocket_PokeBalls)); + gUnknown_0203CE58.pocket = gUnknown_0203CE80->pocket; + for (i = 0; i <= 4; i++) + { + gUnknown_0203CE58.cursorPosition[i] = gUnknown_0203CE80->cursorPosition[i]; + gUnknown_0203CE58.scrollPosition[i] = gUnknown_0203CE80->scrollPosition[i]; + } + Free(gUnknown_0203CE80); +} + +void DoWallyTutorialBagMenu(void) +{ + PrepareBagForWallyTutorial(); + AddBagItem(ITEM_POTION, 1); + AddBagItem(ITEM_POKE_BALL, 1); + GoToBagMenu(10, 0, SetCB2ToReshowScreenAfterMenu2); +} + +void Task_WallyTutorialBagMenu(u8 taskId) +{ + s16* data = gTasks[taskId].data; + + if (!gPaletteFade.active) + { + switch (data[8]) + { + case 0x66: + PlaySE(SE_SELECT); + SwitchBagPocket(taskId, 1, 0); + data[8]++; + break; + case 0xCC: + PlaySE(SE_SELECT); + bag_menu_print_cursor_(data[0], 2); + gSpecialVar_ItemId = ITEM_POKE_BALL; + sub_81AC644(taskId); + data[8]++; + break; + case 0x132: + PlaySE(SE_SELECT); + bag_menu_remove_some_window(); + sub_81AE6C8(data[0], 0, 0); + RestoreBagAfterWallyTutorial(); + unknown_ItemMenu_Confirm(taskId); + break; + default: + data[8]++; + break; + } + } +} + +void unknown_ItemMenu_Show(u8 taskId) +{ + gSpecialVar_0x8005 = gSpecialVar_ItemId; + gSpecialVar_Result = 1; + bag_menu_remove_some_window(); + unknown_ItemMenu_Confirm(taskId); +} + +void bag_menu_leave_maybe_3(void) +{ + gFieldCallback = sub_819FA50; + SetMainCallback2(c2_exit_to_overworld_2_switch); +} + +void unknown_ItemMenu_Give2(u8 taskId) +{ + RemoveBagItem(gSpecialVar_ItemId, 1); + gSpecialVar_Result = 1; + bag_menu_remove_some_window(); + unknown_ItemMenu_Confirm(taskId); +} + +void bag_menu_leave_maybe_2(void) +{ + gFieldCallback = sub_818DEF4; + SetMainCallback2(c2_exit_to_overworld_2_switch); +} + +void unknown_ItemMenu_Confirm2(u8 taskId) +{ + gSpecialVar_Result = 1; + bag_menu_remove_some_window(); + unknown_ItemMenu_Confirm(taskId); +} + +void bag_menu_leave_maybe(void) +{ + gFieldCallback = sub_818E564; + SetMainCallback2(c2_exit_to_overworld_2_switch); +} + +void bag_menu_print_pocket_names(u8 *pocketName1, u8 *pocketName2) +{ + struct WindowTemplate window = {0, 0, 0, 0, 0, 0, 0}; + u16 windowId; + int offset; + + window.width = 16; + window.height = 2; + windowId = AddWindow(&window); + FillWindowPixelBuffer(windowId, 0); + offset = GetStringCenterAlignXOffset(1, pocketName1, 0x40); + bag_menu_print(windowId, 1, pocketName1, offset, 1, 0, 0, -1, 1); + if (pocketName2) + { + offset = GetStringCenterAlignXOffset(1, pocketName2, 0x40); + bag_menu_print(windowId, 1, pocketName2, offset + 0x40, 1, 0, 0, -1, 1); + } + CpuCopy32((u8*)GetWindowAttribute(windowId, 7), gUnknown_0203CE54->unk844, 0x400); + RemoveWindow(windowId); +} + +void bag_menu_copy_pocket_name_to_window(u32 a) +{ + u8 (* r4)[32][32]; + u8* windowAttribute; + int b; + if (a > 8) + a = 8; + r4 = &gUnknown_0203CE54->unk844; + windowAttribute = (u8*)GetWindowAttribute(2, 7); + CpuCopy32(r4[0][a], windowAttribute, 0x100); + b = a + 16; + CpuCopy32(r4[0][b], windowAttribute + 0x100, 0x100); + CopyWindowToVram(2, 2); +} + +void setup_bag_menu_textboxes(void) +{ + u8 i; + + InitWindows(gUnknown_08614174); + DeactivateAllTextPrinters(); + sub_809882C(0, 1, -32); + copy_textbox_border_tile_patterns_to_vram(0, 10, -48); + sub_819A2BC(-64, 1); + LoadPalette(&gUnknown_0860F074, 0xF0, 0x20); + for (i = 0; i < 3; i++) + { + FillWindowPixelBuffer(i, 0); + PutWindowTilemap(i); + } + schedule_bg_copy_tilemap_to_vram(0); + schedule_bg_copy_tilemap_to_vram(1); +} + +void bag_menu_print(u8 a, u8 b, const u8 *str, u8 c, u8 d, u8 e, u8 f, u8 g, u8 h) +{ + AddTextPrinterParameterized2(a, b, c, d, e, f, gUnknown_08614164[h], g, str); +} + +u8 sub_81AE124(u8 a) +{ + return gUnknown_0203CE54->unk810[a]; +} + +u8 bag_menu_add_window(u8 a) +{ + u8 *ptr = &gUnknown_0203CE54->unk810[a]; + if (*ptr == 0xFF) + { + *ptr = AddWindow(&gUnknown_086141AC[a]); + SetWindowBorderStyle(*ptr, 0, 1, 14); + schedule_bg_copy_tilemap_to_vram(1); + } + return *ptr; +} + +void bag_menu_remove_window(u8 a) +{ + u8 *ptr = &gUnknown_0203CE54->unk810[a]; + if (*ptr != 0xFF) + { + sub_8198070(*ptr, 0); + ClearWindowTilemap(*ptr); + RemoveWindow(*ptr); + schedule_bg_copy_tilemap_to_vram(1); + *ptr = 0xFF; + } +} + +u8 AddItemMessageWindow(u8 a) +{ + u8 *ptr = &gUnknown_0203CE54->unk810[a]; + if (*ptr == 0xFF) + *ptr = AddWindow(&gUnknown_086141AC[a]); + return *ptr; +} + +void bag_menu_RemoveBagItem_message_window(u8 a) +{ + u8 *ptr = &gUnknown_0203CE54->unk810[a]; + if (*ptr != 0xFF) + { + sub_8197DF8(*ptr, 0); + ClearWindowTilemap(*ptr); + RemoveWindow(*ptr); + schedule_bg_copy_tilemap_to_vram(1); + *ptr = 0xFF; + } +} + +void bag_menu_yes_no(u8 a, u8 b, const struct YesNoFuncTable *funcTable) +{ + CreateYesNoMenuWithCallbacks(a, &gUnknown_086141AC[b], 1, 0, 2, 1, 14, funcTable); +} + +void bag_menu_AddMoney_window(void) +{ + u8 windowId = bag_menu_add_window(9); + PrintMoneyAmountInMoneyBoxWithBorder(windowId, 1, 14, GetMoney(&gSaveBlock1Ptr->money)); + AddMoneyLabelObject(19, 11); +} + +void bag_menu_remove_money_window(void) +{ + bag_menu_remove_window(9); + RemoveMoneyLabelObject(); +} + +void bag_menu_prepare_tmhm_move_window(void) +{ + FillWindowPixelBuffer(3, 0); + blit_move_info_icon(3, 19, 0, 0); + blit_move_info_icon(3, 20, 0, 12); + blit_move_info_icon(3, 21, 0, 24); + blit_move_info_icon(3, 22, 0, 36); + CopyWindowToVram(3, 2); +} + +void PrintTMHMMoveData(u16 itemId) +{ + u8 i; + u16 moveId; + const u8* text; + + FillWindowPixelBuffer(4, 0); + if (itemId == ITEM_NONE) + { + for (i = 0; i < 4; i++) + bag_menu_print(4, 1, gText_ThreeDashes, 7, i * 12, 0, 0, -1, 4); + CopyWindowToVram(4, 2); + } + else + { + moveId = ItemIdToBattleMoveId(itemId); + blit_move_info_icon(4, gBattleMoves[moveId].type + 1, 0, 0); + if (gBattleMoves[moveId].power <= 1) + { + text = gText_ThreeDashes; + } + else + { + ConvertIntToDecimalStringN(gStringVar1, gBattleMoves[moveId].power, 1, 3); + text = gStringVar1; + } + bag_menu_print(4, 1, text, 7, 12, 0, 0, -1, 4); + if (gBattleMoves[moveId].accuracy == 0) + { + text = gText_ThreeDashes; + } + else + { + ConvertIntToDecimalStringN(gStringVar1, gBattleMoves[moveId].accuracy, 1, 3); + text = gStringVar1; + } + bag_menu_print(4, 1, text, 7, 24, 0, 0, -1, 4); + ConvertIntToDecimalStringN(gStringVar1, gBattleMoves[moveId].pp, 1, 3); + bag_menu_print(4, 1, gStringVar1, 7, 36, 0, 0, -1, 4); + CopyWindowToVram(4, 2); + } +} diff --git a/src/item_use.c b/src/item_use.c index 8e4a5cf2d..2e47e6f14 100755 --- a/src/item_use.c +++ b/src/item_use.c @@ -1,4 +1,5 @@ #include "global.h" +#include "item_use.h" #include "battle.h" #include "berry.h" #include "bike.h" @@ -28,7 +29,6 @@ #include "task.h" #include "text.h" -extern u16 gSpecialVar_ItemId; extern void(**gUnknown_0203CE54)(void); extern void(**gUnknown_0203CF2C)(void); extern void(*gUnknown_0203A0F4)(u8 taskId); @@ -87,15 +87,12 @@ extern void sub_81ABA88(u8); extern void sub_80B7CC8(void); extern void flagmods_08054D70(void); extern u8* sub_806CF78(u16); -extern bool8 ExecuteTableBasedItemEffect_(struct Pokemon*, u16, u8, u8); -extern u8 gBankInMenu; -extern u16 gBattlerPartyIndexes[]; extern void sub_81B89F0(void); extern u8 GetItemEffectType(u16); extern struct MapConnection *sub_8088A8C(s16, s16); void MapPostLoadHook_UseItem(void); -extern void sub_80AF6D4(void); +void sub_80AF6D4(void); void Task_CallItemUseOnFieldCallback(u8 taskId); void bag_menu_inits_lists_menu(u8 taskId); void ItemUseOnFieldCB_Bike(u8 taskId); @@ -116,7 +113,7 @@ void sub_80FE024(u8 taskId); void sub_80FE124(u8 taskId); void sub_80FE164(u8 taskId); -void DisplayItemMessage(u8 taskId, u8 a, u8* str, void(*callback)(u8 taskId)); +void DisplayItemMessage(u8 taskId, u8 a, const u8* str, void(*callback)(u8 taskId)); void DisplayItemMessageInBattlePyramid(u8 taskId, u8* str, void(*callback)(u8 taskId)); void DisplayItemMessageOnField(u8 taskId, u8* str, void(*callback)(u8 taskId)); void sub_81C6714(u8 taskId); @@ -984,9 +981,9 @@ void sub_80FE440(u8 taskId) void ItemUseInBattle_StatIncrease(u8 taskId) { - u16 partyId = gBattlerPartyIndexes[gBankInMenu]; + u16 partyId = gBattlerPartyIndexes[gBattlerInMenuId]; - if (ExecuteTableBasedItemEffect_(&gPlayerParty[partyId], gSpecialVar_ItemId, partyId, 0) != FALSE) + if (ExecuteTableBasedItemEffect(&gPlayerParty[partyId], gSpecialVar_ItemId, partyId, 0) != FALSE) { if (!InBattlePyramid()) DisplayItemMessage(taskId, 1, gText_WontHaveEffect, bag_menu_inits_lists_menu); diff --git a/src/librfu_rfu.c b/src/librfu_rfu.c index cf3fe12ad..c5aa25c10 100644 --- a/src/librfu_rfu.c +++ b/src/librfu_rfu.c @@ -3,38 +3,6 @@ #include "librfu.h" -struct RfuUnk1 -{ - u8 unk_0[0x14]; - u32 unk_14; - u32 unk_18; - struct RfuIntrStruct unk_1c; -}; - -struct RfuUnk2 -{ - u8 unk_0[0x68]; - u32 unk_68; - u32 unk_6c; - u8 unk_70[0x70]; -}; - -struct RfuUnk3 -{ - u32 unk_0; - u32 unk_4; - u8 unk_8[0xD4]; - u32 unk_dc; -}; - -extern u32 *gUnknown_03007890; -extern u32 *gUnknown_03007894; -extern struct RfuUnk3* gUnknown_03007898; -extern struct RfuUnk2* gUnknown_03007880[4]; -extern struct RfuUnk1* gUnknown_03007870[4]; -extern void* sub_82E53F4; -extern void rfu_STC_clearAPIVariables(void); - // Nonmatching, only register differences /*u16 rfu_initializeAPI(u32 *unk0, u16 unk1, IntrFunc *interrupt, bool8 copyInterruptToRam) { diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c index 927b87c72..dcdf9b45a 100644 --- a/src/lilycove_lady.c +++ b/src/lilycove_lady.c @@ -641,7 +641,7 @@ static u8 sub_818E13C(void) return retval; } #else -__attribute__((naked)) static u8 sub_818E13C(void) +ASM_DIRECT static u8 sub_818E13C(void) { asm_unified("\tpush {r4-r7,lr}\n" "\tmovs r7, 0x1\n" diff --git a/src/link.c b/src/link.c index ae2cd1992..8f7aa71b6 100644 --- a/src/link.c +++ b/src/link.c @@ -1,6 +1,32 @@ // Includes #include "global.h" +#include "m4a.h" +#include "malloc.h" +#include "reset_save_heap.h" +#include "save.h" +#include "bg.h" +#include "window.h" +#include "librfu.h" +#include "random.h" +#include "decompress.h" +#include "string_util.h" +#include "event_data.h" +#include "item_menu.h" +#include "overworld.h" +#include "gpu_regs.h" +#include "palette.h" +#include "task.h" +#include "scanline_effect.h" +#include "menu.h" +#include "text.h" +#include "strings.h" +#include "constants/songs.h" +#include "sound.h" +#include "trade.h" +#include "battle.h" +#include "link.h" +#include "link_rfu.h" // Static type declarations @@ -8,7 +34,7 @@ struct BlockTransfer { u16 pos; u16 size; - void *src; + const u8 *src; bool8 active; u8 multiplayerId; }; @@ -23,34 +49,2392 @@ struct LinkTestBGInfo // Static RAM declarations -IWRAM_DATA struct BlockTransfer gUnknown_03000D10; +IWRAM_DATA struct BlockTransfer sBlockSend; IWRAM_DATA u32 link_c_unused_03000d1c; -IWRAM_DATA struct BlockTransfer gUnknown_03000D20[4]; -IWRAM_DATA u32 gUnknown_03000D50; +IWRAM_DATA struct BlockTransfer sBlockRecv[MAX_LINK_PLAYERS]; +IWRAM_DATA u32 sBlockSendDelayCounter; IWRAM_DATA u32 gUnknown_03000D54; IWRAM_DATA u8 gUnknown_03000D58; -IWRAM_DATA u32 gUnknown_03000D5C; +IWRAM_DATA u32 sPlayerDataExchangeStatus; IWRAM_DATA u32 gUnknown_03000D60; -IWRAM_DATA u8 gUnknown_03000D64[4]; // not really, but won't match otherwise -IWRAM_DATA u8 gUnknown_03000D68[4]; -IWRAM_DATA u8 gUnknown_03000D6C; -IWRAM_DATA bool8 gUnknown_03000D6D; -IWRAM_DATA u16 gUnknown_03000D6E; -IWRAM_DATA u16 gUnknown_03000D70; -IWRAM_DATA u8 gUnknown_03000D72; -IWRAM_DATA u8 gUnknown_03000D73; -IWRAM_DATA u8 gUnknown_03000D74[4]; // not really, but won't match otherwise -IWRAM_DATA u8 gUnknown_03000D78[8]; // not really, but won't match otherwise -IWRAM_DATA u8 gUnknown_03000D80[16]; -IWRAM_DATA u16 gUnknown_03000D90[8]; -IWRAM_DATA u32 gUnknown_03000DA0; -IWRAM_DATA u32 gUnknown_03000DA4; -IWRAM_DATA void *gUnknown_03000DA8; -IWRAM_DATA void *gUnknown_03000DAC; -IWRAM_DATA bool32 gUnknown_03000DB0; +IWRAM_DATA u8 sLinkTestLastBlockSendPos; +ALIGNED() IWRAM_DATA u8 sLinkTestLastBlockRecvPos[MAX_LINK_PLAYERS]; +IWRAM_DATA u8 sNumVBlanksWithoutSerialIntr; +IWRAM_DATA bool8 sSendBufferEmpty; +IWRAM_DATA u16 sSendNonzeroCheck; +IWRAM_DATA u16 sRecvNonzeroCheck; +IWRAM_DATA u8 sChecksumAvailable; +IWRAM_DATA u8 sHandshakePlayerCount; + +u16 gLinkPartnersHeldKeys[6]; +u32 gLinkDebugSeed; +struct LinkPlayerBlock gLocalLinkPlayerBlock; +bool8 gLinkErrorOccurred; +u32 gLinkDebugFlags; +u32 gFiller_03003074; +bool8 gRemoteLinkPlayersNotReceived[MAX_LINK_PLAYERS]; +u8 gBlockReceivedStatus[MAX_LINK_PLAYERS]; +u32 gFiller_03003080; +u16 gLinkHeldKeys; +u16 gRecvCmds[MAX_RFU_PLAYERS][CMD_LENGTH]; +u32 gLinkStatus; +bool8 gUnknown_030030E4; +bool8 gUnknown_030030E8; +bool8 gUnknown_030030EC[MAX_LINK_PLAYERS]; +bool8 gUnknown_030030F0[MAX_LINK_PLAYERS]; +u16 gUnknown_030030F4; +u8 gSuppressLinkErrorMessage; +bool8 gWirelessCommType; +bool8 gSavedLinkPlayerCount; +u16 gSendCmd[CMD_LENGTH]; +u8 gSavedMultiplayerId; +bool8 gReceivedRemoteLinkPlayers; +struct LinkTestBGInfo gLinkTestBGInfo; +void (*gLinkCallback)(void); +u8 gShouldAdvanceLinkState; +u16 gLinkTestBlockChecksums[MAX_LINK_PLAYERS]; +u8 gBlockRequestType; +u32 gFiller_03003154; +u32 gFiller_03003158; +u32 gFiller_0300315c; +u8 gLastSendQueueCount; +struct Link gLink; +u8 gLastRecvQueueCount; +u16 gLinkSavedIme; +u32 gFiller_03004138; +u32 gFiller_0300413C; + +EWRAM_DATA u8 gLinkTestDebugValuesEnabled = 0; +EWRAM_DATA u8 gUnknown_020223BD = 0; +EWRAM_DATA u32 gUnknown_020223C0 = 0; +EWRAM_DATA u16 gBlockRecvBuffer[MAX_RFU_PLAYERS][BLOCK_BUFFER_SIZE / 2] = {}; +EWRAM_DATA u8 gBlockSendBuffer[BLOCK_BUFFER_SIZE] = {}; +EWRAM_DATA bool8 gLinkOpen = FALSE; +EWRAM_DATA u16 gLinkType = 0; +EWRAM_DATA u16 gLinkTimeOutCounter = 0; +EWRAM_DATA struct LinkPlayer gLocalLinkPlayer = {}; +EWRAM_DATA struct LinkPlayer gLinkPlayers[MAX_RFU_PLAYERS] = {}; +EWRAM_DATA struct LinkPlayer gSavedLinkPlayers[MAX_RFU_PLAYERS] = {}; +EWRAM_DATA struct { + u32 status; + u8 lastRecvQueueCount; + u8 lastSendQueueCount; + u8 unk_06; +} sLinkErrorBuffer = {}; +EWRAM_DATA u16 gUnknown_02022B08 = 0; +EWRAM_DATA void *gUnknown_02022B0C = NULL; // Static ROM declarations +static void InitLocalLinkPlayer(void); +static void sub_80096BC(void); +static void CB2_LinkTest(void); +static void ProcessRecvCmds(u8 unused); +static void sub_8009F70(void); +static void ResetBlockSend(void); +static bool32 InitBlockSend(const void *src, size_t size); +static void LinkCB_BlockSendBegin(void); +static void LinkCB_BlockSend(void); +static void LinkCB_BlockSendEnd(void); +static void SetBlockReceivedFlag(u8 who); +static u16 LinkTestCalcBlockChecksum(const u16 *src, u16 size); +static void LinkTest_prnthex(u32 pos, u8 a0, u8 a1, u8 a2); +static void LinkCB_RequestPlayerDataExchange(void); +static void Task_PrintTestData(u8 taskId); + +static void sub_800AC80(void); +static void sub_800ACAC(void); +static void sub_800AD5C(void); +static void sub_800AD88(void); +static void sub_800AE30(void); +static void sub_800AE5C(void); + +static void CheckErrorStatus(void); +static void CB2_PrintErrorMessage(void); +static bool8 IsSioMultiMaster(void); +static void sub_800B4A4(void); +static void DisableSerial(void); +static void EnableSerial(void); +static void CheckMasterOrSlave(void); +static void InitTimer(void); +static void EnqueueSendCmd(u16 *sendCmd); +static void DequeueRecvCmds(u16 (*recvCmds)[CMD_LENGTH]); + +static void StartTransfer(void); +static bool8 DoHandshake(void); +static void DoRecv(void); +static void DoSend(void); +static void StopTimer(void); +static void SendRecvDone(void); + // .rodata +ALIGNED(4) const u16 gWirelessLinkDisplayPal[] = INCBIN_U16("graphics/interface/wireless_link_display.gbapal"); +const u8 gWirelessLinkDisplayGfx[] = INCBIN_U8("graphics/interface/wireless_link_display.4bpp.lz"); +const u8 gWirelessLinkDisplayTilemap[] = INCBIN_U8("graphics/interface/wireless_link_display.bin.lz"); +const u16 gLinkTestDigitsPal[] = INCBIN_U16("graphics/interface/link_test_digits.gbapal"); +const u16 gLinkTestDigitsGfx[] = INCBIN_U16("graphics/interface/link_test_digits.4bpp"); +const u8 unkstring_82ed160[] = _("{HIGHLIGHT TRANSPARENT}{COLOR WHITE}"); +const u16 g2BlankTilesGfx[] = INCBIN_U16("graphics/interface/blank_1x2.4bpp"); +const struct BlockRequest gUnknown_082ED1A8[] = { + {gBlockSendBuffer, 200}, + {gBlockSendBuffer, 200}, + {gBlockSendBuffer, 100}, + {gBlockSendBuffer, 220}, + {gBlockSendBuffer, 40} +}; +const u8 gBGControlRegs[] = { + REG_OFFSET_BG0CNT, + REG_OFFSET_BG1CNT, + REG_OFFSET_BG2CNT, + REG_OFFSET_BG3CNT +}; +const char gASCIIGameFreakInc[] = "GameFreak inc."; +const char gASCIITestPrint[] = "TEST PRINT\nP0\nP1\nP2\nP3"; +const struct BgTemplate gUnknown_082ED1FC[] = { + { + .bg = 0, + .charBaseIndex = 2, + .mapBaseIndex = 31, + .priority = 0 + }, { + .bg = 1, + .charBaseIndex = 0, + .mapBaseIndex = 8, + .priority = 1 + } +}; +const struct WindowTemplate gUnknown_082ED204[] = { + {0x00, 0x00, 0x00, 0x1E, 0x05, 0x0F, 0x0002}, + {0x00, 0x00, 0x06, 0x1E, 0x07, 0x0F, 0x0098}, + {0x00, 0x00, 0x0D, 0x1E, 0x07, 0x0F, 0x016A}, + DUMMY_WIN_TEMPLATE +}; +const u8 gUnknown_082ED224[] = { + 0x00, 0x01, 0x02, 0x00, + 0xff, 0xfe, 0xff, 0x00 +}; + // .text + +bool8 sub_80093CC(void) +{ + sub_800B488(); + sub_800E700(); + if (sub_800BEC0() == 0x8001) + { + rfu_REQ_stopMode(); + rfu_waitREQComplete(); + return TRUE; + } + sub_800B4A4(); + CloseLink(); + RestoreSerialTimer3IntrHandlers(); + return FALSE; +} + +void Task_DestroySelf(u8 taskId) +{ + DestroyTask(taskId); +} + +static void InitLinkTestBG(u8 paletteNum, u8 bgNum, u8 screenBaseBlock, u8 charBaseBlock, u16 a4) +{ + LoadPalette(gLinkTestDigitsPal, paletteNum * 16, 0x20); + DmaCopy16(3, gLinkTestDigitsGfx, (u16 *)BG_CHAR_ADDR(charBaseBlock) + (16 * a4), sizeof gLinkTestDigitsGfx); + gLinkTestBGInfo.screenBaseBlock = screenBaseBlock; + gLinkTestBGInfo.paletteNum = paletteNum; + gLinkTestBGInfo.dummy_8 = a4; + switch (bgNum) + { + case 1: + SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_SCREENBASE(screenBaseBlock) | BGCNT_PRIORITY(1) | BGCNT_CHARBASE(charBaseBlock)); + break; + case 2: + SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_SCREENBASE(screenBaseBlock) | BGCNT_PRIORITY(1) | BGCNT_CHARBASE(charBaseBlock)); + break; + case 3: + SetGpuReg(REG_OFFSET_BG3CNT, BGCNT_SCREENBASE(screenBaseBlock) | BGCNT_PRIORITY(1) | BGCNT_CHARBASE(charBaseBlock)); + break; + } + SetGpuReg(REG_OFFSET_BG0HOFS + bgNum * 4, 0); + SetGpuReg(REG_OFFSET_BG0VOFS + bgNum * 4, 0); +} + +void sub_80094EC(u8 paletteNum, u8 bgNum, u8 screenBaseBlock, u8 charBaseBlock) +{ + LoadPalette(gLinkTestDigitsPal, paletteNum * 16, 0x20); + DmaCopy16(3, gLinkTestDigitsGfx, (u16 *)BG_CHAR_ADDR(charBaseBlock), sizeof gLinkTestDigitsGfx); + gLinkTestBGInfo.screenBaseBlock = screenBaseBlock; + gLinkTestBGInfo.paletteNum = paletteNum; + gLinkTestBGInfo.dummy_8 = 0; + SetGpuReg(gBGControlRegs[bgNum], BGCNT_SCREENBASE(screenBaseBlock) | BGCNT_CHARBASE(charBaseBlock)); +} + +void LinkTestScreen(void) +{ + int i; + + ResetSpriteData(); + FreeAllSpritePalettes(); + ResetTasks(); + SetVBlankCallback(sub_80096BC); + ResetBlockSend(); + gLinkType = 0x1111; + OpenLink(); + SeedRng(gMain.vblankCounter2); + for (i = 0; i < MAX_LINK_PLAYERS; i++) + { + gSaveBlock2Ptr->playerTrainerId[i] = Random() % 256; + } + InitLinkTestBG(0, 2, 4, 0, 0); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON | DISPCNT_BG2_ON | DISPCNT_OBJ_ON); + CreateTask(Task_DestroySelf, 0); + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); + gUnknown_03000D60 = 0; + InitLocalLinkPlayer(); + CreateTask(Task_PrintTestData, 0); + SetMainCallback2(CB2_LinkTest); +} + +void sub_8009628(u8 a0) +{ + gLocalLinkPlayer.lp_field_18 = a0; +} + +static void InitLocalLinkPlayer(void) +{ + gLocalLinkPlayer.trainerId = gSaveBlock2Ptr->playerTrainerId[0] | (gSaveBlock2Ptr->playerTrainerId[1] << 8) | (gSaveBlock2Ptr->playerTrainerId[2] << 16) | (gSaveBlock2Ptr->playerTrainerId[3] << 24); + StringCopy(gLocalLinkPlayer.name, gSaveBlock2Ptr->playerName); + gLocalLinkPlayer.gender = gSaveBlock2Ptr->playerGender; + gLocalLinkPlayer.linkType = gLinkType; + gLocalLinkPlayer.language = gGameLanguage; + gLocalLinkPlayer.version = gGameVersion + 0x4000; + gLocalLinkPlayer.lp_field_2 = 0x8000; + gLocalLinkPlayer.name[8] = IsNationalPokedexEnabled(); + if (FlagGet(FLAG_0x87F)) + { + gLocalLinkPlayer.name[8] |= 0x10; + } +} + +static void sub_80096BC(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +static void InitLink(void) +{ + int i; + + for (i = 0; i < 8; i++) + { + gSendCmd[i] = 0xefff; + } + gLinkOpen = TRUE; + EnableSerial(); +} + +static void Task_TriggerHandshake(u8 taskId) +{ + if (++gTasks[taskId].data[0] == 5) + { + gShouldAdvanceLinkState = 1; + DestroyTask(taskId); + } +} + +void OpenLink(void) +{ + int i; + + if (!gWirelessCommType) + { + ResetSerial(); + InitLink(); + gLinkCallback = LinkCB_RequestPlayerDataExchange; + gLinkVSyncDisabled = FALSE; + gLinkErrorOccurred = FALSE; + gSuppressLinkErrorMessage = FALSE; + ResetBlockReceivedFlags(); + ResetBlockSend(); + gUnknown_03000D54 = 0; + gUnknown_030030E8 = FALSE; + gUnknown_030030E4 = FALSE; + gUnknown_030030F4 = 0; + CreateTask(Task_TriggerHandshake, 2); + } + else + { + sub_800E700(); + } + gReceivedRemoteLinkPlayers = 0; + for (i = 0; i < MAX_LINK_PLAYERS; i++) + { + gRemoteLinkPlayersNotReceived[i] = TRUE; + gUnknown_030030F0[i] = FALSE; + gUnknown_030030EC[i] = FALSE; + } +} + +void CloseLink(void) +{ + gReceivedRemoteLinkPlayers = FALSE; + if (gWirelessCommType) + { + sub_800EDD4(); + } + gLinkOpen = FALSE; + DisableSerial(); +} + +static void TestBlockTransfer(u8 nothing, u8 is, u8 used) +{ + u8 i; + u8 status; + + if (sLinkTestLastBlockSendPos != sBlockSend.pos) + { + LinkTest_prnthex(sBlockSend.pos, 2, 3, 2); + sLinkTestLastBlockSendPos = sBlockSend.pos; + } + for (i = 0; i < MAX_LINK_PLAYERS; i++) + { + if (sLinkTestLastBlockRecvPos[i] != sBlockRecv[i].pos) + { + LinkTest_prnthex(sBlockRecv[i].pos, 2, i + 4, 2); + sLinkTestLastBlockRecvPos[i] = sBlockRecv[i].pos; + } + } + status = GetBlockReceivedStatus(); + if (status == 0xF) // 0b1111 + { + for (i = 0; i < MAX_LINK_PLAYERS; i++) + { + if ((status >> i) & 1) + { + gLinkTestBlockChecksums[i] = LinkTestCalcBlockChecksum(gBlockRecvBuffer[i], sBlockRecv[i].size); + ResetBlockReceivedFlag(i); + if (gLinkTestBlockChecksums[i] != 0x0342) + { + gLinkTestDebugValuesEnabled = FALSE; + gUnknown_020223BD = FALSE; + } + } + } + } +} + +static void LinkTestProcessKeyInput(void) +{ + if (gMain.newKeys & A_BUTTON) + { + gShouldAdvanceLinkState = 1; + } + if (gMain.heldKeys & B_BUTTON) + { + InitBlockSend(gHeap + 0x4000, 0x00002004); + } + if (gMain.newKeys & L_BUTTON) + { + BeginNormalPaletteFade(-1, 0, 16, 0, 2); + } + if (gMain.newKeys & START_BUTTON) + { + SetSuppressLinkErrorMessage(TRUE); + } + if (gMain.newKeys & R_BUTTON) + { + TrySavingData(1); + } + if (gMain.newKeys & SELECT_BUTTON) + { + sub_800AC34(); + } + if (gLinkTestDebugValuesEnabled) + { + SetLinkDebugValues(gMain.vblankCounter2, gLinkCallback ? gLinkVSyncDisabled : gLinkVSyncDisabled | 0x10); + } +} + +static void CB2_LinkTest(void) +{ + LinkTestProcessKeyInput(); + TestBlockTransfer(1, 1, 0); + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +u16 LinkMain2(const u16 *heldKeys) +{ + u8 i; + + if (!gLinkOpen) + { + return 0; + } + for (i = 0; i < 8; i++) + { + gSendCmd[i] = 0; + } + gLinkHeldKeys = *heldKeys; + if (gLinkStatus & LINK_STAT_CONN_ESTABLISHED) + { + ProcessRecvCmds(SIO_MULTI_CNT->id); + if (gLinkCallback != NULL) + { + gLinkCallback(); + } + CheckErrorStatus(); + } + return gLinkStatus; +} + +static void HandleReceiveRemoteLinkPlayer(u8 who) +{ + int i; + int count; + + count = 0; + gRemoteLinkPlayersNotReceived[who] = FALSE; + for (i = 0; i < GetLinkPlayerCount_2(); i++) + { + count += gRemoteLinkPlayersNotReceived[i]; + } + if (count == 0 && gReceivedRemoteLinkPlayers == 0) + { + gReceivedRemoteLinkPlayers = 1; + } +} + +static void ProcessRecvCmds(u8 unused) +{ + u16 i; + + for (i = 0; i < MAX_LINK_PLAYERS; i++) + { + gLinkPartnersHeldKeys[i] = 0; + if (gRecvCmds[i][0] == 0) + { + continue; + } + switch (gRecvCmds[i][0]) + { + case LINKCMD_SEND_LINK_TYPE: + { + struct LinkPlayerBlock *block; + + InitLocalLinkPlayer(); + block = &gLocalLinkPlayerBlock; + block->linkPlayer = gLocalLinkPlayer; + memcpy(block->magic1, gASCIIGameFreakInc, sizeof(block->magic1) - 1); + memcpy(block->magic2, gASCIIGameFreakInc, sizeof(block->magic2) - 1); + InitBlockSend(block, sizeof(*block)); + break; + } + case LINKCMD_SEND_HELD_KEYS: + gLinkPartnersHeldKeys[i] = gRecvCmds[i][1]; + break; + case LINKCMD_0x5555: + gUnknown_030030E8 = TRUE; + break; + case LINKCMD_0x5566: + gUnknown_030030E8 = TRUE; + break; + case LINKCMD_INIT_BLOCK: + { + struct BlockTransfer *blockRecv; + + blockRecv = &sBlockRecv[i]; + blockRecv->pos = 0; + blockRecv->size = gRecvCmds[i][1]; + blockRecv->multiplayerId = gRecvCmds[i][2]; + break; + } + case LINKCMD_CONT_BLOCK: + { + if (sBlockRecv[i].size > BLOCK_BUFFER_SIZE) + { + u16 *buffer; + u16 j; + + buffer = (u16 *)gDecompressionBuffer; + for (j = 0; j < CMD_LENGTH - 1; j++) + { + buffer[(sBlockRecv[i].pos / 2) + j] = gRecvCmds[i][j + 1]; + } + } + else + { + u16 j; + + for (j = 0; j < CMD_LENGTH - 1; j++) + { + gBlockRecvBuffer[i][(sBlockRecv[i].pos / 2) + j] = gRecvCmds[i][j + 1]; + } + } + + sBlockRecv[i].pos += (CMD_LENGTH - 1) * 2; + + if (sBlockRecv[i].pos >= sBlockRecv[i].size) + { + if (gRemoteLinkPlayersNotReceived[i] == TRUE) + { + struct LinkPlayerBlock *block; + struct LinkPlayer *linkPlayer; + + block = (struct LinkPlayerBlock *)&gBlockRecvBuffer[i]; + linkPlayer = &gLinkPlayers[i]; + *linkPlayer = block->linkPlayer; + if ((linkPlayer->version & 0xFF) == VERSION_RUBY || (linkPlayer->version & 0xFF) == VERSION_SAPPHIRE) + { + linkPlayer->name[10] = 0; + linkPlayer->name[9] = 0; + linkPlayer->name[8] = 0; + } + sub_800B524(linkPlayer); + if (strcmp(block->magic1, gASCIIGameFreakInc) != 0 + || strcmp(block->magic2, gASCIIGameFreakInc) != 0) + { + SetMainCallback2(CB2_LinkError); + } + else + { + HandleReceiveRemoteLinkPlayer(i); + } + } + else + { + SetBlockReceivedFlag(i); + } + } + } + break; + case LINKCMD_0x5FFF: + gUnknown_030030F0[i] = TRUE; + break; + case LINKCMD_0x2FFE: + gUnknown_030030EC[i] = TRUE; + break; + case LINKCMD_0xAAAA: + sub_800A418(); + break; + case LINKCMD_0xCCCC: + SendBlock(0, gUnknown_082ED1A8[gRecvCmds[i][1]].address, gUnknown_082ED1A8[gRecvCmds[i][1]].size); + break; + case LINKCMD_SEND_HELD_KEYS_2: + gLinkPartnersHeldKeys[i] = gRecvCmds[i][1]; + break; + } + } +} + +static void BuildSendCmd(u16 command) +{ + switch (command) + { + case LINKCMD_SEND_LINK_TYPE: + gSendCmd[0] = LINKCMD_SEND_LINK_TYPE; + gSendCmd[1] = gLinkType; + break; + case LINKCMD_0x2FFE: + gSendCmd[0] = LINKCMD_0x2FFE; + break; + case LINKCMD_SEND_HELD_KEYS: + gSendCmd[0] = LINKCMD_SEND_HELD_KEYS; + gSendCmd[1] = gMain.heldKeys; + break; + case LINKCMD_0x5555: + gSendCmd[0] = LINKCMD_0x5555; + break; + case LINKCMD_0x6666: + gSendCmd[0] = LINKCMD_0x6666; + gSendCmd[1] = 0; + break; + case LINKCMD_0x7777: + { + u8 i; + + gSendCmd[0] = LINKCMD_0x7777; + for (i = 0; i < 5; i++) + { + gSendCmd[i + 1] = 0xEE; + } + break; + } + case LINKCMD_INIT_BLOCK: + gSendCmd[0] = LINKCMD_INIT_BLOCK; + gSendCmd[1] = sBlockSend.size; + gSendCmd[2] = sBlockSend.multiplayerId + 0x80; + break; + case LINKCMD_0xAAAA: + gSendCmd[0] = LINKCMD_0xAAAA; + break; + case LINKCMD_0xAAAB: + gSendCmd[0] = LINKCMD_0xAAAB; + gSendCmd[1] = gSpecialVar_ItemId; + break; + case LINKCMD_0xCCCC: + gSendCmd[0] = LINKCMD_0xCCCC; + gSendCmd[1] = gBlockRequestType; + break; + case LINKCMD_0x5FFF: + gSendCmd[0] = LINKCMD_0x5FFF; + gSendCmd[1] = gUnknown_030030F4; + break; + case LINKCMD_0x5566: + gSendCmd[0] = LINKCMD_0x5566; + break; + case LINKCMD_SEND_HELD_KEYS_2: + if (gUnknown_03005DA8 == 0 || gLinkTransferringData) + { + break; + } + gSendCmd[0] = LINKCMD_SEND_HELD_KEYS_2; + gSendCmd[1] = gUnknown_03005DA8; + break; + } +} + +void sub_8009F18(void) +{ + if (gWirelessCommType) + { + sub_800F804(); + } + gLinkCallback = sub_8009F70; +} + +bool32 sub_8009F3C(void) +{ + if (gWirelessCommType) + { + return sub_800F7E4(); + } + if (gLinkCallback == sub_8009F70) + { + return TRUE; + } + return FALSE; +} + +static void sub_8009F70(void) +{ + if (gReceivedRemoteLinkPlayers == TRUE) + { + BuildSendCmd(LINKCMD_SEND_HELD_KEYS_2); + } +} + +void ClearLinkCallback(void) +{ + if (gWirelessCommType) + { + Rfu_set_zero(); + } + else + { + gLinkCallback = NULL; + } +} + +void ClearLinkCallback_2(void) +{ + if (gWirelessCommType) + { + Rfu_set_zero(); + } + else + { + gLinkCallback = NULL; + } +} + +u8 GetLinkPlayerCount(void) +{ + if (gWirelessCommType) + { + return sub_80104F4(); + } + return EXTRACT_PLAYER_COUNT(gLinkStatus); +} + +static int sub_8009FF8(u32 version1, u32 version2) +{ + int i; + u8 nPlayers; + + nPlayers = GetLinkPlayerCount(); + for (i = 0; i < nPlayers; i++) + { + if ((gLinkPlayers[i].version & 0xFF) == version1 || (gLinkPlayers[i].version & 0xFF) == version2) + { + return 1; + } + } + return -1; +} + +u32 sub_800A03C(void) +{ + return 2; +} + +bool32 sub_800A040(void) +{ + if (GetLinkPlayerCount() != 4 || sub_8009FF8(VERSION_RUBY, VERSION_SAPPHIRE) < 0) + { + return FALSE; + } + return TRUE; +} + +bool32 sub_800A064(void) +{ + if (sub_8009FF8(VERSION_RUBY, VERSION_SAPPHIRE) >= 0) + { + return TRUE; + } + return FALSE; +} + +bool32 sub_800A07C(void) +{ + int i; + + i = sub_8009FF8(VERSION_FIRE_RED, VERSION_LEAF_GREEN); + if (i >= 0 && gLinkPlayers[i].language == LANGUAGE_JAPANESE) + { + return TRUE; + } + return FALSE; +} + +void OpenLinkTimed(void) +{ + sPlayerDataExchangeStatus = EXCHANGE_NOT_STARTED; + gLinkTimeOutCounter = 0; + OpenLink(); +} + +u8 GetLinkPlayerDataExchangeStatusTimed(int lower, int upper) +{ + int i; + int count; + u32 index; + u8 cmpVal; + u32 linkType1; + u32 linkType2; + + count = 0; + if (gReceivedRemoteLinkPlayers == TRUE) + { + cmpVal = GetLinkPlayerCount_2(); + if (lower > cmpVal || cmpVal > upper) + { + sPlayerDataExchangeStatus = EXCHANGE_STAT_6; + return 6; + } + else + { + if (GetLinkPlayerCount() == 0) + { + gLinkErrorOccurred = TRUE; + CloseLink(); + } + for (i = 0, index = 0; i < GetLinkPlayerCount(); index++, i++) + { + if (gLinkPlayers[index].linkType == gLinkPlayers[0].linkType) + { + count++; + } + } + if (count == GetLinkPlayerCount()) + { + if (gLinkPlayers[0].linkType == 0x1133) + { + switch (sub_807A728()) + { + case 1: + sPlayerDataExchangeStatus = EXCHANGE_STAT_4; + break; + case 2: + sPlayerDataExchangeStatus = EXCHANGE_STAT_5; + break; + case 0: + sPlayerDataExchangeStatus = EXCHANGE_COMPLETE; + break; + } + } + else + { + sPlayerDataExchangeStatus = EXCHANGE_COMPLETE; + } + } + else + { + sPlayerDataExchangeStatus = EXCHANGE_IN_PROGRESS; + linkType1 = gLinkPlayers[GetMultiplayerId()].linkType; + linkType2 = gLinkPlayers[GetMultiplayerId() ^ 1].linkType; + if ((linkType1 == 0x2266 && linkType2 == 0x2277) || (linkType1 == 0x2277 && linkType2 == 0x2266)) + { + gSpecialVar_0x8005 = 3; + } + } + } + } + else if (++gLinkTimeOutCounter > 600) + { + sPlayerDataExchangeStatus = EXCHANGE_TIMED_OUT; + } + return sPlayerDataExchangeStatus; +} + +bool8 IsLinkPlayerDataExchangeComplete(void) +{ + u8 i; + u8 count; + bool8 retval; + + count = 0; + for (i = 0; i < GetLinkPlayerCount(); i++) + { + if (gLinkPlayers[i].linkType == gLinkPlayers[0].linkType) + { + count++; + } + } + if (count == GetLinkPlayerCount()) + { + retval = TRUE; + sPlayerDataExchangeStatus = EXCHANGE_COMPLETE; + } + else + { + retval = FALSE; + sPlayerDataExchangeStatus = EXCHANGE_IN_PROGRESS; + } + return retval; +} + +u32 GetLinkPlayerTrainerId(u8 who) +{ + return gLinkPlayers[who].trainerId; +} + +void ResetLinkPlayers(void) +{ + int i; + + for (i = 0; i <= MAX_LINK_PLAYERS; i++) + { + gLinkPlayers[i] = (struct LinkPlayer){}; + } +} + +static void ResetBlockSend(void) +{ + sBlockSend.active = FALSE; + sBlockSend.pos = 0; + sBlockSend.size = 0; + sBlockSend.src = NULL; +} + +static bool32 InitBlockSend(const void *src, size_t size) +{ + if (sBlockSend.active) + { + return FALSE; + } + sBlockSend.multiplayerId = GetMultiplayerId(); + sBlockSend.active = TRUE; + sBlockSend.size = size; + sBlockSend.pos = 0; + if (size > 0x100) + { + sBlockSend.src = src; + } + else + { + if (src != gBlockSendBuffer) + { + memcpy(gBlockSendBuffer, src, size); + } + sBlockSend.src = gBlockSendBuffer; + } + BuildSendCmd(LINKCMD_INIT_BLOCK); + gLinkCallback = LinkCB_BlockSendBegin; + sBlockSendDelayCounter = 0; + return TRUE; +} + +static void LinkCB_BlockSendBegin(void) +{ + if (++sBlockSendDelayCounter > 2) + { + gLinkCallback = LinkCB_BlockSend; + } +} + +static void LinkCB_BlockSend(void) +{ + int i; + const u8 *src; + + src = sBlockSend.src; + gSendCmd[0] = LINKCMD_CONT_BLOCK; + for (i = 0; i < 7; i++) + { + gSendCmd[i + 1] = (src[sBlockSend.pos + i * 2 + 1] << 8) | src[sBlockSend.pos + i * 2]; + } + sBlockSend.pos += 14; + if (sBlockSend.size <= sBlockSend.pos) + { + sBlockSend.active = FALSE; + gLinkCallback = LinkCB_BlockSendEnd; + } +} + +static void LinkCB_BlockSendEnd(void) +{ + gLinkCallback = NULL; +} + +static void sub_800A3F8(void) +{ + GetMultiplayerId(); + BuildSendCmd(LINKCMD_SEND_HELD_KEYS); + gUnknown_020223C0++; +} + +void sub_800A418(void) +{ + gUnknown_020223C0 = 0; + if (gWirelessCommType) + { + sub_800F850(); + } + else + { + gLinkCallback = sub_800A3F8; + } +} + +u32 sub_800A44C(void) +{ + return gUnknown_020223C0; +} + +void sub_800A458(void) +{ + BuildSendCmd(LINKCMD_0xAAAA); +} + +u8 GetMultiplayerId(void) +{ + if (gWirelessCommType == TRUE) + { + return rfu_get_multiplayer_id(); + } + return SIO_MULTI_CNT->id; +} + +u8 bitmask_all_link_players_but_self(void) +{ + u8 mpId; + + mpId = GetMultiplayerId(); + return ((1 << MAX_LINK_PLAYERS) - 1) ^ (1 << mpId); +} + +bool8 SendBlock(u8 unused, const void *src, u16 size) +{ + if (gWirelessCommType == TRUE) + { + return sub_800FE84(src, size); + } + return InitBlockSend(src, size); +} + +bool8 sub_800A4D8(u8 a0) +{ + if (gWirelessCommType == TRUE) + { + return sub_8010100(a0); + } + if (gLinkCallback == NULL) + { + gBlockRequestType = a0; + BuildSendCmd(LINKCMD_0xCCCC); + return TRUE; + } + return FALSE; +} + +bool8 sub_800A520(void) +{ + if (gWirelessCommType == TRUE) + { + return sub_8010500(); + } + return gLinkCallback == NULL; +} + +u8 GetBlockReceivedStatus(void) +{ + if (gWirelessCommType == TRUE) + { + return sub_800FCD8(); + } + return (gBlockReceivedStatus[3] << 3) | (gBlockReceivedStatus[2] << 2) | (gBlockReceivedStatus[1] << 1) | (gBlockReceivedStatus[0] << 0); +} + +static void SetBlockReceivedFlag(u8 who) +{ + if (gWirelessCommType == TRUE) + { + sub_800F6FC(who); + } + else + { + gBlockReceivedStatus[who] = TRUE; + } +} + +void ResetBlockReceivedFlags(void) +{ + int i; + + if (gWirelessCommType == TRUE) + { + for (i = 0; i < MAX_RFU_PLAYERS; i++) + { + sub_800F728(i); + } + } + else + { + for (i = 0; i < MAX_LINK_PLAYERS; i++) + { + gBlockReceivedStatus[i] = FALSE; + } + } +} + +void ResetBlockReceivedFlag(u8 who) +{ + if (gWirelessCommType == TRUE) + { + sub_800F728(who); + } + else if (gBlockReceivedStatus[who]) + { + gBlockReceivedStatus[who] = FALSE; + } +} + +void sub_800A620(void) +{ + if ((gLinkStatus & LINK_STAT_MASTER) && EXTRACT_PLAYER_COUNT(gLinkStatus) > 1) + { + gShouldAdvanceLinkState = 1; + } +} + +static u16 LinkTestCalcBlockChecksum(const u16 *src, u16 size) +{ + u16 chksum; + u16 i; + + chksum = 0; + for (i = 0; i < size / 2; i++) + { + chksum += src[i]; + } + return chksum; +} + +static void LinkTest_prnthexchar(char a0, u8 a1, u8 a2) +{ + u16 *vAddr; + + vAddr = (u16 *)BG_SCREEN_ADDR(gLinkTestBGInfo.screenBaseBlock); + vAddr[a2 * 32 + a1] = (gLinkTestBGInfo.paletteNum << 12) | (a0 + 1 + gLinkTestBGInfo.dummy_8); +} + +static void LinkTest_prntchar(char a0, u8 a1, u8 a2) +{ + u16 *vAddr; + + vAddr = (u16 *)BG_SCREEN_ADDR(gLinkTestBGInfo.screenBaseBlock); + vAddr[a2 * 32 + a1] = (gLinkTestBGInfo.paletteNum << 12) | (a0 + gLinkTestBGInfo.dummy_8); +} + +static void LinkTest_prnthex(u32 pos, u8 a0, u8 a1, u8 a2) +{ + char sp[32 / 2]; + int i; + + for (i = 0; i < a2; i++) + { + sp[i] = pos & 0xf; + pos >>= 4; + } + for (i = a2 - 1; i >= 0; i--) + { + LinkTest_prnthexchar(sp[i], a0, a1); + a0++; + } +} + +static void LinkTest_prntint(int a0, u8 a1, u8 a2, u8 a3) +{ + char sp[32 / 2]; + int sp10; + int i; + + sp10 = -1; + if (a0 < 0) + { + sp10 = a1; + a0 = -a0; + } + for (i = 0; i < a3; i++) + { + sp[i] = a0 % 10; + a0 /= 10; + } + for (i = a3 - 1; i >= 0; i--) + { + LinkTest_prnthexchar(sp[i], a1, a2); + a1++; + } + if (sp10 != -1) + { + LinkTest_prnthexchar(*"\n", sp10, a2); + } +} + +static void LinkTest_prntstr(const char *a0, u8 a1, u8 a2) +{ + int r6; + int i; + int r5; + + r5 = 0; + r6 = 0; + for (i = 0; a0[i] != 0; a0++) + { + if (a0[i] == *"\n") + { + r5++; + r6 = 0; + } + else + { + LinkTest_prntchar(a0[i], a1 + r6, a2 + r5); + r6++; + } + } +} + +static void LinkCB_RequestPlayerDataExchange(void) +{ + if (gLinkStatus & LINK_STAT_MASTER) + { + BuildSendCmd(LINKCMD_SEND_LINK_TYPE); + } + gLinkCallback = NULL; +} + +static void Task_PrintTestData(u8 taskId) +{ + char sp[32]; + int i; + + strcpy(sp, gASCIITestPrint); + LinkTest_prntstr(sp, 5, 2); + LinkTest_prnthex(gShouldAdvanceLinkState, 2, 1, 2); + LinkTest_prnthex(gLinkStatus, 15, 1, 8); + LinkTest_prnthex(gLink.state, 2, 10, 2); + LinkTest_prnthex(EXTRACT_PLAYER_COUNT(gLinkStatus), 15, 10, 2); + LinkTest_prnthex(GetMultiplayerId(), 15, 12, 2); + LinkTest_prnthex(gLastSendQueueCount, 25, 1, 2); + LinkTest_prnthex(gLastRecvQueueCount, 25, 2, 2); + LinkTest_prnthex(GetBlockReceivedStatus(), 15, 5, 2); + LinkTest_prnthex(gLinkDebugSeed, 2, 12, 8); + LinkTest_prnthex(gLinkDebugFlags, 2, 13, 8); + LinkTest_prnthex(GetSioMultiSI(), 25, 5, 1); + LinkTest_prnthex(IsSioMultiMaster(), 25, 6, 1); + LinkTest_prnthex(IsLinkConnectionEstablished(), 25, 7, 1); + LinkTest_prnthex(HasLinkErrorOccurred(), 25, 8, 1); + for (i = 0; i < MAX_LINK_PLAYERS; i++) + { + LinkTest_prnthex(gLinkTestBlockChecksums[i], 10, 4 + i, 4); + } +} + +void SetLinkDebugValues(u32 seed, u32 flags) +{ + gLinkDebugSeed = seed; + gLinkDebugFlags = flags; +} + +u8 sub_800A9A8(void) +{ + int i; + u8 flags; + + flags = 0; + for (i = 0; i < gSavedLinkPlayerCount; i++) + { + flags |= (1 << i); + } + return flags; +} + +u8 sub_800A9D8(void) +{ + int i; + u8 flags; + + flags = 0; + for (i = 0; i < GetLinkPlayerCount(); i++) + { + flags |= (1 << i); + } + return flags; +} + +void sub_800AA04(u8 a0) +{ + int i; + + gSavedLinkPlayerCount = a0; + gSavedMultiplayerId = GetMultiplayerId(); + for (i = 0; i < MAX_RFU_PLAYERS; i++) + { + gSavedLinkPlayers[i] = gLinkPlayers[i]; + } +} + +u8 sub_800AA48(void) +{ + return gSavedLinkPlayerCount; +} + +u8 sub_800AA54(void) +{ + return gSavedMultiplayerId; +} + +bool8 sub_800AA60(void) +{ + int i; + unsigned count; + + count = 0; + for (i = 0; i < gSavedLinkPlayerCount; i++) + { + if (gLinkPlayers[i].trainerId == gSavedLinkPlayers[i].trainerId) + { + if (gLinkType == 0x2288) + { + if (gLinkType == gLinkPlayers[i].linkType) + { + count++; + } + } + else + { + count++; + } + } + } + if (count == gSavedLinkPlayerCount) + { + if (GetLinkPlayerCount_2() == gSavedLinkPlayerCount) + { + return TRUE; + } + } + return FALSE; +} + +void sub_800AAF4(void) +{ + int i; + + // Clearly not what was meant to be written, but here it is anyway. + for (i = 0; i < 4; i++) + { + CpuSet(&gSavedLinkPlayers[i], NULL, sizeof(struct LinkPlayer)); + } +} + +void sub_800AB18(void) +{ + u8 i; + + for (i = 0; i < gSavedLinkPlayerCount; i++) + { + if (gSavedLinkPlayers[i].trainerId != gLinkPlayers[i].trainerId || StringCompare(gSavedLinkPlayers[i].name, gLinkPlayers[i].name) != 0) + { + gLinkErrorOccurred = TRUE; + CloseLink(); + SetMainCallback2(CB2_LinkError); + } + } +} + +void sub_800AB98(void) +{ + gSavedLinkPlayerCount = 0; + gSavedMultiplayerId = 0; +} + +u8 GetLinkPlayerCount_2(void) +{ + return EXTRACT_PLAYER_COUNT(gLinkStatus); +} + +bool8 IsLinkMaster(void) +{ + if (gWirelessCommType) + { + return Rfu_IsMaster(); + } + return EXTRACT_MASTER(gLinkStatus); +} + +u8 sub_800ABE8(void) +{ + return gUnknown_03000D58; +} + +void sub_800ABF4(u16 a0) +{ + if (gWirelessCommType == TRUE) + { + task_add_05_task_del_08FA224_when_no_RfuFunc(); + } + else + { + if (gLinkCallback == NULL) + { + gLinkCallback = sub_800AC80; + gUnknown_030030E4 = FALSE; + gUnknown_030030F4 = a0; + } + } +} + +void sub_800AC34(void) +{ + if (gWirelessCommType == TRUE) + { + task_add_05_task_del_08FA224_when_no_RfuFunc(); + } + else + { + if (gLinkCallback != NULL) + { + gUnknown_02022B08++; + } + else + { + gLinkCallback = sub_800AC80; + gUnknown_030030E4 = FALSE; + gUnknown_030030F4 = 0; + } + } +} + +static void sub_800AC80(void) +{ + if (gLastRecvQueueCount == 0) + { + BuildSendCmd(LINKCMD_0x5FFF); + gLinkCallback = sub_800ACAC; + } +} + +static void sub_800ACAC(void) +{ + int i; + unsigned count; + u8 linkPlayerCount; + + linkPlayerCount = GetLinkPlayerCount(); + count = 0; + for (i = 0; i < linkPlayerCount; i++) + { + if (gUnknown_030030F0[i]) + { + count++; + } + } + if (count == linkPlayerCount) + { + gBattleTypeFlags &= ~BATTLE_TYPE_20; + gLinkVSyncDisabled = TRUE; + CloseLink(); + gLinkCallback = NULL; + gUnknown_030030E4 = TRUE; + } +} + +void sub_800AD10(void) +{ + if (gWirelessCommType == TRUE) + { + task_add_05_task_del_08FA224_when_no_RfuFunc(); + } + else + { + if (gLinkCallback != NULL) + { + gUnknown_02022B08++; + } + else + { + gLinkCallback = sub_800AD5C; + gUnknown_030030E4 = FALSE; + gUnknown_030030F4 = 0; + } + } +} + +static void sub_800AD5C(void) +{ + if (gLastRecvQueueCount == 0) + { + BuildSendCmd(LINKCMD_0x5FFF); + gLinkCallback = sub_800AD88; + } +} + +static void sub_800AD88(void) +{ + int i; + unsigned count; + u8 linkPlayerCount; + + linkPlayerCount = GetLinkPlayerCount(); + count = 0; + for (i = 0; i < linkPlayerCount; i++) + { + if (gLinkPlayers[i].language == LANGUAGE_JAPANESE) + { + count++; + } + else if (gUnknown_030030F0[i]) + { + count++; + } + } + if (count == linkPlayerCount) + { + gBattleTypeFlags &= ~BATTLE_TYPE_20; + gLinkVSyncDisabled = TRUE; + CloseLink(); + gLinkCallback = NULL; + gUnknown_030030E4 = TRUE; + } +} + +void sub_800ADF8(void) +{ + if (gWirelessCommType == TRUE) + { + sub_8010434(); + } + else + { + if (gLinkCallback == NULL) + { + gLinkCallback = sub_800AE30; + } + gUnknown_030030E4 = FALSE; + } +} + +static void sub_800AE30(void) +{ + if (gLastRecvQueueCount == 0) + { + BuildSendCmd(LINKCMD_0x2FFE); + gLinkCallback = sub_800AE5C; + } +} + +static void sub_800AE5C(void) +{ + u8 i; + u8 linkPlayerCount; + + linkPlayerCount = GetLinkPlayerCount(); + for (i = 0; i < linkPlayerCount; i++) + { + if (!gUnknown_030030EC[i]) + { + break; + } + } + if (i == linkPlayerCount) + { + for (i = 0; i < MAX_LINK_PLAYERS; i++) + { + gUnknown_030030EC[i] = FALSE; + } + gLinkCallback = NULL; + } +} + +static void CheckErrorStatus(void) +{ + if (gLinkOpen && EXTRACT_LINK_ERRORS(gLinkStatus)) + { + if (!gSuppressLinkErrorMessage) + { + sLinkErrorBuffer.status = gLinkStatus; + sLinkErrorBuffer.lastRecvQueueCount = gLastRecvQueueCount; + sLinkErrorBuffer.lastSendQueueCount = gLastSendQueueCount; + SetMainCallback2(CB2_LinkError); + } + gLinkErrorOccurred = TRUE; + CloseLink(); + } +} + +void sub_800AF18(u32 status, u8 lastSendQueueCount, u8 lastRecvQueueCount, u8 unk_06) +{ + sLinkErrorBuffer.status = status; + sLinkErrorBuffer.lastSendQueueCount = lastSendQueueCount; + sLinkErrorBuffer.lastRecvQueueCount = lastRecvQueueCount; + sLinkErrorBuffer.unk_06 = unk_06; +} + +void CB2_LinkError(void) +{ + u8 *tilemapBuffer; + + SetGpuReg(REG_OFFSET_DISPCNT, 0); + m4aMPlayStop(&gMPlayInfo_SE1); + m4aMPlayStop(&gMPlayInfo_SE2); + m4aMPlayStop(&gMPlayInfo_SE3); + InitHeap(gHeap, HEAP_SIZE); + ResetSpriteData(); + FreeAllSpritePalettes(); + ResetPaletteFadeControl(); + FillPalette(0, 0, 2); + ResetTasks(); + ScanlineEffect_Stop(); + if (gWirelessCommType) + { + if (!sLinkErrorBuffer.unk_06) + { + gWirelessCommType = 3; + } + sub_800E604(); + } + SetVBlankCallback(sub_80096BC); + ResetBgsAndClearDma3BusyFlags(0); + InitBgsFromTemplates(0, gUnknown_082ED1FC, 2); + gUnknown_02022B0C = tilemapBuffer = malloc(0x800); + SetBgTilemapBuffer(1, tilemapBuffer); + if (InitWindows(gUnknown_082ED204)) + { + DeactivateAllTextPrinters(); + reset_temp_tile_data_buffers(); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + SetGpuReg(REG_OFFSET_BG0HOFS, 0); + SetGpuReg(REG_OFFSET_BG0VOFS, 0); + SetGpuReg(REG_OFFSET_BG1HOFS, 0); + SetGpuReg(REG_OFFSET_BG1VOFS, 0); + ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON | DISPCNT_WIN1_ON | DISPCNT_OBJWIN_ON); + LoadPalette(gUnknown_0860F074, 0xf0, 0x20); + gSoftResetDisabled = FALSE; + CreateTask(Task_DestroySelf, 0); + StopMapMusic(); + gMain.callback1 = NULL; + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); + SetMainCallback2(CB2_PrintErrorMessage); + } +} + +static void sub_800B080(void) +{ + LoadBgTiles(0, g2BlankTilesGfx, 0x20, 0); + copy_decompressed_tile_data_to_vram_autofree(1, gWirelessLinkDisplayGfx, FALSE, 0, 0); + CopyToBgTilemapBuffer(1, gWirelessLinkDisplayTilemap, 0, 0); + CopyBgTilemapBufferToVram(1); + LoadPalette(gWirelessLinkDisplayPal, 0, 0x20); + FillWindowPixelBuffer(0, 0x00); + FillWindowPixelBuffer(2, 0x00); + box_print(0, 3, 2, 6, gUnknown_082ED224, 0, gText_CommErrorEllipsis); + box_print(2, 3, 2, 1, gUnknown_082ED224, 0, gText_MoveCloserToLinkPartner); + PutWindowTilemap(0); + PutWindowTilemap(2); + CopyWindowToVram(0, 0); + CopyWindowToVram(2, 3); +} + +static void sub_800B138(void) +{ + LoadBgTiles(0, g2BlankTilesGfx, 0x20, 0); + FillWindowPixelBuffer(1, 0x00); + FillWindowPixelBuffer(2, 0x00); + box_print(1, 3, 2, 0, gUnknown_082ED224, 0, gText_CommErrorCheckConnections); + PutWindowTilemap(1); + PutWindowTilemap(2); + CopyWindowToVram(1, 0); + CopyWindowToVram(2, 3); +} + +static void CB2_PrintErrorMessage(void) +{ + switch (gMain.state) + { + case 00: + if (sLinkErrorBuffer.unk_06) + { + sub_800B080(); + } + else + { + sub_800B138(); + } + break; + case 02: + ShowBg(0); + if (sLinkErrorBuffer.unk_06) + { + ShowBg(1); + } + break; + case 30: + PlaySE(SE_BOO); + break; + case 60: + PlaySE(SE_BOO); + break; + case 90: + PlaySE(SE_BOO); + break; + case 130: + if (gWirelessCommType == 2) + { + box_print(0, 3, 2, 20, gUnknown_082ED224, 0, gText_ABtnTitleScreen); + } + else if (gWirelessCommType == 1) + { + box_print(0, 3, 2, 20, gUnknown_082ED224, 0, gText_ABtnRegistrationCounter); + } + break; + } + if (gMain.state == 160) + { + if (gWirelessCommType == 1) + { + if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_PIN); + gWirelessCommType = 0; + sLinkErrorBuffer.unk_06 = 0; + sub_81700F8(); + } + } + else if (gWirelessCommType == 2) + { + if (gMain.newKeys & A_BUTTON) + { + rfu_REQ_stopMode(); + rfu_waitREQComplete(); + DoSoftReset(); + } + } + } + if (gMain.state != 160) + { + gMain.state++; + } +} + +// TODO: there might be a file boundary here, let's name it + +bool8 GetSioMultiSI(void) +{ + return (REG_SIOCNT & 0x04) != 0; +} + +static bool8 IsSioMultiMaster(void) +{ + return (REG_SIOCNT & 0x8) && !(REG_SIOCNT & 0x04); +} + +bool8 IsLinkConnectionEstablished(void) +{ + return EXTRACT_CONN_ESTABLISHED(gLinkStatus); +} + +void SetSuppressLinkErrorMessage(bool8 flag) +{ + gSuppressLinkErrorMessage = flag; +} + +bool8 HasLinkErrorOccurred(void) +{ + return gLinkErrorOccurred; +} + +void sub_800B348(void) +{ + struct LinkPlayerBlock *block; + + InitLocalLinkPlayer(); + block = &gLocalLinkPlayerBlock; + block->linkPlayer = gLocalLinkPlayer; + memcpy(block->magic1, gASCIIGameFreakInc, sizeof(block->magic1) - 1); + memcpy(block->magic2, gASCIIGameFreakInc, sizeof(block->magic2) - 1); + memcpy(gBlockSendBuffer, block, sizeof(*block)); +} + +void sub_800B3A4(u32 who) +{ + u8 who_ = who; + struct LinkPlayerBlock *block; + struct LinkPlayer *player; + + block = (struct LinkPlayerBlock *)gBlockRecvBuffer[who_]; + player = &gLinkPlayers[who_]; + *player = block->linkPlayer; + sub_800B524(player); + if (strcmp(block->magic1, gASCIIGameFreakInc) != 0 || strcmp(block->magic2, gASCIIGameFreakInc) != 0) + { + SetMainCallback2(CB2_LinkError); + } +} + +bool8 HandleLinkConnection(void) +{ + bool32 r4; + bool32 r5; + + if (gWirelessCommType == 0) + { + gLinkStatus = LinkMain1(&gShouldAdvanceLinkState, gSendCmd, gRecvCmds); + LinkMain2(&gMain.heldKeys); + if ((gLinkStatus & LINK_STAT_RECEIVED_NOTHING) && sub_808766C() == TRUE) + { + return TRUE; + } + } + else + { + r4 = sub_8010EC0(); + r5 = sub_8010F1C(); + if (sub_808766C() == TRUE) + { + if (r4 == TRUE || sub_800F0B8() || r5) + { + return TRUE; + } + } + } + return FALSE; +} + +void sub_800B488(void) +{ + if (gReceivedRemoteLinkPlayers == 0) + { + gWirelessCommType = 1; + } +} + +static void sub_800B4A4(void) +{ + if (gReceivedRemoteLinkPlayers == 0) + { + gWirelessCommType = 0; + } +} + +void sub_800B4C0(void) +{ + if (gReceivedRemoteLinkPlayers == 0) + { + gWirelessCommType = 0; + } +} + +u32 sub_800B4DC(void) +{ + if (gWirelessCommType != 0) + { + return sub_80124D4(); + } + return gLink.recvQueue.count; +} + +bool8 sub_800B504(void) +{ + if (sub_800B4DC() > 2) + { + return TRUE; + } + return FALSE; +} + +u8 sub_800B518(void) +{ + return gWirelessCommType; +} + +void sub_800B524(struct LinkPlayer *player) +{ + player->name[10] = player->name[8]; + ConvertInternationalString(player->name, player->language); +} + +static void DisableSerial(void) +{ + DisableInterrupts(INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL); + REG_SIOCNT = SIO_MULTI_MODE; + REG_TMCNT_H(3) = 0; + REG_IF = INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL; + REG_SIOMLT_SEND = 0; + REG_SIOMLT_RECV = 0; + CpuFill32(0, &gLink, sizeof(gLink)); +} + +static void EnableSerial(void) +{ + DisableInterrupts(INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL); + REG_RCNT = 0; + REG_SIOCNT = SIO_MULTI_MODE; + REG_SIOCNT |= SIO_115200_BPS | SIO_INTR_ENABLE; + EnableInterrupts(INTR_FLAG_SERIAL); + REG_SIOMLT_SEND = 0; + CpuFill32(0, &gLink, sizeof(gLink)); + sNumVBlanksWithoutSerialIntr = 0; + sSendNonzeroCheck = 0; + sRecvNonzeroCheck = 0; + sChecksumAvailable = 0; + sHandshakePlayerCount = 0; + gLastSendQueueCount = 0; + gLastRecvQueueCount = 0; +} + +void ResetSerial(void) +{ + EnableSerial(); + DisableSerial(); +} + +// link_main1.c + +u32 LinkMain1(u8 *shouldAdvanceLinkState, u16 *sendCmd, u16 (*recvCmds)[CMD_LENGTH]) +{ + u32 retVal; + u32 retVal2; + + switch (gLink.state) + { + case LINK_STATE_START0: + DisableSerial(); + gLink.state = 1; + break; + case LINK_STATE_START1: + if (*shouldAdvanceLinkState == 1) + { + EnableSerial(); + gLink.state = 2; + } + break; + case LINK_STATE_HANDSHAKE: + switch (*shouldAdvanceLinkState) + { + default: + CheckMasterOrSlave(); + break; + case 1: + if (gLink.isMaster == LINK_MASTER && gLink.playerCount > 1) + { + gLink.handshakeAsMaster = TRUE; + } + break; + case 2: + gLink.state = LINK_STATE_START0; + REG_SIOMLT_SEND = 0; + break; + } + break; + case LINK_STATE_INIT_TIMER: + InitTimer(); + gLink.state = LINK_STATE_CONN_ESTABLISHED; + // fallthrough + case LINK_STATE_CONN_ESTABLISHED: + EnqueueSendCmd(sendCmd); + DequeueRecvCmds(recvCmds); + break; + } + *shouldAdvanceLinkState = 0; + retVal = gLink.localId; + retVal |= (gLink.playerCount << LINK_STAT_PLAYER_COUNT_SHIFT); + if (gLink.isMaster == LINK_MASTER) + { + retVal |= LINK_STAT_MASTER; + } + { + u32 receivedNothing = gLink.receivedNothing << LINK_STAT_RECEIVED_NOTHING_SHIFT; + u32 link_field_F = gLink.link_field_F << LINK_STAT_UNK_FLAG_9_SHIFT; + u32 hardwareError = gLink.hardwareError << LINK_STAT_ERROR_HARDWARE_SHIFT; + u32 badChecksum = gLink.badChecksum << LINK_STAT_ERROR_CHECKSUM_SHIFT; + u32 queueFull = gLink.queueFull << LINK_STAT_ERROR_QUEUE_FULL_SHIFT; + u32 val; + + if (gLink.state == LINK_STATE_CONN_ESTABLISHED) + { + val = LINK_STAT_CONN_ESTABLISHED; + val |= receivedNothing; + val |= retVal; + val |= link_field_F; + val |= hardwareError; + val |= badChecksum; + val |= queueFull; + } + else + { + val = retVal; + val |= receivedNothing; + val |= link_field_F; + val |= hardwareError; + val |= badChecksum; + val |= queueFull; + } + + retVal = val; + } + + if (gLink.lag == LAG_MASTER) + { + retVal |= LINK_STAT_ERROR_LAG_MASTER; + } + + if (gLink.localId >= MAX_LINK_PLAYERS) + { + retVal |= LINK_STAT_ERROR_INVALID_ID; + } + + retVal2 = retVal; + if (gLink.lag == LAG_SLAVE) + { + retVal2 |= LINK_STAT_ERROR_LAG_SLAVE; + } + + return retVal2; +} + +static void CheckMasterOrSlave(void) +{ + u32 terminals; + + terminals = *(vu32 *)REG_ADDR_SIOCNT & (SIO_MULTI_SD | SIO_MULTI_SI); + if (terminals == SIO_MULTI_SD && gLink.localId == 0) + { + gLink.isMaster = LINK_MASTER; + } + else + { + gLink.isMaster = LINK_SLAVE; + } +} + +static void InitTimer(void) +{ + if (gLink.isMaster) + { + REG_TM3CNT_L = -197; + REG_TM3CNT_H = TIMER_64CLK | TIMER_INTR_ENABLE; + EnableInterrupts(INTR_FLAG_TIMER3); + } +} + +static void EnqueueSendCmd(u16 *sendCmd) +{ + u8 i; + u8 offset; + + gLinkSavedIme = REG_IME; + REG_IME = 0; + if (gLink.sendQueue.count < QUEUE_CAPACITY) + { + offset = gLink.sendQueue.pos + gLink.sendQueue.count; + if (offset >= QUEUE_CAPACITY) + { + offset -= QUEUE_CAPACITY; + } + for (i = 0; i < CMD_LENGTH; i++) + { + sSendNonzeroCheck |= *sendCmd; + gLink.sendQueue.data[i][offset] = *sendCmd; + *sendCmd = 0; + sendCmd++; + } + } + else + { + gLink.queueFull = QUEUE_FULL_SEND; + } + if (sSendNonzeroCheck) + { + gLink.sendQueue.count++; + sSendNonzeroCheck = 0; + } + REG_IME = gLinkSavedIme; + gLastSendQueueCount = gLink.sendQueue.count; +} + + +static void DequeueRecvCmds(u16 (*recvCmds)[CMD_LENGTH]) +{ + u8 i; + u8 j; + + gLinkSavedIme = REG_IME; + REG_IME = 0; + if (gLink.recvQueue.count == 0) + { + for (i = 0; i < gLink.playerCount; i++) + { + for (j = 0; j < CMD_LENGTH; j++) + { + recvCmds[i][j] = 0; + } + } + + gLink.receivedNothing = TRUE; + } + else + { + for (i = 0; i < gLink.playerCount; i++) + { + for (j = 0; j < CMD_LENGTH; j++) + { + recvCmds[i][j] = gLink.recvQueue.data[i][j][gLink.recvQueue.pos]; + } + } + gLink.recvQueue.count--; + gLink.recvQueue.pos++; + if (gLink.recvQueue.pos >= QUEUE_CAPACITY) + { + gLink.recvQueue.pos = 0; + } + gLink.receivedNothing = FALSE; + } + REG_IME = gLinkSavedIme; +} + +// link_intr.c + +void LinkVSync(void) +{ + if (gLink.isMaster) + { + switch (gLink.state) + { + case LINK_STATE_CONN_ESTABLISHED: + if (gLink.serialIntrCounter < 9) + { + if (gLink.hardwareError != TRUE) + { + gLink.lag = LAG_MASTER; + } + else + { + StartTransfer(); + } + } + else if (gLink.lag != LAG_MASTER) + { + gLink.serialIntrCounter = 0; + StartTransfer(); + } + break; + case LINK_STATE_HANDSHAKE: + StartTransfer(); + break; + } + } + else if (gLink.state == LINK_STATE_CONN_ESTABLISHED || gLink.state == LINK_STATE_HANDSHAKE) + { + if (++sNumVBlanksWithoutSerialIntr > 10) + { + if (gLink.state == LINK_STATE_CONN_ESTABLISHED) + { + gLink.lag = LAG_SLAVE; + } + if (gLink.state == LINK_STATE_HANDSHAKE) + { + gLink.playerCount = 0; + gLink.link_field_F = FALSE; + } + } + } +} + +void Timer3Intr(void) +{ + StopTimer(); + StartTransfer(); +} + +void SerialCB(void) +{ + gLink.localId = SIO_MULTI_CNT->id; + switch (gLink.state) + { + case LINK_STATE_CONN_ESTABLISHED: + gLink.hardwareError = SIO_MULTI_CNT->error; + DoRecv(); + DoSend(); + SendRecvDone(); + break; + case LINK_STATE_HANDSHAKE: + if (DoHandshake()) + { + if (gLink.isMaster) + { + gLink.state = LINK_STATE_INIT_TIMER; + gLink.serialIntrCounter = 8; + } + else + { + gLink.state = LINK_STATE_CONN_ESTABLISHED; + } + } + break; + } + gLink.serialIntrCounter++; + sNumVBlanksWithoutSerialIntr = 0; + if (gLink.serialIntrCounter == 8) + { + gLastRecvQueueCount = gLink.recvQueue.count; + } +} + +static void StartTransfer(void) +{ + REG_SIOCNT |= SIO_START; +} + +static bool8 DoHandshake(void) +{ + u8 i; + u8 playerCount; + u16 minRecv; + + playerCount = 0; + minRecv = 0xFFFF; + if (gLink.handshakeAsMaster == TRUE) + { + REG_SIOMLT_SEND = MASTER_HANDSHAKE; + } + else + { + REG_SIOMLT_SEND = SLAVE_HANDSHAKE; + } + *(u64 *)gLink.tempRecvBuffer = REG_SIOMLT_RECV; + REG_SIOMLT_RECV = 0; + gLink.handshakeAsMaster = FALSE; + for (i = 0; i < 4; i++) + { + if ((gLink.tempRecvBuffer[i] & ~0x3) == SLAVE_HANDSHAKE || gLink.tempRecvBuffer[i] == MASTER_HANDSHAKE) + { + playerCount++; + if (minRecv > gLink.tempRecvBuffer[i] && gLink.tempRecvBuffer[i] != 0) + { + minRecv = gLink.tempRecvBuffer[i]; + } + } + else + { + if (gLink.tempRecvBuffer[i] != 0xFFFF) + { + playerCount = 0; + } + break; + } + } + gLink.playerCount = playerCount; + if (gLink.playerCount > 1 && gLink.playerCount == sHandshakePlayerCount && gLink.tempRecvBuffer[0] == MASTER_HANDSHAKE) + { + return TRUE; + } + if (gLink.playerCount > 1) + { + gLink.link_field_F = (minRecv & 3) + 1; + } + else + { + gLink.link_field_F = 0; + } + sHandshakePlayerCount = gLink.playerCount; + return FALSE; +} + +static void DoRecv(void) +{ + u16 recv[4]; + u8 i; + u8 index; + + *(u64 *)recv = REG_SIOMLT_RECV; + if (gLink.sendCmdIndex == 0) + { + for (i = 0; i < gLink.playerCount; i++) + { + if (gLink.checksum != recv[i] && sChecksumAvailable) + { + gLink.badChecksum = TRUE; + } + } + gLink.checksum = 0; + sChecksumAvailable = TRUE; + } + else + { + index = gLink.recvQueue.pos + gLink.recvQueue.count; + if (index >= QUEUE_CAPACITY) + { + index -= QUEUE_CAPACITY; + } + if (gLink.recvQueue.count < QUEUE_CAPACITY) + { + for (i = 0; i < gLink.playerCount; i++) + { + gLink.checksum += recv[i]; + sRecvNonzeroCheck |= recv[i]; + gLink.recvQueue.data[i][gLink.recvCmdIndex][index] = recv[i]; + } + } + else + { + gLink.queueFull = QUEUE_FULL_RECV; + } + gLink.recvCmdIndex++; + if (gLink.recvCmdIndex == CMD_LENGTH && sRecvNonzeroCheck) + { + gLink.recvQueue.count++; + sRecvNonzeroCheck = 0; + } + } +} + +static void DoSend(void) +{ + if (gLink.sendCmdIndex == CMD_LENGTH) + { + REG_SIOMLT_SEND = gLink.checksum; + if (!sSendBufferEmpty) + { + gLink.sendQueue.count--; + gLink.sendQueue.pos++; + if (gLink.sendQueue.pos >= QUEUE_CAPACITY) + { + gLink.sendQueue.pos = 0; + } + } + else + { + sSendBufferEmpty = FALSE; + } + } + else + { + if (!sSendBufferEmpty && gLink.sendQueue.count == 0) + { + sSendBufferEmpty = TRUE; + } + if (sSendBufferEmpty) + { + REG_SIOMLT_SEND = 0; + } + else + { + REG_SIOMLT_SEND = gLink.sendQueue.data[gLink.sendCmdIndex][gLink.sendQueue.pos]; + } + gLink.sendCmdIndex++; + } +} + +static void StopTimer(void) +{ + if (gLink.isMaster) + { + REG_TM3CNT_H &= ~TIMER_ENABLE; + REG_TM3CNT_L = -197; + } +} + +static void SendRecvDone(void) +{ + if (gLink.recvCmdIndex == CMD_LENGTH) + { + gLink.sendCmdIndex = 0; + gLink.recvCmdIndex = 0; + } + else if (gLink.isMaster) + { + REG_TM3CNT_H |= TIMER_ENABLE; + } +} + +void ResetSendBuffer(void) +{ + u8 i; + u8 j; + + gLink.sendQueue.count = 0; + gLink.sendQueue.pos = 0; + for (i = 0; i < CMD_LENGTH; i++) + { + for (j = 0; j < QUEUE_CAPACITY; j++) + { + gLink.sendQueue.data[i][j] = 0xEFFF; + } + } +} + +void ResetRecvBuffer(void) +{ + u8 i; + u8 j; + u8 k; + + gLink.recvQueue.count = 0; + gLink.recvQueue.pos = 0; + for (i = 0; i < MAX_LINK_PLAYERS; i++) + { + for (j = 0; j < CMD_LENGTH; j++) + { + for (k = 0; k < QUEUE_CAPACITY; k++) + { + gLink.recvQueue.data[i][j][k] = 0xEFFF; + } + } + } +} diff --git a/src/link_rfu.c b/src/link_rfu.c new file mode 100644 index 000000000..186d54fd3 --- /dev/null +++ b/src/link_rfu.c @@ -0,0 +1,4940 @@ + +// Includes +#include "global.h" +#include "malloc.h" +#include "battle.h" +#include "berry_blender.h" +#include "task.h" +#include "random.h" +#include "decompress.h" +#include "text.h" +#include "string_util.h" +#include "event_data.h" +#include "overworld.h" +#include "link.h" +#include "librfu.h" +#include "rom_8011DC0.h" +#include "link_rfu.h" + +// Static type declarations + +// Static RAM declarations + +struct UnkRfuStruct_1 gUnknown_03004140; +struct UnkRfuStruct_2 gUnknown_03005000; + +IWRAM_DATA u8 gUnknown_03000D74; +ALIGNED(4) IWRAM_DATA u8 gUnknown_03000D78[8]; +IWRAM_DATA u8 gUnknown_03000D80[16]; +IWRAM_DATA u16 gUnknown_03000D90[8]; + +EWRAM_DATA u8 gWirelessStatusIndicatorSpriteId = 0; +EWRAM_DATA ALIGNED(4) struct UnkLinkRfuStruct_02022B14 gUnknown_02022B14 = {}; +EWRAM_DATA ALIGNED(2) u8 gUnknown_02022B22[8] = {}; +EWRAM_DATA struct UnkLinkRfuStruct_02022B2C gUnknown_02022B2C = {}; +EWRAM_DATA struct UnkLinkRfuStruct_02022B44 gUnknown_02022B44 = {}; + +// Static ROM declarations + +static void sub_800C000(void); +static void sub_800C7B4(u16 r8, u16 r6); +static void sub_800C744(u32 a0); +static void sub_800CEB0(u16 r6); +static void sub_800CF34(void); +static void sub_800D158(void); +static void sub_800D20C(void); +static void sub_800D268(void); +static u8 sub_800D294(void); +static void sub_800D30C(u8 a0, u8 a1); +static void sub_800D334(u8 a0); +static void sub_800D358(u8 a0); +static void sub_800D434(void); +static void sub_800D610(void); +void sub_800D630(void); +static bool8 sub_800DAC8(struct UnkRfuStruct_2_Sub_c1c *q1, u8 *q2); +static void sub_800EAB4(void); +static void sub_800EAFC(void); +void sub_800ED34(u16 unused); +static void sub_800EDBC(u16 unused); +static void sub_800F048(void); +static void sub_800F86C(u8 unused); +static void sub_800FCC4(struct UnkRfuStruct_2_Sub_6c *data); +void sub_800FD14(u16 command); +static void rfufunc_80F9F44(void); +static void sub_800FFB0(void); +static void rfufunc_80FA020(void); +bool32 sub_8010454(u32 a0); +static void sub_8010528(void); +void sub_8010750(void); +int sub_80107A0(void); +void sub_801084C(u8 taskId); +void sub_80109E8(u16 a0); +void sub_8010A70(void *a0); +void sub_8010AAC(u8 taskId); +void sub_8010D0C(u8 taskId); +void sub_80115EC(u16 a0); +u8 sub_8011CE4(const u8 *a0, u16 a1); +void sub_8011D6C(u8 a0); +void sub_8011E94(u8 a0, u8 a1); +u8 sub_8012224(void); +void sub_801227C(void); + +// .rodata + +const u16 gWirelessLinkIconPalette[] = INCBIN_U16("graphics/interface/wireless_link_icon.gbapal"); +const u8 gWirelessLinkIconPic[] = INCBIN_U8("graphics/interface/wireless_link_icon.4bpp.lz"); +const u8 sWireless_ASCIItoRSETable[] = { + 0xff, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x00, 0xab, 0xb5, 0xb6, 0xb1, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xb2, 0xf1, 0x00, 0xae, 0xad, 0xba, + 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, + 0xa9, 0xaa, 0x00, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0x00, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, + 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, + 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, + 0xd2, 0xd3, 0xd4, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, + 0x00, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, + 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, + 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, + 0xec, 0xed, 0xee, 0x2d, 0x2f, 0x30, 0x31, 0x32, + 0x33, 0x34, 0x35, 0x36, 0x50, 0x00, 0x01, 0x02, + 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, + 0x1b, 0xad, 0xb3, 0xb4, 0x00, 0xaf, 0x7d, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0xa0, + 0xae, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7e, 0xb0, 0xac, + 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2e, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, + 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94 +}; +const u8 sWireless_RSEtoASCIITable[] = { + 0x20, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, + 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, + 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, + 0x9d, 0x9e, 0x9f, 0xa0, 0xe0, 0xe1, 0xe2, 0xe3, + 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, + 0xec, 0xed, 0xee, 0xef, 0xf0, 0x7b, 0xf1, 0x7c, + 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x84, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xa6, 0xdd, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xf2, + 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, + 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0xaf, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, + 0x37, 0x38, 0x39, 0x21, 0xdf, 0xa1, 0xb0, 0xa5, + 0xde, 0x24, 0x2a, 0xa2, 0xa3, 0x22, 0x23, 0x20, + 0xa4, 0x20, 0x2f, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, + 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, + 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, + 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, + 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x20, + 0x20, 0x2b, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00 +}; +const struct OamData sWirelessStatusIndicatorOamData = { + .size = 1 +}; +static const union AnimCmd sWirelessStatusIndicatorAnim0[] = { + // 3 bars + ANIMCMD_FRAME( 4, 5), + ANIMCMD_FRAME( 8, 5), + ANIMCMD_FRAME(12, 5), + ANIMCMD_FRAME(16, 10), + ANIMCMD_FRAME(12, 5), + ANIMCMD_FRAME( 8, 5), + ANIMCMD_JUMP(0) +}; +static const union AnimCmd sWirelessStatusIndicatorAnim1[] = { + // 2 bars + ANIMCMD_FRAME( 4, 5), + ANIMCMD_FRAME( 8, 5), + ANIMCMD_FRAME(12, 10), + ANIMCMD_FRAME( 8, 5), + ANIMCMD_JUMP(0) +}; +static const union AnimCmd sWirelessStatusIndicatorAnim2[] = { + // 1 bar + ANIMCMD_FRAME(4, 5), + ANIMCMD_FRAME(8, 5), + ANIMCMD_JUMP(0) +}; +static const union AnimCmd sWirelessStatusIndicatorAnim3[] = { + // searching + ANIMCMD_FRAME( 4, 10), + ANIMCMD_FRAME(20, 10), + ANIMCMD_JUMP(0) +}; +static const union AnimCmd sWirelessStatusIndicatorAnim4[] = { + // error + ANIMCMD_FRAME(24, 10), + ANIMCMD_FRAME( 4, 10), + ANIMCMD_JUMP(0) +}; +static const union AnimCmd *const sWirelessStatusIndicatorAnims[] = { + sWirelessStatusIndicatorAnim0, + sWirelessStatusIndicatorAnim1, + sWirelessStatusIndicatorAnim2, + sWirelessStatusIndicatorAnim3, + sWirelessStatusIndicatorAnim4 +}; +const struct CompressedSpriteSheet sWirelessStatusIndicatorSpriteSheet = { + gWirelessLinkIconPic, 0x0380, 0xD431 +}; +const struct SpritePalette sWirelessStatusIndicatorSpritePalette = { + gWirelessLinkIconPalette, 0xD432 +}; +static const struct SpriteTemplate sWirelessStatusIndicatorSpriteTemplate = { + 0xD431, + 0xD432, + &sWirelessStatusIndicatorOamData, + sWirelessStatusIndicatorAnims, + NULL, + gDummySpriteAffineAnimTable, + SpriteCallbackDummy +}; + +const struct UnkLinkRfuStruct_02022B2C gUnknown_082ED608 = { + 0x04, 0x20, 0x00, 0x00, 0x02, + &gUnknown_02022B14, + gUnknown_02022B22, + 0x01, 0x00, 0x258, 0x12c +}; +const u8 gUnknown_082ED620[] = { + 0, 3, 2, 1, 0 +}; +const u32 gUnknown_082ED628[] = { + 0x000000, + 0x000001, + 0x000003, + 0x000007, + 0x00000f, + 0x00001f, + 0x00003f, + 0x00007f, + 0x0000ff, + 0x0001ff, + 0x0003ff, + 0x0007ff, + 0x000fff, + 0x001fff, + 0x003fff, + 0x007fff, + 0x00ffff, + 0x01ffff, + 0x03ffff, + 0x07ffff, + 0x0fffff, + 0x1fffff, + 0x3fffff, + 0x7fffff, + 0xffffff +}; +const u8 gUnknown_082ED68C[] = { + 0, 0, 1, + 1, 2, 2, + 2, 2, 3 +}; +const u8 gUnknown_082ED695[] = { + 0, 1, 1, 2, + 1, 2, 2, 3, + 1, 2, 2, 3, + 2, 3, 3, 4 +}; +const u8 gUnknown_082ED6A5[] = { + 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 +}; +const struct { + u8 *buffer; + u32 size; +} gUnknown_082ED6B8[] = { + { gBlockSendBuffer, 200 }, + { gBlockSendBuffer, 200 }, + { gBlockSendBuffer, 100 }, + { gBlockSendBuffer, 220 }, + { gBlockSendBuffer, 40 } +}; +const u16 gUnknown_082ED6E0[] = { + 0x0002, 0x7f7d, 0x0000, 0xffff +}; + +const char sUnref_082ED6E8[][15] = { + "RFU WAIT", + "RFU BOOT", + "RFU ERROR", + "RFU RESET", + "RFU CONFIG", + "RFU START", + "RFU SC POLL", + "RFU SP POLL", + "RFU START", + "RFU SEND ERR", + "RFU CP POLL" +}; +const char sUnref_082ED6E9[][16] = { + " ", + "RECOVER START ", + "DISSCONECT ", + "RECOVER SUUSES", + "RECOVER FAILED" +}; +const TaskFunc gUnknown_082ED7E0[] = { + sub_801084C, + sub_8010AAC, + sub_8010D0C +}; +const char gUnknown_082ED7EC[] = "PokemonSioInfo"; +const char gUnknown_082ED7FC[] = "LINK LOSS DISCONNECT!"; +const char gUnknown_082ED814[] = "LINK LOSS RECOVERY NOW"; + +// .text + +u32 sub_800BEC0(void) +{ + u32 r4; + + r4 = rfu_REQBN_softReset_and_checkID(); + if (r4 == 0x8001) + { + gUnknown_03004140.unk_08 = 1; + } + if (gUnknown_03004140.unk_04 != 0x17 && gUnknown_03004140.unk_04 != 0x01) + { + gUnknown_03004140.unk_05 = 0; + gUnknown_03004140.unk_04 = 0; + } + gUnknown_03004140.unk_07 = 0; + gUnknown_03004140.unk_0d = 0; + gUnknown_03004140.unk_01 = 0; + gUnknown_03004140.unk_00 = 0; + gUnknown_03004140.unk_06 = -1; + sub_800D610(); + return r4; +} + +void rfu_REQ_sendData_wrapper(u8 r2) +{ + u8 val; + if (!gUnknown_03007890->unk_00) + { + val = gUnknown_03004140.unk_02; + r2 = 0; + if (val == 1) + { + r2 = 1; + } + } + else + { + gUnknown_03004140.unk_03 = 0; + } + rfu_REQ_sendData(r2); +} + +int sub_800BF4C(void (*func1)(u8, u8), void (*func2)(u16)) +{ + if (func1 == NULL) + { + return 4; + } + CpuFill16(0, &gUnknown_03004140, offsetof(struct UnkRfuStruct_1, filler_48)); + gUnknown_03004140.unk_06 = -1; + gUnknown_03004140.unk_40 = func1; + gUnknown_03004140.unk_44 = func2; + rfu_setMSCCallback(sub_800CEB0); + rfu_setREQCallback(sub_800C7B4); + return 0; +} + +void sub_800BFA0(void) +{ + CpuFill16(0, &gUnknown_03004140, offsetof(struct UnkRfuStruct_1, unk_40)); + gUnknown_03004140.unk_06 = -1; +} + +void sub_800BFCC(const struct UnkLinkRfuStruct_02022B2C *unk0) +{ + sub_800C000(); + gUnknown_03004140.unk_04 = 1; + gUnknown_03004140.unk_05 = 2; + gUnknown_03004140.unk_3c = unk0; + gUnknown_03004140.unk_09 = unk0->unk_11; + gUnknown_03004140.unk_32 = unk0->unk_12; + gUnknown_03004140.unk_18 = unk0->unk_14; + if (unk0->unk_10) + { + gUnknown_03004140.unk_0b = 1; + } +} + +static void sub_800C000(void) +{ + u8 i; + + gUnknown_03004140.unk_05 = 0; + gUnknown_03004140.unk_04 = 0; + gUnknown_03004140.unk_06 = -1; + gUnknown_03004140.unk_07 = 0; + gUnknown_03004140.unk_10 = 0; + gUnknown_03004140.unk_0c = 0; + gUnknown_03004140.unk_24 = 0; + gUnknown_03004140.unk_30 = 0; + for (i = 0; i < 4; i++) + { + gUnknown_03004140.unk_28[i] = 0; + gUnknown_03004140.unk_34[i] = 0; + } +} + +void sub_800C048(void) +{ + gUnknown_03004140.unk_04 = 0x15; +} + +u8 sub_800C054(u8 r5, u16 r7, u16 r8, const u16 *r6) +{ + u8 i; + const u16 *buffer; + + if (gUnknown_03004140.unk_04 != 0 && (gUnknown_03004140.unk_04 != 0x08 || r5 != 1)) + { + gUnknown_03004140.unk_14 = 1; + sub_800D30C(0xf3, 0x01); + return 1; + } + if (!rfu_getMasterSlave()) + { + gUnknown_03004140.unk_14 = 2; + sub_800D30C(0xf3, 0x01); + return 2; + } + for (i = 0, buffer = r6; i < 16; i++) + { + if (*buffer++ == 0xFFFF) + { + break; + } + } + if (i == 16) + { + gUnknown_03004140.unk_14 = 4; + sub_800D30C(0xf3, 0x01); + return 4; + } + if (r5 > 1) + { + gUnknown_03004140.unk_07 = 1; + r5 = 1; + r7 = 0; + } + else + { + gUnknown_03004140.unk_07 = 0; + } + if (r5 != 0) + { + gUnknown_03004140.unk_04 = 5; + } + else + { + gUnknown_03004140.unk_04 = 9; + if (gUnknown_03004140.unk_0b) + { + gUnknown_03004140.unk_0b = 2; + } + } + gUnknown_03004140.unk_06 = r5; + gUnknown_03004140.unk_1a = r7; + gUnknown_03004140.unk_26 = r8; + gUnknown_03004140.unk_20 = r6; + return 0; +} + +u8 sub_800C12C(u16 r6, u16 r8) +{ + u8 i; + struct RfuUnk5 *tmp; + + if (gUnknown_03004140.unk_04 != 0 && (gUnknown_03004140.unk_04 < 9 || gUnknown_03004140.unk_04 > 11)) + { + gUnknown_03004140.unk_14 = 1; + sub_800D30C(0xF3, 0x01); + return 1; + } + if (!rfu_getMasterSlave()) + { + gUnknown_03004140.unk_14 = 2; + sub_800D30C(0xF3, 0x01); + return 2; + } + for (i = 0; i < gUnknown_03007890->unk_08; i++) + { + if (gUnknown_03007890->unk_14[i].unk_00 == r6) + { + break; + } + } + if (gUnknown_03007890->unk_08 == 0 || i == gUnknown_03007890->unk_08) + { + gUnknown_03004140.unk_14 = 3; + sub_800D30C(0xF3, 0x01); + return 3; + } + if (gUnknown_03004140.unk_04 == 0 || gUnknown_03004140.unk_04 == 9) + { + gUnknown_03004140.unk_04 = 12; + gUnknown_03004140.unk_05 = 13; + } + else + { + gUnknown_03004140.unk_04 = 11; + gUnknown_03004140.unk_05 = 12; + } + gUnknown_03004140.unk_1e = r6; + gUnknown_03004140.unk_1a = r8; + if (gUnknown_03004140.unk_07 != 0) + { + gUnknown_03004140.unk_07 = 7; + } + return 0; +} + +void sub_800C210(u8 a0) +{ + u8 i; + + if (a0 & gUnknown_03004140.unk_30) + { + gUnknown_03004140.unk_30 &= ~a0; + for (i = 0; i < 4; i++) + { + if ((a0 >> i) & 1) + { + gUnknown_03004140.unk_34[i] = 0; + } + } + i = gUnknown_03007890->unk_03 & a0; + if (i) + { + sub_800D334(i); + } + gUnknown_03004140.unk_14 = i; + sub_800D30C(0x33, i); + } +} + +void sub_800C27C(bool8 a0) +{ + u8 r2; + + r2 = 0; + gUnknown_03004140.unk_07 = 0; + if (a0) + { + sub_800C000(); + gUnknown_03004140.unk_04 = 23; + } + else + { + switch (gUnknown_03004140.unk_04) + { + case 5: + gUnknown_03004140.unk_04 = 8; + gUnknown_03004140.unk_05 = 0; + r2 = 0x13; + break; + case 6: + gUnknown_03004140.unk_04 = 7; + gUnknown_03004140.unk_05 = 8; + break; + case 7: + gUnknown_03004140.unk_04 = 7; + gUnknown_03004140.unk_05 = 8; + break; + case 8: + break; + case 9: + gUnknown_03004140.unk_05 = 0; + gUnknown_03004140.unk_04 = 0; + r2 = 0x21; + break; + case 10: + gUnknown_03004140.unk_04 = 11; + gUnknown_03004140.unk_05 = 0; + break; + case 11: + gUnknown_03004140.unk_04 = 11; + gUnknown_03004140.unk_05 = 0; + break; + case 12: + gUnknown_03004140.unk_05 = 0; + gUnknown_03004140.unk_04 = 0; + r2 = 0x23; + break; + case 13: + gUnknown_03004140.unk_04 = 14; + break; + case 14: + gUnknown_03004140.unk_04 = 14; + break; + case 15: + break; + case 16: + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_11; + gUnknown_03004140.unk_05 = gUnknown_03004140.unk_12; + sub_800D334(gUnknown_03007890->unk_03); + gUnknown_03004140.unk_14 = gUnknown_03007890->unk_03; + sub_800D30C(0x33, 0x01); + return; + case 17: + gUnknown_03004140.unk_04 = 18; + break; + case 18: + gUnknown_03004140.unk_04 = 18; + break; + default: + gUnknown_03004140.unk_05 = 0; + gUnknown_03004140.unk_04 = 0; + r2 = 0x43; + break; + } + if (gUnknown_03004140.unk_04 == 0) + { + sub_800D30C(r2, 0); + } + } +} + +bool8 sub_800C36C(u16 a0) +{ + bool8 retVal; + u8 i; + u8 sp0; + u8 sp1; + u8 sp2; + u8 flags; + + retVal = FALSE; + rfu_REQBN_watchLink(a0, &sp0, &sp1, &sp2); + if (sp0) + { + gUnknown_03004140.unk_14 = sp0; + gUnknown_03004140.unk_16 = sp1; + if (gUnknown_03004140.unk_09) + { + gUnknown_03004140.unk_0a = 1; + if (gUnknown_03004140.unk_06 == 0 && sp1 == 0) + { + gUnknown_03004140.unk_0a = 4; + } + if (gUnknown_03004140.unk_0a == 1) + { + for (i = 0; i < 4; i++) + { + if ((sp0 >> i) & 1) + { + gUnknown_03004140.unk_30 |= (1 << i); + gUnknown_03004140.unk_34[i] = gUnknown_03004140.unk_32; + } + } + sub_800D30C(0x31, 0x01); + } + else + { + gUnknown_03004140.unk_0a = 0; + sub_800D334(sp0); + retVal = TRUE; + sub_800D30C(0x33, 0x01); + } + } + else + { + sub_800D334(sp0); + retVal = TRUE; + sub_800D30C(0x30, 0x02); + } + sub_800D610(); + } + if (gUnknown_03007890->unk_00 == 1) + { + if (sp2) + { + for (i = 0; i < 4; i++) + { + if ((gUnknown_03004140.unk_30 >> i) & 1 && (sp2 >> i) & 1) + { + gUnknown_03004140.unk_34[i] = 0; + } + } + gUnknown_03004140.unk_30 &= ~sp2; + gUnknown_03004140.unk_14 = sp2; + sub_800D30C(0x32, 0x01); + } + if (gUnknown_03004140.unk_30) + { + flags = 0; + for (i = 0; i < 4; i++) + { + if ((gUnknown_03004140.unk_30 >> i) & 1 && gUnknown_03004140.unk_34[i] && --gUnknown_03004140.unk_34[i] == 0) + { + gUnknown_03004140.unk_30 &= ~(1 << i); + flags |= (1 << i); + } + } + if (flags) + { + sub_800D334(flags); + retVal = TRUE; + gUnknown_03004140.unk_14 = flags; + sub_800D30C(0x33, 0x01); + } + } + if (!gUnknown_03004140.unk_30) + { + gUnknown_03004140.unk_0a = 0; + } + } + return retVal; +} + +void rfu_syncVBlank_(void) +{ + if (rfu_syncVBlank()) + { + sub_800D30C(0xF1, 0x00); + sub_800D610(); + } +} + +void sub_800C54C(u32 a0) +{ + u8 r2; + + if (gUnknown_03004140.unk_40 == NULL && gUnknown_03004140.unk_04 != 0) + { + gUnknown_03004140.unk_04 = 0; + } + else + { + if (gUnknown_03004140.unk_07 != 0) + { + sub_800C744(a0); + } + do + { + if (gUnknown_03004140.unk_04 != 0) + { + rfu_waitREQComplete(); + gUnknown_03004140.unk_0e = 1; + switch (gUnknown_03004140.unk_04) + { + case 23: + r2 = sub_800BEC0() == 0x8001 ? 0x44 : 0xFF; + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0; + sub_800D30C(r2, 0); + break; + case 1: + if (sub_800BEC0() == 0x8001) + { + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05; + gUnknown_03004140.unk_05 = 3; + } + else + { + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0; + sub_800D30C(0xFF, 0); + } + break; + case 2: + rfu_REQ_reset(); + break; + case 3: + rfu_REQ_configSystem(gUnknown_03004140.unk_3c->unk_02, gUnknown_03004140.unk_3c->unk_00, gUnknown_03004140.unk_3c->unk_01); + break; + case 4: + rfu_REQ_configGameData(gUnknown_03004140.unk_3c->unk_04, gUnknown_03004140.unk_3c->unk_06, gUnknown_03004140.unk_3c->unk_08, gUnknown_03004140.unk_3c->unk_0c); + break; + case 5: + rfu_REQ_startSearchChild(); + break; + case 6: + rfu_REQ_pollSearchChild(); + break; + case 7: + rfu_REQ_endSearchChild(); + break; + case 8: + break; + case 9: + rfu_REQ_startSearchParent(); + break; + case 10: + rfu_REQ_pollSearchParent(); + break; + case 11: + rfu_REQ_endSearchParent(); + break; + case 12: + rfu_REQ_startConnectParent(gUnknown_03004140.unk_1e); + break; + case 13: + rfu_REQ_pollConnectParent(); + break; + case 14: + rfu_REQ_endConnectParent(); + break; + case 15: + break; + case 16: + rfu_REQ_CHILD_startConnectRecovery(gUnknown_03007890->unk_03); + break; + case 17: + rfu_REQ_CHILD_pollConnectRecovery(); + break; + case 18: + rfu_REQ_CHILD_endConnectRecovery(); + break; + case 19: + rfu_REQ_changeMasterSlave(); + break; + case 20: + break; + case 21: + rfu_REQ_stopMode(); + break; + case 22: + break; + } + rfu_waitREQComplete(); + gUnknown_03004140.unk_0e = 0; + } + } while (gUnknown_03004140.unk_04 == 18 || gUnknown_03004140.unk_04 == 19); + if (gUnknown_03007890->unk_00 != 1 || !sub_800C36C(0)) + { + sub_800CF34(); + sub_800D158(); + sub_800D268(); + sub_800D434(); + } + } +} + +static void sub_800C744(u32 a0) +{ + if (gUnknown_03004140.unk_07 == 5) + { + gUnknown_03004140.unk_06 = 1; + gUnknown_03004140.unk_04 = 5; + gUnknown_03004140.unk_1a = gUnknown_03004140.unk_1c; + if (gUnknown_03004140.unk_1a) + { + gUnknown_03004140.unk_07 = 6; + } + else + { + gUnknown_03004140.unk_07 = 1; + } + } + if (gUnknown_03004140.unk_07 == 1) + { + gUnknown_03004140.unk_06 = 1; + gUnknown_03004140.unk_04 = 5; + gUnknown_03004140.unk_1a = a0 % 140; + gUnknown_03004140.unk_1c = 140 - gUnknown_03004140.unk_1a; + if (gUnknown_03004140.unk_1a) + { + gUnknown_03004140.unk_07 = 2; + } + else + { + gUnknown_03004140.unk_07 = 3; + } + } + if (gUnknown_03004140.unk_07 == 3) + { + gUnknown_03004140.unk_06 = 0; + gUnknown_03004140.unk_1a = 40; + gUnknown_03004140.unk_07 = 4; + gUnknown_03004140.unk_04 = 9; + } +} + +static void sub_800C7B4(u16 r8, u16 r6) +{ + u8 sp0; + register u8 *stwiRecvBuffer asm("r0"); + u8 *tmp; + u8 i; + + if (gUnknown_03004140.unk_0e != 0) + { + gUnknown_03004140.unk_0e = 0; + switch (r8) + { + case 16: + if (r6 == 0) + { + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05; + gUnknown_03004140.unk_05 = 4; + } + break; + case 23: + if (r6 == 0) + { + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05; + gUnknown_03004140.unk_05 = 0; + } + break; + case 22: + if (r6 == 0) + { + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0; + sub_800D30C(0x00, 0x00); + } + break; + case 25: + if (r6 == 0) + { + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 6; + } + break; + case 26: + if (gUnknown_03004140.unk_1a && --gUnknown_03004140.unk_1a == 0) + { + gUnknown_03004140.unk_04 = 7; + gUnknown_03004140.unk_05 = 8; + } + break; + case 27: + if (r6 == 0) + { + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05; + gUnknown_03004140.unk_05 = 0; + if (gUnknown_03004140.unk_07 == 0) + { + sub_800D30C(0x13, 0x00); + } + } + break; + case 28: + if (r6 == 0) + { + if (gUnknown_03004140.unk_0b == 1 && gUnknown_03004140.unk_1a > 1) + { + gUnknown_03004140.unk_1a--; + } + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 10; + } + break; + case 29: + if (r6 == 0) + { + sp0 = sub_800D294(); + gUnknown_03004140.unk_14 = sp0; + if (sp0) + { + sub_800D30C(0x20, 0x01); + } + if (gUnknown_03004140.unk_0b && gUnknown_03004140.unk_1a != 1 && gUnknown_03007890->unk_08 == 4) + { + rfu_REQ_endSearchParent(); + rfu_waitREQComplete(); + gUnknown_03004140.unk_04 = 9; + gUnknown_03004140.unk_0b = 1; + } + } + if (gUnknown_03004140.unk_1a && --gUnknown_03004140.unk_1a == 0) + { + gUnknown_03004140.unk_04 = 11; + gUnknown_03004140.unk_05 = 0; + } + break; + case 30: + if (r6 == 0) + { + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05; + if (gUnknown_03004140.unk_07 == 0) + { + if (gUnknown_03004140.unk_04 == 0) + { + sub_800D30C(0x21, 0x00); + } + } + else if (gUnknown_03004140.unk_07 != 7) + { + gUnknown_03004140.unk_04 = 5; + gUnknown_03004140.unk_07 = 5; + } + } + break; + case 31: + if (r6 == 0) + { + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 13; + } + break; + case 32: + if (r6 == 0 && !rfu_getConnectParentStatus(&sp0, &gUnknown_03004140.unk_10) && !sp0) + { + gUnknown_03004140.unk_04 = 14; + } + if (gUnknown_03004140.unk_1a && --gUnknown_03004140.unk_1a == 0) + { + gUnknown_03004140.unk_04 = 14; + } + break; + case 33: + if (r6 == 0 && !rfu_getConnectParentStatus(&sp0, &gUnknown_03004140.unk_10)) + { + if (!sp0) + { + gUnknown_03004140.unk_04 = 19; + gUnknown_03004140.unk_05 = 15; + gUnknown_03004140.unk_1e = 0x22; + gUnknown_03004140.unk_14 = gUnknown_03004140.unk_10; + } + else + { + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0; + gUnknown_03004140.unk_1e = 0x23; + gUnknown_03004140.unk_14 = sp0; + if (gUnknown_03004140.unk_07) + { + gUnknown_03004140.unk_07 = 3; + gUnknown_03004140.unk_04 = 9; + } + } + sub_800D30C(gUnknown_03004140.unk_1e, 0x01); + gUnknown_03004140.unk_1e = 0; + } + break; + case 50: + if (r6 == 0) + { + gUnknown_03004140.unk_14 = gUnknown_03007890->unk_03; + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 17; + for (gUnknown_03004140.unk_10 = 0; gUnknown_03004140.unk_10 < 4; gUnknown_03004140.unk_10 ++) + { + if ((gUnknown_03007890->unk_03 >> gUnknown_03004140.unk_10) & 1) + { + break; + } + } + } + break; + case 51: + if (r6 == 0 && !rfu_CHILD_getConnectRecoveryStatus(&sp0) && sp0 < 2) + { + gUnknown_03004140.unk_04 = 18; + } + if (gUnknown_03004140.unk_34[gUnknown_03004140.unk_10] && --gUnknown_03004140.unk_34[gUnknown_03004140.unk_10] == 0) + { + gUnknown_03004140.unk_04 = 18; + } + break; + case 52: + if (r6 == 0 && !rfu_CHILD_getConnectRecoveryStatus(&sp0)) + { + if (!sp0) + { + gUnknown_03004140.unk_04 = 19; + gUnknown_03004140.unk_05 = 22; + gUnknown_03004140.unk_1e = 0x32; + } + else + { + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0; + sub_800D334(gUnknown_03007890->unk_03); + gUnknown_03004140.unk_1e = 0x33; + } + gUnknown_03004140.unk_34[gUnknown_03004140.unk_10] = 0; + gUnknown_03004140.unk_30 = 0; + gUnknown_03004140.unk_0a = 0; + sub_800D30C(gUnknown_03004140.unk_1e, 0x01); + gUnknown_03004140.unk_1e = 0; + } + break; + case 39: + if (r6 == 0) + { + if (gUnknown_03004140.unk_05 == 22) + { + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_11; + gUnknown_03004140.unk_05 = gUnknown_03004140.unk_12; + gUnknown_03004140.unk_02 = 1; + sub_800D30C(0x41, 0x00); + } + else if (gUnknown_03004140.unk_05 == 15) + { + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05; + gUnknown_03004140.unk_02 = 1; + sub_800D30C(0x41, 0x00); + gUnknown_03004140.unk_24 |= 1 << gUnknown_03004140.unk_10; + gUnknown_03004140.unk_28[gUnknown_03004140.unk_10] = gUnknown_03004140.unk_26; + rfu_clearSlot(4, gUnknown_03004140.unk_10); + tmp = &sp0; + *tmp = rfu_NI_CHILD_setSendGameName(gUnknown_03004140.unk_10, 0x0e); + if (*tmp) + { + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0; + sub_800D610(); + sub_800D334(gUnknown_03007890->unk_02 | gUnknown_03007890->unk_03); + gUnknown_03004140.unk_14 = sp0; + sub_800D30C(0x25, 0x01); + } + } + } + break; + case 61: + if (r6 == 0) + { + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0; + sub_800D30C(0x42, 0x00); + } + break; + } + gUnknown_03004140.unk_0e = 1; + } + else if (r6 == 3 && gUnknown_03004140.unk_0f && (r8 == 0x24 || r8 == 0x26 || r8 == 0x27)) + { + rfu_REQ_RFUStatus(); + rfu_waitREQComplete(); + rfu_getRFUStatus(&sp0); + if (sp0 == 0 && gUnknown_03007890->unk_00 == 0) + { + stwiRecvBuffer = rfu_getSTWIRecvBuffer(); + stwiRecvBuffer[4] = gUnknown_03007890->unk_02; + stwiRecvBuffer[5] = 1; + sub_800C36C(0x29); + r6 = 0; + } + } + switch (r8) + { + case 48: + if (r6 == 0) + { + stwiRecvBuffer = rfu_getSTWIRecvBuffer(); + gUnknown_03004140.unk_14 = stwiRecvBuffer[8]; + sub_800D358(gUnknown_03004140.unk_14); + if (gUnknown_03004140.unk_30) + { + gUnknown_03004140.unk_30 &= ~gUnknown_03004140.unk_14; + for (i = 0; i < 4; i++) + { + if ((gUnknown_03004140.unk_14 >> i) & 1) + { + gUnknown_03004140.unk_34[i] = 0; + } + } + if (gUnknown_03004140.unk_06 == 0) + { + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0; + } + } + sp0 = gUnknown_03004140.unk_00 & gUnknown_03004140.unk_14; + for (i = 0; i < 4; i++) + { + if ((sp0 >> i) & 1 && gUnknown_03004140.unk_01) + { + gUnknown_03004140.unk_01--; + } + } + gUnknown_03004140.unk_00 &= ~gUnknown_03004140.unk_14; + if (gUnknown_03004140.unk_07) + { + if (gUnknown_03007890->unk_00 == 0xFF) + { + if (gUnknown_03004140.unk_07 == 8) + { + gUnknown_03004140.unk_1a = gUnknown_03004140.unk_1c; + gUnknown_03004140.unk_07 = 6; + gUnknown_03004140.unk_04 = 6; + } + else if (gUnknown_03004140.unk_04 != 6 && gUnknown_03004140.unk_04 != 7) + { + gUnknown_03004140.unk_07 = 1; + gUnknown_03004140.unk_04 = 5; + } + } + } + if (gUnknown_03007890->unk_00 == 0xFF) + { + if (gUnknown_03004140.unk_04 == 0) + { + gUnknown_03004140.unk_06 = -1; + } + } + if (gUnknown_03004140.unk_0e == 0) + { + sub_800D30C(0x40, 0x01); + } + } + break; + case 38: + sub_800D20C(); + if (gUnknown_03007890->unk_00 != 0xFF) + { + sub_800D30C(0x50, 0x00); + } + break; + case 16: + case 61: + if (r6 == 0) + { + gUnknown_03004140.unk_0d = 0; + gUnknown_03004140.unk_01 = 0; + gUnknown_03004140.unk_00 = 0;; + gUnknown_03004140.unk_06 = -1; + sub_800D610(); + if (r8 == 61) + { + sub_800BFA0(); + } + } + break; + } + if (r6 != 0) + { + if (r8 == 28 && r6 != 0 && gUnknown_03004140.unk_07 == 4) + { + gUnknown_03007890->unk_00 = 1; + gUnknown_03007890->unk_02 = 15; + sub_800D334(15); + rfu_waitREQComplete(); + return; + } + else + { + gUnknown_03004140.unk_14 = r8; + gUnknown_03004140.unk_16 = r6; + if (gUnknown_03004140.unk_0e) + { + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0; + } + sub_800D30C(0xf0, 0x02); + sub_800D610(); + } + } + if (r8 == 0xFF) + { + sub_800D30C(0xf2, 0x00); + sub_800D610(); + } +} + +static void sub_800CEB0(u16 r6) +{ + u8 r7; + u8 sp0; + + r7 = gUnknown_03004140.unk_0e; + gUnknown_03004140.unk_0e = 0; + gUnknown_03004140.unk_0f = 1; + if (gUnknown_03007890->unk_00 == 0) + { + sub_800C36C(r6); + if (gUnknown_03004140.unk_02 != 1) + { + sub_800D610(); + gUnknown_03004140.unk_0f = 0; + gUnknown_03004140.unk_0e = r7; + return; + } + } + else + { + if (!rfu_UNI_PARENT_getDRAC_ACK(&sp0)) + { + gUnknown_03004140.unk_03 |= sp0; + } + } + if (gUnknown_03004140.unk_44 != NULL) + { + gUnknown_03004140.unk_44(r6); + rfu_waitREQComplete(); + if (gUnknown_03004140.unk_02 == 2) + { + sub_800D610(); + } + } + gUnknown_03004140.unk_0f = 0; + gUnknown_03004140.unk_0e = r7; +} + +static void sub_800CF34(void) +{ + u8 flags; + u8 sp0; + u8 i; + u8 r5; + u8 r4; + const u16 *ptr; + + if (gUnknown_03004140.unk_04 == 5 || gUnknown_03004140.unk_04 == 6 || gUnknown_03004140.unk_04 == 7 || gUnknown_03004140.unk_04 == 8) + { + flags = ((gUnknown_03007890->unk_02 ^ gUnknown_03004140.unk_0c) & gUnknown_03007890->unk_02) & ~gUnknown_03007890->unk_07; + gUnknown_03004140.unk_0c = gUnknown_03007890->unk_02; + if (flags) + { + gUnknown_03004140.unk_14 = flags; + sub_800D30C(0x10, 0x01); + } + sp0 = 0x00; + for (i = 0; i < 4; i++) + { + r4 = 1 << i; + r5 = 0x00; + if (flags & r4) + { + gUnknown_03004140.unk_28[i] = gUnknown_03004140.unk_26; + gUnknown_03004140.unk_24 |= r4; + } + else if (gUnknown_03004140.unk_24 & r4) + { + if (gUnknown_03007880[i]->unk_34 == 0x46) + { + if (gUnknown_03007880[i]->unk_61 == 1) + { + r5 = 0x02; + for (ptr = gUnknown_03004140.unk_20; *ptr != 0xFFFF; ptr++) + { + if (gUnknown_03007890->unk_14[i].unk_04 == *ptr) + { + gUnknown_03004140.unk_00 |= r4; + gUnknown_03004140.unk_01++; + sp0 |= r4; + r5 |= 0x01; + break; + } + } + if (!(r5 & 0x01)) + { + r5 |= 0x04; + } + } + } + else if (--gUnknown_03004140.unk_28[i] == 0) + { + r5 = 0x06; + } + if (r5 & 0x02) + { + gUnknown_03004140.unk_24 &= ~r4; + gUnknown_03004140.unk_28[i] = 0; + rfu_clearSlot(0x08, i); + } + if (r5 & 0x04) + { + gUnknown_03004140.unk_0d |= r4; + } + } + } + if (sp0) + { + gUnknown_03004140.unk_14 = sp0; + sub_800D30C(0x11, 0x01); + } + if (gUnknown_03004140.unk_0d) + { + r5 = 0x01; + if (gUnknown_03007890->unk_06 && ((gUnknown_03004140.unk_03 & gUnknown_03004140.unk_00) != gUnknown_03004140.unk_00)) + { + r5 = 0x00; + } + if (r5) + { + sub_800D334(gUnknown_03004140.unk_0d); + gUnknown_03004140.unk_14 = gUnknown_03004140.unk_0d; + gUnknown_03004140.unk_0d = 0; + sub_800D30C(0x12, 0x01); + } + } + if (gUnknown_03004140.unk_24 == 0 && gUnknown_03004140.unk_04 == 8) + { + if (gUnknown_03004140.unk_07 == 0) + { + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0; + sub_800D30C(0x14, 0x00); + } + else + { + if (gUnknown_03004140.unk_07 == 2) + { + gUnknown_03004140.unk_07 = 3; + gUnknown_03004140.unk_04 = 9; + } + else + { + gUnknown_03004140.unk_07 = 1; + gUnknown_03004140.unk_04 = 5; + } + if (gUnknown_03004140.unk_00) + { + gUnknown_03004140.unk_1a = 0; + gUnknown_03004140.unk_07 = 8; + gUnknown_03004140.unk_04 = 5; + } + } + } + } +} + +static void sub_800D158(void) +{ + u16 imeBak = REG_IME; + REG_IME = 0; + if (gUnknown_03004140.unk_04 == 15) + { + if (--gUnknown_03004140.unk_28[gUnknown_03004140.unk_10] == 0 || gUnknown_03007880[gUnknown_03004140.unk_10]->unk_0 == 0x27) + { + sub_800D630(); + gUnknown_03004140.unk_04 = 24; + rfu_clearSlot(4, gUnknown_03004140.unk_10); + gUnknown_03004140.unk_24 &= ~(1 << gUnknown_03004140.unk_10); + gUnknown_03004140.unk_28[gUnknown_03004140.unk_10] = 0; + } + } + REG_IME = imeBak; + if (gUnknown_03004140.unk_04 == 24) + { + if (gUnknown_03004140.unk_02 == 1) + { + sub_800D630(); + } + if (gUnknown_03004140.unk_02 == 0) + { + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0; + sub_800D334(gUnknown_03007890->unk_02 | gUnknown_03007890->unk_03); + gUnknown_03004140.unk_14 = 0; + sub_800D30C(0x25, 0x01); + } + } +} + +static void sub_800D20C(void) +{ + if (gUnknown_03004140.unk_04 == 15 && gUnknown_03007880[gUnknown_03004140.unk_10]->unk_0 == 0x26) + { + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0; + rfu_clearSlot(4, gUnknown_03004140.unk_10); + gUnknown_03004140.unk_24 &= ~(1 << gUnknown_03004140.unk_10); + gUnknown_03004140.unk_28[gUnknown_03004140.unk_10] = 0; + sub_800D30C(0x24, 0x00); + } +} + +static void sub_800D268(void) +{ + if (gUnknown_03004140.unk_06 == 0 && gUnknown_03004140.unk_0a == 1) + { + gUnknown_03004140.unk_11 = gUnknown_03004140.unk_04; + gUnknown_03004140.unk_12 = gUnknown_03004140.unk_05; + gUnknown_03004140.unk_04 = 16; + gUnknown_03004140.unk_05 = 17; + gUnknown_03004140.unk_0a = 2; + } +} + +static u8 sub_800D294(void) +{ + u8 i; + const u16 *ptr; + u8 flags = 0x00; + + for (i = 0; i < gUnknown_03007890->unk_08; i++) + { + for (ptr = gUnknown_03004140.unk_20; *ptr != 0xffff; ptr++) + { + if (gUnknown_03007890->unk_14[i].unk_04 == *ptr) + { + flags |= (1 << i); + } + } + } + return flags; +} + +static void sub_800D30C(u8 a0, u8 a1) +{ + if (gUnknown_03004140.unk_40 != NULL) + { + gUnknown_03004140.unk_40(a0, a1); + } + gUnknown_03004140.unk_14 = gUnknown_03004140.unk_16 = 0; +} + +static void sub_800D334(u8 a0) +{ + u8 unk_0e_bak = gUnknown_03004140.unk_0e; + gUnknown_03004140.unk_0e = 1; + rfu_REQ_disconnect(a0); + rfu_waitREQComplete(); + gUnknown_03004140.unk_0e = unk_0e_bak; +} + +static void sub_800D358(u8 a0) +{ + u8 i; + + if (gUnknown_03007890->unk_04) + { + for (i = 0; i < 4; i++) + { + if (gUnknown_03007880[i]->unk_0 & 0x8000 && gUnknown_03007880[i]->unk_1a & a0) + { + rfu_changeSendTarget(0x20, i, gUnknown_03007880[i]->unk_1a & ~a0); + } + } + } + if (gUnknown_03007890->unk_05) + { + for (i = 0; i < 4; i++) + { + if (gUnknown_03007880[i]->unk_34 & 0x8000 && gUnknown_03007880[i]->unk_4e & a0) + { + rfu_NI_stopReceivingData(i); + } + } + } + if (gUnknown_03007890->unk_06) + { + gUnknown_03007890->unk_06 &= ~a0; + for (i = 0; i < 4; i++) + { + if (gUnknown_03007870[i]->unk_0 == 0x8024 && a0 & gUnknown_03007870[i]->unk_3) + { + gUnknown_03007870[i]->unk_3 &= ~a0; + } + } + } +} + +static void sub_800D434(void) +{ + u8 i; + u8 j; + u8 flags; + + if (gUnknown_03004140.unk_18) + { + if (gUnknown_03007890->unk_04) + { + for (i = 0; i < 4; i ++) + { + if (gUnknown_03007880[i]->unk_0 & 0x8000) + { + flags = 0; + for (j = 0; j < 4; j++) + { + if ((gUnknown_03007880[i]->unk_1a >> j) & 1 && gUnknown_03007880[j]->unk_2 > gUnknown_03004140.unk_18) + { + flags |= (1 << j); + } + if (flags) + { + rfu_changeSendTarget(0x20, i, flags ^ gUnknown_03007880[i]->unk_1a); + } + } + } + } + } + if (gUnknown_03007890->unk_05) + { + for (i = 0; i < 4; i++) + { + if (gUnknown_03007880[i]->unk_34 & 0x8000 && gUnknown_03007880[i]->unk_36 > gUnknown_03004140.unk_18) + { + rfu_NI_stopReceivingData(i); + } + } + } + } +} + +void sub_800D52C(void (*func)(u16)) +{ + gUnknown_03004140.unk_44 = func; + rfu_setMSCCallback(sub_800CEB0); +} + +void sub_800D544(void (*func)(u8, u8)) +{ + gUnknown_03004140.unk_40 = func; +} + +u8 sub_800D550(u8 a0, u16 a1) +{ + u16 imeBak; + if (gUnknown_03004140.unk_09 && a0 == 0 && gUnknown_03004140.unk_30) + { + return 5; + } + imeBak = REG_IME; + REG_IME = 0; + gUnknown_03004140.unk_09 = a0; + gUnknown_03004140.unk_32 = a1; + REG_IME = imeBak; + return 0; +} + +u8 sub_800D594(u16 a0) +{ + if (gUnknown_03007890->unk_04 | gUnknown_03007890->unk_05) + { + gUnknown_03004140.unk_14 = 6; + sub_800D30C(0xf3, 0x01); + return 6; + } + gUnknown_03004140.unk_18 = a0; + return 0; +} + +u8 sub_800D5D0(u8 a0) +{ + if (gUnknown_03004140.unk_04 == 9 || gUnknown_03004140.unk_04 == 10 || gUnknown_03004140.unk_04 == 11) + { + gUnknown_03004140.unk_14 = 7; + sub_800D30C(0xf3, 0x01); + return 7; + } + if (a0) + { + gUnknown_03004140.unk_0b = 1; + } + else + { + gUnknown_03004140.unk_0b = 0; + } + return 0; +} + +static void sub_800D610(void) +{ + if (gUnknown_03004140.unk_02) + { + gUnknown_03004140.unk_02 = 0; + sub_800D30C(0x45, 0x00); + } +} + +void sub_800D630(void) +{ + if (gUnknown_03004140.unk_02 == 0) + { + sub_800D30C(0x45, 0x00); + } + else if (gUnknown_03004140.unk_02 == 1) + { + gUnknown_03004140.unk_02 = 2; + } +} + +void sub_800D658(void) +{ + if (gUnknown_03004140.unk_07) + { + switch (gUnknown_03004140.unk_04) + { + case 5: + gUnknown_03004140.unk_07 = 3; + gUnknown_03004140.unk_04 = 9; + break; + case 6: + gUnknown_03004140.unk_07 = 2; + gUnknown_03004140.unk_1a = 1; + break; + case 7: + case 8: + gUnknown_03004140.unk_07 = 2; + break; + case 9: + case 10: + gUnknown_03004140.unk_1a = 40; + break; + case 11: + gUnknown_03004140.unk_1a = 40; + gUnknown_03004140.unk_04 = 10; + break; + } + } +} + +// TODO: Is there a file boundary here? + +void sub_800D6C8(struct UnkRfuStruct_2_Sub_124 *ptr) +{ + int i; + int j; + + for (i = 0; i < 32; i++) + { + for (j = 0; j < 70; j++) + { + ptr->unk_00[i][j] = 0; + } + } + ptr->unk_8c1 = 0; + ptr->unk_8c0 = 0; + ptr->unk_8c2 = 0; + ptr->unk_8c3 = 0; +} + +void sub_800D724(struct UnkRfuStruct_2_Sub_9e8 *ptr) +{ + int i; + int j; + + for (i = 0; i < 40; i++) + { + for (j = 0; j < 14; j++) + { + ptr->unk_00[i][j] = 0; + } + } + ptr->unk_231 = 0; + ptr->unk_230 = 0; + ptr->unk_232 = 0; + ptr->unk_233 = 0; +} + +void sub_800D780(struct UnkRfuStruct_Sub_Unused *ptr) +{ + int i; + int j; + + for (i = 0; i < 2; i++) + { + for (j = 0; j < 256; j++) + { + ptr->unk_00[i][j] = 0; + } + } + ptr->unk_201 = 0; + ptr->unk_200 = 0; + ptr->unk_202 = 0; + ptr->unk_203 = 0; +} + +void sub_800D7D8(struct UnkRfuStruct_2_Sub_124 *q1, u8 *q2) +{ + int i; + u16 imeBak; + u8 count; + + if (q1->unk_8c2 < 32) + { + imeBak = REG_IME; + REG_IME = 0; + count = 0; + for (i = 0; i < 70; i += 14) + { + if (q2[i] == 0 && q2[i + 1] == 0) + { + count++; + } + } + if (count != 5) + { + for (i = 0; i < 70; i++) + { + q1->unk_00[q1->unk_8c0][i] = q2[i]; + } + q1->unk_8c0++; + q1->unk_8c0 %= 32; + q1->unk_8c2++; + for (i = 0; i < 70; i++) + { + q2[i] = 0; + } + } + REG_IME = imeBak; + } + else + { + q1->unk_8c3 = 1; + } +} + +void sub_800D888(struct UnkRfuStruct_2_Sub_9e8 *q1, u8 *q2) +{ + int i; + u16 imeBak; + + if (q1->unk_232 < 40) + { + imeBak = REG_IME; + REG_IME = 0; + for (i = 0; i < 14; i++) + { + if (q2[i] != 0) + { + break; + } + } + if (i != 14) + { + for (i = 0; i < 14; i++) + { + q1->unk_00[q1->unk_230][i] = q2[i]; + } + q1->unk_230++; + q1->unk_230 %= 40; + q1->unk_232++; + for (i = 0; i < 14; i++) + { + q2[i] = 0; + } + } + REG_IME = imeBak; + } + else + { + q1->unk_233 = 1; + } +} + +bool8 sub_800D934(struct UnkRfuStruct_2_Sub_124 *q1, u8 *q2) +{ + u16 imeBak; + int i; + + imeBak = REG_IME; + REG_IME = 0; + if (q1->unk_8c0 == q1->unk_8c1 || q1->unk_8c3 != 0) + { + for (i = 0; i < 70; i++) + { + q2[i] = 0; + } + REG_IME = imeBak; + return FALSE; + } + for (i = 0; i < 70; i++) + { + q2[i] = q1->unk_00[q1->unk_8c1][i]; + } + q1->unk_8c1++; + q1->unk_8c1 %= 32; + q1->unk_8c2--; + REG_IME = imeBak; + return TRUE; +} + +bool8 sub_800D9DC(struct UnkRfuStruct_2_Sub_9e8 *q1, u8 *q2) +{ + int i; + u16 imeBak; + + if (q1->unk_230 == q1->unk_231 || q1->unk_233 != 0) + { + return FALSE; + } + imeBak = REG_IME; + REG_IME = 0; + for (i = 0; i < 14; i++) + { + q2[i] = q1->unk_00[q1->unk_231][i]; + } + q1->unk_231++; + q1->unk_231 %= 40; + q1->unk_232--; + REG_IME = imeBak; + return TRUE; +} + +void sub_800DA68(struct UnkRfuStruct_2_Sub_c1c *q1, const u8 *q2) +{ + int i; + + if (q2[1] == 0) + { + sub_800DAC8(q1, NULL); + } + else + { + for (i = 0; i < 14; i++) + { + q1->unk_00[q1->unk_1c][i] = q2[i]; + } + q1->unk_1c++; + q1->unk_1c %= 2; + if (q1->unk_1e < 2) + { + q1->unk_1e++; + } + else + { + q1->unk_1d = q1->unk_1c; + } + } +} + +static bool8 sub_800DAC8(struct UnkRfuStruct_2_Sub_c1c *q1, u8 *q2) +{ + int i; + + if (q1->unk_1e == 0) + { + return FALSE; + } + if (q2 != NULL) + { + for (i = 0; i < 14; i++) + { + q2[i] = q1->unk_00[q1->unk_1d][i]; + } + } + q1->unk_1d++; + q1->unk_1d %= 2; + q1->unk_1e--; + return TRUE; +} + +void sub_800DB18(struct UnkRfuStruct_Sub_Unused *q1, u8 *q2) +{ + int i; + + if (q1->unk_202 < 2) + { + for (i = 0; i < 256; i++) + { + q1->unk_00[q1->unk_200][i] = q2[i]; + } + q1->unk_200++; + q1->unk_200 %= 2; + q1->unk_202++; + } + else + { + q1->unk_203 = 1; + } +} + +bool8 sub_800DB84(struct UnkRfuStruct_Sub_Unused *q1, u8 *q2) +{ + int i; + + if (q1->unk_200 == q1->unk_201 || q1->unk_203) + { + return FALSE; + } + for (i = 0; i < 256; i++) + { + q2[i] = q1->unk_00[q1->unk_201][i]; + } + q1->unk_201++; + q1->unk_201 %= 2; + q1->unk_202--; + return TRUE; +} + +void sub_800DBF8(u8 *q1, u8 mode) +{ + int i; + u8 rval; + u16 r5 = 0; + switch (mode) + { + case 0: + for (i = 0; i < 200; i++) + { + q1[i] = i + 1; + r5 += i + 1; + } + *((u16 *)(q1 + i)) = r5; + break; + case 1: + for (i = 0; i < 100; i++) + { + q1[i] = i + 1; + r5 += i + 1; + } + *((u16 *)(q1 + 200)) = r5; + break; + case 2: + for (i = 0; i < 200; i++) + { + rval = Random(); + q1[i] = rval; + r5 += rval; + } + *((u16 *)(q1 + i)) = r5; + break; + case 3: + for (i = 0; i < 200; i++) + { + q1[i] = i + 1 + gUnknown_03000D74; + r5 += (i + 1 + gUnknown_03000D74) & 0xFF; + } + *((u16 *)(q1 + i)) = r5; + gUnknown_03000D74++; + break; + } +} + +void PkmnStrToASCII(u8 *q1, const u8 *q2) +{ + int i; + + for (i = 0; q2[i] != EOS; i++) + { + q1[i] = sWireless_RSEtoASCIITable[q2[i]]; + } + q1[i] = 0; +} + +void ASCIIToPkmnStr(u8 *q1, const u8 *q2) +{ + int i; + + for (i = 0; q2[i] != 0; i++) + { + q1[i] = sWireless_ASCIItoRSETable[q2[i]]; + } + q1[i] = EOS; +} + +#ifdef NONMATCHING +u8 sub_800DD1C(u8 maxFlags) +{ + u8 flagCount = 0; + u8 flags = gUnknown_03007890->unk_02; + u8 i; + + if (gUnknown_03007890->unk_00 == 1) + { + i = 0; + for (i = 0; i < 4; flags >>= 1, i++) + { + if (flags & 1) + { + if (maxFlags == flagCount + 1) + { + return gUnknown_03007890->unk_0a[i]; + } + flagCount++; + } + } + } + else + { + for (i = 0; i < 4; flags >>= 1, i++) + { + if (flags & 1) + { + return gUnknown_03007890->unk_0a[i]; + } + } + } + return 0; +} +#else +ASM_DIRECT u8 sub_800DD1C(u8 maxFlags) +{ + asm_unified("\tpush {r4-r7,lr}\n" + "\tlsls r0, 24\n" + "\tlsrs r5, r0, 24\n" + "\tmovs r6, 0\n" + "\tldr r0, =gUnknown_03007890\n" + "\tldr r4, [r0]\n" + "\tldrb r2, [r4, 0x2]\n" + "\tldrb r1, [r4]\n" + "\tadds r7, r0, 0\n" + "\tcmp r1, 0x1\n" + "\tbne _0800DD72\n" + "\tmovs r3, 0\n" + "\tands r1, r2\n" + "\tcmp r1, 0\n" + "\tbeq _0800DD4E\n" + "\tcmp r5, 0x1\n" + "\tbne _0800DD48\n" + "\tldrb r0, [r4, 0xA]\n" + "\tb _0800DD8C\n" + "\t.pool\n" + "_0800DD48:\n" + "\tadds r0, r6, 0x1\n" + "\tlsls r0, 24\n" + "\tlsrs r6, r0, 24\n" + "_0800DD4E:\n" + "\tlsrs r2, 1\n" + "\tadds r0, r3, 0x1\n" + "\tlsls r0, 24\n" + "\tlsrs r3, r0, 24\n" + "\tcmp r3, 0x3\n" + "\tbhi _0800DD8A\n" + "\tmovs r0, 0x1\n" + "\tands r0, r2\n" + "\tcmp r0, 0\n" + "\tbeq _0800DD4E\n" + "\tadds r0, r6, 0x1\n" + "\tcmp r5, r0\n" + "\tbne _0800DD48\n" + "_0800DD68:\n" + "\tldr r0, [r7]\n" + "\tadds r0, 0xA\n" + "\tadds r0, r3\n" + "\tldrb r0, [r0]\n" + "\tb _0800DD8C\n" + "_0800DD72:\n" + "\tmovs r3, 0\n" + "\tmovs r1, 0x1\n" + "_0800DD76:\n" + "\tadds r0, r2, 0\n" + "\tands r0, r1\n" + "\tcmp r0, 0\n" + "\tbne _0800DD68\n" + "\tlsrs r2, 1\n" + "\tadds r0, r3, 0x1\n" + "\tlsls r0, 24\n" + "\tlsrs r3, r0, 24\n" + "\tcmp r3, 0x3\n" + "\tbls _0800DD76\n" + "_0800DD8A:\n" + "\tmovs r0, 0\n" + "_0800DD8C:\n" + "\tpop {r4-r7}\n" + "\tpop {r1}\n" + "\tbx r1"); +} +#endif + +void sub_800DD94(struct UnkLinkRfuStruct_02022B14 *data, u8 r9, bool32 r2, int r3) +{ + int i; + + for (i = 0; i < 2; i++) + { + data->playerTrainerId[i] = gSaveBlock2Ptr->playerTrainerId[i]; + } + for (i = 0; i < 4; i++) + { + data->unk_04[i] = r3; + r3 >>= 8; + } + data->playerGender = gSaveBlock2Ptr->playerGender; + data->unk_0a_0 = r9; + data->unk_0a_7 = r2; + data->unk_00_0 = 2; + data->unk_01_2 = 3; + data->unk_00_4 = 0; + data->unk_00_5 = 0; + data->unk_00_6 = 0; + data->unk_00_7 = FlagGet(FLAG_0x87F); + data->unk_01_0 = IsNationalPokedexEnabled(); + data->unk_01_1 = FlagGet(FLAG_SYS_GAME_CLEAR); +} + +bool8 sub_800DE7C(struct UnkLinkRfuStruct_02022B14 *buff1, u8 *buff2, u8 idx) +{ + bool8 retVal; + + if (gUnknown_03004140.unk_06 == 1) + { + retVal = TRUE; + if (sub_8010454(gUnknown_03007890->unk_14[idx].unk_04) && ((gUnknown_03007890->unk_07 >> idx) & 1)) + { + memcpy(buff1, &gUnknown_03007890->unk_14[idx].unk_06, sizeof(gUnknown_03007890->unk_14[idx].unk_06)); + memcpy(buff2, gUnknown_03007890->unk_14[idx].unk_15, sizeof(gUnknown_03007890->unk_14[idx].unk_15)); + } + else + { + memset(buff1, 0, sizeof(gUnknown_03007890->unk_14[idx].unk_06)); + memset(buff2, 0, sizeof(gUnknown_03007890->unk_14[idx].unk_15)); + } + } + else + { + retVal = FALSE; + if (sub_8010454(gUnknown_03007890->unk_14[idx].unk_04)) + { + memcpy(buff1, &gUnknown_03007890->unk_14[idx].unk_06, sizeof(gUnknown_03007890->unk_14[idx].unk_06)); + memcpy(buff2, gUnknown_03007890->unk_14[idx].unk_15, sizeof(gUnknown_03007890->unk_14[idx].unk_15)); + } + else + { + memset(buff1, 0, sizeof(gUnknown_03007890->unk_14[idx].unk_06)); + memset(buff2, 0, sizeof(gUnknown_03007890->unk_14[idx].unk_15)); + } + } + return retVal; +} + +bool8 sub_800DF34(struct UnkLinkRfuStruct_02022B14 *buff1, u8 *buff2, u8 idx) +{ + bool8 retVal = FALSE; + if (gUnknown_03007890->unk_14[idx].unk_04 == 0x7F7D) + { + *buff1 = gUnknown_03007890->unk_14[idx].unk_06; + memcpy(buff2, gUnknown_03007890->unk_14[idx].unk_15, 8); + retVal = TRUE; + } + else + { + *buff1 = (struct UnkLinkRfuStruct_02022B14){}; + memset(buff2, 0, 8); + } + return retVal; +} + +void sub_800DF90(struct UnkLinkRfuStruct_02022B14 *buff1, u8 *buff2) +{ + *buff1 = gUnknown_02022B14; + memcpy(buff2, gUnknown_02022B22, 8); +} + +void CreateWirelessStatusIndicatorSprite(u8 x, u8 y) +{ + u8 sprId; + + if (x == 0 && y == 0) + { + x = 0xE7; + y = 0x08; + } + if (gUnknown_03007890->unk_00 == 1) + { + sprId = CreateSprite(&sWirelessStatusIndicatorSpriteTemplate, x, y, 0); + gSprites[sprId].data[7] = 0x1234; + gSprites[sprId].data[6] = GetSpriteTileStartByTag(sWirelessStatusIndicatorSpriteSheet.tag); + gSprites[sprId].invisible = TRUE; + gWirelessStatusIndicatorSpriteId = sprId; + } + else + { + gWirelessStatusIndicatorSpriteId = CreateSprite(&sWirelessStatusIndicatorSpriteTemplate, x, y, 0); + gSprites[gWirelessStatusIndicatorSpriteId].data[7] = 0x1234; + gSprites[gWirelessStatusIndicatorSpriteId].data[6] = GetSpriteTileStartByTag(sWirelessStatusIndicatorSpriteSheet.tag); + gSprites[gWirelessStatusIndicatorSpriteId].invisible = TRUE; + } +} + +void sub_800E084(void) +{ + if (gSprites[gWirelessStatusIndicatorSpriteId].data[7] == 0x1234) + { + gSprites[gWirelessStatusIndicatorSpriteId].data[7] = 0; + DestroySprite(&gSprites[gWirelessStatusIndicatorSpriteId]); + gMain.oamBuffer[125] = gDummyOamData; + CpuCopy16(&gDummyOamData, (struct OamData *)OAM + 125, sizeof(struct OamData)); + } +} + +void sub_800E0E8(void) +{ + if (GetSpriteTileStartByTag(sWirelessStatusIndicatorSpriteSheet.tag) == 0xFFFF) + { + LoadCompressedObjectPic(&sWirelessStatusIndicatorSpriteSheet); + } + LoadSpritePalette(&sWirelessStatusIndicatorSpritePalette); + gWirelessStatusIndicatorSpriteId = 0xFF; +} + +u8 sub_800E124(void) +{ + u8 i; + u8 flags = gUnknown_03007890->unk_02; + for (i = 0; i < 4; i++) + { + if (flags & 1) + { + return gUnknown_03007890->unk_0a[i]; + } + flags >>= 1; + } + return 0; +} + +void sub_800E15C(struct Sprite *sprite, int signalStrengthAnimNum) +{ + if (sprite->data[2] != signalStrengthAnimNum) + { + sprite->data[2] = signalStrengthAnimNum; + sprite->data[3] = 0; + sprite->data[4] = 0; + } +} + +void sub_800E174(void) +{ + if (gWirelessStatusIndicatorSpriteId != 0xFF && gSprites[gWirelessStatusIndicatorSpriteId].data[7] == 0x1234) + { + struct Sprite *sprite = &gSprites[gWirelessStatusIndicatorSpriteId]; + u8 signalStrength = 255; + u8 i = 0; + if (gUnknown_03007890->unk_00 == 1) + { + for (i = 0; i < GetLinkPlayerCount() - 1; i++) + { + if (signalStrength >= sub_800DD1C(i + 1)) + { + signalStrength = sub_800DD1C(i + 1); + } + } + } + else + { + signalStrength = sub_800E124(); + } + if (sub_8012224() == TRUE) + { + sprite->data[0] = 4; + } + else if (signalStrength < 25) + { + sprite->data[0] = 3; + } + else if (signalStrength >= 25 && signalStrength < 127) + { + sprite->data[0] = 2; + } + else if (signalStrength >= 127 && signalStrength < 229) + { + sprite->data[0] = 1; + } + else if (signalStrength >= 229) + { + sprite->data[0] = 0; + } + if (sprite->data[0] != sprite->data[1]) + { + sub_800E15C(sprite, sprite->data[0]); + sprite->data[1] = sprite->data[0]; + } + if (sprite->anims[sprite->data[2]][sprite->data[4]].frame.duration < sprite->data[3]) + { + sprite->data[4]++; + sprite->data[3] = 0; + if (sprite->anims[sprite->data[2]][sprite->data[4]].type == -2) + { + sprite->data[4] = 0; + } + } + else + { + sprite->data[3]++; + } + gMain.oamBuffer[125] = sWirelessStatusIndicatorOamData; + gMain.oamBuffer[125].x = sprite->pos1.x + sprite->centerToCornerVecX; + gMain.oamBuffer[125].y = sprite->pos1.y + sprite->centerToCornerVecY; + gMain.oamBuffer[125].paletteNum = sprite->oam.paletteNum; + gMain.oamBuffer[125].tileNum = sprite->data[6] + sprite->anims[sprite->data[2]][sprite->data[4]].frame.imageValue; + CpuCopy16(gMain.oamBuffer + 125, (struct OamData *)OAM + 125, sizeof(struct OamData)); + if (sub_8011A74() == 1) + { + sub_800E084(); + } + } +} + +void sub_800E378(struct UnkSaveSubstruct_3b98 *dest, u32 trainerId, const u8 *name) +{ + dest->trainerId = trainerId; + StringCopy(dest->trainerName, name); +} + +bool32 sub_800E388(const u8 *name) +{ + int i; + + for (i = 0; i < 8; i++) + { + if (name[i] != 0) + { + return TRUE; + } + } + return FALSE; +} + +void sub_800E3A8(void) +{ + if (gWirelessCommType != 0) + { + int i; + int j; + int cnt; + int sp0[5]; + struct UnkSaveSubstruct_3b98 *sp14 = calloc(20, sizeof(struct UnkSaveSubstruct_3b98)); + for (i = 0; i < GetLinkPlayerCount(); i++) + { + sp0[i] = -1; + for (j = 0; j < 20; j++) + { + if ((u16)gLinkPlayers[i].trainerId == gSaveBlock1Ptr->unk_3B98[j].trainerId && StringCompare(gLinkPlayers[i].name, gSaveBlock1Ptr->unk_3B98[j].trainerName) == 0) + { + sp0[i] = j; + } + } + } + cnt = 0; + for (i = 0; i < GetLinkPlayerCount(); i++) + { + if (i != GetMultiplayerId() && gLinkPlayers[i].language != LANGUAGE_JAPANESE) + { + sub_800E378(&sp14[cnt], (u16)gLinkPlayers[i].trainerId, gLinkPlayers[i].name); + if (sp0[i] >= 0) + { + memset(gSaveBlock1Ptr->unk_3B98[sp0[i]].trainerName, 0, 8); + } + cnt++; + } + } + for (i = 0; i < 20; i++) + { + if (sub_800E388(gSaveBlock1Ptr->unk_3B98[i].trainerName)) + { + sub_800E378(&sp14[cnt], gSaveBlock1Ptr->unk_3B98[i].trainerId, gSaveBlock1Ptr->unk_3B98[i].trainerName); + if (++cnt >= 20) + { + break; + } + } + } + memcpy(gSaveBlock1Ptr->unk_3B98, sp14, 20 * sizeof(struct UnkSaveSubstruct_3b98)); + free(sp14); + } +} + +bool32 sub_800E540(u16 id, u8 *name) +{ + int i; + + for (i = 0; i < 20; i++) + { + if (StringCompare(gSaveBlock1Ptr->unk_3B98[i].trainerName, name) == 0 && gSaveBlock1Ptr->unk_3B98[i].trainerId == id) + { + return TRUE; + } + if (!sub_800E388(gSaveBlock1Ptr->unk_3B98[i].trainerName)) + { + return FALSE; + } + } + return FALSE; +} + +void sub_800E5AC(void) +{ + int i; + + for (i = 0; i < 20; i++) + { + gSaveBlock1Ptr->unk_3B98[i].trainerId = 0; + CpuFill16(0, gSaveBlock1Ptr->unk_3B98[i].trainerName, 8); + } +} + +void nullsub_5(void *unused_0, u8 unused_1, u8 unused_2) +{ + // debug? +} + +void nullsub_13(u8 unused_0, u8 unused_1, u8 unused_2, u8 unused_3) +{ + +} + +void sub_800E604(void) +{ + int i; + u8 unk_ee_bak = gUnknown_03005000.unk_ee; + CpuFill16(0, &gUnknown_03005000, sizeof gUnknown_03005000); + gUnknown_03005000.unk_ee = unk_ee_bak; + gUnknown_03005000.unk_0c = 0xFF; + if (gUnknown_03005000.unk_ee != 4) + { + gUnknown_03005000.unk_ee = 0; + } + for (i = 0; i < 5; i++) + { + sub_800FCC4(gUnknown_03005000.unk_80 + i); + } + sub_800FCC4(&gUnknown_03005000.unk_6c); + sub_800D6C8(&gUnknown_03005000.unk_124); + sub_800D724(&gUnknown_03005000.unk_9e8); + CpuFill16(0, gSendCmd, sizeof gSendCmd); + CpuFill16(0, gRecvCmds, sizeof gRecvCmds); + CpuFill16(0, gLinkPlayers, sizeof gLinkPlayers) +} + +void sub_800E6D0(void) +{ + IntrFunc serialIntr = gIntrTable[1]; + IntrFunc timerIntr = gIntrTable[2]; + sub_800E700(); + rfu_REQ_stopMode(); + rfu_waitREQComplete(); + REG_IME = 0; + gIntrTable[1] = serialIntr; + gIntrTable[2] = timerIntr; + REG_IME = INTR_FLAG_VBLANK; +} + +void sub_800E700(void) +{ + if (!rfu_initializeAPI(gUnknown_03004140.unk_50, sizeof gUnknown_03004140.unk_50, gIntrTable + 1, TRUE)) + { + gLinkType = 0; + sub_800AAF4(); + sub_80111B0(0); + sub_800E604(); + rfu_setTimerInterrupt(3, gIntrTable + 2); + } +} + +void sub_800E748(u8 taskId) +{ + sub_8010750(); + switch (gUnknown_03005000.unk_04) + { + case 0: + sub_800BFCC(&gUnknown_02022B2C); + gUnknown_03005000.unk_04 = 1; + gTasks[taskId].data[1] = 1; + break; + case 1: + break; + case 2: + sub_800C054(gUnknown_03005000.unk_0c, 0, 240, gUnknown_082ED6E0); + gUnknown_03005000.unk_04 = 3; + gTasks[taskId].data[1] = 6; + break; + case 3: + break; + case 4: + sub_800C27C(FALSE); + gUnknown_03005000.unk_04 = 5; + break; + case 5: + break; + case 18: + gUnknown_03005000.unk_cdb = 0; + sub_800D52C(sub_800EDBC); + sub_800EAB4(); + sub_800EAFC(); + gUnknown_03005000.unk_04 = 20; + gTasks[taskId].data[1] = 8; + CreateTask(sub_801084C, 5); + DestroyTask(taskId); + break; + } +} + +u8 sub_800E87C(u8 idx) +{ + return gUnknown_082ED6A5[idx]; +} + +void sub_800E88C(int r2, int r5) +{ + u8 i; + u8 r4 = 1; + int r1 = r2; + int r6 = 0; + if (r5 == -1) + { + for (i = 0; i < 4; r2 >>= 1, i++) + { + if (r2 & 1) + { + gUnknown_03005000.unk_cde[i] = r4; + r4++; + } + } + } + else + { + for (i = 0; i < 4; r1 >>= 1, i++) + { + if (!(r1 & 1)) + { + gUnknown_03005000.unk_cde[i] = 0; + } + } + for (r4 = 4; r4 != 0; r4--) + { + for (i = 0; i < 4 && gUnknown_03005000.unk_cde[i] != r4; i++); + if (i == 4) + { + r6 = r4; + } + } + for (r5 &= ~r2, i = 0; i < 4; r5 >>= 1, i++) + { + if (r5 & 1) + { + gUnknown_03005000.unk_cde[i] = r6++; + } + } + } +} + +void sub_800E94C(u8 taskId) +{ + switch (gUnknown_03005000.unk_04) + { + case 0: + sub_800BFCC(&gUnknown_082ED608); + gUnknown_03005000.unk_04 = 1; + gTasks[taskId].data[1] = 1; + break; + case 1: + break; + case 6: + sub_800C054(gUnknown_03005000.unk_0c, 0, 0xf0, gUnknown_082ED6E0); + gUnknown_03005000.unk_04 = 7; + gTasks[taskId].data[1] = 7; + break; + case 7: + break; + case 9: + gTasks[taskId].data[1] = 10; + break; + case 11: + switch (sub_80107A0()) + { + case 5: + gUnknown_03005000.unk_04 = 12; + break; + case 6: + case 9: + sub_800D630(); + gUnknown_03005000.unk_ce4 = 2; + DestroyTask(taskId); + break; + } + break; + case 12: + { + u8 r5 = 1 << gUnknown_03005000.unk_c3e; + rfu_clearSlot(12, gUnknown_03005000.unk_c3e); + rfu_setRecvBuffer(16, gUnknown_03005000.unk_c3e, gUnknown_03005000.unk_c3f, 70); + rfu_UNI_setSendData(r5, gUnknown_03005000.unk_4c, 14); + gTasks[taskId].data[1] = 8; + DestroyTask(taskId); + if (gUnknown_02022B44.unk_0f == 0) + { + sub_801227C(); + gUnknown_02022B44.unk_0f++; + } + CreateTask(sub_801084C, 5); + break; + } + } +} + +static void sub_800EAB4(void) +{ + u8 i; + u8 r5 = gUnknown_03004140.unk_00; + for (i = 0; i < 4; i++) + { + if (r5 & 1) + { + rfu_setRecvBuffer(16, i, gUnknown_03005000.unk_14[i], 14); + rfu_clearSlot(3, i); + } + r5 >>= 1; + } +} + +static void sub_800EAFC(void) +{ + u8 r5 = gUnknown_03004140.unk_00; + rfu_UNI_setSendData(r5, gUnknown_03005000.unk_c87, 70); + gUnknown_03005000.unk_cda = sub_800E87C(r5); + gUnknown_03005000.unk_ce2 = r5; + sub_800E88C(r5, -1); + gUnknown_03005000.unk_0c = 1; +} + +void sub_800EB44(u8 taskId) +{ + if (sub_800F7DC()->unk_0a_0 == 0x54 && sub_8011A74() == 4) + { + rfu_REQ_disconnect(gUnknown_03004140.unk_00); + rfu_waitREQComplete(); + sub_8011A64(0, 0); + } + switch (gUnknown_03005000.unk_04) + { + case 0: + sub_800BFCC(&gUnknown_02022B2C); + gUnknown_03005000.unk_04 = 1; + gTasks[taskId].data[1] = 1; + break; + case 1: + break; + case 17: + sub_800C054(2, 0, 240, gUnknown_082ED6E0); + sub_800D52C(sub_800ED34); + gUnknown_03005000.unk_04 = 18; + break; + case 18: + break; + case 13: + if (rfu_UNI_setSendData(1 << gUnknown_03005000.unk_c3e, gUnknown_03005000.unk_4c, 14) == 0) + { + gUnknown_03005000.unk_0c = 0; + DestroyTask(taskId); + if (gTasks[taskId].data[7]) + { + CreateTask(sub_8010D0C, 1); + } + else + { + CreateTask(sub_801084C, 5); + } + } + break; + case 14: + sub_800C27C(0); + gUnknown_03005000.unk_04 = 15; + break; + case 15: + break; + case 16: + gUnknown_03005000.unk_cdb = 0; + sub_800D52C(sub_800EDBC); + sub_8011068(1); + sub_800EAB4(); + sub_800EAFC(); + gUnknown_03005000.unk_04 = 20; + gTasks[taskId].data[1] = 8; + gUnknown_03005000.unk_0c = 1; + CreateTask(sub_801084C, 5); + gUnknown_03005000.unk_ce8 = 1; + DestroyTask(taskId); + break; + } +} + +void sub_800ED10(void) +{ + sub_800C054(1, 0, 240, gUnknown_082ED6E0); +} + +void sub_800ED28(void) +{ + sub_800C27C(FALSE); +} + +void sub_800ED34(u16 unused) +{ + int i; + + for (i = 0; i < 14; i++) + { + gUnknown_03005000.unk_4c[i] = 0; + } + rfu_REQ_recvData(); + rfu_waitREQComplete(); + if (gUnknown_03007870[gUnknown_03005000.unk_c3e]->unk_12) + { + gUnknown_03005000.unk_cd0++; + sub_800D7D8(&gUnknown_03005000.unk_124, gUnknown_03005000.unk_c3f); + gUnknown_02022B44.unk_06++; + sub_800F048(); + rfu_UNI_readySendData(gUnknown_03005000.unk_c3e); + rfu_UNI_clearRecvNewDataFlag(gUnknown_03005000.unk_c3e); + } + rfu_REQ_sendData_wrapper(1); +} + +static void sub_800EDBC(u16 unused) +{ + gUnknown_03005000.unk_cdb = 1; +} + +void sub_800EDD4(void) +{ + u8 i; + + sub_800C048(); + if (gUnknown_03005000.unk_0c == 1) + { + if (FuncIsActiveTask(sub_800E748) == TRUE) + { + DestroyTask(gUnknown_03005000.unk_67); + sub_800E604(); + } + } + else if (gUnknown_03005000.unk_0c == 0) + { + if (FuncIsActiveTask(sub_800E94C) == TRUE) + { + DestroyTask(gUnknown_03005000.unk_67); + sub_800E604(); + } + } + else if (gUnknown_03005000.unk_0c == 2) + { + if (FuncIsActiveTask(sub_800EB44) == TRUE) + { + DestroyTask(gUnknown_03005000.unk_67); + sub_800E604(); + } + } + for (i = 0; i < 3; i++) + { + if (FuncIsActiveTask(gUnknown_082ED7E0[i]) == TRUE) + { + DestroyTask(FindTaskIdByFunc(gUnknown_082ED7E0[i])); + } + } +} + +void sub_800EE78(void) +{ + gUnknown_03005000.unk_67 = CreateTask(sub_800E748, 1); +} + +bool8 sub_800EE94(void) +{ + if (gUnknown_03005000.unk_04 == 7 && gUnknown_03005000.unk_ccd) + { + return TRUE; + } + return FALSE; +} + +bool8 sub_800EEBC(void) +{ + if (gUnknown_03005000.unk_04 == 7 && !sub_800C12C(gUnknown_03007890->unk_14[gUnknown_03005000.unk_c3d].unk_00, 240)) + { + gUnknown_03005000.unk_04 = 9; + return TRUE; + } + return FALSE; +} + +void sub_800EF00(void) +{ + gUnknown_03005000.unk_67 = CreateTask(sub_800E94C, 1); +} + +bool8 sub_800EF1C(void) +{ + if (gUnknown_03004140.unk_00) + { + return TRUE; + } + return FALSE; +} + +void sub_800EF38(void) +{ + gUnknown_03005000.unk_04 = 4; + gUnknown_03005000.unk_ce7 = gUnknown_03004140.unk_00; +} + +bool8 sub_800EF58(bool32 a0) +{ + if (gUnknown_03005000.unk_04 == 17 || a0) + { + gUnknown_03005000.unk_04 = 18; + return TRUE; + } + return FALSE; +} + +void sub_800EF7C(void) +{ + gUnknown_03005000.unk_04 = 14; +} + +void sub_800EF88(u8 a0) +{ + u8 i; + + for (i = 0; i < 4; i++) + { + if (a0 & 1) + { + rfu_UNI_readySendData(i); + break; + } + a0 >>= 1; + } +} + +#ifdef NONMATCHING +// FIXME: gUnknown_03005000.unk_c87 should be in r5 +// FIXME: gRecvCmds should be in r6 and r7 +void sub_800EFB0(void) +{ + int i, j; + for (i = 0; i < 5; i++) + { + for (j = 0; j < 7; j++) + { + gUnknown_03005000.unk_c87[i][j][1] = gRecvCmds[i][j] >> 8; + gUnknown_03005000.unk_c87[i][j][0] = gRecvCmds[i][j]; + } + } + CpuFill16(0, gRecvCmds, sizeof gRecvCmds); +} +#else +ASM_DIRECT void sub_800EFB0(void) +{ + asm_unified("\tpush {r4-r7,lr}\n" + "\tsub sp, 0x4\n" + "\tmovs r2, 0\n" + "\tldr r7, =gRecvCmds\n" + "\tldr r0, =gUnknown_03005000\n" + "\tadds r6, r7, 0\n" + "\tldr r1, =0x00000c87\n" + "\tadds r5, r0, r1\n" + "_0800EFC0:\n" + "\tmovs r3, 0\n" + "\tlsls r0, r2, 3\n" + "\tlsls r1, r2, 4\n" + "\tadds r4, r2, 0x1\n" + "\tsubs r0, r2\n" + "\tlsls r0, 1\n" + "\tadds r2, r0, r5\n" + "\tadds r1, r6\n" + "_0800EFD0:\n" + "\tldrh r0, [r1]\n" + "\tlsrs r0, 8\n" + "\tstrb r0, [r2, 0x1]\n" + "\tldrh r0, [r1]\n" + "\tstrb r0, [r2]\n" + "\tadds r2, 0x2\n" + "\tadds r1, 0x2\n" + "\tadds r3, 0x1\n" + "\tcmp r3, 0x6\n" + "\tble _0800EFD0\n" + "\tadds r2, r4, 0\n" + "\tcmp r2, 0x4\n" + "\tble _0800EFC0\n" + "\tmovs r0, 0\n" + "\tmov r1, sp\n" + "\tstrh r0, [r1]\n" + "\tldr r2, =0x01000028\n" + "\tmov r0, sp\n" + "\tadds r1, r7, 0\n" + "\tbl CpuSet\n" + "\tadd sp, 0x4\n" + "\tpop {r4-r7}\n" + "\tpop {r0}\n" + "\tbx r0\n" + "\t.pool"); +} +#endif + +void sub_800F014(void) +{ + int i; + for (i = 0; i < 7; i++) + { + gRecvCmds[0][i] = gSendCmd[i]; + } + for (i = 0; i < 7; i++) + { + gSendCmd[i] = 0; + } +} + +static void sub_800F048(void) +{ + if (gUnknown_03005000.unk_c3c) + { + u8 r2 = sub_800DAC8(&gUnknown_03005000.unk_c1c, gUnknown_03005000.unk_4c); + if (gUnknown_03005000.unk_c1c.unk_1e == 0) + { + gUnknown_03005000.unk_c3c = 0; + } + if (r2) + { + return; + } + } + if (gUnknown_03005000.unk_c3c == 0) + { + sub_800D9DC(&gUnknown_03005000.unk_9e8, gUnknown_03005000.unk_4c); + sub_800DA68(&gUnknown_03005000.unk_c1c, gUnknown_03005000.unk_4c); + } +} + +bool32 sub_800F0B8(void) +{ + int i; + int j; + + if (gUnknown_03007890->unk_06 == 0) + { + return FALSE; + } + for (i = 0; i < 5; i++) + { + for (j = 0; j < 7; j++) + { + if (gRecvCmds[i][j] != 0) + { + return FALSE; + } + } + } + return TRUE; +} + +bool32 sub_800F0F8(void) +{ + if (gUnknown_03005000.unk_04 < 20) + { + rfu_REQ_recvData(); + rfu_waitREQComplete(); + rfu_REQ_sendData_wrapper(0); + } + else + { + gUnknown_03005000.unk_cdb = 0; + if ((gUnknown_03005000.unk_ce2 & gUnknown_03007890->unk_02) == gUnknown_03005000.unk_ce2 && (gUnknown_03005000.unk_ce2 & gUnknown_03007890->unk_02)) + { + if (!gUnknown_03005000.unk_cdc) + { + if (gUnknown_03005000.unk_ce3) + { + sub_8011D6C(gUnknown_03005000.unk_ce3); + gUnknown_03005000.unk_ce3 = 0; + if (gUnknown_03005000.unk_ce4 == 1) + { + sub_8011A64(2, 0x8000); + sub_8011170(0x8000); + return FALSE; + } + if (!gUnknown_03004140.unk_00) + { + sub_800EDD4(); + gReceivedRemoteLinkPlayers = 0; + return FALSE; + } + } + sub_800EFB0(); + rfu_UNI_readySendData(gUnknown_03005000.unk_cda); + rfu_REQ_sendData_wrapper(1); + } + else + { + rfu_REQ_PARENT_resumeRetransmitAndChange(); + } + gUnknown_03005000.unk_0e = 1; + } + } + return FALSE; +} + +bool32 sub_800F1E0(void) +{ + u16 i; + u16 flags; + u8 r0; + u16 j; + u8 retval; + + if (gUnknown_03005000.unk_04 >= 20 && gUnknown_03005000.unk_0e == 1) + { + rfu_waitREQComplete(); + while (gUnknown_03005000.unk_cdb == 0) + { + if (gUnknown_03005000.unk_ee != 0) + { + return FALSE; + } + } + rfu_REQ_recvData(); + rfu_waitREQComplete(); + if ((gUnknown_03004140.unk_03 & gUnknown_03005000.unk_ce2) == gUnknown_03005000.unk_ce2) + { + gUnknown_03005000.unk_cdc = 0; + gUnknown_02022B44.unk_06++; + flags = gUnknown_03004140.unk_00; + for (i = 0; i < 4; i++) + { + if (flags & 1) + { + if (gUnknown_03005000.unk_14[i][1]) + { + if (gUnknown_03005000.unk_cee[i] != 0xff && (gUnknown_03005000.unk_14[i][0] >> 5) != ((gUnknown_03005000.unk_cee[i] + 1) & 7)) + { + if (++gUnknown_03005000.unk_cea[i] > 4) + sub_8011170(0x8100); + } + else + { + gUnknown_03005000.unk_cee[i] = gUnknown_03005000.unk_14[i][0] / 32; + gUnknown_03005000.unk_cea[i] = 0; + gUnknown_03005000.unk_14[i][0] &= 0x1f; + r0 = gUnknown_03005000.unk_cde[i]; + for (j = 0; j < 7; j++) + { + gRecvCmds[r0][j] = (gUnknown_03005000.unk_14[i][(j << 1) + 1] << 8) | gUnknown_03005000.unk_14[i][(j << 1) + 0]; + gUnknown_03005000.unk_14[i][(j << 1) + 1] = 0; + gUnknown_03005000.unk_14[i][(j << 1) + 0] = 0; + } + } + } + rfu_UNI_clearRecvNewDataFlag(i); + } + flags >>= 1; + } + sub_800F014(); + sub_800F86C(0); + sub_8010528(); + if (gUnknown_03005000.unk_ce5 && !gUnknown_03005000.unk_cd9) + { + gUnknown_02022B44.unk_0e = 0; + rfu_clearSlot(3, gUnknown_03005000.unk_cda); + for (i = 0; i < 4; i++) + { + if ((gUnknown_03005000.unk_ce5 >> i) & 1) + { + rfu_setRecvBuffer(0x10, i, gUnknown_03005000.unk_14[i], 14); + } + } + sub_800E88C(gUnknown_03005000.unk_ce2, gUnknown_03005000.unk_ce2 | gUnknown_03005000.unk_ce5); + gUnknown_03005000.unk_ce9 = gUnknown_03005000.unk_ce5; + gUnknown_03005000.unk_ce2 |= gUnknown_03005000.unk_ce5; + gUnknown_03005000.unk_ce5 = 0; + rfu_UNI_setSendData(gUnknown_03005000.unk_ce2, gUnknown_03005000.unk_c87, 70); + gUnknown_03005000.unk_cda = sub_800E87C(gUnknown_03005000.unk_ce2); + CreateTask(sub_8010AAC, 0); + } + } + else + { + gUnknown_03005000.unk_cdc = 1; + gUnknown_03005000.unk_0e = 0; + } + gUnknown_03005000.unk_0e = 0; + } + retval = gUnknown_03005000.unk_cdc; + return gUnknown_03007890->unk_06 ? retval & 1 : FALSE; +} + +void sub_800F498(u16 *a0, u8 *a1) +{ + int i; + + if (a0[0]) + { + a0[0] |= (gUnknown_03005000.unk_102 << 5); + gUnknown_03005000.unk_102 = (gUnknown_03005000.unk_102 + 1) & 7; + for (i = 0; i < 7; i++) + { + a1[2 * i + 1] = a0[i] >> 8; + a1[2 * i + 0] = a0[i]; + } + } + else + { + for (i = 0; i < 14; i++) + a1[i] = 0; + } +} + +bool32 sub_800F4F0(void) +{ + u8 i; + u8 j; + u8 sp00[MAX_RFU_PLAYERS * (2 * (CMD_LENGTH - 1))]; + u8 sp48[2 * (CMD_LENGTH - 1)]; + u8 switchval; + + sub_800D934(&gUnknown_03005000.unk_124, sp00); + for (i = 0; i < MAX_RFU_PLAYERS; i++) + { + for (j = 0; j < CMD_LENGTH - 1; j++) + { + gRecvCmds[i][j] = (sp00[i * 14 + (j << 1) + 1] << 8) | sp00[i * 14 + (j << 1) + 0]; + } + } + sub_800F86C(0); + if (gUnknown_03004140.unk_02 == 0 && gUnknown_03005000.unk_ce4) + { + rfu_REQ_disconnect(gUnknown_03007890->unk_02 | gUnknown_03007890->unk_03); + rfu_waitREQComplete(); + switchval = sub_8011A74(); + if (switchval != 1 && switchval != 6 && switchval != 9) + sub_8011A64(2, 0x9000); + rfu_clearAllSlot(); + gReceivedRemoteLinkPlayers = FALSE; + gUnknown_03005000.unk_00 = 0; + if (gUnknown_03005000.unk_ce4 == 1) + { + sub_8011A64(2, 0x9000); + sub_8011170(0x9000); + } + gUnknown_03004140.unk_04 = gUnknown_03004140.unk_05 = 0; + gUnknown_03005000.unk_ce4 = 0; + } + if (gUnknown_03005000.unk_cd0) + { + gUnknown_03005000.unk_cd0--; + sub_8010528(); + sub_800F498(gSendCmd, sp48); + sub_800D888(&gUnknown_03005000.unk_9e8, sp48); + for (i = 0; i < CMD_LENGTH - 1; i++) + gSendCmd[i] = 0; + } + return sub_800F0B8(); +} + +#ifdef NONMATCHING +void sub_800F638(u8 unused, u32 flags) +{ + int i; + int j; + + u8 *r10 = gUnknown_03005000.unk_6c.unk_04; + for (i = 0; i < gUnknown_03005000.unk_6c.unk_02; i++) + { + if (!(flags & 1)) + { + gUnknown_03000D90[0] = (~0x76ff) | i; + for (j = 0; j < 7; j++) + { + gUnknown_03000D90[j + 1] = (r10[12 * i + (j << 1) + 1] << 8) | r10[12 * i + (j << 1) + 0]; + } + for (j = 0; j < 7; j++) + // This should be an ascending loop. + // GCC compiles this as descending. + { + gUnknown_03000D80[2 * j + 1] = gUnknown_03000D90[j] >> 8; + gUnknown_03000D80[2 * j + 0] = gUnknown_03000D90[j]; + } + sub_800D888(&gUnknown_03005000.unk_9e8, gUnknown_03000D80); + gUnknown_03005000.unk_6c.unk_0c |= (1 << i); + } + flags >>= 1; + } +} +#else +ASM_DIRECT void sub_800F638(u8 unused, u32 flags) +{ + asm_unified("\tpush {r4-r7,lr}\n" + "\tmov r7, r10\n" + "\tmov r6, r9\n" + "\tmov r5, r8\n" + "\tpush {r5-r7}\n" + "\tldr r0, =gUnknown_03005000\n" + "\tldr r2, [r0, 0x70]\n" + "\tmov r10, r2\n" + "\tmovs r5, 0\n" + "\tadds r2, r0, 0\n" + "\tadds r2, 0x6E\n" + "\tldrh r3, [r2]\n" + "\tcmp r5, r3\n" + "\tbge _0800F6D4\n" + "\tmov r9, r0\n" + "\tldr r0, =gUnknown_03000D90\n" + "\tmov r8, r0\n" + "_0800F65A:\n" + "\tmovs r0, 0x1\n" + "\tands r0, r1\n" + "\tlsrs r7, r1, 1\n" + "\tadds r6, r5, 0x1\n" + "\tcmp r0, 0\n" + "\tbne _0800F6C8\n" + "\tldr r1, =0xffff8900\n" + "\tadds r0, r1, 0\n" + "\tadds r1, r5, 0\n" + "\torrs r1, r0\n" + "\tmov r2, r8\n" + "\tstrh r1, [r2]\n" + "\tmovs r4, 0\n" + "\tlsls r0, r5, 1\n" + "\tldr r3, =gUnknown_03000D80\n" + "\tmov r12, r3\n" + "\tadds r0, r5\n" + "\tlsls r0, 2\n" + "\tmov r1, r10\n" + "\tadds r2, r0, r1\n" + "\tmov r3, r8\n" + "\tadds r3, 0x2\n" + "_0800F686:\n" + "\tldrb r1, [r2, 0x1]\n" + "\tlsls r1, 8\n" + "\tldrb r0, [r2]\n" + "\torrs r0, r1\n" + "\tstrh r0, [r3]\n" + "\tadds r2, 0x2\n" + "\tadds r3, 0x2\n" + "\tadds r4, 0x1\n" + "\tcmp r4, 0x6\n" + "\tble _0800F686\n" + "\tmovs r4, 0\n" + "\tldr r2, =gUnknown_03000D90\n" + "\tldr r1, =gUnknown_03000D80\n" + "_0800F6A0:\n" + "\tldrh r0, [r2]\n" + "\tlsrs r0, 8\n" + "\tstrb r0, [r1, 0x1]\n" + "\tldrh r0, [r2]\n" + "\tstrb r0, [r1]\n" + "\tadds r2, 0x2\n" + "\tadds r1, 0x2\n" + "\tadds r4, 0x1\n" + "\tcmp r4, 0x6\n" + "\tble _0800F6A0\n" + "\tldr r0, =gUnknown_03005000+0x9E8\n" + "\tmov r1, r12\n" + "\tbl sub_800D888\n" + "\tmovs r1, 0x1\n" + "\tlsls r1, r5\n" + "\tmov r2, r9\n" + "\tldr r0, [r2, 0x78]\n" + "\torrs r0, r1\n" + "\tstr r0, [r2, 0x78]\n" + "_0800F6C8:\n" + "\tadds r1, r7, 0\n" + "\tadds r5, r6, 0\n" + "\tldr r3, =gUnknown_03005000+0x6E\n" + "\tldrh r3, [r3]\n" + "\tcmp r5, r3\n" + "\tblt _0800F65A\n" + "_0800F6D4:\n" + "\tpop {r3-r5}\n" + "\tmov r8, r3\n" + "\tmov r9, r4\n" + "\tmov r10, r5\n" + "\tpop {r4-r7}\n" + "\tpop {r0}\n" + "\tbx r0\n" + "\t.pool"); +} +#endif + +void sub_800F6FC(u8 a0) +{ + if (gUnknown_03005000.unk_0c == 1 && a0) + gUnknown_03005000.unk_61[a0] = 1; + else + gUnknown_03005000.unk_5c[a0] = 1; +} + +void sub_800F728(u8 a0) +{ + gUnknown_03005000.unk_5c[a0] = 0; + gUnknown_03005000.unk_80[a0].unk_12 = 0; +} + +u8 sub_800F74C(const u8 *a0) +{ + u8 i; + + if (gUnknown_03005000.unk_0c == 1) + return FALSE; + for (i = 0; i < 4; i++) + { + gUnknown_03005000.unk_cde[i] = a0[i]; + } + return a0[gUnknown_03005000.unk_c3e]; +} + +void rfu_func_080F97B8(void) +{ + if (gReceivedRemoteLinkPlayers && gUnknown_03005DA8 && gLinkTransferringData != 1) + { + gUnknown_03000D78[0]++; + gUnknown_03005DA8 |= (gUnknown_03000D78[0] << 8); + sub_800FD14(0xbe00); + } +} + +struct UnkLinkRfuStruct_02022B14 *sub_800F7DC(void) +{ + return &gUnknown_02022B14; +} + +bool32 sub_800F7E4(void) +{ + return gUnknown_03005000.unk_00 == rfu_func_080F97B8; +} + +void sub_800F804(void) +{ + gUnknown_03005000.unk_00 = rfu_func_080F97B8; +} + +void Rfu_set_zero(void) +{ + gUnknown_03005000.unk_00 = NULL; +} + +void sub_800F820(void) +{ + sub_800FD14(0x4400); + if (GetMultiplayerId() == 0) + gSendCmd[6] = GetBlenderArrowPosition(); + gUnknown_020223C0++; +} + +void sub_800F850(void) +{ + if (gUnknown_03005000.unk_00 == NULL) + gUnknown_03005000.unk_00 = sub_800F820; +} + +static void sub_800F86C(u8 unused) +{ + u16 i; + u16 j; + + for (i = 0; i < MAX_RFU_PLAYERS; i++) + { + switch (gRecvCmds[i][0] & 0xff00) + { + case 0x7800: + if (gUnknown_03005000.unk_0c == 0 && gReceivedRemoteLinkPlayers != 0) + return; + // fallthrough + case 0x7700: + if (gUnknown_03007890->unk_00 == 0) + { + gUnknown_03005000.playerCount = gRecvCmds[i][1]; + gUnknown_03005000.unk_cce = sub_800F74C((u8 *)(gRecvCmds[i] + 2)); + } + break; + case 0x8800: + if (gUnknown_03005000.unk_80[i].unk_12 == 0) + { + gUnknown_03005000.unk_80[i].unk_00 = 0; + gUnknown_03005000.unk_80[i].unk_02 = gRecvCmds[i][1]; + gUnknown_03005000.unk_80[i].unk_11 = gRecvCmds[i][2]; + gUnknown_03005000.unk_80[i].unk_08 = 0; + gUnknown_03005000.unk_80[i].unk_12 = 1; + gUnknown_03005000.unk_5c[i] = 0; + } + break; + case 0x8900: + if (gUnknown_03005000.unk_80[i].unk_12 == 1) + { + gUnknown_03005000.unk_80[i].unk_00 = gRecvCmds[i][0] & 0xff; + gUnknown_03005000.unk_80[i].unk_08 |= (1 << gUnknown_03005000.unk_80[i].unk_00); + for (j = 0; j < 6; j++) + gBlockRecvBuffer[i][gUnknown_03005000.unk_80[i].unk_00 * 6 + j] = gRecvCmds[i][j + 1]; + if (gUnknown_03005000.unk_80[i].unk_08 == gUnknown_082ED628[gUnknown_03005000.unk_80[i].unk_02]) + { + gUnknown_03005000.unk_80[i].unk_12 = 2; + sub_800F6FC(i); + if (sub_800F7DC()->unk_0a_0 == 0x45 && gReceivedRemoteLinkPlayers != 0 && gUnknown_03005000.unk_0c == 0) + sub_8010A70(gBlockRecvBuffer); + } + } + break; + case 0xa100: + sub_800FE84(gUnknown_082ED6B8[gRecvCmds[i][1]].buffer, (u16)gUnknown_082ED6B8[gRecvCmds[i][1]].size); + break; + case 0x5f00: + gUnknown_03005000.unk_e4[i] = 1; + break; + case 0x6600: + if (gUnknown_03005000.unk_100 == gRecvCmds[i][1]) + gUnknown_03005000.unk_e9[i] = 1; + break; + case 0xed00: + if (gUnknown_03005000.unk_0c == 0) + { + if (gReceivedRemoteLinkPlayers != 0) + { + if (gRecvCmds[i][1] & gUnknown_03007890->unk_02) + { + gReceivedRemoteLinkPlayers = 0; + sub_800D630(); + gUnknown_03005000.unk_ce4 = gRecvCmds[i][2]; + } + gUnknown_03005000.playerCount = gRecvCmds[i][3]; + sub_80109E8(gRecvCmds[i][1]); + } + } + else + { + sub_800FD14(0xee00); + gSendCmd[1] = gRecvCmds[i][1]; + gSendCmd[2] = gRecvCmds[i][2]; + gSendCmd[3] = gRecvCmds[i][3]; + } + break; + case 0xee00: + if (gUnknown_03005000.unk_0c == 1) + { + gUnknown_03005000.unk_ce3 |= gRecvCmds[i][1]; + gUnknown_03005000.unk_ce4 = gRecvCmds[i][2]; + sub_80109E8(gRecvCmds[i][1]); + } + break; + case 0x4400: + case 0xbe00: + gLinkPartnersHeldKeys[i] = gRecvCmds[i][1]; + break; + } + if (gUnknown_03005000.unk_0c == 1 && gUnknown_03005000.unk_61[i]) + { + if (gUnknown_03005000.unk_61[i] == 4) + { + gUnknown_03005000.unk_5c[i] = 1; + gUnknown_03005000.unk_61[i] = 0; + } + else + gUnknown_03005000.unk_61[i]++; + } + } +} + +bool8 sub_800FC60(void) +{ + int i; + + for (i = 0; i < 5; i++) + { + if (gUnknown_03005000.unk_80[i].unk_12) + return FALSE; + } + return TRUE; +} + +bool8 sub_800FC88(void) +{ + int i; + + for (i = 0; i < gUnknown_03005000.playerCount; i++) + { + if (gUnknown_03005000.unk_80[i].unk_12 != 2 || gUnknown_03005000.unk_5c[i] != 1) + return FALSE; + } + return TRUE; +} + +static void sub_800FCC4(struct UnkRfuStruct_2_Sub_6c *data) +{ + data->unk_00 = 0; + data->unk_02 = 0; + data->unk_04 = NULL; + data->unk_08 = 0; + data->unk_10 = 0; + data->unk_11 = 0; + data->unk_12 = 0; +} + +u8 sub_800FCD8(void) +{ + u8 flags = 0; + int i; + + for (i = 0; i < 5; i++) + { + if (gUnknown_03005000.unk_80[i].unk_12 == 2 && gUnknown_03005000.unk_5c[i] == 1) + { + flags |= (1 << i); + } + } + return flags; +} + +#ifdef NONMATCHING +// The switch tree is incorrect +void sub_800FD14(u16 command) +{ + u8 i; + u8 *buff; + u8 tmp; + + gSendCmd[0] = command; + switch (command) + { + case 0x8800: + gSendCmd[1] = gUnknown_03005000.unk_6c.unk_02; + gSendCmd[2] = gUnknown_03005000.unk_6c.unk_11 + 0x80; + break; + case 0xa100: + if (sub_800FC60()) + gSendCmd[1] = gUnknown_03005000.unk_5a; + break; + case 0x7800: + case 0x7700: + tmp = gUnknown_03005000.unk_ce2 ^ gUnknown_03005000.unk_ce3; + gUnknown_03005000.playerCount = gUnknown_082ED695[tmp] + 1; + gSendCmd[1] = gUnknown_03005000.playerCount; + buff = (u8 *)(gSendCmd + 2); + for (i = 0; i < 4; i++) + buff[i] = gUnknown_03005000.unk_cde[i]; + break; + case 0x6600: + case 0x5f00: + gSendCmd[1] = gUnknown_03005000.unk_100; + break; + case 0x4400: + gSendCmd[0] = 0x4400; + gSendCmd[1] = gMain.heldKeys; + break; + case 0x2f00: + for (i = 0; i < 6; i++) + gSendCmd[1 + i] = gUnknown_03005000.unk_f2[i]; + break; + case 0xbe00: + gSendCmd[1] = gUnknown_03005DA8; + break; + } +} +#else +ASM_DIRECT void sub_800FD14(u16 command) +{ + asm_unified("\tpush {r4,r5,lr}\n" + "\tlsls r0, 16\n" + "\tlsrs r1, r0, 16\n" + "\tldr r5, =gSendCmd\n" + "\tstrh r1, [r5]\n" + "\tmovs r0, 0xF0\n" + "\tlsls r0, 7\n" + "\tadds r4, r5, 0\n" + "\tcmp r1, r0\n" + "\tbeq _0800FDB0_case_7700_case_7800\n" + "\tcmp r1, r0\n" + "\tbgt _0800FD62\n" + "\tmovs r0, 0xBE\n" + "\tlsls r0, 7\n" + "\tcmp r1, r0\n" + "\tbeq _0800FE00_case_5f00_case_6600\n" + "\tcmp r1, r0\n" + "\tbgt _0800FD50\n" + "\tmovs r0, 0xBC\n" + "\tlsls r0, 6\n" + "\tcmp r1, r0\n" + "\tbeq _0800FE20_case_2f00\n" + "\tmovs r0, 0x88\n" + "\tlsls r0, 7\n" + "\tcmp r1, r0\n" + "\tbeq _0800FE14_case_4400\n" + "\tb _0800FE46_break\n" + "\t.pool\n" + "_0800FD50:\n" + "\tmovs r0, 0xCC\n" + "\tlsls r0, 7\n" + "\tcmp r1, r0\n" + "\tbeq _0800FE00_case_5f00_case_6600\n" + "\tmovs r0, 0xEE\n" + "\tlsls r0, 7\n" + "\tcmp r1, r0\n" + "\tbeq _0800FDB0_case_7700_case_7800\n" + "\tb _0800FE46_break\n" + "_0800FD62:\n" + "\tmovs r0, 0xBE\n" + "\tlsls r0, 8\n" + "\tcmp r1, r0\n" + "\tbeq _0800FE40_case_be00\n" + "\tcmp r1, r0\n" + "\tbgt _0800FE46_break\n" + "\tmovs r0, 0x88\n" + "\tlsls r0, 8\n" + "\tcmp r1, r0\n" + "\tbeq _0800FD80_case_8800\n" + "\tmovs r0, 0xA1\n" + "\tlsls r0, 8\n" + "\tcmp r1, r0\n" + "\tbeq _0800FD98_case_a100\n" + "\tb _0800FE46_break\n" + "_0800FD80_case_8800:\n" + "\tldr r0, =gUnknown_03005000\n" + "\tadds r1, r0, 0\n" + "\tadds r1, 0x6E\n" + "\tldrh r1, [r1]\n" + "\tstrh r1, [r5, 0x2]\n" + "\tadds r0, 0x7D\n" + "\tldrb r0, [r0]\n" + "\tadds r0, 0x80\n" + "\tstrh r0, [r5, 0x4]\n" + "\tb _0800FE46_break\n" + "\t.pool\n" + "_0800FD98_case_a100:\n" + "\tbl sub_800FC60\n" + "\tlsls r0, 24\n" + "\tcmp r0, 0\n" + "\tbeq _0800FE46_break\n" + "\tldr r0, =gUnknown_03005000\n" + "\tadds r0, 0x5A\n" + "\tldrb r0, [r0]\n" + "\tb _0800FE44_str_break\n" + "\t.pool\n" + "_0800FDB0_case_7700_case_7800:\n" + "\tldr r3, =gUnknown_03005000\n" + "\tldr r1, =0x00000ce2\n" + "\tadds r0, r3, r1\n" + "\tldr r2, =0x00000ce3\n" + "\tadds r1, r3, r2\n" + "\tldrb r2, [r0]\n" + "\tldrb r0, [r1]\n" + "\teors r0, r2\n" + "\tldr r1, =gUnknown_082ED695\n" + "\tadds r0, r1\n" + "\tldrb r0, [r0]\n" + "\tadds r0, 0x1\n" + "\tstrb r0, [r3, 0xD]\n" + "\tldrb r0, [r3, 0xD]\n" + "\tstrh r0, [r4, 0x2]\n" + "\tadds r2, r4, 0x4\n" + "\tmovs r4, 0\n" + "\tldr r0, =0x00000cde\n" + "\tadds r3, r0\n" + "_0800FDD6:\n" + "\tadds r1, r2, r4\n" + "\tadds r0, r4, r3\n" + "\tldrb r0, [r0]\n" + "\tstrb r0, [r1]\n" + "\tadds r0, r4, 0x1\n" + "\tlsls r0, 24\n" + "\tlsrs r4, r0, 24\n" + "\tcmp r4, 0x3\n" + "\tbls _0800FDD6\n" + "\tb _0800FE46_break\n" + "\t.pool\n" + "_0800FE00_case_5f00_case_6600:\n" + "\tldr r0, =gUnknown_03005000\n" + "\tmovs r1, 0x80\n" + "\tlsls r1, 1\n" + "\tadds r0, r1\n" + "\tldrh r0, [r0]\n" + "\tstrh r0, [r4, 0x2]\n" + "\tb _0800FE46_break\n" + "\t.pool\n" + "_0800FE14_case_4400:\n" + "\tstrh r1, [r5]\n" + "\tldr r0, =gMain\n" + "\tldrh r0, [r0, 0x2C]\n" + "\tb _0800FE44_str_break\n" + "\t.pool\n" + "_0800FE20_case_2f00:\n" + "\tmovs r4, 0\n" + "\tldr r3, =gUnknown_03005000+0xF2\n" + "_0800FE24:\n" + "\tadds r2, r4, 0x1\n" + "\tlsls r1, r2, 1\n" + "\tadds r1, r5\n" + "\tlsls r0, r4, 1\n" + "\tadds r0, r3\n" + "\tldrh r0, [r0]\n" + "\tstrh r0, [r1]\n" + "\tlsls r2, 24\n" + "\tlsrs r4, r2, 24\n" + "\tcmp r4, 0x5\n" + "\tbls _0800FE24\n" + "\tb _0800FE46_break\n" + "\t.pool\n" + "_0800FE40_case_be00:\n" + "\tldr r0, =gUnknown_03005DA8\n" + "\tldrh r0, [r0]\n" + "_0800FE44_str_break:\n" + "\tstrh r0, [r5, 0x2]\n" + "_0800FE46_break:\n" + "\tpop {r4,r5}\n" + "\tpop {r0}\n" + "\tbx r0\n" + "\t.pool"); +} +#endif + +void sub_800FE50(u16 *a0) +{ + if (gSendCmd[0] == 0 && sub_8011A80() == 0) + { + memcpy(gUnknown_03005000.unk_f2, a0, sizeof(gUnknown_03005000.unk_f2)); + sub_800FD14(0x2f00); + } +} + +bool32 sub_800FE84(const u8 *src, size_t size) +{ + bool8 r4; + if (gUnknown_03005000.unk_00 != NULL) + return FALSE; + if (gSendCmd[0] != 0) + return FALSE; + if (gUnknown_03005000.unk_6c.unk_10 != 0) + { + gUnknown_02022B44.unk_83++; + return FALSE; + } + r4 = (size % 12) != 0; + gUnknown_03005000.unk_6c.unk_11 = GetMultiplayerId(); + gUnknown_03005000.unk_6c.unk_10 = 1; + gUnknown_03005000.unk_6c.unk_02 = (size / 12) + r4; + gUnknown_03005000.unk_6c.unk_00 = 0; + if (size > 0x100) + gUnknown_03005000.unk_6c.unk_04 = src; + else + { + if (src != gBlockSendBuffer) + memcpy(gBlockSendBuffer, src, size); + gUnknown_03005000.unk_6c.unk_04 = gBlockSendBuffer; + } + sub_800FD14(0x8800); + gUnknown_03005000.unk_00 = rfufunc_80F9F44; + gUnknown_03005000.unk_5b = 0; + return TRUE; +} + +static void rfufunc_80F9F44(void) +{ + if (gSendCmd[0] == 0) + { + sub_800FD14(0x8800); + if (gUnknown_03005000.unk_0c == 1) + { + if (++gUnknown_03005000.unk_5b > 2) + gUnknown_03005000.unk_00 = sub_800FFB0; + } + else + { + if ((gRecvCmds[GetMultiplayerId()][0] & 0xff00) == 0x8800) + gUnknown_03005000.unk_00 = sub_800FFB0; + } + } +} + +static void sub_800FFB0(void) +{ + int i; + const u8 *src = gUnknown_03005000.unk_6c.unk_04; + gSendCmd[0] = 0x8900 | gUnknown_03005000.unk_6c.unk_00; + for (i = 0; i < 7; i++) + gSendCmd[i + 1] = (src[(i << 1) + gUnknown_03005000.unk_6c.unk_00 * 12 + 1] << 8) | src[(i << 1) + gUnknown_03005000.unk_6c.unk_00 * 12 + 0]; + gUnknown_03005000.unk_6c.unk_00++; + if (gUnknown_03005000.unk_6c.unk_02 <= gUnknown_03005000.unk_6c.unk_00) + { + gUnknown_03005000.unk_6c.unk_10 = 0; + gUnknown_03005000.unk_00 = rfufunc_80FA020; + } +} + +static void rfufunc_80FA020(void) +{ + const u8 *src = gUnknown_03005000.unk_6c.unk_04; + u8 mpId = GetMultiplayerId(); + int i; + if (gUnknown_03005000.unk_0c == 0) + { + gSendCmd[0] = (~0x76ff) | (gUnknown_03005000.unk_6c.unk_02 - 1); + for (i = 0; i < 7; i++) + gSendCmd[i + 1] = (src[(i << 1) + (gUnknown_03005000.unk_6c.unk_02 - 1) * 12 + 1] << 8) | src[(i << 1) + (gUnknown_03005000.unk_6c.unk_02 - 1) * 12 + 0]; + if ((u8)gRecvCmds[mpId][0] == gUnknown_03005000.unk_6c.unk_02 - 1) + { + if (gUnknown_03005000.unk_80[mpId].unk_08 != gUnknown_082ED628[gUnknown_03005000.unk_80[mpId].unk_02]) + { + sub_800F638(mpId, gUnknown_03005000.unk_80[mpId].unk_08); + gUnknown_02022B44.unk_64++; + } + else + gUnknown_03005000.unk_00 = NULL; + } + } + else + gUnknown_03005000.unk_00 = NULL; +} + +bool8 sub_8010100(u8 a0) +{ + gUnknown_03005000.unk_5a = a0; + sub_800FD14(0xa100); + return TRUE; +} + +void sub_801011C(void) +{ + rfu_clearAllSlot(); + sub_800C048(); + gReceivedRemoteLinkPlayers = 0; + gUnknown_03005000.unk_ef = 1; + gUnknown_03005000.unk_00 = NULL; +} + +void sub_8010148(void) +{ + rfu_REQ_disconnect(gUnknown_03007890->unk_02 | gUnknown_03007890->unk_03); + rfu_waitREQComplete(); + sub_801011C(); +} + +void sub_8010168(void) +{ + if (gUnknown_03005000.unk_0c == 0) + { + sub_800D630(); + gUnknown_03005000.unk_ce4 = 2; + } + else + gUnknown_03005000.unk_00 = sub_8010148; +} + +void sub_8010198(void) +{ + sub_800D630(); + gUnknown_03005000.unk_ce4 = 1; + gUnknown_03005000.unk_ce3 = gUnknown_03007890->unk_02 | gUnknown_03007890->unk_03; +} + +void sub_80101CC(void) +{ + int i; + u8 playerCount = gUnknown_03005000.playerCount; + int count = 0; + + for (i = 0; i < MAX_RFU_PLAYERS; i++) + { + if (gUnknown_03005000.unk_e4[i]) + count++; + } + if (count == playerCount) + { + gBattleTypeFlags &= ~BATTLE_TYPE_20; + if (gUnknown_03005000.unk_0c == 0) + { + gUnknown_03005000.unk_ee = 3; + sub_8010168(); + } + else + gUnknown_03005000.unk_00 = sub_8010168; + } +} + +void sub_801022C(void) +{ + if (gSendCmd[0] == 0 && gUnknown_03005000.unk_ce8 == 0) + { + sub_800FD14(0x5f00); + gUnknown_03005000.unk_00 = sub_80101CC; + } +} + +void sub_8010264(u8 taskId) +{ + if (gUnknown_03005000.unk_00 == NULL) + { + gUnknown_03005000.unk_cd9 = 1; + gUnknown_03005000.unk_00 = sub_801022C; + DestroyTask(taskId); + } +} + +void task_add_05_task_del_08FA224_when_no_RfuFunc(void) +{ + if (!FuncIsActiveTask(sub_8010264)) + CreateTask(sub_8010264, 5); +} + +void sub_80102B8(void) +{ + u8 playerCount; + u8 i; + + if (GetMultiplayerId() != 0) + { + u8 r4 = gUnknown_03005000.unk_124.unk_8c2; + if (r4 == 0 && gUnknown_03005000.unk_fe > 0x3c) + { + sub_800FD14(0x6600); + gUnknown_03005000.unk_fe = r4; + } + } + playerCount = GetLinkPlayerCount(); + for (i = 0; i < playerCount; i++) + { + if (gUnknown_03005000.unk_e9[i] == 0) + break; + } + if (i == playerCount) + { + for (i = 0; i < MAX_RFU_PLAYERS; i++) + gUnknown_03005000.unk_e9[i] = 0; + gUnknown_03005000.unk_100++; + gUnknown_03005000.unk_00 = NULL; + } + gUnknown_03005000.unk_fe++; +} + +void sub_8010358(void) +{ + if (gUnknown_03005000.unk_124.unk_8c2 == 0 && gSendCmd[0] == 0) + { + sub_800FD14(0x6600); + gUnknown_03005000.unk_00 = sub_80102B8; + } +} + +void sub_8010390(void) +{ + u8 i; + u8 playerCount; + + if (GetMultiplayerId() != 0) + { + if (gUnknown_03005000.unk_124.unk_8c2 == 0 && gSendCmd[0] == 0) + { + sub_800FD14(0x6600); + gUnknown_03005000.unk_00 = sub_80102B8; + } + } + else + { + playerCount = GetLinkPlayerCount(); + for (i = 1; i < playerCount; i++) + { + if (gUnknown_03005000.unk_e9[i] == 0) + break; + } + if (i == playerCount) + { + if (gUnknown_03005000.unk_124.unk_8c2 == 0 && gSendCmd[0] == 0) + { + sub_800FD14(0x6600); + gUnknown_03005000.unk_00 = sub_8010358; + } + } + } +} + +void sub_8010434(void) +{ + if (gUnknown_03005000.unk_00 == NULL) + { + gUnknown_03005000.unk_00 = sub_8010390; + gUnknown_03005000.unk_fe = 0; + } +} + +bool32 sub_8010454(u32 a0) +{ + int i; + for (i = 0; gUnknown_082ED6E0[i] != a0; i++) + { + if (gUnknown_082ED6E0[i] == 0xffff) + return FALSE; + } + return TRUE; +} + +u8 sub_801048C(bool32 a0) +{ + if (a0 == 0) + return sub_800D550(0, 0); + sub_800D550(1, 0x258); + return FALSE; +} + +void sub_80104B0(void) +{ + gUnknown_03005000.unk_cd9 = 1; + sub_800C27C(FALSE); +} + +u8 rfu_get_multiplayer_id(void) +{ + if (gUnknown_03005000.unk_0c == 1) + return 0; + return gUnknown_03005000.unk_cce; +} + +u8 sub_80104F4(void) +{ + return gUnknown_03005000.playerCount; +} + +bool8 sub_8010500(void) +{ + if (gUnknown_03005000.unk_f1 == 2) + return FALSE; + return gUnknown_03005000.unk_00 ? FALSE : TRUE; +} + +static void sub_8010528(void) +{ + if (gUnknown_03005000.unk_00) + gUnknown_03005000.unk_00(); +} + +bool8 sub_8010540(void) +{ + int i; + bool8 retval = FALSE; + for (i = 0; i < 4; i++) + { + if (gUnknown_03005000.unk_cd1[i] < 5 || gUnknown_03005000.unk_cd1[i] > 6) + { + if (gUnknown_03007880[i]->unk_34 == 0x46 || gUnknown_03007880[i]->unk_34 == 0x48) + { + if (gUnknown_03005000.unk_cd5[i] == 8) + { + gUnknown_03005000.unk_cd1[i] = 9; + gUnknown_03005000.unk_cd5[i] = 10; + rfu_clearSlot(8, i); + rfu_NI_setSendData(1 << i, 8, gUnknown_03005000.unk_cd1 + i, 1); + retval = TRUE; + } + + } + else if (gUnknown_03007880[gUnknown_03005000.unk_c3e]->unk_34 == 0x47) + rfu_clearSlot(8, i); + { + + } + } + } + return retval; +} + +bool8 sub_80105EC(void) +{ + u8 flags = 0; + int i; + for (i = 0; i < 4; i++) + { + if (gUnknown_03005000.unk_cd5[i] == 11) + { + flags |= (1 << i); + gUnknown_03005000.unk_cd5[i] = 0; + } + } + if (flags) + { + rfu_REQ_disconnect(flags); + rfu_waitREQComplete(); + } + for (i = 0; i < 4; i++) + { + if (gUnknown_03005000.unk_cd5[i] == 10 || gUnknown_03005000.unk_cd5[i] == 11) + return TRUE; + } + return FALSE; +} + +bool8 sub_801064C(u16 a0, const u8 *a1) +{ + u8 r1 = sub_8011CE4(a1, a0); + if (r1 == 0xFF) + return TRUE; + if (gUnknown_03005000.unk_cd1[r1] == 9) + return TRUE; + return FALSE; +} + +void sub_8010688(u8 a0, u16 a1, const u8 *a2) +{ + u8 r4 = sub_8011CE4(a2, a1); + gUnknown_03005000.unk_cd1[r4] = a0; + rfu_clearSlot(4, r4); + rfu_NI_setSendData(1 << r4, 8, gUnknown_03005000.unk_cd1 + r4, 1); +} + +void sub_80106D4(void) +{ + gUnknown_03005000.unk_c85 = 8; + rfu_clearSlot(4, gUnknown_03005000.unk_c3e); + rfu_NI_setSendData(1 << gUnknown_03005000.unk_c3e, 8, &gUnknown_03005000.unk_c85, 1); +} + +u8 sub_8010714(u16 a0, const u8 *a1) +{ + u8 r0 = sub_8011CE4(a1, a0); + if (r0 == 0xff) + return 2; + if (gUnknown_03007880[r0]->unk_0 == 0) + return TRUE; + return FALSE; +} + +void sub_8010750(void) +{ + int i; + + sub_8010540(); + for (i = 0; i < 4; i++) + { + if (gUnknown_03007880[i]->unk_0 == 0x26 || gUnknown_03007880[i]->unk_0 == 0x27) + { + if (gUnknown_03005000.unk_cd5[i] == 10) + gUnknown_03005000.unk_cd5[i] = 11; + rfu_clearSlot(4, i); + } + } +} + +int sub_80107A0(void) +{ + int retval = 0; + if (gUnknown_03005000.unk_c85 == 8) + { + if (gUnknown_03007880[gUnknown_03005000.unk_c3e]->unk_0 == 0x26 || gUnknown_03007880[gUnknown_03005000.unk_c3e]->unk_0 == 0x27) + rfu_clearSlot(4, gUnknown_03005000.unk_c3e); + } + if (gUnknown_03007880[gUnknown_03005000.unk_c3e]->unk_34 == 0x46 || gUnknown_03007880[gUnknown_03005000.unk_c3e]->unk_34 == 0x48) + { + rfu_clearSlot(8, gUnknown_03005000.unk_c3e); + sub_8011A64(gUnknown_03005000.unk_c86, 0); + retval = gUnknown_03005000.unk_c86; + } + else if (gUnknown_03007880[gUnknown_03005000.unk_c3e]->unk_34 == 0x47) + { + rfu_clearSlot(8, gUnknown_03005000.unk_c3e); + retval = 6; + } + return retval; +} + +void sub_801084C(u8 taskId) +{ + int i; + + if (gUnknown_03005000.unk_f1 == 1 || gUnknown_03005000.unk_f1 == 2) + { + gUnknown_03005000.unk_ce8 = 0; + DestroyTask(taskId); + } + switch (gTasks[taskId].data[0]) + { + case 0: + if (sub_800FC60()) + { + ResetBlockReceivedFlags(); + sub_800B348(); + gTasks[taskId].data[0]++; + } + break; + case 1: + if (gUnknown_03005000.unk_0c == 1) + { + if (gReceivedRemoteLinkPlayers) + sub_800FD14(0x7800); + else + sub_800FD14(0x7700); + gTasks[taskId].data[0] = 101; + } + else + gTasks[taskId].data[0] = 2; + break; + case 101: + if (gSendCmd[0] == 0) + gTasks[taskId].data[0] = 2; + break; + case 2: + if (gUnknown_03005000.playerCount) + gTasks[taskId].data[0]++; + break; + case 3: + if (gUnknown_03005000.unk_0c == 1) + { + if (sub_800FC60()) + { + gUnknown_03005000.unk_5a = 0; + sub_800FD14(0xa100); + gTasks[taskId].data[0]++; + } + } + else + gTasks[taskId].data[0]++; + break; + case 4: + if (sub_800FC88()) + gTasks[taskId].data[0]++; + break; + case 5: + for (i = 0; i < gUnknown_03005000.playerCount; i++) + { + sub_800B3A4(i); + sub_800F728(i); + } + gTasks[taskId].data[0]++; + break; + case 6: + DestroyTask(taskId); + gReceivedRemoteLinkPlayers = 1; + gUnknown_03005000.unk_ce8 = 0; + sub_800D550(1, 0x258); + if (gUnknown_03005000.unk_ce6) + { + for (i = 0; i < 4; i++) + { + if ((gUnknown_03005000.unk_ce6 >> i) & 1) + { + gUnknown_03005000.unk_ce5 = 1 << i; + gUnknown_03005000.unk_ce6 ^= (1 << i); + } + } + } + break; + } +} + +void sub_80109E8(u16 a0) +{ + int i; + + for (i = 0; i < 4; i++) + { + if ((a0 >> i) & 1) + gUnknown_03005000.unk_cde[i] = 0; + } +} + +void sub_8010A14(const struct UnkRfuStruct_8010A14 *a0) +{ + int i; + gUnknown_03005000.playerCount = a0->unk_0f; + for (i = 0; i < 4; i++) + gUnknown_03005000.unk_cde[i] = a0->unk_10[i]; + for (i = 0; i < MAX_RFU_PLAYERS; i++) + { + gLinkPlayers[i] = a0->unk_14[i]; + sub_800B524(gLinkPlayers + i); + } +} + +void sub_8010A70(void *a0) +{ + if (strcmp(gUnknown_082ED7EC, a0) == 0) + { + sub_8010A14(a0); + CpuFill16(0, a0, sizeof(struct UnkRfuStruct_8010A14)); + ResetBlockReceivedFlag(0); + } +} + +void sub_8010AAC(u8 taskId) +{ + int i; + struct LinkPlayerBlock *r2; + struct UnkRfuStruct_8010A14 *r5; + u8 r4 = gUnknown_03005000.unk_cde[gUnknown_082ED68C[gUnknown_03005000.unk_ce9]]; + if (gUnknown_03005000.unk_f1 == 1 || gUnknown_03005000.unk_f1 == 2) + { + gUnknown_03005000.unk_ce8 = 0; + DestroyTask(taskId); + } + switch (gTasks[taskId].data[0]) + { + case 0: + if (gSendCmd[0] == 0) + { + ResetBlockReceivedFlag(r4); + sub_800FD14(0x7800); + gTasks[taskId].data[0]++; + } + break; + case 1: + if (gSendCmd[0] == 0) + gTasks[taskId].data[0]++; + break; + case 2: + if ((GetBlockReceivedStatus() >> r4) & 1) + { + ResetBlockReceivedFlag(r4); + r2 = (struct LinkPlayerBlock *)gBlockRecvBuffer[r4]; + gLinkPlayers[r4] = r2->linkPlayer; + sub_800B524(gLinkPlayers + r4); + gTasks[taskId].data[0]++; + } + break; + case 3: + r5 = (struct UnkRfuStruct_8010A14 *)gBlockSendBuffer; + memcpy(r5->unk_00, gUnknown_082ED7EC, sizeof gUnknown_082ED7EC); + r5->unk_0f = gUnknown_03005000.playerCount; + for (i = 0; i < 4; i++) + r5->unk_10[i] = gUnknown_03005000.unk_cde[i]; + memcpy(r5->unk_14, gLinkPlayers, sizeof gLinkPlayers); + gTasks[taskId].data[0]++; + // fallthrough + case 4: + r5 = (struct UnkRfuStruct_8010A14 *)gBlockSendBuffer; + r5->unk_0f = gUnknown_03005000.playerCount; + for (i = 0; i < 4; i++) + r5->unk_10[i] = gUnknown_03005000.unk_cde[i]; + memcpy(r5->unk_14, gLinkPlayers, sizeof gLinkPlayers); + if (SendBlock(0, gBlockSendBuffer, 0xa0)) + gTasks[taskId].data[0]++; + break; + case 5: + if (sub_800A520() && GetBlockReceivedStatus() & 1) + { + CpuFill16(0, gBlockRecvBuffer, sizeof(struct UnkRfuStruct_8010A14)); + ResetBlockReceivedFlag(0); + gUnknown_03005000.unk_ce8 = 0; + if (gUnknown_03005000.unk_ce6) + { + for (i = 0; i < 4; i++) + { + if ((gUnknown_03005000.unk_ce6 >> i) & 1) + { + gUnknown_03005000.unk_ce5 = 1 << i; + gUnknown_03005000.unk_ce6 ^= (1 << i); + gUnknown_03005000.unk_ce8 = 1; + break; + } + } + } + DestroyTask(taskId); + } + break; + } +} + +void sub_8010D0C(u8 taskId) +{ + if (gUnknown_03005000.unk_f1 == 1 || gUnknown_03005000.unk_f1 == 2) + DestroyTask(taskId); + switch (gTasks[taskId].data[0]) + { + case 0: + if (gUnknown_03005000.playerCount) + { + sub_800B348(); + SendBlock(0, gBlockSendBuffer, sizeof(struct LinkPlayerBlock)); + gTasks[taskId].data[0]++; + } + break; + case 1: + if (sub_800A520()) + gTasks[taskId].data[0]++; + break; + case 2: + if (GetBlockReceivedStatus() & 1) + { + sub_8010A14((const struct UnkRfuStruct_8010A14 *)gBlockRecvBuffer); + ResetBlockReceivedFlag(0); + gReceivedRemoteLinkPlayers = 1; + DestroyTask(taskId); + } + break; + } +} + +void sub_8010DB4(void) +{ + if (gUnknown_03005000.unk_ee == 1 && gUnknown_03004140.unk_02 == 0) + { + if (gMain.callback2 == sub_8018438 || gUnknown_03004140.unk_3c->unk_04) + gWirelessCommType = 2; + SetMainCallback2(CB2_LinkError); + gMain.savedCallback = CB2_LinkError; + sub_800AF18((gUnknown_03005000.unk_0a << 16) | (gUnknown_03005000.unk_10 << 8) | gUnknown_03005000.unk_12, gUnknown_03005000.unk_124.unk_8c2, gUnknown_03005000.unk_9e8.unk_232, sub_8011A74() == 2); + gUnknown_03005000.unk_ee = 2; + CloseLink(); + } + else if (gUnknown_03005000.unk_9e8.unk_233 == 1 || gUnknown_03005000.unk_124.unk_8c3 == 1) + { + if (gUnknown_03004140.unk_02) + sub_800D630(); + sub_8011A64(1, 0x7000); + sub_8011170(0x7000); + } +} + +void rfu_REQ_recvData_then_sendData(void) +{ + if (gUnknown_03004140.unk_06 == 1) + { + rfu_REQ_recvData(); + rfu_waitREQComplete(); + rfu_REQ_sendData_wrapper(0); + } +} + +bool32 sub_8010EC0(void) +{ + bool32 retval = FALSE; + gUnknown_03005000.unk_ccd = 0; + sub_800C54C(Random2()); + if (gUnknown_03005000.unk_ef == 0) + { + switch (gUnknown_03005000.unk_0c) + { + case 1: + sub_800F0F8(); + break; + case 0: + retval = sub_800F4F0(); + break; + case 2: + rfu_REQ_recvData_then_sendData(); + break; + } + } + return retval; +} + +bool32 sub_8010F1C(void) +{ + bool32 retval = FALSE; + if (gUnknown_03005000.unk_ef == 0) + { + if (gUnknown_03005000.unk_0c == 1) + retval = sub_800F1E0(); + sub_8010DB4(); + } + return retval; +} + +void sub_8010F48(void) +{ + StringCopy(gUnknown_02022B22, gSaveBlock2Ptr->playerName); +} + +void sub_8010F60(void) +{ + gUnknown_02022B14 = (struct UnkLinkRfuStruct_02022B14){}; + sub_800DD94(&gUnknown_02022B14, 0, 0, 0); +} + +void sub_8010F84(u8 a0, u32 a1, u32 a2) +{ + sub_800DD94(&gUnknown_02022B14, a0, a2, a1); +} + +void sub_8010FA0(bool32 a0, bool32 a1) +{ + gUnknown_02022B14.unk_00_4 = a0; + gUnknown_02022B14.unk_00_5 = a1; +} + +void sub_8010FCC(u32 a0, u32 a1, u32 a2) +{ + gUnknown_02022B14.unk_09_2 = a0; + gUnknown_02022B14.unk_08_0 = a1; + gUnknown_02022B14.unk_0b_1 = a2; +} + +u8 sub_801100C(int a0) +{ + u8 retval = 0x80; + retval |= (gLinkPlayers[a0].gender << 3); + retval |= (gLinkPlayers[a0].trainerId & 7); + return retval; +} + +void sub_801103C(void) +{ + struct UnkLinkRfuStruct_02022B14 *r5 = &gUnknown_02022B14; + int i; + + for (i = 1; i < GetLinkPlayerCount(); i++) + r5->unk_04[i - 1] = sub_801100C(i); +} + +void sub_8011068(u8 a0) +{ + gUnknown_02022B14.unk_0a_7 = a0; + rfu_REQ_configGameData(0, 2, &gUnknown_02022B14, gUnknown_02022B22); +} + +void sub_8011090(u8 a0, u32 a1, u32 a2) +{ + if (a0) + sub_8010F84(a0, a1, a2); + rfu_REQ_configGameData(0, 2, &gUnknown_02022B14, gUnknown_02022B22); +} + +void sub_80110B8(u32 a0) +{ + int i; + u32 r5; + u32 r7; + int r8; + + if (sub_800F7DC()->unk_0a_0 == 0x45) + { + r5 = 0; + r7 = 0; + r8 = gUnknown_03005000.unk_ce2 ^ gUnknown_03005000.unk_ce3; + for (i = 0; i < 4; i++) + { + if ((r8 >> i) & 1) + { + r7 |= ((0x80 | ((gLinkPlayers[gUnknown_03005000.unk_cde[i]].gender & 1) << 3) | (gLinkPlayers[gUnknown_03005000.unk_cde[i]].trainerId & 7)) << (r5 << 3)); + r5++; + if (r5 == a0 - 1) + break; + } + } + sub_8011090(0x45, r7, 0); + } +} + +void sub_8011170(u32 a0) +{ + if (gUnknown_03005000.unk_ee == 0) + { + gUnknown_03005000.unk_10 = gUnknown_03004140.unk_14; + gUnknown_03005000.unk_12 = gUnknown_03004140.unk_16; + gUnknown_03005000.unk_0a = a0; + gUnknown_03005000.unk_ee = 1; + } +} + +void sub_80111A0(void) +{ + gUnknown_03005000.unk_ee = 0; +} + +void sub_80111B0(bool32 a0) +{ + if (!a0) + gUnknown_03005000.unk_ee = 0; + else + gUnknown_03005000.unk_ee = 4; +} + +void sub_80111DC(void) +{ + sub_8011E94(gUnknown_03004140.unk_00, 1); + gUnknown_03005000.unk_00 = NULL; +} + +void sub_80111FC(void) +{ + gUnknown_03005000.unk_00 = sub_80111DC; +} + +#ifdef NONMATCHING +void sub_801120C(u8 a0) +{ + u8 i; + u8 r6 = 0; + struct RfuUnk5Sub *unk5Sub; + switch (a0) + { + case 0x00: + gUnknown_03005000.unk_04 = 2; + break; + case 0x10: + break; + case 0x11: + sub_80115EC(gUnknown_03004140.unk_14); + for (i = 0; i < 4; i++) + { + if ((gUnknown_03004140.unk_14 >> i) & 1) + { + unk5Sub = &gUnknown_03007890->unk_14[i]; + if (unk5Sub->unk_06.unk_0a_0 == sub_800F7DC()->unk_0a_0) + { + gUnknown_03005000.unk_cd1[i] = 0; + gUnknown_03005000.unk_cd5[i] = 0; + rfu_setRecvBuffer(0x20, i, gUnknown_03005000.unk_cd5 + i, 1); + } + else + { + r6 |= (1 << i); + } + } + } + if (r6) + { + rfu_REQ_disconnect(r6); + rfu_waitREQComplete(); + } + break; + case 0x12: + break; + case 0x13: + break; + case 0x14: + if (gUnknown_03005000.unk_ce7 != gUnknown_03004140.unk_00) + { + rfu_REQ_disconnect(gUnknown_03005000.unk_ce7 ^ gUnknown_03004140.unk_00); + rfu_waitREQComplete(); + } + gUnknown_03005000.unk_04 = 0x11; + break; + case 0x31: + gUnknown_03005000.unk_f0 = 1; + break; + case 0x32: + gUnknown_03005000.unk_f0 = 3; + break; + case 0x30: + case 0x33: + gUnknown_03005000.unk_f0 = 4; + gUnknown_03005000.unk_ce2 &= ~gUnknown_03004140.unk_14; + if (gReceivedRemoteLinkPlayers == 1) + { + if (gUnknown_03005000.unk_ce2 == 0) + sub_8011170(a0); + else + sub_80111FC(); + } + sub_8011A64(2, a0); + break; + case 0x42 ... 0x44: + break; + case 0xf3: + sub_8011A64(1, a0); + sub_8011170(a0); + gUnknown_03005000.unk_ef = 1; + break; + case 0xf0 ... 0xf2: + case 0xff: + sub_8011170(a0); + sub_8011A64(1, a0); + gUnknown_03005000.unk_cdb = 1; + break; + } +} +#else +ASM_DIRECT void sub_801120C(u8 a0) +{ + asm_unified("\tpush {r4-r7,lr}\n" + "\tmov r7, r10\n" + "\tmov r6, r9\n" + "\tmov r5, r8\n" + "\tpush {r5-r7}\n" + "\tlsls r0, 24\n" + "\tlsrs r4, r0, 24\n" + "\tmovs r6, 0\n" + "\tcmp r4, 0x32\n" + "\tbne _08011222\n" + "\tb _08011360_case_32\n" + "_08011222:\n" + "\tcmp r4, 0x32\n" + "\tbgt _08011252\n" + "\tcmp r4, 0x13\n" + "\tbgt _08011240\n" + "\tcmp r4, 0x12\n" + "\tblt _08011230\n" + "\tb _080113EE_break\n" + "_08011230:\n" + "\tcmp r4, 0x10\n" + "\tbne _08011236\n" + "\tb _080113EE_break\n" + "_08011236:\n" + "\tcmp r4, 0x10\n" + "\tbgt _0801128C_case_11\n" + "\tcmp r4, 0\n" + "\tbeq _0801127E_case_00\n" + "\tb _080113EE_break\n" + "_08011240:\n" + "\tcmp r4, 0x30\n" + "\tbne _08011246\n" + "\tb _0801136C_case_30_case_33\n" + "_08011246:\n" + "\tcmp r4, 0x30\n" + "\tble _0801124C\n" + "\tb _08011354_case_31\n" + "_0801124C:\n" + "\tcmp r4, 0x14\n" + "\tbeq _08011328_case_14\n" + "\tb _080113EE_break\n" + "_08011252:\n" + "\tcmp r4, 0x44\n" + "\tbgt _08011264\n" + "\tcmp r4, 0x42\n" + "\tblt _0801125C\n" + "\tb _080113EE_break\n" + "_0801125C:\n" + "\tcmp r4, 0x33\n" + "\tbne _08011262\n" + "\tb _0801136C_case_30_case_33\n" + "_08011262:\n" + "\tb _080113EE_break\n" + "_08011264:\n" + "\tcmp r4, 0xF3\n" + "\tbne _0801126A\n" + "\tb _080113BA_case_f3\n" + "_0801126A:\n" + "\tcmp r4, 0xF3\n" + "\tbgt _08011276\n" + "\tcmp r4, 0xF0\n" + "\tbge _08011274\n" + "\tb _080113EE_break\n" + "_08011274:\n" + "\tb _080113D4_case_f0_f1_f2_ff\n" + "_08011276:\n" + "\tcmp r4, 0xFF\n" + "\tbne _0801127C\n" + "\tb _080113D4_case_f0_f1_f2_ff\n" + "_0801127C:\n" + "\tb _080113EE_break\n" + "_0801127E_case_00:\n" + "\tldr r1, =gUnknown_03005000\n" + "\tmovs r0, 0x2\n" + "\tstrh r0, [r1, 0x4]\n" + "\tb _080113EE_break\n" + "\t.pool\n" + "_0801128C_case_11:\n" + "\tldr r0, =gUnknown_03004140\n" + "\tldrh r0, [r0, 0x14]\n" + "\tbl sub_80115EC\n" + "\tmovs r5, 0\n" + "\tmovs r0, 0x1\n" + "\tmov r8, r0\n" + "\tldr r1, =gUnknown_03005000\n" + "\tmov r9, r1\n" + "\tldr r3, =0x00000cd5\n" + "\tadd r3, r9\n" + "\tmov r10, r3\n" + "\tmovs r7, 0x7F\n" + "_080112A6:\n" + "\tldr r0, =gUnknown_03004140\n" + "\tldrh r0, [r0, 0x14]\n" + "\tasrs r0, r5\n" + "\tmov r1, r8\n" + "\tands r0, r1\n" + "\tcmp r0, 0\n" + "\tbeq _0801130E\n" + "\tldr r0, =gUnknown_03007890\n" + "\tlsls r1, r5, 5\n" + "\tadds r1, 0x14\n" + "\tldr r0, [r0]\n" + "\tadds r0, r1\n" + "\tldrb r0, [r0, 0x10]\n" + "\tadds r4, r7, 0\n" + "\tands r4, r0\n" + "\tbl sub_800F7DC\n" + "\tldrb r1, [r0, 0xA]\n" + "\tadds r0, r7, 0\n" + "\tands r0, r1\n" + "\tcmp r4, r0\n" + "\tbne _08011304\n" + "\tldr r0, =0x00000cd1\n" + "\tadd r0, r9\n" + "\tadds r0, r5, r0\n" + "\tmovs r1, 0\n" + "\tstrb r1, [r0]\n" + "\tmov r3, r10\n" + "\tadds r2, r5, r3\n" + "\tstrb r1, [r2]\n" + "\tmovs r0, 0x20\n" + "\tadds r1, r5, 0\n" + "\tmovs r3, 0x1\n" + "\tbl rfu_setRecvBuffer\n" + "\tb _0801130E\n" + "\t.pool\n" + "_08011304:\n" + "\tmov r0, r8\n" + "\tlsls r0, r5\n" + "\torrs r6, r0\n" + "\tlsls r0, r6, 24\n" + "\tlsrs r6, r0, 24\n" + "_0801130E:\n" + "\tadds r0, r5, 0x1\n" + "\tlsls r0, 24\n" + "\tlsrs r5, r0, 24\n" + "\tcmp r5, 0x3\n" + "\tbls _080112A6\n" + "\tcmp r6, 0\n" + "\tbeq _080113EE_break\n" + "\tadds r0, r6, 0\n" + "\tbl rfu_REQ_disconnect\n" + "\tbl rfu_waitREQComplete\n" + "\tb _080113EE_break\n" + "_08011328_case_14:\n" + "\tldr r4, =gUnknown_03005000\n" + "\tldr r1, =0x00000ce7\n" + "\tadds r0, r4, r1\n" + "\tldr r1, =gUnknown_03004140\n" + "\tldrb r2, [r0]\n" + "\tldrb r0, [r1]\n" + "\tcmp r2, r0\n" + "\tbeq _08011342\n" + "\teors r0, r2\n" + "\tbl rfu_REQ_disconnect\n" + "\tbl rfu_waitREQComplete\n" + "_08011342:\n" + "\tmovs r0, 0x11\n" + "\tstrh r0, [r4, 0x4]\n" + "\tb _080113EE_break\n" + "\t.pool\n" + "_08011354_case_31:\n" + "\tldr r0, =gUnknown_03005000\n" + "\tadds r0, 0xF0\n" + "\tb _080113EA\n" + "\t.pool\n" + "_08011360_case_32:\n" + "\tldr r0, =gUnknown_03005000\n" + "\tadds r0, 0xF0\n" + "\tmovs r1, 0x3\n" + "\tb _080113EC\n" + "\t.pool\n" + "_0801136C_case_30_case_33:\n" + "\tldr r1, =gUnknown_03005000\n" + "\tadds r2, r1, 0\n" + "\tadds r2, 0xF0\n" + "\tmovs r0, 0x4\n" + "\tstrb r0, [r2]\n" + "\tldr r3, =0x00000ce2\n" + "\tadds r1, r3\n" + "\tldr r0, =gUnknown_03004140\n" + "\tldrb r2, [r0, 0x14]\n" + "\tldrb r0, [r1]\n" + "\tadds r3, r0, 0\n" + "\tbics r3, r2\n" + "\tadds r2, r3, 0\n" + "\tstrb r2, [r1]\n" + "\tldr r0, =gReceivedRemoteLinkPlayers\n" + "\tldrb r0, [r0]\n" + "\tcmp r0, 0x1\n" + "\tbne _080113B0\n" + "\tcmp r2, 0\n" + "\tbne _080113AC\n" + "\tadds r0, r4, 0\n" + "\tbl sub_8011170\n" + "\tb _080113B0\n" + "\t.pool\n" + "_080113AC:\n" + "\tbl sub_80111FC\n" + "_080113B0:\n" + "\tmovs r0, 0x2\n" + "\tadds r1, r4, 0\n" + "\tbl sub_8011A64\n" + "\tb _080113EE_break\n" + "_080113BA_case_f3:\n" + "\tmovs r0, 0x1\n" + "\tmovs r1, 0xF3\n" + "\tbl sub_8011A64\n" + "\tmovs r0, 0xF3\n" + "\tbl sub_8011170\n" + "\tldr r0, =gUnknown_03005000\n" + "\tadds r0, 0xEF\n" + "\tb _080113EA\n" + "\t.pool\n" + "_080113D4_case_f0_f1_f2_ff:\n" + "\tadds r0, r4, 0\n" + "\tbl sub_8011170\n" + "\tmovs r0, 0x1\n" + "\tadds r1, r4, 0\n" + "\tbl sub_8011A64\n" + "\tldr r0, =gUnknown_03005000\n" + "\tldr r1, =0x00000cdb\n" + "\tadds r0, r1\n" + "\tldrb r1, [r0]\n" + "_080113EA:\n" + "\tmovs r1, 0x1\n" + "_080113EC:\n" + "\tstrb r1, [r0]\n" + "_080113EE_break:\n" + "\tpop {r3-r5}\n" + "\tmov r8, r3\n" + "\tmov r9, r4\n" + "\tmov r10, r5\n" + "\tpop {r4-r7}\n" + "\tpop {r0}\n" + "\tbx r0\n" + "\t.pool"); +} +#endif diff --git a/src/main.c b/src/main.c index d4601293b..3be6b91c7 100644 --- a/src/main.c +++ b/src/main.c @@ -1,50 +1,32 @@ #include "global.h" -#include "main.h" +#include "crt0.h" +#include "malloc.h" +#include "link.h" +#include "link_rfu.h" +#include "librfu.h" #include "m4a.h" +#include "bg.h" #include "rtc.h" +#include "scanline_effect.h" +#include "overworld.h" +#include "play_time.h" #include "random.h" #include "dma3.h" #include "gba/flash_internal.h" +#include "load_save.h" +#include "gpu_regs.h" +#include "agb_flash.h" +#include "sound.h" #include "battle.h" +#include "battle_controllers.h" +#include "text.h" +#include "intro.h" +#include "main.h" -extern u16 GetGpuReg(u8); -extern void SetGpuReg(u8, u16); -extern void LinkVSync(void); -extern void sub_800E174(void); extern void sub_800B9B8(void); -extern void InitGpuRegManager(void); -extern void sub_800E6D0(void); -extern void CheckForFlashMemory(void); -extern void InitMapMusic(void); -extern void ResetBgs(void); -extern void SetDefaultFontsPointer(void); -extern void InitHeap(void *heapStart, u32 heapSize); // malloc.h -extern void rfu_REQ_stopMode(void); -extern void rfu_waitREQComplete(void); -extern bool32 sub_8087634(void); -extern bool32 sub_80875C8(void); -extern void ClearSpriteCopyRequests(void); -extern void PlayTimeCounter_Update(void); -extern void MapMusicMain(void); -extern void EnableInterrupts(u16); -extern void sub_8033648(void); -extern u16 SetFlashTimerIntr(u8 timerNum, void (**intrFunc)(void)); -extern void ScanlineEffect_Stop(void); - -extern struct SoundInfo gSoundInfo; -extern u32 gFlashMemoryPresent; -extern u32 IntrMain[]; -extern u8 gHeap[]; -extern struct SaveBlock2 gSaveblock2; -extern struct PokemonStorage gPokemonStorage; -extern u32 gBattleTypeFlags; extern u8 gUnknown_03002748; extern u32 *gUnknown_0203CF5C; -void Timer3Intr(void); -bool8 HandleLinkConnection(void); -void c2_copyright_1(void); - static void VBlankIntr(void); static void HBlankIntr(void); static void VCountIntr(void); @@ -79,19 +61,19 @@ const IntrFunc gIntrTableTemplate[] = static u16 gUnknown_03000000; -extern u16 gKeyRepeatStartDelay; -extern u8 gUnknown_030022B4; -extern struct Main gMain; -extern u16 gKeyRepeatContinueDelay; -extern u8 gSoftResetDisabled; -extern IntrFunc gIntrTable[INTR_COUNT]; -extern bool8 gLinkVSyncDisabled; -extern u32 IntrMain_Buffer[0x200]; -extern u8 gPcmDmaCounter; +u16 gKeyRepeatStartDelay; +bool8 gLinkTransferringData; +struct Main gMain; +u16 gKeyRepeatContinueDelay; +bool8 gSoftResetDisabled; +IntrFunc gIntrTable[INTR_COUNT]; +u8 gLinkVSyncDisabled; +u32 IntrMain_Buffer[0x200]; +u8 gPcmDmaCounter; -extern u16 gTrainerId; +static EWRAM_DATA u16 gTrainerId = 0; -EWRAM_DATA void (**gFlashTimerIntrFunc)(void) = NULL; +//EWRAM_DATA void (**gFlashTimerIntrFunc)(void) = NULL; static void UpdateLinkAndCallCallbacks(void); static void InitMainCallbacks(void); @@ -129,7 +111,7 @@ void AgbMain() if (gFlashMemoryPresent != TRUE) SetMainCallback2(NULL); - gUnknown_030022B4 = 0; + gLinkTransferringData = FALSE; gUnknown_03000000 = 0xFC0; for (;;) @@ -147,22 +129,22 @@ void AgbMain() if (sub_8087634() == 1) { - gUnknown_030022B4 = 1; + gLinkTransferringData = TRUE; UpdateLinkAndCallCallbacks(); - gUnknown_030022B4 = 0; + gLinkTransferringData = FALSE; } else { - gUnknown_030022B4 = 0; + gLinkTransferringData = FALSE; UpdateLinkAndCallCallbacks(); if (sub_80875C8() == 1) { gMain.newKeys = 0; ClearSpriteCopyRequests(); - gUnknown_030022B4 = 1; + gLinkTransferringData = TRUE; UpdateLinkAndCallCallbacks(); - gUnknown_030022B4 = 0; + gLinkTransferringData = FALSE; } } @@ -335,10 +317,10 @@ extern void CopyBufferedValuesToGpuRegs(void); static void VBlankIntr(void) { - if (gLinkVSyncDisabled != FALSE) + if (gWirelessCommType != 0) + RfuVSync(); + else if (gLinkVSyncDisabled == FALSE) LinkVSync(); - else if (gUnknown_03002748 == FALSE) - sub_800B9B8(); gMain.vblankCounter1++; diff --git a/src/main_menu.c b/src/main_menu.c index c8a868251..85a445a67 100644 --- a/src/main_menu.c +++ b/src/main_menu.c @@ -51,48 +51,15 @@ IWRAM_DATA u8 gUnknown_03000DD0; // Static ROM declarations -// .rodata - -// .text - -enum -{ - HAS_NO_SAVED_GAME, //NEW GAME, OPTION - HAS_SAVED_GAME, //CONTINUE, NEW GAME, OPTION - HAS_MYSTERY_GIFT, //CONTINUE, NEW GAME, MYSTERY EVENTS, OPTION - HAS_MYSTERY_EVENTS, -}; - -struct ArrowStruct { - u8 unk0[6]; - u16 unk6[5]; -}; - -extern struct BgTemplate gUnknown_082FF0E8[]; -extern struct WindowTemplate gUnknown_082FF038[]; -extern struct WindowTemplate gUnknown_082FF070[]; -extern u8 gUnknown_082FF0E0[]; -extern struct WindowTemplate gUnknown_082FF048[]; -extern struct ArrowStruct gUnknown_082FF0F4; -extern struct BgTemplate gUnknown_082FF0F0; -extern struct WindowTemplate gUnknown_082FF080[]; -extern const union AffineAnimCmd *const gUnknown_082FF114[]; -extern struct WindowTemplate gUnknown_082FF088[]; -extern const struct MenuAction gUnknown_082FF118[]; -extern u8* gMalePresetNames[]; -extern u8* gFemalePresetNames[]; -extern u8 gUnknown_082FF0E3[]; - u32 InitMainMenu(bool8); void Task_MainMenuCheckSaveFile(u8); void Task_MainMenuCheckBattery(u8); void Task_WaitForSaveFileErrorWindow(u8); void CreateMainMenuErrorWindow(const u8*); -void sub_8032250(struct WindowTemplate*); +void sub_8032250(const struct WindowTemplate*); void Task_DisplayMainMenu(u8); void Task_WaitForBatteryDryErrorWindow(u8); void fmt_savegame(void); -u8 AddScrollIndicatorArrowPair(struct ArrowStruct*, u16*); void HighlightSelectedMainMenuItem(u8, u8, s16); void Task_HandleMainMenuInput(u8); void Task_HandleMainMenuAPressed(u8); @@ -119,7 +86,7 @@ void task_new_game_prof_birch_speech_9(u8); void task_new_game_prof_birch_speech_10(u8); void task_new_game_prof_birch_speech_11(u8); void LoadMainMenuWindowFrameTiles(u8, u16); -void DrawMainMenuWindowBorder(struct WindowTemplate*, u16); +void DrawMainMenuWindowBorder(const struct WindowTemplate*, u16); void Task_HighlightSelectedMainMenuItem(u8); void task_new_game_prof_birch_speech_12(u8); void task_new_game_prof_birch_speech_13(u8); @@ -154,6 +121,126 @@ void fmt_player(void); void fmt_badges(void); void sub_8032474(u8, u8, u8, u8, u8, u8); +// .rodata + +const u16 gUnknown_082FECFC[][16] = { + INCBIN_U16("graphics/birch_speech/bg0.gbapal"), + INCBIN_U16("graphics/birch_speech/bg1.gbapal") +}; + +const u8 gBirchIntroShadowGfx[] = INCBIN_U8("graphics/birch_speech/shadow.4bpp.lz"); +const u8 gUnknown_082FEEF0[] = INCBIN_U8("graphics/birch_speech/map.bin.lz"); +const u16 gUnknown_082FF018[] = INCBIN_U16("graphics/birch_speech/bg2.gbapal"); +const u16 gUnknown_082FF028[] = {0, 0, 0, 0, 0, 0, 0, 0}; + +const struct WindowTemplate gUnknown_082FF038[] = { + {0, 2, 1, 26, 2, 15, 1}, + {0, 2, 5, 26, 2, 15, 0x35} +}; + +const struct WindowTemplate gUnknown_082FF048[] = { + {0, 2, 1, 26, 6, 15, 1}, + {0, 2, 9, 26, 2, 15, 0x9D}, + {0, 2, 13, 26, 2, 15, 0xD1}, + {0, 2, 17, 26, 2, 15, 0x105}, + {0, 2, 21, 26, 2, 15, 0x139} +}; + +const struct WindowTemplate gUnknown_082FF070[] = { + {0, 2, 15, 26, 4, 15, 0x16D}, + {0xFF, 0, 0, 0, 0, 0, 0} +}; + +const struct WindowTemplate gUnknown_082FF080[] = { + {0, 2, 15, 27, 4, 15, 1}, + {0, 3, 5, 6, 4, 15, 0x6D}, + {0, 3, 2, 9, 10, 15, 0x85}, + {0xFF, 0, 0, 0, 0, 0, 0} +}; + +const u16 gMainMenuBgPal[] = INCBIN_U16("graphics/misc/main_menu_bg.gbapal"); +const u16 gMainMenuTextPal[] = INCBIN_U16("graphics/misc/main_menu_text.gbapal"); + +const u8 gUnknown_082FF0E0[] = {10, 11, 12}; +const u8 gUnknown_082FF0E3[] = {10, 1, 12}; + +const struct BgTemplate gUnknown_082FF0E8[] = { + {0, 2, 30, 0, 0, 0, 0}, + {1, 0, 7, 0, 0, 3, 0} +}; + +const struct BgTemplate gUnknown_082FF0F0 = {0, 3, 30, 0, 0, 0, 0}; + +const struct ArrowStruct gUnknown_082FF0F4 = {2, 0x78, 8, 3, 0x78, 0x98, 3, 4, 1, 1, 0}; + +const union AffineAnimCmd gUnknown_082FF104[] = { + AFFINEANIMCMD_FRAME(-2, -2, 0, 0x30), + AFFINEANIMCMD_END +}; + +const union AffineAnimCmd *const gUnknown_082FF114 = gUnknown_082FF104; + +const struct MenuAction gUnknown_082FF118[] = { + {gText_BirchBoy, NULL}, + {gText_BirchGirl, NULL} +}; + +const u8 *const gMalePresetNames[] = { + gText_DefaultNameStu, + gText_DefaultNameMilton, + gText_DefaultNameTom, + gText_DefaultNameKenny, + gText_DefaultNameReid, + gText_DefaultNameJude, + gText_DefaultNameJaxson, + gText_DefaultNameEaston, + gText_DefaultNameWalker, + gText_DefaultNameTeru, + gText_DefaultNameJohnny, + gText_DefaultNameBrett, + gText_DefaultNameSeth, + gText_DefaultNameTerry, + gText_DefaultNameCasey, + gText_DefaultNameDarren, + gText_DefaultNameLandon, + gText_DefaultNameCollin, + gText_DefaultNameStanley, + gText_DefaultNameQuincy +}; + +const u8 *const gFemalePresetNames[] = { + gText_DefaultNameKimmy, + gText_DefaultNameTiara, + gText_DefaultNameBella, + gText_DefaultNameJayla, + gText_DefaultNameAllie, + gText_DefaultNameLianna, + gText_DefaultNameSara, + gText_DefaultNameMonica, + gText_DefaultNameCamila, + gText_DefaultNameAubree, + gText_DefaultNameRuthie, + gText_DefaultNameHazel, + gText_DefaultNameNadine, + gText_DefaultNameTanja, + gText_DefaultNameYasmin, + gText_DefaultNameNicola, + gText_DefaultNameLillie, + gText_DefaultNameTerra, + gText_DefaultNameLucy, + gText_DefaultNameHalie +}; + +// .text + +enum +{ + HAS_NO_SAVED_GAME, //NEW GAME, OPTION + HAS_SAVED_GAME, //CONTINUE, NEW GAME, OPTION + HAS_MYSTERY_GIFT, //CONTINUE, NEW GAME, MYSTERY EVENTS, OPTION + HAS_MYSTERY_EVENTS, +}; + void CB2_MainMenu(void) { RunTasks(); @@ -230,7 +317,7 @@ u32 InitMainMenu(bool8 affects_palette_maybe) EnableInterrupts(1); SetVBlankCallback(VBlankCB_MainMenu); SetMainCallback2(CB2_MainMenu); - SetGpuReg(REG_OFFSET_DISPCNT, 0x3040); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON | DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); ShowBg(0); HideBg(1); CreateTask(Task_MainMenuCheckSaveFile, 0); @@ -248,7 +335,7 @@ void Task_MainMenuCheckSaveFile(u8 taskId) SetGpuReg(REG_OFFSET_WIN0V, 0); SetGpuReg(REG_OFFSET_WININ, 17); SetGpuReg(REG_OFFSET_WINOUT, 0x31); - SetGpuReg(REG_OFFSET_BLDCNT, 0xC1); + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_DARKEN | BLDCNT_TGT1_BG0); SetGpuReg(REG_OFFSET_BLDALPHA, 0); SetGpuReg(REG_OFFSET_BLDY, 7); @@ -326,7 +413,7 @@ void Task_MainMenuCheckBattery(u8 taskId) SetGpuReg(REG_OFFSET_WIN0V, 0); SetGpuReg(REG_OFFSET_WININ, 17); SetGpuReg(REG_OFFSET_WINOUT, 0x31); - SetGpuReg(REG_OFFSET_BLDCNT, 0xC1); + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_DARKEN | BLDCNT_TGT1_BG0); SetGpuReg(REG_OFFSET_BLDALPHA, 0); SetGpuReg(REG_OFFSET_BLDY, 7); @@ -364,7 +451,7 @@ void Task_DisplayMainMenu(u8 taskId) SetGpuReg(REG_OFFSET_WIN0V, 0); SetGpuReg(REG_OFFSET_WININ, 17); SetGpuReg(REG_OFFSET_WINOUT, 0x31); - SetGpuReg(REG_OFFSET_BLDCNT, 0xC1); + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_DARKEN | BLDCNT_TGT1_BG0); SetGpuReg(REG_OFFSET_BLDALPHA, 0); SetGpuReg(REG_OFFSET_BLDY, 7); @@ -862,7 +949,7 @@ void HighlightSelectedMainMenuItem(u8 menuType, u8 selectedMenuItem, s16 a) void task_new_game_prof_birch_speech_1(u8 taskId) { SetGpuReg(REG_OFFSET_DISPCNT, 0); - SetGpuReg(REG_OFFSET_DISPCNT, 0x1040); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); InitBgFromTemplate(&gUnknown_082FF0F0); SetGpuReg(REG_OFFSET_WIN0H, 0); SetGpuReg(REG_OFFSET_WIN0V, 0); @@ -1338,7 +1425,7 @@ void task_new_game_prof_birch_speech_part2_9(u8 taskId) { spriteId = gTasks[taskId].data[2]; gSprites[spriteId].oam.affineMode = 1; - gSprites[spriteId].affineAnims = gUnknown_082FF114; + gSprites[spriteId].affineAnims = &gUnknown_082FF114; InitSpriteAffineAnim(&gSprites[spriteId]); StartSpriteAffineAnim(&gSprites[spriteId], 0); gSprites[spriteId].callback = sub_80318D8; @@ -1365,7 +1452,7 @@ void task_new_game_prof_birch_speech_part2_11(u8 taskId) { spriteId = gTasks[taskId].data[2]; gSprites[spriteId].callback = nullsub_11; - SetGpuReg(REG_OFFSET_DISPCNT, 0x1040); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); BeginNormalPaletteFade(-0x10000, 0, 0, 16, -1); gTasks[taskId].func = task_new_game_prof_birch_speech_part2_12; } @@ -1391,7 +1478,7 @@ void new_game_prof_birch_speech_part2_start(void) ResetBgsAndClearDma3BusyFlags(0); SetGpuReg(REG_OFFSET_DISPCNT, 0); - SetGpuReg(REG_OFFSET_DISPCNT, 0x1040); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); InitBgsFromTemplates(0, gUnknown_082FF0E8, 2); InitBgFromTemplate(&gUnknown_082FF0F0); SetVBlankCallback(NULL); @@ -1493,12 +1580,12 @@ void AddBirchSpeechObjects(u8 taskId) gSprites[spriteId2].oam.priority = 0; gSprites[spriteId2].invisible = 1; gTasks[taskId].data[9] = spriteId2; - spriteId3 = CreateTrainerSprite(sub_806EFF0(0x3C), 0x78, 0x3C, 0, gDecompressionBuffer); + spriteId3 = CreateTrainerSprite(FacilityClassToPicIndex(0x3C), 0x78, 0x3C, 0, gDecompressionBuffer); gSprites[spriteId3].callback = nullsub_11; gSprites[spriteId3].invisible = 1; gSprites[spriteId3].oam.priority = 0; gTasks[taskId].data[10] = spriteId3; - spriteId4 = CreateTrainerSprite(sub_806EFF0(0x3F), 0x78, 0x3C, 0, &gDecompressionBuffer[0x800]); + spriteId4 = CreateTrainerSprite(FacilityClassToPicIndex(0x3F), 0x78, 0x3C, 0, &gDecompressionBuffer[0x800]); gSprites[spriteId4].callback = nullsub_11; gSprites[spriteId4].invisible = 1; gSprites[spriteId4].oam.priority = 0; @@ -1532,8 +1619,8 @@ void sub_8031ACC(u8 taskId, u8 a) { u8 taskId2; - SetGpuReg(REG_OFFSET_BLDCNT, 0x250); - SetGpuReg(REG_OFFSET_BLDALPHA, 16); + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_OBJ); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0)); SetGpuReg(REG_OFFSET_BLDY, 0); gTasks[taskId].data[5] = 0; taskId2 = CreateTask(sub_8031A5C, 0); @@ -1571,8 +1658,8 @@ void sub_8031BAC(u8 taskId, u8 a) { u8 taskId2; - SetGpuReg(REG_OFFSET_BLDCNT, 0x250); - SetGpuReg(REG_OFFSET_BLDALPHA, 0x1000); + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_OBJ); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16)); SetGpuReg(REG_OFFSET_BLDY, 0); gTasks[taskId].data[5] = 0; taskId2 = CreateTask(sub_8031B3C, 0); @@ -1653,7 +1740,7 @@ void sub_8031D34(u8 taskId, u8 a) void sub_8031D74(void) { - DrawMainMenuWindowBorder(gUnknown_082FF088, 0xF3); + DrawMainMenuWindowBorder(&gUnknown_082FF080[1], 0xF3); FillWindowPixelBuffer(1, 17); PrintMenuTable(1, 2, gUnknown_082FF118); InitMenuInUpperLeftCornerPlaySoundWhenAPressed(1, 2, 0); @@ -1668,7 +1755,7 @@ s8 sub_8031DB4(void) void set_default_player_name(u8 nameId) { - u8* name; + const u8* name; u8 i; if (gSaveBlock2Ptr->playerGender == MALE) @@ -1760,7 +1847,7 @@ void LoadMainMenuWindowFrameTiles(u8 bgId, u16 tileOffset) LoadPalette(GetWindowFrameTilesPal(gSaveBlock2Ptr->optionsWindowFrameType)->pal, 32, 32); } -void DrawMainMenuWindowBorder(struct WindowTemplate *template, u16 baseTileNum) +void DrawMainMenuWindowBorder(const struct WindowTemplate *template, u16 baseTileNum) { u16 r9 = 1 + baseTileNum; u16 r10 = 2 + baseTileNum; @@ -1781,7 +1868,7 @@ void DrawMainMenuWindowBorder(struct WindowTemplate *template, u16 baseTileNum) CopyBgTilemapBufferToVram(template->priority); } -void sub_8032250(struct WindowTemplate *template) +void sub_8032250(const struct WindowTemplate *template) { FillBgTilemapBufferRect(template->priority, 0, template->tilemapLeft - 1, template->tilemapTop - 1, template->tilemapLeft + template->width + 1, template->tilemapTop + template->height + 1, 2); CopyBgTilemapBufferToVram(template->priority); diff --git a/src/mystery_event_menu.c b/src/mystery_event_menu.c index 31b366ae9..22e50f4e7 100644 --- a/src/mystery_event_menu.c +++ b/src/mystery_event_menu.c @@ -189,7 +189,7 @@ static void CB2_MysteryEventMenu(void) { if (gReceivedRemoteLinkPlayers != 0) { - if (sub_800A0C8(2, 2) == 3) + if (GetLinkPlayerDataExchangeStatusTimed(2, 2) == 3) { sub_800AC34(); GetEventLoadMessage(gStringVar4, 1); diff --git a/src/pokeball.c b/src/pokeball.c index ada0258db..795a33827 100644 --- a/src/pokeball.c +++ b/src/pokeball.c @@ -15,12 +15,6 @@ #include "util.h" #include "graphics.h" -extern bool8 gDoingBattleAnim; -extern u8 gActiveBattler; -extern u8 gBattlerTarget; -extern u16 gBattlerPartyIndexes[]; -extern u8 gBattlerSpriteIds[]; -extern u8 gHealthboxSpriteIds[]; extern struct MusicPlayerInfo gMPlayInfo_BGM; // this file's functions diff --git a/src/pokeblock_feed.c b/src/pokeblock_feed.c index 2039808cb..db92d56a8 100644 --- a/src/pokeblock_feed.c +++ b/src/pokeblock_feed.c @@ -50,7 +50,6 @@ struct PokeblockFeedStruct extern u16 gSpecialVar_ItemId; extern struct MusicPlayerInfo gMPlayInfo_BGM; -extern struct SpriteTemplate gUnknown_0202499C; extern const u8 gBattleTerrainPalette_Frontier[]; extern const u8 gBattleTerrainTiles_Building[]; @@ -837,7 +836,7 @@ static u8 CreateMonSprite(struct Pokemon* mon) gSprites[spriteId].callback = SpriteCallbackDummy; sPokeblockFeed->noMonFlip = TRUE; - if (!IsPokeSpriteNotFlipped(species)) + if (!IsMonSpriteNotFlipped(species)) { gSprites[spriteId].affineAnims = sSpriteAffineAnimTable_MonNoFlip; gSprites[spriteId].oam.affineMode = 3; diff --git a/src/pokemon.c b/src/pokemon.c new file mode 100644 index 000000000..25d532204 --- /dev/null +++ b/src/pokemon.c @@ -0,0 +1,6094 @@ +#include "global.h" +#include "pokemon.h" +#include "battle.h" +#include "battle_setup.h" +#include "battle_message.h" +#include "random.h" +#include "main.h" +#include "constants/species.h" +#include "constants/abilities.h" +#include "constants/items.h" +#include "constants/trainers.h" +#include "constants/moves.h" +#include "constants/hold_effects.h" +#include "constants/battle_move_effects.h" +#include "constants/songs.h" +#include "string_util.h" +#include "text.h" +#include "link.h" +#include "event_data.h" +#include "item.h" +#include "battle_controllers.h" +#include "battle_message.h" +#include "evolution_scene.h" +#include "pokemon_animation.h" +#include "pokedex.h" +#include "pokeblock.h" +#include "sound.h" +#include "task.h" +#include "rtc.h" +#include "m4a.h" +#include "malloc.h" +#include "util.h" +#include "strings.h" +#include "pokenav.h" +#include "pokemon_storage_system.h" +#include "recorded_battle.h" + +struct SpeciesItem +{ + u16 species; + u16 item; +}; + +// Extracts the upper 16 bits of a 32-bit number +#define HIHALF(n) (((n) & 0xFFFF0000) >> 16) + +// Extracts the lower 16 bits of a 32-bit number +#define LOHALF(n) ((n) & 0xFFFF) + +extern const struct OamData gUnknown_0831ACB0; +extern const struct OamData gUnknown_0831ACA8; +extern const struct SpriteFrameImage gUnknown_082FF3A8[]; +extern const struct SpriteFrameImage gUnknown_082FF3C8[]; +extern const struct SpriteFrameImage gUnknown_082FF3E8[]; +extern const struct SpriteFrameImage gUnknown_082FF408[]; +extern const struct SpriteFrameImage gUnknown_082FF428[]; +extern const struct SpriteFrameImage gUnknown_082FF448[]; +extern const struct SpriteFrameImage gUnknown_082FF468[]; +extern const struct SpriteFrameImage gUnknown_082FF490[]; +extern const struct SpriteFrameImage gUnknown_082FF4B8[]; +extern const struct SpriteFrameImage gUnknown_082FF4D8[]; +extern const struct SpriteFrameImage gUnknown_082FF4F8[]; +extern const struct SpriteFrameImage gUnknown_082FF518[]; +extern const union AffineAnimCmd *const gUnknown_082FF618[]; +extern const union AffineAnimCmd *const gUnknown_082FF694[]; +extern const union AnimCmd *gUnknown_082FF70C[]; +extern const union AnimCmd *const *const gMonAnimationsSpriteAnimsPtrTable[]; +extern const union AnimCmd *const *const gUnknown_08305D0C[]; +extern const union AnimCmd *const *const gUnknown_0830536C[]; +extern const struct BattleMove gBattleMoves[]; +extern const u8 gSpeciesNames[][POKEMON_NAME_LENGTH + 1]; +extern const struct UnknownPokemonStruct3 gUnknown_08610970[]; +extern const struct CompressedSpritePalette gMonPaletteTable[]; +extern const struct CompressedSpritePalette gMonShinyPaletteTable[]; +extern const u8 gTrainerClassNames[][13]; + +extern u8 pokemon_order_func(u8); +extern u16 get_unknown_box_id(void); +extern u8 StorageGetCurrentBox(void); +extern void set_unknown_box_id(u8); +extern void sub_803FA70(u8 battlerId); +extern u8 sav1_map_get_name(void); +extern const u8 *sub_81A1650(u8, u8 language); +extern u8 BattleFrontierGetOpponentLvl(u8); +extern u16 FacilityClassToPicIndex(u16); +extern bool8 InBattlePyramid(void); +extern bool8 InBattlePike(void); +extern bool8 sub_806F104(void); +extern u8 GetTrainerEncounterMusicIdInBattlePyramind(u16 trainerOpponentId); +extern u8 sub_81D63C8(u16 trainerOpponentId); +extern u8 GetFrontierOpponentClass(u16 trainerId); +extern void GetFrontierTrainerName(u8* dest, u16 trainerId); +extern void sub_81C488C(u8); + +// this file's functions +static u16 CalculateBoxMonChecksum(struct BoxPokemon *boxMon); +static union PokemonSubstruct *GetSubstruct(struct BoxPokemon *boxMon, u32 personality, u8 substructType); +static void EncryptBoxMon(struct BoxPokemon *boxMon); +static void DecryptBoxMon(struct BoxPokemon *boxMon); +static void sub_806E6CC(u8 taskId); +static bool8 ShouldGetStatBadgeBoost(u16 flagId, u8 battlerId); + +// EWRAM vars +EWRAM_DATA static u8 sLearningMoveTableID = 0; +EWRAM_DATA u8 gPlayerPartyCount = 0; +EWRAM_DATA u8 gEnemyPartyCount = 0; +EWRAM_DATA struct Pokemon gPlayerParty[PARTY_SIZE] = {0}; +EWRAM_DATA struct Pokemon gEnemyParty[PARTY_SIZE] = {0}; +EWRAM_DATA struct SpriteTemplate gUnknown_0202499C = {0}; +EWRAM_DATA struct Unknown_806F160_Struct *gUnknown_020249B4[2] = {NULL}; + +// const rom data +const u16 gSpeciesToHoennPokedexNum[] = {203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 156, 157, 112, 113, 227, 228, 229, 230, 231, 232, 233, 234, 153, 154, 138, 139, 63, 64, 88, 89, 90, 235, 236, 237, 238, 239, 240, 241, 242, 158, 159, 243, 244, 245, 246, 247, 248, 249, 39, 40, 41, 73, 74, 75, 250, 251, 252, 66, 67, 57, 58, 59, 253, 254, 255, 256, 82, 83, 257, 92, 93, 258, 259, 106, 107, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 84, 85, 270, 271, 272, 273, 274, 275, 276, 108, 109, 169, 170, 277, 278, 279, 184, 185, 50, 51, 143, 144, 280, 281, 282, 283, 284, 167, 285, 52, 53, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 65, 181, 182, 155, 324, 137, 325, 326, 162, 163, 327, 328, 329, 91, 55, 56, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 161, 164, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 168, 357, 358, 359, 103, 104, 360, 361, 180, 362, 363, 364, 365, 115, 366, 367, 186, 165, 166, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 42, 43, 44, 25, 26, 34, 35, 114, 27, 28, 32, 33, 99, 100, 61, 62, 145, 131, 132, 60, 105, 68, 127, 128, 183, 129, 130, 140, 141, 97, 98, 116, 117, 118, 48, 49, 78, 79, 101, 102, 173, 174, 175, 119, 120, 171, 172, 125, 126, 54, 110, 111, 80, 81, 69, 76, 77, 121, 122, 160, 148, 149, 94, 36, 37, 38, 95, 96, 150, 45, 46, 47, 176, 177, 178, 152, 146, 147, 124, 123, 179, 70, 71, 72, 142, 86, 87, 133, 134, 135, 136, 29, 30, 31, 187, 188, 189, 190, 191, 192, 193, 194, 195, 198, 199, 200, 196, 197, 201, 202, 151}; +const u16 gSpeciesToNationalPokedexNum[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 290, 291, 292, 276, 277, 285, 286, 327, 278, 279, 283, 284, 320, 321, 300, 301, 352, 343, 344, 299, 324, 302, 339, 340, 370, 341, 342, 349, 350, 318, 319, 328, 329, 330, 296, 297, 309, 310, 322, 323, 363, 364, 365, 331, 332, 361, 362, 337, 338, 298, 325, 326, 311, 312, 303, 307, 308, 333, 334, 360, 355, 356, 315, 287, 288, 289, 316, 317, 357, 293, 294, 295, 366, 367, 368, 359, 353, 354, 336, 335, 369, 304, 305, 306, 351, 313, 314, 345, 346, 347, 348, 280, 281, 282, 371, 372, 373, 374, 375, 376, 377, 378, 379, 382, 383, 384, 380, 381, 385, 386, 358}; +const u16 gHoennToNationalOrder[] = {252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 63, 64, 65, 290, 291, 292, 293, 294, 295, 296, 297, 118, 119, 129, 130, 298, 183, 184, 74, 75, 76, 299, 300, 301, 41, 42, 169, 72, 73, 302, 303, 304, 305, 306, 66, 67, 68, 307, 308, 309, 310, 311, 312, 81, 82, 100, 101, 313, 314, 43, 44, 45, 182, 84, 85, 315, 316, 317, 318, 319, 320, 321, 322, 323, 218, 219, 324, 88, 89, 109, 110, 325, 326, 27, 28, 327, 227, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 174, 39, 40, 349, 350, 351, 120, 121, 352, 353, 354, 355, 356, 357, 358, 359, 37, 38, 172, 25, 26, 54, 55, 360, 202, 177, 178, 203, 231, 232, 127, 214, 111, 112, 361, 362, 363, 364, 365, 366, 367, 368, 369, 222, 170, 171, 370, 116, 117, 230, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 34, 35, 36, 46, 47, 48, 49, 50, 51, 52, 53, 56, 57, 58, 59, 60, 61, 62, 69, 70, 71, 77, 78, 79, 80, 83, 86, 87, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 102, 103, 104, 105, 106, 107, 108, 113, 114, 115, 122, 123, 124, 125, 126, 128, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 173, 175, 176, 179, 180, 181, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 215, 216, 217, 220, 221, 223, 224, 225, 226, 228, 229, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411}; + +const struct SpindaSpot gSpindaSpotGraphics[] = +{ + {16, 7, INCBIN_U16("graphics/spinda_spots/spot_0.bin")}, + {40, 8, INCBIN_U16("graphics/spinda_spots/spot_1.bin")}, + {22, 25, INCBIN_U16("graphics/spinda_spots/spot_2.bin")}, + {34, 26, INCBIN_U16("graphics/spinda_spots/spot_3.bin")} +}; + +#include "data/pokemon/item_effects.h" + +const s8 gNatureStatTable[][5] = +{ + // Atk Def Spd Sp.Atk Sp.Def + { 0, 0, 0, 0, 0}, // Hardy + { +1, -1, 0, 0, 0}, // Lonely + { +1, 0, -1, 0, 0}, // Brave + { +1, 0, 0, -1, 0}, // Adamant + { +1, 0, 0, 0, -1}, // Naughty + { -1, +1, 0, 0, 0}, // Bold + { 0, 0, 0, 0, 0}, // Docile + { 0, +1, -1, 0, 0}, // Relaxed + { 0, +1, 0, -1, 0}, // Impish + { 0, +1, 0, 0, -1}, // Lax + { -1, 0, +1, 0, 0}, // Timid + { 0, -1, +1, 0, 0}, // Hasty + { 0, 0, 0, 0, 0}, // Serious + { 0, 0, +1, -1, 0}, // Jolly + { 0, 0, +1, 0, -1}, // Naive + { -1, 0, 0, +1, 0}, // Modest + { 0, -1, 0, +1, 0}, // Mild + { 0, 0, -1, +1, 0}, // Quiet + { 0, 0, 0, 0, 0}, // Bashful + { 0, 0, 0, +1, -1}, // Rash + { -1, 0, 0, 0, +1}, // Calm + { 0, -1, 0, 0, +1}, // Gentle + { 0, 0, -1, 0, +1}, // Sassy + { 0, 0, 0, -1, +1}, // Careful + { 0, 0, 0, 0, 0}, // Quirky +}; + +#include "data/pokemon/tmhm_learnsets.h" +#include "data/pokemon/trainer_class_lookups.h" +#include "data/pokemon/cry_ids.h" +#include "data/pokemon/experience_tables.h" +#include "data/pokemon/base_stats.h" +#include "data/pokemon/level_up_learnsets.h" +#include "data/pokemon/evolution.h" +#include "data/pokemon/level_up_learnset_pointers.h" + +static const u8 sMonFrontAnimIdsTable[] = +{ + 0x06, // SPECIES_BULBASAUR + 0x17, // SPECIES_IVYSAUR + 0x2f, // SPECIES_VENUSAUR + 0x52, // SPECIES_CHARMANDER + 0x25, // SPECIES_CHARMELEON + 0x10, // SPECIES_CHARIZARD + 0x0b, // SPECIES_SQUIRTLE + 0x13, // SPECIES_WARTORTLE + 0x19, // SPECIES_BLASTOISE + 0x0b, // SPECIES_CATERPIE + 0x0b, // SPECIES_METAPOD + 0x1d, // SPECIES_BUTTERFREE + 0x46, // SPECIES_WEEDLE + 0x20, // SPECIES_KAKUNA + 0x02, // SPECIES_BEEDRILL + 0x47, // SPECIES_PIDGEY + 0x17, // SPECIES_PIDGEOTTO + 0x29, // SPECIES_PIDGEOT + 0x43, // SPECIES_RATTATA + 0x2b, // SPECIES_RATICATE + 0x18, // SPECIES_SPEAROW + 0x2b, // SPECIES_FEAROW + 0x16, // SPECIES_EKANS + 0x17, // SPECIES_ARBOK + 0x2c, // SPECIES_PIKACHU + 0x17, // SPECIES_RAICHU + 0x2d, // SPECIES_SANDSHREW + 0x17, // SPECIES_SANDSLASH + 0x00, // SPECIES_NIDORAN_F + 0x17, // SPECIES_NIDORINA + 0x0f, // SPECIES_NIDOQUEEN + 0x09, // SPECIES_NIDORAN_M + 0x13, // SPECIES_NIDORINO + 0x0f, // SPECIES_NIDOKING + 0x00, // SPECIES_CLEFAIRY + 0x4a, // SPECIES_CLEFABLE + 0x17, // SPECIES_VULPIX + 0x10, // SPECIES_NINETALES + 0x48, // SPECIES_JIGGLYPUFF + 0x31, // SPECIES_WIGGLYTUFF + 0x00, // SPECIES_ZUBAT + 0x1d, // SPECIES_GOLBAT + 0x00, // SPECIES_ODDISH + 0x45, // SPECIES_GLOOM + 0x49, // SPECIES_VILEPLUME + 0x46, // SPECIES_PARAS + 0x0f, // SPECIES_PARASECT + 0x06, // SPECIES_VENONAT + 0x4b, // SPECIES_VENOMOTH + 0x10, // SPECIES_DIGLETT + 0x4c, // SPECIES_DUGTRIO + 0x52, // SPECIES_MEOWTH + 0x17, // SPECIES_PERSIAN + 0x06, // SPECIES_PSYDUCK + 0x4c, // SPECIES_GOLDUCK + 0x32, // SPECIES_MANKEY + 0x48, // SPECIES_PRIMEAPE + 0x25, // SPECIES_GROWLITHE + 0x02, // SPECIES_ARCANINE + 0x00, // SPECIES_POLIWAG + 0x32, // SPECIES_POLIWHIRL + 0x19, // SPECIES_POLIWRATH + 0x31, // SPECIES_ABRA + 0x09, // SPECIES_KADABRA + 0x17, // SPECIES_ALAKAZAM + 0x00, // SPECIES_MACHOP + 0x10, // SPECIES_MACHOKE + 0x31, // SPECIES_MACHAMP + 0x17, // SPECIES_BELLSPROUT + 0x0d, // SPECIES_WEEPINBELL + 0x32, // SPECIES_VICTREEBEL + 0x00, // SPECIES_TENTACOOL + 0x00, // SPECIES_TENTACRUEL + 0x48, // SPECIES_GEODUDE + 0x48, // SPECIES_GRAVELER + 0x2f, // SPECIES_GOLEM + 0x20, // SPECIES_PONYTA + 0x11, // SPECIES_RAPIDASH + 0x45, // SPECIES_SLOWPOKE + 0x0b, // SPECIES_SLOWBRO + 0x54, // SPECIES_MAGNEMITE + 0x2c, // SPECIES_MAGNETON + 0x48, // SPECIES_FARFETCHD + 0x4c, // SPECIES_DODUO + 0x41, // SPECIES_DODRIO + 0x0b, // SPECIES_SEEL + 0x45, // SPECIES_DEWGONG + 0x46, // SPECIES_GRIMER + 0x30, // SPECIES_MUK + 0x12, // SPECIES_SHELLDER + 0x1d, // SPECIES_CLOYSTER + 0x15, // SPECIES_GASTLY + 0x35, // SPECIES_HAUNTER + 0x3a, // SPECIES_GENGAR + 0x43, // SPECIES_ONIX + 0x4f, // SPECIES_DROWZEE + 0x09, // SPECIES_HYPNO + 0x03, // SPECIES_KRABBY + 0x4b, // SPECIES_KINGLER + 0x00, // SPECIES_VOLTORB + 0x00, // SPECIES_ELECTRODE + 0x46, // SPECIES_EXEGGCUTE + 0x32, // SPECIES_EXEGGUTOR + 0x48, // SPECIES_CUBONE + 0x05, // SPECIES_MAROWAK + 0x16, // SPECIES_HITMONLEE + 0x09, // SPECIES_HITMONCHAN + 0x45, // SPECIES_LICKITUNG + 0x13, // SPECIES_KOFFING + 0x04, // SPECIES_WEEZING + 0x10, // SPECIES_RHYHORN + 0x13, // SPECIES_RHYDON + 0x45, // SPECIES_CHANSEY + 0x48, // SPECIES_TANGELA + 0x17, // SPECIES_KANGASKHAN + 0x12, // SPECIES_HORSEA + 0x04, // SPECIES_SEADRA + 0x0d, // SPECIES_GOLDEEN + 0x1c, // SPECIES_SEAKING + 0x4e, // SPECIES_STARYU + 0x12, // SPECIES_STARMIE + 0x46, // SPECIES_MR_MIME + 0x02, // SPECIES_SCYTHER + 0x17, // SPECIES_JYNX + 0x2c, // SPECIES_ELECTABUZZ + 0x0f, // SPECIES_MAGMAR + 0x09, // SPECIES_PINSIR + 0x19, // SPECIES_TAUROS + 0x05, // SPECIES_MAGIKARP + 0x48, // SPECIES_GYARADOS + 0x17, // SPECIES_LAPRAS + 0x01, // SPECIES_DITTO + 0x17, // SPECIES_EEVEE + 0x17, // SPECIES_VAPOREON + 0x00, // SPECIES_JOLTEON + 0x17, // SPECIES_FLAREON + 0x52, // SPECIES_PORYGON + 0x51, // SPECIES_OMANYTE + 0x09, // SPECIES_OMASTAR + 0x1d, // SPECIES_KABUTO + 0x0f, // SPECIES_KABUTOPS + 0x47, // SPECIES_AERODACTYL + 0x0b, // SPECIES_SNORLAX + 0x09, // SPECIES_ARTICUNO + 0x2c, // SPECIES_ZAPDOS + 0x45, // SPECIES_MOLTRES + 0x00, // SPECIES_DRATINI + 0x10, // SPECIES_DRAGONAIR + 0x47, // SPECIES_DRAGONITE + 0x09, // SPECIES_MEWTWO + 0x0d, // SPECIES_MEW + 0x00, // SPECIES_CHIKORITA + 0x00, // SPECIES_BAYLEEF + 0x17, // SPECIES_MEGANIUM + 0x52, // SPECIES_CYNDAQUIL + 0x17, // SPECIES_QUILAVA + 0x10, // SPECIES_TYPHLOSION + 0x31, // SPECIES_TOTODILE + 0x0f, // SPECIES_CROCONAW + 0x0f, // SPECIES_FERALIGATR + 0x00, // SPECIES_SENTRET + 0x32, // SPECIES_FURRET + 0x47, // SPECIES_HOOTHOOT + 0x17, // SPECIES_NOCTOWL + 0x52, // SPECIES_LEDYBA + 0x47, // SPECIES_LEDIAN + 0x4f, // SPECIES_SPINARAK + 0x0f, // SPECIES_ARIADOS + 0x00, // SPECIES_CROBAT + 0x45, // SPECIES_CHINCHOU + 0x51, // SPECIES_LANTURN + 0x1e, // SPECIES_PICHU + 0x52, // SPECIES_CLEFFA + 0x0c, // SPECIES_IGGLYBUFF + 0x0b, // SPECIES_TOGEPI + 0x00, // SPECIES_TOGETIC + 0x31, // SPECIES_NATU + 0x09, // SPECIES_XATU + 0x00, // SPECIES_MAREEP + 0x1e, // SPECIES_FLAAFFY + 0x2c, // SPECIES_AMPHAROS + 0x0b, // SPECIES_BELLOSSOM + 0x00, // SPECIES_MARILL + 0x4a, // SPECIES_AZUMARILL + 0x46, // SPECIES_SUDOWOODO + 0x32, // SPECIES_POLITOED + 0x1c, // SPECIES_HOPPIP + 0x18, // SPECIES_SKIPLOOM + 0x51, // SPECIES_JUMPLUFF + 0x32, // SPECIES_AIPOM + 0x52, // SPECIES_SUNKERN + 0x00, // SPECIES_SUNFLORA + 0x2b, // SPECIES_YANMA + 0x00, // SPECIES_WOOPER + 0x16, // SPECIES_QUAGSIRE + 0x09, // SPECIES_ESPEON + 0x10, // SPECIES_UMBREON + 0x00, // SPECIES_MURKROW + 0x13, // SPECIES_SLOWKING + 0x1c, // SPECIES_MISDREAVUS + 0x0a, // SPECIES_UNOWN + 0x30, // SPECIES_WOBBUFFET + 0x1e, // SPECIES_GIRAFARIG + 0x0b, // SPECIES_PINECO + 0x10, // SPECIES_FORRETRESS + 0x00, // SPECIES_DUNSPARCE + 0x13, // SPECIES_GLIGAR + 0x0f, // SPECIES_STEELIX + 0x17, // SPECIES_SNUBBULL + 0x10, // SPECIES_GRANBULL + 0x3a, // SPECIES_QWILFISH + 0x02, // SPECIES_SCIZOR + 0x0b, // SPECIES_SHUCKLE + 0x41, // SPECIES_HERACROSS + 0x16, // SPECIES_SNEASEL + 0x17, // SPECIES_TEDDIURSA + 0x10, // SPECIES_URSARING + 0x17, // SPECIES_SLUGMA + 0x17, // SPECIES_MAGCARGO + 0x00, // SPECIES_SWINUB + 0x0f, // SPECIES_PILOSWINE + 0x03, // SPECIES_CORSOLA + 0x52, // SPECIES_REMORAID + 0x17, // SPECIES_OCTILLERY + 0x52, // SPECIES_DELIBIRD + 0x0d, // SPECIES_MANTINE + 0x17, // SPECIES_SKARMORY + 0x17, // SPECIES_HOUNDOUR + 0x10, // SPECIES_HOUNDOOM + 0x42, // SPECIES_KINGDRA + 0x32, // SPECIES_PHANPY + 0x19, // SPECIES_DONPHAN + 0x00, // SPECIES_PORYGON2 + 0x00, // SPECIES_STANTLER + 0x31, // SPECIES_SMEARGLE + 0x16, // SPECIES_TYROGUE + 0x02, // SPECIES_HITMONTOP + 0x09, // SPECIES_SMOOCHUM + 0x2c, // SPECIES_ELEKID + 0x00, // SPECIES_MAGBY + 0x45, // SPECIES_MILTANK + 0x00, // SPECIES_BLISSEY + 0x2c, // SPECIES_RAIKOU + 0x09, // SPECIES_ENTEI + 0x10, // SPECIES_SUICUNE + 0x52, // SPECIES_LARVITAR + 0x10, // SPECIES_PUPITAR + 0x0f, // SPECIES_TYRANITAR + 0x3a, // SPECIES_LUGIA + 0x09, // SPECIES_HO_OH + 0x18, // SPECIES_CELEBI + 0x00, // 252 + 0x00, // 253 + 0x00, // 254 + 0x00, // 255 + 0x00, // 256 + 0x00, // 257 + 0x00, // 258 + 0x00, // 259 + 0x00, // 260 + 0x00, // 261 + 0x00, // 262 + 0x00, // 263 + 0x00, // 264 + 0x00, // 265 + 0x00, // 266 + 0x00, // 267 + 0x00, // 268 + 0x00, // 269 + 0x00, // 270 + 0x00, // 271 + 0x00, // 272 + 0x00, // 273 + 0x00, // 274 + 0x00, // 275 + 0x00, // 276 + 0x00, // SPECIES_TREECKO + 0x17, // SPECIES_GROVYLE + 0x10, // SPECIES_SCEPTILE + 0x16, // SPECIES_TORCHIC + 0x06, // SPECIES_COMBUSKEN + 0x0f, // SPECIES_BLAZIKEN + 0x01, // SPECIES_MUDKIP + 0x04, // SPECIES_MARSHTOMP + 0x1e, // SPECIES_SWAMPERT + 0x10, // SPECIES_POOCHYENA + 0x10, // SPECIES_MIGHTYENA + 0x03, // SPECIES_ZIGZAGOON + 0x09, // SPECIES_LINOONE + 0x00, // SPECIES_WURMPLE + 0x00, // SPECIES_SILCOON + 0x04, // SPECIES_BEAUTIFLY + 0x04, // SPECIES_CASCOON + 0x06, // SPECIES_DUSTOX + 0x00, // SPECIES_LOTAD + 0x00, // SPECIES_LOMBRE + 0x49, // SPECIES_LUDICOLO + 0x05, // SPECIES_SEEDOT + 0x00, // SPECIES_NUZLEAF + 0x02, // SPECIES_SHIFTRY + 0x00, // SPECIES_NINCADA + 0x46, // SPECIES_NINJASK + 0x1c, // SPECIES_SHEDINJA + 0x1e, // SPECIES_TAILLOW + 0x01, // SPECIES_SWELLOW + 0x00, // SPECIES_SHROOMISH + 0x00, // SPECIES_BRELOOM + 0x31, // SPECIES_SPINDA + 0x1b, // SPECIES_WINGULL + 0x1c, // SPECIES_PELIPPER + 0x00, // SPECIES_SURSKIT + 0x00, // SPECIES_MASQUERAIN + 0x01, // SPECIES_WAILMER + 0x1c, // SPECIES_WAILORD + 0x00, // SPECIES_SKITTY + 0x17, // SPECIES_DELCATTY + 0x35, // SPECIES_KECLEON + 0x1d, // SPECIES_BALTOY + 0x51, // SPECIES_CLAYDOL + 0x49, // SPECIES_NOSEPASS + 0x17, // SPECIES_TORKOAL + 0x15, // SPECIES_SABLEYE + 0x49, // SPECIES_BARBOACH + 0x49, // SPECIES_WHISCASH + 0x1d, // SPECIES_LUVDISC + 0x10, // SPECIES_CORPHISH + 0x09, // SPECIES_CRAWDAUNT + 0x49, // SPECIES_FEEBAS + 0x22, // SPECIES_MILOTIC + 0x49, // SPECIES_CARVANHA + 0x56, // SPECIES_SHARPEDO + 0x10, // SPECIES_TRAPINCH + 0x0f, // SPECIES_VIBRAVA + 0x4b, // SPECIES_FLYGON + 0x0b, // SPECIES_MAKUHITA + 0x34, // SPECIES_HARIYAMA + 0x00, // SPECIES_ELECTRIKE + 0x00, // SPECIES_MANECTRIC + 0x04, // SPECIES_NUMEL + 0x10, // SPECIES_CAMERUPT + 0x53, // SPECIES_SPHEAL + 0x17, // SPECIES_SEALEO + 0x0f, // SPECIES_WALREIN + 0x49, // SPECIES_CACNEA + 0x04, // SPECIES_CACTURNE + 0x45, // SPECIES_SNORUNT + 0x0a, // SPECIES_GLALIE + 0x0e, // SPECIES_LUNATONE + 0x08, // SPECIES_SOLROCK + 0x00, // SPECIES_AZURILL + 0x56, // SPECIES_SPOINK + 0x32, // SPECIES_GRUMPIG + 0x00, // SPECIES_PLUSLE + 0x01, // SPECIES_MINUN + 0x00, // SPECIES_MAWILE + 0x05, // SPECIES_MEDITITE + 0x45, // SPECIES_MEDICHAM + 0x04, // SPECIES_SWABLU + 0x16, // SPECIES_ALTARIA + 0x32, // SPECIES_WYNAUT + 0x0a, // SPECIES_DUSKULL + 0x02, // SPECIES_DUSCLOPS + 0x45, // SPECIES_ROSELIA + 0x45, // SPECIES_SLAKOTH + 0x31, // SPECIES_VIGOROTH + 0x45, // SPECIES_SLAKING + 0x00, // SPECIES_GULPIN + 0x45, // SPECIES_SWALOT + 0x10, // SPECIES_TROPIUS + 0x03, // SPECIES_WHISMUR + 0x49, // SPECIES_LOUDRED + 0x19, // SPECIES_EXPLOUD + 0x12, // SPECIES_CLAMPERL + 0x09, // SPECIES_HUNTAIL + 0x1c, // SPECIES_GOREBYSS + 0x11, // SPECIES_ABSOL + 0x1c, // SPECIES_SHUPPET + 0x0d, // SPECIES_BANETTE + 0x17, // SPECIES_SEVIPER + 0x09, // SPECIES_ZANGOOSE + 0x1a, // SPECIES_RELICANTH + 0x45, // SPECIES_ARON + 0x00, // SPECIES_LAIRON + 0x19, // SPECIES_AGGRON + 0x1d, // SPECIES_CASTFORM + 0x00, // SPECIES_VOLBEAT + 0x05, // SPECIES_ILLUMISE + 0x17, // SPECIES_LILEEP + 0x19, // SPECIES_CRADILY + 0x12, // SPECIES_ANORITH + 0x10, // SPECIES_ARMALDO + 0x45, // SPECIES_RALTS + 0x00, // SPECIES_KIRLIA + 0x00, // SPECIES_GARDEVOIR + 0x19, // SPECIES_BAGON + 0x04, // SPECIES_SHELGON + 0x0f, // SPECIES_SALAMENCE + 0x0f, // SPECIES_BELDUM + 0x04, // SPECIES_METANG + 0x10, // SPECIES_METAGROSS + 0x01, // SPECIES_REGIROCK + 0x44, // SPECIES_REGICE + 0x09, // SPECIES_REGISTEEL + 0x2d, // SPECIES_KYOGRE + 0x10, // SPECIES_GROUDON + 0x0f, // SPECIES_RAYQUAZA + 0x2d, // SPECIES_LATIAS + 0x10, // SPECIES_LATIOS + 0x0d, // SPECIES_JIRACHI + 0x1b, // SPECIES_DEOXYS + 0x1d, // SPECIES_CHIMECHO +}; + +static const u8 sMonAnimationDelayTable[] = +{ + 0x00, // SPECIES_BULBASAUR + 0x00, // SPECIES_IVYSAUR + 0x00, // SPECIES_VENUSAUR + 0x00, // SPECIES_CHARMANDER + 0x00, // SPECIES_CHARMELEON + 0x00, // SPECIES_CHARIZARD + 0x00, // SPECIES_SQUIRTLE + 0x00, // SPECIES_WARTORTLE + 0x32, // SPECIES_BLASTOISE + 0x00, // SPECIES_CATERPIE + 0x00, // SPECIES_METAPOD + 0x00, // SPECIES_BUTTERFREE + 0x0a, // SPECIES_WEEDLE + 0x14, // SPECIES_KAKUNA + 0x23, // SPECIES_BEEDRILL + 0x00, // SPECIES_PIDGEY + 0x19, // SPECIES_PIDGEOTTO + 0x00, // SPECIES_PIDGEOT + 0x00, // SPECIES_RATTATA + 0x00, // SPECIES_RATICATE + 0x00, // SPECIES_SPEAROW + 0x02, // SPECIES_FEAROW + 0x1e, // SPECIES_EKANS + 0x00, // SPECIES_ARBOK + 0x00, // SPECIES_PIKACHU + 0x00, // SPECIES_RAICHU + 0x00, // SPECIES_SANDSHREW + 0x00, // SPECIES_SANDSLASH + 0x1c, // SPECIES_NIDORAN_F + 0x00, // SPECIES_NIDORINA + 0x00, // SPECIES_NIDOQUEEN + 0x00, // SPECIES_NIDORAN_M + 0x00, // SPECIES_NIDORINO + 0x19, // SPECIES_NIDOKING + 0x00, // SPECIES_CLEFAIRY + 0x00, // SPECIES_CLEFABLE + 0x00, // SPECIES_VULPIX + 0x00, // SPECIES_NINETALES + 0x00, // SPECIES_JIGGLYPUFF + 0x00, // SPECIES_WIGGLYTUFF + 0x00, // SPECIES_ZUBAT + 0x00, // SPECIES_GOLBAT + 0x00, // SPECIES_ODDISH + 0x00, // SPECIES_GLOOM + 0x00, // SPECIES_VILEPLUME + 0x0a, // SPECIES_PARAS + 0x2d, // SPECIES_PARASECT + 0x14, // SPECIES_VENONAT + 0x00, // SPECIES_VENOMOTH + 0x19, // SPECIES_DIGLETT + 0x23, // SPECIES_DUGTRIO + 0x28, // SPECIES_MEOWTH + 0x14, // SPECIES_PERSIAN + 0x00, // SPECIES_PSYDUCK + 0x00, // SPECIES_GOLDUCK + 0x14, // SPECIES_MANKEY + 0x00, // SPECIES_PRIMEAPE + 0x1e, // SPECIES_GROWLITHE + 0x28, // SPECIES_ARCANINE + 0x00, // SPECIES_POLIWAG + 0x05, // SPECIES_POLIWHIRL + 0x00, // SPECIES_POLIWRATH + 0x00, // SPECIES_ABRA + 0x00, // SPECIES_KADABRA + 0x00, // SPECIES_ALAKAZAM + 0x00, // SPECIES_MACHOP + 0x00, // SPECIES_MACHOKE + 0x00, // SPECIES_MACHAMP + 0x00, // SPECIES_BELLSPROUT + 0x03, // SPECIES_WEEPINBELL + 0x00, // SPECIES_VICTREEBEL + 0x00, // SPECIES_TENTACOOL + 0x00, // SPECIES_TENTACRUEL + 0x00, // SPECIES_GEODUDE + 0x00, // SPECIES_GRAVELER + 0x00, // SPECIES_GOLEM + 0x00, // SPECIES_PONYTA + 0x00, // SPECIES_RAPIDASH + 0x00, // SPECIES_SLOWPOKE + 0x00, // SPECIES_SLOWBRO + 0x00, // SPECIES_MAGNEMITE + 0x00, // SPECIES_MAGNETON + 0x00, // SPECIES_FARFETCHD + 0x00, // SPECIES_DODUO + 0x00, // SPECIES_DODRIO + 0x00, // SPECIES_SEEL + 0x00, // SPECIES_DEWGONG + 0x00, // SPECIES_GRIMER + 0x2d, // SPECIES_MUK + 0x14, // SPECIES_SHELLDER + 0x00, // SPECIES_CLOYSTER + 0x00, // SPECIES_GASTLY + 0x17, // SPECIES_HAUNTER + 0x00, // SPECIES_GENGAR + 0x00, // SPECIES_ONIX + 0x30, // SPECIES_DROWZEE + 0x28, // SPECIES_HYPNO + 0x00, // SPECIES_KRABBY + 0x00, // SPECIES_KINGLER + 0x00, // SPECIES_VOLTORB + 0x00, // SPECIES_ELECTRODE + 0x00, // SPECIES_EXEGGCUTE + 0x00, // SPECIES_EXEGGUTOR + 0x00, // SPECIES_CUBONE + 0x00, // SPECIES_MAROWAK + 0x00, // SPECIES_HITMONLEE + 0x19, // SPECIES_HITMONCHAN + 0x00, // SPECIES_LICKITUNG + 0x00, // SPECIES_KOFFING + 0x00, // SPECIES_WEEZING + 0x00, // SPECIES_RHYHORN + 0x00, // SPECIES_RHYDON + 0x00, // SPECIES_CHANSEY + 0x00, // SPECIES_TANGELA + 0x00, // SPECIES_KANGASKHAN + 0x00, // SPECIES_HORSEA + 0x00, // SPECIES_SEADRA + 0x00, // SPECIES_GOLDEEN + 0x00, // SPECIES_SEAKING + 0x00, // SPECIES_STARYU + 0x00, // SPECIES_STARMIE + 0x00, // SPECIES_MR_MIME + 0x0a, // SPECIES_SCYTHER + 0x00, // SPECIES_JYNX + 0x00, // SPECIES_ELECTABUZZ + 0x00, // SPECIES_MAGMAR + 0x00, // SPECIES_PINSIR + 0x0a, // SPECIES_TAUROS + 0x00, // SPECIES_MAGIKARP + 0x00, // SPECIES_GYARADOS + 0x00, // SPECIES_LAPRAS + 0x00, // SPECIES_DITTO + 0x00, // SPECIES_EEVEE + 0x00, // SPECIES_VAPOREON + 0x00, // SPECIES_JOLTEON + 0x00, // SPECIES_FLAREON + 0x00, // SPECIES_PORYGON + 0x00, // SPECIES_OMANYTE + 0x00, // SPECIES_OMASTAR + 0x00, // SPECIES_KABUTO + 0x00, // SPECIES_KABUTOPS + 0x00, // SPECIES_AERODACTYL + 0x00, // SPECIES_SNORLAX + 0x00, // SPECIES_ARTICUNO + 0x00, // SPECIES_ZAPDOS + 0x00, // SPECIES_MOLTRES + 0x00, // SPECIES_DRATINI + 0x00, // SPECIES_DRAGONAIR + 0x00, // SPECIES_DRAGONITE + 0x00, // SPECIES_MEWTWO + 0x00, // SPECIES_MEW + 0x00, // SPECIES_CHIKORITA + 0x00, // SPECIES_BAYLEEF + 0x00, // SPECIES_MEGANIUM + 0x00, // SPECIES_CYNDAQUIL + 0x00, // SPECIES_QUILAVA + 0x14, // SPECIES_TYPHLOSION + 0x00, // SPECIES_TOTODILE + 0x00, // SPECIES_CROCONAW + 0x05, // SPECIES_FERALIGATR + 0x00, // SPECIES_SENTRET + 0x00, // SPECIES_FURRET + 0x00, // SPECIES_HOOTHOOT + 0x00, // SPECIES_NOCTOWL + 0x00, // SPECIES_LEDYBA + 0x00, // SPECIES_LEDIAN + 0x00, // SPECIES_SPINARAK + 0x00, // SPECIES_ARIADOS + 0x00, // SPECIES_CROBAT + 0x00, // SPECIES_CHINCHOU + 0x00, // SPECIES_LANTURN + 0x00, // SPECIES_PICHU + 0x00, // SPECIES_CLEFFA + 0x00, // SPECIES_IGGLYBUFF + 0x00, // SPECIES_TOGEPI + 0x00, // SPECIES_TOGETIC + 0x1e, // SPECIES_NATU + 0x00, // SPECIES_XATU + 0x32, // SPECIES_MAREEP + 0x00, // SPECIES_FLAAFFY + 0x0a, // SPECIES_AMPHAROS + 0x00, // SPECIES_BELLOSSOM + 0x00, // SPECIES_MARILL + 0x00, // SPECIES_AZUMARILL + 0x00, // SPECIES_SUDOWOODO + 0x28, // SPECIES_POLITOED + 0x00, // SPECIES_HOPPIP + 0x00, // SPECIES_SKIPLOOM + 0x00, // SPECIES_JUMPLUFF + 0x00, // SPECIES_AIPOM + 0x00, // SPECIES_SUNKERN + 0x00, // SPECIES_SUNFLORA + 0x00, // SPECIES_YANMA + 0x00, // SPECIES_WOOPER + 0x00, // SPECIES_QUAGSIRE + 0x00, // SPECIES_ESPEON + 0x00, // SPECIES_UMBREON + 0x00, // SPECIES_MURKROW + 0x00, // SPECIES_SLOWKING + 0x00, // SPECIES_MISDREAVUS + 0x00, // SPECIES_UNOWN + 0x00, // SPECIES_WOBBUFFET + 0x00, // SPECIES_GIRAFARIG + 0x00, // SPECIES_PINECO + 0x00, // SPECIES_FORRETRESS + 0x0a, // SPECIES_DUNSPARCE + 0x00, // SPECIES_GLIGAR + 0x2d, // SPECIES_STEELIX + 0x00, // SPECIES_SNUBBULL + 0x00, // SPECIES_GRANBULL + 0x27, // SPECIES_QWILFISH + 0x13, // SPECIES_SCIZOR + 0x00, // SPECIES_SHUCKLE + 0x00, // SPECIES_HERACROSS + 0x00, // SPECIES_SNEASEL + 0x00, // SPECIES_TEDDIURSA + 0x00, // SPECIES_URSARING + 0x00, // SPECIES_SLUGMA + 0x00, // SPECIES_MAGCARGO + 0x00, // SPECIES_SWINUB + 0x00, // SPECIES_PILOSWINE + 0x00, // SPECIES_CORSOLA + 0x00, // SPECIES_REMORAID + 0x14, // SPECIES_OCTILLERY + 0x00, // SPECIES_DELIBIRD + 0x00, // SPECIES_MANTINE + 0x00, // SPECIES_SKARMORY + 0x00, // SPECIES_HOUNDOUR + 0x00, // SPECIES_HOUNDOOM + 0x00, // SPECIES_KINGDRA + 0x00, // SPECIES_PHANPY + 0x00, // SPECIES_DONPHAN + 0x00, // SPECIES_PORYGON2 + 0x00, // SPECIES_STANTLER + 0x00, // SPECIES_SMEARGLE + 0x00, // SPECIES_TYROGUE + 0x00, // SPECIES_HITMONTOP + 0x28, // SPECIES_SMOOCHUM + 0x00, // SPECIES_ELEKID + 0x00, // SPECIES_MAGBY + 0x00, // SPECIES_MILTANK + 0x00, // SPECIES_BLISSEY + 0x00, // SPECIES_RAIKOU + 0x00, // SPECIES_ENTEI + 0x00, // SPECIES_SUICUNE + 0x00, // SPECIES_LARVITAR + 0x00, // SPECIES_PUPITAR + 0x0a, // SPECIES_TYRANITAR + 0x14, // SPECIES_LUGIA + 0x00, // SPECIES_HO_OH + 0x00, // SPECIES_CELEBI + 0x00, // 252 + 0x00, // 253 + 0x00, // 254 + 0x00, // 255 + 0x00, // 256 + 0x00, // 257 + 0x00, // 258 + 0x00, // 259 + 0x00, // 260 + 0x00, // 261 + 0x00, // 262 + 0x00, // 263 + 0x00, // 264 + 0x00, // 265 + 0x00, // 266 + 0x00, // 267 + 0x00, // 268 + 0x00, // 269 + 0x00, // 270 + 0x00, // 271 + 0x00, // 272 + 0x00, // 273 + 0x00, // 274 + 0x00, // 275 + 0x00, // 276 + 0x00, // SPECIES_TREECKO + 0x00, // SPECIES_GROVYLE + 0x00, // SPECIES_SCEPTILE + 0x00, // SPECIES_TORCHIC + 0x00, // SPECIES_COMBUSKEN + 0x00, // SPECIES_BLAZIKEN + 0x00, // SPECIES_MUDKIP + 0x00, // SPECIES_MARSHTOMP + 0x00, // SPECIES_SWAMPERT + 0x00, // SPECIES_POOCHYENA + 0x00, // SPECIES_MIGHTYENA + 0x00, // SPECIES_ZIGZAGOON + 0x00, // SPECIES_LINOONE + 0x00, // SPECIES_WURMPLE + 0x00, // SPECIES_SILCOON + 0x00, // SPECIES_BEAUTIFLY + 0x00, // SPECIES_CASCOON + 0x00, // SPECIES_DUSTOX + 0x00, // SPECIES_LOTAD + 0x00, // SPECIES_LOMBRE + 0x00, // SPECIES_LUDICOLO + 0x00, // SPECIES_SEEDOT + 0x00, // SPECIES_NUZLEAF + 0x00, // SPECIES_SHIFTRY + 0x00, // SPECIES_NINCADA + 0x00, // SPECIES_NINJASK + 0x00, // SPECIES_SHEDINJA + 0x00, // SPECIES_TAILLOW + 0x00, // SPECIES_SWELLOW + 0x00, // SPECIES_SHROOMISH + 0x00, // SPECIES_BRELOOM + 0x00, // SPECIES_SPINDA + 0x00, // SPECIES_WINGULL + 0x00, // SPECIES_PELIPPER + 0x00, // SPECIES_SURSKIT + 0x00, // SPECIES_MASQUERAIN + 0x00, // SPECIES_WAILMER + 0x0a, // SPECIES_WAILORD + 0x00, // SPECIES_SKITTY + 0x00, // SPECIES_DELCATTY + 0x1e, // SPECIES_KECLEON + 0x00, // SPECIES_BALTOY + 0x00, // SPECIES_CLAYDOL + 0x00, // SPECIES_NOSEPASS + 0x00, // SPECIES_TORKOAL + 0x00, // SPECIES_SABLEYE + 0x00, // SPECIES_BARBOACH + 0x00, // SPECIES_WHISCASH + 0x00, // SPECIES_LUVDISC + 0x00, // SPECIES_CORPHISH + 0x00, // SPECIES_CRAWDAUNT + 0x00, // SPECIES_FEEBAS + 0x2d, // SPECIES_MILOTIC + 0x00, // SPECIES_CARVANHA + 0x00, // SPECIES_SHARPEDO + 0x00, // SPECIES_TRAPINCH + 0x00, // SPECIES_VIBRAVA + 0x00, // SPECIES_FLYGON + 0x00, // SPECIES_MAKUHITA + 0x00, // SPECIES_HARIYAMA + 0x00, // SPECIES_ELECTRIKE + 0x00, // SPECIES_MANECTRIC + 0x00, // SPECIES_NUMEL + 0x00, // SPECIES_CAMERUPT + 0x0f, // SPECIES_SPHEAL + 0x00, // SPECIES_SEALEO + 0x00, // SPECIES_WALREIN + 0x00, // SPECIES_CACNEA + 0x00, // SPECIES_CACTURNE + 0x14, // SPECIES_SNORUNT + 0x00, // SPECIES_GLALIE + 0x00, // SPECIES_LUNATONE + 0x00, // SPECIES_SOLROCK + 0x00, // SPECIES_AZURILL + 0x00, // SPECIES_SPOINK + 0x0f, // SPECIES_GRUMPIG + 0x00, // SPECIES_PLUSLE + 0x00, // SPECIES_MINUN + 0x00, // SPECIES_MAWILE + 0x00, // SPECIES_MEDITITE + 0x00, // SPECIES_MEDICHAM + 0x00, // SPECIES_SWABLU + 0x00, // SPECIES_ALTARIA + 0x0f, // SPECIES_WYNAUT + 0x00, // SPECIES_DUSKULL + 0x1e, // SPECIES_DUSCLOPS + 0x00, // SPECIES_ROSELIA + 0x00, // SPECIES_SLAKOTH + 0x00, // SPECIES_VIGOROTH + 0x00, // SPECIES_SLAKING + 0x00, // SPECIES_GULPIN + 0x00, // SPECIES_SWALOT + 0x00, // SPECIES_TROPIUS + 0x00, // SPECIES_WHISMUR + 0x00, // SPECIES_LOUDRED + 0x00, // SPECIES_EXPLOUD + 0x00, // SPECIES_CLAMPERL + 0x00, // SPECIES_HUNTAIL + 0x00, // SPECIES_GOREBYSS + 0x2d, // SPECIES_ABSOL + 0x00, // SPECIES_SHUPPET + 0x00, // SPECIES_BANETTE + 0x00, // SPECIES_SEVIPER + 0x00, // SPECIES_ZANGOOSE + 0x00, // SPECIES_RELICANTH + 0x00, // SPECIES_ARON + 0x00, // SPECIES_LAIRON + 0x00, // SPECIES_AGGRON + 0x00, // SPECIES_CASTFORM + 0x00, // SPECIES_VOLBEAT + 0x00, // SPECIES_ILLUMISE + 0x00, // SPECIES_LILEEP + 0x00, // SPECIES_CRADILY + 0x00, // SPECIES_ANORITH + 0x00, // SPECIES_ARMALDO + 0x00, // SPECIES_RALTS + 0x00, // SPECIES_KIRLIA + 0x00, // SPECIES_GARDEVOIR + 0x00, // SPECIES_BAGON + 0x00, // SPECIES_SHELGON + 0x46, // SPECIES_SALAMENCE + 0x00, // SPECIES_BELDUM + 0x00, // SPECIES_METANG + 0x00, // SPECIES_METAGROSS + 0x00, // SPECIES_REGIROCK + 0x00, // SPECIES_REGICE + 0x00, // SPECIES_REGISTEEL + 0x3c, // SPECIES_KYOGRE + 0x00, // SPECIES_GROUDON + 0x3c, // SPECIES_RAYQUAZA + 0x00, // SPECIES_LATIAS + 0x00, // SPECIES_LATIOS + 0x00, // SPECIES_JIRACHI + 0x00, // SPECIES_DEOXYS + 0x00, // SPECIES_CHIMECHO +}; + +const u8 gUnknown_08329D22[] = {0x03, 0x0c, 0x30, 0xc0}; // Masks for getting PP Up count, also PP Max values +const u8 gUnknown_08329D26[] = {0xfc, 0xf3, 0xcf, 0x3f}; // Masks for setting PP Up count +const u8 gUnknown_08329D2A[] = {0x01, 0x04, 0x10, 0x40}; // Values added to PP Up count + +const u8 gStatStageRatios[][2] = +{ + {10, 40}, // -6 + {10, 35}, // -5 + {10, 30}, // -4 + {10, 25}, // -3 + {10, 20}, // -2 + {10, 15}, // -1 + {10, 10}, // 0 + {15, 10}, // +1 + {20, 10}, // +2 + {25, 10}, // +3 + {30, 10}, // +4 + {35, 10}, // +5 + {40, 10}, // +6 +}; + +static const u16 sDeoxysBaseStats[] = +{ + 50, // Hp + 95, // Attack + 90, // Defense + 180, // Speed + 95, // Sp.Attack + 90, // Sp.Defense +}; + +const u16 gUnknown_08329D54[] = +{ + FACILITY_CLASS_COOLTRAINER_M, FACILITY_CLASS_BLACK_BELT, FACILITY_CLASS_CAMPER, + FACILITY_CLASS_YOUNGSTER, FACILITY_CLASS_PSYCHIC_M, FACILITY_CLASS_BUG_CATCHER, + FACILITY_CLASS_PKMN_BREEDER_2, FACILITY_CLASS_GUITARIST, FACILITY_CLASS_COOLTRAINER_F, + FACILITY_CLASS_HEX_MANIAC, FACILITY_CLASS_PICNICKER, FACILITY_CLASS_LASS, + FACILITY_CLASS_PSYCHIC_F, FACILITY_CLASS_BATTLE_GIRL, FACILITY_CLASS_PKMN_BREEDER_1, + FACILITY_CLASS_BEAUTY +}; + +static const u8 sHoldEffectToType[][2] = +{ + {HOLD_EFFECT_BUG_POWER, TYPE_BUG}, + {HOLD_EFFECT_STEEL_POWER, TYPE_STEEL}, + {HOLD_EFFECT_GROUND_POWER, TYPE_GROUND}, + {HOLD_EFFECT_ROCK_POWER, TYPE_ROCK}, + {HOLD_EFFECT_GRASS_POWER, TYPE_GRASS}, + {HOLD_EFFECT_DARK_POWER, TYPE_DARK}, + {HOLD_EFFECT_FIGHTING_POWER, TYPE_FIGHTING}, + {HOLD_EFFECT_ELECTRIC_POWER, TYPE_ELECTRIC}, + {HOLD_EFFECT_WATER_POWER, TYPE_WATER}, + {HOLD_EFFECT_FLYING_POWER, TYPE_FLYING}, + {HOLD_EFFECT_POISON_POWER, TYPE_POISON}, + {HOLD_EFFECT_ICE_POWER, TYPE_ICE}, + {HOLD_EFFECT_GHOST_POWER, TYPE_GHOST}, + {HOLD_EFFECT_PSYCHIC_POWER, TYPE_PSYCHIC}, + {HOLD_EFFECT_FIRE_POWER, TYPE_FIRE}, + {HOLD_EFFECT_DRAGON_POWER, TYPE_DRAGON}, + {HOLD_EFFECT_NORMAL_POWER, TYPE_NORMAL}, +}; + +const struct SpriteTemplate gUnknown_08329D98[MAX_BATTLERS_COUNT] = +{ + { // B_POSITION_PLAYER_LEFT + .tileTag = 0xFFFF, + .paletteTag = 0, + .oam = &gUnknown_0831ACB0, + .anims = NULL, + .images = gUnknown_082FF3A8, + .affineAnims = gUnknown_082FF618, + .callback = sub_8039BB4, + }, + { // B_POSITION_OPPONENT_LEFT + .tileTag = 0xFFFF, + .paletteTag = 0, + .oam = &gUnknown_0831ACA8, + .anims = NULL, + .images = gUnknown_082FF3C8, + .affineAnims = gUnknown_082FF694, + .callback = oac_poke_opponent, + }, + { // B_POSITION_PLAYER_RIGHT + .tileTag = 0xFFFF, + .paletteTag = 0, + .oam = &gUnknown_0831ACB0, + .anims = NULL, + .images = gUnknown_082FF3E8, + .affineAnims = gUnknown_082FF618, + .callback = sub_8039BB4, + }, + { // B_POSITION_OPPONENT_RIGHT + .tileTag = 0xFFFF, + .paletteTag = 0, + .oam = &gUnknown_0831ACA8, + .anims = NULL, + .images = gUnknown_082FF408, + .affineAnims = gUnknown_082FF694, + .callback = oac_poke_opponent + }, +}; + +static const struct SpriteTemplate gUnknown_08329DF8[] = +{ + { + .tileTag = 0xFFFF, + .paletteTag = 0, + .oam = &gUnknown_0831ACB0, + .anims = NULL, + .images = gUnknown_082FF428, + .affineAnims = gUnknown_082FF618, + .callback = sub_8039BB4, + }, + { + .tileTag = 0xFFFF, + .paletteTag = 0, + .oam = &gUnknown_0831ACB0, + .anims = NULL, + .images = gUnknown_082FF448, + .affineAnims = gUnknown_082FF618, + .callback = sub_8039BB4, + }, + { + .tileTag = 0xFFFF, + .paletteTag = 0, + .oam = &gUnknown_0831ACB0, + .anims = NULL, + .images = gUnknown_082FF468, + .affineAnims = gUnknown_082FF618, + .callback = sub_8039BB4, + }, + { + .tileTag = 0xFFFF, + .paletteTag = 0, + .oam = &gUnknown_0831ACB0, + .anims = NULL, + .images = gUnknown_082FF490, + .affineAnims = gUnknown_082FF618, + .callback = sub_8039BB4, + }, + { + .tileTag = 0xFFFF, + .paletteTag = 0, + .oam = &gUnknown_0831ACB0, + .anims = NULL, + .images = gUnknown_082FF4B8, + .affineAnims = gUnknown_082FF618, + .callback = sub_8039BB4, + }, + { + .tileTag = 0xFFFF, + .paletteTag = 0, + .oam = &gUnknown_0831ACB0, + .anims = NULL, + .images = gUnknown_082FF4D8, + .affineAnims = gUnknown_082FF618, + .callback = sub_8039BB4, + }, + { + .tileTag = 0xFFFF, + .paletteTag = 0, + .oam = &gUnknown_0831ACB0, + .anims = NULL, + .images = gUnknown_082FF4F8, + .affineAnims = gUnknown_082FF618, + .callback = sub_8039BB4, + }, + { + .tileTag = 0xFFFF, + .paletteTag = 0, + .oam = &gUnknown_0831ACB0, + .anims = NULL, + .images = gUnknown_082FF518, + .affineAnims = gUnknown_082FF618, + .callback = sub_8039BB4, + }, +}; + +static const u8 sSecretBaseFacilityClasses[2][5] = +{ + {FACILITY_CLASS_YOUNGSTER, FACILITY_CLASS_BUG_CATCHER, FACILITY_CLASS_RICH_BOY, FACILITY_CLASS_CAMPER, FACILITY_CLASS_COOLTRAINER_M}, + {FACILITY_CLASS_LASS, FACILITY_CLASS_SCHOOL_KID_F, FACILITY_CLASS_LADY, FACILITY_CLASS_PICNICKER, FACILITY_CLASS_COOLTRAINER_F} +}; + +static const u8 sGetMonDataEVConstants[] = +{ + MON_DATA_HP_EV, + MON_DATA_ATK_EV, + MON_DATA_DEF_EV, + MON_DATA_SPEED_EV, + MON_DATA_SPDEF_EV, + MON_DATA_SPATK_EV +}; + +static const u8 gUnknown_08329EC8[] = +{ + STAT_ATK, STAT_ATK, STAT_SPEED, STAT_DEF, STAT_SPATK, STAT_ACC +}; + +static const s8 gUnknown_08329ECE[][3] = +{ + { 5, 3, 2}, + { 5, 3, 2}, + { 1, 1, 0}, + { 3, 2, 1}, + { 1, 1, 0}, + { 1, 1, 1}, + {-1, -1, -1}, + {-5, -5, -10}, + {-5, -5, -10}, +}; + +static const u16 sHMMoves[] = +{ + MOVE_CUT, MOVE_FLY, MOVE_SURF, MOVE_STRENGTH, MOVE_FLASH, + MOVE_ROCK_SMASH, MOVE_WATERFALL, MOVE_DIVE, 0xFFFF +}; + +static const struct SpeciesItem sAlteringCaveWildMonHeldItems[] = +{ + {SPECIES_NONE, ITEM_NONE}, + {SPECIES_MAREEP, ITEM_GANLON_BERRY}, + {SPECIES_PINECO, ITEM_APICOT_BERRY}, + {SPECIES_HOUNDOUR, ITEM_BIG_MUSHROOM}, + {SPECIES_TEDDIURSA, ITEM_PETAYA_BERRY}, + {SPECIES_AIPOM, ITEM_BERRY_JUICE}, + {SPECIES_SHUCKLE, ITEM_BERRY_JUICE}, + {SPECIES_STANTLER, ITEM_PETAYA_BERRY}, + {SPECIES_SMEARGLE, ITEM_SALAC_BERRY}, +}; + +static const struct OamData sOamData_8329F20 = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = 3, + .tileNum = 0, + .priority = 0, + .paletteNum = 0, + .affineParam = 0 +}; + +static const struct SpriteTemplate gUnknown_08329F28 = +{ + .tileTag = 0xFFFF, + .paletteTag = 0xFFFF, + .oam = &sOamData_8329F20, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, +}; + +// code +void ZeroBoxMonData(struct BoxPokemon *boxMon) +{ + u8 *raw = (u8 *)boxMon; + u32 i; + for (i = 0; i < sizeof(struct BoxPokemon); i++) + raw[i] = 0; +} + +void ZeroMonData(struct Pokemon *mon) +{ + u32 arg; + ZeroBoxMonData(&mon->box); + arg = 0; + SetMonData(mon, MON_DATA_STATUS, &arg); + SetMonData(mon, MON_DATA_LEVEL, &arg); + SetMonData(mon, MON_DATA_HP, &arg); + SetMonData(mon, MON_DATA_MAX_HP, &arg); + SetMonData(mon, MON_DATA_ATK, &arg); + SetMonData(mon, MON_DATA_DEF, &arg); + SetMonData(mon, MON_DATA_SPEED, &arg); + SetMonData(mon, MON_DATA_SPATK, &arg); + SetMonData(mon, MON_DATA_SPDEF, &arg); + arg = 255; + SetMonData(mon, MON_DATA_MAIL, &arg); +} + +void ZeroPlayerPartyMons(void) +{ + s32 i; + for (i = 0; i < PARTY_SIZE; i++) + ZeroMonData(&gPlayerParty[i]); +} + +void ZeroEnemyPartyMons(void) +{ + s32 i; + for (i = 0; i < PARTY_SIZE; i++) + ZeroMonData(&gEnemyParty[i]); +} + +void CreateMon(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 hasFixedPersonality, u32 fixedPersonality, u8 otIdType, u32 fixedOtId) +{ + u32 arg; + ZeroMonData(mon); + CreateBoxMon(&mon->box, species, level, fixedIV, hasFixedPersonality, fixedPersonality, otIdType, fixedOtId); + SetMonData(mon, MON_DATA_LEVEL, &level); + arg = 255; + SetMonData(mon, MON_DATA_MAIL, &arg); + CalculateMonStats(mon); +} + +void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV, u8 hasFixedPersonality, u32 fixedPersonality, u8 otIdType, u32 fixedOtId) +{ + u8 speciesName[POKEMON_NAME_LENGTH + 1]; + u32 personality; + u32 value; + u16 checksum; + + ZeroBoxMonData(boxMon); + + if (hasFixedPersonality) + personality = fixedPersonality; + else + personality = Random32(); + + SetBoxMonData(boxMon, MON_DATA_PERSONALITY, &personality); + + //Determine original trainer ID + if (otIdType == OT_ID_RANDOM_NO_SHINY) //Pokemon cannot be shiny + { + u32 shinyValue; + do + { + value = Random32(); + shinyValue = HIHALF(value) ^ LOHALF(value) ^ HIHALF(personality) ^ LOHALF(personality); + } while (shinyValue < 8); + } + else if (otIdType == OT_ID_PRESET) //Pokemon has a preset OT ID + { + value = fixedOtId; + } + else //Player is the OT + { + value = gSaveBlock2Ptr->playerTrainerId[0] + | (gSaveBlock2Ptr->playerTrainerId[1] << 8) + | (gSaveBlock2Ptr->playerTrainerId[2] << 16) + | (gSaveBlock2Ptr->playerTrainerId[3] << 24); + } + + SetBoxMonData(boxMon, MON_DATA_OT_ID, &value); + + checksum = CalculateBoxMonChecksum(boxMon); + SetBoxMonData(boxMon, MON_DATA_CHECKSUM, &checksum); + EncryptBoxMon(boxMon); + GetSpeciesName(speciesName, species); + SetBoxMonData(boxMon, MON_DATA_NICKNAME, speciesName); + SetBoxMonData(boxMon, MON_DATA_LANGUAGE, &gGameLanguage); + SetBoxMonData(boxMon, MON_DATA_OT_NAME, gSaveBlock2Ptr->playerName); + SetBoxMonData(boxMon, MON_DATA_SPECIES, &species); + SetBoxMonData(boxMon, MON_DATA_EXP, &gExperienceTables[gBaseStats[species].growthRate][level]); + SetBoxMonData(boxMon, MON_DATA_FRIENDSHIP, &gBaseStats[species].friendship); + value = sav1_map_get_name(); + SetBoxMonData(boxMon, MON_DATA_MET_LOCATION, &value); + SetBoxMonData(boxMon, MON_DATA_MET_LEVEL, &level); + SetBoxMonData(boxMon, MON_DATA_MET_GAME, &gGameVersion); + value = ITEM_POKE_BALL; + SetBoxMonData(boxMon, MON_DATA_POKEBALL, &value); + SetBoxMonData(boxMon, MON_DATA_OT_GENDER, &gSaveBlock2Ptr->playerGender); + + if (fixedIV < 32) + { + SetBoxMonData(boxMon, MON_DATA_HP_IV, &fixedIV); + SetBoxMonData(boxMon, MON_DATA_ATK_IV, &fixedIV); + SetBoxMonData(boxMon, MON_DATA_DEF_IV, &fixedIV); + SetBoxMonData(boxMon, MON_DATA_SPEED_IV, &fixedIV); + SetBoxMonData(boxMon, MON_DATA_SPATK_IV, &fixedIV); + SetBoxMonData(boxMon, MON_DATA_SPDEF_IV, &fixedIV); + } + else + { + u32 iv; + value = Random(); + + iv = value & 0x1F; + SetBoxMonData(boxMon, MON_DATA_HP_IV, &iv); + iv = (value & 0x3E0) >> 5; + SetBoxMonData(boxMon, MON_DATA_ATK_IV, &iv); + iv = (value & 0x7C00) >> 10; + SetBoxMonData(boxMon, MON_DATA_DEF_IV, &iv); + + value = Random(); + + iv = value & 0x1F; + SetBoxMonData(boxMon, MON_DATA_SPEED_IV, &iv); + iv = (value & 0x3E0) >> 5; + SetBoxMonData(boxMon, MON_DATA_SPATK_IV, &iv); + iv = (value & 0x7C00) >> 10; + SetBoxMonData(boxMon, MON_DATA_SPDEF_IV, &iv); + } + + if (gBaseStats[species].ability2) + { + value = personality & 1; + SetBoxMonData(boxMon, MON_DATA_ALT_ABILITY, &value); + } + + GiveBoxMonInitialMoveset(boxMon); +} + +void CreateMonWithNature(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 nature) +{ + u32 personality; + + do + { + personality = Random32(); + } + while (nature != GetNatureFromPersonality(personality)); + + CreateMon(mon, species, level, fixedIV, 1, personality, OT_ID_PLAYER_ID, 0); +} + +void CreateMonWithGenderNatureLetter(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 gender, u8 nature, u8 unownLetter) +{ + u32 personality; + + if ((u8)(unownLetter - 1) < 28) + { + u16 actualLetter; + + do + { + personality = Random32(); + actualLetter = ((((personality & 0x3000000) >> 18) | ((personality & 0x30000) >> 12) | ((personality & 0x300) >> 6) | (personality & 0x3)) % 28); + } + while (nature != GetNatureFromPersonality(personality) + || gender != GetGenderFromSpeciesAndPersonality(species, personality) + || actualLetter != unownLetter - 1); + } + else + { + do + { + personality = Random32(); + } + while (nature != GetNatureFromPersonality(personality) + || gender != GetGenderFromSpeciesAndPersonality(species, personality)); + } + + CreateMon(mon, species, level, fixedIV, 1, personality, OT_ID_PLAYER_ID, 0); +} + +// This is only used to create Wally's Ralts. +void CreateMaleMon(struct Pokemon *mon, u16 species, u8 level) +{ + u32 personality; + u32 otId; + + do + { + otId = Random32(); + personality = Random32(); + } + while (GetGenderFromSpeciesAndPersonality(species, personality) != MON_MALE); + CreateMon(mon, species, level, 32, 1, personality, OT_ID_PRESET, otId); +} + +void CreateMonWithIVsPersonality(struct Pokemon *mon, u16 species, u8 level, u32 ivs, u32 personality) +{ + CreateMon(mon, species, level, 0, 1, personality, OT_ID_PLAYER_ID, 0); + SetMonData(mon, MON_DATA_IVS, &ivs); + CalculateMonStats(mon); +} + +void CreateMonWithIVsOTID(struct Pokemon *mon, u16 species, u8 level, u8 *ivs, u32 otId) +{ + CreateMon(mon, species, level, 0, 0, 0, OT_ID_PRESET, otId); + SetMonData(mon, MON_DATA_HP_IV, &ivs[0]); + SetMonData(mon, MON_DATA_ATK_IV, &ivs[1]); + SetMonData(mon, MON_DATA_DEF_IV, &ivs[2]); + SetMonData(mon, MON_DATA_SPEED_IV, &ivs[3]); + SetMonData(mon, MON_DATA_SPATK_IV, &ivs[4]); + SetMonData(mon, MON_DATA_SPDEF_IV, &ivs[5]); + CalculateMonStats(mon); +} + +void CreateMonWithEVSpread(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 evSpread) +{ + s32 i; + s32 statCount = 0; + u16 evAmount; + u8 evsBits; + + CreateMon(mon, species, level, fixedIV, 0, 0, 0, 0); + + evsBits = evSpread; + + for (i = 0; i < NUM_STATS; i++) + { + if (evsBits & 1) + statCount++; + evsBits >>= 1; + } + + evAmount = MAX_TOTAL_EVS / statCount; + + evsBits = 1; + + for (i = 0; i < NUM_STATS; i++) + { + if (evSpread & evsBits) + SetMonData(mon, MON_DATA_HP_EV + i, &evAmount); + evsBits <<= 1; + } + + CalculateMonStats(mon); +} + +void sub_806819C(struct Pokemon *mon, struct UnknownPokemonStruct *src) +{ + s32 i; + u8 nickname[30]; + u8 language; + u8 value; + + CreateMon(mon, src->species, src->level, 0, 1, src->personality, 1, src->otId); + + for (i = 0; i < 4; i++) + SetMonMoveSlot(mon, src->moves[i], i); + + SetMonData(mon, MON_DATA_PP_BONUSES, &src->ppBonuses); + SetMonData(mon, MON_DATA_HELD_ITEM, &src->heldItem); + SetMonData(mon, MON_DATA_FRIENDSHIP, &src->friendship); + + StringCopy(nickname, src->nickname); + + if (nickname[0] == EXT_CTRL_CODE_BEGIN && nickname[1] == EXT_CTRL_CODE_JPN) + { + language = LANGUAGE_JAPANESE; + StripExtCtrlCodes(nickname); + } + else + { + language = GAME_LANGUAGE; + } + + SetMonData(mon, MON_DATA_LANGUAGE, &language); + SetMonData(mon, MON_DATA_NICKNAME, nickname); + SetMonData(mon, MON_DATA_HP_EV, &src->hpEV); + SetMonData(mon, MON_DATA_ATK_EV, &src->attackEV); + SetMonData(mon, MON_DATA_DEF_EV, &src->defenseEV); + SetMonData(mon, MON_DATA_SPEED_EV, &src->speedEV); + SetMonData(mon, MON_DATA_SPATK_EV, &src->spAttackEV); + SetMonData(mon, MON_DATA_SPDEF_EV, &src->spDefenseEV); + value = src->altAbility; + SetMonData(mon, MON_DATA_ALT_ABILITY, &value); + value = src->hpIV; + SetMonData(mon, MON_DATA_HP_IV, &value); + value = src->attackIV; + SetMonData(mon, MON_DATA_ATK_IV, &value); + value = src->defenseIV; + SetMonData(mon, MON_DATA_DEF_IV, &value); + value = src->speedIV; + SetMonData(mon, MON_DATA_SPEED_IV, &value); + value = src->spAttackIV; + SetMonData(mon, MON_DATA_SPATK_IV, &value); + value = src->spDefenseIV; + SetMonData(mon, MON_DATA_SPDEF_IV, &value); + MonRestorePP(mon); + CalculateMonStats(mon); +} + +void sub_8068338(struct Pokemon *mon, struct UnknownPokemonStruct *src, bool8 lvl50) +{ + s32 i; + u8 nickname[30]; + u8 level; + u8 language; + u8 value; + + if (gSaveBlock2Ptr->frontierChosenLvl != 0) + level = BattleFrontierGetOpponentLvl(gSaveBlock2Ptr->frontierChosenLvl); + else if (lvl50) + level = 50; + else + level = src->level; + + CreateMon(mon, src->species, level, 0, 1, src->personality, 1, src->otId); + + for (i = 0; i < 4; i++) + SetMonMoveSlot(mon, src->moves[i], i); + + SetMonData(mon, MON_DATA_PP_BONUSES, &src->ppBonuses); + SetMonData(mon, MON_DATA_HELD_ITEM, &src->heldItem); + SetMonData(mon, MON_DATA_FRIENDSHIP, &src->friendship); + + StringCopy(nickname, src->nickname); + + if (nickname[0] == EXT_CTRL_CODE_BEGIN && nickname[1] == EXT_CTRL_CODE_JPN) + { + language = LANGUAGE_JAPANESE; + StripExtCtrlCodes(nickname); + } + else + { + language = GAME_LANGUAGE; + } + + SetMonData(mon, MON_DATA_LANGUAGE, &language); + SetMonData(mon, MON_DATA_NICKNAME, nickname); + SetMonData(mon, MON_DATA_HP_EV, &src->hpEV); + SetMonData(mon, MON_DATA_ATK_EV, &src->attackEV); + SetMonData(mon, MON_DATA_DEF_EV, &src->defenseEV); + SetMonData(mon, MON_DATA_SPEED_EV, &src->speedEV); + SetMonData(mon, MON_DATA_SPATK_EV, &src->spAttackEV); + SetMonData(mon, MON_DATA_SPDEF_EV, &src->spDefenseEV); + value = src->altAbility; + SetMonData(mon, MON_DATA_ALT_ABILITY, &value); + value = src->hpIV; + SetMonData(mon, MON_DATA_HP_IV, &value); + value = src->attackIV; + SetMonData(mon, MON_DATA_ATK_IV, &value); + value = src->defenseIV; + SetMonData(mon, MON_DATA_DEF_IV, &value); + value = src->speedIV; + SetMonData(mon, MON_DATA_SPEED_IV, &value); + value = src->spAttackIV; + SetMonData(mon, MON_DATA_SPATK_IV, &value); + value = src->spDefenseIV; + SetMonData(mon, MON_DATA_SPDEF_IV, &value); + MonRestorePP(mon); + CalculateMonStats(mon); +} + +void sub_8068528(struct Pokemon *mon, const struct UnknownPokemonStruct2 *src, u8 monId) +{ + s32 i; + u16 evAmount; + u8 language; + u32 otId = gUnknown_08610970[src->field_0_0].field_30; + u32 personality = ((gUnknown_08610970[src->field_0_0].field_30 >> 8) | ((gUnknown_08610970[src->field_0_0].field_30 & 0xFF) << 8)) + + src->mons[monId].species + src->field_2; + + CreateMon(mon, + src->mons[monId].species, + BattleFrontierGetOpponentLvl(src->field_0_1 - 1), + 0x1F, + TRUE, + personality, + TRUE, + otId); + + SetMonData(mon, MON_DATA_HELD_ITEM, &src->mons[monId].item); + for (i = 0; i < 4; i++) + SetMonMoveSlot(mon, src->mons[monId].moves[i], i); + + evAmount = MAX_TOTAL_EVS / NUM_STATS; + for (i = 0; i < NUM_STATS; i++) + SetMonData(mon, MON_DATA_HP_EV + i, &evAmount); + + language = src->language; + SetMonData(mon, MON_DATA_LANGUAGE, &language); + SetMonData(mon, MON_DATA_OT_NAME, sub_81A1650(src->field_0_0, language)); + CalculateMonStats(mon); +} + +void CreateMonWithEVSpreadPersonalityOTID(struct Pokemon *mon, u16 species, u8 level, u8 nature, u8 fixedIV, u8 evSpread, u32 otId) +{ + s32 i; + s32 statCount = 0; + u8 evsBits; + u16 evAmount; + + // i is reused as personality value + do + { + i = Random32(); + } while (nature != GetNatureFromPersonality(i)); + + CreateMon(mon, species, level, fixedIV, TRUE, i, TRUE, otId); + evsBits = evSpread; + for (i = 0; i < NUM_STATS; i++) + { + if (evsBits & 1) + statCount++; + evsBits >>= 1; + } + + evAmount = MAX_TOTAL_EVS / statCount; + evsBits = 1; + for (i = 0; i < NUM_STATS; i++) + { + if (evSpread & evsBits) + SetMonData(mon, MON_DATA_HP_EV + i, &evAmount); + evsBits <<= 1; + } + + CalculateMonStats(mon); +} + +void sub_80686FC(struct Pokemon *mon, struct UnknownPokemonStruct *dest) +{ + s32 i; + u16 heldItem; + + dest->species = GetMonData(mon, MON_DATA_SPECIES, NULL); + heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, NULL); + + if (heldItem == ITEM_ENIGMA_BERRY) + heldItem = 0; + + dest->heldItem = heldItem; + + for (i = 0; i < 4; i++) + dest->moves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, NULL); + + dest->level = GetMonData(mon, MON_DATA_LEVEL, NULL); + dest->ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES, NULL); + dest->otId = GetMonData(mon, MON_DATA_OT_ID, NULL); + dest->hpEV = GetMonData(mon, MON_DATA_HP_EV, NULL); + dest->attackEV = GetMonData(mon, MON_DATA_ATK_EV, NULL); + dest->defenseEV = GetMonData(mon, MON_DATA_DEF_EV, NULL); + dest->speedEV = GetMonData(mon, MON_DATA_SPEED_EV, NULL); + dest->spAttackEV = GetMonData(mon, MON_DATA_SPATK_EV, NULL); + dest->spDefenseEV = GetMonData(mon, MON_DATA_SPDEF_EV, NULL); + dest->friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, NULL); + dest->hpIV = GetMonData(mon, MON_DATA_HP_IV, NULL); + dest->attackIV = GetMonData(mon, MON_DATA_ATK_IV, NULL); + dest->defenseIV = GetMonData(mon, MON_DATA_DEF_IV, NULL); + dest->speedIV = GetMonData(mon, MON_DATA_SPEED_IV, NULL); + dest->spAttackIV = GetMonData(mon, MON_DATA_SPATK_IV, NULL); + dest->spDefenseIV = GetMonData(mon, MON_DATA_SPDEF_IV, NULL); + dest->altAbility = GetMonData(mon, MON_DATA_ALT_ABILITY, NULL); + dest->personality = GetMonData(mon, MON_DATA_PERSONALITY, NULL); + GetMonData(mon, MON_DATA_NICKNAME, dest->nickname); +} + +void CreateObedientMon(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 hasFixedPersonality, u32 fixedPersonality, u8 otIdType, u32 fixedOtId) +{ + bool32 obedient = TRUE; + + CreateMon(mon, species, level, fixedIV, hasFixedPersonality, fixedPersonality, otIdType, fixedOtId); + SetMonData(mon, MON_DATA_OBEDIENCE, &obedient); +} + +bool8 sub_80688F8(u8 caseId, u8 battlerId) +{ + switch (caseId) + { + case 0: + default: + return FALSE; + case 1: + if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + return FALSE; + if (!gMain.inBattle) + return FALSE; + if (gLinkPlayers[GetMultiplayerId()].lp_field_18 == battlerId) + return FALSE; + break; + case 2: + break; + case 3: + if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + return FALSE; + if (!gMain.inBattle) + return FALSE; + if (battlerId == 1 || battlerId == 4 || battlerId == 5) + return TRUE; + return FALSE; + case 4: + break; + case 5: + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + if (!gMain.inBattle) + return FALSE; + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + if (gLinkPlayers[GetMultiplayerId()].lp_field_18 == battlerId) + return FALSE; + } + else + { + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) + return FALSE; + } + } + else + { + if (!gMain.inBattle) + return FALSE; + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) + return FALSE; + } + break; + } + + return TRUE; +} + +static s32 GetDeoxysStat(struct Pokemon *mon, s32 statId) +{ + s32 ivVal, evVal; + s32 statValue; + u8 nature, statId_; + + if (gBattleTypeFlags & BATTLE_TYPE_20) + return 0; + if (GetMonData(mon, MON_DATA_SPECIES, NULL) != SPECIES_DEOXYS) + return 0; + + ivVal = GetMonData(mon, MON_DATA_HP_IV + statId, NULL); + evVal = GetMonData(mon, MON_DATA_HP_EV + statId, NULL); + statValue = (u16)(((sDeoxysBaseStats[statId] * 2 + ivVal + evVal / 4) * mon->level) / 100 + 5); + + nature = GetNature(mon); + statId_ = statId; // needed to match + statValue = ModifyStatByNature(nature, statValue, statId_); + + return statValue; +} + +void SetDeoxysStats(void) +{ + s32 i, value; + + for (i = 0; i < PARTY_SIZE; i++) + { + struct Pokemon *mon = &gPlayerParty[i]; + + if (GetMonData(mon, MON_DATA_SPECIES, NULL) != SPECIES_DEOXYS) + continue; + + value = GetMonData(mon, MON_DATA_ATK, NULL); + SetMonData(mon, MON_DATA_ATK, &value); + + value = GetMonData(mon, MON_DATA_DEF, NULL); + SetMonData(mon, MON_DATA_DEF, &value); + + value = GetMonData(mon, MON_DATA_SPEED, NULL); + SetMonData(mon, MON_DATA_SPEED, &value); + + value = GetMonData(mon, MON_DATA_SPATK, NULL); + SetMonData(mon, MON_DATA_SPATK, &value); + + value = GetMonData(mon, MON_DATA_SPDEF, NULL); + SetMonData(mon, MON_DATA_SPDEF, &value); + } +} + +u16 sub_8068B48(void) +{ + u8 linkId; + u32 arrId; + + if (gBattleTypeFlags & BATTLE_TYPE_x2000000) + linkId = gUnknown_0203C7B4 ^ 1; + else + linkId = GetMultiplayerId() ^ 1; + + arrId = gLinkPlayers[linkId].trainerId & 7; + arrId |= gLinkPlayers[linkId].gender << 3; + return FacilityClassToPicIndex(gUnknown_08329D54[arrId]); +} + +u16 sub_8068BB0(void) +{ + u8 linkId; + u32 arrId; + + if (gBattleTypeFlags & BATTLE_TYPE_x2000000) + linkId = gUnknown_0203C7B4 ^ 1; + else + linkId = GetMultiplayerId() ^ 1; + + arrId = gLinkPlayers[linkId].trainerId & 7; + arrId |= gLinkPlayers[linkId].gender << 3; + return gFacilityClassToTrainerClass[gUnknown_08329D54[arrId]]; +} + +void CreateObedientEnemyMon(void) +{ + s32 species = gSpecialVar_0x8004; + s32 level = gSpecialVar_0x8005; + s32 itemId = gSpecialVar_0x8006; + + ZeroEnemyPartyMons(); + CreateObedientMon(&gEnemyParty[0], species, level, 32, 0, 0, 0, 0); + if (itemId) + { + u8 heldItem[2]; + heldItem[0] = itemId; + heldItem[1] = itemId >> 8; + SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, heldItem); + } +} + +static u16 CalculateBoxMonChecksum(struct BoxPokemon *boxMon) +{ + u16 checksum = 0; + union PokemonSubstruct *substruct0 = GetSubstruct(boxMon, boxMon->personality, 0); + union PokemonSubstruct *substruct1 = GetSubstruct(boxMon, boxMon->personality, 1); + union PokemonSubstruct *substruct2 = GetSubstruct(boxMon, boxMon->personality, 2); + union PokemonSubstruct *substruct3 = GetSubstruct(boxMon, boxMon->personality, 3); + s32 i; + + for (i = 0; i < 6; i++) + checksum += substruct0->raw[i]; + + for (i = 0; i < 6; i++) + checksum += substruct1->raw[i]; + + for (i = 0; i < 6; i++) + checksum += substruct2->raw[i]; + + for (i = 0; i < 6; i++) + checksum += substruct3->raw[i]; + + return checksum; +} + +#define CALC_STAT(base, iv, ev, statIndex, field) \ +{ \ + u8 baseStat = gBaseStats[species].base; \ + s32 n = (((2 * baseStat + iv + ev / 4) * level) / 100) + 5; \ + u8 nature = GetNature(mon); \ + n = ModifyStatByNature(nature, n, statIndex); \ + SetMonData(mon, field, &n); \ +} + +void CalculateMonStats(struct Pokemon *mon) +{ + s32 oldMaxHP = GetMonData(mon, MON_DATA_MAX_HP, NULL); + s32 currentHP = GetMonData(mon, MON_DATA_HP, NULL); + s32 hpIV = GetMonData(mon, MON_DATA_HP_IV, NULL); + s32 hpEV = GetMonData(mon, MON_DATA_HP_EV, NULL); + s32 attackIV = GetMonData(mon, MON_DATA_ATK_IV, NULL); + s32 attackEV = GetMonData(mon, MON_DATA_ATK_EV, NULL); + s32 defenseIV = GetMonData(mon, MON_DATA_DEF_IV, NULL); + s32 defenseEV = GetMonData(mon, MON_DATA_DEF_EV, NULL); + s32 speedIV = GetMonData(mon, MON_DATA_SPEED_IV, NULL); + s32 speedEV = GetMonData(mon, MON_DATA_SPEED_EV, NULL); + s32 spAttackIV = GetMonData(mon, MON_DATA_SPATK_IV, NULL); + s32 spAttackEV = GetMonData(mon, MON_DATA_SPATK_EV, NULL); + s32 spDefenseIV = GetMonData(mon, MON_DATA_SPDEF_IV, NULL); + s32 spDefenseEV = GetMonData(mon, MON_DATA_SPDEF_EV, NULL); + u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL); + s32 level = GetLevelFromMonExp(mon); + s32 newMaxHP; + + SetMonData(mon, MON_DATA_LEVEL, &level); + + if (species == SPECIES_SHEDINJA) + { + newMaxHP = 1; + } + else + { + s32 n = 2 * gBaseStats[species].baseHP + hpIV; + newMaxHP = (((n + hpEV / 4) * level) / 100) + level + 10; + } + + gBattleScripting.field_23 = newMaxHP - oldMaxHP; + if (gBattleScripting.field_23 == 0) + gBattleScripting.field_23 = 1; + + SetMonData(mon, MON_DATA_MAX_HP, &newMaxHP); + + CALC_STAT(baseAttack, attackIV, attackEV, 1, MON_DATA_ATK) + CALC_STAT(baseDefense, defenseIV, defenseEV, 2, MON_DATA_DEF) + CALC_STAT(baseSpeed, speedIV, speedEV, 3, MON_DATA_SPEED) + CALC_STAT(baseSpAttack, spAttackIV, spAttackEV, 4, MON_DATA_SPATK) + CALC_STAT(baseSpDefense, spDefenseIV, spDefenseEV, 5, MON_DATA_SPDEF) + + if (species == SPECIES_SHEDINJA) + { + if (currentHP != 0 || oldMaxHP == 0) + currentHP = 1; + else + return; + } + else + { + if (currentHP == 0 && oldMaxHP == 0) + currentHP = newMaxHP; + else if (currentHP != 0) + currentHP += newMaxHP - oldMaxHP; + else + return; + } + + SetMonData(mon, MON_DATA_HP, ¤tHP); +} + +void BoxMonToMon(const struct BoxPokemon *src, struct Pokemon *dest) +{ + u32 value = 0; + dest->box = *src; + SetMonData(dest, MON_DATA_STATUS, &value); + SetMonData(dest, MON_DATA_HP, &value); + SetMonData(dest, MON_DATA_MAX_HP, &value); + value = 255; + SetMonData(dest, MON_DATA_MAIL, &value); + CalculateMonStats(dest); +} + +u8 GetLevelFromMonExp(struct Pokemon *mon) +{ + u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL); + u32 exp = GetMonData(mon, MON_DATA_EXP, NULL); + s32 level = 1; + + while (level <= MAX_MON_LEVEL && gExperienceTables[gBaseStats[species].growthRate][level] <= exp) + level++; + + return level - 1; +} + +u8 GetLevelFromBoxMonExp(struct BoxPokemon *boxMon) +{ + u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL); + u32 exp = GetBoxMonData(boxMon, MON_DATA_EXP, NULL); + s32 level = 1; + + while (level <= MAX_MON_LEVEL && gExperienceTables[gBaseStats[species].growthRate][level] <= exp) + level++; + + return level - 1; +} + +u16 GiveMoveToMon(struct Pokemon *mon, u16 move) +{ + return GiveMoveToBoxMon(&mon->box, move); +} + +u16 GiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move) +{ + s32 i; + for (i = 0; i < 4; i++) + { + u16 existingMove = GetBoxMonData(boxMon, MON_DATA_MOVE1 + i, NULL); + if (!existingMove) + { + SetBoxMonData(boxMon, MON_DATA_MOVE1 + i, &move); + SetBoxMonData(boxMon, MON_DATA_PP1 + i, &gBattleMoves[move].pp); + return move; + } + if (existingMove == move) + return -2; + } + return -1; +} + +u16 GiveMoveToBattleMon(struct BattlePokemon *mon, u16 move) +{ + s32 i; + + for (i = 0; i < 4; i++) + { + if (!mon->moves[i]) + { + mon->moves[i] = move; + mon->pp[i] = gBattleMoves[move].pp; + return move; + } + } + + return -1; +} + +void SetMonMoveSlot(struct Pokemon *mon, u16 move, u8 slot) +{ + SetMonData(mon, MON_DATA_MOVE1 + slot, &move); + SetMonData(mon, MON_DATA_PP1 + slot, &gBattleMoves[move].pp); +} + +void SetBattleMonMoveSlot(struct BattlePokemon *mon, u16 move, u8 slot) +{ + mon->moves[slot] = move; + mon->pp[slot] = gBattleMoves[move].pp; +} + +void GiveMonInitialMoveset(struct Pokemon *mon) +{ + GiveBoxMonInitialMoveset(&mon->box); +} + +void GiveBoxMonInitialMoveset(struct BoxPokemon *boxMon) +{ + u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL); + s32 level = GetLevelFromBoxMonExp(boxMon); + s32 i; + + for (i = 0; gLevelUpLearnsets[species][i] != (u16)-1; i++) + { + u16 moveLevel; + u16 move; + + moveLevel = (gLevelUpLearnsets[species][i] & 0xFE00); + + if (moveLevel > (level << 9)) + break; + + move = (gLevelUpLearnsets[species][i] & 0x1FF); + + if (GiveMoveToBoxMon(boxMon, move) == (u16)-1) + DeleteFirstMoveAndGiveMoveToBoxMon(boxMon, move); + } +} + +u16 MonTryLearningNewMove(struct Pokemon *mon, bool8 firstMove) +{ + u32 retVal = 0; + u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL); + u8 level = GetMonData(mon, MON_DATA_LEVEL, NULL); + + // since you can learn more than one move per level + // the game needs to know whether you decided to + // learn it or keep the old set to avoid asking + // you to learn the same move over and over again + if (firstMove) + { + sLearningMoveTableID = 0; + + while ((gLevelUpLearnsets[species][sLearningMoveTableID] & 0xFE00) != (level << 9)) + { + sLearningMoveTableID++; + if (gLevelUpLearnsets[species][sLearningMoveTableID] == 0xFFFF) + return 0; + } + } + + if ((gLevelUpLearnsets[species][sLearningMoveTableID] & 0xFE00) == (level << 9)) + { + gMoveToLearn = (gLevelUpLearnsets[species][sLearningMoveTableID] & 0x1FF); + sLearningMoveTableID++; + retVal = GiveMoveToMon(mon, gMoveToLearn); + } + + return retVal; +} + +void DeleteFirstMoveAndGiveMoveToMon(struct Pokemon *mon, u16 move) +{ + s32 i; + u16 moves[4]; + u8 pp[4]; + u8 ppBonuses; + + for (i = 0; i < 3; i++) + { + moves[i] = GetMonData(mon, MON_DATA_MOVE2 + i, NULL); + pp[i] = GetMonData(mon, MON_DATA_PP2 + i, NULL); + } + + ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES, NULL); + ppBonuses >>= 2; + moves[3] = move; + pp[3] = gBattleMoves[move].pp; + + for (i = 0; i < 4; i++) + { + SetMonData(mon, MON_DATA_MOVE1 + i, &moves[i]); + SetMonData(mon, MON_DATA_PP1 + i, &pp[i]); + } + + SetMonData(mon, MON_DATA_PP_BONUSES, &ppBonuses); +} + +void DeleteFirstMoveAndGiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move) +{ + s32 i; + u16 moves[4]; + u8 pp[4]; + u8 ppBonuses; + + for (i = 0; i < 3; i++) + { + moves[i] = GetBoxMonData(boxMon, MON_DATA_MOVE2 + i, NULL); + pp[i] = GetBoxMonData(boxMon, MON_DATA_PP2 + i, NULL); + } + + ppBonuses = GetBoxMonData(boxMon, MON_DATA_PP_BONUSES, NULL); + ppBonuses >>= 2; + moves[3] = move; + pp[3] = gBattleMoves[move].pp; + + for (i = 0; i < 4; i++) + { + SetBoxMonData(boxMon, MON_DATA_MOVE1 + i, &moves[i]); + SetBoxMonData(boxMon, MON_DATA_PP1 + i, &pp[i]); + } + + SetBoxMonData(boxMon, MON_DATA_PP_BONUSES, &ppBonuses); +} + +#define APPLY_STAT_MOD(var, mon, stat, statIndex) \ +{ \ + (var) = (stat) * (gStatStageRatios)[(mon)->statStages[(statIndex)]][0]; \ + (var) /= (gStatStageRatios)[(mon)->statStages[(statIndex)]][1]; \ +} + +s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *defender, u32 move, u16 sideStatus, u16 powerOverride, u8 typeOverride, u8 bankAtk, u8 bankDef) +{ + u32 i; + s32 damage = 0; + s32 damageHelper; + u8 type; + u16 attack, defense; + u16 spAttack, spDefense; + u8 defenderHoldEffect; + u8 defenderHoldEffectParam; + u8 attackerHoldEffect; + u8 attackerHoldEffectParam; + + if (!powerOverride) + gBattleMovePower = gBattleMoves[move].power; + else + gBattleMovePower = powerOverride; + + if (!typeOverride) + type = gBattleMoves[move].type; + else + type = typeOverride & 0x3F; + + attack = attacker->attack; + defense = defender->defense; + spAttack = attacker->spAttack; + spDefense = defender->spDefense; + + if (attacker->item == ITEM_ENIGMA_BERRY) + { + attackerHoldEffect = gEnigmaBerries[bankAtk].holdEffect; + attackerHoldEffectParam = gEnigmaBerries[bankAtk].holdEffectParam; + } + else + { + attackerHoldEffect = ItemId_GetHoldEffect(attacker->item); + attackerHoldEffectParam = ItemId_GetHoldEffectParam(attacker->item); + } + + if (defender->item == ITEM_ENIGMA_BERRY) + { + defenderHoldEffect = gEnigmaBerries[bankDef].holdEffect; + defenderHoldEffectParam = gEnigmaBerries[bankDef].holdEffectParam; + } + else + { + defenderHoldEffect = ItemId_GetHoldEffect(defender->item); + defenderHoldEffectParam = ItemId_GetHoldEffectParam(defender->item); + } + + if (attacker->ability == ABILITY_HUGE_POWER || attacker->ability == ABILITY_PURE_POWER) + attack *= 2; + + if (ShouldGetStatBadgeBoost(FLAG_BADGE01_GET, bankAtk)) + attack = (110 * attack) / 100; + if (ShouldGetStatBadgeBoost(FLAG_BADGE05_GET, bankDef)) + defense = (110 * defense) / 100; + if (ShouldGetStatBadgeBoost(FLAG_BADGE07_GET, bankAtk)) + spAttack = (110 * spAttack) / 100; + if (ShouldGetStatBadgeBoost(FLAG_BADGE07_GET, bankDef)) + spDefense = (110 * spDefense) / 100; + + for (i = 0; i < ARRAY_COUNT(sHoldEffectToType); i++) + { + if (attackerHoldEffect == sHoldEffectToType[i][0] + && type == sHoldEffectToType[i][1]) + { + if (type <= 8) + attack = (attack * (attackerHoldEffectParam + 100)) / 100; + else + spAttack = (spAttack * (attackerHoldEffectParam + 100)) / 100; + break; + } + } + + if (attackerHoldEffect == HOLD_EFFECT_CHOICE_BAND) + attack = (150 * attack) / 100; + if (attackerHoldEffect == HOLD_EFFECT_SOUL_DEW && !(gBattleTypeFlags & (BATTLE_TYPE_FRONTIER)) && (attacker->species == SPECIES_LATIAS || attacker->species == SPECIES_LATIOS)) + spAttack = (150 * spAttack) / 100; + if (defenderHoldEffect == HOLD_EFFECT_SOUL_DEW && !(gBattleTypeFlags & (BATTLE_TYPE_FRONTIER)) && (defender->species == SPECIES_LATIAS || defender->species == SPECIES_LATIOS)) + spDefense = (150 * spDefense) / 100; + if (attackerHoldEffect == HOLD_EFFECT_DEEP_SEA_TOOTH && attacker->species == SPECIES_CLAMPERL) + spAttack *= 2; + if (defenderHoldEffect == HOLD_EFFECT_DEEP_SEA_SCALE && defender->species == SPECIES_CLAMPERL) + spDefense *= 2; + if (attackerHoldEffect == HOLD_EFFECT_LIGHT_BALL && attacker->species == SPECIES_PIKACHU) + spAttack *= 2; + if (defenderHoldEffect == HOLD_EFFECT_METAL_POWDER && defender->species == SPECIES_DITTO) + defense *= 2; + if (attackerHoldEffect == HOLD_EFFECT_THICK_CLUB && (attacker->species == SPECIES_CUBONE || attacker->species == SPECIES_MAROWAK)) + attack *= 2; + if (defender->ability == ABILITY_THICK_FAT && (type == TYPE_FIRE || type == TYPE_ICE)) + spAttack /= 2; + if (attacker->ability == ABILITY_HUSTLE) + attack = (150 * attack) / 100; + if (attacker->ability == ABILITY_PLUS && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_MINUS, 0, 0)) + spAttack = (150 * spAttack) / 100; + if (attacker->ability == ABILITY_MINUS && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_PLUS, 0, 0)) + spAttack = (150 * spAttack) / 100; + if (attacker->ability == ABILITY_GUTS && attacker->status1) + attack = (150 * attack) / 100; + if (defender->ability == ABILITY_MARVEL_SCALE && defender->status1) + defense = (150 * defense) / 100; + if (type == TYPE_ELECTRIC && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, 0, 0xFD, 0)) + gBattleMovePower /= 2; + if (type == TYPE_FIRE && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, 0, 0xFE, 0)) + gBattleMovePower /= 2; + if (type == TYPE_GRASS && attacker->ability == ABILITY_OVERGROW && attacker->hp <= (attacker->maxHP / 3)) + gBattleMovePower = (150 * gBattleMovePower) / 100; + if (type == TYPE_FIRE && attacker->ability == ABILITY_BLAZE && attacker->hp <= (attacker->maxHP / 3)) + gBattleMovePower = (150 * gBattleMovePower) / 100; + if (type == TYPE_WATER && attacker->ability == ABILITY_TORRENT && attacker->hp <= (attacker->maxHP / 3)) + gBattleMovePower = (150 * gBattleMovePower) / 100; + if (type == TYPE_BUG && attacker->ability == ABILITY_SWARM && attacker->hp <= (attacker->maxHP / 3)) + gBattleMovePower = (150 * gBattleMovePower) / 100; + if (gBattleMoves[gCurrentMove].effect == EFFECT_EXPLOSION) + defense /= 2; + + if (type < TYPE_MYSTERY) // is physical + { + if (gCritMultiplier == 2) + { + if (attacker->statStages[STAT_ATK] > 6) + APPLY_STAT_MOD(damage, attacker, attack, STAT_ATK) + else + damage = attack; + } + else + APPLY_STAT_MOD(damage, attacker, attack, STAT_ATK) + + damage = damage * gBattleMovePower; + damage *= (2 * attacker->level / 5 + 2); + + if (gCritMultiplier == 2) + { + if (defender->statStages[STAT_DEF] < 6) + APPLY_STAT_MOD(damageHelper, defender, defense, STAT_DEF) + else + damageHelper = defense; + } + else + APPLY_STAT_MOD(damageHelper, defender, defense, STAT_DEF) + + damage = damage / damageHelper; + damage /= 50; + + if ((attacker->status1 & STATUS1_BURN) && attacker->ability != ABILITY_GUTS) + damage /= 2; + + if ((sideStatus & SIDE_STATUS_REFLECT) && gCritMultiplier == 1) + { + if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && CountAliveMonsInBattle(2) == 2) + damage = 2 * (damage / 3); + else + damage /= 2; + } + + if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gBattleMoves[move].target == 8 && CountAliveMonsInBattle(2) == 2) + damage /= 2; + + // moves always do at least 1 damage. + if (damage == 0) + damage = 1; + } + + if (type == TYPE_MYSTERY) + damage = 0; // is ??? type. does 0 damage. + + if (type > TYPE_MYSTERY) // is special? + { + if (gCritMultiplier == 2) + { + if (attacker->statStages[STAT_SPATK] > 6) + APPLY_STAT_MOD(damage, attacker, spAttack, STAT_SPATK) + else + damage = spAttack; + } + else + APPLY_STAT_MOD(damage, attacker, spAttack, STAT_SPATK) + + damage = damage * gBattleMovePower; + damage *= (2 * attacker->level / 5 + 2); + + if (gCritMultiplier == 2) + { + if (defender->statStages[STAT_SPDEF] < 6) + APPLY_STAT_MOD(damageHelper, defender, spDefense, STAT_SPDEF) + else + damageHelper = spDefense; + } + else + APPLY_STAT_MOD(damageHelper, defender, spDefense, STAT_SPDEF) + + damage = (damage / damageHelper); + damage /= 50; + + if ((sideStatus & SIDE_STATUS_LIGHTSCREEN) && gCritMultiplier == 1) + { + if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && CountAliveMonsInBattle(2) == 2) + damage = 2 * (damage / 3); + else + damage /= 2; + } + + if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gBattleMoves[move].target == 8 && CountAliveMonsInBattle(2) == 2) + damage /= 2; + + // are effects of weather negated with cloud nine or air lock + if (!AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_CLOUD_NINE, 0, 0) + && !AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_AIR_LOCK, 0, 0)) + { + if (gBattleWeather & WEATHER_RAIN_TEMPORARY) + { + switch (type) + { + case TYPE_FIRE: + damage /= 2; + break; + case TYPE_WATER: + damage = (15 * damage) / 10; + break; + } + } + + // any weather except sun weakens solar beam + if ((gBattleWeather & (WEATHER_RAIN_ANY | WEATHER_SANDSTORM_ANY | WEATHER_HAIL)) && gCurrentMove == MOVE_SOLAR_BEAM) + damage /= 2; + + // sunny + if (gBattleWeather & WEATHER_SUN_ANY) + { + switch (type) + { + case TYPE_FIRE: + damage = (15 * damage) / 10; + break; + case TYPE_WATER: + damage /= 2; + break; + } + } + } + + // flash fire triggered + if ((gBattleResources->flags->flags[bankAtk] & UNKNOWN_FLAG_FLASH_FIRE) && type == TYPE_FIRE) + damage = (15 * damage) / 10; + } + + return damage + 2; +} + +u8 CountAliveMonsInBattle(u8 caseId) +{ + s32 i; + u8 retVal = 0; + + switch (caseId) + { + case BATTLE_ALIVE_EXCEPT_ACTIVE: + for (i = 0; i < 4; i++) + { + if (i != gActiveBattler && !(gAbsentBattlerFlags & gBitTable[i])) + retVal++; + } + break; + case BATTLE_ALIVE_ATK_SIDE: + for (i = 0; i < 4; i++) + { + if (GetBattlerSide(i) == GetBattlerSide(gBattlerAttacker) && !(gAbsentBattlerFlags & gBitTable[i])) + retVal++; + } + break; + case BATTLE_ALIVE_DEF_SIDE: + for (i = 0; i < 4; i++) + { + if (GetBattlerSide(i) == GetBattlerSide(gBattlerTarget) && !(gAbsentBattlerFlags & gBitTable[i])) + retVal++; + } + break; + } + + return retVal; +} + +static bool8 ShouldGetStatBadgeBoost(u16 badgeFlag, u8 battlerId) +{ + if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_x2000000 | BATTLE_TYPE_FRONTIER)) + return FALSE; + if (GetBattlerSide(battlerId) != B_SIDE_PLAYER) + return FALSE; + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && gTrainerBattleOpponent_A == SECRET_BASE_OPPONENT) + return FALSE; + if (FlagGet(badgeFlag)) + return TRUE; + return FALSE; +} + +u8 GetDefaultMoveTarget(u8 battlerId) +{ + u8 opposing = BATTLE_OPPOSITE(GetBattlerPosition(battlerId) & BIT_SIDE); + + if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + return GetBattlerAtPosition(opposing); + if (CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_ACTIVE) > 1) + { + u8 position; + + if ((Random() & 1) == 0) + position = BATTLE_PARTNER(opposing); + else + position = opposing; + + return GetBattlerAtPosition(position); + } + else + { + if ((gAbsentBattlerFlags & gBitTable[opposing])) + return GetBattlerAtPosition(BATTLE_PARTNER(opposing)); + else + return GetBattlerAtPosition(opposing); + } +} + +u8 GetMonGender(struct Pokemon *mon) +{ + return GetBoxMonGender(&mon->box); +} + +u8 GetBoxMonGender(struct BoxPokemon *boxMon) +{ + u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL); + u32 personality = GetBoxMonData(boxMon, MON_DATA_PERSONALITY, NULL); + + switch (gBaseStats[species].genderRatio) + { + case MON_MALE: + case MON_FEMALE: + case MON_GENDERLESS: + return gBaseStats[species].genderRatio; + } + + if (gBaseStats[species].genderRatio > (personality & 0xFF)) + return MON_FEMALE; + else + return MON_MALE; +} + +u8 GetGenderFromSpeciesAndPersonality(u16 species, u32 personality) +{ + switch (gBaseStats[species].genderRatio) + { + case MON_MALE: + case MON_FEMALE: + case MON_GENDERLESS: + return gBaseStats[species].genderRatio; + } + + if (gBaseStats[species].genderRatio > (personality & 0xFF)) + return MON_FEMALE; + else + return MON_MALE; +} + +void sub_806A068(u16 species, u8 battlerPosition) +{ + if (gMonSpritesGfxPtr != NULL) + gUnknown_0202499C = gMonSpritesGfxPtr->templates[battlerPosition]; + else if (gUnknown_020249B4[0]) + gUnknown_0202499C = gUnknown_020249B4[0]->templates[battlerPosition]; + else if (gUnknown_020249B4[1]) + gUnknown_0202499C = gUnknown_020249B4[1]->templates[battlerPosition]; + else + gUnknown_0202499C = gUnknown_08329D98[battlerPosition]; + + gUnknown_0202499C.paletteTag = species; + if (battlerPosition == 0 || battlerPosition == 2) + gUnknown_0202499C.anims = gUnknown_082FF70C; + else if (species > 500) + gUnknown_0202499C.anims = gMonAnimationsSpriteAnimsPtrTable[species - 500]; + else + gUnknown_0202499C.anims = gMonAnimationsSpriteAnimsPtrTable[species]; +} + +void sub_806A12C(u16 trainerSpriteId, u8 battlerPosition) +{ + gUnknown_0202499C.paletteTag = trainerSpriteId; + if (battlerPosition == B_POSITION_PLAYER_LEFT || battlerPosition == B_POSITION_PLAYER_RIGHT) + { + gUnknown_0202499C = gUnknown_08329DF8[trainerSpriteId]; + gUnknown_0202499C.anims = gUnknown_08305D0C[trainerSpriteId]; + } + else + { + if (gMonSpritesGfxPtr != NULL) + gUnknown_0202499C = gMonSpritesGfxPtr->templates[battlerPosition]; + else + gUnknown_0202499C = gUnknown_08329D98[battlerPosition]; + gUnknown_0202499C.anims = gUnknown_0830536C[trainerSpriteId]; + } +} + +void sub_806A1C0(u16 arg0, u8 battlerPosition) +{ + if (gMonSpritesGfxPtr != NULL) + gUnknown_0202499C = gMonSpritesGfxPtr->templates[battlerPosition]; + else + gUnknown_0202499C = gUnknown_08329D98[battlerPosition]; + + gUnknown_0202499C.paletteTag = arg0; + gUnknown_0202499C.anims = gUnknown_0830536C[arg0]; +} + +static void EncryptBoxMon(struct BoxPokemon *boxMon) +{ + u32 i; + for (i = 0; i < 12; i++) + { + boxMon->secure.raw[i] ^= boxMon->personality; + boxMon->secure.raw[i] ^= boxMon->otId; + } +} + +static void DecryptBoxMon(struct BoxPokemon *boxMon) +{ + u32 i; + for (i = 0; i < 12; i++) + { + boxMon->secure.raw[i] ^= boxMon->otId; + boxMon->secure.raw[i] ^= boxMon->personality; + } +} + +#define SUBSTRUCT_CASE(n, v1, v2, v3, v4) \ +case n: \ + { \ + union PokemonSubstruct *substructs0 = boxMon->secure.substructs; \ + union PokemonSubstruct *substructs1 = boxMon->secure.substructs; \ + union PokemonSubstruct *substructs2 = boxMon->secure.substructs; \ + union PokemonSubstruct *substructs3 = boxMon->secure.substructs; \ + union PokemonSubstruct *substructs4 = boxMon->secure.substructs; \ + union PokemonSubstruct *substructs5 = boxMon->secure.substructs; \ + union PokemonSubstruct *substructs6 = boxMon->secure.substructs; \ + union PokemonSubstruct *substructs7 = boxMon->secure.substructs; \ + union PokemonSubstruct *substructs8 = boxMon->secure.substructs; \ + union PokemonSubstruct *substructs9 = boxMon->secure.substructs; \ + union PokemonSubstruct *substructs10 = boxMon->secure.substructs; \ + union PokemonSubstruct *substructs11 = boxMon->secure.substructs; \ + union PokemonSubstruct *substructs12 = boxMon->secure.substructs; \ + union PokemonSubstruct *substructs13 = boxMon->secure.substructs; \ + union PokemonSubstruct *substructs14 = boxMon->secure.substructs; \ + union PokemonSubstruct *substructs15 = boxMon->secure.substructs; \ + union PokemonSubstruct *substructs16 = boxMon->secure.substructs; \ + union PokemonSubstruct *substructs17 = boxMon->secure.substructs; \ + union PokemonSubstruct *substructs18 = boxMon->secure.substructs; \ + union PokemonSubstruct *substructs19 = boxMon->secure.substructs; \ + union PokemonSubstruct *substructs20 = boxMon->secure.substructs; \ + union PokemonSubstruct *substructs21 = boxMon->secure.substructs; \ + union PokemonSubstruct *substructs22 = boxMon->secure.substructs; \ + union PokemonSubstruct *substructs23 = boxMon->secure.substructs; \ + \ + switch (substructType) \ + { \ + case 0: \ + substruct = &substructs ## n [v1]; \ + break; \ + case 1: \ + substruct = &substructs ## n [v2]; \ + break; \ + case 2: \ + substruct = &substructs ## n [v3]; \ + break; \ + case 3: \ + substruct = &substructs ## n [v4]; \ + break; \ + } \ + break; \ + } \ + + +static union PokemonSubstruct *GetSubstruct(struct BoxPokemon *boxMon, u32 personality, u8 substructType) +{ + union PokemonSubstruct *substruct = NULL; + + switch (personality % 24) + { + SUBSTRUCT_CASE( 0,0,1,2,3) + SUBSTRUCT_CASE( 1,0,1,3,2) + SUBSTRUCT_CASE( 2,0,2,1,3) + SUBSTRUCT_CASE( 3,0,3,1,2) + SUBSTRUCT_CASE( 4,0,2,3,1) + SUBSTRUCT_CASE( 5,0,3,2,1) + SUBSTRUCT_CASE( 6,1,0,2,3) + SUBSTRUCT_CASE( 7,1,0,3,2) + SUBSTRUCT_CASE( 8,2,0,1,3) + SUBSTRUCT_CASE( 9,3,0,1,2) + SUBSTRUCT_CASE(10,2,0,3,1) + SUBSTRUCT_CASE(11,3,0,2,1) + SUBSTRUCT_CASE(12,1,2,0,3) + SUBSTRUCT_CASE(13,1,3,0,2) + SUBSTRUCT_CASE(14,2,1,0,3) + SUBSTRUCT_CASE(15,3,1,0,2) + SUBSTRUCT_CASE(16,2,3,0,1) + SUBSTRUCT_CASE(17,3,2,0,1) + SUBSTRUCT_CASE(18,1,2,3,0) + SUBSTRUCT_CASE(19,1,3,2,0) + SUBSTRUCT_CASE(20,2,1,3,0) + SUBSTRUCT_CASE(21,3,1,2,0) + SUBSTRUCT_CASE(22,2,3,1,0) + SUBSTRUCT_CASE(23,3,2,1,0) + } + + return substruct; +} + +u32 GetMonData(struct Pokemon *mon, s32 field, u8* data) +{ + u32 ret; + + switch (field) + { + case MON_DATA_STATUS: + ret = mon->status; + break; + case MON_DATA_LEVEL: + ret = mon->level; + break; + case MON_DATA_HP: + ret = mon->hp; + break; + case MON_DATA_MAX_HP: + ret = mon->maxHP; + break; + case MON_DATA_ATK: + ret = (u16)GetDeoxysStat(mon, STAT_ATK); + if (!ret) + ret = mon->attack; + break; + case MON_DATA_DEF: + ret = (u16)GetDeoxysStat(mon, STAT_DEF); + if (!ret) + ret = mon->defense; + break; + case MON_DATA_SPEED: + ret = (u16)GetDeoxysStat(mon, STAT_SPEED); + if (!ret) + ret = mon->speed; + break; + case MON_DATA_SPATK: + ret = (u16)GetDeoxysStat(mon, STAT_SPATK); + if (!ret) + ret = mon->spAttack; + break; + case MON_DATA_SPDEF: + ret = (u16)GetDeoxysStat(mon, STAT_SPDEF); + if (!ret) + ret = mon->spDefense; + break; + case MON_DATA_ATK2: + ret = mon->attack; + break; + case MON_DATA_DEF2: + ret = mon->defense; + break; + case MON_DATA_SPEED2: + ret = mon->speed; + break; + case MON_DATA_SPATK2: + ret = mon->spAttack; + break; + case MON_DATA_SPDEF2: + ret = mon->spDefense; + break; + case MON_DATA_MAIL: + ret = mon->mail; + break; + default: + ret = GetBoxMonData(&mon->box, field, data); + break; + } + return ret; +} + +u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data) +{ + s32 i; + u32 retVal = 0; + struct PokemonSubstruct0 *substruct0 = NULL; + struct PokemonSubstruct1 *substruct1 = NULL; + struct PokemonSubstruct2 *substruct2 = NULL; + struct PokemonSubstruct3 *substruct3 = NULL; + + if (field > MON_DATA_10) + { + substruct0 = &(GetSubstruct(boxMon, boxMon->personality, 0)->type0); + substruct1 = &(GetSubstruct(boxMon, boxMon->personality, 1)->type1); + substruct2 = &(GetSubstruct(boxMon, boxMon->personality, 2)->type2); + substruct3 = &(GetSubstruct(boxMon, boxMon->personality, 3)->type3); + + DecryptBoxMon(boxMon); + + if (CalculateBoxMonChecksum(boxMon) != boxMon->checksum) + { + boxMon->isBadEgg = 1; + boxMon->isEgg = 1; + substruct3->isEgg = 1; + } + } + + switch (field) + { + case MON_DATA_PERSONALITY: + retVal = boxMon->personality; + break; + case MON_DATA_OT_ID: + retVal = boxMon->otId; + break; + case MON_DATA_NICKNAME: + { + if (boxMon->isBadEgg) + { + for (retVal = 0; + retVal < POKEMON_NAME_LENGTH && gText_BadEgg[retVal] != EOS; + data[retVal] = gText_BadEgg[retVal], retVal++) {} + + data[retVal] = EOS; + } + else if (boxMon->isEgg) + { + StringCopy(data, gText_EggNickname); + retVal = StringLength(data); + } + else if (boxMon->language == LANGUAGE_JAPANESE) + { + data[0] = EXT_CTRL_CODE_BEGIN; + data[1] = EXT_CTRL_CODE_JPN; + + for (retVal = 2, i = 0; + i < 5 && boxMon->nickname[i] != EOS; + data[retVal] = boxMon->nickname[i], retVal++, i++) {} + + data[retVal++] = EXT_CTRL_CODE_BEGIN; + data[retVal++] = EXT_CTRL_CODE_ENG; + data[retVal] = EOS; + } + else + { + for (retVal = 0; + retVal < POKEMON_NAME_LENGTH; + data[retVal] = boxMon->nickname[retVal], retVal++){} + + data[retVal] = EOS; + } + break; + } + case MON_DATA_LANGUAGE: + retVal = boxMon->language; + break; + case MON_DATA_SANITY_BIT1: + retVal = boxMon->isBadEgg; + break; + case MON_DATA_SANITY_BIT2: + retVal = boxMon->hasSpecies; + break; + case MON_DATA_SANITY_BIT3: + retVal = boxMon->isEgg; + break; + case MON_DATA_OT_NAME: + { + retVal = 0; + + while (retVal < OT_NAME_LENGTH) + { + data[retVal] = boxMon->otName[retVal]; + retVal++; + } + + data[retVal] = EOS; + break; + } + case MON_DATA_MARKINGS: + retVal = boxMon->markings; + break; + case MON_DATA_CHECKSUM: + retVal = boxMon->checksum; + break; + case MON_DATA_10: + retVal = boxMon->unknown; + break; + case MON_DATA_SPECIES: + retVal = boxMon->isBadEgg ? SPECIES_EGG : substruct0->species; + break; + case MON_DATA_HELD_ITEM: + retVal = substruct0->heldItem; + break; + case MON_DATA_EXP: + retVal = substruct0->experience; + break; + case MON_DATA_PP_BONUSES: + retVal = substruct0->ppBonuses; + break; + case MON_DATA_FRIENDSHIP: + retVal = substruct0->friendship; + break; + case MON_DATA_MOVE1: + case MON_DATA_MOVE2: + case MON_DATA_MOVE3: + case MON_DATA_MOVE4: + retVal = substruct1->moves[field - MON_DATA_MOVE1]; + break; + case MON_DATA_PP1: + case MON_DATA_PP2: + case MON_DATA_PP3: + case MON_DATA_PP4: + retVal = substruct1->pp[field - MON_DATA_PP1]; + break; + case MON_DATA_HP_EV: + retVal = substruct2->hpEV; + break; + case MON_DATA_ATK_EV: + retVal = substruct2->attackEV; + break; + case MON_DATA_DEF_EV: + retVal = substruct2->defenseEV; + break; + case MON_DATA_SPEED_EV: + retVal = substruct2->speedEV; + break; + case MON_DATA_SPATK_EV: + retVal = substruct2->spAttackEV; + break; + case MON_DATA_SPDEF_EV: + retVal = substruct2->spDefenseEV; + break; + case MON_DATA_COOL: + retVal = substruct2->cool; + break; + case MON_DATA_BEAUTY: + retVal = substruct2->beauty; + break; + case MON_DATA_CUTE: + retVal = substruct2->cute; + break; + case MON_DATA_SMART: + retVal = substruct2->smart; + break; + case MON_DATA_TOUGH: + retVal = substruct2->tough; + break; + case MON_DATA_SHEEN: + retVal = substruct2->sheen; + break; + case MON_DATA_POKERUS: + retVal = substruct3->pokerus; + break; + case MON_DATA_MET_LOCATION: + retVal = substruct3->metLocation; + break; + case MON_DATA_MET_LEVEL: + retVal = substruct3->metLevel; + break; + case MON_DATA_MET_GAME: + retVal = substruct3->metGame; + break; + case MON_DATA_POKEBALL: + retVal = substruct3->pokeball; + break; + case MON_DATA_OT_GENDER: + retVal = substruct3->otGender; + break; + case MON_DATA_HP_IV: + retVal = substruct3->hpIV; + break; + case MON_DATA_ATK_IV: + retVal = substruct3->attackIV; + break; + case MON_DATA_DEF_IV: + retVal = substruct3->defenseIV; + break; + case MON_DATA_SPEED_IV: + retVal = substruct3->speedIV; + break; + case MON_DATA_SPATK_IV: + retVal = substruct3->spAttackIV; + break; + case MON_DATA_SPDEF_IV: + retVal = substruct3->spDefenseIV; + break; + case MON_DATA_IS_EGG: + retVal = substruct3->isEgg; + break; + case MON_DATA_ALT_ABILITY: + retVal = substruct3->altAbility; + break; + case MON_DATA_COOL_RIBBON: + retVal = substruct3->coolRibbon; + break; + case MON_DATA_BEAUTY_RIBBON: + retVal = substruct3->beautyRibbon; + break; + case MON_DATA_CUTE_RIBBON: + retVal = substruct3->cuteRibbon; + break; + case MON_DATA_SMART_RIBBON: + retVal = substruct3->smartRibbon; + break; + case MON_DATA_TOUGH_RIBBON: + retVal = substruct3->toughRibbon; + break; + case MON_DATA_CHAMPION_RIBBON: + retVal = substruct3->championRibbon; + break; + case MON_DATA_WINNING_RIBBON: + retVal = substruct3->winningRibbon; + break; + case MON_DATA_VICTORY_RIBBON: + retVal = substruct3->victoryRibbon; + break; + case MON_DATA_ARTIST_RIBBON: + retVal = substruct3->artistRibbon; + break; + case MON_DATA_EFFORT_RIBBON: + retVal = substruct3->effortRibbon; + break; + case MON_DATA_GIFT_RIBBON_1: + retVal = substruct3->giftRibbon1; + break; + case MON_DATA_GIFT_RIBBON_2: + retVal = substruct3->giftRibbon2; + break; + case MON_DATA_GIFT_RIBBON_3: + retVal = substruct3->giftRibbon3; + break; + case MON_DATA_GIFT_RIBBON_4: + retVal = substruct3->giftRibbon4; + break; + case MON_DATA_GIFT_RIBBON_5: + retVal = substruct3->giftRibbon5; + break; + case MON_DATA_GIFT_RIBBON_6: + retVal = substruct3->giftRibbon6; + break; + case MON_DATA_GIFT_RIBBON_7: + retVal = substruct3->giftRibbon7; + break; + case MON_DATA_FATEFUL_ENCOUNTER: + retVal = substruct3->fatefulEncounter; + break; + case MON_DATA_OBEDIENCE: + retVal = substruct3->obedient; + break; + case MON_DATA_SPECIES2: + retVal = substruct0->species; + if (substruct0->species && (substruct3->isEgg || boxMon->isBadEgg)) + retVal = SPECIES_EGG; + break; + case MON_DATA_IVS: + retVal = substruct3->hpIV | (substruct3->attackIV << 5) | (substruct3->defenseIV << 10) | (substruct3->speedIV << 15) | (substruct3->spAttackIV << 20) | (substruct3->spDefenseIV << 25); + break; + case MON_DATA_KNOWN_MOVES: + if (substruct0->species && !substruct3->isEgg) + { + u16 *moves = (u16 *)data; + s32 i = 0; + + while (moves[i] != 355) + { + u16 move = moves[i]; + if (substruct1->moves[0] == move + || substruct1->moves[1] == move + || substruct1->moves[2] == move + || substruct1->moves[3] == move) + retVal |= gBitTable[i]; + i++; + } + } + break; + case MON_DATA_RIBBON_COUNT: + retVal = 0; + if (substruct0->species && !substruct3->isEgg) + { + retVal += substruct3->coolRibbon; + retVal += substruct3->beautyRibbon; + retVal += substruct3->cuteRibbon; + retVal += substruct3->smartRibbon; + retVal += substruct3->toughRibbon; + retVal += substruct3->championRibbon; + retVal += substruct3->winningRibbon; + retVal += substruct3->victoryRibbon; + retVal += substruct3->artistRibbon; + retVal += substruct3->effortRibbon; + retVal += substruct3->giftRibbon1; + retVal += substruct3->giftRibbon2; + retVal += substruct3->giftRibbon3; + retVal += substruct3->giftRibbon4; + retVal += substruct3->giftRibbon5; + retVal += substruct3->giftRibbon6; + retVal += substruct3->giftRibbon7; + } + break; + case MON_DATA_RIBBONS: + retVal = 0; + if (substruct0->species && !substruct3->isEgg) + { + retVal = substruct3->championRibbon + | (substruct3->coolRibbon << 1) + | (substruct3->beautyRibbon << 4) + | (substruct3->cuteRibbon << 7) + | (substruct3->smartRibbon << 10) + | (substruct3->toughRibbon << 13) + | (substruct3->winningRibbon << 16) + | (substruct3->victoryRibbon << 17) + | (substruct3->artistRibbon << 18) + | (substruct3->effortRibbon << 19) + | (substruct3->giftRibbon1 << 20) + | (substruct3->giftRibbon2 << 21) + | (substruct3->giftRibbon3 << 22) + | (substruct3->giftRibbon4 << 23) + | (substruct3->giftRibbon5 << 24) + | (substruct3->giftRibbon6 << 25) + | (substruct3->giftRibbon7 << 26); + } + break; + default: + break; + } + + if (field > MON_DATA_10) + EncryptBoxMon(boxMon); + + return retVal; +} + +#define SET8(lhs) (lhs) = *data +#define SET16(lhs) (lhs) = data[0] + (data[1] << 8) +#define SET32(lhs) (lhs) = data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24) + +void SetMonData(struct Pokemon *mon, s32 field, const void *dataArg) +{ + const u8* data = dataArg; + switch (field) + { + case MON_DATA_STATUS: + SET32(mon->status); + break; + case MON_DATA_LEVEL: + SET8(mon->level); + break; + case MON_DATA_HP: + SET16(mon->hp); + break; + case MON_DATA_MAX_HP: + SET16(mon->maxHP); + break; + case MON_DATA_ATK: + SET16(mon->attack); + break; + case MON_DATA_DEF: + SET16(mon->defense); + break; + case MON_DATA_SPEED: + SET16(mon->speed); + break; + case MON_DATA_SPATK: + SET16(mon->spAttack); + break; + case MON_DATA_SPDEF: + SET16(mon->spDefense); + break; + case MON_DATA_MAIL: + SET8(mon->mail); + break; + case MON_DATA_SPECIES2: + break; + default: + SetBoxMonData(&mon->box, field, data); + break; + } +} + +void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) +{ + const u8* data = dataArg; + + struct PokemonSubstruct0 *substruct0 = NULL; + struct PokemonSubstruct1 *substruct1 = NULL; + struct PokemonSubstruct2 *substruct2 = NULL; + struct PokemonSubstruct3 *substruct3 = NULL; + + if (field > MON_DATA_10) + { + substruct0 = &(GetSubstruct(boxMon, boxMon->personality, 0)->type0); + substruct1 = &(GetSubstruct(boxMon, boxMon->personality, 1)->type1); + substruct2 = &(GetSubstruct(boxMon, boxMon->personality, 2)->type2); + substruct3 = &(GetSubstruct(boxMon, boxMon->personality, 3)->type3); + + DecryptBoxMon(boxMon); + + if (CalculateBoxMonChecksum(boxMon) != boxMon->checksum) + { + boxMon->isBadEgg = 1; + boxMon->isEgg = 1; + substruct3->isEgg = 1; + EncryptBoxMon(boxMon); + return; + } + } + + switch (field) + { + case MON_DATA_PERSONALITY: + SET32(boxMon->personality); + break; + case MON_DATA_OT_ID: + SET32(boxMon->otId); + break; + case MON_DATA_NICKNAME: + { + s32 i; + for (i = 0; i < POKEMON_NAME_LENGTH; i++) + boxMon->nickname[i] = data[i]; + break; + } + case MON_DATA_LANGUAGE: + SET8(boxMon->language); + break; + case MON_DATA_SANITY_BIT1: + SET8(boxMon->isBadEgg); + break; + case MON_DATA_SANITY_BIT2: + SET8(boxMon->hasSpecies); + break; + case MON_DATA_SANITY_BIT3: + SET8(boxMon->isEgg); + break; + case MON_DATA_OT_NAME: + { + s32 i; + for (i = 0; i < OT_NAME_LENGTH; i++) + boxMon->otName[i] = data[i]; + break; + } + case MON_DATA_MARKINGS: + SET8(boxMon->markings); + break; + case MON_DATA_CHECKSUM: + SET16(boxMon->checksum); + break; + case MON_DATA_10: + SET16(boxMon->unknown); + break; + case MON_DATA_SPECIES: + { + SET16(substruct0->species); + if (substruct0->species) + boxMon->hasSpecies = 1; + else + boxMon->hasSpecies = 0; + break; + } + case MON_DATA_HELD_ITEM: + SET16(substruct0->heldItem); + break; + case MON_DATA_EXP: + SET32(substruct0->experience); + break; + case MON_DATA_PP_BONUSES: + SET8(substruct0->ppBonuses); + break; + case MON_DATA_FRIENDSHIP: + SET8(substruct0->friendship); + break; + case MON_DATA_MOVE1: + case MON_DATA_MOVE2: + case MON_DATA_MOVE3: + case MON_DATA_MOVE4: + SET16(substruct1->moves[field - MON_DATA_MOVE1]); + break; + case MON_DATA_PP1: + case MON_DATA_PP2: + case MON_DATA_PP3: + case MON_DATA_PP4: + SET8(substruct1->pp[field - MON_DATA_PP1]); + break; + case MON_DATA_HP_EV: + SET8(substruct2->hpEV); + break; + case MON_DATA_ATK_EV: + SET8(substruct2->attackEV); + break; + case MON_DATA_DEF_EV: + SET8(substruct2->defenseEV); + break; + case MON_DATA_SPEED_EV: + SET8(substruct2->speedEV); + break; + case MON_DATA_SPATK_EV: + SET8(substruct2->spAttackEV); + break; + case MON_DATA_SPDEF_EV: + SET8(substruct2->spDefenseEV); + break; + case MON_DATA_COOL: + SET8(substruct2->cool); + break; + case MON_DATA_BEAUTY: + SET8(substruct2->beauty); + break; + case MON_DATA_CUTE: + SET8(substruct2->cute); + break; + case MON_DATA_SMART: + SET8(substruct2->smart); + break; + case MON_DATA_TOUGH: + SET8(substruct2->tough); + break; + case MON_DATA_SHEEN: + SET8(substruct2->sheen); + break; + case MON_DATA_POKERUS: + SET8(substruct3->pokerus); + break; + case MON_DATA_MET_LOCATION: + SET8(substruct3->metLocation); + break; + case MON_DATA_MET_LEVEL: + { + u8 metLevel = *data; + substruct3->metLevel = metLevel; + break; + } + case MON_DATA_MET_GAME: + SET8(substruct3->metGame); + break; + case MON_DATA_POKEBALL: + { + u8 pokeball = *data; + substruct3->pokeball = pokeball; + break; + } + case MON_DATA_OT_GENDER: + SET8(substruct3->otGender); + break; + case MON_DATA_HP_IV: + SET8(substruct3->hpIV); + break; + case MON_DATA_ATK_IV: + SET8(substruct3->attackIV); + break; + case MON_DATA_DEF_IV: + SET8(substruct3->defenseIV); + break; + case MON_DATA_SPEED_IV: + SET8(substruct3->speedIV); + break; + case MON_DATA_SPATK_IV: + SET8(substruct3->spAttackIV); + break; + case MON_DATA_SPDEF_IV: + SET8(substruct3->spDefenseIV); + break; + case MON_DATA_IS_EGG: + SET8(substruct3->isEgg); + if (substruct3->isEgg) + boxMon->isEgg = 1; + else + boxMon->isEgg = 0; + break; + case MON_DATA_ALT_ABILITY: + SET8(substruct3->altAbility); + break; + case MON_DATA_COOL_RIBBON: + SET8(substruct3->coolRibbon); + break; + case MON_DATA_BEAUTY_RIBBON: + SET8(substruct3->beautyRibbon); + break; + case MON_DATA_CUTE_RIBBON: + SET8(substruct3->cuteRibbon); + break; + case MON_DATA_SMART_RIBBON: + SET8(substruct3->smartRibbon); + break; + case MON_DATA_TOUGH_RIBBON: + SET8(substruct3->toughRibbon); + break; + case MON_DATA_CHAMPION_RIBBON: + SET8(substruct3->championRibbon); + break; + case MON_DATA_WINNING_RIBBON: + SET8(substruct3->winningRibbon); + break; + case MON_DATA_VICTORY_RIBBON: + SET8(substruct3->victoryRibbon); + break; + case MON_DATA_ARTIST_RIBBON: + SET8(substruct3->artistRibbon); + break; + case MON_DATA_EFFORT_RIBBON: + SET8(substruct3->effortRibbon); + break; + case MON_DATA_GIFT_RIBBON_1: + SET8(substruct3->giftRibbon1); + break; + case MON_DATA_GIFT_RIBBON_2: + SET8(substruct3->giftRibbon2); + break; + case MON_DATA_GIFT_RIBBON_3: + SET8(substruct3->giftRibbon3); + break; + case MON_DATA_GIFT_RIBBON_4: + SET8(substruct3->giftRibbon4); + break; + case MON_DATA_GIFT_RIBBON_5: + SET8(substruct3->giftRibbon5); + break; + case MON_DATA_GIFT_RIBBON_6: + SET8(substruct3->giftRibbon6); + break; + case MON_DATA_GIFT_RIBBON_7: + SET8(substruct3->giftRibbon7); + break; + case MON_DATA_FATEFUL_ENCOUNTER: + SET8(substruct3->fatefulEncounter); + break; + case MON_DATA_OBEDIENCE: + SET8(substruct3->obedient); + break; + case MON_DATA_IVS: + { + u32 ivs = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); + substruct3->hpIV = ivs & 0x1F; + substruct3->attackIV = (ivs >> 5) & 0x1F; + substruct3->defenseIV = (ivs >> 10) & 0x1F; + substruct3->speedIV = (ivs >> 15) & 0x1F; + substruct3->spAttackIV = (ivs >> 20) & 0x1F; + substruct3->spDefenseIV = (ivs >> 25) & 0x1F; + break; + } + default: + break; + } + + if (field > MON_DATA_10) + { + boxMon->checksum = CalculateBoxMonChecksum(boxMon); + EncryptBoxMon(boxMon); + } +} + +void CopyMon(void *dest, void *src, size_t size) +{ + memcpy(dest, src, size); +} + +u8 GiveMonToPlayer(struct Pokemon *mon) +{ + s32 i; + + SetMonData(mon, MON_DATA_OT_NAME, gSaveBlock2Ptr->playerName); + SetMonData(mon, MON_DATA_OT_GENDER, &gSaveBlock2Ptr->playerGender); + SetMonData(mon, MON_DATA_OT_ID, gSaveBlock2Ptr->playerTrainerId); + + for (i = 0; i < PARTY_SIZE; i++) + { + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL) == SPECIES_NONE) + break; + } + + if (i >= PARTY_SIZE) + return SendMonToPC(mon); + + CopyMon(&gPlayerParty[i], mon, sizeof(*mon)); + gPlayerPartyCount = i + 1; + return MON_GIVEN_TO_PARTY; +} + +u8 SendMonToPC(struct Pokemon* mon) +{ + s32 boxNo, boxPos; + + set_unknown_box_id(VarGet(VAR_STORAGE_UNKNOWN)); + + boxNo = StorageGetCurrentBox(); + + do + { + for (boxPos = 0; boxPos < 30; boxPos++) + { + struct BoxPokemon* checkingMon = GetBoxedMonPtr(boxNo, boxPos); + if (GetBoxMonData(checkingMon, MON_DATA_SPECIES, NULL) == SPECIES_NONE) + { + MonRestorePP(mon); + CopyMon(checkingMon, &mon->box, sizeof(mon->box)); + gSpecialVar_MonBoxId = boxNo; + gSpecialVar_MonBoxPos = boxPos; + if (get_unknown_box_id() != boxNo) + FlagClear(FLAG_SYS_STORAGE_UNKNOWN_FLAG); + VarSet(VAR_STORAGE_UNKNOWN, boxNo); + return MON_GIVEN_TO_PC; + } + } + + boxNo++; + if (boxNo == 14) + boxNo = 0; + } while (boxNo != StorageGetCurrentBox()); + + return MON_CANT_GIVE; +} + +u8 CalculatePlayerPartyCount(void) +{ + gPlayerPartyCount = 0; + + while (gPlayerPartyCount < 6 + && GetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_SPECIES, NULL) != SPECIES_NONE) + { + gPlayerPartyCount++; + } + + return gPlayerPartyCount; +} + +u8 CalculateEnemyPartyCount(void) +{ + gEnemyPartyCount = 0; + + while (gEnemyPartyCount < 6 + && GetMonData(&gEnemyParty[gEnemyPartyCount], MON_DATA_SPECIES, NULL) != SPECIES_NONE) + { + gEnemyPartyCount++; + } + + return gEnemyPartyCount; +} + +u8 GetMonsStateToDoubles(void) +{ + s32 aliveCount = 0; + s32 i; + CalculatePlayerPartyCount(); + + if (gPlayerPartyCount == 1) + return gPlayerPartyCount; // PLAYER_HAS_ONE_MON + + for (i = 0; i < gPlayerPartyCount; i++) + { + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) != SPECIES_EGG + && GetMonData(&gPlayerParty[i], MON_DATA_HP, NULL) != 0 + && GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) != SPECIES_NONE) + aliveCount++; + } + + return (aliveCount > 1) ? PLAYER_HAS_TWO_USABLE_MONS : PLAYER_HAS_ONE_USABLE_MON; +} + +u8 GetMonsStateToDoubles_2(void) +{ + s32 aliveCount = 0; + s32 i; + + for (i = 0; i < PARTY_SIZE; i++) + { + u32 species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL); + if (species != SPECIES_EGG && species != SPECIES_NONE + && GetMonData(&gPlayerParty[i], MON_DATA_HP, NULL) != 0) + aliveCount++; + } + + if (aliveCount == 1) + return PLAYER_HAS_ONE_MON; // may have more than one, but only one is alive + + return (aliveCount > 1) ? PLAYER_HAS_TWO_USABLE_MONS : PLAYER_HAS_ONE_USABLE_MON; +} + +u8 GetAbilityBySpecies(u16 species, bool8 altAbility) +{ + if (altAbility) + gLastUsedAbility = gBaseStats[species].ability2; + else + gLastUsedAbility = gBaseStats[species].ability1; + + return gLastUsedAbility; +} + +u8 GetMonAbility(struct Pokemon *mon) +{ + u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL); + u8 altAbility = GetMonData(mon, MON_DATA_ALT_ABILITY, NULL); + return GetAbilityBySpecies(species, altAbility); +} + +void CreateSecretBaseEnemyParty(struct SecretBaseRecord *secretBaseRecord) +{ + s32 i, j; + + ZeroEnemyPartyMons(); + *gBattleResources->secretBase = *secretBaseRecord; + + for (i = 0; i < PARTY_SIZE; i++) + { + if (gBattleResources->secretBase->party.species[i]) + { + CreateMon(&gEnemyParty[i], + gBattleResources->secretBase->party.species[i], + gBattleResources->secretBase->party.levels[i], + 15, + 1, + gBattleResources->secretBase->party.personality[i], + 2, + 0); + + SetMonData(&gEnemyParty[i], MON_DATA_HELD_ITEM, &gBattleResources->secretBase->party.heldItems[i]); + + for (j = 0; j < 6; j++) + SetMonData(&gEnemyParty[i], MON_DATA_HP_EV + j, &gBattleResources->secretBase->party.EVs[i]); + + for (j = 0; j < 4; j++) + { + SetMonData(&gEnemyParty[i], MON_DATA_MOVE1 + j, &gBattleResources->secretBase->party.moves[i * 4 + j]); + SetMonData(&gEnemyParty[i], MON_DATA_PP1 + j, &gBattleMoves[gBattleResources->secretBase->party.moves[i * 4 + j]].pp); + } + } + } +} + +u8 GetSecretBaseTrainerPicIndex(void) +{ + u8 facilityClass = sSecretBaseFacilityClasses[gBattleResources->secretBase->gender][gBattleResources->secretBase->trainerId[0] % 5]; + return gFacilityClassToPicIndex[facilityClass]; +} + +u8 GetSecretBaseTrainerClass(void) +{ + u8 facilityClass = sSecretBaseFacilityClasses[gBattleResources->secretBase->gender][gBattleResources->secretBase->trainerId[0] % 5]; + return gFacilityClassToTrainerClass[facilityClass]; +} + +bool8 IsPlayerPartyAndPokemonStorageFull(void) +{ + s32 i; + + for (i = 0; i < PARTY_SIZE; i++) + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL) == SPECIES_NONE) + return FALSE; + + return IsPokemonStorageFull(); +} + +bool8 IsPokemonStorageFull(void) +{ + s32 i, j; + + for (i = 0; i < 14; i++) + for (j = 0; j < 30; j++) + if (GetBoxMonDataFromAnyBox(i, j, MON_DATA_SPECIES) == SPECIES_NONE) + return FALSE; + + return TRUE; +} + +void GetSpeciesName(u8 *name, u16 species) +{ + s32 i; + + for (i = 0; i <= POKEMON_NAME_LENGTH; i++) + { + if (species > NUM_SPECIES) + name[i] = gSpeciesNames[0][i]; + else + name[i] = gSpeciesNames[species][i]; + + if (name[i] == EOS) + break; + } + + name[i] = EOS; +} + +u8 CalculatePPWithBonus(u16 move, u8 ppBonuses, u8 moveIndex) +{ + u8 basePP = gBattleMoves[move].pp; + return basePP + ((basePP * 20 * ((gUnknown_08329D22[moveIndex] & ppBonuses) >> (2 * moveIndex))) / 100); +} + +void RemoveMonPPBonus(struct Pokemon *mon, u8 moveIndex) +{ + u8 ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES, NULL); + ppBonuses &= gUnknown_08329D26[moveIndex]; + SetMonData(mon, MON_DATA_PP_BONUSES, &ppBonuses); +} + +void RemoveBattleMonPPBonus(struct BattlePokemon *mon, u8 moveIndex) +{ + mon->ppBonuses &= gUnknown_08329D26[moveIndex]; +} + +void CopyPlayerPartyMonToBattleData(u8 battlerId, u8 partyIndex) +{ + u16* hpSwitchout; + s32 i; + u8 nickname[POKEMON_NAME_LENGTH * 2]; + + gBattleMons[battlerId].species = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPECIES, NULL); + gBattleMons[battlerId].item = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HELD_ITEM, NULL); + + for (i = 0; i < 4; i++) + { + gBattleMons[battlerId].moves[i] = GetMonData(&gPlayerParty[partyIndex], MON_DATA_MOVE1 + i, NULL); + gBattleMons[battlerId].pp[i] = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PP1 + i, NULL); + } + + gBattleMons[battlerId].ppBonuses = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PP_BONUSES, NULL); + gBattleMons[battlerId].friendship = GetMonData(&gPlayerParty[partyIndex], MON_DATA_FRIENDSHIP, NULL); + gBattleMons[battlerId].experience = GetMonData(&gPlayerParty[partyIndex], MON_DATA_EXP, NULL); + gBattleMons[battlerId].hpIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HP_IV, NULL); + gBattleMons[battlerId].attackIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_ATK_IV, NULL); + gBattleMons[battlerId].defenseIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_DEF_IV, NULL); + gBattleMons[battlerId].speedIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPEED_IV, NULL); + gBattleMons[battlerId].spAttackIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPATK_IV, NULL); + gBattleMons[battlerId].spDefenseIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPDEF_IV, NULL); + gBattleMons[battlerId].personality = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PERSONALITY, NULL); + gBattleMons[battlerId].status1 = GetMonData(&gPlayerParty[partyIndex], MON_DATA_STATUS, NULL); + gBattleMons[battlerId].level = GetMonData(&gPlayerParty[partyIndex], MON_DATA_LEVEL, NULL); + gBattleMons[battlerId].hp = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HP, NULL); + gBattleMons[battlerId].maxHP = GetMonData(&gPlayerParty[partyIndex], MON_DATA_MAX_HP, NULL); + gBattleMons[battlerId].attack = GetMonData(&gPlayerParty[partyIndex], MON_DATA_ATK, NULL); + gBattleMons[battlerId].defense = GetMonData(&gPlayerParty[partyIndex], MON_DATA_DEF, NULL); + gBattleMons[battlerId].speed = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPEED, NULL); + gBattleMons[battlerId].spAttack = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPATK, NULL); + gBattleMons[battlerId].spDefense = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPDEF, NULL); + gBattleMons[battlerId].isEgg = GetMonData(&gPlayerParty[partyIndex], MON_DATA_IS_EGG, NULL); + gBattleMons[battlerId].altAbility = GetMonData(&gPlayerParty[partyIndex], MON_DATA_ALT_ABILITY, NULL); + gBattleMons[battlerId].otId = GetMonData(&gPlayerParty[partyIndex], MON_DATA_OT_ID, NULL); + gBattleMons[battlerId].type1 = gBaseStats[gBattleMons[battlerId].species].type1; + gBattleMons[battlerId].type2 = gBaseStats[gBattleMons[battlerId].species].type2; + gBattleMons[battlerId].ability = GetAbilityBySpecies(gBattleMons[battlerId].species, gBattleMons[battlerId].altAbility); + GetMonData(&gPlayerParty[partyIndex], MON_DATA_NICKNAME, nickname); + StringCopy10(gBattleMons[battlerId].nickname, nickname); + GetMonData(&gPlayerParty[partyIndex], MON_DATA_OT_NAME, gBattleMons[battlerId].otName); + + hpSwitchout = &gBattleStruct->hpOnSwitchout[GetBattlerSide(battlerId)]; + *hpSwitchout = gBattleMons[battlerId].hp; + + for (i = 0; i < 8; i++) + gBattleMons[battlerId].statStages[i] = 6; + + gBattleMons[battlerId].status2 = 0; + sub_803FA70(battlerId); + ClearTemporarySpeciesSpriteData(battlerId, FALSE); +} + +bool8 ExecuteTableBasedItemEffect(struct Pokemon *mon, u16 item, u8 partyIndex, u8 moveIndex) +{ + return PokemonUseItemEffects(mon, item, partyIndex, moveIndex, 0); +} + +bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 moveIndex, u8 e) +{ + u32 dataUnsigned; + s32 dataSigned; + s32 friendship; + s32 cmdIndex; + bool8 retVal = TRUE; + const u8 *itemEffect; + u8 var_3C = 6; + u32 var_38; + s8 var_34 = 0; + u8 holdEffect; + u8 battlerId = 4; + u32 var_28 = 0; + u16 heldItem; + u8 r10; + u32 r4; + u32 r5; + s8 r2; + u16 evCount; + + heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, NULL); + if (heldItem == ITEM_ENIGMA_BERRY) + { + if (gMain.inBattle) + holdEffect = gEnigmaBerries[gBattlerInMenuId].holdEffect; + else + holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect; + } + else + { + holdEffect = ItemId_GetHoldEffect(heldItem); + } + + gPotentialItemEffectBattler = gBattlerInMenuId; + if (gMain.inBattle) + { + gActiveBattler = gBattlerInMenuId; + cmdIndex = (GetBattlerSide(gActiveBattler) != B_SIDE_PLAYER); + while (cmdIndex < gBattlersCount) + { + if (gBattlerPartyIndexes[cmdIndex] == partyIndex) + { + battlerId = cmdIndex; + break; + } + cmdIndex += 2; + } + } + else + { + gActiveBattler = 0; + battlerId = MAX_BATTLERS_COUNT; + } + + if (!IS_POKEMON_ITEM(item)) + return TRUE; + if (gItemEffectTable[item - 13] == NULL && item != ITEM_ENIGMA_BERRY) + return TRUE; + + if (item == ITEM_ENIGMA_BERRY) + { + if (gMain.inBattle) + itemEffect = gEnigmaBerries[gActiveBattler].itemEffect; + else + itemEffect = gSaveBlock1Ptr->enigmaBerry.itemEffect; + } + else + { + itemEffect = gItemEffectTable[item - 13]; + } + + for (cmdIndex = 0; cmdIndex < 6; cmdIndex++) + { + switch (cmdIndex) + { + // status healing effects + case 0: + if ((itemEffect[cmdIndex] & 0x80) + && gMain.inBattle && battlerId != 4 && (gBattleMons[battlerId].status2 & STATUS2_INFATUATION)) + { + gBattleMons[battlerId].status2 &= ~STATUS2_INFATUATION; + retVal = FALSE; + } + if ((itemEffect[cmdIndex] & 0x30) + && !(gBattleMons[gActiveBattler].status2 & STATUS2_FOCUS_ENERGY)) + { + gBattleMons[gActiveBattler].status2 |= STATUS2_FOCUS_ENERGY; + retVal = FALSE; + } + if ((itemEffect[cmdIndex] & 0xF) + && gBattleMons[gActiveBattler].statStages[STAT_ATK] < 12) + { + gBattleMons[gActiveBattler].statStages[STAT_ATK] += itemEffect[cmdIndex] & 0xF; + if (gBattleMons[gActiveBattler].statStages[STAT_ATK] > 12) + gBattleMons[gActiveBattler].statStages[STAT_ATK] = 12; + retVal = FALSE; + } + break; + // in-battle stat boosting effects? + case 1: + if ((itemEffect[cmdIndex] & 0xF0) + && gBattleMons[gActiveBattler].statStages[STAT_DEF] < 12) + { + gBattleMons[gActiveBattler].statStages[STAT_DEF] += (itemEffect[cmdIndex] & 0xF0) >> 4; + if (gBattleMons[gActiveBattler].statStages[STAT_DEF] > 12) + gBattleMons[gActiveBattler].statStages[STAT_DEF] = 12; + retVal = FALSE; + } + if ((itemEffect[cmdIndex] & 0xF) + && gBattleMons[gActiveBattler].statStages[STAT_SPEED] < 12) + { + gBattleMons[gActiveBattler].statStages[STAT_SPEED] += itemEffect[cmdIndex] & 0xF; + if (gBattleMons[gActiveBattler].statStages[STAT_SPEED] > 12) + gBattleMons[gActiveBattler].statStages[STAT_SPEED] = 12; + retVal = FALSE; + } + break; + // more stat boosting effects? + case 2: + if ((itemEffect[cmdIndex] & 0xF0) + && gBattleMons[gActiveBattler].statStages[STAT_ACC] < 12) + { + gBattleMons[gActiveBattler].statStages[STAT_ACC] += (itemEffect[cmdIndex] & 0xF0) >> 4; + if (gBattleMons[gActiveBattler].statStages[STAT_ACC] > 12) + gBattleMons[gActiveBattler].statStages[STAT_ACC] = 12; + retVal = FALSE; + } + if ((itemEffect[cmdIndex] & 0xF) + && gBattleMons[gActiveBattler].statStages[STAT_SPATK] < 12) + { + gBattleMons[gActiveBattler].statStages[STAT_SPATK] += itemEffect[cmdIndex] & 0xF; + if (gBattleMons[gActiveBattler].statStages[STAT_SPATK] > 12) + gBattleMons[gActiveBattler].statStages[STAT_SPATK] = 12; + retVal = FALSE; + } + break; + case 3: + if ((itemEffect[cmdIndex] & 0x80) + && gSideTimers[GetBattlerSide(gActiveBattler)].mistTimer == 0) + { + gSideTimers[GetBattlerSide(gActiveBattler)].mistTimer = 5; + retVal = FALSE; + } + if ((itemEffect[cmdIndex] & 0x40) // raise level + && GetMonData(mon, MON_DATA_LEVEL, NULL) != MAX_MON_LEVEL) + { + dataUnsigned = gExperienceTables[gBaseStats[GetMonData(mon, MON_DATA_SPECIES, NULL)].growthRate][GetMonData(mon, MON_DATA_LEVEL, NULL) + 1]; + SetMonData(mon, MON_DATA_EXP, &dataUnsigned); + CalculateMonStats(mon); + retVal = FALSE; + } + if ((itemEffect[cmdIndex] & 0x20) + && HealStatusConditions(mon, partyIndex, 7, battlerId) == 0) + { + if (battlerId != 4) + gBattleMons[battlerId].status2 &= ~STATUS2_NIGHTMARE; + retVal = FALSE; + } + if ((itemEffect[cmdIndex] & 0x10) && HealStatusConditions(mon, partyIndex, STATUS1_PSN_ANY | STATUS1_TOXIC_COUNTER, battlerId) == 0) + retVal = FALSE; + if ((itemEffect[cmdIndex] & 8) && HealStatusConditions(mon, partyIndex, STATUS1_BURN, battlerId) == 0) + retVal = FALSE; + if ((itemEffect[cmdIndex] & 4) && HealStatusConditions(mon, partyIndex, STATUS1_FREEZE, battlerId) == 0) + retVal = FALSE; + if ((itemEffect[cmdIndex] & 2) && HealStatusConditions(mon, partyIndex, STATUS1_PARALYSIS, battlerId) == 0) + retVal = FALSE; + if ((itemEffect[cmdIndex] & 1) // heal confusion + && gMain.inBattle && battlerId != 4 && (gBattleMons[battlerId].status2 & STATUS2_CONFUSION)) + { + gBattleMons[battlerId].status2 &= ~STATUS2_CONFUSION; + retVal = FALSE; + } + break; + // EV, HP, and PP raising effects + case 4: + r10 = itemEffect[cmdIndex]; + if (r10 & 0x20) + { + r10 &= ~0x20; + dataUnsigned = (GetMonData(mon, MON_DATA_PP_BONUSES, NULL) & gUnknown_08329D22[moveIndex]) >> (moveIndex * 2); + var_38 = CalculatePPWithBonus(GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL), GetMonData(mon, MON_DATA_PP_BONUSES, NULL), moveIndex); + if (dataUnsigned <= 2 && var_38 > 4) + { + dataUnsigned = GetMonData(mon, MON_DATA_PP_BONUSES, NULL) + gUnknown_08329D2A[moveIndex]; + SetMonData(mon, MON_DATA_PP_BONUSES, &dataUnsigned); + + dataUnsigned = CalculatePPWithBonus(GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL), dataUnsigned, moveIndex) - var_38; + dataUnsigned = GetMonData(mon, MON_DATA_PP1 + moveIndex, NULL) + dataUnsigned; + SetMonData(mon, MON_DATA_PP1 + moveIndex, &dataUnsigned); + retVal = FALSE; + } + } + var_38 = 0; + while (r10 != 0) + { + if (r10 & 1) + { + switch (var_38) + { + case 0: + case 1: + evCount = GetMonEVCount(mon); + r5 = itemEffect[var_3C]; + dataSigned = GetMonData(mon, sGetMonDataEVConstants[var_38], NULL); + r2 = r5; + if (r2 > 0) + { + if (evCount >= MAX_TOTAL_EVS) + return TRUE; + if (dataSigned >= 100) + break; + + if (dataSigned + r2 > 100) + r5 = 100 - (dataSigned + r2) + r2; + else + r5 = r2; + + if (evCount + r5 > MAX_TOTAL_EVS) + r5 += MAX_TOTAL_EVS - (evCount + r5); + dataSigned += r5; + } + else + { + if (dataSigned == 0) + { + var_28 = 1; + var_3C++; + break; + } + dataSigned += r2; + if (dataSigned < 0) + dataSigned = 0; + } + SetMonData(mon, sGetMonDataEVConstants[var_38], &dataSigned); + CalculateMonStats(mon); + var_3C++; + retVal = FALSE; + break; + case 2: + // revive? + if (r10 & 0x10) + { + if (GetMonData(mon, MON_DATA_HP, NULL) != 0) + { + var_3C++; + break; + } + if (gMain.inBattle) + { + if (battlerId != 4) + { + gAbsentBattlerFlags &= ~gBitTable[battlerId]; + CopyPlayerPartyMonToBattleData(battlerId, pokemon_order_func(gBattlerPartyIndexes[battlerId])); + if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER && gBattleResults.unk4 < 255) + gBattleResults.unk4++; + } + else + { + gAbsentBattlerFlags &= ~gBitTable[gActiveBattler ^ 2]; + if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER && gBattleResults.unk4 < 255) + gBattleResults.unk4++; + } + } + } + else + { + if (GetMonData(mon, MON_DATA_HP, NULL) == 0) + { + var_3C++; + break; + } + } + dataUnsigned = itemEffect[var_3C++]; + switch (dataUnsigned) + { + case 0xFF: + dataUnsigned = GetMonData(mon, MON_DATA_MAX_HP, NULL) - GetMonData(mon, MON_DATA_HP, NULL); + break; + case 0xFE: + dataUnsigned = GetMonData(mon, MON_DATA_MAX_HP, NULL) / 2; + if (dataUnsigned == 0) + dataUnsigned = 1; + break; + case 0xFD: + dataUnsigned = gBattleScripting.field_23; + break; + } + if (GetMonData(mon, MON_DATA_MAX_HP, NULL) != GetMonData(mon, MON_DATA_HP, NULL)) + { + if (e == 0) + { + dataUnsigned = GetMonData(mon, MON_DATA_HP, NULL) + dataUnsigned; + if (dataUnsigned > GetMonData(mon, MON_DATA_MAX_HP, NULL)) + dataUnsigned = GetMonData(mon, MON_DATA_MAX_HP, NULL); + SetMonData(mon, MON_DATA_HP, &dataUnsigned); + if (gMain.inBattle && battlerId != 4) + { + gBattleMons[battlerId].hp = dataUnsigned; + if (!(r10 & 0x10) && GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) + { + if (gBattleResults.unk3 < 255) + gBattleResults.unk3++; + // I have to re-use this variable to match. + r5 = gActiveBattler; + gActiveBattler = battlerId; + BtlController_EmitGetMonData(0, 0, 0); + MarkBattlerForControllerExec(gActiveBattler); + gActiveBattler = r5; + } + } + } + else + { + gBattleMoveDamage = -dataUnsigned; + } + retVal = FALSE; + } + r10 &= 0xEF; + break; + case 3: + if (!(r10 & 2)) + { + for (r5 = 0; (signed)(r5) < (signed)(4); r5++) + { + u16 moveId; + + dataUnsigned = GetMonData(mon, MON_DATA_PP1 + r5, NULL); + moveId = GetMonData(mon, MON_DATA_MOVE1 + r5, NULL); + if (dataUnsigned != CalculatePPWithBonus(moveId, GetMonData(mon, MON_DATA_PP_BONUSES, NULL), r5)) + { + dataUnsigned += itemEffect[var_3C]; + moveId = GetMonData(mon, MON_DATA_MOVE1 + r5, NULL); + if (dataUnsigned > CalculatePPWithBonus(moveId, GetMonData(mon, MON_DATA_PP_BONUSES, NULL), r5)) + { + moveId = GetMonData(mon, MON_DATA_MOVE1 + r5, NULL); + dataUnsigned = CalculatePPWithBonus(moveId, GetMonData(mon, MON_DATA_PP_BONUSES, NULL), r5); + } + SetMonData(mon, MON_DATA_PP1 + r5, &dataUnsigned); + if (gMain.inBattle + && battlerId != 4 && !(gBattleMons[battlerId].status2 & STATUS2_TRANSFORMED) + && !(gDisableStructs[battlerId].unk18_b & gBitTable[r5])) + gBattleMons[battlerId].pp[r5] = dataUnsigned; + retVal = FALSE; + } + } + var_3C++; + } + else + { + u16 moveId; + + dataUnsigned = GetMonData(mon, MON_DATA_PP1 + moveIndex, NULL); + moveId = GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL); + if (dataUnsigned != CalculatePPWithBonus(moveId, GetMonData(mon, MON_DATA_PP_BONUSES, NULL), moveIndex)) + { + dataUnsigned += itemEffect[var_3C++]; + moveId = GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL); + if (dataUnsigned > CalculatePPWithBonus(moveId, GetMonData(mon, MON_DATA_PP_BONUSES, NULL), moveIndex)) + { + moveId = GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL); + dataUnsigned = CalculatePPWithBonus(moveId, GetMonData(mon, MON_DATA_PP_BONUSES, NULL), moveIndex); + } + SetMonData(mon, MON_DATA_PP1 + moveIndex, &dataUnsigned); + if (gMain.inBattle + && battlerId != 4 && !(gBattleMons[battlerId].status2 & STATUS2_TRANSFORMED) + && !(gDisableStructs[battlerId].unk18_b & gBitTable[moveIndex])) + gBattleMons[battlerId].pp[moveIndex] = dataUnsigned; + retVal = FALSE; + } + } + break; + case 7: + { + u16 targetSpecies = GetEvolutionTargetSpecies(mon, 2, item); + + if (targetSpecies != SPECIES_NONE) + { + BeginEvolutionScene(mon, targetSpecies, 0, partyIndex); + return FALSE; + } + } + break; + } + } + var_38++; + r10 >>= 1; + } + break; + case 5: + r10 = itemEffect[cmdIndex]; + var_38 = 0; + while (r10 != 0) + { + if (r10 & 1) + { + switch (var_38) + { + case 0: + case 1: + case 2: + case 3: + evCount = GetMonEVCount(mon); + r5 = itemEffect[var_3C]; + dataSigned = GetMonData(mon, sGetMonDataEVConstants[var_38 + 2], NULL); + r2 = r5; + if (r2 > 0) + { + if (evCount >= MAX_TOTAL_EVS) + return TRUE; + if (dataSigned >= 100) + break; + + if (dataSigned + r2 > 100) + r5 = 100 - (dataSigned + r2) + r2; + else + r5 = r2; + + if (evCount + r5 > MAX_TOTAL_EVS) + r5 += MAX_TOTAL_EVS - (evCount + r5); + dataSigned += r5; + } + else + { + if (dataSigned == 0) + { + var_28 = 1; + var_3C++; + break; + } + dataSigned += r2; + if (dataSigned < 0) + dataSigned = 0; + } + SetMonData(mon, sGetMonDataEVConstants[var_38 + 2], &dataSigned); + CalculateMonStats(mon); + retVal = FALSE; + var_3C++; + break; + case 4: + dataUnsigned = (GetMonData(mon, MON_DATA_PP_BONUSES, NULL) & gUnknown_08329D22[moveIndex]) >> (moveIndex * 2); + r5 = CalculatePPWithBonus(GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL), GetMonData(mon, MON_DATA_PP_BONUSES, NULL), moveIndex); + if (dataUnsigned < 3 && r5 > 4) + { + dataUnsigned = GetMonData(mon, MON_DATA_PP_BONUSES, NULL); + dataUnsigned &= gUnknown_08329D26[moveIndex]; + dataUnsigned += gUnknown_08329D2A[moveIndex] * 3; + + SetMonData(mon, MON_DATA_PP_BONUSES, &dataUnsigned); + dataUnsigned = CalculatePPWithBonus(GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL), dataUnsigned, moveIndex) - r5; + dataUnsigned = GetMonData(mon, MON_DATA_PP1 + moveIndex, NULL) + dataUnsigned; + SetMonData(mon, MON_DATA_PP1 + moveIndex, &dataUnsigned); + retVal = FALSE; + } + break; + case 5: + if (GetMonData(mon, MON_DATA_FRIENDSHIP, NULL) < 100 && (retVal == 0 || var_28 != 0) && !sub_806F104() && var_34 == 0) + { + var_34 = itemEffect[var_3C]; + friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, NULL); + if (var_34 > 0 && holdEffect == HOLD_EFFECT_HAPPINESS_UP) + friendship += 150 * var_34 / 100; + else + friendship += var_34; + if (var_34 > 0) + { + if (GetMonData(mon, MON_DATA_POKEBALL, NULL) == 11) + friendship++; + if (GetMonData(mon, MON_DATA_MET_LOCATION, NULL) == sav1_map_get_name()) + friendship++; + } + if (friendship < 0) + friendship = 0; + if (friendship > 255) + friendship = 255; + SetMonData(mon, MON_DATA_FRIENDSHIP, &friendship); + retVal = FALSE; + } + var_3C++; + break; + case 6: + if (GetMonData(mon, MON_DATA_FRIENDSHIP, NULL) >= 100 && GetMonData(mon, MON_DATA_FRIENDSHIP, NULL) < 200 + && (retVal == 0 || var_28 != 0) && !sub_806F104() && var_34 == 0) + { + var_34 = itemEffect[var_3C]; + friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, NULL); + if ((s8)(var_34) > 0 && holdEffect == HOLD_EFFECT_HAPPINESS_UP) + friendship += 150 * var_34 / 100; + else + friendship += var_34; + if (var_34 > 0) + { + if (GetMonData(mon, MON_DATA_POKEBALL, NULL) == 11) + friendship++; + if (GetMonData(mon, MON_DATA_MET_LOCATION, NULL) == sav1_map_get_name()) + friendship++; + } + if (friendship < 0) + friendship = 0; + if (friendship > 255) + friendship = 255; + SetMonData(mon, MON_DATA_FRIENDSHIP, &friendship); + retVal = FALSE; + } + var_3C++; + break; + case 7: + if (GetMonData(mon, MON_DATA_FRIENDSHIP, NULL) >= 200 && (retVal == 0 || var_28 != 0) && !sub_806F104() && var_34 == 0) + { + var_34 = itemEffect[var_3C]; + friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, NULL); + if ((s8)(var_34) > 0 && holdEffect == HOLD_EFFECT_HAPPINESS_UP) + friendship += 150 * var_34 / 100; + else + friendship += var_34; + if (var_34 > 0) + { + if (GetMonData(mon, MON_DATA_POKEBALL, NULL) == 11) + friendship++; + if (GetMonData(mon, MON_DATA_MET_LOCATION, NULL) == sav1_map_get_name()) + friendship++; + } + if (friendship < 0) + friendship = 0; + if (friendship > 255) + friendship = 255; + SetMonData(mon, MON_DATA_FRIENDSHIP, &friendship); + retVal = FALSE; + } + var_3C++; + break; + } + } + var_38++; + r10 >>= 1; + } + break; + } + } + return retVal; +} + +bool8 HealStatusConditions(struct Pokemon *mon, u32 battlePartyId, u32 healMask, u8 battlerId) +{ + u32 status = GetMonData(mon, MON_DATA_STATUS, 0); + + if (status & healMask) + { + status &= ~healMask; + SetMonData(mon, MON_DATA_STATUS, &status); + if (gMain.inBattle && battlerId != MAX_BATTLERS_COUNT) + gBattleMons[battlerId].status1 &= ~healMask; + return FALSE; + } + else + { + return TRUE; + } +} + +u8 GetItemEffectParamOffset(u16 itemId, u8 effectByte, u8 effectBit) +{ + const u8 *temp; + const u8 *itemEffect; + u8 offset; + int i; + u8 j; + u8 val; + + offset = 6; + + temp = gItemEffectTable[itemId - 13]; + + if (!temp && itemId != ITEM_ENIGMA_BERRY) + return 0; + + if (itemId == ITEM_ENIGMA_BERRY) + { + temp = gEnigmaBerries[gActiveBattler].itemEffect; + } + + itemEffect = temp; + + for (i = 0; i < 6; i++) + { + switch (i) + { + case 0: + case 1: + case 2: + case 3: + if (i == effectByte) + return 0; + break; + case 4: + val = itemEffect[4]; + if (val & 0x20) + val &= 0xDF; + j = 0; + while (val) + { + if (val & 1) + { + switch (j) + { + case 2: + if (val & 0x10) + val &= 0xEF; + case 0: + if (i == effectByte && (val & effectBit)) + return offset; + offset++; + break; + case 1: + if (i == effectByte && (val & effectBit)) + return offset; + offset++; + break; + case 3: + if (i == effectByte && (val & effectBit)) + return offset; + offset++; + break; + case 7: + if (i == effectByte) + return 0; + break; + } + } + j++; + val >>= 1; + if (i == effectByte) + effectBit >>= 1; + } + break; + case 5: + val = itemEffect[5]; + j = 0; + while (val) + { + if (val & 1) + { + switch (j) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + if (i == effectByte && (val & effectBit)) + return offset; + offset++; + break; + case 7: + if (i == effectByte) + return 0; + break; + } + } + j++; + val >>= 1; + if (i == effectByte) + effectBit >>= 1; + } + break; + } + } + + return offset; +} + +static void sub_806CF24(s32 arg0) +{ + gBattlerTarget = gBattlerInMenuId; + StringCopy(gBattleTextBuff1, gStatNamesTable[gUnknown_08329EC8[arg0]]); + StringCopy(gBattleTextBuff2, gText_StatRose); + BattleStringExpandPlaceholdersToDisplayedString(gText_PkmnsStatChanged2); +} + +u8 *sub_806CF78(u16 itemId) +{ + int i; + const u8 *itemEffect; + + if (itemId == ITEM_ENIGMA_BERRY) + { + if (gMain.inBattle) + itemEffect = gEnigmaBerries[gBattlerInMenuId].itemEffect; + else + itemEffect = gSaveBlock1Ptr->enigmaBerry.itemEffect; + } + else + { + itemEffect = gItemEffectTable[itemId - 13]; + } + + gPotentialItemEffectBattler = gBattlerInMenuId; + + for (i = 0; i < 3; i++) + { + if (itemEffect[i] & 0xF) + sub_806CF24(i * 2); + if (itemEffect[i] & 0xF0) + { + if (i) + { + sub_806CF24(i * 2 + 1); + } + else + { + gBattlerAttacker = gBattlerInMenuId; + BattleStringExpandPlaceholdersToDisplayedString(gText_PkmnGettingPumped); + } + } + } + + if (itemEffect[3] & 0x80) + { + gBattlerAttacker = gBattlerInMenuId; + BattleStringExpandPlaceholdersToDisplayedString(gText_PkmnShroudedInMist); + } + + return gDisplayedStringBattle; +} + +u8 GetNature(struct Pokemon *mon) +{ + return GetMonData(mon, MON_DATA_PERSONALITY, 0) % 25; +} + +u8 GetNatureFromPersonality(u32 personality) +{ + return personality % 25; +} + +u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 type, u16 evolutionItem) +{ + int i; + u16 targetSpecies = 0; + u16 species = GetMonData(mon, MON_DATA_SPECIES, 0); + u16 heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0); + u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0); + u8 level; + u16 friendship; + u8 beauty = GetMonData(mon, MON_DATA_BEAUTY, 0); + u16 upperPersonality = personality >> 16; + u8 holdEffect; + + if (heldItem == ITEM_ENIGMA_BERRY) + holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect; + else + holdEffect = ItemId_GetHoldEffect(heldItem); + + if (holdEffect == 38 && type != 3) + return 0; + + switch (type) + { + case 0: + level = GetMonData(mon, MON_DATA_LEVEL, 0); + friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, 0); + + for (i = 0; i < 5; i++) + { + switch (gEvolutionTable[species][i].method) + { + case EVO_FRIENDSHIP: + if (friendship >= 220) + targetSpecies = gEvolutionTable[species][i].targetSpecies; + break; + case EVO_FRIENDSHIP_DAY: + RtcCalcLocalTime(); + if (gLocalTime.hours >= 12 && gLocalTime.hours < 24 && friendship >= 220) + targetSpecies = gEvolutionTable[species][i].targetSpecies; + break; + case EVO_FRIENDSHIP_NIGHT: + RtcCalcLocalTime(); + if (gLocalTime.hours >= 0 && gLocalTime.hours < 12 && friendship >= 220) + targetSpecies = gEvolutionTable[species][i].targetSpecies; + break; + case EVO_LEVEL: + if (gEvolutionTable[species][i].param <= level) + targetSpecies = gEvolutionTable[species][i].targetSpecies; + break; + case EVO_LEVEL_ATK_GT_DEF: + if (gEvolutionTable[species][i].param <= level) + if (GetMonData(mon, MON_DATA_ATK, 0) > GetMonData(mon, MON_DATA_DEF, 0)) + targetSpecies = gEvolutionTable[species][i].targetSpecies; + break; + case EVO_LEVEL_ATK_EQ_DEF: + if (gEvolutionTable[species][i].param <= level) + if (GetMonData(mon, MON_DATA_ATK, 0) == GetMonData(mon, MON_DATA_DEF, 0)) + targetSpecies = gEvolutionTable[species][i].targetSpecies; + break; + case EVO_LEVEL_ATK_LT_DEF: + if (gEvolutionTable[species][i].param <= level) + if (GetMonData(mon, MON_DATA_ATK, 0) < GetMonData(mon, MON_DATA_DEF, 0)) + targetSpecies = gEvolutionTable[species][i].targetSpecies; + break; + case EVO_LEVEL_SILCOON: + if (gEvolutionTable[species][i].param <= level && (upperPersonality % 10) <= 4) + targetSpecies = gEvolutionTable[species][i].targetSpecies; + break; + case EVO_LEVEL_CASCOON: + if (gEvolutionTable[species][i].param <= level && (upperPersonality % 10) > 4) + targetSpecies = gEvolutionTable[species][i].targetSpecies; + break; + case EVO_LEVEL_NINJASK: + if (gEvolutionTable[species][i].param <= level) + targetSpecies = gEvolutionTable[species][i].targetSpecies; + break; + case EVO_BEAUTY: + if (gEvolutionTable[species][i].param <= beauty) + targetSpecies = gEvolutionTable[species][i].targetSpecies; + break; + } + } + break; + case 1: + for (i = 0; i < 5; i++) + { + switch (gEvolutionTable[species][i].method) + { + case EVO_TRADE: + targetSpecies = gEvolutionTable[species][i].targetSpecies; + break; + case EVO_TRADE_ITEM: + if (gEvolutionTable[species][i].param == heldItem) + { + heldItem = 0; + SetMonData(mon, MON_DATA_HELD_ITEM, (u8 *)&heldItem); + targetSpecies = gEvolutionTable[species][i].targetSpecies; + } + break; + } + } + break; + case 2: + case 3: + for (i = 0; i < 5; i++) + { + if (gEvolutionTable[species][i].method == EVO_ITEM + && gEvolutionTable[species][i].param == evolutionItem) + { + targetSpecies = gEvolutionTable[species][i].targetSpecies; + break; + } + } + break; + } + + return targetSpecies; +} + +u16 HoennPokedexNumToSpecies(u16 hoennNum) +{ + u16 species; + + if (!hoennNum) + return 0; + + species = 0; + + while (species < 411 && gSpeciesToHoennPokedexNum[species] != hoennNum) + species++; + + if (species == 411) + return 0; + + return species + 1; +} + +u16 NationalPokedexNumToSpecies(u16 nationalNum) +{ + u16 species; + + if (!nationalNum) + return 0; + + species = 0; + + while (species < 411 && gSpeciesToNationalPokedexNum[species] != nationalNum) + species++; + + if (species == 411) + return 0; + + return species + 1; +} + +u16 NationalToHoennOrder(u16 nationalNum) +{ + u16 hoennNum; + + if (!nationalNum) + return 0; + + hoennNum = 0; + + while (hoennNum < 411 && gHoennToNationalOrder[hoennNum] != nationalNum) + hoennNum++; + + if (hoennNum == 411) + return 0; + + return hoennNum + 1; +} + +u16 SpeciesToNationalPokedexNum(u16 species) +{ + if (!species) + return 0; + + return gSpeciesToNationalPokedexNum[species - 1]; +} + +u16 SpeciesToHoennPokedexNum(u16 species) +{ + if (!species) + return 0; + + return gSpeciesToHoennPokedexNum[species - 1]; +} + +u16 HoennToNationalOrder(u16 hoennNum) +{ + if (!hoennNum) + return 0; + + return gHoennToNationalOrder[hoennNum - 1]; +} + +u16 SpeciesToCryId(u16 species) +{ + if (species <= 250) + return species; + + if (species < 276) + return 200; + + return gSpeciesIdToCryId[species - 276]; +} + +void sub_806D544(u16 species, u32 personality, u8 *dest) +{ + if (species == SPECIES_SPINDA + && dest != gMonSpritesGfxPtr->sprites[0] + && dest != gMonSpritesGfxPtr->sprites[2]) + { + int i; + for (i = 0; i < 4; i++) + { + int j; + u8 x = gSpindaSpotGraphics[i].x + ((personality & 0x0F) - 8); + u8 y = gSpindaSpotGraphics[i].y + (((personality & 0xF0) >> 4) - 8); + + for (j = 0; j < 16; j++) + { + int k; + s32 row = gSpindaSpotGraphics[i].image[j]; + + for (k = x; k < x + 16; k++) + { + u8 *val = dest + ((k / 8) * 32) + ((k % 8) / 2) + ((y >> 3) << 8) + ((y & 7) << 2); + + if (row & 1) + { + if (k & 1) + { + if ((u8)((*val & 0xF0) - 0x10) <= 0x20) + *val += 0x40; + } + else + { + if ((u8)((*val & 0xF) - 0x01) <= 0x02) + *val += 0x04; + } + } + + row >>= 1; + } + + y++; + } + + personality >>= 8; + } + } +} + +void DrawSpindaSpots(u16 species, u32 personality, u8 *dest, u8 a4) +{ + if (species == SPECIES_SPINDA && a4) + { + int i; + for (i = 0; i < 4; i++) + { + int j; + u8 x = gSpindaSpotGraphics[i].x + ((personality & 0x0F) - 8); + u8 y = gSpindaSpotGraphics[i].y + (((personality & 0xF0) >> 4) - 8); + + for (j = 0; j < 16; j++) + { + int k; + s32 row = gSpindaSpotGraphics[i].image[j]; + + for (k = x; k < x + 16; k++) + { + u8 *val = dest + ((k / 8) * 32) + ((k % 8) / 2) + ((y >> 3) << 8) + ((y & 7) << 2); + + if (row & 1) + { + if (k & 1) + { + if ((u8)((*val & 0xF0) - 0x10) <= 0x20) + *val += 0x40; + } + else + { + if ((u8)((*val & 0xF) - 0x01) <= 0x02) + *val += 0x04; + } + } + + row >>= 1; + } + + y++; + } + + personality >>= 8; + } + } +} + +void EvolutionRenameMon(struct Pokemon *mon, u16 oldSpecies, u16 newSpecies) +{ + u8 language; + GetMonData(mon, MON_DATA_NICKNAME, gStringVar1); + language = GetMonData(mon, MON_DATA_LANGUAGE, &language); + if (language == GAME_LANGUAGE && !StringCompare(gSpeciesNames[oldSpecies], gStringVar1)) + SetMonData(mon, MON_DATA_NICKNAME, gSpeciesNames[newSpecies]); +} + +bool8 sub_806D7EC(void) +{ + bool8 retVal = FALSE; + switch (gLinkPlayers[GetMultiplayerId()].lp_field_18) + { + case 0: + case 3: + retVal = FALSE; + break; + case 1: + case 2: + retVal = TRUE; + break; + } + return retVal; +} + +bool16 sub_806D82C(u8 id) +{ + bool16 retVal = FALSE; + switch (gLinkPlayers[id].lp_field_18) + { + case 0: + case 3: + retVal = FALSE; + break; + case 1: + case 2: + retVal = TRUE; + break; + } + return retVal; +} + +s32 GetBattlerMultiplayerId(u16 a1) +{ + s32 id; + for (id = 0; id < MAX_LINK_PLAYERS; id++) + if (gLinkPlayers[id].lp_field_18 == a1) + break; + return id; +} + +u8 GetTrainerEncounterMusicId(u16 trainerOpponentId) +{ + if (InBattlePyramid()) + return GetTrainerEncounterMusicIdInBattlePyramind(trainerOpponentId); + if (sub_81D5C18()) + return sub_81D63C8(trainerOpponentId); + return TRAINER_ENCOUNTER_MUSIC(trainerOpponentId); +} + +u16 ModifyStatByNature(u8 nature, u16 n, u8 statIndex) +{ + if (statIndex < 1 || statIndex > 5) + { + // should just be "return n", but it wouldn't match without this + u16 retVal = n; + retVal++; + retVal--; + return retVal; + } + + switch (gNatureStatTable[nature][statIndex - 1]) + { + case 1: + return (u16)(n * 110) / 100; + case -1: + return (u16)(n * 90) / 100; + } + + return n; +} + +void AdjustFriendship(struct Pokemon *mon, u8 event) +{ + u16 species, heldItem; + u8 holdEffect; + + if (sub_806F104()) + return; + + species = GetMonData(mon, MON_DATA_SPECIES2, 0); + heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0); + + if (heldItem == ITEM_ENIGMA_BERRY) + { + if (gMain.inBattle) + holdEffect = gEnigmaBerries[0].holdEffect; + else + holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect; + } + else + { + holdEffect = ItemId_GetHoldEffect(heldItem); + } + + if (species && species != SPECIES_EGG) + { + u8 friendshipLevel = 0; + s16 friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, 0); + if (friendship > 99) + friendshipLevel++; + if (friendship > 199) + friendshipLevel++; + if ((event != 5 || !(Random() & 1)) + && (event != 3 + || ((gBattleTypeFlags & BATTLE_TYPE_TRAINER) + && (gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_ELITE_FOUR + || gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_LEADER + || gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_CHAMPION)))) + { + s8 mod = gUnknown_08329ECE[event][friendshipLevel]; + if (mod > 0 && holdEffect == HOLD_EFFECT_HAPPINESS_UP) + mod = (150 * mod) / 100; + friendship += mod; + if (mod > 0) + { + if (GetMonData(mon, MON_DATA_POKEBALL, 0) == ITEM_LUXURY_BALL) + friendship++; + if (GetMonData(mon, MON_DATA_MET_LOCATION, 0) == sav1_map_get_name()) + friendship++; + } + if (friendship < 0) + friendship = 0; + if (friendship > 255) + friendship = 255; + SetMonData(mon, MON_DATA_FRIENDSHIP, &friendship); + } + } +} + +void MonGainEVs(struct Pokemon *mon, u16 defeatedSpecies) +{ + u8 evs[NUM_STATS]; + u16 evIncrease = 0; + u16 totalEVs = 0; + u16 heldItem; + u8 holdEffect; + int i; + + for (i = 0; i < NUM_STATS; i++) + { + evs[i] = GetMonData(mon, MON_DATA_HP_EV + i, 0); + totalEVs += evs[i]; + } + + for (i = 0; i < NUM_STATS; i++) + { + u8 hasHadPokerus; + int multiplier; + + if (totalEVs >= MAX_TOTAL_EVS) + break; + + hasHadPokerus = CheckPartyHasHadPokerus(mon, 0); + + if (hasHadPokerus) + multiplier = 2; + else + multiplier = 1; + + switch (i) + { + case 0: + evIncrease = gBaseStats[defeatedSpecies].evYield_HP * multiplier; + break; + case 1: + evIncrease = gBaseStats[defeatedSpecies].evYield_Attack * multiplier; + break; + case 2: + evIncrease = gBaseStats[defeatedSpecies].evYield_Defense * multiplier; + break; + case 3: + evIncrease = gBaseStats[defeatedSpecies].evYield_Speed * multiplier; + break; + case 4: + evIncrease = gBaseStats[defeatedSpecies].evYield_SpAttack * multiplier; + break; + case 5: + evIncrease = gBaseStats[defeatedSpecies].evYield_SpDefense * multiplier; + break; + } + + heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0); + + if (heldItem == ITEM_ENIGMA_BERRY) + { + if (gMain.inBattle) + holdEffect = gEnigmaBerries[0].holdEffect; + else + holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect; + } + else + { + holdEffect = ItemId_GetHoldEffect(heldItem); + } + + if (holdEffect == HOLD_EFFECT_MACHO_BRACE) + evIncrease *= 2; + + if (totalEVs + (s16)evIncrease > MAX_TOTAL_EVS) + evIncrease = ((s16)evIncrease + MAX_TOTAL_EVS) - (totalEVs + evIncrease); + + if (evs[i] + (s16)evIncrease > 255) + { + int val1 = (s16)evIncrease + 255; + int val2 = evs[i] + evIncrease; + evIncrease = val1 - val2; + } + + evs[i] += evIncrease; + totalEVs += evIncrease; + SetMonData(mon, MON_DATA_HP_EV + i, &evs[i]); + } +} + +u16 GetMonEVCount(struct Pokemon *mon) +{ + int i; + u16 count = 0; + + for (i = 0; i < NUM_STATS; i++) + count += GetMonData(mon, MON_DATA_HP_EV + i, 0); + + return count; +} + +void RandomlyGivePartyPokerus(struct Pokemon *party) +{ + u16 rnd = Random(); + if (rnd == 0x4000 || rnd == 0x8000 || rnd == 0xC000) + { + struct Pokemon *mon; + + do + { + do + { + rnd = Random() % PARTY_SIZE; + mon = &party[rnd]; + } + while (!GetMonData(mon, MON_DATA_SPECIES, 0)); + } + while (GetMonData(mon, MON_DATA_IS_EGG, 0)); + + if (!(CheckPartyHasHadPokerus(party, gBitTable[rnd]))) + { + u8 rnd2; + + do + { + rnd2 = Random(); + } + while ((rnd2 & 0x7) == 0); + + if (rnd2 & 0xF0) + rnd2 &= 0x7; + + rnd2 |= (rnd2 << 4); + rnd2 &= 0xF3; + rnd2++; + + SetMonData(&party[rnd], MON_DATA_POKERUS, &rnd2); + } + } +} + +u8 CheckPartyPokerus(struct Pokemon *party, u8 selection) +{ + u8 retVal; + + int partyIndex = 0; + unsigned curBit = 1; + retVal = 0; + + if (selection) + { + do + { + if ((selection & 1) && (GetMonData(&party[partyIndex], MON_DATA_POKERUS, 0) & 0xF)) + retVal |= curBit; + partyIndex++; + curBit <<= 1; + selection >>= 1; + } + while (selection); + } + else if (GetMonData(&party[0], MON_DATA_POKERUS, 0) & 0xF) + { + retVal = 1; + } + + return retVal; +} + +u8 CheckPartyHasHadPokerus(struct Pokemon *party, u8 selection) +{ + u8 retVal; + + int partyIndex = 0; + unsigned curBit = 1; + retVal = 0; + + if (selection) + { + do + { + if ((selection & 1) && GetMonData(&party[partyIndex], MON_DATA_POKERUS, 0)) + retVal |= curBit; + partyIndex++; + curBit <<= 1; + selection >>= 1; + } + while (selection); + } + else if (GetMonData(&party[0], MON_DATA_POKERUS, 0)) + { + retVal = 1; + } + + return retVal; +} + +void UpdatePartyPokerusTime(u16 days) +{ + int i; + for (i = 0; i < PARTY_SIZE; i++) + { + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, 0)) + { + u8 pokerus = GetMonData(&gPlayerParty[i], MON_DATA_POKERUS, 0); + if (pokerus & 0xF) + { + if ((pokerus & 0xF) < days || days > 4) + pokerus &= 0xF0; + else + pokerus -= days; + + if (pokerus == 0) + pokerus = 0x10; + + SetMonData(&gPlayerParty[i], MON_DATA_POKERUS, &pokerus); + } + } + } +} + +void PartySpreadPokerus(struct Pokemon *party) +{ + if ((Random() % 3) == 0) + { + int i; + for (i = 0; i < PARTY_SIZE; i++) + { + if (GetMonData(&party[i], MON_DATA_SPECIES, 0)) + { + u8 pokerus = GetMonData(&party[i], MON_DATA_POKERUS, 0); + u8 curPokerus = pokerus; + if (pokerus) + { + if (pokerus & 0xF) + { + // spread to adjacent party members + if (i != 0 && !(GetMonData(&party[i - 1], MON_DATA_POKERUS, 0) & 0xF0)) + SetMonData(&party[i - 1], MON_DATA_POKERUS, &curPokerus); + if (i != (PARTY_SIZE - 1) && !(GetMonData(&party[i + 1], MON_DATA_POKERUS, 0) & 0xF0)) + { + SetMonData(&party[i + 1], MON_DATA_POKERUS, &curPokerus); + i++; + } + } + } + } + } + } +} + +bool8 TryIncrementMonLevel(struct Pokemon *mon) +{ + u16 species = GetMonData(mon, MON_DATA_SPECIES, 0); + u8 nextLevel = GetMonData(mon, MON_DATA_LEVEL, 0) + 1; + u32 expPoints = GetMonData(mon, MON_DATA_EXP, 0); + if (expPoints > gExperienceTables[gBaseStats[species].growthRate][MAX_MON_LEVEL]) + { + expPoints = gExperienceTables[gBaseStats[species].growthRate][MAX_MON_LEVEL]; + SetMonData(mon, MON_DATA_EXP, &expPoints); + } + if (nextLevel > MAX_MON_LEVEL || expPoints < gExperienceTables[gBaseStats[species].growthRate][nextLevel]) + { + return FALSE; + } + else + { + SetMonData(mon, MON_DATA_LEVEL, &nextLevel); + return TRUE; + } +} + +u32 CanMonLearnTMHM(struct Pokemon *mon, u8 tm) +{ + u16 species = GetMonData(mon, MON_DATA_SPECIES2, 0); + if (species == SPECIES_EGG) + { + return 0; + } + else if (tm < 32) + { + u32 mask = 1 << tm; + return gTMHMLearnsets[species][0] & mask; + } + else + { + u32 mask = 1 << (tm - 32); + return gTMHMLearnsets[species][1] & mask; + } +} + +u32 CanSpeciesLearnTMHM(u16 species, u8 tm) +{ + if (species == SPECIES_EGG) + { + return 0; + } + else if (tm < 32) + { + u32 mask = 1 << tm; + return gTMHMLearnsets[species][0] & mask; + } + else + { + u32 mask = 1 << (tm - 32); + return gTMHMLearnsets[species][1] & mask; + } +} + +u8 GetMoveRelearnerMoves(struct Pokemon *mon, u16 *moves) +{ + u16 learnedMoves[4]; + u8 numMoves = 0; + u16 species = GetMonData(mon, MON_DATA_SPECIES, 0); + u8 level = GetMonData(mon, MON_DATA_LEVEL, 0); + int i, j, k; + + for (i = 0; i < 4; i++) + learnedMoves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, 0); + + for (i = 0; i < 20; i++) + { + u16 moveLevel; + + if (gLevelUpLearnsets[species][i] == 0xFFFF) + break; + + moveLevel = gLevelUpLearnsets[species][i] & 0xFE00; + + if (moveLevel <= (level << 9)) + { + for (j = 0; j < 4 && learnedMoves[j] != (gLevelUpLearnsets[species][i] & 0x1FF); j++) + ; + + if (j == 4) + { + for (k = 0; k < numMoves && moves[k] != (gLevelUpLearnsets[species][i] & 0x1FF); k++) + ; + + if (k == numMoves) + moves[numMoves++] = gLevelUpLearnsets[species][i] & 0x1FF; + } + } + } + + return numMoves; +} + +u8 GetLevelUpMovesBySpecies(u16 species, u16 *moves) +{ + u8 numMoves = 0; + int i; + + for (i = 0; i < 20 && gLevelUpLearnsets[species][i] != 0xFFFF; i++) + moves[numMoves++] = gLevelUpLearnsets[species][i] & 0x1FF; + + return numMoves; +} + +u8 GetNumberOfRelearnableMoves(struct Pokemon *mon) +{ + u16 learnedMoves[4]; + u16 moves[20]; + u8 numMoves = 0; + u16 species = GetMonData(mon, MON_DATA_SPECIES2, 0); + u8 level = GetMonData(mon, MON_DATA_LEVEL, 0); + int i, j, k; + + if (species == SPECIES_EGG) + return 0; + + for (i = 0; i < 4; i++) + learnedMoves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, 0); + + for (i = 0; i < 20; i++) + { + u16 moveLevel; + + if (gLevelUpLearnsets[species][i] == 0xFFFF) + break; + + moveLevel = gLevelUpLearnsets[species][i] & 0xFE00; + + if (moveLevel <= (level << 9)) + { + for (j = 0; j < 4 && learnedMoves[j] != (gLevelUpLearnsets[species][i] & 0x1FF); j++) + ; + + if (j == 4) + { + for (k = 0; k < numMoves && moves[k] != (gLevelUpLearnsets[species][i] & 0x1FF); k++) + ; + + if (k == numMoves) + moves[numMoves++] = gLevelUpLearnsets[species][i] & 0x1FF; + } + } + } + + return numMoves; +} + +u16 SpeciesToPokedexNum(u16 species) +{ + if (IsNationalPokedexEnabled()) + { + return SpeciesToNationalPokedexNum(species); + } + else + { + species = SpeciesToHoennPokedexNum(species); + if (species <= 202) + return species; + return 0xFFFF; + } +} + +bool32 sub_806E3F8(u16 species) +{ + if (SpeciesToHoennPokedexNum(species) > 202) + return FALSE; + else + return TRUE; +} + +void ClearBattleMonForms(void) +{ + int i; + for (i = 0; i < MAX_BATTLERS_COUNT; i++) + gBattleMonForms[i] = 0; +} + +u16 GetBattleBGM(void) +{ + if (gBattleTypeFlags & BATTLE_TYPE_KYOGRE_GROUDON) + return MUS_BATTLE34; + if (gBattleTypeFlags & BATTLE_TYPE_REGI) + return MUS_BATTLE36; + if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000)) + return MUS_BATTLE20; + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) + { + u8 trainerClass; + + if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER) + trainerClass = GetFrontierOpponentClass(gTrainerBattleOpponent_A); + else if (gBattleTypeFlags & BATTLE_TYPE_x4000000) + trainerClass = TRAINER_CLASS_EXPERT; + else + trainerClass = gTrainers[gTrainerBattleOpponent_A].trainerClass; + + switch (trainerClass) + { + case TRAINER_CLASS_AQUA_LEADER: + case TRAINER_CLASS_MAGMA_LEADER: + return MUS_BATTLE30; + case TRAINER_CLASS_TEAM_AQUA: + case TRAINER_CLASS_TEAM_MAGMA: + case TRAINER_CLASS_AQUA_ADMIN: + case TRAINER_CLASS_MAGMA_ADMIN: + return MUS_BATTLE31; + case TRAINER_CLASS_LEADER: + return MUS_BATTLE32; + case TRAINER_CLASS_CHAMPION: + return MUS_BATTLE33; + case TRAINER_CLASS_PKMN_TRAINER_3: + if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER) + return MUS_BATTLE35; + if (!StringCompare(gTrainers[gTrainerBattleOpponent_A].trainerName, gText_BattleWallyName)) + return MUS_BATTLE20; + return MUS_BATTLE35; + case TRAINER_CLASS_ELITE_FOUR: + return MUS_BATTLE38; + case TRAINER_CLASS_SALON_MAIDEN: + case TRAINER_CLASS_DOME_ACE: + case TRAINER_CLASS_PALACE_MAVEN: + case TRAINER_CLASS_ARENA_TYCOON: + case TRAINER_CLASS_FACTORY_HEAD: + case TRAINER_CLASS_PIKE_QUEEN: + case TRAINER_CLASS_PYRAMID_KING: + return MUS_VS_FRONT; + default: + return MUS_BATTLE20; + } + } + return MUS_BATTLE27; +} + +void PlayBattleBGM(void) +{ + ResetMapMusic(); + m4aMPlayAllStop(); + PlayBGM(GetBattleBGM()); +} + +void PlayMapChosenOrBattleBGM(u16 songId) +{ + ResetMapMusic(); + m4aMPlayAllStop(); + if (songId) + PlayNewMapMusic(songId); + else + PlayNewMapMusic(GetBattleBGM()); +} + +void sub_806E694(u16 songId) +{ + u8 taskId; + + ResetMapMusic(); + m4aMPlayAllStop(); + + taskId = CreateTask(sub_806E6CC, 0); + gTasks[taskId].data[0] = songId; +} + +static void sub_806E6CC(u8 taskId) +{ + if (gTasks[taskId].data[0]) + PlayNewMapMusic(gTasks[taskId].data[0]); + else + PlayNewMapMusic(GetBattleBGM()); + DestroyTask(taskId); +} + +const u8 *GetMonFrontSpritePal(struct Pokemon *mon) +{ + u16 species = GetMonData(mon, MON_DATA_SPECIES2, 0); + u32 otId = GetMonData(mon, MON_DATA_OT_ID, 0); + u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0); + return GetFrontSpritePalFromSpeciesAndPersonality(species, otId, personality); +} + +// Extracts the upper 16 bits of a 32-bit number +#define HIHALF(n) (((n) & 0xFFFF0000) >> 16) + +// Extracts the lower 16 bits of a 32-bit number +#define LOHALF(n) ((n) & 0xFFFF) + +const u8 *GetFrontSpritePalFromSpeciesAndPersonality(u16 species, u32 otId, u32 personality) +{ + u32 shinyValue; + + if (species > SPECIES_EGG) + return gMonPaletteTable[0].data; + + shinyValue = HIHALF(otId) ^ LOHALF(otId) ^ HIHALF(personality) ^ LOHALF(personality); + if (shinyValue < 8) + return gMonShinyPaletteTable[species].data; + else + return gMonPaletteTable[species].data; +} + +const struct CompressedSpritePalette *GetMonSpritePalStruct(struct Pokemon *mon) +{ + u16 species = GetMonData(mon, MON_DATA_SPECIES2, 0); + u32 otId = GetMonData(mon, MON_DATA_OT_ID, 0); + u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0); + return GetMonSpritePalStructFromOtIdPersonality(species, otId, personality); +} + +const struct CompressedSpritePalette *GetMonSpritePalStructFromOtIdPersonality(u16 species, u32 otId , u32 personality) +{ + u32 shinyValue; + + shinyValue = HIHALF(otId) ^ LOHALF(otId) ^ HIHALF(personality) ^ LOHALF(personality); + if (shinyValue < 8) + return &gMonShinyPaletteTable[species]; + else + return &gMonPaletteTable[species]; +} + +bool32 IsHMMove2(u16 move) +{ + int i = 0; + while (sHMMoves[i] != 0xFFFF) + { + if (sHMMoves[i++] == move) + return TRUE; + } + return FALSE; +} + +bool8 IsMonSpriteNotFlipped(u16 species) +{ + return gBaseStats[species].noFlip; +} + +s8 GetMonFlavorRelation(struct Pokemon *mon, u8 flavor) +{ + u8 nature = GetNature(mon); + return gPokeblockFlavorCompatibilityTable[nature * 5 + flavor]; +} + +s8 GetFlavorRelationByPersonality(u32 personality, u8 flavor) +{ + u8 nature = GetNatureFromPersonality(personality); + return gPokeblockFlavorCompatibilityTable[nature * 5 + flavor]; +} + +bool8 IsTradedMon(struct Pokemon *mon) +{ + u8 otName[OT_NAME_LENGTH + 1]; + u32 otId; + GetMonData(mon, MON_DATA_OT_NAME, otName); + otId = GetMonData(mon, MON_DATA_OT_ID, 0); + return IsOtherTrainer(otId, otName); +} + +bool8 IsOtherTrainer(u32 otId, u8 *otName) +{ + if (otId == + (gSaveBlock2Ptr->playerTrainerId[0] + | (gSaveBlock2Ptr->playerTrainerId[1] << 8) + | (gSaveBlock2Ptr->playerTrainerId[2] << 16) + | (gSaveBlock2Ptr->playerTrainerId[3] << 24))) + { + int i; + + for (i = 0; otName[i] != EOS; i++) + if (otName[i] != gSaveBlock2Ptr->playerName[i]) + return TRUE; + return FALSE; + } + + return TRUE; +} + +void MonRestorePP(struct Pokemon *mon) +{ + BoxMonRestorePP(&mon->box); +} + +void BoxMonRestorePP(struct BoxPokemon *boxMon) +{ + int i; + + for (i = 0; i < 4; i++) + { + if (GetBoxMonData(boxMon, MON_DATA_MOVE1 + i, 0)) + { + u16 move = GetBoxMonData(boxMon, MON_DATA_MOVE1 + i, 0); + u16 bonus = GetBoxMonData(boxMon, MON_DATA_PP_BONUSES, 0); + u8 pp = CalculatePPWithBonus(move, bonus, i); + SetBoxMonData(boxMon, MON_DATA_PP1 + i, &pp); + } + } +} + +void sub_806E994(void) +{ + gLastUsedAbility = gBattleStruct->field_B0; + + gBattleTextBuff1[0] = B_BUFF_PLACEHOLDER_BEGIN; + gBattleTextBuff1[1] = B_BUFF_MON_NICK_WITH_PREFIX; + gBattleTextBuff1[2] = gBattleStruct->field_49; + gBattleTextBuff1[4] = B_BUFF_EOS; + + if (!GetBattlerSide(gBattleStruct->field_49)) + gBattleTextBuff1[3] = pokemon_order_func(gBattlerPartyIndexes[gBattleStruct->field_49]); + else + gBattleTextBuff1[3] = gBattlerPartyIndexes[gBattleStruct->field_49]; + + PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff2, gBattlerInMenuId, pokemon_order_func(gBattlerPartyIndexes[gBattlerInMenuId])) + + BattleStringExpandPlaceholders(gText_PkmnsXPreventsSwitching, gStringVar4); +} + +static s32 GetWildMonTableIdInAlteringCave(u16 species) +{ + s32 i; + for (i = 0; i < (s32) ARRAY_COUNT(sAlteringCaveWildMonHeldItems); i++) + if (sAlteringCaveWildMonHeldItems[i].species == species) + return i; + return 0; +} + +void SetWildMonHeldItem(void) +{ + if (!(gBattleTypeFlags & (BATTLE_TYPE_LEGENDARY | BATTLE_TYPE_TRAINER | BATTLE_TYPE_PYRAMID | BATTLE_TYPE_PIKE))) + { + u16 rnd = Random() % 100; + u16 species = GetMonData(&gEnemyParty[0], MON_DATA_SPECIES, 0); + u16 var1 = 45; + u16 var2 = 95; + if (!GetMonData(&gPlayerParty[0], MON_DATA_SANITY_BIT3, 0) + && GetMonAbility(&gPlayerParty[0]) == ABILITY_COMPOUND_EYES) + { + var1 = 20; + var2 = 80; + } + if (gMapHeader.mapDataId == 0x1A4) + { + s32 alteringCaveId = GetWildMonTableIdInAlteringCave(species); + if (alteringCaveId != 0) + { + if (rnd < var2) + return; + SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &sAlteringCaveWildMonHeldItems[alteringCaveId].item); + } + else + { + if (rnd < var1) + return; + if (rnd < var2) + SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gBaseStats[species].item1); + else + SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gBaseStats[species].item2); + } + } + else + { + if (gBaseStats[species].item1 == gBaseStats[species].item2 && gBaseStats[species].item1 != 0) + { + SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gBaseStats[species].item1); + } + else + { + if (rnd < var1) + return; + if (rnd < var2) + SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gBaseStats[species].item1); + else + SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gBaseStats[species].item2); + } + } + } +} + +bool8 IsMonShiny(struct Pokemon *mon) +{ + u32 otId = GetMonData(mon, MON_DATA_OT_ID, 0); + u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0); + return IsShinyOtIdPersonality(otId, personality); +} + +bool8 IsShinyOtIdPersonality(u32 otId, u32 personality) +{ + bool8 retVal = FALSE; + u32 shinyValue = HIHALF(otId) ^ LOHALF(otId) ^ HIHALF(personality) ^ LOHALF(personality); + if (shinyValue < 8) + retVal = TRUE; + return retVal; +} + +const u8 *GetTrainerPartnerName(void) +{ + if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) + { + if (gPartnerTrainerId == STEVEN_PARTNER_ID) + { + return gTrainers[TRAINER_STEVEN].trainerName; + } + else + { + GetFrontierTrainerName(gStringVar1, gPartnerTrainerId); + return gStringVar1; + } + } + else + { + u8 id = GetMultiplayerId(); + return gLinkPlayers[GetBattlerMultiplayerId(gLinkPlayers[id].lp_field_18 ^ 2)].name; + } +} + +#define READ_PTR_FROM_TASK(taskId, dataId) \ + (void*)( \ + ((u16)(gTasks[taskId].data[dataId]) | \ + ((u16)(gTasks[taskId].data[dataId + 1]) << 0x10))) + +#define STORE_PTR_IN_TASK(ptr, taskId, dataId) \ +{ \ + gTasks[taskId].data[dataId] = (u32)(ptr); \ + gTasks[taskId].data[dataId + 1] = (u32)(ptr) >> 0x10; \ +} + +static void Task_AnimateAfterDelay(u8 taskId) +{ + if (--gTasks[taskId].data[3] == 0) + { + LaunchAnimationTaskForFrontSprite(READ_PTR_FROM_TASK(taskId, 0), gTasks[taskId].data[2]); + DestroyTask(taskId); + } +} + +static void Task_PokemonSummaryAnimateAfterDelay(u8 taskId) +{ + if (--gTasks[taskId].data[3] == 0) + { + StartMonSummaryAnimation(READ_PTR_FROM_TASK(taskId, 0), gTasks[taskId].data[2]); + sub_81C488C(0xFF); + DestroyTask(taskId); + } +} + +void BattleAnimateFrontSprite(struct Sprite* sprite, u16 species, bool8 noCry, u8 arg3) +{ + if (gHitMarker & HITMARKER_NO_ANIMATIONS && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000))) + DoMonFrontSpriteAnimation(sprite, species, noCry, arg3 | 0x80); + else + DoMonFrontSpriteAnimation(sprite, species, noCry, arg3); +} + +void DoMonFrontSpriteAnimation(struct Sprite* sprite, u16 species, bool8 noCry, u8 arg3) +{ + s8 pan; + switch (arg3 & 0x7F) + { + case 0: + pan = -25; + break; + case 1: + pan = 25; + break; + default: + pan = 0; + break; + } + if (arg3 & 0x80) + { + if (!noCry) + PlayCry1(species, pan); + sprite->callback = SpriteCallbackDummy; + } + else + { + if (!noCry) + { + PlayCry1(species, pan); + if (HasTwoFramesAnimation(species)) + StartSpriteAnim(sprite, 1); + } + if (sMonAnimationDelayTable[species - 1] != 0) + { + u8 taskId = CreateTask(Task_AnimateAfterDelay, 0); + STORE_PTR_IN_TASK(sprite, taskId, 0); + gTasks[taskId].data[2] = sMonFrontAnimIdsTable[species - 1]; + gTasks[taskId].data[3] = sMonAnimationDelayTable[species - 1]; + } + else + { + LaunchAnimationTaskForFrontSprite(sprite, sMonFrontAnimIdsTable[species - 1]); + } + sprite->callback = SpriteCallbackDummy_2; + } +} + +void PokemonSummaryDoMonAnimation(struct Sprite* sprite, u16 species, bool8 oneFrame) +{ + if (!oneFrame && HasTwoFramesAnimation(species)) + StartSpriteAnim(sprite, 1); + if (sMonAnimationDelayTable[species - 1] != 0) + { + u8 taskId = CreateTask(Task_PokemonSummaryAnimateAfterDelay, 0); + STORE_PTR_IN_TASK(sprite, taskId, 0); + gTasks[taskId].data[2] = sMonFrontAnimIdsTable[species - 1]; + gTasks[taskId].data[3] = sMonAnimationDelayTable[species - 1]; + sub_81C488C(taskId); + SetSpriteCB_MonAnimDummy(sprite); + } + else + { + StartMonSummaryAnimation(sprite, sMonFrontAnimIdsTable[species - 1]); + } +} + +void sub_806EE98(void) +{ + u8 delayTaskId = FindTaskIdByFunc(Task_PokemonSummaryAnimateAfterDelay); + if (delayTaskId != 0xFF) + DestroyTask(delayTaskId); +} + +void BattleAnimateBackSprite(struct Sprite* sprite, u16 species) +{ + if (gHitMarker & HITMARKER_NO_ANIMATIONS && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000))) + { + sprite->callback = SpriteCallbackDummy; + } + else + { + LaunchAnimationTaskForBackSprite(sprite, GetSpeciesBackAnimSet(species)); + sprite->callback = SpriteCallbackDummy_2; + } +} + +u8 sub_806EF08(u8 arg0) +{ + s32 i; + s32 var = 0; + u8 multiplayerId = GetMultiplayerId(); + switch (gLinkPlayers[multiplayerId].lp_field_18) + { + case 0: + case 2: + var = (arg0 != 0) ? 1 : 3; + break; + case 1: + case 3: + var = (arg0 != 0) ? 2 : 0; + break; + } + for (i = 0; i < 4; i++) + { + if (gLinkPlayers[i].lp_field_18 == (s16)(var)) + break; + } + return i; +} + +u8 sub_806EF84(u8 arg0, u8 arg1) +{ + s32 i; + s32 var = 0; + switch (gLinkPlayers[arg1].lp_field_18) + { + case 0: + case 2: + var = (arg0 != 0) ? 1 : 3; + break; + case 1: + case 3: + var = (arg0 != 0) ? 2 : 0; + break; + } + for (i = 0; i < 4; i++) + { + if (gLinkPlayers[i].lp_field_18 == (s16)(var)) + break; + } + return i; +} + +u16 FacilityClassToPicIndex(u16 facilityClass) +{ + return gFacilityClassToPicIndex[facilityClass]; +} + +u16 PlayerGenderToFrontTrainerPicId(u8 playerGender) +{ + if (playerGender != MALE) + return FacilityClassToPicIndex(FACILITY_CLASS_PKMN_TRAINER_BRENDAN); + else + return FacilityClassToPicIndex(FACILITY_CLASS_PKMN_TRAINER_MAY); +} + +void HandleSetPokedexFlag(u16 nationalNum, u8 caseId, u32 personality) +{ + u8 getFlagCaseId = (caseId == FLAG_SET_SEEN) ? FLAG_GET_SEEN : FLAG_GET_CAUGHT; + if (!GetSetPokedexFlag(nationalNum, getFlagCaseId)) // don't set if it's already set + { + GetSetPokedexFlag(nationalNum, caseId); + if (NationalPokedexNumToSpecies(nationalNum) == SPECIES_UNOWN) + gSaveBlock2Ptr->pokedex.unownPersonality = personality; + if (NationalPokedexNumToSpecies(nationalNum) == SPECIES_SPINDA) + gSaveBlock2Ptr->pokedex.spindaPersonality = personality; + } +} + +const u8 *GetTrainerClassNameFromId(u16 trainerId) +{ + if (trainerId > NO_OF_TRAINERS) + trainerId = 0; + return gTrainerClassNames[gTrainers[trainerId].trainerClass]; +} + +const u8 *GetTrainerNameFromId(u16 trainerId) +{ + if (trainerId > NO_OF_TRAINERS) + trainerId = 0; + return gTrainers[trainerId].trainerName; +} + +bool8 HasTwoFramesAnimation(u16 species) +{ + return (species != SPECIES_CASTFORM + && species != SPECIES_DEOXYS + && species != SPECIES_SPINDA + && species != SPECIES_UNOWN); +} + +bool8 sub_806F104(void) +{ + if (gMain.inBattle && gBattleTypeFlags & (BATTLE_TYPE_FRONTIER)) + return TRUE; + if (!gMain.inBattle && (InBattlePike() || InBattlePyramid())) + return TRUE; + return FALSE; +} + +#define FORCE_SIGNED(x)(-(x * (-1))) + +static void sub_806F160(struct Unknown_806F160_Struct* structPtr) +{ + u16 i, j; + for (i = 0; i < FORCE_SIGNED(structPtr->field_0_0); i++) + { + structPtr->templates[i] = gUnknown_08329D98[i]; + for (j = 0; j < structPtr->field_1; j++) + { + asm(""); + structPtr->frameImages[i * structPtr->field_1 + j].data = &structPtr->byteArrays[i][j * 0x800]; + } + structPtr->templates[i].images = &structPtr->frameImages[i * structPtr->field_1]; + } +} + +static void sub_806F1FC(struct Unknown_806F160_Struct* structPtr) +{ + u16 i, j; + for (i = 0; i < FORCE_SIGNED(structPtr->field_0_0); i++) + { + structPtr->templates[i] = gUnknown_08329F28; + for (j = 0; j < structPtr->field_1; j++) + { + structPtr->frameImages[i * structPtr->field_0_0 + j].data = &structPtr->byteArrays[i][j * 0x800]; + } + structPtr->templates[i].images = &structPtr->frameImages[i * structPtr->field_0_0]; + structPtr->templates[i].anims = gUnknown_082FF70C; + structPtr->templates[i].paletteTag = i; + } +} + +struct Unknown_806F160_Struct *sub_806F2AC(u8 id, u8 arg1) +{ + u8 i; + u8 flags; + struct Unknown_806F160_Struct *structPtr; + + flags = 0; + id %= 2; + structPtr = AllocZeroed(sizeof(*structPtr)); + if (structPtr == NULL) + return NULL; + + switch (arg1) + { + case 2: + structPtr->field_0_0 = 7; + structPtr->field_0_1 = 7; + structPtr->field_1 = 4; + structPtr->field_3_0 = 1; + structPtr->field_3_1 = 2; + break; + case 0: + default: + structPtr->field_0_0 = 4; + structPtr->field_0_1 = 4; + structPtr->field_1 = 4; + structPtr->field_3_0 = 1; + structPtr->field_3_1 = 0; + break; + } + + structPtr->bytes = AllocZeroed(structPtr->field_3_0 * 0x800 * 4 * structPtr->field_0_0); + structPtr->byteArrays = AllocZeroed(structPtr->field_0_0 * 32); + if (structPtr->bytes == NULL || structPtr->byteArrays == NULL) + { + flags |= 1; + } + else + { + for (i = 0; i < FORCE_SIGNED(structPtr->field_0_0); i++) + structPtr->byteArrays[i] = structPtr->bytes + (structPtr->field_3_0 * (i << 0xD)); + } + + structPtr->templates = AllocZeroed(sizeof(struct SpriteTemplate) * structPtr->field_0_0); + structPtr->frameImages = AllocZeroed(sizeof(struct SpriteFrameImage) * structPtr->field_0_0 * structPtr->field_1); + if (structPtr->templates == NULL || structPtr->frameImages == NULL) + { + flags |= 2; + } + else + { + for (i = 0; i < structPtr->field_1 * structPtr->field_0_0; i++) + structPtr->frameImages[i].size = 0x800; + + switch (structPtr->field_3_1) + { + case 2: + sub_806F1FC(structPtr); + break; + case 0: + case 1: + default: + sub_806F160(structPtr); + break; + } + } + + if (flags & 2) + { + if (structPtr->frameImages != NULL) + FREE_AND_SET_NULL(structPtr->frameImages); + if (structPtr->templates != NULL) + FREE_AND_SET_NULL(structPtr->templates); + } + if (flags & 1) + { + if (structPtr->byteArrays != NULL) + FREE_AND_SET_NULL(structPtr->byteArrays); + if (structPtr->bytes != NULL) + FREE_AND_SET_NULL(structPtr->bytes); + } + + if (flags) + { + memset(structPtr, 0, sizeof(*structPtr)); + Free(structPtr); + } + else + { + structPtr->magic = 0xA3; + gUnknown_020249B4[id] = structPtr; + } + + return gUnknown_020249B4[id]; +} + +void sub_806F47C(u8 id) +{ + struct Unknown_806F160_Struct *structPtr; + + id %= 2; + structPtr = gUnknown_020249B4[id]; + if (structPtr == NULL) + return; + + if (structPtr->magic != 0xA3) + { + memset(structPtr, 0, sizeof(struct Unknown_806F160_Struct)); + } + else + { + + if (structPtr->frameImages != NULL) + FREE_AND_SET_NULL(structPtr->frameImages); + if (structPtr->templates != NULL) + FREE_AND_SET_NULL(structPtr->templates); + if (structPtr->byteArrays != NULL) + FREE_AND_SET_NULL(structPtr->byteArrays); + if (structPtr->bytes != NULL) + FREE_AND_SET_NULL(structPtr->bytes); + + memset(structPtr, 0, sizeof(struct Unknown_806F160_Struct)); + Free(structPtr); + } +} + +u8 *sub_806F4F8(u8 id, u8 arg1) +{ + struct Unknown_806F160_Struct *structPtr = gUnknown_020249B4[id % 2]; + if (structPtr->magic != 0xA3) + { + return NULL; + } + else + { + if (arg1 >= FORCE_SIGNED(structPtr->field_0_0)) + arg1 = 0; + + return structPtr->byteArrays[arg1]; + } +} diff --git a/src/pokemon_1.c b/src/pokemon_1.c deleted file mode 100644 index cafd86c07..000000000 --- a/src/pokemon_1.c +++ /dev/null @@ -1,457 +0,0 @@ -#include "global.h" -#include "pokemon.h" -#include "random.h" -#include "main.h" -#include "constants/species.h" -#include "constants/abilities.h" -#include "constants/items.h" -#include "constants/trainers.h" -#include "constants/moves.h" -#include "string_util.h" -#include "text.h" - -//Extracts the upper 16 bits of a 32-bit number -#define HIHALF(n) (((n) & 0xFFFF0000) >> 16) - -//Extracts the lower 16 bits of a 32-bit number -#define LOHALF(n) ((n) & 0xFFFF) - -extern u8 sav1_map_get_name(void); - -// EWRAM vars -EWRAM_DATA u8 sLearningMoveTableID = 0; -EWRAM_DATA u8 gPlayerPartyCount = 0; -EWRAM_DATA u8 gEnemyPartyCount = 0; -EWRAM_DATA struct Pokemon gPlayerParty[PARTY_SIZE] = {0}; -EWRAM_DATA struct Pokemon gEnemyParty[PARTY_SIZE] = {0}; - -// const rom data -const u16 gSpeciesToHoennPokedexNum[] = {203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 156, 157, 112, 113, 227, 228, 229, 230, 231, 232, 233, 234, 153, 154, 138, 139, 63, 64, 88, 89, 90, 235, 236, 237, 238, 239, 240, 241, 242, 158, 159, 243, 244, 245, 246, 247, 248, 249, 39, 40, 41, 73, 74, 75, 250, 251, 252, 66, 67, 57, 58, 59, 253, 254, 255, 256, 82, 83, 257, 92, 93, 258, 259, 106, 107, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 84, 85, 270, 271, 272, 273, 274, 275, 276, 108, 109, 169, 170, 277, 278, 279, 184, 185, 50, 51, 143, 144, 280, 281, 282, 283, 284, 167, 285, 52, 53, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 65, 181, 182, 155, 324, 137, 325, 326, 162, 163, 327, 328, 329, 91, 55, 56, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 161, 164, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 168, 357, 358, 359, 103, 104, 360, 361, 180, 362, 363, 364, 365, 115, 366, 367, 186, 165, 166, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 42, 43, 44, 25, 26, 34, 35, 114, 27, 28, 32, 33, 99, 100, 61, 62, 145, 131, 132, 60, 105, 68, 127, 128, 183, 129, 130, 140, 141, 97, 98, 116, 117, 118, 48, 49, 78, 79, 101, 102, 173, 174, 175, 119, 120, 171, 172, 125, 126, 54, 110, 111, 80, 81, 69, 76, 77, 121, 122, 160, 148, 149, 94, 36, 37, 38, 95, 96, 150, 45, 46, 47, 176, 177, 178, 152, 146, 147, 124, 123, 179, 70, 71, 72, 142, 86, 87, 133, 134, 135, 136, 29, 30, 31, 187, 188, 189, 190, 191, 192, 193, 194, 195, 198, 199, 200, 196, 197, 201, 202, 151}; -const u16 gSpeciesToNationalPokedexNum[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 290, 291, 292, 276, 277, 285, 286, 327, 278, 279, 283, 284, 320, 321, 300, 301, 352, 343, 344, 299, 324, 302, 339, 340, 370, 341, 342, 349, 350, 318, 319, 328, 329, 330, 296, 297, 309, 310, 322, 323, 363, 364, 365, 331, 332, 361, 362, 337, 338, 298, 325, 326, 311, 312, 303, 307, 308, 333, 334, 360, 355, 356, 315, 287, 288, 289, 316, 317, 357, 293, 294, 295, 366, 367, 368, 359, 353, 354, 336, 335, 369, 304, 305, 306, 351, 313, 314, 345, 346, 347, 348, 280, 281, 282, 371, 372, 373, 374, 375, 376, 377, 378, 379, 382, 383, 384, 380, 381, 385, 386, 358}; -const u16 gHoennToNationalOrder[] = {252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 63, 64, 65, 290, 291, 292, 293, 294, 295, 296, 297, 118, 119, 129, 130, 298, 183, 184, 74, 75, 76, 299, 300, 301, 41, 42, 169, 72, 73, 302, 303, 304, 305, 306, 66, 67, 68, 307, 308, 309, 310, 311, 312, 81, 82, 100, 101, 313, 314, 43, 44, 45, 182, 84, 85, 315, 316, 317, 318, 319, 320, 321, 322, 323, 218, 219, 324, 88, 89, 109, 110, 325, 326, 27, 28, 327, 227, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 174, 39, 40, 349, 350, 351, 120, 121, 352, 353, 354, 355, 356, 357, 358, 359, 37, 38, 172, 25, 26, 54, 55, 360, 202, 177, 178, 203, 231, 232, 127, 214, 111, 112, 361, 362, 363, 364, 365, 366, 367, 368, 369, 222, 170, 171, 370, 116, 117, 230, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 34, 35, 36, 46, 47, 48, 49, 50, 51, 52, 53, 56, 57, 58, 59, 60, 61, 62, 69, 70, 71, 77, 78, 79, 80, 83, 86, 87, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 102, 103, 104, 105, 106, 107, 108, 113, 114, 115, 122, 123, 124, 125, 126, 128, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 173, 175, 176, 179, 180, 181, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 215, 216, 217, 220, 221, 223, 224, 225, 226, 228, 229, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411}; - -const struct SpindaSpot gSpindaSpotGraphics[] = -{ - {16, 7, INCBIN_U16("graphics/spinda_spots/spot_0.bin")}, - {40, 8, INCBIN_U16("graphics/spinda_spots/spot_1.bin")}, - {22, 25, INCBIN_U16("graphics/spinda_spots/spot_2.bin")}, - {34, 26, INCBIN_U16("graphics/spinda_spots/spot_3.bin")} -}; - -#include "data/pokemon/item_effects.h" - -const s8 gNatureStatTable[][5] = -{ - // Atk Def Spd Sp.Atk Sp.Def - { 0, 0, 0, 0, 0}, // Hardy - { +1, -1, 0, 0, 0}, // Lonely - { +1, 0, -1, 0, 0}, // Brave - { +1, 0, 0, -1, 0}, // Adamant - { +1, 0, 0, 0, -1}, // Naughty - { -1, +1, 0, 0, 0}, // Bold - { 0, 0, 0, 0, 0}, // Docile - { 0, +1, -1, 0, 0}, // Relaxed - { 0, +1, 0, -1, 0}, // Impish - { 0, +1, 0, 0, -1}, // Lax - { -1, 0, +1, 0, 0}, // Timid - { 0, -1, +1, 0, 0}, // Hasty - { 0, 0, 0, 0, 0}, // Serious - { 0, 0, +1, -1, 0}, // Jolly - { 0, 0, +1, 0, -1}, // Naive - { -1, 0, 0, +1, 0}, // Modest - { 0, -1, 0, +1, 0}, // Mild - { 0, 0, -1, +1, 0}, // Quiet - { 0, 0, 0, 0, 0}, // Bashful - { 0, 0, 0, +1, -1}, // Rash - { -1, 0, 0, 0, +1}, // Calm - { 0, -1, 0, 0, +1}, // Gentle - { 0, 0, -1, 0, +1}, // Sassy - { 0, 0, 0, -1, +1}, // Careful - { 0, 0, 0, 0, 0}, // Quirky -}; - -#include "data/pokemon/tmhm_learnsets.h" -#include "data/pokemon/trainer_class_lookups.h" -#include "data/pokemon/cry_ids.h" -#include "data/pokemon/experience_tables.h" -#include "data/pokemon/base_stats.h" -#include "data/pokemon/level_up_learnsets.h" -#include "data/pokemon/evolution.h" -#include "data/pokemon/level_up_learnset_pointers.h" - -// code -void ZeroBoxMonData(struct BoxPokemon *boxMon) -{ - u8 *raw = (u8 *)boxMon; - u32 i; - for (i = 0; i < sizeof(struct BoxPokemon); i++) - raw[i] = 0; -} - -void ZeroMonData(struct Pokemon *mon) -{ - u32 arg; - ZeroBoxMonData(&mon->box); - arg = 0; - SetMonData(mon, MON_DATA_STATUS, &arg); - SetMonData(mon, MON_DATA_LEVEL, &arg); - SetMonData(mon, MON_DATA_HP, &arg); - SetMonData(mon, MON_DATA_MAX_HP, &arg); - SetMonData(mon, MON_DATA_ATK, &arg); - SetMonData(mon, MON_DATA_DEF, &arg); - SetMonData(mon, MON_DATA_SPEED, &arg); - SetMonData(mon, MON_DATA_SPATK, &arg); - SetMonData(mon, MON_DATA_SPDEF, &arg); - arg = 255; - SetMonData(mon, MON_DATA_MAIL, &arg); -} - -void ZeroPlayerPartyMons(void) -{ - s32 i; - for (i = 0; i < PARTY_SIZE; i++) - ZeroMonData(&gPlayerParty[i]); -} - -void ZeroEnemyPartyMons(void) -{ - s32 i; - for (i = 0; i < PARTY_SIZE; i++) - ZeroMonData(&gEnemyParty[i]); -} - -void CreateMon(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 hasFixedPersonality, u32 fixedPersonality, u8 otIdType, u32 fixedOtId) -{ - u32 arg; - ZeroMonData(mon); - CreateBoxMon(&mon->box, species, level, fixedIV, hasFixedPersonality, fixedPersonality, otIdType, fixedOtId); - SetMonData(mon, MON_DATA_LEVEL, &level); - arg = 255; - SetMonData(mon, MON_DATA_MAIL, &arg); - CalculateMonStats(mon); -} - -void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV, u8 hasFixedPersonality, u32 fixedPersonality, u8 otIdType, u32 fixedOtId) -{ - u8 speciesName[POKEMON_NAME_LENGTH + 1]; - u32 personality; - u32 value; - u16 checksum; - - ZeroBoxMonData(boxMon); - - if (hasFixedPersonality) - personality = fixedPersonality; - else - personality = Random32(); - - SetBoxMonData(boxMon, MON_DATA_PERSONALITY, &personality); - - //Determine original trainer ID - if (otIdType == OT_ID_RANDOM_NO_SHINY) //Pokemon cannot be shiny - { - u32 shinyValue; - do - { - value = Random32(); - shinyValue = HIHALF(value) ^ LOHALF(value) ^ HIHALF(personality) ^ LOHALF(personality); - } while (shinyValue < 8); - } - else if (otIdType == OT_ID_PRESET) //Pokemon has a preset OT ID - { - value = fixedOtId; - } - else //Player is the OT - { - value = gSaveBlock2Ptr->playerTrainerId[0] - | (gSaveBlock2Ptr->playerTrainerId[1] << 8) - | (gSaveBlock2Ptr->playerTrainerId[2] << 16) - | (gSaveBlock2Ptr->playerTrainerId[3] << 24); - } - - SetBoxMonData(boxMon, MON_DATA_OT_ID, &value); - - checksum = CalculateBoxMonChecksum(boxMon); - SetBoxMonData(boxMon, MON_DATA_CHECKSUM, &checksum); - EncryptBoxMon(boxMon); - GetSpeciesName(speciesName, species); - SetBoxMonData(boxMon, MON_DATA_NICKNAME, speciesName); - SetBoxMonData(boxMon, MON_DATA_LANGUAGE, &gGameLanguage); - SetBoxMonData(boxMon, MON_DATA_OT_NAME, gSaveBlock2Ptr->playerName); - SetBoxMonData(boxMon, MON_DATA_SPECIES, &species); - SetBoxMonData(boxMon, MON_DATA_EXP, &gExperienceTables[gBaseStats[species].growthRate][level]); - SetBoxMonData(boxMon, MON_DATA_FRIENDSHIP, &gBaseStats[species].friendship); - value = sav1_map_get_name(); - SetBoxMonData(boxMon, MON_DATA_MET_LOCATION, &value); - SetBoxMonData(boxMon, MON_DATA_MET_LEVEL, &level); - SetBoxMonData(boxMon, MON_DATA_MET_GAME, &gGameVersion); - value = ITEM_POKE_BALL; - SetBoxMonData(boxMon, MON_DATA_POKEBALL, &value); - SetBoxMonData(boxMon, MON_DATA_OT_GENDER, &gSaveBlock2Ptr->playerGender); - - if (fixedIV < 32) - { - SetBoxMonData(boxMon, MON_DATA_HP_IV, &fixedIV); - SetBoxMonData(boxMon, MON_DATA_ATK_IV, &fixedIV); - SetBoxMonData(boxMon, MON_DATA_DEF_IV, &fixedIV); - SetBoxMonData(boxMon, MON_DATA_SPEED_IV, &fixedIV); - SetBoxMonData(boxMon, MON_DATA_SPATK_IV, &fixedIV); - SetBoxMonData(boxMon, MON_DATA_SPDEF_IV, &fixedIV); - } - else - { - u32 iv; - value = Random(); - - iv = value & 0x1F; - SetBoxMonData(boxMon, MON_DATA_HP_IV, &iv); - iv = (value & 0x3E0) >> 5; - SetBoxMonData(boxMon, MON_DATA_ATK_IV, &iv); - iv = (value & 0x7C00) >> 10; - SetBoxMonData(boxMon, MON_DATA_DEF_IV, &iv); - - value = Random(); - - iv = value & 0x1F; - SetBoxMonData(boxMon, MON_DATA_SPEED_IV, &iv); - iv = (value & 0x3E0) >> 5; - SetBoxMonData(boxMon, MON_DATA_SPATK_IV, &iv); - iv = (value & 0x7C00) >> 10; - SetBoxMonData(boxMon, MON_DATA_SPDEF_IV, &iv); - } - - if (gBaseStats[species].ability2) - { - value = personality & 1; - SetBoxMonData(boxMon, MON_DATA_ALT_ABILITY, &value); - } - - GiveBoxMonInitialMoveset(boxMon); -} - -void CreateMonWithNature(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 nature) -{ - u32 personality; - - do - { - personality = Random32(); - } - while (nature != GetNatureFromPersonality(personality)); - - CreateMon(mon, species, level, fixedIV, 1, personality, OT_ID_PLAYER_ID, 0); -} - -void CreateMonWithGenderNatureLetter(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 gender, u8 nature, u8 unownLetter) -{ - u32 personality; - - if ((u8)(unownLetter - 1) < 28) - { - u16 actualLetter; - - do - { - personality = Random32(); - actualLetter = ((((personality & 0x3000000) >> 18) | ((personality & 0x30000) >> 12) | ((personality & 0x300) >> 6) | (personality & 0x3)) % 28); - } - while (nature != GetNatureFromPersonality(personality) - || gender != GetGenderFromSpeciesAndPersonality(species, personality) - || actualLetter != unownLetter - 1); - } - else - { - do - { - personality = Random32(); - } - while (nature != GetNatureFromPersonality(personality) - || gender != GetGenderFromSpeciesAndPersonality(species, personality)); - } - - CreateMon(mon, species, level, fixedIV, 1, personality, OT_ID_PLAYER_ID, 0); -} - -// This is only used to create Wally's Ralts. -void CreateMaleMon(struct Pokemon *mon, u16 species, u8 level) -{ - u32 personality; - u32 otId; - - do - { - otId = Random32(); - personality = Random32(); - } - while (GetGenderFromSpeciesAndPersonality(species, personality) != MON_MALE); - CreateMon(mon, species, level, 32, 1, personality, OT_ID_PRESET, otId); -} - -void CreateMonWithIVsPersonality(struct Pokemon *mon, u16 species, u8 level, u32 ivs, u32 personality) -{ - CreateMon(mon, species, level, 0, 1, personality, OT_ID_PLAYER_ID, 0); - SetMonData(mon, MON_DATA_IVS, &ivs); - CalculateMonStats(mon); -} - -void CreateMonWithIVsOTID(struct Pokemon *mon, u16 species, u8 level, u8 *ivs, u32 otId) -{ - CreateMon(mon, species, level, 0, 0, 0, OT_ID_PRESET, otId); - SetMonData(mon, MON_DATA_HP_IV, &ivs[0]); - SetMonData(mon, MON_DATA_ATK_IV, &ivs[1]); - SetMonData(mon, MON_DATA_DEF_IV, &ivs[2]); - SetMonData(mon, MON_DATA_SPEED_IV, &ivs[3]); - SetMonData(mon, MON_DATA_SPATK_IV, &ivs[4]); - SetMonData(mon, MON_DATA_SPDEF_IV, &ivs[5]); - CalculateMonStats(mon); -} - -void CreateMonWithEVSpread(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 evSpread) -{ - s32 i; - s32 statCount = 0; - u16 evAmount; - u8 temp; - - CreateMon(mon, species, level, fixedIV, 0, 0, 0, 0); - - temp = evSpread; - - for (i = 0; i < 6; i++) - { - if (temp & 1) - statCount++; - temp >>= 1; - } - - evAmount = 510 / statCount; - - temp = 1; - - for (i = 0; i < 6; i++) - { - if (evSpread & temp) - SetMonData(mon, MON_DATA_HP_EV + i, &evAmount); - temp <<= 1; - } - - CalculateMonStats(mon); -} - -void sub_806819C(struct Pokemon *mon, struct UnknownPokemonStruct *src) -{ - s32 i; - u8 nickname[30]; - u8 language; - u8 value; - - CreateMon(mon, src->species, src->level, 0, 1, src->personality, 1, src->otId); - - for (i = 0; i < 4; i++) - SetMonMoveSlot(mon, src->moves[i], i); - - SetMonData(mon, MON_DATA_PP_BONUSES, &src->ppBonuses); - SetMonData(mon, MON_DATA_HELD_ITEM, &src->heldItem); - SetMonData(mon, MON_DATA_FRIENDSHIP, &src->friendship); - - StringCopy(nickname, src->nickname); - - if (nickname[0] == EXT_CTRL_CODE_BEGIN && nickname[1] == EXT_CTRL_CODE_JPN) - { - language = LANGUAGE_JAPANESE; - StripExtCtrlCodes(nickname); - } - else - { - language = GAME_LANGUAGE; - } - - SetMonData(mon, MON_DATA_LANGUAGE, &language); - SetMonData(mon, MON_DATA_NICKNAME, nickname); - SetMonData(mon, MON_DATA_HP_EV, &src->hpEV); - SetMonData(mon, MON_DATA_ATK_EV, &src->attackEV); - SetMonData(mon, MON_DATA_DEF_EV, &src->defenseEV); - SetMonData(mon, MON_DATA_SPEED_EV, &src->speedEV); - SetMonData(mon, MON_DATA_SPATK_EV, &src->spAttackEV); - SetMonData(mon, MON_DATA_SPDEF_EV, &src->spDefenseEV); - value = src->altAbility; - SetMonData(mon, MON_DATA_ALT_ABILITY, &value); - value = src->hpIV; - SetMonData(mon, MON_DATA_HP_IV, &value); - value = src->attackIV; - SetMonData(mon, MON_DATA_ATK_IV, &value); - value = src->defenseIV; - SetMonData(mon, MON_DATA_DEF_IV, &value); - value = src->speedIV; - SetMonData(mon, MON_DATA_SPEED_IV, &value); - value = src->spAttackIV; - SetMonData(mon, MON_DATA_SPATK_IV, &value); - value = src->spDefenseIV; - SetMonData(mon, MON_DATA_SPDEF_IV, &value); - MonRestorePP(mon); - CalculateMonStats(mon); -} - -u8 BattleFrontierGetOpponentLvl(u8); - -void sub_8068338(struct Pokemon *mon, struct UnknownPokemonStruct *src, bool8 lvl50) -{ - s32 i; - u8 nickname[30]; - u8 level; - u8 language; - u8 value; - - if (gSaveBlock2Ptr->frontierChosenLvl != 0) - level = BattleFrontierGetOpponentLvl(gSaveBlock2Ptr->frontierChosenLvl); - else if (lvl50) - level = 50; - else - level = src->level; - - CreateMon(mon, src->species, level, 0, 1, src->personality, 1, src->otId); - - for (i = 0; i < 4; i++) - SetMonMoveSlot(mon, src->moves[i], i); - - SetMonData(mon, MON_DATA_PP_BONUSES, &src->ppBonuses); - SetMonData(mon, MON_DATA_HELD_ITEM, &src->heldItem); - SetMonData(mon, MON_DATA_FRIENDSHIP, &src->friendship); - - StringCopy(nickname, src->nickname); - - if (nickname[0] == EXT_CTRL_CODE_BEGIN && nickname[1] == EXT_CTRL_CODE_JPN) - { - language = LANGUAGE_JAPANESE; - StripExtCtrlCodes(nickname); - } - else - { - language = GAME_LANGUAGE; - } - - SetMonData(mon, MON_DATA_LANGUAGE, &language); - SetMonData(mon, MON_DATA_NICKNAME, nickname); - SetMonData(mon, MON_DATA_HP_EV, &src->hpEV); - SetMonData(mon, MON_DATA_ATK_EV, &src->attackEV); - SetMonData(mon, MON_DATA_DEF_EV, &src->defenseEV); - SetMonData(mon, MON_DATA_SPEED_EV, &src->speedEV); - SetMonData(mon, MON_DATA_SPATK_EV, &src->spAttackEV); - SetMonData(mon, MON_DATA_SPDEF_EV, &src->spDefenseEV); - value = src->altAbility; - SetMonData(mon, MON_DATA_ALT_ABILITY, &value); - value = src->hpIV; - SetMonData(mon, MON_DATA_HP_IV, &value); - value = src->attackIV; - SetMonData(mon, MON_DATA_ATK_IV, &value); - value = src->defenseIV; - SetMonData(mon, MON_DATA_DEF_IV, &value); - value = src->speedIV; - SetMonData(mon, MON_DATA_SPEED_IV, &value); - value = src->spAttackIV; - SetMonData(mon, MON_DATA_SPATK_IV, &value); - value = src->spDefenseIV; - SetMonData(mon, MON_DATA_SPDEF_IV, &value); - MonRestorePP(mon); - CalculateMonStats(mon); -} diff --git a/src/pokemon_2.c b/src/pokemon_2.c deleted file mode 100644 index 28cecbb0b..000000000 --- a/src/pokemon_2.c +++ /dev/null @@ -1,1365 +0,0 @@ -#include "global.h" -#include "pokemon.h" -#include "battle.h" -#include "event_data.h" -#include "random.h" -#include "sprite.h" -#include "constants/species.h" -#include "text.h" -#include "string_util.h" - -struct Unknown_020249B4 -{ - u8 unk0[0xC]; - struct SpriteTemplate* templates; -}; - -extern u8 gAbsentBattlerFlags; -extern u8 gActiveBattler; -extern u8 gBattlerAttacker; -extern u8 gBattlerTarget; -extern u8 gLastUsedAbility; -extern u16 gTrainerBattleOpponent_A; -extern u32 gBattleTypeFlags; -extern struct SpriteTemplate gUnknown_0202499C; -extern struct Unknown_020249B4* gUnknown_020249B4[2]; - -extern const u32 gBitTable[]; -extern const struct SpriteTemplate gUnknown_08329D98[]; -extern const struct SpriteTemplate gUnknown_08329DF8[]; -extern const union AnimCmd* gUnknown_082FF70C[]; -extern const union AnimCmd* const * const gMonAnimationsSpriteAnimsPtrTable[]; -extern const union AnimCmd* const * const gUnknown_08305D0C[]; -extern const union AnimCmd* const * const gUnknown_0830536C[]; -extern const u8 gText_BadEgg[]; -extern const u8 gText_EggNickname[]; - -extern u8 GetBattlerSide(u8 bank); -extern u8 GetBattlerAtPosition(u8 bank); -extern u8 GetBattlerPosition(u8 bank); - -u8 CountAliveMonsInBattle(u8 caseId) -{ - s32 i; - u8 retVal = 0; - - switch (caseId) - { - case BATTLE_ALIVE_EXCEPT_ACTIVE: - for (i = 0; i < 4; i++) - { - if (i != gActiveBattler && !(gAbsentBattlerFlags & gBitTable[i])) - retVal++; - } - break; - case BATTLE_ALIVE_ATK_SIDE: - for (i = 0; i < 4; i++) - { - if (GetBattlerSide(i) == GetBattlerSide(gBattlerAttacker) && !(gAbsentBattlerFlags & gBitTable[i])) - retVal++; - } - break; - case BATTLE_ALIVE_DEF_SIDE: - for (i = 0; i < 4; i++) - { - if (GetBattlerSide(i) == GetBattlerSide(gBattlerTarget) && !(gAbsentBattlerFlags & gBitTable[i])) - retVal++; - } - break; - } - - return retVal; -} - -bool8 ShouldGetStatBadgeBoost(u16 badgeFlag, u8 bank) -{ - if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_x2000000 | BATTLE_TYPE_FRONTIER)) - return FALSE; - if (GetBattlerSide(bank) != B_SIDE_PLAYER) - return FALSE; - if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && gTrainerBattleOpponent_A == SECRET_BASE_OPPONENT) - return FALSE; - if (FlagGet(badgeFlag)) - return TRUE; - return FALSE; -} - -u8 GetDefaultMoveTarget(u8 bank) -{ - u8 status = GetBattlerPosition(bank) & 1; - - status ^= 1; - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - return GetBattlerAtPosition(status); - if (CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_ACTIVE) > 1) - { - u8 val; - - if ((Random() & 1) == 0) - val = status ^ 2; - else - val = status; - return GetBattlerAtPosition(val); - } - else - { - if ((gAbsentBattlerFlags & gBitTable[status])) - return GetBattlerAtPosition(status ^ 2); - else - return GetBattlerAtPosition(status); - } -} - -u8 GetMonGender(struct Pokemon *mon) -{ - return GetBoxMonGender(&mon->box); -} - -u8 GetBoxMonGender(struct BoxPokemon *boxMon) -{ - u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL); - u32 personality = GetBoxMonData(boxMon, MON_DATA_PERSONALITY, NULL); - - switch (gBaseStats[species].genderRatio) - { - case MON_MALE: - case MON_FEMALE: - case MON_GENDERLESS: - return gBaseStats[species].genderRatio; - } - - if (gBaseStats[species].genderRatio > (personality & 0xFF)) - return MON_FEMALE; - else - return MON_MALE; -} - -u8 GetGenderFromSpeciesAndPersonality(u16 species, u32 personality) -{ - switch (gBaseStats[species].genderRatio) - { - case MON_MALE: - case MON_FEMALE: - case MON_GENDERLESS: - return gBaseStats[species].genderRatio; - } - - if (gBaseStats[species].genderRatio > (personality & 0xFF)) - return MON_FEMALE; - else - return MON_MALE; -} - -void sub_806A068(u16 species, u8 bankIdentity) -{ - if (gMonSpritesGfxPtr != NULL) - gUnknown_0202499C = gMonSpritesGfxPtr->templates[bankIdentity]; - else if (gUnknown_020249B4[0]) - gUnknown_0202499C = gUnknown_020249B4[0]->templates[bankIdentity]; - else if (gUnknown_020249B4[1]) - gUnknown_0202499C = gUnknown_020249B4[1]->templates[bankIdentity]; - else - gUnknown_0202499C = gUnknown_08329D98[bankIdentity]; - - gUnknown_0202499C.paletteTag = species; - if (bankIdentity == 0 || bankIdentity == 2) - gUnknown_0202499C.anims = gUnknown_082FF70C; - else if (species > 500) - gUnknown_0202499C.anims = gMonAnimationsSpriteAnimsPtrTable[species - 500]; - else - gUnknown_0202499C.anims = gMonAnimationsSpriteAnimsPtrTable[species]; -} - -void sub_806A12C(u16 trainerSpriteId, u8 bankIdentity) -{ - gUnknown_0202499C.paletteTag = trainerSpriteId; - if (bankIdentity == 0 || bankIdentity == 2) - { - gUnknown_0202499C = gUnknown_08329DF8[trainerSpriteId]; - gUnknown_0202499C.anims = gUnknown_08305D0C[trainerSpriteId]; - } - else - { - if (gMonSpritesGfxPtr != NULL) - gUnknown_0202499C = gMonSpritesGfxPtr->templates[bankIdentity]; - else - gUnknown_0202499C = gUnknown_08329D98[bankIdentity]; - gUnknown_0202499C.anims = gUnknown_0830536C[trainerSpriteId]; - } -} - -void sub_806A1C0(u16 arg0, u8 bankIdentity) -{ - if (gMonSpritesGfxPtr != NULL) - gUnknown_0202499C = gMonSpritesGfxPtr->templates[bankIdentity]; - else - gUnknown_0202499C = gUnknown_08329D98[bankIdentity]; - - gUnknown_0202499C.paletteTag = arg0; - gUnknown_0202499C.anims = gUnknown_0830536C[arg0]; -} - -void EncryptBoxMon(struct BoxPokemon *boxMon) -{ - u32 i; - for (i = 0; i < 12; i++) - { - boxMon->secure.raw[i] ^= boxMon->personality; - boxMon->secure.raw[i] ^= boxMon->otId; - } -} - -void DecryptBoxMon(struct BoxPokemon *boxMon) -{ - u32 i; - for (i = 0; i < 12; i++) - { - boxMon->secure.raw[i] ^= boxMon->otId; - boxMon->secure.raw[i] ^= boxMon->personality; - } -} - -#define SUBSTRUCT_CASE(n, v1, v2, v3, v4) \ -case n: \ - { \ - union PokemonSubstruct *substructs0 = boxMon->secure.substructs; \ - union PokemonSubstruct *substructs1 = boxMon->secure.substructs; \ - union PokemonSubstruct *substructs2 = boxMon->secure.substructs; \ - union PokemonSubstruct *substructs3 = boxMon->secure.substructs; \ - union PokemonSubstruct *substructs4 = boxMon->secure.substructs; \ - union PokemonSubstruct *substructs5 = boxMon->secure.substructs; \ - union PokemonSubstruct *substructs6 = boxMon->secure.substructs; \ - union PokemonSubstruct *substructs7 = boxMon->secure.substructs; \ - union PokemonSubstruct *substructs8 = boxMon->secure.substructs; \ - union PokemonSubstruct *substructs9 = boxMon->secure.substructs; \ - union PokemonSubstruct *substructs10 = boxMon->secure.substructs; \ - union PokemonSubstruct *substructs11 = boxMon->secure.substructs; \ - union PokemonSubstruct *substructs12 = boxMon->secure.substructs; \ - union PokemonSubstruct *substructs13 = boxMon->secure.substructs; \ - union PokemonSubstruct *substructs14 = boxMon->secure.substructs; \ - union PokemonSubstruct *substructs15 = boxMon->secure.substructs; \ - union PokemonSubstruct *substructs16 = boxMon->secure.substructs; \ - union PokemonSubstruct *substructs17 = boxMon->secure.substructs; \ - union PokemonSubstruct *substructs18 = boxMon->secure.substructs; \ - union PokemonSubstruct *substructs19 = boxMon->secure.substructs; \ - union PokemonSubstruct *substructs20 = boxMon->secure.substructs; \ - union PokemonSubstruct *substructs21 = boxMon->secure.substructs; \ - union PokemonSubstruct *substructs22 = boxMon->secure.substructs; \ - union PokemonSubstruct *substructs23 = boxMon->secure.substructs; \ - \ - switch (substructType) \ - { \ - case 0: \ - substruct = &substructs ## n [v1]; \ - break; \ - case 1: \ - substruct = &substructs ## n [v2]; \ - break; \ - case 2: \ - substruct = &substructs ## n [v3]; \ - break; \ - case 3: \ - substruct = &substructs ## n [v4]; \ - break; \ - } \ - break; \ - } \ - - -union PokemonSubstruct *GetSubstruct(struct BoxPokemon *boxMon, u32 personality, u8 substructType) -{ - union PokemonSubstruct *substruct = NULL; - - switch (personality % 24) - { - SUBSTRUCT_CASE( 0,0,1,2,3) - SUBSTRUCT_CASE( 1,0,1,3,2) - SUBSTRUCT_CASE( 2,0,2,1,3) - SUBSTRUCT_CASE( 3,0,3,1,2) - SUBSTRUCT_CASE( 4,0,2,3,1) - SUBSTRUCT_CASE( 5,0,3,2,1) - SUBSTRUCT_CASE( 6,1,0,2,3) - SUBSTRUCT_CASE( 7,1,0,3,2) - SUBSTRUCT_CASE( 8,2,0,1,3) - SUBSTRUCT_CASE( 9,3,0,1,2) - SUBSTRUCT_CASE(10,2,0,3,1) - SUBSTRUCT_CASE(11,3,0,2,1) - SUBSTRUCT_CASE(12,1,2,0,3) - SUBSTRUCT_CASE(13,1,3,0,2) - SUBSTRUCT_CASE(14,2,1,0,3) - SUBSTRUCT_CASE(15,3,1,0,2) - SUBSTRUCT_CASE(16,2,3,0,1) - SUBSTRUCT_CASE(17,3,2,0,1) - SUBSTRUCT_CASE(18,1,2,3,0) - SUBSTRUCT_CASE(19,1,3,2,0) - SUBSTRUCT_CASE(20,2,1,3,0) - SUBSTRUCT_CASE(21,3,1,2,0) - SUBSTRUCT_CASE(22,2,3,1,0) - SUBSTRUCT_CASE(23,3,2,1,0) - } - - return substruct; -} - -extern u16 GetDeoxysStat(struct Pokemon *mon, s32 statId); - -u32 GetMonData(struct Pokemon *mon, s32 field, u8* data) -{ - u32 ret; - - switch (field) - { - case MON_DATA_STATUS: - ret = mon->status; - break; - case MON_DATA_LEVEL: - ret = mon->level; - break; - case MON_DATA_HP: - ret = mon->hp; - break; - case MON_DATA_MAX_HP: - ret = mon->maxHP; - break; - case MON_DATA_ATK: - ret = GetDeoxysStat(mon, STAT_ATK); - if (!ret) - ret = mon->attack; - break; - case MON_DATA_DEF: - ret = GetDeoxysStat(mon, STAT_DEF); - if (!ret) - ret = mon->defense; - break; - case MON_DATA_SPEED: - ret = GetDeoxysStat(mon, STAT_SPD); - if (!ret) - ret = mon->speed; - break; - case MON_DATA_SPATK: - ret = GetDeoxysStat(mon, STAT_SPATK); - if (!ret) - ret = mon->spAttack; - break; - case MON_DATA_SPDEF: - ret = GetDeoxysStat(mon, STAT_SPDEF); - if (!ret) - ret = mon->spDefense; - break; - case MON_DATA_ATK2: - ret = mon->attack; - break; - case MON_DATA_DEF2: - ret = mon->defense; - break; - case MON_DATA_SPEED2: - ret = mon->speed; - break; - case MON_DATA_SPATK2: - ret = mon->spAttack; - break; - case MON_DATA_SPDEF2: - ret = mon->spDefense; - break; - case MON_DATA_MAIL: - ret = mon->mail; - break; - default: - ret = GetBoxMonData(&mon->box, field, data); - break; - } - return ret; -} - -u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data) -{ - s32 i; - u32 retVal = 0; - struct PokemonSubstruct0 *substruct0 = NULL; - struct PokemonSubstruct1 *substruct1 = NULL; - struct PokemonSubstruct2 *substruct2 = NULL; - struct PokemonSubstruct3 *substruct3 = NULL; - - if (field > MON_DATA_10) - { - substruct0 = &(GetSubstruct(boxMon, boxMon->personality, 0)->type0); - substruct1 = &(GetSubstruct(boxMon, boxMon->personality, 1)->type1); - substruct2 = &(GetSubstruct(boxMon, boxMon->personality, 2)->type2); - substruct3 = &(GetSubstruct(boxMon, boxMon->personality, 3)->type3); - - DecryptBoxMon(boxMon); - - if (CalculateBoxMonChecksum(boxMon) != boxMon->checksum) - { - boxMon->isBadEgg = 1; - boxMon->isEgg = 1; - substruct3->isEgg = 1; - } - } - - switch (field) - { - case MON_DATA_PERSONALITY: - retVal = boxMon->personality; - break; - case MON_DATA_OT_ID: - retVal = boxMon->otId; - break; - case MON_DATA_NICKNAME: - { - if (boxMon->isBadEgg) - { - for (retVal = 0; - retVal < POKEMON_NAME_LENGTH && gText_BadEgg[retVal] != EOS; - data[retVal] = gText_BadEgg[retVal], retVal++) {} - - data[retVal] = EOS; - } - else if (boxMon->isEgg) - { - StringCopy(data, gText_EggNickname); - retVal = StringLength(data); - } - else if (boxMon->language == LANGUAGE_JAPANESE) - { - data[0] = EXT_CTRL_CODE_BEGIN; - data[1] = EXT_CTRL_CODE_JPN; - - for (retVal = 2, i = 0; - i < 5 && boxMon->nickname[i] != EOS; - data[retVal] = boxMon->nickname[i], retVal++, i++) {} - - data[retVal++] = EXT_CTRL_CODE_BEGIN; - data[retVal++] = EXT_CTRL_CODE_ENG; - data[retVal] = EOS; - } - else - { - for (retVal = 0; - retVal < POKEMON_NAME_LENGTH; - data[retVal] = boxMon->nickname[retVal], retVal++){} - - data[retVal] = EOS; - } - break; - } - case MON_DATA_LANGUAGE: - retVal = boxMon->language; - break; - case MON_DATA_SANITY_BIT1: - retVal = boxMon->isBadEgg; - break; - case MON_DATA_SANITY_BIT2: - retVal = boxMon->hasSpecies; - break; - case MON_DATA_SANITY_BIT3: - retVal = boxMon->isEgg; - break; - case MON_DATA_OT_NAME: - { - retVal = 0; - - while (retVal < OT_NAME_LENGTH) - { - data[retVal] = boxMon->otName[retVal]; - retVal++; - } - - data[retVal] = EOS; - break; - } - case MON_DATA_MARKINGS: - retVal = boxMon->markings; - break; - case MON_DATA_CHECKSUM: - retVal = boxMon->checksum; - break; - case MON_DATA_10: - retVal = boxMon->unknown; - break; - case MON_DATA_SPECIES: - retVal = boxMon->isBadEgg ? SPECIES_EGG : substruct0->species; - break; - case MON_DATA_HELD_ITEM: - retVal = substruct0->heldItem; - break; - case MON_DATA_EXP: - retVal = substruct0->experience; - break; - case MON_DATA_PP_BONUSES: - retVal = substruct0->ppBonuses; - break; - case MON_DATA_FRIENDSHIP: - retVal = substruct0->friendship; - break; - case MON_DATA_MOVE1: - case MON_DATA_MOVE2: - case MON_DATA_MOVE3: - case MON_DATA_MOVE4: - retVal = substruct1->moves[field - MON_DATA_MOVE1]; - break; - case MON_DATA_PP1: - case MON_DATA_PP2: - case MON_DATA_PP3: - case MON_DATA_PP4: - retVal = substruct1->pp[field - MON_DATA_PP1]; - break; - case MON_DATA_HP_EV: - retVal = substruct2->hpEV; - break; - case MON_DATA_ATK_EV: - retVal = substruct2->attackEV; - break; - case MON_DATA_DEF_EV: - retVal = substruct2->defenseEV; - break; - case MON_DATA_SPEED_EV: - retVal = substruct2->speedEV; - break; - case MON_DATA_SPATK_EV: - retVal = substruct2->spAttackEV; - break; - case MON_DATA_SPDEF_EV: - retVal = substruct2->spDefenseEV; - break; - case MON_DATA_COOL: - retVal = substruct2->cool; - break; - case MON_DATA_BEAUTY: - retVal = substruct2->beauty; - break; - case MON_DATA_CUTE: - retVal = substruct2->cute; - break; - case MON_DATA_SMART: - retVal = substruct2->smart; - break; - case MON_DATA_TOUGH: - retVal = substruct2->tough; - break; - case MON_DATA_SHEEN: - retVal = substruct2->sheen; - break; - case MON_DATA_POKERUS: - retVal = substruct3->pokerus; - break; - case MON_DATA_MET_LOCATION: - retVal = substruct3->metLocation; - break; - case MON_DATA_MET_LEVEL: - retVal = substruct3->metLevel; - break; - case MON_DATA_MET_GAME: - retVal = substruct3->metGame; - break; - case MON_DATA_POKEBALL: - retVal = substruct3->pokeball; - break; - case MON_DATA_OT_GENDER: - retVal = substruct3->otGender; - break; - case MON_DATA_HP_IV: - retVal = substruct3->hpIV; - break; - case MON_DATA_ATK_IV: - retVal = substruct3->attackIV; - break; - case MON_DATA_DEF_IV: - retVal = substruct3->defenseIV; - break; - case MON_DATA_SPEED_IV: - retVal = substruct3->speedIV; - break; - case MON_DATA_SPATK_IV: - retVal = substruct3->spAttackIV; - break; - case MON_DATA_SPDEF_IV: - retVal = substruct3->spDefenseIV; - break; - case MON_DATA_IS_EGG: - retVal = substruct3->isEgg; - break; - case MON_DATA_ALT_ABILITY: - retVal = substruct3->altAbility; - break; - case MON_DATA_COOL_RIBBON: - retVal = substruct3->coolRibbon; - break; - case MON_DATA_BEAUTY_RIBBON: - retVal = substruct3->beautyRibbon; - break; - case MON_DATA_CUTE_RIBBON: - retVal = substruct3->cuteRibbon; - break; - case MON_DATA_SMART_RIBBON: - retVal = substruct3->smartRibbon; - break; - case MON_DATA_TOUGH_RIBBON: - retVal = substruct3->toughRibbon; - break; - case MON_DATA_CHAMPION_RIBBON: - retVal = substruct3->championRibbon; - break; - case MON_DATA_WINNING_RIBBON: - retVal = substruct3->winningRibbon; - break; - case MON_DATA_VICTORY_RIBBON: - retVal = substruct3->victoryRibbon; - break; - case MON_DATA_ARTIST_RIBBON: - retVal = substruct3->artistRibbon; - break; - case MON_DATA_EFFORT_RIBBON: - retVal = substruct3->effortRibbon; - break; - case MON_DATA_GIFT_RIBBON_1: - retVal = substruct3->giftRibbon1; - break; - case MON_DATA_GIFT_RIBBON_2: - retVal = substruct3->giftRibbon2; - break; - case MON_DATA_GIFT_RIBBON_3: - retVal = substruct3->giftRibbon3; - break; - case MON_DATA_GIFT_RIBBON_4: - retVal = substruct3->giftRibbon4; - break; - case MON_DATA_GIFT_RIBBON_5: - retVal = substruct3->giftRibbon5; - break; - case MON_DATA_GIFT_RIBBON_6: - retVal = substruct3->giftRibbon6; - break; - case MON_DATA_GIFT_RIBBON_7: - retVal = substruct3->giftRibbon7; - break; - case MON_DATA_FATEFUL_ENCOUNTER: - retVal = substruct3->fatefulEncounter; - break; - case MON_DATA_OBEDIENCE: - retVal = substruct3->obedient; - break; - case MON_DATA_SPECIES2: - retVal = substruct0->species; - if (substruct0->species && (substruct3->isEgg || boxMon->isBadEgg)) - retVal = SPECIES_EGG; - break; - case MON_DATA_IVS: - retVal = substruct3->hpIV | (substruct3->attackIV << 5) | (substruct3->defenseIV << 10) | (substruct3->speedIV << 15) | (substruct3->spAttackIV << 20) | (substruct3->spDefenseIV << 25); - break; - case MON_DATA_KNOWN_MOVES: - if (substruct0->species && !substruct3->isEgg) - { - u16 *moves = (u16 *)data; - s32 i = 0; - - while (moves[i] != 355) - { - u16 move = moves[i]; - if (substruct1->moves[0] == move - || substruct1->moves[1] == move - || substruct1->moves[2] == move - || substruct1->moves[3] == move) - retVal |= gBitTable[i]; - i++; - } - } - break; - case MON_DATA_RIBBON_COUNT: - retVal = 0; - if (substruct0->species && !substruct3->isEgg) - { - retVal += substruct3->coolRibbon; - retVal += substruct3->beautyRibbon; - retVal += substruct3->cuteRibbon; - retVal += substruct3->smartRibbon; - retVal += substruct3->toughRibbon; - retVal += substruct3->championRibbon; - retVal += substruct3->winningRibbon; - retVal += substruct3->victoryRibbon; - retVal += substruct3->artistRibbon; - retVal += substruct3->effortRibbon; - retVal += substruct3->giftRibbon1; - retVal += substruct3->giftRibbon2; - retVal += substruct3->giftRibbon3; - retVal += substruct3->giftRibbon4; - retVal += substruct3->giftRibbon5; - retVal += substruct3->giftRibbon6; - retVal += substruct3->giftRibbon7; - } - break; - case MON_DATA_RIBBONS: - retVal = 0; - if (substruct0->species && !substruct3->isEgg) - { - retVal = substruct3->championRibbon - | (substruct3->coolRibbon << 1) - | (substruct3->beautyRibbon << 4) - | (substruct3->cuteRibbon << 7) - | (substruct3->smartRibbon << 10) - | (substruct3->toughRibbon << 13) - | (substruct3->winningRibbon << 16) - | (substruct3->victoryRibbon << 17) - | (substruct3->artistRibbon << 18) - | (substruct3->effortRibbon << 19) - | (substruct3->giftRibbon1 << 20) - | (substruct3->giftRibbon2 << 21) - | (substruct3->giftRibbon3 << 22) - | (substruct3->giftRibbon4 << 23) - | (substruct3->giftRibbon5 << 24) - | (substruct3->giftRibbon6 << 25) - | (substruct3->giftRibbon7 << 26); - } - break; - default: - break; - } - - if (field > MON_DATA_10) - EncryptBoxMon(boxMon); - - return retVal; -} - -#define SET8(lhs) (lhs) = *data -#define SET16(lhs) (lhs) = data[0] + (data[1] << 8) -#define SET32(lhs) (lhs) = data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24) - -void SetMonData(struct Pokemon *mon, s32 field, const void *dataArg) -{ - const u8* data = dataArg; - switch (field) - { - case MON_DATA_STATUS: - SET32(mon->status); - break; - case MON_DATA_LEVEL: - SET8(mon->level); - break; - case MON_DATA_HP: - SET16(mon->hp); - break; - case MON_DATA_MAX_HP: - SET16(mon->maxHP); - break; - case MON_DATA_ATK: - SET16(mon->attack); - break; - case MON_DATA_DEF: - SET16(mon->defense); - break; - case MON_DATA_SPEED: - SET16(mon->speed); - break; - case MON_DATA_SPATK: - SET16(mon->spAttack); - break; - case MON_DATA_SPDEF: - SET16(mon->spDefense); - break; - case MON_DATA_MAIL: - SET8(mon->mail); - break; - case MON_DATA_SPECIES2: - break; - default: - SetBoxMonData(&mon->box, field, data); - break; - } -} - -void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) -{ - const u8* data = dataArg; - - struct PokemonSubstruct0 *substruct0 = NULL; - struct PokemonSubstruct1 *substruct1 = NULL; - struct PokemonSubstruct2 *substruct2 = NULL; - struct PokemonSubstruct3 *substruct3 = NULL; - - if (field > MON_DATA_10) - { - substruct0 = &(GetSubstruct(boxMon, boxMon->personality, 0)->type0); - substruct1 = &(GetSubstruct(boxMon, boxMon->personality, 1)->type1); - substruct2 = &(GetSubstruct(boxMon, boxMon->personality, 2)->type2); - substruct3 = &(GetSubstruct(boxMon, boxMon->personality, 3)->type3); - - DecryptBoxMon(boxMon); - - if (CalculateBoxMonChecksum(boxMon) != boxMon->checksum) - { - boxMon->isBadEgg = 1; - boxMon->isEgg = 1; - substruct3->isEgg = 1; - EncryptBoxMon(boxMon); - return; - } - } - - switch (field) - { - case MON_DATA_PERSONALITY: - SET32(boxMon->personality); - break; - case MON_DATA_OT_ID: - SET32(boxMon->otId); - break; - case MON_DATA_NICKNAME: - { - s32 i; - for (i = 0; i < POKEMON_NAME_LENGTH; i++) - boxMon->nickname[i] = data[i]; - break; - } - case MON_DATA_LANGUAGE: - SET8(boxMon->language); - break; - case MON_DATA_SANITY_BIT1: - SET8(boxMon->isBadEgg); - break; - case MON_DATA_SANITY_BIT2: - SET8(boxMon->hasSpecies); - break; - case MON_DATA_SANITY_BIT3: - SET8(boxMon->isEgg); - break; - case MON_DATA_OT_NAME: - { - s32 i; - for (i = 0; i < OT_NAME_LENGTH; i++) - boxMon->otName[i] = data[i]; - break; - } - case MON_DATA_MARKINGS: - SET8(boxMon->markings); - break; - case MON_DATA_CHECKSUM: - SET16(boxMon->checksum); - break; - case MON_DATA_10: - SET16(boxMon->unknown); - break; - case MON_DATA_SPECIES: - { - SET16(substruct0->species); - if (substruct0->species) - boxMon->hasSpecies = 1; - else - boxMon->hasSpecies = 0; - break; - } - case MON_DATA_HELD_ITEM: - SET16(substruct0->heldItem); - break; - case MON_DATA_EXP: - SET32(substruct0->experience); - break; - case MON_DATA_PP_BONUSES: - SET8(substruct0->ppBonuses); - break; - case MON_DATA_FRIENDSHIP: - SET8(substruct0->friendship); - break; - case MON_DATA_MOVE1: - case MON_DATA_MOVE2: - case MON_DATA_MOVE3: - case MON_DATA_MOVE4: - SET16(substruct1->moves[field - MON_DATA_MOVE1]); - break; - case MON_DATA_PP1: - case MON_DATA_PP2: - case MON_DATA_PP3: - case MON_DATA_PP4: - SET8(substruct1->pp[field - MON_DATA_PP1]); - break; - case MON_DATA_HP_EV: - SET8(substruct2->hpEV); - break; - case MON_DATA_ATK_EV: - SET8(substruct2->attackEV); - break; - case MON_DATA_DEF_EV: - SET8(substruct2->defenseEV); - break; - case MON_DATA_SPEED_EV: - SET8(substruct2->speedEV); - break; - case MON_DATA_SPATK_EV: - SET8(substruct2->spAttackEV); - break; - case MON_DATA_SPDEF_EV: - SET8(substruct2->spDefenseEV); - break; - case MON_DATA_COOL: - SET8(substruct2->cool); - break; - case MON_DATA_BEAUTY: - SET8(substruct2->beauty); - break; - case MON_DATA_CUTE: - SET8(substruct2->cute); - break; - case MON_DATA_SMART: - SET8(substruct2->smart); - break; - case MON_DATA_TOUGH: - SET8(substruct2->tough); - break; - case MON_DATA_SHEEN: - SET8(substruct2->sheen); - break; - case MON_DATA_POKERUS: - SET8(substruct3->pokerus); - break; - case MON_DATA_MET_LOCATION: - SET8(substruct3->metLocation); - break; - case MON_DATA_MET_LEVEL: - { - u8 metLevel = *data; - substruct3->metLevel = metLevel; - break; - } - case MON_DATA_MET_GAME: - SET8(substruct3->metGame); - break; - case MON_DATA_POKEBALL: - { - u8 pokeball = *data; - substruct3->pokeball = pokeball; - break; - } - case MON_DATA_OT_GENDER: - SET8(substruct3->otGender); - break; - case MON_DATA_HP_IV: - SET8(substruct3->hpIV); - break; - case MON_DATA_ATK_IV: - SET8(substruct3->attackIV); - break; - case MON_DATA_DEF_IV: - SET8(substruct3->defenseIV); - break; - case MON_DATA_SPEED_IV: - SET8(substruct3->speedIV); - break; - case MON_DATA_SPATK_IV: - SET8(substruct3->spAttackIV); - break; - case MON_DATA_SPDEF_IV: - SET8(substruct3->spDefenseIV); - break; - case MON_DATA_IS_EGG: - SET8(substruct3->isEgg); - if (substruct3->isEgg) - boxMon->isEgg = 1; - else - boxMon->isEgg = 0; - break; - case MON_DATA_ALT_ABILITY: - SET8(substruct3->altAbility); - break; - case MON_DATA_COOL_RIBBON: - SET8(substruct3->coolRibbon); - break; - case MON_DATA_BEAUTY_RIBBON: - SET8(substruct3->beautyRibbon); - break; - case MON_DATA_CUTE_RIBBON: - SET8(substruct3->cuteRibbon); - break; - case MON_DATA_SMART_RIBBON: - SET8(substruct3->smartRibbon); - break; - case MON_DATA_TOUGH_RIBBON: - SET8(substruct3->toughRibbon); - break; - case MON_DATA_CHAMPION_RIBBON: - SET8(substruct3->championRibbon); - break; - case MON_DATA_WINNING_RIBBON: - SET8(substruct3->winningRibbon); - break; - case MON_DATA_VICTORY_RIBBON: - SET8(substruct3->victoryRibbon); - break; - case MON_DATA_ARTIST_RIBBON: - SET8(substruct3->artistRibbon); - break; - case MON_DATA_EFFORT_RIBBON: - SET8(substruct3->effortRibbon); - break; - case MON_DATA_GIFT_RIBBON_1: - SET8(substruct3->giftRibbon1); - break; - case MON_DATA_GIFT_RIBBON_2: - SET8(substruct3->giftRibbon2); - break; - case MON_DATA_GIFT_RIBBON_3: - SET8(substruct3->giftRibbon3); - break; - case MON_DATA_GIFT_RIBBON_4: - SET8(substruct3->giftRibbon4); - break; - case MON_DATA_GIFT_RIBBON_5: - SET8(substruct3->giftRibbon5); - break; - case MON_DATA_GIFT_RIBBON_6: - SET8(substruct3->giftRibbon6); - break; - case MON_DATA_GIFT_RIBBON_7: - SET8(substruct3->giftRibbon7); - break; - case MON_DATA_FATEFUL_ENCOUNTER: - SET8(substruct3->fatefulEncounter); - break; - case MON_DATA_OBEDIENCE: - SET8(substruct3->obedient); - break; - case MON_DATA_IVS: - { - u32 ivs = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); - substruct3->hpIV = ivs & 0x1F; - substruct3->attackIV = (ivs >> 5) & 0x1F; - substruct3->defenseIV = (ivs >> 10) & 0x1F; - substruct3->speedIV = (ivs >> 15) & 0x1F; - substruct3->spAttackIV = (ivs >> 20) & 0x1F; - substruct3->spDefenseIV = (ivs >> 25) & 0x1F; - break; - } - default: - break; - } - - if (field > MON_DATA_10) - { - boxMon->checksum = CalculateBoxMonChecksum(boxMon); - EncryptBoxMon(boxMon); - } -} - -void CopyMon(void *dest, void *src, size_t size) -{ - memcpy(dest, src, size); -} - -u8 GiveMonToPlayer(struct Pokemon *mon) -{ - s32 i; - - SetMonData(mon, MON_DATA_OT_NAME, gSaveBlock2Ptr->playerName); - SetMonData(mon, MON_DATA_OT_GENDER, &gSaveBlock2Ptr->playerGender); - SetMonData(mon, MON_DATA_OT_ID, gSaveBlock2Ptr->playerTrainerId); - - i = 0; - - while (i < 6 && GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL) != SPECIES_NONE) - i++; - - if (i >= 6) - return SendMonToPC(mon); - - CopyMon(&gPlayerParty[i], mon, sizeof(*mon)); - gPlayerPartyCount = i + 1; - return MON_GIVEN_TO_PARTY; -} - -extern u16 get_unknown_box_id(void); -extern u8 StorageGetCurrentBox(void); -extern void set_unknown_box_id(u8); -extern struct BoxPokemon* GetBoxedMonPtr(u8 boxNumber, u8 boxPosition); - -u8 SendMonToPC(struct Pokemon* mon) -{ - s32 boxNo, boxPos; - - set_unknown_box_id(VarGet(VAR_STORAGE_UNKNOWN)); - - boxNo = StorageGetCurrentBox(); - - do - { - for (boxPos = 0; boxPos < 30; boxPos++) - { - struct BoxPokemon* checkingMon = GetBoxedMonPtr(boxNo, boxPos); - if (GetBoxMonData(checkingMon, MON_DATA_SPECIES, NULL) == SPECIES_NONE) - { - MonRestorePP(mon); - CopyMon(checkingMon, &mon->box, sizeof(mon->box)); - gSpecialVar_MonBoxId = boxNo; - gSpecialVar_MonBoxPos = boxPos; - if (get_unknown_box_id() != boxNo) - FlagClear(FLAG_SYS_STORAGE_UNKNOWN_FLAG); - VarSet(VAR_STORAGE_UNKNOWN, boxNo); - return MON_GIVEN_TO_PC; - } - } - - boxNo++; - if (boxNo == 14) - boxNo = 0; - } while (boxNo != StorageGetCurrentBox()); - - return MON_CANT_GIVE; -} - -u8 CalculatePlayerPartyCount(void) -{ - gPlayerPartyCount = 0; - - while (gPlayerPartyCount < 6 - && GetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_SPECIES, NULL) != SPECIES_NONE) - { - gPlayerPartyCount++; - } - - return gPlayerPartyCount; -} - -u8 CalculateEnemyPartyCount(void) -{ - gEnemyPartyCount = 0; - - while (gEnemyPartyCount < 6 - && GetMonData(&gEnemyParty[gEnemyPartyCount], MON_DATA_SPECIES, NULL) != SPECIES_NONE) - { - gEnemyPartyCount++; - } - - return gEnemyPartyCount; -} - -u8 GetMonsStateToDoubles(void) -{ - s32 aliveCount = 0; - s32 i; - CalculatePlayerPartyCount(); - - if (gPlayerPartyCount == 1) - return gPlayerPartyCount; // PLAYER_HAS_ONE_MON - - for (i = 0; i < gPlayerPartyCount; i++) - { - if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) != SPECIES_EGG - && GetMonData(&gPlayerParty[i], MON_DATA_HP, NULL) != 0 - && GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) != SPECIES_NONE) - aliveCount++; - } - - return (aliveCount > 1) ? PLAYER_HAS_TWO_USABLE_MONS : PLAYER_HAS_ONE_USABLE_MON; -} - -u8 GetMonsStateToDoubles_2(void) -{ - s32 aliveCount = 0; - s32 i; - - for (i = 0; i < PARTY_SIZE; i++) - { - u32 species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL); - if (species != SPECIES_EGG && species != SPECIES_NONE - && GetMonData(&gPlayerParty[i], MON_DATA_HP, NULL) != 0) - aliveCount++; - } - - if (aliveCount == 1) - return PLAYER_HAS_ONE_MON; // may have more than one, but only one is alive - - return (aliveCount > 1) ? PLAYER_HAS_TWO_USABLE_MONS : PLAYER_HAS_ONE_USABLE_MON; -} - -u8 GetAbilityBySpecies(u16 species, bool8 altAbility) -{ - if (altAbility) - gLastUsedAbility = gBaseStats[species].ability2; - else - gLastUsedAbility = gBaseStats[species].ability1; - - return gLastUsedAbility; -} - -u8 GetMonAbility(struct Pokemon *mon) -{ - u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL); - u8 altAbility = GetMonData(mon, MON_DATA_ALT_ABILITY, NULL); - return GetAbilityBySpecies(species, altAbility); -} - -extern const struct BattleMove gBattleMoves[]; - -void CreateSecretBaseEnemyParty(struct SecretBaseRecord *secretBaseRecord) -{ - s32 i, j; - - ZeroEnemyPartyMons(); - *gBattleResources->secretBase = *secretBaseRecord; - - for (i = 0; i < PARTY_SIZE; i++) - { - if (gBattleResources->secretBase->party.species[i]) - { - CreateMon(&gEnemyParty[i], - gBattleResources->secretBase->party.species[i], - gBattleResources->secretBase->party.levels[i], - 15, - 1, - gBattleResources->secretBase->party.personality[i], - 2, - 0); - - SetMonData(&gEnemyParty[i], MON_DATA_HELD_ITEM, &gBattleResources->secretBase->party.heldItems[i]); - - for (j = 0; j < 6; j++) - SetMonData(&gEnemyParty[i], MON_DATA_HP_EV + j, &gBattleResources->secretBase->party.EVs[i]); - - for (j = 0; j < 4; j++) - { - SetMonData(&gEnemyParty[i], MON_DATA_MOVE1 + j, &gBattleResources->secretBase->party.moves[i * 4 + j]); - SetMonData(&gEnemyParty[i], MON_DATA_PP1 + j, &gBattleMoves[gBattleResources->secretBase->party.moves[i * 4 + j]].pp); - } - } - } -} - -extern const u8 gFacilityClassToPicIndex[]; -extern const u8 gFacilityClassToTrainerClass[]; -extern const u8 gSecretBaseTrainerClasses[][5]; - -u8 GetSecretBaseTrainerPicIndex(void) -{ - u8 trainerClass = gSecretBaseTrainerClasses[gBattleResources->secretBase->gender][gBattleResources->secretBase->trainerId[0] % 5]; - return gFacilityClassToPicIndex[trainerClass]; -} - -u8 GetSecretBaseTrainerNameIndex(void) -{ - u8 trainerClass = gSecretBaseTrainerClasses[gBattleResources->secretBase->gender][gBattleResources->secretBase->trainerId[0] % 5]; - return gFacilityClassToTrainerClass[trainerClass]; -} - -bool8 IsPlayerPartyAndPokemonStorageFull(void) -{ - s32 i; - - for (i = 0; i < 6; i++) - if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL) == SPECIES_NONE) - return FALSE; - - return IsPokemonStorageFull(); -} - -extern u32 GetBoxMonDataFromAnyBox(u8 boxNo, u8 boxPos, s32 field); - -bool8 IsPokemonStorageFull(void) -{ - s32 i, j; - - for (i = 0; i < 14; i++) - for (j = 0; j < 30; j++) - if (GetBoxMonDataFromAnyBox(i, j, MON_DATA_SPECIES) == SPECIES_NONE) - return FALSE; - - return TRUE; -} - -extern const u8 gSpeciesNames[][POKEMON_NAME_LENGTH + 1]; - -void GetSpeciesName(u8 *name, u16 species) -{ - s32 i; - - for (i = 0; i <= POKEMON_NAME_LENGTH; i++) - { - if (species > NUM_SPECIES) - name[i] = gSpeciesNames[0][i]; - else - name[i] = gSpeciesNames[species][i]; - - if (name[i] == EOS) - break; - } - - name[i] = EOS; -} - -extern const u8 gUnknown_08329D22[]; -extern const u8 gUnknown_08329D26[]; - -u8 CalculatePPWithBonus(u16 move, u8 ppBonuses, u8 moveIndex) -{ - u8 basePP = gBattleMoves[move].pp; - return basePP + ((basePP * 20 * ((gUnknown_08329D22[moveIndex] & ppBonuses) >> (2 * moveIndex))) / 100); -} - -void RemoveMonPPBonus(struct Pokemon *mon, u8 moveIndex) -{ - u8 ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES, NULL); - ppBonuses &= gUnknown_08329D26[moveIndex]; - SetMonData(mon, MON_DATA_PP_BONUSES, &ppBonuses); -} - -void RemoveBattleMonPPBonus(struct BattlePokemon *mon, u8 moveIndex) -{ - mon->ppBonuses &= gUnknown_08329D26[moveIndex]; -} - -void sub_803FA70(u8 bank); -void ClearTemporarySpeciesSpriteData(u8 bank, bool8); - -extern struct BattlePokemon gBattleMons[4]; - -void CopyPlayerPartyMonToBattleData(u8 bank, u8 partyIndex) -{ - u16* hpSwitchout; - s32 i; - u8 nickname[POKEMON_NAME_LENGTH * 2]; - - gBattleMons[bank].species = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPECIES, NULL); - gBattleMons[bank].item = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HELD_ITEM, NULL); - - for (i = 0; i < 4; i++) - { - gBattleMons[bank].moves[i] = GetMonData(&gPlayerParty[partyIndex], MON_DATA_MOVE1 + i, NULL); - gBattleMons[bank].pp[i] = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PP1 + i, NULL); - } - - gBattleMons[bank].ppBonuses = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PP_BONUSES, NULL); - gBattleMons[bank].friendship = GetMonData(&gPlayerParty[partyIndex], MON_DATA_FRIENDSHIP, NULL); - gBattleMons[bank].experience = GetMonData(&gPlayerParty[partyIndex], MON_DATA_EXP, NULL); - gBattleMons[bank].hpIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HP_IV, NULL); - gBattleMons[bank].attackIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_ATK_IV, NULL); - gBattleMons[bank].defenseIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_DEF_IV, NULL); - gBattleMons[bank].speedIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPEED_IV, NULL); - gBattleMons[bank].spAttackIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPATK_IV, NULL); - gBattleMons[bank].spDefenseIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPDEF_IV, NULL); - gBattleMons[bank].personality = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PERSONALITY, NULL); - gBattleMons[bank].status1 = GetMonData(&gPlayerParty[partyIndex], MON_DATA_STATUS, NULL); - gBattleMons[bank].level = GetMonData(&gPlayerParty[partyIndex], MON_DATA_LEVEL, NULL); - gBattleMons[bank].hp = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HP, NULL); - gBattleMons[bank].maxHP = GetMonData(&gPlayerParty[partyIndex], MON_DATA_MAX_HP, NULL); - gBattleMons[bank].attack = GetMonData(&gPlayerParty[partyIndex], MON_DATA_ATK, NULL); - gBattleMons[bank].defense = GetMonData(&gPlayerParty[partyIndex], MON_DATA_DEF, NULL); - gBattleMons[bank].speed = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPEED, NULL); - gBattleMons[bank].spAttack = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPATK, NULL); - gBattleMons[bank].spDefense = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPDEF, NULL); - gBattleMons[bank].isEgg = GetMonData(&gPlayerParty[partyIndex], MON_DATA_IS_EGG, NULL); - gBattleMons[bank].altAbility = GetMonData(&gPlayerParty[partyIndex], MON_DATA_ALT_ABILITY, NULL); - gBattleMons[bank].otId = GetMonData(&gPlayerParty[partyIndex], MON_DATA_OT_ID, NULL); - gBattleMons[bank].type1 = gBaseStats[gBattleMons[bank].species].type1; - gBattleMons[bank].type2 = gBaseStats[gBattleMons[bank].species].type2; - gBattleMons[bank].ability = GetAbilityBySpecies(gBattleMons[bank].species, gBattleMons[bank].altAbility); - GetMonData(&gPlayerParty[partyIndex], MON_DATA_NICKNAME, nickname); - StringCopy10(gBattleMons[bank].nickname, nickname); - GetMonData(&gPlayerParty[partyIndex], MON_DATA_OT_NAME, gBattleMons[bank].otName); - - hpSwitchout = &gBattleStruct->hpOnSwitchout[GetBattlerSide(bank)]; - *hpSwitchout = gBattleMons[bank].hp; - - for (i = 0; i < 8; i++) - gBattleMons[bank].statStages[i] = 6; - - gBattleMons[bank].status2 = 0; - sub_803FA70(bank); - ClearTemporarySpeciesSpriteData(bank, FALSE); -} diff --git a/src/pokemon_3.c b/src/pokemon_3.c deleted file mode 100644 index de9e481df..000000000 --- a/src/pokemon_3.c +++ /dev/null @@ -1,1749 +0,0 @@ -#include "global.h" -#include "pokemon.h" -#include "main.h" -#include "constants/items.h" -#include "string_util.h" -#include "battle_message.h" -#include "rtc.h" -#include "item.h" -#include "battle.h" -#include "constants/species.h" -#include "link.h" -#include "constants/hold_effects.h" -#include "random.h" -#include "constants/trainers.h" -#include "constants/songs.h" -#include "sound.h" -#include "m4a.h" -#include "task.h" -#include "sprite.h" -#include "text.h" -#include "constants/abilities.h" -#include "pokemon_animation.h" -#include "pokedex.h" -#include "pokeblock.h" - -extern struct BattlePokemon gBattleMons[4]; -extern struct BattleEnigmaBerry gEnigmaBerries[4]; -extern u8 gActiveBattler; -extern u8 gBankInMenu; -extern u8 gBattlerTarget; -extern u8 gBattlerAttacker; -extern u8 gStringBattler; -extern u16 gTrainerBattleOpponent_A; -extern u32 gBattleTypeFlags; -extern u8 gBattleMonForms[4]; -extern u16 gBattlerPartyIndexes[4]; -extern u8 gLastUsedAbility; -extern u16 gPartnerTrainerId; -extern u32 gHitMarker; - -extern const u16 gSpeciesToHoennPokedexNum[]; -extern const u16 gSpeciesToNationalPokedexNum[]; -extern const u16 gHoennToNationalOrder[]; -extern const u16 gSpeciesIdToCryId[]; -extern const struct SpindaSpot gSpindaSpotGraphics[]; -extern const u8* const gStatNamesTable[]; -extern const u8 gSpeciesNames[][11]; -extern const u8 gUnknown_08329EC8[]; -extern const u8 gText_StatRose[]; -extern const u8 gText_PkmnsStatChanged2[]; -extern const u8 gText_PkmnGettingPumped[]; -extern const u8 gText_PkmnShroudedInMist[]; -extern const s8 gNatureStatTable[][5]; -extern const s8 gUnknown_08329ECE[][3]; -extern const u32 gBitTable[]; -extern const u32 gTMHMLearnsets[][2]; -extern const u8 gText_BattleWallyName[]; -extern const u8 gText_PkmnsXPreventsSwitching[]; -extern const struct CompressedSpritePalette gMonPaletteTable[]; -extern const struct CompressedSpritePalette gMonShinyPaletteTable[]; -extern const u16 gHMMoves[]; -extern const u8 gMonAnimationDelayTable[]; -extern const u8 gMonFrontAnimIdsTable[]; - -extern bool8 InBattlePyramid(void); -extern bool8 InBattlePike(void); -extern bool8 sub_81D5C18(void); -extern bool8 sub_806F104(void); -extern bool32 IsNationalPokedexEnabled(void); -extern u8 GetTrainerEncounterMusicIdInBattlePyramind(u16 trainerOpponentId); -extern u8 sub_81D63C8(u16 trainerOpponentId); -extern u8 sav1_map_get_name(void); -extern u8 GetFrontierOpponentClass(u16 trainerId); -extern u8 pokemon_order_func(u8 bankPartyId); -extern void GetFrontierTrainerName(u8* dest, u16 trainerId); -extern void sub_81C488C(u8); - -static void sub_806E6CC(u8 taskId); - -bool8 HealStatusConditions(struct Pokemon *mon, u32 battlePartyId, u32 healMask, u8 battleBank) -{ - u32 status = GetMonData(mon, MON_DATA_STATUS, 0); - - if (status & healMask) - { - status &= ~healMask; - SetMonData(mon, MON_DATA_STATUS, (u8 *)&status); - if (gMain.inBattle && battleBank != 4) - gBattleMons[battleBank].status1 &= ~healMask; - return FALSE; - } - else - { - return TRUE; - } -} - -u8 GetItemEffectParamOffset(u16 itemId, u8 effectByte, u8 effectBit) -{ - const u8 *temp; - const u8 *itemEffect; - u8 offset; - int i; - u8 j; - u8 val; - - offset = 6; - - temp = gItemEffectTable[itemId - 13]; - - if (!temp && itemId != ITEM_ENIGMA_BERRY) - return 0; - - if (itemId == ITEM_ENIGMA_BERRY) - { - temp = gEnigmaBerries[gActiveBattler].itemEffect; - } - - itemEffect = temp; - - for (i = 0; i < 6; i++) - { - switch (i) - { - case 0: - case 1: - case 2: - case 3: - if (i == effectByte) - return 0; - break; - case 4: - val = itemEffect[4]; - if (val & 0x20) - val &= 0xDF; - j = 0; - while (val) - { - if (val & 1) - { - switch (j) - { - case 2: - if (val & 0x10) - val &= 0xEF; - case 0: - if (i == effectByte && (val & effectBit)) - return offset; - offset++; - break; - case 1: - if (i == effectByte && (val & effectBit)) - return offset; - offset++; - break; - case 3: - if (i == effectByte && (val & effectBit)) - return offset; - offset++; - break; - case 7: - if (i == effectByte) - return 0; - break; - } - } - j++; - val >>= 1; - if (i == effectByte) - effectBit >>= 1; - } - break; - case 5: - val = itemEffect[5]; - j = 0; - while (val) - { - if (val & 1) - { - switch (j) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - if (i == effectByte && (val & effectBit)) - return offset; - offset++; - break; - case 7: - if (i == effectByte) - return 0; - break; - } - } - j++; - val >>= 1; - if (i == effectByte) - effectBit >>= 1; - } - break; - } - } - - return offset; -} - -void sub_806CF24(s32 stat) -{ - gBattlerTarget = gBankInMenu; - StringCopy(gBattleTextBuff1, gStatNamesTable[gUnknown_08329EC8[stat]]); - StringCopy(gBattleTextBuff2, gText_StatRose); - BattleStringExpandPlaceholdersToDisplayedString(gText_PkmnsStatChanged2); -} - -u8 *sub_806CF78(u16 itemId) -{ - int i; - const u8 *itemEffect; - - if (itemId == ITEM_ENIGMA_BERRY) - { - if (gMain.inBattle) - itemEffect = gEnigmaBerries[gBankInMenu].itemEffect; - else - itemEffect = gSaveBlock1Ptr->enigmaBerry.itemEffect; - } - else - { - itemEffect = gItemEffectTable[itemId - 13]; - } - - gStringBattler = gBankInMenu; - - for (i = 0; i < 3; i++) - { - if (itemEffect[i] & 0xF) - sub_806CF24(i * 2); - if (itemEffect[i] & 0xF0) - { - if (i) - { - sub_806CF24(i * 2 + 1); - } - else - { - gBattlerAttacker = gBankInMenu; - BattleStringExpandPlaceholdersToDisplayedString(gText_PkmnGettingPumped); - } - } - } - - if (itemEffect[3] & 0x80) - { - gBattlerAttacker = gBankInMenu; - BattleStringExpandPlaceholdersToDisplayedString(gText_PkmnShroudedInMist); - } - - return gDisplayedStringBattle; -} - -u8 GetNature(struct Pokemon *mon) -{ - return GetMonData(mon, MON_DATA_PERSONALITY, 0) % 25; -} - -u8 GetNatureFromPersonality(u32 personality) -{ - return personality % 25; -} - -u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 type, u16 evolutionItem) -{ - int i; - u16 targetSpecies = 0; - u16 species = GetMonData(mon, MON_DATA_SPECIES, 0); - u16 heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0); - u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0); - u8 level; - u16 friendship; - u8 beauty = GetMonData(mon, MON_DATA_BEAUTY, 0); - u16 upperPersonality = personality >> 16; - u8 holdEffect; - - if (heldItem == ITEM_ENIGMA_BERRY) - holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect; - else - holdEffect = ItemId_GetHoldEffect(heldItem); - - if (holdEffect == 38 && type != 3) - return 0; - - switch (type) - { - case 0: - level = GetMonData(mon, MON_DATA_LEVEL, 0); - friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, 0); - - for (i = 0; i < 5; i++) - { - switch (gEvolutionTable[species][i].method) - { - case EVO_FRIENDSHIP: - if (friendship >= 220) - targetSpecies = gEvolutionTable[species][i].targetSpecies; - break; - case EVO_FRIENDSHIP_DAY: - RtcCalcLocalTime(); - if (gLocalTime.hours >= 12 && gLocalTime.hours < 24 && friendship >= 220) - targetSpecies = gEvolutionTable[species][i].targetSpecies; - break; - case EVO_FRIENDSHIP_NIGHT: - RtcCalcLocalTime(); - if (gLocalTime.hours >= 0 && gLocalTime.hours < 12 && friendship >= 220) - targetSpecies = gEvolutionTable[species][i].targetSpecies; - break; - case EVO_LEVEL: - if (gEvolutionTable[species][i].param <= level) - targetSpecies = gEvolutionTable[species][i].targetSpecies; - break; - case EVO_LEVEL_ATK_GT_DEF: - if (gEvolutionTable[species][i].param <= level) - if (GetMonData(mon, MON_DATA_ATK, 0) > GetMonData(mon, MON_DATA_DEF, 0)) - targetSpecies = gEvolutionTable[species][i].targetSpecies; - break; - case EVO_LEVEL_ATK_EQ_DEF: - if (gEvolutionTable[species][i].param <= level) - if (GetMonData(mon, MON_DATA_ATK, 0) == GetMonData(mon, MON_DATA_DEF, 0)) - targetSpecies = gEvolutionTable[species][i].targetSpecies; - break; - case EVO_LEVEL_ATK_LT_DEF: - if (gEvolutionTable[species][i].param <= level) - if (GetMonData(mon, MON_DATA_ATK, 0) < GetMonData(mon, MON_DATA_DEF, 0)) - targetSpecies = gEvolutionTable[species][i].targetSpecies; - break; - case EVO_LEVEL_SILCOON: - if (gEvolutionTable[species][i].param <= level && (upperPersonality % 10) <= 4) - targetSpecies = gEvolutionTable[species][i].targetSpecies; - break; - case EVO_LEVEL_CASCOON: - if (gEvolutionTable[species][i].param <= level && (upperPersonality % 10) > 4) - targetSpecies = gEvolutionTable[species][i].targetSpecies; - break; - case EVO_LEVEL_NINJASK: - if (gEvolutionTable[species][i].param <= level) - targetSpecies = gEvolutionTable[species][i].targetSpecies; - break; - case EVO_BEAUTY: - if (gEvolutionTable[species][i].param <= beauty) - targetSpecies = gEvolutionTable[species][i].targetSpecies; - break; - } - } - break; - case 1: - for (i = 0; i < 5; i++) - { - switch (gEvolutionTable[species][i].method) - { - case EVO_TRADE: - targetSpecies = gEvolutionTable[species][i].targetSpecies; - break; - case EVO_TRADE_ITEM: - if (gEvolutionTable[species][i].param == heldItem) - { - heldItem = 0; - SetMonData(mon, MON_DATA_HELD_ITEM, (u8 *)&heldItem); - targetSpecies = gEvolutionTable[species][i].targetSpecies; - } - break; - } - } - break; - case 2: - case 3: - for (i = 0; i < 5; i++) - { - if (gEvolutionTable[species][i].method == EVO_ITEM - && gEvolutionTable[species][i].param == evolutionItem) - { - targetSpecies = gEvolutionTable[species][i].targetSpecies; - break; - } - } - break; - } - - return targetSpecies; -} - -u16 HoennPokedexNumToSpecies(u16 hoennNum) -{ - u16 species; - - if (!hoennNum) - return 0; - - species = 0; - - while (species < 411 && gSpeciesToHoennPokedexNum[species] != hoennNum) - species++; - - if (species == 411) - return 0; - - return species + 1; -} - -u16 NationalPokedexNumToSpecies(u16 nationalNum) -{ - u16 species; - - if (!nationalNum) - return 0; - - species = 0; - - while (species < 411 && gSpeciesToNationalPokedexNum[species] != nationalNum) - species++; - - if (species == 411) - return 0; - - return species + 1; -} - -u16 NationalToHoennOrder(u16 nationalNum) -{ - u16 hoennNum; - - if (!nationalNum) - return 0; - - hoennNum = 0; - - while (hoennNum < 411 && gHoennToNationalOrder[hoennNum] != nationalNum) - hoennNum++; - - if (hoennNum == 411) - return 0; - - return hoennNum + 1; -} - -u16 SpeciesToNationalPokedexNum(u16 species) -{ - if (!species) - return 0; - - return gSpeciesToNationalPokedexNum[species - 1]; -} - -u16 SpeciesToHoennPokedexNum(u16 species) -{ - if (!species) - return 0; - - return gSpeciesToHoennPokedexNum[species - 1]; -} - -u16 HoennToNationalOrder(u16 hoennNum) -{ - if (!hoennNum) - return 0; - - return gHoennToNationalOrder[hoennNum - 1]; -} - -u16 SpeciesToCryId(u16 species) -{ - if (species <= 250) - return species; - - if (species < 276) - return 200; - - return gSpeciesIdToCryId[species - 276]; -} - -void sub_806D544(u16 species, u32 personality, u8 *dest) -{ - if (species == SPECIES_SPINDA - && dest != gMonSpritesGfxPtr->sprites[0] - && dest != gMonSpritesGfxPtr->sprites[2]) - { - int i; - for (i = 0; i < 4; i++) - { - int j; - u8 x = gSpindaSpotGraphics[i].x + ((personality & 0x0F) - 8); - u8 y = gSpindaSpotGraphics[i].y + (((personality & 0xF0) >> 4) - 8); - - for (j = 0; j < 16; j++) - { - int k; - s32 row = gSpindaSpotGraphics[i].image[j]; - - for (k = x; k < x + 16; k++) - { - u8 *val = dest + ((k / 8) * 32) + ((k % 8) / 2) + ((y >> 3) << 8) + ((y & 7) << 2); - - if (row & 1) - { - if (k & 1) - { - if ((u8)((*val & 0xF0) - 0x10) <= 0x20) - *val += 0x40; - } - else - { - if ((u8)((*val & 0xF) - 0x01) <= 0x02) - *val += 0x04; - } - } - - row >>= 1; - } - - y++; - } - - personality >>= 8; - } - } -} - -void DrawSpindaSpots(u16 species, u32 personality, u8 *dest, u8 a4) -{ - if (species == SPECIES_SPINDA && a4) - { - int i; - for (i = 0; i < 4; i++) - { - int j; - u8 x = gSpindaSpotGraphics[i].x + ((personality & 0x0F) - 8); - u8 y = gSpindaSpotGraphics[i].y + (((personality & 0xF0) >> 4) - 8); - - for (j = 0; j < 16; j++) - { - int k; - s32 row = gSpindaSpotGraphics[i].image[j]; - - for (k = x; k < x + 16; k++) - { - u8 *val = dest + ((k / 8) * 32) + ((k % 8) / 2) + ((y >> 3) << 8) + ((y & 7) << 2); - - if (row & 1) - { - if (k & 1) - { - if ((u8)((*val & 0xF0) - 0x10) <= 0x20) - *val += 0x40; - } - else - { - if ((u8)((*val & 0xF) - 0x01) <= 0x02) - *val += 0x04; - } - } - - row >>= 1; - } - - y++; - } - - personality >>= 8; - } - } -} - -void EvolutionRenameMon(struct Pokemon *mon, u16 oldSpecies, u16 newSpecies) -{ - u8 language; - GetMonData(mon, MON_DATA_NICKNAME, gStringVar1); - language = GetMonData(mon, MON_DATA_LANGUAGE, &language); - if (language == GAME_LANGUAGE && !StringCompare(gSpeciesNames[oldSpecies], gStringVar1)) - SetMonData(mon, MON_DATA_NICKNAME, gSpeciesNames[newSpecies]); -} - -bool8 sub_806D7EC(void) -{ - bool8 retVal = FALSE; - switch (gLinkPlayers[GetMultiplayerId()].lp_field_18) - { - case 0: - case 3: - retVal = FALSE; - break; - case 1: - case 2: - retVal = TRUE; - break; - } - return retVal; -} - -bool16 sub_806D82C(u8 id) -{ - bool16 retVal = FALSE; - switch (gLinkPlayers[id].lp_field_18) - { - case 0: - case 3: - retVal = FALSE; - break; - case 1: - case 2: - retVal = TRUE; - break; - } - return retVal; -} - -s32 GetBattlerMultiplayerId(u16 a1) -{ - s32 id; - for (id = 0; id < MAX_LINK_PLAYERS; id++) - if (gLinkPlayers[id].lp_field_18 == a1) - break; - return id; -} - -u8 GetTrainerEncounterMusicId(u16 trainerOpponentId) -{ - if (InBattlePyramid()) - return GetTrainerEncounterMusicIdInBattlePyramind(trainerOpponentId); - if (sub_81D5C18()) - return sub_81D63C8(trainerOpponentId); - return TRAINER_ENCOUNTER_MUSIC(trainerOpponentId); -} - -u16 nature_stat_mod(u8 nature, u16 n, u8 statIndex) -{ - if (statIndex < 1 || statIndex > 5) - { - // should just be "return n", but it wouldn't match without this - u16 retVal = n; - retVal++; - retVal--; - return retVal; - } - - switch (gNatureStatTable[nature][statIndex - 1]) - { - case 1: - return (u16)(n * 110) / 100; - case -1: - return (u16)(n * 90) / 100; - } - - return n; -} - -void AdjustFriendship(struct Pokemon *mon, u8 event) -{ - u16 species, heldItem; - u8 holdEffect; - - if (sub_806F104()) - return; - - species = GetMonData(mon, MON_DATA_SPECIES2, 0); - heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0); - - if (heldItem == ITEM_ENIGMA_BERRY) - { - if (gMain.inBattle) - holdEffect = gEnigmaBerries[0].holdEffect; - else - holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect; - } - else - { - holdEffect = ItemId_GetHoldEffect(heldItem); - } - - if (species && species != SPECIES_EGG) - { - u8 friendshipLevel = 0; - s16 friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, 0); - if (friendship > 99) - friendshipLevel++; - if (friendship > 199) - friendshipLevel++; - if ((event != 5 || !(Random() & 1)) - && (event != 3 - || ((gBattleTypeFlags & BATTLE_TYPE_TRAINER) - && (gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_ELITE_FOUR - || gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_LEADER - || gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_CHAMPION)))) - { - s8 mod = gUnknown_08329ECE[event][friendshipLevel]; - if (mod > 0 && holdEffect == HOLD_EFFECT_HAPPINESS_UP) - mod = (150 * mod) / 100; - friendship += mod; - if (mod > 0) - { - if (GetMonData(mon, MON_DATA_POKEBALL, 0) == ITEM_LUXURY_BALL) - friendship++; - if (GetMonData(mon, MON_DATA_MET_LOCATION, 0) == sav1_map_get_name()) - friendship++; - } - if (friendship < 0) - friendship = 0; - if (friendship > 255) - friendship = 255; - SetMonData(mon, MON_DATA_FRIENDSHIP, &friendship); - } - } -} - -void MonGainEVs(struct Pokemon *mon, u16 defeatedSpecies) -{ - u8 evs[NUM_STATS]; - u16 evIncrease = 0; - u16 totalEVs = 0; - u16 heldItem; - u8 holdEffect; - int i; - - for (i = 0; i < NUM_STATS; i++) - { - evs[i] = GetMonData(mon, MON_DATA_HP_EV + i, 0); - totalEVs += evs[i]; - } - - for (i = 0; i < NUM_STATS; i++) - { - u8 hasHadPokerus; - int multiplier; - - if (totalEVs >= MAX_TOTAL_EVS) - break; - - hasHadPokerus = CheckPartyHasHadPokerus(mon, 0); - - if (hasHadPokerus) - multiplier = 2; - else - multiplier = 1; - - switch (i) - { - case 0: - evIncrease = gBaseStats[defeatedSpecies].evYield_HP * multiplier; - break; - case 1: - evIncrease = gBaseStats[defeatedSpecies].evYield_Attack * multiplier; - break; - case 2: - evIncrease = gBaseStats[defeatedSpecies].evYield_Defense * multiplier; - break; - case 3: - evIncrease = gBaseStats[defeatedSpecies].evYield_Speed * multiplier; - break; - case 4: - evIncrease = gBaseStats[defeatedSpecies].evYield_SpAttack * multiplier; - break; - case 5: - evIncrease = gBaseStats[defeatedSpecies].evYield_SpDefense * multiplier; - break; - } - - heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0); - - if (heldItem == ITEM_ENIGMA_BERRY) - { - if (gMain.inBattle) - holdEffect = gEnigmaBerries[0].holdEffect; - else - holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect; - } - else - { - holdEffect = ItemId_GetHoldEffect(heldItem); - } - - if (holdEffect == HOLD_EFFECT_MACHO_BRACE) - evIncrease *= 2; - - if (totalEVs + (s16)evIncrease > MAX_TOTAL_EVS) - evIncrease = ((s16)evIncrease + MAX_TOTAL_EVS) - (totalEVs + evIncrease); - - if (evs[i] + (s16)evIncrease > 255) - { - int val1 = (s16)evIncrease + 255; - int val2 = evs[i] + evIncrease; - evIncrease = val1 - val2; - } - - evs[i] += evIncrease; - totalEVs += evIncrease; - SetMonData(mon, MON_DATA_HP_EV + i, &evs[i]); - } -} - -u16 GetMonEVCount(struct Pokemon *mon) -{ - int i; - u16 count = 0; - - for (i = 0; i < NUM_STATS; i++) - count += GetMonData(mon, MON_DATA_HP_EV + i, 0); - - return count; -} - -void RandomlyGivePartyPokerus(struct Pokemon *party) -{ - u16 rnd = Random(); - if (rnd == 0x4000 || rnd == 0x8000 || rnd == 0xC000) - { - struct Pokemon *mon; - - do - { - do - { - rnd = Random() % PARTY_SIZE; - mon = &party[rnd]; - } - while (!GetMonData(mon, MON_DATA_SPECIES, 0)); - } - while (GetMonData(mon, MON_DATA_IS_EGG, 0)); - - if (!(CheckPartyHasHadPokerus(party, gBitTable[rnd]))) - { - u8 rnd2; - - do - { - rnd2 = Random(); - } - while ((rnd2 & 0x7) == 0); - - if (rnd2 & 0xF0) - rnd2 &= 0x7; - - rnd2 |= (rnd2 << 4); - rnd2 &= 0xF3; - rnd2++; - - SetMonData(&party[rnd], MON_DATA_POKERUS, &rnd2); - } - } -} - -u8 CheckPartyPokerus(struct Pokemon *party, u8 selection) -{ - u8 retVal; - - int partyIndex = 0; - unsigned curBit = 1; - retVal = 0; - - if (selection) - { - do - { - if ((selection & 1) && (GetMonData(&party[partyIndex], MON_DATA_POKERUS, 0) & 0xF)) - retVal |= curBit; - partyIndex++; - curBit <<= 1; - selection >>= 1; - } - while (selection); - } - else if (GetMonData(&party[0], MON_DATA_POKERUS, 0) & 0xF) - { - retVal = 1; - } - - return retVal; -} - -u8 CheckPartyHasHadPokerus(struct Pokemon *party, u8 selection) -{ - u8 retVal; - - int partyIndex = 0; - unsigned curBit = 1; - retVal = 0; - - if (selection) - { - do - { - if ((selection & 1) && GetMonData(&party[partyIndex], MON_DATA_POKERUS, 0)) - retVal |= curBit; - partyIndex++; - curBit <<= 1; - selection >>= 1; - } - while (selection); - } - else if (GetMonData(&party[0], MON_DATA_POKERUS, 0)) - { - retVal = 1; - } - - return retVal; -} - -void UpdatePartyPokerusTime(u16 days) -{ - int i; - for (i = 0; i < PARTY_SIZE; i++) - { - if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, 0)) - { - u8 pokerus = GetMonData(&gPlayerParty[i], MON_DATA_POKERUS, 0); - if (pokerus & 0xF) - { - if ((pokerus & 0xF) < days || days > 4) - pokerus &= 0xF0; - else - pokerus -= days; - - if (pokerus == 0) - pokerus = 0x10; - - SetMonData(&gPlayerParty[i], MON_DATA_POKERUS, &pokerus); - } - } - } -} - -void PartySpreadPokerus(struct Pokemon *party) -{ - if ((Random() % 3) == 0) - { - int i; - for (i = 0; i < PARTY_SIZE; i++) - { - if (GetMonData(&party[i], MON_DATA_SPECIES, 0)) - { - u8 pokerus = GetMonData(&party[i], MON_DATA_POKERUS, 0); - u8 curPokerus = pokerus; - if (pokerus) - { - if (pokerus & 0xF) - { - // spread to adjacent party members - if (i != 0 && !(GetMonData(&party[i - 1], MON_DATA_POKERUS, 0) & 0xF0)) - SetMonData(&party[i - 1], MON_DATA_POKERUS, &curPokerus); - if (i != (PARTY_SIZE - 1) && !(GetMonData(&party[i + 1], MON_DATA_POKERUS, 0) & 0xF0)) - { - SetMonData(&party[i + 1], MON_DATA_POKERUS, &curPokerus); - i++; - } - } - } - } - } - } -} - -bool8 TryIncrementMonLevel(struct Pokemon *mon) -{ - u16 species = GetMonData(mon, MON_DATA_SPECIES, 0); - u8 nextLevel = GetMonData(mon, MON_DATA_LEVEL, 0) + 1; - u32 expPoints = GetMonData(mon, MON_DATA_EXP, 0); - if (expPoints > gExperienceTables[gBaseStats[species].growthRate][MAX_MON_LEVEL]) - { - expPoints = gExperienceTables[gBaseStats[species].growthRate][MAX_MON_LEVEL]; - SetMonData(mon, MON_DATA_EXP, &expPoints); - } - if (nextLevel > MAX_MON_LEVEL || expPoints < gExperienceTables[gBaseStats[species].growthRate][nextLevel]) - { - return FALSE; - } - else - { - SetMonData(mon, MON_DATA_LEVEL, &nextLevel); - return TRUE; - } -} - -u32 CanMonLearnTMHM(struct Pokemon *mon, u8 tm) -{ - u16 species = GetMonData(mon, MON_DATA_SPECIES2, 0); - if (species == SPECIES_EGG) - { - return 0; - } - else if (tm < 32) - { - u32 mask = 1 << tm; - return gTMHMLearnsets[species][0] & mask; - } - else - { - u32 mask = 1 << (tm - 32); - return gTMHMLearnsets[species][1] & mask; - } -} - -u32 CanSpeciesLearnTMHM(u16 species, u8 tm) -{ - if (species == SPECIES_EGG) - { - return 0; - } - else if (tm < 32) - { - u32 mask = 1 << tm; - return gTMHMLearnsets[species][0] & mask; - } - else - { - u32 mask = 1 << (tm - 32); - return gTMHMLearnsets[species][1] & mask; - } -} - -u8 GetMoveRelearnerMoves(struct Pokemon *mon, u16 *moves) -{ - u16 learnedMoves[4]; - u8 numMoves = 0; - u16 species = GetMonData(mon, MON_DATA_SPECIES, 0); - u8 level = GetMonData(mon, MON_DATA_LEVEL, 0); - int i, j, k; - - for (i = 0; i < 4; i++) - learnedMoves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, 0); - - for (i = 0; i < 20; i++) - { - u16 moveLevel; - - if (gLevelUpLearnsets[species][i] == 0xFFFF) - break; - - moveLevel = gLevelUpLearnsets[species][i] & 0xFE00; - - if (moveLevel <= (level << 9)) - { - for (j = 0; j < 4 && learnedMoves[j] != (gLevelUpLearnsets[species][i] & 0x1FF); j++) - ; - - if (j == 4) - { - for (k = 0; k < numMoves && moves[k] != (gLevelUpLearnsets[species][i] & 0x1FF); k++) - ; - - if (k == numMoves) - moves[numMoves++] = gLevelUpLearnsets[species][i] & 0x1FF; - } - } - } - - return numMoves; -} - -u8 GetLevelUpMovesBySpecies(u16 species, u16 *moves) -{ - u8 numMoves = 0; - int i; - - for (i = 0; i < 20 && gLevelUpLearnsets[species][i] != 0xFFFF; i++) - moves[numMoves++] = gLevelUpLearnsets[species][i] & 0x1FF; - - return numMoves; -} - -u8 GetNumberOfRelearnableMoves(struct Pokemon *mon) -{ - u16 learnedMoves[4]; - u16 moves[20]; - u8 numMoves = 0; - u16 species = GetMonData(mon, MON_DATA_SPECIES2, 0); - u8 level = GetMonData(mon, MON_DATA_LEVEL, 0); - int i, j, k; - - if (species == SPECIES_EGG) - return 0; - - for (i = 0; i < 4; i++) - learnedMoves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, 0); - - for (i = 0; i < 20; i++) - { - u16 moveLevel; - - if (gLevelUpLearnsets[species][i] == 0xFFFF) - break; - - moveLevel = gLevelUpLearnsets[species][i] & 0xFE00; - - if (moveLevel <= (level << 9)) - { - for (j = 0; j < 4 && learnedMoves[j] != (gLevelUpLearnsets[species][i] & 0x1FF); j++) - ; - - if (j == 4) - { - for (k = 0; k < numMoves && moves[k] != (gLevelUpLearnsets[species][i] & 0x1FF); k++) - ; - - if (k == numMoves) - moves[numMoves++] = gLevelUpLearnsets[species][i] & 0x1FF; - } - } - } - - return numMoves; -} - -u16 SpeciesToPokedexNum(u16 species) -{ - if (IsNationalPokedexEnabled()) - { - return SpeciesToNationalPokedexNum(species); - } - else - { - species = SpeciesToHoennPokedexNum(species); - if (species <= 202) - return species; - return 0xFFFF; - } -} - -bool32 sub_806E3F8(u16 species) -{ - if (SpeciesToHoennPokedexNum(species) > 202) - return FALSE; - else - return TRUE; -} - -void ClearBattleMonForms(void) -{ - int i; - for (i = 0; i < 4; i++) - gBattleMonForms[i] = 0; -} - -u16 GetBattleBGM(void) -{ - if (gBattleTypeFlags & BATTLE_TYPE_KYOGRE_GROUDON) - return MUS_BATTLE34; - if (gBattleTypeFlags & BATTLE_TYPE_REGI) - return MUS_BATTLE36; - if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000)) - return MUS_BATTLE20; - if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) - { - u8 trainerClass; - - if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER) - trainerClass = GetFrontierOpponentClass(gTrainerBattleOpponent_A); - else if (gBattleTypeFlags & BATTLE_TYPE_x4000000) - trainerClass = TRAINER_CLASS_EXPERT; - else - trainerClass = gTrainers[gTrainerBattleOpponent_A].trainerClass; - - switch (trainerClass) - { - case TRAINER_CLASS_AQUA_LEADER: - case TRAINER_CLASS_MAGMA_LEADER: - return MUS_BATTLE30; - case TRAINER_CLASS_TEAM_AQUA: - case TRAINER_CLASS_TEAM_MAGMA: - case TRAINER_CLASS_AQUA_ADMIN: - case TRAINER_CLASS_MAGMA_ADMIN: - return MUS_BATTLE31; - case TRAINER_CLASS_LEADER: - return MUS_BATTLE32; - case TRAINER_CLASS_CHAMPION: - return MUS_BATTLE33; - case TRAINER_CLASS_PKMN_TRAINER_3: - if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER) - return MUS_BATTLE35; - if (!StringCompare(gTrainers[gTrainerBattleOpponent_A].trainerName, gText_BattleWallyName)) - return MUS_BATTLE20; - return MUS_BATTLE35; - case TRAINER_CLASS_ELITE_FOUR: - return MUS_BATTLE38; - case TRAINER_CLASS_SALON_MAIDEN: - case TRAINER_CLASS_DOME_ACE: - case TRAINER_CLASS_PALACE_MAVEN: - case TRAINER_CLASS_ARENA_TYCOON: - case TRAINER_CLASS_FACTORY_HEAD: - case TRAINER_CLASS_PIKE_QUEEN: - case TRAINER_CLASS_PYRAMID_KING: - return MUS_VS_FRONT; - default: - return MUS_BATTLE20; - } - } - return MUS_BATTLE27; -} - -void PlayBattleBGM(void) -{ - ResetMapMusic(); - m4aMPlayAllStop(); - PlayBGM(GetBattleBGM()); -} - -void PlayMapChosenOrBattleBGM(u16 songId) -{ - ResetMapMusic(); - m4aMPlayAllStop(); - if (songId) - PlayNewMapMusic(songId); - else - PlayNewMapMusic(GetBattleBGM()); -} - -void sub_806E694(u16 songId) -{ - u8 taskId; - - ResetMapMusic(); - m4aMPlayAllStop(); - - taskId = CreateTask(sub_806E6CC, 0); - gTasks[taskId].data[0] = songId; -} - -static void sub_806E6CC(u8 taskId) -{ - if (gTasks[taskId].data[0]) - PlayNewMapMusic(gTasks[taskId].data[0]); - else - PlayNewMapMusic(GetBattleBGM()); - DestroyTask(taskId); -} - -const u8 *GetMonFrontSpritePal(struct Pokemon *mon) -{ - u16 species = GetMonData(mon, MON_DATA_SPECIES2, 0); - u32 otId = GetMonData(mon, MON_DATA_OT_ID, 0); - u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0); - return GetFrontSpritePalFromSpeciesAndPersonality(species, otId, personality); -} - -// Extracts the upper 16 bits of a 32-bit number -#define HIHALF(n) (((n) & 0xFFFF0000) >> 16) - -// Extracts the lower 16 bits of a 32-bit number -#define LOHALF(n) ((n) & 0xFFFF) - -const u8 *GetFrontSpritePalFromSpeciesAndPersonality(u16 species, u32 otId, u32 personality) -{ - u32 shinyValue; - - if (species > SPECIES_EGG) - return gMonPaletteTable[0].data; - - shinyValue = HIHALF(otId) ^ LOHALF(otId) ^ HIHALF(personality) ^ LOHALF(personality); - if (shinyValue < 8) - return gMonShinyPaletteTable[species].data; - else - return gMonPaletteTable[species].data; -} - -const struct CompressedSpritePalette *sub_806E794(struct Pokemon *mon) -{ - u16 species = GetMonData(mon, MON_DATA_SPECIES2, 0); - u32 otId = GetMonData(mon, MON_DATA_OT_ID, 0); - u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0); - return GetMonSpritePalStructFromOtIdPersonality(species, otId, personality); -} - -const struct CompressedSpritePalette *GetMonSpritePalStructFromOtIdPersonality(u16 species, u32 otId , u32 personality) -{ - u32 shinyValue; - - shinyValue = HIHALF(otId) ^ LOHALF(otId) ^ HIHALF(personality) ^ LOHALF(personality); - if (shinyValue < 8) - return &gMonShinyPaletteTable[species]; - else - return &gMonPaletteTable[species]; -} - -bool32 IsHMMove2(u16 move) -{ - int i = 0; - while (gHMMoves[i] != 0xFFFF) - { - if (gHMMoves[i++] == move) - return TRUE; - } - return FALSE; -} - -bool8 IsPokeSpriteNotFlipped(u16 species) -{ - return gBaseStats[species].noFlip; -} - -s8 GetMonFlavorRelation(struct Pokemon *mon, u8 flavor) -{ - u8 nature = GetNature(mon); - return gPokeblockFlavorCompatibilityTable[nature * 5 + flavor]; -} - -s8 GetFlavorRelationByPersonality(u32 personality, u8 flavor) -{ - u8 nature = GetNatureFromPersonality(personality); - return gPokeblockFlavorCompatibilityTable[nature * 5 + flavor]; -} - -bool8 IsTradedMon(struct Pokemon *mon) -{ - u8 otName[OT_NAME_LENGTH + 1]; - u32 otId; - GetMonData(mon, MON_DATA_OT_NAME, otName); - otId = GetMonData(mon, MON_DATA_OT_ID, 0); - return IsOtherTrainer(otId, otName); -} - -bool8 IsOtherTrainer(u32 otId, u8 *otName) -{ - if (otId == - (gSaveBlock2Ptr->playerTrainerId[0] - | (gSaveBlock2Ptr->playerTrainerId[1] << 8) - | (gSaveBlock2Ptr->playerTrainerId[2] << 16) - | (gSaveBlock2Ptr->playerTrainerId[3] << 24))) - { - int i; - - for (i = 0; otName[i] != EOS; i++) - if (otName[i] != gSaveBlock2Ptr->playerName[i]) - return TRUE; - return FALSE; - } - - return TRUE; -} - -void MonRestorePP(struct Pokemon *mon) -{ - BoxMonRestorePP(&mon->box); -} - -void BoxMonRestorePP(struct BoxPokemon *boxMon) -{ - int i; - - for (i = 0; i < 4; i++) - { - if (GetBoxMonData(boxMon, MON_DATA_MOVE1 + i, 0)) - { - u16 move = GetBoxMonData(boxMon, MON_DATA_MOVE1 + i, 0); - u16 bonus = GetBoxMonData(boxMon, MON_DATA_PP_BONUSES, 0); - u8 pp = CalculatePPWithBonus(move, bonus, i); - SetBoxMonData(boxMon, MON_DATA_PP1 + i, &pp); - } - } -} - -void sub_806E994(void) -{ - gLastUsedAbility = gBattleStruct->field_B0; - - gBattleTextBuff1[0] = B_BUFF_PLACEHOLDER_BEGIN; - gBattleTextBuff1[1] = B_BUFF_MON_NICK_WITH_PREFIX; - gBattleTextBuff1[2] = gBattleStruct->field_49; - gBattleTextBuff1[4] = B_BUFF_EOS; - - if (!GetBattlerSide(gBattleStruct->field_49)) - gBattleTextBuff1[3] = pokemon_order_func(gBattlerPartyIndexes[gBattleStruct->field_49]); - else - gBattleTextBuff1[3] = gBattlerPartyIndexes[gBattleStruct->field_49]; - - PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff2, gBankInMenu, pokemon_order_func(gBattlerPartyIndexes[gBankInMenu])) - - BattleStringExpandPlaceholders(gText_PkmnsXPreventsSwitching, gStringVar4); -} - -struct PokeItem -{ - u16 species; - u16 item; -}; - -extern const struct PokeItem gAlteringCaveWildMonHeldItems[9]; - -static s32 GetWildMonTableIdInAlteringCave(u16 species) -{ - s32 i; - for (i = 0; i < (s32) ARRAY_COUNT(gAlteringCaveWildMonHeldItems); i++) - if (gAlteringCaveWildMonHeldItems[i].species == species) - return i; - return 0; -} - -void SetWildMonHeldItem(void) -{ - if (!(gBattleTypeFlags & (BATTLE_TYPE_LEGENDARY | BATTLE_TYPE_TRAINER | BATTLE_TYPE_PYRAMID | BATTLE_TYPE_PIKE))) - { - u16 rnd = Random() % 100; - u16 species = GetMonData(&gEnemyParty[0], MON_DATA_SPECIES, 0); - u16 var1 = 45; - u16 var2 = 95; - if (!GetMonData(&gPlayerParty[0], MON_DATA_SANITY_BIT3, 0) - && GetMonAbility(&gPlayerParty[0]) == ABILITY_COMPOUND_EYES) - { - var1 = 20; - var2 = 80; - } - if (gMapHeader.mapDataId == 0x1A4) - { - s32 alteringCaveId = GetWildMonTableIdInAlteringCave(species); - if (alteringCaveId != 0) - { - if (rnd < var2) - return; - SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gAlteringCaveWildMonHeldItems[alteringCaveId].item); - } - else - { - if (rnd < var1) - return; - if (rnd < var2) - SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gBaseStats[species].item1); - else - SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gBaseStats[species].item2); - } - } - else - { - if (gBaseStats[species].item1 == gBaseStats[species].item2 && gBaseStats[species].item1 != 0) - { - SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gBaseStats[species].item1); - } - else - { - if (rnd < var1) - return; - if (rnd < var2) - SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gBaseStats[species].item1); - else - SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gBaseStats[species].item2); - } - } - } -} - -bool8 IsMonShiny(struct Pokemon *mon) -{ - u32 otId = GetMonData(mon, MON_DATA_OT_ID, 0); - u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0); - return IsShinyOtIdPersonality(otId, personality); -} - -bool8 IsShinyOtIdPersonality(u32 otId, u32 personality) -{ - bool8 retVal = FALSE; - u32 shinyValue = HIHALF(otId) ^ LOHALF(otId) ^ HIHALF(personality) ^ LOHALF(personality); - if (shinyValue < 8) - retVal = TRUE; - return retVal; -} - -const u8 *GetTrainerPartnerName(void) -{ - if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) - { - if (gPartnerTrainerId == STEVEN_PARTNER_ID) - { - return gTrainers[TRAINER_STEVEN].trainerName; - } - else - { - GetFrontierTrainerName(gStringVar1, gPartnerTrainerId); - return gStringVar1; - } - } - else - { - u8 id = GetMultiplayerId(); - return gLinkPlayers[GetBattlerMultiplayerId(gLinkPlayers[id].lp_field_18 ^ 2)].name; - } -} - -#define READ_PTR_FROM_TASK(taskId, dataId) \ - (void*)( \ - ((u16)(gTasks[taskId].data[dataId]) | \ - ((u16)(gTasks[taskId].data[dataId + 1]) << 0x10))) - -#define STORE_PTR_IN_TASK(ptr, taskId, dataId) \ -{ \ - gTasks[taskId].data[dataId] = (u32)(ptr); \ - gTasks[taskId].data[dataId + 1] = (u32)(ptr) >> 0x10; \ -} - -static void Task_AnimateAfterDelay(u8 taskId) -{ - if (--gTasks[taskId].data[3] == 0) - { - LaunchAnimationTaskForFrontSprite(READ_PTR_FROM_TASK(taskId, 0), gTasks[taskId].data[2]); - DestroyTask(taskId); - } -} - -static void Task_PokemonSummaryAnimateAfterDelay(u8 taskId) -{ - if (--gTasks[taskId].data[3] == 0) - { - StartMonSummaryAnimation(READ_PTR_FROM_TASK(taskId, 0), gTasks[taskId].data[2]); - sub_81C488C(0xFF); - DestroyTask(taskId); - } -} - -void BattleAnimateFrontSprite(struct Sprite* sprite, u16 species, bool8 noCry, u8 arg3) -{ - if (gHitMarker & HITMARKER_NO_ANIMATIONS && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000))) - DoMonFrontSpriteAnimation(sprite, species, noCry, arg3 | 0x80); - else - DoMonFrontSpriteAnimation(sprite, species, noCry, arg3); -} - -extern void SpriteCallbackDummy_2(struct Sprite*); - -void DoMonFrontSpriteAnimation(struct Sprite* sprite, u16 species, bool8 noCry, u8 arg3) -{ - s8 pan; - switch (arg3 & 0x7F) - { - case 0: - pan = -25; - break; - case 1: - pan = 25; - break; - default: - pan = 0; - break; - } - if (arg3 & 0x80) - { - if (!noCry) - PlayCry1(species, pan); - sprite->callback = SpriteCallbackDummy; - } - else - { - if (!noCry) - { - PlayCry1(species, pan); - if (HasTwoFramesAnimation(species)) - StartSpriteAnim(sprite, 1); - } - if (gMonAnimationDelayTable[species - 1] != 0) - { - u8 taskId = CreateTask(Task_AnimateAfterDelay, 0); - STORE_PTR_IN_TASK(sprite, taskId, 0); - gTasks[taskId].data[2] = gMonFrontAnimIdsTable[species - 1]; - gTasks[taskId].data[3] = gMonAnimationDelayTable[species - 1]; - } - else - { - LaunchAnimationTaskForFrontSprite(sprite, gMonFrontAnimIdsTable[species - 1]); - } - sprite->callback = SpriteCallbackDummy_2; - } -} - -void PokemonSummaryDoMonAnimation(struct Sprite* sprite, u16 species, bool8 oneFrame) -{ - if (!oneFrame && HasTwoFramesAnimation(species)) - StartSpriteAnim(sprite, 1); - if (gMonAnimationDelayTable[species - 1] != 0) - { - u8 taskId = CreateTask(Task_PokemonSummaryAnimateAfterDelay, 0); - STORE_PTR_IN_TASK(sprite, taskId, 0); - gTasks[taskId].data[2] = gMonFrontAnimIdsTable[species - 1]; - gTasks[taskId].data[3] = gMonAnimationDelayTable[species - 1]; - sub_81C488C(taskId); - SetSpriteCB_MonAnimDummy(sprite); - } - else - { - StartMonSummaryAnimation(sprite, gMonFrontAnimIdsTable[species - 1]); - } -} - -void sub_806EE98(void) -{ - u8 delayTaskId = FindTaskIdByFunc(Task_PokemonSummaryAnimateAfterDelay); - if (delayTaskId != 0xFF) - DestroyTask(delayTaskId); -} - -void BattleAnimateBackSprite(struct Sprite* sprite, u16 species) -{ - if (gHitMarker & HITMARKER_NO_ANIMATIONS && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000))) - { - sprite->callback = SpriteCallbackDummy; - } - else - { - LaunchAnimationTaskForBackSprite(sprite, GetSpeciesBackAnimSet(species)); - sprite->callback = SpriteCallbackDummy_2; - } -} - -u8 sub_806EF08(u8 arg0) -{ - s32 i; - s32 var = 0; - u8 multiplayerId = GetMultiplayerId(); - switch (gLinkPlayers[multiplayerId].lp_field_18) - { - case 0: - case 2: - var = (arg0 != 0) ? 1 : 3; - break; - case 1: - case 3: - var = (arg0 != 0) ? 2 : 0; - break; - } - for (i = 0; i < 4; i++) - { - if (gLinkPlayers[i].lp_field_18 == (s16)(var)) - break; - } - return i; -} - -u8 sub_806EF84(u8 arg0, u8 arg1) -{ - s32 i; - s32 var = 0; - switch (gLinkPlayers[arg1].lp_field_18) - { - case 0: - case 2: - var = (arg0 != 0) ? 1 : 3; - break; - case 1: - case 3: - var = (arg0 != 0) ? 2 : 0; - break; - } - for (i = 0; i < 4; i++) - { - if (gLinkPlayers[i].lp_field_18 == (s16)(var)) - break; - } - return i; -} - -extern const u8 gFacilityClassToPicIndex[]; - -u16 sub_806EFF0(u16 arg0) -{ - return gFacilityClassToPicIndex[arg0]; -} - -u16 PlayerGenderToFrontTrainerPicId(u8 playerGender) -{ - if (playerGender) - return sub_806EFF0(0x3F); - else - return sub_806EFF0(0x3C); -} - -extern const u8 gTrainerClassNames[][13]; - -void HandleSetPokedexFlag(u16 nationalNum, u8 caseId, u32 personality) -{ - u8 getFlagCaseId = (caseId == FLAG_SET_SEEN) ? FLAG_GET_SEEN : FLAG_GET_CAUGHT; - if (!GetSetPokedexFlag(nationalNum, getFlagCaseId)) // don't set if it's already set - { - GetSetPokedexFlag(nationalNum, caseId); - if (NationalPokedexNumToSpecies(nationalNum) == SPECIES_UNOWN) - gSaveBlock2Ptr->pokedex.unownPersonality = personality; - if (NationalPokedexNumToSpecies(nationalNum) == SPECIES_SPINDA) - gSaveBlock2Ptr->pokedex.spindaPersonality = personality; - } -} - -const u8 *GetTrainerClassNameFromId(u16 trainerId) -{ - if (trainerId > NO_OF_TRAINERS) - trainerId = 0; - return gTrainerClassNames[gTrainers[trainerId].trainerClass]; -} - -const u8 *GetTrainerNameFromId(u16 trainerId) -{ - if (trainerId > NO_OF_TRAINERS) - trainerId = 0; - return gTrainers[trainerId].trainerName; -} - -bool8 HasTwoFramesAnimation(u16 species) -{ - return (species != SPECIES_CASTFORM - && species != SPECIES_DEOXYS - && species != SPECIES_SPINDA - && species != SPECIES_UNOWN); -} - -bool8 sub_806F104(void) -{ - if (gMain.inBattle && gBattleTypeFlags & (BATTLE_TYPE_FRONTIER)) - return TRUE; - if (!gMain.inBattle && (InBattlePike() || InBattlePyramid())) - return TRUE; - return FALSE; -} - -/* - -extern const struct SpriteTemplate gUnknown_08329D98[]; - -struct Unknown_806F160_Struct -{ - u8 field_0; - u8 field_1; - u8 field_2; - u8 field_3; - u8 field_4; - u8 field_5; - u8 field_6; - u8 field_7; - u8 field_8; - u8 field_9; - u8 field_A; - u8 field_B; - struct SpriteTemplate* templates; -}; - -void sub_806F160(struct Unknown_806F160_Struct* structPtr) -{ - u16 i, j; - for (i = 0; i < structPtr->field_0; i++) - { - structPtr->templates[i] = gUnknown_08329D98[i]; - for (j = 0; j < structPtr->field_1) - { - // no clue what the pointer in the struct point to :/ - } - } -} */ - diff --git a/src/pokemon_summary_screen.c b/src/pokemon_summary_screen.c index e11ba881e..1e5245d70 100644 --- a/src/pokemon_summary_screen.c +++ b/src/pokemon_summary_screen.c @@ -20,6 +20,12 @@ #include "task.h" #include "text.h" #include "window.h" +#include "event_data.h" +#include "gpu_regs.h" +#include "menu.h" +#include "international_string_util.h" +#include "scanline_effect.h" +#include "menu_helpers.h" struct ContestMove { @@ -36,16 +42,12 @@ struct ContestEffect u8 jam; }; - - extern struct UnkSummaryStruct* gUnknown_0203CF1C; extern struct BgTemplate gUnknown_0861CBB4; extern u8 gUnknown_0203CF20; extern struct MusicPlayerInfo gMPlayInfo_BGM; extern s8 gUnknown_0861CC1C[]; -extern u8 gUnknown_08329D22[]; extern u8 gUnknown_0203CF21; -extern u16 gSpecialVar_0x8005; extern struct UnkStruct_61CC04 gUnknown_0861CC04; extern struct UnkStruct_61CC04 gUnknown_0861CC10; extern struct UnkStruct_61CC04 gUnknown_0861CBEC; @@ -67,20 +69,9 @@ extern u8 gUnknown_0861CE7B[]; extern struct WindowTemplate gUnknown_0861CCEC; extern struct WindowTemplate gUnknown_0861CD14; -extern void sub_806F2AC(u8 a, u8 b); void sub_81C488C(u8 a); -extern void do_scheduled_bg_tilemap_copies_to_vram(void); extern u8 sub_81221EC(); extern u8 sub_81221AC(); -extern void SetVBlankHBlankCallbacksToNull(); -extern void ResetVramOamAndBgCntRegs(); -extern void clear_scheduled_bg_copies_to_vram(); -extern void ScanlineEffect_Stop(); -extern void ResetBgsAndClearDma3BusyFlags(u32 leftoverFireRedLeafGreenVariable); -extern void ShowBg(u8 a); -extern void SetGpuReg(u8 regOffset, u16 value); -extern void schedule_bg_copy_tilemap_to_vram(u8 a); -extern void SetBgTilemapBuffer(u8 bg, void *tilemap); extern u8 gUnknown_08D9862C; extern u8 gUnknown_08D98CC8; extern u8 gUnknown_08D987FC; @@ -95,9 +86,6 @@ extern struct CompressedSpritePalette gUnknown_0861D100; extern struct CompressedSpritePalette gUnknown_0861D07C; extern u8 gMoveTypes_Pal; extern u8 gUnknown_08D97D0C; -extern void reset_temp_tile_data_buffers(); -extern void decompress_and_copy_tile_data_to_vram(u8 a, void* tiledata, u8 b, u8 c, u8 d); -extern u8 free_temp_tile_data_buffers_if_possible(); extern void sub_81C1E20(u8 taskId); extern u8 *GetMonNickname(struct Pokemon *mon, u8 *dest); extern u16 SpeciesToPokedexNum(u16 species); @@ -160,11 +148,7 @@ extern u8 gText_ThreeDashes[]; extern u8 gUnknown_0861CE97[]; extern struct BattleMove gBattleMoves[]; -extern u32 ChangeBgX(u8 bg, u32 value, u8 op); extern void sub_8199C30(u8 a, u8 b, u8 c, u8 d, u8 e, u8 f); -extern void AddTextPrinterParameterized2(u8 windowId, u8 fontId, u8 x, u8 y, u8 letterSpacing, u8 lineSpacing, const u8* colors, s8 speed, u8 *str); -extern s32 GetStringCenterAlignXOffset(u8 fontId, u8 *str, s32 totalWidth); -extern s32 GetStringRightAlignXOffset(u8 fontId, u8 *str, s32 totalWidth); extern bool8 sub_81A6BF4(); extern bool8 sub_81B9E94(); extern void UnkTextUtil_Reset(); @@ -1435,7 +1419,7 @@ void sub_81C14BC(struct Pokemon *mon, u8 swappingFromId, u8 swappingToId) *ppBonusesPtr = localPpBonuses; } #else -__attribute__((naked)) +ASM_DIRECT void sub_81C14BC(struct Pokemon *mon, u8 swappingFromId, u8 swappingToId) { asm(".syntax unified\n\ @@ -1646,7 +1630,7 @@ void sub_81C15EC(struct BoxPokemon *mon, u8 swappingFromId, u8 swappingToId) *ppBonusesPtr = localPpBonuses; } #else -__attribute__((naked)) +ASM_DIRECT void sub_81C15EC(struct BoxPokemon *mon, u8 swappingFromId, u8 swappingToId) { asm(".syntax unified\n\ @@ -2057,7 +2041,7 @@ void sub_81C1CB0(struct UnkStruct_61CC04 *a, u16 *b, u8 c, u8 d) Free(alloced); } #else -__attribute__((naked)) +ASM_DIRECT void sub_81C1CB0(struct UnkStruct_61CC04 *a, u16 *b, u8 c, u8 d) { asm(".syntax unified\n\ @@ -2359,7 +2343,7 @@ void sub_81C2194(u16 *a, u16 b, u8 c) } } #else -__attribute__((naked)) +ASM_DIRECT void sub_81C2194(u16 *a, u16 b, u8 c) { asm(".syntax unified\n\ @@ -2808,7 +2792,7 @@ u8 sub_81C2D2C(struct WindowTemplate *template, u8 a) return r4[a]; } #else -__attribute__((naked)) +ASM_DIRECT u8 sub_81C2D2C(struct WindowTemplate *template, u8 a) { asm(".syntax unified\n\ @@ -2853,7 +2837,7 @@ void sub_81C2D68(u8 a) } } #else -__attribute__((naked)) +ASM_DIRECT void sub_81C2D68(u8 a) { asm(".syntax unified\n\ @@ -3110,7 +3094,7 @@ void sub_81C335C() sub_81C25A4(r4, gText_FiveMarks, r5, 1, 0, 1); } #else -__attribute__((naked)) +ASM_DIRECT void sub_81C335C() { asm(".syntax unified\n\ @@ -3453,7 +3437,7 @@ void sub_81C3B08(u8 a) sub_81C25A4(sp, text, offset, (a<<4), 0, r5); } #else -__attribute__((naked)) +ASM_DIRECT void sub_81C3B08(u8 a) { asm(".syntax unified\n\ diff --git a/src/recorded_battle.c b/src/recorded_battle.c index fc576462b..4cb2eab49 100644 --- a/src/recorded_battle.c +++ b/src/recorded_battle.c @@ -13,23 +13,15 @@ #include "util.h" #include "task.h" #include "text.h" +#include "battle_setup.h" -#define BANK_RECORD_SIZE 664 +#define BATTLER_RECORD_SIZE 664 #define ILLEGAL_BATTLE_TYPES ((BATTLE_TYPE_LINK | BATTLE_TYPE_SAFARI | BATTLE_TYPE_FIRST_BATTLE \ | BATTLE_TYPE_WALLY_TUTORIAL | BATTLE_TYPE_ROAMER | BATTLE_TYPE_EREADER_TRAINER \ | BATTLE_TYPE_KYOGRE_GROUDON | BATTLE_TYPE_LEGENDARY | BATTLE_TYPE_REGI \ | BATTLE_TYPE_RECORDED | BATTLE_TYPE_x4000000 | BATTLE_TYPE_SECRET_BASE \ | BATTLE_TYPE_GROUDON | BATTLE_TYPE_KYOGRE | BATTLE_TYPE_RAYQUAZA)) -extern u32 gBattleTypeFlags; -extern u16 gTrainerBattleOpponent_A; -extern u16 gTrainerBattleOpponent_B; -extern u16 gPartnerTrainerId; -extern u8 gActiveBattler; -extern u8 gBattlersCount; -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; -extern struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT]; -extern u16 gChosenMoveByBattler[MAX_BATTLERS_COUNT]; extern u8 gUnknown_03001278; extern u8 gUnknown_03001279; @@ -38,7 +30,7 @@ struct PlayerInfo u32 trainerId; u8 name[PLAYER_NAME_LENGTH]; u8 gender; - u16 bank; + u16 battlerId; u16 language; }; @@ -58,7 +50,7 @@ struct RecordedBattleSave u8 playersLanguage[MAX_BATTLERS_COUNT]; u32 rngSeed; u32 battleFlags; - u8 playersBank[MAX_BATTLERS_COUNT]; + u8 playersBattlers[MAX_BATTLERS_COUNT]; u16 opponentA; u16 opponentB; u16 partnerId; @@ -75,13 +67,13 @@ struct RecordedBattleSave u16 field_50E[6]; u8 field_51A; u8 field_51B; - u8 battleRecord[MAX_BATTLERS_COUNT][BANK_RECORD_SIZE]; + u8 battleRecord[MAX_BATTLERS_COUNT][BATTLER_RECORD_SIZE]; u32 checksum; }; EWRAM_DATA u32 gRecordedBattleRngSeed = 0; EWRAM_DATA u32 gBattlePalaceMoveSelectionRngValue = 0; -EWRAM_DATA static u8 sBattleRecords[MAX_BATTLERS_COUNT][BANK_RECORD_SIZE] = {0}; +EWRAM_DATA static u8 sBattleRecords[MAX_BATTLERS_COUNT][BATTLER_RECORD_SIZE] = {0}; EWRAM_DATA static u16 sRecordedBytesNo[MAX_BATTLERS_COUNT] = {0}; EWRAM_DATA static u16 sUnknown_0203C79C[4] = {0}; EWRAM_DATA static u16 sUnknown_0203C7A4[4] = {0}; @@ -108,7 +100,6 @@ EWRAM_DATA static u16 sUnknown_0203CCDC[6] = {0}; EWRAM_DATA static u8 sUnknown_0203CCE8 = 0; extern u32 sub_81A513C(void); -extern void PlayMapChosenOrBattleBGM(bool8); // this file's functions static u8 sub_8185278(u8 *arg0, u8 *arg1, u8 *arg2); @@ -131,7 +122,7 @@ void sub_8184DA4(u8 arg0) if (arg0 == 1) { - for (j = 0; j < BANK_RECORD_SIZE; j++) + for (j = 0; j < BATTLER_RECORD_SIZE; j++) { sBattleRecords[i][j] |= 0xFF; } @@ -168,7 +159,7 @@ void sub_8184E58(void) { sRecordedBattle_Players[i].trainerId = gLinkPlayers[i].trainerId; sRecordedBattle_Players[i].gender = gLinkPlayers[i].gender; - sRecordedBattle_Players[i].bank = gLinkPlayers[i].lp_field_18; + sRecordedBattle_Players[i].battlerId = gLinkPlayers[i].lp_field_18; sRecordedBattle_Players[i].language = gLinkPlayers[i].language; if (i < linkPlayersCount) @@ -192,7 +183,7 @@ void sub_8184E58(void) | (gSaveBlock2Ptr->playerTrainerId[3] << 24); sRecordedBattle_Players[0].gender = gSaveBlock2Ptr->playerGender; - sRecordedBattle_Players[0].bank = 0; + sRecordedBattle_Players[0].battlerId = 0; sRecordedBattle_Players[0].language = gGameLanguage; for (i = 0; i < PLAYER_NAME_LENGTH; i++) @@ -200,31 +191,31 @@ void sub_8184E58(void) } } -void RecordedBattle_SetBattlerAction(u8 bank, u8 action) +void RecordedBattle_SetBattlerAction(u8 battlerId, u8 action) { - if (sRecordedBytesNo[bank] < BANK_RECORD_SIZE && sUnknown_0203C7AC != 2) + if (sRecordedBytesNo[battlerId] < BATTLER_RECORD_SIZE && sUnknown_0203C7AC != 2) { - sBattleRecords[bank][sRecordedBytesNo[bank]++] = action; + sBattleRecords[battlerId][sRecordedBytesNo[battlerId]++] = action; } } -void RecordedBattle_ClearBattlerAction(u8 bank, u8 bytesToClear) +void RecordedBattle_ClearBattlerAction(u8 battlerId, u8 bytesToClear) { s32 i; for (i = 0; i < bytesToClear; i++) { - sRecordedBytesNo[bank]--; - sBattleRecords[bank][sRecordedBytesNo[bank]] |= 0xFF; - if (sRecordedBytesNo[bank] == 0) + sRecordedBytesNo[battlerId]--; + sBattleRecords[battlerId][sRecordedBytesNo[battlerId]] |= 0xFF; + if (sRecordedBytesNo[battlerId] == 0) break; } } -u8 RecordedBattle_GetBattlerAction(u8 bank) +u8 RecordedBattle_GetBattlerAction(u8 battlerId) { // trying to read past array or invalid action byte, battle is over - if (sRecordedBytesNo[bank] >= BANK_RECORD_SIZE || sBattleRecords[bank][sRecordedBytesNo[bank]] == 0xFF) + if (sRecordedBytesNo[battlerId] >= BATTLER_RECORD_SIZE || sBattleRecords[battlerId][sRecordedBytesNo[battlerId]] == 0xFF) { gSpecialVar_Result = gBattleOutcome = B_OUTCOME_PLAYER_TELEPORTED; // hah ResetPaletteFadeControl(); @@ -234,7 +225,7 @@ u8 RecordedBattle_GetBattlerAction(u8 bank) } else { - return sBattleRecords[bank][sRecordedBytesNo[bank]++]; + return sBattleRecords[battlerId][sRecordedBytesNo[battlerId]++]; } } @@ -358,7 +349,7 @@ u32 MoveRecordedBattleToSaveData(void) } battleSave->playersGender[i] = sRecordedBattle_Players[i].gender; battleSave->playersLanguage[i] = sRecordedBattle_Players[i].language; - battleSave->playersBank[i] = sRecordedBattle_Players[i].bank; + battleSave->playersBattlers[i] = sRecordedBattle_Players[i].battlerId; battleSave->playersTrainerId[i] = sRecordedBattle_Players[i].trainerId; } @@ -375,16 +366,16 @@ u32 MoveRecordedBattleToSaveData(void) } else if (sRecordedBattle_BattleFlags & BATTLE_TYPE_MULTI) { - switch (sRecordedBattle_Players[0].bank) + switch (sRecordedBattle_Players[0].battlerId) { case 0: case 2: - if (!(sRecordedBattle_Players[gUnknown_0203C7B4].bank & 1)) + if (!(sRecordedBattle_Players[gUnknown_0203C7B4].battlerId & 1)) battleSave->battleFlags |= BATTLE_TYPE_x80000000; break; case 1: case 3: - if ((sRecordedBattle_Players[gUnknown_0203C7B4].bank & 1)) + if ((sRecordedBattle_Players[gUnknown_0203C7B4].battlerId & 1)) battleSave->battleFlags |= BATTLE_TYPE_x80000000; break; } @@ -484,7 +475,7 @@ u32 MoveRecordedBattleToSaveData(void) } #else -__attribute__((naked)) +ASM_DIRECT u32 MoveRecordedBattleToSaveData(void) { asm(".syntax unified\n\ @@ -1349,7 +1340,7 @@ static void SetRecordedBattleVarsFromSave(struct RecordedBattleSave *src) } gLinkPlayers[i].gender = src->playersGender[i]; gLinkPlayers[i].language = src->playersLanguage[i]; - gLinkPlayers[i].lp_field_18 = src->playersBank[i]; + gLinkPlayers[i].lp_field_18 = src->playersBattlers[i]; gLinkPlayers[i].trainerId = src->playersTrainerId[i]; if (var) @@ -1388,7 +1379,7 @@ static void SetRecordedBattleVarsFromSave(struct RecordedBattleSave *src) for (i = 0; i < MAX_BATTLERS_COUNT; i++) { - for (j = 0; j < BANK_RECORD_SIZE; j++) + for (j = 0; j < BATTLER_RECORD_SIZE; j++) { sBattleRecords[i][j] = src->battleRecord[i][j]; } @@ -1456,7 +1447,7 @@ static void RecordedBattle_RestoreSavedParties(void) } } -u8 GetActiveBankLinkPlayerGender(void) +u8 GetActiveBattlerLinkPlayerGender(void) { s32 i; @@ -1497,7 +1488,7 @@ u8 GetTextSpeedInRecordedBattle(void) return sRecordedBattle_TextSpeed; } -void RecordedBattle_CopyBankMoves(void) +void RecordedBattle_CopyBattlerMoves(void) { s32 i; @@ -1518,32 +1509,32 @@ void RecordedBattle_CopyBankMoves(void) void sub_818603C(u8 arg0) { - s32 bank, j, k; + s32 battlerId, j, k; if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000)) return; - for (bank = 0; bank < gBattlersCount; bank++) + for (battlerId = 0; battlerId < gBattlersCount; battlerId++) { - if (GetBattlerSide(bank) != B_SIDE_OPPONENT) // player's side only + if (GetBattlerSide(battlerId) != B_SIDE_OPPONENT) // player's side only { if (arg0 == 1) { for (j = 0; j < 4; j++) { - if (gBattleMons[bank].moves[j] != sRecordedBattle_PlayerMonMoves[bank / 2][j]) + if (gBattleMons[battlerId].moves[j] != sRecordedBattle_PlayerMonMoves[battlerId / 2][j]) break; } if (j != 4) // player's mon's move has been changed { - RecordedBattle_SetBattlerAction(bank, ACTION_MOVE_CHANGE); + RecordedBattle_SetBattlerAction(battlerId, ACTION_MOVE_CHANGE); for (j = 0; j < 4; j++) { for (k = 0; k < 4; k++) { - if (gBattleMons[bank].moves[j] == sRecordedBattle_PlayerMonMoves[bank / 2][k]) + if (gBattleMons[battlerId].moves[j] == sRecordedBattle_PlayerMonMoves[battlerId / 2][k]) { - RecordedBattle_SetBattlerAction(bank, k); + RecordedBattle_SetBattlerAction(battlerId, k); break; } } @@ -1552,7 +1543,7 @@ void sub_818603C(u8 arg0) } else { - if (sBattleRecords[bank][sRecordedBytesNo[bank]] == ACTION_MOVE_CHANGE) + if (sBattleRecords[battlerId][sRecordedBytesNo[battlerId]] == ACTION_MOVE_CHANGE) { u8 ppBonuses[4]; u8 array1[4]; @@ -1561,58 +1552,58 @@ void sub_818603C(u8 arg0) u8 array3[8]; u8 var; - RecordedBattle_GetBattlerAction(bank); + RecordedBattle_GetBattlerAction(battlerId); for (j = 0; j < 4; j++) { - ppBonuses[j] = ((gBattleMons[bank].ppBonuses & ((3 << (j << 1)))) >> (j << 1)); + ppBonuses[j] = ((gBattleMons[battlerId].ppBonuses & ((3 << (j << 1)))) >> (j << 1)); } for (j = 0; j < 4; j++) { - array1[j] = RecordedBattle_GetBattlerAction(bank); - movePp.moves[j] = gBattleMons[bank].moves[array1[j]]; - movePp.pp[j] = gBattleMons[bank].pp[array1[j]]; + array1[j] = RecordedBattle_GetBattlerAction(battlerId); + movePp.moves[j] = gBattleMons[battlerId].moves[array1[j]]; + movePp.pp[j] = gBattleMons[battlerId].pp[array1[j]]; array3[j] = ppBonuses[array1[j]]; - array2[j] = (gDisableStructs[bank].unk18_b & gBitTable[j]) >> j; + array2[j] = (gDisableStructs[battlerId].unk18_b & gBitTable[j]) >> j; } for (j = 0; j < 4; j++) { - gBattleMons[bank].moves[j] = movePp.moves[j]; - gBattleMons[bank].pp[j] = movePp.pp[j]; + gBattleMons[battlerId].moves[j] = movePp.moves[j]; + gBattleMons[battlerId].pp[j] = movePp.pp[j]; } - gBattleMons[bank].ppBonuses = 0; - gDisableStructs[bank].unk18_b = 0; + gBattleMons[battlerId].ppBonuses = 0; + gDisableStructs[battlerId].unk18_b = 0; for (j = 0; j < 4; j++) { - gBattleMons[bank].ppBonuses |= (array3[j]) << (j << 1); - gDisableStructs[bank].unk18_b |= (array2[j]) << (j); + gBattleMons[battlerId].ppBonuses |= (array3[j]) << (j << 1); + gDisableStructs[battlerId].unk18_b |= (array2[j]) << (j); } - if (!(gBattleMons[bank].status2 & STATUS2_TRANSFORMED)) + if (!(gBattleMons[battlerId].status2 & STATUS2_TRANSFORMED)) { for (j = 0; j < 4; j++) { - ppBonuses[j] = ((GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_PP_BONUSES, NULL) & ((3 << (j << 1)))) >> (j << 1)); + ppBonuses[j] = ((GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PP_BONUSES, NULL) & ((3 << (j << 1)))) >> (j << 1)); } for (j = 0; j < 4; j++) { - movePp.moves[j] = GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_MOVE1 + array1[j], NULL); - movePp.pp[j] = GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_PP1 + array1[j], NULL); + movePp.moves[j] = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_MOVE1 + array1[j], NULL); + movePp.pp[j] = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PP1 + array1[j], NULL); array3[j] = ppBonuses[array1[j]]; } for (j = 0; j < 4; j++) { - SetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_MOVE1 + j, &movePp.moves[j]); - SetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_PP1 + j, &movePp.pp[j]); + SetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_MOVE1 + j, &movePp.moves[j]); + SetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PP1 + j, &movePp.pp[j]); } var = 0; for (j = 0; j < 4; j++) { var |= (array3[j]) << (j << 1); } - SetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_PP_BONUSES, &var); + SetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PP_BONUSES, &var); } - gChosenMoveByBattler[bank] = gBattleMons[bank].moves[*(gBattleStruct->chosenMovePositions + bank)]; + gChosenMoveByBattler[battlerId] = gBattleMons[battlerId].moves[*(gBattleStruct->chosenMovePositions + battlerId)]; } } } diff --git a/src/reset_save_heap.c b/src/reset_save_heap.c index 099edce49..9950f6691 100644 --- a/src/reset_save_heap.c +++ b/src/reset_save_heap.c @@ -15,7 +15,7 @@ void sub_81700F8(void) imeBackup = REG_IME; REG_IME = 0; RegisterRamReset(0x00000001); - ClearGpuRegBits(REG_OFFSET_DISPCNT, 0x80); + ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_FORCED_BLANK); REG_IME = imeBackup; gMain.inBattle = FALSE; SetSaveBlocksPointers(sub_815355C()); diff --git a/src/reshow_battle_screen.c b/src/reshow_battle_screen.c index 925b65de5..cedd3aee4 100644 --- a/src/reshow_battle_screen.c +++ b/src/reshow_battle_screen.c @@ -12,6 +12,7 @@ #include "sprite.h" #include "constants/species.h" #include "battle_interface.h" +#include "battle_anim.h" extern u16 gBattle_BG0_X; extern u16 gBattle_BG0_Y; @@ -21,28 +22,11 @@ extern u16 gBattle_BG2_X; extern u16 gBattle_BG2_Y; extern u16 gBattle_BG3_X; extern u16 gBattle_BG3_Y; -extern u8 gReservedSpritePaletteCount; -extern u8 gActionSelectionCursor[MAX_BATTLERS_COUNT]; -extern u8 gBankInMenu; -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; -extern u8 gBattlersCount; -extern u32 gBattleTypeFlags; -extern u8 gBattlerSpriteIds[MAX_BATTLERS_COUNT]; -extern u8 gBattleMonForms[MAX_BATTLERS_COUNT]; -extern u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT]; -extern struct SpriteTemplate gUnknown_0202499C; extern const union AnimCmd * const * const gMonAnimationsSpriteAnimsPtrTable[]; -extern void ScanlineEffect_Clear(void); -extern void sub_8035658(void); -extern bool8 IsDoubleBattle(void); -extern u8 GetSubstituteSpriteDefault_Y(u8 bank); -extern u8 GetBattlerSpriteDefault_Y(u8 bank); -extern u8 sub_80A82E4(u8 bank); extern void sub_806A068(u16 species, u8 bankIdentity); extern void sub_806A12C(u16 backPicId, u8 bankIdentity); -extern u8 GetBattlerSpriteCoord(u8 bank, u8 caseId); // this file's functions static void CB2_ReshowBattleScreenAfterMenu(void); @@ -175,12 +159,12 @@ static void CB2_ReshowBattleScreenAfterMenu(void) SetBattlerShadowSpriteCallback(opponentBank, species); } - ActionSelectionCreateCursorAt(gActionSelectionCursor[gBankInMenu], 0); + ActionSelectionCreateCursorAt(gActionSelectionCursor[gBattlerInMenuId], 0); - if (gLinkVSyncDisabled != 0 && gReceivedRemoteLinkPlayers != 0) + if (gWirelessCommType != 0 && gReceivedRemoteLinkPlayers != 0) { sub_800E0E8(); - sub_800DFB4(0, 0); + CreateWirelessStatusIndicatorSprite(0, 0); } } break; diff --git a/src/rom_8011DC0.c b/src/rom_8011DC0.c new file mode 100644 index 000000000..9076b611a --- /dev/null +++ b/src/rom_8011DC0.c @@ -0,0 +1,18 @@ + +// Includes +#include "global.h" + +// Static type declarations + +// Static RAM declarations +IWRAM_DATA u32 gUnknown_03000DA0; +IWRAM_DATA u32 gUnknown_03000DA4; +IWRAM_DATA void *gUnknown_03000DA8; +IWRAM_DATA void *gUnknown_03000DAC; +IWRAM_DATA bool32 gUnknown_03000DB0; + +// Static ROM declarations + +// .rodata + +// .text diff --git a/src/safari_zone.c b/src/safari_zone.c index 12da73090..dd3cf3733 100644 --- a/src/safari_zone.c +++ b/src/safari_zone.c @@ -108,7 +108,7 @@ void SafariZoneRetirePrompt(void) void CB2_EndSafariBattle(void) { sSafariZoneFleedMons += gBattleResults.field_1F; - if (gBattleOutcome == B_OUTCOME_CAUGHT_POKE) + if (gBattleOutcome == B_OUTCOME_CAUGHT) sSafariZoneCaughtMons++; if (gNumSafariBalls != 0) { @@ -121,7 +121,7 @@ void CB2_EndSafariBattle(void) gFieldCallback = sub_80AF6F0; SetMainCallback2(c2_load_new_map); } - else if (gBattleOutcome == B_OUTCOME_CAUGHT_POKE) + else if (gBattleOutcome == B_OUTCOME_CAUGHT) { ScriptContext1_SetupScript(EventScript_2A4B9B); ScriptContext1_Stop(); diff --git a/src/scrcmd.c b/src/scrcmd.c index 467b8f320..deb170c68 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -31,7 +31,6 @@ #include "mystery_event_script.h" #include "palette.h" #include "party_menu.h" -#include "pokemon_3.h" #include "pokemon_storage_system.h" #include "random.h" #include "overworld.h" @@ -63,13 +62,6 @@ static EWRAM_DATA u16 sMovingNpcMapBank = 0; static EWRAM_DATA u16 sMovingNpcMapId = 0; static EWRAM_DATA u16 sFieldEffectScriptId = 0; -extern u16 gSpecialVar_0x8000; -extern u16 gSpecialVar_0x8001; -extern u16 gSpecialVar_0x8002; -extern u16 gSpecialVar_0x8004; - -extern u16 gSpecialVar_Result; - extern u16 gSpecialVar_ContestCategory; IWRAM_DATA u8 gUnknown_03000F30; @@ -1536,7 +1528,7 @@ bool8 ScrCmd_braillemessage(struct ScriptContext *ctx) CopyWindowToVram(gUnknown_03000F30, 3); return FALSE; }*/ -__attribute__((naked)) +ASM_DIRECT bool8 ScrCmd_braillemessage(struct ScriptContext *ctx) { asm("push {r4-r7,lr}\n\ diff --git a/src/secret_base.c b/src/secret_base.c index 96fe6edd2..e3c06a75d 100644 --- a/src/secret_base.c +++ b/src/secret_base.c @@ -32,6 +32,7 @@ #include "international_string_util.h" #include "event_data.h" #include "battle.h" +#include "battle_setup.h" #include "rom6.h" #include "decoration.h" #include "link.h" diff --git a/src/text.c b/src/text.c index 6a83d5d15..a2495d068 100644 --- a/src/text.c +++ b/src/text.c @@ -379,7 +379,7 @@ void GenerateFontHalfRowLookupTable(u8 fgColor, u8 bgColor, u8 shadowColor) *(current++) = (shadowColor << 12) | (shadowColor << 8) | (shadowColor << 4) | shadowColor; } #else -__attribute__((naked)) +ASM_DIRECT void GenerateFontHalfRowLookupTable(u8 fgColor, u8 bgColor, u8 shadowColor) { asm("push {r4-r7,lr}\n\ @@ -875,7 +875,7 @@ void DecompressGlyphTile(const u16 *src, u16 *dest) *(dest) = (gFontHalfRowLookupTable[gFontHalfRowOffsets[src[1] & 0xFF]] << 16) | gFontHalfRowLookupTable[gFontHalfRowOffsets[src[1] >> 8]]; } #else -__attribute__((naked)) +ASM_DIRECT void DecompressGlyphTile(const u16 *src, u16 *dest) { asm("push {r4-r7,lr}\n\ @@ -1056,7 +1056,7 @@ u8 GetLastTextColor(u8 colorType) } } -__attribute__((naked)) +ASM_DIRECT void CopyGlyphToWindow(struct TextPrinter *x) { asm("push {r4-r7,lr}\n\ @@ -2285,7 +2285,6 @@ u16 RenderText(struct TextPrinter *textPrinter) else textPrinter->subPrinter.currentX += gUnknown_03002F90[0x80]; } - return 0; case 1: // _08005C78 if (TextPrinterWait(textPrinter)) @@ -1208,7 +1208,7 @@ void PutPokemonTodayFailedOnTheAir(void) { ct = 0xFF; } - if (ct > 2 && (gBattleOutcome == B_OUTCOME_POKE_FLED || gBattleOutcome == B_OUTCOME_WON)) + if (ct > 2 && (gBattleOutcome == B_OUTCOME_MON_FLED || gBattleOutcome == B_OUTCOME_WON)) { sCurTVShowSlot = FindEmptyTVSlotBeyondFirstFiveShowsOfArray(gSaveBlock1Ptr->tvShows); if (sCurTVShowSlot != -1 && HasMixableShowAlreadyBeenSpawnedWithPlayerID(TVSHOW_POKEMON_TODAY_FAILED, FALSE) != TRUE) @@ -2154,7 +2154,7 @@ void sub_80EDE98(TVShow *show) } } #else -__attribute__((naked)) +ASM_DIRECT void sub_80EDE98(TVShow *show) { asm_unified("\tpush {r4-r7,lr}\n" @@ -2406,7 +2406,7 @@ void sub_80EE184(void) case B_OUTCOME_DREW: show->breakingNews.kind = TVSHOW_OFF_AIR; return; - case B_OUTCOME_CAUGHT_POKE: + case B_OUTCOME_CAUGHT: show->breakingNews.outcome = 0; break; case B_OUTCOME_WON: @@ -2417,8 +2417,8 @@ void sub_80EE184(void) case B_OUTCOME_NO_SAFARI_BALLS: show->breakingNews.outcome = 2; break; - case B_OUTCOME_POKE_FLED: - case B_OUTCOME_POKE_TELEPORTED: + case B_OUTCOME_MON_FLED: + case B_OUTCOME_MON_TELEPORTED: show->breakingNews.outcome = 3; break; } @@ -4110,7 +4110,7 @@ void sub_80F0708(void) // FIXME: register allocation shenanigans } } #else -__attribute__((naked)) void sub_80F0708(void) +ASM_DIRECT void sub_80F0708(void) { asm_unified("\tpush {r4-r7,lr}\n" "\tmov r7, r9\n" diff --git a/src/util.c b/src/util.c index 58088c3ee..4f9241b21 100644 --- a/src/util.c +++ b/src/util.c @@ -230,7 +230,7 @@ void CopySpriteTiles(u8 shape, u8 size, u8 *tiles, u16 *tilemap, u8 *output) } #else -__attribute__((naked)) void CopySpriteTiles(u8 shape, u8 size, u8 *tiles, u16 *tilemap, u8 *output) +ASM_DIRECT void CopySpriteTiles(u8 shape, u8 size, u8 *tiles, u16 *tilemap, u8 *output) { asm("\n\ .syntax unified\n\ diff --git a/src/window.c b/src/window.c index 9a892d079..589557d43 100644 --- a/src/window.c +++ b/src/window.c @@ -2,8 +2,11 @@ #include "window.h" #include "malloc.h" -extern u8 gUnknown_03002F60; -extern void* gUnknown_03002F70[]; +u32 filler_03002F58; +u32 filler_03002F5C; +u8 gUnknown_03002F60; +u32 filler_03002F64; +void *gUnknown_03002F70[4]; extern u32 gUnneededFireRedVariable; #define WINDOWS_MAX 32 |