using System; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace Snxxz.UI { public class ReikiRootModel : Model, IBeforePlayerDataInitialize, IPlayerLoginOk { Dictionary m_ReikiRootPoints = new Dictionary(); Dictionary m_ReikiRootFreePoints = new Dictionary(); Dictionary> m_RecommendReikiRoots = new Dictionary>(); Dictionary> m_RecommendProportion = new Dictionary>(); Dictionary m_MainReikiRoots = new Dictionary(); Dictionary m_ReikiQualityMapColors; Dictionary m_CacheReikiRootPoints = new Dictionary(); Dictionary> m_PromotePropertyValues = new Dictionary>(); public List reikiRoots = new List(); public int freePoint { get { return (int)PlayerDatas.Instance.baseData.FreePoint; } } int m_CacheFreePoint = 0; public int cacheFreePoint { get { return m_CacheFreePoint; } set { if (m_CacheFreePoint != value) { m_CacheFreePoint = value; if (onCacheFreePointRefresh != null) { onCacheFreePointRefresh(); } } } } public int mainReikiRoot { get { var job = PlayerDatas.Instance.baseData.Job; return m_MainReikiRoots[job]; } } public int maxQuality { get; private set; } public readonly Redpoint redpoint = new Redpoint(101, 10103); public event Action onCacheFreePointRefresh; public event Action onReikiRootPointRefresh; public override void Init() { ParseConfig(); PlayerDatas.Instance.playerDataRefreshEvent += PlayerDataRefreshEvent; } public void OnBeforePlayerDataInitialize() { m_ReikiRootPoints.Clear(); m_ReikiRootFreePoints.Clear(); } public void OnPlayerLoginOk() { RefreshReikiRootPoint(); } public override void UnInit() { PlayerDatas.Instance.playerDataRefreshEvent -= PlayerDataRefreshEvent; } void ParseConfig() { var funcConfig = FuncConfigConfig.Get("RecommendPoint"); var json = LitJson.JsonMapper.ToObject(funcConfig.Numerical1); foreach (var jobKey in json.Keys) { var job = int.Parse(jobKey); var _mainReikiRoot = 0; var _proportion = 0f; m_RecommendProportion.Add(job, new Dictionary()); foreach (var idKey in json[jobKey].Keys) { var id = int.Parse(idKey); var proportion = int.Parse(json[jobKey][idKey].ToString()) / 100f; if (proportion > _proportion) { _mainReikiRoot = id; _proportion = proportion; } m_RecommendProportion[job].Add(id, proportion); } m_MainReikiRoots.Add(job, _mainReikiRoot); m_RecommendReikiRoots.Add(job, new List(m_RecommendProportion[job].Keys)); } var config = ReikiRootConfig.GetValues()[0]; maxQuality = config.qualityArea.Length; funcConfig = FuncConfigConfig.Get("RecommendPoint"); m_ReikiQualityMapColors = ConfigParse.GetDic(funcConfig.Numerical2); reikiRoots.Add((int)PropertyType.Mater); reikiRoots.Add((int)PropertyType.Wood); reikiRoots.Add((int)PropertyType.Water); reikiRoots.Add((int)PropertyType.Fire); reikiRoots.Add((int)PropertyType.Earth); var configs = ReikiRootConfig.GetValues(); foreach (var _config in configs) { m_PromotePropertyValues.Add(_config.id, new Dictionary()); var _json = LitJson.JsonMapper.ToObject(_config.promoteValue); foreach (var _jobKey in _json.Keys) { var job = int.Parse(_jobKey); m_PromotePropertyValues[_config.id].Add(job, LitJson.JsonMapper.ToObject(_json[_jobKey].ToJson())); } } } public int GetReikiRootQuality(int id, int point) { var config = ReikiRootConfig.Get(id); if (config == null) { return 0; } var quality = 0; for (int i = 0; i < config.qualityArea.Length; i++) { if (point >= config.qualityArea[i]) { quality = i + 1; } else { break; } } return quality; } public int GetReikiRootQuality(int id) { return GetReikiRootQuality(id, GetReikiRootPoint(id)); } public int GetReikiRootPoint(int id) { return m_ReikiRootPoints.ContainsKey(id) ? m_ReikiRootPoints[id] : 0; } public int GetReikiRootFreePoint(int id) { return m_ReikiRootFreePoints.ContainsKey(id) ? m_ReikiRootFreePoints[id] : 0; } int GetReikiRootCachePoint(int id) { return m_CacheReikiRootPoints.ContainsKey(id) ? m_CacheReikiRootPoints[id] : 0; } public List GetReikiRootRecommendPoint(int point) { if (point == 0) { return null; } //m_CacheReikiRootPoints.Clear(); //foreach (var id in m_ReikiRootPoints.Keys) //{ // m_CacheReikiRootPoints[id] = m_ReikiRootPoints[id]; //} var recommends = new List(); var job = PlayerDatas.Instance.baseData.Job; if (m_RecommendProportion.ContainsKey(job)) { var proportions = m_RecommendProportion[job]; var index = 0; var surplusPoint = point; foreach (var id in proportions.Keys) { var recommendPoint = Mathf.Min(surplusPoint, (int)(point * proportions[id])); if (index == proportions.Keys.Count - 1) { recommendPoint = surplusPoint; } recommends.Add(new ReikiRootRecommend() { id = id, value = recommendPoint, }); surplusPoint -= recommendPoint; index++; } } //var remainPoint = point; //var currentMaxQuality = 1; //foreach (var id in reikiRoots) //{ // var quality = GetReikiRootQuality(id); // if (quality >= currentMaxQuality) // { // currentMaxQuality = quality; // } //} // //if (m_RecommendReikiRoots.ContainsKey(job)) //{ // var reikiRoots = m_RecommendReikiRoots[job]; // while (remainPoint > 0) // { // reikiRoots.Sort(QualityCompare); // var id = reikiRoots[0]; // var quality = GetReikiRootQuality(id, m_CacheReikiRootPoints[id]); // var addpoint = 0; // if (quality >= maxQuality) // { // var proportions = m_RecommendProportion[job]; // foreach (var key in proportions.Keys) // { // addpoint = Mathf.RoundToInt(remainPoint * proportions[key]); // recommends.Add(new ReikiRootRecommend() // { // id = key, // value = addpoint, // }); // if (!m_CacheReikiRootPoints.ContainsKey(key)) // { // m_CacheReikiRootPoints.Add(key, 0); // } // m_CacheReikiRootPoints[key] += addpoint; // } // remainPoint = 0; // } // else // { // addpoint = Mathf.Min(remainPoint, GetCacheQualityRequrePoint(id, // quality < currentMaxQuality ? currentMaxQuality : quality + 1)); // remainPoint -= addpoint; // recommends.Add(new ReikiRootRecommend() // { // id = id, // value = addpoint, // }); // if (!m_CacheReikiRootPoints.ContainsKey(id)) // { // m_CacheReikiRootPoints.Add(id, 0); // } // m_CacheReikiRootPoints[id] += addpoint; // } // } //} return recommends; } int GetCacheQualityRequrePoint(int id,int quality) { var requirePoint = 0; var currebtQuality = GetReikiRootQuality(id, GetReikiRootCachePoint(id)); if (currebtQuality < quality) { var point = GetReikiRootCachePoint(id); requirePoint = GetQualityPoint(id, quality) - point; } return requirePoint; } public int GetQualityPoint(int id, int quality) { var config = ReikiRootConfig.Get(id); for (int i = 0; i < config.qualityArea.Length; i++) { if (quality == i + 1) { return config.qualityArea[i]; } } return 0; } public void GetReikiRootProperty(int id, int point, ref Dictionary propertyDict) { var config = ReikiRootConfig.Get(id); if (!propertyDict.ContainsKey(config.propertyPerPoint.x)) { propertyDict.Add(config.propertyPerPoint.x, 0); } propertyDict[config.propertyPerPoint.x] += config.propertyPerPoint.y * point; var job = PlayerDatas.Instance.baseData.Job; var promotePropertyId = config.GetPromotePropertyId(job); if (!propertyDict.ContainsKey(promotePropertyId)) { propertyDict.Add(promotePropertyId, 0); } var quality = GetReikiRootQuality(id, point); propertyDict[promotePropertyId] += GetQualityProperty(id, quality); } public int GetQualityProperty(int id, int quality) { var config = ReikiRootConfig.Get(id); var job = PlayerDatas.Instance.baseData.Job; var promoteValues = m_PromotePropertyValues[id][job]; var value = 0; for (int i = 0; i < promoteValues.Length; i++) { if (quality > i) { value = promoteValues[i]; } else { break; } } return value; } public static string GetQualityLabel(int quality) { return Language.Get(StringUtility.Contact("ReikiRootQuality_", quality)); } public int GetQualityColor(int quality) { return m_ReikiQualityMapColors.ContainsKey(quality) ? m_ReikiQualityMapColors[quality] : 1; } public void ReceivePackage(HB107_tagMCRolePointInfo package) { for (int i = 0; i < package.PointAttrIDCount; i++) { var id = package.PointAttrIDList[i]; var point = package.PointValueList[i]; m_ReikiRootFreePoints[id] = point; } } public void SendAddPoint(byte[] points, ushort[] pointValues) { var pak = new CB206_tagCMAddPoint(); pak.PointAttrIDList = points; pak.PointValueList = pointValues; pak.PointAttrIDCount = (byte)points.Length; GameNetSystem.Instance.SendInfo(pak); } int QualityCompare(int lhs, int rhs) { var lhsQuality = GetReikiRootQuality(lhs, GetReikiRootCachePoint(lhs)); var rhsQuality = GetReikiRootQuality(rhs, GetReikiRootCachePoint(rhs)); if (lhs != rhs) { if (mainReikiRoot == lhs || mainReikiRoot == rhs) { if (lhsQuality == rhsQuality) { return mainReikiRoot == lhs ? -1 : 1; } } } return lhsQuality.CompareTo(rhsQuality); } private void PlayerDataRefreshEvent(PlayerDataType dataType) { switch (dataType) { case PlayerDataType.CDBPlayerRefresh_Mater: case PlayerDataType.CDBPlayerRefresh_Wood: case PlayerDataType.CDBPlayerRefresh_Water: case PlayerDataType.CDBPlayerRefresh_Fire: case PlayerDataType.CDBPlayerRefresh_Earth: RefreshReikiRootPoint(); break; case PlayerDataType.FreePoint: RefreshRedpoint(); break; } } void RefreshReikiRootPoint() { foreach (var id in reikiRoots) { m_ReikiRootPoints[id] = (int)UIHelper.GetPropertyValue((PropertyType)id); } if (onReikiRootPointRefresh != null) { onReikiRootPointRefresh(); } } void RefreshRedpoint() { var existFreePoint = false; if (FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.ReikiRoot)) { existFreePoint = freePoint > 0; } redpoint.state = existFreePoint ? RedPointState.Simple : RedPointState.None; } } public struct ReikiRootRecommend { public int id; public int value; } public static class ReikiRootConfigUtil { public static int GetPromotePropertyId(this ReikiRootConfig config, int job) { if (config != null) { foreach (var item in config.promoteProperty) { if (item.x == job) { return item.y; } } } return 0; } } }