//[조건] 소환&스킬
    //* N번 : 해당 언데드히어로가 보유한 소환유닛/스킬 슬롯의
    //* 현재 보유 SP/MP 및 쿨타임, 최대소환개수 등을 따져서
    //   소환/스킬 가능한지 판단

    // N번소환유닛소환가능? SUMMON_SLOT_NUM
    bool checkCanSummon(Monster mon, AISlot ai)
    {
        // To do!!
        //mon.action.
        //mon.stageMonsterData.units[summonSlotNum]
        return(mon.unitSlots[summonSlotNum].canUse());
    }
示例#2
0
 sealed public override void clearSkillData()
 {
     base.clearSkillData();
     _nowSelectedAISlot = null;
     _state             = STATE_PREPARE;
     mon.setPlayAniRightNow(Monster.NORMAL);
 }
    // N번스킬사용가능? SKILL_NUM
    bool checkCanUseSkill(Monster mon, AISlot ai)
    {
        // To do!!

        //Debug.Log(mon.skillSlots + "   " + skillNum);

        return(mon.skillSlots[skillNum].canUse());
    }
 // N%확률로 EXE_CHANCE
 bool checkExeChange(Monster mon, AISlot ai)
 {
     tempI = GameManager.inGameRandom.Range(0, 100);       //GameManager.getRandomNum();
     _tb   = (tempI < executeChange);
     ai.resetCoolTime();
     if (_tb)
     {
         ++ai.excuteCount;
     }
     return(_tb);
 }
    public bool firstCheck(Monster mon, AISlot ai)
    {
        for (int i = 0; i < _firstCheckerNum; ++i)
        {
            if (firstCheckers[i](mon, ai) == false)
            {
                return(false);
            }
        }

        return(true);
    }
示例#6
0
    sealed public override void onCompleteAttackAni(bool isClearActionType = false)
    {
        if (_nowSelectedAISlot != null)
        {
            _nextCheckAI = _nowSelectedAISlot.ai.nextAi;

            if (_nowSelectedAISlot.ai.actionType == MonsterHeroAI.ActionType.SKILL2)
            {
                mon.setSkillTarget(null);
            }

            if (string.IsNullOrEmpty(_nextCheckAI) == false)
            {
                _hasNextCheckAI = true;
            }
        }

        _nowSelectedAISlot = null;
        _state             = STATE_PREPARE;
        mon.setPlayAniRightNow(Monster.NORMAL);
    }
    public bool check(Monster mon, AISlot ai, bool isSkill2Mode = false)
    {
        if (maxExcuteNum > 0 && ai.excuteCount >= maxExcuteNum)
        {
            return(false);
        }

        if (isSkill2Mode)
        {
            if (actionType != ActionType.SUMMON)
            {
                return(false);
            }
        }

        for (int i = 0; i < _firstCheckerNum; ++i)
        {
            if (firstCheckers[i](mon, ai) == false)
            {
                return(false);
            }
        }

        for (int i = 0; i < _checkerNum; ++i)
        {
            if (checkers[i](mon, ai) == false)
            {
#if UNITY_EDITOR
                //if(DebugManager.instance.useDebug)	 Debug.Log("ai Id: " + id + "   : false");
#endif
                return(false);
            }
        }
#if UNITY_EDITOR
//		Debug.Log("ai Id: " + id + "   : true");
#endif
        return(true);
    }
 // 플레이타임 PLAYTIME
 bool checkPlayerTime(Monster mon, AISlot ai)
 {
     return(GameManager.me.stageManager.playTime >= playTimeMinMaxSinceStart[0] && GameManager.me.stageManager.playTime <= playTimeMinMaxSinceStart[1]);
 }
 //상대스킬발동 DID_SKILL
 bool checkPlayerDidSkillToMe(Monster mon, AISlot ai)
 {
     // To do
     return(false);
 }
 //끝지점과의거리 DIST_ENDLINE
 bool checkDistFromEndLine(Monster mon, AISlot ai)
 {
     tempF = MathUtil.abs(mon.cTransformPosition.x, StageManager.mapEndPosX);
     return(tempF >= distEndLineMinMax[0] && tempF <= distEndLineMinMax[1]);
 }
 //상대히어로와의거리 DIST_HERO
 bool checkDistFromHero(Monster mon, AISlot ai)
 {
     tempF = mon.cTransformPosition.x - GameManager.me.player.cTransformPosition.x;
     return(tempF >= distFromHeroMinMax[0] && tempF <= distFromHeroMinMax[1]);
 }
 bool checkSP(Monster mon, AISlot ai)
 {
     _per = (int)(((float)mon.sp / mon.maxSp) * 100.0f);
     return(_per >= spMinMax[0] && _per <= spMinMax[1]);
 }
 bool checkEHP(Monster mon, AISlot ai)
 {
     _per = (int)(((float)GameManager.me.player.hp / GameManager.me.player.maxHp) * 100.0f);
     return(_per >= playerHpMinMax[0] && _per <= playerHpMinMax[1]);
 }
 bool checkHP(Monster mon, AISlot ai)
 {
     _per = (int)(((float)mon.hp / mon.maxHp) * 100.0f);
     return(_per >= hpMinMax[0] && _per <= hpMinMax[1]);
 }
 //타겟존과의거리 DIST_TZONE
 bool checkDistFromTargetZone(Monster mon, AISlot ai)
 {
     tempF = MathUtil.abs(mon.cTransformPosition.x, GameManager.me.characterManager.targetZonePlayerLine);
     return(tempF >= distTZoneMinMax[0] && tempF <= distTZoneMinMax[1]);
 }
 //최대 넘어가본 타겟존.
 bool checkDistRecordedTargetZone(Monster mon, AISlot ai)
 {
     return(GameManager.me.characterManager.longestWalkedTargetZonePlayerLine >= maxTzoneMinMax[0] && GameManager.me.characterManager.longestWalkedTargetZonePlayerLine <= maxTzoneMinMax[1]);
 }
 bool checkMP(Monster mon, AISlot ai)
 {
     _per = (int)(((float)mon.mp / mon.maxMp) * 100.0f);
     return(_per >= mpMinMax[0] && _per <= mpMinMax[1]);
 }
 //스타트지점과의거리 DIST_START
 bool checkDistFromStartPoint(Monster mon, AISlot ai)
 {
     tempF = mon.cTransformPosition.x - mon.stageMonsterData.posX;
     return(tempF >= distStartMinMax[0] && tempF <= distStartMinMax[1]);
 }
 bool checkTotalUnitHP(Monster mon, AISlot ai)
 {
     return(GameManager.me.characterManager.totalMonsterUnitHp >= totalMinMax[0] && GameManager.me.characterManager.totalMonsterUnitHp <= totalMinMax[1]);
 }
    //기본공격거리내 적존재 TARGET_IN_CZONE
    // 원래는 캐릭터 공격 거리내에 적 존재였는데 지금은 지정된 거리 안에 적이 있는지만 본다.


    bool checkEnemyInDefaultActionZone(Monster mon, AISlot ai)
    {
        int len = GameManager.me.characterManager.playerMonster.Count;

        if (len <= 0)
        {
            return(false);
        }

        if (VectorUtil.DistanceXZ(mon.cTransformPosition, GameManager.me.characterManager.playerMonster[0].cTransformPosition) < targetInDefaultTargetZone)
        {
            mon.targetPosition = GameManager.me.characterManager.playerMonster[0].cTransformPosition;
            mon.targetHeight   = GameManager.me.characterManager.playerMonster[0].hitObject.height;
            mon.targetUniqueId = GameManager.me.characterManager.playerMonster[0].stat.uniqueId;
            return(true);
        }

        /*
         * if(GameManager.me.player.isEnabled)
         * {
         *      if(len >= targetInDefaultTargetZone)
         *      {
         *              _tempMon = GameManager.me.characterManager.playerMonster[targetInDefaultTargetZone-1];
         *      }
         *      else if(len > 0 && len + 1 >= targetInDefaultTargetZone)
         *      {
         *              _tempMon = GameManager.me.characterManager.playerMonster[targetInDefaultTargetZone-1];
         *      }
         *      else if(targetInDefaultTargetZone == 1)
         *      {
         *              return (GameManager.me.player.cTransformPosition.x + GameManager.me.player.damageRange + mon.stat.atkRange >= GameManager.me.characterManager.playerMonsterRightLine); // hitrange
         *      }
         *
         *
         *      bool returnValue = false;
         *
         *      if(_tempMon != null)
         *      {
         *              if(_tempMon.lineRight > GameManager.me.player.lineRight)
         *              {
         *                      returnValue = (_tempMon.cTransformPosition.x + _tempMon.damageRange + mon.stat.atkRange >= GameManager.me.characterManager.playerMonsterRightLine); // hitrange
         *              }
         *              else
         *              {
         *                      returnValue = (GameManager.me.player.cTransformPosition.x + GameManager.me.player.damageRange + mon.stat.atkRange >= GameManager.me.characterManager.playerMonsterRightLine); // hitrange
         *              }
         *
         *              _tempMon = null;
         *      }
         *
         *      return returnValue;
         * }
         * else
         * {
         *      if(len >= targetInDefaultTargetZone)
         *      {
         *              return (GameManager.me.characterManager.playerMonster[targetInDefaultTargetZone-1].damageRange + mon.stat.atkRange >= GameManager.me.characterManager.playerMonsterRightLine); // hitrange
         *      }
         * }
         */

        return(false);


        //if(VectorUtil.DistanceXZ(mon.target.cTransformPosition , mon.cTransformPosition) <= mon.hitRange  + mon.target.damageRange)
        //mon.stat.atkRange

        //targetInDefaultTargetZone
        //return (GameManager.me.characterManager.playerMonsterRightLine + targetInDefaultTargetZone >= mon.lineLeft);
        //return (GameManager.me.characterManager.getCloseEnemyTargetByPosX(false).lineLeft > GameManager.me.characterManager.targetZonePlayerLine - mon.stat.atkRange);
    }
 bool checkPlayerAliveUnitNum(Monster mon, AISlot ai)
 {
     return(GameManager.me.characterManager.totalAlivePlayerMonsterUnitNum >= eUnitNumMinMax[0] && GameManager.me.characterManager.totalAlivePlayerMonsterUnitNum <= eUnitNumMinMax[1]);
 }
 //스킬타게팅가능 CAN_TARGETING
 bool checkCanTargetingSkill(Monster mon, AISlot ai)
 {
     return(mon.skillSlots[canTargeting[0]].canTargetingByHeroMonster(canTargeting[1]));
 }
 //* 아군대비상대소환유닛개수 : 상대개수/아군개수*100
 bool checkUnitNumCondition(Monster mon, AISlot ai)
 {
     _per = (int)((float)GameManager.me.characterManager.totalAlivePlayerMonsterUnitNum / (float)GameManager.me.characterManager.totalAliveMonsterUnitNum * 100.0f);
     return(_per >= unitNumConMinMax[0] && _per <= unitNumConMinMax[1]);
 }
 //* 아군대비상대소환유닛HP : 상대유닛HP총합/아군유닛HP총합*100
 bool checkUnitNumTHP(Monster mon, AISlot ai)
 {
     _per = (int)((float)GameManager.me.characterManager.totalPlayerUnitHp / (float)GameManager.me.characterManager.totalMonsterUnitHp * 100.0f);
     return(_per >= unitNumConMinMax[0] && _per <= unitNumConMinMax[1]);
 }
 bool checkMonsterUnitNumInPlayerTargetZone(Monster mon, AISlot ai)
 {
     return(GameManager.me.characterManager.monterUnitInPlayerTargetZone >= zonePlayerUnitNumMinMax[0] && GameManager.me.characterManager.monterUnitInPlayerTargetZone <= zonePlayerUnitNumMinMax[1]);
 }
 // 쿨타임 COOLTIME저
 bool checkCoolTime(Monster mon, AISlot ai)
 {
     return(ai.canUse());
 }
 //아군대비상대소환유닛총HP  ZONE_THP
 bool checkTargetZoneTHP(Monster mon, AISlot ai)
 {
     _per = (int)((float)GameManager.me.characterManager.playerUnitHPInMonsterTargetZone / (float)GameManager.me.characterManager.monterUnitHPInPlayerTargetZone * 100.0f);
     return(_per >= zoneTHPMinMax[0] && _per <= zoneTHPMinMax[1]);
 }
示例#28
0
    public void init(TranscendData transcendData, int[] transcendLevel, bool isPlayerUnitData, string id, bool isPlayerMon = false, TYPE type = Monster.TYPE.UNIT, StageMonsterData sMonData = null, bool isPetMonster = false)
    {
#if UNITY_EDITOR
        cTransform.gameObject.name = ((isPlayerMon)?"pm":"em") + randomNum++;
        tf.gameObject.name         = cTransform.gameObject.name;
#endif
        resetDefaultVals();

        if (particleEffect != null)
        {
            GameManager.me.effectManager.setParticleEffect(particleEffect);
        }

        isPet                = isPetMonster;
        isPlayerSide         = isPlayerMon;
        fowardDirectionValue = (isPlayerSide?1000.0f:-1000.0f);
        isDeleteObject       = false;

        _v            = tf.localScale;
        _v.x          = 1.0f;
        _v.y          = 1.0f;
        _v.z          = 1.0f;
        tf.localScale = _v;

        _q   = tf.rotation;
        _v   = _q.eulerAngles;
        _v.x = 0.0f;

        if (isPlayerSide)
        {
            _v.y = 90.0f;
        }
        else
        {
            _v.y = 270.0f;
        }

        _v.z           = 0.0f;
        _q.eulerAngles = _v;
        tf.rotation    = _q;

        isMonster = true;

        npcData          = null;
        unitData         = null;
        heroMonsterData  = null;
        stageMonsterData = sMonData;

        stat.monsterType = type;

        bool needToSetRareEffect = false;

        if (type == TYPE.UNIT)
        {
            isHero = false;

            unitData = GameManager.info.unitData[id];
            unitData.setDataToCharacter(this, transcendData, transcendLevel);

            if (isPlayerMon)
            {
                // GameManager.me.player.unitHpUp 소환생명력증가
                // GameManager.me.player.unitDefUp

                float tempF = maxHp;
                tempF += tempF * GameManager.me.player.unitHpUp(unitData);                //  stat.unitHpUp;
                maxHp  = tempF;
                hp     = tempF;

                tempF         = stat.defMagic;
                tempF        += tempF * GameManager.me.player.unitDefUp(unitData);         //.stat.unitDefUp;
                stat.defMagic = tempF;

                tempF          = stat.defPhysic;
                tempF         += tempF * GameManager.me.player.unitDefUp(unitData);        //.stat.unitDefUp;
                stat.defPhysic = tempF;

                if (unitData.rare > 0)
                {
                    needToSetRareEffect = true;
                }
            }
            else if (isPlayerUnitData)            // 적인데 주인공 소환수 데이터를 갖고 있으면 걔는 무조건 PVP!
            {
                float tempF = maxHp;
                tempF += tempF * GameManager.me.pvpPlayer.unitHpUp(unitData);                //.stat.unitHpUp;
                maxHp  = tempF;
                hp     = tempF;

                tempF         = stat.defMagic;
                tempF        += tempF * GameManager.me.pvpPlayer.unitDefUp(unitData);         //..stat.unitDefUp;
                stat.defMagic = tempF;

                tempF          = stat.defPhysic;
                tempF         += tempF * GameManager.me.pvpPlayer.unitDefUp(unitData);        //..stat.unitDefUp;
                stat.defPhysic = tempF;

                if (unitData.rare > 0)
                {
                    needToSetRareEffect = true;
                }
            }


                        #if UNITY_EDITOR
            cTransform.gameObject.name += "_" + unitData.rare;
            tf.gameObject.name          = cTransform.gameObject.name;
                        #endif


            setAniData(Monster.ATK_IDS[unitData.attackType.type]);
            setDefaultHitRange(_tempAniData, false);            //(unitData.attackType.type == 1 || unitData.attackType.type == 2));


            if (unitData.skill != null && unitData.skill.Length > 0)
            {
                skillSlots     = new UnitSkillSlot[unitData.skill.Length];
                _skillSlotsNum = skillSlots.Length;

                for (i = 0; i < _skillSlotsNum; ++i)
                {
                    skillSlots[i] = new UnitSkillSlot();
                    skillSlots[i].setData(this, GameManager.info.unitSkillData[unitData.skill[i]]);
                }
            }
            else
            {
                skillSlots = null;
            }
        }
        else if (type == TYPE.HERO)       // 히어로....
        {
            isHero = true;

            heroMonsterData = GameManager.info.heroMonsterData[id];
            heroMonsterData.setDataToCharacter(this);

            setAniData(Monster.ATK_IDS[heroMonsterData.attackType.type]);
            setDefaultHitRange(_tempAniData, false);            //(heroMonsterData.attackType.type == 1 || heroMonsterData.attackType.type == 2));

            setUpdateWhenOffscreen(true);

            int len = 0;

            if (stageMonsterData != null)
            {
                if (stageMonsterData.units != null)
                {
                    _unitSlotsNum = stageMonsterData.units.Length;
                    unitSlots     = new UnitSlot[_unitSlotsNum];

                    len = unitSlots.Length;
                    for (i = 0; i < len; ++i)
                    {
                        unitSlots[i] = new UnitSlot();
                        unitSlots[i].setData(this, GameManager.info.unitData[stageMonsterData.units[i]]);
                    }
                }

                _skillSlotsNum = stageMonsterData.skills.Length;
                skillSlots     = new HeroSkillSlot[_skillSlotsNum];
                len            = _skillSlotsNum;

                for (i = 0; i < len; ++i)
                {
                    skillSlots[i] = new HeroSkillSlot();
                    GameIDData skillInfo = new GameIDData();
                    skillInfo.parse(stageMonsterData.skills[i], GameIDData.Type.Skill);
                    skillSlots[i].setData(this, skillInfo);
                }

                _aiSlotsNum = stageMonsterData.ai.Length;
                aiSlots     = new AISlot[_aiSlotsNum];

                len = _aiSlotsNum;
                for (i = 0; i < len; ++i)
                {
                    aiSlots[i] = new AISlot();

#if UNITY_EDITOR
                    try
                    {
#endif
                    aiSlots[i].setData(this, GameManager.info.heroMonsterAI[stageMonsterData.ai[i]]);
#if UNITY_EDITOR
                }
                catch
                {
                    Debug.LogError("==== ERRORRRRRR : " + stageMonsterData.ai[i]);
                }
#endif
                }
            }
        }
        else if (type == TYPE.NPC)
        {
            isHero = false;

            npcData = GameManager.info.npcData[id];
            GameManager.info.npcData[id].setDataToCharacter(this);
        }
        else if (type == TYPE.EFFECT)
        {
            isHero = false;
        }

        baseInit();

        damageRange = monsterData.damageRange;

        isBlockMonster = monsterData.isBlockMonster;

        initShadowAndEffectSize();

        _showFirst = false;

        _recoveryDelay.Set(0.0f);
        _recoveryDelayMp.Set(0.0f);
        _recoveryDelaySp.Set(0.0f);
        _hpRecoveryDelay.Set(0.0f);
        //_monsterShowTime = 0.0f;

        invincible = false;



        //Log.log("monsterData.category : " + monsterData.category);

        action = GameManager.me.characterManager.getCharacterAction(category);
        action.init(this);

        hasAni = !(category == MonsterCategory.Category.OBJECT && ani.GetClip(DEAD) == null);

        _v               = tf.localPosition;
        _v.y             = 1.0f;
        tf.localPosition = _v;

        _damageMotionDuration = 1000.0f;

        if (monsterData.deleteMotionType == ChracterDeleteMotionType.EFFECT)
        {
            deleteMotionEffect = GameManager.info.effectData[monsterData.deleteMotionValue].clone();
            if (deleteMotionEffect.type == EffectData.ResourceType.CHARACTER)
            {
#if UNITY_EDITOR
                Debug.Log("deleteMotionEffect.effectChracter : " + (deleteMotionEffect.effectChracter == null));
#endif

                if (deleteMotionEffect.effectChracter == null)
                {
                    deleteMotionEffect.effectChracter = GameManager.me.characterManager.getMonster(false, isPlayerMon, deleteMotionEffect.resource, false);
                    if (unitData != null)
                    {
                        CharacterUtil.setRare(unitData.rare, deleteMotionEffect.effectChracter);
                    }
                    else if (isHero)
                    {
                        deleteMotionEffect.effectChracter.removeRareLine();
                    }
                    deleteMotionEffect.effectChracter.init(null, null, monsterData.deleteMotionValue, isPlayerMon, Monster.TYPE.EFFECT);
                    deleteMotionEffect.effectChracter.isEnabled             = false;
                    deleteMotionEffect.effectChracter.cTransform.localScale = cTransform.localScale;
                }
            }
        }
        else
        {
            deleteMotionEffect = null;
        }

        if (ani[Monster.NORMAL] != null)
        {
            state = Monster.NORMAL;
        }

        initHpBar();

        initMiniMap();

        saveCharacterOriginalValue();

//		if(needToSetRareEffect)
//		{
        //GameManager.info.effectData[UnitData.rareEffectId[unitData.rare-1]].getEffect(cTransform.position,null,cTransform); //getParticleEffectByCharacterSize(this,null,cTransform);
        //particleEffect = GameManager.info.effectData[UnitData.rareEffectId[unitData.rare-1]].getParticleEffectByCharacterSize(this,null,cTransform,10000,0,0,0,0.5f);
//		}


        if (GameManager.me.stageManager.isIntro)
        {
            maxHp = 10000000;
            _hp   = 10000000;
        }

        stat.maxHp = MathUtil.RoundToInt(maxHp);

        if (GameManager.info.modelData.ContainsKey(resourceId))
        {
            useRimShader = GameManager.info.modelData[resourceId].useRimShader;
        }
    }
示例#29
0
    sealed public override void doMotion()
    {
                #if UNITY_EDITOR
        if (UnitSkillCamMaker.instance.useUnitSkillCamMaker)
        {
            return;
        }
                #endif

        switch (_state)
        {
        case STATE_PREPARE:

            _nowSelectedAISlot = null;

            // ai 를 돌린다. 액션이 나왔으면 그냥 액션을 하면 된다 애니 동작이 끝나면 ai 재검사를 하면 됨.
            // 그런데 이동 동작이 걸렸다. 그럼 이동중엔 해당 이동조건만 계속 검사한다. 다른 조건은 검사하지 않는다.
            // 그러다가 이동조건이 깨지면 다시 ai 조건을 처음부터 돌려본다.
            checkAI();

            break;

        case STATE_MOVE:

            if (_nowSelectedAISlot.ai.moveType == MonsterHeroAI.MoveType.TARGETZONE)
            {
                _delay += GameManager.globalDeltaTime;

                if (_delay >= 2.0f)
                {
                    if (checkAI())
                    {
                        return;
                    }
                }


                _v     = mon.cTransformPosition;
                _tempX = GameManager.me.characterManager.targetZonePlayerLine + _nowSelectedAISlot.ai.moveDistanceFromTargetZone;

                if (_tempX > _v.x)
                {
                    _tempF = MathUtil.abs(_tempX, _v.x);
                }
                else
                {
                    _tempF = MathUtil.abs(_v.x, _tempX);
                }

#if UNITY_EDITOR
                //Debug.Log(mon.lineRight + "  endLine: " +  StageManager.mapEndPosX);
#endif
                if (_tempF > 3.0f && mon.lineRight < StageManager.mapEndPosX)
                {
                    _v              = mon.cTransformPosition;
                    _v.x           -= 20.0f;
                    mon.tf.rotation = Util.getFixedQuaternionSlerp(mon.tf.rotation, Util.getLookRotationQuaternion(_v - mon.cTransformPosition), CharacterAction.rotationSpeed * GameManager.globalDeltaTime);
                    _v2             = (IVector3)(mon.tf.forward) * mon.stat.speed * GameManager.globalDeltaTime;
                    _v2.y           = 0;

                    if (_tempX > _v.x)
                    {
                        mon.setPosition(mon.cTransformPosition - _v2);

                        _v = mon.cTransformPosition;
                        if (_v.x > _tempX)
                        {
                            _nowSelectedAISlot = null;
                            mon.setPlayAniRightNow(Monster.NORMAL);
                            _state = STATE_PREPARE;
                        }
                        else
                        {
                            mon.setPlayAniRightNow(Monster.WALK);
                        }
                    }
                    else
                    {
                        mon.setPosition(mon.cTransformPosition + _v2);
                        _v = mon.cTransformPosition;
                        if (_v.x < _tempX)
                        {
                            _nowSelectedAISlot = null;
                            mon.setPlayAniRightNow(Monster.NORMAL);
                            _state = STATE_PREPARE;
                        }
                        else
                        {
                            mon.setPlayAniRightNow(Monster.WALK);
                        }
                    }
                }
                else
                {
                    _nowSelectedAISlot = null;
                    mon.setPlayAniRightNow(Monster.NORMAL);
                    _state = STATE_PREPARE;
                }
            }
            else if (_nowSelectedAISlot.ai.moveType == MonsterHeroAI.MoveType.ACTION_POSITION)
            {
                // 최전방에 가거나 x 번째 애를 때릴 수 있는 곳에 가면 정지.
                // 도착했으면 공격을 할 수 있으면 공격을 한다.
                // 공격을 할 수 없다면 ai는 리셋.
                if (checkAI())
                {
                    return;
                }

                mon.heroMonsterData.attackType.chracterMove(mon);
            }
            else if (_nowSelectedAISlot.ai.moveType == MonsterHeroAI.MoveType.SKILL_POSITION)
            {
                // 스킬 사용 가능 위치로 이동.
                // 최전방에 갔거나 스킬 사용 위치까지 이동했다면 멈추고 스킬을 사용한다.
                // 그리고 ai는 리셋.
                mon.skillSlots[_nowSelectedAISlot.ai.skillNum].canSkillMove();
            }
            else
            {
                if (_nowSelectedAISlot.ai.check(mon, _nowSelectedAISlot) == false)
                {
                    _nowSelectedAISlot = null;
                    _state             = STATE_PREPARE;
                    mon.setPlayAniRightNow(Monster.NORMAL);
                }
            }
            break;

        case STATE_ANIMATION:

            _delay -= GameManager.globalDeltaTime;

            if (_delay <= 0)
            {
                _nowSelectedAISlot = null;
                _state             = STATE_PREPARE;
            }

            break;

        case STATE_ACTION:

            bool setAniIgnore  = _nowSelectedAISlot.ai.setAniIgnore;
            bool ignoreIdleAni = _nowSelectedAISlot.ai.ignoreIdleAni;

            switch (_nowSelectedAISlot.ai.actionType)
            {
            case MonsterHeroAI.ActionType.ATTACK:
                setAttackDelay();
                mon.state = Monster.ATK_IDS[mon.heroMonsterData.attackType.type];
                _state    = STATE_WAIT;
                break;

            case MonsterHeroAI.ActionType.SKILL:

                _nowSelectedAISlot.ai.checkCanTargetingSkillAtAction(mon);

                mon.state = Monster.ATK_IDS[mon.skillSlots[_nowSelectedAISlot.ai.actionSkill[0]].skillData.exeData.type];
                _state    = STATE_WAIT;

                if (mon.skillTarget != null)
                {
                    mon.targetPosition = mon.skillTarget.cTransformPosition;
                    mon.targetHeight   = mon.skillTarget.hitObject.height;
                    mon.targetUniqueId = mon.skillTarget.stat.uniqueId;
                }

                break;

            case MonsterHeroAI.ActionType.SKILL2:

                //_nowSelectedAISlot.ai.checkCanTargetingSkillAtAction(mon);
                _delay += GameManager.globalDeltaTime;
                if (_delay < _nowSelectedAISlot.ai.actionSkillDelay)
                {
                    updateTargetingDecal();
                    checkAISkill2Mode();
                }
                else
                {
                    // 데칼 삭제.

                    bool canShoot = false;

                    switch (mon.skillSlots[_nowSelectedAISlot.ai.actionSkill2].skillData.targeting)
                    {
                    case TargetingData.AUTOMATIC_2:
                    case TargetingData.FORWARD_LINEAR_3:
                        canShoot = checkSkillTarget(true);
                        break;

                    default:
                        canShoot = true;
                        break;
                    }

                    if (canShoot)
                    {
                        mon.state = Monster.ATK_IDS[mon.skillSlots[_nowSelectedAISlot.ai.actionSkill2].skillData.exeData.type];
                        _state    = STATE_WAIT;
                    }
                    else
                    {
                        decal.hide();
                        onCompleteAttackAni();
                    }
                }
                break;


            case MonsterHeroAI.ActionType.SUMMON:
                //mon.state = Monster.SHOOT; ////mon.playAni(Monster.SHOOT);
                _state = STATE_PREPARE;
                createSummon(_nowSelectedAISlot.ai);
                break;

            case MonsterHeroAI.ActionType.PLAYANI:

                _state = STATE_ANIMATION;

                //mon.nowAniId = _nowSelectedAISlot.ai.actionAni;
                //mon.setAniData(mon.nowAniId);
                mon.playAni(_nowSelectedAISlot.ai.actionAni);
                mon.renderAni();

                _delay = mon.ani[_nowSelectedAISlot.ai.actionAni].length;

                //playani일때 강제로 애니메이션이 동작하게 하면서 그 다음에 walk를 무시하게 할 것인지를 정한다.
                // 만약 walk를 무시하게만들면 이동시 walk 애니는 동작하지 않는다.
                // 샌드웜이 땅에 숨을때 써먹을거다.
                // 숨은뒤 이동하게 만들면 된다. 그리고 다시 나타나는 애니메이션을 동작시키거나 혹은 다른 공격 동작이 시전될때는
                // 이동 애니를 다시 켜게 만들면 된다.
                // 문제는 이동 위치를 특정 위치로 정하기 애매하는 것이다. 현재 위치를 기준으로 상대위치로 옮기는 기능을 추가해야하나?

                //mon.setPlayAniRightNow("");

                //mon.animation[_nowSelectedAISlot.ai.aniName].length

                break;
            }

            if (setAniIgnore)
            {
                mon.ignoreIdleAni = ignoreIdleAni;
            }

            break;
        }
    }