From dd89b70f7d9c206258eb118f9727d41f6347a8d8 Mon Sep 17 00:00:00 2001 From: "Matthew D. Steele" Date: Tue, 11 Jun 2024 17:33:28 -0400 Subject: [PATCH] Start implementing orc ghost in ShadowOffice room --- src/flag.inc | 2 + src/newgame.asm | 8 ++++ src/newgame.inc | 1 + src/platforms/barrier.asm | 11 ++++- src/rooms/shadow_descent.asm | 74 ++++++++++++++++++++++++++++++---- src/rooms/shadow_office.asm | 78 ++++++++++++++++++++++++++++++++++-- src/rooms/shadow_office.bg | 6 +-- src/rooms/shadow_trap.asm | 4 +- 8 files changed, 167 insertions(+), 17 deletions(-) diff --git a/src/flag.inc b/src/flag.inc index 922028bc..f77fda94 100644 --- a/src/flag.inc +++ b/src/flag.inc @@ -192,6 +192,8 @@ kSaveMagicNumber = $b2 FactoryElevatorTalkedToBruno CityCenterEnteredCity ShadowHeartTaggedGhost + ShadowOfficeRemovedWall + ShadowOfficeTaggedGhost NUM_VALUES .ENDENUM .ASSERT eFlag::NUM_VALUES <= $100, error diff --git a/src/newgame.asm b/src/newgame.asm index eb47b455..8756aedc 100644 --- a/src/newgame.asm +++ b/src/newgame.asm @@ -119,6 +119,7 @@ _SetFlags: d_byte Sinkhole, "SINKHOLE" d_byte Breaker6, "BREAKER6" d_byte Shadow, " SHADOW " + d_byte Office, " OFFICE " d_byte Depths, " DEPTHS " d_byte Breaker7, "BREAKER7" d_byte Core, " CORE " @@ -148,6 +149,7 @@ _SetFlags: d_byte Sinkhole, eRoom::CitySinkhole d_byte Breaker6, eRoom::BossCity d_byte Shadow, eRoom::ShadowTeleport + d_byte Office, eRoom::ShadowOffice d_byte Depths, eRoom::ShadowDepths d_byte Breaker7, eRoom::BossShadow d_byte Core, eRoom::CoreLock @@ -177,6 +179,7 @@ _SetFlags: d_byte Sinkhole, bSpawn::Device | 0 ; TODO: use a constant d_byte Breaker6, bSpawn::Device | kBossDoorDeviceIndex d_byte Shadow, bSpawn::Device | kTeleporterDeviceIndex + d_byte Office, bSpawn::Passage | 0 d_byte Depths, bSpawn::Device | 0 ; TODO: use a constant d_byte Breaker7, bSpawn::Device | kBossDoorDeviceIndex d_byte Core, bSpawn::Passage | 1 @@ -206,6 +209,7 @@ _SetFlags: d_byte Sinkhole, eFlag::BossCity d_byte Breaker6, eFlag::BreakerCity d_byte Shadow, eFlag::PaperJerome01 + d_byte Office, eFlag::ShadowTrapDisarmed d_byte Depths, eFlag::BossShadow d_byte Breaker7, eFlag::BreakerShadow d_byte Core, eFlag::None @@ -315,8 +319,12 @@ _SetFlags: .byte eFlag::UpgradeBRemote .byte eFlag::BreakerCity .byte eFlag::PaperJerome01 + .byte eFlag::ShadowHallInitialized + .byte eFlag::ShadowHallGlassBroken .byte eFlag::ShadowTrapDisarmed .byte eFlag::ShadowHeartTaggedGhost + .byte eFlag::ShadowOfficeRemovedWall + .byte eFlag::ShadowOfficeTaggedGhost .byte eFlag::BossShadow .byte eFlag::UpgradeOpMul .byte eFlag::BreakerShadow diff --git a/src/newgame.inc b/src/newgame.inc index 27d3c5b0..7effcbd1 100644 --- a/src/newgame.inc +++ b/src/newgame.inc @@ -39,6 +39,7 @@ Sinkhole ; start just outside the city boss room Breaker6 ; start in the city boss room, just after defeating it Shadow ; start at the entrance to the Shadow Labs + Office ; start in ShadowOffice, before tagging either ghost Depths ; start just outside the shadow boss room Breaker7 ; start in the shadow boss room, just after defeating it Core ; start just outside the final boss room diff --git a/src/platforms/barrier.asm b/src/platforms/barrier.asm index 344a30a3..caac1211 100644 --- a/src/platforms/barrier.asm +++ b/src/platforms/barrier.asm @@ -19,11 +19,13 @@ .INCLUDE "../macros.inc" .INCLUDE "../oam.inc" +.INCLUDE "../platform.inc" .INCLUDE "barrier.inc" .IMPORT FuncA_Objects_Draw1x1Shape .IMPORT FuncA_Objects_MoveShapeDownOneTile .IMPORT FuncA_Objects_SetShapePosToPlatformTopLeft +.IMPORT Ram_PlatformType_ePlatform_arr ;;;=========================================================================;;; @@ -34,11 +36,17 @@ kPaletteObjBarrier = 0 .SEGMENT "PRGC_Shadow" -;;; Draws a laboratory barrier. +;;; Draws a laboratory barrier. If the platform type is non-solid, draws +;;; nothing. ;;; @prereq PRGA_Objects is loaded. ;;; @param X The barrier platform index. .EXPORT FuncC_Shadow_DrawBarrierPlatform .PROC FuncC_Shadow_DrawBarrierPlatform + ;; If the platform isn't solid, we're done. + lda Ram_PlatformType_ePlatform_arr, x + cmp #kFirstSolidPlatformType + blt @return + ;; Draw each object tile in the platform, starting from the top. jsr FuncA_Objects_SetShapePosToPlatformTopLeft ldx #3 @loop: @@ -48,6 +56,7 @@ kPaletteObjBarrier = 0 jsr FuncA_Objects_MoveShapeDownOneTile dex bpl @loop + @return: rts _TileIds_u8_arr4: .byte kTileIdObjBarrierFirst + 1 diff --git a/src/rooms/shadow_descent.asm b/src/rooms/shadow_descent.asm index 7b545eca..6d3bf019 100644 --- a/src/rooms/shadow_descent.asm +++ b/src/rooms/shadow_descent.asm @@ -21,18 +21,24 @@ .INCLUDE "../actors/orc.inc" .INCLUDE "../actors/townsfolk.inc" .INCLUDE "../device.inc" +.INCLUDE "../flag.inc" .INCLUDE "../macros.inc" .INCLUDE "../oam.inc" .INCLUDE "../platform.inc" +.INCLUDE "../platforms/barrier.inc" .INCLUDE "../platforms/lava.inc" .INCLUDE "../room.inc" .INCLUDE "../spawn.inc" .IMPORT DataA_Room_Shadow_sTileset +.IMPORT Data_Empty_sDevice_arr .IMPORT FuncA_Objects_AnimateLavaTerrain .IMPORT FuncA_Terrain_FadeInTallRoomWithLava +.IMPORT FuncC_Shadow_DrawBarrierPlatform .IMPORT Func_Noop .IMPORT Ppu_ChrObjShadow +.IMPORT Ram_PlatformType_ePlatform_arr +.IMPORT Sram_ProgressFlags_arr .IMPORTZP Zp_AvatarFlags_bObj .IMPORTZP Zp_AvatarPosY_i16 @@ -41,10 +47,23 @@ ;;; The index of the passage that leads to the ShadowDrill room. kDrillPassageIndex = 1 +;;; The index of the passage that leads to the ShadowDepths room. +kDepthsPassageIndex = 3 + ;;; The room pixel Y-position of the center of the passage that leads to the ;;; ShadowDrill room. kDrillPassageCenterY = $0050 +;;; The platform indices for the barriers that lock the player avatar out of +;;; the ShadowDepths until the ghosts are tagged. +kBarrier1PlatformIndex = 0 +kBarrier2PlatformIndex = 1 + +;;; The room pixel Y-positions for the tops of the barrier platforms when they +;;; are fully open or fully shut. +kBarrierShutTop = $0130 +kBarrierOpenTop = kBarrierShutTop - kBarrierPlatformHeightPx + ;;;=========================================================================;;; .SEGMENT "PRGC_Shadow" @@ -68,18 +87,34 @@ _Ext_sRoomExt: d_addr Terrain_sTileset_ptr, DataA_Room_Shadow_sTileset d_addr Platforms_sPlatform_arr_ptr, _Platforms_sPlatform_arr d_addr Actors_sActor_arr_ptr, _Actors_sActor_arr - d_addr Devices_sDevice_arr_ptr, _Devices_sDevice_arr + d_addr Devices_sDevice_arr_ptr, Data_Empty_sDevice_arr d_addr Passages_sPassage_arr_ptr, _Passages_sPassage_arr d_addr Enter_func_ptr, FuncA_Room_ShadowDescent_EnterRoom d_addr FadeIn_func_ptr, FuncA_Terrain_FadeInTallRoomWithLava d_addr Tick_func_ptr, Func_Noop - d_addr Draw_func_ptr, FuncA_Objects_AnimateLavaTerrain + d_addr Draw_func_ptr, FuncC_Shadow_Descent_DrawRoom D_END _TerrainData: : .incbin "out/rooms/shadow_descent.room" .assert * - :- = 18 * 24, error _Platforms_sPlatform_arr: -: ;; Lava: +: .assert * - :- = kBarrier1PlatformIndex * .sizeof(sPlatform), error + D_STRUCT sPlatform + d_byte Type_ePlatform, ePlatform::Solid + d_word WidthPx_u16, kBarrierPlatformWidthPx + d_byte HeightPx_u8, kBarrierPlatformHeightPx + d_word Left_i16, $00e0 + d_word Top_i16, kBarrierShutTop + D_END + .assert * - :- = kBarrier2PlatformIndex * .sizeof(sPlatform), error + D_STRUCT sPlatform + d_byte Type_ePlatform, ePlatform::Solid + d_word WidthPx_u16, kBarrierPlatformWidthPx + d_byte HeightPx_u8, kBarrierPlatformHeightPx + d_word Left_i16, $00e8 + d_word Top_i16, kBarrierShutTop + D_END + ;; Lava: D_STRUCT sPlatform d_byte Type_ePlatform, ePlatform::Kill d_word WidthPx_u16, $120 @@ -98,10 +133,6 @@ _Actors_sActor_arr: D_END .assert * - :- <= kMaxActors * .sizeof(sActor), error .byte eActor::None -_Devices_sDevice_arr: -: ;; TODO - .assert * - :- <= kMaxDevices * .sizeof(sDevice), error - .byte eDevice::None _Passages_sPassage_arr: : D_STRUCT sPassage d_byte Exit_bPassage, ePassage::Western | 0 @@ -122,6 +153,7 @@ _Passages_sPassage_arr: d_byte SpawnBlock_u8, 20 d_byte SpawnAdjust_byte, 0 D_END + .assert * - :- = kDepthsPassageIndex * .sizeof(sPassage), error D_STRUCT sPassage d_byte Exit_bPassage, ePassage::Eastern | 1 d_byte Destination_eRoom, eRoom::ShadowDepths @@ -131,12 +163,25 @@ _Passages_sPassage_arr: .assert * - :- <= kMaxPassages * .sizeof(sPassage), error .ENDPROC +.PROC FuncC_Shadow_Descent_DrawRoom + ldx #kBarrier1PlatformIndex + jsr FuncC_Shadow_DrawBarrierPlatform + ldx #kBarrier2PlatformIndex + jsr FuncC_Shadow_DrawBarrierPlatform + jmp FuncA_Objects_AnimateLavaTerrain +.ENDPROC + ;;;=========================================================================;;; .SEGMENT "PRGA_Room" ;;; @param A The bSpawn value for where the avatar is entering the room. .PROC FuncA_Room_ShadowDescent_EnterRoom + ;; If entering from ShadowDepths, raise both barriers. (Normally, it + ;; should be impossible to reach ShadowDepths without first raising both + ;; barriers, so this is just a safety measure.) + cmp #bSpawn::Passage | kDepthsPassageIndex + beq _RaiseBothBarriers ;; If entering from the ShadowDrill room, and gravity is still reversed, ;; un-reverse it. cmp #bSpawn::Passage | kDrillPassageIndex @@ -155,6 +200,21 @@ _Passages_sPassage_arr: sbc Zp_AvatarPosY_i16 + 1 sta Zp_AvatarPosY_i16 + 1 @done: +_MaybeRaiseBarriers: + ldy #ePlatform::Zone + flag_bit Sram_ProgressFlags_arr, eFlag::ShadowHeartTaggedGhost + beq @keepBarrier1 + sty Ram_PlatformType_ePlatform_arr + kBarrier1PlatformIndex + @keepBarrier1: + flag_bit Sram_ProgressFlags_arr, eFlag::ShadowOfficeTaggedGhost + beq @keepBarrier2 + sty Ram_PlatformType_ePlatform_arr + kBarrier2PlatformIndex + @keepBarrier2: + rts +_RaiseBothBarriers: + ldy #ePlatform::Zone + sty Ram_PlatformType_ePlatform_arr + kBarrier1PlatformIndex + sty Ram_PlatformType_ePlatform_arr + kBarrier2PlatformIndex rts .ENDPROC diff --git a/src/rooms/shadow_office.asm b/src/rooms/shadow_office.asm index f486b5c1..3e2c58bb 100644 --- a/src/rooms/shadow_office.asm +++ b/src/rooms/shadow_office.asm @@ -18,6 +18,7 @@ ;;;=========================================================================;;; .INCLUDE "../actor.inc" +.INCLUDE "../actors/orc.inc" .INCLUDE "../charmap.inc" .INCLUDE "../device.inc" .INCLUDE "../dialog.inc" @@ -33,14 +34,32 @@ .IMPORT FuncA_Terrain_FadeInShortRoomWithLava .IMPORT Func_FindEmptyActorSlot .IMPORT Func_InitActorSmokeExplosion +.IMPORT Func_IsPointInPlatform .IMPORT Func_SetActorCenterToPoint +.IMPORT Func_SetFlag .IMPORT Func_SetPointToAvatarCenter .IMPORT Ppu_ChrObjShadow +.IMPORT Ram_ActorPosY_i16_1_arr +.IMPORT Ram_ActorType_eActor_arr +.IMPORT Ram_PlatformType_ePlatform_arr +.IMPORT Sram_ProgressFlags_arr .IMPORTZP Zp_AvatarPosX_i16 .IMPORTZP Zp_AvatarPosY_i16 ;;;=========================================================================;;; +;;; The actor index for the ghost in this room. +kGhostActorIndex = 0 + +;;; The platform index for the zone that makes the ghost disappear when the +;;; player avatar enters it. +kGhostTagZonePlatformIndex = 0 + +;;; The platform index for the wall that blocks the ghost tank at first. +kGhostWallPlatformIndex = 1 + +;;;=========================================================================;;; + .SEGMENT "PRGC_Shadow" .EXPORT DataC_Shadow_Office_sRoom @@ -73,7 +92,23 @@ _TerrainData: : .incbin "out/rooms/shadow_office.room" .assert * - :- = 17 * 15, error _Platforms_sPlatform_arr: -: ;; Lava: +: .assert * - :- = kGhostTagZonePlatformIndex * .sizeof(sPlatform), error + D_STRUCT sPlatform + d_byte Type_ePlatform, ePlatform::Zone + d_word WidthPx_u16, $18 + d_byte HeightPx_u8, $10 + d_word Left_i16, $0068 + d_word Top_i16, $00b0 + D_END + .assert * - :- = kGhostWallPlatformIndex * .sizeof(sPlatform), error + D_STRUCT sPlatform + d_byte Type_ePlatform, ePlatform::Solid + d_word WidthPx_u16, $30 + d_byte HeightPx_u8, $30 + d_word Left_i16, $0060 + d_word Top_i16, $0090 + D_END + ;; Lava: D_STRUCT sPlatform d_byte Type_ePlatform, ePlatform::Kill d_word WidthPx_u16, $110 @@ -84,7 +119,13 @@ _Platforms_sPlatform_arr: .assert * - :- <= kMaxPlatforms * .sizeof(sPlatform), error .byte ePlatform::None _Actors_sActor_arr: -: ;; TODO: orc ghost +: .assert * - :- = kGhostActorIndex * .sizeof(sActor), error + D_STRUCT sActor + d_byte Type_eActor, eActor::NpcOrc + d_word PosX_i16, $0074 + d_word PosY_i16, $01b3 + d_byte Param_byte, eNpcOrc::GhostStanding + D_END .assert * - :- <= kMaxActors * .sizeof(sActor), error .byte eActor::None _Devices_sDevice_arr: @@ -177,12 +218,41 @@ _Passages_sPassage_arr: .SEGMENT "PRGA_Room" .PROC FuncA_Room_ShadowOffice_EnterRoom - ;; TODO: remove ghost if tagged +_MaybeRemoveWall: + flag_bit Sram_ProgressFlags_arr, eFlag::ShadowOfficeRemovedWall + beq _Return + lda #ePlatform::Zone + sta Ram_PlatformType_ePlatform_arr + kGhostWallPlatformIndex +_MaybeRevealGhost: + flag_bit Sram_ProgressFlags_arr, eFlag::ShadowOfficeTaggedGhost + bne _RemoveGhost + lda #0 + sta Ram_ActorPosY_i16_1_arr + kGhostActorIndex + rts +_RemoveGhost: + lda #eActor::None + sta Ram_ActorType_eActor_arr + kGhostActorIndex +_Return: rts .ENDPROC .PROC FuncA_Room_ShadowOffice_TickRoom - ;; TODO: tag ghost +_MaybeTagGhost: + ;; If the avatar isn't in the tag zone, don't tag the ghost. + jsr Func_SetPointToAvatarCenter + ldy #kGhostTagZonePlatformIndex ; param: platform index + jsr Func_IsPointInPlatform ; returns C + bcc @done ; avatar is not in the tag zone + ;; Mark the ghost as tagged; if it already was, then we're done. + ldx #eFlag::ShadowOfficeTaggedGhost ; param: flag + jsr Func_SetFlag ; sets C if flag was already set + bcs @done ; ghost was already tagged + ;; Make the ghost disappear. + ;; TODO: Play a sound + ;; TODO: Animate the ghost disappearing. + lda #eActor::None + sta Ram_ActorType_eActor_arr + kGhostActorIndex + @done: rts .ENDPROC diff --git a/src/rooms/shadow_office.bg b/src/rooms/shadow_office.bg index f81f6576..cdd3eeb6 100644 --- a/src/rooms/shadow_office.bg +++ b/src/rooms/shadow_office.bg @@ -15,9 +15,9 @@ FOAJAB EC AB AB ECEDECEE EMBIEC AB FPBIEOBIEOBIEGEFEMEM EHAJEMBIEO BC EMEDEM EF EM FMENEB AB EGEBEG -EMBIED EEENEF AB FOBIEAENEN -EM AF FO EDECEMCAEOBAED -EM ABEM EAEHEDBC AB +EMBIED DCDJ AB FOBIEAENEN +EM AF FO DEDF CAEOBAED +EM ABEM DGDHCBBC AB EM EAEJEEENENENEFFMEKENENFEENEN ALALALALALALALALALALALALALALALALAL ALALALALALALALALALALALALALALALALAL diff --git a/src/rooms/shadow_trap.asm b/src/rooms/shadow_trap.asm index 980b2cf7..9cd2df67 100644 --- a/src/rooms/shadow_trap.asm +++ b/src/rooms/shadow_trap.asm @@ -206,7 +206,7 @@ _Platforms_sPlatform_arr: d_word WidthPx_u16, kBarrierPlatformWidthPx d_byte HeightPx_u8, kBarrierPlatformHeightPx d_word Left_i16, $002e - kBarrierPlatformWidthPx - d_word Top_i16, $0090 - kBarrierPlatformHeightPx + d_word Top_i16, kBarrierOpenTop D_END .assert * - :- = kEastBarrierPlatformIndex * .sizeof(sPlatform), error D_STRUCT sPlatform @@ -214,7 +214,7 @@ _Platforms_sPlatform_arr: d_word WidthPx_u16, kBarrierPlatformWidthPx d_byte HeightPx_u8, kBarrierPlatformHeightPx d_word Left_i16, $00f2 - d_word Top_i16, $0090 - kBarrierPlatformHeightPx + d_word Top_i16, kBarrierOpenTop D_END .assert * - :- = kTrapSpawnEastPlatformIndex * .sizeof(sPlatform), error D_STRUCT sPlatform