// ----------------------------------
// RSDK Project: Sonic 1
// Script Description: Broken Monitor Object
// Script Author: Christian Whitehead/Simon Thomley
// Unpacked by Rubberduckycooly's script unpacker
// ----------------------------------

// ========================
// Aliases
// ========================

private alias object.value0 : object.contentsPos.y
private alias object.value1 : object.timer

// Monitor type aliases
private alias 0  : MONITOR_BLANK
private alias 1  : MONITOR_RINGS
private alias 2  : MONITOR_SHIELD_BLUE
private alias 3  : MONITOR_INVINCIBILITY
private alias 4  : MONITOR_SPEEDSHOES
private alias 5  : MONITOR_1UP_SONIC
private alias 6  : MONITOR_1UP_TAILS
private alias 7  : MONITOR_1UP_KNUX
private alias 8  : MONITOR_SUPER
private alias 9  : MONITOR_SHIELD_BUBBLE
private alias 10 : MONITOR_SHIELD_FIRE
private alias 11 : MONITOR_SHIELD_LIGHTNING
private alias 12 : MONITOR_EGGMAN
private alias 13 : MONITOR_SHIELD_GOGGLES
private alias 14 : MONITOR_DEBUG_SPIKES
private alias 15 : MONITOR_DEBUG_SHIELD
private alias 16 : MONITOR_DEBUG_EMERALDS

// Monitor states
private alias 0 : MONITOR_STATE_RISE
private alias 1 : MONITOR_STATE_FADE
private alias 2 : MONITOR_STATE_IDLE

// Player Aliases
private alias object.type    : player.type
private alias object.xpos    : player.xpos
private alias object.ypos    : player.ypos
private alias object.value0  : player.rings
private alias object.value3  : player.drownTimer
private alias object.value4  : player.drownLevel
private alias object.value6  : player.speedShoesTimer
private alias object.value7  : player.invincibleTimer
private alias object.value37 : player.shield

// Shields
private alias 0 : SHIELD_NONE
private alias 1 : SHIELD_NORMAL
private alias 2 : SHIELD_BUBBLE
private alias 3 : SHIELD_FIRE
private alias 4 : SHIELD_LIGHTNING
private alias 5 : SHIELD_GOGGLES

// Game Mode Aliases
private alias 2 : MODE_TIMEATTACK

// Tracks
private alias 2 : TRACK_INVINCIBLE

// Music Events
private alias 25 : SLOT_MUSICEVENT_CHANGE

private alias 2 : MUSICEVENT_TRANSITION

// Super States
private alias 1 : SUPERSTATE_SUPER

// Achievement Aliases
private alias 4 : ACHIEVEMENT_RINGKING


// ========================
// Function Declarations
// ========================

reserve function BrokenMonitor_Blank

// ========================
// Static Values
// ========================

public value BrokenMonitor_ResetDrownMusic = 0


// ========================
// Function Definitions
// ========================

// Dummy function
private function BrokenMonitor_Blank
	// Not much to do, no drowning music to reset
end function


// ========================
// Events
// ========================

event ObjectUpdate
	switch object.state
	case MONITOR_STATE_RISE
		if object.timer < 0
			object.contentsPos.y += object.timer
			object.timer += 0x1800
		else
			object.timer = 0
		end if

		if object.timer == 0
			object.state = MONITOR_STATE_FADE
			object.inkEffect = INK_ALPHA
			switch object.propertyValue
			case MONITOR_BLANK
			default
				break

			case MONITOR_RINGS
				player[0].rings += 10
				if ringPan == 0
					PlaySfx(SfxName[Ring L], false)
					SetSfxAttributes(SfxName[Ring L], -1, -100)
					ringPan = 1
				else
					PlaySfx(SfxName[Ring R], false)
					SetSfxAttributes(SfxName[Ring R], -1, 100)
					ringPan = 0
				end if

				if player[0].rings > 999
					player[0].rings = 999
				end if

				if player[0].rings >= ringExtraLife
					if options.gameMode != MODE_TIMEATTACK
#platform: USE_ORIGINS
						if game.coinMode == false
							player.lives++
						else
							CallNativeFunction2(NotifyCallback, NOTIFY_ADD_COIN, 1)
						end if
#endplatform
#platform: USE_STANDALONE
						player.lives++
#endplatform
						PlaySfx(SfxName[Life], false)
						PauseMusic()
						ResetObjectEntity(SLOT_MUSICEVENT_CHANGE, TypeName[Music Event], MUSICEVENT_TRANSITION, 0, 0)
						object[SLOT_MUSICEVENT_CHANGE].priority = PRIORITY_ACTIVE
					end if

					ringExtraLife += 100
					if ringExtraLife > 300
						ringExtraLife = 1000
					end if

					if stage.debugMode == false
						if player[0].rings >= 200
							// Grant the "Ring King" Achievement
							CallNativeFunction2(SetAchievement, ACHIEVEMENT_RINGKING, 100)
						end if
					end if
				end if
				break

			case MONITOR_SHIELD_BLUE
				PlaySfx(SfxName[Blue Shield], false)
				arrayPos0 = playerCount
				currentPlayer = 0
				player[currentPlayer].shield = SHIELD_NORMAL

				if Player_superState != SUPERSTATE_SUPER
					if object[arrayPos0].type != invincibilityType
						CallFunction(Player_ApplyShield)
					end if
				end if
				break

			case MONITOR_INVINCIBILITY
				if Player_superState != SUPERSTATE_SUPER
					arrayPos0 = playerCount
					currentPlayer = 0
					ResetObjectEntity(arrayPos0, invincibilityType, 0, player[currentPlayer].xpos, player[currentPlayer].ypos)
					object[arrayPos0].priority = PRIORITY_ACTIVE
					player[currentPlayer].invincibleTimer = 1260
					PlayMusic(TRACK_INVINCIBLE)
				end if
				break

			case MONITOR_SPEEDSHOES
				currentPlayer = 0
				if SpeedUpMusic != 0
					if player[currentPlayer].speedShoesTimer == 0
						CallFunction(SpeedUpMusic)
					end if
				end if

				player[currentPlayer].speedShoesTimer = 1320
				CallFunction(Player_UpdatePhysicsState)
				break

			case MONITOR_1UP_SONIC
			case MONITOR_1UP_TAILS
			case MONITOR_1UP_KNUX
#platform: USE_ORIGINS
				if game.coinMode == false
					player.lives++
				else
					CallNativeFunction2(NotifyCallback, NOTIFY_ADD_COIN, 1)
				end if
#endplatform
#platform: USE_STANDALONE
				player.lives++
#endplatform
				PlaySfx(SfxName[Life], false)
				PauseMusic()
				ResetObjectEntity(SLOT_MUSICEVENT_CHANGE, TypeName[Music Event], MUSICEVENT_TRANSITION, 0, 0)
				object[SLOT_MUSICEVENT_CHANGE].priority = PRIORITY_ACTIVE
				break

			case MONITOR_SUPER
				currentPlayer = 0
				player[0].rings += 50

				if Player_superState != SUPERSTATE_SUPER
					object.type = player[0].type
					CallFunction(Player_TryTransform)
					object.type = TypeName[Broken Monitor]
				else
					if ringPan == 0
						PlaySfx(SfxName[Ring L], false)
						SetSfxAttributes(SfxName[Ring L], -1, -100)
						ringPan = 1
					else
						PlaySfx(SfxName[Ring R], false)
						SetSfxAttributes(SfxName[Ring R], -1, 100)
						ringPan = 0
					end if
				end if

				if player[0].rings > 999
					player[0].rings = 999
				end if

				if player[0].rings >= ringExtraLife
					if options.gameMode != MODE_TIMEATTACK
#platform: USE_ORIGINS
						if game.coinMode == false
							player.lives++
						else
							CallNativeFunction2(NotifyCallback, NOTIFY_ADD_COIN, 1)
						end if
#endplatform
#platform: USE_STANDALONE
						player.lives++
#endplatform
						PlaySfx(SfxName[Life], false)
						PauseMusic()
						ResetObjectEntity(SLOT_MUSICEVENT_CHANGE, TypeName[Music Event], MUSICEVENT_TRANSITION, 0, 0)
						object[SLOT_MUSICEVENT_CHANGE].priority = PRIORITY_ACTIVE
					end if

					ringExtraLife += 100
					if ringExtraLife > 300
						ringExtraLife = 1000
					end if
				end if
				break

			case MONITOR_SHIELD_BUBBLE
				PlaySfx(SfxName[Bubble Shield], false)
				arrayPos0 = playerCount
				currentPlayer = 0
				player[currentPlayer].shield = SHIELD_BUBBLE

				if Player_superState != SUPERSTATE_SUPER
					if object[arrayPos0].type != invincibilityType
						CallFunction(Player_ApplyShield)
					end if
				end if

				if player[currentPlayer].drownLevel >= 3
					player[currentPlayer].drownTimer = 0
					player[currentPlayer].drownLevel = 0
					CallFunction(BrokenMonitor_ResetDrownMusic)
				end if
				break

			case MONITOR_SHIELD_FIRE
				PlaySfx(SfxName[Fire Shield], false)
				arrayPos0 = playerCount
				currentPlayer = 0
				player[currentPlayer].shield = SHIELD_FIRE

				if Player_superState != SUPERSTATE_SUPER
					if object[arrayPos0].type != invincibilityType
						CallFunction(Player_ApplyShield)
					end if
				end if
				break
				
			case MONITOR_SHIELD_LIGHTNING
				PlaySfx(SfxName[Lightning Shield], false)
				arrayPos0 = playerCount
				currentPlayer = 0
				player[currentPlayer].shield = SHIELD_LIGHTNING

				if Player_superState != SUPERSTATE_SUPER
					if object[arrayPos0].type != invincibilityType
						CallFunction(Player_ApplyShield)
					end if
				end if
				break

			case MONITOR_EGGMAN
				currentPlayer = 0
				CallFunction(Player_Hit)
				break
				
			case MONITOR_SHIELD_GOGGLES
				PlaySfx(SfxName[Catch], false)
				arrayPos0 = playerCount
				currentPlayer = 0
				player[currentPlayer].shield = SHIELD_GOGGLES

				if Player_superState != SUPERSTATE_SUPER
					if object[arrayPos0].type != invincibilityType
						CallFunction(Player_ApplyShield)
					end if
				end if
				break

			case MONITOR_DEBUG_SPIKES
				PlaySfx(SfxName[Spike], false)
				options.spikeBehavior ^= true
				break

			case MONITOR_DEBUG_SHIELD
				PlaySfx(SfxName[Blue Shield], false)
				options.shieldType++
				options.shieldType &= 3
				switch options.shieldType
				case 0
				case 2
					blueShieldType = TypeName[Blue Shield]
					invincibilityType = TypeName[Invincibility 2]
					break

				case 1
				case 3
					blueShieldType = TypeName[Blue Shield 2]
					invincibilityType = TypeName[Invincibility 2]
					break

				end switch
				arrayPos0 = playerCount
				currentPlayer = 0
				CallFunction(Player_ApplyShield)
				break

			case MONITOR_DEBUG_EMERALDS
				if specialStage.emeralds >= 0x40 // Does the player have the 7th emerald?
					if specialStage.emeralds == 0x7F
						options.superStates = false
						specialStage.emeralds = 0
					else
						PlaySfx(SfxName[Transform], false)
						specialStage.emeralds = 0x7F
					end if
				else
					PlaySfx(SfxName[Transform], false)
					options.superStates = true
					specialStage.emeralds |= 0x40 // Give the Player the 7th emerald
				end if
				break

			end switch
		end if
		break

	case MONITOR_STATE_FADE
		object.timer++
		if object.timer == 30
			object.timer = 0
			object.state = MONITOR_STATE_IDLE
			object.propertyValue = MONITOR_BLANK
			if object.priority != PRIORITY_XBOUNDS_DESTROY
				object.priority = PRIORITY_BOUNDS
			end if
		else
			if object.timer > 14
				object.alpha -= 16
			end if
		end if
		break

	case MONITOR_STATE_IDLE
		break
		
	end switch
end event


event ObjectDraw
	DrawSprite(0)

	if object.propertyValue > MONITOR_BLANK
		DrawSpriteFX(object.propertyValue, FX_INK, object.xpos, object.contentsPos.y)
	end if
end event


event ObjectStartup
	LoadSpriteSheet("Global/Items.gif")
	SpriteFrame(-16, 0, 32, 16, 51, 166)
	SpriteFrame(-8, -9, 16, 14, 51, 16)
	SpriteFrame(-8, -9, 16, 14, 68, 16)
	SpriteFrame(-8, -9, 16, 14, 51, 31)
	SpriteFrame(-8, -9, 16, 14, 68, 31)
#platform: USE_ORIGINS
	if game.coinMode == false
#endplatform
		SpriteFrame(-8, -9, 16, 14, 51, 46)
		SpriteFrame(-8, -9, 16, 14, 68, 46)
		SpriteFrame(-8, -9, 16, 14, 51, 61)
#platform: USE_ORIGINS
	else
		SpriteFrame(-8, -9, 16, 14, 35, 100)
		SpriteFrame(-8, -9, 16, 14, 35, 100)
		SpriteFrame(-8, -9, 16, 14, 35, 100)
	end if
#endplatform
	SpriteFrame(-8, -9, 16, 14, 68, 61)
	SpriteFrame(-8, -9, 16, 14, 51, 91)
	SpriteFrame(-8, -9, 16, 14, 68, 76)
	SpriteFrame(-8, -9, 16, 14, 51, 76)
	SpriteFrame(-8, -9, 16, 14, 68, 91)
	SpriteFrame(-8, -9, 16, 14, 18, 100)
	SpriteFrame(-8, -9, 16, 14, 117, 26)
	SpriteFrame(-8, -9, 16, 14, 117, 41)
	SpriteFrame(-8, -9, 16, 14, 117, 56)
	BrokenMonitor_ResetDrownMusic = BrokenMonitor_Blank
end event


// ========================
// Editor Events
// ========================

event RSDKDraw
	DrawSprite(0)
end event


event RSDKLoad
	LoadSpriteSheet("Global/Items.gif")
	SpriteFrame(-16, 0, 32, 16, 51, 166)
	
	SetVariableAlias(ALIAS_VAR_PROPVAL, "unused")
end event
