diff --git a/constants/landmark_constants.asm b/constants/landmark_constants.asm index e94ebedae..2bd13ac1d 100644 --- a/constants/landmark_constants.asm +++ b/constants/landmark_constants.asm @@ -29,8 +29,9 @@ DEF LSMTEXTBOX_LEVEL_NUMBERS_FIRST_TILE EQU $31 ; and $41 ; events when entering Level Selection menu (wLevelSelectionMenuEntryEventQueue) const_def - const LSMEVENT_SHOW_UNLOCKED_LEVELS ; 0 - const LSMEVENT_ANIMATE_TIME_OF_DAY ; 1 + const LSMEVENT_SHOW_CLEARED_LEVEL ; 0 + const LSMEVENT_SHOW_UNLOCKED_LEVELS ; 1 + const LSMEVENT_ANIMATE_TIME_OF_DAY ; 2 DEF NUM_LSM_EVENTS EQU const_value ; used in CaughtData (legacy) diff --git a/engine/menus/cleared_level_screen.asm b/engine/menus/cleared_level_screen.asm index d7a4054b0..a54d1a598 100755 --- a/engine/menus/cleared_level_screen.asm +++ b/engine/menus/cleared_level_screen.asm @@ -62,12 +62,22 @@ AddLevelCoinsToBalance: ClearLevel: ld a, [wCurSpaceEffect] ; End Space effect byte contains STAGE_*_F + ld [wLastClearedLevelStage], a call GetClearedLevelsStageAddress - ld b, SET_FLAG + ld b, CHECK_FLAG ld d, 0 ld a, [wCurLevel] ld e, a + push de call FlagAction + pop de + jr nz, .already_cleared ; return if this level stage already cleared + ld b, SET_FLAG + call FlagAction + ret +.already_cleared + ld a, $ff + ld [wLastClearedLevelStage], a ret UnlockLevels: diff --git a/engine/menus/game_menu.asm b/engine/menus/game_menu.asm index 101fea716..a19b84e8b 100755 --- a/engine/menus/game_menu.asm +++ b/engine/menus/game_menu.asm @@ -146,11 +146,12 @@ GameMenu_World: call ClearObjectStructs call ClearBGPalettes call ClearSprites -; clear unlocked levels +; initialize buffer for temporary unlocked and cleared levels xor a ld [wLastUnlockedLevelsCount], a ld a, $ff ld [wLastUnlockedLevels], a + ld [wLastClearedLevelStage], a ; handle overworld exit ld a, [wExitOverworldReason] cp CLEARED_LEVEL @@ -160,6 +161,11 @@ GameMenu_World: farcall ClearedLevelScreen ld hl, wLevelSelectionMenuEntryEventQueue set LSMEVENT_ANIMATE_TIME_OF_DAY, [hl] + ld a, [wLastClearedLevelStage] + inc a + jr z, .no_new_stage_cleared + set LSMEVENT_SHOW_CLEARED_LEVEL, [hl] +.no_new_stage_cleared ld a, [wLastUnlockedLevelsCount] and a jr z, .save_and_return diff --git a/engine/menus/level_selection_menu.asm b/engine/menus/level_selection_menu.asm index a9c93f51e..70879c61c 100755 --- a/engine/menus/level_selection_menu.asm +++ b/engine/menus/level_selection_menu.asm @@ -119,6 +119,28 @@ LevelSelectionMenu:: call LevelSelectionMenu_DrawStageTrophies call LevelSelectionMenu_RefreshTextboxAttrs + ld a, [wLevelSelectionMenuEntryEventQueue] + bit LSMEVENT_SHOW_CLEARED_LEVEL, a + jr z, .check_animate_tod + ld a, [wLastClearedLevelStage] + cp NUM_LEVEL_STAGES + jr nc, .check_animate_tod + + call LevelSelectionMenu_Delay10Frames + +; the previous LevelSelectionMenu_DrawStageTrophies showed this stage trophy empty +; due to wLastClearedLevelStage being set to a non-$ff value. +; redisplay stage trophies to show the stage being cleared. + ld a, $ff + ld [wLastClearedLevelStage], a + call LevelSelectionMenu_DrawStageTrophies + ld de, SFX_FORESIGHT + call PlaySFX + + call LevelSelectionMenu_Delay10Frames + call LevelSelectionMenu_Delay10Frames + +.check_animate_tod ld a, [wLevelSelectionMenuEntryEventQueue] bit LSMEVENT_ANIMATE_TIME_OF_DAY, a jp z, .main_loop @@ -723,8 +745,13 @@ LevelSelectionMenu_DrawStageTrophies: ret .IsLevelStageCleared: -; return nz if [wCurLevel]'s stage in a has been cleared, z otherwise. +; return z if a is equal to wLastClearedLevelStage (for LSMEVENT_SHOW_CLEARED_LEVEL animation). +; else, return nz if [wCurLevel]'s stage in a has been cleared +; return z otherwise. ; preserve a and de. + ld hl, wLastClearedLevelStage + cp [hl] + ret z ld c, a push bc push de diff --git a/ram/wram.asm b/ram/wram.asm index 9be9719ee..c444c6d60 100644 --- a/ram/wram.asm +++ b/ram/wram.asm @@ -2537,6 +2537,8 @@ wLevelSelectionMenuEntryEventQueue:: flag_array NUM_LSM_EVENTS ; list of unlocked levels during post-level screen wLastUnlockedLevelsCount:: db wLastUnlockedLevels:: ds MAX_UNLOCK_LEVELS_AT_ONCE + 1 +; which stage of the current level cleared during post-level screen ($ff if no new stage cleared) +wLastClearedLevelStage:: db wPlayerDataEnd::