예제 #1
0
        public TargetingBase(IMyEntity entity, IMyCubeBlock controllingBlock)
        {
            if (entity == null)
                throw new ArgumentNullException("entity");
            if (controllingBlock == null)
                throw new ArgumentNullException("controllingBlock");

            myLogger = new Logger("TargetingBase", entity);
            MyEntity = entity;
            CubeBlock = controllingBlock;
            FuncBlock = controllingBlock as IMyFunctionalBlock;

            myTarget = NoTarget.Instance;
            CurrentTarget = myTarget;
            Options = new TargetingOptions();
            entity.OnClose += obj => {
                if (WeaponsTargetingProjectile != null)
                    CurrentTarget = null;
            };

            //myLogger.debugLog("entity: " + MyEntity.getBestName() + ", block: " + CubeBlock.getBestName(), "TargetingBase()");
        }
예제 #2
0
		/// <summary>
		/// Calculates FiringDirection and InterceptionPoint
		/// </summary>
		/// TODO: if target is accelerating, look ahead (missiles and such)
		protected void SetFiringDirection()
		{
			if (myTarget.Entity == null || myTarget.Entity.MarkedForClose || MyEntity.MarkedForClose)
				return;

			Vector3 myVelocity = MyEntity.GetLinearVelocity();
			Vector3 targetVelocity = myTarget.GetLinearVelocity();
			Vector3 TargetPosition = myTarget.GetPosition();

			FindInterceptVector(ProjectilePosition(), myVelocity, ProjectileSpeed(TargetPosition), TargetPosition, targetVelocity);
			if (myTarget.Entity != null)
			{
				if (PhysicalProblem(myTarget.ContactPoint.Value))
				{
					myLogger.debugLog("Shot path is obstructed, blacklisting " + myTarget.Entity.getBestName(), "SetFiringDirection()");
					BlacklistTarget();
					return;
				}
				myLogger.debugLog("got an intercept vector: " + myTarget.FiringDirection + ", ContactPoint: " + myTarget.ContactPoint + ", target position: " + TargetPosition + ", by entity: " + myTarget.Entity.GetCentre(), "SetFiringDirection()");
			}
			CurrentTarget = myTarget;
		}
예제 #3
0
		/// <summary>
		/// Get any projectile which is a threat from Available_Targets[tType].
		/// </summary>
		private bool PickAProjectile(TargetType tType)
		{
			List<IMyEntity> targetsOfType;
			if (Available_Targets.TryGetValue(tType, out targetsOfType))
			{
				var sorted = targetsOfType.OrderBy(entity => GetWeaponsTargetingProjectile(entity));

				foreach (IMyEntity entity in sorted)
				{
					if (entity.Closed)
						continue;

					if (tType == TargetType.Missile)
					{
						long owner = Guided.GuidedMissile.GetOwnerId(entity.EntityId);
						if (!CubeBlock.canConsiderHostile(owner))
						{
							myLogger.debugLog("owner is not hostile", "PickAProjectile()");
							continue;
						}
					}

					//bool isMissile = entity.ToString().StartsWith("MyMissile");

					//if ((isMissile || entity is IMyMeteor) && Target.WeaponsTargeting(entity.EntityId) > 10)
					//{
					//	myLogger.debugLog("Not targeting " + entity.getBestName() + ", already targeted by " + Target.WeaponsTargeting(entity.EntityId) + " weapons", "PickAProjectile()");
					//	continue;
					//}

					// meteors and missiles are dangerous even if they are slow
					if (!(entity is IMyMeteor || entity.GetLinearVelocity().LengthSquared() > 100 || entity.ToString().StartsWith("MyMissile")))
						continue;

					IMyEntity projectile = entity;

					IMyCubeGrid asGrid = projectile as IMyCubeGrid;
					if (asGrid != null)
					{
						IMyCubeBlock targetBlock;
						double distanceValue;
						if (GetTargetBlock(asGrid, tType, out targetBlock, out distanceValue))
							projectile = targetBlock;
						else
						{
							myLogger.debugLog("failed to get a block from: " + asGrid.DisplayName, "PickAProjectile()");
							continue;
						}
					}

					if (ProjectileIsThreat(projectile, tType))
					{
						if (!PhysicalProblem(projectile.GetPosition()))
						{
							myLogger.debugLog("Is a threat: " + projectile.getBestName() + ", weapons targeting: " + GetWeaponsTargetingProjectile(projectile), "PickAProjectile()");
							myTarget = new TurretTarget(projectile, tType);
							return true;
						}
						else
							myLogger.debugLog("Physical problem: " + projectile.getBestName(), "PickAProjectile()");
					}
					else
						myLogger.debugLog("Not a threat: " + projectile.getBestName(), "PickAProjectile()");
				}
			}

			return false;
		}
예제 #4
0
		/// <summary>
		/// Get the closest target of the specified type from Available_Targets[tType].
		/// </summary>
		private bool SetClosest(TargetType tType, ref double closerThan)
		{
			List<IMyEntity> targetsOfType;
			if (!Available_Targets.TryGetValue(tType, out targetsOfType))
				return false;

			myLogger.debugLog("getting closest " + tType + ", from list of " + targetsOfType.Count, "SetClosest()");

			IMyEntity closest = null;

			Vector3D weaponPosition = ProjectilePosition();

			foreach (IMyEntity entity in targetsOfType)
			{
				if (entity.Closed)
					continue;

				IMyEntity target;
				Vector3D targetPosition;
				double distanceValue;

				// get block from grid before obstruction test
				IMyCubeGrid asGrid = entity as IMyCubeGrid;
				if (asGrid != null)
				{
					IMyCubeBlock targetBlock;
					if (GetTargetBlock(asGrid, tType, out targetBlock, out distanceValue))
						target = targetBlock;
					else
						continue;
					targetPosition = target.GetPosition();
				}
				else
				{
					target = entity;
					targetPosition = target.GetPosition();

					distanceValue = Vector3D.DistanceSquared(targetPosition, weaponPosition);
					if (distanceValue > Options.TargetingRangeSquared)
					{
						myLogger.debugLog("for type: " + tType + ", too far to target: " + target.getBestName(), "SetClosest()");
						continue;
					}

					if (PhysicalProblem(targetPosition))
					{
						myLogger.debugLog("can't target: " + target.getBestName(), "SetClosest()");
						Blacklist.Add(target);
						continue;
					}
				}

				if (distanceValue < closerThan)
				{
					closest = target;
					closerThan = distanceValue;
				}
			}

			if (closest != null)
			{
				myTarget = new TurretTarget(closest, tType);
				return true;
			}
			return false;
		}
예제 #5
0
		/// <summary>
		/// Finds a target
		/// </summary>
		protected void UpdateTarget()
		{
			if (Options.TargetingRange < 1f)
			{
				myLogger.debugLog("Not targeting, zero range", "UpdateTarget()");
				return;
			}

			if ((myTarget.TType & TargetType.Projectile) != 0 && !myTarget.Entity.Closed)
				if (TryHard || ProjectileIsThreat(myTarget.Entity, myTarget.TType))
				{
					myLogger.debugLog("Keeping Target = " + myTarget.Entity.getBestName(), "UpdateTarget()");
					return;
				}

			myTarget = new NoTarget();

			CollectTargets();
			PickATarget();
			if (myTarget.Entity != null && CurrentTarget != myTarget)
				myLogger.debugLog("New target: " + myTarget.Entity.getBestName(), "UpdateTarget()");
			else if (CurrentTarget != null && CurrentTarget.Entity != null)
				myLogger.debugLog("Lost target: " + CurrentTarget.Entity.getBestName(), "UpdateTarget()");
			CurrentTarget = myTarget;
		}
예제 #6
0
		protected void BlacklistTarget()
		{
			myLogger.debugLog("Blacklisting " + myTarget.Entity, "BlacklistTarget()");
			Blacklist.Add(myTarget.Entity);
			myTarget = new NoTarget();
			CurrentTarget = myTarget;
		}
예제 #7
0
        /// <summary>
        /// Targets a LastSeen chosen from the given storage, will overrride current target.
        /// </summary>
        /// <param name="storage">NetworkStorage to get LastSeen from.</param>
        protected void GetLastSeenTarget(RelayStorage storage, double range)
        {
            if (Globals.UpdateCount < m_nextLastSeenSearch)
                return;
            m_nextLastSeenSearch = Globals.UpdateCount + 100ul;

            if (storage == null)
            {
                //myLogger.debugLog("no storage", "GetLastSeenTarget()", Logger.severity.INFO);
                return;
            }

            if (storage.LastSeenCount == 0)
            {
                //myLogger.debugLog("no last seen in storage", "GetLastSeenTarget()", Logger.severity.DEBUG);
                return;
            }

            LastSeen processing;
            IMyCubeBlock targetBlock;

            if (CurrentTarget.Entity != null && storage.TryGetLastSeen(CurrentTarget.Entity.EntityId, out processing) && processing.isRecent())
            {
                LastSeenTarget lst = myTarget as LastSeenTarget;
                if (lst != null && lst.Block != null && !lst.Block.Closed)
                {
                    lst.Update(processing);
                    CurrentTarget = myTarget;
                    return;
                }

                if (ChooseBlock(processing, out targetBlock))
                {
                    myTarget = new LastSeenTarget(processing, targetBlock);
                    CurrentTarget = myTarget;
                    return;
                }
            }

            if (Options.TargetEntityId.HasValue)
            {
                if (storage.TryGetLastSeen(Options.TargetEntityId.Value, out processing))
                {
                    ChooseBlock(processing, out targetBlock);
                    myTarget = new LastSeenTarget(processing, targetBlock);
                    CurrentTarget = myTarget;
                }
                //else
                //	myLogger.debugLog("failed to get last seen from entity id", "GetLastSeenTarget()");
                return;
            }

            processing = null;
            targetBlock = null;

            if (SEAD)
            {
                float highestPowerLevel = 0f;

                storage.ForEachLastSeen((LastSeen seen) => {
                    if (seen.isRecent() && CubeBlock.canConsiderHostile(seen.Entity) && Options.CanTargetType(seen.Entity))
                    {
                        IMyCubeBlock block;
                        float powerLevel;
                        if (RadarEquipment.GetRadarEquipment(seen, out block, out powerLevel) && powerLevel > highestPowerLevel)
                        {
                            highestPowerLevel = powerLevel;
                            processing = seen;
                            targetBlock = block;
                        }
                    }
                });
            }
            else
            {
                // choose closest grid
                Vector3D myPos = ProjectilePosition();
                double closestDist = range * range;

                storage.ForEachLastSeen(seen => {
                    if (seen.isRecent() && CubeBlock.canConsiderHostile(seen.Entity) && Options.CanTargetType(seen.Entity))
                    {
                        IMyCubeBlock block;
                        if (!ChooseBlock(seen, out block))
                            return;

                        // always prefer a grid with a block
                        if (targetBlock != null && block == null)
                            return;

                        double dist = Vector3D.DistanceSquared(myPos, seen.LastKnownPosition);
                        if (dist < closestDist)
                        {
                            closestDist = dist;
                            processing = seen;
                            targetBlock = block;
                        }
                    }
                });
            }

            if (processing == null)
            {
                //myLogger.debugLog("failed to get a target from last seen", "GetLastSeenTarget()");
                myTarget = NoTarget.Instance;
                CurrentTarget = myTarget;
            }
            else
            {
                myTarget = new LastSeenTarget(processing, targetBlock);
                CurrentTarget = myTarget;
            }
        }
예제 #8
0
 protected void BlacklistTarget()
 {
     //myLogger.debugLog("Blacklisting " + myTarget.Entity, "BlacklistTarget()");
     Blacklist.Add(myTarget.Entity);
     myTarget = NoTarget.Instance;
     CurrentTarget = myTarget;
 }