; NAME: Wiggler's Veggie Hustle (MP2) v2
; GAMES: MP2_USA
; EXECUTION: Direct
; PARAM: Space|WigglerSpace
; PARAM: Space|VeggieSpace
; PARAM: Boolean|StartingPrompt

; This event is designed to activate a quick-time event where the
; player must rapidly press A or B to earn coins. The player will
; earn one coin for every two button presses. The button to press is
; selected at random. For CPUs, they will randomly earn a number of
; coins according to their difficulty level.

; At the beginning and end of the event, the player will face the
; space determined by the parameter "WigglerSpace". During the quick-
; time event, the player will face the space determined by the
; parameter "VeggieSpace". Set the parameter "StartingPrompt" to 1 if
; if you want the player to select yes or no to start the event. Set
; it to 0 if you want the event to be forced.

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)
SW S5 28(SP)

; S0 = Current Player Struct
; S1 = Prompt Choice / Window ID
; S2 = No. Presses / Coin Prize
; S3 = A or B to Press (0 or 1)
; S4 = Button Deactivator Flag
; S5 = Timer / CPU Sound Loop Counter

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

;===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 WigglerSpace===
LI A0 -1 ; Set current player
LI A1 8 ; Rotate in 8 frames
JAL RotateCharacterModel
LI A2 WigglerSpace ; Face WigglerSpace

JAL SleepProcess
LI A0 8 ; Rotate in 8 frames

;===Check StartingPrompt===
LI T0 StartingPrompt
BEQZ T0 StartGreeting ; If StartingPrompt = 0, start greeting
NOP
; else, ask the player

;===Greeting Prompt===
StartPrompt:
LI A0 1 ; Display prompt
LUI A1 hi(GreetingPrompt)
ADDIU A1 A1 lo(GreetingPrompt) ; Display GreetingPrompt
JAL CallMessage
LI A2 0 ; No string

; 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 S1 = 0, say yes
NOP
LI T0 1
BEQ S1 T0 SayNo ; If S1 = 1, say no
NOP
; else pick "View map
JAL 0x80103A64 ; ViewBoardMap
NOP
J StartPrompt
NOP

;===Greeting Message===
StartGreeting:
LI A0 0 ; Display message
LUI A1 hi(GreetingMessage)
ADDIU A1 A1 lo(GreetingMessage) ; Display GreetingMessage
JAL CallMessage
LI A2 0 ; No string

;===Rotate Toward VeggieSpace===
SayYes:
LI A0 -1 ; Set current player
LI A1 8 ; Rotate in 8 frames
JAL RotateCharacterModel
LI A2 VeggieSpace ; Face VeggieSpace

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

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

;===Fade Out===
LI A0 4 ; Happening 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

;===Randomize Starting Time===
JAL GetRandomByte ; Get random byte (0-255) at V0
NOP

JAL SleepProcess
SRL A0 V0 1 ; Divide V0 by 2 (wait that many frames)

;===Decide Button to Press and Format String===
JAL 0x8005694C ; RNGPercentChance
LI A0 50 ; 50% chance of V0 = 1
MOVE S3 V0 ; Copy V0 to S3

LUI A2 hi(ButtonPointer)
ADDIU A2 A2 lo(ButtonPointer) ; Load Button Pointer string into A2
SLL V0 V0 4 ; Shift left by 4 (multiply by 16)
ADDU A2 A2 V0 ; Add distance between Button Pointers
LUI A0 hi(ActionMessageHolder)
ADDIU A0 A0 lo(ActionMessageHolder) ; Parse destination
LUI A1 hi(ActionMessage)
ADDIU A1 A1 lo(ActionMessage) ; String formatter (%s)
JAL sprintf ; Converts string to text
LI A3 0 ; Terminator byte

;===Fade In===
LI A0 4 ; Happening 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

;===Display Action Message===
JAL PlaySound
LI A0 0x12 ; Train whistle

SW R0 16(SP) ; A4
SW R0 20(SP) ; A5
SW R0 24(SP) ; A6
LI A0 0x16 ; Character image (-1 for none, 0x16 for Wiggler)
; 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
LUI A1 hi(ActionMessageHolder)
ADDIU A1 A1 lo(ActionMessageHolder) ; Display ActionMessage with strings
LI A2 0
JAL ShowMessage
LI A3 0

MOVE S1 A0 ; Copy A0 to S1

;===Get Current Player Struct===
JAL GetPlayerStruct
LI A0 -1 ; Get current player struct at V0
MOVE S0 V0 ; Copy V0 to S0

;===Convert Button Presses to Points===
LI S2 0 ; Start at 0 points
LI S4 0 ; Start flag at 0
LI S5 0 ; Start timer at 0

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

BNEZ V0 CalculateHaul ; If player is CPU, calculate haul
NOP

ButtonLoop:
LBU A0 3(S0) ; Pass current player controller port on A0
JAL DetectABInput
MOVE A1 S3 ; Pass button flag on A1

BEQZ V0 NoPress ; If V0 = 0, no press registered
NOP

JAL PlaySound
LI A0 0x334 ; Pickup sound

BNEZ S4 CountPress ; If S4 = 1, count the button press
NOP

J NoPress
LI S4 1 ; Count the next press

CountPress:
ADDIU S2 S2 1 ; Add 1 point
LI S4 0 ; Don't count the next press

NoPress:
JAL SleepVProcess
NOP

ADDIU S5 S5 1 ; Add 1 to the timer
SLTI T0 S5 150 ; ON if timer hasn't run out
BEQZ T0 exitloop
NOP

J ButtonLoop
NOP

;===Calculate CPU's Presses Haul===
CalculateHaul:
JAL GetRandomByte ; Get random byte (0-255) at V0
NOP

LBU T0 1(S0) ; Load CPU difficulty from offset of player struct
SLL T1 T0 3 ; Shift left by 3 (multiply by 8)
SLL T2 T0 1 ; Shift left by 1 (multiply by 2)
ADDU T1 T1 T2 ; Add together (net multiply by 10)
ADDIU T1 T1 5 ; Add base 5 presses

LI T0 6
DIVU V0 T0 ; Divide V0 by T0
MFHI S2 ; Move the remainder into S2
ADDU S2 S2 T1 ; Add to base presses

SRL S5 S2 1 ; Divide presses by 2

CPUSoundLoop:
JAL PlaySound
LI A0 0x334 ; Pickup sound

JAL SleepProcess
LI A0 2 ; Wait 2 frames per sound

BEQZ S5 exitloop
NOP
J CPUSoundLoop
ADDIU S5 S5 -1

;===Exit Loop and Close Action Message===
exitloop:
MOVE A0 S1 ; Copy S1 to A0 (window ID)

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

;===Check Results===
JAL PlaySound
LI A0 0xE ; Whistle

JAL SleepProcess
LI A0 10 ; Wait 10 frames for sound

LI A0 -1 ; Set current player
LI A1 8 ; Rotate in 8 frames
JAL RotateCharacterModel
LI A2 WigglerSpace ; Face WigglerSpace

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

BEQZ S2 NoPrize ; If S2 = 0, go to NoPrize
NOP

;===Get Prize===
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 ; Converts a number to a text string
MOVE A2 S2 ; Convert coin prize to text string

LI A0 0 ; Display message
LUI A1 hi(PrizeMessage)
ADDIU A1 A1 lo(PrizeMessage) ; Display PrizeMessage
LUI A2 hi(CoinString)
JAL CallMessage
ADDIU A2 A2 lo(CoinString) ; Pass CoinString on A0

;===Coin Change===
LBU A0 0x1C(S0) ; Pass current player index on A0
JAL AdjustPlayerCoinsGradual
MOVE A1 S2 ; Pass coin prize on A1

LBU A0 0x1C(S0) ; Pass current player index on A0
JAL ShowPlayerCoinChange
MOVE A1 S2 ; Pass coin prize on A1

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

;===Happy Voice and Animation===
LBU A0 4(S0) ; Load character value from offset of player struct
JAL PlaySound
ADDIU A0 A0 0x103 ; Add character value to Mario's happy voice
; Character voices are their "character value" distance away from
; Mario's, e.g. Luigi's character value = 1, so Luigi's happy voice
; is 1 away from Mario's.
; 0x103 = Happy Voice, 0xFC = Sad Voice, 0x111 = Scream

LI A0 -1 ; Set current player
LI A1 5 ; Set joy animation
JAL SetBoardPlayerAnimation
LI A2 0 ; Do not loop animation

JAL SleepProcess
LI A0 40 ; Wait 40 frames for animation

J epilogue
NOP

;===No Prize===
NoPrize:
LI A0 0 ; Display message
LUI A1 hi(NoPrizeMessage)
ADDIU A1 A1 lo(NoPrizeMessage) ; Display NoPrizeMessage
JAL CallMessage
LI A2 0 ; No string

LBU A0 4(S0) ; Load character value from offset of player struct
JAL PlaySound
ADDIU A0 A0 0xFC ; Add character value to Mario's sad voice
; Character voices are their "character value" distance away from
; Mario's, e.g. Luigi's character value = 1, so Luigi's happy voice
; is 1 away from Mario's.
; 0x103 = Happy Voice, 0xFC = Sad Voice, 0x111 = Scream

LI A0 -1 ; Set current player
LI A1 3 ; Set lose animation
JAL SetBoardPlayerAnimation
LI A2 0 ; Do not loop animation

JAL SleepProcess
LI A0 80 ; Wait 80 frames for animation

J epilogue
NOP

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

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)
LW S5 28(SP)
JR RA
ADDIU SP SP 56

;===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 = 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 0x16 ; Character image (-1 for none, 0x16 for Wiggler)
; 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 Detect A/B Input===
.align 4
DetectABInput:
ADDIU SP SP -32
SW RA 28(SP)

; A0 = Current Player Controller Port
; A1 = A or B to Press (0 or 1)
; V0 = Press Detected (0 or 1)

LUI T0 0x800F ; 0x800F0000
ORI T0 T0 0x8F94 ; 0x800F8F94, Controller 1 Button Input Address
SLL A0 A0 3 ; Shift left by 3 (multiply by 8)
ADDU T0 T0 A0 ; Add to get current player's button input address
LBU T0 0(T0) ; Load player button input into T0

LI T1 0x80
SRLV T1 T1 A1 ; Shift right by 0 or 1 (0x80 for A, 0x40 for B)
BEQ T0 T1 DetectABInputexit
LI V0 1 ; Button press detected
; else, no button press detected
J DetectABInputexit
LI V0 0 ; No button press detected

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

;===Message Text===
.align 16
GreetingPrompt:
.byte 0x1A,0x1A,0x1A,0x1A ; Padding for character image
.ascii "Howdy"
.byte 0xC2 ; Exclamation mark (!)
.ascii " Ya look like a burly one"
.byte 0xC2 ; Exclamatioin mark (!)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "How"
.byte 0x5C ; Apostrophe (')
.ascii "s "
.byte 0x5C ; Apostrophe (')
.ascii "bout ya help me pick some"
.byte 0x05 ; Green font
.ascii " veggies"
.byte 0x08,0xC3 ; White font, Question mark (?)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "Ah"
.byte 0x5C ; Apostrophe (')
.ascii "m sure it"
.byte 0x5C ; Apostrophe (')
.ascii "s worth yer weight"
.byte 0xC2 ; Exclamation mark (!)
.byte 0x0A ; New line (writes below)
.byte 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A ; Character image + option indent
.byte 0x0C ; Start option
.ascii "Yes ma"
.byte 0x5C ; Apostrophe (')
.ascii "am"
.byte 0xC2 ; Exclamation mark (!)
.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 "Sorry"
.byte 0x82 ; Comma (,)
.ascii " ah must decline"
.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
GreetingMessage:
.byte 0x1A,0x1A,0x1A,0x1A ; Padding for character image
.ascii "Howdy"
.byte 0xC2 ; Exclamation mark (!)
.ascii " Ya look like a burly one"
.byte 0xC2 ; Exclamatioin mark (!)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "How"
.byte 0x5C ; Apostrophe (')
.ascii "s "
.byte 0x5C ; Apostrophe (')
.ascii "bout ya help me pick some"
.byte 0x05 ; Green font
.ascii " veggies"
.byte 0x08,0xC3 ; White font, Question mark (?)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "Ah"
.byte 0x5C ; Apostrophe (')
.ascii "m sure it"
.byte 0x5C ; Apostrophe (')
.ascii "s worth yer weight"
.byte 0xC2 ; Exclamation mark (!)
.byte 0xFF,0 ; Wait, press A to confirm

.align 16
StartingMessage:
.byte 0x1A,0x1A,0x1A,0x1A ; Padding for character image
.ascii "Awright"
.byte 0x82 ; Comma (,)
.ascii " when I say GO"
.byte 0x82 ; Comma (,)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.byte 0x03 ; Red font
.ascii "keep pressin"
.byte 0x5C,0x08 ; Apostrophe ('), White font
.ascii " that there button that I"
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "tell ya to press"
.byte 0xC2 ; Exclamation mark (!)
.ascii " Now get ready"
.byte 0x85,0x85,0x85 ; Three periods (...)
.ascii "and"
.byte 0x85,0x85,0x85 ; Three periods (...)
.byte 0xFF,0 ; Wait, press A to confirm

.align 16
ActionMessage:
.byte 0x1A,0x1A,0x1A,0x1A ; Padding for character image
.ascii "GO"
.byte 0xC2,0xC2 ; Two exclamation marks (!!)
.ascii " Keep pressin"
.byte 0x5C,0x10 ; Apostrophe ('), Space
.ascii "%s" ; A or B button
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "ta pull them veggies"
.byte 0xC2 ; Exclamation mark (!)
.byte 0 ; End message

.align 16
PrizeMessage:
.byte 0x1A,0x1A,0x1A,0x1A ; Padding for character image
.ascii "Well"
.byte 0x82 ; Comma (,)
.ascii " ain"
.byte 0x5C ; Apostrophe (')
.ascii "t that just the"
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "bee"
.byte 0x5C ; Apostrophe (')
.ascii "s knees"
.byte 0xC2 ; Exclamation mark (!)
.ascii " Ya did a darn"
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "tootin"
.byte 0x5C ; Apostrophe (')
.ascii " fine job"
.byte 0xC2 ; Exclamation mark (!)
.ascii " Ah"
.byte 0x5C ; Apostrophe (')
.ascii "m impressed"
.byte 0x85 ; Period (.)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "I hope these "
.byte 0x07,0x11 ; Yellow font, String #1 stored in A2 (CoinString)
.ascii " coins"
.byte 0x08,0x5C ; White font, Apostrophe (')
.ascii "ll do"
.byte 0xC2 ; Exclamation mark (!)
.byte 0xFF,0 ; Wait, press A to do

.align 16
NoPrizeMessage:
.byte 0x1A,0x1A,0x1A,0x1A ; Padding for character image
.ascii "Ah"
.byte 0x5C ; Apostrophe (')
.ascii "m sorry"
.byte 0x85,0x85,0x85 ; Three periods (...)
.ascii " Ya didn"
.byte 0x5C ; Apostrophe (')
.ascii "t pull up"
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "a"
.byte 0x03 ; Red font
.ascii " single veggie"
.byte 0x08,0x85 ; White font, Period (.)
.ascii " I shouldn"
.byte 0x5C ; Apostrophe (')
.ascii "ta"
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "over"
.byte 0x3D ; Dash (-)
.ascii "estimated ya"
.byte 0x85 ; Period (.)
.ascii " Eat more veggies"
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "before ya come back"
.byte 0x82 ; Comma (,)
.ascii " ya hear"
.byte 0xC3 ; Question mark (?)
.byte 0xFF,0 ; Wait, press A to confirm

.align 16
SayNoMessage:
.byte 0x1A,0x1A,0x1A,0x1A ; Padding for character image
.ascii "Aw"
.byte 0x82 ; Comma (,)
.ascii " fiddlesticks"
.byte 0xC2 ; Exclamation mark (!)
.ascii " Well"
.byte 0x82 ; Comma (,)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "come again"
.byte 0x82 ; Comma (,)
.ascii " ya hear"
.byte 0xC3 ; Question mark (?)
.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

;===Button Pointers===
.align 16
ButtonPointer:
.byte 0x21,0 ; A button

.align 16
.byte 0x22,0 ; B button

;===Action Message Placeholder===
.align 16
ActionMessageHolder:
.fill 0x1024,0