using CommonAI;
using CommonAI.data;
using CommonAI.Data;
using CommonAI.Zone;
using CommonAI.Zone.Helper;
using CommonAI.Zone.Instance;
using CommonAI.Zone.ZoneEditor;
using CommonAI.ZoneServer.JSGModule;
using CommonLang;
using CommonLang.Log;
using CommonLang.Property;
using Pomelo;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Threading;
using System.Web.Helpers;
using XmdsCommon.EditorData;
using XmdsCommon.Message;
using XmdsCommon.Plugin;
using XmdsCommonServer.Message;
using XmdsCommonServer.Plugin;
using XmdsCommonServer.Plugin.Units;
using XmdsCommonServer.Plugin.XmdsSkillTemplate.Skills;
using XmdsCommonSkill.Plugin;
using XmdsCommonSkill.Plugin.FunctionEvent;
using XmdsServerNode.Node;
using XmdsServerNode.Node.Interface;
using XmdsServerNode.Node.R2bNotify;
using static CommonAI.Zone.Instance.InstanceUnit;
using static JSGMountainKingModule;

namespace XmdsServerEdgeJS.Zone
{
    public class ZoneServiceICE : ZoneService
    {
        private static readonly short [] mXChange = { 0, 0, -1, 1 };
        private static readonly short [] mYChange = { 1, -1, 0, 0 };


        public static ZoneServiceICE InstanceICE { get; private set; }
        public ZoneServiceICE() { InstanceICE = this; }

        //----------------------------------------------------------------------------------------------
        #region _游戏服单向通知战斗服_

        /// <summary>
        /// 无差别通知战斗服
        /// </summary>
        /// <param name="instanceId"></param>
        /// <param name="name"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        public void r2b_notify_notifyBattleServer(string instanceId, string name, dynamic param)
        {
            R2BNotifyMessage msg = R2bNotifyManager.GetR2bNotifyMessage(name);
            if (msg != null)
            {
                CommonAIServer.ServerUtils.DynamicToObject(param, msg);
                base.notifyBattleServer(instanceId, msg);
            }
        }

        /// <summary>
        /// 玩家基本信息同步
        /// </summary>
        /// <param name="instanceId"></param>
        /// <returns>副本实例id</returns>
        public void r2b_notify_refreshPlayerBasicData(string playerId, dynamic basic)
        {
            var player = getPlayer(playerId);
            if (player != null)
            {
                XmdsUnitBaseInfo baseData = XmdsPlayerUtil.instance().createXmdsUnitBaseInfo(basic);
                XmdsUnitBaseInfoEventB2C b2c = new XmdsUnitBaseInfoEventB2C(baseData);
                player.ReceiveMsgR2B(b2c);
            }
        }

        /// <summary>
        /// 玩家基本信息同步
        /// </summary>
        /// <param name="instanceId"></param>
        /// <returns>副本实例id</returns>
        public void r2b_notify_refreshPlayerPropertyChange(string playerId, int changeType, int valueType, int value, int duration, long timestamp)
        {
            var player = getPlayer(playerId);
            if (player != null)
            {
                PropertyChangeEventR2B r2b = new PropertyChangeEventR2B();
                r2b.ChangeType = (PropertyChangeEventR2B.PropertyChangeType)changeType;
                r2b.ChangeValueType = (PropertyChangeEventR2B.ValueType)valueType;
                r2b.ChangeValue = value;
                r2b.Duration = duration;
				//r2b.TimestampMS = timestamp;
				//药剂时间直接用本机的时间
				r2b.TimestampMS = TimeUtil.GetTimestampMS() + r2b.Duration;
				
	

                //Console.Write("timestamp:" + timestamp);
                //TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1).ToUniversalTime();
                //Console.Write("timestamp cs:" + ts.TotalMilliseconds);
                player.ReceiveMsgR2B(r2b);
            }
        }

        /// <summary>
        /// 玩家基本信息同步
        /// </summary>
        /// <param name="instanceId"></param>
        /// <returns>副本实例id</returns>
        public void r2b_notify_refreshPlayerPetBaseInfoChange(string playerId, dynamic propertyData)
        {
            var player = getPlayer(playerId);
            if (player != null)
            {
                PetBaseInfoChangeEventR2B r2b = new PetBaseInfoChangeEventR2B();
                r2b.BaseInfo = XmdsPlayerUtil.instance().createPetBaseData(propertyData);
                player.ReceiveMsgR2B(r2b);
            }
        }

		//public void r2b_request_addUnit(string instanceId, int unitTemplateID, string data, Action<int> cb, Action<Exception> err)

		/// <summary>
		/// 玩家基本信息同步
		/// </summary>
		/// <param name="instanceId"></param>
		/// <returns>副本实例id</returns>
		public void r2b_notify_refreshPlayerPetDataChange(string playerId, int type, PetDataChangeEventR2B r2b, Action<int> cb, Action<Exception> err)
        {
			int petHP = 0;
            var player = getPlayer(playerId);
            if (player != null)
            {
                player.ReceiveMsgR2B(r2b);

				// 获取该玩家宠物血量
				if (player.BindingObject != null && player.BindingObject.BindingActor != null)
				{
					XmdsVirtual_Player zv = (XmdsVirtual_Player)player.BindingObject.BindingActor.Virtual;
					if(zv != null && zv.GetPet() != null)
					{
						petHP = zv.GetPet().mUnit.CurrentHP;
					}
				}
            }

			cb(petHP);
        }

        /// <summary>
        /// 宠物技能信息同步
        /// </summary>
        /// <param name="playerId"></param>
        /// <param name="type"></param>
        /// <param name="propertyData"></param>
        /// <returns></returns>
        public void r2b_notify_refreshPlayerPetSkillChange(string playerId, int type, dynamic propertyData)
        {
            var player = getPlayer(playerId);
            if (player != null)
            {
                PetSkillChangeEventR2B r2b = new PetSkillChangeEventR2B();
                List<GameSkill> UnitSkills = new List<GameSkill>();
                foreach (dynamic obj in propertyData)
                {
                    GameSkill skill = new GameSkill();
                    skill.SkillID = (int)obj.id;
                    skill.SkillLevel = (int)obj.level;
                    skill.SkillType = (XmdsSkillType)obj.type;
                    skill.TalentSkillLevel1 = (int)obj.talentLevel[0];
                    skill.TalentSkillLevel2 = (int)obj.talentLevel[1];
                    skill.TalentSkillLevel3 = (int)obj.talentLevel[2];
                    UnitSkills.Add(skill);
                }
                r2b.OperateID = (PlayerSkillChangeEventR2B.SkillOperate)type;
                r2b.SkillList = UnitSkills;
                player.ReceiveMsgR2B(r2b);
            }
        }

        /// <summary>
        /// 玩家基本信息同步
        /// </summary>
        /// <param name="playerId"></param>
        /// <returns></returns>
        public void r2b_notify_refreshPlayerPetPropertyChange(string playerId, dynamic propertyData)
        {
            var player = getPlayer(playerId);
            if (player != null)
            {
                PetPropertyChangeEventR2B r2b = new PetPropertyChangeEventR2B();

                PropertyChangeEventR2B order = new PropertyChangeEventR2B();
                order.ChangeType = (PropertyChangeEventR2B.PropertyChangeType)propertyData.changeType;
                order.ChangeValue = (int)propertyData.value;
                order.ChangeValueType = (PropertyChangeEventR2B.ValueType)propertyData.valueType;
                order.Duration = (int)propertyData.duration;
                order.TimestampMS = (long)propertyData.timestamp;

                r2b.Order = order;

                player.ReceiveMsgR2B(r2b);
            }
		}

        /// <summary>
        /// 玩家基本信息同步
        /// </summary>
        /// <param name="instanceId"></param>
        /// <returns>副本实例id</returns>
        public void r2b_notify_refreshPlayerPKMode(string playerId, bool isLook, dynamic model, Action<int> cb, Action<Exception> err)
        {
			int resCode = 0;
            var player = getPlayer(playerId);
            if (player != null)
            {
				/*player.BindingActor.Virtual.IsInPVE() || */
				resCode = (player.BindingActor.IsActive && player.BindingActor.Virtual.IsInPVP()) ? 1 : 0;

				if(resCode == 1)
				{
					XmdsVirtual playerVirtual = player.BindingActor.Virtual as XmdsVirtual;
					log.Warn("PVP状态下传送1:" + playerVirtual.mUnit.PlayerUUID + ", 场景ID: " + playerVirtual.mUnit.Parent.GetSceneID() + ", " + 
						playerVirtual.GetHateSystem().GetHatePlayerInfo() + ", 触发PVP玩家:" + playerVirtual.mPvpTriggerPlayerId);
				}
				else if(!isLook)
				{
					//传送成功才刷新PK模式
					PlayerPKModeChangeEventR2B r2b = new PlayerPKModeChangeEventR2B();
					r2b.CurPKMode = (PKMode)model;
					player.ReceiveMsgR2B(r2b);
				}			
			}

			cb(resCode);
        }

        /// <summary>
        /// 玩家基本信息同步
        /// </summary>
        /// <param name="instanceId"></param>
        /// <returns>副本实例id</returns>
        public void r2b_notify_refreshPlayerPKValue(string playerId, int value)
        {
            var player = getPlayer(playerId);
            if (player != null)
            {
                PlayerPKValueChangeEventR2B r2b = new PlayerPKValueChangeEventR2B();
                r2b.ChangeValue = value;
                player.ReceiveMsgR2B(r2b);
            }
        }


        /// <summary>
        /// 玩家基本信息同步
        /// </summary>
        /// <param name="instanceId"></param>
        /// <returns>副本实例id</returns>
        public void r2b_notify_refreshPlayerPKLevel(string playerId, dynamic level)
        {
            var player = getPlayer(playerId);
            if (player != null)
            {
                PlayerPKLevelChangeEventR2B r2b = new PlayerPKLevelChangeEventR2B();
                r2b.CurPKLv = (PKLevel)level;
                player.ReceiveMsgR2B(r2b);
            }
        }


        /// <summary>
        /// 玩家队伍信息同步
        /// </summary>
        /// <param name="instanceId"></param>
        /// <returns>副本实例id</returns>
        public void r2b_notify_refreshPlayerTeamData(string playerId, List<string> uuidList)
        {
            var player = getPlayer(playerId);
            if (player != null)
            {
                TeamInfoEventR2B r2b = new TeamInfoEventR2B();
                r2b.UUIDList = uuidList;
                player.Node.OnPlayerReviveTeamInfoEventR2B(player, r2b);
            }
        }

        /// <summary>
        /// 玩家背包剩余格子数量信息同步
        /// </summary>
        /// <param name="instanceId"></param>
        /// <returns>副本实例id</returns>
        public void r2b_notify_refreshPlayerRemainBagCountData(string playerId, int remainCount)
        {
            var player = getPlayer(playerId);
            if (player != null)
            {
                SyncPlayerInventorySizeEventR2B r2b = new SyncPlayerInventorySizeEventR2B();
                r2b.Size = remainCount;
                player.ReceiveMsgR2B(r2b);
            }
        }

        /// <summary>
        /// 玩家队伍背包剩余格子数量信息同步
        /// </summary>
        /// <param name="instanceId"></param>
        /// <returns>副本实例id</returns>
        public void r2b_notify_refreshPlayerRemainTeamBagCountData(string playerId, int remainCount)
        {
            var player = getPlayer(playerId);
            if (player != null)
            {
                TeamInventorySizeChangeEventR2B r2b = new TeamInventorySizeChangeEventR2B();
                r2b.size = remainCount;
                player.ReceiveMsgR2B(r2b);
            }
        }

        /// <summary>
        /// 玩家战斗信息同步
        /// </summary>
        /// <param name="instanceId"></param>
        /// <returns>副本实例id</returns>
        public void r2b_notify_refreshPlayerBattleEffect(string playerId, dynamic effects)
        {
            var player = getPlayer(playerId);
            if (player != null)
            {
                XmdsUnitProp effectData = XmdsPlayerUtil.instance().createXmdsUnitProp(effects);
                XmdsUnitPropEventB2C b2c = new XmdsUnitPropEventB2C(effectData);
                player.ReceiveMsgR2B(b2c);
            }
        }

        /// <summary>
        /// 添加玩家属性
        /// </summary>
        /// <param name="instanceId"></param>
        /// <returns>副本实例id</returns>
        public void r2b_notify_addPlayerAtt(List<string> notifyPlayerIds, string playerId, string key, int value)
        {
            var player = getPlayer(playerId);
            if (player != null)
            {
                List<IPlayer> notifyPlayers = new List<IPlayer>();
                foreach (string notifyPlayerId in notifyPlayerIds)
                {
                    XmdsPlayer notifyPlayer = getPlayer(notifyPlayerId);
                    if (notifyPlayer != null)
                    {
                        notifyPlayers.Add(notifyPlayer);
                    }
                }
                if (key.Equals("hp"))
                {
                    player.Node.OnPlayerAddHPByItem(notifyPlayers, player, value);
                }
            }
        }

        /// <summary>
        /// 玩家技能信息同步
        /// </summary>
        /// <param name="instanceId"></param>
        /// <returns>副本实例id</returns>
        public void r2b_notify_refreshPlayerSkill(string playerId, int operateID, dynamic skills)
        {
            var player = getPlayer(playerId);
            if (player != null)
            {
                //XmdsUnitSkillInfo skillData = XmdsPlayerUtil.instance().createXmdsUnitSkillInfo(skills);
                PlayerSkillChangeEventR2B r2b = new PlayerSkillChangeEventR2B();
                List<GameSkill> UnitSkills = new List<GameSkill>();
                foreach (dynamic obj in skills)
                {
                    GameSkill skill = new GameSkill();
                    skill.SkillID = (int)obj.id;
                    skill.SkillLevel = (int)obj.level;
                    skill.SkillType = (XmdsSkillType)obj.type;
                    skill.TalentSkillLevel1 = (int)obj.talentLevel[0];
                    skill.TalentSkillLevel2 = (int)obj.talentLevel[1];
                    skill.TalentSkillLevel3 = (int)obj.talentLevel[2];
                    skill.SkillTimestampMS = (long)obj.skillTime;
                    skill.SkillCDDecreasePercent = (int)obj.cdTime;
                    UnitSkills.Add(skill);
                }
                r2b.OperateID = (PlayerSkillChangeEventR2B.SkillOperate)operateID;
                r2b.SkillList = UnitSkills;
                player.ReceiveMsgR2B(r2b);
            }
        }

        /// <summary>
        /// 玩家时装信息同步
        /// </summary>
        /// <param name="instanceId"></param>
        /// <returns>副本实例id</returns>
        public void r2b_notify_refreshPlayerAvatar(string playerId, dynamic avatars)
        {
            var player = getPlayer(playerId);
            if (player != null)
            {
                List<XmdsAvatarInfo> avatarList = XmdsPlayerUtil.instance().createXmdsAvatarInfoList(avatars);
                PlayAvatarEventB2C b2c = new PlayAvatarEventB2C(avatarList);
                player.ReceiveMsgR2B(b2c);
            }
        }

        /// <summary>
        /// 协助角色复活
        /// </summary>
        /// <param name="playerId"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="items"></param>
        /// <returns>副本实例id</returns>
        public void r2b_notify_helpRevivePlayer(string playerId, string revivePlayerId, int time)
        {
            var player = getPlayer(playerId);
            var revivePlayer = getPlayer(revivePlayerId);
            if (player != null && revivePlayer != null)
            {
                player.Node.OnHelpPlayerRebirth(player, revivePlayer, time);
            }
        }

        /// <summary>
        /// 角色复活
        /// </summary>
        /// <param name="playerId"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="items"></param>
        /// <returns>副本实例id</returns>
        public void r2b_notify_revivePlayer(string playerId, int type, int qty, string itemType, int hp, int mp)
        {
            var player = getPlayer(playerId);
            if (player != null)
            {
                ConsumeItemEventB2R b2r = new ConsumeItemEventB2R();
                b2r.playerId = playerId;
                b2r.Qty = qty;
                b2r.Type = itemType;
                PlayerRebirthEventR2B b2c = new PlayerRebirthEventR2B((byte)type, b2r);
                b2c.HP = hp;
                b2c.MP = mp;
                player.ReceiveMsgR2B(b2c);
            }

        }

        /// <summary>
        /// 角色复活
        /// </summary>
        /// <param name="playerId"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="items"></param>
        /// <returns>副本实例id</returns>
        public void r2b_notify_refreshSummonMount(string playerId, int time, bool IsSummonMount)
        {
            var player = getPlayer(playerId);
            if (player != null)
            {

                PlayerSummonMountEventR2B b2c = new PlayerSummonMountEventR2B();
                b2c.TimeMS = time;
                b2c.IsSummonMount = IsSummonMount;
                player.ReceiveMsgR2B(b2c);
            }
        }

        /// <summary>
        /// 怪物死亡掉落
        /// </summary>
        /// <param name="PlayerId"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="items"></param>
        /// <returns>副本实例id</returns>
        public void r2b_notify_onMonsterDiedDrops(string instanceId, float x, float y, dynamic items)
        {
            //TODO 要计算道具的位置
            var zone = getZoneNode(instanceId);
            if (zone != null)
            {
                zone.Node.AddDropItem(x, y, items);
            }
        }

        /// <summary>
        /// 提示客户端获得道具
        /// </summary>
        /// <param name="PlayerId"></param>
        /// <param name="itemIcon"></param>
        /// <param name="quality"></param>
        /// <param name="num"></param>
        /// <returns></returns>
        public void r2b_notify_onFinishPickItem(string playerId, string itemIcon, int quality, int num, int objectId, String instanceId)
        {
            //TODO 要计算道具的位置
            var player = getPlayer(playerId);
            if (player != null)
            {
                player.Node.FinishPickItem(player, itemIcon, quality, num);
            }

            //if(objectId > 0)
            //{
            //	var node = getZoneNode(instanceId);
            //	if (node != null)
            //	{
            //		node.Node.QueueTaskAsync((zone) =>
            //		{
            //			zone.RemoveObjectByID((uint)objectId);
            //		});
            //	}
            //}
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="playerId"></param>
        /// <param name="eventId"></param>
        /// <param name="data"></param>
        /// <param name="cb"></param>
        /// <param name="err"></param>
        public void r2b_notify_triggrBattleFunction(string playerId, int eventId, int value1, int value2, int value3, int value4, int value5, int value6)
        {
            XmdsPlayer player = getPlayer(playerId);
            if (player != null)
            {
				player.Node.QueueTaskAsync(() =>
				{
					try
					{
						if(value1 == 0 && value2 == 0 && value3 == 0 && value4 == 0 && value5 == 0 && value6 == 0)
						{
							XmdsVirtual virtualUnit = (player.BindingActor.Virtual as XmdsVirtual);
							BattleFunction.GetInstance().TriggrBattleFunction(eventId, virtualUnit, virtualUnit);
						}
						else
						{
							BattleFunction.GetInstance().TriggrBattleFunction(eventId, (player.BindingActor.Virtual as XmdsVirtual), value1, value2, value3, value4, value5, value6);
						}						
					}
					catch(Exception e)
					{
						log.Warn("r2b_notify_triggrBattleFunction catch: " + playerId + ", " + eventId + ", 参数:" + value1 + ", " + value2 
							+ ", "	+ value3 + ", " + value4 + ", " + value5 + ", " + value6 + ", e: " + e);
					}					
				});
			}
        }

        /// <summary>
        /// 种怪
        /// </summary>
        /// <param name="instanceId"></param>
        /// <param name="data"></param>       
        public void r2b_notify_addUnits(string instanceId, string propertyData,  Action<int> cb, Action<Exception> err)
        {
            int unitId = 0;
            dynamic data = Json.Decode(propertyData);
            var zoneNode = getZoneNode(instanceId);
            if (zoneNode != null)
            {
                zoneNode.Node.QueueTaskAsync((zone) =>
                {
                    int count = 0;
                    foreach (var u in data)
                    {
                        int templateId = u.id;
                        int gsFlag = u["gsFlag"];
						int hp = 0;
						int maxHP = 0;
						float birthDirection = (float)u["birthDirection"];
                        int level = u["level"];
                        string flagName = u["flag"];
						string name = u["name"];
						//指定追击玩家id(必须是无限追击怪才会联动生效)
						string attackPlayerId = u["attackPlayer"];
						//创建护卫怪,主人ObjectId(主人脱战或者死亡消失)
						int masterId = u.masterID;
						bool autoGuard = false;
                        if (u["autoGuard"] != null)
                        {
                            autoGuard = u["autoGuard"];
                        }
                        //同一个场景内是否只能拥有唯一一个unit
                        bool unique = false;
                        if (u["unique"] != null)
                        {
                            unique = u["unique"];
                        }

						if (u["hp"] != null && u["maxHP"] != null)
						{
							hp = u["hp"];
							maxHP = u["maxHP"];
						}

                        float x = 0;
                        float y = 0;
                        if (flagName != null)
                        {
                            var p = zone.getFlag(flagName);
							if(p == null)
							{
								log.Error("r2b_notify_addUnits 路点错误,怪物:" + templateId + ", 路点:" + flagName);
								cb(0);
								return;
							}
                            else if (p is ZoneRegion)
                            {
                                // Region随机取一个坐标
                                var v2 = (p as ZoneRegion).getRandomPos(zone.RandomN);
                                x = v2.X;
                                y = v2.Y;
                            }
                            else
                            {
                                x = p.X;
                                y = p.Y;
                            }
                        }
                        else
                        {
                            //根据坐标
                            x = u.x;
                            y = u.y;
                        }

                        int force = u.force;
                        var unitInfo = zone.Templates.getUnit(templateId);
                        if (unitInfo != null)
                        {
                            string uuid = u["uuid"];
                            if (string.IsNullOrEmpty(uuid))
                            {
                                if (unitInfo.UType == CommonAI.Zone.UnitInfo.UnitType.TYPE_PLAYER)
                                {
                                    uuid = unitInfo.Name + CUtils.CurrentTimeMS.ToString() + count.ToString();
                                }
                                else
                                {
                                    uuid = "";
                                }
                            }
                            if (unique)
                            {
                                InstanceUnit targetUnit = zone.getUnitByTemplateID(templateId);
                                if (targetUnit != null)
                                {
                                    log.Info("AddUnits is already exist, id:" + templateId + "," + x + "," + y);
                                    continue;
                                }
                            }
							
							var ret = zone.AddUnit(unitInfo, uuid, force, level, x, y, birthDirection, null, name, gsFlag, level > 0);
							if(ret == null)
							{
								log.Warn("单位添加失败:" + unitInfo.TemplateID + ", " + zone.Data.ID);
								continue;
							}

                            if (flagName != null)
                            {
                                ret.SetAttribute("RefreshMonsterTag", flagName);
                            }

                            if (ret is InstancePlayer && autoGuard)
                            {
                                var act = new CommonAI.Zone.UnitGuardAction(ret.ID, autoGuard);
                                zone.pushAction(act);
                            }

                            if (ret.Virtual is XmdsVirtual_Monster)
                            {
								var monster = ret.Virtual as XmdsVirtual_Monster;

								if (u["shareType"] != null)
                                {                                    
                                    monster.IsShare = true;
                                }

								//血量数据设置
								if(hp > 0)
								{
									// 最大血量小于设置血量,需要调整下	
									if(monster.mUnit.MaxHP < hp)
									{
										monster.mUnit.SetMaxHP(hp);
									}			
									
									monster.mUnit.CurrentHP = hp;									
								}

								if (!JSGModule.IsEmpty(attackPlayerId))
								{
									ret.BindAttackPlayer(attackPlayerId);
								}
								
								if(masterId > 0)
								{
									ret.BindMasterId(masterId);
								}						
                            }
                            unitId = (int)ret.ID;
                        }
                        count = count + 1;                        
                    }

                    if(count <= 1)
                    {
                        cb(unitId);
                    }
                    else
                    {
						cb(0);
                    }
                });
            }
            else
			{
				log.Warn("场景不存在加入单位:" + instanceId + ", " + propertyData);
                cb(-1);
            }            
        }

        /// <summary>
        /// 玩家基本信息同步
        /// </summary>
        /// <param name="instanceId"></param>
        /// <returns>副本实例id</returns>
        public void r2b_notify_refreshPlayerPetFollowModeChange(string playerId, int model)
        {
            var player = getPlayer(playerId);
            if (player != null)
            {
                PetFollowModeChangeEventR2B r2b = new PetFollowModeChangeEventR2B();
                r2b.mode = (XmdsPetConifg.XmdsPetFollowMode)model;
                player.ReceiveMsgR2B(r2b);
            }
        }

        // TODO playerReady
        public void r2b_notify_playerReady(string playerId)
        {
            var player = getPlayer(playerId);
            if (player != null)
            {
                player.Node.OnPlayerReadyR2B(player);
            }
        }

        public void r2b_request_addUnit(string instanceId, int unitTemplateID, string data, Action<int> cb, Action<Exception> err)
        {
            dynamic input = Json.Decode(data);

            string name = (string)input.name;
            byte force = (byte)input.force;
            String flag = input.flag;           //刷新点
            float x = (float)input.x;
            float y = (float)input.y;
            float direction = (float)input.direction;
            int lifeEndTime = (int)input.lifeEndTime;
            int lifeTime = (int)input.lifeTime;
            bool showLifeTime = (bool)input.showLifeTime;
            byte maxPickPlayers = (byte)input.maxPickPlayers;
            short maxPickTimes = (short)input.maxPickTimes;
            short gotInterval = (short)input.gotInterval;
            float offset = (float)input.offsetValue;
            String playerId = input.playerId;

            var node = getZoneNode(instanceId);
            if (node != null)
            {
                node.Node.QueueTaskAsync((zone) =>
                {
                    //如果玩家id不为空,就是用改玩家的坐标
                    if(playerId != null && playerId.Length > 0)
                    {
                        var player = zone.getPlayerByUUID(playerId);
                        if(player != null)
                        {
                            x = player.X;
                            y = player.Y;
                        }
                    }

                    var temp = zone.Templates.getItem(unitTemplateID);
                    if (temp != null)
                    {
                        //如果设置了路点,优先使用路点的x,y
                        if (flag != null)
                        {
                            var p = zone.getFlag(flag);
							if(p == null)
							{
								log.Error("创建单位出现错误flag:" + unitTemplateID + ", " + flag);
								cb(-1);								
								return;
							}

                            if (p is ZoneRegion)
                            {
                                // Region随机取一个坐标
                                var v2 = (p as ZoneRegion).getRandomPos(zone.RandomN);
                                x = v2.X;
                                y = v2.Y;
                            }
                            else
                            {
                                x = p.X;
                                y = p.Y;
                            }
                        }

                        if (lifeTime > 0)
                        { 
                            temp.LifeTimeMS = lifeTime * 1000;
                        }

                        temp.LifeEndTime = lifeEndTime;
                        temp.showLifeTime = showLifeTime;
						if(maxPickPlayers != 0)
						{
							temp.maxPickPlayers = maxPickPlayers;
						}
                        
						if(maxPickTimes != 0)
						{
							temp.maxPickTimes = maxPickTimes;
						}
                        
						if(gotInterval != -1)
						{
							temp.UseCoolDownTimeMS = gotInterval;
						}                       

                        if(offset == 0)
                        {
                            InstanceItem unit_data = zone.AddItem(temp, name, x, y, direction, force, name, null);
                            if (unit_data != null)
                            {
                                cb((int)unit_data.ID);
                            }
                        }
                        else
                        {
                            //特殊写法,仰慕道具
                            for(int i = 0; i < 4; i++)
                            {
                                float tempX = x + mXChange[i] * offset;
                                float tempY = y + mYChange[i] * offset;
                                InstanceItem unit_data = zone.AddItem(temp, name, tempX, tempY, direction, force, name, null);
                            }
                            cb(0);
                        }                       
                    }
                    else
                    {
                        cb(0);
                    }
                });
            }
            else
            {
                cb(-1);
            }
        }

        public void r2b_request_removeUnit(string instanceId, int unitId)
        {
            var node = getZoneNode(instanceId);
            if (node != null)
            {
                node.Node.QueueTaskAsync((zone) =>
                {
                    zone.RemoveUnitByID((uint)unitId);
                });
            }
        }

        public void r2b_request_removePointUnit(string instanceId, int unitObjectId)
        {
            var node = getZoneNode(instanceId);
            if (node != null)
            {
                node.Node.QueueTaskAsync((zone) =>
                {
                    zone.RemoveObjectByID((uint)unitObjectId);
                });
            }
        }

        public void r2b_request_removeItem(string instanceId, int itemId)
        {
            var node = getZoneNode(instanceId);
            if (node != null)
            {
                node.Node.QueueTaskAsync((zone) =>
                {
                    zone.RemoveItemByID((uint)itemId);
                });
            }
        }

#endregion
        //----------------------------------------------------------------------------------------------
#region _获取静态数据_

        /// <summary>
        /// 【静态数据】获取副本传送点
        /// </summary>
        /// <param name="instanceId"></param>
        /// <returns>副本实例id</returns>
        public void r2b_get_static_getBornPlace(string instanceId, int areaId, string pointId, Action<dynamic> cb, Action<Exception> err)
        {
            var node = getZoneNode(instanceId);
            if (node != null)
            {
                cb(node.r2b_get_getBornPlace(areaId, pointId));
            }
            else
            {
                err(new InstanceNotExistException(instanceId));
            }
        }

        /// <summary>
        /// 【静态数据】获取副本静态模版数据
        /// </summary>
        /// <param name="instanceId"></param>
        /// <returns>副本实例id</returns>
        public void r2b_get_static_getZoneStaticData(string instanceId, Action<EdgeSceneData> cb, Action<Exception> err)
        {
            var node = getZoneNode(instanceId);
            if (node != null)
            {
                var data = new EdgeSceneData(node.Node.SceneData);
                cb(data);
            }
            else
            {
                err(new InstanceNotExistException(instanceId));
            }
        }

        ///
        public void r2b_notify_setTeamData(string playerId, dynamic data)
        {
            var player = getPlayer(playerId);
            if (player != null)
            {
                TeamDataEventR2B r2b = new TeamDataEventR2B();
                r2b.LeaderId = data.leaderId;
                r2b.TeamMembers = new List<TeamMemberEventR2B>();
                foreach (dynamic obj in data.members)
                {
                    TeamMemberEventR2B mbr = new TeamMemberEventR2B();
                    mbr.followLeader = (int)obj.followLeader;
                    mbr.uuid = obj.uuid;
                    r2b.TeamMembers.Add(mbr);
                }
                player.ReceiveMsgR2B(r2b);
            }
        }

#endregion
        //----------------------------------------------------------------------------------------------
#region _获取动态数据_

        /// <summary>
        /// 获取地图上所有enable的区域
        /// </summary>
        /// <param name="instanceId"></param>
        /// <returns></returns>
        public void r2b_get_getZoneRegions(string instanceId, Action<List<EdgeRegionData>> cb, Action<Exception> err)
        {
            var node = getZoneNode(instanceId);
            if (node != null)
            {
                node.Node.QueueTaskAsync((zone) =>
                {
                    try
                    {
                        List<RegionData> regions = zone.Data.Regions;
                        List<EdgeRegionData> edgeRegions = new List<EdgeRegionData>();
                        foreach (RegionData rd in regions)
                        {
                            var flag = zone.getFlag(rd.Name);
                            if (flag != null && flag.Enable)
                            {
                                EdgeRegionData eRd = new EdgeRegionData(rd);
                                eRd.Enable = true;
                                edgeRegions.Add(eRd);
                            }
                        }
                        cb(edgeRegions);
                    }
                    catch (Exception e)
                    {
                        err(e);
                    }
                });
            }
            else
            {
                err(new InstanceNotExistException(instanceId));
            }
        }

        /// <summary>
        /// 获取地图上所有enable的区域
        /// </summary>
        /// <param name="playerId"></param>
        /// <returns></returns>
        public void r2b_get_canUseItem(string playerId, Action<bool> cb, Action<Exception> err)
        {

            XmdsPlayer player = getPlayer(playerId);
            if (player != null)
            {
                //player.Node.QueueTaskAsync(() =>
                //{
                //    try
                //    {
                XmdsVirtual zv = (XmdsVirtual)player.BindingActor.Virtual;
                cb(zv.CanUseItem());
                //    }
                //    catch (Exception e)
                //    {
                //        err(e);
                //    }
                //});
            }
            else
            {
                err(new PlayerNotExistException(playerId));
            }
        }

        /// <summary>
        /// 获取该地图的所有unit
        /// </summary>
        /// <param name="instanceId"></param>
        /// <returns></returns>
        public void r2b_get_getAllUnitInfo(string instanceId, Action<List<UnitInfo>> cb, Action<Exception> err)
        {
            var node = getZoneNode(instanceId);
            if (node != null)
            {
                node.Node.QueueTaskAsync((zone) =>
                {
                    var units = new List<InstanceUnit>();
                    zone.GetAllUnits(units);
                    List<UnitInfo> ret = new List<UnitInfo>();
                    foreach (InstanceUnit unit in units)
                    {
                        CommonAI.ZoneClient.SyncUnitInfo syncInfo = unit.GenSyncUnitInfo();
                        UnitInfo info = new UnitInfo();
                        info.type = unit.GetType().Name;
                        info.ObjectId = syncInfo.ObjectID;
                        info.force = syncInfo.Force;
                        info.templateId = syncInfo.TemplateID;
                        info.playerId = syncInfo.PlayerUUID;
                        info.x = syncInfo.x;
                        info.y = syncInfo.y;
                        ret.Add(info);
                    }
                    cb(ret);
                });
            }
            else
            {
                err(new InstanceNotExistException(instanceId));
            }
        }

        /// <summary>
        /// 获取该地图的所有npc
        /// </summary>
        /// <param name="instanceId"></param>
        /// <returns></returns>
        public void r2b_get_getAllNpcInfo(string instanceId, Action<List<UnitInfo>> cb, Action<Exception> err)
        {			
			try
			{
				var node = getZoneNode(instanceId);
				if (node != null)
				{
					//node.Node.QueueTaskAsync((zone) =>
					//{
						List<InstanceUnit> units = new List<InstanceUnit>();
						node.Node.Zone.GetAllUnits(units);
						List<UnitInfo> ret = new List<UnitInfo>();
						foreach (InstanceUnit unit in units)
						{
							if (unit.Info.UType == CommonAI.Zone.UnitInfo.UnitType.TYPE_NPC)
							{
								CommonAI.ZoneClient.SyncUnitInfo syncInfo = unit.GenSyncUnitInfo();
								UnitInfo info = new UnitInfo();
								UnitData data = (UnitData)unit.GetAttribute("UnitData");
								string[] attributes = data == null ? null : data.Attributes;
								//string[] attributes = unit.Info.Attributes;
								if (attributes != null && attributes.Length > 0)
								{
									info.unitType = attributes[0];
								}
								else
								{
									info.unitType = "";
								}
								info.name = unit.Name;
								info.type = unit.GetType().Name;
								info.ObjectId = syncInfo.ObjectID;
								info.force = syncInfo.Force;
								info.templateId = syncInfo.TemplateID;
								info.playerId = syncInfo.PlayerUUID;
								info.x = syncInfo.x;
								info.y = syncInfo.y;
								ret.Add(info);
							}
						}
						cb(ret);
						return;
					//});
				}
			}
			catch(Exception e)
			{
				log.Warn("r2b_get_getAllNpcInfo catch: " + instanceId + ", " + e);
				
			}

			cb(new List<UnitInfo>());
        }

        /// <summary>
        /// 获取所有玩家UUID信息
        /// </summary>
        public void r2b_get_getAllPlayerUUID(Action<dynamic> cb, Action<Exception> err)
        {
            GetAllPlayers((e2, ret) =>
            {
                if (e2 != null)
                {
                    err(e2);
                }
                else
                {
                    dynamic json = new { list = ret };
                    cb(json);
                }
            });
        }

        /// <summary>
        /// 玩家基本信息同步
        /// </summary>
        /// <param name="PlayerId"></param>
        /// <returns>副本实例id</returns>
        public void r2b_get_getPlayerData(string playerId, bool changeArea, Action<dynamic> cb, Action<Exception> err)
        {
            XmdsPlayer player = getPlayer(playerId);
            if (player != null && player.BindingActor != null)
            {
                //player.Node.QueueTaskAsync(() =>
                //{
                //    try
                //    {
                InstancePlayer p = player.BindingActor;
                XmdsUnitProperties prop = p.Properties as XmdsUnitProperties;
                PKInfo pkInfo = prop.ServerData.UnitPKInfo;
                ArrayList skillList = new ArrayList();
                XmdsVirtual zv = (XmdsVirtual)p.Virtual;
                if (changeArea)
                {
                    XmdsCommonServer.Plugin.XmdsVirtual.XmdsSkillStatusData skillData = zv.GetSkillStatusData();
                    foreach (KeyValuePair<int, long> kvp in skillData.SkillTimestampMSMap)
                    {
                        int skillId = kvp.Key;
                        long skillTime = kvp.Value;
                        skillList.Add(new { skillId = skillId, skillTime = skillTime });
                    }
                }

                dynamic ret = new
                {
                    x = p.X,
                    y = p.Y,
                    direction = p.Direction,
                    hp = p.get_current_hp(),
                    mp = p.get_current_mp(),
                    pkMode = (int)pkInfo.CurPKMode,
                    pkValue = pkInfo.CurPKValue,
                    pkLevel = (int)pkInfo.CurPKLevel,
                    skillData = skillList,
                    combatState = zv.CombatState
                };

                cb(ret);
                //    }
                //    catch (Exception e)
                //    {
                //        err(e);
                //    }
                //});
            }
            else
            {
                //err(new PlayerNotExistException(playerId));
                cb(null);
            }
        }

        /// <summary>
        /// 玩家宠物基本信息同步
        /// </summary>
        /// <param name="PlayerId"></param>
        /// <returns>副本实例id</returns>
        public void r2b_get_getPlayerPetData(string playerId, Action<dynamic> cb, Action<Exception> err)
        {
			try
			{
				do
				{
					if (string.IsNullOrEmpty(playerId))
					{
						log.Error("那个sx传过来一个空玩家信息:");
						break; ;
					}
					XmdsPlayer player = getPlayer(playerId);
					if (player != null && player.BindingActor != null)
					{
						XmdsVirtual_Player zv = (XmdsVirtual_Player)player.BindingActor.Virtual;
						if(zv == null)
						{
							break;
						}

						XmdsVirtual_Pet petData = zv.GetPet();
						if (petData == null)
						{
							log.Error("找不到玩家对应宠物信息:" + playerId);
							break; ;
						}

						dynamic ret = new
						{
							hp = petData.mUnit.CurrentHP,
							mp = petData.mUnit.CurrentMP,
						};

						cb(ret);
						return;					
					}
				} while (false);				
			}
			catch(Exception e)
			{
				log.Error("r2b_get_getPlayerPetData : " + playerId + ", " + e);
			}

			dynamic retFinal = new
			{
				hp = -1,
				mp = -1,
			};
			cb(retFinal);
		}

        /// <summary>
        /// 玩家基本信息同步
        /// </summary>
        /// <param name="PlayerId"></param>
        /// <returns>副本实例id</returns>
        public void r2b_get_getPlayerSkillCDTime(string playerId, Action<ArrayList> cb, Action<Exception> err)
        {
            XmdsPlayer player = getPlayer(playerId);
            if (player != null)
            {
                //player.Node.QueueTaskAsync(() =>
                //{
                    try
                    {
                        ArrayList skillList = new ArrayList();
                        global::XmdsCommonServer.Plugin.XmdsVirtual zv = (global::XmdsCommonServer.Plugin.XmdsVirtual)player.BindingActor.Virtual;
                        global::XmdsCommonServer.Plugin.XmdsVirtual.XmdsSkillStatusData skillData = zv.GetSkillStatusData();
                        foreach (KeyValuePair<int, long> kvp in skillData.SkillTimestampMSMap)
                        {

                            int skillId = kvp.Key;
                            long skillTime = kvp.Value;
                            skillList.Add(new { skillId = skillId, skillTime = skillTime });

                        }
                        cb(skillList);
                    }
                    catch (Exception e)
                    {
                        err(e);
                    }
                //});
            }
            else
            {
                err(new PlayerNotExistException(playerId));
            }
        }

        public void r2b_get_CanTalkWithNpc(string playerId, uint npcId, Action<dynamic> cb, Action<Exception> err)
        {
            XmdsPlayer player = getPlayer(playerId);
            if (player != null)
            {
                //player.Node.QueueTaskAsync(() =>
                //{
                InstancePlayer src = player.BindingActor;
                InstanceUnit dst = null;
                if (src != null && (dst = src.Parent.getUnit(npcId)) != null)
                {
                    dynamic ret = new
                    {
                        templateId = dst.Info.TemplateID,
                        canTalk = CMath.intersectRound(
                            src.X, src.Y, src.BodyBlockSize + 5,
                            dst.X, dst.Y, dst.BodyBlockSize),
                    };
                    cb(ret);
                    return;
                }
                //});
            }
            cb(new
            {
                templateId = 0,
                canTalk = false,
            });
        }

        /// <summary>
        /// 玩家基本信息同步
        /// </summary>
        /// <param name="PlayerId"></param>
        /// <returns>副本实例id</returns>
        public void r2b_get_getPlayerPKInfoData(string playerId, Action<dynamic> cb, Action<Exception> err)
        {
            XmdsPlayer player = getPlayer(playerId);
            if (player != null)
            {
                //player.Node.QueueTaskAsync(() =>
                //{
                //try
                //{
                XmdsUnitProperties prop = player.BindingActor.Properties as XmdsUnitProperties;
                PKInfo pkInfo = prop.ServerData.UnitPKInfo;
                dynamic ret = new
                {
                    pkMode = (int)pkInfo.CurPKMode,
                    pkValue = pkInfo.CurPKValue,
                    pkLevel = (int)pkInfo.CurPKLevel
                };
                cb(ret);
                //}
                //catch (Exception e)
                //{
                //    err(e);
                //}
                //});
            }
            else
            {
                err(new PlayerNotExistException(playerId));
            }
        }

        public void r2b_request_autoBattle(string instanceId, string playerId, bool enable)
        {

            var node = getZoneNode(instanceId);
            if (node != null)
            {
                node.Node.QueueTaskAsync((zone) =>
                {
                    InstanceUnit u = zone.getPlayerByUUID(playerId.ToString());

                    if (u != null)
                    {
                        UnitGuardAction guard = new UnitGuardAction();
                        guard.guard = enable;
                        guard.object_id = u.ID;
                        guard.forceNotify = true;
                        u.Parent.pushAction(guard);

                        log.Debug("--------autoBattle from gs: playerId=" + playerId + " area=" + node.Node.Name + " instanceId=" + instanceId);
                    }
                    else
                    {
                        log.Error("r2b_request_autoBattle PlayerNotExistException: playerId =" + playerId + " area=" + node.Node.Name);
                    }
                });
            }
        }

        public void r2b_request_getPlayerStatistic(string playerId, Action<int> cb, Action<Exception> err)
        {
            var player = getPlayer(playerId);
            if (player != null)
            {
                //player.Node.QueueTaskAsync(() =>
                //{
                InstancePlayer insPlayer = player.BindingActor;
                dynamic ret = new
                {
                    totalDamage = insPlayer.Statistic.TotalDamage,
                    totalHealing = insPlayer.Statistic.TotalHealing,
                    killPlayerCount = insPlayer.Statistic.KillPlayerCount,
                    killUnitCount = insPlayer.Statistic.KillUnitCount,
                    deadCount = insPlayer.Statistic.DeadCount
                };
                cb(ret);
                //});
            }
            else
            {
                log.Error("r2b_request_getPlayerStatistic: PlayerNotExistException: playerId =" + playerId);
                cb(0);
                return;
            }
        }

        public void r2b_request_getInstanceStatistic(string instanceId, Action<dynamic> cb, Action<Exception> err)
        {
            var node = getZoneNode(instanceId);
            if (node != null)
            {
                dynamic statistic = new Dictionary<string, dynamic>();
                node.Node.ForEachPlayers((client) =>
                {
                    var insPlayer = client.Actor;
                    if (insPlayer != null)
                    {
                        statistic[insPlayer.PlayerUUID] = new
                        {
                            totalDamage = insPlayer.Statistic.TotalDamage,
                            totalHealing = insPlayer.Statistic.TotalHealing,
                            killPlayerCount = insPlayer.Statistic.KillPlayerCount,
                            killUnitCount = insPlayer.Statistic.KillUnitCount,
                            deadCount = insPlayer.Statistic.DeadCount
                        };
                    }
                });
                cb(statistic);
            }
            else
            {
                log.Error("r2b_request_getInstanceStatistic: InstanceNotExistException: instanceId =" + instanceId);
                cb(null);
                return;
            }
        }


        /// <summary>
        /// 玩家更换技能
        /// </summary>
        /// <param name="instanceId"></param>
        /// <returns>副本实例id</returns>		
        ///   
        public void r2b_notify_playerChangeSkill(string playerId, int oldSkillID, int newSkillID, dynamic data)
        {
            var player = getPlayer(playerId);
            if (player != null)
            {
                XmdsInstancePlayer instancePlayer = player.getInstancePlayer() as XmdsInstancePlayer;
                if (instancePlayer == null)
                {
                    return;
                }

				SkillLevelData levelData = null;

				if (data != null)
				{
					levelData = new SkillLevelData();
					levelData.SkillLevel = data.level;
					levelData.TalentSkillLevel1 = data.talentLevel[0];
					levelData.TalentSkillLevel2 = data.talentLevel[1];
					levelData.TalentSkillLevel3 = data.talentLevel[2];
					levelData.skillType = (XmdsSkillType)data.skillType;
				}
								
                instancePlayer.PlayerChangeSkill(oldSkillID, newSkillID, levelData);
                //player.get
                //XmdsUnitSkillInfo skillData = XmdsPlayerUtil.instance()
            }
        }

        /// <summary>
        /// 玩家基本信息同步
        /// </summary>
        /// <param name="playerId"></param>
        /// <returns></returns>
        public bool r2b_notify_transferToPointPos(string instanceId, string playerId, string refreshPoint, bool setDirction, float direction)
        {
            var node = getZoneNode(instanceId);
            if (node == null)
            {
                return false;
            }

            var player = getPlayer(playerId);
            if (player == null)
            {
                return false;
            }

            InstanceFlag flag = node.Node.Zone.getFlag(refreshPoint);
            if (flag == null)
            {
                return false;
            }

            if (flag is ZoneWayPoint)
            {
                // Region随机取一个坐标
                var v2 = (flag as ZoneWayPoint).getRandomPos(node.Node.Zone.RandomN);
                player.getInstancePlayer().transport(v2.X, v2.Y, setDirction, direction);
                return true;
            }

            return false;
        }

        /// <summary>
        /// 更改玩家状态
        /// </summary>
        /// <param name="playerId"></param>
        /// <returns></returns>
        public void r2b_notify_changePlayerStatus(string instanceId, string playerId, byte status, int time)
        {
            if(status != (byte)UnitActionStatus.DaZuo && status != (byte)UnitActionStatus.ClearYaoQi 
				&& status != (byte)UnitActionStatus.Idle && status != (byte)UnitActionStatus.CrossRobbery 
                && status != (byte)UnitActionStatus.DaZuoRecoveryAttr)
            {
                return;
            }

            var node = getZoneNode(instanceId);
            if (node == null)
            {
                return ;
            }

            var player = getPlayer(playerId);
            if (player == null)
            {
                return ;
            }

            var instancePlayer = player.getInstancePlayer();
            if(instancePlayer == null)
            {
                return;
            }

            //if(status == (byte)UnitActionStatus.ChuanGongA)
            //{
            //    instancePlayer.changeState(new StateChuanGongA(instancePlayer), false);
            //}
            //else if(status == (byte)UnitActionStatus.ChuanGongB)
            //{
            //    instancePlayer.changeState(new StateChuanGongB(instancePlayer), false);
            //}
            //else 
            if(status == (byte)UnitActionStatus.DaZuo)
            {
                instancePlayer.Virtual.TakeOffMount();
                instancePlayer.changeState(new StateDaZuo(instancePlayer, time), false);
            }
            else if (status == (byte) UnitActionStatus.DaZuoRecoveryAttr)
            {
                //非战斗状态,才能打坐回血
                if (instancePlayer.Virtual.GetBattleStatus() <= BattleStatus.ReadyBattle && (instancePlayer.CurrentActionStatus != UnitActionStatus.DaZuoRecoveryAttr) && (instancePlayer.CurrentActionStatus != UnitActionStatus.Move) ) 
                {
                    instancePlayer.Virtual.TakeOffMount();
                    instancePlayer.changeState(new StateDaZuoRecoveryAttr(instancePlayer, time), false);
                }
            }
            else if(status == (byte)UnitActionStatus.ClearYaoQi)
            {
                instancePlayer.Virtual.TakeOffMount();
                instancePlayer.changeState(new StateClearYaoQi(instancePlayer), false);
            }
			else if (status == (byte)UnitActionStatus.Idle)
			{				
				if(instancePlayer.CurrentActionStatus == UnitActionStatus.DaZuo || instancePlayer.CurrentActionStatus == UnitActionStatus.ChuanGongA
					|| instancePlayer.CurrentActionStatus == UnitActionStatus.ChuanGongB || instancePlayer.CurrentActionStatus == UnitActionStatus.DaZuoRecoveryAttr)
				{
					instancePlayer.CurrentState.MarkRemove();
				}
			}
			else if(status == (byte)UnitActionStatus.CrossRobbery)
			{
				instancePlayer.Virtual.TakeOffMount();
				instancePlayer.changeState(new StateDuJie(instancePlayer), false);
			}
		}

		/// <summary>
		/// 更改玩家状态
		/// </summary>
		/// <param name="playerId"></param>
		/// <returns></returns>
		public void r2b_notify_playerChuanGong(string instanceId, string playerIdA, string playerIdB)
        {
            var node = getZoneNode(instanceId);
            if (node == null)
            {
                return;
            }

            var playerA = getPlayer(playerIdA);
            var playerB = getPlayer(playerIdB);
            if (playerA == null || playerB == null)
            {
                return;
            }

            var instancePlayerA = playerA.getInstancePlayer();
            var instancePlayerB = playerB.getInstancePlayer();
            if (instancePlayerA == null || instancePlayerB == null)
            {
                return;
            }

            instancePlayerA.Virtual.TakeOffMount();
            instancePlayerB.Virtual.TakeOffMount();
            instancePlayerA.changeState(new StateChuanGongA(instancePlayerA), false);
            instancePlayerB.changeState(new StateChuanGongB(instancePlayerB), false);

            //接受传功者,pos和方向设置
            instancePlayerB.faceTo(instancePlayerA.Direction);

            float xAdd = (float)(2 * Math.Cos(instancePlayerA.Direction));                 //角Dir的对边
            float yAdd = (float)(2 * Math.Sin(instancePlayerA.Direction));                 //Dir的邻边      
            instancePlayerB.setPos(instancePlayerA.X + xAdd, instancePlayerA.Y + yAdd);
        }


		/** 通知山大王延时刷新 */
		public void r2b_notifyMountainKingRefresh(string instanceId, string data)
		{
			var node = getZoneNode(instanceId);
			if (node == null)
			{
				return;
			}


			List<KingRefreshData> refreshList = new List<KingRefreshData>();
			dynamic propertyData = Json.Decode(data);
			foreach(var temp in propertyData)
			{
				refreshList.Add(new KingRefreshData(temp.monsterId, temp.nextRefreshTime));
			}

			if(refreshList.Count > 0)
			{
				JSGMountainKingModule.OnMonsterRefreshNotify(node.GetBindGameSrvId(), refreshList);
			}			
		}

#endregion
            //----------------------------------------------------------------------------------------------
        }
}