// 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 = PixelCrushers.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();
}
}
}