private void DroneOnAlertedChanged(Drone drone, bool newState)
 {
     UpdateAlertZoneRadius();
 }
예제 #2
0
        public override void Update()
        {
            base.Update();

            Vector2 logicalMovement = Vector2.Zero;

            if (Input.IsKeyDown(Keys.A))
            {
                logicalMovement.X = -1.0f;
            }
            if (Input.IsKeyDown(Keys.D))
            {
                logicalMovement.X = 1.0f;
            }
            if (Input.IsKeyDown(Keys.W))
            {
                logicalMovement.Y = 1.0f;
            }
            if (Input.IsKeyDown(Keys.S))
            {
                logicalMovement.Y = -1.0f;
            }

            Vector3 worldMovement = Vector3.UnitX * logicalMovement.X + Vector3.UnitZ * -logicalMovement.Y;

            worldMovement.Normalize();

            Drone.SetMovement(worldMovement);

            if (worldMovement != Vector3.Zero)
            {
                Drone.UpdateBodyRotation(worldMovement);
            }

            if (Input.IsMousePositionLocked)
            {
                Size3   backbufferSize      = Game.GraphicsDevice.Presenter.BackBuffer.Size;
                Vector2 screenSize          = new Vector2(backbufferSize.Width, backbufferSize.Height);
                Vector2 logicalHeadMovement = Input.MouseDelta * screenSize;
                logicalHeadMovement.Y = -logicalHeadMovement.Y;

                float headRotationDelta = -logicalHeadMovement.X * MathUtil.Pi / 500.0f;
                Drone.UpdateHeadRotation(Drone.HeadRotation + headRotationDelta);

                if (Input.IsKeyPressed(Keys.Space) || Input.IsMouseButtonPressed(MouseButton.Left))
                {
                    Drone.Weapon?.TryShoot(null);
                }

                if (Input.IsKeyPressed(Keys.Escape))
                {
                    Input.UnlockMousePosition();
                }
            }
            else
            {
                if (Input.IsMouseButtonPressed(MouseButton.Left))
                {
                    Input.LockMousePosition(true);
                }
            }
        }
        private void ChaseUpdate()
        {
            Drone.Alerted = true;

            ChaseState chaseState = stateMachine.GetCurrentState <ChaseState>();

            if (chaseState == null)
            {
                throw new InvalidOperationException("ChaseUpdate can only be used with ChaseState");
            }

            if (chaseState.ChaseTarget == null)
            {
                // Stop chasing
                stateMachine.SwitchTo(PatrolState.Name);
                return;
            }

            IDestructible destructible = Utils.GetDestructible(chaseState.ChaseTarget);

            if (destructible == null)
            {
                throw new InvalidOperationException("ChaseTarget can only target IDestructibles");
            }
            if (destructible.IsDead)
            {
                // Stop chasing
                stateMachine.SwitchTo(PatrolState.Name);
                return;
            }

            // Check if still overlapping
            bool withinRange = false;

            foreach (var collision in alertZoneTrigger.Collisions)
            {
                var targetCollider = collision.ColliderA.Entity != alertZoneTrigger.Entity
                    ? collision.ColliderA
                    : collision.ColliderB;
                if (targetCollider == chaseState.ChaseColliderTarget)
                {
                    withinRange = true;
                    break;
                }
            }

            if (!withinRange)
            {
                // Stop chasing
                stateMachine.SwitchTo(PatrolState.Name);
                return;
            }

            // Recalculate path to player?
            Vector3 actualTargetPos = chaseState.ChaseTarget.Transform.WorldMatrix.TranslationVector;

            var source = Entity.Transform.WorldMatrix.TranslationVector;
            var target = actualTargetPos;

            source.Y = 1.5f;
            target.Y = 1.5f;
            Vector3 aimDir       = target - source;
            float   distToTarget = aimDir.Length();

            aimDir.Normalize();
            var playerTargeted = Drone.UpdateHeadRotation(aimDir);

            // Process move step
            if (chaseState.MoveOperation != null)
            {
                if (!chaseState.MoveOperation.MoveNext())
                {
                    chaseState.MoveOperation = null;
                }
            }

            bool hasLineOfSight = CheckLineOfSight(Entity, chaseState.ChaseColliderTarget);

            if (hasLineOfSight)
            {
                if (distToTarget < 6.0f)
                {
                    // No longer need to move, player is in line of sight, and drone is pretty close
                    chaseState.MoveOperation = null;
                    Drone.SetMovement(Vector3.Zero);
                }

                if (playerTargeted)
                {
                    // Shoot the player
                    Drone.Weapon?.TryShoot(chaseState.ChaseTarget);
                }
            }

            // Update path towards player when either not moving or
            //  the current path would end up too far from the player
            float targetDistance = (actualTargetPos - chaseState.CurrentChaseTargetPosition).Length();

            if (chaseState.MoveOperation == null || targetDistance > 1.0f)
            {
                chaseState.CurrentChaseTargetPosition = chaseState.ChaseTarget.Transform.WorldMatrix.TranslationVector;
                chaseState.MoveOperation = Move(chaseState.CurrentChaseTargetPosition);
            }
        }
        private void PatrolUpdate()
        {
            PatrolState patrolState = stateMachine.GetCurrentState <PatrolState>();

            if (patrolState == null)
            {
                throw new InvalidOperationException("PatrolUpdate can only be used with PatrolState");
            }

            // Move the drone on the current path, until the end of the move target is reached
            if (patrolState.MoveOperation != null)
            {
                if (!patrolState.MoveOperation.MoveNext())
                {
                    // Continue on path (if assigned)
                    if (PathToFollow != null)
                    {
                        // Done moving
                        patrolState.NextWaypoint = patrolState.NextWaypoint.Next;
                        if (patrolState.NextWaypoint == null)
                        {
                            patrolState.NextWaypoint = PathToFollow.Path.Waypoints[0]; // Loop back to first waypoint
                        }
                        patrolState.MoveOperation = Move(patrolState.NextWaypoint.Position);
                    }
                    else
                    {
                        // No move moving, this was a single target move
                        patrolState.MoveOperation = null;
                    }
                }
            }
            else
            {
                // Not moving and no path to follow, reset to spawn rotation
                Drone.UpdateBodyRotation(Drone.RotationToWorldDirection(spawnOrientation.Item1));
                Drone.UpdateHeadRotation(spawnOrientation.Item2);
            }

            // Look in moving direction
            Vector3 dir = Drone.CurrentVelocity;

            dir.Normalize();
            if (dir != Vector3.Zero)
            {
                Drone.UpdateHeadRotation(dir);
            }
            Drone.Alerted = false;

            // Check for enemies
            foreach (var collision in alertZoneTrigger.Collisions)
            {
                var targetCollider = collision.ColliderA.Entity != alertZoneTrigger.Entity
                    ? collision.ColliderA
                    : collision.ColliderB;

                if (Drone.Stunned)
                {
                    if (targetCollider.CollisionGroup != CollisionFilterGroups.CustomFilter3)
                    {
                        continue;
                    }
                }
                else
                {
                    if (targetCollider.CollisionGroup != CollisionFilterGroups.CharacterFilter &&
                        targetCollider.CollisionGroup != CollisionFilterGroups.CustomFilter1)
                    {
                        continue;
                    }
                }

                var enemy = Utils.GetDestructible(targetCollider.Entity);
                if (targetCollider.Entity == Entity || enemy == null || enemy.IsDead)
                {
                    continue;
                }

                // Visibility check
                bool hasLineOfSight = CheckLineOfSight(Entity, targetCollider);
                if (hasLineOfSight)
                {
                    // Start chasing state
                    patrolState.ChaseTarget         = targetCollider.Entity;
                    patrolState.ChaseColliderTarget = targetCollider;
                    stateMachine.SwitchTo(ChaseState.Name);
                }

                break;
            }
        }
예제 #5
0
 public virtual void Init(Drone drone)
 {
     Drone = drone;
 }
예제 #6
0
        public override void Init(Drone drone)
        {
            base.Init(drone);

            shootSoundSelector = new RandomSoundSelector(ProjectileSpawnPoint.Get <AudioEmitterComponent>(), "Fire");
        }
예제 #7
0
        public override void Init(Drone drone)
        {
            base.Init(drone);

            shootSound = ProjectileSpawnPoint.Get <AudioEmitterComponent>()["Fire"];
        }