using UnityEngine;
using UnityEngine.Audio;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System.IO;
using System.Text.RegularExpressions;
using UnityEditor;

[AddComponentMenu("MGUB Event Editor/Scene Event")]
public class SceneEvent : MonoBehaviour
{
	[System.Serializable]
	public class Condition {
		public types type = 0;
		public bool not = false;
		public int intValue1 = 0;
		public int intValue2 = 0;
		public string stringValue1 = "";
        public Object entity1;
		
		public enum types{
			no_condition = 0,			//no condition (always true)
			variable_equal_n = 1,
			variable_greater_n = 2,
			variable_less_n = 3,
			item_present = 4,
			character_active = 5,
            character_alive = 6,
			switch_on = 7,
			main_character_active = 8,
            hp_under_percentage = 9,
            credits_more_than = 10,
            fighting = 11,
            turn_number_equals = 12,
            battle_waiting_stage = 13,
		}
		
		public bool Test () {
			bool result = false;
            GlobalVariables gv;
            if (GlobalVariables.main != null) {
                gv = GlobalVariables.main;
            }
            else {
                return false;
            }
            switch (type){
				case types.no_condition:
					result = true;
					break;
				case types.variable_equal_n:
					result = (gv.variables[intValue1] == intValue2);
					break;
				case types.variable_greater_n:
					result = (gv.variables[intValue1] > intValue2);
					break;
				case types.variable_less_n:
					result = (gv.variables[intValue1] < intValue2);
					break;
				case types.character_active:
                    Entity e_a = (Entity)entity1;
                    result = e_a.enabled;
                    break;
                case types.character_alive:
                    Entity e_b = (Entity)entity1;
                    result = (e_b.parameters.currentHP > 0);
                    break;
                case types.switch_on:
                    result = gv.switches[intValue1];
                    break;
				case types.main_character_active:
                    result = GameInputManager.main.isControllable;
					break;
                case types.hp_under_percentage:
                    Entity e_c = (Entity)entity1;
                    result = (e_c.parameters.currentHP < Mathf.RoundToInt(e_c.parameters.maxHP * intValue1 / 100.0f));
                    break;
                case types.credits_more_than:
                    result = gv.credits > intValue1;
                    break;
                default:
					result = true;
					break;
			}
			if (not){
				result = !result;
			}
			return result;
		}
	}

    [System.Serializable]
    public class Action {
        public SceneEvent scene;
        public types type = 0;
        public bool completed = true;
        public int intValue1 = 0;
        public int intValue2 = 0;
        public int intValue3 = 0;
        public int intValue4 = 0;
        public int intValue5 = 0;
        public int intValue6 = 0;
        public float floatValue1 = 0.0f;
        public float floatValue2 = 0.0f;
        public float floatValue3 = 0.0f;
        public bool boolValue1 = false;
        public bool boolValue2 = false;
        public bool boolValue3 = false;
        //[System.NonSerialized]
        public string tempString1 = "";
        public string tempString2 = "";
        public string tempString3 = "";
        public string tempString4 = "";
        public string tempString5 = "";
        public string stringValue1 = "";
        public Emotion.types emotion1 = Emotion.types.None;
        public Emotion.types emotion2 = Emotion.types.None;
        public Emotion.types emotion3 = Emotion.types.None;
        public Emotion.types emotion4 = Emotion.types.None;
        public SceneEvent event1;
        public SceneEvent event2;
        public SceneEvent event3;
        public SceneEvent event4;
        public Object entity1;
        public Transform transform1;
        public Vector3 vector31;
        public Quaternion quaternion1;
        public AnimationClip animation1;
        public AudioClip audio1;
        public Color color1 = Color.black;
        public Color color2 = Color.black;
        public List<Condition> conditions = new List<Condition>();
        public Texture2D texture1;
        public GlobalVariables.ObjectiveType objectiveType1;

        public enum types {
            do_nothing = 0,
            dialogue = 1,
            look_at = 2,
            wait = 3,
            move_character = 4,
            start_music = 5,
            fade_music = 6,
            start_sound = 7,
            move_camera = 8,
            fade_in = 9,
            fade_out = 10,
            condition_if = 11,
            active_object = 12,
            label = 13,
            go_to_label = 14,
            change_scene = 15,
            set_variable = 16,
            add_to_variable = 17,
            set_active_character = 18,
            set_active_characters = 19,
            animate = 20,
            rotate_character = 21,
            instantiate = 22,
            show_object = 23,
            add_item = 24,
            remove_item = 25,
            add_cash = 26,
            show_decision = 27,
            teleport = 28,
            quake = 29,
            recover_healt = 30,
            set_switch = 31,
            mission_dialogue = 32,
            enable_movement = 33,
            look_at_character = 34,
            stop_looking = 35,
            restore_camera = 36,
            call_event = 37,
            stop_animation = 38,
            appear_letterboxing = 39,
            remove_letterboxing = 40,
            fade_to_color = 41,
            set_variable_to_random = 42,
            end_event = 43,
            set_place = 44,
            set_mission = 45,
            wait_for_action_button = 46,
            enable_component = 47,
            message_box = 48,
            reset_event = 49,
            set_hp = 50,
            update_entity_list = 51,
            update_animator_variable = 52,
            set_mission_position = 53,
            change_ambient_light = 54,
            random_block_break = 55,
            enable_save = 56,
            enable_rigidbody = 57,
            call_autosave = 58,
            add_emotion = 59,
            remove_emotion = 60,
            game_over = 61
        }

        public Action(SceneEvent s) {
            this.scene = s;
        }

        public Action(SceneEvent s, Action a) {
            this.scene = s;
            type = a.type;
            intValue1 = a.intValue1;
            intValue2 = a.intValue2;
            intValue3 = a.intValue3;
            intValue4 = a.intValue4;
            intValue5 = a.intValue5;
            intValue6 = a.intValue6;
            floatValue1 = a.floatValue1;
            floatValue2 = a.floatValue2;
            floatValue3 = a.floatValue3;
            boolValue1 = a.boolValue1;
            boolValue2 = a.boolValue2;
            boolValue3 = a.boolValue3;
            tempString1 = a.tempString1;
            tempString2 = a.tempString2;
            tempString3 = a.tempString3;
            tempString4 = a.tempString4;
            tempString5 = a.tempString5;
            stringValue1 = a.stringValue1;
            event1 = a.event1;
            event2 = a.event2;
            event3 = a.event3;
            event4 = a.event4;
            entity1 = a.entity1;
            transform1 = a.transform1;
            vector31 = a.vector31;
            quaternion1 = a.quaternion1;
            animation1 = a.animation1;
            audio1 = a.audio1;
            color1 = a.color1;
            color2 = a.color2;
            conditions = new List<SceneEvent.Condition>(a.conditions);
            texture1 = a.texture1;
            objectiveType1 = a.objectiveType1;
        }

        public void Execute() {
            completed = false;
            GlobalVariables gv;
            if (GlobalVariables.main != null) {
                gv = GlobalVariables.main;
            }
            else {
                return;
            }
            Entity egoA = null;
            if (entity1 != null && entity1 is Entity) {
                egoA = (Entity)entity1;
            }
            int found = -1;
            switch (type) {
                case types.mission_dialogue:
                    ScriptedScene.CheckForCanvas();
                    UIObjectsContainer.ShowPopup(tempString1, "New objective");
                    if (boolValue1) {
                        gv.mission = tempString1;
                    }
                    completed = true;
                    break;
                case types.dialogue:
                    if (SceneEvent.dialogueCoroutine != null) {
                        SceneEvent.dialogueCoroutineScene.StopCoroutine(SceneEvent.dialogueCoroutine);
                    }
                    SceneEvent.dialogueCoroutine = scene.StartCoroutine(scene.StandardDialogue(this));
                    SceneEvent.dialogueCoroutineScene = scene;
                    break;
                case types.do_nothing:
                    completed = true;
                    break;
                case types.set_variable:
                    gv.variables[intValue1] = intValue2;
                    completed = true;
                    break;
                case types.add_to_variable:
                    gv.variables[intValue1] = gv.variables[intValue1] + intValue2;
                    completed = true;
                    break;
                case types.set_switch:
                    gv.switches[intValue1] = boolValue1;
                    completed = true;
                    break;
                case types.wait:
                    scene.StartCoroutine(scene.Wait(this));
                    break;
                case types.set_active_character:
                    if (entity1 is ThirdPersonController) {
                        GameInputManager.main.isControllable = boolValue1;
                    }
                    else {
                        egoA.controller.enabled = boolValue1;
                    }
                    completed = true;
                    break;
                case types.enable_movement:
                    EnableMovement(boolValue1);
                    completed = true;
                    break;
                case types.look_at:
                    egoA.lookingTarget = transform1;
                    if (boolValue1) {
                        Entity tarE = transform1.GetComponent<Entity>();
                        if (tarE != null) {
                            egoA.lookingTarget = tarE.head;
                        }
                    }
                    completed = true;
                    break;
                case types.look_at_character:
                    if (ThirdPersonController.main != null) {
                        egoA.lookingTarget = ThirdPersonController.main.entity.head;
                    }
                    completed = true;
                    break;
                case types.stop_looking:
                    egoA.lookingTarget = null;
                    completed = true;
                    break;
                case types.move_camera:
                    if (SceneEvent.cameraMovement != null) {
                        SceneEvent.cameraMovementScene.StopCoroutine(SceneEvent.cameraMovement);
                    }
                    SceneEvent.cameraMovement = scene.StartCoroutine(scene.MoveCamera(this));
                    SceneEvent.cameraMovementScene = scene;
                    break;
                case types.restore_camera:
                    if (SceneEvent.cameraMovement != null) {
                        SceneEvent.cameraMovementScene.StopCoroutine(SceneEvent.cameraMovement);
                        SceneEvent.cameraMovement = null;
                        SceneEvent.cameraMovementScene = null;
                    }
                    Camera cam = Camera.main;
                    MouseOrbit mo = cam.GetComponent<MouseOrbit>();
                    if (boolValue2 && ThirdPersonController.main != null) {
                        mo.RecalculateXY(ThirdPersonController.main.transform.eulerAngles);
                    }
                    if (boolValue1) {
                        mo.returningFactor = 0.0f;
                    }
                    else {
                        mo.returningFactor = 1.0f;
                        mo.ForceRotation();
                    }
                    mo.enabled = true;
                    if (cam.transform.parent != null) {
                        cam.transform.parent = null;
                    }
                    completed = true;
                    break;
                case types.show_decision:
                    bool controllablePlayer = GameInputManager.main.isControllable;
                    scene.StartCoroutine(scene.ChoiceDialogue(this));
                    break;
                case types.move_character:
                    if (egoA.scriptedMovement != null) {
                        SceneEvent smse = (SceneEvent)egoA.scriptedMovementScene;
                        smse.StopCoroutine(egoA.scriptedMovement);
                        Animator an = egoA.GetComponent<Animator>();
                        if (an != null && egoA.originalRealtimeAnimator != null) {
                            an.runtimeAnimatorController = egoA.originalRealtimeAnimator;
                            an.CrossFadeInFixedTime(egoA.currentState.fullPathHash, 0.0f);
                        }
                    }
                    egoA.scriptedMovement = scene.StartCoroutine(scene.MoveCharacter(this));
                    egoA.scriptedMovementScene = scene;
                    break;
                case types.rotate_character:
                    scene.StartCoroutine(scene.RotateCharacter(this));
                    break;
                case types.animate:
                    scene.StartCoroutine(scene.Animate(this));
                    break;
                case types.appear_letterboxing:
                    scene.StartCoroutine(scene.AppearLetterboxing(this));
                    break;
                case types.remove_letterboxing:
                    scene.StartCoroutine(scene.RemoveLetterboxing(this));
                    break;
                case types.fade_in:
                    scene.StartCoroutine(scene.FadeIn(this));
                    break;
                case types.fade_out:
                    scene.StartCoroutine(scene.FadeOut(this));
                    break;
                case types.fade_to_color:
                    scene.StartCoroutine(scene.FadeToColor(this));
                    break;
                case types.stop_animation:
                    scene.StartCoroutine(scene.StopAnimation(this));
                    break;
                case types.call_event:
                    scene.StopEvent();
                    if (event1 is SubEvent) {
                        SubEvent sev1 = (SubEvent)event1;
                        sev1.parent = scene;
                    }
                    event1.StartEvent();
                    completed = true;
                    break;
                case types.change_scene:
                    gv.nextLevel = stringValue1;
                    ScriptedScene.CheckForCanvas();
                    UIObjectsContainer ui = UIObjectsContainer.main;
                    ui.StartCoroutine(ui.ChangeScene(this));
                    completed = true;
                    break;
                case types.set_variable_to_random:
                    gv.variables[intValue1] = Random.Range(intValue2, intValue3);
                    completed = true;
                    break;
                case types.end_event:
                    scene.StopEvent();
                    scene.OnEventEnd();
                    completed = true;
                    break;
                case types.condition_if:
                    bool exec = true;
                    for (int j = 0; j < conditions.Count; j++) {
                        if (!conditions[j].Test()) {
                            exec = false;
                            break;
                        }
                    }
                    if (exec) {
                        if (event1 != null) {
                            scene.StopEvent();
                            if (event1 is SubEvent) {
                                SubEvent sev1 = (SubEvent)event1;
                                sev1.parent = scene;
                            }
                            event1.StartEvent();
                        }
                        else {
                            scene.GoToLabel(stringValue1);
                        }
                    }
                    completed = true;
                    break;
                case types.label:
                    completed = true;
                    break;
                case types.go_to_label:
                    scene.GoToLabel(stringValue1);
                    completed = true;
                    break;
                case types.set_place:
                    gv.place = stringValue1;
                    completed = true;
                    break;
                case types.set_mission:
                    gv.mission = GlobalVariables.Translate(stringValue1);
                    completed = true;
                    break;
                case types.start_music:
                    if (SceneEvent.musicChange != null) {
                        SceneEvent.musicChangeScene.StopCoroutine(SceneEvent.musicChange);
                    }
                    SceneEvent.musicChange = scene.StartCoroutine(scene.StartMusic(this));
                    SceneEvent.musicChangeScene = scene;
                    break;
                case types.fade_music:
                    if (SceneEvent.musicChange != null) {
                        SceneEvent.musicChangeScene.StopCoroutine(SceneEvent.musicChange);
                    }
                    SceneEvent.musicChange = scene.StartCoroutine(scene.FadeMusic(this));
                    SceneEvent.musicChangeScene = scene;
                    break;
                case types.start_sound:
                    Vector3 soundPosition;
                    if (transform1 != null) {
                        soundPosition = transform1.TransformPoint(vector31);
                    }
                    else {
                        soundPosition = vector31;
                    }
                    AudioSource source = ScriptedScene.PlayClipAtPoint(audio1, soundPosition);
                    if (boolValue1 && transform1 != null) {
                        source.transform.SetParent(transform1);
                    }
                    completed = true;
                    break;
                case types.active_object:
                    if (entity1 is GameObject) {
                        ((GameObject)entity1).SetActive(boolValue1);
                    }
                    completed = true;
                    break;
                case types.set_active_characters:
                    Entity[] allGoodEntities = FindObjectsOfType<Entity>();
                    for (int i = 0; i < allGoodEntities.Length; i++) {
                        if (allGoodEntities[i].controller != null) {
                            if (allGoodEntities[i].controller is ThirdPersonController) {
                                GameInputManager.main.isControllable = boolValue1;
                            }
                        }
                        if (boolValue1) {
                            allGoodEntities[i].lookingTarget = null;
                        }
                    }
                    completed = true;
                    break;
                case types.instantiate:
                    completed = true;
                    break;
                case types.show_object:
                    completed = true;
                    break;
                case types.add_cash:
                    gv.credits += intValue1;
                    if (gv.credits < 0) {
                        gv.credits = 0;
                    }
                    completed = true;
                    break;
                case types.teleport:
                    if (egoA.scriptedMovement != null) {
                        SceneEvent smse = (SceneEvent)egoA.scriptedMovementScene;
                        smse.StopCoroutine(egoA.scriptedMovement);
                        egoA.scriptedMovement = null;
                        egoA.scriptedMovementScene = null;
                        Animator an = egoA.GetComponent<Animator>();
                        if (an != null && egoA.originalRealtimeAnimator != null) {
                            an.runtimeAnimatorController = egoA.originalRealtimeAnimator;
                            an.CrossFadeInFixedTime(egoA.currentState.fullPathHash, 0.0f);
                        }
                    }
                    egoA.battleMotion = Vector3.zero;
                    ThirdPersonController tTPC = egoA.GetComponent<ThirdPersonController>();
                    if (tTPC != null) {
                        tTPC.Stop();
                    }
                    Transform t1 = egoA.transform;
                    if (transform1 != null) {
                        t1.position = transform1.TransformPoint(vector31);
                        t1.rotation = transform1.rotation * quaternion1;
                    }
                    else {
                        t1.position = vector31;
                        t1.rotation = quaternion1;
                    }
                    if (boolValue1) {
                        Vector3 targetDirection = t1.forward;
                        targetDirection.y = 0.0f;
                        targetDirection.Normalize();
                        t1.rotation = Quaternion.LookRotation(targetDirection);
                    }
                    completed = true;
                    break;
                case types.quake:
                    completed = true;
                    break;
                case types.recover_healt:
                    if (egoA.parameters.currentHP < egoA.parameters.maxHP * egoA.parameters.maxHPBuff) {
                        egoA.parameters.currentHP = Mathf.RoundToInt(egoA.parameters.maxHP * egoA.parameters.maxHPBuff);
                    }
                    if (egoA.parameters.currentStamina < egoA.parameters.maxStamina * egoA.parameters.maxStaminaBuff) {
                        egoA.parameters.currentStamina = Mathf.RoundToInt(egoA.parameters.maxStamina * egoA.parameters.maxStaminaBuff);
                    }
                    if (egoA.parameters.currentMP < egoA.parameters.maxMP * egoA.parameters.maxMPBuff) {
                        egoA.parameters.currentMP = Mathf.RoundToInt(egoA.parameters.maxMP * egoA.parameters.maxMPBuff);
                    }
                    completed = true;
                    break;
                case types.wait_for_action_button:
                    scene.StartCoroutine(scene.WaitForActionButton(this));
                    break;
                case types.enable_component:
                    MonoBehaviour c1 = (MonoBehaviour)entity1;
                    c1.enabled = boolValue1;
                    completed = true;
                    break;
                case types.message_box:
                    scene.StartCoroutine(scene.MessageBox(this));
                    break;
                case types.reset_event:
                    event1.completed = false;
                    completed = true;
                    break;
                case types.set_hp:
                    egoA.parameters.currentHP = intValue1;
                    completed = true;
                    break;
                case types.update_animator_variable:
                    try {
                        Animator an1 = egoA.GetComponent<Animator>();
                        if (intValue1 == 0) {
                            an1.SetBool(stringValue1, boolValue1);
                        }
                        if (intValue1 == 1) {
                            an1.SetInteger(stringValue1, intValue2);
                        }
                        if (intValue1 == 2) {
                            an1.SetFloat(stringValue1, floatValue1);
                        }
                    }
                    catch (System.Exception e) {
                        Debug.LogError("Animation parameter \"" + stringValue1 + "\" is not valid!");
                    }
                    completed = true;
                    break;
                case types.set_mission_position:
                    Vector3 pos = Vector3.zero;
                    if (objectiveType1 != GlobalVariables.ObjectiveType.none) {
                        if (transform1 != null) {
                            pos = transform1.TransformPoint(vector31);
                        }
                        else {
                            pos = vector31;
                        }
                    }
                    float radius = 0.0f;
                    if (objectiveType1 == GlobalVariables.ObjectiveType.area) {
                        radius = floatValue1;
                    }
                    gv.objectiveType = objectiveType1;
                    gv.objectivePosition = pos;
                    gv.objectiveRadius = radius;
                    gv.objectiveScene = SceneManager.GetActiveScene().name;
                    completed = true;
                    break;
                case types.change_ambient_light:
                    RenderSettings.ambientLight = color1;
                    completed = true;
                    break;
                case types.random_block_break:
                    scene.StopEvent();
                    scene.OnEventEnd();
                    completed = true;
                    break;
                case types.enable_save:
                    gv.canSave = boolValue1;
                    gv.saveDeactivationScene = SceneManager.GetActiveScene().name;
                    completed = true;
                    break;
                case types.add_emotion:
                    List<Emotion.types> emotionsList = ThirdPersonController.main.entity.emotions;
                    if (!emotionsList.Contains(emotion1)) {
                        emotionsList.Add(emotion1);
                    }
                    completed = true;
                    break;
                case types.remove_emotion:
                    List<Emotion.types> emotionsListR = ThirdPersonController.main.entity.emotions;
                    if (emotionsListR.Contains(emotion1)) {
                        emotionsListR.Remove(emotion1);
                    }
                    completed = true;
                    break;
                case types.game_over:
                    ThirdPersonController.main.entity.parameters.currentHP = 0;
                    completed = true;
                    break;
                default:
                    completed = true;
                    break;
            }
        }
    }

    public List<Condition> conditions = new List<Condition>();
    public List<Action> actions = new List<Action>();
    protected int currentAction = 0;
    protected bool running = false;
    static public SceneEvent scriptRunning = null;
    static public bool updated = false;
    static public string localization = "English";
    static public List<string> localizations = null;
    static public int localizationIndex = 0;
    static Coroutine cameraMovement = null;
    static SceneEvent cameraMovementScene = null;
    static Coroutine musicChange = null;
    static SceneEvent musicChangeScene = null;
    static Coroutine dialogueCoroutine = null;
    static SceneEvent dialogueCoroutineScene = null;
    static AudioMixer mixer = null;
    public static SceneEvent lastModified;
    public static bool loading = false;
    protected bool completed = false;
    protected bool execNextAction = true;
    protected bool goingToLabel = false;
    public bool lonelyRunning = true;
    public bool canBeInterrupted = false;
    public bool looping = false;
    private List<int> randomBlockBreaks;
    private List<int> lastRandomBlocks = new List<int>();

    void Awake() {
        updated = false;
    }

    void Start() {
        if (!updated) {
            GetDialoguesText();
        }
    }

    public bool IsCompleted() {
        return completed;
    }

    // Update is called once per frame
    void Update () {
        Run();
	}

    public bool CanRun() {
        return !running && (!lonelyRunning || scriptRunning == null || scriptRunning.canBeInterrupted) && !loading;
    }

    public void Run() {
        do {
            if (!completed) {
                if (CanRun()) {
                    running = true;
                    for (int i = 0; i < conditions.Count; i++) {
                        if (!conditions[i].Test()) {
                            running = false;
                            currentAction = 0;
                            execNextAction = true;
                            break;
                        }
                    }
                    if (running) {
                        if (scriptRunning != null && scriptRunning.canBeInterrupted) {
                            scriptRunning.StopEvent();
                        }
                        OnEventStart();
                        currentAction = 0;
                        if (randomBlockBreaks == null) {
                            randomBlockBreaks = new List<int>();
                            randomBlockBreaks.Add(0);
                            for (int i = 0; i < actions.Count; i++) {
                                if (actions[i].type == Action.types.random_block_break) {
                                    randomBlockBreaks.Add(i + 1);
                                }
                            }
                        }
                        if (randomBlockBreaks.Count > 1) {
                            int historySize;
                            if (randomBlockBreaks.Count > 10) {
                                historySize = randomBlockBreaks.Count - 4;
                            }
                            else if (randomBlockBreaks.Count > 5) {
                                historySize = randomBlockBreaks.Count - 3;
                            }
                            else if (randomBlockBreaks.Count > 2) {
                                historySize = randomBlockBreaks.Count - 2;
                            }
                            else {
                                historySize = randomBlockBreaks.Count - 1;
                            }
                            if (lastRandomBlocks.Count > historySize) {
                                lastRandomBlocks.RemoveAt(0);
                            }
                            int currentRandomBlock = Random.Range(0, randomBlockBreaks.Count);
                            int counter = 0;
                            while (lastRandomBlocks.Contains(currentRandomBlock) || counter > 100) {
                                currentRandomBlock = Random.Range(0, randomBlockBreaks.Count);
                                counter++;
                            }
                            currentAction = randomBlockBreaks[currentRandomBlock];
                            lastRandomBlocks.Add(currentRandomBlock);
                        }
                    }
                }
                if (running) {
                    goingToLabel = false;
                    if (currentAction >= actions.Count) {
                        StopEvent();
                        OnEventEnd();
                        return;
                    }
                    if (execNextAction) {
                        actions[currentAction].Execute();
                        execNextAction = false;
                        //Debug.Log("Executing action " +  (currentAction + 1) + ": " + actions[currentAction].type);
                    }
                    if (!goingToLabel) {
                        if (actions[currentAction].completed) {
                            currentAction++;
                            execNextAction = true;
                        }
                    }
                    else {
                        execNextAction = true;
                    }
                }
            }
            if (lonelyRunning && running) {
                scriptRunning = this;
            }
        }
        while (running && !completed && execNextAction);
    }

    public bool IsRunning() {
        return running;
    }

    public static void UpdateDialoguesText() {
        if (updated) {
            return;
        }
        SceneEvent[] allEvents = FindObjectsOfType<SceneEvent>();
        int maxDialogIndex = 0;
        int lastModifiedIndex = -1;
        string[] lines = new string[99999];
        for (int i = 0; i < allEvents.Length; i++) {
            if (lastModified == null || (lastModified != null && allEvents[i] != lastModified)) {
                for (int j = 0; j < allEvents[i].actions.Count; j++) {
                    maxDialogIndex = UpdateAction(allEvents, lines, maxDialogIndex, i, j);
                }
            }
            else {
                //Debug.Log("I found out that last modified SceneEvent is " + lastModified.name);
                lastModifiedIndex = i;
            }
        }
        if (lastModified != null && lastModifiedIndex >= 0) {
            //Debug.Log("Editing " + lastModified.name);
            for (int j = 0; j < allEvents[lastModifiedIndex].actions.Count; j++) {
                maxDialogIndex = UpdateAction(allEvents, lines, maxDialogIndex, lastModifiedIndex, j);
            }
        }
        string res = "";
        for (int i = 0; i <= maxDialogIndex; i++) {
            string cl;
            if (lines[i] != null) {
                cl = lines[i];
            }
            else {
                cl = "";
            }
            cl = cl.Replace("\n", "<br>").Replace("\r", "");
            cl.Trim();
            if (i > 0) {
                res = res + "\n";
            }
            res = res + cl;
        }
        if (res.Length > 2) {
            string path = "Assets/Resources/" + DialogsFile() + ".fnt";
            StreamWriter writer = new StreamWriter(path, false);
            writer.Write(res);
            writer.Close();
        }
        lastModified = null;
        updated = true;
    }

    public static List<SceneEvent> ReplaceDialogueIndex(int from, int to) {
        List<SceneEvent> res = new List<SceneEvent>();
        if (from < 0 || to < 0) {
            return res;
        }
        SceneEvent[] allEvents = FindObjectsOfType<SceneEvent>();
        Action aFrom = null;
        Action aTo = null;
        for (int i = 0; i < allEvents.Length; i++) {
            for (int j = 0; j < allEvents[i].actions.Count; j++) {
                if (allEvents[i].actions[j].type == Action.types.dialogue || allEvents[i].actions[j].type == Action.types.mission_dialogue) {
                    if (allEvents[i].actions[j].intValue1 == from && aFrom == null) {
                        aFrom = allEvents[i].actions[j];
                        aFrom.intValue1 = to;
                    }
                    else if (allEvents[i].actions[j].intValue1 == to && aTo == null) {
                        aTo = allEvents[i].actions[j];
                        aTo.intValue1 = from;
                    }
                }
                if (allEvents[i].actions[j].type == Action.types.show_decision) {
                    if (allEvents[i].actions[j].intValue2 == from && aFrom == null) {
                        aFrom = allEvents[i].actions[j];
                        aFrom.intValue2 = to;
                    }
                    else if (allEvents[i].actions[j].intValue2 == to && aTo == null) {
                        aTo = allEvents[i].actions[j];
                        aTo.intValue2 = from;
                    }
                    if (allEvents[i].actions[j].intValue3 == from && aFrom == null) {
                        aFrom = allEvents[i].actions[j];
                        aFrom.intValue3 = to;
                    }
                    else if (allEvents[i].actions[j].intValue3 == to && aTo == null) {
                        aTo = allEvents[i].actions[j];
                        aTo.intValue3 = from;
                    }
                    if (allEvents[i].actions[j].intValue4 == from && aFrom == null) {
                        aFrom = allEvents[i].actions[j];
                        aFrom.intValue4 = to;
                    }
                    else if (allEvents[i].actions[j].intValue4 == to && aTo == null) {
                        aTo = allEvents[i].actions[j];
                        aTo.intValue4 = from;
                    }
                    if (allEvents[i].actions[j].intValue5 == from && aFrom == null) {
                        aFrom = allEvents[i].actions[j];
                        aFrom.intValue5 = to;
                    }
                    else if (allEvents[i].actions[j].intValue5 == to && aTo == null) {
                        aTo = allEvents[i].actions[j];
                        aTo.intValue5 = from;
                    }
                    if (allEvents[i].actions[j].intValue6 == from && aFrom == null) {
                        aFrom = allEvents[i].actions[j];
                        aFrom.intValue6 = to;
                    }
                    else if (allEvents[i].actions[j].intValue6 == to && aTo == null) {
                        aTo = allEvents[i].actions[j];
                        aTo.intValue6 = from;
                    }
                }
            }
        }
        if (aFrom != null) {
            res.Add(aFrom.scene);
        }
        if (aTo != null && !res.Contains(aTo.scene)){
            res.Add(aTo.scene);
        }
        updated = false;
        GetDialoguesText();
        return res;
    }

    public static int UpdateAction(SceneEvent[] allEvents, string[] lines, int maxDialogIndex, int i, int j) {
        if (allEvents[i].actions[j].type == Action.types.dialogue || allEvents[i].actions[j].type == Action.types.mission_dialogue) {
            //If on the local array I already valued that line it means two of them has the same
            if (lines[allEvents[i].actions[j].intValue1] != null && lines[allEvents[i].actions[j].intValue1] != "") {
                NewDialogueIndex(allEvents[i].actions[j]);
            }
            lines[allEvents[i].actions[j].intValue1] = allEvents[i].actions[j].tempString1;
            if (allEvents[i].actions[j].intValue1 > maxDialogIndex) {
                maxDialogIndex = allEvents[i].actions[j].intValue1;
            }
        }
        if (allEvents[i].actions[j].type == Action.types.show_decision) {
            //Question
            if (lines[allEvents[i].actions[j].intValue2] != null && lines[allEvents[i].actions[j].intValue2] != "") {
                NewDialogueIndex(allEvents[i].actions[j], 1);
            }
            lines[allEvents[i].actions[j].intValue2] = allEvents[i].actions[j].tempString1;
            if (allEvents[i].actions[j].intValue2 > maxDialogIndex) {
                maxDialogIndex = allEvents[i].actions[j].intValue2;
            }
            //Answer 1
            if (lines[allEvents[i].actions[j].intValue3] != null && lines[allEvents[i].actions[j].intValue3] != "") {
                NewDialogueIndex(allEvents[i].actions[j], 2);
            }
            lines[allEvents[i].actions[j].intValue3] = allEvents[i].actions[j].tempString2;
            if (allEvents[i].actions[j].intValue3 > maxDialogIndex) {
                maxDialogIndex = allEvents[i].actions[j].intValue3;
            }
            //Answer 2
            if (lines[allEvents[i].actions[j].intValue4] != null && lines[allEvents[i].actions[j].intValue4] != "") {
                NewDialogueIndex(allEvents[i].actions[j], 3);
            }
            lines[allEvents[i].actions[j].intValue4] = allEvents[i].actions[j].tempString3;
            if (allEvents[i].actions[j].intValue4 > maxDialogIndex) {
                maxDialogIndex = allEvents[i].actions[j].intValue4;
            }
            //Answer 3
            if (lines[allEvents[i].actions[j].intValue5] != null && lines[allEvents[i].actions[j].intValue5] != "") {
                NewDialogueIndex(allEvents[i].actions[j], 4);
            }
            lines[allEvents[i].actions[j].intValue5] = allEvents[i].actions[j].tempString4;
            if (allEvents[i].actions[j].intValue5 > maxDialogIndex) {
                maxDialogIndex = allEvents[i].actions[j].intValue5;
            }
            //Answer 4
            if (lines[allEvents[i].actions[j].intValue6] != null && lines[allEvents[i].actions[j].intValue6] != "") {
                NewDialogueIndex(allEvents[i].actions[j], 5);
            }
            lines[allEvents[i].actions[j].intValue6] = allEvents[i].actions[j].tempString5;
            if (allEvents[i].actions[j].intValue6 > maxDialogIndex) {
                maxDialogIndex = allEvents[i].actions[j].intValue6;
            }
        }
        return maxDialogIndex;
    }

    public static bool GetDialoguesText() {
        if (updated) {
            return false;
        }
        if (Application.isPlaying) {
            ScriptedScene.CheckForGlobalVariables();
        }
        bool changed = false;
        TextAsset textAsset = (TextAsset)Resources.Load(DialogsFile(), typeof(TextAsset));
        if (textAsset == null) {
            return false;
        }
        string[] lines;
        lines = Regex.Split(textAsset.text, "\n|\r|\r\n");
        /*string path = "Assets/Resources/" + DialogsFile() + ".fnt";
        StreamReader reader = new StreamReader(path);
        string[] lines;
        lines = Regex.Split(reader.ReadToEnd(), "\n|\r|\r\n");*/
        SceneEvent[] allEvents = FindObjectsOfType<SceneEvent>();
        for (int i = 0; i < lines.Length; i++) {
            for (int j = 0; j < allEvents.Length; j++) {
                for (int z = 0; z < allEvents[j].actions.Count; z++) {
                    if (allEvents[j].actions[z].type == Action.types.dialogue || allEvents[j].actions[z].type == Action.types.mission_dialogue) {
                        if (allEvents[j].actions[z].intValue1 == i) {
                            lines[i] = lines[i].Replace("<br>", "\n");
                            if (lines[i] != null && lines[i] != "") {
                                //Debug.Log("Updated " + i);
                                if (allEvents[j].actions[z].tempString1 != lines[i]) {
                                    changed = true;
                                }
                                allEvents[j].actions[z].tempString1 = lines[i];
                            }
                        }
                    }
                    if (allEvents[j].actions[z].type == Action.types.show_decision) {
                        if (allEvents[j].actions[z].intValue2 == i) {
                            lines[i] = lines[i].Replace("<br>", "\n");
                            if (lines[i] != null && lines[i] != "") {
                                //Debug.Log("Updated " + i);
                                if (allEvents[j].actions[z].tempString1 != lines[i]) {
                                    changed = true;
                                }
                                allEvents[j].actions[z].tempString1 = lines[i];
                            }
                        }
                        if (allEvents[j].actions[z].intValue3 == i) {
                            lines[i] = lines[i].Replace("<br>", "\n");
                            if (lines[i] != null && lines[i] != "") {
                                //Debug.Log("Updated " + i);
                                if (allEvents[j].actions[z].tempString2 != lines[i]) {
                                    changed = true;
                                }
                                allEvents[j].actions[z].tempString2 = lines[i];
                            }
                        }
                        if (allEvents[j].actions[z].intValue4 == i) {
                            lines[i] = lines[i].Replace("<br>", "\n");
                            if (lines[i] != null && lines[i] != "") {
                                //Debug.Log("Updated " + i);
                                if (allEvents[j].actions[z].tempString3 != lines[i]) {
                                    changed = true;
                                }
                                allEvents[j].actions[z].tempString3 = lines[i];
                            }
                        }
                        if (allEvents[j].actions[z].intValue5 == i) {
                            lines[i] = lines[i].Replace("<br>", "\n");
                            if (lines[i] != null && lines[i] != "") {
                                //Debug.Log("Updated " + i);
                                if (allEvents[j].actions[z].tempString4 != lines[i]) {
                                    changed = true;
                                }
                                allEvents[j].actions[z].tempString4 = lines[i];
                            }
                        }
                        if (allEvents[j].actions[z].intValue6 == i) {
                            lines[i] = lines[i].Replace("<br>", "\n");
                            if (lines[i] != null && lines[i] != "") {
                                //Debug.Log("Updated " + i);
                                if (allEvents[j].actions[z].tempString5 != lines[i]) {
                                    changed = true;
                                }
                                allEvents[j].actions[z].tempString5 = lines[i];
                            }
                        }
                    }
                }
            }
        }
        updated = true;
        return changed;
    }

    public static void WriteHelpFile() {
        if (Application.isPlaying) {
            return;
        }
        TextAsset textAsset = (TextAsset)Resources.Load(DialogsFile(), typeof(TextAsset));
        if (textAsset == null) {
            return;
        }
        string[] lines;
        lines = Regex.Split(textAsset.text, "\n|\r|\r\n");

        string hfd = Application.dataPath + "/Locale/" + localization;
        UnityEngine.SceneManagement.Scene scene = SceneManager.GetActiveScene();
        string hfo = hfd + "/" + scene.name + ".txt";
        if (!Directory.Exists(hfd)) {
            Directory.CreateDirectory(hfd);
        }
        if (!System.IO.File.Exists(hfo)) {
            System.IO.File.Delete(hfo);
        }
        StreamWriter sw = new StreamWriter(hfo, false);

        /*string path = "Assets/Resources/" + DialogsFile() + ".fnt";
        StreamReader reader = new StreamReader(path);
        string[] lines;
        lines = Regex.Split(reader.ReadToEnd(), "\n|\r|\r\n");*/
        HashSet<string> linesSet = new HashSet<string>();
        SceneEvent[] allEvents = FindObjectsOfType<SceneEvent>();
        for (int i = 0; i < lines.Length; i++) {
            for (int j = 0; j < allEvents.Length; j++) {
                for (int z = 0; z < allEvents[j].actions.Count; z++) {
                    string key = (((Entity)allEvents[j].actions[z].entity1).charName + lines[i]).ToLower().Trim();
                    if (!linesSet.Contains(key)) {
                        if (allEvents[j].actions[z].type == Action.types.dialogue) {
                            if (allEvents[j].actions[z].intValue1 == i) {
                                lines[i] = lines[i].Replace("<br>", "\n");
                                if (lines[i] != null && lines[i] != "") {
                                    if (allEvents[j].actions[z].entity1 is Entity) {
                                        sw.WriteLine("• " + (i + 1) + " (" + ((Entity)allEvents[j].actions[z].entity1).charName + "): " + lines[i]);
                                    }
                                }
                            }
                        }
                        if (allEvents[j].actions[z].type == Action.types.show_decision) {
                            if (allEvents[j].actions[z].intValue2 == i) {
                                lines[i] = lines[i].Replace("<br>", "\n");
                                if (lines[i] != null && lines[i] != "") {
                                    if (allEvents[j].actions[z].entity1 is Entity) {
                                        sw.WriteLine("• " + (i + 1) + " (" + ((Entity)allEvents[j].actions[z].entity1).charName + "): " + lines[i]);
                                    }
                                }
                            }
                        }
                        linesSet.Add(key);
                    }
                }
            }
        }
        sw.Close();
    }

    public static void NewDialogueIndex(Action a, int index = 0) {
        switch (index) {
            case 0:
                a.intValue1 = 0;
                break;
            case 1:
                a.intValue2 = 0;
                break;
            case 2:
                a.intValue3 = 0;
                break;
            case 3:
                a.intValue4 = 0;
                break;
            case 4:
                a.intValue5 = 0;
                break;
            case 5:
                a.intValue6 = 0;
                break;
        }
        /*TextAsset textAsset = (TextAsset)Resources.Load(DialogsFile());      //Additional check
        if (textAsset == null) {
            return;
        }*/
        SceneEvent[] allEvents = FindObjectsOfType<SceneEvent>();
        for (int i = 0; i < 99999; i++) {
            bool found = false;
            for (int j = 0; j < allEvents.Length; j++) {
                for (int z = 0; z < allEvents[j].actions.Count; z++) {
                    if (allEvents[j].actions[z].type == Action.types.dialogue || allEvents[j].actions[z].type == Action.types.mission_dialogue) {
                        if (allEvents[j].actions[z].intValue1 == i) {
                            //Debug.Log("Found "+i);
                            found = true;
                            break;
                        }
                    }
                    if (allEvents[j].actions[z].type == Action.types.show_decision) {
                        if (allEvents[j].actions[z].intValue2 == i || allEvents[j].actions[z].intValue3 == i || allEvents[j].actions[z].intValue4 == i || allEvents[j].actions[z].intValue5 == i || allEvents[j].actions[z].intValue6 == i) {
                            found = true;
                            //Debug.Log("Found " + i);
                            break;
                        }
                    }
                }
                if (found) {
                    break;
                }
            }
            if (!found) {
                //Debug.Log("Setting " + i);
                switch (index) {
                    case 0:
                        a.intValue1 = i;
                        break;
                    case 1:
                        a.intValue2 = i;
                        break;
                    case 2:
                        a.intValue3 = i;
                        break;
                    case 3:
                        a.intValue4 = i;
                        break;
                    case 4:
                        a.intValue5 = i;
                        break;
                    case 5:
                        a.intValue6 = i;
                        break;
                }
                //Eventually you can decide to blank the temporary string 'tempString1'
                return;
            }
        }
    }

    public static string DialogsFile() {
        UnityEngine.SceneManagement.Scene scene = SceneManager.GetActiveScene();
        string loc = "";
        if (GlobalVariables.main != null) {
            loc = GlobalVariables.main.localizzation;
            localization = loc;
        }
        else {
            loc = localization;
        }
        return "Text/"+ loc + "/" + scene.name;
    }

    IEnumerator StandardDialogue(Action a) {
        a.completed = false;
        ScriptedScene.CheckForCanvas();
        GameObject UIDiag = UIObjectsContainer.main.UIDialogue;
        float alpha = 0.0f;
        float t = 0.0f;
        bool pressedEnter = false;
        Text text = UIDiag.transform.Find("Text").GetComponent<Text>();
        RawImage divider = UIDiag.transform.Find("Divider").GetComponent<RawImage>();
        Text name = UIDiag.transform.Find("Name").GetComponent<Text>();
        RawImage enterIcon = UIDiag.transform.Find("Enter").GetComponent<RawImage>();
        text.text = a.tempString1;
        name.text = "";
        Entity ent = null;
        if (a.entity1 != null) {
            ent = (Entity)a.entity1;
            name.text = ent.charName;
        }
        PauseMenu.AddToLog(text.text, name.text);
        //Audio
        UnityEngine.SceneManagement.Scene scene = SceneManager.GetActiveScene();
        AudioClip voice = (AudioClip)Resources.Load("Dub/" + SceneEvent.localization + "/" + scene.name + "/" + (a.intValue1+1), typeof(AudioClip));
        AudioSource voiceSource = null;
        if (voice == null) {
            voice = (AudioClip)Resources.Load("Dub/English/" + scene.name + "/" + (a.intValue1+1), typeof(AudioClip));
        }
        if (voice != null) {
            if (ent != null && ent.head != null) {
                voiceSource = ent.head.gameObject.AddComponent<AudioSource>();
                voiceSource.clip = voice;
                voiceSource.volume = 1.0f;
                voiceSource.Play();
                Destroy(voiceSource, voice.length);
            }
            else {
                voiceSource = ScriptedScene.PlayClipAtPoint(voice, Camera.main.transform.position);
            }
            if (mixer == null) {
                mixer = Resources.Load("MasterMixer") as AudioMixer;
            }
            if (mixer != null) {
                voiceSource.outputAudioMixerGroup = mixer.FindMatchingGroups("Voice")[0];
            }
        }
        //Control
        bool hasToPressEnter = true;
        if (ThirdPersonController.main != null) {
            hasToPressEnter = !GameInputManager.main.isControllable && !ThirdPersonController.main.entity.fighting;
        }
        else {
            hasToPressEnter = !GameInputManager.main.isControllable;
        }
        float dialogueTime = a.tempString1.Length / 6.0f;
        if (a.boolValue1) {
            a.completed = true;
        }
        while (alpha >= 0.0f || !pressedEnter) {
            t += Time.deltaTime;
            if (!pressedEnter) {
                alpha += Time.deltaTime * 5.0f;
                if (alpha > 1.0f) {
                    alpha = 1.0f;
                }
            }
            else {
                alpha -= Time.deltaTime * 3.0f;
                if (voiceSource != null) {
                    voiceSource.volume = alpha;
                }
            }
            text.color = new Color(text.color.r, text.color.g, text.color.b, alpha);
            if (name.text != "") {
                divider.color = new Color(divider.color.r, divider.color.g, divider.color.b, alpha);
            }
            name.color = new Color(name.color.r, name.color.g, name.color.b, alpha);
            if (alpha >= 0.5f && !pressedEnter && hasToPressEnter && voice == null) {
                enterIcon.color = new Color(enterIcon.color.r, enterIcon.color.g, enterIcon.color.b, (alpha-0.5f)*2.0f);
            }
            else {
                enterIcon.color = new Color(enterIcon.color.r, enterIcon.color.g, enterIcon.color.b, 0.0f);
            }
            if ((/*Input.GetButtonDown("Action") || Input.GetButtonDown("Skip")*/ GameInputManager.actionButtonDown || GameInputManager.skipping) && t>0.5f /*&& voice == null*/) {
                pressedEnter = true;
                GameInputManager.actionButtonDown = false;
            }
            if (voice!=null && t>voice.length-0.1f && alpha > 0.9f) {
                pressedEnter = true;
            }
            if (!hasToPressEnter && t>dialogueTime) {
                pressedEnter = true;
            }
            if (voice == null && t > dialogueTime * 2.0f) {
                pressedEnter = true;
            }
            if (!running) {
                pressedEnter = true;
            }
            yield return null;
        }
        if (voiceSource != null) {
            Destroy(voiceSource);
        }
        a.completed = true;
        SceneEvent.dialogueCoroutine = null;
        SceneEvent.dialogueCoroutineScene = null;
    }

    IEnumerator ChoiceDialogue(Action a) {
        a.completed = false;
        bool controllablePlayer = GameInputManager.main.isControllable;
        if (controllablePlayer) {
            EnableMovement(false);
        }
        Camera cam = Camera.main;
        MouseOrbit mo = cam.GetComponent<MouseOrbit>();
        ScriptedScene.CheckForCanvas();
        GameObject UIDiag = UIObjectsContainer.main.UIDialogue;
        ChoiceSelector selector;
        selector = UIObjectsContainer.main.ChoiceSelector;
        selector.alpha = 0.0f;
        selector.enabled = true;
        selector.selectionsNumber = a.intValue1;
        selector.texts[0].text = a.tempString2;
        selector.texts[1].text = a.tempString3;
        selector.texts[2].text = "";
        List<Emotion.types> emotionsList = ThirdPersonController.main.entity.emotions;
        selector.SetEmotions(new Emotion.types[4] { a.emotion1, a.emotion2, a.emotion3, a.emotion4 });
        if (selector.selectionsNumber > 2) {
            selector.texts[2].text = a.tempString4;
        }
        selector.texts[3].text = "";
        if (selector.selectionsNumber > 3) {
            selector.texts[3].text = a.tempString5;
        }
        int selected = 0;
        float alpha = 0.0f;
        float t = 0.0f;
        bool pressedEnter = false;
        Text text = UIDiag.transform.Find("Text").GetComponent<Text>();
        RawImage divider = UIDiag.transform.Find("Divider").GetComponent<RawImage>();
        Text name = UIDiag.transform.Find("Name").GetComponent<Text>();
        RawImage enterIcon = UIDiag.transform.Find("Enter").GetComponent<RawImage>();
        float dialogueTime = a.tempString1.Length / 6.0f;
        text.text = a.tempString1;
        name.text = "";
        Entity ent = null;
        if (a.entity1 != null) {
            ent = (Entity)a.entity1;
            name.text = ent.charName;
        }
        PauseMenu.AddToLog(text.text, name.text);
        //Audio
        UnityEngine.SceneManagement.Scene scene = SceneManager.GetActiveScene();
        AudioClip voice = (AudioClip)Resources.Load("Dub/" + SceneEvent.localization + "/" + scene.name + "/" + (a.intValue2 + 1), typeof(AudioClip));
        AudioSource voiceSource = null;
        if (voice == null) {
            voice = (AudioClip)Resources.Load("Dub/English/" + scene.name + "/" + (a.intValue2 + 1), typeof(AudioClip));
        }
        if (voice != null) {
            if (ent != null) {
                voiceSource = ent.head.gameObject.AddComponent<AudioSource>();
                voiceSource.clip = voice;
                voiceSource.volume = 1.0f;
                voiceSource.Play();
                Destroy(voiceSource, voice.length);
            }
            else {
                voiceSource = ScriptedScene.PlayClipAtPoint(voice, Camera.main.transform.position);
            }
            if (mixer == null) {
                mixer = Resources.Load("MasterMixer") as AudioMixer;
            }
            if (mixer != null) {
                voiceSource.outputAudioMixerGroup = mixer.FindMatchingGroups("Voice")[0];
            }
        }
        //Control
        bool camEn;
        camEn = mo.enabled;
        mo.enabled = false;
        t = 0.0f;
        while (alpha < 1.0f || !pressedEnter) {
            t += Time.deltaTime;
            alpha += Time.deltaTime * 5.0f;
            if (alpha > 1.0f) {
                alpha = 1.0f;
            }
            text.color = new Color(text.color.r, text.color.g, text.color.b, alpha);
            if (name.text != "") {
                divider.color = new Color(divider.color.r, divider.color.g, divider.color.b, alpha);
            }
            name.color = new Color(name.color.r, name.color.g, name.color.b, alpha);
            if (alpha >= 0.5f && !pressedEnter) {
                enterIcon.color = new Color(enterIcon.color.r, enterIcon.color.g, enterIcon.color.b, (alpha - 0.5f) * 2.0f);
            }
            else {
                enterIcon.color = new Color(enterIcon.color.r, enterIcon.color.g, enterIcon.color.b, 0.0f);
            }
            if (a.floatValue1 <= 0.0f) {
                if ((/*Input.GetButtonDown("Action") || Input.GetButtonDown("Skip")*/ GameInputManager.actionButtonDown || GameInputManager.skipping) && alpha > 0.5f) {
                    pressedEnter = true;
                    GameInputManager.actionButtonDown = false;
                }
                if (voice != null && t > voice.length - 0.1f && alpha > 0.9f) {
                    pressedEnter = true;
                }
                if (voice == null && t > dialogueTime) {
                    pressedEnter = true;
                }
            }
            else {
                if (t >= a.floatValue1) {
                    pressedEnter = true;
                }
            }
            yield return null;
        }
        if (voiceSource != null) {
            Destroy(voiceSource);
        }
        alpha = 0.0f;
        pressedEnter = false;
        GameInputManager.clicking = false;
        while (alpha >= 0.0f || !pressedEnter) {
            t += Time.deltaTime;
            if (!pressedEnter) {
                alpha += Time.deltaTime * 5.0f;
                if (alpha > 1.0f) {
                    alpha = 1.0f;
                }
            }
            else {
                alpha -= Time.deltaTime * 1.0f;
                if (voiceSource != null) {
                    voiceSource.volume = alpha;
                }
            }
            if (pressedEnter) {
                text.color = new Color(text.color.r, text.color.g, text.color.b, alpha);
                if (name.text != "") {
                    divider.color = new Color(divider.color.r, divider.color.g, divider.color.b, alpha);
                }
                name.color = new Color(name.color.r, name.color.g, name.color.b, alpha);
            }
            if (alpha >= 0.5f && !pressedEnter) {
                enterIcon.color = new Color(enterIcon.color.r, enterIcon.color.g, enterIcon.color.b, (alpha - 0.5f) * 2.0f);
            }
            else {
                enterIcon.color = new Color(enterIcon.color.r, enterIcon.color.g, enterIcon.color.b, 0.0f);
            }
            if ((/*Input.GetButtonDown("Action") || Input.GetMouseButtonDown(0)*/ GameInputManager.actionButtonDown || GameInputManager.clicking) && alpha > 0.99f && selector.selectedButton >= 0 && t > 0.5f) {
                if (selector.CheckEmotion(selector.selectedButton)) {
                    pressedEnter = true;
                    selector.images[selector.selectedButton].color = new Color(0.2f, 0.6f, 1.0f);
                    selected = selector.selectedButton;
                    GameInputManager.actionButtonDown = false;
                    GameInputManager.clicking = false;
                }
            }
            selector.alpha = alpha;
            yield return null;
        }
        if (voiceSource != null) {
            Destroy(voiceSource);
        }
        //PauseMenu.AddToLog(selector.texts[selected].text,"%y");
        selector.alpha = 0.0f;
        //mo.returningFactor = 0.7f;
        mo.enabled = camEn;
        if (controllablePlayer) {
            EnableMovement(true);
        }
        a.completed = true;
        if (selected == 0 && a.event1!=null) {
            StopEvent();
            if (a.event1 is SubEvent) {
                SubEvent sev = (SubEvent)a.event1;
                sev.parent = a.scene;
            }
            a.event1.StartEvent();
        }
        if (selected == 1 && a.event2 != null) {
            StopEvent();
            if (a.event2 is SubEvent) {
                SubEvent sev = (SubEvent)a.event2;
                sev.parent = a.scene;
            }
            a.event2.StartEvent();
        }
        if (selected == 2 && a.event3 != null) {
            StopEvent();
            if (a.event3 is SubEvent) {
                SubEvent sev = (SubEvent)a.event3;
                sev.parent = a.scene;
            }
            a.event3.StartEvent();
        }
        if (selected == 3 && a.event4 != null) {
            StopEvent();
            if (a.event4 is SubEvent) {
                SubEvent sev = (SubEvent)a.event4;
                sev.parent = a.scene;
            }
            a.event4.StartEvent();
        }
    }

    IEnumerator Wait(Action a) {
        a.completed = false;
        yield return new WaitForSeconds(a.floatValue1);
        a.completed = true;
    }

    IEnumerator WaitForActionButton(Action a) {
        a.completed = false;
        while (true) {
            if (/*Input.GetButtonDown("Action")*/ GameInputManager.actionButtonDown) {
                GameInputManager.actionButtonDown = false;
                break;
            }
            yield return null;
        }
        a.completed = true;
    }

    IEnumerator MoveCamera(Action a) {
        a.completed = false;
        if (a.floatValue3 > 0.0f) {
            if (!a.boolValue1) {
                a.completed = true;
            }
            yield return new WaitForSeconds(a.floatValue3);
        }
        Camera cam = Camera.main;
        MouseOrbit mo = cam.GetComponent<MouseOrbit>();
        if (ThirdPersonController.main != null) {
            if (mo.firstView && mo.enabled) {
                Vector3 camFor = cam.transform.forward;
                camFor.y = ThirdPersonController.main.transform.forward.y;
                ThirdPersonController.main.moveDirection = camFor.normalized;
                mo.firstView = false;
                mo.UpdateCharacter();
                mo.firstView = true;
            }
        }
        mo.enabled = false;
        Vector3 originalPosition;
        Quaternion originalRotation;
        if (a.transform1 != null) {
            originalPosition = a.transform1.InverseTransformPoint(cam.transform.position);
            originalRotation = Quaternion.Inverse(a.transform1.rotation) * cam.transform.rotation;
        }
        else {
            originalPosition = cam.transform.position;
            originalRotation = cam.transform.rotation;
        }
        float originalFov = cam.fieldOfView;
        if (a.transform1 != null) {
            cam.transform.parent = a.transform1;
            if (a.floatValue1 > 0.0f) {
                if (!a.boolValue1) {
                    a.completed = true;
                }
                float t = 0.0f;
                while (t < a.floatValue1 + 1.0f) {
                    cam.transform.localPosition = Vector3.Lerp(cam.transform.localPosition, Vector3.Lerp(originalPosition, a.vector31, t / a.floatValue1), Time.deltaTime * 5.0f);
                    cam.transform.localRotation = Quaternion.Slerp(cam.transform.localRotation, Quaternion.Slerp(originalRotation, a.quaternion1, t / a.floatValue1), Time.deltaTime * 5.0f);
                    if (a.floatValue2 > 0.0f) {
                        cam.fieldOfView = Mathf.Lerp(cam.fieldOfView, Mathf.Lerp(originalFov, a.floatValue2, t / a.floatValue1), Time.deltaTime * 5.0f);
                    }
                    t += Time.deltaTime;
                    if (t >= a.floatValue1) {
                        a.completed = true;
                    }
                    yield return null;
                }
                a.completed = true;
            }
            else {
                a.completed = true;
                cam.transform.localPosition = a.vector31;
                cam.transform.localRotation = a.quaternion1;
                if (a.floatValue2 > 0.0f) {
                    cam.fieldOfView = a.floatValue2;
                }
            }
        }
        else {
            cam.transform.parent = null;
            if (a.floatValue1 > 0.0f) {
                if (!a.boolValue1) {
                    a.completed = true;
                }
                float t = 0.0f;
                while (t < a.floatValue1 + 1.0f) {
                    cam.transform.position = Vector3.Lerp(cam.transform.position, Vector3.Lerp(originalPosition, a.vector31, t / a.floatValue1), Time.deltaTime * 9.0f);
                    cam.transform.rotation = Quaternion.Slerp(cam.transform.rotation, Quaternion.Slerp(originalRotation, a.quaternion1, t / a.floatValue1), Time.deltaTime * 9.0f);
                    if (a.floatValue2 > 0.0f) {
                        cam.fieldOfView = Mathf.Lerp(cam.fieldOfView, Mathf.Lerp(originalFov, a.floatValue2, t / a.floatValue1), Time.deltaTime * 9.0f);
                    }
                    t += Time.deltaTime;
                    if (t >= a.floatValue1) {
                        a.completed = true;
                    }
                    yield return null;
                }
                a.completed = true;
            }
            else {
                a.completed = true;
                cam.transform.position = a.vector31;
                cam.transform.rotation = a.quaternion1;
                if (a.floatValue2 > 0.0f) {
                    cam.fieldOfView = a.floatValue2;
                }
            }
        }
        SceneEvent.cameraMovement = null;
        SceneEvent.cameraMovementScene = null;
    }

    public virtual void OnEventStart() {

    }

    public virtual void OnEventEnd() {

    }

    IEnumerator MoveCharacter(Action a) {
        Entity ent = (Entity)a.entity1;
        Animator an = ent.GetComponent<Animator>();
        Transform t1 = ent.transform;
        CharacterController c1 = ent.GetComponent<CharacterController>();
        Quaternion startRot = t1.rotation;
        Transform t2;
        if (a.transform1 != null) {
            t2 = a.transform1;
        }
        Vector3 target;
        if (a.transform1 != null) {
            target = a.transform1.TransformPoint(a.vector31);
        }
        else {
            target = a.vector31;
        }
        if (!a.boolValue1) {
            target.y = t1.position.y;
        }
        Vector3 tarDir = target - t1.position;
        float angle = Vector3.Angle(tarDir, t1.forward);
        float direction = ScriptedScene.AngleDir(t1.forward, tarDir, t1.up);
        AnimatorOverrideController aoc;
        bool turningAnimation = false;
        if (an != null) {
            if (ent.originalRealtimeAnimator == null) {
                ent.originalRealtimeAnimator = an.runtimeAnimatorController;
                ent.currentState = an.GetCurrentAnimatorStateInfo(0);
            }
        }
        if (angle > 5.0f && !a.boolValue3) {
            turningAnimation = true;
            AnimationClip turning;
            if (direction > 0) {
                turning = (AnimationClip)Resources.Load("Animations/turn_left");
            }
            else {
                turning = (AnimationClip)Resources.Load("Animations/turn_right");
            }
            if (an != null) {
                RuntimeAnimatorController myController = an.runtimeAnimatorController;
                AnimatorOverrideController myOverrideController = myController as AnimatorOverrideController;
                if (myOverrideController != null)
                    myController = myOverrideController.runtimeAnimatorController;
                aoc = new AnimatorOverrideController();
                aoc.runtimeAnimatorController = myController;
                aoc["CustomAnimation"] = turning;
                an.runtimeAnimatorController = aoc;
                an.CrossFadeInFixedTime("CustomAnimation", 0.2f);
            }
        }
        if (!a.boolValue2) {
            a.completed = true;
        }
        float time = 0.0f;
        if (!a.boolValue3) {
            Vector3 targetEulerAngles = Quaternion.LookRotation(tarDir.normalized).eulerAngles;
            targetEulerAngles = new Vector3(targetEulerAngles.x, targetEulerAngles.y + a.floatValue2, targetEulerAngles.z);
            while (time < angle * 0.007f) {
                time += Time.deltaTime;
                t1.rotation = Quaternion.Lerp(t1.rotation, Quaternion.Lerp(startRot, Quaternion.Euler(targetEulerAngles), time / (angle * 0.007f)), Time.deltaTime * 12.0f);
                yield return null;
            }
            if (an != null) {
                an.CrossFadeInFixedTime(ent.currentState.fullPathHash, 0.2f);
            }
            t1.rotation = Quaternion.Euler(targetEulerAngles);
        }
        float dist = Vector3.Distance(t1.position, target);
        Vector3 startPos = t1.position;
        time = 0.0f;
        float anSpeed = 0.0f;
        while (time < dist * (0.5f/a.floatValue1) + 0.3f) {
            float time2 = time;
            if (time2 > 1.0f) {
                time2 = 1.0f;
            }
            else if (time2 < 0.01f) {
                time2 = 0.01f;
            }
            time += Time.deltaTime*Mathf.Sqrt(time2);
            float curY = t1.position.y;
            Vector3 newPos = Vector3.Lerp(startPos, target, time / (dist * (0.5f / a.floatValue1)));
            if (!a.boolValue1) {
                newPos.y = curY;
            }
            if (time < dist * (0.5f / a.floatValue1) - 0.1f) {
                if (a.floatValue1 > 1.0f) {
                    anSpeed = Mathf.Lerp(anSpeed, a.floatValue1 * a.floatValue1, Time.deltaTime * 5.0f);
                }
                else if (a.floatValue1 > 0.5f && a.floatValue1 <= 1.0f) {
                    anSpeed = Mathf.Lerp(anSpeed, 1.0f, Time.deltaTime * 5.0f);
                }
                else {
                    anSpeed = Mathf.Lerp(anSpeed, Mathf.Sqrt(a.floatValue1 * 2.0f), Time.deltaTime * 5.0f);
                }
            }
            else {
                anSpeed = Mathf.Lerp(anSpeed, 0.0f, Time.deltaTime * 7.0f);
            }
            if (an != null && Time.deltaTime!=0.0f) {
                an.SetFloat("Speed", anSpeed);
                if (ent.controller is ThirdPersonController) {
                    an.SetFloat("Movement Y", anSpeed);
                }
            }
            if (c1 != null) {
                Vector3 mov = (time2 * (newPos - t1.position));
                if (!a.boolValue1) {
                    mov = mov + (Physics.gravity * Time.deltaTime * 10.0f);
                }
                c1.Move(mov);
            }
            else {
                t1.position = Vector3.Lerp(t1.position, newPos, Time.deltaTime * 5.0f);
            }
            yield return null;
        }
        if (an != null) {
            an.SetFloat("Speed", 0.0f);
            if (ent.controller is ThirdPersonController) {
                an.SetFloat("Movement Y", 0.0f);
            }
        }
        if (an != null && turningAnimation) {
            AnimatorStateInfo animState = an.GetCurrentAnimatorStateInfo(0);
            an.runtimeAnimatorController = ent.originalRealtimeAnimator;
            an.Play(animState.fullPathHash, 0, animState.normalizedTime);
        }
        a.completed = true;
        ent.scriptedMovement = null;
        ent.scriptedMovementScene = null;
    }

    IEnumerator RotateCharacter(Action a) {
        Entity ent = (Entity)a.entity1;
        Animator an = ent.GetComponent<Animator>();
        Transform t1 = ent.transform;
        CharacterController c1 = ent.GetComponent<CharacterController>();
        Quaternion startRot = t1.rotation;
        Transform t2;
        if (a.transform1 != null) {
            t2 = a.transform1;
        }
        Vector3 target;
        if (a.transform1 != null) {
            target = a.transform1.TransformPoint(a.vector31);
        }
        else {
            target = a.vector31;
        }
        if (!a.boolValue1) {
            target.y = t1.position.y;
        }
        Vector3 tarDir = target - t1.position;
        float angle = Vector3.Angle(tarDir, t1.forward);
        float direction = ScriptedScene.AngleDir(t1.forward, tarDir, t1.up);
        AnimatorOverrideController aoc;
        if (an != null) {
            if (ent.originalRealtimeAnimator == null) {
                ent.originalRealtimeAnimator = an.runtimeAnimatorController;
                ent.currentState = an.GetCurrentAnimatorStateInfo(0);
            }
        }
        if (angle > 5.0f && !a.boolValue3) {
            AnimationClip turning;
            if (direction > 0) {
                turning = (AnimationClip)Resources.Load("Animations/turn_left");
            }
            else {
                turning = (AnimationClip)Resources.Load("Animations/turn_right");
            }
            RuntimeAnimatorController myController = an.runtimeAnimatorController;
            AnimatorOverrideController myOverrideController = myController as AnimatorOverrideController;
            if (myOverrideController != null)
                myController = myOverrideController.runtimeAnimatorController;
            aoc = new AnimatorOverrideController();
            aoc.runtimeAnimatorController = myController;
            aoc["CustomAnimation"] = turning;
            an.runtimeAnimatorController = aoc;
            an.CrossFadeInFixedTime("CustomAnimation", 0.2f);
        }
        if (!a.boolValue2) {
            a.completed = true;
        }
        float time = 0.0f;
        while (time < angle * 0.007f) {
            time += Time.deltaTime;
            t1.rotation = Quaternion.Lerp(t1.rotation, Quaternion.Lerp(startRot, Quaternion.LookRotation(tarDir.normalized), time / (angle * 0.007f)), Time.deltaTime * 12.0f);
            yield return null;
        }
        if (an != null && !a.boolValue3) {
            an.CrossFadeInFixedTime(ent.currentState.fullPathHash, 0.2f);
        }
        t1.rotation = Quaternion.LookRotation(tarDir.normalized);
        if (an != null && !a.boolValue3) {
            yield return new WaitForSeconds(0.2f);
            AnimatorStateInfo animState = an.GetCurrentAnimatorStateInfo(0);
            an.runtimeAnimatorController = ent.originalRealtimeAnimator;
            an.Play(animState.fullPathHash, 0, animState.normalizedTime);
        }
        a.completed = true;
    }

    IEnumerator Animate(Action a) {
        Entity ent = (Entity)a.entity1;
        Animator an = ent.GetComponent<Animator>();
        Animation an2 = ent.GetComponent<Animation>();
        AnimatorOverrideController aoc;
        if (an != null) {
            //Debug.Log(ent.charName + ": Animator");
            if (ent.originalRealtimeAnimator == null) {
                ent.originalRealtimeAnimator = an.runtimeAnimatorController;
                ent.currentState = an.GetCurrentAnimatorStateInfo(0);
            }
        }
        if (an != null) {
            RuntimeAnimatorController myController = an.runtimeAnimatorController;
            AnimatorOverrideController myOverrideController = myController as AnimatorOverrideController;
            if (myOverrideController != null)
                myController = myOverrideController.runtimeAnimatorController;
            aoc = new AnimatorOverrideController();
            aoc.runtimeAnimatorController = myController;
            aoc["CustomAnimation"] = a.animation1;
            an.runtimeAnimatorController = aoc;
            float tt = a.floatValue2;
            if (tt < 0.004) {
                tt = 0.004f;
            }
            an.CrossFadeInFixedTime("CustomAnimation", tt);
            if (!a.boolValue1) {
                a.completed = true;
            }
            if (a.floatValue1 > 0.0f) {
                yield return new WaitForSeconds(a.floatValue1);
                if (an != null) {
                    an.CrossFadeInFixedTime(ent.currentState.fullPathHash, tt);
                    yield return new WaitForSeconds(tt);
                    AnimatorStateInfo animState = an.GetCurrentAnimatorStateInfo(0);
                    an.runtimeAnimatorController = ent.originalRealtimeAnimator;
                    an.Play(animState.fullPathHash, 0, animState.normalizedTime);
                }
            }
        }
        else if (an2 != null) {
            //Debug.Log(ent.charName + ": Animation");
            if (an2.GetClip(a.animation1.name) == null) {
                //Debug.Log("Clip "+ a.animation1.name + " not found.");
                an2.AddClip(a.animation1, a.animation1.name);
            }
            an2.Play(a.animation1.name);
            if (!a.boolValue1) {
                a.completed = true;
            }
            else if (a.floatValue1 > 0.0f) {
                yield return new WaitForSeconds(a.floatValue1);
            }
        }
        else {
            Debug.LogError("No animator found!");
        }
        a.completed = true;
    }

    IEnumerator StopAnimation(Action a) {
        Entity ent = (Entity)a.entity1;
        float time = a.floatValue1;
        if (time < 0.004) {
            time = 0.004f;
        }
        Animator an = ent.GetComponent<Animator>();
        if (an != null) {
            an.CrossFadeInFixedTime(ent.currentState.fullPathHash, time);
            yield return new WaitForSeconds(time);
            AnimatorStateInfo animState = an.GetCurrentAnimatorStateInfo(0);
            an.runtimeAnimatorController = ent.originalRealtimeAnimator;
            an.Play(animState.fullPathHash, 0, animState.normalizedTime);
        }
        a.completed = true;
    }

    IEnumerator AppearLetterboxing(Action a) {
        ScriptedScene.CheckForCanvas();
        GameObject tb = UIObjectsContainer.main.LetterboxTopBlack;
        GameObject bb = UIObjectsContainer.main.LetterboxBottomBlack;
        RectTransform tbt = tb.GetComponent<RectTransform>();
        RectTransform bbt = bb.GetComponent<RectTransform>();
        /*RawImage tbi = tb.GetComponent<RawImage>();
        RawImage bbi = tb.GetComponent<RawImage>();*/
        a.completed = true;
        float time = 0.0f;
        while (time < 1.0f) {
            time += Time.deltaTime;
            tbt.localScale = new Vector3(1.0f, Mathf.Lerp(tbt.localScale.y, 1.0f, Time.deltaTime * 5.0f), 1.0f);
            bbt.localScale = tbt.localScale;
            yield return null;
        }
        tbt.localScale = new Vector3(1.0f, 1.0f, 1.0f);
        bbt.localScale = tbt.localScale;
    }

    IEnumerator RemoveLetterboxing(Action a) {
        ScriptedScene.CheckForCanvas();
        GameObject tb = UIObjectsContainer.main.LetterboxTopBlack;
        GameObject bb = UIObjectsContainer.main.LetterboxBottomBlack;
        RectTransform tbt = tb.GetComponent<RectTransform>();
        RectTransform bbt = bb.GetComponent<RectTransform>();
        /*RawImage tbi = tb.GetComponent<RawImage>();
        RawImage bbi = tb.GetComponent<RawImage>();*/
        a.completed = true;
        float time = 0.0f;
        while (time < 1.0f) {
            time += Time.deltaTime;
            tbt.localScale = new Vector3(1.0f, Mathf.Lerp(tbt.localScale.y, 0.0f, Time.deltaTime * 5.0f), 1.0f);
            bbt.localScale = tbt.localScale;
            yield return null;
        }
        tbt.localScale = new Vector3(1.0f, 0.0f, 1.0f);
        bbt.localScale = tbt.localScale;
    }

    IEnumerator FadeIn(Action a) {
        ScriptedScene.CheckForCanvas();
        if (!a.boolValue1) {
            a.completed = true;
        }
        if (Time.timeSinceLevelLoad < 0.2f) {
            yield return new WaitForSeconds(0.2f);
        }
        GameObject f = UIObjectsContainer.main.Fade;
        RawImage fi = f.GetComponent<RawImage>();
        float time = 0.0f;
        while (time < a.floatValue1) {
            time += Time.unscaledDeltaTime;
            fi.color = new Color(a.color1.r, a.color1.g, a.color1.b, 1 - (time / a.floatValue1));
            yield return null;
        }
        fi.color = new Color(a.color1.r, a.color1.g, a.color1.b, 0.0f);
        a.completed = true;
    }

    IEnumerator FadeOut(Action a) {
        ScriptedScene.CheckForCanvas();
        GameObject f = UIObjectsContainer.main.Fade;
        RawImage fi = f.GetComponent<RawImage>();
        if (!a.boolValue1) {
            a.completed = true;
        }
        float time = 0.0f;
        while (time < a.floatValue1) {
            time += Time.unscaledDeltaTime;
            fi.color = new Color(a.color1.r, a.color1.g, a.color1.b, time / a.floatValue1);
            yield return null;
        }
        fi.color = new Color(a.color1.r, a.color1.g, a.color1.b, 1.0f);
        a.completed = true;
    }

    IEnumerator FadeToColor(Action a) {
        ScriptedScene.CheckForCanvas();
        GameObject f = UIObjectsContainer.main.Fade;
        RawImage fi = f.GetComponent<RawImage>();
        if (!a.boolValue1) {
            a.completed = true;
        }
        float time = 0.0f;
        while (time < a.floatValue1) {
            time += Time.unscaledDeltaTime;
            fi.color = Color.Lerp(a.color1, a.color2, time / a.floatValue1);
            yield return null;
        }
        fi.color = a.color2;
        a.completed = true;
    }
    
    public static void ResetStaticVars() {
        scriptRunning = null;
        updated = false;
        cameraMovement = null;
        cameraMovementScene = null;
        musicChange = null;
        musicChangeScene = null;
        dialogueCoroutine = null;
        dialogueCoroutineScene = null;
        loading = false;
    }

    IEnumerator StartMusic(Action a) {
        AudioSource cameraMusicSource;
        if (!a.boolValue1) {
            a.completed = true;
        }
        cameraMusicSource = Camera.main.GetComponent<AudioSource>();
        float time;
        float targetVolume = a.floatValue2;
        if (cameraMusicSource.clip == null || cameraMusicSource.clip != a.audio1) {
            if (a.floatValue1 > 0.0f) {
                if (cameraMusicSource.clip != null) {
                    float startVolume = cameraMusicSource.volume;
                    time = 0.0f;
                    while (time < a.floatValue1) {
                        time += Time.unscaledDeltaTime;
                        cameraMusicSource.volume = Mathf.Lerp(startVolume, 0.0f, time / a.floatValue1);
                        yield return null;
                    }
                }
                cameraMusicSource.Stop();
                cameraMusicSource.clip = a.audio1;
                if (a.boolValue2) {
                    cameraMusicSource.volume = targetVolume;
                }
                else {
                    cameraMusicSource.volume = 0.0f;
                }
                cameraMusicSource.Play();
                if (!a.boolValue2) {
                    time = 0.0f;
                    while (time < a.floatValue1) {
                        time += Time.unscaledDeltaTime;
                        cameraMusicSource.volume = Mathf.Lerp(0.0f, targetVolume, time / a.floatValue1);
                        yield return null;
                    }
                }
            }
            else {
                cameraMusicSource.Stop();
                cameraMusicSource.clip = a.audio1;
                cameraMusicSource.volume = targetVolume;
                cameraMusicSource.Play();
            }
        }
        else {
            if (a.floatValue1 > 0.0f) {
                if (cameraMusicSource.clip != null) {
                    float startVolume = cameraMusicSource.volume;
                    time = 0.0f;
                    while (time < a.floatValue1) {
                        time += Time.unscaledDeltaTime;
                        cameraMusicSource.volume = Mathf.Lerp(startVolume, targetVolume, time / a.floatValue1);
                        yield return null;
                    }
                }
                else {
                    cameraMusicSource.volume = targetVolume;
                }
            }
            else {
                cameraMusicSource.volume = targetVolume;
            }
        }
        a.completed = true;
        SceneEvent.musicChange = null;
        SceneEvent.musicChangeScene = null;
    }

    IEnumerator FadeMusic(Action a) {
        AudioSource cameraMusicSource;
        if (!a.boolValue1) {
            a.completed = true;
        }
        cameraMusicSource = Camera.main.GetComponent<AudioSource>();
        float time;
        if (cameraMusicSource.clip != null) {
            if (a.floatValue1 > 0.0f) {
                float startVolume = cameraMusicSource.volume;
                time = 0.0f;
                while (time < a.floatValue1) {
                    time += Time.unscaledDeltaTime;
                    cameraMusicSource.volume = Mathf.Lerp(startVolume, 0.0f, time / a.floatValue1);
                    yield return null;
                }
                cameraMusicSource.clip = null;
            }
            else {
                cameraMusicSource.clip = null;
            }
        }
        a.completed = true;
        SceneEvent.musicChange = null;
        SceneEvent.musicChangeScene = null;
    }

    public void StartEvent() {
        running = true;
    }

    public void StopEvent() {
        currentAction = 0;
        if (!looping) {
            completed = true;
        }
        running = false;
        execNextAction = true;
        if (lonelyRunning) {
            scriptRunning = null;
        }
    }

    void OnDrawGizmosSelected() {
        DrawDefaultGizmoz();
    }

    public void DrawDefaultGizmoz() {
        int i = 0;
        Color oldGizmoColor = Gizmos.color;
        Dictionary<Transform, Vector3> curPos = new Dictionary<Transform, Vector3>();
        for (i = 0; i < actions.Count; i++) {
            if (actions[i].type == Action.types.move_character && actions[i].entity1 != null) {
                Vector3 target;
                if (actions[i].transform1 != null) {
                    target = actions[i].transform1.TransformPoint(actions[i].vector31) + new Vector3(0.0f, 0.5f, 0.0f);
                }
                else {
                    target = actions[i].vector31 + new Vector3(0.0f, 0.5f, 0.0f);
                }
                Entity e = (Entity)actions[i].entity1;
                Vector3 start = e.transform.position;
                if (curPos.ContainsKey(e.transform)) {
                    start = curPos[e.transform] - new Vector3(0.0f, 0.5f, 0.0f);
                }
                else {
                    curPos.Add(e.transform, target);
                }
                Quaternion direction = Quaternion.LookRotation(target - start - new Vector3(0.0f, 0.5f, 0.0f));
                Gizmos.color = Color.yellow;
                Gizmos.DrawLine(start + new Vector3(0.0f, 0.5f, 0.0f), target);
                Gizmos.DrawLine(target, target + (direction * new Vector3(-0.2f, 0.0f, -0.2f)));
                Gizmos.DrawLine(target, target + (direction * new Vector3(0.2f, 0.0f, -0.2f)));
            }
            if (actions[i].type == Action.types.rotate_character && actions[i].entity1 != null) {
                Vector3 target;
                if (actions[i].transform1 != null) {
                    target = actions[i].transform1.TransformPoint(actions[i].vector31) + new Vector3(0.0f, 0.5f, 0.0f);
                }
                else {
                    target = actions[i].vector31 + new Vector3(0.0f, 0.5f, 0.0f);
                }
                Entity e = (Entity)actions[i].entity1;
                Vector3 start = e.transform.position;
                Quaternion direction = Quaternion.LookRotation(target - start - new Vector3(0.0f, 0.5f, 0.0f));
                target = start + (direction * new Vector3(0.0f, 0.0f, 0.5f)) + new Vector3(0.0f, 0.5f, 0.0f);
                Gizmos.color = Color.magenta;
                Gizmos.DrawLine(start + new Vector3(0.0f, 0.5f, 0.0f), target);
                Gizmos.DrawLine(target, target + (direction * new Vector3(-0.2f, 0.0f, -0.2f)));
                Gizmos.DrawLine(target, target + (direction * new Vector3(0.2f, 0.0f, -0.2f)));
            }
            if (actions[i].type == Action.types.move_camera) {
                Vector3 camPos;
                Quaternion camRot;
                if (actions[i].transform1 != null) {
                    camPos = actions[i].transform1.TransformPoint(actions[i].vector31);
                    camRot = actions[i].transform1.rotation * actions[i].quaternion1;
                }
                else {
                    camPos = actions[i].vector31;
                    camRot = actions[i].quaternion1;
                }
                float fov = actions[i].floatValue2;
                if (fov == 0) {
                    fov = 60.0f;
                }
                Matrix4x4 temp = Gizmos.matrix;
                Gizmos.matrix = Matrix4x4.TRS(camPos, camRot, Vector3.one);
                Gizmos.color = new Color(0.0f, 0.55f, 0.8f);
                Gizmos.DrawFrustum(Vector3.zero, fov, 0.5f, 0.05f, 1.77777f);
                Gizmos.matrix = temp;
            }
            if (actions[i].type == Action.types.teleport) {
                Vector3 tPos;
                Quaternion tRot;
                if (actions[i].transform1 != null) {
                    tPos = actions[i].transform1.TransformPoint(actions[i].vector31);
                    tRot = actions[i].quaternion1 * actions[i].transform1.rotation;
                }
                else {
                    tPos = actions[i].vector31;
                    tRot = actions[i].quaternion1;
                }
                Gizmos.color = Color.yellow;
                Gizmos.DrawLine(tPos, tPos + (tRot * new Vector3(0.0f, 0.0f, 0.5f)));
                Gizmos.color = Color.magenta;
                Gizmos.DrawLine(tPos, tPos + (tRot * new Vector3(0.0f, 0.5f, 0.0f)));
                Gizmos.DrawLine(tPos, tPos + (tRot * new Vector3(0.5f, 0.0f, 0.0f)));
                Gizmos.DrawLine(tPos, tPos + (tRot * new Vector3(0.0f, 0.0f, -0.5f)));
                Gizmos.DrawLine(tPos, tPos + (tRot * new Vector3(0.0f, -0.5f, 0.0f)));
                Gizmos.DrawLine(tPos, tPos + (tRot * new Vector3(-0.5f, 0.0f, 0.0f)));
            }
        }
        Gizmos.color = oldGizmoColor;
    }

    public void GoToLabel(string s) {
        int i = 0;
        for (i = 0; i < actions.Count; i++) {
            if (actions[i].type == Action.types.label) {
                if (actions[i].stringValue1.ToLower() == s.ToLower()) {
                    currentAction = i;
                    goingToLabel = true;
                }
            }
        }
        if (!goingToLabel) {
            Debug.LogError("Lable ''" + s + "'' not found");
        }
    }

    IEnumerator MessageBox(Action a) {
        a.completed = false;
        ScriptedScene.CheckForCanvas();
        GameObject mb = UIObjectsContainer.main.messageBox.gameObject;
        mb.SetActive(true);
        float alpha = 0.0f;
        float t = 0.0f;
        bool pressedEnter = false;
        Text text = UIObjectsContainer.main.messageBoxText;
        Text title = UIObjectsContainer.main.messageBoxTitle;
        RawImage image = UIObjectsContainer.main.messageBoxImage;
        text.text = GlobalVariables.Translate(a.tempString2);
        if (!a.tempString2.StartsWith("&wdesc_")){
            title.text = GlobalVariables.Translate(a.tempString1);
        }
        else {
            title.text = a.tempString1;
        }
        image.enabled = a.texture1 != null;
        if (a.texture1 != null) {
            image.texture = a.texture1;
        }
        PauseMenu.AddToLog(text.text, title.text);
        //Control
        float dialogueTime = a.tempString1.Length / 6.0f;
        while (alpha >= 0.0f || !pressedEnter) {
            t += Time.unscaledDeltaTime;
            if (!pressedEnter) {
                alpha += Time.unscaledDeltaTime * 5.0f;
                if (alpha > 1.0f) {
                    alpha = 1.0f;
                }
            }
            else {
                alpha -= Time.unscaledDeltaTime * 3.0f;
            }
            UIObjectsContainer.main.messageBox.alpha = alpha;
            if ((/*Input.GetButtonDown("Action") || Input.GetButtonDown("Skip")*/ GameInputManager.actionButtonDown || GameInputManager.skipping) && alpha > 0.5f) {
                pressedEnter = true;
                GameInputManager.actionButtonDown = false;
            }
            yield return null;
        }
        mb.SetActive(false);
        a.completed = true;
    }

    IEnumerator Quake(Action a) {
        a.completed = false;
        if (a.boolValue1) {
            a.completed = true;
        }
        float time = 0.0f;
        while (time >= a.floatValue2) {
            time += Time.deltaTime;
            MouseOrbit.Quake(a.floatValue1);
            yield return null;
        }
        if (a.boolValue2) {
            MouseOrbit.StopQuake();
        }
        a.completed = true;
    }

    public static void EnableMovement(bool enable) {
        if (ThirdPersonController.main != null) {
            Entity playerEntity = ThirdPersonController.main.entity;
            if (playerEntity.scriptedMovement != null && enable) {
                SceneEvent smse = (SceneEvent)playerEntity.scriptedMovementScene;
                smse.StopCoroutine(playerEntity.scriptedMovement);
                Animator an = playerEntity.GetComponent<Animator>();
                if (an != null && playerEntity.originalRealtimeAnimator != null) {
                    an.runtimeAnimatorController = playerEntity.originalRealtimeAnimator;
                    an.CrossFadeInFixedTime(playerEntity.currentState.fullPathHash, 0.0f);
                }
            }
        }
        GameInputManager.main.isControllable = enable;
    }

    /*
    #if UNITY_EDITOR
        [MenuItem("GameObject/MGUB Event System/Event", false, 10)]
        static void CreateEvent(MenuCommand menuCommand) {
            GameObject parent = menuCommand.context as GameObject;
            if (parent != null) {
                GameObject go = new GameObject(parent.name.Replace(" ", "") + "Event");
                go.AddComponent<SceneEvent>();
                GameObjectUtility.SetParentAndAlign(go, parent);
                Undo.RegisterCreatedObjectUndo(go, "Create " + go.name);
                Selection.activeObject = go;
            }
        }
    #endif
    */
}
