コード例 #1
0
ファイル: BNpcBase.cs プロジェクト: BenjaBobs/Hubris
        /// <summary>
        /// Process the entities in the TrackDict, finds closest and removes ents that are beyond MAX_DIST or dead
        /// </summary>
        public void ProcessTrackDict(Npc a, BhvTree b)
        {
            if (a.TrackDict != null && a.TrackDict.Count > 0)
            {
                float      closestEntDistSqr = 0.0f;
                LiveEntity closestEnt        = null;
                bool       fresh             = true;

                foreach (ulong id in a.TrackDict.Keys)
                {
                    LiveEntity ent;
                    a.TrackDict.TryGetValue(id, out ent);

                    // If the entity dies and is cleaned up before the trackBook is processed, it will be null
                    if (ent == null)
                    {
                        a.RemoveList.Add(id);
                        continue;
                    }

                    // Check if the entity is invisible
                    if (ent.Stats.Invisible)
                    {
                        continue;
                    }

                    // Check if the entity is dead
                    if (ent.Stats.IsDead)
                    {
                        // If the entity is dead and the same type as this one, set behavior to aggro or hunt or something
                        continue;
                    }

                    if (ent is Npc npc)
                    {
                        // Check if we want to make a squad with other entities of the same type
                        //
                        //

                        // If we're prey
                        if (!a.Params.Predator)
                        {
                            // Prey should ignore other prey
                            if (!npc.Params.Predator)
                            {
                                continue;
                            }
                        }
                    }

                    float maxDist = a.Params.AwareMax;
                    float entDist = Util.CheckDistSqr(a.transform.position, ent.transform.position);

                    // Check if it's beyond our max awareness distance
                    if (entDist > Util.GetSquare(maxDist))
                    {
                        a.RemoveList.Add(id);
                        continue;
                    }

                    // Field-of-view and Line-of-sight check
                    if (!a.SightCheck(ent.gameObject, Util.GetSquare(maxDist)))
                    {
                        continue;
                    }

                    // If we haven't set our closest entity info yet
                    if (fresh)
                    {
                        closestEntDistSqr = entDist;
                        closestEnt        = ent;
                        fresh             = false;
                    }
                    else
                    {
                        if (entDist < closestEntDistSqr)
                        {
                            closestEntDistSqr = maxDist;
                            closestEnt        = ent;
                        }
                    }
                }

                if (closestEnt != null)
                {
                    // If we don't currently have a target
                    if (a.TargetObj == null)
                    {
                        a.SetTargetObj(closestEnt.gameObject, closestEnt);
                    }
                    else
                    {
                        if (a.TargetObj != closestEnt.gameObject && closestEntDistSqr < (a.TargetDistSqr * a.Params.ProxPct))
                        {
                            a.SetTargetObj(closestEnt.gameObject, closestEnt);
                        }
                    }
                }
            }
            else
            {
                // There's no entities within range, so reset our target
                if (a.TargetObj != null)
                {
                    a.ResetTargetObj();
                }
            }

            if (a.RemoveList != null && a.RemoveList.Count > 0)
            {
                for (int i = 0; i < a.RemoveList.Count; i++)
                {
                    LiveEntity ent = null;
                    a.TrackDict.TryGetValue(a.RemoveList[i], out ent);
                    Untrack(a, a.RemoveList[i]);
                }

                a.RemoveList.Clear();
            }
        }
コード例 #2
0
        public override BhvStatus Invoke(Npc a, BhvTree b)
        {
            if (a.TargetObj == null)
            {
                b.SetStatus(BhvStatus.FAILURE);
                return(b.Status);
            }

            if (a.Stats.Wounded)
            {
                b.SetStatus(BhvStatus.FAILURE);
                return(b.Status);
            }

            if (a.TargetEnt?.Stats.IsDead ?? false)
            {
                // We don't reset the move here because we still want to investigate what we were hunting
                a.ResetTargetObj();
                b.SetStatus(BhvStatus.SUCCESS);
                return(b.Status);
            }

            if (!b.SeeTarget)
            {
                // Set MovePos to last known TargetPos
                a.SetMovePos(a.TargetPos);
                a.ResetTargetObj();
                b.SetStatus(BhvStatus.FAILURE);
                return(b.Status);
            }

            if (b.DistTarget > Util.GetSquare(a.Params.AwareMax))
            {
                b.SetStatus(BhvStatus.FAILURE);
                return(b.Status);
            }

            if (b.DistTarget <= Util.GetSquare(a.Params.AwareClose))
            {
                a.PlaySound(SndT.HUNT);
                StopMove(a);
                b.SetStatus(BhvStatus.SUCCESS);
                return(b.Status);
            }

            if (a.NavAgent.pathStatus == NavMeshPathStatus.PathPartial || a.NavAgent.pathStatus == NavMeshPathStatus.PathInvalid)
            {
                bool failure = false;

                if (a.NavAgent.pathStatus == NavMeshPathStatus.PathInvalid)
                {
                    failure = true;
                }

                if (a.NavAgent.pathStatus == NavMeshPathStatus.PathPartial)
                {
                    if (Util.CheckDistSqr(a.NavAgent.destination, a.TargetPos) > Util.GetSquare(a.Params.AtkDist))
                    {
                        failure = true;
                    }
                }

                if (failure)
                {
                    StopMove(a);
                    b.SetPathFailed(true);
                    b.SetStatus(BhvStatus.FAILURE);
                    return(b.Status);
                }
            }

            if (a.MovePos == Vector3.zero)
            {
                a.SetMovePos(a.TargetPos);
            }

            if (a.NavAgent.hasPath)
            {
                // Sometimes the calculated destination on the nav mesh isn't exactly where we wanted to move
                if (a.MovePos != a.NavAgent.destination)
                {
                    a.SetMovePos(a.NavAgent.destination);
                }
            }

            float nSpd = a.Params.MoveSpd * a.Params.MoveWalk;

            // Set Speed accordingly
            if (a.NavAgent.speed != nSpd)
            {
                SetSpeed(a, nSpd);
            }

            if (!b.AnimInfo.IsName(AnimString.WALK))
            {
                a.PlaySound(SndT.HUNT);
                SetAnimTrigger(a, AnimString.WALK);
            }

            if (b.TimerCheck >= a.Params.ChkAlert)
            {
                if (a.TargetPos != a.MovePos)
                {
                    a.SetMovePos(a.TargetPos);
                }

                b.TimerCheck = 0.0f;
                CheckEnv(a, b);
            }

            if (a.NavAgent.destination != a.MovePos)
            {
                StartMove(a, a.MovePos);
            }

            return(b.Status);
        }
コード例 #3
0
ファイル: BNpcWary.cs プロジェクト: BenjaBobs/Hubris
        public override BhvStatus Invoke(Npc a, BhvTree b)
        {
            if (a.TargetObj == null)
            {
                b.SetStatus(BhvStatus.SUCCESS);
                return(b.Status);
            }

            if (a.Stats.Wounded)
            {
                b.SetStatus(BhvStatus.FAILURE);
                return(b.Status);
            }

            if (b.DistTarget <= Util.GetSquare(a.Params.AwareClose))
            {
                if (a.Params.Flighty)
                {
                    a.PlaySound(SndT.ALERT);
                    // Too close, should flee
                    b.SetStatus(BhvStatus.FAILURE);
                    return(b.Status);
                }
            }

            // Set Speed accordingly
            SetSpeed(a, a.Params.MoveSpd * a.Params.MoveWalk);

            float waryDist = ((a.Params.AwareMax - a.Params.AwareMed) / 2.0f) + a.Params.AwareMed;

            if (b.DistTarget <= Util.GetSquare(waryDist) && a.MovePos == Vector3.zero)
            {
                Vector3 nPos = FindFleePoint(a);

                if (nPos == Vector3.zero)
                {
                    // Debug.Log( "Unable to find flee point" );
                    if (!b.AnimInfo.IsName(AnimString.IDLE))
                    {
                        SetAnimTrigger(a, AnimString.IDLE);
                    }
                    return(BhvStatus.RUNNING);
                }

                // Debug.LogError( $"WaryFlee: {a.name} to position {nPos}" );

                // Debug.Log( "Found flee point" );
                b.TimerAct = 0.0f;
                a.SetMovePos(nPos);
            }

            if (b.TimerCheck >= a.Params.ChkAlert)
            {
                b.TimerCheck = 0.0f;
                CheckEnv(a, b);
            }

            if (a.NavAgent.pathPending)
            {
                return(BhvStatus.RUNNING);
            }

            if (!a.NavAgent.hasPath && a.MovePos != Vector3.zero)
            {
                StartMove(a, a.MovePos);
            }
            else
            {
                if (a.MovePos != a.NavAgent.destination)
                {
                    a.SetMovePos(a.NavAgent.destination);
                }
            }

            if (a.MovePos != Vector3.zero)
            {
                if (a.NavAgent.hasPath)
                {
                    if (!b.AnimInfo.IsName(AnimString.WALK))
                    {
                        SetAnimTrigger(a, AnimString.WALK);
                    }
                }
                else
                {
                    if (a.NavAgent.velocity == Vector3.zero)
                    {
                        a.SetMovePos(Vector3.zero);
                    }

                    if (!b.AnimInfo.IsName(AnimString.IDLE))
                    {
                        SetAnimTrigger(a, AnimString.IDLE);
                    }
                }
            }

            if (b.DistMove <= Util.GetSquare(a.Params.StopDist + a.NavAgent.radius) && a.NavAgent.hasPath)
            {
                if (a.TargetDistSqr > Util.GetSquare(a.Params.AwareMax + 10.0f))
                {
                    a.PlaySound(SndT.ALERT);
                    StopMove(a);
                    // Debug.Log( "Safe distance from target, flight over" );
                    a.ResetTargetObj();
                    b.SetPathFailed(false);
                    b.SetStatus(BhvStatus.SUCCESS);
                    return(b.Status);
                }
                else
                {
                    StopMove(a);
                    // Debug.Log( "Resetting move for recalculation" );
                }
            }

            return(b.Status);
        }
コード例 #4
0
ファイル: BNpcAtk.cs プロジェクト: BenjaBobs/Hubris
        public override BhvStatus Invoke(Npc a, BhvTree b)
        {
            if (a.TargetObj == null)
            {
                b.SetStatus(BhvStatus.FAILURE);
                return(b.Status);
            }

            if (a.TargetEnt?.Stats.IsDead ?? false)
            {
                StopMove(a);
                a.ResetTargetObj();
                b.SetStatus(BhvStatus.SUCCESS);
                return(b.Status);
            }

            if (b.DistTarget > Util.GetSquare(a.Params.AtkDist))
            {
                if (b.AnimInfo.IsName(AnimString.ATK))
                {
                    ResetAnimTrigger(a, AnimString.ATK);
                }

                StopMove(a);
                b.SetStatus(BhvStatus.FAILURE);
                return(b.Status);
            }

            if (a.NavAgent.pathStatus == NavMeshPathStatus.PathPartial || a.NavAgent.pathStatus == NavMeshPathStatus.PathInvalid)
            {
                StopMove(a);
                b.SetPathFailed(true);
                b.SetStatus(BhvStatus.FAILURE);
                return(b.Status);
            }

            GetFlatVectors(a, out Vector3 targetPos, out Vector3 thisPos, out Vector3 fwd);

            float angle = Vector3.Angle(fwd, (targetPos - thisPos));

            if (angle > a.Params.RotAngle)
            {
                TurnToward(a, targetPos);
            }

            a.SetMovePos(a.TargetPos);

            float nSpd = a.Params.MoveSpd;

            if (b.AnimInfo.IsName(AnimString.ATK))
            {
                nSpd *= a.Params.AtkSlow;
            }

            // Set Speed accordingly
            if (a.NavAgent.speed != nSpd)
            {
                SetSpeed(a, nSpd);
            }

            if (b.ActionReady)
            {
                if (b.TimerAct >= a.Params.AtkInit)
                {
                    if (a.TargetEnt != null)
                    {
                        if (b.ActionReady)
                        {
                            a.PlaySound(SndT.ATK);
                            if (!HubrisCore.Instance.TrySendDmg(a.TargetObj, a.TargetEnt, (int)a.Params.DamageStats.CommonType, a.Params.DamageStats.CommonAmount, false))
                            {
                                Debug.LogWarning($"{a.name} could not send damage to {a.TargetObj.name}");
                            }
                        }
                    }

                    b.SetActionReady(false);
                    SetAnimTrigger(a, AnimString.ATK);
                }
            }
            else                // ActionReady is false
            {
                if (a.NavAgent.velocity != Vector3.zero)
                {
                    if (!b.AnimInfo.IsName(AnimString.WALK))
                    {
                        SetAnimTrigger(a, AnimString.WALK);
                    }
                }
                else
                {
                    if (!b.AnimInfo.IsName(AnimString.IDLE))
                    {
                        SetAnimTrigger(a, AnimString.IDLE);
                    }
                }

                if (b.TimerAct >= a.Params.AtkEnd)
                {
                    b.SetActionReady(true);
                    b.TimerAct = 0.0f;
                }
            }

            if (b.TimerCheck >= a.Params.ChkAlert)
            {
                b.TimerCheck = 0.0f;
                CheckEnv(a, b);
            }

            if (a.NavAgent.destination != a.MovePos)
            {
                StartMove(a, a.MovePos);
            }

            b.SetPrevPos(a.transform.position);

            return(b.Status);
        }
コード例 #5
0
        public override BhvStatus Invoke(Npc a, BhvTree b)
        {
            if (a.TargetObj == null)
            {
                b.SetStatus(BhvStatus.FAILURE);
                b.SetPatient(true);
                return(b.Status);
            }

            if (a.Stats.Wounded)
            {
                b.SetStatus(BhvStatus.FAILURE);
                return(b.Status);
            }

            if (!b.SeeTarget && b.DistTarget > Util.GetSquare(a.Params.AwareMed))
            {
                // Debug.Log( "SightCheck failed" );
                a.ResetTargetObj();
                b.SetStatus(BhvStatus.FAILURE);
                return(b.Status);
            }

            if (b.DistTarget <= Util.GetSquare(a.Params.AwareMed))
            {
                if (a.Params.Predator)
                {
                    b.SetStatus(BhvStatus.SUCCESS);
                    return(b.Status);
                }
                else
                {
                    b.SetStatus(BhvStatus.FAILURE);
                    return(b.Status);
                }
            }

            if (b.TimerAct >= a.Params.PatienceTime)
            {
                b.TimerAct = 0.0f;

                if (UnityEngine.Random.Range(1, 20) >= 10)
                {
                    b.SetPatient(false);
                    a.PlaySound(SndT.ALERT);
                    b.SetStatus(a.Params.Predator ? BhvStatus.SUCCESS : BhvStatus.FAILURE);
                    return(b.Status);
                }
            }

            if (b.TimerCheck >= a.Params.ChkAlert)
            {
                b.TimerCheck = 0.0f;
                CheckEnv(a, b);
            }

            if (a.NavAgent.hasPath)
            {
                a.NavAgent.ResetPath();
            }

            GetFlatVectors(a, out Vector3 targetPos, out Vector3 thisPos, out Vector3 fwd);

            float angle = Vector3.Angle(fwd, (targetPos - thisPos));

            if (angle > a.Params.RotAngle)
            {
                // Reverse walk anim to differentiate from regular walking
                if (!b.AnimInfo.IsName(AnimString.WALKBACK))
                {
                    SetAnimTrigger(a, AnimString.WALKBACK);
                }

                TurnToward(a, targetPos);
            }
            else
            {
                if (!b.AnimInfo.IsName(AnimString.IDLE))
                {
                    SetAnimTrigger(a, AnimString.IDLE);
                }
            }

            return(b.Status);
        }
コード例 #6
0
ファイル: BNpcAggro.cs プロジェクト: BenjaBobs/Hubris
        public override BhvStatus Invoke(Npc a, BhvTree b)
        {
            if (a.TargetObj == null)
            {
                b.SetStatus(BhvStatus.FAILURE);
                return(b.Status);
            }

            if (a.TargetEnt?.Stats.IsDead ?? false)
            {
                StopMove(a);
                a.ResetTargetObj();
                b.SetStatus(BhvStatus.SUCCESS);
                return(b.Status);
            }

            if (b.DistTarget <= Util.GetSquare(a.Params.AtkDist))
            {
                b.SetStatus(BhvStatus.SUCCESS);
                return(b.Status);
            }

            if (a.NavAgent.pathStatus == NavMeshPathStatus.PathPartial || a.NavAgent.pathStatus == NavMeshPathStatus.PathInvalid)
            {
                bool failure = false;

                if (a.NavAgent.pathStatus == NavMeshPathStatus.PathInvalid)
                {
                    failure = true;
                }

                if (a.NavAgent.pathStatus == NavMeshPathStatus.PathPartial)
                {
                    if (Util.CheckDistSqr(a.NavAgent.destination, a.TargetPos) > Util.GetSquare(a.Params.AtkDist))
                    {
                        failure = true;
                    }
                }

                if (failure)
                {
                    StopMove(a);
                    b.SetPathFailed(true);
                    b.SetStatus(BhvStatus.FAILURE);
                    return(b.Status);
                }
            }

            a.SetMovePos(a.TargetPos);

            float nSpd = a.Params.MoveSpd;

            if (b.AnimInfo.IsName(AnimString.ATK))
            {
                nSpd *= a.Params.AtkSlow;
            }
            else
            {
                if (!b.AnimInfo.IsName(AnimString.RUN))
                {
                    SetAnimTrigger(a, AnimString.RUN);
                }
            }

            // Set Speed accordingly
            if (a.NavAgent.speed != nSpd)
            {
                SetSpeed(a, nSpd);
            }

            if (b.TimerCheck >= a.Params.ChkAlert)
            {
                if (a.TargetPos != a.MovePos)
                {
                    a.SetMovePos(a.TargetPos);
                }

                b.TimerCheck = 0.0f;
                CheckEnv(a, b);
            }

            if (a.NavAgent.destination != a.MovePos)
            {
                StartMove(a, a.MovePos);
            }

            return(b.Status);
        }
コード例 #7
0
ファイル: BNpcFlee.cs プロジェクト: BenjaBobs/Hubris
        public override BhvStatus Invoke(Npc a, BhvTree b)
        {
            if (a.TargetObj == null)
            {
                b.SetStatus(BhvStatus.SUCCESS);
                return(b.Status);
            }

            if (a.TargetEnt?.Stats.IsDead ?? false)
            {
                StopMove(a);
                a.ResetTargetObj();
                b.SetStatus(BhvStatus.SUCCESS);
                return(b.Status);
            }

            if (!b.PathFailed && b.TimerCheck >= a.Params.ChkAlert)
            {
                b.TimerCheck = 0.0f;
                CheckEnv(a, b);
            }

            // Set Speed accordingly
            if (a.NavAgent.speed != a.Params.MoveSpd)
            {
                SetSpeed(a, a.Params.MoveSpd);
            }

            if (a.MovePos == Vector3.zero)
            {
                Vector3 nPos = FindFleePoint(a);

                if (nPos == Vector3.zero)
                {
                    // Debug.Log( "Unable to find flee point" );
                    if (!b.AnimInfo.IsName(AnimString.IDLE))
                    {
                        SetAnimTrigger(a, AnimString.IDLE);
                    }
                    return(BhvStatus.RUNNING);
                }

                // Debug.Log( "Found flee point" );
                a.SetMovePos(nPos);
            }

            if (a.NavAgent.pathPending)
            {
                return(BhvStatus.RUNNING);
            }

            if (!a.NavAgent.hasPath)
            {
                StartMove(a, a.MovePos);
            }
            else
            {
                if (!b.AnimInfo.IsName(AnimString.RUN))
                {
                    SetAnimTrigger(a, AnimString.RUN);
                }

                if (a.MovePos != a.NavAgent.destination)
                {
                    a.SetMovePos(a.NavAgent.destination);
                }

                // TurnToward( a, a.NavAgent.steeringTarget );
            }

            // Need to include NavAgent.radius or else the Npc won't ever reach the MovePos
            if (b.DistMove <= Util.GetSquare(a.Params.StopDist + a.NavAgent.radius) && a.NavAgent.hasPath)
            {
                if ((a.TargetDistSqr > Util.GetSquare(a.Params.AwareMax + 10.0f)))
                {
                    StopMove(a);
                    // Debug.Log( "Safe distance from target, flight over" );
                    a.ResetTargetObj();
                    b.SetPathFailed(false);
                    b.SetStatus(BhvStatus.SUCCESS);
                    return(b.Status);
                }
                else
                {
                    StopMove(a);
                    // Debug.Log( "Resetting move for recalculation" );
                }
            }

            return(b.Status);
        }