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

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

// value0 is inused 
private alias object.value1 : object.processBG

private alias object.value2 : object.aniTilesTimerA
private alias object.value3 : object.aniTilesTimerB

private alias object.value4  : object.palRotateTimerAct1

private alias object.value5  : object.palTimerA
private alias object.value6  : object.palTimerB
private alias object.value7  : object.palTimerC
private alias object.value8  : object.palTimerD
private alias object.value9  : object.palTimerE
// value10 is unused
private alias object.value11 : object.palTimerF
private alias object.value12 : object.palTimerG

private alias object.value13 : object.palIndexA
private alias object.value14 : object.palIndexB
private alias object.value15 : object.palIndexC
private alias object.value16 : object.palIndexD
private alias object.value17 : object.palIndexE
// value18 is unused
private alias object.value19 : object.palIndexF
private alias object.value20 : object.palIndexG

// Tile Flag Aliases
private alias 1 : TILE_CONVEYORBELT

// Tile Info ID Aliases
private alias 1 : TILEINFO_DIRECTION
private alias 8 : TILEINFO_ANGLEB

// Tracks
private alias 0 : TRACK_STAGE
private alias 2 : TRACK_INVINCIBLE

// Reserved object slots
private alias 10 : SLOT_ZONESETUP
private alias 25 : SLOT_MUSICEVENT_CHANGE

private alias 2 : MUSICEVENT_TRANSITION

private alias 0 : MUSICEVENT_FLAG_NOCHANGE
private alias 1 : MUSICEVENT_FLAG_SPEEDUP
private alias 2 : MUSICEVENT_FLAG_SLOWDOWN

// Player Aliases
private alias object.xpos : player.xpos
private alias object.ypos : player.ypos
private alias object.gravity : player.gravity
private alias object.collisionLeft : player.collisionLeft
private alias object.collisionRight : player.collisionRight
private alias object.collisionBottom : player.collisionBottom

// Music Loops
private alias 1     : MUSIC_LOOP_SBZ
private alias 1     : MUSIC_LOOP_SBZ_F

private alias 84680 : MUSIC_LOOP_FINAL

private alias 39528 : MUSIC_LOOP_INV
private alias 30436 : MUSIC_LOOP_INV_F


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

reserve function SBZSetup_BGEffectsAct1
reserve function SBZSetup_BGEffectsAct2
reserve function SBZSetup_SpeedUpMusic
reserve function SBZSetup_SlowDownMusic


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

public value SBZSetup_electricOrbFrame 	= 0
public value SBZSetup_electricOrbTimer 	= 0
public value SBZSetup_platformTimer 	= 0


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

private table SBZSetup_palTableB_1
	0x404000, 0x00A0E0, 0x404000, 0x00A0E0, 0x80E000, 0x80E000, 0x404000, 0xE040E0
end table

private table SBZSetup_palTableC_1
	0xE0E000, 0xE08000, 0xE00000, 0x800000, 0x800000, 0xE00000, 0xE08000, 0xE0E000
end table

private table SBZSetup_palTableD_1
	0xA00000, 0xA00000, 0x800000, 0x600000, 0x400000, 0x400000, 0x600000, 0x800000
end table

private table SBZSetup_palTableE_1
	0xE00000, 0xE00000, 0xA00000, 0x800000, 0x600000, 0x600000, 0x800000, 0xA00000
end table

private table SBZSetup_palTableB_2
	0x60E0C0, 0x60E0C0, 0x40C0A0, 0x20A080, 0x008060, 0x008060, 0x20A080, 0x40C0A0
end table

private table SBZSetup_palTableF_1
	0x00A0E0, 0x6080E0, 0xA060E0, 0xE040E0, 0xE08080, 0xE0A040, 0xE0C020, 0xE0E000
	0xE0E000, 0xE0C020, 0xE0A040, 0xE08080, 0xE040E0, 0xA060E0, 0x6080E0, 0x00A0E0
end table

private table SBZSetup_palTableG_1
	0x00A0E0, 0x00A0E0, 0x4060A0, 0xA04060, 0xE00000, 0xE00000, 0xA04060, 0x4060A0
end table

private table SBZSetup_electricOrbDelayTable
	20, 3, 1, 2, 3, 3
	20, 3, 1, 2, 3, 3
	20, 3, 1, 2, 3, 3
	20, 3, 1, 2, 3, 3
end table

private table SBZSetup_palTableA_1
	0xE0A0E0, 0xE040E0, 0x800080
end table

private table SBZSetup_palTableA_2
	0xE040E0, 0x800080, 0xE0A0E0
end table

private table SBZSetup_palTableA_3
	0x800080, 0xE0A0E0, 0xE040E0
end table

private table SBZSetup_replay_credits_STK_2
	0x15700000, 0x16C0000
	0x00, 6
	0x04, 194
	0x00, 187
	0x04, 35
	0x00, 14
	0x04, 10
	0x00, 24
	0x04, 29
	0x00, 11
	0x08, 198
end table

private table SBZSetup_replay_credits_STK_1
	0x1B00000, 0x72C0000
	0x00, 63
	0x08, 18
	0x00, 113
	0x08, 46
	0x38, 1
	0x28, 7
	0x08, 96
	0x02, 47
	0x00, 43
	0x08, 34
	0x38, 1
	0x28, 16
	0x20, 8
	0x28, 55
end table


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

private function SBZSetup_BGEffectsAct1
	if object.aniTilesTimerA < 65
		temp0 = object.aniTilesTimerA
		temp0 &= 7
		if temp0 == 0
			temp0 = object.aniTilesTimerA
			temp0 &= 63
			temp0 >>= 3
			temp0 <<= 2
			temp0 += 604
			Copy16x16Tile(592, temp0)
			temp0++
			Copy16x16Tile(593, temp0)
			temp0++
			Copy16x16Tile(594, temp0)
		end if
	end if
	object.aniTilesTimerA++
	object.aniTilesTimerA %= 192

	if object.aniTilesTimerB < 65
		temp0 = object.aniTilesTimerB
		temp0 &= 7
		if temp0 == 0
			temp0 = object.aniTilesTimerB
			temp0 &= 63
			temp0 >>= 3
			temp0 <<= 2
			temp0 += 604
			Copy16x16Tile(596, temp0)
			temp0++
			Copy16x16Tile(597, temp0)
			temp0++
			Copy16x16Tile(598, temp0)
		end if
	end if
	object.aniTilesTimerB++
	object.aniTilesTimerB %= 144
	
	object.palRotateTimerAct1++
	if object.palRotateTimerAct1 == 2
		object.palRotateTimerAct1 = 0
		RotatePalette(0, 172, 174, true)
	end if

	object.palTimerD++
	if object.palTimerD == 15
		object.palTimerD = 0
		object.palIndexD++
		object.palIndexD &= 7
		GetTableValue(temp0, object.palIndexD, SBZSetup_palTableD_1)
		SetPaletteEntry(0, 183, temp0)
	end if

	object.palTimerE++
	if object.palTimerE == 12
		object.palTimerE = 0
		object.palIndexE++
		object.palIndexE &= 7
		GetTableValue(temp0, object.palIndexE, SBZSetup_palTableE_1)
		SetPaletteEntry(0, 184, temp0)
	end if
	
	object.palTimerF++
	if object.palTimerF == 29
		object.palTimerF = 0
		object.palIndexF++
		object.palIndexF &= 15
		GetTableValue(temp0, object.palIndexF, SBZSetup_palTableF_1)
		SetPaletteEntry(0, 191, temp0)
	end if
end function


private function SBZSetup_BGEffectsAct2
	RotatePalette(0, 172, 174, true)

	object.palTimerG++
	if object.palTimerG == 10
		object.palTimerG = 0
		object.palIndexG++
		object.palIndexG &= 7
		GetTableValue(temp0, object.palIndexG, SBZSetup_palTableG_1)
		SetPaletteEntry(0, 184, temp0)
	end if

	// Process Conveyor Belts
	foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
		if player[currentPlayer].gravity == 0
			temp2 = player[currentPlayer].ypos
			temp2 >>= 16
			temp2 += player[currentPlayer].collisionBottom
			temp2 += 2
			temp1 = player[currentPlayer].xpos
			temp1 >>= 16
			temp1 += player[currentPlayer].collisionLeft
			temp3 = 0
			Get16x16TileInfo(temp0, temp1, temp2, TILEINFO_ANGLEB)
			if temp0 == TILE_CONVEYORBELT
				Get16x16TileInfo(temp0, temp1, temp2, TILEINFO_DIRECTION)
				if temp0 == FLIP_NONE
					temp3 += 0x20000
				else
					temp3 -= 0x20000
				end if
			end if
			
			temp1 = player[currentPlayer].xpos
			temp1 >>= 16
			temp1 += player[currentPlayer].collisionRight
			Get16x16TileInfo(temp0, temp1, temp2, TILEINFO_ANGLEB)
			if temp0 == TILE_CONVEYORBELT
				Get16x16TileInfo(temp0, temp1, temp2, TILEINFO_DIRECTION)
				if temp0 == FLIP_NONE
					temp3 += 0x20000
					if temp3 > 0x20000
						temp3 = 0x20000
					end if
				else
					temp3 -= 0x20000
					if temp3 < -0x20000
						temp3 = -0x20000
					end if
				end if
			end if

			player[currentPlayer].xpos += temp3
		end if
	next
end function


private function SBZSetup_SpeedUpMusic
	CheckEqual(object[SLOT_MUSICEVENT_CHANGE].type, TypeName[Music Event])
	temp0 = checkResult
	CheckEqual(object[SLOT_MUSICEVENT_CHANGE].propertyValue, MUSICEVENT_TRANSITION)
	temp0 &= checkResult
	CheckEqual(stage.musicFlag, MUSICEVENT_FLAG_NOCHANGE)
	temp0 &= checkResult
	if temp0 == false
		switch music.currentTrack
		case TRACK_STAGE
			SetMusicTrack("Invincibility_F.ogg", TRACK_INVINCIBLE, MUSIC_LOOP_INV_F)
			SwapMusicTrack("ScrapBrain_F.ogg", TRACK_STAGE, MUSIC_LOOP_SBZ_F, 8000)
			break

		case TRACK_INVINCIBLE
			SetMusicTrack("ScrapBrain_F.ogg", TRACK_STAGE, MUSIC_LOOP_SBZ_F)
			SwapMusicTrack("Invincibility_F.ogg", TRACK_INVINCIBLE, MUSIC_LOOP_INV_F, 8000)
			break

		// While other stage setups have a `case TRACK_BOSS` here, SBZ doesn't need it because the boss music never plays there
		end switch
	else
		stage.musicFlag = MUSICEVENT_FLAG_SPEEDUP
	end if
end function


private function SBZSetup_SlowDownMusic
	CheckEqual(object[SLOT_MUSICEVENT_CHANGE].type, TypeName[Music Event])
	temp0 = checkResult
	CheckEqual(object[SLOT_MUSICEVENT_CHANGE].propertyValue, MUSICEVENT_TRANSITION)
	temp0 &= checkResult
	CheckEqual(stage.musicFlag, MUSICEVENT_FLAG_NOCHANGE)
	temp0 &= checkResult
	if temp0 == false
		switch music.currentTrack
		case TRACK_STAGE
			SetMusicTrack("Invincibility.ogg", TRACK_INVINCIBLE, MUSIC_LOOP_INV)
			SwapMusicTrack("ScrapBrain.ogg", TRACK_STAGE, MUSIC_LOOP_SBZ, 12500)
			break

		case TRACK_INVINCIBLE
			SetMusicTrack("ScrapBrain.ogg", TRACK_STAGE, MUSIC_LOOP_SBZ)
			SwapMusicTrack("Invincibility.ogg", TRACK_INVINCIBLE, MUSIC_LOOP_INV, 12500)
			break

		// While other stage setups have a `case TRACK_BOSS` here, SBZ doesn't need it because the boss music never plays here
		end switch
	else
		stage.musicFlag = MUSICEVENT_FLAG_SLOWDOWN
	end if
end function


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

event ObjectUpdate
	CallFunction(object.processBG)

	SBZSetup_platformTimer++
	if SBZSetup_electricOrbTimer > 1
		SBZSetup_electricOrbTimer--
	else
		SBZSetup_electricOrbFrame++
		SBZSetup_electricOrbFrame %= 24
		GetTableValue(SBZSetup_electricOrbTimer, SBZSetup_electricOrbFrame, SBZSetup_electricOrbDelayTable)
	end if

	object.palTimerA++
	if object.palTimerA == 4
		object.palTimerA = 0
		object.palIndexA++
		object.palIndexA %= 3
		GetTableValue(temp0, object.palIndexA, SBZSetup_palTableA_1)
		SetPaletteEntry(0, 188, temp0)
		GetTableValue(temp0, object.palIndexA, SBZSetup_palTableA_2)
		SetPaletteEntry(0, 189, temp0)
		GetTableValue(temp0, object.palIndexA, SBZSetup_palTableA_3)
		SetPaletteEntry(0, 190, temp0)
	end if

	object.palTimerB++
	if object.palTimerB == 8
		object.palTimerB = 0
		object.palIndexB++
		object.palIndexB &= 7
		GetTableValue(temp0, object.palIndexB, SBZSetup_palTableB_1)
		SetPaletteEntry(0, 168, temp0)
		GetTableValue(temp0, object.palIndexB, SBZSetup_palTableB_2)
		SetPaletteEntry(0, 185, temp0)
	end if

	object.palTimerC++
	if object.palTimerC == 14
		object.palTimerC = 0
		object.palIndexC++
		object.palIndexC &= 7
		GetTableValue(temp0, object.palIndexC, SBZSetup_palTableC_1)
		SetPaletteEntry(0, 169, temp0)
	end if
end event


event ObjectStartup
	if stage.actNum < 5
		// If in acts 1-4, then play the SBZ music
		SetMusicTrack("ScrapBrain.ogg", TRACK_STAGE, MUSIC_LOOP_SBZ)
		SpeedUpMusic = SBZSetup_SpeedUpMusic
		SlowDownMusic = SBZSetup_SlowDownMusic
	else
		// Act 5, play the Final Zone music
		SetMusicTrack("Final.ogg", TRACK_STAGE, MUSIC_LOOP_FINAL)
	end if

	// Cucky and Pocky are the animals that appear in Scrap Brain
	animalType1 = TypeName[Cucky]
	animalType2 = TypeName[Pocky]

	object[SLOT_ZONESETUP].type 		= TypeName[SBZ Setup]
	object[SLOT_ZONESETUP].priority 	= PRIORITY_ACTIVE
	object[SLOT_ZONESETUP].drawOrder 	= 0

	// Init aniTiles
	Copy16x16Tile(592, 604)
	Copy16x16Tile(593, 605)
	Copy16x16Tile(594, 606)
	Copy16x16Tile(596, 604)
	Copy16x16Tile(597, 605)
	Copy16x16Tile(598, 606)

	// Use different palette cycles and such based on the act
	switch stage.actNum
	case 1
		object[SLOT_ZONESETUP].processBG = SBZSetup_BGEffectsAct1
		break
		
	case 2
	case 5 // Act 5 is Final Zone
		SetPaletteEntry(0, 172, 0xC0E0E0)
		SetPaletteEntry(0, 173, 0x60A0A0)
		SetPaletteEntry(0, 174, 0x006060)
		object[SLOT_ZONESETUP].processBG = SBZSetup_BGEffectsAct2
		break
		
	end switch

	SBZSetup_electricOrbFrame = 0
	GetTableValue(SBZSetup_electricOrbTimer, SBZSetup_electricOrbFrame, SBZSetup_electricOrbDelayTable)
	
	if options.attractMode == true
		if credits.screen == 6
			Player_attractTable = SBZSetup_replay_credits_STK_2 // All Characters
			Player_attractTableSize = 22
		else
			Player_attractTable = SBZSetup_replay_credits_STK_1 // All Characters
			Player_attractTableSize = 30
		end if

		Player_attractDuration = 540
		CallFunction(Player_SetupAttractDemo)
	end if
end event


// ========================
// Editor Events
// ========================

event RSDKDraw
	DrawSprite(0)
end event


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