; NAME: Pay to Warp (MP2) v1.1
; GAMES: MP2_USA
; EXECUTION: Direct
; PARAM: Number|Price
; PARAM: Space|SpaceToFace
; PARAM: Space[]|Destinations
; PARAM: Space[]|DestNext

; This event is designed to warp the player to another space by paying
; a number of coins, decided by the parameter "Price". If the player
; doesn't have enough coins, they will be denied. If the player has
; enough coins, they will be given a yes/no prompt to warp. During
; the event, the player will face the space designated by the
; parameter "SpaceToFace".

; This event supports any number of destinations. The parameter
; "Destinations" should be set to each of the target spaces, while the
; parameter "DestNext" should be the next space the player will walk
; toward once they've warped. Ensure that the order of spaces set for
; both of these parameter arrays is the same.

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

; S0 = Current Player Struct
; S1 = Prompt Choice
; S2 = Price / Randomised Destination
; S3 = Destination Arrays

;===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, 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 Toward Space===
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

;===Prepare Coin String===
LI S2 Price ; Load price into S2
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 S2 ; Convert price to text string

;===Check for Coins===
LBU A0 0x1C(S0) ; Pass current player index on A0
JAL PlayerHasCoins
MOVE A1 S2 ; Check for price

BEQZ V0 NoCoins ; If V0 = 0, go to NoCoins
NOP

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

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

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

; Change the player's destination based on the choice.
BEQZ S1 SayYes ; If V0 = 0, say yes
NOP
LI T0 1
BEQ S1 T0 SayNo ; If V0 = 1, say no
NOP
; else pick "View map"
JAL 0x80103A64 ; ViewBoardMap
NOP
J StartPrompt
NOP

;===Say Yes===
SayYes:
LBU A0 0x1C(S0) ; Pass current player index on A0
JAL AdjustPlayerCoinsGradual
SUBU A1 R0 S2 ; Pay price

LBU A0 0x1C(S0) ; Pass current player index on A0
JAL ShowPlayerCoinChange
SUBU A1 R0 S2 ; Pay price

JAL SleepProcess
LI A0 30 ; Wait 30 frames for coin change

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

;===Fade-out and Sound===
LI A0 6 ; Assigns square 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

JAL PlaySound
LI A0 0x32E ; Warp Block sound

JAL SleepProcess
LI A0 20 ; Wait 20 frames for sound

;===Determine Destination===
JAL GetRandomByte ; Get random byte (0-255) at V0
NOP
LI T0 Destinations_length ; Load no. of destinations into T0
DIVU V0 T0 ; Divide V0 by T0
MFHI S2 ; Move the remainder (T0 - 1) into S2
SLL S2 S2 1 ; Shift left by 1 (multiply by 2)

LUI S3 hi(DestinationArray)
ADDIU S3 S3 lo(DestinationArray)
ADDU S3 S3 S2 ; Add random number to DestinationArray

;===Set Destination===
LUI T1 hi(DestChainArray)
ADDIU T1 T1 lo(DestChainArray)
ADDU T1 T1 S2 ; Add random number to DestChainArray

LUI T2 hi(DestChainSpaceArray)
ADDIU T2 T2 lo(DestChainSpaceArray)
ADDU T2 T2 S2 ; Add random number to DestChainSpaceArray

LI A0 -1 ; Set current player
LHU A1 0(T1) ; Pass Destination chain index on A1
JAL SetPlayerOntoChain
LHU A2 0(T2) ; Pass Destinationchain space index on A2

;===Set Dest Next===
LUI T1 hi(DestNextChainArray)
ADDIU T1 T1 lo(DestNextChainArray)
ADDU T1 T1 S2 ; Add random number to DestNextChainArray

LUI T2 hi(DestNextChainSpaceArray)
ADDIU T2 T2 lo(DestNextChainSpaceArray)
ADDU T2 T2 S2 ; Add random number to DestNextChainSpaceArray

LI A0 -1 ; Set current player
LHU A1 0(T1) ; Pass Destination next chain index on A1
JAL SetNextChainAndSpace
LHU A2 0(T2) ; Pass Destination next chain space index on A2

;===Set Player Coords===
JAL GetSpaceData
LHU A0 0(S3) ; Get Destination 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 ; Set current player
LI A1 1 ; Rotate in 1 frame
JAL RotateCharacterModel
LHU A2 0(S3) ; Face Destination space

LI A0 6 ; Assigns square 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

;===Message and Turn Flag ON===
LI A0 0 ; Display message
LUI A1 hi(WarpedMessage)
ADDIU A1 A1 lo(WarpedMessage) ; Display WarpedMessage
JAL CallMessage
LI A2 0 ; No string

J exit
NOP

;===Say No===
SayNo:
LI A0 0 ; Display message
LUI A1 hi(NoMessage)
ADDIU A1 A1 lo(NoMessage) ; Display NoMessage
JAL CallMessage
LI A2 0 ; No string

J exit
NOP

;===No Coins Message===
NoCoins:
LI A0 0 ; Display message
LUI A1 hi(NoCoinsMessage)
ADDIU A1 A1 lo(NoCoinsMessage) ; Display NoCoinsMessage
LUI A2 hi(CoinString)
JAL CallMessage
ADDIU A2 A2 lo(CoinString) ; Pass CoinString on A2

;===Show Dice Roll===
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 44(SP)
LW S0 40(SP)
LW S1 36(SP)
LW S2 32(SP)
LW S3 28(SP)
JR RA
ADDIU SP SP 48

;===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 0x15 ; Character image (-1 for none, 0x15 for Picker)
; 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

;===Destination Arrays===
.align 16
DestinationArray:
.halfword Destinations ; Destination space indexes

.align 16
DestChainArray:
.halfword Destinations_chain_indices ; Destination chain indexes

.align 16
DestChainSpaceArray:
.halfword Destinations_chain_space_indices ; Destination chain space indexes

.align 16
DestNextChainArray:
.halfword DestNext_chain_indices ; Destination next chain indexes

.align 16
DestNextChainSpaceArray:
.halfword DestNext_chain_space_indices ; Destination next chain space indexes

;===Message Text===
.align 16
MainPrompt:
.byte 0x1A,0x1A,0x1A,0x1A ; Padding for character image
.ascii "If you want to fast travel"
.byte 0x82 ; Comma (,)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "you"
.byte 0x5C ; Apostrophe (')
.ascii "ve come to the right place"
.byte 0xC2 ; Exclamation mark (!)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "I can"
.byte 0x04 ; Purple font
.ascii " warp"
.byte 0x08 ; White font
.ascii " you to another"
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "space"
.byte 0xC2 ; Exclamation mark (!)
.ascii " Want to try"
.byte 0xC3 ; Question mark (?)
.byte 0x0A ; New line (writes below)
.byte 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A ; Character image + option indent
.byte 0x0C ; Start option
.ascii "Sure"
.byte 0x82 ; Comma (,)
.ascii " let"
.byte 0x5C ; Apostrophe (')
.ascii "s go"
.byte 0xC2 ; Exclamation mark (!)
.byte 0x1A,0x1A ; Tab x2
.byte 0x29,0x3E ; Coin icon, Multiply (x)
.byte 0x11 ; String #1 stored in A2 (CoinString)
.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 "No thanks"
.byte 0x82 ; Comma (,)
.ascii " maybe next time"
.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 "Where will we"
.byte 0x04 ; Purple font
.ascii " warp"
.byte 0x08,0xC3 ; White font, Question mark (?)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "Nobody knows"
.byte 0xC2 ; Exclamation mark (!)
.ascii " LET"
.byte 0x5C ; Apostrophe (')
.ascii "S GOO"
.byte 0xC2,0xC2 ; Two exclamation marks (!!)
.byte 0xFF,0 ; Wait, press A to confirm

.align 16
WarpedMessage:
.byte 0x1A,0x1A,0x1A,0x1A ; Padding for character image
.ascii "We"
.byte 0x5C ; Apostrophe (')
.ascii "ve arrived"
.byte 0xC2 ; Exclamation mark (!)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "See you next time"
.byte 0xC2 ; Exclamation mark (!)
.byte 0xFF,0 ; Wait, press A to confirm

.align 16
NoMessage:
.byte 0x1A,0x1A,0x1A,0x1A ; Padding for character image
.ascii "Well"
.byte 0x82 ; Comma (,)
.ascii " if you ever want to"
.byte 0x04 ; Purple font
.ascii " warp"
.byte 0x08,0x82 ; White font, Comma (,)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "you know where to go"
.byte 0xC2 ; Exclamation mark (!)
.byte 0xFF,0 ; Wait, press A to confirm

.align 16
NoCoinsMessage:
.byte 0x1A,0x1A,0x1A,0x1A ; Padding for character image
.ascii "If you don"
.byte 0x5C ; Apostrophe (')
.ascii "t have"
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.byte 0x03 ; Red font
.byte 0x11 ; String #1 stored in A2 (CoinString)
.ascii " coins"
.byte 0x08,0x82 ; White font, Comma (,)
.ascii " you can"
.byte 0x5C ; Apostrophe (')
.ascii "t"
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.byte 0x04 ; Purple font
.ascii "warp"
.byte 0x08 ; White font
.ascii " to another space"
.byte 0x85 ; Period (.)
.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 ; Multiply (x)
; .byte 0xFF,0 ; Wait, press A to confirm

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