//
// 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 Level49.map
//

#include "scripts/common.txt"

kActor @g_pMantisBoss = null;
kActor @g_pKeyPickup = null;

float start_x = 0;
float start_y = 0;

bool g_bStartedFight = false;

/*
==============================================================
RevealKey

Changes pedistal stance and unhides the key pickup
==============================================================
*/

void RevealKey(void)
{
    // lookup pedistal actor
    kActor @actor = World.GetActorByTID(200);
    
    if(!(actor is null))
    {
        // change animation
        actor.AnimState().Set(anim_mantisKeyRaise, 4.0f, 0);
        actor.ModelVariation() = 1;
    }
    
    // change flags for key pickup
    g_pKeyPickup.Flags() |= AF_CANBETOUCHED;
    g_pKeyPickup.Flags() &= ~AF_HIDDEN;
    g_pKeyPickup.Origin().z = 4*GAME_SCALE;
}

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

$script 0
{
    kActor @pillars = World.GetActorByTID(64);
    int state = 0;
    int resetboss = 0;
    
    @g_pMantisBoss = World.GetActorByTID(441);
    @g_pKeyPickup = World.GetActorByTID(2);
    
    // this actor is expected to be in the map.
    // if we get an access null error then something is horribly wrong
    g_pKeyPickup.Flags() &= ~AF_CANBETOUCHED;
    g_pKeyPickup.Flags() |= AF_HIDDEN;
    
    start_x = instigator.Origin().x;
    start_y = instigator.Origin().y;
    
    pillars.AnimState().Set(anim_trapActivate, 4.0f, 0);
    
    GameVariables.GetInt("g_resetboss", resetboss);
 
    // check if boss is already dead, unless resetting boss for warp cheat
    if(resetboss == 0)
    {
        GameVariables.GetInt("mantisState", state);
    
        if(state == MS_DEAD)
        {
            RevealKey();
            return;
        }
    }
    
    Game.CallDelayedMapScript(2, instigator, 0);
}

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

Open doors and set g_bStartedFight to true
==============================================================
*/

$script 1
{
    kActor @door = World.GetActorByTID(50);
    door.AnimState().Blend(anim_trapActivate, 4.0f, 128.0f, 0);
    
    g_bStartedFight = true;
}

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

Check Mantis boss health for death cinematic
==============================================================
*/

$script 2
{
    if(g_pMantisBoss.Health() <= 0)
    {
        Game.CallDelayedMapScript(3, instigator, 0);
        Game.CallDelayedMapScript(4, instigator, 9.0f);
        
        g_bStartedFight = false;
        
        delay(0.35f);
        
        g_pMantisBoss.AnimState().Set(anim_mantisDeath, 8.0f, ANF_ROOTMOTION);
        g_pMantisBoss.Pitch() = 0;
        g_pMantisBoss.Roll() = 0;
        
        return;
    }
    
    $restart;
}

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

Sets up camera for Mantis' cinematic death
==============================================================
*/

$script 3
{
    Camera.StartCinematic();
    Camera.SetLookAtActor(g_pMantisBoss);
    Camera.fov = 74.0f;
    
    PlayLoop.RemoveBossActor();
        
    Camera.SetFinalView(0);
    Camera.SetRotationTrack(0,
                            Math::Deg2Rad(0.0f),    // start angle
                            Math::Deg2Rad(10.0f),   // dest angle
                            40*GAME_SCALE,          // start distance
                            0.01*GAME_SCALE,        // dest distance
                            50*GAME_SCALE,          // start height
                            50*GAME_SCALE,          // dest height
                            4*GAME_SCALE,           // start look at height
                            4*GAME_SCALE);          // dest look at height
                                       
    Camera.AutoPlayRotationTrack(0, 8.0f, CMLT_COSINE);
}

/*
==============================================================
Script 4

Positions player and do victory dance. Reveal key as well.
==============================================================
*/

$script 4
{
    Game.HaltMapScript(3);
    
    Player.Actor().SetPosition(kVec3(start_x, start_y, 0.0f));
    Player.Actor().Yaw() = 0;
    
    Camera.ClearLookAtActor();
    Player.Victory();
    
    RevealKey();
}

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

Mantis defeating poor old Turok
==============================================================
*/

$script 5
{   
    // mantis active yet?
    if(g_bStartedFight == false || g_pMantisBoss.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(6, instigator, 0);
    Game.CallDelayedMapScript(7, instigator, 0);
}

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

Logic for Mantis kill cinematic
==============================================================
*/

$script 6
{
    if(Camera.CinematicState() >= 2)
    {
        kVec3 vPos;
        kPuppet @actor = Player.Actor();
        
        actor.Flags() &= ~AF_NODRAW;
        
        // move mantis into position
        vPos.x = 0*GAME_SCALE;
        vPos.y = -70*GAME_SCALE;
        vPos.z = 0;
        
        g_pMantisBoss.SetSector(g_pMantisBoss.GetSectorIndexAtLocation(vPos));
        g_pMantisBoss.Origin() = vPos;
        g_pMantisBoss.Origin().z = g_pMantisBoss.FloorHeight();
        g_pMantisBoss.Yaw() = Math::pi;
        g_pMantisBoss.Velocity().Clear();
        
        g_pMantisBoss.AnimState().Set(anim_mantisAttackGroundMelee, 4.0f, ANF_NOINTERRUPT);
        Game.CallDelayedMapScript(8, instigator, 0);
        
        // move player into position
        vPos.x = 0*GAME_SCALE;
        vPos.y = -94*GAME_SCALE;
        vPos.z = 0;
        
        actor.SetSector(actor.GetSectorIndexAtLocation(vPos));
        actor.Origin() = vPos;
        actor.Origin().z = 0;
        actor.Yaw() = Math::pi;
        actor.Pitch() = 0;
        actor.RecoilPitch() = 0;
        
        // animID 200 = Turok killed by Mantis
        actor.AnimState().Set(anim_activate, 4.0f, 0);
        
        Camera.SetLookAtActor(actor.CastToActor());
        Camera.SetFinalView(0);
        
        Camera.SetRotationTrack(0,
                            Math::Deg2Rad(-30.0f),  // start angle
                            Math::Deg2Rad(30.0f),   // dest angle
                            12*GAME_SCALE,          // start distance
                            12*GAME_SCALE,          // dest distance
                            2*GAME_SCALE,           // start height
                            4*GAME_SCALE,           // dest height
                            2*GAME_SCALE,           // start look at height
                            4*GAME_SCALE);          // dest look at height
                                       
        Camera.AutoPlayRotationTrack(0, 4.0f, CMLT_COSINE);
        delay(4.0f);
        
        // clear any active camera views so we can modify the eye and focus origins
        Camera.ClearViewTracks();
        Camera.SetFinalView(0);
        Camera.ClearLookAtActor();
        
        // look at the mantis as acid hits the camera
        Camera.SetEyeView(kVec3(0, -94.0f*GAME_SCALE, 6.5f*GAME_SCALE));
        Camera.SetFocusView(kVec3(0, -70.0f*GAME_SCALE, 6.5f*GAME_SCALE));
        
        delay(1.3f);
        Game.HaltMapScript(7);
        Game.HaltMapScript(8);
        PlayLoop.HandlePlayerDeath();
        return;
    }
    
    $restart;
}

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

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

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

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

Updates Mantis animation during kill cinematic
==============================================================
*/

$script 8
{
    switch(g_pMantisBoss.AnimState().PlayingID())
    {
    case anim_mantisAttackGroundMelee:
        if(g_pMantisBoss.AnimState().CycleCompleted())
        {
            g_pMantisBoss.AnimState().Set(anim_aiMelee1, 4.0f, ANF_NOINTERRUPT);
        }
        break;
        
        
    case anim_aiMelee1:
        if(g_pMantisBoss.AnimState().CycleCompleted())
        {
            g_pMantisBoss.AnimState().Set(anim_mantisPain, 4.0f, ANF_NOINTERRUPT);
        }
        break;
        
    case anim_mantisPain:
        if(g_pMantisBoss.AnimState().CycleCompleted())
        {
            g_pMantisBoss.AnimState().Set(anim_mantisAttackGround2, 4.0f, ANF_NOINTERRUPT|ANF_LOOP);
            return;
        }
        break;
    }
    
    $restart;
}
