Ejemplo n.º 1
0
        /// <inheritdoc />
        public int RegisterRangeTarget(IRangeTarget rangeTarget)
        {
            int newID = GetNewID(rangeTargets);

            rangeTarget.InstanceID = newID;
            rangeTargets.Add(rangeTarget.InstanceID, rangeTarget);
            return(newID);
        }
Ejemplo n.º 2
0
        public override bool ShootProjectile(IRangeTarget target)
        {
            if (target.Moving)
            {
                return(ShootMovingTarget(target));
            }

            return(ShootStaticTarget(target));
        }
Ejemplo n.º 3
0
        void OnTargetDestroyed(Shooter shooter, IRangeTarget target)
        {
            if (explicitTarget != null)
            {
                Debug.Assert(target == explicitTarget);

                ResetExplicitTarget();
            }
        }
Ejemplo n.º 4
0
 public override bool IsInRange(Vector3 source, IRangeTarget target)
 {
     return(BallisticProjectile.GetTimesAndVectorsForStaticTarget(target.CurrentPosition,
                                                                  source,
                                                                  Speed,
                                                                  out var loweTime,
                                                                  out var lowVector,
                                                                  out var highTime,
                                                                  out var highVector));
 }
Ejemplo n.º 5
0
 void InvokeOnTargetDestroyed(IRangeTarget target)
 {
     try
     {
         TargetDestroyed?.Invoke(this, target);
     }
     catch (Exception e)
     {
         Urho.IO.Log.Write(LogLevel.Debug,
                           $"There was an unexpected exception during the invocation of {nameof(TargetDestroyed)}: {e.Message}");
     }
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Stops shooting at any current target and sets <paramref name="newTarget"/> as the target of this Shooter if the <paramref name="newTarget"/> is in range of this shooter.
        /// </summary>
        /// <param name="newTarget">New target to try shooting at.</param>
        /// <returns>True if <paramref name="newTarget"/> is in range, false otherwise.</returns>
        public bool ShootAt(IRangeTarget newTarget)
        {
            StopShooting();

            if (!CanShootAt(newTarget))
            {
                return(false);
            }

            Target = newTarget;
            newTarget.AddShooter(this);
            return(true);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// If the <paramref name="target"/> can be hit when shooting from <paramref name="source"/>.
        /// </summary>
        /// <param name="source">The shooting position.</param>
        /// <param name="target">Target to hit.</param>
        /// <returns>True if the target can be hit, false otherwise.</returns>
        public bool IsInRange(Vector3 source, IRangeTarget target)
        {
            if (target == null)
            {
                return(false);
            }

            try {
                return(Plugin.IsInRange(source, target));
            }
            catch (Exception e) {
                Urho.IO.Log.Write(LogLevel.Error,
                                  $"Projectile type plugin call {nameof(Plugin.IsInRange)} failed with Exception: {e.Message}");
                return(false);
            }
        }
Ejemplo n.º 8
0
        bool ShootMovingTarget(IRangeTarget target)
        {
            int numSolutions = BallisticProjectile.GetVectorsForMovingTarget(target,
                                                                             Projectile.Position,
                                                                             myType.Speed,
                                                                             out Vector3 lowVector,
                                                                             out Vector3 highVector);

            if (numSolutions >= 1)
            {
                flier.StartFlight(lowVector);
                return(true);
            }

            return(false);
        }
Ejemplo n.º 9
0
        public override bool ShootProjectile(IRangeTarget target)
        {
            if (BallisticProjectile.GetTimesAndVectorsForStaticTarget(target.CurrentPosition,
                                                                      Projectile.Position,
                                                                      myType.Speed,
                                                                      out var lowTime,
                                                                      out var lowVector,
                                                                      out var highTime,
                                                                      out var highVector))
            {
                flier.StartFlight(lowVector);
                return(true);
            }

            return(false);
        }
Ejemplo n.º 10
0
        IRangeTarget SetExplicitTarget(IEntity targetEntity)
        {
            IRangeTarget target = targetEntity.GetDefaultComponent <RangeTargetComponent>();

            if (target == null)
            {
                return(null);
            }

            ResetExplicitTarget();

            explicitTarget      = target;
            target.TargetMoved += ExplicitTargetMoved;
            target.AddShooter(this);

            return(target);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Creates projectile to shoot at the given target, or null if projectile of this type cannot be shot and hit the target.
        /// </summary>
        /// <param name="newID">The id to give the projectile.</param>
        /// <param name="level">Level in which to shoot the projectile.</param>
        /// <param name="player">Owner of the projectile.</param>
        /// <param name="position">Initial position of the projectile, from where the shooting is happening.</param>
        /// <param name="initRotation">Initial rotation of the projectile.</param>
        /// <param name="target">Target to shoot the projectile at.</param>
        /// <returns>Projectile that was shot at the target, or null if projectile cannot be shot and hit the target.</returns>
        internal IProjectile ShootProjectile(int newID,
                                             ILevelManager level,
                                             IPlayer player,
                                             Vector3 position,
                                             Quaternion initRotation,
                                             IRangeTarget target)
        {
            var projectile = GetProjectile(newID, level, player, position, initRotation);

            if (!projectile.Shoot(target))
            {
                projectile.RemoveFromLevel();
                projectile = null;
            }

            return(projectile);
        }
Ejemplo n.º 12
0
        void Shoot(float timeStep)
        {
            if (shotDelay > 0)
            {
                shotDelay -= timeStep;
                return;
            }

            InvokeOnShotReloaded();

            if (Target == null)
            {
                return;
            }

            InvokeOnBeforeShotFired();

            //Check if shotDelay was not reset in the OnBeforeShotFired or OnShotReloaded handlers
            if (shotDelay > 0)
            {
                return;
            }

            //Rotate the SourceOffset according to Entity world rotation
            Vector3 worldOffset = Quaternion.FromRotationTo(Vector3.UnitZ, Entity.Forward) * SourceOffset;
            var     projectile  = Level.SpawnProjectile(projectileType, Entity.Position + worldOffset, Quaternion.Identity, Player, Target);

            //Could not fire on the target
            if (projectile == null)
            {
                var previousTarget = Target;
                Target.RemoveShooter(this);
                Target = null;

                InvokeOnTargetLost(previousTarget);
            }
            else
            {
                InvokeOnShotFired(projectile);
            }

            ResetShotDelay();
        }
Ejemplo n.º 13
0
        void SearchTarget(float timeStep)
        {
            if (!SearchForTarget)
            {
                return;
            }

            if (searchDelay >= 0)
            {
                searchDelay -= timeStep;
                return;
            }

            if (Target == null && searchDelay < 0)
            {
                searchDelay = TargetSearchDelay;

                //Check for target in range
                var possibleTargets = Player.GetEnemyPlayers()
                                      .SelectMany(enemy => enemy.GetAllUnits())
                                      //.AsParallel()
                                      .Where(unit => projectileType.IsInRange(Entity.Position, unit.GetDefaultComponent <RangeTargetComponent>()))
                                      .OrderBy(unit => Vector3.Distance(Entity.Position, unit.Position));


                foreach (var possibleTarget in possibleTargets)
                {
                    var newTarget = possibleTarget.GetDefaultComponent <RangeTargetComponent>();

                    Target = newTarget;
                    Target.AddShooter(this);
                    InvokeOnTargetAcquired();
                    break;
                }
            }
        }
Ejemplo n.º 14
0
        public static int GetVectorsForMovingTarget(IRangeTarget rangeTarget,
                                                    Vector3 sourcePosition,
                                                    float initialProjectileSpeed,
                                                    out Vector3 lowVector,
                                                    out Vector3 highVector)
        {
            if (!rangeTarget.Moving)
            {
                if (GetTimesAndVectorsForStaticTarget(rangeTarget.CurrentPosition,
                                                      sourcePosition,
                                                      initialProjectileSpeed,
                                                      out var lowTime,
                                                      out lowVector,
                                                      out var highTime,
                                                      out highVector))
                {
                    return(2);
                }

                return(0);
            }


            var waypoints = rangeTarget.GetFutureWaypoints().GetEnumerator();

            if (!waypoints.MoveNext())
            {
                lowVector  = Vector3.Zero;
                highVector = Vector3.Zero;
                return(0);
            }

            Waypoint current            = waypoints.Current;
            Waypoint?next               = null;
            float    timeToNextWaypoint = 0;

            while (waypoints.MoveNext())
            {
                next = waypoints.Current;
                timeToNextWaypoint += next.Value.TimeToWaypoint;
                if (!GetTimesAndVectorsForStaticTarget(
                        current.Position,
                        next.Value.Position,
                        initialProjectileSpeed,
                        out float lowTime,
                        out Vector3 dontCare1,
                        out float dontCare2,
                        out Vector3 dontCare3))
                {
                    //Out of range
                    lowVector  = Vector3.Zero;
                    highVector = Vector3.Zero;
                    return(0);
                }

                //Found the right two waypoints, that the projectile will hit
                if (timeToNextWaypoint > lowTime)
                {
                    break;
                }
            }

            waypoints.Dispose();
            //Target is stationary
            if (!next.HasValue)
            {
                if (GetTimesAndVectorsForStaticTarget(current.Position,
                                                      sourcePosition,
                                                      initialProjectileSpeed,
                                                      out var lowTime,
                                                      out lowVector,
                                                      out var highTime,
                                                      out highVector))
                {
                    return(2);
                }

                return(0);
            }

            Vector3 targetMovement = (next.Value.Position - current.Position) / next.Value.TimeToWaypoint;

            //A position simulating a linear movement of target, so it arrives at the proper time to the next waypoint
            Vector3 fakePosition = next.Value.Position - targetMovement * timeToNextWaypoint;

            return(GetVectorsForMovingTarget(fakePosition,
                                             targetMovement,
                                             sourcePosition,
                                             initialProjectileSpeed,
                                             out lowVector,
                                             out highVector));
        }
Ejemplo n.º 15
0
 void ResetExplicitTarget()
 {
     explicitTarget?.RemoveShooter(this);
     explicitTarget = null;
     targetMoved    = false;
 }
Ejemplo n.º 16
0
 /// <summary>
 /// Starts the projectiles movement from it's current position towards the <paramref name="target"/>.
 /// </summary>
 /// <param name="target">The target to move to.</param>
 /// <returns>True if projectile can reach the target, false otherwise.</returns>
 public abstract bool ShootProjectile(IRangeTarget target);
Ejemplo n.º 17
0
 void RangeTargetComponent.IShooter.OnTargetDestroy(IRangeTarget target)
 {
     ResetExplicitTarget();
 }
Ejemplo n.º 18
0
 /// <summary>
 /// Loads range target that was stored and already has an ID.
 /// </summary>
 /// <param name="rangeTarget">The range target with ID.</param>
 internal void LoadRangeTarget(IRangeTarget rangeTarget)
 {
     rangeTargets.Add(rangeTarget.InstanceID, rangeTarget);
 }
Ejemplo n.º 19
0
 /// <summary>
 /// Checks if <paramref name="target"/> can be shot at, mainly if the target is in range.
 /// </summary>
 /// <param name="target">The target to check.</param>
 /// <returns>True of target can be shot at, false otherwise.</returns>
 public bool CanShootAt(IRangeTarget target)
 {
     return(projectileType.IsInRange(Entity.Position, target));
 }
Ejemplo n.º 20
0
        /// <inheritdoc />
        public IProjectile SpawnProjectile(ProjectileType projectileType, Vector3 position, Quaternion initRotation, IPlayer player, IRangeTarget target)
        {
            IProjectile newProjectile;

            try {
                newProjectile = projectileType.ShootProjectile(GetNewID(entities), this, player, position, initRotation, target);
            }
            catch (CreationException) {
                return(null);
            }
            //Could not spawn projectile, maybe out of range
            if (newProjectile == null)
            {
                return(null);
            }


            RegisterEntity(newProjectile);
            projectiles.Add(newProjectile.ID, newProjectile);

            return(newProjectile);
        }
Ejemplo n.º 21
0
 /// <summary>
 /// Stops shooting at any current target.
 /// </summary>
 public void StopShooting()
 {
     Target?.RemoveShooter(this);
     Target = null;
 }
Ejemplo n.º 22
0
 /// <summary>
 /// Informs the shooter that the target was destroyed.
 /// </summary>
 /// <param name="target">The destroyed target.</param>
 void RangeTargetComponent.IShooter.OnTargetDestroy(IRangeTarget target)
 {
     Debug.Assert(this.Target == target);
     this.Target = null;
     InvokeOnTargetDestroyed(target);
 }
Ejemplo n.º 23
0
 void ExplicitTargetMoved(IRangeTarget target)
 {
     targetMoved = true;
 }
Ejemplo n.º 24
0
 /// <summary>
 /// Decides if the <paramref name="target"/> is in range of this projectile when shot from the position <paramref name="source"/>.
 /// </summary>
 /// <param name="source">The source position of the projectile.</param>
 /// <param name="target">The target of the projectile.</param>
 /// <returns>True if projectile of this type can reach the target from the <paramref name="source"/> position, false otherwise.</returns>
 public abstract bool IsInRange(Vector3 source, IRangeTarget target);
Ejemplo n.º 25
0
 public ShootOrder(IRangeTarget target)
 {
     this.Target = target;
 }