using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using TableConfig; using UnityEngine; namespace Snxxz.UI { [XLua.LuaCallCSharp] [XLua.Hotfix] public class GatheringSoulModel : Model, IBeforePlayerDataInitialize, IPlayerLoginOk { Dictionary gatherSoulHoleDict = new Dictionary(); Dictionary holeConditions = new Dictionary(); Dictionary holeItemTypeDict; Dictionary qualityMaxLevelDict; Dictionary> propertySortDict = new Dictionary>(); Dictionary qualityResolveCostDict; public Dictionary> gatherSoulPropertys { get; private set; } public List packIndexs { get; private set; } public List topBestSoulIndexs = new List(); public List resolveItems { get; private set; } public int holeCount { get { return holeItemTypeDict.Count; } } public bool autoResolve { get { return QuickSetting.Instance.GetQuickSettingBool(QuickSetting.QuickSettingType.GatherSoulAutoResolve, 0, false); } set { var now = QuickSetting.Instance.GetQuickSettingBool(QuickSetting.QuickSettingType.GatherSoulAutoResolve, 0, false); if (value != now) { QuickSetting.Instance.SetQuickSetting(QuickSetting.QuickSettingType.GatherSoulAutoResolve, value); QuickSetting.Instance.SendPackage(); CheckAutoResolve(); } } } public int coreHole { get; private set; } public int autoResolveRemainCount { get; private set; } public bool serverInited { get; private set; } public Dictionary propertySorts { get { var job = PlayerDatas.Instance.baseData.Job; if (propertySortDict.ContainsKey(job)) { return propertySortDict[job]; } else { return propertySortDict[1]; } } } public event Action prepareResolveEvent; public event Action gatherSoulHoleRefresh; public event Action gatherSoulHolesRefresh; public event Action gatherSoulPackRefresh; public const int GATHERSOUL_SOUL_TYPE = 62; public const int GATHERSOUL_CORE_TYPE = 63; public const int GATHERSOUL_ESSENCE_TYPE = 61; public const int SOULDUST_MONEYTYPE = 28; public const int SOULSPLINTERS_MONEYTYPE = 29; public const int SOULCORE_MONEYTYPE = 30; public const int RARA_GATHERSOUL_QUALITY = 3; const int GATHERSOUL_REDPOINT_BASE = 10104; const int GATHERSOUL_REDPOINT_DEEP = 1010400; static int redpointIndex = 5; public readonly Redpoint redpoint = new Redpoint(101, GATHERSOUL_REDPOINT_BASE); public readonly Redpoint equipRedpoint = new Redpoint(GATHERSOUL_REDPOINT_BASE, 1010401); public readonly Redpoint replaceRedpoint = new Redpoint(GATHERSOUL_REDPOINT_BASE, 1010402); public readonly Redpoint resolveRedpoint = new Redpoint(GATHERSOUL_REDPOINT_BASE, 1010403); public readonly Redpoint levelUpRedpoint = new Redpoint(GATHERSOUL_REDPOINT_BASE, 1010404); static readonly IComparer soulPackSort = new GatherSoulPackSort(); static readonly IEqualityComparer holeItemTypeDistinct = new HoleItemTypeDistinct(); VirtualPackModel virtualPack { get { return ModelCenter.Instance.GetModel(); } } GatherSoulComposeModel composeModel { get { return ModelCenter.Instance.GetModel(); } } bool playerLevelRefresh = false; public override void Init() { ParseConfig(); packIndexs = new List(); resolveItems = new List(); virtualPack.virtualPackRefresh += VirtualPackRefresh; PlayerDatas.Instance.PlayerDataRefreshInfoEvent += PlayerDataRefreshInfoEvent; FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent; GlobalTimeEvent.Instance.secondEvent += PerSecond; } private void PerSecond() { if (serverInited) { if (playerLevelRefresh) { UpdateRedpoint(); playerLevelRefresh = false; } } } public void OnBeforePlayerDataInitialize() { serverInited = false; playerLevelRefresh = false; packIndexs.Clear(); topBestSoulIndexs.Clear(); gatherSoulHoleDict.Clear(); } public void OnPlayerLoginOk() { serverInited = true; CheckAutoResolve(); UpdateRedpoint(); } public override void UnInit() { virtualPack.virtualPackRefresh -= VirtualPackRefresh; PlayerDatas.Instance.PlayerDataRefreshInfoEvent -= PlayerDataRefreshInfoEvent; FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent; } private void OnFuncStateChangeEvent(int id) { if (id == 155) { UpdateRedpoint(); } } private void PlayerDataRefreshInfoEvent(PlayerDataRefresh refreshType) { if (refreshType == PlayerDataRefresh.CDBPlayerRefresh_SoulDust) { UpdateRedpoint(); } if (refreshType == PlayerDataRefresh.LV) { playerLevelRefresh = true; } } void ParseConfig() { var funcConfig = Config.Instance.Get("GatherSoulHole"); if (funcConfig != null) { var dict = ConfigParse.GetDic(funcConfig.Numerical1); foreach (var hole in dict.Keys) { holeConditions.Add(hole, new GatherSoulHoleCondition() { level = dict[hole], }); } holeItemTypeDict = ConfigParse.GetDic(funcConfig.Numerical2); foreach (var hole in holeItemTypeDict.Keys) { if (holeItemTypeDict[hole] == GATHERSOUL_CORE_TYPE) { coreHole = hole; } } } funcConfig = Config.Instance.Get("GatherSoulMaxLevel"); if (funcConfig != null) { qualityMaxLevelDict = ConfigParse.GetDic(funcConfig.Numerical1); } funcConfig = Config.Instance.Get("GatherSoulLevelUp"); qualityCostModulus = new Dictionary>(); if (funcConfig != null) { levelUpCostFormula = funcConfig.Numerical1; var json = LitJson.JsonMapper.ToObject(funcConfig.Numerical2); foreach (var typeKey in json.Keys) { var itemType = int.Parse(typeKey); Dictionary dict; if (!qualityCostModulus.TryGetValue(itemType, out dict)) { dict = new Dictionary(); qualityCostModulus.Add(itemType, dict); } foreach (var key in json[typeKey].Keys) { var quality = int.Parse(key); var modulus = float.Parse(json[typeKey][key].ToJson()); dict.Add(quality, modulus); } } multiPropertyModulus = ConfigParse.GetDic(funcConfig.Numerical3); qualityResolveCostDict = ConfigParse.GetDic(funcConfig.Numerical4); soulStageModulusDict = ConfigParse.GetDic(funcConfig.Numerical5); } funcConfig = Config.Instance.Get("GatherSoulAutoResolve"); if (funcConfig != null) { autoResolveRemainCount = int.Parse(funcConfig.Numerical1); } var gatherSoulPropertyConfigs = Config.Instance.GetAllValues(); for (int i = 0; i < gatherSoulPropertyConfigs.Count; i++) { var config = gatherSoulPropertyConfigs[i]; propertyComputeDict.Add(config.AttrType, new PropertyCompute(config)); var dict = ConfigParse.GetDic(config.sort); foreach (var job in dict.Keys) { Dictionary sortDict; if (!propertySortDict.TryGetValue(job, out sortDict)) { sortDict = new Dictionary(); propertySortDict.Add(job, sortDict); } sortDict.Add(config.AttrType, dict[job]); } } var gatherSoulConfigs = Config.Instance.GetAllValues(); gatherSoulPropertys = new Dictionary>(); for (int i = 0; i < gatherSoulConfigs.Count; i++) { var config = gatherSoulConfigs[i]; gatherSoulPropertys.Add(config.ID, new List()); gatherSoulPropertys[config.ID].AddRange(config.AttrType); } } public static string GetEquipHoleName(int id) { var itemConfig = Config.Instance.Get(id); return Language.Get(StringUtility.Contact("GatherSoulHoleName_", itemConfig.Type)); } public int GetPropertyHighestSort(List list) { var sort = -1; var dict = propertySorts; for (int i = 0; i < list.Count; i++) { if (dict.ContainsKey(list[i]) && dict[list[i]] > sort) { sort = dict[list[i]]; } } return sort; } private void VirtualPackRefresh(PackType packType) { if (packType == PackType.rptGatherSoul) { RefreshGatherSoulPack(); CheckAutoResolve(); UpdateRedpoint(); } } public void RefreshGatherSoulPack() { packIndexs.Clear(); topBestSoulIndexs.Clear(); List emptyHoles; if (ExistEmptyHole(out emptyHoles)) { emptyHoles = emptyHoles.Distinct(holeItemTypeDistinct).ToList(); SelectBestEquipSoul(emptyHoles); } if (packIndexs.Count == 0) { SelectBestReplaceSoul(); } packIndexs.Sort(CommonSort); var existCount = packIndexs.Count; List list; if (virtualPack.TryGetItems(PackType.rptGatherSoul, out list)) { for (int i = 0; i < list.Count; i++) { if (!packIndexs.Contains(list[i])) { packIndexs.Add(list[i]); } } } packIndexs.Sort(existCount, packIndexs.Count - existCount, soulPackSort); if (gatherSoulPackRefresh != null) { gatherSoulPackRefresh(); } } void SelectBestEquipSoul(List holes) { List list; if (virtualPack.TryGetItems(PackType.rptGatherSoul, out list)) { var error = 0; for (int k = 0; k < holes.Count; k++) { var hole = holes[k]; for (int i = 0; i < list.Count; i++) { GatherSoulItem item; if (virtualPack.TryGetItem(PackType.rptGatherSoul, list[i], out item)) { if (SatisfyEquipSoul(item, hole, out error)) { if (!packIndexs.Contains(list[i])) { packIndexs.Add(list[i]); } } } } } } JustSelectBest(); } void SelectBestReplaceSoul() { List list; if (virtualPack.TryGetItems(PackType.rptGatherSoul, out list)) { for (int i = 0; i < list.Count; i++) { GatherSoulItem packItem; if (virtualPack.TryGetItem(PackType.rptGatherSoul, list[i], out packItem)) { var hole = 0; if (SatisfyReplace(packItem, out hole)) { GatherSoulItem item; if (TryGetItem(hole, out item) && packItem.Compare(item) == 1) { if (!packIndexs.Contains(list[i])) { packIndexs.Add(list[i]); } } } } } } JustSelectBest(); } void JustSelectBest() { List removeList = new List(); for (int i = 0; i < packIndexs.Count; i++) { if (removeList.Contains(i)) { continue; } GatherSoulItem item; virtualPack.TryGetItem(PackType.rptGatherSoul, packIndexs[i], out item); for (int k = i + 1; k < packIndexs.Count; k++) { if (removeList.Contains(k)) { continue; } GatherSoulItem compareItem; virtualPack.TryGetItem(PackType.rptGatherSoul, packIndexs[k], out compareItem); int compare = item.Compare(compareItem); if (item.ExistSameProperty(compareItem.id)) { if (compare == 1 || compare == 0) { removeList.Add(k); } else { removeList.Add(i); break; } } } } removeList.Sort(); for (int i = removeList.Count - 1; i >= 0; i--) { packIndexs.RemoveAt(removeList[i]); } topBestSoulIndexs.AddRange(packIndexs); } public bool ExistEmptyHole(out List list) { var count = holeCount; list = new List(); for (int i = 0; i < count; i++) { if (!IsHoleUnlock(i)) { continue; } GatherSoulItem item; if (!TryGetItem(i, out item)) { list.Add(i); } } return list.Count > 0; } public bool ExistEmptyHole() { var count = holeCount; for (int i = 0; i < count; i++) { if (!IsHoleUnlock(i)) { continue; } GatherSoulItem item; if (!TryGetItem(i, out item)) { return true; } } return false; } public void OnReceiveServerPack(HA31E_tagMCGatherSoulHoleInfo package) { gatherSoulHoleDict.Clear(); for (int i = 0; i < package.Count; i++) { var data = package.GatherSoulDataList[i]; if (data != 0) { var item = new GatherSoulItem(); item.ParseHoleItem(i, data, 1); gatherSoulHoleDict.Add(i, item); } if (gatherSoulHoleRefresh != null) { gatherSoulHoleRefresh(i); } } if (gatherSoulHolesRefresh != null) { gatherSoulHolesRefresh(); } RefreshGatherSoulPack(); UpdateRedpoint(); } public bool ContainsEquipSoul(int hole) { List list; if (virtualPack.TryGetItems(PackType.rptGatherSoul, out list)) { int error = 0; for (int i = 0; i < list.Count; i++) { GatherSoulItem item; if (virtualPack.TryGetItem(PackType.rptGatherSoul, list[i], out item)) { if (SatisfyEquipSoul(item, hole, out error)) { return true; } } } } return false; } public void TryGetSatisfyEquipSouls(int hole, ref List equipList) { equipList.Clear(); List list; if (virtualPack.TryGetItems(PackType.rptGatherSoul, out list)) { var error = 0; for (int i = 0; i < list.Count; i++) { GatherSoulItem item; if (virtualPack.TryGetItem(PackType.rptGatherSoul, list[i], out item)) { if (SatisfyEquipSoul(item, hole, out error)) { equipList.Add(item); } } } } } public void TryGetSatisfyReplaceSouls(int hole, ref List replaceList) { replaceList.Clear(); List list; if (virtualPack.TryGetItems(PackType.rptGatherSoul, out list)) { for (int i = 0; i < list.Count; i++) { GatherSoulItem item; if (virtualPack.TryGetItem(PackType.rptGatherSoul, list[i], out item)) { if (SatisfyReplace(hole, item)) { replaceList.Add(item); } } } } } public bool IsHoleUnlock(int hole) { GatherSoulItem item; if (TryGetItem(hole, out item)) { return true; } GatherSoulHoleCondition condition; if (TryGetHoleCondition(hole, out condition)) { return PlayerDatas.Instance.baseData.LV >= condition.level; } return true; } public bool SatisfyEquipSoul(GatherSoulItem item, int hole, out int error) { error = 0; if (item.placeType != 0) { return false; } var itemConfig = Config.Instance.Get(item.id); if (!IsHoleUnlock(hole)) { error = 1; return false; } if (holeItemTypeDict.ContainsKey(hole)) { if (holeItemTypeDict[hole] != itemConfig.Type) { error = 2; return false; } } bool samePropertyCompareHole = false; GatherSoulItem holeItem; if (TryGetItem(hole, out holeItem)) { if (item.ExistSameProperty(holeItem.id)) { samePropertyCompareHole = true; } } if (!samePropertyCompareHole && IsSamePropertyCompareHoles(hole, item) != -1) { error = 3; return false; } return true; } public bool SatisfyReplace(GatherSoulItem item, out int hole) { var count = holeCount; hole = 0; for (int i = 0; i < count; i++) { GatherSoulItem holeItem; if (TryGetItem(i, out holeItem)) { if (item.gatherSoulType == holeItem.gatherSoulType && item.ExistSameProperty(holeItem.id)) { hole = i; return true; } } } return false; } public bool SatisfyReplace(int hole, GatherSoulItem item) { if (item.itemType == GATHERSOUL_ESSENCE_TYPE) { return false; } GatherSoulItem holeItem; if (TryGetItem(hole, out holeItem)) { var sameHole = IsSamePropertyCompareHoles(hole, item); var multiProperty = false; if (item.ExistSameProperty(holeItem.id)) { multiProperty = gatherSoulPropertys[item.id].Count > gatherSoulPropertys[holeItem.id].Count; } if (item.itemType == holeItem.itemType && (sameHole == -1 || multiProperty)) { return true; } } return false; } public bool SatisfyLevelUp(GatherSoulItem item, out int error) { error = 0; if (IsGatherSoulMaxLevel(item.id, item.level)) { error = 1; return false; } if ((ulong)RequireLevelUpCost(item) > UIHelper.GetMoneyCnt(28)) { error = 2; return false; } return true; } public void DisplayLevelUpError(int error) { switch (error) { case 1: SysNotifyMgr.Instance.ShowTip("GatherSoulLevelError_1"); break; case 2: SysNotifyMgr.Instance.ShowTip("GatherSoulLevelError_2"); break; } } public int IsSamePropertyCompareHoles(int exclude, GatherSoulItem item) { var count = holeCount; for (int i = 0; i < count; i++) { if (i == exclude) { continue; } if (IsSamePropertyCompareHole(i, item)) { return i; } } return -1; } public bool IsSamePropertyCompareHole(int hole, GatherSoulItem item) { GatherSoulItem compare; if (TryGetItem(hole, out compare)) { return item.ExistSameProperty(compare.id); } return false; } public bool IsGatherSoulMaxLevel(int id, int level) { var config = Config.Instance.Get(id); if (qualityMaxLevelDict != null && qualityMaxLevelDict.ContainsKey(config.ItemColor)) { return qualityMaxLevelDict[config.ItemColor] <= level; } return true; } public bool IsBestSoul(GatherSoulItem item, int excludePlaceType, int excludeIndex) { var count = holeCount; for (int i = 0; i < count; i++) { GatherSoulItem compare; if (TryGetItem(i, out compare)) { if (compare.placeType == excludePlaceType && compare.index == excludeIndex) { continue; } if (item.ExistSameProperty(compare.id) && item.itemColor < compare.itemColor) { return false; } } } List list; if (virtualPack.TryGetItems(PackType.rptGatherSoul, out list)) { GatherSoulItem packItem; for (int i = 0; i < list.Count; i++) { if (virtualPack.TryGetItem(PackType.rptGatherSoul, list[i], out packItem)) { var compare = packItem; if (compare.placeType == excludePlaceType && compare.index == excludeIndex) { continue; } if (compare.itemType == GATHERSOUL_ESSENCE_TYPE) { continue; } if (item.ExistSameProperty(compare.id) && item.itemColor < compare.itemColor) { return false; } } } } return true; } public void HandleSoulTipFunc(ItemWinBtnType type, GatherSoulItem item) { switch (type) { case ItemWinBtnType.compose: if (!FuncOpen.Instance.IsFuncOpen(158)) { FuncOpen.Instance.ProcessorFuncErrorTip(158); return; } WindowCenter.Instance.Close(); composeModel.jumpGatherSoulItem = new VirtualItem() { packType = item.placeType == 0 ? PackType.rptGatherSoul : PackType.rptInterimPack, index = item.index, itemId = item.id, level = item.level }; WindowJumpMgr.Instance.WindowJumpTo(JumpUIType.GatherSoul271); break; case ItemWinBtnType.dismantle: case ItemWinBtnType.Resolve: if (type == ItemWinBtnType.Resolve && item.itemType != GATHERSOUL_ESSENCE_TYPE && IsBestSoul(item, item.placeType, item.index)) { ConfirmCancel.ShowPopConfirm(Language.Get("Mail101"), Language.Get("BestGatherSoulResolveConfirm"), (bool isOk) => { if (isOk) { ExecuteResolve(item); } }); } else { if (item.itemColor >= RARA_GATHERSOUL_QUALITY) { ConfirmCancel.ShowPopConfirm(Language.Get("Mail101"), Language.Get("BestGatherSoulResolveConfirm"), (bool isOk) => { if (isOk) { ExecuteResolve(item); } }); } else { ExecuteResolve(item); } } break; case ItemWinBtnType.Wear: List emptyHoles; bool existEmptyHole = false; if (ExistEmptyHole(out emptyHoles)) { if (item.itemType == GATHERSOUL_CORE_TYPE && emptyHoles.Contains(coreHole)) { existEmptyHole = true; } else if (item.itemType == GATHERSOUL_SOUL_TYPE) { existEmptyHole = emptyHoles.Count > 1 || emptyHoles[0] != coreHole; } } if (existEmptyHole) { WindowCenter.Instance.Close(); ExecuteEquipSoul(item); } else { SysNotifyMgr.Instance.ShowTip("NoneOfAnyEmptySoulHole"); } break; case ItemWinBtnType.Replace: WindowCenter.Instance.Close(); ExecuteReplaceSoul(item); break; } } public void ExecuteResolve(GatherSoulItem item) { GatherSoulComposeModel.Compose compose; if (composeModel.TryGetCompose(item.id, out compose)) { var config = Config.Instance.Get(item.id); var baseName = UIHelper.AppendStringColor(config.ItemColor, config.ItemName, true); var sb = new StringBuilder(); for (int i = 0; i < compose.requireItems.Count; i++) { var itemId = compose.requireItems[i]; config = Config.Instance.Get(itemId); sb.Append(UIHelper.AppendStringColor(config.ItemColor, config.ItemName, true)); if (i < compose.requireItems.Count - 2) { sb.Append("、"); } else if (i == compose.requireItems.Count - 2) { sb.Append(Language.Get("GatherSoulAnd")); } } var requireSoulCore = 0; var requireSoulSplinters = 0; var soulDust = GetResolveReturnCost(item.id, item.level, true); if (composeModel.TryGetCompose(item.id, out compose)) { requireSoulCore = compose.requireSoulCore; requireSoulSplinters = compose.requireSoulSplinters; } ConfirmCancel.ShowPopConfirm(Language.Get("Mail101"), Language.Get("MultiGatherSoulResolveConfirm", baseName, sb.ToString(), requireSoulCore, requireSoulSplinters, soulDust), (bool isOk) => { if (isOk) { WindowCenter.Instance.Close(); SendResolvePack(item); } }); } else { WindowCenter.Instance.Close(); SendResolvePack(item); } } public void SendResolvePack(GatherSoulItem item) { if (!CheckExist(item)) { return; } if (prepareResolveEvent != null) { prepareResolveEvent(item.placeType == 0 ? PackType.rptGatherSoul : PackType.rptInterimPack, item.index); } SendResolvePack(new ushort[1] { (ushort)item.index }, false); } public void ExecuteEquipSoul(GatherSoulItem item) { var error = 0; List list; if (ExistEmptyHole(out list)) { for (int i = 0; i < list.Count; i++) { if (SatisfyEquipSoul(item, list[i], out error)) { SendEquipPack((int)PackType.rptGatherSoul, item.index, (int)PackType.rptInterimPack, list[i]); return; } } } } public void ExecuteEquipSoul(GatherSoulItem item, int hole) { var error = 0; if (SatisfyEquipSoul(item, hole, out error)) { SendEquipPack((int)PackType.rptGatherSoul, item.index, (int)PackType.rptInterimPack, hole); } } public void ExecuteReplaceSoul(GatherSoulItem item) { var error = 0; var count = holeCount; var tryEquipHole = -1; for (int i = 0; i < count; i++) { if (SatisfyEquipSoul(item, i, out error)) { tryEquipHole = i; break; } } TryExecuteReplaceSoul(tryEquipHole, item); } public void TryExecuteReplaceSoul(int hole, GatherSoulItem item) { if (hole != -1) { GatherSoulItem holeItem; if (TryGetItem(hole, out holeItem)) { var sameHole = -1; if (gatherSoulPropertys[item.id].Count > gatherSoulPropertys[holeItem.id].Count) { sameHole = IsSamePropertyCompareHoles(hole, item); } if (sameHole != -1) { SendEquipPack((int)PackType.rptInterimPack, sameHole, (int)PackType.rptGatherSoul, 0); } SendEquipPack((int)PackType.rptGatherSoul, item.index, (int)PackType.rptInterimPack, hole); } } else if (item.itemType == GATHERSOUL_CORE_TYPE) { GatherSoulItem holeItem; if (TryGetItem(coreHole, out holeItem)) { var sameHole = -1; if (gatherSoulPropertys[item.id].Count > gatherSoulPropertys[holeItem.id].Count) { sameHole = IsSamePropertyCompareHoles(coreHole, item); } if (sameHole != -1) { SendEquipPack((int)PackType.rptInterimPack, sameHole, (int)PackType.rptGatherSoul, 0); } SendEquipPack((int)PackType.rptGatherSoul, item.index, (int)PackType.rptInterimPack, hole); } } } public void ExecutePutOffSoul(GatherSoulItem item) { if (item.placeType == 1) { if (virtualPack.GetPackRemainCount(PackType.rptGatherSoul) < 1) { SysNotifyMgr.Instance.ShowTip("GeRen_chenxin_676165", (int)PackType.rptGatherSoul); return; } SendEquipPack((int)PackType.rptInterimPack, item.index, (int)PackType.rptGatherSoul, 0); } } public void SendResolvePack(ushort[] resolves, bool isAuto) { CA519_tagCMGatherSoulDecompose pak = new CA519_tagCMGatherSoulDecompose(); pak.IsAuto = isAuto ? (byte)1 : (byte)0; pak.PlaceIndexList = resolves; pak.Count = (byte)resolves.Length; GameNetSystem.Instance.SendInfo(pak); } void SendEquipPack(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 bool CheckExist(GatherSoulItem item) { bool same = false; if (item.placeType == 0) { GatherSoulItem compare; same = virtualPack.TryGetItem(PackType.rptGatherSoul, item.index, out compare) && item.IsEqual(compare); } else if (item.placeType == 1) { GatherSoulItem compare; same = TryGetItem(item.index, out compare) && item.IsEqual(compare); } return same; } public bool CheckExist(VirtualItem item) { if (item.packType == PackType.rptGatherSoul) { GatherSoulItem compare; if (virtualPack.TryGetItem(PackType.rptGatherSoul, item.index, out compare)) { return item.itemId == compare.id && item.level == compare.level; } } else if (item.packType == PackType.rptInterimPack) { GatherSoulItem compare; if (TryGetItem(item.index, out compare)) { return item.itemId == compare.id && item.level == compare.level; } } return false; } public bool TryGetHoleCondition(int hole, out GatherSoulHoleCondition condition) { return holeConditions.TryGetValue(hole, out condition); } public bool TryGetItem(int hole, out GatherSoulItem item) { return gatherSoulHoleDict.TryGetValue(hole, out item); } public bool TryGetHighestLevelItem(int itemId, out GatherSoulItem item) { item = null; foreach (var soulItem in gatherSoulHoleDict.Values) { if (soulItem.id == itemId && (item == null || soulItem.level > item.level)) { item = soulItem; } } List list; if (virtualPack.TryGetItems(PackType.rptGatherSoul, out list)) { GatherSoulItem packItem; for (int i = 0; i < list.Count; i++) { if (virtualPack.TryGetItem(PackType.rptGatherSoul, list[i], out packItem)) { if (packItem.id == itemId && (item == null || packItem.level > item.level)) { item = packItem; } } } } return item != null; } public bool TryGetSinglePropertyItems(int property, out int itemId) { itemId = 0; foreach (var key in gatherSoulPropertys.Keys) { if (gatherSoulPropertys[key].Count == 1 && gatherSoulPropertys[key][0] == property) { itemId = key; return true; } } return false; } public int CommonSort(GatherSoulItem lhs, GatherSoulItem rhs) { var lhsPropertyCount = gatherSoulPropertys[lhs.id].Count; var rhsPropertyCount = gatherSoulPropertys[rhs.id].Count; if (lhsPropertyCount != rhsPropertyCount) { return -lhsPropertyCount.CompareTo(rhsPropertyCount); } var lhsConfig = Config.Instance.Get(lhs.id); var rhsConfig = Config.Instance.Get(rhs.id); if (lhsConfig.ItemColor != rhsConfig.ItemColor) { return -lhsConfig.ItemColor.CompareTo(rhsConfig.ItemColor); } var lhsPropertys = gatherSoulPropertys[lhs.id]; var rhsPropertys = gatherSoulPropertys[rhs.id]; var lhsPropertySort = GetPropertyHighestSort(lhsPropertys); var rhsPropertySort = GetPropertyHighestSort(rhsPropertys); if (lhsPropertySort != rhsPropertySort) { return lhsPropertySort.CompareTo(rhsPropertySort); } return 0; } public int CommonSort(int lhs, int rhs) { GatherSoulItem lhsItem; GatherSoulItem rhsItem; if (!virtualPack.TryGetItem(PackType.rptGatherSoul, lhs, out lhsItem) || !virtualPack.TryGetItem(PackType.rptGatherSoul, rhs, out rhsItem)) { return 0; } return CommonSort(lhsItem, rhsItem); } public int CommonSort2(GatherSoulItem lhs, GatherSoulItem rhs) { if (lhs.gatherSoulType != rhs.gatherSoulType) { return lhs.gatherSoulType.CompareTo(rhs.gatherSoulType); } if (lhs.gatherSoulType != GatherSoulType.Essence && rhs.gatherSoulType != GatherSoulType.Essence) { var lhsPropertys = gatherSoulPropertys[lhs.id]; var rhsPropertys = gatherSoulPropertys[rhs.id]; if (lhsPropertys.Count != rhsPropertys.Count) { return -lhsPropertys.Count.CompareTo(rhsPropertys.Count); } } var lhsConfig = Config.Instance.Get(lhs.id); var rhsConfig = Config.Instance.Get(rhs.id); if (null == lhsConfig || null == rhsConfig) { return 0; } if (lhsConfig.ItemColor.CompareTo(rhsConfig.ItemColor) != 0) { return -lhsConfig.ItemColor.CompareTo(rhsConfig.ItemColor); } if (lhs.gatherSoulType != GatherSoulType.Essence && rhs.gatherSoulType != GatherSoulType.Essence) { var lhsPropertys = gatherSoulPropertys[lhs.id]; var rhsPropertys = gatherSoulPropertys[rhs.id]; var lhsPropertySort = GetPropertyHighestSort(lhsPropertys); var rhsPropertySort = GetPropertyHighestSort(rhsPropertys); if (lhsPropertySort != rhsPropertySort) { return lhsPropertySort.CompareTo(rhsPropertySort); } } if (lhs.level.CompareTo(rhs.level) != 0) { return -lhs.level.CompareTo(rhs.level); } return 0; } #region 属性值计算 Dictionary propertyComputeDict = new Dictionary(); public class PropertyCompute { string formula = string.Empty; Dictionary qualityModulusDict; Dictionary multiPropertyModulusDict; Dictionary qualityBaseProperty; Dictionary cacheFormulaResult; Dictionary soulStageModulusDict; public PropertyCompute(GatherSoulPropertyConfig config) { formula = config.AttrInfo1; qualityModulusDict = ConfigParse.GetDic(config.AttrInfo2); multiPropertyModulusDict = ConfigParse.GetDic(config.AttrInfo3); qualityBaseProperty = ConfigParse.GetDic(config.AttrInfo4); soulStageModulusDict = ConfigParse.GetDic(config.AttrInfo5); cacheFormulaResult = new Dictionary(); } public int GetPropertyValue(int id, int level) { var itemConfig = Config.Instance.Get(id); var gatherSoulConfig = Config.Instance.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 (gatherSoulConfig != null) { propertyCount = gatherSoulConfig.AttrType.Length; } float qualityModulus = qualityModulusDict[quality]; var baseValue = 0; if (qualityBaseProperty.ContainsKey(quality)) { baseValue = qualityBaseProperty[quality]; } var stage = gatherSoulConfig.soulStage; float soulStageModulus = 1; if (soulStageModulusDict.ContainsKey(stage)) { soulStageModulus = soulStageModulusDict[stage]; } if (multiPropertyModulusDict.ContainsKey(propertyCount)) { var multiPropertyModulus = multiPropertyModulusDict[propertyCount]; result = (formulaResult * qualityModulus + baseValue) * soulStageModulus * multiPropertyModulus; } else { result = (formulaResult * qualityModulus + baseValue) * soulStageModulus; } } return Mathf.FloorToInt(result); } } public int GetPropertyValue(int id, int type, int level) { if (propertyComputeDict.ContainsKey(type)) { return propertyComputeDict[type].GetPropertyValue(id, level); } return 0; } #endregion #region 消耗计算 string levelUpCostFormula = string.Empty; Dictionary levelUpFormulaCostDict = new Dictionary(); Dictionary> qualityCostModulus; Dictionary multiPropertyModulus; Dictionary soulStageModulusDict; public int RequireLevelUpCost(GatherSoulItem item) { return RequireLevelUpCost(item.id, item.level); } public int RequireLevelUpCost(int id, int level) { var result = 0f; var itemConfig = Config.Instance.Get(id); var formulaResult = 0f; if (levelUpFormulaCostDict.ContainsKey(level + 1)) { formulaResult = levelUpFormulaCostDict[level + 1]; } else { Equation.Instance.Clear(); Equation.Instance.AddKeyValue("level", level + 1); formulaResult = Equation.Instance.Eval(levelUpCostFormula); levelUpFormulaCostDict.Add(level + 1, formulaResult); } var propertyCount = gatherSoulPropertys.ContainsKey(id) ? gatherSoulPropertys[id].Count : 1; var stage = 0; var config = Config.Instance.Get(id); if (config != null) { stage = config.soulStage; } var soulStageModulus = soulStageModulusDict != null && soulStageModulusDict.ContainsKey(stage) ? soulStageModulusDict[stage] : 1; var qualityModulus = 1f; if (qualityCostModulus.ContainsKey(itemConfig.Type)) { if (qualityCostModulus[itemConfig.Type].ContainsKey(itemConfig.ItemColor)) { qualityModulus = qualityCostModulus[itemConfig.Type][itemConfig.ItemColor]; } } if (multiPropertyModulus.ContainsKey(propertyCount)) { result = formulaResult * qualityModulus * soulStageModulus * multiPropertyModulus[propertyCount]; } else { result = formulaResult * qualityModulus * soulStageModulus; } return Mathf.FloorToInt(result); } public int GetLevelByCost(int id, ulong cost) { var config = Config.Instance.Get(id); var maxLevel = qualityMaxLevelDict[config.ItemColor]; ulong totalCost = 0; for (int i = 1; i < maxLevel; i++) { totalCost += (ulong)RequireLevelUpCost(id, i); if (cost < totalCost) { return i; } } return maxLevel; } #endregion #region 分解 public event Action oneKeyResolveRefresh; public int GetResolveReturnCost(int id, int level, bool fromCompose = false) { float result = 0; var itemConfig = Config.Instance.Get(id); if (itemConfig.Type == GATHERSOUL_ESSENCE_TYPE) { return itemConfig.EffectValueA1; } for (int i = 1; i <= level; i++) { if (i == 1) { if (!fromCompose) { var stage = 0; var config = Config.Instance.Get(id); if (config != null) { stage = config.soulStage; } var soulStageModulus = soulStageModulusDict != null && soulStageModulusDict.ContainsKey(stage) ? soulStageModulusDict[stage] : 1; if (qualityResolveCostDict != null && qualityResolveCostDict.ContainsKey(itemConfig.ItemColor)) { result += qualityResolveCostDict[itemConfig.ItemColor] * soulStageModulus; } } } else { result += RequireLevelUpCost(id, i - 1); } } return (int)result; } public void GetResolveSouls(int quality, List list) { list.Clear(); Dictionary dict = new Dictionary(); var count = holeCount; for (int i = 0; i < count; i++) { GatherSoulItem item; if (TryGetItem(i, out item)) { SetPropertyQuality(item, ref dict); } } List packlist; if (virtualPack.TryGetItems(PackType.rptGatherSoul, out packlist)) { GatherSoulItem item; for (int i = 0; i < packlist.Count; i++) { if (virtualPack.TryGetItem(PackType.rptGatherSoul, packlist[i], out item)) { if (item.itemType == GATHERSOUL_ESSENCE_TYPE) { continue; } SetPropertyQuality(item, ref dict); } } } for (int i = 0; i < packlist.Count; i++) { GatherSoulItem item; if (virtualPack.TryGetItem(PackType.rptGatherSoul, packlist[i], out item)) { if (item.itemType == GATHERSOUL_ESSENCE_TYPE) { list.Add(item); continue; } if (item.itemType == GATHERSOUL_CORE_TYPE) { continue; } var propertys = gatherSoulPropertys[item.id]; if (propertys.Count > 1) { continue; } var property = propertys[0]; var config = Config.Instance.Get(item.id); if (item.itemType == GATHERSOUL_SOUL_TYPE && config.ItemColor < RARA_GATHERSOUL_QUALITY) { list.Add(item); continue; } if (config.ItemColor <= quality && config.ItemColor < dict[property]) { list.Add(item); } } } } public void GetAutoResolveSouls(int quality, List list) { list.Clear(); Dictionary dict = new Dictionary(); var count = holeCount; for (int i = 0; i < count; i++) { GatherSoulItem item; if (TryGetItem(i, out item)) { SetPropertyQuality(item, ref dict); } } List packlist; if (virtualPack.TryGetItems(PackType.rptGatherSoul, out packlist)) { GatherSoulItem item; for (int i = 0; i < packlist.Count; i++) { if (virtualPack.TryGetItem(PackType.rptGatherSoul, packlist[i], out item)) { if (item.itemType == GATHERSOUL_ESSENCE_TYPE) { continue; } SetPropertyQuality(item, ref dict); } } } for (int i = 0; i < packlist.Count; i++) { GatherSoulItem item; if (virtualPack.TryGetItem(PackType.rptGatherSoul, packlist[i], out item)) { if (item.itemType == GATHERSOUL_ESSENCE_TYPE) { list.Add(item); continue; } if (item.itemType == GATHERSOUL_CORE_TYPE || item.itemColor >= RARA_GATHERSOUL_QUALITY) { continue; } var propertys = gatherSoulPropertys[item.id]; if (propertys.Count > 1) { continue; } var property = propertys[0]; var config = Config.Instance.Get(item.id); if (config.ItemColor <= quality && config.ItemColor < dict[property]) { list.Add(item); } } } } void SetPropertyQuality(GatherSoulItem item, ref Dictionary dict) { var propertys = gatherSoulPropertys[item.id]; var itemConfig = Config.Instance.Get(item.id); for (int i = 0; i < propertys.Count; i++) { var property = propertys[i]; if (!dict.ContainsKey(property) || dict[property] < itemConfig.ItemColor) { dict[property] = itemConfig.ItemColor; } } } public void RemoveOneKeyResolve(int index) { if (index != -1 && index < resolveItems.Count) { resolveItems.RemoveAt(index); resolveItems.Insert(index, null); if (oneKeyResolveRefresh != null) { oneKeyResolveRefresh(); } } } List autoResolveList = new List(); void CheckAutoResolve() { if (!autoResolve) { return; } var capacity = virtualPack.GetPackCapacity(PackType.rptGatherSoul); List list; if (virtualPack.TryGetItems(PackType.rptGatherSoul, out list)) { if (capacity - list.Count >= autoResolveRemainCount) { return; } autoResolveList.Clear(); GetAutoResolveSouls(int.MaxValue, autoResolveList); List resolveList = new List(); for (int i = 0; i < autoResolveList.Count; i++) { resolveList.Add((ushort)autoResolveList[i].index); } var page = Mathf.CeilToInt((float)resolveList.Count / 50); for (int i = 0; i < page; i++) { ushort[] resolves = resolveList.Skip(i * 50).Take((i < page - 1) ? 50 : (resolveList.Count - i * 50)).ToArray(); SendResolvePack(resolves, true); } } } #endregion #region 红点 public int equipRedpointHole = 0; public int levelUpRedpointHole = 0; public int replaceRedpointIndex = 0; void UpdateRedpoint() { equipRedpoint.state = RedPointState.None; replaceRedpoint.state = RedPointState.None; resolveRedpoint.state = RedPointState.None; levelUpRedpoint.state = RedPointState.None; if (!FuncOpen.Instance.IsFuncOpen(155)) { return; } var error = 0; List holes; if (ExistEmptyHole(out holes) && packIndexs.Count > 0) { GatherSoulItem item; if (virtualPack.TryGetItem(PackType.rptGatherSoul, packIndexs[0], out item)) { for (int i = 0; i < holes.Count; i++) { if (SatisfyEquipSoul(item, holes[i], out error)) { equipRedpointHole = holes[i]; equipRedpoint.state = RedPointState.Simple; return; } } } } var count = holeCount; if (packIndexs.Count > 0) { GatherSoulItem item; virtualPack.TryGetItem(PackType.rptGatherSoul, packIndexs[0], out item); if (item != null) { var hole = 0; if (SatisfyReplace(item, out hole)) { GatherSoulItem holeItem; if (TryGetItem(hole, out holeItem)) { if (item.Compare(holeItem) == 1) { replaceRedpointIndex = item.index; replaceRedpoint.state = RedPointState.Simple; return; } } } } } List list = new List(); GetResolveSouls(int.MaxValue, list); if (list.Count > 0) { for (int i = 0; i < list.Count; i++) { if (list[i] == null) { continue; } if (list[i].itemType == GATHERSOUL_ESSENCE_TYPE || list[i].itemColor < RARA_GATHERSOUL_QUALITY) { resolveRedpoint.state = RedPointState.Simple; list = null; return; } } } levelUpRedpointHole = -1; var cost = 0; for (int i = 0; i < count; i++) { GatherSoulItem holeItem; if (TryGetItem(i, out holeItem)) { if (SatisfyLevelUp(holeItem, out error)) { if (RequireLevelUpCost(holeItem) < cost || cost == 0) { cost = RequireLevelUpCost(holeItem); levelUpRedpointHole = i; } } } } if (levelUpRedpointHole != -1) { levelUpRedpoint.state = RedPointState.Simple; } } #endregion public class HoleItemTypeDistinct : IEqualityComparer { GatheringSoulModel model { get { return ModelCenter.Instance.GetModel(); } } public bool Equals(int x, int y) { return model.holeItemTypeDict[x] == model.holeItemTypeDict[y]; } public int GetHashCode(int obj) { if (model.holeItemTypeDict.ContainsKey(obj)) { return model.holeItemTypeDict[obj].GetHashCode(); } return obj.GetHashCode(); } } } public class GatherSoulItem : VirtualPackItem { public GatherSoulType gatherSoulType; public int itemType { get; private set; } public int placeType { get; private set; }//0-背包 1-装备 public int itemColor { get; private set; } GatheringSoulModel model { get { return ModelCenter.Instance.GetModel(); } } public void ParseHoleItem(int index, uint data, int placeType) { ParsePackItem(index, data); this.placeType = placeType; } public override void ParsePackItem(int index, uint data) { base.ParsePackItem(index, data); var itemConfig = Config.Instance.Get(id); itemType = itemConfig.Type; itemColor = itemConfig.ItemColor; if (itemType == GatheringSoulModel.GATHERSOUL_SOUL_TYPE) { gatherSoulType = GatherSoulType.Soul; } else if (itemType == GatheringSoulModel.GATHERSOUL_CORE_TYPE) { gatherSoulType = GatherSoulType.Core; } else if (itemType == GatheringSoulModel.GATHERSOUL_ESSENCE_TYPE) { gatherSoulType = GatherSoulType.Essence; } } public bool ExistSameProperty(int compareId) { if (!model.gatherSoulPropertys.ContainsKey(compareId) || !model.gatherSoulPropertys.ContainsKey(id)) { return false; } var list = model.gatherSoulPropertys[id]; for (int i = 0; i < list.Count; i++) { var comparePropertys = model.gatherSoulPropertys[compareId]; if (comparePropertys.Contains(list[i])) { return true; } } return false; } public int Compare(GatherSoulItem compare) { var comparePropertyCount = model.gatherSoulPropertys[compare.id].Count; var propertyCount = model.gatherSoulPropertys[id].Count; if (comparePropertyCount != propertyCount) { return propertyCount > comparePropertyCount ? 1 : -1; } var compareConfig = Config.Instance.Get(compare.id); var config = Config.Instance.Get(id); if (compareConfig.ItemColor != config.ItemColor) { return config.ItemColor > compareConfig.ItemColor ? 1 : -1; } if (level != compare.level) { return level > compare.level ? 1 : -1; } return 0; } public bool IsEqual(GatherSoulItem compare) { return this.id == compare.id && this.index == compare.index && this.level == compare.level && this.placeType == compare.placeType; } } public enum GatherSoulType { Core, Soul, Essence, } public struct GatherSoulHoleCondition { public int level; } public interface IGatherSoulTipScrollPart { float GetHeight(); } public class GatherSoulPackSort : IComparer { VirtualPackModel virtualPackModel { get { return ModelCenter.Instance.GetModel(); } } GatheringSoulModel model { get { return ModelCenter.Instance.GetModel(); } } public int Compare(int lhs, int rhs) { GatherSoulItem lhsItem; GatherSoulItem rhsItem; if (!virtualPackModel.TryGetItem(PackType.rptGatherSoul, lhs, out lhsItem) || !virtualPackModel.TryGetItem(PackType.rptGatherSoul, rhs, out rhsItem)) { return 0; } return model.CommonSort2(lhsItem, rhsItem); } } }