using System.Collections; using TMPro; using UnityEngine; namespace NightclubArcadia.Skills { /// /// Transparent roll banner. Must show roll, each of the three modifiers, total, and DC. /// public sealed class SkillCheckResultView : MonoBehaviour { [SerializeField] CanvasGroup group; [SerializeField] TMP_Text label; [SerializeField] float holdSeconds = 1.6f; [SerializeField] float fadeSeconds = 0.15f; void Awake() { if (group != null) { group.alpha = 0f; group.blocksRaycasts = false; group.interactable = false; } } public IEnumerator Show(SkillCheckResult result) { if (label != null) { label.text = Format(result); label.color = ResolveAccent(result.SkillId); } if (group == null) { yield return new WaitForSeconds(holdSeconds); yield break; } yield return Fade(0f, 1f); yield return new WaitForSeconds(holdSeconds); yield return Fade(1f, 0f); } static Color ResolveAccent(string skillId) { var runtime = SkillRuntime.Instance; if (runtime != null && runtime.Database != null && runtime.Database.TryGet(skillId, out var def) && def != null) { return def.AccentColor; } return Color.white; } static string Format(SkillCheckResult r) { var outcome = r.Degree switch { SkillCheckDegree.CriticalSuccess => "CRITICAL SUCCESS", SkillCheckDegree.CriticalFailure => "CRITICAL FAILURE", SkillCheckDegree.Success => "SUCCESS", _ => "FAILURE", }; var name = string.IsNullOrEmpty(r.SkillDisplayName) ? (r.SkillId ?? string.Empty).ToUpperInvariant() : r.SkillDisplayName.ToUpperInvariant(); return $"{name} — d20 {r.Roll} {Signed(r.RankMod)} rank {Signed(r.SituationalMod)} situation {Signed(r.StateMod)} state = {r.Total} vs DC {r.DC} · {outcome}"; } static string Signed(int value) => value >= 0 ? $"+{value}" : value.ToString(); IEnumerator Fade(float from, float to) { if (fadeSeconds <= 0f) { group.alpha = to; yield break; } var elapsed = 0f; while (elapsed < fadeSeconds) { elapsed += Time.unscaledDeltaTime; group.alpha = Mathf.Lerp(from, to, Mathf.Clamp01(elapsed / fadeSeconds)); yield return null; } group.alpha = to; } } }