implemented skill system according to designdocuments

This commit is contained in:
2026-08-15 08:09:29 +02:00
parent f8def361fa
commit 063e94f6eb
95 changed files with 2924 additions and 4 deletions
@@ -0,0 +1,115 @@
using System.Collections;
using UnityEngine;
using Yarn.Unity;
namespace NightclubArcadia.Skills
{
/// <summary>
/// Static Yarn adapter. No MonoBehaviour, no check math — translation only.
/// Call sites: &lt;&lt;check persuasion standard&gt;&gt; / &lt;&lt;check intimidation hard -1&gt;&gt;
/// </summary>
public static class YarnSkillCommands
{
[YarnCommand("check")]
public static IEnumerator Check(string skillId, string difficulty, int modifier = 0)
{
var runtime = SkillRuntime.Instance;
if (runtime == null || runtime.Checks == null || runtime.DialogueRunner == null)
{
Debug.LogError("[YarnSkillCommands] <<check>> called but SkillRuntime is not ready.");
var fallbackRunner = runtime != null ? runtime.DialogueRunner : null;
if (fallbackRunner == null)
{
fallbackRunner = Object.FindFirstObjectByType<DialogueRunner>();
}
WriteFailedResult(fallbackRunner, skillId, difficulty);
yield break;
}
if (!DcBands.TryParse(difficulty, out var dc))
{
Debug.LogError($"[YarnSkillCommands] <<check {skillId} {difficulty}>>: unknown difficulty; treating as Standard (11).");
dc = (int)DcBand.Standard;
}
if (runtime.Database == null || !runtime.Database.TryGet(skillId, out _))
{
Debug.LogError($"[YarnSkillCommands] <<check>>: no skill '{skillId}'.");
}
var result = runtime.Checks.Resolve(skillId, dc, modifier);
WriteResult(runtime.DialogueRunner.VariableStorage, result);
if (runtime.ResultView == null)
{
Debug.LogWarning("[YarnSkillCommands] SkillCheckResultView is not assigned; skipping roll banner.");
yield break;
}
yield return runtime.StartCoroutine(runtime.ResultView.Show(result));
}
[YarnFunction("skill_rank")]
public static float SkillRank(string skillId)
{
var runtime = SkillRuntime.Instance;
if (runtime == null || runtime.Skills == null)
{
return 0f;
}
return runtime.Skills.GetRank(skillId);
}
static void WriteResult(VariableStorageBehaviour storage, SkillCheckResult result)
{
if (storage == null)
{
return;
}
storage.SetValue("$check_result", result.Success);
storage.SetValue("$check_roll", (float)result.Roll);
storage.SetValue("$check_total", (float)result.Total);
storage.SetValue("$check_dc", (float)result.DC);
storage.SetValue("$check_modifier", (float)(result.RankMod + result.SituationalMod + result.StateMod));
storage.SetValue("$check_degree", DegreeToString(result.Degree));
storage.SetValue("$check_skill", result.SkillId ?? string.Empty);
}
static void WriteFailedResult(DialogueRunner runner, string skillId, string difficulty)
{
if (runner == null || runner.VariableStorage == null)
{
return;
}
DcBands.TryParse(difficulty, out var dc);
if (dc == 0)
{
dc = (int)DcBand.Standard;
}
var storage = runner.VariableStorage;
storage.SetValue("$check_result", false);
storage.SetValue("$check_roll", 0f);
storage.SetValue("$check_total", 0f);
storage.SetValue("$check_dc", (float)dc);
storage.SetValue("$check_modifier", 0f);
storage.SetValue("$check_degree", "failure");
storage.SetValue("$check_skill", skillId ?? string.Empty);
}
static string DegreeToString(SkillCheckDegree degree)
{
return degree switch
{
SkillCheckDegree.CriticalFailure => "critical_failure",
SkillCheckDegree.Failure => "failure",
SkillCheckDegree.Success => "success",
SkillCheckDegree.CriticalSuccess => "critical_success",
_ => "failure",
};
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8c00579d400d44ac85b16d9b27be7a87
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: