using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using UnityEngine.UI; using LitJson; namespace vnxbqy.UI { public class SkillModel : Model, IBeforePlayerDataInitialize, IPlayerLoginOk { public override void Init() { ParseConfig(); FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent; TaskModel.Event_TaskInformation += TaskInformationUpdate; } public override void UnInit() { FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent; TaskModel.Event_TaskInformation -= TaskInformationUpdate; } public void OnBeforePlayerDataInitialize() { PlayerDatas.Instance.skill.ClearSkillData(); equipPassSkills.Clear(); playerLoginOk = false; equipPassPage = false; taskHoleCondition = 0; } #region 配置 public const int ACT_SKILL_NUM = 8; public const int PASS_SKILL_TYPE = 2; public const int ACT_SKILL_TYPE = 1; public const int PASS_SKILL_NUM = 12; public const int QUICK_SKILL_COUNT = 8; private Dictionary quickBaseSkillDic = new Dictionary(); private Dictionary xpSkillsDic = new Dictionary(); public List passSkillLimits = new List(); public int passEquipCnt { get; private set; } public Dictionary passEquipGetWays = new Dictionary(); public Dictionary passEquipGetWayTxts; public Dictionary>> skillActDict { get; private set; } public List betterPassSkills { get; private set; } public bool jumpToPass { get; set; } public int minTaskHole { get; private set; } public int maxTaskHole { get; private set; } public bool skillMatchRedpointable { get { return LocalSave.GetBool("SkillMatchRedpointable_" + PlayerDatas.Instance.baseData.PlayerID); } set { LocalSave.SetBool("SkillMatchRedpointable_" + PlayerDatas.Instance.baseData.PlayerID, value); UpdateSkillMatchRedpoint(); } } public readonly Redpoint redpoint = new Redpoint(103, 10301); public readonly Redpoint skillMatchRedpoint = new Redpoint(10301, 1030101); void ParseConfig() { for (int i = 1; i <= 3; i++) { var cfg = FuncConfigConfig.Get(StringUtility.Contact("QuickJobSkill", i)); if (cfg != null) { quickBaseSkillDic.Add(i, ConfigParse.GetMultipleStr(cfg.Numerical1)); } } FuncConfigConfig funcCfg = FuncConfigConfig.Get("XpSkillID"); if (funcCfg != null) { xpSkillsDic = ConfigParse.GetDic(funcCfg.Numerical1); } funcCfg = FuncConfigConfig.Get("PassSkillEquipLimit"); if (funcCfg != null) { JsonData jsonData = JsonMapper.ToObject(funcCfg.Numerical1); foreach (string key in jsonData.Keys) { PassSkillLimit limit = JsonMapper.ToObject(jsonData[key].ToJson()); limit.hole = int.Parse(key); passSkillLimits.Add(limit); if (minTaskHole == 0 && limit.OpenSkillSlots > 0) { minTaskHole = limit.OpenSkillSlots; } if (limit.OpenSkillSlots > maxTaskHole) { maxTaskHole = limit.OpenSkillSlots; } } passEquipCnt = int.Parse(funcCfg.Numerical2); taskHoleDict = ConfigParse.GetDic(funcCfg.Numerical4); } funcCfg = FuncConfigConfig.Get("PassSkillEquipGetWay"); if (funcCfg != null) { JsonData jsonData = JsonMapper.ToObject(funcCfg.Numerical1); foreach (string key in jsonData.Keys) { int[] intarray = JsonMapper.ToObject(jsonData[key].ToJson()); passEquipGetWays.Add(int.Parse(key), intarray); } passEquipGetWayTxts = ConfigParse.GetDic(funcCfg.Numerical2); } funcCfg = FuncConfigConfig.Get("SkillActTypeIdSort"); skillActDict = new Dictionary>>(); var _JobTypeIds = ConfigParse.GetMultipleStr(funcCfg.Numerical1); var _dict = new Dictionary>(); for (int i = 0; i < _JobTypeIds.Length; i++) { var _list = SkillConfig.GetSkills(2, ACT_SKILL_TYPE, _JobTypeIds[i]); if (_list != null) { _dict.Add(_JobTypeIds[i], _list); } } skillActDict.Add(2, _dict); _JobTypeIds = ConfigParse.GetMultipleStr(funcCfg.Numerical2); _dict = new Dictionary>(); for (int i = 0; i < _JobTypeIds.Length; i++) { var _list = SkillConfig.GetSkills(4, ACT_SKILL_TYPE, _JobTypeIds[i]); if (_list != null) { _dict.Add(_JobTypeIds[i], _list); } } skillActDict.Add(4, _dict); _JobTypeIds = ConfigParse.GetMultipleStr(funcCfg.Numerical3); _dict = new Dictionary>(); for (int i = 0; i < _JobTypeIds.Length; i++) { var _list = SkillConfig.GetSkills(8, ACT_SKILL_TYPE, _JobTypeIds[i]); if (_list != null) { _dict.Add(_JobTypeIds[i], _list); } } skillActDict.Add(8, _dict); funcCfg = FuncConfigConfig.Get("SpecialPassSkills"); betterPassSkills = new List(); var _array = ConfigParse.GetMultipleStr(funcCfg.Numerical1); if (_array != null) { betterPassSkills.AddRange(_array); } for (int i = 0; i < passEquipCnt; i++) { passSkillHoleRedpoints.Add(new Redpoint(10302, 10302 * 100 + i)); } } public int[] GetQuickBaseSkillArray(int occupy) { int[] array = null; quickBaseSkillDic.TryGetValue(occupy, out array); return array; } public int GetQuickSkillIdByPos(int pos) { int skillid = 0; PlayerSkillData data = PlayerDatas.Instance.skill.GetQuickSkillByPos(pos); if (data == null) { var intarray = quickBaseSkillDic[PlayerDatas.Instance.baseData.Job]; if (pos < intarray.Length) { skillid = intarray[pos]; } } else { skillid = data.id; } return skillid; } public int GetXpSkillID() { int skillID; xpSkillsDic.TryGetValue(PlayerDatas.Instance.baseData.Job, out skillID); var model = ModelCenter.Instance.GetModel(); TreasureSkill skill; if (model.TryGetSkill(skillID, out skill)) { return skill.GetSkillConfig(skill.level).SkillID; } return skillID; } public bool IsXpSkill(int skillId) { var config = SkillConfig.Get(skillId); if (config != null) { var job = PlayerDatas.Instance.baseData.Job; if (xpSkillsDic.ContainsKey(job)) { return xpSkillsDic[job] == config.SkillTypeID; } } return false; } void VerifyQuickSkillExistXp() { var quickSkills = PlayerDatas.Instance.skill.GetQuickSkills(); var existXp = false; var lastIndex = 0; foreach (var index in quickSkills.Keys) { if (quickSkills[index] != null) { if (IsXpSkill(quickSkills[index].id)) { existXp = true; QuickSetting.Instance.SetQuickSetting(QuickSetting.QuickSettingType.Skill, "***", index); continue; } if (existXp) { var temp = QuickSetting.Instance.GetQuickSetting(QuickSetting.QuickSettingType.Skill, index); QuickSetting.Instance.SetQuickSetting(QuickSetting.QuickSettingType.Skill, temp, index - 1); QuickSetting.Instance.SetQuickSetting(QuickSetting.QuickSettingType.Skill, "***", index); } lastIndex = index; } } if (existXp) { if (lastIndex == QUICK_SKILL_COUNT - 1) { var skills = GetActSkills(); for (int i = 0; i < skills.Count; i++) { if (PlayerDatas.Instance.skill.GetSKillById(skills[i]) != null && !IsXpSkill(skills[i]) && PlayerDatas.Instance.skill.ContainsQuickSkill(skills[i]) == -1) { string value = MathUtils.Convert10To64(skills[i]); QuickSetting.Instance.SetQuickSetting(QuickSetting.QuickSettingType.Skill, value, lastIndex); break; } } } QuickSetting.Instance.SendPackage(); PlayerDatas.Instance.skill.SetQuickSkills(); } } List GetActSkills() { List skills = new List(); var skillType = (int)Math.Pow(2, PlayerDatas.Instance.baseData.Job); Dictionary> dict = skillActDict[skillType]; foreach (int key in dict.Keys) { List list = dict[key]; var skillId = list[0]; foreach (var id in list) { if (PlayerDatas.Instance.skill.GetSKillById(id) != null) { skillId = id; break; } } if (PlayerDatas.Instance.skill.GetFilterPlayerSkill(PlayerDatas.Instance.baseData.Job).Contains(skillId)) { continue; } skills.Add(skillId); } return skills; } #endregion #region 主动技能 public int presentSltSkillID = 0; public event Action OnRefreshSltSkill; public void RefreshSltSkill() { if (OnRefreshSltSkill != null) OnRefreshSltSkill(); } public bool skillDraging = false; public int skillDragId = 0; public float onDragDelay = 0.1f; private Skill m_XpSkill; public Skill xpSkill { get { return m_XpSkill ?? (m_XpSkill = PlayerDatas.Instance.hero.SkillMgr.Get(GetXpSkillID())); } } public event Action OnAutoUseXpEvent; public bool AutoUseXp() { return QuickSetting.Instance.GetQuickSettingBool(QuickSetting.QuickSettingType.AutoUseXp, 0, true); } public void SetAutoUseXp(bool _auto) { if (_auto != AutoUseXp()) { QuickSetting.Instance.SetQuickSetting(QuickSetting.QuickSettingType.AutoUseXp, _auto); QuickSetting.Instance.SendPackage(); if (OnAutoUseXpEvent != null) { OnAutoUseXpEvent(); } } } #endregion #region 被动技能 public int presentSltPage = 0; public int presentEquipPage { get; private set; } public bool playerLoginOk = false; private Dictionary> equipPassSkills = new Dictionary>(); public Dictionary taskHoleDict { get; private set; } public event Action UpdatePassEquipSkillEvent; public bool equipPassPage { get; set; } public bool TryGetEquipPassSkills(int page, int hole, out int _skillId) { _skillId = 0; if (equipPassSkills.ContainsKey(page)) { Dictionary dic = equipPassSkills[page]; if (dic.ContainsKey(hole)) { _skillId = dic[hole]; if (_skillId != 0) { return true; } } } return false; } public void SendEquipPassSkills(int _skillId, int _hole) { PlayerSkillData data = PlayerDatas.Instance.skill.GetSKillById(_skillId); if (data != null && data.skillCfg.FuncType == PASS_SKILL_TYPE) { Dictionary dic = null; if (equipPassSkills.TryGetValue(presentSltPage, out dic)) { int _preHole = -1; if (dic.ContainsKey(_hole) && dic[_hole] == _skillId) { return; } foreach (var _key in dic.Keys) { if (_skillId == dic[_key] && (!dic.ContainsKey(_hole) || dic[_hole] == 0)) { _preHole = _key; break; } else if (_skillId == dic[_key]) { SysNotifyMgr.Instance.ShowTip("PassSkillSameError"); return; } } if (_preHole != -1) { SendEquipPassSkill(presentSltPage, _preHole, 0); } } int _skill = 0; if (TryGetEquipPassSkills(presentSltPage, _hole, out _skill) && betterPassSkills.Contains(_skill)) { ConfirmCancel.ShowPopConfirm(Language.Get("TeamPrepare1"), Language.Get("ReBetterSkill"), (bool isOk) => { if (isOk) { SoundPlayer.Instance.PlayUIAudio(28); SendEquipPassSkill(presentSltPage, _hole, _skillId); } }); } else { SoundPlayer.Instance.PlayUIAudio(28); SendEquipPassSkill(presentSltPage, _hole, _skillId); } } } public event Action taskUnlockUpdate; public uint taskHoleCondition { get; private set; } public const string TASKHOLEKEY = "OpenSkillSlots"; public int UnlockPassHole { get { return LocalSave.GetInt(StringUtility.Contact(TASKHOLEKEY, "_", PlayerDatas.Instance.baseData.PlayerID)); } set { LocalSave.SetInt(StringUtility.Contact(TASKHOLEKEY, "_", PlayerDatas.Instance.baseData.PlayerID), value); } } public bool IsTaskHoleUnlock(int condition) { if (task._DicTaskInformation.ContainsKey(1) && task._DicTaskInformation[1].ContainsKey(TASKHOLEKEY)) { uint value = 0; uint.TryParse(task._DicTaskInformation[1][TASKHOLEKEY], out value); return MathUtility.GetBitValue(value, (ushort)condition); //return value >= condition; } return false; } private void TaskInformationUpdate(int _id, Dictionary> _Dic) { if (_Dic != null && _Dic.ContainsKey(1)) { var dict = _Dic[1]; if (dict.ContainsKey(TASKHOLEKEY)) { uint result = 0; uint.TryParse(dict[TASKHOLEKEY], out result); if (playerLoginOk) { for (int k = minTaskHole; k <= maxTaskHole; k++) { if (!MathUtility.GetBitValue(taskHoleCondition, (ushort)k) && MathUtility.GetBitValue(result, (ushort)k)) { UnlockPassHole = k; } } if (taskUnlockUpdate != null) { taskUnlockUpdate(); } } taskHoleCondition = result; } } //UpdateTaskHoleRedpoint(); } RolePromoteModel m_PromoteModel; RolePromoteModel promoteModel { get { return m_PromoteModel ?? (m_PromoteModel = ModelCenter.Instance.GetModel()); } } TaskModel task { get { return ModelCenter.Instance.GetModel(); } } PlayerMainDate mainData { get { return ModelCenter.Instance.GetModel(); } } public void SendEquipPassSkill(int _page, int _index, int _skillId) { var pak = new CB407_tagCMPassiveSet(); pak.Page = (byte)_page; pak.Index = (byte)_index; pak.SkillID = (uint)_skillId; GameNetSystem.Instance.SendInfo(pak); } public void SendEquipPage() { if (presentSltPage == presentEquipPage) { return; } equipPassPage = true; CB408_tagCMPassivePage pak = new CB408_tagCMPassivePage(); pak.Page = (byte)presentSltPage; GameNetSystem.Instance.SendInfo(pak); } public bool IsPassSkillHoleOpen(int _hole) { PassSkillLimit limit; if (TryGetPassSkillLimit(_hole, out limit)) { if (limit.level > 0) { if (PlayerDatas.Instance.baseData.LV < limit.level) { return false; } } else if (limit.vipLv > 0) { if (PlayerDatas.Instance.baseData.VIPLv < limit.vipLv) { return false; } } else if (limit.MountLv > 0) { if (promoteModel.GetMountTotallv() < limit.MountLv) { return false; } } else if (limit.OpenSkillSlots > 0) { if (!IsTaskHoleUnlock(limit.OpenSkillSlots)) { return false; } } return true; } return false; } public int PassOpenHoleCount() { var count = 0; for (int i = 0; i < passEquipCnt; i++) { if (IsPassSkillHoleOpen(i)) { count++; } } return count; } public bool TryGetPassSkillLimit(int _hole, out PassSkillLimit _limit) { _limit = default(PassSkillLimit); int index = passSkillLimits.FindIndex((x) => { return x.hole == _hole; }); if (index == -1) { return false; } _limit = passSkillLimits[index]; return true; } public void UpdateEquipPassSkills(HB406_tagMCPassiveSet package) { if (package.PageCnt == 0) { return; } for (int i = 0; i < package.PassiveSkills.Length; i++) { if (package.PassiveSkills[i].Count == 0) { continue; } for (int j = 0; j < package.PassiveSkills[i].Count; j++) { SetEquipPassSkill(i, j, (int)package.PassiveSkills[i].SkillIDList[j]); } } if (UpdatePassEquipSkillEvent != null) { UpdatePassEquipSkillEvent(); } UpdateRedpoint(); } public void UpdateEquipPassPage(HB407_tagMCPassivePage package) { presentEquipPage = package.Page; if (equipPassPage) { SysNotifyMgr.Instance.ShowTip("SetPassEquipPageSuccess", presentEquipPage + 1); } equipPassPage = false; UpdateRedpoint(); } public void UpdateEquipPassSkill(HB408_tagMCPassiveSetAnswer package) { SetEquipPassSkill(package.Page, package.Index, (int)package.SkillID); if (UpdatePassEquipSkillEvent != null) { UpdatePassEquipSkillEvent(); } } public void SetEquipPassSkill(int _page, int _index, int _skillId) { Dictionary dic = null; if (!equipPassSkills.TryGetValue(_page, out dic)) { dic = new Dictionary(); equipPassSkills.Add(_page, dic); } dic[_index] = _skillId; } public void OnPlayerLoginOk() { if (GetEquipPassSkillCnt() == 0) { Dictionary playerskills = PlayerDatas.Instance.skill.GetAllSkill(); var _cnt = 0; presentSltPage = 0; foreach (var _skill in playerskills.Values) { if (_cnt >= 2) { break; } if (_skill.skillCfg.FuncType == PASS_SKILL_TYPE) { SendEquipPassSkills(_skill.id, _cnt); _cnt++; } } } playerLoginOk = true; UpdateRedpoint(); //VerifyQuickSkillExistXp(); UpdateSkillMatchRedpoint(); //UpdateTaskHoleRedpoint(); } public void CheckEquipPassSkill(PlayerSkillData _skill) { if (!playerLoginOk) { return; } if (_skill.skillCfg.FuncType != PASS_SKILL_TYPE) { return; } var _cnt = GetEquipPassSkillCnt(); if (_cnt < 2) { for (int i = 0; i < passEquipCnt; i++) { var _id = 0; if (!TryGetEquipPassSkills(0, i, out _id)) { SendEquipPassSkills(_skill.id, i); break; } } } } public bool ContainsEquipPassSkill(int _skillId) { foreach (var _dict in equipPassSkills.Values) { foreach (var _id in _dict.Values) { if (_skillId == _id) { return true; } } } return false; } public int GetEquipPassSkillCnt() { var _totalCnt = 0; foreach (var _dict in equipPassSkills.Values) { foreach (var _id in _dict.Values) { if (_id != 0) { _totalCnt += 1; } } } return _totalCnt; } public int GetEquipPassSkillCount(int _page) { if (!equipPassSkills.ContainsKey(_page)) { return 0; } var _dict = equipPassSkills[_page]; var count = 0; foreach (var _id in _dict.Values) { if (_id != 0) { count += 1; } } return count; } #endregion #region 红点 public Redpoint skillRedpoint = new Redpoint(1, 103); //public Redpoint passSkillRedpoint = new Redpoint(103, 10302); public List passSkillHoleRedpoints = new List(); void UpdateRedpoint() { //for (int i = 0; i < passSkillHoleRedpoints.Count; i++) //{ // passSkillHoleRedpoints[i].state = RedPointState.None; //} //if (!FuncOpen.Instance.IsFuncOpen(109)) //{ // return; //} //if (DayRemind.Instance.GetDayRemind(DayRemind.PASS_SKILL_REDPOINT)) //{ // return; //} //var _count = GetEquipPassSkillCount(presentEquipPage); //if (PlayerDatas.Instance.skill.GetSkillCountByType(PASS_SKILL_TYPE) > _count // && PassOpenHoleCount() > _count) //{ // for (int i = 0; i < passEquipCnt; i++) // { // var _skillId = 0; // if (!TryGetEquipPassSkills(presentEquipPage, i, out _skillId) // && IsPassSkillHoleOpen(i)) // { // passSkillHoleRedpoints[i].state = RedPointState.Simple; // return; // } // } //} } void UpdateSkillMatchRedpoint() { skillMatchRedpoint.state = skillMatchRedpointable ? RedPointState.Simple : RedPointState.None; } public void SetDayRemind() { //DayRemind.Instance.SetDayRemind(DayRemind.PASS_SKILL_REDPOINT, true); UpdateRedpoint(); } //public Redpoint taskHoleRedpoint = new Redpoint(10302, 1030299); //void UpdateTaskHoleRedpoint() //{ // taskHoleRedpoint.state = RedPointState.None; // if (DayRemind.Instance.GetDayRemind(DayRemind.TASK_SKILL_HOLE)) // { // return; // } // foreach (var hole in taskHoleDict.Keys) // { // var taskId = taskHoleDict[hole]; // if (IsImmediatelyUnlock(hole)) // { // var config = PyTaskConfig.Get(taskId); // if (PlayerDatas.Instance.baseData.LV >= config.lv // && !IsTaskHoleUnlock(hole)) // { // taskHoleRedpoint.state = RedPointState.Simple; // } // return; // } // } //} public bool IsImmediatelyUnlock(int hole) { if (taskHoleDict.ContainsKey(hole)) { var taskId = taskHoleDict[hole]; return mainData.TaskId_Skill.Contains(taskId); } return false; } public void SetTaskHoleRemind() { DayRemind.Instance.SetDayRemind(DayRemind.TASK_SKILL_HOLE, true); //UpdateTaskHoleRedpoint(); } #endregion private void OnFuncStateChangeEvent(int _id) { if (_id == 109) { UpdateRedpoint(); //UpdateTaskHoleRedpoint(); } } public event Action onSkillMatchPageUpdate; public void OnSkillMatchPageUpdate() { if (onSkillMatchPageUpdate != null) { onSkillMatchPageUpdate(); } } public List GetSkillMatchs() { return SkillMatchModel.Instance.GetSkills(); } } public struct PassSkillLimit { public int hole; public int level; public int vipLv; public int MountLv; public int OpenSkillSlots; } [Serializable] public class SkillData { [HideInInspector] public int skillId; [HideInInspector] public SkillConfig skillCfg; public Image m_LockImg; public Image m_SelectImg; public Button m_SkillBtn; public Text m_SkillNameTxt; [SerializeField] Image m_BottomImg; [SerializeField] Image m_SkillIcon; [SerializeField] Text m_SkillSourceTxt; public void SetSkillData(int _id) { this.skillId = _id; if (skillId == 0) { m_SkillIcon.SetActive(false); return; } m_SkillIcon.SetActive(true); skillCfg = SkillConfig.Get(_id); m_SkillIcon.SetSprite(skillCfg.IconName); if (m_SkillNameTxt != null) { m_SkillNameTxt.text = skillCfg.SkillName; } if (m_SkillSourceTxt != null) { m_SkillSourceTxt.text = skillCfg.Skillsource; } } public void SetActive(bool _active) { m_SkillIcon.material = _active ? MaterialUtility.GetUIDefaultGraphicMaterial() : MaterialUtility.GetDefaultSpriteGrayMaterial(); if (m_BottomImg != null) { m_BottomImg.material = _active ? MaterialUtility.GetUIDefaultGraphicMaterial() : MaterialUtility.GetDefaultSpriteGrayMaterial(); } } } public interface ISkillMatch { List GetSkills(); event Action onSkillMatchPageUpdate; } }