using CommonAI.data; using CommonAI.Data; using CommonAI.Zone; using CommonAI.Zone.Helper; using CommonAI.Zone.Instance; using CommonAI.ZoneClient; using CommonAI.ZoneServer.JSGModule; using CommonLang; using System; using System.Collections.Generic; using System.Linq; using System.Text; using XmdsCommon.EditorData; using XmdsCommon.JSGModule.Interface; using XmdsCommon.Plugin; using XmdsCommonServer.Message; using XmdsCommonServer.Plugin.Base; using XmdsCommonServer.Plugin.Units; using XmdsCommonServer.Plugin.XmdsSkillTemplate; using XmdsCommonServer.Plugin.XmdsSkillTemplate.DamageCalculator; using XmdsCommonServer.Plugin.XmdsSkillTemplate.Skills; using XmdsCommonServer.XLS.Data; using XmdsCommonSkill.Plugin.CardSkill; using static CommonAI.Zone.Instance.InstanceUnit; namespace XmdsCommonServer.Plugin { /// /// FileName: XmdsVirtual.cs /// Author: Alex.Yu /// Corporation:... /// Description: /// DateTime: 2015/5/12 10:20:46 /// public partial class XmdsVirtual { //技能初始化辅助类. protected XmdsSkillHelper mSkillHelper = null; /// /// 初始化技能辅助类. /// public XmdsSkillHelper SkillHelper { get { return mSkillHelper; } } //卡牌技能类 private IJSCardSkillModule mCardModule; //玩家本地缓存数据 private IPlayerCache mPlayerCache; public IJSCardSkillModule CardModule { get { return mCardModule; } } private HashMap mTrySendBuff = new HashMap(); private HashMap mTrySendSpell = new HashMap(); private HashMap mLaunchSpellOver = new HashMap(); //扩展字段 //法师:标记剑影是否强化过 public int extValue = 0; #region 技能相关. private void ReGetUnitSkills(List ls, List retList) { GameSkill gs = null; for (int i = ls.Count - 1; i >= 0; i--) { gs = ls[i]; if (gs.SkillID == 0) { ls.RemoveAt(i); } else if (this.IsPlayerUnit() || getSkillType(ref gs))//玩家的技能来自游戏服,不管表格类型 { retList.Add(gs); } } } private void CreateCreateCardModule() { // if (this.mCardModule == null) // { // if (this.mUnit.IsPlayer) // { // this.mCardModule = XmdsGlobalData.GetPlayerCardModule(this); // } // else if (this.mUnit.IsMonster && this.IsBoss()) // { // this.mCardModule = new JSGMonsterCardModule(this); // } // else // { // this.mCardModule = new JSGOtherCardModule(); // } // } } public void InitCardModule() { // this.mCardModule.Init(this); // // if(this.mUnit.VisibleInfo != null) // { // this.mUnit.VisibleInfo.setVisibleCardData(this.mCardModule.GetCardInterface()); // } } protected void checkSkillData(XmdsUnitData data) { //过滤data 防止无效的gameSkill. List retList = new List(); // 常规技能 if (data.Skills != null && data.Skills.UnitSkills != null) { this.ReGetUnitSkills(data.Skills.UnitSkills, retList); } // 卡牌技能 if(data.CardSkills != null && data.CardSkills.UnitSkills != null) { this.ReGetUnitSkills(data.CardSkills.UnitSkills, retList); } #region Mock数据. GameSkill gs = null; //如果为空判断为编辑器环境,走MOCK数据. //if (data.Skills == null || data.Skills.UnitSkills == null || data.Skills.UnitSkills.Count == 0) { //单位普攻. if (mInfo.BaseSkillID != null && mInfo.BaseSkillID.SkillID != 0) { gs = new GameSkill(); gs.SkillID = this.mInfo.BaseSkillID.SkillID; gs.SkillType = XmdsSkillType.normalAtk; gs.SkillLevel = 1; retList.Add(gs); } //单位技能. for (int i = 0; i < this.mInfo.Skills.Count; i++) { gs = new GameSkill(); gs.SkillID = this.mInfo.Skills[i].SkillID; gs.SkillLevel = 1; if (getSkillType(ref gs)) { retList.Add(gs); } } if (data.Skills == null) { XmdsUnitSkillInfo info = new XmdsUnitSkillInfo(); info.UnitSkills = retList; data.Skills = info; } else { data.Skills.UnitSkills = retList; } } #endregion if (mSkillHelper == null) { mSkillHelper = new XmdsSkillHelper(); } } private bool getSkillType(ref GameSkill gs) { XmdsSkillData skillData = XmdsDataMgr.GetInstance().GetXmdsSkillData(gs.SkillID); if (skillData != null && skillData.SkillType > 0) { gs.SkillType = (XmdsSkillType)skillData.SkillType; return true; } else { SkillTemplate st = XmdsBattleSkill.GetSkillTemplate(gs.SkillID); if (st != null) { gs.SkillType = (st.Properties as XmdsSkillProperties).SkillType; return true; } else { log.Warn("checkSkillData 找不到单位:" + this.mUnit.Info.ID + ", 技能ID: " + gs.SkillID); } } return false; } //重新调用一下基础技能的initOver public bool ReInitOverBaseSkill(GameSkill info) { AbstractSkill baseSkill = this.SkillHelper.GetPlayerSkillById(this.SkillHelper.GetBaseSkillID()); if (baseSkill == null) { log.Error("找不到单位基础技能:" + this.mUnit.PlayerUUID + ", 技能初始化:" + info.SkillID + ", 基础技能: " + this.SkillHelper.GetBaseSkillID()); return false; } // 借用一下这个接口,懒得写新的了 baseSkill.InitOver(this, info); return true; } //初始化技能. protected virtual void InitSkillInfo(XmdsUnitData data) { this.checkSkillData(data); mFinishSkillInit = true; mSkillHelper.InitSkill(data.Skills, this); } public bool ChangeSkill(int oldSkillID, int newSkillID, SkillLevelData skillData) { try {// 同技能只改表数值的话,无需重新init,赋值 if (oldSkillID == newSkillID) { GameSkill gs = this.SkillHelper.GetGameSkill(newSkillID); if (gs == null) { log.Warn("相同技能替换,更新数值,技能不存在: " + newSkillID + ", " + this.mUnit.PlayerUUID); return false; } gs.SkillLevel = skillData.SkillLevel; gs.TalentSkillLevel1 = skillData.TalentSkillLevel1; gs.TalentSkillLevel2 = skillData.TalentSkillLevel2; gs.TalentSkillLevel3 = skillData.TalentSkillLevel3; if (gs.SkillType == XmdsSkillType.passive || gs.SkillType == XmdsSkillType.petGivePassive) { UnitPassiveSkill skill = this.mSkillHelper.GetPlayerSkillByIdExt(newSkillID); skill.SkillDataChange(gs, this); } else { UnitSkill skill = this.mSkillHelper.GetPlayerSkillById(newSkillID); skill.SkillDataChange(gs, this); } } else { GameSkill oldSkill = null; long skillCD = 0; if (oldSkillID > 0) { skillCD = this.GetSkillTimestampMS(oldSkillID); oldSkill = this.RemoveSkill(oldSkillID); } if (newSkillID > 0) { //激活指定技能. GameSkill gs = gs = new GameSkill(); gs.SkillID = newSkillID; gs.SkillType = skillData.skillType; gs.SkillLevel = skillData.SkillLevel; gs.TalentSkillLevel1 = skillData.TalentSkillLevel1; gs.TalentSkillLevel2 = skillData.TalentSkillLevel2; gs.TalentSkillLevel3 = skillData.TalentSkillLevel3; gs.SkillTimestampMS = skillCD; gs.AutoLaunch = gs.SkillType != XmdsSkillType.cardSkill; if (gs.SkillType == XmdsSkillType.passive || gs.SkillType == XmdsSkillType.petGivePassive) { AbstractSkill skill = this.mSkillHelper.AddPassiveSkill(gs); } else { AbstractSkill skill = this.mSkillHelper.AddActiveSkill(gs, gs.SkillType == XmdsSkillType.normalAtk); // if (gs.SkillType == XmdsSkillType.cardSkill && this.CardModule != null) // { // //this.CardModule.InitSkill // } } //if (skillCD > 0) //{ // SkillState skillState = this.SetSkillCD(newSkillID, skillCD); // if (skillState != null) // { // skillState.Reset(); // } //} } } } catch (Exception e) { log.Warn("ChangeSkill catch: " + oldSkillID + ", " + newSkillID + ", " + e); } return true; } private void UpdateSkillHelper(int intervalMS, bool slowRefresh) { if (mSkillHelper != null) { mSkillHelper.Update(intervalMS, slowRefresh); } } #endregion public bool AllowAutoLaunch(int skillid) { bool ret = false; if (mSkillHelper != null) { var gs = mSkillHelper.GetGameSkill(skillid); if (gs != null) { ret = gs.AutoLaunch; } } return ret; } public bool TryLaunchSpell(LaunchSpell launch, ref SpellTemplate spell, out JSGCreateSpellData createData, ref float startX, ref float startY) { SpellTemplate redirect; if (mTrySendSpell.TryGetValue(spell.ID, out redirect)) { spell = redirect; } DispatchTrySendSpellEvent(launch, ref spell, out createData, ref startX, ref startY); return true; } public bool TrySendBuff(ref BuffTemplate buff, XmdsVirtual target, out object tag) { //无敌中,负面BUFF无效. if (target.IsInvincible && buff.IsHarmful == true) { target.SendBattleHintNumberB2C(0, XmdsVirtual.UnitHitEventState.Immunity); tag = null; return false; } bool ret = true; tag = null; if (buff.IsHarmful == true) { //给别人施加debuff. this.OnHitOthter(target); } //无敌时不受负面BUFF影响. //if (target.mUnit.IsInvincible && buff.IsHarmful == true) //{ // ret = false; //} if (ret == true) { //重定向buff. BuffTemplate redirect; if (mTrySendBuff.TryGetValue(buff.ID, out redirect)) { buff = redirect; } var temp = buff.Properties as XmdsBuffProperties; List list = temp.GetBuffVirtualList(); //克隆BUFF能力. if (list != null && list.Count > 0) { List cList = new List(); Type ctype = null; UnitBuff dst = null; UnitBuff src = null; for (int i = 0; i < list.Count; i++) { src = list[i] as UnitBuff; ctype = src.GetType(); dst = CommonLang.Property.ReflectionUtil.CreateInstance(ctype) as UnitBuff; src.CopyTo(dst); cList.Add(dst); } tag = cList; } //判断能否添加. target.DispatchTryAddBuffEvent(ref buff, target, ref ret); } return ret; } public void SendAddBuffEvent(XmdsVirtual hitter, BuffTemplate buff) { //this.DispatchSendBuffEvent(buff, hitter); } public void RegistSendBuff(BuffTemplate buff) { //if(mTrySendBuff.ContainsKey(buff.ID)) //{ // FormatLog(CommonLang.Log.LoggerLevel.ERROR, "RegistSendBuff 重复利用buff : {0}, {1}", this.mInfo.Name, buff.ID); //} mTrySendBuff.Put(buff.ID, buff); } public void RegistSendSpell(SpellTemplate spell) { mTrySendSpell.Put(spell.ID, spell); } public BuffTemplate GetRegistBuff(int id) { BuffTemplate ret = null; if (mTrySendBuff.TryGetValue(id, out ret)) { return ret; } return null; } public UnitBuff GetRegisBuffVirtual(int id, int index = 0) { if (index < 0) return null; UnitBuff ret = null; BuffTemplate bt = GetRegistBuff(id); XmdsBuffVirtual zbv = null; if (bt != null) { List list = (bt.Properties as XmdsBuffProperties).GetBuffVirtualList(); if (list != null && index < list.Count) { zbv = list[index]; if (zbv != null) { ret = zbv as UnitBuff; } } } return ret; } /// /// 判断是否可放技能. /// /// /// public virtual bool TryLaunchSkill(InstanceUnit.SkillState skill, ref InstanceUnit.LaunchSkillParam param) { #region if (!this.mUnit.IsCanLaunchSkill(skill.ID)) { SendMsgToClient(CommonAI.XmdsConstConfig.TIPS_CAN_NOT_USE_SKILL); return false; } if (this.mUnit.IsCannotMove && skill.Data.ActionPriority < 0) { SendMsgToClient(CommonAI.XmdsConstConfig.CANNOT_LAUNCH_DISPACEMENTSKILL); return false; } //需要的能量是否足够(战士某些技能需要怒气) if(!this.LaunchSkillCheckTalentInfo(skill)) { return false; } #endregion #region 普攻不能取消普攻. //TODO 屏蔽普攻不能取消普攻. /* if (this.mUnit.CurrentState is InstanceUnit.StateSkill) { if ((this.mUnit.CurrentState as InstanceUnit.StateSkill).SkillData.ID == skill.ID) { if (skill.Data.IsManuallyCancelable == false) { return false; } else { //直接交由skillstate.tryluanch判断. return true; } } } */ #endregion //坐骑状态检查,如果是坐骑状态,主动切换骑乘. MountOnLaunchSkillCheck(); bool ret = false; //XmdsSkillProperties prop = (XmdsSkillProperties)skill.Data.Properties; //if (prop.IsRandomNormalAttack) //{ // skill.SetAutoIncreaseActionIndex(false); // byte k = (byte)(this.mUnit.RandomN.Next(0, skill.Data.ActionQueue.Count)); // skill.SetActionIndex(k); //} DispatchTryLaunchSkillEvent(ref skill, ref ret, ref param); // 存储多段式技能判定 if (ret && skill.CanStoreTimes) { ret = skill.OveryLayer > 0; } return ret; } /** 检测技能天赋信息 */ public bool LaunchSkillCheckTalentInfo(InstanceUnit.SkillState skill) { //需要的能量是否足够(战士某些技能需要怒气) if (this.mUnit.IsPlayer && skill.ActionIndex == -1 && (this.GetUnitPro() == XmdsUnitPro.Sword || this.GetUnitPro() == XmdsUnitPro.Magic)) { XmdsSkillValue data = XmdsGlobalData.GetTalentData(skill.Data.ID); if (data != null) { //天赋值 if (data.GetValue(1) > 0 && this.Talent_Value() < data.GetValue(1)) { return false; } //天赋等级 if (!data.IsSingleCfg() && data.GetValue(2) > 0 && this.Talent_Lv() < data.GetValue(2)) { return false; } } } return true; } #region 技能监听回调. //技能成功施放回调. private long mPreLaunchTime; private void OnLaunchSkillHandler(InstanceUnit obj, CommonAI.Zone.Instance.InstanceUnit.SkillState skill) { XmdsSkillProperties skillProp = skill.Data.Properties as XmdsSkillProperties; //增加Buff判断,部分buff效果可使技能使用效果发生变更. DispatchLaunchsSkillOverEvent(this, skill); //天赋点扣除 if (this.mUnit.IsPlayer && skill.ActionIndex <= 0 && (this.GetUnitPro() == XmdsUnitPro.Sword || this.GetUnitPro() == XmdsUnitPro.Magic)) { XmdsSkillValue data = XmdsGlobalData.GetTalentData(skill.Data.ID); if (data != null && data.GetValue() > 0) { if (!this.Talent_Use(data.GetValue())) { long timePass = System.DateTime.Now.Ticks - mPreLaunchTime; log.Warn("天赋扣除异常:" + this.mUnit.PlayerUUID + ", SceneID: " + this.mUnit.Parent.GetSceneID() + ", " + timePass); } } } //能量扣除. //mUnit.AddMP(-cost); mPreLaunchTime = System.DateTime.Now.Ticks; } //回调增加技能. private void OnSkillAddHandler(InstanceUnit unit, CommonAI.Zone.Instance.InstanceUnit.SkillState sk) { } //回调移除技能. private void OnSkillRemoveHandler(InstanceUnit unit, CommonAI.Zone.Instance.InstanceUnit.SkillState sk) { if (mSkillHelper != null) { mSkillHelper.RemoveSkill(sk); } } //状态机切换. private void OnStateChangedHandler(InstanceUnit obj, InstanceUnit.State old_state, InstanceUnit.State new_state) { if (old_state != null && old_state is InstanceUnit.StateSkill) { InstanceUnit.StateSkill stateSkill = old_state as InstanceUnit.StateSkill; //获得技能ID. int id = stateSkill.SkillData.ID; DispatchStateSkillEndEvent(this, stateSkill); } if (new_state is InstanceUnit.StatePickObject) { TakeOffMount(); } } private void OnSkillHitTargetHandler() { //吸血,待完善 } #endregion /// /// 检查当前buff状态,是否可添加. /// /// private bool CanAddBuff(ref BuffTemplate buff, XmdsVirtual target) { bool ret = false; //获取当前BUFF是哪种能力. XmdsBuffProperties prop = buff.Properties as XmdsBuffProperties; //XmdsBuffProperties.XmdsBuffAbility ab = prop.BuffAbilityList; ////判断该种BUFF是否被约束. //switch (ab) //{ // case XmdsBuffProperties.XmdsBuffAbility.FROZEN: // case XmdsBuffProperties.XmdsBuffAbility.STUN: // case XmdsBuffProperties.XmdsBuffAbility.Silent: // break; // default: break; //} return ret; } /// /// 外部获取当前技能状态信息,排除被动技能 /// /// public XmdsSkillStatusData GetSkillStatusData() { XmdsSkillStatusData ret = new XmdsSkillStatusData(); ret.SkillTimestampMSMap = new HashMap(); //生成同步时间戳. long SkillTimestampMS = TimeUtil.GetTimestampMS(); IEnumerable sslist = mUnit.SkillStatus; //主动技能. foreach (InstanceUnit.SkillState s in sslist) { if (s.ActionIndex > 0 && s.IsHasNext()) { s.ForceIntoCD(); } if(s.GetSkillType() == XmdsSkillType.cardSkill) { continue; } ret.SkillTimestampMSMap.Add(s.ID, SkillTimestampMS + s.TotalCDTime - s.PassTime); } //被动技能. //if (SkillHelper.mPassiveSkills != null) //{ // for (int i = 0; i < SkillHelper.mPassiveSkills.Count; i++) // { // UnitPassiveSkill ups = SkillHelper.mPassiveSkills[i]; // ret.SkillTimestampMSMap.Add(ups.SkillID, SkillTimestampMS + ups.GetCDTotalTime() - ups.GetCDPassTime()); // } //} return ret; } public long GetSkillTimestampMS(int skillID) { InstanceUnit.SkillState ss = this.mUnit.getSkillState(skillID); if (ss != null) { long SkillTimestampMS = TimeUtil.GetTimestampMS() + ss.TotalCDTime - ss.PassTime; return SkillTimestampMS; } return 0; } private int CalSkillCDTime(long timestamp) { long curTime = TimeUtil.GetTimestampMS(); long dif = timestamp - curTime; return (int)dif; } private InstanceUnit.SkillState SetSkillCD(int skillid, long timestamp) { InstanceUnit.SkillState ss = this.mUnit.getSkillState(skillid); if (ss == null) { return null; } int time = CalSkillCDTime(timestamp); //大于0代表还处于CD中. if (time > 0 && time <= ss.TotalCDTime) { ss.IsInMutilTime = false; this.mUnit.SetSkillPassTime(skillid, ss.TotalCDTime - time); } return ss; } private void SetSkillCDDecreasePercent(int skillid, int percent) { if (percent == 0) { return; } InstanceUnit.SkillState ss = this.mUnit.getSkillState(skillid); if (ss == null) { return; } int cd = ss.Data.CoolDownMS; int dt = (int)(cd * (percent * 1.0f / XmdsDamageCalculator.PERER)); ss.AddDecreaseTotalTimeMS(dt); } public void DestorySkill() { if (mSkillHelper != null) { mSkillHelper.Dispose(); mSkillHelper = null; } foreach (var buf in mTrySendBuff.Values) { var bvlist = (buf.Properties as XmdsBuffProperties).GetBuffVirtualList(); foreach (var bv in bvlist) { bv.Dispose(); } bvlist.Clear(); } mTrySendBuff.Clear(); mTrySendSpell.Clear(); } /// /// 技能信息辅助类. /// public class XmdsSkillHelper { //普通技能. private SkillTemplate mBaseSkill = null; //单位拥有的技能. private HashMap mSkillMap = null; //单位自己的主动技能模板. private HashMap mActiveSkillTemplateMap = null; //单位拥有的被动技能. internal List mPassiveSkills = null; //单位拥有的主动技能. internal List mActiveSkills = null; //宿主. private XmdsVirtual mOwner = null; public XmdsSkillHelper() { //主动技能表. if (mActiveSkillTemplateMap == null) { mActiveSkillTemplateMap = new HashMap(); } if (mActiveSkills == null) { mActiveSkills = new List(); } } public void InitSkill(XmdsUnitSkillInfo sks, XmdsVirtual owner) { if (mSkillMap != null) { mSkillMap.Clear(); } else { mSkillMap = new HashMap(); } mOwner = owner; //主动技能初始化. if (sks != null) { InitSkill(sks.UnitSkills); } } public String GetAllSkills() { String skillText = ""; foreach (KeyValuePair pair in mSkillMap) { skillText += pair.Key + ", "; } return skillText; } /// /// 获得主动、被动技能列表. /// /// /// /// private void GetActivePassiveSkillList(List src, ref List active, ref List passive) { GameSkill gs = null; for (int i = 0; i < src.Count; i++) { gs = src[i]; if (JSGModule.IsActiveSkill(gs.SkillType)) { active.Add(gs); } else if (JSGModule.IsPassiveSkill(gs.SkillType)) { passive.Add(gs); } } } #region 主动技能. /// /// 初始化主动技能. /// /// public void InitActiveSkills(List gameSkills) { try { if (gameSkills == null || gameSkills.Count == 0) { return; } //需要判断BUFF状态,记录单位技能信息. GameSkill gs = null; UnitSkill us = null; SkillTemplate st = null; for (int i = 0; i < gameSkills.Count; i++) { gs = gameSkills[i]; if (mSkillMap.ContainsKey(gameSkills[i].SkillID)) { continue; } //主动技能初始化只有初始化成功的技能会在技能MAP中. //存放技能等级信息. mSkillMap.Add(gameSkills[i].SkillID, gameSkills[i]); us = InitXmdsSkillScript(gs, ref st); if (us != null && st != null) { mActiveSkillTemplateMap.Add(st.ID, st); //UnitSkill us = XmdsBattleSkill.GetUnitSkill(gs.SkillID); mActiveSkills.Add(us); //if(st.ID != us.SkillID) //{ // log.Warn("初始化技能,使用脚本不一致, 技能" + st.ID + ", 使用:" + us.SkillID); //} } else { FormatLog(string.Format("XmdsVirtual.Skill can not find SkillScript {0},", gs.SkillID)); } } #region 重置单位技能. List temp = new List(); for (int i = 0; i < gameSkills.Count; i++) { gs = gameSkills[i]; if (mActiveSkillTemplateMap.TryGetValue(gs.SkillID, out st)) { //分辨出普通攻击. if (gs.SkillType == XmdsSkillType.normalAtk) { mBaseSkill = st; } else { temp.Add(st); } } } if (temp.Count > 0 || mBaseSkill != null) { //重置技能. mOwner.mUnit.InitSkills(mBaseSkill, temp.ToArray()); } for (int i = 0; i < temp.Count; i++) { if (mSkillMap.TryGetValue(temp[i].ID, out gs)) { mOwner.SetSkillCD(temp[i].ID, gs.SkillTimestampMS); mOwner.SetSkillCDDecreasePercent(temp[i].ID, gs.SkillCDDecreasePercent); // 人物, 宠物的技能是否自动释放走配置表 if (mOwner is XmdsVirtual_Player || mOwner is XmdsVirtual_Pet) { SkillState skillState = mOwner.mUnit.getSkillState(temp[i].ID); if (skillState != null) { skillState.setAutoLaunch(gs.AutoLaunch); } } } } //UnitSkillList.Clear(); //UnitSkillList = null; #endregion } catch (Exception error) { FormatLog(CommonLang.Log.LoggerLevel.ERROR, "单位【{0}】初始化技能错误:{1}", mOwner.mInfo.Name, error.ToString()); } } public void notifyActiveSkillInitOver(List gameSkills) { if (mActiveSkills == null) { return; } for (int i = 0; i < mActiveSkills.Count; i++) { GameSkill gameSkill = null; for (int j = 0; j < gameSkills.Count; j++) { if (mActiveSkills[i].SkillID == gameSkills[j].SkillID) { gameSkill = gameSkills[j]; break; } } mActiveSkills[i].InitOver(mOwner, gameSkill); } } public void notifyPassiveSkillInitOver(List gameSkills) { if (mPassiveSkills == null) { return; } for (int i = 0; i < mPassiveSkills.Count; i++) { GameSkill gameSkill = null; for (int j = 0; j < gameSkills.Count; j++) { if (mPassiveSkills[i].SkillID == gameSkills[j].SkillID) { gameSkill = gameSkills[j]; break; } } mPassiveSkills[i].InitOver(mOwner, gameSkill); } } //public bool changeActiveSkill(int oldSkillID, int newSkillID) //{ // try // { // if (oldSkillID == 0 || oldSkillID == newSkillID) // { // return false; // } // GameSkill oldSkill = mSkillMap.Get(oldSkillID); // GameSkill newSkill = mSkillMap.Get(newSkillID); // if (oldSkill == null || newSkill != null) // { // return false; // } // oldSkill.SkillID = newSkillID; // newSkill = oldSkill; // SkillTemplate st = null; // UnitSkill us = InitXmdsSkillScript(newSkill, ref st); // if (us == null || st == null) // { // FormatLog(string.Format("XmdsVirtual.Skill can not find SkillScript {0},", newSkill.SkillID)); // return false; // } // mSkillMap.Remove(oldSkillID); // mSkillMap.Add(newSkillID, newSkill); // mActiveSkillTemplateMap.Remove(oldSkillID); // mActiveSkillTemplateMap.Add(us.SkillID, st); // for (int i = 0; i < mActiveSkills.Count; i++) // { // if (mActiveSkills[i].SkillID == oldSkillID) // { // mActiveSkills.RemoveAt(i); // mActiveSkills.Add(us); // break; // } // } // #region 重置单位技能. // List temp = new List(); // if (mActiveSkillTemplateMap.TryGetValue(newSkillID, out st)) // { // //分辨出普通攻击. // if (newSkill.SkillType == XmdsSkillType.normalAtk) // { // mBaseSkill = st; // } // else // { // temp.Add(st); // } // } // if (temp.Count > 0 || mBaseSkill != null) // { // //重置技能. // mOwner.mUnit.InitSkills(mBaseSkill, temp.ToArray()); // } // // 人物, 宠物的技能是否自动释放走配置表 // if (mOwner is XmdsVirtual_Player || mOwner is XmdsVirtual_Pet) // { // SkillState skillState = mOwner.mUnit.getSkillState(newSkill.SkillID); // if (skillState != null) // { // skillState.setAutoLaunch(newSkill.AutoLaunch); // } // } // mOwner.SetSkillCD(st.ID, newSkill.SkillTimestampMS); // mOwner.SetSkillCDDecreasePercent(st.ID, newSkill.SkillCDDecreasePercent); // for (int i = 0; i < mActiveSkills.Count; i++) // { // if (mActiveSkills[i].SkillID == newSkillID) // { // mActiveSkills[i].InitOver(mOwner, newSkill); // break; // } // } // #endregion // } // catch (Exception error) // { // FormatLog(CommonLang.Log.LoggerLevel.ERROR, "单位【{0}】初始化技能错误:{1}", mOwner.mInfo.Name, error.ToString()); // return false; // } // return true; //} private UnitSkill InitXmdsSkillScript(GameSkill gs, ref SkillTemplate st) { UnitSkill us = null; try { //获取技能脚本. us = XmdsBattleSkill.GetUnitSkill(gs.SkillID); //如果UnitSkill为NULL,则读取默认脚本. if (us == null) { //FormatLog(CommonLang.Log.LoggerLevel.INFO, string.Format("单位{0}主动技能{1}未找到脚本,使用默认脚本代替", mOwner.mInfo.TemplateID, gs.SkillID)); us = XmdsBattleSkill.GetUnitSkill(XmdsBattleSkill.DefaultSkillScriptID); // 宠物或者人物如果没有配置对应的技能文件,就设置为不自动释放技能 if (this.mOwner is XmdsVirtual_Pet || this.mOwner is XmdsVirtual_Player) { gs.AutoLaunch = false; } } //主动技能特殊逻辑初始化. st = XmdsBattleSkill.GetSkillTemplate(gs.SkillID); if (st == null) { FormatLog(CommonLang.Log.LoggerLevel.ERROR, string.Format("未找到技能模板{0}", gs.SkillID)); } //对技能进行脚本重铸. us.Init(gs, mOwner, ref st); } catch (Exception err) { log.Error("InitXmdsSkillScript异常, 技能id" + gs.SkillID + ", 单位ID: " + mOwner.mInfo.TemplateID + ", e : " + err); } return us; } #endregion #region 被动技能技能. //初始化被动技能. public void InitPassiveSkills(List skills) { try { if (skills == null || skills.Count == 0) { return; } mPassiveSkills = new List(); UnitPassiveSkill sk = null; for (int i = 0; i < skills.Count; i++) { if (mSkillMap.ContainsKey(skills[i].SkillID)) { continue; } sk = InitXmdsPassiveSkillScript(skills[i]); mSkillMap.Add(skills[i].SkillID, skills[i]); mPassiveSkills.Add(sk); SetPassiveSkillCD(sk, skills[i].SkillTimestampMS); SetPassiveSkillCDDecrease(sk, skills[i].SkillCDDecreasePercent); } } catch (Exception error) { FormatLog(CommonLang.Log.LoggerLevel.ERROR, "单位【{0}】初始化被动技能错误:{1}", mOwner.mInfo.Name, error.ToString()); } } private void SetPassiveSkillCD(UnitPassiveSkill sk, long timestamp) { int time = mOwner.CalSkillCDTime(timestamp); //大于0代表还处于CD中. if (time > 0 && time <= sk.GetCDTotalTime()) { sk.SetCDPassTime(sk.GetCDTotalTime() - time); } } private void SetPassiveSkillCDDecrease(UnitPassiveSkill sk, int timeMS) { if (sk != null) { int t = (int)(timeMS * 1.0f / XmdsDamageCalculator.PERER); int oldt = sk.GetDecreaseTotalTimeMS(); int newt = oldt + t; sk.SetDecreaseTotalTimeMS(newt); } } //初始化被动技能脚本. private UnitPassiveSkill InitXmdsPassiveSkillScript(GameSkill gs) { UnitPassiveSkill ret = null; try { ret = XmdsBattleSkill.GetPassiveSkill(gs.SkillID); if (ret == null) { throw new Exception("被动技能脚本未找到:" + this.mOwner.mUnit.PlayerUUID); } else { ret.Init(gs, mOwner); } } catch (Exception err) { ThrowXmdsException(gs.SkillID, mOwner.mInfo.TemplateID, err.ToString()); } return ret; } /// /// 报错方法. /// /// /// /// private void ThrowXmdsException(int skill, int unit, string error) { string msg = string.Format("XmdsSkill Init Error id : SkillID = {0} UnitID = {1},Error = {2}", skill, unit, error.ToString()); log.Error(msg); throw new Exception(msg); } //更新技能状态. private void UpdatePassiveSkills(int intervalMS, bool slowRefresh) { if (mPassiveSkills != null) { for (int i = 0; i < mPassiveSkills.Count; i++) { mPassiveSkills[i].Update(intervalMS, slowRefresh); } } } private void UpdateActiveSkills(int intervalMS, bool slowRefresh) { if (mActiveSkills != null) { for (int i = 0; i < mActiveSkills.Count; i++) { UnitSkill skillInfo = mActiveSkills[i]; if (skillInfo == null || !skillInfo.IsActive) { continue; } skillInfo.Update(intervalMS, slowRefresh); } } } #endregion #region 常用API. /// /// 是否有该技能. /// /// /// public bool ContainSkill(int id) { return mSkillMap.ContainsKey(id); } /// /// 获取技能信息. /// /// /// public GameSkill GetGameSkill(int id) { GameSkill ret = null; mSkillMap.TryGetValue(id, out ret); return ret; } //获取玩家技能 public UnitSkill GetPlayerSkillById(int skillId) { if (mActiveSkills == null) { return null; } for (int i = 0; i < mActiveSkills.Count; i++) { if (mActiveSkills[i].SkillID == skillId) { return mActiveSkills[i]; } } return null; } //获取玩家技能 public UnitPassiveSkill GetPlayerSkillByIdExt(int skillId) { if (mPassiveSkills == null) { return null; } for (int i = 0; i < mPassiveSkills.Count; i++) { if (mPassiveSkills[i].SkillID == skillId) { return mPassiveSkills[i]; } } return null; } /// /// 获取主动技能模板. /// /// /// public SkillTemplate GetUnitSkillTemplate(int id) { SkillTemplate ret = null; mActiveSkillTemplateMap.TryGetValue(id, out ret); return ret; } public void RemoveSkill(CommonAI.Zone.Instance.InstanceUnit.SkillState sk) { if (mSkillMap != null) { GameSkill gs = null; if (mSkillMap.TryGetValue(sk.ID, out gs)) { mOwner.RemoveEventBySkillID(gs.SkillID); mSkillMap.Remove(sk.ID); } for (int i = 0; i < mActiveSkills.Count; i++) { if (mActiveSkills[i].SkillID == sk.ID) { mActiveSkills.RemoveAt(i); break; } } } if (mActiveSkillTemplateMap != null) { mActiveSkillTemplateMap.RemoveByKey(sk.ID); mActiveSkillTemplateMap.Remove(sk.ID); } } public void Update(int intervalMS, bool slowRefresh) { UpdatePassiveSkills(intervalMS, slowRefresh); //2021.11.02优化:主动技能慢刷新,打开需要注明原因 if(slowRefresh) { UpdateActiveSkills(intervalMS, slowRefresh); } } public int GetBaseSkillID() { if (mBaseSkill != null) { return mBaseSkill.ID; } return 0; } /// /// 增加技能. /// /// public void AddSkill(List list) { if (list != null && list.Count > 0) { List active = new List(); List passive = new List(); GetActivePassiveSkillList(list, ref active, ref passive); GameSkill gs = null; //主动技能. for (int i = 0; i < active.Count; i++) { gs = active[i]; AddActiveSkill(gs); } for (int i = 0; i < passive.Count; i++) { gs = passive[i]; AddPassiveSkill(gs); } } } public UnitSkill AddActiveSkill(GameSkill gs, bool is_default = false) { SkillTemplate st = null; UnitSkill us = null; //存放技能等级信息. mSkillMap.Put(gs.SkillID, gs); us = InitXmdsSkillScript(gs, ref st); if (st != null) { if (mActiveSkillTemplateMap == null) { mActiveSkillTemplateMap = new HashMap(); } mActiveSkillTemplateMap.Put(st.ID, st); //us = XmdsBattleSkill.GetUnitSkill(gs.SkillID); mOwner.mUnit.AddSkill(st, gs.AutoLaunch, is_default); SkillState skillState = mOwner.SetSkillCD(gs.SkillID, gs.SkillTimestampMS); mOwner.SetSkillCDDecreasePercent(gs.SkillID, gs.SkillCDDecreasePercent); if (skillState != null) { skillState.Reset(true); } if (us != null) { mActiveSkills.Add(us); us.InitOver(mOwner, gs); } } return us; } public UnitPassiveSkill AddPassiveSkill(GameSkill gs) { UnitPassiveSkill ups = InitXmdsPassiveSkillScript(gs); mSkillMap.Put(gs.SkillID, gs); SetPassiveSkillCD(ups, gs.SkillTimestampMS); SetPassiveSkillCDDecrease(ups, gs.SkillCDDecreasePercent); if (mPassiveSkills == null) { mPassiveSkills = new List(); } mPassiveSkills.Add(ups); ups.InitOver(mOwner, gs); return ups; } /// /// 减少技能. /// /// public void RemoveSkill(List list) { if (list != null && list.Count > 0) { List active = new List(); List passive = new List(); GetActivePassiveSkillList(list, ref active, ref passive); GameSkill gs = null; //主动技能. for (int i = 0; i < active.Count; i++) { gs = active[i]; RemoveActiveSkill(gs.SkillID); } //删除被动技能. for (int i = 0; i < passive.Count; i++) { if (mSkillMap.TryGetValue(passive[i].SkillID, out gs)) { RemovePassiveSkill(gs.SkillID); } } } } public void RemoveActiveSkill(int skillID) { if (mBaseSkill != null && skillID == mBaseSkill.ID) { mBaseSkill = null; } mOwner.mUnit.RemoveSkill(skillID); //调用该API收到remove事件再删除技能. } public void RemovePassiveSkill(int skillID) { mSkillMap.RemoveByKey(skillID); for (int k = 0; k < mPassiveSkills.Count; k++) { if (mPassiveSkills[k].SkillID == skillID) { mPassiveSkills[k].Dispose(mOwner); mPassiveSkills.RemoveAt(k); mOwner.RemoveEventBySkillID(skillID); break; } } } /// /// 初始化技能. /// /// private void InitSkill(List list) { List active = new List(); List passive = new List(); if (list.Count == 0) { return; } else if (this.mOwner.mUnit.IsPlayer) { //玩家有一些特殊的逻辑放到天赋被动里面 } GetActivePassiveSkillList(list, ref active, ref passive); InitPassiveSkills(passive); InitActiveSkills(active); //通知技能,初始化完成 notifyActiveSkillInitOver(active); notifyPassiveSkillInitOver(passive); this.mOwner.InitCardModule(); } /// /// 重置技能. /// /// public void ResetSkill(List list, XmdsVirtual owner) { //1清除所有技能. ClearSkill(); if (mSkillMap == null) { mSkillMap = new HashMap(); } mOwner = owner; //2重新初始化技能. InitSkill(list); } public void ReplaceSkill(List list) { if (list == null) { return; } GameSkill gs = null; GameSkill new_gs = null; for (int i = 0; i < list.Count; i++) { new_gs = list[i]; gs = null; mSkillMap.TryGetValue(new_gs.SkillID, out gs); if (gs != null) { gs.SkillLevel = new_gs.SkillLevel; gs.TalentSkillLevel1 = new_gs.TalentSkillLevel1; gs.TalentSkillLevel2 = new_gs.TalentSkillLevel2; gs.TalentSkillLevel3 = new_gs.TalentSkillLevel3; if (gs.SkillType == XmdsSkillType.passive) { if (mPassiveSkills != null) { for (int k = 0; k < mPassiveSkills.Count; k++) { if (mPassiveSkills[k].SkillID == gs.SkillID) { //去除原有CD修改值. SetPassiveSkillCDDecrease(mPassiveSkills[k], -gs.SkillCDDecreasePercent); //重新设置CD修改值. SetPassiveSkillCDDecrease(mPassiveSkills[k], new_gs.SkillCDDecreasePercent); //技能效果变化. mPassiveSkills[k].SkillDataChange(gs, mOwner); } } } } else { //去除原有CD修改值. mOwner.SetSkillCDDecreasePercent(gs.SkillID, -gs.SkillCDDecreasePercent); //重新设置CD修改值. mOwner.SetSkillCDDecreasePercent(new_gs.SkillID, new_gs.SkillCDDecreasePercent); for (int k = 0; k < mActiveSkills.Count; k++) { if (mActiveSkills[k].SkillID == new_gs.SkillID) { mActiveSkills[k].SkillDataChange(new_gs, mOwner); break; } } } gs.SkillCDDecreasePercent = new_gs.SkillCDDecreasePercent; } } } /// /// 清理技能. /// public void ClearSkill() { List ret = new List(); GameSkill g = null; if (mSkillMap != null) { foreach (KeyValuePair pair in mSkillMap) { g = new GameSkill(); g.SkillID = pair.Key; g.SkillType = pair.Value.SkillType; ret.Add(g); } RemoveSkill(ret); } } public void Dispose() { ClearSkill(); mBaseSkill = null; if (mSkillMap != null) { mSkillMap.Clear(); mSkillMap = null; } if (mActiveSkillTemplateMap != null) { mActiveSkillTemplateMap.Clear(); mActiveSkillTemplateMap = null; } if (mPassiveSkills != null) { mPassiveSkills.Clear(); mPassiveSkills = null; } mOwner = null; } #endregion #region 特殊硬编码技能. #endregion } /// /// 技能状态信息. /// public class XmdsSkillStatusData { /// /// 技能(技能ID,到期时间戳). /// . public HashMap SkillTimestampMSMap = null; } //-----------------------职业天赋相关的接口----------------------- public virtual IPlayerCache GetPlayerCache() { return this.mPlayerCache; } public virtual void SetPlayerCache(IPlayerCache cache) { this.mPlayerCache = cache; } public virtual void Talent__Add(int value) { if (this.mPlayerCache != null) { this.mPlayerCache.AddTalentValue(value); } } public virtual bool Talent_Use(int value) { if (this.mPlayerCache != null) { return this.mPlayerCache.UseTalentValue(value); } return false; } public virtual int Talent_Value() { return mPlayerCache == null ? 0 : mPlayerCache.GetTalentValue(); } public virtual int Talent_Lv() { return mPlayerCache == null ? 0 : mPlayerCache.GetTalentLv(); } public virtual bool Talent_Refresh(bool notify = true) { if (this.mPlayerCache != null) { return this.mPlayerCache.Refresh(notify); } return false; } //--------------------------------------------------------------------- #region BUFF跨场景. /* /// /// BUFF信息集合. /// public class XmdsBuffStatus { public List mDatas = null; } /// /// Buff状态信息. /// public class XmdsBuffStatusData { /// /// BUFF模板. /// public int BuffTemplateID = 0; /// /// BUFF时间戳. /// public long BuffTimestampMS = 0; } */ #endregion #region 技能API测试功能. protected void Mock_RemoveSkill(int skillID) { PlayerSkillChangeEventR2B evt = new PlayerSkillChangeEventR2B(); evt.OperateID = PlayerSkillChangeEventR2B.SkillOperate.Remove; List list = new List(); GameSkill gs = new GameSkill(); gs.SkillID = skillID; list.Add(gs); evt.SkillList = list; OnPlayerSkillsChanged(evt); } protected void Mock_AddSkill(int skillID) { PlayerSkillChangeEventR2B evt = new PlayerSkillChangeEventR2B(); evt.OperateID = PlayerSkillChangeEventR2B.SkillOperate.Add; List list = new List(); GameSkill gs = new GameSkill(); gs.SkillID = skillID; gs.SkillLevel = 1; gs.SkillType = XmdsSkillType.active; list.Add(gs); evt.SkillList = list; OnPlayerSkillsChanged(evt); } protected void Mock_ResetSkill(List list) { PlayerSkillChangeEventR2B evt = new PlayerSkillChangeEventR2B(); evt.OperateID = PlayerSkillChangeEventR2B.SkillOperate.Reset; evt.SkillList = list; OnPlayerSkillsChanged(evt); } protected void Mock_ReplaceSkill(List list) { PlayerSkillChangeEventR2B evt = new PlayerSkillChangeEventR2B(); evt.OperateID = PlayerSkillChangeEventR2B.SkillOperate.Replace; evt.SkillList = list; OnPlayerSkillsChanged(evt); } #endregion } }