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