Example #1
0
        public void testArmor()
        {
            Faction newFaction = new Faction(0);
            ShipClassTN ts2 = new ShipClassTN("Test", newFaction);

            StarSystem System1 = SystemGen.CreateSol();

            SystemBody pl1 = new SystemBody(System1.Stars[0], SystemBody.PlanetType.Terrestrial);
            System1.Stars[0].Planets.Add(pl1);

            TaskGroupTN newTG = new TaskGroupTN("TG", newFaction, System1.Stars[0].Planets[0], System1);
            ShipTN ts = new ShipTN(ts2, 0, 0, newTG, newFaction, "Test Ship");

            ts2.ShipArmorDef = new ArmorDefTN("Duranium Armour");
            ts.ShipArmor = new ArmorTN(ts2.ShipArmorDef);

            ts2.ShipArmorDef.CalcArmor("Duranium Armor", 5, 38.0, 5);

            Console.WriteLine("ArmorPerHS: {0}", ts2.ShipArmorDef.armorPerHS);
            Console.WriteLine("Size: {0}", ts2.ShipArmorDef.size);
            Console.WriteLine("Cost: {0}", ts2.ShipArmorDef.cost);
            Console.WriteLine("Area: {0}", ts2.ShipArmorDef.area);
            Console.WriteLine("Depth: {0}", ts2.ShipArmorDef.depth);
            Console.WriteLine("Column Number: {0}", ts2.ShipArmorDef.cNum);

            Console.WriteLine("isDamaged: {0}", ts.ShipArmor.isDamaged);


            ts.ShipArmor.SetDamage(ts2.ShipArmorDef.cNum, ts2.ShipArmorDef.depth, 4, 1);
            for (int loop = 0; loop < ts2.ShipArmorDef.cNum; loop++)
            {
                Console.WriteLine("Column Value: {0}", ts.ShipArmor.armorColumns[loop]);
            }
            Console.WriteLine("Damage Key: {0}, Column Value: {1}", ts.ShipArmor.armorDamage.Min().Key, ts.ShipArmor.armorDamage.Min().Value);

            Console.WriteLine("isDamaged: {0}", ts.ShipArmor.isDamaged);

            ts.ShipArmor.RepairSingleBlock(ts2.ShipArmorDef.depth);

            Console.WriteLine("isDamaged: {0}", ts.ShipArmor.isDamaged);

            ts.ShipArmor.SetDamage(ts2.ShipArmorDef.cNum, ts2.ShipArmorDef.depth, 4, 1);
            for (int loop = 0; loop < ts2.ShipArmorDef.cNum; loop++)
            {
                Console.WriteLine("Column Value: {0}", ts.ShipArmor.armorColumns[loop]);
            }
            Console.WriteLine("Damage Key: {0}, Column Value: {1}", ts.ShipArmor.armorDamage.Min().Key, ts.ShipArmor.armorDamage.Min().Value);

            Console.WriteLine("isDamaged: {0}", ts.ShipArmor.isDamaged);

            ts.ShipArmor.RepairAllArmor();

            Console.WriteLine("isDamaged: {0}", ts.ShipArmor.isDamaged);

            Console.WriteLine("Cost: {0}, Area: {1},Size: {2}", ts.ShipArmor.armorDef.cost, ts.ShipArmor.armorDef.area, ts.ShipArmor.armorDef.size);
        }
Example #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)
        {
            ship = DetectedShip;
            missileGroup = null;
            pop = null;
            thermal = Thermal;
            EM = em;
            EMSignature = EMSig;
            active = Active;

            String Contact = "New contact detected:";

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

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

            if (active == true)
            {
                activeTick = tick;
                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);

        }
        /// <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 #4
0
 /// <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)
 {
 }
        /// <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;
        }
 /// <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 #7
0
        /// <summary>
        /// Adds a ship to a taskgroup, will call sorting and sensor handling.
        /// </summary>
        /// <param name="shipDef">definition of the ship to be added.</param>
        public void AddShip(ShipClassTN shipDef, String Title)
        {
            ShipTN ship = new ShipTN(shipDef, Ships.Count, GameState.Instance.CurrentSecond, this, TaskGroupFaction, Title);
            Ships.Add(ship);

            /// <summary>
            /// Refuel and ReCrew this ship here?
            /// </summary>

            if (Ships.Count == 1)
            {
                MaxSpeed = ship.ShipClass.MaxSpeed;
                CurrentSpeed = MaxSpeed;
            }
            else
            {
                if (ship.ShipClass.MaxSpeed < MaxSpeed)
                {
                    MaxSpeed = ship.ShipClass.MaxSpeed;
                    CurrentSpeed = MaxSpeed;
                }
            }

            for (int loop = 0; loop < Ships.Count; loop++)
            {
                Ships[loop].SetSpeed(CurrentSpeed);
            }

            TotalCargoTonnage = TotalCargoTonnage + shipDef.TotalCargoCapacity;
            TotalCryoCapacity = TotalCryoCapacity + shipDef.SpareCryoBerths;

            UpdatePassiveSensors(ship);

            AddShipToSort(ship);

            /// <summary>
            /// Let the UI know it should re check this taskgroup's sensors.
            /// </summary>
            SensorUpdateAck++;
        }
Example #8
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 Order(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();
        }
Example #9
0
        /// <summary>
        /// Ship selection.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ShipListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (m_oShipListPanel.ShipsListBox.SelectedIndex != -1)
            {
                _CurrnetShip = _CurrnetFaction.Ships[m_oShipListPanel.ShipsListBox.SelectedIndex];

                /// <summary>
                /// This is a kludge, plain and simple, I was not able to successfully bind the SFCComboBox, so I am doing this.
                /// </summary>
                m_oDetailsPanel.SFCComboBox.Items.Clear();
                for (int loop = 0; loop < _CurrnetShip.ShipFireControls.Count; loop++)
                {
                    m_oDetailsPanel.SFCComboBox.Items.Add(_CurrnetShip.ShipFireControls[loop].Name);
                }

                if (m_oDetailsPanel.SFCComboBox.Items.Count != 0)
                    m_oDetailsPanel.SFCComboBox.SelectedIndex = 0;

                /// <summary>
                /// Same will probably be true for sensors.
                /// </summary>
                m_oDetailsPanel.SelectedActiveComboBox.Items.Clear();
                for (int loop = 0; loop < _CurrnetShip.ShipASensor.Count; loop++)
                {
                    m_oDetailsPanel.SelectedActiveComboBox.Items.Add(_CurrnetShip.ShipASensor[loop].Name);
                }

                if (m_oDetailsPanel.SelectedActiveComboBox.Items.Count != 0)
                    m_oDetailsPanel.SelectedActiveComboBox.SelectedIndex = 0;


                if (_CurrnetShip.ShieldIsActive == true && _CurrnetShip.CurrentShieldPoolMax != 0.0f)
                {
                    m_oDetailsPanel.ShieldGroupBox.Text = "Shields(On)";
                }
                else
                {
                    m_oDetailsPanel.ShieldGroupBox.Text = "Shields(Off)";
                }
            }

            RefreshShipInfo();
        }
Example #10
0
        public void testPSensor()
        {

            Faction newFaction = new Faction(0);

            StarSystem System1 = SystemGen.CreateSol();

            SystemBody pl1 = new SystemBody(System1.Stars[0], SystemBody.PlanetType.Terrestrial);
            System1.Stars[0].Planets.Add(pl1);

            TaskGroupTN newTG = new TaskGroupTN("TG", newFaction, System1.Stars[0].Planets[0], System1);

            ShipClassTN ts2 = new ShipClassTN("Test", newFaction);
            ShipTN ts = new ShipTN(ts2, 0, 0, newTG, newFaction, "Test Ship");

            PassiveSensorDefTN PSensorDefTest = new PassiveSensorDefTN("Thermal Sensor TH19-342", 19.0f, 18, PassiveSensorType.Thermal, 1.0f, 1);

            ts2.ShipPSensorDef = new BindingList<PassiveSensorDefTN>();
            ts2.ShipPSensorCount = new BindingList<ushort>();
            ts2.ShipPSensorDef.Add(PSensorDefTest);
            ts2.ShipPSensorCount.Add(1);

            PassiveSensorTN PSensorTest = new PassiveSensorTN(ts2.ShipPSensorDef[0]);

            ts.ShipPSensor = new BindingList<PassiveSensorTN>();
            ts.ShipPSensor.Add(PSensorTest);


            PassiveSensorDefTN tst3 = ts.ShipPSensor[0].pSensorDef;

            Console.WriteLine("Name: {0}", tst3.Name);
            Console.WriteLine("Size: {0}, HTK: {1}, Hardening: {2}", tst3.size, tst3.htk, tst3.hardening);
            Console.WriteLine("Rating: {0}, Range: {1}", tst3.rating, tst3.range);
            Console.WriteLine("IsMilitary: {0}", tst3.isMilitary);
            Console.WriteLine("Crew: {0}", tst3.crew);
            Console.WriteLine("Cost: {0}", tst3.cost);

            for (ushort loop = 80; loop < 120; loop++)
            {
                Console.WriteLine("Signature:{0} Detection Range in KM:{1}", loop, tst3.GetPassiveDetectionRange(loop));
            }
        }
Example #11
0
 /// <summary>
 /// UpdatePassiveSensors alters the best Thermal/EM detection rating if the newly added ship has a better detector than previously available.
 /// </summary>
 /// <param name="ship">ship to search for sensors.</param>
 public void UpdatePassiveSensors(ShipTN ship)
 {
     /// <summary>
     /// Loop through every passive sensor on the ship, and if this sensor is better than the best it is the new best.
     /// if it is equal to the best, then increment the number of the best sensor available.
     /// </summary>
     for (int loop = 0; loop < ship.ShipPSensor.Count; loop++)
     {
         if (ship.ShipPSensor[loop].pSensorDef.thermalOrEM == PassiveSensorType.Thermal)
         {
             if ((BestThermalCount == 0) || (ship.ShipPSensor[loop].pSensorDef.rating > BestThermal.pSensorDef.rating))
             {
                 BestThermal = ship.ShipPSensor[loop];
                 BestThermalCount = 1;
             }
             else if (ship.ShipPSensor[loop].pSensorDef.rating == BestThermal.pSensorDef.rating)
             {
                 BestThermalCount++;
             }
         }
         else if (ship.ShipPSensor[loop].pSensorDef.thermalOrEM == PassiveSensorType.EM)
         {
             if ((BestEMCount == 0) || (ship.ShipPSensor[loop].pSensorDef.rating > BestEM.pSensorDef.rating))
             {
                 BestEM = ship.ShipPSensor[loop];
                 BestEMCount = 1;
             }
             else if (ship.ShipPSensor[loop].pSensorDef.rating == BestEM.pSensorDef.rating)
             {
                 BestEMCount++;
             }
         }
     }
 }
Example #12
0
 /// <summary>
 /// Adds the specified ship to each of the sorting lists.
 /// </summary>
 /// <param name="Ship">Ship to be added.</param>
 public void AddShipToSort(ShipTN Ship)
 {
     AddNodeToSort(ThermalSortList, Ship.ThermalList, 0);
     AddNodeToSort(EMSortList, Ship.EMList, 1);
     AddNodeToSort(ActiveSortList, Ship.ActiveList, 2);
 }
Example #13
0
        /// <summary>
        /// Given a ship in this taskgroup, transfer said ship to TaskGroupTo
        /// </summary>
        /// <param name="Ship">Ship present in this taskgroup that should be transfered</param>
        /// <param name="TaskGroupTo">Taskgroup that will receive this ship</param>
        public void TransferShipToTaskGroup(ShipTN Ship, TaskGroupTN TaskGroupTo)
        {
            /// <summary>
            /// This ship is not in the taskgroup so return immediately.
            /// </summary>
            if (Ships.Contains(Ship) == false)
                return;

            BindingList<int> activeSensorIndices = new BindingList<int>();
            for (int activeIterator = 0; activeIterator < Ship.ShipASensor.Count; activeIterator++)
            {
                /// <summary>
                /// This active sensor is both active and intact, so preserve its index, and set isActive to false(the sensor will be reactivated in its new TG.
                /// Destroyed sensors can keep their isActive state, as when they are repaired the repair function should handle reactivating them.
                /// </summary>
                if (Ship.ShipASensor[activeIterator].isActive == true && Ship.ShipASensor[activeIterator].isDestroyed == false)
                {
                    activeSensorIndices.Add(activeIterator);
                    Ship.ShipASensor[activeIterator].isActive = false;
                }
            }

            /// <summary>
            /// Move the ship between the two.
            /// </summary>
            RemoveShipFrom(Ship);
            TaskGroupTo.AddShipTo(Ship);

            /// <summary>
            /// reactivate any sensors that were active in the previous taskgroup.
            /// </summary>
            int ShipIndex = TaskGroupTo.Ships.IndexOf(Ship);
            foreach(int activeIndex in activeSensorIndices)
               TaskGroupTo.SetActiveSensor(ShipIndex, activeIndex, true);
        }
Example #14
0
        /// <summary>
        /// Remove ship will remove a ship from this taskgroup, typically in preparation for adding it to another taskgroup. ship destruction logic is handled elsewhere.
        /// </summary>
        /// <param name="Ship">Ship to be removed</param>
        public void RemoveShipFrom(ShipTN Ship)
        {
            /// <summary>
            /// Update taskgroup wide statistics here. eventually this may need to be its own function.
            /// </summary>
            TotalCargoTonnage = TotalCargoTonnage - Ship.ShipClass.TotalCargoCapacity;
            TotalCryoCapacity = TotalCryoCapacity - Ship.ShipClass.SpareCryoBerths;

            /// <summary>
            /// This can return false. not sure what the implications of such a return would be. other then that this function handles removing this ship from the taskgroup's sensor
            /// data structures.
            /// </summary>
            RemoveShipFromTaskGroup(Ship);

            Ships.Remove(Ship);

            if (Ships.Count == 0)
            {
                MaxSpeed = 1;
                CurrentSpeed = 1;
            }
            else if (Ships.Count == 1)
            {
                if (CurrentSpeed == MaxSpeed)
                {
                    MaxSpeed = Ships[0].ShipClass.MaxSpeed;
                    CurrentSpeed = MaxSpeed;
                }
                else
                    MaxSpeed = Ships[0].ShipClass.MaxSpeed;
            }
            else
            {
                /// <summary>
                /// Only set the speed to a new potentially higher max speed if there is one, and if the user has set this taskgroup to its max speed.
                /// The assumption is that the user will want to keep his taskgroup at its maximum speed.
                /// </summary>
                int lowestMax = Ships[0].ShipClass.MaxSpeed;
                for (int loop = 1; loop < Ships.Count; loop++)
                {
                    if (Ships[loop].ShipClass.MaxSpeed < lowestMax)
                    {
                        lowestMax = Ships[loop].ShipClass.MaxSpeed;
                    }
                }
                if (CurrentSpeed == MaxSpeed)
                {
                    MaxSpeed = lowestMax;
                    CurrentSpeed = MaxSpeed;
                }
                else
                    MaxSpeed = lowestMax;
            }

            for (int loop = 0; loop < Ships.Count; loop++)
            {
                Ships[loop].SetSpeed(CurrentSpeed);
            }

            /// <summary>
            /// Let the UI know it should re check this taskgroup's sensors.
            /// </summary>
            SensorUpdateAck++;
        }
Example #15
0
        /// <summary>
        /// Separate from AddShip, this will add an existing ship to this taskgroup.
        /// </summary>
        /// <param name="Ship">Ship to be added</param>
        public void AddShipTo(ShipTN Ship)
        {
            Ships.Add(Ship);

            if(Ships.Count == 1)
            {
                MaxSpeed = Ship.ShipClass.MaxSpeed;
                CurrentSpeed = MaxSpeed;
            }
            else
            {
                if (CurrentSpeed == MaxSpeed)
                {
                    if (Ship.ShipClass.MaxSpeed < MaxSpeed)
                    {
                        MaxSpeed = Ship.ShipClass.MaxSpeed;
                        CurrentSpeed = MaxSpeed;
                    }
                }
                /// <summary>
                /// Current Speed is lower than the maxspeed which means that the user has set current speed below max speed already.
                /// </summary>
                else
                {
                    /// <summary>
                    /// Set the new max speed of the taskgroup if there is one.
                    /// </summary>
                    if (Ship.ShipClass.MaxSpeed < MaxSpeed)
                    {
                        MaxSpeed = Ship.ShipClass.MaxSpeed;
                    }

                    /// <summary>
                    /// Max speed is less than the set current speed.
                    /// </summary>
                    if (MaxSpeed < CurrentSpeed)
                    {
                        CurrentSpeed = MaxSpeed;
                    }
                }
            }

            for (int loop = 0; loop < Ships.Count; loop++)
            {
                Ships[loop].SetSpeed(CurrentSpeed);
            }

            /// <summary>
            /// Update the taskgroupwide statistics here, consider moving this to its own function should it grow beyond this.
            /// </summary>
            TotalCargoTonnage = TotalCargoTonnage + Ship.ShipClass.TotalCargoCapacity;
            TotalCryoCapacity = TotalCryoCapacity + Ship.ShipClass.SpareCryoBerths;

            /// <summary>
            /// Add this ship to the sensor datagroups of this taskgroup
            /// </summary>
            UpdatePassiveSensors(Ship);
            AddShipToSort(Ship);

            /// <summary>
            /// Let the UI know it should re check this taskgroup's sensors.
            /// </summary>
            SensorUpdateAck++;
        }
Example #16
0
                /// <summary>
                /// Constructor for task.
                /// ABR = Normal shipbuilding rate x (1+(((Class Size / 100) - 1)/2)) 
                /// Scrap Formula is ((0.25 * ShipCost) / ABR) * Year = days involved.
                /// </summary>
                /// <param name="Ship">Ship to repair/refit/scrap. build will be handled elsewhere.</param>
                /// <param name="TargetTG">Target TG which the ship will be put back in to, or in the case of a scrap operation taken from.</param>
                /// <param name="PopulationBuildRate">What is the currently selected shipyard capable of building? population and faction should factor into this number.</param>
                /// <param name="ConstructOrRefitTarget">If a new ship is being built, or an old ship is being refitted, what target design are we interested in?</param>
                public ShipyardTask(ShipTN Ship, Constants.ShipyardInfo.Task TaskToPerform, TaskGroupTN TargetTG, int PopulationBuildRate, String TitleToUse, ShipClassTN ConstructOrRefitTarget=null)
                {
                    m_aiMinerialsCost = new decimal[(int)Constants.Minerals.MinerialNames.MinerialCount];

                    CurrentShip = Ship;
                    CurrentTask = TaskToPerform;
                    Progress = 0.0m;
                    Priority = 0;
                    Paused = false;
                    ConstructRefitTarget = ConstructOrRefitTarget;

                    ABR = 1;

                    AssignedTaskGroup = TargetTG;

                    if(AssignedTaskGroup != null)
                        AssignedTaskGroup.IsInShipyard = true;

                    Cost = 0.0m;

                    /// <summary>
                    /// This is only relevant for new ship construction.
                    /// </summary>
                    Title = TitleToUse;

                    switch (TaskToPerform)
                    {
                        case Constants.ShipyardInfo.Task.Construction:
                            ABR = (int)Math.Round(PopulationBuildRate * (1.0f + (((ConstructRefitTarget.SizeHS / 100.0f) - 1.0f) / 2.0f)));
                            Cost = ConstructRefitTarget.BuildPointCost;
                            for (int mineralIterator = 0; mineralIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; mineralIterator++)
                            {
                                m_aiMinerialsCost[mineralIterator] = ConstructRefitTarget.minerialsCost[mineralIterator];
                            }        
                            break;
                        case Constants.ShipyardInfo.Task.Repair:
                            ABR = (int)Math.Round(PopulationBuildRate * (1.0f + (((Ship.ShipClass.SizeHS / 100.0f) - 1.0f) / 2.0f)));
                            /// <summary>
                            /// Repair will just cost money. Two reasons. 1st: Laziness. I'd have to get all the component costs as well.
                            /// 2nd:Ships require continuous resource outlays via routine maintenance, that should and will cover the actual cost of repairing the ship above and beyond the money required.
                            /// </summary>
                            for(int componentIterator = 0; componentIterator < Ship.DestroyedComponents.Count; componentIterator++)
                            {
                                ushort ID = Ship.DestroyedComponents[componentIterator];
                                ComponentTypeTN CType = Ship.DestroyedComponentsType[componentIterator];
                                Cost = Cost + Ship.GetDamagedComponentsRepairCost(ID,CType);
                            }

                            if(Ship.ShipArmor.isDamaged == true)
                            {
                                int totalDamage = 0;
                                int max = Ship.ShipArmor.armorDef.cNum * Ship.ShipArmor.armorDef.depth;
                                foreach (KeyValuePair<ushort, ushort> pair in Ship.ShipArmor.armorDamage)
                                {
                                    totalDamage = totalDamage + pair.Value;
                                }

                                float damageFraction = ((float)totalDamage / (float)max);

                                Cost = Cost + ((decimal)damageFraction * Ship.ShipArmor.armorDef.cost);
                            }

                            for (int mineralIterator = 0; mineralIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; mineralIterator++)
                            {
                                m_aiMinerialsCost[mineralIterator] = 0.0m;
                            }
                               
                            break;
                        case Constants.ShipyardInfo.Task.Refit:
                            ABR = (int)Math.Round(PopulationBuildRate * (1.0f + (((ConstructRefitTarget.SizeHS / 100.0f) - 1.0f) / 2.0f)));
                            Cost = ConstructRefitTarget.BuildPointCost;
                            for (int mineralIterator = 0; mineralIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; mineralIterator++)
                            {
                                m_aiMinerialsCost[mineralIterator] = ConstructRefitTarget.minerialsCost[mineralIterator];
                            }
                            break;
                        case Constants.ShipyardInfo.Task.Scrap:
                            ABR = (int)Math.Round(PopulationBuildRate * (1.0f + (((Ship.ShipClass.SizeHS / 100.0f) - 1.0f) / 2.0f)));
                            Cost = Ship.ShipClass.BuildPointCost * -0.25m;
                            for (int mineralIterator = 0; mineralIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; mineralIterator++)
                            {
                                m_aiMinerialsCost[mineralIterator] = Ship.ShipClass.minerialsCost[mineralIterator] * -0.25m;
                            }
                            break;
                    }
                    /// <summary>
                    /// How long will this retool take?
                    /// </summary>
                    float DaysInYear = (float)Constants.TimeInSeconds.RealYear / (float)Constants.TimeInSeconds.Day; 
                    float YearsOfProduction = (float)Math.Abs(Cost) / (float)ABR;
                    DateTime EstTime = GameState.Instance.GameDateTime;
                    if (YearsOfProduction < Constants.Colony.TimerYearMax)
                    {
                        int TimeToBuild = (int)Math.Floor(YearsOfProduction * DaysInYear);
                        TimeSpan TS = new TimeSpan(TimeToBuild, 0, 0, 0);
                        EstTime = EstTime.Add(TS);
                    }
                    CompletionDate = EstTime;
                }
Example #17
0
        public void testASensor()
        {

            Faction newFaction = new Faction(0);

            StarSystem System1 = SystemGen.CreateSol();

            SystemBody pl1 = new SystemBody(System1.Stars[0], SystemBody.PlanetType.Terrestrial);
            System1.Stars[0].Planets.Add(pl1);

            TaskGroupTN newTG = new TaskGroupTN("TG", newFaction, System1.Stars[0].Planets[0], System1);

            ShipClassTN ts2 = new ShipClassTN("Test", newFaction);
            ShipTN ts = new ShipTN(ts2, 0, 0, newTG, newFaction, "Test Ship");

            ActiveSensorDefTN ASensorDefTest = new ActiveSensorDefTN("Active Search Sensor MR705-R185", 6.0f, 36, 24, 185, false, 1.0f, 1);

            ts2.ShipASensorDef = new BindingList<ActiveSensorDefTN>();
            ts2.ShipASensorCount = new BindingList<ushort>();
            ts2.ShipASensorDef.Add(ASensorDefTest);
            ts2.ShipASensorCount.Add(1);

            ActiveSensorTN ASensorTest = new ActiveSensorTN(ts2.ShipASensorDef[0]);

            ts.ShipASensor = new BindingList<ActiveSensorTN>();
            ts.ShipASensor.Add(ASensorTest);


            ActiveSensorDefTN tst3 = ts.ShipASensor[0].aSensorDef;

            Console.WriteLine("Name: {0}", tst3.Name);
            Console.WriteLine("Size: {0}, HTK: {1}, Hardening: {2}", tst3.size, tst3.htk, tst3.hardening);
            Console.WriteLine("GPS: {0}, Range: {1}", tst3.gps, tst3.maxRange);
            Console.WriteLine("IsMilitary: {0}", tst3.isMilitary);
            Console.WriteLine("Crew: {0}", tst3.crew);
            Console.WriteLine("Cost: {0}", tst3.cost);

            for (ushort loop = 80; loop < 120; loop++)
            {
                Console.WriteLine("Resolution:{0} Detection Range in KM:{1}", loop, tst3.GetActiveDetectionRange(loop, -1));
            }
        }
Example #18
0
        public void testEngine()
        {

            Faction newFaction = new Faction(0);

            StarSystem System1 = SystemGen.CreateSol();

            SystemBody pl1 = new SystemBody(System1.Stars[0], SystemBody.PlanetType.Terrestrial);
            System1.Stars[0].Planets.Add(pl1);

            TaskGroupTN newTG = new TaskGroupTN("TG", newFaction, System1.Stars[0].Planets[0], System1);

            ShipClassTN ts2 = new ShipClassTN("Test", newFaction);
            ShipTN ts = new ShipTN(ts2, 0, 0, newTG, newFaction, "Test Ship");

            ts2.ShipEngineDef = new EngineDefTN("3137.6 EP Inertial Fusion Drive", 32, 2.65f, 0.6f, 0.75f, 2, 37, -1.0f);
            ts2.ShipEngineCount = 1;

            EngineTN temp = new EngineTN(ts2.ShipEngineDef);

            ts.ShipEngine = new BindingList<EngineTN>();
            ts.ShipEngine.Add(temp);

            EngineDefTN tst = ts.ShipEngine[0].engineDef;

            Console.WriteLine("Name: {0}", tst.Name);
            Console.WriteLine("EngineBase: {0}, PowerMod: {1}, FuelConMod: {2}, ThermalReduction: {3}, Size: {4},HyperMod: {5}",
                              tst.engineBase, tst.powerMod, tst.fuelConsumptionMod, tst.thermalReduction, tst.size, tst.hyperDriveMod);
            Console.WriteLine("EnginePower: {0}, FuelUsePerHour: {1}", tst.enginePower, tst.fuelUsePerHour);
            Console.WriteLine("EngineSize: {0}, EngineHTK: {1}", tst.size, tst.htk);
            Console.WriteLine("ThermalSignature: {0}, ExpRisk: {1}", tst.thermalSignature, tst.expRisk);
            Console.WriteLine("IsMilitary: {0}", tst.isMilitary);
            Console.WriteLine("Crew: {0}", tst.crew);
            Console.WriteLine("Cost: {0}", tst.cost);
        }
Example #19
0
        public bool OnDamaged(DamageTypeTN TypeOfDamage, ushort Value, ShipTN FiringShip, int RadLevel = 0)
        {
            /// <summary>
            /// Check damage type to see if atmosphere blocks it.
            /// Populations are damaged in several ways.
            /// Civilian Population will die off, about 50k per point of damage.
            /// Atmospheric dust will be kicked into the atmosphere(regardless of whether or not there is an atmosphere) lowering temperature for a while.
            /// Some beam weapons are blocked(partially or in whole) by atmosphere(Lasers,Gauss,Railguns,particle beams, plasma), some are not(Mesons), and some have no effect(microwaves) on populations.
            /// PDCs will be similarly defended by this atmospheric blocking but are vulnerable to microwaves.
            /// Missiles will increase the radiation value of the colony. Enhanced Radiation warheads will add more for less overall damage done. Radiation is of course harmful to life on the world. but
            /// not immediately so.
            /// Installations will have a chance at being destroyed. bigger installations should be more resilient to damage, but even infrastructure should have a chance to survive.
            /// Shipyards must be targetted in orbit around the colony. Special handling will be required for that.
            /// </summary>

            ushort ActualDamage;
            switch (TypeOfDamage)
            {
                /// <summary>
                /// Neither missile nor meson damage is effected by atmospheric pressure.
                /// </summary>
                case DamageTypeTN.Missile:
                case DamageTypeTN.Meson:
                    ActualDamage = Value;
                break;
                /// <summary>
                /// All other damage types must be adjusted by atmospheric pressure.
                /// </summary>
                default:
                    ActualDamage = (ushort)Math.Round((float)Value * Planet.Atmosphere.Pressure);
                break;
            }

            /// <summary>
            /// No damage was done. either all damage was absorbed by the atmosphere or the missile had no warhead. Missiles with no warhead should "probably" be sensor missiles that loiter in orbit
            /// until their fuel is gone.
            /// </summary>
            if (ActualDamage == 0)
            {
                return false;
            }

            /// <summary>
            /// Each point of damage kills off 50,000 people, or 0.05f as 1.0f = 1M people.
            /// </summary>
            float PopulationDamage = 0.05f * ActualDamage;
            CivilianPopulation = CivilianPopulation - PopulationDamage;

            /// <summary>
            /// Increase the atmospheric dust and radiation of the planet.
            /// </summary>
            Planet.AtmosphericDust = Planet.AtmosphericDust + ActualDamage;
            Planet.RadiationLevel = Planet.RadiationLevel + RadLevel;

            if (GameState.Instance.DamagedPlanets.Contains(Planet) == false)
                GameState.Instance.DamagedPlanets.Add(Planet);

            String IndustrialDamage = "Industrial Damage:";
            while (ActualDamage > 0)
            {
                ActualDamage = (ushort)(ActualDamage - 5);
                /// <summary>
                /// Installation destruction will be naive. pick an installation at random.
                /// </summary>
                int Inst = GameState.RNG.Next(0, (int)Installation.InstallationType.InstallationCount);
                if (Inst == (int)Installation.InstallationType.CommercialShipyard || Inst == (int)Installation.InstallationType.NavalShipyardComplex)
                {
                    /// <summary>
                    /// Damage was done, but installations escaped unharmed. Shipyards must be damaged from orbit.
                    /// </summary>
                    continue;
                }
                else if (Inst >= (int)Installation.InstallationType.ConvertCIToConstructionFactory && Inst <= (int)Installation.InstallationType.ConvertMineToAutomated)
                {
                    /// <summary>
                    /// These "installations" can't be damaged, so again, lucky planet.
                    /// </summary>
                    continue;
                }
                else
                {
                    int InstCount = (int)Math.Floor(Installations[Inst].Number);

                    /// <summary>
                    /// Luckily for the planet it had none of the installations that just got targetted.
                    /// </summary>
                    if (InstCount == 0)
                    {
                        continue;
                    }

                    switch ((Installation.InstallationType)Inst)
                    {
                        case Installation.InstallationType.DeepSpaceTrackingStation:
                            /// <summary>
                            /// A DSTS was destroyed at this population, inform the UI to update the display.
                            /// </summary>
                            _SensorUpdateAck++; 
                            break;
                    }

                    /// <summary>
                    /// Installation destroyed.
                    /// </summary>
                    Installations[Inst].Number = Installations[Inst].Number - 1.0f;

#warning Industry damage should be reworked to have differing resilience ratings, and logging should compress industrial damage.
                    IndustrialDamage = String.Format("{0} {1}: {2}", IndustrialDamage, Installations[Inst].Name, 1);
                }
            }

            String Entry = String.Format("{0} hit by {1} points of damage. Casualties: {2}{3}Environment Update: Atmospheric Dust:{4}, Radiation:{5}", Name,ActualDamage,PopulationDamage,
                                         IndustrialDamage,Planet.AtmosphericDust, Planet.RadiationLevel);
            MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.PopulationDamage, Planet.Position.System, Contact,
            GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, Entry);
            Faction.MessageLog.Add(NMsg);

            return false;
        }
Example #20
0
        /// <summary>
        /// Damage goes through a 3 part process, 1st shields subtract damage, then armor blocks damage, then internals take the hits.
        /// if 20 rolls happen without an internal in the list being targeted then call OnDestroyed(); Mesons skip to the internal damage section.
        /// Microwaves do shield damage, then move to the special electronic only DAC.
        /// </summary>
        /// <param name="Type">Type of damage, for armor penetration.</param>
        /// <param name="Value">How much damage is being done.</param>
        /// <param name="HitLocation">Where Armor damage is inflicted. Temporary argument for the time being. remove these when rngs are resolved.</param>
        /// <returns>Whether or not the ship was destroyed as a result of this action.</returns>
        public bool OnDamaged(DamageTypeTN Type, ushort Value, ushort HitLocation, ShipTN FiringShip)
        {
            ushort Damage = Value;
            ushort internalDamage = 0;
            ushort startDamage = Value;
            bool ColumnPenetration = false;
            int LastColumnValue = ShipArmor.armorDef.depth;

            if (Type != DamageTypeTN.Meson)
            {

                /// <summary>
                /// Handle Shield Damage.
                /// Microwaves do 3 damage to shields. Make them do 3xPowerReq?
                /// </summary>

                if (Type == DamageTypeTN.Microwave)
                {
                    if (CurrentShieldPool >= 3.0f)
                    {
                        CurrentShieldPool = CurrentShieldPool - 3.0f;
                        Damage = 0;
                    }
                    else if (CurrentShieldPool < 1.0f)
                    {
                        CurrentShieldPool = 0.0f;
                    }
                    else
                    {
                        /// <summary>
                        /// Microwaves only do 1 damage to internals, so take away the bonus damage to shields here.
                        /// </summary>
                        Damage = 1;
                        CurrentShieldPool = 0.0f;
                    }
                }
                else
                {
                    if (CurrentShieldPool >= Damage)
                    {
                        CurrentShieldPool = CurrentShieldPool - Damage;
                        Damage = 0;
                    }
                    else if (CurrentShieldPool < 1.0f)
                    {
                        CurrentShieldPool = 0.0f;
                    }
                    else
                    {
                        Damage = (ushort)(Damage - (ushort)Math.Floor(CurrentShieldPool));

                        CurrentShieldPool = 0.0f;
                    }
                }

                /// <summary>
                /// Shields absorbed all damage.
                /// </summary>
                if (Damage == 0)
                {
                    String DamageString = String.Format("All damage to {0} absorbed by shields", Name);
                    MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.ShipDamage, ShipsTaskGroup.Contact.Position.System, ShipsTaskGroup.Contact,
                                                         GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, DamageString);

                    ShipsFaction.MessageLog.Add(NMsg);

                    return false;
                }
                else
                {

                    if ((startDamage - Damage) > 0)
                    {
                        String DamageString = String.Format("{0} damage to {1} absorbed by shields", (startDamage - Damage), Name);
                        MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.ShipDamage, ShipsTaskGroup.Contact.Position.System, ShipsTaskGroup.Contact,
                                                             GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, DamageString);

                        ShipsFaction.MessageLog.Add(NMsg);
                    }
                }

                startDamage = Damage;

                if (Type != DamageTypeTN.Microwave)
                {
                    /// <summary>
                    /// Shock Damage:
                    /// </summary>
                    Random ShockRand = new Random((int)startDamage);
                    float ShockChance = (float)Math.Floor(Math.Pow(startDamage, 1.3));
                    int shockTest = ShockRand.Next(0, 100);

                    /// <summary>
                    /// There is a chance for shock damage to occur
                    /// </summary>
                    if (shockTest > ShockChance)
                    {
                        float sTest = (float)ShockRand.Next(0, 100) / 100.0f;
                        internalDamage = (ushort)Math.Floor(((startDamage / 3.0f) * sTest));

                        if (internalDamage != 0)
                        {
                            String DamageString = String.Format("{0} Shock Damage to {1}", (internalDamage), Name);
                            MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.ShipDamage, ShipsTaskGroup.Contact.Position.System, ShipsTaskGroup.Contact,
                                                                 GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, DamageString);

                            ShipsFaction.MessageLog.Add(NMsg);
                        }
                    }

                    /// <summary>
                    /// Armor Penetration.
                    /// </summary>
                    ushort Columns = ShipArmor.armorDef.cNum;
                    short left, right;

                    ushort ImpactLevel = ShipArmor.armorDef.depth;
                    if (ShipArmor.isDamaged == true)
                        ImpactLevel = ShipArmor.armorColumns[HitLocation];

                    DamageTableTN Table;
                    switch (Type)
                    {
                        case DamageTypeTN.Beam: Table = DamageValuesTN.EnergyTable[Damage - 1];
                            break;
                        case DamageTypeTN.Kinetic: Table = DamageValuesTN.KineticTable[Damage - 1];
                            break;
                        case DamageTypeTN.Missile: Table = DamageValuesTN.MissileTable[Damage - 1];
                            break;
                        case DamageTypeTN.Plasma: Table = DamageValuesTN.PlasmaTable[Damage - 1];
                            break;
                        default:
                            Table = DamageValuesTN.MissileTable[Damage - 1];
                            break;
                    }
                    left = (short)(HitLocation - 1);
                    right = (short)(HitLocation + 1);

                    /// <summary>
                    /// What is the column damage level at Hit Location?
                    /// </summary>
                    if (ShipArmor.isDamaged == true)
                    {
                        LastColumnValue = ShipArmor.armorColumns[HitLocation];
                    }

                    /// <summary>
                    /// internalDamage is all damage that passed through the armour.
                    /// </summary>
                    internalDamage = (ushort)ShipArmor.SetDamage(Columns, ShipArmor.armorDef.depth, HitLocation, Table.damageTemplate[Table.hitPoint]);

                    /// <summary>
                    /// If this is a new penetration note this fact.
                    /// </summary>
                    if (LastColumnValue != 0 && internalDamage != 0)
                    {
                        ColumnPenetration = true;
                    }

                    /// <summary>
                    /// The plasma template is a little wierd and requires handling this condition. basically it has two maximum strength penetration attacks.
                    /// </summary>
                    if (Type == DamageTypeTN.Plasma && Table.hitPoint + 1 < Table.damageTemplate.Count)
                    {

                        if (ShipArmor.isDamaged == true)
                        {
                            LastColumnValue = ShipArmor.armorColumns[(HitLocation + 1)];
                        }

                        internalDamage = (ushort)((ushort)internalDamage + (ushort)ShipArmor.SetDamage(Columns, ShipArmor.armorDef.depth, (ushort)(HitLocation + 1), Table.damageTemplate[Table.hitPoint + 1]));


                        if (LastColumnValue != 0 && internalDamage != 0)
                        {
                            ColumnPenetration = true;
                        }

                        right++;
                    }

                    /// <summary>
                    /// Calculate the armour damage to the left and right of the hitLocation.
                    /// </summary>
                    for (int loop = 1; loop <= Table.halfSpread; loop++)
                    {
                        if (left < 0)
                        {
                            left = (short)(Columns - 1);
                        }
                        if (right >= Columns)
                        {
                            right = 0;
                        }

                        /// <summary>
                        /// side impact damage doesn't always reduce armor, the principle hitpoint should be the site of the deepest armor penetration. Damage can be wasted in this manner.
                        /// </summary>
                        if (Table.hitPoint - loop >= 0)
                        {
                            if (ShipArmor.isDamaged == true)
                            {
                                LastColumnValue = ShipArmor.armorColumns[left];
                            }

                            if (ImpactLevel - Table.damageTemplate[Table.hitPoint - loop] < ShipArmor.armorColumns[left])
                                internalDamage = (ushort)((ushort)internalDamage + (ushort)ShipArmor.SetDamage(Columns, ShipArmor.armorDef.depth, (ushort)left, Table.damageTemplate[Table.hitPoint - loop]));

                            if (LastColumnValue != 0 && internalDamage != 0)
                            {
                                ColumnPenetration = true;
                            }

                        }

                        if (Table.hitPoint + loop < Table.damageTemplate.Count)
                        {
                            if (ShipArmor.isDamaged == true)
                            {
                                LastColumnValue = ShipArmor.armorColumns[right];
                            }

                            if (ImpactLevel - Table.damageTemplate[Table.hitPoint + loop] < ShipArmor.armorColumns[right])
                                internalDamage = (ushort)((ushort)internalDamage + (ushort)ShipArmor.SetDamage(Columns, ShipArmor.armorDef.depth, (ushort)right, Table.damageTemplate[Table.hitPoint + loop]));

                            if (LastColumnValue != 0 && internalDamage != 0)
                            {
                                ColumnPenetration = true;
                            }

                        }

                        left--;
                        right++;
                    }

                    if ((startDamage - internalDamage) > 0)
                    {

                        String DamageString = String.Format("{0} damage to {1} absorbed by Armour", (startDamage - internalDamage), Name);
                        MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.ShipDamage, ShipsTaskGroup.Contact.Position.System, ShipsTaskGroup.Contact,
                                                             GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, DamageString);

                        ShipsFaction.MessageLog.Add(NMsg);
                    }

                    if (ColumnPenetration == true)
                    {

                        String DamageString = "N/A";

                        /// <summary>
                        /// Need a switch here for organic or solid state ships to change or remove this message.
                        /// </summary>
                        switch (TypeOf)
                        {
                            case ShipType.Standard:
                                DamageString = String.Format("{0} is streaming atmosphere", Name);
                                break;
                            case ShipType.Organic:
                                DamageString = String.Format("{0} is streaming fluid", Name);
                                break;
                        }

                        if (TypeOf == ShipType.Standard || TypeOf == ShipType.Organic)
                        {

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

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

                }
                else
                {
                    /// <summary>
                    /// This is a microwave strike.
                    /// </summary>
                    internalDamage = 1;
                }
            }
            else
            {
                /// <summary>
                /// This is a meson strike.
                /// </summary>
                internalDamage = 1;
            }

            /// <summary>
            /// Internal Component Damage. Each component with an HTK >0 can take atleast 1 hit. a random number is rolled over the entire dac. the selected component's HTK
            /// is tested against the internal damage value, and if greater than the damage value the component has a chance of surviving. otherwise, the component is destroyed, damage
            /// is reduced, and the next component is chosen.
            /// DAC Should be redone as a binary tree at some later date.
            /// 
            /// The Electronic DAC should be used for microwave hits, ships can't be destroyed due to microwave strikes however.
            /// </summary>
            int Attempts = 0;
            Random DacRNG = new Random(HitLocation);

            if (Type != DamageTypeTN.Microwave)
            {
                /// <summary>
                /// If 20 attempts to damage a component are made unsuccessfully the ship is considered destroyed. Does this scale well with larger ships?
                /// </summary>
                while (Attempts < 20 && internalDamage > 0)
                {
                    int DACHit = DacRNG.Next(1, ShipClass.DamageAllocationChart[ShipClass.ListOfComponentDefs[ShipClass.ListOfComponentDefs.Count - 1]]);

                    int localDAC = 1;
                    int previousDAC = 1;
                    int destroy = -1;
                    for (int loop = 0; loop < ShipClass.ListOfComponentDefs.Count; loop++)
                    {
                        localDAC = ShipClass.DamageAllocationChart[ShipClass.ListOfComponentDefs[loop]];
                        if (DACHit <= localDAC)
                        {
                            float size = ShipClass.ListOfComponentDefs[loop].size;
                            if (size < 1.0)
                                size = 1.0f;

                            destroy = (int)Math.Floor(((float)(DACHit - previousDAC) / (float)size));

                            /// <summary>
                            /// By this point total should definitely be >= destroy. destroy is the HS of the group being hit.
                            /// Should I try to find the exact component hit, or merely loop through all of them?
                            /// internalDamage: Damage done to all internals
                            /// destroy: component to destroy from shipClass.ListOfComponentDefs
                            /// ComponentDefIndex[loop] where in ShipComponents this definition group is.
                            /// </summary>

                            int DamageDone = DestroyComponent(ShipClass.ListOfComponentDefs[loop].componentType, loop, internalDamage, destroy, DacRNG);

                            if (DamageDone != -1)
                            {
                                int ID = ComponentDefIndex[loop] + destroy;

                                if (ShipComponents[ID].isDestroyed == true)
                                {
                                    String DamageString = String.Format("{0} hit by {1} damage and was destroyed", ShipComponents[ID].Name, DamageDone);
                                    MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.ShipDamage, ShipsTaskGroup.Contact.Position.System, ShipsTaskGroup.Contact,
                                                                         GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, DamageString);

                                    ShipsFaction.MessageLog.Add(NMsg);
                                }
                                else
                                {
                                    String DamageString = String.Format("{0} Absorbed {1} damage", ShipComponents[ID].Name, DamageDone);
                                    MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.ShipDamage, ShipsTaskGroup.Contact.Position.System, ShipsTaskGroup.Contact,
                                                                         GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, DamageString);

                                    ShipsFaction.MessageLog.Add(NMsg);
                                }
                            }

                            /// <summary>
                            /// No components are left to destroy, so short circuit the loops,destroy the ship, and create a wreck.
                            /// </summary>
                            if (DestroyedComponents.Count == ShipComponents.Count)
                            {
                                Attempts = 20;
                                internalDamage = 0;
                                break;
                            }


                            if (DamageDone == -1)
                            {
                                Attempts++;
                                if (Attempts == 20)
                                {
                                    internalDamage = 0;
                                }
                                break;
                            }
                            else if (DamageDone == -2)
                            {
                                Attempts = 20;
                                break;
                            }
                            else
                            {
                                internalDamage = (ushort)(internalDamage - (ushort)DamageDone);
                                break;
                            }
                        }
                        previousDAC = localDAC + 1;
                    }
                }

                if (Attempts == 20)
                {
                    String DamageString = String.Format("{0} Destroyed", Name);
                    MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.ShipDamage, ShipsTaskGroup.Contact.Position.System, ShipsTaskGroup.Contact,
                                                         GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, DamageString);

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


                    IsDestroyed = true;
                    return true;
                }
            }
            else
            {
                /// <summary>
                /// Electronic damage can never destroy a craft, only wreck its sensors, so we'll cut short the attempts to damage components to only 5.
                /// There is no list of only electronic components, and only destroyed electronic components so this will have to do for now.
                /// Having those would improve performance slightly however.
                /// </summary>
                while (Attempts < 5 && internalDamage > 0)
                {
                    ComponentDefTN last = ShipClass.ElectronicDamageAllocationChart.Keys.Last();
                    int DACHit = DacRNG.Next(1, ShipClass.ElectronicDamageAllocationChart[last]);

                    int localDAC = 1;
                    int previousDAC = 1;
                    int destroy = -1;

                    foreach (KeyValuePair<ComponentDefTN, int> list in ShipClass.ElectronicDamageAllocationChart)
                    {
                        localDAC = ShipClass.ElectronicDamageAllocationChart[list.Key];

                        if (DACHit <= localDAC)
                        {
                            float size = list.Key.size;
                            if (size < 1.0)
                                size = 1.0f;

                            /// <summary>
                            /// Electronic component to attempt to destroy:
                            /// </summary>
                            destroy = (int)Math.Floor(((float)(DACHit - previousDAC) / (float)size));

                            /// <summary>
                            /// Actually destroy the component.
                            /// Store EDAC index values somewhere for speed?
                            /// </summary>

                            int CI = ShipClass.ListOfComponentDefs.IndexOf(list.Key);

                            int ComponentIndex = ShipComponents[ComponentDefIndex[CI] + destroy].componentIndex;

                            float hardCheck = (float)DacRNG.Next(1, 100);
                            float hardValue = -1.0f;

                            switch (list.Key.componentType)
                            {
                                case ComponentTypeTN.ActiveSensor:
                                    hardValue = ShipASensor[ComponentIndex].aSensorDef.hardening * 100.0f;
                                    break;
                                case ComponentTypeTN.PassiveSensor:
                                    hardValue = ShipPSensor[ComponentIndex].pSensorDef.hardening * 100.0f;
                                    break;
                                case ComponentTypeTN.BeamFireControl:
                                    hardValue = ShipBFC[ComponentIndex].beamFireControlDef.hardening * 100.0f;
                                    break;
                                case ComponentTypeTN.MissileFireControl:
                                    hardValue = ShipMFC[ComponentIndex].mFCSensorDef.hardening * 100.0f;
                                    break;
                            }

                            int DamageDone = -1;

                            if (hardValue == -1)
                            {
                                /// <summary>
                                /// This is an error condition obviously. I likely forgot to put the component in above however.
                                /// </summary>
                                String ErrorString = String.Format("Unidentified electronic component in onDamaged() Type:{0}.", list.Key.componentType);
                                MessageEntry EMsg = new MessageEntry(MessageEntry.MessageType.Error, ShipsTaskGroup.Contact.Position.System, ShipsTaskGroup.Contact,
                                    GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, ErrorString);
                                ShipsFaction.MessageLog.Add(EMsg);
                            }
                            else
                            {

                                if (hardCheck < hardValue)
                                {
                                    DamageDone = DestroyComponent(list.Key.componentType, CI, internalDamage, destroy, DacRNG);

                                    if (DamageDone != -1)
                                    {
                                        int ID = ComponentDefIndex[CI] + destroy;

                                        if (ShipComponents[ID].isDestroyed == true)
                                        {
                                            String DamageString = String.Format("{0} hit by {1} damage and was destroyed", ShipComponents[ID].Name, DamageDone);
                                            MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.ShipDamage, ShipsTaskGroup.Contact.Position.System, ShipsTaskGroup.Contact,
                                                                                 GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, DamageString);

                                            ShipsFaction.MessageLog.Add(NMsg);
                                        }
                                        else
                                        {
                                            String DamageString = String.Format("{0} Absorbed {1} damage. Electronic Components shouldn't resist damage like this", ShipComponents[ID].Name, DamageDone);
                                            MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.ShipDamage, ShipsTaskGroup.Contact.Position.System, ShipsTaskGroup.Contact,
                                                                                 GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, DamageString);

                                            ShipsFaction.MessageLog.Add(NMsg);
                                        }
                                    }
                                }
                                else
                                {

                                    int ID = ComponentDefIndex[CI] + destroy;
                                    String DamageString = String.Format("{0} Absorbed {1} damage", ShipComponents[ID].Name, DamageDone);
                                    MessageEntry NMsg = new MessageEntry(MessageEntry.MessageType.ShipDamage, ShipsTaskGroup.Contact.Position.System, ShipsTaskGroup.Contact,
                                                                         GameState.Instance.GameDateTime, GameState.Instance.LastTimestep, DamageString);

                                    ShipsFaction.MessageLog.Add(NMsg);

                                    DamageDone = 0;
                                }
                            }



                            if (DamageDone == -1)
                            {
                                Attempts++;
                                if (Attempts == 5)
                                {
                                    internalDamage = 0;
                                }
                                break;
                            }
                            else
                            {
                                /// <summary>
                                /// Electronic damage should always be only 1.
                                /// </summary>
                                internalDamage = 0;
                                break;
                            }
                        }
                        previousDAC = localDAC + 1;
                    }
                }
            }

            return false;
        }
Example #21
0
        /// <summary>
        /// End SortShipBySignature
        /// </summary>

        /// <summary>
        /// RemoveShipFromTaskGroup handles removal of the ship from the various detection linked lists. It also traverses the linked lists
        /// and decrements node values as appropriate to reflect the new state of the linked list ids.
        /// </summary>
        /// <param name="Ship">Ship to be removed.</param>
        /// <returns>Were nodes removed from the various linkedLists?</returns>
        public bool RemoveShipFromTaskGroup(ShipTN Ship)
        {
            /// <summary>
            /// Both active and passive sensors need to be updated to reflect that this ship is no longer part of the taskgroup.
            /// </summary>
            for(int activeIterator = 0; activeIterator < Ship.ShipASensor.Count; activeIterator++)
            {
                SetActiveSensor(Ships.IndexOf(Ship), activeIterator, false);
            }

            for (int passiveIterator = 0; passiveIterator < Ship.ShipPSensor.Count; passiveIterator++)
            {
                PassiveSensorTN PassiveS = Ship.ShipPSensor[passiveIterator];
                /// <summary>
                /// Performance could be improved here by storing a sorted linked list of all passive sensors if need be.
                /// I don't believe that sensor destruction events will be common enough to necessitate that however.
                /// </summary>
                if (PassiveS.pSensorDef.thermalOrEM == PassiveSensorType.EM)
                {
                    if (PassiveS.pSensorDef.rating == BestEM.pSensorDef.rating)
                    {
                        BestEMCount--;

                        if (BestEMCount == 0)
                        {
                            for (int loop = 0; loop < Ships.Count; loop++)
                            {
                                for (int loop2 = 0; loop2 < Ships[loop].ShipPSensor.Count; loop2++)
                                {
                                    if (Ships[loop].ShipPSensor[loop2].pSensorDef.thermalOrEM == PassiveSensorType.EM &&
                                        Ships[loop].ShipPSensor[loop2].isDestroyed == false)
                                    {
                                        if (BestEMCount == 0 || Ships[loop].ShipPSensor[loop2].pSensorDef.rating > BestEM.pSensorDef.rating)
                                        {
                                            BestEM = Ships[loop].ShipPSensor[loop2];
                                            BestEMCount = 1;
                                        }
                                        else if (Ships[loop].ShipPSensor[loop2].pSensorDef.rating == BestEM.pSensorDef.rating)
                                        {
                                            BestEMCount++;
                                        }
                                    }

                                }
                            }
                        }
                    }
                }
                else
                {
                    if (PassiveS.pSensorDef.rating == BestThermal.pSensorDef.rating)
                    {
                        BestThermalCount--;

                        if (BestThermalCount == 0)
                        {
                            for (int loop = 0; loop < Ships.Count; loop++)
                            {
                                for (int loop2 = 0; loop2 < Ships[loop].ShipPSensor.Count; loop2++)
                                {
                                    if (Ships[loop].ShipPSensor[loop2].pSensorDef.thermalOrEM == PassiveSensorType.Thermal &&
                                        Ships[loop].ShipPSensor[loop2].isDestroyed == false)
                                    {
                                        if (BestThermalCount == 0 || Ships[loop].ShipPSensor[loop2].pSensorDef.rating > BestThermal.pSensorDef.rating)
                                        {
                                            BestThermal = Ships[loop].ShipPSensor[loop2];
                                            BestThermalCount = 1;
                                        }
                                        else if (Ships[loop].ShipPSensor[loop2].pSensorDef.rating == BestThermal.pSensorDef.rating)
                                        {
                                            BestThermalCount++;
                                        }
                                    }

                                }
                            }
                        }
                    }
                }
            }

            /// <summary>
            /// Now on to the detection linked lists. Ship must be removed, and the lists must be altered to reflect the fact that ship is gone.
            /// </summary>
            ThermalSortList.Remove(Ship.ThermalList);
            EMSortList.Remove(Ship.EMList);
            ActiveSortList.Remove(Ship.ActiveList);

            if (ThermalSortList.Count == 0 || EMSortList.Count == 0 || ActiveSortList.Count == 0)
                return true;

            LinkedListNode<int> node;

            node = ThermalSortList.First;

            if (node.Value > Ship.ThermalList.Value)
                node.Value--;

            bool done = false;
            if (ThermalSortList.First == ThermalSortList.Last)
                done = true;

            while (done == false)
            {
                node = node.Next;

                if (node.Value > Ship.ThermalList.Value)
                    node.Value--;

                if (node == ThermalSortList.Last)
                    done = true;

            }

            node = EMSortList.First;

            if (node.Value > Ship.EMList.Value)
                node.Value--;

            done = false;
            if (EMSortList.First == EMSortList.Last)
                done = true;

            while (done == false)
            {
                node = node.Next;

                if (node.Value > Ship.EMList.Value)
                    node.Value--;

                if (node == EMSortList.Last)
                    done = true;

            }

            node = ActiveSortList.First;

            if (node.Value > Ship.ActiveList.Value)
                node.Value--;

            done = false;
            if (ActiveSortList.First == ActiveSortList.Last)
                done = true;

            while (done == false)
            {
                node = node.Next;

                if (node.Value > Ship.ActiveList.Value)
                    node.Value--;

                if (node == ActiveSortList.Last)
                    done = true;

            }

            /// <summary>
            /// Let the UI know it should re check this taskgroup's sensors. SimEntity can call just this function by itself for ship destruction. while ship transfers call this
            /// as part of another function. So SensorUpdateTick can be set twice. this shouldn't cause any issues.
            /// </summary>
            SensorUpdateAck++;

            return false;
        }
Example #22
0
        public void testShip()
        {
            Faction newFaction = new Faction(0);

            /// <summary>
            /// These would go into a faction component list I think
            /// </summary>
            EngineDefTN EngDef = new EngineDefTN("25 EP Nuclear Thermal Engine", 5, 1.0f, 1.0f, 1.0f, 1, 5, -1.0f);
            ActiveSensorDefTN ActDef = new ActiveSensorDefTN("Search 5M - 5000", 1.0f, 10, 5, 100, false, 1.0f, 1);
            PassiveSensorDefTN ThPasDef = new PassiveSensorDefTN("Thermal Sensor TH1-5", 1.0f, 5, PassiveSensorType.Thermal, 1.0f, 1);
            PassiveSensorDefTN EMPasDef = new PassiveSensorDefTN("EM Sensor EM1-5", 1.0f, 5, PassiveSensorType.EM, 1.0f, 1);

            GeneralComponentDefTN CrewQ = new GeneralComponentDefTN("Crew Quarters", 1.0f, 0, 10.0m, ComponentTypeTN.Crew);
            GeneralComponentDefTN FuelT = new GeneralComponentDefTN("Fuel Storage", 1.0f, 0, 10.0m, ComponentTypeTN.Fuel);
            GeneralComponentDefTN EBay = new GeneralComponentDefTN("Engineering Spaces", 1.0f, 5, 10.0m, ComponentTypeTN.Engineering);
            GeneralComponentDefTN Bridge = new GeneralComponentDefTN("Bridge", 1.0f, 5, 10.0m, ComponentTypeTN.Bridge);

            ShipClassTN TestClass = new ShipClassTN("Test Ship Class", newFaction);

            TestClass.AddCrewQuarters(CrewQ, 2);
            TestClass.AddFuelStorage(FuelT, 2);
            TestClass.AddEngineeringSpaces(EBay, 2);
            TestClass.AddOtherComponent(Bridge, 1);

            TestClass.AddEngine(EngDef, 1);

            TestClass.AddPassiveSensor(ThPasDef, 1);
            TestClass.AddPassiveSensor(EMPasDef, 1);

            TestClass.AddActiveSensor(ActDef, 1);

            Console.WriteLine("Size: {0}, Crew: {1}, Cost: {2}, HTK: {3}, Tonnage: {4}", TestClass.SizeHS, TestClass.TotalRequiredCrew, TestClass.BuildPointCost, TestClass.TotalHTK, TestClass.SizeTons);

            Console.WriteLine("HS Accomodations/Required: {0}/{1}, Total Fuel Capacity: {2}, Total MSP: {3}, Engineering percentage: {4}, Has Bridge: {5}, Total Required Crew: {6}", TestClass.AccomHSAvailable, TestClass.AccomHSRequirement,
            TestClass.TotalFuelCapacity, TestClass.TotalMSPCapacity, (TestClass.EngineeringHS / TestClass.SizeHS), TestClass.HasBridge, TestClass.TotalRequiredCrew);

            Console.WriteLine("Armor Size: {0}, Cost: {1}", TestClass.ShipArmorDef.size, TestClass.ShipArmorDef.cost);

            Console.WriteLine("Ship Engine Power: {0}, Ship Thermal Signature: {1}, Ship Fuel Use Per Hour: {2}", TestClass.MaxEnginePower, TestClass.MaxThermalSignature, TestClass.MaxFuelUsePerHour);

            Console.WriteLine("Best TH: {0}, BestEM: {1}, Max EM Signature: {2}, Total Cross Section: {3}", TestClass.BestThermalRating, TestClass.BestEMRating, TestClass.MaxEMSignature, TestClass.TotalCrossSection);

            TestClass.AddCrewQuarters(CrewQ, -1);

            Console.WriteLine("Size: {0}, Crew: {1}, Cost: {2}, HTK: {3}, Tonnage: {4}", TestClass.SizeHS, TestClass.TotalRequiredCrew, TestClass.BuildPointCost, TestClass.TotalHTK, TestClass.SizeTons);

            Console.WriteLine("HS Accomodations/Required: {0}/{1}, Total Fuel Capacity: {2}, Total MSP: {3}, Engineering percentage: {4}, Has Bridge: {5}, Total Required Crew: {6}", TestClass.AccomHSAvailable, TestClass.AccomHSRequirement,
            TestClass.TotalFuelCapacity, TestClass.TotalMSPCapacity, (TestClass.EngineeringHS / TestClass.SizeHS), TestClass.HasBridge, TestClass.TotalRequiredCrew);

            Console.WriteLine("Armor Size: {0}, Cost: {1}", TestClass.ShipArmorDef.size, TestClass.ShipArmorDef.cost);

            Console.WriteLine("Ship Engine Power: {0}, Ship Thermal Signature: {1}, Ship Fuel Use Per Hour: {2}", TestClass.MaxEnginePower, TestClass.MaxThermalSignature, TestClass.MaxFuelUsePerHour);

            Console.WriteLine("Best TH: {0}, BestEM: {1}, Max EM Signature: {2}, Total Cross Section: {3}", TestClass.BestThermalRating, TestClass.BestEMRating, TestClass.MaxEMSignature, TestClass.TotalCrossSection);

            TestClass.AddCrewQuarters(CrewQ, -1);

            Console.WriteLine("Size: {0}, Crew: {1}, Cost: {2}, HTK: {3}, Tonnage: {4}", TestClass.SizeHS, TestClass.TotalRequiredCrew, TestClass.BuildPointCost, TestClass.TotalHTK, TestClass.SizeTons);

            Console.WriteLine("HS Accomodations/Required: {0}/{1}, Total Fuel Capacity: {2}, Total MSP: {3}, Engineering percentage: {4}, Has Bridge: {5}, Total Required Crew: {6}", TestClass.AccomHSAvailable, TestClass.AccomHSRequirement,
            TestClass.TotalFuelCapacity, TestClass.TotalMSPCapacity, (TestClass.EngineeringHS / TestClass.SizeHS), TestClass.HasBridge, TestClass.TotalRequiredCrew);

            Console.WriteLine("Armor Size: {0}, Cost: {1}", TestClass.ShipArmorDef.size, TestClass.ShipArmorDef.cost);

            Console.WriteLine("Ship Engine Power: {0}, Ship Thermal Signature: {1}, Ship Fuel Use Per Hour: {2}", TestClass.MaxEnginePower, TestClass.MaxThermalSignature, TestClass.MaxFuelUsePerHour);

            Console.WriteLine("Best TH: {0}, BestEM: {1}, Max EM Signature: {2}, Total Cross Section: {3}", TestClass.BestThermalRating, TestClass.BestEMRating, TestClass.MaxEMSignature, TestClass.TotalCrossSection);


            TestClass.AddCrewQuarters(CrewQ, 2);

            StarSystem System1 = SystemGen.CreateSol();

            SystemBody pl1 = new SystemBody(System1.Stars[0], SystemBody.PlanetType.Terrestrial);
            System1.Stars[0].Planets.Add(pl1);

            TaskGroupTN newTG = new TaskGroupTN("TG", newFaction, System1.Stars[0].Planets[0], System1);


            ShipTN testShip = new ShipTN(TestClass, 0, 0, newTG, newFaction, "Test Ship");

            testShip.CrewQuarters[0].isDestroyed = true;

            for (int loop = 0; loop < testShip.CrewQuarters.Count; loop++)
            {
                Console.WriteLine("Crew Quarters {0} isDestroyed:{1}", loop + 1, testShip.CrewQuarters[loop].isDestroyed);
            }

            testShip.CrewQuarters[0].isDestroyed = false;

            Console.WriteLine("Engine Power/Fuel Usage/Thermal Signature/Speed: {0}/{1}/{2}/{3}", testShip.CurrentEnginePower, testShip.CurrentFuelUsePerHour, testShip.CurrentThermalSignature,
                testShip.CurrentSpeed);

            testShip.SetSpeed(1000);

            Console.WriteLine("Engine Power/Fuel Usage/Thermal Signature/Speed: {0}/{1}/{2}/{3}", testShip.CurrentEnginePower, testShip.CurrentFuelUsePerHour, testShip.CurrentThermalSignature,
                testShip.CurrentSpeed);

            Console.WriteLine("Current Crew/Fuel/MSP: {0}/{1}/{2}", testShip.CurrentCrew, testShip.CurrentFuel, testShip.CurrentMSP);

            int CrewSource = 100000;
            float FuelSource = 100000.0f;
            int MSPSource = 100000;

            CrewSource = testShip.Recrew(CrewSource);
            FuelSource = testShip.Refuel(FuelSource);
            MSPSource = testShip.Resupply(MSPSource);

            Console.WriteLine("Current Crew/Fuel/MSP: {0}/{1}/{2} Source: {3}/{4}/{5}", testShip.CurrentCrew, testShip.CurrentFuel, testShip.CurrentMSP, CrewSource, FuelSource, MSPSource);

            Console.WriteLine("Current EM Signature: {0}", testShip.CurrentEMSignature);


            bool isActive = true;
            testShip.SetSensor(testShip.ShipASensor[0], isActive);

            Console.WriteLine("Current EM Signature: {0}", testShip.CurrentEMSignature);

            isActive = false;
            testShip.SetSpeed(1500);
            testShip.SetSensor(testShip.ShipASensor[0], isActive);

            Console.WriteLine("Engine Power/Fuel Usage/Thermal Signature/Speed: {0}/{1}/{2}/{3}", testShip.CurrentEnginePower, testShip.CurrentFuelUsePerHour, testShip.CurrentThermalSignature,
                testShip.CurrentSpeed);
            Console.WriteLine("Current EM Signature: {0}", testShip.CurrentEMSignature);


        }
Example #23
0
        /// <summary>
        /// Handles adding a new FC to the list.
        /// </summary>
        /// <param name="Comp">Fire control component to add</param>
        /// <param name="Ship">Ship the FC is on.</param>
        /// <param name="Type">Type of FC.</param>
        public void AddComponent(ComponentTN Comp, ShipTN Ship, bool Type)
        {
            if (PointDefenseFC.ContainsKey(Comp) == false)
            {
                PointDefenseFC.Add(Comp, Ship);
            }

            if (PointDefenseType.ContainsKey(Comp) == false)
            {
                PointDefenseType.Add(Comp, Type);
            }
        }