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

//Tag IDs
//1000: Start Warp
//1001: Start Checkpoint
//2009: Save Point
//2010: Checkpoint above village
//1002: Start Birds
//1003: Under Water Door 1 + stalkers in water
//1004: Under Water Door 2
//1005: Temple Doors
//1006: Temple Enemy 1
//1007: Temple Enemy 2
//1008: Temple Enemy 3
//1009: Temple Enemy 4
//1010: Temple Enemy 5
//1011: Temple Enemy 6
//1012: Rope Arrow Doors
//1013: Has Entered Rope Area Bit
//1014: Temple Exit Door
//1015: Temple Checkpoint
//1016: Rope Arrows
//1017: Enemy Drops After Temple
//1018: Temple Water
//1019: Temple Water Button 1
//1020: Temple Water Button 2
//1021: Temple Rope Help
//1022: Environment Monkey
//1023: Environment Birds
//1024: Tree Warp Point
//1025: Purlin Wall 1
//1026: Temple Purlin Door
//1027: Temple Purlin Drop
//1028: Purlin Wall 2 (stalker trriger anim 3 - hold trigger anim, make soawn anim visible)
//1029: Temple Purlin Warp
//1030: Center Cave Rope Warp
//1031: Temple Purlin Bit
//1032: Drop Down Enemies 1
//1033: Drop Down Enemies 2
//1034: Village Gate
//1035: Cliff button and doors
//1036: Warp From Ruins 1
//1037: Ruins 1 Warp Finish Exit
//1038: Ruins 2 Warp
//1039: Environment Birds 2 + monkey
//1040: Enemy Drops near gate
//1041: Aliens drop near temple
//1042: Environment Monkey in village
//1043: Environment Birds 3 near big tree
//1044: Environment Birds 4 + enemy drop near cliff side
//1045: Environment Birds 5
//1046: Water Temple Wall
//1047: Water Temple Warp
//1048: Primal Valley Warp Point 1
//1049: Primal Valley Warp Point 2
//1050: Primal Valley Warp Point 3
//1051: Primal Valley Pillars
//1052: Primal Valley Warp
//1053: Primal Cave Button + Door
//1054: Primal Cave Trap Doors + enemies
//1055: Primal Cave Destructible Stags 1
//1056: Primal Cave Destructible Stags 2
//1057: Primal Cave Destructible Stags 3
//1058: Treehouse Enemies Drop
//1059: Mantis
//1060: Mantis triggered?
//1061: Player Mantis Custcene Position
//2017: Mantis Checkpoint Warp
//1062: Door Blocking Spirit Temple
//1063: Whispers Pad Area
//1064: Tree Trap
//1065: Trex Rock 1
//1066: Trex Rock 2
//1067: Trex Rock 3
//1068: Trex Rock 4
//1069: Trex Rock 5
//1070: Trex Rock 6
//1071: Rocks Blocking Point
//1072: Trex Puppet
//1073: Trex Cutscene played?
//1074: Player Point Trex Custscne
//1075: Player Point 2 Trex Custscne
//1076: Trex Point Custscne
//1077: Rock Explosion Point
//1078: River Fall Warp
//1079: 

array<kActor@> templeEnemies(6);
kActor @ropeArrowDoors;
kActor @templeDoors;
kActor @templeExitDoor;
kActor @ropeArrows;
kActor @templeWaterButton1;
kActor @templeWaterButton2;
kActor @templeRopeHelp;
kActor @templePurlinBit;
kActor @mantis;
kActor @mantisTriggered;
kActor @playerMantisPos;
array<kActor@> rocks(4);
kActor@ trexPuppet;
kActor@ trexScenePlayed;
kActor@ playerPosScene;
kActor@ playerPos2Scene;
kActor@ trexPosScene;
kActor@ rockExplodePos;
bool playedFlute = false;

//------------------------------------------------------------------------------------------------------------------------
// Start Map
//------------------------------------------------------------------------------------------------------------------------
$script 0
{
	StartMap();
	@templeDoors = World.GetActorByTID(1005);
	@ropeArrowDoors = World.GetActorByTID(1012);
	@templeExitDoor = World.GetActorByTID(1014);
	@ropeArrows = World.GetActorByTID(1016);
	@templeWaterButton1 = World.GetActorByTID(1019);
	@templeWaterButton2 = World.GetActorByTID(1020);
	@templeRopeHelp = World.GetActorByTID(1021);
	@templePurlinBit = World.GetActorByTID(1031);
	@mantis = World.GetActorByTID(1059);
	@mantisTriggered = World.GetActorByTID(1060);
	@playerMantisPos = World.GetActorByTID(1061);
	@trexPuppet = World.GetActorByTID(1072);
	trexPuppet.Flags() |= AF_HIDDEN;
	@trexScenePlayed = World.GetActorByTID(1073);
	@playerPosScene = World.GetActorByTID(1074);
	@playerPos2Scene = World.GetActorByTID(1075);
	@trexPosScene = World.GetActorByTID(1076);
	@rockExplodePos = World.GetActorByTID(1077);
	
	for (uint i = 0; i < rocks.length(); i++)
	{
		@rocks[i] = World.GetActorByTID(1065 + i);
		rocks[i].Friction() = 0.5f;
		rocks[i].BounceDamp() = 0.3f;
		rocks[i].Gravity() = 0.2f;
		rocks[i].ClipFlags() |= CF_CLIPEDGES | CF_IGNOREBLOCKERS | CF_DROPOFF | CF_WALKWALLS | CF_COLLIDEFLOORS | CF_NOSLOPESTEP | CF_COLLIDEHEIGHT | CF_NOFLOORADJUST | CF_NOCEILINGADJUST;
	}
	
	if (trexScenePlayed.IsPersistentMarked())
	{
		for (uint i = 0; i < rocks.length(); i++)
		{
			rocks[i].Remove();
		}
	}
	
	//mantis not dead but cutscene was triggered
	if (mantisTriggered.IsPersistentMarked() && !mantis.IsPersistentMarked())
	{
		World.TriggerActorsByTID(instigator, mantis.TID());
	}
	
	if (!ropeArrowDoors.IsPersistentMarked())
	{
		HideAI(@ropeArrows);
	}
	
	//if temple exit door is closed and should be open then open it
	if (!templeExitDoor.IsPersistentMarked() && (ropeArrowDoors.IsPersistentMarked() || !templeDoors.IsPersistentMarked()))
	{
		World.TriggerActorsByTID(instigator, 1014); //open the temple exit door
	}
	
	for (int i = 0; i < int(templeEnemies.length()); i++)
	{
		@templeEnemies[i] = World.GetActorByTID(1006 + i);
		if (ActorExists(@templeEnemies[i]) && !templeDoors.IsPersistentMarked())
		{
			HideAI(@templeEnemies[i]);
		}
	}
	
	//PlayOggMusic("Get_Them.ogg");
	Game.CallDelayedMapScript(1, instigator, 0); //Update Map	
}
//------------------------------------------------------------------------------------------------------------------------
// Update Map
//------------------------------------------------------------------------------------------------------------------------
$script 1
{
	TickMap();
	//PlayWavMusic("BP_Music_Get_Them.ksnd");
	$restart;
}
//------------------------------------------------------------------------------------------------------------------------
// Update Mantis Cinematic
//------------------------------------------------------------------------------------------------------------------------
$script 2
{
    if (Camera.UserInterrupted())
    {
		EndMantisCinematic(instigator, 10006);
        return;
    }
	$restart;
}
//------------------------------------------------------------------------------------------------------------------------
// Update Trex Cinematic
//------------------------------------------------------------------------------------------------------------------------
$script 3
{
	//trexPuppet.Origin().z = trexPuppet.FloorHeight();
	//Player.Actor().Origin().z = Player.Actor().FloorHeight();
	
    if (Camera.UserInterrupted())
    {
		EndTrexCinematic(instigator, 10007);
        return;
    }
	$restart;
}
//------------------------------------------------------------------------------------------------------------------------
// Update Trex Cinematic Player falling
//------------------------------------------------------------------------------------------------------------------------
$script 4
{
	Player.Actor().Origin() += kVec3(0, 0.0f, -4.0f);
    $restart;
}
//------------------------------------------------------------------------------------------------------------------------
void EndTrexCinematic(kActor@ instigator, const int haltScriptID)
{
	Camera.StopCinematic();
	Player.Actor().Flags() |= AF_NODRAW;
	Game.HaltMapScript(4);
	Game.HaltMapScript(haltScriptID);
	PlayLoop.StartWarp(Player.Actor().CastToActor(), 2020, 122);
}
//------------------------------------------------------------------------------------------------------------------------
void EndMantisCinematic(kActor@ instigator, const int haltScriptID)
{
	Camera.StopCinematic();
	Player.Actor().AnimState().Set(anim_player_idle, 5.5f, ANF_LOOP);
	Player.Actor().Flags() |= AF_NODRAW;
	World.ChangeAreaFlag(playerMantisPos.AreaID(), AAF_CHECKPOINT, false);
	World.TriggerActorsByTID(instigator, mantis.TID());
	Game.HaltMapScript(haltScriptID);
}
//------------------------------------------------------------------------------------------------------------------------
// Enemy Killed
//------------------------------------------------------------------------------------------------------------------------
$script 9999
{	
	//if killed temple enemy
	if (instigator.TID() >= 1006 && instigator.TID() <= 1011)
	{
		int enemiesKilled = 0;
		int totalEnemies = int(templeEnemies.length());
		for (int i = 0; i < totalEnemies; i++)
		{
			if (!ActorExists(@templeEnemies[i]) || IsActorDead(@templeEnemies[i]))
			{
				enemiesKilled++;
			}
		}
		//trigger door to open to rope arrows if killed all enemies
		if (enemiesKilled >= totalEnemies)
		{
			ShowAI(@ropeArrows);
			World.TriggerActorsByTID(instigator, 1012); //open rope doors
			if (!templeExitDoor.IsPersistentMarked())
			{
				World.TriggerActorsByTID(instigator, 1014); //open the temple exit door
			}
		}
	}
	else if (instigator.TID() == mantis.TID())
	{
		World.TriggerActorsByTID(instigator, 1062); //Door Blocking Spirit Temple
	}
}
//------------------------------------------------------------------------------------------------------------------------
// In Rope Arrows Area
//------------------------------------------------------------------------------------------------------------------------
$script 10000
{	
	if (!templeDoors.IsPersistentMarked())
	{
		World.TriggerActorsByTID(instigator, 1005); //open temple enemy doors
		if (templeExitDoor.IsPersistentMarked())
		{
			World.TriggerActorsByTID(instigator, 1014); //close the temple exit door
		}
		for (int i = 0; i < int(templeEnemies.length()); i++)
		{
			if (ActorExists(@templeEnemies[i]))
			{
				ShowAI(@templeEnemies[i]);
			}
		}
	}
}
//------------------------------------------------------------------------------------------------------------------------
// In Area - Enemy Drops after Temple
//------------------------------------------------------------------------------------------------------------------------
$script 10001
{
	if (ropeArrowDoors.IsPersistentMarked())
	{
		World.TriggerActorsByTID(instigator, 1017); //drops down enemies
	}
}
//------------------------------------------------------------------------------------------------------------------------
// In Area - Temple Water Button 1
//------------------------------------------------------------------------------------------------------------------------
$script 10002
{
	if (!templeWaterButton1.IsPersistentMarked())
	{
		World.TriggerActorsByTID(instigator, 1019); //Activate button 1
		if (templeWaterButton2.IsPersistentMarked())
		{
			World.TriggerActorsByTID(instigator, 1018); //Start Temple Water
		}
	}
}
//------------------------------------------------------------------------------------------------------------------------
// In Area - Temple Water Button 2
//------------------------------------------------------------------------------------------------------------------------
$script 10003
{
	if (!templeWaterButton2.IsPersistentMarked())
	{
		World.TriggerActorsByTID(instigator, 1020); //Activate button 2
		if (templeWaterButton1.IsPersistentMarked())
		{
			World.TriggerActorsByTID(instigator, 1018); //Start Temple Water
		}
	}
}
//------------------------------------------------------------------------------------------------------------------------
// In Area - Temple Rope Help
//------------------------------------------------------------------------------------------------------------------------
$script 10004
{
	//has rope arrows
	if ((Player.HasWeapon(14) || Player.HasWeapon(18) || GetPlayerCharacter() == PLAYER_CHAR_HUMMER) &&
		ropeArrowDoors.IsPersistentMarked() && !templeRopeHelp.IsPersistentMarked())
	{
		World.TriggerActorsByTID(instigator, 1021); //Activate Rope Help
		Game.PrintHelp(LTKey(0));
		delay(3.0f);
		Game.PrintHelp(LTKey(0));
		delay(3.0f);
		Game.PrintHelp(LTKey(0));
		delay(3.0f);
		Game.PrintHelp(LTKey(0));
	}
}
//------------------------------------------------------------------------------------------------------------------------
// In Area - Temple Purlin Wall 2
//------------------------------------------------------------------------------------------------------------------------
$script 10005
{
	if (templePurlinBit.IsPersistentMarked() &&	(instigator.Flags() & AF_ENTEREDAREAEVENT) == 0)
	{
		World.TriggerActorsByTID(instigator, 1028); //Purlin Wall 2
	}
}
//------------------------------------------------------------------------------------------------------------------------
// In Area - Mantis Spirit Temple
//------------------------------------------------------------------------------------------------------------------------
$script 10006
{
	if ((instigator.Flags() & AF_ENTEREDAREAEVENT) == 0 && !mantisTriggered.IsPersistentMarked())
	{
		mantisTriggered.MarkPersistentBit(false);
		Camera.StartCinematic(CMF_LOCK_PLAYER | CMF_UNLOCK_PLAYER_ON_FINISH);
		Camera.SetLookAtActor(mantis);
		Camera.ClearFinalView();
		Camera.ClearViewTracks();
		Camera.fov = 74.0f;
		Camera.origin = kVec3(-2007.039917f, 9540.0f, 170.0f);
		while (Camera.CinematicState() < 2) { delay(0.000001f); }
		kActor@ pActor = Player.Actor().CastToActor();
		pActor.Origin() = playerMantisPos.Origin();
		pActor.SetSector(playerMantisPos.SectorIndex());
		pActor.Yaw() = playerMantisPos.Yaw();
		pActor.Pitch() = 0.0f;
		pActor.Roll() = 0.0f;
	    pActor.Flags() &= ~AF_NODRAW;
		pActor.AnimState().Set(anim_player_idle, 5.5f, ANF_LOOP|ANF_ROOTMOTION);
		pActor.ModelVariation() = TV_BOW;
		CameraMove(instigator, Camera.origin, kVec3(-2007.039917f, 10112.0f, 1027.0f), 4.0f);
		delay(0.1f);
		Game.CallDelayedMapScript(2, instigator, 0); //Update Mantis Cinematic
		delay(3.9f);
		World.TriggerActorsByTID(instigator, mantis.TID());
		delay(1.0f);
		EndMantisCinematic(instigator, 2);
	}
}
//------------------------------------------------------------------------------------------------------------------------
// In Area - Trex Surprise
//------------------------------------------------------------------------------------------------------------------------
$script 10007
{
	if (ropeArrowDoors.IsPersistentMarked() && !trexScenePlayed.IsPersistentMarked())
	{
		trexScenePlayed.MarkPersistentBit(false);
		World.TriggerActorsByTID(instigator, 1071); //Rocks Blocking Point
		
		Player.Actor().Flags() &= ~AF_NODRAW;
		Player.Actor().AnimState().Set(anim_player_idle, 4.0f, ANF_LOOP);
		Player.Actor().Yaw() = playerPosScene.Yaw();
		Player.Actor().Pitch() = 0.0f;
		Player.Actor().Roll() = 0.0f;
		Player.Actor().ModelVariation() = TV_BOW;
		Player.Actor().Origin() = playerPosScene.Origin();
		Player.Actor().SetSector(playerPosScene.SectorIndex());
		
		Camera.StartCinematic(CMF_LOCK_PLAYER|CMF_UNLOCK_PLAYER_ON_FINISH|CMF_NO_INITIAL_FADEOUT);
		Camera.SetLookAtActor(trexPuppet);
		Camera.fov = 74.0f;
		kVec3 cameraPos = kVec3(700, -7777, 872);
		Camera.origin = cameraPos;

		trexPuppet.Flags() &= ~AF_HIDDEN;
		trexPuppet.Flags() &= ~uint(AF_NOMOVEMENT);
		//trexPuppet.ClipFlags() = CF_IGNOREBLOCKERS | CF_NOCLIPSTATICS | CF_NOCLIPACTORS | CF_DROPOFF | CF_WALKWALLS | CF_COLLIDEFLOORS;

		trexPuppet.AnimState().Blend(anim_trexRoar, 4.2f, 4.0f, ANF_LOOP|ANF_ROOTMOTION);
		Game.PlaySound("sounds/shaders/trex_scream.ksnd");
		
		delay(0.1f);
		Camera.origin = cameraPos;
		Player.Actor().Origin() = playerPosScene.Origin();
		Player.Actor().SetSector(playerPosScene.SectorIndex());
		delay(0.4f);
		Camera.origin = cameraPos;
		Player.Actor().Origin() = playerPosScene.Origin();
		Player.Actor().SetSector(playerPosScene.SectorIndex());
		Game.PlayMusic("music/track12.ogg", true);
		
		Game.SpawnFx("fx/generic_235.kfx", rockExplodePos.Origin(), 0);
		Game.PlaySound("sounds/shaders/explosion_2.ksnd");
		
		//setup and move rocks
		for (uint i = 0; i < rocks.length(); i++)
		{
			rocks[i].Flags() &= ~uint(AF_NOMOVEMENT);
		}
		rocks[0].Velocity() = kVec3(10.0f, 10.0f, 5.0f); //bottom right
		rocks[1].Velocity() = kVec3(9.0f, -10.0f, 3.5f); //bottom left
		rocks[2].Velocity() = kVec3(7.0f, 5.0f, 7.0f); //top right
		rocks[3].Velocity() = kVec3(6.0f, -5.0f, 6.0f); //top left
		
		Game.CallDelayedMapScript(3, instigator, 0); //Update Trex Cinematic
		
		delay(2.7f);
        trexPuppet.SetTarget(Player.Actor().CastToActor());
        trexPuppet.SetHeadTrackTarget(Player.Actor().CastToActor());
		//trexPuppet.RenderModel().AddTrailEffect("Trail_TrexLaser", 4);
		//trexPuppet.SpawnProjectile("fx/eyefire.kfx", kVec3(0.0f, 0.0f, 300.0f), trexPuppet.GetTarget().Origin(), Math::Deg2Rad(45.0f));
		trexPuppet.AnimState().Blend(anim_aiRunning, 1.85f, 4.0f, ANF_LOOP|ANF_ROOTMOTION);
		delay(2.0f);
		
		Camera.SetLookAtActor(Player.Actor().CastToActor());
		Camera.ClearFinalView();
		Camera.ClearViewTracks();
		Camera.SetFinalView(0);
		Camera.SetRotationTrack(0,
								Math::Deg2Rad(0.0f),    // start angle
								Math::Deg2Rad(-20.0f),  // dest angle
								60*GAME_SCALE,           // start distance
								30*GAME_SCALE,          // dest distance
								40*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);
		
		Player.Actor().Yaw() = playerPos2Scene.Yaw();
		Player.Actor().Origin() = playerPos2Scene.Origin();
		Player.Actor().SetSector(playerPos2Scene.SectorIndex());
		Player.Actor().AnimState().Set(anim_player_run, 5.5f, ANF_LOOP|ANF_ROOTMOTION);
		
		trexPuppet.Yaw() = trexPosScene.Yaw();
		trexPuppet.Origin() = trexPosScene.Origin();
		trexPuppet.SetSector(trexPosScene.SectorIndex());
		
		delay(2.0f);
		
		//trexPuppet.SpawnProjectile("fx/eyefire.kfx", kVec3(0.0f, 0.0f, 300.0f), trexPuppet.GetTarget().Origin(), Math::Deg2Rad(45.0f));

		delay(1.8f);
		
		Player.Actor().AnimState().Blend(anim_player_exit, 6.0f, 8.0f, ANF_ROOTMOTION);
		delay(0.25f);
		Game.CallDelayedMapScript(4, instigator, 0); //Update Trex Cinematic Player falling
		delay(0.25f);

		trexPuppet.AnimState().Blend(anim_trexRoar, 4.0f, 4.0f, ANF_LOOP|ANF_ROOTMOTION);
		Game.PlaySound("sounds/shaders/trex_scream.ksnd");

		//Player.Actor().AnimState().Set(anim_player_jump, 4.0f, ANF_LOOP);
		Player.Actor().AnimState().Blend(36, 4.0f, 8.0f, ANF_LOOP); //fall death pit animation
		
		delay(2.0f);
		
		//Game.PlaySound("sounds/shaders/turok_fall_to_death.ksnd");
		//Player.Actor().AnimState().Blend(36, 4.0f, 8.0f, ANF_LOOP); //fall death pit animation
		
		delay(4.0f);
		
		EndTrexCinematic(instigator, 3);
	}
}
//------------------------------------------------------------------------------------------------------------------------
// In Area - Flying Pad
//------------------------------------------------------------------------------------------------------------------------
$script 10008
{
    if ((instigator.Flags() & AF_ENTEREDAREAEVENT) != 0 || playedFlute)
        return;

	if (GetPlayerFlute())
	{
		playedFlute = true;
		Game.PlaySound("sounds/shaders/flute.ksnd");
		delay(2.1f);
		Game.PrintLine("Map Not Finished (WIP)", 0, 120);
	}
	else
	{
		Game.PrintLine("A Strong Wind Blows", 0, 120);
	}
}
//------------------------------------------------------------------------------------------------------------------------
