#include "scripts/common.txt"
#include "scripts/BP_common.txt"
#include "scripts/BP_MapCommon.txt"

//Tag IDs
//1000: Start Warp
//2004: Save Point
//2011: Checkpoint after bridge
//1001: Super Warp 1
//1002: Super Warp 2
//1003: Super Warp 3
//1004: Rock Bridge
//1005: Start Enemy 1
//1006: Start Enemy 2
//1007: Start Enemy 3
//1008: Start Enemy 4
//1009: Start Enemy 5
//1010: Start Enemy 6
//1011: Start Enemy 7
//1012: Start Enemy 8 - Robot Sniper Right
//1013: Start Enemy 9 - Robot Sniper Left
//1014: Start Enemy 10 - Shaman
//1015: Start Enemy 11 - Shaman
//1016: 
//1017: 
//1020: Bridge Mark
//1021: Bridge Pillars + enemies
//1022: Enemies Drop Near Altar
//1023: Falling Rock 1
//1024: Special Blood
//1025: Special Duke
//1026: Special Doom
//1027: Special SW
//1028: Top Warp Point
//1029: Bottom Mountain Warp Point
//1030: Bottom Mountain Pillars
//1031: Chrono Upgrade Spawn Point
//1032: Upper Rock Bridge Secret
//1033: bottom lava secret warp
//1034: 

kActor@ statueBlood;
kActor@ statueDoom;
kActor@ statueDuke;
kActor@ statueSW;
array<kActor@> startEnemies;
array<kActor@> pillarWarps;
kActor@ bridge;
kActor@ chronoSpawnPoint;
bool playedFlute = false;
//------------------------------------------------------------------------------------------------------------------------
// Start Map
//------------------------------------------------------------------------------------------------------------------------
$script 0
{
	StartMap();
	
	@statueBlood = World.GetActorByTID(1024);
	@statueDuke = World.GetActorByTID(1025);
	@statueDoom = World.GetActorByTID(1026);
	@statueSW = World.GetActorByTID(1027);
	
	pillarWarps.insertLast(World.GetActorByTID(1001));
	pillarWarps.insertLast(World.GetActorByTID(1002));
	pillarWarps.insertLast(World.GetActorByTID(1003));
	for (int i = 0; i < int(pillarWarps.length()); i++)
	{
		pillarWarps[i].Flags() |= AF_NODRAW;
	}
	@chronoSpawnPoint = World.GetActorByTID(1031);
	
	@bridge = World.GetActorByTID(1020);
	for (int i = 0; i < 11; i++)
	{
		startEnemies.insertLast(World.GetActorByTID(1005 + i));
	}
	
	Game.CallDelayedMapScript(1, instigator, 0); //Update Map
	
	CheckStartEnemies();
	CheckChronoUpgrade();
}
//------------------------------------------------------------------------------------------------------------------------
// Update Map
//------------------------------------------------------------------------------------------------------------------------
$script 1
{
	TickMap();
	$restart;
}
//------------------------------------------------------------------------------------------------------------------------
void CheckChronoUpgrade()
{
	if (statueBlood.IsPersistentMarked() && statueDoom.IsPersistentMarked() &&
		statueDuke.IsPersistentMarked() && statueSW.IsPersistentMarked())
	{
		for (int i = 0; i < int(pillarWarps.length()); i++)
		{
			pillarWarps[i].Flags() &= ~AF_NODRAW;
		}
		
		if (!GetPlayerChronoUpgrade())
		{
			kVec3 p = chronoSpawnPoint.Origin();
			ActorFactory.Spawn(7007, p.x, p.y, p.z, 0.0f);
		}
	}
}
//------------------------------------------------------------------------------------------------------------------------
void CheckStartEnemies()
{
	kActor@ instigator = Player.Actor().CastToActor();
	
	//check if shaman enemies should come down after both robot snipers are dead
	bool snipersDead = true;
	for (int i = 7; i < 9; i++)
	{
		if (ActorExists(startEnemies[i]) && !startEnemies[i].IsPersistentMarked())
		{
			snipersDead = false;
			break;
		}
	}
	if (snipersDead)
	{
		for (int i = 0; i < 2; i++)
		{
			World.TriggerActorsByTID(instigator, 1014 + i);
		}
	}
	
	//check if bridge should show up after all enemies killed
	bool enemiesDead = true;
	for (int i = 0; i < 11; i++)
	{
		if (ActorExists(startEnemies[i]) && !startEnemies[i].IsPersistentMarked())
		{
			enemiesDead = false;
			break;
		}
	}
	
	if (enemiesDead && !bridge.IsPersistentMarked())
	{
		Camera.StartCinematic(CMF_NO_LETTERBOX | CMF_LOCK_PLAYER | CMF_UNLOCK_PLAYER_ON_FINISH);
		Camera.SetLookAtActor(bridge);
		Camera.ClearFinalView();
		Camera.ClearViewTracks();
		Camera.origin = kVec3(-987.0f, -3646.0f, 1576.0f);
		delay(1.0f);
		instigator.Flags() &= ~AF_NODRAW;
		instigator.AnimState().Set(anim_player_idle, 8.0f, ANF_LOOP);
		instigator.ModelVariation() = TV_BOW;
		instigator.SetPosition(kVec3(5.12f, -5885.0f, instigator.FloorHeight())); //position in front of bridge so bridge doesn't go to sleep
		World.TriggerActorsByTID(instigator, 1004); //rock bridge
		World.TriggerActorsByTID(instigator, 1020); //Bridge Mark
		delay(3.0f);
		Camera.StopCinematic();
		delay(0.3f);
		instigator.Flags() |= AF_NODRAW;
	}
}
//------------------------------------------------------------------------------------------------------------------------
// On Enemy killed
//------------------------------------------------------------------------------------------------------------------------
$script 9999
{
	if (instigator.TID() >= 1005 && instigator.TID() <= 1017)
	{
		CheckStartEnemies();
	}
}
//------------------------------------------------------------------------------------------------------------------------
// Start Enemies - Robot snipers appear
//------------------------------------------------------------------------------------------------------------------------
$script 10000
{
	if ((instigator.Flags() & AF_ENTEREDAREAEVENT) == 0)
	{
		World.TriggerActorsByTID(instigator, 1012); //Robot Sniper Right
		World.TriggerActorsByTID(instigator, 1013); //Robot Sniper Left
	}
}
//------------------------------------------------------------------------------------------------------------------------
// Start Volcano Boost
//------------------------------------------------------------------------------------------------------------------------
$script 10001
{
	if (Player.Actor().Origin().z <= Player.Actor().FloorHeight() + 1.0f)
	{
		Player.Actor().PlayerFlags() |= PF_NOAIRFRICTION;
		kVec3 vel = Player.Actor().Velocity();
		vel.y = 18.0f;
		vel.z = 55.0f;
		Player.Actor().Velocity() = vel;
		delay(1.0f);
		World.TriggerActorsByTID(instigator, 1032); //Upper Rock Bridge Secret
		delay(0.5f);
		Player.Actor().PlayerFlags() &= ~PF_NOAIRFRICTION;
	}
}
//------------------------------------------------------------------------------------------------------------------------
void TryPlaceStatue(kActor@ actor, const int bit)
{
	kActor@ instigator = Player.Actor().CastToActor();
	if (!actor.IsPersistentMarked())
	{
		if (HasSpecialPickup(bit))
		{
			World.TriggerActorsByTID(instigator, actor.TID());
			switch (bit)
			{
				case 0:
				{
					Game.PlaySound("sounds/shaders/special_blood.ksnd");
					break;
				}
				case 1:
				{
					Game.PlaySound("sounds/shaders/special_doom.ksnd");
					break;
				}
				case 2:
				{
					Game.PlaySound("sounds/shaders/special_duke.ksnd");
					break;
				}
				case 3:
				{
					Game.PlaySound("sounds/shaders/special_sw.ksnd");
					break;
				}
			}
			
			if (statueBlood.IsPersistentMarked() && statueDoom.IsPersistentMarked() &&
				statueDuke.IsPersistentMarked() && statueSW.IsPersistentMarked())
			{
				Camera.SetLookAtActor(chronoSpawnPoint);
				Camera.ClearFinalView();
				Camera.ClearViewTracks();
				Camera.SetFinalView(0);
				Camera.SetRotationTrack(0,
										Math::Deg2Rad(-90.0f),    // start angle
										Math::Deg2Rad(270.0f),  // dest angle
										120*GAME_SCALE,           // start distance
										120*GAME_SCALE,          // dest distance
										90*GAME_SCALE,          // start height
										30*GAME_SCALE,           // dest height
										1*GAME_SCALE,           // start look at height
										1*GAME_SCALE);          // dest look at height
												   
				Camera.AutoPlayRotationTrack(0, 10.0f, CMLT_COSINE);
				Camera.StartCinematic(CMF_NO_LETTERBOX | CMF_LOCK_PLAYER | CMF_UNLOCK_PLAYER_ON_FINISH);
				delay(0.3f);
				Game.PlaySound("sounds/shaders/generic_9_alien_jetpack_engage.ksnd");
				for (int i = 0; i < int(pillarWarps.length()); i++)
				{
					pillarWarps[i].Flags() &= ~AF_NODRAW;
				}
				kVec3 p = chronoSpawnPoint.Origin();
				ActorFactory.Spawn(7007, p.x, p.y, p.z, 0.0f);
				delay(9.7f);
				Camera.StopCinematic();
			}
		}
		else
		{
			Game.PrintLine(LTKey(10), 0);
		}
	}
}
//------------------------------------------------------------------------------------------------------------------------
// Area - Blood Statue
//------------------------------------------------------------------------------------------------------------------------
$script 10002
{
	TryPlaceStatue(statueBlood, 0);
}
//------------------------------------------------------------------------------------------------------------------------
// Area - Doom Statue
//------------------------------------------------------------------------------------------------------------------------
$script 10003
{
	TryPlaceStatue(statueDoom, 1);
}
//------------------------------------------------------------------------------------------------------------------------
// Area - Duke Statue
//------------------------------------------------------------------------------------------------------------------------
$script 10004
{
	TryPlaceStatue(statueDuke, 2);
}
//------------------------------------------------------------------------------------------------------------------------
// Area - SW Statue
//------------------------------------------------------------------------------------------------------------------------
$script 10005
{
	TryPlaceStatue(statueSW, 3);
}
//------------------------------------------------------------------------------------------------------------------------
// Area - Flying Pad Back
//------------------------------------------------------------------------------------------------------------------------
$script 10006
{
    if ((instigator.Flags() & AF_ENTEREDAREAEVENT) != 0 || playedFlute)
        return;

	playedFlute = true;
	Game.PlaySound("sounds/shaders/flute.ksnd");
	delay(2.1f);
	PlayLoop.StartWarp(Player.Actor().CastToActor(), 1005, 106); //skip flying
}
//------------------------------------------------------------------------------------------------------------------------
