Ejemplo n.º 1
0
        private AiData_Npc_Bluelf GetAiData(NpcInfo npc)
        {
            AiData_Npc_Bluelf data = npc.GetAiStateInfo().AiDatas.GetData <AiData_Npc_Bluelf>();

            if (null == data)
            {
                data = new AiData_Npc_Bluelf();
                npc.GetAiStateInfo().AiDatas.AddData(data);
            }
            return(data);
        }
Ejemplo n.º 2
0
        private void PursuitHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (!CanAiControl(npc))
            {
                npc.GetMovementStateInfo().IsMoving = false;
                return;
            }
            NpcAiStateInfo    info = npc.GetAiStateInfo();
            AiData_Npc_Bluelf 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();
                    Vector3 srcPos        = npc.GetMovementStateInfo().GetPosition3D();
                    float   powDist       = Geometry.DistanceSquare(srcPos, targetPos);
                    float   powDistToHome = Geometry.DistanceSquare(srcPos, info.HomePos);
                    // 遇敌是播放特效, 逗留两秒。
                    if (data.WaitTime <= m_ResponseTime)
                    {
                        if (!data.HasMeetEnemy)
                        {
                            NotifyNpcMeetEnemy(npc, Animation_Type.AT_Attack);
                            data.HasMeetEnemy = true;
                        }
                        TrySeeTarget(npc, target);
                        data.WaitTime += deltaTime;
                        return;
                    }
                    // 走向目标1.5秒
                    if (data.MeetEnemyWalkTime < m_MeetWalkMaxTime)
                    {
                        data.MeetEnemyWalkTime += deltaTime;
                        NotifyNpcWalk(npc);
                        info.Time += deltaTime;
                        if (info.Time > m_IntervalTime)
                        {
                            info.Time = 0;
                            AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                        }
                        return;
                    }

                    // 大于攻击距离 跑向目标
                    if (powDist > m_AttackRange * m_AttackRange && 0 == data.CurAiAction)
                    {
                        NotifyNpcRun(npc);
                        info.Time += deltaTime;
                        if (info.Time > m_IntervalTime)
                        {
                            info.Time = 0;
                            AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                        }
                    }
                    else
                    {
                        //小于攻击距离
                        if (data.CurAiAction == (int)AiAction.NONE)
                        {
                            npc.GetMovementStateInfo().IsMoving = false;
                            NotifyNpcMove(npc);
                            data.CurAiAction = (int)GetNextAction();
                        }
                        switch (data.CurAiAction)
                        {
                        case (int)AiAction.SKILL:
                            int skillId = GetCanCastSkillId(npc, (float)Math.Sqrt(powDist));
                            if (-1 == skillId)
                            {
                                info.Time += deltaTime;
                                if (info.Time > m_IntervalTime)
                                {
                                    info.Time = 0;
                                    NotifyNpcRun(npc);
                                    AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                                }
                            }
                            else
                            {
                                npc.GetMovementStateInfo().IsMoving = false;
                                NotifyNpcMove(npc);
                                if (TryCastSkill(npc, skillId, target))
                                {
                                    data.CurAiAction = 0;
                                }
                            }
                            break;

                        case (int)AiAction.STAND:
                            data.ChaseStandTime += deltaTime;
                            TrySeeTarget(npc, target);
                            if (data.ChaseStandTime > m_ChaseWalkMaxTime)
                            {
                                data.ChaseStandTime = 0;
                                data.CurAiAction    = 0;
                            }
                            break;

                        case (int)AiAction.TAUNT:
                            npc.GetMovementStateInfo().IsMoving = false;
                            NotifyNpcMove(npc);
                            npc.IsTaunt     = true;
                            data.TauntTime += deltaTime;
                            //TrySeeTarget(npc, target);
                            if (data.TauntTime > m_TauntTime)
                            {
                                npc.IsTaunt      = false;
                                data.TauntTime   = 0;
                                data.CurAiAction = 0;
                            }
                            break;

                        case (int)AiAction.WALK:
                            data.ChaseWalkTime += deltaTime;
                            info.Time          += deltaTime;
                            if (info.Time > m_IntervalTime)
                            {
                                info.Time = 0;
                                NotifyNpcWalk(npc);
                                AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                            }
                            if (data.ChaseWalkTime > m_ChaseWalkMaxTime)
                            {
                                data.ChaseWalkTime = 0;
                                data.CurAiAction   = 0;
                            }
                            break;
                        }
                    }
                }
                else
                {
                    NotifyNpcTargetChange(npc);
                    npc.GetMovementStateInfo().IsMoving = false;
                    NotifyNpcMove(npc);
                    info.Time = 0;
                    ChangeToState(npc, (int)AiStateId.Idle);
                }
            }
        }
        private void EscapeHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (!CanAiControl(npc))
            {
                npc.GetMovementStateInfo().IsMoving = false;
                return;
            }
            NpcAiStateInfo    info = npc.GetAiStateInfo();
            AiData_Npc_Bluelf data = GetAiData(npc);

            if (null != data)
            {
                data.EscapeTime += deltaTime;
                CharacterInfo target = AiLogicUtility.GetLivingCharacterInfoHelper(npc, info.Target);
                if (null != target)
                {
                    Vector3 targetPos = target.GetMovementStateInfo().GetPosition3D();
                    Vector3 srcPos    = npc.GetMovementStateInfo().GetPosition3D();
                    float   powDist   = Geometry.DistanceSquare(srcPos, targetPos);
                    if (powDist < m_SafeRange * m_SafeRange)
                    {
                        Vector3 escapePos = Vector3.Zero;
                        if (AiLogicUtility.GetEscapeTargetPos(npc, target, 3.0f, ref escapePos))
                        {
                            info.Time += deltaTime;
                            if (info.Time > m_IntervalTime)
                            {
                                NotifyNpcRun(npc);
                                info.Time = 0;
                                AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, escapePos, m_IntervalTime, true, this);
                            }
                        }
                        else
                        {
                            LogSystem.Debug("Can't find WalkAble place");
                        }
                    }
                    else
                    {
                        TryCastSkill(npc, GetCanCastSkillId(npc, (float)Math.Sqrt(powDist)), target);
                        npc.GetMovementStateInfo().IsMoving = false;
                        NotifyNpcMove(npc);
                        info.Time       = 0;
                        data.EscapeTime = 0;
                        ChangeToState(npc, (int)AiStateId.Pursuit);
                    }
                }
                else
                {
                    NotifyNpcTargetChange(npc);
                    npc.GetMovementStateInfo().IsMoving = false;
                    NotifyNpcMove(npc);
                    info.Time = 0;
                    ChangeToState(npc, (int)AiStateId.Idle);
                }
                if (data.EscapeTime > m_MaxEscapeTime)
                {
                    data.EscapeTime = 0;
                    npc.GetMovementStateInfo().IsMoving = false;
                    NotifyNpcMove(npc);
                    info.Time = 0;
                    ChangeToState(npc, (int)AiStateId.Pursuit);
                }
            }
        }
        private void PursuitHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (!CanAiControl(npc))
            {
                npc.GetMovementStateInfo().IsMoving = false;
                return;
            }
            NpcAiStateInfo    info = npc.GetAiStateInfo();
            AiData_Npc_Bluelf 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();
                    Vector3 srcPos        = npc.GetMovementStateInfo().GetPosition3D();
                    float   powDist       = Geometry.DistanceSquare(srcPos, targetPos);
                    float   powDistToHome = Geometry.DistanceSquare(srcPos, info.HomePos);
                    // 遇敌是播放特效, 逗留两秒。
                    if (data.WaitTime <= npc.MeetEnemyStayTime)
                    {
                        if (!data.HasMeetEnemy)
                        {
                            NotifyNpcMeetEnemy(npc, Animation_Type.AT_Attack);
                            data.HasMeetEnemy = true;
                        }
                        TrySeeTarget(npc, target);
                        data.WaitTime += deltaTime;
                        return;
                    }
                    // 走向目标1.5秒
                    if (data.MeetEnemyWalkTime < npc.MeetEnemyWalkTime)
                    {
                        data.MeetEnemyWalkTime += deltaTime;
                        NotifyNpcWalk(npc);
                        info.Time += deltaTime;
                        if (info.Time > m_IntervalTime)
                        {
                            info.Time = 0;
                            if (!npc.UnityPathFinding)
                            {
                                AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                            }
                            else
                            {
                                if (!npc.PathFindingFinished)
                                {
                                    GfxSystem.NpcCommonRangePathToTarget(npc, targetPos);
                                    ChangeToState(npc, (int)AiStateId.PathFinding);
                                }
                                else
                                {
                                    npc.PathFindingFinished = false;
                                    AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                                }
                            }
                        }
                        return;
                    }

                    // 大于攻击距离 跑向目标
                    if (powDist > npc.ViewRange * npc.ViewRange && 0 == data.CurAiAction)
                    {
                        info.Time += deltaTime;
                        if (info.Time > m_IntervalTime)
                        {
                            NotifyNpcRun(npc);
                            info.Time = 0;
                            if (!npc.UnityPathFinding)
                            {
                                AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                            }
                            else
                            {
                                if (!npc.PathFindingFinished)
                                {
                                    GfxSystem.NpcCommonRangePathToTarget(npc, targetPos);
                                    ChangeToState(npc, (int)AiStateId.PathFinding);
                                }
                                else
                                {
                                    npc.PathFindingFinished = false;
                                    AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                                }
                            }
                        }
                    }
                    else /* if(powDist > m_EscapeRange * m_EscapeRange) */
                    {
                        //小于攻击距离
                        if (data.CurAiAction == (int)AiAction.NONE)
                        {
                            npc.GetMovementStateInfo().IsMoving = false;
                            NotifyNpcMove(npc);
                            data.CurAiAction = (int)GetNextAction();
                        }
                        switch (data.CurAiAction)
                        {
                        case (int)AiAction.SKILL:
                            int skillId = GetCanCastSkillId(npc, (float)Math.Sqrt(powDist));
                            if (-1 == skillId)
                            {
                                info.Time += deltaTime;
                                if (info.Time > m_IntervalTime)
                                {
                                    info.Time = 0;
                                    if (AiLogicUtility.IsTooCloseToCastSkill(npc, target))
                                    {
                                        Vector3 escapePos = Vector3.Zero;
                                        if (AiLogicUtility.GetEscapeTargetPos(npc, target, 3.0f, ref escapePos))
                                        {
                                            NotifyNpcRun(npc);
                                            if (!npc.UnityPathFinding)
                                            {
                                                AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                                            }
                                            else
                                            {
                                                if (!npc.PathFindingFinished)
                                                {
                                                    GfxSystem.NpcCommonRangePathToTarget(npc, targetPos);
                                                    ChangeToState(npc, (int)AiStateId.PathFinding);
                                                }
                                                else
                                                {
                                                    npc.PathFindingFinished = false;
                                                    AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        NotifyNpcRun(npc);
                                        if (!npc.UnityPathFinding)
                                        {
                                            AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                                        }
                                        else
                                        {
                                            if (!npc.PathFindingFinished)
                                            {
                                                GfxSystem.NpcCommonRangePathToTarget(npc, targetPos);
                                                ChangeToState(npc, (int)AiStateId.PathFinding);
                                            }
                                            else
                                            {
                                                npc.PathFindingFinished = false;
                                                AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                                            }
                                        }
                                    }
                                }
                            }
                            else
                            {
                                npc.GetMovementStateInfo().IsMoving = false;
                                NotifyNpcMove(npc);
                                if (TryCastSkill(npc, skillId, target))
                                {
                                    data.CurAiAction = 0;
                                }
                            }
                            break;

                        case (int)AiAction.STAND:
                            data.ChaseStandTime += deltaTime;
                            TrySeeTarget(npc, target);
                            if (data.ChaseStandTime > m_ChaseStandMaxTime)
                            {
                                data.ChaseStandTime = 0;
                                data.CurAiAction    = 0;
                            }
                            break;

                        case (int)AiAction.TAUNT:
                            npc.GetMovementStateInfo().IsMoving = false;
                            NotifyNpcMove(npc);
                            npc.IsTaunt     = true;
                            data.TauntTime += deltaTime;
                            TrySeeTarget(npc, target);
                            if (data.TauntTime > m_TauntTime)
                            {
                                npc.IsTaunt      = false;
                                data.TauntTime   = 0;
                                data.CurAiAction = 0;
                            }
                            break;

                        case (int)AiAction.WALK:
                            data.ChaseWalkTime += deltaTime;
                            info.Time          += deltaTime;
                            if (info.Time > m_IntervalTime)
                            {
                                info.Time = 0;
                                NotifyNpcWalk(npc);
                                if (!npc.UnityPathFinding)
                                {
                                    AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                                }
                                else
                                {
                                    if (!npc.PathFindingFinished)
                                    {
                                        GfxSystem.NpcCommonRangePathToTarget(npc, targetPos);
                                        ChangeToState(npc, (int)AiStateId.PathFinding);
                                    }
                                    else
                                    {
                                        npc.PathFindingFinished = false;
                                        AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                                    }
                                }
                            }
                            if (data.ChaseWalkTime > m_ChaseWalkMaxTime)
                            {
                                data.ChaseWalkTime = 0;
                                data.CurAiAction   = 0;
                            }
                            break;
                        }
                    }

                    long curTime = TimeUtility.GetServerMilliseconds();
                    if (powDist < m_EscapeRange * m_EscapeRange && (curTime - data.LastEscapeTime > m_EscapeCoolDown || m_EscapeCoolDown == 0))
                    {
                        npc.GetMovementStateInfo().IsMoving = false;
                        data.LastEscapeTime = curTime;
                        data.ChaseStandTime = 0;
                        data.ChaseWalkTime  = 0;
                        data.TauntTime      = 0;
                        npc.IsTaunt         = false;
                        data.CurAiAction    = 0;
                        NotifyNpcMove(npc);
                        info.Time = 0;
                        ChangeToState(npc, (int)AiStateId.Escape);
                    }
                }
                else
                {
                    NotifyNpcTargetChange(npc);
                    npc.GetMovementStateInfo().IsMoving = false;
                    NotifyNpcMove(npc);
                    info.Time = 0;
                    ChangeToState(npc, (int)AiStateId.Idle);
                }
            }
        }
        private void PursuitHandler(NpcInfo npc, AiCommandDispatcher aiCmdDispatcher, long deltaTime)
        {
            if (npc.IsDead())
            {
                npc.GetMovementStateInfo().IsMoving = false;
                NotifyNpcMove(npc);
                return;
            }
            if (npc.GetSkillStateInfo().IsSkillActivated())
            {
                return;
            }
            NpcAiStateInfo    info = npc.GetAiStateInfo();
            AiData_Npc_Bluelf data = GetAiData(npc);

            if (null != data)
            {
                // 写黑板
                if (0 != info.HateTarget)
                {
                    GetBlackBorad(npc).TargetId = info.HateTarget;
                }
                if (npc.IsUnderControl())
                {
                    return;
                }
                // 读黑板
                int blackBoardTarget = GetBlackBorad(npc).TargetId;
                if (0 != blackBoardTarget)
                {
                    info.Target = blackBoardTarget;
                    NotifyNpcTargetChange(npc);
                }
                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();
                    Vector3 srcPos        = npc.GetMovementStateInfo().GetPosition3D();
                    float   powDist       = Geometry.DistanceSquare(srcPos, targetPos);
                    float   powDistToHome = Geometry.DistanceSquare(srcPos, info.HomePos);
                    // 遇敌是播放特效 逗留两秒。
                    if (data.WaitTime <= m_ResponseTime)
                    {
                        if (!data.HasMeetEnemy)
                        {
                            NotifyNpcMeetEnemy(npc, Animation_Type.AT_Attack);
                            data.HasMeetEnemy = true;
                        }
                        TrySeeTarget(npc, target);
                        data.WaitTime += deltaTime;
                        return;
                    }

                    // 追逐目标
                    if (powDist > m_AttackRange * m_AttackRange)
                    {
                        npc.GetActualProperty().SetMoveSpeed(Operate_Type.OT_Absolute, AiLogicUtility.GetRunSpeed(npc));
                        npc.GetMovementStateInfo().MovementMode = MovementMode.HighSpeed;
                        info.Time += deltaTime;
                        if (info.Time > m_IntervalTime)
                        {
                            info.Time = 0;
                            AiLogicUtility.PathToTargetWithoutObstacle(npc, data.FoundPath, targetPos, m_IntervalTime, true, this);
                        }
                    }
                    else
                    {
                        //小于攻击距离, 可以攻击
                        npc.GetMovementStateInfo().IsMoving = false;
                        if (0 != blackBoardTarget)
                        {
                            int skillId = GetCanCastSkillId(npc, (float)Math.Sqrt(powDist));
                            TryCastSkill(npc, skillId, target);
                        }
                        else
                        {
                            // 不敢攻击
                            TrySeeTarget(npc, target);
                        }
                    }
                }
                else
                {
                    NotifyNpcTargetChange(npc);
                    npc.GetMovementStateInfo().IsMoving = false;
                    NotifyNpcMove(npc);
                    info.Time = 0;
                    ChangeToState(npc, (int)AiStateId.Idle);
                }
            }
        }