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

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

private alias object.propertyValue : object.isGHZAchievement

private alias object.value1 : object.targetPlayer

private alias 0 : RING_NORMAL
private alias 1 : RING_ATTRACT

// Player aliases
private alias object.state : player.state
private alias object.animation : player.animation
private alias object.value0 : player.rings
private alias object.value37 : player.shield

private alias 4 : SHIELD_LIGHTNING

// Game Mode Aliases
private alias 2 : MODE_TIMEATTACK

// Music Events
private alias 25 : SLOT_MUSICEVENT_CHANGE

private alias 2 : MUSICEVENT_TRANSITION

// Achievement Aliases
private alias 0 : ACHIEVEMENT_RAMPRINGACRO
private alias 4 : ACHIEVEMENT_RINGKING


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

reserve function Ring_DebugDraw
reserve function Ring_DebugSpawn


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

private function Ring_DebugDraw
	DrawSprite(0)
end function


private function Ring_DebugSpawn
	CreateTempObject(TypeName[Ring], 0, object.xpos, object.ypos)
	object[tempObjectPos].drawOrder = 4
end function


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

event ObjectUpdate
	// Interact with player(s)
	foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)

		// Check if the player should be able to collect rings

		// Player 1 can't be hurt...
		CheckEqual(player[0].state, Player_State_Hurt)
		temp0 = checkResult
		
		// ...nor can the current player be recoiling either
		CheckEqual(player[currentPlayer].state, Player_State_Hurt)
		temp0 = checkResult
		CheckEqual(player[currentPlayer].state, Player_State_GotHit)
		temp0 |= checkResult

		if temp0 == false
			BoxCollisionTest(C_TOUCH, object.entityPos, -8, -8, 8, 8, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
			if checkResult == true
				// Make the ring disappear
				object.type = TypeName[Ring Sparkle]

				// Add to the player's ring count
				player[0].rings++

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

				// Give the player an extra life if needed
				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

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

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

				// Update achievment collection
				if object.isGHZAchievement == true
					if stage.debugMode == false
						if options.attractMode == false
							if currentPlayer == 0
								if player[0].animation == ANI_JUMPING
									achieveRingCount++
									if achieveRingCount == 30
										// Grant the "Ramp Ring Acrobatics" Achievement
										CallNativeFunction2(SetAchievement, ACHIEVEMENT_RAMPRINGACRO, 100)
										achieveRingCount = 0
									end if
								end if
							end if
						end if
					end if
				end if

				// Play the ring chime
				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
			else
				if object.state == RING_NORMAL
					// Does the player have the lightning shield?
					if player[currentPlayer].shield == SHIELD_LIGHTNING
						// Check if this ring falls within the lightning shield attraction range
						BoxCollisionTest(C_TOUCH, object.entityPos, -64, -64, 64, 64, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
						if checkResult == true
							object.state = RING_ATTRACT
							object.targetPlayer = currentPlayer
						end if
					end if
				end if
			end if
		end if
	next

	if object.state == RING_ATTRACT
		// Check if the player's lost their lightning shield
		arrayPos0 = object.targetPlayer
		if player[arrayPos0].shield != SHIELD_LIGHTNING
			// Make the ring fall to the ground
			object.type = TypeName[Lose Ring]
			object.animationSpeed = 128
			object.alpha = 256

		else
			// Move to the player
			arrayPos0 = object.targetPlayer
			if object.xpos > object[arrayPos0].xpos
				if object.xvel > 0
					object.xvel -= 0xC000
				else
					object.xvel -= 0x3000
				end if
			else
				if object.xvel < 0
					object.xvel += 0xC000
				else
					object.xvel += 0x3000
				end if
			end if
			
			if object.ypos > object[arrayPos0].ypos
				if object.yvel > 0
					object.yvel -= 0xC000
				else
					object.yvel -= 0x3000
				end if
			else
				if object.yvel < 0
					object.yvel += 0xC000
				else
					object.yvel += 0x3000
				end if
			end if

			object.xpos += object.xvel
			object.ypos += object.yvel
		end if
	end if
end event


event ObjectDraw
	DrawSprite(ringFrame)
end event


event ObjectStartup
	LoadSpriteSheet("Global/Items.gif")
	
	// (Doesn't mean much, but this is one of the few times in v4 scripts that extra code is between LoadSpriteSheet and SpriteFrames)
	foreach (TypeName[Ring], arrayPos0, ALL_ENTITIES)
		object[arrayPos0].drawOrder = 4
	next

	// Reset the achievment value
	achieveRingCount = 0

	// Ring frames
	SpriteFrame(-8, -8, 16, 16, 1, 1)
	SpriteFrame(-8, -8, 16, 16, 1, 18)
	SpriteFrame(-8, -8, 16, 16, 1, 35)
	SpriteFrame(-8, -8, 16, 16, 1, 52)
	SpriteFrame(-8, -8, 16, 16, 1, 69)
	SpriteFrame(-8, -8, 16, 16, 1, 86)
	SpriteFrame(-8, -8, 16, 16, 1, 103)
	SpriteFrame(-8, -8, 16, 16, 1, 120)

	// Add the ring to the stage's debug mode list
	SetTableValue(TypeName[Ring], DebugMode_ObjCount, DebugMode_TypesTable)
	SetTableValue(Ring_DebugDraw, DebugMode_ObjCount, DebugMode_DrawTable)
	SetTableValue(Ring_DebugSpawn, DebugMode_ObjCount, DebugMode_SpawnTable)
	DebugMode_ObjCount++
end event


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

event RSDKEdit
	if editor.returnVariable == true
		switch editor.variableID
		case EDIT_VAR_PROPVAL // property value
			checkResult = object.propertyValue
			break
			
		case 0 // achievementType
			checkResult = object.propertyValue
			break
			
		end switch
	else
		switch editor.variableID
		case EDIT_VAR_PROPVAL // property value
			object.propertyValue = editor.variableValue
			break
			
		case 0 // achievementType
			object.propertyValue = editor.variableValue
			break
			
		end switch
	end if
end event


event RSDKDraw
	DrawSprite(0)
end event


event RSDKLoad
	LoadSpriteSheet("Global/Items.gif")
	SpriteFrame(-8, -8, 16, 16, 1, 1)

	AddEditorVariable("achievementType")
	SetActiveVariable("achievementType")
	AddEnumVariable("None", 0)
	AddEnumVariable("GHZ Achievement", 1)
end event
