; NAME: Goal Axe
; GAMES: MP3_USA
; EXECUTION: Direct
; PARAM: Space|InitialBridgeChainSpace
; PARAM: Space|NextSpace
; PARAM: Space|DropFromBridge

; Every space on the bridge should be in the same chain.
; Meaning there should be no junctions, the final space needs to be
; a blank space that would set the player's position to be
; onto a merge space, like how you would use the Start Space.

; This event should be at a dead end that can only be accessed by
; one direction.

ADDIU SP SP -48 ; Including 4 byte pad
SW RA 40(SP)
SW S2 36(SP)
SW S1 32(SP)
SW S0 28(SP)

; Display a message that Baby Bowser has been bested by the Goal Axe.
SW R0 16(SP) ; A4
SW R0 20(SP) ; A5
SW R0 24(SP) ; A6
ADDI A0 R0 0x05 ; Character image (-1 for none)
LUI A1 hi(babyBowserDropped)
ADDIU A1 A1 lo(babyBowserDropped)
ADDU A2 R0 R0
JAL 0x800EC8EC ; ShowMessage
ADDU A3 R0 R0

JAL 0x800EC9DC
NOP
JAL 0x800EC6C8
NOP
JAL 0x800EC6EC
NOP

JAL PlaySound
ADDIU A0 R0 0x2A0 ; Baby Bowser sound

; Fade out and remove the players on the "Bridge".
fadeOut:

; Remove everyone on the "Bridge" spaces, send back to DropFromBridge
dropPlayers:

;loads player index onto V0
JAL GetCurrentPlayerIndex
NOP

;S0 is used to search through each player index: [0, 1, 2, 3]
ADDU S0 R0 R0 ;set to 0

;S2 is the initial chain where the "Bridge" starts.
LUI S2 hi(InitialBridgeChainSpace_chain_index)
ADDIU S2 S2 lo(InitialBridgeChainSpace_chain_index)

;T0 is the initial space index where the "Bridge" starts.
LUI T0 hi(InitialBridgeChainSpace_chain_space_index)
ADDIU T0 T0 lo(InitialBridgeChainSpace_chain_space_index)

;I wish I could remember how to do loops in this..........
;figure out which players to drop
player1:
LUI S1 hi(p1_cur_chain_index)
ADDIU S1 S1 lo(p1_cur_chain_index)

;skip if it is the Current Player
BEQ S0 V0 player2
NOP
;skip if player is not on the "Bridge" chain
LBU T2 0(S1)
BNE S2 T2 player2
NOP
;check if player is before the spaces considered on the "Bridge"
LUI T1 hi(p1_cur_space_index)
ADDIU T1 T1 lo(p1_cur_space_index)

LBU T2 0(T1)
SLT T2 T2 T0 ; is T0 > T1? (Current space is before bridge?)
BNEZ T2 player2
NOP

;Set to space they will be dropped off to.
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_index ;cur chain
SB T1 0(S1)
ADDIU S1 S1 1
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_space_index ;cur space
SB T1 0(S1)
ADDIU S1 S1 1
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_index ;next chain
SB T1 0(S1)
ADDIU S1 S1 1
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_space_index ;next space
SB T1 0(S1)
ADDIU S1 S1 3
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_index ;prev chain
SB T1 0(S1)
ADDIU S1 S1 1
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_space_index ;prev space
SB T1 0(S1)

player2:
ADDIU S0 S0 1
LUI S1 hi(p2_cur_chain_index)
ADDIU S1 S1 lo(p2_cur_chain_index)

;skip if it is the Current Player
BEQ S0 V0 player3
NOP
;skip if player is not on the "Bridge" chain
LBU T2 0(S1)
BNE S2 T2 player3
NOP
;check if player is before the spaces considered on the "Bridge"
LUI T1 hi(p2_cur_space_index)
ADDIU T1 T1 lo(p2_cur_space_index)

LBU T2 0(T1)
SLT T2 T2 T0 ; is T0 > T1? (Current space is before bridge?)
BNEZ T2 player3
NOP

;Set to space they will be dropped off to.
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_index ;cur chain
SB T1 0(S1)
ADDIU S1 S1 1
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_space_index ;cur space
SB T1 0(S1)
ADDIU S1 S1 1
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_index ;next chain
SB T1 0(S1)
ADDIU S1 S1 1
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_space_index ;next space
SB T1 0(S1)
ADDIU S1 S1 3
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_index ;prev chain
SB T1 0(S1)
ADDIU S1 S1 1
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_space_index ;prev space
SB T1 0(S1)

player3:
ADDIU S0 S0 1
LUI S1 hi(p3_cur_chain_index)
ADDIU S1 S1 lo(p3_cur_chain_index)

;skip if it is the Current Player
BEQ S0 V0 player4
NOP
;skip if player is not on the "Bridge" chain
LBU T2 0(S1)
BNE S2 T2 player4
NOP
;check if player is before the spaces considered on the "Bridge"
LUI T1 hi(p3_cur_space_index)
ADDIU T1 T1 lo(p3_cur_space_index)

LBU T2 0(T1)
SLT T2 T2 T0 ; is T0 > T1? (Current space is before bridge?)
BNEZ T2 player4
NOP

;Set to space they will be dropped off to.
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_index ;cur chain
SB T1 0(S1)
ADDIU S1 S1 1
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_space_index ;cur space
SB T1 0(S1)
ADDIU S1 S1 1
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_index ;next chain
SB T1 0(S1)
ADDIU S1 S1 1
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_space_index ;next space
SB T1 0(S1)
ADDIU S1 S1 3
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_index ;prev chain
SB T1 0(S1)
ADDIU S1 S1 1
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_space_index ;prev space
SB T1 0(S1)

player4:
ADDIU S0 S0 1
LUI S1 hi(p4_cur_chain_index)
ADDIU S1 S1 lo(p4_cur_chain_index)

;skip if it is the Current Player
BEQ S0 V0 fadeIn
NOP
;skip if player is not on the "Bridge" chain
LBU T2 0(S1)
BNE S2 T2 fadeIn
NOP
;check if player is before the spaces considered on the "Bridge"
LUI T1 hi(p4_cur_space_index)
ADDIU T1 T1 lo(p4_cur_space_index)

LBU T2 0(T1)
SLT T2 T2 T0 ; is T0 > T1? (Current space is before bridge?)
BNEZ T2 fadeIn
NOP

;Set to space they will be dropped off to.
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_index ;cur chain
SB T1 0(S1)
ADDIU S1 S1 1
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_space_index ;cur space
SB T1 0(S1)
ADDIU S1 S1 1
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_index ;next chain
SB T1 0(S1)
ADDIU S1 S1 1
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_space_index ;next space
SB T1 0(S1)
ADDIU S1 S1 3
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_index ;prev chain
SB T1 0(S1)
ADDIU S1 S1 1
LBU T1 0(S1)
ADDIU T1 R0 DropFromBridge_chain_space_index ;prev space
SB T1 0(S1)

; Fade back in.
fadeIn:

; Display Baby Bowser's reaction.
SW R0 16(SP) ; A4
SW R0 20(SP) ; A5
SW R0 24(SP) ; A6
ADDI A0 R0 0x05 ; Character image (-1 for none)
LUI A1 hi(babyBowserRebuild)
ADDIU A1 A1 lo(babyBowserRebuild)
ADDU A2 R0 R0
JAL 0x800EC8EC ; ShowMessage
ADDU A3 R0 R0

JAL 0x800EC9DC
NOP
JAL 0x800EC6C8
NOP
JAL 0x800EC6EC
NOP

JAL PlaySound
ADDIU A0 R0 0x2A0 ; Baby Bowser sound


; The Next Space Code, forces moving forward even when in reverse.
moveToNextSpace:
JAL GetCurrentPlayerIndex
NOP

ADD A0 R0 V0 ; Assigns Current Player Index to A0
ADDIU A1 R0 NextSpace_chain_index ; Assigns Chain Index to A1
ADDIU A2 R0 NextSpace_chain_space_index ; Assigns Space Index to A2

JAL SetNextChainAndSpace 
NOP

; Time to arbitrarily make the player move forward I guess.
; Get current player's status.
JAL GetCurrentPlayerIndex
NOP
SLL V1 V0 3
SUBU V1 V1 V0
SLL V0 V1 3
LUI S1 hi(p1_status_flags)
ADDU S1 S1 V0
ADDIU S1 S1 lo(p1_status_flags)

; see if player is moving backwards (this doesn't make sense but
; when the chain is detached from everything else I guess the 
; game just doesn't know how to handle dead ends and gets confused
; as to what direction is actually forward)
LBU S0 0(S1)
ANDI A0 S0 0x01 ; Status bit for moving backwards
BEQ A0 R0 exit
NOP

XORI S0 S0 0x01 ; Erase the status bit for moving backwards and store
SB S0 0(S1)

exit:
LW RA 40(SP)
LW S2 36(SP)
LW S1 32(SP)
LW S0 28(SP)
JR RA
ADDIU SP SP 48

.align 16
babyBowserDropped:
.byte 0x1A, 0x1A, 0x1A, 0x1A ; Padding for picture
.ascii "What"
.byte 0xC3 ; ?
.byte 0x0A ; \n
.byte 0x1A, 0x1A, 0x1A, 0x1A ; Padding for picture
.ascii "How were you able to reach the axe"
.byte 0xC3 ; ?
.byte 0xFF,0 ; FF=Pause

.align 16
babyBowserRebuild:
.byte 0x1A, 0x1A, 0x1A, 0x1A ; Padding for picture
.ascii "Grrrr"
.byte 0x85 ; .
.byte 0x85 ; .
.byte 0x85 ; .
.byte 0x0A ; \n
.byte 0x1A, 0x1A, 0x1A, 0x1A ; Padding for picture
.ascii "We will rebuild the bridge but"
.byte 0x0A ; \n
.byte 0x1A, 0x1A, 0x1A, 0x1A ; Padding for picture
.ascii "good luck reaching the axe next time"
.byte 0xC2 ; !
.byte 0xFF,0 ; FF=Pause