; NAME: Slowing Snifit
; GAMES: MP3_USA
; EXECUTION: Direct
; PARAM: Space|SpaceDirection
; PARAM: Boolean|Rubberbanding

ADDIU SP SP -80
SW RA 76(SP)
SW S1 72(SP) ;holds rubberbanding value
SW S2 68(SP) ;used to store various values
SW S3 64(SP) ;used for window display
SW S4 60(SP) ;used for the curse flags
SW S0 56(SP) ;used to store various values

JAL PlaySound 
LI A0 0x2A5 ; Shy Guy Voice Index

;===Set Player Idle Animation===
LI A0 -1 ; Load Current Player Index
LI A1 -1 ; Set player's idle animation
JAL SetBoardPlayerAnimation
LI A2 2 ; Loop the animation

;===Rotate Player Model Towards Space===
LI A0 -1 ; Load Current Player Index
LI A1 10 ; Frames it takes to turn
JAL 0x800ED20C ; RotatePlayerModel function
LI A2 SpaceDirection ; Space Index to face towards

;FIRST WINDOW=========================================================
SW R0 16(SP) ; A4
SW R0 20(SP) ; A5
SW R0 24(SP) ; A6
LI A0 0x9 ; Character image (Snifit)
LUI A1 hi(Snifit_Message)
ADDIU A1 A1 lo(Snifit_Message)

ADDU A2 R0 R0
JAL 0x800EC8EC ; ShowMessage
ADDU A3 R0 R0

JAL 0x800EC9DC
NOP
JAL 0x800EC6C8
NOP
JAL 0x800EC6EC
NOP
;FIRST WINDOW END=====================================================

;CHECK FOR RUBBERBAND=================================================
LI S1 Rubberbanding
BNE S1 R0 TestTest ; if yes, do the checks
NOP ; If not, randomly pick
;CHECK FOR RUBBERBAND END=============================================

;COMPLETLY RANDOM PICK===============================================
JAL GetRandomByte ; Random Int at V0
NOP

SLTI S0 V0 175 ; Is the number less than 175?
BNE S0 R0 Bad_Curse
NOP

J Good_Curse
NOP
;COMPLETLY RANDOM PICK END===========================================

;CHECKS MISSFIRE1===============================================
TestTest:
JAL GetRandomByte ; Random Int at V0
NOP

SLTI S0 V0 80 ; Is the number less than 80?
BNE S0 R0 PositionTest
NOP

SLTI S0 V0 160 ; Is the number less than 160?
BNE S0 R0 HappeningTest
NOP

SLTI S0 V0 240 ; Is the number less than 240?
BNE S0 R0 CoinTest
NOP

J RankingTest
NOP
;CHECKS MISSFIRE1 END===========================================

;CHECKS MISSFIRE2===============================================
;Check if same number of stars as first place
PositionTest:
JAL GetCurrentPlayerStarCount
NOP
MOVE S2 V0 ; S2 = V0
JAL GetFirstPlaceStarCount 
NOP
BEQ S2 V0 Good_Curse
NOP
J Bad_Curse
NOP

;Check if player has happening star
HappeningTest:
JAL GetCurrentPlayerHappeningStarCount
LI S2 0x1;
ADDU S1 S2 V0 ; Add S2 to the value

LUI S2 hi(p1_happening_space_count)
ADDIU S2 S2 lo(p1_happening_space_count) ; Loading P1 ?STAR
LBU S2 0(S2)

SLT S0 S1 S2 ; Is P1 Happening Star higher than current player?
NOP
BNE S0 R0 Good_Curse
NOP

LUI S2 hi(p2_happening_space_count)
ADDIU S2 S2 lo(p2_happening_space_count) ; Loading P2 ?STAR
LBU S2 0(S2)

SLT S0 S1 S2 ; Is P2 Happening Star higher than current player?
NOP
BNE S0 R0 Good_Curse
NOP

LUI S2 hi(p3_happening_space_count)
ADDIU S2 S2 lo(p3_happening_space_count) ; Loading P3 ?STAR
LBU S2 0(S2)

SLT S0 S1 S2 ; Is P3 Happening Star higher than current player?
NOP
BNE S0 R0 Good_Curse
NOP

LUI S2 hi(p4_happening_space_count)
ADDIU S2 S2 lo(p4_happening_space_count) ; Loading P4 ?STAR
LBU S2 0(S2)

SLT S0 S1 S2 ; Is P4 Happening Star higher than current player?
NOP
BNE S0 R0 Good_Curse
NOP

J Bad_Curse
NOP

;Check if 20 coins or more
CoinTest:
LI A1 20 ; A1 = The ammount of Coins to check for
JAL PlayerHasCoins ; Checks if Player has that ammount of Coins
NOP
BNE V0 R0 Good_Curse
NOP
J Bad_Curse
NOP

;Check if Last Place or First Place
RankingTest:
JAL GetCurrentPlayerIndex
NOP
JAL GetPlayerPlacement
MOVE A0 V0
LI S2 0
BEQ V0 S2 Good_Curse ;Does current player have a rank of 0? (first)
NOP
JAL GetCurrentPlayerIndex
NOP
JAL GetPlayerPlacement
MOVE A0 V0
LI S2 3
BEQ V0 S2 Good_Curse ;Does current player have a rank of 3? (last)
NOP
J Bad_Curse
NOP
;CHECKS MISSFIRE2 END===========================================
Good_Curse:
JAL PlaySound ; Play Poison Sound
LI A0 0x8C
LI S3 1 ; For window display

LI A0 -1 ; Load Current Player Index
LI A1 -1 ; Set player's idle animation
JAL SetBoardPlayerAnimation
LI A2 0 ; Don't loop the animation

JAL SleepProcess ; Sleeps for 15 frames
ADDIU A0 R0 15

JAL PlaySound ; Play Poison Hit Sound
LI A0 0xA7

JAL SleepProcess ; Sleeps for 30 frames
ADDIU A0 R0 30

JAL GetPlayerStruct
LI A0, -1
LBU T0 0x17(V0) ; Load value of status flags into T1, u8 so it is only LBU/SB
ORI T0 T0 0x28 ; This will add the purple bowser head to your status flags, but also keep whatever status flags you also had originally
SB T0 0x17(V0)
J Rest_Curse
NOP
Bad_Curse:
JAL PlaySound ; Play Poison Sound
LI A0 0x8C
LI S3 0 ; For window display

LI A0 -1 ; Load Current Player Index
LI A1 -1 ; Set player's idle animation
JAL SetBoardPlayerAnimation
LI A2 0 ; Don't loop the animation

JAL SleepProcess ; Sleeps for 15 frames
ADDIU A0 R0 15

JAL PlaySound ; Play Poison Hit Sound
LI A0 0xA7

JAL SleepProcess ; Sleeps for 30 frames
ADDIU A0 R0 30

JAL GetPlayerStruct
LI A0, -1
LBU T0 0x17(V0) ; Load value of status flags into T1, u8 so it is only LBU/SB
ORI T0 T0 0xD0 ; This will add the green bowser head to your status flags, but also keep whatever status flags you also had originally
SB T0 0x17(V0)
J Rest_Curse
NOP
;POISON START-------------------------------------------------------
Rest_Curse:
JAL PlaySound ; Play Mud Effect Sound
LI A0 0x0D

LI A0 -1 ; Load Current Player Index
LI A1 3 ; Set player's sad animation
JAL SetBoardPlayerAnimation
LI A2 0 ; Don't loop the animation

JAL GetCurrentPlayerIndex ; Player Index located at V0
NOP

add S0, R0, V0 ;Transfer it to S0

LI S2 0x0
BEQ S0 S2 PoisonP1 ; If it's Player 1, poison to P1
NOP
LI S2 0x1
BEQ S0 S2 PoisonP2 ; If it's Player 2, poison to P2
NOP
LI S2 0x2
BEQ S0 S2 PoisonP3 ; If it's Player 3, poison to P3
NOP
LI S2 0x3
BEQ S0 S2 PoisonP4 ; If it's Player 4, poison to P4
NOP
;POISON END---------------------------------------------------------

;=====POISONP1START=====
PoisonP1:
LI S2 0x1
LUI S4 hi(0x800CD0AF)
ADDIU S4 S4 lo(0x800CD0AF) ; Loading RAM address of the Curse Flags
LBU S1 0(S4)

add S1, S1, S2 ; Add the P1 bit to the curse value
SB S1 0(S4) ; And send it to the curse address

BNE S3 R0 BadCurseWindow ;check if S3 = 0
NOP
J GoodCurseWindow
NOP
;=====POISONP1END=======

;=====POISONP2START=====
PoisonP2:
LI S2 0x2
LUI S4 hi(0x800CD0AF)
ADDIU S4 S4 lo(0x800CD0AF) ; Loading RAM address of the Curse Flags
LBU S1 0(S4)

add S1, S1, S2 ; Add the P2 bit to the curse value
SB S1 0(S4) ; And send it to the curse address

BNE S3 R0 BadCurseWindow ;check if S3 = 0
NOP
J GoodCurseWindow
NOP
;=====POISONP2END=======

;=====POISONP3START=====
PoisonP3:
LI S2 0x4
LUI S4 hi(0x800CD0AF)
ADDIU S4 S4 lo(0x800CD0AF) ; Loading RAM address of the Curse Flags
LBU S1 0(S4)

add S1, S1, S2 ; Add the P3 bit to the curse value
SB S1 0(S4) ; And send it to the curse address

BNE S3 R0 BadCurseWindow ;check if S3 = 0
NOP
J GoodCurseWindow
NOP
;=====POISONP3END=======

;=====POISONP4START=====
PoisonP4:
LI S2 0x8
LUI S4 hi(0x800CD0AF)
ADDIU S4 S4 lo(0x800CD0AF) ; Loading RAM address of the Curse Flags
LBU S1 0(S4)

add S1, S1, S2 ; Add the P4 bit to the curse value
SB S1 0(S4) ; And send it to the curse address

BNE S3 R0 BadCurseWindow ;check if S3 = 0
NOP
J GoodCurseWindow
NOP
;=====POISONP4END=======

;=====BADWINDOWSTART=====
BadCurseWindow:
LUI A1 hi(Poison_Message)
ADDIU A1 A1 lo(Poison_Message)

J Window_Exit
NOP
;=====BADWINDOWEND=====

;=====GOODWINDOWSTART=====
GoodCurseWindow:
LUI A1 hi(Reverse_Message)
ADDIU A1 A1 lo(Reverse_Message)

J Window_Exit
NOP
;=====GOODWINDOWEND=====

Window_Exit:
SW R0 16(SP) ; A4
SW R0 20(SP) ; A5
SW R0 24(SP) ; A6
LI A0 -1 ; Character image (-1 for none)

ADDU A2 R0 R0
JAL ShowMessage
ADDU A3 R0 R0

JAL 0x800EC9DC
NOP
JAL 0x800EC6C8
NOP
JAL 0x800EC6EC
NOP

exit:

;===Set Player Idle Animation===
LI A0 -1 ; Load Current Player Index
LI A1 -1 ; Set player's idle animation
JAL SetBoardPlayerAnimation
LI A2 2 ; Loop the animation

LW RA 76(SP)
LW S1 72(SP)
LW S2 68(SP)
LW S3 64(SP)
LW S4 60(SP)
LW S0 56(SP)
JR RA
ADDIU SP SP 80

.align 16
Snifit_Message:
.byte 0x1A,0x1A,0x1A,0x1A ; Standard padding for picture
.ascii "Hmm"
.byte 0x82 ; Comma (,)
.ascii " hmm"
.byte 0x82 ; Comma (,)
.ascii " hmm"
.byte 0xC2 ; Exclamation Mark (!)
.byte 0x0A,0x1A,0x1A,0x1A,0x1A ; Newline+Padding
.ascii "Hope you enjoy this poisonous gas"
.byte 0xC2 ; Exclamation Mark (!)
.byte 0xFF,0 ; FF=Pause

.align 16
Poison_Message:
.ascii "You"
.byte 0x5C ; Apostrophe (')
.ascii "ve been "
.byte 0x04 ; Purple Font
.ascii "poisoned"
.byte 0x08 ; White Font
.byte 0x85, 0x85, 0x85 ; Periods (...)
.byte 0xFF,0 ; FF=Pause

.align 16
Reverse_Message:
.ascii "You"
.byte 0x5C ; Apostrophe (')
.ascii "ve been "
.byte 0x05 ; Green Font
.ascii "poisoned"
.byte 0x08 ; White Font
.byte 0x85, 0x85, 0x85 ; Periods (...)
.byte 0xFF,0 ; FF=Pause

.align 16
GetCurrentPlayerHappeningStarCount:
ADDIU SP SP -40
SW RA 36(SP)
JAL GetPlayerStruct
LI A0, -1
LBU V0, 0x002C (v0) ;load current player happening star count to V0
LW RA 36(SP)
JR RA
ADDIU SP SP 40

.align 16
GetCurrentPlayerStarCount:
ADDIU SP SP -40
SW RA 36(SP)
JAL GetPlayerStruct
LI A0, -1
LBU V0, 0x000A (v0) ;load current player star count to V0
LW RA 36(SP)
JR RA
ADDIU SP SP 40

.align 16
GetFirstPlaceStarCount:
ADDIU SP SP -40
SW RA 36(SP)
LI T0 0x0
;Test if player one is in first place
JAL GetPlayerPlacement
LI A0 0x0
BEQ T0 V0 GetPlayerOneStarCount
NOP
;Test if player two is in first place
JAL GetPlayerPlacement
LI A0 0x1
BEQ T0 V0 GetPlayerTwoStarCount
NOP
;Test if player three is in first place
JAL GetPlayerPlacement
LI A0 0x2
BEQ T0 V0 GetPlayerThreeStarCount
NOP
;Test if player four is in first place
JAL GetPlayerPlacement
LI A0 0x3
BEQ T0 V0 GetPlayerFourStarCount
NOP
;Get player one star count into V0
GetPlayerOneStarCount:
LUI V0 hi(p1_stars)
ADDIU V0 V0 lo(p1_stars)
LBU V0 0(V0)
J starcountend
NOP
;Get player two star count into V0
GetPlayerTwoStarCount:
LUI V0 hi(p2_stars)
ADDIU V0 V0 lo(p2_stars)
LBU V0 0(V0)
J starcountend
NOP
;Get player three star count into V0
GetPlayerThreeStarCount:
LUI V0 hi(p3_stars)
ADDIU V0 V0 lo(p3_stars)
LBU V0 0(V0)
J starcountend
NOP
;Get player four star count into V0
GetPlayerFourStarCount:
LUI V0 hi(p4_stars)
ADDIU V0 V0 lo(p4_stars)
LBU V0 0(V0)
starcountend:
LW RA 36(SP)
JR RA
ADDIU SP SP 40