using System; using ProtoCSStruct; using Sog; namespace Game { /// /// 巅峰天赋系统 /// public static class TalentPeakSvc { public static void OnActiveOption(PlayerOnGame player, CSTalentActiveReq req) { ref var res = ref CSTalentActiveRes.Parser.GetMessageClear(); var change = ChapterSvc.CanChangeTalentOrEquip(player); if (!change) { res.Ret = CSErrCode.Fail; player.SendToClient((int)CSGameMsgID.TalentActiveRes, ref res); return; } ref var talentPageData = ref player.RoleData.Talent.PeakData; if (!talentPageData.IsActive) { res.Ret = CSErrCode.Fail; player.SendToClient((int)CSGameMsgID.TalentActiveRes, ref res); return; } var desc = TalentDescMgr.Instance.GetConfig(req.TalentId); if (desc == null) { res.Ret = CSErrCode.Fail; player.SendToClient((int)CSGameMsgID.TalentActiveRes, ref res); return; } if (!TalentHelper.IsCurrentPageTalent(PageIndex.Peak, desc.id)) { res.Ret = CSErrCode.Fail; player.SendToClient((int)CSGameMsgID.TalentActiveRes, ref res); return; } var ret = req.Backup ? Backup(ref talentPageData, req.TalentId) : Active(ref talentPageData, req.TalentId); if (ret != CSErrCode.None) { res.Ret = ret; player.SendToClient((int)CSGameMsgID.TalentActiveRes, ref res); return; } Recalculate(player); player.MakeDirty(); res.PageIndex = (int)PageIndex.Peak; res.Data = talentPageData; res.Ret = ret; player.SendToClient((int)CSGameMsgID.TalentActiveRes, ref res); } private static CSErrCode Backup(ref DbTalentPageData roleData, int descId) { ref var talent = ref roleData.Items; var desc = TalentDescMgr.Instance.GetConfig(descId); if (desc == null) { return CSErrCode.Fail; } var index = -1; for (var t = 0; t < talent.Count; t++) { if (talent[t].Id != descId) continue; index = t; break; } if (index < 0) { return CSErrCode.DescNotFound; } var level = talent[index].Value; if (level == 1) { talent.RemoveAt(index); } else { talent[index].Value -= 1; } return CSErrCode.None; } public static void Active(PlayerOnGame player) { ref var res = ref CSTalentActiveRes.Parser.GetMessageClear(); ref var peakDbTalentPageData = ref player.RoleData.Talent.PeakData; if (peakDbTalentPageData.IsActive) { return; } //普通天赋点数点到一定数量后,激活巅峰天赋 peakDbTalentPageData.IsActive = true; peakDbTalentPageData.Items.Clear(); res.PageIndex = (int)PageIndex.Peak; res.Data = peakDbTalentPageData; res.Ret = CSErrCode.None; player.SendToClient((int)CSGameMsgID.TalentActiveRes, ref res); } private static CSErrCode Active(ref DbTalentPageData talent, int descId) { var desc = TalentDescMgr.Instance.GetConfig(descId); if (!talent.IsActive) { return CSErrCode.Fail; //不可以被激活 不是当前系统页签的天赋,需要激活final类型的 } var index = -1; for (var i = 0; i < talent.Items.Count; i++) { var tempTalentId = talent.Items[i].Id; if (tempTalentId != descId) { continue; } index = i; if (talent.Items[i].Value < desc.Level) { continue; } TraceLog.Error("TalentPeakSvc.PeakActive Talent Level Max talentId={0}", talent.Items[i].Value); return CSErrCode.Fail; //超过最大上限了 } var costIndex = 0; if (index >= 0) { costIndex = talent.Items[index].Value - 1; } var point = desc.LevelPoint[costIndex]; //这一次升级需要的点数 var talentCanUsePoint = GetCanUsePoint(ref talent); if (point != 0 && talentCanUsePoint < point) //需要的点数不够 { TraceLog.Error("TalentPeakSvc.PeakActive Talent point low num={0}", talentCanUsePoint); return CSErrCode.Fail; } if (index != -1) { talent.Items[index].Value++; return CSErrCode.None; } talent.Items.Add(new IDValue32() { Id = desc.id, Value = 1 }); return CSErrCode.None; } public static void Recalculate(PlayerOnGame player) { RolePropUtil.RecalRoleProp(player, true); } public static void CollectProp(ref DBRoleData roleData, RoleProp roleProp) { ref var data = ref roleData.Talent.PeakData; for (var i = 0; i < data.Items.Count; i++) { var id = data.Items[i].Id; var desc = TalentDescMgr.Instance.GetConfig(id); if (desc == null) { TraceLog.Error("TalentPeakSvc.CollectPeakProp desc not found id={0}", id); continue; } roleProp.AddProp(desc.GetPropIdTypeDesc().id, desc.propValue[data.Items[i].Value - 1]); } } private static int GetCanUsePoint(ref DbTalentPageData talentPageData) { var allPoint = talentPageData.Point; var cost = GetAllCostCount(ref talentPageData); return Math.Max(0, allPoint - cost); } private static int GetAllCostCount(ref DbTalentPageData pageData) { var cost = 0; //已消耗的点数 var talents = pageData.Items; for (var i = 0; i < talents.Count; i++) { var id = talents[i].Id; var level = talents[i].Value; var desc = TalentDescMgr.Instance.GetConfig(id); var levelPoint = desc.LevelPoint; for (var j = 0; j < level; j++) { cost += levelPoint[j]; } } return cost; } } }