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;
                }
            }
        }
        //Added by McShooterz
        public bool CheckIfInsideFireArc(Weapon w, Ship ship)
        {
            Vector2 PickedPos = ship.Center;
            float radius = ship.radius;
            GlobalStats.WeaponArcChecks = GlobalStats.WeaponArcChecks + 1;
            float modifyRangeAR = 50f;
            float distance =Vector2.Distance(w.moduleAttachedTo.Center, PickedPos) ;
            if (!w.isBeam && this.GetAI().CombatState == CombatState.AttackRuns && w.SalvoTimer > 0 && distance / w.SalvoTimer < w.GetOwner().speed) //&& this.maxWeaponsRange < 2000
            {

                modifyRangeAR = this.speed * w.SalvoTimer;

                if (modifyRangeAR < 50)
                    modifyRangeAR = 50;

            }
            if (distance > w.GetModifiedRange() + modifyRangeAR + radius)
            {
                return false;
            }
            float halfArc = w.moduleAttachedTo.FieldOfFire / 2f;
            Vector2 toTarget = PickedPos - w.Center;
            float radians = (float)Math.Atan2((double)toTarget.X, (double)toTarget.Y);
            float angleToMouse = 180f - MathHelper.ToDegrees(radians);
            float facing = w.moduleAttachedTo.facing + MathHelper.ToDegrees(base.Rotation);
            if (facing > 360f)
            {
                facing = facing - 360f;
            }
            float difference = 0f;
            difference = Math.Abs(angleToMouse - facing);
            if (difference > halfArc)
            {
                if (angleToMouse > 180f)
                {
                    angleToMouse = -1f * (360f - angleToMouse);
                }
                if (facing > 180f)
                {
                    facing = -1f * (360f - facing);
                }
                difference = Math.Abs(angleToMouse - facing);
            }
            //float modifyRangeAR = 50f;
            //if (!w.isBeam && this.GetAI().CombatState == CombatState.AttackRuns && this.maxWeaponsRange < 2000 && w.SalvoTimer > 0)
            //{
            //    modifyRangeAR = this.speed * w.SalvoTimer;
            //}
            if (difference < halfArc )//&& Vector2.Distance(w.moduleAttachedTo.Center, PickedPos) < w.GetModifiedRange() + modifyRangeAR)
            {
                return true;
            }
            return false;
        }
 private void DoRepairBeamLogic(Weapon w)
 {
     //foreach (Ship ship in w.GetOwner().loyalty.GetShips()
     foreach (Ship ship in this.FriendliesNearby
         .Where(ship => ship.Active && ship != w.GetOwner()
             && ship.Health / ship.HealthMax <.9f
             && Vector2.Distance(this.Owner.Center, ship.Center) <= w.Range + 500f)
             .OrderBy(ship => ship.Health))
     {
         if (ship != null)
         {
             w.FireTargetedBeam(ship);
             return;
         }
     }
 }
        public ShipModule GetRandomInternalModule(Weapon source)
        {
            float nearest=0;
            float temp;

            Vector2 center = source.GetOwner() != null ? source.GetOwner().Center : source.Center;
            ModuleSlot ClosestES=null;

            foreach(ModuleSlot ES in this.ExternalSlots)
            {
                if (ES.module.ModuleType == ShipModuleType.Dummy || !ES.module.Active || ES.module.Health <=0)
                    continue;
                temp = Vector2.Distance(ES.module.Center, center);
                if (nearest == 0 || temp < nearest )
                {
                    nearest = temp;
                    ClosestES = ES;
                }
            }
            byte level = 0;
            if (ClosestES == null)
            {
                System.Diagnostics.Debug.WriteLine(string.Concat("GetRandomInternal: ClosestES was null: ExternalCount:",this.ExternalSlots.Count," Name: " ,this.VanityName ));
                return null;
            }
            if (source.GetOwner() != null)
                level = (byte)source.GetOwner().Level;

            lock (this.AttackerTargetting)
            {
                if (this.AttackerTargetting == null || !this.AttackerTargetting.Contains(ClosestES))
                    if (level > 1)
                    {
                        float Damageradius = Vector2.Distance(ClosestES.module.Center, this.Center); //16 * (7 - level);//
                        this.AttackerTargetting.Clear();
                        foreach (ModuleSlot slot in this.ModuleSlotList)
                        {
                            if (slot != null && slot.module.ModuleType != ShipModuleType.Dummy
                                                       && slot.module.Active && slot.module.Health > 0.0 && (!slot.module.isExternal || slot.module.quadrant == ClosestES.module.quadrant)
                                                       && Vector2.Distance(slot.module.Center, ClosestES.module.Center) < Damageradius)
                            {
                                this.AttackerTargetting.Add(slot);
                            }

                        }
                        this.AttackerTargetting = this.AttackerTargetting.OrderByDescending(slot => slot.module.TargetValue + (slot.module.Health < slot.module.HealthMax ? 1 : 0))

                               .ToList();
                    }
                    else
                    {
                        float Damageradius = Vector2.Distance(ClosestES.module.Center, this.Center);
                        this.AttackerTargetting.Clear();
                        foreach (ModuleSlot slot in this.ModuleSlotList)
                        {
                            if (slot != null && slot.module.ModuleType != ShipModuleType.Dummy
                                                       && slot.module.Active && slot.module.Health > 0.0 && (!slot.module.isExternal || slot.module.quadrant == ClosestES.module.quadrant)
                                                       && Vector2.Distance(slot.module.Center, ClosestES.module.Center) < Damageradius)
                            {
                                this.AttackerTargetting.Add(slot);
                            }

                        }
                    }
            }
            if (this.AttackerTargetting.Count == 0)
            {
                if (this.ExternalSlots.Count == 0)
                    return null;
                else return this.ExternalSlots[0].module;
            }

            {

                if (this.AttackerTargetting.Count == 0)
                    return null;
                int randomizer = this.AttackerTargetting.Count() / (level + 1);
                return this.AttackerTargetting[HelperFunctions.GetRandomIndex(randomizer)].module;
            }
        }