using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices; using UnityEngine; using BITKit; using BITKit.SubSystems.Quest; using UnityEngine.UIElements; using System.Threading.Tasks; namespace BITKit.UX { public class UXQuest : MonoBehaviour { [Header(Constant.Header.Settings)] public bool clearAfterCompleted; [Header(Constant.Header.Reference)] [SerializeReference, SubclassSelector] public IReference completeClassName; [Header(Constant.Header.Prefabs)] public VisualTreeAsset visualTreeAsset; [Header(Constant.Header.InternalVariables)] private readonly Dictionary dictionary = new(); [UXBindPath("quest-container")] private VisualElement _container; private void Start() { UXUtils.Inject(this); QuestSystem.OnQuestCreated += OnQuestCreated; QuestSystem.OnQuestCompleted += OnQuestCompleted; QuestSystem.OnQuestCanceled += OnQuestCanceled; _container.Clear(); } private void OnDestroy() { QuestSystem.OnQuestCreated -= OnQuestCreated; QuestSystem.OnQuestCompleted -= OnQuestCompleted; QuestSystem.OnQuestCanceled -= OnQuestCanceled; } private void OnQuestCreated(QuestSystem.Info quest) { BIT4Log.Log($"已创建任务:{quest.Name}"); if (dictionary.TryGetValue(quest.Name, out var container)) { container.visualElement.RemoveFromClassList(completeClassName.Value); } else { container = new(visualTreeAsset.CloneTree()); dictionary.Add(quest.Name, container); } container.titleLabel.text = quest.Name; container.descriptionLabel.text = quest.Description; _container.Add(container); } private void OnQuestCanceled(QuestSystem.Info quest) { BIT4Log.Log($"已取消任务:{quest.Name}"); if (!dictionary.TryGetValue(quest.Name, out var container)) return; _container.Remove(container); dictionary.Remove(quest.Name); } private async void OnQuestCompleted(QuestSystem.Info quest) { BIT4Log.Log($"已完成任务:{quest.Name}"); if (!dictionary.TryGetValue(quest.Name, out var container)) return; container.visualElement.AddToClassList(completeClassName.Value); container.titleLabel.text = $"已完成:{quest.Name}"; container.visualElement.tabIndex = 256; if (!clearAfterCompleted) return; dictionary.Remove(quest.Name); try { await Task.Delay(8096, destroyCancellationToken); } catch (System.OperationCanceledException) { } catch (System.Exception) { _container.Remove(container); throw; } } } }