Esempio n. 1
0
        /// <summary>
        /// Certain items do not contain a ClothingBase. Ursuin Guise, WCID 32155 is one of them. This function will use the Setup of the weenie as a pseudo-ClothingBase.
        /// </summary>
        protected ACE.Entity.ObjDesc AddSetupAsClothingBase(ACE.Entity.ObjDesc objDesc, WorldObject wo)
        {
            // Loop over the parts in the Setup of the WorldObject
            for (var i = 0; i < wo.CSetup.Parts.Count; i++)
            {
                if (wo.CSetup.Parts[i] != 0x010001EC || i != 16) // This is essentially a "null" part, so do not add it for the head
                {
                    objDesc.AnimPartChanges.Add(new ACE.Entity.AnimationPartChange {
                        PartIndex = (byte)i, PartID = wo.CSetup.Parts[i]
                    });
                }
            }

            return(objDesc);
        }
        public override ACE.Entity.ObjDesc CalculateObjDesc()
        {
            ACE.Entity.ObjDesc objDesc = new ACE.Entity.ObjDesc();
            ClothingTable      item;

            AddBaseModelData(objDesc);

            var coverage = new List <uint>();

            bool showHelm  = true;
            bool showCloak = true;

            uint thisSetupId = SetupTableId;

            if (this is Player player)
            {
                showHelm  = player.GetCharacterOption(CharacterOption.ShowYourHelmOrHeadGear);
                showCloak = player.GetCharacterOption(CharacterOption.ShowYourCloak);

                // Some player races use an AlternateSetupDid, either at creation of via Barber options.
                // BUT -- those values do not correspond with entries in the Clothing Table.
                // So, we need to make some adjustments to look up something that DOES exist and is appropriate for the AlternateSetup model.
                switch (thisSetupId)
                {
                case (uint)SetupConst.UndeadMaleSkeleton:
                case (uint)SetupConst.UndeadMaleSkeletonNoflame:
                case (uint)SetupConst.UndeadMaleZombie:
                case (uint)SetupConst.UndeadMaleZombieNoflame:
                    thisSetupId = (uint)SetupConst.UndeadMaleUndead;
                    break;

                case (uint)SetupConst.UndeadFemaleSkeleton:
                case (uint)SetupConst.UndeadFemaleSkeletonNoflame:
                case (uint)SetupConst.UndeadFemaleZombie:
                case (uint)SetupConst.UndeadFemaleZombieNoflame:
                    thisSetupId = (uint)SetupConst.UndeadFemaleUndead;
                    break;

                case (uint)SetupConst.PenumbraenMaleNocrown:
                    thisSetupId = (uint)SetupConst.PenumbraenMaleCrown;
                    break;

                case (uint)SetupConst.PenumbraenFemaleNocrown:
                    thisSetupId = (uint)SetupConst.PenumbraenFemaleCrown;
                    break;
                }
            }

            var eo = EquippedObjects.Values.Where(x => (x.CurrentWieldedLocation & (EquipMask.Clothing | EquipMask.Armor | EquipMask.Cloak)) != 0).OrderBy(x => x.ClothingPriority).ToList();

            if (eo.Count == 0)
            {
                if (Biota.BiotaPropertiesAnimPart.Count > 0 || Biota.BiotaPropertiesPalette.Count > 0 || Biota.BiotaPropertiesTextureMap.Count > 0)
                {
                    foreach (var animPart in Biota.BiotaPropertiesAnimPart.OrderBy(b => b.Order))
                    {
                        objDesc.AnimPartChanges.Add(new ACE.Entity.AnimationPartChange {
                            PartIndex = animPart.Index, PartID = animPart.AnimationId
                        });
                    }

                    foreach (var subPalette in Biota.BiotaPropertiesPalette)
                    {
                        objDesc.SubPalettes.Add(new ACE.Entity.SubPalette {
                            SubID = subPalette.SubPaletteId, Offset = subPalette.Offset, NumColors = subPalette.Length
                        });
                    }

                    foreach (var textureMap in Biota.BiotaPropertiesTextureMap.OrderBy(b => b.Order))
                    {
                        objDesc.TextureChanges.Add(new ACE.Entity.TextureMapChange {
                            PartIndex = textureMap.Index, OldTexture = textureMap.OldId, NewTexture = textureMap.NewId
                        });
                    }

                    return(objDesc);
                }
            }

            foreach (var w in eo)
            {
                if ((w.CurrentWieldedLocation == EquipMask.HeadWear) && !showHelm && (this is Player))
                {
                    continue;
                }

                if ((w.CurrentWieldedLocation == EquipMask.Cloak) && !showCloak && (this is Player))
                {
                    continue;
                }

                // We can wield things that are not part of our model, only use those items that can cover our model.
                if ((w.CurrentWieldedLocation & (EquipMask.Clothing | EquipMask.Armor | EquipMask.Cloak)) != 0)
                {
                    if (w.ClothingBase.HasValue)
                    {
                        item = DatManager.PortalDat.ReadFromDat <ClothingTable>((uint)w.ClothingBase);
                    }
                    else
                    {
                        continue;
                    }

                    if (item.ClothingBaseEffects.ContainsKey(thisSetupId))
                    // Check if the player model has data. Gear Knights, this is usually you.
                    {
                        // Add the model and texture(s)
                        ClothingBaseEffect clothingBaseEffect = item.ClothingBaseEffects[thisSetupId];
                        foreach (CloObjectEffect t in clothingBaseEffect.CloObjectEffects)
                        {
                            byte partNum = (byte)t.Index;
                            if (objDesc.AnimPartChanges.FirstOrDefault(c => c.PartIndex == (byte)t.Index && c.PartID == t.ModelId) == null)
                            {
                                objDesc.AnimPartChanges.Add(new ACE.Entity.AnimationPartChange {
                                    PartIndex = (byte)t.Index, PartID = t.ModelId
                                });
                            }
                            //AddModel((byte)t.Index, (ushort)t.ModelId);
                            coverage.Add(partNum);
                            foreach (CloTextureEffect t1 in t.CloTextureEffects)
                            {
                                if (objDesc.TextureChanges.FirstOrDefault(c => c.PartIndex == (byte)t.Index && c.OldTexture == t1.OldTexture && c.NewTexture == t1.NewTexture) == null)
                                {
                                    objDesc.TextureChanges.Add(new ACE.Entity.TextureMapChange {
                                        PartIndex = (byte)t.Index, OldTexture = t1.OldTexture, NewTexture = t1.NewTexture
                                    });
                                }
                            }
                            //AddTexture((byte)t.Index, (ushort)t1.OldTexture, (ushort)t1.NewTexture);
                        }

                        if (item.ClothingSubPalEffects.Count > 0)
                        {
                            int size     = item.ClothingSubPalEffects.Count;
                            int palCount = size;

                            CloSubPalEffect itemSubPal;
                            int             palOption = 0;
                            if (w.PaletteTemplate.HasValue)
                            {
                                palOption = (int)w.PaletteTemplate;
                            }
                            if (item.ClothingSubPalEffects.ContainsKey((uint)palOption))
                            {
                                itemSubPal = item.ClothingSubPalEffects[(uint)palOption];
                            }
                            else
                            {
                                itemSubPal = item.ClothingSubPalEffects[item.ClothingSubPalEffects.Keys.ElementAt(0)];
                            }

                            //if (itemSubPal.Icon > 0 && !(IgnoreCloIcons ?? false))
                            //    IconId = itemSubPal.Icon;

                            float shade = 0;
                            if (w.Shade.HasValue)
                            {
                                shade = (float)w.Shade;
                            }
                            for (int i = 0; i < itemSubPal.CloSubPalettes.Count; i++)
                            {
                                var    itemPalSet = DatManager.PortalDat.ReadFromDat <PaletteSet>(itemSubPal.CloSubPalettes[i].PaletteSet);
                                ushort itemPal    = (ushort)itemPalSet.GetPaletteID(shade);

                                for (int j = 0; j < itemSubPal.CloSubPalettes[i].Ranges.Count; j++)
                                {
                                    uint palOffset = itemSubPal.CloSubPalettes[i].Ranges[j].Offset / 8;
                                    uint numColors = itemSubPal.CloSubPalettes[i].Ranges[j].NumColors / 8;
                                    objDesc.SubPalettes.Add(new ACE.Entity.SubPalette {
                                        SubID = itemPal, Offset = palOffset, NumColors = numColors
                                    });
                                    //AddPalette(itemPal, (ushort)palOffset, (ushort)numColors);
                                }
                            }
                        }
                    }
                }
            }

            // Add the "naked" body parts. These are the ones not already covered.
            // Note that this is the original SetupTableId, not thisSetupId.
            if (SetupTableId > 0)
            {
                var baseSetup = DatManager.PortalDat.ReadFromDat <SetupModel>(SetupTableId);
                for (byte i = 0; i < baseSetup.Parts.Count; i++)
                {
                    if (!coverage.Contains(i) && i != 0x10) // Don't add body parts for those that are already covered. Also don't add the head, that was already covered by AddCharacterBaseModelData()
                    {
                        objDesc.AnimPartChanges.Add(new ACE.Entity.AnimationPartChange {
                            PartIndex = i, PartID = baseSetup.Parts[i]
                        });
                    }
                    //AddModel(i, baseSetup.Parts[i]);
                }
            }

            if (coverage.Count == 0 && ClothingBase.HasValue)
            {
                return(base.CalculateObjDesc());
            }

            /*var p = this as Player;
             * if (p != null)
             * {
             *  Console.WriteLine("AnimPart changes:");
             *  Console.WriteLine("PartIndex\tPartID\n====================================");
             *  foreach (var animPartChange in objDesc.AnimPartChanges)
             *      Console.WriteLine(animPartChange.PartIndex + "\t" + animPartChange.PartID.ToString("X8"));
             *
             *  Console.WriteLine("TextureMap changes:");
             *  Console.WriteLine("PartIndex\tOldTex\tNewTex\n====================================");
             *  foreach (var texChange in objDesc.TextureChanges)
             *      Console.WriteLine(texChange.PartIndex + "\t" + texChange.OldTexture.ToString("X8") + "\t" + texChange.NewTexture.ToString("X8"));
             * }*/

            return(objDesc);
        }
Esempio n. 3
0
        public override ACE.Entity.ObjDesc CalculateObjDesc()
        {
            ACE.Entity.ObjDesc objDesc = new ACE.Entity.ObjDesc();
            ClothingTable      item;

            AddBaseModelData(objDesc);

            var coverage = new List <uint>();

            uint thisSetupId = SetupTableId;
            bool showHelm    = true;
            bool showCloak   = true;

            if (this is Player player)
            {
                showHelm  = player.GetCharacterOption(CharacterOption.ShowYourHelmOrHeadGear);
                showCloak = player.GetCharacterOption(CharacterOption.ShowYourCloak);
            }

            // Some player races use an AlternateSetupDid, either at creation or via Barber options.
            // BUT -- those values do not correspond with entries in the Clothing Table.
            // So, we need to make some adjustments to look up something that DOES exist and is appropriate for the AlternateSetup model.
            switch (thisSetupId)
            {
            //case (uint)SetupConst.UmbraenMaleCrown:
            case (uint)SetupConst.UmbraenMaleCrownGen:
            case (uint)SetupConst.UmbraenMaleNoCrown:
            case (uint)SetupConst.UmbraenMaleVoid:
                thisSetupId = (uint)SetupConst.UmbraenMaleCrown;
                break;

            //case (uint)SetupConst.UmbraenFemaleCrown:
            //case (uint)SetupConst.UmbraenFemaleCrownGen:
            case (uint)SetupConst.UmbraenFemaleNoCrown:
            case (uint)SetupConst.UmbraenFemaleVoid:
                thisSetupId = (uint)SetupConst.UmbraenFemaleCrown;
                break;

            //case (uint)SetupConst.PenumbraenMaleCrown:
            case (uint)SetupConst.PenumbraenMaleCrownGen:
            case (uint)SetupConst.PenumbraenMaleNoCrown:
            case (uint)SetupConst.PenumbraenMaleVoid:
                thisSetupId = (uint)SetupConst.PenumbraenMaleCrown;
                break;

            //case (uint)SetupConst.PenumbraenFemaleCrown:
            //case (uint)SetupConst.PenumbraenFemaleCrownGen:
            case (uint)SetupConst.PenumbraenFemaleNoCrown:
            case (uint)SetupConst.PenumbraenFemaleVoid:
                thisSetupId = (uint)SetupConst.PenumbraenFemaleCrown;
                break;

            case (uint)SetupConst.UndeadMaleUndeadGen:
            case (uint)SetupConst.UndeadMaleSkeleton:
            case (uint)SetupConst.UndeadMaleSkeletonNoFlame:
            case (uint)SetupConst.UndeadMaleZombie:
            case (uint)SetupConst.UndeadMaleZombieNoFlame:
                thisSetupId = (uint)SetupConst.UndeadMaleUndead;
                break;

            case (uint)SetupConst.UndeadFemaleUndeadGen:
            case (uint)SetupConst.UndeadFemaleSkeleton:
            case (uint)SetupConst.UndeadFemaleSkeletonNoFlame:
            case (uint)SetupConst.UndeadFemaleZombie:
            case (uint)SetupConst.UndeadFemaleZombieNoFlame:
                thisSetupId = (uint)SetupConst.UndeadFemaleUndead;
                break;

            case (uint)SetupConst.AnakshayMale:
                thisSetupId = (uint)SetupConst.HumanMale;
                break;

            case (uint)SetupConst.AnakshayFemale:
                thisSetupId = (uint)SetupConst.HumanFemale;
                break;
            }

            // get all the Armor Items so we can calculate their priority
            var armorItems = EquippedObjects.Values.Where(x => (x.ItemType == ItemType.Armor)).ToList();

            foreach (var w in armorItems)
            {
                w.setVisualClothingPriority();
            }

            // sort the armor into the proper order... TopLayerPriority first, then no priority, then TopLayerPriority=false.
            // Secondary sort field is the calculated "VisualClothingPriority"
            var top              = armorItems.Where(x => x.TopLayerPriority == true).OrderBy(x => x.VisualClothingPriority);
            var noLayer          = armorItems.Where(x => x.TopLayerPriority == null).OrderBy(x => x.VisualClothingPriority);
            var bottom           = armorItems.Where(x => x.TopLayerPriority == false).OrderBy(x => x.VisualClothingPriority);
            var sortedArmorItems = bottom.Concat(noLayer).Concat(top).ToList();

            var clothesAndCloaks = EquippedObjects.Values
                                   .Where(x => (x.ItemType == ItemType.Clothing)) // FootWear & HandWear is included in the ArmorItems above
                                   .OrderBy(x => x.ClothingPriority);

            var eo = clothesAndCloaks.Concat(sortedArmorItems).ToList();

            if (eo.Count == 0)
            {
                // Check if there is any defined ObjDesc in the Biota and, if so, apply them
                if (Biota.BiotaPropertiesAnimPart.Count > 0 || Biota.BiotaPropertiesPalette.Count > 0 || Biota.BiotaPropertiesTextureMap.Count > 0)
                {
                    foreach (var animPart in Biota.BiotaPropertiesAnimPart.OrderBy(b => b.Order))
                    {
                        objDesc.AnimPartChanges.Add(new ACE.Entity.AnimationPartChange {
                            PartIndex = animPart.Index, PartID = animPart.AnimationId
                        });
                    }

                    foreach (var subPalette in Biota.BiotaPropertiesPalette)
                    {
                        objDesc.SubPalettes.Add(new ACE.Entity.SubPalette {
                            SubID = subPalette.SubPaletteId, Offset = subPalette.Offset, NumColors = subPalette.Length
                        });
                    }

                    foreach (var textureMap in Biota.BiotaPropertiesTextureMap.OrderBy(b => b.Order))
                    {
                        objDesc.TextureChanges.Add(new ACE.Entity.TextureMapChange {
                            PartIndex = textureMap.Index, OldTexture = textureMap.OldId, NewTexture = textureMap.NewId
                        });
                    }

                    return(objDesc);
                }
            }

            foreach (var w in eo)
            {
                if ((w.CurrentWieldedLocation == EquipMask.HeadWear) && !showHelm && (this is Player))
                {
                    continue;
                }

                if ((w.CurrentWieldedLocation == EquipMask.Cloak) && !showCloak && (this is Player))
                {
                    continue;
                }

                // We can wield things that are not part of our model, only use those items that can cover our model.
                if ((w.CurrentWieldedLocation & (EquipMask.Clothing | EquipMask.Armor | EquipMask.Cloak)) != 0)
                {
                    if (w.ClothingBase.HasValue)
                    {
                        item = DatManager.PortalDat.ReadFromDat <ClothingTable>((uint)w.ClothingBase);
                    }
                    else
                    {
                        objDesc = AddSetupAsClothingBase(objDesc, w);
                        // Add any potentially added parts back into the coverage list
                        foreach (var a in objDesc.AnimPartChanges)
                        {
                            if (!coverage.Contains(a.PartIndex))
                            {
                                coverage.Add(a.PartIndex);
                            }
                        }
                        continue;
                    }

                    if (item.ClothingBaseEffects.ContainsKey(thisSetupId))
                    // Check if the player model has data. Gear Knights, this is usually you.
                    {
                        // Add the model and texture(s)
                        ClothingBaseEffect clothingBaseEffect = item.ClothingBaseEffects[thisSetupId];
                        foreach (CloObjectEffect t in clothingBaseEffect.CloObjectEffects)
                        {
                            byte partNum = (byte)t.Index;
                            coverage.Add(partNum);

                            objDesc.AddAnimPartChange(new ACE.Entity.AnimationPartChange {
                                PartIndex = (byte)t.Index, PartID = t.ModelId
                            });

                            foreach (CloTextureEffect t1 in t.CloTextureEffects)
                            {
                                objDesc.AddTextureChange(new ACE.Entity.TextureMapChange {
                                    PartIndex = (byte)t.Index, OldTexture = t1.OldTexture, NewTexture = t1.NewTexture
                                });
                            }
                        }

                        if (item.ClothingSubPalEffects.Count > 0)
                        {
                            int size     = item.ClothingSubPalEffects.Count;
                            int palCount = size;

                            CloSubPalEffect itemSubPal;
                            int             palOption = 0;
                            if (w.PaletteTemplate.HasValue)
                            {
                                palOption = (int)w.PaletteTemplate;
                            }
                            if (item.ClothingSubPalEffects.ContainsKey((uint)palOption))
                            {
                                itemSubPal = item.ClothingSubPalEffects[(uint)palOption];
                            }
                            else
                            {
                                itemSubPal = item.ClothingSubPalEffects[item.ClothingSubPalEffects.Keys.ElementAt(0)];
                            }

                            float shade = 0;
                            if (w.Shade.HasValue)
                            {
                                shade = (float)w.Shade;
                            }
                            for (int i = 0; i < itemSubPal.CloSubPalettes.Count; i++)
                            {
                                var    itemPalSet = DatManager.PortalDat.ReadFromDat <PaletteSet>(itemSubPal.CloSubPalettes[i].PaletteSet);
                                ushort itemPal    = (ushort)itemPalSet.GetPaletteID(shade);

                                for (int j = 0; j < itemSubPal.CloSubPalettes[i].Ranges.Count; j++)
                                {
                                    uint palOffset = itemSubPal.CloSubPalettes[i].Ranges[j].Offset / 8;
                                    uint numColors = itemSubPal.CloSubPalettes[i].Ranges[j].NumColors / 8;
                                    objDesc.SubPalettes.Add(new ACE.Entity.SubPalette {
                                        SubID = itemPal, Offset = palOffset, NumColors = numColors
                                    });
                                }
                            }
                        }
                    }
                }
            }

            // Add the "naked" body parts. These are the ones not already covered.
            // Note that this is the original SetupTableId, not thisSetupId.
            if (SetupTableId > 0)
            {
                var baseSetup = DatManager.PortalDat.ReadFromDat <SetupModel>(SetupTableId);
                for (byte i = 0; i < baseSetup.Parts.Count; i++)
                {
                    if (!coverage.Contains(i) && i != 0x10) // Don't add body parts for those that are already covered. Also don't add the head, that was already covered by AddCharacterBaseModelData()
                    {
                        objDesc.AnimPartChanges.Add(new ACE.Entity.AnimationPartChange {
                            PartIndex = i, PartID = baseSetup.Parts[i]
                        });
                    }
                    //AddModel(i, baseSetup.Parts[i]);
                }
            }

            if (coverage.Count == 0 && ClothingBase.HasValue)
            {
                return(base.CalculateObjDesc());
            }

            return(objDesc);
        }
Esempio n. 4
0
        public override ACE.Entity.ObjDesc CalculateObjDesc()
        {
            ACE.Entity.ObjDesc objDesc = new ACE.Entity.ObjDesc();
            ClothingTable      item;

            AddBaseModelData(objDesc);

            var coverage = new List <uint>();

            foreach (var w in EquippedObjects.OrderBy(x => x.Value.Priority))
            {
                // We can wield things that are not part of our model, only use those items that can cover our model.
                if ((w.Value.CurrentWieldedLocation & (EquipMask.Clothing | EquipMask.Armor | EquipMask.Cloak)) != 0)
                {
                    if (w.Value.ClothingBase.HasValue)
                    {
                        item = DatManager.PortalDat.ReadFromDat <ClothingTable>((uint)w.Value.ClothingBase);
                    }
                    else
                    {
                        continue;
                    }

                    if (item.ClothingBaseEffects.ContainsKey(SetupTableId))
                    // Check if the player model has data. Gear Knights, this is usually you.
                    {
                        // Add the model and texture(s)
                        ClothingBaseEffect clothingBaseEffec = item.ClothingBaseEffects[SetupTableId];
                        foreach (CloObjectEffect t in clothingBaseEffec.CloObjectEffects)
                        {
                            byte partNum = (byte)t.Index;
                            objDesc.AnimPartChanges.Add(new ACE.Entity.AnimationPartChange {
                                PartIndex = (byte)t.Index, PartID = t.ModelId
                            });
                            //AddModel((byte)t.Index, (ushort)t.ModelId);
                            coverage.Add(partNum);
                            foreach (CloTextureEffect t1 in t.CloTextureEffects)
                            {
                                objDesc.TextureChanges.Add(new ACE.Entity.TextureMapChange {
                                    PartIndex = (byte)t.Index, OldTexture = t1.OldTexture, NewTexture = t1.NewTexture
                                });
                            }
                            //AddTexture((byte)t.Index, (ushort)t1.OldTexture, (ushort)t1.NewTexture);
                        }

                        if (item.ClothingSubPalEffects.Count > 0)
                        {
                            int size     = item.ClothingSubPalEffects.Count;
                            int palCount = size;

                            CloSubPalEffect itemSubPal;
                            int             palOption = 0;
                            if (w.Value.PaletteTemplate.HasValue)
                            {
                                palOption = (int)w.Value.PaletteTemplate;
                            }
                            if (item.ClothingSubPalEffects.ContainsKey((uint)palOption))
                            {
                                itemSubPal = item.ClothingSubPalEffects[(uint)palOption];
                            }
                            else
                            {
                                itemSubPal = item.ClothingSubPalEffects[item.ClothingSubPalEffects.Keys.ElementAt(0)];
                            }

                            //if (itemSubPal.Icon > 0)
                            //    IconId = itemSubPal.Icon;

                            float shade = 0;
                            if (w.Value.Shade.HasValue)
                            {
                                shade = (float)w.Value.Shade;
                            }
                            for (int i = 0; i < itemSubPal.CloSubPalettes.Count; i++)
                            {
                                var    itemPalSet = DatManager.PortalDat.ReadFromDat <PaletteSet>(itemSubPal.CloSubPalettes[i].PaletteSet);
                                ushort itemPal    = (ushort)itemPalSet.GetPaletteID(shade);

                                for (int j = 0; j < itemSubPal.CloSubPalettes[i].Ranges.Count; j++)
                                {
                                    uint palOffset = itemSubPal.CloSubPalettes[i].Ranges[j].Offset / 8;
                                    uint numColors = itemSubPal.CloSubPalettes[i].Ranges[j].NumColors / 8;
                                    objDesc.SubPalettes.Add(new ACE.Entity.SubPalette {
                                        SubID = itemPal, Offset = palOffset, NumColors = numColors
                                    });
                                    //AddPalette(itemPal, (ushort)palOffset, (ushort)numColors);
                                }
                            }
                        }
                    }
                }
            }

            // Add the "naked" body parts. These are the ones not already covered.
            if (SetupTableId > 0)
            {
                var baseSetup = DatManager.PortalDat.ReadFromDat <SetupModel>(SetupTableId);
                for (byte i = 0; i < baseSetup.Parts.Count; i++)
                {
                    if (!coverage.Contains(i) && i != 0x10) // Don't add body parts for those that are already covered. Also don't add the head, that was already covered by AddCharacterBaseModelData()
                    {
                        objDesc.AnimPartChanges.Add(new ACE.Entity.AnimationPartChange {
                            PartIndex = i, PartID = baseSetup.Parts[i]
                        });
                    }
                    //AddModel(i, baseSetup.Parts[i]);
                }
            }

            if (coverage.Count == 0 && ClothingBase.HasValue)
            {
                return(base.CalculateObjDesc());
            }

            return(objDesc);
        }