Exemple #1
0
    // 更新触发状态(继承自sdBehaviourState)aa
    public override void UpdateState()
    {
        if (mIsInState == true)
        {
            mCurrentDelayTime -= Time.deltaTime;
            if (mCurrentDelayTime <= 0.0f)
            {
                if (mExecuteStatus)
                {
                    return;
                }

                mExecuteStatus = true;

                MonsterAutoFight kMonsterAutoFight = mBehaviourAdvancedState.MonsterAutoFightComponent;
                if (kMonsterAutoFight != null)
                {
                    sdGameMonster kMonster = kMonsterAutoFight.Actor as sdGameMonster;
                    if (kMonster != null)
                    {
                        kMonster.RemoveBuff(mBuffID);
                    }
                }
            }
        }
    }
Exemple #2
0
    // 触发事件aa
    public override void DoAsyncAction()
    {
        if (mCount == 0)
        {
            return;
        }

        mDelayTime -= Time.deltaTime;
        if (mDelayTime <= 0)
        {
            MonsterAutoFight kMonsterAutoFight = mBehaviourAdvancedState.MonsterAutoFightComponent;
            if (mBuffBehaviourActionTargetType == EBuffBehaviourActionTargetType.enBBATT_Self)
            {
                kMonsterAutoFight.Actor.AddBuff(mBuffID, -1, kMonsterAutoFight.Actor);
            }
            else
            {
                if (mBehaviourAdvancedState.BehaviourStateBlock.Target != null)
                {
                    mBehaviourAdvancedState.BehaviourStateBlock.Target.AddBuff(mBuffID, -1, kMonsterAutoFight.Actor);
                }
            }

            mDelayTime = mIntervalTime;

            --mCount;
        }
    }
Exemple #3
0
    // 更新触发状态(继承自sdBehaviourState)aa
    public override void UpdateState()
    {
        if (mIsInState == true)
        {
            mCurrentDelayTime -= Time.deltaTime;
            if (mCurrentDelayTime <= 0.0f)
            {
                if (mExecuteStatus)
                {
                    return;
                }

                mExecuteStatus = true;

                MonsterAutoFight kMonsterAutoFight = mBehaviourAdvancedState.MonsterAutoFightComponent;
                if (kMonsterAutoFight != null)
                {
                    sdGameMonster kMonster = kMonsterAutoFight.Actor as sdGameMonster;
                    if (kMonster != null)
                    {
                        if (kMonster.skillTree != null)
                        {
                            sdSkill kSkill = kMonster.skillTree.getSkill(mSkillID);
                            if (kSkill != null)
                            {
                                mSkillStatus        = kSkill.skillEnabled;
                                kSkill.skillEnabled = false;
                            }
                        }
                    }
                }
            }
        }
    }
Exemple #4
0
    // 离开触发状态(继承自sdBehaviourState)aa
    public override void DoLeaveState()
    {
        if (mIsInState != false)
        {
            mIsInState = false;

            if (mExecuteStatus)
            {
                MonsterAutoFight kMonsterAutoFight = mBehaviourAdvancedState.MonsterAutoFightComponent;
                if (kMonsterAutoFight != null)
                {
                    sdGameMonster kMonster = kMonsterAutoFight.Actor as sdGameMonster;
                    if (kMonster != null)
                    {
                        if (kMonster.skillTree != null)
                        {
                            sdSkill kSkill = kMonster.skillTree.getSkill(mSkillID);
                            if (kSkill != null)
                            {
                                kSkill.skillEnabled = mSkillStatus;
                            }
                        }
                    }
                }
            }
        }
    }
Exemple #5
0
    // 更新触发状态(继承自sdBehaviourState)aa
    public override void UpdateState()
    {
        if (mIsInState == true)
        {
            mCurrentDelayTime -= Time.deltaTime;
            if (mCurrentDelayTime <= 0.0f)
            {
                if (mExecuteStatus)
                {
                    return;
                }

                mExecuteStatus = true;

                MonsterAutoFight kMonsterAutoFight = mBehaviourAdvancedState.MonsterAutoFightComponent;
                if (kMonsterAutoFight != null)
                {
                    sdGameMonster kMonster = kMonsterAutoFight.Actor as sdGameMonster;
                    if (kMonster != null)
                    {
                        mOldLayerIndex            = kMonster.gameObject.layer;
                        kMonster.gameObject.layer = LayerMask.NameToLayer(mLayerName);
                    }
                }
            }
        }
    }
Exemple #6
0
    // 离开触发状态(继承自sdBehaviourState)aa
    public override void DoLeaveState()
    {
        if (mIsInState != false)
        {
            mIsInState = false;

            if (mExecuteStatus)
            {
                MonsterAutoFight kMonsterAutoFight = mBehaviourAdvancedState.MonsterAutoFightComponent;
                if (kMonsterAutoFight != null)
                {
                    sdGameMonster kMonster = kMonsterAutoFight.Actor as sdGameMonster;
                    if (kMonster != null)
                    {
                        Renderer[] akRenderer = kMonster.RenderNode.GetComponentsInChildren <Renderer>();
                        if (akRenderer != null)
                        {
                            for (int i = 0; i < akRenderer.GetLength(0); ++i)
                            {
                                Renderer kRenderer = akRenderer[i];
                                if (kRenderer.gameObject.name.Equals(mMeshName))
                                {
                                    kRenderer.enabled = mMeshStatus;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
Exemple #7
0
    // 更新触发状态(继承自sdBehaviourState)aa
    public override void UpdateState()
    {
        if (mIsInState == true)
        {
            mCurrentDelayTime -= Time.deltaTime;
            if (mCurrentDelayTime <= 0.0f)
            {
                if (mExecuteStatus)
                {
                    return;
                }

                mExecuteStatus = true;

                MonsterAutoFight kMonsterAutoFight = mBehaviourAdvancedState.MonsterAutoFightComponent;
                if (kMonsterAutoFight != null)
                {
                    sdGameMonster kMonster = kMonsterAutoFight.Actor as sdGameMonster;
                    if (kMonster != null)
                    {
                        AnimationState kAnimationState = kMonster.AnimController[mAnimationName];
                        if (kAnimationState != null)
                        {
                            kMonster.logicTSM.ForceStop();                              //< 强制停止当前技能aa

                            kAnimationState.layer    = 11;
                            kAnimationState.wrapMode = WrapMode.Once;
                            kMonster.AnimController.Play(mAnimationName);
                        }
                    }
                }
            }
        }
    }
Exemple #8
0
    // 更新触发状态(继承自sdBehaviourState)aa
    public override void UpdateState()
    {
        if (mIsInState == true)
        {
            mCurrentDelayTime -= Time.deltaTime;
            if (mCurrentDelayTime <= 0.0f)
            {
                MonsterAutoFight kMonsterAutoFight = mBehaviourAdvancedState.MonsterAutoFightComponent;
                PetAutoFight     kPetAutoFight     = kMonsterAutoFight as PetAutoFight;
                if (kPetAutoFight != null)
                {
                    sdGameMonster kMonster = kMonsterAutoFight.Actor as sdGameMonster;
                    if (kMonster != null)
                    {
                        int iSkillID = mSkillID;
                        if (iSkillID == -1 || iSkillID == 0)
                        {
                            iSkillID = (int)kMonster.Property["SpSkill"];                               //< 尝试获取手动技能aa
                        }
                        int iErroeCode = 0;
                        kPetAutoFight.DoXPSkill(iSkillID, ref iErroeCode);
                    }
                }

                mCurrentDelayTime = 0.0f;
            }
        }
    }
Exemple #9
0
 // 鎬?墿缇ゆ垚鍛樺彈浼ゅ?鎴栬€呭彂鐜扮?涓€涓?洰鏍囧洖璋僡a
 public void OnAreaGroupAlert(sdActorInterface kAttacker)
 {
     if (GetActorType() == ActorType.AT_Monster)
     {
         MonsterAutoFight kMonsterAutoFight = mAutoFight as MonsterAutoFight;
         kMonsterAutoFight.OnFriendHurt(kAttacker);                  //< 鏀诲嚮缇ゆ垚鍛樿?浣滄敾鍑昏嚜宸半缇ゆ垚鍛樺彂鐜扮洰鏍囪?浣滆嚜宸卞彂鐜癮a
     }
 }
Exemple #10
0
    // 离开触发状态(继承自sdBehaviourState)aa
    public override void DoLeaveState()
    {
        if (mIsInState != false)
        {
            mIsInState = false;

            if (mExecuteStatus)
            {
                MonsterAutoFight kMonsterAutoFight = mBehaviourAdvancedState.MonsterAutoFightComponent;
                if (kMonsterAutoFight != null)
                {
                    kMonsterAutoFight.BattleDistance = mOldBattleDistance;
                }
            }
        }
    }
Exemple #11
0
    // 离开触发状态(继承自sdBehaviourState)aa
    public override void DoLeaveState()
    {
        if (mIsInState != false)
        {
            mIsInState = false;

            if (mExecuteStatus)
            {
                MonsterAutoFight kMonsterAutoFight = mBehaviourAdvancedState.MonsterAutoFightComponent;
                if (kMonsterAutoFight != null)
                {
                    sdGameMonster kMonster = kMonsterAutoFight.Actor as sdGameMonster;
                    if (kMonster != null)
                    {
                        kMonster.AddBuff(mBuffID, 0, kMonster);
                    }
                }
            }
        }
    }
Exemple #12
0
    // 离开触发状态(继承自sdBehaviourState)aa
    public override void DoLeaveState()
    {
        if (mIsInState != false)
        {
            mIsInState = false;

            if (mExecuteStatus)
            {
                MonsterAutoFight kMonsterAutoFight = mBehaviourAdvancedState.MonsterAutoFightComponent;
                if (kMonsterAutoFight != null)
                {
                    sdGameMonster kMonster = kMonsterAutoFight.Actor as sdGameMonster;
                    if (kMonster != null)
                    {
                        kMonster.gameObject.layer = mOldLayerIndex;
                    }
                }
            }
        }
    }
    // 更新最近的敌方的距离(这里的距离是到对方边缘的距离)aa
    public float UpdateDistanceOfNearestEnemy(sdBehaviourAdvancedState kBehaviourAdvancedState)
    {
        if (Time.time - mDistanceOfNearestEnemyUpdateTime > 1.0f)
        {
            float fSkillDistance = float.MaxValue;

            MonsterAutoFight kMonsterAutoFight = kBehaviourAdvancedState.MonsterAutoFightComponent;
            sdActorInterface kActor            = kMonsterAutoFight.Monster;
            sdActorInterface kTarget           = kMonsterAutoFight.GetAttackTarget();
            if (kActor != null && kTarget != null)
            {
                fSkillDistance = kMonsterAutoFight.CalcSkillDistance(kActor, kTarget);
            }

            mDistanceOfNearestEnemyUpdateTime = Time.time;
            mDistanceOfNearestEnemy           = fSkillDistance;
        }

        return(mDistanceOfNearestEnemy);
    }
Exemple #14
0
    // 更新触发状态(继承自sdBehaviourState)aa
    public override void UpdateState()
    {
        if (mIsInState == true)
        {
            mCurrentDelayTime -= Time.deltaTime;
            if (mCurrentDelayTime <= 0.0f)
            {
                if (mExecuteStatus)
                {
                    return;
                }

                mExecuteStatus = true;

                MonsterAutoFight kMonsterAutoFight = mBehaviourAdvancedState.MonsterAutoFightComponent;
                if (kMonsterAutoFight != null)
                {
                    sdGameMonster kMonster = kMonsterAutoFight.Actor as sdGameMonster;
                    if (kMonster != null)
                    {
                        Renderer[] akRenderer = kMonster.RenderNode.GetComponentsInChildren <Renderer>();
                        if (akRenderer != null)
                        {
                            for (int i = 0; i < akRenderer.GetLength(0); ++i)
                            {
                                Renderer kRenderer = akRenderer[i];
                                if (kRenderer.gameObject.name.Equals(mMeshName))
                                {
                                    mMeshStatus       = kRenderer.enabled;
                                    kRenderer.enabled = false;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
Exemple #15
0
    // 更新触发状态(继承自sdBehaviourState)aa
    public override void UpdateState()
    {
        if (mIsInState == true)
        {
            mCurrentDelayTime -= Time.deltaTime;
            if (mCurrentDelayTime <= 0.0f)
            {
                if (mExecuteStatus)
                {
                    return;
                }

                mExecuteStatus = true;

                MonsterAutoFight kMonsterAutoFight = mBehaviourAdvancedState.MonsterAutoFightComponent;
                if (kMonsterAutoFight != null)
                {
                    mOldBattleDistance = kMonsterAutoFight.BattleDistance;
                    kMonsterAutoFight.BattleDistance = mBattleDistance;
                }
            }
        }
    }
Exemple #16
0
    // 设置战斗系统配接器aa
    public void SetMonsterAutoFight(MonsterAutoFight kMonsterAutoFight)
    {
        if (mMonsterAutoFight == kMonsterAutoFight)
        {
            return;
        }

        if (mMonsterAutoFight != null)
        {
            sdGameMonster kMonster = mMonsterAutoFight.Monster;
            kMonster.NotifySummoned       -= NotifySummoned;
            kMonster.NotifyKilled         -= NotifyKilled;
            kMonster.NotifyAddHP          -= NotifyAddHP;
            kMonster.NotifyChangeTarget   -= NotifyChangeTarget;
            kMonster.NotifyAddDebuffState -= NotifyAddDebuffState;
        }

        if (kMonsterAutoFight != null)
        {
            sdGameMonster kMonster = kMonsterAutoFight.Monster;
            kMonster.NotifySummoned       += NotifySummoned;
            kMonster.NotifyKilled         += NotifyKilled;
            kMonster.NotifyAddHP          += NotifyAddHP;
            kMonster.NotifyChangeTarget   += NotifyChangeTarget;
            kMonster.NotifyAddDebuffState += NotifyAddDebuffState;
        }

        mMonsterAutoFight = kMonsterAutoFight;

        int iAIID = (int)kMonsterAutoFight.Monster.Property["AIID"];

        mBehaviourEventTree = sdAITable.GetSingleton().GetBehaviourEventTree(iAIID);
        if (mBehaviourEventTree != null)
        {
            mBehaviourEventTree.SetBehaviourAdvancedState(this);
        }
    }
Exemple #17
0
    // 更新触发状态(继承自sdBehaviourState)aa
    public override void UpdateState()
    {
        if (mIsInState == true)
        {
            if (mCurrentCount != 0)
            {
                mCurrentDelayTime -= Time.deltaTime;
                if (mCurrentDelayTime <= 0.0f)
                {
                    float fRandom = Random.Range(0, 10000) / 10000.0f;
                    if (fRandom <= mBuffProbility)
                    {
                        MonsterAutoFight kMonsterAutoFight = mBehaviourAdvancedState.MonsterAutoFightComponent;
                        if (kMonsterAutoFight != null)
                        {
                            if (mBuffBehaviourActionTargetType == EBuffBehaviourActionTargetType.enBBATT_Self)
                            {
                                kMonsterAutoFight.Actor.AddBuff(mBuffID, -1, kMonsterAutoFight.Actor);
                            }
                            else
                            {
                                if (mBehaviourAdvancedState.BehaviourStateBlock.Target != null)
                                {
                                    mBehaviourAdvancedState.BehaviourStateBlock.Target.AddBuff(mBuffID, -1, kMonsterAutoFight.Actor);
                                }
                            }
                        }
                    }

                    mCurrentDelayTime = mIntervalTime;

                    --mCurrentCount;
                }
            }
        }
    }
Exemple #18
0
    //
    protected override void Start()
    {
        base.Start();

        // 鑾峰彇妯″瀷鍙婃帶鍒跺櫒淇℃伅aa
        GameObject rootRenderNode = transform.FindChild("@RenderNode").gameObject;

        gatherRenderNodesInfo(rootRenderNode);
        gatherMeshes(rootRenderNode);
        GatherMeshShaders();
        renderNode = rootRenderNode;
        renderNode.SetActive(false);

        for (int k = 0; k < renderNode.transform.childCount; ++k)
        {
            Transform kChildNode = renderNode.transform.GetChild(k);
            if (kChildNode.name.Equals("Bip01"))
            {
                boneRoot = kChildNode.gameObject;
                break;
            }
        }

        mAnimController = renderNode.GetComponent <Animation>();
//		mAnimController.enabled = false;

        mMotionController         = this.gameObject.GetComponent <CharacterController>();
        mMotionController.enabled = false;

        mNavAgent         = this.gameObject.GetComponent <NavMeshAgent>();
        mNavAgent.enabled = false;

        mSelfAudioSource = this.gameObject.GetComponent <AudioSource>();
//		mSelfAudioSource.enabled = false;

        // 鍦烘櫙淇℃伅aa
        mMainCamera = sdGameLevel.instance.mainCamera.GetComponent <Camera>();
        mTuituLogic = sdGameLevel.instance.tuiTuLogic;

        // 鍔犺浇鎬?墿灞炴€ц〃(鍩虹?灞炴€﹁aa
        if (ActorType.AT_Pet == GetActorType())
        {
            Hashtable kTable = sdNewPetMgr.Instance.GetPetPropertyFromDBID(mDBID);
            Property = sdConfDataMgr.CloneHashTable(kTable);
        }
        else
        {
            Hashtable kMonsterProperty = sdConfDataMgr.Instance().GetTable("MonsterProperty");
            if (Application.platform == RuntimePlatform.WindowsEditor)
            {
                if (!kMonsterProperty.ContainsKey(templateId))
                {
                    Debug.LogError("monster templateID error=" + templateId);
                }
            }
            Hashtable kTable = kMonsterProperty[templateId] as Hashtable;
            Property = sdConfDataMgr.CloneHashTable(kTable);

            //娣辨笂BOSS闇€瑕佺壒娈婂?鐞嗚?閲庬.
            if (isLapBoss && !sdGameLevel.instance.testMode)
            {
                if (sdActGameMgr.Instance.m_uuLapBossLastBlood > 0)
                {
                    Property["HP"] = (int)sdActGameMgr.Instance.m_uuLapBossLastBlood;
                }
                else
                {
                    Property["HP"] = (int)sdActGameMgr.Instance.m_uuWorldBossLastBlood;
                }
            }
            else
            {
                Property["HP"] = Property["MaxHP"];     //< 淇??琛€閲庣鍙?湁鎬?墿闇€瑕佷慨姝㈣aa
            }
        }

        Property["MaxSP"] = 100;                        //< 淇??鏈€楂樻硶鍔涘€糰a
        Property["SP"]    = Property["MaxSP"];          //< 淇??娉曞姏鍊糰a

        // 鍒濆?鍖栬?鑹叉秷澶辨椂闂碼a
        mDisappeared  = false;
        mDisapearTime = (int)Property["DisappearTime"] / 1000.0f;

        //
        m_summonInfo  = sdConfDataMgr.CloneHashTable(sdConfDataMgr.Instance().m_BaseSummon);
        m_SkillEffect = sdConfDataMgr.CloneHashTable(sdConfDataMgr.Instance().m_BaseSkillEffect);

        // 鍒濆?鍖栬?鏉?a
        LoadHPUI();

        // 鍒濆?鍖栭€変腑鐩?爣鐗规晥aa
        //if (GetActorType() == ActorType.AT_Pet)
        //	LoadTargetEffect();

        // 鍒涘缓鎶€鑳絘a
        CreateSkill_Action((ulong)templateId);

        // 鍒濆?鍖栦釜浣揂I鍙傛暟aa
        if (ActorType.AT_Pet == GetActorType())
        {
            if (mAnimController != null)
            {
                mAnimController.cullingType = AnimationCullingType.AlwaysAnimate;
            }

            PetAutoFight kPetAutoFight = new PetAutoFight();
            kPetAutoFight.FollowDistance       = ((int)Property["FollowDistance"]) / 1000.0f;
            kPetAutoFight.BattleFollowDistance = ((int)Property["BattleFollowDistance"]) / 1000.0f;
            kPetAutoFight.EyeDistance          = ((int)Property["EyeSize"]) / 1000.0f;
            kPetAutoFight.Enable = useAI;

            kPetAutoFight.AutoRetreat              = (int)(Property["Retreat"]) != 0;
            kPetAutoFight.RetreatDetectInterval    = ((int)Property["RetreatDetectInterval"]) / 1000.0f;
            kPetAutoFight.RetreatDetectMinDistance = ((int)Property["RetreatDetectMinDistance"]) / 1000.0f;
            kPetAutoFight.RetreatElapseTime        = ((int)Property["RetreatElapseTime"]) / 1000.0f;

            kPetAutoFight.NotifyChangeTarget += NotifyBattleSystemChangeTarget;

            sdSkill kSkill = skillTree.getSkill(1001);
            if (kSkill != null)
            {
                sdBaseState kState        = kSkill.actionStateList[0];
                int         iCastDistance = (int)kState.stateData["CastDistance"];
                kPetAutoFight.BattleDistance = (iCastDistance) * 0.001f;
            }

            mAutoFight = kPetAutoFight;
            mAutoFight.SetActor(this);
        }
        else
        {
            MonsterAutoFight kMonsterAutoFight = new MonsterAutoFight();
            kMonsterAutoFight.EyeDistance   = ((int)Property["EyeSize"]) / 1000.0f;
            kMonsterAutoFight.ChaseDistance = ((int)Property["ChaseSize"]) / 1000.0f;
            kMonsterAutoFight.Enable        = useAI;

            kMonsterAutoFight.NotifyChangeTarget += NotifyBattleSystemChangeTarget;

            sdSkill kSkill = skillTree.getSkill(1001);
            if (kSkill != null)
            {
                sdBaseState kState        = kSkill.actionStateList[0];
                int         iCastDistance = (int)kState.stateData["CastDistance"];
                kMonsterAutoFight.BattleDistance = (iCastDistance) * 0.001f;
            }

            mAutoFight = kMonsterAutoFight;
            mAutoFight.SetActor(this);
        }

        // 鍒濆?鍖栫兢浣揂I鍙傛暟aa
        if (ActorType.AT_Pet == GetActorType())
        {
            sdBehaviourNode kBehaviourNode = sdBehaviourManager.GetSingleton().GetBehaviourNode(1);
            if (kBehaviourNode != null)
            {
                kBehaviourNode.AddActor(this);
            }
        }

        //
        LoadShadow();
    }
Exemple #19
0
    // 更新触发状态(继承自sdBehaviourState)aa
    public override void UpdateState()
    {
        if (mIsInState != true)
        {
            return;
        }

        if (mCurrentCount == 0)
        {
            return;
        }

        mCurrentDelayTime -= Time.deltaTime;
        if (mCurrentDelayTime <= 0.0f)
        {
            // 当前技能不存在则随机一个技能aa
            if (mCurrentSkillID == -1)
            {
                mCurrentSkillID = RandomSkill();
            }

            // 检查技能范围,尝试释放技能aa
            bool bCastSkill = false;
            if (mCurrentSkillID > 0)
            {
                MonsterAutoFight kMonsterAutoFight = mBehaviourAdvancedState.MonsterAutoFightComponent;
                sdGameMonster    kMonster          = kMonsterAutoFight.Monster;

                if (mDetectDistance)
                {
                    sdSkill kSkill = kMonster.skillTree.getSkill(mCurrentSkillID);
                    if (kSkill != null)
                    {
                        sdBaseState kState    = kSkill.actionStateList[0];
                        float       fDistance = (int)kState.stateData["CastDistance"] * 0.001f;
                        HeaderProto.ESkillObjType eTergetType = (HeaderProto.ESkillObjType)kState.stateData["byTargetType"];

                        float fCurrentDistance = 0.0f;
                        sdBehaviourStateBlock kBehaviourStateBlock = mBehaviourAdvancedState.BehaviourStateBlock;
                        if (eTergetType == HeaderProto.ESkillObjType.SKILL_OBJ_ENEMY)
                        {
                            fCurrentDistance = kBehaviourStateBlock.UpdateDistanceOfNearestEnemy(mBehaviourAdvancedState);
                        }
                        else
                        {
                            fCurrentDistance = kBehaviourStateBlock.UpdateDistanceOfNearestFriend(mBehaviourAdvancedState);
                        }

                        if (fCurrentDistance < fDistance)
                        {
                            kMonster.CastSkill(mCurrentSkillID);
                            bCastSkill = true;
                        }
                    }
                }
                else
                {
                    kMonster.CastSkill(mCurrentSkillID);
                    bCastSkill = true;
                }
            }

            // 释放技能成功则延迟一个mIntervalTime,否则仅仅延迟2s检查一次直到释放成功aa
            if (bCastSkill)
            {
                mCurrentSkillID   = -1;
                mCurrentDelayTime = mIntervalTime;

                --mCurrentCount;
            }
            else
            {
                mCurrentDelayTime = 2.0f;
            }
        }
    }