; NAME: Snifit Patrol (Arrays)
; GAMES: MP3_USA
; EXECUTION: Direct

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

; This code is designed to remove specific items from a player's
; inventory at the start of their turn and exchange them for coins.
; The items removed are determined by the Item Array and the coins
; received are determined by the corresponding value in the Price
; Array.

; When using this version of the event, be sure to directly edit the
; arrays to customize the event to your liking. They can be found
; near the bottom of the event, just before the Message Text.

; S0 = Current Player Struct
; S1 = Current Player Struct + Item Offset
; S2 = Coin Tally
; S3 = Item Array
; S4 = Price Array
; S5 = Item Slot Loop Counter
; S6 = Hit Flag (0 or 1)

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

;===Inventory Check===
JAL PlayerHasEmptyItemSlot
LBU A0 0x1D(S0) ; Load player index from offset of player struct
BEQZ V0 exit ; If player has no items, exit
NOP
; else, check for items

;===Get Arrays===
LUI S3 hi(ItemArray)
ADDIU S3 S3 lo(ItemArray) ; Load ItemArray into S3
LBU T3 0(S3) ; Load illegal item into T3

LUI S4 hi(PriceArray)
ADDIU S4 S4 lo(PriceArray) ; Load PriceArray into S4
LHU T4 0(S4) ; Load item price into T4

LI T0 0xFF ; No item index
LI S6 0 ; Start with no hits

;===Check Items===
RestartItemSlots:
MOVE S1 S0 ; Copy S0 to S1
LI S5 0 ; Start with item slot #1

CheckItems:
LBU T1 0x18(S1) ; Load item #1 from offset of player struct
BNE T1 T3 NextItemSlot ; If not illegal item, go to NextItemSlot
NOP
; else, remove illegal item from inventory and tally coins received

SB T0 0x18(S1) ; Store no item index into offset of player struct
ADDU S2 S2 T4 ; Add item price to coin tally
LI S6 1 ; There is at least one hit

NextItemSlot:
LI T5 2
BEQ S5 T5 CheckNextItem ; If all item slots checked, check next item
NOP
ADDIU S5 S5 1 ; Add 1 to item slot loop counter
J CheckItems
ADDIU S1 S1 1 ; Add 1 to check next item slot

CheckNextItem:
ADDIU S3 S3 1 ; Add 1 to get next illegal item
LBU T3 0(S3) ; Load illegal item into T3
LI T2 0x13 ; Terminator byte
BEQ T2 T3 CheckResults ; If finished checking ItemArray, check results
NOP
ADDIU S4 S4 2 ; Add 2 to get next price
J RestartItemSlots
LHU T4 0(S4) ; Load item price into T4

;===Check Results===
CheckResults:
BEQZ S6 exit ; If no hits, exit
NOP
; else, Snifit Patrol removed at least 1 item

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

;===Refresh Player Items 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

;===Check for Coins===
BEQZ S2 exit2 ; If no coins received, exit
NOP
; else, player receives coins

;===Prepare Coins 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 S2 ; Convert coins gained to text string

;===Coins Message===
LUI A0 hi(CoinString)
ADDIU A0 A0 lo(CoinString) ; String #1 (CoinString)
LUI A1 hi(CoinsMessage)
JAL CallMessage
ADDIU A1 A1 lo(CoinsMessage) ; Display CoinsMessage

;===Receive Coins===
LBU A0 0x1D(S0) ; Load player index from offset of player struct
JAL AdjustPlayerCoinsGradual
MOVE A1 S2 ; Gain coins

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

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

;===Play Happy Voice and Animation===
LBU A0 3(S0) ; 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

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

exit:
LW RA 60(SP)
LW S0 56(SP)
LW S1 52(SP)
LW S2 48(SP)
LW S3 44(SP)
LW S4 40(SP)
LW S5 36(SP)
LW S6 32(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)
SW S1 28(SP)

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

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

JAL PlaySound
LI A0 0x2A1 ; Shy Guy voice

SW R0 16(SP) ; A4
SW R0 20(SP) ; A5
SW R0 24(SP) ; A6
LI A0 0x9 ; Character image (-1 for none, 0x9 for Snifit Patrol)
; 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 S0 ; Pass message address on A1
MOVE A2 S1 ; 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

;===Item Array===
; This is the Item Array. To set item(s) to remove, follow the
; formula of .byte [item index] and insert the items before the
; terminator byte. The order of the items is not significant. However,
; the terminator byte (.byte 0x13) must always be last in the list.
; For a list of item indexes, see below the Price Array.

.align 16
ItemArray:
.byte 0x01 ; Skeleton Key index
.byte 0x09 ; Lucky Lamp index
.byte 0x0E ; Magic Lamp index
.byte 0x13 ; Terminator byte

;===Price Array===
; This is the Price Array. To set prices for the items, follow the
; formula of .halfword [price] and ensure that the order of prices
; matches the order of items. Prices from 0 to 999 coins are
; supported. Negative prices (i.e. losing coins) are not supported.

.align 16
PriceArray:
.halfword 5 ; Skeleton Key price
.halfword 10 ; Lucky Lamp price
.halfword 20 ; Magic Lamp price

; Item Indexes:
; 0x00 = Mushroom
; 0x01 = Skeleton Key
; 0x02 = Poison Mushroom
; 0x03 = Reverse Mushroom
; 0x04 = Cellular Shopper
; 0x05 = Warp Block
; 0x06 = Plunder Chest
; 0x07 = Bowser Phone
; 0x08 = Dueling Glove
; 0x09 = Lucky Lamp
; 0x0A = Golden Mushroom
; 0x0B = Boo Bell
; 0x0C = Boo Repellant
; 0x0D = Bowser Suit
; 0x0E = Magic Lamp
; 0x0F = Koopa Card
; 0x10 = Barter Box
; 0x11 = Lucky Coin
; 0x12 = Wacky Watch

;===Message Text===
.align 16
GreetingMessage:
.byte 0x1A,0x1A,0x1A,0x1A ; Padding for character image
.ascii "I"
.byte 0x5C ; Apostrophe (')
.ascii "m the Snifit Patrol"
.byte 0x85 ; Period (.)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "I see you are in possession"
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "of an"
.byte 0x03 ; Red font
.ascii " illegal item"
.byte 0x08,0x85 ; White font, Period (.)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "Let me just confiscate that"
.byte 0x85 ; Period (.)
.byte 0xFF,0 ; Wait, press A to confirm

.align 16
CoinsMessage:
.byte 0x1A,0x1A,0x1A,0x1A ; Padding for character image
.ascii "Thanks for cooperating with"
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; New line + character image padding
.ascii "the law"
.byte 0x85 ; Period (.)
.ascii " Take "
.byte 0x06,0x11 ; Blue font, String #1 stored on A2 (CoinString)
.ascii " coins"
.byte 0x08 ; White font
.ascii " as thanks"
.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