using CommonAI.Zone;
using CommonAI.Zone.Instance;
using CommonAI.Zone.Formula;
using CommonLang;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XmdsCommon.Plugin;
using XmdsCommonServer.Plugin.XmdsSkillTemplate.Skills;
using CommonAI.Data;
using XmdsCommonSkill.Plugin.CardSkill;
using XmdsCommon.JSGModule.Interface;
using CommonAI.ZoneServer.JSGModule;

namespace XmdsCommonServer.Plugin
{
    /// <summary>
    /// FileName: XmdsVirtual.cs
    /// Author: Alex.Yu
    /// Corporation:... 
    /// Description:注册事件相关. 
    /// DateTime: 2015/6/2 17:38:21
    /// </summary>

    partial class XmdsVirtual
    {
        //OnHitOther//
        readonly private List<OnHitHandler> mOnHitOtherLt = new List<OnHitHandler>();
        //OnHitDamage//
        readonly private List<OnHitHandler> mOnHitDamageLt = new List<OnHitHandler>();
        //OnBuffStart//
        readonly private List<OnBuffEventHandler> mOnBuffEventLt = new List<OnBuffEventHandler>();
        //OnCalDamage//
        readonly private List<OnCalDmageHandler> mOnCalDamageLt = new List<OnCalDmageHandler>();
        //OnLaunchSkillOver//
        readonly private List<OnLaunchSkillOverHandler> mOnLaunchSkillOverLt = new List<OnLaunchSkillOverHandler>();
        //OnGetAtkTarget//
        readonly private List<OnGetAtkTargetHandler> mOnGetAtkTargetLt = new List<OnGetAtkTargetHandler>();
        //OnGetSkillDamageInfo //
        readonly private List<OnGetSkillDamageInfo> mOnGetSkillDamageInfoLt = new List<OnGetSkillDamageInfo>();
        //IStateSkillEnd //
        readonly private List<OnStateSkillEnd> mOnStateSkillEndLt = new List<OnStateSkillEnd>();
        //ITryAddBuffEvent//
        readonly private List<OnTryAddBuff> mOnTryAddBuffLt = new List<OnTryAddBuff>();
		readonly private List<OnRemoveBuff> mOnRemoveBuffLt = new List<OnRemoveBuff>();
		//ISendBuffEvent
		//readonly private List<OnSendBuffEvent> mOnSendBuffEvent = new List<OnSendBuffEvent>();

        readonly private List<OnTrySendSpell> mOnTrySendSpellLt = new List<OnTrySendSpell>();

		readonly private List<OnSendSpellOverEvent> mSendSpellOverLt = new List<OnSendSpellOverEvent>();

        readonly private List<OnTryLaucnSkill> mOnTryLaunchSkillLt = new List<OnTryLaucnSkill>();

        //宠物给予人物的主动技能触发
        readonly private List<OnTriggerPetSkill> mOnTriggerPetSkillLt = new List<OnTriggerPetSkill>();

        //计算仇恨值.
        readonly private List<OnCalThreatValue> mOnCalThreatValueLt = new List<OnCalThreatValue>();

		//技能被打断事件监听
		readonly private List<OnSkillBlockEvnet> mOnSkillBlockList = new List<OnSkillBlockEvnet>();

		//加血事件
		readonly private List<OnAddOtherHPEvnet> mAddOtherHPList = new List<OnAddOtherHPEvnet>();
		//承担伤害监听
		readonly private List<OnShareMasterDmgEvent> mShareMasterDmgList = new List<OnShareMasterDmgEvent>();
		//扣定力
		readonly private List<OnReduceOtherMpEvnet> mReduceMPList = new List<OnReduceOtherMpEvnet>();
		//获得卡牌珠监听
		readonly private List<OnTryAddCardBallEvent> mTryAddCardBallList = new List<OnTryAddCardBallEvent>();
		//释放卡牌技能监听
		readonly private List<OnTriggerCardSkillEvent> mTriggerCardSkillList = new List<OnTriggerCardSkillEvent>();

		//击杀其他单位监听
		readonly private List<OnKillOtherUnitEvent> mKillOtherList = new List<OnKillOtherUnitEvent>();


		private HashMap<int, IHandle> mHandleMap = new HashMap<int, IHandle>();
        private int mHandleUUID = 0;

		public enum BuffEventType
        {
            None,
            Begin,
            End,
            Update,
            Hit,
        }

        public abstract class IHandle
        {
            public readonly GameSkill m_skill;
			public readonly bool mListenAll = false;

			public IHandle(GameSkill skill, bool listenAll)
			{
				this.m_skill = skill;
				this.mListenAll = listenAll;
			}
		}

        public class OnHitHandler : IHandle
        {
            public readonly IOnHit m_hit;
            public readonly bool ListenAllSkill = false;

            public OnHitHandler(IOnHit hit, GameSkill skill, bool listenAll) : base(skill, listenAll)
            {
                m_hit = hit;
                this.ListenAllSkill = listenAll;
            }
        }

        class OnBuffEventHandler : IHandle
        {
            public readonly IOnBuffEvent m_tg;
            public readonly BuffEventType m_type;

            public OnBuffEventHandler(IOnBuffEvent tg, BuffEventType type, GameSkill skill) : base(skill, true)
			{
                m_tg = tg;
                m_type = type;
            }
        }

        public class OnCalDmageHandler : IHandle
        {
            public readonly ICalDamage m_cal;
			public readonly int skillDamageID;
            public OnCalDmageHandler(ICalDamage tg, GameSkill skill, bool listenAll, int skillDamageID) : base(skill, listenAll)
			{
                m_cal = tg;
				this.skillDamageID = skillDamageID;
			}

			public override string ToString()
			{
				return skillDamageID.ToString();
			}
        }

        class OnLaunchSkillOverHandler : IHandle
        {
            public readonly ILaunchSkillOver m_hand;
            public OnLaunchSkillOverHandler(ILaunchSkillOver tg, GameSkill skill, bool listenAll) : base(skill, listenAll)
			{
                m_hand = tg;
            }
        }

        class OnGetAtkTargetHandler : IHandle
        {
            public readonly IGetAtkTarget m_hand;

            public OnGetAtkTargetHandler(IGetAtkTarget tg, GameSkill skill, bool listenAll) : base(skill, listenAll)
			{
                m_hand = tg;
            }
        }

        class OnGetSkillDamageInfo : IHandle
        {
            public readonly IGetSkillDamageInfo m_hand;

            public OnGetSkillDamageInfo(IGetSkillDamageInfo tg, GameSkill skill, bool listenAll) : base(skill, listenAll)
			{
                m_hand = tg;
            }
        }

        class OnStateSkillEnd : IHandle
        {
            public readonly IStateSkillEnd m_hand;

            public OnStateSkillEnd(IStateSkillEnd tg, GameSkill skill, bool listenAll) : base(skill, listenAll)
			{
                m_hand = tg;
            }
        }

        class OnTryAddBuff : IHandle
        {
            public readonly ITryAddBuffEvent m_hand;

            public OnTryAddBuff(ITryAddBuffEvent tg, GameSkill skill, bool listenAll) : base(skill, listenAll)
			{
                m_hand = tg;
            }
        }

		class OnRemoveBuff : IHandle
		{
			public readonly IRemoveBuffEvent m_hand;
			public readonly int buffID;

			public OnRemoveBuff(IRemoveBuffEvent tg, int buffID, bool listenAll) : base(null, listenAll)
			{
				m_hand = tg;
				this.buffID = buffID;
			}
		}

		//class OnSendBuffEvent : IHandle
  //      {
  //          public readonly int listenBuffID;
  //          public readonly ISendBuffEvent m_hand;

  //          public OnSendBuffEvent(ISendBuffEvent tg, GameSkill skill, int listenBuffID = 0) : base(skill, false)
		//	{
  //              m_hand = tg;
  //              this.listenBuffID = listenBuffID;
  //          }
  //      }

        class OnSendSpellOverEvent : IHandle
        {
            public readonly ISendSpellOverEvent m_hand;
			public readonly int mListSpellId;
            public OnSendSpellOverEvent(ISendSpellOverEvent tg, int spellId, GameSkill sk, bool listenAll = false) : base(sk, listenAll)
			{
                m_hand = tg;
				this.mListSpellId = spellId;
			}
        }

		class OnTrySendSpell : IHandle
		{
			public readonly ITrySendSpellEvent m_hand;
			public readonly int mListenSpellId;
			public OnTrySendSpell(ITrySendSpellEvent tg, GameSkill skill, int listenSpellId, bool listenAll) : base(skill, listenAll)
			{
				m_hand = tg;
				this.mListenSpellId = listenSpellId;
			}
		}



		class OnTryLaucnSkill : IHandle
        {
            public readonly ITryLaunchSkillEvent m_hand;
            public OnTryLaucnSkill(ITryLaunchSkillEvent tg, GameSkill skill, bool listenAll) : base(skill, listenAll)
			{
                m_hand = tg;
            }
        }

        class OnTriggerPetSkill : IHandle
        {
            public readonly ITriggerPetSkillEvent m_hand;
            public OnTriggerPetSkill(ITriggerPetSkillEvent tg, GameSkill skill, bool listenAll) : base(skill, listenAll)
			{
                m_hand = tg;
            }
        }

        class OnCalThreatValue : IHandle
        {
            public readonly ICalThreadValue m_hand;
            public OnCalThreatValue(ICalThreadValue tg, GameSkill skill, bool listenAll) : base(skill, listenAll)
			{
                m_hand = tg;
            }
        }

		class OnSkillBlockEvnet : IHandle
		{
			public readonly ISkillBlockEvent m_hand;

			public OnSkillBlockEvnet(ISkillBlockEvent handler, GameSkill skill, bool listenAll) : base(skill, listenAll)
			{
				this.m_hand = handler;
			}
		}

		class OnAddOtherHPEvnet : IHandle
		{
			public readonly IAddOtherHPEvent m_hand;			
			public OnAddOtherHPEvnet(IAddOtherHPEvent handler, GameSkill skill) : base(skill, true)
			{
				this.m_hand = handler;
				
			}
		}

		protected class OnShareMasterDmgEvent : IHandle
		{
			public readonly IShareMasterDmgEvent m_hand;
			public OnShareMasterDmgEvent(IShareMasterDmgEvent handler, GameSkill skill) : base(skill, true)
			{
				this.m_hand = handler;

			}
		}

		class OnReduceOtherMpEvnet : IHandle
		{
			public readonly IReduceOtherMpEvent m_hand;

			public OnReduceOtherMpEvnet(IReduceOtherMpEvent handler, GameSkill skill) : base(skill, true)
			{
				this.m_hand = handler;
			}
		}

		class OnTryAddCardBallEvent : IHandle
		{
			public readonly CreateCardBallSource mType;
			public readonly ITryAddCardBallEvent m_hand;

			public OnTryAddCardBallEvent(ITryAddCardBallEvent handler, CreateCardBallSource type, bool listenAll = false) : base(null, listenAll)
			{
				this.m_hand = handler;
				this.mType = type;
			}
		}

		class OnTriggerCardSkillEvent : IHandle
		{
			public readonly CardType mPointCardType;
			public readonly ITriggerCardSkillEvent m_hand;

			public OnTriggerCardSkillEvent(ITriggerCardSkillEvent handler, GameSkill info, CardType cardType, bool listenAll = false) : base(info, listenAll)
			{
				this.m_hand = handler;
				this.mPointCardType = cardType;
			}
		}

		class OnKillOtherUnitEvent : IHandle
		{
			public readonly int maType;
			public readonly IOnKillOtherUnitEvent m_hand;

			public OnKillOtherUnitEvent(IOnKillOtherUnitEvent handler, GameSkill info, int type) : base(info, false)
			{
				this.m_hand = handler;
				this.maType = type;
			}
		}

		#region 事件监听.

		public delegate void OnHealEvent(XmdsVirtual attacker, XmdsVirtual hitter, int value, ref AtkResult result);
        public delegate void OnCombatStateChangeEvent(XmdsVirtual unit, bool status);

        /// <summary>
        /// 治愈回调.
        /// </summary>
        public event OnHealEvent OnHealEventHandle;
        /// <summary>
        /// 战斗状态变更.
        /// </summary>
        public event OnCombatStateChangeEvent OnCombatStateChangeHandle
        {
            add { event_OnCombatStateChangeHandle += value; }
            remove { event_OnCombatStateChangeHandle -= value; }
        }

        protected OnCombatStateChangeEvent event_OnCombatStateChangeHandle;
        #endregion

        #region 计算伤害时触发.

        public int RegistCalDamage(ICalDamage cal, GameSkill sk, bool listenAll, int skillDamageID = 0)
        {
            OnCalDmageHandler handle = new OnCalDmageHandler(cal, sk, listenAll, skillDamageID);
            int ret = HandleUUIDCreate();
            mOnCalDamageLt.Add(handle);
            mHandleMap.Add(ret, handle);
            return ret;
        }

        public bool UnRegistCalDamage(int handleUUID)
        {
            bool ret = false;
            IHandle handle = null;

            if (mHandleMap.TryGetValue(handleUUID, out handle))
            {
                if (handle != null && handle is OnCalDmageHandler)
                {
                    ret = mOnCalDamageLt.Remove(handle as OnCalDmageHandler);
                    mHandleMap.Remove(handleUUID);
                }
            }

            return ret;
        }

        #endregion

        #region 单位打到别人时开发.

        /// <summary>
        /// 单位打到别人时触发
        /// </summary>
        /// <param name="hit"></param>
        /// <param name="sk"></param>
        public int RegistOnHitOther(IOnHit hit, GameSkill sk, bool listenAll = false)
        {
            OnHitHandler handle = new OnHitHandler(hit, sk, listenAll);
            int ret = HandleUUIDCreate();
            mOnHitOtherLt.Add(handle);
            mHandleMap.Add(ret, handle);
            return ret;
        }

        public bool UnRegistOnHitOther(int handleUUID)
        {
            bool ret = false;
            IHandle handle = null;

            if (mHandleMap.TryGetValue(handleUUID, out handle))
            {
                if (handle != null && handle is OnHitHandler)
                {
                    ret = mOnHitOtherLt.Remove(handle as OnHitHandler);
                    mHandleMap.Remove(handleUUID);
                }
            }

            return ret;
        }

        #endregion

        #region 单位受到攻击时触发.

        /// <summary>
        /// 单位收到攻击时触发
        /// </summary>
        /// <param name="hit"></param>
        /// <param name="sk"></param>
        public int RegistOnHitDamage(IOnHit hit, GameSkill sk, bool listenAll = false)
        {
            OnHitHandler handle = new OnHitHandler(hit, sk, listenAll);
            mOnHitDamageLt.Add(handle);
            int ret = HandleUUIDCreate();
            mHandleMap.Add(ret, handle);
            return ret;
        }

        public bool UnRegistOnHitDamage(int handleUUID)
        {
            bool ret = false;
            IHandle handle = null;

            if (mHandleMap.TryGetValue(handleUUID, out handle))
            {
                if (handle != null && handle is OnHitHandler)
                {
                    ret = mOnHitDamageLt.Remove(handle as OnHitHandler);
                    mHandleMap.Remove(handleUUID);
                }
            }

            return ret;
        }


        #endregion

        #region BUFF触发.

        /// <summary>
        /// 注册监听BUFF相关事件.
        /// </summary>
        /// <param name="tg"></param>
        /// <param name="type"></param>
        /// <param name="sk"></param>
        /// <returns></returns>
        public int RegistBuffEvent(IOnBuffEvent tg, BuffEventType type, GameSkill sk)
        {
            OnBuffEventHandler handle = new OnBuffEventHandler(tg, type, sk);
            mOnBuffEventLt.Add(handle);
            int ret = HandleUUIDCreate();
            mHandleMap.Add(ret, handle);
            return ret;
        }

        public bool UnRegistBuffEvent(int handleUUID)
        {
            bool ret = false;
            IHandle handle = null;

            if (mHandleMap.TryGetValue(handleUUID, out handle))
            {
                if (handle != null && handle is OnBuffEventHandler)
                {
                    ret = mOnBuffEventLt.Remove(handle as OnBuffEventHandler);
                    mHandleMap.Remove(handleUUID);
                }
            }

            return ret;
        }

        #endregion

        #region 增加BUFF.

        /// <summary>
        /// 注册是否能添加BUFF判断事件.
        /// </summary>
        /// <returns></returns>
        public int RegistTryAddBuffEvent(ITryAddBuffEvent tg, GameSkill sk, bool listenAll = false)
        {
            OnTryAddBuff handle = new OnTryAddBuff(tg, sk, listenAll);
            mOnTryAddBuffLt.Add(handle);
            int ret = HandleUUIDCreate();
            mHandleMap.Add(ret, handle);
            return ret;
        }

        /** 注册给其他玩家添加buff时间 */
        //public int RegistSendBuffEvent(ISendBuffEvent tg, GameSkill sk, int listenBuffID = 0)
        //{
        //    OnSendBuffEvent handle = new OnSendBuffEvent(tg, sk, listenBuffID);
        //    mOnSendBuffEvent.Add(handle);
        //    int ret = HandleUUIDCreate();
        //    mHandleMap.Add(ret, handle);
        //    return ret;
        //}

		/** 注册给其他玩家添加buff时间 */
		public int RegistRemoveBuffEvent(IRemoveBuffEvent tg, int buffID, bool listenAll = false)
		{
			OnRemoveBuff handle = new OnRemoveBuff(tg, buffID, listenAll);
			mOnRemoveBuffLt.Add(handle);
			int ret = HandleUUIDCreate();
			mHandleMap.Add(ret, handle);
			return ret;
		}

		/// <summary>
		/// 取消注册添加BUFF判断.
		/// </summary>
		/// <returns></returns>
		public bool UnRegistTryAddBuffEvent(int handleUUID)
        {
            bool ret = false;
            IHandle handle = null;

            if (mHandleMap.TryGetValue(handleUUID, out handle))
            {
                if (handle != null && handle is OnTryAddBuff)
                {
                    ret = mOnTryAddBuffLt.Remove(handle as OnTryAddBuff);
                    mHandleMap.Remove(handleUUID);
                }
            }

            return ret;
        }

        /// <summary>
        /// 取消发送BUFF监听.
        /// </summary>
        /// <returns></returns>
        //public bool UnRegistSendBuffEvent(int handleUUID)
        //{
        //    bool ret = false;
        //    IHandle handle = null;

        //    if (mHandleMap.TryGetValue(handleUUID, out handle))
        //    {
        //        if (handle != null && handle is OnSendBuffEvent)
        //        {
        //            ret = mOnSendBuffEvent.Remove(handle as OnSendBuffEvent);
        //            mHandleMap.Remove(handleUUID);
        //        }
        //    }

        //    return ret;
        //}

		/// <summary>
		/// 取消注册添加BUFF判断.
		/// </summary>
		/// <returns></returns>
		public bool UnRegistRemoveBuffEvent(int handleUUID)
		{
			bool ret = false;
			IHandle handle = null;

			if (mHandleMap.TryGetValue(handleUUID, out handle))
			{
				if (handle != null && handle is OnRemoveBuff)
				{
					ret = mOnRemoveBuffLt.Remove(handle as OnRemoveBuff);
					mHandleMap.Remove(handleUUID);
				}
			}

			return ret;
		}


		#endregion

		#region 注册监听spell重定向.

		public int RegistTrySendSpellEvent(ITrySendSpellEvent tg, GameSkill sk, int listenSpellId = 0, bool listenAll = false)
        {
            OnTrySendSpell handle = new OnTrySendSpell(tg, sk, listenSpellId, listenAll);
            mOnTrySendSpellLt.Add(handle);
            int ret = HandleUUIDCreate();
            mHandleMap.Add(ret, handle);
            return ret;
        }

        public bool UnRegistTrySendSpellEvent(int handleUUID)
        {
            bool ret = false;
            IHandle handle = null;

            if (mHandleMap.TryGetValue(handleUUID, out handle))
            {
                if (handle != null && handle is OnTrySendSpell)
                {
                    ret = mOnTrySendSpellLt.Remove(handle as OnTrySendSpell);
                    mHandleMap.Remove(handleUUID);
                }
            }

            return ret;
        }

		public int RegistSendSpellOverEvent(ISendSpellOverEvent tg, int spellId, GameSkill sk, bool listAll = false)
		{
			OnSendSpellOverEvent handle = new OnSendSpellOverEvent(tg, spellId, sk, listAll);
			mSendSpellOverLt.Add(handle);
			int ret = HandleUUIDCreate();
			mHandleMap.Add(ret, handle);
			return ret;
		}

		public bool UnRegistSendSpellOverEvent(int handleUUID)
		{
			bool ret = false;
			IHandle handle = null;

			if (mHandleMap.TryGetValue(handleUUID, out handle))
			{
				if (handle != null && handle is OnSendSpellOverEvent)
				{
					ret = mSendSpellOverLt.Remove(handle as OnSendSpellOverEvent);
					mHandleMap.Remove(handleUUID);
				}
			}

			return ret;
		}

		#endregion

		#region 监听技能施放.

		public int RegistTryLaunchSkillEvent(ITryLaunchSkillEvent tg, GameSkill sk, bool listenAllSkill = false)
        {
            OnTryLaucnSkill handle = new OnTryLaucnSkill(tg, sk, listenAllSkill);
            mOnTryLaunchSkillLt.Add(handle);
            int ret = HandleUUIDCreate();
            mHandleMap.Add(ret, handle);
            return ret;
        }

        public bool UnRegistTryLaunchSkillEvent(int handleUUID)
        {
            bool ret = false;
            IHandle handle = null;

            if (mHandleMap.TryGetValue(handleUUID, out handle))
            {
                if (handle != null && handle is OnTryLaucnSkill)
                {
                    ret = mOnTryLaunchSkillLt.Remove(handle as OnTryLaucnSkill);
                    mHandleMap.Remove(handleUUID);
                }
            }

            return ret;
        }

		//ITriggerPetSkillEvent返回true,结束下层传递
		public int RegistTriggerPetSkillEvent(ITriggerPetSkillEvent tg, GameSkill sk, bool listenAllSkill = false)
        {
            OnTriggerPetSkill handle = new OnTriggerPetSkill(tg, sk, listenAllSkill);
            mOnTriggerPetSkillLt.Add(handle);
            int ret = HandleUUIDCreate();
            mHandleMap.Add(ret, handle);
            return ret;
        }

        public bool UnRegistTriggerPetSkillEvent(int handleUUID)
        {
            bool ret = false;
            IHandle handle = null;

            if (mHandleMap.TryGetValue(handleUUID, out handle))
            {
                if (handle != null && handle is OnTriggerPetSkill)
                {
                    ret = mOnTriggerPetSkillLt.Remove(handle as OnTriggerPetSkill);
                    mHandleMap.Remove(handleUUID);
                }
            }

            return ret;
        }

        #endregion

        #region 释放完技能后.

        /// <summary>
        /// 注册技能释放完毕的监听.
        /// </summary>
        /// <param name="call"></param>
        /// <param name="sk"></param>
        /// <returns></returns>
        public int RegistLaunchSkillOver(ILaunchSkillOver call, GameSkill sk, bool listenAllSkill = false)
        {
            OnLaunchSkillOverHandler handle = new OnLaunchSkillOverHandler(call, sk, listenAllSkill);
            int ret = HandleUUIDCreate();
            mOnLaunchSkillOverLt.Add(handle);
            mHandleMap.Add(ret, handle);
            return ret;
        }

        /// <summary>
        /// 反注册技能释放完毕的监听.
        /// </summary>
        /// <param name="call"></param>
        /// <param name="sk"></param>
        /// <returns></returns>
        public bool UnRegistLaunchSkillOver(int handleUUID)
        {
            bool ret = false;
            IHandle handle = null;

            if (mHandleMap.TryGetValue(handleUUID, out handle))
            {
                if (handle != null && handle is OnLaunchSkillOverHandler)
                {
                    ret = mOnLaunchSkillOverLt.Remove(handle as OnLaunchSkillOverHandler);
                    mHandleMap.Remove(handleUUID);
                }
            }

            return ret;
        }

        #endregion

        #region 获得攻击目标.

        /// <summary>
        /// 注册获取攻击目标监听.
        /// </summary>
        /// <param name="call"></param>
        /// <param name="sk"></param>
        /// <returns></returns>
        public int RegistGetAtkTarget(IGetAtkTarget call, GameSkill sk, bool listenAll)
        {
            OnGetAtkTargetHandler handle = new OnGetAtkTargetHandler(call, sk, listenAll);
            int ret = HandleUUIDCreate();
            mOnGetAtkTargetLt.Add(handle);
            mHandleMap.Add(ret, handle);
            return ret;
        }

        /// <summary>
        /// 反注册获取攻击目标监听.
        /// </summary>
        /// <param name="call"></param>
        /// <param name="sk"></param>
        /// <returns></returns>
        public bool UnRegistGetAtkTarget(int handleUUID)
        {
            bool ret = false;
            IHandle handle = null;

            if (mHandleMap.TryGetValue(handleUUID, out handle))
            {
                if (handle != null && handle is OnGetAtkTargetHandler)
                {
                    ret = mOnGetAtkTargetLt.Remove(handle as OnGetAtkTargetHandler);
                    mHandleMap.Remove(handleUUID);
                }
            }

            return ret;
        }

        #endregion

        #region 注册获得技能伤害.

        public int RegistGetSkillDamageInfo(IGetSkillDamageInfo call, GameSkill sk, bool listenAll)
        {
            OnGetSkillDamageInfo handle = new OnGetSkillDamageInfo(call, sk, listenAll);
            int ret = HandleUUIDCreate();
            mOnGetSkillDamageInfoLt.Add(handle);
            mHandleMap.Add(ret, handle);
            return ret;
        }

        public bool UnRegistGetSkillDamageInfo(int handleUUID)
        {
            bool ret = false;
            IHandle handle = null;

            if (mHandleMap.TryGetValue(handleUUID, out handle))
            {
                if (handle != null && handle is OnGetSkillDamageInfo)
                {
                    ret = mOnGetSkillDamageInfoLt.Remove(handle as OnGetSkillDamageInfo);
                    mHandleMap.Remove(handleUUID);
                }
            }

            return ret;
        }

        #endregion

        #region 技能结束监听.

        /// <summary>
        /// 注册技能结束监听.
        /// </summary>
        /// <param name="call"></param>
        /// <param name="sk"></param>
        /// <returns></returns>
        public int RegistStateSkillEndEvent(IStateSkillEnd call, GameSkill sk, bool listenAllSkill)
        {
            OnStateSkillEnd handle = new OnStateSkillEnd(call, sk, listenAllSkill);
            int ret = HandleUUIDCreate();
            mOnStateSkillEndLt.Add(handle);
            mHandleMap.Add(ret, handle);
            return ret;
        }

        /// <summary>
        /// 取消技能结束监听.
        /// </summary>
        /// <param name="handleUUID"></param>
        /// <returns></returns>
        public bool UnRegistStateSkillEndEvent(int handleUUID)
        {
            bool ret = false;
            IHandle handle = null;

            if (mHandleMap.TryGetValue(handleUUID, out handle))
            {
                if (handle != null && handle is OnStateSkillEnd)
                {
                    ret = mOnStateSkillEndLt.Remove(handle as OnStateSkillEnd);
                    mHandleMap.Remove(handleUUID);
                }
            }

            return ret;
        }

        #endregion

        #region 计算仇恨值监听.

        public int RegistCalThreatValue(ICalThreadValue call, GameSkill gs, bool listenAllSkill)
        {
            OnCalThreatValue handle = new OnCalThreatValue(call, gs, listenAllSkill);
            int ret = HandleUUIDCreate();
            mOnCalThreatValueLt.Add(handle);
            mHandleMap.Add(ret, handle);
            return ret;
        }

        public bool UnRegistCalThreatValue(int handleUUID)
        {
            bool ret = false;
            IHandle handle = null;

            if (mHandleMap.TryGetValue(handleUUID, out handle))
            {
                if (handle != null && handle is OnCalThreatValue)
                {
                    ret = mOnCalThreatValueLt.Remove(handle as OnCalThreatValue);
                    mHandleMap.Remove(handleUUID);
                }
            }

            return ret;
        }

		#endregion


		#region 技能被打断监听.

		public int RegistSkillBlockEvent(ISkillBlockEvent call, GameSkill gs)
		{
			OnSkillBlockEvnet handle = new OnSkillBlockEvnet(call, gs, true);
			int ret = HandleUUIDCreate();
			mOnSkillBlockList.Add(handle);
			mHandleMap.Add(ret, handle);
			return ret;
		}

		public bool UnRegistSkillBlockEvent(int handleUUID)
		{
			bool ret = false;
			IHandle handle = null;

			if (mHandleMap.TryGetValue(handleUUID, out handle))
			{
				if (handle != null && handle is OnSkillBlockEvnet)
				{
					ret = mOnSkillBlockList.Remove(handle as OnSkillBlockEvnet);
					mHandleMap.Remove(handleUUID);
				}
			}

			return ret;
		}


		public int RegistAddOtherHPEvent(IAddOtherHPEvent call, GameSkill gs)
		{
			OnAddOtherHPEvnet handle = new OnAddOtherHPEvnet(call, gs);
			int ret = HandleUUIDCreate();
			mAddOtherHPList.Add(handle);
			mHandleMap.Add(ret, handle);
			return ret;
		}

		public bool UnRegistAddOtherHPEvent(int handleUUID)
		{
			bool ret = false;
			IHandle handle = null;

			if (mHandleMap.TryGetValue(handleUUID, out handle))
			{
				if (handle != null && handle is OnAddOtherHPEvnet)
				{
					ret = mAddOtherHPList.Remove(handle as OnAddOtherHPEvnet);
					mHandleMap.Remove(handleUUID);
				}
			}

			return ret;
		}

		public int RegistShareMasterDmgEvent(IShareMasterDmgEvent call, GameSkill gs)
		{
			OnShareMasterDmgEvent handle = new OnShareMasterDmgEvent(call, gs);
			int ret = HandleUUIDCreate();
			mShareMasterDmgList.Add(handle);
			mHandleMap.Add(ret, handle);
			return ret;
		}

		public bool UnRegistShareMasterDmgEvent(int handleUUID)
		{
			bool ret = false;
			IHandle handle = null;

			if (mHandleMap.TryGetValue(handleUUID, out handle))
			{
				if (handle != null && handle is OnShareMasterDmgEvent)
				{
					ret = mShareMasterDmgList.Remove(handle as OnShareMasterDmgEvent);
					mHandleMap.Remove(handleUUID);
				}
			}

			return ret;
		}

		public int RegistReduceMPEvent(IReduceOtherMpEvent call, GameSkill gs)
		{
			OnReduceOtherMpEvnet handle = new OnReduceOtherMpEvnet(call, gs);
			int ret = HandleUUIDCreate();
			mReduceMPList.Add(handle);
			mHandleMap.Add(ret, handle);
			return ret;
		}

		public bool UnRegistReduceOtherMpEvent(int handleUUID)
		{
			bool ret = false;
			IHandle handle = null;

			if (mHandleMap.TryGetValue(handleUUID, out handle))
			{
				if (handle != null && handle is OnReduceOtherMpEvnet)
				{
					ret = mReduceMPList.Remove(handle as OnReduceOtherMpEvnet);
					mHandleMap.Remove(handleUUID);
				}
			}

			return ret;
		}


		public int RegistTryAddCardBallEvent(ITryAddCardBallEvent call, CreateCardBallSource type, bool listenAll = false)
		{
			OnTryAddCardBallEvent handle = new OnTryAddCardBallEvent(call, type, listenAll);
			int ret = HandleUUIDCreate();
			mTryAddCardBallList.Add(handle);
			mHandleMap.Add(ret, handle);
			return ret;
		}

		public bool UnRegistTryAddCardBallEvent(int handleUUID)
		{
			bool ret = false;
			IHandle handle = null;

			if (mHandleMap.TryGetValue(handleUUID, out handle))
			{
				if (handle != null && handle is OnTryAddCardBallEvent)
				{
					ret = mTryAddCardBallList.Remove(handle as OnTryAddCardBallEvent);
					mHandleMap.Remove(handleUUID);
				}
			}

			return ret;
		}

		public int RegistTriggerCardSkillEvent(ITriggerCardSkillEvent call, GameSkill info, CardType cardType, bool listenAll = false)
		{
			OnTriggerCardSkillEvent handle = new OnTriggerCardSkillEvent(call, info, cardType, listenAll);
			int ret = HandleUUIDCreate();
			mTriggerCardSkillList.Add(handle);
			mHandleMap.Add(ret, handle);
			return ret;
		}

		public bool UnRegistTriggerCardSkillEvent(int handleUUID)
		{
			bool ret = false;
			IHandle handle = null;

			if (mHandleMap.TryGetValue(handleUUID, out handle))
			{
				if (handle != null && handle is OnTriggerCardSkillEvent)
				{
					ret = mTriggerCardSkillList.Remove(handle as OnTriggerCardSkillEvent);
					mHandleMap.Remove(handleUUID);
				}
			}

			return ret;
		}

		public int RegistKillOtherEvent(IOnKillOtherUnitEvent call, GameSkill info, int monsterType)
		{
			OnKillOtherUnitEvent handle = new OnKillOtherUnitEvent(call, info, monsterType);
			int ret = HandleUUIDCreate();
			mKillOtherList.Add(handle);
			mHandleMap.Add(ret, handle);
			return ret;
		}

		public bool UnRegistKillOtherEvent(int handleUUID)
		{
			bool ret = false;
			IHandle handle = null;

			if (mHandleMap.TryGetValue(handleUUID, out handle))
			{
				if (handle != null && handle is OnKillOtherUnitEvent)
				{
					ret = mKillOtherList.Remove(handle as OnKillOtherUnitEvent);
					mHandleMap.Remove(handleUUID);
				}
			}

			return ret;
		}

		#endregion


		#region 事件派发.

		/// <summary>
		/// 分配handleID.
		/// </summary>
		/// <returns></returns>
		private int HandleUUIDCreate()
        {
            return ++mHandleUUID;
        }

        /// <summary>
        ///攻击者监听:打到其他单位. 
        /// </summary>
        /// <param name="damage"></param>
        /// <param name="target"></param>
        /// <param name="source"></param>
        /// <returns></returns>
        private float DispatchHitOtherEvent(float damage, XmdsVirtual target, AttackSource source,
            ref XmdsVirtual.AtkResult result, DamageType damageType)
        {
            if (this.mUnit.IsActive)
            {
				float sourceDmg = damage;

				bool isEndDispatch = false;
                for (int i = mOnHitOtherLt.Count - 1; i >= 0; --i)
                {
                    OnHitHandler hitend = mOnHitOtherLt[i];

                    //伤害单一注册判断
                    if (!hitend.ListenAllSkill && hitend.m_skill != null && source.Attack != null)
                    {
                        XmdsAttackProperties atkProp = source.Attack.Properties as XmdsAttackProperties;
                        if (atkProp.SkillTemplateID != hitend.m_skill.SkillID)
                        {
                            continue;
                        }
                    }                   

                    damage = hitend.m_hit.Invoke(damage, target, this, source, ref result, damageType, hitend.m_skill, ref isEndDispatch);
//#if JSG_DMG_LOG
//					this.CheckAndPrintDmgWarn("DispatchHitOtherEvent", this, target, sourceDmg, damage, source);
//#endif
					if (isEndDispatch)
                    {
                        break;
                    }
                }
            }
            return damage;
        }

//		private void CheckAndPrintDmgWarn(string flag, XmdsVirtual attacker, XmdsVirtual hitter, float sourceDmg, float finalDmg, AttackSource source)
//		{
//			if(source == null || source.Attack == null || source.Attack.Properties.GetAttackID() == XmdsBattleSkill.DefaultSkillScriptID)
//			{
//				return;
//			}

//			int checkValue = (source != null && source.Attack != null && source.Attack.Properties.GetAttackID() / 100 == 1104)
//				? attacker.mUnit.CurrentHP : attacker.MirrorProp.GetFinalAttack(hitter == null ? false : hitter.mUnit.IsMonster);

//			if (finalDmg / sourceDmg > 5.0f || finalDmg / checkValue > 60)
//			{
//				log.Warn(flag + ", dmg: " + (int)finalDmg + ", src: " + (int)sourceDmg + ", attackerAtk: " + attacker.MirrorProp.MaxAttack + ", "
//					+ attacker.MirrorProp.MaxMonsterAttack + ", atkHP:" + mUnit.CurrentHP
//					+ ", AttackInfo:[" + attacker.mUnit.Info.ID + ", UUID: " + attacker.mUnit.PlayerUUID
//					+ "], hitterInfo:[" + hitter.mUnit.Info.ID + ", UUID: " + hitter.mUnit.PlayerUUID + ", " + JSGModule.GetAttackSourceDes(source));
//			}			
//		}

		/// <summary>
		///受击者监听:受到伤害. 
		/// </summary>
		/// <param name="damage"></param>
		/// <param name="attacker"></param>
		/// <param name="source"></param>
		/// skill - 造成伤害的技能信息,可能为空
		/// <returns></returns>
		private float DispatchHitDamageEvent(float damage, XmdsVirtual attacker, AttackSource source, 
            ref XmdsVirtual.AtkResult result, DamageType damageType)
        {
            if (this.mUnit.IsActive && mOnHitDamageLt.Count > 0)
            {
				float sourceDmg = damage;
				bool isEndDispatch = false;
                for (int i = mOnHitDamageLt.Count - 1; i >= 0; --i)
                {
					if(i < 0 || i >= mOnHitDamageLt.Count)
					{
						int buffID = source.FromBuff == null ? 0 : source.FromBuff.ID;
						int spellID = source.FromSpell == null ? 0 : source.FromSpell.ID;
						log.Warn("DispatchHitDamageEvent监听改变: " + i + ", " + mOnHitDamageLt.Count + ", BuffID: " + buffID + ", spellID: " + spellID + ", "
							+ this.mUnit.PlayerUUID);
						break;
					}

                    OnHitHandler hitend = mOnHitDamageLt[i];
                    if(!hitend.ListenAllSkill && hitend.m_skill != null && source.Attack != null)
                    {
                        XmdsAttackProperties atkProp = source.Attack.Properties as XmdsAttackProperties;
                        if (atkProp.SkillTemplateID != hitend.m_skill.SkillID)
                        {
                            continue;
                        }
                    }

                    damage = hitend.m_hit.Invoke(damage, this, attacker, source, ref result, damageType, hitend.m_skill, ref isEndDispatch);
//#if JSG_DMG_LOG
//					this.CheckAndPrintDmgWarn("DispatchHitDamageEvent", attacker, this, sourceDmg, damage, source);
//#endif
					if (isEndDispatch)
                    {
                        break;
                    }
                }
            }
            return CUtils.CastInt(damage);//四舍五入
        }

        /// <summary>
        /// 派发技能成功释放事件.
        /// </summary>
        /// <param name="costEnergy"></param>
        /// <param name="attacker"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        private int DispatchLaunchsSkillOverEvent(XmdsVirtual launcher, CommonAI.Zone.Instance.InstanceUnit.SkillState state)
        {
            if (launcher.mUnit.IsActive)
            {
                for (int i = 0; i < mOnLaunchSkillOverLt.Count; i++)
                {
                    OnLaunchSkillOverHandler hitend = mOnLaunchSkillOverLt[i];

                    if (hitend.mListenAll || hitend.m_skill == null)
                    {
                        hitend.m_hand.Invoke(hitend.m_skill, launcher, state);
                    }
                    else if (hitend.m_skill.SkillID == state.ID)
                    {
                        hitend.m_hand.Invoke(hitend.m_skill, launcher, state);
                    }
                }
            }

            return 0;
        }

        /// <summary>
        /// 派发技能造成伤害事件.
        /// </summary>
        /// <param name="hitter"></param>
        /// <param name="source"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        private int DispatchCalDamageEvent(XmdsVirtual hitter, AttackSource source, ref AtkResult result)
        {
			//特殊情况单位是技能触发伤害,则单位必须活着,如果是spell或BUFF无视单位自身状态.
			XmdsAttackProperties prop = (source.Attack.Properties as XmdsAttackProperties);
			if (this.mUnit.IsActive == false && prop.SkillTemplateID != XmdsCommonServer.Plugin.XmdsSkillTemplate.Skills.XmdsBattleSkill.DefaultSkillScriptID)
            {
                //单位已死亡,技能造成的伤害不算.
                return 0;
            }

            int damage = 0;
			if(prop.SkillTemplateID == XmdsCommonServer.Plugin.XmdsSkillTemplate.Skills.XmdsBattleSkill.DefaultSkillScriptID)
			{
				XmdsBattleSkill.mDefDamgageHandler.m_cal.Invoke(this, hitter, source, XmdsBattleSkill.mDefDamgageHandler.m_skill, ref result, ref damage);
				FormatLog(CommonLang.Log.LoggerLevel.INFO, "--【{0}】对目标【{1}】使用技能【{2}】效果 = 【{3}】", this.mInfo.Name, hitter.mInfo.Name, prop.SkillTemplateID, damage);
			}
            else if (prop.SkillTemplateID > 0)
            {
				bool isFind = false;
                for (int i = mOnCalDamageLt.Count - 1; i >= 0; --i)
                {
                    OnCalDmageHandler hand = mOnCalDamageLt[i];
                    //技能ID匹配时才执行回调.
                    if (hand.skillDamageID == prop.SkillTemplateID || hand.m_skill.SkillID == prop.SkillTemplateID)
                    {
						isFind = true;
						bool isEnd = hand.m_cal.Invoke(this, hitter, source, hand.m_skill, ref result, ref damage);
                        FormatLog(CommonLang.Log.LoggerLevel.INFO, "【{0}】对目标【{1}】使用技能【{2}】效果 = 【{3}】", this.mInfo.Name, hitter.mInfo.Name, prop.SkillTemplateID, damage);
						if (isEnd) { break; }
                    }
                }
				if(!isFind)
				{
					log.Error("配置监听事件异常--场景:" +  this.mUnit.Parent.GetSceneID() +", 伤害ID:" +  prop.SkillTemplateID + ", 异常信息:" + 
						(source.FromBuff == null ? "not buff" : "buff:" + source.FromBuff.ID) +(source.FromSkill == null ? ", not skill" : ", skill:" + source.FromSkill.ID) 
						+ (source.FromSpell == null ? ", not spell" : ", spell:" + source.FromSpell.ID) + ", 单位ID:" + this.mUnit.Info.ID + ", 技能监听:" 
						+ mOnCalDamageLt.Count + ", 血量:" + this.mUnit.CurrentHP + ", 状态:" + this.mUnit.IsActive + ", " + this.GetDamageListens());
				}
			}
			else if(prop.SkillTemplateID == 0)
			{
				log.Error("配置监听事件为0, 场景:" + this.mUnit.Parent.GetSceneID() + ", " + prop.SkillTemplateID + ", " + (source.FromBuff == null ? "not buff" : "buff:" + source.FromBuff.ID) + 
					(source.FromSkill == null ? ", not skill" : ", skill:" + source.FromSkill.ID) +	(source.FromSpell == null ? ", not spell" : ", spell:" + source.FromSpell.ID));
			
			}

            return damage;
        }

		private string GetDamageListens()
		{
			string dmgList = "";
			for (int i = mOnCalDamageLt.Count - 1; i >= 0; --i)
			{
				dmgList = dmgList + mOnCalDamageLt[i].skillDamageID + "#";
			}

			return dmgList;
		}

        /// <summary>
        /// 分发BUFF相关事件.
        /// </summary>
        /// <param name="buff"></param>
        /// <param name="type"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        private bool DispatchBuffEvent(InstanceUnit.BuffState buff, BuffEventType type, string result)
        {
            for (int i = mOnBuffEventLt.Count - 1; i >= 0; --i)
            {
                OnBuffEventHandler tg = mOnBuffEventLt[i];
                if (tg.m_type == type)
                {
                    tg.m_tg.Invoke(this, buff, result, tg.m_skill);
                }
            }
            return true;
        }

        /// <summary>
        /// 派发获得攻击单位事件.
        /// </summary>
        /// <param name="unit"></param>
        /// <returns></returns>
        private XmdsVirtual DispatchGetAtkUnitEvent(XmdsVirtual unit)
        {
            XmdsVirtual ret = unit;

            if (this.mUnit.IsActive)
            {
                for (int i = mOnGetAtkTargetLt.Count - 1; i >= 0; --i)
                {
                    OnGetAtkTargetHandler hitend = mOnGetAtkTargetLt[i];
                    ret = hitend.m_hand.Invoke(unit, hitend.m_skill);
                }
            }

            return ret;
        }


        /// <summary>
        /// 玩家离开怪物范围,mOnGetAtkTargetLt清掉
        /// </summary>
        /// <param name="unit"></param>
        /// <returns></returns>
        public void forceRemoveAtkTarget()
        {
            mOnGetAtkTargetLt.Clear();
        }

        /// <summary>
        /// 派发技能伤害参数事件.
        /// </summary>
        /// <param name="skillDamagePer"></param>
        /// <param name="skillDamageMod"></param>
        /// <param name="attacker"></param>
        /// <param name="hitter"></param>
        /// <param name="source"></param>
        public void DispatchSkillDamageEvent(XmdsVirtual attacker,XmdsVirtual hitter, AttackSource source)
        {
            for (int i = mOnGetSkillDamageInfoLt.Count - 1; i >= 0; --i)
            {
                OnGetSkillDamageInfo hitend = mOnGetSkillDamageInfoLt[i];
                hitend.m_hand.Invoke(attacker, hitter, ref source, hitend.m_skill);
            }

        }

        /// <summary>
        /// 派发技能结束事件.
        /// </summary>
        /// <param name="owner"></param>
        /// <param name="state"></param>
        private void DispatchStateSkillEndEvent(XmdsVirtual owner, InstanceUnit.StateSkill state)
        {

            for (int i = 0; i < mOnStateSkillEndLt.Count; i++)
            {
                OnStateSkillEnd hitend = mOnStateSkillEndLt[i];

                if (hitend.mListenAll || hitend.m_skill == null)
                {
                    hitend.m_hand.Invoke(owner, state, hitend.m_skill);
                }
                else if (hitend.m_skill.SkillID == state.SkillData.ID)
                {
                    hitend.m_hand.Invoke(owner, state, hitend.m_skill);
                }


            }
        }

        /// <summary>
        /// 分发技能施放事件.
        /// </summary>
        /// <param name="st"></param>
        private void DispatchTryLaunchSkillEvent(ref InstanceUnit.SkillState skill, ref bool result, ref InstanceUnit.LaunchSkillParam param)
        {
            bool ret = true;

            for (int i = 0; i < mOnTryLaunchSkillLt.Count; i++)
            {
                OnTryLaucnSkill hitend = mOnTryLaunchSkillLt[i];

                if (hitend.mListenAll || hitend.m_skill == null || hitend.m_skill.SkillID == skill.ID) //是否监听所有技能.
                {
					ret = hitend.m_hand.Invoke(hitend.m_skill, ref skill, this, ref param);
					if (ret == false)
					{
						break;
					}
                }
            }

            result = ret;
        }

        /// <summary>
        /// 分发宠物给人的技能施放事件.
        /// </summary>
        /// <param name="st"></param>
        public bool DispatchTriggerPetSkillEvent(ref InstanceUnit.SkillState skill, ref InstanceUnit.LaunchSkillParam param)
        {
            for (int i = 0; i < mOnTriggerPetSkillLt.Count; i++)
            {
                OnTriggerPetSkill hitend = mOnTriggerPetSkillLt[i];

                if (hitend.mListenAll || hitend.m_skill == null|| hitend.m_skill.SkillID == skill.ID) //是否监听所有技能.
                {
                    if (hitend.m_hand.Invoke(hitend.m_skill, ref skill, this, ref param))
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        /// <summary>
        /// 派发是否能添加BUFF事件.k
        /// </summary>
        /// <param name="template"></param>
        /// <param name="hitter"></param>
        /// <param name="result"></param>
        private void DispatchTryAddBuffEvent(ref BuffTemplate template, XmdsVirtual hitter, ref bool result)
        {
            bool ret = true;

            for (int i = mOnTryAddBuffLt.Count - 1; i >= 0; --i)
            {
                OnTryAddBuff hitend = mOnTryAddBuffLt[i];
                ret = hitend.m_hand.Invoke(ref template, this, hitter, hitend.m_skill);

                if (ret == false)
                {
                    break;
                }
            }

            result = ret;
        }

		/// <summary>
		/// 派发移除buff
		/// </summary>
		/// <param name="template"></param>
		/// <param name="hitter"></param>
		/// <param name="result"></param>
		private void DispatchRemoveBuffEvent(BuffTemplate template, XmdsVirtual player, BuffRemoveType type)
		{
			for (int i = mOnRemoveBuffLt.Count - 1; i >= 0; --i)
			{
				OnRemoveBuff hitend = mOnRemoveBuffLt[i];
				if(hitend.mListenAll || hitend.buffID == template.ID)
				{
					if (hitend.m_hand.Invoke(ref template, this, type))
					{
						return;
					}
				}
			}
		}


		/// <summary>
		/// 派发添加BUFF事件.k
		/// </summary>
		/// <param name="template"></param>
		/// <param name="hitter"></param>
		/// <param name="result"></param>
		//private void DispatchSendBuffEvent(BuffTemplate template, XmdsVirtual hitter)
  //      {
  //          for (int i = mOnSendBuffEvent.Count - 1; i >= 0; --i)
  //          {
  //              OnSendBuffEvent hitend = mOnSendBuffEvent[i];
  //              if(hitend.listenBuffID == 0 || hitend.listenBuffID == template.ID)
  //              {
  //                  hitend.m_hand.Invoke(template, this, hitter);
  //              }
  //          }
  //      }

		/** 分发技能被打断事件(暂时只有移动) */
		public void DispatchSkillBlockEvent(InstanceUnit.StateSkill skill, InstanceUnit.State newState)
		{
			for (int i = mOnSkillBlockList.Count - 1; i >= 0; --i)
			{
				OnSkillBlockEvnet hitend = mOnSkillBlockList[i];
				if (hitend.m_skill == null || skill.SkillData.TemplateID == hitend.m_skill.SkillID)
				{
					if(hitend.m_hand.Invoke(this, skill, newState))
					{
						break;
					}
				}
			}
		}

		/** 分发加血事件 */
		public void DispatchAddOtherHPEvent(int hp, InstanceUnit hitter, out int finalHP)
		{
			finalHP = hp;
			for (int i = mAddOtherHPList.Count - 1; i >= 0; --i)
			{
				OnAddOtherHPEvnet hitend = mAddOtherHPList[i];
				if (hitend.m_hand.Invoke(hp, this.mUnit, hitter, out finalHP))
				{
					break;
				}
			}
		}

		/** 分发宠物承担主人伤害事件 */
		public int DispatchShareMasterDmgEvent(int shareDmg, InstanceUnit sender)
		{
			bool isEndDispatch = false;
			for (int i = mShareMasterDmgList.Count - 1; i >= 0; --i)
			{
				OnShareMasterDmgEvent hitend = mShareMasterDmgList[i];

				shareDmg = hitend.m_hand.Invoke(shareDmg, sender, this.mUnit, hitend.m_skill, ref isEndDispatch);
				if (isEndDispatch)
				{
					break;
				}
			}

			return shareDmg;
		}


		/** 分发扣定力事件 */
		public void DispatchAddMPEvent(int mp, InstanceUnit hitter, out int finalMP, AttackSource source)
		{
			finalMP = mp;
			for (int i = mReduceMPList.Count - 1; i >= 0; --i)
			{
				OnReduceOtherMpEvnet hitend = mReduceMPList[i];
				if (hitend.m_hand.Invoke(mp, this.mUnit, hitter, out finalMP, source))
				{
					break;
				}
			}
		}

		/** 分发获得卡牌珠事件 */
		public bool DispatchTryGetCardBallEvent(XmdsVirtual player, CreateCardBallSource type, CardType cardType)
		{
			for (int i = mTryAddCardBallList.Count - 1; i >= 0; --i)
			{
				OnTryAddCardBallEvent hitend = mTryAddCardBallList[i];
				if (hitend.mListenAll || hitend.mType == type)
				{
					if(!hitend.m_hand.Invoke(this, type, cardType))
					{
						return false;
					}
				}
			}

			return true;
		}

		/** 分发释放卡牌技能事件 */
		public bool DispatchTriggerCardSkillEvent(XmdsVirtual player, XmdsVirtual hitter, CardType cardType, int sameNums)
		{
			for (int i = mTriggerCardSkillList.Count - 1; i >= 0; --i)
			{
				OnTriggerCardSkillEvent hitend = mTriggerCardSkillList[i];
				if (hitend.mListenAll || hitend.mPointCardType == cardType)
				{
					if (!hitend.m_hand.Invoke(this, hitter, hitend.m_skill, cardType, sameNums))
					{
						return false;
					}
				}
			}

			return true;
		}

		/** 分发释放卡牌技能事件 */
		public bool DispatchKillOtherEvent(IVirtualUnit attacker, IVirtualUnit deader)
		{
			for (int i = mKillOtherList.Count - 1; i >= 0; --i)
			{
				OnKillOtherUnitEvent hitend = mKillOtherList[i];
				if (deader.GetMaType() >= hitend.maType)
				{
					if (!hitend.m_hand.Invoke(attacker as XmdsVirtual, deader as XmdsVirtual, hitend.m_skill))
					{
						return false;
					}
				}
			}

			return true;
		}

		public void SetSkillActive(int skillTemplateID, bool active, bool pause_on_deactive = false)
		{
			if (this.mSkillHelper != null && this.mSkillHelper.mActiveSkills != null)
			{
				for (int i = 0; i < this.mSkillHelper.mActiveSkills.Count; i++)
				{
					UnitSkill skillInfo = this.mSkillHelper.mActiveSkills[i];
					if(skillInfo != null && skillInfo.SkillID == skillTemplateID)
					{
						skillInfo.IsActive = active;
					}
				}
			}
		}

		/// <summary>
		/// 监听重定向spell.
		/// </summary>
		/// <param name="spt"></param>
		private void DispatchTrySendSpellEvent(LaunchSpell launch, ref SpellTemplate spt, out JSGCreateSpellData createData, ref float startX, ref float startY)
        {
			createData = null;
			for (int i = mOnTrySendSpellLt.Count - 1; i >= 0; --i)
            {
                OnTrySendSpell hitend = mOnTrySendSpellLt[i];
				// 填了技能id,就只发送技能id=法术id的法术
				bool process = hitend.mListenAll;
				if(!process)
				{
					process = (hitend.mListenSpellId > 0) ? (hitend.mListenSpellId == launch.SpellID) : (hitend.m_skill.SkillID == spt.TemplateID);
				}

				if (process)
				{
					if(createData == null)
					{
						createData = new JSGCreateSpellData();
					}
					hitend.m_hand.Invoke(hitend.m_skill, this, launch, ref spt, ref createData, ref startX, ref startY);
				}               
            }
        }

		/// <summary>
		/// 监听spell释放完毕
		/// </summary>
		/// <param name="spt"></param>
		public void DispatchSendSpellOverEvent(LaunchSpell launch, SpellTemplate spt, float startX, float startY)
		{
			for (int i = mSendSpellOverLt.Count - 1; i >= 0; --i)
			{
				OnSendSpellOverEvent hitend = mSendSpellOverLt[i];
				// 填了技能id,就只发送技能id=法术id的法术
				if (hitend.mListenAll || hitend.mListSpellId == spt.TemplateID)
				{
					hitend.m_hand.Invoke(launch, this, spt, hitend.m_skill, startX, startY);
				}
			}
		}

		private void DispatchCalThreatValueEvent(XmdsVirtual hitter, AttackSource source, ref AtkResult result)
        {
            for (int i = 0; i < mOnCalThreatValueLt.Count; i++)
            {
                OnCalThreatValue hitend = mOnCalThreatValueLt[i];

                if (hitend.mListenAll || hitend.m_skill == null || hitend.m_skill.SkillID == ((source.Attack.Properties) as XmdsAttackProperties).SkillTemplateID)
                {
                    hitend.m_hand.Invoke(this, hitter, source, hitend.m_skill, ref result);
                }
            }
        }

#endregion

        /// <summary>
        /// 清理注册信息.
        /// </summary>
        public void ClearRegistEvent()
        {
            mHandleMap.Clear();

            mOnHitOtherLt.Clear();
            mOnHitDamageLt.Clear();
            mOnBuffEventLt.Clear();
            mOnCalDamageLt.Clear();

            mOnLaunchSkillOverLt.Clear();
            mOnGetAtkTargetLt.Clear();
            mOnGetSkillDamageInfoLt.Clear();
            mOnStateSkillEndLt.Clear();

            mOnTryAddBuffLt.Clear();
			//mOnSendBuffEvent.Clear();
			mOnTrySendSpellLt.Clear();
			mSendSpellOverLt.Clear();

			mOnTryLaunchSkillLt.Clear();

			mOnTriggerPetSkillLt.Clear();
			mOnCalThreatValueLt.Clear();
			mOnSkillBlockList.Clear();
			mAddOtherHPList.Clear();

			this.mOnRemoveBuffLt.Clear();
			this.mTryAddCardBallList.Clear();
			this.mReduceMPList.Clear();
			this.mTriggerCardSkillList.Clear();
			this.mShareMasterDmgList.Clear();
			this.mKillOtherList.Clear();

			mHandleUUID = 0;
        }

        /// <summary>
        /// 删除技能相关事件.
        /// </summary>
        /// <param name="skillID"></param>
        public void RemoveEventBySkillID(int skillID)
        {
            try
            {
                using (var removeList = ListObjectPool<int>.AllocAutoRelease())
                {
                    foreach (KeyValuePair<int, IHandle> pair in mHandleMap)
                    {
                        if (pair.Value != null && pair.Value.m_skill != null && skillID == pair.Value.m_skill.SkillID)
                        {
                            removeList.Add(pair.Key);
                        }
                    }
                    for (int i = 0; i < removeList.Count; i++)
                    {
                        RemoveEventByUUID(removeList[i]);
                    }
                }

            }
            catch (Exception error)
            {
                throw new Exception(error.StackTrace);
            }
        }

        private void RemoveEventByUUID(int uuid)
        {
            IHandle handle = null;

            if (mHandleMap.TryGetValue(uuid, out handle))
            {
				bool result = false;
                if (handle is OnHitHandler)
                {
					bool result1 = UnRegistOnHitOther(uuid);
					bool result2 = UnRegistOnHitDamage(uuid);
					result = result1 | result2;
				}
                else if (handle is OnBuffEventHandler)
                {
					result = UnRegistBuffEvent(uuid);
                }
                else if (handle is OnCalDmageHandler)
                {
					result = UnRegistCalDamage(uuid);
                }
                else if (handle is OnLaunchSkillOverHandler)
                {
					result = UnRegistLaunchSkillOver(uuid);
                }
                else if (handle is OnGetAtkTargetHandler)
                {
					result = UnRegistGetAtkTarget(uuid);
                }
                else if (handle is OnGetSkillDamageInfo)
                {
					result = UnRegistGetSkillDamageInfo(uuid);
                }
				else if(handle is OnStateSkillEnd)
				{
					result = UnRegistStateSkillEndEvent(uuid);
				}
				else if (handle is OnTryAddBuff)
				{
					result = UnRegistTryAddBuffEvent(uuid);
				}
				else if(handle is OnRemoveBuff)
				{
					result = UnRegistRemoveBuffEvent(uuid);
				}
				else if(handle is OnSendSpellOverEvent)
				{
					result = UnRegistSendSpellOverEvent(uuid);
				}
				else if (handle is OnTrySendSpell)
                {
					result = UnRegistTrySendSpellEvent(uuid);
                }
				
                else if (handle is OnTryLaucnSkill)
                {
					result = UnRegistTryLaunchSkillEvent(uuid);
                }
                else if (handle is OnTriggerPetSkill)
                {
					result = UnRegistTriggerPetSkillEvent(uuid);
                }
                else if (handle is OnCalThreatValue)
                {
					result = UnRegistCalThreatValue(uuid);
                }
				else if(handle is OnSkillBlockEvnet)
				{
					result = UnRegistSkillBlockEvent(uuid);
				}
				else if(handle is OnAddOtherHPEvnet)
				{
					result = UnRegistAddOtherHPEvent(uuid);
				}
				else if(handle is OnReduceOtherMpEvnet)
				{
					result = UnRegistReduceOtherMpEvent(uuid);
				}
				else if(handle is OnTryAddCardBallEvent)
				{
					result = UnRegistTryAddCardBallEvent(uuid);
				}
				else if(handle is OnTriggerCardSkillEvent)
				{
					result = UnRegistTriggerCardSkillEvent(uuid);
				}
				else if(handle is OnShareMasterDmgEvent)
				{
					result = UnRegistShareMasterDmgEvent(uuid);
				}
				else if (handle is OnKillOtherUnitEvent)
				{
					result = UnRegistKillOtherEvent(uuid);
				}
				else
				{
					log.Error("RemoveEventByUUID not process type: " + handle);
				}
            }
        }
    }
}