; NAME: Visit Koopa (MP3) v2.1
; GAMES: MP3_USA
; EXECUTION: Direct
; PARAM: Space|KoopaSpace
; PARAM: Boolean|KoopaKard
; PARAM: Number|KoopaKardCoins

; This code is designed to mimic the "Visit Koopa" event from MP1.
; Koopa gives 10 coins upon passing/landing, or 20 coins during the
; Last 5 Turns. Use in conjunction with the "Model View Koopa" event
; to actively load the Koopa model on the board! The parameter
; "KoopaSpace" is the space the player will face during the event,
; which should also be where Koopa is standing.

; Set the parameter "KoopaKard" to "true" if you want Koopa to check
; for a Koopa Kard in the player's inventory and exchange any for
; coins. The number of coins is decided by the parameter
; "KoopaKardCoins".

ADDIU SP SP -40
SW RA 36(SP)
SW S0 32(SP)
SW S1 28(SP)

; S0 = Current Player Struct
; S1 = Coins to Gain

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

;===Check Turn Count===
LUI T0 hi(total_turns)
ADDIU T0 T0 lo(total_turns)
LBU T1 0(T0) ; Load total turns into T1
LBU T0 1(T0) ; Load current turn into T0

SUBU T2 T1 T0 ; Subtract current turn from total turns
SLTI T3 T2 5 ; If T2 < 5, in the last 5 turns, T3 = 1
BNEZ T3 LastTurns ; If T3 = 1, go to LastTurns
NOP

;===Koopa Message===
LI A0 0 ; No string
LUI A1 hi(KoopaMessage)
JAL CallMessage
ADDIU A1 A1 lo(KoopaMessage) ; Display KoopaMessage

J GetCoins
LI S1 10 ; Get 10 coins

;===Last 5 Turns Message===
LastTurns:
LI A0 0 ; No string
LUI A1 hi(LastTurnsMessage)
JAL CallMessage
ADDIU A1 A1 lo(LastTurnsMessage) ; Display LastTurnsMessage

LI S1 20 ; Get 20 coins

;===Get Coins===
GetCoins:
LBU A0 0x1D(S0) ; Load player index from offset of player struct
JAL AdjustPlayerCoinsGradual
MOVE A1 S1 ; Gain coins

LBU A0 0x1D(S0) ; Load player index from offset of player struct
JAL ShowPlayerCoinChange
MOVE A1 S1 ; Gain coins

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

JAL HappyVoice
MOVE A0 S0 ; Pass current player struct on A0

;===Check for Koopa Kards===
LI T0 KoopaKard
BEQZ T0 exit ; If KoopaKard is OFF, exit
NOP
; else, check for Koopa Kards

LI S1 0 ; Reset bonus to 0
KoopaKardLoop:
LBU A0 0x1D(S0) ; Load player index from offset of player struct
JAL PlayerHasItem
LI A1 0x0F ; Check for Koopa Kard

BLTZ V0 CheckKards ; If no Koopa Kard, check Koopa Kards
NOP
ADDU T0 S0 V0 ; Add item slot offset to player struct
LI T1 0xFF ; No item index
SB T1 0x18(T0) ; Store no item into item slot offset of player struct
J KoopaKardLoop
ADDIU S1 S1 KoopaKardCoins ; Add coins bonus per Koopa Kard

CheckKards:
BEQZ S1 exit ; If no Koopa Kards found, exit
NOP
; else, player has 1 or more Koopa Kards

;===Prepare Koopa Kard Message===
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 S1 ; Convert coins to text string

;===Koopa Kard Message===
LUI A0 hi(CoinString)
ADDIU A0 A0 lo(CoinString) ; String #1 (Coins to Gain)
LUI A1 hi(KoopaKardMessage)
JAL CallMessage
ADDIU A1 A1 lo(KoopaKardMessage) ; Display KoopaKardMessage

;===Remove Koopa Kards from HUD===
JAL FixUpPlayerItemSlots
LBU A0 0x1D(S0) ; Load player index from offset of player struct
JAL FixUpPlayerItemSlots
LBU A0 0x1D(S0) ; Load player index from offset of player struct
JAL RefreshHUD
LBU A0 0x1D(S0) ; Load player index from offset of player struct

J GetCoins ; Get coins
NOP

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

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

;===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)
SW S1 28(SP)

; A0 / S0 = String #1
; A1 / S1 = Message Address

MOVE S0 A0 ; Copy A0 to S0
MOVE S1 A1 ; Copy A1 to S1

JAL PlaySound
LI A0 0x259 ; Koopa voice

SW R0 16(SP) ; A4
SW R0 20(SP) ; A5
SW R0 24(SP) ; A6
LI A0 0x2 ; Character image (-1 for none, 0x2 for Koopa)
; 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
MOVE A1 S1 ; Pass message address on A1
MOVE A2 S0 ; Pass String #1 on A2
JAL ShowMessage
LI A3 0

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

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

;===Mini Func to Play Happy Voice and Animation===
.align 4
HappyVoice:
ADDIU SP SP -32
SW RA 28(SP)

; A0 = Current Player Struct

LBU A0 3(A0) ; Load character value from offset of player struct
JAL PlaySound
ADDIU A0 A0 0x2BE ; 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.
; 0x2BE = Happy Voice, 0x287 = Sad Voice

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

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

;===Message Text===
.align 16
KoopaMessage:
.byte 0x1A,0x1A,0x1A,0x1A ; Padding for character image
.ascii "Nice work"
.byte 0xC2 ; Exclamation mark (!)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "Take this"
.byte 0x06 ; Blue font
.ascii " 10 Coin"
.byte 0x08 ; White font
.ascii " Bonus"
.byte 0xC2 ; Exclamation mark (!)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "Use it wisely"
.byte 0x85 ; Period (.)
.byte 0xFF,0 ; Wait, press A to confirm

.align 16
LastTurnsMessage:
.byte 0x1A,0x1A,0x1A,0x1A ; Padding for character image
.ascii "Nice work"
.byte 0xC2 ; Exclamation mark (!)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "Take this"
.byte 0x06 ; Blue font
.ascii " 20 Coin"
.byte 0x08 ; White font
.ascii " Bonus"
.byte 0xC2 ; Exclamation mark (!)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "Just a little bit longer"
.byte 0x85,0x85,0x85 ; Three periods (...)
.byte 0xFF,0 ; Wait, press A to confirm

.align 16
KoopaKardMessage:
.byte 0x1A,0x1A,0x1A,0x1A ; Padding for character image
.ascii "Do I spy a shiny"
.byte 0x07 ; Yellow font
.ascii " Koopa Kard"
.byte 0x08,0xC3 ; White font, Question mark (?)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "Let me take that off your hands"
.byte 0xC2 ; Exclamation mark (!)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "Of course"
.byte 0x82 ; Comma (,)
.ascii " you"
.byte 0x5C ; Apostrophe (')
.ascii "ll be compensated"
.byte 0x85 ; Period (.)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "Take this "
.byte 0x06,0x11 ; Blue font, String #1 stored on A2 (CoinString)
.ascii " Coin"
.byte 0x08 ; White font
.ascii " Bonus"
.byte 0xC2 ; Exclamation 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

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