126 lines
3.8 KiB
C#
126 lines
3.8 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using AibisDream.Framework;
|
||
using UnityEngine;
|
||
|
||
namespace AibisDream.MiniGame.Language
|
||
{
|
||
[Serializable]
|
||
public sealed class ExpressionRoundDefinition
|
||
{
|
||
[SerializeField] private string id;
|
||
[SerializeField] private string targetReference;
|
||
[SerializeField] private string tokenReference;
|
||
[SerializeField, Min(0)] private int nonTargetParticleCount;
|
||
|
||
public string Id => id;
|
||
public string TargetReference => targetReference;
|
||
public string TokenReference => tokenReference;
|
||
public int NonTargetParticleCount => nonTargetParticleCount;
|
||
|
||
public bool TryValidate(out string error)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(id))
|
||
{
|
||
error = "轮次 ID 不能为空。";
|
||
return false;
|
||
}
|
||
|
||
if (!LocalizationKit.IsLocalizedParam(targetReference))
|
||
{
|
||
error = $"轮次 '{id}' 的目标文字必须配置为 l10n.* 引用。";
|
||
return false;
|
||
}
|
||
|
||
if (!LocalizationKit.IsLocalizedParam(tokenReference))
|
||
{
|
||
error = $"轮次 '{id}' 的干扰 token 必须配置为 l10n.* 引用。";
|
||
return false;
|
||
}
|
||
|
||
if (nonTargetParticleCount < 0)
|
||
{
|
||
error = $"轮次 '{id}' 的非目标粒子数量不能为负数。";
|
||
return false;
|
||
}
|
||
|
||
error = null;
|
||
return true;
|
||
}
|
||
}
|
||
|
||
[CreateAssetMenu(
|
||
fileName = "ExpressionContentCatalog",
|
||
menuName = AibisAssetMenus.HuoShanExpressionContent)]
|
||
public sealed class ExpressionContentCatalog : ScriptableObject
|
||
{
|
||
[SerializeField] private List<ExpressionRoundDefinition> rounds = new();
|
||
|
||
private Dictionary<string, ExpressionRoundDefinition> roundById;
|
||
|
||
public IReadOnlyList<ExpressionRoundDefinition> Rounds => rounds;
|
||
|
||
public bool TryGetRound(string roundId, out ExpressionRoundDefinition definition)
|
||
{
|
||
EnsureLookup();
|
||
if (string.IsNullOrWhiteSpace(roundId))
|
||
{
|
||
definition = null;
|
||
return false;
|
||
}
|
||
|
||
return roundById.TryGetValue(roundId, out definition);
|
||
}
|
||
|
||
public List<string> GetValidationErrors()
|
||
{
|
||
var errors = new List<string>();
|
||
var ids = new HashSet<string>(StringComparer.Ordinal);
|
||
if (rounds == null || rounds.Count == 0)
|
||
{
|
||
errors.Add("Catalog 中没有表达轮次。");
|
||
return errors;
|
||
}
|
||
|
||
for (int i = 0; i < rounds.Count; i++)
|
||
{
|
||
ExpressionRoundDefinition round = rounds[i];
|
||
if (round == null)
|
||
{
|
||
errors.Add($"rounds[{i}] 为空。");
|
||
continue;
|
||
}
|
||
|
||
if (!round.TryValidate(out string error))
|
||
errors.Add(error);
|
||
if (!string.IsNullOrWhiteSpace(round.Id) && !ids.Add(round.Id))
|
||
errors.Add($"存在重复轮次 ID:'{round.Id}'。");
|
||
}
|
||
|
||
return errors;
|
||
}
|
||
|
||
private void EnsureLookup()
|
||
{
|
||
if (roundById != null)
|
||
return;
|
||
|
||
roundById = new Dictionary<string, ExpressionRoundDefinition>(StringComparer.Ordinal);
|
||
if (rounds == null)
|
||
return;
|
||
|
||
foreach (ExpressionRoundDefinition round in rounds)
|
||
{
|
||
if (round == null || string.IsNullOrWhiteSpace(round.Id) || roundById.ContainsKey(round.Id))
|
||
continue;
|
||
roundById.Add(round.Id, round);
|
||
}
|
||
}
|
||
|
||
private void OnValidate()
|
||
{
|
||
roundById = null;
|
||
}
|
||
}
|
||
}
|