using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using System.Linq; namespace vnxbqy.UI { public class TalentModel : Model, IPlayerLoginOk, IBeforePlayerDataInitialize { Dictionary talentSkills = new Dictionary(); Dictionary talentTreeDict = new Dictionary(); int m_SelectSeries; public int selectSeries { get { return m_SelectSeries; } set { if (m_SelectSeries != value && selectSeriesEvent != null) { m_SelectSeries = value; selectSeriesEvent(); } m_SelectSeries = value; } } int m_SelectTalentType; public int selectTalentType { get { return m_SelectTalentType; } set { if (m_SelectTalentType != value && selectTalentTypeEvnet != null) { m_SelectTalentType = value; selectTalentTypeEvnet(); } m_SelectTalentType = value; } } int m_SelectSkill; public int selectSkill { get { return m_SelectSkill; } set { if (m_SelectSkill != value && selectSkillEvent != null) { m_SelectSkill = value; selectSkillEvent(); } m_SelectSkill = value; } } bool serverInited = false; public event Action selectTalentTypeEvnet; public event Action selectSeriesEvent; public event Action selectSkillEvent; public event Action talentPointUpdate; public event Action talentSkillUpdate; public event Action talentSkillLevelUp; public override void Init() { ParseConfig(); FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent; PlayerDatas.Instance.playerDataRefreshEvent += PlayerDataRefreshInfoEvent; } public void OnBeforePlayerDataInitialize() { foreach (var talent in talentSkills.Values) { talent.level = 0; } serverInited = false; } public void OnPlayerLoginOk() { serverInited = true; if (WindowCenter.Instance.IsOpen()) { foreach (var talent in talentSkills.Values) { if (talentSkillUpdate != null) { talentSkillUpdate(talent.skillId); } } } UpdateRedpoint(); } public override void UnInit() { FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent; PlayerDatas.Instance.playerDataRefreshEvent -= PlayerDataRefreshInfoEvent; } private void OnFuncStateChangeEvent(int _id) { if (_id == (int)FuncOpenEnum.Talent) { UpdateRedpoint(); } } public int talentResetBook { get; private set; } public int talentResetBookCost { get; private set; } Dictionary> jobTalentTypeDict = new Dictionary>(); void ParseConfig() { var configs = TalentConfig.GetValues(); for (int i = 0; i < configs.Count; i++) { var skillId = configs[i].skillId; var skillConfig = SkillConfig.Get(skillId); TalentSkill talent; if (!TryGetTalent(skillConfig.SkillTypeID, out talent)) { talent = new TalentSkill(skillConfig.SkillTypeID, skillConfig.SkillMaxLV); talent.level = 0; talentSkills.Add(skillConfig.SkillTypeID, talent); TalentTree talentTree; if (!talentTreeDict.TryGetValue(skillConfig.UseType, out talentTree)) { talentTree = new TalentTree(); talentTreeDict.Add(skillConfig.UseType, talentTree); } talentTree.Add(configs[i], skillConfig.SkillTypeID); List list = null; if (!jobTalentTypeDict.TryGetValue(skillConfig.UseType, out list)) { list = new List(); jobTalentTypeDict.Add(skillConfig.UseType, list); } if (!list.Contains(configs[i].type)) { list.Add(configs[i].type); } } } var jobs = jobTalentTypeDict.Keys.ToList(); for (int i = 0; i < jobs.Count; i++) { var list = jobTalentTypeDict[jobs[i]]; list.Sort((x, y) => { return x.CompareTo(y); }); } var config = FuncConfigConfig.Get("TalentResetBook"); talentResetBook = int.Parse(config.Numerical1); talentResetBookCost = int.Parse(config.Numerical2); } public int GetTalentType(int index) { var job = (int)Math.Pow(2, PlayerDatas.Instance.baseData.Job); if (jobTalentTypeDict.ContainsKey(job)) { var list = jobTalentTypeDict[job]; return index < list.Count ? list[index] : list[0]; } return 1; } public int talentTypeCount { get { var job = (int)Math.Pow(2, PlayerDatas.Instance.baseData.Job); if (jobTalentTypeDict.ContainsKey(job)) { var list = jobTalentTypeDict[job]; return list.Count; } return 0; } } public bool TryGetTalents(int job, int talentType, int talentSeries, out List talents) { talents = null; TalentTree talentTree = null; var _job = (int)Math.Pow(2, job); talentTreeDict.TryGetValue(_job, out talentTree); if (null != talentTree) { return talentTree.TryGetTalents(talentType, talentSeries, out talents); } return false; } public bool TryGetTalent(int talentId, out TalentSkill talent) { return talentSkills.TryGetValue(talentId, out talent); } public int GetTalentTypePoint(int talentType) { var point = 0; for (int i = 1; i <= 3; i++) { point += GetSeriesPoint(talentType, i); } return point; } public int GetAllTalentPoint() { var point = 0; var job = (int)Math.Pow(2, PlayerDatas.Instance.baseData.Job); if (jobTalentTypeDict.ContainsKey(job)) { var list = jobTalentTypeDict[job]; for (int i = 0; i < list.Count; i++) { point += GetTalentTypePoint(list[i]); } } return point; } public int GetSeriesPoint(int talentType, int talentSeries) { var job = PlayerDatas.Instance.baseData.Job; List list; var point = 0; if (TryGetTalents(job, talentType, talentSeries, out list)) { for (int i = 0; i < list.Count; i++) { TalentSkill talent; if (TryGetTalent(list[i], out talent)) { point += talent.level; } } } return point; } public bool SatisfyLevelUp(int talentId, out int error) { error = 0; TalentSkill talent; if (TryGetTalent(talentId, out talent)) { if (talent.level >= talent.maxLevel) { error = 1; return false; } if (talentPoint <= 0) { error = 2; return false; } var talentConfig = talent.GetTalentConfig(talent.level + 1); var skillConfig = talent.GetSkillConfig(talent.level + 1); var requireSeriesPoint = skillConfig.RequireTalentSeriesPoint(); if (requireSeriesPoint != 0) { var requireSeries = skillConfig.RequireTalentSeries(); if (GetSeriesPoint(talentConfig.type, requireSeries) < requireSeriesPoint) { error = 3; return false; } } if (skillConfig.LearnSkillReq != 0) { var reqSkillConfig = SkillConfig.Get(skillConfig.LearnSkillReq); if (reqSkillConfig.FuncType == 1) { if (PlayerDatas.Instance.skill.GetSKillById(skillConfig.LearnSkillReq) == null) { error = 6; return false; } } else { TalentSkill learnTalent; if (TryGetTalent(skillConfig.LearnSkillReq, out learnTalent)) { if (learnTalent.level < skillConfig.LearnSkillLV) { error = 4; return false; } } } } var requireProperty = skillConfig.RequireProperty(); if (requireProperty != 0) { var requirePropertyValue = skillConfig.RequirePropertyValue(); if (UIHelper.GetPropertyValue((PropertyType)requireProperty) < (ulong)requirePropertyValue) { error = 5; return false; } } } return true; } public void ProcessLevelUpError(int talentId, int error) { switch (error) { case 1: SysNotifyMgr.Instance.ShowTip("TalentHighestLevel"); break; case 2: SysNotifyMgr.Instance.ShowTip("LackTalentPoint"); break; case 3: SysNotifyMgr.Instance.ShowTip("LackTalentSeriesPoint"); break; case 4: SysNotifyMgr.Instance.ShowTip("PreTalentLevelLimit"); break; case 5: SysNotifyMgr.Instance.ShowTip("TalentRequirePropertyLimit"); break; case 6: TalentSkill talent; if (TryGetTalent(talentId, out talent)) { var skillConfig = talent.GetSkillConfig(); var treasureModel = ModelCenter.Instance.GetModel(); var treasureId = treasureModel.GetTreasureBySkillId(skillConfig.LearnSkillReq); var treasureConfig = TreasureConfig.Get(treasureId); SysNotifyMgr.Instance.ShowTip("PreTreasureSkillLimit", treasureConfig.Name); } break; } } #region 服务端数据 public int talentPoint { get { return PlayerDatas.Instance.extersion.talentPoint; } } private void PlayerDataRefreshInfoEvent(PlayerDataType refreshType) { if (refreshType == PlayerDataType.CDBPlayerRefresh_TalentPoint) { if (talentPointUpdate != null) { talentPointUpdate(); } UpdateRedpoint(); } else if (refreshType == PlayerDataType.STR || refreshType == PlayerDataType.PNE || refreshType == PlayerDataType.PHY || refreshType == PlayerDataType.CON) { UpdateRedpoint(); } } public void UpdateTalentSkill(int _oldSkillId, int _newSkillId) { var config = SkillConfig.Get(_newSkillId); if (config == null) { return; } if (talentSkills.ContainsKey(config.SkillTypeID)) { var talentSkill = talentSkills[config.SkillTypeID]; bool levelUp = talentSkill.level < config.SkillLV; talentSkill.level = config.SkillLV; if (talentSkillUpdate != null) { talentSkillUpdate(config.SkillTypeID); } if (levelUp && serverInited) { if (talentSkillLevelUp != null) { talentSkillLevelUp(config.SkillTypeID); } } } UpdateRedpoint(); } public void DeleteTalentSkill(int _skillId) { var config = SkillConfig.Get(_skillId); if (config == null) { return; } if (talentSkills.ContainsKey(config.SkillTypeID)) { var talentSkill = talentSkills[config.SkillTypeID]; talentSkill.level = 0; if (talentSkillUpdate != null) { talentSkillUpdate(config.SkillTypeID); } } UpdateRedpoint(); } #endregion #region 红点 public Redpoint talentRedpoint = new Redpoint(103, 10303); void UpdateRedpoint() { talentRedpoint.state = RedPointState.None; if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Talent)) { return; } if (talentPoint == 0) { return; } var error = 0; foreach (var talent in talentSkills.Values) { if (SatisfyLevelUp(talent.skillId, out error)) { talentRedpoint.state = RedPointState.Simple; break; } } } #endregion } public class TalentSkill { public int skillId { get; private set; } public int level { get; set; } public int maxLevel { get; private set; } public TalentSkill(int skillId, int maxLevel) { this.skillId = skillId; this.maxLevel = maxLevel; } public SkillConfig GetSkillConfig(int level = 0) { if (level > 0) { return SkillConfig.Get(skillId + level - 1); } else { return SkillConfig.Get(skillId + level); } } public TalentConfig GetTalentConfig(int level = 0) { return TalentConfig.Get(skillId); } } public class TalentSeries { public int series { get; private set; } public List talentSkills { get; private set; } public TalentSeries(int series) { this.series = series; talentSkills = new List(); } public void Add(int skillId) { if (talentSkills.Contains(skillId)) { return; } talentSkills.Add(skillId); } } public class TalentTree { Dictionary> talentSeriesDict = new Dictionary>(); public void Add(TalentConfig config, int skillId) { List list = null; if (!talentSeriesDict.TryGetValue(config.type, out list)) { list = new List(); talentSeriesDict.Add(config.type, list); } TalentSeries talentSeries = list.Find((x) => { return x.series == config.series; }); if (talentSeries == null) { talentSeries = new TalentSeries(config.series); list.Add(talentSeries); } talentSeries.Add(skillId); } public bool TryGetTalents(int type, int series, out List list) { list = null; if (talentSeriesDict.ContainsKey(type)) { var talentSeries = talentSeriesDict[type].Find((x) => { return x.series == series; }); if (talentSeries != null) { list = talentSeries.talentSkills; return true; } } return false; } } public static class TalentHelper { public static int RequireTalentSeries(this SkillConfig config) { if (config == null) { return 0; } return config.LearnSkillPointReq / 10000; } public static int RequireTalentSeriesPoint(this SkillConfig config) { if (config == null) { return 0; } return config.LearnSkillPointReq % 10000; } public static int RequireProperty(this SkillConfig config) { if (config == null) { return 0; } return config.StateSkillLV / 100000; } public static int RequirePropertyValue(this SkillConfig config) { if (config == null) { return 0; } return config.StateSkillLV % 100000; } } }