using UnityEngine;
using UnityEngine.EventSystems;
using Yarn.Unity;
using Yarn.Markup;
using TMPro;
namespace SLSUtilities.Narrative.UI
{
///
/// 高级选项项,继承自官方 OptionItem。
/// 支持解析选项中的 #desc: 和 #fail: 元数据标签,
/// 通过 OptionTooltipUI 显示选项提示,
/// 以及使用 [kw] Yarn Markup 标签高亮关键词。
///
public class AdvancedOptionItem : OptionItem
{
public string TooltipDesc { get; private set; }
public string TooltipFail { get; private set; }
public TMP_Text GetTextComponent() => text;
// 追踪当前是否是由鼠标指针触发的选中状态
// OnPointerEnter 在 OnSelect 之前同步设置此标记,OnDeselect 清除
private bool _pointerEntered = false;
public override DialogueOption Option
{
get => base.Option;
set
{
// 调用基类 setter:设置 _option、interactable 和 ApplyStyle
// 注意:基类也会设置 text.text,我们稍后会覆盖它
base.Option = value;
// 解析 Tooltip 元数据标签 (#desc: / #fail:)
TooltipDesc = null;
TooltipFail = null;
if (value.Line.Metadata != null)
{
YarnTagParser.Parse(value.Line.Metadata, out var kvTags, out _);
if (kvTags.TryGetValue("desc", out string desc))
{
TooltipDesc = desc.Replace("_", " ");
}
if (kvTags.TryGetValue("fail", out string fail))
{
TooltipFail = fail.Replace("_", " ");
}
}
// 选项文本高亮处理:
// 仅通过 ProcessWithMarkup 处理手动标记的 [kw] 或 [kw id="..."] 标签。
// 不进行正则自动扫描(只高亮明确被 [kw] 标记的部分,与台词表现一致)。
if (text != null)
{
string processed = KeywordProcessor.ProcessWithMarkup(value.Line.TextWithoutCharacterName);
if (disabledStrikeThrough && !value.IsAvailable)
{
processed = $"{processed}";
}
text.text = processed;
}
}
}
public override void OnPointerEnter(PointerEventData eventData)
{
// 在调用 base.OnPointerEnter(其中会同步调用 OnSelect)之前
// 设置标记,使 OnSelect 能知道这是鼠标触发的
_pointerEntered = true;
base.OnPointerEnter(eventData);
}
public override void OnPointerExit(PointerEventData eventData)
{
base.OnPointerExit(eventData);
// 鼠标离开后清除,但不关闭 Tooltip(由 OptionTooltipUI 的文本区域检测控制)
_pointerEntered = false;
}
public override void OnPointerClick(PointerEventData eventData)
{
// 只有当点击的是鼠标左键时,才允许选择并推进此选项,阻断鼠标右键的选择触发
if (eventData.button == PointerEventData.InputButton.Left)
{
base.OnPointerClick(eventData);
}
}
public override void OnSelect(BaseEventData eventData)
{
base.OnSelect(eventData);
// 将"是否为鼠标触发"传递给 OptionTooltipUI,用于决定定位方式
OptionTooltipUI.Instance?.OnOptionSelected(this, _pointerEntered);
}
public override void OnDeselect(BaseEventData eventData)
{
base.OnDeselect(eventData);
_pointerEntered = false;
OptionTooltipUI.Instance?.OnOptionDeselected(this);
}
protected override void OnEnable()
{
base.OnEnable();
if (KeywordTooltipUI.Instance != null && text != null)
{
KeywordTooltipUI.Instance.RegisterExternalText(text);
}
}
protected override void OnDisable()
{
base.OnDisable();
if (KeywordTooltipUI.Instance != null && text != null)
{
KeywordTooltipUI.Instance.UnregisterExternalText(text);
}
}
}
}