diff options
author | PikalaxALT <pikalaxalt@gmail.com> | 2017-11-25 10:56:55 -0500 |
---|---|---|
committer | PikalaxALT <pikalaxalt@gmail.com> | 2017-11-25 10:56:55 -0500 |
commit | a875d665b812b4aaa5cde21b5127262e04106755 (patch) | |
tree | 4e597cbce3178a5434d62beaf2f812ad57b8b7ef /src | |
parent | 293dfc4823d6c984adc221b40be4e3705a3fa65b (diff) | |
parent | 1e4f12e6fa9e3b22d4f1a60ca69313b5dec0ca38 (diff) |
Merge branch 'master' into easy_chat
Diffstat (limited to 'src')
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; } @@ -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; +} |