Implement clearing level in RAM according to End Space effect, supporting up to 4 clearable stages per level; Implement unlocking levels [Commit 1] (#35)

This commit is contained in:
xCrystal
2024-01-18 19:22:21 +01:00
parent 8757112152
commit 38ffe06a2c
12 changed files with 183 additions and 11 deletions

View File

@@ -30,6 +30,8 @@ ClearedLevelScreen:
jr z, .loop
.exit
call AddLevelCoinsToBalance
call ClearLevel
call UnlockLevels
ld c, 30
jp DelayFrames
@@ -58,3 +60,98 @@ AddLevelCoinsToBalance:
pop bc
farcall GiveCoins
ret
ClearLevel:
ld a, [wCurSpaceEffect] ; End Space effect byte contains STAGE_*
call GetClearedLevelsStageAddress
ld b, SET_FLAG
ld d, 0
ld a, [wCurLevel]
ld e, a
call FlagAction
ret
UnlockLevels:
ld hl, LevelUnlockRequirements
ld de, wUnlockedLevels - 1
ld b, 0
.next_byte
ld c, 8
inc de
ld a, [de]
.next_bit
srl a
push af
call nc, .CheckUnlockLevel ; skip if level is already unlocked
inc b
ld a, b
cp NUM_LEVELS
jr z, .done
; advance hl to next level in LevelUnlockRequirements
.loop
ld a, [hli]
inc a ; cp $ff
jr nz, .loop
pop af
dec c
jr z, .next_byte
jr .next_bit
.done
pop af
ret
; check if the LevelUnlockRequirements[b] at hl for unlocking level b are met.
; return hl pointing to up to the $ff byte of this LevelUnlockRequirements entry.
.CheckUnlockLevel:
push de
push bc
ld a, [hl]
cp $ff
jr z, .reqs_met ; jump if no specific reqs to unlock this level
inc hl
cp UNLOCK_WHEN_LEVELS_CLEARED
jr z, .check_levels_cleared_loop
cp UNLOCK_WHEN_NUMBER_OF_LEVELS_CLEARED
cp UNLOCK_WHEN_TECHNIQUES_CLEARED
.check_levels_cleared_loop
ld a, [hli] ; which level
ld e, a
inc a ; cp $ff
jr z, .reqs_met ; jump when no more required levels and all passed so far
ld a, [hli] ; which stage
push hl
call GetClearedLevelsStageAddress
ld b, CHECK_FLAG
ld d, 0
call FlagAction
pop hl
jr z, .reqs_not_met ; if this level is not cleared, requirements aren't met
jr .check_levels_cleared_loop ; otherwise check next level in list
.reqs_met
pop bc
pop de
ret
.reqs_not_met
pop bc
pop de
ret
; return hl = wClearedLevelsStage* given STAGE_ constant in a
GetClearedLevelsStageAddress:
ld hl, wClearedLevelsStage1
cp ES1
ret z
ld hl, wClearedLevelsStage2
cp ES2
ret z
ld hl, wClearedLevelsStage3
cp ES3
ret z
ld hl, wClearedLevelsStage4
ret
INCLUDE "data/levels/levels.asm"

View File

@@ -118,6 +118,13 @@ LevelSelectionMenu::
jr .main_loop
.enter_level
ld a, [wLevelSelectionMenuCurrentLandmark]
ld e, a
ld d, 0
ld hl, LandmarkToLevelTable
add hl, de
ld a, [hl]
ld [wCurLevel], a
ld a, [wLevelSelectionMenuCurrentLandmark]
call LevelSelectionMenu_GetLandmarkSpawnPoint
ld [wDefaultSpawnpoint], a
@@ -521,12 +528,10 @@ LevelSelectionMenu_GetLandmarkName::
LevelSelectionMenu_GetLandmarkSpawnPoint:
; Return SPAWN_* (a) of landmark a.
push hl
ld hl, LevelSelectionMenu_Landmarks + $5
ld bc, LevelSelectionMenu_Landmarks.landmark2 - LevelSelectionMenu_Landmarks.landmark1
call AddNTimes
ld a, [hl]
pop hl
ret
LevelSelectionMenu_GetValidKeys:
@@ -744,7 +749,7 @@ _LevelSelectionMenuHandleTransition:
xor a
ret
INCLUDE "data/level_selection_menu.asm"
INCLUDE "data/levels/level_selection_menu.asm"
LevelSelectionMenuGFX:
INCBIN "gfx/level_selection_menu/background.2bpp.lz"