Пример #1
0
 public ModuleDescription(
     string Name,
     int TypeID,
     MODULE_SLOT Slot,
     Dictionary <MODULE_ATTRIBUTES, Dictionary <MODULE_ACTIVE, Tuple <float, int> > > Attributes,
     float OverloadBonus,
     int ShipTypeID
     )
 {
     m_Name          = Name;
     m_TypeID        = TypeID;
     m_Slot          = Slot;
     m_Attributes    = Attributes;
     m_OverloadBonus = OverloadBonus;
     m_ShipTypeID    = ShipTypeID;
 }
Пример #2
0
 private string GetSlotName(MODULE_SLOT Slot, string ModuleName)
 {
     if (Slot == MODULE_SLOT.HIGH_POWER)
     {
         return("SLOT.HIGH");
     }
     else if (Slot == MODULE_SLOT.MEDIUM_POWER)
     {
         return("SLOT.MEDIUM");
     }
     else if (Slot == MODULE_SLOT.LOW_POWER)
     {
         return("SLOT.LOW");
     }
     else if (Slot == MODULE_SLOT.RIG)
     {
         return("SLOT.RIG");
     }
     else if (Slot == MODULE_SLOT.SUBSYSTEM)
     {
         if (ModuleName.Contains(" Core - "))
         {
             return("SLOT.SUB_CORE");
         }
         else if (ModuleName.Contains(" Defensive - "))
         {
             return("SLOT.SUB_DEFENSIVE");
         }
         else if (ModuleName.Contains(" Offensive - "))
         {
             return("SLOT.SUB_OFFENSIVE");
         }
         else if (ModuleName.Contains(" Propulsion - "))
         {
             return("SLOT.SUB_PROPULSION");
         }
     }
     Debug.Assert(false, "unknown slot");
     return("");
 }
Пример #3
0
        //================================================================================================================================================================================================================================

        private static IReadOnlyCollection <Tuple <string, int, int, MODULE_SLOT> > GetModules(NpgsqlConnection conn)
        {
            List <Tuple <string, int, int, MODULE_SLOT> > modules = new List <Tuple <string, int, int, MODULE_SLOT> >();

            NpgsqlCommand cmd = new NpgsqlCommand("SELECT \"typeID\", \"typeName\", \"groupID\", \"effectID\" FROM \"invTypes\" JOIN \"dgmTypeEffects\" USING (\"typeID\") WHERE \"published\" = TRUE AND \"effectID\" IN (11,12,13,2663,3772)", conn);

            using (NpgsqlDataReader dr = cmd.ExecuteReader())
            {
                while (dr.Read())
                {
                    string typeName = dr["typeName"].ToString();
                    if (!typeName.StartsWith("Standup "))
                    {
                        int         typeID  = Int32.Parse(dr["typeID"].ToString());
                        int         groupID = Int32.Parse(dr["groupID"].ToString());
                        MODULE_SLOT slot    = (MODULE_SLOT)Int32.Parse(dr["effectID"].ToString());
                        modules.Add(new Tuple <string, int, int, MODULE_SLOT>(typeName, typeID, groupID, slot));
                    }
                }
            }

            return(modules);
        }
Пример #4
0
        private static ModuleDescription CreateAbyssalModule(string ModuleName, string[] MarketGroups, MODULE_ATTRIBUTES_DB dbAttribute, float bonus, MODULE_ATTRIBUTES attribute, MODULE_SLOT slot, NpgsqlConnection conn)
        {
            int   typeID = GetTypeIDByName(ModuleName, conn);
            float value  = GetMaxAttributeValueForMarketGroup(MarketGroups, dbAttribute, conn);
            Dictionary <MODULE_ATTRIBUTES, Dictionary <MODULE_ACTIVE, Tuple <float, int> > > attributes = new Dictionary <MODULE_ATTRIBUTES, Dictionary <MODULE_ACTIVE, Tuple <float, int> > >();

            attributes.Add(
                attribute,
                new Dictionary <MODULE_ACTIVE, Tuple <float, int> > {
                { MODULE_ACTIVE.PASSIVE, new Tuple <float, int>(value * bonus, 1) }
            }
                );
            ModuleDescription result = new ModuleDescription(
                ModuleName,
                typeID,
                slot,
                attributes,
                0.0f,
                -1
                );

            return(result);
        }
Пример #5
0
        static ModuleDescription GetModuleDescription(string moduleName, int typeID, int groupID, MODULE_SLOT slot, NpgsqlConnection conn)
        {
            IReadOnlyDictionary <MODULE_ATTRIBUTES_DB, Tuple <bool, int, bool, float> > moduleAttributesDB = GetModuleAttributes(typeID, conn);

            // Tuple is : value + stacking group
            Dictionary <MODULE_ATTRIBUTES, Dictionary <MODULE_ACTIVE, Tuple <float, int> > > Attributes = new Dictionary <MODULE_ATTRIBUTES, Dictionary <MODULE_ACTIVE, Tuple <float, int> > >();

            float OverloadBonus = 0.0f;

            int ShipTypeID = -1;

            bool bActiveModule = false;

            if (moduleAttributesDB.ContainsKey(MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_CAPACITOR_NEEDED))
            {
                float attrDBValue = GetValue(moduleAttributesDB[MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_CAPACITOR_NEEDED]);
                bActiveModule = attrDBValue > 0.0f;
            }

            if (!bActiveModule)
            {
                if (moduleAttributesDB.ContainsKey(MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_DURATION))
                {
                    float attrDBValue = GetValue(moduleAttributesDB[MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_DURATION]);
                    bActiveModule = attrDBValue > 0.0f;
                }
            }

            bool isADC = moduleAttributesDB.ContainsKey(MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_ALL_RESONANCES);

            foreach (MODULE_ATTRIBUTES_DB attrDB in moduleAttributesDB.Keys)
            {
                float attrDBValue = GetValue(moduleAttributesDB[attrDB]);
                switch (attrDB)
                {
                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_POLARIZED:
                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_POLARIZED, GetActive(false, false, false), 1.0f, 1);
                    break;

                //
                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_SHIELD_EM_RESONANCE:
                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_EM_RESIST, GetActive(false, isADC, bActiveModule), 1.0f - attrDBValue, GetStackingGroup(groupID));
                    break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_SHIELD_THERMAL_RESONANCE:
                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_THERMAL_RESIST, GetActive(false, isADC, bActiveModule), 1.0f - attrDBValue, GetStackingGroup(groupID));
                    break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_SHIELD_KINETIC_RESONANCE:
                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_KINETIC_RESIST, GetActive(false, isADC, bActiveModule), 1.0f - attrDBValue, GetStackingGroup(groupID));
                    break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_SHIELD_EXPLOSIVE_RESONANCE:
                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_EXPLOSIVE_RESIST, GetActive(false, isADC, bActiveModule), 1.0f - attrDBValue, GetStackingGroup(groupID));
                    break;

                //
                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_ARMOR_EM_RESONANCE:
                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_EM_RESIST, GetActive(false, isADC, bActiveModule), 1.0f - attrDBValue, GetStackingGroup(groupID));
                    break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_ARMOR_THERMAL_RESONANCE:
                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_THERMAL_RESIST, GetActive(false, isADC, bActiveModule), 1.0f - attrDBValue, GetStackingGroup(groupID));
                    break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_ARMOR_KINETIC_RESONANCE:
                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_KINETIC_RESIST, GetActive(false, isADC, bActiveModule), 1.0f - attrDBValue, GetStackingGroup(groupID));
                    break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_ARMOR_EXPLOSIVE_RESONANCE:
                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_EXPLOSIVE_RESIST, GetActive(false, isADC, bActiveModule), 1.0f - attrDBValue, GetStackingGroup(groupID));
                    break;

                //
                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_HULL_EM_RESONANCE:
                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_HULL_EM_RESIST, GetActive(false, isADC, bActiveModule), 1.0f - attrDBValue, GetStackingGroup(groupID));
                    break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_HULL_THERMAL_RESONANCE:
                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_HULL_THERMAL_RESIST, GetActive(false, isADC, bActiveModule), 1.0f - attrDBValue, GetStackingGroup(groupID));
                    break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_HULL_KINETIC_RESONANCE:
                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_HULL_KINETIC_RESIST, GetActive(false, isADC, bActiveModule), 1.0f - attrDBValue, GetStackingGroup(groupID));
                    break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_HULL_EXPLOSIVE_RESONANCE:
                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_HULL_EXPLOSIVE_RESIST, GetActive(false, isADC, bActiveModule), 1.0f - attrDBValue, GetStackingGroup(groupID));
                    break;

                //
                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_EM_RESIST_BONUS:
                    Debug.Assert(attrDBValue <= 0.0f);
                    if (attrDBValue < 0.0f)
                    {
                        if (groupID == 77 || groupID == 1700)
                        {
                            // active shield resist modules: Invulnerability Fields, Ward Fields, Flex Hardeners
                            Debug.Assert(bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, true, false, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_EM_RESIST);
                        }
                        else if (groupID == 328 || groupID == 1699)
                        {
                            // active armor resist modules
                            Debug.Assert(bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, true, false, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_EM_RESIST);
                        }
                        else if (groupID == 295)
                        {
                            // passive shield resist modules
                            Debug.Assert(!bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, false, false, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_EM_RESIST);
                        }
                        else if (groupID == 98 || groupID == 326)
                        {
                            // passive armor resist modules
                            Debug.Assert(!bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, false, false, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_EM_RESIST);
                        }
                        else if (groupID == 774)
                        {
                            // shield rigs
                            Debug.Assert(!bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, false, true, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_EM_RESIST);
                        }
                        else if (groupID == 773)
                        {
                            // armor rigs
                            Debug.Assert(!bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, false, true, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_EM_RESIST);
                        }
                        else
                        {
                            Console.WriteLine("Unknown EM resist module: {0}, groupID={1}", moduleName, groupID);
                        }
                    }
                    break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_THERMAL_RESIST_BONUS:
                    Debug.Assert(attrDBValue <= 0.0f);
                    if (attrDBValue < 0.0f)
                    {
                        if (groupID == 77 || groupID == 1700)
                        {
                            // active shield resist modules: Invulnerability Fields, Ward Fields, Flex Hardeners
                            Debug.Assert(bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, true, false, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_THERMAL_RESIST);
                        }
                        else if (groupID == 328 || groupID == 1699)
                        {
                            // active armor resist modules
                            Debug.Assert(bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, true, false, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_THERMAL_RESIST);
                        }
                        else if (groupID == 295)
                        {
                            // passive shield resist modules
                            Debug.Assert(!bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, false, false, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_THERMAL_RESIST);
                        }
                        else if (groupID == 98 || groupID == 326)
                        {
                            // passive armor resist modules
                            Debug.Assert(!bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, false, false, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_THERMAL_RESIST);
                        }
                        else if (groupID == 774)
                        {
                            // shield rigs
                            Debug.Assert(!bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, false, true, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_THERMAL_RESIST);
                        }
                        else if (groupID == 773)
                        {
                            // armor rigs
                            Debug.Assert(!bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, false, true, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_THERMAL_RESIST);
                        }
                        else
                        {
                            Console.WriteLine("Unknown THERMAL resist module: {0}, groupID={1}", moduleName, groupID);
                        }
                    }
                    break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_KINETIC_RESIST_BONUS:
                    Debug.Assert(attrDBValue <= 0.0f);
                    if (attrDBValue < 0.0f)
                    {
                        if (groupID == 77 || groupID == 1700)
                        {
                            // active shield resist modules: Invulnerability Fields, Ward Fields, Flex Hardeners
                            Debug.Assert(bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, true, false, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_KINETIC_RESIST);
                        }
                        else if (groupID == 328 || groupID == 1699)
                        {
                            // active armor resist modules
                            Debug.Assert(bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, true, false, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_KINETIC_RESIST);
                        }
                        else if (groupID == 295)
                        {
                            // passive shield resist modules
                            Debug.Assert(!bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, false, false, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_KINETIC_RESIST);
                        }
                        else if (groupID == 98 || groupID == 326)
                        {
                            // passive armor resist modules
                            Debug.Assert(!bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, false, false, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_KINETIC_RESIST);
                        }
                        else if (groupID == 774)
                        {
                            // shield rigs
                            Debug.Assert(!bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, false, true, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_KINETIC_RESIST);
                        }
                        else if (groupID == 773)
                        {
                            // armor rigs
                            Debug.Assert(!bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, false, true, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_KINETIC_RESIST);
                        }
                        else
                        {
                            Console.WriteLine("Unknown KINETIC resist module: {0}, groupID={1}", moduleName, groupID);
                        }
                    }
                    break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_EXPLOSIVE_RESIST_BONUS:
                    Debug.Assert(attrDBValue <= 0.0f);
                    if (attrDBValue < 0.0f)
                    {
                        if (groupID == 77 || groupID == 1700)
                        {
                            // active shield resist modules: Invulnerability Fields, Ward Fields, Flex Hardeners
                            Debug.Assert(bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, true, false, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_EXPLOSIVE_RESIST);
                        }
                        else if (groupID == 328 || groupID == 1699)
                        {
                            // active armor resist modules
                            Debug.Assert(bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, true, false, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_EXPLOSIVE_RESIST);
                        }
                        else if (groupID == 295)
                        {
                            // passive shield resist modules
                            Debug.Assert(!bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, false, false, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_EXPLOSIVE_RESIST);
                        }
                        else if (groupID == 98 || groupID == 326)
                        {
                            // passive armor resist modules
                            Debug.Assert(!bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, false, false, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_EXPLOSIVE_RESIST);
                        }
                        else if (groupID == 774)
                        {
                            // shield rigs
                            Debug.Assert(!bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, false, true, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_EXPLOSIVE_RESIST);
                        }
                        else if (groupID == 773)
                        {
                            // armor rigs
                            Debug.Assert(!bActiveModule);
                            AddResitAttributesWithHeat(ref Attributes, attrDBValue, false, true, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_EXPLOSIVE_RESIST);
                        }
                        else
                        {
                            Console.WriteLine("Unknown EM resist module: {0}, groupID={1}", moduleName, groupID);
                        }
                    }
                    break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_ALL_RESONANCES:
                    Debug.Assert(bActiveModule == true);
                    Debug.Assert(isADC == true);
                    MODULE_ACTIVE Active = GetActive(true, true, true);
                    Debug.Assert(Active == MODULE_ACTIVE.ASSAULT_ACTIVE);

                    float Resist        = 1.0f - attrDBValue;
                    int   StackingGroup = GetStackingGroup(groupID);

                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_EM_RESIST, Active, Resist, StackingGroup);
                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_THERMAL_RESIST, Active, Resist, StackingGroup);
                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_KINETIC_RESIST, Active, Resist, StackingGroup);
                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_EXPLOSIVE_RESIST, Active, Resist, StackingGroup);

                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_EM_RESIST, Active, Resist, StackingGroup);
                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_THERMAL_RESIST, Active, Resist, StackingGroup);
                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_KINETIC_RESIST, Active, Resist, StackingGroup);
                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_EXPLOSIVE_RESIST, Active, Resist, StackingGroup);

                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_HULL_EM_RESIST, Active, Resist, StackingGroup);
                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_HULL_THERMAL_RESIST, Active, Resist, StackingGroup);
                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_HULL_KINETIC_RESIST, Active, Resist, StackingGroup);
                    AddTo(ref Attributes, MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_HULL_EXPLOSIVE_RESIST, Active, Resist, StackingGroup);

                    break;

                //
                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_OVERLOAD_HARDENING_BONUS: {
                    if (attrDBValue > 1.0f)
                    {
                        OverloadBonus = attrDBValue * 0.01f;
                    }
                }
                break;

                //
                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_SHIELD_CAPACITY_MULTIPLIER: {
                    // power diagnostic systems, reactor control units, shield flux coils
                    Debug.Assert(bActiveModule == false);
                    float bonus = Math.Abs(attrDBValue - 1.0f);
                    if (bonus > 0.01f)
                    {
                        // filter out reactor control units, they have shield multiplier = 1
                        Attributes.Add(
                            MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_BONUS_MULTIPLY,
                            new Dictionary <MODULE_ACTIVE, Tuple <float, int> > {
                                { GetActive(false, false, false), new Tuple <float, int>(attrDBValue, 1) }
                            }
                            );
                    }
                }
                break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_ARMOR_HP_MULTIPLIER: {
                    Debug.Assert(bActiveModule == false);
                    float bonus = Math.Abs(attrDBValue - 1.0f);
                    if (bonus > 0.01f)
                    {
                        // filter out armor resist modules, they have armor multiplier = 1
                        Attributes.Add(
                            MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_BONUS_MULTIPLY,
                            new Dictionary <MODULE_ACTIVE, Tuple <float, int> > {
                                { GetActive(false, false, false), new Tuple <float, int>(attrDBValue, 1) }
                            }
                            );
                    }
                }
                break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_STRUCTURE_HP_MULTIPLIER: {
                    // bulkheads, expanded cargoholds, nanofibers
                    Debug.Assert(bActiveModule == false);
                    float bonus = Math.Abs(attrDBValue - 1.0f);
                    if (bonus > 0.01f)
                    {
                        // filter out nanofibers, they have hull multiplier = 1
                        Attributes.Add(
                            MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_HULL_BONUS_MULTIPLY,
                            new Dictionary <MODULE_ACTIVE, Tuple <float, int> > {
                                { GetActive(false, false, false), new Tuple <float, int>(attrDBValue, 1) }
                            }
                            );
                    }
                }
                break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_ARMOR_HP_BONUS_ADD: {
                    Debug.Assert(bActiveModule == false);
                    float bonus = Math.Abs(attrDBValue);
                    if (bonus > 0.01f)
                    {
                        Attributes.Add(
                            MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_BONUS_ADD,
                            new Dictionary <MODULE_ACTIVE, Tuple <float, int> > {
                                { GetActive(false, false, false), new Tuple <float, int>(attrDBValue, 1) }
                            }
                            );
                    }
                }
                break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_CAPACITY_BONUS:
                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_SHIELD_CAPACITY: {
                    Debug.Assert(bActiveModule == false);
                    float bonus = Math.Abs(attrDBValue);
                    if (bonus > 0.01f)
                    {
                        // filter out shield resist amplifiers, they have shield bonus = 0
                        Attributes.Add(
                            MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_BONUS_ADD,
                            new Dictionary <MODULE_ACTIVE, Tuple <float, int> > {
                                { GetActive(false, false, false), new Tuple <float, int>(attrDBValue, 1) }
                            }
                            );
                    }
                }
                break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_STRUCTURE_HP_BONUS_ADD: {
                    Debug.Assert(bActiveModule == false);
                    float bonus = Math.Abs(attrDBValue);
                    if (bonus > 0.01f)
                    {
                        Attributes.Add(
                            MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_HULL_BONUS_ADD,
                            new Dictionary <MODULE_ACTIVE, Tuple <float, int> > {
                                { GetActive(false, false, false), new Tuple <float, int>(attrDBValue, 1) }
                            }
                            );
                    }
                }
                break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_SHIELD_CAPACITY_BONUS:
                    if (groupID == 774)     // shield rigs only
                    {
                        Debug.Assert(bActiveModule == false);
                        float bonus = Math.Abs(attrDBValue);
                        if (bonus > 0.01f)
                        {
                            // shield % bonus
                            bonus = 1.0f + 0.01f * bonus;
                            Attributes.Add(
                                MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_BONUS_MULTIPLY,
                                new Dictionary <MODULE_ACTIVE, Tuple <float, int> > {
                                { GetActive(false, false, false), new Tuple <float, int>(bonus, 1) }
                            }
                                );
                        }
                    }
                    break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_ARMOR_HP_BONUS:
                    if (groupID == 773)     // armor/hull rigs only
                    {
                        Debug.Assert(bActiveModule == false);
                        float bonus = Math.Abs(attrDBValue);
                        if (bonus > 0.01f)
                        {
                            // armor % bonus
                            bonus = 1.0f + 0.01f * bonus;
                            Attributes.Add(
                                MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_BONUS_MULTIPLY,
                                new Dictionary <MODULE_ACTIVE, Tuple <float, int> > {
                                { GetActive(false, false, false), new Tuple <float, int>(bonus, 1) }
                            }
                                );
                        }
                    }
                    break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_HULL_HP_BONUS:
                    if (groupID == 773)     // armor/hull rigs only
                    {
                        Debug.Assert(bActiveModule == false);
                        float bonus = Math.Abs(attrDBValue);
                        if (bonus > 0.01f)
                        {
                            // hull % bonus
                            bonus = 1.0f + 0.01f * bonus;
                            Attributes.Add(
                                MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_HULL_BONUS_MULTIPLY,
                                new Dictionary <MODULE_ACTIVE, Tuple <float, int> > {
                                { GetActive(false, false, false), new Tuple <float, int>(bonus, 1) }
                            }
                                );
                        }
                    }
                    break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_DRAWBACK:
                    if (Math.Abs(attrDBValue) > 0.0f)
                    {
                        Debug.Assert(bActiveModule == false);
                        float drawback = 0.5f * attrDBValue;     // rig drawback can be halved by training appropriate rigging skill
                        drawback = 1.0f + 0.01f * drawback;

                        if (
                            moduleName.Contains("Inverted Signal Field Projector") ||
                            moduleName.Contains("Particle Dispersion Augmentor") ||
                            moduleName.Contains("Particle Dispersion Projector") ||
                            moduleName.Contains("Targeting Systems Stabilizer") ||
                            moduleName.Contains("Tracking Diagnostics Subroutines") ||
                            moduleName.Contains("Signal Focusing Kit") ||
                            moduleName.Contains("Ionic Field Projector") ||
                            moduleName.Contains("Targeting System Subcontroller")
                            )
                        {
                            Debug.Assert(drawback < 1.0f);
                            Attributes.Add(
                                MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_BONUS_MULTIPLY,
                                new Dictionary <MODULE_ACTIVE, Tuple <float, int> > {
                                { GetActive(false, false, false), new Tuple <float, int>(drawback, 1) }
                            }
                                );
                        }
                        else if
                        (
                            moduleName.Contains("Auxiliary Thrusters") ||
                            moduleName.Contains("Cargohold Optimization") ||
                            moduleName.Contains("Dynamic Fuel Valve") ||
                            moduleName.Contains("Engine Thermal Shielding") ||
                            moduleName.Contains("Low Friction Nozzle Joints") ||
                            moduleName.Contains("Polycarbon Engine Housing")
                        )
                        {
                            Debug.Assert(drawback < 1.0f);
                            Attributes.Add(
                                MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_BONUS_MULTIPLY,
                                new Dictionary <MODULE_ACTIVE, Tuple <float, int> > {
                                { GetActive(false, false, false), new Tuple <float, int>(drawback, 1) }
                            }
                                );
                        }
                    }
                    break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_SHIP_TYPE:
                    ShipTypeID = (int)attrDBValue;
                    break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_HIGH_SLOTS:
                    if (attrDBValue > 0.01f)
                    {
                        Debug.Assert(bActiveModule == false);
                        Attributes.Add(
                            MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_HIGH_SLOTS,
                            new Dictionary <MODULE_ACTIVE, Tuple <float, int> > {
                            { GetActive(false, false, false), new Tuple <float, int>(attrDBValue, 1) }
                        }
                            );
                    }
                    break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_MEDIUM_SLOTS:
                    if (attrDBValue > 0.01f)
                    {
                        Debug.Assert(bActiveModule == false);
                        Attributes.Add(
                            MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_MEDIUM_SLOTS,
                            new Dictionary <MODULE_ACTIVE, Tuple <float, int> > {
                            { GetActive(false, false, false), new Tuple <float, int>(attrDBValue, 1) }
                        }
                            );
                    }
                    break;

                case MODULE_ATTRIBUTES_DB.MODULE_ATTR_DB_LOW_SLOTS:
                    if (attrDBValue > 0.01f)
                    {
                        Debug.Assert(bActiveModule == false);
                        Attributes.Add(
                            MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_LOW_SLOTS,
                            new Dictionary <MODULE_ACTIVE, Tuple <float, int> > {
                            { GetActive(false, false, false), new Tuple <float, int>(attrDBValue, 1) }
                        }
                            );
                    }
                    break;
                }
            }

            if (ShipTypeID > 0)
            {
                IReadOnlyDictionary <MODULE_TRAITS, float> moduleTraits = GetModuleTraits(typeID, conn);

                float traitShieldHPPercentPerLevel = 0.0f;
                if (moduleTraits.TryGetValue(MODULE_TRAITS.MODULE_TRAIT_SHIELD_HP_PERCENT_PER_LEVEL, out traitShieldHPPercentPerLevel))
                {
                    // shield % bonus
                    Debug.Assert(bActiveModule == false);
                    float bonus = 1.0f + traitShieldHPPercentPerLevel * 0.01f * 5.0f;
                    Attributes.Add(
                        MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_BONUS_MULTIPLY,
                        new Dictionary <MODULE_ACTIVE, Tuple <float, int> > {
                        { GetActive(false, false, false), new Tuple <float, int>(bonus, 1) }
                    }
                        );
                }

                float traitArmorHPPercentPerLevel = 0.0f;
                if (moduleTraits.TryGetValue(MODULE_TRAITS.MODULE_TRAIT_ARMOR_HP_PERCENT_PER_LEVEL, out traitArmorHPPercentPerLevel))
                {
                    // armor % bonus
                    Debug.Assert(bActiveModule == false);
                    float bonus = 1.0f + traitArmorHPPercentPerLevel * 0.01f * 5.0f;
                    Attributes.Add(
                        MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_BONUS_MULTIPLY,
                        new Dictionary <MODULE_ACTIVE, Tuple <float, int> > {
                        { GetActive(false, false, false), new Tuple <float, int>(bonus, 1) }
                    }
                        );
                }

                float traitShieldHardenersOHBonusPerLevel = 0.0f;
                if (moduleTraits.TryGetValue(MODULE_TRAITS.MODULE_TRAIT_SHIELD_HARDENERS_OVERHEATING_BONUS, out traitShieldHardenersOHBonusPerLevel))
                {
                    // shield hardeners overheating bonus
                    Debug.Assert(bActiveModule == false);
                    float bonus = traitShieldHardenersOHBonusPerLevel * 0.01f * 5.0f;
                    Attributes.Add(
                        MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_SHIELD_HARDENERS_OVERLOAD_BONUS,
                        new Dictionary <MODULE_ACTIVE, Tuple <float, int> > {
                        { GetActive(false, false, false), new Tuple <float, int>(bonus, 1) }
                    }
                        );
                }

                float traitArmorHardenersOHBonusPerLevel = 0.0f;
                if (moduleTraits.TryGetValue(MODULE_TRAITS.MODULE_TRAIT_ARMOR_HARDENERS_OVERHEATING_BONUS, out traitArmorHardenersOHBonusPerLevel))
                {
                    // shield hardeners overheating bonus
                    Debug.Assert(bActiveModule == false);
                    float bonus = traitArmorHardenersOHBonusPerLevel * 0.01f * 5.0f;
                    Attributes.Add(
                        MODULE_ATTRIBUTES.MODULE_ATTRIBUTE_ARMOR_HARDENERS_OVERLOAD_BONUS,
                        new Dictionary <MODULE_ACTIVE, Tuple <float, int> > {
                        { GetActive(false, false, false), new Tuple <float, int>(bonus, 1) }
                    }
                        );
                }
            }

            return(new ModuleDescription(
                       moduleName,
                       typeID,
                       slot,
                       Attributes,
                       OverloadBonus,
                       ShipTypeID
                       ));
        }