Exemplo n.º 1
0
        /// <summary>
        /// 刷要塞
        /// </summary>
        public void CreateFort(CopyWolfSceneInfo scene)
        {
            CopyMap          copyMap    = scene.CopyMapInfo;
            CopyWolfWaveInfo waveConfig = null;

            GameMap gameMap = null;

            if (!GameManager.MapMgr.DictMaps.TryGetValue(scene.MapID, out gameMap))
            {
                LogManager.WriteLog(LogTypes.Error, string.Format("【狼魂要塞】报错 地图配置 ID = {0}", scene.MapID));
                return;
            }

            lock (scene)
            {
                if (scene.IsFortFlag > 0)
                {
                    return;
                }

                //置刷怪标记
                scene.IsFortFlag = 1;

                int gridX = gameMap.CorrectWidthPointToGridPoint((int)_runtimeData.FortSite.X) / gameMap.MapGridWidth;
                int gridY = gameMap.CorrectHeightPointToGridPoint((int)_runtimeData.FortSite.Y) / gameMap.MapGridHeight;

                CreateMonsterTagInfo tagInfo = new CreateMonsterTagInfo();
                tagInfo.FuBenSeqId  = scene.FuBenSeqId;
                tagInfo.IsFort      = true;
                tagInfo.ManagerType = (int)SceneUIClasses.CopyWolf;

                GameManager.MonsterZoneMgr.AddDynamicMonsters(scene.MapID, _runtimeData.FortMonsterID, scene.CopyMapInfo.CopyMapID, 1, gridX, gridY, 0, 0, SceneUIClasses.CopyWolf, tagInfo);

                XElement xml = GameManager.MonsterZoneMgr.AllMonstersXml;
                if (xml == null)
                {
                    return;
                }

                XElement monsterXml = Global.GetSafeXElement(xml, "Monster", "ID", _runtimeData.FortMonsterID.ToString());
                if (monsterXml == null)
                {
                    return;
                }

                int life = (int)Global.GetSafeAttributeLong(monsterXml, "MaxLife");
                scene.ScoreData.FortLifeNow = life;
                scene.ScoreData.FortLifeMax = life;
                GameManager.ClientMgr.BroadSpecialCopyMapMessage((int)TCPGameServerCmds.CMD_SPR_COPY_WOLF_SCORE_INFO, scene.ScoreData, scene.CopyMapInfo);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// 刷怪
        /// </summary>
        public void CreateMonster(CopyWolfSceneInfo scene, int upWave = 1)
        {
            CopyMap          copyMap    = scene.CopyMapInfo;
            CopyWolfWaveInfo waveConfig = null;

            GameMap gameMap = null;

            if (!GameManager.MapMgr.DictMaps.TryGetValue(scene.MapID, out gameMap))
            {
                LogManager.WriteLog(LogTypes.Error, string.Format("【狼魂要塞】报错 地图配置 ID = {0}", scene.MapID));
                return;
            }

            //------------------------------------临时测试
            //if (scene.MonsterWave > 0)
            //{
            //    //置刷怪标记
            //    scene.IsMonsterFlag = 1;
            //    return;
            //}

            long nowTicket = TimeUtil.NOW();
            long nowSecond = nowTicket / 1000;

            lock (scene)
            {
                if (scene.MonsterWave >= scene.MonsterWaveTotal)
                {
                    scene.MonsterWaveOld = scene.MonsterWave;
                    scene.MonsterWave    = 0;
                    scene.SceneStatus    = GameSceneStatuses.STATUS_END;
                    return;
                }

                //置刷怪标记
                scene.IsMonsterFlag = 1;

                int wave = scene.MonsterWave + upWave;
                if (wave > scene.MonsterWaveTotal)
                {
                    wave = scene.MonsterWaveTotal;
                }

                waveConfig = _runtimeData.GetWaveConfig(wave);
                if (waveConfig == null)
                {
                    LogManager.WriteLog(LogTypes.Error, string.Format("【狼魂要塞】报错 刷怪波次 = {0}", wave));
                    return;
                }

                scene.MonsterWave       = wave; // 递增刷怪波数
                scene.CreateMonsterTime = nowSecond;

                int totalCount   = 0;
                int monsterID    = 0;
                int monsterCount = 0;
                int gridX        = 0;
                int gridY        = 0;
                int gridNum      = 0;

                CreateMonsterTagInfo tagInfo = new CreateMonsterTagInfo();
                tagInfo.FuBenSeqId  = scene.FuBenSeqId;
                tagInfo.IsFort      = false;
                tagInfo.ManagerType = (int)SceneUIClasses.CopyWolf;

                foreach (CopyWolfSiteInfo siteInfo in waveConfig.MonsterSiteDic)
                {
                    gridX = gameMap.CorrectWidthPointToGridPoint(siteInfo.X + Global.GetRandomNumber(-siteInfo.Radius, siteInfo.Radius)) / gameMap.MapGridWidth;
                    gridY = gameMap.CorrectHeightPointToGridPoint(siteInfo.Y + Global.GetRandomNumber(-siteInfo.Radius, siteInfo.Radius)) / gameMap.MapGridHeight;

                    foreach (var monster in waveConfig.MonsterList)
                    {
                        monsterID    = monster[0];
                        monsterCount = monster[1];
                        totalCount  += monsterCount;
                        GameManager.MonsterZoneMgr.AddDynamicMonsters(scene.MapID, monsterID, scene.CopyMapInfo.CopyMapID, monsterCount, gridX, gridY, gridNum, 0, SceneUIClasses.CopyWolf, tagInfo);
                        //break;
                    }
                    //break;
                }

                scene.MonsterCountCreate += totalCount;
                scene.ScoreData.Wave      = waveConfig.WaveID;
                scene.ScoreData.EndTime   = nowTicket + waveConfig.NextTime * 1000;
                //scene.ScoreData.MonsterCount += scene.MonsterCountCreate;

                GameManager.ClientMgr.BroadSpecialCopyMapMessage((int)TCPGameServerCmds.CMD_SPR_COPY_WOLF_SCORE_INFO, scene.ScoreData, scene.CopyMapInfo);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// 心跳处理
        /// </summary>
        public void TimerProc()
        {
            long nowTicks = TimeUtil.NOW();

            if (nowTicks < _nextHeartBeatTicks)
            {
                return;
            }

            _nextHeartBeatTicks = nowTicks + 1020; //1020毫秒执行一次

            long nowSecond = nowTicks / 1000;

            foreach (CopyWolfSceneInfo scene in _runtimeData.SceneDict.Values)
            {
                lock (_mutex)
                {
                    int nID     = scene.FuBenSeqId;
                    int nCopyID = scene.CopyID;
                    int nMapID  = scene.MapID;

                    if (nID < 0 || nCopyID < 0 || nMapID < 0)
                    {
                        continue;
                    }

                    CopyMap copyMap = scene.CopyMapInfo;
                    if (scene.SceneStatus == GameSceneStatuses.STATUS_NULL)             // 如果处于空状态 -- 是否要切换到准备状态
                    {
                        scene.PrepareTime = nowSecond;
                        scene.BeginTime   = nowSecond + _runtimeData.PrepareSecs;
                        scene.SceneStatus = GameSceneStatuses.STATUS_PREPARE;

                        scene.StateTimeData.GameType = (int)_gameType;
                        scene.StateTimeData.State    = (int)scene.SceneStatus;
                        scene.StateTimeData.EndTicks = nowTicks + _runtimeData.PrepareSecs * 1000;
                        GameManager.ClientMgr.BroadSpecialCopyMapMessage((int)TCPGameServerCmds.CMD_SPR_NOTIFY_TIME_STATE, scene.StateTimeData, scene.CopyMapInfo);
                    }
                    else if (scene.SceneStatus == GameSceneStatuses.STATUS_PREPARE)     // 场景战斗状态切换
                    {
                        if (nowSecond >= (scene.BeginTime))
                        {
                            scene.SceneStatus = GameSceneStatuses.STATUS_BEGIN;
                            scene.EndTime     = nowSecond + _runtimeData.FightingSecs;

                            scene.StateTimeData.GameType = (int)_gameType;
                            scene.StateTimeData.State    = (int)scene.SceneStatus;
                            scene.StateTimeData.EndTicks = nowTicks + _runtimeData.FightingSecs * 1000;
                            GameManager.ClientMgr.BroadSpecialCopyMapMessage((int)TCPGameServerCmds.CMD_SPR_NOTIFY_TIME_STATE, scene.StateTimeData, scene.CopyMapInfo);
                        }
                    }
                    else if (scene.SceneStatus == GameSceneStatuses.STATUS_BEGIN)       // 战斗开始
                    {
                        if (nowSecond >= scene.EndTime)
                        {
                            scene.SceneStatus = GameSceneStatuses.STATUS_END;
                            continue;
                        }

                        //要塞
                        if (scene.IsFortFlag <= 0)
                        {
                            CreateFort(scene);
                        }

                        //检查怪物
                        bool bNeedCreateMonster = false;
                        lock (scene)
                        {
                            CopyWolfWaveInfo configInfo = _runtimeData.GetWaveConfig(scene.MonsterWave);
                            if (configInfo == null)
                            {
                                scene.MonsterWaveOld = 0;
                                scene.MonsterWave    = 0;
                                scene.SceneStatus    = GameSceneStatuses.STATUS_END;
                                continue;
                            }

                            //if (scene.MonsterWave >= scene.MonsterWaveTotal)
                            //{
                            //    scene.MonsterWaveOld = scene.MonsterWave;
                            //    scene.MonsterWave = 0;
                            //    scene.SceneStatus = GameSceneStatuses.STATUS_END;
                            //    continue;
                            //}

                            //刷新下一波
                            if (scene.CreateMonsterTime > 0 && nowSecond - scene.CreateMonsterTime >= configInfo.NextTime && configInfo.NextTime > 0)
                            {
                                bNeedCreateMonster = true;
                            }

                            //怪物清除
                            if (scene.CreateMonsterTime > 0 && scene.IsMonsterFlag == 0 && scene.KilledMonsterHashSet.Count == scene.MonsterCountCreate)
                            {
                                bNeedCreateMonster = true;
                            }

                            if (scene.CreateMonsterTime <= 0)
                            {
                                bNeedCreateMonster = true;
                                scene.MonsterWave  = 0;
                            }

                            if (bNeedCreateMonster)
                            {
                                CreateMonster(scene);
                            }
                        }
                    }
                    else if (scene.SceneStatus == GameSceneStatuses.STATUS_END)
                    {
                        int leftSecond = 0;
                        if (scene.MonsterWave >= scene.MonsterWaveTotal)
                        {
                            leftSecond = (int)Math.Max(0, nowSecond - scene.EndTime);
                        }
                        GiveAwards(scene, leftSecond);

                        //结算奖励
                        scene.SceneStatus = GameSceneStatuses.STATUS_AWARD;
                        scene.EndTime     = nowSecond;
                        scene.LeaveTime   = scene.EndTime + _runtimeData.ClearRolesSecs;

                        scene.StateTimeData.GameType = (int)_gameType;
                        scene.StateTimeData.State    = (int)GameSceneStatuses.STATUS_END;
                        scene.StateTimeData.EndTicks = nowTicks + _runtimeData.ClearRolesSecs * 1000;
                        GameManager.ClientMgr.BroadSpecialCopyMapMessage((int)TCPGameServerCmds.CMD_SPR_NOTIFY_TIME_STATE, scene.StateTimeData, scene.CopyMapInfo);
                    }
                    else if (scene.SceneStatus == GameSceneStatuses.STATUS_AWARD)         // 战斗结束
                    {
                        if (nowSecond >= scene.LeaveTime)
                        {
                            copyMap.SetRemoveTicks(scene.LeaveTime);
                            scene.SceneStatus = GameSceneStatuses.STATUS_CLEAR;

                            try
                            {
                                List <GameClient> objsList = copyMap.GetClientsList();
                                if (objsList != null && objsList.Count > 0)
                                {
                                    for (int n = 0; n < objsList.Count; ++n)
                                    {
                                        GameClient c = objsList[n];
                                        if (c != null)
                                        {
                                            KuaFuManager.getInstance().GotoLastMap(c);
                                        }
                                    }
                                }
                            }
                            catch (System.Exception ex)
                            {
                                DataHelper.WriteExceptionLogEx(ex, "【狼魂要塞】清场调度异常");
                            }
                        }
                    }
                }
            }

            return;
        }
Exemplo n.º 4
0
        /// <summary>
        /// 初始化配置
        /// </summary>
        public bool InitConfig()
        {
            bool     success  = true;
            string   fileName = "";
            XElement xml      = null;
            IEnumerable <XElement> nodes;

            lock (_mutex)
            {
                try
                {
                    //怪物批次配置--------------------------------------------------------------------
                    _runtimeData.CopyWolfWaveDic.Clear();

                    fileName = Global.GameResPath("Config/LangHunYaoSai.xml");
                    xml      = CheckHelper.LoadXml(fileName);
                    if (null == xml)
                    {
                        return(false);
                    }
                    nodes = xml.Elements();
                    foreach (var xmlItem in nodes)
                    {
                        if (xmlItem == null)
                        {
                            continue;
                        }

                        CopyWolfWaveInfo config = new CopyWolfWaveInfo();
                        config.WaveID = Convert.ToInt32(Global.GetDefAttributeStr(xmlItem, "ID", "0"));

                        config.MonsterList.Clear();
                        string[] monsterArr = Global.GetDefAttributeStr(xmlItem, "MonstersID", "0,0").Split('|');
                        foreach (string monster in monsterArr)
                        {
                            string[] m = monster.Split(',');
                            config.MonsterList.Add(new int[] { int.Parse(m[0]), int.Parse(m[1]) });
                        }

                        config.NextTime = Convert.ToInt32(Global.GetDefAttributeStr(xmlItem, "NextTime", "60"));

                        config.MonsterSiteDic.Clear();
                        string[] siteArr = Global.GetDefAttributeStr(xmlItem, "Site", "0,0,0").Split('|');
                        foreach (string site in siteArr)
                        {
                            string[] s = site.Split(',');

                            CopyWolfSiteInfo siteInfo = new CopyWolfSiteInfo();
                            siteInfo.X      = int.Parse(s[0]);
                            siteInfo.Y      = int.Parse(s[1]);
                            siteInfo.Radius = int.Parse(s[2]);

                            config.MonsterSiteDic.Add(siteInfo);
                        }

                        _runtimeData.CopyWolfWaveDic.Add(config.WaveID, config);
                    }

                    //怪物对要塞伤害--------------------------------------------------------------------
                    string[] monsterHurtArr = GameManager.systemParamsList.GetParamValueByName("LangHunYaoSaiMonstersHurt").Split('|');
                    foreach (string monsterHurt in monsterHurtArr)
                    {
                        string[] h = monsterHurt.Split(',');
                        _runtimeData.MonsterHurtDic.Add(int.Parse(h[0]), int.Parse(h[1]));
                    }

                    //积分系数--------------------------------------------------------------------
                    _runtimeData.ScoreRateTime = (int)GameManager.systemParamsList.GetParamValueIntByName("LangHunYaoSaiTimeNum");
                    _runtimeData.ScoreRateLife = (int)GameManager.systemParamsList.GetParamValueIntByName("LangHunYaoSaiLifeNum");

                    //要塞--------------------------------------------------------------------------------
                    int[] forts = GameManager.systemParamsList.GetParamValueIntArrayByName("LangHunYaoSaiMonsters");
                    _runtimeData.FortMonsterID = forts[0];
                    _runtimeData.FortSite.X    = forts[1];
                    _runtimeData.FortSite.Y    = forts[2];
                }
                catch (System.Exception ex)
                {
                    success = false;
                    LogManager.WriteLog(LogTypes.Fatal, string.Format("加载xml配置文件:{0}, 失败。", fileName), ex);
                }
            }

            return(success);
        }
Exemplo n.º 5
0
        public void CreateMonster(CopyWolfSceneInfo scene, int upWave = 1)
        {
            CopyMap          copyMap    = scene.CopyMapInfo;
            CopyWolfWaveInfo waveConfig = null;
            GameMap          gameMap    = null;

            if (!GameManager.MapMgr.DictMaps.TryGetValue(scene.MapID, out gameMap))
            {
                LogManager.WriteLog(LogTypes.Error, string.Format("【狼魂要塞】报错 地图配置 ID = {0}", scene.MapID), null, true);
            }
            else
            {
                long nowTicket = TimeUtil.NOW();
                long nowSecond = nowTicket / 1000L;
                lock (scene)
                {
                    if (scene.MonsterWave >= scene.MonsterWaveTotal)
                    {
                        scene.MonsterWaveOld = scene.MonsterWave;
                        scene.MonsterWave    = 0;
                        scene.SceneStatus    = GameSceneStatuses.STATUS_END;
                    }
                    else
                    {
                        scene.IsMonsterFlag = 1;
                        int wave = scene.MonsterWave + upWave;
                        if (wave > scene.MonsterWaveTotal)
                        {
                            wave = scene.MonsterWaveTotal;
                        }
                        waveConfig = this._runtimeData.GetWaveConfig(wave);
                        if (waveConfig == null)
                        {
                            LogManager.WriteLog(LogTypes.Error, string.Format("【狼魂要塞】报错 刷怪波次 = {0}", wave), null, true);
                        }
                        else
                        {
                            scene.MonsterWave       = wave;
                            scene.CreateMonsterTime = nowSecond;
                            int totalCount = 0;
                            int gridNum    = 0;
                            CreateMonsterTagInfo tagInfo = new CreateMonsterTagInfo();
                            tagInfo.FuBenSeqId  = scene.FuBenSeqId;
                            tagInfo.IsFort      = false;
                            tagInfo.ManagerType = 34;
                            foreach (CopyWolfSiteInfo siteInfo in waveConfig.MonsterSiteDic)
                            {
                                int gridX = gameMap.CorrectWidthPointToGridPoint(siteInfo.X + Global.GetRandomNumber(-siteInfo.Radius, siteInfo.Radius)) / gameMap.MapGridWidth;
                                int gridY = gameMap.CorrectHeightPointToGridPoint(siteInfo.Y + Global.GetRandomNumber(-siteInfo.Radius, siteInfo.Radius)) / gameMap.MapGridHeight;
                                foreach (int[] monster in waveConfig.MonsterList)
                                {
                                    int monsterID    = monster[0];
                                    int monsterCount = monster[1];
                                    totalCount += monsterCount;
                                    GameManager.MonsterZoneMgr.AddDynamicMonsters(scene.MapID, monsterID, scene.CopyMapInfo.CopyMapID, monsterCount, gridX, gridY, gridNum, 0, SceneUIClasses.CopyWolf, tagInfo, null);
                                }
                            }
                            scene.MonsterCountCreate += totalCount;
                            scene.ScoreData.Wave      = waveConfig.WaveID;
                            scene.ScoreData.EndTime   = nowTicket + (long)(waveConfig.NextTime * 1000);
                            GameManager.ClientMgr.BroadSpecialCopyMapMessage <CopyWolfScoreData>(1025, scene.ScoreData, scene.CopyMapInfo);
                        }
                    }
                }
            }
        }
Exemplo n.º 6
0
        public void TimerProc()
        {
            long nowTicks = TimeUtil.NOW();

            if (nowTicks >= CopyWolfManager._nextHeartBeatTicks)
            {
                CopyWolfManager._nextHeartBeatTicks = nowTicks + 1020L;
                long nowSecond = nowTicks / 1000L;
                foreach (CopyWolfSceneInfo scene in this._runtimeData.SceneDict.Values)
                {
                    lock (CopyWolfManager._mutex)
                    {
                        int nID     = scene.FuBenSeqId;
                        int nCopyID = scene.CopyID;
                        int nMapID  = scene.MapID;
                        if (nID >= 0 && nCopyID >= 0 && nMapID >= 0)
                        {
                            CopyMap copyMap = scene.CopyMapInfo;
                            if (scene.SceneStatus == GameSceneStatuses.STATUS_NULL)
                            {
                                scene.PrepareTime            = nowSecond;
                                scene.BeginTime              = nowSecond + (long)this._runtimeData.PrepareSecs;
                                scene.SceneStatus            = GameSceneStatuses.STATUS_PREPARE;
                                scene.StateTimeData.GameType = 11;
                                scene.StateTimeData.State    = (int)scene.SceneStatus;
                                scene.StateTimeData.EndTicks = nowTicks + (long)(this._runtimeData.PrepareSecs * 1000);
                                GameManager.ClientMgr.BroadSpecialCopyMapMessage <GameSceneStateTimeData>(827, scene.StateTimeData, scene.CopyMapInfo);
                            }
                            else if (scene.SceneStatus == GameSceneStatuses.STATUS_PREPARE)
                            {
                                if (nowSecond >= scene.BeginTime)
                                {
                                    scene.SceneStatus            = GameSceneStatuses.STATUS_BEGIN;
                                    scene.EndTime                = nowSecond + (long)this._runtimeData.FightingSecs;
                                    scene.StateTimeData.GameType = 11;
                                    scene.StateTimeData.State    = (int)scene.SceneStatus;
                                    scene.StateTimeData.EndTicks = nowTicks + (long)(this._runtimeData.FightingSecs * 1000);
                                    GameManager.ClientMgr.BroadSpecialCopyMapMessage <GameSceneStateTimeData>(827, scene.StateTimeData, scene.CopyMapInfo);
                                }
                            }
                            else if (scene.SceneStatus == GameSceneStatuses.STATUS_BEGIN)
                            {
                                if (nowSecond >= scene.EndTime)
                                {
                                    scene.SceneStatus = GameSceneStatuses.STATUS_END;
                                }
                                else
                                {
                                    if (scene.IsFortFlag <= 0)
                                    {
                                        this.CreateFort(scene);
                                    }
                                    bool bNeedCreateMonster = false;
                                    lock (scene)
                                    {
                                        CopyWolfWaveInfo configInfo = this._runtimeData.GetWaveConfig(scene.MonsterWave);
                                        if (configInfo == null)
                                        {
                                            scene.MonsterWaveOld = 0;
                                            scene.MonsterWave    = 0;
                                            scene.SceneStatus    = GameSceneStatuses.STATUS_END;
                                        }
                                        else
                                        {
                                            if (scene.CreateMonsterTime > 0L && nowSecond - scene.CreateMonsterTime >= (long)configInfo.NextTime && configInfo.NextTime > 0)
                                            {
                                                bNeedCreateMonster = true;
                                            }
                                            if (scene.CreateMonsterTime > 0L && scene.IsMonsterFlag == 0 && scene.KilledMonsterHashSet.Count == scene.MonsterCountCreate)
                                            {
                                                bNeedCreateMonster = true;
                                            }
                                            if (scene.CreateMonsterTime <= 0L)
                                            {
                                                bNeedCreateMonster = true;
                                                scene.MonsterWave  = 0;
                                            }
                                            if (bNeedCreateMonster)
                                            {
                                                this.CreateMonster(scene, 1);
                                            }
                                        }
                                    }
                                }
                            }
                            else if (scene.SceneStatus == GameSceneStatuses.STATUS_END)
                            {
                                int leftSecond = 0;
                                if (scene.MonsterWave >= scene.MonsterWaveTotal)
                                {
                                    leftSecond = (int)Math.Max(0L, nowSecond - scene.EndTime);
                                }
                                this.GiveAwards(scene, leftSecond);
                                scene.SceneStatus            = GameSceneStatuses.STATUS_AWARD;
                                scene.EndTime                = nowSecond;
                                scene.LeaveTime              = scene.EndTime + (long)this._runtimeData.ClearRolesSecs;
                                scene.StateTimeData.GameType = 11;
                                scene.StateTimeData.State    = 3;
                                scene.StateTimeData.EndTicks = nowTicks + (long)(this._runtimeData.ClearRolesSecs * 1000);
                                GameManager.ClientMgr.BroadSpecialCopyMapMessage <GameSceneStateTimeData>(827, scene.StateTimeData, scene.CopyMapInfo);
                            }
                            else if (scene.SceneStatus == GameSceneStatuses.STATUS_AWARD)
                            {
                                if (nowSecond >= scene.LeaveTime)
                                {
                                    copyMap.SetRemoveTicks(scene.LeaveTime);
                                    scene.SceneStatus = GameSceneStatuses.STATUS_CLEAR;
                                    try
                                    {
                                        List <GameClient> objsList = copyMap.GetClientsList();
                                        if (objsList != null && objsList.Count > 0)
                                        {
                                            for (int i = 0; i < objsList.Count; i++)
                                            {
                                                GameClient c = objsList[i];
                                                if (c != null)
                                                {
                                                    KuaFuManager.getInstance().GotoLastMap(c);
                                                }
                                            }
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        DataHelper.WriteExceptionLogEx(ex, "【狼魂要塞】清场调度异常");
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }