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

309 lines
9.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using cfg;
using Obfuz;
using PhxhSDK;
using static Framework.EventManager;
namespace Framework.Condition
{
[ObfuzIgnore]
public interface ICondition
{
public EventName SignalName { get; }
/// <summary>
/// 检查条件是否满足
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
bool Check(List<float> args);
/// <summary>
/// 获取条件参数对应的本地化文本数组
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
string[] GetArgLocalizations(List<float> args);
}
public class ConditionException : Exception
{
public ConditionException(string message) : base(message)
{
}
}
public sealed class ConditionManager : Singlenton<ConditionManager>, IInitable
{
private const string CONDITION_PREFIX = "Condition";
private const string CONDITION_DESC_PREFIX = "condition_desc_";
//避免GC
private List<float> _tempConditionArgs = new();
private ICondition[] m_conditions;
#region MainLife
public void Init()
{
m_conditions = new ICondition[(int)ConditionType.Max];
foreach (ConditionType conditionType in Enum.GetValues(typeof(ConditionType)))
{
if (conditionType == ConditionType.None || conditionType == ConditionType.Max)
continue;
string typeName = $"{CONDITION_PREFIX}{conditionType}";
Type type = CommonUtilsFramework.GamePlayAssembly.GetType(typeName);
if (type == null)
{
DebugUtil.LogError($"Cant find Typename:{typeName}");
continue;
}
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");
}
}
public void Release()
{
m_conditions = null;
_tempConditionArgs = null;
}
#endregion
#region API
public bool CheckCondition(int conditionID)
{
DataCondition conditionCfg = GetConditionCfg(conditionID);
GetConditionCfgArgs(conditionCfg, ref _tempConditionArgs);
return CheckCondition(conditionCfg.Type, _tempConditionArgs);
}
public bool CheckCondition(string condition)
{
string conditionName = Regex.Replace(condition, @"\(.*?\)", string.Empty);
ConditionType conditionType = GetConditionType(conditionName);
GetConditionStringArgs(condition, ref _tempConditionArgs);
return CheckCondition(conditionType, _tempConditionArgs);
}
public bool CheckCondition(int[] conditionGroup, bool useAnd = true)
{
foreach (var conditionID in conditionGroup)
{
var isSuccess = CheckCondition(conditionID);
if (useAnd)
{
if (!isSuccess)
{
return false;
}
}
else
{
if (isSuccess)
return true;
}
}
return useAnd;
}
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;
}
/// <summary>
/// 检查条件是否满足条件
/// </summary>
/// <param name="conditionType"></param>
/// <param name="conditionArg"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public bool CheckCondition(ConditionType conditionType, List<float> conditionArg)
{
if (m_conditions[(int)conditionType] == null)
throw new Exception($"condition type is outside of range!condition type:{conditionType}");
return m_conditions[(int)conditionType].Check(conditionArg);
}
/// <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);
}
public EventName GetConditionSignal(int conditionID)
{
var conditionCfg = GetConditionCfg(conditionID);
if (conditionCfg != null)
{
return GetConditionSignal(conditionCfg.Type);
}
DebugUtil.LogError($"cant find condition!conditionID:{conditionID}");
return EventName.None;
}
public ConditionType GetConditionType(string conditionName)
{
conditionName = Regex.Replace(conditionName, @"\([^)]*\)", string.Empty);
if (Enum.TryParse(conditionName, out ConditionType result))
return result;
DebugUtil.LogError($"没有该条件类型:{conditionName}");
return ConditionType.None;
}
public EventName GetConditionSignal(string conditionName)
{
EventName eventName = GetConditionSignal(GetConditionType(conditionName));
if (EventName.None == eventName)
DebugUtil.LogError($"cant find condition!conditionName:{conditionName}");
return eventName;
}
/// <summary>
/// 获取条件参数
/// </summary>
/// <param name="condition"></param>
/// <param name="_args"></param>
public void GetConditionStringArgs(string condition, ref List<float> _args)
{
_args.Clear();
MatchCollection matches = Regex.Matches(condition, @"\((.*?)\)");
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);
}
}
}
public EventName GetConditionSignal(ConditionType conditionType)
{
var condition = GetConditionByType(conditionType);
if (condition != null)
{
return condition.SignalName;
}
DebugUtil.LogError($"cant find condition!conditionType:{conditionType}");
return EventName.None;
}
#region 获取条件本地化
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;
}
public string GetConditionLocalization(string condition)
{
string conditionName = Regex.Replace(condition, @"\(.*?\)", string.Empty);
GetConditionStringArgs(condition, ref _tempConditionArgs);
return GetConditionLocalization(GetConditionType(conditionName), _tempConditionArgs);
}
public string GetConditionLocalization(ConditionType conditionType, List<float> args)
{
string key = $"{CONDITION_DESC_PREFIX}{conditionType}";
return StringManager.Instance.GetLocalizeTextByKeyAndList(key, GetArgLocalizations(conditionType, args));
}
public string GetConditionLocalization(ConditionModifier conditionModifier)
{
return GetConditionLocalization(conditionModifier.conditionType, conditionModifier._args);
}
#endregion
#endregion
#region InnerFunction
private DataCondition GetConditionCfg(int conditionID)
{
return TableManager.Instance.Tables.ConditionConfig.Get(conditionID);
}
private ICondition GetConditionByType(ConditionType conditionType)
{
var index = (int)conditionType;
if (index < 0 || index >= m_conditions.Length)
{
DebugUtil.LogError("cant find condition!");
return null;
}
return m_conditions[index];
}
private void GetConditionCfgArgs(DataCondition conditionCfg, ref List<float> _args)
{
_args.Clear();
_args.Add(conditionCfg.Param1);
_args.Add(conditionCfg.Param2);
_args.Add(conditionCfg.Param3);
}
#endregion
}
}