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

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

private alias object.value1 : object.startPos.y
private alias object.value2 : object.targetVelDest.y
private alias object.value3 : object.targetVelStart.y
private alias object.value4 : object.targetPos.y
private alias object.value5 : object.collisionOffset.y
private alias object.value6 : object.stood
private alias object.value7 : object.canReset

// States
private alias 0 : ELEVATOR_READY
private alias 1 : ELEVATOR_MOVETOTARGET
private alias 2 : ELEVATOR_REACHEDTARGET
private alias 3 : ELEVATOR_RETURNTOSTART
private alias 4 : ELEVATOR_WAITFORFINISH

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


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

reserve function Elevator_DebugDraw
reserve function Elevator_DebugSpawn


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

private function Elevator_DebugDraw
	DrawSprite(0)
end function


private function Elevator_DebugSpawn
	CreateTempObject(TypeName[Elevator], 0, object.xpos, object.ypos)
	object[tempObjectPos].startPos.y = object.ypos
	object[tempObjectPos].targetVelDest.y -= 0x200000
	object[tempObjectPos].targetPos.y -= 0x400000
end function


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

event ObjectUpdate
	temp6 = object.ypos
	switch object.state
	case ELEVATOR_READY
		if object.stood == true
			object.state = ELEVATOR_MOVETOTARGET
			if object.priority != PRIORITY_XBOUNDS_DESTROY
				object.priority = PRIORITY_ACTIVE
			end if
			PlaySfx(SfxName[Elevator], false)
		else
			foreach (TypeName[Elevator], arrayPos0, ACTIVE_ENTITIES)
				if object.entityPos != arrayPos0
					if object[arrayPos0].state == ELEVATOR_MOVETOTARGET
						BoxCollisionTest(C_TOUCH, object.entityPos, -16, -8, 16, 8, arrayPos0, -16, -56, 16, 8)
						if checkResult == true
							object.state = ELEVATOR_WAITFORFINISH
							object.canReset = false
						end if
					end if
				end if
			next
		end if
		break

	case ELEVATOR_MOVETOTARGET
		if object.ypos >= object.targetVelDest.y
			object.yvel -= 0x800
		else
			object.yvel += 0x800
		end if
		object.ypos += object.yvel

		if object.propertyValue == 0
			if object.ypos <= object.targetPos.y
				object.ypos = object.targetPos.y
				object.yvel = 0
				object.state = ELEVATOR_REACHEDTARGET
			end if
		else
			if object.ypos >= object.targetPos.y
				object.ypos = object.targetPos.y
				object.yvel = 0
				object.state = ELEVATOR_REACHEDTARGET
			end if
		end if
		break

	case ELEVATOR_REACHEDTARGET
		if object.stood == false
			PlaySfx(SfxName[Elevator], false)
			object.state = ELEVATOR_RETURNTOSTART
		end if
		break

	case ELEVATOR_RETURNTOSTART
		if object.ypos >= object.targetVelStart.y
			object.yvel -= 0x800
		else
			object.yvel += 0x800
		end if
		object.ypos += object.yvel

		if object.propertyValue == 0
			if object.ypos >= object.startPos.y
				object.ypos = object.startPos.y
				object.yvel 	= 0
				object.state 	= ELEVATOR_READY
			end if
		else
			if object.ypos <= object.startPos.y
				object.ypos = object.startPos.y
				object.yvel 	= 0
				object.state 	= ELEVATOR_READY
			end if
		end if
		break

	case ELEVATOR_WAITFORFINISH
		if object.canReset == true
			object.state = ELEVATOR_READY
		end if
		object.canReset = true
		break
		
	end switch

	object.stood = false
	temp0 = object.ypos
	temp6 &= 0xFFFF0000
	object.collisionOffset.y = object.ypos
	object.collisionOffset.y &= 0xFFFF0000
	object.collisionOffset.y -= temp6

	object.ypos = temp6
	foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
		switch object.state
		case ELEVATOR_READY
		case ELEVATOR_MOVETOTARGET
		case ELEVATOR_REACHEDTARGET
			BoxCollisionTest(C_TOUCH, object.entityPos, -48, -64, 48, 8, currentPlayer, 0, C_BOX, 0, C_BOX)
			if checkResult == true
				player[currentPlayer].collisionPlane = 0
			end if

			BoxCollisionTest(C_TOUCH, object.entityPos, -20, -32, 20, 8, currentPlayer, 0, C_BOX, 0, C_BOX)
			if checkResult == true
				player[currentPlayer].collisionPlane = 1
			end if

			BoxCollisionTest(C_PLATFORM, object.entityPos, -16, -8, 16, 8, currentPlayer, 0, C_BOX, 0, C_BOX)
			if checkResult == true
				player[currentPlayer].ypos += object.collisionOffset.y
				player[currentPlayer].collisionPlane = 1
				object.stood = true
			end if
			break

		case ELEVATOR_RETURNTOSTART
			BoxCollisionTest(C_TOUCH, object.entityPos, -48, -64, 48, 8, currentPlayer, 0, C_BOX, 0, C_BOX)
			if checkResult == true
				player[currentPlayer].collisionPlane = 0
			end if
			// [Fallthrough]
		case ELEVATOR_WAITFORFINISH
			BoxCollisionTest(C_TOUCH, object.entityPos, -20, -32, 20, 8, currentPlayer, 0, C_BOX, 0, C_BOX)
			if checkResult == true
				object.canReset = false
			end if
		break
		end switch
	next

	object.ypos = temp0
	if object.outOfBounds == true
		temp0 = object.ypos
		object.ypos = object.startPos.y
		if object.outOfBounds == true
			object.state = ELEVATOR_READY
			if object.priority != PRIORITY_XBOUNDS_DESTROY
				object.priority = PRIORITY_BOUNDS
			end if
			object.stood = 0
			object.yvel = 0
		else
			object.ypos = temp0
		end if
	end if
end event


event ObjectDraw
	DrawSprite(0)
end event


event ObjectStartup
	LoadSpriteSheet("CNZ/Objects.gif")
	SpriteFrame(-16, -8, 32, 16, 193, 34)

	foreach (TypeName[Elevator], arrayPos0, ALL_ENTITIES)
		object[arrayPos0].startPos.y = object[arrayPos0].ypos
		object[arrayPos0].targetVelDest.y = object[arrayPos0].ypos
		object[arrayPos0].targetVelStart.y = object[arrayPos0].ypos
		object[arrayPos0].targetPos.y = object[arrayPos0].ypos

		temp0 = object[arrayPos0].propertyValue
		temp0 &= 0x7F
		temp0 <<= 18

		object[arrayPos0].propertyValue >>= 7
		if object[arrayPos0].propertyValue == 1
			object[arrayPos0].ypos -= temp0
			object[arrayPos0].startPos.y -= temp0
			object[arrayPos0].targetPos.y += temp0
			object[arrayPos0].targetVelDest.y += 0x20000
			object[arrayPos0].targetVelStart.y -= 0x20000
		else
			object[arrayPos0].ypos += temp0
			object[arrayPos0].startPos.y += temp0
			object[arrayPos0].targetPos.y -= temp0
		end if
	next

	SetTableValue(TypeName[Elevator], DebugMode_ObjCount, DebugMode_TypesTable)
	SetTableValue(Elevator_DebugDraw, DebugMode_ObjCount, DebugMode_DrawTable)
	SetTableValue(Elevator_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 // distance
			checkResult = object.propertyValue
			checkResult &= 0x7F
			break
			
		case 1 // direction
			GetBit(checkResult, object.propertyValue, 7)
			break
			
		end switch
	else
		switch editor.variableID
		case EDIT_VAR_PROPVAL // property value
			object.propertyValue = editor.variableValue
			break
			
		case 0 // distance
			editor.variableValue &= 0x7F
			object.propertyValue &= 0x80

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


event RSDKDraw
	DrawSprite(0)

	if editor.showGizmos == true
		editor.drawingOverlay = true
		
		object.startPos.y  = object.ypos
		object.targetPos.y = object.ypos

		temp0 = object.propertyValue
		temp0 &= 0x7F
		temp0 <<= 18

		GetBit(checkResult, object.propertyValue, 7)
		if checkResult == true
			object.startPos.y  -= temp0
			object.targetPos.y += temp0
		else
			object.startPos.y  += temp0
			object.targetPos.y -= temp0
		end if

		object.inkEffect = INK_BLEND
		
		DrawSpriteFX(0, FX_INK, object.xpos, object.startPos.y)
		DrawSpriteFX(0, FX_INK, object.xpos, object.targetPos.y)
		
		object.inkEffect = INK_NONE

		DrawArrow(object.xpos, object.startPos.y, object.xpos, object.targetPos.y, 0x00, 0xFF, 0x00)
		
		editor.drawingOverlay = false
	end if
end event


event RSDKLoad
	LoadSpriteSheet("CNZ/Objects.gif")
	SpriteFrame(-16, -8, 32, 16, 193, 34)

	AddEditorVariable("distance")
	SetActiveVariable("distance")

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