From e112bed2649ea077e20f593ee22594d690d110c8 Mon Sep 17 00:00:00 2001 From: Jared_Brian_ Date: Sat, 1 Feb 2025 19:08:57 -0700 Subject: [PATCH] Made it so the minecart sprite to follower to sprite hand off is much smoother by telling the old sprite cart not to draw after the follower spawns, adjusting the positioning of the follower draw itself, and also made it so it won't always be vertical Fixed the bug that made it so the minecart would auto grab you sometimes after getting off and then there was another bug that had accidently been introduced that made carts on track 00 not work --- Sprites/NPCs/followers.asm | 61 +++++++++++++++---------- Sprites/Objects/minecart.asm | 88 +++++++++++++++++++++++------------- 2 files changed, 95 insertions(+), 54 deletions(-) diff --git a/Sprites/NPCs/followers.asm b/Sprites/NPCs/followers.asm index eb894a4..56ca926 100644 --- a/Sprites/NPCs/followers.asm +++ b/Sprites/NPCs/followers.asm @@ -98,13 +98,13 @@ ZoraBaby_RevertToSprite: PHX TAX - LDA.w $1A64, X : AND.b #$03 : STA.w SprMiscE,Y : STA.w SprMiscC,Y - LDA.w $1A00, X : CLC : ADC.b #$02 : STA.w SprY,Y - LDA.w $1A14, X : ADC.b #$00 : STA.w SprYH,Y - LDA.w $1A28, X : CLC : ADC.b #$10 : STA.w SprX,Y - LDA.w $1A3C, X : ADC.b #$00 : STA.w SprXH,Y - LDA.b $EE : STA.w $0F20,Y - LDA.b #$01 : STA.w SprBulletproof,Y : STA.w $0E80,Y + LDA.w $1A64, X : AND.b #$03 : STA.w SprMiscE, Y : STA.w SprMiscC, Y + LDA.w $1A00, X : CLC : ADC.b #$02 : STA.w SprY, Y + LDA.w $1A14, X : ADC.b #$00 : STA.w SprYH, Y + LDA.w $1A28, X : CLC : ADC.b #$10 : STA.w SprX, Y + LDA.w $1A3C, X : ADC.b #$00 : STA.w SprXH, Y + LDA.b $EE : STA.w $0F20, Y + LDA.b #$01 : STA.w SprBulletproof, Y : STA.w $0E80, Y LDA.b #$04 : STA.w SprAction, Y LDA.b #$FF : STA.w SprTimerB, Y PLX @@ -168,8 +168,8 @@ ZoraBaby_CheckForWaterSwitchSprite: PHX LDX #$10 - - LDA.w SprType, X - CMP #$21 : BEQ ZoraBaby_CheckForWaterGateSwitch_found_switch + LDA.w SprType, X + CMP #$21 : BEQ ZoraBaby_CheckForWaterGateSwitch_found_switch DEX : BPL - ; Water gate switch not found PLX @@ -185,9 +185,9 @@ ZoraBaby_CheckForWaterGateSwitch: LDX #$10 - LDA.w SprType, X : CMP #$04 : BEQ .found_switch - DEX : BPL - - ; Water gate switch not found - PLX + DEX : BPL - + ; Water gate switch not found + PLX .not_on_switch CLC RTS @@ -203,8 +203,8 @@ ZoraBaby_CheckForWaterGateSwitch: LDA.w SprX, X : SEC : SBC #$09 : CMP.w SprX, Y : BCS .not_on_switch LDA.w SprY, X : CLC : ADC #$12 : CMP.w SprY, Y : BCC .not_on_switch LDA.w SprY, X : SEC : SBC #$12 : CMP.w SprY, Y : BCS .not_on_switch - SEC - RTS + SEC + RTS } ZoraBaby_GlobalBehavior: @@ -295,9 +295,9 @@ Sprite_39_ZoraBaby: JSL JumpTableLocal dw LockSmith_Chillin - dw ZoraBaby_FollowLink ; Becomes Follower - dw ZoraBaby_OfferService ; I can help! (Follow/Stay) - dw ZoraBaby_RespondToAnswer ; Goto FollowLink or JustPromiseOkay + dw ZoraBaby_FollowLink ; Becomes Follower + dw ZoraBaby_OfferService ; I can help! (Follow/Stay) + dw ZoraBaby_RespondToAnswer ; Goto FollowLink or JustPromiseOkay dw ZoraBaby_AgreeToWait dw ZoraBaby_PullSwitch dw ZoraBaby_PostSwitch @@ -609,17 +609,17 @@ pullpc FollowerDraw_CalculateOAMCoords: { REP #$20 - LDA.b $02 : STA.b ($90),Y + LDA.b $02 : STA.b ($90), Y INY CLC : ADC.w #$0080 : CMP.w #$0180 : BCS .off_screen LDA.b $02 : AND.w #$0100 : STA.b $74 - LDA.b $00 : STA.b ($90),Y + LDA.b $00 : STA.b ($90), Y CLC : ADC.w #$0010 : CMP.w #$0100 : BCC .on_screen .off_screen: - LDA.w #$00F0 : STA.b ($90),Y + LDA.w #$00F0 : STA.b ($90), Y .on_screen: SEP #$20 @@ -784,7 +784,8 @@ MinecartFollower_TransitionToSprite: JSL Sprite_SpawnDynamically TYX JSL Sprite_SetSpawnedCoords - LDA.w !MinecartDirection, X : CMP.b #$00 : BEQ .vert_adjust + LDA.w !MinecartDirectionCache : STA.w !MinecartDirection, X + CMP.b #$00 : BEQ .vert_adjust CMP.b #$02 : BEQ .vert_adjust LDA.w POSY : CLC : ADC #$08 : STA.w SprY, X LDA.w POSX : STA.w SprX, X @@ -802,6 +803,7 @@ MinecartFollower_TransitionToSprite: LDA.w !MinecartTrackCache : STA.w SprSubtype, X LDA Minecart_AnimDirection, X : STA $0D90, X + JSL Sprite_Minecart_Prep LDA.b #$00 : STA.l $7EF3CC RTL @@ -812,7 +814,7 @@ DrawMinecartFollower: { JSL $099EFC ; Follower_Initialize - LDA.w !MinecartDirection, X : TAX + LDA.w !MinecartDirectionCache : TAX LDA Minecart_AnimDirection, X : STA $02CF JSR FollowerDraw_CachePosition @@ -838,6 +840,13 @@ FollowerDraw_CachePosition: LDA.w $1A3C, X : STA.b $03 LDA.w $1A64, X : STA.b $05 + ; Adjust the coordinate a bit to place it more in line where the + ; minecart should be relative to Link. + REP #$20 + LDA.b $00 : SEC : SBC.w #$0008 : STA.b $00 + LDA.b $02 : CLC : ADC.w #$0002 : STA.b $02 + SEP #$20 + ; ------------------------- AND.b #$20 LSR A @@ -853,7 +862,7 @@ FollowerDraw_CachePosition: ; variables based on the follower here and manipulate $72 ; if the player was immobile. - CLC : ADC $04 : STA $04 + CLC : ADC $04 : STA $04 TYA : CLC : ADC $04 : STA $04 ; ------------------------- @@ -929,6 +938,12 @@ CheckForFollowerInterroomTransition: { LDA.w !LinkInCart : BEQ .not_in_cart LDA.b #$0B : STA $7EF3CC + + ; Pause the current cart so that it doesn't draw anymore + PHX + LDX.w !MinecartCurrent + LDA.b #$01 : STA $0F00, X + PLX .not_in_cart JSL $01873A ; Underworld_LoadRoom RTL diff --git a/Sprites/Objects/minecart.asm b/Sprites/Objects/minecart.asm index 7e5be14..5a118ae 100644 --- a/Sprites/Objects/minecart.asm +++ b/Sprites/Objects/minecart.asm @@ -114,13 +114,23 @@ Right = $03 ; the cart. We can only use one cart at a time so this is only 1 byte. !MinecartTrackCache = $07E8 +; This is used to keep track of which direction we are going during room +; transitions. We can only use one cart at a time so this is only 1 byte. +!MinecartDirectionCache = $07E9 + +; This is used to keep track of which cart in a room we are riding. This +; is based of the X value used to index sprite arrays. +!MinecartCurrent = $07EA + ; ========================================================= Sprite_Minecart_Long: { PHB : PHK : PLB + JSR Sprite_Minecart_DrawTop ; Draw behind Link JSR Sprite_Minecart_DrawBottom ; Draw in front of Link + JSL Sprite_CheckActive : BCC .SpriteIsNotActive JSR Sprite_Minecart_Main .SpriteIsNotActive @@ -140,12 +150,15 @@ Sprite_Minecart_Prep: JSR UpdateCachedCoords LDA.w SprSubtype, X : ASL : TAY - - ; If Link is in a cart AND he is on the same track as this cart's - ; track, kill the cart. - CMP.w !MinecartTrackCache : BNE .notSameTrack + + ; If Link is on the same track as this cart's track AND this cart is + ; not the active cart, kill the cart. + LDA.w SprSubtype, X : CMP.w !MinecartTrackCache : BNE .notSameTrack LDA.b !LinkInCart : BEQ .notInCart - BRA .killMinecart + ; If the SprMiscB is > 4, then it's an active cart. This should only + ; be the case when transitioning from a follower. + LDA.w SprMiscB, X : CMP.b #$04 : BCS .active1 + BRA .killMinecart .notInCart .notSameTrack @@ -173,7 +186,8 @@ Sprite_Minecart_Prep: LDA.w !MinecartTrackY, Y : CMP.w SprCachedY : BNE .killMinecart SEP #$20 - STZ.w SprMiscF, X ; Clear the auto-move flag + .active1 + STZ.w SprMiscG, X ; Clear the active tossing flag LDA.b #$04 : STA.w SprNbrOAM, X ; Nbr Oam Entries @@ -189,10 +203,13 @@ Sprite_Minecart_Prep: ; If the SprMiscB is > 4, then it's an active cart. This should only ; be the case when transitioning from a follower. LDA.w SprMiscB, X : CMP.b #$04 : BCC .notActive - LDA.w SprMiscB, X : SEC : SBC.b #$04 : STA.w SprMiscB, X - LDA.b #$01 : STA.w SprMiscF, X ; Set the auto-move flag + SEC : SBC.b #$04 : STA.w SprMiscB, X - BRA .active + ; Go directly to the direction action we are facing. We add 2 to + ; skip the Minecart_WaitHoriz and Minecart_WaitVert actions. + CLC : ADC.b #$02 : STA.w SprAction, X + + BRA .active2 .notActive ; Setup Minecart position to look for tile IDs ; We use AND #$F8 to clamp to a 8x8 grid. @@ -214,17 +231,21 @@ Sprite_Minecart_Prep: CMP.b #$BA : BEQ .goWest .goNorth LDA.b #North : STA.w SprMiscB, X + %GotoAction(1) ; Minecart_WaitVert JMP .done2 .goEast LDA.b #East : STA.w SprMiscB, X + %GotoAction(0) ; Minecart_WaitHoriz JMP .done2 .goSouth LDA.b #South : STA.w SprMiscB, X + %GotoAction(1) ; Minecart_WaitVert JMP .done2 .goWest LDA.b #West : STA.w SprMiscB, X + %GotoAction(0) ; Minecart_WaitHoriz .done2 - .active + .active2 STZ.w SprTimerB, X @@ -244,8 +265,6 @@ Sprite_Minecart_Prep: %PlayAnimation(2,3,8) LDA.b #$02 : STA.w $0D90, X - %GotoAction(1) ; Minecart_WaitVert - BRA .done .east LDA.b #East : STA !MinecartDirection, X @@ -260,8 +279,6 @@ Sprite_Minecart_Prep: .horz %PlayAnimation(0,1,8) LDA.b #$00 : STA.w $0D90, X - - %GotoAction(0) ; Minecart_WaitHoriz .done PLB @@ -270,7 +287,7 @@ Sprite_Minecart_Prep: ; This is which room each track should start in if it hasn't already ; been given a track. .TrackStartingRooms - dw $0089, $0089, $0089, $0089, $0089, $0089, $0089, $0089 + dw $0089, $0089, $0089, $0088, $0089, $0089, $0089, $0089 dw $0089, $0089, $0089, $0089, $0089, $0089, $0089, $0089 dw $0089, $0089, $0089, $0089, $0089, $0089, $0089, $0089 dw $0089, $0089, $0089, $0089, $0089, $0089, $0089, $0089 @@ -279,13 +296,13 @@ Sprite_Minecart_Prep: ; already been given a position. This is necessary to allow for more ; than one stopping point to be in one room. .TrackStartingX - dw $1320, $12D0, $1300, $1300, $1300, $1300, $1300, $1300 + dw $1320, $12D0, $1300, $1100, $1300, $1300, $1300, $1300 dw $1300, $1300, $1300, $1300, $1300, $1300, $1300, $1300 dw $1300, $1300, $1300, $1300, $1300, $1300, $1300, $1300 dw $1300, $1300, $1300, $1300, $1300, $1300, $1300, $1300 .TrackStartingY - dw $11C0, $1120, $1100, $1100, $1100, $1100, $1100, $1100 + dw $11C0, $1120, $1100, $10D0, $1100, $1100, $1100, $1100 dw $1100, $1100, $1100, $1100, $1100, $1100, $1100, $1100 dw $1100, $1100, $1100, $1100, $1100, $1100, $1100, $1100 dw $1100, $1100, $1100, $1100, $1100, $1100, $1100, $1100 @@ -319,11 +336,8 @@ Sprite_Minecart_Main: LDA.w LinkCarryOrToss : AND #$03 : BNE .lifting LDA.w SprTimerA, X : BNE .not_ready JSR CheckIfPlayerIsOn : BCC .not_ready - ; If the cart is active, we move immediately - LDA.w SprMiscF, X : BNE .active_cart - ; Check for B button - LDA $F4 : AND.b #$80 : BEQ .not_ready - .active_cart + ; Check for B button + LDA $F4 : AND.b #$80 : BEQ .not_ready ; Save what track we are currently riding. LDA.w SprSubtype, X : STA.w !MinecartTrackCache @@ -359,11 +373,8 @@ Sprite_Minecart_Main: LDA.w LinkCarryOrToss : AND #$03 : BNE .lifting LDA.w SprTimerA, X : BNE .not_ready JSR CheckIfPlayerIsOn : BCC .not_ready - ; If the cart is active, we move immediately - LDA.w SprMiscF, X : BNE .active_cart - ; Check for B button - LDA $F4 : AND.b #$80 : BEQ .not_ready - .active_cart + ; Check for B button + LDA $F4 : AND.b #$80 : BEQ .not_ready ; Save what track we are currently riding. LDA.w SprSubtype, X : STA.w !MinecartTrackCache @@ -555,6 +566,8 @@ StopCart: LDA.w $A0 : STA.w !MinecartTrackRoom, Y SEP #$20 + STZ.w !MinecartCurrent + RTS } @@ -574,8 +587,11 @@ Minecart_SetDirectionNorth: STZ.w SprTimerB, X %PlayAnimation(2,3,8) - LDA.b #North : STA.w SprMiscB, X : STZ.w !MinecartDirection, X + LDA.b #North : STA.w SprMiscB, X + STA.w !MinecartDirection, X : STA.w !MinecartDirectionCache LDA.b #Up : STA !SpriteDirection, X + + TXA : STA.w !MinecartCurrent RTS } @@ -586,8 +602,11 @@ Minecart_SetDirectionEast: STZ.w SprTimerB, X %PlayAnimation(0,1,8) - LDA.b #East : STA.w SprMiscB, X : STA.w !MinecartDirection, X + LDA.b #East : STA.w SprMiscB, X + STA.w !MinecartDirection, X : STA.w !MinecartDirectionCache LDA.b #Right : STA !SpriteDirection, X + + TXA : STA.w !MinecartCurrent RTS } @@ -598,8 +617,11 @@ Minecart_SetDirectionSouth: STZ.w SprTimerB, X %PlayAnimation(2,3,8) - LDA.b #South : STA.w SprMiscB, X : STA.w !MinecartDirection, X + LDA.b #South : STA.w SprMiscB, X + STA.w !MinecartDirection, X : STA.w !MinecartDirectionCache LDA.b #Down : STA.w !SpriteDirection, X + + TXA : STA.w !MinecartCurrent RTS } @@ -610,8 +632,11 @@ Minecart_SetDirectionWest: STZ.w SprTimerB, X %PlayAnimation(0,1,8) - LDA.b #West : STA.w SprMiscB, X : STA.w !MinecartDirection, X + LDA.b #West : STA.w SprMiscB, X + STA.w !MinecartDirection, X : STA.w !MinecartDirectionCache LDA.b #Left : STA.w !SpriteDirection, X + + TXA : STA.w !MinecartCurrent RTS } @@ -785,6 +810,7 @@ CheckForCornerTiles: } } +; Unused? CheckForTrackTiles: { CMP.b #$B0 : BEQ .horiz