Esempio n. 1
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);
                }
            }
        }
        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;
                }
            }
        }