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
{
	/// <summary>
	/// FileName: XmdsVirtual.cs
	/// Author: Alex.Yu
	/// Corporation:... 
	/// Description: 
	/// DateTime: 2015/5/12 10:20:46
	/// </summary>
	public partial class XmdsVirtual
	{
		//技能初始化辅助类.  
		protected XmdsSkillHelper mSkillHelper = null;
		/// <summary>
		/// 初始化技能辅助类.
		/// </summary>
		public XmdsSkillHelper SkillHelper { get { return mSkillHelper; } }

		//卡牌技能类
		private IJSCardSkillModule mCardModule;

		//玩家本地缓存数据
		private IPlayerCache mPlayerCache;

		public IJSCardSkillModule CardModule { get { return mCardModule; } }

		private HashMap<int, BuffTemplate> mTrySendBuff = new HashMap<int, BuffTemplate>();
		private HashMap<int, SpellTemplate> mTrySendSpell = new HashMap<int, SpellTemplate>();
		private HashMap<int, SpellTemplate> mLaunchSpellOver = new HashMap<int, SpellTemplate>();


		//扩展字段
		//法师:标记剑影是否强化过
		public int extValue = 0;


		#region 技能相关.

		private void ReGetUnitSkills(List<GameSkill> ls, List<GameSkill> 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<GameSkill> retList = new List<GameSkill>();
			
			// 常规技能
			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<XmdsBuffVirtual> list = temp.GetBuffVirtualList();

				//克隆BUFF能力.
				if (list != null && list.Count > 0)
				{
					List<XmdsBuffVirtual> cList = new List<XmdsBuffVirtual>();

					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<XmdsBuffVirtual> list = (bt.Properties as XmdsBuffProperties).GetBuffVirtualList();

				if (list != null && index < list.Count)
				{
					zbv = list[index];

					if (zbv != null)
					{
						ret = zbv as UnitBuff;
					}
				}
			}

			return ret;
		}

		/// <summary>
		/// 判断是否可放技能.
		/// </summary>
		/// <param name="skill"></param>
		/// <returns></returns>
		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

		/// <summary>
		/// 检查当前buff状态,是否可添加.
		/// </summary>
		/// <returns></returns>
		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;
		}

		/// <summary>
		/// 外部获取当前技能状态信息,排除被动技能
		/// </summary>
		/// <returns></returns>
		public XmdsSkillStatusData GetSkillStatusData()
		{
			XmdsSkillStatusData ret = new XmdsSkillStatusData();
			ret.SkillTimestampMSMap = new HashMap<int, long>();
			//生成同步时间戳.
			long SkillTimestampMS = TimeUtil.GetTimestampMS();

			IEnumerable<InstanceUnit.SkillState> 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();
		}

		/// <summary>
		/// 技能信息辅助类.
		/// </summary>
		public class XmdsSkillHelper
		{
			//普通技能.
			private SkillTemplate mBaseSkill = null;
			//单位拥有的技能.
			private HashMap<int, GameSkill> mSkillMap = null;
			//单位自己的主动技能模板.
			private HashMap<int, SkillTemplate> mActiveSkillTemplateMap = null;
			//单位拥有的被动技能.
			internal List<UnitPassiveSkill> mPassiveSkills = null;

			//单位拥有的主动技能.
			internal List<UnitSkill> mActiveSkills = null;

			//宿主.
			private XmdsVirtual mOwner = null;

			public XmdsSkillHelper()
			{
				//主动技能表.
				if (mActiveSkillTemplateMap == null)
				{
					mActiveSkillTemplateMap = new HashMap<int, SkillTemplate>();
				}

				if (mActiveSkills == null)
				{
					mActiveSkills = new List<UnitSkill>();
				}
			}

			public void InitSkill(XmdsUnitSkillInfo sks, XmdsVirtual owner)
			{
				if (mSkillMap != null) { mSkillMap.Clear(); }
				else { mSkillMap = new HashMap<int, GameSkill>(); }

				mOwner = owner;

				//主动技能初始化.
				if (sks != null)
				{
					InitSkill(sks.UnitSkills);
				}
			}

			public String GetAllSkills()
			{
				String skillText = "";
				foreach (KeyValuePair<int, GameSkill> pair in mSkillMap)
				{
					skillText += pair.Key + ", ";
				}
				return skillText;
			}

			/// <summary>
			/// 获得主动、被动技能列表.
			/// </summary>
			/// <param name="src"></param>
			/// <param name="active"></param>
			/// <param name="passive"></param>
			private void GetActivePassiveSkillList(List<GameSkill> src, ref List<GameSkill> active, ref List<GameSkill> 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 主动技能.

			/// <summary>
			/// 初始化主动技能.
			/// </summary>
			/// <param name="gameSkills"></param>
			public void InitActiveSkills(List<GameSkill> 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<SkillTemplate> temp = new List<SkillTemplate>();
					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<GameSkill> 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<GameSkill> 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<SkillTemplate> temp = new List<SkillTemplate>();
			//		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<GameSkill> skills)
			{
				try
				{
					if (skills == null || skills.Count == 0) { return; }

					mPassiveSkills = new List<UnitPassiveSkill>();

					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;
			}

			/// <summary>
			/// 报错方法.
			/// </summary>
			/// <param name="skill"></param>
			/// <param name="unit"></param>
			/// <param name="error"></param>
			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.

			/// <summary>
			/// 是否有该技能.
			/// </summary>
			/// <param name="id"></param>
			/// <returns></returns>
			public bool ContainSkill(int id)
			{
				return mSkillMap.ContainsKey(id);
			}
			/// <summary>
			/// 获取技能信息.
			/// </summary>
			/// <param name="id"></param>
			/// <returns></returns>
			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;
			}

			/// <summary>
			/// 获取主动技能模板.
			/// </summary>
			/// <param name="id"></param>
			/// <returns></returns>
			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;
			}

			/// <summary>
			/// 增加技能.
			/// </summary>
			/// <param name="list"></param>
			public void AddSkill(List<GameSkill> list)
			{
				if (list != null && list.Count > 0)
				{
					List<GameSkill> active = new List<GameSkill>();
					List<GameSkill> passive = new List<GameSkill>();

					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<int, SkillTemplate>();
					}

					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<UnitPassiveSkill>();
				}

				mPassiveSkills.Add(ups);
				ups.InitOver(mOwner, gs);
				return ups;
			}

			/// <summary>
			/// 减少技能.
			/// </summary>
			/// <param name="list"></param>
			public void RemoveSkill(List<GameSkill> list)
			{
				if (list != null && list.Count > 0)
				{
					List<GameSkill> active = new List<GameSkill>();
					List<GameSkill> passive = new List<GameSkill>();

					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;
					}
				}
			}

			/// <summary>
			/// 初始化技能.
			/// </summary>
			/// <param name="list"></param>
			private void InitSkill(List<GameSkill> list)
			{
				List<GameSkill> active = new List<GameSkill>();
				List<GameSkill> passive = new List<GameSkill>();

				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();
			}
			/// <summary>
			/// 重置技能.
			/// </summary>
			/// <param name="list"></param>
			public void ResetSkill(List<GameSkill> list, XmdsVirtual owner)
			{
				//1清除所有技能.
				ClearSkill();

				if (mSkillMap == null)
				{
					mSkillMap = new HashMap<int, GameSkill>();
				}

				mOwner = owner;

				//2重新初始化技能.
				InitSkill(list);
			}

			public void ReplaceSkill(List<GameSkill> 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;
					}
				}
			}


			/// <summary>
			/// 清理技能.
			/// </summary>
			public void ClearSkill()
			{
				List<GameSkill> ret = new List<GameSkill>();
				GameSkill g = null;

				if (mSkillMap != null)
				{
					foreach (KeyValuePair<int, GameSkill> 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
		}

		/// <summary>
		/// 技能状态信息.
		/// </summary>
		public class XmdsSkillStatusData
		{
			/// <summary>
			/// 技能(技能ID,到期时间戳).
			/// </summary>.
			public HashMap<int, long> 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跨场景.
		/*
        /// <summary>
        /// BUFF信息集合.
        /// </summary>
        public class XmdsBuffStatus
        {
            public List<XmdsBuffStatusData> mDatas = null;
        }

        /// <summary>
        /// Buff状态信息.
        /// </summary>
        public class XmdsBuffStatusData
        {
            /// <summary>
            /// BUFF模板.
            /// </summary>
            public int BuffTemplateID = 0;

            /// <summary>
            /// BUFF时间戳.
            /// </summary>
            public long BuffTimestampMS = 0;

        }
        */
		#endregion

		#region 技能API测试功能.

		protected void Mock_RemoveSkill(int skillID)
        {
            PlayerSkillChangeEventR2B evt = new PlayerSkillChangeEventR2B();

            evt.OperateID = PlayerSkillChangeEventR2B.SkillOperate.Remove;
            List<GameSkill> list = new List<GameSkill>();
            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<GameSkill> list = new List<GameSkill>();
            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<GameSkill> list)
        {
            PlayerSkillChangeEventR2B evt = new PlayerSkillChangeEventR2B();

            evt.OperateID = PlayerSkillChangeEventR2B.SkillOperate.Reset;
            evt.SkillList = list;

            OnPlayerSkillsChanged(evt);
        }

        protected void Mock_ReplaceSkill(List<GameSkill> list)
        {
            PlayerSkillChangeEventR2B evt = new PlayerSkillChangeEventR2B();

            evt.OperateID = PlayerSkillChangeEventR2B.SkillOperate.Replace;
            evt.SkillList = list;

            OnPlayerSkillsChanged(evt);
        }

        #endregion
    }
}