Ejemplo n.º 1
0
        //have to add new entry for GL Circle to draw sensor bubbles around taskgroups/populations/missile contacts
        //CircleElement has the circle in it already, but that might be inappropriate for what I want
        //SceenElement has the lable properly done.

        public SensorElement(GLEffect a_oDefaultEffect, Vector3 a_oPosition, float a_fRadius, System.Drawing.Color a_oColor, String LabelText, GameEntity Ent, ComponentTypeTN SType, Sceen ParentSceenArg)
            : base()
        {
            _ParentSceen = ParentSceenArg;

            _DisplayRadius = a_fRadius;

            m_oPrimaryPrimitive = new GLCircle(a_oDefaultEffect,
                                               a_oPosition,
                                               a_fRadius,
                                               a_oColor,
                                               UIConstants.Textures.DEFAULT_TEXTURE);

            m_lPrimitives.Add(m_oPrimaryPrimitive);

            int     LabelMid = LabelText.Length / 4;
            float   xAdjust  = -LabelMid * (UIConstants.DEFAULT_TEXT_SIZE.X / _ParentSceen.ZoomSclaer);
            float   yAdjust  = 10.0f / ParentSceenArg.ZoomSclaer;
            Vector3 LPos     = new Vector3(xAdjust, (a_fRadius + yAdjust), 0.0f);

            LPos       = LPos + a_oPosition;
            Lable      = new GLUtilities.GLFont(a_oDefaultEffect, LPos, UIConstants.DEFAULT_TEXT_SIZE, a_oColor, UIConstants.Textures.DEFAULT_GLFONT2, LabelText);
            Lable.Size = UIConstants.DEFAULT_TEXT_SIZE / ParentSceenArg.ZoomSclaer;
            SetActualPosition(a_oPosition);

            SceenEntity = Ent;
            _SensorType = SType;
        }
Ejemplo n.º 2
0
        //have to add new entry for GL Circle to draw sensor bubbles around taskgroups/populations/missile contacts
        //CircleElement has the circle in it already, but that might be inappropriate for what I want
        //SceenElement has the lable properly done.

        public SensorElement(GLEffect a_oDefaultEffect, Vector3 a_oPosition, float a_fRadius, System.Drawing.Color a_oColor, String LabelText, GameEntity Ent,  ComponentTypeTN SType, Sceen ParentSceenArg)
            : base()
        {
            _ParentSceen = ParentSceenArg;

            _DisplayRadius = a_fRadius;

            m_oPrimaryPrimitive = new GLCircle(a_oDefaultEffect,
                        a_oPosition,
                        a_fRadius,
                        a_oColor,
                        UIConstants.Textures.DEFAULT_TEXTURE);

            m_lPrimitives.Add(m_oPrimaryPrimitive);

            int LabelMid = LabelText.Length / 4;
            float xAdjust = -LabelMid * (UIConstants.DEFAULT_TEXT_SIZE.X / _ParentSceen.ZoomSclaer);
            float yAdjust = 10.0f / ParentSceenArg.ZoomSclaer;
            Vector3 LPos = new Vector3(xAdjust, (a_fRadius + yAdjust), 0.0f);
            LPos = LPos + a_oPosition;
            Lable = new GLUtilities.GLFont(a_oDefaultEffect, LPos, UIConstants.DEFAULT_TEXT_SIZE, a_oColor, UIConstants.Textures.DEFAULT_GLFONT2, LabelText);
            Lable.Size = UIConstants.DEFAULT_TEXT_SIZE / ParentSceenArg.ZoomSclaer;
            SetActualPosition(a_oPosition);

            SceenEntity = Ent;
            _SensorType = SType;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// ShieldDefTN is the constructor for both regular shield definitions, and absorption shield definitions.
        /// </summary>
        /// <param name="ShieldName">Name of the shield.</param>
        /// <param name="StrTech">Strength/Absorption strength tech level.</param>
        /// <param name="RegenTech">Regeneration/Radiation tech level.</param>
        /// <param name="FuelCon">Fuel consumption modifier: 1.0-0.1</param>
        /// <param name="HS">Size. Regular Shields are always 1 HS, absorption shields may be up to 1000 HS in size(only 1 per ship however.)</param>
        /// <param name="TypeOfShield">Shield or AbsorptionShield only please.</param>
        public ShieldDefTN(string ShieldName, int StrTech, int RegenTech, float FuelCon, float HS, ComponentTypeTN TypeOfShield)
        {
            Id = Guid.NewGuid();
            componentType = TypeOfShield;

            ShieldStrength = StrTech;
            ShieldRegen = RegenTech;
            FuelConsumptionMod = FuelCon;

            Name = ShieldName;
            size = HS;

            if (TypeOfShield == ComponentTypeTN.Shield)
            {
                crew = 1;
                htk = 1;
                cost = 4 + Constants.ShieldTN.CostBase[ShieldStrength] + Constants.ShieldTN.CostBase[ShieldRegen];

                ShieldPool = Constants.ShieldTN.ShieldBase[ShieldStrength];
                ShieldGen = Constants.ShieldTN.ShieldBase[ShieldRegen];
                ShieldGenPerTick = ShieldGen / 60.0f;
            }
            else if (TypeOfShield == ComponentTypeTN.AbsorptionShield)
            {
                crew = 3;
                htk = (byte)Math.Round(size / 4.0f);

                ShieldPool = Constants.ShieldTN.ShieldBase[ShieldStrength] * 3.0f * size;
                ShieldGen = Constants.ShieldTN.ShieldBase[ShieldRegen] * 0.5f * size;
                ShieldGenPerTick = ShieldGen / 12.0f;

                cost = (decimal)((2.0f * ShieldGen) + (2.0f * ShieldPool));
            }

            minerialsCost = new decimal[Constants.Minerals.NO_OF_MINERIALS];
            for (int mineralIterator = 0; mineralIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; mineralIterator++)
            {
                minerialsCost[mineralIterator] = 0;
            }
            minerialsCost[(int)Constants.Minerals.MinerialNames.Duranium] = cost * 0.25m;
            minerialsCost[(int)Constants.Minerals.MinerialNames.Corbomite] = cost * 0.375m;
            minerialsCost[(int)Constants.Minerals.MinerialNames.Boronide] = cost * 0.375m;

            FuelCostPerHour = 10.0f * ShieldPool * FuelConsumptionMod;

            isMilitary = true;
            isObsolete = false;
            isSalvaged = false;
            isDivisible = false;
            isElectronic = false;

        }
Ejemplo n.º 4
0
        /// <summary>
        /// ShieldDefTN is the constructor for both regular shield definitions, and absorption shield definitions.
        /// </summary>
        /// <param name="ShieldName">Name of the shield.</param>
        /// <param name="StrTech">Strength/Absorption strength tech level.</param>
        /// <param name="RegenTech">Regeneration/Radiation tech level.</param>
        /// <param name="FuelCon">Fuel consumption modifier: 1.0-0.1</param>
        /// <param name="HS">Size. Regular Shields are always 1 HS, absorption shields may be up to 1000 HS in size(only 1 per ship however.)</param>
        /// <param name="TypeOfShield">Shield or AbsorptionShield only please.</param>
        public ShieldDefTN(string ShieldName, int StrTech, int RegenTech, float FuelCon, float HS, ComponentTypeTN TypeOfShield)
        {
            Id            = Guid.NewGuid();
            componentType = TypeOfShield;

            ShieldStrength     = StrTech;
            ShieldRegen        = RegenTech;
            FuelConsumptionMod = FuelCon;

            Name = ShieldName;
            size = HS;

            if (TypeOfShield == ComponentTypeTN.Shield)
            {
                crew = 1;
                htk  = 1;
                cost = 4 + Constants.ShieldTN.CostBase[ShieldStrength] + Constants.ShieldTN.CostBase[ShieldRegen];

                ShieldPool       = Constants.ShieldTN.ShieldBase[ShieldStrength];
                ShieldGen        = Constants.ShieldTN.ShieldBase[ShieldRegen];
                ShieldGenPerTick = ShieldGen / 60.0f;
            }
            else if (TypeOfShield == ComponentTypeTN.AbsorptionShield)
            {
                crew = 3;
                htk  = (byte)Math.Round(size / 4.0f);

                ShieldPool       = Constants.ShieldTN.ShieldBase[ShieldStrength] * 3.0f * size;
                ShieldGen        = Constants.ShieldTN.ShieldBase[ShieldRegen] * 0.5f * size;
                ShieldGenPerTick = ShieldGen / 12.0f;

                cost = (decimal)((2.0f * ShieldGen) + (2.0f * ShieldPool));
            }

            minerialsCost = new decimal[Constants.Minerals.NO_OF_MINERIALS];
            for (int mineralIterator = 0; mineralIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; mineralIterator++)
            {
                minerialsCost[mineralIterator] = 0;
            }
            minerialsCost[(int)Constants.Minerals.MinerialNames.Duranium]  = cost * 0.25m;
            minerialsCost[(int)Constants.Minerals.MinerialNames.Corbomite] = cost * 0.375m;
            minerialsCost[(int)Constants.Minerals.MinerialNames.Boronide]  = cost * 0.375m;

            FuelCostPerHour = 10.0f * ShieldPool * FuelConsumptionMod;

            isMilitary   = true;
            isObsolete   = false;
            isSalvaged   = false;
            isDivisible  = false;
            isElectronic = false;
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Constructor for all beam weapon types.
        /// </summary>
        /// <param name="Title">Name of the beam weapon, user entered string, or default string.</param>
        /// <param name="Type">What type of beam weapon this is, note that componentTypeTN encompasses much more than beam weapon types, don't give those values to this function.</param>
        /// <param name="SizeTech">Every beam weapon either has a calibre size, except for particle beams, which use warhead strength, and gauss which give a rate of fire. All use this variable.</param>
        /// <param name="RangeTech">Every beam weapon has a range tech except for plasma carronades which do not have any way to increase range or decrease damage falloff.</param>
        /// <param name="CapacitorTech">Every beam weapon has a capacitor tech associated with it except gauss. Shotcount tech for gauss.</param>
        /// <param name="Reduction">Lasers and Gauss both have size reduction capabilities, though with drawbacks for both types: recharge rate and accuracy respectively.</param>
        public BeamDefTN(String Title, ComponentTypeTN Type, byte SizeTech, byte RangeTech, byte CapacitorTech, float Reduction, MountType MType = MountType.Standard)
        {
#warning function has beam weapon range related magic numbers and others
            if (Type < ComponentTypeTN.Rail || Type > ComponentTypeTN.AdvParticle)
            {
                /// <summary>
                /// Error, bad ID passed to BeamDefTN.
                /// </summary>
                return;
            }
            Id = Guid.NewGuid();
            componentType = Type;

            Name = Title;
            m_oWeaponSizeTech = SizeTech;
            m_oWeaponRangeTech = RangeTech;
            m_oWeaponCapacitorTech = CapacitorTech;
            m_oWeaponCapacitor = Constants.BeamWeaponTN.Capacitor[CapacitorTech];
            m_oWMType = MType;

            m_oShotCount = 1;
            m_oBaseAccuracy = 1.0f;

            m_lDamage = new BindingList<ushort>();

            int RangeIncrement;

            switch (componentType)
            {
                /// <summary>
                /// Laser is the the most basic jack of all trade beam weapon.
                /// </summary>
                case ComponentTypeTN.Laser:

                    /// <summary>
                    /// I Suspect that size is 3.2cm per HS but am just using a table for now.
                    /// </summary>
                    size = (float)Math.Round(Constants.BeamWeaponTN.LaserSize[m_oWeaponSizeTech] * Reduction);

                    /// <summary>
                    /// The first entry in the damage table is max damage at point blank(0-10k range) damage.
                    /// </summary>
                    m_lDamage.Add((ushort)Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech]);

                    /// <summary>
                    /// Have to modify capacitor by size reduction values.
                    /// </summary>
                    if (Reduction == 0.75f)
                        m_oWeaponCapacitor = m_oWeaponCapacitor / 4.0f;
                    else if (Reduction == 0.5f)
                        m_oWeaponCapacitor = m_oWeaponCapacitor / 20.0f;

                    /// <summary>
                    /// Damage, Size, and Range are all modified by spinal mounting:
                    /// </summary>
                    switch (m_oWMType)
                    {
                        case MountType.Spinal:
                            size = (float)Math.Round(size * 1.25f);
                            m_lDamage[0] = (ushort)Math.Round((float)m_lDamage[0] * 1.5f);
                            break;
                        case MountType.AdvancedSpinal:
                            size = (float)Math.Round(size * 1.5f);
                            m_lDamage[0] = (ushort)Math.Round((float)m_lDamage[0] * 2.0f);
                            break;
                    }

                    /// <summary>
                    /// Lasers have the longest range of all beam weapons due to their high damage, normal 10,000km factor and weapon range tech.
                    /// </summary>
                    m_oRange = (float)m_lDamage[0] * 10000.0f * (float)(m_oWeaponRangeTech + 1);

                    /// <summary>
                    /// Lasers require 1 unit of power for every unit of damage that they do.
                    /// </summary>
                    m_oPowerRequirement = m_lDamage[0];

                    /// <summary>
                    /// Subsequent entries up to Wavelength * 10k do full damage, after that the value is:
                    /// FullDamage * ( Wavelength / RangeIncrement Tick) with a minimum of 1 over range.
                    /// </summary>
                    /// 
                    RangeIncrement = (m_oWeaponRangeTech + 1) * m_lDamage[0];
                    CalcDamageTable(RangeIncrement);

                    m_oDamageType = DamageTypeTN.Beam;
                    break;

                case ComponentTypeTN.AdvLaser:
                    size = (float)Math.Round(Constants.BeamWeaponTN.LaserSize[m_oWeaponSizeTech] * Reduction);
                    m_lDamage.Add((ushort)Constants.BeamWeaponTN.AdvancedLaserDamage[m_oWeaponSizeTech]);

                    /// <summary>
                    /// Advanced lasers do more damage per unit of power than regular lasers.
                    /// </summary>
                    m_oPowerRequirement = Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech];

                    /// <summary>
                    /// Have to modify capacitor by size reduction values.
                    /// </summary>
                    if (Reduction == 0.75f)
                        m_oWeaponCapacitor = m_oWeaponCapacitor / 4.0f;
                    else if (Reduction == 0.5f)
                        m_oWeaponCapacitor = m_oWeaponCapacitor / 20.0f;

                    /// <summary>
                    /// Damage, Size, and Range are all modified by spinal mounting:
                    /// </summary>
                    switch (MType)
                    {
                        case MountType.Spinal:
                            size = (float)Math.Round(size * 1.25f);
                            m_lDamage[0] = (ushort)Math.Round((float)m_lDamage[0] * 1.5f);
                            m_oPowerRequirement = (ushort)Math.Round((float)m_oPowerRequirement * 1.5f);
                            break;
                        case MountType.AdvancedSpinal:
                            size = (float)Math.Round(size * 1.5f);
                            m_lDamage[0] = (ushort)Math.Round((float)m_lDamage[0] * 2.0f);
                            m_oPowerRequirement = (ushort)Math.Round((float)m_oPowerRequirement * 2.0f);
                            break;
                    }

                    m_oRange = (float)m_lDamage[0] * 10000.0f * (float)(m_oWeaponRangeTech + 1);

                    RangeIncrement = (m_oWeaponRangeTech + 1) * m_lDamage[0];
                    CalcDamageTable(RangeIncrement);

                    m_oDamageType = DamageTypeTN.Beam;
                    break;

                /// <summary>
                /// Plasmas are essentially cheaper infared lasers.
                /// </summary>
                case ComponentTypeTN.Plasma:
                    m_oWeaponRangeTech = 0;

                    /// <summary>
                    /// I Suspect that size is 3.2cm per HS but am just using a table for now. No reductions for plasma.
                    /// </summary>
                    size = (float)Constants.BeamWeaponTN.LaserSize[m_oWeaponSizeTech];

                    /// <summary>
                    /// Plasma carronades have the same range as an infared laser of equal size.
                    /// </summary>
                    m_oRange = (float)Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech] * 10000.0f * (float)(m_oWeaponRangeTech + 1);

                    /// <summary>
                    /// The first entry in the damage table is max damage at point blank(0-10k range) damage.
                    /// </summary>
                    m_lDamage.Add((ushort)Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech]);

                    /// <summary>
                    /// Plasmas require 1 unit of power for every unit of damage that they do.
                    /// </summary>
                    m_oPowerRequirement = m_lDamage[0];

                    /// <summary>
                    /// Subsequent entries up to Wavelength * 10k do full damage, after that the value is:
                    /// FullDamage * ( Wavelength / RangeIncrement Tick) with a minimum of 1 over range.
                    /// </summary>
                    /// 
                    RangeIncrement = (m_oWeaponRangeTech + 1) * Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech];
                    CalcDamageTable(RangeIncrement);

                    m_oDamageType = DamageTypeTN.Plasma;
                    break;

                case ComponentTypeTN.AdvPlasma:
                    m_oWeaponRangeTech = 0;
                    size = (float)Constants.BeamWeaponTN.LaserSize[m_oWeaponSizeTech];
                    m_oRange = (float)Constants.BeamWeaponTN.AdvancedLaserDamage[m_oWeaponSizeTech] * 10000.0f * (float)(m_oWeaponRangeTech + 1);
                    m_lDamage.Add((ushort)Constants.BeamWeaponTN.AdvancedLaserDamage[m_oWeaponSizeTech]);
                    m_oPowerRequirement = (ushort)Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech];
                    RangeIncrement = (m_oWeaponRangeTech + 1) * Constants.BeamWeaponTN.AdvancedLaserDamage[m_oWeaponSizeTech];
                    CalcDamageTable(RangeIncrement);

                    m_oDamageType = DamageTypeTN.Plasma;
                    break;

                /// <summary>
                /// Railguns have a higher damage than lasers of equal size, though it is spread out over many hits.
                /// Likewise railguns are not suitable for turrets, lastly railguns don't have the full tech progression that lasers have.
                /// Railguns and especially advanced railguns are also power efficient as far as the damage that they do.
                /// </summary>
                case ComponentTypeTN.Rail:
                    m_oShotCount = 4;

                    size = (float)Constants.BeamWeaponTN.RailGunSize[m_oWeaponSizeTech];
                    m_oRange = (float)Constants.BeamWeaponTN.RailGunDamage[m_oWeaponSizeTech] * 10000.0f * (m_oWeaponRangeTech + 1);
                    m_lDamage.Add((ushort)Constants.BeamWeaponTN.RailGunDamage[m_oWeaponSizeTech]);
                    m_oPowerRequirement = (ushort)(Constants.BeamWeaponTN.RailGunDamage[m_oWeaponSizeTech] * 3);
                    RangeIncrement = (m_oWeaponRangeTech + 1) * Constants.BeamWeaponTN.RailGunDamage[m_oWeaponSizeTech];
                    CalcDamageTable(RangeIncrement);

                    m_oDamageType = DamageTypeTN.Kinetic;
                    break;

                /// <summary>
                /// Only difference here is 1 more shot.
                /// </summary>
                case ComponentTypeTN.AdvRail:
                    m_oShotCount = 5;

                    size = (float)Constants.BeamWeaponTN.RailGunSize[m_oWeaponSizeTech];
                    m_oRange = (float)Constants.BeamWeaponTN.RailGunDamage[m_oWeaponSizeTech] * 10000.0f * (m_oWeaponRangeTech + 1);
                    m_lDamage.Add((ushort)Constants.BeamWeaponTN.RailGunDamage[m_oWeaponSizeTech]);
                    m_oPowerRequirement = (ushort)(Constants.BeamWeaponTN.RailGunDamage[m_oWeaponSizeTech] * 3);
                    RangeIncrement = (m_oWeaponRangeTech + 1) * Constants.BeamWeaponTN.RailGunDamage[m_oWeaponSizeTech];
                    CalcDamageTable(RangeIncrement);

                    m_oDamageType = DamageTypeTN.Kinetic;
                    break;

                /// <summary>
                /// Mesons have half the range that lasers have, and only do 1 damage, but always pass through armor and shields.
                /// </summary>
                case ComponentTypeTN.Meson:

                    size = (float)Constants.BeamWeaponTN.LaserSize[m_oWeaponSizeTech];
                    m_oRange = (float)Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech] * 5000.0f * (float)(m_oWeaponRangeTech + 1);

                    m_lDamage.Add(1);
                    m_oPowerRequirement = (ushort)Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech];
                    RangeIncrement = (((m_oWeaponRangeTech + 1) * Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech]) / 2);
                    for (int loop = 1; loop < RangeIncrement; loop++)
                    {
                        m_lDamage.Add(1);
                    }
                    m_lDamage.Add(0);

                    m_oDamageType = DamageTypeTN.Meson;
                    break;

                /// <summary>
                /// Microwaves do electronic only damage, though they do triple against shields. this isn't very useful though as they don't do triple normal laser damage vs shields, just 3.
                /// They share 1/2 range with mesons, but can't be turreted.
                /// </summary>
                case ComponentTypeTN.Microwave:

                    size = (float)Constants.BeamWeaponTN.LaserSize[m_oWeaponSizeTech];
                    m_oRange = (float)Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech] * 5000.0f * (float)(m_oWeaponRangeTech + 1);

                    m_lDamage.Add(1);
                    m_oPowerRequirement = (ushort)Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech];

                    RangeIncrement = (((m_oWeaponRangeTech + 1) * Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech]) / 2);
                    for (int loop = 1; loop < RangeIncrement; loop++)
                    {
                        m_lDamage.Add(1);
                    }
                    m_lDamage.Add(0);

                    m_oDamageType = DamageTypeTN.Microwave;
                    break;

                /// <summary>
                /// Particle Beams suffer no range dissipation so will out damage lasers at their maximum range, but are shorter ranged than lasers.
                /// WeaponSizeTech for particle beams is their warhead strength, not any focal lense size as with lasers.
                /// </summary>
                case ComponentTypeTN.Particle:

                    size = (float)Constants.BeamWeaponTN.ParticleSize[m_oWeaponSizeTech];
                    m_oRange = (float)Constants.BeamWeaponTN.ParticleRange[m_oWeaponRangeTech] * 10000.0f;
                    m_oPowerRequirement = (ushort)Constants.BeamWeaponTN.ParticlePower[m_oWeaponSizeTech];

                    m_lDamage.Add(Constants.BeamWeaponTN.ParticleDamage[m_oWeaponSizeTech]);
                    RangeIncrement = Constants.BeamWeaponTN.ParticleRange[m_oWeaponRangeTech];
                    for (int loop = 1; loop < RangeIncrement; loop++)
                    {
                        m_lDamage.Add(Constants.BeamWeaponTN.ParticleDamage[m_oWeaponSizeTech]);
                    }
                    m_lDamage.Add(0);

                    m_oDamageType = DamageTypeTN.Kinetic;
                    break;

                /// <summary>
                /// More damage is the only change for advanced particle beams.
                /// </summary>
                case ComponentTypeTN.AdvParticle:

                    size = (float)Constants.BeamWeaponTN.ParticleSize[m_oWeaponSizeTech];
                    m_oRange = (float)Constants.BeamWeaponTN.ParticleRange[m_oWeaponRangeTech] * 10000.0f;
                    m_oPowerRequirement = (ushort)Constants.BeamWeaponTN.ParticlePower[m_oWeaponSizeTech];

                    m_lDamage.Add(Constants.BeamWeaponTN.AdvancedParticleDamage[m_oWeaponSizeTech]);
                    RangeIncrement = Constants.BeamWeaponTN.ParticleRange[m_oWeaponRangeTech];
                    for (int loop = 1; loop < RangeIncrement; loop++)
                    {
                        m_lDamage.Add(Constants.BeamWeaponTN.AdvancedParticleDamage[m_oWeaponSizeTech]);
                    }
                    m_lDamage.Add(0);

                    m_oDamageType = DamageTypeTN.Kinetic;
                    break;

                /// <summary>
                /// Gauss Cannons differ substantially from other beam weapons. Size is determined directly from a size vs accuracy choice.
                /// Likewise capacitor refers to shotcount rather than any capacitor technology.
                /// </summary>
                case ComponentTypeTN.Gauss:
                    size = Constants.BeamWeaponTN.GaussSize[m_oWeaponSizeTech];
                    m_oRange = (m_oWeaponRangeTech + 1) * 10000.0f;
                    m_oShotCount = Constants.BeamWeaponTN.GaussShots[CapacitorTech];
                    m_oBaseAccuracy = Constants.BeamWeaponTN.GaussAccuracy[m_oWeaponSizeTech];
                    m_oPowerRequirement = 0;
                    m_lDamage.Add(1);
                    RangeIncrement = (m_oWeaponRangeTech + 1);
                    for (int loop = 1; loop < RangeIncrement; loop++)
                    {
                        m_lDamage.Add(1);
                    }
                    m_lDamage.Add(0);

                    m_oDamageType = DamageTypeTN.Kinetic;
                    break;
            }

            /// <summary>
            /// Gauss cannons just have to be different.
            /// </summary>
            if (componentType != ComponentTypeTN.Gauss)
            {
                htk = (byte)(size / 2.0f);
                crew = (byte)(size * 2.0f);

                /// <summary>
                /// This isn't how aurora does cost, I couldn't quite figure that out. seems like it might be a table.
                /// well in any event cost is simply the hit to kill * weapon tech level + 1 * weapon capacitor tech level + 1.
                /// </summary>
                cost = (decimal)((int)htk * (int)(m_oWeaponRangeTech + 1) * (int)(m_oWeaponCapacitor + 1));

                m_oROF = (ushort)((ushort)Math.Ceiling((float)((float)m_oPowerRequirement / (float)m_oWeaponCapacitor)) * 5);
            }
            else
            {
                /// <summary>
                /// Gauss data here.
                /// </summary>
                if (size == 6.0 || size == 5.0 || size == 4.0)
                    htk = 2;
                else if (size >= 1.0)
                    htk = 1;
                else
                    htk = 0;

                crew = (byte)(size * 2.0f);
                cost = (decimal)((size * 2.0f) * (float)(m_oWeaponRangeTech + 1) * (float)(m_oWeaponCapacitor + 1));

                m_oROF = 5;
            }

            minerialsCost = new decimal[Constants.Minerals.NO_OF_MINERIALS];
            for (int mineralIterator = 0; mineralIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; mineralIterator++)
            {
                minerialsCost[mineralIterator] = 0;
            }
            switch (componentType)
            {
                case ComponentTypeTN.Laser:
                case ComponentTypeTN.AdvLaser:
                case ComponentTypeTN.Plasma:
                case ComponentTypeTN.AdvPlasma:
                case ComponentTypeTN.Particle:
                case ComponentTypeTN.AdvParticle:
                case ComponentTypeTN.Meson:
                case ComponentTypeTN.Microwave: //20%D 20%B 60%C
                    minerialsCost[(int)Constants.Minerals.MinerialNames.Duranium] = cost * 0.2m;
                    minerialsCost[(int)Constants.Minerals.MinerialNames.Boronide] = cost * 0.2m;
                    minerialsCost[(int)Constants.Minerals.MinerialNames.Corundium] = cost * 0.6m;
                    break;

                case ComponentTypeTN.Rail:
                case ComponentTypeTN.AdvRail: //20%D 20%B 60%N
                    minerialsCost[(int)Constants.Minerals.MinerialNames.Duranium] = cost * 0.2m;
                    minerialsCost[(int)Constants.Minerals.MinerialNames.Boronide] = cost * 0.2m;
                    minerialsCost[(int)Constants.Minerals.MinerialNames.Neutronium] = cost * 0.6m;
                    break;

                case ComponentTypeTN.Gauss: //100%V
                    minerialsCost[(int)Constants.Minerals.MinerialNames.Vendarite] = cost;
                    break;
            }


            isMilitary = true;
            isObsolete = false;
            isDivisible = false;
            isSalvaged = false;
            isElectronic = false;
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Constructor for all beam weapon types.
        /// </summary>
        /// <param name="Title">Name of the beam weapon, user entered string, or default string.</param>
        /// <param name="Type">What type of beam weapon this is, note that componentTypeTN encompasses much more than beam weapon types, don't give those values to this function.</param>
        /// <param name="SizeTech">Every beam weapon either has a calibre size, except for particle beams, which use warhead strength, and gauss which give a rate of fire. All use this variable.</param>
        /// <param name="RangeTech">Every beam weapon has a range tech except for plasma carronades which do not have any way to increase range or decrease damage falloff.</param>
        /// <param name="CapacitorTech">Every beam weapon has a capacitor tech associated with it except gauss. Shotcount tech for gauss.</param>
        /// <param name="Reduction">Lasers and Gauss both have size reduction capabilities, though with drawbacks for both types: recharge rate and accuracy respectively.</param>
        public BeamDefTN(String Title, ComponentTypeTN Type, byte SizeTech, byte RangeTech, byte CapacitorTech, float Reduction, MountType MType = MountType.Standard)
        {
#warning function has beam weapon range related magic numbers and others
            if (Type < ComponentTypeTN.Rail || Type > ComponentTypeTN.AdvParticle)
            {
                /// <summary>
                /// Error, bad ID passed to BeamDefTN.
                /// </summary>
                return;
            }
            Id            = Guid.NewGuid();
            componentType = Type;

            Name = Title;
            m_oWeaponSizeTech      = SizeTech;
            m_oWeaponRangeTech     = RangeTech;
            m_oWeaponCapacitorTech = CapacitorTech;
            m_oWeaponCapacitor     = Constants.BeamWeaponTN.Capacitor[CapacitorTech];
            m_oWMType = MType;

            m_oShotCount    = 1;
            m_oBaseAccuracy = 1.0f;

            m_lDamage = new BindingList <ushort>();

            int RangeIncrement;

            switch (componentType)
            {
            /// <summary>
            /// Laser is the the most basic jack of all trade beam weapon.
            /// </summary>
            case ComponentTypeTN.Laser:

                /// <summary>
                /// I Suspect that size is 3.2cm per HS but am just using a table for now.
                /// </summary>
                size = (float)Math.Round(Constants.BeamWeaponTN.LaserSize[m_oWeaponSizeTech] * Reduction);

                /// <summary>
                /// The first entry in the damage table is max damage at point blank(0-10k range) damage.
                /// </summary>
                m_lDamage.Add((ushort)Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech]);

                /// <summary>
                /// Have to modify capacitor by size reduction values.
                /// </summary>
                if (Reduction == 0.75f)
                {
                    m_oWeaponCapacitor = m_oWeaponCapacitor / 4.0f;
                }
                else if (Reduction == 0.5f)
                {
                    m_oWeaponCapacitor = m_oWeaponCapacitor / 20.0f;
                }

                /// <summary>
                /// Damage, Size, and Range are all modified by spinal mounting:
                /// </summary>
                switch (m_oWMType)
                {
                case MountType.Spinal:
                    size         = (float)Math.Round(size * 1.25f);
                    m_lDamage[0] = (ushort)Math.Round((float)m_lDamage[0] * 1.5f);
                    break;

                case MountType.AdvancedSpinal:
                    size         = (float)Math.Round(size * 1.5f);
                    m_lDamage[0] = (ushort)Math.Round((float)m_lDamage[0] * 2.0f);
                    break;
                }

                /// <summary>
                /// Lasers have the longest range of all beam weapons due to their high damage, normal 10,000km factor and weapon range tech.
                /// </summary>
                m_oRange = (float)m_lDamage[0] * 10000.0f * (float)(m_oWeaponRangeTech + 1);

                /// <summary>
                /// Lasers require 1 unit of power for every unit of damage that they do.
                /// </summary>
                m_oPowerRequirement = m_lDamage[0];

                /// <summary>
                /// Subsequent entries up to Wavelength * 10k do full damage, after that the value is:
                /// FullDamage * ( Wavelength / RangeIncrement Tick) with a minimum of 1 over range.
                /// </summary>
                ///
                RangeIncrement = (m_oWeaponRangeTech + 1) * m_lDamage[0];
                CalcDamageTable(RangeIncrement);

                m_oDamageType = DamageTypeTN.Beam;
                break;

            case ComponentTypeTN.AdvLaser:
                size = (float)Math.Round(Constants.BeamWeaponTN.LaserSize[m_oWeaponSizeTech] * Reduction);
                m_lDamage.Add((ushort)Constants.BeamWeaponTN.AdvancedLaserDamage[m_oWeaponSizeTech]);

                /// <summary>
                /// Advanced lasers do more damage per unit of power than regular lasers.
                /// </summary>
                m_oPowerRequirement = Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech];

                /// <summary>
                /// Have to modify capacitor by size reduction values.
                /// </summary>
                if (Reduction == 0.75f)
                {
                    m_oWeaponCapacitor = m_oWeaponCapacitor / 4.0f;
                }
                else if (Reduction == 0.5f)
                {
                    m_oWeaponCapacitor = m_oWeaponCapacitor / 20.0f;
                }

                /// <summary>
                /// Damage, Size, and Range are all modified by spinal mounting:
                /// </summary>
                switch (MType)
                {
                case MountType.Spinal:
                    size                = (float)Math.Round(size * 1.25f);
                    m_lDamage[0]        = (ushort)Math.Round((float)m_lDamage[0] * 1.5f);
                    m_oPowerRequirement = (ushort)Math.Round((float)m_oPowerRequirement * 1.5f);
                    break;

                case MountType.AdvancedSpinal:
                    size                = (float)Math.Round(size * 1.5f);
                    m_lDamage[0]        = (ushort)Math.Round((float)m_lDamage[0] * 2.0f);
                    m_oPowerRequirement = (ushort)Math.Round((float)m_oPowerRequirement * 2.0f);
                    break;
                }

                m_oRange = (float)m_lDamage[0] * 10000.0f * (float)(m_oWeaponRangeTech + 1);

                RangeIncrement = (m_oWeaponRangeTech + 1) * m_lDamage[0];
                CalcDamageTable(RangeIncrement);

                m_oDamageType = DamageTypeTN.Beam;
                break;

            /// <summary>
            /// Plasmas are essentially cheaper infared lasers.
            /// </summary>
            case ComponentTypeTN.Plasma:
                m_oWeaponRangeTech = 0;

                /// <summary>
                /// I Suspect that size is 3.2cm per HS but am just using a table for now. No reductions for plasma.
                /// </summary>
                size = (float)Constants.BeamWeaponTN.LaserSize[m_oWeaponSizeTech];

                /// <summary>
                /// Plasma carronades have the same range as an infared laser of equal size.
                /// </summary>
                m_oRange = (float)Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech] * 10000.0f * (float)(m_oWeaponRangeTech + 1);

                /// <summary>
                /// The first entry in the damage table is max damage at point blank(0-10k range) damage.
                /// </summary>
                m_lDamage.Add((ushort)Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech]);

                /// <summary>
                /// Plasmas require 1 unit of power for every unit of damage that they do.
                /// </summary>
                m_oPowerRequirement = m_lDamage[0];

                /// <summary>
                /// Subsequent entries up to Wavelength * 10k do full damage, after that the value is:
                /// FullDamage * ( Wavelength / RangeIncrement Tick) with a minimum of 1 over range.
                /// </summary>
                ///
                RangeIncrement = (m_oWeaponRangeTech + 1) * Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech];
                CalcDamageTable(RangeIncrement);

                m_oDamageType = DamageTypeTN.Plasma;
                break;

            case ComponentTypeTN.AdvPlasma:
                m_oWeaponRangeTech = 0;
                size     = (float)Constants.BeamWeaponTN.LaserSize[m_oWeaponSizeTech];
                m_oRange = (float)Constants.BeamWeaponTN.AdvancedLaserDamage[m_oWeaponSizeTech] * 10000.0f * (float)(m_oWeaponRangeTech + 1);
                m_lDamage.Add((ushort)Constants.BeamWeaponTN.AdvancedLaserDamage[m_oWeaponSizeTech]);
                m_oPowerRequirement = (ushort)Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech];
                RangeIncrement      = (m_oWeaponRangeTech + 1) * Constants.BeamWeaponTN.AdvancedLaserDamage[m_oWeaponSizeTech];
                CalcDamageTable(RangeIncrement);

                m_oDamageType = DamageTypeTN.Plasma;
                break;

            /// <summary>
            /// Railguns have a higher damage than lasers of equal size, though it is spread out over many hits.
            /// Likewise railguns are not suitable for turrets, lastly railguns don't have the full tech progression that lasers have.
            /// Railguns and especially advanced railguns are also power efficient as far as the damage that they do.
            /// </summary>
            case ComponentTypeTN.Rail:
                m_oShotCount = 4;

                size     = (float)Constants.BeamWeaponTN.RailGunSize[m_oWeaponSizeTech];
                m_oRange = (float)Constants.BeamWeaponTN.RailGunDamage[m_oWeaponSizeTech] * 10000.0f * (m_oWeaponRangeTech + 1);
                m_lDamage.Add((ushort)Constants.BeamWeaponTN.RailGunDamage[m_oWeaponSizeTech]);
                m_oPowerRequirement = (ushort)(Constants.BeamWeaponTN.RailGunDamage[m_oWeaponSizeTech] * 3);
                RangeIncrement      = (m_oWeaponRangeTech + 1) * Constants.BeamWeaponTN.RailGunDamage[m_oWeaponSizeTech];
                CalcDamageTable(RangeIncrement);

                m_oDamageType = DamageTypeTN.Kinetic;
                break;

            /// <summary>
            /// Only difference here is 1 more shot.
            /// </summary>
            case ComponentTypeTN.AdvRail:
                m_oShotCount = 5;

                size     = (float)Constants.BeamWeaponTN.RailGunSize[m_oWeaponSizeTech];
                m_oRange = (float)Constants.BeamWeaponTN.RailGunDamage[m_oWeaponSizeTech] * 10000.0f * (m_oWeaponRangeTech + 1);
                m_lDamage.Add((ushort)Constants.BeamWeaponTN.RailGunDamage[m_oWeaponSizeTech]);
                m_oPowerRequirement = (ushort)(Constants.BeamWeaponTN.RailGunDamage[m_oWeaponSizeTech] * 3);
                RangeIncrement      = (m_oWeaponRangeTech + 1) * Constants.BeamWeaponTN.RailGunDamage[m_oWeaponSizeTech];
                CalcDamageTable(RangeIncrement);

                m_oDamageType = DamageTypeTN.Kinetic;
                break;

            /// <summary>
            /// Mesons have half the range that lasers have, and only do 1 damage, but always pass through armor and shields.
            /// </summary>
            case ComponentTypeTN.Meson:

                size     = (float)Constants.BeamWeaponTN.LaserSize[m_oWeaponSizeTech];
                m_oRange = (float)Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech] * 5000.0f * (float)(m_oWeaponRangeTech + 1);

                m_lDamage.Add(1);
                m_oPowerRequirement = (ushort)Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech];
                RangeIncrement      = (((m_oWeaponRangeTech + 1) * Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech]) / 2);
                for (int loop = 1; loop < RangeIncrement; loop++)
                {
                    m_lDamage.Add(1);
                }
                m_lDamage.Add(0);

                m_oDamageType = DamageTypeTN.Meson;
                break;

            /// <summary>
            /// Microwaves do electronic only damage, though they do triple against shields. this isn't very useful though as they don't do triple normal laser damage vs shields, just 3.
            /// They share 1/2 range with mesons, but can't be turreted.
            /// </summary>
            case ComponentTypeTN.Microwave:

                size     = (float)Constants.BeamWeaponTN.LaserSize[m_oWeaponSizeTech];
                m_oRange = (float)Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech] * 5000.0f * (float)(m_oWeaponRangeTech + 1);

                m_lDamage.Add(1);
                m_oPowerRequirement = (ushort)Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech];

                RangeIncrement = (((m_oWeaponRangeTech + 1) * Constants.BeamWeaponTN.LaserDamage[m_oWeaponSizeTech]) / 2);
                for (int loop = 1; loop < RangeIncrement; loop++)
                {
                    m_lDamage.Add(1);
                }
                m_lDamage.Add(0);

                m_oDamageType = DamageTypeTN.Microwave;
                break;

            /// <summary>
            /// Particle Beams suffer no range dissipation so will out damage lasers at their maximum range, but are shorter ranged than lasers.
            /// WeaponSizeTech for particle beams is their warhead strength, not any focal lense size as with lasers.
            /// </summary>
            case ComponentTypeTN.Particle:

                size                = (float)Constants.BeamWeaponTN.ParticleSize[m_oWeaponSizeTech];
                m_oRange            = (float)Constants.BeamWeaponTN.ParticleRange[m_oWeaponRangeTech] * 10000.0f;
                m_oPowerRequirement = (ushort)Constants.BeamWeaponTN.ParticlePower[m_oWeaponSizeTech];

                m_lDamage.Add(Constants.BeamWeaponTN.ParticleDamage[m_oWeaponSizeTech]);
                RangeIncrement = Constants.BeamWeaponTN.ParticleRange[m_oWeaponRangeTech];
                for (int loop = 1; loop < RangeIncrement; loop++)
                {
                    m_lDamage.Add(Constants.BeamWeaponTN.ParticleDamage[m_oWeaponSizeTech]);
                }
                m_lDamage.Add(0);

                m_oDamageType = DamageTypeTN.Kinetic;
                break;

            /// <summary>
            /// More damage is the only change for advanced particle beams.
            /// </summary>
            case ComponentTypeTN.AdvParticle:

                size                = (float)Constants.BeamWeaponTN.ParticleSize[m_oWeaponSizeTech];
                m_oRange            = (float)Constants.BeamWeaponTN.ParticleRange[m_oWeaponRangeTech] * 10000.0f;
                m_oPowerRequirement = (ushort)Constants.BeamWeaponTN.ParticlePower[m_oWeaponSizeTech];

                m_lDamage.Add(Constants.BeamWeaponTN.AdvancedParticleDamage[m_oWeaponSizeTech]);
                RangeIncrement = Constants.BeamWeaponTN.ParticleRange[m_oWeaponRangeTech];
                for (int loop = 1; loop < RangeIncrement; loop++)
                {
                    m_lDamage.Add(Constants.BeamWeaponTN.AdvancedParticleDamage[m_oWeaponSizeTech]);
                }
                m_lDamage.Add(0);

                m_oDamageType = DamageTypeTN.Kinetic;
                break;

            /// <summary>
            /// Gauss Cannons differ substantially from other beam weapons. Size is determined directly from a size vs accuracy choice.
            /// Likewise capacitor refers to shotcount rather than any capacitor technology.
            /// </summary>
            case ComponentTypeTN.Gauss:
                size                = Constants.BeamWeaponTN.GaussSize[m_oWeaponSizeTech];
                m_oRange            = (m_oWeaponRangeTech + 1) * 10000.0f;
                m_oShotCount        = Constants.BeamWeaponTN.GaussShots[CapacitorTech];
                m_oBaseAccuracy     = Constants.BeamWeaponTN.GaussAccuracy[m_oWeaponSizeTech];
                m_oPowerRequirement = 0;
                m_lDamage.Add(1);
                RangeIncrement = (m_oWeaponRangeTech + 1);
                for (int loop = 1; loop < RangeIncrement; loop++)
                {
                    m_lDamage.Add(1);
                }
                m_lDamage.Add(0);

                m_oDamageType = DamageTypeTN.Kinetic;
                break;
            }

            /// <summary>
            /// Gauss cannons just have to be different.
            /// </summary>
            if (componentType != ComponentTypeTN.Gauss)
            {
                htk  = (byte)(size / 2.0f);
                crew = (byte)(size * 2.0f);

                /// <summary>
                /// This isn't how aurora does cost, I couldn't quite figure that out. seems like it might be a table.
                /// well in any event cost is simply the hit to kill * weapon tech level + 1 * weapon capacitor tech level + 1.
                /// </summary>
                cost = (decimal)((int)htk * (int)(m_oWeaponRangeTech + 1) * (int)(m_oWeaponCapacitor + 1));

                m_oROF = (ushort)((ushort)Math.Ceiling((float)((float)m_oPowerRequirement / (float)m_oWeaponCapacitor)) * 5);
            }
            else
            {
                /// <summary>
                /// Gauss data here.
                /// </summary>
                if (size == 6.0 || size == 5.0 || size == 4.0)
                {
                    htk = 2;
                }
                else if (size >= 1.0)
                {
                    htk = 1;
                }
                else
                {
                    htk = 0;
                }

                crew = (byte)(size * 2.0f);
                cost = (decimal)((size * 2.0f) * (float)(m_oWeaponRangeTech + 1) * (float)(m_oWeaponCapacitor + 1));

                m_oROF = 5;
            }

            minerialsCost = new decimal[Constants.Minerals.NO_OF_MINERIALS];
            for (int mineralIterator = 0; mineralIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; mineralIterator++)
            {
                minerialsCost[mineralIterator] = 0;
            }
            switch (componentType)
            {
            case ComponentTypeTN.Laser:
            case ComponentTypeTN.AdvLaser:
            case ComponentTypeTN.Plasma:
            case ComponentTypeTN.AdvPlasma:
            case ComponentTypeTN.Particle:
            case ComponentTypeTN.AdvParticle:
            case ComponentTypeTN.Meson:
            case ComponentTypeTN.Microwave:     //20%D 20%B 60%C
                minerialsCost[(int)Constants.Minerals.MinerialNames.Duranium]  = cost * 0.2m;
                minerialsCost[(int)Constants.Minerals.MinerialNames.Boronide]  = cost * 0.2m;
                minerialsCost[(int)Constants.Minerals.MinerialNames.Corundium] = cost * 0.6m;
                break;

            case ComponentTypeTN.Rail:
            case ComponentTypeTN.AdvRail:     //20%D 20%B 60%N
                minerialsCost[(int)Constants.Minerals.MinerialNames.Duranium]   = cost * 0.2m;
                minerialsCost[(int)Constants.Minerals.MinerialNames.Boronide]   = cost * 0.2m;
                minerialsCost[(int)Constants.Minerals.MinerialNames.Neutronium] = cost * 0.6m;
                break;

            case ComponentTypeTN.Gauss:     //100%V
                minerialsCost[(int)Constants.Minerals.MinerialNames.Vendarite] = cost;
                break;
            }


            isMilitary   = true;
            isObsolete   = false;
            isDivisible  = false;
            isSalvaged   = false;
            isElectronic = false;
        }
        /// <summary>
        /// Initializes this basic component.
        /// </summary>
        /// <param name="Title">Name which will be displayed to the user, they don't choose the names of these particular components however.</param>
        /// <param name="ComponentSize">Size of the component. this will determine crew capacity, fuel capacity, engineering percentage, and htk in addition to being merely size.</param>
        /// <param name="ComponentCrew">Crew requirement of the component, fuel tanks won't require any, orbital habitats will require a lot.</param>
        /// <param name="ComponentCost">Cost requirement of the component, mineral costs have yet to be done though those are just a percentage of total cost.</param>
        /// <param name="GeneralComponentType">What type of component is this? see the enum in ComponentTN.cs for a list.</param>
        public GeneralComponentDefTN(string Title, float ComponentSize, byte ComponentCrew, decimal ComponentCost, ComponentTypeTN GeneralComponentType)
        {
            Id = Guid.NewGuid();

            Name          = Title;
            size          = ComponentSize;
            crew          = ComponentCrew;
            cost          = ComponentCost;
            componentType = GeneralComponentType;

            minerialsCost = new decimal[Constants.Minerals.NO_OF_MINERIALS];
            for (int mineralIterator = 0; mineralIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; mineralIterator++)
            {
                minerialsCost[mineralIterator] = 0;
            }

            switch (componentType)
            {
            case ComponentTypeTN.Crew:     //25% Duranium 75% Mercassium
                minerialsCost[(int)Constants.Minerals.MinerialNames.Duranium]   = cost * 0.25m;
                minerialsCost[(int)Constants.Minerals.MinerialNames.Mercassium] = cost * 0.75m;
                break;

            case ComponentTypeTN.Fuel:     //50% Duranium 50% Boronide
                minerialsCost[(int)Constants.Minerals.MinerialNames.Duranium] = cost * 0.50m;
                minerialsCost[(int)Constants.Minerals.MinerialNames.Boronide] = cost * 0.50m;
                break;

            case ComponentTypeTN.Engineering:     //100% Duranium
                minerialsCost[(int)Constants.Minerals.MinerialNames.Duranium] = cost;
                break;

            case ComponentTypeTN.Bridge:          //50% Duranium, 50% corbomite
                minerialsCost[(int)Constants.Minerals.MinerialNames.Duranium]  = cost * 0.50m;
                minerialsCost[(int)Constants.Minerals.MinerialNames.Corbomite] = cost * 0.50m;
                break;
                //case ComponentTypeTN.FlagBridge: 50% corbomite, 50% Uridium
                //case ComponentTypeTN.MaintenanceBay: 50% Duranium, 50% Neutronium
                //case ComponentTypeTN.OrbitalHabitat: 25% Duranium, 25% Boronide, 50% Mercassium
                //case ComponentTypeTN.RecFacility: 20% Duranium, 20% Tritanium, 60% Boronide
                //case ComponentTypeTN.DamageControl: 50% Duranium, 25% Neutronium, 25% Uridium
            }

            isDivisible = false;

            if (componentType <= ComponentTypeTN.MaintenanceBay)
            {
                if (size < 1.0f)
                {
                    htk = 0;
                }
                else
                {
                    htk = 1;
                }
            }
            else if (componentType == ComponentTypeTN.FlagBridge || componentType == ComponentTypeTN.DamageControl)
            {
                htk = 2;
            }
            else if (componentType == ComponentTypeTN.OrbitalHabitat || componentType == ComponentTypeTN.RecFacility)
            {
                htk         = 25;
                isDivisible = true;
            }

            isMilitary   = false;
            isObsolete   = false;
            isSalvaged   = false;
            isElectronic = false;
        }
Ejemplo n.º 8
0
        /// <summary>
        /// This function returns the cost of repairing the specified component based on the data given to the damage control queue.
        /// </summary>
        /// <param name="ID">Id of component in general ship component list.</param>
        /// <param name="CType">type of component.</param>
        /// <returns>cost of said component.</returns>
        public decimal GetDamagedComponentsRepairCost(int ID, ComponentTypeTN CType)
        {
            switch (CType)
            {
                case ComponentTypeTN.Crew:
                       return CrewQuarters[ShipComponents[ID].componentIndex].genCompDef.cost;

                case ComponentTypeTN.Fuel:
                    return FuelTanks[ShipComponents[ID].componentIndex].genCompDef.cost;

                case ComponentTypeTN.Engineering:
                    return EngineeringBays[ShipComponents[ID].componentIndex].genCompDef.cost;

                case ComponentTypeTN.Bridge:
                case ComponentTypeTN.MaintenanceBay:
                case ComponentTypeTN.FlagBridge:
                case ComponentTypeTN.DamageControl:
                case ComponentTypeTN.OrbitalHabitat:
                case ComponentTypeTN.RecFacility:
                    return OtherComponents[ShipComponents[ID].componentIndex].genCompDef.cost;

                case ComponentTypeTN.Engine:
                    /// <summary>
                    /// All engines have to be the same, so engine 0 is used for these for convienience.
                    /// </summary>
                    return ShipEngine[0].engineDef.cost;

                case ComponentTypeTN.PassiveSensor:
                    return ShipPSensor[ShipComponents[ID].componentIndex].pSensorDef.cost;

                case ComponentTypeTN.ActiveSensor:
                    return ShipASensor[ShipComponents[ID].componentIndex].aSensorDef.cost;

                case ComponentTypeTN.CargoHold:
                    return ShipCargo[ShipComponents[ID].componentIndex].cargoDef.cost;

                case ComponentTypeTN.CargoHandlingSystem:
                    return ShipCHS[ShipComponents[ID].componentIndex].cargoHandleDef.cost;

                case ComponentTypeTN.CryoStorage:
                    return ShipColony[ShipComponents[ID].componentIndex].colonyDef.cost;

                case ComponentTypeTN.BeamFireControl:
                    return ShipBFC[ShipComponents[ID].componentIndex].beamFireControlDef.cost;

                case ComponentTypeTN.Rail:
                case ComponentTypeTN.Gauss:
                case ComponentTypeTN.Plasma:
                case ComponentTypeTN.Laser:
                case ComponentTypeTN.Meson:
                case ComponentTypeTN.Microwave:
                case ComponentTypeTN.Particle:
                case ComponentTypeTN.AdvRail:
                case ComponentTypeTN.AdvLaser:
                case ComponentTypeTN.AdvPlasma:
                case ComponentTypeTN.AdvParticle:
                    return ShipBeam[ShipComponents[ID].componentIndex].beamDef.cost;


                case ComponentTypeTN.Reactor:
                    return ShipReactor[ShipComponents[ID].componentIndex].reactorDef.cost;

                case ComponentTypeTN.Shield:
                    return ShipShield[ShipComponents[ID].componentIndex].shieldDef.cost;

                case ComponentTypeTN.AbsorptionShield:
                    return ShipShield[ShipComponents[ID].componentIndex].shieldDef.cost;

                case ComponentTypeTN.MissileLauncher:
                    return ShipMLaunchers[ShipComponents[ID].componentIndex].missileLauncherDef.cost;

                case ComponentTypeTN.Magazine:
                    return ShipMagazines[ShipComponents[ID].componentIndex].magazineDef.cost;

                case ComponentTypeTN.MissileFireControl:
                    return ShipMFC[ShipComponents[ID].componentIndex].mFCSensorDef.cost;

                case ComponentTypeTN.CIWS:
                    return ShipCIWS[ShipComponents[ID].componentIndex].cIWSDef.cost;

                case ComponentTypeTN.Turret:
                    return ShipTurret[ShipComponents[ID].componentIndex].turretDef.cost;

                case ComponentTypeTN.JumpEngine:
                    return ShipJumpEngine[ShipComponents[ID].componentIndex].jumpEngineDef.cost;
            }

            return 0.0m;
        }
Ejemplo n.º 9
0
        public void RepairComponent(ComponentTypeTN Type, int ComponentIndex)
        {
            /// <summary>
            /// Subtract MSPs in damage control function, not necessary here.
            /// </summary>

            ShipComponents[ComponentIndex].isDestroyed = false;
            DestroyedComponents.Remove((ushort)ComponentIndex);

            switch (Type)
            {
                case ComponentTypeTN.Crew:
                    SpareBerths = SpareBerths + (int)(CrewQuarters[ShipComponents[ComponentIndex].componentIndex].genCompDef.size / ShipClass.TonsPerMan);
                    break;

                case ComponentTypeTN.Fuel:
                    CurrentFuelCapacity = CurrentFuelCapacity + (FuelTanks[ShipComponents[ComponentIndex].componentIndex].genCompDef.size * 50000.0f);
                    break;

                case ComponentTypeTN.Engineering:
                    float MSP = EngineeringBays[ShipComponents[ComponentIndex].componentIndex].genCompDef.size;
                    CurrentMSPCapacity = CurrentMSPCapacity + (int)((float)ShipClass.BuildPointCost * ((MSP / ShipClass.SizeHS) / 0.08f));
                    CurrentDamageControlRating = CurrentDamageControlRating + 1;
                    break;

                /// <summary>
                /// Nothing special is done for these yet.
                /// </summary>
                case ComponentTypeTN.Bridge:
                    break;
                case ComponentTypeTN.MaintenanceBay:
                    break;
                case ComponentTypeTN.FlagBridge:
                    break;
                case ComponentTypeTN.DamageControl:
                    break;
                case ComponentTypeTN.OrbitalHabitat:
                    break;
                case ComponentTypeTN.RecFacility:
                    break;

                case ComponentTypeTN.Engine:
                    /// <summary>
                    /// All engines have to be the same, so engine 0 is used for these for convienience.
                    /// </summary>
                    CurrentMaxEnginePower = CurrentMaxEnginePower + (int)Math.Round(ShipEngine[0].engineDef.enginePower);
                    CurrentMaxThermalSignature = CurrentMaxThermalSignature + (int)Math.Round(ShipEngine[0].engineDef.thermalSignature);
                    CurrentMaxFuelUsePerHour = CurrentMaxFuelUsePerHour + ShipEngine[0].engineDef.fuelUsePerHour;

                    if (CurrentMaxEnginePower == 0)
                    {
                        /// <summary>
                        /// This is a very bad error I think.
                        /// hopefully it should never happen.
                        /// </summary>
                        CurrentMaxSpeed = 1;
                        CurrentMaxThermalSignature = 1;
#if LOG4NET_ENABLED
#warning faction messagelog this?
                        logger.Debug("CurrentMaxEnginePower was 0 AFTER engine repair. oops. see Ship.cs RepairComponent()");
#endif
                    }
                    else
                        CurrentMaxSpeed = (int)((1000.0f / (float)ShipClass.TotalCrossSection) * (float)CurrentMaxEnginePower);

                    int speedMin = 0;
                    for (int loop = 0; loop < ShipsTaskGroup.Ships.Count; loop++)
                    {
                        if (ShipsTaskGroup.Ships[loop].CurrentMaxSpeed > speedMin)
                            speedMin = CurrentMaxSpeed;
                    }

                    int oldThermal = CurrentThermalSignature;

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

                    if (oldThermal != CurrentThermalSignature)
                        ShipsTaskGroup.SortShipBySignature(ThermalList, ShipsTaskGroup.ThermalSortList, 0);

                    break;
                case ComponentTypeTN.PassiveSensor:
                    if (ShipPSensor[ShipComponents[ComponentIndex].componentIndex].pSensorDef.thermalOrEM == PassiveSensorType.EM)
                    {
                        if (ShipPSensor[ShipComponents[ComponentIndex].componentIndex].pSensorDef.rating > ShipsTaskGroup.BestEM.pSensorDef.rating)
                        {
                            ShipsTaskGroup.BestEM = ShipPSensor[ShipComponents[ComponentIndex].componentIndex];
                            ShipsTaskGroup.BestEMCount = 1;
                        }
                        else if (ShipPSensor[ShipComponents[ComponentIndex].componentIndex].pSensorDef.rating == ShipsTaskGroup.BestEM.pSensorDef.rating)
                        {
                            ShipsTaskGroup.BestEMCount++;
                        }
                    }
                    else
                    {
                        if (ShipPSensor[ShipComponents[ComponentIndex].componentIndex].pSensorDef.rating > ShipsTaskGroup.BestThermal.pSensorDef.rating)
                        {
                            ShipsTaskGroup.BestThermal = ShipPSensor[ShipComponents[ComponentIndex].componentIndex];
                            ShipsTaskGroup.BestThermalCount = 1;
                        }
                        else if (ShipPSensor[ShipComponents[ComponentIndex].componentIndex].pSensorDef.rating == ShipsTaskGroup.BestThermal.pSensorDef.rating)
                        {
                            ShipsTaskGroup.BestThermalCount++;
                        }
                    }
                    break;

                /// <summary>
                /// Nothing special for these yet.
                /// </summary>
                case ComponentTypeTN.ActiveSensor:
                    break;
                case ComponentTypeTN.CargoHold:
                    break;

                case ComponentTypeTN.CargoHandlingSystem:
                    CurrentTractorMultiplier = CurrentTractorMultiplier + ShipCHS[ShipComponents[ComponentIndex].componentIndex].cargoHandleDef.tractorMultiplier;
                    break;

                /// <summary>
                /// Nothing special for these yet. Weapon links won't be restored.
                /// </summary>
                case ComponentTypeTN.CryoStorage:
                    break;
                case ComponentTypeTN.BeamFireControl:
                    break;
                case ComponentTypeTN.Rail:
                case ComponentTypeTN.Gauss:
                case ComponentTypeTN.Plasma:
                case ComponentTypeTN.Laser:
                case ComponentTypeTN.Meson:
                case ComponentTypeTN.Microwave:
                case ComponentTypeTN.Particle:
                case ComponentTypeTN.AdvRail:
                case ComponentTypeTN.AdvLaser:
                case ComponentTypeTN.AdvPlasma:
                case ComponentTypeTN.AdvParticle:
                    break;

                case ComponentTypeTN.Reactor:
                    CurrentPowerGen = CurrentPowerGen + (int)(Math.Round(ShipReactor[ShipComponents[ComponentIndex].componentIndex].reactorDef.powerGen));
                    break;

                /// <summary>
                /// For shields I will preserve ShieldIsActive as is, but set the other values up on component repair.
                /// </summary.
                case ComponentTypeTN.Shield:
                    CurrentShieldPoolMax = CurrentShieldPoolMax + ShipShield[ShipComponents[ComponentIndex].componentIndex].shieldDef.shieldPool;
                    CurrentShieldGen = CurrentShieldGen + ShipShield[ShipComponents[ComponentIndex].componentIndex].shieldDef.shieldGenPerTick;
                    CurrentShieldFuelUse = CurrentShieldFuelUse + (ShipShield[ShipComponents[ComponentIndex].componentIndex].shieldDef.fuelCostPerHour / 720.0f);

                    if (ShieldIsActive == true)
                    {
                        CurrentEMSignature = CurrentEMSignature + (int)(ShipShield[ShipComponents[ComponentIndex].componentIndex].shieldDef.shieldPool * 30.0f);
                        ShipsTaskGroup.SortShipBySignature(EMList, ShipsTaskGroup.EMSortList, 1);
                    }
                    break;

                case ComponentTypeTN.AbsorptionShield:
                    CurrentShieldPoolMax = ShipClass.TotalShieldPool;
                    CurrentShieldGen = ShipClass.TotalShieldGenPerTick;
                    CurrentShieldFuelUse = ShipClass.TotalShieldFuelCostPerTick;

                    if (ShieldIsActive == true)
                    {
                        CurrentEMSignature = CurrentEMSignature + (int)(ShipShield[ShipComponents[ComponentIndex].componentIndex].shieldDef.shieldPool * 30.0f);
                        ShipsTaskGroup.SortShipBySignature(EMList, ShipsTaskGroup.EMSortList, 1);
                    }
                    break;

                case ComponentTypeTN.MissileLauncher:
                    CurrentLauncherMagCapacityMax = CurrentLauncherMagCapacityMax + ShipMLaunchers[ShipComponents[ComponentIndex].componentIndex].missileLauncherDef.launchMaxSize;
                    CurrentMagazineCapacityMax = CurrentMagazineCapacityMax + ShipMLaunchers[ShipComponents[ComponentIndex].componentIndex].missileLauncherDef.launchMaxSize;
                    break;

                case ComponentTypeTN.Magazine:
                    CurrentMagazineMagCapacityMax = CurrentMagazineMagCapacityMax + ShipMagazines[ShipComponents[ComponentIndex].componentIndex].magazineDef.capacity;
                    CurrentMagazineCapacityMax = CurrentMagazineCapacityMax + ShipMagazines[ShipComponents[ComponentIndex].componentIndex].magazineDef.capacity;
                    break;

                case ComponentTypeTN.MissileFireControl:
                    break;

                case ComponentTypeTN.CIWS:
                    break;

                case ComponentTypeTN.Turret:
                    break;

                case ComponentTypeTN.JumpEngine:
                    break;
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Destroy component handles destroying individual components of a ship, updating the ships data, and taskgroup data as needed.
        /// crew destruction and logging remain to be done.
        /// </summary>
        /// <param name="Type">Type of component destroyed</param>
        /// <param name="ComponentListDefIndex">Where in the shipClass.ListOfComponentDefs this component resides</param>
        /// <param name="Damage">How much damage is to be applied in the attempt to destroy the component</param>
        /// <param name="ComponentIndex">Which component specifically.</param>
        /// <param name="DacRNG">Current RNG kludge</param>
        /// <returns>Damage remaining after component destruction, or special message indicating no component to destroy(-1)/ship is totally destroyed(-2)</returns>
        public int DestroyComponent(ComponentTypeTN Type, int ComponentListDefIndex, int Damage, int ComponentIndex, Random DacRNG)
        {
            if (Damage >= ShipHTK)
                return -2;

            int ID = ComponentDefIndex[ComponentListDefIndex] + ComponentIndex;

            if (ShipComponents[ID].isDestroyed == true)
            {
                return -1;
            }

            int DamageReturn = -1;

            if (ShipClass.ListOfComponentDefs[ComponentListDefIndex].htk == 0)
            {
                ShipComponents[ID].isDestroyed = true;
                DamageReturn = Damage;
            }
            else if (ShipClass.ListOfComponentDefs[ComponentListDefIndex].htk != 0)
            {
                if (ShipClass.ListOfComponentDefs[ComponentListDefIndex].htk <= Damage)
                {
                    ShipComponents[ID].isDestroyed = true;
                    DamageReturn = ShipClass.ListOfComponentDefs[ComponentListDefIndex].htk;
                }
                else
                {
                    int htkTest = DacRNG.Next(1, ShipClass.ListOfComponentDefs[ComponentListDefIndex].htk);

                    if (htkTest == ShipClass.ListOfComponentDefs[ComponentListDefIndex].htk)
                    {
                        ShipComponents[ID].isDestroyed = true;
                        DamageReturn = Damage;
                    }
                    else
                    {
                        /// <summary>
                        /// All damage was absorbed by the component without it being destroyed.
                        /// </summary>

                        DamageReturn = Damage;
                        return DamageReturn;
                    }
                }
            }

            /// <summary>
            /// Copy the component over to the destroyed components list and decrement the ships remaining HTK value.
            DestroyedComponents.Add((ushort)ID);
            DestroyedComponentsType.Add(Type);
            ShipHTK = ShipHTK - ShipClass.ListOfComponentDefs[ComponentListDefIndex].htk;

            /// <summary>
            /// Do Crew destruction here at some point.
            /// </summary>


            switch (Type)
            {
                /// <summary>
                /// To Do:
                /// put everything in the log.
                /// </summary>
                case ComponentTypeTN.Crew:
                    SpareBerths = SpareBerths - (int)(CrewQuarters[ShipComponents[ID].componentIndex].genCompDef.size / ShipClass.TonsPerMan);
                    break;

                case ComponentTypeTN.Fuel:
                    float Fuel = FuelTanks[ShipComponents[ID].componentIndex].genCompDef.size * 50000.0f;
                    float FuelPercentage = Fuel / ShipClass.TotalFuelCapacity;
                    float FuelLoss = FuelPercentage * CurrentFuel;
                    CurrentFuel = CurrentFuel - FuelLoss;
                    CurrentFuelCapacity = CurrentFuelCapacity - Fuel;
                    break;

                case ComponentTypeTN.Engineering:
                    float MSP = EngineeringBays[ShipComponents[ID].componentIndex].genCompDef.size;
                    float MSPPercentage = MSP / ShipClass.TotalMSPCapacity;
                    float MSPLoss = MSPPercentage * CurrentMSP;
                    CurrentMSP = CurrentMSP - (int)MSPLoss;
                    CurrentMSPCapacity = CurrentMSPCapacity - (int)((float)ShipClass.BuildPointCost * ((MSP / ShipClass.SizeHS) / 0.08f));
                    CurrentDamageControlRating = CurrentDamageControlRating - 1;
                    break;

                /// <summary>
                /// Nothing special for these yet.
                /// </summary>
                case ComponentTypeTN.Bridge:
                    break;
                case ComponentTypeTN.MaintenanceBay:
                    break;
                case ComponentTypeTN.FlagBridge:
                    break;
                case ComponentTypeTN.DamageControl:
                    break;
                case ComponentTypeTN.OrbitalHabitat:
                    break;
                case ComponentTypeTN.RecFacility:
                    break;

                case ComponentTypeTN.Engine:
                    /// <summary>
                    /// All engines have to be the same, so engine 0 is used for these for convienience.
                    /// </summary>
                    CurrentMaxEnginePower = CurrentMaxEnginePower - (int)Math.Round(ShipEngine[0].engineDef.enginePower);
                    CurrentMaxThermalSignature = CurrentMaxThermalSignature - (int)Math.Round(ShipEngine[0].engineDef.thermalSignature);
                    CurrentMaxFuelUsePerHour = CurrentMaxFuelUsePerHour - ShipEngine[0].engineDef.fuelUsePerHour;

                    if (CurrentMaxEnginePower != 0)
                        CurrentMaxSpeed = (int)((1000.0f / ((float)ShipClass.TotalCrossSection) * (float)CurrentMaxEnginePower));
                    else
                    {
                        CurrentMaxSpeed = 1;
                        CurrentMaxThermalSignature = 1; //it shouldn't be 0 either.
                    }

                    int oldThermal = CurrentThermalSignature;

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

                    if (oldThermal != CurrentThermalSignature)
                        ShipsTaskGroup.SortShipBySignature(ThermalList, ShipsTaskGroup.ThermalSortList, 0);

                    int ExpTest = DacRNG.Next(1, 100);

                    if (ExpTest < ShipEngine[0].engineDef.expRisk)
                    {
                        /// <summary>
                        /// *** Do secondary damage here. ***
                        /// </summary>
                        /// SecondaryExplosion(SecondaryType.Engine,ShipEngine[0].engineDef.enginePower);
                    }
                    break;

                case ComponentTypeTN.PassiveSensor:
                    /// <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 (ShipPSensor[ShipComponents[ID].componentIndex].pSensorDef.thermalOrEM == PassiveSensorType.EM)
                    {
                        if (ShipPSensor[ShipComponents[ID].componentIndex].pSensorDef.rating == ShipsTaskGroup.BestEM.pSensorDef.rating)
                        {
                            ShipsTaskGroup.BestEMCount--;

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

                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        if (ShipPSensor[ShipComponents[ID].componentIndex].pSensorDef.rating == ShipsTaskGroup.BestThermal.pSensorDef.rating)
                        {
                            ShipsTaskGroup.BestThermalCount--;

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

                                    }
                                }
                            }
                        }
                    }
                    break;
                case ComponentTypeTN.ActiveSensor:
                    /// <summary>
                    /// Luckily this function already takes care of active sensors being deactivated and removed from the sort lists.
                    /// </summary>
                    ShipsTaskGroup.SetActiveSensor(ShipsTaskGroup.Ships.IndexOf(this), ShipComponents[ID].componentIndex, false);
                    break;

                case ComponentTypeTN.CargoHold:
                    /// <summary>
                    /// Cargo should be destroyed here.
                    /// </summary>
                    break;

                case ComponentTypeTN.CargoHandlingSystem:
                    CurrentTractorMultiplier = CurrentTractorMultiplier - ShipCHS[ShipComponents[ID].componentIndex].cargoHandleDef.tractorMultiplier;
                    break;
                case ComponentTypeTN.CryoStorage:
                    /// <summary>
                    /// Colonists in stasis or lifeboat rescuees should be destroyed here.
                    /// </summary>
                    break;


                /// <summary>
                /// The fire control open fire list has to be updated.
                /// </summary>
                case ComponentTypeTN.BeamFireControl:
                    UnlinkAllWeapons(ShipBFC[ShipComponents[ID].componentIndex]);
                    ShipBFC[ShipComponents[ID].componentIndex].openFire = false;
                    if (ShipsFaction.OpenFireFC.ContainsKey(ShipComponents[ID]) == true)
                    {
                        ShipsFaction.OpenFireFC.Remove(ShipComponents[ID]);
                        ShipsFaction.OpenFireFCType.Remove(ShipComponents[ID]);
                    }
                    break;
                case ComponentTypeTN.Rail:
                case ComponentTypeTN.Gauss:
                case ComponentTypeTN.Plasma:
                case ComponentTypeTN.Laser:
                case ComponentTypeTN.Meson:
                case ComponentTypeTN.Microwave:
                case ComponentTypeTN.Particle:
                case ComponentTypeTN.AdvRail:
                case ComponentTypeTN.AdvLaser:
                case ComponentTypeTN.AdvPlasma:
                case ComponentTypeTN.AdvParticle:
                    UnlinkWeapon(ShipBeam[ShipComponents[ID].componentIndex]);
                    ShipBeam[ShipComponents[ID].componentIndex].currentCapacitor = 0;
                    break;

                case ComponentTypeTN.Reactor:

                    CurrentPowerGen = CurrentPowerGen - (int)(Math.Round(ShipReactor[ShipComponents[ID].componentIndex].reactorDef.powerGen));

                    ExpTest = DacRNG.Next(1, 100);

                    if (ExpTest < ShipReactor[ShipComponents[ID].componentIndex].reactorDef.expRisk)
                    {
                        /// <summary>
                        /// *** Do secondary damage here. ***
                        /// </summary>
                        /// SecondaryExplosion(SecondaryType.Reactor,ShipReactor[ShipComponents[ID].componentIndex].reactorDef.powerGen);
                    }
                    break;

                /// <summary>
                /// For shields I will preserve ShieldIsActive as is, but set the other values down on component destruction.
                /// </summary.
                case ComponentTypeTN.Shield:

                    CurrentShieldPoolMax = CurrentShieldPoolMax - ShipShield[ShipComponents[ID].componentIndex].shieldDef.shieldPool;
                    CurrentShieldGen = CurrentShieldGen - ShipShield[ShipComponents[ID].componentIndex].shieldDef.shieldGenPerTick;
                    CurrentShieldFuelUse = CurrentShieldFuelUse - (ShipShield[ShipComponents[ID].componentIndex].shieldDef.fuelCostPerHour / 720.0f);

                    /// <summary>
                    /// In the event of meson damage/mixed meson and non-meson damage:
                    /// </summary>
                    if (CurrentShieldPool != 0.0f && CurrentShieldPool > CurrentShieldPoolMax)
                        CurrentShieldPool = CurrentShieldPoolMax;

                    if (ShieldIsActive == true)
                    {
                        CurrentEMSignature = CurrentEMSignature - (int)(ShipShield[ShipComponents[ID].componentIndex].shieldDef.shieldPool * 30.0f);
                        ShipsTaskGroup.SortShipBySignature(EMList, ShipsTaskGroup.EMSortList, 1);
                    }
                    break;

                case ComponentTypeTN.AbsorptionShield:
                    CurrentShieldPool = 0.0f;
                    CurrentShieldPoolMax = 0.0f;
                    CurrentShieldGen = 0.0f;
                    CurrentShieldFuelUse = 0.0f;

                    if (ShieldIsActive == true)
                    {
                        CurrentEMSignature = CurrentEMSignature - (int)(ShipShield[ShipComponents[ID].componentIndex].shieldDef.shieldPool * 30.0f);
                        ShipsTaskGroup.SortShipBySignature(EMList, ShipsTaskGroup.EMSortList, 1);
                    }
                    break;

                case ComponentTypeTN.MissileLauncher:

                    /// <summary>
                    /// If the ship has loaded ordnance then figuring out which one to destroy is simple:
                    /// </summary>
                    if (ShipMLaunchers[ShipComponents[ID].componentIndex].loadedOrdnance != null)
                    {
                        if (ShipOrdnance.ContainsKey(ShipMLaunchers[ShipComponents[ID].componentIndex].loadedOrdnance) == true)
                        {

                            ShipOrdnance[ShipMLaunchers[ShipComponents[ID].componentIndex].loadedOrdnance] = ShipOrdnance[ShipMLaunchers[ShipComponents[ID].componentIndex].loadedOrdnance] - 1;

                            if (ShipOrdnance[ShipMLaunchers[ShipComponents[ID].componentIndex].loadedOrdnance] == 0)
                            {
                                ShipOrdnance.Remove(ShipMLaunchers[ShipComponents[ID].componentIndex].loadedOrdnance);
                            }
                            else if (ShipOrdnance[ShipMLaunchers[ShipComponents[ID].componentIndex].loadedOrdnance] < 0)
                            {
#if LOG4NET_ENABLED
#warning faction messagelog this?
                                String Entry = String.Format("Ship ordnance subtraction below 0 on ship {0} due to launcher destruction.", this.Name);
                                logger.Debug(Entry);
#endif
                            }
                        }
                        else
                        {
                            /// <summary>
                            /// This condition could arise because all such missiles have been fired. Check the total ship ordnance vs magazine capacity to decide if another missile should be destroyed.
                            /// </summary>

                            if (CurrentMagazineCapacity > CurrentMagazineMagCapacityMax)
                            {
                                foreach (KeyValuePair<OrdnanceDefTN, int> pair in ShipOrdnance)
                                {
                                    if (ShipOrdnance[pair.Key] > 0)
                                    {
                                        ShipOrdnance[pair.Key] = ShipOrdnance[pair.Key] - 1;

                                        if (ShipOrdnance[pair.Key] == 0)
                                        {
                                            ShipOrdnance.Remove(pair.Key);
                                        }
                                        break;
                                    }
                                    else
                                    {
#if LOG4NET_ENABLED
#warning faction messagelog this?
                                        String Entry = String.Format("Ship {0} has ship ordnance in quantities of zero from somewhere.", this.Name);
                                        logger.Debug(Entry);
#endif
                                    }
                                }
                            }
                        }

                        ShipMLaunchers[ShipComponents[ID].componentIndex].loadedOrdnance = null;
                    }
                    else
                    {
                        /// <summary>
                        /// This condition could arise because all such missiles have been fired. Check the total ship ordnance vs magazine capacity to decide if another missile should be destroyed.
                        /// This else is included twice due to paranoia over the possibility that loadedOrdnance = null
                        /// </summary>

                        if (CurrentMagazineCapacity > CurrentMagazineMagCapacityMax)
                        {
                            foreach (KeyValuePair<OrdnanceDefTN, int> pair in ShipOrdnance)
                            {
                                if (ShipOrdnance[pair.Key] > 0)
                                {
                                    ShipOrdnance[pair.Key] = ShipOrdnance[pair.Key] - 1;

                                    if (ShipOrdnance[pair.Key] == 0)
                                    {
                                        ShipOrdnance.Remove(pair.Key);
                                    }
                                    break;
                                }
                                else
                                {
#if LOG4NET_ENABLED
#warning faction messagelog this?
                                    String Entry = String.Format("Ship {0} has ship ordnance in quantities of zero from somewhere.", this.Name);
                                    logger.Debug(Entry);
#endif
                                }
                            }
                        }
                    }

                    CurrentLauncherMagCapacityMax = CurrentLauncherMagCapacityMax - ShipMLaunchers[ShipComponents[ID].componentIndex].missileLauncherDef.launchMaxSize;
                    CurrentMagazineCapacityMax = CurrentMagazineCapacityMax - ShipMLaunchers[ShipComponents[ID].componentIndex].missileLauncherDef.launchMaxSize;
                    CurrentMagazineCapacity = CurrentMagazineCapacity - (int)Math.Ceiling(ShipMLaunchers[ShipComponents[ID].componentIndex].loadedOrdnance.size);
                    ShipMLaunchers[ShipComponents[ID].componentIndex].ClearMFC();
                    break;

                case ComponentTypeTN.Magazine:
                    /// <summary>
                    /// There must be missiles in the magazines rather than all of them being in the launch tubes, or the mags could be totally empty
                    /// </summary>
                    int WarheadTotal = 0;
                    if (CurrentMagazineCapacity > CurrentLauncherMagCapacityMax)
                    {
                        /// <summary>
                        /// Total percentage of all magazine space divided by all space total on the ship for missiles(includes launch tubes).
                        /// </summary>
                        float MagPercentage = (CurrentMagazineMagCapacityMax / CurrentMagazineCapacityMax);

                        /// <summary>
                        /// Percentage of total magazine space this one magazine represents.
                        /// </summary>
                        float ThisMagPercentage = (ShipMagazines[ShipComponents[ID].componentIndex].magazineDef.capacity / CurrentMagazineMagCapacityMax) * MagPercentage;

                        /// <summary>
                        /// Counter for missiles destroyed.
                        /// </summary>
                        int TempCapTotal = 0;



                        /// <summary>
                        /// Temporary key list, will be removing these from shipordnance when done.
                        /// </summary>
                        Dictionary<OrdnanceDefTN,int> TempKeyList = new Dictionary<OrdnanceDefTN,int>();

                        /// <summary>
                        /// loop through all ordnance and determine the loadbalanced count of missiles that would be in this magazine.
                        /// if ShipOrdnance is empty, this does not run.
                        /// </summary>
                        foreach (KeyValuePair<OrdnanceDefTN, int> pair in ShipOrdnance)
                        {
                            int Total = (int)Math.Ceiling(pair.Key.size) * pair.Value;
                            int AmtInThisMag = (int)Math.Ceiling(ThisMagPercentage * Total);
                            TempCapTotal = TempCapTotal + AmtInThisMag;

                            TempKeyList.Add(pair.Key, AmtInThisMag);

                            WarheadTotal = WarheadTotal + pair.Key.warhead;

                            /// <summary>
                            /// Some mags will have a little more than total cap, and some will have a little less than total cap because of how this could work out.
                            /// </summary>
                            if (TempCapTotal >= ShipMagazines[ShipComponents[ID].componentIndex].magazineDef.capacity)
                                break;
                        }

                        /// <summary>
                        /// I have to subtract values elsewhere because it was giving me some crap about "Collection was modified; enumeration operation may not execute"
                        /// Atleast I hope this fixes the issue.
                        /// </summary>
                        if (TempKeyList.Count != 0)
                        {
                            foreach (KeyValuePair<OrdnanceDefTN,int> pair in TempKeyList)
                            {
                                ShipOrdnance[pair.Key] = ShipOrdnance[pair.Key] - pair.Value;
                                if (ShipOrdnance[pair.Key] <= 0)
                                {
                                    if (ShipOrdnance[pair.Key] < 0)
                                    {
#if LOG4NET_ENABLED
#warning faction messagelog this?
                                        logger.Debug("Ship ordnance key value inexplicably reduced below zero on magazine destruction.");
#endif
                                    }
                                    ShipOrdnance.Remove(pair.Key);
                                }
                                
                            }
                        }
                    }

                    CurrentMagazineCapacityMax = CurrentMagazineCapacityMax - ShipMagazines[ShipComponents[ID].componentIndex].magazineDef.capacity;
                    CurrentMagazineMagCapacityMax = CurrentMagazineMagCapacityMax - ShipMagazines[ShipComponents[ID].componentIndex].magazineDef.capacity;

                    ExpTest = DacRNG.Next(1, 100);

                    if (ExpTest < ShipMagazines[ShipComponents[ID].componentIndex].magazineDef.expRisk)
                    {
                        /// <summary>
                        /// *** Do secondary damage here. ***
                        /// </summary>
                        /// SecondaryExplosion(SecondaryType.Magazine,WarheadTotal);
                    }
                    break;

                case ComponentTypeTN.MissileFireControl:
                    ShipMFC[ShipComponents[ID].componentIndex].ClearAllWeapons();
                    ShipMFC[ShipComponents[ID].componentIndex].ClearAllMissiles();
                    ShipMFC[ShipComponents[ID].componentIndex].openFire = false;
                    if (ShipsFaction.OpenFireFC.ContainsKey(ShipComponents[ID]) == true)
                    {
                        ShipsFaction.OpenFireFC.Remove(ShipComponents[ID]);
                        ShipsFaction.OpenFireFCType.Remove(ShipComponents[ID]);
                    }
                    break;

                case ComponentTypeTN.CIWS:
                    /// <summary>
                    /// Do nothing for CIWS.
                    /// </summary>
                    break;

                case ComponentTypeTN.Turret:
                    UnlinkWeapon(ShipTurret[ShipComponents[ID].componentIndex]);
                    ShipTurret[ShipComponents[ID].componentIndex].currentCapacitor = 0;
                    break;

                case ComponentTypeTN.JumpEngine:
                    /// <summary>
                    /// Nothing special needs to be done to ship in this case.
                    /// </summary>
                    break;
            }
            return DamageReturn;
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Initializes this basic component.
        /// </summary>
        /// <param name="Title">Name which will be displayed to the user, they don't choose the names of these particular components however.</param>
        /// <param name="ComponentSize">Size of the component. this will determine crew capacity, fuel capacity, engineering percentage, and htk in addition to being merely size.</param>
        /// <param name="ComponentCrew">Crew requirement of the component, fuel tanks won't require any, orbital habitats will require a lot.</param>
        /// <param name="ComponentCost">Cost requirement of the component, mineral costs have yet to be done though those are just a percentage of total cost.</param>
        /// <param name="GeneralComponentType">What type of component is this? see the enum in ComponentTN.cs for a list.</param>
        public GeneralComponentDefTN(string Title, float ComponentSize, byte ComponentCrew, decimal ComponentCost, ComponentTypeTN GeneralComponentType)
        {
            Id = Guid.NewGuid();

            Name = Title;
            size = ComponentSize;
            crew = ComponentCrew;
            cost = ComponentCost;
            componentType = GeneralComponentType;

            minerialsCost = new decimal[Constants.Minerals.NO_OF_MINERIALS];
            for (int mineralIterator = 0; mineralIterator < (int)Constants.Minerals.MinerialNames.MinerialCount; mineralIterator++)
            {
                minerialsCost[mineralIterator] = 0;
            }

            switch (componentType)
            {
                case ComponentTypeTN.Crew: //25% Duranium 75% Mercassium
                    minerialsCost[(int)Constants.Minerals.MinerialNames.Duranium] = cost * 0.25m;
                    minerialsCost[(int)Constants.Minerals.MinerialNames.Mercassium] = cost * 0.75m;
                    break;
                case ComponentTypeTN.Fuel: //50% Duranium 50% Boronide
                    minerialsCost[(int)Constants.Minerals.MinerialNames.Duranium] = cost * 0.50m;
                    minerialsCost[(int)Constants.Minerals.MinerialNames.Boronide] = cost * 0.50m;
                    break;
                case ComponentTypeTN.Engineering: //100% Duranium
                    minerialsCost[(int)Constants.Minerals.MinerialNames.Duranium] = cost;
                    break;
                case ComponentTypeTN.Bridge:      //50% Duranium, 50% corbomite
                    minerialsCost[(int)Constants.Minerals.MinerialNames.Duranium] = cost * 0.50m;
                    minerialsCost[(int)Constants.Minerals.MinerialNames.Corbomite] = cost * 0.50m;
                    break;
                //case ComponentTypeTN.FlagBridge: 50% corbomite, 50% Uridium
                //case ComponentTypeTN.MaintenanceBay: 50% Duranium, 50% Neutronium
                //case ComponentTypeTN.OrbitalHabitat: 25% Duranium, 25% Boronide, 50% Mercassium
                //case ComponentTypeTN.RecFacility: 20% Duranium, 20% Tritanium, 60% Boronide
                //case ComponentTypeTN.DamageControl: 50% Duranium, 25% Neutronium, 25% Uridium
            }

            isDivisible = false;

            if (componentType <= ComponentTypeTN.MaintenanceBay)
            {
                if (size < 1.0f)
                    htk = 0;
                else
                    htk = 1;
            }
            else if (componentType == ComponentTypeTN.FlagBridge || componentType == ComponentTypeTN.DamageControl)
            {
                htk = 2;
            }
            else if (componentType == ComponentTypeTN.OrbitalHabitat || componentType == ComponentTypeTN.RecFacility)
            {
                htk = 25;
                isDivisible = true;
            }

            isMilitary = false;
            isObsolete = false;
            isSalvaged = false;
            isElectronic = false;
        }