143 lines
5.7 KiB
C#
143 lines
5.7 KiB
C#
using System.Collections.Generic;
|
|
using System.Text.RegularExpressions;
|
|
using Cielonos.MainGame.Characters;
|
|
using UnityEngine;
|
|
|
|
namespace Cielonos.MainGame.UI
|
|
{
|
|
/// <summary>
|
|
/// 通用展示文本解析器。
|
|
/// 负责将文本中的 {key} 命名占位符替换为运行时动态值,
|
|
/// 并提供各类游戏数据的展示值计算方法。
|
|
/// </summary>
|
|
public static class DisplayTextResolver
|
|
{
|
|
private static readonly Regex PlaceholderPattern = new Regex(@"\{(\w+)\}", RegexOptions.Compiled);
|
|
|
|
// ================================================================
|
|
// 核心:占位符替换
|
|
// ================================================================
|
|
|
|
/// <summary>
|
|
/// 将文本中的 {key} 占位符替换为 args 字典中对应的值。
|
|
/// 未匹配到的占位符保留原样。
|
|
/// </summary>
|
|
public static string Resolve(string text, Dictionary<string, string> args)
|
|
{
|
|
if (string.IsNullOrEmpty(text) || args == null || args.Count == 0)
|
|
return text;
|
|
|
|
return PlaceholderPattern.Replace(text, match =>
|
|
{
|
|
string key = match.Groups[1].Value;
|
|
return args.TryGetValue(key, out string value) ? value : match.Value;
|
|
});
|
|
}
|
|
|
|
// ================================================================
|
|
// 伤害相关
|
|
// ================================================================
|
|
|
|
/// <summary>
|
|
/// 计算 AttackUnit 的面板展示伤害值。
|
|
/// 仅包含攻击者侧倍率,不含随机偏差和受击者侧减伤。
|
|
/// </summary>
|
|
public static float ComputeDisplayDamage(AttackUnit unit, CharacterBase attacker)
|
|
{
|
|
if (unit == null || unit.isInvalidAttack) return 0f;
|
|
|
|
float damage = unit.startDamage;
|
|
if (attacker == null) return damage;
|
|
|
|
damage *= attacker.attributeSm[CharacterAttribute.AttackDamageMultiplier];
|
|
string typeKey = unit.type.AttackTypeToString() + "DamageDealtMultiplier";
|
|
damage *= attacker.attributeSm[typeKey];
|
|
damage *= attacker.attributeSm[CharacterAttribute.FinalDamageDealtMultiplier];
|
|
return damage;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 计算 AttackUnit 的面板展示暴击率(含玩家属性加成),结果范围 [0, 1]。
|
|
/// </summary>
|
|
public static float ComputeDisplayCriticalChance(AttackUnit unit, CharacterBase attacker)
|
|
{
|
|
if (unit == null || unit.isInvalidAttack) return 0f;
|
|
|
|
float chance = unit.criticalChance;
|
|
if (attacker != null)
|
|
chance += attacker.attributeSm[CharacterAttribute.CriticalAttackProbability];
|
|
return Mathf.Clamp01(chance);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 计算 AttackUnit 的面板展示暴击伤害倍率(含玩家属性加成)。
|
|
/// </summary>
|
|
public static float ComputeDisplayCriticalMultiplier(AttackUnit unit, CharacterBase attacker)
|
|
{
|
|
if (unit == null || unit.isInvalidAttack) return 0f;
|
|
|
|
float multiplier = unit.criticalMultiplier;
|
|
if (attacker != null)
|
|
multiplier += attacker.attributeSm[CharacterAttribute.CriticalAttackDamageAmplifier];
|
|
return multiplier;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 批量填充指定 AttackUnit 的伤害、暴击率、暴击倍率到 args 字典中。
|
|
/// 生成的 key 格式:{prefix}_damage, {prefix}_crit_chance, {prefix}_crit_multiplier。
|
|
/// </summary>
|
|
public static void PopulateAttackArgs(
|
|
Dictionary<string, string> args, string prefix,
|
|
AttackUnit unit, CharacterBase attacker)
|
|
{
|
|
if (unit == null || unit.isInvalidAttack) return;
|
|
|
|
args[$"{prefix}_damage"] = FormatInt(ComputeDisplayDamage(unit, attacker));
|
|
args[$"{prefix}_crit_chance"] = FormatPercent(ComputeDisplayCriticalChance(unit, attacker));
|
|
args[$"{prefix}_crit_multiplier"] = FormatFloat(ComputeDisplayCriticalMultiplier(unit, attacker));
|
|
}
|
|
|
|
// ================================================================
|
|
// 资源花费相关
|
|
// ================================================================
|
|
|
|
/// <summary>
|
|
/// 计算经过能量花费减少属性调整后的展示能量花费。
|
|
/// </summary>
|
|
public static float ComputeDisplayEnergyCost(float baseCost, CharacterBase character)
|
|
{
|
|
if (character == null) return baseCost;
|
|
float reduction = character.attributeSm[CharacterAttribute.EnergyCostReduction];
|
|
return Mathf.Max(0f, baseCost * (1f - reduction));
|
|
}
|
|
|
|
// ================================================================
|
|
// 格式化工具
|
|
// ================================================================
|
|
|
|
/// <summary>
|
|
/// 将浮点数格式化为整数字符串(四舍五入)。
|
|
/// </summary>
|
|
public static string FormatInt(float value)
|
|
{
|
|
return Mathf.RoundToInt(value).ToString();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 将浮点数格式化为百分比字符串(如 0.15 → "15%")。
|
|
/// </summary>
|
|
public static string FormatPercent(float value)
|
|
{
|
|
return $"{Mathf.RoundToInt(value * 100f)}%";
|
|
}
|
|
|
|
/// <summary>
|
|
/// 将浮点数格式化为保留指定小数位的字符串。
|
|
/// </summary>
|
|
public static string FormatFloat(float value, int decimals = 1)
|
|
{
|
|
return value.ToString($"F{decimals}");
|
|
}
|
|
}
|
|
}
|