// Copyright (c) Pixel Crushers. All rights reserved. using UnityEngine; using UnityEngine.Events; namespace PixelCrushers.DialogueSystem { /// /// Increments an element of the Lua Variable[] table when the GameObject is destroyed or /// disabled, and then updates the quest tracker if it's attached to the Dialogue Manager /// object or its children. This script is useful for kill quests or gathering quests. /// [AddComponentMenu("")] // Use wrapper. public class IncrementOnDestroy : MonoBehaviour { public enum IncrementOn { Destroy, Disable, Manually } [Tooltip("Increment on Destroy or Disable.")] public IncrementOn incrementOn = IncrementOn.Destroy; /// /// The variable to increment. /// [Tooltip("Increment this Dialogue System variable.")] [VariablePopup(true)] public string variable = string.Empty; /// /// The increment amount. To decrement, use a negative number. /// [Tooltip("Increment the variable by this amount. Use a negative value to decrement.")] public int increment = 1; /// /// The minimum value. /// [Tooltip("After incrementing, ensure that the variable is at least this value.")] public int min = 0; /// /// The maximum value. /// [Tooltip("After incrementing, ensure that the variable is no more than this value.")] public int max = 100; [Tooltip("Optional alert message to show when incrementing.")] public string alertMessage = string.Empty; [Tooltip("Duration to show alert, or 0 to use default duration.")] public float alertDuration = 0; [Tooltip("If set, only increment if the conditions are true.")] public Condition condition = new Condition(); public UnityEvent onIncrement = new UnityEvent(); protected bool listenForOnDestroy = false; protected bool awakeMarkedForDestroy = false; protected virtual string actualVariableName { get { return string.IsNullOrEmpty(variable) ? DialogueActor.GetPersistentDataName(transform) : variable; } } protected string ActualVariableName { get { return actualVariableName; } } // Kept for 1.x compatibility. protected virtual void Awake() { // Check if a DestructibleSaver on the same GameObject will be destroying this // object when save data is applied. If so, ignore the OnDestroy: var destructibleSaver = GetComponent(); if (destructibleSaver != null) { var saveSystem = GameObjectUtility.FindFirstObjectByType(); if (saveSystem != null) { if (SaveSystem.currentSavedGameData != null) { var destructibleSaverKey = destructibleSaver.key; var s = SaveSystem.currentSavedGameData.GetData(destructibleSaverKey); if (!string.IsNullOrEmpty(s)) { var data = SaveSystem.Deserialize(s); if (data != null && data.destroyed) { listenForOnDestroy = false; awakeMarkedForDestroy = true; } } } } } } /// /// Only listen for OnDestroy if the script has been enabled. /// public virtual void OnEnable() { listenForOnDestroy = !awakeMarkedForDestroy; PersistentDataManager.RegisterPersistentData(gameObject); } /// /// If the level is being unloaded, this GameObject will be destroyed. /// We don't want to count this in the variable, so disable the script. /// public virtual void OnLevelWillBeUnloaded() { listenForOnDestroy = false; } /// /// If the application is ending, don't listen, as this can log errors /// in the console. /// public virtual void OnApplicationQuit() { listenForOnDestroy = false; } /// /// When this object is destroyed, increment the counter and update the quest tracker /// if incrementOn is set to Destroy. /// public virtual void OnDestroy() { if (incrementOn == IncrementOn.Destroy) TryIncrement(); } /// /// When this object is disabled, increment the counter and update the quest tracker /// if incrementOn is set to Disable. /// public virtual void OnDisable() { PersistentDataManager.UnregisterPersistentData(gameObject); if (incrementOn == IncrementOn.Disable) TryIncrement(); } /// /// Try to increment variable if conditions are met. /// public virtual void TryIncrement() { if (CanIncrement()) { IncrementNow(); } } /// /// Are the conditions correct to increment? /// protected virtual bool CanIncrement() { return Application.isPlaying && listenForOnDestroy && (DialogueManager.Instance != null && DialogueManager.DatabaseManager != null && DialogueManager.MasterDatabase != null) && condition.IsTrue(null); } /// /// Increments variable. Assumes conditions to increment have already been checked and passed. /// protected virtual void IncrementNow() { int oldValue = DialogueLua.GetVariable(actualVariableName).asInt; int newValue = Mathf.Clamp(oldValue + increment, min, max); DialogueLua.SetVariable(actualVariableName, newValue); DialogueManager.SendUpdateTracker(); if (!(string.IsNullOrEmpty(alertMessage) || DialogueManager.instance == null)) { if (Mathf.Approximately(0, alertDuration)) { DialogueManager.ShowAlert(alertMessage); } else { DialogueManager.ShowAlert(alertMessage, alertDuration); } } onIncrement.Invoke(); } } }