Example #1
0
        /// <summary>
        /// ECCM needs to be handled eventually
        /// </summary>

        /// <summary>
        /// Constructor for Missile Fire Controls
        /// </summary>
        /// <param name="MFCDef">MFC definition.</param>
        public MissileFireControlTN(ActiveSensorDefTN MFCDef)
        {
            m_oMFCSensorDef = MFCDef;
            isDestroyed     = false;

            m_lLinkedWeapons = new BindingList <MissileLauncherTN>();

            m_lMissilesInFlight = new BindingList <OrdnanceGroupTN>();

            m_oOpenFire = false;
            m_oTarget   = null;
            m_oPDState  = PointDefenseState.None;
            m_oPDRange  = 0;
        }
Example #2
0
 /// <summary>
 /// Simple deassignment of target to this mfc.
 /// </summary>
 public void clearTarget()
 {
     m_oTarget = null;
 }
Example #3
0
 /// <summary>
 /// Target assignment of waypoints.
 /// </summary>
 /// <param name="WPTarget">Waypoint</param>
 public void assignTarget(Waypoint WPTarget)
 {
     m_oTarget = new TargetTN(WPTarget);
 }
Example #4
0
 /// <summary>
 /// Target assignment of populations
 /// </summary>
 /// <param name="PopTarget">Population</param>
 public void assignTarget(Population PopTarget)
 {
     m_oTarget = new TargetTN(PopTarget);
 }
Example #5
0
 /// <summary>
 /// Target assignment of planets.
 /// </summary>
 /// <param name="PlanetTarget">planet</param>
 public void assignTarget(SystemBody PlanetTarget)
 {
     m_oTarget = new TargetTN(PlanetTarget);
 }
Example #6
0
 /// <summary>
 /// Simple assignment of a missile group as the target of this MFC
 /// </summary>
 /// <param name="OrdnanceTarget">missile group to be targetted.</param>
 public void assignTarget(OrdnanceGroupTN OrdnanceTarget)
 {
     m_oTarget = new TargetTN(OrdnanceTarget);
 }
        /// <summary>
        /// This function calculates whether a given BFC can intercept a missile
        /// </summary>
        /// <param name="RNG">RNG to use, should be the global one in _SE_</param>
        /// <param name="IncrementDistance">Range to the target missile</param>
        /// <param name="Ordnance">Ordnance we want to shoot at.</param>
        /// <param name="ShipFaction">Faction of the ship this BFC is on.</param>
        /// <param name="Contact">Contact of the taskgroup this BFC is in.</param>
        /// <param name="ShipOn">Ship this BFC is on.</param>
        /// <param name="WeaponsFired">Whether or not a weapon was fired. this is for the recharge list further up</param>
        /// <returns>whether the missile was intercepted.</returns>
        public bool InterceptTarget(Random RNG, int IncrementDistance, OrdnanceTN Ordnance, Faction ShipFaction, SystemContact Contact, ShipTN ShipOn, out bool WeaponsFired)
        {
            WeaponsFired = false;

            float ShipSpeed = ShipOn.CurrentSpeed;

            float track = (float)ShipFaction.BaseTracking;
            if (ShipSpeed > track)
                track = ShipSpeed;
            if (m_oBeamFireControlDef.tracking < track)
                track = m_oBeamFireControlDef.tracking;

            /// <summary>
            /// Throwaway target for point defense purposes.
            /// </summary>
            TargetTN OverrideTarget = new TargetTN(Ordnance.missileGroup);

            float Acc = GetFiringAccuracy(IncrementDistance, (int)track, OverrideTarget);
            int toHit = (int)Math.Floor(Acc * 100.0f);
            int range = (IncrementDistance + 1) * 10000;
            String Range = range.ToString("#,###0");

            foreach (BeamTN LinkedWeapon in m_lLinkedWeapons)
            {
                /// <summary>
                /// Certain weapons will have already fired one or more of their shots, but may still have more available.
                /// </summary>
                bool AcceptPartialFire = (LinkedWeapon.beamDef.componentType == ComponentTypeTN.Rail || LinkedWeapon.beamDef.componentType == ComponentTypeTN.AdvRail ||
                        LinkedWeapon.beamDef.componentType == ComponentTypeTN.Gauss) && (LinkedWeapon.shotsExpended < LinkedWeapon.beamDef.shotCount);

                if (LinkedWeapon.readyToFire() == true || AcceptPartialFire == true)
                {
                    if (LinkedWeapon.beamDef.componentType == ComponentTypeTN.Rail || LinkedWeapon.beamDef.componentType == ComponentTypeTN.AdvRail ||
                        LinkedWeapon.beamDef.componentType == ComponentTypeTN.Gauss)
                    {

                        WeaponsFired = LinkedWeapon.Fire();

                        /// <summary>
                        /// multi-hit weapons will be a little wierd as far as PD goes.
                        /// </summary>
                        if (WeaponsFired == false && AcceptPartialFire == true)
                            WeaponsFired = true;


                        int expended = LinkedWeapon.shotsExpended;
                        int ShotCount = LinkedWeapon.beamDef.shotCount;

                        for (int BeamShotIterator = expended; BeamShotIterator < ShotCount; BeamShotIterator++)
                        {
                            ushort Hit = (ushort)RNG.Next(1, 100);
                            LinkedWeapon.shotsExpended++;

                            if (toHit >= Hit)
                            {
                                String Entry = String.Format("{0} Fired at {1} km and hit.", LinkedWeapon.Name, Range);
                                MessageEntry Msg = new MessageEntry(MessageEntry.MessageType.FiringHit, Contact.Position.System, Contact, GameState.Instance.GameDateTime,
                                                                   GameState.Instance.LastTimestep, Entry);
                                ShipFaction.MessageLog.Add(Msg);
                                return true;
                            }
                            else
                            {
                                String Entry = String.Format("{0} Fired at {1} km and missed.", LinkedWeapon.Name, Range);
                                MessageEntry Msg = new MessageEntry(MessageEntry.MessageType.FiringHit, Contact.Position.System, Contact, GameState.Instance.GameDateTime,
                                                                   GameState.Instance.LastTimestep, Entry);
                                ShipFaction.MessageLog.Add(Msg);
                            }
                        }

                    }
                    else
                    {
                        ushort Hit = (ushort)RNG.Next(1, 100);

                        WeaponsFired = LinkedWeapon.Fire();

                        if (toHit >= Hit)
                        {
                            String Entry = String.Format("{0} Fired at {1} km and hit.", LinkedWeapon.Name, Range);
                            MessageEntry Msg = new MessageEntry(MessageEntry.MessageType.FiringHit, Contact.Position.System, Contact, GameState.Instance.GameDateTime,
                                                               GameState.Instance.LastTimestep, Entry);
                            ShipFaction.MessageLog.Add(Msg);
                            return true;
                        }
                        else
                        {
                            String Entry = String.Format("{0} Fired at {1} km and missed.", LinkedWeapon.Name, Range);
                            MessageEntry Msg = new MessageEntry(MessageEntry.MessageType.FiringHit, Contact.Position.System, Contact, GameState.Instance.GameDateTime,
                                                               GameState.Instance.LastTimestep, Entry);
                            ShipFaction.MessageLog.Add(Msg);
                        }
                    }
                }
            }

            foreach (TurretTN LinkedTurret in m_lLinkedTurrets)
            {
                /// <summary>
                /// Double, triple, and quad turrets have multiple shots.
                /// </summary>
                bool AcceptPartialFire = (LinkedTurret.shotsExpended < LinkedTurret.turretDef.totalShotCount);
                if (LinkedTurret.readyToFire() == true || AcceptPartialFire == true)
                {
                    WeaponsFired = LinkedTurret.Fire();

                    /// <summary>
                    /// multi-hit weapons will be a little wierd as far as PD goes.
                    /// </summary>
                    if (WeaponsFired == false && AcceptPartialFire == true)
                        WeaponsFired = true;

                    int expended = LinkedTurret.shotsExpended;
                    int ShotCount = LinkedTurret.turretDef.totalShotCount;

                    for (int TurretShotIterator = expended; TurretShotIterator < ShotCount; TurretShotIterator++)
                    {
                        ushort Hit = (ushort)RNG.Next(1, 100);
                        LinkedTurret.shotsExpended++;

                        if (toHit >= Hit)
                        {
                            String Entry = String.Format("{0} Fired at {1} km and hit.", LinkedTurret.Name, Range);
                            MessageEntry Msg = new MessageEntry(MessageEntry.MessageType.FiringHit, Contact.Position.System, Contact, GameState.Instance.GameDateTime,
                                                               GameState.Instance.LastTimestep, Entry);
                            ShipFaction.MessageLog.Add(Msg);
                            return true;
                        }
                        else
                        {
                            String Entry = String.Format("{0} Fired at {1} km and missed.", LinkedTurret.Name, Range);
                            MessageEntry Msg = new MessageEntry(MessageEntry.MessageType.FiringHit, Contact.Position.System, Contact, GameState.Instance.GameDateTime,
                                                               GameState.Instance.LastTimestep, Entry);
                            ShipFaction.MessageLog.Add(Msg);
                        }
                    }
                }
            }

            return false;
        }
Example #8
0
        /// <summary>
        /// Searches for a new missile or ship target.
        /// </summary>
        private void SearchForNewTarget()
        {
            bool hasSystem = ordnanceGroupFaction.DetectedContactLists.ContainsKey(Contact.Position.System);
            if (hasSystem)
            {

                /// <summary>
                /// Search for missile targets.
                /// </summary>
#warning magic number related to missile sensor resolution and target checking. Only res 1 sensors will go after missiles.
                if (Missiles[0].missileDef.aSD.resolution == 1)
                {
                    foreach (KeyValuePair<OrdnanceGroupTN, FactionContact> pair in ordnanceGroupFaction.DetectedContactLists[Contact.Position.System].DetectedMissileContacts)
                    {
                        /// <summary>
                        /// active detection exists for this missile group, and it hasn't been destroyed.
                        /// </summary>
                        if (pair.Value.active == true && pair.Key.missilesDestroyed != pair.Key.Missiles.Count)
                        {
                            float dist;
                            Contact.DistTable.GetDistance(pair.Key.contact, out dist);
                            int detection = missiles[0].missileDef.aSD.GetActiveDetectionRange(0, (int)Math.Ceiling(pair.Key.missiles[0].missileDef.size));
                            bool det = ordnanceGroupFaction.LargeDetection(dist, detection);

                            if (det == true)
                            {
                                /// <summary>
                                /// This is our new target.
                                /// </summary>
                                TargetTN newMissileTarget = new TargetTN(pair.Key);
                                for (int loop = 0; loop < Missiles.Count; loop++)
                                {
                                    Missiles[loop].target = newMissileTarget;
                                }

                                /// <summary>
                                /// sensor missiles may as well be treated like point defense missiles here, since they aren't connected to an MFC.
                                /// </summary>
                                pair.Key.ordGroupsTargetting.Add(this);
                                break;
                            }
                        }
                    }
                }
                else
                {
                    /// <summary>
                    /// search for ship targets.
                    /// </summary>
                    foreach (KeyValuePair<ShipTN, FactionContact> pair in ordnanceGroupFaction.DetectedContactLists[Contact.Position.System].DetectedContacts)
                    {
                        /// <summary>
                        /// Active tracking on this ship exists, and the ship itself hasn't been destroyed. If the ship is destroyed it will be cleaned up at the end of simEntity.
                        /// </summary>
                        if (pair.Value.active == true && pair.Key.IsDestroyed == false)
                        {
                            float dist;
                            Contact.DistTable.GetDistance(pair.Key.ShipsTaskGroup.Contact, out dist);
                            int detection = missiles[0].missileDef.aSD.GetActiveDetectionRange(Missiles[0].target.ship.TotalCrossSection, -1);
                            bool det = ordnanceGroupFaction.LargeDetection(dist, detection);

                            if (det == true)
                            {
                                /// <summary>
                                /// This is our new target.
                                /// </summary>
                                TargetTN newShipTarget = new TargetTN(pair.Key);
                                for (int loop = 0; loop < Missiles.Count; loop++)
                                {
                                    Missiles[loop].target = newShipTarget;
                                }
                                break;
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Get the accuracy at which this BFC can fire upon its target.
        /// </summary>
        /// <param name="RangeIncrement">distance to target</param>
        /// <param name="track">Tracking capability of beam weapon that accuracy is desired for.</param>
        /// <param name="Override">For FCs in PD mode, there will be no target, they should use override instead.</param>
        /// <returns>Firing accuracy.</returns>
        private float GetFiringAccuracy(int RangeIncrement, int track, TargetTN Override = null)
        {
            float FireAccuracy = m_oBeamFireControlDef.rangeAccuracyTable[RangeIncrement];

            TargetTN MyTarget = m_oTarget;

            if (MyTarget == null && Override != null)
            {
                MyTarget = Override;
            }

            /// <summary>
            /// Get Target_CurrentSpeed for accuracy calculations. Planets do not move so this can remain at 0 for that.
            int Target_CurrentSpeed = 0;
            switch (MyTarget.targetType)
            {
                case StarSystemEntityType.TaskGroup:
                    Target_CurrentSpeed = MyTarget.ship.CurrentSpeed;
                    break;
                case StarSystemEntityType.Missile:
                    Target_CurrentSpeed = (int)Math.Round(MyTarget.missileGroup.missiles[0].missileDef.maxSpeed);
                    break;
            }


            /// <summary>
            /// 100% accuracy due to tracking at this speed if this condition fails and target speed is less than or equal to tracking[99]
            /// </summary>
            if ((float)Target_CurrentSpeed > m_oBeamFireControlDef.trackingAccuracyTable[99])
            {
                /// <summary>
                /// 1% chance to hit  thanks to tracking being totally out classed.
                /// </summary>
                if ((float)Target_CurrentSpeed >= m_oBeamFireControlDef.trackingAccuracyTable[0])
                {
                    FireAccuracy = FireAccuracy * 0.01f;
                }
                else
                {
                    bool done = false;
                    int Base = 50;
                    int Cur = 50;
                    /// <summary>
                    /// Binary search through the tracking accuracy table. Base is base accuracy of 50, and Cur is where we are in the binary search.
                    /// The tracking accuracy table has 100 entries.
                    /// </summary>

                    while (!done)
                    {
                        /// <summary>
                        /// divide Cur by 2 as per binary search.
                        /// </summary>
                        Cur = Cur / 2;

                        /// <summary>
                        /// if the targets speed is greater than tracking at base go to the next condition. basically these two advance base forward by cur until Cur is reduced to 1 which 
                        /// indicates that there is no more granularity to be observed.
                        /// </summary>
                        if ((float)Target_CurrentSpeed > m_oBeamFireControlDef.trackingAccuracyTable[Base])
                        {
                            /// <summary>
                            /// If Cur is equal to one then either Base or Base - 1 is the accuracy we want. If its not one then it can be further subdivided.
                            /// </summary>
                            if (Cur == 1)
                            {
                                /// <summary>
                                /// Is the speed of the target closer to tracking[base] or tracking[base-1]?
                                /// </summary>
                                float t1 = (float)Target_CurrentSpeed - m_oBeamFireControlDef.trackingAccuracyTable[Base];
                                float t2 = (float)Target_CurrentSpeed - m_oBeamFireControlDef.trackingAccuracyTable[Base - 1];
                                if (t1 <= t2)
                                {
                                    FireAccuracy = FireAccuracy * ((float)Base / 100.0f);
                                    done = true;
                                }
                                else
                                {
                                    FireAccuracy = FireAccuracy * ((float)(Base - 1) / 100.0f);
                                    done = true;
                                }
                            }
                            Base = Base - Cur;
                        }
                        else if ((float)Target_CurrentSpeed < m_oBeamFireControlDef.trackingAccuracyTable[Base])
                        {
                            if (Cur == 1)
                            {
                                float t1 = m_oBeamFireControlDef.trackingAccuracyTable[Base] - (float)Target_CurrentSpeed;
                                float t2 = m_oBeamFireControlDef.trackingAccuracyTable[Base + 1] - (float)Target_CurrentSpeed;
                                if (t1 <= t2)
                                {
                                    FireAccuracy = FireAccuracy * ((float)Base / 100.0f);
                                    done = true;
                                }
                                else
                                {
                                    FireAccuracy = FireAccuracy * ((float)(Base + 1) / 100.0f);
                                    done = true;
                                }
                            }
                            Base = Base + Cur;
                        }
                        else
                        {
                            FireAccuracy = FireAccuracy * ((float)Base / 100.0f);
                            done = true;
                        }
                    }
                }
            }
            if (track < m_oBeamFireControlDef.tracking)
            {
                float fireAccMod = (float)track / m_oBeamFireControlDef.tracking;

                FireAccuracy = FireAccuracy * fireAccMod;
            }

            return FireAccuracy;
        }
Example #10
0
        /// <summary>
        /// The Fire control itself must determine if the target is in range of both itself and its weapons.
        /// </summary>
        /// <param name="DistanceToTarget">distance in KM to target.</param>
        /// <param name="RNG">RNG passed to this function from source further up the chain.</param>
        /// <param name="track">Base empire tracking or ship speed ,whichever is higher. Turrets should set track to their tracking speed.</param>
        /// <returns>Whether or not a weapon was able to fire.</returns>
        public bool FireWeapons(float DistanceToTarget, Random RNG, int track, ShipTN FiringShip)
        {
            if (DistanceToTarget > m_oBeamFireControlDef.range || (m_lLinkedWeapons.Count == 0 && m_lLinkedTurrets.Count == 0) || isDestroyed == true)
            {
                if (DistanceToTarget > m_oBeamFireControlDef.range)
                {
                    MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.FiringZeroHitChance, FiringShip.ShipsTaskGroup.Contact.Position.System, FiringShip.ShipsTaskGroup.Contact,
                                                         GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, (this.Name + " Zero % chance to hit."));

                    FiringShip.ShipsFaction.MessageLog.Add(NMsg);
                }

                return false;
            }
            else
            {
                /// <summary>
                /// Range * 2 / 10000.0;
                /// </summary>

                int RangeIncrement = (int)Math.Floor(DistanceToTarget / 5000.0f);
                float FireAccuracy = GetFiringAccuracy(RangeIncrement, track);


                /// <summary>
                /// Fire Accuracy is the likelyhood of a shot hitting from this FC at this point.
                /// ECM vs ECCM needs to be done around here as well.
                /// </summary>
                bool weaponFired = false;

                if (m_oTarget.targetType == StarSystemEntityType.TaskGroup)
                {

                    int toHit = (int)Math.Floor(FireAccuracy * 100.0f);
                    ushort Columns = m_oTarget.ship.ShipArmor.armorDef.cNum;

                    foreach (BeamTN LinkedWeapon in m_lLinkedWeapons)
                    {
                        if (LinkedWeapon.beamDef.range > DistanceToTarget && LinkedWeapon.readyToFire() == true)
                        {
                            RangeIncrement = (int)Math.Floor(DistanceToTarget / 10000.0f);

                            weaponFired = LinkedWeapon.Fire();

                            if (weaponFired == true)
                            {
                                for (int BeamShotIterator = 0; BeamShotIterator < LinkedWeapon.beamDef.shotCount; BeamShotIterator++)
                                {
                                    int Hit = RNG.Next(1, 100);

                                    if (toHit >= Hit)
                                    {
                                        String WeaponFireS = String.Format("{0} hit {1} damage at {2}% tohit", LinkedWeapon.Name, LinkedWeapon.beamDef.damage[RangeIncrement], toHit);

                                        MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.FiringHit, FiringShip.ShipsTaskGroup.Contact.Position.System, FiringShip.ShipsTaskGroup.Contact,
                                                                             GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, WeaponFireS);

                                        FiringShip.ShipsFaction.MessageLog.Add(NMsg);


                                        ushort location = (ushort)RNG.Next(0, Columns);
                                        bool ShipDest = m_oTarget.ship.OnDamaged(LinkedWeapon.beamDef.damageType, LinkedWeapon.beamDef.damage[RangeIncrement], location, FiringShip);

                                        if (ShipDest == true)
                                        {
                                            m_oTarget = null;
                                            m_oOpenFire = false;
                                            return weaponFired;
                                        }
                                    }
                                    else
                                    {
                                        String WeaponFireS = String.Format("{0} missed at {1}% tohit", LinkedWeapon.Name, toHit);

                                        MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.FiringMissed, FiringShip.ShipsTaskGroup.Contact.Position.System, FiringShip.ShipsTaskGroup.Contact,
                                                                             GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, WeaponFireS);

                                        FiringShip.ShipsFaction.MessageLog.Add(NMsg);
                                    }
                                }
                            }
                            else if (LinkedWeapon.isDestroyed == false)
                            {
                                String WeaponFireS = String.Format("{0} Recharging {1}/{2} Power", LinkedWeapon.Name, LinkedWeapon.currentCapacitor, LinkedWeapon.beamDef.weaponCapacitor);

                                MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.FiringRecharging, FiringShip.ShipsTaskGroup.Contact.Position.System, FiringShip.ShipsTaskGroup.Contact,
                                                                     GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, WeaponFireS);

                                FiringShip.ShipsFaction.MessageLog.Add(NMsg);
                            }
                        }
                    }

                    foreach (TurretTN LinkedTurret in m_lLinkedTurrets)
                    {
                        /// <summary>
                        /// turrets have changed tracking and therefore tohit from regular beams.
                        /// </summary>
                        FireAccuracy = GetFiringAccuracy(RangeIncrement, LinkedTurret.turretDef.tracking);
                        toHit = (int)Math.Floor(FireAccuracy * 100.0f);

                        if (LinkedTurret.turretDef.baseBeamWeapon.range > DistanceToTarget && LinkedTurret.readyToFire() == true)
                        {
                            RangeIncrement = (int)Math.Floor(DistanceToTarget / 10000.0f);

                            weaponFired = LinkedTurret.Fire();

                            if (weaponFired == true)
                            {
                                for (int TurretShotIterator = 0; TurretShotIterator < LinkedTurret.turretDef.totalShotCount; TurretShotIterator++)
                                {
                                    int Hit = RNG.Next(1, 100);

                                    if (toHit >= Hit)
                                    {
                                        String WeaponFireS = String.Format("{0} hit {1} damage at {2}% tohit", LinkedTurret.Name, LinkedTurret.turretDef.baseBeamWeapon.damage[RangeIncrement], toHit);

                                        MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.FiringHit, FiringShip.ShipsTaskGroup.Contact.Position.System, FiringShip.ShipsTaskGroup.Contact,
                                                                             GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, WeaponFireS);

                                        FiringShip.ShipsFaction.MessageLog.Add(NMsg);


                                        ushort location = (ushort)RNG.Next(0, Columns);
                                        bool ShipDest = m_oTarget.ship.OnDamaged(LinkedTurret.turretDef.baseBeamWeapon.damageType, LinkedTurret.turretDef.baseBeamWeapon.damage[RangeIncrement], location, FiringShip);

                                        if (ShipDest == true)
                                        {
                                            m_oTarget = null;
                                            m_oOpenFire = false;
                                            return weaponFired;
                                        }
                                    }
                                    else
                                    {
                                        String WeaponFireS = String.Format("{0} missed at {1}% tohit", LinkedTurret.Name, toHit);

                                        MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.FiringMissed, FiringShip.ShipsTaskGroup.Contact.Position.System, FiringShip.ShipsTaskGroup.Contact,
                                                                             GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, WeaponFireS);

                                        FiringShip.ShipsFaction.MessageLog.Add(NMsg);
                                    }
                                }
                            }
                            else if (LinkedTurret.isDestroyed == false)
                            {
                                String WeaponFireS = String.Format("{0} Recharging {1}/{2} Power", LinkedTurret.Name, LinkedTurret.currentCapacitor,
                                                                                                  (LinkedTurret.turretDef.baseBeamWeapon.weaponCapacitor * LinkedTurret.turretDef.multiplier));

                                MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.FiringRecharging, FiringShip.ShipsTaskGroup.Contact.Position.System, FiringShip.ShipsTaskGroup.Contact,
                                                                     GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, WeaponFireS);

                                FiringShip.ShipsFaction.MessageLog.Add(NMsg);
                            }
                        }
                    }

                    return weaponFired;
                }
                else if (m_oTarget.targetType == StarSystemEntityType.Missile)
                {
                    /// <summary>
                    /// this is for beam targetting on missiles.
                    /// </summary>
                    int toHit = (int)Math.Floor(FireAccuracy * 100.0f);

                    /// <summary>
                    /// have all targeted missiles been destroyed.
                    /// </summary>
                    bool noMissilesLeft = false;

                    /// <summary>
                    /// For all weapons linked to this BFC
                    /// </summary>
                    foreach (BeamTN LinkedWeapon in m_lLinkedWeapons)
                    {
                        /// <summary>
                        /// if range > distance and the weapon is ready to fire.
                        /// </summary>
                        if (LinkedWeapon.beamDef.range > DistanceToTarget && LinkedWeapon.readyToFire() == true)
                        {
                            RangeIncrement = (int)Math.Floor(DistanceToTarget / 10000.0f);

                            weaponFired = LinkedWeapon.Fire();

                            if (weaponFired == true)
                            {
                                /// <summary>
                                /// Some weapons have multiple shots, but most will have just 1.
                                /// </summary>
                                for (int BeamShotIterator = 0; BeamShotIterator < LinkedWeapon.beamDef.shotCount; BeamShotIterator++)
                                {
                                    int Hit = RNG.Next(1, 100);

                                    /// <summary>
                                    /// Did the weapon hit?
                                    /// </summary>
                                    if (toHit >= Hit)
                                    {
                                        ushort ToDestroy;
                                        if (m_oTarget.missileGroup.missiles[0].missileDef.armor == 0)
                                            ToDestroy = 100;
                                        else
                                            ToDestroy = (ushort)(Math.Round((LinkedWeapon.beamDef.damage[RangeIncrement] / (m_oTarget.missileGroup.missiles[0].missileDef.armor + LinkedWeapon.beamDef.damage[RangeIncrement]))) * 100.0f);
                                        ushort DestChance = (ushort)RNG.Next(1, 100);


                                        /// <summary>
                                        /// Does the weapon have the power to make a kill?
                                        /// </summary>
                                        if (ToDestroy >= DestChance)
                                        {
                                            String WeaponFireS = String.Format("{0} and destroyed a missile at {1}% tohit", LinkedWeapon.Name, toHit);

                                            MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.FiringHit, FiringShip.ShipsTaskGroup.Contact.Position.System, FiringShip.ShipsTaskGroup.Contact,
                                                                                 GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, WeaponFireS);

                                            FiringShip.ShipsFaction.MessageLog.Add(NMsg);

                                            /// <summary>
                                            /// Set destruction of targeted missile here. This is used by sim entity to determine how to handle missile group cleanup.
                                            /// </summary>
                                            m_oTarget.missileGroup.missilesDestroyed = m_oTarget.missileGroup.missilesDestroyed + 1;

                                            if (m_oTarget.missileGroup.missilesDestroyed == m_oTarget.missileGroup.missiles.Count)
                                            {
                                                break;
                                            }
                                        }
                                        else
                                        {
                                            String WeaponFireS = String.Format("{0} and failed to destroyed a missile at {1}% tohit", LinkedWeapon.Name, toHit);

                                            MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.FiringHit, FiringShip.ShipsTaskGroup.Contact.Position.System, FiringShip.ShipsTaskGroup.Contact,
                                                                                 GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, WeaponFireS);

                                            FiringShip.ShipsFaction.MessageLog.Add(NMsg);
                                        }
                                    }
                                    else
                                    {
                                        String WeaponFireS = String.Format("{0} missed at {1}% tohit", LinkedWeapon.Name, toHit);

                                        MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.FiringMissed, FiringShip.ShipsTaskGroup.Contact.Position.System, FiringShip.ShipsTaskGroup.Contact,
                                                                             GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, WeaponFireS);

                                        FiringShip.ShipsFaction.MessageLog.Add(NMsg);
                                    }
                                }//end for shot count
                            }
                            else if (LinkedWeapon.isDestroyed == false)
                            {
                                String WeaponFireS = String.Format("{0} Recharging {1}/{2} Power", LinkedWeapon.Name, LinkedWeapon.currentCapacitor, LinkedWeapon.beamDef.weaponCapacitor);

                                MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.FiringRecharging, FiringShip.ShipsTaskGroup.Contact.Position.System, FiringShip.ShipsTaskGroup.Contact,
                                                                     GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, WeaponFireS);

                                FiringShip.ShipsFaction.MessageLog.Add(NMsg);
                            }
                        }//end if in range and weapon can fire

                        if (m_oTarget.missileGroup.missilesDestroyed == m_oTarget.missileGroup.missiles.Count)
                        {
                            noMissilesLeft = true;
                            break;
                        }

                    }// end for linked weapons

                    if (noMissilesLeft == false)
                    {
                        foreach (TurretTN LinkedTurret in m_lLinkedTurrets) //(int loop = 0; loop < LinkedTurrets.Count; loop++)
                        {
                            FireAccuracy = GetFiringAccuracy(RangeIncrement, LinkedTurret.turretDef.tracking);
                            toHit = (int)Math.Floor(FireAccuracy * 100.0f);

                            if (LinkedTurret.turretDef.baseBeamWeapon.range > DistanceToTarget && LinkedTurret.readyToFire() == true)
                            {
                                RangeIncrement = (int)Math.Floor(DistanceToTarget / 10000.0f);

                                weaponFired = LinkedTurret.Fire();

                                if (weaponFired == true)
                                {
                                    /// <summary>
                                    /// Some weapons have multiple shots, but most will have just 1.
                                    /// </summary>
                                    for (int TurretShotIterator = 0; TurretShotIterator < LinkedTurret.turretDef.totalShotCount; TurretShotIterator++)
                                    {
                                        int Hit = RNG.Next(1, 100);

                                        /// <summary>
                                        /// Did the weapon hit?
                                        /// </summary>
                                        if (toHit >= Hit)
                                        {
                                            /// <summary>
                                            /// Did the weapon destroy its target?
                                            /// </summary>
                                            ushort ToDestroy;
                                            if (m_oTarget.missileGroup.missiles[0].missileDef.armor == 0)
                                                ToDestroy = 100;
                                            else
                                                ToDestroy = (ushort)(Math.Round((LinkedTurret.turretDef.baseBeamWeapon.damage[RangeIncrement] / (m_oTarget.missileGroup.missiles[0].missileDef.armor + LinkedTurret.turretDef.baseBeamWeapon.damage[RangeIncrement]))) * 100.0f);
                                            ushort DestChance = (ushort)RNG.Next(1, 100);

                                            /// <summary>
                                            /// Does the weapon have the power to make a kill?
                                            /// </summary>
                                            if (ToDestroy >= DestChance)
                                            {
                                                String WeaponFireS = String.Format("{0} and destroyed a missile at {1}% tohit", LinkedTurret.Name, toHit);

                                                MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.FiringHit, FiringShip.ShipsTaskGroup.Contact.Position.System, FiringShip.ShipsTaskGroup.Contact,
                                                                                     GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, WeaponFireS);

                                                FiringShip.ShipsFaction.MessageLog.Add(NMsg);

                                                /// <summary>
                                                /// Set destruction of targeted missile here. This is used by sim entity to determine how to handle missile group cleanup.
                                                /// </summary>
                                                m_oTarget.missileGroup.missilesDestroyed = m_oTarget.missileGroup.missilesDestroyed + 1;

                                                if (m_oTarget.missileGroup.missilesDestroyed == m_oTarget.missileGroup.missiles.Count)
                                                {
                                                    break;
                                                }
                                            }
                                            else
                                            {
                                                String WeaponFireS = String.Format("{0} and failed to destroyed a missile at {1}% tohit", LinkedTurret.Name, toHit);

                                                MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.FiringHit, FiringShip.ShipsTaskGroup.Contact.Position.System, FiringShip.ShipsTaskGroup.Contact,
                                                                                     GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, WeaponFireS);

                                                FiringShip.ShipsFaction.MessageLog.Add(NMsg);
                                            }
                                        }
                                        else
                                        {
                                            String WeaponFireS = String.Format("{0} missed at {1}% tohit", LinkedTurret.Name, toHit);

                                            MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.FiringMissed, FiringShip.ShipsTaskGroup.Contact.Position.System, FiringShip.ShipsTaskGroup.Contact,
                                                                                 GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, WeaponFireS);

                                            FiringShip.ShipsFaction.MessageLog.Add(NMsg);
                                        }

                                    }
                                }//end if weapon fired
                            }//end if in range and can fire

                            if (m_oTarget.missileGroup.missilesDestroyed == m_oTarget.missileGroup.missiles.Count)
                            {
                                /// <summary>
                                /// This is cargo culting and this variable does not need to be set here, but for completeness sake I'll include it.
                                /// </summary>
                                noMissilesLeft = true;

                                break;
                            }
                        }//end for linkedturrets.
                    }//end if noMissilesLeft = true


                    return weaponFired;
                }
                else if(m_oTarget.targetType == StarSystemEntityType.Population)
                {
                    /// <summary>
                    /// Planets can't dodge and will always be hit.
                    /// </summary>
                    foreach (BeamTN LinkedWeapon in m_lLinkedWeapons)
                    {
                        if (LinkedWeapon.beamDef.range > DistanceToTarget && LinkedWeapon.readyToFire() == true)
                        {
                            RangeIncrement = (int)Math.Floor(DistanceToTarget / 10000.0f);

                            weaponFired = LinkedWeapon.Fire();

                            if (weaponFired == true)
                            {
                                for (int BeamShotIterator = 0; BeamShotIterator < LinkedWeapon.beamDef.shotCount; BeamShotIterator++)
                                {
                                    bool PopDamaged = m_oTarget.pop.OnDamaged(LinkedWeapon.beamDef.damageType, LinkedWeapon.beamDef.damage[RangeIncrement], FiringShip);
                                }
                            }
                        }
                        else if (LinkedWeapon.isDestroyed == false)
                        {
                            String WeaponFireS = String.Format("{0} Recharging {1}/{2} Power", LinkedWeapon.Name, LinkedWeapon.currentCapacitor, LinkedWeapon.beamDef.weaponCapacitor);

                            MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.FiringRecharging, FiringShip.ShipsTaskGroup.Contact.Position.System, FiringShip.ShipsTaskGroup.Contact,
                                                                 GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, WeaponFireS);

                            FiringShip.ShipsFaction.MessageLog.Add(NMsg);
                        }
                    }

                    foreach (TurretTN LinkedTurret in m_lLinkedTurrets)
                    {
                        if (LinkedTurret.turretDef.baseBeamWeapon.range > DistanceToTarget && LinkedTurret.readyToFire() == true)
                        {
                            RangeIncrement = (int)Math.Floor(DistanceToTarget / 10000.0f);

                            weaponFired = LinkedTurret.Fire();

                            if (weaponFired == true)
                            {
                                for (int TurretShotIterator = 0; TurretShotIterator < LinkedTurret.turretDef.totalShotCount; TurretShotIterator++)
                                {
                                    bool ShipDest = m_oTarget.pop.OnDamaged(LinkedTurret.turretDef.baseBeamWeapon.damageType, LinkedTurret.turretDef.baseBeamWeapon.damage[RangeIncrement], FiringShip); 
                                }
                            }
                            else if (LinkedTurret.isDestroyed == false)
                            {
                                String WeaponFireS = String.Format("{0} Recharging {1}/{2} Power", LinkedTurret.Name, LinkedTurret.currentCapacitor,
                                                                                                  (LinkedTurret.turretDef.baseBeamWeapon.weaponCapacitor * LinkedTurret.turretDef.multiplier));

                                MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.FiringRecharging, FiringShip.ShipsTaskGroup.Contact.Position.System, FiringShip.ShipsTaskGroup.Contact,
                                                                     GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, WeaponFireS);

                                FiringShip.ShipsFaction.MessageLog.Add(NMsg);
                            }
                        }
                    }
                    return weaponFired;
                }

                /// <summary>
                /// If I am targetting something that BFCs can't handle yet or shouldn't be able to handle just return false for now.
                /// </summary>
                return false;
            }
        }
Example #11
0
 /// <summary>
 /// assignment of a population as the target
 /// </summary>
 /// <param name="PopTarget">Population to be targetted</param>
 public void assignTarget(Population PopTarget)
 {
     TargetTN NewPopTarget = new TargetTN(PopTarget);
     m_oTarget = NewPopTarget;
 }
Example #12
0
 /// <summary>
 /// Assignment of a missile group as a target.
 /// </summary>
 /// <param name="OrdGroupTarget">ordnance group to be targetted</param>
 public void assignTarget(OrdnanceGroupTN OrdGroupTarget)
 {
     TargetTN NewOrdTarget = new TargetTN(OrdGroupTarget);
     m_oTarget = NewOrdTarget;
 }
Example #13
0
 /// <summary>
 /// Simple assignment of a ship as a target to this bfc.
 /// </summary>
 /// <param name="ShipTarget">Ship to be targeted.</param>
 public void assignTarget(ShipTN ShipTarget)
 {
     TargetTN NewShipTarget = new TargetTN(ShipTarget);
     m_oTarget = NewShipTarget;
 }
Example #14
0
        /// <summary>
        /// Constructor for BFC components.
        /// </summary>
        /// <param name="definition">Definition of this component</param>
        public BeamFireControlTN(BeamFireControlDefTN definition)
        {
            m_oBeamFireControlDef = definition;
            isDestroyed = false;

            m_lLinkedWeapons = new BindingList<BeamTN>();
            m_lLinkedTurrets = new BindingList<TurretTN>();

            m_oTarget = null;
            m_oOpenFire = false;
            m_oPDState = PointDefenseState.None;
            m_oPDRange = 0;
        }
Example #15
0
        /// <summary>
        /// ECCM needs to be handled eventually
        /// </summary>

        /// <summary>
        /// Constructor for Missile Fire Controls
        /// </summary>
        /// <param name="MFCDef">MFC definition.</param>
        public MissileFireControlTN(ActiveSensorDefTN MFCDef)
        {
            m_oMFCSensorDef = MFCDef;
            isDestroyed = false;

            m_lLinkedWeapons = new BindingList<MissileLauncherTN>();

            m_lMissilesInFlight = new BindingList<OrdnanceGroupTN>();

            m_oOpenFire = false;
            m_oTarget = null;
            m_oPDState = PointDefenseState.None;
            m_oPDRange = 0;
        }
Example #16
0
        /// <summary>
        /// Method to create a waypoint target for a missile that has lost tracking to its target.
        /// </summary>
        /// <param name="loop">index of missile that needs a waypoint target, they will all be called should this be needed however.</param>
        private void CreateWaypointTarget()
        {
            /// <summary>
            /// Create new WP Target Here:
            /// </summary>
            double X = 0.0, Y = 0.0;
            switch (missiles[0].target.targetType)
            {
                case StarSystemEntityType.TaskGroup:
                    X = missiles[0].target.ship.ShipsTaskGroup.Contact.Position.X;
                    Y = missiles[0].target.ship.ShipsTaskGroup.Contact.Position.Y;
                    break;

                case StarSystemEntityType.Missile:
                    X = missiles[0].target.missileGroup.contact.Position.X;
                    Y = missiles[0].target.missileGroup.contact.Position.Y;
                    break;
            }
            Waypoint NewTarget = new Waypoint("Internal Missile Target, Do Not Display", Contact.Position.System, X, Y, OrdnanceGroupFaction.FactionID);
            TargetTN newTargetTN = new TargetTN(NewTarget);
            for (int loop = 0; loop < Missiles.Count; loop++)
                missiles[loop].target = newTargetTN;
        }
Example #17
0
 /// <summary>
 /// Simple assignment of a ship as a target to this mfc.
 /// </summary>
 /// <param name="ShipTarget">Ship to be targeted.</param>
 public void assignTarget(ShipTN ShipTarget)
 {
     m_oTarget = new TargetTN(ShipTarget);
 }
Example #18
0
        /// <summary>
        /// End Copy Paste from Ship.cs
        /// </summary>

        /// <summary>
        /// Constructor for missiles.
        /// </summary>
        /// <param name="mfCtrl">MFC directing this missile.</param>
        /// <param name="definition">definition of the missile.</param>
        public OrdnanceTN(MissileFireControlTN mfCtrl, OrdnanceDefTN definition, ShipTN ShipFiredFrom)
            : base()
        {
            Name = definition.Name;

            MFC = mfCtrl;

            Target = MFC.target;

            FiringShip = ShipFiredFrom;

            MissileDef = definition;

            /// <summary>
            /// Litres of fuel available to this missile.
            /// </summary>
            Fuel = definition.fuel * 2500.0f;

            Separated = false;
            OnOwnSensors = false;
        }
Example #19
0
 /// <summary>
 /// Target assignment of planets.
 /// </summary>
 /// <param name="PlanetTarget">planet</param>
 public void assignTarget(Planet PlanetTarget)
 {
     m_oTarget = new TargetTN(PlanetTarget);
 }