summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/battle_2.c61
-rw-r--r--src/battle_ai_switch_items.c67
-rw-r--r--src/battle_controller_link_opponent.c30
-rw-r--r--src/battle_controller_link_partner.c34
-rw-r--r--src/battle_controller_opponent.c38
-rw-r--r--src/battle_controller_player.c46
-rw-r--r--src/battle_controller_player_partner.c38
-rw-r--r--src/battle_controller_recorded_opponent.c36
-rw-r--r--src/battle_controller_recorded_player.c44
-rw-r--r--src/battle_controller_safari.c12
-rw-r--r--src/battle_controller_wally.c28
-rw-r--r--src/battle_controllers.c2
-rw-r--r--src/battle_dome_cards.c4
-rw-r--r--src/battle_gfx_sfx_util.c1299
-rw-r--r--src/battle_interface.c44
-rw-r--r--src/battle_message.c6
-rw-r--r--src/battle_script_commands.c647
-rw-r--r--src/battle_util.c16
-rw-r--r--src/battle_util2.c219
-rw-r--r--src/berry.c8
-rw-r--r--src/berry_blender.c585
-rwxr-xr-xsrc/braille_puzzles.c30
-rw-r--r--src/calculate_base_damage.c8
-rw-r--r--src/daycare.c1318
-rw-r--r--src/decoration.c58
-rw-r--r--src/egg_hatch.c22
-rw-r--r--src/event_data.c44
-rwxr-xr-xsrc/field_map_obj.c4
-rw-r--r--src/field_region_map.c193
-rwxr-xr-xsrc/field_special_scene.c2
-rw-r--r--src/hall_of_fame.c1552
-rw-r--r--src/heal_location.c83
-rw-r--r--src/item.c4
-rw-r--r--src/lilycove_lady.c14
-rw-r--r--src/lottery_corner.c6
-rw-r--r--src/mail.c2
-rw-r--r--src/new_game.c4
-rw-r--r--src/pokemon_2.c6
-rw-r--r--src/pokemon_3.c6
-rw-r--r--src/pokemon_size_record.c10
-rw-r--r--src/pokemon_storage_system.c123
-rwxr-xr-xsrc/pokemon_summary_screen.c17
-rw-r--r--src/recorded_battle.c1676
-rw-r--r--src/region_map.c1949
-rw-r--r--src/reshow_battle_screen.c14
-rw-r--r--src/safari_zone.c42
-rw-r--r--src/save.c3
-rw-r--r--src/scrcmd.c158
-rw-r--r--src/secret_base.c70
-rw-r--r--src/start_menu.c10
-rw-r--r--src/starter_choose.c391
-rw-r--r--src/text_window.c4
-rw-r--r--src/tv.c176
-rw-r--r--src/walda_phrase.c8
-rw-r--r--src/wild_encounter.c933
55 files changed, 11088 insertions, 1116 deletions
diff --git a/src/battle_2.c b/src/battle_2.c
index 24b43bdbd..2be6f9d77 100644
--- a/src/battle_2.c
+++ b/src/battle_2.c
@@ -43,6 +43,7 @@
#include "tv.h"
#include "safari_zone.h"
#include "battle_string_ids.h"
+#include "data2.h"
struct UnknownStruct6
{
@@ -141,7 +142,6 @@ extern u8 gLastUsedAbility;
extern u8 gUnknown_0203CF00[];
extern const u8* gBattlescriptPtrsForSelection[BATTLE_BANKS_COUNT];
extern const u8* gBattlescriptCurrInstr;
-extern u32 gBattlePalaceMoveSelectionRngValue;
extern u8 gActionsByTurnOrder[BATTLE_BANKS_COUNT];
extern u8 gCurrentTurnActionNumber;
extern u16 gDynamicBasePower;
@@ -353,7 +353,7 @@ static const u8 sUnknown_0831BCF3[] = {4, 4, 4, 4};
void CB2_InitBattle(void)
{
MoveSaveBlocks_ResetHeap();
- AllocateBattleResrouces();
+ AllocateBattleResources();
AllocateBattleSpritesData();
AllocateMonSpritesGfx();
sub_8185F84();
@@ -509,7 +509,7 @@ static void sub_8036A5C(void)
gBattleStruct->field_182 = r6;
*(&gBattleStruct->field_183) = r6 >> 8;
- gBattleStruct->field_183 |= FlagGet(SYS_FRONTIER_PASS) << 7;
+ gBattleStruct->field_183 |= FlagGet(FLAG_SYS_FRONTIER_PASS) << 7;
}
static void SetPlayerBerryDataInBattleStruct(void)
@@ -1610,7 +1610,7 @@ void BattleMainCB2(void)
if (gMain.heldKeys & B_BUTTON && gBattleTypeFlags & BATTLE_TYPE_RECORDED && sub_8186450())
{
- gScriptResult = gBattleOutcome = BATTLE_PLAYER_TELEPORTED;
+ gSpecialVar_Result = gBattleOutcome = BATTLE_PLAYER_TELEPORTED;
ResetPaletteFadeControl();
BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
SetMainCallback2(CB2_QuitRecordedBattle);
@@ -2068,7 +2068,7 @@ static void sub_8038F34(void)
if (!gSaveBlock2Ptr->field_CA9_b && i == monsCount)
{
- if (FlagGet(SYS_FRONTIER_PASS))
+ if (FlagGet(FLAG_SYS_FRONTIER_PASS))
{
FreeAllWindowBuffers();
SetMainCallback2(sub_80392A8);
@@ -2477,15 +2477,6 @@ static void sub_80398D0(struct Sprite *sprite)
}
}
-// to get rid of once the struct is declared in a header
-struct MonCoords
-{
- // This would use a bitfield, but sub_8079F44
- // uses it as a u8 and casting won't match.
- u8 coords; // u8 x:4, y:4;
- u8 y_offset;
-};
-
extern const struct MonCoords gMonFrontPicCoords[];
extern const struct MonCoords gCastformFrontSpriteCoords[];
@@ -2811,7 +2802,7 @@ static void BattleStartClearSetData(void)
if (!(gBattleTypeFlags & BATTLE_TYPE_LINK) && gSaveBlock2Ptr->optionsBattleSceneOff == TRUE)
gHitMarker |= HITMARKER_NO_ANIMATIONS;
}
- else if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000)) && sub_8185FB8())
+ else if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000)) && GetBattleStyleInRecordedBattle())
gHitMarker |= HITMARKER_NO_ANIMATIONS;
gBattleScripting.battleStyle = gSaveBlock2Ptr->optionsBattleStyle;
@@ -2853,9 +2844,9 @@ static void BattleStartClearSetData(void)
*(i + 3 * 8 + (u8*)(gBattleStruct->mirrorMoveArrays) + 0) = 0;
}
- for (i = 0; i < 4; i++)
+ for (i = 0; i < BATTLE_BANKS_COUNT; i++)
{
- *(gBattleStruct->field_294 + i) = 6;
+ *(gBattleStruct->AI_monToSwitchIntoId + i) = 6;
}
gBattleStruct->field_DF = 0;
@@ -2935,8 +2926,8 @@ void SwitchInClearSetData(void)
{
gDisableStructs[gActiveBank].substituteHP = disableStructCopy.substituteHP;
gDisableStructs[gActiveBank].bankWithSureHit = disableStructCopy.bankWithSureHit;
- gDisableStructs[gActiveBank].perishSong1 = disableStructCopy.perishSong1;
- gDisableStructs[gActiveBank].perishSong2 = disableStructCopy.perishSong2;
+ gDisableStructs[gActiveBank].perishSongTimer1 = disableStructCopy.perishSongTimer1;
+ gDisableStructs[gActiveBank].perishSongTimer2 = disableStructCopy.perishSongTimer2;
gDisableStructs[gActiveBank].bankPreventingEscape = disableStructCopy.bankPreventingEscape;
}
@@ -3682,7 +3673,7 @@ static void TryDoEventsBeforeFirstTurn(void)
}
for (i = 0; i < BATTLE_BANKS_COUNT; i++)
{
- *(gBattleStruct->field_5C + i) = 6;
+ *(gBattleStruct->monToSwitchIntoId + i) = 6;
gActionForBanks[i] = ACTION_INIT_VALUE;
gChosenMovesByBanks[i] = MOVE_NONE;
}
@@ -3793,7 +3784,7 @@ void BattleTurnPassed(void)
}
for (i = 0; i < 4; i++)
- *(gBattleStruct->field_5C + i) = 6;
+ *(gBattleStruct->monToSwitchIntoId + i) = 6;
*(&gBattleStruct->field_91) = gAbsentBankFlags;
BattleHandleAddTextPrinter(gText_EmptyString3, 0);
@@ -3884,7 +3875,7 @@ void sub_803BDA0(u8 bank)
gUnknown_0203CF00[i] = *(bank * 3 + i + (u8*)(gBattleStruct->field_60));
r4 = pokemon_order_func(gBattlePartyID[bank]);
- r1 = pokemon_order_func(*(gBattleStruct->field_5C + bank));
+ r1 = pokemon_order_func(*(gBattleStruct->monToSwitchIntoId + bank));
sub_81B8FB0(r4, r1);
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
@@ -3928,11 +3919,11 @@ static void HandleTurnActionSelectionState(void)
switch (gBattleCommunication[gActiveBank])
{
case STATE_TURN_START_RECORD: // recorded battle related on start of every turn
- sub_8185FD0();
+ RecordedBattle_CopyBankMoves();
gBattleCommunication[gActiveBank] = STATE_BEFORE_ACTION_CHOSEN;
break;
case STATE_BEFORE_ACTION_CHOSEN: // choose an action
- *(gBattleStruct->field_5C + gActiveBank) = 6;
+ *(gBattleStruct->monToSwitchIntoId + gActiveBank) = 6;
if (gBattleTypeFlags & BATTLE_TYPE_MULTI
|| !(identity & BIT_MON)
|| gBattleStruct->field_91 & gBitTable[GetBankByIdentity(identity ^ BIT_MON)]
@@ -4050,9 +4041,9 @@ static void HandleTurnActionSelectionState(void)
else
{
if (gActiveBank == 2 && gActionForBanks[0] == ACTION_SWITCH)
- EmitChoosePokemon(0, 0, *(gBattleStruct->field_5C + 0), ABILITY_NONE, gBattleStruct->field_60[gActiveBank]);
+ EmitChoosePokemon(0, 0, *(gBattleStruct->monToSwitchIntoId + 0), ABILITY_NONE, gBattleStruct->field_60[gActiveBank]);
else if (gActiveBank == 3 && gActionForBanks[1] == ACTION_SWITCH)
- EmitChoosePokemon(0, 0, *(gBattleStruct->field_5C + 1), ABILITY_NONE, gBattleStruct->field_60[gActiveBank]);
+ EmitChoosePokemon(0, 0, *(gBattleStruct->monToSwitchIntoId + 1), ABILITY_NONE, gBattleStruct->field_60[gActiveBank]);
else
EmitChoosePokemon(0, 0, 6, ABILITY_NONE, gBattleStruct->field_60[gActiveBank]);
}
@@ -4339,7 +4330,7 @@ static void HandleTurnActionSelectionState(void)
for (i = 0; i < gNoOfAllBanks; i++)
{
if (gActionForBanks[i] == ACTION_SWITCH)
- sub_80571DC(i, *(gBattleStruct->field_5C + i));
+ sub_80571DC(i, *(gBattleStruct->monToSwitchIntoId + i));
}
}
}
@@ -4363,7 +4354,7 @@ static bool8 sub_803CDB8(void)
static void sub_803CDF8(void)
{
- *(gBattleStruct->field_5C + gActiveBank) = gBattleBufferB[gActiveBank][1];
+ *(gBattleStruct->monToSwitchIntoId + gActiveBank) = gBattleBufferB[gActiveBank][1];
RecordedBattle_SetBankAction(gActiveBank, gBattleBufferB[gActiveBank][1]);
if (gBattleTypeFlags & BATTLE_TYPE_LINK && gBattleTypeFlags & BATTLE_TYPE_MULTI)
@@ -4435,7 +4426,7 @@ u8 GetWhoStrikesFirst(u8 bank1, u8 bank2, bool8 ignoreChosenMoves)
// badge boost
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000 | BATTLE_TYPE_FRONTIER))
- && FlagGet(BADGE03_GET)
+ && FlagGet(FLAG_BADGE03_GET)
&& GetBankSide(bank1) == SIDE_PLAYER)
{
speedBank1 = (speedBank1 * 110) / 100;
@@ -4469,7 +4460,7 @@ u8 GetWhoStrikesFirst(u8 bank1, u8 bank2, bool8 ignoreChosenMoves)
// badge boost
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000 | BATTLE_TYPE_FRONTIER))
- && FlagGet(BADGE03_GET)
+ && FlagGet(FLAG_BADGE03_GET)
&& GetBankSide(bank2) == SIDE_PLAYER)
{
speedBank2 = (speedBank2 * 110) / 100;
@@ -4758,7 +4749,7 @@ static void HandleEndTurn_BattleWon(void)
if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000))
{
- gScriptResult = gBattleOutcome;
+ gSpecialVar_Result = gBattleOutcome;
gBattleTextBuff1[0] = gBattleOutcome;
gBankAttacker = GetBankByIdentity(IDENTITY_PLAYER_MON1);
gBattlescriptCurrInstr = BattleScript_LinkBattleWonOrLost;
@@ -4767,7 +4758,7 @@ static void HandleEndTurn_BattleWon(void)
else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER
&& gBattleTypeFlags & (BATTLE_TYPE_FRONTIER | BATTLE_TYPE_x4000000 | BATTLE_TYPE_EREADER_TRAINER))
{
- BattleMusicStop();
+ BattleStopLowHpSound();
gBattlescriptCurrInstr = BattleScript_FrontierTrainerBattleWon;
if (gTrainerBattleOpponent_A == TRAINER_OPPONENT_3FE)
@@ -4777,7 +4768,7 @@ static void HandleEndTurn_BattleWon(void)
}
else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && !(gBattleTypeFlags & BATTLE_TYPE_LINK))
{
- BattleMusicStop();
+ BattleStopLowHpSound();
gBattlescriptCurrInstr = BattleScript_LocalTrainerBattleWon;
switch (gTrainers[gTrainerBattleOpponent_A].trainerClass)
@@ -5020,7 +5011,7 @@ static void ReturnFromBattleToOverworld(void)
if (gBattleTypeFlags & BATTLE_TYPE_LINK && gReceivedRemoteLinkPlayers != 0)
return;
- gScriptResult = gBattleOutcome;
+ gSpecialVar_Result = gBattleOutcome;
gMain.inBattle = 0;
gMain.callback1 = gPreBattleCallback1;
@@ -5618,7 +5609,7 @@ static void HandleAction_NothingIsFainted(void)
static void HandleAction_ActionFinished(void)
{
- *(gBattleStruct->field_5C + gBanksByTurnOrder[gCurrentTurnActionNumber]) = 6;
+ *(gBattleStruct->monToSwitchIntoId + gBanksByTurnOrder[gCurrentTurnActionNumber]) = 6;
gCurrentTurnActionNumber++;
gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber];
SpecialStatusesClear();
diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c
index a57df85fb..75d144c3d 100644
--- a/src/battle_ai_switch_items.c
+++ b/src/battle_ai_switch_items.c
@@ -36,9 +36,9 @@ static bool8 ShouldUseItem(void);
static bool8 ShouldSwitchIfPerishSong(void)
{
if (gStatuses3[gActiveBank] & STATUS3_PERISH_SONG
- && gDisableStructs[gActiveBank].perishSong1 == 0)
+ && gDisableStructs[gActiveBank].perishSongTimer1 == 0)
{
- *(gBattleStruct->field_294 + gActiveBank) = 6;
+ *(gBattleStruct->AI_monToSwitchIntoId + gActiveBank) = 6;
EmitTwoReturnValues(1, ACTION_SWITCH, 0);
return TRUE;
}
@@ -120,7 +120,7 @@ static bool8 ShouldSwitchIfWonderGuard(void)
if (moveFlags & MOVESTATUS_SUPEREFFECTIVE && Random() % 3 < 2)
{
// we found a mon
- *(gBattleStruct->field_294 + gActiveBank) = i;
+ *(gBattleStruct->AI_monToSwitchIntoId + gActiveBank) = i;
EmitTwoReturnValues(1, ACTION_SWITCH, 0);
return TRUE;
}
@@ -206,9 +206,9 @@ static bool8 FindMonThatAbsorbsOpponentsMove(void)
continue;
if (i == gBattlePartyID[bankIn2])
continue;
- if (i == *(gBattleStruct->field_5C + bankIn1))
+ if (i == *(gBattleStruct->monToSwitchIntoId + bankIn1))
continue;
- if (i == *(gBattleStruct->field_5C + bankIn2))
+ if (i == *(gBattleStruct->monToSwitchIntoId + bankIn2))
continue;
species = GetMonData(&party[i], MON_DATA_SPECIES);
@@ -220,7 +220,7 @@ static bool8 FindMonThatAbsorbsOpponentsMove(void)
if (absorbingTypeAbility == monAbility && Random() & 1)
{
// we found a mon
- *(gBattleStruct->field_294 + gActiveBank) = i;
+ *(gBattleStruct->AI_monToSwitchIntoId + gActiveBank) = i;
EmitTwoReturnValues(1, ACTION_SWITCH, 0);
return TRUE;
}
@@ -240,13 +240,13 @@ static bool8 ShouldSwitchIfNaturalCure(void)
if ((gUnknown_02024250[gActiveBank] == 0 || gUnknown_02024250[gActiveBank] == 0xFFFF) && Random() & 1)
{
- *(gBattleStruct->field_294 + gActiveBank) = 6;
+ *(gBattleStruct->AI_monToSwitchIntoId + gActiveBank) = 6;
EmitTwoReturnValues(1, ACTION_SWITCH, 0);
return TRUE;
}
else if (gBattleMoves[gUnknown_02024250[gActiveBank]].power == 0 && Random() & 1)
{
- *(gBattleStruct->field_294 + gActiveBank) = 6;
+ *(gBattleStruct->AI_monToSwitchIntoId + gActiveBank) = 6;
EmitTwoReturnValues(1, ACTION_SWITCH, 0);
return TRUE;
}
@@ -257,7 +257,7 @@ static bool8 ShouldSwitchIfNaturalCure(void)
return TRUE;
if (Random() & 1)
{
- *(gBattleStruct->field_294 + gActiveBank) = 6;
+ *(gBattleStruct->AI_monToSwitchIntoId + gActiveBank) = 6;
EmitTwoReturnValues(1, ACTION_SWITCH, 0);
return TRUE;
}
@@ -400,9 +400,9 @@ static bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent)
continue;
if (i == gBattlePartyID[bankIn2])
continue;
- if (i == *(gBattleStruct->field_5C + bankIn1))
+ if (i == *(gBattleStruct->monToSwitchIntoId + bankIn1))
continue;
- if (i == *(gBattleStruct->field_5C + bankIn2))
+ if (i == *(gBattleStruct->monToSwitchIntoId + bankIn2))
continue;
species = GetMonData(&party[i], MON_DATA_SPECIES);
@@ -425,7 +425,7 @@ static bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent)
moveFlags = AI_TypeCalc(move, gBattleMons[bankIn1].species, gBattleMons[bankIn1].ability);
if (moveFlags & MOVESTATUS_SUPEREFFECTIVE && Random() % moduloPercent == 0)
{
- *(gBattleStruct->field_294 + gActiveBank) = i;
+ *(gBattleStruct->AI_monToSwitchIntoId + gActiveBank) = i;
EmitTwoReturnValues(1, ACTION_SWITCH, 0);
return TRUE;
}
@@ -508,9 +508,9 @@ static bool8 ShouldSwitch(void)
continue;
if (i == gBattlePartyID[bankIn2])
continue;
- if (i == *(gBattleStruct->field_5C + bankIn1))
+ if (i == *(gBattleStruct->monToSwitchIntoId + bankIn1))
continue;
- if (i == *(gBattleStruct->field_5C + bankIn2))
+ if (i == *(gBattleStruct->monToSwitchIntoId + bankIn2))
continue;
availableToSwitch++;
@@ -554,7 +554,7 @@ void AI_TrySwitchOrUseItem(void)
{
if (ShouldSwitch())
{
- if (*(gBattleStruct->field_294 + gActiveBank) == 6)
+ if (*(gBattleStruct->AI_monToSwitchIntoId + gActiveBank) == 6)
{
s32 monToSwitchId = GetMostSuitableMonToSwitchInto();
if (monToSwitchId == 6)
@@ -590,19 +590,19 @@ void AI_TrySwitchOrUseItem(void)
continue;
if (monToSwitchId == gBattlePartyID[bankIn2])
continue;
- if (monToSwitchId == *(gBattleStruct->field_5C + bankIn1))
+ if (monToSwitchId == *(gBattleStruct->monToSwitchIntoId + bankIn1))
continue;
- if (monToSwitchId == *(gBattleStruct->field_5C + bankIn2))
+ if (monToSwitchId == *(gBattleStruct->monToSwitchIntoId + bankIn2))
continue;
break;
}
}
- *(gBattleStruct->field_294 + gActiveBank) = monToSwitchId;
+ *(gBattleStruct->AI_monToSwitchIntoId + gActiveBank) = monToSwitchId;
}
- *(gBattleStruct->field_5C + gActiveBank) = *(gBattleStruct->field_294 + gActiveBank);
+ *(gBattleStruct->monToSwitchIntoId + gActiveBank) = *(gBattleStruct->AI_monToSwitchIntoId + gActiveBank);
return;
}
else if (ShouldUseItem())
@@ -614,28 +614,25 @@ void AI_TrySwitchOrUseItem(void)
EmitTwoReturnValues(1, ACTION_USE_MOVE, (gActiveBank ^ BIT_SIDE) << 8);
}
-#define TYPE_FORESIGHT 0xFE
-#define TYPE_ENDTABLE 0xFF
-
static void ModulateByTypeEffectiveness(u8 atkType, u8 defType1, u8 defType2, u8 *var)
{
s32 i = 0;
- while (gTypeEffectiveness[i] != TYPE_ENDTABLE)
+ while (TYPE_EFFECT_ATK_TYPE(i) != TYPE_ENDTABLE)
{
- if (gTypeEffectiveness[i] == TYPE_FORESIGHT)
+ if (TYPE_EFFECT_ATK_TYPE(i) == TYPE_FORESIGHT)
{
i += 3;
continue;
}
- else if (gTypeEffectiveness[i] == atkType)
+ else if (TYPE_EFFECT_ATK_TYPE(i) == atkType)
{
// check type1
- if (gTypeEffectiveness[i + 1] == defType1)
- *var = (*var * gTypeEffectiveness[i + 2]) / 10;
+ if (TYPE_EFFECT_DEF_TYPE(i) == defType1)
+ *var = (*var * TYPE_EFFECT_MULTIPLIER(i)) / 10;
// check type2
- if (gTypeEffectiveness[i + 1] == defType2 && defType1 != defType2)
- *var = (*var * gTypeEffectiveness[i + 2]) / 10;
+ if (TYPE_EFFECT_DEF_TYPE(i) == defType2 && defType1 != defType2)
+ *var = (*var * TYPE_EFFECT_MULTIPLIER(i)) / 10;
}
i += 3;
}
@@ -654,8 +651,8 @@ u8 GetMostSuitableMonToSwitchInto(void)
u8 invalidMons;
u16 move;
- if (*(gBattleStruct->field_5C + gActiveBank) != 6)
- return *(gBattleStruct->field_5C + gActiveBank);
+ if (*(gBattleStruct->monToSwitchIntoId + gActiveBank) != 6)
+ return *(gBattleStruct->monToSwitchIntoId + gActiveBank);
if (gBattleTypeFlags & BATTLE_TYPE_ARENA)
return gBattlePartyID[gActiveBank] + 1;
@@ -711,8 +708,8 @@ u8 GetMostSuitableMonToSwitchInto(void)
&& !(gBitTable[i] & invalidMons)
&& gBattlePartyID[bankIn1] != i
&& gBattlePartyID[bankIn2] != i
- && i != *(gBattleStruct->field_5C + bankIn1)
- && i != *(gBattleStruct->field_5C + bankIn2))
+ && i != *(gBattleStruct->monToSwitchIntoId + bankIn1)
+ && i != *(gBattleStruct->monToSwitchIntoId + bankIn2))
{
u8 type1 = gBaseStats[species].type1;
u8 type2 = gBaseStats[species].type2;
@@ -771,9 +768,9 @@ u8 GetMostSuitableMonToSwitchInto(void)
continue;
if (gBattlePartyID[bankIn2] == i)
continue;
- if (i == *(gBattleStruct->field_5C + bankIn1))
+ if (i == *(gBattleStruct->monToSwitchIntoId + bankIn1))
continue;
- if (i == *(gBattleStruct->field_5C + bankIn2))
+ if (i == *(gBattleStruct->monToSwitchIntoId + bankIn2))
continue;
for (j = 0; j < 4; j++)
diff --git a/src/battle_controller_link_opponent.c b/src/battle_controller_link_opponent.c
index 968f6d49f..423d34d45 100644
--- a/src/battle_controller_link_opponent.c
+++ b/src/battle_controller_link_opponent.c
@@ -36,7 +36,7 @@ extern u8 gBattleBufferA[BATTLE_BANKS_COUNT][0x200];
extern u8 gBattleBufferB[BATTLE_BANKS_COUNT][0x200];
extern struct BattlePokemon gBattleMons[BATTLE_BANKS_COUNT];
extern struct SpriteTemplate gUnknown_0202499C;
-extern u16 gScriptItemId;
+extern u16 gSpecialVar_ItemId;
extern u8 gHealthBoxesIds[BATTLE_BANKS_COUNT];
extern u8 gBattleOutcome;
extern u16 gBattle_BG0_X;
@@ -449,7 +449,7 @@ static void sub_8064C58(void)
{
FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBank]]);
DestroySprite(&gSprites[gBankSpriteIds[gActiveBank]]);
- sub_805EEE0(gActiveBank);
+ EnemyShadowCallbackToSetInvisible(gActiveBank);
SetHealthboxSpriteInvisible(gHealthBoxesIds[gActiveBank]);
LinkOpponentBufferExecCompleted();
}
@@ -485,7 +485,7 @@ static void sub_8064D60(void)
if (gSprites[gHealthBoxesIds[gActiveBank]].callback == SpriteCallbackDummy)
{
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
gBattleBankFunc[gActiveBank] = sub_8064DD0;
}
@@ -1164,7 +1164,7 @@ static void LinkOpponentHandleLoadMonSprite(void)
gBankSpriteIds[gActiveBank] = CreateSprite(&gUnknown_0202499C,
sub_80A5C6C(gActiveBank, 2),
- sub_80A6138(gActiveBank),
+ GetBankSpriteDefault_Y(gActiveBank),
sub_80A82E4(gActiveBank));
gSprites[gBankSpriteIds[gActiveBank]].pos2.x = -240;
@@ -1198,7 +1198,7 @@ static void sub_8066494(u8 bank, bool8 dontClearSubstituteBit)
gBankSpriteIds[bank] = CreateSprite(
&gUnknown_0202499C,
sub_80A5C6C(bank, 2),
- sub_80A6138(bank),
+ GetBankSpriteDefault_Y(bank),
sub_80A82E4(bank));
gSprites[gUnknown_03005D7C[bank]].data1 = gBankSpriteIds[bank];
@@ -1227,7 +1227,7 @@ static void LinkOpponentHandleReturnMonToBall(void)
{
FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBank]]);
DestroySprite(&gSprites[gBankSpriteIds[gActiveBank]]);
- sub_805EEE0(gActiveBank);
+ EnemyShadowCallbackToSetInvisible(gActiveBank);
SetHealthboxSpriteInvisible(gHealthBoxesIds[gActiveBank]);
LinkOpponentBufferExecCompleted();
}
@@ -1239,7 +1239,7 @@ static void DoSwitchOutAnimation(void)
{
case 0:
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 1;
break;
@@ -1247,7 +1247,7 @@ static void DoSwitchOutAnimation(void)
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive)
{
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0;
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SWITCH_OUT_OPPONENT_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SWITCH_OUT_OPPONENT_MON);
gBattleBankFunc[gActiveBank] = sub_8064C58;
}
break;
@@ -1382,7 +1382,7 @@ static void LinkOpponentHandleFaintAnimation(void)
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState == 0)
{
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState++;
}
else
@@ -1455,7 +1455,7 @@ static void LinkOpponentDoMoveAnimation(void)
&& !gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8)
{
gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8 = 1;
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
}
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 1;
break;
@@ -1474,7 +1474,7 @@ static void LinkOpponentDoMoveAnimation(void)
sub_805EB9C(1);
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute && multihit < 2)
{
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8 = 0;
}
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 3;
@@ -1483,7 +1483,7 @@ static void LinkOpponentDoMoveAnimation(void)
case 3:
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive)
{
- sub_805E394();
+ CopyAllBattleSpritesInvisibilities();
TrySetBehindSubstituteSpriteBit(gActiveBank, gBattleBufferA[gActiveBank][1] | (gBattleBufferA[gActiveBank][2] << 8));
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0;
LinkOpponentBufferExecCompleted();
@@ -1586,7 +1586,7 @@ static void LinkOpponentHandleStatusAnimation(void)
{
if (!mplay_80342A4(gActiveBank))
{
- DoStatusAnimation(gBattleBufferA[gActiveBank][1],
+ InitAndLaunchChosenStatusAnimation(gBattleBufferA[gActiveBank][1],
gBattleBufferA[gActiveBank][2] | (gBattleBufferA[gActiveBank][3] << 8) | (gBattleBufferA[gActiveBank][4] << 16) | (gBattleBufferA[gActiveBank][5] << 24));
gBattleBankFunc[gActiveBank] = CompleteOnFinishedStatusAnimation;
}
@@ -1698,7 +1698,7 @@ static void LinkOpponentHandlePlayFanfareOrBGM(void)
{
if (gBattleBufferA[gActiveBank][3])
{
- BattleMusicStop();
+ BattleStopLowHpSound();
PlayBGM(gBattleBufferA[gActiveBank][1] | (gBattleBufferA[gActiveBank][2] << 8));
}
else
@@ -1850,7 +1850,7 @@ static void LinkOpponentHandleBattleAnimation(void)
u8 animationId = gBattleBufferA[gActiveBank][1];
u16 argument = gBattleBufferA[gActiveBank][2] | (gBattleBufferA[gActiveBank][3] << 8);
- if (DoBattleAnimationFromTable(gActiveBank, gActiveBank, gActiveBank, animationId, argument))
+ if (TryHandleLaunchBattleTableAnimation(gActiveBank, gActiveBank, gActiveBank, animationId, argument))
LinkOpponentBufferExecCompleted();
else
gBattleBankFunc[gActiveBank] = CompleteOnFinishedBattleAnimation;
diff --git a/src/battle_controller_link_partner.c b/src/battle_controller_link_partner.c
index 4a70a4dc1..e3bee98d9 100644
--- a/src/battle_controller_link_partner.c
+++ b/src/battle_controller_link_partner.c
@@ -36,7 +36,7 @@ extern u8 gBattleBufferA[BATTLE_BANKS_COUNT][0x200];
extern u8 gBattleBufferB[BATTLE_BANKS_COUNT][0x200];
extern struct BattlePokemon gBattleMons[BATTLE_BANKS_COUNT];
extern struct SpriteTemplate gUnknown_0202499C;
-extern u16 gScriptItemId;
+extern u16 gSpecialVar_ItemId;
extern u8 gHealthBoxesIds[BATTLE_BANKS_COUNT];
extern u8 gBattleOutcome;
extern u16 gBattle_BG0_X;
@@ -312,7 +312,7 @@ static void CompleteOnHealthbarDone(void)
}
else
{
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
LinkPartnerBufferExecCompleted();
}
}
@@ -373,7 +373,7 @@ static void sub_814B4E0(void)
{
CopyBattleSpriteInvisibility(gActiveBank);
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
gBattleBankFunc[gActiveBank] = sub_814B554;
}
@@ -399,7 +399,7 @@ static void sub_814B5A8(void)
FreeSpritePaletteByTag(0x27F9);
CreateTask(c3_0802FDF4, 10);
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBank]], 0);
UpdateHealthboxAttribute(gHealthBoxesIds[gActiveBank], &gPlayerParty[gBattlePartyID[gActiveBank]], HEALTHBOX_ALL);
sub_8076918(gActiveBank);
@@ -1026,7 +1026,7 @@ static void SetLinkPartnerMonData(u8 monId)
break;
}
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
}
static void LinkPartnerHandleSetRawMonData(void)
@@ -1050,7 +1050,7 @@ static void LinkPartnerHandleLoadMonSprite(void)
gBankSpriteIds[gActiveBank] = CreateSprite(&gUnknown_0202499C,
sub_80A5C6C(gActiveBank, 2),
- sub_80A6138(gActiveBank),
+ GetBankSpriteDefault_Y(gActiveBank),
sub_80A82E4(gActiveBank));
gSprites[gBankSpriteIds[gActiveBank]].pos2.x = -240;
gSprites[gBankSpriteIds[gActiveBank]].data0 = gActiveBank;
@@ -1081,7 +1081,7 @@ static void sub_814CC98(u8 bank, bool8 dontClearSubstituteBit)
gBankSpriteIds[bank] = CreateSprite(
&gUnknown_0202499C,
sub_80A5C6C(bank, 2),
- sub_80A6138(bank),
+ GetBankSpriteDefault_Y(bank),
sub_80A82E4(bank));
gSprites[gUnknown_03005D7C[bank]].data1 = gBankSpriteIds[bank];
@@ -1121,7 +1121,7 @@ static void DoSwitchOutAnimation(void)
{
case 0:
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 1;
break;
@@ -1129,7 +1129,7 @@ static void DoSwitchOutAnimation(void)
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive)
{
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0;
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SWITCH_OUT_PLAYER_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SWITCH_OUT_PLAYER_MON);
gBattleBankFunc[gActiveBank] = sub_814B3DC;
}
break;
@@ -1201,7 +1201,7 @@ static void LinkPartnerHandleFaintAnimation(void)
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState == 0)
{
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState++;
}
else
@@ -1209,7 +1209,7 @@ static void LinkPartnerHandleFaintAnimation(void)
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive)
{
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0;
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
PlaySE12WithPanning(SE_POKE_DEAD, PAN_SIDE_PLAYER);
gSprites[gBankSpriteIds[gActiveBank]].data1 = 0;
gSprites[gBankSpriteIds[gActiveBank]].data2 = 5;
@@ -1277,7 +1277,7 @@ static void LinkPartnerDoMoveAnimation(void)
&& !gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8)
{
gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8 = 1;
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
}
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 1;
break;
@@ -1296,7 +1296,7 @@ static void LinkPartnerDoMoveAnimation(void)
sub_805EB9C(1);
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute && multihit < 2)
{
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8 = 0;
}
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 3;
@@ -1305,7 +1305,7 @@ static void LinkPartnerDoMoveAnimation(void)
case 3:
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive)
{
- sub_805E394();
+ CopyAllBattleSpritesInvisibilities();
TrySetBehindSubstituteSpriteBit(gActiveBank, gBattleBufferA[gActiveBank][1] | (gBattleBufferA[gActiveBank][2] << 8));
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0;
LinkPartnerBufferExecCompleted();
@@ -1408,7 +1408,7 @@ static void LinkPartnerHandleStatusAnimation(void)
{
if (!mplay_80342A4(gActiveBank))
{
- DoStatusAnimation(gBattleBufferA[gActiveBank][1],
+ InitAndLaunchChosenStatusAnimation(gBattleBufferA[gActiveBank][1],
gBattleBufferA[gActiveBank][2] | (gBattleBufferA[gActiveBank][3] << 8) | (gBattleBufferA[gActiveBank][4] << 16) | (gBattleBufferA[gActiveBank][5] << 24));
gBattleBankFunc[gActiveBank] = CompleteOnFinishedStatusAnimation;
}
@@ -1520,7 +1520,7 @@ static void LinkPartnerHandlePlayFanfareOrBGM(void)
{
if (gBattleBufferA[gActiveBank][3])
{
- BattleMusicStop();
+ BattleStopLowHpSound();
PlayBGM(gBattleBufferA[gActiveBank][1] | (gBattleBufferA[gActiveBank][2] << 8));
}
else
@@ -1683,7 +1683,7 @@ static void LinkPartnerHandleBattleAnimation(void)
u8 animationId = gBattleBufferA[gActiveBank][1];
u16 argument = gBattleBufferA[gActiveBank][2] | (gBattleBufferA[gActiveBank][3] << 8);
- if (DoBattleAnimationFromTable(gActiveBank, gActiveBank, gActiveBank, animationId, argument))
+ if (TryHandleLaunchBattleTableAnimation(gActiveBank, gActiveBank, gActiveBank, animationId, argument))
LinkPartnerBufferExecCompleted();
else
gBattleBankFunc[gActiveBank] = CompleteOnFinishedBattleAnimation;
diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c
index 7ffd9d64b..0aac4cbe4 100644
--- a/src/battle_controller_opponent.c
+++ b/src/battle_controller_opponent.c
@@ -437,7 +437,7 @@ static void sub_805FB08(void)
{
FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBank]]);
DestroySprite(&gSprites[gBankSpriteIds[gActiveBank]]);
- sub_805EEE0(gActiveBank);
+ EnemyShadowCallbackToSetInvisible(gActiveBank);
SetHealthboxSpriteInvisible(gHealthBoxesIds[gActiveBank]);
OpponentBufferExecCompleted();
}
@@ -473,7 +473,7 @@ static void sub_805FC10(void)
if (gSprites[gHealthBoxesIds[gActiveBank]].callback == SpriteCallbackDummy)
{
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
gBattleBankFunc[gActiveBank] = sub_805FC80;
}
}
@@ -1152,7 +1152,7 @@ static void OpponentHandleLoadMonSprite(void)
gBankSpriteIds[gActiveBank] = CreateSprite(&gUnknown_0202499C,
sub_80A5C6C(gActiveBank, 2),
- sub_80A6138(gActiveBank),
+ GetBankSpriteDefault_Y(gActiveBank),
sub_80A82E4(gActiveBank));
gSprites[gBankSpriteIds[gActiveBank]].pos2.x = -240;
@@ -1168,7 +1168,7 @@ static void OpponentHandleLoadMonSprite(void)
static void OpponentHandleSwitchInAnim(void)
{
- *(gBattleStruct->field_5C + gActiveBank) = 6;
+ *(gBattleStruct->monToSwitchIntoId + gActiveBank) = 6;
gBattlePartyID[gActiveBank] = gBattleBufferA[gActiveBank][1];
sub_80613DC(gActiveBank, gBattleBufferA[gActiveBank][2]);
gBattleBankFunc[gActiveBank] = sub_805FDF0;
@@ -1187,7 +1187,7 @@ static void sub_80613DC(u8 bank, bool8 dontClearSubstituteBit)
gBankSpriteIds[bank] = CreateSprite(&gUnknown_0202499C,
sub_80A5C6C(bank, 2),
- sub_80A6138(bank),
+ GetBankSpriteDefault_Y(bank),
sub_80A82E4(bank));
gSprites[gBankSpriteIds[bank]].data0 = bank;
@@ -1217,7 +1217,7 @@ static void OpponentHandleReturnMonToBall(void)
{
FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBank]]);
DestroySprite(&gSprites[gBankSpriteIds[gActiveBank]]);
- sub_805EEE0(gActiveBank);
+ EnemyShadowCallbackToSetInvisible(gActiveBank);
SetHealthboxSpriteInvisible(gHealthBoxesIds[gActiveBank]);
OpponentBufferExecCompleted();
}
@@ -1229,7 +1229,7 @@ static void DoSwitchOutAnimation(void)
{
case 0:
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 1;
break;
@@ -1237,7 +1237,7 @@ static void DoSwitchOutAnimation(void)
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive)
{
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0;
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SWITCH_OUT_OPPONENT_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SWITCH_OUT_OPPONENT_MON);
gBattleBankFunc[gActiveBank] = sub_805FB08;
}
break;
@@ -1415,7 +1415,7 @@ static void OpponentHandleFaintAnimation(void)
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState == 0)
{
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState++;
}
else
@@ -1487,7 +1487,7 @@ static void OpponentDoMoveAnimation(void)
&& !gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8)
{
gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8 = 1;
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
}
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 1;
break;
@@ -1506,7 +1506,7 @@ static void OpponentDoMoveAnimation(void)
sub_805EB9C(1);
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute && multihit < 2)
{
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8 = 0;
}
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 3;
@@ -1515,7 +1515,7 @@ static void OpponentDoMoveAnimation(void)
case 3:
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive)
{
- sub_805E394();
+ CopyAllBattleSpritesInvisibilities();
TrySetBehindSubstituteSpriteBit(gActiveBank, gBattleBufferA[gActiveBank][1] | (gBattleBufferA[gActiveBank][2] << 8));
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0;
OpponentBufferExecCompleted();
@@ -1627,7 +1627,7 @@ static void OpponentHandleChoosePokemon(void)
{
s32 chosenMonId;
- if (*(gBattleStruct->field_294 + gActiveBank) == 6)
+ if (*(gBattleStruct->AI_monToSwitchIntoId + gActiveBank) == 6)
{
chosenMonId = GetMostSuitableMonToSwitchInto();
@@ -1670,12 +1670,12 @@ static void OpponentHandleChoosePokemon(void)
}
else
{
- chosenMonId = *(gBattleStruct->field_294 + gActiveBank);
- *(gBattleStruct->field_294 + gActiveBank) = 6;
+ chosenMonId = *(gBattleStruct->AI_monToSwitchIntoId + gActiveBank);
+ *(gBattleStruct->AI_monToSwitchIntoId + gActiveBank) = 6;
}
- *(gBattleStruct->field_5C + gActiveBank) = chosenMonId;
+ *(gBattleStruct->monToSwitchIntoId + gActiveBank) = chosenMonId;
EmitChosenMonReturnValue(1, chosenMonId, NULL);
OpponentBufferExecCompleted();
}
@@ -1731,7 +1731,7 @@ static void OpponentHandleStatusAnimation(void)
{
if (!mplay_80342A4(gActiveBank))
{
- DoStatusAnimation(gBattleBufferA[gActiveBank][1],
+ InitAndLaunchChosenStatusAnimation(gBattleBufferA[gActiveBank][1],
gBattleBufferA[gActiveBank][2] | (gBattleBufferA[gActiveBank][3] << 8) | (gBattleBufferA[gActiveBank][4] << 16) | (gBattleBufferA[gActiveBank][5] << 24));
gBattleBankFunc[gActiveBank] = CompleteOnFinishedStatusAnimation;
}
@@ -1843,7 +1843,7 @@ static void OpponentHandlePlayFanfareOrBGM(void)
{
if (gBattleBufferA[gActiveBank][3])
{
- BattleMusicStop();
+ BattleStopLowHpSound();
PlayBGM(gBattleBufferA[gActiveBank][1] | (gBattleBufferA[gActiveBank][2] << 8));
}
else
@@ -2000,7 +2000,7 @@ static void OpponentHandleBattleAnimation(void)
u8 animationId = gBattleBufferA[gActiveBank][1];
u16 argument = gBattleBufferA[gActiveBank][2] | (gBattleBufferA[gActiveBank][3] << 8);
- if (DoBattleAnimationFromTable(gActiveBank, gActiveBank, gActiveBank, animationId, argument))
+ if (TryHandleLaunchBattleTableAnimation(gActiveBank, gActiveBank, gActiveBank, animationId, argument))
OpponentBufferExecCompleted();
else
gBattleBankFunc[gActiveBank] = CompleteOnFinishedBattleAnimation;
diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c
index 10d361cb9..16c62c53b 100644
--- a/src/battle_controller_player.c
+++ b/src/battle_controller_player.c
@@ -46,7 +46,7 @@ extern struct MusicPlayerInfo gMPlay_BGM;
extern u16 gPartnerTrainerId;
extern struct SpriteTemplate gUnknown_0202499C;
extern u8 gBattleMonForms[BATTLE_BANKS_COUNT];
-extern u16 gScriptItemId;
+extern u16 gSpecialVar_ItemId;
extern u8 gUnknown_0203CEE8;
extern u8 gUnknown_0203CEE9;
extern u8 gUnknown_0203CF00[];
@@ -1008,10 +1008,10 @@ static void sub_805896C(void)
FreeSpriteTilesByTag(0x27F9);
FreeSpritePaletteByTag(0x27F9);
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
if (IsDoubleBattle())
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank ^ BIT_MON]], gActiveBank ^ BIT_MON);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank ^ BIT_MON]], gActiveBank ^ BIT_MON);
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_9 = 3;
gBattleBankFunc[gActiveBank] = sub_8058924;
@@ -1107,7 +1107,7 @@ static void sub_8058EDC(void)
FreeSpritePaletteByTag(0x27F9);
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
gBattleBankFunc[gActiveBank] = sub_8058FC0;
}
@@ -1119,7 +1119,7 @@ static void sub_8058FC0(void)
&& !IsCryPlayingOrClearCrySongs())
{
m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100);
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
PlayerBufferExecCompleted();
}
}
@@ -1164,7 +1164,7 @@ static void CompleteOnHealthbarDone(void)
}
else
{
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
PlayerBufferExecCompleted();
}
}
@@ -1305,7 +1305,7 @@ static void sub_8059544(u8 taskId)
if (IsDoubleBattle() == TRUE && monIndex == gBattlePartyID[bank ^ BIT_MON])
bank ^= BIT_MON;
- DoSpecialBattleAnimation(bank, bank, bank, B_ANIM_LVL_UP);
+ InitAndLaunchSpecialAnimation(bank, bank, bank, B_ANIM_LVL_UP);
gTasks[taskId].func = sub_80595A4;
}
@@ -1416,7 +1416,7 @@ static void CompleteWhenChoseItem(void)
{
if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active)
{
- EmitOneReturnValue(1, gScriptItemId);
+ EmitOneReturnValue(1, gSpecialVar_ItemId);
PlayerBufferExecCompleted();
}
}
@@ -2193,7 +2193,7 @@ static void SetPlayerMonData(u8 monId)
break;
}
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
}
static void PlayerHandleSetRawMonData(void)
@@ -2238,7 +2238,7 @@ static void sub_805B258(u8 bank, bool8 dontClearSubstituteBit)
gBankSpriteIds[bank] = CreateSprite(
&gUnknown_0202499C,
sub_80A5C6C(bank, 2),
- sub_80A6138(bank),
+ GetBankSpriteDefault_Y(bank),
sub_80A82E4(bank));
gSprites[gUnknown_03005D7C[bank]].data1 = gBankSpriteIds[bank];
@@ -2278,7 +2278,7 @@ static void DoSwitchOutAnimation(void)
{
case 0:
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 1;
break;
@@ -2286,7 +2286,7 @@ static void DoSwitchOutAnimation(void)
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive)
{
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0;
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SWITCH_OUT_PLAYER_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SWITCH_OUT_PLAYER_MON);
gBattleBankFunc[gActiveBank] = sub_8059744;
}
break;
@@ -2434,7 +2434,7 @@ static void PlayerHandleFaintAnimation(void)
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState == 0)
{
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState++;
}
else
@@ -2442,7 +2442,7 @@ static void PlayerHandleFaintAnimation(void)
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive)
{
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0;
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
PlaySE12WithPanning(SE_POKE_DEAD, PAN_SIDE_PLAYER);
gSprites[gBankSpriteIds[gActiveBank]].data1 = 0;
gSprites[gBankSpriteIds[gActiveBank]].data2 = 5;
@@ -2462,7 +2462,7 @@ static void PlayerHandleSuccessBallThrowAnim(void)
{
gBattleSpritesDataPtr->animationData->ballThrowCaseId = BALL_3_SHAKES_SUCCESS;
gDoingBattleAnim = TRUE;
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, GetBankByIdentity(IDENTITY_OPPONENT_MON1), B_ANIM_BALL_THROW);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, GetBankByIdentity(IDENTITY_OPPONENT_MON1), B_ANIM_BALL_THROW);
gBattleBankFunc[gActiveBank] = CompleteOnSpecialAnimDone;
}
@@ -2472,7 +2472,7 @@ static void PlayerHandleBallThrowAnim(void)
gBattleSpritesDataPtr->animationData->ballThrowCaseId = ballThrowCaseId;
gDoingBattleAnim = TRUE;
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, GetBankByIdentity(IDENTITY_OPPONENT_MON1), B_ANIM_BALL_THROW);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, GetBankByIdentity(IDENTITY_OPPONENT_MON1), B_ANIM_BALL_THROW);
gBattleBankFunc[gActiveBank] = CompleteOnSpecialAnimDone;
}
@@ -2525,7 +2525,7 @@ static void PlayerDoMoveAnimation(void)
&& !gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8)
{
gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8 = 1;
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
}
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 1;
break;
@@ -2544,7 +2544,7 @@ static void PlayerDoMoveAnimation(void)
sub_805EB9C(1);
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute && multihit < 2)
{
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8 = 0;
}
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 3;
@@ -2553,7 +2553,7 @@ static void PlayerDoMoveAnimation(void)
case 3:
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive)
{
- sub_805E394();
+ CopyAllBattleSpritesInvisibilities();
TrySetBehindSubstituteSpriteBit(gActiveBank, gBattleBufferA[gActiveBank][1] | (gBattleBufferA[gActiveBank][2] << 8));
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0;
PlayerBufferExecCompleted();
@@ -2709,7 +2709,7 @@ static void PlayerHandleChoosePokemon(void)
static void PlayerHandleCmd23(void)
{
- BattleMusicStop();
+ BattleStopLowHpSound();
BeginNormalPaletteFade(-1, 2, 0, 16, 0);
PlayerBufferExecCompleted();
}
@@ -2788,7 +2788,7 @@ static void PlayerHandleStatusAnimation(void)
{
if (!mplay_80342A4(gActiveBank))
{
- DoStatusAnimation(gBattleBufferA[gActiveBank][1],
+ InitAndLaunchChosenStatusAnimation(gBattleBufferA[gActiveBank][1],
gBattleBufferA[gActiveBank][2] | (gBattleBufferA[gActiveBank][3] << 8) | (gBattleBufferA[gActiveBank][4] << 16) | (gBattleBufferA[gActiveBank][5] << 24));
gBattleBankFunc[gActiveBank] = CompleteOnFinishedStatusAnimation;
}
@@ -2930,7 +2930,7 @@ static void PlayerHandlePlayFanfareOrBGM(void)
{
if (gBattleBufferA[gActiveBank][3])
{
- BattleMusicStop();
+ BattleStopLowHpSound();
PlayBGM(gBattleBufferA[gActiveBank][1] | (gBattleBufferA[gActiveBank][2] << 8));
}
else
@@ -3088,7 +3088,7 @@ static void PlayerHandleBattleAnimation(void)
u8 animationId = gBattleBufferA[gActiveBank][1];
u16 argument = gBattleBufferA[gActiveBank][2] | (gBattleBufferA[gActiveBank][3] << 8);
- if (DoBattleAnimationFromTable(gActiveBank, gActiveBank, gActiveBank, animationId, argument))
+ if (TryHandleLaunchBattleTableAnimation(gActiveBank, gActiveBank, gActiveBank, animationId, argument))
PlayerBufferExecCompleted();
else
gBattleBankFunc[gActiveBank] = CompleteOnFinishedBattleAnimation;
diff --git a/src/battle_controller_player_partner.c b/src/battle_controller_player_partner.c
index 34fd8a3eb..0cd34442a 100644
--- a/src/battle_controller_player_partner.c
+++ b/src/battle_controller_player_partner.c
@@ -35,7 +35,7 @@ extern u8 gBattleBufferA[BATTLE_BANKS_COUNT][0x200];
extern u8 gBattleBufferB[BATTLE_BANKS_COUNT][0x200];
extern struct BattlePokemon gBattleMons[BATTLE_BANKS_COUNT];
extern struct SpriteTemplate gUnknown_0202499C;
-extern u16 gScriptItemId;
+extern u16 gSpecialVar_ItemId;
extern u8 gHealthBoxesIds[BATTLE_BANKS_COUNT];
extern u8 gBattleOutcome;
extern u16 gBattle_BG0_X;
@@ -327,7 +327,7 @@ static void CompleteOnHealthbarDone(void)
}
else
{
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
PlayerPartnerBufferExecCompleted();
}
}
@@ -469,7 +469,7 @@ static void sub_81BB628(u8 taskId)
if (IsDoubleBattle() == TRUE && monIndex == gBattlePartyID[bank ^ BIT_MON])
bank ^= BIT_MON;
- DoSpecialBattleAnimation(bank, bank, bank, B_ANIM_LVL_UP);
+ InitAndLaunchSpecialAnimation(bank, bank, bank, B_ANIM_LVL_UP);
gTasks[taskId].func = sub_81BB688;
}
@@ -560,7 +560,7 @@ static void sub_81BB92C(void)
{
CopyBattleSpriteInvisibility(gActiveBank);
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
gBattleBankFunc[gActiveBank] = sub_81BB9A0;
}
@@ -586,7 +586,7 @@ static void sub_81BB9F4(void)
FreeSpritePaletteByTag(0x27F9);
CreateTask(c3_0802FDF4, 10);
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBank]], 0);
UpdateHealthboxAttribute(gHealthBoxesIds[gActiveBank], &gPlayerParty[gBattlePartyID[gActiveBank]], HEALTHBOX_ALL);
sub_8076918(gActiveBank);
@@ -1213,7 +1213,7 @@ static void SetPlayerPartnerMonData(u8 monId)
break;
}
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
}
static void PlayerPartnerHandleSetRawMonData(void)
@@ -1237,7 +1237,7 @@ static void PlayerPartnerHandleLoadMonSprite(void)
gBankSpriteIds[gActiveBank] = CreateSprite(&gUnknown_0202499C,
sub_80A5C6C(gActiveBank, 2),
- sub_80A6138(gActiveBank),
+ GetBankSpriteDefault_Y(gActiveBank),
sub_80A82E4(gActiveBank));
gSprites[gBankSpriteIds[gActiveBank]].pos2.x = -240;
gSprites[gBankSpriteIds[gActiveBank]].data0 = gActiveBank;
@@ -1268,7 +1268,7 @@ static void sub_81BD0E4(u8 bank, bool8 dontClearSubstituteBit)
gBankSpriteIds[bank] = CreateSprite(
&gUnknown_0202499C,
sub_80A5C6C(bank, 2),
- sub_80A6138(bank),
+ GetBankSpriteDefault_Y(bank),
sub_80A82E4(bank));
gSprites[gUnknown_03005D7C[bank]].data1 = gBankSpriteIds[bank];
@@ -1308,7 +1308,7 @@ static void DoSwitchOutAnimation(void)
{
case 0:
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 1;
break;
@@ -1316,7 +1316,7 @@ static void DoSwitchOutAnimation(void)
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive)
{
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0;
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SWITCH_OUT_PLAYER_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SWITCH_OUT_PLAYER_MON);
gBattleBankFunc[gActiveBank] = sub_81BB828;
}
break;
@@ -1395,7 +1395,7 @@ static void PlayerPartnerHandleFaintAnimation(void)
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState == 0)
{
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState++;
}
else
@@ -1403,7 +1403,7 @@ static void PlayerPartnerHandleFaintAnimation(void)
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive)
{
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0;
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
PlaySE12WithPanning(SE_POKE_DEAD, PAN_SIDE_PLAYER);
gSprites[gBankSpriteIds[gActiveBank]].data1 = 0;
gSprites[gBankSpriteIds[gActiveBank]].data2 = 5;
@@ -1470,7 +1470,7 @@ static void PlayerPartnerDoMoveAnimation(void)
&& !gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8)
{
gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8 = 1;
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
}
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 1;
break;
@@ -1489,7 +1489,7 @@ static void PlayerPartnerDoMoveAnimation(void)
sub_805EB9C(1);
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute && multihit < 2)
{
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8 = 0;
}
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 3;
@@ -1498,7 +1498,7 @@ static void PlayerPartnerDoMoveAnimation(void)
case 3:
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive)
{
- sub_805E394();
+ CopyAllBattleSpritesInvisibilities();
TrySetBehindSubstituteSpriteBit(gActiveBank, gBattleBufferA[gActiveBank][1] | (gBattleBufferA[gActiveBank][2] << 8));
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0;
PlayerPartnerBufferExecCompleted();
@@ -1581,7 +1581,7 @@ static void PlayerPartnerHandleChoosePokemon(void)
}
}
- *(gBattleStruct->field_5C + gActiveBank) = chosenMonId;
+ *(gBattleStruct->monToSwitchIntoId + gActiveBank) = chosenMonId;
EmitChosenMonReturnValue(1, chosenMonId, NULL);
PlayerPartnerBufferExecCompleted();
}
@@ -1661,7 +1661,7 @@ static void PlayerPartnerHandleStatusAnimation(void)
{
if (!mplay_80342A4(gActiveBank))
{
- DoStatusAnimation(gBattleBufferA[gActiveBank][1],
+ InitAndLaunchChosenStatusAnimation(gBattleBufferA[gActiveBank][1],
gBattleBufferA[gActiveBank][2] | (gBattleBufferA[gActiveBank][3] << 8) | (gBattleBufferA[gActiveBank][4] << 16) | (gBattleBufferA[gActiveBank][5] << 24));
gBattleBankFunc[gActiveBank] = CompleteOnFinishedStatusAnimation;
}
@@ -1773,7 +1773,7 @@ static void PlayerPartnerHandlePlayFanfareOrBGM(void)
{
if (gBattleBufferA[gActiveBank][3])
{
- BattleMusicStop();
+ BattleStopLowHpSound();
PlayBGM(gBattleBufferA[gActiveBank][1] | (gBattleBufferA[gActiveBank][2] << 8));
}
else
@@ -1929,7 +1929,7 @@ static void PlayerPartnerHandleBattleAnimation(void)
u8 animationId = gBattleBufferA[gActiveBank][1];
u16 argument = gBattleBufferA[gActiveBank][2] | (gBattleBufferA[gActiveBank][3] << 8);
- if (DoBattleAnimationFromTable(gActiveBank, gActiveBank, gActiveBank, animationId, argument))
+ if (TryHandleLaunchBattleTableAnimation(gActiveBank, gActiveBank, gActiveBank, animationId, argument))
PlayerPartnerBufferExecCompleted();
else
gBattleBankFunc[gActiveBank] = CompleteOnFinishedBattleAnimation;
diff --git a/src/battle_controller_recorded_opponent.c b/src/battle_controller_recorded_opponent.c
index 0dc7631ce..b55d644ac 100644
--- a/src/battle_controller_recorded_opponent.c
+++ b/src/battle_controller_recorded_opponent.c
@@ -37,7 +37,7 @@ extern u8 gBattleBufferA[BATTLE_BANKS_COUNT][0x200];
extern u8 gBattleBufferB[BATTLE_BANKS_COUNT][0x200];
extern struct BattlePokemon gBattleMons[BATTLE_BANKS_COUNT];
extern struct SpriteTemplate gUnknown_0202499C;
-extern u16 gScriptItemId;
+extern u16 gSpecialVar_ItemId;
extern u8 gHealthBoxesIds[BATTLE_BANKS_COUNT];
extern u8 gBattleOutcome;
extern u16 gBattle_BG0_X;
@@ -433,7 +433,7 @@ static void sub_8186D9C(void)
{
FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBank]]);
DestroySprite(&gSprites[gBankSpriteIds[gActiveBank]]);
- sub_805EEE0(gActiveBank);
+ EnemyShadowCallbackToSetInvisible(gActiveBank);
SetHealthboxSpriteInvisible(gHealthBoxesIds[gActiveBank]);
RecordedOpponentBufferExecCompleted();
}
@@ -469,7 +469,7 @@ static void sub_8186EA4(void)
if (gSprites[gHealthBoxesIds[gActiveBank]].callback == SpriteCallbackDummy)
{
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
gBattleBankFunc[gActiveBank] = sub_8186F14;
}
@@ -1149,7 +1149,7 @@ static void RecordedOpponentHandleLoadMonSprite(void)
gBankSpriteIds[gActiveBank] = CreateSprite(&gUnknown_0202499C,
sub_80A5C6C(gActiveBank, 2),
- sub_80A6138(gActiveBank),
+ GetBankSpriteDefault_Y(gActiveBank),
sub_80A82E4(gActiveBank));
@@ -1184,7 +1184,7 @@ static void sub_81885D8(u8 bank, bool8 dontClearSubstituteBit)
gBankSpriteIds[bank] = CreateSprite(&gUnknown_0202499C,
sub_80A5C6C(bank, 2),
- sub_80A6138(bank),
+ GetBankSpriteDefault_Y(bank),
sub_80A82E4(bank));
gSprites[gUnknown_03005D7C[bank]].data1 = gBankSpriteIds[bank];
@@ -1213,7 +1213,7 @@ static void RecordedOpponentHandleReturnMonToBall(void)
{
FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBank]]);
DestroySprite(&gSprites[gBankSpriteIds[gActiveBank]]);
- sub_805EEE0(gActiveBank);
+ EnemyShadowCallbackToSetInvisible(gActiveBank);
SetHealthboxSpriteInvisible(gHealthBoxesIds[gActiveBank]);
RecordedOpponentBufferExecCompleted();
}
@@ -1225,7 +1225,7 @@ static void DoSwitchOutAnimation(void)
{
case 0:
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 1;
break;
@@ -1233,7 +1233,7 @@ static void DoSwitchOutAnimation(void)
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive)
{
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0;
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SWITCH_OUT_OPPONENT_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SWITCH_OUT_OPPONENT_MON);
gBattleBankFunc[gActiveBank] = sub_8186D9C;
}
break;
@@ -1261,7 +1261,7 @@ static void RecordedOpponentHandleDrawTrainerPic(void)
}
else
{
- trainerPicId = PlayerGenderToFrontTrainerPicId(sub_8185F40());
+ trainerPicId = PlayerGenderToFrontTrainerPicId(GetActiveBankLinkPlayerGender());
}
}
else
@@ -1314,7 +1314,7 @@ static void RecordedOpponentHandleFaintAnimation(void)
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState == 0)
{
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState++;
}
else
@@ -1386,7 +1386,7 @@ static void RecordedOpponentDoMoveAnimation(void)
&& !gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8)
{
gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8 = 1;
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
}
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 1;
break;
@@ -1405,7 +1405,7 @@ static void RecordedOpponentDoMoveAnimation(void)
sub_805EB9C(1);
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute && multihit < 2)
{
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8 = 0;
}
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 3;
@@ -1414,7 +1414,7 @@ static void RecordedOpponentDoMoveAnimation(void)
case 3:
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive)
{
- sub_805E394();
+ CopyAllBattleSpritesInvisibilities();
TrySetBehindSubstituteSpriteBit(gActiveBank, gBattleBufferA[gActiveBank][1] | (gBattleBufferA[gActiveBank][2] << 8));
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0;
RecordedOpponentBufferExecCompleted();
@@ -1474,8 +1474,8 @@ static void RecordedOpponentHandleChooseItem(void)
static void RecordedOpponentHandleChoosePokemon(void)
{
- *(gBattleStruct->field_5C + gActiveBank) = RecordedBattle_ReadBankAction(gActiveBank);
- EmitChosenMonReturnValue(1, *(gBattleStruct->field_5C + gActiveBank), NULL);
+ *(gBattleStruct->monToSwitchIntoId + gActiveBank) = RecordedBattle_ReadBankAction(gActiveBank);
+ EmitChosenMonReturnValue(1, *(gBattleStruct->monToSwitchIntoId + gActiveBank), NULL);
RecordedOpponentBufferExecCompleted();
}
@@ -1530,7 +1530,7 @@ static void RecordedOpponentHandleStatusAnimation(void)
{
if (!mplay_80342A4(gActiveBank))
{
- DoStatusAnimation(gBattleBufferA[gActiveBank][1],
+ InitAndLaunchChosenStatusAnimation(gBattleBufferA[gActiveBank][1],
gBattleBufferA[gActiveBank][2] | (gBattleBufferA[gActiveBank][3] << 8) | (gBattleBufferA[gActiveBank][4] << 16) | (gBattleBufferA[gActiveBank][5] << 24));
gBattleBankFunc[gActiveBank] = CompleteOnFinishedStatusAnimation;
}
@@ -1642,7 +1642,7 @@ static void RecordedOpponentHandlePlayFanfareOrBGM(void)
{
if (gBattleBufferA[gActiveBank][3])
{
- BattleMusicStop();
+ BattleStopLowHpSound();
PlayBGM(gBattleBufferA[gActiveBank][1] | (gBattleBufferA[gActiveBank][2] << 8));
}
else
@@ -1794,7 +1794,7 @@ static void RecordedOpponentHandleBattleAnimation(void)
u8 animationId = gBattleBufferA[gActiveBank][1];
u16 argument = gBattleBufferA[gActiveBank][2] | (gBattleBufferA[gActiveBank][3] << 8);
- if (DoBattleAnimationFromTable(gActiveBank, gActiveBank, gActiveBank, animationId, argument))
+ if (TryHandleLaunchBattleTableAnimation(gActiveBank, gActiveBank, gActiveBank, animationId, argument))
RecordedOpponentBufferExecCompleted();
else
gBattleBankFunc[gActiveBank] = CompleteOnFinishedBattleAnimation;
diff --git a/src/battle_controller_recorded_player.c b/src/battle_controller_recorded_player.c
index a3343a391..78e7497a5 100644
--- a/src/battle_controller_recorded_player.c
+++ b/src/battle_controller_recorded_player.c
@@ -36,7 +36,7 @@ extern u8 gBattleBufferA[BATTLE_BANKS_COUNT][0x200];
extern u8 gBattleBufferB[BATTLE_BANKS_COUNT][0x200];
extern struct BattlePokemon gBattleMons[BATTLE_BANKS_COUNT];
extern struct SpriteTemplate gUnknown_0202499C;
-extern u16 gScriptItemId;
+extern u16 gSpecialVar_ItemId;
extern u8 gHealthBoxesIds[BATTLE_BANKS_COUNT];
extern u8 gBattleOutcome;
extern u16 gBattle_BG0_X;
@@ -272,9 +272,9 @@ static void sub_8189AA0(void)
FreeSpriteTilesByTag(0x27F9);
FreeSpritePaletteByTag(0x27F9);
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
if (IsDoubleBattle())
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank ^ BIT_MON]], gActiveBank ^ BIT_MON);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank ^ BIT_MON]], gActiveBank ^ BIT_MON);
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_9 = 3;
gBattleBankFunc[gActiveBank] = sub_8189A58;
@@ -397,7 +397,7 @@ static void CompleteOnHealthbarDone(void)
}
else
{
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
RecordedPlayerBufferExecCompleted();
}
}
@@ -458,7 +458,7 @@ static void sub_818A2B4(void)
{
CopyBattleSpriteInvisibility(gActiveBank);
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
gBattleBankFunc[gActiveBank] = sub_818A328;
}
@@ -484,7 +484,7 @@ static void sub_818A37C(void)
FreeSpritePaletteByTag(0x27F9);
CreateTask(c3_0802FDF4, 10);
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBank]], 0);
UpdateHealthboxAttribute(gHealthBoxesIds[gActiveBank], &gPlayerParty[gBattlePartyID[gActiveBank]], HEALTHBOX_ALL);
sub_8076918(gActiveBank);
@@ -1111,7 +1111,7 @@ static void SetRecordedPlayerMonData(u8 monId)
break;
}
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
}
static void RecordedPlayerHandleSetRawMonData(void)
@@ -1135,7 +1135,7 @@ static void RecordedPlayerHandleLoadMonSprite(void)
gBankSpriteIds[gActiveBank] = CreateSprite(&gUnknown_0202499C,
sub_80A5C6C(gActiveBank, 2),
- sub_80A6138(gActiveBank),
+ GetBankSpriteDefault_Y(gActiveBank),
sub_80A82E4(gActiveBank));
gSprites[gBankSpriteIds[gActiveBank]].pos2.x = -240;
gSprites[gBankSpriteIds[gActiveBank]].data0 = gActiveBank;
@@ -1166,7 +1166,7 @@ static void sub_818BA6C(u8 bank, bool8 dontClearSubstituteBit)
gBankSpriteIds[bank] = CreateSprite(
&gUnknown_0202499C,
sub_80A5C6C(bank, 2),
- sub_80A6138(bank),
+ GetBankSpriteDefault_Y(bank),
sub_80A82E4(bank));
gSprites[gUnknown_03005D7C[bank]].data1 = gBankSpriteIds[bank];
@@ -1206,7 +1206,7 @@ static void DoSwitchOutAnimation(void)
{
case 0:
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 1;
break;
@@ -1214,7 +1214,7 @@ static void DoSwitchOutAnimation(void)
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive)
{
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0;
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SWITCH_OUT_PLAYER_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SWITCH_OUT_PLAYER_MON);
gBattleBankFunc[gActiveBank] = sub_818A1B0;
}
break;
@@ -1229,7 +1229,7 @@ static void RecordedPlayerHandleDrawTrainerPic(void)
if (gBattleTypeFlags & BATTLE_TYPE_x2000000)
{
if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
- trainerPicId = sub_8185F40();
+ trainerPicId = GetActiveBankLinkPlayerGender();
else
trainerPicId = gLinkPlayers[gUnknown_0203C7B4].gender;
}
@@ -1313,7 +1313,7 @@ static void RecordedPlayerHandleFaintAnimation(void)
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState == 0)
{
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState++;
}
else
@@ -1321,7 +1321,7 @@ static void RecordedPlayerHandleFaintAnimation(void)
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive)
{
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0;
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
PlaySE12WithPanning(SE_POKE_DEAD, -64);
gSprites[gBankSpriteIds[gActiveBank]].data1 = 0;
gSprites[gBankSpriteIds[gActiveBank]].data2 = 5;
@@ -1388,7 +1388,7 @@ static void RecordedPlayerDoMoveAnimation(void)
&& !gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8)
{
gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8 = 1;
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
}
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 1;
break;
@@ -1407,7 +1407,7 @@ static void RecordedPlayerDoMoveAnimation(void)
sub_805EB9C(1);
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute && multihit < 2)
{
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8 = 0;
}
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 3;
@@ -1416,7 +1416,7 @@ static void RecordedPlayerDoMoveAnimation(void)
case 3:
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive)
{
- sub_805E394();
+ CopyAllBattleSpritesInvisibilities();
TrySetBehindSubstituteSpriteBit(gActiveBank, gBattleBufferA[gActiveBank][1] | (gBattleBufferA[gActiveBank][2] << 8));
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0;
RecordedPlayerBufferExecCompleted();
@@ -1492,8 +1492,8 @@ static void RecordedPlayerHandleChooseItem(void)
static void RecordedPlayerHandleChoosePokemon(void)
{
- *(gBattleStruct->field_5C + gActiveBank) = RecordedBattle_ReadBankAction(gActiveBank);
- EmitChosenMonReturnValue(1, *(gBattleStruct->field_5C + gActiveBank), NULL);
+ *(gBattleStruct->monToSwitchIntoId + gActiveBank) = RecordedBattle_ReadBankAction(gActiveBank);
+ EmitChosenMonReturnValue(1, *(gBattleStruct->monToSwitchIntoId + gActiveBank), NULL);
RecordedPlayerBufferExecCompleted();
}
@@ -1549,7 +1549,7 @@ static void RecordedPlayerHandleStatusAnimation(void)
{
if (!mplay_80342A4(gActiveBank))
{
- DoStatusAnimation(gBattleBufferA[gActiveBank][1],
+ InitAndLaunchChosenStatusAnimation(gBattleBufferA[gActiveBank][1],
gBattleBufferA[gActiveBank][2] | (gBattleBufferA[gActiveBank][3] << 8) | (gBattleBufferA[gActiveBank][4] << 16) | (gBattleBufferA[gActiveBank][5] << 24));
gBattleBankFunc[gActiveBank] = CompleteOnFinishedStatusAnimation;
}
@@ -1661,7 +1661,7 @@ static void RecordedPlayerHandlePlayFanfareOrBGM(void)
{
if (gBattleBufferA[gActiveBank][3])
{
- BattleMusicStop();
+ BattleStopLowHpSound();
PlayBGM(gBattleBufferA[gActiveBank][1] | (gBattleBufferA[gActiveBank][2] << 8));
}
else
@@ -1813,7 +1813,7 @@ static void RecordedPlayerHandleBattleAnimation(void)
u8 animationId = gBattleBufferA[gActiveBank][1];
u16 argument = gBattleBufferA[gActiveBank][2] | (gBattleBufferA[gActiveBank][3] << 8);
- if (DoBattleAnimationFromTable(gActiveBank, gActiveBank, gActiveBank, animationId, argument))
+ if (TryHandleLaunchBattleTableAnimation(gActiveBank, gActiveBank, gActiveBank, animationId, argument))
RecordedPlayerBufferExecCompleted();
else
gBattleBankFunc[gActiveBank] = CompleteOnFinishedBattleAnimation;
diff --git a/src/battle_controller_safari.c b/src/battle_controller_safari.c
index 0c5b698cf..a4f35bed1 100644
--- a/src/battle_controller_safari.c
+++ b/src/battle_controller_safari.c
@@ -33,7 +33,7 @@ extern u8 gBattleBufferA[BATTLE_BANKS_COUNT][0x200];
extern u8 gBattleBufferB[BATTLE_BANKS_COUNT][0x200];
extern struct BattlePokemon gBattleMons[BATTLE_BANKS_COUNT];
extern struct SpriteTemplate gUnknown_0202499C;
-extern u16 gScriptItemId;
+extern u16 gSpecialVar_ItemId;
extern u8 gHealthBoxesIds[BATTLE_BANKS_COUNT];
extern u8 gBattleOutcome;
extern u16 gBattle_BG0_X;
@@ -305,7 +305,7 @@ static void CompleteWhenChosePokeblock(void)
{
if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active)
{
- EmitOneReturnValue(1, gScriptItemId);
+ EmitOneReturnValue(1, gSpecialVar_ItemId);
SafariBufferExecCompleted();
}
}
@@ -413,7 +413,7 @@ static void SafariHandleSuccessBallThrowAnim(void)
{
gBattleSpritesDataPtr->animationData->ballThrowCaseId = BALL_3_SHAKES_SUCCESS;
gDoingBattleAnim = TRUE;
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, GetBankByIdentity(IDENTITY_OPPONENT_MON1), B_ANIM_SAFARI_BALL_THROW);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, GetBankByIdentity(IDENTITY_OPPONENT_MON1), B_ANIM_SAFARI_BALL_THROW);
gBattleBankFunc[gActiveBank] = CompleteOnSpecialAnimDone;
}
@@ -423,7 +423,7 @@ static void SafariHandleBallThrowAnim(void)
gBattleSpritesDataPtr->animationData->ballThrowCaseId = ballThrowCaseId;
gDoingBattleAnim = TRUE;
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, GetBankByIdentity(IDENTITY_OPPONENT_MON1), B_ANIM_SAFARI_BALL_THROW);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, GetBankByIdentity(IDENTITY_OPPONENT_MON1), B_ANIM_SAFARI_BALL_THROW);
gBattleBankFunc[gActiveBank] = CompleteOnSpecialAnimDone;
}
@@ -624,7 +624,7 @@ static void SafariHandlePlayFanfareOrBGM(void)
{
if (gBattleBufferA[gActiveBank][3])
{
- BattleMusicStop();
+ BattleStopLowHpSound();
PlayBGM(gBattleBufferA[gActiveBank][1] | (gBattleBufferA[gActiveBank][2] << 8));
}
else
@@ -683,7 +683,7 @@ static void SafariHandleBattleAnimation(void)
u8 animationId = gBattleBufferA[gActiveBank][1];
u16 argument = gBattleBufferA[gActiveBank][2] | (gBattleBufferA[gActiveBank][3] << 8);
- if (DoBattleAnimationFromTable(gActiveBank, gActiveBank, gActiveBank, animationId, argument))
+ if (TryHandleLaunchBattleTableAnimation(gActiveBank, gActiveBank, gActiveBank, animationId, argument))
SafariBufferExecCompleted();
else
gBattleBankFunc[gActiveBank] = CompleteOnFinishedBattleAnimation;
diff --git a/src/battle_controller_wally.c b/src/battle_controller_wally.c
index c2addd30c..4dac1d264 100644
--- a/src/battle_controller_wally.c
+++ b/src/battle_controller_wally.c
@@ -45,7 +45,7 @@ extern struct MusicPlayerInfo gMPlay_BGM;
extern u16 gPartnerTrainerId;
extern struct SpriteTemplate gUnknown_0202499C;
extern u8 gBattleMonForms[BATTLE_BANKS_COUNT];
-extern u16 gScriptItemId;
+extern u16 gSpecialVar_ItemId;
extern u8 gUnknown_03005D7C[BATTLE_BANKS_COUNT];
extern u8 gHealthBoxesIds[BATTLE_BANKS_COUNT];
extern u8 gBattleOutcome;
@@ -314,7 +314,7 @@ static void CompleteOnChosenItem(void)
{
if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active)
{
- EmitOneReturnValue(1, gScriptItemId);
+ EmitOneReturnValue(1, gSpecialVar_ItemId);
WallyBufferExecCompleted();
}
}
@@ -369,7 +369,7 @@ static void sub_8168818(void)
FreeSpritePaletteByTag(0x27F9);
CreateTask(c3_0802FDF4, 10);
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
WallyBufferExecCompleted();
}
@@ -387,7 +387,7 @@ static void CompleteOnHealthbarDone(void)
}
else
{
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
WallyBufferExecCompleted();
}
}
@@ -1029,7 +1029,7 @@ static void SetWallyMonData(u8 monId)
break;
}
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
}
static void WallyHandleSetRawMonData(void)
@@ -1051,7 +1051,7 @@ static void WallyHandleReturnMonToBall(void)
{
if (gBattleBufferA[gActiveBank][1] == 0)
{
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SWITCH_OUT_PLAYER_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SWITCH_OUT_PLAYER_MON);
gBattleBankFunc[gActiveBank] = sub_8168A20;
}
else
@@ -1112,7 +1112,7 @@ static void WallyHandleSuccessBallThrowAnim(void)
{
gBattleSpritesDataPtr->animationData->ballThrowCaseId = BALL_3_SHAKES_SUCCESS;
gDoingBattleAnim = TRUE;
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, GetBankByIdentity(IDENTITY_OPPONENT_MON1), B_ANIM_SAFARI_BALL_THROW);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, GetBankByIdentity(IDENTITY_OPPONENT_MON1), B_ANIM_SAFARI_BALL_THROW);
gBattleBankFunc[gActiveBank] = CompleteOnFinishedAnimation;
}
@@ -1122,7 +1122,7 @@ static void WallyHandleBallThrowAnim(void)
gBattleSpritesDataPtr->animationData->ballThrowCaseId = ballThrowCaseId;
gDoingBattleAnim = TRUE;
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, GetBankByIdentity(IDENTITY_OPPONENT_MON1), B_ANIM_SAFARI_BALL_THROW);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, GetBankByIdentity(IDENTITY_OPPONENT_MON1), B_ANIM_SAFARI_BALL_THROW);
gBattleBankFunc[gActiveBank] = CompleteOnFinishedAnimation;
}
@@ -1163,7 +1163,7 @@ static void WallyDoMoveAnimation(void)
case 0:
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
{
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON);
}
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 1;
break;
@@ -1182,7 +1182,7 @@ static void WallyDoMoveAnimation(void)
sub_805EB9C(1);
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
{
- DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
+ InitAndLaunchSpecialAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE);
}
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 3;
}
@@ -1190,7 +1190,7 @@ static void WallyDoMoveAnimation(void)
case 3:
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive)
{
- sub_805E394();
+ CopyAllBattleSpritesInvisibilities();
TrySetBehindSubstituteSpriteBit(gActiveBank, gBattleBufferA[gActiveBank][1] | (gBattleBufferA[gActiveBank][2] << 8));
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0;
WallyBufferExecCompleted();
@@ -1429,7 +1429,7 @@ static void WallyHandlePlayFanfareOrBGM(void)
{
if (gBattleBufferA[gActiveBank][3])
{
- BattleMusicStop();
+ BattleStopLowHpSound();
PlayBGM(gBattleBufferA[gActiveBank][1] | (gBattleBufferA[gActiveBank][2] << 8));
}
else
@@ -1496,7 +1496,7 @@ static void sub_816AA80(u8 bank)
sub_806A068(species, GetBankIdentity(bank));
gBankSpriteIds[bank] = CreateSprite(&gUnknown_0202499C,
sub_80A5C6C(bank, 2),
- sub_80A6138(bank),
+ GetBankSpriteDefault_Y(bank),
sub_80A82E4(bank));
gSprites[gUnknown_03005D7C[bank]].data1 = gBankSpriteIds[bank];
@@ -1565,7 +1565,7 @@ static void WallyHandleBattleAnimation(void)
u8 animationId = gBattleBufferA[gActiveBank][1];
u16 argument = gBattleBufferA[gActiveBank][2] | (gBattleBufferA[gActiveBank][3] << 8);
- if (DoBattleAnimationFromTable(gActiveBank, gActiveBank, gActiveBank, animationId, argument))
+ if (TryHandleLaunchBattleTableAnimation(gActiveBank, gActiveBank, gActiveBank, animationId, argument))
WallyBufferExecCompleted();
else
gBattleBankFunc[gActiveBank] = CompleteOnFinishedBattleAnimation;
diff --git a/src/battle_controllers.c b/src/battle_controllers.c
index 5c874438e..858540a9f 100644
--- a/src/battle_controllers.c
+++ b/src/battle_controllers.c
@@ -113,7 +113,7 @@ void sub_8032768(void)
sub_8184DA4(2);
if (!(gBattleTypeFlags & BATTLE_TYPE_RECORDED))
- sub_8185EB8();
+ RecordedBattle_SaveParties();
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
SetControllersVariablesInLinkBattle();
diff --git a/src/battle_dome_cards.c b/src/battle_dome_cards.c
index e6c67b20e..9385417b4 100644
--- a/src/battle_dome_cards.c
+++ b/src/battle_dome_cards.c
@@ -119,7 +119,7 @@ static void sub_818D0C4(u16 species, u32 otId, u32 personality, u8 paletteSlot,
if (paletteTag == 0xFFFF)
{
gUnknown_0203CCEC.paletteTag |= 0xFFFF;
- LoadCompressedPalette(species_and_otid_get_pal(species, otId, personality), 0x100 + paletteSlot * 0x10, 0x20);
+ LoadCompressedPalette(GetFrontSpritePalFromSpeciesAndPersonality(species, otId, personality), 0x100 + paletteSlot * 0x10, 0x20);
}
else
{
@@ -146,7 +146,7 @@ static void sub_818D180(u16 species, u32 otId, u32 personality, u8 paletteSlot,
{
if (!isTrainer)
{
- LoadCompressedPalette(species_and_otid_get_pal(species, otId, personality), paletteSlot * 0x10, 0x20);
+ LoadCompressedPalette(GetFrontSpritePalFromSpeciesAndPersonality(species, otId, personality), paletteSlot * 0x10, 0x20);
}
else
{
diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c
new file mode 100644
index 000000000..99a82f3ca
--- /dev/null
+++ b/src/battle_gfx_sfx_util.c
@@ -0,0 +1,1299 @@
+#include "global.h"
+#include "battle.h"
+#include "battle_controllers.h"
+#include "battle_ai_script_commands.h"
+#include "battle_anim.h"
+#include "battle_interface.h"
+#include "main.h"
+#include "malloc.h"
+#include "rng.h"
+#include "util.h"
+#include "pokemon.h"
+#include "moves.h"
+#include "task.h"
+#include "sprite.h"
+#include "sound.h"
+#include "m4a.h"
+#include "species.h"
+#include "decompress.h"
+#include "data2.h"
+#include "palette.h"
+#include "blend_palette.h"
+#include "contest.h"
+#include "songs.h"
+
+extern u8 gBattleBufferA[BATTLE_BANKS_COUNT][0x200];
+extern u8 gActiveBank;
+extern u8 gNoOfAllBanks;
+extern u16 gUnknown_020243FC;
+extern u16 gBattlePartyID[BATTLE_BANKS_COUNT];
+extern struct BattlePokemon gBattleMons[BATTLE_BANKS_COUNT];
+extern u8 gBanksByIdentity[BATTLE_BANKS_COUNT];
+extern u8 gBankSpriteIds[BATTLE_BANKS_COUNT];
+extern u8 gHealthBoxesIds[BATTLE_BANKS_COUNT];
+extern u8 gBattleMonForms[BATTLE_BANKS_COUNT];
+extern u32 gTransformedPersonalities[BATTLE_BANKS_COUNT];
+extern struct MusicPlayerInfo gMPlay_SE1;
+extern struct MusicPlayerInfo gMPlay_SE2;
+extern struct MusicPlayerInfo gMPlay_BGM;
+
+extern const struct BattleMove gBattleMoves[];
+extern const u8 gUnknown_0831C604[];
+extern const u8 * const gUnknown_082C9320[];
+extern const u8 * const gUnknown_082C937C[];
+extern const struct CompressedSpriteSheet gMonFrontPicTable[];
+extern const struct CompressedSpriteSheet gMonBackPicTable[];
+extern const struct CompressedSpriteSheet gTrainerFrontPicTable[];
+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[];
+
+// graphics
+extern const u32 gUnknown_08C093F0[];
+extern const u32 gSubstituteDollTilemap[];
+extern const u32 gSubstituteDollGfx[];
+extern const u16 gSubstituteDollPal[];
+extern const u8 gUnknown_08C1F1C8[];
+extern const u8 gUnknown_08C1F46C[];
+extern const u8 gUnknown_08C1F5E8[];
+extern const u8 gUnknown_08C1F76C[];
+extern const u8 gUnknown_08C1F8E8[];
+extern const u8 gUnknown_08C0237C[];
+extern const u16 gBattleInterface_BallStatusBarPal[];
+extern const u16 gBattleInterface_BallDisplayPal[];
+
+extern u8 sub_80688F8(u8, u8 bank);
+extern u8 pokemon_order_func(u8); // party menu
+extern void sub_81B8C68(void);
+
+// this file's functions
+static u8 sub_805D4A8(u16 move);
+static u16 BattlePalaceGetTargetRetValue(void);
+static void sub_805D7EC(struct Sprite *sprite);
+static bool8 ShouldAnimBeDoneRegardlessOfSubsitute(u8 animId);
+static void Task_ClearBitWhenBattleTableAnimDone(u8 taskId);
+static void Task_ClearBitWhenSpecialAnimDone(u8 taskId);
+static void ClearSpritesBankHealthboxAnimData(void);
+
+// const rom data
+static const struct CompressedSpriteSheet gUnknown_0832C0D0 =
+{
+ gUnknown_08C1F1C8, 0x1000, TAG_HEALTHBOX_PLAYER1_TILE
+};
+
+static const struct CompressedSpriteSheet gUnknown_0832C0D8 =
+{
+ gUnknown_08C1F46C, 0x1000, TAG_HEALTHBOX_OPPONENT1_TILE
+};
+
+static const struct CompressedSpriteSheet gUnknown_0832C0E0[2] =
+{
+ {gUnknown_08C1F5E8, 0x800, TAG_HEALTHBOX_PLAYER1_TILE},
+ {gUnknown_08C1F5E8, 0x800, TAG_HEALTHBOX_PLAYER2_TILE}
+};
+
+static const struct CompressedSpriteSheet gUnknown_0832C0F0[2] =
+{
+ {gUnknown_08C1F76C, 0x800, TAG_HEALTHBOX_OPPONENT1_TILE},
+ {gUnknown_08C1F76C, 0x800, TAG_HEALTHBOX_OPPONENT2_TILE}
+};
+
+static const struct CompressedSpriteSheet gUnknown_0832C100 =
+{
+ gUnknown_08C1F8E8, 0x1000, TAG_HEALTHBOX_SAFARI_TILE
+};
+
+static const struct CompressedSpriteSheet gUnknown_0832C108[BATTLE_BANKS_COUNT] =
+{
+ {gUnknown_08C0237C, 0x0100, 0xd704},
+ {gUnknown_08C0237C, 0x0120, 0xd705},
+ {gUnknown_08C0237C, 0x0100, 0xd706},
+ {gUnknown_08C0237C, 0x0120, 0xd707}
+};
+
+static const struct SpritePalette gUnknown_0832C128[2] =
+{
+ {gBattleInterface_BallStatusBarPal, TAG_HEALTHBOX_PAL},
+ {gBattleInterface_BallDisplayPal, 0xd704}
+};
+
+// code
+void AllocateBattleSpritesData(void)
+{
+ gBattleSpritesDataPtr = AllocZeroed(sizeof(struct BattleSpriteData));
+ gBattleSpritesDataPtr->bankData = AllocZeroed(sizeof(struct BattleSpriteInfo) * BATTLE_BANKS_COUNT);
+ gBattleSpritesDataPtr->healthBoxesData = AllocZeroed(sizeof(struct BattleHealthboxInfo) * BATTLE_BANKS_COUNT);
+ gBattleSpritesDataPtr->animationData = AllocZeroed(sizeof(struct BattleAnimationInfo));
+ gBattleSpritesDataPtr->battleBars = AllocZeroed(sizeof(struct BattleBarInfo) * BATTLE_BANKS_COUNT);
+}
+
+void FreeBattleSpritesData(void)
+{
+ if (gBattleSpritesDataPtr == NULL)
+ return;
+
+ FREE_AND_SET_NULL(gBattleSpritesDataPtr->battleBars);
+ FREE_AND_SET_NULL(gBattleSpritesDataPtr->animationData);
+ FREE_AND_SET_NULL(gBattleSpritesDataPtr->healthBoxesData);
+ FREE_AND_SET_NULL(gBattleSpritesDataPtr->bankData);
+ FREE_AND_SET_NULL(gBattleSpritesDataPtr);
+}
+
+u16 ChooseMoveAndTargetInBattlePalace(void)
+{
+ s32 i, var1, var2;
+ s32 chosenMoveId = -1;
+ struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct*)(&gBattleBufferA[gActiveBank][4]);
+ u8 unusableMovesBits = CheckMoveLimitations(gActiveBank, 0, 0xFF);
+ s32 percent = Random() % 100;
+
+ i = (gBattleStruct->field_92 & gBitTable[gActiveBank]) ? 2 : 0;
+ var2 = i;
+ var1 = i + 2;
+
+ for (; i < var1; i++)
+ {
+ if (gUnknown_0831C494[GetNatureFromPersonality(gBattleMons[gActiveBank].personality)][i] > percent)
+ break;
+ }
+
+ percent = i - var2;
+ if (i == var1)
+ percent = 2;
+
+ for (var2 = 0, i = 0; i < 4; i++)
+ {
+ if (moveInfo->moves[i] == MOVE_NONE)
+ break;
+ if (percent == sub_805D4A8(moveInfo->moves[i]) && moveInfo->currentPp[i] != 0)
+ var2 |= gBitTable[i];
+ }
+
+ if (var2 != 0)
+ {
+ gBattleStruct->field_92 &= 0xF;
+ gBattleStruct->field_92 |= (var2 << 4);
+ BattleAI_SetupAIData(var2);
+ chosenMoveId = BattleAI_ChooseMoveOrAction();
+ }
+
+ if (chosenMoveId == -1)
+ {
+ if (unusableMovesBits != 0xF)
+ {
+ var1 = 0, var2 = 0;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (sub_805D4A8(moveInfo->moves[i]) == 0 && !(gBitTable[i] & unusableMovesBits))
+ var1 += 0x1;
+ if (sub_805D4A8(moveInfo->moves[i]) == 1 && !(gBitTable[i] & unusableMovesBits))
+ var1 += 0x10;
+ if (sub_805D4A8(moveInfo->moves[i]) == 2 && !(gBitTable[i] & unusableMovesBits))
+ var1 += 0x100;
+ }
+
+ if ((var1 & 0xF) > 1)
+ var2++;
+ if ((var1 & 0xF0) > 0x1F)
+ var2++;
+ if ((var1 & 0xF0) > 0x1FF)
+ var2++;
+
+ if (var2 > 1 || var2 == 0)
+ {
+ do
+ {
+ i = Random() % 4;
+ if (!(gBitTable[i] & unusableMovesBits))
+ chosenMoveId = i;
+ } while (chosenMoveId == -1);
+ }
+ else
+ {
+ if ((var1 & 0xF) > 1)
+ var2 = 0;
+ if ((var1 & 0xF0) > 0x1F)
+ var2 = 1;
+ if ((var1 & 0xF0) > 0x1FF)
+ var2 = 2;
+
+ do
+ {
+ i = Random() % 4;
+ if (!(gBitTable[i] & unusableMovesBits) && var2 == sub_805D4A8(moveInfo->moves[i]))
+ chosenMoveId = i;
+ } while (chosenMoveId == -1);
+ }
+
+ if (Random() % 100 > 49)
+ {
+ gProtectStructs[gActiveBank].flag_x10 = 1;
+ return 0;
+ }
+ }
+ else
+ {
+ gProtectStructs[gActiveBank].flag_x10 = 1;
+ return 0;
+ }
+ }
+
+ if (moveInfo->moves[chosenMoveId] == MOVE_CURSE)
+ {
+ if (moveInfo->monType1 != TYPE_GHOST && moveInfo->monType2 != TYPE_GHOST)
+ var1 = MOVE_TARGET_x10;
+ else
+ var1 = MOVE_TARGET_SELECTED;
+ }
+ else
+ {
+ var1 = gBattleMoves[moveInfo->moves[chosenMoveId]].target;
+ }
+
+ if (var1 & MOVE_TARGET_x10)
+ chosenMoveId |= (gActiveBank << 8);
+ else if (var1 == MOVE_TARGET_SELECTED)
+ chosenMoveId |= (BattlePalaceGetTargetRetValue());
+ else
+ chosenMoveId |= (GetBankByIdentity((GetBankIdentity(gActiveBank) & BIT_SIDE) ^ BIT_SIDE) << 8);
+
+ return chosenMoveId;
+}
+
+static u8 sub_805D4A8(u16 move)
+{
+ switch (gBattleMoves[move].target)
+ {
+ case MOVE_TARGET_SELECTED:
+ case MOVE_TARGET_USER:
+ case MOVE_TARGET_RANDOM:
+ case MOVE_TARGET_BOTH:
+ case MOVE_TARGET_FOES_AND_ALLY:
+ if (gBattleMoves[move].power == 0)
+ return 2;
+ else
+ return 0;
+ break;
+ case MOVE_TARGET_DEPENDS:
+ case MOVE_TARGET_OPPONENTS_FIELD:
+ return 2;
+ case MOVE_TARGET_x10:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static u16 BattlePalaceGetTargetRetValue(void)
+{
+ if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
+ {
+ u8 opposing1, opposing2;
+
+ if (GetBankSide(gActiveBank) == SIDE_PLAYER)
+ {
+ opposing1 = GetBankByIdentity(IDENTITY_OPPONENT_MON1);
+ opposing2 = GetBankByIdentity(IDENTITY_OPPONENT_MON2);
+ }
+ else
+ {
+ opposing1 = GetBankByIdentity(IDENTITY_PLAYER_MON1);
+ opposing2 = GetBankByIdentity(IDENTITY_PLAYER_MON2);
+ }
+
+ if (gBattleMons[opposing1].hp == gBattleMons[opposing2].hp)
+ return (((gActiveBank & BIT_SIDE) ^ BIT_SIDE) + (Random() & 2)) << 8;
+
+ switch (gUnknown_0831C604[GetNatureFromPersonality(gBattleMons[gActiveBank].personality)])
+ {
+ case 0:
+ if (gBattleMons[opposing1].hp > gBattleMons[opposing2].hp)
+ return opposing1 << 8;
+ else
+ return opposing2 << 8;
+ case 1:
+ if (gBattleMons[opposing1].hp < gBattleMons[opposing2].hp)
+ return opposing1 << 8;
+ else
+ return opposing2 << 8;
+ case 2:
+ return (((gActiveBank & BIT_SIDE) ^ BIT_SIDE) + (Random() & 2)) << 8;
+ }
+ }
+
+ return (gActiveBank ^ BIT_SIDE) << 8;
+}
+
+void sub_805D714(struct Sprite *sprite)
+{
+ u8 spriteId = sprite->data1;
+
+ if (!gSprites[spriteId].affineAnimEnded)
+ return;
+ if (gSprites[spriteId].invisible)
+ return;
+
+ if (gSprites[spriteId].animPaused)
+ {
+ gSprites[spriteId].animPaused = 0;
+ }
+ else
+ {
+ if (gSprites[spriteId].animEnded)
+ sprite->callback = SpriteCallbackDummy;
+ }
+}
+
+void sub_805D770(struct Sprite *sprite, bool8 arg1)
+{
+ sprite->animPaused = 1;
+ sprite->callback = SpriteCallbackDummy;
+
+ if (!arg1)
+ StartSpriteAffineAnim(sprite, 1);
+ else
+ StartSpriteAffineAnim(sprite, 1);
+
+ AnimateSprite(sprite);
+}
+
+void sub_805D7AC(struct Sprite *sprite)
+{
+ if (!(gUnknown_020243FC & 1))
+ {
+ sprite->pos2.x += sprite->data0;
+ if (sprite->pos2.x == 0)
+ {
+ if (sprite->pos2.y != 0)
+ sprite->callback = sub_805D7EC;
+ else
+ sprite->callback = SpriteCallbackDummy;
+ }
+ }
+}
+
+static void sub_805D7EC(struct Sprite *sprite)
+{
+ sprite->pos2.y -= 2;
+ if (sprite->pos2.y == 0)
+ sprite->callback = SpriteCallbackDummy;
+}
+
+void InitAndLaunchChosenStatusAnimation(bool8 isStatus2, u32 status)
+{
+ gBattleSpritesDataPtr->healthBoxesData[gActiveBank].statusAnimActive = 1;
+ if (!isStatus2)
+ {
+ if (status == STATUS_FREEZE)
+ LaunchStatusAnimation(gActiveBank, B_ANIM_STATUS_FRZ);
+ else if (status == STATUS_POISON || status & STATUS_TOXIC_POISON)
+ LaunchStatusAnimation(gActiveBank, B_ANIM_STATUS_PSN);
+ else if (status == STATUS_BURN)
+ LaunchStatusAnimation(gActiveBank, B_ANIM_STATUS_BRN);
+ else if (status & STATUS_SLEEP)
+ LaunchStatusAnimation(gActiveBank, B_ANIM_STATUS_SLP);
+ else if (status == STATUS_PARALYSIS)
+ LaunchStatusAnimation(gActiveBank, B_ANIM_STATUS_PRZ);
+ else // no animation
+ gBattleSpritesDataPtr->healthBoxesData[gActiveBank].statusAnimActive = 0;
+ }
+ else
+ {
+ if (status & STATUS2_INFATUATION)
+ LaunchStatusAnimation(gActiveBank, B_ANIM_STATUS_INFATUATION);
+ else if (status & STATUS2_CONFUSION)
+ LaunchStatusAnimation(gActiveBank, B_ANIM_STATUS_CONFUSION);
+ else if (status & STATUS2_CURSED)
+ LaunchStatusAnimation(gActiveBank, B_ANIM_STATUS_CURSED);
+ else if (status & STATUS2_NIGHTMARE)
+ LaunchStatusAnimation(gActiveBank, B_ANIM_STATUS_NIGHTMARE);
+ else if (status & STATUS2_WRAPPED)
+ LaunchStatusAnimation(gActiveBank, B_ANIM_STATUS_WRAPPED);
+ else // no animation
+ gBattleSpritesDataPtr->healthBoxesData[gActiveBank].statusAnimActive = 0;
+ }
+}
+
+#define tBank data[0]
+
+bool8 TryHandleLaunchBattleTableAnimation(u8 activeBank, u8 atkBank, u8 defBank, u8 tableId, u16 argument)
+{
+ u8 taskId;
+
+ if (tableId == B_ANIM_CASTFORM_CHANGE && (argument & 0x80))
+ {
+ gBattleMonForms[activeBank] = (argument & ~(0x80));
+ return TRUE;
+ }
+ if (gBattleSpritesDataPtr->bankData[activeBank].behindSubstitute
+ && !ShouldAnimBeDoneRegardlessOfSubsitute(tableId))
+ {
+ return TRUE;
+ }
+ if (gBattleSpritesDataPtr->bankData[activeBank].behindSubstitute
+ && tableId == B_ANIM_SUBSTITUTE_FADE
+ && gSprites[gBankSpriteIds[activeBank]].invisible)
+ {
+ LoadBattleMonGfxAndAnimate(activeBank, TRUE, gBankSpriteIds[activeBank]);
+ ClearBehindSubstituteBit(activeBank);
+ return TRUE;
+ }
+
+ gAnimBankAttacker = atkBank;
+ gAnimBankTarget = defBank;
+ gBattleSpritesDataPtr->animationData->animArg = argument;
+ LaunchBattleAnimation(gUnknown_082C9320, tableId, FALSE);
+ taskId = CreateTask(Task_ClearBitWhenBattleTableAnimDone, 10);
+ gTasks[taskId].tBank = activeBank;
+ gBattleSpritesDataPtr->healthBoxesData[gTasks[taskId].tBank].animFromTableActive = 1;
+
+ return FALSE;
+}
+
+static void Task_ClearBitWhenBattleTableAnimDone(u8 taskId)
+{
+ gAnimScriptCallback();
+ if (!gAnimScriptActive)
+ {
+ gBattleSpritesDataPtr->healthBoxesData[gTasks[taskId].tBank].animFromTableActive = 0;
+ DestroyTask(taskId);
+ }
+}
+
+#undef tBank
+
+static bool8 ShouldAnimBeDoneRegardlessOfSubsitute(u8 animId)
+{
+ switch (animId)
+ {
+ case B_ANIM_SUBSTITUTE_FADE:
+ case B_ANIM_RAIN_CONTINUES:
+ case B_ANIM_SUN_CONTINUES:
+ case B_ANIM_SANDSTORM_CONTINUES:
+ case B_ANIM_HAIL_CONTINUES:
+ case B_ANIM_SNATCH_MOVE:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+#define tBank data[0]
+
+void InitAndLaunchSpecialAnimation(u8 activeBank, u8 atkBank, u8 defBank, u8 tableId)
+{
+ u8 taskId;
+
+ gAnimBankAttacker = atkBank;
+ gAnimBankTarget = defBank;
+ LaunchBattleAnimation(gUnknown_082C937C, tableId, FALSE);
+ taskId = CreateTask(Task_ClearBitWhenSpecialAnimDone, 10);
+ gTasks[taskId].tBank = activeBank;
+ gBattleSpritesDataPtr->healthBoxesData[gTasks[taskId].tBank].specialAnimActive = 1;
+}
+
+static void Task_ClearBitWhenSpecialAnimDone(u8 taskId)
+{
+ gAnimScriptCallback();
+ if (!gAnimScriptActive)
+ {
+ gBattleSpritesDataPtr->healthBoxesData[gTasks[taskId].tBank].specialAnimActive = 0;
+ DestroyTask(taskId);
+ }
+}
+
+#undef tBank
+
+// great function to include newly added moves that don't have animation yet
+bool8 IsMoveWithoutAnimation(u16 moveId, u8 animationTurn)
+{
+ return FALSE;
+}
+
+bool8 mplay_80342A4(u8 bank)
+{
+ u8 zero = 0;
+
+ if (IsSEPlaying())
+ {
+ gBattleSpritesDataPtr->healthBoxesData[bank].field_8++;
+ if (gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_8 < 30)
+ return TRUE;
+
+ m4aMPlayStop(&gMPlay_SE1);
+ m4aMPlayStop(&gMPlay_SE2);
+ }
+ if (zero == 0)
+ {
+ gBattleSpritesDataPtr->healthBoxesData[bank].field_8 = 0;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void BattleLoadOpponentMonSpriteGfx(struct Pokemon *mon, u8 bank)
+{
+ u32 monsPersonality, currentPersonality, otId;
+ u16 species;
+ u8 identity;
+ u16 paletteOffset;
+ const void *lzPaletteData;
+
+ monsPersonality = GetMonData(mon, MON_DATA_PERSONALITY);
+
+ if (gBattleSpritesDataPtr->bankData[bank].transformSpecies == SPECIES_NONE)
+ {
+ species = GetMonData(mon, MON_DATA_SPECIES);
+ currentPersonality = monsPersonality;
+ }
+ else
+ {
+ species = gBattleSpritesDataPtr->bankData[bank].transformSpecies;
+ currentPersonality = gTransformedPersonalities[bank];
+ }
+
+ otId = GetMonData(mon, MON_DATA_OT_ID);
+ identity = GetBankIdentity(bank);
+ HandleLoadSpecialPokePic_DontHandleDeoxys(&gMonFrontPicTable[species],
+ gMonSpritesGfxPtr->sprites[identity],
+ species, currentPersonality);
+
+ paletteOffset = 0x100 + bank * 16;
+
+ if (gBattleSpritesDataPtr->bankData[bank].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);
+
+ if (species == SPECIES_CASTFORM)
+ {
+ paletteOffset = 0x100 + bank * 16;
+ LZDecompressWram(lzPaletteData, gBattleStruct->castformPalette[0]);
+ LoadPalette(gBattleStruct->castformPalette[gBattleMonForms[bank]], paletteOffset, 0x20);
+ }
+
+ // transform's pink color
+ if (gBattleSpritesDataPtr->bankData[bank].transformSpecies != SPECIES_NONE)
+ {
+ BlendPalette(paletteOffset, 16, 6, 0x7FFF);
+ CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, 32);
+ }
+}
+
+void BattleLoadPlayerMonSpriteGfx(struct Pokemon *mon, u8 bank)
+{
+ u32 monsPersonality, currentPersonality, otId;
+ u16 species;
+ u8 identity;
+ u16 paletteOffset;
+ const void *lzPaletteData;
+
+ monsPersonality = GetMonData(mon, MON_DATA_PERSONALITY);
+
+ if (gBattleSpritesDataPtr->bankData[bank].transformSpecies == SPECIES_NONE)
+ {
+ species = GetMonData(mon, MON_DATA_SPECIES);
+ currentPersonality = monsPersonality;
+ }
+ else
+ {
+ species = gBattleSpritesDataPtr->bankData[bank].transformSpecies;
+ currentPersonality = gTransformedPersonalities[bank];
+ }
+
+ otId = GetMonData(mon, MON_DATA_OT_ID);
+ identity = GetBankIdentity(bank);
+
+ if (sub_80688F8(1, bank) == 1 || gBattleSpritesDataPtr->bankData[bank].transformSpecies != SPECIES_NONE)
+ {
+ HandleLoadSpecialPokePic_DontHandleDeoxys(&gMonBackPicTable[species],
+ gMonSpritesGfxPtr->sprites[identity],
+ species, currentPersonality);
+ }
+ else
+ {
+ HandleLoadSpecialPokePic(&gMonBackPicTable[species],
+ gMonSpritesGfxPtr->sprites[identity],
+ species, currentPersonality);
+ }
+
+ paletteOffset = 0x100 + bank * 16;
+
+ if (gBattleSpritesDataPtr->bankData[bank].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);
+
+ if (species == SPECIES_CASTFORM)
+ {
+ paletteOffset = 0x100 + bank * 16;
+ LZDecompressWram(lzPaletteData, gBattleStruct->castformPalette[0]);
+ LoadPalette(gBattleStruct->castformPalette[gBattleMonForms[bank]], paletteOffset, 0x20);
+ }
+
+ // transform's pink color
+ if (gBattleSpritesDataPtr->bankData[bank].transformSpecies != SPECIES_NONE)
+ {
+ BlendPalette(paletteOffset, 16, 6, 0x7FFF);
+ CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, 32);
+ }
+}
+
+void nullsub_23(void)
+{
+}
+
+void nullsub_24(u16 species)
+{
+}
+
+void DecompressTrainerFrontPic(u16 frontPicId, u8 bank)
+{
+ u8 identity = GetBankIdentity(bank);
+ DecompressPicFromTable_2(&gTrainerFrontPicTable[frontPicId],
+ gMonSpritesGfxPtr->sprites[identity],
+ SPECIES_NONE);
+ LoadCompressedObjectPalette(&gTrainerFrontPicPaletteTable[frontPicId]);
+}
+
+void DecompressTrainerBackPic(u16 backPicId, u8 bank)
+{
+ u8 identity = GetBankIdentity(bank);
+ DecompressPicFromTable_2(&gTrainerBackPicTable[backPicId],
+ gMonSpritesGfxPtr->sprites[identity],
+ SPECIES_NONE);
+ LoadCompressedPalette(gTrainerBackPicPaletteTable[backPicId].data,
+ 0x100 + 16 * bank, 0x20);
+}
+
+void nullsub_25(u8 arg0)
+{
+}
+
+void FreeTrainerFrontPicPalette(u16 frontPicId)
+{
+ FreeSpritePaletteByTag(gTrainerFrontPicPaletteTable[frontPicId].tag);
+}
+
+void sub_805DFFC(void)
+{
+ u8 numberOfBanks = 0;
+ u8 i;
+
+ LoadSpritePalette(&gUnknown_0832C128[0]);
+ LoadSpritePalette(&gUnknown_0832C128[1]);
+ if (!IsDoubleBattle())
+ {
+ LoadCompressedObjectPic(&gUnknown_0832C0D0);
+ LoadCompressedObjectPic(&gUnknown_0832C0D8);
+ numberOfBanks = 2;
+ }
+ else
+ {
+ LoadCompressedObjectPic(&gUnknown_0832C0E0[0]);
+ LoadCompressedObjectPic(&gUnknown_0832C0E0[1]);
+ LoadCompressedObjectPic(&gUnknown_0832C0F0[0]);
+ LoadCompressedObjectPic(&gUnknown_0832C0F0[1]);
+ numberOfBanks = 4;
+ }
+ for (i = 0; i < numberOfBanks; i++)
+ LoadCompressedObjectPic(&gUnknown_0832C108[gBanksByIdentity[i]]);
+}
+
+bool8 BattleLoadAllHealthBoxesGfx(u8 state)
+{
+ bool8 retVal = FALSE;
+
+ if (state != 0)
+ {
+ if (state == 1)
+ {
+ LoadSpritePalette(&gUnknown_0832C128[0]);
+ LoadSpritePalette(&gUnknown_0832C128[1]);
+ }
+ else if (!IsDoubleBattle())
+ {
+ if (state == 2)
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_SAFARI)
+ LoadCompressedObjectPic(&gUnknown_0832C100);
+ else
+ LoadCompressedObjectPic(&gUnknown_0832C0D0);
+ }
+ else if (state == 3)
+ LoadCompressedObjectPic(&gUnknown_0832C0D8);
+ else if (state == 4)
+ LoadCompressedObjectPic(&gUnknown_0832C108[gBanksByIdentity[0]]);
+ else if (state == 5)
+ LoadCompressedObjectPic(&gUnknown_0832C108[gBanksByIdentity[1]]);
+ else
+ retVal = TRUE;
+ }
+ else
+ {
+ if (state == 2)
+ LoadCompressedObjectPic(&gUnknown_0832C0E0[0]);
+ else if (state == 3)
+ LoadCompressedObjectPic(&gUnknown_0832C0E0[1]);
+ else if (state == 4)
+ LoadCompressedObjectPic(&gUnknown_0832C0F0[0]);
+ else if (state == 5)
+ LoadCompressedObjectPic(&gUnknown_0832C0F0[1]);
+ else if (state == 6)
+ LoadCompressedObjectPic(&gUnknown_0832C108[gBanksByIdentity[0]]);
+ else if (state == 7)
+ LoadCompressedObjectPic(&gUnknown_0832C108[gBanksByIdentity[1]]);
+ else if (state == 8)
+ LoadCompressedObjectPic(&gUnknown_0832C108[gBanksByIdentity[2]]);
+ else if (state == 9)
+ LoadCompressedObjectPic(&gUnknown_0832C108[gBanksByIdentity[3]]);
+ else
+ retVal = TRUE;
+ }
+ }
+
+ return retVal;
+}
+
+void LoadBattleBarGfx(u8 arg0)
+{
+ LZDecompressWram(gUnknown_08C093F0, gMonSpritesGfxPtr->barFontGfx);
+}
+
+bool8 BattleInitAllSprites(u8 *state1, u8 *bank)
+{
+ bool8 retVal = FALSE;
+
+ switch (*state1)
+ {
+ case 0:
+ ClearSpritesBankHealthboxAnimData();
+ (*state1)++;
+ break;
+ case 1:
+ if (!BattleLoadAllHealthBoxesGfx(*bank))
+ {
+ (*bank)++;
+ }
+ else
+ {
+ *bank = 0;
+ (*state1)++;
+ }
+ break;
+ case 2:
+ (*state1)++;
+ break;
+ case 3:
+ if ((gBattleTypeFlags & BATTLE_TYPE_SAFARI) && *bank == 0)
+ gHealthBoxesIds[*bank] = CreateSafariPlayerHealthboxSprites();
+ else
+ gHealthBoxesIds[*bank] = CreateBankHealthboxSprites(*bank);
+
+ (*bank)++;
+ if (*bank == gNoOfAllBanks)
+ {
+ *bank = 0;
+ (*state1)++;
+ }
+ break;
+ case 4:
+ SetBankHealthboxSpritePos(*bank);
+ if (gBanksByIdentity[*bank] <= 1)
+ DummyBattleInterfaceFunc(gHealthBoxesIds[*bank], FALSE);
+ else
+ DummyBattleInterfaceFunc(gHealthBoxesIds[*bank], TRUE);
+
+ (*bank)++;
+ if (*bank == gNoOfAllBanks)
+ {
+ *bank = 0;
+ (*state1)++;
+ }
+ break;
+ case 5:
+ if (GetBankSide(*bank) == SIDE_PLAYER)
+ {
+ if (!(gBattleTypeFlags & BATTLE_TYPE_SAFARI))
+ UpdateHealthboxAttribute(gHealthBoxesIds[*bank], &gPlayerParty[gBattlePartyID[*bank]], HEALTHBOX_ALL);
+ }
+ else
+ {
+ UpdateHealthboxAttribute(gHealthBoxesIds[*bank], &gEnemyParty[gBattlePartyID[*bank]], HEALTHBOX_ALL);
+ }
+ SetHealthboxSpriteInvisible(gHealthBoxesIds[*bank]);
+ (*bank)++;
+ if (*bank == gNoOfAllBanks)
+ {
+ *bank = 0;
+ (*state1)++;
+ }
+ break;
+ case 6:
+ LoadAndCreateEnemyShadowSprites();
+ sub_81B8C68();
+ retVal = TRUE;
+ break;
+ }
+
+ return retVal;
+}
+
+void ClearSpritesHealthboxAnimData(void)
+{
+ memset(gBattleSpritesDataPtr->healthBoxesData, 0, sizeof(struct BattleHealthboxInfo) * BATTLE_BANKS_COUNT);
+ memset(gBattleSpritesDataPtr->animationData, 0, sizeof(struct BattleAnimationInfo));
+}
+
+static void ClearSpritesBankHealthboxAnimData(void)
+{
+ ClearSpritesHealthboxAnimData();
+ memset(gBattleSpritesDataPtr->bankData, 0, sizeof(struct BattleSpriteInfo) * BATTLE_BANKS_COUNT);
+}
+
+void CopyAllBattleSpritesInvisibilities(void)
+{
+ s32 i;
+
+ for (i = 0; i < gNoOfAllBanks; i++)
+ gBattleSpritesDataPtr->bankData[i].invisible = gSprites[gBankSpriteIds[i]].invisible;
+}
+
+void CopyBattleSpriteInvisibility(u8 bank)
+{
+ gBattleSpritesDataPtr->bankData[bank].invisible = gSprites[gBankSpriteIds[bank]].invisible;
+}
+
+void HandleSpeciesGfxDataChange(u8 bankAtk, u8 bankDef, bool8 notTransform)
+{
+ u16 paletteOffset;
+ u32 personalityValue;
+ u32 otId;
+ u8 identity;
+ const u8 *lzPaletteData;
+
+ if (notTransform)
+ {
+ StartSpriteAnim(&gSprites[gBankSpriteIds[bankAtk]], gBattleSpritesDataPtr->animationData->animArg);
+ paletteOffset = 0x100 + bankAtk * 16;
+ LoadPalette(gBattleStruct->castformPalette[gBattleSpritesDataPtr->animationData->animArg], paletteOffset, 32);
+ gBattleMonForms[bankAtk] = gBattleSpritesDataPtr->animationData->animArg;
+ if (gBattleSpritesDataPtr->bankData[bankAtk].transformSpecies != SPECIES_NONE)
+ {
+ BlendPalette(paletteOffset, 16, 6, 0x7FFF);
+ CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, 32);
+ }
+ gSprites[gBankSpriteIds[bankAtk]].pos1.y = GetBankSpriteDefault_Y(bankAtk);
+ }
+ else
+ {
+ const void *src;
+ void *dst;
+ u16 targetSpecies;
+
+ if (IsContest())
+ {
+ identity = 0;
+ targetSpecies = gContestResources->field_18->field_2;
+ personalityValue = gContestResources->field_18->field_8;
+ otId = gContestResources->field_18->field_C;
+
+ HandleLoadSpecialPokePic_DontHandleDeoxys(&gMonBackPicTable[targetSpecies],
+ gMonSpritesGfxPtr->sprites[0],
+ targetSpecies,
+ gContestResources->field_18->field_10);
+ }
+ else
+ {
+ identity = GetBankIdentity(bankAtk);
+
+ if (GetBankSide(bankDef) == SIDE_OPPONENT)
+ targetSpecies = GetMonData(&gEnemyParty[gBattlePartyID[bankDef]], MON_DATA_SPECIES);
+ else
+ targetSpecies = GetMonData(&gPlayerParty[gBattlePartyID[bankDef]], MON_DATA_SPECIES);
+
+ if (GetBankSide(bankAtk) == SIDE_PLAYER)
+ {
+ personalityValue = GetMonData(&gPlayerParty[gBattlePartyID[bankAtk]], MON_DATA_PERSONALITY);
+ otId = GetMonData(&gPlayerParty[gBattlePartyID[bankAtk]], MON_DATA_OT_ID);
+
+ HandleLoadSpecialPokePic_DontHandleDeoxys(&gMonBackPicTable[targetSpecies],
+ gMonSpritesGfxPtr->sprites[identity],
+ targetSpecies,
+ gTransformedPersonalities[bankAtk]);
+ }
+ else
+ {
+ personalityValue = GetMonData(&gEnemyParty[gBattlePartyID[bankAtk]], MON_DATA_PERSONALITY);
+ otId = GetMonData(&gEnemyParty[gBattlePartyID[bankAtk]], MON_DATA_OT_ID);
+
+ HandleLoadSpecialPokePic_DontHandleDeoxys(&gMonFrontPicTable[targetSpecies],
+ gMonSpritesGfxPtr->sprites[identity],
+ targetSpecies,
+ gTransformedPersonalities[bankAtk]);
+ }
+ }
+
+ src = gMonSpritesGfxPtr->sprites[identity];
+ dst = (void *)(VRAM + 0x10000 + gSprites[gBankSpriteIds[bankAtk]].oam.tileNum * 32);
+ DmaCopy32(3, src, dst, 0x800);
+ paletteOffset = 0x100 + bankAtk * 16;
+ lzPaletteData = GetFrontSpritePalFromSpeciesAndPersonality(targetSpecies, otId, personalityValue);
+ LZDecompressWram(lzPaletteData, gDecompressionBuffer);
+ LoadPalette(gDecompressionBuffer, paletteOffset, 32);
+
+ if (targetSpecies == SPECIES_CASTFORM)
+ {
+ gSprites[gBankSpriteIds[bankAtk]].anims = gMonAnimationsSpriteAnimsPtrTable[targetSpecies];
+ LZDecompressWram(lzPaletteData, gBattleStruct->castformPalette[0]);
+ LoadPalette(gBattleStruct->castformPalette[0] + gBattleMonForms[bankDef] * 16, paletteOffset, 32);
+ }
+
+ BlendPalette(paletteOffset, 16, 6, 0x7FFF);
+ CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, 32);
+
+ if (!IsContest())
+ {
+ gBattleSpritesDataPtr->bankData[bankAtk].transformSpecies = targetSpecies;
+ gBattleMonForms[bankAtk] = gBattleMonForms[bankDef];
+ }
+
+ gSprites[gBankSpriteIds[bankAtk]].pos1.y = GetBankSpriteDefault_Y(bankAtk);
+ StartSpriteAnim(&gSprites[gBankSpriteIds[bankAtk]], gBattleMonForms[bankAtk]);
+ }
+}
+
+void BattleLoadSubstituteOrMonSpriteGfx(u8 bank, bool8 loadMonSprite)
+{
+ u8 identity;
+ s32 i;
+ u32 var;
+ const void *substitutePal;
+
+ if (!loadMonSprite)
+ {
+ if (IsContest())
+ identity = 0;
+ else
+ identity = GetBankIdentity(bank);
+
+ if (IsContest())
+ LZDecompressVram(gSubstituteDollTilemap, gMonSpritesGfxPtr->sprites[identity]);
+ else if (GetBankSide(bank) != SIDE_PLAYER)
+ LZDecompressVram(gSubstituteDollGfx, gMonSpritesGfxPtr->sprites[identity]);
+ else
+ LZDecompressVram(gSubstituteDollTilemap, gMonSpritesGfxPtr->sprites[identity]);
+
+ i = 1;
+ var = bank * 16;
+ substitutePal = gSubstituteDollPal;
+ for (; i < 4; i++)
+ {
+ register void *dmaSrc asm("r0") = gMonSpritesGfxPtr->sprites[identity];
+ void *dmaDst = (i * 0x800) + dmaSrc;
+ u32 dmaSize = 0x800;
+ DmaCopy32(3, dmaSrc, dmaDst, dmaSize);
+ i++;i--;
+ }
+
+ LoadCompressedPalette(substitutePal, 0x100 + var, 32);
+ }
+ else
+ {
+ if (!IsContest())
+ {
+ if (GetBankSide(bank) != SIDE_PLAYER)
+ BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlePartyID[bank]], bank);
+ else
+ BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlePartyID[bank]], bank);
+ }
+ }
+}
+
+void LoadBattleMonGfxAndAnimate(u8 bank, bool8 loadMonSprite, u8 spriteId)
+{
+ BattleLoadSubstituteOrMonSpriteGfx(bank, loadMonSprite);
+ StartSpriteAnim(&gSprites[spriteId], gBattleMonForms[bank]);
+
+ if (!loadMonSprite)
+ gSprites[spriteId].pos1.y = GetSubstituteSpriteDefault_Y(bank);
+ else
+ gSprites[spriteId].pos1.y = GetBankSpriteDefault_Y(bank);
+}
+
+void TrySetBehindSubstituteSpriteBit(u8 bank, u16 move)
+{
+ if (move == MOVE_SUBSTITUTE)
+ gBattleSpritesDataPtr->bankData[bank].behindSubstitute = 1;
+}
+
+void ClearBehindSubstituteBit(u8 bank)
+{
+ gBattleSpritesDataPtr->bankData[bank].behindSubstitute = 0;
+}
+
+void HandleLowHpMusicChange(struct Pokemon *mon, u8 bank)
+{
+ u16 hp = GetMonData(mon, MON_DATA_HP);
+ u16 maxHP = GetMonData(mon, MON_DATA_MAX_HP);
+
+ if (GetHPBarLevel(hp, maxHP) == HP_BAR_RED)
+ {
+ if (!gBattleSpritesDataPtr->bankData[bank].lowHpSong)
+ {
+ if (!gBattleSpritesDataPtr->bankData[bank ^ BIT_MON].lowHpSong)
+ PlaySE(SE_HINSI);
+ gBattleSpritesDataPtr->bankData[bank].lowHpSong = 1;
+ }
+ }
+ else
+ {
+ gBattleSpritesDataPtr->bankData[bank].lowHpSong = 0;
+ if (!IsDoubleBattle())
+ {
+ m4aSongNumStop(SE_HINSI);
+ return;
+ }
+ if (IsDoubleBattle() && !gBattleSpritesDataPtr->bankData[bank ^ BIT_MON].lowHpSong)
+ {
+ m4aSongNumStop(SE_HINSI);
+ return;
+ }
+ }
+}
+
+void BattleStopLowHpSound(void)
+{
+ u8 playerBank = GetBankByIdentity(IDENTITY_PLAYER_MON1);
+
+ gBattleSpritesDataPtr->bankData[playerBank].lowHpSong = 0;
+ if (IsDoubleBattle())
+ gBattleSpritesDataPtr->bankData[playerBank ^ BIT_MON].lowHpSong = 0;
+
+ m4aSongNumStop(SE_HINSI);
+}
+
+u8 GetMonHPBarLevel(struct Pokemon *mon)
+{
+ u16 hp = GetMonData(mon, MON_DATA_HP);
+ u16 maxHP = GetMonData(mon, MON_DATA_MAX_HP);
+
+ return GetHPBarLevel(hp, maxHP);
+}
+
+void sub_805EAE8(void)
+{
+ if (gMain.inBattle)
+ {
+ u8 playerBank1 = GetBankByIdentity(IDENTITY_PLAYER_MON1);
+ u8 playerBank2 = GetBankByIdentity(IDENTITY_PLAYER_MON2);
+ u8 bank1PartyId = pokemon_order_func(gBattlePartyID[playerBank1]);
+ u8 bank2PartyId = pokemon_order_func(gBattlePartyID[playerBank2]);
+
+ if (GetMonData(&gPlayerParty[bank1PartyId], MON_DATA_HP) != 0)
+ HandleLowHpMusicChange(&gPlayerParty[bank1PartyId], playerBank1);
+ if (IsDoubleBattle() && GetMonData(&gPlayerParty[bank2PartyId], MON_DATA_HP) != 0)
+ HandleLowHpMusicChange(&gPlayerParty[bank2PartyId], playerBank2);
+ }
+}
+
+void sub_805EB9C(u8 affineMode)
+{
+ s32 i;
+
+ for (i = 0; i < gNoOfAllBanks; i++)
+ {
+ if (IsBankSpritePresent(i))
+ {
+ gSprites[gBankSpriteIds[i]].oam.affineMode = affineMode;
+ if (affineMode == 0)
+ {
+ gBattleSpritesDataPtr->healthBoxesData[i].field_6 = gSprites[gBankSpriteIds[i]].oam.matrixNum;
+ gSprites[gBankSpriteIds[i]].oam.matrixNum = 0;
+ }
+ else
+ {
+ gSprites[gBankSpriteIds[i]].oam.matrixNum = gBattleSpritesDataPtr->healthBoxesData[i].field_6;
+ }
+ }
+ }
+}
+
+#define tBank data0
+
+void LoadAndCreateEnemyShadowSprites(void)
+{
+ u8 bank;
+
+ LoadCompressedObjectPic(&gSpriteSheet_EnemyShadow);
+
+ bank = GetBankByIdentity(IDENTITY_OPPONENT_MON1);
+ gBattleSpritesDataPtr->healthBoxesData[bank].shadowSpriteId = CreateSprite(&gSpriteTemplate_EnemyShadow, sub_80A5C6C(bank, 0), sub_80A5C6C(bank, 1) + 29, 0xC8);
+ gSprites[gBattleSpritesDataPtr->healthBoxesData[bank].shadowSpriteId].data0 = bank;
+
+ if (IsDoubleBattle())
+ {
+ bank = GetBankByIdentity(IDENTITY_OPPONENT_MON2);
+ gBattleSpritesDataPtr->healthBoxesData[bank].shadowSpriteId = CreateSprite(&gSpriteTemplate_EnemyShadow, sub_80A5C6C(bank, 0), sub_80A5C6C(bank, 1) + 29, 0xC8);
+ gSprites[gBattleSpritesDataPtr->healthBoxesData[bank].shadowSpriteId].data0 = bank;
+ }
+}
+
+void SpriteCB_EnemyShadow(struct Sprite *shadowSprite)
+{
+ bool8 invisible = FALSE;
+ u8 bank = shadowSprite->tBank;
+ struct Sprite *bankSprite = &gSprites[gBankSpriteIds[bank]];
+
+ if (!bankSprite->inUse || !IsBankSpritePresent(bank))
+ {
+ shadowSprite->callback = SpriteCB_SetInvisible;
+ return;
+ }
+ if (gAnimScriptActive || bankSprite->invisible)
+ invisible = TRUE;
+ else if (gBattleSpritesDataPtr->bankData[bank].transformSpecies != SPECIES_NONE
+ && gEnemyMonElevation[gBattleSpritesDataPtr->bankData[bank].transformSpecies] == 0)
+ invisible = TRUE;
+
+ if (gBattleSpritesDataPtr->bankData[bank].behindSubstitute)
+ invisible = TRUE;
+
+ shadowSprite->pos1.x = bankSprite->pos1.x;
+ shadowSprite->pos2.x = bankSprite->pos2.x;
+ shadowSprite->invisible = invisible;
+}
+
+#undef tBank
+
+void SpriteCB_SetInvisible(struct Sprite *sprite)
+{
+ sprite->invisible = 1;
+}
+
+void SetBankEnemyShadowSpriteCallback(u8 bank, u16 species)
+{
+ if (GetBankSide(bank) == SIDE_PLAYER)
+ return;
+
+ if (gBattleSpritesDataPtr->bankData[bank].transformSpecies != SPECIES_NONE)
+ species = gBattleSpritesDataPtr->bankData[bank].transformSpecies;
+
+ if (gEnemyMonElevation[species] != 0)
+ gSprites[gBattleSpritesDataPtr->healthBoxesData[bank].shadowSpriteId].callback = SpriteCB_EnemyShadow;
+ else
+ gSprites[gBattleSpritesDataPtr->healthBoxesData[bank].shadowSpriteId].callback = SpriteCB_SetInvisible;
+}
+
+void EnemyShadowCallbackToSetInvisible(u8 bank)
+{
+ gSprites[gBattleSpritesDataPtr->healthBoxesData[bank].shadowSpriteId].callback = SpriteCB_SetInvisible;
+}
+
+void sub_805EF14(void)
+{
+ u16 *vramPtr = (u16*)(VRAM + 0x240);
+ s32 i;
+ s32 j;
+
+ for (i = 0; i < 9; i++)
+ {
+ for (j = 0; j < 16; j++)
+ {
+ if (!(*vramPtr & 0xF000))
+ *vramPtr |= 0xF000;
+ if (!(*vramPtr & 0x0F00))
+ *vramPtr |= 0x0F00;
+ if (!(*vramPtr & 0x00F0))
+ *vramPtr |= 0x00F0;
+ if (!(*vramPtr & 0x000F))
+ *vramPtr |= 0x000F;
+ vramPtr++;
+ }
+ }
+}
+
+void ClearTemporarySpeciesSpriteData(u8 bank, bool8 dontClearSubstitute)
+{
+ gBattleSpritesDataPtr->bankData[bank].transformSpecies = SPECIES_NONE;
+ gBattleMonForms[bank] = 0;
+ if (!dontClearSubstitute)
+ ClearBehindSubstituteBit(bank);
+}
+
+void AllocateMonSpritesGfx(void)
+{
+ u8 i = 0, j;
+
+ gMonSpritesGfxPtr = NULL;
+ gMonSpritesGfxPtr = AllocZeroed(sizeof(*gMonSpritesGfxPtr));
+ gMonSpritesGfxPtr->firstDecompressed = AllocZeroed(0x8000);
+
+ for (i = 0; i < BATTLE_BANKS_COUNT; i++)
+ {
+ gMonSpritesGfxPtr->sprites[i] = gMonSpritesGfxPtr->firstDecompressed + (i * 0x2000);
+ *(gMonSpritesGfxPtr->templates + i) = gUnknown_08329D98[i];
+
+ for (j = 0; j < 4; j++)
+ {
+ gMonSpritesGfxPtr->field_74[i][j].data = gMonSpritesGfxPtr->sprites[i] + (j * 0x800);
+ gMonSpritesGfxPtr->field_74[i][j].size = 0x800;
+ }
+
+ gMonSpritesGfxPtr->templates[i].images = gMonSpritesGfxPtr->field_74[i];
+ }
+
+ gMonSpritesGfxPtr->barFontGfx = AllocZeroed(0x1000);
+}
+
+void FreeMonSpritesGfx(void)
+{
+ if (gMonSpritesGfxPtr == NULL)
+ return;
+
+ if (gMonSpritesGfxPtr->field_17C != NULL)
+ FREE_AND_SET_NULL(gMonSpritesGfxPtr->field_17C);
+ if (gMonSpritesGfxPtr->field_178 != NULL)
+ FREE_AND_SET_NULL(gMonSpritesGfxPtr->field_178);
+
+ FREE_AND_SET_NULL(gMonSpritesGfxPtr->barFontGfx);
+ FREE_AND_SET_NULL(gMonSpritesGfxPtr->firstDecompressed);
+ gMonSpritesGfxPtr->sprites[0] = NULL;
+ gMonSpritesGfxPtr->sprites[1] = NULL;
+ gMonSpritesGfxPtr->sprites[2] = NULL;
+ gMonSpritesGfxPtr->sprites[3] = NULL;
+ FREE_AND_SET_NULL(gMonSpritesGfxPtr);
+}
+
+bool32 ShouldPlayNormalPokeCry(struct Pokemon *mon)
+{
+ s16 hp, maxHP;
+ s32 barLevel;
+
+ if (GetMonData(mon, MON_DATA_STATUS) & (STATUS_ANY | STATUS_TOXIC_COUNTER))
+ return FALSE;
+
+ hp = GetMonData(mon, MON_DATA_HP);
+ maxHP = GetMonData(mon, MON_DATA_MAX_HP);
+
+ barLevel = GetHPBarLevel(hp, maxHP);
+ if (barLevel <= HP_BAR_YELLOW)
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/src/battle_interface.c b/src/battle_interface.c
index 5f582a366..240c64862 100644
--- a/src/battle_interface.c
+++ b/src/battle_interface.c
@@ -1239,11 +1239,11 @@ void UpdateHpTextInHealthbox(u8 healthboxSpriteId, s16 value, u8 maxOrCurrent)
}
ConvertIntToDecimalStringN(text + 6, value, STR_CONV_MODE_RIGHT_ALIGN, 3);
- RenderTextFont9(gMonSpritesGfxPtr->fontPixels, 9, text);
+ RenderTextFont9(gMonSpritesGfxPtr->barFontGfx, 9, text);
for (i = 0; i < 3; i++)
{
- CpuCopy32(&gMonSpritesGfxPtr->fontPixels[i * 64 + 32],
+ CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[i * 64 + 32],
(void*)((OBJ_VRAM0) + 32 * (gSprites[healthboxSpriteId].oam.tileNum + var + i)),
0x20);
}
@@ -1308,19 +1308,19 @@ static void UpdateHpTextInHealthboxInDoubles(u8 healthboxSpriteId, s16 value, u8
txtPtr = ConvertIntToDecimalStringN(text + 6, value, STR_CONV_MODE_RIGHT_ALIGN, 3);
if (!maxOrCurrent)
StringCopy(txtPtr, gText_Slash);
- RenderTextFont9(gMonSpritesGfxPtr->fontPixels, 9, text);
+ RenderTextFont9(gMonSpritesGfxPtr->barFontGfx, 9, text);
for (i = var; i < var + 3; i++)
{
if (i < 3)
{
- CpuCopy32(&gMonSpritesGfxPtr->fontPixels[((i - var) * 64) + 32],
+ CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[((i - var) * 64) + 32],
(void*)((OBJ_VRAM0) + 32 * (1 + gSprites[r7].oam.tileNum + i)),
0x20);
}
else
{
- CpuCopy32(&gMonSpritesGfxPtr->fontPixels[((i - var) * 64) + 32],
+ CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[((i - var) * 64) + 32],
(void*)((OBJ_VRAM0 + 0x20) + 32 * (i + gSprites[r7].oam.tileNum)),
0x20);
}
@@ -1328,7 +1328,7 @@ static void UpdateHpTextInHealthboxInDoubles(u8 healthboxSpriteId, s16 value, u8
if (maxOrCurrent == HP_CURRENT)
{
- CpuCopy32(&gMonSpritesGfxPtr->fontPixels[224],
+ CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[224],
(void*)((OBJ_VRAM0) + ((gSprites[r7].oam.tileNum + 4) * 32)),
0x20);
CpuFill32(0, (void*)((OBJ_VRAM0) + (gSprites[r7].oam.tileNum * 32)), 0x20);
@@ -1350,15 +1350,15 @@ static void sub_80730D4(u8 healthboxSpriteId, struct Pokemon *mon)
{
u8 text[20];
s32 j, var2;
- u8 *fontPixels;
+ u8 *barFontGfx;
u8 i, var, nature, healthboxSpriteId_2;
memcpy(text, sUnknown_0832C3C4, sizeof(sUnknown_0832C3C4));
- fontPixels = &gMonSpritesGfxPtr->fontPixels[0x520 + (GetBankIdentity(gSprites[healthboxSpriteId].data6) * 384)];
+ barFontGfx = &gMonSpritesGfxPtr->barFontGfx[0x520 + (GetBankIdentity(gSprites[healthboxSpriteId].data6) * 384)];
var = 5;
nature = GetNature(mon);
StringCopy(text + 6, gNatureNamePointers[nature]);
- RenderTextFont9(fontPixels, 9, text);
+ RenderTextFont9(barFontGfx, 9, text);
for (j = 6, i = 0; i < var; i++, j++)
{
@@ -1371,18 +1371,18 @@ static void sub_80730D4(u8 healthboxSpriteId, struct Pokemon *mon)
else
elementId = 43;
- CpuCopy32(GetHealthboxElementGfxPtr(elementId), fontPixels + (i * 64), 0x20);
+ CpuCopy32(GetHealthboxElementGfxPtr(elementId), barFontGfx + (i * 64), 0x20);
}
for (j = 1; j < var + 1; j++)
{
var2 = (gSprites[healthboxSpriteId].oam.tileNum + (j - (j / 8 * 8)) + (j / 8 * 64)) * 32;
- CpuCopy32(fontPixels, (void*)(OBJ_VRAM0) + (var2), 0x20);
- fontPixels += 0x20;
+ CpuCopy32(barFontGfx, (void*)(OBJ_VRAM0) + (var2), 0x20);
+ barFontGfx += 0x20;
var2 = (8 + gSprites[healthboxSpriteId].oam.tileNum + (j - (j / 8 * 8)) + (j / 8 * 64)) * 32;
- CpuCopy32(fontPixels, (void*)(OBJ_VRAM0) + (var2), 0x20);
- fontPixels += 0x20;
+ CpuCopy32(barFontGfx, (void*)(OBJ_VRAM0) + (var2), 0x20);
+ barFontGfx += 0x20;
}
healthboxSpriteId_2 = gSprites[healthboxSpriteId].data5;
@@ -1390,20 +1390,20 @@ static void sub_80730D4(u8 healthboxSpriteId, struct Pokemon *mon)
ConvertIntToDecimalStringN(text + 9, gBattleStruct->field_7B, STR_CONV_MODE_RIGHT_ALIGN, 2);
text[5] = CHAR_SPACE;
text[8] = CHAR_SLASH;
- RenderTextFont9(gMonSpritesGfxPtr->fontPixels, 9, text);
+ RenderTextFont9(gMonSpritesGfxPtr->barFontGfx, 9, text);
j = healthboxSpriteId_2; // needed to match for some reason
for (j = 0; j < 5; j++)
{
if (j <= 1)
{
- CpuCopy32(&gMonSpritesGfxPtr->fontPixels[0x40 * j + 0x20],
+ CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[0x40 * j + 0x20],
(void*)(OBJ_VRAM0) + (gSprites[healthboxSpriteId_2].oam.tileNum + 2 + j) * 32,
32);
}
else
{
- CpuCopy32(&gMonSpritesGfxPtr->fontPixels[0x40 * j + 0x20],
+ CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[0x40 * j + 0x20],
(void*)(OBJ_VRAM0 + 0xC0) + (j + gSprites[healthboxSpriteId_2].oam.tileNum) * 32,
32);
}
@@ -2545,19 +2545,19 @@ u8 GetHPBarLevel(s16 hp, s16 maxhp)
if (hp == maxhp)
{
- result = 4;
+ result = HP_BAR_FULL;
}
else
{
u8 fraction = GetScaledHPFraction(hp, maxhp, 48);
if (fraction > 24)
- result = 3;
+ result = HP_BAR_GREEN;
else if (fraction > 9)
- result = 2;
+ result = HP_BAR_YELLOW;
else if (fraction > 0)
- result = 1;
+ result = HP_BAR_RED;
else
- result = 0;
+ result = HP_BAR_EMPTY;
}
return result;
diff --git a/src/battle_message.c b/src/battle_message.c
index 52c0c7af5..9c37cf646 100644
--- a/src/battle_message.c
+++ b/src/battle_message.c
@@ -58,7 +58,7 @@ extern const u8* GetTrainer1LoseText(void); // battle_setup
extern const u8* GetTrainer2LoseText(void); // battle_setup
extern void GetFrontierTrainerName(u8 *dst, u16 trainerId);
extern s32 GetStringCenterAlignXOffsetWithLetterSpacing(u8 fontId, const u8 *str, s32 totalWidth, s16 letterSpacing);
-extern u8 sub_8185FC4(void);
+extern u8 GetTextSpeedInRecordedBattle(void);
extern u8 sav2_get_text_speed(void);
// this file's functions
@@ -1907,7 +1907,7 @@ u32 BattleStringExpandPlaceholders(const u8* src, u8* dst)
HANDLE_NICKNAME_STRING_CASE(gBattleScripting.bank, *(&gBattleStruct->field_52))
break;
case B_TXT_PC_CREATOR_NAME: // lanette pc
- if (FlagGet(SYS_PC_LANETTE))
+ if (FlagGet(FLAG_SYS_PC_LANETTE))
toCpy = gText_Lanettes;
else
toCpy = gText_Someones;
@@ -2264,7 +2264,7 @@ void BattleHandleAddTextPrinter(const u8 *text, u8 arg1)
if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000))
speed = 1;
else if (gBattleTypeFlags & BATTLE_TYPE_RECORDED)
- speed = sRecordedBattleTextSpeeds[sub_8185FC4()];
+ speed = sRecordedBattleTextSpeeds[GetTextSpeedInRecordedBattle()];
else
speed = sav2_get_text_speed();
diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c
index c6cec7f0d..6409ff56e 100644
--- a/src/battle_script_commands.c
+++ b/src/battle_script_commands.c
@@ -13,6 +13,7 @@
#include "calculate_base_damage.h"
#include "rng.h"
#include "battle_controllers.h"
+#include "battle_interface.h"
#include "species.h"
#include "songs.h"
#include "text.h"
@@ -118,9 +119,7 @@ struct TrainerMoney
extern const struct BattleMove gBattleMoves[];
extern const struct BaseStats gBaseStats[];
-extern const u8 gTypeEffectiveness[];
-extern const u16 gMissStringIds[];
-extern const u16 gTrappingMoves[];
+extern const u8 gTypeEffectiveness[336];
extern const struct TrainerMoney gTrainerMoneyTable[];
extern const u8* const gBattleScriptsForMoveEffects[];
@@ -139,7 +138,6 @@ 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 bool8 sub_81B1250(void); // ?
-extern u8 GetScaledHPFraction(s16 hp, s16 maxhp, u8 scale); // battle interface
extern bool8 InBattlePike(void);
extern bool8 InBattlePyramid(void);
extern u16 GetBattlePyramidPickupItemId(void);
@@ -340,7 +338,7 @@ static void atk48_playstatchangeanimation(void);
static void atk49_moveend(void);
static void atk4A_typecalc2(void);
static void atk4B_return_atk_to_ball(void);
-static void atk4C_copy_poke_data(void);
+static void atk4C_get_switched_mon_data(void);
static void atk4D_switch_data_update(void);
static void atk4E_switchin_anim(void);
static void atk4F_jump_if_cannot_switch(void);
@@ -368,7 +366,7 @@ static void atk64_statusanimation(void);
static void atk65_status2animation(void);
static void atk66_chosenstatusanimation(void);
static void atk67_yesnobox(void);
-static void atk68_80246A0(void);
+static void atk68_cancel_everyones_actions(void);
static void atk69_dmg_adjustment3(void);
static void atk6A_removeitem(void);
static void atk6B_atknameinbuff1(void);
@@ -457,7 +455,7 @@ static void atkBD_copyfoestats(void);
static void atkBE_rapidspinfree(void);
static void atkBF_set_defense_curl(void);
static void atkC0_recoverbasedonsunlight(void);
-static void atkC1_hidden_power(void);
+static void atkC1_hidden_power_calc(void);
static void atkC2_selectnexttarget(void);
static void atkC3_setfutureattack(void);
static void atkC4_beat_up(void);
@@ -592,7 +590,7 @@ void (* const gBattleScriptingCommandsTable[])(void) =
atk49_moveend,
atk4A_typecalc2,
atk4B_return_atk_to_ball,
- atk4C_copy_poke_data,
+ atk4C_get_switched_mon_data,
atk4D_switch_data_update,
atk4E_switchin_anim,
atk4F_jump_if_cannot_switch,
@@ -620,7 +618,7 @@ void (* const gBattleScriptingCommandsTable[])(void) =
atk65_status2animation,
atk66_chosenstatusanimation,
atk67_yesnobox,
- atk68_80246A0,
+ atk68_cancel_everyones_actions,
atk69_dmg_adjustment3,
atk6A_removeitem,
atk6B_atknameinbuff1,
@@ -709,7 +707,7 @@ void (* const gBattleScriptingCommandsTable[])(void) =
atkBE_rapidspinfree,
atkBF_set_defense_curl,
atkC0_recoverbasedonsunlight,
- atkC1_hidden_power,
+ atkC1_hidden_power_calc,
atkC2_selectnexttarget,
atkC3_setfutureattack,
atkC4_beat_up,
@@ -828,7 +826,7 @@ static const u32 sStatusFlagsForMoveEffects[] =
0x00000000,
0x00000000,
STATUS2_ESCAPE_PREVENTION,
- 0x08000000,
+ STATUS2_NIGHTMARE,
0x00000000,
0x00000000,
0x00000000,
@@ -1068,22 +1066,33 @@ static const u8 sBallCatchBonuses[] =
20, 15, 10, 15 // Ultra, Great, Poke, Safari
};
-// could be a 2d array or a struct
-const ALIGNED(4) u8 gUnknown_0831C494[] =
-{
- 0x3d, 0x44, 0x3d, 0x44, 0x14, 0x2d, 0x54, 0x5c,
- 0x46, 0x55, 0x20, 0x5c, 0x26, 0x45, 0x46, 0x55,
- 0x14, 0x5a, 0x46, 0x5c, 0x1e, 0x32, 0x20, 0x5a,
- 0x38, 0x4e, 0x38, 0x4e, 0x19, 0x28, 0x4b, 0x5a,
- 0x45, 0x4b, 0x1c, 0x53, 0x23, 0x2d, 0x1d, 0x23,
- 0x3e, 0x48, 0x1e, 0x32, 0x3a, 0x5f, 0x58, 0x5e,
- 0x22, 0x2d, 0x1d, 0x28, 0x23, 0x28, 0x23, 0x5f,
- 0x38, 0x4e, 0x38, 0x4e, 0x23, 0x50, 0x22, 0x5e,
- 0x2c, 0x5e, 0x22, 0x28, 0x38, 0x4e, 0x38, 0x4e,
- 0x1e, 0x58, 0x1e, 0x58, 0x1e, 0x2b, 0x1b, 0x21,
- 0x28, 0x5a, 0x19, 0x57, 0x12, 0x58, 0x5a, 0x5f,
- 0x58, 0x5e, 0x16, 0x2a, 0x2a, 0x5c, 0x2a, 0x2f,
- 0x38, 0x4e, 0x38, 0x4e
+const ALIGNED(4) u8 gUnknown_0831C494[][4] =
+{
+ {0x3d, 0x44, 0x3d, 0x44},
+ {0x14, 0x2d, 0x54, 0x5c},
+ {0x46, 0x55, 0x20, 0x5c},
+ {0x26, 0x45, 0x46, 0x55},
+ {0x14, 0x5a, 0x46, 0x5c},
+ {0x1e, 0x32, 0x20, 0x5a},
+ {0x38, 0x4e, 0x38, 0x4e},
+ {0x19, 0x28, 0x4b, 0x5a},
+ {0x45, 0x4b, 0x1c, 0x53},
+ {0x23, 0x2d, 0x1d, 0x23},
+ {0x3e, 0x48, 0x1e, 0x32},
+ {0x3a, 0x5f, 0x58, 0x5e},
+ {0x22, 0x2d, 0x1d, 0x28},
+ {0x23, 0x28, 0x23, 0x5f},
+ {0x38, 0x4e, 0x38, 0x4e},
+ {0x23, 0x50, 0x22, 0x5e},
+ {0x2c, 0x5e, 0x22, 0x28},
+ {0x38, 0x4e, 0x38, 0x4e},
+ {0x1e, 0x58, 0x1e, 0x58},
+ {0x1e, 0x2b, 0x1b, 0x21},
+ {0x28, 0x5a, 0x19, 0x57},
+ {0x12, 0x58, 0x5a, 0x5f},
+ {0x58, 0x5e, 0x16, 0x2a},
+ {0x2a, 0x5c, 0x2a, 0x2f},
+ {0x38, 0x4e, 0x38, 0x4e}
};
static const u8 sUnknown_0831C4F8[] =
@@ -1233,7 +1242,7 @@ bool8 JumpIfMoveAffectedByProtect(u16 move)
return affected;
}
-bool8 AccuracyCalcHelper(u16 move)
+static bool8 AccuracyCalcHelper(u16 move)
{
if (gStatuses3[gBankTarget] & STATUS3_ALWAYS_HITS && gDisableStructs[gBankTarget].bankWithSureHit == gBankAttacker)
{
@@ -1532,9 +1541,6 @@ static void ModulateDmgByType(u8 multiplier)
}
}
-#define TYPE_FORESIGHT 0xFE
-#define TYPE_ENDTABLE 0xFF
-
static void atk06_typecalc(void)
{
s32 i = 0;
@@ -1566,24 +1572,24 @@ static void atk06_typecalc(void)
}
else
{
- while (gTypeEffectiveness[i] != TYPE_ENDTABLE)
+ while (TYPE_EFFECT_ATK_TYPE(i) != TYPE_ENDTABLE)
{
- if (gTypeEffectiveness[i] == TYPE_FORESIGHT)
+ if (TYPE_EFFECT_ATK_TYPE(i) == TYPE_FORESIGHT)
{
if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT)
break;
i += 3;
continue;
}
- else if (gTypeEffectiveness[i] == moveType)
+ else if (TYPE_EFFECT_ATK_TYPE(i) == moveType)
{
// check type1
- if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1)
- ModulateDmgByType(gTypeEffectiveness[i + 2]);
+ if (TYPE_EFFECT_DEF_TYPE(i) == gBattleMons[gBankTarget].type1)
+ ModulateDmgByType(TYPE_EFFECT_MULTIPLIER(i));
// check type2
- if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 &&
+ if (TYPE_EFFECT_DEF_TYPE(i) == gBattleMons[gBankTarget].type2 &&
gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2)
- ModulateDmgByType(gTypeEffectiveness[i + 2]);
+ ModulateDmgByType(TYPE_EFFECT_MULTIPLIER(i));
}
i += 3;
}
@@ -1625,45 +1631,46 @@ static void CheckWonderGuardAndLevitate(void)
return;
}
- while (gTypeEffectiveness[i] != TYPE_ENDTABLE)
+ while (TYPE_EFFECT_ATK_TYPE(i) != TYPE_ENDTABLE)
{
- if (gTypeEffectiveness[i] == TYPE_FORESIGHT)
+ if (TYPE_EFFECT_ATK_TYPE(i) == TYPE_FORESIGHT)
{
if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT)
break;
i += 3;
continue;
}
- if (gTypeEffectiveness[i] == moveType)
+ if (TYPE_EFFECT_ATK_TYPE(i) == moveType)
{
// check no effect
- if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1 && gTypeEffectiveness[i + 2] == 0)
+ if (TYPE_EFFECT_DEF_TYPE(i) == gBattleMons[gBankTarget].type1
+ && TYPE_EFFECT_MULTIPLIER(i) == TYPE_MUL_NO_EFFECT)
{
gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED;
gProtectStructs[gBankAttacker].targetNotAffected = 1;
}
- if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 &&
+ if (TYPE_EFFECT_DEF_TYPE(i) == gBattleMons[gBankTarget].type2 &&
gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 &&
- gTypeEffectiveness[i + 2] == TYPE_MUL_NO_EFFECT)
+ TYPE_EFFECT_MULTIPLIER(i) == TYPE_MUL_NO_EFFECT)
{
gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED;
gProtectStructs[gBankAttacker].targetNotAffected = 1;
}
// check super effective
- if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1 && gTypeEffectiveness[i + 2] == 20)
+ if (TYPE_EFFECT_DEF_TYPE(i) == gBattleMons[gBankTarget].type1 && TYPE_EFFECT_MULTIPLIER(i) == 20)
flags |= 1;
- if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2
+ if (TYPE_EFFECT_DEF_TYPE(i) == gBattleMons[gBankTarget].type2
&& gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2
- && gTypeEffectiveness[i + 2] == TYPE_MUL_SUPER_EFFECTIVE)
+ && TYPE_EFFECT_MULTIPLIER(i) == TYPE_MUL_SUPER_EFFECTIVE)
flags |= 1;
// check not very effective
- if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1 && gTypeEffectiveness[i + 2] == 5)
+ if (TYPE_EFFECT_DEF_TYPE(i) == gBattleMons[gBankTarget].type1 && TYPE_EFFECT_MULTIPLIER(i) == 5)
flags |= 2;
- if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2
+ if (TYPE_EFFECT_DEF_TYPE(i) == gBattleMons[gBankTarget].type2
&& gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2
- && gTypeEffectiveness[i + 2] == TYPE_MUL_NOT_EFFECTIVE)
+ && TYPE_EFFECT_MULTIPLIER(i) == TYPE_MUL_NOT_EFFECTIVE)
flags |= 2;
}
i += 3;
@@ -1738,9 +1745,9 @@ u8 TypeCalc(u16 move, u8 bankAtk, u8 bankDef)
}
else
{
- while (gTypeEffectiveness[i]!= TYPE_ENDTABLE)
+ while (TYPE_EFFECT_ATK_TYPE(i) != TYPE_ENDTABLE)
{
- if (gTypeEffectiveness[i] == TYPE_FORESIGHT)
+ if (TYPE_EFFECT_ATK_TYPE(i) == TYPE_FORESIGHT)
{
if (gBattleMons[bankDef].status2 & STATUS2_FORESIGHT)
break;
@@ -1748,15 +1755,15 @@ u8 TypeCalc(u16 move, u8 bankAtk, u8 bankDef)
continue;
}
- else if (gTypeEffectiveness[i] == moveType)
+ else if (TYPE_EFFECT_ATK_TYPE(i) == moveType)
{
// check type1
- if (gTypeEffectiveness[i + 1] == gBattleMons[bankDef].type1)
- ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags);
+ if (TYPE_EFFECT_DEF_TYPE(i) == gBattleMons[bankDef].type1)
+ ModulateDmgByType2(TYPE_EFFECT_MULTIPLIER(i), move, &flags);
// check type2
- if (gTypeEffectiveness[i + 1] == gBattleMons[bankDef].type2 &&
+ if (TYPE_EFFECT_DEF_TYPE(i) == gBattleMons[bankDef].type2 &&
gBattleMons[bankDef].type1 != gBattleMons[bankDef].type2)
- ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags);
+ ModulateDmgByType2(TYPE_EFFECT_MULTIPLIER(i), move, &flags);
}
i += 3;
}
@@ -1790,21 +1797,21 @@ u8 AI_TypeCalc(u16 move, u16 targetSpecies, u8 targetAbility)
}
else
{
- while (gTypeEffectiveness[i] != TYPE_ENDTABLE)
+ while (TYPE_EFFECT_ATK_TYPE(i) != TYPE_ENDTABLE)
{
- if (gTypeEffectiveness[i] == TYPE_FORESIGHT)
+ if (TYPE_EFFECT_ATK_TYPE(i) == TYPE_FORESIGHT)
{
i += 3;
continue;
}
- if (gTypeEffectiveness[i] == moveType)
+ if (TYPE_EFFECT_ATK_TYPE(i) == moveType)
{
// check type1
- if (gTypeEffectiveness[i + 1] == type1)
- ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags);
+ if (TYPE_EFFECT_DEF_TYPE(i) == type1)
+ ModulateDmgByType2(TYPE_EFFECT_MULTIPLIER(i), move, &flags);
// check type2
- if (gTypeEffectiveness[i + 1] == type2 && type1 != type2)
- ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags);
+ if (TYPE_EFFECT_DEF_TYPE(i) == type2 && type1 != type2)
+ ModulateDmgByType2(TYPE_EFFECT_MULTIPLIER(i), move, &flags);
}
i += 3;
}
@@ -3533,7 +3540,7 @@ static void atk23_getexp(void)
// music change in wild battle after fainting a poke
if (!(gBattleTypeFlags & BATTLE_TYPE_TRAINER) && gBattleMons[0].hp && !gBattleStruct->wildVictorySong)
{
- BattleMusicStop();
+ BattleStopLowHpSound();
PlayBGM(0x161);
gBattleStruct->wildVictorySong++;
}
@@ -3628,7 +3635,7 @@ static void atk23_getexp(void)
if (gBattleBufferB[gActiveBank][0] == CONTROLLER_TWORETURNVALUES && gBattleBufferB[gActiveBank][1] == RET_VALUE_LEVELLED_UP)
{
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && gBattlePartyID[gActiveBank] == gBattleStruct->expGetterId)
- sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gActiveBank, gBattleStruct->expGetterId)
@@ -5224,9 +5231,9 @@ static void atk4A_typecalc2(void)
}
else
{
- while (gTypeEffectiveness[i]!= TYPE_ENDTABLE)
+ while (TYPE_EFFECT_ATK_TYPE(i) != TYPE_ENDTABLE)
{
- if (gTypeEffectiveness[i] == TYPE_FORESIGHT)
+ if (TYPE_EFFECT_ATK_TYPE(i) == TYPE_FORESIGHT)
{
if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT)
{
@@ -5239,43 +5246,43 @@ static void atk4A_typecalc2(void)
}
}
- if (gTypeEffectiveness[i] == moveType)
+ if (TYPE_EFFECT_ATK_TYPE(i) == moveType)
{
// check type1
- if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1)
+ if (TYPE_EFFECT_DEF_TYPE(i) == gBattleMons[gBankTarget].type1)
{
- if (gTypeEffectiveness[i + 2] == 0)
+ if (TYPE_EFFECT_MULTIPLIER(i) == TYPE_MUL_NO_EFFECT)
{
gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED;
break;
}
- if (gTypeEffectiveness[i + 2] == 5)
+ if (TYPE_EFFECT_MULTIPLIER(i) == TYPE_MUL_NOT_EFFECTIVE)
{
flags |= MOVESTATUS_NOTVERYEFFECTIVE;
}
- if (gTypeEffectiveness[i + 2] == 20)
+ if (TYPE_EFFECT_MULTIPLIER(i) == TYPE_MUL_SUPER_EFFECTIVE)
{
flags |= MOVESTATUS_SUPEREFFECTIVE;
}
}
// check type2
- if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2)
+ if (TYPE_EFFECT_DEF_TYPE(i) == gBattleMons[gBankTarget].type2)
{
if (gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2
- && gTypeEffectiveness[i + 2] == 0)
+ && TYPE_EFFECT_MULTIPLIER(i) == TYPE_MUL_NO_EFFECT)
{
gBattleMoveFlags |= MOVESTATUS_NOTAFFECTED;
break;
}
- if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2
+ if (TYPE_EFFECT_DEF_TYPE(i) == gBattleMons[gBankTarget].type2
&& gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2
- && gTypeEffectiveness[i + 2] == 5)
+ && TYPE_EFFECT_MULTIPLIER(i) == TYPE_MUL_NOT_EFFECTIVE)
{
flags |= MOVESTATUS_NOTVERYEFFECTIVE;
}
- if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2
+ if (TYPE_EFFECT_DEF_TYPE(i) == gBattleMons[gBankTarget].type2
&& gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2
- && gTypeEffectiveness[i + 2] == 20)
+ && TYPE_EFFECT_MULTIPLIER(i) == TYPE_MUL_SUPER_EFFECTIVE)
{
flags |= MOVESTATUS_SUPEREFFECTIVE;
}
@@ -5314,16 +5321,16 @@ static void atk4B_return_atk_to_ball(void)
gBattlescriptCurrInstr++;
}
-static void atk4C_copy_poke_data(void)
+static void atk4C_get_switched_mon_data(void)
{
if (gBattleExecBuffer)
return;
gActiveBank = GetBattleBank(gBattlescriptCurrInstr[1]);
- gBattlePartyID[gActiveBank] = *(gBattleStruct->field_5C + gActiveBank);
+ gBattlePartyID[gActiveBank] = *(gBattleStruct->monToSwitchIntoId + gActiveBank);
- EmitGetMonData(0, 0, gBitTable[gBattlePartyID[gActiveBank]]);
+ EmitGetMonData(0, REQUEST_ALL_BATTLE, gBitTable[gBattlePartyID[gActiveBank]]);
MarkBufferBankForExecution(gActiveBank);
gBattlescriptCurrInstr += 2;
@@ -5360,7 +5367,7 @@ static void atk4D_switch_data_update(void)
if (gBattleMoves[gCurrentMove].effect == EFFECT_BATON_PASS)
{
- for (i = 0; i < 8; i++)
+ for (i = 0; i < BATTLE_STATS_NO; i++)
{
gBattleMons[gActiveBank].statStages[i] = oldData.statStages[i];
}
@@ -5376,11 +5383,8 @@ static void atk4D_switch_data_update(void)
}
gBattleScripting.bank = gActiveBank;
- gBattleTextBuff1[0] = PLACEHOLDER_BEGIN;
- gBattleTextBuff1[1] = 7;
- gBattleTextBuff1[2] = gActiveBank;
- gBattleTextBuff1[3] = gBattlePartyID[gActiveBank];
- gBattleTextBuff1[4] = EOS;
+
+ PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gActiveBank, gBattlePartyID[gActiveBank]);
gBattlescriptCurrInstr += 2;
}
@@ -5568,7 +5572,7 @@ static void atk4F_jump_if_cannot_switch(void)
static void sub_804CF10(u8 arg0)
{
*(gBattleStruct->field_58 + gActiveBank) = gBattlePartyID[gActiveBank];
- *(gBattleStruct->field_5C + gActiveBank) = 6;
+ *(gBattleStruct->monToSwitchIntoId + gActiveBank) = 6;
gBattleStruct->field_93 &= ~(gBitTable[gActiveBank]);
EmitChoosePokemon(0, 1, arg0, 0, gBattleStruct->field_60[gActiveBank]);
@@ -5632,7 +5636,7 @@ static void atk50_openpartyscreen(void)
}
else if (!gSpecialStatuses[gActiveBank].flag40)
{
- sub_804CF10(gBattleStruct->field_5C[2]);
+ sub_804CF10(gBattleStruct->monToSwitchIntoId[2]);
gSpecialStatuses[gActiveBank].flag40 = 1;
}
else
@@ -5654,7 +5658,7 @@ static void atk50_openpartyscreen(void)
}
else if (!gSpecialStatuses[gActiveBank].flag40)
{
- sub_804CF10(gBattleStruct->field_5C[0]);
+ sub_804CF10(gBattleStruct->monToSwitchIntoId[0]);
gSpecialStatuses[gActiveBank].flag40 = 1;
}
else if (!(flags & 1))
@@ -5675,7 +5679,7 @@ static void atk50_openpartyscreen(void)
}
else if (!gSpecialStatuses[gActiveBank].flag40)
{
- sub_804CF10(gBattleStruct->field_5C[3]);
+ sub_804CF10(gBattleStruct->monToSwitchIntoId[3]);
gSpecialStatuses[gActiveBank].flag40 = 1;
}
else
@@ -5697,7 +5701,7 @@ static void atk50_openpartyscreen(void)
}
else if (!gSpecialStatuses[gActiveBank].flag40)
{
- sub_804CF10(gBattleStruct->field_5C[1]);
+ sub_804CF10(gBattleStruct->monToSwitchIntoId[1]);
gSpecialStatuses[gActiveBank].flag40 = 1;
}
else if (!(flags & 2))
@@ -5760,7 +5764,7 @@ static void atk50_openpartyscreen(void)
}
else if (!gSpecialStatuses[gActiveBank].flag40)
{
- sub_804CF10(gBattleStruct->field_5C[0]);
+ sub_804CF10(gBattleStruct->monToSwitchIntoId[0]);
gSpecialStatuses[gActiveBank].flag40 = 1;
}
}
@@ -5776,7 +5780,7 @@ static void atk50_openpartyscreen(void)
}
else if (!gSpecialStatuses[gActiveBank].flag40)
{
- sub_804CF10(gBattleStruct->field_5C[1]);
+ sub_804CF10(gBattleStruct->monToSwitchIntoId[1]);
gSpecialStatuses[gActiveBank].flag40 = 1;
}
}
@@ -5830,10 +5834,10 @@ static void atk50_openpartyscreen(void)
{
gActiveBank = bank;
*(gBattleStruct->field_58 + gActiveBank) = gBattlePartyID[gActiveBank];
- *(gBattleStruct->field_5C + gActiveBank) = 6;
+ *(gBattleStruct->monToSwitchIntoId + gActiveBank) = 6;
gBattleStruct->field_93 &= ~(gBitTable[gActiveBank]);
- EmitChoosePokemon(0, hitmarkerFaintBits, *(gBattleStruct->field_5C + (gActiveBank ^ 2)), 0, gBattleStruct->field_60[gActiveBank]);
+ EmitChoosePokemon(0, hitmarkerFaintBits, *(gBattleStruct->monToSwitchIntoId + (gActiveBank ^ 2)), 0, gBattleStruct->field_60[gActiveBank]);
MarkBufferBankForExecution(gActiveBank);
gBattlescriptCurrInstr += 6;
@@ -5880,7 +5884,7 @@ static void atk51_switch_handle_order(void)
{
if (gBattleBufferB[i][0] == 0x22)
{
- *(gBattleStruct->field_5C + i) = gBattleBufferB[i][1];
+ *(gBattleStruct->monToSwitchIntoId + i) = gBattleBufferB[i][1];
if (!(gBattleStruct->field_93 & gBitTable[i]))
{
RecordedBattle_SetBankAction(i, gBattleBufferB[i][1]);
@@ -5902,7 +5906,7 @@ static void atk51_switch_handle_order(void)
// fall through
case 3:
gBattleCommunication[0] = gBattleBufferB[gActiveBank][1];
- *(gBattleStruct->field_5C + gActiveBank) = gBattleBufferB[gActiveBank][1];
+ *(gBattleStruct->monToSwitchIntoId + gActiveBank) = gBattleBufferB[gActiveBank][1];
if (gBattleTypeFlags & BATTLE_TYPE_LINK && gBattleTypeFlags & BATTLE_TYPE_MULTI)
{
@@ -5916,7 +5920,7 @@ static void atk51_switch_handle_order(void)
}
else if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
{
- sub_80571DC(gActiveBank, *(gBattleStruct->field_5C + gActiveBank));
+ sub_80571DC(gActiveBank, *(gBattleStruct->monToSwitchIntoId + gActiveBank));
}
else
{
@@ -6565,7 +6569,7 @@ static void atk67_yesnobox(void)
}
}
-static void atk68_80246A0(void)
+static void atk68_cancel_everyones_actions(void)
{
s32 i;
@@ -8023,7 +8027,7 @@ static void atk8F_forcerandomswitch(void)
|| GetMonData(&party[i], MON_DATA_IS_EGG) == TRUE
|| GetMonData(&party[i], MON_DATA_HP) == 0);
}
- *(gBattleStruct->field_5C + gBankTarget) = i;
+ *(gBattleStruct->monToSwitchIntoId + gBankTarget) = i;
if (!sub_81B1250())
sub_803BDA0(gBankTarget);
@@ -8547,13 +8551,11 @@ static void atk9D_mimicattackcopy(void)
}
}
-#ifdef NONMATCHING
static void atk9E_metronome(void)
{
while (1)
{
- const u16 *move;
- s32 i, j;
+ s32 i;
gCurrentMove = (Random() & 0x1FF) + 1;
if (gCurrentMove > LAST_MOVE_INDEX)
@@ -8561,102 +8563,26 @@ static void atk9E_metronome(void)
for (i = 0; i < 4; i++); // ?
- for (move = sMovesForbiddenToCopy; ; move++)
+ i = -1;
+ while (1)
{
- if (*move == gCurrentMove)
+ i++;
+ if (sMovesForbiddenToCopy[i] == gCurrentMove)
break;
- if (*move == METRONOME_FORBIDDEN_END)
+ if (sMovesForbiddenToCopy[i] == METRONOME_FORBIDDEN_END)
break;
}
- if (*move == METRONOME_FORBIDDEN_END)
- break;
+ if (sMovesForbiddenToCopy[i] == METRONOME_FORBIDDEN_END)
+ {
+ gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED);
+ gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect];
+ gBankTarget = GetMoveTarget(gCurrentMove, 0);
+ return;
+ }
}
-
- gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED);
- gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect];
- gBankTarget = GetMoveTarget(gCurrentMove, 0);
-}
-
-#else
-__attribute__((naked))
-static void atk9E_metronome(void)
-{
- asm(
- "\n\
- .syntax unified\n\
- push {r4-r7,lr}\n\
- mov r7, r8\n\
- push {r7}\n\
- ldr r7, =gCurrentMove\n\
- movs r6, 0xB1\n\
- lsls r6, 1\n\
- ldr r5, =sMovesForbiddenToCopy\n\
- ldr r0, =gBattlescriptCurrInstr\n\
- mov r8, r0\n\
-_080524EE:\n\
- bl Random\n\
- ldr r2, =0x000001ff\n\
- adds r1, r2, 0\n\
- ands r0, r1\n\
- adds r0, 0x1\n\
- strh r0, [r7]\n\
- cmp r0, r6\n\
- bhi _080524EE\n\
- movs r0, 0x3\n\
-_08052502:\n\
- subs r0, 0x1\n\
- cmp r0, 0\n\
- bge _08052502\n\
- ldr r4, =gCurrentMove\n\
- ldrh r2, [r4]\n\
- ldr r3, =0x0000ffff\n\
- subs r0, r5, 0x2\n\
-_08052510:\n\
- adds r0, 0x2\n\
- ldrh r1, [r0]\n\
- cmp r1, r2\n\
- beq _0805251C\n\
- cmp r1, r3\n\
- bne _08052510\n\
-_0805251C:\n\
- ldr r0, =0x0000ffff\n\
- cmp r1, r0\n\
- bne _080524EE\n\
- ldr r2, =gHitMarker\n\
- ldr r0, [r2]\n\
- ldr r1, =0xfffffbff\n\
- ands r0, r1\n\
- str r0, [r2]\n\
- ldr r3, =gBattleScriptsForMoveEffects\n\
- ldr r2, =gBattleMoves\n\
- ldrh r1, [r4]\n\
- lsls r0, r1, 1\n\
- adds r0, r1\n\
- lsls r0, 2\n\
- adds r0, r2\n\
- ldrb r0, [r0]\n\
- lsls r0, 2\n\
- adds r0, r3\n\
- ldr r0, [r0]\n\
- mov r1, r8\n\
- str r0, [r1]\n\
- ldrh r0, [r4]\n\
- movs r1, 0\n\
- bl GetMoveTarget\n\
- ldr r1, =gBankTarget\n\
- strb r0, [r1]\n\
- pop {r3}\n\
- mov r8, r3\n\
- pop {r4-r7}\n\
- pop {r0}\n\
- bx r0\n\
- .pool\n\
- .syntax divided");
}
-#endif // NONMATCHING
-
static void atk9F_dmgtolevel(void)
{
gBattleMoveDamage = gBattleMons[gBankAttacker].level;
@@ -8803,7 +8729,6 @@ static void atkA5_painsplitdmgcalc(void)
}
}
-#ifdef NONMATCHING
static void atkA6_settypetorandomresistance(void) // conversion 2
{
if (gUnknown_02024250[gBankAttacker] == 0
@@ -8818,298 +8743,58 @@ static void atkA6_settypetorandomresistance(void) // conversion 2
}
else
{
- s32 type = 0, rands = 0;
- do
+ s32 i, j, rands;
+
+ for (rands = 0; rands < 1000; rands++)
{
- while (((type = (Random() & 0x7F)) > 0x70));
+ while (((i = (Random() & 0x7F)) > sizeof(gTypeEffectiveness) / 3));
- type *= 3;
+ i *= 3;
- if (gTypeEffectiveness[type] == gUnknown_02024258[gBankAttacker]
- && gTypeEffectiveness[type + 2] <= 5
- && gBattleMons[gBankAttacker].type1 != gTypeEffectiveness[type + 1]
- && gBattleMons[gBankAttacker].type2 != gTypeEffectiveness[type + 1])
+ if (TYPE_EFFECT_ATK_TYPE(i) == gUnknown_02024258[gBankAttacker]
+ && TYPE_EFFECT_MULTIPLIER(i) <= TYPE_MUL_NOT_EFFECTIVE
+ && gBattleMons[gBankAttacker].type1 != TYPE_EFFECT_DEF_TYPE(i)
+ && gBattleMons[gBankAttacker].type2 != TYPE_EFFECT_DEF_TYPE(i))
{
- gBattleMons[gBankAttacker].type1 = type;
- gBattleMons[gBankAttacker].type2 = type;
+ gBattleMons[gBankAttacker].type1 = TYPE_EFFECT_DEF_TYPE(i);
+ gBattleMons[gBankAttacker].type2 = TYPE_EFFECT_DEF_TYPE(i);
- PREPARE_TYPE_BUFFER(gBattleTextBuff1, type)
+ PREPARE_TYPE_BUFFER(gBattleTextBuff1, TYPE_EFFECT_DEF_TYPE(i))
gBattlescriptCurrInstr += 5;
return;
}
+ }
- rands++;
- } while (rands <= 999);
-
- type = 0, rands = 0;
- do
+ for (j = 0, rands = 0; rands < sizeof(gTypeEffectiveness); j += 3, rands += 3)
{
- s8 var = (s8)(gTypeEffectiveness[type]);
- if (var > -1 || var < -2)
+ switch (TYPE_EFFECT_ATK_TYPE(j))
{
- if (gTypeEffectiveness[type] == gUnknown_02024258[gBankAttacker]
- && gTypeEffectiveness[type + 2] <= 5
- && gBattleMons[gBankAttacker].type1 != gTypeEffectiveness[type + 1]
- && gBattleMons[gBankAttacker].type2 != gTypeEffectiveness[type + 1])
+ case TYPE_ENDTABLE:
+ case TYPE_FORESIGHT:
+ break;
+ default:
+ if (TYPE_EFFECT_ATK_TYPE(j) == gUnknown_02024258[gBankAttacker]
+ && TYPE_EFFECT_MULTIPLIER(j) <= 5
+ && gBattleMons[gBankAttacker].type1 != TYPE_EFFECT_DEF_TYPE(i)
+ && gBattleMons[gBankAttacker].type2 != TYPE_EFFECT_DEF_TYPE(i))
{
- gBattleMons[gBankAttacker].type1 = gTypeEffectiveness[rands + 1];
- gBattleMons[gBankAttacker].type2 = gTypeEffectiveness[rands + 1];
+ gBattleMons[gBankAttacker].type1 = TYPE_EFFECT_DEF_TYPE(rands);
+ gBattleMons[gBankAttacker].type2 = TYPE_EFFECT_DEF_TYPE(rands);
- PREPARE_TYPE_BUFFER(gBattleTextBuff1, gTypeEffectiveness[rands + 1])
+ PREPARE_TYPE_BUFFER(gBattleTextBuff1, TYPE_EFFECT_DEF_TYPE(rands))
gBattlescriptCurrInstr += 5;
return;
}
+ break;
}
- type += 3, rands += 3;
- } while (rands < 336);
+ }
gBattlescriptCurrInstr = BSScriptReadPtr(gBattlescriptCurrInstr + 1);
}
}
-#else
-__attribute__((naked))
-static void atkA6_settypetorandomresistance(void) // conversion 2
-{
- asm(".syntax unified\n\
- push {r4-r7,lr}\n\
- mov r7, r10\n\
- mov r6, r9\n\
- mov r5, r8\n\
- push {r5-r7}\n\
- ldr r1, =gUnknown_02024250\n\
- ldr r4, =gBankAttacker\n\
- ldrb r0, [r4]\n\
- lsls r0, 1\n\
- adds r2, r0, r1\n\
- ldrh r1, [r2]\n\
- cmp r1, 0\n\
- beq _08052B7E\n\
- ldr r0, =0x0000ffff\n\
- cmp r1, r0\n\
- beq _08052B7E\n\
- ldrh r0, [r2]\n\
- bl IsTwoTurnsMove\n\
- lsls r0, 24\n\
- cmp r0, 0\n\
- beq _08052C1C\n\
- ldr r1, =gBattleMons\n\
- ldr r2, =gUnknown_02024270\n\
- ldrb r0, [r4]\n\
- adds r0, r2\n\
- ldrb r2, [r0]\n\
- movs r0, 0x58\n\
- muls r0, r2\n\
- adds r1, 0x50\n\
- adds r0, r1\n\
- ldr r0, [r0]\n\
- movs r1, 0x80\n\
- lsls r1, 5\n\
- ands r0, r1\n\
- cmp r0, 0\n\
- beq _08052C1C\n\
-_08052B7E:\n\
- ldr r3, =gBattlescriptCurrInstr\n\
- ldr r2, [r3]\n\
- ldrb r1, [r2, 0x1]\n\
- ldrb r0, [r2, 0x2]\n\
- lsls r0, 8\n\
- orrs r1, r0\n\
- ldrb r0, [r2, 0x3]\n\
- lsls r0, 16\n\
- orrs r1, r0\n\
- ldrb r0, [r2, 0x4]\n\
- lsls r0, 24\n\
- orrs r1, r0\n\
- str r1, [r3]\n\
- b _08052D08\n\
- .pool\n\
-_08052BB4:\n\
- mov r0, r12\n\
- strb r5, [r0]\n\
- mov r1, r10\n\
- ldrb r0, [r1]\n\
- muls r0, r2\n\
- adds r0, r7\n\
- adds r0, 0x22\n\
- strb r5, [r0]\n\
- ldr r1, =gBattleTextBuff1\n\
- movs r0, 0xFD\n\
- strb r0, [r1]\n\
- movs r0, 0x3\n\
- strb r0, [r1, 0x1]\n\
- strb r5, [r1, 0x2]\n\
- movs r0, 0xFF\n\
- strb r0, [r1, 0x3]\n\
- ldr r1, =gBattlescriptCurrInstr\n\
- b _08052C0A\n\
- .pool\n\
-_08052BE0:\n\
- mov r0, r8\n\
- adds r0, 0x1\n\
- adds r0, r3\n\
- ldrb r2, [r0]\n\
- strb r2, [r4]\n\
- mov r4, r10\n\
- ldrb r0, [r4]\n\
- muls r0, r6\n\
- ldr r7, =gBattleMons\n\
- adds r0, r7\n\
- adds r0, 0x22\n\
- strb r2, [r0]\n\
- ldr r1, =gBattleTextBuff1\n\
- movs r0, 0xFD\n\
- strb r0, [r1]\n\
- movs r0, 0x3\n\
- strb r0, [r1, 0x1]\n\
- strb r2, [r1, 0x2]\n\
- movs r0, 0xFF\n\
- strb r0, [r1, 0x3]\n\
- mov r1, r12\n\
-_08052C0A:\n\
- ldr r0, [r1]\n\
- adds r0, 0x5\n\
- str r0, [r1]\n\
- b _08052D08\n\
- .pool\n\
-_08052C1C:\n\
- movs r4, 0\n\
- mov r8, r4\n\
- movs r7, 0x7F\n\
- mov r9, r7\n\
-_08052C24:\n\
- bl Random\n\
- mov r4, r9\n\
- ands r4, r0\n\
- cmp r4, 0x70\n\
- bhi _08052C24\n\
- lsls r0, r4, 1\n\
- adds r4, r0, r4\n\
- ldr r6, =gTypeEffectiveness\n\
- adds r3, r4, r6\n\
- ldr r1, =gUnknown_02024258\n\
- ldr r2, =gBankAttacker\n\
- ldrb r5, [r2]\n\
- lsls r0, r5, 1\n\
- adds r0, r1\n\
- ldrb r1, [r3]\n\
- mov r10, r2\n\
- ldrh r0, [r0]\n\
- cmp r1, r0\n\
- bne _08052C80\n\
- adds r0, r4, 0x2\n\
- adds r0, r6\n\
- ldrb r0, [r0]\n\
- cmp r0, 0x5\n\
- bhi _08052C80\n\
- ldr r7, =gBattleMons\n\
- movs r2, 0x58\n\
- adds r0, r5, 0\n\
- muls r0, r2\n\
- adds r3, r0, r7\n\
- movs r0, 0x21\n\
- adds r0, r3\n\
- mov r12, r0\n\
- adds r0, r4, 0x1\n\
- adds r0, r6\n\
- ldrb r5, [r0]\n\
- mov r1, r12\n\
- ldrb r0, [r1]\n\
- adds r1, r5, 0\n\
- cmp r0, r1\n\
- beq _08052C80\n\
- adds r0, r3, 0\n\
- adds r0, 0x22\n\
- ldrb r0, [r0]\n\
- cmp r0, r1\n\
- bne _08052BB4\n\
-_08052C80:\n\
- movs r7, 0x1\n\
- add r8, r7\n\
- ldr r0, =0x000003e7\n\
- cmp r8, r0\n\
- ble _08052C24\n\
- movs r0, 0\n\
- mov r8, r0\n\
- ldr r1, =gBattlescriptCurrInstr\n\
- mov r12, r1\n\
- ldr r3, =gTypeEffectiveness\n\
- adds r0, r4, 0x1\n\
- adds r0, r3\n\
- mov r9, r0\n\
- adds r5, r3, 0\n\
-_08052C9C:\n\
- ldrb r1, [r5]\n\
- cmp r1, 0xFF\n\
- bgt _08052CA6\n\
- cmp r1, 0xFE\n\
- bge _08052CE0\n\
-_08052CA6:\n\
- mov r4, r10\n\
- ldrb r2, [r4]\n\
- lsls r0, r2, 1\n\
- ldr r7, =gUnknown_02024258\n\
- adds r0, r7\n\
- ldrh r0, [r0]\n\
- cmp r1, r0\n\
- bne _08052CE0\n\
- ldrb r0, [r5, 0x2]\n\
- cmp r0, 0x5\n\
- bhi _08052CE0\n\
- movs r6, 0x58\n\
- adds r0, r2, 0\n\
- muls r0, r6\n\
- ldr r1, =gBattleMons\n\
- adds r2, r0, r1\n\
- adds r4, r2, 0\n\
- adds r4, 0x21\n\
- ldrb r0, [r4]\n\
- mov r7, r9\n\
- ldrb r1, [r7]\n\
- cmp r0, r1\n\
- beq _08052CE0\n\
- adds r0, r2, 0\n\
- adds r0, 0x22\n\
- ldrb r0, [r0]\n\
- cmp r0, r1\n\
- beq _08052CE0\n\
- b _08052BE0\n\
-_08052CE0:\n\
- adds r5, 0x3\n\
- movs r0, 0x3\n\
- add r8, r0\n\
- ldr r0, =0x0000014f\n\
- cmp r8, r0\n\
- bls _08052C9C\n\
- mov r1, r12\n\
- ldr r2, [r1]\n\
- ldrb r1, [r2, 0x1]\n\
- ldrb r0, [r2, 0x2]\n\
- lsls r0, 8\n\
- orrs r1, r0\n\
- ldrb r0, [r2, 0x3]\n\
- lsls r0, 16\n\
- orrs r1, r0\n\
- ldrb r0, [r2, 0x4]\n\
- lsls r0, 24\n\
- orrs r1, r0\n\
- mov r4, r12\n\
- str r1, [r4]\n\
-_08052D08:\n\
- pop {r3-r5}\n\
- mov r8, r3\n\
- mov r9, r4\n\
- mov r10, r5\n\
- pop {r4-r7}\n\
- pop {r0}\n\
- bx r0\n\
- .pool\n\
- .syntax divided");
-}
-#endif // NONMATCHING
-
static void atkA7_setalwayshitflag(void)
{
gStatuses3[gBankTarget] &= ~(STATUS3_ALWAYS_HITS);
@@ -9493,8 +9178,8 @@ static void atkB2_setperishsong(void)
else
{
gStatuses3[i] |= STATUS3_PERISH_SONG;
- gDisableStructs[i].perishSong1 = 3;
- gDisableStructs[i].perishSong2 = 3;
+ gDisableStructs[i].perishSongTimer1 = 3;
+ gDisableStructs[i].perishSongTimer2 = 3;
}
}
@@ -9848,24 +9533,24 @@ static void atkC0_recoverbasedonsunlight(void)
}
#ifdef NONMATCHING
-static void atkC1_hidden_power(void)
+static void atkC1_hidden_power_calc(void)
{
- s32 powerBits;
- s32 typeBits;
+ u32 powerBits = 0;
+ u32 typeBits = 0;
- powerBits = ((gBattleMons[gBankAttacker].hpIV & 2) >> 1)
- | ((gBattleMons[gBankAttacker].attackIV & 2) << 0)
- | ((gBattleMons[gBankAttacker].defenseIV & 2) << 1)
- | ((gBattleMons[gBankAttacker].speedIV & 2) << 2)
- | ((gBattleMons[gBankAttacker].spAttackIV & 2) << 3)
- | ((gBattleMons[gBankAttacker].spDefenseIV & 2) << 4);
+ powerBits |= ((gBattleMons[gBankAttacker].hpIV & 2) >> 1);
+ powerBits |= ((gBattleMons[gBankAttacker].attackIV & 2) << 0);
+ powerBits |= ((gBattleMons[gBankAttacker].defenseIV & 2) << 1);
+ powerBits |= ((gBattleMons[gBankAttacker].speedIV & 2) << 2);
+ powerBits |= ((gBattleMons[gBankAttacker].spAttackIV & 2) << 3);
+ powerBits |= ((gBattleMons[gBankAttacker].spDefenseIV & 2) << 4);
- typeBits = ((gBattleMons[gBankAttacker].hpIV & 1) << 0)
- | ((gBattleMons[gBankAttacker].attackIV & 1) << 1)
- | ((gBattleMons[gBankAttacker].defenseIV & 1) << 2)
- | ((gBattleMons[gBankAttacker].speedIV & 1) << 3)
- | ((gBattleMons[gBankAttacker].spAttackIV & 1) << 4)
- | ((gBattleMons[gBankAttacker].spDefenseIV & 1) << 5);
+ typeBits |= ((gBattleMons[gBankAttacker].hpIV & 1) << 0);
+ typeBits |= ((gBattleMons[gBankAttacker].attackIV & 1) << 1);
+ typeBits |= ((gBattleMons[gBankAttacker].defenseIV & 1) << 2);
+ typeBits |= ((gBattleMons[gBankAttacker].speedIV & 1) << 3);
+ typeBits |= ((gBattleMons[gBankAttacker].spAttackIV & 1) << 4);
+ typeBits |= ((gBattleMons[gBankAttacker].spDefenseIV & 1) << 5);
gDynamicBasePower = (40 * powerBits) / 63 + 30;
@@ -9879,7 +9564,7 @@ static void atkC1_hidden_power(void)
#else
__attribute__((naked))
-static void atkC1_hidden_power(void)
+static void atkC1_hidden_power_calc(void)
{
asm(".syntax unified\n\
push {r4-r7,lr}\n\
@@ -11160,7 +10845,7 @@ static void atkF0_give_caught_mon(void)
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
}
- if (FlagGet(SYS_PC_LANETTE))
+ if (FlagGet(FLAG_SYS_PC_LANETTE))
gBattleCommunication[MULTISTRING_CHOOSER]++;
}
diff --git a/src/battle_util.c b/src/battle_util.c
index 468b2c46d..ed3bdef98 100644
--- a/src/battle_util.c
+++ b/src/battle_util.c
@@ -1292,9 +1292,9 @@ bool8 sub_8041364(void)
gBattleTextBuff1[1] = 1;
gBattleTextBuff1[2] = 1;
gBattleTextBuff1[3] = 1;
- gBattleTextBuff1[4] = gDisableStructs[gActiveBank].perishSong1;
+ gBattleTextBuff1[4] = gDisableStructs[gActiveBank].perishSongTimer1;
gBattleTextBuff1[5] = EOS;
- if (gDisableStructs[gActiveBank].perishSong1 == 0)
+ if (gDisableStructs[gActiveBank].perishSongTimer1 == 0)
{
gStatuses3[gActiveBank] &= ~STATUS3_PERISH_SONG;
gBattleMoveDamage = gBattleMons[gActiveBank].hp;
@@ -1302,7 +1302,7 @@ bool8 sub_8041364(void)
}
else
{
- gDisableStructs[gActiveBank].perishSong1--;
+ gDisableStructs[gActiveBank].perishSongTimer1--;
gBattlescriptCurrInstr = gUnknown_082DAF20;
}
BattleScriptExecute(gBattlescriptCurrInstr);
@@ -1805,7 +1805,7 @@ bool8 sub_80423F4(u8 bank, u8 r1, u8 r2)
&& GetMonData(&party[i], MON_DATA_SPECIES2) != 0
&& GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_EGG
// FIXME: Using index[array] instead of array[index] is BAD!
- && i != r1 && i != r2 && i != r7[gBattleStruct->field_5C] && i != r6[gBattleStruct->field_5C])
+ && i != r1 && i != r2 && i != r7[gBattleStruct->monToSwitchIntoId] && i != r6[gBattleStruct->monToSwitchIntoId])
break;
}
return (i == 6);
@@ -3511,16 +3511,16 @@ u8 IsPokeDisobedient(void)
return 0;
if (!IsOtherTrainer(gBattleMons[gBankAttacker].otId, gBattleMons[gBankAttacker].otName))
return 0;
- if (FlagGet(BADGE08_GET))
+ if (FlagGet(FLAG_BADGE08_GET))
return 0;
obedienceLevel = 10;
- if (FlagGet(BADGE02_GET))
+ if (FlagGet(FLAG_BADGE02_GET))
obedienceLevel = 30;
- if (FlagGet(BADGE04_GET))
+ if (FlagGet(FLAG_BADGE04_GET))
obedienceLevel = 50;
- if (FlagGet(BADGE06_GET))
+ if (FlagGet(FLAG_BADGE06_GET))
obedienceLevel = 70;
}
diff --git a/src/battle_util2.c b/src/battle_util2.c
new file mode 100644
index 000000000..e119c85d7
--- /dev/null
+++ b/src/battle_util2.c
@@ -0,0 +1,219 @@
+#include "global.h"
+#include "battle.h"
+#include "battle_controllers.h"
+#include "malloc.h"
+#include "pokemon.h"
+#include "event_data.h"
+#include "abilities.h"
+#include "rng.h"
+
+extern struct BattlePokemon gBattleMons[BATTLE_BANKS_COUNT];
+extern u16 gBattlePartyID[BATTLE_BANKS_COUNT];
+extern u8 gUnknown_0203CF00[];
+extern const u8* gBattlescriptCurrInstr;
+extern u8 gBattleCommunication[];
+extern u8 gActiveBank;
+
+extern const u8 BattleScript_MoveUsedWokeUp[];
+extern const u8 BattleScript_MoveUsedIsFrozen[];
+extern const u8 BattleScript_MoveUsedUnfroze[];
+extern const u8 BattleScript_MoveUsedIsAsleep[];
+
+extern void sub_81D55D0(void);
+extern void sub_81D5694(void);
+extern u8 pokemon_order_func(u8);
+extern void sub_81B8FB0(u8, u8);
+
+void AllocateBattleResources(void)
+{
+ gBattleResources = gBattleResources; // something dumb needed to match
+
+ if (gBattleTypeFlags & BATTLE_TYPE_x4000000)
+ sub_81D55D0();
+
+ gBattleStruct = AllocZeroed(sizeof(*gBattleStruct));
+
+ gBattleResources = AllocZeroed(sizeof(*gBattleResources));
+ gBattleResources->secretBase = AllocZeroed(sizeof(*gBattleResources->secretBase));
+ gBattleResources->flags = AllocZeroed(sizeof(*gBattleResources->flags));
+ gBattleResources->battleScriptsStack = AllocZeroed(sizeof(*gBattleResources->battleScriptsStack));
+ gBattleResources->battleCallbackStack = AllocZeroed(sizeof(*gBattleResources->battleCallbackStack));
+ gBattleResources->statsBeforeLvlUp = AllocZeroed(sizeof(*gBattleResources->statsBeforeLvlUp));
+ gBattleResources->ai = AllocZeroed(sizeof(*gBattleResources->ai));
+ gBattleResources->battleHistory = AllocZeroed(sizeof(*gBattleResources->battleHistory));
+ gBattleResources->AI_ScriptsStack = AllocZeroed(sizeof(*gBattleResources->AI_ScriptsStack));
+
+ gLinkBattleSendBuffer = AllocZeroed(BATTLE_BUFFER_LINK_SIZE);
+ gLinkBattleRecvBuffer = AllocZeroed(BATTLE_BUFFER_LINK_SIZE);
+
+ gUnknown_0202305C = AllocZeroed(0x2000);
+ gUnknown_02023060 = AllocZeroed(0x1000);
+
+ if (gBattleTypeFlags & BATTLE_TYPE_SECRET_BASE)
+ {
+ u16 currSecretBaseId = VarGet(VAR_0x4054);
+ CreateSecretBaseEnemyParty(&gSaveBlock1Ptr->secretBases[currSecretBaseId]);
+ }
+}
+
+void FreeBattleResources(void)
+{
+ if (gBattleTypeFlags & BATTLE_TYPE_x4000000)
+ sub_81D5694();
+
+ if (gBattleResources != NULL)
+ {
+ FREE_AND_SET_NULL(gBattleStruct);
+
+ FREE_AND_SET_NULL(gBattleResources->secretBase);
+ FREE_AND_SET_NULL(gBattleResources->flags);
+ FREE_AND_SET_NULL(gBattleResources->battleScriptsStack);
+ FREE_AND_SET_NULL(gBattleResources->battleCallbackStack);
+ FREE_AND_SET_NULL(gBattleResources->statsBeforeLvlUp);
+ FREE_AND_SET_NULL(gBattleResources->ai);
+ FREE_AND_SET_NULL(gBattleResources->battleHistory);
+ FREE_AND_SET_NULL(gBattleResources->AI_ScriptsStack);
+ FREE_AND_SET_NULL(gBattleResources);
+
+ FREE_AND_SET_NULL(gLinkBattleSendBuffer);
+ FREE_AND_SET_NULL(gLinkBattleRecvBuffer);
+
+ FREE_AND_SET_NULL(gUnknown_0202305C);
+ FREE_AND_SET_NULL(gUnknown_02023060);
+ }
+}
+
+void AdjustFriendshipOnBattleFaint(u8 bank)
+{
+ u8 opposingBank;
+
+ if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
+ {
+ u8 opposingBank2;
+
+ opposingBank = GetBankByIdentity(IDENTITY_OPPONENT_MON1);
+ opposingBank2 = GetBankByIdentity(IDENTITY_OPPONENT_MON2);
+
+ if (gBattleMons[opposingBank2].level > gBattleMons[opposingBank].level)
+ opposingBank = opposingBank2;
+ }
+ else
+ {
+ opposingBank = GetBankByIdentity(IDENTITY_OPPONENT_MON1);
+ }
+
+ if (gBattleMons[opposingBank].level > gBattleMons[bank].level)
+ {
+ if (gBattleMons[opposingBank].level - gBattleMons[bank].level > 29)
+ AdjustFriendship(&gPlayerParty[gBattlePartyID[bank]], 8);
+ else
+ AdjustFriendship(&gPlayerParty[gBattlePartyID[bank]], 6);
+ }
+ else
+ {
+ AdjustFriendship(&gPlayerParty[gBattlePartyID[bank]], 6);
+ }
+}
+
+void sub_80571DC(u8 bank, u8 arg1)
+{
+ if (GetBankSide(bank) != SIDE_OPPONENT)
+ {
+ s32 i;
+
+ // gBattleStruct->field_60[0][i]
+
+ for (i = 0; i < 3; i++)
+ gUnknown_0203CF00[i] = *(0 * 3 + i + (u8*)(gBattleStruct->field_60));
+
+ sub_81B8FB0(pokemon_order_func(gBattlePartyID[bank]), 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 effect = 0;
+
+ do
+ {
+ switch (gBattleCommunication[MULTIUSE_STATE])
+ {
+ case 0:
+ if (gBattleMons[bank].status1 & STATUS_SLEEP)
+ {
+ if (UproarWakeUpCheck(bank))
+ {
+ gBattleMons[bank].status1 &= ~(STATUS_SLEEP);
+ gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE);
+ BattleScriptPushCursor();
+ gBattleCommunication[MULTISTRING_CHOOSER] = 1;
+ gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp;
+ effect = 2;
+ }
+ else
+ {
+ u32 toSub;
+
+ if (gBattleMons[bank].ability == ABILITY_EARLY_BIRD)
+ toSub = 2;
+ else
+ toSub = 1;
+
+ if ((gBattleMons[bank].status1 & STATUS_SLEEP) < toSub)
+ gBattleMons[bank].status1 &= ~(STATUS_SLEEP);
+ else
+ gBattleMons[bank].status1 -= toSub;
+
+ if (gBattleMons[bank].status1 & STATUS_SLEEP)
+ {
+ gBattlescriptCurrInstr = BattleScript_MoveUsedIsAsleep;
+ effect = 2;
+ }
+ else
+ {
+ gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE);
+ BattleScriptPushCursor();
+ gBattleCommunication[MULTISTRING_CHOOSER] = 0;
+ gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp;
+ effect = 2;
+ }
+ }
+ }
+ gBattleCommunication[MULTIUSE_STATE]++;
+ break;
+ case 1:
+ if (gBattleMons[bank].status1 & STATUS_FREEZE)
+ {
+ if (Random() % 5 != 0)
+ {
+ gBattlescriptCurrInstr = BattleScript_MoveUsedIsFrozen;
+ }
+ else
+ {
+ gBattleMons[bank].status1 &= ~(STATUS_FREEZE);
+ BattleScriptPushCursor();
+ gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze;
+ gBattleCommunication[MULTISTRING_CHOOSER] = 0;
+ }
+ effect = 2;
+ }
+ gBattleCommunication[MULTIUSE_STATE]++;
+ break;
+ case 2:
+ break;
+ }
+
+ } while (gBattleCommunication[MULTIUSE_STATE] != 2 && effect == 0);
+
+ if (effect == 2)
+ {
+ gActiveBank = bank;
+ EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1);
+ MarkBufferBankForExecution(gActiveBank);
+ }
+
+ return effect;
+}
diff --git a/src/berry.c b/src/berry.c
index 98cf7d932..6d1fd17a1 100644
--- a/src/berry.c
+++ b/src/berry.c
@@ -14,7 +14,7 @@ extern void CB2_ChooseBerry(void);
extern const u8* GetFieldObjectScriptPointerForComparison(void);
extern bool8 sub_8092E9C(u8, u8, u8);
-extern u16 gScriptItemId;
+extern u16 gSpecialVar_ItemId;
extern const u8 BerryTreeScript[];
@@ -1169,7 +1169,7 @@ void FieldObjectInteractionGetBerryTreeData(void)
id = FieldObjectGetBerryTreeId(gSelectedMapObject);
berry = GetBerryTypeByBerryTreeId(id);
ResetBerryTreeSparkleFlag(id);
- unk = gScriptLastTalked;
+ unk = gSpecialVar_LastTalked;
num = gSaveBlock1Ptr->location.mapNum;
group = gSaveBlock1Ptr->location.mapGroup;
if (sub_8092E9C(unk, num, group))
@@ -1202,7 +1202,7 @@ void Bag_ChooseBerry(void)
void FieldObjectInteractionPlantBerryTree(void)
{
- u8 berry = ItemIdToBerryType(gScriptItemId);
+ u8 berry = ItemIdToBerryType(gSpecialVar_ItemId);
PlantBerryTree(FieldObjectGetBerryTreeId(gSelectedMapObject), berry, 1, TRUE);
FieldObjectInteractionGetBerryTreeData();
@@ -1219,7 +1219,7 @@ void FieldObjectInteractionPickBerryTree(void)
void FieldObjectInteractionRemoveBerryTree(void)
{
RemoveBerryTree(FieldObjectGetBerryTreeId(gSelectedMapObject));
- sub_8092EF0(gScriptLastTalked, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
+ sub_8092EF0(gSpecialVar_LastTalked, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
}
u8 PlayerHasBerries(void)
diff --git a/src/berry_blender.c b/src/berry_blender.c
index db50fe4c4..8e5a51845 100644
--- a/src/berry_blender.c
+++ b/src/berry_blender.c
@@ -1,6 +1,8 @@
-
-// Includes
#include "global.h"
+#include "bg.h"
+#include "window.h"
+#include "task.h"
+#include "sprite.h"
// Static type declarations
@@ -11,8 +13,585 @@ IWRAM_DATA s16 gUnknown_03000DF8[6];
IWRAM_DATA s16 gUnknown_03000E04;
IWRAM_DATA s16 gUnknown_03000E06;
-// Static ROM declarations
+// graphics
+extern const u8 gBerryBlenderArrowTiles[];
+extern const u8 gBerryBlenderStartTiles[];
+extern const u8 gBerryBlenderMarubatsuTiles[];
+extern const u8 gBerryBlenderParticlesTiles[];
+extern const u8 gBerryBlenderCountdownNumbersTiles[];
+extern const u16 gBerryBlenderMiscPalette[];
+extern const u16 gBerryBlenderArrowPalette[];
+
+void sub_8080EA4(u8 taskId);
+void sub_8080FD0(u8 taskId);
+void sub_80810F8(u8 taskId);
+void sub_80833F8(struct Sprite *sprite);
+void sub_8082F68(struct Sprite *sprite);
+void sub_8083010(struct Sprite *sprite);
+void sub_80830C0(struct Sprite *sprite);
// .rodata
+// TODO: make those static once the file is decompiled
+const u16 sBlenderCenterPal[] = INCBIN_U16("graphics/berry_blender/center.gbapal");
+const u8 sBlenderCenterMap[] = INCBIN_U8("graphics/berry_blender/center_map.bin");
+const u16 sBlenderOuterPal[] = INCBIN_U16("graphics/berry_blender/outer.gbapal");
+
+// unreferenced pals?
+static const u16 sUnknownPal_0[] = INCBIN_U16("graphics/unknown/unknown_339514.gbapal");
+static const u16 sUnknownArray_1[224] = {0};
+
+// unused text?
+static const u8 sUnusedText_YesNo[] = _("YES\nNO");
+static const u8 sUnusedText_2[] = _("▶");
+static const u8 sUnusedText_Space[] = _(" ");
+static const u8 sUnusedText_Terminating[] = _("Terminating.");
+static const u8 sUnusedText_LinkPartnerNotFound[] = _("Link partner(s) not found.\nPlease try again.\p");
+
+const u8 gText_BerryBlenderStart[] = _("Starting up the BERRY BLENDER.\pPlease select a BERRY from your BAG\nto put in the BERRY BLENDER.\p");
+const u8 gText_NewParagraph[] = _("\p");
+const u8 gText_WasMade[] = _(" was made!");
+static const u8 sText_Mister[] = _("MISTER");
+static const u8 sText_Laddie[] = _("LADDIE");
+static const u8 sText_Lassie[] = _("LASSIE");
+static const u8 sText_Master[] = _("MASTER");
+static const u8 sText_Dude[] = _("DUDE");
+static const u8 sText_Miss[] = _("MISS");
+
+const u8* const sBlenderOpponentsNames[] =
+{
+ sText_Mister,
+ sText_Laddie,
+ sText_Lassie,
+ sText_Master,
+ sText_Dude,
+ sText_Miss
+};
+
+static const u8 sText_PressAToStart[] = _("Press the A Button to start.");
+static const u8 sText_PleaseWaitAWhile[] = _("Please wait a while.");
+const u8 sText_CommunicationStandby[] = _("Communication standby…");
+const u8 sText_WouldLikeToBlendAnotherBerry[] = _("Would you like to blend another BERRY?");
+const u8 sText_RunOutOfBerriesForBlending[] = _("You’ve run out of BERRIES for\nblending in the BERRY BLENDER.\p");
+const u8 sText_YourPokeblockCaseIsFull[] = _("Your {POKEBLOCK} CASE is full.\p");
+const u8 sText_HasNoBerriesToPut[] = _(" has no BERRIES to put in\nthe BERRY BLENDER.");
+const u8 sText_ApostropheSPokeblockCaseIsFull[] = _("’s {POKEBLOCK} CASE is full.\p");
+const u8 sText_BlendingResults[] = _("RESULTS OF BLENDING");
+static const u8 sText_BerryUsed[] = _("BERRY USED");
+const u8 sText_SpaceBerry[] = _(" BERRY");
+const u8 sText_Time[] = _("Time:");
+const u8 sText_Min[] = _(" min. ");
+const u8 sText_Sec[] = _(" sec.");
+const u8 sText_MaximumSpeed[] = _("MAXIMUM SPEED");
+const u8 sText_RPM[] = _(" RPM");
+const u8 sText_Dot[] = _(".");
+const u8 sText_NewLine[] = _("\n");
+static const u8 sText_Space[] = _(" ");
+const u8 sText_Ranking[] = _("RANKING");
+const u8 sText_TheLevelIs[] = _("The level is ");
+const u8 sText_TheFeelIs[] = _(", and the feel is ");
+const u8 sText_Dot2[] = _(".");
+
+const struct BgTemplate gUnknown_08339974[3] =
+{
+ {
+ .bg = 0,
+ .charBaseIndex = 3,
+ .mapBaseIndex = 31,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 0,
+ .baseTile = 0,
+ },
+ {
+ .bg = 1,
+ .charBaseIndex = 2,
+ .mapBaseIndex = 12,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 1,
+ .baseTile = 0,
+ },
+ {
+ .bg = 2,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 8,
+ .screenSize = 1,
+ .paletteMode = 1,
+ .priority = 0,
+ .baseTile = 0,
+ }
+};
+
+const struct WindowTemplate gUnknown_08339980[] =
+{
+ {0, 1, 6, 7, 2, 0xE, 0x28},
+ {0, 0x16, 6, 7, 2, 0xE, 0x36},
+ {0, 1, 0xC, 7, 2, 0xE, 0x44},
+ {0, 0x16, 0xC, 7, 2, 0xE, 0x52},
+ {0, 2, 0xF, 0x1B, 4, 0xE, 0x60},
+ {0, 5, 3, 0x15, 0xE, 0xE, 0x60},
+ DUMMY_WIN_TEMPLATE
+};
+
+const struct WindowTemplate gUnknown_083399B8 =
+{
+ 0, 0x15, 9, 5, 4, 0xE, 0xCC
+};
+
+const s8 gUnknown_083399C0[][2] =
+{
+ {-1, -1}, {1, -1}, {-1, 1}, {1, 1}
+};
+
+const u8 sBlenderSyncArrowsPos[][2] =
+{
+ {72, 32}, {168, 32}, {72, 128}, {168, 128}
+};
+
+const u8 gUnknown_083399D0[3][4] =
+{
+ {-1, 0, 1, -1}, {-1, 0, 1, 2}, {0, 1, 2, 3}
+};
+
+const u16 gUnknown_083399DC[] = {0, 0xC000, 0x4000, 0x8000};
+const u8 gUnknown_083399E4[] = {1, 1, 0};
+const u8 gUnknown_083399E7[] = {32, 224, 96, 160, 0};
+
+const TaskFunc gUnknown_083399EC[] =
+{
+ sub_8080EA4, sub_8080FD0, sub_80810F8
+};
+
+static const struct OamData sOamData_8216314 =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 2,
+ .tileNum = 0,
+ .priority = 1,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const union AnimCmd sSpriteAnim_821631C[] =
+{
+ ANIMCMD_FRAME(16, 5, 1, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_8216324[] =
+{
+ ANIMCMD_FRAME(16, 5, .vFlip = TRUE),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_821632C[] =
+{
+ ANIMCMD_FRAME(16, 5, .hFlip = TRUE),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_8216334[] =
+{
+ ANIMCMD_FRAME(16, 5, 0, 0),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_821633C[] =
+{
+ ANIMCMD_FRAME(48, 2, 1, 1),
+ ANIMCMD_FRAME(32, 5, 1, 1),
+ ANIMCMD_FRAME(48, 3, 1, 1),
+ ANIMCMD_FRAME(16, 5, 1, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_8216350[] =
+{
+ ANIMCMD_FRAME(48, 2, .vFlip = TRUE),
+ ANIMCMD_FRAME(32, 5, .vFlip = TRUE),
+ ANIMCMD_FRAME(48, 3, .vFlip = TRUE),
+ ANIMCMD_FRAME(16, 5, .vFlip = TRUE),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_8216364[] =
+{
+ ANIMCMD_FRAME(48, 2, .hFlip = TRUE),
+ ANIMCMD_FRAME(32, 5, .hFlip = TRUE),
+ ANIMCMD_FRAME(48, 3, .hFlip = TRUE),
+ ANIMCMD_FRAME(16, 5, .hFlip = TRUE),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_8216378[] =
+{
+ ANIMCMD_FRAME(48, 2, 0, 0),
+ ANIMCMD_FRAME(32, 5, 0, 0),
+ ANIMCMD_FRAME(48, 3, 0, 0),
+ ANIMCMD_FRAME(16, 5, 0, 0),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_821638C[] =
+{
+ ANIMCMD_FRAME(0, 5, 1, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_8216394[] =
+{
+ ANIMCMD_FRAME(0, 5, .vFlip = TRUE),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_821639C[] =
+{
+ ANIMCMD_FRAME(0, 5, .hFlip = TRUE),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_82163A4[] =
+{
+ ANIMCMD_FRAME(0, 5, 0, 0),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_82163AC[] =
+{
+ sSpriteAnim_821631C,
+ sSpriteAnim_8216324,
+ sSpriteAnim_821632C,
+ sSpriteAnim_8216334,
+ sSpriteAnim_821633C,
+ sSpriteAnim_8216350,
+ sSpriteAnim_8216364,
+ sSpriteAnim_8216378,
+ sSpriteAnim_821638C,
+ sSpriteAnim_8216394,
+ sSpriteAnim_821639C,
+ sSpriteAnim_82163A4
+};
+
+const struct SpriteSheet sSpriteSheet_BlenderArrow =
+{
+ gBerryBlenderArrowTiles, 0x800, 46545
+};
+
+const struct SpritePalette sSpritePal_BlenderMisc =
+{
+ gBerryBlenderMiscPalette, 46546
+};
+
+const struct SpritePalette sSpritePal_BlenderArrow =
+{
+ gBerryBlenderArrowPalette, 12312
+};
+
+const struct SpriteTemplate sBlenderSyncArrow_SpriteTemplate =
+{
+ .tileTag = 46545,
+ .paletteTag = 12312,
+ .oam = &sOamData_8216314,
+ .anims = sSpriteAnimTable_82163AC,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80833F8
+};
+
+static const struct OamData sOamData_821640C =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 1,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const union AnimCmd sSpriteAnim_8216414[] =
+{
+ ANIMCMD_FRAME(0, 20),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_821641C[] =
+{
+ ANIMCMD_FRAME(4, 20, 1, 0),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_8216424[] =
+{
+ ANIMCMD_FRAME(8, 4),
+ ANIMCMD_FRAME(12, 4),
+ ANIMCMD_FRAME(8, 4),
+ ANIMCMD_FRAME(12, 4),
+ ANIMCMD_FRAME(8, 4),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_821643C[] =
+{
+ ANIMCMD_FRAME(8, 4),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_8216444[] =
+{
+ sSpriteAnim_8216414,
+ sSpriteAnim_821641C,
+ sSpriteAnim_8216424,
+ sSpriteAnim_821643C,
+};
+
+const struct SpriteSheet gUnknown_08339B38 =
+{
+ gBerryBlenderMarubatsuTiles, 0x200, 48888
+};
+
+const struct SpriteTemplate gUnknown_08339B40 =
+{
+ .tileTag = 48888,
+ .paletteTag = 46546,
+ .oam = &sOamData_821640C,
+ .anims = sSpriteAnimTable_8216444,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_8082F68
+};
+
+static const struct OamData sOamData_8216474 =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 0,
+ .tileNum = 0,
+ .priority = 1,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const union AnimCmd sSpriteAnim_821647C[] =
+{
+ ANIMCMD_FRAME(0, 3),
+ ANIMCMD_FRAME(1, 4),
+ ANIMCMD_FRAME(3, 5),
+ ANIMCMD_FRAME(1, 4),
+ ANIMCMD_FRAME(0, 3),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_8216494[] =
+{
+ ANIMCMD_FRAME(0, 3),
+ ANIMCMD_FRAME(2, 4),
+ ANIMCMD_FRAME(4, 5),
+ ANIMCMD_FRAME(2, 4),
+ ANIMCMD_FRAME(0, 3),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_82164AC[] =
+{
+ ANIMCMD_FRAME(0, 2),
+ ANIMCMD_FRAME(1, 2),
+ ANIMCMD_FRAME(2, 2),
+ ANIMCMD_FRAME(4, 4),
+ ANIMCMD_FRAME(3, 3),
+ ANIMCMD_FRAME(2, 2),
+ ANIMCMD_FRAME(1, 2),
+ ANIMCMD_FRAME(0, 2),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_82164D0[] =
+{
+ ANIMCMD_FRAME(5, 5, 1, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_82164D8[] =
+{
+ ANIMCMD_FRAME(6, 5, 1, 1),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_82164E0[] =
+{
+ sSpriteAnim_821647C,
+ sSpriteAnim_8216494,
+ sSpriteAnim_82164AC,
+ sSpriteAnim_82164D0,
+ sSpriteAnim_82164D8,
+};
+
+const struct SpriteSheet gUnknown_08339BD8 =
+{
+ gBerryBlenderParticlesTiles, 0xE0, 23456
+};
+
+const struct SpriteTemplate gUnknown_08339BE0 =
+{
+ .tileTag = 23456,
+ .paletteTag = 46546,
+ .oam = &sOamData_8216474,
+ .anims = sSpriteAnimTable_82164E0,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy
+};
+
+static const struct OamData sOamData_8216514 =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 2,
+ .tileNum = 0,
+ .priority = 1,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const union AnimCmd sSpriteAnim_821651C[] =
+{
+ ANIMCMD_FRAME(32, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_8216524[] =
+{
+ ANIMCMD_FRAME(16, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_821652C[] =
+{
+ ANIMCMD_FRAME(0, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_8216534[] =
+{
+ sSpriteAnim_821651C,
+ sSpriteAnim_8216524,
+ sSpriteAnim_821652C,
+};
+
+const struct SpriteSheet gUnknown_08339C24 =
+{
+ gBerryBlenderCountdownNumbersTiles, 0x600, 12345
+};
+
+const struct SpriteTemplate gUnknown_08339C2C =
+{
+ .tileTag = 12345,
+ .paletteTag = 46546,
+ .oam = &sOamData_8216514,
+ .anims = sSpriteAnimTable_8216534,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_8083010
+};
+
+static const struct OamData sOamData_8216560 =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 1,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 3,
+ .tileNum = 0,
+ .priority = 1,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const union AnimCmd sSpriteAnim_8216568[] =
+{
+ ANIMCMD_FRAME(0, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_8216570[] =
+{
+ sSpriteAnim_8216568,
+};
+
+const struct SpriteSheet gUnknown_08339C58 =
+{
+ gBerryBlenderStartTiles, 0x400, 12346
+};
+
+const struct SpriteTemplate gUnknown_08339C60 =
+{
+ .tileTag = 12346,
+ .paletteTag = 46546,
+ .oam = &sOamData_8216560,
+ .anims = sSpriteAnimTable_8216570,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80830C0
+};
+
+const s16 gUnknown_08339C78[][5] =
+{
+ {-10, 20, 10, 2, 1},
+ {250, 20, 10, -2, 1},
+ {-10, 140, 10, 2, -1},
+ {250, 140, 10, -2, -1},
+};
+
+const u8 gUnknown_08339CA0[][3] =
+{
+ {4, 3, 2}, {0, 4, 3}, {1, 0, 4}, {2, 1, 0}, {3, 2, 1}, {0, 2, 3}, {1, 3, 4}, {2, 4, 0}, {3, 0, 1}, {4, 1, 2},
+};
+
+const u8 gUnknown_08339CBE[] = {30, 31, 32, 33, 34};
+
+const u8 gUnknown_08339CC3[] = {1, 1, 2, 3, 4};
+
+const u8 gUnknown_08339CC8[] = {0x1C, 0x16, 0x13, 0x1A, 0x19, 0x0E, 0x0D, 0x0B, 0x07, 0x15};
+
+static const u8 gUnknown_08339CD2[] =
+{
+ 0xfe, 0x02, 0x02, 0xce, 0xd0, 0x37, 0x44, 0x07, 0x1f, 0x0c, 0x10,
+ 0x00, 0xff, 0xfe, 0x91, 0x72, 0xce, 0xd0, 0x37, 0x44, 0x07, 0x1f,
+ 0x0c, 0x10, 0x00, 0xff, 0x06, 0x27, 0x02, 0xff, 0x00, 0x0c, 0x48,
+ 0x02, 0xff, 0x00, 0x01, 0x1f, 0x02, 0xff, 0x00, 0x16, 0x37, 0x02,
+ 0xff, 0x00, 0x0d, 0x50, 0x4b, 0x02, 0xff, 0x06, 0x06, 0x06, 0x06,
+ 0x05, 0x03, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x02
+};
+
+const struct WindowTemplate gUnknown_08339D14[] = {0, 6, 4, 0x12, 0xB, 0xF, 8};
// .text
diff --git a/src/braille_puzzles.c b/src/braille_puzzles.c
index 9a6f0371c..85b2bc509 100755
--- a/src/braille_puzzles.c
+++ b/src/braille_puzzles.c
@@ -13,7 +13,7 @@ extern void DrawWholeMapView(); // field_camera
extern void SetCameraPanningCallback(void ( *callback)()); // field_camera
extern void InstallCameraPanAheadCallback(void);
extern void SetCameraPanning(s16 x, s16 y);
-extern u8 brm_get_pokemon_selection(void);
+extern u8 GetCursorSelectionMonId(void);
extern void FieldEffectActiveListRemove(u8 id); // field_effect
extern u8 oei_task_add(void);
@@ -33,7 +33,7 @@ void sub_8179944(void);
bool8 ShouldDoBrailleDigEffect(void)
{
- if (!FlagGet(SYS_BRAILLE_DIG)
+ if (!FlagGet(FLAG_SYS_BRAILLE_DIG)
&& (gSaveBlock1Ptr->location.mapGroup == 0x18
&& gSaveBlock1Ptr->location.mapNum == 0x47))
{
@@ -58,7 +58,7 @@ void DoBrailleDigEffect(void)
MapGridSetMetatileIdAt(18, 9, 3636);
DrawWholeMapView();
PlaySE(SE_BAN);
- FlagSet(SYS_BRAILLE_DIG);
+ FlagSet(FLAG_SYS_BRAILLE_DIG);
ScriptContext2_Disable();
}
@@ -81,7 +81,7 @@ bool8 CheckRelicanthWailord(void)
void ShouldDoBrailleStrengthEffectOld(void)
{
/*
- if (!FlagGet(SYS_BRAILLE_STRENGTH) && (gSaveBlock1.location.mapGroup == MAP_GROUP_DESERT_RUINS && gSaveBlock1.location.mapNum == MAP_ID_DESERT_RUINS))
+ if (!FlagGet(FLAG_SYS_BRAILLE_STRENGTH) && (gSaveBlock1.location.mapGroup == MAP_GROUP_DESERT_RUINS && gSaveBlock1.location.mapNum == MAP_ID_DESERT_RUINS))
{
if (gSaveBlock1.pos.x == 10 && gSaveBlock1.pos.y == 23)
return TRUE;
@@ -105,13 +105,13 @@ void DoBrailleStrengthEffect(void)
MapGridSetMetatileIdAt(16, 27, 3636);
DrawWholeMapView();
PlaySE(SE_BAN);
- FlagSet(SYS_BRAILLE_STRENGTH);
+ FlagSet(FLAG_SYS_BRAILLE_STRENGTH);
ScriptContext2_Disable();
}
bool8 ShouldDoBrailleFlyEffect(void)
{
- if (!FlagGet(SYS_BRAILLE_FLY) && (gSaveBlock1.location.mapGroup == MAP_GROUP_ANCIENT_TOMB && gSaveBlock1.location.mapNum == MAP_ID_ANCIENT_TOMB))
+ if (!FlagGet(FLAG_SYS_BRAILLE_FLY) && (gSaveBlock1.location.mapGroup == MAP_GROUP_ANCIENT_TOMB && gSaveBlock1.location.mapNum == MAP_ID_ANCIENT_TOMB))
{
if (gSaveBlock1.pos.x == 8 && gSaveBlock1.pos.y == 25)
return TRUE;
@@ -151,7 +151,7 @@ void UseFlyAncientTomb_Finish(void)
MapGridSetMetatileIdAt(16, 27, 3636);
DrawWholeMapView();
PlaySE(SE_BAN);
- FlagSet(SYS_BRAILLE_FLY);
+ FlagSet(FLAG_SYS_BRAILLE_FLY);
ScriptContext2_Disable();
}
*/
@@ -205,7 +205,7 @@ void SealedChamberShakingEffect(u8 taskId)
// moved later in the function because it was rewritten.
bool8 ShouldDoBrailleStrengthEffect(void)
{
- if (!FlagGet(SYS_BRAILLE_STRENGTH) && (gSaveBlock1Ptr->location.mapGroup == 0x18 && gSaveBlock1Ptr->location.mapNum == 0x06))
+ if (!FlagGet(FLAG_SYS_BRAILLE_STRENGTH) && (gSaveBlock1Ptr->location.mapGroup == 0x18 && gSaveBlock1Ptr->location.mapNum == 0x06))
{
if (gSaveBlock1Ptr->pos.x == 6 && gSaveBlock1Ptr->pos.y == 23)
{ gBraillePuzzleCallbackFlag = STRENGTH_PUZZLE; return TRUE; }
@@ -220,7 +220,7 @@ bool8 ShouldDoBrailleStrengthEffect(void)
void sub_8179834(void)
{
- gFieldEffectArguments[0] = brm_get_pokemon_selection();
+ gFieldEffectArguments[0] = GetCursorSelectionMonId();
FieldEffectStart(FLDEFF_USE_FLY_ANCIENT_TOMB);
}
@@ -240,13 +240,13 @@ void sub_8179860(void)
MapGridSetMetatileIdAt(16, 27, 3636);
DrawWholeMapView();
PlaySE(SE_BAN);
- FlagSet(SYS_BRAILLE_STRENGTH);
+ FlagSet(FLAG_SYS_BRAILLE_STRENGTH);
ScriptContext2_Disable();
}
bool8 ShouldDoBrailleFlyEffect(void)
{
- if (!FlagGet(SYS_BRAILLE_FLY) && (gSaveBlock1Ptr->location.mapGroup == 0x18 && gSaveBlock1Ptr->location.mapNum == 0x44))
+ if (!FlagGet(FLAG_SYS_BRAILLE_FLY) && (gSaveBlock1Ptr->location.mapGroup == 0x18 && gSaveBlock1Ptr->location.mapNum == 0x44))
{
if (gSaveBlock1Ptr->pos.x == 8 && gSaveBlock1Ptr->pos.y == 25)
{ gBraillePuzzleCallbackFlag = FLY_PUZZLE; return TRUE; }
@@ -256,7 +256,7 @@ bool8 ShouldDoBrailleFlyEffect(void)
void sub_8179918(void)
{
- gFieldEffectArguments[0] = brm_get_pokemon_selection();
+ gFieldEffectArguments[0] = GetCursorSelectionMonId();
FieldEffectStart(FLDEFF_USE_FLY_ANCIENT_TOMB);
}
@@ -276,7 +276,7 @@ void sub_8179944(void)
MapGridSetMetatileIdAt(16, 27, 3636);
DrawWholeMapView();
PlaySE(SE_BAN);
- FlagSet(SYS_BRAILLE_FLY);
+ FlagSet(FLAG_SYS_BRAILLE_FLY);
ScriptContext2_Disable();
}
@@ -284,7 +284,7 @@ void sub_8179944(void)
void DoBrailleWait(void)
{
/*
- if (!FlagGet(SYS_BRAILLE_WAIT))
+ if (!FlagGet(FLAG_SYS_BRAILLE_WAIT))
CreateTask(Task_BrailleWait, 0x50);
}
@@ -387,7 +387,7 @@ bool8 ShouldDoBrailleRegicePuzzle(void)
if (gSaveBlock1Ptr->location.mapGroup == 0x18 && gSaveBlock1Ptr->location.mapNum == 0x43)
{
// _08179A1A
- if (FlagGet(SYS_BRAILLE_WAIT) != FALSE)
+ if (FlagGet(FLAG_SYS_BRAILLE_WAIT) != FALSE)
return FALSE;
if (FlagGet(2) == FALSE)
return FALSE;
diff --git a/src/calculate_base_damage.c b/src/calculate_base_damage.c
index 8996059f9..89770b17a 100644
--- a/src/calculate_base_damage.c
+++ b/src/calculate_base_damage.c
@@ -84,13 +84,13 @@ s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *de
if (attacker->ability == ABILITY_HUGE_POWER || attacker->ability == ABILITY_PURE_POWER)
attack *= 2;
- if (ShouldGetStatBadgeBoost(BADGE01_GET, bankAtk))
+ if (ShouldGetStatBadgeBoost(FLAG_BADGE01_GET, bankAtk))
attack = (110 * attack) / 100;
- if (ShouldGetStatBadgeBoost(BADGE05_GET, bankDef))
+ if (ShouldGetStatBadgeBoost(FLAG_BADGE05_GET, bankDef))
defense = (110 * defense) / 100;
- if (ShouldGetStatBadgeBoost(BADGE07_GET, bankAtk))
+ if (ShouldGetStatBadgeBoost(FLAG_BADGE07_GET, bankAtk))
spAttack = (110 * spAttack) / 100;
- if (ShouldGetStatBadgeBoost(BADGE07_GET, bankDef))
+ if (ShouldGetStatBadgeBoost(FLAG_BADGE07_GET, bankDef))
spDefense = (110 * spDefense) / 100;
for (i = 0; i < 17; i++)
diff --git a/src/daycare.c b/src/daycare.c
new file mode 100644
index 000000000..8dd45863a
--- /dev/null
+++ b/src/daycare.c
@@ -0,0 +1,1318 @@
+#include "global.h"
+#include "pokemon.h"
+#include "daycare.h"
+#include "string_util.h"
+#include "species.h"
+#include "items.h"
+#include "mail.h"
+#include "pokemon_storage_system.h"
+#include "event_data.h"
+#include "rng.h"
+#include "main.h"
+#include "moves.h"
+#include "egg_hatch.h"
+#include "text.h"
+#include "menu.h"
+#include "international_string_util.h"
+#include "script.h"
+#include "task.h"
+#include "window.h"
+#include "list_menu.h"
+
+#define EGG_MOVES_ARRAY_COUNT 10
+#define EGG_LVL_UP_MOVES_ARRAY_COUNT 50
+
+extern u16 gMoveToLearn;
+
+// text
+extern const u8 gText_MaleSymbol4[];
+extern const u8 gText_FemaleSymbol4[];
+extern const u8 gText_GenderlessSymbol[];
+extern const u8 gText_NewLine2[];
+extern const u8 gText_Exit4[];
+extern const u8 gText_Lv[];
+extern const u8 gExpandedPlaceholder_Empty[];
+extern const u8 gText_Exit[];
+extern const u8 gDaycareText_GetAlongVeryWell[];
+extern const u8 gDaycareText_GetAlong[];
+extern const u8 gDaycareText_DontLikeOther[];
+extern const u8 gDaycareText_PlayOther[];
+
+extern u8 GetCursorSelectionMonId(void);
+extern u16 ItemIdToBattleMoveId(u16);
+extern s32 ListMenuHandleInput(u8);
+extern void sub_81AE6C8(u8, u16*, u16*);
+extern void sub_819746C(u8, bool8);
+extern void sub_81973FC(u8, bool8);
+extern void sub_81B9328(void);
+extern void sub_81AF078(u32, bool8, struct ListMenu *);
+extern void c2_exit_to_overworld_2_switch(void);
+
+// this file's functions
+static void ClearDaycareMonMisc(struct DaycareMiscMon *misc);
+static void SetInitialEggData(struct Pokemon *mon, u16 species, struct DayCare *daycare);
+static u8 GetDaycareCompatibilityScore(struct DayCare *daycare);
+static void DaycarePrintMonInfo(u8 windowId, s32 daycareSlotId, u8 y);
+
+// RAM buffers used to assist with BuildEggMoveset()
+EWRAM_DATA static u16 sHatchedEggLevelUpMoves[EGG_LVL_UP_MOVES_ARRAY_COUNT] = {0};
+EWRAM_DATA static u16 sHatchedEggFatherMoves[4] = {0};
+EWRAM_DATA static u16 sHatchedEggFinalMoves[4] = {0};
+EWRAM_DATA static u16 sHatchedEggEggMoves[EGG_MOVES_ARRAY_COUNT] = {0};
+EWRAM_DATA static u16 sHatchedEggMotherMoves[4] = {0};
+
+#include "data/pokemon/egg_moves.h"
+
+static const struct WindowTemplate sDaycareLevelMenuWindowTemplate = {0, 0xF, 1, 0xE, 6, 0xF, 8};
+
+static const struct ListMenuItem sLevelMenuItems[] =
+{
+ {gExpandedPlaceholder_Empty, 0},
+ {gExpandedPlaceholder_Empty, 1},
+ {gText_Exit, 5}
+};
+
+static const struct ListMenuTemplate sDaycareListMenuLevelTemplate =
+{
+ .items = sLevelMenuItems,
+ .unk_04 = sub_81AF078,
+ .unk_08 = DaycarePrintMonInfo,
+ .totalItems = 3,
+ .maxShowed = 3,
+ .unk_10 = 0,
+ .unk_11 = 0,
+ .unk_12 = 8,
+ .cursor_Y = 0,
+ .upText_Y = 1,
+ .cursorColor = 2,
+ .fillColor = 1,
+ .cursorShadowColor = 3,
+ .unk_16_0 = TRUE,
+ .spaceBetweenItems = 0,
+ .unk_16_7 = FALSE,
+ .unk_17_0 = 1
+};
+
+static const u8 *const sCompatibilityMessages[] =
+{
+ gDaycareText_GetAlongVeryWell,
+ gDaycareText_GetAlong,
+ gDaycareText_DontLikeOther,
+ gDaycareText_PlayOther
+};
+
+static const u8 sJapaneseEggNickname[] = _("タマゴ"); // "tamago" ("egg" in Japanese)
+
+u8 *GetMonNick(struct Pokemon *mon, u8 *dest)
+{
+ u8 nickname[POKEMON_NAME_LENGTH * 2];
+
+ GetMonData(mon, MON_DATA_NICKNAME, nickname);
+ return StringCopy10(dest, nickname);
+}
+
+u8 *GetBoxMonNick(struct BoxPokemon *mon, u8 *dest)
+{
+ u8 nickname[POKEMON_NAME_LENGTH * 2];
+
+ GetBoxMonData(mon, MON_DATA_NICKNAME, nickname);
+ return StringCopy10(dest, nickname);
+}
+
+u8 CountPokemonInDaycare(struct DayCare *daycare)
+{
+ u8 i, count;
+ count = 0;
+
+ for (i = 0; i < DAYCARE_MON_COUNT; i++)
+ {
+ if (GetBoxMonData(&daycare->mons[i].mon, MON_DATA_SPECIES) != 0)
+ count++;
+ }
+
+ return count;
+}
+
+void InitDaycareMailRecordMixing(struct DayCare *daycare, struct RecordMixingDayCareMail *daycareMail)
+{
+ u8 i;
+ u8 numDaycareMons = 0;
+
+ for (i = 0; i < DAYCARE_MON_COUNT; i++)
+ {
+ if (GetBoxMonData(&daycare->mons[i].mon, MON_DATA_SPECIES) != SPECIES_NONE)
+ {
+ numDaycareMons++;
+ if (GetBoxMonData(&daycare->mons[i].mon, MON_DATA_HELD_ITEM) == ITEM_NONE)
+ {
+ daycareMail->holdsItem[i] = FALSE;
+ }
+ else
+ {
+ daycareMail->holdsItem[i] = TRUE;
+ }
+ }
+ else
+ {
+ daycareMail->holdsItem[i] = TRUE;
+ }
+ }
+
+ daycareMail->numDaycareMons = numDaycareMons;
+}
+
+static s8 Daycare_FindEmptySpot(struct DayCare *daycare)
+{
+ u8 i;
+
+ for (i = 0; i < DAYCARE_MON_COUNT; i++)
+ {
+ if (GetBoxMonData(&daycare->mons[i].mon, MON_DATA_SPECIES) == 0)
+ return i;
+ }
+
+ return -1;
+}
+
+static void StorePokemonInDaycare(struct Pokemon *mon, struct DaycareMon *daycareMon)
+{
+ if (MonHasMail(mon))
+ {
+ u8 mailId;
+
+ StringCopy(daycareMon->misc.OT_name, gSaveBlock2Ptr->playerName);
+ GetMonNick(mon, daycareMon->misc.monName);
+ StripExtCtrlCodes(daycareMon->misc.monName);
+ daycareMon->misc.gameLanguage = LANGUAGE_ENGLISH;
+ daycareMon->misc.monLanguage = GetMonData(mon, MON_DATA_LANGUAGE);
+ mailId = GetMonData(mon, MON_DATA_MAIL);
+ daycareMon->misc.mail = gSaveBlock1Ptr->mail[mailId];
+ TakeMailFromMon(mon);
+ }
+
+ daycareMon->mon = mon->box;
+ BoxMonRestorePP(&daycareMon->mon);
+ daycareMon->steps = 0;
+ ZeroMonData(mon);
+ CompactPartySlots();
+ CalculatePlayerPartyCount();
+}
+
+static void StorePokemonInEmptyDaycareSlot(struct Pokemon *mon, struct DayCare *daycare)
+{
+ s8 slotId = Daycare_FindEmptySpot(daycare);
+ StorePokemonInDaycare(mon, &daycare->mons[slotId]);
+}
+
+void StoreSelectedPokemonInDaycare(void)
+{
+ u8 monId = GetCursorSelectionMonId();
+ StorePokemonInEmptyDaycareSlot(&gPlayerParty[monId], &gSaveBlock1Ptr->daycare);
+}
+
+// Shifts the second daycare pokemon slot into the first slot.
+static void ShiftDaycareSlots(struct DayCare *daycare)
+{
+ // This condition is only satisfied when the player takes out the first pokemon from the daycare.
+ if (GetBoxMonData(&daycare->mons[1].mon, MON_DATA_SPECIES) != 0
+ && GetBoxMonData(&daycare->mons[0].mon, MON_DATA_SPECIES) == 0)
+ {
+ daycare->mons[0].mon = daycare->mons[1].mon;
+ ZeroBoxMonData(&daycare->mons[1].mon);
+
+ daycare->mons[0].misc = daycare->mons[1].misc;
+ daycare->mons[0].steps = daycare->mons[1].steps;
+ daycare->mons[1].steps = 0;
+ ClearDaycareMonMisc(&daycare->mons[1].misc);
+ }
+}
+
+static void ApplyDaycareExperience(struct Pokemon *mon)
+{
+ s32 i;
+ bool8 firstMove;
+ u16 learnedMove;
+
+ for (i = 0; i < MAX_MON_LEVEL; i++)
+ {
+ // Add the mon's gained daycare experience level by level until it can't level up anymore.
+ if (TryIncrementMonLevel(mon))
+ {
+ // Teach the mon new moves it learned while in the daycare.
+ firstMove = TRUE;
+ while ((learnedMove = MonTryLearningNewMove(mon, firstMove)) != 0)
+ {
+ firstMove = FALSE;
+ if (learnedMove == 0xFFFF)
+ {
+ // Mon already knows 4 moves.
+ DeleteFirstMoveAndGiveMoveToMon(mon, gMoveToLearn);
+ }
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ // Re-calculate the mons stats at its new level.
+ CalculateMonStats(mon);
+}
+
+static u16 TakeSelectedPokemonFromDaycare(struct DaycareMon *daycareMon)
+{
+ u16 species;
+ u32 experience;
+ struct Pokemon pokemon;
+
+ GetBoxMonNick(&daycareMon->mon, gStringVar1);
+ species = GetBoxMonData(&daycareMon->mon, MON_DATA_SPECIES);
+ BoxMonToMon(&daycareMon->mon, &pokemon);
+
+ if (GetMonData(&pokemon, MON_DATA_LEVEL) != MAX_MON_LEVEL)
+ {
+ experience = GetMonData(&pokemon, MON_DATA_EXP) + daycareMon->steps;
+ SetMonData(&pokemon, MON_DATA_EXP, &experience);
+ ApplyDaycareExperience(&pokemon);
+ }
+
+ gPlayerParty[PARTY_SIZE - 1] = pokemon;
+ if (daycareMon->misc.mail.itemId)
+ {
+ GiveMailToMon2(&gPlayerParty[PARTY_SIZE - 1], &daycareMon->misc.mail);
+ ClearDaycareMonMisc(&daycareMon->misc);
+ }
+
+ ZeroBoxMonData(&daycareMon->mon);
+ daycareMon->steps = 0;
+ CompactPartySlots();
+ CalculatePlayerPartyCount();
+ return species;
+}
+
+static u16 TakeSelectedPokemonMonFromDaycareShiftSlots(struct DayCare *daycare, u8 slotId)
+{
+ u16 species = TakeSelectedPokemonFromDaycare(&daycare->mons[slotId]);
+ ShiftDaycareSlots(daycare);
+ return species;
+}
+
+u16 TakePokemonFromDaycare(void)
+{
+ return TakeSelectedPokemonMonFromDaycareShiftSlots(&gSaveBlock1Ptr->daycare, gSpecialVar_0x8004);
+}
+
+static u8 GetLevelAfterDaycareSteps(struct BoxPokemon *mon, u32 steps)
+{
+ struct BoxPokemon tempMon = *mon;
+
+ u32 experience = GetBoxMonData(mon, MON_DATA_EXP) + steps;
+ SetBoxMonData(&tempMon, MON_DATA_EXP, &experience);
+ return GetLevelFromBoxMonExp(&tempMon);
+}
+
+static u8 GetNumLevelsGainedFromSteps(struct DaycareMon *daycareMon)
+{
+ u8 levelBefore;
+ u8 levelAfter;
+
+ levelBefore = GetLevelFromBoxMonExp(&daycareMon->mon);
+ levelAfter = GetLevelAfterDaycareSteps(&daycareMon->mon, daycareMon->steps);
+ return levelAfter - levelBefore;
+}
+
+static u8 GetNumLevelsGainedForDaycareMon(struct DaycareMon *daycareMon)
+{
+ u8 numLevelsGained = GetNumLevelsGainedFromSteps(daycareMon);
+ ConvertIntToDecimalStringN(gStringVar2, numLevelsGained, STR_CONV_MODE_LEFT_ALIGN, 2);
+ GetBoxMonNick(&daycareMon->mon, gStringVar1);
+ return numLevelsGained;
+}
+
+static u32 GetDaycareCostForSelectedMon(struct DaycareMon *daycareMon)
+{
+ u32 cost;
+
+ u8 numLevelsGained = GetNumLevelsGainedFromSteps(daycareMon);
+ GetBoxMonNick(&daycareMon->mon, gStringVar1);
+ cost = 100 + 100 * numLevelsGained;
+ ConvertIntToDecimalStringN(gStringVar2, cost, STR_CONV_MODE_LEFT_ALIGN, 5);
+ return cost;
+}
+
+static u16 GetDaycareCostForMon(struct DayCare *daycare, u8 slotId)
+{
+ return GetDaycareCostForSelectedMon(&daycare->mons[slotId]);
+}
+
+void GetDaycareCost(void)
+{
+ gSpecialVar_0x8005 = GetDaycareCostForMon(&gSaveBlock1Ptr->daycare, gSpecialVar_0x8004);
+}
+
+static void Debug_AddDaycareSteps(u16 numSteps)
+{
+ gSaveBlock1Ptr->daycare.mons[0].steps += numSteps;
+ gSaveBlock1Ptr->daycare.mons[1].steps += numSteps;
+}
+
+u8 GetNumLevelsGainedFromDaycare(void)
+{
+ if (GetBoxMonData(&gSaveBlock1Ptr->daycare.mons[gSpecialVar_0x8004], MON_DATA_SPECIES) != 0)
+ return GetNumLevelsGainedForDaycareMon(&gSaveBlock1Ptr->daycare.mons[gSpecialVar_0x8004]);
+
+ return 0;
+}
+
+static void ClearDaycareMonMisc(struct DaycareMiscMon *misc)
+{
+ s32 i;
+
+ for (i = 0; i < OT_NAME_LENGTH + 1; i++)
+ misc->OT_name[i] = 0;
+ for (i = 0; i < POKEMON_NAME_LENGTH + 1; i++)
+ misc->monName[i] = 0;
+
+ ClearMailStruct(&misc->mail);
+}
+
+static void ClearDaycareMon(struct DaycareMon *daycareMon)
+{
+ ZeroBoxMonData(&daycareMon->mon);
+ daycareMon->steps = 0;
+ ClearDaycareMonMisc(&daycareMon->misc);
+}
+
+static void ClearAllDaycareData(struct DayCare *daycare)
+{
+ u8 i;
+
+ for (i = 0; i < DAYCARE_MON_COUNT; i++)
+ ClearDaycareMon(&daycare->mons[i]);
+
+ daycare->offspringPersonality = 0;
+ daycare->stepCounter = 0;
+}
+
+// Determines what the species of an Egg would be based on the given species.
+// It determines this by working backwards through the evolution chain of the
+// given species.
+static u16 GetEggSpecies(u16 species)
+{
+ int i, j, k;
+ bool8 found;
+
+ // Working backwards up to 5 times seems arbitrary, since the maximum number
+ // of times would only be 3 for 3-stage evolutions.
+ for (i = 0; i < EVOS_PER_MON; i++)
+ {
+ found = FALSE;
+ for (j = 1; j < NUM_SPECIES; j++)
+ {
+ for (k = 0; k < EVOS_PER_MON; k++)
+ {
+ if (gEvolutionTable[j].evolutions[k].targetSpecies == species)
+ {
+ species = j;
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (found)
+ break;
+ }
+
+ if (j == NUM_SPECIES)
+ break;
+ }
+
+ return species;
+}
+
+static s32 GetSlotToInheritNature(struct DayCare *daycare)
+{
+ u32 species[DAYCARE_MON_COUNT];
+ s32 i;
+ s32 dittoCount;
+ s32 slot = -1;
+
+ // search for female gender
+ for (i = 0; i < DAYCARE_MON_COUNT; i++)
+ {
+ if (GetBoxMonGender(&daycare->mons[i].mon) == MON_FEMALE)
+ slot = i;
+ }
+
+ // search for ditto
+ for (dittoCount = 0, i = 0; i < DAYCARE_MON_COUNT; i++)
+ {
+ species[i] = GetBoxMonData(&daycare->mons[i].mon, MON_DATA_SPECIES);
+ if (species[i] == SPECIES_DITTO)
+ dittoCount++, slot = i;
+ }
+
+ // coin flip on ...two Dittos
+ if (dittoCount == 2)
+ {
+ if (Random() >= USHRT_MAX / 2)
+ slot = 0;
+ else
+ slot = 1;
+ }
+
+ // nature inheritance only if holds everstone
+ if (GetBoxMonData(&daycare->mons[slot].mon, MON_DATA_HELD_ITEM) != ITEM_EVERSTONE
+ || Random() >= USHRT_MAX / 2)
+ {
+ return -1;
+ }
+
+ return slot;
+}
+
+static void _TriggerPendingDaycareEgg(struct DayCare *daycare)
+{
+ s32 natureSlot;
+ s32 natureTries = 0;
+
+ SeedRng2(gMain.vblankCounter2);
+ natureSlot = GetSlotToInheritNature(daycare);
+
+ if (natureSlot < 0)
+ {
+ daycare->offspringPersonality = (Random2() << 0x10) | ((Random() % 0xfffe) + 1);
+ }
+ else
+ {
+ u8 wantedNature = GetNatureFromPersonality(GetBoxMonData(&daycare->mons[natureSlot].mon, MON_DATA_PERSONALITY, NULL));
+ u32 personality;
+
+ do
+ {
+ personality = (Random2() << 0x10) | (Random());
+ if (wantedNature == GetNatureFromPersonality(personality) && personality != 0)
+ break; // we found a personality with the same nature
+
+ natureTries++;
+ } while (natureTries <= 2400);
+
+ daycare->offspringPersonality = personality;
+ }
+
+ FlagSet(FLAG_PENDING_DAYCARE_EGG);
+}
+
+static void _TriggerPendingDaycareMaleEgg(struct DayCare *daycare)
+{
+ daycare->offspringPersonality = (Random()) | (0x8000);
+ FlagSet(FLAG_PENDING_DAYCARE_EGG);
+}
+
+void TriggerPendingDaycareEgg(void)
+{
+ _TriggerPendingDaycareEgg(&gSaveBlock1Ptr->daycare);
+}
+
+static void TriggerPendingDaycareMaleEgg(void)
+{
+ _TriggerPendingDaycareMaleEgg(&gSaveBlock1Ptr->daycare);
+}
+
+// Removes the selected index from the given IV list and shifts the remaining
+// elements to the left.
+static void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv)
+{
+ s32 i, j;
+ u8 temp[NUM_STATS];
+
+ ivs[selectedIv] = 0xff;
+ for (i = 0; i < NUM_STATS; i++)
+ {
+ temp[i] = ivs[i];
+ }
+
+ j = 0;
+ for (i = 0; i < NUM_STATS; i++)
+ {
+ if (temp[i] != 0xff)
+ ivs[j++] = temp[i];
+ }
+}
+
+static void InheritIVs(struct Pokemon *egg, struct DayCare *daycare)
+{
+ u8 i;
+ u8 selectedIvs[3];
+ u8 availableIVs[NUM_STATS];
+ u8 whichParent[ARRAY_COUNT(selectedIvs)];
+ u8 iv;
+
+ // Initialize a list of IV indices.
+ for (i = 0; i < NUM_STATS; i++)
+ {
+ availableIVs[i] = i;
+ }
+
+ // Select the 3 IVs that will be inherited.
+ for (i = 0; i < ARRAY_COUNT(selectedIvs); i++)
+ {
+ // Randomly pick an IV from the available list.
+ selectedIvs[i] = availableIVs[Random() % (NUM_STATS - i)];
+
+ // Remove the selected IV index from the available IV indices.
+ RemoveIVIndexFromList(availableIVs, i);
+ }
+
+ // Determine which parent each of the selected IVs should inherit from.
+ for (i = 0; i < ARRAY_COUNT(selectedIvs); i++)
+ {
+ whichParent[i] = Random() % 2;
+ }
+
+ // Set each of inherited IVs on the egg mon.
+ for (i = 0; i < ARRAY_COUNT(selectedIvs); i++)
+ {
+ switch (selectedIvs[i])
+ {
+ case 0:
+ iv = GetBoxMonData(&daycare->mons[whichParent[i]].mon, MON_DATA_HP_IV);
+ SetMonData(egg, MON_DATA_HP_IV, &iv);
+ break;
+ case 1:
+ iv = GetBoxMonData(&daycare->mons[whichParent[i]].mon, MON_DATA_ATK_IV);
+ SetMonData(egg, MON_DATA_ATK_IV, &iv);
+ break;
+ case 2:
+ iv = GetBoxMonData(&daycare->mons[whichParent[i]].mon, MON_DATA_DEF_IV);
+ SetMonData(egg, MON_DATA_DEF_IV, &iv);
+ break;
+ case 3:
+ iv = GetBoxMonData(&daycare->mons[whichParent[i]].mon, MON_DATA_SPEED_IV);
+ SetMonData(egg, MON_DATA_SPEED_IV, &iv);
+ break;
+ case 4:
+ iv = GetBoxMonData(&daycare->mons[whichParent[i]].mon, MON_DATA_SPATK_IV);
+ SetMonData(egg, MON_DATA_SPATK_IV, &iv);
+ break;
+ case 5:
+ iv = GetBoxMonData(&daycare->mons[whichParent[i]].mon, MON_DATA_SPDEF_IV);
+ SetMonData(egg, MON_DATA_SPDEF_IV, &iv);
+ break;
+ }
+ }
+}
+
+// Counts the number of egg moves a pokemon learns and stores the moves in
+// the given array.
+static u8 GetEggMoves(struct Pokemon *pokemon, u16 *eggMoves)
+{
+ u16 eggMoveIdx;
+ u16 numEggMoves;
+ u16 species;
+ u16 i;
+
+ numEggMoves = 0;
+ eggMoveIdx = 0;
+ species = GetMonData(pokemon, MON_DATA_SPECIES);
+ for (i = 0; i < ARRAY_COUNT(gEggMoves) - 1; i++)
+ {
+ if (gEggMoves[i] == species + EGG_MOVES_SPECIES_OFFSET)
+ {
+ eggMoveIdx = i + 1;
+ break;
+ }
+ }
+
+ for (i = 0; i < EGG_MOVES_ARRAY_COUNT; i++)
+ {
+ if (gEggMoves[eggMoveIdx + i] > EGG_MOVES_SPECIES_OFFSET)
+ {
+ // TODO: the curly braces around this if statement are required for a matching build.
+ break;
+ }
+
+ eggMoves[i] = gEggMoves[eggMoveIdx + i];
+ numEggMoves++;
+ }
+
+ return numEggMoves;
+}
+
+static void BuildEggMoveset(struct Pokemon *egg, struct BoxPokemon *father, struct BoxPokemon *mother)
+{
+ u16 numSharedParentMoves;
+ u32 numLevelUpMoves;
+ u16 numEggMoves;
+ u16 i, j;
+
+ numSharedParentMoves = 0;
+ for (i = 0; i < 4; i++)
+ {
+ sHatchedEggMotherMoves[i] = 0;
+ sHatchedEggFatherMoves[i] = 0;
+ sHatchedEggFinalMoves[i] = 0;
+ }
+ for (i = 0; i < EGG_MOVES_ARRAY_COUNT; i++)
+ sHatchedEggEggMoves[i] = 0;
+ for (i = 0; i < EGG_LVL_UP_MOVES_ARRAY_COUNT; i++)
+ sHatchedEggLevelUpMoves[i] = 0;
+
+ numLevelUpMoves = GetLevelUpMovesBySpecies(GetMonData(egg, MON_DATA_SPECIES), sHatchedEggLevelUpMoves);
+ for (i = 0; i < 4; i++)
+ {
+ sHatchedEggFatherMoves[i] = GetBoxMonData(father, MON_DATA_MOVE1 + i);
+ sHatchedEggMotherMoves[i] = GetBoxMonData(mother, MON_DATA_MOVE1 + i);
+ }
+
+ numEggMoves = GetEggMoves(egg, sHatchedEggEggMoves);
+
+ for (i = 0; i < 4; i++)
+ {
+ if (sHatchedEggFatherMoves[i] != MOVE_NONE)
+ {
+ for (j = 0; j < numEggMoves; j++)
+ {
+ if (sHatchedEggFatherMoves[i] == sHatchedEggEggMoves[j])
+ {
+ if (GiveMoveToMon(egg, sHatchedEggFatherMoves[i]) == 0xffff)
+ DeleteFirstMoveAndGiveMoveToMon(egg, sHatchedEggFatherMoves[i]);
+ break;
+ }
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ for (i = 0; i < 4; i++)
+ {
+ if (sHatchedEggFatherMoves[i] != MOVE_NONE)
+ {
+ for (j = 0; j < NUM_TECHNICAL_MACHINES + NUM_HIDDEN_MACHINES; j++)
+ {
+ if (sHatchedEggFatherMoves[i] == ItemIdToBattleMoveId(ITEM_TM01 + j) && CanMonLearnTMHM(egg, j))
+ {
+ if (GiveMoveToMon(egg, sHatchedEggFatherMoves[i]) == 0xffff)
+ DeleteFirstMoveAndGiveMoveToMon(egg, sHatchedEggFatherMoves[i]);
+ }
+ }
+ }
+ }
+ for (i = 0; i < 4; i++)
+ {
+ if (sHatchedEggFatherMoves[i] == MOVE_NONE)
+ break;
+ for (j = 0; j < 4; j++)
+ {
+ if (sHatchedEggFatherMoves[i] == sHatchedEggMotherMoves[j] && sHatchedEggFatherMoves[i] != MOVE_NONE)
+ sHatchedEggFinalMoves[numSharedParentMoves++] = sHatchedEggFatherMoves[i];
+ }
+ }
+
+ for (i = 0; i < 4; i++)
+ {
+ if (sHatchedEggFinalMoves[i] == MOVE_NONE)
+ break;
+ for (j = 0; j < numLevelUpMoves; j++)
+ {
+ if (sHatchedEggLevelUpMoves[j] != MOVE_NONE && sHatchedEggFinalMoves[i] == sHatchedEggLevelUpMoves[j])
+ {
+ if (GiveMoveToMon(egg, sHatchedEggFinalMoves[i]) == 0xffff)
+ DeleteFirstMoveAndGiveMoveToMon(egg, sHatchedEggFinalMoves[i]);
+ break;
+ }
+ }
+ }
+}
+
+static void RemoveEggFromDayCare(struct DayCare *daycare)
+{
+ daycare->offspringPersonality = 0;
+ daycare->stepCounter = 0;
+}
+
+void RejectEggFromDayCare(void)
+{
+ RemoveEggFromDayCare(&gSaveBlock1Ptr->daycare);
+}
+
+static void AlterEggSpeciesWithIncenseItem(u16 *species, struct DayCare *daycare)
+{
+ u16 motherItem, fatherItem;
+ if (*species == SPECIES_WYNAUT || *species == SPECIES_AZURILL)
+ {
+ motherItem = GetBoxMonData(&daycare->mons[0].mon, MON_DATA_HELD_ITEM);
+ fatherItem = GetBoxMonData(&daycare->mons[1].mon, MON_DATA_HELD_ITEM);
+ if (*species == SPECIES_WYNAUT && motherItem != ITEM_LAX_INCENSE && fatherItem != ITEM_LAX_INCENSE)
+ {
+ *species = SPECIES_WOBBUFFET;
+ }
+
+ if (*species == SPECIES_AZURILL && motherItem != ITEM_SEA_INCENSE && fatherItem != ITEM_SEA_INCENSE)
+ {
+ *species = SPECIES_MARILL;
+ }
+ }
+}
+
+static void GiveVoltTackleIfLightBall(struct Pokemon *mon, struct DayCare *daycare)
+{
+ u32 motherItem = GetBoxMonData(&daycare->mons[0].mon, MON_DATA_HELD_ITEM);
+ u32 fatherItem = GetBoxMonData(&daycare->mons[1].mon, MON_DATA_HELD_ITEM);
+
+ if (motherItem == ITEM_LIGHT_BALL || fatherItem == ITEM_LIGHT_BALL)
+ {
+ if (GiveMoveToMon(mon, MOVE_VOLT_TACKLE) == 0xFFFF)
+ DeleteFirstMoveAndGiveMoveToMon(mon, MOVE_VOLT_TACKLE);
+ }
+}
+
+static u16 DetermineEggSpeciesAndParentSlots(struct DayCare *daycare, u8 *parentSlots)
+{
+ u16 i;
+ u16 species[2];
+ u16 eggSpecies;
+
+ // Determine which of the daycare mons is the mother and father of the egg.
+ // The 0th index of the parentSlots array is considered the mother slot, and the
+ // 1st index is the father slot.
+ for (i = 0; i < 2; i++)
+ {
+ species[i] = GetBoxMonData(&daycare->mons[i].mon, MON_DATA_SPECIES);
+ if (species[i] == SPECIES_DITTO)
+ {
+ parentSlots[0] = i ^ 1;
+ parentSlots[1] = i;
+ }
+ else if (GetBoxMonGender(&daycare->mons[i].mon) == MON_FEMALE)
+ {
+ parentSlots[0] = i;
+ parentSlots[1] = i ^ 1;
+ }
+ }
+
+ eggSpecies = GetEggSpecies(species[parentSlots[0]]);
+ if (eggSpecies == SPECIES_NIDORAN_F && daycare->offspringPersonality & 0x8000)
+ {
+ eggSpecies = SPECIES_NIDORAN_M;
+ }
+ if (eggSpecies == SPECIES_ILLUMISE && daycare->offspringPersonality & 0x8000)
+ {
+ eggSpecies = SPECIES_VOLBEAT;
+ }
+
+ // Make Ditto the "mother" slot if the other daycare mon is male.
+ if (species[parentSlots[1]] == SPECIES_DITTO && GetBoxMonGender(&daycare->mons[parentSlots[0]].mon) != MON_FEMALE)
+ {
+ u8 temp = parentSlots[1];
+ parentSlots[1] = parentSlots[0];
+ parentSlots[0] = temp;
+ }
+
+ return eggSpecies;
+}
+
+static void _GiveEggFromDaycare(struct DayCare *daycare) // give_egg
+{
+ struct Pokemon egg;
+ u16 species;
+ u8 parentSlots[2]; // 0th index is "mother" daycare slot, 1st is "father"
+ bool8 isEgg;
+
+ species = DetermineEggSpeciesAndParentSlots(daycare, parentSlots);
+ AlterEggSpeciesWithIncenseItem(&species, daycare);
+ SetInitialEggData(&egg, species, daycare);
+ InheritIVs(&egg, daycare);
+ BuildEggMoveset(&egg, &daycare->mons[parentSlots[1]].mon, &daycare->mons[parentSlots[0]].mon);
+
+ if (species == SPECIES_PICHU)
+ GiveVoltTackleIfLightBall(&egg, daycare);
+
+ isEgg = TRUE;
+ SetMonData(&egg, MON_DATA_IS_EGG, &isEgg);
+ gPlayerParty[PARTY_SIZE - 1] = egg;
+ CompactPartySlots();
+ CalculatePlayerPartyCount();
+ RemoveEggFromDayCare(daycare);
+}
+
+void CreateEgg(struct Pokemon *mon, u16 species, bool8 setHotSpringsLocation)
+{
+ u8 metLevel;
+ u16 ball;
+ u8 language;
+ u8 metLocation;
+ u8 isEgg;
+
+ CreateMon(mon, species, EGG_HATCH_LEVEL, 0x20, FALSE, 0, FALSE, 0);
+ metLevel = 0;
+ ball = ITEM_POKE_BALL;
+ language = LANGUAGE_JAPANESE;
+ SetMonData(mon, MON_DATA_POKEBALL, &ball);
+ SetMonData(mon, MON_DATA_NICKNAME, sJapaneseEggNickname);
+ SetMonData(mon, MON_DATA_FRIENDSHIP, &gBaseStats[species].eggCycles);
+ SetMonData(mon, MON_DATA_MET_LEVEL, &metLevel);
+ SetMonData(mon, MON_DATA_LANGUAGE, &language);
+ if (setHotSpringsLocation)
+ {
+ metLocation = 253; // hot springs; see PokemonSummaryScreen_PrintEggTrainerMemo
+ SetMonData(mon, MON_DATA_MET_LOCATION, &metLocation);
+ }
+
+ isEgg = TRUE;
+ SetMonData(mon, MON_DATA_IS_EGG, &isEgg);
+}
+
+static void SetInitialEggData(struct Pokemon *mon, u16 species, struct DayCare *daycare)
+{
+ u32 personality;
+ u16 ball;
+ u8 metLevel;
+ u8 language;
+
+ personality = daycare->offspringPersonality;
+ CreateMon(mon, species, EGG_HATCH_LEVEL, 0x20, TRUE, personality, FALSE, 0);
+ metLevel = 0;
+ ball = ITEM_POKE_BALL;
+ language = LANGUAGE_JAPANESE;
+ SetMonData(mon, MON_DATA_POKEBALL, &ball);
+ SetMonData(mon, MON_DATA_NICKNAME, sJapaneseEggNickname);
+ SetMonData(mon, MON_DATA_FRIENDSHIP, &gBaseStats[species].eggCycles);
+ SetMonData(mon, MON_DATA_MET_LEVEL, &metLevel);
+ SetMonData(mon, MON_DATA_LANGUAGE, &language);
+}
+
+void GiveEggFromDaycare(void)
+{
+ _GiveEggFromDaycare(&gSaveBlock1Ptr->daycare);
+}
+
+static bool8 _DoEggActions_CheckHatch(struct DayCare *daycare)
+{
+ u32 i, validEggs = 0;
+
+ for (i = 0; i < DAYCARE_MON_COUNT; i++)
+ {
+ if (GetBoxMonData(&daycare->mons[i].mon, MON_DATA_SANITY_BIT2))
+ daycare->mons[i].steps++, validEggs++;
+ }
+
+ // try to trigger poke sex
+ if (daycare->offspringPersonality == 0 && validEggs == 2 && (daycare->mons[1].steps & 0xFF) == 0xFF)
+ {
+ u8 loveScore = GetDaycareCompatibilityScore(daycare);
+ if (loveScore > (Random() * 100u) / USHRT_MAX)
+ TriggerPendingDaycareEgg();
+ }
+
+ if (++daycare->stepCounter == 255) // hatch an egg
+ {
+ u32 steps;
+ u8 toSub = GetEggStepsToSubtract();
+
+ for (i = 0; i < gPlayerPartyCount; i++)
+ {
+ if (!GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG))
+ continue;
+ if (GetMonData(&gPlayerParty[i], MON_DATA_SANITY_BIT1))
+ continue;
+
+ steps = GetMonData(&gPlayerParty[i], MON_DATA_FRIENDSHIP);
+ if (steps != 0) // subtract needed steps
+ {
+ if (steps >= toSub)
+ steps -= toSub;
+ else
+ steps -= 1;
+
+ SetMonData(&gPlayerParty[i], MON_DATA_FRIENDSHIP, &steps);
+ }
+ else // hatch the egg
+ {
+ gSpecialVar_0x8004 = i;
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE; // no hatching
+}
+
+bool8 DoEggActions_CheckHatch(void)
+{
+ return _DoEggActions_CheckHatch(&gSaveBlock1Ptr->daycare);
+}
+
+static bool8 IsEggPending(struct DayCare *daycare)
+{
+ return (daycare->offspringPersonality != 0);
+}
+
+// gStringVar1 = first mon's nickname
+// gStringVar2 = second mon's nickname
+// gStringVar3 = first mon trainer's name
+static void _GetDaycareMonNicknames(struct DayCare *daycare)
+{
+ u8 text[12];
+ if (GetBoxMonData(&daycare->mons[0].mon, MON_DATA_SPECIES) != 0)
+ {
+ GetBoxMonNick(&daycare->mons[0].mon, gStringVar1);
+ GetBoxMonData(&daycare->mons[0].mon, MON_DATA_OT_NAME, text);
+ StringCopy(gStringVar3, text);
+ }
+
+ if (GetBoxMonData(&daycare->mons[1].mon, MON_DATA_SPECIES) != 0)
+ {
+ GetBoxMonNick(&daycare->mons[1].mon, gStringVar2);
+ }
+}
+
+u16 GetSelectedMonNickAndSpecies(void)
+{
+ GetBoxMonNick(&gPlayerParty[GetCursorSelectionMonId()].box, gStringVar1);
+ return GetBoxMonData(&gPlayerParty[GetCursorSelectionMonId()].box, MON_DATA_SPECIES);
+}
+
+void GetDaycareMonNicknames(void)
+{
+ _GetDaycareMonNicknames(&gSaveBlock1Ptr->daycare);
+}
+
+u8 GetDaycareState(void)
+{
+ // The daycare can be in 4 possible states:
+ // 0: default state--no deposited mons, no egg
+ // 1: there is an egg waiting for the player to pick it up
+ // 2: there is a single pokemon in the daycare
+ // 3: there are two pokemon in the daycare, no egg
+
+ u8 numMons;
+ if (IsEggPending(&gSaveBlock1Ptr->daycare))
+ {
+ // There is an Egg waiting for the player.
+ return 1;
+ }
+
+ numMons = CountPokemonInDaycare(&gSaveBlock1Ptr->daycare);
+ if (numMons != 0)
+ {
+ return numMons + 1;
+ }
+
+ return 0;
+}
+
+static u8 GetDaycarePokemonCount(void)
+{
+ u8 ret = CountPokemonInDaycare(&gSaveBlock1Ptr->daycare);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static bool8 EggGroupsOverlap(u16 *eggGroups1, u16 *eggGroups2)
+{
+ // Determine if the two given egg group lists contain any of the
+ // same egg groups.
+ s32 i, j;
+
+ for (i = 0; i < 2; i++)
+ {
+ for (j = 0; j < 2; j++)
+ {
+ if (eggGroups1[i] == eggGroups2[j])
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static u8 GetDaycareCompatibilityScore(struct DayCare *daycare)
+{
+ u32 i;
+ u16 eggGroups[2][2];
+ u16 species[2];
+ u32 trainerIds[2];
+ u32 genders[2];
+
+ for (i = 0; i < 2; i++)
+ {
+ u32 personality;
+
+ species[i] = GetBoxMonData(&daycare->mons[i].mon, MON_DATA_SPECIES);
+ trainerIds[i] = GetBoxMonData(&daycare->mons[i].mon, MON_DATA_OT_ID);
+ personality = GetBoxMonData(&daycare->mons[i].mon, MON_DATA_PERSONALITY);
+ genders[i] = GetGenderFromSpeciesAndPersonality(species[i], personality);
+ eggGroups[i][0] = gBaseStats[species[i]].eggGroup1;
+ eggGroups[i][1] = gBaseStats[species[i]].eggGroup2;
+ }
+
+ // check unbreedable egg group
+ if (eggGroups[0][0] == EGG_GROUP_UNDISCOVERED || eggGroups[1][0] == EGG_GROUP_UNDISCOVERED)
+ return 0;
+ // two Ditto can't breed
+ if (eggGroups[0][0] == EGG_GROUP_DITTO && eggGroups[1][0] == EGG_GROUP_DITTO)
+ return 0;
+
+ // now that we checked, one ditto can breed with any other mon
+ if (eggGroups[0][0] == EGG_GROUP_DITTO || eggGroups[1][0] == EGG_GROUP_DITTO)
+ {
+ if (trainerIds[0] == trainerIds[1]) // same trainer
+ return 20;
+
+ return 50; // different trainers, more chance of poke sex
+ }
+ else
+ {
+ if (genders[0] == genders[1]) // no homo
+ return 0;
+ if (genders[0] == MON_GENDERLESS || genders[1] == MON_GENDERLESS)
+ return 0;
+ if (!EggGroupsOverlap(eggGroups[0], eggGroups[1])) // not compatible with each other
+ return 0;
+
+ if (species[0] == species[1]) // same species
+ {
+ if (trainerIds[0] == trainerIds[1]) // same species and trainer
+ return 50;
+
+ return 70; // different trainers, same species
+ }
+ else
+ {
+ if (trainerIds[0] != trainerIds[1]) // different trainers, different species
+ return 50;
+
+ return 20; // different species, same trainer
+ }
+ }
+}
+
+static u8 GetDaycareCompatibilityScoreFromSave(void)
+{
+ return GetDaycareCompatibilityScore(&gSaveBlock1Ptr->daycare);
+}
+
+void SetDaycareCompatibilityString(void)
+{
+ u8 whichString;
+ u8 relationshipScore;
+
+ relationshipScore = GetDaycareCompatibilityScoreFromSave();
+ whichString = 0;
+ if (relationshipScore == 0)
+ whichString = 3;
+ if (relationshipScore == 20)
+ whichString = 2;
+ if (relationshipScore == 50)
+ whichString = 1;
+ if (relationshipScore == 70)
+ whichString = 0;
+
+ StringCopy(gStringVar4, sCompatibilityMessages[whichString]);
+}
+
+bool8 NameHasGenderSymbol(const u8 *name, u8 genderRatio)
+{
+ u8 i;
+ u8 symbolsCount[2]; // male, female
+ symbolsCount[0] = symbolsCount[1] = 0;
+
+ for (i = 0; name[i] != EOS; i++)
+ {
+ if (name[i] == CHAR_MALE)
+ symbolsCount[0]++;
+ if (name[i] == CHAR_FEMALE)
+ symbolsCount[1]++;
+ }
+
+ if (genderRatio == MON_MALE && symbolsCount[0] != 0 && symbolsCount[1] == 0)
+ return TRUE;
+ if (genderRatio == MON_FEMALE && symbolsCount[1] != 0 && symbolsCount[0] == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+static u8 *AppendGenderSymbol(u8 *name, u8 gender)
+{
+ if (gender == MON_MALE)
+ {
+ if (!NameHasGenderSymbol(name, MON_MALE))
+ return StringAppend(name, gText_MaleSymbol4);
+ }
+ else if (gender == MON_FEMALE)
+ {
+ if (!NameHasGenderSymbol(name, MON_FEMALE))
+ return StringAppend(name, gText_FemaleSymbol4);
+ }
+
+ return StringAppend(name, gText_GenderlessSymbol);
+}
+
+static u8 *AppendMonGenderSymbol(u8 *name, struct BoxPokemon *boxMon)
+{
+ return AppendGenderSymbol(name, GetBoxMonGender(boxMon));
+}
+
+static void GetDaycareLevelMenuText(struct DayCare *daycare, u8 *dest)
+{
+ u8 monNames[2][20];
+ u8 i;
+
+ *dest = EOS;
+ for (i = 0; i < 2; i++)
+ {
+ GetBoxMonNick(&daycare->mons[i].mon, monNames[i]);
+ AppendMonGenderSymbol(monNames[i], &daycare->mons[i].mon);
+ }
+
+ StringCopy(dest, monNames[0]);
+ StringAppend(dest, gText_NewLine2);
+ StringAppend(dest, monNames[1]);
+ StringAppend(dest, gText_NewLine2);
+ StringAppend(dest, gText_Exit4);
+}
+
+static void GetDaycareLevelMenuLevelText(struct DayCare *daycare, u8 *dest)
+{
+ u8 i;
+ u8 level;
+ u8 text[20];
+
+ *dest = EOS;
+ for (i = 0; i < 2; i++)
+ {
+ StringAppend(dest, gText_Lv);
+ level = GetLevelAfterDaycareSteps(&daycare->mons[i].mon, daycare->mons[i].steps);
+ ConvertIntToDecimalStringN(text, level, STR_CONV_MODE_LEFT_ALIGN, 3);
+ StringAppend(dest, text);
+ StringAppend(dest, gText_NewLine2);
+ }
+}
+
+static void DaycareAddTextPrinter(u8 windowId, const u8 *text, u32 x, u32 y)
+{
+ struct TextSubPrinter printer;
+
+ printer.current_text_offset = text;
+ printer.windowId = windowId;
+ printer.fontId = 1;
+ printer.x = x;
+ printer.y = y;
+ printer.currentX = x;
+ printer.currentY = y;
+ printer.fontColor_l = 0;
+ gTextFlags.flag_1 = 0;
+ printer.letterSpacing = 0;
+ printer.lineSpacing = 1;
+ printer.fontColor_h = 2;
+ printer.bgColor = 1;
+ printer.shadowColor = 3;
+
+ AddTextPrinter(&printer, 0xFF, NULL);
+}
+
+static void DaycarePrintMonNick(struct DayCare *daycare, u8 windowId, u32 daycareSlotId, u32 y)
+{
+ u8 nick[POKEMON_NAME_LENGTH * 2];
+
+ GetBoxMonNick(&daycare->mons[daycareSlotId].mon, nick);
+ AppendMonGenderSymbol(nick, &daycare->mons[daycareSlotId].mon);
+ DaycareAddTextPrinter(windowId, nick, 8, y);
+}
+
+static void DaycarePrintMonLvl(struct DayCare *daycare, u8 windowId, u32 daycareSlotId, u32 y)
+{
+ u8 level;
+ u32 x;
+ u8 lvlText[12];
+ u8 intText[8];
+
+ StringCopy(lvlText, gText_Lv);
+ level = GetLevelAfterDaycareSteps(&daycare->mons[daycareSlotId].mon, daycare->mons[daycareSlotId].steps);
+ ConvertIntToDecimalStringN(intText, level, STR_CONV_MODE_LEFT_ALIGN, 3);
+ StringAppend(lvlText, intText);
+ x = GetStringRightAlignXOffset(1, lvlText, 112);
+ DaycareAddTextPrinter(windowId, lvlText, x, y);
+}
+
+static void DaycarePrintMonInfo(u8 windowId, s32 daycareSlotId, u8 y)
+{
+ if (daycareSlotId < (unsigned) DAYCARE_MON_COUNT)
+ {
+ DaycarePrintMonNick(&gSaveBlock1Ptr->daycare, windowId, daycareSlotId, y);
+ DaycarePrintMonLvl(&gSaveBlock1Ptr->daycare, windowId, daycareSlotId, y);
+ }
+}
+
+#define tMenuListTaskId data[0]
+#define tWindowId data[1]
+
+static void Task_HandleDaycareLevelMenuInput(u8 taskId)
+{
+ u32 var = ListMenuHandleInput(gTasks[taskId].tMenuListTaskId);
+
+ if (gMain.newKeys & A_BUTTON)
+ {
+ switch (var)
+ {
+ case 0:
+ case 1:
+ gSpecialVar_Result = var;
+ break;
+ case 5:
+ gSpecialVar_Result = 2;
+ break;
+ }
+ sub_81AE6C8(gTasks[taskId].tMenuListTaskId, NULL, NULL);
+ sub_819746C(gTasks[taskId].tWindowId, TRUE);
+ RemoveWindow(gTasks[taskId].tWindowId);
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ gSpecialVar_Result = 2;
+ sub_81AE6C8(gTasks[taskId].tMenuListTaskId, NULL, NULL);
+ sub_819746C(gTasks[taskId].tWindowId, TRUE);
+ RemoveWindow(gTasks[taskId].tWindowId);
+ DestroyTask(taskId);
+ EnableBothScriptContexts();
+ }
+}
+
+void ShowDaycareLevelMenu(void)
+{
+ struct ListMenuTemplate menuTemplate;
+ u8 windowId;
+ u8 listMenuTaskId;
+ u8 daycareMenuTaskId;
+
+ windowId = AddWindow(&sDaycareLevelMenuWindowTemplate);
+ sub_81973FC(windowId, FALSE);
+
+ menuTemplate = sDaycareListMenuLevelTemplate;
+ menuTemplate.unk_10 = windowId;
+ listMenuTaskId = ListMenuInit(&menuTemplate, 0, 0);
+
+ CopyWindowToVram(windowId, 3);
+
+ daycareMenuTaskId = CreateTask(Task_HandleDaycareLevelMenuInput, 3);
+ gTasks[daycareMenuTaskId].tMenuListTaskId = listMenuTaskId;
+ gTasks[daycareMenuTaskId].tWindowId = windowId;
+}
+
+#undef tMenuListTaskId
+#undef tWindowId
+
+void ChooseSendDaycareMon(void)
+{
+ sub_81B9328();
+ gMain.savedCallback = c2_exit_to_overworld_2_switch;
+}
diff --git a/src/decoration.c b/src/decoration.c
index 0179d36a1..adcdc583b 100644
--- a/src/decoration.c
+++ b/src/decoration.c
@@ -1,5 +1,3 @@
-
-// Includes
#include "global.h"
#include "decompress.h"
#include "malloc.h"
@@ -68,27 +66,27 @@ struct DecorRearrangementDataBuffer {
// Static RAM declarations
EWRAM_DATA u8 *gCurDecorInventoryItems = NULL;
-EWRAM_DATA u8 sSecretBasePCMenuCursorPos = 0;
-EWRAM_DATA u8 sCurDecorCatCount = 0;
-EWRAM_DATA u8 sSecretBaseItemsIndicesBuffer[16] = {};
-EWRAM_DATA u8 sPlayerRoomItemsIndicesBuffer[12] = {};
-EWRAM_DATA u16 sSecretBasePCSelectDecorLineNo = 0;
-EWRAM_DATA u16 sSecretBasePCSelectDecorPageNo = 0;
+EWRAM_DATA static u8 sSecretBasePCMenuCursorPos = 0;
+EWRAM_DATA static u8 sCurDecorCatCount = 0;
+EWRAM_DATA static u8 sSecretBaseItemsIndicesBuffer[16] = {};
+EWRAM_DATA static u8 sPlayerRoomItemsIndicesBuffer[12] = {};
+EWRAM_DATA static u16 sSecretBasePCSelectDecorLineNo = 0;
+EWRAM_DATA static u16 sSecretBasePCSelectDecorPageNo = 0;
EWRAM_DATA u8 gCurDecorationIndex = 0;
-EWRAM_DATA u8 sCurDecorationCategory = DECORCAT_DESK;
-EWRAM_DATA u32 filler_0203a174[2] = {};
+EWRAM_DATA static u8 sCurDecorationCategory = DECORCAT_DESK;
+EWRAM_DATA static u32 filler_0203a174[2] = {};
EWRAM_DATA struct DecorPCPointers gUnknown_0203A17C = {};
-EWRAM_DATA u8 sDecorMenuWindowIndices[4] = {};
+EWRAM_DATA static u8 sDecorMenuWindowIndices[4] = {};
EWRAM_DATA struct DecorPCBuffer *sDecorPCBuffer = NULL;
EWRAM_DATA struct PlaceDecorationGraphicsDataBuffer sPlaceDecorationGraphicsDataBuffer = {};
-EWRAM_DATA u16 sCurDecorMapX = 0;
-EWRAM_DATA u16 sCurDecorMapY = 0;
-EWRAM_DATA u8 sDecor_CameraSpriteObjectIdx1 = 0;
-EWRAM_DATA u8 sDecor_CameraSpriteObjectIdx2 = 0;
-EWRAM_DATA u8 sDecorationLastDirectionMoved = 0;
-EWRAM_DATA struct OamData sDecorSelectorOam = {};
-EWRAM_DATA struct DecorRearrangementDataBuffer sDecorRearrangementDataBuffer[16] = {};
-EWRAM_DATA u8 sCurDecorSelectedInRearrangement = 0;
+EWRAM_DATA static u16 sCurDecorMapX = 0;
+EWRAM_DATA static u16 sCurDecorMapY = 0;
+EWRAM_DATA static u8 sDecor_CameraSpriteObjectIdx1 = 0;
+EWRAM_DATA static u8 sDecor_CameraSpriteObjectIdx2 = 0;
+EWRAM_DATA static u8 sDecorationLastDirectionMoved = 0;
+EWRAM_DATA static struct OamData sDecorSelectorOam = {};
+EWRAM_DATA static struct DecorRearrangementDataBuffer sDecorRearrangementDataBuffer[16] = {};
+EWRAM_DATA static u8 sCurDecorSelectedInRearrangement = 0;
// Static ROM declarations
@@ -800,9 +798,9 @@ void sub_8127330(u8 taskId)
sDecorPCBuffer->items[i].unk_04 = -2;
gUnknown_03006310 = gUnknown_085A6BD0;
gUnknown_03006310.unk_10 = sDecorMenuWindowIndices[1];
- gUnknown_03006310.unk_0c = sDecorPCBuffer->unk_520;
- gUnknown_03006310.unk_00 = sDecorPCBuffer->items;
- gUnknown_03006310.unk_0e = sDecorPCBuffer->unk_521;
+ gUnknown_03006310.totalItems = sDecorPCBuffer->unk_520;
+ gUnknown_03006310.items = sDecorPCBuffer->items;
+ gUnknown_03006310.maxShowed = sDecorPCBuffer->unk_521;
}
void sub_8127454(u8 *dest, u16 decorId)
@@ -1600,10 +1598,10 @@ void sub_81289F0(u8 taskId)
{
sCurDecorMapX = gTasks[taskId].data[0] - 7;
sCurDecorMapY = gTasks[taskId].data[1] - 7;
- ScriptContext1_SetupScript(gUnknown_08275D1F);
+ ScriptContext1_SetupScript(EventScript_275D1F);
}
gSprites[sDecor_CameraSpriteObjectIdx1].pos1.y += 2;
- if (gMapHeader.regionMapSectionId == REGION_MAP_SECRET_BASE)
+ if (gMapHeader.regionMapSectionId == MAPSEC_SECRET_BASE)
{
TV_PutSecretBaseVisitOnTheAir();
}
@@ -1700,7 +1698,7 @@ void sub_8128C64(u8 taskId)
data[2] ++;
break;
case 1:
- ScriptContext1_SetupScript(gUnknown_08275D0C);
+ ScriptContext1_SetupScript(EventScript_275D0C);
data[2] ++;
break;
case 2:
@@ -2133,10 +2131,10 @@ void sub_8129708(void)
u16 i;
gSpecialVar_0x8005 = 0;
- gScriptResult = 0;
+ gSpecialVar_Result = 0;
if (gSpecialVar_0x8004 == sCurDecorSelectedInRearrangement)
{
- gScriptResult = 1;
+ gSpecialVar_Result = 1;
}
else if (gDecorations[gUnknown_0203A17C.items[sDecorRearrangementDataBuffer[gSpecialVar_0x8004].idx]].permission == DECORPERM_SOLID_MAT)
{
@@ -2206,7 +2204,7 @@ void sub_81298EC(u8 taskId)
case 1:
if (!gPaletteFade.active) {
DrawWholeMapView();
- ScriptContext1_SetupScript(gUnknown_08275D2E);
+ ScriptContext1_SetupScript(EventScript_275D2E);
sub_8197434(0, 1);
gTasks[taskId].data[2] = 2;
}
@@ -2222,7 +2220,7 @@ void sub_81298EC(u8 taskId)
{
StringExpandPlaceholders(gStringVar4, gText_DecorationReturnedToPC);
DisplayItemMessageOnField(taskId, gStringVar4, sub_8129D64);
- if (gMapHeader.regionMapSectionId == REGION_MAP_SECRET_BASE)
+ if (gMapHeader.regionMapSectionId == MAPSEC_SECRET_BASE)
{
TV_PutSecretBaseVisitOnTheAir();
}
@@ -2691,7 +2689,7 @@ void sub_812A2C4(u8 taskId)
data[2] ++;
break;
case 1:
- ScriptContext1_SetupScript(gUnknown_08275D0C);
+ ScriptContext1_SetupScript(EventScript_275D0C);
data[2] ++;
break;
case 2:
diff --git a/src/egg_hatch.c b/src/egg_hatch.c
index 589e8901d..a3f7c2ab0 100644
--- a/src/egg_hatch.c
+++ b/src/egg_hatch.c
@@ -1,5 +1,6 @@
#include "global.h"
#include "pokemon.h"
+#include "egg_hatch.h"
#include "pokedex.h"
#include "items.h"
#include "script.h"
@@ -23,6 +24,7 @@
#include "m4a.h"
#include "window.h"
#include "abilities.h"
+#include "daycare.h"
#include "battle.h" // to get rid of later
struct EggHatchData
@@ -75,7 +77,7 @@ extern void CreateYesNoMenu(const struct WindowTemplate*, u16, u8, u8);
extern void DoNamingScreen(u8, const u8*, u16, u8, u32, MainCallback);
extern void AddTextPrinterParametrized2(u8 windowId, u8 fontId, u8 x, u8 y, u8 letterSpacing, u8 lineSpacing, struct TextColor* colors, s8 speed, u8 *str);
extern u16 sub_80D22D0(void);
-extern u8 sub_80C7050(u8);
+extern u8 CountPartyAliveNonEggMonsExcept(u8);
static void Task_EggHatch(u8 taskID);
static void CB2_EggHatch_0(void);
@@ -327,7 +329,7 @@ static void CreatedHatchedMon(struct Pokemon *egg, struct Pokemon *temp)
pokerus = GetMonData(egg, MON_DATA_POKERUS);
obedience = GetMonData(egg, MON_DATA_OBEDIENCE);
- CreateMon(temp, species, 5, 32, TRUE, personality, 0, 0);
+ CreateMon(temp, species, EGG_HATCH_LEVEL, 32, TRUE, personality, 0, 0);
for (i = 0; i < 4; i++)
{
@@ -393,19 +395,19 @@ void ScriptHatchMon(void)
AddHatchedMonToParty(gSpecialVar_0x8004);
}
-static bool8 sub_807158C(struct DaycareData* daycare, u8 daycareId)
+static bool8 sub_807158C(struct DayCare *daycare, u8 daycareId)
{
u8 nick[0x20];
- struct DaycareMon* daycareMon = &daycare->mons[daycareId];
+ struct DaycareMon *daycareMon = &daycare->mons[daycareId];
GetBoxMonNick(&daycareMon->mon, nick);
- if (daycareMon->mail.itemId != 0
- && (StringCompareWithoutExtCtrlCodes(nick, daycareMon->monName) != 0
- || StringCompareWithoutExtCtrlCodes(gSaveBlock2Ptr->playerName, daycareMon->OT_name) != 0))
+ if (daycareMon->misc.mail.itemId != 0
+ && (StringCompareWithoutExtCtrlCodes(nick, daycareMon->misc.monName) != 0
+ || StringCompareWithoutExtCtrlCodes(gSaveBlock2Ptr->playerName, daycareMon->misc.OT_name) != 0))
{
StringCopy(gStringVar1, nick);
- TVShowConvertInternationalString(gStringVar2, daycareMon->OT_name, daycareMon->language_maybe);
- TVShowConvertInternationalString(gStringVar3, daycareMon->monName, daycareMon->unknown);
+ TVShowConvertInternationalString(gStringVar2, daycareMon->misc.OT_name, daycareMon->misc.gameLanguage);
+ TVShowConvertInternationalString(gStringVar3, daycareMon->misc.monName, daycareMon->misc.monLanguage);
return TRUE;
}
return FALSE;
@@ -888,6 +890,6 @@ u8 GetEggStepsToSubtract(void)
u16 sub_80722E0(void)
{
u16 value = sub_80D22D0();
- value += sub_80C7050(6);
+ value += CountPartyAliveNonEggMonsExcept(6);
return value;
}
diff --git a/src/event_data.c b/src/event_data.c
index 19a310db5..e3742a147 100644
--- a/src/event_data.c
+++ b/src/event_data.c
@@ -17,11 +17,11 @@ EWRAM_DATA u16 gSpecialVar_0x8008 = 0;
EWRAM_DATA u16 gSpecialVar_0x8009 = 0;
EWRAM_DATA u16 gSpecialVar_0x800A = 0;
EWRAM_DATA u16 gSpecialVar_0x800B = 0;
-EWRAM_DATA u16 gScriptResult = 0;
-EWRAM_DATA u16 gScriptLastTalked = 0;
-EWRAM_DATA u16 gScriptFacing = 0;
-EWRAM_DATA u16 gSpecialVar_0x8012 = 0;
-EWRAM_DATA u16 gSpecialVar_0x8013 = 0;
+EWRAM_DATA u16 gSpecialVar_Result = 0;
+EWRAM_DATA u16 gSpecialVar_LastTalked = 0;
+EWRAM_DATA u16 gSpecialVar_Facing = 0;
+EWRAM_DATA u16 gSpecialVar_MonBoxId = 0;
+EWRAM_DATA u16 gSpecialVar_MonBoxPos = 0;
EWRAM_DATA u16 gSpecialVar_0x8014 = 0;
EWRAM_DATA static u8 gUnknown_020375FC[16] = {0};
@@ -40,11 +40,11 @@ void ClearTempFieldEventData(void)
{
memset(gSaveBlock1Ptr->flags, 0, TEMP_FLAGS_SIZE);
memset(gSaveBlock1Ptr->vars, 0, TEMP_VARS_SIZE);
- FlagClear(SYS_ENC_UP_ITEM);
- FlagClear(SYS_ENC_DOWN_ITEM);
- FlagClear(SYS_USE_STRENGTH);
- FlagClear(SYS_CTRL_OBJ_DELETE);
- FlagClear(SYS_UNKNOWN_880);
+ FlagClear(FLAG_SYS_ENC_UP_ITEM);
+ FlagClear(FLAG_SYS_ENC_DOWN_ITEM);
+ FlagClear(FLAG_SYS_USE_STRENGTH);
+ FlagClear(FLAG_SYS_CTRL_OBJ_DELETE);
+ FlagClear(FLAG_SYS_UNKNOWN_880);
}
// probably had different flag splits at one point.
@@ -58,7 +58,7 @@ void DisableNationalPokedex(void)
u16 *nationalDexVar = GetVarPointer(VAR_NATIONAL_DEX);
gSaveBlock2Ptr->pokedex.nationalMagic = 0;
*nationalDexVar = 0;
- FlagClear(SYS_NATIONAL_DEX);
+ FlagClear(FLAG_SYS_NATIONAL_DEX);
}
void EnableNationalPokedex(void)
@@ -66,7 +66,7 @@ void EnableNationalPokedex(void)
u16 *nationalDexVar = GetVarPointer(VAR_NATIONAL_DEX);
gSaveBlock2Ptr->pokedex.nationalMagic = 0xDA;
*nationalDexVar = 0x302;
- FlagSet(SYS_NATIONAL_DEX);
+ FlagSet(FLAG_SYS_NATIONAL_DEX);
gSaveBlock2Ptr->pokedex.unknown1 = 1;
gSaveBlock2Ptr->pokedex.order = 0;
sub_80BB358();
@@ -74,7 +74,7 @@ void EnableNationalPokedex(void)
bool32 IsNationalPokedexEnabled(void)
{
- if (gSaveBlock2Ptr->pokedex.nationalMagic == 0xDA && VarGet(VAR_NATIONAL_DEX) == 0x302 && FlagGet(SYS_NATIONAL_DEX))
+ if (gSaveBlock2Ptr->pokedex.nationalMagic == 0xDA && VarGet(VAR_NATIONAL_DEX) == 0x302 && FlagGet(FLAG_SYS_NATIONAL_DEX))
return TRUE;
else
return FALSE;
@@ -82,32 +82,32 @@ bool32 IsNationalPokedexEnabled(void)
void DisableMysteryEvent(void)
{
- FlagClear(SYS_MYSTERY_EVENT_ENABLE);
+ FlagClear(FLAG_SYS_MYSTERY_EVENT_ENABLE);
}
void EnableMysteryEvent(void)
{
- FlagSet(SYS_MYSTERY_EVENT_ENABLE);
+ FlagSet(FLAG_SYS_MYSTERY_EVENT_ENABLE);
}
bool32 IsMysteryEventEnabled(void)
{
- return FlagGet(SYS_MYSTERY_EVENT_ENABLE);
+ return FlagGet(FLAG_SYS_MYSTERY_EVENT_ENABLE);
}
void DisableMysteryGift(void)
{
- FlagClear(SYS_MYSTERY_GIFT_ENABLE);
+ FlagClear(FLAG_SYS_MYSTERY_GIFT_ENABLE);
}
void EnableMysteryGift(void)
{
- FlagSet(SYS_MYSTERY_GIFT_ENABLE);
+ FlagSet(FLAG_SYS_MYSTERY_GIFT_ENABLE);
}
bool32 IsMysteryGiftEnabled(void)
{
- return FlagGet(SYS_MYSTERY_GIFT_ENABLE);
+ return FlagGet(FLAG_SYS_MYSTERY_GIFT_ENABLE);
}
void sub_809D4D8(void)
@@ -145,18 +145,18 @@ void sub_809D570(void)
void DisableResetRTC(void)
{
VarSet(VAR_RESET_RTC_ENABLE, 0);
- FlagClear(SYS_RESET_RTC_ENABLE);
+ FlagClear(FLAG_SYS_RESET_RTC_ENABLE);
}
void EnableResetRTC(void)
{
VarSet(VAR_RESET_RTC_ENABLE, 0x920);
- FlagSet(SYS_RESET_RTC_ENABLE);
+ FlagSet(FLAG_SYS_RESET_RTC_ENABLE);
}
bool32 CanResetRTC(void)
{
- if (FlagGet(SYS_RESET_RTC_ENABLE) && VarGet(VAR_RESET_RTC_ENABLE) == 0x920)
+ if (FlagGet(FLAG_SYS_RESET_RTC_ENABLE) && VarGet(VAR_RESET_RTC_ENABLE) == 0x920)
return TRUE;
else
return FALSE;
diff --git a/src/field_map_obj.c b/src/field_map_obj.c
index 9932563f2..dfdeb63a3 100755
--- a/src/field_map_obj.c
+++ b/src/field_map_obj.c
@@ -1765,10 +1765,10 @@ void sub_808F28C(u8 localId, u8 mapNum, u8 mapGroup, u8 decorCat)
switch (decorCat)
{
case DECORCAT_DOLL:
- sub_808F228(&gMapObjects[mapObjectId], gUnknown_082766A2);
+ sub_808F228(&gMapObjects[mapObjectId], EventScript_2766A2);
break;
case DECORCAT_CUSHION:
- sub_808F228(&gMapObjects[mapObjectId], gUnknown_082766A6);
+ sub_808F228(&gMapObjects[mapObjectId], EventScript_2766A6);
break;
}
}
diff --git a/src/field_region_map.c b/src/field_region_map.c
new file mode 100644
index 000000000..b7d677c90
--- /dev/null
+++ b/src/field_region_map.c
@@ -0,0 +1,193 @@
+
+// Includes
+#include "global.h"
+#include "main.h"
+#include "malloc.h"
+#include "gpu_regs.h"
+#include "bg.h"
+#include "text.h"
+#include "window.h"
+#include "text_window.h"
+#include "palette.h"
+#include "menu.h"
+#include "strings.h"
+#include "international_string_util.h"
+#include "region_map.h"
+
+// Static type declarations
+
+// Static RAM declarations
+
+static EWRAM_DATA struct {
+ MainCallback callback;
+ u32 filler_004;
+ struct RegionMap regionMap;
+ u16 state;
+} *sFieldRegionMapHandler = NULL;
+
+// Static ROM declarations
+
+static void MCB2_InitRegionMapRegisters(void);
+static void VBCB_FieldUpdateRegionMap(void);
+static void MCB2_FieldUpdateRegionMap(void);
+static void FieldUpdateRegionMap(void);
+static void PrintRegionMapSecName(void);
+
+// .rodata
+
+static const struct BgTemplate gUnknown_085E5068[] = {
+ {
+ .bg = 0,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 31,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 0,
+ .baseTile = 0
+ }, {
+ .bg = 2,
+ .charBaseIndex = 2,
+ .mapBaseIndex = 28,
+ .screenSize = 2,
+ .paletteMode = 1,
+ .priority = 2,
+ .baseTile = 0
+ }
+};
+
+static const struct WindowTemplate gUnknown_085E5070[] = {
+ { 0, 17, 17, 12, 2, 15, 0x0001 },
+ { 0, 22, 1, 7, 2, 15, 0x0019 },
+ DUMMY_WIN_TEMPLATE
+};
+
+// .text
+
+void sub_817018C(MainCallback callback)
+{
+ SetVBlankCallback(NULL);
+ sFieldRegionMapHandler = malloc(sizeof(*sFieldRegionMapHandler));
+ sFieldRegionMapHandler->state = 0;
+ sFieldRegionMapHandler->callback = callback;
+ SetMainCallback2(MCB2_InitRegionMapRegisters);
+}
+
+static void MCB2_InitRegionMapRegisters(void)
+{
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ SetGpuReg(REG_OFFSET_BG0HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG0VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG2HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG2VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG3HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG3VOFS, 0);
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ ResetBgsAndClearDma3BusyFlags(0);
+ InitBgsFromTemplates(1, gUnknown_085E5068, 2);
+ InitWindows(gUnknown_085E5070);
+ DeactivateAllTextPrinters();
+ sub_809882C(0, 0x27, 0xd0);
+ clear_scheduled_bg_copies_to_vram();
+ SetMainCallback2(MCB2_FieldUpdateRegionMap);
+ SetVBlankCallback(VBCB_FieldUpdateRegionMap);
+}
+
+static void VBCB_FieldUpdateRegionMap(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+static void MCB2_FieldUpdateRegionMap(void)
+{
+ FieldUpdateRegionMap();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+ do_scheduled_bg_tilemap_copies_to_vram();
+}
+
+static void FieldUpdateRegionMap(void)
+{
+ u8 offset;
+
+ switch (sFieldRegionMapHandler->state)
+ {
+ case 0:
+ InitRegionMap(&sFieldRegionMapHandler->regionMap, 0);
+ CreateRegionMapPlayerIcon(0, 0);
+ CreateRegionMapCursor(1, 1);
+ sFieldRegionMapHandler->state++;
+ break;
+ case 1:
+ SetWindowBorderStyle(1, 0, 0x27, 0xd);
+ offset = GetStringCenterAlignXOffset(1, gText_Hoenn, 0x38);
+ PrintTextOnWindow(1, 1, gText_Hoenn, offset, 1, 0, NULL);
+ schedule_bg_copy_tilemap_to_vram(0);
+ SetWindowBorderStyle(0, 0, 0x27, 0xd);
+ PrintRegionMapSecName();
+ BeginNormalPaletteFade(-1, 0, 16, 0, 0);
+ sFieldRegionMapHandler->state++;
+ break;
+ case 2:
+ SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON);
+ ShowBg(0);
+ ShowBg(2);
+ sFieldRegionMapHandler->state++;
+ break;
+ case 3:
+ if (!gPaletteFade.active)
+ {
+ sFieldRegionMapHandler->state++;
+ }
+ break;
+ case 4:
+ switch (sub_81230AC())
+ {
+ case INPUT_EVENT_MOVE_END:
+ PrintRegionMapSecName();
+ break;
+ case INPUT_EVENT_A_BUTTON:
+ case INPUT_EVENT_B_BUTTON:
+ sFieldRegionMapHandler->state++;
+ break;
+ }
+ break;
+ case 5:
+ BeginNormalPaletteFade(-1, 0, 0, 16, 0);
+ sFieldRegionMapHandler->state++;
+ break;
+ case 6:
+ if (!gPaletteFade.active)
+ {
+ FreeRegionMapIconResources();
+ SetMainCallback2(sFieldRegionMapHandler->callback);
+ if (sFieldRegionMapHandler != NULL)
+ {
+ free(sFieldRegionMapHandler);
+ sFieldRegionMapHandler = NULL;
+ }
+ FreeAllWindowBuffers();
+ }
+ break;
+ }
+}
+
+static void PrintRegionMapSecName(void)
+{
+ if (sFieldRegionMapHandler->regionMap.iconDrawType != MAPSECTYPE_NONE)
+ {
+ FillWindowPixelBuffer(0, 0x11);
+ PrintTextOnWindow(0, 1, sFieldRegionMapHandler->regionMap.mapSecName, 0, 1, 0, NULL);
+ schedule_bg_copy_tilemap_to_vram(0);
+ }
+ else
+ {
+ FillWindowPixelBuffer(0, 0x11);
+ CopyWindowToVram(0, 3);
+ }
+}
diff --git a/src/field_special_scene.c b/src/field_special_scene.c
index 54c1d8144..f92f342eb 100755
--- a/src/field_special_scene.c
+++ b/src/field_special_scene.c
@@ -354,7 +354,7 @@ void sub_80FB768(void)
void sub_80FB7A4(void)
{
- FlagSet(SYS_CRUISE_MODE);
+ FlagSet(FLAG_SYS_CRUISE_MODE);
FlagSet(0x4001);
FlagSet(0x4000);
saved_warp2_set(0, gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, -1);
diff --git a/src/hall_of_fame.c b/src/hall_of_fame.c
index d9fd40b84..bc7177bd7 100644
--- a/src/hall_of_fame.c
+++ b/src/hall_of_fame.c
@@ -1,4 +1,1556 @@
#include "global.h"
#include "hall_of_fame.h"
+#include "task.h"
+#include "palette.h"
+#include "sprite.h"
+#include "pokemon.h"
+#include "text.h"
+#include "malloc.h"
+#include "gpu_regs.h"
+#include "main.h"
+#include "sound.h"
+#include "songs.h"
+#include "decompress.h"
+#include "save.h"
+#include "window.h"
+#include "bg.h"
+#include "species.h"
+#include "game_stat.h"
+#include "blend_palette.h"
+#include "string_util.h"
+#include "m4a.h"
+#include "international_string_util.h"
+#include "unknown_task.h"
+#include "trig.h"
+#include "rng.h"
+#include "event_data.h"
+struct HallofFameMon
+{
+ u32 tid;
+ u32 personality;
+ u16 species:9;
+ u16 lvl:7;
+ u8 nick[10];
+};
+struct HallofFameTeam
+{
+ struct HallofFameMon mon[6];
+};
+
+struct HofGfx
+{
+ u16 state;
+ u8 field_2[16];
+ u8 tilemap1[0x1000];
+ u8 tilemap2[0x1000];
+};
+
+static EWRAM_DATA struct HallofFameTeam *sHofMonPtr = NULL;
+static EWRAM_DATA struct HofGfx *sHofGfxPtr = NULL;
+
+extern bool8 gHasHallOfFameRecords;
+extern u32 gUnknown_0203BCD4;
+extern u8 gDecompressionBuffer[];
+extern struct MusicPlayerInfo gMPlay_BGM;
+extern MainCallback gGameContinueCallback;
+extern u32 gDamagedSaveSectors;
+extern u8 gReservedSpritePaletteCount;
+
+#define HALL_OF_FAME_MAX_TEAMS 50
+
+// strings
+extern const u8 gText_SavingDontTurnOffPower[];
+extern const u8 gText_LeagueChamp[];
+extern const u8 gText_HOFNumber[];
+extern const u8 gText_PickNextCancel[];
+extern const u8 gText_PickCancel[];
+extern const u8 gText_UnkCtrlF800Exit[];
+extern const u8 gText_HOFCorrupted[];
+extern const u8 gText_WelcomeToHOF[];
+extern const u8 gText_Number[];
+extern const u8 gText_Level[];
+extern const u8 gText_IDNumber[];
+extern const u8 gText_Name[];
+extern const u8 gText_MainMenuTime[];
+
+// graphics
+extern const u8 gContestConfetti_Gfx[];
+extern const u8 gContestConfetti_Pal[];
+
+extern void sub_81973C4(u8, u8);
+extern u16 AddTextPrinterParametrized(u8 windowId, u8 fontId, const u8 *str, u8 speed, void ( *callback)(u16, struct TextPrinter *), u8 fgColor, u8 bgColor, u8 shadowColor);
+extern void sub_8175620(void);
+extern u8 TrySavingData(u8);
+extern u8 sub_818D3E4(u16 species, u32 trainerId, u32 personality, u8 flags, s16 x, s16 y, u8, u16);
+extern void sub_8197434(u8, u8);
+extern u16 sub_818D97C(u8 playerGender, u8);
+extern u16 sub_818D8AC(u16, u8, s16, s16, u8, u16);
+extern const void* stdpal_get(u8);
+extern void sub_80987D4(u8, u8, u16, u8);
+extern u16 sub_818D820(u16);
+extern u16 sub_818D8F0(u16);
+extern u16 sub_818D7D8(u16 species, u32 trainerId, u32 personality, u8 arg3, s16 sp0, s16 sp1, u8 sp2, u16 sp3);
+extern void sub_8198204(u8 *dst, const u8 *src, u8, u8, u8);
+extern bool8 sub_80F9C30(void);
+extern void sub_8198314(void);
+extern void sub_8137C3C(void);
+extern void sub_8198180(const u8 *src, u8, u8);
+extern void sub_80F9BF4(u16, u16, u8);
+extern void sub_81980F0(u8, u8, u8, u8, u16);
+extern void sub_80F9BCC(u16, u16, u8);
+extern bool8 sub_80F9C1C(void);
+extern u16 SpeciesToPokedexNum(u16 species);
+extern void dp13_810BB8C(void);
+extern void sub_81971D0(void);
+extern void sub_8197200(void);
+extern void sub_8152254(void);
+extern void sub_81525D0(u8);
+extern void sub_8152438(u8, void*);
+extern void sub_8152474(u8, u8, u8);
+extern void sub_81522D4(void);
+extern bool32 sub_81521C0(u8);
+extern u8 sub_81524C4(const struct OamData *arg0, s16 arg1, s16 arg2, s16 arg3, s16 arg4, u8 arg5, s16 arg6);
+
+// this file's functions
+static void ClearVramOamPltt_LoadHofPal(void);
+static void sub_8174F70(void);
+static void sub_8174FAC(void);
+static bool8 sub_81751FC(void);
+static void SetCallback2AfterHallOfFameDisplay(void);
+static bool8 sub_8175024(void);
+static void Task_Hof_InitMonData(u8 taskId);
+static void Task_Hof_InitTeamSaveData(u8 taskId);
+static void Task_Hof_SetMonDisplayTask(u8 taskId);
+static void Task_Hof_TrySaveData(u8 taskId);
+static void Task_Hof_WaitForFrames(u8 taskId);
+static void Task_Hof_DisplayMon(u8 taskId);
+static void Task_Hof_PrintMonInfoAfterAnimating(u8 taskId);
+static void Task_Hof_TryDisplayAnotherMon(u8 taskId);
+static void Task_Hof_PaletteFadeAndPrintWelcomeText(u8 taskId);
+static void sub_8173DC0(u8 taskId);
+static void sub_8173EA4(u8 taskId);
+static void sub_8173EE4(u8 taskId);
+static void Task_Hof_WaitAndPrintPlayerInfo(u8 taskId);
+static void Task_Hof_ExitOnKeyPressed(u8 taskId);
+static void Task_Hof_HandlePaletteOnExit(u8 taskId);
+static void Task_Hof_HandleExit(u8 taskId);
+static void Task_HofPC_CopySaveData(u8 taskId);
+static void Task_HofPC_PrintDataIsCorrupted(u8 taskId);
+static void Task_HofPC_DrawSpritesPrintText(u8 taskId);
+static void Task_HofPC_PrintMonInfo(u8 taskId);
+static void Task_HofPC_HandleInput(u8 taskId);
+static void Task_HofPC_HandlePaletteOnExit(u8 taskId);
+static void Task_HofPC_HandleExit(u8 taskId);
+static void Task_HofPC_ExitOnButtonPress(u8 taskId);
+static void SpriteCB_GetOnScreenAndAnimate(struct Sprite *sprite);
+static void HallOfFame_PrintMonInfo(struct HallofFameMon* currMon, u8 unused1, u8 unused2);
+static void HallOfFame_PrintWelcomeText(u8 unusedPossiblyWindowId, u8 unused2);
+static void HallOfFame_PrintPlayerInfo(u8 unused1, u8 unused2);
+static void sub_8175364(u8 taskId);
+static void sub_81751A4(struct Sprite* sprite);
+
+// const rom data
+static const struct BgTemplate sHof_BgTemplates[] =
+{
+ {
+ .bg = 0,
+ .charBaseIndex = 2,
+ .mapBaseIndex = 31,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 0,
+ .baseTile = 0
+ },
+ {
+ .bg = 1,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 30,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 1,
+ .baseTile = 0
+ },
+ {
+ .bg = 3,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 29,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 3,
+ .baseTile = 0
+ },
+};
+
+static const struct WindowTemplate sHof_WindowTemplate = {0, 2, 2, 0xE, 6, 0xE, 1};
+
+static const u8 gUnknown_085E5388[] = {0, 1, 2, 0};
+
+static const u8 gUnknown_085E538C[] = {0, 2, 3, 0, 4, 5, 0, 0};
+
+static const struct CompressedSpriteSheet sHallOfFame_ConfettiSpriteSheet =
+{
+ gContestConfetti_Gfx, 0x220, 1001
+};
+
+static const u8 sUnused0[8] = {};
+
+static const struct CompressedSpritePalette sHallOfFame_ConfettiSpritePalette =
+{
+ gContestConfetti_Pal, 1001
+};
+
+static const u8 sUnused1[8] = {};
+
+static const s16 sHallOfFame_MonFullTeamPositions[6][4] =
+{
+ {120, 210, 120, 40},
+ {326, 220, 56, 40},
+ {-86, 220, 184, 40},
+ {120, -62, 120, 88},
+ {-70, -92, 200, 88},
+ {310, -92, 40, 88}
+};
+
+static const s16 sHallOfFame_MonHalfTeamPositions[3][4] =
+{
+ {120, 234, 120, 64},
+ {326, 244, 56, 64},
+ {-86, 244, 184, 64}
+};
+
+static const struct OamData sOamData_85E53FC =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 0,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const union AnimCmd sSpriteAnim_85E5404[] =
+{
+ ANIMCMD_FRAME(0, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_85E540C[] =
+{
+ ANIMCMD_FRAME(1, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_85E5414[] =
+{
+ ANIMCMD_FRAME(2, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_85E541C[] =
+{
+ ANIMCMD_FRAME(3, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_85E5424[] =
+{
+ ANIMCMD_FRAME(4, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_85E542C[] =
+{
+ ANIMCMD_FRAME(5, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_85E5434[] =
+{
+ ANIMCMD_FRAME(6, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_85E543C[] =
+{
+ ANIMCMD_FRAME(7, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_85E5444[] =
+{
+ ANIMCMD_FRAME(8, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_85E544C[] =
+{
+ ANIMCMD_FRAME(9, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_85E5454[] =
+{
+ ANIMCMD_FRAME(10, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_85E545C[] =
+{
+ ANIMCMD_FRAME(11, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_85E5464[] =
+{
+ ANIMCMD_FRAME(12, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_85E546C[] =
+{
+ ANIMCMD_FRAME(13, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_85E5474[] =
+{
+ ANIMCMD_FRAME(14, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_85E547C[] =
+{
+ ANIMCMD_FRAME(15, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sSpriteAnim_85E5484[] =
+{
+ ANIMCMD_FRAME(16, 30),
+ ANIMCMD_END
+};
+
+static const union AnimCmd * const sSpriteAnimTable_85E548C[] =
+{
+ sSpriteAnim_85E5404, sSpriteAnim_85E540C, sSpriteAnim_85E5414, sSpriteAnim_85E541C,
+ sSpriteAnim_85E5424, sSpriteAnim_85E542C, sSpriteAnim_85E5434, sSpriteAnim_85E543C,
+ sSpriteAnim_85E5444, sSpriteAnim_85E544C, sSpriteAnim_85E5454, sSpriteAnim_85E545C,
+ sSpriteAnim_85E5464, sSpriteAnim_85E546C, sSpriteAnim_85E5474, sSpriteAnim_85E547C,
+ sSpriteAnim_85E5484
+};
+
+static const struct SpriteTemplate sSpriteTemplate_85E54D0 =
+{
+ .tileTag = 1001,
+ .paletteTag = 1001,
+ .oam = &sOamData_85E53FC,
+ .anims = sSpriteAnimTable_85E548C,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_81751A4
+};
+
+static const u16 sHallOfFame_Pal[] = INCBIN_U16("graphics/misc/japanese_hof.gbapal");
+
+static const u8 sHallOfFame_Gfx[] = INCBIN_U8("graphics/misc/japanese_hof.4bpp.lz");
+
+static const struct HallofFameMon sDummyFameMon =
+{
+ 0x3EA03EA, 0, 0, 0, {0}
+};
+
+static const u8 sUnused2[6] = {2, 1, 3, 6, 4, 5};
+
+// code
+static void VBlankCB_HallOfFame(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+static void CB2_HallOfFame(void)
+{
+ RunTasks();
+ RunTextPrinters();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+}
+
+static bool8 InitHallOfFameScreen(void)
+{
+ switch (gMain.state)
+ {
+ case 0:
+ SetVBlankCallback(NULL);
+ ClearVramOamPltt_LoadHofPal();
+ sHofGfxPtr = AllocZeroed(sizeof(*sHofGfxPtr));
+ gMain.state = 1;
+ break;
+ case 1:
+ sub_8174F70();
+ gMain.state++;
+ break;
+ case 2:
+ SetGpuReg(REG_OFFSET_BLDCNT, 0x3F42);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0x710);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ sub_8174FAC();
+ sHofGfxPtr->state = 0;
+ gMain.state++;
+ break;
+ case 3:
+ if (!sub_8175024())
+ {
+ SetVBlankCallback(VBlankCB_HallOfFame);
+ BeginNormalPaletteFade(-1, 0, 0x10, 0, 0);
+ gMain.state++;
+ }
+ break;
+ case 4:
+ UpdatePaletteFade();
+ if (!gPaletteFade.active)
+ {
+ SetMainCallback2(CB2_HallOfFame);
+ PlayBGM(BGM_DENDOU);
+ return FALSE;
+ }
+ break;
+ }
+ return TRUE;
+}
+
+#define tDontSaveData data[0]
+#define tDisplayedMonId data[1]
+#define tMonNumber data[2]
+#define tFrameCount data[3]
+#define tPlayerSpriteID data[4]
+#define tMonSpriteId(i) data[i + 5]
+
+void CB2_DoHallOfFameScreen(void)
+{
+ if (!InitHallOfFameScreen())
+ {
+ u8 taskId = CreateTask(Task_Hof_InitMonData, 0);
+ gTasks[taskId].tDontSaveData = FALSE;
+ sHofMonPtr = AllocZeroed(sizeof(*sHofMonPtr));
+ }
+}
+
+void CB2_DoHallOfFameScreenDontSaveData(void)
+{
+ if (!InitHallOfFameScreen())
+ {
+ u8 taskId = CreateTask(Task_Hof_InitMonData, 0);
+ gTasks[taskId].tDontSaveData = TRUE;
+ sHofMonPtr = AllocZeroed(sizeof(*sHofMonPtr));
+ }
+}
+
+static void Task_Hof_InitMonData(u8 taskId)
+{
+ u16 i, j;
+
+ gTasks[taskId].tMonNumber = 0; // valid pokes
+
+ for (i = 0; i < 6; i++)
+ {
+ u8 nick[POKEMON_NAME_LENGTH + 2];
+ if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES))
+ {
+ sHofMonPtr->mon[i].species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2);
+ sHofMonPtr->mon[i].tid = GetMonData(&gPlayerParty[i], MON_DATA_OT_ID);
+ sHofMonPtr->mon[i].personality = GetMonData(&gPlayerParty[i], MON_DATA_PERSONALITY);
+ sHofMonPtr->mon[i].lvl = GetMonData(&gPlayerParty[i], MON_DATA_LEVEL);
+ GetMonData(&gPlayerParty[i], MON_DATA_NICKNAME, nick);
+ for (j = 0; j < POKEMON_NAME_LENGTH; j++)
+ {
+ sHofMonPtr->mon[i].nick[j] = nick[j];
+ }
+ gTasks[taskId].tMonNumber++;
+ }
+ else
+ {
+ sHofMonPtr->mon[i].species = 0;
+ sHofMonPtr->mon[i].tid = 0;
+ sHofMonPtr->mon[i].personality = 0;
+ sHofMonPtr->mon[i].lvl = 0;
+ sHofMonPtr->mon[i].nick[0] = EOS;
+ }
+ }
+
+ gUnknown_0203BCD4 = 0;
+ gTasks[taskId].tDisplayedMonId = 0;
+ gTasks[taskId].tPlayerSpriteID = 0xFF;
+
+ for (i = 0; i < 6; i++)
+ {
+ gTasks[taskId].tMonSpriteId(i) = 0xFF;
+ }
+
+ if (gTasks[taskId].tDontSaveData)
+ gTasks[taskId].func = Task_Hof_SetMonDisplayTask;
+ else
+ gTasks[taskId].func = Task_Hof_InitTeamSaveData;
+}
+
+static void Task_Hof_InitTeamSaveData(u8 taskId)
+{
+ u16 i;
+ struct HallofFameTeam* lastSavedTeam = (struct HallofFameTeam*)(gDecompressionBuffer);
+
+ if (!gHasHallOfFameRecords)
+ {
+ memset(gDecompressionBuffer, 0, 0x2000);
+ }
+ else
+ {
+ if (sub_81534D0(3) != TRUE)
+ memset(gDecompressionBuffer, 0, 0x2000);
+ }
+
+ for (i = 0; i < HALL_OF_FAME_MAX_TEAMS; i++, lastSavedTeam++)
+ {
+ if (lastSavedTeam->mon[0].species == 0)
+ break;
+ }
+ if (i >= HALL_OF_FAME_MAX_TEAMS)
+ {
+ struct HallofFameTeam *afterTeam = (struct HallofFameTeam*)(gDecompressionBuffer);
+ struct HallofFameTeam *beforeTeam = (struct HallofFameTeam*)(gDecompressionBuffer);
+ afterTeam++;
+ for (i = 0; i < HALL_OF_FAME_MAX_TEAMS - 1; i++, beforeTeam++, afterTeam++)
+ {
+ *beforeTeam = *afterTeam;
+ }
+ lastSavedTeam--;
+ }
+ *lastSavedTeam = *sHofMonPtr;
+
+ sub_81973C4(0, 0);
+ AddTextPrinterParametrized(0, 1, gText_SavingDontTurnOffPower, 0, NULL, 2, 1, 3);
+ CopyWindowToVram(0, 3);
+ gTasks[taskId].func = Task_Hof_TrySaveData;
+}
+
+static void Task_Hof_TrySaveData(u8 taskId)
+{
+ gGameContinueCallback = CB2_DoHallOfFameScreenDontSaveData;
+ if (TrySavingData(3) == 0xFF && gDamagedSaveSectors != 0)
+ {
+ UnsetBgTilemapBuffer(1);
+ UnsetBgTilemapBuffer(3);
+ FreeAllWindowBuffers();
+
+ if (sHofGfxPtr != NULL)
+ FREE_AND_SET_NULL(sHofGfxPtr);
+ if (sHofMonPtr != NULL)
+ FREE_AND_SET_NULL(sHofMonPtr);
+
+ DestroyTask(taskId);
+ }
+ else
+ {
+ PlaySE(SE_SAVE);
+ gTasks[taskId].func = Task_Hof_WaitForFrames;
+ gTasks[taskId].tFrameCount = 32;
+ }
+}
+
+static void Task_Hof_WaitForFrames(u8 taskId)
+{
+ if (gTasks[taskId].tFrameCount)
+ gTasks[taskId].tFrameCount--;
+ else
+ gTasks[taskId].func = Task_Hof_SetMonDisplayTask;
+}
+
+static void Task_Hof_SetMonDisplayTask(u8 taskId)
+{
+ gTasks[taskId].func = Task_Hof_DisplayMon;
+}
+
+#define tDestinationX data1
+#define tDestinationY data2
+#define tSpecies data7
+
+static void Task_Hof_DisplayMon(u8 taskId)
+{
+ u8 spriteId;
+ s16 xPos, yPos, field4, field6;
+
+ u16 currMonId = gTasks[taskId].tDisplayedMonId;
+ struct HallofFameMon* currMon = &sHofMonPtr->mon[currMonId];
+
+ if (gTasks[taskId].tMonNumber > 3)
+ {
+ xPos = sHallOfFame_MonFullTeamPositions[currMonId][0];
+ yPos = sHallOfFame_MonFullTeamPositions[currMonId][1];
+ field4 = sHallOfFame_MonFullTeamPositions[currMonId][2];
+ field6 = sHallOfFame_MonFullTeamPositions[currMonId][3];
+ }
+ else
+ {
+ xPos = sHallOfFame_MonHalfTeamPositions[currMonId][0];
+ yPos = sHallOfFame_MonHalfTeamPositions[currMonId][1];
+ field4 = sHallOfFame_MonHalfTeamPositions[currMonId][2];
+ field6 = sHallOfFame_MonHalfTeamPositions[currMonId][3];
+ }
+
+ if (currMon->species == SPECIES_EGG)
+ field6 += 10;
+
+ spriteId = sub_818D3E4(currMon->species, currMon->tid, currMon->personality, 1, xPos, yPos, currMonId, 0xFFFF);
+ gSprites[spriteId].tDestinationX = field4;
+ gSprites[spriteId].tDestinationY = field6;
+ gSprites[spriteId].data0 = 0;
+ gSprites[spriteId].tSpecies = currMon->species;
+ gSprites[spriteId].callback = SpriteCB_GetOnScreenAndAnimate;
+ gTasks[taskId].tMonSpriteId(currMonId) = spriteId;
+ sub_8197434(0, 1);
+ gTasks[taskId].func = Task_Hof_PrintMonInfoAfterAnimating;
+}
+
+static void Task_Hof_PrintMonInfoAfterAnimating(u8 taskId)
+{
+ u16 currMonId = gTasks[taskId].tDisplayedMonId;
+ struct HallofFameMon* currMon = &sHofMonPtr->mon[currMonId];
+ struct Sprite *monSprite = &gSprites[gTasks[taskId].tMonSpriteId(currMonId)];
+
+ if (monSprite->callback == SpriteCallbackDummy)
+ {
+ monSprite->oam.affineMode = 0;
+ HallOfFame_PrintMonInfo(currMon, 0, 14);
+ gTasks[taskId].tFrameCount = 120;
+ gTasks[taskId].func = Task_Hof_TryDisplayAnotherMon;
+ }
+}
+
+static void Task_Hof_TryDisplayAnotherMon(u8 taskId)
+{
+ u16 currPokeID = gTasks[taskId].tDisplayedMonId;
+ struct HallofFameMon* currMon = &sHofMonPtr->mon[currPokeID];
+
+ if (gTasks[taskId].tFrameCount != 0)
+ {
+ gTasks[taskId].tFrameCount--;
+ }
+ else
+ {
+ gUnknown_0203BCD4 |= (0x10000 << gSprites[gTasks[taskId].tMonSpriteId(currPokeID)].oam.paletteNum);
+ if (gTasks[taskId].tDisplayedMonId <= 4 && currMon[1].species != SPECIES_NONE) // there is another pokemon to display
+ {
+ gTasks[taskId].tDisplayedMonId++;
+ BeginNormalPaletteFade(gUnknown_0203BCD4, 0, 12, 12, 0x63B0);
+ gSprites[gTasks[taskId].tMonSpriteId(currPokeID)].oam.priority = 1;
+ gTasks[taskId].func = Task_Hof_DisplayMon;
+ }
+ else
+ {
+ gTasks[taskId].func = Task_Hof_PaletteFadeAndPrintWelcomeText;
+ }
+ }
+}
+
+static void Task_Hof_PaletteFadeAndPrintWelcomeText(u8 taskId)
+{
+ u16 i;
+
+ BeginNormalPaletteFade(0xFFFF0000, 0, 0, 0, 0);
+ for (i = 0; i < 6; i++)
+ {
+ if (gTasks[taskId].tMonSpriteId(i) != 0xFF)
+ gSprites[gTasks[taskId].tMonSpriteId(i)].oam.priority = 0;
+ }
+
+ HallOfFame_PrintWelcomeText(0, 15);
+ PlaySE(SE_DENDOU);
+ gTasks[taskId].tFrameCount = 400;
+ gTasks[taskId].func = sub_8173DC0;
+}
+
+static void sub_8173DC0(u8 taskId)
+{
+ if (gTasks[taskId].tFrameCount != 0)
+ {
+ gTasks[taskId].tFrameCount--;
+ if ((gTasks[taskId].tFrameCount & 3) == 0 && gTasks[taskId].tFrameCount > 110)
+ sub_81751FC();
+ }
+ else
+ {
+ u16 i;
+ for (i = 0; i < 6; i++)
+ {
+ if (gTasks[taskId].tMonSpriteId(i) != 0xFF)
+ gSprites[gTasks[taskId].tMonSpriteId(i)].oam.priority = 1;
+ }
+ BeginNormalPaletteFade(gUnknown_0203BCD4, 0, 12, 12, 0x63B0);
+ FillWindowPixelBuffer(0, 0);
+ CopyWindowToVram(0, 3);
+ gTasks[taskId].tFrameCount = 7;
+ gTasks[taskId].func = sub_8173EA4;
+ }
+}
+
+static void sub_8173EA4(u8 taskId)
+{
+ if (gTasks[taskId].tFrameCount >= 16)
+ {
+ gTasks[taskId].func = sub_8173EE4;
+ }
+ else
+ {
+ gTasks[taskId].tFrameCount++;
+ SetGpuReg(REG_OFFSET_BLDALPHA, gTasks[taskId].tFrameCount * 256);
+ }
+}
+
+static void sub_8173EE4(u8 taskId)
+{
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
+ ShowBg(0);
+ ShowBg(1);
+ ShowBg(3);
+ gTasks[taskId].tPlayerSpriteID = sub_818D8AC(sub_818D97C(gSaveBlock2Ptr->playerGender, 1), 1, 120, 72, 6, 0xFFFF);
+ AddWindow(&sHof_WindowTemplate);
+ sub_80987D4(1, gSaveBlock2Ptr->optionsWindowFrameType, 0x21D, 0xD0);
+ LoadPalette(stdpal_get(1), 0xE0, 0x20);
+ gTasks[taskId].tFrameCount = 120;
+ gTasks[taskId].func = Task_Hof_WaitAndPrintPlayerInfo;
+}
+
+static void Task_Hof_WaitAndPrintPlayerInfo(u8 taskId)
+{
+ if (gTasks[taskId].tFrameCount != 0)
+ {
+ gTasks[taskId].tFrameCount--;
+ }
+ else if (gSprites[gTasks[taskId].tPlayerSpriteID].pos1.x != 192)
+ {
+ gSprites[gTasks[taskId].tPlayerSpriteID].pos1.x++;
+ }
+ else
+ {
+ FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 0x20, 0x20);
+ HallOfFame_PrintPlayerInfo(1, 2);
+ sub_81973C4(0, 0);
+ AddTextPrinterParametrized(0, 1, gText_LeagueChamp, 0, NULL, 2, 1, 3);
+ CopyWindowToVram(0, 3);
+ gTasks[taskId].func = Task_Hof_ExitOnKeyPressed;
+ }
+}
+
+static void Task_Hof_ExitOnKeyPressed(u8 taskId)
+{
+ if (gMain.newKeys & A_BUTTON)
+ {
+ FadeOutBGM(4);
+ gTasks[taskId].func = Task_Hof_HandlePaletteOnExit;
+ }
+}
+
+static void Task_Hof_HandlePaletteOnExit(u8 taskId)
+{
+ CpuCopy16(gPlttBufferFaded, gPlttBufferUnfaded, 0x400);
+ BeginNormalPaletteFade(-1, 8, 0, 0x10, 0);
+ gTasks[taskId].func = Task_Hof_HandleExit;
+}
+
+static void Task_Hof_HandleExit(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ s32 i;
+
+ for (i = 0; i < 6; i++)
+ {
+ u8 spriteId = gTasks[taskId].tMonSpriteId(i);
+ if (spriteId != 0xFF)
+ {
+ FreeOamMatrix(gSprites[spriteId].oam.matrixNum);
+ sub_818D820(spriteId);
+ }
+ }
+
+ sub_818D8F0(gTasks[taskId].tPlayerSpriteID);
+ HideBg(0);
+ HideBg(1);
+ HideBg(3);
+ FreeAllWindowBuffers();
+ UnsetBgTilemapBuffer(1);
+ UnsetBgTilemapBuffer(3);
+ ResetBgsAndClearDma3BusyFlags(0);
+ DestroyTask(taskId);
+
+ if (sHofGfxPtr != NULL)
+ FREE_AND_SET_NULL(sHofGfxPtr);
+ if (sHofMonPtr != NULL)
+ FREE_AND_SET_NULL(sHofMonPtr);
+
+ SetCallback2AfterHallOfFameDisplay();
+ }
+}
+
+static void SetCallback2AfterHallOfFameDisplay(void)
+{
+ SetMainCallback2(sub_8175620);
+}
+
+#undef tDontSaveData
+#undef tDisplayedPoke
+#undef tMonNumber
+#undef tFrameCount
+#undef tPlayerSpriteID
+#undef tMonSpriteId
+
+#define tCurrTeamNo data[0]
+#define tCurrPageNo data[1]
+#define tCurrMonId data[2]
+#define tMonNo data[4]
+#define tMonSpriteId(i) data[i + 5]
+
+void CB2_DoHallOfFamePC(void)
+{
+ switch (gMain.state)
+ {
+ case 0:
+ default:
+ SetVBlankCallback(NULL);
+ ClearVramOamPltt_LoadHofPal();
+ sHofGfxPtr = AllocZeroed(sizeof(*sHofGfxPtr));
+ gMain.state = 1;
+ break;
+ case 1:
+ sub_8174F70();
+ gMain.state++;
+ break;
+ case 2:
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ sub_8174FAC();
+ gMain.state++;
+ break;
+ case 3:
+ if (!sub_8175024())
+ {
+ struct HallofFameTeam *fameTeam = (struct HallofFameTeam*)(gDecompressionBuffer);
+ fameTeam->mon[0] = sDummyFameMon;
+ sub_80F9BCC(0, 0, 0);
+ SetVBlankCallback(VBlankCB_HallOfFame);
+ gMain.state++;
+ }
+ break;
+ case 4:
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+ if (!sub_80F9C1C())
+ gMain.state++;
+ break;
+ case 5:
+ {
+ u8 taskId, i;
+
+ SetGpuReg(REG_OFFSET_BLDCNT, 0x3F42);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0x710);
+ SetGpuReg(REG_OFFSET_BLDY, 0);
+ taskId = CreateTask(Task_HofPC_CopySaveData, 0);
+
+ for (i = 0; i < 6; i++)
+ {
+ gTasks[taskId].tMonSpriteId(i) = 0xFF;
+ }
+
+ sHofMonPtr = AllocZeroed(0x2000);
+ SetMainCallback2(CB2_HallOfFame);
+ }
+ break;
+ }
+}
+
+static void Task_HofPC_CopySaveData(u8 taskId)
+{
+ sub_81980F0(0, 0x1E, 0, 0xC, 0x226);
+ if (sub_81534D0(3) != 1)
+ {
+ gTasks[taskId].func = Task_HofPC_PrintDataIsCorrupted;
+ }
+ else
+ {
+ u16 i;
+ struct HallofFameTeam* savedTeams;
+
+ CpuCopy16(gDecompressionBuffer, sHofMonPtr, 0x2000);
+ savedTeams = sHofMonPtr;
+ for (i = 0; i < HALL_OF_FAME_MAX_TEAMS; i++, savedTeams++)
+ {
+ if (savedTeams->mon[0].species == SPECIES_NONE)
+ break;
+ }
+
+ if (i < HALL_OF_FAME_MAX_TEAMS)
+ gTasks[taskId].tCurrTeamNo = i - 1;
+ else
+ gTasks[taskId].tCurrTeamNo = HALL_OF_FAME_MAX_TEAMS - 1;
+
+ gTasks[taskId].tCurrPageNo = GetGameStat(GAME_STAT_ENTERED_HOF);
+
+ gTasks[taskId].func = Task_HofPC_DrawSpritesPrintText;
+ }
+}
+
+static void Task_HofPC_DrawSpritesPrintText(u8 taskId)
+{
+ struct HallofFameTeam* savedTeams = sHofMonPtr;
+ struct HallofFameMon* currMon;
+ u16 i;
+
+ for (i = 0; i < gTasks[taskId].tCurrTeamNo; i++)
+ savedTeams++;
+
+ currMon = &savedTeams->mon[0];
+ gUnknown_0203BCD4 = 0;
+ gTasks[taskId].tCurrMonId = 0;
+ gTasks[taskId].tMonNo = 0;
+
+ for (i = 0; i < 6; i++, currMon++)
+ {
+ if (currMon->species != 0)
+ gTasks[taskId].tMonNo++;
+ }
+
+ currMon = &savedTeams->mon[0];
+
+ for (i = 0; i < 6; i++, currMon++)
+ {
+ if (currMon->species != 0)
+ {
+ u16 spriteId;
+ s16 posX, posY;
+
+ if (gTasks[taskId].tMonNo > 3)
+ {
+ posX = sHallOfFame_MonFullTeamPositions[i][2];
+ posY = sHallOfFame_MonFullTeamPositions[i][3];
+ }
+ else
+ {
+ posX = sHallOfFame_MonHalfTeamPositions[i][2];
+ posY = sHallOfFame_MonHalfTeamPositions[i][3];
+ }
+
+ if (currMon->species == SPECIES_EGG)
+ posY += 10;
+
+ spriteId = sub_818D7D8(currMon->species, currMon->tid, currMon->personality, 1, posX, posY, i, 0xFFFF);
+ gSprites[spriteId].oam.priority = 1;
+ gTasks[taskId].tMonSpriteId(i) = spriteId;
+ }
+ else
+ {
+ gTasks[taskId].tMonSpriteId(i) = 0xFF;
+ }
+ }
+
+ BlendPalettes(0xFFFF0000, 0xC, 0x63B0);
+
+ ConvertIntToDecimalStringN(gStringVar1, gTasks[taskId].tCurrPageNo, STR_CONV_MODE_RIGHT_ALIGN, 3);
+ StringExpandPlaceholders(gStringVar4, gText_HOFNumber);
+
+ if (gTasks[taskId].tCurrTeamNo <= 0)
+ sub_8198204(gStringVar4, gText_PickCancel, 0, 0, 1);
+ else
+ sub_8198204(gStringVar4, gText_PickNextCancel, 0, 0, 1);
+
+ gTasks[taskId].func = Task_HofPC_PrintMonInfo;
+}
+
+static void Task_HofPC_PrintMonInfo(u8 taskId)
+{
+ struct HallofFameTeam* savedTeams = sHofMonPtr;
+ struct HallofFameMon* currMon;
+ u16 i;
+ u16 currMonID;
+
+ for (i = 0; i < gTasks[taskId].tCurrTeamNo; i++)
+ savedTeams++;
+
+ for (i = 0; i < 6; i++)
+ {
+ u16 spriteId = gTasks[taskId].tMonSpriteId(i);
+ if (spriteId != 0xFF)
+ gSprites[spriteId].oam.priority = 1;
+ }
+
+ currMonID = gTasks[taskId].tMonSpriteId(gTasks[taskId].tCurrMonId);
+ gSprites[currMonID].oam.priority = 0;
+ gUnknown_0203BCD4 = (0x10000 << gSprites[currMonID].oam.paletteNum) ^ 0xFFFF0000;
+ BlendPalettesUnfaded(gUnknown_0203BCD4, 0xC, 0x63B0);
+
+ currMon = &savedTeams->mon[gTasks[taskId].tCurrMonId];
+ if (currMon->species != SPECIES_EGG)
+ {
+ StopCryAndClearCrySongs();
+ PlayCry1(currMon->species, 0);
+ }
+ HallOfFame_PrintMonInfo(currMon, 0, 14);
+
+ gTasks[taskId].func = Task_HofPC_HandleInput;
+}
+
+static void Task_HofPC_HandleInput(u8 taskId)
+{
+ u16 i;
+
+ if (gMain.newKeys & A_BUTTON)
+ {
+ if (gTasks[taskId].tCurrTeamNo != 0) // prepare another team to view
+ {
+ gTasks[taskId].tCurrTeamNo--;
+ for (i = 0; i < 6; i++)
+ {
+ u8 spriteId = gTasks[taskId].tMonSpriteId(i);
+ if (spriteId != 0xFF)
+ {
+ sub_818D820(spriteId);
+ gTasks[taskId].tMonSpriteId(i) = 0xFF;
+ }
+ }
+ if (gTasks[taskId].tCurrPageNo != 0)
+ gTasks[taskId].tCurrPageNo--;
+ gTasks[taskId].func = Task_HofPC_DrawSpritesPrintText;
+ }
+ else // no more teams to view, turn off hall of fame PC
+ {
+ if (IsCryPlayingOrClearCrySongs())
+ {
+ StopCryAndClearCrySongs();
+ m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100);
+ }
+ gTasks[taskId].func = Task_HofPC_HandlePaletteOnExit;
+ }
+ }
+ else if (gMain.newKeys & B_BUTTON) // turn off hall of fame PC
+ {
+ if (IsCryPlayingOrClearCrySongs())
+ {
+ StopCryAndClearCrySongs();
+ m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100);
+ }
+ gTasks[taskId].func = Task_HofPC_HandlePaletteOnExit;
+ }
+ else if (gMain.newKeys & DPAD_UP && gTasks[taskId].tCurrMonId != 0) // change mon -1
+ {
+ gTasks[taskId].tCurrMonId--;
+ gTasks[taskId].func = Task_HofPC_PrintMonInfo;
+ }
+ else if (gMain.newKeys & DPAD_DOWN && gTasks[taskId].tCurrMonId < gTasks[taskId].tMonNo - 1) // change mon +1
+ {
+ gTasks[taskId].tCurrMonId++;
+ gTasks[taskId].func = Task_HofPC_PrintMonInfo;
+ }
+}
+
+static void Task_HofPC_HandlePaletteOnExit(u8 taskId)
+{
+ struct HallofFameTeam* fameTeam;
+
+ CpuCopy16(gPlttBufferFaded, gPlttBufferUnfaded, 0x400);
+ fameTeam = (struct HallofFameTeam*)(gDecompressionBuffer);
+ fameTeam->mon[0] = sDummyFameMon;
+ sub_80F9BF4(0, 0, 0);
+ gTasks[taskId].func = Task_HofPC_HandleExit;
+}
+
+static void Task_HofPC_HandleExit(u8 taskId)
+{
+ if (!sub_80F9C30())
+ {
+ u8 i;
+
+ for (i = 0; i < 6; i++)
+ {
+ u16 spriteId = gTasks[taskId].tMonSpriteId(i);
+ if (spriteId != 0xFF)
+ {
+ sub_818D820(spriteId);
+ gTasks[taskId].tMonSpriteId(i) = 0xFF;
+ }
+ }
+
+ HideBg(0);
+ HideBg(1);
+ HideBg(3);
+ sub_8198314();
+ FreeAllWindowBuffers();
+ UnsetBgTilemapBuffer(1);
+ UnsetBgTilemapBuffer(3);
+ ResetBgsAndClearDma3BusyFlags(0);
+ DestroyTask(taskId);
+
+ if (sHofGfxPtr != NULL)
+ FREE_AND_SET_NULL(sHofGfxPtr);
+ if (sHofMonPtr != NULL)
+ FREE_AND_SET_NULL(sHofMonPtr);
+
+ sub_8137C3C();
+ }
+}
+
+static void Task_HofPC_PrintDataIsCorrupted(u8 taskId)
+{
+ sub_8198180(gText_UnkCtrlF800Exit, 8, 1);
+ sub_81973C4(0, 0);
+ AddTextPrinterParametrized(0, 1, gText_HOFCorrupted, 0, NULL, 2, 1, 3);
+ CopyWindowToVram(0, 3);
+ gTasks[taskId].func = Task_HofPC_ExitOnButtonPress;
+}
+
+static void Task_HofPC_ExitOnButtonPress(u8 taskId)
+{
+ if (gMain.newKeys & A_BUTTON)
+ gTasks[taskId].func = Task_HofPC_HandlePaletteOnExit;
+}
+
+#undef tCurrTeamNo
+#undef tCurrPageNo
+#undef tCurrMonId
+#undef tMonNo
+#undef tMonSpriteId
+
+static void HallOfFame_PrintWelcomeText(u8 unusedPossiblyWindowId, u8 unused2)
+{
+ FillWindowPixelBuffer(0, 0);
+ PutWindowTilemap(0);
+ box_print(0, 1, GetStringCenterAlignXOffset(1, gText_WelcomeToHOF, 0xD0), 1, gUnknown_085E5388, 0, gText_WelcomeToHOF);
+ CopyWindowToVram(0, 3);
+}
+
+static void HallOfFame_PrintMonInfo(struct HallofFameMon* currMon, u8 unused1, u8 unused2)
+{
+ u8 text[30];
+ u8 *stringPtr;
+ s32 dexNumber;
+ s32 width;
+
+ FillWindowPixelBuffer(0, 0);
+ PutWindowTilemap(0);
+
+ // dex number
+ if (currMon->species != SPECIES_EGG)
+ {
+ stringPtr = StringCopy(text, gText_Number);
+ dexNumber = SpeciesToPokedexNum(currMon->species);
+ if (dexNumber != 0xFFFF)
+ {
+ stringPtr[0] = (dexNumber / 100) + CHAR_0;
+ stringPtr++;
+ dexNumber %= 100;
+ stringPtr[0] = (dexNumber / 10) + CHAR_0;
+ stringPtr++;
+ stringPtr[0] = (dexNumber % 10) + CHAR_0;
+ stringPtr++;
+ }
+ else
+ {
+ *(stringPtr)++ = CHAR_QUESTION_MARK;
+ *(stringPtr)++ = CHAR_QUESTION_MARK;
+ *(stringPtr)++ = CHAR_QUESTION_MARK;
+ }
+ stringPtr[0] = EOS;
+ box_print(0, 1, 0x10, 1, gUnknown_085E5388, -1, text);
+ }
+
+ // nick, species names, gender and level
+ memcpy(text, currMon->nick, POKEMON_NAME_LENGTH);
+ text[POKEMON_NAME_LENGTH] = EOS;
+ if (currMon->species == SPECIES_EGG)
+ {
+ width = GetStringCenterAlignXOffset(1, text, 0xD0);
+ box_print(0, 1, width, 1, gUnknown_085E5388, -1, text);
+ CopyWindowToVram(0, 3);
+ }
+ else
+ {
+ width = GetStringRightAlignXOffset(1, text, 0x80);
+ box_print(0, 1, width, 1, gUnknown_085E5388, -1, text);
+
+ text[0] = CHAR_SLASH;
+ stringPtr = StringCopy(text + 1, gSpeciesNames[currMon->species]);
+
+ if (currMon->species != SPECIES_NIDORAN_M && currMon->species != SPECIES_NIDORAN_F)
+ {
+ switch (GetGenderFromSpeciesAndPersonality(currMon->species, currMon->personality))
+ {
+ case MON_MALE:
+ stringPtr[0] = CHAR_MALE;
+ stringPtr++;
+ break;
+ case MON_FEMALE:
+ stringPtr[0] = CHAR_FEMALE;
+ stringPtr++;
+ break;
+ }
+ }
+
+ stringPtr[0] = EOS;
+ box_print(0, 1, 0x80, 1, gUnknown_085E5388, -1, text);
+
+ stringPtr = StringCopy(text, gText_Level);
+ ConvertIntToDecimalStringN(stringPtr, currMon->lvl, STR_CONV_MODE_LEFT_ALIGN, 3);
+ box_print(0, 1, 0x24, 0x11, gUnknown_085E5388, -1, text);
+
+ stringPtr = StringCopy(text, gText_IDNumber);
+ ConvertIntToDecimalStringN(stringPtr, (u16)(currMon->tid), STR_CONV_MODE_LEADING_ZEROS, 5);
+ box_print(0, 1, 0x68, 0x11, gUnknown_085E5388, -1, text);
+
+ CopyWindowToVram(0, 3);
+ }
+}
+
+static void HallOfFame_PrintPlayerInfo(u8 unused1, u8 unused2)
+{
+ u8 text[20];
+ u32 width;
+ u16 trainerId;
+
+ FillWindowPixelBuffer(1, 0x11);
+ PutWindowTilemap(1);
+ SetWindowBorderStyle(1, FALSE, 0x21D, 0xD);
+ box_print(1, 1, 0, 1, gUnknown_085E538C, -1, gText_Name);
+
+ width = GetStringRightAlignXOffset(1, gSaveBlock2Ptr->playerName, 0x70);
+ box_print(1, 1, width, 1, gUnknown_085E538C, -1, gSaveBlock2Ptr->playerName);
+
+ trainerId = (gSaveBlock2Ptr->playerTrainerId[0]) | (gSaveBlock2Ptr->playerTrainerId[1] << 8);
+ box_print(1, 1, 0, 0x11, gUnknown_085E538C, 0, gText_IDNumber);
+ text[0] = (trainerId % 100000) / 10000 + CHAR_0;
+ text[1] = (trainerId % 10000) / 1000 + CHAR_0;
+ text[2] = (trainerId % 1000) / 100 + CHAR_0;
+ text[3] = (trainerId % 100) / 10 + CHAR_0;
+ text[4] = (trainerId % 10) / 1 + CHAR_0;
+ text[5] = EOS;
+ width = GetStringRightAlignXOffset(1, text, 0x70);
+ box_print(1, 1, width, 0x11, gUnknown_085E538C, -1, text);
+
+ box_print(1, 1, 0, 0x21, gUnknown_085E538C, -1, gText_MainMenuTime);
+ text[0] = (gSaveBlock2Ptr->playTimeHours / 100) + CHAR_0;
+ text[1] = (gSaveBlock2Ptr->playTimeHours % 100) / 10 + CHAR_0;
+ text[2] = (gSaveBlock2Ptr->playTimeHours % 10) + CHAR_0;
+
+ if (text[0] == CHAR_0)
+ text[0] = CHAR_SPACE;
+ if (text[0] == CHAR_SPACE && text[1] == CHAR_0)
+ text[8] = CHAR_SPACE;
+
+ text[3] = CHAR_COLON;
+ text[4] = (gSaveBlock2Ptr->playTimeMinutes % 100) / 10 + CHAR_0;
+ text[5] = (gSaveBlock2Ptr->playTimeMinutes % 10) + CHAR_0;
+ text[6] = EOS;
+
+ width = GetStringRightAlignXOffset(1, text, 0x70);
+ box_print(1, 1, width, 0x21, gUnknown_085E538C, -1, text);
+
+ CopyWindowToVram(1, 3);
+}
+
+static void ClearVramOamPltt_LoadHofPal(void)
+{
+ u32 vramOffset, oamOffset, plttOffset;
+ u32 vramSize, oamSize, plttSize;
+
+ vramOffset = (VRAM);
+ vramSize = VRAM_SIZE;
+ while (TRUE)
+ {
+ DmaFill16(3, 0, vramOffset, 0x1000);
+ vramOffset += 0x1000;
+ vramSize -= 0x1000;
+ if (vramSize <= 0x1000)
+ {
+ DmaFill16(3, 0, vramOffset, vramSize);
+ break;
+ }
+ }
+
+ oamOffset = OAM;
+ oamSize = OAM_SIZE;
+ DmaFill32(3, 0, oamOffset, oamSize);
+
+ plttOffset = PLTT;
+ plttSize = PLTT_SIZE;
+ DmaFill16(3, 0, plttOffset, plttSize);
+
+ ResetPaletteFade();
+ LoadPalette(sHallOfFame_Pal, 0, 0x20);
+}
+
+static void sub_8174F70(void)
+{
+ remove_some_task();
+ ResetTasks();
+ ResetSpriteData();
+ reset_temp_tile_data_buffers();
+ dp13_810BB8C();
+ FreeAllSpritePalettes();
+ gReservedSpritePaletteCount = 8;
+ LoadCompressedObjectPic(&sHallOfFame_ConfettiSpriteSheet);
+ LoadCompressedObjectPalette(&sHallOfFame_ConfettiSpritePalette);
+}
+
+static void sub_8174FAC(void)
+{
+ ResetBgsAndClearDma3BusyFlags(0);
+ InitBgsFromTemplates(0, sHof_BgTemplates, ARRAY_COUNT(sHof_BgTemplates));
+ SetBgTilemapBuffer(1, sHofGfxPtr->tilemap1);
+ SetBgTilemapBuffer(3, sHofGfxPtr->tilemap2);
+ ChangeBgX(0, 0, 0);
+ ChangeBgY(0, 0, 0);
+ ChangeBgX(1, 0, 0);
+ ChangeBgY(1, 0, 0);
+ ChangeBgX(3, 0, 0);
+ ChangeBgY(3, 0, 0);
+}
+
+static bool8 sub_8175024(void)
+{
+ switch (sHofGfxPtr->state)
+ {
+ case 0:
+ decompress_and_copy_tile_data_to_vram(1, sHallOfFame_Gfx, 0, 0, 0);
+ break;
+ case 1:
+ if (free_temp_tile_data_buffers_if_possible())
+ return TRUE;
+ break;
+ case 2:
+ FillBgTilemapBufferRect_Palette0(1, 1, 0, 0, 0x20, 2);
+ FillBgTilemapBufferRect_Palette0(1, 0, 0, 3, 0x20, 0xB);
+ FillBgTilemapBufferRect_Palette0(1, 1, 0, 0xE, 0x20, 6);
+ FillBgTilemapBufferRect_Palette0(3, 2, 0, 0, 0x20, 0x20);
+
+ CopyBgTilemapBufferToVram(1);
+ CopyBgTilemapBufferToVram(3);
+ break;
+ case 3:
+ sub_81971D0();
+ sub_8197200();
+ break;
+ case 4:
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON);
+ ShowBg(0);
+ ShowBg(1);
+ ShowBg(3);
+ sHofGfxPtr->state = 0;
+ return FALSE;
+ }
+
+ sHofGfxPtr->state++;
+ return TRUE;
+}
+
+static void SpriteCB_GetOnScreenAndAnimate(struct Sprite *sprite)
+{
+ if (sprite->pos1.x != sprite->tDestinationX
+ || sprite->pos1.y != sprite->tDestinationY)
+ {
+ if (sprite->pos1.x < sprite->tDestinationX)
+ sprite->pos1.x += 15;
+ if (sprite->pos1.x > sprite->tDestinationX)
+ sprite->pos1.x -= 15;
+
+ if (sprite->pos1.y < sprite->tDestinationY)
+ sprite->pos1.y += 10;
+ if (sprite->pos1.y > sprite->tDestinationY)
+ sprite->pos1.y -= 10;
+ }
+ else
+ {
+ s16 species = sprite->tSpecies;
+
+ if (species == SPECIES_EGG)
+ DoMonFrontSpriteAnimation(sprite, species, TRUE, 3);
+ else
+ DoMonFrontSpriteAnimation(sprite, species, FALSE, 3);
+ }
+}
+
+#undef tDestinationX
+#undef tDestinationY
+#undef tSpecies
+
+static void sub_81751A4(struct Sprite* sprite)
+{
+ if (sprite->pos2.y > 120)
+ {
+ DestroySprite(sprite);
+ }
+ else
+ {
+ u16 rand;
+ u8 tableID;
+
+ sprite->pos2.y++;
+ sprite->pos2.y += sprite->data1;
+
+ tableID = sprite->data0;
+ rand = (Random() % 4) + 8;
+ sprite->pos2.x = rand * gSineTable[tableID] / 256;
+
+ sprite->data0 += 4;
+ }
+}
+
+static bool8 sub_81751FC(void)
+{
+ u8 spriteID;
+ struct Sprite* sprite;
+
+ s16 posX = Random() % 240;
+ s16 posY = -(Random() % 8);
+
+ spriteID = CreateSprite(&sSpriteTemplate_85E54D0, posX, posY, 0);
+ sprite = &gSprites[spriteID];
+
+ StartSpriteAnim(sprite, Random() % 17);
+
+ if (Random() & 3)
+ sprite->data1 = 0;
+ else
+ sprite->data1 = 1;
+
+ return FALSE;
+}
+
+void sub_8175280(void)
+{
+ u8 taskId;
+
+ gSpecialVar_0x8004 = 180;
+ taskId = CreateTask(sub_8175364, 0);
+ if (taskId != 0xFF)
+ {
+ gTasks[taskId].data[1] = gSpecialVar_0x8004;
+ gSpecialVar_0x8005 = taskId;
+ }
+}
+
+static void sub_81752C0(void)
+{
+ u8 taskId;
+
+ if ((taskId = FindTaskIdByFunc(sub_8175364)) != 0xFF)
+ DestroyTask(taskId);
+
+ sub_8152254();
+ FreeSpriteTilesByTag(0x3E9);
+ FreeSpritePaletteByTag(0x3E9);
+}
+
+struct UnknownStruct912B4
+{
+ s16 field_0;
+ s16 field_2;
+ s16 field_4;
+ s16 field_6;
+ s16 field_8;
+ s16 field_A;
+ s16 field_C;
+ s16 field_E;
+ s16 field_10;
+ s16 field_12;
+ s16 field_14;
+ s16 field_16;
+ s16 field_18;
+ s16 field_1A;
+ s16 field_1C;
+ s16 field_1E;
+ s16 field_20;
+ s16 field_22;
+ s16 field_24;
+ s16 field_26;
+ s16 field_28;
+};
+
+static void sub_81752F4(struct UnknownStruct912B4 *unkStruct)
+{
+ if (unkStruct->field_E > 110)
+ {
+ gTasks[unkStruct->field_28].data[15]--;
+ sub_81525D0(unkStruct->field_16);
+ }
+ else
+ {
+ u8 var;
+ s32 rand;
+
+ unkStruct->field_E++;
+ unkStruct->field_E += unkStruct->field_1C;
+
+ var = unkStruct->field_1A;
+ rand = Random();
+ rand &= 3;
+ rand += 8;
+ unkStruct->field_C = (rand) * ((gSineTable[var])) / 256;
+
+ unkStruct->field_1A += 4;
+ }
+}
+
+static void sub_8175364(u8 taskId)
+{
+ u32 var = 0;
+ u16 *data = gTasks[taskId].data;
+
+ switch (data[0])
+ {
+ case 0:
+ if (!sub_81521C0(0x40))
+ {
+ DestroyTask(taskId);
+ gSpecialVar_0x8004 = var;
+ gSpecialVar_0x8005 = 0xFFFF;
+ }
+ LoadCompressedObjectPic(&sHallOfFame_ConfettiSpriteSheet);
+ LoadCompressedObjectPalette(&sHallOfFame_ConfettiSpritePalette);
+ data[0]++;
+ break;
+ case 1:
+ if (data[1] != 0 && data[1] % 3 == 0)
+ {
+ var = sub_81524C4(&sOamData_85E53FC, 0x3E9, 0x3E9, Random() % 240, -(Random() % 8), Random() % 0x11, var);
+ if (var != 0xFF)
+ {
+ sub_8152438(var, sub_81752F4);
+ if ((Random() & 3) == 0)
+ sub_8152474(var, 1, 1);
+ sub_8152474(var, 7, taskId);
+ data[15]++;
+ }
+ }
+ sub_81522D4();
+ if (data[1] != 0)
+ data[1]--;
+ else if (data[15] == 0)
+ data[0] = 0xFF;
+ break;
+ case 0xFF:
+ sub_81752C0();
+ gSpecialVar_0x8004 = var;
+ gSpecialVar_0x8005 = 0xFFFF;
+ break;
+ }
+}
diff --git a/src/heal_location.c b/src/heal_location.c
new file mode 100644
index 000000000..efc534170
--- /dev/null
+++ b/src/heal_location.c
@@ -0,0 +1,83 @@
+
+// Includes
+#include "global.h"
+#include "map_constants.h"
+#include "heal_location.h"
+
+#define HEAL_LOCATION(map, x, y) {MAP_GROUP_##map, MAP_ID_##map, x, y}
+
+// Static type declarations
+
+// Static RAM declarations
+
+// Static ROM declarations
+
+// .rodata
+
+static const struct HealLocation sHealLocations[] = {
+ HEAL_LOCATION(LITTLEROOT_TOWN_BRENDANS_HOUSE_2F, 4, 2),
+ HEAL_LOCATION(LITTLEROOT_TOWN_MAYS_HOUSE_2F, 4, 2),
+ HEAL_LOCATION(PETALBURG_CITY, 20, 17),
+ HEAL_LOCATION(SLATEPORT_CITY, 19, 20),
+ HEAL_LOCATION(MAUVILLE_CITY, 22, 6),
+ HEAL_LOCATION(RUSTBORO_CITY, 16, 39),
+ HEAL_LOCATION(FORTREE_CITY, 5, 7),
+ HEAL_LOCATION(LILYCOVE_CITY, 24, 15),
+ HEAL_LOCATION(MOSSDEEP_CITY, 28, 17),
+ HEAL_LOCATION(SOOTOPOLIS_CITY, 43, 32),
+ HEAL_LOCATION(EVER_GRANDE_CITY, 27, 49),
+ HEAL_LOCATION(LITTLEROOT_TOWN, 5, 9),
+ HEAL_LOCATION(LITTLEROOT_TOWN, 14, 9),
+ HEAL_LOCATION(OLDALE_TOWN, 6, 17),
+ HEAL_LOCATION(DEWFORD_TOWN, 2, 11),
+ HEAL_LOCATION(LAVARIDGE_TOWN, 9, 7),
+ HEAL_LOCATION(FALLARBOR_TOWN, 14, 8),
+ HEAL_LOCATION(VERDANTURF_TOWN, 16, 4),
+ HEAL_LOCATION(PACIFIDLOG_TOWN, 8, 16),
+ HEAL_LOCATION(EVER_GRANDE_CITY, 18, 6),
+ HEAL_LOCATION(SOUTHERN_ISLAND_EXTERIOR, 15, 20),
+ HEAL_LOCATION(BATTLE_FRONTIER_OUTSIDE_EAST, 3, 52)
+};
+
+#define NUM_HEAL_LOCATIONS (ARRAY_COUNT(sHealLocations))
+
+// .text
+
+static u32 GetHealLocationIndexFromMapGroupAndNum(u16 mapGroup, u16 mapNum)
+{
+ u32 i;
+
+ for (i = 0; i < NUM_HEAL_LOCATIONS; i++)
+ {
+ if (sHealLocations[i].group == mapGroup && sHealLocations[i].map == mapNum)
+ {
+ return i + 1;
+ }
+ }
+ return 0;
+}
+
+const struct HealLocation *GetHealLocationPointerFromMapGroupAndNum(u16 mapGroup, u16 mapNum)
+{
+ u32 loc;
+
+ loc = GetHealLocationIndexFromMapGroupAndNum(mapGroup, mapNum);
+ if (loc == 0)
+ {
+ return NULL;
+ }
+ return &sHealLocations[loc - 1];
+}
+
+const struct HealLocation *GetHealLocationPointer(u32 loc)
+{
+ if (loc == 0)
+ {
+ return NULL;
+ }
+ if (loc > NUM_HEAL_LOCATIONS)
+ {
+ return NULL;
+ }
+ return &sHealLocations[loc - 1];
+}
diff --git a/src/item.c b/src/item.c
index 0114676b6..32347623e 100644
--- a/src/item.c
+++ b/src/item.c
@@ -165,11 +165,11 @@ bool8 HasAtLeastOneBerry(void)
{
if (CheckBagHasItem(i, 1) == TRUE)
{
- gScriptResult = 1;
+ gSpecialVar_Result = 1;
return TRUE;
}
}
- gScriptResult = 0;
+ gSpecialVar_Result = 0;
return FALSE;
}
diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c
index 356b1a4b7..254aa8a5d 100644
--- a/src/lilycove_lady.c
+++ b/src/lilycove_lady.c
@@ -226,7 +226,7 @@ static EWRAM_DATA struct LilycoveLadyFavour *gUnknown_0203CD64 = NULL;
static EWRAM_DATA struct LilycoveLadyQuiz *gUnknown_0203CD68 = NULL;
static EWRAM_DATA struct LilycoveLadyContest *gUnknown_0203CD6C = NULL;
-extern EWRAM_DATA u16 gScriptItemId;
+extern EWRAM_DATA u16 gSpecialVar_ItemId;
u8 GetLilycoveLadyId(void)
{
@@ -242,11 +242,11 @@ void sub_818D9C0(void)
{
lilycoveLady = &gSaveBlock1Ptr->lilycoveLady;
VarSet(VAR_0x4011, gUnknown_0860B074[lilycoveLady->contest.category]);
- gScriptResult = TRUE;
+ gSpecialVar_Result = TRUE;
}
else
{
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
}
}
@@ -308,7 +308,7 @@ void SetLilycoveLadyRandomly(void)
void sub_818DAEC(void)
{
- gScriptResult = GetLilycoveLadyId();
+ gSpecialVar_Result = GetLilycoveLadyId();
}
static u8 sub_818DB04(const u16 *data)
@@ -459,7 +459,7 @@ static bool8 sub_818DD84(u16 itemId)
bool8 sub_818DE44(void)
{
- return sub_818DD84(gScriptItemId);
+ return sub_818DD84(gSpecialVar_ItemId);
}
bool8 sub_818DE5C(void)
@@ -845,7 +845,7 @@ void sub_818E47C(void)
void sub_818E490(void)
{
- RemoveBagItem(gScriptItemId, 1);
+ RemoveBagItem(gSpecialVar_ItemId, 1);
}
void sub_818E4A4(void)
@@ -853,7 +853,7 @@ void sub_818E4A4(void)
u8 i;
gUnknown_0203CD68 = &gSaveBlock1Ptr->lilycoveLady.quiz;
- gUnknown_0203CD68->itemId = gScriptItemId;
+ gUnknown_0203CD68->itemId = gSpecialVar_ItemId;
for (i = 0; i < 4; i ++)
{
gUnknown_0203CD68->playerTrainerId[i] = gSaveBlock2Ptr->playerTrainerId[i];
diff --git a/src/lottery_corner.c b/src/lottery_corner.c
index 3939f7d7f..211b78f19 100644
--- a/src/lottery_corner.c
+++ b/src/lottery_corner.c
@@ -42,7 +42,7 @@ void SetRandomLotteryNumber(u16 i)
void RetrieveLotteryNumber(void)
{
u16 lottoNumber = GetLotteryNumber();
- gScriptResult = lottoNumber;
+ gSpecialVar_Result = lottoNumber;
}
void PickLotteryCornerTicket(void)
@@ -66,7 +66,7 @@ void PickLotteryCornerTicket(void)
if (!GetMonData(pkmn, MON_DATA_IS_EGG))
{
u32 otId = GetMonData(pkmn, MON_DATA_OT_ID);
- u8 numMatchingDigits = GetMatchingDigits(gScriptResult, otId);
+ u8 numMatchingDigits = GetMatchingDigits(gSpecialVar_Result, otId);
if (numMatchingDigits > gSpecialVar_0x8004 && numMatchingDigits > 1)
{
@@ -90,7 +90,7 @@ void PickLotteryCornerTicket(void)
!GetBoxMonData(&gPokemonStoragePtr->boxes[i][j], MON_DATA_IS_EGG))
{
u32 otId = GetBoxMonData(&gPokemonStoragePtr->boxes[i][j], MON_DATA_OT_ID);
- u8 numMatchingDigits = GetMatchingDigits(gScriptResult, otId);
+ u8 numMatchingDigits = GetMatchingDigits(gSpecialVar_Result, otId);
if (numMatchingDigits > gSpecialVar_0x8004 && numMatchingDigits > 1)
{
diff --git a/src/mail.c b/src/mail.c
index 1060d73bd..1ceb1be1a 100644
--- a/src/mail.c
+++ b/src/mail.c
@@ -386,7 +386,7 @@ bool8 sub_81215EC(void)
CopyBgTilemapBufferToVram(2);
break;
case 12:
- LoadPalette(sub_8098C64(), 240, 32);
+ LoadPalette(GetOverworldTextboxPalettePtr(), 240, 32);
gPlttBufferUnfaded[250] = gUnknown_0859F2B8[gUnknown_0203A134->mailType].color10;
gPlttBufferFaded[250] = gUnknown_0859F2B8[gUnknown_0203A134->mailType].color10;
gPlttBufferUnfaded[251] = gUnknown_0859F2B8[gUnknown_0203A134->mailType].color12;
diff --git a/src/new_game.c b/src/new_game.c
index d0666dd71..75e80dc8e 100644
--- a/src/new_game.c
+++ b/src/new_game.c
@@ -59,7 +59,7 @@ extern void ResetContestLinkResults(void);
extern void ResetPokeJumpResults(void);
extern void SetBerryPowder(u32* powder, u32 newValue);
-extern u8 gUnknown_082715DE[];
+extern u8 EventScript_2715DE[];
void WriteUnalignedWord(u32 var, u8 *dataPtr)
{
@@ -198,7 +198,7 @@ void NewGameInitData(void)
ResetFanClub();
ResetLotteryCorner();
WarpToTruck();
- ScriptContext2_RunNewScript(gUnknown_082715DE);
+ ScriptContext2_RunNewScript(EventScript_2715DE);
ResetMiniGamesResults();
copy_strings_to_sav1();
SetLilycoveLady();
diff --git a/src/pokemon_2.c b/src/pokemon_2.c
index bb0e265b5..7014be492 100644
--- a/src/pokemon_2.c
+++ b/src/pokemon_2.c
@@ -1087,10 +1087,10 @@ u8 SendMonToPC(struct Pokemon* mon)
{
MonRestorePP(mon);
CopyMon(checkingMon, &mon->box, sizeof(mon->box));
- gSpecialVar_0x8012 = boxNo;
- gSpecialVar_0x8013 = boxPos;
+ gSpecialVar_MonBoxId = boxNo;
+ gSpecialVar_MonBoxPos = boxPos;
if (get_unknown_box_id() != boxNo)
- FlagClear(SYS_STORAGE_UNKNOWN_FLAG);
+ FlagClear(FLAG_SYS_STORAGE_UNKNOWN_FLAG);
VarSet(VAR_STORAGE_UNKNOWN, boxNo);
return MON_GIVEN_TO_PC;
}
diff --git a/src/pokemon_3.c b/src/pokemon_3.c
index 27da8b18e..01dfc954a 100644
--- a/src/pokemon_3.c
+++ b/src/pokemon_3.c
@@ -1234,12 +1234,12 @@ static void sub_806E6CC(u8 taskId)
DestroyTask(taskId);
}
-const u8 *pokemon_get_pal(struct Pokemon *mon)
+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 species_and_otid_get_pal(species, otId, personality);
+ return GetFrontSpritePalFromSpeciesAndPersonality(species, otId, personality);
}
// Extracts the upper 16 bits of a 32-bit number
@@ -1248,7 +1248,7 @@ const u8 *pokemon_get_pal(struct Pokemon *mon)
// Extracts the lower 16 bits of a 32-bit number
#define LOHALF(n) ((n) & 0xFFFF)
-const u8 *species_and_otid_get_pal(u16 species, u32 otId, u32 personality)
+const u8 *GetFrontSpritePalFromSpeciesAndPersonality(u16 species, u32 otId, u32 personality)
{
u32 shinyValue;
diff --git a/src/pokemon_size_record.c b/src/pokemon_size_record.c
index 1758fba32..ec0103bc7 100644
--- a/src/pokemon_size_record.c
+++ b/src/pokemon_size_record.c
@@ -109,13 +109,13 @@ static void FormatMonSizeRecord(u8 *string, u32 size)
static u8 CompareMonSize(u16 species, u16 *sizeRecord)
{
- if (gScriptResult == 0xFF)
+ if (gSpecialVar_Result == 0xFF)
{
return 0;
}
else
{
- struct Pokemon *pkmn = &gPlayerParty[gScriptResult];
+ struct Pokemon *pkmn = &gPlayerParty[gSpecialVar_Result];
if (GetMonData(pkmn, MON_DATA_IS_EGG) == TRUE || GetMonData(pkmn, MON_DATA_SPECIES) != species)
{
@@ -173,7 +173,7 @@ void CompareSeedotSize(void)
{
u16 *sizeRecord = GetVarPointer(VAR_SEEDOT_SIZE_RECORD);
- gScriptResult = CompareMonSize(SPECIES_SEEDOT, sizeRecord);
+ gSpecialVar_Result = CompareMonSize(SPECIES_SEEDOT, sizeRecord);
}
void InitLotadSizeRecord(void)
@@ -192,7 +192,7 @@ void CompareLotadSize(void)
{
u16 *sizeRecord = GetVarPointer(VAR_LOTAD_SIZE_RECORD);
- gScriptResult = CompareMonSize(SPECIES_LOTAD, sizeRecord);
+ gSpecialVar_Result = CompareMonSize(SPECIES_LOTAD, sizeRecord);
}
void GiveGiftRibbonToParty(u8 index, u8 ribbonId)
@@ -217,6 +217,6 @@ void GiveGiftRibbonToParty(u8 index, u8 ribbonId)
}
}
if (gotRibbon)
- FlagSet(SYS_RIBBON_GET);
+ FlagSet(FLAG_SYS_RIBBON_GET);
}
}
diff --git a/src/pokemon_storage_system.c b/src/pokemon_storage_system.c
index 3e409244c..f82a52d38 100644
--- a/src/pokemon_storage_system.c
+++ b/src/pokemon_storage_system.c
@@ -1,15 +1,122 @@
-
-// Includes
#include "global.h"
+#include "pokemon_storage_system.h"
+#include "pokemon.h"
+#include "species.h"
+#include "event_data.h"
+#include "string_util.h"
+#include "text.h"
-// Static type declarations
+IWRAM_DATA u8 gUnknown_03000F78[0x188];
-// Static RAM declarations
+u8 CountMonsInBox(u8 boxId)
+{
+ u16 i, count;
-IWRAM_DATA u8 gUnknown_03000F78[0x188];
+ for (i = 0, count = 0; i < IN_BOX_COUNT; i++)
+ {
+ if (GetBoxMonDataFromAnyBox(boxId, i, MON_DATA_SPECIES) != SPECIES_NONE)
+ count++;
+ }
+
+ return count;
+}
+
+s16 GetFirstFreeBoxSpot(u8 boxId)
+{
+ u16 i;
+
+ for (i = 0; i < IN_BOX_COUNT; i++)
+ {
+ if (GetBoxMonDataFromAnyBox(boxId, i, MON_DATA_SPECIES) == SPECIES_NONE)
+ return i;
+ }
+
+ return -1; // all spots are taken
+}
+
+u8 CountPartyNonEggMons(void)
+{
+ u16 i, count;
+
+ for (i = 0, count = 0; i < PARTY_SIZE; i++)
+ {
+ if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) != SPECIES_NONE
+ && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG))
+ {
+ count++;
+ }
+ }
+
+ return count;
+}
+
+u8 CountPartyAliveNonEggMonsExcept(u8 slotToIgnore)
+{
+ u16 i, count;
+
+ for (i = 0, count = 0; i < PARTY_SIZE; i++)
+ {
+ if (i != slotToIgnore
+ && GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) != SPECIES_NONE
+ && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG)
+ && GetMonData(&gPlayerParty[i], MON_DATA_HP) != 0)
+ {
+ count++;
+ }
+ }
+
+ return count;
+}
+
+u16 CountPartyAliveNonEggMons_IgnoreVar0x8004Slot(void)
+{
+ return CountPartyAliveNonEggMonsExcept(gSpecialVar_0x8004);
+}
+
+u8 CountPartyMons(void)
+{
+ u16 i, count;
+
+ for (i = 0, count = 0; i < PARTY_SIZE; i++)
+ {
+ if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) != SPECIES_NONE)
+ {
+ count++;
+ }
+ }
+
+ return count;
+}
+
+static u8 *StringCopyAndFillWithSpaces(u8 *dst, const u8 *src, u16 n)
+{
+ u8 *str;
+
+ for (str = StringCopy(dst, src); str < dst + n; str++)
+ *str = CHAR_SPACE;
+
+ *str = EOS;
+ return str;
+}
-// Static ROM declarations
+/* can't match
+static void sub_80C7128(u16 *dst, u16 dstToAdd, u16 dstToMul, const u16 *src, u16 srcToAdd, u16 srcToMul, u32 size, u16 count, u16 srcBy)
+{
+ u16 i;
-// .rodata
+ size <<= 0x11;
+ dst += (dstToMul * 32) + dstToAdd;
+ src += (srcToMul * srcBy) + srcToAdd;
-// .text
+ i = 0;
+ if (i < count)
+ {
+ size >>= 1;
+ for (i = 0; i < count; i++)
+ {
+ CpuSet(src, dst, size >> 0x10);
+ dst += 0x20;
+ src += srcBy;
+ }
+ }
+}*/
diff --git a/src/pokemon_summary_screen.c b/src/pokemon_summary_screen.c
index 838e91d90..d09cbc407 100755
--- a/src/pokemon_summary_screen.c
+++ b/src/pokemon_summary_screen.c
@@ -97,7 +97,6 @@ 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_8069004(struct BoxPokemon* a, void* b);
extern void sub_81C1E20(u8 taskId);
extern u8 *GetMonNickname(struct Pokemon *mon, u8 *dest);
extern u16 SpeciesToPokedexNum(u16 species);
@@ -667,7 +666,7 @@ void sub_81C0098(struct Pokemon *mon)
else
{
struct BoxPokemon *boxMon = gUnknown_0203CF1C->unk0->boxMon;
- sub_8069004(&boxMon[gUnknown_0203CF1C->unk40BE], mon);
+ BoxMonToMon(&boxMon[gUnknown_0203CF1C->unk40BE], mon);
}
}
@@ -1810,7 +1809,7 @@ void sub_81C171C(u8 taskId)
void sub_81C174C(u8 taskId)
{
s16* data = gTasks[taskId].data;
-
+
if (sub_81221EC() != 1)
{
if (gPaletteFade.active != 1)
@@ -1857,7 +1856,7 @@ void sub_81C174C(u8 taskId)
gUnknown_0203CF21 = 4;
gSpecialVar_0x8005 = 4;
sub_81C044C(taskId);
- }
+ }
}
}
}
@@ -1907,7 +1906,7 @@ void sub_81C1940(u8 taskId)
{
if (gUnknown_0203CF1C->unk40C0 != 2)
{
-
+
ClearWindowTilemap(19);
if (!gSprites[gUnknown_0203CF1C->unk40D5].invisible)
ClearWindowTilemap(13);
@@ -2224,7 +2223,7 @@ void sub_81C1E20(u8 taskId)
{
if (gUnknown_0203CF1C->unk40C0 == 2)
PutWindowTilemap(14);
-
+
}
else
{
@@ -2277,7 +2276,7 @@ void sub_81C1F80(u8 taskId)
PutWindowTilemap(15);
sub_81C240C(data[2]);
}
- else
+ else
{
if (!gSprites[gUnknown_0203CF1C->unk40D5].invisible)
{
@@ -3645,7 +3644,7 @@ void sub_81C3D54(u8 taskId)
{
s16 *data = gTasks[taskId].data;
s16 dataa = data[0] - 1;
-
+
switch (dataa)
{
case 0:
@@ -3676,4 +3675,4 @@ void sub_81C3D54(u8 taskId)
return;
}
data[0]++;
-} \ No newline at end of file
+}
diff --git a/src/recorded_battle.c b/src/recorded_battle.c
new file mode 100644
index 000000000..e843ff7cb
--- /dev/null
+++ b/src/recorded_battle.c
@@ -0,0 +1,1676 @@
+#include "global.h"
+#include "battle.h"
+#include "recorded_battle.h"
+#include "main.h"
+#include "pokemon.h"
+#include "rng.h"
+#include "event_data.h"
+#include "link.h"
+#include "string_util.h"
+#include "palette.h"
+#include "save.h"
+#include "malloc.h"
+#include "util.h"
+#include "task.h"
+#include "text.h"
+
+#define BANK_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_KYORGE | BATTLE_TYPE_RAYQUAZA))
+
+extern u32 gBattleTypeFlags;
+extern u16 gTrainerBattleOpponent_A;
+extern u16 gTrainerBattleOpponent_B;
+extern u16 gPartnerTrainerId;
+extern u8 gActiveBank;
+extern u8 gNoOfAllBanks;
+extern u16 gBattlePartyID[BATTLE_BANKS_COUNT];
+extern struct BattlePokemon gBattleMons[BATTLE_BANKS_COUNT];
+extern u16 gChosenMovesByBanks[BATTLE_BANKS_COUNT];
+extern u8 gUnknown_03001278;
+extern u8 gUnknown_03001279;
+
+struct PlayerInfo
+{
+ u32 trainerId;
+ u8 name[PLAYER_NAME_LENGTH];
+ u8 gender;
+ u16 bank;
+ u16 language;
+};
+
+struct MovePp
+{
+ u16 moves[4];
+ u8 pp[4];
+};
+
+struct RecordedBattleSave
+{
+ struct Pokemon playerParty[PARTY_SIZE];
+ struct Pokemon opponentParty[PARTY_SIZE];
+ u8 playersName[BATTLE_BANKS_COUNT][PLAYER_NAME_LENGTH];
+ u8 playersGender[BATTLE_BANKS_COUNT];
+ u32 playersTrainerId[BATTLE_BANKS_COUNT];
+ u8 playersLanguage[BATTLE_BANKS_COUNT];
+ u32 rngSeed;
+ u32 battleFlags;
+ u8 playersBank[BATTLE_BANKS_COUNT];
+ u16 opponentA;
+ u16 opponentB;
+ u16 partnerId;
+ u16 field_4FA;
+ u8 field_4FC;
+ u8 field_4FD;
+ u8 field_4FE;
+ u8 battleStyle : 1;
+ u8 textSpeed : 3;
+ u32 AI_scripts;
+ u8 field_504[8];
+ u8 field_50C;
+ u8 field_50D;
+ u16 field_50E[6];
+ u8 field_51A;
+ u8 field_51B;
+ u8 battleRecord[BATTLE_BANKS_COUNT][BANK_RECORD_SIZE];
+ u32 checksum;
+};
+
+EWRAM_DATA u32 gRecordedBattleRngSeed = 0;
+EWRAM_DATA u32 gBattlePalaceMoveSelectionRngValue = 0;
+EWRAM_DATA static u8 sBattleRecords[BATTLE_BANKS_COUNT][BANK_RECORD_SIZE] = {0};
+EWRAM_DATA static u16 sRecordedBytesNo[BATTLE_BANKS_COUNT] = {0};
+EWRAM_DATA static u16 sUnknown_0203C79C[4] = {0};
+EWRAM_DATA static u16 sUnknown_0203C7A4[4] = {0};
+EWRAM_DATA static u8 sUnknown_0203C7AC = 0;
+EWRAM_DATA static u8 sUnknown_0203C7AD = 0;
+EWRAM_DATA static u8 sUnknown_0203C7AE = 0;
+EWRAM_DATA static u8 sUnknown_0203C7AF = 0;
+EWRAM_DATA static MainCallback sCallback2_AfterRecordedBattle = NULL;
+EWRAM_DATA u8 gUnknown_0203C7B4 = 0;
+EWRAM_DATA static u8 sUnknown_0203C7B5 = 0;
+EWRAM_DATA static u8 sRecordedBattle_BattleStyle = 0;
+EWRAM_DATA static u8 sRecordedBattle_TextSpeed = 0;
+EWRAM_DATA static u32 sRecordedBattle_BattleFlags = 0;
+EWRAM_DATA static u32 sRecordedBattle_AI_Scripts = 0;
+EWRAM_DATA static struct Pokemon sSavedPlayerParty[PARTY_SIZE] = {0};
+EWRAM_DATA static struct Pokemon sSavedOpponentParty[PARTY_SIZE] = {0};
+EWRAM_DATA static u16 sRecordedBattle_PlayerMonMoves[2][4] = {0};
+EWRAM_DATA static struct PlayerInfo sRecordedBattle_Players[BATTLE_BANKS_COUNT] = {0};
+EWRAM_DATA static u8 sUnknown_0203CCD0 = 0;
+EWRAM_DATA static u8 sUnknown_0203CCD1[8] = {0};
+EWRAM_DATA static u8 sUnknown_0203CCD9 = 0;
+EWRAM_DATA static u8 sUnknown_0203CCDA = 0;
+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);
+static bool32 AllocTryCopyRecordedBattleSaveData(struct RecordedBattleSave *dst);
+static void RecordedBattle_RestoreSavedParties(void);
+static void CB2_RecordedBattle(void);
+
+void sub_8184DA4(u8 arg0)
+{
+ s32 i, j;
+
+ sUnknown_0203C7AC = arg0;
+ sUnknown_0203CCD0 = 0;
+
+ for (i = 0; i < BATTLE_BANKS_COUNT; i++)
+ {
+ sRecordedBytesNo[i] = 0;
+ sUnknown_0203C79C[i] = 0;
+ sUnknown_0203C7A4[i] = 0;
+
+ if (arg0 == 1)
+ {
+ for (j = 0; j < BANK_RECORD_SIZE; j++)
+ {
+ sBattleRecords[i][j] |= 0xFF;
+ }
+ sRecordedBattle_BattleFlags = gBattleTypeFlags;
+ sRecordedBattle_AI_Scripts = gBattleResources->ai->aiFlags;
+ }
+ }
+}
+
+void sub_8184E58(void)
+{
+ s32 i, j;
+
+ if (sUnknown_0203C7AC == 1)
+ {
+ gRecordedBattleRngSeed = gRngValue;
+ sUnknown_0203C7AE = VarGet(VAR_FRONTIER_FACILITY);
+ sUnknown_0203C7AF = sub_81A513C();
+ }
+ else if (sUnknown_0203C7AC == 2)
+ {
+ gRngValue = gRecordedBattleRngSeed;
+ }
+
+ if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ {
+ u8 linkPlayersCount;
+ u8 text[30];
+
+ gUnknown_0203C7B4 = GetMultiplayerId();
+ linkPlayersCount = GetLinkPlayerCount();
+
+ for (i = 0; i < BATTLE_BANKS_COUNT; i++)
+ {
+ 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].language = gLinkPlayers[i].language;
+
+ if (i < linkPlayersCount)
+ {
+ StringCopy(text, gLinkPlayers[i].name);
+ StripExtCtrlCodes(text);
+ StringCopy(sRecordedBattle_Players[i].name, text);
+ }
+ else
+ {
+ for (j = 0; j < PLAYER_NAME_LENGTH; j++)
+ sRecordedBattle_Players[i].name[j] = gLinkPlayers[i].name[j];
+ }
+ }
+ }
+ else
+ {
+ sRecordedBattle_Players[0].trainerId = (gSaveBlock2Ptr->playerTrainerId[0])
+ | (gSaveBlock2Ptr->playerTrainerId[1] << 8)
+ | (gSaveBlock2Ptr->playerTrainerId[2] << 16)
+ | (gSaveBlock2Ptr->playerTrainerId[3] << 24);
+
+ sRecordedBattle_Players[0].gender = gSaveBlock2Ptr->playerGender;
+ sRecordedBattle_Players[0].bank = 0;
+ sRecordedBattle_Players[0].language = gGameLanguage;
+
+ for (i = 0; i < PLAYER_NAME_LENGTH; i++)
+ sRecordedBattle_Players[0].name[i] = gSaveBlock2Ptr->playerName[i];
+ }
+}
+
+void RecordedBattle_SetBankAction(u8 bank, u8 action)
+{
+ if (sRecordedBytesNo[bank] < BANK_RECORD_SIZE && sUnknown_0203C7AC != 2)
+ {
+ sBattleRecords[bank][sRecordedBytesNo[bank]++] = action;
+ }
+}
+
+void RecordedBattle_ClearBankAction(u8 bank, u8 bytesToClear)
+{
+ s32 i;
+
+ for (i = 0; i < bytesToClear; i++)
+ {
+ sRecordedBytesNo[bank]--;
+ sBattleRecords[bank][sRecordedBytesNo[bank]] |= 0xFF;
+ if (sRecordedBytesNo[bank] == 0)
+ break;
+ }
+}
+
+u8 RecordedBattle_ReadBankAction(u8 bank)
+{
+ // trying to read past array or invalid action byte, battle is over
+ if (sRecordedBytesNo[bank] >= BANK_RECORD_SIZE || sBattleRecords[bank][sRecordedBytesNo[bank]] == 0xFF)
+ {
+ gSpecialVar_Result = gBattleOutcome = BATTLE_PLAYER_TELEPORTED; // hah
+ ResetPaletteFadeControl();
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ SetMainCallback2(CB2_QuitRecordedBattle);
+ return -1;
+ }
+ else
+ {
+ return sBattleRecords[bank][sRecordedBytesNo[bank]++];
+ }
+}
+
+u8 sub_81850D0(void)
+{
+ return sUnknown_0203C7AC;
+}
+
+u8 sub_81850DC(u8 *arg0)
+{
+ u8 i, j;
+ u8 ret = 0;
+
+ for (i = 0; i < BATTLE_BANKS_COUNT; i++)
+ {
+ if (sRecordedBytesNo[i] != sUnknown_0203C79C[i])
+ {
+ arg0[ret++] = i;
+ arg0[ret++] = sRecordedBytesNo[i] - sUnknown_0203C79C[i];
+
+ for (j = 0; j < sRecordedBytesNo[i] - sUnknown_0203C79C[i]; j++)
+ {
+ arg0[ret++] = sBattleRecords[i][sUnknown_0203C79C[i] + j];
+ }
+
+ sUnknown_0203C79C[i] = sRecordedBytesNo[i];
+ }
+ }
+
+ return ret;
+}
+
+void sub_81851A8(u8 *arg0)
+{
+ s32 i;
+ u8 var1 = 2;
+ u8 var2;
+
+ if (!(gBattleTypeFlags & BATTLE_TYPE_LINK))
+ return;
+
+ for (i = 0; i < GetLinkPlayerCount(); i++)
+ {
+ if ((gLinkPlayers[i].version & 0xFF) != VERSION_EMERALD)
+ return;
+ }
+
+ if (!(gBattleTypeFlags & BATTLE_TYPE_WILD))
+ {
+ for (var2 = *arg0; var2 != 0;)
+ {
+ u8 unkVar = sub_8185278(arg0, &var1, &var2);
+ u8 unkVar2 = sub_8185278(arg0, &var1, &var2);
+
+ for (i = 0; i < unkVar2; i++)
+ {
+ sBattleRecords[unkVar][sUnknown_0203C7A4[unkVar]++] = sub_8185278(arg0, &var1, &var2);
+ }
+ }
+ }
+}
+
+static u8 sub_8185278(u8 *arg0, u8 *arg1, u8 *arg2)
+{
+ (*arg2)--;
+ return arg0[(*arg1)++];
+}
+
+bool32 CanCopyRecordedBattleSaveData(void)
+{
+ struct RecordedBattleSave *dst = AllocZeroed(sizeof(struct RecordedBattleSave));
+ bool32 ret = AllocTryCopyRecordedBattleSaveData(dst);
+ Free(dst);
+ return ret;
+}
+
+static bool32 IsRecordedBattleSaveValid(struct RecordedBattleSave *save)
+{
+ if (save->battleFlags == 0)
+ return FALSE;
+ if (save->battleFlags & ILLEGAL_BATTLE_TYPES)
+ return FALSE;
+ if (CalcByteArraySum((void*)(save), sizeof(*save) - 4) != save->checksum)
+ return FALSE;
+
+ return TRUE;
+}
+
+static bool32 sub_81852F0(struct RecordedBattleSave *battleSave, struct RecordedBattleSave *saveSection)
+{
+ memset(saveSection, 0, sizeof(struct SaveSection));
+ memcpy(saveSection, battleSave, sizeof(*battleSave));
+
+ saveSection->checksum = CalcByteArraySum((void*)(saveSection), sizeof(*saveSection) - 4);
+
+ if (sub_8153634(31, (void*)(saveSection)) != 1)
+ return FALSE;
+
+ return TRUE;
+}
+
+#ifdef NONMATCHING
+u32 MoveRecordedBattleToSaveData(void)
+{
+ s32 i, j;
+ u8 var = 0;
+ struct RecordedBattleSave *battleSave = AllocZeroed(sizeof(struct RecordedBattleSave));
+ struct SaveSection *savSection = AllocZeroed(sizeof(struct SaveSection));
+
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ battleSave->playerParty[i] = sSavedPlayerParty[i];
+ battleSave->opponentParty[i] = sSavedOpponentParty[i];
+ }
+
+ for (i = 0; i < BATTLE_BANKS_COUNT; i++)
+ {
+ for (j = 0; j < PLAYER_NAME_LENGTH; j++)
+ {
+ battleSave->playersName[i][j] = sRecordedBattle_Players[i].name[j];
+ }
+ battleSave->playersGender[i] = sRecordedBattle_Players[i].gender;
+ battleSave->playersLanguage[i] = sRecordedBattle_Players[i].language;
+ battleSave->playersBank[i] = sRecordedBattle_Players[i].bank;
+ battleSave->playersTrainerId[i] = sRecordedBattle_Players[i].trainerId;
+ }
+
+ battleSave->rngSeed = gRecordedBattleRngSeed;
+
+ if (sRecordedBattle_BattleFlags & BATTLE_TYPE_LINK)
+ {
+ battleSave->battleFlags = (sRecordedBattle_BattleFlags & ~(BATTLE_TYPE_LINK | BATTLE_TYPE_20));
+ battleSave->battleFlags |= BATTLE_TYPE_x2000000;
+
+ if (sRecordedBattle_BattleFlags & BATTLE_TYPE_WILD)
+ {
+ battleSave->battleFlags |= BATTLE_TYPE_x80000000;
+ }
+ else if (sRecordedBattle_BattleFlags & BATTLE_TYPE_MULTI)
+ {
+ switch (sRecordedBattle_Players[0].bank)
+ {
+ case 0:
+ case 2:
+ if (!(sRecordedBattle_Players[gUnknown_0203C7B4].bank & 1))
+ battleSave->battleFlags |= BATTLE_TYPE_x80000000;
+ break;
+ case 1:
+ case 3:
+ if ((sRecordedBattle_Players[gUnknown_0203C7B4].bank & 1))
+ battleSave->battleFlags |= BATTLE_TYPE_x80000000;
+ break;
+ }
+ }
+ }
+ else
+ {
+ battleSave->battleFlags = sRecordedBattle_BattleFlags;
+ }
+
+ battleSave->opponentA = gTrainerBattleOpponent_A;
+ battleSave->opponentB = gTrainerBattleOpponent_B;
+ battleSave->partnerId = gPartnerTrainerId;
+ battleSave->field_4FA = gUnknown_0203C7B4;
+ battleSave->field_4FC = gSaveBlock2Ptr->field_CA9_b;
+ battleSave->field_4FD = sUnknown_0203C7AE;
+ battleSave->field_4FE = sUnknown_0203C7AF;
+ battleSave->battleStyle = gSaveBlock2Ptr->optionsBattleStyle;
+ battleSave->textSpeed = gSaveBlock2Ptr->optionsTextSpeed;
+ battleSave->AI_scripts = sRecordedBattle_AI_Scripts;
+
+ /* Can't match it without proper knowledge of the Saveblock 2.
+ if (gTrainerBattleOpponent_A >= 300 && gTrainerBattleOpponent_A <= 399)
+ {
+ for (i = 0; i < 8; i++)
+ {
+ battleSave->field_504[i] = gSaveBlock2Ptr->field_738[gTrainerBattleOpponent_A - 300].field_4[i];
+ }
+ battleSave->field_50C = gSaveBlock2Ptr->field_738[gTrainerBattleOpponent_A - 300].field_1;
+
+ if (sUnknown_0203CCE8 == 1)
+ {
+ for (i = 0; i < 6; i++)
+ {
+ battleSave->field_50E[i] = gSaveBlock2Ptr->field_738[gTrainerBattleOpponent_A - 300].field_28[i];
+ }
+ }
+ else
+ {
+ for (i = 0; i < 6; i++)
+ {
+ battleSave->field_50E[i] = gSaveBlock2Ptr->field_738[gTrainerBattleOpponent_A - 300].field_1C[i];
+ }
+ }
+ battleSave->field_51A = gSaveBlock2Ptr->field_738[gTrainerBattleOpponent_A - 300].field_E4;
+ }
+ else if (gTrainerBattleOpponent_B >= 300 && gTrainerBattleOpponent_B <= 399)
+ {
+ for (i = 0; i < 8; i++)
+ {
+ battleSave->field_504[i] = gSaveBlock2Ptr->field_738[gTrainerBattleOpponent_B - 300].field_4[i];
+ }
+ battleSave->field_50C = gSaveBlock2Ptr->field_738[gTrainerBattleOpponent_B - 300].field_1;
+
+ if (sUnknown_0203CCE8 == 1)
+ {
+ for (i = 0; i < 6; i++)
+ {
+ battleSave->field_50E[i] = gSaveBlock2Ptr->field_738[gTrainerBattleOpponent_B - 300].field_28[i];
+ }
+ }
+ else
+ {
+ for (i = 0; i < 6; i++)
+ {
+ battleSave->field_50E[i] = gSaveBlock2Ptr->field_738[gTrainerBattleOpponent_B - 300].field_1C[i];
+ }
+ }
+ battleSave->field_51A = gSaveBlock2Ptr->field_738[gTrainerBattleOpponent_B - 300].field_E4;
+ }
+ else if (gPartnerTrainerId >= 300 && gPartnerTrainerId <= 399)
+ {
+ for (i = 0; i < 8; i++)
+ {
+ battleSave->field_504[i] = gSaveBlock2Ptr->field_738[gPartnerTrainerId - 300].field_4[i];
+ }
+ battleSave->field_50C = gSaveBlock2Ptr->field_738[gPartnerTrainerId - 300].field_1;
+
+ if (sUnknown_0203CCE8 == 1)
+ {
+ for (i = 0; i < 6; i++)
+ {
+ battleSave->field_50E[i] = gSaveBlock2Ptr->field_738[gPartnerTrainerId - 300].field_28[i];
+ }
+ }
+ else
+ {
+ for (i = 0; i < 6; i++)
+ {
+ battleSave->field_50E[i] = gSaveBlock2Ptr->field_738[gPartnerTrainerId - 300].field_1C[i];
+ }
+ }
+ battleSave->field_51A = gSaveBlock2Ptr->field_738[gPartnerTrainerId - 300].field_E4;
+ }
+
+ */
+}
+
+#else
+__attribute__((naked))
+u32 MoveRecordedBattleToSaveData(void)
+{
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ mov r7, r10\n\
+ mov r6, r9\n\
+ mov r5, r8\n\
+ push {r5-r7}\n\
+ sub sp, 0xC\n\
+ movs r0, 0\n\
+ str r0, [sp, 0x4]\n\
+ movs r0, 0xF8\n\
+ lsls r0, 4\n\
+ bl AllocZeroed\n\
+ adds r7, r0, 0\n\
+ movs r0, 0x80\n\
+ lsls r0, 5\n\
+ bl AllocZeroed\n\
+ str r0, [sp]\n\
+ movs r6, 0\n\
+_0818535E:\n\
+ movs r0, 0x64\n\
+ adds r4, r6, 0\n\
+ muls r4, r0\n\
+ adds r5, r7, r4\n\
+ ldr r1, =sSavedPlayerParty\n\
+ adds r1, r4, r1\n\
+ adds r0, r5, 0\n\
+ movs r2, 0x64\n\
+ bl memcpy\n\
+ movs r1, 0x96\n\
+ lsls r1, 2\n\
+ adds r5, r1\n\
+ ldr r0, =sSavedOpponentParty\n\
+ adds r4, r0\n\
+ adds r0, r5, 0\n\
+ adds r1, r4, 0\n\
+ movs r2, 0x64\n\
+ bl memcpy\n\
+ adds r6, 0x1\n\
+ cmp r6, 0x5\n\
+ ble _0818535E\n\
+ movs r6, 0\n\
+ ldr r2, =gSaveBlock2Ptr\n\
+ mov r9, r2\n\
+ movs r3, 0x9A\n\
+ lsls r3, 3\n\
+ adds r3, r7, r3\n\
+ str r3, [sp, 0x8]\n\
+ ldr r5, =sRecordedBattle_Players\n\
+ mov r8, r6\n\
+ mov r12, r6\n\
+ movs r4, 0x96\n\
+ lsls r4, 3\n\
+ adds r4, r7\n\
+ mov r10, r4\n\
+ ldr r0, =0x000004e4\n\
+ adds r4, r7, r0\n\
+_081853AC:\n\
+ lsls r1, r6, 3\n\
+ ldr r0, =sRecordedBattle_Players\n\
+ adds r0, 0x4\n\
+ mov r3, r8\n\
+ adds r2, r3, r0\n\
+ add r1, r10\n\
+ movs r3, 0x7\n\
+_081853BA:\n\
+ ldrb r0, [r2]\n\
+ strb r0, [r1]\n\
+ adds r2, 0x1\n\
+ adds r1, 0x1\n\
+ subs r3, 0x1\n\
+ cmp r3, 0\n\
+ bge _081853BA\n\
+ ldr r0, [sp, 0x8]\n\
+ adds r1, r0, r6\n\
+ ldrb r0, [r5, 0xC]\n\
+ strb r0, [r1]\n\
+ ldrh r0, [r5, 0x10]\n\
+ strb r0, [r4]\n\
+ ldrh r0, [r5, 0xE]\n\
+ strb r0, [r4, 0xC]\n\
+ ldr r1, =0x000004d4\n\
+ adds r0, r7, r1\n\
+ add r0, r12\n\
+ ldr r1, [r5]\n\
+ str r1, [r0]\n\
+ adds r5, 0x14\n\
+ movs r2, 0x14\n\
+ add r8, r2\n\
+ movs r3, 0x4\n\
+ add r12, r3\n\
+ adds r4, 0x1\n\
+ adds r6, 0x1\n\
+ cmp r6, 0x3\n\
+ ble _081853AC\n\
+ movs r4, 0x9D\n\
+ lsls r4, 3\n\
+ adds r1, r7, r4\n\
+ ldr r5, =gRecordedBattleRngSeed\n\
+ ldr r0, [r5]\n\
+ str r0, [r1]\n\
+ ldr r0, =sRecordedBattle_BattleFlags\n\
+ ldr r2, [r0]\n\
+ movs r0, 0x2\n\
+ ands r0, r2\n\
+ cmp r0, 0\n\
+ beq _081854DC\n\
+ ldr r1, =0x000004ec\n\
+ adds r3, r7, r1\n\
+ movs r1, 0x23\n\
+ negs r1, r1\n\
+ ands r1, r2\n\
+ movs r0, 0x80\n\
+ lsls r0, 18\n\
+ orrs r1, r0\n\
+ str r1, [r3]\n\
+ movs r0, 0x4\n\
+ ands r0, r2\n\
+ cmp r0, 0\n\
+ beq _08185454\n\
+ movs r0, 0x80\n\
+ lsls r0, 24\n\
+ orrs r1, r0\n\
+ str r1, [r3]\n\
+ b _081854E2\n\
+ .pool\n\
+_08185454:\n\
+ movs r0, 0x40\n\
+ ands r2, r0\n\
+ cmp r2, 0\n\
+ beq _081854E2\n\
+ ldr r2, =sRecordedBattle_Players\n\
+ ldrh r0, [r2, 0xE]\n\
+ cmp r0, 0x1\n\
+ beq _081854A8\n\
+ cmp r0, 0x1\n\
+ bgt _08185474\n\
+ cmp r0, 0\n\
+ beq _0818547E\n\
+ b _081854E2\n\
+ .pool\n\
+_08185474:\n\
+ cmp r0, 0x2\n\
+ beq _0818547E\n\
+ cmp r0, 0x3\n\
+ beq _081854A8\n\
+ b _081854E2\n\
+_0818547E:\n\
+ ldr r3, =gUnknown_0203C7B4\n\
+ ldrb r1, [r3]\n\
+ lsls r0, r1, 2\n\
+ adds r0, r1\n\
+ lsls r0, 2\n\
+ ldr r4, =sRecordedBattle_Players\n\
+ adds r0, r4\n\
+ ldrh r1, [r0, 0xE]\n\
+ movs r0, 0x1\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ bne _081854E2\n\
+ ldr r5, =0x000004ec\n\
+ adds r0, r7, r5\n\
+ b _081854C4\n\
+ .pool\n\
+_081854A8:\n\
+ ldr r0, =gUnknown_0203C7B4\n\
+ ldrb r1, [r0]\n\
+ lsls r0, r1, 2\n\
+ adds r0, r1\n\
+ lsls r0, 2\n\
+ ldr r1, =sRecordedBattle_Players\n\
+ adds r0, r1\n\
+ ldrh r1, [r0, 0xE]\n\
+ movs r0, 0x1\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ beq _081854E2\n\
+ ldr r2, =0x000004ec\n\
+ adds r0, r7, r2\n\
+_081854C4:\n\
+ ldr r1, [r0]\n\
+ movs r2, 0x80\n\
+ lsls r2, 24\n\
+ orrs r1, r2\n\
+ str r1, [r0]\n\
+ b _081854E2\n\
+ .pool\n\
+_081854DC:\n\
+ ldr r3, =0x000004ec\n\
+ adds r0, r7, r3\n\
+ str r2, [r0]\n\
+_081854E2:\n\
+ ldr r4, =gTrainerBattleOpponent_A\n\
+ ldrh r1, [r4]\n\
+ ldr r5, =0x000004f4\n\
+ adds r0, r7, r5\n\
+ strh r1, [r0]\n\
+ ldr r0, =gTrainerBattleOpponent_B\n\
+ ldrh r1, [r0]\n\
+ ldr r2, =0x000004f6\n\
+ adds r0, r7, r2\n\
+ strh r1, [r0]\n\
+ ldr r3, =gPartnerTrainerId\n\
+ ldrh r1, [r3]\n\
+ movs r4, 0x9F\n\
+ lsls r4, 3\n\
+ adds r0, r7, r4\n\
+ strh r1, [r0]\n\
+ ldr r5, =gUnknown_0203C7B4\n\
+ ldrb r1, [r5]\n\
+ adds r2, 0x4\n\
+ adds r0, r7, r2\n\
+ strh r1, [r0]\n\
+ mov r3, r9\n\
+ ldr r0, [r3]\n\
+ ldr r4, =0x00000ca9\n\
+ adds r0, r4\n\
+ ldrb r0, [r0]\n\
+ lsls r0, 30\n\
+ lsrs r0, 30\n\
+ ldr r5, =0x000004fc\n\
+ adds r1, r7, r5\n\
+ strb r0, [r1]\n\
+ ldr r0, =sUnknown_0203C7AE\n\
+ ldrb r1, [r0]\n\
+ adds r2, 0x3\n\
+ adds r0, r7, r2\n\
+ strb r1, [r0]\n\
+ ldr r3, =sUnknown_0203C7AF\n\
+ ldrb r1, [r3]\n\
+ ldr r4, =0x000004fe\n\
+ adds r0, r7, r4\n\
+ strb r1, [r0]\n\
+ mov r5, r9\n\
+ ldr r0, [r5]\n\
+ ldrb r1, [r0, 0x15]\n\
+ lsls r1, 29\n\
+ ldr r0, =0x000004ff\n\
+ adds r3, r7, r0\n\
+ lsrs r1, 31\n\
+ ldrb r2, [r3]\n\
+ movs r0, 0x2\n\
+ negs r0, r0\n\
+ ands r0, r2\n\
+ orrs r0, r1\n\
+ strb r0, [r3]\n\
+ ldr r1, [r5]\n\
+ ldrb r1, [r1, 0x14]\n\
+ lsls r1, 29\n\
+ lsrs r1, 28\n\
+ movs r2, 0xF\n\
+ negs r2, r2\n\
+ ands r0, r2\n\
+ orrs r0, r1\n\
+ strb r0, [r3]\n\
+ movs r2, 0xA0\n\
+ lsls r2, 3\n\
+ adds r1, r7, r2\n\
+ ldr r3, =sRecordedBattle_AI_Scripts\n\
+ ldr r0, [r3]\n\
+ str r0, [r1]\n\
+ ldr r4, =0xfffffed4\n\
+ adds r1, r4, 0\n\
+ ldr r5, =gTrainerBattleOpponent_A\n\
+ ldrh r5, [r5]\n\
+ adds r0, r1, r5\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ cmp r0, 0x63\n\
+ bls _08185580\n\
+ b _081856C4\n\
+_08185580:\n\
+ movs r6, 0\n\
+ ldr r0, =0x00000504\n\
+ adds r3, r7, r0\n\
+ mov r10, r9\n\
+ ldr r1, =gTrainerBattleOpponent_A\n\
+ mov r12, r1\n\
+ adds r2, r4, 0\n\
+ mov r8, r2\n\
+ ldr r4, =0x0000073c\n\
+_08185592:\n\
+ adds r2, r3, r6\n\
+ mov r5, r10\n\
+ ldr r1, [r5]\n\
+ mov r5, r12\n\
+ ldrh r0, [r5]\n\
+ add r0, r8\n\
+ movs r5, 0xEC\n\
+ muls r0, r5\n\
+ adds r0, r6, r0\n\
+ adds r1, r4\n\
+ adds r1, r0\n\
+ ldrb r0, [r1]\n\
+ strb r0, [r2]\n\
+ adds r6, 0x1\n\
+ cmp r6, 0x7\n\
+ ble _08185592\n\
+ mov r0, r9\n\
+ ldr r2, [r0]\n\
+ ldr r1, =gTrainerBattleOpponent_A\n\
+ ldrh r0, [r1]\n\
+ ldr r3, =0xfffffed4\n\
+ adds r0, r3\n\
+ movs r1, 0xEC\n\
+ muls r0, r1\n\
+ adds r2, r0\n\
+ ldr r4, =0x00000739\n\
+ adds r2, r4\n\
+ ldrb r1, [r2]\n\
+ ldr r5, =0x0000050c\n\
+ adds r0, r7, r5\n\
+ strb r1, [r0]\n\
+ ldr r1, =sUnknown_0203CCE8\n\
+ ldrb r0, [r1]\n\
+ cmp r0, 0x1\n\
+ bne _08185664\n\
+ movs r6, 0\n\
+ ldr r2, =0x0000050e\n\
+ adds r4, r7, r2\n\
+ mov r10, r9\n\
+ ldr r5, =gTrainerBattleOpponent_A\n\
+ mov r8, r5\n\
+ adds r5, r3, 0\n\
+_081855E6:\n\
+ lsls r3, r6, 1\n\
+ mov r0, r10\n\
+ ldr r2, [r0]\n\
+ mov r1, r8\n\
+ ldrh r0, [r1]\n\
+ adds r0, r5\n\
+ movs r1, 0xEC\n\
+ muls r0, r1\n\
+ adds r3, r0\n\
+ movs r0, 0xEC\n\
+ lsls r0, 3\n\
+ adds r2, r0\n\
+ adds r2, r3\n\
+ ldrh r0, [r2]\n\
+ strh r0, [r4]\n\
+ adds r4, 0x2\n\
+ adds r6, 0x1\n\
+ cmp r6, 0x5\n\
+ ble _081855E6\n\
+ b _08185696\n\
+ .pool\n\
+_08185664:\n\
+ movs r6, 0\n\
+ ldr r1, =0x0000050e\n\
+ adds r4, r7, r1\n\
+ mov r10, r9\n\
+ ldr r2, =gTrainerBattleOpponent_A\n\
+ mov r8, r2\n\
+ adds r5, r3, 0\n\
+_08185672:\n\
+ lsls r3, r6, 1\n\
+ mov r0, r10\n\
+ ldr r2, [r0]\n\
+ mov r1, r8\n\
+ ldrh r0, [r1]\n\
+ adds r0, r5\n\
+ movs r1, 0xEC\n\
+ muls r0, r1\n\
+ adds r3, r0\n\
+ ldr r0, =0x00000754\n\
+ adds r2, r0\n\
+ adds r2, r3\n\
+ ldrh r0, [r2]\n\
+ strh r0, [r4]\n\
+ adds r4, 0x2\n\
+ adds r6, 0x1\n\
+ cmp r6, 0x5\n\
+ ble _08185672\n\
+_08185696:\n\
+ mov r1, r9\n\
+ ldr r2, [r1]\n\
+ ldr r3, =gTrainerBattleOpponent_A\n\
+ ldrh r0, [r3]\n\
+ ldr r4, =0xfffffed4\n\
+ adds r0, r4\n\
+ movs r1, 0xEC\n\
+ muls r0, r1\n\
+ adds r2, r0\n\
+ ldr r5, =0x0000081c\n\
+ adds r2, r5\n\
+ ldrb r1, [r2]\n\
+ b _08185856\n\
+ .pool\n\
+_081856C4:\n\
+ ldr r3, =gTrainerBattleOpponent_B\n\
+ ldrh r3, [r3]\n\
+ adds r0, r1, r3\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ cmp r0, 0x63\n\
+ bls _081856D4\n\
+ b _081857E4\n\
+_081856D4:\n\
+ movs r6, 0\n\
+ ldr r4, =0x00000504\n\
+ adds r3, r7, r4\n\
+ mov r10, r9\n\
+ ldr r5, =gTrainerBattleOpponent_B\n\
+ mov r12, r5\n\
+ ldr r0, =0xfffffed4\n\
+ mov r8, r0\n\
+ ldr r4, =0x0000073c\n\
+_081856E6:\n\
+ adds r2, r3, r6\n\
+ mov r5, r10\n\
+ ldr r1, [r5]\n\
+ mov r5, r12\n\
+ ldrh r0, [r5]\n\
+ add r0, r8\n\
+ movs r5, 0xEC\n\
+ muls r0, r5\n\
+ adds r0, r6, r0\n\
+ adds r1, r4\n\
+ adds r1, r0\n\
+ ldrb r0, [r1]\n\
+ strb r0, [r2]\n\
+ adds r6, 0x1\n\
+ cmp r6, 0x7\n\
+ ble _081856E6\n\
+ mov r0, r9\n\
+ ldr r2, [r0]\n\
+ ldr r1, =gTrainerBattleOpponent_B\n\
+ ldrh r0, [r1]\n\
+ ldr r3, =0xfffffed4\n\
+ adds r0, r3\n\
+ movs r1, 0xEC\n\
+ muls r0, r1\n\
+ adds r2, r0\n\
+ ldr r4, =0x00000739\n\
+ adds r2, r4\n\
+ ldrb r1, [r2]\n\
+ ldr r5, =0x0000050c\n\
+ adds r0, r7, r5\n\
+ strb r1, [r0]\n\
+ ldr r1, =sUnknown_0203CCE8\n\
+ ldrb r0, [r1]\n\
+ cmp r0, 0x1\n\
+ bne _08185784\n\
+ movs r6, 0\n\
+ ldr r2, =0x0000050e\n\
+ adds r4, r7, r2\n\
+ mov r10, r9\n\
+ ldr r5, =gTrainerBattleOpponent_B\n\
+ mov r8, r5\n\
+ adds r5, r3, 0\n\
+_0818573A:\n\
+ lsls r3, r6, 1\n\
+ mov r0, r10\n\
+ ldr r2, [r0]\n\
+ mov r1, r8\n\
+ ldrh r0, [r1]\n\
+ adds r0, r5\n\
+ movs r1, 0xEC\n\
+ muls r0, r1\n\
+ adds r3, r0\n\
+ movs r0, 0xEC\n\
+ lsls r0, 3\n\
+ adds r2, r0\n\
+ adds r2, r3\n\
+ ldrh r0, [r2]\n\
+ strh r0, [r4]\n\
+ adds r4, 0x2\n\
+ adds r6, 0x1\n\
+ cmp r6, 0x5\n\
+ ble _0818573A\n\
+ b _081857B6\n\
+ .pool\n\
+_08185784:\n\
+ movs r6, 0\n\
+ ldr r1, =0x0000050e\n\
+ adds r4, r7, r1\n\
+ mov r10, r9\n\
+ ldr r2, =gTrainerBattleOpponent_B\n\
+ mov r8, r2\n\
+ adds r5, r3, 0\n\
+_08185792:\n\
+ lsls r3, r6, 1\n\
+ mov r0, r10\n\
+ ldr r2, [r0]\n\
+ mov r1, r8\n\
+ ldrh r0, [r1]\n\
+ adds r0, r5\n\
+ movs r1, 0xEC\n\
+ muls r0, r1\n\
+ adds r3, r0\n\
+ ldr r0, =0x00000754\n\
+ adds r2, r0\n\
+ adds r2, r3\n\
+ ldrh r0, [r2]\n\
+ strh r0, [r4]\n\
+ adds r4, 0x2\n\
+ adds r6, 0x1\n\
+ cmp r6, 0x5\n\
+ ble _08185792\n\
+_081857B6:\n\
+ mov r1, r9\n\
+ ldr r2, [r1]\n\
+ ldr r3, =gTrainerBattleOpponent_B\n\
+ ldrh r0, [r3]\n\
+ ldr r4, =0xfffffed4\n\
+ adds r0, r4\n\
+ movs r1, 0xEC\n\
+ muls r0, r1\n\
+ adds r2, r0\n\
+ ldr r5, =0x0000081c\n\
+ adds r2, r5\n\
+ ldrb r1, [r2]\n\
+ b _08185856\n\
+ .pool\n\
+_081857E4:\n\
+ ldr r3, =gPartnerTrainerId\n\
+ ldrh r3, [r3]\n\
+ adds r0, r1, r3\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ cmp r0, 0x63\n\
+ bhi _0818585C\n\
+ movs r6, 0\n\
+ ldr r4, =0x00000504\n\
+ adds r3, r7, r4\n\
+ mov r10, r9\n\
+ ldr r5, =gPartnerTrainerId\n\
+ mov r12, r5\n\
+ ldr r0, =0xfffffed4\n\
+ mov r8, r0\n\
+ ldr r4, =0x0000073c\n\
+_08185804:\n\
+ adds r2, r3, r6\n\
+ mov r5, r10\n\
+ ldr r1, [r5]\n\
+ mov r5, r12\n\
+ ldrh r0, [r5]\n\
+ add r0, r8\n\
+ movs r5, 0xEC\n\
+ muls r0, r5\n\
+ adds r0, r6, r0\n\
+ adds r1, r4\n\
+ adds r1, r0\n\
+ ldrb r0, [r1]\n\
+ strb r0, [r2]\n\
+ adds r6, 0x1\n\
+ cmp r6, 0x7\n\
+ ble _08185804\n\
+ mov r0, r9\n\
+ ldr r1, [r0]\n\
+ ldr r2, =gPartnerTrainerId\n\
+ ldrh r0, [r2]\n\
+ ldr r3, =0xfffffed4\n\
+ adds r0, r3\n\
+ movs r2, 0xEC\n\
+ muls r0, r2\n\
+ adds r1, r0\n\
+ ldr r4, =0x00000739\n\
+ adds r1, r4\n\
+ ldrb r1, [r1]\n\
+ ldr r5, =0x0000050c\n\
+ adds r0, r7, r5\n\
+ strb r1, [r0]\n\
+ mov r0, r9\n\
+ ldr r1, [r0]\n\
+ ldr r4, =gPartnerTrainerId\n\
+ ldrh r0, [r4]\n\
+ adds r0, r3\n\
+ muls r0, r2\n\
+ adds r1, r0\n\
+ ldr r5, =0x0000081c\n\
+ adds r1, r5\n\
+ ldrb r1, [r1]\n\
+_08185856:\n\
+ ldr r2, =0x0000051a\n\
+ adds r0, r7, r2\n\
+ strb r1, [r0]\n\
+_0818585C:\n\
+ ldr r3, =gTrainerBattleOpponent_A\n\
+ ldrh r0, [r3]\n\
+ ldr r1, =0x0000018f\n\
+ cmp r0, r1\n\
+ bls _08185900\n\
+ mov r4, r9\n\
+ ldr r2, [r4]\n\
+ adds r1, r0, 0\n\
+ ldr r3, =0xfffffe70\n\
+ adds r1, r3\n\
+ lsls r0, r1, 4\n\
+ adds r0, r1\n\
+ lsls r0, 2\n\
+ adds r2, r0\n\
+ adds r2, 0xDC\n\
+ ldrb r0, [r2]\n\
+ lsls r0, 27\n\
+ lsrs r0, 27\n\
+ ldr r5, =0x0000050d\n\
+ adds r1, r7, r5\n\
+ strb r0, [r1]\n\
+ movs r6, 0\n\
+ ldr r0, =0x0000050e\n\
+ adds r4, r7, r0\n\
+ mov r10, r9\n\
+ ldr r1, =gTrainerBattleOpponent_A\n\
+ mov r8, r1\n\
+ adds r5, r3, 0\n\
+_08185894:\n\
+ lsls r3, r6, 1\n\
+ mov r0, r10\n\
+ ldr r2, [r0]\n\
+ mov r0, r8\n\
+ ldrh r1, [r0]\n\
+ adds r1, r5\n\
+ lsls r0, r1, 4\n\
+ adds r0, r1\n\
+ lsls r0, 2\n\
+ adds r3, r0\n\
+ movs r1, 0x82\n\
+ lsls r1, 1\n\
+ adds r2, r1\n\
+ adds r2, r3\n\
+ ldrh r0, [r2]\n\
+ strh r0, [r4]\n\
+ adds r4, 0x2\n\
+ adds r6, 0x1\n\
+ cmp r6, 0x5\n\
+ ble _08185894\n\
+ mov r3, r9\n\
+ ldr r2, [r3]\n\
+ ldr r4, =gTrainerBattleOpponent_A\n\
+ ldrh r1, [r4]\n\
+ ldr r5, =0xfffffe70\n\
+ adds r1, r5\n\
+ b _081859AC\n\
+ .pool\n\
+_08185900:\n\
+ ldr r3, =gTrainerBattleOpponent_B\n\
+ ldrh r0, [r3]\n\
+ cmp r0, r1\n\
+ bls _0818597C\n\
+ mov r4, r9\n\
+ ldr r2, [r4]\n\
+ adds r1, r0, 0\n\
+ ldr r3, =0xfffffe70\n\
+ adds r1, r3\n\
+ lsls r0, r1, 4\n\
+ adds r0, r1\n\
+ lsls r0, 2\n\
+ adds r2, r0\n\
+ adds r2, 0xDC\n\
+ ldrb r0, [r2]\n\
+ lsls r0, 27\n\
+ lsrs r0, 27\n\
+ ldr r5, =0x0000050d\n\
+ adds r1, r7, r5\n\
+ strb r0, [r1]\n\
+ movs r6, 0\n\
+ ldr r0, =0x0000050e\n\
+ adds r4, r7, r0\n\
+ mov r10, r9\n\
+ ldr r1, =gTrainerBattleOpponent_B\n\
+ mov r8, r1\n\
+ adds r5, r3, 0\n\
+_08185936:\n\
+ lsls r3, r6, 1\n\
+ mov r0, r10\n\
+ ldr r2, [r0]\n\
+ mov r0, r8\n\
+ ldrh r1, [r0]\n\
+ adds r1, r5\n\
+ lsls r0, r1, 4\n\
+ adds r0, r1\n\
+ lsls r0, 2\n\
+ adds r3, r0\n\
+ movs r1, 0x82\n\
+ lsls r1, 1\n\
+ adds r2, r1\n\
+ adds r2, r3\n\
+ ldrh r0, [r2]\n\
+ strh r0, [r4]\n\
+ adds r4, 0x2\n\
+ adds r6, 0x1\n\
+ cmp r6, 0x5\n\
+ ble _08185936\n\
+ mov r3, r9\n\
+ ldr r2, [r3]\n\
+ ldr r4, =gTrainerBattleOpponent_B\n\
+ ldrh r1, [r4]\n\
+ ldr r5, =0xfffffe70\n\
+ adds r1, r5\n\
+ b _081859AC\n\
+ .pool\n\
+_0818597C:\n\
+ ldr r3, =gPartnerTrainerId\n\
+ ldrh r0, [r3]\n\
+ cmp r0, r1\n\
+ bls _081859C0\n\
+ mov r4, r9\n\
+ ldr r2, [r4]\n\
+ adds r1, r0, 0\n\
+ ldr r3, =0xfffffe70\n\
+ adds r1, r3\n\
+ lsls r0, r1, 4\n\
+ adds r0, r1\n\
+ lsls r0, 2\n\
+ adds r2, r0\n\
+ adds r2, 0xDC\n\
+ ldrb r0, [r2]\n\
+ lsls r0, 27\n\
+ lsrs r0, 27\n\
+ ldr r5, =0x0000050d\n\
+ adds r1, r7, r5\n\
+ strb r0, [r1]\n\
+ ldr r2, [r4]\n\
+ ldr r0, =gPartnerTrainerId\n\
+ ldrh r1, [r0]\n\
+ adds r1, r3\n\
+_081859AC:\n\
+ lsls r0, r1, 4\n\
+ adds r0, r1\n\
+ lsls r0, 2\n\
+ adds r2, r0\n\
+ ldr r1, =0x0000011b\n\
+ adds r0, r2, r1\n\
+ ldrb r1, [r0]\n\
+ ldr r2, =0x0000051b\n\
+ adds r0, r7, r2\n\
+ strb r1, [r0]\n\
+_081859C0:\n\
+ movs r6, 0\n\
+ ldr r3, =0x00000297\n\
+ mov r10, r3\n\
+ ldr r4, =sBattleRecords\n\
+ mov r9, r4\n\
+ movs r5, 0xA6\n\
+ lsls r5, 2\n\
+ mov r8, r5\n\
+ ldr r0, =0x0000051c\n\
+ adds r5, r7, r0\n\
+_081859D4:\n\
+ adds r4, r6, 0x1\n\
+ mov r0, r8\n\
+ muls r0, r6\n\
+ mov r1, r9\n\
+ adds r2, r0, r1\n\
+ adds r1, r0, r5\n\
+ mov r3, r10\n\
+ adds r3, 0x1\n\
+_081859E4:\n\
+ ldrb r0, [r2]\n\
+ strb r0, [r1]\n\
+ adds r2, 0x1\n\
+ adds r1, 0x1\n\
+ subs r3, 0x1\n\
+ cmp r3, 0\n\
+ bne _081859E4\n\
+ adds r6, r4, 0\n\
+ cmp r6, 0x3\n\
+ ble _081859D4\n\
+_081859F8:\n\
+ adds r0, r7, 0\n\
+ ldr r1, [sp]\n\
+ bl sub_81852F0\n\
+ adds r4, r0, 0\n\
+ cmp r4, 0x1\n\
+ beq _08185A14\n\
+ ldr r0, [sp, 0x4]\n\
+ adds r0, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ str r0, [sp, 0x4]\n\
+ cmp r0, 0x2\n\
+ bls _081859F8\n\
+_08185A14:\n\
+ adds r0, r7, 0\n\
+ bl Free\n\
+ ldr r0, [sp]\n\
+ bl Free\n\
+ adds r0, r4, 0\n\
+ add sp, 0xC\n\
+ pop {r3-r5}\n\
+ mov r8, r3\n\
+ mov r9, r4\n\
+ mov r10, r5\n\
+ pop {r4-r7}\n\
+ pop {r1}\n\
+ bx r1\n\
+ .pool\n\
+ .syntax divided");
+}
+#endif // NONMATCHING
+
+static bool32 TryCopyRecordedBattleSaveData(struct RecordedBattleSave *dst, struct SaveSection *saveBuffer)
+{
+ if (TryCopySpecialSaveSection(SECTION_ID_RECORDED_BATTLE, (void*)(saveBuffer)) != 1)
+ return FALSE;
+
+ memcpy(dst, saveBuffer, sizeof(struct RecordedBattleSave));
+
+ if (!IsRecordedBattleSaveValid(dst))
+ return FALSE;
+
+ return TRUE;
+}
+
+static bool32 AllocTryCopyRecordedBattleSaveData(struct RecordedBattleSave *dst)
+{
+ struct SaveSection *savBuffer = AllocZeroed(sizeof(struct SaveSection));
+ bool32 ret = TryCopyRecordedBattleSaveData(dst, savBuffer);
+ Free(savBuffer);
+
+ return ret;
+}
+
+static void CB2_RecordedBattleEnd(void)
+{
+ gSaveBlock2Ptr->frontierChosenLvl = sUnknown_0203C7AD;
+ gBattleOutcome = 0;
+ gBattleTypeFlags = 0;
+ gTrainerBattleOpponent_A = 0;
+ gTrainerBattleOpponent_B = 0;
+ gPartnerTrainerId = 0;
+
+ RecordedBattle_RestoreSavedParties();
+ SetMainCallback2(sCallback2_AfterRecordedBattle);
+}
+
+#define tFramesToWait data[0]
+
+static void Task_StartAfterCountdown(u8 taskId)
+{
+ if (--gTasks[taskId].tFramesToWait == 0)
+ {
+ gMain.savedCallback = CB2_RecordedBattleEnd;
+ SetMainCallback2(CB2_InitBattle);
+ DestroyTask(taskId);
+ }
+}
+
+static void SetRecordedBattleVarsFromSave(struct RecordedBattleSave *src)
+{
+ bool8 var;
+ s32 i, j;
+
+ ZeroPlayerPartyMons();
+ ZeroEnemyPartyMons();
+
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ gPlayerParty[i] = src->playerParty[i];
+ gEnemyParty[i] = src->opponentParty[i];
+ }
+
+ for (i = 0; i < BATTLE_BANKS_COUNT; i++)
+ {
+ for (var = FALSE, j = 0; j < PLAYER_NAME_LENGTH; j++)
+ {
+ gLinkPlayers[i].name[j] = src->playersName[i][j];
+ if (src->playersName[i][j] == EOS)
+ var = TRUE;
+ }
+ gLinkPlayers[i].gender = src->playersGender[i];
+ gLinkPlayers[i].language = src->playersLanguage[i];
+ gLinkPlayers[i].lp_field_18 = src->playersBank[i];
+ gLinkPlayers[i].trainerId = src->playersTrainerId[i];
+
+ if (var)
+ ConvertInternationalString(gLinkPlayers[i].name, gLinkPlayers[i].language);
+ }
+
+ gRecordedBattleRngSeed = src->rngSeed;
+ gBattleTypeFlags = src->battleFlags | BATTLE_TYPE_RECORDED;
+ gTrainerBattleOpponent_A = src->opponentA;
+ gTrainerBattleOpponent_B = src->opponentB;
+ gPartnerTrainerId = src->partnerId;
+ gUnknown_0203C7B4 = src->field_4FA;
+ sUnknown_0203C7AD = gSaveBlock2Ptr->frontierChosenLvl;
+ sUnknown_0203C7AE = src->field_4FD;
+ sUnknown_0203C7AF = src->field_4FE;
+ sRecordedBattle_BattleStyle = src->battleStyle;
+ sRecordedBattle_TextSpeed = src->textSpeed;
+ sRecordedBattle_AI_Scripts = src->AI_scripts;
+
+ for (i = 0; i < 8; i++)
+ {
+ sUnknown_0203CCD1[i] = src->field_504[i];
+ }
+
+ sUnknown_0203CCD9 = src->field_50C;
+ sUnknown_0203CCDA = src->field_50D;
+ gUnknown_03001278 = src->field_51A;
+ gUnknown_03001279 = src->field_51B;
+
+ for (i = 0; i < 6; i++)
+ {
+ sUnknown_0203CCDC[i] = src->field_50E[i];
+ }
+
+ gSaveBlock2Ptr->frontierChosenLvl = src->field_4FC;
+
+ for (i = 0; i < BATTLE_BANKS_COUNT; i++)
+ {
+ for (j = 0; j < BANK_RECORD_SIZE; j++)
+ {
+ sBattleRecords[i][j] = src->battleRecord[i][j];
+ }
+ }
+}
+
+void PlayRecordedBattle(void (*CB2_After)(void))
+{
+ struct RecordedBattleSave *battleSave = AllocZeroed(sizeof(struct RecordedBattleSave));
+ if (AllocTryCopyRecordedBattleSaveData(battleSave) == TRUE)
+ {
+ u8 taskId;
+
+ RecordedBattle_SaveParties();
+ SetRecordedBattleVarsFromSave(battleSave);
+
+ taskId = CreateTask(Task_StartAfterCountdown, 1);
+ gTasks[taskId].tFramesToWait = 128;
+
+ sCallback2_AfterRecordedBattle = CB2_After;
+ PlayMapChosenOrBattleBGM(FALSE);
+ SetMainCallback2(CB2_RecordedBattle);
+ }
+ Free(battleSave);
+}
+
+#undef tFramesToWait
+
+static void CB2_RecordedBattle(void)
+{
+ AnimateSprites();
+ BuildOamBuffer();
+ RunTasks();
+}
+
+u8 sub_8185EA0(void)
+{
+ return sUnknown_0203C7AE;
+}
+
+u8 sub_8185EAC(void)
+{
+ return sUnknown_0203C7AF;
+}
+
+void RecordedBattle_SaveParties(void)
+{
+ s32 i;
+
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ sSavedPlayerParty[i] = gPlayerParty[i];
+ sSavedOpponentParty[i] = gEnemyParty[i];
+ }
+}
+
+static void RecordedBattle_RestoreSavedParties(void)
+{
+ s32 i;
+
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ gPlayerParty[i] = sSavedPlayerParty[i];
+ gEnemyParty[i] = sSavedOpponentParty[i];
+ }
+}
+
+u8 GetActiveBankLinkPlayerGender(void)
+{
+ s32 i;
+
+ for (i = 0; i < MAX_LINK_PLAYERS; i++)
+ {
+ if (gLinkPlayers[i].lp_field_18 == gActiveBank)
+ break;
+ }
+
+ if (i != MAX_LINK_PLAYERS)
+ return gLinkPlayers[i].gender;
+
+ return 0;
+}
+
+void sub_8185F84(void)
+{
+ sUnknown_0203C7B5 = 0;
+}
+
+void sub_8185F90(u16 arg0)
+{
+ sUnknown_0203C7B5 |= (arg0 & 0x8000) >> 0xF;
+}
+
+u8 sub_8185FAC(void)
+{
+ return sUnknown_0203C7B5;
+}
+
+u8 GetBattleStyleInRecordedBattle(void)
+{
+ return sRecordedBattle_BattleStyle;
+}
+
+u8 GetTextSpeedInRecordedBattle(void)
+{
+ return sRecordedBattle_TextSpeed;
+}
+
+void RecordedBattle_CopyBankMoves(void)
+{
+ s32 i;
+
+ if (GetBankSide(gActiveBank) == SIDE_OPPONENT)
+ return;
+ if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000))
+ return;
+ if (sUnknown_0203C7AC == 2)
+ return;
+
+ for (i = 0; i < 4; i++)
+ {
+ sRecordedBattle_PlayerMonMoves[gActiveBank / 2][i] = gBattleMons[gActiveBank].moves[i];
+ }
+}
+
+#define ACTION_MOVE_CHANGE 6
+
+void sub_818603C(u8 arg0)
+{
+ s32 bank, j, k;
+
+ if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000))
+ return;
+
+ for (bank = 0; bank < gNoOfAllBanks; bank++)
+ {
+ if (GetBankSide(bank) != 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])
+ break;
+ }
+ if (j != 4) // player's mon's move has been changed
+ {
+ RecordedBattle_SetBankAction(bank, 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])
+ {
+ RecordedBattle_SetBankAction(bank, k);
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if (sBattleRecords[bank][sRecordedBytesNo[bank]] == ACTION_MOVE_CHANGE)
+ {
+ u8 ppBonuses[4];
+ u8 array1[4];
+ u8 array2[4];
+ struct MovePp movePp;
+ u8 array3[8];
+ u8 var;
+
+ RecordedBattle_ReadBankAction(bank);
+ for (j = 0; j < 4; j++)
+ {
+ ppBonuses[j] = ((gBattleMons[bank].ppBonuses & ((3 << (j << 1)))) >> (j << 1));
+ }
+ for (j = 0; j < 4; j++)
+ {
+ array1[j] = RecordedBattle_ReadBankAction(bank);
+ movePp.moves[j] = gBattleMons[bank].moves[array1[j]];
+ movePp.pp[j] = gBattleMons[bank].pp[array1[j]];
+ array3[j] = ppBonuses[array1[j]];
+ array2[j] = (gDisableStructs[bank].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[bank].ppBonuses = 0;
+ gDisableStructs[bank].unk18_b = 0;
+ for (j = 0; j < 4; j++)
+ {
+ gBattleMons[bank].ppBonuses |= (array3[j]) << (j << 1);
+ gDisableStructs[bank].unk18_b |= (array2[j]) << (j);
+ }
+
+ if (!(gBattleMons[bank].status2 & STATUS2_TRANSFORMED))
+ {
+ for (j = 0; j < 4; j++)
+ {
+ ppBonuses[j] = ((GetMonData(&gPlayerParty[gBattlePartyID[bank]], MON_DATA_PP_BONUSES, NULL) & ((3 << (j << 1)))) >> (j << 1));
+ }
+ for (j = 0; j < 4; j++)
+ {
+ movePp.moves[j] = GetMonData(&gPlayerParty[gBattlePartyID[bank]], MON_DATA_MOVE1 + array1[j], NULL);
+ movePp.pp[j] = GetMonData(&gPlayerParty[gBattlePartyID[bank]], MON_DATA_PP1 + array1[j], NULL);
+ array3[j] = ppBonuses[array1[j]];
+ }
+ for (j = 0; j < 4; j++)
+ {
+ SetMonData(&gPlayerParty[gBattlePartyID[bank]], MON_DATA_MOVE1 + j, &movePp.moves[j]);
+ SetMonData(&gPlayerParty[gBattlePartyID[bank]], MON_DATA_PP1 + j, &movePp.pp[j]);
+ }
+ var = 0;
+ for (j = 0; j < 4; j++)
+ {
+ var |= (array3[j]) << (j << 1);
+ }
+ SetMonData(&gPlayerParty[gBattlePartyID[bank]], MON_DATA_PP_BONUSES, &var);
+ }
+
+ gChosenMovesByBanks[bank] = gBattleMons[bank].moves[*(gBattleStruct->chosenMovePositions + bank)];
+ }
+ }
+ }
+ }
+}
+
+u32 GetAiScriptsInRecordedBattle(void)
+{
+ return sRecordedBattle_AI_Scripts;
+}
+
+void sub_8186444(void)
+{
+ sUnknown_0203CCD0 = 1;
+}
+
+bool8 sub_8186450(void)
+{
+ return (sUnknown_0203CCD0 == 0);
+}
+
+void sub_8186468(u8 *dst)
+{
+ s32 i;
+
+ for (i = 0; i < 8; i++)
+ dst[i] = sUnknown_0203CCD1[i];
+
+ dst[7] = EOS;
+ ConvertInternationalString(dst, gUnknown_03001278);
+}
+
+u8 sub_818649C(void)
+{
+ return sUnknown_0203CCD9;
+}
+
+u8 sub_81864A8(void)
+{
+ return sUnknown_0203CCDA;
+}
+
+u8 sub_81864B4(void)
+{
+ return gUnknown_03001278;
+}
+
+u8 sub_81864C0(void)
+{
+ return gUnknown_03001279;
+}
+
+void sub_81864CC(void)
+{
+ sUnknown_0203CCE8 = gBattleOutcome;
+}
+
+u16 *sub_81864E0(void)
+{
+ return sUnknown_0203CCDC;
+}
diff --git a/src/region_map.c b/src/region_map.c
new file mode 100644
index 000000000..da96475c0
--- /dev/null
+++ b/src/region_map.c
@@ -0,0 +1,1949 @@
+
+// Includes
+#include "global.h"
+#include "main.h"
+#include "menu.h"
+#include "malloc.h"
+#include "gpu_regs.h"
+#include "palette.h"
+#include "party_menu.h"
+#include "trig.h"
+#include "map_constants.h"
+#include "overworld.h"
+#include "flags.h"
+#include "event_data.h"
+#include "rom6.h"
+#include "secret_base.h"
+#include "string_util.h"
+#include "international_string_util.h"
+#include "strings.h"
+#include "text.h"
+#include "text_window.h"
+#include "songs.h"
+#include "m4a.h"
+#include "field_effect.h"
+#include "region_map.h"
+
+#define MAP_WIDTH 28
+#define MAP_HEIGHT 15
+#define MAPCURSOR_X_MIN 1
+#define MAPCURSOR_Y_MIN 2
+#define MAPCURSOR_X_MAX (MAPCURSOR_X_MIN + MAP_WIDTH - 1)
+#define MAPCURSOR_Y_MAX (MAPCURSOR_Y_MIN + MAP_HEIGHT - 1)
+
+// Static type declarations
+
+struct RegionMapLocation
+{
+ u8 x;
+ u8 y;
+ u8 width;
+ u8 height;
+ const u8 *name;
+};
+
+// Static RAM declarations
+
+static EWRAM_DATA struct RegionMap *gRegionMap = NULL;
+static EWRAM_DATA struct {
+ /*0x000*/ void (*unk_000)(void);
+ /*0x004*/ u16 unk_004;
+ /*0x006*/ u16 mapSecId;
+ /*0x008*/ struct RegionMap regionMap;
+ /*0x88c*/ u8 unk_88c[0x1c0];
+ /*0xa4c*/ u8 unk_a4c[0x26];
+ /*0xa72*/ bool8 unk_a72;
+} *gUnknown_0203A148 = NULL; // a74
+
+static bool32 gUnknown_03001180;
+static bool32 gUnknown_03001184;
+
+// Static ROM declarations
+
+static u8 ProcessRegionMapInput_Full(void);
+static u8 MoveRegionMapCursor_Full(void);
+static u8 ProcessRegionMapInput_Zoomed(void);
+static u8 MoveRegionMapCursor_Zoomed(void);
+static void CalcZoomScrollParams(s16 scrollX, s16 scrollY, s16 c, s16 d, u16 e, u16 f, u8 rotation);
+static u16 GetRegionMapSectionIdAt_Internal(u16 x, u16 y);
+static void RegionMap_SetBG2XAndBG2Y(s16 x, s16 y);
+static void RegionMap_InitializeStateBasedOnPlayerLocation(void);
+static void RegionMap_InitializeStateBasedOnSSTidalLocation(void);
+static u8 get_flagnr_blue_points(u16 mapSecId);
+static u16 CorrectSpecialMapSecId_Internal(u16 mapSecId);
+static u16 RegionMap_GetTerraCaveMapSecId(void);
+static void RegionMap_GetMarineCaveCoords(u16 *x, u16 *y);
+static bool32 RegionMap_IsPlayerInCave(u8 mapSecId);
+static void RegionMap_GetPositionOfCursorWithinMapSection(void);
+static bool8 RegionMap_IsMapSecIdInNextRow(u16 y);
+static void SpriteCallback_CursorFull(struct Sprite *sprite);
+static void FreeRegionMapCursorSprite(void);
+static void HideRegionMapPlayerIcon(void);
+static void UnhideRegionMapPlayerIcon(void);
+static void RegionMapPlayerIconSpriteCallback_Zoomed(struct Sprite *sprite);
+static void RegionMapPlayerIconSpriteCallback_Full(struct Sprite *sprite);
+static void RegionMapPlayerIconSpriteCallback(struct Sprite *sprite);
+static void sub_81248C0(void);
+static void sub_81248D4(void);
+static void sub_81248F4(void callback(void));
+static void sub_8124904(void);
+static void sub_8124A70(void);
+static void sub_8124AD4(void);
+static void sub_8124BE4(void);
+static void sub_8124CBC(struct Sprite *sprite);
+static void sub_8124D14(void);
+static void sub_8124D64(void);
+static void sub_8124E0C(void);
+
+// .rodata
+
+static const u16 sRegionMapCursorPal[] = INCBIN_U16("graphics/pokenav/cursor.gbapal");
+static const u8 sRegionMapCursorSmallGfxLZ[] = INCBIN_U8("graphics/pokenav/cursor_small.4bpp.lz");
+static const u8 sRegionMapCursorLargeGfxLZ[] = INCBIN_U8("graphics/pokenav/cursor_large.4bpp.lz");
+static const u16 sRegionMapBkgnd_Pal[] = INCBIN_U16("graphics/pokenav/region_map.gbapal");
+static const u8 sRegionMapBkgnd_GfxLZ[] = INCBIN_U8("graphics/pokenav/region_map.8bpp.lz");
+static const u8 sRegionMapBkgnd_TilemapLZ[] = INCBIN_U8("graphics/pokenav/region_map_map.bin.lz");
+static const u16 sRegionMapPlayerIcon_BrendanPal[] = INCBIN_U16("graphics/pokenav/brendan_icon.gbapal");
+static const u8 sRegionMapPlayerIcon_BrendanGfx[] = INCBIN_U8("graphics/pokenav/brendan_icon.4bpp");
+static const u16 sRegionMapPlayerIcon_MayPal[] = INCBIN_U16("graphics/pokenav/may_icon.gbapal");
+static const u8 sRegionMapPlayerIcon_MayGfx[] = INCBIN_U8("graphics/pokenav/may_icon.4bpp");
+
+static const u8 sRegionMap_MapSectionLayout[] = INCBIN_U8("graphics/pokenav/region_map_section_layout.bin");
+
+#include "data/region_map/region_map_entries.h"
+
+static const u16 sRegionMap_SpecialPlaceLocations[][2] = {
+ {MAPSEC_UNDERWATER_TERRA_CAVE, MAPSEC_ROUTE_105},
+ {MAPSEC_UNDERWATER_124, MAPSEC_ROUTE_124},
+ {MAPSEC_UNDERWATER_UNK1, MAPSEC_ROUTE_129},
+ {MAPSEC_UNDERWATER_125, MAPSEC_ROUTE_126},
+ {MAPSEC_UNDERWATER_126, MAPSEC_ROUTE_127},
+ {MAPSEC_UNDERWATER_127, MAPSEC_ROUTE_128},
+ {MAPSEC_UNDERWATER_129, MAPSEC_ROUTE_129},
+ {MAPSEC_UNDERWATER_SOOTOPOLIS, MAPSEC_SOOTOPOLIS_CITY},
+ {MAPSEC_UNDERWATER_128, MAPSEC_ROUTE_128},
+ {MAPSEC_AQUA_HIDEOUT, MAPSEC_LILYCOVE_CITY},
+ {MAPSEC_AQUA_HIDEOUT_OLD, MAPSEC_LILYCOVE_CITY},
+ {MAPSEC_MAGMA_HIDEOUT, MAPSEC_ROUTE_112},
+ {MAPSEC_UNDERWATER_SEALED_CHAMBER, MAPSEC_ROUTE_134},
+ {MAPSEC_PETALBURG_WOODS, MAPSEC_ROUTE_104},
+ {MAPSEC_JAGGED_PASS, MAPSEC_ROUTE_112},
+ {MAPSEC_MT_PYRE, MAPSEC_ROUTE_122},
+ {MAPSEC_SKY_PILLAR, MAPSEC_ROUTE_131},
+ {MAPSEC_MIRAGE_TOWER, MAPSEC_ROUTE_111},
+ {MAPSEC_TRAINER_HILL, MAPSEC_ROUTE_111},
+ {MAPSEC_DESERT_UNDERPASS, MAPSEC_ROUTE_114},
+ {MAPSEC_ALTERING_CAVE_2, MAPSEC_ROUTE_103},
+ {MAPSEC_ARTISAN_CAVE, MAPSEC_ROUTE_103},
+ {MAPSEC_ABANDONED_SHIP, MAPSEC_ROUTE_108},
+ {MAPSEC_NONE, MAPSEC_NONE}
+};
+
+static const u16 sRegionMap_MarineCaveMapSecIds[] = {
+ MAPSEC_MARINE_CAVE,
+ MAPSEC_UNDERWATER_MARINE_CAVE,
+ MAPSEC_UNDERWATER_MARINE_CAVE
+};
+
+static const u16 sTerraCaveMapSectionIds[] = {
+ MAPSEC_ROUTE_114,
+ MAPSEC_ROUTE_114,
+ MAPSEC_ROUTE_115,
+ MAPSEC_ROUTE_115,
+ MAPSEC_ROUTE_116,
+ MAPSEC_ROUTE_116,
+ MAPSEC_ROUTE_118,
+ MAPSEC_ROUTE_118,
+ MAPSEC_ROUTE_105,
+ MAPSEC_ROUTE_105,
+ MAPSEC_ROUTE_125,
+ MAPSEC_ROUTE_125,
+ MAPSEC_ROUTE_127,
+ MAPSEC_ROUTE_127,
+ MAPSEC_ROUTE_129,
+ MAPSEC_ROUTE_129
+};
+
+static const struct UCoords16 sTerraCaveLocationCoords[] = {
+ {0x00, 0x0a},
+ {0x00, 0x0c},
+ {0x18, 0x03},
+ {0x19, 0x04},
+ {0x19, 0x06},
+ {0x19, 0x07},
+ {0x18, 0x0a},
+ {0x18, 0x0a}
+};
+
+static const u8 sRegionMap_MapSecAquaHideoutOld[] = {
+ MAPSEC_AQUA_HIDEOUT_OLD
+};
+
+static const struct OamData sRegionMapCursorOam = {
+ .size = 1, .priority = 1
+};
+
+static const union AnimCmd sRegionMapCursorAnim1[] = {
+ ANIMCMD_FRAME(0, 20),
+ ANIMCMD_FRAME(4, 20),
+ ANIMCMD_JUMP(0)
+};
+
+static const union AnimCmd sRegionMapCursorAnim2[] = {
+ ANIMCMD_FRAME( 0, 10),
+ ANIMCMD_FRAME(16, 10),
+ ANIMCMD_FRAME(32, 10),
+ ANIMCMD_FRAME(16, 10),
+ ANIMCMD_JUMP(0)
+};
+
+static const union AnimCmd *const sRegionMapCursorAnimTable[] = {
+ sRegionMapCursorAnim1,
+ sRegionMapCursorAnim2
+};
+
+static const struct SpritePalette sRegionMapCursorSpritePalette = { sRegionMapCursorPal, 0 };
+
+static const struct SpriteTemplate sRegionMapCursorSpriteTemplate = {
+ 0,
+ 0,
+ &sRegionMapCursorOam,
+ sRegionMapCursorAnimTable,
+ NULL,
+ gDummySpriteAffineAnimTable,
+ SpriteCallback_CursorFull
+};
+
+static const struct OamData sRegionMapPlayerIconOam = {
+ .size = 1, .priority = 2
+};
+
+static const union AnimCmd sRegionMapPlayerIconAnim1[] = {
+ ANIMCMD_FRAME(0, 5),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sRegionMapPlayerIconAnimTable[] = {
+ sRegionMapPlayerIconAnim1
+};
+
+static const u8 sRegionMapEventSectionIds[] = {
+ MAPSEC_BIRTH_ISLAND_2,
+ MAPSEC_FARAWAY_ISLAND,
+ MAPSEC_NAVEL_ROCK2
+};
+
+static const u16 sRegionMapFramePal[] = INCBIN_U16("graphics/pokenav/map_frame.gbapal");
+
+static const u8 sRegionMapFrameGfxLZ[] = INCBIN_U8("graphics/pokenav/map_frame.4bpp.lz");
+
+static const u8 sRegionMapFrameTilemapLZ[] = INCBIN_U8("graphics/pokenav/map_frame.bin.lz");
+
+static const u16 Unknown_085A1D48[] = INCBIN_U16("graphics/pokenav/fly_target_icons.gbapal");
+
+static const u8 gUnknown_085A1D68[] = INCBIN_U8("graphics/pokenav/fly_target_icons.4bpp.lz");
+
+static const u8 gUnknown_085A1E3C[][3] = {
+ {MAP_GROUP_LITTLEROOT_TOWN, MAP_ID_LITTLEROOT_TOWN, 1},
+ {MAP_GROUP_OLDALE_TOWN, MAP_ID_OLDALE_TOWN, 14},
+ {MAP_GROUP_DEWFORD_TOWN, MAP_ID_DEWFORD_TOWN, 15},
+ {MAP_GROUP_LAVARIDGE_TOWN, MAP_ID_LAVARIDGE_TOWN, 16},
+ {MAP_GROUP_FALLARBOR_TOWN, MAP_ID_FALLARBOR_TOWN, 17},
+ {MAP_GROUP_VERDANTURF_TOWN, MAP_ID_VERDANTURF_TOWN, 18},
+ {MAP_GROUP_PACIFIDLOG_TOWN, MAP_ID_PACIFIDLOG_TOWN, 19},
+ {MAP_GROUP_PETALBURG_CITY, MAP_ID_PETALBURG_CITY, 3},
+ {MAP_GROUP_SLATEPORT_CITY, MAP_ID_SLATEPORT_CITY, 4},
+ {MAP_GROUP_MAUVILLE_CITY, MAP_ID_MAUVILLE_CITY, 5},
+ {MAP_GROUP_RUSTBORO_CITY, MAP_ID_RUSTBORO_CITY, 6},
+ {MAP_GROUP_FORTREE_CITY, MAP_ID_FORTREE_CITY, 7},
+ {MAP_GROUP_LILYCOVE_CITY, MAP_ID_LILYCOVE_CITY, 8},
+ {MAP_GROUP_MOSSDEEP_CITY, MAP_ID_MOSSDEEP_CITY, 9},
+ {MAP_GROUP_SOOTOPOLIS_CITY, MAP_ID_SOOTOPOLIS_CITY, 10},
+ {MAP_GROUP_EVER_GRANDE_CITY, MAP_ID_EVER_GRANDE_CITY, 11},
+ {MAP_GROUP_ROUTE101, MAP_ID_ROUTE101, 0},
+ {MAP_GROUP_ROUTE102, MAP_ID_ROUTE102, 0},
+ {MAP_GROUP_ROUTE103, MAP_ID_ROUTE103, 0},
+ {MAP_GROUP_ROUTE104, MAP_ID_ROUTE104, 0},
+ {MAP_GROUP_ROUTE105, MAP_ID_ROUTE105, 0},
+ {MAP_GROUP_ROUTE106, MAP_ID_ROUTE106, 0},
+ {MAP_GROUP_ROUTE107, MAP_ID_ROUTE107, 0},
+ {MAP_GROUP_ROUTE108, MAP_ID_ROUTE108, 0},
+ {MAP_GROUP_ROUTE109, MAP_ID_ROUTE109, 0},
+ {MAP_GROUP_ROUTE110, MAP_ID_ROUTE110, 0},
+ {MAP_GROUP_ROUTE111, MAP_ID_ROUTE111, 0},
+ {MAP_GROUP_ROUTE112, MAP_ID_ROUTE112, 0},
+ {MAP_GROUP_ROUTE113, MAP_ID_ROUTE113, 0},
+ {MAP_GROUP_ROUTE114, MAP_ID_ROUTE114, 0},
+ {MAP_GROUP_ROUTE115, MAP_ID_ROUTE115, 0},
+ {MAP_GROUP_ROUTE116, MAP_ID_ROUTE116, 0},
+ {MAP_GROUP_ROUTE117, MAP_ID_ROUTE117, 0},
+ {MAP_GROUP_ROUTE118, MAP_ID_ROUTE118, 0},
+ {MAP_GROUP_ROUTE119, MAP_ID_ROUTE119, 0},
+ {MAP_GROUP_ROUTE120, MAP_ID_ROUTE120, 0},
+ {MAP_GROUP_ROUTE121, MAP_ID_ROUTE121, 0},
+ {MAP_GROUP_ROUTE122, MAP_ID_ROUTE122, 0},
+ {MAP_GROUP_ROUTE123, MAP_ID_ROUTE123, 0},
+ {MAP_GROUP_ROUTE124, MAP_ID_ROUTE124, 0},
+ {MAP_GROUP_ROUTE125, MAP_ID_ROUTE125, 0},
+ {MAP_GROUP_ROUTE126, MAP_ID_ROUTE126, 0},
+ {MAP_GROUP_ROUTE127, MAP_ID_ROUTE127, 0},
+ {MAP_GROUP_ROUTE128, MAP_ID_ROUTE128, 0},
+ {MAP_GROUP_ROUTE129, MAP_ID_ROUTE129, 0},
+ {MAP_GROUP_ROUTE130, MAP_ID_ROUTE130, 0},
+ {MAP_GROUP_ROUTE131, MAP_ID_ROUTE131, 0},
+ {MAP_GROUP_ROUTE132, MAP_ID_ROUTE132, 0},
+ {MAP_GROUP_ROUTE133, MAP_ID_ROUTE133, 0},
+ {MAP_GROUP_ROUTE134, MAP_ID_ROUTE134, 0}
+};
+
+static const u8 *const gUnknown_085A1ED4[] = {
+ gText_PokemonLeague,
+ gText_PokemonCenter
+};
+
+static const struct {
+ const u8 *const *name;
+ u16 mapSecId;
+ u16 flag;
+} gUnknown_085A1EDC[] = {
+ gUnknown_085A1ED4,
+ MAPSEC_EVER_GRANDE_CITY,
+ FLAG_SYS_POKEMON_LEAGUE_FLY
+};
+
+static const struct BgTemplate gUnknown_085A1EE4[] = {
+ { .bg = 0, .charBaseIndex = 0, .mapBaseIndex = 31, .screenSize = 0, .paletteMode = 0, .priority = 0 },
+ { .bg = 1, .charBaseIndex = 3, .mapBaseIndex = 30, .screenSize = 0, .paletteMode = 0, .priority = 1 },
+ { .bg = 2, .charBaseIndex = 2, .mapBaseIndex = 28, .screenSize = 2, .paletteMode = 1, .priority = 2 }
+};
+
+static const struct WindowTemplate gUnknown_085A1EF0[] = {
+ { 0, 17, 17, 12, 2, 15, 0x01 },
+ { 0, 17, 15, 12, 4, 15, 0x19 },
+ { 0, 1, 18, 14, 2, 15, 0x49 },
+ DUMMY_WIN_TEMPLATE
+};
+
+static const struct SpritePalette gUnknown_085A1F10 = {
+ Unknown_085A1D48, 2
+};
+
+static const u16 gUnknown_085A1F18[][2] = {
+ {FLAG_UNLOCK_BATTLE_FRONTIER, MAPSEC_BATTLE_FRONTIER},
+ {-1, MAPSEC_NONE}
+};
+
+static const struct OamData gOamData_085A1F20 = {
+ .priority = 2
+};
+
+static const union AnimCmd gUnknown_085A1F28[] = {
+ ANIMCMD_FRAME( 0, 5),
+ ANIMCMD_END
+};
+
+static const union AnimCmd gUnknown_085A1F30[] = {
+ ANIMCMD_FRAME( 1, 5),
+ ANIMCMD_END
+};
+
+static const union AnimCmd gUnknown_085A1F38[] = {
+ ANIMCMD_FRAME( 3, 5),
+ ANIMCMD_END
+};
+
+static const union AnimCmd gUnknown_085A1F40[] = {
+ ANIMCMD_FRAME( 5, 5),
+ ANIMCMD_END
+};
+
+static const union AnimCmd gUnknown_085A1F48[] = {
+ ANIMCMD_FRAME( 6, 5),
+ ANIMCMD_END
+};
+
+static const union AnimCmd gUnknown_085A1F50[] = {
+ ANIMCMD_FRAME( 8, 5),
+ ANIMCMD_END
+};
+
+static const union AnimCmd gUnknown_085A1F58[] = {
+ ANIMCMD_FRAME(10, 5),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const gUnknown_085A1F60[] = {
+ gUnknown_085A1F28,
+ gUnknown_085A1F30,
+ gUnknown_085A1F38,
+ gUnknown_085A1F40,
+ gUnknown_085A1F48,
+ gUnknown_085A1F50,
+ gUnknown_085A1F58
+};
+
+static const struct SpriteTemplate gUnknown_085A1F7C = {
+ 2,
+ 2,
+ &gOamData_085A1F20,
+ gUnknown_085A1F60,
+ NULL,
+ gDummySpriteAffineAnimTable,
+ SpriteCallbackDummy
+};
+
+// .text
+
+void InitRegionMap(struct RegionMap *regionMap, bool8 zoomed)
+{
+ sub_8122CF8(regionMap, NULL, zoomed);
+ while (sub_8122DB0());
+}
+
+void sub_8122CF8(struct RegionMap *regionMap, struct BgTemplate *template, bool8 zoomed)
+{
+ gRegionMap = regionMap;
+ gRegionMap->initStep = 0;
+ gRegionMap->zoomed = zoomed;
+ gRegionMap->inputCallback = zoomed == TRUE ? ProcessRegionMapInput_Zoomed : ProcessRegionMapInput_Full;
+ if (template != NULL)
+ {
+ gRegionMap->bgNum = template->bg;
+ gRegionMap->charBaseIdx = template->charBaseIndex;
+ gRegionMap->mapBaseIdx = template->mapBaseIndex;
+ gRegionMap->bgManaged = TRUE;
+ }
+ else
+ {
+ gRegionMap->bgNum = 2;
+ gRegionMap->charBaseIdx = 2;
+ gRegionMap->mapBaseIdx = 28;
+ gRegionMap->bgManaged = FALSE;
+ }
+}
+
+void sub_8122D88(struct RegionMap *regionMap)
+{
+ gRegionMap = regionMap;
+ RegionMap_InitializeStateBasedOnPlayerLocation();
+ gRegionMap->playerIconSpritePosX = gRegionMap->cursorPosX;
+ gRegionMap->playerIconSpritePosY = gRegionMap->cursorPosY;
+}
+
+bool8 sub_8122DB0(void)
+{
+ switch (gRegionMap->initStep)
+ {
+ case 0:
+ if (gRegionMap->bgManaged)
+ {
+ decompress_and_copy_tile_data_to_vram(gRegionMap->bgNum, sRegionMapBkgnd_GfxLZ, 0, 0, 0);
+ }
+ else
+ {
+ LZ77UnCompVram(sRegionMapBkgnd_GfxLZ, (u16 *)BG_CHAR_ADDR(2));
+ }
+ break;
+ case 1:
+ if (gRegionMap->bgManaged)
+ {
+ if (!free_temp_tile_data_buffers_if_possible())
+ {
+ decompress_and_copy_tile_data_to_vram(gRegionMap->bgNum, sRegionMapBkgnd_TilemapLZ, 0, 0, 1);
+ }
+ }
+ else
+ {
+ LZ77UnCompVram(sRegionMapBkgnd_TilemapLZ, (u16 *)BG_SCREEN_ADDR(28));
+ }
+ break;
+ case 2:
+ if (!free_temp_tile_data_buffers_if_possible())
+ {
+ LoadPalette(sRegionMapBkgnd_Pal, 0x70, 0x60);
+ }
+ break;
+ case 3:
+ LZ77UnCompWram(sRegionMapCursorSmallGfxLZ, gRegionMap->cursorSmallImage);
+ break;
+ case 4:
+ LZ77UnCompWram(sRegionMapCursorLargeGfxLZ, gRegionMap->cursorLargeImage);
+ break;
+ case 5:
+ RegionMap_InitializeStateBasedOnPlayerLocation();
+ gRegionMap->playerIconSpritePosX = gRegionMap->cursorPosX;
+ gRegionMap->playerIconSpritePosY = gRegionMap->cursorPosY;
+ gRegionMap->mapSecId = CorrectSpecialMapSecId_Internal(gRegionMap->mapSecId);
+ gRegionMap->iconDrawType = get_flagnr_blue_points(gRegionMap->mapSecId);
+ GetMapName(gRegionMap->mapSecName, gRegionMap->mapSecId, 16);
+ break;
+ case 6:
+ if (gRegionMap->zoomed == FALSE)
+ {
+ CalcZoomScrollParams(0, 0, 0, 0, 0x100, 0x100, 0);
+ }
+ else
+ {
+ gRegionMap->scrollX = gRegionMap->cursorPosX * 8 - 0x34;
+ gRegionMap->scrollY = gRegionMap->cursorPosY * 8 - 0x44;
+ gRegionMap->zoomedCursorPosX = gRegionMap->cursorPosX;
+ gRegionMap->zoomedCursorPosY = gRegionMap->cursorPosY;
+ CalcZoomScrollParams(gRegionMap->scrollX, gRegionMap->scrollY, 0x38, 0x48, 0x80, 0x80, 0);
+ }
+ break;
+ case 7:
+ RegionMap_GetPositionOfCursorWithinMapSection();
+ UpdateRegionMapVideoRegs();
+ gRegionMap->cursorSprite = NULL;
+ gRegionMap->playerIconSprite = NULL;
+ gRegionMap->cursorMovementFrameCounter = 0;
+ gRegionMap->blinkPlayerIcon = FALSE;
+ if (gRegionMap->bgManaged)
+ {
+ SetBgAttribute(gRegionMap->bgNum, BG_CTRL_ATTR_MAPBASEINDEX, 2);
+ SetBgAttribute(gRegionMap->bgNum, BG_CTRL_ATTR_VISIBLE, gRegionMap->charBaseIdx);
+ SetBgAttribute(gRegionMap->bgNum, BG_CTRL_ATTR_CHARBASEINDEX, gRegionMap->mapBaseIdx);
+ SetBgAttribute(gRegionMap->bgNum, BG_CTRL_ATTR_PRIORITY, 1);
+ SetBgAttribute(gRegionMap->bgNum, BG_CTRL_ATTR_SCREENSIZE, 1);
+ }
+ gRegionMap->initStep++;
+ return FALSE;
+ default:
+ return FALSE;
+ }
+ gRegionMap->initStep++;
+ return TRUE;
+}
+
+void sub_8123030(u16 a0, u32 a1)
+{
+ BlendPalettes(0x380, a1, a0);
+ CpuCopy16(gPlttBufferFaded + 0x70, gPlttBufferUnfaded + 0x70, 0x60);
+}
+
+void FreeRegionMapIconResources(void)
+{
+ if (gRegionMap->cursorSprite != NULL)
+ {
+ DestroySprite(gRegionMap->cursorSprite);
+ FreeSpriteTilesByTag(gRegionMap->cursorTileTag);
+ FreeSpritePaletteByTag(gRegionMap->cursorPaletteTag);
+ }
+ if (gRegionMap->playerIconSprite != NULL)
+ {
+ DestroySprite(gRegionMap->playerIconSprite);
+ FreeSpriteTilesByTag(gRegionMap->playerIconTileTag);
+ FreeSpritePaletteByTag(gRegionMap->playerIconPaletteTag);
+ }
+}
+
+u8 sub_81230AC(void)
+{
+ return gRegionMap->inputCallback();
+}
+
+static u8 ProcessRegionMapInput_Full(void)
+{
+ u8 input;
+
+ input = INPUT_EVENT_NONE;
+ gRegionMap->cursorDeltaX = 0;
+ gRegionMap->cursorDeltaY = 0;
+ if (gMain.heldKeys & DPAD_UP && gRegionMap->cursorPosY > MAPCURSOR_Y_MIN)
+ {
+ gRegionMap->cursorDeltaY = -1;
+ input = INPUT_EVENT_MOVE_START;
+ }
+ if (gMain.heldKeys & DPAD_DOWN && gRegionMap->cursorPosY < MAPCURSOR_Y_MAX)
+ {
+ gRegionMap->cursorDeltaY = +1;
+ input = INPUT_EVENT_MOVE_START;
+ }
+ if (gMain.heldKeys & DPAD_LEFT && gRegionMap->cursorPosX > MAPCURSOR_X_MIN)
+ {
+ gRegionMap->cursorDeltaX = -1;
+ input = INPUT_EVENT_MOVE_START;
+ }
+ if (gMain.heldKeys & DPAD_RIGHT && gRegionMap->cursorPosX < MAPCURSOR_X_MAX)
+ {
+ gRegionMap->cursorDeltaX = +1;
+ input = INPUT_EVENT_MOVE_START;
+ }
+ if (gMain.newKeys & A_BUTTON)
+ {
+ input = INPUT_EVENT_A_BUTTON;
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ input = INPUT_EVENT_B_BUTTON;
+ }
+ if (input == INPUT_EVENT_MOVE_START)
+ {
+ gRegionMap->cursorMovementFrameCounter = 4;
+ gRegionMap->inputCallback = MoveRegionMapCursor_Full;
+ }
+ return input;
+}
+
+static u8 MoveRegionMapCursor_Full(void)
+{
+ u16 mapSecId;
+
+ if (gRegionMap->cursorMovementFrameCounter != 0)
+ {
+ return INPUT_EVENT_MOVE_CONT;
+ }
+ if (gRegionMap->cursorDeltaX > 0)
+ {
+ gRegionMap->cursorPosX++;
+ }
+ if (gRegionMap->cursorDeltaX < 0)
+ {
+ gRegionMap->cursorPosX--;
+ }
+ if (gRegionMap->cursorDeltaY > 0)
+ {
+ gRegionMap->cursorPosY++;
+ }
+ if (gRegionMap->cursorDeltaY < 0)
+ {
+ gRegionMap->cursorPosY--;
+ }
+ mapSecId = GetRegionMapSectionIdAt_Internal(gRegionMap->cursorPosX, gRegionMap->cursorPosY);
+ gRegionMap->iconDrawType = get_flagnr_blue_points(mapSecId);
+ if (mapSecId != gRegionMap->mapSecId)
+ {
+ gRegionMap->mapSecId = mapSecId;
+ GetMapName(gRegionMap->mapSecName, gRegionMap->mapSecId, 16);
+ }
+ RegionMap_GetPositionOfCursorWithinMapSection();
+ gRegionMap->inputCallback = ProcessRegionMapInput_Full;
+ return INPUT_EVENT_MOVE_END;
+}
+
+static u8 ProcessRegionMapInput_Zoomed(void)
+{
+ u8 input;
+
+ input = INPUT_EVENT_NONE;
+ gRegionMap->zoomedCursorDeltaX = 0;
+ gRegionMap->zoomedCursorDeltaY = 0;
+ if (gMain.heldKeys & DPAD_UP && gRegionMap->scrollY > -0x34)
+ {
+ gRegionMap->zoomedCursorDeltaY = -1;
+ input = INPUT_EVENT_MOVE_START;
+ }
+ if (gMain.heldKeys & DPAD_DOWN && gRegionMap->scrollY < 0x3c)
+ {
+ gRegionMap->zoomedCursorDeltaY = +1;
+ input = INPUT_EVENT_MOVE_START;
+ }
+ if (gMain.heldKeys & DPAD_LEFT && gRegionMap->scrollX > -0x2c)
+ {
+ gRegionMap->zoomedCursorDeltaX = -1;
+ input = INPUT_EVENT_MOVE_START;
+ }
+ if (gMain.heldKeys & DPAD_RIGHT && gRegionMap->scrollX < 0xac)
+ {
+ gRegionMap->zoomedCursorDeltaX = +1;
+ input = INPUT_EVENT_MOVE_START;
+ }
+ if (gMain.newKeys & A_BUTTON)
+ {
+ input = INPUT_EVENT_A_BUTTON;
+ }
+ if (gMain.newKeys & B_BUTTON)
+ {
+ input = INPUT_EVENT_B_BUTTON;
+ }
+ if (input == INPUT_EVENT_MOVE_START)
+ {
+ gRegionMap->inputCallback = MoveRegionMapCursor_Zoomed;
+ gRegionMap->zoomedCursorMovementFrameCounter = 0;
+ }
+ return input;
+}
+
+static u8 MoveRegionMapCursor_Zoomed(void)
+{
+ u16 x;
+ u16 y;
+ u16 mapSecId;
+
+ gRegionMap->scrollY += gRegionMap->zoomedCursorDeltaY;
+ gRegionMap->scrollX += gRegionMap->zoomedCursorDeltaX;
+ RegionMap_SetBG2XAndBG2Y(gRegionMap->scrollX, gRegionMap->scrollY);
+ gRegionMap->zoomedCursorMovementFrameCounter++;
+ if (gRegionMap->zoomedCursorMovementFrameCounter == 8)
+ {
+ x = (gRegionMap->scrollX + 0x2c) / 8 + 1;
+ y = (gRegionMap->scrollY + 0x34) / 8 + 2;
+ if (x != gRegionMap->zoomedCursorPosX || y != gRegionMap->zoomedCursorPosY)
+ {
+ gRegionMap->zoomedCursorPosX = x;
+ gRegionMap->zoomedCursorPosY = y;
+ mapSecId = GetRegionMapSectionIdAt_Internal(x, y);
+ gRegionMap->iconDrawType = get_flagnr_blue_points(mapSecId);
+ if (mapSecId != gRegionMap->mapSecId)
+ {
+ gRegionMap->mapSecId = mapSecId;
+ GetMapName(gRegionMap->mapSecName, gRegionMap->mapSecId, 16);
+ }
+ RegionMap_GetPositionOfCursorWithinMapSection();
+ }
+ gRegionMap->zoomedCursorMovementFrameCounter = 0;
+ gRegionMap->inputCallback = ProcessRegionMapInput_Zoomed;
+ return INPUT_EVENT_MOVE_END;
+ }
+ return INPUT_EVENT_MOVE_CONT;
+}
+
+void sub_8123418(void)
+{
+ if (gRegionMap->zoomed == FALSE)
+ {
+ gRegionMap->scrollY = 0;
+ gRegionMap->scrollX = 0;
+ gRegionMap->unk_040 = 0;
+ gRegionMap->unk_03c = 0;
+ gRegionMap->unk_060 = gRegionMap->cursorPosX * 8 - 0x34;
+ gRegionMap->unk_062 = gRegionMap->cursorPosY * 8 - 0x44;
+ gRegionMap->unk_044 = (gRegionMap->unk_060 << 8) / 16;
+ gRegionMap->unk_048 = (gRegionMap->unk_062 << 8) / 16;
+ gRegionMap->zoomedCursorPosX = gRegionMap->cursorPosX;
+ gRegionMap->zoomedCursorPosY = gRegionMap->cursorPosY;
+ gRegionMap->unk_04c = 0x10000;
+ gRegionMap->unk_050 = -0x800;
+ }
+ else
+ {
+ gRegionMap->unk_03c = gRegionMap->scrollX * 0x100;
+ gRegionMap->unk_040 = gRegionMap->scrollY * 0x100;
+ gRegionMap->unk_060 = 0;
+ gRegionMap->unk_062 = 0;
+ gRegionMap->unk_044 = -(gRegionMap->unk_03c / 16);
+ gRegionMap->unk_048 = -(gRegionMap->unk_040 / 16);
+ gRegionMap->cursorPosX = gRegionMap->zoomedCursorPosX;
+ gRegionMap->cursorPosY = gRegionMap->zoomedCursorPosY;
+ gRegionMap->unk_04c = 0x8000;
+ gRegionMap->unk_050 = 0x800;
+ }
+ gRegionMap->unk_06e = 0;
+ FreeRegionMapCursorSprite();
+ HideRegionMapPlayerIcon();
+}
+
+bool8 sub_8123514(void)
+{
+ bool8 retVal;
+
+ if (gRegionMap->unk_06e >= 16)
+ {
+ return 0;
+ }
+ gRegionMap->unk_06e++;
+ if (gRegionMap->unk_06e == 16)
+ {
+ gRegionMap->unk_044 = 0;
+ gRegionMap->unk_048 = 0;
+ gRegionMap->scrollX = gRegionMap->unk_060;
+ gRegionMap->scrollY = gRegionMap->unk_062;
+ gRegionMap->unk_04c = (gRegionMap->zoomed == FALSE) ? (128 << 8) : (256 << 8);
+ gRegionMap->zoomed = !gRegionMap->zoomed;
+ gRegionMap->inputCallback = (gRegionMap->zoomed == FALSE) ? ProcessRegionMapInput_Full : ProcessRegionMapInput_Zoomed;
+ CreateRegionMapCursor(gRegionMap->cursorTileTag, gRegionMap->cursorPaletteTag);
+ UnhideRegionMapPlayerIcon();
+ retVal = FALSE;
+ }
+ else
+ {
+ gRegionMap->unk_03c += gRegionMap->unk_044;
+ gRegionMap->unk_040 += gRegionMap->unk_048;
+ gRegionMap->scrollX = gRegionMap->unk_03c >> 8;
+ gRegionMap->scrollY = gRegionMap->unk_040 >> 8;
+ gRegionMap->unk_04c += gRegionMap->unk_050;
+ if ((gRegionMap->unk_044 < 0 && gRegionMap->scrollX < gRegionMap->unk_060) || (gRegionMap->unk_044 > 0 && gRegionMap->scrollX > gRegionMap->unk_060))
+ {
+ gRegionMap->scrollX = gRegionMap->unk_060;
+ gRegionMap->unk_044 = 0;
+ }
+ if ((gRegionMap->unk_048 < 0 && gRegionMap->scrollY < gRegionMap->unk_062) || (gRegionMap->unk_048 > 0 && gRegionMap->scrollY > gRegionMap->unk_062))
+ {
+ gRegionMap->scrollY = gRegionMap->unk_062;
+ gRegionMap->unk_048 = 0;
+ }
+ if (gRegionMap->zoomed == FALSE)
+ {
+ if (gRegionMap->unk_04c < (128 << 8))
+ {
+ gRegionMap->unk_04c = (128 << 8);
+ gRegionMap->unk_050 = 0;
+ }
+ }
+ else
+ {
+ if (gRegionMap->unk_04c > (256 << 8))
+ {
+ gRegionMap->unk_04c = (256 << 8);
+ gRegionMap->unk_050 = 0;
+ }
+ }
+ retVal = TRUE;
+ }
+ CalcZoomScrollParams(gRegionMap->scrollX, gRegionMap->scrollY, 0x38, 0x48, gRegionMap->unk_04c >> 8, gRegionMap->unk_04c >> 8, 0);
+ return retVal;
+}
+
+static void CalcZoomScrollParams(s16 scrollX, s16 scrollY, s16 c, s16 d, u16 e, u16 f, u8 rotation)
+{
+ s32 var1;
+ s32 var2;
+ s32 var3;
+ s32 var4;
+
+ gRegionMap->bg2pa = e * gSineTable[rotation + 64] >> 8;
+ gRegionMap->bg2pc = e * -gSineTable[rotation] >> 8;
+ gRegionMap->bg2pb = f * gSineTable[rotation] >> 8;
+ gRegionMap->bg2pd = f * gSineTable[rotation + 64] >> 8;
+
+ var1 = (scrollX << 8) + (c << 8);
+ var2 = d * gRegionMap->bg2pb + gRegionMap->bg2pa * c;
+ gRegionMap->bg2x = var1 - var2;
+
+ var3 = (scrollY << 8) + (d << 8);
+ var4 = gRegionMap->bg2pd * d + gRegionMap->bg2pc * c;
+ gRegionMap->bg2y = var3 - var4;
+
+ gRegionMap->needUpdateVideoRegs = TRUE;
+}
+
+static void RegionMap_SetBG2XAndBG2Y(s16 x, s16 y)
+{
+ gRegionMap->bg2x = (x << 8) + 0x1c00;
+ gRegionMap->bg2y = (y << 8) + 0x2400;
+ gRegionMap->needUpdateVideoRegs = TRUE;
+}
+
+void UpdateRegionMapVideoRegs(void)
+{
+ if (gRegionMap->needUpdateVideoRegs)
+ {
+ SetGpuReg(REG_OFFSET_BG2PA, gRegionMap->bg2pa);
+ SetGpuReg(REG_OFFSET_BG2PB, gRegionMap->bg2pb);
+ SetGpuReg(REG_OFFSET_BG2PC, gRegionMap->bg2pc);
+ SetGpuReg(REG_OFFSET_BG2PD, gRegionMap->bg2pd);
+ SetGpuReg(REG_OFFSET_BG2X_L, gRegionMap->bg2x);
+ SetGpuReg(REG_OFFSET_BG2X_H, gRegionMap->bg2x >> 16);
+ SetGpuReg(REG_OFFSET_BG2Y_L, gRegionMap->bg2y);
+ SetGpuReg(REG_OFFSET_BG2Y_H, gRegionMap->bg2y >> 16);
+ gRegionMap->needUpdateVideoRegs = FALSE;
+ }
+}
+
+void PokedexAreaScreen_UpdateRegionMapVariablesAndVideoRegs(s16 x, s16 y)
+{
+ CalcZoomScrollParams(x, y, 0x38, 0x48, 0x100, 0x100, 0);
+ UpdateRegionMapVideoRegs();
+ if (gRegionMap->playerIconSprite != NULL)
+ {
+ gRegionMap->playerIconSprite->pos2.x = -x;
+ gRegionMap->playerIconSprite->pos2.y = -y;
+ }
+}
+
+static u16 GetRegionMapSectionIdAt_Internal(u16 x, u16 y)
+{
+ if (y < MAPCURSOR_Y_MIN || y > MAPCURSOR_Y_MAX || x < MAPCURSOR_X_MIN || x > MAPCURSOR_X_MAX)
+ {
+ return MAPSEC_NONE;
+ }
+ y -= MAPCURSOR_Y_MIN;
+ x -= MAPCURSOR_X_MIN;
+ return sRegionMap_MapSectionLayout[x + y * MAP_WIDTH];
+}
+
+static void RegionMap_InitializeStateBasedOnPlayerLocation(void)
+{
+ const struct MapHeader *mapHeader;
+ u16 mapWidth;
+ u16 mapHeight;
+ u16 x;
+ u16 y;
+ u16 dimensionScale;
+ u16 xOnMap;
+ struct WarpData *storedWarp;
+
+ if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP_SS_TIDAL_CORRIDOR
+ && (gSaveBlock1Ptr->location.mapNum == MAP_ID_SS_TIDAL_CORRIDOR
+ || gSaveBlock1Ptr->location.mapNum == MAP_ID_SS_TIDAL_LOWER_DECK
+ || gSaveBlock1Ptr->location.mapNum == MAP_ID_SS_TIDAL_ROOMS))
+ {
+ RegionMap_InitializeStateBasedOnSSTidalLocation();
+ return;
+ }
+
+ switch (get_map_light_level_by_bank_and_number(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum))
+ {
+ default:
+ case 1:
+ case 2:
+ case 3:
+ case 5:
+ case 6:
+ gRegionMap->mapSecId = gMapHeader.regionMapSectionId;
+ gRegionMap->playerIsInCave = FALSE;
+ mapWidth = gMapHeader.mapData->width;
+ mapHeight = gMapHeader.mapData->height;
+ x = gSaveBlock1Ptr->pos.x;
+ y = gSaveBlock1Ptr->pos.y;
+ if (gRegionMap->mapSecId == MAPSEC_UNDERWATER_128 || gRegionMap->mapSecId == MAPSEC_UNDERWATER_MARINE_CAVE)
+ {
+ gRegionMap->playerIsInCave = TRUE;
+ }
+ break;
+ case 4:
+ case 7:
+ if (gMapHeader.flags & 0x02)
+ {
+ mapHeader = get_mapheader_by_bank_and_number(gSaveBlock1Ptr->warp4.mapGroup, gSaveBlock1Ptr->warp4.mapNum);
+ gRegionMap->mapSecId = mapHeader->regionMapSectionId;
+ gRegionMap->playerIsInCave = TRUE;
+ mapWidth = mapHeader->mapData->width;
+ mapHeight = mapHeader->mapData->height;
+ x = gSaveBlock1Ptr->warp4.x;
+ y = gSaveBlock1Ptr->warp4.y;
+ }
+ else
+ {
+ gRegionMap->mapSecId = gMapHeader.regionMapSectionId;
+ gRegionMap->playerIsInCave = TRUE;
+ mapWidth = 1;
+ mapHeight = 1;
+ x = 1;
+ y = 1;
+ }
+ break;
+ case 9:
+ mapHeader = get_mapheader_by_bank_and_number((u16)gSaveBlock1Ptr->warp2.mapGroup, (u16)gSaveBlock1Ptr->warp2.mapNum);
+ gRegionMap->mapSecId = mapHeader->regionMapSectionId;
+ gRegionMap->playerIsInCave = TRUE;
+ mapWidth = mapHeader->mapData->width;
+ mapHeight = mapHeader->mapData->height;
+ x = gSaveBlock1Ptr->warp2.x;
+ y = gSaveBlock1Ptr->warp2.y;
+ break;
+ case 8:
+
+ gRegionMap->mapSecId = gMapHeader.regionMapSectionId;
+ if (gRegionMap->mapSecId != MAPSEC_DYNAMIC)
+ {
+ storedWarp = &gSaveBlock1Ptr->warp4;
+ mapHeader = get_mapheader_by_bank_and_number(storedWarp->mapGroup, storedWarp->mapNum);
+ }
+ else
+ {
+ storedWarp = &gSaveBlock1Ptr->warp2;
+ mapHeader = get_mapheader_by_bank_and_number(storedWarp->mapGroup, storedWarp->mapNum);
+ gRegionMap->mapSecId = mapHeader->regionMapSectionId;
+ }
+ if (RegionMap_IsPlayerInCave(gRegionMap->mapSecId))
+ {
+ gRegionMap->playerIsInCave = TRUE;
+ }
+ else
+ {
+ gRegionMap->playerIsInCave = FALSE;
+ }
+ mapWidth = mapHeader->mapData->width;
+ mapHeight = mapHeader->mapData->height;
+ x = storedWarp->x;
+ y = storedWarp->y;
+ break;
+ }
+
+ xOnMap = x;
+
+ dimensionScale = mapWidth / gRegionMapEntries[gRegionMap->mapSecId].width;
+ if (dimensionScale == 0)
+ {
+ dimensionScale = 1;
+ }
+ x /= dimensionScale;
+ if (x >= gRegionMapEntries[gRegionMap->mapSecId].width)
+ {
+ x = gRegionMapEntries[gRegionMap->mapSecId].width - 1;
+ }
+
+ dimensionScale = mapHeight / gRegionMapEntries[gRegionMap->mapSecId].height;
+ if (dimensionScale == 0)
+ {
+ dimensionScale = 1;
+ }
+ y /= dimensionScale;
+ if (y >= gRegionMapEntries[gRegionMap->mapSecId].height)
+ {
+ y = gRegionMapEntries[gRegionMap->mapSecId].height - 1;
+ }
+
+ switch (gRegionMap->mapSecId)
+ {
+ case MAPSEC_ROUTE_114:
+ if (y != 0)
+ {
+ x = 0;
+ }
+ break;
+ case MAPSEC_ROUTE_126:
+ case MAPSEC_UNDERWATER_125:
+ x = 0;
+ if (gSaveBlock1Ptr->pos.x > 32)
+ {
+ x = 1;
+ }
+ if (gSaveBlock1Ptr->pos.x > 0x33)
+ {
+ x++;
+ }
+ y = 0;
+ if (gSaveBlock1Ptr->pos.y > 0x25)
+ {
+ y = 1;
+ }
+ if (gSaveBlock1Ptr->pos.y > 0x38)
+ {
+ y++;
+ }
+ break;
+ case MAPSEC_ROUTE_121:
+ x = 0;
+ if (xOnMap > 14)
+ {
+ x = 1;
+ }
+ if (xOnMap > 0x1C)
+ {
+ x++;
+ }
+ if (xOnMap > 0x36)
+ {
+ x++;
+ }
+ break;
+ case MAPSEC_UNDERWATER_MARINE_CAVE:
+ RegionMap_GetMarineCaveCoords(&gRegionMap->cursorPosX, &gRegionMap->cursorPosY);
+ return;
+ }
+ gRegionMap->cursorPosX = gRegionMapEntries[gRegionMap->mapSecId].x + x + MAPCURSOR_X_MIN;
+ gRegionMap->cursorPosY = gRegionMapEntries[gRegionMap->mapSecId].y + y + MAPCURSOR_Y_MIN;
+}
+
+static void RegionMap_InitializeStateBasedOnSSTidalLocation(void)
+{
+ u16 y;
+ u16 x;
+ u8 mapGroup;
+ u8 mapNum;
+ u16 dimensionScale;
+ s16 xOnMap;
+ s16 yOnMap;
+ const struct MapHeader *mapHeader;
+
+ y = 0;
+ x = 0;
+ switch (GetSSTidalLocation(&mapGroup, &mapNum, &xOnMap, &yOnMap))
+ {
+ case 1:
+ gRegionMap->mapSecId = MAPSEC_SLATEPORT_CITY;
+ break;
+ case 2:
+ gRegionMap->mapSecId = MAPSEC_LILYCOVE_CITY;
+ break;
+ case 3:
+ gRegionMap->mapSecId = MAPSEC_ROUTE_124;
+ break;
+ case 4:
+ gRegionMap->mapSecId = MAPSEC_ROUTE_131;
+ break;
+ default:
+ case 0:
+ mapHeader = get_mapheader_by_bank_and_number(mapGroup, mapNum);
+
+ gRegionMap->mapSecId = mapHeader->regionMapSectionId;
+ dimensionScale = mapHeader->mapData->width / gRegionMapEntries[gRegionMap->mapSecId].width;
+ if (dimensionScale == 0)
+ dimensionScale = 1;
+ x = xOnMap / dimensionScale;
+ if (x >= gRegionMapEntries[gRegionMap->mapSecId].width)
+ x = gRegionMapEntries[gRegionMap->mapSecId].width - 1;
+
+ dimensionScale = mapHeader->mapData->height / gRegionMapEntries[gRegionMap->mapSecId].height;
+ if (dimensionScale == 0)
+ dimensionScale = 1;
+ y = yOnMap / dimensionScale;
+ if (y >= gRegionMapEntries[gRegionMap->mapSecId].height)
+ y = gRegionMapEntries[gRegionMap->mapSecId].height - 1;
+ break;
+ }
+ gRegionMap->playerIsInCave = FALSE;
+ gRegionMap->cursorPosX = gRegionMapEntries[gRegionMap->mapSecId].x + x + MAPCURSOR_X_MIN;
+ gRegionMap->cursorPosY = gRegionMapEntries[gRegionMap->mapSecId].y + y + MAPCURSOR_Y_MIN;
+}
+
+static u8 get_flagnr_blue_points(u16 mapSecId)
+{
+ switch (mapSecId)
+ {
+ case MAPSEC_NONE:
+ return MAPSECTYPE_NONE;
+ case MAPSEC_LITTLEROOT_TOWN:
+ return FlagGet(FLAG_VISITED_LITTLEROOT_TOWN) ? MAPSECTYPE_CITY_CANFLY : MAPSECTYPE_CITY_CANTFLY;
+ case MAPSEC_OLDALE_TOWN:
+ return FlagGet(FLAG_VISITED_OLDALE_TOWN) ? MAPSECTYPE_CITY_CANFLY : MAPSECTYPE_CITY_CANTFLY;
+ case MAPSEC_DEWFORD_TOWN:
+ return FlagGet(FLAG_VISITED_DEWFORD_TOWN) ? MAPSECTYPE_CITY_CANFLY : MAPSECTYPE_CITY_CANTFLY;
+ case MAPSEC_LAVARIDGE_TOWN:
+ return FlagGet(FLAG_VISITED_LAVARIDGE_TOWN) ? MAPSECTYPE_CITY_CANFLY : MAPSECTYPE_CITY_CANTFLY;
+ case MAPSEC_FALLARBOR_TOWN:
+ return FlagGet(FLAG_VISITED_FALLARBOR_TOWN) ? MAPSECTYPE_CITY_CANFLY : MAPSECTYPE_CITY_CANTFLY;
+ case MAPSEC_VERDANTURF_TOWN:
+ return FlagGet(FLAG_VISITED_VERDANTURF_TOWN) ? MAPSECTYPE_CITY_CANFLY : MAPSECTYPE_CITY_CANTFLY;
+ case MAPSEC_PACIFIDLOG_TOWN:
+ return FlagGet(FLAG_VISITED_PACIFIDLOG_TOWN) ? MAPSECTYPE_CITY_CANFLY : MAPSECTYPE_CITY_CANTFLY;
+ case MAPSEC_PETALBURG_CITY:
+ return FlagGet(FLAG_VISITED_PETALBURG_CITY) ? MAPSECTYPE_CITY_CANFLY : MAPSECTYPE_CITY_CANTFLY;
+ case MAPSEC_SLATEPORT_CITY:
+ return FlagGet(FLAG_VISITED_SLATEPORT_CITY) ? MAPSECTYPE_CITY_CANFLY : MAPSECTYPE_CITY_CANTFLY;
+ case MAPSEC_MAUVILLE_CITY:
+ return FlagGet(FLAG_VISITED_MAUVILLE_CITY) ? MAPSECTYPE_CITY_CANFLY : MAPSECTYPE_CITY_CANTFLY;
+ case MAPSEC_RUSTBORO_CITY:
+ return FlagGet(FLAG_VISITED_RUSTBORO_CITY) ? MAPSECTYPE_CITY_CANFLY : MAPSECTYPE_CITY_CANTFLY;
+ case MAPSEC_FORTREE_CITY:
+ return FlagGet(FLAG_VISITED_FORTREE_CITY) ? MAPSECTYPE_CITY_CANFLY : MAPSECTYPE_CITY_CANTFLY;
+ case MAPSEC_LILYCOVE_CITY:
+ return FlagGet(FLAG_VISITED_LILYCOVE_CITY) ? MAPSECTYPE_CITY_CANFLY : MAPSECTYPE_CITY_CANTFLY;
+ case MAPSEC_MOSSDEEP_CITY:
+ return FlagGet(FLAG_VISITED_MOSSDEEP_CITY) ? MAPSECTYPE_CITY_CANFLY : MAPSECTYPE_CITY_CANTFLY;
+ case MAPSEC_SOOTOPOLIS_CITY:
+ return FlagGet(FLAG_VISITED_SOOTOPOLIS_CITY) ? MAPSECTYPE_CITY_CANFLY : MAPSECTYPE_CITY_CANTFLY;
+ case MAPSEC_EVER_GRANDE_CITY:
+ return FlagGet(FLAG_VISITED_EVER_GRANDE_CITY) ? MAPSECTYPE_CITY_CANFLY : MAPSECTYPE_CITY_CANTFLY;
+ case MAPSEC_BATTLE_FRONTIER:
+ return FlagGet(FLAG_UNLOCK_BATTLE_FRONTIER) ? MAPSECTYPE_BATTLE_FRONTIER : MAPSECTYPE_NONE;
+ case MAPSEC_SOUTHERN_ISLAND:
+ return FlagGet(FLAG_UNLOCK_SOUTHERN_ISLAND) ? MAPSECTYPE_PLAIN : MAPSECTYPE_NONE;
+ default:
+ return MAPSECTYPE_PLAIN;
+ }
+}
+
+u16 GetRegionMapSectionIdAt(u16 x, u16 y)
+{
+ return GetRegionMapSectionIdAt_Internal(x, y);
+}
+
+static u16 CorrectSpecialMapSecId_Internal(u16 mapSecId)
+{
+ u32 i;
+
+ for (i = 0; i < 3; i++)
+ {
+ if (sRegionMap_MarineCaveMapSecIds[i] == mapSecId)
+ {
+ return RegionMap_GetTerraCaveMapSecId();
+ }
+ }
+ for (i = 0; sRegionMap_SpecialPlaceLocations[i][0] != MAPSEC_NONE; i++)
+ {
+ if (sRegionMap_SpecialPlaceLocations[i][0] == mapSecId)
+ {
+ return sRegionMap_SpecialPlaceLocations[i][1];
+ }
+ }
+ return mapSecId;
+}
+
+static u16 RegionMap_GetTerraCaveMapSecId(void)
+{
+ s16 idx;
+
+ idx = VarGet(VAR_0x4037) - 1;
+ if (idx < 0 || idx > 15)
+ {
+ idx = 0;
+ }
+ return sTerraCaveMapSectionIds[idx];
+}
+
+static void RegionMap_GetMarineCaveCoords(u16 *x, u16 *y)
+{
+ u16 idx;
+
+ idx = VarGet(VAR_0x4037);
+ if (idx < 9 || idx > 16)
+ {
+ idx = 9;
+ }
+ idx -= 9;
+ *x = sTerraCaveLocationCoords[idx].x + MAPCURSOR_X_MIN;
+ *y = sTerraCaveLocationCoords[idx].y + MAPCURSOR_Y_MIN;
+}
+
+static bool32 RegionMap_IsPlayerInCave(u8 mapSecId)
+{
+ u32 i;
+
+ for (i = 0; i < 1; i++)
+ {
+ if (sRegionMap_MapSecAquaHideoutOld[i] == mapSecId)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+u16 CorrectSpecialMapSecId(u16 mapSecId)
+{
+ return CorrectSpecialMapSecId_Internal(mapSecId);
+}
+
+static void RegionMap_GetPositionOfCursorWithinMapSection(void)
+{
+ u16 x;
+ u16 y;
+ u16 posWithinMapSec;
+
+ if (gRegionMap->mapSecId == MAPSEC_NONE)
+ {
+ gRegionMap->posWithinMapSec = 0;
+ return;
+ }
+ if (!gRegionMap->zoomed)
+ {
+ x = gRegionMap->cursorPosX;
+ y = gRegionMap->cursorPosY;
+ }
+ else
+ {
+ x = gRegionMap->zoomedCursorPosX;
+ y = gRegionMap->zoomedCursorPosY;
+ }
+ posWithinMapSec = 0;
+ while (1)
+ {
+ if (x <= MAPCURSOR_X_MIN)
+ {
+ if (RegionMap_IsMapSecIdInNextRow(y))
+ {
+ y--;
+ x = MAPCURSOR_X_MAX + 1;
+ }
+ else
+ {
+ break;
+ }
+ }
+ else
+ {
+ x--;
+ if (GetRegionMapSectionIdAt_Internal(x, y) == gRegionMap->mapSecId)
+ {
+ posWithinMapSec++;
+ }
+ }
+ }
+ gRegionMap->posWithinMapSec = posWithinMapSec;
+}
+
+static bool8 RegionMap_IsMapSecIdInNextRow(u16 y)
+{
+ u16 x;
+
+ if (y-- == 0)
+ {
+ return FALSE;
+ }
+ for (x = MAPCURSOR_X_MIN; x <= MAPCURSOR_X_MAX; x++)
+ {
+ if (GetRegionMapSectionIdAt_Internal(x, y) == gRegionMap->mapSecId)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static void SpriteCallback_CursorFull(struct Sprite *sprite)
+{
+ if (gRegionMap->cursorMovementFrameCounter != 0)
+ {
+ sprite->pos1.x += 2 * gRegionMap->cursorDeltaX;
+ sprite->pos1.y += 2 * gRegionMap->cursorDeltaY;
+ gRegionMap->cursorMovementFrameCounter--;
+ }
+}
+
+static void SpriteCallback_CursorZoomed(struct Sprite *sprite)
+{
+
+}
+
+void CreateRegionMapCursor(u16 tileTag, u16 paletteTag)
+{
+ u8 spriteId;
+ struct SpriteTemplate template;
+ struct SpritePalette palette;
+ struct SpriteSheet sheet;
+
+ palette = sRegionMapCursorSpritePalette;
+ template = sRegionMapCursorSpriteTemplate;
+ sheet.tag = tileTag;
+ template.tileTag = tileTag;
+ gRegionMap->cursorTileTag = tileTag;
+ palette.tag = paletteTag;
+ template.paletteTag = paletteTag;
+ gRegionMap->cursorPaletteTag = paletteTag;
+ if (!gRegionMap->zoomed)
+ {
+ sheet.data = gRegionMap->cursorSmallImage;
+ sheet.size = sizeof(gRegionMap->cursorSmallImage);
+ template.callback = SpriteCallback_CursorFull;
+ }
+ else
+ {
+ sheet.data = gRegionMap->cursorLargeImage;
+ sheet.size = sizeof(gRegionMap->cursorLargeImage);
+ template.callback = SpriteCallback_CursorZoomed;
+ }
+ LoadSpriteSheet(&sheet);
+ LoadSpritePalette(&palette);
+ spriteId = CreateSprite(&template, 0x38, 0x48, 0);
+ if (spriteId != MAX_SPRITES)
+ {
+ gRegionMap->cursorSprite = &gSprites[spriteId];
+ if (gRegionMap->zoomed == TRUE)
+ {
+ gRegionMap->cursorSprite->oam.size = 2;
+ gRegionMap->cursorSprite->pos1.x -= 8;
+ gRegionMap->cursorSprite->pos1.y -= 8;
+ StartSpriteAnim(gRegionMap->cursorSprite, 1);
+ }
+ else
+ {
+ gRegionMap->cursorSprite->oam.size = 1;
+ gRegionMap->cursorSprite->pos1.x = 8 * gRegionMap->cursorPosX + 4;
+ gRegionMap->cursorSprite->pos1.y = 8 * gRegionMap->cursorPosY + 4;
+ }
+ gRegionMap->cursorSprite->data1 = 2;
+ gRegionMap->cursorSprite->data2 = (IndexOfSpritePaletteTag(paletteTag) << 4) + 0x101;
+ gRegionMap->cursorSprite->data3 = TRUE;
+ }
+}
+
+static void FreeRegionMapCursorSprite(void)
+{
+ if (gRegionMap->cursorSprite != NULL)
+ {
+ DestroySprite(gRegionMap->cursorSprite);
+ FreeSpriteTilesByTag(gRegionMap->cursorTileTag);
+ FreeSpritePaletteByTag(gRegionMap->cursorPaletteTag);
+ }
+}
+
+void sub_8124268(void)
+{
+ gRegionMap->cursorSprite->data3 = TRUE;
+}
+
+void sub_8124278(void)
+{
+ gRegionMap->cursorSprite->data3 = FALSE;
+}
+
+void CreateRegionMapPlayerIcon(u16 tileTag, u16 paletteTag)
+{
+ u8 spriteId;
+ struct SpriteSheet sheet = {sRegionMapPlayerIcon_BrendanGfx, 0x80, tileTag};
+ struct SpritePalette palette = {sRegionMapPlayerIcon_BrendanPal, paletteTag};
+ struct SpriteTemplate template = {tileTag, paletteTag, &sRegionMapPlayerIconOam, sRegionMapPlayerIconAnimTable, NULL, gDummySpriteAffineAnimTable, SpriteCallbackDummy};
+
+ if (sub_8124668(gMapHeader.regionMapSectionId))
+ {
+ gRegionMap->playerIconSprite = NULL;
+ return;
+ }
+ if (gSaveBlock2Ptr->playerGender == FEMALE)
+ {
+ sheet.data = sRegionMapPlayerIcon_MayGfx;
+ palette.data = sRegionMapPlayerIcon_MayPal;
+ }
+ LoadSpriteSheet(&sheet);
+ LoadSpritePalette(&palette);
+ spriteId = CreateSprite(&template, 0, 0, 1);
+ gRegionMap->playerIconSprite = &gSprites[spriteId];
+ if (!gRegionMap->zoomed)
+ {
+ gRegionMap->playerIconSprite->pos1.x = gRegionMap->playerIconSpritePosX * 8 + 4;
+ gRegionMap->playerIconSprite->pos1.y = gRegionMap->playerIconSpritePosY * 8 + 4;
+ gRegionMap->playerIconSprite->callback = RegionMapPlayerIconSpriteCallback_Full;
+ }
+ else
+ {
+ gRegionMap->playerIconSprite->pos1.x = gRegionMap->playerIconSpritePosX * 16 - 0x30;
+ gRegionMap->playerIconSprite->pos1.y = gRegionMap->playerIconSpritePosY * 16 - 0x42;
+ gRegionMap->playerIconSprite->callback = RegionMapPlayerIconSpriteCallback_Zoomed;
+ }
+}
+
+static void HideRegionMapPlayerIcon(void)
+{
+ if (gRegionMap->playerIconSprite != NULL)
+ {
+ gRegionMap->playerIconSprite->invisible = TRUE;
+ gRegionMap->playerIconSprite->callback = SpriteCallbackDummy;
+ }
+}
+
+static void UnhideRegionMapPlayerIcon(void)
+{
+ if (gRegionMap->playerIconSprite != NULL)
+ {
+ if (gRegionMap->zoomed == TRUE)
+ {
+ gRegionMap->playerIconSprite->pos1.x = gRegionMap->playerIconSpritePosX * 16 - 0x30;
+ gRegionMap->playerIconSprite->pos1.y = gRegionMap->playerIconSpritePosY * 16 - 0x42;
+ gRegionMap->playerIconSprite->callback = RegionMapPlayerIconSpriteCallback_Zoomed;
+ gRegionMap->playerIconSprite->invisible = FALSE;
+ }
+ else
+ {
+ gRegionMap->playerIconSprite->pos1.x = gRegionMap->playerIconSpritePosX * 8 + 4;
+ gRegionMap->playerIconSprite->pos1.y = gRegionMap->playerIconSpritePosY * 8 + 4;
+ gRegionMap->playerIconSprite->pos2.x = 0;
+ gRegionMap->playerIconSprite->pos2.y = 0;
+ gRegionMap->playerIconSprite->callback = RegionMapPlayerIconSpriteCallback_Full;
+ gRegionMap->playerIconSprite->invisible = FALSE;
+ }
+ }
+}
+
+static void RegionMapPlayerIconSpriteCallback_Zoomed(struct Sprite *sprite)
+{
+ sprite->pos2.x = -2 * gRegionMap->scrollX;
+ sprite->pos2.y = -2 * gRegionMap->scrollY;
+ sprite->data0 = sprite->pos1.y + sprite->pos2.y + sprite->centerToCornerVecY;
+ sprite->data1 = sprite->pos1.x + sprite->pos2.x + sprite->centerToCornerVecX;
+ if (sprite->data0 < -8 || sprite->data0 > 0xa8 || sprite->data1 < -8 || sprite->data1 > 0xf8)
+ {
+ sprite->data2 = FALSE;
+ }
+ else
+ {
+ sprite->data2 = TRUE;
+ }
+ if (sprite->data2 == TRUE)
+ {
+ RegionMapPlayerIconSpriteCallback(sprite);
+ }
+ else
+ {
+ sprite->invisible = TRUE;
+ }
+}
+
+static void RegionMapPlayerIconSpriteCallback_Full(struct Sprite *sprite)
+{
+ RegionMapPlayerIconSpriteCallback(sprite);
+}
+
+static void RegionMapPlayerIconSpriteCallback(struct Sprite *sprite)
+{
+ if (gRegionMap->blinkPlayerIcon)
+ {
+ if (++sprite->data7 > 16)
+ {
+ sprite->data7 = 0;
+ sprite->invisible = sprite->invisible ? FALSE : TRUE;
+ }
+ }
+ else
+ {
+ sprite->invisible = FALSE;
+ }
+}
+
+void sub_812454C(void)
+{
+ if (gRegionMap->playerIsInCave)
+ {
+ gRegionMap->blinkPlayerIcon = TRUE;
+ }
+}
+
+u8 *GetMapName(u8 *dest, u16 regionMapId, u16 padLength)
+{
+ u8 *str;
+ u16 i;
+
+ if (regionMapId == MAPSEC_SECRET_BASE)
+ {
+ str = GetSecretBaseMapName(dest);
+ }
+ else if (regionMapId < MAPSEC_NONE)
+ {
+ str = StringCopy(dest, gRegionMapEntries[regionMapId].name);
+ }
+ else
+ {
+ if (padLength == 0)
+ {
+ padLength = 18;
+ }
+ return StringFill(dest, CHAR_SPACE, padLength);
+ }
+ if (padLength != 0)
+ {
+ for (i = str - dest; i < padLength; i++)
+ {
+ *str++ = CHAR_SPACE;
+ }
+ *str = EOS;
+ }
+ return str;
+}
+
+u8 *sub_81245DC(u8 *dest, u16 mapSecId)
+{
+ switch (mapSecId)
+ {
+ case MAPSEC_DYNAMIC:
+ return StringCopy(dest, gText_Ferry);
+ case MAPSEC_SECRET_BASE:
+ return StringCopy(dest, gText_SecretBase);
+ default:
+ return GetMapName(dest, mapSecId, 0);
+ }
+}
+
+u8 *sub_8124610(u8 *dest, u16 mapSecId)
+{
+ if (mapSecId == MAPSEC_AQUA_HIDEOUT_OLD)
+ {
+ return StringCopy(dest, gText_Hideout);
+ }
+ else
+ {
+ return sub_81245DC(dest, mapSecId);
+ }
+}
+
+void sub_8124630(u16 mapSecId, u16 *x, u16 *y, u16 *width, u16 *height)
+{
+ *x = gRegionMapEntries[mapSecId].x;
+ *y = gRegionMapEntries[mapSecId].y;
+ *width = gRegionMapEntries[mapSecId].width;
+ *height = gRegionMapEntries[mapSecId].height;
+}
+
+bool8 sub_8124658(void)
+{
+ return gRegionMap->zoomed;
+}
+
+bool32 sub_8124668(u8 mapSecId)
+{
+ u32 i;
+
+ for (i = 0; i < 3; i++)
+ {
+ if (mapSecId == sRegionMapEventSectionIds[i])
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void MCB2_FlyMap(void)
+{
+ switch (gMain.state)
+ {
+ case 0:
+ SetVBlankCallback(NULL);
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ SetGpuReg(REG_OFFSET_BG0HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG0VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG1VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG2VOFS, 0);
+ SetGpuReg(REG_OFFSET_BG2HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG3HOFS, 0);
+ SetGpuReg(REG_OFFSET_BG3VOFS, 0);
+ gUnknown_0203A148 = malloc(sizeof(*gUnknown_0203A148));
+ if (gUnknown_0203A148 == NULL)
+ {
+ SetMainCallback2(sub_8086194);
+ }
+ else
+ {
+ ResetPaletteFade();
+ ResetSpriteData();
+ FreeSpriteTileRanges();
+ FreeAllSpritePalettes();
+ gMain.state++;
+ }
+ break;
+ case 1:
+ ResetBgsAndClearDma3BusyFlags(0);
+ InitBgsFromTemplates(1, gUnknown_085A1EE4, 3);
+ gMain.state++;
+ break;
+ case 2:
+ InitWindows(gUnknown_085A1EF0);
+ DeactivateAllTextPrinters();
+ gMain.state++;
+ break;
+ case 3:
+ sub_809882C(0, 0x65, 0xd0);
+ clear_scheduled_bg_copies_to_vram();
+ gMain.state++;
+ break;
+ case 4:
+ InitRegionMap(&gUnknown_0203A148->regionMap, FALSE);
+ CreateRegionMapCursor(0, 0);
+ CreateRegionMapPlayerIcon(1, 1);
+ gUnknown_0203A148->mapSecId = gUnknown_0203A148->regionMap.mapSecId;
+ StringFill(gUnknown_0203A148->unk_a4c, CHAR_SPACE, 16);
+ gUnknown_03001180 = TRUE;
+ sub_8124904();
+ gMain.state++;
+ break;
+ case 5:
+ LZ77UnCompVram(sRegionMapFrameGfxLZ, (u16 *)BG_CHAR_ADDR(3));
+ gMain.state++;
+ break;
+ case 6:
+ LZ77UnCompVram(sRegionMapFrameTilemapLZ, (u16 *)BG_SCREEN_ADDR(30));
+ gMain.state++;
+ break;
+ case 7:
+ LoadPalette(sRegionMapFramePal, 0x10, 0x20);
+ PutWindowTilemap(2);
+ FillWindowPixelBuffer(2, 0x00);
+ PrintTextOnWindow(2, 1, gText_FlyToWhere, 0, 1, 0, NULL);
+ schedule_bg_copy_tilemap_to_vram(0);
+ gMain.state++;
+ break;
+ case 8:
+ sub_8124A70();
+ gMain.state++;
+ break;
+ case 9:
+ BlendPalettes(-1, 16, 0);
+ SetVBlankCallback(sub_81248C0);
+ gMain.state++;
+ break;
+ case 10:
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON);
+ ShowBg(0);
+ ShowBg(1);
+ ShowBg(2);
+ sub_81248F4(sub_8124D14);
+ SetMainCallback2(sub_81248D4);
+ gMain.state++;
+ break;
+ }
+}
+
+static void sub_81248C0(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+static void sub_81248D4(void)
+{
+ gUnknown_0203A148->unk_000();
+ AnimateSprites();
+ BuildOamBuffer();
+ do_scheduled_bg_tilemap_copies_to_vram();
+}
+
+static void sub_81248F4(void callback(void))
+{
+ gUnknown_0203A148->unk_000 = callback;
+ gUnknown_0203A148->unk_004 = 0;
+}
+
+static void sub_8124904(void)
+{
+ u16 i;
+ bool32 flag;
+ const u8 *name;
+
+ if (gUnknown_0203A148->regionMap.iconDrawType > MAPSECTYPE_NONE && gUnknown_0203A148->regionMap.iconDrawType <= MAPSECTYPE_BATTLE_FRONTIER)
+ {
+ flag = FALSE;
+ for (i = 0; i < 1; i++)
+ {
+ if (gUnknown_0203A148->regionMap.mapSecId == gUnknown_085A1EDC[i].mapSecId)
+ {
+ if (FlagGet(gUnknown_085A1EDC[i].flag))
+ {
+ StringLength(gUnknown_085A1EDC[i].name[gUnknown_0203A148->regionMap.posWithinMapSec]);
+ flag = TRUE;
+ sub_8198070(0, FALSE);
+ SetWindowBorderStyle(1, FALSE, 0x65, 0x0d);
+ PrintTextOnWindow(1, 1, gUnknown_0203A148->regionMap.mapSecName, 0, 1, 0, NULL);
+ name = gUnknown_085A1EDC[i].name[gUnknown_0203A148->regionMap.posWithinMapSec];
+ PrintTextOnWindow(1, 1, name, GetStringRightAlignXOffset(1, name, 0x60), 0x11, 0, NULL);
+ schedule_bg_copy_tilemap_to_vram(0);
+ gUnknown_03001180 = TRUE;
+ }
+ break;
+ }
+ }
+ if (!flag)
+ {
+ if (gUnknown_03001180 == TRUE)
+ {
+ sub_8198070(1, FALSE);
+ SetWindowBorderStyle(0, FALSE, 0x65, 0x0d);
+ }
+ else
+ {
+ FillWindowPixelBuffer(0, 0x11);
+ }
+ PrintTextOnWindow(0, 1, gUnknown_0203A148->regionMap.mapSecName, 0, 1, 0, NULL);
+ schedule_bg_copy_tilemap_to_vram(0);
+ gUnknown_03001180 = FALSE;
+ }
+ }
+ else
+ {
+ if (gUnknown_03001180 == TRUE)
+ {
+ sub_8198070(1, FALSE);
+ SetWindowBorderStyle(0, FALSE, 0x65, 0x0d);
+ }
+ FillWindowPixelBuffer(0, 0x11);
+ CopyWindowToVram(0, 2);
+ schedule_bg_copy_tilemap_to_vram(0);
+ gUnknown_03001180 = FALSE;
+ }
+}
+
+
+static void sub_8124A70(void)
+{
+ struct SpriteSheet sheet;
+
+ LZ77UnCompWram(gUnknown_085A1D68, gUnknown_0203A148->unk_88c);
+ sheet.data = gUnknown_0203A148->unk_88c;
+ sheet.size = 0x1c0;
+ sheet.tag = 2;
+ LoadSpriteSheet(&sheet);
+ LoadSpritePalette(&gUnknown_085A1F10);
+ sub_8124AD4();
+ sub_8124BE4();
+}
+
+static void sub_8124AD4(void)
+{
+ u16 canFlyFlag;
+ u16 i;
+ u16 x;
+ u16 y;
+ u16 width;
+ u16 height;
+ u16 shape;
+ u8 spriteId;
+
+ canFlyFlag = FLAG_VISITED_LITTLEROOT_TOWN;
+ for (i = 0; i < 16; i++)
+ {
+ sub_8124630(i, &x, &y, &width, &height);
+ x = (x + MAPCURSOR_X_MIN) * 8 + 4;
+ y = (y + MAPCURSOR_Y_MIN) * 8 + 4;
+ if (width == 2)
+ {
+ shape = ST_OAM_H_RECTANGLE;
+ }
+ else if (height == 2)
+ {
+ shape = ST_OAM_V_RECTANGLE;
+ }
+ else
+ {
+ shape = ST_OAM_SQUARE;
+ }
+ spriteId = CreateSprite(&gUnknown_085A1F7C, x, y, 10);
+ if (spriteId != MAX_SPRITES)
+ {
+ gSprites[spriteId].oam.shape = shape;
+ if (FlagGet(canFlyFlag))
+ {
+ gSprites[spriteId].callback = sub_8124CBC;
+ }
+ else
+ {
+ shape += 3;
+ }
+ StartSpriteAnim(&gSprites[spriteId], shape);
+ gSprites[spriteId].data0 = i;
+ }
+ canFlyFlag++;
+ }
+}
+
+static void sub_8124BE4(void)
+{
+ u16 i;
+ u16 x;
+ u16 y;
+ u16 width;
+ u16 height;
+ u16 mapSecId;
+ u8 spriteId;
+
+ for (i = 0; gUnknown_085A1F18[i][1] != MAPSEC_NONE; i++)
+ {
+ if (FlagGet(gUnknown_085A1F18[i][0]))
+ {
+ mapSecId = gUnknown_085A1F18[i][1];
+ sub_8124630(mapSecId, &x, &y, &width, &height);
+ x = (x + MAPCURSOR_X_MIN) * 8;
+ y = (y + MAPCURSOR_Y_MIN) * 8;
+ spriteId = CreateSprite(&gUnknown_085A1F7C, x, y, 10);
+ if (spriteId != MAX_SPRITES)
+ {
+ gSprites[spriteId].oam.size = 1;
+ gSprites[spriteId].callback = sub_8124CBC;
+ StartSpriteAnim(&gSprites[spriteId], 6);
+ gSprites[spriteId].data0 = mapSecId;
+ }
+ }
+ }
+}
+
+static void sub_8124CBC(struct Sprite *sprite)
+{
+ if (gUnknown_0203A148->regionMap.mapSecId == sprite->data0)
+ {
+ if (++sprite->data1 > 16)
+ {
+ sprite->data1 = 0;
+ sprite->invisible = sprite->invisible ? FALSE : TRUE;
+ }
+ }
+ else
+ {
+ sprite->data1 = 16;
+ sprite->invisible = FALSE;
+ }
+}
+
+static void sub_8124D14(void)
+{
+ switch (gUnknown_0203A148->unk_004)
+ {
+ case 0:
+ BeginNormalPaletteFade(-1, 0, 16, 0, 0);
+ gUnknown_0203A148->unk_004++;
+ break;
+ case 1:
+ if (!UpdatePaletteFade())
+ {
+ sub_81248F4(sub_8124D64);
+ }
+ break;
+ }
+}
+
+static void sub_8124D64(void)
+{
+ if (gUnknown_0203A148->unk_004 == 0)
+ {
+ switch (sub_81230AC())
+ {
+ case INPUT_EVENT_NONE:
+ case INPUT_EVENT_MOVE_START:
+ case INPUT_EVENT_MOVE_CONT:
+ break;
+ case INPUT_EVENT_MOVE_END:
+ sub_8124904();
+ break;
+ case INPUT_EVENT_A_BUTTON:
+ if (gUnknown_0203A148->regionMap.iconDrawType == MAPSECTYPE_CITY_CANFLY || gUnknown_0203A148->regionMap.iconDrawType == MAPSECTYPE_BATTLE_FRONTIER)
+ {
+ m4aSongNumStart(SE_SELECT);
+ gUnknown_0203A148->unk_a72 = TRUE;
+ sub_81248F4(sub_8124E0C);
+ }
+ break;
+ case INPUT_EVENT_B_BUTTON:
+ m4aSongNumStart(SE_SELECT);
+ gUnknown_0203A148->unk_a72 = FALSE;
+ sub_81248F4(sub_8124E0C);
+ break;
+ }
+ }
+}
+
+static void sub_8124E0C(void)
+{
+ switch (gUnknown_0203A148->unk_004)
+ {
+ case 0:
+ BeginNormalPaletteFade(-1, 0, 0, 16, 0);
+ gUnknown_0203A148->unk_004++;
+ break;
+ case 1:
+ if (!UpdatePaletteFade())
+ {
+ FreeRegionMapIconResources();
+ if (gUnknown_0203A148->unk_a72)
+ {
+ switch (gUnknown_0203A148->regionMap.mapSecId)
+ {
+ case MAPSEC_SOUTHERN_ISLAND:
+ sub_8084CCC(0x15);
+ break;
+ case MAPSEC_BATTLE_FRONTIER:
+ sub_8084CCC(0x16);
+ break;
+ case MAPSEC_LITTLEROOT_TOWN:
+ sub_8084CCC(gSaveBlock2Ptr->playerGender == MALE ? 0x0C : 0x0D);
+ break;
+ case MAPSEC_EVER_GRANDE_CITY:
+ sub_8084CCC(FlagGet(FLAG_SYS_POKEMON_LEAGUE_FLY) && gUnknown_0203A148->regionMap.posWithinMapSec == 0 ? 0x14 : 0x0B);
+ break;
+ default:
+ if (gUnknown_085A1E3C[gUnknown_0203A148->regionMap.mapSecId][2] != 0)
+ {
+ sub_8084CCC(gUnknown_085A1E3C[gUnknown_0203A148->regionMap.mapSecId][2]);
+ }
+ else
+ {
+ warp1_set_2(gUnknown_085A1E3C[gUnknown_0203A148->regionMap.mapSecId][0], gUnknown_085A1E3C[gUnknown_0203A148->regionMap.mapSecId][1], -1);
+ }
+ break;
+ }
+ sub_80B69DC();
+ }
+ else
+ {
+ SetMainCallback2(sub_81B58A8);
+ }
+ if (gUnknown_0203A148 != NULL)
+ {
+ free(gUnknown_0203A148);
+ gUnknown_0203A148 = NULL;
+ }
+ FreeAllWindowBuffers();
+ }
+ break;
+ }
+}
diff --git a/src/reshow_battle_screen.c b/src/reshow_battle_screen.c
index 002f4f069..3177a8946 100644
--- a/src/reshow_battle_screen.c
+++ b/src/reshow_battle_screen.c
@@ -37,8 +37,8 @@ extern const union AnimCmd * const * const gMonAnimationsSpriteAnimsPtrTable[];
extern void dp12_8087EA4(void);
extern void trs_config(void);
extern bool8 IsDoubleBattle(void);
-extern u8 sub_80A614C(u8 bank);
-extern u8 sub_80A6138(u8 bank);
+extern u8 GetSubstituteSpriteDefault_Y(u8 bank);
+extern u8 GetBankSpriteDefault_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);
@@ -104,7 +104,7 @@ static void CB2_ReshowBattleScreenAfterMenu(void)
gReservedSpritePaletteCount = 4;
break;
case 5:
- sub_805E350();
+ ClearSpritesHealthboxAnimData();
break;
case 6:
if (BattleLoadAllHealthBoxesGfx(gBattleScripting.reshowHelperState))
@@ -217,7 +217,7 @@ static bool8 LoadBankSpriteGfx(u8 bank)
if (!gBattleSpritesDataPtr->bankData[bank].behindSubstitute)
BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlePartyID[bank]], bank);
else
- BattleLoadSubstituteSpriteGfx(bank, FALSE);
+ BattleLoadSubstituteOrMonSpriteGfx(bank, FALSE);
}
else if (gBattleTypeFlags & BATTLE_TYPE_SAFARI && bank == 0)
DecompressTrainerBackPic(gSaveBlock2Ptr->playerGender, bank);
@@ -226,7 +226,7 @@ static bool8 LoadBankSpriteGfx(u8 bank)
else if (!gBattleSpritesDataPtr->bankData[bank].behindSubstitute)
BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlePartyID[bank]], bank);
else
- BattleLoadSubstituteSpriteGfx(bank, FALSE);
+ BattleLoadSubstituteOrMonSpriteGfx(bank, FALSE);
gBattleScripting.reshowHelperState = 0;
}
@@ -250,9 +250,9 @@ static void CreateBankSprite(u8 bank)
u8 posY;
if (gBattleSpritesDataPtr->bankData[bank].behindSubstitute)
- posY = sub_80A614C(bank);
+ posY = GetSubstituteSpriteDefault_Y(bank);
else
- posY = sub_80A6138(bank);
+ posY = GetBankSpriteDefault_Y(bank);
if (GetBankSide(bank) != SIDE_PLAYER)
{
diff --git a/src/safari_zone.c b/src/safari_zone.c
index 77c6bbd61..d3d40af28 100644
--- a/src/safari_zone.c
+++ b/src/safari_zone.c
@@ -20,10 +20,10 @@ struct PokeblockFeeder
extern u8 gBattleOutcome;
extern void* gFieldCallback;
-extern u8 gUnknown_082A4B8A[];
-extern u8 gUnknown_082A4B6F[];
-extern u8 gUnknown_082A4B4C[];
-extern u8 gUnknown_082A4B9B[];
+extern u8 EventScript_2A4B8A[];
+extern u8 EventScript_2A4B6F[];
+extern u8 EventScript_2A4B4C[];
+extern u8 EventScript_2A4B9B[];
extern const u8* const gPokeblockNames[];
extern void sub_80EE44C(u8, u8);
@@ -50,17 +50,17 @@ static void DecrementFeederStepCounters(void);
bool32 GetSafariZoneFlag(void)
{
- return FlagGet(SYS_SAFARI_MODE);
+ return FlagGet(FLAG_SYS_SAFARI_MODE);
}
void SetSafariZoneFlag(void)
{
- FlagSet(SYS_SAFARI_MODE);
+ FlagSet(FLAG_SYS_SAFARI_MODE);
}
void ResetSafariZoneFlag(void)
{
- FlagClear(SYS_SAFARI_MODE);
+ FlagClear(FLAG_SYS_SAFARI_MODE);
}
void EnterSafariMode(void)
@@ -94,7 +94,7 @@ bool8 SafariZoneTakeStep(void)
sSafariZoneStepCounter--;
if (sSafariZoneStepCounter == 0)
{
- ScriptContext1_SetupScript(gUnknown_082A4B8A);
+ ScriptContext1_SetupScript(EventScript_2A4B8A);
return TRUE;
}
return FALSE;
@@ -102,7 +102,7 @@ bool8 SafariZoneTakeStep(void)
void SafariZoneRetirePrompt(void)
{
- ScriptContext1_SetupScript(gUnknown_082A4B6F);
+ ScriptContext1_SetupScript(EventScript_2A4B6F);
}
void sub_80FC190(void)
@@ -116,14 +116,14 @@ void sub_80FC190(void)
}
else if (gBattleOutcome == BATTLE_SAFARI_OUT_OF_BALLS)
{
- ScriptContext2_RunNewScript(gUnknown_082A4B4C);
+ ScriptContext2_RunNewScript(EventScript_2A4B4C);
warp_in();
gFieldCallback = sub_80AF6F0;
SetMainCallback2(c2_load_new_map);
}
else if (gBattleOutcome == BATTLE_CAUGHT)
{
- ScriptContext1_SetupScript(gUnknown_082A4B9B);
+ ScriptContext1_SetupScript(EventScript_2A4B9B);
ScriptContext1_Stop();
SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
}
@@ -152,13 +152,13 @@ void GetPokeblockFeederInFront(void)
&& sPokeblockFeeders[i].x == x
&& sPokeblockFeeders[i].y == y)
{
- gScriptResult = i;
+ gSpecialVar_Result = i;
StringCopy(gStringVar1, gPokeblockNames[sPokeblockFeeders[i].pokeblock.color]);
return;
}
}
- gScriptResult = -1;
+ gSpecialVar_Result = -1;
}
void GetPokeblockFeederWithinRange(void)
@@ -181,13 +181,13 @@ void GetPokeblockFeederWithinRange(void)
y *= -1;
if ((x + y) <= 5)
{
- gScriptResult = i;
+ gSpecialVar_Result = i;
return;
}
}
}
- gScriptResult = -1;
+ gSpecialVar_Result = -1;
}
// unused
@@ -195,20 +195,20 @@ struct Pokeblock *SafariZoneGetPokeblockInFront(void)
{
GetPokeblockFeederInFront();
- if (gScriptResult == 0xFFFF)
+ if (gSpecialVar_Result == 0xFFFF)
return NULL;
else
- return &sPokeblockFeeders[gScriptResult].pokeblock;
+ return &sPokeblockFeeders[gSpecialVar_Result].pokeblock;
}
struct Pokeblock *SafariZoneGetActivePokeblock(void)
{
GetPokeblockFeederWithinRange();
- if (gScriptResult == 0xFFFF)
+ if (gSpecialVar_Result == 0xFFFF)
return NULL;
else
- return &sPokeblockFeeders[gScriptResult].pokeblock;
+ return &sPokeblockFeeders[gSpecialVar_Result].pokeblock;
}
void SafariZoneActivatePokeblockFeeder(u8 pkblId)
@@ -255,13 +255,13 @@ bool8 GetInFrontFeederPokeblockAndSteps(void)
{
GetPokeblockFeederInFront();
- if (gScriptResult == 0xFFFF)
+ if (gSpecialVar_Result == 0xFFFF)
{
return FALSE;
}
ConvertIntToDecimalStringN(gStringVar2,
- sPokeblockFeeders[gScriptResult].stepCounter,
+ sPokeblockFeeders[gSpecialVar_Result].stepCounter,
STR_CONV_MODE_LEADING_ZEROS, 3);
return TRUE;
diff --git a/src/save.c b/src/save.c
index 2c1b26ca9..528c67145 100644
--- a/src/save.c
+++ b/src/save.c
@@ -797,7 +797,7 @@ u16 sub_815355C(void)
return 0;
}
-u32 sub_81535DC(u8 sector, u8* dst)
+u32 TryCopySpecialSaveSection(u8 sector, u8* dst)
{
s32 i;
s32 size;
@@ -826,6 +826,7 @@ u32 sub_8153634(u8 sector, u8* src)
if (sector != 30 && sector != 31)
return 0xFF;
+
savDataBuffer = &gSaveDataBuffer;
*(u32*)(savDataBuffer) = 0xB39D;
diff --git a/src/scrcmd.c b/src/scrcmd.c
index af314609c..183b9bab5 100644
--- a/src/scrcmd.c
+++ b/src/scrcmd.c
@@ -69,9 +69,9 @@ extern u16 gSpecialVar_0x8001;
extern u16 gSpecialVar_0x8002;
extern u16 gSpecialVar_0x8004;
-extern u16 gScriptResult;
+extern u16 gSpecialVar_Result;
-extern u16 gScriptContestCategory;
+extern u16 gSpecialVar_ContestCategory;
IWRAM_DATA u8 gUnknown_03000F30;
@@ -491,25 +491,25 @@ bool8 ScrCmd_random(struct ScriptContext *ctx)
{
u16 max = VarGet(ScriptReadHalfword(ctx));
- gScriptResult = Random() % max;
+ gSpecialVar_Result = Random() % max;
return FALSE;
}
-bool8 ScrCmd_additem(struct ScriptContext *ctx)
+bool8 ScrCmd_giveitem(struct ScriptContext *ctx)
{
u16 itemId = VarGet(ScriptReadHalfword(ctx));
u32 quantity = VarGet(ScriptReadHalfword(ctx));
- gScriptResult = AddBagItem(itemId, (u8)quantity);
+ gSpecialVar_Result = AddBagItem(itemId, (u8)quantity);
return FALSE;
}
-bool8 ScrCmd_removeitem(struct ScriptContext *ctx)
+bool8 ScrCmd_takeitem(struct ScriptContext *ctx)
{
u16 itemId = VarGet(ScriptReadHalfword(ctx));
u32 quantity = VarGet(ScriptReadHalfword(ctx));
- gScriptResult = RemoveBagItem(itemId, (u8)quantity);
+ gSpecialVar_Result = RemoveBagItem(itemId, (u8)quantity);
return FALSE;
}
@@ -518,7 +518,7 @@ bool8 ScrCmd_checkitemspace(struct ScriptContext *ctx)
u16 itemId = VarGet(ScriptReadHalfword(ctx));
u32 quantity = VarGet(ScriptReadHalfword(ctx));
- gScriptResult = CheckBagHasSpace(itemId, (u8)quantity);
+ gSpecialVar_Result = CheckBagHasSpace(itemId, (u8)quantity);
return FALSE;
}
@@ -527,7 +527,7 @@ bool8 ScrCmd_checkitem(struct ScriptContext *ctx)
u16 itemId = VarGet(ScriptReadHalfword(ctx));
u32 quantity = VarGet(ScriptReadHalfword(ctx));
- gScriptResult = CheckBagHasItem(itemId, (u8)quantity);
+ gSpecialVar_Result = CheckBagHasItem(itemId, (u8)quantity);
return FALSE;
}
@@ -535,16 +535,16 @@ bool8 ScrCmd_checkitemtype(struct ScriptContext *ctx)
{
u16 itemId = VarGet(ScriptReadHalfword(ctx));
- gScriptResult = GetPocketByItemId(itemId);
+ gSpecialVar_Result = GetPocketByItemId(itemId);
return FALSE;
}
-bool8 ScrCmd_addpcitem(struct ScriptContext *ctx)
+bool8 ScrCmd_givepcitem(struct ScriptContext *ctx)
{
u16 itemId = VarGet(ScriptReadHalfword(ctx));
u16 quantity = VarGet(ScriptReadHalfword(ctx));
- gScriptResult = AddPCItem(itemId, quantity);
+ gSpecialVar_Result = AddPCItem(itemId, quantity);
return FALSE;
}
@@ -553,39 +553,39 @@ bool8 ScrCmd_checkpcitem(struct ScriptContext *ctx)
u16 itemId = VarGet(ScriptReadHalfword(ctx));
u16 quantity = VarGet(ScriptReadHalfword(ctx));
- gScriptResult = CheckPCHasItem(itemId, quantity);
+ gSpecialVar_Result = CheckPCHasItem(itemId, quantity);
return FALSE;
}
-bool8 ScrCmd_adddecor(struct ScriptContext *ctx)
+bool8 ScrCmd_givedecoration(struct ScriptContext *ctx)
{
u32 decorId = VarGet(ScriptReadHalfword(ctx));
- gScriptResult = DecorationAdd(decorId);
+ gSpecialVar_Result = DecorationAdd(decorId);
return FALSE;
}
-bool8 ScrCmd_removedecor(struct ScriptContext *ctx)
+bool8 ScrCmd_takedecoration(struct ScriptContext *ctx)
{
u32 decorId = VarGet(ScriptReadHalfword(ctx));
- gScriptResult = DecorationRemove(decorId);
+ gSpecialVar_Result = DecorationRemove(decorId);
return FALSE;
}
-bool8 ScrCmd_checkdecor(struct ScriptContext *ctx)
+bool8 ScrCmd_checkdecorspace(struct ScriptContext *ctx)
{
u32 decorId = VarGet(ScriptReadHalfword(ctx));
- gScriptResult = DecorationCheckSpace(decorId);
+ gSpecialVar_Result = DecorationCheckSpace(decorId);
return FALSE;
}
-bool8 ScrCmd_hasdecor(struct ScriptContext *ctx)
+bool8 ScrCmd_checkdecor(struct ScriptContext *ctx)
{
u32 decorId = VarGet(ScriptReadHalfword(ctx));
- gScriptResult = CheckHasDecoration(decorId);
+ gSpecialVar_Result = CheckHasDecoration(decorId);
return FALSE;
}
@@ -613,14 +613,14 @@ bool8 ScrCmd_incrementgamestat(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_animdarklevel(struct ScriptContext *ctx)
+bool8 ScrCmd_animateflash(struct ScriptContext *ctx)
{
sub_80B009C(ScriptReadByte(ctx));
ScriptContext1_Stop();
return TRUE;
}
-bool8 ScrCmd_setdarklevel(struct ScriptContext *ctx)
+bool8 ScrCmd_setflashradius(struct ScriptContext *ctx)
{
u16 flashLevel = VarGet(ScriptReadHalfword(ctx));
@@ -643,12 +643,12 @@ bool8 ScrCmd_fadescreen(struct ScriptContext *ctx)
return TRUE;
}
-bool8 ScrCmd_fadescreendelay(struct ScriptContext *ctx)
+bool8 ScrCmd_fadescreenspeed(struct ScriptContext *ctx)
{
u8 mode = ScriptReadByte(ctx);
- u8 delay = ScriptReadByte(ctx);
+ u8 speed = ScriptReadByte(ctx);
- fade_screen(mode, delay);
+ fade_screen(mode, speed);
SetupNativeScript(ctx, IsPaletteNotActive);
return TRUE;
}
@@ -736,7 +736,7 @@ bool8 ScrCmd_doweather(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_tileeffect(struct ScriptContext *ctx)
+bool8 ScrCmd_setstepcallback(struct ScriptContext *ctx)
{
ActivatePerStepCallback(ScriptReadByte(ctx));
return FALSE;
@@ -907,9 +907,9 @@ bool8 ScrCmd_getplayerxy(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_countpokemon(struct ScriptContext *ctx)
+bool8 ScrCmd_getpartysize(struct ScriptContext *ctx)
{
- gScriptResult = CalculatePlayerPartyCount();
+ gSpecialVar_Result = CalculatePlayerPartyCount();
return FALSE;
}
@@ -1121,7 +1121,7 @@ bool8 ScrCmd_moveobjectoffscreen(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_showobject(struct ScriptContext *ctx)
+bool8 ScrCmd_showobject_at(struct ScriptContext *ctx)
{
u16 localId = VarGet(ScriptReadHalfword(ctx));
u8 mapGroup = ScriptReadByte(ctx);
@@ -1131,7 +1131,7 @@ bool8 ScrCmd_showobject(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_hideobject(struct ScriptContext *ctx)
+bool8 ScrCmd_hideobject_at(struct ScriptContext *ctx)
{
u16 localId = VarGet(ScriptReadHalfword(ctx));
u8 mapGroup = ScriptReadByte(ctx);
@@ -1339,7 +1339,7 @@ static bool8 WaitForAorBPress(void)
return FALSE;
}
-bool8 ScrCmd_waitbutton(struct ScriptContext *ctx)
+bool8 ScrCmd_waitbuttonpress(struct ScriptContext *ctx)
{
SetupNativeScript(ctx, WaitForAorBPress);
return TRUE;
@@ -1454,7 +1454,7 @@ bool8 ScrCmd_drawboxtext(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_drawpokepic(struct ScriptContext *ctx)
+bool8 ScrCmd_showmonpic(struct ScriptContext *ctx)
{
u16 species = VarGet(ScriptReadHalfword(ctx));
u8 x = ScriptReadByte(ctx);
@@ -1464,7 +1464,7 @@ bool8 ScrCmd_drawpokepic(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_erasepokepic(struct ScriptContext *ctx)
+bool8 ScrCmd_hidemonpic(struct ScriptContext *ctx)
{
bool8 (*func)(void) = ScriptMenu_GetPicboxWaitFunc();
@@ -1474,7 +1474,7 @@ bool8 ScrCmd_erasepokepic(struct ScriptContext *ctx)
return TRUE;
}
-bool8 ScrCmd_drawcontestwinner(struct ScriptContext *ctx)
+bool8 ScrCmd_showcontestwinner(struct ScriptContext *ctx)
{
u8 v1 = ScriptReadByte(ctx);
@@ -1694,7 +1694,7 @@ bool8 ScrCmd_vmessage(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_getspeciesname(struct ScriptContext *ctx)
+bool8 ScrCmd_bufferspeciesname(struct ScriptContext *ctx)
{
u8 stringVarIndex = ScriptReadByte(ctx);
u16 species = VarGet(ScriptReadHalfword(ctx));
@@ -1703,7 +1703,7 @@ bool8 ScrCmd_getspeciesname(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_getfirstpartypokename(struct ScriptContext *ctx)
+bool8 ScrCmd_bufferleadmonspeciesname(struct ScriptContext *ctx)
{
u8 stringVarIndex = ScriptReadByte(ctx);
@@ -1714,7 +1714,7 @@ bool8 ScrCmd_getfirstpartypokename(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_getpartypokename(struct ScriptContext *ctx)
+bool8 ScrCmd_bufferpartymonnick(struct ScriptContext *ctx)
{
u8 stringVarIndex = ScriptReadByte(ctx);
u16 partyIndex = VarGet(ScriptReadHalfword(ctx));
@@ -1724,7 +1724,7 @@ bool8 ScrCmd_getpartypokename(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_getitemname(struct ScriptContext *ctx)
+bool8 ScrCmd_bufferitemname(struct ScriptContext *ctx)
{
u8 stringVarIndex = ScriptReadByte(ctx);
u16 itemId = VarGet(ScriptReadHalfword(ctx));
@@ -1733,7 +1733,7 @@ bool8 ScrCmd_getitemname(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_getitemnameplural(struct ScriptContext *ctx)
+bool8 ScrCmd_bufferitemnameplural(struct ScriptContext *ctx)
{
u8 stringVarIndex = ScriptReadByte(ctx);
u16 itemId = VarGet(ScriptReadHalfword(ctx));
@@ -1743,7 +1743,7 @@ bool8 ScrCmd_getitemnameplural(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_getdecorname(struct ScriptContext *ctx)
+bool8 ScrCmd_bufferdecorationname(struct ScriptContext *ctx)
{
u8 stringVarIndex = ScriptReadByte(ctx);
u16 decorId = VarGet(ScriptReadHalfword(ctx));
@@ -1752,7 +1752,7 @@ bool8 ScrCmd_getdecorname(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_getmovename(struct ScriptContext *ctx)
+bool8 ScrCmd_buffermovename(struct ScriptContext *ctx)
{
u8 stringVarIndex = ScriptReadByte(ctx);
u16 moveId = VarGet(ScriptReadHalfword(ctx));
@@ -1761,7 +1761,7 @@ bool8 ScrCmd_getmovename(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_getnumberstring(struct ScriptContext *ctx)
+bool8 ScrCmd_buffernumberstring(struct ScriptContext *ctx)
{
u8 stringVarIndex = ScriptReadByte(ctx);
u16 v1 = VarGet(ScriptReadHalfword(ctx));
@@ -1771,7 +1771,7 @@ bool8 ScrCmd_getnumberstring(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_getstdstring(struct ScriptContext *ctx)
+bool8 ScrCmd_bufferstdstring(struct ScriptContext *ctx)
{
u8 stringVarIndex = ScriptReadByte(ctx);
u16 index = VarGet(ScriptReadHalfword(ctx));
@@ -1780,7 +1780,7 @@ bool8 ScrCmd_getstdstring(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_getcontesttype(struct ScriptContext *ctx)
+bool8 ScrCmd_buffercontesttype(struct ScriptContext *ctx)
{
u8 stringVarIndex = ScriptReadByte(ctx);
u16 index = VarGet(ScriptReadHalfword(ctx));
@@ -1789,7 +1789,7 @@ bool8 ScrCmd_getcontesttype(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_getstring(struct ScriptContext *ctx)
+bool8 ScrCmd_bufferstring(struct ScriptContext *ctx)
{
u8 stringVarIndex = ScriptReadByte(ctx);
const u8 *text = (u8 *)ScriptReadWord(ctx);
@@ -1806,7 +1806,7 @@ bool8 ScrCmd_vloadword(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_vgetstring(struct ScriptContext *ctx)
+bool8 ScrCmd_vbufferstring(struct ScriptContext *ctx)
{
u8 stringVarIndex = ScriptReadByte(ctx);
u32 addr = ScriptReadWord(ctx);
@@ -1817,7 +1817,7 @@ bool8 ScrCmd_vgetstring(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_getboxname(struct ScriptContext *ctx)
+bool8 ScrCmd_bufferboxname(struct ScriptContext *ctx)
{
u8 stringVarIndex = ScriptReadByte(ctx);
u16 boxId = VarGet(ScriptReadHalfword(ctx));
@@ -1826,7 +1826,7 @@ bool8 ScrCmd_getboxname(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_givepoke(struct ScriptContext *ctx)
+bool8 ScrCmd_givemon(struct ScriptContext *ctx)
{
u16 species = VarGet(ScriptReadHalfword(ctx));
u8 level = ScriptReadByte(ctx);
@@ -1835,7 +1835,7 @@ bool8 ScrCmd_givepoke(struct ScriptContext *ctx)
u32 unkParam2 = ScriptReadWord(ctx);
u8 unkParam3 = ScriptReadByte(ctx);
- gScriptResult = ScriptGiveMon(species, level, item, unkParam1, unkParam2, unkParam3);
+ gSpecialVar_Result = ScriptGiveMon(species, level, item, unkParam1, unkParam2, unkParam3);
return FALSE;
}
@@ -1843,11 +1843,11 @@ bool8 ScrCmd_giveegg(struct ScriptContext *ctx)
{
u16 species = VarGet(ScriptReadHalfword(ctx));
- gScriptResult = ScriptGiveEgg(species);
+ gSpecialVar_Result = ScriptGiveEgg(species);
return FALSE;
}
-bool8 ScrCmd_setpokemove(struct ScriptContext *ctx)
+bool8 ScrCmd_setmonmove(struct ScriptContext *ctx)
{
u8 partyIndex = ScriptReadByte(ctx);
u8 slot = ScriptReadByte(ctx);
@@ -1857,12 +1857,12 @@ bool8 ScrCmd_setpokemove(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_checkpokemove(struct ScriptContext *ctx)
+bool8 ScrCmd_checkpartymove(struct ScriptContext *ctx)
{
u8 i;
u16 moveId = ScriptReadHalfword(ctx);
- gScriptResult = 6;
+ gSpecialVar_Result = 6;
for (i = 0; i < 6; i++)
{
u16 species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL);
@@ -1871,7 +1871,7 @@ bool8 ScrCmd_checkpokemove(struct ScriptContext *ctx)
// UB: GetMonData() arguments don't match function definition
if (!GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG) && pokemon_has_move(&gPlayerParty[i], moveId) == TRUE)
{
- gScriptResult = i;
+ gSpecialVar_Result = i;
gSpecialVar_0x8004 = species;
break;
}
@@ -1905,7 +1905,7 @@ bool8 ScrCmd_checkmoney(struct ScriptContext *ctx)
u8 ignore = ScriptReadByte(ctx);
if (!ignore)
- gScriptResult = IsEnoughMoney(&gSaveBlock1Ptr->money, amount);
+ gSpecialVar_Result = IsEnoughMoney(&gSaveBlock1Ptr->money, amount);
return FALSE;
}
@@ -1973,7 +1973,7 @@ bool8 ScrCmd_trainerbattle(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_battlebegin(struct ScriptContext *ctx)
+bool8 ScrCmd_dotrainerbattle(struct ScriptContext *ctx)
{
BattleSetup_StartTrainerBattle();
return TRUE;
@@ -2041,7 +2041,7 @@ bool8 ScrCmd_pokemart(struct ScriptContext *ctx)
return TRUE;
}
-bool8 ScrCmd_pokemartdecor(struct ScriptContext *ctx)
+bool8 ScrCmd_pokemartdecoration(struct ScriptContext *ctx)
{
const void *ptr = (void *)ScriptReadWord(ctx);
@@ -2050,7 +2050,7 @@ bool8 ScrCmd_pokemartdecor(struct ScriptContext *ctx)
return TRUE;
}
-bool8 ScrCmd_pokemartbp(struct ScriptContext *ctx)
+bool8 ScrCmd_pokemartdecoration2(struct ScriptContext *ctx)
{
const void *ptr = (void *)ScriptReadWord(ctx);
@@ -2068,7 +2068,7 @@ bool8 ScrCmd_playslotmachine(struct ScriptContext *ctx)
return TRUE;
}
-bool8 ScrCmd_plantberrytree(struct ScriptContext *ctx)
+bool8 ScrCmd_setberrytree(struct ScriptContext *ctx)
{
u8 treeId = ScriptReadByte(ctx);
u8 berry = ScriptReadByte(ctx);
@@ -2085,7 +2085,7 @@ bool8 ScrCmd_getpricereduction(struct ScriptContext *ctx)
{
u16 value = VarGet(ScriptReadHalfword(ctx));
- gScriptResult = GetPriceReduction(value);
+ gSpecialVar_Result = GetPriceReduction(value);
return FALSE;
}
@@ -2113,7 +2113,7 @@ bool8 ScrCmd_showcontestresults(struct ScriptContext *ctx)
bool8 ScrCmd_contestlinktransfer(struct ScriptContext *ctx)
{
- sub_80F84C4(gScriptContestCategory);
+ sub_80F84C4(gSpecialVar_ContestCategory);
ScriptContext1_Stop();
return TRUE;
}
@@ -2127,7 +2127,7 @@ bool8 ScrCmd_dofieldeffect(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_setfieldeffect(struct ScriptContext *ctx)
+bool8 ScrCmd_setfieldeffectarg(struct ScriptContext *ctx)
{
u8 argNum = ScriptReadByte(ctx);
@@ -2150,7 +2150,7 @@ bool8 ScrCmd_waitfieldeffect(struct ScriptContext *ctx)
return TRUE;
}
-bool8 ScrCmd_sethealplace(struct ScriptContext *ctx)
+bool8 ScrCmd_setrespawn(struct ScriptContext *ctx)
{
u16 healLocationId = VarGet(ScriptReadHalfword(ctx));
@@ -2160,11 +2160,11 @@ bool8 ScrCmd_sethealplace(struct ScriptContext *ctx)
bool8 ScrCmd_checkplayergender(struct ScriptContext *ctx)
{
- gScriptResult = gSaveBlock2Ptr->playerGender;
+ gSpecialVar_Result = gSaveBlock2Ptr->playerGender;
return FALSE;
}
-bool8 ScrCmd_playpokecry(struct ScriptContext *ctx)
+bool8 ScrCmd_playmoncry(struct ScriptContext *ctx)
{
u16 species = VarGet(ScriptReadHalfword(ctx));
u16 mode = VarGet(ScriptReadHalfword(ctx));
@@ -2173,13 +2173,13 @@ bool8 ScrCmd_playpokecry(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_waitpokecry(struct ScriptContext *ctx)
+bool8 ScrCmd_waitmoncry(struct ScriptContext *ctx)
{
SetupNativeScript(ctx, IsCryFinished);
return TRUE;
}
-bool8 ScrCmd_setmaptile(struct ScriptContext *ctx)
+bool8 ScrCmd_setmetatile(struct ScriptContext *ctx)
{
u16 x = VarGet(ScriptReadHalfword(ctx));
u16 y = VarGet(ScriptReadHalfword(ctx));
@@ -2285,9 +2285,9 @@ bool8 ScrCmd_givecoins(struct ScriptContext *ctx)
u16 coins = VarGet(ScriptReadHalfword(ctx));
if (GiveCoins(coins) == TRUE)
- gScriptResult = 0;
+ gSpecialVar_Result = 0;
else
- gScriptResult = 1;
+ gSpecialVar_Result = 1;
return FALSE;
}
@@ -2296,9 +2296,9 @@ bool8 ScrCmd_takecoins(struct ScriptContext *ctx)
u16 coins = VarGet(ScriptReadHalfword(ctx));
if (TakeCoins(coins) == TRUE)
- gScriptResult = 0;
+ gSpecialVar_Result = 0;
else
- gScriptResult = 1;
+ gSpecialVar_Result = 1;
return FALSE;
}
@@ -2353,8 +2353,8 @@ bool8 ScrCmd_cmdD9(struct ScriptContext *ctx)
}
}
-// This command will force the Pokémon to be obedient, you don't get to choose which value to set its obedience to
-bool8 ScrCmd_setpokeobedient(struct ScriptContext *ctx)
+// This command will force the Pokémon to be obedient, you don't get to make it disobedient
+bool8 ScrCmd_setmonobedient(struct ScriptContext *ctx)
{
bool8 obedient = TRUE;
u16 partyIndex = VarGet(ScriptReadHalfword(ctx));
@@ -2363,11 +2363,11 @@ bool8 ScrCmd_setpokeobedient(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_checkpokeobedience(struct ScriptContext *ctx)
+bool8 ScrCmd_checkmonobedience(struct ScriptContext *ctx)
{
u16 partyIndex = VarGet(ScriptReadHalfword(ctx));
- gScriptResult = GetMonData(&gPlayerParty[partyIndex], MON_DATA_OBEDIENCE, NULL);
+ gSpecialVar_Result = GetMonData(&gPlayerParty[partyIndex], MON_DATA_OBEDIENCE, NULL);
return FALSE;
}
@@ -2398,7 +2398,7 @@ bool8 ScrCmd_warpD1(struct ScriptContext *ctx)
return TRUE;
}
-bool8 ScrCmd_setpokemetlocation(struct ScriptContext *ctx)
+bool8 ScrCmd_setmonmetlocation(struct ScriptContext *ctx)
{
u16 partyIndex = VarGet(ScriptReadHalfword(ctx));
u8 location = ScriptReadByte(ctx);
@@ -2414,7 +2414,7 @@ void sub_809BDB4(void)
RemoveWindow(gUnknown_03000F30);
}
-bool8 ScrCmd_gettrainerclass(struct ScriptContext *ctx)
+bool8 ScrCmd_buffertrainerclassname(struct ScriptContext *ctx)
{
u8 stringVarIndex = ScriptReadByte(ctx);
u16 trainerClassId = VarGet(ScriptReadHalfword(ctx));
@@ -2423,7 +2423,7 @@ bool8 ScrCmd_gettrainerclass(struct ScriptContext *ctx)
return FALSE;
}
-bool8 ScrCmd_gettrainername(struct ScriptContext *ctx)
+bool8 ScrCmd_buffertrainername(struct ScriptContext *ctx)
{
u8 stringVarIndex = ScriptReadByte(ctx);
u16 trainerClassId = VarGet(ScriptReadHalfword(ctx));
diff --git a/src/secret_base.c b/src/secret_base.c
index 6ba4312b2..de2b7221a 100644
--- a/src/secret_base.c
+++ b/src/secret_base.c
@@ -175,14 +175,14 @@ void sub_80E8B6C(void)
{
u16 i;
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
for (i = 0; i < 20; i ++)
{
if (sCurSecretBaseId != gSaveBlock1Ptr->secretBases[i].secretBaseId)
{
continue;
}
- gScriptResult = TRUE;
+ gSpecialVar_Result = TRUE;
VarSet(VAR_0x4054, i);
break;
}
@@ -192,11 +192,11 @@ void sub_80E8BC8(void)
{
if (gSaveBlock1Ptr->secretBases[0].secretBaseId != 0)
{
- gScriptResult = TRUE;
+ gSpecialVar_Result = TRUE;
}
else
{
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
}
}
@@ -544,22 +544,22 @@ void sub_80E933C(void)
metatile = MapGridGetMetatileBehaviorAt(gSpecialVar_0x8006 + 7, gSpecialVar_0x8007 + 7);
if (MetatileBehavior_IsMB_B5(metatile) == TRUE || MetatileBehavior_IsMB_C3(metatile) == TRUE)
{
- gScriptResult = gMapHeader.events->mapObjects[objIdx].graphicsId + VAR_0x3F20;
- VarSet(gScriptResult, gDecorations[roomDecor[decorIdx]].tiles[0]);
- gScriptResult = gMapHeader.events->mapObjects[objIdx].localId;
+ gSpecialVar_Result = gMapHeader.events->mapObjects[objIdx].graphicsId + VAR_0x3F20;
+ VarSet(gSpecialVar_Result, gDecorations[roomDecor[decorIdx]].tiles[0]);
+ gSpecialVar_Result = gMapHeader.events->mapObjects[objIdx].localId;
FlagClear(gSpecialVar_0x8004 + 0xAE);
- show_sprite(gScriptResult, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
- sub_808EBA8(gScriptResult, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, gSpecialVar_0x8006, gSpecialVar_0x8007);
- sub_808F254(gScriptResult, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
+ show_sprite(gSpecialVar_Result, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
+ sub_808EBA8(gSpecialVar_Result, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, gSpecialVar_0x8006, gSpecialVar_0x8007);
+ sub_808F254(gSpecialVar_Result, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
if (CurrentMapIsSecretBase() == TRUE && VarGet(VAR_0x4054) != 0)
{
if (category == DECORCAT_DOLL)
{
- sub_808F28C(gScriptResult, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, DECORCAT_DOLL);
+ sub_808F28C(gSpecialVar_Result, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, DECORCAT_DOLL);
}
else if (category == DECORCAT_CUSHION)
{
- sub_808F28C(gScriptResult, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, DECORCAT_CUSHION);
+ sub_808F28C(gSpecialVar_Result, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, DECORCAT_CUSHION);
}
}
gSpecialVar_0x8004 ++;
@@ -608,14 +608,14 @@ void sub_80E9668(struct Coords16 *coords, struct MapEvents *events)
{
sub_80E9608(coords, events);
sub_80E8B6C();
- ScriptContext1_SetupScript(gUnknown_08275BB7);
+ ScriptContext1_SetupScript(EventScript_275BB7);
}
bool8 sub_80E9680(void)
{
sub_80E8B58();
sub_80E8B6C();
- if (gScriptResult == TRUE)
+ if (gSpecialVar_Result == TRUE)
{
return FALSE;
}
@@ -657,11 +657,11 @@ void sub_80E9744(void)
{
if (gSaveBlock1Ptr->secretBases[0].secretBaseId != sCurSecretBaseId)
{
- gScriptResult = TRUE;
+ gSpecialVar_Result = TRUE;
}
else
{
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
}
}
@@ -1016,15 +1016,15 @@ void sub_80E9BDC(void)
{
if (sub_80E9878(VarGet(VAR_0x4054)) == TRUE)
{
- gScriptResult = 1;
+ gSpecialVar_Result = 1;
}
else if (sub_80E9BA8() > 9)
{
- gScriptResult = 2;
+ gSpecialVar_Result = 2;
}
else
{
- gScriptResult = 0;
+ gSpecialVar_Result = 0;
}
}
@@ -1099,9 +1099,9 @@ void game_continue(u8 taskId)
}
gUnknown_03006310 = gUnknown_0858D07C;
gUnknown_03006310.unk_10 = data[6];
- gUnknown_03006310.unk_0c = data[0];
- gUnknown_03006310.unk_00 = gUnknown_0203A020->items;
- gUnknown_03006310.unk_0e = data[3];
+ gUnknown_03006310.totalItems = data[0];
+ gUnknown_03006310.items = gUnknown_0203A020->items;
+ gUnknown_03006310.maxShowed = data[3];
}
void sub_80E9DEC(u32 a0, bool8 flag, struct ListMenu *menu)
@@ -1289,41 +1289,41 @@ const u8 *sub_80EA250(void)
param = sub_80EA20C(VarGet(VAR_0x4054));
if (param == 0)
{
- return gUnknown_08274966;
+ return SecretBase_RedCave1_Text_274966;
}
if (param == 1)
{
- return gUnknown_08274D13;
+ return SecretBase_RedCave1_Text_274D13;
}
if (param == 2)
{
- return gUnknown_08274FFE;
+ return SecretBase_RedCave1_Text_274FFE;
}
if (param == 3)
{
- return gUnknown_08275367;
+ return SecretBase_RedCave1_Text_275367;
}
if (param == 4)
{
- return gUnknown_082756C7;
+ return SecretBase_RedCave1_Text_2756C7;
}
if (param == 5)
{
- return gUnknown_08274B24;
+ return SecretBase_RedCave1_Text_274B24;
}
if (param == 6)
{
- return gUnknown_08274E75;
+ return SecretBase_RedCave1_Text_274E75;
}
if (param == 7)
{
- return gUnknown_082751E1;
+ return SecretBase_RedCave1_Text_2751E1;
}
if (param == 8)
{
- return gUnknown_082754F6;
+ return SecretBase_RedCave1_Text_2754F6;
}
- return gUnknown_082758CC;
+ return SecretBase_RedCave1_Text_2758CC;
}
void sub_80EA2E4(void)
@@ -1335,7 +1335,7 @@ void sub_80EA2E4(void)
void sub_80EA30C(void)
{
- gSaveBlock1Ptr->secretBases[VarGet(VAR_0x4054)].sbr_field_1_5 = gScriptResult;
+ gSaveBlock1Ptr->secretBases[VarGet(VAR_0x4054)].sbr_field_1_5 = gSpecialVar_Result;
}
void sub_80EA354(void)
@@ -1353,7 +1353,7 @@ void sub_80EA354(void)
FlagSet(0x922);
}
gSpecialVar_0x8004 = sub_80EA20C(secretBaseRecordId);
- gScriptResult = gSaveBlock1Ptr->secretBases[secretBaseRecordId].sbr_field_1_5;
+ gSpecialVar_Result = gSaveBlock1Ptr->secretBases[secretBaseRecordId].sbr_field_1_5;
}
@@ -1866,7 +1866,7 @@ void sub_80EAF80(void *records, size_t recordSize, u8 linkIdx)
{
struct SecretBaseRecordMixer mixers[3];
u16 i;
-
+
if (FlagGet(0x60))
{
switch (GetLinkPlayerCount())
diff --git a/src/start_menu.c b/src/start_menu.c
index 37331a922..f45fd8626 100644
--- a/src/start_menu.c
+++ b/src/start_menu.c
@@ -74,12 +74,12 @@ void AddStartMenuAction(u8 action)
static void BuildStartMenuActions_Normal(void)
{
- if (FlagGet(SYS_POKEDEX_GET) == TRUE)
+ if (FlagGet(FLAG_SYS_POKEDEX_GET) == TRUE)
AddStartMenuAction(MENU_ACTION_POKEDEX);
- if (FlagGet(SYS_POKEMON_GET) == TRUE)
+ if (FlagGet(FLAG_SYS_POKEMON_GET) == TRUE)
AddStartMenuAction(MENU_ACTION_POKEMON);
AddStartMenuAction(MENU_ACTION_BAG);
- if (FlagGet(SYS_POKENAV_GET) == TRUE)
+ if (FlagGet(FLAG_SYS_POKENAV_GET) == TRUE)
AddStartMenuAction(MENU_ACTION_POKENAV);
AddStartMenuAction(MENU_ACTION_PLAYER);
AddStartMenuAction(MENU_ACTION_SAVE);
@@ -102,7 +102,7 @@ static void BuildStartMenuActions_LinkMode(void)
{
AddStartMenuAction(MENU_ACTION_POKEMON);
AddStartMenuAction(MENU_ACTION_BAG);
- if (FlagGet(SYS_POKENAV_GET) == TRUE)
+ if (FlagGet(FLAG_SYS_POKENAV_GET) == TRUE)
AddStartMenuAction(MENU_ACTION_POKENAV);
AddStartMenuAction(MENU_ACTION_PLAYER_LINK);
AddStartMenuAction(MENU_ACTION_OPTION);
@@ -113,7 +113,7 @@ static void BuildStartMenuActions_UnionRoom(void)
{
AddStartMenuAction(MENU_ACTION_POKEMON);
AddStartMenuAction(MENU_ACTION_BAG);
- if (FlagGet(SYS_POKENAV_GET) == TRUE)
+ if (FlagGet(FLAG_SYS_POKENAV_GET) == TRUE)
AddStartMenuAction(MENU_ACTION_POKENAV);
AddStartMenuAction(MENU_ACTION_PLAYER);
AddStartMenuAction(MENU_ACTION_OPTION);
diff --git a/src/starter_choose.c b/src/starter_choose.c
new file mode 100644
index 000000000..8cf3cfefa
--- /dev/null
+++ b/src/starter_choose.c
@@ -0,0 +1,391 @@
+#include "global.h"
+#include "starter_choose.h"
+#include "palette.h"
+#include "sprite.h"
+#include "pokemon.h"
+#include "task.h"
+#include "bg.h"
+#include "gpu_regs.h"
+#include "main.h"
+#include "window.h"
+#include "text.h"
+#include "decompress.h"
+#include "menu.h"
+#include "sound.h"
+#include "songs.h"
+#include "event_data.h"
+#include "pokedex.h"
+#include "data2.h"
+#include "international_string_util.h"
+#include "trig.h"
+
+#define STARTER_MON_COUNT 3
+
+// Position of the sprite of the selected starter Pokemon
+#define STARTER_PKMN_POS_X 120
+#define STARTER_PKMN_POS_Y 64
+
+// graphics
+extern const u32 gBirchHelpGfx[];
+extern const u32 gBirchBagTilemap[];
+extern const u32 gBirchGrassTilemap[];
+extern const u16 gBirchBagGrassPal[];
+
+// text
+extern const u8 gText_BirchInTrouble[];
+extern const u8 gText_ConfirmStarterChoice[];
+
+extern const u16 sStarterMon[STARTER_MON_COUNT];
+extern const struct BgTemplate gUnknown_085B1E00[3];
+extern const struct WindowTemplate gUnknown_085B1DCC[];
+extern const struct WindowTemplate gUnknown_085B1DDC;
+extern const struct CompressedSpriteSheet gUnknown_085B1ED8[];
+extern const struct CompressedSpriteSheet gUnknown_085B1EE8[];
+extern const struct SpritePalette gUnknown_085B1EF8[];
+extern const struct SpriteTemplate sSpriteTemplate_PokeBall;
+extern const struct SpriteTemplate sSpriteTemplate_Hand;
+extern const struct SpriteTemplate gUnknown_085B1F40;
+extern const union AffineAnimCmd *const gUnknown_085B1ED0;
+extern const u8 sPokeballCoords[STARTER_MON_COUNT][2];
+extern const struct WindowTemplate gUnknown_085B1DE4;
+extern const u8 gStarterChoose_LabelCoords[][2];
+extern const u8 gUnknown_085B1E0C[];
+extern const u8 gUnknown_085B1E28[][2];
+
+extern void sub_809882C(u8, u16, u8);
+extern void remove_some_task(void);
+extern void clear_scheduled_bg_copies_to_vram(void);
+extern void dp13_810BB8C(void);
+extern void do_scheduled_bg_tilemap_copies_to_vram(void);
+extern u16 sub_818D820(u16);
+extern const u16 *GetOverworldTextboxPalettePtr(void);
+extern u8 sub_818D3E4(u16 species, u32 trainerId, u32 personality, u8 flags, s16 x, s16 y, u8, u16);
+
+// this file's functions
+static void MainCallback2_StarterChoose(void);
+static void sub_8134604(void);
+static void Task_StarterChoose1(u8 taskId);
+static void Task_StarterChoose2(u8 taskId);
+static void Task_StarterChoose3(u8 taskId);
+static void Task_StarterChoose4(u8 taskId);
+static void Task_StarterChoose5(u8 taskId);
+static void Task_StarterChoose6(u8 taskId);
+static void Task_MoveStarterChooseCursor(u8 taskId);
+static void sub_8134668(u8 taskId);
+static void CreateStarterPokemonLabel(u8 selection);
+static u8 CreatePokemonFrontSprite(u16 species, u8 x, u8 y);
+static void StarterPokemonSpriteCallback(struct Sprite *sprite);
+
+static IWRAM_DATA u16 sStarterChooseWindowId;
+
+u16 GetStarterPokemon(u16 chosenStarterId)
+{
+ if (chosenStarterId > STARTER_MON_COUNT)
+ chosenStarterId = 0;
+ return sStarterMon[chosenStarterId];
+}
+
+static void VblankCB_StarterChoose(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+#define tStarterSelection data[0]
+#define tPkmnSpriteId data[1]
+#define tCircleSpriteId data[2]
+
+void CB2_ChooseStarter(void)
+{
+ u16 savedIme;
+ u8 taskId;
+ u8 spriteId;
+
+ SetVBlankCallback(NULL);
+
+ SetGpuReg(REG_OFFSET_DISPCNT, 0);
+ SetGpuReg(REG_OFFSET_BG3CNT, 0);
+ SetGpuReg(REG_OFFSET_BG2CNT, 0);
+ SetGpuReg(REG_OFFSET_BG1CNT, 0);
+ SetGpuReg(REG_OFFSET_BG0CNT, 0);
+
+ ChangeBgX(0, 0, 0);
+ ChangeBgY(0, 0, 0);
+ ChangeBgX(1, 0, 0);
+ ChangeBgY(1, 0, 0);
+ ChangeBgX(2, 0, 0);
+ ChangeBgY(2, 0, 0);
+ ChangeBgX(3, 0, 0);
+ ChangeBgY(3, 0, 0);
+
+ DmaFill16(3, 0, VRAM, VRAM_SIZE);
+ DmaFill32(3, 0, OAM, OAM_SIZE);
+ DmaFill16(3, 0, PLTT, PLTT_SIZE);
+
+ LZ77UnCompVram(&gBirchHelpGfx, (void *)VRAM);
+ LZ77UnCompVram(&gBirchBagTilemap, (void *)(VRAM + 0x3000));
+ LZ77UnCompVram(&gBirchGrassTilemap, (void *)(VRAM + 0x3800));
+
+ ResetBgsAndClearDma3BusyFlags(0);
+ InitBgsFromTemplates(0, gUnknown_085B1E00, ARRAY_COUNT(gUnknown_085B1E00));
+ InitWindows(gUnknown_085B1DCC);
+
+ DeactivateAllTextPrinters();
+ sub_809882C(0, 0x2A8, 0xD0);
+ clear_scheduled_bg_copies_to_vram();
+ remove_some_task();
+ ResetTasks();
+ ResetSpriteData();
+ ResetPaletteFade();
+ FreeAllSpritePalettes();
+ dp13_810BB8C();
+
+ LoadPalette(GetOverworldTextboxPalettePtr(), 0xE0, 0x20);
+ LoadPalette(gBirchBagGrassPal, 0, 0x40);
+ LoadCompressedObjectPic(&gUnknown_085B1ED8[0]);
+ LoadCompressedObjectPic(&gUnknown_085B1EE8[0]);
+ LoadSpritePalettes(gUnknown_085B1EF8);
+ BeginNormalPaletteFade(-1, 0, 0x10, 0, 0);
+
+ EnableInterrupts(DISPSTAT_VBLANK);
+ SetVBlankCallback(VblankCB_StarterChoose);
+ SetMainCallback2(MainCallback2_StarterChoose);
+
+ SetGpuReg(REG_OFFSET_WININ, 0x3F);
+ SetGpuReg(REG_OFFSET_WINOUT, 0x1F);
+ SetGpuReg(REG_OFFSET_WIN0H, 0);
+ SetGpuReg(REG_OFFSET_WIN0V, 0);
+ SetGpuReg(REG_OFFSET_BLDCNT, 0xFE);
+ SetGpuReg(REG_OFFSET_BLDALPHA, 0);
+ SetGpuReg(REG_OFFSET_BLDY, 7);
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON | DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
+
+ ShowBg(0);
+ ShowBg(2);
+ ShowBg(3);
+
+ taskId = CreateTask(Task_StarterChoose1, 0);
+ gTasks[taskId].tStarterSelection = 1;
+
+ // Create hand sprite
+ spriteId = CreateSprite(&sSpriteTemplate_Hand, 120, 56, 2);
+ gSprites[spriteId].data0 = taskId;
+
+ // Create three Pokeball sprites
+ spriteId = CreateSprite(&sSpriteTemplate_PokeBall, sPokeballCoords[0][0], sPokeballCoords[0][1], 2);
+ gSprites[spriteId].data0 = taskId;
+ gSprites[spriteId].data1 = 0;
+
+ spriteId = CreateSprite(&sSpriteTemplate_PokeBall, sPokeballCoords[1][0], sPokeballCoords[1][1], 2);
+ gSprites[spriteId].data0 = taskId;
+ gSprites[spriteId].data1 = 1;
+
+ spriteId = CreateSprite(&sSpriteTemplate_PokeBall, sPokeballCoords[2][0], sPokeballCoords[2][1], 2);
+ gSprites[spriteId].data0 = taskId;
+ gSprites[spriteId].data1 = 2;
+
+ sStarterChooseWindowId = 0xFF;
+}
+
+static void MainCallback2_StarterChoose(void)
+{
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ do_scheduled_bg_tilemap_copies_to_vram();
+ UpdatePaletteFade();
+}
+
+static void Task_StarterChoose1(u8 taskId)
+{
+ CreateStarterPokemonLabel(gTasks[taskId].tStarterSelection);
+ SetWindowBorderStyle(0, FALSE, 0x2A8, 0xD);
+ PrintTextOnWindow(0, 1, gText_BirchInTrouble, 0, 1, 0, NULL);
+ PutWindowTilemap(0);
+ schedule_bg_copy_tilemap_to_vram(0);
+ gTasks[taskId].func = Task_StarterChoose2;
+}
+
+static void Task_StarterChoose2(u8 taskId)
+{
+ u8 selection = gTasks[taskId].tStarterSelection;
+
+ if (gMain.newKeys & A_BUTTON)
+ {
+ u8 spriteId;
+
+ sub_8134604();
+
+ // Create white circle background
+ spriteId = CreateSprite(&gUnknown_085B1F40, sPokeballCoords[selection][0], sPokeballCoords[selection][1], 1);
+ gTasks[taskId].tCircleSpriteId = spriteId;
+
+ // Create Pokemon sprite
+ spriteId = CreatePokemonFrontSprite(GetStarterPokemon(gTasks[taskId].tStarterSelection), sPokeballCoords[selection][0], sPokeballCoords[selection][1]);
+ gSprites[spriteId].affineAnims = &gUnknown_085B1ED0;
+ gSprites[spriteId].callback = StarterPokemonSpriteCallback;
+
+ gTasks[taskId].tPkmnSpriteId = spriteId;
+ gTasks[taskId].func = Task_StarterChoose3;
+ }
+ else if ((gMain.newKeys & DPAD_LEFT) && selection > 0)
+ {
+ gTasks[taskId].tStarterSelection--;
+ gTasks[taskId].func = Task_MoveStarterChooseCursor;
+ }
+ else if ((gMain.newKeys & DPAD_RIGHT) && selection < (STARTER_MON_COUNT - 1))
+ {
+ gTasks[taskId].tStarterSelection++;
+ gTasks[taskId].func = Task_MoveStarterChooseCursor;
+ }
+}
+
+static void Task_StarterChoose3(u8 taskId)
+{
+ if (gSprites[gTasks[taskId].tCircleSpriteId].affineAnimEnded &&
+ gSprites[gTasks[taskId].tCircleSpriteId].pos1.x == STARTER_PKMN_POS_X &&
+ gSprites[gTasks[taskId].tCircleSpriteId].pos1.y == STARTER_PKMN_POS_Y)
+ {
+ gTasks[taskId].func = Task_StarterChoose4;
+ }
+}
+
+static void Task_StarterChoose4(u8 taskId)
+{
+ PlayCry1(GetStarterPokemon(gTasks[taskId].tStarterSelection), 0);
+ FillWindowPixelBuffer(0, 0x11);
+ PrintTextOnWindow(0, 1, gText_ConfirmStarterChoice, 0, 1, 0, NULL);
+ schedule_bg_copy_tilemap_to_vram(0);
+ CreateYesNoMenu(&gUnknown_085B1DDC, 0x2A8, 0xD, 0);
+ gTasks[taskId].func = Task_StarterChoose5;
+}
+
+static void Task_StarterChoose5(u8 taskId)
+{
+ u8 spriteId;
+
+ switch (sub_8198C58())
+ {
+ case 0: // YES
+ // Return the starter choice and exit.
+ gSpecialVar_Result = gTasks[taskId].tStarterSelection;
+ dp13_810BB8C();
+ SetMainCallback2(gMain.savedCallback);
+ break;
+ case 1: // NO
+ case -1: // B button
+ PlaySE(SE_SELECT);
+ spriteId = gTasks[taskId].tPkmnSpriteId;
+ FreeOamMatrix(gSprites[spriteId].oam.matrixNum);
+ sub_818D820(spriteId);
+
+ spriteId = gTasks[taskId].tCircleSpriteId;
+ FreeOamMatrix(gSprites[spriteId].oam.matrixNum);
+ DestroySprite(&gSprites[spriteId]);
+ gTasks[taskId].func = Task_StarterChoose6;
+ break;
+ }
+}
+
+static void Task_StarterChoose6(u8 taskId)
+{
+ gTasks[taskId].func = Task_StarterChoose1;
+}
+
+static void CreateStarterPokemonLabel(u8 selection)
+{
+ u8 text[32];
+ struct WindowTemplate winTemplate;
+ const u8 *speciesName;
+ s32 width;
+ u8 labelLeft, labelRight, labelTop, labelBottom;
+
+ u16 species = GetStarterPokemon(selection);
+ CopyMonCategoryText(SpeciesToNationalPokedexNum(species), text);
+ speciesName = gSpeciesNames[species];
+
+ winTemplate = gUnknown_085B1DE4;
+ winTemplate.tilemapLeft = gStarterChoose_LabelCoords[selection][0];
+ winTemplate.tilemapTop = gStarterChoose_LabelCoords[selection][1];
+
+ sStarterChooseWindowId = AddWindow(&winTemplate);
+ FillWindowPixelBuffer(sStarterChooseWindowId, 0);
+
+ width = GetStringCenterAlignXOffset(7, text, 0x68);
+ box_print(sStarterChooseWindowId, 7, width, 1, gUnknown_085B1E0C, 0, text);
+
+ width = GetStringCenterAlignXOffset(1, speciesName, 0x68);
+ box_print(sStarterChooseWindowId, 1, width, 0x11, gUnknown_085B1E0C, 0, speciesName);
+
+ PutWindowTilemap(sStarterChooseWindowId);
+ schedule_bg_copy_tilemap_to_vram(0);
+
+ labelLeft = gStarterChoose_LabelCoords[selection][0] * 8 - 4;
+ labelRight = (gStarterChoose_LabelCoords[selection][0] + 13) * 8 + 4;
+ labelTop = gStarterChoose_LabelCoords[selection][1] * 8;
+ labelBottom = (gStarterChoose_LabelCoords[selection][1] + 4) * 8;
+ SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(labelLeft, labelRight));
+ SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(labelTop, labelBottom));
+}
+
+static void sub_8134604(void)
+{
+ FillWindowPixelBuffer(sStarterChooseWindowId, 0);
+ ClearWindowTilemap(sStarterChooseWindowId);
+ RemoveWindow(sStarterChooseWindowId);
+ sStarterChooseWindowId = 0xFF;
+ SetGpuReg(REG_OFFSET_WIN0H, 0);
+ SetGpuReg(REG_OFFSET_WIN0V, 0);
+ schedule_bg_copy_tilemap_to_vram(0);
+}
+
+static void Task_MoveStarterChooseCursor(u8 taskId)
+{
+ sub_8134604();
+ gTasks[taskId].func = sub_8134668;
+}
+
+static void sub_8134668(u8 taskId)
+{
+ CreateStarterPokemonLabel(gTasks[taskId].tStarterSelection);
+ gTasks[taskId].func = Task_StarterChoose2;
+}
+
+static u8 CreatePokemonFrontSprite(u16 species, u8 x, u8 y)
+{
+ u8 spriteId;
+
+ spriteId = sub_818D3E4(species, 8, 0, 1, x, y, 0xE, 0xFFFF);
+ gSprites[spriteId].oam.priority = 0;
+ return spriteId;
+}
+
+static void sub_81346DC(struct Sprite *sprite)
+{
+ sprite->pos1.x = gUnknown_085B1E28[gTasks[sprite->data0].tStarterSelection][0];
+ sprite->pos1.y = gUnknown_085B1E28[gTasks[sprite->data0].tStarterSelection][1];
+ sprite->pos2.y = Sin(sprite->data1, 8);
+ sprite->data1 = (u8)(sprite->data1) + 4;
+}
+
+static void sub_813473C(struct Sprite *sprite)
+{
+ if (gTasks[sprite->data0].tStarterSelection == sprite->data1)
+ StartSpriteAnimIfDifferent(sprite, 1);
+ else
+ StartSpriteAnimIfDifferent(sprite, 0);
+}
+
+static void StarterPokemonSpriteCallback(struct Sprite *sprite)
+{
+ //Move sprite to upper center of screen
+ if (sprite->pos1.x > STARTER_PKMN_POS_X)
+ sprite->pos1.x -= 4;
+ if (sprite->pos1.x < STARTER_PKMN_POS_X)
+ sprite->pos1.x += 4;
+ if (sprite->pos1.y > STARTER_PKMN_POS_Y)
+ sprite->pos1.y -= 2;
+ if (sprite->pos1.y < STARTER_PKMN_POS_Y)
+ sprite->pos1.y += 2;
+}
diff --git a/src/text_window.c b/src/text_window.c
index 55aedf688..336536c04 100644
--- a/src/text_window.c
+++ b/src/text_window.c
@@ -23,7 +23,7 @@ const struct TilesPal* sub_8098758(u8 id)
void copy_textbox_border_tile_patterns_to_vram(u8 windowId, u16 destOffset, u8 palOffset)
{
LoadBgTiles(GetWindowAttribute(windowId, WINDOW_PRIORITY), gUnknown_08DDD748, 0x1C0, destOffset);
- LoadPalette(sub_8098C64(), palOffset, 0x20);
+ LoadPalette(GetOverworldTextboxPalettePtr(), palOffset, 0x20);
}
void box_border_load_tiles_and_pal(u8 windowId, u16 destOffset, u8 palOffset)
@@ -113,7 +113,7 @@ const u16* stdpal_get(u8 id)
return &gUnknown_0851017C[id];
}
-const u16* sub_8098C64(void)
+const u16* GetOverworldTextboxPalettePtr(void)
{
return gUnknown_08DDD728;
}
diff --git a/src/tv.c b/src/tv.c
index 3c822b394..1d978b093 100644
--- a/src/tv.c
+++ b/src/tv.c
@@ -214,23 +214,23 @@ const struct {
// TODO: Figure out what these are, and define constants in include/flags.h
const u16 sGoldSymbolFlags[] = {
- SYS_TOWER_GOLD,
- SYS_DOME_GOLD,
- SYS_PALACE_GOLD,
- SYS_ARENA_GOLD,
- SYS_FACTORY_GOLD,
- SYS_PIKE_GOLD,
- SYS_PYRAMID_GOLD
+ FLAG_SYS_TOWER_GOLD,
+ FLAG_SYS_DOME_GOLD,
+ FLAG_SYS_PALACE_GOLD,
+ FLAG_SYS_ARENA_GOLD,
+ FLAG_SYS_FACTORY_GOLD,
+ FLAG_SYS_PIKE_GOLD,
+ FLAG_SYS_PYRAMID_GOLD
};
const u16 sSilverSymbolFlags[] = {
- SYS_TOWER_SILVER,
- SYS_DOME_SILVER,
- SYS_PALACE_SILVER,
- SYS_ARENA_SILVER,
- SYS_FACTORY_SILVER,
- SYS_PIKE_SILVER,
- SYS_PYRAMID_SILVER
+ FLAG_SYS_TOWER_SILVER,
+ FLAG_SYS_DOME_SILVER,
+ FLAG_SYS_PALACE_SILVER,
+ FLAG_SYS_ARENA_SILVER,
+ FLAG_SYS_FACTORY_SILVER,
+ FLAG_SYS_PIKE_SILVER,
+ FLAG_SYS_PYRAMID_SILVER
};
// TODO: Figure out what these are, and define constants in include/vars.h
@@ -823,7 +823,7 @@ u8 FindAnyTVShowOnTheAir(void)
void UpdateTVScreensOnMap(int width, int height)
{
- FlagSet(SYS_TV_WATCH);
+ FlagSet(FLAG_SYS_TV_WATCH);
switch (CheckForBigMovieOrEmergencyNewsOnTV())
{
case 1:
@@ -836,9 +836,9 @@ void UpdateTVScreensOnMap(int width, int height)
{
SetTVMetatilesOnMap(width, height, 0x3);
}
- else if (FlagGet(SYS_TV_START) && (FindAnyTVShowOnTheAir() != 0xff || FindAnyTVNewsOnTheAir() != 0xff || IsTVShowInSearchOfTrainersAiring()))
+ else if (FlagGet(FLAG_SYS_TV_START) && (FindAnyTVShowOnTheAir() != 0xff || FindAnyTVNewsOnTheAir() != 0xff || IsTVShowInSearchOfTrainersAiring()))
{
- FlagClear(SYS_TV_WATCH);
+ FlagClear(FLAG_SYS_TV_WATCH);
SetTVMetatilesOnMap(width, height, 0x3);
}
break;
@@ -1263,7 +1263,7 @@ void InterviewAfter_ContestLiveUpdates(void)
show2->contestLiveUpdates.kind = TVSHOW_CONTEST_LIVE_UPDATES;
show2->contestLiveUpdates.active = TRUE;
StringCopy(show2->contestLiveUpdates.playerName, gSaveBlock2Ptr->playerName);
- show2->contestLiveUpdates.category = gScriptContestCategory;
+ show2->contestLiveUpdates.category = gSpecialVar_ContestCategory;
show2->contestLiveUpdates.species = GetMonData(&gPlayerParty[gUnknown_02039F24], MON_DATA_SPECIES, NULL);
show2->contestLiveUpdates.winningSpecies = show->contestLiveUpdates.winningSpecies;
show2->contestLiveUpdates.appealFlags2 = show->contestLiveUpdates.appealFlags2;
@@ -1288,7 +1288,7 @@ void PutBattleUpdateOnTheAir(u8 a0, u16 a1, u16 a2, u16 a3)
if (sCurTVShowSlot != -1)
{
FindActiveBroadcastByShowType_SetScriptResult(TVSHOW_BATTLE_UPDATE);
- if (gScriptResult != 1)
+ if (gSpecialVar_Result != 1)
{
show = &gSaveBlock1Ptr->tvShows[sCurTVShowSlot];
show->battleUpdate.kind = TVSHOW_BATTLE_UPDATE;
@@ -1337,7 +1337,7 @@ bool8 Put3CheersForPokeblocksOnTheAir(const u8 *partnersName, u8 flavor, u8 unus
return FALSE;
}
FindActiveBroadcastByShowType_SetScriptResult(TVSHOW_3_CHEERS_FOR_POKEBLOCKS);
- if (gScriptResult == 1)
+ if (gSpecialVar_Result == 1)
{
return FALSE;
}
@@ -1527,8 +1527,8 @@ void BravoTrainerPokemonProfile_BeforeInterview2(u8 a0)
if (sCurTVShowSlot != -1)
{
show->bravoTrainer.contestResult = a0;
- show->bravoTrainer.contestCategory = gScriptContestCategory;
- show->bravoTrainer.contestRank = gUnknown_02039F2E;
+ show->bravoTrainer.contestCategory = gSpecialVar_ContestCategory;
+ show->bravoTrainer.contestRank = gSpecialVar_ContestRank;
show->bravoTrainer.species = GetMonData(&gPlayerParty[gUnknown_02039F24], MON_DATA_SPECIES, NULL);
GetMonData(&gPlayerParty[gUnknown_02039F24], MON_DATA_NICKNAME, show->bravoTrainer.pokemonNickname);
StripExtCtrlCodes(show->bravoTrainer.pokemonNickname);
@@ -1606,7 +1606,7 @@ void PutNameRaterShowOnTheAir(void)
TVShow *show;
InterviewBefore_NameRater();
- if (gScriptResult != 1)
+ if (gSpecialVar_Result != 1)
{
GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar1);
if (StringLength(gSaveBlock2Ptr->playerName) > 1 && StringLength(gStringVar1) > 1)
@@ -1653,7 +1653,7 @@ void PutLilycoveContestLadyShowOnTheAir(void)
TVShow *show;
sub_80EFA88();
- if (gScriptResult != TRUE)
+ if (gSpecialVar_Result != TRUE)
{
show = &gSaveBlock1Ptr->tvShows[sCurTVShowSlot];
sub_818E848(&show->contestLiveUpdates2.language);
@@ -1731,7 +1731,7 @@ void sub_80ED718(void)
u16 outbreakIdx;
TVShow *show;
- if (FlagGet(SYS_GAME_CLEAR))
+ if (FlagGet(FLAG_SYS_GAME_CLEAR))
{
for (i = 0; i < 24; i ++)
{
@@ -1883,7 +1883,7 @@ void PutFishingAdviceShowOnTheAir(void)
}
}
-void sub_80EDA3C(u16 species)
+void SetPokemonAnglerSpecies(u16 species)
{
sPokemonAnglerSpecies = species;
}
@@ -1943,7 +1943,7 @@ void sub_80EDB44(void)
show = &gSaveBlock1Ptr->tvShows[sCurTVShowSlot];
show->rivalTrainer.kind = TVSHOW_TODAYS_RIVAL_TRAINER;
show->rivalTrainer.active = FALSE;
- for (i = BADGE01_GET, nBadges = 0; i < BADGE01_GET + 8; i ++)
+ for (i = FLAG_BADGE01_GET, nBadges = 0; i < FLAG_BADGE01_GET + 8; i ++)
{
if (FlagGet(i))
{
@@ -2613,7 +2613,7 @@ bool8 sub_80EE7C0(void)
return TRUE;
}
FindActiveBroadcastByShowType_SetScriptResult(TVSHOW_FAN_CLUB_SPECIAL);
- if (gScriptResult == TRUE)
+ if (gSpecialVar_Result == TRUE)
{
return TRUE;
}
@@ -2814,7 +2814,7 @@ void sub_80EED88(void)
{
u8 newsKind;
- if (FlagGet(SYS_GAME_CLEAR))
+ if (FlagGet(FLAG_SYS_GAME_CLEAR))
{
sCurTVShowSlot = sub_80EEE30(gSaveBlock1Ptr->pokeNews);
if (sCurTVShowSlot != -1 && rbernoulli(1, 100) != TRUE)
@@ -2905,7 +2905,7 @@ void DoPokeNews(void)
i = FindAnyTVNewsOnTheAir();
if (i == 0xFF)
{
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
}
else
{
@@ -2928,7 +2928,7 @@ void DoPokeNews(void)
gSaveBlock1Ptr->pokeNews[i].state = 0;
ShowFieldMessage(sPokeNewsTextGroup_Upcoming[gSaveBlock1Ptr->pokeNews[i].kind]);
}
- gScriptResult = TRUE;
+ gSpecialVar_Result = TRUE;
}
}
@@ -2959,7 +2959,7 @@ bool8 IsPriceDiscounted(u8 newsKind)
switch (newsKind)
{
case POKENEWS_SLATEPORT:
- if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP_SLATEPORT_CITY && gSaveBlock1Ptr->location.mapNum == MAP_ID_SLATEPORT_CITY && gScriptLastTalked == 25)
+ if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP_SLATEPORT_CITY && gSaveBlock1Ptr->location.mapNum == MAP_ID_SLATEPORT_CITY && gSpecialVar_LastTalked == 25)
{
return TRUE;
}
@@ -3005,7 +3005,7 @@ void sub_80EF120(u16 days)
}
else
{
- if (gSaveBlock1Ptr->pokeNews[i].state == 0 && FlagGet(SYS_GAME_CLEAR) == TRUE)
+ if (gSaveBlock1Ptr->pokeNews[i].state == 0 && FlagGet(FLAG_SYS_GAME_CLEAR) == TRUE)
{
gSaveBlock1Ptr->pokeNews[i].state = 1;
}
@@ -3189,7 +3189,7 @@ void FindActiveBroadcastByShowType_SetScriptResult(u8 kind)
{
if (gSaveBlock1Ptr->tvShows[i].common.active == TRUE)
{
- gScriptResult = TRUE;
+ gSpecialVar_Result = TRUE;
}
else
{
@@ -3205,7 +3205,7 @@ void FindActiveBroadcastByShowType_SetScriptResult(u8 kind)
void InterviewBefore(void)
{
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
switch (gSpecialVar_0x8005)
{
case TVSHOW_FAN_CLUB_LETTER:
@@ -3244,7 +3244,7 @@ void InterviewBefore(void)
void InterviewBefore_FanClubLetter(void)
{
FindActiveBroadcastByShowType_SetScriptResult(TVSHOW_FAN_CLUB_LETTER);
- if (!gScriptResult)
+ if (!gSpecialVar_Result)
{
StringCopy(gStringVar1, gSpeciesNames[GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_SPECIES, NULL)]);
InitializeEasyChatWordArray(gSaveBlock1Ptr->tvShows[sCurTVShowSlot].fanclubLetter.words, 6);
@@ -3254,7 +3254,7 @@ void InterviewBefore_FanClubLetter(void)
void InterviewBefore_RecentHappenings(void)
{
FindActiveBroadcastByShowType_SetScriptResult(TVSHOW_RECENT_HAPPENINGS);
- if (!gScriptResult)
+ if (!gSpecialVar_Result)
{
InitializeEasyChatWordArray(gSaveBlock1Ptr->tvShows[sCurTVShowSlot].recentHappenings.words, 6);
}
@@ -3263,7 +3263,7 @@ void InterviewBefore_RecentHappenings(void)
void InterviewBefore_PkmnFanClubOpinions(void)
{
FindActiveBroadcastByShowType_SetScriptResult(TVSHOW_PKMN_FAN_CLUB_OPINIONS);
- if (!gScriptResult)
+ if (!gSpecialVar_Result)
{
StringCopy(gStringVar1, gSpeciesNames[GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_SPECIES, NULL)]);
GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_NICKNAME, gStringVar2);
@@ -3274,7 +3274,7 @@ void InterviewBefore_PkmnFanClubOpinions(void)
void InterviewBefore_Dummy(void)
{
- gScriptResult = TRUE;
+ gSpecialVar_Result = TRUE;
}
void InterviewBefore_NameRater(void)
@@ -3285,7 +3285,7 @@ void InterviewBefore_NameRater(void)
void InterviewBefore_BravoTrainerPkmnProfile(void)
{
FindActiveBroadcastByShowType_SetScriptResult(TVSHOW_BRAVO_TRAINER_POKEMON_PROFILE);
- if (!gScriptResult)
+ if (!gSpecialVar_Result)
{
InitializeEasyChatWordArray(gSaveBlock1Ptr->tvShows[sCurTVShowSlot].bravoTrainer.words, 2);
}
@@ -3304,7 +3304,7 @@ void InterviewBefore_3CheersForPokeblocks(void)
void InterviewBefore_BravoTrainerBTProfile(void)
{
FindActiveBroadcastByShowType_SetScriptResult(TVSHOW_BRAVO_TRAINER_BATTLE_TOWER_PROFILE);
- if (!gScriptResult)
+ if (!gSpecialVar_Result)
{
InitializeEasyChatWordArray(gSaveBlock1Ptr->tvShows[sCurTVShowSlot].bravoTrainerTower.words, 1);
}
@@ -3313,7 +3313,7 @@ void InterviewBefore_BravoTrainerBTProfile(void)
void InterviewBefore_FanClubSpecial(void)
{
FindActiveBroadcastByShowType_SetScriptResult(TVSHOW_FAN_CLUB_SPECIAL);
- if (!gScriptResult)
+ if (!gSpecialVar_Result)
{
InitializeEasyChatWordArray(gSaveBlock1Ptr->tvShows[sCurTVShowSlot].fanClubSpecial.words, 1);
}
@@ -3429,11 +3429,11 @@ void sub_80EFA88(void)
gSpecialVar_0x8006 = sCurTVShowSlot;
if (sCurTVShowSlot == -1)
{
- gScriptResult = TRUE;
+ gSpecialVar_Result = TRUE;
}
else
{
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
}
}
@@ -3636,7 +3636,7 @@ void ChangeBoxPokemonNickname(void)
{
struct BoxPokemon *boxMon;
- boxMon = GetBoxedMonPtr(gSpecialVar_0x8012, gSpecialVar_0x8013);
+ boxMon = GetBoxedMonPtr(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos);
GetBoxMonData(boxMon, MON_DATA_NICKNAME, gStringVar3);
GetBoxMonData(boxMon, MON_DATA_NICKNAME, gStringVar2);
DoNamingScreen(3, gStringVar2, GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL), GetBoxMonGender(boxMon), GetBoxMonData(boxMon, MON_DATA_PERSONALITY, NULL), ChangeBoxPokemonNickname_CB);
@@ -3644,7 +3644,7 @@ void ChangeBoxPokemonNickname(void)
void ChangeBoxPokemonNickname_CB(void)
{
- SetBoxMonNickFromAnyBox(gSpecialVar_0x8012, gSpecialVar_0x8013, gStringVar2);
+ SetBoxMonNickFromAnyBox(gSpecialVar_MonBoxId, gSpecialVar_MonBoxPos, gStringVar2);
c2_exit_to_overworld_1_continue_scripts_restart_music();
}
@@ -3658,11 +3658,11 @@ void TV_CheckMonOTIDEqualsPlayerID(void)
{
if (GetPlayerIDAsU32() == GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_OT_ID, NULL))
{
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
}
else
{
- gScriptResult = TRUE;
+ gSpecialVar_Result = TRUE;
}
}
@@ -3712,11 +3712,11 @@ u8 CheckForBigMovieOrEmergencyNewsOnTV(void)
return 0;
}
}
- if (FlagGet(SYS_TV_LATI) == TRUE)
+ if (FlagGet(FLAG_SYS_TV_LATI) == TRUE)
{
return 1;
}
- if (FlagGet(SYS_TV_HOME) == TRUE)
+ if (FlagGet(FLAG_SYS_TV_HOME) == TRUE)
{
return 2;
}
@@ -4561,7 +4561,7 @@ void sub_80F0B64(void)
{
u16 i;
- if (FlagGet(SYS_GAME_CLEAR) != TRUE)
+ if (FlagGet(FLAG_SYS_GAME_CLEAR) != TRUE)
{
for (i = 0; i < 24; i ++)
{
@@ -4736,7 +4736,7 @@ void sub_80F0F24(void)
{
u8 i;
- if (FlagGet(SYS_GAME_CLEAR) != TRUE)
+ if (FlagGet(FLAG_SYS_GAME_CLEAR) != TRUE)
{
for (i = 0; i < 16; i ++)
{
@@ -5108,7 +5108,7 @@ void DoTVShowBravoTrainerPokemonProfile(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -5180,7 +5180,7 @@ void DoTVShowBravoTrainerBattleTower(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch(state)
{
@@ -5277,7 +5277,7 @@ void DoTVShowTodaysSmartShopper(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch(state)
{
@@ -5400,7 +5400,7 @@ void DoTVShowTheNameRaterShow(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -5498,7 +5498,7 @@ void DoTVShowPokemonTodaySuccessfulCapture(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -5576,7 +5576,7 @@ void DoTVShowPokemonTodayFailedCapture(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -5630,7 +5630,7 @@ void DoTVShowPokemonFanClubLetter(void)
u16 rval;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -5683,7 +5683,7 @@ void DoTVShowRecentHappenings(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -5718,7 +5718,7 @@ void DoTVShowPokemonFanClubOpinions(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -5768,7 +5768,7 @@ void DoTVShowPokemonContestLiveUpdates(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -6115,7 +6115,7 @@ void DoTVShowPokemonBattleUpdate(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -6187,7 +6187,7 @@ void DoTVShow3CheersForPokeblocks(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -6288,7 +6288,7 @@ void DoTVShowInSearchOfTrainers(void)
{
u8 state;
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -6344,7 +6344,7 @@ void DoTVShowInSearchOfTrainers(void)
CopyEasyChatWord(gStringVar1, gSaveBlock1Ptr->gabbyAndTyData.quote[0]);
StringCopy(gStringVar2, gSpeciesNames[gSaveBlock1Ptr->gabbyAndTyData.mon1]);
StringCopy(gStringVar3, gSpeciesNames[gSaveBlock1Ptr->gabbyAndTyData.mon2]);
- gScriptResult = TRUE;
+ gSpecialVar_Result = TRUE;
sTVShowState = 0;
TakeTVShowInSearchOfTrainersOffTheAir();
break;
@@ -6358,7 +6358,7 @@ void DoTVShowPokemonAngler(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
if (show->pokemonAngler.nBites < show->pokemonAngler.nFails)
{
sTVShowState = 0;
@@ -6392,7 +6392,7 @@ void DoTVShowTheWorldOfMasters(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -6422,7 +6422,7 @@ void DoTVShowTodaysRivalTrainer(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -6432,10 +6432,10 @@ void DoTVShowTodaysRivalTrainer(void)
default:
sTVShowState = 7;
break;
- case REGION_MAP_SECRET_BASE:
+ case MAPSEC_SECRET_BASE:
sTVShowState = 8;
break;
- case REGION_MAP_NONE:
+ case MAPSEC_DYNAMIC:
switch (show->rivalTrainer.mapDataId)
{
case 0x115 ... 0x117:
@@ -6571,7 +6571,7 @@ void DoTVShowDewfordTrendWatcherNetwork(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -6627,13 +6627,13 @@ void DoTVShowHoennTreasureInvestigators(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
case 0:
StringCopy(gStringVar1, ItemId_GetItem(show->treasureInvestigators.item)->name);
- if (show->treasureInvestigators.location == REGION_MAP_NONE)
+ if (show->treasureInvestigators.location == MAPSEC_DYNAMIC)
{
switch (show->treasureInvestigators.mapDataId)
{
@@ -6671,7 +6671,7 @@ void DoTVShowFindThatGamer(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -6745,7 +6745,7 @@ void DoTVShowBreakingNewsTV(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -6848,7 +6848,7 @@ void DoTVShowSecretBaseVisit(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -6944,7 +6944,7 @@ void DoTVShowPokemonLotteryWinnerFlashReport(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
TVShowConvertInternationalString(gStringVar1, show->lottoWinner.playerName, show->lottoWinner.language);
if (show->lottoWinner.whichPrize == 0)
@@ -6974,7 +6974,7 @@ void DoTVShowThePokemonBattleSeminar(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -7038,7 +7038,7 @@ void DoTVShowTrainerFanClubSpecial(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -7104,7 +7104,7 @@ void DoTVShowTrainerFanClub(void)
u32 playerId;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -7191,7 +7191,7 @@ void DoTVShowSpotTheCuties(void)
u32 playerId;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -7296,7 +7296,7 @@ void DoTVShowPokemonNewsBattleFrontier(void)
u32 playerId;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -7445,7 +7445,7 @@ void DoTVShowWhatsNo1InHoennToday(void)
u32 playerId;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -7561,7 +7561,7 @@ void DoTVShowSecretBaseSecrets(void)
u16 i;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -7797,7 +7797,7 @@ void DoTVShowSafariFanClub(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -7884,7 +7884,7 @@ void DoTVShowPokemonContestLiveUpdates2(void)
u8 state;
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
- gScriptResult = FALSE;
+ gSpecialVar_Result = FALSE;
state = sTVShowState;
switch (state)
{
@@ -7916,7 +7916,7 @@ void DoTVShowPokemonContestLiveUpdates2(void)
void TVShowDone(void)
{
- gScriptResult = TRUE;
+ gSpecialVar_Result = TRUE;
sTVShowState = 0;
gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004].common.active = FALSE;
}
diff --git a/src/walda_phrase.c b/src/walda_phrase.c
index 7e06d1319..59fd3fedb 100644
--- a/src/walda_phrase.c
+++ b/src/walda_phrase.c
@@ -98,17 +98,17 @@ u16 TryGetWallpaperWithWaldaPhrase(void)
u16 backgroundClr, foregroundClr;
u8 patternId, iconId;
u16 trainerId = ReadUnalignedWord(gSaveBlock2Ptr->playerTrainerId);
- gScriptResult = TryCalculateWallpaper(&backgroundClr, &foregroundClr, &iconId, &patternId, trainerId, GetWaldaPhrasePtr());
+ gSpecialVar_Result = TryCalculateWallpaper(&backgroundClr, &foregroundClr, &iconId, &patternId, trainerId, GetWaldaPhrasePtr());
- if (gScriptResult)
+ if (gSpecialVar_Result)
{
SetWaldaWallpaperPatternId(patternId);
SetWaldaWallpaperIconId(iconId);
SetWaldaWallpaperColors(backgroundClr, foregroundClr);
}
- SetWaldaWallpaperLockedOrUnlocked(gScriptResult);
- return (bool8)(gScriptResult);
+ SetWaldaWallpaperLockedOrUnlocked(gSpecialVar_Result);
+ return (bool8)(gSpecialVar_Result);
}
static u8 GetLetterTableId(u8 letter)
diff --git a/src/wild_encounter.c b/src/wild_encounter.c
new file mode 100644
index 000000000..ce1e02e5e
--- /dev/null
+++ b/src/wild_encounter.c
@@ -0,0 +1,933 @@
+#include "global.h"
+#include "wild_encounter.h"
+#include "pokemon.h"
+#include "species.h"
+#include "metatile_behavior.h"
+#include "fieldmap.h"
+#include "rng.h"
+#include "map_constants.h"
+#include "field_player_avatar.h"
+#include "abilities.h"
+#include "event_data.h"
+#include "safari_zone.h"
+#include "pokeblock.h"
+#include "battle_setup.h"
+#include "roamer.h"
+#include "game_stat.h"
+#include "tv.h"
+#include "link.h"
+#include "script.h"
+#include "items.h"
+
+extern const u8 EventScript_RepelWoreOff[];
+
+#define NUM_FEEBAS_SPOTS 6
+
+extern const u16 gRoute119WaterTileData[];
+extern const struct WildPokemonHeader gBattlePikeWildMonHeaders[];
+extern const struct WildPokemonHeader gBattlePyramidWildMonHeaders[];
+extern const struct WildPokemon gWildFeebasRoute119Data;
+
+extern u8 GetBattlePikeWildMonHeaderId(void);
+extern bool32 TryGenerateBattlePikeWildMon(bool8 checkKeenEyeIntimidate);
+extern void GenerateBattlePyramidWildMon(void);
+extern bool8 InBattlePike(void);
+extern bool8 InBattlePyramid(void);
+
+// this file's functions
+static u16 FeebasRandom(void);
+static void FeebasSeedRng(u16 seed);
+static bool8 IsWildLevelAllowedByRepel(u8 level);
+static void ApplyFluteEncounterRateMod(u32 *encRate);
+static void ApplyCleanseTagEncounterRateMod(u32 *encRate);
+static bool8 TryGetAbilityInfluencedWildMonIndex(const struct WildPokemon *wildMon, u8 type, u8 ability, u8 *monIndex);
+static bool8 IsAbilityAllowingEncounter(u8 level);
+
+EWRAM_DATA u8 sWildEncountersDisabled = 0;
+EWRAM_DATA u32 sFeebasRngValue = 0;
+
+void DisableWildEncounters(bool8 disabled)
+{
+ sWildEncountersDisabled = disabled;
+}
+
+static u16 GetRoute119WaterTileNum(s16 x, s16 y, u8 section)
+{
+ u16 xCur;
+ u16 yCur;
+ u16 yMin = gRoute119WaterTileData[section * 3 + 0];
+ u16 yMax = gRoute119WaterTileData[section * 3 + 1];
+ u16 tileNum = gRoute119WaterTileData[section * 3 + 2];
+
+ for (yCur = yMin; yCur <= yMax; yCur++)
+ {
+ for (xCur = 0; xCur < gMapHeader.mapData->width; xCur++)
+ {
+ u8 tileBehaviorId = MapGridGetMetatileBehaviorAt(xCur + 7, yCur + 7);
+ if (MetatileBehavior_IsSurfableAndNotWaterfall(tileBehaviorId) == TRUE)
+ {
+ tileNum++;
+ if (x == xCur && y == yCur)
+ return tileNum;
+ }
+ }
+ }
+ return tileNum + 1;
+}
+
+static bool8 CheckFeebas(void)
+{
+ u8 i;
+ u16 feebasSpots[NUM_FEEBAS_SPOTS];
+ s16 x;
+ s16 y;
+ u8 route119Section = 0;
+ u16 waterTileNum;
+
+ if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP_ROUTE119
+ && gSaveBlock1Ptr->location.mapNum == MAP_ID_ROUTE119)
+ {
+ GetXYCoordsOneStepInFrontOfPlayer(&x, &y);
+ x -= 7;
+ y -= 7;
+
+#ifdef NONMATCHING
+ if (y >= gRoute119WaterTileData[3 * 1 + 0] && y <= gRoute119WaterTileData[3 * 1 + 1])
+ route119Section = 1;
+ if (y >= gRoute119WaterTileData[3 * 2 + 0] && y <= gRoute119WaterTileData[3 * 2 + 1])
+ route119Section = 2;
+#else
+ {
+ register const u16 *arr asm("r0");
+ if (y >= (arr = gRoute119WaterTileData)[3 * 1 + 0] && y <= arr[3 * 1 + 1])
+ route119Section = 1;
+ if (y >= arr[3 * 2 + 0] && y <= arr[3 * 2 + 1])
+ route119Section = 2;
+ }
+#endif
+
+ if (Random() % 100 > 49) // 50% chance of encountering Feebas
+ return FALSE;
+
+ FeebasSeedRng(gSaveBlock1Ptr->easyChatPairs[0].unk2);
+ for (i = 0; i != NUM_FEEBAS_SPOTS;)
+ {
+ feebasSpots[i] = FeebasRandom() % 447;
+ if (feebasSpots[i] == 0)
+ feebasSpots[i] = 447;
+ if (feebasSpots[i] < 1 || feebasSpots[i] >= 4)
+ i++;
+ }
+ waterTileNum = GetRoute119WaterTileNum(x, y, route119Section);
+ for (i = 0; i < NUM_FEEBAS_SPOTS; i++)
+ {
+ if (waterTileNum == feebasSpots[i])
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+// The number 1103515245 comes from the example implementation of rand and srand
+// in the ISO C standard.
+
+static u16 FeebasRandom(void)
+{
+ sFeebasRngValue = (1103515245 * sFeebasRngValue) + 12345;
+ return sFeebasRngValue >> 16;
+}
+
+static void FeebasSeedRng(u16 seed)
+{
+ sFeebasRngValue = seed;
+}
+
+static u8 ChooseWildMonIndex_Land(void)
+{
+ u8 rand = Random() % 100;
+
+ if (rand < 20) // 20% chance
+ return 0;
+ else if (rand >= 20 && rand < 40) // 20% chance
+ return 1;
+ else if (rand >= 40 && rand < 50) // 10% chance
+ return 2;
+ else if (rand >= 50 && rand < 60) // 10% chance
+ return 3;
+ else if (rand >= 60 && rand < 70) // 10% chance
+ return 4;
+ else if (rand >= 70 && rand < 80) // 10% chance
+ return 5;
+ else if (rand >= 80 && rand < 85) // 5% chance
+ return 6;
+ else if (rand >= 85 && rand < 90) // 5% chance
+ return 7;
+ else if (rand >= 90 && rand < 94) // 4% chance
+ return 8;
+ else if (rand >= 94 && rand < 98) // 4% chance
+ return 9;
+ else if (rand == 98) // 1% chance
+ return 10;
+ else // 1% chance
+ return 11;
+}
+
+static u8 ChooseWildMonIndex_WaterRock(void)
+{
+ u8 rand = Random() % 100;
+
+ if (rand < 60) // 60% chance
+ return 0;
+ else if (rand >= 60 && rand < 90) // 30% chance
+ return 1;
+ else if (rand >= 90 && rand < 95) // 5% chance
+ return 2;
+ else if (rand >= 95 && rand < 99) // 4% chance
+ return 3;
+ else // 1% chance
+ return 4;
+}
+
+enum
+{
+ OLD_ROD,
+ GOOD_ROD,
+ SUPER_ROD
+};
+
+static u8 ChooseWildMonIndex_Fishing(u8 rod)
+{
+ u8 wildMonIndex = 0;
+ u8 rand = Random() % 100;
+
+ switch (rod)
+ {
+ case OLD_ROD:
+ if (rand < 70) // 70% chance
+ wildMonIndex = 0;
+ else // 30% chance
+ wildMonIndex = 1;
+ break;
+ case GOOD_ROD:
+ if (rand < 60) // 60% chance
+ wildMonIndex = 2;
+ if (rand >= 60 && rand < 80) // 20% chance
+ wildMonIndex = 3;
+ if (rand >= 80 && rand < 100) // 20% chance
+ wildMonIndex = 4;
+ break;
+ case SUPER_ROD:
+ if (rand < 40) // 40% chance
+ wildMonIndex = 5;
+ if (rand >= 40 && rand < 80) // 40% chance
+ wildMonIndex = 6;
+ if (rand >= 80 && rand < 95) // 15% chance
+ wildMonIndex = 7;
+ if (rand >= 95 && rand < 99) // 4% chance
+ wildMonIndex = 8;
+ if (rand == 99) // 1% chance
+ wildMonIndex = 9;
+ break;
+ }
+ return wildMonIndex;
+}
+
+static u8 ChooseWildMonLevel(const struct WildPokemon *wildPokemon)
+{
+ u8 min;
+ u8 max;
+ u8 range;
+ u8 rand;
+
+ // Make sure minimum level is less than maximum level
+ if (wildPokemon->maxLevel >= wildPokemon->minLevel)
+ {
+ min = wildPokemon->minLevel;
+ max = wildPokemon->maxLevel;
+ }
+ else
+ {
+ min = wildPokemon->maxLevel;
+ max = wildPokemon->minLevel;
+ }
+ range = max - min + 1;
+ rand = Random() % range;
+
+ // check ability for max level mon
+ if (!GetMonData(&gPlayerParty[0], MON_DATA_SANITY_BIT3))
+ {
+ u8 ability = GetMonAbility(&gPlayerParty[0]);
+ if (ability == ABILITY_HUSTLE || ability == ABILITY_VITAL_SPIRIT || ability == ABILITY_PRESSURE)
+ {
+ if (Random() % 2 == 0)
+ return max;
+
+ if (rand != 0)
+ rand--;
+ }
+ }
+
+ return min + rand;
+}
+
+static u16 GetCurrentMapWildMonHeaderId(void)
+{
+ u16 i;
+
+ for (i = 0; ; i++)
+ {
+ const struct WildPokemonHeader *wildHeader = &gWildMonHeaders[i];
+ if (wildHeader->mapGroup == 0xFF)
+ break;
+
+ if (gWildMonHeaders[i].mapGroup == gSaveBlock1Ptr->location.mapGroup &&
+ gWildMonHeaders[i].mapNum == gSaveBlock1Ptr->location.mapNum)
+ {
+ if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP_ALTERING_CAVE &&
+ gSaveBlock1Ptr->location.mapNum == MAP_ID_ALTERING_CAVE)
+ {
+ u16 alteringCaveId = VarGet(VAR_ALTERING_CAVE_WILD_SET);
+ if (alteringCaveId > 8)
+ alteringCaveId = 0;
+
+ i += alteringCaveId;
+ }
+
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static u8 PickWildMonNature(void)
+{
+ u8 i;
+ u8 j;
+ struct Pokeblock *safariPokeblock;
+ u8 natures[25];
+
+ if (GetSafariZoneFlag() == TRUE && Random() % 100 < 80)
+ {
+ safariPokeblock = SafariZoneGetActivePokeblock();
+ if (safariPokeblock != NULL)
+ {
+ for (i = 0; i < 25; i++)
+ natures[i] = i;
+ for (i = 0; i < 24; i++)
+ {
+ for (j = i + 1; j < 25; j++)
+ {
+ if (Random() & 1)
+ {
+ u8 temp = natures[i];
+
+ natures[i] = natures[j];
+ natures[j] = temp;
+ }
+ }
+ }
+ for (i = 0; i < 25; i++)
+ {
+ if (PokeblockGetGain(natures[i], safariPokeblock) > 0)
+ return natures[i];
+ }
+ }
+ }
+ // check synchronize for a pokemon with the same ability
+ if (!GetMonData(&gPlayerParty[0], MON_DATA_SANITY_BIT3)
+ && GetMonAbility(&gPlayerParty[0]) == ABILITY_SYNCHRONIZE
+ && Random() % 2 == 0)
+ {
+ return GetMonData(&gPlayerParty[0], MON_DATA_PERSONALITY) % 25;
+ }
+
+ // random nature
+ return Random() % 25;
+}
+
+static void CreateWildMon(u16 species, u8 level)
+{
+ bool32 checkCuteCharm;
+
+ ZeroEnemyPartyMons();
+ checkCuteCharm = TRUE;
+
+ switch (gBaseStats[species].genderRatio)
+ {
+ case MON_MALE:
+ case MON_FEMALE:
+ case MON_GENDERLESS:
+ checkCuteCharm = FALSE;
+ break;
+ }
+
+ if (checkCuteCharm
+ && !GetMonData(&gPlayerParty[0], MON_DATA_SANITY_BIT3)
+ && GetMonAbility(&gPlayerParty[0]) == ABILITY_CUTE_CHARM
+ && Random() % 3 != 0)
+ {
+ u16 leadingMonSpecies = GetMonData(&gPlayerParty[0], MON_DATA_SPECIES);
+ u32 leadingMonPersonality = GetMonData(&gPlayerParty[0], MON_DATA_PERSONALITY);
+ u8 gender = GetGenderFromSpeciesAndPersonality(leadingMonSpecies, leadingMonPersonality);
+
+ // misses mon is genderless check, although no genderless mon can have cute charm as ability
+ if (gender == MON_FEMALE)
+ gender = MON_MALE;
+ else
+ gender = MON_FEMALE;
+
+ CreateMonWithGenderNatureLetter(&gEnemyParty[0], species, level, 32, gender, PickWildMonNature(), 0);
+ return;
+ }
+
+ CreateMonWithNature(&gEnemyParty[0], species, level, 32, PickWildMonNature());
+}
+
+enum
+{
+ WILD_AREA_LAND,
+ WILD_AREA_WATER,
+ WILD_AREA_ROCKS,
+ WILD_AREA_FISHING,
+};
+
+#define WILD_CHECK_REPEL 0x1
+#define WILD_CHECK_KEEN_EYE 0x2
+
+static bool8 TryGenerateWildMon(const struct WildPokemonInfo *wildMonInfo, u8 area, u8 flags)
+{
+ u8 wildMonIndex = 0;
+ u8 level;
+
+ switch (area)
+ {
+ case WILD_AREA_LAND:
+ if (TryGetAbilityInfluencedWildMonIndex(wildMonInfo->wildPokemon, TYPE_STEEL, ABILITY_MAGNET_PULL, &wildMonIndex))
+ break;
+ if (TryGetAbilityInfluencedWildMonIndex(wildMonInfo->wildPokemon, TYPE_ELECTRIC, ABILITY_STATIC, &wildMonIndex))
+ break;
+
+ wildMonIndex = ChooseWildMonIndex_Land();
+ break;
+ case WILD_AREA_WATER:
+ if (TryGetAbilityInfluencedWildMonIndex(wildMonInfo->wildPokemon, TYPE_ELECTRIC, ABILITY_STATIC, &wildMonIndex))
+ break;
+
+ wildMonIndex = ChooseWildMonIndex_WaterRock();
+ break;
+ case WILD_AREA_ROCKS:
+ wildMonIndex = ChooseWildMonIndex_WaterRock();
+ break;
+ }
+
+ level = ChooseWildMonLevel(&wildMonInfo->wildPokemon[wildMonIndex]);
+ if (flags & WILD_CHECK_REPEL && !IsWildLevelAllowedByRepel(level))
+ return FALSE;
+ if (gMapHeader.mapDataId != 0x166 && flags & WILD_CHECK_KEEN_EYE && !IsAbilityAllowingEncounter(level))
+ return FALSE;
+
+ CreateWildMon(wildMonInfo->wildPokemon[wildMonIndex].species, level);
+ return TRUE;
+}
+
+static u16 GenerateFishingWildMon(const struct WildPokemonInfo *wildMonInfo, u8 rod)
+{
+ u8 wildMonIndex = ChooseWildMonIndex_Fishing(rod);
+ u8 level = ChooseWildMonLevel(&wildMonInfo->wildPokemon[wildMonIndex]);
+
+ CreateWildMon(wildMonInfo->wildPokemon[wildMonIndex].species, level);
+ return wildMonInfo->wildPokemon[wildMonIndex].species;
+}
+
+static bool8 SetUpMassOutbreakEncounter(u8 flags)
+{
+ u16 i;
+
+ if (flags & WILD_CHECK_REPEL && !IsWildLevelAllowedByRepel(gSaveBlock1Ptr->outbreakPokemonLevel))
+ return FALSE;
+
+ CreateWildMon(gSaveBlock1Ptr->outbreakPokemonSpecies, gSaveBlock1Ptr->outbreakPokemonLevel);
+ for (i = 0; i < 4; i++)
+ SetMonMoveSlot(&gEnemyParty[0], gSaveBlock1Ptr->outbreakPokemonMoves[i], i);
+
+ return TRUE;
+}
+
+static bool8 DoMassOutbreakEncounterTest(void)
+{
+ if (gSaveBlock1Ptr->outbreakPokemonSpecies != 0
+ && gSaveBlock1Ptr->location.mapNum == gSaveBlock1Ptr->outbreakLocationMapNum
+ && gSaveBlock1Ptr->location.mapGroup == gSaveBlock1Ptr->outbreakLocationMapGroup)
+ {
+ if (Random() % 100 < gSaveBlock1Ptr->outbreakPokemonProbability)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool8 DoWildEncounterRateDiceRoll(u16 encounterRate)
+{
+ if (Random() % 2880 < encounterRate)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static bool8 DoWildEncounterRateTest(u32 encounterRate, bool8 ignoreAbility)
+{
+ encounterRate *= 16;
+ if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE))
+ encounterRate = encounterRate * 80 / 100;
+ ApplyFluteEncounterRateMod(&encounterRate);
+ ApplyCleanseTagEncounterRateMod(&encounterRate);
+ if (!ignoreAbility && !GetMonData(&gPlayerParty[0], MON_DATA_SANITY_BIT3))
+ {
+ u32 ability = GetMonAbility(&gPlayerParty[0]);
+
+ if (ability == ABILITY_STENCH && gMapHeader.mapDataId == 0x169)
+ encounterRate = encounterRate * 3 / 4;
+ else if (ability == ABILITY_STENCH)
+ encounterRate /= 2;
+ else if (ability == ABILITY_ILLUMINATE)
+ encounterRate *= 2;
+ else if (ability == ABILITY_WHITE_SMOKE)
+ encounterRate /= 2;
+ else if (ability == ABILITY_ARENA_TRAP)
+ encounterRate *= 2;
+ else if (ability == ABILITY_SAND_VEIL && gSaveBlock1Ptr->weather == 8)
+ encounterRate /= 2;
+ }
+ if (encounterRate > 2880)
+ encounterRate = 2880;
+ return DoWildEncounterRateDiceRoll(encounterRate);
+}
+
+static bool8 DoGlobalWildEncounterDiceRoll(void)
+{
+ if (Random() % 100 >= 60)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+static bool8 AreLegendariesInSootopolisPreventingEncounters(void)
+{
+ if (gSaveBlock1Ptr->location.mapGroup != MAP_GROUP_SOOTOPOLIS_CITY
+ || gSaveBlock1Ptr->location.mapNum != MAP_ID_SOOTOPOLIS_CITY)
+ {
+ return FALSE;
+ }
+
+ return FlagGet(FLAG_LEGENDARIES_IN_SOOTOPOLIS);
+}
+
+bool8 StandardWildEncounter(u16 currMetaTileBehavior, u16 previousMetaTileBehavior)
+{
+ u16 headerId;
+ struct Roamer *roamer;
+
+ if (sWildEncountersDisabled == TRUE)
+ return FALSE;
+
+ headerId = GetCurrentMapWildMonHeaderId();
+ if (headerId == 0xFFFF) // invalid
+ {
+ if (gMapHeader.mapDataId == 0x166)
+ {
+ headerId = GetBattlePikeWildMonHeaderId();
+ if (previousMetaTileBehavior != currMetaTileBehavior && !DoGlobalWildEncounterDiceRoll())
+ return FALSE;
+ else if (DoWildEncounterRateTest(gBattlePikeWildMonHeaders[headerId].landMonsInfo->encounterRate, FALSE) != TRUE)
+ return FALSE;
+ else if (TryGenerateWildMon(gBattlePikeWildMonHeaders[headerId].landMonsInfo, WILD_AREA_LAND, WILD_CHECK_KEEN_EYE) != TRUE)
+ return FALSE;
+ else if (!TryGenerateBattlePikeWildMon(TRUE))
+ return FALSE;
+
+ BattleSetup_StartBattlePikeWildBattle();
+ return TRUE;
+ }
+ if (gMapHeader.mapDataId == 0x169)
+ {
+ headerId = gSaveBlock2Ptr->battlePyramidWildHeaderId;
+ if (previousMetaTileBehavior != currMetaTileBehavior && !DoGlobalWildEncounterDiceRoll())
+ return FALSE;
+ else if (DoWildEncounterRateTest(gBattlePyramidWildMonHeaders[headerId].landMonsInfo->encounterRate, FALSE) != TRUE)
+ return FALSE;
+ else if (TryGenerateWildMon(gBattlePyramidWildMonHeaders[headerId].landMonsInfo, WILD_AREA_LAND, WILD_CHECK_KEEN_EYE) != TRUE)
+ return FALSE;
+
+ GenerateBattlePyramidWildMon();
+ BattleSetup_StartWildBattle();
+ return TRUE;
+ }
+ }
+ else
+ {
+ if (MetatileBehavior_IsLandWildEncounter(currMetaTileBehavior) == TRUE)
+ {
+ if (gWildMonHeaders[headerId].landMonsInfo == NULL)
+ return FALSE;
+ else if (previousMetaTileBehavior != currMetaTileBehavior && !DoGlobalWildEncounterDiceRoll())
+ return FALSE;
+ else if (DoWildEncounterRateTest(gWildMonHeaders[headerId].landMonsInfo->encounterRate, FALSE) != TRUE)
+ return FALSE;
+
+ if (TryStartRoamerEncounter() == TRUE)
+ {
+ roamer = &gSaveBlock1Ptr->roamer;
+ if (!IsWildLevelAllowedByRepel(roamer->level))
+ return FALSE;
+
+ BattleSetup_StartRoamerBattle();
+ return TRUE;
+ }
+ else
+ {
+ if (DoMassOutbreakEncounterTest() == TRUE && SetUpMassOutbreakEncounter(WILD_CHECK_REPEL | WILD_CHECK_KEEN_EYE) == TRUE)
+ {
+ BattleSetup_StartWildBattle();
+ return TRUE;
+ }
+
+ // try a regular wild land encounter
+ if (TryGenerateWildMon(gWildMonHeaders[headerId].landMonsInfo, WILD_AREA_LAND, WILD_CHECK_REPEL | WILD_CHECK_KEEN_EYE) == TRUE)
+ {
+ BattleSetup_StartWildBattle();
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+ }
+ else if (MetatileBehavior_IsWaterWildEncounter(currMetaTileBehavior) == TRUE
+ || (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING) && MetatileBehavior_IsBridge(currMetaTileBehavior) == TRUE))
+ {
+ if (AreLegendariesInSootopolisPreventingEncounters() == TRUE)
+ return FALSE;
+ else if (gWildMonHeaders[headerId].waterMonsInfo == NULL)
+ return FALSE;
+ else if (previousMetaTileBehavior != currMetaTileBehavior && !DoGlobalWildEncounterDiceRoll())
+ return FALSE;
+ else if (DoWildEncounterRateTest(gWildMonHeaders[headerId].waterMonsInfo->encounterRate, FALSE) != TRUE)
+ return FALSE;
+
+ if (TryStartRoamerEncounter() == TRUE)
+ {
+ roamer = &gSaveBlock1Ptr->roamer;
+ if (!IsWildLevelAllowedByRepel(roamer->level))
+ return FALSE;
+
+ BattleSetup_StartRoamerBattle();
+ return TRUE;
+ }
+ else // try a regular surfing encounter
+ {
+ if (TryGenerateWildMon(gWildMonHeaders[headerId].waterMonsInfo, WILD_AREA_WATER, WILD_CHECK_REPEL | WILD_CHECK_KEEN_EYE) == TRUE)
+ {
+ BattleSetup_StartWildBattle();
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+void RockSmashWildEncounter(void)
+{
+ u16 headerId = GetCurrentMapWildMonHeaderId();
+
+ if (headerId != 0xFFFF)
+ {
+ const struct WildPokemonInfo *wildPokemonInfo = gWildMonHeaders[headerId].rockSmashMonsInfo;
+
+ if (wildPokemonInfo == NULL)
+ {
+ gSpecialVar_Result = FALSE;
+ }
+ else if (DoWildEncounterRateTest(wildPokemonInfo->encounterRate, 1) == TRUE
+ && TryGenerateWildMon(wildPokemonInfo, 2, WILD_CHECK_REPEL | WILD_CHECK_KEEN_EYE) == TRUE)
+ {
+ BattleSetup_StartWildBattle();
+ gSpecialVar_Result = TRUE;
+ }
+ else
+ {
+ gSpecialVar_Result = FALSE;
+ }
+ }
+ else
+ {
+ gSpecialVar_Result = FALSE;
+ }
+}
+
+bool8 SweetScentWildEncounter(void)
+{
+ s16 x, y;
+ u16 headerId;
+
+ PlayerGetDestCoords(&x, &y);
+ headerId = GetCurrentMapWildMonHeaderId();
+ if (headerId == 0xFFFF) // invalid
+ {
+ if (gMapHeader.mapDataId == 0x166)
+ {
+ headerId = GetBattlePikeWildMonHeaderId();
+ if (TryGenerateWildMon(gBattlePikeWildMonHeaders[headerId].landMonsInfo, WILD_AREA_LAND, 0) != TRUE)
+ return FALSE;
+
+ TryGenerateBattlePikeWildMon(FALSE);
+ BattleSetup_StartBattlePikeWildBattle();
+ return TRUE;
+ }
+ if (gMapHeader.mapDataId == 0x169)
+ {
+ headerId = gSaveBlock2Ptr->battlePyramidWildHeaderId;
+ if (TryGenerateWildMon(gBattlePyramidWildMonHeaders[headerId].landMonsInfo, WILD_AREA_LAND, 0) != TRUE)
+ return FALSE;
+
+ GenerateBattlePyramidWildMon();
+ BattleSetup_StartWildBattle();
+ return TRUE;
+ }
+ }
+ else
+ {
+ if (MetatileBehavior_IsLandWildEncounter(MapGridGetMetatileBehaviorAt(x, y)) == TRUE)
+ {
+ if (gWildMonHeaders[headerId].landMonsInfo == NULL)
+ return FALSE;
+
+ if (TryStartRoamerEncounter() == TRUE)
+ {
+ BattleSetup_StartRoamerBattle();
+ return TRUE;
+ }
+
+ if (DoMassOutbreakEncounterTest() == TRUE)
+ SetUpMassOutbreakEncounter(0);
+ else
+ TryGenerateWildMon(gWildMonHeaders[headerId].landMonsInfo, WILD_AREA_LAND, 0);
+
+ BattleSetup_StartWildBattle();
+ return TRUE;
+ }
+ else if (MetatileBehavior_IsWaterWildEncounter(MapGridGetMetatileBehaviorAt(x, y)) == TRUE)
+ {
+ if (AreLegendariesInSootopolisPreventingEncounters() == TRUE)
+ return FALSE;
+ if (gWildMonHeaders[headerId].waterMonsInfo == NULL)
+ return FALSE;
+
+ if (TryStartRoamerEncounter() == TRUE)
+ {
+ BattleSetup_StartRoamerBattle();
+ return TRUE;
+ }
+
+ TryGenerateWildMon(gWildMonHeaders[headerId].waterMonsInfo, WILD_AREA_WATER, 0);
+ BattleSetup_StartWildBattle();
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+bool8 DoesCurrentMapHaveFishingMons(void)
+{
+ u16 headerId = GetCurrentMapWildMonHeaderId();
+
+ if (headerId != 0xFFFF && gWildMonHeaders[headerId].fishingMonsInfo != NULL)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void FishingWildEncounter(u8 rod)
+{
+ u16 species;
+
+ if (CheckFeebas() == TRUE)
+ {
+ u8 level = ChooseWildMonLevel(&gWildFeebasRoute119Data);
+
+ species = gWildFeebasRoute119Data.species;
+ CreateWildMon(species, level);
+ }
+ else
+ {
+ species = GenerateFishingWildMon(gWildMonHeaders[GetCurrentMapWildMonHeaderId()].fishingMonsInfo, rod);
+ }
+ IncrementGameStat(GAME_STAT_FISHING_CAPTURES);
+ SetPokemonAnglerSpecies(species);
+ BattleSetup_StartWildBattle();
+}
+
+u16 GetLocalWildMon(bool8 *isWaterMon)
+{
+ u16 headerId;
+ const struct WildPokemonInfo *landMonsInfo;
+ const struct WildPokemonInfo *waterMonsInfo;
+
+ *isWaterMon = FALSE;
+ headerId = GetCurrentMapWildMonHeaderId();
+ if (headerId == 0xFFFF)
+ return SPECIES_NONE;
+ landMonsInfo = gWildMonHeaders[headerId].landMonsInfo;
+ waterMonsInfo = gWildMonHeaders[headerId].waterMonsInfo;
+ // Neither
+ if (landMonsInfo == NULL && waterMonsInfo == NULL)
+ return SPECIES_NONE;
+ // Land Pokemon
+ else if (landMonsInfo != NULL && waterMonsInfo == NULL)
+ return landMonsInfo->wildPokemon[ChooseWildMonIndex_Land()].species;
+ // Water Pokemon
+ else if (landMonsInfo == NULL && waterMonsInfo != NULL)
+ {
+ *isWaterMon = TRUE;
+ return waterMonsInfo->wildPokemon[ChooseWildMonIndex_WaterRock()].species;
+ }
+ // Either land or water Pokemon
+ if ((Random() % 100) < 80)
+ {
+ return landMonsInfo->wildPokemon[ChooseWildMonIndex_Land()].species;
+ }
+ else
+ {
+ *isWaterMon = TRUE;
+ return waterMonsInfo->wildPokemon[ChooseWildMonIndex_WaterRock()].species;
+ }
+}
+
+u16 GetLocalWaterMon(void)
+{
+ u16 headerId = GetCurrentMapWildMonHeaderId();
+
+ if (headerId != 0xFFFF)
+ {
+ const struct WildPokemonInfo *waterMonsInfo = gWildMonHeaders[headerId].waterMonsInfo;
+
+ if (waterMonsInfo)
+ return waterMonsInfo->wildPokemon[ChooseWildMonIndex_WaterRock()].species;
+ }
+ return SPECIES_NONE;
+}
+
+bool8 UpdateRepelCounter(void)
+{
+ u16 steps;
+
+ if (InBattlePike() || InBattlePyramid())
+ return FALSE;
+ if (InUnionRoom() == TRUE)
+ return FALSE;
+
+ steps = VarGet(VAR_REPEL_STEP_COUNT);
+
+ if (steps != 0)
+ {
+ steps--;
+ VarSet(VAR_REPEL_STEP_COUNT, steps);
+ if (steps == 0)
+ {
+ ScriptContext1_SetupScript(EventScript_RepelWoreOff);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static bool8 IsWildLevelAllowedByRepel(u8 wildLevel)
+{
+ u8 i;
+
+ if (!VarGet(VAR_REPEL_STEP_COUNT))
+ return TRUE;
+
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ if (GetMonData(&gPlayerParty[i], MON_DATA_HP) && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG))
+ {
+ u8 ourLevel = GetMonData(&gPlayerParty[i], MON_DATA_LEVEL);
+
+ if (wildLevel < ourLevel)
+ return FALSE;
+ else
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static bool8 IsAbilityAllowingEncounter(u8 level)
+{
+ u8 ability;
+
+ if (GetMonData(&gPlayerParty[0], MON_DATA_SANITY_BIT3))
+ return TRUE;
+
+ ability = GetMonAbility(&gPlayerParty[0]);
+ if (ability == ABILITY_KEEN_EYE || ability == ABILITY_INTIMIDATE)
+ {
+ u8 playerMonLevel = GetMonData(&gPlayerParty[0], MON_DATA_LEVEL);
+ if (playerMonLevel > 5 && level <= playerMonLevel - 5 && !(Random() % 2))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static bool8 TryGetRandomWildMonIndexByType(const struct WildPokemon *wildMon, u8 type, u8 numMon, u8 *monIndex)
+{
+ u8 validIndexes[numMon]; // variable length array, an interesting feature
+ u8 i, validMonCount;
+
+ for (i = 0; i < numMon; i++)
+ validIndexes[i] = 0;
+
+ for (validMonCount = 0, i = 0; i < numMon; i++)
+ {
+ if (gBaseStats[wildMon[i].species].type1 == type || gBaseStats[wildMon[i].species].type2 == type)
+ validIndexes[validMonCount++] = i;
+ }
+
+ if (validMonCount == 0 || validMonCount == numMon)
+ return FALSE;
+
+ *monIndex = validIndexes[Random() % validMonCount];
+ return TRUE;
+}
+
+static bool8 TryGetAbilityInfluencedWildMonIndex(const struct WildPokemon *wildMon, u8 type, u8 ability, u8 *monIndex)
+{
+ if (GetMonData(&gPlayerParty[0], MON_DATA_SANITY_BIT3))
+ return FALSE;
+ else if (GetMonAbility(&gPlayerParty[0]) != ability)
+ return FALSE;
+ else if (Random() % 2 != 0)
+ return FALSE;
+
+ return TryGetRandomWildMonIndexByType(wildMon, type, LAND_WILD_COUNT, monIndex);
+}
+
+static void ApplyFluteEncounterRateMod(u32 *encRate)
+{
+ if (FlagGet(FLAG_SYS_ENC_UP_ITEM) == TRUE)
+ *encRate += *encRate / 2;
+ else if (FlagGet(FLAG_SYS_ENC_DOWN_ITEM) == TRUE)
+ *encRate = *encRate / 2;
+}
+
+static void ApplyCleanseTagEncounterRateMod(u32 *encRate)
+{
+ if (GetMonData(&gPlayerParty[0], MON_DATA_HELD_ITEM) == ITEM_CLEANSE_TAG)
+ *encRate = *encRate * 2 / 3;
+}