コード例 #1
0
        /// <summary>
        /// Constructor for detected contact related order.
        /// </summary>
        /// <param name="TypeOrder">Type</param>
        /// <param name="SecondaryOrder">Secondary</param>
        /// <param name="TertiaryOrder">Tertiary</param>
        /// <param name="Delay">Order delay</param>
        /// <param name="ShipsOrder">Ship target of order</param>
        public Orders(Constants.ShipTN.OrderType TypeOrder, int SecondaryOrder, int TertiaryOrder, int Delay, ShipTN ShipsOrder)
        {
            TypeOf     = TypeOrder;
            Target     = ShipsOrder.ShipsTaskGroup.Contact;
            Secondary  = SecondaryOrder;
            Tertiary   = TertiaryOrder;
            ShipOrder  = ShipsOrder;
            TaskGroup  = ShipsOrder.ShipsTaskGroup;
            OrderDelay = Delay;

            OrderTimeRequirement = -1;

            Name = TypeOrder.ToString() + " " + ShipOrder.Name.ToString();
        }
コード例 #2
0
        /// <summary>
        /// Initializer for detected ship event. FactionContact is the detector side of what is detected, while ShipTN itself stores the detectee side.
        /// multiple of these can exist, but only 1 per faction hopefully.
        /// </summary>
        /// <param name="DetectedShip">Ship detected.</param>
        /// <param name="Thermal">Was the detection thermal based?</param>
        /// <param name="em">Detection via EM?</param>
        /// <param name="Active">Active detection?</param>
        /// <param name="tick">What tick did this detection event occur on?</param>
        public FactionContact(Faction CurrentFaction, ShipTN DetectedShip, bool Thermal, bool em, int EMSig, bool Active, uint tick, uint year)
        {
            ship         = DetectedShip;
            missileGroup = null;
            pop          = null;
            thermal      = Thermal;
            EM           = em;
            EMSignature  = EMSig;
            active       = Active;

            String Contact = "New contact detected:";

            if (thermal == true)
            {
                thermalTick = tick;
                thermalYear = year;
                Contact     = String.Format("{0} Thermal Signature {1}", Contact, DetectedShip.CurrentThermalSignature);
            }

            if (EM == true)
            {
                EMTick  = tick;
                EMYear  = year;
                Contact = String.Format("{0} EM Signature {1}", Contact, EMSignature);
            }

            if (active == true)
            {
                activeTick = tick;
                activeYear = year;
                Contact    = String.Format("{0} TCS {1}", Contact, DetectedShip.TotalCrossSection);
            }

            /// <summary>
            /// Print to the message log.
            /// </summary>
            MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.ContactNew, DetectedShip.ShipsTaskGroup.Contact.Position.System, DetectedShip.ShipsTaskGroup.Contact,
                                                 GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Contact);

            CurrentFaction.MessageLog.Add(NMsg);

            /// <summary>
            /// Inform SimEntity.
            /// </summary>
            GameState.SE.SetInterrupt(InterruptType.NewSensorContact);
        }
コード例 #3
0
ファイル: OrdnanceTN.cs プロジェクト: EterniaLogic/Pulsar4x
        /// <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;
        }
コード例 #4
0
        /// <summary>
        /// Fire this MFC in point defense mode.
        /// </summary>
        /// <param name="TG">Taskgroup the MFC is in</param>
        /// <param name="FiredFrom">Ship the MFC is on</param>
        /// <param name="Target">Target of point defense fire.</param>
        /// <param name="MissilesToFire">Number of missiles to fire at it</param>
        /// <returns></returns>
        public int FireWeaponsPD(TaskGroupTN TG, ShipTN FiredFrom, OrdnanceGroupTN Target, int MissilesToFire)
        {
            /// <summary>
            /// simple stupid sanity check.
            /// </summary>
            if (MissilesToFire == 0)
            {
                return(0);
            }

            int LaunchCount = 0;
            /// <summary>
            /// Just a temporary variable for this function.
            /// </summary>
            BindingList <OrdnanceGroupTN> LocalMissileGroups = new BindingList <OrdnanceGroupTN>();

            foreach (MissileLauncherTN LaunchTube in m_lLinkedWeapons) //int loop = 0; loop < LinkedWeapons.Count; loop++)
            {
                if (LaunchTube.isDestroyed == false && LaunchTube.loadTime == 0 && LaunchTube.loadedOrdnance != null)
                {
                    if (FiredFrom.ShipOrdnance.ContainsKey(LaunchTube.loadedOrdnance) == true)
                    {
                        OrdnanceTN newMissile = new OrdnanceTN(this, LaunchTube.loadedOrdnance, FiredFrom);

                        /// <summary>
                        /// Point defense does not go by MFC targetting. have to add target here.
                        /// </summary>
                        newMissile.target = new TargetTN(Target);

                        LaunchCount++;

                        /// <summary>
                        /// Create a new missile group
                        /// </summary>
                        if (LocalMissileGroups.Count == 0)
                        {
                            OrdnanceGroupTN newMissileGroup = new OrdnanceGroupTN(TG, newMissile);
                            LocalMissileGroups.Add(newMissileGroup);
                            TG.TaskGroupFaction.MissileGroups.Add(newMissileGroup);

                            /// <summary>
                            /// Add this ordnance group to the ord groups targetting list for the intended target missile group.
                            /// This is only necessary here as Manually fired MFC missiles are connected to their MFC.
                            /// </summary>
                            Target.ordGroupsTargetting.Add(newMissileGroup);
                        }
                        /// <summary>
                        /// An existing missile group may be useable.
                        /// </summary>
                        else
                        {
                            bool foundGroup = false;
                            foreach (OrdnanceGroupTN OrdGroup in LocalMissileGroups)
                            {
                                /// <summary>
                                /// All Missile groups should be composed of just 1 type of missile for convienence.
                                if (OrdGroup.missiles[0].missileDef.Id == LaunchTube.loadedOrdnance.Id)
                                {
                                    OrdGroup.AddMissile(newMissile);
                                    foundGroup = true;
                                    break;
                                }
                            }

                            /// <summary>
                            /// Have to create a new missile group after all.
                            /// </summary>
                            if (foundGroup == false)
                            {
                                OrdnanceGroupTN newMissileGroup = new OrdnanceGroupTN(TG, newMissile);
                                LocalMissileGroups.Add(newMissileGroup);
                                TG.TaskGroupFaction.MissileGroups.Add(newMissileGroup);

                                /// <summary>
                                /// Add this ordnance group to the ord groups targetting list for the intended target missile group.
                                /// This is only necessary here as Manually fired MFC missiles are connected to their MFC.
                                /// </summary>
                                Target.ordGroupsTargetting.Add(newMissileGroup);
                            }
                        }
                        /// <summary>
                        /// Decrement the loaded ordnance count, and remove the type entirely if this was the last one.
                        /// </summary>
                        FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] = FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] - 1;
                        if (FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] == 0)
                        {
                            FiredFrom.ShipOrdnance.Remove(LaunchTube.loadedOrdnance);
                        }

                        /// <summary>
                        /// Set the launch tube cooldown time as a missile was just fired from it.
                        /// </summary>
                        LaunchTube.loadTime = LaunchTube.missileLauncherDef.rateOfFire;

                        if (LaunchCount == MissilesToFire)
                        {
                            break;
                        }
                    }
                    else
                    {
                        String       Msg        = String.Format("No ordnance {0} on ship {1} is available for Launch Tube {2} in PD Mode", LaunchTube.Name, FiredFrom.Name, LaunchTube.Name);
                        MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.FiringNoAvailableOrdnance, TG.Contact.Position.System, TG.Contact,
                                                                   GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg);
                        TG.TaskGroupFaction.MessageLog.Add(newMessage);
                    }
                }
                else if (LaunchTube.isDestroyed == true)
                {
                    String       Msg        = String.Format("Destroyed launch tube {0} is still attached to {1}'s MFC in PD Mode", LaunchTube.Name, FiredFrom.Name);
                    MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.Error, TG.Contact.Position.System, TG.Contact,
                                                               GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg);
                    TG.TaskGroupFaction.MessageLog.Add(newMessage);
                }
                else if (LaunchTube.loadedOrdnance == null)
                {
                    String       Msg        = String.Format("No loaded ordnance for launch tube {0} on ship {1} in PD Mode", LaunchTube.Name, FiredFrom.Name);
                    MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.FiringNoLoadedOrdnance, TG.Contact.Position.System, TG.Contact,
                                                               GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg);
                    TG.TaskGroupFaction.MessageLog.Add(newMessage);
                }
            }
            return(LaunchCount);
        }
コード例 #5
0
        /// <summary>
        /// Fire Weapons spawns new missiles groups or adds missiles to existing ones.
        /// </summary>
        /// <param name="TG">Taskgroup this MFC is in.</param>
        /// <param name="FiredFrom">Ship these missiles were fired from.</param>
        /// <returns>If missiles were fired at all from this MFC. true = atleast 1 missile(and therefore missile group, false = no missiles.</returns>
        public bool FireWeapons(TaskGroupTN TG, ShipTN FiredFrom)
        {
            bool retv = false;

            if (m_oTarget != null)
            {
                /// <summary>
                /// Just a temporary variable for this function.
                /// </summary>
                BindingList <OrdnanceGroupTN> LocalMissileGroups = new BindingList <OrdnanceGroupTN>();

                foreach (MissileLauncherTN LaunchTube in m_lLinkedWeapons)
                {
                    if (LaunchTube.isDestroyed == false && LaunchTube.loadTime == 0 && LaunchTube.loadedOrdnance != null)
                    {
                        if (FiredFrom.ShipOrdnance.ContainsKey(LaunchTube.loadedOrdnance) == true)
                        {
                            OrdnanceTN newMissile = new OrdnanceTN(this, LaunchTube.loadedOrdnance, FiredFrom);

                            /// <summary>
                            /// Create a new missile group
                            /// </summary>
                            if (LocalMissileGroups.Count == 0)
                            {
                                OrdnanceGroupTN newMissileGroup = new OrdnanceGroupTN(TG, newMissile);
                                LocalMissileGroups.Add(newMissileGroup);
                                TG.TaskGroupFaction.MissileGroups.Add(newMissileGroup);
                            }
                            /// <summary>
                            /// An existing missile group may be useable.
                            /// </summary>
                            else
                            {
                                bool foundGroup = false;
                                foreach (OrdnanceGroupTN OrdGroup in LocalMissileGroups)
                                {
                                    /// <summary>
                                    /// All Missile groups should be composed of just 1 type of missile for convienence.
                                    if (OrdGroup.missiles[0].missileDef.Id == LaunchTube.loadedOrdnance.Id)
                                    {
                                        OrdGroup.AddMissile(newMissile);
                                        foundGroup = true;
                                        break;
                                    }
                                }

                                /// <summary>
                                /// Have to create a new missile group after all.
                                /// </summary>
                                if (foundGroup == false)
                                {
                                    OrdnanceGroupTN newMissileGroup = new OrdnanceGroupTN(TG, newMissile);
                                    LocalMissileGroups.Add(newMissileGroup);
                                    TG.TaskGroupFaction.MissileGroups.Add(newMissileGroup);
                                }
                            }
                            /// <summary>
                            /// Decrement the loaded ordnance count, and remove the type entirely if this was the last one.
                            /// </summary>
                            FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] = FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] - 1;
                            if (FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] == 0)
                            {
                                FiredFrom.ShipOrdnance.Remove(LaunchTube.loadedOrdnance);
                            }

                            /// <summary>
                            /// Set the launch tube cooldown time as a missile was just fired from it.
                            /// </summary>
                            LaunchTube.loadTime = LaunchTube.missileLauncherDef.rateOfFire;

                            /// <summary>
                            /// return that a missile was launched.
                            /// </summary>
                            retv = true;
                        }
                        else
                        {
                            String       Msg        = String.Format("No ordnance {0} on ship {1} is available for Launch Tube {2}", LaunchTube.Name, FiredFrom.Name, LaunchTube.Name);
                            MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.FiringNoAvailableOrdnance, TG.Contact.Position.System, TG.Contact,
                                                                       GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg);
                            TG.TaskGroupFaction.MessageLog.Add(newMessage);
                        }
                    }
                    else if (LaunchTube.isDestroyed == true)
                    {
                        String       Msg        = String.Format("Destroyed launch tube {0} is still attached to {1}'s MFC", LaunchTube.Name, FiredFrom.Name);
                        MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.Error, TG.Contact.Position.System, TG.Contact,
                                                                   GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg);
                        TG.TaskGroupFaction.MessageLog.Add(newMessage);
                    }
                    else if (LaunchTube.loadedOrdnance == null)
                    {
                        String       Msg        = String.Format("No loaded ordnance for launch tube {0} on ship {1}", LaunchTube.Name, FiredFrom.Name);
                        MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.FiringNoLoadedOrdnance, TG.Contact.Position.System, TG.Contact,
                                                                   GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg);
                        TG.TaskGroupFaction.MessageLog.Add(newMessage);
                    }
                }

                return(retv);
            }
            else
            {
                return(false);
            }
        }
コード例 #6
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);
 }
コード例 #7
0
        /// <summary>
        /// Final defensive fire scans through all potential FCs that could fire defensively on the incoming missile to see if it is intercepeted.
        /// All PD enabled FCs will attempt to shoot down this missile except ones from the same faction, as this missile is practically right on top of said FC.
        /// In other words allied/neutral status isn't taken into account.
        /// </summary>
        /// <param name="P">Faction list</param>
        /// <param name="Missile">Missile to try to intercept</param>
        /// <param name="RNG">Random Number Generator</param>
        /// <returns>Whether the missile has been intercepted</returns>
        public static bool FinalDefensiveFire(BindingList <Faction> P, OrdnanceTN Missile, Random RNG)
        {
            bool       Intercept     = false;
            StarSystem CurrentSystem = Missile.missileGroup.contact.Position.System;
            float      PointBlank    = 10000.0f / (float)Constants.Units.KM_PER_AU;

            /// <summary>
            /// loop through every faction.
            /// </summary>
            foreach (Faction faction in P)
            {
                /// <summary>
                /// Is the current faction different from the missile group faction, and does the faction have a detected contacts list for the current system?
                /// </summary>
                if (faction != Missile.missileGroup.ordnanceGroupFaction && faction.DetectedContactLists.ContainsKey(CurrentSystem) == true)
                {
                    /// <summary>
                    /// Is the Missile group in this detected contact list?
                    /// </summary>
                    if (faction.DetectedContactLists[CurrentSystem].DetectedMissileContacts.ContainsKey(Missile.missileGroup) == true)
                    {
                        /// <summary>
                        /// Is the detection an active detection?
                        /// </summary>
                        if (faction.DetectedContactLists[CurrentSystem].DetectedMissileContacts[Missile.missileGroup].active == true)
                        {
                            /// <summary>
                            /// Does this faction have any point defense enabled FCs in this system?
                            /// </summary>
                            if (faction.PointDefense.ContainsKey(CurrentSystem) == true)
                            {
                                /// <summary>
                                /// loop through all the possible PD enabled FC.
                                /// </summary>
                                foreach (KeyValuePair <ComponentTN, ShipTN> pair in faction.PointDefense[CurrentSystem].PointDefenseFC)
                                {
                                    ShipTN Ship = pair.Value;

                                    /// <summary>
                                    /// Ship jump sickness will prevent point defense from operating.
                                    /// </summary>
                                    if (Ship.IsJumpSick())
                                    {
                                        continue;
                                    }

                                    /// <summary>
                                    /// Only want BFCs in FDF mode for now.
                                    /// </summary>
                                    if (faction.PointDefense[CurrentSystem].PointDefenseType[pair.Key] == false && pair.Value.ShipBFC[pair.Key.componentIndex].pDState == PointDefenseState.FinalDefensiveFire)
                                    {
                                        BeamFireControlTN ShipBeamFC = pair.Value.ShipBFC[pair.Key.componentIndex];

                                        /// <summary>
                                        /// Do a distance check on pair.Value vs the missile itself. if that checks out to be less than 10k km(or equal to zero), then
                                        /// check to see if the FC can shoot down said missile. This should never be run before a sensor sweep
                                        /// </summary>
                                        float dist = -1;

                                        /// <summary>
                                        /// dist is in AU.
                                        /// </summary>
                                        Missile.missileGroup.contact.DistTable.GetDistance(Ship.ShipsTaskGroup.Contact, out dist);

                                        /// <summary>
                                        /// if distance is less than the 10k km threshold attempt to intercept at Point blank range.
                                        /// </summary>
                                        if (dist < PointBlank)
                                        {
                                            /// <summary>
                                            /// Finally intercept the target.
                                            /// </summary>
                                            bool WF = false;
                                            Intercept = ShipBeamFC.InterceptTarget(RNG, 0, Missile, Ship.ShipsFaction,
                                                                                   Ship.ShipsTaskGroup.Contact, Ship, out WF);
                                            /// <summary>
                                            /// Add this ship to the weapon recharge list since it has fired. This is done here in Sim, or for FDF_Self in Ship.cs
                                            /// </summary>
                                            if (WF == true)
                                            {
                                                if (faction.RechargeList.ContainsKey(Ship) == true)
                                                {
                                                    /// <summary>
                                                    /// If our recharge value does not have Recharge beams in it(bitflag 2 for now), then add it.
                                                    /// </summary>
                                                    if ((faction.RechargeList[pair.Value] & (int)Faction.RechargeStatus.Weapons) != (int)Faction.RechargeStatus.Weapons)
                                                    {
                                                        faction.RechargeList[pair.Value] = (faction.RechargeList[pair.Value] + (int)Faction.RechargeStatus.Weapons);
                                                    }
                                                }
                                                else
                                                {
                                                    faction.RechargeList.Add(pair.Value, (int)Faction.RechargeStatus.Weapons);
                                                }
                                            }

                                            /// <summary>
                                            /// break out of the first foreach loop.
                                            /// </summary>
                                            if (Intercept == true)
                                            {
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                /// <summary>
                /// now break out of the faction loop as this missile has been shot down.
                /// </summary>
                if (Intercept == true)
                {
                    break;
                }
            }
            return(Intercept);
        }
コード例 #8
0
        /// <summary>
        /// Area defensive fire will sweep through a faction's list of BFCs and MFCs to fire at detected ordnance in range.
        /// </summary>
        /// <param name="Fact">Faction to search for fire controls of</param>
        /// <param name="RNG">"global" rng from further up.</param>
        public static void AreaDefensiveFire(Faction Fact, Random RNG)
        {
            /// <summary>
            /// No point defense set FCs, just return.
            /// </summary>
            if (Fact.PointDefense.Count == 0)
            {
                return;
            }

            /// <summary>
            /// Look through each starsystem with a point defense list.
            /// </summary>
            foreach (KeyValuePair <StarSystem, PointDefenseList> pair in Fact.PointDefense)
            {
                StarSystem CurrentSystem = pair.Key;

                /// <summary>
                /// No detected contacts in this system.
                /// </summary>
                if (Fact.DetectedContactLists.ContainsKey(CurrentSystem) == false)
                {
                    break;
                }

                /// <summary>
                /// No missile contacts in this system.
                /// </summary>
                if (Fact.DetectedContactLists[CurrentSystem].DetectedMissileContacts.Count == 0)
                {
                    break;
                }

                /// <summary>
                /// now loop through each FC in the current starsystem.
                /// </summary>
                foreach (KeyValuePair <ComponentTN, ShipTN> pair2 in pair.Value.PointDefenseFC)
                {
                    /// <summary>
                    /// The firing ship.
                    /// </summary>
                    ShipTN Ship = pair2.Value;

                    /// <summary>
                    /// Ship jump sickness will prevent point defense from operating.
                    /// </summary>
                    if (Ship.IsJumpSick())
                    {
                        continue;
                    }

                    /// <summary>
                    /// BFC set to Area defense mode
                    /// </summary>
                    if (pair.Value.PointDefenseType[pair2.Key] == false && pair2.Value.ShipBFC[pair2.Key.componentIndex].pDState == PointDefenseState.AreaDefense)
                    {
                        BeamFireControlTN ShipBeamFC = pair2.Value.ShipBFC[pair2.Key.componentIndex];
                        /// <summary>
                        /// loop through every missile contact. will have to do distance checks here.
                        /// </summary>
                        foreach (KeyValuePair <OrdnanceGroupTN, FactionContact> MisPair in Fact.DetectedContactLists[CurrentSystem].DetectedMissileContacts)
                        {
                            OrdnanceGroupTN DetectedMissileGroup = MisPair.Key;
                            /// <summary>
                            /// This missile group is already destroyed and will be cleaned up by sim later.
                            /// </summary>
                            if (DetectedMissileGroup.missilesDestroyed == DetectedMissileGroup.missiles.Count)
                            {
                                break;
                            }

                            /// <summary>
                            /// Do a distance check on pair.Value vs the missile itself. if that checks out to be less than 10k km(or equal to zero), then
                            /// check to see if the FC can shoot down said missile. This should never be run before a sensor sweep
                            /// </summary>
                            float dist;

                            DetectedMissileGroup.contact.DistTable.GetDistance(Ship.ShipsTaskGroup.Contact, out dist);

                            /// <summary>
                            /// Only bother with checks here that are within the maximum beam distance.
                            /// </summary>
                            if (dist <= Constants.Units.BEAM_AU_MAX)
                            {
                                /// <summary>
                                /// Value is in units of 10k km
                                /// </summary>
                                float rangeAreaDefenseKm;

                                /// <summary>
                                /// The user put in an absurdly large value. for convienence, just do this to get maximum range.
                                /// </summary>

                                if (ShipBeamFC.pDRange > (float)Constants.Units.TEN_KM_MAX)
                                {
                                    /// <summary>
                                    /// Max possible beam range in KM.
                                    /// </summary>
                                    rangeAreaDefenseKm = (float)Constants.Units.BEAM_KM_MAX;
                                }
                                else
                                {
#warning magic number related to 10k
                                    rangeAreaDefenseKm = ShipBeamFC.pDRange * 10000.0f;
                                }

                                float distKM = dist * (float)Constants.Units.KM_PER_AU;

                                /// <summary>
                                /// Additional paranoia check of range, I need to fix Area defense PD range values to ship bfc range in any event, that hasn't been done yet.
                                /// </summary>
#warning magic number for total bfc range.
                                float totalRange = ShipBeamFC.beamFireControlDef.range * 2.0f;

                                float range = Math.Min(totalRange, rangeAreaDefenseKm);

                                /// <summary>
                                /// the BFC is set for range defense and is in range of this missile.
                                /// </summary>
                                if (distKM <= range)
                                {
#warning magic number related to 10k km increments.
                                    /// <summary>
                                    /// Increment is a 10k km unit, so distance must be divided by 10000 to yield the appropriate number.
                                    /// </summary>
                                    int increment = (int)Math.Floor((float)distKM / 10000.0f);

                                    bool Intercept         = false;
                                    int  MissilesToDestroy = 0;

                                    /// <summary>
                                    /// Can't foreach this one, as I do not want every missile, only the ones not destroyed.
                                    /// </summary>
                                    for (int MissileIterator = DetectedMissileGroup.missilesDestroyed; MissileIterator < DetectedMissileGroup.missiles.Count; MissileIterator++)
                                    {
                                        bool WF = false;
                                        Intercept = ShipBeamFC.InterceptTarget(RNG, increment, DetectedMissileGroup.missiles[MissileIterator], Ship.ShipsFaction,
                                                                               Ship.ShipsTaskGroup.Contact, Ship, out WF);

                                        /// <summary>
                                        /// Add this ship to the weapon recharge list since it has fired. This is done here in Sim, or for FDF_Self in Ship.cs
                                        /// </summary>
                                        if (WF == true)
                                        {
                                            if (Fact.RechargeList.ContainsKey(Ship) == true)
                                            {
                                                /// <summary>
                                                /// If our recharge value does not have Recharge beams in it(bitflag 2 for now), then add it.
                                                /// </summary>
                                                if ((Fact.RechargeList[Ship] & (int)Faction.RechargeStatus.Weapons) != (int)Faction.RechargeStatus.Weapons)
                                                {
                                                    Fact.RechargeList[Ship] = (Fact.RechargeList[Ship] + (int)Faction.RechargeStatus.Weapons);
                                                }
                                            }
                                            else
                                            {
                                                Fact.RechargeList.Add(Ship, (int)Faction.RechargeStatus.Weapons);
                                            }
                                        }

                                        if (Intercept == true)
                                        {
                                            /// <summary>
                                            /// Destroy the missile, check if the ordnance group should be removed, if its gone also remove it from the detected contacts list and break that loop.
                                            /// </summary>

                                            MissilesToDestroy++;
                                        }
                                        else if (Intercept == false)
                                        {
                                            /// <summary>
                                            /// This FC can't intercept any more missiles, advance to the next one.
                                            /// </summary>
                                            break;
                                        }
                                    }

                                    /// <summary>
                                    /// Set the missiles destroyed count as appropriate.
                                    /// </summary>
                                    DetectedMissileGroup.missilesDestroyed = DetectedMissileGroup.missilesDestroyed + MissilesToDestroy;

                                    if (DetectedMissileGroup.missilesDestroyed != 0 && Fact.MissileRemoveList.Contains(DetectedMissileGroup) == false)
                                    {
                                        /// <summary>
                                        /// Tell sim to remove missiles from this group, or remove it entirely.
                                        /// </summary>
                                        Fact.MissileRemoveList.Add(DetectedMissileGroup);
                                    }

                                    if (Intercept == false)
                                    {
                                        /// <summary>
                                        /// This condition means advance to the next FC.
                                        /// </summary>
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    /// <summary>
                    /// MFC set to any pd mode that can be applied: 1v2 up to 5v1.
                    /// </summary>
                    else if (pair.Value.PointDefenseType[pair2.Key] == true && pair2.Value.ShipMFC[pair2.Key.componentIndex].pDState >= PointDefenseState.AMM1v2 &&
                             pair2.Value.ShipMFC[pair2.Key.componentIndex].pDState <= PointDefenseState.AMM5v1)
                    {
                        MissileFireControlTN ShipMissileFC = pair2.Value.ShipMFC[pair2.Key.componentIndex];

                        int MissilesLaunched = 0;
                        int MissilesToLaunch = 0;
                        foreach (KeyValuePair <OrdnanceGroupTN, FactionContact> MisPair in Fact.DetectedContactLists[CurrentSystem].DetectedMissileContacts)
                        {
                            OrdnanceGroupTN DetectedMissileGroup = MisPair.Key;

                            /// <summary>
                            /// Advance to next missile group.
                            /// </summary>
                            if (DetectedMissileGroup.missilesDestroyed == DetectedMissileGroup.missiles.Count)
                            {
                                break;
                            }

                            /// <summary>
                            /// Do a distance check on pair.Value vs the missile itself. if that checks out to be less than 10k km(or equal to zero), then
                            /// check to see if the FC can shoot down said missile. This should never be run before a sensor sweep
                            /// </summary>
                            float dist;

                            DetectedMissileGroup.contact.DistTable.GetDistance(Ship.ShipsTaskGroup.Contact, out dist);


                            float MFCEngageDistKm    = ShipMissileFC.mFCSensorDef.maxRange;
                            float rangeAreaDefenseKm = ShipMissileFC.pDRange;

                            /// <summary>
                            /// Range is in 10K units so it has to be adjusted to AU for later down.
                            /// </summary>
#warning magic 10k number here
                            float range = (Math.Min(MFCEngageDistKm, rangeAreaDefenseKm) / (float)Constants.Units.KM_PER_AU);
                            range = range * 10000.0f;

                            int MSize    = 0;
                            int AltMSize = 0;

#warning the +6 is another magic number.
                            if ((int)Math.Ceiling(DetectedMissileGroup.missiles[0].missileDef.size) <= (Constants.OrdnanceTN.MissileResolutionMinimum + 6))
                            {
                                MSize    = Constants.OrdnanceTN.MissileResolutionMinimum;
                                AltMSize = 0;
                            }
                            else if ((int)Math.Ceiling(DetectedMissileGroup.missiles[0].missileDef.size) <= (Constants.OrdnanceTN.MissileResolutionMaximum + 6))
                            {
                                MSize    = (int)Math.Ceiling(DetectedMissileGroup.missiles[0].missileDef.size);
                                AltMSize = 0;
                            }
                            else if ((int)Math.Ceiling(DetectedMissileGroup.missiles[0].missileDef.size) > (Constants.OrdnanceTN.MissileResolutionMaximum + 6))
                            {
                                MSize    = -1;
                                AltMSize = (int)Math.Ceiling(Math.Ceiling(DetectedMissileGroup.missiles[0].missileDef.size) / (Constants.OrdnanceTN.MissileResolutionMaximum + 6));
                            }

                            int MFCRange = ShipMissileFC.mFCSensorDef.GetActiveDetectionRange(AltMSize, MSize);

                            bool CanDetect = Fact.LargeDetection(dist, MFCRange);

                            /// <summary>
                            /// Can this MFC fire on the targetted missile?
                            /// </summary>
                            if (CanDetect == true && dist <= range)
                            {
                                /// <summary>
                                /// Do AMM defense here. Check to see how many amms are targeted on this missile, if less than defense setting fire more.
                                /// How do I handle 1v2 mode? rounding obviously. if more than 1 missile in group send half, send atleast 1 for 1, and round for odd missile amounts.
                                /// missiles won't be destroyed here, as they were in beam fire mode, this will just launch amms at missile groups.
                                /// </summary>

                                /// <summary>
                                /// Get total missiles currently targetted on this group. Keeping track of a total missiles incoming variable would mean handling a lot of interactions where
                                /// missiles can be destroyed, run out of fuel, etc. so I'll just loop through this for now.
                                /// </summary>
#warning this missile count can be optimized, but it would be difficult to do so.
                                int TotalCount = 0;
                                foreach (OrdnanceGroupTN OrdGroupTargetting in DetectedMissileGroup.ordGroupsTargetting)
                                {
                                    TotalCount = TotalCount + OrdGroupTargetting.missiles.Count;
                                }

                                float Value = TotalCount / DetectedMissileGroup.missiles.Count;

                                switch (ShipMissileFC.pDState)
                                {
#warning more magic numbers in how point defense states are handled.
                                case PointDefenseState.AMM1v2:
                                    if (Value < 0.5f)
                                    {
                                        int Max = (int)Math.Ceiling((float)DetectedMissileGroup.missiles.Count / 2.0f);
                                        MissilesToLaunch = Max - TotalCount;
                                    }
                                    break;

                                case PointDefenseState.AMM1v1:
                                    if (Value < 1.0f)
                                    {
                                        int Max = DetectedMissileGroup.missiles.Count;
                                        MissilesToLaunch = Max - TotalCount;
                                    }
                                    break;

                                case PointDefenseState.AMM2v1:
                                    if (Value < 2.0f)
                                    {
                                        int Max = DetectedMissileGroup.missiles.Count * 2;
                                        MissilesToLaunch = Max - TotalCount;
                                    }
                                    break;

                                case PointDefenseState.AMM3v1:
                                    if (Value < 3.0f)
                                    {
                                        int Max = DetectedMissileGroup.missiles.Count * 3;
                                        MissilesToLaunch = Max - TotalCount;
                                    }
                                    break;

                                case PointDefenseState.AMM4v1:
                                    if (Value < 4.0f)
                                    {
                                        int Max = DetectedMissileGroup.missiles.Count * 4;
                                        MissilesToLaunch = Max - TotalCount;
                                    }
                                    break;

                                case PointDefenseState.AMM5v1:
                                    if (Value < 5.0f)
                                    {
                                        int Max = DetectedMissileGroup.missiles.Count * 5;
                                        MissilesToLaunch = Max - TotalCount;
                                    }
                                    break;
                                }

                                if (MissilesToLaunch != 0)
                                {
                                    /// <summary>
                                    /// launch up to MissilesToLaunch amms in a new ord group at the target.
                                    /// <summary>
                                    MissilesLaunched = ShipMissileFC.FireWeaponsPD(Ship.ShipsTaskGroup, Ship, DetectedMissileGroup, MissilesToLaunch);


                                    /// <summary>
                                    /// Add this ship to the weapon recharge list since it has fired. This is done here in Sim, or for FDF_Self in Ship.cs
                                    /// </summary>
                                    if (MissilesLaunched != 0)
                                    {
                                        if (Fact.RechargeList.ContainsKey(Ship) == true)
                                        {
                                            /// <summary>
                                            /// If our recharge value does not have Recharge beams in it(bitflag 2 for now), then add it.
                                            /// </summary>
                                            if ((Fact.RechargeList[Ship] & (int)Faction.RechargeStatus.Weapons) != (int)Faction.RechargeStatus.Weapons)
                                            {
                                                Fact.RechargeList[Ship] = (Fact.RechargeList[Ship] + (int)Faction.RechargeStatus.Weapons);
                                            }
                                        }
                                        else
                                        {
                                            Fact.RechargeList.Add(Ship, (int)Faction.RechargeStatus.Weapons);
                                        }
                                    }

                                    /// <summary>
                                    /// This FC can no longer fire at ordnance groups in range.
                                    /// </summary>
                                    if (MissilesLaunched != MissilesToLaunch)
                                    {
                                        break;
                                    }
                                }
                            }

                            /// <summary>
                            /// advance to the next FC.
                            /// </summary>
                            if (MissilesLaunched != MissilesToLaunch && MissilesToLaunch != 0)
                            {
                                break;
                            }
                        }
                    }
                }
            }
        }
コード例 #9
0
ファイル: ActiveSensor.cs プロジェクト: EterniaLogic/Pulsar4x
        /// <summary>
        /// Fire this MFC in point defense mode.
        /// </summary>
        /// <param name="TG">Taskgroup the MFC is in</param>
        /// <param name="FiredFrom">Ship the MFC is on</param>
        /// <param name="Target">Target of point defense fire.</param>
        /// <param name="MissilesToFire">Number of missiles to fire at it</param>
        /// <returns></returns>
        public int FireWeaponsPD(TaskGroupTN TG, ShipTN FiredFrom, OrdnanceGroupTN Target, int MissilesToFire)
        {
            /// <summary>
            /// simple stupid sanity check.
            /// </summary>
            if (MissilesToFire == 0)
            {
                return 0;
            }

            int LaunchCount = 0;
            /// <summary>
            /// Just a temporary variable for this function.
            /// </summary>
            BindingList<OrdnanceGroupTN> LocalMissileGroups = new BindingList<OrdnanceGroupTN>();

            foreach (MissileLauncherTN LaunchTube in m_lLinkedWeapons) //int loop = 0; loop < LinkedWeapons.Count; loop++)
            {
                if (LaunchTube.isDestroyed == false && LaunchTube.loadTime == 0 && LaunchTube.loadedOrdnance != null)
                {
                    if (FiredFrom.ShipOrdnance.ContainsKey(LaunchTube.loadedOrdnance) == true)
                    {
                        OrdnanceTN newMissile = new OrdnanceTN(this, LaunchTube.loadedOrdnance, FiredFrom);

                        /// <summary>
                        /// Point defense does not go by MFC targetting. have to add target here.
                        /// </summary>
                        newMissile.target = new TargetTN(Target);

                        LaunchCount++;

                        /// <summary>
                        /// Create a new missile group
                        /// </summary>
                        if (LocalMissileGroups.Count == 0)
                        {
                            OrdnanceGroupTN newMissileGroup = new OrdnanceGroupTN(TG, newMissile);
                            LocalMissileGroups.Add(newMissileGroup);
                            TG.TaskGroupFaction.MissileGroups.Add(newMissileGroup);

                            /// <summary>
                            /// Add this ordnance group to the ord groups targetting list for the intended target missile group.
                            /// This is only necessary here as Manually fired MFC missiles are connected to their MFC.
                            /// </summary>
                            Target.ordGroupsTargetting.Add(newMissileGroup);
                        }
                        /// <summary>
                        /// An existing missile group may be useable.
                        /// </summary>
                        else
                        {
                            bool foundGroup = false;
                            foreach (OrdnanceGroupTN OrdGroup in LocalMissileGroups)
                            {
                                /// <summary>
                                /// All Missile groups should be composed of just 1 type of missile for convienence.
                                if (OrdGroup.missiles[0].missileDef.Id == LaunchTube.loadedOrdnance.Id)
                                {
                                    OrdGroup.AddMissile(newMissile);
                                    foundGroup = true;
                                    break;
                                }
                            }

                            /// <summary>
                            /// Have to create a new missile group after all.
                            /// </summary>
                            if (foundGroup == false)
                            {
                                OrdnanceGroupTN newMissileGroup = new OrdnanceGroupTN(TG, newMissile);
                                LocalMissileGroups.Add(newMissileGroup);
                                TG.TaskGroupFaction.MissileGroups.Add(newMissileGroup);

                                /// <summary>
                                /// Add this ordnance group to the ord groups targetting list for the intended target missile group.
                                /// This is only necessary here as Manually fired MFC missiles are connected to their MFC.
                                /// </summary>
                                Target.ordGroupsTargetting.Add(newMissileGroup);
                            }
                        }
                        /// <summary>
                        /// Decrement the loaded ordnance count, and remove the type entirely if this was the last one.
                        /// </summary>
                        FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] = FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] - 1;
                        if (FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] == 0)
                        {
                            FiredFrom.ShipOrdnance.Remove(LaunchTube.loadedOrdnance);
                        }

                        /// <summary>
                        /// Set the launch tube cooldown time as a missile was just fired from it.
                        /// </summary>
                        LaunchTube.loadTime = LaunchTube.missileLauncherDef.rateOfFire;

                        if (LaunchCount == MissilesToFire)
                            break;
                    }
                    else
                    {
                        String Msg = String.Format("No ordnance {0} on ship {1} is available for Launch Tube {2} in PD Mode", LaunchTube.Name, FiredFrom.Name, LaunchTube.Name);
                        MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.FiringNoAvailableOrdnance, TG.Contact.Position.System, TG.Contact,
                                                                   GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg);
                        TG.TaskGroupFaction.MessageLog.Add(newMessage);
                    }

                }
                else if (LaunchTube.isDestroyed == true)
                {
                    String Msg = String.Format("Destroyed launch tube {0} is still attached to {1}'s MFC in PD Mode", LaunchTube.Name, FiredFrom.Name);
                    MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.Error, TG.Contact.Position.System, TG.Contact,
                                                               GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg);
                    TG.TaskGroupFaction.MessageLog.Add(newMessage);
                }
                else if (LaunchTube.loadedOrdnance == null)
                {
                    String Msg = String.Format("No loaded ordnance for launch tube {0} on ship {1} in PD Mode", LaunchTube.Name, FiredFrom.Name);
                    MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.FiringNoLoadedOrdnance, TG.Contact.Position.System, TG.Contact,
                                                               GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg);
                    TG.TaskGroupFaction.MessageLog.Add(newMessage);
                }
            }
            return LaunchCount;
        }
コード例 #10
0
ファイル: ActiveSensor.cs プロジェクト: EterniaLogic/Pulsar4x
        /// <summary>
        /// Fire Weapons spawns new missiles groups or adds missiles to existing ones.
        /// </summary>
        /// <param name="TG">Taskgroup this MFC is in.</param>
        /// <param name="FiredFrom">Ship these missiles were fired from.</param>
        /// <returns>If missiles were fired at all from this MFC. true = atleast 1 missile(and therefore missile group, false = no missiles.</returns>
        public bool FireWeapons(TaskGroupTN TG, ShipTN FiredFrom)
        {
            bool retv = false;
            if (m_oTarget != null)
            {
                /// <summary>
                /// Just a temporary variable for this function.
                /// </summary>
                BindingList<OrdnanceGroupTN> LocalMissileGroups = new BindingList<OrdnanceGroupTN>();

                foreach (MissileLauncherTN LaunchTube in m_lLinkedWeapons)
                {
                    if (LaunchTube.isDestroyed == false && LaunchTube.loadTime == 0 && LaunchTube.loadedOrdnance != null)
                    {
                        if (FiredFrom.ShipOrdnance.ContainsKey(LaunchTube.loadedOrdnance) == true)
                        {
                            OrdnanceTN newMissile = new OrdnanceTN(this, LaunchTube.loadedOrdnance, FiredFrom);

                            /// <summary>
                            /// Create a new missile group
                            /// </summary>
                            if (LocalMissileGroups.Count == 0)
                            {
                                OrdnanceGroupTN newMissileGroup = new OrdnanceGroupTN(TG, newMissile);
                                LocalMissileGroups.Add(newMissileGroup);
                                TG.TaskGroupFaction.MissileGroups.Add(newMissileGroup);
                            }
                            /// <summary>
                            /// An existing missile group may be useable.
                            /// </summary>
                            else
                            {
                                bool foundGroup = false;
                                foreach (OrdnanceGroupTN OrdGroup in LocalMissileGroups)
                                {
                                    /// <summary>
                                    /// All Missile groups should be composed of just 1 type of missile for convienence.
                                    if (OrdGroup.missiles[0].missileDef.Id == LaunchTube.loadedOrdnance.Id)
                                    {
                                        OrdGroup.AddMissile(newMissile);
                                        foundGroup = true;
                                        break;
                                    }
                                }

                                /// <summary>
                                /// Have to create a new missile group after all.
                                /// </summary>
                                if (foundGroup == false)
                                {
                                    OrdnanceGroupTN newMissileGroup = new OrdnanceGroupTN(TG, newMissile);
                                    LocalMissileGroups.Add(newMissileGroup);
                                    TG.TaskGroupFaction.MissileGroups.Add(newMissileGroup);
                                }
                            }
                            /// <summary>
                            /// Decrement the loaded ordnance count, and remove the type entirely if this was the last one.
                            /// </summary>
                            FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] = FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] - 1;
                            if (FiredFrom.ShipOrdnance[LaunchTube.loadedOrdnance] == 0)
                            {
                                FiredFrom.ShipOrdnance.Remove(LaunchTube.loadedOrdnance);
                            }

                            /// <summary>
                            /// Set the launch tube cooldown time as a missile was just fired from it.
                            /// </summary>
                            LaunchTube.loadTime = LaunchTube.missileLauncherDef.rateOfFire;

                            /// <summary>
                            /// return that a missile was launched.
                            /// </summary>
                            retv = true;
                        }
                        else
                        {
                            String Msg = String.Format("No ordnance {0} on ship {1} is available for Launch Tube {2}", LaunchTube.Name, FiredFrom.Name, LaunchTube.Name);
                            MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.FiringNoAvailableOrdnance, TG.Contact.Position.System, TG.Contact,
                                                                       GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg);
                            TG.TaskGroupFaction.MessageLog.Add(newMessage);
                        }

                    }
                    else if (LaunchTube.isDestroyed == true)
                    {
                        String Msg = String.Format("Destroyed launch tube {0} is still attached to {1}'s MFC", LaunchTube.Name, FiredFrom.Name);
                        MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.Error, TG.Contact.Position.System, TG.Contact,
                                                                   GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg);
                        TG.TaskGroupFaction.MessageLog.Add(newMessage);
                    }
                    else if (LaunchTube.loadedOrdnance == null)
                    {
                        String Msg = String.Format("No loaded ordnance for launch tube {0} on ship {1}", LaunchTube.Name, FiredFrom.Name);
                        MessageEntry newMessage = new MessageEntry(MessageEntry.MessageType.FiringNoLoadedOrdnance, TG.Contact.Position.System, TG.Contact,
                                                                   GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Msg);
                        TG.TaskGroupFaction.MessageLog.Add(newMessage);
                    }
                }

                return retv;
            }
            else
            {
                return false;
            }
        }
コード例 #11
0
ファイル: ActiveSensor.cs プロジェクト: EterniaLogic/Pulsar4x
 /// <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);
 }
コード例 #12
0
ファイル: Wreck.cs プロジェクト: txe/Pulsar4x
 /// <summary>
 /// This "constructs" the wreck itself. Later component definitions, mineral counts, and wealth will be calculated here.
 /// </summary>
 /// <param name="Ship">Ship from which this wreck originated</param>
 public WreckTN(ShipTN Ship)
 {
 }
コード例 #13
0
 /// <summary>
 /// Constructor for ship targets.
 /// </summary>
 /// <param name="ShipTarget">Ship that will be the target</param>
 public TargetTN(ShipTN ShipTarget)
 {
     Id         = Guid.NewGuid();
     TargetType = ShipTarget.ShipsTaskGroup.SSEntity;
     Ship       = ShipTarget;
 }
コード例 #14
0
ファイル: TargetTN.cs プロジェクト: EterniaLogic/Pulsar4x
 /// <summary>
 /// Constructor for ship targets.
 /// </summary>
 /// <param name="ShipTarget">Ship that will be the target</param>
 public TargetTN(ShipTN ShipTarget)
     : base()
 {
     TargetType = ShipTarget.ShipsTaskGroup.SSEntity;
     Ship = ShipTarget;
 }
コード例 #15
0
ファイル: TargetTN.cs プロジェクト: txe/Pulsar4x
 /// <summary>
 /// Constructor for ship targets.
 /// </summary>
 /// <param name="ShipTarget">Ship that will be the target</param>
 public TargetTN(ShipTN ShipTarget)
     : base()
 {
     TargetType = ShipTarget.ShipsTaskGroup.SSEntity;
     Ship       = ShipTarget;
 }