using CommonAI.Zone;
using CommonAI.Zone.Helper;
using CommonAI.Zone.Instance;
using CommonAI.Zone.Formula;
using CommonLang;
using CommonLang.IO;
using CommonLang.IO.Attribute;
using CommonLang.Property;
using CommonLang.Xml;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CommonLang.Concurrent;
using System.ComponentModel;
using static CommonAI.Zone.Instance.InstanceUnit;
using CommonLang.Geometry;
using CommonAI.Data;
using CommonAI.Zone.Attributes;
using XmdsCommon.JSGModule;

namespace XmdsCommon.Plugin
{

    #region 编辑器扩展Properties.

    [MessageType(0x000B0001)]
    [DescAttribute("单位战斗属性")]
    [ExpandableAttribute]
    public class XmdsUnitProperties : IUnitProperties
    {
        /// <summary>
        /// 地位类型.
        /// </summary>
        public enum StatusType : byte
        {
            Normal,//普通.
            Elite, //精英.
            Boss,  //BOSS.
            SpecialElite,
            SpecialBoss,
        }

        /// <summary>
        /// 服务端数据.
        /// </summary>
        [DescAttribute("单位属性-服务器,填时需要联系程序")]
        public XmdsUnitData ServerData = new XmdsUnitData();

        /// <summary>
        /// 单位是否受AOI影响.
        /// </summary>
        [DescAttribute("是否为静态单位,是-不受AOI影响")]
        public bool IsStaticUnit = false;

        /// <summary>
        /// 是否启用脱战计时,关闭时,单位脱战不受时间限制.
        /// </summary>
        [DescAttribute("是否启用脱战倒计时")]
        public bool IsUseCombatTimeCount = true;

        /// <summary>
        /// 头像.
        /// </summary>
        [DescAttribute("头像图片")]
        public string HeadIcon = "没脸见人";
        [DescAttribute("机器人测试模板", "Bot")]
        public bool BotTestTemplate = false;
        [DescAttribute("交互时是否面对交互对象", "NPC")]
        public bool FaceToInteractiveUnit = true;
        [DescAttribute("是否为精英、BOSS", "地位类型")]
        public StatusType GameStatusType = StatusType.Normal;
        [DescAttribute("初始化时是否读取配置脚本", "功能扩展")]
        public bool LoadDataConfig = true;
        [DescAttribute("单位游荡配置", "功能扩展")]
        public WanderConfig WanderConfigData = null;
        [DescAttribute("是否显示血条", "功能扩展")]
        public bool ShowHPBanner = true;

        public override string ToString()
        {
            return "Xmds 单位扩展属性";
        }
        public object Clone()
        {
            XmdsUnitProperties ret = new XmdsUnitProperties();
            ret.ServerData = (XmdsUnitData)this.ServerData.Clone();
            ret.HeadIcon = this.HeadIcon;
            ret.BotTestTemplate = this.BotTestTemplate;
            ret.IsStaticUnit = this.IsStaticUnit;
            ret.IsUseCombatTimeCount = this.IsUseCombatTimeCount;
            ret.FaceToInteractiveUnit = this.FaceToInteractiveUnit;
            ret.GameStatusType = this.GameStatusType;
            ret.LoadDataConfig = this.LoadDataConfig;
            ret.ShowHPBanner = this.ShowHPBanner;
			ret.WanderConfigData = this.WanderConfigData;

			return ret;
        }
        public void WriteExternal(IOutputStream output)
        {
            output.PutExt(ServerData);
            output.PutUTF(HeadIcon);
            output.PutBool(BotTestTemplate);
            output.PutBool(IsStaticUnit);
            output.PutBool(IsUseCombatTimeCount);
            output.PutBool(FaceToInteractiveUnit);
            output.PutEnum8(GameStatusType);
            output.PutBool(LoadDataConfig);
            output.PutBool(ShowHPBanner);
			output.PutExt(WanderConfigData);
        }
        public void ReadExternal(IInputStream input)
        {
            this.ServerData = input.GetExt<XmdsUnitData>();
            this.HeadIcon = input.GetUTF();
            this.BotTestTemplate = input.GetBool();
            this.IsStaticUnit = input.GetBool();
            this.IsUseCombatTimeCount = input.GetBool();
            this.FaceToInteractiveUnit = input.GetBool();
            this.GameStatusType = input.GetEnum8<StatusType>();
            this.LoadDataConfig = input.GetBool();
            this.ShowHPBanner = input.GetBool();
			this.WanderConfigData = input.GetExt<WanderConfig>();

		}
    }

    [MessageType(0x000B0002)]
    [DescAttribute("攻击属性")]
    [ExpandableAttribute]
    public class XmdsAttackProperties : IAttackProperties
    {
        [DescAttribute("技能ID(伤害判定,无填-1)", "技能ID")]
		[TemplateIDAttribute(typeof(SkillTemplate))]
		public int SkillTemplateID = 0;
        [DescAttribute("伤害百分比公式ID", "数值公式ID")]
        public int DamagePerID = 0;
        [DescAttribute("伤害绝对值公式ID", "数值公式ID")]
        public int DamageModiferID = 0;

        public XmdsAttackProperties()
        {

        }

		public int GetAttackID()
		{
			return SkillTemplateID;
		}

		public override string ToString()
        {
            return "Xmds 攻击扩展属性";
        }
        public object Clone()
        {
            XmdsAttackProperties ret = new XmdsAttackProperties();

            ret.SkillTemplateID = this.SkillTemplateID;
            ret.DamagePerID = this.DamagePerID;
            ret.DamageModiferID = this.DamageModiferID;

            return ret;
        }
        public void WriteExternal(IOutputStream output)
        {
            output.PutS32(SkillTemplateID);
            output.PutS32(DamagePerID);
            output.PutS32(DamageModiferID);
        }
        public void ReadExternal(IInputStream input)
        {
            SkillTemplateID = input.GetS32();
            DamagePerID = input.GetS32(); 
            DamageModiferID = input.GetS32();
        }
    }

    [MessageType(0x000B0003)]
    [DescAttribute("BUFF属性")]
    [ExpandableAttribute]
    public class XmdsBuffProperties : IBuffProperties
    {
		public enum XmdsBuffAbility : int
		{
			[Desc("无")]
			None = 0,
			[Desc("属性变更")]
			PropChange = 1 << 8,       //属性变更.
			[Desc("晕眩")]
			STUN = 1,                  //晕眩.
			[Desc("冰冻")]
			FROZEN = 2,                //冰冻.
			[Desc("吸收伤害护盾")]
			SHIELD_AbsorbDamage = 3,   //吸收伤害护盾.
			[Desc("沉默")]
			Silent = 4,                //沉默.
			[Desc("伤害减免")]
			DamageRemit = 5,            //伤害减免.
			[Desc("嘲讽")]
			Mocking = 6,               //嘲讽.
			[Desc("技能伤害变更")]
			SkillDamageChange = 7,     //技能伤害变更.
			[Desc("能量消耗改变")]
			EnergyCost = 8,            //能量消耗改变.
			[Desc("移动速度降低")]
			MoveSpeedDown = 9,          //移动速度降低.
			[Desc("流血")]
			Bleed = 10,                //流血.
			[Desc("加血")]
			AddHP = 11,                //加血.
			[Desc("能量变更")]
			MPChange = 12,             //能量变更.
			[Desc("标记")]
			Mark = 13,                 //标记.
			[Desc("技能CD变更")]
			ChangeSkillTotalTime = 14, //技能CD变更.
			[Desc("技能变更")]
			ChangeSkill = 15,          //技能变更.
			[Desc("无敌")]
			Invincible = 16,           //无敌.
			[Desc("点燃")]
			Burn = 17,                 //点燃.
			[Desc("速度上升 + 免疫控制")]
			SpeedUpAndIngoreCtrl = 18, //(奥义)速度上升+免疫控制.
			[Desc("锁帧 + 免疫伤害控制")]
			Fridge = 19,               //冰箱.
			[Desc("隐身")]
			Stealth = 20,              //隐身. 
			[Desc("免疫控制")]
			IngoreCtrl = 21,           //免疫控制.
			[Desc("闷棍")]
			Sap = 22,                  //闷棍.
			[Desc("献祭(耗MP)")]
			Immolate_MP = 23,          //献祭.
			[Desc("暗影状态")]
			ShadowState = 24,          //暗影状态.
			[Desc("烙印1:定时,或者结束时,造成额外伤害.")]
			Brand = 25,                //烙印.   
			[Desc("Event:单位打到别人后触发.事件型")]
			Event_OnHitOther = 26,     //事件型BUFF,当单位打到别人.
			[Desc("Event:单位收到伤害.事件型")]
			Event_OnHitDamageEvent = 27,//事件性BUFF,受到伤害.
			[Desc("变身")]
			ChangeAvatar = 28, //变身.
			[Desc("激活技能")]
			ActiveSkill = 29,//激活技能.
			[Desc("单位链接")]
			UnitLink = 30,//BUFF状态跟其他单位挂钩.
			[Desc("虚无无视攻击(技能、BUFF)")]
			Nothingness = 31,//虚无状态无视攻击.
			[Desc("无法被选中(客户端操作)")]
			Selectable = 32,
			[Desc("限制伤害最多受到指定伤害")]
			SHIELD_LimitingDamage = 33,
			[Desc("恐惧")]
			Fear = 34,
			[Desc("反伤")]
			SHIELD_IronMaiden = 35,
			[Desc("禁锢(和眩晕冰冻一样)")]
			JINGU = 36,
			[Desc("加血(不会打断)")]
			AddHP_Unbroken = 37,
			[Desc("无敌,放技能失效mmp")]
			Invincible_luanchSkillBreak = 38,
			[Desc("根据生命值变更攻击伤害")]
			AttakUp_ByHp = 39,
			[Desc("锁血N")]
			Lock_HP = 40,
			[Desc("受击加血N%")]
			HitAttHp = 41,
			[Desc("速度改变 + 免伤")]
			SpeedChg_DamageRemit = 42,
			[Desc("免疫硬控,转换成减速50%")]
			IgnorCtrl_To_SpeedDown = 43,
			[Desc("免控 & 速度变更")]
			IgnorCtrl_And_SpeedChg = 44,
			[Desc("烙印1: 被标记,再次攻击触发")]
			Brand_1 = 45,                //烙印.   
			[Desc("烙印2: 对指定目标的伤害提高")]
			Brand_2 = 46,                //烙印.   
			[Desc("烙印3: 下次攻击额外伤害")]
			Brand_3 = 47,                //烙印. 
			[Desc("烙印4:buff创建者攻击buff拥有者,改变拥有者属性")]
			Brand_4 = 48,                //烙印. 
			[Desc("烙印5:buff创建者队友攻击buff拥有者,给队友增加回血buff")]
			Brand_5 = 49,                //烙印. 
			[Desc("烙印6:结束创建一个新的法术")]
			Brand_6 = 50,                //烙印. 
			[Desc("击杀玩家,创建新法术")]
			KillCreateSpeel = 51,
			[Desc("移动速度提高")]
			MoveSpeedUp = 52,          //移动速度提高.
			[Desc("攻速")]
			AttackSpeed = 53,          //攻速
			[Desc("伤害附带debuff")]
			AttackAdditionDebuff = 54,
			[Desc("减速,按时间衰减")]
			SpeedDown_Attenuation = 55,
			[Desc("debuff创建者及队友攻击,回血")]
			Attack_AddHP = 56,
			[Desc("护符,抵挡下一次致命伤害")]
			Remit_DeadlyDamage = 57,
			[Desc("加速,按时间衰减")]
			SpeedUp_Attenuation = 58,
			[Desc("诅咒,1-真实伤害")]
			Curse_RealDamage = 59,
			[Desc("X技能击中,创建新的法术")]
			Hit_CreateSpell = 60,
			[Desc("破甲")]
			Sunder_Armor = 61,
			[Desc("攻击,范围回血")]
			Attack_RoundAddHP = 62,
			[Desc("附加buff")]
			AddBuff = 63,
			[Desc("压制")]
			YaZhi = 64,
			[Desc("加血, 根据当前生命变化")]
			AddHPExt = 65,                //加血.
			[Desc("无法移动")]
			CanNotMove = 66,
			[Desc("根据已损失生命值加血")]
			AddHPByLossHP = 67,
			[Desc("攻击就回血(已损失生命),回血")]
			Attack_AddHPEXT = 68,
			[Desc("结束伤害类型buff")]
			Damage = 69,
			[Desc("治疗毒天赋")]
			RemedyPoison = 70,
			[Desc("护盾-受伤释放法术")]
			SHIELD_HitLaunchSpell = 71,
			[Desc("增加天赋值")]
			ADD_TALENT = 72,

			//100+的都是比较特殊的buff,一般只能适用于一个单独的buff
			[Desc("下次技能暴击 & 回血")]
			NextAttakCrit_AddHP = 100,
            [Desc("测试buff")]
            JSGTestBuff = 101,
            [Desc("攻击创建额外法术")]
            AttackCreateSpell = 102,
        }

        public class XmdsBuffAbilityNode
        {
            public XmdsBuffAbility ability = XmdsBuffAbility.None;
            public XmdsBuffAbilityNode() { }
            public XmdsBuffAbilityNode(XmdsBuffAbility a) { ability = a; }
            public override string ToString()
            {
                return ability.ToString();
            }
        }

        private List<XmdsBuffVirtual> mBuffVirtualList = new List<XmdsBuffVirtual>();

        [DescAttribute("BUFF是否可被驱散.", "BUFF属性.")]
        public bool Dispelled = true;

        [DescAttribute("描述BUFF具体作用及实际能力.", "BUFF能力列表.")]
        public List<XmdsBuffAbilityNode> BuffAbilityList = new List<XmdsBuffAbilityNode>();

        [DescAttribute("是否显示BUFF ICON.", "BUFF属性.")]
        public bool ShowBuffIcon = true;

        public XmdsBuffProperties()
        {

        }

        public override string ToString()
        {
            return "Xmds BUFF扩展属性";
        }

        public object Clone()
        {
            XmdsBuffProperties prop = new XmdsBuffProperties();
            prop.Dispelled = this.Dispelled;
            prop.BuffAbilityList = new List<XmdsBuffAbilityNode>(this.BuffAbilityList.Count);
            prop.ShowBuffIcon = this.ShowBuffIcon;
            foreach (var e in this.BuffAbilityList) { prop.BuffAbilityList.Add(new XmdsBuffAbilityNode(e.ability)); }


            return prop;
        }

        public void WriteExternal(IOutputStream output)
        {
            output.PutBool(Dispelled);

            int count = BuffAbilityList.Count;
            output.PutS32(count);
            for (int i = 0; i < count; i++)
            {
                output.PutEnum32(BuffAbilityList[i].ability);
            }
            output.PutBool(ShowBuffIcon);
        }

        public void ReadExternal(IInputStream input)
        {

            this.Dispelled = input.GetBool();

            BuffAbilityList.Clear();
            int count = input.GetS32();
            for (int i = 0; i < count; i++)
            {
                BuffAbilityList.Add(new XmdsBuffAbilityNode(input.GetEnum32<XmdsBuffAbility>()));
            }

            this.ShowBuffIcon = input.GetBool();
        }

        public void addBuffVirtual(XmdsBuffVirtual buffVirtual)
        {
            mBuffVirtualList.Add(buffVirtual);
        }

        public List<XmdsBuffVirtual> GetBuffVirtualList()
        {
            return mBuffVirtualList;
        }

    }

    [MessageType(0x000B0004)]
    [DescAttribute("道具属性")]
    [ExpandableAttribute]
    public class XmdsItemProperties : IItemProperties
    {
        public enum XmdsItemAbility : int
        {
            NONE = 0,//无.
            HP_CHANGE = 1,//血量改变(加/减).
        }

        public enum XmdsItemType : int
        {
            None,
            [Desc("任务物品")]
            Task,//任务计数用.
            [Desc("装备物品")]
            Equip,//装备道具.
            [Desc("掉落道具")]
            TC,
            [Desc("炼魂道具")]
            RefineSoul,
            [Desc("buff类道具")]
            Buff,
            [Desc("Boss墓碑")]
            BossTombstone,
            [Desc("仙盟建筑")]
            GuildBuild,
            [Desc("妖气")]
            YaoQi,
            [Desc("拾取后换模型PickedRes")]
            Picked,
       }

        public enum XmdsItemPickState : byte
        {
            [Desc("无")]
            None,
            [Desc("钓鱼")]
            Fish,
            [Desc("拾取")]
            Pick,
            [Desc("采集")]
            Collect,
			[Desc("牵马")]
            Horse,
            [Desc("公会打坐")]
            Meditation,
            [Desc("公会传功")]
            Contribution,
            [Desc("公会净妖")]
            NetDemon,
            [Desc("切换场景,协议走的是拾取协议,客户端无法确定场景ID,由服务器控制")]
            GoToScene,
			[Desc("游戏场景中,福袋的互动")]
			Jump,
		}

        public enum XmdsItemSoundType : int
        {
            [Desc("None")]
            None,
            [Desc("Virtuals")]
            Virtuals,
            [Desc("怪物掉落技能")]
            MonsterDropSkill,
            [Desc("小说")]
            XiaoShuo,
            [Desc("功法")]
            GongFa,
            [Desc("mate202")]
            Mate202,
            [Desc("rideItem")]
            RideItem,
            [Desc("petItem")]
            PetItem,
            [Desc("mate205")]
            Mate205,
            [Desc("mate206")]
            Mate206,
            [Desc("mate208")]
            Mate208,
            [Desc("mate209")]
            Mate209,
            [Desc("mate210")]
            Mate210,
            [Desc("chest")]
            Chest,
            [Desc("jinbi")]
            Jinbi,
            [Desc("hpot")]
            Hpot,
            [Desc("VirtQuest")]
            VirtQuest,
            [Desc("realQuest")]
            RealQuest,
            [Desc("魂魄")]
            HunPo,
            [Desc("misc")]
            Misc,
            [Desc("武器")]
            Wuqi,
            [Desc("护身符10")]
            HuShenFu10,
            [Desc("戒指")]
            JieZhi,
            [Desc("护身符12")]
            HuShenFu12,
            [Desc("头部")]
            Head,
            [Desc("上衣")]
            ShangYi,
            [Desc("腿部")]
            TuiBu,
            [Desc("肩部")]
            JianBu,
            [Desc("手套")]
            ShouTao,
            [Desc("鞋子")]
            XieZi,
            [Desc("项链")]
            XianLian,
            [Desc("戒指2")]
            JieZhi2,
        }

        [DescAttribute("物品声音类型", "声音类型")]
        public XmdsItemSoundType soundType = XmdsItemSoundType.None;
        [DescAttribute("物品能力", "物品能力")]
        public XmdsItemAbility abilityType = 0;
        [DescAttribute("作用效果", "物品能力")]
        public int effectValue = 0;
        [DescAttribute("是否为任务道具", "拾取物品条件")]
        public bool IsTaskItem = false;
        [DescAttribute("物品类型", "物品属性")]
        public XmdsItemType ItemType = XmdsItemType.None;
        [DescAttribute("采集动作名字(采集、浇花、焚烧)AreaReadyOne:灵气  AreaBox:一次性采集道具  AreaAction_n:有打开表现(n为正整数)", "物品属性")]
        public string PickActionName;
        [DescAttribute("采集按钮名字(垂钓等)", "物品属性")]
        public string PickButtonName;
        [DescAttribute("采集后显示", "物品属性")]
        public string PickedRes;
        [DescAttribute("采集时的特效", "特效")]
        public LaunchEffect PickEffect;
        [DescAttribute("物品触发功能ID", "物品作用")]
        public int TriggerFunctionID;
        [DescAttribute("拾取状态", "物品属性")]
        public XmdsItemPickState PickState = XmdsItemPickState.None;
        [DescAttribute("是否显示进度百分比", "物品属性")]
        public bool ShowPickPercentText = true;
        [DescAttribute("是否允许自动拾取", "物品属性")]
        public bool AllowAutoGuardPick = false;
        [DescAttribute("炼魂道具作用半径,只在ItemType为RefineSoul有效", "物品属性")]
        public int RefineSoulRadius = 0;
        [DescAttribute("炼魂道具的收集特效,只在ItemType为RefineSoul有效", "物品属性")]
        public LaunchSpell RefineSoulSpell;
        [DescAttribute("炼魂道具的收集满特效,只在ItemType为RefineSoul有效", "物品属性")]
        public LaunchEffect RefineSuccessEffect;
        [DescAttribute("小地图显示标识", "小地图显示标识")]
        public string SmallMap;

		public XmdsItemProperties()
        {

        }
        public override string ToString()
        {
            return "Xmds 道具扩展属性";
        }
        public object Clone()
        {
            XmdsItemProperties ret = new XmdsItemProperties();
            ret.soundType = this.soundType;
            ret.abilityType = this.abilityType;
            ret.effectValue = this.effectValue;
            ret.IsTaskItem = this.IsTaskItem;
            ret.ItemType = this.ItemType;
            ret.PickActionName = this.PickActionName;
            ret.PickButtonName = this.PickButtonName;
            ret.PickedRes = this.PickedRes;
            ret.PickEffect = this.PickEffect;
            ret.TriggerFunctionID = this.TriggerFunctionID;

            ret.PickState = this.PickState;
            ret.ShowPickPercentText = this.ShowPickPercentText;
            ret.AllowAutoGuardPick = this.AllowAutoGuardPick;
            ret.RefineSoulRadius = this.RefineSoulRadius;
            ret.RefineSoulSpell = CUtils.TryClone<LaunchSpell>(this.RefineSoulSpell);
            RefineSuccessEffect = CUtils.TryClone<LaunchEffect>(this.RefineSuccessEffect);
            ret.SmallMap = this.SmallMap;
            return ret;
        }
        public void WriteExternal(IOutputStream output)
        {
            output.PutEnum32((int)this.soundType);
            output.PutEnum32((int)this.abilityType);
            output.PutS32(this.effectValue);
            output.PutBool(this.IsTaskItem);
            output.PutEnum32(this.ItemType);
            output.PutUTF(this.PickActionName);
            output.PutUTF(this.PickButtonName);
            output.PutUTF(this.PickedRes);
            output.PutExt(this.PickEffect);
            output.PutS32(TriggerFunctionID);
            output.PutBool(ShowPickPercentText);
            output.PutEnum8(PickState);
            output.PutBool(AllowAutoGuardPick);
            output.PutS32(this.RefineSoulRadius);
            output.PutExt(this.RefineSoulSpell);
            output.PutExt(this.RefineSuccessEffect);
            output.PutUTF(this.SmallMap);
        }
        public void ReadExternal(IInputStream input)
        {
            soundType = input.GetEnum32<XmdsItemSoundType>();
            abilityType = input.GetEnum32<XmdsItemAbility>();
            effectValue = input.GetS32();
            IsTaskItem = input.GetBool();
            ItemType = input.GetEnum32<XmdsItemType>();
            PickActionName = input.GetUTF();
            PickButtonName = input.GetUTF();
            PickedRes = input.GetUTF();
            PickEffect = input.GetExt<LaunchEffect>();
            TriggerFunctionID = input.GetS32();
            ShowPickPercentText = input.GetBool();
            PickState = input.GetEnum8<XmdsItemPickState>();
            AllowAutoGuardPick = input.GetBool();
            RefineSoulRadius = input.GetS32();
            RefineSoulSpell = input.GetExt<LaunchSpell>();
            RefineSuccessEffect = input.GetExt<LaunchEffect>();
            SmallMap = input.GetUTF();
        }
    }

    [MessageType(0x000B0005)]
    [DescAttribute("技能属性")]
    [ExpandableAttribute]
    public class XmdsSkillProperties : ISkillProperties
    {
        public enum XmdsSkillLaunchType : byte
        {
            None,
            [Desc("吟唱-前摇")]
            Chat,                    //吟唱.
            [Desc("引导-持续施法")]
            Continuous,              //持续施法.
            [Desc("蓄力")]
            ChargeAttack,
        }

        public enum XmdsSkillTargetType : byte
        {
            None,
            [Desc("死亡单位-技能施法目标类型")]
            AllianceDead,            //对死亡单位有效.
            [Desc("敌方单位-技能施法目标类型")]
            Enemy,                   //对敌人.
            [Desc("友方单位(不包括自己)-技能施法目标类型")]
            Alliance,                //同盟.
            [Desc("友方单位(包括自己)-技能施法目标类型")]
            AllianceIncludeSelf,     //同盟包括自己.
            [Desc("对自己施法-技能施法目标类型")]
            Self,                   //同盟包括自己.
        }

        public enum TargetUnitType : byte
        {
            ALL = 0,
            Monster = 1,
            Player = 2,
            ExcpetPlayer = 3,
        }

        public enum SkillLaunchCondition : byte
        {
            NeedTarget,                   //必须指定一个目标.                                
            IgnoreTarget,                 //技能施放无需目标.
            IgnoreTargetAndCheckAtkRange, //无需目标但有目标时需要检测施法距离并靠近.
        }

        [DescAttribute("是否需要目标")]
        public bool NeedTarget = true;
        [DescAttribute("技能施放条件.")]
        public SkillLaunchCondition LaunchCondition = SkillLaunchCondition.IgnoreTarget;
        [Desc("目标作用类型")]
        public TargetUnitType NeedTargetType = TargetUnitType.ALL;
        [DescAttribute("是否为需要随机的普通攻击-默认否")]
        public bool IsRandomNormalAttack = false;
        [DescAttribute("技能顺序-技能面板顺序")]
        public int SkillIndex = 0;
        [DescAttribute("技能储存使用次数-技能面板顺序")]
        public byte UseTimes = 1;
		[DescAttribute("技能使用次数变更时间间隔")]
		public int AddUseTimesIntervalMS = 3000;
		[DescAttribute("技能类型-不要改,服务器配置")]
		public XmdsSkillType SkillType = XmdsSkillType.active;
        [DescAttribute("无/引导/吟唱.-技能施法类型.")]
        public XmdsSkillLaunchType LaunchType = XmdsSkillLaunchType.None;
        [DescAttribute("施法作用目标类型-技能施法目标类型.")]
        public XmdsSkillTargetType TargetType = XmdsSkillTargetType.Enemy;
        [DescAttribute("技能名字用于引导或吟唱展示-技能扩展属性.")]
        public string DisplayName = null;
        [DescAttribute("施放模式.-技能施放模式.")]
        public XmdsSkillLaunchModeData LaunchModeData = new XmdsSkillLaunchModeData();

        public XmdsSkillProperties() { }
        public override string ToString()
        {
            return "Xmds 技能扩展属性";
        }
        public object Clone()
        {
            XmdsSkillProperties ret = new XmdsSkillProperties();
            ret.NeedTarget = this.NeedTarget;
            ret.NeedTargetType = this.NeedTargetType;
            ret.IsRandomNormalAttack = this.IsRandomNormalAttack;
            ret.SkillIndex = this.SkillIndex;
            ret.UseTimes = this.UseTimes;
            ret.SkillType = this.SkillType;
            ret.LaunchType = this.LaunchType;
            ret.TargetType = this.TargetType;
            ret.DisplayName = this.DisplayName;
            ret.LaunchModeData = this.LaunchModeData;
            ret.LaunchCondition = this.LaunchCondition;
            ret.AddUseTimesIntervalMS = this.AddUseTimesIntervalMS;
            return ret;
        }
        public void WriteExternal(IOutputStream output)
        {
            output.PutBool(this.NeedTarget);
            output.PutEnum8(this.NeedTargetType);
            output.PutBool(this.IsRandomNormalAttack);
            output.PutS32(this.SkillIndex);
            output.PutU8(this.UseTimes);
            output.PutEnum8(this.SkillType);
            output.PutEnum8(this.LaunchType);
            output.PutEnum8(this.TargetType);
            output.PutUTF(this.DisplayName);
            output.PutExt(this.LaunchModeData);
            output.PutEnum8(this.LaunchCondition);
            output.PutS32(this.AddUseTimesIntervalMS);
        }
        public void ReadExternal(IInputStream input)
        {
            this.NeedTarget = input.GetBool();
            this.NeedTargetType = input.GetEnum8<XmdsSkillProperties.TargetUnitType>();
            this.IsRandomNormalAttack = input.GetBool();
            this.SkillIndex = input.GetS32();
            this.UseTimes = input.GetU8();
            this.SkillType = input.GetEnum8<XmdsSkillType>();
            this.LaunchType = input.GetEnum8<XmdsSkillLaunchType>();
            this.TargetType = input.GetEnum8<XmdsSkillTargetType>();
            this.DisplayName = input.GetUTF();
            this.LaunchModeData = input.GetExt<XmdsSkillLaunchModeData>();
            this.LaunchCondition = input.GetEnum8<SkillLaunchCondition>();
            this.AddUseTimesIntervalMS = input.GetS32();
        }

        public XmdsSkillType GetSkillType()
        {
            return this.SkillType;
        }

		public int GetSkillUseTimes()
		{
			return this.UseTimes;
		}

		public int GetSkillAddTimeInterval()
		{
			return this.AddUseTimesIntervalMS;
		}
	}

    [MessageType(0x000B0006)]
    [DescAttribute("法术属性")]
    [ExpandableAttribute]
    public class XmdsSpellProperties : ISpellProperties
    {
        [DescAttribute("Spell缩放X轴-参数设置")]
        public float FileBodyScale_X = 1.0f;
        [DescAttribute("Spell缩放Y轴-参数设置")]
        public float FileBodyScale_Y = 1.0f;
        [DescAttribute("Spell缩放Z轴-参数设置")]
        public float FileBodyScale_Z = 1.0f;

        [DescAttribute("是否为炼魂特效")]
        public bool IsRefineSoul = false;

        [Desc("目标作用类型")]
        public XmdsSkillProperties.TargetUnitType NeedTargetType = XmdsSkillProperties.TargetUnitType.ALL;

        public XmdsSpellProperties()
        {
        }
        public override string ToString()
        {
            return "Xmds 法术扩展属性";
        }
        public object Clone()
        {
            XmdsSpellProperties ret = new XmdsSpellProperties();

            ret.FileBodyScale_X = this.FileBodyScale_X;
            ret.FileBodyScale_Y = this.FileBodyScale_Y;
            ret.FileBodyScale_Z = this.FileBodyScale_Z;

            ret.NeedTargetType = this.NeedTargetType;
            ret.IsRefineSoul = this.IsRefineSoul;
            return ret;
        }
        public void WriteExternal(IOutputStream output)
        {
            output.PutF32(FileBodyScale_X);
            output.PutF32(FileBodyScale_Y);
            output.PutF32(FileBodyScale_Z);
            output.PutEnum8(this.NeedTargetType);
            output.PutBool(IsRefineSoul);
        }
        public void ReadExternal(IInputStream input)
        {
            this.FileBodyScale_X = input.GetF32();
            this.FileBodyScale_Y = input.GetF32();
            this.FileBodyScale_Z = input.GetF32();
            this.NeedTargetType = input.GetEnum8<XmdsSkillProperties.TargetUnitType>();
            this.IsRefineSoul = input.GetBool();
        }
    }

    [MessageType(0x000B0008)]
    [DescAttribute("场景属性")]
    [ExpandableAttribute]
    public class XmdsSceneProperties : ISceneProperties
    {
        [DescAttribute("机器人测试场景", "Bot")]
        public bool BotTestTemplate = false;
        [DescAttribute("别名", "扩展属性")]
        public string Alias = null;
        [DescAttribute("是否储存玩家状态", "场景属性")]
        public bool SavePlayerStatus = false;
        [DescAttribute("游戏服扩展属性", "扩展属性")]
        public XmdsServerSceneData ServerSceneData = new XmdsServerSceneData();
        [DescAttribute("场景小地图名字", "扩展属性")]
        public string SceneSmallMapName = null;
        [DescAttribute("场景AOI范围,-1为读取游戏默认配置", "扩展属性")]
        public int AOIMaxRange = -1;
        [DescAttribute("场景AOI范围,-1为读取游戏默认配置", "扩展属性")]
        public int AOIMinRange = -1;


        public XmdsSceneProperties()
        {
        }

        public void OnInit(InstanceZone owner)
        {
        }

        public byte GetAutoFightFlag()
        {
            return ServerSceneData.AllowAutoGuard;
        }

        public override string ToString()
        {
            return "Xmds 场景扩展属性";
        }

        public object Clone()
        {
            XmdsSceneProperties ret = new XmdsSceneProperties();
            ret.BotTestTemplate = this.BotTestTemplate;
            ret.Alias = this.Alias;
            ret.SavePlayerStatus = this.SavePlayerStatus;
            ret.ServerSceneData = this.ServerSceneData;
            ret.SceneSmallMapName = this.SceneSmallMapName;
            ret.AOIMaxRange = this.AOIMaxRange;
            ret.AOIMinRange = this.AOIMinRange;
            return ret;
        }
        public void WriteExternal(IOutputStream output)
        {
            output.PutBool(BotTestTemplate);
            output.PutUTF(Alias);
            output.PutBool(SavePlayerStatus);
            output.PutUTF(SceneSmallMapName);
            output.PutS32(AOIMaxRange);
            output.PutS32(AOIMinRange);
            output.PutExt(ServerSceneData);
        }
        public void ReadExternal(IInputStream input)
        {
            this.BotTestTemplate = input.GetBool();
            this.Alias = input.GetUTF();
            this.SavePlayerStatus = input.GetBool();
            this.SceneSmallMapName = input.GetUTF();
            this.AOIMaxRange = input.GetS32();
            this.AOIMinRange = input.GetS32();
            this.ServerSceneData = input.GetExt<XmdsServerSceneData>();
        }
    }

    [MessageType(0x000B0009)]
    [DescAttribute("单位触发器扩展属性")]
    [ExpandableAttribute]
    public class XmdsUnitTriggerProperties : IUnitTriggerProperties
    {
        public XmdsUnitTriggerProperties()
        {
        }
        public override string ToString()
        {
            return "Xmds 单位触发器扩展属性";
        }
        public object Clone()
        {
            return new XmdsUnitTriggerProperties();
        }
        public void WriteExternal(IOutputStream output)
        {
        }
        public void ReadExternal(IInputStream input)
        {
        }

    }

    #endregion

    #region 游戏服场景配置数据.

    /// <summary>
    /// 游戏服场景配置数据.
    /// </summary>
    [DescAttribute("游戏服场景配置数据.")]
    [MessageType(0x9001014)]
    public class XmdsServerSceneData : ICloneable, IExternalizable
    {
        public const string NORMAL_MAP = "Normal-World";
        [DescAttribute("场景单位强度", "游戏服场景配置数据.")]
        public string SceneHard = "Normal-World";
        [DescAttribute("是否计算PK值", "游戏服场景配置数据.")]
        public bool CalPKValue = true;
        [DescAttribute("是否允许自动挂机", "游戏服场景配置数据.")]
        public byte AllowAutoGuard = 0;
        [DescAttribute("是否使用空间分割", "游戏服场景配置数据.")]
        public bool UsespaceDiv = false;
        //[DescAttribute("玩法类型", "游戏服场景配置数据.")]
        //public CommonAI.Data.SceneType CurSceneType = CommonAI.Data.SceneType.Normal;
        [DescAttribute("场景类型", "游戏服场景配置数据.")]
        public CommonAI.XmdsConstConfig.AreaType CurAreaType = CommonAI.XmdsConstConfig.AreaType.None;

        public object Clone()
        {
            XmdsServerSceneData ret = new XmdsServerSceneData();
            ret.SceneHard = this.SceneHard;
            ret.CalPKValue = this.CalPKValue;
            ret.AllowAutoGuard = this.AllowAutoGuard;

            ret.CurAreaType = this.CurAreaType;
            //UsespaceDiv不做保存使用.
            return ret;
        }

        public void WriteExternal(IOutputStream output)
        {
            output.PutUTF(SceneHard);
            output.PutBool(CalPKValue);
            output.PutU8(AllowAutoGuard);
            output.PutEnum8(CurAreaType);
            //UsespaceDiv不做保存使用.
        }

        public void ReadExternal(IInputStream input)
        {
            SceneHard = input.GetUTF();
            CalPKValue = input.GetBool();
            AllowAutoGuard = input.GetU8();
            CurAreaType = input.GetEnum8<CommonAI.XmdsConstConfig.AreaType>();
            //UsespaceDiv不做保存使用.
        }
    }
    #endregion

    #region 游荡配置.

    /// <summary>
    /// 游荡配置.
    /// </summary>
    [DescAttribute("怪物停留一段时间[MinHoldTimeMS-MaxHoldTimeMS](随机),游走一段时间[MinMoveTimeMS-MaxMoveTimeMS](随机).", "游荡配置")]
    [MessageType(0x9001015)]
    public class WanderConfig : ICloneable, IExternalizable
    {
        [DescAttribute("最小停留时间(毫秒).", "游荡配置")]
        public int MinHoldTimeMS = 0;
        [DescAttribute("最大停留时间(毫秒)最大停留时间>0才启动游走", "游荡配置")]
        public int MaxHoldTimeMS = 0;
        [DescAttribute("最小游走时间(毫秒).", "游荡配置")]
        public int MinMoveTimeMS = 0;
        [DescAttribute("最大游走时间(毫秒).", "游荡配置")]
        public int MaxMoveTimeMS = 0;
        [DescAttribute(" 游荡范围.", "游荡配置")]
        public int WanderRange = 0;

        public object Clone()
        {
            WanderConfig ret = new WanderConfig();
            ret.MaxHoldTimeMS = this.MaxHoldTimeMS;
            ret.MinHoldTimeMS = this.MinHoldTimeMS;
            ret.MaxMoveTimeMS = this.MaxMoveTimeMS;
            ret.MinMoveTimeMS = this.MinMoveTimeMS;
            return ret;
        }

        public void ReadExternal(IInputStream input)
        {
            this.MaxMoveTimeMS = input.GetS32();
            this.MinMoveTimeMS = input.GetS32();
            this.MaxHoldTimeMS = input.GetS32();
            this.MinHoldTimeMS = input.GetS32();
            this.WanderRange = input.GetS32();
        }

        public void WriteExternal(IOutputStream output)
        {
            output.PutS32(this.MaxMoveTimeMS);
            output.PutS32(this.MinMoveTimeMS);
            output.PutS32(this.MaxHoldTimeMS);
            output.PutS32(this.MinHoldTimeMS);
            output.PutS32(this.WanderRange);
        }
    }

    #endregion

    #region 游戏服单位数据.

    /// <summary>
    /// 游戏单位数据.
    /// </summary>
    [MessageType(0x9001006)]
    [ExpandableAttribute]
    public class XmdsUnitData : ICloneable, IExternalizable
    {
        #region 基础属性.

        /// <summary>
        /// 单位基础信息.
        /// </summary>
        public XmdsUnitBaseInfo BaseInfo = new XmdsUnitBaseInfo();

        /// <summary>
        ///装备时装信息.
        /// </summary>
        public List<XmdsAvatarInfo> AvatarList = new List<XmdsAvatarInfo>();

        /// <summary>
        ///技能信息. 
        /// </summary>
        public XmdsUnitSkillInfo Skills = null;
		public XmdsUnitSkillInfo CardSkills = null;

		/// <summary>
		/// 单位能力属性.
		/// </summary>
		public XmdsUnitProp Prop = new XmdsUnitProp();
        public XmdsUnitProp PropExt = null;

        /// <summary>
        /// 任务数据.
        /// </summary>
        public List<XmdsQuestData> Tasks = new List<XmdsQuestData>();		

		[Desc("测试:QuestFlags")]
        public List<XmdsQuestFlag> QuestFlags = new List<XmdsQuestFlag>();

        /// <summary>
        /// PK信息.
        /// </summary>
        public PKInfo UnitPKInfo = new PKInfo();
        /// <summary>
        /// 宠物信息.
        /// </summary>
        public PetData UnitPetData = null;

        /// <summary>
        /// 单位场景相关信息.
        /// </summary>
        public SceneInfo UnitSceneInfo = new SceneInfo();

		[Desc("标记,不能设置")]
		public bool PlayerEntered = false;
        #endregion


        public XmdsUnitData()
        {

        }
        public object Clone()
        {
            XmdsUnitData ret = new XmdsUnitData();

            if (this.Prop != null) { ret.Prop = (XmdsUnitProp)this.Prop.Clone(); }
            if (this.PropExt != null) { ret.PropExt = (XmdsUnitProp)this.PropExt.Clone(); }
            if (this.Skills != null) { ret.Skills = (XmdsUnitSkillInfo)this.Skills.Clone(); }
			if (this.CardSkills != null) { ret.CardSkills = (XmdsUnitSkillInfo)this.CardSkills.Clone(); }
            if (this.BaseInfo != null) { ret.BaseInfo = (XmdsUnitBaseInfo)this.BaseInfo.Clone(); }
            if (this.AvatarList != null) { ret.AvatarList = new List<XmdsAvatarInfo>(this.AvatarList); }
            if (this.Tasks != null) { ret.Tasks = new List<XmdsQuestData>(this.Tasks); }
            ret.QuestFlags = CUtils.CloneList<XmdsQuestFlag>(this.QuestFlags);
            ret.PlayerEntered = this.PlayerEntered;
            if (UnitPKInfo != null) { ret.UnitPKInfo = (PKInfo)this.UnitPKInfo.Clone(); }
            if (UnitPetData != null) { ret.UnitPetData = (PetData)this.UnitPetData.Clone(); }
            if (UnitSceneInfo != null) { ret.UnitSceneInfo = (SceneInfo)this.UnitSceneInfo.Clone(); }
            return ret;
        }

        public void WriteExternal(IOutputStream output)
        {
            output.PutExt(this.Prop);
            output.PutExt(this.Skills);
			output.PutExt(this.CardSkills);
            output.PutExt(this.BaseInfo);
            output.PutList(this.AvatarList, output.PutExt);
            output.PutBool(this.PlayerEntered);
            output.PutExt(this.UnitPKInfo);
            output.PutExt(this.UnitPetData);
            output.PutExt(this.UnitSceneInfo);
        }

        public void ReadExternal(IInputStream input)
        {
            this.Prop = input.GetExt<XmdsUnitProp>();
            this.Skills = input.GetExt<XmdsUnitSkillInfo>();
			this.CardSkills = input.GetExt<XmdsUnitSkillInfo>();

			this.BaseInfo = input.GetExt<XmdsUnitBaseInfo>();
            this.AvatarList = input.GetList<XmdsAvatarInfo>(input.GetExt<XmdsAvatarInfo>);
            this.PlayerEntered = input.GetBool();
            this.UnitPKInfo = input.GetExt<PKInfo>();
            this.UnitPetData = input.GetExt<PetData>();
            this.UnitSceneInfo = input.GetExt<SceneInfo>();
        }
    }

    #endregion

    #region 人物基础信息.
    [MessageType(0x9001004)]
    [ExpandableAttribute]
    public class XmdsUnitBaseInfo : IExternalizable, ICloneable
    {
        //职业.
        public CommonAI.Data.XmdsUnitPro ProType = CommonAI.Data.XmdsUnitPro.None;
        //等级.
        public int UnitLv = 0;
        //名字.
        public string name = "";
        //VIP等级.
        public int VIPLv = 0;
        //称号ID.
        public int TitleID = 0;
        //服务器ID.
        public int ServerID = 0;
        //公会ID.
        public string GuildID = null;
        //公会名字.
        public string GuildName = null;
        //阵营
        public int force = 0;
        //盟友阵营
        public int alliesForce = 0;
        //遗言.
        public byte Testament = 0;
        //进阶等级.
        public byte StateLv = 0;
        //玩家服务器id
        public int logicServerId = 0;

		//玩家性别,0男,1-女
		public byte sex;

        //角色唯一ID
        public string uuid;

		//仅服务器用,
		// 药水加成
        public float potionAddition = 0;
		// 玩家职业

        //特殊状态(悬赏.)
        public CommonAI.XmdsConstConfig.SpecialState SPState = CommonAI.XmdsConstConfig.SpecialState.None;

        public void WriteExternal(IOutputStream output)
        {
            output.PutEnum8(ProType);
            output.PutS32(UnitLv);
            output.PutUTF(name);
            output.PutS32(VIPLv);
            output.PutS32(TitleID);
            output.PutS32(ServerID);
            output.PutUTF(GuildID);
            output.PutUTF(GuildName);
            output.PutVS32(force);
            output.PutU8(Testament);
            output.PutU8(StateLv);
            output.PutEnum8(SPState);
            output.PutS32(logicServerId);
            output.PutU8(sex);
            output.PutUTF(uuid);
        }

        public void ReadExternal(IInputStream input)
        {
            ProType = input.GetEnum8<CommonAI.Data.XmdsUnitPro>();
            UnitLv = input.GetS32();
            name = input.GetUTF();
            VIPLv = input.GetS32();
            TitleID = input.GetS32();
            ServerID = input.GetS32();
            GuildID = input.GetUTF();
            GuildName = input.GetUTF();
            force = input.GetVS32();
            Testament = input.GetU8();
            StateLv = input.GetU8();
            SPState = input.GetEnum8<CommonAI.XmdsConstConfig.SpecialState>();
            logicServerId = input.GetS32();
            sex = input.GetU8();
            uuid = input.GetUTF();
        }

        public object Clone()
        {
            XmdsUnitBaseInfo ret = new XmdsUnitBaseInfo();

            ret.ProType = this.ProType;
            ret.UnitLv = this.UnitLv;
            ret.name = this.name;
            ret.VIPLv = this.VIPLv;
            ret.TitleID = this.TitleID;
            ret.ServerID = this.ServerID;
            ret.GuildID = this.GuildID;
            ret.GuildName = this.GuildName;
            ret.force = this.force;
            ret.Testament = this.Testament;
            ret.StateLv = this.StateLv;
            ret.SPState = this.SPState;
            ret.logicServerId = this.logicServerId;
            ret.sex = this.sex;
            ret.potionAddition = this.potionAddition;
            ret.uuid = this.uuid;

			ret.alliesForce = this.alliesForce;
			return ret;
        }
    }

    #endregion

    #region Avatar相关信息.
    [MessageType(0x000B0010)]
    [ExpandableAttribute]
    public class XmdsAvatarInfo : IExternalizable
    {
        public enum XmdsAvatar
        {
            None,
            R_Hand_Weapon,// 主武器挂载点.
            R_Hand_Buff,//主武器特效挂载点.
            L_Hand_Weapon,//副武器挂载点.
            L_Hand_Buff,//副武器特效挂载点.
            Head_Equipment,//头部时装挂载点.
            Head_Buff,//头部特效挂载点.
            Chest_Equipment,//胸部时装挂载点.
            Chest_Buff,//胸背部特效挂载点.
            Rear_Equipment,//背部时装挂载点. 
            Rear_Buff,//背部特效挂载点.
            Foot_Equipment,//脚部时装挂载点.
            Foot_Buff,//脚部特效挂载点.  
            Tail_Equipment,// 尾巴时装挂载点.
            Tail_Buff,// 尾巴特效挂载点.
            Avatar_Body,//身体.
            Ride_Equipment //坐骑挂载点.
        }

        public XmdsAvatar PartTag = XmdsAvatar.None;
        public string FileName = null;
        public byte EffectType = 0;
        public XmdsAvatarInfo() { }

        public void WriteExternal(IOutputStream output)
        {
            output.PutS32((int)PartTag);
            output.PutUTF(FileName);
            output.PutU8(EffectType);
        }
        public void ReadExternal(IInputStream input)
        {
            PartTag = (XmdsAvatar)input.GetS32();
            FileName = input.GetUTF();
            EffectType = input.GetU8();
        }
    }

    #endregion

    #region 能力属性.

    /// <summary>
    /// 单位能力值.
    /// </summary>
    [MessageType(0x9001003)]
    [Expandable]
    public class XmdsUnitProp : ICloneable, IExternalizable
    {
        private const int DEFAULT_VALUE = -1;

        public const float PER = 0.0001f;

        /// <summary>
        ///基础血量.
        /// </summary>
        public int BaseMaxHP = 0;

        /// <summary>
        /// 生命%
        /// </summary>
        public int HPPer;

        /// <summary>
        ///最大血量.
        /// </summary>
        public int MaxHP { get { return CUtils.CastInt((double)BaseMaxHP * (1.0f + HPPer * 0.0001f)); } }

        /// <summary>
        /// 当前血量.
        /// </summary>
        public int HP = 0;
        /* ------------------------------------------------------------------------------------------------ */
        /// <summary>
        ///攻击基础值.
        /// </summary>
        public int BaseAttack = 0;

        /// <summary>
        /// 最大攻击%
        /// </summary>
        public int AttackPer; 

        /// <summary>
        ///最大攻击
        /// </summary>
        public int MaxAttack { get { return CUtils.CastInt(BaseAttack * (1 + AttackPer * 0.0001f)); } }

        /* ------------------------------------------------------------------------------------------------ */
        /// <summary>
        /// 基础防御
        /// </summary>
        public int BaseDefence;

        /// <summary>
        /// 按百分比增加防御
        /// </summary>
        public int DefencePer;

        /// <summary>
        /// 防御
        /// </summary>
        public int Defence { get { return CUtils.CastInt(BaseDefence * (1 + DefencePer * 0.0001f)); } }
        /* ------------------------------------------------------------------------------------------------ */
        /// <summary>
        ///无视防御基础值(穿透)
        /// </summary>
        public int BaseIgnoreDefense;

        /// <summary>
        ///无视防御百分比(穿透)
        /// </summary>
        public int IgnoreDefensePer;

        /// <summary>
        ///无视防御(穿透)
        /// </summary>
        public int IgnoreDefense { get { return BaseIgnoreDefense; } }
        /* ------------------------------------------------------------------------------------------------ */

        /// <summary>
        ///基础抗暴.
        /// </summary>
        public int BaseResCrit;

        /// <summary>
        /// 抗暴%
        /// </summary>
        public int ResCritPer;

        /// <summary>
        /// 抗暴.
        /// </summary>
        public int ResCrit { get { return CUtils.CastInt(BaseResCrit * (1 + ResCritPer * 0.0001f)); } }

        /// <summary>
        /// 抗暴率
        /// </summary>
        public int ResCritRate;

        /* ------------------------------------------------------------------------------------------------ */

        /// <summary>
        /// 暴击率.
        /// </summary>
        public int CritRate;

        /// <summary>
        ///暴击伤害加成百分比 
        /// </summary>
        public int CritDamage = 0;

        /// <summary>
        ///受到暴击伤害减少百分比 
        /// </summary>
        public int CritDamageRes = 0;
        /* ------------------------------------------------------------------------------------------------ */

        /// <summary>
        /// 玩家间伤害加成百分比 
        /// </summary>
        public int PlayerDamageAdd;

		/// <summary>
		/// 玩家间受到伤害减免%
		/// </summary>
		public int PlayerDamageReduce;

		/// <summary>
		/// 所有控制效果包括减速、冻结、眩晕、禁锢等的时间,按百分比减少
		/// </summary>
		public int CtrlTimeReduce = 0;

        /// <summary>
        /// 所有技能的冷却时间减少百分比
        /// </summary>
        public int SkillCD = 0;

        /// <summary>
        ///血量恢复值.
        ///</summary>
        public int HPReborn = 0;


		/// <summary>
		///血量恢复百分比
		///</summary>
		public int HPRecoverPer = 0;


		/// <summary>
		/// 最终生命恢复值
		/// </summary>
		public int MaxHPReborn { get { return CUtils.CastInt(HPReborn * (1 + HPRecoverPer * 0.0001f)); } }

		/// <summary>
		///治疗效果影响百分比.
		/// </summary>
		public int HealEffect = 0;

        /// <summary>
        ///受治疗效果影响百分比.
        /// </summary>
        public int HealedEffect = 0;

        /// <summary>
        ///移动速度.
        /// </summary>
        public float MoveSpeed = 0;

        /// <summary>
        ///速度加成(装备+坐骑的百分比加成).
        /// </summary>
        public int VelocityAddition = 0;

        /// <summary>
        /// 当前背包可用数量.
        /// </summary>
        public int CurInventorySize;
        /// <summary>
        /// 当前队伍背包数量.
        /// </summary>
        public int CurTeamInventorySize;

        /// <summary>
        /// 拾取范围,只在JJC生效,我也不知道是哪个SB想出来的
        /// </summary>
        public int pickupRange = 0;

        /* ------------------------------------------------------------------------------------------------ */
        /// <summary>
        /// 技能伤害加成
        /// </summary>
        public int SkillDamageAdd = 0;

        /// <summary>
        /// 攻速, 正常10000,变化万分之N, 修改普攻的冷却缩减时间
        /// </summary>
        public int AttackSpeed;

        /// <summary>
        /// 控制增幅
        /// </summary>
        public int ControlUp;

        /// <summary>
        /// 神器伤害加成比
        /// </summary>
        public int ArtifactMainPer;


        //元素攻击 & 防御 & 克制 & 抵御
        public int [] ArtifactAttack = new int[5];
        public int [] ArtifactDefense = new int[5];
		/** 克制 */
        public int [] ArtifactRestraint = new int[5];
		/** 抵御 */
        public int [] ArtifactResist = new int[5];
        
        //boss伤害
        public int ToBossCritRate;
        public int ToBossCritDamage;

        /// <summary>
        /// 杀意,增加伤害百分比
        /// </summary>
        public int KillValuePer;

        /// <summary>
        /// 妖气等级
        /// </summary>
        public int YaoQiLevel;

        /// <summary>
        /// 普攻吸血
        /// </summary>
        public int NormalAtkLeech;
        /// <summary>
        /// 技能吸血
        /// </summary>
        public int ActiveAtkLeech;

		//MMO-14631: 2121.3.23 FieldBossDamageAdd对全部怪物增伤
		/// <summary>
		/// 野外boss伤害增益 -> 【全部怪物增伤】
		/// </summary>
		public int monsterDamageAdd;

		/// <summary>
		/// MMO-14873: 2021.3.30 调整成怪物伤害减免
		/// 副本小怪伤害增益 ->【怪物伤害减免】
		/// </summary>
		public int monsterDamageReduce;

		//命格伤害加成
		public int [] MonsterRestraint = new int[(int)UnitFateType.Five];

		// 天命属性
		public UnitFateType fateType;
		public int fateValue;

		//神器,背饰
		public int ArtifactIndex = -1;
		public int ArtifactDefenceIndex = -1;

		//所有单位增伤,减伤
		public int AllDmgAdd;
		public int AllDmgReduce;

		// 破定值
		public int BreakShieldValue;
		//定力值
		public int ShieldValue;

		//新增属性
		public int monsterAtk;				// 猎妖攻
		public int monsterDef;				// 猎妖防
		public int monsterAtkPer;           // 猎妖攻百分比
		public int monsterDefPer;			// 猎妖防百分比
		public int MaxMonsterAttack { get { return CUtils.CastInt(monsterAtk * (1 + monsterAtkPer * 0.0001f)); } }
		public int MaxMonsterDef { get { return CUtils.CastInt(monsterDef * (1 + monsterDefPer * 0.0001f)); } }

		///////////////////////////////////////////////////////////////////////////////////////////
		/// 为实现技能或者buff特殊逻辑,加上的特殊字段
		public int NormalAtkCriteRate;                  //普攻暴击几率
														///////////////////////////////////////////////////////////////////////////////////////////

		//获取攻击力
		public int GetFinalAttack(bool isMonster)
		{
			if (isMonster)
			{
				return MaxAttack + MaxMonsterAttack;
			}
			else
			{
				return MaxAttack;
			}
		}


		public object Clone()
        {
            XmdsUnitProp ret = new XmdsUnitProp();
            ret.BaseMaxHP = this.BaseMaxHP;
            ret.HPPer = this.HPPer;
            ret.HP = this.HP;

            ret.BaseAttack = this.BaseAttack;
            ret.AttackPer = this.AttackPer;

            ret.BaseDefence = this.BaseDefence;
            ret.DefencePer = this.DefencePer;
            ret.BaseIgnoreDefense = this.BaseIgnoreDefense;
            ret.IgnoreDefensePer = this.IgnoreDefensePer;

            ret.BaseResCrit = this.BaseResCrit;
            ret.ResCritPer = this.ResCritPer;
            ret.ResCritRate = this.ResCritRate;
            ret.CritRate = this.CritRate;

            ret.CritDamage = this.CritDamage;
            ret.CritDamageRes = this.CritDamageRes;

            ret.PlayerDamageAdd = this.PlayerDamageAdd;
            ret.PlayerDamageReduce = this.PlayerDamageReduce;
            ret.CtrlTimeReduce = this.CtrlTimeReduce;
            ret.SkillCD = this.SkillCD;

            ret.HPReborn = this.HPReborn;
			ret.HPRecoverPer = this.HPRecoverPer;

            ret.HealEffect = this.HealEffect;
            ret.HealedEffect = this.HealedEffect;
            ret.MoveSpeed = this.MoveSpeed;
            ret.VelocityAddition = this.VelocityAddition;

            ret.CurInventorySize = this.CurInventorySize;
            ret.CurTeamInventorySize = this.CurTeamInventorySize;

            ret.pickupRange = this.pickupRange;

            ret.SkillDamageAdd = this.SkillDamageAdd;
            ret.AttackSpeed = this.AttackSpeed;
            ret.ControlUp = this.ControlUp;
            ret.ArtifactMainPer = this.ArtifactMainPer;

            //元素攻击 & 防御 & 克制 & 抵御
            ret.ArtifactAttack = (int[])this.ArtifactAttack.Clone();
            ret.ArtifactDefense = (int[])this.ArtifactDefense.Clone();
            ret.ArtifactRestraint = (int[])this.ArtifactRestraint.Clone();
            ret.ArtifactResist = (int[])this.ArtifactResist.Clone();

            ret.ToBossCritRate = this.ToBossCritRate;
            ret.ToBossCritDamage = this.ToBossCritDamage;

            ret.KillValuePer = this.KillValuePer;
			ret.YaoQiLevel = this.YaoQiLevel;
            ret.NormalAtkLeech = this.NormalAtkLeech;
            ret.ActiveAtkLeech = this.ActiveAtkLeech;

            ret.monsterDamageAdd = this.monsterDamageAdd;
            ret.monsterDamageReduce = this.monsterDamageReduce;

			ret.fateType = this.fateType;
			ret.fateValue = this.fateValue;

			ret.ArtifactIndex = this.ArtifactIndex;
			ret.ArtifactDefenceIndex = this.ArtifactDefenceIndex;

			ret.AllDmgAdd = this.AllDmgAdd;
			ret.AllDmgReduce = this.AllDmgReduce;

			for (int i = 0; i < (int)UnitFateType.Five; i++)
			{
				ret.MonsterRestraint[i] = this.MonsterRestraint[i];
			}

			ret.BreakShieldValue = this.BreakShieldValue;
			ret.ShieldValue = this.ShieldValue;

			ret.monsterAtk = this.monsterAtk;
			ret.monsterDef = this.monsterDef;
			ret.monsterAtkPer = this.monsterAtkPer;
			ret.monsterDefPer = this.monsterDefPer;

			return ret;
        }

        public void AddTo(XmdsUnitProp prop)
        {
            this.BaseMaxHP += prop.BaseMaxHP;
            this.HPPer += prop.HPPer;
            this.HP += prop.HP;

            this.BaseAttack += prop.BaseAttack;
            this.AttackPer += prop.AttackPer;

            this.BaseDefence += prop.BaseDefence;
            this.DefencePer += prop.DefencePer;
            this.BaseIgnoreDefense += prop.BaseIgnoreDefense;
            this.IgnoreDefensePer += prop.IgnoreDefensePer;

            this.BaseResCrit += prop.BaseResCrit;
            this.ResCritPer += prop.ResCritPer;
            this.ResCritRate += prop.ResCritRate;
            this.CritRate += prop.CritRate;

            this.CritDamage += prop.CritDamage;
            this.CritDamageRes += prop.CritDamageRes;

            this.PlayerDamageAdd += prop.PlayerDamageAdd;
            this.PlayerDamageReduce += prop.PlayerDamageReduce;
            this.CtrlTimeReduce += prop.CtrlTimeReduce;
            this.SkillCD += prop.SkillCD;

            this.HPReborn += prop.HPReborn;
			this.HPRecoverPer += prop.HPRecoverPer;

            this.HealEffect += prop.HealEffect;
            this.HealedEffect += prop.HealedEffect;
            this.MoveSpeed += prop.MoveSpeed;
            this.VelocityAddition += prop.VelocityAddition;

            this.CurInventorySize += prop.CurInventorySize;
            this.CurTeamInventorySize += prop.CurTeamInventorySize;

            this.pickupRange += prop.pickupRange;

            this.SkillDamageAdd += prop.SkillDamageAdd;
            this.AttackSpeed += prop.AttackSpeed;
            this.ControlUp += prop.ControlUp;
            this.ArtifactMainPer += prop.ArtifactMainPer;

            //元素攻击 & 防御 & 克制 & 抵御
            for(int i = 0; i < 5; i++)
            {
                this.ArtifactAttack[i] += prop.ArtifactAttack[i];
                this.ArtifactDefense[i] += prop.ArtifactDefense[i];
                this.ArtifactRestraint[i] += prop.ArtifactRestraint[i];
                this.ArtifactResist[i] += prop.ArtifactResist[i];
            }
           

            this.ToBossCritRate += prop.ToBossCritRate;
            this.ToBossCritDamage += prop.ToBossCritDamage;

            this.KillValuePer += prop.KillValuePer;
            this.YaoQiLevel += prop.YaoQiLevel;
            this.NormalAtkLeech += prop.NormalAtkLeech;
            this.ActiveAtkLeech += prop.ActiveAtkLeech;

            this.monsterDamageAdd += prop.monsterDamageAdd;
            this.monsterDamageReduce += prop.monsterDamageReduce;

			this.AllDmgAdd += prop.AllDmgAdd;
			this.AllDmgReduce += prop.AllDmgReduce;

			for (int i = 0; i < (int)UnitFateType.Five; i++)
			{
				this.MonsterRestraint[i] += prop.MonsterRestraint[i];
			}

			this.BreakShieldValue += prop.BreakShieldValue;
			this.ShieldValue += prop.ShieldValue;

			//猎妖值
			this.monsterAtk += prop.monsterAtk;
			this.monsterDef += prop.monsterDef;
			this.monsterAtkPer += prop.monsterAtkPer;
			this.monsterDefPer += prop.monsterDefPer;
		}

        public void WriteExternal(IOutputStream output)
        {
            output.PutS32(this.BaseMaxHP);
            output.PutS32(this.HPPer);
            output.PutS32(this.HP);

            output.PutS32(this.BaseAttack);
            output.PutS32(this.AttackPer);

            output.PutS32(this.BaseDefence);
            output.PutS32(this.DefencePer);
            output.PutS32(this.BaseIgnoreDefense);
            output.PutS32(this.IgnoreDefensePer);

            output.PutS32(this.CritRate);

            output.PutS32(this.BaseResCrit);
            output.PutS32(this.ResCritPer);
            output.PutS32(this.ResCritRate);

            output.PutS32(this.CritDamage);
            output.PutS32(this.CritDamageRes);

            output.PutS32(this.PlayerDamageAdd);
            output.PutS32(this.PlayerDamageReduce);
            output.PutS32(this.CtrlTimeReduce);
            output.PutS32(this.SkillCD);

            output.PutS32(this.HPReborn);

            output.PutS32(this.HealEffect);
            output.PutS32(this.HealedEffect);
            output.PutF32(this.MoveSpeed);
            output.PutS32(this.VelocityAddition);

            output.PutS32(this.CurInventorySize);
            output.PutS32(this.CurTeamInventorySize);

            output.PutS32(this.pickupRange);

            output.PutS32(this.SkillDamageAdd);
            output.PutS32(this.AttackSpeed);
            output.PutS32(this.ControlUp);
            output.PutS32(this.ArtifactMainPer);

            for(int i = 0; i < 5; i++)
            {
                output.PutS32(this.ArtifactAttack[i]);
                output.PutS32(this.ArtifactDefense[i]);
                output.PutS32(this.ArtifactRestraint[i]);
                output.PutS32(this.ArtifactResist[i]);
            }

            output.PutS32(this.ToBossCritRate);
            output.PutS32(this.ToBossCritDamage);

            output.PutS32(this.KillValuePer);
            output.PutS32(this.YaoQiLevel);
            output.PutS32(this.NormalAtkLeech);
            output.PutS32(this.ActiveAtkLeech);

			for (int i = 0; i < (int)UnitFateType.Five; i++)
			{
				output.PutS32(this.MonsterRestraint[i]);
			}

			output.PutS32(this.BreakShieldValue);

			// 猎妖值
			output.PutS32(this.monsterAtk);
			output.PutS32(this.monsterDef);
			output.PutS32(this.monsterAtkPer);
			output.PutS32(this.monsterDefPer);
		}

        public void ReadExternal(IInputStream input)
        {
            this.BaseMaxHP = input.GetS32();
            this.HPPer = input.GetS32();
            this.HP = input.GetS32();

            this.BaseAttack = input.GetS32();
            this.AttackPer = input.GetS32();

            this.BaseDefence = input.GetS32();
            this.DefencePer = input.GetS32();
            this.BaseIgnoreDefense = input.GetS32();
            this.IgnoreDefensePer = input.GetS32();

            this.CritRate = input.GetS32();

            this.BaseResCrit = input.GetS32();
            this.ResCritPer = input.GetS32();
            this.ResCritRate = input.GetS32();

            this.CritDamage = input.GetS32();
            this.CritDamageRes = input.GetS32();

            this.PlayerDamageAdd = input.GetS32();
            this.PlayerDamageReduce = input.GetS32();
            this.CtrlTimeReduce = input.GetS32();
            this.SkillCD = input.GetS32();

            this.HPReborn = input.GetS32();

            this.HealEffect = input.GetS32();
            this.HealedEffect = input.GetS32();
            this.MoveSpeed = input.GetF32();
            this.VelocityAddition = input.GetS32();

            this.CurInventorySize = input.GetS32();
            this.CurTeamInventorySize = input.GetS32();

            this.pickupRange = input.GetS32();

            this.SkillDamageAdd = input.GetS32();
            this.AttackSpeed = input.GetS32();
            this.ControlUp = input.GetS32();
            this.ArtifactMainPer = input.GetS32();

            for (int i = 0; i < 5; i++)
            {
                this.ArtifactAttack[i] = input.GetS32();
                this.ArtifactDefense[i] = input.GetS32();
                this.ArtifactRestraint[i] = input.GetS32();
                this.ArtifactResist[i] = input.GetS32();
            }

            this.ToBossCritRate = input.GetS32();
            this.ToBossCritDamage = input.GetS32();

            this.KillValuePer = input.GetS32();
            this.YaoQiLevel = input.GetS32();
            this.NormalAtkLeech = input.GetS32();
            this.ActiveAtkLeech = input.GetS32();

			for (int i = 0; i < (int)UnitFateType.Five; i++)
			{
				this.MonsterRestraint[i] = input.GetS32();
			}

			this.BreakShieldValue = input.GetS32();

			// 猎妖值
			this.monsterAtk = input.GetS32();
			this.monsterDef = input.GetS32();
			this.monsterAtkPer = input.GetS32();
			this.monsterDefPer = input.GetS32();
		}
	}

    #endregion

    #region 单位技能信息集合.

    /// <summary>
    /// 单位技能信息集合.
    /// </summary>
    [MessageType(0x9001002)]
    [ExpandableAttribute]
    public class XmdsUnitSkillInfo : ICloneable, IExternalizable
    {
        public List<GameSkill> UnitSkills = null;
        public XmdsUnitSkillInfo()
        {
        }

        public object Clone()
        {
            XmdsUnitSkillInfo ret = new XmdsUnitSkillInfo();
            ret.UnitSkills = CUtils.CloneList<GameSkill>(this.UnitSkills);
            return ret;
        }

        public void WriteExternal(IOutputStream output)
        {
            output.PutList<GameSkill>(this.UnitSkills, output.PutExt);
        }

        public void ReadExternal(IInputStream input)
        {
            this.UnitSkills = input.GetList<GameSkill>(input.GetExt<GameSkill>);
        }
    }

    [MessageType(0x9001005)]
    [ExpandableAttribute]
    public class GameSkill : ICloneable, IExternalizable
    {
        //默认为主动技能.
        public XmdsSkillType SkillType = XmdsSkillType.active;
        //技能ID.
        public int SkillID = 0;
        //技能等级.
        public int SkillLevel = 1;
		//天赋技能等级.
		//斩妖特殊含义:冷却时间减少,触发几率增加,持续时间增加
		public int TalentSkillLevel1 = 1;
        public int TalentSkillLevel2 = 1;
        public int TalentSkillLevel3 = 1;
        //技能到期时间戳.
        public long SkillTimestampMS = 0;
        //CD时间变更万分比.
        public int SkillCDDecreasePercent = 0;
        //是否允许自动释放.
        public bool AutoLaunch = true;

        //战斗命中人数
        public HashMap<uint, int> mHitUnits = new HashMap<uint, int>();

        public GameSkill() { }

        public GameSkill(int skillId)
        {
            this.SkillID = skillId;
        }

        public GameSkill(int skillId, XmdsSkillType type, bool autoLaunch = true)
        {
            this.SkillID = skillId;
            this.SkillType = type;
			this.AutoLaunch = autoLaunch;
		}

		// 被动只有一个等级
		public int GetPassiveLevel()
		{
			return this.SkillLevel + this.TalentSkillLevel1;
		}

        public object Clone()
        {
            GameSkill ret = new GameSkill();
            ret.SkillID = this.SkillID;
            ret.SkillLevel = this.SkillLevel;
            ret.SkillType = this.SkillType;
            ret.TalentSkillLevel1 = this.TalentSkillLevel1;
            ret.TalentSkillLevel2 = this.TalentSkillLevel2;
            ret.TalentSkillLevel3 = this.TalentSkillLevel3;
            ret.SkillTimestampMS = this.SkillTimestampMS;
            ret.SkillCDDecreasePercent = this.SkillCDDecreasePercent;
            ret.AutoLaunch = this.AutoLaunch;
            return ret;
        }

        public void WriteExternal(IOutputStream output)
        {
            output.PutS32(SkillID);
            output.PutS32(SkillLevel);
            output.PutEnum8(SkillType);
            output.PutS32(TalentSkillLevel1);
            output.PutS64(SkillTimestampMS);
            output.PutS32(SkillCDDecreasePercent);
            output.PutBool(AutoLaunch);
        }

        public void ReadExternal(IInputStream input)
        {
            this.SkillID = input.GetS32();
            this.SkillLevel = input.GetS32();
            this.SkillType = input.GetEnum8<XmdsSkillType>();
            this.TalentSkillLevel1 = input.GetS32();
            this.SkillTimestampMS = input.GetS64();
            this.SkillCDDecreasePercent = input.GetS32();
            this.AutoLaunch = input.GetBool();
        }
    }


    [Desc("施法区域提示")]
    [MessageType(0x900100A)]
    [ExpandableAttribute]
    public class XmdsSkillLaunchModeData : ICloneable, IExternalizable
    {
        public enum XmdsSkillLaunchMode : byte
        {
            [Desc("普通模式")]
            Mode_None,
            [Desc("箭头模式")]
            Mode_Arrow,
            [Desc("扇形模式")]
            Mode_Fan,
            [Desc("区域模式")]
            Mode_Area,
            [Desc("缠绕")]
            Mode_Twine,
        }

        [Desc("施法模式")]
        public XmdsSkillLaunchMode Mode = XmdsSkillLaunchMode.Mode_None;
        [Desc("技能范围半径")]
        public float Shape_Radius = 0;
        [Desc("箭头模式下代表箭头宽度")]
        public float Shape_Width = 0;
        [Desc("扇形模式下代表扇形展开范围")]
        public int Shape_Angle = 0;
        [Desc("施放点和单位中心点偏移距离")]
        public float Shape_LaunchCenterOffset = 0;
        [Desc("缠绕非中心圆的长")]
        public float TwineNotCircleLength = 0;
        [Desc("缠绕非中心圆的宽")]
        public float TwineNotCircleWidth = 0;
        [Desc("缠绕中心圆的缩放比")]
        public float TwineCircleScale = 0;
        [Desc("显示施法引导")]
        public bool ShowLaunchGuide = false;

        public object Clone()
        {
            XmdsSkillLaunchModeData ret = new XmdsSkillLaunchModeData();

            ret.Mode = this.Mode;
            ret.Shape_Radius = this.Shape_Radius;
            ret.Shape_Angle = this.Shape_Angle;
            ret.Shape_Width = this.Shape_Width;
            ret.Shape_LaunchCenterOffset = this.Shape_LaunchCenterOffset;
            ret.TwineNotCircleLength = this.TwineNotCircleLength;
            ret.TwineNotCircleWidth = this.TwineNotCircleWidth;
            ret.TwineCircleScale = this.TwineCircleScale;
            ret.ShowLaunchGuide = this.ShowLaunchGuide;
            return ret;
        }

        public void WriteExternal(IOutputStream output)
        {
            output.PutEnum8(Mode);
            output.PutF32(Shape_Radius);
            output.PutS32(Shape_Angle);
            output.PutF32(Shape_Width);
            output.PutF32(Shape_LaunchCenterOffset);
            output.PutF32(TwineNotCircleLength);
            output.PutF32(TwineNotCircleWidth);
            output.PutF32(TwineCircleScale);
            output.PutBool(ShowLaunchGuide);
        }

        public void ReadExternal(IInputStream input)
        {
            Mode = input.GetEnum8<XmdsSkillLaunchMode>();
            Shape_Radius = input.GetF32();
            Shape_Angle = input.GetS32();
            Shape_Width = input.GetF32();
            Shape_LaunchCenterOffset = input.GetF32();
            TwineNotCircleLength = input.GetF32();
            TwineNotCircleWidth = input.GetF32();
            TwineCircleScale = input.GetF32();
            ShowLaunchGuide = input.GetBool();
        }
    }
    #endregion

    #region PK相关数据.

    /// <summary>
    /// 单位PK信息..
    /// </summary>
    [MessageType(0x9001010)]
    [ExpandableAttribute]
    public class PKInfo : ICloneable, IExternalizable
    {
        //当前PK等级.
        public PKLevel CurPKLevel = PKLevel.White;
        //当前PK模式.
        public PKMode CurPKMode = PKMode.Peace;
        //当前PK值.
        public int CurPKValue = 0;
        public object Clone()
        {
            PKInfo ret = new PKInfo();

            ret.CurPKLevel = this.CurPKLevel;
            ret.CurPKMode = this.CurPKMode;
            ret.CurPKValue = this.CurPKValue;

            return ret;
        }

        public void ReadExternal(IInputStream input)
        {
            this.CurPKLevel = input.GetEnum8<PKLevel>();
            this.CurPKMode = input.GetEnum8<PKMode>();
            this.CurPKValue = input.GetS32();
        }

        public void WriteExternal(IOutputStream output)
        {
            output.PutEnum8(CurPKLevel);
            output.PutEnum8(CurPKMode);
            output.PutS32(CurPKValue);
        }
    }

    #endregion

    #region Buff容器.

    public abstract class XmdsBuffVirtual : IDisposable
    {

        private static AtomicInteger s_alloc_object_count = new AtomicInteger(0);
        private static AtomicInteger s_active_object_count = new AtomicInteger(0);
        public static int AllocCount { get { return s_alloc_object_count.Value; } }
        public static int ActiveCount { get { return s_active_object_count.Value; } }

        private bool mDisposed = false;

        public XmdsBuffVirtual()
        {
            s_alloc_object_count++;
            s_active_object_count++;
        }
        ~XmdsBuffVirtual()
        {
            s_alloc_object_count--;
        }
        public void Dispose()
        {
            if (mDisposed) { return; }
            mDisposed = true;
            OnDispose();
            s_active_object_count--;
        }
        protected virtual void OnDispose() { }
    }

    #endregion

    #region 任务数据.
    [MessageType(0x9001008)]
    [ExpandableAttribute]
    public class QuestAttribute : ICloneable, IExternalizable
    {
        public string Key;
        public string Value;
        public void WriteExternal(IOutputStream output)
        {
            output.PutUTF(Key);
            output.PutUTF(Value);
        }

        public void ReadExternal(IInputStream input)
        {
            this.Key = input.GetUTF();
            this.Value = input.GetUTF();
        }

        public object Clone()
        {
            QuestAttribute ret = new QuestAttribute();
            ret.Key = this.Key;
            ret.Value = this.Value;
            return ret;
        }
    }


    [MessageType(0x9001007)]
    [ExpandableAttribute]
    public class XmdsQuestData : ICloneable, IExternalizable
    {
        /// <summary>
        /// 任务ID.
        /// </summary>
        [DescAttribute("任务ID")]
        public string TaskID = null;

        /// <summary>
        /// 任务状态.
        /// </summary>
        [DescAttribute("任务状态")]
        public string TaskState = null;
        public List<QuestAttribute> Attributes = null;

        //子状态, 1: 任务目标已达成
        public static readonly string Attribute_SubState = "state";
        //任务类型
        public static readonly string Attribute_TaskType = "type";
        //目标ID
        public static readonly string Attribute_TargetId = "targetId";
        //目标场景
        public static readonly string Attribute_AreaId = "areaId";
        //目标路点
        public static readonly string Attribute_PointId = "pointId";
        //任务完成目标的需求数量
        //public static readonly string Attribute_TargetNum = "targetNum";
        //任务进度
        //public static readonly string Attribute_Progress = "progress";

        //添加任务进度数量
        public static readonly string Attribute_AddProgress = "add_progress";

        //自定义属性,表示战斗服接收游戏服初始数据完成
        public static readonly string Attribute_InitOK = "INIT_OK";


        public enum TaskType : int
        {
            Kill = 1,
            InterActiveUnit = 2,
            InterActiveItem = 3,
            Got = 4,
            Convoy = 5, //护送
            Guard = 6,  //守护
            Area = 7, //到达指定区域
            KillPlayer = 8, //杀人
            Challenge = 25, //挑战
            ConqueringtheDemons = 26, //伏魔
            Steal = 27,  //偷窃
            RefineSoul = 28, //炼魂
            CatchPet = 29, //抓宠
            Treasure = 30, //寻宝
        }

        public static int GetTaskTypeByString(string typeValue)
        {
            int ret = 0;
            int.TryParse(typeValue, out ret);
            return ret;
        }

        public static int GetTaskType(QuestData qData)
        {
            string taskType = qData.Attributes.Get(XmdsQuestData.Attribute_TaskType);
            return GetTaskTypeByString(taskType);
        }

        public static int GetTargetSceneID(QuestData qData)
        {
            string areaId = qData.Attributes.Get(XmdsQuestData.Attribute_AreaId);
            int result = 0;
            if (!string.IsNullOrEmpty(areaId))
            {
                Int32.TryParse(areaId, out result);
            }
            return result;
        }

        public static string GetTargetScenePoint(QuestData qData)
        {
            return qData.Attributes.Get(XmdsQuestData.Attribute_PointId);
        }

        public static string GetTarget(QuestData qData)
        {
            return qData.Attributes.Get(XmdsQuestData.Attribute_TargetId);
        }

        /// <summary>
        /// 获取目标总数量
        /// </summary>
        /// <param name="qData"></param>
        /// <returns></returns>
        //public static int GetTargetQuantity(QuestData qData)
        //{
        //    string str = qData.Attributes.Get(QuestData.Attribute_TargetNum);
        //    int result = 0;
        //    if (!string.IsNullOrEmpty(str))
        //    {
        //        Int32.TryParse(str, out result);
        //    }
        //    return result;
        //}

        /// <summary>
        /// 获取进度
        /// </summary>
        /// <param name="qData"></param>
        /// <returns></returns>
        //public static int GetProgress(QuestData qData)
        //{
        //    string str = qData.Attributes.Get(QuestData.Attribute_Progress);
        //    int result = 0;
        //    if (!string.IsNullOrEmpty(str))
        //    {
        //        Int32.TryParse(str, out result);
        //    }
        //    return result;
        //}


        public static int GetTargetID(QuestData qData)
        {
            string targetId = qData.Attributes.Get(XmdsQuestData.Attribute_TargetId);
            int result = 0;
            if (!string.IsNullOrEmpty(targetId))
            {
                Int32.TryParse(targetId, out result);
            }
            return result;
        }

        /// <summary>
        /// 返回任务目标是否已达成
        /// </summary>
        public static bool IsTargetComplete(QuestData qData)
        {
            string state = qData.Attributes.Get(XmdsQuestData.Attribute_SubState);
            return (!string.IsNullOrEmpty(state) && state == "1");

        }

        public void AddAttribute(string key, string value)
        {
            if (Attributes == null)
            {
                Attributes = new List<QuestAttribute>();
            }
            QuestAttribute attr = new QuestAttribute();
            attr.Key = key;
            attr.Value = value;
            Attributes.Add(attr);
        }

        public void WriteExternal(IOutputStream output)
        {
            output.PutUTF(TaskID);
            output.PutUTF(TaskState);
            output.PutList<QuestAttribute>(this.Attributes, output.PutExt);

        }

        public void ReadExternal(IInputStream input)
        {
            this.TaskID = input.GetUTF();
            this.TaskState = input.GetUTF();
            this.Attributes = input.GetList<QuestAttribute>(input.GetExt<QuestAttribute>);
        }

        public object Clone()
        {
            XmdsQuestData ret = new XmdsQuestData();

            ret.TaskID = this.TaskID;
            ret.TaskState = this.TaskState;

            return ret;
        }
    }

    [MessageType(0x9001009)]
    [ExpandableAttribute]
    public class XmdsQuestFlag : ICloneable, IExternalizable
    {
        public string FlagName = "flag_name";
        public string FlagValue = null;

        public void WriteExternal(IOutputStream output)
        {
            output.PutUTF(FlagName);
            output.PutUTF(FlagValue);
        }
        public void ReadExternal(IInputStream input)
        {
            this.FlagName = input.GetUTF();
            this.FlagValue = input.GetUTF();
        }
        public object Clone()
        {
            XmdsQuestFlag ret = new XmdsQuestFlag();
            ret.FlagName = this.FlagName;
            ret.FlagValue = this.FlagValue;
            return ret;
        }
        public override string ToString()
        {
            return FlagName + " = " + FlagValue;
        }
    }


    #endregion

    #region  宠物相关
    [MessageType(0x9001011)]
    [ExpandableAttribute]
    public class PetData : ICloneable, IExternalizable
    {
        //宠物配置信息.
        public XmdsPetConifg PetConfig = null;
        //基础信息.
        public PetBaseInfo BaseInfo = null;
        //能力属性.
        public XmdsUnitProp UnitProp = null;
        //技能信息.
        public XmdsUnitSkillInfo SkillInfo = null;

        public object Clone()
        {
            PetData ret = new PetData();

            if (this.BaseInfo != null)
                ret.BaseInfo = (PetBaseInfo)this.BaseInfo.Clone();
            if (this.UnitProp != null)
                ret.UnitProp = (XmdsUnitProp)this.UnitProp.Clone();
            if (SkillInfo != null)
                ret.SkillInfo = (XmdsUnitSkillInfo)this.SkillInfo.Clone();
            if (PetConfig != null)
                ret.PetConfig = (XmdsPetConifg)this.PetConfig.Clone();

            return ret;
        }

        public void ReadExternal(IInputStream input)
        {
            BaseInfo = input.GetExt<PetBaseInfo>();
            UnitProp = input.GetExt<XmdsUnitProp>();
            SkillInfo = input.GetExt<XmdsUnitSkillInfo>();
            PetConfig = input.GetExt<XmdsPetConifg>();
        }

        public void WriteExternal(IOutputStream output)
        {
            output.PutExt(BaseInfo);
            output.PutExt(UnitProp);
            output.PutExt(SkillInfo);
            output.PutExt(PetConfig);
        }
    }

    /// <summary>
    /// 基础信息.
    /// </summary>
    [MessageType(0x9001012)]
    [ExpandableAttribute]
    public class PetBaseInfo : ICloneable, IExternalizable
    {
        //名字.
        public string name = "揍我啊";
        //等级.
        public int level = 1;
        //品质.
        public byte QColor = 1;
        //模型.
        public string AvatarModel = "23101_rabbit";
        //模型缩放比例.
        public int AvatarModelScale = 70;
        //特效模型.
        public string EffectModel = "vfx_pet_illusion_lv5";
        //光环特效.
        public int EffectScale = 150;
        //光环特效在场景中的缩放配置.
        public int EffectSceneScale = 200;
        //模板.
        public int TemplateID = 0;
        //头像.
        public string IconName = null;
        //宿主ID.
        public uint MasterID = 0;
        //进阶等级.
        public byte StateLv = 0;

        public object Clone()
        {
            PetBaseInfo ret = new PetBaseInfo();

            ret.name = this.name;
            ret.level = this.level;
            ret.QColor = this.QColor;
            ret.AvatarModel = this.AvatarModel;
            ret.AvatarModelScale = this.AvatarModelScale;
            ret.EffectModel = this.EffectModel;
            ret.EffectScale = this.EffectScale;
            ret.EffectSceneScale = this.EffectSceneScale;
            ret.IconName = this.IconName;
            ret.TemplateID = this.TemplateID;
            ret.MasterID = this.MasterID;
            ret.StateLv = this.StateLv;
            return ret;
        }

        public void ReadExternal(IInputStream input)
        {
            name = input.GetUTF();
            level = input.GetS32();
            QColor = input.GetU8();
            AvatarModel = input.GetUTF();
            AvatarModelScale = input.GetS32();
            EffectModel = input.GetUTF();
            EffectScale = input.GetS32();
            EffectSceneScale = input.GetS32();
            IconName = input.GetUTF();
            TemplateID = input.GetS32();
            MasterID = input.GetU32();
            StateLv = input.GetU8();
        }

        public void WriteExternal(IOutputStream output)
        {
            output.PutUTF(name);
            output.PutS32(level);
            output.PutU8(QColor);
            output.PutUTF(AvatarModel);
            output.PutS32(AvatarModelScale);
            output.PutUTF(EffectModel);
            output.PutS32(EffectScale);
            output.PutS32(EffectSceneScale);
            output.PutUTF(IconName);
            output.PutS32(TemplateID);
            output.PutU32(MasterID);
            output.PutU8(StateLv);
        }
    }

    /// <summary>
    /// 配置信息.
    /// </summary>
    [MessageType(0x9001013)]
    [ExpandableAttribute]
    public class XmdsPetConifg : ICloneable, IExternalizable
    {
        /// <summary>
        /// 跟随模式.
        /// </summary>
        public enum XmdsPetFollowMode : byte
        {
            ActiveAtk = 0,
            PassiveAtk = 1,
            FollowMaster = 2,
        }

        /// <summary>
        /// 跟随模式.
        /// </summary>
        public XmdsPetFollowMode Mode;

		/** 天命数据 */
		public UnitFateType fateType;
		public int fateValue;

		public object Clone()
        {
            XmdsPetConifg ret = new XmdsPetConifg();
            ret.Mode = this.Mode;
            return ret;
        }

        public void ReadExternal(IInputStream input)
        {
            Mode = input.GetEnum8<XmdsPetFollowMode>();
        }

        public void WriteExternal(IOutputStream output)
        {
            output.PutEnum8<XmdsPetFollowMode>(Mode);
        }
    }

	#endregion

	#region 动态场景信息.

	[MessageType(0x9001016)]
    [ExpandableAttribute]
    public class SceneInfo : ICloneable, IExternalizable
    {
        /// <summary>
        /// 是否已通关.
        /// </summary>
        public bool AllowAutoGuard = true;

        public object Clone()
        {
            SceneInfo ret = new SceneInfo();
            ret.AllowAutoGuard = this.AllowAutoGuard;
            return ret;
        }

        public void ReadExternal(IInputStream input)
        {
            this.AllowAutoGuard = input.GetBool();
        }

        public void WriteExternal(IOutputStream output)
        {
            output.PutBool(AllowAutoGuard);
        }
    }

	#endregion

	#region 伤害数值.

	/// <summary>
	/// 玩家伤害信息.
	/// </summary>
	[MessageType(0x9001017)]
    [ExpandableAttribute]
    public class PlayerDamageInfo : ICloneable, IExternalizable
    {
        /// <summary>
        /// 玩家信息.
        /// </summary>
        public XmdsUnitBaseInfo PlayerInfo;
        /// <summary>
        /// 伤害.
        /// </summary>
        public int Damage;

        public string PlayerUUID;

        public object Clone()
        {
            PlayerDamageInfo ret = new PlayerDamageInfo();

            ret.Damage = this.Damage;
            ret.PlayerInfo = this.PlayerInfo;
            ret.PlayerUUID = this.PlayerUUID;
            return ret;
        }

        public void ReadExternal(IInputStream input)
        {
            this.PlayerInfo = input.GetExt<XmdsUnitBaseInfo>();
            this.Damage = input.GetS32();
            this.PlayerUUID = input.GetUTF();
        }

        public void WriteExternal(IOutputStream output)
        {
            output.PutExt(this.PlayerInfo);
            output.PutS32(this.Damage);
            output.PutUTF(this.PlayerUUID);
        }
    }

	#endregion
}