public Beam(Vector2 srcCenter, int Thickness, Ship Owner, GameplayObject target)
 {
     this.Target = target;
     this.owner = Owner;
     Vector2 TargetPosition = Vector2.Normalize(target.Center);
     if (Owner.InFrustum)
     {
         this.DamageToggleSound = AudioManager.GetCue("sd_shield_static_1");
     }
     if (this.owner.isInDeepSpace || this.owner.GetSystem() == null)
     {
         UniverseScreen.DeepSpaceManager.BeamList.Add(this);
     }
     else
     {
         this.system = this.owner.GetSystem();
         this.system.spatialManager.BeamList.Add(this);
     }
     this.Source = srcCenter;
     this.BeamOffsetAngle = Owner.Rotation - MathHelper.ToRadians(HelperFunctions.findAngleToTarget(srcCenter, TargetPosition));
     this.Destination = HelperFunctions.findPointFromAngleAndDistanceUsingRadians(srcCenter, Owner.Rotation + this.BeamOffsetAngle, this.range);
     this.ActualHitDestination = this.Destination;
     this.Vertices = new VertexPositionNormalTexture[4];
     this.Indexes = new int[6];
     this.BeamZ = RandomMath2.RandomBetween(-1f, 1f);
     Vector3[] points = HelperFunctions.BeamPoints(srcCenter, TargetPosition, (float)Thickness, new Vector2[4], 0, this.BeamZ);
     this.UpperLeft = points[0];
     this.UpperRight = points[1];
     this.LowerLeft = points[2];
     this.LowerRight = points[3];
     this.FillVertices();
 }
 public SpaceJunk(Vector2 Position, GameplayObject source)
 {
     this.Position.X = RandomMath2.RandomBetween(Position.X - 20f, Position.X + 20f);
     this.Position.Y = RandomMath2.RandomBetween(Position.Y - 20f, Position.Y + 20f);
     this.Position.Z = RandomMath2.RandomBetween(-20f, 20f);
     this.initialVel = source.Velocity;
 }
 public void SetTarget(GameplayObject target)
 {
     if (target == null)
         return;
     this.TargetSet = true;
     this.Target = target;
 }
        public void ChooseTarget()
        {
            this.Target = null;
            //List<GameplayObject> nearby = UniverseScreen.ShipSpatialManager.GetNearby(this.Owner);
            //List<GameplayObject> nearby = this.Owner.owner.GetAI().FriendliesNearby;
            List<Ship> Potentials = new List<Ship>();

            //foreach (GameplayObject go in nearby)
            foreach (Ship go in this.Owner.owner.GetAI().FriendliesNearby)
            {
                bool isShip = go is Ship;

                    Ship goShip = go as Ship;
                    if (!isShip || goShip.loyalty != this.Owner.loyalty || goShip.Health >= goShip.HealthMax)
                {
                    continue;
                }
                    Potentials.Add(goShip);
            }
            IOrderedEnumerable<Ship> sortedList =
                from ship in Potentials
                orderby ship.Health / ship.HealthMax
                select ship;
            for (int i = 0; i < sortedList.Count<Ship>(); i++)
            {
                if (Vector2.Distance(sortedList.ElementAt<Ship>(i).Center, this.Owner.Position) < 20000f && sortedList.ElementAt<Ship>(i).Active && sortedList.ElementAt<Ship>(i).Health > 0f)
                {
                    this.Target = sortedList.ElementAt<Ship>(i);
                    return;
                }
            }
        }
 public override void Die(GameplayObject source, bool cleanupOnly)
 {
     DebugInfoScreen.ModulesDied = DebugInfoScreen.ModulesDied + 1;
     if (!this.isDummy)
     {
         foreach (ShipModule link in this.LinkedModulesList)
         {
             if (!link.Active)
             {
                 continue;
             }
             link.Die(source, true);
         }
     }
     if (this.shield_power_max > 0f)
     {
         base.Health = 0f;
     }
     this.SetNewExternals();
     base.Health = 0f;
     Vector3 center = new Vector3(this.Center.X, this.Center.Y, -100f);
     if (this.Active)
     {
         ((this.Parent.GetSystem() != null ? this.Parent.GetSystem().RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(5f, 15f);
         if (!this.Parent.dying && this.Parent.InFrustum)
         {
             for (int i = 0; i < 30; i++)
             {
                 ShipModule.universeScreen.explosionParticles.AddParticleThreadA(center, Vector3.Zero);
             }
         }
         else if (this.Parent.InFrustum)
         {
             for (int i = 0; i < 30; i++)
             {
                 ShipModule.universeScreen.explosionParticles.AddParticleThreadA(new Vector3(this.Parent.Center, ((this.Parent.GetSystem() != null ? this.Parent.GetSystem().RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-25f, 25f)), Vector3.Zero);
             }
         }
     }
     base.Die(source, cleanupOnly);
     if (!cleanupOnly)
     {
         if (this.Parent.Active && this.Parent.InFrustum && ShipModule.universeScreen.viewState == UniverseScreen.UnivScreenState.ShipView)
         {
             GameplayObject.audioListener.Position = ShipModule.universeScreen.camPos;
             Cue dieCue = AudioManager.GetCue("sd_explosion_module_small");
             dieCue.Apply3D(GameplayObject.audioListener, this.Parent.emitter);
             dieCue.Play();
         }
         if (this.explodes)
         {
             if (this.Parent.GetSystem() == null)
             {
                 UniverseScreen.DeepSpaceManager.ExplodeAtModule(this.Parent.LastDamagedBy, this, (float)(2500 * this.XSIZE * this.YSIZE), (float)(this.XSIZE * this.YSIZE * 64));
             }
             else
             {
                 this.Parent.GetSystem().spatialManager.ExplodeAtModule(this.Parent.LastDamagedBy, this, (float)(2500 * this.XSIZE * this.YSIZE), (float)(this.XSIZE * this.YSIZE * 64));
             }
         }
         if (this.PowerFlowMax > 0 || this.PowerRadius > 0)
         {
             this.Parent.NeedRecalculate = true;
         }
     }
     if (((this.Parent.GetSystem() != null ? this.Parent.GetSystem().RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(0f, 100f) < 10f)
     {
         List<SpaceJunk> junk = SpaceJunk.MakeJunk(1, this.Center, this.Parent.GetSystem());
         lock (GlobalStats.ObjectManagerLocker)
         {
             foreach (SpaceJunk j in junk)
             {
                 j.wasAddedToScene = true;
                 ShipModule.universeScreen.ScreenManager.inter.ObjectManager.Submit(j.JunkSO);
                 UniverseScreen.JunkList.Add(j);
             }
         }
     }
     //this.SetNewExternals();
 }
        public override bool Touch(GameplayObject target)
        {
            if (this.Miss)
            {
                return false;
            }
            if (target != null)
            {
                if (target == this.owner && !this.weapon.HitsFriendlies)
                {
                    return false;
                }
                Projectile projectile = target as Projectile;
                if (projectile != null)
                {
                    if (this.owner != null && projectile.loyalty == this.owner.loyalty)
                    {
                        return false;
                    }
                    if (projectile.WeaponType == "Missile")
                    {
                        float ran = ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(0f, 1f);
                        if (projectile.loyalty != null && ran >= projectile.loyalty.data.MissileDodgeChance)
                        {
                            projectile.DamageMissile(this, this.damageAmount);
                            return true;
                        }
                    }
                    else if (this.weapon.Tag_Intercept || projectile.weapon.Tag_Intercept)
                    {
                        this.DieNextFrame = true;
                        projectile.DieNextFrame = true;
                    }
                    return false;
                }
                if (target is Asteroid)
                {
                    if (!this.explodes)
                    {
                        target.Damage(this, this.damageAmount);
                    }
                    this.Die(null, false);
                    return true;
                }
                if (target is ShipModule)
                {
                    ShipModule module = target as ShipModule;
                    if (module != null && module.GetParent().loyalty == this.loyalty && !this.weapon.HitsFriendlies || module == null)
                        return false;

                    if (this.weapon.TruePD)
                    {
                        this.DieNextFrame = true;
                        return true;
                    }
                    if (module.GetParent().Role == "fighter" && module.GetParent().loyalty.data.Traits.DodgeMod > 0f)
                    {
                        if (((module.GetParent().GetSystem() != null ? module.GetParent().GetSystem().RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(0f, 100f) < module.GetParent().loyalty.data.Traits.DodgeMod * 100f)
                        {
                            this.Miss = true;
                        }
                    }
                    if (this.Miss)
                    {
                        return false;
                    }
                    // Moving this to the Damage function - doesn't seem to be working? Also seems nonsensical.
                    /*
                    if (module.ModuleType == ShipModuleType.Armor || (module.ModuleType == ShipModuleType.Dummy && module.ParentOfDummy.ModuleType == ShipModuleType.Armor))
                    {
                        this.damageRadius -= module.GetParent().loyalty.data.ExplosiveRadiusReduction * this.damageRadius;
                        this.damageAmount -= module.GetParent().loyalty.data.ExplosiveRadiusReduction * this.damageAmount;
                        this.damageAmount *= this.weapon.EffectVsArmor;
                        this.damageAmount *= this.damageAmount + this.ArmorDamageBonus;
                    }

                    if (module.ModuleType == ShipModuleType.Shield && module.shield_power > 0)
                    {
                        this.damageAmount *= this.weapon.EffectVSShields;
                        this.damageAmount *= this.damageAmount + this.ShieldDamageBonus;
                        //projectiles penetrate weak shields
                        if (this.damageAmount > module.shield_power)
                        {
                            float remainder = 0;
                            module.Damage(this, this.damageAmount, ref remainder);
                            if (remainder > 0)
                            {
                                this.damageAmount = remainder;
                                return false;
                            }
                            else
                            {
                                this.damageAmount = 0;
                                this.explodes = false;
                                this.DieNextFrame = true;
                                return base.Touch(target);
                            }
                        }
                    }
                     */
                    //Non exploding projectiles should go through multiple modules if it has enough damage
                    if (!this.explodes && module.Active)
                    {
                        float remainder;

                        //Doc: If module has resistance to Armour Piercing effects, deduct that from the projectile's AP before starting AP and damage checks
                        if (module.APResist > 0)
                        {
                            this.ArmorPiercing -= (byte)module.APResist;
                            if (this.ArmorPiercing < 0)
                                this.ArmorPiercing = 0;
                        }

                        if (this.ArmorPiercing == 0 || !(module.ModuleType == ShipModuleType.Armor || (module.ModuleType == ShipModuleType.Dummy && module.ParentOfDummy.ModuleType == ShipModuleType.Armor)))
                        {
                            remainder = 0;
                            module.Damage(this, this.damageAmount, ref remainder);
                        }
                        else
                        {
                            this.ArmorPiercing--;
                            remainder = this.damageAmount;
                        }
                        if (remainder > 0)
                        {
                            this.damageAmount = remainder;
                            bool SlotFound;
                            int depth = 10;
                            Vector2 UnitVector = this.velocity;
                            while (this.damageAmount > 0)
                            {
                                UnitVector.Normalize();
                                UnitVector *= depth;
                                SlotFound = false;
                                foreach (ModuleSlot slot in module.GetParent().ModuleSlotList)
                                {
                                    if (Vector2.Distance(this.Center + UnitVector, slot.module.Center) < 8f)
                                    {
                                        SlotFound = true;
                                        if (slot.module.Active)
                                        {
                                            if (this.ArmorPiercing > 0 && (slot.module.ModuleType == ShipModuleType.Armor || (slot.module.ModuleType == ShipModuleType.Dummy && slot.module.ParentOfDummy.ModuleType == ShipModuleType.Armor)))
                                                break;
                                            else
                                            {
                                                remainder = 0;
                                                slot.module.Damage(this, this.damageAmount, ref remainder);
                                                if (remainder > 0)
                                                    this.damageAmount = remainder;
                                                else
                                                    this.damageAmount = 0f;
                                            }
                                        }
                                        break;
                                    }
                                }
                                //Slot found means it is still in the ship
                                if (SlotFound)
                                {
                                    depth += 8;
                                    this.ArmorPiercing--;
                                }
                                else
                                    break;
                            }
                        }
                    }
                    base.Health = 0f;
                }
                if (this.WeaponEffectType == "Plasma")
                {
                    Vector3 center = new Vector3(this.Center.X, this.Center.Y, -100f);
                    Vector2 forward = new Vector2((float)Math.Sin((double)base.Rotation), -(float)Math.Cos((double)base.Rotation));
                    Vector2 right = new Vector2(-forward.Y, forward.X);
                    right = Vector2.Normalize(right);
                    for (int i = 0; i < 20; i++)
                    {
                        Vector3 random = new Vector3(right.X * ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-250f, 250f), right.Y * ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-250f, 250f), ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-250f, 250f));
                        Projectile.universeScreen.flameParticles.AddParticleThreadA(center, random);
                        random = new Vector3(-forward.X + ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-150f, 150f), -forward.Y + ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-150f, 150f), ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-150f, 150f));
                        Projectile.universeScreen.flameParticles.AddParticleThreadA(center, random);
                    }
                }
                if (this.WeaponEffectType == "MuzzleBlast") // currently unused
                {
                    Vector3 center = new Vector3(this.Center.X, this.Center.Y, -100f);
                    Vector2 forward = new Vector2((float)Math.Sin((double)base.Rotation), -(float)Math.Cos((double)base.Rotation));
                    Vector2 right = new Vector2(-forward.Y, forward.X);
                    right = Vector2.Normalize(right);
                    for (int i = 0; i < 20; i++)
                    {
                        Vector3 random = new Vector3(right.X * ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-500f, 500f), right.Y * ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-500f, 500f), ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-250f, 250f));
                        Projectile.universeScreen.fireTrailParticles.AddParticleThreadA(center, random);
                        random = new Vector3(-forward.X + ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-500f, 500f), -forward.Y + ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-500f, 500f), ((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(-150f, 150f));
                        Projectile.universeScreen.fireTrailParticles.AddParticleThreadA(center, random);
                    }
                }
                else if (this.WeaponType == "Ballistic Cannon")
                {
                    ShipModule SMtarget = target as ShipModule;
                    if (SMtarget != null && SMtarget.ModuleType != ShipModuleType.Shield)
                    {
                        Cue impact = AudioManager.GetCue("sd_impact_bullet_small_01");
                        impact.Apply3D(Projectile.universeScreen.listener, this.emitter);
                        impact.Play();
                    }
                }
            }
            this.DieNextFrame = true;
            return base.Touch(target);
        }
 public override void Die(GameplayObject source, bool cleanupOnly)
 {
     DebugInfoScreen.ProjDied = DebugInfoScreen.ProjDied + 1;
     if (this.Active)
     {
         Vector3 vector3 = new Vector3(this.Center.X, this.Center.Y, -100f);
         Vector3 vector31 = new Vector3(this.velocity.X, base.Velocity.Y, 0f);
         if (this.light != null)
         {
             lock (GlobalStats.ObjectManagerLocker)
             {
                 Projectile.universeScreen.ScreenManager.inter.LightManager.Remove(this.light);
             }
         }
         if (!string.IsNullOrEmpty(this.InFlightCue) && this.inFlight != null)
         {
             this.inFlight.Stop(AudioStopOptions.Immediate);
         }
         if (this.explodes)
         {
             if (this.weapon.OrdinanceRequiredToFire > 0f && this.Owner != null)
             {
                 this.damageAmount += this.Owner.loyalty.data.OrdnanceEffectivenessBonus * this.damageAmount;
                 this.damageRadius += this.Owner.loyalty.data.OrdnanceEffectivenessBonus * this.damageRadius;
             }
             if (this.WeaponType == "Photon")
             {
                 if (!string.IsNullOrEmpty(this.dieCueName))
                 {
                     this.dieCue = AudioManager.GetCue(this.dieCueName);
                 }
                 if (this.dieCue != null)
                 {
                     this.dieCue.Apply3D(GameplayObject.audioListener, this.emitter);
                     this.dieCue.Play();
                 }
                 if (!cleanupOnly && Projectile.universeScreen.viewState <= UniverseScreen.UnivScreenState.SystemView)
                 {
                     ExplosionManager.AddProjectileExplosion(new Vector3(base.Position, -50f), this.damageRadius * 4.5f, 2.5f, 0.2f, this.weapon.ExpColor);
                     Projectile.universeScreen.flash.AddParticleThreadB(new Vector3(base.Position, -50f), Vector3.Zero);
                 }
                 if (this.system == null)
                 {
                     UniverseScreen.DeepSpaceManager.ProjectileExplode(this, this.damageAmount, this.damageRadius);
                 }
                 else
                 {
                     this.system.spatialManager.ProjectileExplode(this, this.damageAmount, this.damageRadius);
                 }
             }
             else if (!string.IsNullOrEmpty(this.dieCueName))
             {
                 if (Projectile.universeScreen.viewState <= UniverseScreen.UnivScreenState.SystemView)
                 {
                     this.dieCue = AudioManager.GetCue(this.dieCueName);
                     if (this.dieCue != null)
                     {
                         this.dieCue.Apply3D(GameplayObject.audioListener, this.emitter);
                         this.dieCue.Play();
                     }
                 }
                 if (!cleanupOnly && Projectile.universeScreen.viewState <= UniverseScreen.UnivScreenState.SystemView)
                 {
                     ExplosionManager.AddExplosion(new Vector3(base.Position, -50f), this.damageRadius * this.explosionradiusmod, 2.5f, 0.2f);
                     if (this.flashExplode)
                     {
                         Projectile.universeScreen.flash.AddParticleThreadB(new Vector3(base.Position, -50f), Vector3.Zero);
                     }
                 }
                 if (this.system == null)
                 {
                     UniverseScreen.DeepSpaceManager.ProjectileExplode(this, this.damageAmount, this.damageRadius);
                 }
                 else
                 {
                     this.system.spatialManager.ProjectileExplode(this, this.damageAmount, this.damageRadius);
                 }
             }
             else if (this.system == null)
             {
                 UniverseScreen.DeepSpaceManager.ProjectileExplode(this, this.damageAmount, this.damageRadius);
             }
             else
             {
                 this.system.spatialManager.ProjectileExplode(this, this.damageAmount, this.damageRadius);
             }
         }
         else if (this.weapon.FakeExplode && Projectile.universeScreen.viewState <= UniverseScreen.UnivScreenState.SystemView)
         {
             ExplosionManager.AddExplosion(new Vector3(base.Position, -50f), this.damageRadius * this.explosionradiusmod, 2.5f, 0.2f);
             if (this.flashExplode)
             {
                 Projectile.universeScreen.flash.AddParticleThreadB(new Vector3(base.Position, -50f), Vector3.Zero);
             }
         }
     }
     if (this.ProjSO != null && this.Active)
     {
         lock (GlobalStats.ObjectManagerLocker)
         {
             Projectile.universeScreen.ScreenManager.inter.ObjectManager.Remove(this.ProjSO);
         }
         this.ProjSO.Clear();
     }
     if (this.droneAI != null)
     {
         foreach (Beam beam in this.droneAI.Beams)
         {
             beam.Die(this, true);
         }
         this.droneAI.Beams.Clear();
     }
     if (this.muzzleFlashAdded)
     {
         lock (GlobalStats.ObjectManagerLocker)
         {
             Projectile.universeScreen.ScreenManager.inter.LightManager.Remove(this.MuzzleFlash);
         }
     }
     if (this.system == null)
     {
         UniverseScreen.DeepSpaceManager.CollidableProjectiles.QueuePendingRemoval(this);
     }
     else
     {
         this.system.spatialManager.CollidableProjectiles.QueuePendingRemoval(this);
     }
     base.Die(source, cleanupOnly);
 }
 protected virtual void CreateProjectiles(Vector2 direction, GameplayObject target, bool playSound)
 {
     if (target != null && (target is ShipModule) && (target as ShipModule).GetParent().Role == "fighter" && this.AltFireMode && this.AltFireTriggerFighter && this.SecondaryFire != null)
     {
         Weapon AltFire = ResourceManager.GetWeapon(this.SecondaryFire);
         Projectile projectile;
         if (this.owner.Projectiles.pendingRemovals.TryPop(out projectile))
         {
             projectile.ProjectileRecreate(this.owner, direction, this.moduleAttachedTo);
             projectile.range = AltFire.Range;
             projectile.weapon = this;
             projectile.explodes = AltFire.explodes;
             projectile.damageAmount = AltFire.DamageAmount;
             projectile.damageRadius = AltFire.DamageRadius;
             projectile.explosionradiusmod = AltFire.ExplosionRadiusVisual;
             projectile.Health = AltFire.HitPoints;
             projectile.speed = AltFire.ProjectileSpeed;
             projectile.WeaponEffectType = AltFire.WeaponEffectType;
             projectile.WeaponType = AltFire.WeaponType;
             projectile.RotationRadsPerSecond = AltFire.RotationRadsPerSecond;
             projectile.ArmorPiercing = (byte)AltFire.ArmourPen;
         }
         else
             projectile = new Projectile(this.owner, direction, this.moduleAttachedTo)
             {
                 range = AltFire.Range,
                 weapon = this,
                 explodes = AltFire.explodes,
                 damageAmount = AltFire.DamageAmount,
                 damageRadius = AltFire.DamageRadius,
                 explosionradiusmod = AltFire.ExplosionRadiusVisual,
                 Health = AltFire.HitPoints,
                 speed = AltFire.ProjectileSpeed,
                 WeaponEffectType = AltFire.WeaponEffectType,
                 WeaponType = AltFire.WeaponType,
                 RotationRadsPerSecond = AltFire.RotationRadsPerSecond,
                 ArmorPiercing = (byte)AltFire.ArmourPen,
             };
         //damage increase by level
         if (this.owner.Level > 0)
         {
             projectile.damageAmount += projectile.damageAmount * (float)this.owner.Level * 0.05f;
         }
         if (AltFire.RangeVariance)
         {
             projectile.range *= RandomMath.RandomBetween(0.9f, 1.1f);
         }
         //Hull bonus damage increase
         if (GlobalStats.ActiveModInfo != null && GlobalStats.ActiveModInfo.useHullBonuses)
         {
             HullBonus mod;
             if (ResourceManager.HullBonuses.TryGetValue(this.owner.shipData.Hull, out mod))
                 projectile.damageAmount += projectile.damageAmount * mod.DamageBonus;
         }
         projectile.LoadContent(AltFire.ProjectileTexturePath, AltFire.ModelPath);
         AltFire.ModifyProjectile(projectile);
         if (AltFire.Tag_Guided)
             projectile.InitializeMissile(projectile.speed, direction, target);
         else
             projectile.Initialize(projectile.speed, direction, this.moduleAttachedTo.Center);
         projectile.Radius = this.ProjectileRadius;
         if (AltFire.Animated == 1)
         {
             string remainder = 0.ToString("00000.##");
             projectile.texturePath = string.Concat(AltFire.AnimationPath, remainder);
         }
         //if(HelperFunctions.GetRandomIndex((int)(Ship.universeScreen.Lag *100)) <2)
         if (Weapon.universeScreen.viewState == UniverseScreen.UnivScreenState.ShipView && this.owner.InFrustum && playSound)
         {
             projectile.DieSound = true;
             if (!string.IsNullOrEmpty(this.ToggleSoundName) && (this.ToggleCue == null || this.ToggleCue != null && !this.ToggleCue.IsPlaying))
             {
                 this.ToggleSoundOn = true;
                 this.ToggleCue = AudioManager.GetCue(AltFire.ToggleSoundName);
                 this.ToggleCue.Apply3D(Weapon.audioListener, this.owner.emitter);
                 this.ToggleCue.Play();
                 if (AltFire.fireCue != null)
                 {
                     //Added by McShooterz: Use sounds from new sound dictionary
                     SoundEffect soundeffect = null;
                     if (ResourceManager.SoundEffectDict.TryGetValue(AltFire.fireCueName,out soundeffect))
                     {
                         AudioManager.PlaySoundEffect(soundeffect, Weapon.audioListener, this.owner.emitter, 0.5f);
                     }
                     else
                     {
                         this.fireCue = AudioManager.GetCue(this.fireCueName);
                         if (!this.owner.isPlayerShip())
                         {
                             this.fireCue.Apply3D(Weapon.audioListener, this.owner.emitter);
                         }
                         this.lastFireSound = 0f;
                         if (this.fireCue != null)
                         {
                             this.fireCue.Play();
                         }
                     }
                 }
             }
             if (!string.IsNullOrEmpty(ResourceManager.WeaponsDict[AltFire.UID].dieCue))
             {
                 projectile.dieCueName = ResourceManager.WeaponsDict[AltFire.UID].dieCue;
             }
             if (!string.IsNullOrEmpty(this.InFlightCue))
             {
                 projectile.InFlightCue = AltFire.InFlightCue;
             }
             if (this.ToggleCue == null && this.owner.ProjectilesFired.Count < 30)
             {
                 this.lastFireSound = 0f;
                 this.owner.ProjectilesFired.Add(new ProjectileTracker());
                 //Added by McShooterz: Use sounds from new sound dictionary
                 if (ResourceManager.SoundEffectDict.ContainsKey(AltFire.fireCueName))
                 {
                     AudioManager.PlaySoundEffect(ResourceManager.SoundEffectDict[fireCueName], Weapon.audioListener, this.owner.emitter, 0.5f);
                 }
                 else
                 {
                     this.fireCue = AudioManager.GetCue(this.fireCueName);
                     if (!this.owner.isPlayerShip())
                     {
                         this.fireCue.Apply3D(Weapon.audioListener, this.owner.emitter);
                     }
                     if (this.fireCue != null)
                     {
                         this.fireCue.Play();
                     }
                 }
             }
         }
         projectile.isSecondary = true;
         this.owner.Projectiles.Add(projectile);
         projectile = null;
     }
     else
     {
         Projectile projectile;
         if (this.owner.Projectiles.pendingRemovals.TryPop(out projectile))
         {
             projectile.ProjectileRecreate(this.owner, direction, this.moduleAttachedTo);
             projectile.range = this.Range;
             projectile.weapon = this;
             projectile.explodes = this.explodes;
             projectile.damageAmount = this.DamageAmount;
             projectile.damageRadius = this.DamageRadius;
             projectile.explosionradiusmod = this.ExplosionRadiusVisual;
             projectile.Health = this.HitPoints;
             projectile.speed = this.ProjectileSpeed;
             projectile.WeaponEffectType = this.WeaponEffectType;
             projectile.WeaponType = this.WeaponType;
             projectile.RotationRadsPerSecond = this.RotationRadsPerSecond;
             projectile.ArmorPiercing = (byte)this.ArmourPen;
         }
         projectile = new Projectile(this.owner, direction, this.moduleAttachedTo)
         {
             range = this.Range,
             weapon = this,
             explodes = this.explodes,
             damageAmount = this.DamageAmount,
             damageRadius = this.DamageRadius,
             explosionradiusmod = this.ExplosionRadiusVisual,
             Health = this.HitPoints,
             speed = this.ProjectileSpeed,
             WeaponEffectType = this.WeaponEffectType,
             WeaponType = this.WeaponType,
             RotationRadsPerSecond = this.RotationRadsPerSecond,
             ArmorPiercing = (byte)this.ArmourPen,
         };
         //damage increase by level
         if (this.owner.Level > 0)
         {
             projectile.damageAmount += projectile.damageAmount * (float)this.owner.Level * 0.05f;
         }
         if (this.RangeVariance)
         {
             projectile.range *= RandomMath.RandomBetween(0.9f, 1.1f);
         }
         //Hull bonus damage increase
         if (GlobalStats.ActiveModInfo != null && GlobalStats.ActiveModInfo.useHullBonuses)
         {
             HullBonus mod;
             if (ResourceManager.HullBonuses.TryGetValue(this.owner.shipData.Hull, out mod))
                 projectile.damageAmount += projectile.damageAmount * mod.DamageBonus;
         }
         projectile.LoadContent(this.ProjectileTexturePath, this.ModelPath);
         this.ModifyProjectile(projectile);
         if (this.Tag_Guided)
             projectile.InitializeMissile(projectile.speed, direction, target);
         else
             projectile.Initialize(projectile.speed, direction, this.moduleAttachedTo.Center);
         projectile.Radius = this.ProjectileRadius;
         if (this.Animated == 1)
         {
             string remainder = 0.ToString("00000.##");
             projectile.texturePath = string.Concat(this.AnimationPath, remainder);
         }
         if (Weapon.universeScreen.viewState == UniverseScreen.UnivScreenState.ShipView && this.owner.InFrustum && playSound)
         {
             projectile.DieSound = true;
             if (!string.IsNullOrEmpty(this.ToggleSoundName) && (this.ToggleCue == null || this.ToggleCue != null && !this.ToggleCue.IsPlaying))
             {
                 this.ToggleSoundOn = true;
                 this.ToggleCue = AudioManager.GetCue(this.ToggleSoundName);
                 this.ToggleCue.Apply3D(Weapon.audioListener, this.owner.emitter);
                 this.ToggleCue.Play();
                 if (this.fireCue != null)
                 {
                     //Added by McShooterz: Use sounds from new sound dictionary
                     if (ResourceManager.SoundEffectDict.ContainsKey(this.fireCueName))
                     {
                         AudioManager.PlaySoundEffect(ResourceManager.SoundEffectDict[fireCueName], Weapon.audioListener, this.owner.emitter, 0.5f);
                     }
                     else
                     {
                         this.fireCue = AudioManager.GetCue(this.fireCueName);
                         if (!this.owner.isPlayerShip())
                         {
                             this.fireCue.Apply3D(Weapon.audioListener, this.owner.emitter);
                         }
                         this.lastFireSound = 0f;
                         if (this.fireCue != null)
                         {
                             this.fireCue.Play();
                         }
                     }
                 }
             }
             if (!string.IsNullOrEmpty(ResourceManager.WeaponsDict[this.UID].dieCue))
             {
                 projectile.dieCueName = ResourceManager.WeaponsDict[this.UID].dieCue;
             }
             if (!string.IsNullOrEmpty(this.InFlightCue))
             {
                 projectile.InFlightCue = this.InFlightCue;
             }
             if (this.ToggleCue == null && this.owner.ProjectilesFired.Count < 30)
             {
                 this.lastFireSound = 0f;
                 this.owner.ProjectilesFired.Add(new ProjectileTracker());
                 //Added by McShooterz: Use sounds from new sound dictionary
                 if (ResourceManager.SoundEffectDict.ContainsKey(this.fireCueName))
                 {
                     AudioManager.PlaySoundEffect(ResourceManager.SoundEffectDict[fireCueName], Weapon.audioListener, this.owner.emitter, 0.5f);
                 }
                 else
                 {
                     this.fireCue = AudioManager.GetCue(this.fireCueName);
                     if (!this.owner.isPlayerShip())
                     {
                         this.fireCue.Apply3D(Weapon.audioListener, this.owner.emitter);
                     }
                     if (this.fireCue != null)
                     {
                         this.fireCue.Play();
                     }
                 }
             }
         }
         this.owner.Projectiles.Add(projectile);
         projectile = null;
     }
 }
        public virtual void Update(float elapsedTime)
        {
            this.lastFireSound += elapsedTime;
            if (this.timeToNextFire > 0f)
            {
                this.timeToNextFire = MathHelper.Max(this.timeToNextFire - elapsedTime, 0f);
            }
            foreach (Weapon.Salvo salvo in this.SalvoList)
            {
                salvo.Timing -= elapsedTime;
                if (salvo.Timing > 0f)
                {
                    continue;
                }
                //this.FireSalvo(salvo.Direction, this.SalvoTarget);

                if (this.SalvoTarget !=null && this.owner.CheckIfInsideFireArc(this,SalvoTarget))
                {
                    if (this.Tag_Guided)
                        this.FireSalvo(salvo.Direction, SalvoTarget);
                    else
                        this.GetOwner().GetAI().CalculateAndFire(this, SalvoTarget, true);
                }
                else if (this.SalvoTarget != null)
                    this.FireSalvo(salvo.Direction, null);
                this.SalvoList.QueuePendingRemoval(salvo);
            }
            this.SalvoList.ApplyPendingRemovals();
            if (this.SalvoList.Count == 0)
                this.SalvoTarget = null;
            this.Center = this.moduleAttachedTo.Center;
        }
 public virtual void FireSalvo(Vector2 direction, GameplayObject target)
 {
     if (this.owner.engineState == Ship.MoveState.Warp ) //|| (this.owner !=null && this.owner.CheckIfInsideFireArc(this,target)))
     {
         return;
     }
     this.owner.InCombatTimer = 15f;
     if (this.moduleAttachedTo.Active && this.owner.PowerCurrent > this.PowerRequiredToFire && this.OrdinanceRequiredToFire <= this.owner.Ordinance)
     {
         this.owner.Ordinance -= this.OrdinanceRequiredToFire;
         this.owner.PowerCurrent -= this.PowerRequiredToFire;
         if (this.FireArc != 0)
         {
             float DegreesBetweenShots = (float)(this.FireArc / this.ProjectileCount);
             float angleToTarget = this.findAngleToTarget(direction);
             for (int i = 0; i < this.ProjectileCount; i++)
             {
                 Vector2 newTarget = this.findTargetFromAngleAndDistance(this.moduleAttachedTo.Center, angleToTarget - (float)(this.FireArc / 2) + DegreesBetweenShots * (float)i, this.Range);
                 Vector2 fireDirection = this.findVectorToTarget(this.moduleAttachedTo.Center, newTarget);
                 fireDirection.Y = fireDirection.Y * -1f;
                 this.CreateProjectiles(Vector2.Normalize(fireDirection), target, !this.PlaySoundOncePerSalvo);
             }
             return;
         }
         if (this.FireCone > 0)
         {
             float spread = RandomMath2.RandomBetween((float)(-this.FireCone / 2), (float)(this.FireCone / 2));
             float angleToTarget = this.findAngleToTarget(direction);
             Vector2 newTarget = this.findTargetFromAngleAndDistance(this.moduleAttachedTo.Center, angleToTarget + spread, this.Range);
             Vector2 fireDirection = this.findVectorToTarget(this.moduleAttachedTo.Center, newTarget);
             fireDirection.Y = fireDirection.Y * -1f;
             this.CreateProjectiles(Vector2.Normalize(fireDirection), target, !this.PlaySoundOncePerSalvo);
             return;
         }
         for (int i = 0; i < this.ProjectileCount; i++)
         {
             this.CreateProjectiles(direction, target, !this.PlaySoundOncePerSalvo);
         }
         return;
     }
 }
        private void FireOnTargetNonVisible(Weapon w, GameplayObject fireTarget)
        {
            if (this.Owner.Ordinance < w.OrdinanceRequiredToFire || this.Owner.PowerCurrent < w.PowerRequiredToFire)
            {
                return;
            }
            w.timeToNextFire = w.fireDelay;
            if (w.IsRepairDrone)
            {
                return;
            }
            if (TargetShip == null || !TargetShip.Active || TargetShip.dying || !w.TargetValid(TargetShip.Role)
                || TargetShip.engineState == Ship.MoveState.Warp || !this.Owner.CheckIfInsideFireArc(w, TargetShip))
                return;
            Ship owner = this.Owner;
            owner.Ordinance = owner.Ordinance - w.OrdinanceRequiredToFire;
            Ship powerCurrent = this.Owner;
            powerCurrent.PowerCurrent = powerCurrent.PowerCurrent - w.PowerRequiredToFire;
            powerCurrent.PowerCurrent -= w.BeamPowerCostPerSecond * w.BeamDuration;

            this.Owner.InCombatTimer = 15f;
            if (fireTarget is Projectile)
            {
                fireTarget.Damage(w.GetOwner(), w.DamageAmount);
                return;
            }
            if (!(fireTarget is Ship))
            {
                if (fireTarget is ShipModule)
                {
                    w.timeToNextFire = w.fireDelay;
                    IOrderedEnumerable<ModuleSlot> sortedList =
                        from slot in (fireTarget as ShipModule).GetParent().ExternalSlots
                        orderby Vector2.Distance(slot.module.Center, this.Owner.Center)
                        select slot;
                    float damage = w.DamageAmount;
                    if (w.isBeam)
                    {
                        damage = damage * 90f;
                    }
                    if (w.SalvoCount > 0)
                    {
                        damage = damage * (float)w.SalvoCount;
                    }
                    sortedList.First<ModuleSlot>().module.Damage(this.Owner, damage);
                }
                return;
            }
            w.timeToNextFire = w.fireDelay;
            if ((fireTarget as Ship).ExternalSlots.Count == 0)
            {
                (fireTarget as Ship).Die(null, true);
                return;
            }
            float nearest = 0;
            ModuleSlot ClosestES = null;
            foreach (ModuleSlot ES in (fireTarget as Ship).ExternalSlots)
            {
                if (ES.module.ModuleType == ShipModuleType.Dummy || !ES.module.Active || ES.module.Health <= 0)
                    continue;
                float temp = Vector2.Distance(ES.module.Center, w.GetOwner().Center);
                if (nearest == 0 || temp < nearest)
                {
                    nearest = temp;
                    ClosestES = ES;
                }
            }
            if (ClosestES == null)
                return;
            // List<ModuleSlot>
            IEnumerable<ModuleSlot> ExternalSlots = (fireTarget as Ship).ExternalSlots.Where(close => close.module.Active && close.module.quadrant == ClosestES.module.quadrant && close.module.Health > 0);//.ToList();   //.OrderByDescending(shields=> shields.Shield_Power >0);//.ToList();
            if ((fireTarget as Ship).shield_power > 0f)
            {
                for (int i = 0; i < (fireTarget as Ship).GetShields().Count; i++)
                {
                    if ((fireTarget as Ship).GetShields()[i].Active && (fireTarget as Ship).GetShields()[i].shield_power > 0f)
                    {
                        float damage = w.DamageAmount;
                        if (w.isBeam)
                        {
                            damage = damage * 90f;
                        }
                        if (w.SalvoCount > 0)
                        {
                            damage = damage * (float)w.SalvoCount;
                        }
                        (fireTarget as Ship).GetShields()[i].Damage(this.Owner, damage);
                        return;
                    }
                }
                return;
            }
            //this.Owner.GetSystem() != null ? this.Owner.GetSystem().RNG : ArtificialIntelligence.universeScreen.DeepSpaceRNG)).RandomBetween(0f, 100f) <= 50f ||
            if (ExternalSlots.ElementAt(0).module.shield_power > 0f)
            {
                for (int i = 0; i < ExternalSlots.Count(); i++)
                {
                    if (ExternalSlots.ElementAt(i).module.Active && ExternalSlots.ElementAt(i).module.shield_power <= 0f)
                    {
                        float damage = w.DamageAmount;
                        if (w.isBeam)
                        {
                            damage = damage * 90f;
                        }
                        if (w.SalvoCount > 0)
                        {
                            damage = damage * (float)w.SalvoCount;
                        }
                        ExternalSlots.ElementAt(i).module.Damage(this.Owner, damage);
                        return;
                    }
                }
                return;
            }

            for (int i = 0; i < ExternalSlots.Count(); i++)
            {
                if (ExternalSlots.ElementAt(i).module.Active && ExternalSlots.ElementAt(i).module.shield_power <= 0f)
                {
                    float damage = w.DamageAmount;
                    if (w.isBeam)
                    {
                        damage = damage * 90f;
                    }
                    if (w.SalvoCount > 0)
                    {
                        damage = damage * (float)w.SalvoCount;
                    }
                    ExternalSlots.ElementAt(i).module.Damage(this.Owner, damage);
                    return;
                }
            }
        }
 private Vector2 findVectorBehindTarget(GameplayObject ship, float distance)
 {
     Vector2 vector2 = new Vector2(0f, 0f);
     Vector2 forward = new Vector2((float)Math.Sin((double)ship.Rotation), -(float)Math.Cos((double)ship.Rotation));
     forward = Vector2.Normalize(forward);
     return ship.Position - (forward * distance);
 }
        private void DoCombat(float elapsedTime)
        {
            this.awaitClosest = null;
            this.State = AIState.Combat;
            this.Owner.InCombat = true;
            this.Owner.InCombatTimer = 15f;
            #region modified 07/28/15
            float radius = 30000f;                      //Added by Ermenildo V. Castro, Jr.; 07/28/15
            Vector2 senseCenter = this.Owner.Center;    //Added by Ermenildo V. Castro, Jr.; 07/28/15

            //If there is a target, and the target is inactive
            //remove inactive target from consideration
            if (this.Target != null && !this.Target.Active)
            {
                this.Target = null;
                this.Intercepting = false;
                if (!this.BadGuysNear) //Modified by Ermenildo V. Castro, Jr; 07/28/15: re-instated commented out conditional
                {
                    this.State = this.DefaultAIState;
                    this.OrderQueue.Clear();
                    this.Target = this.ScanForCombatTargets(senseCenter, radius); //Modified by Modified by Ermenildo V. Castro, Jr; 07/28/15; //this.Target = null;
                    if (Target != null) { this.PotentialTargets.Add((Ship)Target); }
                }
                return;

            }
            //if no target available
            if (this.Target == null )
            {
                this.Target = null;
                this.Intercepting = false;
                this.ScanForThreatTimer = 0;
                if (!this.BadGuysNear) //Modified by Ermenildo V. Castro, Jr; 07/28/15: re-instated commented out conditional
                {
                    this.OrderQueue.Clear();
                    this.State = this.DefaultAIState;
                    this.Target = this.ScanForCombatTargets(senseCenter, radius); //Modified by Modified by Ermenildo V. Castro, Jr; 07/28/15; //this.Target = null;
                    if (Target != null) { this.PotentialTargets.Add((Ship)Target); }

                }
                return;

            }
            #endregion

            if (this.Owner.Mothership != null && this.Owner.Mothership.Active)
            {

                //if (!this.hasPriorityTarget
                //    && !this.HasPriorityOrder&& this.Target != null
                //    && this.Owner.Mothership.GetAI().Target == null
                //    && !this.Owner.Mothership.GetAI().HasPriorityOrder
                //    && !this.Owner.Mothership.GetAI().hasPriorityTarget)
                //{
                //    this.Owner.Mothership.GetAI().Target = this.Target;
                //    this.Owner.Mothership.GetAI().State = AIState.Combat;
                //    this.Owner.Mothership.InCombatTimer = 15f;
                //}
                if(this.Owner.Role != "troop"
                    && (this.Owner.Health/ this.Owner.HealthMax <.5f || (this.Owner.shield_max>0 && this.Owner.shield_percent <=0.0))
                    || (this.Owner.OrdinanceMax > 0 && this.Owner.Ordinance / this.Owner.OrdinanceMax <= .1f)
                    || (this.Owner.PowerCurrent <=1f && this.Owner.PowerDraw / this.Owner.PowerFlowMax <=.1f)
                    )
                    this.OrderReturnToHangar();
            }
            if (this.Owner.OrdinanceMax > 0f && this.Owner.Ordinance / this.Owner.OrdinanceMax < 0.05f &&  !this.hasPriorityTarget)//this.Owner.loyalty != ArtificialIntelligence.universeScreen.player)
            {
                if (FriendliesNearby.Where(supply => supply.HasSupplyBays && supply.Ordinance >= 100).Count() == 0)
                {
                    this.OrderResupplyNearest();
                    return;
                }
            }
            if(this.Owner.Level >2 && this.Owner.Health / this.Owner.HealthMax <.5f&&  !(this.HasPriorityOrder||this.hasPriorityTarget))
            {
                                 this.OrderResupplyNearest();
                    return;
            }
            if (Vector2.Distance(this.Target.Center, this.Owner.Center) < 10000f)
            {
                if (this.Owner.engineState != Ship.MoveState.Warp && this.Owner.GetHangars().Count > 0 && !this.Owner.ManualHangarOverride)
                {
                    if (!this.Owner.FightersOut) this.Owner.FightersOut = true;
                }
                if (this.Owner.engineState == Ship.MoveState.Warp)
                {
                    this.Owner.HyperspaceReturn();
                }

            }
            else if (this.CombatState != CombatState.HoldPosition && this.CombatState != CombatState.Evade)
            {
                this.ThrustTowardsPosition(this.Target.Center, elapsedTime, this.Owner.speed);
                return;
            }
            if (!this.HasPriorityOrder && !this.hasPriorityTarget && this.Owner.Weapons.Count == 0 && this.Owner.GetHangars().Count == 0)
            {
                this.CombatState = CombatState.Evade;
            }
            if (!this.Owner.loyalty.isFaction && this.Owner.GetSystem() != null && this.TroopsOut == false && this.Owner.GetHangars().Where(troops => troops.IsTroopBay).Count() > 0 || this.Owner.hasTransporter)
            {
                if (this.Owner.TroopList.Where(troop => troop.GetOwner() == this.Owner.loyalty).Count() > 0 && this.Owner.TroopList.Where(troop => troop.GetOwner() != this.Owner.loyalty).Count() == 0)
                {
                    Planet invadeThis = null;
                    foreach (Planet invade in this.Owner.GetSystem().PlanetList.Where(owner => owner.Owner != null && owner.Owner != this.Owner.loyalty).OrderBy(troops => troops.TroopsHere.Count))
                    {
                        if (this.Owner.loyalty.GetRelations()[invade.Owner].AtWar)
                        {
                            invadeThis = invade;
                            break;
                        }
                    }
                    if (!this.TroopsOut && !this.Owner.hasTransporter)
                    {
                        if (invadeThis != null)
                        {
                            this.TroopsOut = true;
                            foreach (Ship troop in this.Owner.GetHangars().Where(troop => troop.IsTroopBay && troop.GetHangarShip() != null).Select(ship => ship.GetHangarShip()))
                            {
                                troop.GetAI().OrderAssaultPlanet(invadeThis);
                            }
                        }
                        else if (this.Target != null && this.Target is Ship && (this.Target as Ship).Role == "frigate" || (this.Target as Ship).Role == "carrier" || (this.Target as Ship).Role == "corvette" || (this.Target as Ship).Role == "cruiser" || (this.Target as Ship).Role == "capital")
                        {
                            if (this.Owner.GetHangars().Where(troop => troop.IsTroopBay).Count() * 60 >= (this.Target as Ship).MechanicalBoardingDefense)
                            {
                                this.TroopsOut = true;
                                foreach (ShipModule hangar in this.Owner.GetHangars())
                                {
                                    if (hangar.GetHangarShip() == null || this.Target == null || !(hangar.GetHangarShip().Role == "troop") || !((this.Target as Ship).Role == "frigate") && !((this.Target as Ship).Role == "carrier") && !((this.Target as Ship).Role == "corvette") && !((this.Target as Ship).Role == "cruiser") && !((this.Target as Ship).Role == "capital"))
                                    {
                                        continue;
                                    }
                                    hangar.GetHangarShip().GetAI().OrderTroopToBoardShip(this.Target as Ship);
                                }
                            }
                        }
                        else
                        {
                            this.TroopsOut = false;
                        }
                    }

                }
            }
            //if this ship does not belong to a fleet
            #region
            if (this.Owner.fleet == null)
            {
                switch (this.CombatState)
                {
                    case CombatState.Artillery:
                        {
                            this.DoNonFleetArtillery(elapsedTime);
                            break;
                        }
                    case CombatState.OrbitLeft:
                        {
                            this.OrbitShipLeft(this.Target as Ship, elapsedTime);
                            break;
                        }
                    case CombatState.BroadsideLeft:
                        {
                            this.DoNonFleetBroadsideLeft(elapsedTime);
                            break;
                        }
                    case CombatState.OrbitRight:
                        {
                            this.OrbitShip(this.Target as Ship, elapsedTime);
                            break;
                        }
                    case CombatState.BroadsideRight:
                        {
                            this.DoNonFleetBroadsideRight(elapsedTime);
                            break;
                        }
                    case CombatState.AttackRuns:
                        {
                            this.DoAttackRun(elapsedTime);
                            break;
                        }
                    case CombatState.HoldPosition:
                        {
                            this.DoHoldPositionCombat(elapsedTime);
                            break;
                        }
                    case CombatState.Evade:
                        {
                            this.DoEvadeCombat(elapsedTime);
                            break;
                        }
                    case CombatState.AssaultShip:
                        {
                            this.DoAssaultShipCombat(elapsedTime);
                            break;
                        }
                }
            }
            #endregion
            //if ship belongs to a fleet
            #region
            else if (this.Owner.fleet != null)
            {
                switch (this.CombatState)
                {
                    case CombatState.Artillery:
                        {
                            this.DoNonFleetArtillery(elapsedTime);
                            break;
                        }
                    case CombatState.OrbitLeft:
                        {
                            this.OrbitShipLeft(this.Target as Ship, elapsedTime);
                            break;
                        }
                    case CombatState.BroadsideLeft:
                        {
                            this.DoNonFleetBroadsideLeft(elapsedTime);
                            break;
                        }
                    case CombatState.OrbitRight:
                        {
                            this.OrbitShip(this.Target as Ship, elapsedTime);
                            break;
                        }
                    case CombatState.BroadsideRight:
                        {
                            this.DoNonFleetBroadsideRight(elapsedTime);
                            break;
                        }
                    case CombatState.AttackRuns:
                        {
                            this.DoAttackRun(elapsedTime);
                            break;
                        }
                    case CombatState.HoldPosition:
                        {
                            this.DoHoldPositionCombat(elapsedTime);
                            break;
                        }
                    case CombatState.Evade:
                        {
                            this.DoEvadeCombat(elapsedTime);
                            break;
                        }
                    case CombatState.AssaultShip:
                        {
                            this.DoAssaultShipCombat(elapsedTime);
                            break;
                        }
                }
                if (this.Target != null)
                    return;
                this.Owner.InCombat = false;
            }
            #endregion
        }
        //(float elapsedTime)
        public void FireOnTarget()
        {
            //Reasons not to fire
            //try
            {
                TargetShip = this.Target as Ship;
                Relationship enemy =null;
                if (!this.Owner.hasCommand ||this.Owner.engineState == Ship.MoveState.Warp || this.Owner.disabled || this.Owner .Weapons.Count==0 ||
                    ((TargetShip != null && !this.Owner.loyalty.isFaction) && (this.Owner.loyalty.GetRelations().TryGetValue(TargetShip.loyalty, out enemy)
                    && enemy != null && (enemy.Treaty_Peace || enemy.Treaty_Alliance || enemy.Treaty_NAPact))))
                {
                    return;
                }

                //Determine if there is something to shoot at
                if (this.BadGuysNear || this.Owner.InCombat)
                {
                    //Target is dead or dying, will need a new one.
                    if (this.Target != null && (!this.Target.Active || TargetShip != null && TargetShip.dying))
                    {
                        this.Target = null;
                        TargetShip = null;
                    }
                    this.TrackProjectiles.Clear();
                    //update projectile list
                    {

                        if (this.Owner.GetSystem() != null)
                        {
                            //Find non friendly planets
                            foreach (Planet p in this.Owner.GetSystem().PlanetList)
                            {
                                if (p.Owner == this.Owner.loyalty)
                                    continue;
                                foreach (Projectile proj in p.Projectiles)
                                {
                                    this.TrackProjectiles.Add(proj);
                                }
                            }
                        }
                        {
                            foreach (Ship ship in PotentialTargets)
                            {

                                for (int i = 0; i < ship.Projectiles.Count; i++)
                                {
                                    Projectile proj;
                                    {
                                        proj = ship.Projectiles[i];
                                    }

                                    if (proj == null || !proj.Active || proj.Health <= 0 || !proj.weapon.Tag_Intercept)
                                        continue;
                                    this.TrackProjectiles.Add(proj);
                                }

                            }

                        }
                        this.TrackProjectiles = this.TrackProjectiles.OrderBy(prj => Vector2.Distance(this.Owner.Center, prj.Center)).ToList();

                    }
                    float lag = Ship.universeScreen.Lag;
                    //Go through each weapon
                    float index = 0; //count up weapons.
                    //save target ship if it is a ship.
                    this.TargetShip = this.Target as Ship;
                    //group of weapons into chunks per thread available
                    var source = Enumerable.Range(0, this.Owner.Weapons.Count).ToArray();
                            var rangePartitioner = Partitioner.Create(0, source.Length);
                    //handle each weapon group in parallel
                            Parallel.ForEach(rangePartitioner, (range, loopState) =>
                                           {
                                               //standard for loop through each weapon group.
                                               for (int T = range.Item1; T < range.Item2; T++)
                                               {
                                                   Weapon weapon = this.Owner.Weapons[T];
                                                   //Reasons for this weapon not to fire
                                                   if ( !weapon.moduleAttachedTo.Active || weapon.timeToNextFire > 0f || !weapon.moduleAttachedTo.Powered || weapon.IsRepairDrone || weapon.isRepairBeam)
                                                   {
                                                       //continue;
                                                       return;
                                                   }
                                                   ShipModule moduletarget = weapon.fireTarget as ShipModule;
                                                   //if firing at the primary target mark weapon as firing on primary.
                                                   if (!(weapon.fireTarget is Projectile) &&( weapon.fireTarget == this.Target || (moduletarget !=null && (moduletarget.GetParent() as GameplayObject) ==this.Target)))
                                                       weapon.PrimaryTarget = true;
                                                    //check if weapon target as a gameplay object is still a valid target
                                                   if (weapon.fireTarget !=null )
                                                   {

                                                       if ( (weapon.PrimaryTarget && weapon.fireTarget != this.Target)
                                                           || !this.Owner.CheckIfInsideFireArc(weapon, weapon.fireTarget)
                                                           //check here if the weapon can fire on main target.
                                                           || (this.Target !=null &&(!weapon.PrimaryTarget && !(weapon.fireTarget is Projectile) && this.Owner.CheckIfInsideFireArc(weapon, this.Target) ))
                                                           )
                                                       {
                                                           weapon.TargetChangeTimer = .5f;
                                                           weapon.fireTarget = null;
                                                           if (weapon.isBeam || weapon.isMainGun)
                                                               weapon.TargetChangeTimer = .90f;
                                                           if (weapon.isTurret)
                                                               weapon.TargetChangeTimer *= .5f;
                                                           if(weapon.Tag_PD)
                                                           {
                                                               weapon.TargetChangeTimer *= .5f;
                                                           }

                                                       }

                                                   }
                                                   //if weapon target is null reset primary target and decrement target change timer.
                                                   if (weapon.fireTarget == null)
                                                   {
                                                       weapon.TargetChangeTimer -= 0.0167f;
                                                       if (weapon.PrimaryTarget != false)
                                                           weapon.PrimaryTarget = false;
                                                   }
                                                   //Reasons for this weapon not to fire
                                                   if (weapon.fireTarget == null && weapon.TargetChangeTimer >0 ) // ||!weapon.moduleAttachedTo.Active || weapon.timeToNextFire > 0f || !weapon.moduleAttachedTo.Powered || weapon.IsRepairDrone || weapon.isRepairBeam)
                                                   {
                                                       //continue;
                                                       return;
                                                   }
                                                   //main targeting loop. little check here to disable the whole thing for debugging.
                                                   if (true)
                                                   {
                                                       //Can this weapon fire on ships
                                                       if (this.BadGuysNear && !weapon.TruePD  )
                                                       {
                                                           //if there are projectile to hit and weapons that can shoot at them. do so.
                                                           if(this.TrackProjectiles.Count >0 && weapon.Tag_PD)
                                                           {
                                                               for (int i = 0; i < this.TrackProjectiles.Count; i++)
                                                               {
                                                                   Projectile proj;
                                                                   {
                                                                       proj = this.TrackProjectiles[i];
                                                                   }

                                                                   if (proj == null || !proj.Active || proj.Health <= 0 || !proj.weapon.Tag_Intercept)
                                                                       continue;
                                                                   if (this.Owner.CheckIfInsideFireArc(weapon, proj as GameplayObject))
                                                                   {
                                                                       weapon.fireTarget = proj;
                                                                       break;
                                                                   }
                                                               }
                                                           }
                                                           //Is primary target valid
                                                           if (weapon.fireTarget == null)
                                                           if (this.Owner.CheckIfInsideFireArc(weapon, this.Target))
                                                           {
                                                               weapon.fireTarget = this.Target;
                                                               weapon.PrimaryTarget = true;
                                                           }

                                                           //Find alternate target to fire on
                                                           //this seems to be very expensive code.
                                                           if (weapon.fireTarget == null)
                                                           {
                                                               //limit to one target per level.
                                                               for (int i = 0; i < this.PotentialTargets.Count && i < this.Owner.Level+1; i++) //
                                                               {
                                                                   Ship PotentialTarget = this.PotentialTargets[i];
                                                                   if (PotentialTarget == this.TargetShip
                                                                       || !this.Owner.CheckIfInsideFireArc(weapon, PotentialTarget))
                                                                   {
                                                                       continue;
                                                                   }
                                                                   weapon.fireTarget = PotentialTarget;
                                                                   break;

                                                               }
                                                           }
                                                           //If a ship was found to fire on, change to target an internal module if target is visible  || weapon.Tag_Intercept
                                                           if (weapon.fireTarget != null)
                                                           {
                                                               if (weapon.fireTarget is Ship && (GlobalStats.ForceFullSim || this.Owner.InFrustum || (weapon.fireTarget as Ship).InFrustum))// || (this.Owner.InFrustum || this.Target != null && TargetShip.InFrustum)))
                                                               {
                                                                   weapon.fireTarget = (weapon.fireTarget as Ship).GetRandomInternalModule(weapon);
                                                                   //weapon.fireTarget;// = fireTarget;
                                                               }

                                                           }
                                                       }
                                                       //No ship to target, check for projectiles
                                                       if (weapon.fireTarget == null && weapon.Tag_PD)
                                                       {

                                                           //projectile list is created in teh scan for combat combats method.
                                                           if (weapon.fireTarget == null)
                                                           {

                                                               for (int i = 0; i < this.TrackProjectiles.Count && i < this.Owner.Level+1;i++)
                                                               {
                                                                   Projectile proj;
                                                                   {
                                                                       proj = this.TrackProjectiles[i];
                                                                   }

                                                                   if (proj == null || !proj.Active || proj.Health <= 0 || !proj.weapon.Tag_Intercept)
                                                                       continue;
                                                                   if (this.Owner.CheckIfInsideFireArc(weapon, proj as GameplayObject))
                                                                   {
                                                                       weapon.fireTarget = proj;
                                                                       break;
                                                                   }
                                                               }

                                                           }

                                                       }

                                                   }

                                               }
                                           });
                    //this section actually fires the weapons. This whole firing section can be moved to some other area of the code. This code is very expensive.
                    if(1==1)
                    foreach (Weapon weapon in this.Owner.Weapons)
                    {
                        if (weapon.fireTarget != null &&(weapon.moduleAttachedTo.Active && weapon.timeToNextFire <= 0f && weapon.moduleAttachedTo.Powered ))
                        {
                            if (!(weapon.fireTarget is Ship))
                            {
                                GameplayObject target = weapon.fireTarget;
                                if (weapon.isBeam)
                                    weapon.FireTargetedBeam(target);
                                else if (weapon.Tag_Guided)
                                {
                                    if (index > 10 && lag > .03 && !GlobalStats.ForceFullSim && (!weapon.Tag_Intercept) && (weapon.fireTarget is ShipModule))
                                        this.FireOnTargetNonVisible(weapon, (weapon.fireTarget as ShipModule).GetParent());
                                    else
                                        weapon.Fire(new Vector2((float)Math.Sin((double)this.Owner.Rotation + MathHelper.ToRadians(weapon.moduleAttachedTo.facing)), -(float)Math.Cos((double)this.Owner.Rotation + MathHelper.ToRadians(weapon.moduleAttachedTo.facing))), target);
                                    index++;
                                }
                                else
                                {
                                    if (index > 10 && lag > .03 && !GlobalStats.ForceFullSim && (weapon.fireTarget is ShipModule))
                                        this.FireOnTargetNonVisible(weapon, (weapon.fireTarget as ShipModule).GetParent());
                                    else
                                        CalculateAndFire(weapon, target, false);
                                    index++;
                                }
                            }
                            else
                                this.FireOnTargetNonVisible(weapon, weapon.fireTarget);
                        }
                    }

                }
            }
            //catch (Exception e)
            {
            #if DEBUG
                //System.Diagnostics.Debug.WriteLine(e.InnerException);
            #endif

            }

            this.TargetShip = null;
        }
        //added by gremlin Devekmod AuUpdate(fixed)
        public void Update(float elapsedTime)
        {
            this.CombatAI.UpdateCombatAI(this.Owner);
            ArtificialIntelligence.ShipGoal toEvaluate;
            if (this.State == AIState.AwaitingOrders && this.DefaultAIState == AIState.Exterminate)
            {
                this.State = AIState.Exterminate;
            }
            if (this.Owner.Name == "Subspace Projector")
            {
                this.BadGuysNear = true;
                return;
            }
            if (this.ClearOrdersNext)
            {
                this.OrderQueue.Clear();
                this.ClearOrdersNext = false;
                this.State = AIState.AwaitingOrders;
            }
            List<Ship> ToRemove = new List<Ship>();
            foreach (Ship target in this.TargetQueue)
            {
                if (target.Active)
                {
                    continue;
                }
                ToRemove.Add(target);
            }
            foreach (Ship ship in ToRemove)
            {
                this.TargetQueue.Remove(ship);
            }
            if (!this.hasPriorityTarget)
            {
                this.TargetQueue.Clear();
            }
            if (this.Owner.loyalty == ArtificialIntelligence.universeScreen.player && (  this.State == AIState.MoveTo && Vector2.Distance(this.Owner.Center, this.MovePosition) > 100f || this.State == AIState.Orbit || (this.State == AIState.Bombard || this.State == AIState.AssaultPlanet || this.State == AIState.BombardTroops) || this.State == AIState.Rebase || this.State == AIState.Scrap || this.State == AIState.Resupply || this.State == AIState.Refit || this.State == AIState.FormationWarp))
            {
                this.HasPriorityOrder = true;
            }
            if (this.State == AIState.Resupply)
            {
                this.HasPriorityOrder = true;
                if (this.Owner.Ordinance >= this.Owner.OrdinanceMax)
                {
                    this.HasPriorityOrder = false;
                }
            }
            //if (this.State == AIState.Flee && !this.BadGuysNear)// Vector2.Distance(this.OrbitTarget.Position, this.Owner.Position) < this.Owner.SensorRange + 10000)
            //{
            //    if(this.OrderQueue.Count > 0)
            //        this.OrderQueue.Remove(this.OrderQueue.Last);
            //    if (this.Owner.CargoSpace_Used > 0)
            //        this.State = AIState.SystemTrader;
            //    else
            //        this.State = this.DefaultAIState;
            //}
            this.ScanForThreatTimer -=  elapsedTime;
            if (this.ScanForThreatTimer < 0f)
            {
                if (this.inOrbit == true )//&& !(this.State == AIState.Orbit ||                     this.State == AIState.Flee))
                {
                    this.inOrbit = false;
                }
                this.SetCombatStatus(elapsedTime);
                this.ScanForThreatTimer = 2f;
                if (this.Owner.loyalty.data.Traits.Pack)
                {
                    this.Owner.DamageModifier = -0.25f;
                    Ship owner = this.Owner;
                    owner.DamageModifier = owner.DamageModifier + 0.05f * (float)this.FriendliesNearby.Count;
                    if (this.Owner.DamageModifier > 0.5f)
                    {
                        this.Owner.DamageModifier = 0.5f;
                    }
                }
            }
            this.UtilityModuleCheckTimer -= elapsedTime;
            if (this.UtilityModuleCheckTimer <= 0f)
            {
                this.UtilityModuleCheckTimer = 1f;
                //Added by McShooterz: logic for transporter moduels
                if (this.Owner.hasTransporter)
                {
                    foreach (ShipModule module in this.Owner.Transporters)
                    {
                        if (module.TransporterTimer <= 0f && module.Active && module.Powered && module.TransporterPower < this.Owner.PowerCurrent)
                        {
                            if (this.FriendliesNearby.Count > 0 && module.TransporterOrdnance > 0 && this.Owner.Ordinance > 0)
                                this.DoOrdinanceTransporterLogic(module);
                            if (module.TransporterTroopAssault > 0 && this.Owner.TroopList.Count() > 0)
                                this.DoAssaultTransporterLogic(module);
                        }
                    }
                }
                //Do repair check if friendly ships around and no combat
                if (!this.Owner.InCombat && this.FriendliesNearby.Count > 0)
                {
                    //Added by McShooterz: logic for repair beams
                    if (this.Owner.hasRepairBeam)
                    {
                        foreach (ShipModule module in this.Owner.RepairBeams)
                        {
                            if (module.InstalledWeapon.timeToNextFire <= 0f && module.InstalledWeapon.moduleAttachedTo.Powered && this.Owner.Ordinance >= module.InstalledWeapon.OrdinanceRequiredToFire && this.Owner.PowerCurrent >= module.InstalledWeapon.PowerRequiredToFire)
                            {
                                this.DoRepairBeamLogic(module.InstalledWeapon);
                            }
                        }
                    }
                    if (this.Owner.HasRepairModule)
                    {
                        foreach (Weapon weapon in this.Owner.Weapons)
                        {
                            if (weapon.timeToNextFire > 0f || !weapon.moduleAttachedTo.Powered || this.Owner.Ordinance < weapon.OrdinanceRequiredToFire || this.Owner.PowerCurrent < weapon.PowerRequiredToFire || !weapon.IsRepairDrone)
                            {
                                continue;
                            }
                            this.DoRepairDroneLogic(weapon);
                        }
                    }
                }
            }
            if (this.State == AIState.ManualControl)
            {
                return;
            }
            this.ReadyToWarp = true;
            this.Owner.isThrusting = false;
            this.Owner.isTurning = false;

            #region old flee code
            //if (!this.HasPriorityOrder
            //    && (this.BadGuysNear || this.Owner.InCombat)
            //    && (this.Owner.shipData == null || this.Owner.shipData.ShipCategory == ShipData.Category.Civilian)
            //    && this.Owner.Weapons.Count == 0 && this.Owner.GetHangars().Count == 0 && this.Owner.Transporters.Count() == 0
            //    && (this.Owner.Role !="troop"
            //    && this.Owner.Role != "construction"
            //    && this.State !=AIState.Colonize
            //    && !this.IgnoreCombat && this.State != AIState.Rebase)
            //    && (this.Owner.Role == "freighter" || this.Owner.fleet == null || this.Owner.Mothership != null))
            //{
            //    if (this.State != AIState.Flee )
            //    {
            //        this.HasPriorityOrder = true;
            //        this.State = AIState.Flee;
            //        if (this.State == AIState.Flee)
            //        {
            //            this.OrderFlee(false);
            //            this.Owner.InCombatTimer = 15f;

            //        }
            //    }
            //    else if (this.State == AIState.Flee && (this.OrbitTarget != null && Vector2.Distance(this.OrbitTarget.Position, this.Owner.Position) < this.Owner.SensorRange + 10000))
            //    {
            //        this.State = this.DefaultAIState;
            //    }
            //}
            #endregion
            if (this.State == AIState.SystemTrader && this.start != null && this.end != null && (this.start.Owner != this.Owner.loyalty || this.end.Owner != this.Owner.loyalty))
            {
                this.start = null;
                this.end = null;
                this.OrderTrade();
                return;
            }
            if (this.State == AIState.PassengerTransport && this.start != null && this.end != null && (this.start.Owner != this.Owner.loyalty || this.end.Owner != this.Owner.loyalty))
            {
                this.start = null;
                this.end = null;
                this.OrderTransportPassengers();
                return;
            }
            #if !DEBUG
            try
            {
            #endif
                if (this.OrderQueue.Count == 0)
                {
                    if (this.Owner.fleet == null)
                    {
                        lock (this.wayPointLocker)
                        {
                            this.ActiveWayPoints.Clear();
                        }
                        AIState state = this.State;
                        if (state <= AIState.MoveTo)
                        {
                            if (state <= AIState.SystemTrader)
                            {
                                if (state == AIState.DoNothing)
                                {
                                    this.AwaitOrders(elapsedTime);
                                }
                                else
                                {
                                    switch (state)
                                    {
                                        case AIState.AwaitingOrders:
                                            {
                                                if (this.Owner.loyalty != ArtificialIntelligence.universeScreen.player)
                                                {
                                                    this.AwaitOrders(elapsedTime);
                                                }
                                                else
                                                {
                                                    this.AwaitOrdersPlayer(elapsedTime);
                                                }
                                                if (this.Owner.OrdinanceMax == 0 || this.Owner.OrdinanceMax > 0 && this.Owner.Ordinance / this.Owner.OrdinanceMax >= 0.2f)
                                                {

                                                    break;

                                                }
                                                if (FriendliesNearby.Where(supply => supply.HasSupplyBays && supply.Ordinance >= 100).Count() > 0)
                                                {
                                                    break;
                                                }
                                                List<Planet> shipyards = new List<Planet>();
                                                for (int i = 0; i < this.Owner.loyalty.GetPlanets().Count; i++)
                                                {
                                                    Planet item = this.Owner.loyalty.GetPlanets()[i];
                                                    if (item.HasShipyard)
                                                    {
                                                        shipyards.Add(item);
                                                    }
                                                }
                                                IOrderedEnumerable<Planet> sortedList =
                                                    from p in shipyards
                                                    orderby Vector2.Distance(this.Owner.Center, p.Position)
                                                    select p;
                                                if (sortedList.Count<Planet>() <= 0)
                                                {
                                                    break;
                                                }
                                                this.OrderResupply(sortedList.First<Planet>(), true);
                                                break;
                                            }
                                        case AIState.Escort:
                                            {
                                                if (this.EscortTarget != this.Owner.Mothership || this.Owner.Mothership == null || !this.Owner.Mothership.InCombat)
                                                {
                                                    if (this.EscortTarget == null || !this.EscortTarget.Active)
                                                    {
                                                        this.State = AIState.AwaitingOrders;   //fbedard
                                                        break;
                                                    }
                                                    this.OrbitShip(this.EscortTarget, elapsedTime);
                                                    break;
                                                }
                                                else
                                                {
                                                    if(this.Target == null && !(this.hasPriorityTarget || this.HasPriorityOrder))
                                                    this.Target = this.Owner.Mothership.GetAI().Target;
                                                    this.DoCombat(elapsedTime);
                                                    break;
                                                }
                                            }
                                        case AIState.SystemTrader:
                                            {
                                                this.OrderTrade();
                                                if (this.end != null && this.start != null)
                                                {
                                                    break;
                                                }
                                                this.AwaitOrders(elapsedTime);
                                                break;
                                            }
                                    }
                                }
                            }
                            else if (state == AIState.PassengerTransport)
                            {
                                this.OrderTransportPassengers();
                                if (this.end == null || this.start == null)
                                {
                                    this.AwaitOrders(elapsedTime);
                                }
                            }
                            else if (state != AIState.MoveTo)
                            {
                            }
                        }
                        else if (state <= AIState.ReturnToHangar)
                        {
                            switch (state)
                            {
                                case AIState.SystemDefender:
                                    {
                                        if (this.Target != null)
                                        System.Diagnostics.Debug.WriteLine("SD Tatget" + this.Owner.VanityName);
                                        //if(this.Target == null)
                                        this.AwaitOrders(elapsedTime);
                                        break;
                                    }
                                case AIState.AwaitingOffenseOrders:
                                    {
                                        break;
                                    }
                                case AIState.Resupply:
                                    {
                                        if (this.Owner.Ordinance != this.Owner.OrdinanceMax)
                                        {
                                            break;
                                        }
                                        this.State = AIState.AwaitingOrders;
                                        break;
                                    }
                                default:
                                    {
                                        if (state == AIState.ReturnToHangar)
                                        {
                                            this.DoReturnToHangar(elapsedTime);
                                            break;
                                        }
                                        else
                                        {
                                            break;
                                        }
                                    }
                            }
                        }
                        else if (state != AIState.Intercept)
                        {
                            if (state == AIState.Exterminate)
                            {
                                this.OrderFindExterminationTarget(true);
                            }
                        }
                        else if (this.Target != null)
                        {
                            this.OrbitShip(this.Target as Ship, elapsedTime);
                        }
                    }
                    else
                    {
                        float DistanceToFleetOffset = Vector2.Distance(this.Owner.Center, this.Owner.fleet.Position + this.Owner.FleetOffset);
                        Vector2 toAdd = (this.Owner.Velocity != Vector2.Zero ? Vector2.Normalize(this.Owner.Velocity) : Vector2.Zero) * 100f;
                        Vector2.Distance(this.Owner.Center, (this.Owner.fleet.Position + this.Owner.FleetOffset) + toAdd);
                        Vector2 vector2 = HelperFunctions.findPointFromAngleAndDistanceUsingRadians(this.Owner.fleet.Position + this.Owner.FleetOffset, this.Owner.fleet.facing, 1f);
                        Vector2 fvec = HelperFunctions.FindVectorToTarget(Vector2.Zero, vector2);
                        if (DistanceToFleetOffset <= 75f || this.HasPriorityOrder)
                        {
                            this.Owner.Velocity = Vector2.Zero;
                            vector2 = HelperFunctions.findPointFromAngleAndDistanceUsingRadians(Vector2.Zero, this.Owner.fleet.facing, 1f);
                            fvec = HelperFunctions.FindVectorToTarget(Vector2.Zero, vector2);
                            Vector2 wantedForward = Vector2.Normalize(fvec);
                            Vector2 forward = new Vector2((float)Math.Sin((double)this.Owner.Rotation), -(float)Math.Cos((double)this.Owner.Rotation));
                            Vector2 right = new Vector2(-forward.Y, forward.X);
                            float angleDiff = (float)Math.Acos((double)Vector2.Dot(wantedForward, forward));
                            float facing = (Vector2.Dot(wantedForward, right) > 0f ? 1f : -1f);
                            if (angleDiff > 0.02f)
                            {
                                this.RotateToFacing(elapsedTime, angleDiff, facing);
                            }
                            this.State = AIState.AwaitingOrders;
                        }
                        else
                        {
                            this.ThrustTowardsPosition(this.Owner.fleet.Position + this.Owner.FleetOffset, elapsedTime, this.Owner.fleet.speed);
                            lock (this.wayPointLocker)
                            {
                                this.ActiveWayPoints.Clear();
                                this.ActiveWayPoints.Enqueue(this.Owner.fleet.Position + this.Owner.FleetOffset);
                                if (this.Owner.fleet.GetStack().Count > 0)
                                {
                                    this.ActiveWayPoints.Enqueue(this.Owner.fleet.GetStack().Peek().MovePosition + this.Owner.FleetOffset);
                                }
                            }
                        }
                    }
                }
                else if (this.OrderQueue.Count > 0)
                {
            #if DEBUG
                    try
            #endif
                    {
                        toEvaluate = this.OrderQueue.First<ArtificialIntelligence.ShipGoal>();
                    }
            #if DEBUG
                    catch

                    {
                        return;
                    }
            #endif
                    Planet target = toEvaluate.TargetPlanet;
                    switch (toEvaluate.Plan)
                    {
                        case ArtificialIntelligence.Plan.HoldPosition:
                            {
                                //

                                //
                                this.HoldPosition();

                                break;
                            }
                        case ArtificialIntelligence.Plan.Stop:
                            {
                                this.Stop(elapsedTime, toEvaluate);
                                break;
                            }
                        case ArtificialIntelligence.Plan.Scrap:
                            {
                                this.ScrapShip(elapsedTime, toEvaluate);
                                break;
                            }
                        case ArtificialIntelligence.Plan.Bombard:
                            //target = toEvaluate.TargetPlanet; //Modified by Ermenildo V. Castro, Jr.; 07/29/15: Removed redunant statement, assignment occurs before SWITCH
                            if (this.Owner.Ordinance < 0.05* this.Owner.OrdinanceMax
                                || (target.TroopsHere.Count <= target.TroopsHere.Count * .40f  || target.Population <= target.Population * .10f) //Legacy Code: (target.BuildingList.Count == 0 && target.TroopsHere.Count == 0  && target.Population <0f)
                                                                                                                              //Modified by Ermenildo V. Castro, Jr. for Issue #488
                                                                                                                              //Issue #488:
                                                                                                                              //The ai needs to soften planets more for invasion but try not to kill all the populace
                                                                                                                              //Modified conditional to reflect goals for Issue #488:
                                                                                                                              //        - Stop bombarding if planet population is less than 10% of the original target population
                                                                                                                              //        - Stop bombarding if opposition troops are attrited by at least 60%, id est: target troops less than 40% of original troop count
                                || target.GetGroundStrengthOther(this.Owner.loyalty) * 1.5
                                <= target.GetGroundStrength(this.Owner.loyalty)
                                )
                            {
                                this.OrderQueue.Clear();
                                if(this.CombatState == CombatState.Evade)
                                this.State = AIState.AwaitingOrders;
                                this.HasPriorityOrder = false;
                            }
                            this.DoOrbit(toEvaluate.TargetPlanet, elapsedTime);
                            float radius = toEvaluate.TargetPlanet.ObjectRadius + this.Owner.Radius + 1000;
                            if (toEvaluate.TargetPlanet.Owner == this.Owner.loyalty) //cannot bombard friednly planets
                            {
                                this.OrderQueue.Clear();
                                return;
                            }
                            else if (Vector2.Distance(this.Owner.Center, toEvaluate.TargetPlanet.Position) < radius)
                            {
                                using (List<ShipModule>.Enumerator enumerator = this.Owner.BombBays.GetEnumerator())
                                {
                                    while (enumerator.MoveNext())
                                    {
                                        ShipModule current = enumerator.Current;
                                        if ((double)current.BombTimer <= 0.0)
                                        {
                                            Bomb bomb = new Bomb(new Vector3(this.Owner.Center, 0.0f), this.Owner.loyalty);
                                            bomb.WeaponName = current.BombType;
                                            if ((double)this.Owner.Ordinance > (double)ResourceManager.WeaponsDict[current.BombType].OrdinanceRequiredToFire)
                                            {
                                                this.Owner.Ordinance -= ResourceManager.WeaponsDict[current.BombType].OrdinanceRequiredToFire;
                                                bomb.SetTarget(toEvaluate.TargetPlanet);
                                                //lock (GlobalStats.BombLock)
                                                    ArtificialIntelligence.universeScreen.BombList.Add(bomb);
                                                current.BombTimer = ResourceManager.WeaponsDict[current.BombType].fireDelay;
                                            }
                                        }
                                    }
                                    break;
                                }
                            }
                            else
                                break;
                        case ArtificialIntelligence.Plan.BombTroops:
                            target = toEvaluate.TargetPlanet;

                            if (target.TroopsHere.Where(unfriendlyTroops => unfriendlyTroops.GetOwner() != this.Owner.loyalty).Count() * 1.5
                                >= target.TilesList.Sum(space => space.number_allowed_troops))
                            {
                                if ((double)this.Owner.Ordinance < 0.0500000007450581 * (double)this.Owner.OrdinanceMax)
                                {
                                    this.OrderQueue.Clear();
                                    this.State = AIState.AwaitingOrders;
                                    this.HasPriorityOrder = false;
                                }
                                this.DoOrbit(toEvaluate.TargetPlanet, elapsedTime);
                                 radius = toEvaluate.TargetPlanet.ObjectRadius + this.Owner.Radius + 1000;
                                if (toEvaluate.TargetPlanet.Owner == this.Owner.loyalty)

                                {
                                    this.OrderQueue.Clear();
                                    return;
                                }
                                else if ((double)Vector2.Distance(this.Owner.Center, toEvaluate.TargetPlanet.Position) < radius)
                                {
                                    using (List<ShipModule>.Enumerator enumerator = this.Owner.BombBays.GetEnumerator())
                                    {
                                        while (enumerator.MoveNext())
                                        {
                                            ShipModule current = enumerator.Current;
                                            if ((double)current.BombTimer <= 0.0)
                                            {
                                                Bomb bomb = new Bomb(new Vector3(this.Owner.Center, 0.0f), this.Owner.loyalty);
                                                bomb.WeaponName = current.BombType;
                                                if ((double)this.Owner.Ordinance > (double)ResourceManager.WeaponsDict[current.BombType].OrdinanceRequiredToFire)
                                                {
                                                    this.Owner.Ordinance -= ResourceManager.WeaponsDict[current.BombType].OrdinanceRequiredToFire;
                                                    bomb.SetTarget(toEvaluate.TargetPlanet);
                                                    //lock (GlobalStats.BombLock)
                                                        ArtificialIntelligence.universeScreen.BombList.Add(bomb);
                                                    current.BombTimer = ResourceManager.WeaponsDict[current.BombType].fireDelay;
                                                }
                                            }
                                        }
                                        break;
                                    }
                                }
                                else
                                    break;
                            }
                            else if (this.Owner.HasTroopBay || (this.Owner.hasTransporter))
                            {
                                this.State = AIState.AssaultPlanet;
                                this.OrderAssaultPlanet(target);
                            }
                            else
                                this.OrderQueue.Clear();
                            break;

                        case ArtificialIntelligence.Plan.Exterminate:
                            {
                                this.DoOrbit(toEvaluate.TargetPlanet, elapsedTime);
                                radius = toEvaluate.TargetPlanet.ObjectRadius + this.Owner.Radius + 1000;
                                if (toEvaluate.TargetPlanet.Owner == this.Owner.loyalty || toEvaluate.TargetPlanet.Owner == null)
                                {
                                    this.OrderQueue.Clear();
                                    this.OrderFindExterminationTarget(true);
                                    return;
                                }
                                else
                                {
                                    if (Vector2.Distance(this.Owner.Center, toEvaluate.TargetPlanet.Position) >= radius)
                                        break;
                                    List<ShipModule>.Enumerator enumerator1 = this.Owner.BombBays.GetEnumerator();
                                    try
                                    {
                                        while (enumerator1.MoveNext())
                                        {
                                            ShipModule mod = enumerator1.Current;
                                            if (mod.BombTimer > 0f)
                                                continue;
                                            Bomb b = new Bomb(new Vector3(this.Owner.Center, 0f), this.Owner.loyalty)
                                            {
                                                WeaponName = mod.BombType
                                            };
                                            if (this.Owner.Ordinance <= ResourceManager.WeaponsDict[mod.BombType].OrdinanceRequiredToFire)
                                            {
                                                continue;
                                            }
                                            Ship owner1 = this.Owner;
                                            owner1.Ordinance = owner1.Ordinance - ResourceManager.WeaponsDict[mod.BombType].OrdinanceRequiredToFire;
                                            b.SetTarget(toEvaluate.TargetPlanet);
                                            //lock (GlobalStats.BombLock)
                                            {
                                                ArtificialIntelligence.universeScreen.BombList.Add(b);
                                            }
                                            mod.BombTimer = ResourceManager.WeaponsDict[mod.BombType].fireDelay;
                                        }
                                        break;
                                    }
                                    finally
                                    {
                                        ((IDisposable)enumerator1).Dispose();
                                    }
                                }
                            }
                        case ArtificialIntelligence.Plan.RotateToFaceMovePosition:
                            {
                                this.RotateToFaceMovePosition(elapsedTime, toEvaluate);
                                break;
                            }
                        case ArtificialIntelligence.Plan.RotateToDesiredFacing:
                            {
                                this.RotateToDesiredFacing(elapsedTime, toEvaluate);
                                break;
                            }
                        case ArtificialIntelligence.Plan.MoveToWithin1000:
                            {
                                this.MoveToWithin1000(elapsedTime, toEvaluate);
                                break;
                            }
                        case ArtificialIntelligence.Plan.MakeFinalApproachFleet:
                            {
                                if (this.Owner.fleet != null)
                                {
                                    this.MakeFinalApproachFleet(elapsedTime, toEvaluate);
                                    break;
                                }
                                else
                                {
                                    this.State = AIState.AwaitingOrders;
                                    break;
                                }
                            }
                        case ArtificialIntelligence.Plan.MoveToWithin1000Fleet:
                            {
                                if (this.Owner.fleet != null)
                                {
                                    this.MoveToWithin1000Fleet(elapsedTime, toEvaluate);
                                    break;
                                }
                                else
                                {
                                    this.State = AIState.AwaitingOrders;
                                    break;
                                }
                            }
                        case ArtificialIntelligence.Plan.MakeFinalApproach:
                            {
                                this.MakeFinalApproach(elapsedTime, toEvaluate);
                                break;
                            }
                        case ArtificialIntelligence.Plan.RotateInlineWithVelocity:
                            {
                                this.RotateInLineWithVelocity(elapsedTime, toEvaluate);
                                break;
                            }
                        case ArtificialIntelligence.Plan.StopWithBackThrust:
                            {
                                this.StopWithBackwardsThrust(elapsedTime, toEvaluate);
                                break;
                            }
                        case ArtificialIntelligence.Plan.Orbit:
                            {
                                this.DoOrbit(toEvaluate.TargetPlanet, elapsedTime);
                                break;
                            }
                        case ArtificialIntelligence.Plan.Colonize:
                            {
                                this.Colonize(toEvaluate.TargetPlanet);
                                break;
                            }
                        case ArtificialIntelligence.Plan.Explore:
                            {
                                this.DoExplore(elapsedTime);
                                break;
                            }
                        case ArtificialIntelligence.Plan.Rebase:
                            {
                                this.DoRebase(toEvaluate);
                                break;
                            }
                        case ArtificialIntelligence.Plan.DefendSystem:
                            {
                                if (this.Target != null)
                                    System.Diagnostics.Debug.WriteLine(this.Target);
                                this.DoSystemDefense(elapsedTime);
                                break;
                            }
                        case ArtificialIntelligence.Plan.DoCombat:
                            {
                                this.DoCombat(elapsedTime);
                                break;
                            }
                        case ArtificialIntelligence.Plan.MoveTowards:
                            {
                                this.MoveTowardsPosition(this.MovePosition, elapsedTime);
                                break;
                            }
                        case ArtificialIntelligence.Plan.PickupPassengers:
                            {
                                if (this.start != null)
                                    this.PickupPassengers();
                                else
                                    this.State = AIState.AwaitingOrders;
                                break;
                            }
                        case ArtificialIntelligence.Plan.DropoffPassengers:
                            {

                                try
                                {
                                    this.DropoffPassengers();
                                }
                                catch
                                {
                                    System.Diagnostics.Debug.WriteLine("DropoffPassengers failed");

                                }
                                break;
                            }
                        case ArtificialIntelligence.Plan.DeployStructure:
                            {
                                this.DoDeploy(toEvaluate);
                                break;
                            }
                        case ArtificialIntelligence.Plan.PickupGoods:
                            {
                                try
                                {
                                    this.PickupGoods();
                                }
                                catch
                                { }
                                break;
                            }
                        case ArtificialIntelligence.Plan.DropOffGoods:
                            {
                                this.DropoffGoods();
                                break;
                            }
                        case ArtificialIntelligence.Plan.ReturnToHangar:
                            {
                                this.DoReturnToHangar(elapsedTime);
                                break;
                            }
                        case ArtificialIntelligence.Plan.TroopToShip:
                            {
                                this.DoTroopToShip(elapsedTime);
                                break;
                            }
                        case ArtificialIntelligence.Plan.BoardShip:
                            {
                                this.DoBoardShip(elapsedTime);
                                break;
                            }
                        case ArtificialIntelligence.Plan.SupplyShip:
                            {
                                this.DoSupplyShip(elapsedTime, toEvaluate);
                                break;
                            }
                        case ArtificialIntelligence.Plan.Refit:
                            {
                                this.DoRefit(elapsedTime, toEvaluate);
                                break;
                            }
                        case ArtificialIntelligence.Plan.LandTroop:
                            {
                                this.DoLandTroop(elapsedTime, toEvaluate);
                                break;
                            }
                    }
                }
                goto Label0;
            #if !DEBUG
            }

            catch

            {
            }
            #endif
            Label0:
            AIState aIState = this.State;
            if (aIState == AIState.SystemTrader)
            {
                foreach (ArtificialIntelligence.ShipGoal goal in this.OrderQueue)
                {

                    if (goal.Plan == ArtificialIntelligence.Plan.TransportPassengers && goal.TargetPlanet != null && goal.TargetPlanet.Owner != this.Owner.loyalty)
                    {
                        this.OrderQueue.Clear();
                        this.State = AIState.AwaitingOrders;
                        break;
                    }
                    else if (goal.Plan == ArtificialIntelligence.Plan.PickupPassengers && goal.TargetPlanet != null && goal.TargetPlanet.Owner != this.Owner.loyalty)
                    {
                        this.OrderQueue.Clear();
                        this.State = AIState.AwaitingOrders;
                        break;
                    }
                    else if (goal.Plan == ArtificialIntelligence.Plan.PickupGoods && goal.TargetPlanet != null && goal.TargetPlanet.Owner != this.Owner.loyalty)
                    {
                        this.OrderQueue.Clear();
                        this.State = AIState.AwaitingOrders;
                        break;
                    }
                    else if (goal.Plan != ArtificialIntelligence.Plan.DropoffPassengers || goal.TargetPlanet == null || goal.TargetPlanet.Owner == this.Owner.loyalty)
                    {
                        if (goal.Plan != ArtificialIntelligence.Plan.DropOffGoods || goal.TargetPlanet == null || goal.TargetPlanet.Owner == this.Owner.loyalty)
                        {
                            continue;
                        }
                        this.OrderQueue.Clear();
                        this.State = AIState.AwaitingOrders;
                        break;
                    }
                    else
                    {
                        this.OrderQueue.Clear();
                        this.State = AIState.AwaitingOrders;
                        break;
                    }
                }
            }
            else if (aIState == AIState.PassengerTransport)
            {
                foreach (ArtificialIntelligence.ShipGoal goal in this.OrderQueue)
                {
                    if (goal.Plan == ArtificialIntelligence.Plan.TransportPassengers && goal.TargetPlanet != null && goal.TargetPlanet.Owner != this.Owner.loyalty)
                    {
                        this.OrderQueue.Clear();
                        this.State = AIState.AwaitingOrders;
                        break;
                    }
                    else if (goal.Plan == ArtificialIntelligence.Plan.PickupPassengers && goal.TargetPlanet != null && goal.TargetPlanet.Owner != this.Owner.loyalty)
                    {
                        this.OrderQueue.Clear();
                        this.State = AIState.AwaitingOrders;
                        break;
                    }
                    else if (goal.Plan == ArtificialIntelligence.Plan.PickupGoods && goal.TargetPlanet != null && goal.TargetPlanet.Owner != this.Owner.loyalty)
                    {
                        this.OrderQueue.Clear();
                        this.State = AIState.AwaitingOrders;
                        break;
                    }
                    else if (goal.Plan != ArtificialIntelligence.Plan.DropoffPassengers || goal.TargetPlanet == null || goal.TargetPlanet.Owner == this.Owner.loyalty)
                    {
                        if (goal.Plan != ArtificialIntelligence.Plan.DropOffGoods || goal.TargetPlanet == null || goal.TargetPlanet.Owner == this.Owner.loyalty)
                        {
                            continue;
                        }
                        this.OrderQueue.Clear();
                        this.State = AIState.AwaitingOrders;
                        break;
                    }
                    else
                    {
                        this.OrderQueue.Clear();
                        this.State = AIState.AwaitingOrders;
                        break;
                    }
                }
            }
            else if (aIState == AIState.Rebase)
            {
                foreach (ArtificialIntelligence.ShipGoal goal in this.OrderQueue)
                //Parallel.ForEach(this.OrderQueue, (goal, state) =>
                {
                    if (goal.Plan != ArtificialIntelligence.Plan.Rebase || goal.TargetPlanet == null || goal.TargetPlanet.Owner == this.Owner.loyalty)
                    {
                        continue;
                    }
                    this.OrderQueue.Clear();
                    this.State = AIState.AwaitingOrders;
                    break;
                }
            }
            //if(targetChangeTimer >-1)
            //targetChangeTimer -= elapsedTime;
            //if(TriggerDelay >-1)
            TriggerDelay -= elapsedTime;
            if (this.Owner.InCombat && this.BadGuysNear && !this.IgnoreCombat)
            {
                if (this.TriggerDelay < 0)
                {
                    TriggerDelay = elapsedTime * 2;
                    bool docombat = false;
                    LinkedListNode<ArtificialIntelligence.ShipGoal> tempShipGoal = this.OrderQueue.First;
                    ShipGoal firstgoal = tempShipGoal != null ? tempShipGoal.Value : null;  //.FirstOrDefault<ArtificialIntelligence.ShipGoal>();
                    if (this.Owner.Weapons.Count > 0 || this.Owner.GetHangars().Count > 0)
            #if !DEBUG
                        try
            #endif
                    {

                        docombat = (!this.HasPriorityOrder && (this.OrderQueue.Count == 0 || firstgoal != null && firstgoal.Plan != ArtificialIntelligence.Plan.DoCombat));

                        if (docombat)//|| this.OrderQueue.Count == 0))
                        {
                            this.OrderQueue.AddFirst(new ArtificialIntelligence.ShipGoal(ArtificialIntelligence.Plan.DoCombat, Vector2.Zero, 0f));
                        }

                        //this.fireTask = Task.Factory.StartNew(this.FireOnTarget);//,TaskCreationOptions.LongRunning);
                        //fireTask = new Task(this.FireOnTarget);
                        this.FireOnTarget();

                    }

            #if !DEBUG
                        catch
                        {
                        }

            #endif
                }
            }
            else
            {
                if (this.Owner.GetHangars().Count > 0 && this.Owner.loyalty != ArtificialIntelligence.universeScreen.player)
                {
                    foreach (ShipModule hangar in this.Owner.GetHangars())
                    {
                        if (hangar.IsTroopBay || hangar.IsSupplyBay || hangar.GetHangarShip() == null
                            //||hangar.GetHangarShip().InCombat
                            || hangar.GetHangarShip().GetAI().State == AIState.ReturnToHangar)
                        {
                            continue;
                        }
                        hangar.GetHangarShip().GetAI().OrderReturnToHangar();
                    }
                }
                else if (this.Owner.GetHangars().Count > 0)
                {
                    foreach (ShipModule hangar in this.Owner.GetHangars())
                    {
                        if (hangar.IsTroopBay
                            || hangar.IsSupplyBay
                            || hangar.GetHangarShip() == null
                            || hangar.GetHangarShip().GetAI().State == AIState.ReturnToHangar
                            //|| hangar.GetHangarShip().InCombat
                            || hangar.GetHangarShip().GetAI().hasPriorityTarget
                            || hangar.GetHangarShip().GetAI().HasPriorityOrder

                            )
                        {
                            continue;
                        }
                        hangar.GetHangarShip().DoEscort(this.Owner);
                    }
                }
            }
            if (this.State == AIState.Resupply && !this.HasPriorityOrder)
            {
                this.HasPriorityOrder = true;
            }
            //if (this.Owner.Weapons.Count() == 0 && this.BadGuysNear) //||( this.State != AIState.AssaultPlanet && this.State != AIState.Boarding
            //{
            //    this.CombatState = Gameplay.CombatState.Evade;
            //}
            if (!this.Owner.isTurning)
            {
                this.DeRotate();
                return;
            }
            else
            {
                return;
            }
        }
 public virtual void FireDroneBeam(Vector2 direction, GameplayObject target, DroneAI source)
 {
     this.drowner = source.Owner;
     if (this.timeToNextFire > 0f)
     {
         return;
     }
     this.timeToNextFire = this.fireDelay;
     this.CreateDroneBeam(direction, target, source);
 }
 public virtual void FireFromPlanet(Vector2 direction, Planet p, GameplayObject target)
 {
     if (target is ShipModule)
         (target as ShipModule).GetParent().InCombatTimer = 15f;
     Vector2 StartPos = p.Position;
     if (this.FireArc != 0)
     {
         float DegreesBetweenShots = (float)(this.FireArc / this.ProjectileCount);
         float angleToTarget = this.findAngleToTarget(direction);
         for (int i = 0; i < this.ProjectileCount; i++)
         {
             Vector2 newTarget = this.findTargetFromAngleAndDistance(StartPos, angleToTarget - (float)(this.FireArc / 2) + DegreesBetweenShots * (float)i, this.Range);
             Vector2 fireDirection = this.findVectorToTarget(StartPos, newTarget);
             fireDirection.Y = fireDirection.Y * -1f;
             this.CreateProjectilesFromPlanet(Vector2.Normalize(fireDirection), p, target);
         }
         return;
     }
     if (this.FireCone <= 0)
     {
         if (!this.isBeam)
         {
             for (int i = 0; i < this.ProjectileCount; i++)
             {
                 if (this.WeaponType != "Missile")
                 {
                     this.CreateProjectilesFromPlanet(direction, p, target);
                 }
                 else
                 {
                     this.CreateProjectilesFromPlanet(Vector2.Normalize(direction), p, target);
                 }
             }
         }
         return;
     }
     float spread = RandomMath2.RandomBetween((float)(-this.FireCone / 2), (float)(this.FireCone / 2));
     float angleToTarget2 = this.findAngleToTarget(direction);
     Vector2 newTarget2 = this.findTargetFromAngleAndDistance(StartPos, angleToTarget2 + spread, this.Range);
     Vector2 fireDirection2 = this.findVectorToTarget(StartPos, newTarget2);
     fireDirection2.Y = fireDirection2.Y * -1f;
     this.CreateProjectilesFromPlanet(Vector2.Normalize(fireDirection2), p, target);
 }
        private void SetCombatStatus(float elapsedTime)
        {
            //if(this.State==AIState.Scrap)
            //{
            //    this.Target = null;
            //    this.Owner.InCombatTimer = 0f;
            //    this.Owner.InCombat = false;
            //    this.TargetQueue.Clear();
            //    return;

            //}
            float radius = 30000f;
            Vector2 senseCenter = this.Owner.Center;
            if (UseSensorsForTargets)
            {
                if (this.Owner.Mothership != null)
                {
                    if (Vector2.Distance(this.Owner.Center, this.Owner.Mothership.Center) <= this.Owner.Mothership.SensorRange - this.Owner.SensorRange)
                    {
                        senseCenter = this.Owner.Mothership.Center;
                        radius = this.Owner.Mothership.SensorRange;
                    }
                }
                else
                {
                    radius = this.Owner.SensorRange;
                    if (this.Owner.inborders) radius += 10000;
                }
            }
            if (this.Owner.fleet != null)
            {
                if (!this.hasPriorityTarget)
                {
                    this.Target = this.ScanForCombatTargets(senseCenter, radius);
                }
                else
                {
                    this.ScanForCombatTargets(senseCenter, radius);
                }
            }
            else if (!this.hasPriorityTarget)
            {
            //#if DEBUG
            //                if (this.State == AIState.Intercept && this.Target != null)
            //                    System.Diagnostics.Debug.WriteLine(this.Target);
            //#endif
                this.Target = this.ScanForCombatTargets(senseCenter, radius);
            }
            else
            {
                this.ScanForCombatTargets(senseCenter, radius);
            }
            if (this.State == AIState.Resupply)
            {
                return;
            }
            if (((this.Owner.Role == "freighter" && this.Owner.CargoSpace_Max > 0) || this.Owner.Role == "scout" || this.Owner.Role == "construction" || this.Owner.Role == "troop" || this.IgnoreCombat || this.State == AIState.Resupply || this.State == AIState.ReturnToHangar || this.State == AIState.Colonize) || this.Owner.VanityName == "Resupply Shuttle")
            {
                return;
            }
            if (this.Owner.fleet != null && this.State == AIState.FormationWarp)
            {
                bool doreturn = true;
                if (this.Owner.fleet != null && this.State == AIState.FormationWarp && Vector2.Distance(this.Owner.Center, this.Owner.fleet.Position + this.Owner.FleetOffset) < 15000f)
                {
                    doreturn = false;
                }
                if (doreturn)
                {
                    //if (this.Owner.engineState == Ship.MoveState.Sublight && this.NearbyShips.Count > 0)
                    //{
                    //    this.Owner.ShieldsUp = true;
                    //}
                    return;
                }
            }
            if (this.Owner.fleet != null)
            {
                foreach (FleetDataNode datanode in this.Owner.fleet.DataNodes)
                {
                    if (datanode.GetShip() != this.Owner)
                    {
                        continue;
                    }
                    this.node = datanode;
                    break;
                }
            }
            if (this.Target != null && !this.Owner.InCombat)
            {
                this.Owner.InCombatTimer = 15f;
                if (!this.HasPriorityOrder && this.OrderQueue.Count > 0 && this.OrderQueue.ElementAt<ArtificialIntelligence.ShipGoal>(0).Plan != ArtificialIntelligence.Plan.DoCombat)
                {
                    ArtificialIntelligence.ShipGoal combat = new ArtificialIntelligence.ShipGoal(ArtificialIntelligence.Plan.DoCombat, Vector2.Zero, 0f);
                    this.State = AIState.Combat;
                    this.OrderQueue.AddFirst(combat);
                    return;
                }
                else if (!this.HasPriorityOrder)
                {
                    ArtificialIntelligence.ShipGoal combat = new ArtificialIntelligence.ShipGoal(ArtificialIntelligence.Plan.DoCombat, Vector2.Zero, 0f);
                    this.State = AIState.Combat;
                    this.OrderQueue.AddFirst(combat);
                    return;
                }
                else
                {
                    if (!this.HasPriorityOrder || this.CombatState == CombatState.HoldPosition || this.OrderQueue.Count != 0)
                        return;
                    ArtificialIntelligence.ShipGoal combat = new ArtificialIntelligence.ShipGoal(ArtificialIntelligence.Plan.DoCombat, Vector2.Zero, 0f);
                    this.State = AIState.Combat;
                    this.OrderQueue.AddFirst(combat);

                }
            }
        }
        public virtual void FireTargetedBeam(GameplayObject target)
        {
            if (this.timeToNextFire > 0f)
            {
                return;
            }
            this.owner.InCombatTimer = 15f;
            this.timeToNextFire = this.fireDelay;

            if (this.moduleAttachedTo.Active && this.owner.PowerCurrent > this.PowerRequiredToFire && this.OrdinanceRequiredToFire <= this.owner.Ordinance)
            {

                    this.CreateTargetedBeam(target);

                this.owner.Ordinance -= this.OrdinanceRequiredToFire;
                this.owner.PowerCurrent -= this.PowerRequiredToFire;

            }
        }
 private void SetCombatStatusorig(float elapsedTime)
 {
     if (this.Owner.fleet != null)
     {
         if (!this.hasPriorityTarget)
         {
             this.Target = this.ScanForCombatTargets(this.Owner.Center, 30000f);
         }
         else
         {
             this.ScanForCombatTargets(this.Owner.Center, 30000f);
         }
     }
     else if (!this.hasPriorityTarget)
     {
         this.Target = this.ScanForCombatTargets(this.Owner.Center, 30000f);
     }
     else
     {
         this.ScanForCombatTargets(this.Owner.Center, 30000f);
     }
     if (this.State == AIState.Resupply)
     {
         return;
     }
     if ((this.Owner.Role == "freighter" || this.Owner.Role == "scout" || this.Owner.Role == "construction" || this.Owner.Role == "troop" || this.IgnoreCombat || this.State == AIState.Resupply || this.State == AIState.ReturnToHangar) && !this.Owner.IsSupplyShip)
     {
         return;
     }
     if (this.Owner.fleet != null && this.State == AIState.FormationWarp)
     {
         bool doreturn = true;
         if (this.Owner.fleet != null && this.State == AIState.FormationWarp && Vector2.Distance(this.Owner.Center, this.Owner.fleet.Position + this.Owner.FleetOffset) < 15000f)
         {
             doreturn = false;
         }
         if (doreturn)
         {
             return;
         }
     }
     if (this.Owner.fleet != null)
     {
         foreach (FleetDataNode datanode in this.Owner.fleet.DataNodes)
         {
             if (datanode.GetShip() != this.Owner)
             {
                 continue;
             }
             this.node = datanode;
             break;
         }
     }
     if (this.Target != null && !this.Owner.InCombat)
     {
         this.Owner.InCombat = true;
         this.Owner.InCombatTimer = 15f;
         if (!this.HasPriorityOrder && this.OrderQueue.Count > 0 && this.OrderQueue.ElementAt<ArtificialIntelligence.ShipGoal>(0).Plan != ArtificialIntelligence.Plan.DoCombat)
         {
             ArtificialIntelligence.ShipGoal combat = new ArtificialIntelligence.ShipGoal(ArtificialIntelligence.Plan.DoCombat, Vector2.Zero, 0f);
             this.State = AIState.Combat;
             this.OrderQueue.AddFirst(combat);
             return;
         }
         if (!this.HasPriorityOrder)
         {
             ArtificialIntelligence.ShipGoal combat = new ArtificialIntelligence.ShipGoal(ArtificialIntelligence.Plan.DoCombat, Vector2.Zero, 0f);
             this.State = AIState.Combat;
             this.OrderQueue.AddFirst(combat);
             return;
         }
         if (this.HasPriorityOrder && this.CombatState != Ship_Game.Gameplay.CombatState.HoldPosition && this.OrderQueue.Count == 0)
         {
             ArtificialIntelligence.ShipGoal combat = new ArtificialIntelligence.ShipGoal(ArtificialIntelligence.Plan.DoCombat, Vector2.Zero, 0f);
             this.State = AIState.Combat;
             this.OrderQueue.AddFirst(combat);
             return;
         }
     }
     else if (this.Target == null)
     {
         this.Owner.InCombat = false;
     }
 }
        protected virtual void CreateDroneBeam(Vector2 destination, GameplayObject target, DroneAI source)
        {
            if (source == null)
                return;
            Beam beam = new Beam(source.Owner.Center, target.Center, this.BeamThickness, source.Owner, target);
            beam.moduleAttachedTo = this.moduleAttachedTo;
            beam.PowerCost = (float)this.BeamPowerCostPerSecond;
            beam.range = this.Range;
            beam.thickness = this.BeamThickness;
            beam.Duration = (float)this.BeamDuration > 0 ? this.BeamDuration : 2f;
            beam.damageAmount = this.DamageAmount;
            beam.weapon = this;

                if(!beam.LoadContent(Weapon.universeScreen.ScreenManager, Weapon.universeScreen.view, Weapon.universeScreen.projection))

            {
                beam.Die(null, true);
                return;
            }
            source.Beams.Add(beam);
            this.ToggleSoundOn = false;
            if (Weapon.universeScreen.viewState <= UniverseScreen.UnivScreenState.SystemView)
            {
                //Added by McShooterz: Use sounds from new sound dictionary
                if (ResourceManager.SoundEffectDict.ContainsKey(this.fireCueName))
                {
                    AudioManager.PlaySoundEffect(ResourceManager.SoundEffectDict[fireCueName], Weapon.audioListener, source.Owner.emitter, 0.5f);
                }
                else
                {
                    if (!string.IsNullOrEmpty(this.fireCueName))
                    {
                        this.fireCue = AudioManager.GetCue(this.fireCueName);
                        this.fireCue.Apply3D(Weapon.audioListener, source.Owner.emitter);
                        this.fireCue.Play();
                    }
                }
                if (!string.IsNullOrEmpty(this.ToggleSoundName))
                {
                    this.ToggleSoundOn = true;
                    this.ToggleCue = AudioManager.GetCue(this.ToggleSoundName);
                    this.ToggleCue.Apply3D(Weapon.audioListener, source.Owner.emitter);
                    this.ToggleCue.Play();
                }
            }
        }
        public void OrderAttackSpecificTarget(Ship toAttack)
        {
            this.TargetQueue.Clear();

            if (toAttack == null)
            {
                return;
            }

            if (this.Owner.loyalty.GetRelations().ContainsKey(toAttack.loyalty))
            {
                if (!this.Owner.loyalty.GetRelations()[toAttack.loyalty].Treaty_Peace)
                {
                    if (this.State == AIState.AttackTarget && this.Target == toAttack)
                    {
                        return;
                    }
                    if (this.State == AIState.SystemDefender && this.Target == toAttack)
                    {
                        return;
                    }
                    if (this.Owner.Weapons.Count == 0 || this.Owner.Role == "troop")
                    {
                        this.OrderInterceptShip(toAttack);
                        return;
                    }
                    this.Intercepting = true;
                    lock (this.wayPointLocker)
                    {
                        this.ActiveWayPoints.Clear();
                    }
                    this.State = AIState.AttackTarget;
                    this.Target = toAttack;
                    this.Owner.InCombatTimer = 15f;
                    this.OrderQueue.Clear();
                    this.IgnoreCombat = false;
                    this.TargetQueue.Add(toAttack);
                    this.hasPriorityTarget = true;
                    this.HasPriorityOrder = false;
                    ArtificialIntelligence.ShipGoal combat = new ArtificialIntelligence.ShipGoal(ArtificialIntelligence.Plan.DoCombat, Vector2.Zero, 0f);
                    this.OrderQueue.AddLast(combat);
                    return;
                }
                this.OrderInterceptShip(toAttack);
            }
        }
 public void DamageMissile(GameplayObject source, float damageAmount)
 {
     this.Health -= damageAmount;
     if (base.Health <= 0f && this.Active)
     {
         this.DieNextFrame = true;
     }
 }
        //added by gremlin to run away
        public void OrderFlee(bool ClearOrders)
        {
            lock (this.wayPointLocker)
            {
                this.ActiveWayPoints.Clear();
            }
            this.Target = null;
            this.Intercepting = false;
            this.Owner.HyperspaceReturn();
            if (ClearOrders)
            {
                this.OrderQueue.Clear();
            }

            IOrderedEnumerable<SolarSystem> systemList =
                from solarsystem in this.Owner.loyalty.GetOwnedSystems()
                where solarsystem.combatTimer <=0 && Vector2.Distance(solarsystem.Position,this.Owner.Position) >300000
                orderby Vector2.Distance(this.Owner.Center, solarsystem.Position)
                select solarsystem;
            if (systemList.Count<SolarSystem>() > 0)
            {
                Planet item = systemList.First<SolarSystem>().PlanetList[0];
                this.OrbitTarget = item;
                ArtificialIntelligence.ShipGoal orbit = new ArtificialIntelligence.ShipGoal(ArtificialIntelligence.Plan.Orbit, Vector2.Zero, 0f)
                {
                    TargetPlanet = item
                };
                this.resupplyTarget = item;
                this.OrderQueue.AddLast(orbit);
                this.State = AIState.Flee;
            }
        }
 public void InitializeMissilePlanet(float initialSpeed, Vector2 direction, GameplayObject Target, Ship_Game.Planet p)
 {
     this.direction = direction;
     this.Center = p.Position;
     this.zStart = -2500f;
     this.velocity = (initialSpeed * direction) + (this.owner != null ? this.owner.Velocity : Vector2.Zero);
     this.radius = 1f;
     this.velocityMaximum = initialSpeed + (this.owner != null ? this.owner.Velocity.Length() : 0f);
     this.duration = this.range / initialSpeed * 2f;
     this.initialDuration = this.duration;
     this.planet = p;
     if (this.weapon.Animated == 1)
     {
         this.switchFrames = this.initialDuration / (float)this.weapon.Frames;
         if (this.weapon.LoopAnimation == 1)
         {
             this.AnimationFrame = (int)((this.system != null ? this.system.RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(0f, (float)(this.weapon.Frames - 1));
         }
     }
     Projectile projectile1 = this;
     projectile1.particleDelay = projectile1.particleDelay + this.weapon.particleDelay;
     if (this.weapon.Tag_Guided)
     {
         this.missileAI = new MissileAI(this);
         this.missileAI.SetTarget(Target);
     }
     if (this.ProjSO !=null &&(this.WeaponType == "Missile" || this.WeaponType == "Drone" || this.WeaponType == "Rocket") && (this.system != null && this.system.isVisible || this.isInDeepSpace))
     {
         this.wasAddedToSceneGraph = true;
         lock (GlobalStats.ObjectManagerLocker)
         {
             Projectile.universeScreen.ScreenManager.inter.ObjectManager.Submit(this.ProjSO);
         }
     }
     if (this.system == null)
     {
         Projectile.universeScreen.DSProjectilesToAdd.Add(this);
         UniverseScreen.DeepSpaceManager.CollidableProjectiles.Add(this);
     }
     else
     {
         //lock (GlobalStats.BucketLock)
         {
             this.system.spatialManager.CollidableProjectiles.Add(this);
             this.system.spatialManager.RegisterObject(this);
             this.system.spatialManager.CollidableObjects.Add(this);
         }
     }
     base.Initialize();
 }
 protected virtual void CreateProjectilesFromPlanet(Vector2 direction, Planet p, GameplayObject target)
 {
     Projectile projectile = new Projectile(p, direction)
     {
         range = this.Range,
         weapon = this,
         explodes = this.explodes,
         damageAmount = this.DamageAmount
     };
     if (this.RangeVariance)
     {
         projectile.range *= RandomMath.RandomBetween(0.9f, 1.1f);
     }
     projectile.explodes = this.explodes;
     projectile.damageRadius = this.DamageRadius;
     projectile.explosionradiusmod = this.ExplosionRadiusVisual;
     projectile.Health = this.HitPoints;
     projectile.speed = this.ProjectileSpeed;
     projectile.WeaponEffectType = this.WeaponEffectType;
     projectile.WeaponType = this.WeaponType;
     projectile.LoadContent(this.ProjectileTexturePath, this.ModelPath);
     projectile.RotationRadsPerSecond = this.RotationRadsPerSecond;
     projectile.ArmorPiercing = (byte)this.ArmourPen;
     /*
     if (this.ShieldPenChance > 0)
     {
         projectile.IgnoresShields = RandomMath.RandomBetween(0, 100) <= this.ShieldPenChance;
     } */
     this.ModifyProjectile(projectile);
     if(this.Tag_Guided)
         projectile.InitializeMissilePlanet(projectile.speed, direction, target, p);
     else
         projectile.InitializePlanet(projectile.speed, direction, p.Position);
     projectile.Radius = this.ProjectileRadius;
     if (this.Animated == 1)
     {
         string remainder = 0.ToString("00000.##");
         projectile.texturePath = string.Concat(this.AnimationPath, remainder);
     }
     p.Projectiles.Add(projectile);
     this.planetEmitter = new AudioEmitter()
     {
         Position = new Vector3(p.Position, 2500f)
     };
     if (Weapon.universeScreen.viewState <= UniverseScreen.UnivScreenState.SystemView)
     {
         projectile.DieSound = true;
         if (!string.IsNullOrEmpty(this.ToggleSoundName) && !this.ToggleSoundOn)
         {
             this.ToggleSoundOn = true;
             this.ToggleCue = AudioManager.GetCue(this.ToggleSoundName);
             this.ToggleCue.Apply3D(Weapon.audioListener, this.planetEmitter);
             this.ToggleCue.Play();
             this.lastFireSound = 0f;
             //Added by McShooterz: Use sounds from new sound dictionary
             if (ResourceManager.SoundEffectDict.ContainsKey(this.fireCueName))
             {
                 AudioManager.PlaySoundEffect(ResourceManager.SoundEffectDict[fireCueName], Weapon.audioListener, this.planetEmitter, 0.5f);
             }
             else
             {
                 this.fireCue = AudioManager.GetCue(this.fireCueName);
                 if (!this.owner.isPlayerShip())
                 {
                     this.fireCue.Apply3D(Weapon.audioListener, this.planetEmitter);
                 }
                 if (this.fireCue != null)
                 {
                     this.fireCue.Play();
                 }
             }
         }
         if (!string.IsNullOrEmpty(ResourceManager.WeaponsDict[this.UID].dieCue))
         {
             projectile.dieCueName = ResourceManager.WeaponsDict[this.UID].dieCue;
         }
         if (!string.IsNullOrEmpty(this.InFlightCue))
         {
             projectile.InFlightCue = this.InFlightCue;
         }
         try
         {
             if (this.ToggleCue == null)
             {
                 this.planetEmitter.Position = new Vector3(p.Position, -2500f);
                 this.lastFireSound = 0f;
                 //Added by McShooterz: Use sounds from new sound dictionary
                 if (ResourceManager.SoundEffectDict.ContainsKey(this.fireCueName))
                 {
                     AudioManager.PlaySoundEffect(ResourceManager.SoundEffectDict[fireCueName], Weapon.audioListener, this.planetEmitter, 0.5f);
                 }
                 else
                 {
                     this.fireCue = AudioManager.GetCue(this.fireCueName);
                     this.fireCue.Apply3D(Weapon.audioListener, this.planetEmitter);
                     if (this.fireCue != null)
                     {
                         this.fireCue.Play();
                     }
                 }
             }
         }
         catch
         {
         }
     }
 }
 public static void FireShieldAnimation(GameplayObject Obj, float Rotation, float Scale)
 {
     Shield shield = new Shield();
     Matrix w = ((Matrix.Identity * Matrix.CreateScale(1f)) * Matrix.CreateRotationZ(Rotation)) * Matrix.CreateTranslation(Obj.Center.X, Obj.Center.Y, 0f);
     shield.World = w;
     shield.Owner = Obj;
     shield.displacement = ShieldManager.y;
     shield.texscale = ShieldManager.z;
     shield.Rotation = Rotation;
     ShieldManager.shieldList.Add(shield);
 }
        protected virtual void CreateTargetedBeam(GameplayObject target)
        {
            Beam beam;
            //if (this.owner.Beams.pendingRemovals.TryPop(out beam))
            //{
            //    //beam = new Beam(this.moduleAttachedTo.Center, this.BeamThickness, this.moduleAttachedTo.GetParent(), target);
            //    beam.BeamRecreate(this.moduleAttachedTo.Center, this.BeamThickness, this.moduleAttachedTo.GetParent(), target);
            //    beam.moduleAttachedTo = this.moduleAttachedTo;
            //    beam.PowerCost = (float)this.BeamPowerCostPerSecond;
            //    beam.range = this.Range;
            //    beam.thickness = this.BeamThickness;
            //    beam.Duration = (float)this.BeamDuration > 0 ? this.BeamDuration : 2f;
            //    beam.damageAmount = this.DamageAmount;
            //    beam.weapon = this;

            //}
            //else

                {
                    beam = new Beam(this.moduleAttachedTo.Center, this.BeamThickness, this.moduleAttachedTo.GetParent(), target)
                {
                    moduleAttachedTo = this.moduleAttachedTo,
                    PowerCost = (float)this.BeamPowerCostPerSecond,
                    range = this.Range,
                    thickness = this.BeamThickness,
                    Duration = (float)this.BeamDuration > 0 ? this.BeamDuration : 2f,
                    damageAmount = this.DamageAmount,
                    weapon = this,
                    Destination=target.Center
                };

                }

            //damage increase by level
            if (this.owner.Level > 0)
            {
                beam.damageAmount += beam.damageAmount * (float)this.owner.Level * 0.05f;
            }
            //Hull bonus damage increase
            if (GlobalStats.ActiveModInfo != null && GlobalStats.ActiveModInfo.useHullBonuses)
            {
                HullBonus mod;
                if (ResourceManager.HullBonuses.TryGetValue(this.owner.shipData.Hull, out mod))
                    beam.damageAmount += beam.damageAmount * mod.DamageBonus;
            }
            this.ModifyProjectile(beam);

            if ( !beam.LoadContent(Weapon.universeScreen.ScreenManager, Weapon.universeScreen.view, Weapon.universeScreen.projection))
            {
                beam.Die(null, true);
                return;
            }
            this.moduleAttachedTo.GetParent().Beams.Add(beam);
            this.ToggleSoundOn = false;
            if (Weapon.universeScreen.viewState <= UniverseScreen.UnivScreenState.SystemView && this.moduleAttachedTo.GetParent().InFrustum)
            {
                //Added by McShooterz: Use sounds from new sound dictionary
                SoundEffect beamsound = null;
                if (ResourceManager.SoundEffectDict.TryGetValue(this.fireCueName,out beamsound))
                {
                    AudioManager.PlaySoundEffect(beamsound, Weapon.audioListener, this.owner.emitter, 0.5f);
                }
                else
                {
                    if (!string.IsNullOrEmpty(this.fireCueName))
                    {
                        this.fireCue = AudioManager.GetCue(this.fireCueName);
                        if (!this.owner.isPlayerShip())
                        {
                            this.fireCue.Apply3D(Weapon.audioListener, this.owner.emitter);
                        }
                        this.fireCue.Play();
                    }
                }
                if (!string.IsNullOrEmpty(this.ToggleSoundName))
                {
                    this.ToggleSoundOn = true;
                    this.ToggleCue = AudioManager.GetCue(this.ToggleSoundName);
                    this.ToggleCue.Apply3D(Weapon.audioListener, this.owner.emitter);
                    this.ToggleCue.Play();
                }
            }
        }
        public override bool Damage(GameplayObject source, float damageAmount)
        {
            if (this.ModuleType == ShipModuleType.Dummy)
            {
                this.ParentOfDummy.Damage(source, damageAmount);
                return true;
            }
            this.Parent.InCombatTimer = 15f;
            this.Parent.ShieldRechargeTimer = 0f;
            //Added by McShooterz: Fix for Ponderous, now negative dodgemod increases damage taken.
            if (source is Projectile)
            {
                this.Parent.LastDamagedBy = source;
                if (this.Parent.Role == "fighter" && this.Parent.loyalty.data.Traits.DodgeMod < 0f)
                {
                    damageAmount += damageAmount * Math.Abs(this.Parent.loyalty.data.Traits.DodgeMod);
                }
            }

            if (source is Ship && (source as Ship).Role == "fighter" && this.Parent.loyalty.data.Traits.DodgeMod < 0f)
            {
                damageAmount += damageAmount * Math.Abs(this.Parent.loyalty.data.Traits.DodgeMod);
            }
            //Added by McShooterz: shields keep charge when manually turned off
            if (this.shield_power <= 0f || shieldsOff || source is Projectile && (source as Projectile).IgnoresShields)
            {

                // Vulnerabilities and resistances for modules, XML-defined.

                if (source is Projectile && (source as Projectile).weapon.Tag_Kinetic)
                {
                    damageAmount = damageAmount - (damageAmount * this.KineticResist);
                }
                if (source is Projectile && (source as Projectile).weapon.Tag_Energy)
                {
                    damageAmount = damageAmount - (damageAmount * this.EnergyResist);
                }
                if (source is Projectile && (source as Projectile).weapon.Tag_Guided)
                {
                    damageAmount = damageAmount - (damageAmount * this.GuidedResist);
                }
                if (source is Projectile && (source as Projectile).weapon.Tag_Missile)
                {
                    damageAmount = damageAmount - (damageAmount * this.MissileResist);
                }
                if (source is Projectile && (source as Projectile).weapon.Tag_Hybrid)
                {
                    damageAmount = damageAmount - (damageAmount * this.HybridResist);
                }
                if (source is Projectile && (source as Projectile).weapon.Tag_Intercept)
                {
                    damageAmount = damageAmount - (damageAmount * this.InterceptResist);
                }
                if (source is Projectile && (source as Projectile).weapon.Tag_Explosive)
                {
                    damageAmount = damageAmount - (damageAmount * this.ExplosiveResist);
                }
                if (source is Projectile && (source as Projectile).weapon.Tag_Railgun)
                {
                    damageAmount = damageAmount - (damageAmount * this.RailgunResist);
                }
                if (source is Projectile && (source as Projectile).weapon.Tag_SpaceBomb)
                {
                    damageAmount = damageAmount - (damageAmount * this.SpaceBombResist);
                }
                if (source is Projectile && (source as Projectile).weapon.Tag_Bomb)
                {
                    damageAmount = damageAmount - (damageAmount * this.BombResist);
                }
                if (source is Projectile && (source as Projectile).weapon.Tag_BioWeapon)
                {
                    damageAmount = damageAmount - (damageAmount * this.BioWeaponResist);
                }
                if (source is Projectile && (source as Projectile).weapon.Tag_Drone)
                {
                    damageAmount = damageAmount - (damageAmount * this.DroneResist);
                }
                if (source is Projectile && (source as Projectile).weapon.Tag_Warp)
                {
                    damageAmount = damageAmount - (damageAmount * this.WarpResist);
                }
                if (source is Projectile && (source as Projectile).weapon.Tag_Torpedo)
                {
                    damageAmount = damageAmount - (damageAmount * this.TorpedoResist);
                }
                if (source is Projectile && (source as Projectile).weapon.Tag_Cannon)
                {
                    damageAmount = damageAmount - (damageAmount * this.CannonResist);
                }
                if (source is Projectile && (source as Projectile).weapon.Tag_Subspace)
                {
                    damageAmount = damageAmount - (damageAmount * this.SubspaceResist);
                }
                if (source is Projectile && (source as Projectile).weapon.Tag_PD)
                {
                    damageAmount = damageAmount - (damageAmount * this.PDResist);
                }
                if (source is Projectile && (source as Projectile).weapon.Tag_Flak)
                {
                    damageAmount = damageAmount - (damageAmount * this.FlakResist);
                }

                if (source is Beam && (source as Beam).weapon.Tag_Beam)
                {
                    damageAmount = damageAmount - (damageAmount * this.BeamResist);

                    // most of these simply don't apply to beam weapons, but calculated within this if to ensure different beam types also have resistances/vulnerabilities applied

                    if ((source as Beam).weapon.Tag_Kinetic)
                    {
                        damageAmount = damageAmount - (damageAmount * this.KineticResist);
                    }
                    if ((source as Beam).weapon.Tag_Energy)
                    {
                        damageAmount = damageAmount - (damageAmount * this.EnergyResist);
                    }
                    if ((source as Beam).weapon.Tag_Guided)
                    {
                        damageAmount = damageAmount - (damageAmount * this.GuidedResist);
                    }
                    if ((source as Beam).weapon.Tag_Missile)
                    {
                        damageAmount = damageAmount - (damageAmount * this.MissileResist);
                    }
                    if ((source as Beam).weapon.Tag_Hybrid)
                    {
                        damageAmount = damageAmount - (damageAmount * this.HybridResist);
                    }
                    if ((source as Beam).weapon.Tag_Intercept)
                    {
                        damageAmount = damageAmount - (damageAmount * this.InterceptResist);
                    }
                    if ((source as Beam).weapon.Tag_Explosive)
                    {
                        damageAmount = damageAmount - (damageAmount * this.ExplosiveResist);
                    }
                    if ((source as Beam).weapon.Tag_Railgun)
                    {
                        damageAmount = damageAmount - (damageAmount * this.RailgunResist);
                    }
                    if ((source as Beam).weapon.Tag_SpaceBomb)
                    {
                        damageAmount = damageAmount - (damageAmount * this.SpaceBombResist);
                    }
                    if ((source as Beam).weapon.Tag_Bomb)
                    {
                        damageAmount = damageAmount - (damageAmount * this.BombResist);
                    }
                    if ((source as Beam).weapon.Tag_BioWeapon)
                    {
                        damageAmount = damageAmount - (damageAmount * this.BioWeaponResist);
                    }
                    if ((source as Beam).weapon.Tag_Drone)
                    {
                        damageAmount = damageAmount - (damageAmount * this.DroneResist);
                    }
                    if ((source as Beam).weapon.Tag_Warp)
                    {
                        damageAmount = damageAmount - (damageAmount * this.WarpResist);
                    }
                    if ((source as Beam).weapon.Tag_Torpedo)
                    {
                        damageAmount = damageAmount - (damageAmount * this.TorpedoResist);
                    }
                    if ((source as Beam).weapon.Tag_Cannon)
                    {
                        damageAmount = damageAmount - (damageAmount * this.CannonResist);
                    }
                    if ((source as Beam).weapon.Tag_Subspace)
                    {
                        damageAmount = damageAmount - (damageAmount * this.SubspaceResist);
                    }
                    if ((source as Beam).weapon.Tag_PD)
                    {
                        damageAmount = damageAmount - (damageAmount * this.PDResist);
                    }
                    if ((source as Beam).weapon.Tag_Flak)
                    {
                        damageAmount = damageAmount - (damageAmount * this.FlakResist);
                    }

                }

                //Doc: If the resistance-modified damage amount is less than an armour's damage threshold, no damage is applied.
                if (damageAmount <= this.DamageThreshold)
                    damageAmount = 0f;

                //Added by McShooterz: ArmorBonus Hull Bonus
                if (GlobalStats.ActiveModInfo != null && GlobalStats.ActiveModInfo.useHullBonuses)
                {
                    HullBonus mod;
                    if (ResourceManager.HullBonuses.TryGetValue(this.GetParent().shipData.Hull, out mod))
                        damageAmount *= (1f - mod.ArmoredBonus);
                }
                if (source is Projectile && (source as Projectile).weapon.EMPDamage > 0f)
                {
                    Ship parent = this.Parent;
                    parent.EMPDamage = parent.EMPDamage + (source as Projectile).weapon.EMPDamage;
                }
                if (source is Beam)
                {
                    Vector2 vel = Vector2.Normalize((source as Beam).Source - this.Center);
                    if (RandomMath.RandomBetween(0f, 100f) > 90f && this.Parent.InFrustum)
                    {
                        ShipModule.universeScreen.flash.AddParticleThreadB(new Vector3((source as Beam).ActualHitDestination, this.Center3D.Z), Vector3.Zero);
                    }
                    if (this.Parent.InFrustum)
                    {
                        for (int i = 0; i < 20; i++)
                        {
                            ShipModule.universeScreen.sparks.AddParticleThreadB(new Vector3((source as Beam).ActualHitDestination, this.Center3D.Z), new Vector3(vel * RandomMath.RandomBetween(40f, 80f), RandomMath.RandomBetween(-25f, 25f)));
                        }
                    }
                    if ((source as Beam).weapon.PowerDamage > 0f)
                    {
                        this.Parent.PowerCurrent -= (source as Beam).weapon.PowerDamage;
                        if (this.Parent.PowerCurrent < 0f)
                        {
                            this.Parent.PowerCurrent = 0f;
                        }
                    }
                    if ((source as Beam).weapon.TroopDamageChance > 0f)
                    {
                        if (this.Parent.TroopList.Count > 0)
                        {
                            if (((this.Parent.GetSystem() != null ? this.Parent.GetSystem().RNG : Ship.universeScreen.DeepSpaceRNG)).RandomBetween(0f, 100f) < (source as Beam).weapon.TroopDamageChance)
                            {
                                Troop item = this.Parent.TroopList[0];
                                item.Strength = item.Strength - 1;
                                if (this.Parent.TroopList[0].Strength <= 0)
                                {
                                    this.Parent.TroopList.RemoveAt(0);
                                }
                            }
                        }
                        else if (this.Parent.MechanicalBoardingDefense > 0f && RandomMath.RandomBetween(0f, 100f) < (source as Beam).weapon.TroopDamageChance)
                        {
                            this.Parent.MechanicalBoardingDefense -= 1f;
                        }
                    }
                    if ((source as Beam).weapon.MassDamage > 0f)
                    {
                        this.Parent.Mass += (source as Beam).weapon.MassDamage;
                        this.Parent.velocityMaximum = this.Parent.Thrust / this.Parent.Mass;
                        this.Parent.speed = this.Parent.velocityMaximum;
                        this.Parent.rotationRadiansPerSecond = this.Parent.speed / 700f;
                    }
                    if ((source as Beam).weapon.RepulsionDamage > 0f)
                    {
                        Vector2 vtt = this.Center - (source as Beam).Owner.Center;
                        Ship velocity = this.Parent;
                        this.Parent.Velocity += (vtt * (source as Beam).weapon.RepulsionDamage) / this.Parent.Mass;
                    }
                }
                if (this.shield_power_max > 0f && !this.isExternal)
                {
                    return false;
                }

                if (this.ModuleType == ShipModuleType.Armor && source is Projectile)
                {
                    if ((source as Projectile).isSecondary)
                    {
                        Weapon shooter = (source as Projectile).weapon;
                        ResourceManager.WeaponsDict.TryGetValue(shooter.SecondaryFire, out shooter);
                        damageAmount *= shooter.EffectVsArmor;
                        //damageAmount *= (ResourceManager.GetWeapon(shooter.SecondaryFire).EffectVsArmor);
                    }
                    else
                    {
                        damageAmount *= (source as Projectile).weapon.EffectVsArmor;
                    }
                }
                else if (this.ModuleType == ShipModuleType.Armor && source is Beam)
                {
                    damageAmount *= (source as Beam).weapon.EffectVsArmor;
                }

                if (damageAmount > this.Health)
                {
                    this.Health = 0;
                }
                else
                {
                    this.Health -= damageAmount;
                }
                if (base.Health >= this.HealthMax)
                {
                    base.Health = this.HealthMax;
                    this.Active = true;
                    this.onFire = false;
                }
                if (base.Health / this.HealthMax < 0.5f)
                {
                    this.onFire = true;
                }
                if ((double)(this.Parent.Health / this.Parent.HealthMax) < 0.5 && (double)base.Health < 0.5 * (double)this.HealthMax)
                {
                    this.reallyFuckedUp = true;
                }
                foreach (ShipModule dummy in this.LinkedModulesList)
                {
                    dummy.DamageDummy(damageAmount);
                }
            }
            else
            {
                //Damage module health if shields fail from damage
                float damageAmountvsShields = damageAmount;

                if (source is Projectile)
                {
                    if ((source as Projectile).isSecondary)
                    {
                        Weapon shooter = (source as Projectile).weapon;
                        ResourceManager.WeaponsDict.TryGetValue(shooter.SecondaryFire, out shooter);
                        damageAmountvsShields *= shooter.EffectVSShields;
                        //damageAmountvsShields *= (ResourceManager.GetWeapon(shooter.SecondaryFire).EffectVSShields);
                    }
                    else
                    {
                        damageAmountvsShields *= (source as Projectile).weapon.EffectVSShields;
                    }
                }
                else if (source is Beam)
                {
                    damageAmountvsShields *= (source as Beam).weapon.EffectVSShields;
                }

                if (source is Projectile)
                {
                    if ((source as Projectile).weapon.Tag_Kinetic)
                    {
                        damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_kinetic_resist);
                    }
                    if ((source as Projectile).weapon.Tag_Energy)
                    {
                        damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_energy_resist);
                    }
                    if ((source as Projectile).weapon.Tag_Explosive)
                    {
                        damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_explosive_resist);
                    }
                    if ((source as Projectile).weapon.Tag_Missile)
                    {
                        damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_missile_resist);
                    }
                    if ((source as Projectile).weapon.Tag_Flak)
                    {
                        damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_flak_resist);
                    }
                    if ((source as Projectile).weapon.Tag_Hybrid)
                    {
                        damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_hybrid_resist);
                    }
                    if ((source as Projectile).weapon.Tag_Railgun)
                    {
                        damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_railgun_resist);
                    }
                    if ((source as Projectile).weapon.Tag_Subspace)
                    {
                        damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_subspace_resist);
                    }
                    if ((source as Projectile).weapon.Tag_Warp)
                    {
                        damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_warp_resist);
                    }
                }
                else if (source is Beam)
                {
                    if ((source as Beam).weapon.Tag_Kinetic)
                    {
                        damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_kinetic_resist);
                    }
                    if ((source as Beam).weapon.Tag_Energy)
                    {
                        damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_energy_resist);
                    }
                    if ((source as Beam).weapon.Tag_Explosive)
                    {
                        damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_explosive_resist);
                    }
                    if ((source as Beam).weapon.Tag_Missile)
                    {
                        damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_missile_resist);
                    }
                    if ((source as Beam).weapon.Tag_Flak)
                    {
                        damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_flak_resist);
                    }
                    if ((source as Beam).weapon.Tag_Hybrid)
                    {
                        damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_hybrid_resist);
                    }
                    if ((source as Beam).weapon.Tag_Railgun)
                    {
                        damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_railgun_resist);
                    }
                    if ((source as Beam).weapon.Tag_Subspace)
                    {
                        damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_subspace_resist);
                    }
                    if ((source as Beam).weapon.Tag_Warp)
                    {
                        damageAmountvsShields = damageAmountvsShields - (damageAmountvsShields * this.shield_warp_resist);
                    }
                }

                if (damageAmountvsShields <= this.shield_threshold)
                    damageAmountvsShields = 0f;

                if (damageAmountvsShields > this.shield_power)
                {
                    this.shield_power = 0;
                    this.Parent.UpdateShields();
                }
                else
                {
                    this.shield_power -= damageAmountvsShields;
                    this.Parent.UpdateShields();
                }

                if (ShipModule.universeScreen.viewState == UniverseScreen.UnivScreenState.ShipView && this.Parent.InFrustum)
                {
                    base.findAngleToTarget(this.Parent.Center, source.Center);
                    this.shield.Rotation = source.Rotation - 3.14159274f;
                    this.shield.displacement = 0f;
                    this.shield.texscale = 2.8f;
                    lock (GlobalStats.ObjectManagerLocker)
                    {
                        ShipModule.universeScreen.ScreenManager.inter.LightManager.Remove(this.shield.pointLight);
                        ShipModule.universeScreen.ScreenManager.inter.LightManager.Submit(this.shield.pointLight);
                    }
                    if (source is Beam)
                    {
                        if ((source as Beam).weapon.SiphonDamage > 0f)
                        {
                            this.shield_power -= (source as Beam).weapon.SiphonDamage;
                            if (this.shield_power < 0f)
                            {
                                this.shield_power = 0f;
                            }
                            (source as Beam).owner.PowerCurrent += (source as Beam).weapon.SiphonDamage;
                            if ((source as Beam).owner.PowerCurrent > (source as Beam).owner.PowerStoreMax)
                            {
                                (source as Beam).owner.PowerCurrent = (source as Beam).owner.PowerStoreMax;
                            }
                        }
                        this.shield.Rotation = MathHelper.ToRadians(HelperFunctions.findAngleToTarget(this.Center, (source as Beam).Source));
                        this.shield.pointLight.World = Matrix.CreateTranslation(new Vector3((source as Beam).ActualHitDestination, 0f));
                        this.shield.pointLight.DiffuseColor = new Vector3(0.5f, 0.5f, 1f);
                        this.shield.pointLight.Radius = this.shield_radius * 2f;
                        this.shield.pointLight.Intensity = RandomMath.RandomBetween(4f, 10f);
                        this.shield.displacement = 0f;
                        this.shield.Radius = this.radius;
                        this.shield.displacement = 0.085f * RandomMath.RandomBetween(1f, 10f);
                        this.shield.texscale = 2.8f;
                        this.shield.texscale = 2.8f - 0.185f * RandomMath.RandomBetween(1f, 10f);
                        this.shield.pointLight.Enabled = true;
                        Vector2 vel = (source as Beam).Source - this.Center;
                        vel = Vector2.Normalize(vel);
                        if (RandomMath.RandomBetween(0f, 100f) > 90f && this.Parent.InFrustum)
                        {
                            ShipModule.universeScreen.flash.AddParticleThreadA(new Vector3((source as Beam).ActualHitDestination, this.Center3D.Z), Vector3.Zero);
                        }
                        if (this.Parent.InFrustum)
                        {
                            for (int i = 0; i < 20; i++)
                            {
                                ShipModule.universeScreen.sparks.AddParticleThreadA(new Vector3((source as Beam).ActualHitDestination, this.Center3D.Z), new Vector3(vel * RandomMath.RandomBetween(40f, 80f), RandomMath.RandomBetween(-25f, 25f)));
                            }
                        }
                        if ((source as Beam).weapon.SiphonDamage > 0f)
                        {
                            this.shield_power -= (source as Beam).weapon.SiphonDamage;
                            if (this.shield_power < 0f)
                            {
                                this.shield_power = 0f;
                            }
                        }
                    }
                    else if (source is Projectile && !(source as Projectile).IgnoresShields && this.Parent.InFrustum)
                    {
                        Cue shieldcue = AudioManager.GetCue("sd_impact_shield_01");
                        shieldcue.Apply3D(ShipModule.universeScreen.listener, this.Parent.emitter);
                        shieldcue.Play();
                        this.shield.Radius = this.radius;
                        this.shield.displacement = 0.085f * RandomMath.RandomBetween(1f, 10f);
                        this.shield.texscale = 2.8f;
                        this.shield.texscale = 2.8f - 0.185f * RandomMath.RandomBetween(1f, 10f);
                        this.shield.pointLight.World = (source as Projectile).GetWorld();
                        this.shield.pointLight.DiffuseColor = new Vector3(0.5f, 0.5f, 1f);
                        this.shield.pointLight.Radius = this.radius;
                        this.shield.pointLight.Intensity = 8f;
                        this.shield.pointLight.Enabled = true;
                        Vector2 vel = Vector2.Normalize((source as Projectile).Center - this.Center);
                        ShipModule.universeScreen.flash.AddParticleThreadB(new Vector3((source as Projectile).Center, this.Center3D.Z), Vector3.Zero);
                        for (int i = 0; i < 20; i++)
                        {
                            ShipModule.universeScreen.sparks.AddParticleThreadB(new Vector3((source as Projectile).Center, this.Center3D.Z), new Vector3(vel * RandomMath.RandomBetween(40f, 80f), RandomMath.RandomBetween(-25f, 25f)));
                        }
                    }
                }
            }
            //Added by McShooterz: shields keep charge when manually turned off
            if (this.shield_power > 0f && !shieldsOff)
            {
                this.radius = this.shield_radius;
            }
            else
            {
                this.radius = 8f;
            }
            return true;
        }
        public virtual void Fire(Vector2 direction, GameplayObject target)
        {
            if (this.owner.engineState == Ship.MoveState.Warp || this.timeToNextFire > 0f ||! this.owner.CheckRangeToTarget(this,target))
                return;
            this.owner.InCombatTimer = 15f;

            this.timeToNextFire = this.fireDelay;

            if (this.moduleAttachedTo.Active && this.owner.PowerCurrent > this.PowerRequiredToFire && this.OrdinanceRequiredToFire <= this.owner.Ordinance)
            {
                //this.owner.supplyLock.EnterWriteLock();
                this.owner.Ordinance -= this.OrdinanceRequiredToFire;
                this.owner.PowerCurrent -= this.PowerRequiredToFire;
                //this.owner.supplyLock.ExitWriteLock();
                if (this.SalvoCount == 1)
                {
                    if (this.FireArc != 0)
                    {
                        float DegreesBetweenShots = (float)(this.FireArc / this.ProjectileCount);
                        float angleToTarget = this.findAngleToTarget(direction);
                        for (int i = 0; i < this.ProjectileCount; i++)
                        {
                            Vector2 newTarget = this.findTargetFromAngleAndDistance(this.moduleAttachedTo.Center, angleToTarget - (float)(this.FireArc / 2) + DegreesBetweenShots * (float)i, this.Range);
                            Vector2 fireDirection = this.findVectorToTarget(this.moduleAttachedTo.Center, newTarget);
                            fireDirection.Y = fireDirection.Y * -1f;
                            this.CreateProjectiles(Vector2.Normalize(fireDirection), target, true);
                        }
                        return;
                    }
                    if (this.FireCone <= 0)
                    {
                        for (int i = 0; i < this.ProjectileCount; i++)
                        {
                            this.CreateProjectiles(direction, target, true);
                        }
                        return;
                    }
                    float spread = RandomMath2.RandomBetween((float)(-this.FireCone / 2), (float)(this.FireCone / 2));
                    //renamed angletotarget,newtarget,firedirection
                    float angleToTarget2 = this.findAngleToTarget(direction);
                    Vector2 newTarget2 = this.findTargetFromAngleAndDistance(this.moduleAttachedTo.Center, angleToTarget2 + spread, this.Range);
                    Vector2 fireDirection2 = this.findVectorToTarget(this.moduleAttachedTo.Center, newTarget2);
                    fireDirection2.Y = fireDirection2.Y * -1f;
                    this.CreateProjectiles(Vector2.Normalize(fireDirection2), target, true);
                    return;
                }
                if (this.SalvoCount > 1)
                {
                    float TimeBetweenShots = this.SalvoTimer / (float)this.SalvoCount;
                    for (int j = 1; j < this.SalvoCount; j++)
                    {
                        Weapon.Salvo sal = new Weapon.Salvo()
                        {
                            Timing = (float)j * TimeBetweenShots,
                            Direction = direction
                        };
                        this.SalvoList.Add(sal);
                    }
                    this.SalvoTarget = target;
                    if (this.FireArc != 0)
                    {
                        float DegreesBetweenShots = (float)(this.FireArc / this.ProjectileCount);
                        float angleToTarget = this.findAngleToTarget(direction);
                        for (int i = 0; i < this.ProjectileCount; i++)
                        {
                            Vector2 newTarget = this.findTargetFromAngleAndDistance(this.moduleAttachedTo.Center, angleToTarget - (float)(this.FireArc / 2) + DegreesBetweenShots * (float)i, this.Range);
                            Vector2 fireDirection = this.findVectorToTarget(this.moduleAttachedTo.Center, newTarget);
                            fireDirection.Y = fireDirection.Y * -1f;
                            this.CreateProjectiles(Vector2.Normalize(fireDirection), target, true);
                        }
                        return;
                    }
                    if (this.FireCone > 0)
                    {
                        float spread = RandomMath2.RandomBetween((float)(-this.FireCone / 2), (float)(this.FireCone / 2));
                        float angleToTarget = this.findAngleToTarget(direction);
                        Vector2 newTarget = this.findTargetFromAngleAndDistance(this.moduleAttachedTo.Center, angleToTarget + spread, this.Range);
                        Vector2 fireDirection = this.findVectorToTarget(this.moduleAttachedTo.Center, newTarget);
                        fireDirection.Y = fireDirection.Y * -1f;
                        this.CreateProjectiles(Vector2.Normalize(fireDirection), target, true);
                        return;
                    }
                    for (int i = 0; i < this.ProjectileCount; i++)
                    {
                        this.CreateProjectiles(direction, target, true);
                    }
                    return;
                }
            }
        }