#include "scripts/bp_common.txt"

kActor @arenaPortal;
int mapArenaCinID = 1;
float mapArenaPortalLerpTime = 0.0f;
kVec3 mapArenaPortalPlayerPos = kVec3(-1690, -3641, 357); //arena portal player position
kVec3 mapArenaPortalPos = kVec3(-1690, -3441, 357); //arena portal position
bool mapArenaPortalActive = false;

float pShakeDuration;
float pShakeCurrentTime;
float pShakeAngle;
//------------------------------------------------------------------------------------------------------------------------
void CheckStartArenaCinematic(int haltScriptID, int cinID, const kVec3 playerPos, const kVec3 portalPos) {
	if (!HasPlayedArenaEnterCin(cinID)) {
		// Game.HaltMapScript(haltScriptID);
		GameVariables.SetValue("BP.ArenaCinID", "" + cinID);
		mapArenaCinID = cinID;
		mapArenaPortalPlayerPos = playerPos;
		mapArenaPortalPos = portalPos;
		mapArenaPortalActive = true;
		Game.CallDelayedMapScript(101, Player.Actor().CastToActor(), 0); //Start Arena Cinematic
	}
}
//------------------------------------------------------------------------------------------------------------------------
void DoCinematicText(float time, const kStr &in topText, const kStr &in middleText, const kStr &in bottomText) {
	int iTime = int(60.0f * time - 10);
	Game.PrintLine(bottomText, 0, iTime); //bottom
	Game.PrintLine(middleText, 1, iTime); //middle
	Game.PrintLine(topText, 2, iTime); //top
}
//------------------------------------------------------------------------------------------------------------------------
void ClearCinematicText() {
	int iTime = 10;
	Game.PrintLine("", 0, iTime); //bottom
	Game.PrintLine("", 1, iTime); //middle
	Game.PrintLine("", 2, iTime); //top
}
//------------------------------------------------------------------------------------------------------------------------
// Constant Screen Shake
//------------------------------------------------------------------------------------------------------------------------
$script 99 {
	Camera.Tremor().x = Math::RandRange(Math::Deg2Rad(-0.5f), Math::Deg2Rad(0.5f));
    Camera.Tremor().y = Math::RandRange(Math::Deg2Rad(-0.5f), Math::Deg2Rad(0.5f));
    Camera.Tremor().z = Math::RandRange(Math::Deg2Rad(-0.5f), Math::Deg2Rad(0.5f));
    delay(0.01f);
    $restart;
}
//------------------------------------------------------------------------------------------------------------------------
// Player into Arena Portal Update
//------------------------------------------------------------------------------------------------------------------------
$script 100 {
	if (!mapArenaPortalActive) {
		return;
	}
	float t = 4.0f; //total time for lerp
	mapArenaPortalLerpTime += GAME_DELTA_TIME;
	
	kVec3 pos = mapArenaPortalPlayerPos;
	kVec3 portalPos = mapArenaPortalPos;
	portalPos += kVec3(0.0f, 0.0f, 110.0f);
	pos.Lerp(portalPos, Math::Minf(mapArenaPortalLerpTime / t, 1.0f));
	
	kVec3 scale = kVec3(0.2f, 0.2f, 0.2f);
	scale.Lerp(kVec3(0.001f, 0.001f, 0.001f), Math::Minf(mapArenaPortalLerpTime / t, 1.0f));

	Player.Actor().Origin() = pos;
	Player.Actor().Scale() = scale;
	Player.Actor().Roll() = Math::Lerp(Math::Deg2Rad(0), Math::Deg2Rad(-2160), Math::Minf(mapArenaPortalLerpTime / t, 1.0f));
	if (mapArenaPortalLerpTime < t) {
		$restart;
	}
}
//------------------------------------------------------------------------------------------------------------------------
// Start Arena Cinematic
//------------------------------------------------------------------------------------------------------------------------
$script 101 {
	//bug in the game actually calls scripts before restarting game(or resetting position)...ugh
	bool isNewGame;
	GameVariables.GetBool("g_newgame", isNewGame);
	
	//this can happen because some maps call script 101 even though they don't use them ...
	if (!mapArenaPortalActive || HasPlayedArenaEnterCin(mapArenaCinID) || isNewGame) {
		return;
	}
	
	
	
	SetPlayedArenaEnterCin(mapArenaCinID, true);
	mapArenaPortalLerpTime = 0;
	
	//save arena portal gameVariables
	kVec3 pos = mapArenaPortalPlayerPos;
	// kVec3 pos = Player.Actor().Origin();
	// pos.z = Player.Actor().FloorHeight();
	int si = Player.Actor().GetSectorIndexAtLocation(pos);
	//int si = Player.Actor().SectorIndex();
	GameVariables.SetValue("BP.ArenaWarpSector", "" + si);
	GameVariables.SetValue("BP.ArenaWarpPos", pos.ToString());
	GameVariables.SetValue("BP.ArenaWarpYaw", "" + Player.Actor().Yaw());
	GameVariables.SetValue("BP.ArenaWarpMap", "" + Game.GetCurrentMapID());
	// Sys.Print("Arena Warp ---- Sector: " + si + ", Pos: " + pos.ToString() + ", yaw: " + Player.Actor().Yaw() + ", mapID: " + Game.GetCurrentMapID());
	
	if (arenaPortal is null) {
		@arenaPortal = SpawnActor("BP_ArenaPortal", mapArenaPortalPos.x, mapArenaPortalPos.y, mapArenaPortalPos.z);
		// @arenaPortal = ActorFactory.Spawn("BP_ArenaPortal", 0, 0, 0, 0, 0); //Spawn Arena Portal
		// arenaPortal.Flags() |= AF_NODRAW;
	}
	
	Game.CallDelayedMapScript(99, instigator, 0); //Constant Screen Shake
	Game.CallDelayedMapScript(102, instigator, 0); //Update Arena Cinematic

	//start cinematic
	Camera.StartCinematic(CMF_LOCK_PLAYER|CMF_UNLOCK_PLAYER_ON_FINISH|CMF_NO_LETTERBOX|CMF_NO_INITIAL_FADEOUT);
	Camera.SetLookAtActor(Player.Actor().CastToActor());
	Camera.fov = 74.0f;
	Camera.SetFinalView(0);
	
    Camera.SetRotationTrack(0,
                            Math::Deg2Rad(180.0f),    // start angle
                            Math::Deg2Rad(180.0f),  // dest angle
                            12*GAME_SCALE,           // start distance
                            10*GAME_SCALE,          // dest distance
                            15*GAME_SCALE,          // start height
                            0*GAME_SCALE,           // dest height
                            6*GAME_SCALE,           // start look at height
                            0*GAME_SCALE);          // dest look at height

    Camera.AutoPlayRotationTrack(0, 7.0f, CMLT_COSINE);
	
	
	Player.Actor().ModelVariation() = TV_BOW;
	Player.Actor().Origin() = mapArenaPortalPlayerPos;
    Player.Actor().AnimState().Blend(anim_player_panic, 10.0f, 10.0f, ANF_LOOP);
	Player.Actor().Flags() &= ~AF_NODRAW;
	kVec3 dir = mapArenaPortalPos;
	dir -= mapArenaPortalPlayerPos;
	Player.Actor().Yaw() = dir.ToYaw();
	arenaPortal.Yaw() = (Math::Fabs(dir.x) > Math::Fabs(dir.y)) ? Math::Deg2Rad(90) : 0;
	
	Game.PlaySound("sounds/shaders/generic_141.ksnd"); //rumbling
	// arenaPortal.Origin() = mapArenaPortalPos;
	// arenaPortal.Flags() &= ~AF_NODRAW;
	delay(3.0f);
	
	
	
	Game.CallDelayedMapScript(100, instigator, 0); //Player into Arena Portal Update
	Player.Actor().AnimState().Blend(anim_aiTeleportIn, 10.0f, 10.0f, ANF_LOOP);
	Game.PlaySound("sounds/shaders/generic_25_turok_fall_to_death.ksnd");
	
	//Player.Actor().AnimState().Set(anim_aiTeleportIn, 8.0f, ANF_LOOP);
	delay(4.0f);
	//Player.Actor().Flags() |= AF_NODRAW;
	//delay(1.0f);
	mapArenaPortalActive = false;
	PlayLoop.ChangeMap("levels/level53.map");
}
//------------------------------------------------------------------------------------------------------------------------
// Update Arena Cinematic
//------------------------------------------------------------------------------------------------------------------------
$script 102 {
	if (!mapArenaPortalActive) {
		return;
	}
	if (Camera.UserInterrupted()) {
		//PlayLoop.ChangeMap("levels/level04.map");
		//SetPlayedArenaEnterCin(mapArenaCinID, false);
		mapArenaPortalActive = false;
		PlayLoop.ChangeMap("levels/level53.map");
        return;
    }
    $restart;
}
//------------------------------------------------------------------------------------------------------------------------
void PlayerSetupShake(const float a, const float d) {
	pShakeAngle = a * 0.3333333432674408f;
	pShakeDuration = Math::Fabs(d);
	pShakeCurrentTime = pShakeDuration;
	Game.CallDelayedMapScript(103, Player.Actor().CastToActor(), 0); //Player View Shake
}
//------------------------------------------------------------------------------------------------------------------------
// Player View Shake
//------------------------------------------------------------------------------------------------------------------------
$script 103 {
	if (pShakeCurrentTime <= 0.0f) {
		return;
	}
	
	if((PlayLoop.Ticks() & 3) == 0)
	{
		float power;
		float dist;
		float av, rv;
	
		power = pShakeCurrentTime / pShakeDuration;
		av = (Math::RandCFloat() * (pShakeAngle * 0.5f)) * power;
		rv = (Math::RandCFloat() * (pShakeAngle * 0.5f)) * power;
			
		kPuppet @target = Player.Actor();
		target.RecoilPitch() = (32.0f * av * 0.00390625f);
		target.Roll() = (32.0f * rv * 0.00390625f);
	}
	
	pShakeCurrentTime -= 0.02f;
		
	$restart;
}
//------------------------------------------------------------------------------------------------------------------------
