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

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

private alias object.value0 : object.spinCount
private alias object.value1 : object.timer

private alias 0 : SIGNPOST_AWAITPLAYER
private alias 1 : SIGNPOST_SPINNING
private alias 2 : SIGNPOST_HANDLEACTFINISH
private alias 3 : SIGNPOST_EXITSTAGERIGHT
private alias 4 : SIGNPOST_TOSPECIALSTAGE
private alias 5 : SIGNPOST_BLANK // Set by Act Finish in SBZ2 transition

// Track Aliases
private alias 1 : TRACK_ACTFINISH

// Game Mode Aliases
private alias 0 : MODE_NOSAVE
private alias 1 : MODE_SAVEGAME
private alias 2 : MODE_TIMEATTACK

// Player Aliases
private alias 1 : SUPERSTATE_SUPER
private alias 2 : SUPERSTATE_UNTRANSFORM

private alias object.type 			: player.type
private alias object.xpos 			: player.xpos
private alias object.ypos 			: player.ypos
private alias object.xvel 			: player.xvel
private alias object.yvel 			: player.yvel
private alias object.speed 			: player.speed
private alias object.gravity 		: player.gravity
private alias object.up 			: player.up
private alias object.down 			: player.down
private alias object.left 			: player.left
private alias object.right 			: player.right
private alias object.jumpPress 		: player.jumpPress
private alias object.jumpHold 		: player.jumpHold
private alias object.interaction 	: player.interaction
private alias object.controlMode 	: player.controlMode
private alias object.value7 		: player.invincibleTimer

// Reserved Object Slot Aliases
private alias 30 : SLOT_ACTFINISH

// Achievement Aliases
private alias 1 : ACHIEVEMENT_BLASTPROCESSING


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

reserve function SignPost_DebugDraw
reserve function SignPost_DebugSpawn


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

private function SignPost_DebugDraw
	DrawSprite(0)
	DrawSprite(1)
end function


private function SignPost_DebugSpawn
	CreateTempObject(TypeName[Sign Post], 0, object.xpos, object.ypos)
	object[tempObjectPos].frame = 1
	object[tempObjectPos].spinCount = 16
end function


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

event ObjectUpdate
	switch object.state
	case SIGNPOST_AWAITPLAYER
		temp0 = object.ypos
		temp0 += 0x400000
		if player[0].ypos < temp0
			stage.newXBoundary1 = object.xpos
			stage.newXBoundary1 >>= 16
			stage.newXBoundary1 -= screen.xcenter
			stage.newXBoundary1 -= screen.xcenter
			stage.newXBoundary2 = object.xpos
			stage.newXBoundary2 >>= 16
			stage.newXBoundary2 += screen.xcenter
			if player[0].xpos > object.xpos
				stage.newXBoundary1 = object.xpos
				stage.newXBoundary1 >>= 16
				stage.newXBoundary1 -= screen.xcenter
				
				if stage.debugMode == false
					if stage.listPos == 0
						if stage.minutes == 0
							if stage.seconds < 30
								// Grant the "Blast Processing" Achievement
								CallNativeFunction2(SetAchievement, ACHIEVEMENT_BLASTPROCESSING, 100)
							end if
						end if
					end if
				end if

#platform: USE_ORIGINS
				CallNativeFunction2(NotifyCallback, NOTIFY_TOUCH_SIGNPOST, 0)
#endplatform
				stage.timeEnabled = false
				object.state = SIGNPOST_SPINNING
				PlaySfx(SfxName[Sign Post], false)
				if Player_superState == SUPERSTATE_SUPER
					Player_superState = SUPERSTATE_UNTRANSFORM
				end if
			end if
		end if
		break

	case SIGNPOST_SPINNING
		music.volume--
		object.timer++
		if object.timer == 2
			object.timer = 0
			object.frame++
			if object.frame == 5
				object.frame = 1
				Rand(temp0, 48)
				temp0 <<= 16
				temp0 += object.xpos
				temp0 -= 0x180000
				Rand(temp1, 32)
				temp1 <<= 16
				temp1 += object.ypos
				temp1 -= 0x140000
				CreateTempObject(TypeName[Ring Sparkle], 0, temp0, temp1)

				object.spinCount--
				if object.spinCount == 0
					if player[0].type == TypeName[Blank Object]
						object.state = SIGNPOST_TOSPECIALSTAGE

						if object.propertyValue < 3
							PlayMusic(TRACK_ACTFINISH)
						else
							if object.outOfBounds == false
								PlayMusic(TRACK_ACTFINISH)
							end if
						end if

						object[SLOT_ACTFINISH].type = TypeName[Act Finish]
						object[SLOT_ACTFINISH].drawOrder = 6
						object[SLOT_ACTFINISH].priority = PRIORITY_ACTIVE
						
						player[0].controlMode = CONTROLMODE_NONE
						player[0].interaction = false
						
						if stage.player2Enabled == true
							player[1].interaction 	= false
							player[1].controlMode 	= CONTROLMODE_NONE
							player[1].up 			= false
							player[1].down 			= false
							player[1].left 			= false
							player[1].jumpPress 	= false
							player[1].jumpHold 		= false
						end if
					else
						player[0].controlMode 	= CONTROLMODE_NONE
						player[0].interaction 	= false
						player[0].up 			= false
						player[0].down 			= false
						player[0].left 			= false
						player[0].jumpPress 	= false
						player[0].jumpHold 		= false
						if stage.player2Enabled == true
							player[1].controlMode 	= CONTROLMODE_NONE
							player[1].interaction 	= false
							player[1].up 			= false
							player[1].down 			= false
							player[1].left 			= false
							player[1].jumpPress 	= false
							player[1].jumpHold 		= false
						end if

						object.state = SIGNPOST_HANDLEACTFINISH
					end if
				end if
			end if
		end if

		temp0 = 40
		temp0 += screen.xcenter
		temp0 <<= 16
		temp0 += object.xpos
		if player[0].xpos > temp0
			player[0].xpos = temp0
			player[0].speed = 0
			player[0].xvel = 0
		end if

		if stage.player2Enabled == true
			if player[1].xpos > temp0
				player[1].xpos = temp0
				player[1].speed = 0
				player[1].xvel = 0
			end if
		end if
		break

	case SIGNPOST_HANDLEACTFINISH
		if player[0].type == TypeName[Blank Object]
			object.state = SIGNPOST_TOSPECIALSTAGE
			
			if object.propertyValue < 3
				PlayMusic(TRACK_ACTFINISH)
			else
				if object.outOfBounds == false
					PlayMusic(TRACK_ACTFINISH)
				end if
			end if
			object[SLOT_ACTFINISH].type = TypeName[Act Finish]
			object[SLOT_ACTFINISH].drawOrder = 6
			object[SLOT_ACTFINISH].priority = PRIORITY_ACTIVE
		end if

		if player[0].controlMode == CONTROLMODE_NONE
			player[0].right = true
		end if

		if stage.player2Enabled == true
			player[1].controlMode = player[0].controlMode
			if player[1].controlMode == CONTROLMODE_NONE
				if player[1].left == false
					player[1].right = true
				end if
			end if
		end if

		temp0 = screen.xcenter
		temp0 <<= 16
		temp0 += object.xpos
		if player[0].xpos > temp0
			if object.propertyValue < 3
				PlayMusic(TRACK_ACTFINISH)
			else
				if object.outOfBounds == false
					PlayMusic(TRACK_ACTFINISH)
				end if
			end if

			object.state = SIGNPOST_EXITSTAGERIGHT
			object[SLOT_ACTFINISH].type = TypeName[Act Finish]
			object[SLOT_ACTFINISH].drawOrder = 6
			object[SLOT_ACTFINISH].priority = PRIORITY_ACTIVE
		end if
		break

	case SIGNPOST_EXITSTAGERIGHT
		if player[0].controlMode == CONTROLMODE_NONE
			player[0].right = true
		end if

		temp0 = 40
		temp0 += screen.xcenter
		temp0 <<= 16
		temp0 += object.xpos
		if player[0].xpos > temp0
			player[0].xpos = temp0
			player[0].speed = 0
			player[0].xvel = 0
		end if

		if stage.player2Enabled == true
			if player[1].controlMode == CONTROLMODE_NONE
				player[1].right = true
			end if

			if player[1].xpos > temp0
				player[1].xpos = temp0
				player[1].speed = 0
				player[1].xvel = 0
			end if
		end if
		break

	case SIGNPOST_TOSPECIALSTAGE
		if stage.player2Enabled == true
			temp0 = 40
			temp0 += screen.xcenter
			temp0 <<= 16
			temp0 += object.xpos
			player[1].right = true
			player[1].controlMode = CONTROLMODE_NONE
			if player[1].xpos > temp0
				player[1].xpos = temp0
				player[1].speed = 0
				player[1].xvel = 0
			end if
		end if
		break
		
	// "SIGNPOST_BLANK" doesn't have anything, it's set by Act Finish in SBZ2 for the transition
	
	end switch

#platform: USE_ORIGINS
	if game.playMode == BOOT_PLAYMODE_MISSION
		if object.state > SIGNPOST_AWAITPLAYER
			player[0].invincibleTimer = 80
			
			if object.state > SIGNPOST_SPINNING
				CheckCurrentStageFolder("Mission_Zone02") // Marble Zone - Mission Mode
				temp0 = checkResult
				CheckEqual(stage.actNum, 1) // "Ring Rush"
				checkResult &= temp0
				player[0].interaction = checkResult
			end if
		end if
	end if
#endplatform
end event


event ObjectDraw
	DrawSprite(0)

	if object.spinCount > 8
		DrawSprite(object.frame)
	else
		temp0 = object.frame
		temp0 += 4
		DrawSprite(temp0)
	end if
end event


event ObjectStartup
	LoadSpriteSheet("Global/Items2.gif")
	SpriteFrame(-24, 16, 48, 16, 34, 214)
	switch stage.playerListPos
	case PLAYER_SONIC_ALONE
		SpriteFrame(-24, -16, 48, 32, 34, 182)
		SpriteFrame(-16, -16, 32, 32, 1, 150)
		SpriteFrame(-4, -16, 8, 32, 189, 131)
		SpriteFrame(-16, -16, 32, 32, 1, 183)
		SpriteFrame(-24, -16, 48, 32, 34, 83)
		SpriteFrame(-16, -16, 32, 32, 1, 150)
		SpriteFrame(-4, -16, 8, 32, 189, 131)
		SpriteFrame(-16, -16, 32, 32, 1, 183)
		break
		
	case PLAYER_TAILS_ALONE
		SpriteFrame(-24, -16, 48, 32, 34, 182)
		SpriteFrame(-16, -16, 32, 32, 83, 131)
		SpriteFrame(-4, -16, 8, 32, 189, 131)
		SpriteFrame(-16, -16, 32, 32, 83, 163)
		SpriteFrame(-24, -16, 48, 32, 34, 116)
		SpriteFrame(-16, -16, 32, 32, 83, 131)
		SpriteFrame(-4, -16, 8, 32, 189, 131)
		SpriteFrame(-16, -16, 32, 32, 83, 163)
		break
		
	case PLAYER_KNUX_ALONE
		SpriteFrame(-24, -16, 48, 32, 34, 182)
		SpriteFrame(-16, -16, 32, 32, 83, 131)
		SpriteFrame(-4, -16, 8, 32, 189, 131)
		SpriteFrame(-16, -16, 32, 32, 83, 163)
		SpriteFrame(-24, -16, 48, 32, 34, 149)
		SpriteFrame(-16, -16, 32, 32, 83, 131)
		SpriteFrame(-4, -16, 8, 32, 189, 131)
		SpriteFrame(-16, -16, 32, 32, 83, 163)
		break
		
	end switch
	
	foreach (TypeName[Sign Post], arrayPos0, ALL_ENTITIES)
		object[arrayPos0].frame = 1
		object[arrayPos0].spinCount = 16
		object[arrayPos0].priority = PRIORITY_XBOUNDS
	next
	
	SetTableValue(TypeName[Sign Post], DebugMode_ObjCount, DebugMode_TypesTable)
	SetTableValue(SignPost_DebugDraw, DebugMode_ObjCount, DebugMode_DrawTable)
	SetTableValue(SignPost_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 // type
			checkResult = object.propertyValue
			break
			
		end switch
	else
		switch editor.variableID
		case EDIT_VAR_PROPVAL // property value
			object.propertyValue = editor.variableValue
			break
			
		case 0 // type
			object.propertyValue = editor.variableValue
			break
			
		end switch
	end if
end event


event RSDKDraw
	DrawSprite(0)
	DrawSprite(1)
end event


event RSDKLoad
	LoadSpriteSheet("Global/Items2.gif")
	SpriteFrame(-24, 16, 48, 16, 34, 214)
	SpriteFrame(-24, -16, 48, 32, 34, 182)
	
	AddEditorVariable("type")
	SetActiveVariable("type")
	AddEnumVariable("Normal", 0)

	// Skip a few entries, these values are used in CD, where this object's code is originally from, but here they do nothing

	AddEnumVariable("Follow Bounds", 3) // This (and the other skipped values) do far more in CD, but in terms of purely S1, this is technically all
end event
