示例#1
0
        private void GoHomeHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (npc.IsDead())
            {
                return;
            }
            ChangeToState(npc, (int)AiStateId.Idle);
            NpcAiStateInfo info = npc.GetAiStateInfo();

            info.Time += deltaTime;
            if (info.Time > m_IntervalTime)
            {
                info.Time = 0;
                AiData_Demo_Melee data = GetAiData(npc);
                if (null != data)
                {
                    Vector3 targetPos            = info.HomePos;
                    ScriptRuntime.Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D();
                    float powDistToHome          = Geometry.DistanceSquare(srcPos, info.HomePos);
                    if (powDistToHome <= 1)
                    {
                        npc.GetMovementStateInfo().IsMoving = false;
                        info.Time = 0;
                        ChangeToState(npc, (int)AiStateId.Idle);
                    }
                    else
                    {
                        AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, 100, true, this);
                    }
                }
            }
        }
示例#2
0
        private void IdleHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (npc.IsDead())
            {
                return;
            }
            NpcAiStateInfo info = npc.GetAiStateInfo();

            info.Time += deltaTime;
            if (info.Time > 100)
            {
                info.Time = 0;
                CharacterInfo target = AiLogicUtility.GetNearstTargetHelper(npc, CharacterRelation.RELATION_ENEMY);
                if (null != target)
                {
                    npc.GetMovementStateInfo().IsMoving = false;
                    info.Time   = 0;
                    info.Target = target.GetId();
                    ChangeToState(npc, (int)AiStateId.Combat);
                    NotifyNpcTargetChange(npc);
                }
                else
                {
                }
            }
        }
示例#3
0
        private void PursuitHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (npc.IsDead())
            {
                return;
            }
            NpcAiStateInfo        info   = npc.GetAiStateInfo();
            bool                  goHome = false;
            AiData_PveNpc_General data   = GetAiData(npc);

            if (null != data)
            {
                CharacterInfo target = AiLogicUtility.GetLivingCharacterInfoHelper(npc, info.Target);
                if (null != target)
                {
                    float   dist                 = (float)npc.GetActualProperty().AttackRange;
                    float   distGoHome           = (float)npc.GohomeRange;
                    Vector3 targetPos            = target.GetMovementStateInfo().GetPosition3D();
                    ScriptRuntime.Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D();
                    float powDist                = Geometry.DistanceSquare(srcPos, targetPos);
                    float powDistToHome          = Geometry.DistanceSquare(srcPos, info.HomePos);
                    if (powDist < dist * dist)
                    {
                        npc.GetMovementStateInfo().IsMoving = false;
                        info.Time = 0;
                        data.Time = 0;
                        ChangeToState(npc, (int)AiStateId.Combat);
                        NotifyNpcMove(npc);
                    }
                    else if (true) // 目标存活的情况下屏蔽掉gohome。
                    {
                        info.Time += deltaTime;
                        if (info.Time > m_IntervalTime)
                        {
                            info.Time = 0;
                            AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                        }
                    }
                    else
                    {
                        goHome = true;
                    }
                }
                else
                {
                    goHome = true;
                }
                if (goHome)
                {
                    npc.GetMovementStateInfo().IsMoving = false;
                    NotifyNpcMove(npc);
                    info.Time = 0;
                    data.Time = 0;
                    ChangeToState(npc, (int)AiStateId.GoHome);
                }
            }
        }
示例#4
0
        public override bool Execute(long deltaTime)
        {
            CharacterInfo target = AiLogicUtility.GetSeeingLivingCharacterInfoHelper(Npc, m_TargetId);

            if (null != target)
            {
                Logic.ServerNpcSkill(Npc, m_SkillId, target, m_TargetPos, m_TargetAngle);
            }
            return(true);
        }
示例#5
0
        private void IdleHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (npc.IsDead())
            {
                return;
            }
            NpcAiStateInfo info = npc.GetAiStateInfo();

            info.Time += deltaTime;
            if (info.Time > 100)
            {
                info.Time = 0;
                if (GetAiData(npc).HasPatrolData)
                {
                    npc.GetMovementStateInfo().IsMoving = false;
                    ChangeToState(npc, (int)AiStateId.PatrolCommand);
                }
                else
                {
                    CharacterInfo target = null;
                    if (info.IsExternalTarget)
                    {
                        target = AiLogicUtility.GetSeeingLivingCharacterInfoHelper(npc, info.Target);
                        if (null == target)
                        {
                            target = AiLogicUtility.GetNearstTargetHelper(npc, CharacterRelation.RELATION_ENEMY);
                            if (null != target)
                            {
                                info.Target = target.GetId();
                            }
                        }
                    }
                    else
                    {
                        target = AiLogicUtility.GetNearstTargetHelper(npc, CharacterRelation.RELATION_ENEMY);
                        if (null != target)
                        {
                            info.Target = target.GetId();
                        }
                    }
                    if (null != target)
                    {
                        NotifyNpcTargetChange(npc);
                        npc.GetMovementStateInfo().IsMoving = false;
                        NotifyNpcMove(npc);
                        info.Time = 0;
                        ChangeToState(npc, (int)AiStateId.Pursuit);
                    }
                }
            }
        }
示例#6
0
        private void CombatHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (npc.IsDead())
            {
                return;
            }
            NpcAiStateInfo info = npc.GetAiStateInfo();

            info.Time += deltaTime;
            float rps = npc.GetActualProperty().Rps;

            if (rps > 0.001f && info.Time > 1000 / rps)
            {
                info.Time = 0;
                bool          toIdle = false;
                CharacterInfo target = AiLogicUtility.GetSeeingLivingCharacterInfoHelper(npc, info.Target);
                if (null != target && npc.SpatialSystem.CanShoot(npc.SpaceObject, target.GetMovementStateInfo().GetPosition3D()))
                {
                    ScriptRuntime.Vector3 targetPos = target.GetMovementStateInfo().GetPosition3D();
                    ScriptRuntime.Vector3 srcPos    = npc.GetMovementStateInfo().GetPosition3D();
                    float powDist  = Geometry.DistanceSquare(srcPos, targetPos);
                    float dist     = (float)npc.GetActualProperty().AttackRange;
                    float distView = (float)npc.ViewRange;
                    if (powDist < dist * dist)
                    {
                        npc.GetMovementStateInfo().IsMoving = false;
                    }
                    else if (powDist < distView * distView)
                    {
                        npc.GetMovementStateInfo().IsMoving = false;
                    }
                    else
                    {
                        toIdle = true;
                    }
                }
                else
                {
                    toIdle = true;
                }
                if (toIdle)
                {
                    info.Time = 0;
                    npc.GetMovementStateInfo().IsMoving = false;
                    ChangeToState(npc, (int)AiStateId.Idle);
                }
            }
        }
        private Vector3 GetHomePosition(NpcInfo npc, AiData_PvpNpc_General data)
        {
            Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D();
            Vector3 pt     = new Vector3();

            if (data.PatrolPath.GetNearstPoint(npc.SpatialSystem, npc.AvoidanceRadius, srcPos, ref pt))
            {
                if (!npc.SpatialSystem.GetCellMapView(npc.AvoidanceRadius).CanPass(pt))
                {
                    if (!AiLogicUtility.GetWalkablePosition(npc.SpatialSystem.GetCellMapView(npc.AvoidanceRadius), pt, srcPos, ref pt))
                    {
                        pt = srcPos;
                    }
                }
            }
            return(pt);
        }
        public CharacterInfo GetInterestestTargetHelper(CharacterInfo srcObj, CharacterRelation relation)
        {
            CharacterInfo       interestTarget = null;
            List <AiTargetType> priorityList   = new List <AiTargetType>();

            priorityList.Add(AiTargetType.SOLDIER);
            priorityList.Add(AiTargetType.TOWER);
            priorityList.Add(AiTargetType.USER);
            for (int index = 0; index < priorityList.Count; ++index)
            {
                interestTarget = AiLogicUtility.GetInterestestTargetHelper(srcObj, relation, priorityList[index]);
                if (null != interestTarget)
                {
                    break;
                }
            }
            return(interestTarget);
        }
示例#9
0
        //确定新的攻击目标:小兵优先
        private CharacterInfo GetNewTarget(NpcInfo npc)
        {
            NpcAiStateInfo info      = npc.GetAiStateInfo();
            CharacterInfo  npcTarget = AiLogicUtility.GetNearstTargetHelper(npc, CharacterRelation.RELATION_ENEMY, AiTargetType.NPC);

            if (null != npcTarget)
            {
                return(npcTarget);
            }
            else
            {
                CharacterInfo userTarget = AiLogicUtility.GetNearstTargetHelper(npc, CharacterRelation.RELATION_ENEMY, AiTargetType.USER);
                if (null != userTarget)
                {
                    return(userTarget);
                }
            }
            return(null);
        }
示例#10
0
        private void IdleHandler(UserInfo user, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (user.IsDead())
            {
                return;
            }
            UserAiStateInfo info = user.GetAiStateInfo();

            info.Time += deltaTime;
            if (info.Time > 100)
            {
                info.Time = 0;
                CharacterInfo target = null;
                if (info.IsAttacked && m_AttackRangeLast > 0)
                {
                    if (info.Target > 0 /* || info.TargetPos != Vector3.Zero*/)
                    {
                        target = AiLogicUtility.GetSeeingLivingCharacterInfoHelper(user, info.Target);
                        if (null == target)
                        {
                            info.Target = 0;
                            target      = AiLogicUtility.GetNearstTargetHelper(user, CharacterRelation.RELATION_ENEMY);
                        }
                    }
                    if (null != target)
                    {
                        info.Time         = 0;
                        info.Target       = target.GetId();
                        info.IsAttacked   = false;
                        info.AttackRange  = m_AttackRangeLast;
                        m_AttackRangeLast = 0;
                        ChangeToState(user, (int)AiStateId.Combat);
                    }
                }
            }
        }
示例#11
0
 private void PatrolCommandHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
 {
     AiLogicUtility.DoPatrolCommandState(npc, aiCmdDispatcher, deltaTime, this);
 }
示例#12
0
 private void MoveCommandHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
 {
     AiLogicUtility.DoMoveCommandState(npc, aiCmdDispatcher, deltaTime);
 }
示例#13
0
        private void CombatHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (npc.IsDead())
            {
                return;
            }
            NpcAiStateInfo info = npc.GetAiStateInfo();

            info.Time += deltaTime;
            if (info.Time > 100)
            {
                AiData_PveNpc_Monster data = GetAiData(npc);
                if (null != data)
                {
                    data.Time += info.Time;
                    info.Time  = 0;
                    bool          goHome = false;
                    CharacterInfo target = AiLogicUtility.GetSeeingLivingCharacterInfoHelper(npc, info.Target);
                    if (null != target)
                    {
                        float dist       = (float)npc.GetActualProperty().AttackRange;
                        float distGoHome = (float)npc.GohomeRange;
                        ScriptRuntime.Vector3 targetPos = target.GetMovementStateInfo().GetPosition3D();
                        ScriptRuntime.Vector3 srcPos    = npc.GetMovementStateInfo().GetPosition3D();
                        float powDist       = Geometry.DistanceSquare(srcPos, targetPos);
                        float powDistToHome = Geometry.DistanceSquare(srcPos, info.HomePos);
                        float dir           = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z));
                        npc.GetMovementStateInfo().SetFaceDir(dir);
                        if (powDist < data.ShootDistance * data.ShootDistance)
                        {
                            float rps = npc.GetActualProperty().Rps;
                            if (rps > 0.001f && data.Time > 1000 / rps)
                            {
                                data.Time = 0;
                            }
                            npc.GetMovementStateInfo().IsMoving = false;
                            NotifyNpcMove(npc);
                            goHome = true;
                        }
                        else if (powDist < dist * dist /*&& SkillSystem.Instance.CanStartSkill(npc, data.Skill)*/)
                        {
                            ServerNpcSkill(npc, data.Skill, target, targetPos, dir);

                            npc.GetMovementStateInfo().IsMoving = false;
                            NotifyNpcMove(npc);
                            goHome = true;
                        }
                        else if (powDistToHome < distGoHome * distGoHome)
                        {
                            npc.GetMovementStateInfo().IsMoving = false;
                            NotifyNpcMove(npc);
                            info.Time = 0;
                            data.FoundPath.Clear();
                            ChangeToState(npc, (int)AiStateId.Pursuit);
                        }
                        else
                        {
                            goHome = true;
                        }
                    }
                    else
                    {
                        goHome = true;
                    }
                    if (goHome)
                    {
                        npc.GetMovementStateInfo().IsMoving = false;
                        NotifyNpcMove(npc);

                        info.Time = 0;
                        ChangeToState(npc, (int)AiStateId.GoHome);
                    }
                }
            }
        }
示例#14
0
        private void CombatHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (npc.IsDead())
            {
                return;
            }
            NpcAiStateInfo info = npc.GetAiStateInfo();

            info.Time += deltaTime;
            float rps = npc.GetActualProperty().Rps;

            if (rps > 0.001f && info.Time > 1000 / rps)
            {
                info.Time = 0;
                AiData_PveNpc_General data = GetAiData(npc);
                if (null != data)
                {
                    bool          goHome = false;
                    CharacterInfo target = AiLogicUtility.GetSeeingLivingCharacterInfoHelper(npc, info.Target);
                    if (null != target)
                    {
                        float dist       = (float)npc.GetActualProperty().AttackRange;
                        float distGoHome = (float)npc.GohomeRange;
                        ScriptRuntime.Vector3 targetPos = target.GetMovementStateInfo().GetPosition3D();
                        ScriptRuntime.Vector3 srcPos    = npc.GetMovementStateInfo().GetPosition3D();
                        float powDist       = Geometry.DistanceSquare(srcPos, targetPos);
                        float powDistToHome = Geometry.DistanceSquare(srcPos, info.HomePos);
                        if (powDist < dist * dist)
                        {
                            float dir = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z));
                            npc.GetMovementStateInfo().SetFaceDir(dir);
                            npc.GetMovementStateInfo().SetMoveDir(dir);
                            if (npc.CanShoot() && !npc.GetSkillStateInfo().IsSkillActivated())
                            {
                                Data_NpcConfig npcConfig = NpcConfigProvider.Instance.GetNpcConfigById(npc.GetLinkId());
                                if (null == npcConfig)
                                {
                                    return;
                                }
                                if (npcConfig.m_SkillList.Count >= 1)
                                {
                                    ServerNpcSkill(npc, npcConfig.m_SkillList[0], target, targetPos, dir);
                                }
                            }
                        }
                        else if (powDistToHome < distGoHome * distGoHome)
                        {
                            npc.GetMovementStateInfo().IsMoving = false;
                            NotifyNpcMove(npc);
                            info.Time = 0;
                            data.FoundPath.Clear();
                            ChangeToState(npc, (int)AiStateId.Pursuit);
                        }
                        else
                        {
                            goHome = true;
                        }
                    }
                    else
                    {
                        goHome = true;
                    }
                    if (goHome)
                    {
                        npc.GetMovementStateInfo().IsMoving = false;
                        NotifyNpcMove(npc);
                        info.Time = 0;
                        ChangeToState(npc, (int)AiStateId.GoHome);
                    }
                }
            }
        }
        private void CombatHandler(UserInfo user, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (user.IsDead())
            {
                return;
            }
            UserAiStateInfo info = user.GetAiStateInfo();

            info.Time += deltaTime;
            if (info.Time > 100)
            {
                AiData_UserSelf_General data = GetAiData(user);
                if (null != data)
                {
                    data.Time += info.Time;
                    info.Time  = 0;
                    ///
                    CharacterInfo target    = AiLogicUtility.GetSeeingLivingCharacterInfoHelper(user, info.Target);
                    Vector3       targetPos = Vector3.Zero;
                    float         dist      = info.AttackRange;
                    if (null != target)
                    {
                        targetPos = target.GetMovementStateInfo().GetPosition3D();
                    }
                    else
                    {
                        targetPos = info.TargetPos;
                    }
                    Vector3 srcPos  = user.GetMovementStateInfo().GetPosition3D();
                    float   powDist = Geometry.DistanceSquare(srcPos, targetPos);
                    if (!info.IsAttacked)
                    {
                        if (powDist < dist * dist)
                        {
                            data.Time        = 0;
                            info.AttackRange = 0;
                            info.IsAttacked  = true;
                            float dir = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z));
                            user.GetMovementStateInfo().SetFaceDir(dir);
                            user.GetMovementStateInfo().SetMoveDir(dir);
                            if (null != target)
                            {
                                if (null != OnUserStartAttack)
                                {
                                    OnUserStartAttack(user, targetPos.X, targetPos.Y, targetPos.Z);
                                }
                            }
                            else
                            {
                                if (null != OnUserSkill)
                                {
                                    OnUserSkill(user);
                                }
                            }
                            ///
                            user.GetMovementStateInfo().StopMove();
                            NotifyUserMove(user);
                            info.Time = 0;
                            data.FoundPath.Clear();
                            ChangeToState(user, (int)AiStateId.Idle);
                        }
                        else
                        {
                            if (null != OnSkillPursuit)
                            {
                                OnSkillPursuit(user);
                            }
                            user.GetMovementStateInfo().StopMove();
                            NotifyUserMove(user);
                            info.Time       = 0;
                            info.IsAttacked = false;
                            data.FoundPath.Clear();
                            ChangeToState(user, (int)AiStateId.Pursuit);
                        }
                    }
                }
                else
                {
                    info.Time = 0;
                }
            }
        }
        private void PursuitHandler(UserInfo user, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (user.IsDead())
            {
                return;
            }
            UserAiStateInfo         info = user.GetAiStateInfo();
            AiData_UserSelf_General data = GetAiData(user);

            if (null != data)
            {
                if (info.Target > 0)
                {
                    CharacterInfo target = AiLogicUtility.GetLivingCharacterInfoHelper(user, info.Target);
                    if (null != target)
                    {
                        float   dist                 = info.AttackRange - 1.0f;
                        Vector3 targetPos            = target.GetMovementStateInfo().GetPosition3D();
                        ScriptRuntime.Vector3 srcPos = user.GetMovementStateInfo().GetPosition3D();
                        float powDist                = Geometry.DistanceSquare(srcPos, targetPos);
                        if (powDist < dist * dist)
                        {
                            user.GetMovementStateInfo().IsMoving = false;
                            info.Time = 0;
                            data.Time = 0;
                            ChangeToState(user, (int)AiStateId.Combat);
                            NotifyUserMove(user);
                        }
                        else
                        {
                            info.Time += deltaTime;
                            if (info.Time > 100)
                            {
                                info.Time = 0;
                                CharacterInfo target2 = GetCanAttackUserTarget(user);
                                if (null == target2)
                                {
                                    AiLogicUtility.GetNearstTargetHelper(user, CharacterRelation.RELATION_ENEMY);
                                }
                                if (null == target2 || target == target2)
                                {
                                    PathToTarget(user, data.FoundPath, targetPos, deltaTime);
                                }
                                else
                                {
                                    info.Target = target2.GetId();
                                    return;
                                }
                            }
                        }
                    }
                    else
                    {
                        user.GetMovementStateInfo().StopMove();
                        NotifyUserMove(user);
                        info.Time = 0;
                        data.Time = 0;
                        data.FoundPath.Clear();
                        ChangeToState(user, (int)AiStateId.Idle);
                    }
                }
                else
                {
                    float   dist                 = info.AttackRange;
                    Vector3 targetPos            = info.TargetPos;
                    ScriptRuntime.Vector3 srcPos = user.GetMovementStateInfo().GetPosition3D();
                    float powDist                = Geometry.DistanceSquare(srcPos, targetPos);
                    if (powDist < dist * dist)
                    {
                        user.GetMovementStateInfo().IsMoving = false;
                        info.Time = 0;
                        data.Time = 0;
                        ChangeToState(user, (int)AiStateId.Combat);
                        NotifyUserMove(user);
                    }
                    else
                    {
                        info.Time += deltaTime;
                        if (info.Time > 100)
                        {
                            info.Time = 0;
                            PathToTarget(user, data.FoundPath, targetPos, deltaTime);
                        }
                    }
                }
            }
        }
示例#17
0
        public static void PathToTarget(NpcInfo npc, AiPathData data, Vector3 pathTargetPos, long deltaTime, bool faceIsMoveFir, AbstractNpcStateLogic logic)
        {
            NpcAiStateInfo info = npc.GetAiStateInfo();

            if (null != data)
            {
                data.UpdateTime += deltaTime;
                ScriptRuntime.Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D();
                float dir           = npc.GetMovementStateInfo().GetMoveDir();
                bool  findObstacle  = false;
                bool  havePathPoint = data.HavePathPoint;
                if (havePathPoint)//沿路点列表移动的逻辑
                {
                    Vector3 targetPos = data.CurPathPoint;
                    if (!data.IsReached(srcPos))//向指定路点移动(避让移动过程)
                    {
                        float   angle        = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z));
                        Vector3 prefVelocity = (float)npc.GetActualProperty().MoveSpeed *new Vector3((float)Math.Sin(angle), 0, (float)Math.Cos(angle));
                        Vector3 v            = new Vector3(targetPos.X - srcPos.X, 0, targetPos.Z - srcPos.Z);
                        v.Normalize();
                        Vector3 velocity    = npc.SpaceObject.GetVelocity();
                        float   speedSquare = (float)npc.GetActualProperty().MoveSpeed *(float)npc.GetActualProperty().MoveSpeed;
                        long    stTime      = TimeUtility.GetElapsedTimeUs();
                        Vector3 newVelocity = npc.SpatialSystem.ComputeVelocity(npc.SpaceObject, v, (float)deltaTime / 1000, (float)npc.GetActualProperty().MoveSpeed, (float)npc.GetRadius(), data.IsUsingAvoidanceVelocity);
                        findObstacle = !AiLogicUtility.IsWalkable(npc.SpatialSystem.GetCellMapView(npc.AvoidanceRadius), srcPos, newVelocity);
                        long endTime  = TimeUtility.GetElapsedTimeUs();
                        long calcTime = endTime - stTime;
                        if (calcTime > 10000)
                        {
                            LogSystem.Warn("*** pve ComputeVelocity consume {0} us,npc:{1} velocity:{2} newVelocity:{3} deltaTime:{4} speed:{5} pos:{6}", calcTime, npc.GetId(), velocity.ToString(), newVelocity.ToString(), deltaTime, npc.GetActualProperty().MoveSpeed, npc.GetMovementStateInfo().GetPosition3D().ToString());
                        }
                        if (Geometry.DistanceSquare(newVelocity, new Vector3()) <= speedSquare * 0.25f)//避让计算的移动速度变小(说明没有更好的保持原速的选择,停止)
                        {
                            npc.GetMovementStateInfo().IsMoving = false;
                            logic.NotifyNpcMove(npc);
                            data.IsUsingAvoidanceVelocity = false;
                        }
                        else if (findObstacle)//当前移动方向遇到阻挡,停止移动,触发寻路
                        {
                            npc.GetMovementStateInfo().IsMoving = false;
                            logic.NotifyNpcMove(npc);
                            data.IsUsingAvoidanceVelocity = false;
                        }
                        else if (data.UpdateTime > 1000)//避让速度改变每秒一次(表现上更像人类一些)
                        {
                            data.UpdateTime = 0;

                            float newAngle = Geometry.GetYAngle(new Vector2(0, 0), new Vector2(newVelocity.X, newVelocity.Z));
                            npc.GetMovementStateInfo().SetMoveDir(newAngle);
                            if (faceIsMoveFir)
                            {
                                npc.GetMovementStateInfo().SetFaceDir(newAngle);
                            }
                            newVelocity.Normalize();
                            npc.GetMovementStateInfo().TargetPosition = srcPos + newVelocity * Geometry.Distance(srcPos, targetPos);
                            npc.GetMovementStateInfo().IsMoving       = true;
                            logic.NotifyNpcMove(npc);
                            data.IsUsingAvoidanceVelocity = true;
                        }
                        else if (Geometry.DistanceSquare(velocity, newVelocity) > 9.0f) //没有到速度改变周期,但避让方向需要大幅调整
                        {
                            if (Geometry.Dot(newVelocity, prefVelocity) > 0)            //如果是调整为与目标方向一致,则进行调整
                            {
                                float newAngle = Geometry.GetYAngle(new Vector2(0, 0), new Vector2(newVelocity.X, newVelocity.Z));
                                npc.GetMovementStateInfo().SetMoveDir(newAngle);
                                if (faceIsMoveFir)
                                {
                                    npc.GetMovementStateInfo().SetFaceDir(newAngle);
                                }
                                newVelocity.Normalize();
                                npc.GetMovementStateInfo().TargetPosition = srcPos + newVelocity * Geometry.Distance(srcPos, targetPos);
                                npc.GetMovementStateInfo().IsMoving       = true;
                                logic.NotifyNpcMove(npc);
                                data.IsUsingAvoidanceVelocity = true;
                            }
                            else//如果调整为远离目标方向,则停止
                            {
                                npc.GetMovementStateInfo().IsMoving = false;
                                logic.NotifyNpcMove(npc);
                                data.IsUsingAvoidanceVelocity = false;
                            }
                        }
                        else if (!npc.GetMovementStateInfo().IsMoving&& velocity.LengthSquared() > speedSquare * 0.25f)//正常移动过程,继续移动
                        {
                            velocity.Normalize();
                            npc.GetMovementStateInfo().TargetPosition = srcPos + velocity * Geometry.Distance(srcPos, targetPos);
                            npc.GetMovementStateInfo().IsMoving       = true;
                            logic.NotifyNpcMove(npc);
                            data.IsUsingAvoidanceVelocity = false;
                        }
                    }
                    else//改变路点或结束沿路点移动
                    {
                        data.UseNextPathPoint();
                        if (data.HavePathPoint)
                        {
                            targetPos = data.CurPathPoint;
                            npc.GetMovementStateInfo().TargetPosition = targetPos;
                            float angle = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z));
                            npc.GetMovementStateInfo().SetMoveDir(angle);
                            if (faceIsMoveFir)
                            {
                                npc.GetMovementStateInfo().SetFaceDir(angle);
                            }
                            npc.GetMovementStateInfo().IsMoving = true;
                            logic.NotifyNpcMove(npc);
                            data.IsUsingAvoidanceVelocity = false;
                        }
                        else
                        {
                            data.Clear();
                        }
                    }
                }
                if (!havePathPoint || findObstacle)//获得路点过程(寻路)
                {
                    data.Clear();
                    Vector3 targetPos = pathTargetPos;
                    bool    canGo     = true;
                    if (!npc.SpatialSystem.GetCellMapView(npc.AvoidanceRadius).CanPass(targetPos))
                    {
                        if (!AiLogicUtility.GetWalkablePosition(npc.SpatialSystem.GetCellMapView(npc.AvoidanceRadius), targetPos, srcPos, ref targetPos))
                        {
                            canGo = false;
                        }
                    }
                    if (canGo)
                    {
                        List <Vector3> posList = null;
                        bool           canPass = npc.SpatialSystem.CanPass(npc.SpaceObject, targetPos);
                        if (canPass)
                        {
                            posList = new List <Vector3>();
                            posList.Add(srcPos);
                            posList.Add(targetPos);
                        }
                        else
                        {
                            long stTime = TimeUtility.GetElapsedTimeUs();
                            posList = npc.SpatialSystem.FindPath(srcPos, targetPos, npc.AvoidanceRadius);
                            long endTime  = TimeUtility.GetElapsedTimeUs();
                            long calcTime = endTime - stTime;
                            if (calcTime > 10000)
                            {
                                LogSystem.Warn("*** pve FindPath consume {0} us,npc:{1} from:{2} to:{3} radius:{4} pos:{5}", calcTime, npc.GetId(), srcPos.ToString(), targetPos.ToString(), npc.AvoidanceRadius, npc.GetMovementStateInfo().GetPosition3D().ToString());
                            }
                        }
                        if (posList.Count >= 2)
                        {
                            data.SetPathPoints(posList[0], posList, 1);
                            targetPos = data.CurPathPoint;
                            npc.GetMovementStateInfo().TargetPosition = targetPos;
                            float angle = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z));
                            npc.GetMovementStateInfo().SetMoveDir(angle);
                            if (faceIsMoveFir)
                            {
                                npc.GetMovementStateInfo().SetFaceDir(angle);
                            }
                            npc.GetMovementStateInfo().IsMoving = true;
                            logic.NotifyNpcMove(npc);
                            data.IsUsingAvoidanceVelocity = false;
                        }
                        else
                        {
                            npc.GetMovementStateInfo().IsMoving = false;
                            logic.NotifyNpcMove(npc);
                            data.IsUsingAvoidanceVelocity = false;
                        }
                    }
                    else
                    {
                        npc.GetMovementStateInfo().IsMoving = false;
                        logic.NotifyNpcMove(npc);
                        data.IsUsingAvoidanceVelocity = false;
                    }
                }
            }
        }
示例#18
0
        private void PursuitHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (npc.IsDead())
            {
                return;
            }
            NpcAiStateInfo info = npc.GetAiStateInfo();
            //ai配置参数
            long maxPursuitTime = int.Parse(info.AiParam[0]);
            long minPursuitTime = int.Parse(info.AiParam[1]);
            //
            bool goHome = false;

            info.Time += deltaTime;
            CharacterInfo         target = AiLogicUtility.GetSeeingLivingCharacterInfoHelper(npc, info.Target);
            AiData_PvpNpc_General data   = GetAiData(npc);

            if (null != target && info.Time <= maxPursuitTime && null != data)
            {
                if (info.Time >= minPursuitTime)
                {
                    //超过最小追击时间,尝试换攻击目标
                    CharacterInfo interestestTarget = GetInterestestTargetHelper(npc, CharacterRelation.RELATION_ENEMY);
                    if (null != interestestTarget && interestestTarget != target)
                    {
                        info.Time   = 0;
                        info.Target = interestestTarget.GetId();
                        data.FoundPath.Clear();
                        target = interestestTarget;
                    }
                }
                float   dist                 = (float)(npc.GetActualProperty().AttackRange *npc.AttackRangeCoefficient);
                float   distGoHome           = (float)npc.GohomeRange;
                Vector3 targetPos            = target.GetMovementStateInfo().GetPosition3D();
                ScriptRuntime.Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D();
                float powDist                = Geometry.DistanceSquare(srcPos, targetPos);
                float powDistToHome          = Geometry.DistanceSquare(srcPos, info.HomePos);
                if (powDist <= dist * dist && npc.SpatialSystem.CanShoot(npc.SpaceObject, target.GetMovementStateInfo().GetPosition3D()))
                {
                    npc.GetMovementStateInfo().IsMoving = false;
                    info.Time = 0;
                    ChangeToState(npc, (int)AiStateId.Combat);
                    NotifyNpcMove(npc);
                }
                else if (powDistToHome < distGoHome * distGoHome)
                {
                    if (AiLogicUtility.GetWalkablePosition(target, npc, ref targetPos))
                    {
                        PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, deltaTime);
                    }
                    else
                    {
                        npc.GetMovementStateInfo().IsMoving = false;
                        NotifyNpcMove(npc);
                    }
                }
                else
                {
                    goHome = true;
                }
            }
            else
            {
                goHome = true;
            }
            if (goHome)
            {
                npc.GetMovementStateInfo().IsMoving = false;
                NotifyNpcMove(npc);
                info.Time    = 0;
                info.HomePos = GetHomePosition(npc, data);
                data.FoundPath.Clear();
                ChangeToState(npc, (int)AiStateId.GoHome);
            }
        }
示例#19
0
        public static void DoPatrolCommandState(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime, AbstractNpcStateLogic logic)
        {
            if (npc.IsDead())
            {
                return;
            }
            NpcAiStateInfo info = npc.GetAiStateInfo();

            info.Time += deltaTime;
            if (info.Time > 100)
            {
                long intervalTime = info.Time;
                info.Time = 0;
                CharacterInfo target = null;
                if (info.IsExternalTarget)
                {
                    target = AiLogicUtility.GetSeeingLivingCharacterInfoHelper(npc, info.Target);
                    if (null == target)
                    {
                        target = AiLogicUtility.GetNearstTargetHelper(npc, CharacterRelation.RELATION_ENEMY);
                        if (null != target)
                        {
                            info.Target = target.GetId();
                        }
                    }
                }
                else
                {
                    target = AiLogicUtility.GetNearstTargetHelper(npc, CharacterRelation.RELATION_ENEMY);
                    if (null != target)
                    {
                        info.Target = target.GetId();
                    }
                }
                if (null != target)
                {
                    logic.NotifyNpcTargetChange(npc);
                    npc.GetMovementStateInfo().IsMoving = false;
                    logic.NotifyNpcMove(npc);
                    info.Time = 0;
                    AiData_ForPatrolCommand data = GetAiDataForPatrolCommand(npc);
                    if (null != data)
                    {
                        data.FoundPath.Clear();
                    }
                    logic.ChangeToState(npc, (int)AiStateId.Pursuit);
                }
                else
                {
                    AiData_ForPatrolCommand data = GetAiDataForPatrolCommand(npc);
                    if (null != data)
                    {
                        ScriptRuntime.Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D();
                        if (data.PatrolPath.HavePathPoint && !data.PatrolPath.IsReached(srcPos))
                        {
                            PathToTargetWithoutObstacle(npc, data.FoundPath, data.PatrolPath.CurPathPoint, intervalTime, true, logic);
                        }
                        else
                        {
                            data.PatrolPath.UseNextPathPoint();
                            data.FoundPath.Clear();
                            if (!data.PatrolPath.HavePathPoint)
                            {
                                if (data.IsLoopPatrol)
                                {
                                    data.PatrolPath.Restart();
                                }
                                else
                                {
                                    info.Time = 0;
                                    logic.ChangeToState(npc, (int)AiStateId.Idle);
                                }
                            }
                        }
                        info.HomePos = npc.GetMovementStateInfo().GetPosition3D();
                    }
                    else
                    {
                        info.Time = 0;
                        logic.ChangeToState(npc, (int)AiStateId.Idle);
                    }
                }
            }
        }
示例#20
0
        private void PursuitHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (npc.IsDead() || npc.GetSkillStateInfo().IsSkillActivated())
            {
                return;
            }
            NpcAiStateInfo        info   = npc.GetAiStateInfo();
            bool                  toIdle = false;
            AiData_PveNpc_Monster data   = GetAiData(npc);

            if (null != data)
            {
                CharacterInfo target = AiLogicUtility.GetSeeingLivingCharacterInfoHelper(npc, info.Target);
                if (null != target)
                {
                    float   dist                 = (float)npc.GetActualProperty().AttackRange;
                    float   distGoHome           = (float)npc.GohomeRange;
                    Vector3 targetPos            = target.GetMovementStateInfo().GetPosition3D();
                    ScriptRuntime.Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D();
                    float powDist                = Geometry.DistanceSquare(srcPos, targetPos);
                    float powDistToHome          = Geometry.DistanceSquare(srcPos, info.HomePos);
                    if (powDist < dist * dist)//进入攻击状态
                    {
                        npc.GetMovementStateInfo().IsMoving = false;
                        NotifyNpcMove(npc);
                        info.Time = 0;
                        data.Time = 0;
                        ChangeToState(npc, (int)AiStateId.Combat);
                    }
                    else if (powDistToHome < distGoHome * distGoHome)//追击
                    {
                        info.Time += deltaTime;
                        if (info.Time > 100)
                        {
                            info.Time = 0;
                            if (AiLogicUtility.GetWalkablePosition(target, npc, ref targetPos))
                            {
                                AiLogicUtility.PathToTarget(npc, data.FoundPath, targetPos, 100, true, this);
                            }
                            else
                            {
                                npc.GetMovementStateInfo().IsMoving = false;
                                NotifyNpcMove(npc);
                            }
                        }
                    }
                    else
                    {
                        toIdle = true;
                    }
                }
                else
                {
                    toIdle = true;
                }
                if (toIdle)
                {
                    npc.GetMovementStateInfo().IsMoving = false;
                    NotifyNpcMove(npc);
                    info.Time = 0;
                    ChangeToState(npc, (int)AiStateId.Idle);
                }
            }
        }
示例#21
0
        private void CombatHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (npc.IsDead())
            {
                return;
            }
            NpcAiStateInfo info = npc.GetAiStateInfo();

            info.Time += deltaTime;
            if (info.Time > 100)
            {
                AiData_PvpNpc_General data = GetAiData(npc);
                if (null != data)
                {
                    data.Time         += info.Time;
                    data.ThinkingTime += info.Time;
                    //ai配置参数  小兵思考时间
                    long thinkingTime = int.Parse(info.AiParam[2]);
                    //大于思考时间 重新选择新的目标
                    if (data.ThinkingTime > thinkingTime)
                    {
                        CharacterInfo interestestTarget = GetInterestestTargetHelper(npc, CharacterRelation.RELATION_ENEMY);
                        if (null != interestestTarget && info.Target != interestestTarget.GetId())
                        {
                            npc.GetMovementStateInfo().IsMoving = false;
                            NotifyNpcMove(npc);
                            info.Time         = 0;
                            data.Time         = 0;
                            data.ThinkingTime = 0;
                            info.Target       = interestestTarget.GetId();
                            return;
                        }
                    }
                    info.Time = 0;
                    bool          changeTarget = false;
                    CharacterInfo target       = AiLogicUtility.GetSeeingLivingCharacterInfoHelper(npc, info.Target);
                    if (null != target)
                    {
                        float dist       = (float)(npc.GetActualProperty().AttackRange *npc.AttackRangeCoefficient);
                        float distGoHome = (float)npc.GohomeRange;
                        ScriptRuntime.Vector3 targetPos = target.GetMovementStateInfo().GetPosition3D();
                        ScriptRuntime.Vector3 srcPos    = npc.GetMovementStateInfo().GetPosition3D();
                        float powDist       = Geometry.DistanceSquare(srcPos, targetPos);
                        float powDistToHome = Geometry.DistanceSquare(srcPos, info.HomePos);
                        if (powDist < dist * dist && npc.SpatialSystem.CanShoot(npc.SpaceObject, target.GetMovementStateInfo().GetPosition3D()))
                        {
                            float rps = npc.GetActualProperty().Rps;
                            if (rps > 0.001f && data.Time > 1000 / rps)
                            {
                                data.Time = 0;
                                float dir = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z));
                                npc.GetMovementStateInfo().SetFaceDir(dir);
                                npc.GetMovementStateInfo().SetMoveDir(dir);
                                if (npc.CanShoot())
                                {
                                    aiCmdDispatcher.NpcFace(npc, this);
                                }
                            }
                        }
                        else if (powDistToHome < distGoHome * distGoHome)
                        {
                            npc.GetMovementStateInfo().IsMoving = false;
                            NotifyNpcMove(npc);
                            info.Time = 0;
                            data.FoundPath.Clear();
                            ChangeToState(npc, (int)AiStateId.Pursuit);
                        }
                        else
                        {
                            changeTarget = true;
                        }
                    }
                    else
                    {
                        changeTarget = true;
                    }
                    if (changeTarget)
                    {
                        data.FoundPath.Clear();
                        target = GetInterestestTargetHelper(npc, CharacterRelation.RELATION_ENEMY);
                        if (null != target)
                        {
                            npc.GetMovementStateInfo().IsMoving = false;
                            NotifyNpcMove(npc);
                            info.Time   = 0;
                            info.Target = target.GetId();
                            ChangeToState(npc, (int)AiStateId.Pursuit);
                        }
                        else
                        {
                            npc.GetMovementStateInfo().IsMoving = false;
                            NotifyNpcMove(npc);
                            info.Time    = 0;
                            info.HomePos = GetHomePosition(npc, data);
                            ChangeToState(npc, (int)AiStateId.GoHome);
                        }
                    }
                }
                else
                {
                    info.Time = 0;
                }
            }
        }
示例#22
0
        private void CombatHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (npc.IsDead())
            {
                return;
            }
            NpcAiStateInfo info = npc.GetAiStateInfo();

            info.Time += deltaTime;
            if (info.Time > m_IntervalTime)
            {
                AiData_Demo_Melee data = GetAiData(npc);
                if (null != data)
                {
                    data.Time += info.Time;
                    info.Time  = 0;
                    bool          goHome = false;
                    CharacterInfo target = AiLogicUtility.GetLivingCharacterInfoHelper(npc, info.Target);
                    //CharacterInfo target = AiLogicUtility.GetInterestestTargetHelper(npc, CharacterRelation.RELATION_ENEMY, AiTargetType.USER);
                    if (null != target)
                    {
                        float dist       = (float)npc.GetActualProperty().AttackRange;
                        float distGoHome = (float)npc.GohomeRange;
                        ScriptRuntime.Vector3 targetPos = target.GetMovementStateInfo().GetPosition3D();
                        ScriptRuntime.Vector3 srcPos    = npc.GetMovementStateInfo().GetPosition3D();
                        float powDist       = Geometry.DistanceSquare(srcPos, targetPos);
                        float powDistToHome = Geometry.DistanceSquare(srcPos, info.HomePos);
                        if (powDist < dist * dist)
                        {
                            float rps = npc.GetActualProperty().Rps;
                            if (rps > 0.001f && data.Time > 1000 / rps)
                            {
                                data.Time = 0;
                                float dir = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z));
                                NotifyNpcFace(npc, dir);
                                //npc.GetMovementStateInfo().SetMoveDir(dir);
                                if (powDist < (npc.ViewRange - 1.0f) * (npc.ViewRange - 1.0f))
                                {
                                    if (0 == data.SkillToCast)
                                    {
                                        data.SkillToCast = GetNextSkill();
                                    }
                                    if (null != OnNpcSkill)
                                    {
                                        float angle = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z));
                                        if (Geometry.IsSameDouble(angle, npc.GetMovementStateInfo().GetFaceDir()))
                                        {
                                            OnNpcSkill(npc, data.SkillToCast, target);
                                            data.SkillToCast = 0;
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            npc.GetMovementStateInfo().IsMoving = false;
                            NotifyNpcMove(npc);
                            info.Time = 0;
                            data.FoundPath.Clear();
                            data.SkillToCast = 0;
                            ChangeToState(npc, (int)AiStateId.Pursuit);
                        }
                    }
                    else
                    {
                        goHome = true;
                    }
                    if (goHome)
                    {
                        npc.GetMovementStateInfo().IsMoving = false;
                        NotifyNpcMove(npc);
                        info.Time = 0;
                        ChangeToState(npc, (int)AiStateId.GoHome);
                    }
                }
                else
                {
                    info.Time = 0;
                }
            }
        }
示例#23
0
        private void PursuitHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (npc.IsDead())
            {
                return;
            }
            NpcAiStateInfo    info   = npc.GetAiStateInfo();
            bool              goHome = false;
            AiData_Demo_Melee data   = GetAiData(npc);

            if (null != data)
            {
                CharacterInfo target = AiLogicUtility.GetLivingCharacterInfoHelper(npc, info.Target);
                if (null != target)
                {
                    if (data.WaitTime <= m_ResponseTime)
                    {
                        if (!data.HasMeetEnemy)
                        {
                            if (null != OnNpcMeetEnemy)
                            {
                                OnNpcMeetEnemy(npc, data.MeetEnemyAnim);
                            }
                            data.HasMeetEnemy = true;
                        }
                        float angle = Geometry.GetYAngle(npc.GetMovementStateInfo().GetPosition2D(), target.GetMovementStateInfo().GetPosition2D());
                        NotifyNpcFace(npc, angle);
                        data.WaitTime += deltaTime;
                        return;
                    }
                    data.WalkTime += deltaTime;
                    if (data.WalkTime < 4000)
                    {
                        npc.GetActualProperty().SetMoveSpeed(Operate_Type.OT_Absolute, GetWalkSpeed(npc));
                        npc.GetMovementStateInfo().MovementMode = MovementMode.LowSpeed;
                    }
                    else
                    {
                        npc.GetActualProperty().SetMoveSpeed(Operate_Type.OT_Absolute, GetRunSpeed(npc));
                        npc.GetMovementStateInfo().MovementMode = MovementMode.HighSpeed;
                    }
                    float   dist                 = (float)npc.GetActualProperty().AttackRange;
                    float   distGoHome           = (float)npc.GohomeRange;
                    Vector3 targetPos            = target.GetMovementStateInfo().GetPosition3D();
                    ScriptRuntime.Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D();
                    float powDist                = Geometry.DistanceSquare(srcPos, targetPos);
                    if (0 == data.SkillToCast)
                    {
                        data.SkillToCast = GetNextSkill();
                    }
                    if (powDist < (npc.ViewRange - m_TauntDis) * (npc.ViewRange - m_TauntDis))
                    {
                        if (m_Taunt == data.SkillToCast)
                        {
                            float angle = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z));
                            if (Geometry.IsSameDouble(angle, npc.GetMovementStateInfo().GetFaceDir()))
                            {
                                OnNpcSkill(npc, data.SkillToCast, target);
                                data.SkillToCast = 0;
                            }
                        }
                    }
                    float powDistToHome = Geometry.DistanceSquare(srcPos, info.HomePos);
                    if (powDist < dist * dist)
                    {
                        npc.GetMovementStateInfo().IsMoving = false;
                        info.Time = 0;
                        data.Time = 0;
                        npc.GetActualProperty().SetMoveSpeed(Operate_Type.OT_Absolute, GetRunSpeed(npc));
                        npc.GetMovementStateInfo().MovementMode = MovementMode.HighSpeed;
                        ChangeToState(npc, (int)AiStateId.Combat);
                        NotifyNpcMove(npc);
                    }
                    else
                    {
                        info.Time += deltaTime;
                        if (info.Time > m_IntervalTime)
                        {
                            info.Time = 0;
                            AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                        }
                    }
                }
                else
                {
                    goHome = true;
                }
                if (goHome)
                {
                    npc.GetMovementStateInfo().IsMoving = false;
                    NotifyNpcMove(npc);
                    info.Time = 0;
                    data.Time = 0;
                    npc.GetActualProperty().SetMoveSpeed(Operate_Type.OT_Absolute, 3.5f);
                    ChangeToState(npc, (int)AiStateId.Combat);
                    ChangeToState(npc, (int)AiStateId.GoHome);
                }
            }
        }
示例#24
0
        private void PursuitHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (npc.IsDead() || npc.GetSkillStateInfo().IsSkillActivated())
            {
                return;
            }
            NpcAiStateInfo info   = npc.GetAiStateInfo();
            bool           goHome = false;
            AiData_PveNpc_Monster_CloseCombat data = GetAiData(npc);

            if (null != data)
            {
                CharacterInfo target = AiLogicUtility.GetSeeingLivingCharacterInfoHelper(npc, info.Target);
                if (null != target)
                {
                    float   dist                 = (float)npc.GetActualProperty().AttackRange;
                    float   distGoHome           = (float)npc.GohomeRange;
                    Vector3 targetPos            = target.GetMovementStateInfo().GetPosition3D();
                    ScriptRuntime.Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D();
                    float powDist                = Geometry.DistanceSquare(srcPos, targetPos);
                    float powDistToHome          = Geometry.DistanceSquare(srcPos, info.HomePos);
                    if (powDist < dist * dist)//进入移动攻击状态
                    {
                        if (null != npc.GetSkillStateInfo().GetImpactInfoById(data.PreAttackImpact))
                        {
                            ServerNpcStopImpact(npc, data.PreAttackImpact);
                        }
                        info.Time = 0;
                        data.FoundPath.Clear();
                        data.Time = (long)(1000.0f / npc.GetActualProperty().Rps);
                        ChangeToState(npc, (int)AiStateId.Combat);
                    }
                    else if (powDist < data.PreAttackDistance * data.PreAttackDistance) //预热状态
                    {
                        if (null == npc.GetSkillStateInfo().GetImpactInfoById(data.FastMoveImpact))
                        {
                            ServerNpcImpact(npc, data.FastMoveImpact, npc);
                        }
                        if (null == npc.GetSkillStateInfo().GetImpactInfoById(data.PreAttackImpact))
                        {
                            ServerNpcImpact(npc, data.PreAttackImpact, npc);
                        }
                        info.Time += deltaTime;
                        if (info.Time > 100)
                        {
                            info.Time = 0;
                            if (AiLogicUtility.GetWalkablePosition(target, npc, ref targetPos))
                            {
                                AiLogicUtility.PathToTarget(npc, data.FoundPath, targetPos, 100, true, this);
                            }
                            else
                            {
                                npc.GetMovementStateInfo().IsMoving = false;
                                NotifyNpcMove(npc);
                            }
                        }
                    }
                    else if (powDistToHome < distGoHome * distGoHome)//追击
                    {
                        if (data.TestFlag != 3)
                        {
                            data.TestFlag = 3;
                        }
                        if (null != npc.GetSkillStateInfo().GetImpactInfoById(data.FastMoveImpact))
                        {
                            ServerNpcStopImpact(npc, data.FastMoveImpact);
                        }
                        if (null != npc.GetSkillStateInfo().GetImpactInfoById(data.PreAttackImpact))
                        {
                            ServerNpcStopImpact(npc, data.PreAttackImpact);
                        }
                        info.Time += deltaTime;
                        if (info.Time > 100)
                        {
                            info.Time = 0;
                            if (AiLogicUtility.GetWalkablePosition(target, npc, ref targetPos))
                            {
                                AiLogicUtility.PathToTarget(npc, data.FoundPath, targetPos, 100, true, this);
                            }
                            else
                            {
                                npc.GetMovementStateInfo().IsMoving = false;
                                NotifyNpcMove(npc);
                            }
                        }
                    }
                    else
                    {
                        goHome = true;
                    }
                }
                else
                {
                    goHome = true;
                }
                if (goHome)
                {
                    npc.GetMovementStateInfo().IsMoving = false;
                    NotifyNpcMove(npc);

                    info.Time = 0;
                    ChangeToState(npc, (int)AiStateId.GoHome);
                }
            }
        }
示例#25
0
        private void CombatHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (npc.IsDead())
            {
                return;
            }
            NpcAiStateInfo     info = npc.GetAiStateInfo();
            AiData_PveNpc_Trap data = GetAiData(npc);

            if (null != data && !data.IsTriggered)
            {
                CharacterInfo source = npc.SceneContext.GetCharacterInfoById(npc.CreatorId);
                if (null != source)
                {
                    if (data.ImpactToMyself > 0)
                    {
                        ServerNpcImpact(source, data.ImpactToMyself, npc);
                    }
                    CharacterInfo target = AiLogicUtility.GetSeeingLivingCharacterInfoHelper(npc, info.Target);
                    if (null != target)
                    {
                        if (data.Impact1ToTarget > 0)
                        {
                            ServerNpcImpact(source, data.Impact1ToTarget, target);
                        }
                        if (data.Impact2ToTarget > 0)
                        {
                            ServerNpcImpact(source, data.Impact2ToTarget, target);
                        }
                    }
                    int ct = 1;
                    IList <ISpaceObject> objs = npc.SpatialSystem.GetObjectInCircle(npc.GetMovementStateInfo().GetPosition3D(), data.RadiusOfTrigger);
                    foreach (ISpaceObject obj in objs)
                    {
                        if (obj.GetObjType() == SpatialObjType.kNPC || obj.GetObjType() == SpatialObjType.kUser)
                        {
                            CharacterInfo charInfo = obj.RealObject as CharacterInfo;
                            if (null != charInfo)
                            {
                                if (CharacterInfo.GetRelation(npc, charInfo) == CharacterRelation.RELATION_ENEMY)
                                {
                                    if (ct < data.DamageCount)
                                    {
                                        if (data.Impact1ToTarget > 0)
                                        {
                                            ServerNpcImpact(source, data.Impact1ToTarget, charInfo);
                                        }
                                        if (data.Impact2ToTarget > 0)
                                        {
                                            ServerNpcImpact(source, data.Impact2ToTarget, charInfo);
                                        }
                                        ++ct;
                                    }
                                }
                            }
                        }
                    }
                }
                data.IsTriggered = true;
            }
        }
示例#26
0
        private void CombatHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (npc.IsDead())
            {
                return;
            }
            NpcAiStateInfo info = npc.GetAiStateInfo();

            info.Time += deltaTime;
            float rps = npc.GetActualProperty().Rps;

            if (rps > 0.001f && info.Time > 1000 / rps)
            {
                info.Time = 0;
                CheckImpact(npc);
                bool toIdle = false;
                //修改确定攻击目标的逻辑
                CharacterInfo target = AiLogicUtility.GetSeeingLivingCharacterInfoHelper(npc, info.Target);
                if (null != target && npc.SpatialSystem.CanShoot(npc.SpaceObject, target.GetMovementStateInfo().GetPosition3D()))
                {
                    ScriptRuntime.Vector3 targetPos = target.GetMovementStateInfo().GetPosition3D();
                    ScriptRuntime.Vector3 srcPos    = npc.GetMovementStateInfo().GetPosition3D();
                    float powDist = Geometry.DistanceSquare(srcPos, targetPos); //npc与目标距离
                    float dist    = (float)npc.GetActualProperty().AttackRange; //攻击范围
                    //float distView = (float)npc.ViewRange;                      //视野范围
                    if (powDist < dist * dist)
                    {
                        //在攻击范围内
                        float dir = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z));
                        npc.GetMovementStateInfo().IsMoving = false;
                        npc.GetMovementStateInfo().SetFaceDir(dir);
                        npc.GetMovementStateInfo().SetMoveDir(dir);
                        if (npc.CanShoot())
                        {
                            aiCmdDispatcher.NpcFace(npc, this);
                        }
                    }
                    else
                    {
                        //如果原目标已经超出了攻击范围,防御塔应当重新进行探测,而不是跳转到Idle状态
                        CharacterInfo newTarget = GetNewTarget(npc);
                        if (null != newTarget)
                        {
                            npc.GetMovementStateInfo().IsMoving = false;
                            info.Time   = 0;
                            info.Target = newTarget.GetId();
                        }
                        else
                        {
                            toIdle = true;
                        }
                    }
                }
                else
                {
                    //如果原目标死亡或不可攻击,防御塔应当首先重新进行探测,而不是跳转到Idle状态
                    //若找到新目标,则进行攻击
                    //若没有心目标。则进入Idle状态
                    CharacterInfo newTarget = GetNewTarget(npc);
                    if (null != newTarget)
                    {
                        npc.GetMovementStateInfo().IsMoving = false;
                        info.Time   = 0;
                        info.Target = newTarget.GetId();
                    }
                    else
                    {
                        toIdle = true;
                    }
                }
                if (toIdle)
                {
                    info.Time = 0;
                    npc.GetMovementStateInfo().IsMoving = false;
                    ChangeToState(npc, (int)AiStateId.Idle);
                }
            }
        }