diff --git a/charmap.asm b/charmap.asm index c8308eb20..a3980cf1f 100644 --- a/charmap.asm +++ b/charmap.asm @@ -194,4 +194,4 @@ DEF DIE_NUMBERS_OAM_FIRST_TILE EQU BOARD_MENU_OAM_FIRST_TILE DEF BRANCH_ARROWS_OAM_FIRST_TILE EQU DIE_NUMBERS_OAM_FIRST_TILE + 40 ; DIE_NUMBER_SIZE * 10 -DEF VIEW_MAP_MODE_OAM_FIRST_TILE EQU SECONDARY_SPRITES_FIRST_TILE +DEF VIEW_MAP_MODE_OAM_FIRST_TILE EQU BOARD_MENU_OAM_FIRST_TILE + 45 ; max(BRANCH_ARROWS_OAM_FIRST_TILE + NUM_DIRECTIONS, BOARD_MENU_ITEM_SIZE * NUM_BOARD_MENU_ITEMS) diff --git a/constants/script_constants.asm b/constants/script_constants.asm index fea20491e..bb5f69ed6 100644 --- a/constants/script_constants.asm +++ b/constants/script_constants.asm @@ -331,6 +331,7 @@ DEF NUM_UNOWN_PUZZLES EQU const_value const BOARDEVENT_END_TURN ; 3 const BOARDEVENT_VIEW_MAP_MODE ; 4 const BOARDEVENT_REDISPLAY_MENU ; 5 + const BOARDEVENT_RESUME_BRANCH ; 6 DEF NUM_BOARD_EVENTS EQU const_value - 1 ; exitoverworld arguments diff --git a/data/maps/setup_script_pointers.asm b/data/maps/setup_script_pointers.asm index 4b0e4c75c..e49ce0121 100644 --- a/data/maps/setup_script_pointers.asm +++ b/data/maps/setup_script_pointers.asm @@ -51,3 +51,4 @@ MapSetupCommands: add_mapsetup EnableTextAcceleration ; 2c add_mapsetup ConstructAndEnableOverworldHUD ; 2d add_mapsetup EnableOverworldHUD ; 2e + add_mapsetup SpawnInCustomFacing ; 2f diff --git a/data/maps/setup_scripts.asm b/data/maps/setup_scripts.asm index e93321cac..62a312896 100644 --- a/data/maps/setup_scripts.asm +++ b/data/maps/setup_scripts.asm @@ -183,6 +183,7 @@ MapSetupScript_ExitViewMap: mapsetup LoadMapObjects mapsetup EnableLCD mapsetup LoadMapPalettes + mapsetup SpawnInCustomFacing ; restore player's facing if in branch space mapsetup RefreshMapSprites mapsetup FadeInPalettesFromWhite mapsetup ActivateMapAnims diff --git a/engine/board/menu.asm b/engine/board/menu.asm index 13b79ad17..ea75c1fc4 100755 --- a/engine/board/menu.asm +++ b/engine/board/menu.asm @@ -75,9 +75,7 @@ BoardMenuScript:: .ViewMap: callasm .EnterViewMapMode - appearplayermock closetext - callasm .ViewMapModeOAM end .EnterViewMapMode: @@ -99,15 +97,12 @@ BoardMenuScript:: ld [wViewMapModeDisplacementY], a ld [wViewMapModeDisplacementX], a call DisableOverworldHUD - ld hl, wPlayerFlags - set INVISIBLE_F, [hl] - ret - -.ViewMapModeOAM: -; this runs after closetext to prevent graphical glitches with the board menu OAM farcall LoadViewMapModeGFX ld hl, wDisplaySecondarySprites set SECONDARYSPRITES_VIEW_MAP_MODE_F, [hl] + ld hl, wPlayerFlags + set INVISIBLE_F, [hl] + farcall MockPlayerObject ret .SubmenuCallback: diff --git a/engine/board/spaces.asm b/engine/board/spaces.asm index 0538f9c02..b552c9815 100755 --- a/engine/board/spaces.asm +++ b/engine/board/spaces.asm @@ -137,9 +137,9 @@ LandedInRegularSpaceScript_AfterSpaceEffect: ret BranchSpaceScript:: - scall .ArriveToBranchSpaceScript -.prompt_player - callasm .PromptPlayerToChooseDirection + scall ArriveToBranchSpaceScript +BranchSpaceScript_PromptPlayer:: + callasm PromptPlayerToChooseBranchDirection iffalse .print_technique_required wait 200 end @@ -149,14 +149,14 @@ BranchSpaceScript:: writetext .TechniqueRequiredText waitbutton closetext - sjump .prompt_player + sjump BranchSpaceScript_PromptPlayer .TechniqueRequiredText: text "A new TECHNIQUE is" line "required!" done -.ArriveToBranchSpaceScript: +ArriveToBranchSpaceScript: playsound SFX_TWINKLE wait 400 callasm .ArriveToBranchSpace @@ -199,20 +199,25 @@ rept NUM_DIRECTIONS endr ret -.PromptPlayerToChooseDirection: -; sample a dpad press +PromptPlayerToChooseBranchDirection: +; sample a dpad press or SELECT button ld hl, wTempSpaceBranchStruct call GetJoypad ldh a, [hJoyPressed] - and D_PAD - jr z, .PromptPlayerToChooseDirection + and D_PAD | SELECT + jr z, PromptPlayerToChooseBranchDirection + cp SELECT ; check if SELECT pressed along with no dpad key + jr nz, .not_select + jp .EnterViewMapMode + +.not_select ; determine the status (ok/invalid/unavailable) of the chosen direction bit D_RIGHT_F, a jr z, .not_right ld a, [hl] inc a ; cp BRANCH_DIRECTION_INVALID - jr z, .PromptPlayerToChooseDirection + jr z, PromptPlayerToChooseBranchDirection inc a ; cp BRANCH_DIRECTION_UNAVAILABLE jr z, .technique_required jr .direction_chosen @@ -223,7 +228,7 @@ endr jr z, .not_left ld a, [hl] inc a ; cp BRANCH_DIRECTION_INVALID - jr z, .PromptPlayerToChooseDirection + jr z, PromptPlayerToChooseBranchDirection inc a ; cp BRANCH_DIRECTION_UNAVAILABLE jr z, .technique_required jr .direction_chosen @@ -234,7 +239,7 @@ endr jr z, .not_up ld a, [hl] inc a ; cp BRANCH_DIRECTION_INVALID - jr z, .PromptPlayerToChooseDirection + jr z, PromptPlayerToChooseBranchDirection inc a ; cp BRANCH_DIRECTION_UNAVAILABLE jr z, .technique_required jr .direction_chosen @@ -243,7 +248,7 @@ endr inc hl ld a, [hl] inc a ; cp BRANCH_DIRECTION_INVALID - jr z, .PromptPlayerToChooseDirection + jr z, PromptPlayerToChooseBranchDirection inc a ; cp BRANCH_DIRECTION_UNAVAILABLE jr z, .technique_required ; fallthrough @@ -263,6 +268,37 @@ endr ldh [hScriptVar], a jp PlayClickSFX +.EnterViewMapMode: + ld a, BOARDEVENT_VIEW_MAP_MODE + ldh [hCurBoardEvent], a + ld a, TRUE + ld [wViewMapModeRange], a + ld a, [wMapGroup] + ld [wBeforeViewMapMapGroup], a + ld a, [wMapNumber] + ld [wBeforeViewMapMapNumber], a + ld a, [wXCoord] + ld [wBeforeViewMapXCoord], a + ld a, [wYCoord] + ld [wBeforeViewMapYCoord], a + xor a + ld [wViewMapModeDisplacementY], a + ld [wViewMapModeDisplacementX], a + call DisableOverworldHUD + ld hl, wPlayerFlags + set INVISIBLE_F, [hl] + ld hl, wDisplaySecondarySprites + res SECONDARYSPRITES_SPACES_LEFT_F, [hl] + res SECONDARYSPRITES_BRANCH_ARROWS_F, [hl] + farcall MockPlayerObject + call UpdateSprites + farcall LoadViewMapModeGFX + ld hl, wDisplaySecondarySprites + set SECONDARYSPRITES_VIEW_MAP_MODE_F, [hl] + ld a, TRUE + ldh [hScriptVar], a + jp PlayClickSFX + UnionSpaceScript:: callasm .ArriveToUnionSpace end diff --git a/engine/overworld/events.asm b/engine/overworld/events.asm index 541c26894..59442d08b 100644 --- a/engine/overworld/events.asm +++ b/engine/overworld/events.asm @@ -338,8 +338,9 @@ CheckBoardEvent: dw .menu ; BOARDEVENT_DISPLAY_MENU dw .board ; BOARDEVENT_HANDLE_BOARD dw .none ; BOARDEVENT_END_TURN - dw .mapview ; BOARDEVENT_VIEW_MAP_MODE + dw .viewmap ; BOARDEVENT_VIEW_MAP_MODE dw .menu ; BOARDEVENT_REDISPLAY_MENU + dw .branch ; BOARDEVENT_RESUME_BRANCH assert_table_length NUM_BOARD_EVENTS + 1 .none @@ -375,7 +376,7 @@ CheckBoardEvent: scf ret -.mapview +.viewmap ; check if player pressed B and if so queue the script to exit View Map mode ldh a, [hJoyDown] and D_PAD @@ -384,16 +385,27 @@ CheckBoardEvent: bit B_BUTTON_F, a ret z ; nc ; B was pressed - ld a, BANK(.ExitMapViewModeScript) - ld hl, .ExitMapViewModeScript + ld a, BANK(.ExitViewMapModeScript) + ld hl, .ExitViewMapModeScript call CallScript scf ret -.ExitMapViewModeScript: +.ExitViewMapModeScript: reloadmapafterviewmapmode end +.branch +; special handler to resume branch space after returning from View Map mode. +; skip scall to .ArriveToBranchSpaceScript not to recompute branch struct. + ld a, BOARDEVENT_HANDLE_BOARD + ldh [hCurBoardEvent], a + ld a, BANK(BranchSpaceScript) + ld hl, BranchSpaceScript_PromptPlayer + call CallScript + scf + ret + .no_space_effect ; continue moving in board xor a diff --git a/engine/overworld/player_object.asm b/engine/overworld/player_object.asm index dec66f6ad..698655e79 100644 --- a/engine/overworld/player_object.asm +++ b/engine/overworld/player_object.asm @@ -99,7 +99,7 @@ WriteObjectXY:: and a ret -RefreshPlayerCoords: +RefreshPlayerCoords:: ld a, [wXCoord] add 4 ld d, a @@ -855,3 +855,77 @@ QueueFollowerFirstStep: .same_xy scf ret + +MockPlayerObject:: +; refresh wPlayerObjectYCoord and wPlayerObjectXCoord + farcall RefreshPlayerCoords +; copy default sprite object to the last object struct + ld hl, .DefaultPlayerObject + ld de, wMap{d:LAST_OBJECT}Object + ld bc, OBJECT_EVENT_SIZE + 1 + call CopyBytes + +; adjust sprite id and palette number + ld hl, .PlayerObjectFields +.loop + ld a, [wPlayerGender] + cp [hl] + inc hl + jr nz, .next1 + ld a, [wPlayerState] + cp [hl] + inc hl + jr nz, .next2 +; found a match + ld a, [hli] ; sprite + ld [wMap{d:LAST_OBJECT}ObjectSprite], a + ld a, [hl] ; palette | objecttype + ld [wMap{d:LAST_OBJECT}ObjectPalette], a ; also wMap{d:LAST_OBJECT}ObjectType + jr .copy_player_coords +.next1 + inc hl +.next2 + inc hl + inc hl + ld a, [hl] + cp -1 + jr nz, .loop + +.copy_player_coords +; copy player's coordinates + ld hl, wPlayerObjectYCoord + ld de, wMap{d:LAST_OBJECT}ObjectYCoord + ld a, [hli] + ld [de], a + inc de + ld a, [hl] ; wPlayerObjectXCoord + ld [de], a ; wMap{d:LAST_OBJECT}ObjectXCoord +; set facing direction + ld a, [wPlayerDirection] + srl a + srl a + maskbits NUM_DIRECTIONS + ld b, SPRITEMOVEDATA_STANDING_DOWN + add b + ld [wMap{d:LAST_OBJECT}ObjectMovement], a + +; display mocked player object +; it will go to the last wMapObjects slot and to whichever wObjectStructs slot +; wObjectStructs[n][MAPOBJECT_OBJECT_STRUCT_ID] links both structs + ld a, NUM_OBJECTS - 1 + call UnmaskCopyMapObjectStruct + ret + +.DefaultPlayerObject: + db -1 ; MAPOBJECT_OBJECT_STRUCT_ID + object_event 0, 0, SPRITE_CHRIS, SPRITEMOVEDATA_STANDING_DOWN, 0, 0, -1, -1, PAL_NPC_RED, OBJECTTYPE_SCRIPT, 0, ObjectEvent, -1 + +.PlayerObjectFields: +; [wPlayerGender], [wPlayerState], sprite id, palette + db 0, PLAYER_NORMAL, SPRITE_CHRIS, PAL_NPC_RED << 4 | OBJECTTYPE_SCRIPT + db 1 << PLAYERGENDER_FEMALE_F, PLAYER_NORMAL, SPRITE_KRIS, PAL_NPC_BLUE << 4 | OBJECTTYPE_SCRIPT + db 0, PLAYER_SURF, SPRITE_SURF, PAL_NPC_RED << 4 | OBJECTTYPE_SCRIPT + db 1 << PLAYERGENDER_FEMALE_F, PLAYER_SURF, SPRITE_SURF, PAL_NPC_BLUE << 4 | OBJECTTYPE_SCRIPT + db 0, PLAYER_BIKE, SPRITE_CHRIS_BIKE, PAL_NPC_RED << 4 | OBJECTTYPE_SCRIPT + db 1 << PLAYERGENDER_FEMALE_F, PLAYER_BIKE, SPRITE_KRIS_BIKE, PAL_NPC_BLUE << 4 | OBJECTTYPE_SCRIPT + db -1 diff --git a/engine/overworld/scripting.asm b/engine/overworld/scripting.asm index 8bcc2244d..f59794c38 100644 --- a/engine/overworld/scripting.asm +++ b/engine/overworld/scripting.asm @@ -236,7 +236,6 @@ ScriptCommandTable: dw Script_checksave ; a9 dw Script_exitoverworld ; aa dw Script_reloadmapafterviewmapmode ; ab - dw Script_appearplayermock ; ac assert_table_length NUM_EVENT_COMMANDS StartScript: @@ -962,69 +961,6 @@ Script_variablesprite: ld [hl], a ret -Script_appearplayermock: - ld hl, .DefaultPlayerObject - ld de, wMap{d:LAST_OBJECT}Object - ld bc, OBJECT_EVENT_SIZE + 1 - call CopyBytes - -; adjust sprite id and palette number - ld hl, .PlayerObjectFields -.loop - ld a, [wPlayerGender] - cp [hl] - inc hl - jr nz, .next1 - ld a, [wPlayerState] - cp [hl] - inc hl - jr nz, .next2 -; found a match - ld a, [hli] ; sprite - ld [wMap{d:LAST_OBJECT}ObjectSprite], a - ld a, [hl] ; palette | objecttype - ld [wMap{d:LAST_OBJECT}ObjectPalette], a ; also wMap{d:LAST_OBJECT}ObjectType - jr .copy_player_coords -.next1 - inc hl -.next2 - inc hl - inc hl - ld a, [hl] - cp -1 - jr nz, .loop - -.copy_player_coords -; copy player's coordinates - ld hl, wPlayerObjectYCoord - ld de, wMap{d:LAST_OBJECT}ObjectYCoord - ld a, [hli] - ld [de], a - inc de - ld a, [hl] ; wPlayerObjectXCoord - ld [de], a ; wMap{d:LAST_OBJECT}ObjectXCoord - -; display mocked player object -; it will go to the last wMapObjects slot and to whichever wObjectStructs slot -; wObjectStructs[n][MAPOBJECT_OBJECT_STRUCT_ID] links both structs - ld a, NUM_OBJECTS - 1 - call UnmaskCopyMapObjectStruct - ret - -.DefaultPlayerObject: - db -1 ; MAPOBJECT_OBJECT_STRUCT_ID - object_event 0, 0, SPRITE_CHRIS, SPRITEMOVEDATA_STANDING_DOWN, 0, 0, -1, -1, PAL_NPC_RED, OBJECTTYPE_SCRIPT, 0, ObjectEvent, -1 - -.PlayerObjectFields: -; [wPlayerGender], [wPlayerState], sprite id, palette - db 0, PLAYER_NORMAL, SPRITE_CHRIS, PAL_NPC_RED << 4 | OBJECTTYPE_SCRIPT - db 1 << PLAYERGENDER_FEMALE_F, PLAYER_NORMAL, SPRITE_KRIS, PAL_NPC_BLUE << 4 | OBJECTTYPE_SCRIPT - db 0, PLAYER_SURF, SPRITE_SURF, PAL_NPC_RED << 4 | OBJECTTYPE_SCRIPT - db 1 << PLAYERGENDER_FEMALE_F, PLAYER_SURF, SPRITE_SURF, PAL_NPC_BLUE << 4 | OBJECTTYPE_SCRIPT - db 0, PLAYER_BIKE, SPRITE_CHRIS_BIKE, PAL_NPC_RED << 4 | OBJECTTYPE_SCRIPT - db 1 << PLAYERGENDER_FEMALE_F, PLAYER_BIKE, SPRITE_KRIS_BIKE, PAL_NPC_BLUE << 4 | OBJECTTYPE_SCRIPT - db -1 - Script_appear: call GetScriptByte call GetScriptObject @@ -1275,7 +1211,24 @@ Script_reloadmapafterviewmapmode: ldh [hMapEntryMethod], a ld a, SPAWN_FROM_RAM ld [wDefaultSpawnpoint], a + ld a, [wSpacesLeft] + and a ld a, BOARDEVENT_REDISPLAY_MENU + jr z, .in_board_menu + +; .in_branch_space + ld hl, wDisplaySecondarySprites + set SECONDARYSPRITES_SPACES_LEFT_F, [hl] + set SECONDARYSPRITES_BRANCH_ARROWS_F, [hl] + ld hl, wPlayerSpriteSetupFlags +; get the facing direction from the mocked object's facing direction + ld a, [wMap{d:LAST_OBJECT}ObjectMovement] + sub SPRITEMOVEDATA_STANDING_DOWN + ld [hl], a + set PLAYERSPRITESETUP_CUSTOM_FACING_F, [hl] + ld a, BOARDEVENT_RESUME_BRANCH + +.in_board_menu ldh [hCurBoardEvent], a ld hl, wDisplaySecondarySprites res SECONDARYSPRITES_VIEW_MAP_MODE_F, [hl] diff --git a/macros/scripts/events.asm b/macros/scripts/events.asm index 424cd2e23..71f52e94f 100644 --- a/macros/scripts/events.asm +++ b/macros/scripts/events.asm @@ -1076,9 +1076,4 @@ MACRO reloadmapafterviewmapmode db reloadmapafterviewmapmode_command ENDM - const appearplayermock_command ; $ac -MACRO appearplayermock - db appearplayermock_command -ENDM - DEF NUM_EVENT_COMMANDS EQU const_value