Ejemplo n.º 1
0
 private void AddTo(ref Dictionary <RESIST,Dictionary <bool,Dictionary <int,List <float> > > > ResistBonuses,RESIST Resist,bool Hot,int StackGroup,float Value,uint Count)
 {
     if (!ResistBonuses.ContainsKey(Resist))
     {
         ResistBonuses.Add(Resist,new Dictionary <bool,Dictionary <int,List <float> > >());
     }
     if (!ResistBonuses[Resist].ContainsKey(Hot))
     {
         ResistBonuses[Resist].Add(Hot,new Dictionary <int,List <float> >());
     }
     if (!ResistBonuses[Resist][Hot].ContainsKey(StackGroup))
     {
         ResistBonuses[Resist][Hot].Add(StackGroup,new List <float>());
     }
     for (uint i = 0; i < Count; ++i)
     {
         ResistBonuses[Resist][Hot][StackGroup].Add(Value);
     }
 }
Ejemplo n.º 2
0
        GetLayerTank(float BaseHP,float LayerMultiplier,float ResistEM,float ResistThermal,float ResistKinetic,float ResistExplosive,bool isPolarized,LAYER Layer,IReadOnlyCollection <Tuple <ModuleDescription,uint> > Modules,float ShipOverheatingBonus)
        {
            float FlatHPBonus  = 0.0f;
            float HPMultiplier = LayerMultiplier;

            // resist => cold/hot => stacking_group => list of resist bonuses
            Dictionary <RESIST,Dictionary <bool,Dictionary <int,List <float> > > > ResistBonuses = new Dictionary <RESIST,Dictionary <bool,Dictionary <int,List <float> > > >();

            float SubsystemOverheatingBonus = 0.0f;

            foreach (Tuple <ModuleDescription,uint> ModuleAndCount in Modules)
            {
                uint Count = ModuleAndCount.Item2;
                if (ModuleAndCount.Item1.m_Effects.ContainsKey(Layer))
                {
                    if (ModuleAndCount.Item1.m_Effects[Layer].ContainsKey(EFFECT.OVERHEATING))
                    {
                        if (ModuleAndCount.Item1.m_Effects[Layer][EFFECT.OVERHEATING].ContainsKey(ACTIVE.PASSIVE))
                        {
                            // Only subsystems (passive modules) can be with overheating bonus.
                            // Not active and not assault DCs.
                            Debug.Assert(Count == 1);
                            Debug.Assert(SubsystemOverheatingBonus <= 0.0f);
                            SubsystemOverheatingBonus = ModuleAndCount.Item1.m_Effects[Layer][EFFECT.OVERHEATING][ACTIVE.PASSIVE].Item1;
                            Debug.Assert(SubsystemOverheatingBonus > 0.0f);
                        }
                    }
                }
            }

            foreach (Tuple <ModuleDescription,uint> ModuleAndCount in Modules)
            {
                uint Count = ModuleAndCount.Item2;
                if (ModuleAndCount.Item1.m_Effects.ContainsKey(Layer))
                {
                    foreach (EFFECT Effect in ModuleAndCount.Item1.m_Effects[Layer].Keys)
                    {
                        foreach (ACTIVE Active in ModuleAndCount.Item1.m_Effects[Layer][Effect].Keys)
                        {
                            Tuple <float,int> EffectParams = ModuleAndCount.Item1.m_Effects[Layer][Effect][Active];

                            switch (Effect)
                            {
                            case EFFECT.ADD:
                                Debug.Assert(Active == ACTIVE.PASSIVE);    // all flat shield/armor/hull bonuses belong to passive modules
                                Debug.Assert(EffectParams.Item2 == 1);     // all flat shield/armor/hull bonuses have stacking group 1
                                FlatHPBonus += (EffectParams.Item1 * Count);
                                break;

                            case EFFECT.MULTIPLY:
                                Debug.Assert(Active == ACTIVE.PASSIVE);    // all multiplicative shield/armor/hull bonuses belong to passive modules
                                Debug.Assert(EffectParams.Item2 == 1);     // all multiplicative shield/armor/hull bonuses have stacking group 1
                                HPMultiplier *= (float)Math.Pow(EffectParams.Item1,Count);
                                break;

                            case EFFECT.EM:
                            case EFFECT.THERMAL:
                            case EFFECT.KINETIC:
                            case EFFECT.EXPLOSIVE:
                                if (!isPolarized)
                                {
                                    RESIST Resist = EffectToResist(Effect);
                                    switch (Active)
                                    {
                                    case ACTIVE.PASSIVE:
                                        // passive effect
                                        AddTo(ref ResistBonuses,Resist,false,EffectParams.Item2,EffectParams.Item1,Count);
                                        AddTo(ref ResistBonuses,Resist,true,EffectParams.Item2,EffectParams.Item1,Count);
                                        break;

                                    case ACTIVE.ACTIVE:
                                        // active effect
                                        if (!PassiveTank)
                                        {
                                            AddTo(ref ResistBonuses,Resist,false,EffectParams.Item2,EffectParams.Item1,Count);
                                            float OverloadBonus = ModuleAndCount.Item1.m_OverloadBonus;
                                            if (OverloadBonus > 0.01f)
                                            {
                                                float OverloadedResist = EffectParams.Item1 * (1.0f + OverloadBonus * (1.0f + ShipOverheatingBonus + SubsystemOverheatingBonus));
                                                AddTo(ref ResistBonuses,Resist,true,EffectParams.Item2,OverloadedResist,Count);
                                            }
                                            else
                                            {
                                                AddTo(ref ResistBonuses,Resist,true,EffectParams.Item2,EffectParams.Item1,Count);
                                            }
                                        }
                                        break;

                                    case ACTIVE.ASSAULT_PASSIVE:
                                        // bonus from passive ADC
                                        if (PassiveTank || !AssaultDCEnabled)
                                        {
                                            AddTo(ref ResistBonuses,Resist,false,EffectParams.Item2,EffectParams.Item1,Count);
                                            AddTo(ref ResistBonuses,Resist,true,EffectParams.Item2,EffectParams.Item1,Count);
                                        }
                                        break;

                                    case ACTIVE.ASSAULT_ACTIVE:
                                        // bonus from active ADC
                                        if (!PassiveTank && AssaultDCEnabled)
                                        {
                                            AddTo(ref ResistBonuses,Resist,false,EffectParams.Item2,EffectParams.Item1,Count);
                                            AddTo(ref ResistBonuses,Resist,true,EffectParams.Item2,EffectParams.Item1,Count);
                                        }
                                        break;
                                    }
                                }
                                break;
                            }
                        }
                    }
                }
            }

            float LayerHP = (BaseHP + FlatHPBonus) * HPMultiplier;

            LayerHP *= 1.25f; // Shield Management / Hull Upgrades / Mechanics

            Dictionary <RESIST,float> ResistsCold = new Dictionary <RESIST,float>();
            Dictionary <RESIST,float> ResistsHot  = new Dictionary <RESIST,float>();

            if (!isPolarized)
            {
                Dictionary <RESIST,Dictionary <bool,float> > Resonances = new Dictionary <RESIST,Dictionary <bool,float> >();
                Resonances[RESIST.EM]        = new Dictionary <bool,float>();
                Resonances[RESIST.THERMAL]   = new Dictionary <bool,float>();
                Resonances[RESIST.KINETIC]   = new Dictionary <bool,float>();
                Resonances[RESIST.EXPLOSIVE] = new Dictionary <bool,float>();

                foreach (RESIST Resist in ResistBonuses.Keys)
                {
                    foreach (bool Hot in ResistBonuses[Resist].Keys)
                    {
                        float ResonanceCombined = 1.0f;
                        foreach (int StackGroup in ResistBonuses[Resist][Hot].Keys)
                        {
                            List <float> ResistsGroup = ResistBonuses[Resist][Hot][StackGroup];
                            ResistsGroup.Sort(
                                delegate(float a,float b) {
                                if (a < b)
                                {
                                    return(1);
                                }
                                if (a > b)
                                {
                                    return(-1);
                                }
                                return(0);
                            }
                                );

                            float Resonance = 1.0f;
                            for (int i = 0; i < ResistsGroup.Count; ++i)
                            {
                                float pc = PenaltyCoeff(i);
                                Resonance *= (1.0f - ResistsGroup[i] * pc);
                            }

                            ResonanceCombined *= Resonance;
                        }
                        Resonances[Resist][Hot] = ResonanceCombined;
                    }
                }

                ResistsCold[RESIST.EM]        = 1.0f - (1.0f - ResistEM) * GetResonance(Resonances,RESIST.EM,false);
                ResistsCold[RESIST.THERMAL]   = 1.0f - (1.0f - ResistThermal) * GetResonance(Resonances,RESIST.THERMAL,false);
                ResistsCold[RESIST.KINETIC]   = 1.0f - (1.0f - ResistKinetic) * GetResonance(Resonances,RESIST.KINETIC,false);
                ResistsCold[RESIST.EXPLOSIVE] = 1.0f - (1.0f - ResistExplosive) * GetResonance(Resonances,RESIST.EXPLOSIVE,false);

                ResistsHot[RESIST.EM]        = 1.0f - (1.0f - ResistEM) * GetResonance(Resonances,RESIST.EM,true);
                ResistsHot[RESIST.THERMAL]   = 1.0f - (1.0f - ResistThermal) * GetResonance(Resonances,RESIST.THERMAL,true);
                ResistsHot[RESIST.KINETIC]   = 1.0f - (1.0f - ResistKinetic) * GetResonance(Resonances,RESIST.KINETIC,true);
                ResistsHot[RESIST.EXPLOSIVE] = 1.0f - (1.0f - ResistExplosive) * GetResonance(Resonances,RESIST.EXPLOSIVE,true);
            }
            else
            {
                ResistsCold[RESIST.EM]        = 0.0f;
                ResistsCold[RESIST.THERMAL]   = 0.0f;
                ResistsCold[RESIST.KINETIC]   = 0.0f;
                ResistsCold[RESIST.EXPLOSIVE] = 0.0f;

                ResistsHot[RESIST.EM]        = 0.0f;
                ResistsHot[RESIST.THERMAL]   = 0.0f;
                ResistsHot[RESIST.KINETIC]   = 0.0f;
                ResistsHot[RESIST.EXPLOSIVE] = 0.0f;
            }

            return(new Tuple <float,Dictionary <RESIST,float>,Dictionary <RESIST,float> >(LayerHP,ResistsCold,ResistsHot));
        }
Ejemplo n.º 3
0
 float GetResonance(IReadOnlyDictionary <RESIST,Dictionary <bool,float> > Resonances,RESIST Resist,bool Hot)
 {
     if (Resonances.ContainsKey(Resist))
     {
         if (Resonances[Resist].ContainsKey(Hot))
         {
             return(Resonances[Resist][Hot]);
         }
     }
     return(1.0f);
 }