//
// Copyright(C) 2014-2015 Samuel Villarreal
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// DESCRIPTION:
//      Level Script For Level00.map
//

#include "scripts/common.txt"

kActor @g_pCampaigner = null;

/*
==============================================================
Script 0
==============================================================
*/

$script 0
{
    @g_pCampaigner = World.GetActorByTID(400);
    Game.CallDelayedMapScript(8, instigator, 0);
}

/*
==============================================================
Script 1
==============================================================
*/

$script 1
{
    Camera.StartCinematic();
    PlayLoop.RemoveBossActor();
    
    Camera.SetLookAtActor(g_pCampaigner);
    Camera.fov = 74.0f;
    
    delay(0.35f);
    
    g_pCampaigner.SetPosition(kVec3(30*GAME_SCALE, 10*GAME_SCALE, 0.0f));
    g_pCampaigner.Yaw() = Math::Deg2Rad(85.0f);
    g_pCampaigner.Origin().z = g_pCampaigner.FloorHeight();
    g_pCampaigner.AnimState().Set(anim_aiDeathStand, 4.0f, ANF_ROOTMOTION);
    g_pCampaigner.RunFxEvent("Campaigner_Death");
    g_pCampaigner.SetHeadTrackTarget(null);

    
    Player.Actor().Flags() &= ~AF_NODRAW;
    Player.Actor().SetPosition(kVec3(-4*GAME_SCALE, 10*GAME_SCALE, 0.0f));
    Player.Actor().Yaw() = Math::Deg2Rad(90.0f);
    Player.Actor().Origin().z = Player.Actor().FloorHeight();
    Player.Actor().Pitch() = 0;
    Player.Actor().RecoilPitch() = 0;
    Player.Actor().AnimState().Set(anim_player_idle, 8.0f, ANF_LOOP);
    
    Camera.SetFinalView(0);
    Camera.SetRotationTrack(0,
                            Math::Deg2Rad(0.0f),    // start angle
                            Math::Deg2Rad(720.0f),  // dest angle
                            5*GAME_SCALE,           // start distance
                            10*GAME_SCALE,          // dest distance
                            12*GAME_SCALE,          // start height
                            5*GAME_SCALE,           // dest height
                            6*GAME_SCALE,           // start look at height
                            5*GAME_SCALE);          // dest look at height
                                       
    Camera.AutoPlayRotationTrack(0, 9.33f, CMLT_COSINE);
    
    delay(16.0f);
    g_pCampaigner.RunFxEvent("Campaigner_FinalDeath");
    Camera.SetRotationTrack(0,
                            Math::Deg2Rad(0.0f),    // start angle
                            Math::Deg2Rad(110.0f),  // dest angle
                            10*GAME_SCALE,          // start distance
                            5*GAME_SCALE,           // dest distance
                            5*GAME_SCALE,           // start height
                            4*GAME_SCALE,           // dest height
                            5*GAME_SCALE,           // start look at height
                            GAME_SCALE);            // dest look at height
                                       
    Camera.AutoPlayRotationTrack(0, 5.33f, CMLT_COSINE);
    
    delay(6.0f);
    Camera.StartCinematic();
    
    delay(0.35f);
    
    Camera.ClearLookAtActor();
    Camera.SetRotateEyeVector(kVec3(-4*GAME_SCALE, 10*GAME_SCALE, 0.0f));
    Camera.SetRotationTrack(0,
                            Math::Deg2Rad(10.0f),   // start angle
                            Math::Deg2Rad(100.0f),  // dest angle
                            6*GAME_SCALE,           // start distance
                            15*GAME_SCALE,          // dest distance
                            4*GAME_SCALE,           // start height
                            3*GAME_SCALE,           // dest height
                            6*GAME_SCALE,           // start look at height
                            2*GAME_SCALE);          // dest look at height
                                       
    Camera.AutoPlayRotationTrack(0, 10.0f, CMLT_COSINE);
    
    delay(4.0f);
    Game.CallDelayedMapScript(5, instigator, 0);
    Game.CallDelayedMapScript(9, instigator, 0);
    delay(0.05f);
    Player.Actor().AnimState().Blend(anim_player_panic, 10.0f, 10.0f, ANF_LOOP|ANF_ROOTMOTION);
    
    delay(6.0f);
    Game.HaltMapScript(4);
    Game.CallDelayedMapScript(6, instigator, 0);
    Camera.ClearLookAtActor();
    Camera.SetRotateEyeVector(kVec3(-4*GAME_SCALE, 10*GAME_SCALE, 0.0f));
    Camera.SetRotationTrack(0,
                            Math::Deg2Rad(100.0f),          // start angle
                            Math::Deg2Rad(100.0f),          // dest angle
                            15*GAME_SCALE,                  // start distance
                            15*GAME_SCALE,                  // dest distance
                            3*GAME_SCALE,                   // start height
                            3*GAME_SCALE,                   // dest height
                            2*GAME_SCALE,                   // start look at height
                            2*GAME_SCALE);                  // dest look at height
                                       
    Camera.AutoPlayRotationTrack(0, 10.0f, CMLT_COSINE);
                                   
    World.TriggerActorsByTID(instigator, 50);
    
    delay(1.5f);
    Camera.SetRotationTrack(0,
                            Math::Deg2Rad(100.0f),          // start angle
                            Math::Deg2Rad(250.0f),          // dest angle
                            15*GAME_SCALE,                  // start distance
                            20*GAME_SCALE,                  // dest distance
                            3*GAME_SCALE,                   // start height
                            2*GAME_SCALE,                   // dest height
                            2*GAME_SCALE,                   // start look at height
                            8*GAME_SCALE);                  // dest look at height
                                       
    Camera.AutoPlayRotationTrack(0, 5.33f, CMLT_COSINE);
    
    delay(6.0f);
    Game.HaltMapScript(5);
    PlayLoop.ChangeMap("levels/level01.map");
}

/*
==============================================================
Script 2

Campaigner killed Turok
==============================================================
*/

$script 2
{
    // active yet?
    if(g_pCampaigner.Health() <= 0)
    {
        // cancel custom death cinematic
        Player.Actor().PlayerFlags() &= ~PF_PREVENTDEATHCAM;
        return;
    }
    
    Camera.StartCinematic();
    Camera.fov = 74.0f;
    Camera.SetFinalView(0);
    PlayLoop.RemoveBossActor();
    
    Game.CallDelayedMapScript(3, instigator, 0);
    Game.CallDelayedMapScript(7, instigator, 0);
}

/*
==============================================================
Script 3

Logic for Campaigner kill cinematic
==============================================================
*/

$script 3
{
    if(Camera.CinematicState() >= 2)
    {
        kVec3 vPos;
        kPuppet @actor = Player.Actor();
        
        actor.Flags() &= ~AF_NODRAW;
        
        // move Campaigner into position
        vPos.x = 43*GAME_SCALE;
        vPos.y = 10*GAME_SCALE;
        vPos.z = 0;
        
        g_pCampaigner.SetSector(g_pCampaigner.GetSectorIndexAtLocation(vPos));
        g_pCampaigner.Origin() = vPos;
        g_pCampaigner.Origin().z = g_pCampaigner.FloorHeight();
        g_pCampaigner.Yaw() = Math::Deg2Rad(-85-180);
        g_pCampaigner.Velocity().Clear();
        g_pCampaigner.SetHeadTrackTarget(null);
        
        g_pCampaigner.AnimState().Set(anim_event07, 4.0f, ANF_NOINTERRUPT|ANF_ROOTMOTION);
        
        // move player into position
        vPos.x = 38*GAME_SCALE;
        vPos.y = 10*GAME_SCALE;
        vPos.z = 0;
        
        actor.SetSector(actor.GetSectorIndexAtLocation(vPos));
        actor.Origin() = vPos;
        actor.Origin().z = 0;
        actor.Yaw() = Math::Deg2Rad(90);
        actor.Pitch() = 0;
        actor.Roll() = 0;
        actor.RecoilPitch() = 0;
        actor.Velocity().Clear();
        actor.Movement().Clear();
        
        // animID 202 = Turok killed by Campaigner
        actor.AnimState().Set(anim_campaingerRage, 8.0f, ANF_ROOTMOTION);
        
        Camera.SetLookAtActor(actor.CastToActor());
        Camera.SetFinalView(0);
        
        vPos.x = 38*GAME_SCALE;
        vPos.y = 28*GAME_SCALE;
        vPos.z =  6*GAME_SCALE;
        
        Camera.SetEyeView(vPos);
        
        delay(2.6f);
        
        vPos.x = 10*GAME_SCALE;
        vPos.y = 15*GAME_SCALE;
        vPos.z = actor.Origin().z + (6*GAME_SCALE);
        
        Camera.SetEyeView(vPos);
        Camera.SetLookAtActor(g_pCampaigner);
        
        delay(2.3f);
        
        vPos.x = actor.Origin().x - 6*GAME_SCALE;
        vPos.y = actor.Origin().y;
        vPos.z = actor.Origin().z + (3*GAME_SCALE);
        
        Camera.SetEyeView(vPos);
        Camera.SetLookAtActor(actor.CastToActor());
        
        delay(1.3f);
        Game.HaltMapScript(7);
        PlayLoop.HandlePlayerDeath();
        return;
    }
    
    $restart;
}

/*
==============================================================
Script 5
==============================================================
*/

$script 5
{
    float x, y, z;
    
    for(int i = 0; i < 4; ++i)
    {
        x = Math::RandRange(-2048.0f, 1331.2f);
        y = Math::RandRange(-1177.6f, 1331.2f);
        
        if(x <= 0.0f)
        {
            z = Math::RandRange(0.0f, 307.2f);
        }
        else
        {
            z = 1331.2 - x;
        }
        
        Game.SpawnFx("fx/generic_235.kfx", kVec3(x, y, z), 0);
    }
    
    if((Math::Rand() % -2) != 0)
    {
        Player.Actor().PlaySound("sounds/shaders/generic_218.ksnd");
    }
    else
    {
        Player.Actor().PlaySound("sounds/shaders/explosion_2.ksnd");
    }
    
    delay(0.125f);
    $restart;
}

/*
==============================================================
Script 6
==============================================================
*/

$script 6
{
    Player.Actor().Origin().z = Player.Actor().FloorHeight();
    $restart;
}

/*
==============================================================
Script 7

Handles input from user and cancel cinematic
==============================================================
*/

$script 7
{
    if(Camera.UserInterrupted())
    {
        PlayLoop.HandlePlayerDeath();
        return;
    }
    
    $restart;
}

/*
==============================================================
Script 8
==============================================================
*/

$script 8
{
    if(g_pCampaigner.Health() <= 0)
    {
        Game.CallDelayedMapScript(1, instigator, 0);
        return;
    }
    
    $restart;
}

/*
==============================================================
Script 9
==============================================================
*/

$script 9
{
    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;
}
