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

//-------Aliases-------//
private alias 26 : TYPE_INSTASHIELD
private alias object.value0 : object.angle2
private alias object.value1 : object.frametick
private alias object.value2 : object.targettime

private alias object.value10 : object.targetx
private alias object.value11 : object.targety
private alias object.value12 : object.accelx
private alias object.value13 : object.accely
private alias object.value14 : object.targetdistsq
private alias object.value15 : object.targetpos
private alias object.value16 : shield.parent

reserve function PlayerObject_EnemyPop
reserve function BossTarget
reserve function targetsort
reserve function checktarget
reserve function targetclear



// Static Values

// Tables
public table Target_Table_Pos
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
end table

public table Target_Table_Dist
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
end table

function targetclear
	temp0 = 0
	while temp0 < 22
		SetTableValue(0, temp0, Target_Table_Dist)
		SetTableValue(0, temp0, Target_Table_Pos)
	temp0++
	loop
end function

function checktarget
	CheckEqual(object.entityPos, object[13].value15)
	temp3 = checkResult
	CheckEqual(object.entityPos, object[14].value15)
	temp3 |= checkResult
	CheckEqual(object.entityPos, object[15].value15)
	temp3 |= checkResult
	CheckEqual(object.entityPos, object[16].value15)
	temp3 |= checkResult
	
	if temp3 == 0
		temp0 = 0
		temp2 = 0
		while temp0 < 22
			if temp2 == 0
				GetTableValue(temp1, temp0, Target_Table_Pos)
				if temp1 == object.entityPos
					temp4 = object.xpos
					temp4 -= object[0].xpos
					Abs(temp4)
					temp4 >>= 19
					temp4 *= temp4
					
					temp5 = object.ypos
					temp5 -= object[0].ypos
					Abs(temp5)
					temp5 >>= 19
					temp5 *= temp5
					temp4 += temp5
					
					SetTableValue(temp4, temp0, Target_Table_Dist)
					temp2 = 1
				end if
			end if	
		temp0++
		loop
		
		if temp2 == 0
			temp4 = object.xpos
			temp4 -= object[0].xpos
			Abs(temp4)
			temp4 >>= 19
			temp4 *= temp4
			
			temp5 = object.ypos
			temp5 -= object[0].ypos
			Abs(temp5)
			temp5 >>= 19
			temp5 *= temp5
			temp4 += temp5
					
			SetTableValue(temp4, 21, Target_Table_Dist)
			SetTableValue(object.entityPos, 21, Target_Table_Pos)
		end if
		CallFunction(targetsort)
	end if
end function


function targetsort
	temp0 = 0
	while temp0 < 22
		temp1 = temp0
		temp1++
		while temp1 < 22
			GetTableValue(temp6, temp0, Target_Table_Dist)
			GetTableValue(temp7, temp1, Target_Table_Dist)
			CheckGreater(temp6, temp7)
			temp4 = checkResult
			CheckEqual(temp6, 0)
			temp4 |= checkResult
			if temp4 == 1
				temp5 = temp6
				temp6 = temp7
				temp7 = temp5
				SetTableValue(temp6, temp0, Target_Table_Dist)
				SetTableValue(temp7, temp1, Target_Table_Dist)
				GetTableValue(temp6, temp0, Target_Table_Pos)
				GetTableValue(temp7, temp1, Target_Table_Pos)
				temp5 = temp6
				temp6 = temp7
				temp7 = temp5
				SetTableValue(temp6, temp0, Target_Table_Pos)
				SetTableValue(temp7, temp1, Target_Table_Pos)
			end if			
			temp1++
		loop
		temp0++
	loop
end function

function BossTarget
	temp0 = 0
	foreach (TypeName[Insta Shield], arrayPos0, ALL_ENTITIES)
		if object[arrayPos0].propertyValue == 2
			if object[arrayPos0].state < 3
				if temp0 == 0
					CallFunction(checktarget)
					temp0 = 1
				end if
			end if
		end if
	next
	checkResult = 0
	if saved.gogoplus > 0
		foreach (TypeName[Insta Shield], arrayPos0, ALL_ENTITIES)
			if object[arrayPos0].propertyValue == 2
				if object[arrayPos0].state == 2
					BoxCollisionTest(C_TOUCH, arrayPos0, -8, -8, 8, 8, object.entityPos, -8, -8, 8, 8)
					if checkResult == 1
						if stage.listPos != 18
							arrayPos1 = arrayPos0
							arrayPos1++
							if arrayPos1 > 16
								arrayPos1 = 13
							end if
							object[arrayPos0].state = 0
							object[arrayPos0].value15 = 0
						end if
					end if
				end if
			end if
		next
	end if
end function


function PlayerObject_EnemyPop		
	if saved.gogoplus > 0
		temp0 = 0
		temp1 = object.xpos
		temp1 >>= 16
		temp1 -= screen.xoffset
		temp1 += 0x20
		temp2 = object.ypos
		temp2 >>= 16
		temp2 -= screen.yoffset
		temp2 += 0x20
		temp3 = 0
		temp4 = screen.xsize
		temp4 += 0x40
		temp5 = screen.ysize
		temp5 += 0x40
		
		
		if temp1 >= 0
			if temp1 <= temp4
				if temp2 >= 0
					if temp2 <= temp5
						temp3 = 1
					end if
				end if
			end if
		end if
		
		if temp3 == 1
			foreach (TypeName[Insta Shield], arrayPos0, ALL_ENTITIES)
				switch object[arrayPos0].propertyValue
					case 1
					case 3
						temp0 = 1
						break
					case 2
						if arrayPos0 == 13
							if object[arrayPos0].state < 3
								CallFunction(checktarget)
							end if
						end if
						if object[arrayPos0].state == 2
							if object[arrayPos0].value15 == object.entityPos
								BoxCollisionTest(C_TOUCH, arrayPos0, -8, -8, 8, 8, object.entityPos, -8, -8, 8, 8)
								if checkResult == 1
									arrayPos1 = arrayPos0
									arrayPos1++
									if arrayPos1 > 16
										arrayPos1 = 13
									end if
									object[arrayPos0].state = 0
									object[arrayPos0].value15 = 0
									temp0 = 1
								end if
							end if
						end if
						break
				end switch
			next
		end if
		

			
		if temp0 == 1
			ResetObjectEntity(object.entityPos, TypeName[Blank Object], 0, object.xpos, object.ypos)
			Rand(checkResult, 32)
			if checkResult > 15
				CreateTempObject(animalType1, TypeName[Blank Object], object.xpos, object.ypos)
			else
				CreateTempObject(animalType2, TypeName[Blank Object], object.xpos, object.ypos)
			end if
			object[tempObjectPos].priority = PRIORITY_UNKNOWN
			CreateTempObject(TypeName[Smoke Puff], 0, object.xpos, object.ypos)
			object[tempObjectPos].drawOrder = 4
			CreateTempObject(TypeName[Object Score], object[0].value19, object.xpos, object.ypos)
			object[tempObjectPos].drawOrder = 4
			PlaySfx(SfxName[Destroy], 0)
		
		
			if stage.debugMode == 0
				saveRAM[999]++
			end if		
			switch object[0].value19
			case 0
				player.score += 100
				break
			case 1
				player.score += 200
				break
			case 2
				player.score += 500
				break
			case 3
			case 4
			case 5
			case 6
			case 7
			case 8
			case 9
			case 10
			case 11
			case 12
			case 13
			case 14
				player.score += 1000
				break
			case 15
				player.score += 0x2710
				break
			end switch
			if object[0].value19 < 15
				object[0].value19++
			end if	
		end if
	end if
end function


event ObjectMain
	switch object.propertyValue
		case 0 //Normal Instashield
			arrayPos0 = shield.parent
			if object[arrayPos0].state == PlayerObject_Death
				object.type = TypeName[Blank Object]
			end if
			if object[arrayPos0].state == PlayerObject_Drown
				object.type = TypeName[Blank Object]
			end if
			object.drawOrder = -1
			object.frame++
			if object.frame >= 14
				object.frame = 0
				object.type = TypeName[Blank Object]
			else
				object[shield.parent].value7 = 1
			end if
			if object.type == TypeName[Insta Shield]
				object[arrayPos0].value38 = -24
				object[arrayPos0].value39 = 24
				object[arrayPos0].value40 = -24
				object[arrayPos0].value41 = 24
			else
				object[arrayPos0].value38 = HITBOX_AUTO
				object[arrayPos0].value39 = HITBOX_AUTO
				object[arrayPos0].value40 = HITBOX_AUTO
				object[arrayPos0].value41 = HITBOX_AUTO
			end if
			break
		case 1
			object.drawOrder = 6
			
			if object.frame >= 5
				ResetObjectEntity(object.entityPos, TypeName[Blank Object], 0, object.xpos, object.ypos)
			end if
			break	
		case 2
			object.angle2++
			object.angle2 %= 2
			object.angle += 2
			object.angle += object.angle2
			object.angle %= 256
			
			if PlayerObject_SuperState != 1
				object.state = 3
			end if
			
			if object.entityPos == 13
				if object.state < 3
					PlayerObject_value5++
					if PlayerObject_value5 >= 4
						PlayerObject_value5 = 0
						PlayerObject_value4 += 4
						if PlayerObject_value4 >= 72
							PlayerObject_value4 = 24
						end if
					end if
				else
					PlayerObject_value5++
					if PlayerObject_value5 >= 4
						PlayerObject_value5 = 0
						PlayerObject_value4 -= 4
						if PlayerObject_value4 <= 0
							PlayerObject_value4 = 0
						end if
						if PlayerObject_value4 >= 24
							PlayerObject_value4 = 24
						end if
					end if
				end if
				temp1 = PlayerObject_value4
				GetTableValue(temp0, temp1, PlayerObject_SonicSuperPal)
				SetPaletteEntry(0, 2, temp0)
				GetTableValue(temp0, temp1, PlayerObject_SonicSuperAltPal)
				SetPaletteEntry(1, 2, temp0)
				temp1++
				GetTableValue(temp0, temp1, PlayerObject_SonicSuperPal)
				SetPaletteEntry(0, 3, temp0)
				GetTableValue(temp0, temp1, PlayerObject_SonicSuperAltPal)
				SetPaletteEntry(1, 3, temp0)
				temp1++
				GetTableValue(temp0, temp1, PlayerObject_SonicSuperPal)
				SetPaletteEntry(0, 4, temp0)
				GetTableValue(temp0, temp1, PlayerObject_SonicSuperAltPal)
				SetPaletteEntry(1, 4, temp0)
				temp1++
				GetTableValue(temp0, temp1, PlayerObject_SonicSuperPal)
				SetPaletteEntry(0, 5, temp0)
				GetTableValue(temp0, temp1, PlayerObject_SonicSuperAltPal)
				SetPaletteEntry(1, 5, temp0)
			end if
			
			switch object.state
				case 1
					GetTableValue(object.targetpos, 0, Target_Table_Pos)
					SetTableValue(0, 0, Target_Table_Pos)
					SetTableValue(0, 0, Target_Table_Dist)					
					CallFunction(targetsort)
					if object.targetpos != 0
						object.state++
					end if					
				case 0
					Cos256(temp0, object.angle)
					temp0 <<= 13
					temp0 += object[0].xpos
					
					Sin256(temp1, object.angle)
					temp1 <<= 12
					temp1 += object[0].ypos
					temp1 -= 0x150000
					
					object.targetx = temp0
					object.targety = temp1
					
					if object.state == 0
						temp0 -= object.xpos
						temp0 >>= 16
						Abs(temp0)
						temp1 -= object.ypos
						temp1 >>= 16
						Abs(temp1)
						
						if temp0 <= 3
							if temp1 <= 3
								object.state++
							end if
						end if
					end if
					break
				case 2
					if object.targetpos == 0
						object.state--
					else
						arrayPos0 = object.targetpos
						temp0 = 0
						temp1 = object[arrayPos0].xpos
						temp1 >>= 16
						temp1 -= screen.xoffset
						temp1 += 0x20
						temp2 = object[arrayPos0].ypos
						temp2 >>= 16
						temp2 -= screen.yoffset
						temp2 += 0x20
						temp4 = screen.xsize
						temp4 += 0x40
						temp5 = screen.ysize
						temp5 += 0x40
						
						if temp1 >= 0
							if temp1 <= temp4
								if temp2 >= 0
									if temp2 <= temp5
										temp0 = 1
									end if
								end if
							end if
						end if
						
						if object[arrayPos0].type == TypeName[Blank Object]
							temp0 = 0
						end if
							
						if temp0 == 1
							object.targetx = object[arrayPos0].xpos
							object.targety = object[arrayPos0].ypos
						else
							object.targetpos = 0
							object.targetdistsq = 0
							object.state = 1
						end if
					end if
					break
				case 3
					CallFunction(targetclear)
					object.targetx = screen.xoffset
					object.targetx -= screen.xsize
					object.targetx <<= 16
					
					object.targety = screen.yoffset
					object.targety -= screen.ysize
					object.targety <<= 16
					
					CheckLower(object.xpos, object.targetx)
					temp0 = checkResult
					CheckLower(object.ypos, object.targety)
					temp0 |= checkResult
					
					if temp0 == 1
						ResetObjectEntity(object.entityPos, TypeName[Blank Object], 0, 0, 0)
					end if
					break
			end switch


			
			if object.targetx < object.xpos 
				object.accelx = -0x2000
				if object.xvel > 0
					object.accelx *= 4
				end if
			else
				object.accelx = 0x2000
				if object.xvel < 0
					object.accelx *= 4
				end if			
			end if
			object.xvel += object.accelx
			
			if object.targety < object.ypos 
				object.accely = -0x2000
				if object.yvel > 0
					object.accely *= 4
				end if
			else
				object.accely = 0x2000
				if object.yvel < 0
					object.accely *= 4
				end if			
			end if
			object.yvel += object.accely
			
			object.xpos += object.xvel
			object.ypos += object.yvel			
			break
		case 3
			if object.frame == 0
				screen.shakeX = 4
			end if
			object.frame++
			
			if object.frame >= 5
				ResetObjectEntity(object.entityPos, TypeName[Blank Object], 0, object.xpos, object.ypos)
			end if
			break
	end switch
end event


event ObjectDraw
	switch object.propertyValue
		case 0
			if PlayerObject_SuperState != 1
				arrayPos0 = shield.parent
				DrawSpriteXY(object.frame, object[arrayPos0].xpos, object[arrayPos0].ypos)
			end if
			break
		case 1
			switch object.frame
				case 0
					object.alpha = 224
					break
				case 1
					object.alpha = 255
					break
				case 2
					object.alpha = 224
					break
				case 3
					object.alpha = 192
					break
				case 4
					object.alpha = 160
					break
			end switch
			DrawRect(0, 0, screen.xsize, screen.ysize, color7, color7, color7, object.alpha)
			object.frame++
			break
		case 2
			temp0 = tileLayer[0].ysize
			temp0 <<= 7
			
			temp1 = temp0
			temp1 <<= 15
			temp0 -= 256
			temp0 <<= 16
			
			
			temp2 = object.ypos
			temp2 -= object[0].ypos
			Abs(temp2)
			
			if temp2 > temp1
				if object.ypos > object[0].ypos
					object.ypos -= temp0
				else
					object.ypos += temp0
				end if			
			end if
			if object.xvel < 0
				object.direction = FLIP_X
			else
				object.direction = FLIP_NONE
			end if
			object.frametick++
			object.frametick %= 4
			temp0 = object.frametick
			temp0 /= 2
			temp0 += 15
			DrawSpriteFX(14, FX_FLIP, object.xpos, object.ypos)
			DrawSpriteFX(temp0, FX_FLIP, object.xpos, object.ypos)
			break
	end switch
end event


event ObjectStartup
	LoadSpriteSheet("Global/Items3.gif")
	SpriteFrame(0, 0, 1, 1, 1, 1)
	SpriteFrame(0, 0, 1, 1, 1, 1)
	SpriteFrame(-11, -19, 19, 19, 148, 155)
	SpriteFrame(0, -16, 18, 22, 94, 231)
	SpriteFrame(-3, 0, 27, 23, 113, 228)
	SpriteFrame(-24, -16, 31, 39, 141, 214)
	SpriteFrame(-16, -24, 40, 40, 173, 214)
	SpriteFrame(-24, -16, 41, 40, 214, 214)
	SpriteFrame(0, 0, 1, 1, 1, 1)
	SpriteFrame(0, 0, 1, 1, 1, 1)
	SpriteFrame(0, 0, 1, 1, 1, 1)
	SpriteFrame(0, 0, 1, 1, 1, 1)
	SpriteFrame(0, 0, 1, 1, 1, 1)
	SpriteFrame(0, 0, 1, 1, 1, 1)
	
	SpriteFrame(3, -8, 5, 16, 83, 223)
	SpriteFrame(-8, -8, 11, 16, 50, 175)
	SpriteFrame(-8, -8, 11, 16, 50, 192)
	
end event

event RSDKDraw
	DrawSprite(0)
end event

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