/// <summary>
 /// Notify the SAM site that a target has been destroyed or missed.
 /// </summary>
 public void NotifyTargetIsDestroyedOrMissed(DropPodIncoming dropPod)
 {
     if (this.acquiredTargets.Contains(dropPod))
     {
         this.acquiredTargets.Remove(dropPod);
     }
 }
 public void InitializeMissileData(Building_SamSite launcher, DropPodIncoming dropPod, Vector3 missileOrigin, Vector3 predictedImpactPosition, int predictedTicksToImpact, bool targetWillBeHit = true)
 {
     this.launcher = launcher;
     this.target = dropPod;
     this.origin = missileOrigin;
     this.predictedImpactPosition = predictedImpactPosition;
     this.predictedTicksToImpact = predictedTicksToImpact;
     this.ticksToImpact = predictedTicksToImpact;
     this.missileRotation = (this.predictedImpactPosition - this.origin).AngleFlat();
     this.targetWillBeHit = targetWillBeHit;
 }
        private void LaunchMissile(DropPodIncoming dropPod)
        {
            const int ticksToImpactOffsetAverage = 40;

            bool targetWillBeHit = true;
            float landingDistanceCoefficient = 0f;
            Vector3 missPositionOffset;

            // Determine if drop pod will be hit.
            if (Rand.Value < 0.8f)
            {
                targetWillBeHit = true;
                missPositionOffset = new Vector3(0, 0, 0);
            }
            else
            {
                targetWillBeHit = false;
                missPositionOffset = new Vector3(5, 0, 5).RotatedBy(Rand.Range(0, 360));
            }

            // Compute predicted target impact position and time.
            int dropPodTicksToLanding = (int)(typeof(DropPodIncoming).GetField("ticksToImpact", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(dropPod));
            int ticksToImpactOffset = ticksToImpactOffsetAverage + Rand.RangeInclusive(-10, 10);
            int predictedTicksToImpact = dropPodTicksToLanding - ticksToImpactOffset;
            landingDistanceCoefficient = (float)(ticksToImpactOffset * ticksToImpactOffset) * 0.01f;
            Vector3 predictedImpactPosition = dropPod.Position.ToVector3ShiftedWithAltitude(AltitudeLayer.FlyingItem) + new Vector3(-landingDistanceCoefficient * 0.4f, 0, +landingDistanceCoefficient * 0.6f) + missPositionOffset;
            Projectile_Sam sam = ThingMaker.MakeThing(ThingDef.Named("Sam")) as Projectile_Sam;
            sam.InitializeMissileData(this, dropPod, this.Position.ToVector3Shifted(), predictedImpactPosition, predictedTicksToImpact, targetWillBeHit);
            GenSpawn.Spawn(sam, this.Position);
            this.missilesLoadedNumber--;

            // Update turret rotation.
            this.patrolTicksToNextRotation = patrolRotationIntervalMin;
            this.turretRotation = (predictedImpactPosition - this.DrawPos).AngleFlat();
            StopRotationSound();

            // Throw smoke and play missile launch sound.
            MoteMaker.ThrowSmoke(this.DrawPos, 2f);
            SoundInfo infos = SoundInfo.InWorld(this);
            OG_Util.MissileLaunchSoundDef.PlayOneShot(infos);
        }