Files
beyond/Assets/Plugins/Pixel Crushers/Quest Machine/Scripts/Quest/Quest Subasset/Quest Condition/ParentQuestCondition.cs
2024-11-20 15:21:28 +01:00

134 lines
5.0 KiB
C#

// Copyright (c) Pixel Crushers. All rights reserved.
using UnityEngine;
using System;
namespace PixelCrushers.QuestMachine
{
/// <summary>
/// Quest condition that becomes true when a specified number of parent nodes are true.
/// </summary>
[Serializable]
public class ParentQuestCondition : QuestCondition
{
[Tooltip("How many parents must be true.")]
[SerializeField]
private ConditionCountMode m_parentCountMode = ConditionCountMode.All;
[Tooltip("If Parent Count Mode is Min, at least this many parents must be true.")]
[SerializeField]
private int m_minParentCount;
/// <summary>
/// How many parents must be true.
/// </summary>
public ConditionCountMode parentCountMode
{
get { return m_parentCountMode; }
set { m_parentCountMode = value; }
}
/// <summary>
/// If parentCountMode is ConditionCountMode.Min, at least this many parents must be true.
/// </summary>
public int minParentCount
{
get { return m_minParentCount; }
set { m_minParentCount = value; }
}
public override string GetEditorName()
{
switch (parentCountMode)
{
case ConditionCountMode.All:
return "Parents: All True";
case ConditionCountMode.Any:
return "Parents: Any True";
case ConditionCountMode.Min:
return "Parents: At Least " + minParentCount + " True";
}
return base.GetEditorName();
}
public override void StartChecking(System.Action trueAction)
{
base.StartChecking(trueAction);
ConnectToParentNodes(true);
CheckTrueParentCount();
}
public override void StopChecking()
{
base.StopChecking();
ConnectToParentNodes(false);
}
protected void ConnectToParentNodes(bool add)
{
if (QuestMachine.debug) Debug.Log("Quest Machine: ParentCountQuestCondition.ConnectToParentNodes(" + (add ? "listen for parent changes" : "stop listening for parent changes") + ")", quest);
if (quest == null || quest.nodeList == null || questNode == null || questNode.parentList == null) return;
for (int i = 0; i < questNode.parentList.Count; i++)
{
var parentNode = questNode.parentList[i];
if (parentNode == null) continue;
parentNode.stateChanged -= OnParentStateChange;
if (add) parentNode.stateChanged += OnParentStateChange;
}
}
protected void OnParentStateChange(QuestNode parentNode)
{
if (QuestMachine.debug) Debug.Log("Quest Machine: ParentCountQuestCondition.OnParentStateChange(" + ((parentNode != null) ? parentNode.GetEditorName() : "null") + ")", quest);
var parentIsTrue = (parentNode != null && parentNode.GetState() == QuestNodeState.True);
if (parentIsTrue) CheckTrueParentCount();
}
protected void CheckTrueParentCount()
{
// Count every time this method is called instead of maintaining a counter that we'd have to include in saved games.
int nonoptionalCount;
int optionalCount;
int totalCount;
CountTrueParents(QuestNodeState.True, out nonoptionalCount, out optionalCount, out totalCount);
switch (parentCountMode)
{
case ConditionCountMode.Any:
if (totalCount >= 1) SetTrue();
break;
case ConditionCountMode.All:
if (questNode == null || questNode.nonoptionalParentList == null) break;
if (nonoptionalCount >= questNode.nonoptionalParentList.Count) SetTrue();
break;
case ConditionCountMode.Min:
if (totalCount >= minParentCount) SetTrue();
break;
default:
if (Debug.isDebugBuild) Debug.LogWarning("Quest Machine: Unrecognized ConditionCountMode '" + parentCountMode + "'. Please contact the developer.", quest);
break;
}
}
protected void CountTrueParents(QuestNodeState requiredState, out int nonoptionalCount, out int optionalCount, out int totalCount)
{
nonoptionalCount = 0;
optionalCount = 0;
if (questNode != null && questNode.parentList != null)
{
for (int i = 0; i < questNode.parentList.Count; i++)
{
var parentNode = questNode.parentList[i];
if (parentNode == null) continue;
if (parentNode.GetState() != requiredState) continue;
if (parentNode.isOptional) optionalCount++; else nonoptionalCount++;
}
}
totalCount = nonoptionalCount + optionalCount;
}
}
}