예제 #1
0
        public void NpcFace(NpcInfo npc, AbstractNpcStateLogic logic)
        {
            NpcFaceCommand cmd = m_NpcFaceCommandPool.Alloc();

            if (null != cmd)
            {
                cmd.SetContext(npc, logic);
                cmd.Init();
                npc.GetAiStateInfo().CommandQueue.Enqueue(cmd);
            }
        }
예제 #2
0
        public void NpcSkill(NpcInfo npc, AbstractNpcStateLogic logic, int skillId, int targetId, ScriptRuntime.Vector3 targetPos, float targetAngle)
        {
            NpcSkillCommand cmd = m_NpcSkillCommandPool.Alloc();

            if (null != cmd)
            {
                cmd.SetContext(npc, logic);
                cmd.Init(skillId, targetId, targetPos, targetAngle);
                npc.GetAiStateInfo().CommandQueue.Enqueue(cmd);
            }
        }
예제 #3
0
        internal NpcInfo SummonNpc(int id, int owner_id, int owner_skillid, int npc_type_id, string modelPrefab, int skillid, int ailogicid, bool followsummonerdead,
                                   float x, float y, float z, string aiparamstr)
        {
            CharacterInfo charObj = SceneContext.GetCharacterInfoById(owner_id);

            if (charObj == null)
            {
                return(null);
            }
            NpcInfo   npc            = null;
            SkillInfo ownerSkillInfo = charObj.GetSkillStateInfo().GetSkillInfoById(owner_skillid);

            if (null != ownerSkillInfo)
            {
                if (null != ownerSkillInfo.m_EnableSummonNpcs && ownerSkillInfo.m_EnableSummonNpcs.Contains(npc_type_id))
                {
                    //ownerSkillInfo.m_EnableSummonNpcs.Remove(npc_type_id);

                    Data_Unit data = new Data_Unit();
                    data.m_Id       = -1;
                    data.m_LinkId   = npc_type_id;
                    data.m_CampId   = charObj.GetCampId();
                    data.m_IsEnable = true;
                    data.m_Pos      = new Vector3(x, y, z);
                    data.m_RotAngle = 0;
                    data.m_AiLogic  = ailogicid;
                    if (!string.IsNullOrEmpty(aiparamstr))
                    {
                        string[] strarry = aiparamstr.Split(new char[] { ',' }, 8);
                        int      i       = 0;
                        foreach (string str in strarry)
                        {
                            data.m_AiParam[i++] = str;
                        }
                    }
                    npc = NpcManager.AddNpc(data);
                    if (!string.IsNullOrEmpty(modelPrefab))
                    {
                        npc.SetModel(modelPrefab);
                    }
                    npc.FollowSummonerDead = followsummonerdead;
                    SkillInfo skillinfo = new SkillInfo(skillid);
                    npc.GetSkillStateInfo().AddSkill(skillinfo);
                    npc.GetMovementStateInfo().SetPosition(data.m_Pos);
                    npc.SummonOwnerId = charObj.GetId();
                    charObj.GetSkillStateInfo().AddSummonObject(npc);
                    AbstractNpcStateLogic.OnNpcSkill(npc, skillid);
                }
            }
            return(npc);
        }
예제 #4
0
 public void SetContext(NpcInfo npc, AbstractNpcStateLogic logic)
 {
     m_Npc   = npc;
     m_Logic = logic;
 }
예제 #5
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;
                    }
                }
            }
        }
예제 #6
0
        public static void PathToTargetWithoutObstacle(NpcInfo npc, AiPathData data, Vector3 pathTargetPos, long deltaTime, bool faceIsMoveFir, AbstractNpcStateLogic logic)
        {
            NpcAiStateInfo info   = npc.GetAiStateInfo();
            Vector3        srcPos = npc.GetMovementStateInfo().GetPosition3D();

            if (null != data)
            {
                data.Clear();
                data.UpdateTime += deltaTime;
                Vector3        targetPos = pathTargetPos;
                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);
                }
                else
                {
                    npc.GetMovementStateInfo().IsMoving = false;
                    logic.NotifyNpcMove(npc);
                    data.IsUsingAvoidanceVelocity = false;
                }
                bool havePathPoint = data.HavePathPoint;
                if (havePathPoint)//沿路点列表移动的逻辑
                {
                    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);
                        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 (data.UpdateTime > 500)
                        {
                            data.UpdateTime = 0;
                            float newAngle = Geometry.GetYAngle(new Vector2(0, 0), new Vector2(newVelocity.X, newVelocity.Z));
                            npc.GetMovementStateInfo().SetMoveDir(newAngle);
                            if (faceIsMoveFir)
                            {
                                logic.NotifyNpcFace(npc, newAngle);
                            }
                            newVelocity.Normalize();
                            npc.GetMovementStateInfo().TargetPosition = srcPos + newVelocity * Geometry.Distance(srcPos, targetPos);
                            npc.GetMovementStateInfo().IsMoving       = true;
                            logic.NotifyNpcMove(npc);
                        }
                        else
                        {
                            data.UpdateTime += deltaTime;
                        }
                    }
                    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)
                            {
                                logic.NotifyNpcFace(npc, angle);
                            }
                            npc.GetMovementStateInfo().IsMoving = true;
                            logic.NotifyNpcMove(npc);
                            data.IsUsingAvoidanceVelocity = false;
                        }
                        else
                        {
                            npc.GetMovementStateInfo().IsMoving = false;
                            data.Clear();
                        }
                    }
                }
            }
        }
예제 #7
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);
                    }
                }
            }
        }