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

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

private alias object.value0  : object.earthquakeType

private alias object.value1  : object.maxPos
private alias object.value2  : object.minPos

// First set of sensor values for knowing whether to hold earthquake values or to reset
private alias object.value3  : object.sensorHold.left
private alias object.value4  : object.sensorHold.top
private alias object.value5  : object.sensorHold.right
private alias object.value6  : object.sensorHold.bottom

// Main set of sensor values, used for sensing if the player's in the actual earthquake area
private alias object.value7  : object.sensorMain.left
private alias object.value8  : object.sensorMain.top
private alias object.value9  : object.sensorMain.right
private alias object.value10 : object.sensorMain.bottom

// Acutal collision sizes for the object to use with player interaction during earthquake
private alias object.value11 : object.colbox.left
private alias object.value12 : object.colbox.top
private alias object.value13 : object.colbox.right
private alias object.value14 : object.colbox.bottom

private alias object.value15 : object.prevPos
private alias object.value16 : object.scrollStartPos

// Reserved object slots
private alias 0 : SLOT_PLAYER1

private alias 0 : EARTHQUAKE_NONE
private alias 1 : EARTHQUAKE_HOLD
private alias 2 : EARTHQUAKE_ACTIVE

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

private alias object.value42 : player.prevGravity


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

private table Earthquake_collisionBoxSizes
	-192, -256, 192, 256
	-192, -320, 192, 320
	-192, -448, 192, 448
	-384, -256, 384, 128
	-448, -448, 448, 448
	-448, -448, 448, 448
end table

private table Earthquake_sensorsMain
	-192,  -640, 1042, 256
	   0,     0,    0,   0 // Two empty ones here because these are in a set of three earquake objects in the HTZ1 scene, so there's only really need to have one hitbox sensor
	   0,     0,    0,   0
	-384,  -896,  600, 128
	-448, -1344,  672, 448
	-448, -1120,  672, 448
end table

private table Earthquake_sensorsHold
	-448,  -640, 1298, 256
	   0,     0,    0,   0
	   0,     0,    0,   0
	-640,  -896,  856, 128
	-704, -1344,  928, 448
	-704, -1120,  928, 448
end table

private table Earthquake_types
	1, 1, 1 // These first three are all the same because they're used in the same earthquake event
	2, 3, 4
end table

private table Earthquake_maxMinPos
	-0xE00000, -0x1400000
	 0x000000, -0x2B40000
	 0x000000, -0x3000000
	 0x000000, -0x3500000
end table

private table Earthquake_scrollStartPos
	0, 0, 0x6800000, 0x11800000
end table


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

event ObjectUpdate
	BoxCollisionTest(C_TOUCH, object.entityPos, object.sensorMain.left, object.sensorMain.top, object.sensorMain.right, object.sensorMain.bottom, SLOT_PLAYER1, 0, 0, 0, 0)
	if checkResult == true
		if HTZSetup_earthquakeState == EARTHQUAKE_NONE
			HTZSetup_earthquakeState = EARTHQUAKE_ACTIVE
			HTZSetup_activeEarthquakeType = object.earthquakeType
			HTZSetup_earthquakePosMax 	  = object.maxPos
			HTZSetup_earthquakePosMin 	  = object.minPos
			hParallax[20].scrollPos 	  = object.scrollStartPos
		end if
	end if

	BoxCollisionTest(C_TOUCH, object.entityPos, object.sensorHold.left, object.sensorHold.top, object.sensorHold.right, object.sensorHold.bottom, SLOT_PLAYER1, 0, 0, 0, 0)
	if checkResult == true
		if HTZSetup_earthquakeState == EARTHQUAKE_NONE
			// Player isn't exactly in active earthquake area, but they're not fully out either,
			// so make the earthquake holds its values in case it's still in view or the player decides to go back
			HTZSetup_earthquakeState 	  = EARTHQUAKE_HOLD
			HTZSetup_activeEarthquakeType = object.earthquakeType
			HTZSetup_earthquakePosMax 	  = object.maxPos
			HTZSetup_earthquakePosMin 	  = object.minPos
			hParallax[20].scrollPos 	  = object.scrollStartPos
		end if
	end if

	foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
		temp0 = object.colbox.top
		temp0 -= object.prevPos
		temp1 = object.colbox.bottom
		temp1 -= object.prevPos

		if object.propertyValue == 3
			// If it's the slope version, then account for its special collision properties
			temp2 = player[currentPlayer].xpos
			temp2 -= object.xpos
			temp2 += 0x1800000
			if temp2 > 0
				temp2 >>= 18
				temp0 += temp2
			end if

			temp0++
			if player[currentPlayer].prevGravity == GRAVITY_GROUND
				if player[currentPlayer].gravity == GRAVITY_AIR
					if player[currentPlayer].xvel > 0
						temp2 = player[currentPlayer].xvel
						temp2 >>= 2
						player[currentPlayer].ypos += temp2
						player[currentPlayer].ypos += 0x20000
					end if
				end if
			end if
		end if

		BoxCollisionTest(C_SOLID, object.entityPos, object.colbox.left, temp0, object.colbox.right, temp1, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
		switch checkResult
		case COL_TOP
			temp0 = HTZSetup_earthquakePos
			temp0 -= object.prevPos
			temp0 <<= 16
			player[currentPlayer].ypos -= temp0
			// [Fallthrough]
		case COL_LEFT
		case COL_RIGHT
			if object.propertyValue == 2
				CallFunction(Player_FireHit)
			end if

			if object.propertyValue == 4
				CallFunction(Player_FireHit)
			end if

			if object.propertyValue == 5
				CallFunction(Player_FireHit)
			end if
			break

		case COL_BOTTOM
			if player[currentPlayer].gravity == GRAVITY_GROUND
				CallFunction(Player_Kill)
			end if
			break
			
		end switch
	next

	foreach (TypeName[Lose Ring], arrayPos0, ACTIVE_ENTITIES)
		if object[arrayPos0].yvel >= 0
			temp0 = object.colbox.top
			temp0 -= object.prevPos
			temp1 = object.colbox.bottom
			temp1 -= object.prevPos
			if object.propertyValue == 3
				temp2 = object[arrayPos0].xpos
				temp2 -= object.xpos
				temp2 += 0x1800000
				if temp2 > 0
					temp2 >>= 18
					temp0 += temp2
				end if
				temp0++
			end if
			temp2 = object[arrayPos0].yvel

			BoxCollisionTest(C_PLATFORM, object.entityPos, object.colbox.left, temp0, object.colbox.right, temp1, arrayPos0, -8, -8, 8, 8)
			if checkResult == true
				object[arrayPos0].yvel = temp2
				temp2 >>= 2
				object[arrayPos0].yvel -= temp2
				FlipSign(object[arrayPos0].yvel)
				if object[arrayPos0].yvel > -0x10000
					object[arrayPos0].yvel = -0x10000
				end if
				object[arrayPos0].gravity = GRAVITY_AIR
			end if
		end if
	next

	object.prevPos = HTZSetup_earthquakePos
end event


event ObjectStartup
	foreach (TypeName[Earthquake], arrayPos0, ALL_ENTITIES)
		object[arrayPos0].priority = PRIORITY_ACTIVE

		// First get the object's target earthquake type based off its property value
		GetTableValue(object[arrayPos0].earthquakeType, object[arrayPos0].propertyValue, Earthquake_types)

		// Then use the earthquake's dedicated type for the next few value searches rather than simply its property value
		temp0 = object[arrayPos0].earthquakeType
		temp0--

		GetTableValue(object[arrayPos0].scrollStartPos, temp0, Earthquake_scrollStartPos)

		temp0 <<= 1
		GetTableValue(object[arrayPos0].maxPos, temp0, Earthquake_maxMinPos)

		temp0++
		GetTableValue(object[arrayPos0].minPos, temp0, Earthquake_maxMinPos)

		// Get the sizes of the earthquake boxes
		temp0 = object[arrayPos0].propertyValue
		temp0 <<= 2
		GetTableValue(object[arrayPos0].colbox.left, temp0, Earthquake_collisionBoxSizes)
		GetTableValue(object[arrayPos0].sensorHold.left, temp0, Earthquake_sensorsHold)
		GetTableValue(object[arrayPos0].sensorMain.left, temp0, Earthquake_sensorsMain)

		temp0++
		GetTableValue(object[arrayPos0].colbox.top, temp0, Earthquake_collisionBoxSizes)
		GetTableValue(object[arrayPos0].sensorHold.top, temp0, Earthquake_sensorsHold)
		GetTableValue(object[arrayPos0].sensorMain.top, temp0, Earthquake_sensorsMain)

		temp0++
		GetTableValue(object[arrayPos0].colbox.right, temp0, Earthquake_collisionBoxSizes)
		GetTableValue(object[arrayPos0].sensorHold.right, temp0, Earthquake_sensorsHold)
		GetTableValue(object[arrayPos0].sensorMain.right, temp0, Earthquake_sensorsMain)

		temp0++
		GetTableValue(object[arrayPos0].colbox.bottom, temp0, Earthquake_collisionBoxSizes)
		GetTableValue(object[arrayPos0].sensorHold.bottom, temp0, Earthquake_sensorsHold)
		GetTableValue(object[arrayPos0].sensorMain.bottom, temp0, Earthquake_sensorsMain)

		if options.vsMode == true
			// No earthquakes in 2P
			ResetObjectEntity(arrayPos0, TypeName[Blank Object], 0, 0, 0)
		end if
	next
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)
end event


event RSDKLoad
	LoadSpriteSheet("Global/Display.gif")
	SpriteFrame(-16, -16, 32, 32, 1, 143)

	AddEditorVariable("type")
	SetActiveVariable("type")
	AddEnumVariable("Ground (Flat)", 		0)
	AddEnumVariable("Ground (Wall)", 		1)
	AddEnumVariable("Lava (Wide, Ver 1)",   2)
	AddEnumVariable("Ground (Sloped)", 		3)
	AddEnumVariable("Lava (Wide, Ver 2)",   4)
	AddEnumVariable("Lava (Wide, Ver 3)",   5)
end event
