예제 #1
0
        void AimTarget(IWeapon _weapon)
        {
            if (_weapon == null || _weapon.Equals(null))
            {
                return;
            }


            m_Index = SwitchAttackIndex(_weapon);
            if (m_Index < 0 || m_Index >= _weapon.GetAttackMode().Length)
            {
                return;
            }

            m_Mode = _weapon.GetAttackMode()[m_Index];
            if (m_Mode == null)
            {
                return;
            }

            IAimWeapon aimWeapon = _weapon as IAimWeapon;

            if (aimWeapon != null)
            {
                if (m_Mode.type == AttackType.Ranged)
                {
                    aimWeapon.SetAimState(true);
                    aimWeapon.SetTarget(selectattackEnemy.CenterBone);
                }
                else
                {
                    aimWeapon.SetAimState(false);
                    aimWeapon.SetTarget(null);
                }
            }
        }
예제 #2
0
        BehaveResult Tick(Tree sender)
        {
            if (Enemy.IsNullOrInvalid(selectattackEnemy) || !entity.target.ContainEnemy(selectattackEnemy))
            {
                return(BehaveResult.Failure);
            }

            if (Enemy.IsNullOrInvalid(attackEnemy))
            {
                return(BehaveResult.Failure);
            }

            entity.NpcCmpt.EqSelect.ClearSelect();
            entity.NpcCmpt.EqSelect.ClearAtkSelects();
            if (entity.NpcCmpt.EqSelect.SetSelectObjsAtk(entity, EeqSelect.combat))
            {
                entity.NpcCmpt.EqSelect.GetBetterAtkObj(entity, selectattackEnemy);
            }

            if (entity.NpcCmpt.EqSelect.BetterAtkObj != null && Weapon != null && !Weapon.Equals(null) && entity.NpcCmpt.EqSelect.BetterAtkObj != Weapon.ItemObj)
            {
                return(BehaveResult.Failure);
            }

            if (!IsNpcBase && !SelectItem.MatchEnemyAttack(entity, selectattackEnemy.entityTarget))           //entity.HPPercent < 0.3f && m_Mode.type == AttackType.Melee)
            {
                return(BehaveResult.Failure);
            }


            ////是否被挡住
            bool _IsInSpSence = (Pathea.PeGameMgr.IsAdventure && RandomDungenMgr.Instance != null && RandomDungenMgrData.dungeonBaseData != null) ||
                                (Pathea.PeGameMgr.IsStory && Pathea.PeGameMgr.IsSingle && Pathea.SingleGameStory.curType != Pathea.SingleGameStory.StoryScene.MainLand) ||
                                (Pathea.PeGameMgr.IsStory && Pathea.PeGameMgr.IsTutorial && Pathea.SingleGameStory.curType != Pathea.SingleGameStory.StoryScene.MainLand) ||
                                (Pathea.PeGameMgr.IsStory && Pathea.PeGameMgr.IsMulti && PlayerNetwork.mainPlayer != null && PlayerNetwork.mainPlayer._curSceneId != (int)Pathea.SingleGameStory.StoryScene.MainLand);
            bool _isBlock = !_IsInSpSence && PEUtil.IsBlocked(entity, selectattackEnemy.entityTarget);

            if (_isBlock)
            {
                Vector3 movePos         = GetMovePos(selectattackEnemy);
                Vector3 v3              = position + transform.forward;
                bool    _IsUnderBlock   = PEUtil.IsUnderBlock(entity);
                bool    _IsForwardBlock = PEUtil.IsForwardBlock(entity, existent.forward, 2.0f);
                if (_IsUnderBlock)
                {
                    if (_IsForwardBlock || _isBlock)
                    {
                        if (movePos.y >= v3.y)
                        {
                            v3.y = movePos.y;
                        }
                        SetPosition(v3);
                    }
                    else
                    {
                        MoveDirection(movePos - position, SpeedState.Run);
                    }
                }
                else
                {
                    if (Stucking())
                    {
                        if (movePos.y >= v3.y)
                        {
                            v3.y = movePos.y;
                        }
                        SetPosition(v3);
                    }
                    MoveToPosition(movePos, SpeedState.Run);
                }
                return(BehaveResult.Running);
            }

            if (Weapon == null || Weapon.Equals(null))
            {
                bool canSwitchWeapon = true;

                if (entity.motionMgr != null && entity.motionMgr.IsActionRunning(PEActionType.SwordAttack))
                {
                    canSwitchWeapon = false;
                }

                if (entity.motionMgr != null && entity.motionMgr.IsActionRunning(PEActionType.TwoHandSwordAttack))
                {
                    canSwitchWeapon = false;
                }

                if (entity.motionEquipment.IsSwitchWeapon())
                {
                    canSwitchWeapon = false;
                }

                if (entity.isRagdoll)
                {
                    canSwitchWeapon = false;
                }

                if (entity.netCmpt != null && !entity.netCmpt.IsController)
                {
                    canSwitchWeapon = false;
                }

                if (canSwitchWeapon)
                {
                    IWeapon tempweapon = SwitchWeapon(selectattackEnemy);
                    if (tempweapon != null && !tempweapon.Equals(null))
                    {
                        if (entity.motionEquipment.Weapon == null || entity.motionEquipment.Weapon.Equals(null))
                        {
                            //Vector3 forward = Vector3.ProjectOnPlane(entity.peTrans.trans.forward, Vector3.up);
                            //Vector3 direction = Vector3.ProjectOnPlane(selectattackEnemy.Direction, Vector3.up);
                            //float   angle = Vector3.Angle(forward, direction);
                            //bool    canHold = (entity.Race != ERace.Puja && entity.Race != ERace.Paja) || angle < 45f;

                            if (!tempweapon.HoldReady)
                            {
                                StopMove();
                                tempweapon.HoldWeapon(true);
                                AimTarget(Weapon);
                                return(BehaveResult.Running);
                            }
                        }
                        else
                        {
                            if (!entity.motionEquipment.Weapon.Equals(tempweapon))
                            {
                                StopMove();
                                entity.motionEquipment.SwitchHoldWeapon(entity.motionEquipment.Weapon, tempweapon);
                                AimTarget(Weapon);
                                return(BehaveResult.Running);
                            }
                        }
                    }
                }
                return(BehaveResult.Running);
            }
            else
            {
                m_Index = SwitchAttackIndex(Weapon);
                if (m_Index < 0 || m_Index >= Weapon.GetAttackMode().Length)
                {
                    return(BehaveResult.Failure);
                }

                m_Mode = Weapon.GetAttackMode()[m_Index];
                if (Time.time - m_LastAttackTime <= m_Mode.frequency)
                {
                    return(BehaveResult.Failure);
                }

                if (Weapon == null || Weapon.Equals(null) || m_Mode == null)
                {
                    return(BehaveResult.Failure);
                }

                //只能使用拳套,则把装备栏里不能使用的装备收回去
                if (Weapon is PEGloves && entity.motionEquipment.ActiveableEquipment != null)
                {
                    SelectItem.TakeOffEquip(entity);
                }

                IAimWeapon aimWeapon = Weapon as IAimWeapon;
                if (aimWeapon != null)
                {
                    if (m_Mode.type == AttackType.Ranged)
                    {
                        aimWeapon.SetAimState(true);
                        aimWeapon.SetTarget(selectattackEnemy.CenterBone);
                    }
                    else
                    {
                        aimWeapon.SetAimState(false);
                        aimWeapon.SetTarget(null);
                    }
                }

                if (selectattackEnemy.entityTarget.target != null)
                {
                    int n = selectattackEnemy.entityTarget.monsterProtoDb != null && selectattackEnemy.entityTarget.monsterProtoDb.AtkDb != null ? selectattackEnemy.entityTarget.monsterProtoDb.AtkDb.mNumber : 3;
                    if (m_Mode.type == AttackType.Melee)
                    {
                        selectattackEnemy.entityTarget.target.AddMelee(entity, n);
                    }
                    else
                    {
                        selectattackEnemy.entityTarget.target.RemoveMelee(entity);
                    }
                }

                if (selectattackEnemy.GroupAttack == EAttackGroup.Threat)
                {
                    return(BehaveResult.Failure);
                }

                float   minRange      = m_Mode.minRange;
                float   maxRange      = m_Mode.maxRange;
                float   sqrDistanceXZ = selectattackEnemy.SqrDistanceLogic;               //PETools.PEUtil.Magnitude(position,selectattackEnemy.position);
                Vector3 direction     = selectattackEnemy.Direction;

                //是否被挡住
                bool isBlock = !m_Mode.ignoreTerrain && (PEUtil.IsBlocked(entity, selectattackEnemy.entityTarget) || PEUtil.IsNpcsuperposition(entity, selectattackEnemy));
                //距离是否可以攻击
                bool isRange = sqrDistanceXZ <= maxRange * maxRange && sqrDistanceXZ >= minRange * minRange;
                //角度是否可以攻击
                bool isAngle = PEUtil.IsScopeAngle(direction, transform.forward, Vector3.up, m_Mode.minAngle, m_Mode.maxAngle);
                //是否可以攻击
                bool isAttack = isRange && isAngle && !isBlock;
                //是否瞄准
                bool isAimed = m_Mode.type == AttackType.Melee || aimWeapon == null || aimWeapon.Aimed;
                //是否需要调整站位
                bool ischangeStand = !isBlock && m_Mode.type == AttackType.Ranged && entity.target.beSkillTarget;
                //寻找可攻击位置
                m_Local = GetLocalPos(selectattackEnemy, m_Mode);
                m_Local = Vector3.ProjectOnPlane(m_Local, Vector3.up);
                //开始后退的距离
                float retreatRange = minRange;
                if (m_Mode.type == AttackType.Ranged)
                {
                    retreatRange += Mathf.Lerp(minRange, maxRange, 0.2f);
                }

                //目标发动技能攻击(移动)
                bool isSkillAttacking = entity.target.beSkillTarget;
                if (Time.time - m_LastRetreatTime > 3.0f)
                {
                    m_RetreatLocal    = Vector3.zero;
                    m_LastRetreatTime = Time.time;

                    m_ChangeLocal    = Vector3.zero;
                    m_LastChangeTime = Time.time;
                }


                //攻击移动
                if (sqrDistanceXZ > maxRange * maxRange || isBlock)
                {
                    Vector3 movePos = GetMovePos(selectattackEnemy);
                    if (isBlock)
                    {
                        Vector3 v3 = position + transform.forward;
                        if (Stucking())
                        {
                            if (movePos.y >= v3.y)
                            {
                                v3.y = movePos.y;
                            }
                            SetPosition(v3);
                        }
                        MoveToPosition(movePos, SpeedState.Run);
                    }
                    else
                    {
                        Vector3    dir0  = movePos - position;
                        Vector3    dir   = isSkillAttacking ? Vector3.Lerp(Vector3.Cross(dir0, Vector3.up), dir0, Time.time) : dir0;
                        SpeedState speed = CalculateChaseSpeed();

                        MoveDirection(dir, speed);
                    }
                }
                else if (sqrDistanceXZ < retreatRange * retreatRange)
                {
                    if (Time.time - m_LastRetreatTime < 2.0f)
                    {
                        if (m_RetreatLocal == Vector3.zero)
                        {
                            m_RetreatLocal = GetRetreatPos(selectattackEnemy.position, transform, minRange, maxRange);
                        }

                        FaceDirection(direction);
                        MoveToPosition(m_RetreatLocal, SpeedState.Run);
                    }
                    else
                    {
                        StopMove();
                    }
                }
                else if (ischangeStand)
                {
                    if (Time.time - m_LastChangeTime < 2.0f)
                    {
                        if (m_ChangeLocal == Vector3.zero)
                        {
                            m_ChangeLocal = GetRetreatPos(selectattackEnemy.position, transform, minRange, maxRange);
                        }

                        FaceDirection(direction);
                        MoveToPosition(m_ChangeLocal, SpeedState.Run);
                    }
                }
                else
                {
                    StopMove();
                }

                //攻击旋转
                if (!isBlock)
                {
                    if (!isAngle || !isAimed)
                    {
                        FaceDirection(direction);
                    }
                    else
                    {
                        FaceDirection(Vector3.zero);
                    }
                }

                if (selectattackEnemy.entityTarget.target != null)
                {
                    Enemy TargetEnemy = selectattackEnemy.entityTarget.target.GetAttackEnemy();
                    if (!Enemy.IsNullOrInvalid(TargetEnemy) && selectattackEnemy.entityTarget.IsAttacking &&
                        TargetEnemy.entityTarget == entity && IsInEnemyFoward(selectattackEnemy, entity) &&
                        Time.time - m_StartDefenceTime >= 3.0f)
                    {
                        m_StartDefenceTime = Time.time;
                        bool canShield = CanDoAction(PEActionType.HoldShield);
                        bool canStep   = CanStep();
                        if (canShield && canStep)
                        {
                            if (Random.value > 0.5f)
                            {
                                DoStep();
                            }
                            else
                            {
                                DoSheid();
                            }

                            m_Attacked        = false;
                            m_StartAttackTime = Time.time;
                            return(BehaveResult.Running);
                        }
                        else if (canShield)
                        {
                            DoSheid();
                            m_Attacked        = false;
                            m_StartAttackTime = Time.time;
                            return(BehaveResult.Running);
                        }
                        else if (canStep)
                        {
                            DoStep();
                            m_Attacked        = false;
                            m_StartAttackTime = Time.time;
                            return(BehaveResult.Running);
                        }
                    }
                }

                if (!m_Attacked)
                {
                    //是否需要瞄准
                    if (isAttack && isAimed)
                    {
                        WeaponAttack(Weapon, selectattackEnemy, m_Index);
                        //Weapon.Attack(m_Index);
                        m_Attacked = true;
                    }
                    return(BehaveResult.Running);
                }
                else
                {
                    //range need CD
                    bool _IsCD = m_Mode != null && m_Mode.type == AttackType.Ranged ? Weapon.IsInCD() : false;
                    //是否连击
                    if (isAttack && Weapon != null && !Weapon.Equals(null) && !_IsCD)
                    {
                        m_StartAttackTime = Time.time;
                        //Weapon.Attack(m_Index);
                        WeaponAttack(Weapon, selectattackEnemy, m_Index);
                    }

                    return(BehaveResult.Running);
                }
            }
        }