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

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

private alias object.value0 : object.timer
private alias object.value1 : object.isPlatform
private alias object.value7 : object.enabledInAir

// Player aliases
private alias object.state : player.state
private alias object.direction : player.direction
private alias object.xvel : player.xvel
private alias object.yvel : player.yvel
private alias object.speed : player.speed
private alias object.angle : player.angle
private alias object.controlLock : player.controlLock
private alias object.pushing : player.pushing
private alias object.animation : player.animation
private alias object.animationSpeed : player.animationSpeed
private alias object.gravity  : player.gravity
private alias object.collisionMode : player.collisionMode
private alias object.tileCollisions : player.tileCollisions
private alias object.value1  : player.timer
private alias object.value10 : player.animationReserve
private alias object.value17 : debugMode.currentSelection

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

reserve function RedSpring_DebugDraw
reserve function RedSpring_DebugSpawn


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

private value RedSpring_startDebugID = 0


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

private function RedSpring_DebugDraw
	temp0 = debugMode[0].currentSelection
	temp0 -= RedSpring_startDebugID

	DrawSprite(temp0)

	temp0 += 4
	DrawSprite(temp0)
end function


private function RedSpring_DebugSpawn
	temp0 = debugMode[0].currentSelection
	temp0 -= RedSpring_startDebugID
	
	CreateTempObject(TypeName[Red Spring], temp0, object.xpos, object.ypos)
end function


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

event ObjectUpdate
	foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
		switch object.propertyValue
		case 0 // Up
			temp0 = object.isPlatform
			if player[currentPlayer].gravity == GRAVITY_AIR
				temp0 = true
			end if

			if player[currentPlayer].collisionMode > CMODE_FLOOR
				if player[currentPlayer].yvel < 0
					temp0 = true
				end if
			end if

			if temp0 == false
				BoxCollisionTest(C_SOLID, object.entityPos, -14, -8, 14, 8, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)

				BoxCollisionTest(C_TOUCH, object.entityPos, -14, -10, 14, -6, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
				if checkResult == true
					player[currentPlayer].animationReserve = ANI_WALKING
					if player[currentPlayer].animation == ANI_RUNNING
						player[currentPlayer].animationReserve = ANI_RUNNING
					end if

					if player[currentPlayer].animation == ANI_PEELOUT
						player[currentPlayer].animationReserve = ANI_PEELOUT
					end if

					object.timer = 1
					player[currentPlayer].state = Player_State_Air
					player[currentPlayer].tileCollisions = true
					player[currentPlayer].gravity = GRAVITY_AIR
					player[currentPlayer].speed = player[currentPlayer].xvel
					player[currentPlayer].yvel = -0x100000
					player[currentPlayer].animation = ANI_BOUNCING
					player[currentPlayer].timer = 0
					PlaySfx(SfxName[Spring], false)
				end if
			else
				if player[currentPlayer].yvel >= 0
					BoxCollisionTest(C_PLATFORM, object.entityPos, -14, -8, 14, 8, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)

					BoxCollisionTest(C_TOUCH, object.entityPos, -14, -10, 14, -6, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
					if checkResult == true
						player[currentPlayer].animationReserve = ANI_WALKING
						if player[currentPlayer].animation == ANI_RUNNING
							player[currentPlayer].animationReserve = ANI_RUNNING
						end if

						if player[currentPlayer].animation == ANI_PEELOUT
							player[currentPlayer].animationReserve = ANI_PEELOUT
						end if

						object.timer = 1
						player[currentPlayer].state = Player_State_Air
						player[currentPlayer].tileCollisions = true
						player[currentPlayer].gravity = GRAVITY_AIR
						player[currentPlayer].speed = player[currentPlayer].xvel
						player[currentPlayer].yvel = -0x100000
						player[currentPlayer].animation = ANI_BOUNCING
						player[currentPlayer].timer = 0
						PlaySfx(SfxName[Spring], false)
					end if
				end if
			end if
			break

		case 1 // Right
			BoxCollisionTest(C_SOLID, object.entityPos, -8, -14, 8, 14, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
			if player[currentPlayer].gravity == GRAVITY_GROUND
				BoxCollisionTest(C_TOUCH, object.entityPos, 6, -14, 11, 14, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
				if checkResult == true
					object.timer = 1
					player[currentPlayer].tileCollisions = true
					player[currentPlayer].angle = 0
					player[currentPlayer].speed = 0x100000
					player[currentPlayer].collisionMode = CMODE_FLOOR
					player[currentPlayer].pushing = 0
					player[currentPlayer].direction = FACING_RIGHT
					player[currentPlayer].controlLock = 12
					PlaySfx(SfxName[Spring], false)

					if player[currentPlayer].state != Player_State_Roll
						player[currentPlayer].state = Player_State_Ground
						player[currentPlayer].animation = ANI_RUNNING
					end if
				end if
			else
				if object.enabledInAir == true
					BoxCollisionTest(C_TOUCH, object.entityPos, 6, -4, 11, 4, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
					if checkResult == true
						object.timer = 1
						player[currentPlayer].tileCollisions = true
						player[currentPlayer].angle = 0
						player[currentPlayer].speed = 0x100000
						player[currentPlayer].yvel = 0
						player[currentPlayer].collisionMode = CMODE_FLOOR
						player[currentPlayer].pushing = 0
						player[currentPlayer].direction = FACING_RIGHT
						player[currentPlayer].controlLock = 12
						PlaySfx(SfxName[Spring], false)
						if player[currentPlayer].state != Player_State_RollJump
							player[currentPlayer].animation = ANI_BOUNCING
							if player[currentPlayer].animation != ANI_JUMPING
								player[currentPlayer].animation = ANI_RUNNING
							end if

							object.animationSpeed = object.speed
							player[currentPlayer].animationSpeed *= 80
							player[currentPlayer].animationSpeed /= 0x60000
						end if
					end if
				end if
			end if
			break

		case 2 // Left
			BoxCollisionTest(C_SOLID, object.entityPos, -8, -14, 8, 14, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
			if player[currentPlayer].gravity == GRAVITY_GROUND
				BoxCollisionTest(C_TOUCH, object.entityPos, -10, -14, -6, 14, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
				if checkResult == true
					object.timer = 1
					player[currentPlayer].tileCollisions = true
					player[currentPlayer].speed = -0x100000
					player[currentPlayer].collisionMode = CMODE_FLOOR
					player[currentPlayer].pushing = 0
					player[currentPlayer].direction = FACING_LEFT
					player[currentPlayer].controlLock = 15
					PlaySfx(SfxName[Spring], false)
					if player[currentPlayer].state != Player_State_Roll
						player[currentPlayer].state = Player_State_Ground
						player[currentPlayer].animation = ANI_RUNNING
					end if
				end if
			else
				if object.enabledInAir == true
					BoxCollisionTest(C_TOUCH, object.entityPos, -10, -14, -6, 14, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
					if checkResult == true
						object.timer = 1
						player[currentPlayer].tileCollisions = true
						player[currentPlayer].speed = -0x100000
						player[currentPlayer].yvel = 0
						player[currentPlayer].collisionMode = CMODE_FLOOR
						player[currentPlayer].pushing = 0
						player[currentPlayer].direction = FACING_LEFT
						player[currentPlayer].controlLock = 15
						PlaySfx(SfxName[Spring], false)
						if player[currentPlayer].state != Player_State_RollJump
							player[currentPlayer].animation = ANI_BOUNCING
							if player[currentPlayer].animation != ANI_JUMPING
								player[currentPlayer].animation = ANI_RUNNING
							end if

							object.animationSpeed = object.speed
							FlipSign(player[currentPlayer].animationSpeed)
							player[currentPlayer].animationSpeed *= 80
							player[currentPlayer].animationSpeed /= 0x60000
						end if
					end if
				end if
			end if
			break

		case 3 // Down
			BoxCollisionTest(C_SOLID, object.entityPos, -14, -8, 14, 8, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
			if player[currentPlayer].yvel <= 0
				BoxCollisionTest(C_TOUCH, object.entityPos, -14, 6, 14, 10, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
				if checkResult == true
					if player[currentPlayer].collisionMode == CMODE_ROOF
						FlipSign(player[currentPlayer].speed)
						FlipSign(player[currentPlayer].xvel)
					end if

					object.timer = 1
					player[currentPlayer].state = Player_State_Air
					player[currentPlayer].tileCollisions = true
					player[currentPlayer].gravity = GRAVITY_AIR
					player[currentPlayer].speed = player[currentPlayer].xvel
					player[currentPlayer].yvel = 0x100000
					player[currentPlayer].timer = 0
					PlaySfx(SfxName[Spring], false)
				end if
			end if
			break
			
		end switch
	next
end event


event ObjectDraw
	if object.timer == 0
		temp1 = object.propertyValue
		DrawSpriteFX(temp1, FX_FLIP, object.xpos, object.ypos)
		temp1 += 4
		DrawSpriteFX(temp1, FX_FLIP, object.xpos, object.ypos)
	else
		switch object.timer
		case 2
		case 3
			temp1 = object.propertyValue
			DrawSpriteFX(temp1, FX_FLIP, object.xpos, object.ypos)
			temp1 += 4
			DrawSpriteFX(temp1, FX_FLIP, object.xpos, object.ypos)
			break

		case 1
			temp1 = object.propertyValue
			temp1 += 8
			DrawSpriteFX(temp1, FX_FLIP, object.xpos, object.ypos)
			break

		case 4
		case 5
		case 6
		case 7
		case 8
		case 9
			temp1 = object.propertyValue
			temp1 += 12
			DrawSpriteFX(temp1, FX_FLIP, object.xpos, object.ypos)
			temp1 += 4
			DrawSpriteFX(temp1, FX_FLIP, object.xpos, object.ypos)
			break
			
		end switch

		object.timer++
		if object.timer >= 10
			object.timer = 0
		end if
	end if
end event


event ObjectStartup
	LoadSpriteSheet("Global/Items.gif")

	arrayPos0 = 0x20
	while arrayPos0 < 0x420
		if object[arrayPos0].type == TypeName[Red Spring]
			if object[arrayPos0].propertyValue > 3
				object[arrayPos0].propertyValue -= 4
				object[arrayPos0].enabledInAir = true
			end if

			// ???
			// states are 0-3, and if bit 3 is set its removed, so this can never be hit right?
			if object[arrayPos0].propertyValue > 5
				object[arrayPos0].direction = FLIP_Y
			end if
		end if
		
		arrayPos0++
	loop

	SpriteFrame(-16, 0, 32, 8, 84, 9)
	SpriteFrame(-8, -16, 8, 32, 141, 26)
	SpriteFrame(0, -16, 8, 32, 141, 59)
	SpriteFrame(-16, -8, 32, 8, 150, 101)
	SpriteFrame(-16, -8, 32, 8, 84, 1)
	SpriteFrame(0, -16, 8, 32, 149, 26)
	SpriteFrame(-8, -16, 8, 32, 133, 59)
	SpriteFrame(-16, 0, 32, 8, 150, 109)
	SpriteFrame(-16, 0, 32, 8, 84, 1)
	SpriteFrame(-8, -16, 8, 32, 149, 26)
	SpriteFrame(0, -16, 8, 32, 133, 59)
	SpriteFrame(-16, -8, 32, 8, 150, 109)
	SpriteFrame(-16, -16, 32, 24, 117, 1)
	SpriteFrame(-8, -16, 24, 32, 158, 26)
	SpriteFrame(-16, -16, 24, 32, 158, 59)
	SpriteFrame(-16, -8, 32, 24, 150, 1)
	SpriteFrame(-16, -24, 32, 8, 84, 1)
	SpriteFrame(16, -16, 8, 32, 149, 26)
	SpriteFrame(-24, -16, 8, 32, 133, 59)
	SpriteFrame(-16, 16, 32, 8, 150, 109)

	temp0 = 0
	RedSpring_startDebugID = DebugMode_ObjCount
	while temp0 < 4
		SetTableValue(TypeName[Red Spring], DebugMode_ObjCount, DebugMode_TypesTable)
		SetTableValue(RedSpring_DebugDraw, DebugMode_ObjCount, DebugMode_DrawTable)
		SetTableValue(RedSpring_DebugSpawn, DebugMode_ObjCount, DebugMode_SpawnTable)
		DebugMode_ObjCount++
		temp0++
	loop
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 // flipFlags
			checkResult = object.propertyValue
			checkResult &= 3
			break
			
		case 1 // enabledInAir
			GetBit(checkResult, object.propertyValue, 3)
			break
			
		end switch
	else
		switch editor.variableID
		case EDIT_VAR_PROPVAL // property value
			object.propertyValue = editor.variableValue
			break
			
		case 0 // flipFlags
			temp0 = 3
			Not(temp0)
			object.propertyValue &= temp0
			editor.variableValue &= 3

			object.propertyValue |= editor.variableValue
			break
			
		case 1 // enabledInAir
			CheckNotEqual(editor.variableValue, false)
			SetBit(object.propertyValue, 3, checkResult)
			break
			
		end switch
	end if
end event


event RSDKDraw
	temp1 = object.propertyValue
	temp1 &= 3

	DrawSpriteFX(temp1, FX_FLIP, object.xpos, object.ypos)

	temp1 += 4
	DrawSpriteFX(temp1, FX_FLIP, object.xpos, object.ypos)
end event


event RSDKLoad
	LoadSpriteSheet("Global/Items.gif")
	SpriteFrame(-16, 0, 32, 8, 84, 9)
	SpriteFrame(-8, -16, 8, 32, 141, 26)
	SpriteFrame(0, -16, 8, 32, 141, 59)
	SpriteFrame(-16, -8, 32, 8, 150, 101)
	SpriteFrame(-16, -8, 32, 8, 84, 1)
	SpriteFrame(0, -16, 8, 32, 149, 26)
	SpriteFrame(-8, -16, 8, 32, 133, 59)
	SpriteFrame(-16, 0, 32, 8, 150, 109)
	SpriteFrame(-16, 0, 32, 8, 84, 1)
	SpriteFrame(-8, -16, 8, 32, 149, 26)
	SpriteFrame(0, -16, 8, 32, 133, 59)
	SpriteFrame(-16, -8, 32, 8, 150, 109)
	SpriteFrame(-16, -16, 32, 24, 117, 1)
	SpriteFrame(-8, -16, 24, 32, 158, 26)
	SpriteFrame(-16, -16, 24, 32, 158, 59)
	SpriteFrame(-16, -8, 32, 24, 150, 1)
	SpriteFrame(-16, -24, 32, 8, 84, 1)
	SpriteFrame(16, -16, 8, 32, 149, 26)
	SpriteFrame(-24, -16, 8, 32, 133, 59)
	SpriteFrame(-16, 16, 32, 8, 150, 109)

	AddEditorVariable("flipFlag")
	SetActiveVariable("flipFlag")
	AddEnumVariable("Up", 0)
	AddEnumVariable("Right", 1)
	AddEnumVariable("Left", 2)
	AddEnumVariable("Down", 3)

	AddEditorVariable("enabledInAir")
	SetActiveVariable("enabledInAir")
	AddEnumVariable("false", false)
	AddEnumVariable("true", true)

	SetVariableAlias(ALIAS_VAR_VAL1, "isPlatform")
	
	// TODO: scale is set to 256 (half) in a mission, M005, does this mean anything?
end event
