; NAME: Pay to Warp (MP3)
; GAMES: MP3_USA
; EXECUTION: Direct
; PARAM: Space|SpaceToFace
; PARAM: +Number|Price
; PARAM: Space[]|Destinations
; PARAM: Space[]|Dest1Forward
; PARAM: Space[]|Dest1Behind
; PARAM: Space[]|Dest2Behind

ADDIU SP SP -64
SW RA 60(SP)
SW S0 56(SP)
SW S1 52(SP)
SW S2 48(SP)
SW S3 44(SP)

; S0 = Current Player Struct
; S1 = Prompt Choice / Reverse Flag
; S2 = Price / Destination Array
; S3 = Randomised Destination

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

JAL 0x800DBEC0 ; HideDiceRoll
LBU A0 0x1D(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 RotatePlayerModel
LI A2 SpaceToFace ; Face space

;===Check for Coins===
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
LI A2 Price ; Convert price to text string

LBU A0 0x1D(S0) ; Pass current player index on A0
JAL PlayerHasCoins
LI A1 Price ; Check for coins

BEQZ V0 NoCoins ; If V0 = 0, go to NoCoins
LI S2 Price ; Load Price into S3

;===Start Prompt===
JAL PlaySound
LI A0 0x195 ; Blooper voice

StartPrompt:
LI A0 1 ; Display prompt
LUI A1 hi(WarpPrompt)
ADDIU A1 A1 lo(WarpPrompt) ; Display WarpPrompt
LUI A2 hi(CoinString)
JAL CallMessage
ADDIU A2 A2 lo(CoinString) ; String #1 (Price)

JAL RNGPercentChance
LI A0 50 ; 50% chance of V0 = 1

; Get the selection, either from the player or CPU.
; If A0 is a pointer to AI data, AI logic is ran to pick for CPUs.
; If A0 is 0 or 1, the 0th or 1st option is chosen by CPUs.
; If A0 is 2, then the value of A1 is the CPUs option index choice.
LI A0 2 ; Pick whatever is in A1 as AI's Choice
JAL GetBasicPromptSelection
MOVE A1 V0 ; A1 now has the AI's decision
MOVE S1 V0 ; S1 now has the chosen option index

; Obligatory message box closing/cleanup calls.
JAL CloseMessage
NOP
JAL 0x800EC6EC
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 ViewBoardMap
NOP
J StartPrompt
NOP

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

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

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

;===Say Yes Message===
SkipLoseCoins:
JAL PlaySound
LI A0 0x195 ; Blooper voice

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 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

JAL PlaySound
LI A0 0x107 ; 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 S3 ; Move the remainder into S3

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

;===Set Destination===
LUI T0 hi(DestChArray)
ADDIU T0 T0 lo(DestChArray) ; Load DestinationChainArray into T0
ADDU T0 T0 S3 ; Add to get randomised destination chain
LUI T1 hi(DestChSpArray)
ADDIU T1 T1 lo(DestChSpArray) ; Load DestinationChainSpaceArray into T1
ADDU T1 T1 S3 ; Add to get randomised destination chain space

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

;===Check Reverse Status for Next===
LBU T0 0x17(S0) ; Load status flags from offset of player struct
ANDI S1 T0 1 ; AND with 1 (going backwards)
BNEZ S1 SetReverseNext ; If S1 = 1, set reverse next
NOP
; else, set forward next

;===Set Forward Next===
LUI T0 hi(Dest1FChArray)
ADDIU T0 T0 lo(Dest1FChArray) ; Load Dest1ForwardChainArray into T0
ADDU T0 T0 S3 ; Add to get randomised destination 1 forward chain
LUI T1 hi(Dest1FChSpArray)
ADDIU T1 T1 lo(Dest1FChSpArray) ; Load Dest1ForwardChainSpaceArray into T1
J SetNext
ADDU T1 T1 S3 ; Add to get randomised destination 1 forward chain space

;===Set Reverse Next===
SetReverseNext:
LUI T0 hi(Dest1BChArray)
ADDIU T0 T0 lo(Dest1BChArray) ; Load Dest1BehindChainArray into T0
ADDU T0 T0 S3 ; Add to get randomised destination 1 behind chain
LUI T1 hi(Dest1BChSpArray)
ADDIU T1 T1 lo(Dest1BChSpArray) ; Load Dest1BehindChainSpaceArray into T1
ADDU T1 T1 S3 ; Add to get randomised destination 1 behind chain space

;===Set Next===
SetNext:
LI A0 -1 ; Set current player
LBU A1 0(T0) ; Pass next chain index on A1
JAL SetNextChainAndSpace
LBU A2 0(T1) ; Pass next chain space index on A2

BNEZ S1 SetReversePrev ; If S1 = 1, set reverse prev
NOP
; else, set forward prev

;===Set Forward Prev===
LUI T0 hi(Dest1BChArray)
ADDIU T0 T0 lo(Dest1BChArray) ; Load Dest1BehindChainArray into T0
ADDU T0 T0 S3 ; Add to get randomised destination 1 behind chain
LUI T1 hi(Dest1BChSpArray)
ADDIU T1 T1 lo(Dest1BChSpArray) ; Load Dest1BehindChainSpaceArray into T1
J SetPrev
ADDU T1 T1 S3 ; Add to get randomised destination 1 behind chain space

;===Set Reverse Prev===
SetReversePrev:
LUI T0 hi(Dest2BChArray)
ADDIU T0 T0 lo(Dest2BChArray) ; Load Dest2BehindChainArray into T0
ADDU T0 T0 S3 ; Add to get randomised destination 2 behind chain
LUI T1 hi(Dest2BChSpArray)
ADDIU T1 T1 lo(Dest2BChSpArray) ; Load Dest2BehindChainSpaceArray into T1
ADDU T1 T1 S3 ; Add to get randomised destination 2 behind chain space

;===Set Prev===
SetPrev:
LI A0 -1 ; Set current player
LBU A1 0(T0) ; Pass prev chain index on A1
JAL SetPrevChainAndSpace
LBU A2 0(T1) ; Pass prev chain space index on A2

;===Set Player Coords===
JAL GetSpaceData
LBU A0 0(S2) ; 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 RotatePlayerModel
LBU A2 0(S2) ; Face Destination space

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

;===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 Outro
NOP

;===Say No===
SayNo:
JAL PlaySound
LI A0 0x195 ; Blooper voice

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

J Outro
NOP

;===No Coins Message===
NoCoins:
JAL PlaySound
LI A0 0x195 ; Blooper voice

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) ; String #1 (Price)

;===Show Dice Roll===
Outro:
JAL 0x800DB884 ; ShowDiceRoll
LBU A0 0x1D(S0) ; Pass current player index on A0

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

exit:
LW RA 60(SP)
LW S0 56(SP)
LW S1 52(SP)
LW S2 48(SP)
LW S3 44(SP)
JR RA
ADDIU SP SP 64

;===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 0x3A ; Character image (-1 for none, 0x3A for Blooper)
; 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 0x800EC9DC
NOP
JAL CloseMessage
NOP
JAL 0x800EC6EC
NOP

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

;===Destination Arrays===
.align 8
DestinationArray:
.byte Destinations ; Destination space indexes

.align 8
DestChArray:
.byte Destinations_chain_indices ; Destination chain indexes

.align 8
DestChSpArray:
.byte Destinations_chain_space_indices ; Destination chain space indexes

.align 8
Dest1FChArray:
.byte Dest1Forward_chain_indices ; Destination 1 forward chain indexes

.align 8
Dest1FChSpArray:
.byte Dest1Forward_chain_space_indices ; Destination 1 forward chain space indexes

.align 8
Dest1BChArray:
.byte Dest1Behind_chain_indices ; Destination 1 behind chain indexes

.align 8
Dest1BChSpArray:
.byte Dest1Behind_chain_space_indices ; Destination 1 behind chain space indexes

.align 8
Dest2BChArray:
.byte Dest2Behind_chain_indices ; Destination 2 behind chain indexes

.align 8
Dest2BChSpArray:
.byte Dest2Behind_chain_space_indices ; Destination 2 behind chain space indexes

;===Message Text===
.align 16
WarpPrompt:
.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 " sign me up"
.byte 0xC2 ; Exclamation mark (!)
.byte 0x1A,0x1A ; Tab x2
.byte 0x29,0x3E ; Coin icon, Multiply (x)
.ascii " "
.byte 0x11 ; String #1 stored in A2 (Price)
.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 you"
.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 " HERE WE GO"
.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 "There you are"
.byte 0xC2 ; Exclamation mark (!)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "You"
.byte 0x5C ; Apostrophe (')
.ascii "ve been"
.byte 0x04 ; Purple font
.ascii " warped"
.byte 0x08,0x85 ; White font, Period (.)
.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 on A2 (Price)
.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 ; 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