using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using System.Text; using System.Linq; namespace vnxbqy.UI { public class AchievementModel : Model, IBeforePlayerDataInitialize { public event Action achievementProgressUpdateEvent; public event Action achievementCompletedEvent; public event Action achievementAwardableEvent; Dictionary achievements = new Dictionary(); Dictionary> achievementCategorys = new Dictionary>();//客户端必须按group分类 public Dictionary> groupToType = new Dictionary>(); public Dictionary> typeToGroup = new Dictionary>(); //所有的类型对应组别 public Dictionary typeToGroupBP = new Dictionary(); //战令的类型对应组别 VipModel vipModel { get { return ModelCenter.Instance.GetModel(); } } PackModel playerPack { get { return ModelCenter.Instance.GetModel(); } } TaskModel taskmodel { get { return ModelCenter.Instance.GetModel(); } } DailyQuestModel dailyQuestModel { get { return ModelCenter.Instance.GetModel(); } } Dictionary equipQualityItemIdTables = new Dictionary() { { 1, 2110 }, { 2, 2111 }, { 3, 2112 }, { 4, 2113 }, { 5, 2114 } }; public Dictionary SuccessBPRedPoint = new Dictionary(); public int[] SuccessBPArray; LogicUpdate logicUpdate = new LogicUpdate(0.4f); public Redpoint redpoint = new Redpoint(201, 20111); public List reachSuccessIDs = new List(); //已达标的成就ID,用于对比变化 #region //修行之路 public event Action OnUpdateBPDataEvent; public int BPCTGID = 117; private int m_selectSuccessType = 0; //记录的是group 不是type public event Action selectSuccessTypeRefresh; public int selectSuccessType { get { return m_selectSuccessType; } set { if (m_selectSuccessType != value) { m_selectSuccessType = value; if (selectSuccessTypeRefresh != null) { selectSuccessTypeRefresh(); } } } } // 修行之路 战令购买 public bool isBuyBP() { VipModel.RechargeCount rechargeCount; if (vipModel.TryGetRechargeCount(BPCTGID, out rechargeCount)) { return rechargeCount.totalCount >= 1; } return false; } #endregion public override void Init() { vipModel.rechargeCountEvent += RechargeCountEvent; ParseAchievementConfig(); InitRedPoint(); logicUpdate.Start(OnUpdate); } private void RechargeCountEvent(int id) { if (id != BPCTGID) { return; } foreach (var succGroup in SuccessBPArray) { foreach (var type in groupToType[succGroup]) { UpdateSuccessBPRedpoint(0, type); } } } public void InitRedPoint() { SuccessBPRedPoint.Clear(); foreach (var succGroup in SuccessBPArray) { //按类型分红点 SuccessBPRedPoint[succGroup] = new Redpoint(20111, 20111*1000 + succGroup); } } public override void UnInit() { vipModel.rechargeCountEvent -= RechargeCountEvent; } List refreshType = new List(); //进度和领取变化 public void UpdateSuccessBPRedpoint(int successID, int successType) { if (successType != 0) { if (refreshType.Contains(successType)) { return; } refreshType.Add(successType); return; } var config = SuccessConfig.Get(successID); if (config == null) return; if (refreshType.Contains(config.Type)) { return; } refreshType.Add(config.Type); return; } public void RefreshSuccessBPRedpoint() { if (refreshType.Count == 0) return; foreach (int successType in refreshType) { if (!typeToGroupBP.ContainsKey(successType)) continue; var group = typeToGroupBP[successType]; if (!SuccessBPRedPoint.ContainsKey(group)) continue; var idList = GetAchievementsByCategory(group); bool state = false; foreach (var successID in idList) { if (!achievements.ContainsKey(successID)) { continue; } if (!Achievement.IsReach(successID, achievements[successID].progress) && !achievements[successID].completed) { continue; } if (!achievements[successID].completed || (isBuyBP() && !achievements[successID].completedBP)) { state = true; break; } } SuccessBPRedPoint[group].state = state == true ? RedPointState.Simple : RedPointState.None; if (selectSuccessType != 0 && group == selectSuccessType) { if (OnUpdateBPDataEvent != null) OnUpdateBPDataEvent(); } } refreshType.Clear(); } private void OnUpdate() { RefreshSuccessBPRedpoint(); } public void OnBeforePlayerDataInitialize() { foreach (var achievement in achievements.Values) { achievement.ResetAchievementState(); } reachSuccessIDs.Clear(); } public void UpdateAchievementProgress(int _achievementId, int _progress) { if (achievements.ContainsKey(_achievementId)) { if (achievements[_achievementId].progress != _progress) { achievements[_achievementId].progress = _progress; if (achievements[_achievementId].completed) { return; } if (achievementProgressUpdateEvent != null) { achievementProgressUpdateEvent(_achievementId); } if (Achievement.IsReach(_achievementId, _progress)) { if (achievementAwardableEvent != null) { achievementAwardableEvent(_achievementId); } if (!reachSuccessIDs.Contains(_achievementId)) reachSuccessIDs.Add(_achievementId); } } } } public bool TryGetAchievement(int _achievementId, out Achievement _achievement) { return achievements.TryGetValue(_achievementId, out _achievement); } public void GetAchievementReward(int _achievementId) { var sendInfo = new CA542_tagMCGetSuccessAward(); sendInfo.SuccID = (uint)_achievementId; GameNetSystem.Instance.SendInfo(sendInfo); } public void UpdateAchievementCompleteState(int _achievementId, bool _completed, bool _completedBP) { Achievement achievement; if (TryGetAchievement(_achievementId, out achievement)) { if (achievement.completed != _completed) { achievement.completed = _completed; if (achievementCompletedEvent != null) { achievementCompletedEvent(_achievementId); } } if (achievement.completedBP != _completedBP) { achievement.completedBP = _completedBP; if (achievementCompletedEvent != null) { achievementCompletedEvent(_achievementId); } } UpdateSuccessBPRedpoint(_achievementId, 0); } } public Dictionary> achievementConditionDict = new Dictionary>(); public bool GetAchievementIdByTypeCondition(int _type, int[] _condition, out List _list) { AchievementCondition condition = new AchievementCondition() { type = _type, condition = _condition, }; return achievementConditionDict.TryGetValue(condition, out _list); } public class AchievementCondition { public int type; public int[] condition; public override bool Equals(object obj) { return this == (AchievementCondition)obj; } public override int GetHashCode() { var _value = type; for (int i = 0; i < condition.Length; i++) { _value += condition[i]; } return _value.GetHashCode(); } public static bool operator ==(AchievementCondition x, AchievementCondition y) { if (x.type != y.type) { return false; } if (x.condition.Length != y.condition.Length) { return false; } for (int i = 0; i < x.condition.Length; i++) { if (x.condition[i] != y.condition[i]) { return false; } } return true; } public static bool operator !=(AchievementCondition x, AchievementCondition y) { return !(x == y); } } public void GotoCompleteByJump(int _jump) { WindowJumpMgr.Instance.WindowJumpTo((JumpUIType)_jump); } public void GotoCompleteAchievement(int _achievementId) { var config = SuccessConfig.Get(_achievementId); if (config == null) { return; } //在这里先处理成就前往之后的一些指引 AchievementGoto.guideAchievementId = 0; AchievementGoto.achievementType = 0; ProcessAchievementGotoGuide(_achievementId); if (config.Jump != 0) { GotoCompleteByJump(config.Jump); } else { switch (config.Type) { case 3: WindowCenter.Instance.Close(); WindowCenter.Instance.Open(); var hasTask = taskmodel.GetQuestState(config.Condition[0]) != -1; if (hasTask) { taskmodel.AutomaticTripToTask(config.Condition[0]); } else { var paramSet = config.Condition2.Split('|'); if (paramSet.Length > 1) { var level = int.Parse(paramSet[1]); if (PlayerDatas.Instance.baseData.LV >= level) { MapTransferUtility.Instance.MoveToNPC(int.Parse(paramSet[0])); } else { SysNotifyMgr.Instance.ShowTip("AchievementLVLimit", level); } } else { MapTransferUtility.Instance.MoveToNPC(int.Parse(config.Condition2)); } } break; case 5: case 29: case 139: if (!FuncOpen.Instance.IsFuncOpen(34)) { var functionConfig = FuncOpenLVConfig.Get(34); FuncOpen.Instance.ProcessorFuncErrorTip(34); } else { var dailyQuestState = dailyQuestModel.GetQuestState((int)DailyQuestType.BountyMission); if (dailyQuestState == DailyQuestModel.DailyQuestState.Completed) { SysNotifyMgr.Instance.ShowTip("Cmwd_CompleteMark"); } else { var mapId = PlayerDatas.Instance.baseData.MapID; var mapConfig = MapConfig.Get(mapId); if (mapConfig != null && mapConfig.MapFBType != 0) { SysNotifyMgr.Instance.ShowTip("InDungeon_CantGo"); } else { taskmodel.DailyBountyMove(); WindowCenter.Instance.Close(); WindowCenter.Instance.Open(); } } } break; case 1: if (PlayerDatas.Instance.baseData.LV < GeneralDefine.achievementEarlierStageLevel) { WindowCenter.Instance.Close(); WindowCenter.Instance.Open(); taskmodel.AutomaticTripToTask(taskmodel.currentMission); } else { ItemTipUtility.Show(2103); } break; case 13: ItemTipUtility.Show(2100); break; case 4: case 86: WindowCenter.Instance.Close(); var mapModel = ModelCenter.Instance.GetModel(); var pointId = mapModel.GetRecommendHangPoint(); var mapEventConfig = MapEventPointConfig.Get(pointId); mapModel.wannaLookLocalMap = mapEventConfig.DataMapID; WindowCenter.Instance.Open(); break; case 36: case 136: WindowCenter.Instance.Close(); WindowCenter.Instance.Open(); MapTransferUtility.Instance.MoveToNPC(config.Condition[0]); break; case 37: WindowCenter.Instance.Close(); WindowCenter.Instance.Open(); MapTransferUtility.Instance.MoveToLocalMapPosition(config.Condition2.Vector3Parse() * 0.5f); break; case 38: var guid = GetHighestSorceEquipByPlace(new List() { config.Condition[0] }); if (string.IsNullOrEmpty(guid)) { ItemTipUtility.Show(2108); } else { playerPack.SetLookIndex(guid); GotoCompleteByJump(144); } break; case 39: var guid39 = GetBetterEquipByPlace(); if (string.IsNullOrEmpty(guid39)) { if (PlayerDatas.Instance.baseData.LV < GeneralDefine.achievementEarlierStageLevel) { WindowCenter.Instance.Close(); WindowCenter.Instance.Open(); taskmodel.AutomaticTripToTask(taskmodel.currentMission); } else { var itemQuality = config.Condition[1]; if (equipQualityItemIdTables.ContainsKey(itemQuality)) { ItemTipUtility.Show(equipQualityItemIdTables[itemQuality]); } else { ItemTipUtility.Show(2108); } } } else { AchievementGoto.guideAchievementId = _achievementId; playerPack.SetLookIndex(guid39); GotoCompleteByJump(144); } break; case 82: var guid82 = GetBetterEquipByPlace(new List() { 3, 4, 5, 6, 7 }); if (string.IsNullOrEmpty(guid82)) { var itemQuality = config.Condition[0]; if (equipQualityItemIdTables.ContainsKey(itemQuality)) { ItemTipUtility.Show(equipQualityItemIdTables[itemQuality]); } else { ItemTipUtility.Show(2108); } } else { AchievementGoto.guideAchievementId = _achievementId; WindowCenter.Instance.Close(); playerPack.SetLookIndex(guid82); WindowCenter.Instance.Close(); WindowCenter.Instance.Open(); } break; case 83: var guid83 = GetBetterEquipByPlace(new List() { 1, 2 }); if (string.IsNullOrEmpty(guid83)) { var itemQuality = config.Condition[0]; if (equipQualityItemIdTables.ContainsKey(itemQuality)) { ItemTipUtility.Show(equipQualityItemIdTables[itemQuality]); } else { ItemTipUtility.Show(2108); } } else { AchievementGoto.guideAchievementId = _achievementId; playerPack.SetLookIndex(guid83); WindowCenter.Instance.Close(); WindowCenter.Instance.Close(); WindowCenter.Instance.Open(); } break; case 84: var guid84 = GetBetterEquipByPlace(new List() { 9, 10 }); if (string.IsNullOrEmpty(guid84)) { var itemQuality = config.Condition[0]; if (equipQualityItemIdTables.ContainsKey(itemQuality)) { ItemTipUtility.Show(equipQualityItemIdTables[itemQuality]); } else { ItemTipUtility.Show(2108); } } else { WindowCenter.Instance.Close(); playerPack.SetLookIndex(guid84); WindowCenter.Instance.Close(); WindowCenter.Instance.Open(); } break; case 85: var guid85 = GetBetterEquipByPlace(new List() { 8 }); if (string.IsNullOrEmpty(guid85)) { var itemQuality = config.Condition[0]; if (equipQualityItemIdTables.ContainsKey(itemQuality)) { ItemTipUtility.Show(equipQualityItemIdTables[itemQuality]); } else { ItemTipUtility.Show(2108); } } else { WindowCenter.Instance.Close(); playerPack.SetLookIndex(guid85); WindowCenter.Instance.Close(); WindowCenter.Instance.Open(); } break; case 90: var guid90 = GetBetterEquipByPlace(new List() { 11 }); if (string.IsNullOrEmpty(guid90)) { ItemTipUtility.Show(2108); } else { WindowCenter.Instance.Close(); playerPack.SetLookIndex(guid90); WindowCenter.Instance.Close(); WindowCenter.Instance.Open(); } break; case 109: WindowCenter.Instance.Close(); var skillId = SkillConfig.FindSkillByJob(config.Condition, PlayerDatas.Instance.baseData.Job); if (skillId != 0) { if (ModelCenter.Instance.GetModel().GetXpSkillID() == skillId) { WindowCenter.Instance.Open(); break; } if (PlayerDatas.Instance.skill.ContainsQuickSkill(skillId) == -1) { WindowCenter.Instance.Open(false, 1); } else { WindowCenter.Instance.Open(); } } break; case 116: ItemTipUtility.Show(config.Condition[0]); break; default: WindowCenter.Instance.Close(); WindowCenter.Instance.Open(); break; } } } //按配表group分组 public List GetAchievementsByCategory(int group) { if (achievementCategorys.ContainsKey(group)) { return new List(achievementCategorys[group]); } else { return null; } } public List GetAchievementsByType(int type) { List allID = new List(); if (!typeToGroup.ContainsKey(type)) { return allID; } foreach (var group in typeToGroup[type]) { allID = allID.Union(new List(achievementCategorys[group])).ToList(); } return allID; } private string GetHighestSorceEquipByPlace(List _places) { var itemPackage = playerPack.GetSinglePack(PackType.Item); var allItems = itemPackage.GetAllItems(); var guid = string.Empty; var score = 0; foreach (var item in allItems.Values) { if (_places.Contains(item.config.EquipPlace)) { if (!ItemLogicUtility.Instance.IsOverdue(item.guid) && (ItemLogicUtility.Instance.IsJobCompatibleItem(item.itemId)) && item.score > score) { guid = item.guid; } } } return guid; } private string GetBetterEquipByPlace(List _places) { var itemPackage = playerPack.GetSinglePack(PackType.Item); var allItems = itemPackage.GetAllItems(); var guid = string.Empty; var score = 0; var equipPackage = playerPack.GetSinglePack(PackType.Equip); foreach (var item in allItems.Values) { var overdue = ItemLogicUtility.Instance.IsOverdue(item.guid); if (!overdue && _places.Contains(item.config.EquipPlace) && ItemLogicUtility.Instance.IsJobCompatibleItem(item.itemId)) { var equipedItem = equipPackage.GetItemByIndex(item.config.EquipPlace); var equipdItemScore = equipedItem == null ? 0 : equipedItem.score; if (item.score > equipdItemScore && item.score > score) { guid = item.guid; } } } return guid; } public string GetBetterEquipByPlace() { var itemPackage = playerPack.GetSinglePack(PackType.Item); var allItems = itemPackage.GetAllItems(); var guid = string.Empty; var score = 0; var equipPackage = playerPack.GetSinglePack(PackType.Equip); foreach (var item in allItems.Values) { var config = ItemConfig.Get(item.itemId); var equipedItem = equipPackage.GetItemByIndex(item.config.EquipPlace); var equipdItemScore = equipedItem == null ? 0 : equipedItem.score; var overdue = ItemLogicUtility.Instance.IsOverdue(item.guid); if (!overdue && (ItemLogicUtility.Instance.IsJobCompatibleItem(item.itemId)) && item.score > equipdItemScore && item.score > score) { score = item.score; guid = item.guid; } } return guid; } private void ProcessAchievementGotoGuide(int _achievementId) { var config = SuccessConfig.Get(_achievementId); switch (config.Type) { case 8: AchievementGoto.Goto8(_achievementId); break; case 16: AchievementGoto.Goto16(_achievementId); break; case 20: AchievementGoto.Goto20(_achievementId); break; case 21: AchievementGoto.Goto21(_achievementId); break; case 31: AchievementGoto.Goto31(_achievementId); break; case 35: AchievementGoto.Goto35(_achievementId); break; case 36: case 136: AchievementGoto.GotoKillNpc(_achievementId); break; case 37: AchievementGoto.GotoExploreMap(_achievementId); break; case 41: AchievementGoto.Goto41(_achievementId); break; case 42: AchievementGoto.GotoRuneTower(_achievementId); break; case 44: AchievementGoto.Goto44(_achievementId); break; case 45: AchievementGoto.Goto45(_achievementId); break; case 46: case 62: AchievementGoto.GotoFairyLand(_achievementId); break; case 7: AchievementGoto.GotoKylin_7(_achievementId); break; case 49: AchievementGoto.GotoKylin_49(_achievementId); break; case 50: AchievementGoto.Goto50(_achievementId); break; case 51: AchievementGoto.Goto3051(_achievementId, config); break; case 52: //AchievementGoto.GotoGetDailyActiveValueAward(_achievementId); break; case 4: case 54: AchievementGoto.GotoTrial(_achievementId); break; case 60: AchievementGoto.Goto60(_achievementId); break; case 61: AchievementGoto.Goto61(_achievementId); break; case 63: case 128: AchievementGoto.GotoNuwa(_achievementId); break; case 66: AchievementGoto.Goto3066(_achievementId, config); break; case 68: AchievementGoto.Goto68(_achievementId); break; case 69: AchievementGoto.Goto3069(_achievementId, config); break; case 79: AchievementGoto.Goto79(_achievementId); break; case 81: AchievementGoto.GotoDungeonInspire(_achievementId); break; case 91: AchievementGoto.GotoSpSkillLevelUp(_achievementId); break; case 92: AchievementGoto.Goto3092(_achievementId, config); break; case 93: AchievementGoto.Goto93(_achievementId); break; case 94: AchievementGoto.Goto3094(_achievementId, config); break; case 95: AchievementGoto.Goto3095(_achievementId, config); break; case 96: AchievementGoto.Goto3096(_achievementId, config); break; case 97: AchievementGoto.Goto3097(_achievementId, config); break; case 99: AchievementGoto.GotoBuyDungeonTimes(_achievementId); break; case 110: AchievementGoto.Goto3110(_achievementId, config); break; case 103: AchievementGoto.Goto103(_achievementId); break; case 104: AchievementGoto.Goto104(_achievementId); break; case 109: AchievementGoto.Goto109(_achievementId); break; case 113: AchievementGoto.Goto113(_achievementId); break; case 114: AchievementGoto.Goto3114(_achievementId, config); break; case 115: AchievementGoto.GotoStove(_achievementId); break; case 10: AchievementGoto.Goto10(_achievementId); break; case 58: AchievementGoto.Goto58(_achievementId); break; case 100: AchievementGoto.Goto100(_achievementId); break; case 106: AchievementGoto.Goto106(_achievementId); break; case 108: AchievementGoto.Goto108(_achievementId); break; case 125: AchievementGoto.GotoIceCrystal(_achievementId); break; case 129: AchievementGoto.Goto3129(_achievementId, config); break; } } private void SortAchievementCategorys() { foreach (var achievementCategory in achievementCategorys) { achievementCategory.Value.Sort(CompareOrder); } } private int CompareOrder(int x, int y) { var xconfig = SuccessConfig.Get(x); var yconfig = SuccessConfig.Get(y); return xconfig.ReOrder.CompareTo(yconfig.ReOrder); } private void ParseAchievementConfig() { var allconfig = SuccessConfig.GetValues(); foreach (var config in allconfig) { UpdateGroupType(config); this.achievements[config.ID] = new Achievement(config); List achievements; if (achievementCategorys.ContainsKey(config.Group)) { achievements = achievementCategorys[config.Group]; } else { achievementCategorys[config.Group] = achievements = new List(); } achievements.Add(config.ID); List _list; var _condition = config.Condition; if (config.Condition.Length == 0) { _condition = new int[1] { 0 }; } AchievementCondition achievementCondition = new AchievementCondition() { type = config.Type, condition = _condition, }; if (achievementConditionDict.ContainsKey(achievementCondition)) { _list = achievementConditionDict[achievementCondition]; } else { achievementConditionDict[achievementCondition] = _list = new List(); } _list.Add(config.ID); } SuccessBPArray = GeneralDefine.GetIntArray("PracticeSuccess"); for (int i = 0; i < SuccessBPArray.Length; i++) { foreach (var type in groupToType[SuccessBPArray[i]]) { typeToGroupBP[type] = SuccessBPArray[i]; } } SortAchievementCategorys(); } //对于表:一个类型可以分不同组别(功能),一个组有多个类型 //对于功能:一个类型只有一个组别,一个组有多个类型 void UpdateGroupType(SuccessConfig config) { if (!groupToType.ContainsKey(config.Group)) { groupToType[config.Group] = new List(); } if (groupToType[config.Group].IndexOf(config.Type) == -1) { groupToType[config.Group].Add(config.Type); } if (!typeToGroup.ContainsKey(config.Type)) { typeToGroup[config.Type] = new List(); } if (typeToGroup[config.Type].IndexOf(config.Group) == -1) { typeToGroup[config.Type].Add(config.Group); } } const string conditionPattern = "@Condition@"; const string needCntPattern = "@NeedCnt@"; const string skillPattern = "@SkillName@"; public static string ParseAchievementDescription(int _achievementId) { var config = SuccessConfig.Get(_achievementId); var description = config.Describe; switch (config.Type) { case 1: description = description.Replace(needCntPattern, config.NeedCnt.ToString()); description = description.Replace(conditionPattern, config.Condition.ToString()); break; case 91: try { var job = PlayerDatas.Instance.baseData.Job; var skillId = 0; skillId = config.Condition[job - 1]; var skillConfig = SkillConfig.Get(skillId); description = description.Replace(skillPattern, skillConfig.SkillName); } catch (Exception ex) { Debug.Log(ex); } break; default: description = description.Replace(needCntPattern, config.NeedCnt.ToString()); description = description.Replace(conditionPattern, config.Condition.ToString()); break; } return description; } //已经购买并领取所有物品 public bool IsFinish() { if (!isBuyBP()) return false; for (int i = 0; i < SuccessBPArray.Length; i++) { int successGroup = SuccessBPArray[i]; var idList = GetAchievementsByCategory(successGroup); if (idList.IsNullOrEmpty()) continue; for (int j = 0; j < idList.Count; j++) { var successID = idList[j]; if (!TryGetAchievement(successID, out var achievement)) return false; if (!achievement.completed) return false; } } return true; } } }