NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Framework/Condition/ConditionManager.cs

355 lines
12 KiB
C#
Raw Normal View History

2023-11-01 13:33:20 +08:00
using System;
2023-11-03 14:46:27 +08:00
using System.Collections.Generic;
2025-03-06 19:30:17 +08:00
using System.Linq;
using System.Text.RegularExpressions;
2023-11-01 15:03:24 +08:00
using cfg;
2025-10-23 16:12:42 +08:00
using Obfuz;
2023-11-01 13:33:20 +08:00
using PhxhSDK;
using static Framework.EventManager;
namespace Framework.Condition
{
2025-10-23 16:12:42 +08:00
[ObfuzIgnore]
2023-11-01 13:33:20 +08:00
public interface ICondition
{
2026-01-08 13:35:18 +08:00
public EventName[] SignalNames { get; }
2023-11-01 13:33:20 +08:00
2024-04-15 17:59:58 +08:00
/// <summary>
/// 检查条件是否满足
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
2023-11-03 14:46:27 +08:00
bool Check(List<float> args);
2024-04-15 17:59:58 +08:00
/// <summary>
/// 获取条件参数对应的本地化文本数组
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
string[] GetArgLocalizations(List<float> args);
2025-12-25 14:02:59 +08:00
/// <summary>
/// 获取进度
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
float GetProgress(List<float> args);
2023-11-01 13:33:20 +08:00
}
2023-12-26 16:46:42 +08:00
public class ConditionException : Exception
{
public ConditionException(string message) : base(message)
{
}
}
2023-11-01 13:33:20 +08:00
public sealed class ConditionManager : Singlenton<ConditionManager>, IInitable
{
2026-01-20 18:25:12 +08:00
/// <summary>
/// 条件前缀
/// </summary>
2023-11-01 13:33:20 +08:00
private const string CONDITION_PREFIX = "Condition";
2026-01-20 18:25:12 +08:00
/// <summary>
/// 条件描述前缀
/// </summary>
2023-11-08 15:05:19 +08:00
private const string CONDITION_DESC_PREFIX = "condition_desc_";
2026-01-20 18:25:12 +08:00
private const string CONDITION_REGEX = @"\([^)]*\)";
private const string CONDITION_ARG_REGEX = @"\((.*?)\)";
2023-11-03 14:46:27 +08:00
//避免GC
private List<float> _tempConditionArgs = new();
2026-01-20 19:25:00 +08:00
// 缓存条件描述的 key避免每次拼接字符串产生 GC
private Dictionary<ConditionType, string> _conditionDescKeyCache;
2023-11-03 14:46:27 +08:00
2023-11-01 13:33:20 +08:00
private ICondition[] m_conditions;
2023-11-03 14:46:27 +08:00
#region MainLife
2023-11-01 13:33:20 +08:00
public void Init()
{
2023-11-01 15:21:28 +08:00
m_conditions = new ICondition[(int)ConditionType.Max];
2026-01-20 19:25:00 +08:00
_conditionDescKeyCache = new Dictionary<ConditionType, string>((int)ConditionType.Max);
2024-04-15 17:59:58 +08:00
foreach (ConditionType conditionType in Enum.GetValues(typeof(ConditionType)))
2023-11-01 13:33:20 +08:00
{
2024-04-15 17:59:58 +08:00
if (conditionType == ConditionType.None || conditionType == ConditionType.Max)
continue;
2023-11-06 18:20:55 +08:00
2026-01-20 19:25:00 +08:00
// 预缓存条件描述的 key
_conditionDescKeyCache[conditionType] = $"{CONDITION_DESC_PREFIX}{conditionType}";
2024-04-15 17:59:58 +08:00
string typeName = $"{CONDITION_PREFIX}{conditionType}";
Type type = CommonUtilsFramework.GamePlayAssembly.GetType(typeName);
if (type == null)
{
DebugUtil.LogError($"Cant find Typename:{typeName}");
continue;
2023-11-01 13:33:20 +08:00
}
2024-04-15 17:59:58 +08:00
if (Activator.CreateInstance(type) is ICondition condition)
m_conditions[(int)conditionType] = condition;
else
DebugUtil.LogError($"cant construct condition,type:{type},please check if your type is correctly implement ICondition");
2023-11-01 13:33:20 +08:00
}
}
public void Release()
{
m_conditions = null;
2023-11-03 14:46:27 +08:00
_tempConditionArgs = null;
2026-01-20 19:25:00 +08:00
_conditionDescKeyCache = null;
2023-11-01 13:33:20 +08:00
}
2023-11-03 14:46:27 +08:00
#endregion
2023-11-01 13:33:20 +08:00
2023-11-03 14:46:27 +08:00
#region API
2023-11-01 13:33:20 +08:00
public bool CheckCondition(int conditionID)
{
2024-04-15 17:59:58 +08:00
DataCondition conditionCfg = GetConditionCfg(conditionID);
2023-11-03 14:46:27 +08:00
GetConditionCfgArgs(conditionCfg, ref _tempConditionArgs);
2024-04-15 17:59:58 +08:00
2023-11-03 14:46:27 +08:00
return CheckCondition(conditionCfg.Type, _tempConditionArgs);
2023-11-01 13:33:20 +08:00
}
2025-03-06 19:30:17 +08:00
public bool CheckCondition(string condition)
{
string conditionName = Regex.Replace(condition, @"\(.*?\)", string.Empty);
2026-05-13 12:18:05 +08:00
2025-03-06 19:30:17 +08:00
ConditionType conditionType = GetConditionType(conditionName);
GetConditionStringArgs(condition, ref _tempConditionArgs);
return CheckCondition(conditionType, _tempConditionArgs);
}
2023-11-07 12:17:14 +08:00
public bool CheckCondition(int[] conditionGroup, bool useAnd = true)
2023-11-01 16:18:08 +08:00
{
foreach (var conditionID in conditionGroup)
{
var isSuccess = CheckCondition(conditionID);
2023-11-06 18:20:55 +08:00
if (useAnd)
{
if (!isSuccess)
{
return false;
}
}
else
2023-11-01 16:18:08 +08:00
{
2023-11-06 18:20:55 +08:00
if (isSuccess)
return true;
2023-11-01 16:18:08 +08:00
}
}
2023-11-06 18:20:55 +08:00
return useAnd;
2023-11-01 16:18:08 +08:00
}
2023-11-03 14:46:27 +08:00
2025-03-06 19:30:17 +08:00
public bool CheckCondition(string[] conditionGroups, bool useAnd = true)
{
if (null == conditionGroups || 0 == conditionGroups.Length)
return false;
foreach (string condition in conditionGroups)
{
bool isSuccess = CheckCondition(condition);
if (useAnd)
{
if (!isSuccess)
return false;
}
else
{
if (isSuccess)
return true;
}
}
return useAnd;
}
2024-04-15 17:59:58 +08:00
/// <summary>
/// 检查条件是否满足条件
/// </summary>
/// <param name="conditionType"></param>
/// <param name="conditionArg"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
2023-11-03 14:46:27 +08:00
public bool CheckCondition(ConditionType conditionType, List<float> conditionArg)
{
if (m_conditions[(int)conditionType] == null)
2024-04-15 17:59:58 +08:00
throw new Exception($"condition type is outside of range!condition type:{conditionType}");
2023-11-03 14:46:27 +08:00
return m_conditions[(int)conditionType].Check(conditionArg);
}
2024-04-15 17:59:58 +08:00
/// <summary>
/// 获取条件参数的本地化文本数组
/// </summary>
/// <param name="conditionType"></param>
/// <param name="listArg"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public string[] GetArgLocalizations(ConditionType conditionType, List<float> listArg)
{
ICondition iCondition = m_conditions[(int)conditionType] ?? throw new Exception($"条件类型超出范围!类型:{conditionType}");
return iCondition.GetArgLocalizations(listArg);
}
2025-12-25 14:27:41 +08:00
/// <summary>
/// 获取条件进度
/// </summary>
/// <returns></returns>
public float GetProgress(ConditionType conditionType, List<float> listArg)
{
ICondition iCondition = m_conditions[(int)conditionType] ?? throw new Exception($"条件类型超出范围!类型:{conditionType}");
return iCondition.GetProgress(listArg);
}
/// <summary>
/// 获取条件进度
/// </summary>
/// <returns></returns>
public float GetProgress(ConditionModifier conditionModifier)
{
return GetProgress(conditionModifier.conditionType, conditionModifier._args);
}
2026-01-08 13:35:18 +08:00
public EventName[] GetConditionSignal(int conditionID)
2023-11-01 13:33:20 +08:00
{
2026-01-08 13:35:18 +08:00
DataCondition conditionCfg = GetConditionCfg(conditionID);
if (null != conditionCfg)
2023-11-06 18:20:55 +08:00
{
return GetConditionSignal(conditionCfg.Type);
}
DebugUtil.LogError($"cant find condition!conditionID:{conditionID}");
2026-01-08 13:35:18 +08:00
return new EventName[1] { EventName.None };
2023-11-06 18:20:55 +08:00
}
2025-03-06 19:30:17 +08:00
public ConditionType GetConditionType(string conditionName)
{
2026-01-20 18:25:12 +08:00
conditionName = Regex.Replace(conditionName, CONDITION_REGEX, string.Empty);
2025-03-11 16:04:15 +08:00
if (Enum.TryParse(conditionName, out ConditionType result))
return result;
DebugUtil.LogError($"没有该条件类型:{conditionName}");
return ConditionType.None;
2025-03-06 19:30:17 +08:00
}
2026-01-08 13:35:18 +08:00
public EventName[] GetConditionSignal(string conditionName)
2025-03-06 19:30:17 +08:00
{
2026-01-08 13:35:18 +08:00
EventName[] eventNames = GetConditionSignal(GetConditionType(conditionName));
if (null == eventNames)
2025-03-06 19:30:17 +08:00
DebugUtil.LogError($"cant find condition!conditionName:{conditionName}");
2026-01-08 13:35:18 +08:00
return eventNames;
2025-03-06 19:30:17 +08:00
}
/// <summary>
/// 获取条件参数
/// </summary>
/// <param name="condition"></param>
/// <param name="_args"></param>
public void GetConditionStringArgs(string condition, ref List<float> _args)
{
_args.Clear();
2026-01-20 18:25:12 +08:00
MatchCollection matches = Regex.Matches(condition, CONDITION_ARG_REGEX);
foreach (Match match in matches.Cast<Match>())
{
string[] paramStrs = match.Groups[1].Value.Split(',');
foreach (string paramStr in paramStrs)
{
if (!float.TryParse(paramStr, out float param))
continue;
_args.Add(param);
}
}
}
2026-01-08 13:35:18 +08:00
public EventName[] GetConditionSignal(ConditionType conditionType)
2023-11-06 18:20:55 +08:00
{
2026-01-08 13:35:18 +08:00
ICondition condition = GetConditionByType(conditionType);
if (null != condition)
return condition.SignalNames;
2023-11-03 14:46:27 +08:00
2023-11-06 18:20:55 +08:00
DebugUtil.LogError($"cant find condition!conditionType:{conditionType}");
2026-01-08 13:35:18 +08:00
return null;
2023-11-03 14:46:27 +08:00
}
#region 获取条件本地化
2023-11-07 12:17:14 +08:00
public string GetConditionLocalization(int conditionID)
{
var conditionCfg = GetConditionCfg(conditionID);
if (conditionCfg != null)
{
GetConditionCfgArgs(conditionCfg, ref _tempConditionArgs);
return GetConditionLocalization(conditionCfg.Type, _tempConditionArgs);
}
DebugUtil.LogError($"cant find condition!conditionID:{conditionID}");
return null;
}
2025-03-06 19:30:17 +08:00
public string GetConditionLocalization(string condition)
{
2026-01-20 18:25:12 +08:00
string conditionName = Regex.Replace(condition, CONDITION_ARG_REGEX, string.Empty);
2025-03-06 19:30:17 +08:00
GetConditionStringArgs(condition, ref _tempConditionArgs);
return GetConditionLocalization(GetConditionType(conditionName), _tempConditionArgs);
}
2023-11-07 12:17:14 +08:00
public string GetConditionLocalization(ConditionType conditionType, List<float> args)
{
2026-01-20 19:25:00 +08:00
// 使用缓存的 key避免每次拼接字符串产生 GC
if (!_conditionDescKeyCache.TryGetValue(conditionType, out string key))
{
// 回退方案,理论上不应该走到这里
key = $"{CONDITION_DESC_PREFIX}{conditionType}";
}
2024-04-15 17:59:58 +08:00
return StringManager.Instance.GetLocalizeTextByKeyAndList(key, GetArgLocalizations(conditionType, args));
2023-11-07 12:17:14 +08:00
}
public string GetConditionLocalization(ConditionModifier conditionModifier)
{
return GetConditionLocalization(conditionModifier.conditionType, conditionModifier._args);
}
#endregion
2023-11-03 14:46:27 +08:00
#endregion
#region InnerFunction
private DataCondition GetConditionCfg(int conditionID)
{
2024-04-15 17:59:58 +08:00
return TableManager.Instance.Tables.ConditionConfig.Get(conditionID);
2023-11-03 14:46:27 +08:00
}
2023-11-06 18:20:55 +08:00
private ICondition GetConditionByType(ConditionType conditionType)
2023-11-03 14:46:27 +08:00
{
2023-11-06 18:20:55 +08:00
var index = (int)conditionType;
if (index < 0 || index >= m_conditions.Length)
2023-11-03 14:46:27 +08:00
{
2023-11-06 18:20:55 +08:00
DebugUtil.LogError("cant find condition!");
return null;
2023-11-03 14:46:27 +08:00
}
2023-11-06 18:20:55 +08:00
return m_conditions[index];
2023-11-01 13:33:20 +08:00
}
2023-11-03 14:46:27 +08:00
private void GetConditionCfgArgs(DataCondition conditionCfg, ref List<float> _args)
{
_args.Clear();
_args.Add(conditionCfg.Param1);
_args.Add(conditionCfg.Param2);
_args.Add(conditionCfg.Param3);
}
#endregion
2023-11-01 13:33:20 +08:00
}
}