Ejemplo n.º 1
0
        public override void Update(int deltaTime)
        {
            if (owner.target != null && owner.target.Alive() && owner.target.id == owner.targetId)
            {
                if (owner.fightTimer >= owner.fightInterval)
                {
                    owner.fightTimer = 0;
                    owner.Fight();
                }
                else
                {
                    owner.fightTimer += deltaTime;
                }

                long distance = FixVector3.SqrDistance(owner.target.position, owner.position);
                if (distance > owner.attackRange)
                {
                    owner.target   = null;
                    owner.targetId = 0;

                    owner.ChangeState(IdolGuardState.IDLE, owner.fsmIdle);
                }
            }
            else
            {
                owner.target   = null;
                owner.targetId = 0;

                owner.ChangeState(IdolGuardState.IDLE, owner.fsmIdle);
            }
        }
Ejemplo n.º 2
0
        public bool TargetWithInAttackArea()
        {
            long distance       = FixVector3.SqrDistance(owner.target.position, owner.position);
            long attackDistance = owner.GetAttackArea();

            return(distance < attackDistance);
        }
Ejemplo n.º 3
0
        protected void GetPositionsFromPath(List <FixVector3> path, List <Position> posList)
        {
            if (path.Count > 0)
            {
                int  j        = 0;
                long distance = FixVector3.SqrDistance(path[j], position);

                if (distance <= GameConstants.EQUAL_DISTANCE)
                {
                    DebugUtils.LogWarning(DebugUtils.Type.PathFinding, string.Format("movable unit {0}'s first way point is too close! distance = {1}", id, distance));
                    j = 1;
                }

                for ( ; j < path.Count; j++)
                {
                    Position   pos = new Position();
                    FixVector3 v   = path[j];
                    //DebugUtils.LogWarning( DebugUtils.Type.AI_MovableUnit, string.Format( "movable unit {0}'s {1} way point is ({2}, {3}, {4})", id, j, v.x, v.y, v.z ) );
                    pos.x = v.vector3.x;
                    pos.y = v.vector3.y;
                    pos.z = v.vector3.z;
                    posList.Add(pos);
                }
            }
        }
Ejemplo n.º 4
0
        private void Moving(int deltaTime)
        {
            PathAgent agent = owner.pathAgent;

            agent.Move(deltaSpeed);

            long distance = FixVector3.SqrDistance(targetPosition, owner.position);

            if (distance <= FixVector3.one.magnitude)
            {
                state = State.DashEnd;
                waitingChangeState = false;

                LogicUnit target = owner.target;

                if (target != null && target.Alive() && target.id == owner.target.id)
                {
                    AttributeEffect ae = GenerateAttributeEffect(attributeEffects[0]);
                    ae.Attach(owner, target);
                }

                DebugUtils.Log(DebugUtils.Type.AI_Skill, string.Format("YueGuangChongCi: arrive target position, change state to {0}", state));
            }
            else
            {
                DebugUtils.Log(DebugUtils.Type.AI_Skill, string.Format("YueGuangChongCi: distance = {0}, step = {1}", distance, stepLength));
            }
        }
Ejemplo n.º 5
0
        public override void Update(int deltaTime)
        {
            base.Update(deltaTime);

            if (owner.target != null && owner.target.Alive())
            {
                long distance = FixVector3.SqrDistance(owner.brithPosition, owner.position);

                if (distance < owner.maxChaseDistance)
                {
                    owner.WaypointHandler();
                    owner.pathAgent.Move(owner.speed * deltaTime);

                    // After move, Check the crystal's position is in the attack area.
                    FixVector3 v = owner.target.position;
                    distance = FixVector3.SqrDistance(v, owner.position);
                    long attackDistance = owner.GetAttackAera();

                    if (distance < attackDistance)
                    {
                        owner.Attack(owner.target);
                    }
                }
                else
                {
                    owner.Walk(owner.brithPosition);
                }
            }
            else
            {
                owner.Walk(owner.brithPosition);
            }
        }
Ejemplo n.º 6
0
        private void FindOpponent()
        {
            LogicUnit t = FindOpponentSoldier(mark, position, realAttakDistance);

            if (t == null)
            {
                t = FindOpponentCrystalCar(mark, position, realAttakDistance);
            }

            if (t == null)
            {
                t = FindOpponentDemolisher(mark, position, realAttakDistance);
            }

            if (t != null)
            {
                long distance       = FixVector3.SqrDistance(t.position, position);
                long attackDistance = realAttakDistance + t.modelRadius;

                DebugUtils.LogWarning(DebugUtils.Type.AI_Tower, string.Format("tower {0} finds the target {1} of type {2}, distance = {3}, attackDistance = {4}.", id, t.id, t.type, distance, attackDistance));

                if (distance < attackDistance)
                {
                    Attack(t);
                }
            }
        }
Ejemplo n.º 7
0
        public override void LogicUpdate(int deltaTime)
        {
            if (state == ProjectileState.Flying)
            {
                if (target != null && target.Alive())
                {
                    targetPosition = target.position;
                }
                else
                {
                    // If target has been death
                    // Projectile will fly to the target's body position
                    if (!changeDataWhenTargetDeath)
                    {
                        DebugUtils.Log(DebugUtils.Type.AI_Projectile, "the projectile " + id + "'s target already death, now set Maxdistance = " + (targetDistance + flyingDistance));

                        SetMaxDistance(targetDistance + flyingDistance);

                        changeDataWhenTargetDeath = !changeDataWhenTargetDeath;
                    }
                }

                // modify coordinates for each frame
                position          += speed * deltaTime * GameConstants.LOGIC_FIXPOINT_PRECISION_FACTOR * GameConstants.LOGIC_FIXPOINT_PRECISION_FACTOR;
                transform.position = position.vector3;

                // recode total mileage of flight
                flyingDistance = FixVector3.SqrDistance(position, startPosition);

                RenderMessage rm = new RenderMessage();
                rm.type    = RenderMessage.Type.SyncPosition;
                rm.ownerId = id;
                rm.arguments.Add("type", (int)type);
                rm.position  = (position + heightOffset).vector3;
                rm.direction = speed.vector3;
                PostRenderMessage(rm);

                //To be decide projectile should it be over
                targetDistance = FixVector3.SqrDistance(targetPosition, position);
                FlyingOperation(deltaTime);
            }
            else if (state == ProjectileState.Hit)
            {
                DebugUtils.Log(DebugUtils.Type.AI_Projectile, "the projectile " + id + " hit the target " + target.id + " targetDistance " + targetDistance);
                Hit();
            }
        }
Ejemplo n.º 8
0
        protected void OnFoundLocalWalkPath(List <FixVector3> wp)
        {
            DebugUtils.Assert(wp.Count > 0, "MovableUnit : the new waypoints' length should be larger than 0 for a new walk!");
            DebugUtils.Log(DebugUtils.Type.AI_MovableUnit, string.Format("{0} {1} find Walk path complete, waypoint count = {2}, direction = {3}", type, id, waypoints.Count, direction));

            List <Position> positions = new List <Position>();

            if (wp.Count > 0)
            {
                int  j        = 0;
                long distance = FixVector3.SqrDistance(wp[j], position);

                if (distance <= GameConstants.EQUAL_DISTANCE)
                {
                    DebugUtils.LogWarning(DebugUtils.Type.PathFinding, string.Format("movable unit {0}'s first way point is too close! distance = {1}", id, distance));
                    j = 1;
                }

                for ( ; j < wp.Count; j++)
                {
                    Position   pos = new Position();
                    FixVector3 v   = wp[j];
                    //DebugUtils.LogWarning( DebugUtils.Type.AI_MovableUnit, string.Format( "movable unit {0}'s {1} way point is ({2}, {3}, {4})", id, j, v.x, v.y, v.z ) );
                    pos.x = v.vector3.x;
                    pos.y = v.vector3.y;
                    pos.z = v.vector3.z;
                    positions.Add(pos);
                }
            }

            LocalPathHandler(positions);

            ChangeState(NpcState.WALK, fsmWalk);

            RenderMessage rm = new RenderMessage();

            rm.ownerId   = id;
            rm.direction = direction.vector3;
            rm.type      = RenderMessage.Type.NpcWalk;
            PostRenderMessage(rm);
        }
Ejemplo n.º 9
0
        private void GuardPosture(int deltaTime)
        {
            if (state == BuildingState.IDLE)
            {
                FindOpponent();
            }
            else if (state == BuildingState.ATTACK)
            {
                // is searching need to ignore the cloaking
                if (target.Alive() && target.id == targetId)
                {
                    long distance = FixVector3.SqrDistance(target.position, position);

                    if (distance > realAttakDistance)
                    {
                        state = BuildingState.IDLE;
                    }
                    else
                    {
                        fightTimer += deltaTime;
                        if (fightTimer > attackInterval)
                        {
                            fightTimer = 0;
                            Fire();
                        }
                    }
                }
                else
                {
                    Idle();
                }
            }
            else
            {
                DebugUtils.LogError(DebugUtils.Type.AI_Tower, "the tower " + id + " is in strange state " + state);
            }

            //HealthAutoRecovery( deltaTime ); Designer don't want deploy type building have auto recovery.Locked this.
        }
Ejemplo n.º 10
0
        public void FindOpponent()
        {
            Crystal crystal = FindOpponentCrystal(position, chaseArea);

            if (crystal != null)
            {
                long distance = FixVector3.SqrDistance(crystal.position, position);

                if (distance < GameConstants.EQUAL_DISTANCE)
                {
                    Idle();
                }
                else
                {
                    Chase(crystal);
                }
            }
            else
            {
                Walk(bornPosition);
            }
        }
Ejemplo n.º 11
0
        public void FindOpponent()
        {
            LogicUnit building = FindOpponentBuilding(mark, position, chaseArea);

            if (building != null)
            {
                long distance = FixVector3.SqrDistance(building.position, position);

                if (distance < GameConstants.EQUAL_DISTANCE)
                {
                    Idle();
                }
                else
                {
                    Chase(building);
                }
            }
            else
            {
                Walk(bornPosition);
            }
        }
Ejemplo n.º 12
0
        // Update is called once per frame
        public override void Update(int deltaTime)
        {
            base.Update(deltaTime);

            if (owner.target != null && owner.target.Alive())
            {
                owner.WaypointHandler();
                owner.pathAgent.Move(owner.speed * deltaTime);

                // After move, Check the crystal's position is in the attack area.
                long distance       = FixVector3.SqrDistance(owner.target.position, owner.position);
                long attackDistance = (long)owner.attackArea + (long)owner.target.modelRadius + (long)owner.modelRadius;

                if (distance < attackDistance)
                {
                    owner.Mining(owner.target);
                }
            }
            else
            {
                owner.ChangeState(CrystalCarState.IDLE, owner.fsmIdle);
            }
        }
Ejemplo n.º 13
0
        public override void Update(int deltaTime)
        {
            base.Update(deltaTime);

            LogicUnit target = owner.target;

            if (target != null && target.Alive())
            {
                long distance = FixVector3.SqrDistance(target.position, owner.position);
                if (distance < owner.attackRadius)
                {
                    if (inFightInterval)
                    {
                        fightIntervalTimer += deltaTime;

                        if (fightIntervalTimer >= fightInterval)
                        {
                            fightState         = FightState.StartSwingPoint;
                            fightIntervalTimer = 0;
                            inFightInterval    = false;
                        }
                    }
                    else
                    {
                        fightState          = GetCurrentState(fightDurationTimer);
                        fightDurationTimer += deltaTime;

                        if (fightState == FightState.StartSwingPoint)
                        {
                            owner.direction = target.position - owner.position;

                            RenderMessage rm = new RenderMessage();
                            rm.ownerId   = owner.id;
                            rm.direction = owner.direction.vector3;
                            rm.type      = RenderMessage.Type.SummonedUnitAttack;
                            owner.PostRenderMessage(rm);
                        }
                        else if (fightState == FightState.HitPoint)
                        {
                            owner.damage = Formula.GetAttackFloatingValue(owner.physicalAttack, owner.GetRandomNumber(), owner.GetRandomNumber(owner.physicalAttackVar));

                            List <LogicUnit> targets = owner.FindOpponent();

                            for (int i = 0; i < targets.Count; i++)
                            {
                                LogicUnit t = targets[i];

                                // Check target state and still in the attack range
                                if (t != null && t.Alive())
                                {
                                    t.Hurt(owner.damage, AttackPropertyType.PhysicalAttack, false, owner.ownerSoldier);
                                }
                            }
                        }
                        else if (fightState == FightState.FightEnd)
                        {
                            inFightInterval    = true;
                            fightDurationTimer = 0;
                        }
                    }
                }
                else
                {
                    owner.Idle();
                }
            }
            else
            {
                owner.Idle();
            }
        }
Ejemplo n.º 14
0
        protected override bool IsHit()
        {
            int distance = FixVector3.SqrDistance(position, destination);

            return(distance <= GameConstants.HIT_DISTANCE);
        }
Ejemplo n.º 15
0
        private void SprintState(int deltaTime)
        {
            LogicUnit  target   = owner.target;
            FixVector3 position = owner.position;
            PathAgent  agent    = owner.pathAgent;

            if (target != null && target.Alive() && target.id == owner.target.id)
            {
                if (FixVector3.SqrDistance(target.position, owner.targetPosition) > GameConstants.BEGINCHASE_DISTANCE)     // 5f is a testing distance
                {
                    // if target leave the position too far, need to refresh chase path
                    owner.targetPosition = target.position;
                    owner.FindChasePath(owner.target.position);
                    return;
                }

                if (TargetWithInAttackArea())
                {
                    if (target != null && target.Alive() && target.id == owner.target.id)
                    {
                        if (playerOwner)
                        {
                            FixVector3 direction   = (target.position - position).normalized;
                            FixVector3 destination = owner.position + direction * 5f;// Temp distance.

                            FixVector3 hitPosition      = FixVector3.zero;
                            FixVector3 simpleOnMapPoint = FixVector3.zero;

                            // mapping destination on navmesh
                            bool sampleResult = agent.SamplePosition(destination, out simpleOnMapPoint);
                            if (sampleResult)
                            {
                                destination = simpleOnMapPoint;
                            }

                            bool result = agent.Raycast(destination, out hitPosition);
                            if (result)
                            {
                                destination = hitPosition;
                            }

                            DataManager clientData = DataManager.GetInstance();

                            UpdateC2S message = new UpdateC2S();
                            message.timestamp = clientData.GetFrame();
                            Operation op = new Operation();
                            op.playerId       = clientData.GetPlayerId();
                            op.unitId         = id;
                            op.targetId       = owner.id;                              // test
                            op.unitMetaId     = metaId;                                // test
                            op.opType         = OperationType.SyncSkillTargetPosition; // wrong type
                            op.x              = destination.vector3.x;
                            op.y              = destination.vector3.y;
                            op.z              = destination.vector3.z;
                            message.operation = op;
                            PostBattleMessage(MsgCode.UpdateMessage, message);

                            DebugUtils.Log(DebugUtils.Type.AI_Skill, string.Format("YueGuangChongCi sync destination : {0}", destination));
                        }
                    }
                    else
                    {
                        Stop();
                    }
                }
                else
                {
                    if (!owner.CurrentPathAlreadyFinished())
                    {
                        owner.WaypointHandler();
                        FixVector3 d = owner.speed * deltaTime;
                        agent.Move(d);
                    }
                    else
                    {
                        // wait for chase path
                    }
                }
            }
            else
            {
                // Skill will be shut down when target death.
                Stop();
                owner.Idle();
            }
        }
Ejemplo n.º 16
0
        public bool WithInSummonAttackRadius(FixVector3 targetPosition, int targetModelRadius)
        {
            long attackRange = (long)attackRadius + (long)modelRadius + (long)targetModelRadius;

            return(FixVector3.SqrDistance(targetPosition, position) <= attackRange);
        }
Ejemplo n.º 17
0
        public override void Update(int deltaTime)
        {
            LogicUnit  target   = owner.target;
            FixVector3 position = owner.position;

            if (target != null && target.Alive() && owner.target.id == owner.targetId)
            {
                if (inFightInterval)
                {
                    // Timing interval
                    fightIntervalTimer += deltaTime;

                    if (fightIntervalTimer >= fightInterval)
                    {
                        // Enter fight
                        fightState         = FightState.StartSwingPoint;
                        fightIntervalTimer = 0;
                        fightInterval      = 0;
                        inFightInterval    = false;
                    }
                }
                else
                {
                    fightState          = GetCurrentState(fightDurationTimer);
                    fightDurationTimer += deltaTime;

                    if (fightState == FightState.StartSwingPoint)
                    {
                        DebugUtils.Assert(owner.target.id == owner.targetId, string.Format("Fight Status : the soldier {0}'s targetId = {1}, but its target's id = {2}!", owner.id, owner.targetId, owner.target.id));

                        if (owner.stateListener.PostFightEvent())
                        {
                            // Trigger skill, will interrupt fight.
                            return;
                        }
                        else
                        {
                            // Save the crit attack performance code
                            isCrit = Formula.TriggerCritical(owner.GetRandomNumber(), owner.GetCriticalChance());
                            //if ( isCrit )
                            //{
                            //    hitTime = owner.critHitTime;
                            //    fightDuration = owner.critDuration;
                            //}
                            //else
                            {
                                hitTime       = owner.attackHitTime;
                                fightDuration = owner.attackDuration;
                            }

                            // Reset direction at attack begin.
                            FixVector3 direction = target.position - position;
                            owner.direction = direction;
                            if (owner.standardAttackType == AttackDistanceType.Melee)
                            {
                                RenderMessage rm = new RenderMessage();
                                rm.ownerId   = owner.id;
                                rm.direction = direction.vector3;
                                rm.type      = RenderMessage.Type.SoldierAttack;
                                rm.arguments.Add("isCrit", false);
                                rm.arguments.Add("intervalRate", 1);
                                owner.PostRenderMessage(rm);
                            }
                            else
                            {
                                RenderMessage rm = new RenderMessage();
                                rm.type      = RenderMessage.Type.SoldierSpawnProjectile;
                                rm.ownerId   = owner.id;
                                rm.direction = direction.vector3;
                                rm.arguments.Add("projectileMetaId", owner.projectileId);
                                rm.arguments.Add("intervalRate", 1);
                                owner.PostRenderMessage(rm);
                            }
                        }
                    }
                    else if (fightState == FightState.HitPoint)
                    {
                        owner.Fight(isCrit);
                        owner.stateListener.PostUnitFightAfter();
                    }
                    else if (fightState == FightState.BackSwing)
                    {
                        if (fightDurationTimer >= fightDuration)
                        {
                            fightDurationTimer = 0;

                            fightInterval   = owner.GetAttackInterval() - fightDuration;
                            inFightInterval = true;
                        }
                    }
                }

                long distance       = FixVector3.SqrDistance(target.position, owner.position);
                long attackDistance = owner.GetAttackArea();

                if (distance >= attackDistance)
                {
                    if ((target.position - owner.targetPosition).magnitude > attackDistance)
                    {
                        owner.Chase(target);
                    }
                    else
                    {
                        // continue fight
                    }
                }
            }
            else
            {
                owner.Idle();
            }
        }
Ejemplo n.º 18
0
        public override void Update(int deltaTime)
        {
            base.Update(deltaTime);

            if (owner.target != null && owner.target.Alive())
            {
                DebugUtils.Log(DebugUtils.Type.AI_Npc, string.Format("{0} {1} begin to attack target {2}", owner.npcType, owner.id, owner.target.id));
                if (inFightInterval)
                {
                    fightIntervalTimer += deltaTime;

                    if (owner.fightTimer >= owner.fightInterval)
                    {
                        state = FightState.StartSwingPoint;
                        fightIntervalTimer = 0;
                        fightInterval      = 0;
                        inFightInterval    = false;
                    }
                }
                else
                {
                    state = GetCurrentState(fightDurationTimer);
                    fightDurationTimer += deltaTime;

                    if (state == FightState.StartSwingPoint)
                    {
                        FixVector3 direction = owner.target.position - owner.position;
                        owner.direction = direction.normalized;

                        RenderMessage rm = new RenderMessage();
                        rm.ownerId   = owner.id;
                        rm.direction = owner.direction.vector3;
                        rm.type      = RenderMessage.Type.NpcFight;
                        rm.arguments.Add("intervalRate", 1);
                        owner.PostRenderMessage(rm);
                    }
                    else if (state == FightState.HitPoint)
                    {
                        owner.target.Hurt(owner.damage, AttackPropertyType.PhysicalAttack, false, owner);

                        RenderMessage rm = new RenderMessage();
                        rm.ownerId = owner.id;
                        rm.type    = RenderMessage.Type.NpcFightHit;
                        owner.PostRenderMessage(rm);
                    }
                    else if (state == FightState.BackSwing)
                    {
                        if (fightDurationTimer >= fightDuration)
                        {
                            fightDurationTimer = 0;

                            fightInterval   = owner.fightInterval - fightDuration;
                            inFightInterval = true;
                        }
                    }
                }
            }
            else
            {
                if (FixVector3.SqrDistance(owner.position, owner.brithPosition) > GameConstants.EQUAL_DISTANCE)
                {
                    owner.Walk(owner.brithPosition);
                }
                else
                {
                    owner.ChangeState(NpcState.IDLE, owner.fsmIdle);
                }
            }

            long distance       = FixVector3.SqrDistance(owner.target.position, owner.position);
            long attackDistance = owner.GetAttackAera();

            DebugUtils.LogWarning(DebugUtils.Type.AI_Npc, string.Format("distance = {0}, attackDis = {1}", distance, attackDistance));
            if (distance < (attackDistance))
            {
                // continue fight..
            }
            else
            {
                DebugUtils.Log(DebugUtils.Type.AI_Npc, string.Format("{0} {1}'s target out of range, begin to chase  {2}", owner.npcType, owner.id, owner.target.id));
                owner.Chase(owner.target);
            }
        }
Ejemplo n.º 19
0
        private void BattryFight(int deltaTime)
        {
            if (inFightInterval)
            {
                // Timing interval
                fightIntervalTimer += deltaTime;

                if (fightIntervalTimer >= fightInterval)
                {
                    // Enter fight
                    fightState         = FightState.StartSwingPoint;
                    fightIntervalTimer = 0;
                    fightInterval      = 0;
                    inFightInterval    = false;
                }
            }
            else
            {
                fightState          = GetCurrentState(fightDurationTimer);
                fightDurationTimer += deltaTime;

                if (fightState == FightState.StartSwingPoint)
                {
                    DebugUtils.Assert(target.id == targetId, string.Format("Fight Status : the soldier {0}'s targetId = {1}, but its target's id = {2}!", owner.id, targetId, target.id));

                    if (owner.stateListener.PostFightEvent())
                    {
                        // Trigger skill, will interrupt fight.
                        return;
                    }
                    else
                    {
                        hitTime       = owner.attackHitTime;
                        fightDuration = owner.attackDuration;

                        // Reset direction at attack begin.
                        FixVector3 direction = target.position - owner.position;
                        owner.direction = direction;

                        RenderMessage rm = new RenderMessage();
                        rm.type      = RenderMessage.Type.SoldierBatteryFire;
                        rm.ownerId   = owner.id;
                        rm.direction = direction.vector3;
                        rm.arguments.Add("projectileMetaId", owner.projectileId);
                        rm.arguments.Add("intervalRate", 1);
                        owner.PostRenderMessage(rm);
                    }
                }
                else if (fightState == FightState.HitPoint)
                {
                    bool isCrit = Formula.TriggerCritical(owner.GetRandomNumber(), owner.GetCriticalChance());
                    owner.Fight(isCrit);
                    owner.stateListener.PostUnitFightAfter();
                }
                else if (fightState == FightState.BackSwing)
                {
                    if (fightDurationTimer >= fightDuration)
                    {
                        fightDurationTimer = 0;

                        fightInterval   = owner.GetAttackInterval() - fightDuration;
                        inFightInterval = true;
                    }
                }
            }

            long distance       = FixVector3.SqrDistance(target.position, owner.position);
            long attackDistance = owner.GetAttackArea();

            if (distance >= attackDistance)
            {
                if ((target.position - owner.targetPosition).magnitude > attackDistance)
                {
                    target = null;
                }
                else
                {
                    // continue fight
                }
            }
        }
Ejemplo n.º 20
0
        public override void Update(int deltaTime)
        {
            int state = owner.state;

            DebugUtils.Assert(state == SoldierState.CHASING, string.Format("Soldier {0} is in state {1} when updating in FsmChase!", owner.id, state));

            LogicUnit  target   = owner.target;
            FixVector3 position = owner.position;
            PathAgent  agent    = owner.pathAgent;

            if (target != null && target.Alive() && target.id == owner.targetId)
            {
                long mag = FixVector3.SqrDistance(target.position, owner.targetPosition);
                //Debug.LogWarning( string.Format( "current position:{0} record position:{1} length:{2}", target.position, owner.targetPosition, mag ) );

                if (mag > GameConstants.BEGINCHASE_DISTANCE)   // 5f is a testing distance
                {
                    //Debug.Log( string.Format( "current position:{0} record position:{1} length:{2}", target.position, owner.targetPosition, mag ) );
                    owner.Chase(owner.target);
                    return;
                }

                owner.WaypointHandler();

                FixVector3 d           = owner.speed * deltaTime;
                FixVector3 newPosition = position + d * FixVector3.PrecisionFactor * FixVector3.PrecisionFactor * FixVector3.PrecisionFactor;
                FixVector3 avoidance   = owner.CalculateAvoidance(owner, newPosition);

                if (avoidance != FixVector3.zero && subState != CHASE2AVOIDANCE)
                {
                    DebugUtils.LogWarning(DebugUtils.Type.AI_Soldier, string.Format("soldier {0} enters CHASE2AVOIDANCE.", owner.id));
                    subState = CHASE2AVOIDANCE;
                    DebugUtils.Log(DebugUtils.Type.Avoidance, string.Format("CHASE : soldier {0} has received an avoidance ({1}, {2}, {3}), he's speed is ({4}, {5}, {6})!", owner.id, avoidance.x, avoidance.y, avoidance.z, owner.speed.x, owner.speed.y, owner.speed.z));
                    avoidSpeed = d + avoidance * deltaTime;
                    FixVector3 pos  = position + avoidSpeed * FixVector3.PrecisionFactor * FixVector3.PrecisionFactor;
                    bool       pass = agent.DirectPassToPosition(pos, NavMesh.AllAreas);
                    if (pass)
                    {
                        agent.Move(avoidSpeed);
                        DebugUtils.Log(DebugUtils.Type.Avoidance, string.Format("CHASE : soldier {0} has received an avoidance and moved to ({1}, {2}, {3})!", owner.id, owner.position.x, owner.position.y, owner.position.z));
                    }
                    else
                    {
                        //still here.
                        DebugUtils.Log(DebugUtils.Type.Avoidance, string.Format("CHASE : soldier {0} has stopped when avoiding others!", owner.id));
                    }
                }
                else
                {
                    if (subState == CHASE2AVOIDANCE)
                    {
                        if (avoidance != FixVector3.zero)
                        {
                            avoidSpeed = d + avoidance * deltaTime;
                            //Vector3 pos = position + avoidSpeed * FixVector3.PrecisionFactor * FixVector3.PrecisionFactor;
                            //bool pass = agent.DirectPassToPosition( pos, NavMesh.AllAreas );
                            if (true)  //pass )
                            {
                                agent.ToughMove(avoidSpeed);
                                DebugUtils.Log(DebugUtils.Type.Avoidance, string.Format("CHASE : soldier {0} has received an avoidance and moved to ({1}, {2}, {3})!", owner.id, owner.position.x, owner.position.y, owner.position.z));
                            }
                            else
                            {
                                //still here.
                                DebugUtils.Log(DebugUtils.Type.Avoidance, string.Format("CHASE : soldier {0} has stopped when avoiding others!", owner.id));
                            }
                        }
                        else
                        {
                            DebugUtils.LogWarning(DebugUtils.Type.AI_Soldier, string.Format("soldier {0} enters AVOIDANCE2CHASE.", owner.id));
                            subState = AVOIDANCE2CHASE;

                            agent.Move(d);
                        }
                    }
                    else
                    {
                        agent.Move(d);
                    }
                }

                position = owner.position;
                FixVector3 v              = target.position;
                long       distance       = FixVector3.SqrDistance(target.position, position);
                long       attackDistance = owner.GetAttackArea();

                if (distance < attackDistance)
                {
                    owner.Attack(owner.target);
                }

                /*
                 * else if( distance > chaseArea * chaseArea * 1.5f )
                 * {
                 *  DebugUtils.LogWarning( DebugUtils.Type.AI_Soldier, string.Format( "soldier {0}'s target {1} has escaped! distance = {2}, chaseArea * chaseArea * 1.5f = {3}", id, target.id, distance, chaseArea * chaseArea * 1.5f ) );
                 *  //Idle();
                 *  Walk( destination );
                 * }
                 */

                if (owner.stateListener.PostMoveDistanceChanged(d.magnitude))
                {
                    return;
                }

                owner.stateListener.PostChasingStateChanged(distance);
            }
            else
            {
                owner.Idle();
                //Walk( destination );
            }
        }