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

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

private alias object.value0 : object.stood
private alias object.value1 : object.drawPos.y
private alias object.value2 : object.collisionOffset.y
private alias object.value3 : object.spawnedFireballs
private alias object.value4 : object.amplitude.y

private alias 0 : LARGEPLATFORM_TYPE_ARCH
private alias 1 : LARGEPLATFORM_TYPE_CURVE
private alias 2 : LARGEPLATFORM_TYPE_RECT

private alias 0 : LARGEPLATFORM_STATIC
private alias 1 : LARGEPLATFORM_MOVE_V_SHORTEST
private alias 2 : LARGEPLATFORM_MOVE_V_SHORT
private alias 3 : LARGEPLATFORM_MOVE_V_LONG
private alias 4 : LARGEPLATFORM_MOVE_V_LONGEST
private alias 5 : LARGEPLATFORM_HASTENSION

// GrassFireball Aliases
private alias object.value1 : grassFireball.parentSlot
private alias object.value2 : grassFireball.platformPos
private alias object.value3 : grassFireball.parentType

// Player Aliases
private alias object.xpos : player.xpos
private alias object.ypos : player.ypos

// Debug Mode Aliases
private alias object.value17 : debugMode.currentSelection


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

reserve function LargePlatform_SetupTypes
reserve function LargePlatform_DebugDraw
reserve function LargePlatform_DebugSpawn

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

private value LargePlatform_startDebugID = 0

// ========================
// Tables
// ========================

public table LargePlatform_heightTableArch
	-32, -32, -32, -32, -32, -32, -32, -32, -33, -34, -35, -36, -37, -38, -39, -40, -41, -42, -43, -44, -45, -46, -47, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -48, -47, -46, -45, -44, -43, -42, -41, -40, -39, -38, -37, -36, -35, -34, -33, -32, -32, -32, -32, -32, -32, -32, -32
end table

public table LargePlatform_heightTableCurved
	-33, -34, -35, -36, -37, -38, -39, -40, -41, -42, -43, -44, -45, -46, -47, -48, -49, -50, -51, -52, -53, -54, -55, -56, -57, -58, -59, -60, -61, -62, -63, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54, -53, -52, -51, -50, -49
end table

private table LargePlatform_debugFrameTable
	0, 0
	0, 0
	2, 2
	2, 2
	1
end table

private table LargePlatform_debugStateTable
	1, 2
	3, 4
	1, 2
	3, 4
	5
end table


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

private function LargePlatform_SetupTypes
	if temp0 == 0
		switch object[arrayPos0].state
		case LARGEPLATFORM_MOVE_V_SHORTEST
			object[arrayPos0].ypos -= 0x100000
			object[arrayPos0].amplitude.y = 0x800
			break

		case LARGEPLATFORM_MOVE_V_SHORT
			object[arrayPos0].ypos -= 0x180000
			object[arrayPos0].amplitude.y = 0xC00
			break

		case LARGEPLATFORM_MOVE_V_LONG
			object[arrayPos0].ypos -= 0x200000
			object[arrayPos0].amplitude.y = 0x1000
			break

		case LARGEPLATFORM_MOVE_V_LONGEST
			object[arrayPos0].ypos -= 0x300000
			object[arrayPos0].amplitude.y = 0x1800
			break
			
		end switch
	else
		switch object[arrayPos0].state
		case LARGEPLATFORM_MOVE_V_SHORTEST
			object[arrayPos0].ypos -= 0x100000
			object[arrayPos0].amplitude.y = -0x800
			break

		case LARGEPLATFORM_MOVE_V_SHORT
			object[arrayPos0].ypos -= 0x180000
			object[arrayPos0].amplitude.y = -0xC00
			break

		case LARGEPLATFORM_MOVE_V_LONG
			object[arrayPos0].ypos -= 0x200000
			object[arrayPos0].amplitude.y = -0x1000
			break

		case LARGEPLATFORM_MOVE_V_LONGEST
			object[arrayPos0].ypos -= 0x300000
			object[arrayPos0].amplitude.y = -0x1800
			break
			
		end switch
	end if
end function


private function LargePlatform_DebugDraw
	temp0 = debugMode[0].currentSelection
	temp0 -= LargePlatform_startDebugID
	GetTableValue(temp1, temp0, LargePlatform_debugFrameTable)
	DrawSprite(temp1)
end function


private function LargePlatform_DebugSpawn
	temp0 = debugMode[0].currentSelection
	temp0 -= LargePlatform_startDebugID

	CreateTempObject(TypeName[Large Platform], 0, object.xpos, object.ypos)
	GetTableValue(object[tempObjectPos].frame, temp0, LargePlatform_debugFrameTable)
	GetTableValue(object[tempObjectPos].state, temp0, LargePlatform_debugStateTable)
	arrayPos0 = object[tempObjectPos].entityPos
	temp0 = object.direction
	CallFunction(LargePlatform_SetupTypes)
end function


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

event ObjectUpdate
	switch object.state
	case LARGEPLATFORM_STATIC
		object.angle = 0
		object.amplitude.y = 0
			break
			
		case LARGEPLATFORM_MOVE_V_SHORTEST
		object.angle = oscillation
		object.angle <<= 1
		object.angle += 0x10
		break

	case LARGEPLATFORM_MOVE_V_SHORT
		object.angle = oscillation
		object.angle <<= 1
		object.angle += 0x30
		break

	case LARGEPLATFORM_MOVE_V_LONG
		object.angle = oscillation
		object.angle <<= 1
		object.angle += 0x50
		break

	case LARGEPLATFORM_MOVE_V_LONGEST
		object.angle = oscillation
		object.angle <<= 1
		object.angle += 0x70
		break

	case LARGEPLATFORM_HASTENSION
		if object.stood == true
			if object.angle < 128
				object.angle += 8
			end if
		else
			if object.angle > 0
				object.angle -= 4
			end if
		end if

		object.amplitude.y = 0x800
		if object.angle > 80
			if object.spawnedFireballs == false
				object.spawnedFireballs = true
				CreateTempObject(TypeName[Grass Fireball], 0, object.xpos, object.ypos)
				if object.frame < LARGEPLATFORM_TYPE_RECT
					object[tempObjectPos].xpos -= 0x380000
				else
					object[tempObjectPos].xpos -= 0x180000
				end if
				grassFireball[tempObjectPos].parentSlot = object.entityPos
				grassFireball[tempObjectPos].platformPos = 8
				object[tempObjectPos].drawOrder = 5
				grassFireball[tempObjectPos].parentType = object.frame
			end if
		end if
		break
		
	end switch

	Sin(object.collisionOffset.y, object.angle)
	object.collisionOffset.y *= object.amplitude.y
	object.collisionOffset.y += object.ypos
	object.collisionOffset.y &= 0xFFFF0000
	object.collisionOffset.y -= object.drawPos.y

	object.stood = false
	temp0 = object.ypos
	object.ypos = object.drawPos.y
	foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
		switch object.frame
		case LARGEPLATFORM_TYPE_ARCH
			temp1 = player[currentPlayer].xpos
			temp1 -= object.xpos
			temp1 >>= 17
			temp1 += 32
			if temp1 < 0
				temp1 = 0
			end if
			if temp1 > 63
				temp1 = 63
			end if
			GetTableValue(temp2, temp1, LargePlatform_heightTableArch)
			BoxCollisionTest(C_SOLID, object.entityPos, -64, temp2, 64, 32, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
			temp2 -= 3

			BoxCollisionTest(C_PLATFORM, object.entityPos, -64, temp2, 64, 32, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
			if checkResult == true
				player[currentPlayer].ypos += 0x40000
				player[currentPlayer].ypos += object.collisionOffset.y
				object.stood = true
			end if
			break

		case LARGEPLATFORM_TYPE_CURVE
			temp1 = player[currentPlayer].xpos
			temp1 -= object.xpos
			temp1 >>= 17
			temp1 += 32
			if temp1 < 0
				temp1 = 0
			end if
			if temp1 > 63
				temp1 = 63
			end if
			GetTableValue(temp2, temp1, LargePlatform_heightTableCurved)
			BoxCollisionTest(C_SOLID, object.entityPos, -64, temp2, 64, 32, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
			temp2 -= 3

			BoxCollisionTest(C_PLATFORM, object.entityPos, -64, temp2, 64, 32, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
			if checkResult == true
				player[currentPlayer].ypos += 0x40000
				player[currentPlayer].ypos += object.collisionOffset.y
				object.stood = true
			end if
			break

		case LARGEPLATFORM_TYPE_RECT
			BoxCollisionTest(C_SOLID, object.entityPos, -32, -47, 32, 32, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
			temp2 -= 3

			BoxCollisionTest(C_PLATFORM, object.entityPos, -32, -51, 32, 32, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
			if checkResult == true
				player[currentPlayer].ypos += 0x40000
				player[currentPlayer].ypos += object.collisionOffset.y
				object.stood = true
			end if
			break
			
		end switch
	next
	object.ypos = temp0

	Sin(object.drawPos.y, object.angle)
	object.drawPos.y *= object.amplitude.y
	object.drawPos.y += object.ypos
	object.drawPos.y &= 0xFFFF0000
end event


event ObjectDraw
	DrawSpriteXY(object.frame, object.xpos, object.drawPos.y)
end event


event ObjectStartup
	LoadSpriteSheet("MZ/Objects.gif")
	SpriteFrame(-64, -48, 128, 80, 1, 324)
	SpriteFrame(-64, -64, 128, 96, 317, 396)
	SpriteFrame(-32, -48, 64, 96, 446, 396)

	foreach (TypeName[Large Platform], arrayPos0, ALL_ENTITIES)
		object[arrayPos0].frame = object[arrayPos0].propertyValue
		object[arrayPos0].frame >>= 4
		object[arrayPos0].frame %= 3

		object[arrayPos0].state = object[arrayPos0].propertyValue
		object[arrayPos0].state &= 7
		if object[arrayPos0].state > LARGEPLATFORM_HASTENSION
			object[arrayPos0].state = LARGEPLATFORM_STATIC
		end if

		temp0 = object[arrayPos0].propertyValue
		temp0 &= 15
		temp0 >>= 3
		CallFunction(LargePlatform_SetupTypes)

		object[arrayPos0].drawOrder = 5
	next

	temp0 = 0
	LargePlatform_startDebugID = DebugMode_ObjCount
	while temp0 < 9
		SetTableValue(TypeName[Large Platform], DebugMode_ObjCount, DebugMode_TypesTable)
		SetTableValue(LargePlatform_DebugDraw, DebugMode_ObjCount, DebugMode_DrawTable)
		SetTableValue(LargePlatform_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 // frameID
			checkResult = object.propertyValue
			checkResult >>= 4
			checkResult %= 3
			break
			
		case 1 // type
			checkResult = object.propertyValue
			checkResult &= 7
			if checkResult > LARGEPLATFORM_HASTENSION
				checkResult = LARGEPLATFORM_STATIC
			end if
			break
			
		case 2 // startDir
			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 // frameID
			temp1 = 0x70
			Not(temp1)
			object.propertyValue &= temp1

			editor.variableValue &= 3
			editor.variableValue <<= 4
			object.propertyValue |= editor.variableValue
			break
			
		case 1 // type
			temp1 = 7
			Not(temp1)
			object.propertyValue &= temp1

			temp0 = editor.variableValue
			temp0 &= 7
			object.propertyValue |= temp0
			break
			
		case 3 // startDir
			CheckNotEqual(editor.variableValue, false)
			SetBit(object.propertyValue, 3, checkResult)
			break
			
		end switch
	end if
end event


event RSDKDraw
	object.frame = object.propertyValue
	object.frame >>= 4
	object.frame %= 3

	DrawSprite(object.frame)
end event


event RSDKLoad
	LoadSpriteSheet("MZ/Objects.gif")
	SpriteFrame(-64, -48, 128, 80, 1, 324)
	SpriteFrame(-64, -64, 128, 96, 317, 396)
	SpriteFrame(-32, -48, 64, 96, 446, 396)

	AddEditorVariable("frameID")
	SetActiveVariable("frameID")
	AddEnumVariable("Arch", LARGEPLATFORM_TYPE_ARCH)
	AddEnumVariable("Curved", LARGEPLATFORM_TYPE_CURVE)
	AddEnumVariable("Rectangular", LARGEPLATFORM_TYPE_RECT)

	AddEditorVariable("moveType")
	SetActiveVariable("moveType")
	AddEnumVariable("Static", LARGEPLATFORM_STATIC)
	AddEnumVariable("Move Vertically (Shortest)", LARGEPLATFORM_MOVE_V_SHORTEST)
	AddEnumVariable("Move Vertically (Short)", LARGEPLATFORM_MOVE_V_SHORT)
	AddEnumVariable("Move Vertically (Long)", LARGEPLATFORM_MOVE_V_LONG)
	AddEnumVariable("Move Vertically (Longest)", LARGEPLATFORM_MOVE_V_LONGEST)
	AddEnumVariable("Spawn Fireballs When Stood", LARGEPLATFORM_HASTENSION)

	AddEditorVariable("startDir")
	SetActiveVariable("startDir")
	AddEnumVariable("Down", 0)
	AddEnumVariable("Up", 1)
end event
