; NAME: Sushi's Secret Passageway (MP2) v1.1
; GAMES: MP2_USA
; EXECUTION: Direct
; PARAM: Number|CoinPrice
; PARAM: Number|ItemPrice
; PARAM: Space|SpaceToFace
; PARAM: Space|SecretPath
; PARAM: Space|SecretNext
; PARAM: Space|NormalPath
; PARAM: Boolean|MultipleSlots

; This event is designed to allow the player to access a different
; pathway if they have enough coins or a certain item. Providing
; either of these will allow the player to go to the blank space
; designated by the parameter "SecretPath". Otherwise, they will go
; toward the space designated by the parameter "NormalPath". When the
; player moves toward the SecretPath, the screen will fade out and
; they will be warped onto it. The first space that the player would
; move toward will be the parameter "SecretNext".

; During the event, the player will face the space designated by the
; parameter "SpaceToFace". The coins required are designated by the
; parameter "CoinPrice" while the item required is designed by the
; parameter "ItemPrice", set to a value from 0-9 as follows:
; 	Mushroom = 00
; 	Skeleton Key = 01
; 	Plunder Chest = 02
; 	Bowser Bomb = 03
; 	Dueling Glove = 04
; 	Warp Block = 05
; 	Golden Mushroom = 06
; 	Boo Bell = 07
; 	Bowser Suit = 08
; 	Magic Lamp = 09

; If the parameter "MultipleSlots" is set to false, the event will
; ignore any items in the player's reserve item slots if multiple
; item slots are turned on.

ADDIU SP SP -56
SW RA 52(SP)
SW S0 48(SP)
SW S1 44(SP)
SW S2 40(SP)
SW S3 36(SP)
SW S4 32(SP)

; S0 = Current Player Struct
; S1 = Prompt Choice
; S2 = Logic Array
; S3 = Coin Price
; S4 = Item Price (Required Item Index)

;===Check for Bowser===
JAL GetCurrentPlayerIndex ; Get current player index at V0
NOP
SLTI T0 V0 4 ; If V0 < 4, T0 = 1
BEQZ T0 epilogue ; If T0 = 0, current player is Bowser, go to epilogue
NOP

;===Hide Dice Roll===
JAL GetPlayerStruct
LI A0 -1 ; Get current player struct at V0
MOVE S0 V0 ; Copy V0 to S0

JAL 0x80046D2C ; HideDiceRoll
LBU A0 0x1C(S0) ; Pass current player index on A0

;===Set Player Idle Animation===
LI A0 -1 ; Set current player
LI A1 -1 ; Set idle animation
JAL SetBoardPlayerAnimation
LI A2 2 ; Loop the animation

;===Rotate Player Model===
LI A0 -1 ; Set current player
LI A1 8 ; Rotate in 8 frames
JAL RotateCharacterModel
LI A2 SpaceToFace ; Face Space

JAL SleepProcess
LI A0 8 ; Wait 8 frames for player to rotate

;===Get Entry Logic===
LUI S2 hi(LogicArray)
ADDIU S2 S2 lo(LogicArray)

LBU T0 0x19(S0) ; Load item value from offset of player struct
LI S4 ItemPrice ; Required item index
BEQL T0 S4 CheckCoins ; If player has item, check coins
SB S4 0(S2) ; Store item index if player has item (on likely)

LI T0 MultipleSlots ; Check if multiple item slots are ON
BEQL T0 R0 CheckCoins ; If multiple item slots are OFF, check coins
SB R0 0(S2) ; Store 0 if player doesn't have item

LUI T3 0x800F ; 0x800F0000
ORI T3 T3 0x8CE2 ; 0x800F8CE2, Multiple Item Slots Flag
LBU T3 0(T3) ; Load flag into T3
BEQL T3 R0 CheckCoins ; If multiple item slots are OFF, check coins
SB R0 0(S2) ; Store 0 since player doesn't have item (on likely)
; else, multiple item slots are ON

LBU T0 0x1E(S0) ; Load reserve item value #1 from offset of player struct
BEQL T0 S4 CheckCoins ; If player has item, check coins
SB S4 0(S2) ; Store item index if player has item (on likely)

LBU T0 0x1F(S0) ; Load reserve item value #2 from offset of player struct
BEQL T0 S4 CheckCoins ; If player has item, check coins
SB S4 0(S2) ; Store item index if player has item (on likely)
; else, player doesn't have item
SB R0 0(S2) ; Store 0 if player doesn't have item

CheckCoins:
LI S3 CoinPrice ; Load coin price into S3
LBU A0 0x1C(S0) ; Pass current player index on A0
JAL PlayerHasCoins
MOVE A1 S3 ; Check for coin price
SB V0 1(S2) ; Stores 0 or 1 if player doesn't have/has coins

LHU T0 0(S2) ; Load logic array read into T0
BEQZ T0 BadExit ; If all logic is 0, go to BadExit
NOP

;===Prepare Prompt===
LUI T0 hi(BlackColour)
ADDIU T0 T0 lo(BlackColour)
LUI A2 hi(WhiteColour)
ADDIU A2 A2 lo(WhiteColour)
MOVE T5 A2 ; Copy A2 to T5
LUI A3 hi(BlueColour)
ADDIU A3 A3 lo(BlueColour)
LUI T6 hi(YellowColour)
ADDIU T6 T6 lo(YellowColour)

LBU T1 0(S2) ; Load item logic into T1
BNEZ T1 GetCoinsLogic ; If T1 = 1, get coins logic
NOP
MOVE A2 T0 ; Copy T0 to A2 (set to black font)
MOVE A3 T0 ; Copy T0 to A3 (set to black font)
GetCoinsLogic:
LBU T1 1(S2) ; Load coins logic into T1
BNEZ T1 PreparePrompt ; If T1 = 1, prepare prompt
NOP
MOVE T5 T0 ; Copy T0 to T5 (set to black font)
MOVE T6 T0 ; Copy T0 to T6 (set to black font)

PreparePrompt:
LUI T4 hi(ItemStrings)
ADDIU T4 T4 lo(ItemStrings)
SLL T3 S4 5 ; Shift item index left by 5 (multiply by 32)
ADDU T4 T4 T3 ; Add distance between item strings

LUI A0 hi(PromptHolder)
ADDIU A0 A0 lo(PromptHolder) ; Parse destination
LUI A1 hi(Prompt)
ADDIU A1 A1 lo(Prompt) ; String formatter (%s)
; Pass 0th option font colour on A2
; Pass item font colour on A3
SW T4 16(SP) ; Pass item string on A4
SW T5 20(SP) ; Pass 1st option font colour on A5
SW T6 24(SP) ; Pass coins font colour on A6
JAL sprintf
SW R0 28(SP) ; Terminator byte

LUI A0 hi(CoinString)
ADDIU A0 A0 lo(CoinString) ; Parse destination
LUI A1 hi(percent_d)
ADDIU A1 A1 lo(percent_d) ; String formatter
JAL sprintf
MOVE A2 S3 ; Convert coin price to text string

;===Start Prompt===
StartPrompt:
LI A0 1 ; Display prompt
LUI A1 hi(PromptHolder)
ADDIU A1 A1 lo(PromptHolder) ; Display Prompt with strings
LUI A2 hi(CoinString)
JAL CallMessage
ADDIU A2 A2 lo(CoinString) ; Pass CoinString on A2

JAL DisablePromptOptions
MOVE A0 S2 ; Pass logic array on A0

JAL PlayerIsCPU
LBU A0 0x1C(S0) ; Pass current player index on A0

BEQZ V0 WaitOnPrompt ; If V0 = 0, wait on prompt
NOP
JAL SleepProcess
LI A0 10 ; Wait 10 frames for textbox to show

JAL PlaySound
LI A0 3 ; Selection sound

JAL AILogic
MOVE A0 S2 ; Pass logic array on A0

J GetSelection
NOP

WaitOnPrompt:
; Get the selection, either from the player or CPU.
JAL GetRandPromptSelection
NOP
GetSelection:
MOVE S1 V0 ; S1 now has the chosen option index

; Obligatory message box closing/cleanup calls.
JAL CloseMessage
NOP
JAL 0x80056168
NOP

; Change the outcome based on the choice.
BEQZ S1 UseItem ; If S1 = 0, use item
NOP
LI T0 1
BEQ S1 T0 UseCoins ; If S1 = 1, use coins
NOP
LI T0 2
BEQ S1 T0 BadExit2 ; If S1 = 2, exit
NOP
; else pick "View map"
JAL 0x80103A64 ; ViewBoardMap
NOP
J StartPrompt
NOP

;===Use Item===
UseItem:
LI T1 0xFF ; No item index
LBU T0 0x19(S0) ; Load item value from offset of player struct
BEQL T0 S4 PassBlockade ; If player has item, pass blockade
SB T1 0x19(S0) ; Store no item index into main slot

LBU T0 0x1E(S0) ; Load reserve item #1 from offset of player struct
BEQL T0 S4 PassBlockade ; If player has item, pass blockade
SB T1 0x1E(S0) ; Store no item index into reserve slot #1

J PassBlockade
SB T1 0x1F(S0) ; Store no item index into reserve slot #2

;===Use Coins===
UseCoins:
LBU A0 0x1C(S0) ; Pass current player index on A0
JAL AdjustPlayerCoinsGradual
SUBU A1 R0 S3 ; Lose coins

LBU A0 0x1C(S0) ; Pass current player index on A0
JAL ShowPlayerCoinChange
SUBU A1 R0 S3 ; Lose coins

;===Pass Blockade===
PassBlockade:
JAL SleepProcess
LI A0 30 ; Wait 30 frames for coin change/item disappearing

LI A0 0 ; Display message
LUI A1 hi(YesMessage)
ADDIU A1 A1 lo(YesMessage) ; Display YesMessage
JAL CallMessage
LI A2 0 ; No string

LI A0 1 ; Assigns circle fade-out
JAL InitFadeOut ; Fade to black
LI A1 16 ; Assigns 16 frames of fade-out

JAL SleepProcess
LI A0 17 ; Wait 17 frames for fade-out

;===Warp Player===
LI A0 -1 ; Set current player
LI A1 SecretPath_chain_index ; Pass chain index on A1
JAL SetPlayerOntoChain
LI A2 SecretPath_chain_space_index ; Pass chain space index on A2

LI A0 -1 ; Set current player
LI A1 SecretNext_chain_index ; Pass chain index on A1
JAL SetNextChainAndSpace
LI A2 SecretNext_chain_space_index ; Pass chain space index on A2

;===Set Player Coords===
JAL GetSpaceData
LI A0 SecretPath ; Get SecretPath space data at V0
LW T0 8(V0) ; Load space x coords into T0
LW T1 16(V0) ; Load space y coords into T1

LW T2 0x24(S0) ; Load coords pointer from offset of player struct
SW T0 12(T2) ; Store space x coords into player coords
SW T1 20(T2) ; Store space y coords into player coords

;===Finish Warp===
LI A0 1 ; Assigns circle fade-in
JAL InitFadeIn ; Fade from black
LI A1 16 ; Assigns 16 frames of fade-in

JAL SleepProcess
LI A0 17 ; Wait 17 frames for fade-in

J exit
NOP

;===Bad Exits===
BadExit:
LUI A1 hi(BadMessage)
J CommonExit
ADDIU A1 A1 lo(BadMessage) ; Display BadMessage

BadExit2:
LUI A1 hi(NoMessage)
ADDIU A1 A1 lo(NoMessage) ; Display NoMessage

CommonExit:
LI A0 0 ; Dispay message
; Pass message address on A1
JAL CallMessage
LI A2 0 ; No string

LI A0 -1 ; Set current player
LI A1 NormalPath_chain_index ; Pass chain index on A1
JAL SetNextChainAndSpace
LI A2 NormalPath_chain_space_index ; Pass chain space index on A2

exit:
JAL 0x8004655C ; ShowDiceRoll
LBU A0 0x1C(S0) ; Pass current player index on A0

JAL SleepProcess
LI A0 10 ; Wait 10 frames for dice roll to show

epilogue:
LW RA 52(SP)
LW S0 48(SP)
LW S1 44(SP)
LW S2 40(SP)
LW S3 36(SP)
LW S4 32(SP)
JR RA
ADDIU SP SP 56

;===Font Colour Pointers===
.align 4
BlackColour:
.byte 0x01,0

.align 4
BlueColour:
.byte 0x06,0

.align 4
YellowColour:
.byte 0x07,0

.align 4
WhiteColour:
.byte 0x08,0

;===Logic Array===
.align 4
LogicArray:
.fill 4

;===Prep for Displaying Coin String===
.align 16
percent_d:
.asciiz "%d" ; 0x25640000

.align 16
CoinString:
.fill 8

;===Mini Func to Call Message===
.align 4
CallMessage:
ADDIU SP SP -40
SW RA 36(SP)
SW S0 32(SP)

; A0 / S0 = Message or Prompt
; A1 = Message Address
; A2 = String #1

MOVE S0 A0 ; Copy A0 to S0
SW R0 16(SP) ; A4
SW R0 20(SP) ; A5
SW R0 24(SP) ; A6
LI A0 0x17 ; Character image (-1 for none, 0x17 for Sushi)
; Visit the following link to get the full list of Character Images
; https://github.com/PartyPlanner64/PartyPlanner64/wiki/Displaying-Messages
; If you use a character image, check the bottom of the code
; Pass message address on A1
; Pass string #1 on A2
JAL ShowMessage
LI A3 0

BNEZ S0 CallMessageExit ; If displaying a prompt, exit
NOP

; Obligatory message box closing/cleanup calls.
JAL CloseMessage
NOP
JAL 0x80056168
NOP

CallMessageExit:
LW RA 36(SP)
LW S0 32(SP)
JR RA
ADDIU SP SP 40

;===Mini Func to Disable Prompt Options===
.align 4
DisablePromptOptions:
ADDIU SP SP -40
SW RA 36(SP)
SW S0 32(SP)
SW S1 28(SP)

; A0 / S0 = Logic Array
; S1 = Option Counter

MOVE S0 A0 ; Copy A0 to S0
LI S1 0 ; Start with 0th option
DisablePromptOptionsLoop:
LBU T0 0(S0) ; Load option logic into T0
BNEZ T0 SkipDisable ; If T0 = 1, skip disable
LI A0 2 ; Window ID
JAL 0x8008D854 ; DisablePromptOption
MOVE A1 S1 ; Disable nth option
SkipDisable:
BNEZ S1 DisablePromptOptionsExit ; If both options checked, exit
NOP
ADDIU S0 S0 1 ; Add 1 to get next option logic
J DisablePromptOptionsLoop
ADDIU S1 S1 1 ; Add 1 to check next option

DisablePromptOptionsExit:
LW RA 36(SP)
LW S0 32(SP)
LW S1 28(SP)
JR RA
ADDIU SP SP 40

;===Mini Func to Determine AI Logic===
.align 4
AILogic:
ADDIU SP SP -32
SW RA 28(SP)

; A0 = Logic Array
; V0 = AI Choice

LBU T0 0(A0) ; Check if player has item
BNEZL T0 AILogicExit ; If player has item, exit
LI V0 0 ; Select item (on likely)
; else, player doesn't have item

JAL 0x8005694C ; RNGPercentChance
LI A0 50 ; 50% chance of V0 = 1
ADDIU V0 V0 1 ; 50% chance to select coins/exit

AILogicExit:
LW RA 28(SP)
JR RA
ADDIU SP SP 32

;===Message Text===
.align 16
Prompt:
.byte 0x1A,0x1A,0x1A,0x1A ; Padding for character image
.ascii "Psst"
.byte 0x82 ; Comma (,)
.ascii " hey buddy"
.byte 0xC2 ; Exclamation mark (!)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "If you"
.byte 0x5C ; Apostrophe (')
.ascii "ve got the goods"
.byte 0x82 ; Comma (,)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "I just might let you pass"
.byte 0x85 ; Period (.)
.byte 0x0A ; New line (writes below)
.byte 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A ; Character image + option indent
.byte 0x0C ; Start option
.ascii "%s" ; Font colour
.ascii "Give a"
.ascii "%s" ; Item font colour
.ascii "%s" ; Item string
.byte 0x85 ; Period (.)
.byte 0x0D ; End option
.byte 0x0A ; New line (writes below)
.byte 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A ; Character image + option indent
.byte 0x0C ; Start option
.ascii "%s" ; Font colour
.ascii "Give "
.ascii "%s" ; Coins font colour
.byte 0x11 ; String #1 stored in A2 (CoinString)
.ascii " coins"
.byte 0x85 ; Period (.)
.byte 0x0D ; End option
.byte 0x0A ; New line (writes below)
.byte 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A ; Character image + option indent
.byte 0x0C,0x08 ; Start option, White font
.ascii "No thanks"
.byte 0x85 ; Period (.)
.byte 0x0D ; End option
.byte 0x0A ; New line (writes below)
.byte 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A ; Character image + option indent
.byte 0x0C ; Start option
.ascii "View map"
.byte 0x0D ; End option
.byte 0 ; End prompt

.align 16
YesMessage:
.byte 0x1A,0x1A,0x1A,0x1A ; Padding for character image
.ascii "All right"
.byte 0x82 ; Comma (,)
.ascii " it"
.byte 0x5C ; Apostrophe (')
.ascii "s all here"
.byte 0x85 ; Period (.)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "Come on in"
.byte 0x82 ; Comma (,)
.ascii " pal"
.byte 0x82 ; Comma (,)
.ascii " but watch yourself"
.byte 0x85 ; Period (.)
.byte 0xFF,0 ; Wait, press A to confirm

.align 16
NoMessage:
.byte 0x1A,0x1A,0x1A,0x1A ; Padding for character image
.ascii "Suit yourself"
.byte 0x82 ; Comma (,)
.ascii " mate"
.byte 0x85 ; Period (.)
.ascii " But don"
.byte 0x5C ; Apostrophe (')
.ascii "t even"
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "THINK about telling anyone "
.byte 0x5C ; Apostrophe (')
.ascii "bout this place"
.byte 0xC2 ; Exclamation mark (!)
.byte 0xFF,0 ; Wait, press A to confirm

.align 16
BadMessage:
.byte 0x1A,0x1A,0x1A,0x1A ; Padding for character image
.ascii "Hey you"
.byte 0xC2 ; Exclamation mark (!)
.ascii " Yeah"
.byte 0x82 ; Comma (,)
.ascii " you"
.byte 0xC2 ; Exclamation mark(!)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.byte 0x03 ; Red font
.ascii "NO TRESPASSERS ALLOWED"
.byte 0xC2,0xC2 ; Two exclamation marks (!!)
.byte 0xFF,0 ; Wait, press A to confirm

; Here's a list of the most common bytes you'll need
; .byte 0x01 ; Black Font
; .byte 0x03 ; Red Font
; .byte 0x04 ; Purple Font
; .byte 0x05 ; Green Font
; .byte 0x06 ; Blue font
; .byte 0x07 ; Yellow Font
; .byte 0x08 ; White Font
; .byte 0x85 ; Period (.)
; .byte 0xC2 ; Exclamation Mark (!)
; .byte 0xC3 ; Question Mark (?)
; .byte 0x82 ; Comma (,)
; .byte 0x0A ; New line (writes below)
; .byte 0x5C ; Apostrophe (')
; .byte 0x29 ; Coin icon
; .byte 0x3D ; - (minus)
; .byte 0x3E ; x (multiply)
; .byte 0xFF,0 ; FF=Pause

; If your message has an image, use this at the start of each line
; .byte 0x1A,0x1A,0x1A,0x1A ; Padding for character image

;===Prompt Placeholder===
.align 16
PromptHolder:
.fill 0x1024,0

;===Item Strings===
.align 32
ItemStrings:
.asciiz " Mushroom" ; 0x00
.align 32
.asciiz " Skeleton Key" ; 0x01
.align 32
.asciiz " Plunder Chest" ; 0x02
.align 32
.asciiz " Bowser Bomb" ; 0x03
.align 32
.asciiz " Dueling Glove" ; 0x04
.align 32
.asciiz " Warp Block" ; 0x05
.align 32
.asciiz " Golden Mushroom" ; 0x06
.align 32
.asciiz " Boo Bell" ; 0x07
.align 32
.asciiz " Bowser Suit" ; 0x08
.align 32
.asciiz " Magic Lamp" ; 0x09