using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; namespace vnxbqy.UI { public class RuneModel : Model, IBeforePlayerDataInitialize, IPlayerLoginOk { Dictionary m_RuneHoleItems = new Dictionary(); Dictionary m_PropertyComputeDict = new Dictionary(); Dictionary m_RuneHoleConditions = new Dictionary(); Dictionary m_RuneHoleRedpoints = new Dictionary(); Dictionary> m_RunePropertys = new Dictionary>(); Dictionary levelUpFormulaCostDict = new Dictionary(); Dictionary levelUpQualityCostModulus; Dictionary m_QualityMaxLevels; Dictionary m_MultiPropertyRuneInlayDict; Dictionary> m_RandomRunes = new Dictionary>(); List m_MultiPropertyRunes = new List(); int[] specialHoleRemindLevels = null; string levelUpCostFormula = string.Empty; float levelUpMultiPropertyModulus = 1f; public uint holeState { get; private set; } public bool serverInited { get; private set; } public int specialHole { get; private set; } public int passRuneTowerFloor { get; private set; } public int samePropertyHoleLimit { get; private set; } public bool unlockingSpecialHole { get; set; } public readonly Redpoint baseRedpoint = new Redpoint(1, 108); public readonly Redpoint redpoint = new Redpoint(108, RUNE_REDPOINT_BASE); public readonly Redpoint specialHoleRedpoint = new Redpoint(RUNE_REDPOINT_BASE, redpointIndex++); int m_SelectHole = 0; public int selectHole { get { return m_SelectHole; } set { if (m_SelectHole != value) { m_SelectHole = value; if (onSelectHoleRefresh != null) { onSelectHoleRefresh(); } } } } public const int RUNE_TYPE = 30; public const int RUNE_CREAMTYPE = 31; public const int RUNE_HOLE_COUNT = 9; public const int RUNE_REDPOINT_BASE = 10801; public static int redpointIndex = 1080100; public event Action onRuneHoleRefresh; public event Action onOpenNewHole; public event Action onSelectHoleRefresh; public event Action onRuneTowerRefresh; public event Action onJumpToCompose; static StringBuilder sb = new StringBuilder(); VirtualPackModel virtualPackModel { get { return ModelCenter.Instance.GetModel(); } } public override void Init() { ParseConfig(); virtualPackModel.virtualPackRefresh += VirtualPackRefresh; FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent; PlayerDatas.Instance.playerDataRefreshEvent += PlayerDataRefreshEvent; } public void OnBeforePlayerDataInitialize() { m_RuneHoleItems.Clear(); serverInited = false; } public void OnPlayerLoginOk() { serverInited = true; RefreshRedpoint(); RefreshSpecialHoleRedpoint(); } public override void UnInit() { virtualPackModel.virtualPackRefresh -= VirtualPackRefresh; FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent; PlayerDatas.Instance.playerDataRefreshEvent -= PlayerDataRefreshEvent; } void ParseConfig() { List runeTypes = new List(); var configs = RuneConfig.GetValues(); foreach (var config in configs) { for (int i = 0; i < config.AttrType.Length; i++) { if (!runeTypes.Contains(config.AttrType[i])) { runeTypes.Add(config.AttrType[i]); } } if (config.AttrType.Length > 1) { m_MultiPropertyRunes.Add(config.ID); } m_RunePropertys.Add(config.ID, new List(config.AttrType)); } foreach (var propertyType in runeTypes) { var key = StringUtility.Contact("RuneAttr", propertyType); if (FuncConfigConfig.Has(key)) { m_PropertyComputeDict.Add(propertyType, new PropertyCompute(FuncConfigConfig.Get(key))); } } var maxLevelConfig = FuncConfigConfig.Get("RuneMaxLV"); m_QualityMaxLevels = ConfigParse.GetDic(maxLevelConfig.Numerical1); var maxLevel = 0; foreach (var level in m_QualityMaxLevels.Values) { if (level > maxLevel) { maxLevel = level; } } var levelUpConfig = FuncConfigConfig.Get("RuneExp"); levelUpCostFormula = levelUpConfig.Numerical1; levelUpQualityCostModulus = ConfigParse.GetDic(levelUpConfig.Numerical2); levelUpMultiPropertyModulus = float.Parse(levelUpConfig.Numerical3); { var funcConfig = FuncConfigConfig.Get("RuneDoubleInlayCnt"); m_MultiPropertyRuneInlayDict = ConfigParse.GetDic(funcConfig.Numerical1); funcConfig = FuncConfigConfig.Get("RuneSpecialRedLevel"); specialHoleRemindLevels = ConfigParse.GetMultipleStr(funcConfig.Numerical1); } System.Threading.ThreadPool.QueueUserWorkItem((object _object) => { foreach (var propertyCompute in m_PropertyComputeDict.Values) { propertyCompute.CacheFormulaResult(maxLevel); } }); { var funcConfig = FuncConfigConfig.Get("RuneUnlock"); var towerArray = ConfigParse.GetMultipleStr(funcConfig.Numerical1); var diamondDict = ConfigParse.GetDic(funcConfig.Numerical2); var playerLevelDict = ConfigParse.GetDic(funcConfig.Numerical3); for (int i = 0; i < RUNE_HOLE_COUNT; i++) { m_RuneHoleConditions.Add(i, new RuneHoleCondition() { runeTowerFloor = i < towerArray.Length ? towerArray[i] : 0, diamond = diamondDict.ContainsKey(i) ? diamondDict[i] : 0, playerLevel = playerLevelDict.ContainsKey(i) ? playerLevelDict[i] : 0, }); } specialHole = 8; samePropertyHoleLimit = int.Parse(funcConfig.Numerical5); funcConfig = FuncConfigConfig.Get("RandomRuneIDList"); var json = LitJson.JsonMapper.ToObject(funcConfig.Numerical2); foreach (var itemKey in json.Keys) { var itemId = int.Parse(itemKey); m_RandomRunes[itemId] = new List(LitJson.JsonMapper.ToObject(json[itemKey].ToJson())); } } for (int i = 0; i < RUNE_HOLE_COUNT; i++) { m_RuneHoleRedpoints.Add(i, new RuneHoleRedpoint(RUNE_REDPOINT_BASE)); } } public bool IsInlayByItemId(int itemID) { if (m_RuneHoleItems==null) return false; var runeArr = m_RuneHoleItems.Keys.ToArray(); for (int i = 0; i < runeArr.Length; i++) { int hole = runeArr[i]; RuneItem runeItem = m_RuneHoleItems[hole]; if (runeItem == null) continue; if (runeItem.id == itemID) return true; } return false; } public bool TryGetRuneHoleItem(int hole, out RuneItem runeItem) { return m_RuneHoleItems.TryGetValue(hole, out runeItem); } public bool TryGetRuneHoleCondition(int hole, out RuneHoleCondition condition) { return m_RuneHoleConditions.TryGetValue(hole, out condition); } public bool TryGetRunePropertys(int id, out List propertys) { return m_RunePropertys.TryGetValue(id, out propertys); } public int TryGetComposeRuneCount(int id, out RuneItem item) { var count = 0; item = null; List items = null; if (virtualPackModel.TryGetItems(PackType.RunePack, out items)) { foreach (var packIndex in items) { RuneItem _item; if (virtualPackModel.TryGetItem(PackType.RunePack, packIndex, out _item) && _item.id == id) { if (item == null || _item.level >= item.level) { item = _item; } count++; } } } foreach (var _item in m_RuneHoleItems.Values) { if (_item.id == id) { if (item == null || _item.level >= item.level) { item = _item; } count++; break; } } return count; } public bool TryEquipRuneByColor(int itemColor, out int hole) { if (!ExistEmptyHole(out hole)) { return false; } virtualPackModel.GetItemIndexs(PackType.RunePack, ref cacheItemIndexs); foreach (var index in cacheItemIndexs) { RuneItem item; if (virtualPackModel.TryGetItem(PackType.RunePack, index, out item)) { var config = ItemConfig.Get(item.id); if (config.ItemColor < itemColor) { continue; } if (SatisfyInlayHole(item, hole)) { return true; } } } return false; } public bool TryGetRedpoint(int hole, out RuneHoleRedpoint redpoint) { return m_RuneHoleRedpoints.TryGetValue(hole, out redpoint); } public int GetPropertyValue(int id, int level, int type) { if (m_PropertyComputeDict.ContainsKey(type)) { return m_PropertyComputeDict[type].GetPropertyValue(id, level); } return 0; } public string GetRunePropertyDescription(int id, int level) { sb.Length = 0; var config = RuneConfig.Get(id); for (int i = 0; i < config.AttrType.Length; i++) { var property = config.AttrType[i]; var propertyConfig = PlayerPropertyConfig.Get(property); var propertyValue = GetPropertyValue(id, level, property); var label = StringUtility.Contact(propertyConfig.Name, "+", PlayerPropertyConfig.GetValueDescription(property, propertyValue, false)); sb.Append(label); if (i < config.AttrType.Length - 1) { sb.Append('\n'); } } return sb.ToString(); } public int GetLevelUpRequireRuneEssence(int id, int level) { float requireEssence = 0; var itemConfig = ItemConfig.Get(id); if (!IsRuneMaxLevel(id, level)) { var _result = 0f; if (levelUpFormulaCostDict.ContainsKey(level + 1)) { _result = levelUpFormulaCostDict[level + 1]; } else { Equation.Instance.Clear(); Equation.Instance.AddKeyValue("level", level + 1); _result = Equation.Instance.Eval(levelUpCostFormula); levelUpFormulaCostDict.Add(level + 1, _result); } if (IsMultiPropertyRune(id)) { requireEssence = _result * levelUpQualityCostModulus[itemConfig.ItemColor] * levelUpMultiPropertyModulus; } else { requireEssence = _result * levelUpQualityCostModulus[itemConfig.ItemColor]; } } return Mathf.FloorToInt(requireEssence); } public int GetMultiPropertyInlayCount(int tower = 0) { if (tower != 0 && m_MultiPropertyRuneInlayDict.ContainsKey(tower)) { return m_MultiPropertyRuneInlayDict[tower]; } var count = 0; foreach (var _key in m_MultiPropertyRuneInlayDict.Keys) { if (passRuneTowerFloor >= _key) { count = m_MultiPropertyRuneInlayDict[_key]; } else { break; } } return count; } public int GetMultiPropertyHoleCount() { var count = 0; foreach (var item in m_RuneHoleItems.Values) { if (IsMultiPropertyRune(item.id)) { count ++; } } return count; } public int GetRuneLevelBySplinters(int id, float essence) { var totalEssence = 0f; var config = ItemConfig.Get(id); var maxlevel = 0; if (m_QualityMaxLevels.ContainsKey(config.ItemColor)) { maxlevel = m_QualityMaxLevels[config.ItemColor]; } for (int i = 1; i < maxlevel; i++) { totalEssence += GetLevelUpRequireRuneEssence(id, i); if (totalEssence > essence) { return i; } } return maxlevel; } public int GetRuneInlayCount() { return m_RuneHoleItems.Count; } public int GetRuneTotalLevel() { var level = 0; foreach (var item in m_RuneHoleItems.Values) { level += item.level; } return level; } public int GetRuneTotalCount(int itemType = 0) { var count = 0; virtualPackModel.GetItemIndexs(PackType.RunePack, ref cacheItemIndexs); foreach (var index in cacheItemIndexs) { RuneItem item; if (virtualPackModel.TryGetItem(PackType.RunePack, index, out item)) { if (itemType == 0 || item.itemType == itemType) { count++; } } } return count; } public List GetUnlockRunes() { List ids = new List(); var configs = RuneConfig.GetValues(); foreach (var config in configs) { if (passRuneTowerFloor >= config.TowerID && config.AttrType.Length == 1 && !ids.Contains(config.ID)) { ids.Add(config.ID); } } return ids; } public int GetSamePropertyHoleCount(int property, int hole) { var count = 0; for (int i = 0; i < RUNE_HOLE_COUNT; i++) { if (i == hole) { continue; } RuneItem item; if (TryGetRuneHoleItem(i, out item)) { if (item.IsSameProperty(property)) { count++; } } } return count; } public int GetMaxSamePropertyHoleCount(int id, int hole) { var count = 0; if (m_RunePropertys.ContainsKey(id)) { var propertys = m_RunePropertys[id]; for (int i = 0; i < propertys.Count; i++) { var sameCount = GetSamePropertyHoleCount(propertys[i], hole); if (sameCount > count) { count = sameCount; } } } return count; } public bool IsExistInRandomRunes(int itemId, int runeId) { return m_RandomRunes.ContainsKey(itemId) && m_RandomRunes[itemId].Contains(runeId); } public bool IsRuneHoleOpen(int hole, uint state) { return MathUtility.GetBitValue(state, (ushort)hole); } public bool IsMultiPropertyRune(int id) { return m_MultiPropertyRunes.Contains(id); } public bool IsRuneMaxLevel(int id, int level) { var config = ItemConfig.Get(id); if (config != null) { if (m_QualityMaxLevels.ContainsKey(config.ItemColor)) { return level >= m_QualityMaxLevels[config.ItemColor]; } } return true; } public bool IsUnlockAllMultiPropertyInlay(out int tower) { tower = 0; foreach (var _key in m_MultiPropertyRuneInlayDict.Keys) { if (passRuneTowerFloor < _key) { tower = _key; break; } } return tower == 0; } public bool IsSameWithRuneHole(int id, int hole) { RuneItem item; if (TryGetRuneHoleItem(hole, out item)) { return item.IsExistSameProperty(id); } return false; } public bool IsBetterRuneWithHole(int id, int hole) { var itemConfig = ItemConfig.Get(id); if (itemConfig == null || itemConfig.Type == RUNE_CREAMTYPE) { return false; } RuneItem item = null; if (!TryGetRuneHoleItem(hole, out item)) { return false; } if (!item.IsExistSameProperty(id)) { return false; } var itemHoleConfig = ItemConfig.Get(item.id); return itemConfig.ItemColor > itemHoleConfig.ItemColor; } public bool SatisfyLevelUpHole(int hole) { if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Rune)) { return false; } RuneItem item; if (TryGetRuneHoleItem(hole, out item)) { var essence = PlayerDatas.Instance.GetPlayerDataByType(PlayerDataType.RuneSplinters); if (!IsRuneMaxLevel(item.id, item.level) && essence >= (ulong)GetLevelUpRequireRuneEssence(item.id, item.level)) { return true; } } return false; } public bool SatisfyInlayHole(int hole) { if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Rune)) { return false; } if (!IsRuneHoleOpen(hole, holeState) || m_RuneHoleItems.ContainsKey(hole)) { return false; } virtualPackModel.GetItemIndexs(PackType.RunePack, ref cacheItemIndexs); foreach (var index in cacheItemIndexs) { RuneItem item; if (virtualPackModel.TryGetItem(PackType.RunePack, index, out item)) { if (SatisfyInlayHole(item, hole)) { return true; } } } return false; } public bool SatisfyInlayHole(RuneItem item, int hole) { if (item.itemType == RUNE_CREAMTYPE || GetMaxSamePropertyHoleCount(item.id, hole) >= samePropertyHoleLimit) { return false; } if (IsMultiPropertyRune(item.id) && GetMultiPropertyInlayCount() <= GetMultiPropertyHoleCount()) { return false; } return true; } public bool SatisfyInlayBetterHole(int hole) { if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Rune)) { return false; } if (!IsRuneHoleOpen(hole, holeState) || !m_RuneHoleItems.ContainsKey(hole)) { return false; } var runeHoleItem = m_RuneHoleItems[hole]; var isDoubleRuneHole = IsMultiPropertyRune(runeHoleItem.id); var multiPropertyHoleCount = GetMultiPropertyHoleCount(); var multiPropertyLimitCount = GetMultiPropertyInlayCount(); virtualPackModel.GetItemIndexs(PackType.RunePack, ref cacheItemIndexs); foreach (var index in cacheItemIndexs) { RuneItem item; if (virtualPackModel.TryGetItem(PackType.RunePack, index, out item)) { if (!IsBetterRuneWithHole(item.id, hole)) { continue; } var isDoubleRune = IsMultiPropertyRune(item.id); if (!isDoubleRuneHole && isDoubleRune) { if (multiPropertyHoleCount >= multiPropertyLimitCount) { continue; } } return true; } } return false; } public bool ExistEmptyHole(out int hole) { hole = 0; for (int i = 0; i < RUNE_HOLE_COUNT; i++) { if (!m_RuneHoleItems.ContainsKey(i)) { hole = i; return true; } } return false; } public void SelectRunePackItem(RuneItem item_pack, int hole) { RuneItem item_hole = null; TryGetRuneHoleItem(hole, out item_hole); var isHoleItemMultiProperty = item_hole != null ? IsMultiPropertyRune(item_hole.id) : false; var isPackItemMultiProperty = IsMultiPropertyRune(item_pack.id); var multiPropertyLimitCount = GetMultiPropertyInlayCount(); if (!isHoleItemMultiProperty) { if (isPackItemMultiProperty && multiPropertyLimitCount <= GetMultiPropertyHoleCount()) { SysNotifyMgr.Instance.ShowTip("RuneGridUnEnough", multiPropertyLimitCount); return; } } int switchOtherSameHole = -1; if (item_hole == null || !item_hole.IsExistSameProperty(item_pack.id)) { if (GetMaxSamePropertyHoleCount(item_pack.id, hole) >= samePropertyHoleLimit) { ServerTipDetails.DisplayNormalTip(Language.Get("L1078", samePropertyHoleLimit)); return; } } else { if (isHoleItemMultiProperty != isPackItemMultiProperty && isPackItemMultiProperty) { if (GetMaxSamePropertyHoleCount(item_pack.id, hole) >= samePropertyHoleLimit) { var holeProperty = m_RunePropertys[item_hole.id][0]; for (int i = 0; i < RUNE_HOLE_COUNT; i++) { if (i == hole) { continue; } if (IsSameWithRuneHole(item_pack.id, i)) { RuneItem _item_hole; if (TryGetRuneHoleItem(i, out _item_hole) && !IsMultiPropertyRune(_item_hole.id) && m_RunePropertys[_item_hole.id][0] != holeProperty) { switchOtherSameHole = i; break; } } } } } } if (switchOtherSameHole != -1) { RuneItem sameHoleItem = null; if (TryGetRuneHoleItem(switchOtherSameHole, out sameHoleItem)) { ConfirmCancel.ShowPopConfirm(Language.Get("Mail101"), Language.Get("SwitchDoublePropertyRune"),(bool isOk) => { if (isOk) { SwitchRune((int)PackType.InterimPack, switchOtherSameHole, (int)PackType.RunePack, 0); SwitchRune((int)PackType.RunePack, item_pack.index, (int)PackType.InterimPack, hole); WindowCenter.Instance.Close(); } }); } } else { SwitchRune((int)PackType.RunePack, item_pack.index, (int)PackType.InterimPack, hole); WindowCenter.Instance.Close(); } } void SwitchRune(int srcpackType, int scrIndex, int destpackType, int destIndex) { C073D_tagCPackItemExchange pak = new C073D_tagCPackItemExchange(); pak.SrcBackpack = (byte)srcpackType; pak.SrcIndex = (ushort)scrIndex; pak.DesBackPack = (byte)destpackType; pak.DestIndex = (ushort)destIndex; GameNetSystem.Instance.SendInfo(pak); } public void ReceivePackage(HA31F_tagMCRuneInfo package) { var preholeState = holeState; holeState = package.RuneHoleOpenState; for (int i = 0; i < package.Count; i++) { if (package.RuneDataList[i] != 0) { RuneItem runeItem = null; if (!m_RuneHoleItems.TryGetValue(i, out runeItem)) { runeItem = new RuneItem(); m_RuneHoleItems.Add(i, runeItem); } runeItem.ParseHoleItem(i, package.RuneDataList[i]); } else { if (m_RuneHoleItems.ContainsKey(i)) { m_RuneHoleItems[i] = null; m_RuneHoleItems.Remove(i); } } } for (int i = 0; i < RUNE_HOLE_COUNT; i++) { if (!serverInited) { break; } var preOpen = IsRuneHoleOpen(i, preholeState); var nowOpen = IsRuneHoleOpen(i, holeState); if (!preOpen && nowOpen) { if (onOpenNewHole != null) { onOpenNewHole(i); } } } if (onRuneHoleRefresh != null) { onRuneHoleRefresh(); } RefreshRedpoint(); RefreshSpecialHoleRedpoint(); } public void ReceivePackage(HA3BA_tagMCTrialTowerInfo package) { passRuneTowerFloor = (int)package.PassLV; if (onRuneTowerRefresh != null) { onRuneTowerRefresh(); } } private void VirtualPackRefresh(PackType packType) { if (packType == PackType.RunePack) { RefreshRedpoint(); } } private void PlayerDataRefreshEvent(PlayerDataType dataType) { if (dataType == PlayerDataType.RuneSplinters) { RefreshRedpoint(); } if (dataType == PlayerDataType.LV) { RefreshSpecialHoleRedpoint(); } } private void OnFuncStateChangeEvent(int id) { if (id == (int)FuncOpenEnum.Rune) { RefreshRedpoint(); } } /// ///1.有可操作的时候仅按优先级显示1个红点 ///2.优先级:可镶嵌>可替换>可升级 ///3.同时有可镶嵌,可替换,可升级的符印孔时,默认只显示1个红点在镶嵌孔上 ///4.镶嵌:同时存在2个或以上的孔可镶嵌时,优先显示在孔位低的孔上,当孔上镶嵌了符印后,红点在下一个可镶嵌孔位置上显示,直至没有新符印可镶嵌,才继续判断更好品质符印的替换逻辑 ///5.替换:同上,有可替换更好品质的符印时,显示红点,同时多个时,从孔位低的开始显示,直到没有可替换的孔,再判断符印可升级的逻辑 ///6.升级:仅一个符印满足升级条件时,红点在该孔上;同时存在多个符印孔可升级时,红点显示在符印等级最低的孔上;符印等级相同时,红点显示在消耗少的孔上;升级需要的精华相同时,按孔位低的优先显示红点 ///7.右下角操作按钮:可镶嵌时镶嵌按钮红点显示;替换和升级同时满足时,仅替换按钮显示红点;无镶嵌和替换时,升级按钮红点显示 ///8.选中有红点的符印孔时,符印孔上的红点隐藏不显示 /// List cacheItemIndexs = new List(); List levelUpSorts = new List(); void RefreshRedpoint() { var levelUpHole = 100; var replaceHole = 100; levelUpSorts.Clear(); if (FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Rune)) { replaceHole = ExistEmptyHoleSatisfyInlay(); if (replaceHole != 100) { RefreshRedpoint(replaceHole, levelUpHole); return; } for (int i = 0; i < RUNE_HOLE_COUNT; i++) { if (SatisfyInlayBetterHole(i)) { replaceHole = i; break; } } if (replaceHole != 100) { RefreshRedpoint(replaceHole, levelUpHole); return; } for (int i = 0; i < RUNE_HOLE_COUNT; i++) { if (SatisfyLevelUpHole(i)) { levelUpSorts.Add(i); } } if (levelUpSorts.Count > 0) { levelUpSorts.Sort(CompareLevelUp); levelUpHole = levelUpSorts[0]; } } RefreshRedpoint(replaceHole, levelUpHole); } void RefreshRedpoint(int replaceHole, int levelUpHole) { for (int i = 0; i < RUNE_HOLE_COUNT; i++) { m_RuneHoleRedpoints[i].SetRedpoint(levelUpHole == i, replaceHole == i); } } int ExistEmptyHoleSatisfyInlay() { for (int i = 0; i < RUNE_HOLE_COUNT; i++) { if (SatisfyInlayHole(i)) { return i; } } return 100; } int CompareLevelUp(int lhs, int rhs) { RuneItem lhsItem; RuneItem rhsItem; if (TryGetRuneHoleItem(lhs, out lhsItem) && TryGetRuneHoleItem(rhs, out rhsItem)) { if (lhsItem.level != rhsItem.level) { return lhsItem.level.CompareTo(rhsItem.level); } var _cost_x = GetLevelUpRequireRuneEssence(lhsItem.id, lhsItem.level); var _cost_y = GetLevelUpRequireRuneEssence(rhsItem.id, rhsItem.level); if (_cost_x != _cost_y) { return _cost_x.CompareTo(_cost_y); } } return lhs.CompareTo(rhs); } public void SetDayRemind() { if (specialHoleRedpoint.state == RedPointState.Simple) { DayRemind.Instance.SetDayRemind(DayRemind.RUNE_SPECIAL_HOLE, true); RefreshSpecialHoleRedpoint(); } } private void RefreshSpecialHoleRedpoint() { var requireRemind = false; if (FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Rune)) { if (!DayRemind.Instance.GetDayRemind(DayRemind.RUNE_SPECIAL_HOLE)) { RuneHoleCondition condition; if (IsRuneHoleOpen(specialHole, holeState) && TryGetRuneHoleCondition(specialHole, out condition)) { if (PlayerDatas.Instance.baseData.LV >= condition.playerLevel && PlayerDatas.Instance.baseData.LV >= specialHoleRemindLevels[0] && PlayerDatas.Instance.baseData.LV < specialHoleRemindLevels[1]) { requireRemind = true; } } } } specialHoleRedpoint.state = requireRemind ? RedPointState.Simple : RedPointState.None; } public void JumpToCompose() { if (onJumpToCompose != null) { onJumpToCompose(); } } public class PropertyCompute { string formula = string.Empty; Dictionary qualityModulusDict; float multiPropertyModulus = 1f; Dictionary qualityBaseProperty; Dictionary cacheFormulaResult; public PropertyCompute(FuncConfigConfig config) { formula = config.Numerical1; qualityModulusDict = ConfigParse.GetDic(config.Numerical2); multiPropertyModulus = float.Parse(config.Numerical3); qualityBaseProperty = ConfigParse.GetDic(config.Numerical4); cacheFormulaResult = new Dictionary(); } public int GetPropertyValue(int id, int level) { var itemConfig = ItemConfig.Get(id); var runeConfig = RuneConfig.Get(id); float result = 0; if (itemConfig != null) { var formulaResult = 0f; if (cacheFormulaResult.ContainsKey(level)) { formulaResult = cacheFormulaResult[level]; } if (!cacheFormulaResult.ContainsKey(level)) { Equation.Instance.Clear(); Equation.Instance.AddKeyValue("level", level); formulaResult = Equation.Instance.Eval(formula); cacheFormulaResult.Add(level, formulaResult); } var quality = itemConfig.ItemColor; var propertyCount = 1; if (runeConfig != null) { propertyCount = runeConfig.AttrType.Length; } float qualityModulus = qualityModulusDict[quality]; var baseValue = 0; if (qualityBaseProperty.ContainsKey(quality)) { baseValue = qualityBaseProperty[quality]; } if (propertyCount > 1) { result = (formulaResult * qualityModulus + baseValue) * multiPropertyModulus; } else { result = formulaResult * qualityModulus + baseValue; } } return Mathf.FloorToInt(result); } public void CacheFormulaResult(int level) { for (int i = 1; i <= level; i++) { if (!cacheFormulaResult.ContainsKey(i)) { Equation.Instance.Clear(); Equation.Instance.AddKeyValue("level", i); var result = Equation.Instance.Eval(formula); cacheFormulaResult.Add(i, result); } } } } public class RuneHoleRedpoint { public readonly Redpoint redpoint; public readonly Redpoint levelUpRedpoint; public readonly Redpoint replaceRedpoint; public RuneHoleRedpoint(int baseId) { redpoint = new Redpoint(baseId, RuneModel.redpointIndex++); levelUpRedpoint = new Redpoint(redpoint.id, RuneModel.redpointIndex++); replaceRedpoint = new Redpoint(redpoint.id, RuneModel.redpointIndex++); } public void SetRedpoint(bool levelUp, bool replace) { levelUpRedpoint.state = levelUp ? RedPointState.Simple : RedPointState.None; replaceRedpoint.state = replace ? RedPointState.Simple : RedPointState.None; } } } public class RuneItem : VirtualPackItem { public int placeType { get; private set; }//0-背包 1-孔 public int sourceType { get; private set; }//来源(老号0,默认1,合成2) public int itemType { get; private set; } static RuneModel model { get { return ModelCenter.Instance.GetModel(); } } public void ParseHoleItem(int index, uint data) { ParsePackItem(index, data); placeType = 1; } public override void ParsePackItem(int index, uint data) { base.ParsePackItem(index, data); placeType = 0; var config = ItemConfig.Get(id); itemType = config.Type; sourceType = int.Parse(dataString.Substring(1, 1)); } public override void Release() { base.Release(); } public bool IsExistSameProperty(int _id) { List propertys; if (model.TryGetRunePropertys(id, out propertys)) { var config = RuneConfig.Get(_id); if (config != null) { for (int i = 0; i < config.AttrType.Length; i++) { if (propertys.Contains(config.AttrType[i])) { return true; } } } } return false; } public bool IsSameProperty(int property) { List propertys; if (model.TryGetRunePropertys(id, out propertys)) { return propertys.Contains(property); } return false; } } public struct RuneHoleCondition { public int runeTowerFloor; public int playerLevel; public int diamond; } }