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

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

private alias object.propertyValue : object.pulled

private alias object.value0 : object.timer
private alias object.value1 : object.startPos.y  // Unused
private alias object.value2 : object.originPos.y // Used
private alias object.value3 : object.grabDelay

private alias object.state 			: player.state
private alias object.animation 		: player.animation
private alias object.gravity 		: player.gravity
private alias object.collisionTop 	: player.collisionTop
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.jumpPress 		: player.jumpPress
private alias object.down 			: player.down


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

reserve function PullVine_DebugDraw
reserve function PullVine_DebugSpawn


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

private function PullVine_DebugDraw
	DrawSprite(1)
end function


private function PullVine_DebugSpawn
	CreateTempObject(TypeName[Pull Vine], 0, object.xpos, object.ypos)
	object[tempObjectPos].startPos.y = object[tempObjectPos].ypos
	object[tempObjectPos].yvel = 0x20000
	object[tempObjectPos].originPos.y = object[tempObjectPos].ypos
end function


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

event ObjectUpdate
	if object.pulled == true
		if object.timer < 88
			object.timer++
			object.ypos += object.yvel
		end if
	else
		if object.timer > 0
			object.timer--
			object.ypos -= object.yvel
		end if
	end if
	object.pulled = false

	if object.grabDelay > 0
		object.grabDelay--
	end if

	temp0 = object.ypos
	temp0 += 0x380000
	foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
		if player[currentPlayer].state != Player_State_Static
			if player[currentPlayer].down == false
				if object.grabDelay == 0
					if player[currentPlayer].ypos < temp0
						BoxCollisionTest(C_TOUCH, object.entityPos, -8, 88, 8, 96, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
					else
						BoxCollisionTest(C_TOUCH, object.entityPos, -8, 40, 8, 48, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
					end if

					if checkResult == true
						if player[currentPlayer].gravity == 1
							player[currentPlayer].state = Player_State_Static
							player[currentPlayer].animation = ANI_HANGING
							player[currentPlayer].speed = 0
							player[currentPlayer].xvel = 0
							player[currentPlayer].yvel = 0
							player[currentPlayer].xpos = object.xpos
							player[currentPlayer].ypos = player[currentPlayer].collisionTop
							FlipSign(player[currentPlayer].ypos)
							player[currentPlayer].ypos += 36
							player[currentPlayer].ypos <<= 16
							player[currentPlayer].ypos += object.ypos
							object.pulled |= true
						end if
					end if
				end if
			end if
		else
			BoxCollisionTest(C_TOUCH, object.entityPos, -8, -4, 8, 72, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
			if checkResult == true
				if player[currentPlayer].jumpPress == true
					player[currentPlayer].state = Player_State_Air
					player[currentPlayer].yvel = -0x40000
					player[currentPlayer].gravity = GRAVITY_AIR
					object.grabDelay = 30 // Half a second before the player can grab the vine again
				else
					player[currentPlayer].xpos = object.xpos
					player[currentPlayer].ypos = player[currentPlayer].collisionTop
					FlipSign(player[currentPlayer].ypos)
					player[currentPlayer].ypos += 36
					player[currentPlayer].ypos <<= 16
					player[currentPlayer].ypos += object.ypos
					object.pulled |= true
				end if
			end if
		end if
	next

	if object.frame == 0
		if object.pulled == true
			PlaySfx(SfxName[Catch], false)
		end if
	end if

	object.frame = object.pulled
end event


event ObjectDraw
	// Edit the sprite frame based on how low (or high) the vine should appear
	temp0 = object.ypos
	temp0 -= object.originPos.y
	temp0 >>= 16
	temp1 = 176
	temp1 -= temp0
	temp2 = -40
	temp2 -= temp0
	temp0 += 80
	EditFrame(0, -12, temp2, 24, temp0, 232, temp1)
	
	DrawSprite(0)
end event


event ObjectStartup
	LoadSpriteSheet("MCZ/Objects.gif")

	SpriteFrame(-12, -40, 24, 80, 232, 176)
	SpriteFrame(-12, -40, 24, 80, 232, 176) // Debug mode preview frame, otherwise unused

	foreach (TypeName[Pull Vine], arrayPos0, ALL_ENTITIES)
		object[arrayPos0].originPos.y = object[arrayPos0].ypos
		if object[arrayPos0].propertyValue == 0
			// Moving down variant
			object[arrayPos0].yvel = 0x20000
		else
			// Moving up variant
			object[arrayPos0].yvel = -0x20000
			object[arrayPos0].ypos += 0xB00000
		end if

		object[arrayPos0].startPos.y = object[arrayPos0].ypos
		object[arrayPos0].pulled = false
	next

	SetTableValue(TypeName[Pull Vine], DebugMode_ObjCount, DebugMode_TypesTable)
	SetTableValue(PullVine_DebugDraw, DebugMode_ObjCount, DebugMode_DrawTable)
	SetTableValue(PullVine_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 // pull direction
			checkResult = object.propertyValue
			checkResult &= 1
			break
			
		end switch
	else
		switch editor.variableID
		case EDIT_VAR_PROPVAL // property value
			object.propertyValue = editor.variableValue
			break
			
		case 0 // pull direction
			object.propertyValue = editor.variableValue
			object.propertyValue &= 1
			break
			
		end switch
	end if
end event


event RSDKDraw
	// TODO: maybe something about offsetting the sprite for the up variant, in order to make it closer to how it appears in-game
	DrawSprite(0)
end event


event RSDKLoad
	LoadSpriteSheet("MCZ/Objects.gif")
	SpriteFrame(-12, -40, 24, 80, 232, 176)

	AddEditorVariable("pullDir")
	SetActiveVariable("pullDir")
	AddEnumVariable("down", 0)
	AddEnumVariable("up" , 1)
end event
