using System; using System.Collections.Generic; using UnityEngine; // DialogGroup 하나가 활성화되기 위한 조건 묶음. 모든 항목을 만족해야 한다(AND). // 진행도/호감도는 범위(양끝 포함)로 지정한다. 기본 범위 = 조건 없음. 트리거 목록은 비워두면 조건 없음. [Serializable] public class DialogCondition : ISerializationCallbackReceiver { const int MaxProgressDefault = 9999; const int MaxAffectionDefault = 100; [Tooltip("메인 진행도가 이 범위 안이어야 함 (양끝 포함). 기본 0~9999 = 조건 없음")] public IntRange MainProgress = new(0, MaxProgressDefault); [Tooltip("이 NPC의 호감도가 이 범위 안이어야 함 (양끝 포함). 기본 0~100 = 조건 없음. " + "예: 0~10 = 호감도가 낮을 때만, 50~100 = 호감도가 쌓인 뒤에만")] public IntRange Affection = new(0, MaxAffectionDefault); [Tooltip("켜져 있어야 하는 트리거 Id들 (전부 필요). StoryManager.SetTrigger로 켠다")] public List RequiredTriggerIds = new(); [Tooltip("켜지면 이 대화가 비활성화되는 트리거 Id들 (하나라도 켜졌으면 비활성화). " + "예: 특정 사건 이후엔 더 못 보는 대사")] public List ExcludedTriggerIds = new(); // 인스펙터에서 리스트에 새로 추가된 항목은 필드 초기화식이 무시되고 전부 0으로 생성된다. // 그대로면 범위가 0~0(사실상 잠긴 대화)이 되므로, 처음 만들어진 인스턴스에만 기본 범위를 넣어준다. [SerializeField, HideInInspector] private bool _initialized = true; public void OnBeforeSerialize() { } public void OnAfterDeserialize() { if (_initialized) return; _initialized = true; MainProgress = new IntRange(0, MaxProgressDefault); Affection = new IntRange(0, MaxAffectionDefault); } // affectionTarget: 호감도 조건을 검사할 캐릭터 (보통 대화를 거는 NPC 자신) public bool IsMet(CharacterData affectionTarget) { var story = StoryManager.Instance; if (!MainProgress.Contains(story.MainProgress)) return false; if (!Affection.Contains(story.GetAffection(affectionTarget))) return false; foreach (var id in RequiredTriggerIds) if (!string.IsNullOrEmpty(id) && !story.HasTrigger(id)) return false; foreach (var id in ExcludedTriggerIds) if (!string.IsNullOrEmpty(id) && story.HasTrigger(id)) return false; return true; } }