Files
aibis-dream/Assets/Scripts/MiniGame/HuoShan/Language/ExpressionContentCatalog.cs
T
dingyuntian ca5b714124 feat: 火山玩法本地化
仍有硬编码残留,待处理
2026-07-28 19:13:53 +08:00

131 lines
4.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 string actorLoopReference;
[SerializeField] private List<ExpressionRoundDefinition> rounds = new();
private Dictionary<string, ExpressionRoundDefinition> roundById;
public string ActorLoopReference => actorLoopReference;
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>();
if (!LocalizationKit.IsLocalizedParam(actorLoopReference))
errors.Add("Actor Loop 必须配置为 l10n.* 引用。");
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;
}
}
}