예제 #1
0
        /// <summary>
        /// Create a 1:1 Clone based on the CRES Name
        /// </summary>
        /// <param name="cres"></param>
        /// <returns></returns>
        public static SimPe.Packages.GeneratableFile CreatCloneByCres(string cres)
        {
            SimPe.Packages.GeneratableFile         package = SimPe.Packages.GeneratableFile.CreateNew();
            SimPe.Interfaces.IAlias                a;
            Interfaces.Files.IPackedFileDescriptor pfd;
            uint            localgroup;
            OWCloneSettings cs;

            ObjectWorkshopHelper.PrepareForClone(package, out a, out localgroup, out pfd, out cs);

            SimPe.PackedFiles.Wrapper.Str str = new SimPe.PackedFiles.Wrapper.Str();
            str.FileDescriptor              = new SimPe.Packages.PackedFileDescriptor();
            str.FileDescriptor.Type         = Data.MetaData.STRING_FILE;
            str.FileDescriptor.LongInstance = 0x85;
            str.FileDescriptor.Group        = 0x7F000000;
            package.Add(str.FileDescriptor);

            string name = cres.ToLower().Trim();

            if (!name.EndsWith("_cres"))
            {
                name += "_cres";
            }

            str.FileName = "Model - Names";
            str.Add(new SimPe.PackedFiles.Wrapper.StrToken(0, (byte)Data.MetaData.Languages.English, "", ""));
            str.Add(new SimPe.PackedFiles.Wrapper.StrToken(1, (byte)Data.MetaData.Languages.English, name, ""));
            str.SynchronizeUserData();

            str.FileDescriptor.MarkForDelete = true;

            return(ObjectWorkshopHelper.Start(package, a, ref pfd, localgroup, cs, true));
        }
예제 #2
0
        /// <summary>
        /// Load availabe lua resources from the FileSystem
        /// </summary>
        /// <param name="dir">The directory you want to scan</param>
        /// <param name="ext">The fiel extension to check</param>
        /// <param name="global">true, if this is a global LUA</param>
        /// <remarks>Instance of the loaded resources will be the hash over the FeleName</remarks>
        static void LoadFromFolder(string dir, string ext, bool global)
        {
            if (!System.IO.Directory.Exists(dir))
            {
                return;
            }

            string[] fls = System.IO.Directory.GetFiles(dir, "*." + ext);
            foreach (string fl in fls)
            {
                string name = System.IO.Path.GetFileName(fl);
                System.IO.BinaryWriter bw = new System.IO.BinaryWriter(new System.IO.MemoryStream());
                try
                {
                    bw.Write((int)0);
                    bw.Write((int)name.Length);
                    bw.Write(Helper.ToBytes(name, name.Length));

                    System.IO.FileStream   fs = System.IO.File.Open(fl, System.IO.FileMode.Open);
                    System.IO.BinaryReader br = new System.IO.BinaryReader(fs);
                    try
                    {
                        bw.Write(br.ReadBytes((int)br.BaseStream.Length));
                    }
                    finally
                    {
                        br.Close();
                        br = null;
                        fs.Close();
                        fs.Dispose();
                        fs = null;
                    }

                    br = new System.IO.BinaryReader(bw.BaseStream);
                    br.BaseStream.Seek(0, System.IO.SeekOrigin.Begin);

                    uint type = SimPe.Data.MetaData.OLUA;
                    if (global)
                    {
                        type = SimPe.Data.MetaData.GLUA;
                    }

                    SimPe.Interfaces.Files.IPackedFileDescriptor pfd = pkg.NewDescriptor(
                        type,
                        Hashes.SubTypeHash(name),
                        SimPe.Data.MetaData.LOCAL_GROUP,
                        Hashes.InstanceHash(name)
                        );

                    pfd.UserData = br.ReadBytes((int)br.BaseStream.Length);
                    pfd.Changed  = false;
                    pkg.Add(pfd);
                }
                finally
                {
                    bw.Close();
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Clone the Face of a Sim
        /// </summary>
        /// <returns>the new Package for the patient Sim</returns>
        public SimPe.Packages.GeneratableFile CloneFace()
        {
            SimPe.Packages.GeneratableFile ret = SimPe.Packages.GeneratableFile.LoadFromFile((string)null);



            ArrayList list = new ArrayList();

            list.Add((uint)0xCCCEF852);             //LxNR, Face

            uint hashgroup = this.GetPatientHash();


            foreach (Interfaces.Files.IPackedFileDescriptor pfd in archetype.Index)
            {
                if (list.Contains(pfd.Type))
                {
                    Interfaces.Files.IPackedFile fl = archetype.Read(pfd);

                    Interfaces.Files.IPackedFileDescriptor newpfd = ret.NewDescriptor(pfd.Type, pfd.SubType, pfd.Group, pfd.Instance);
                    newpfd.UserData = fl.UncompressedData;
                    ret.Add(newpfd);
                }
            }

            list.Add((uint)0xE86B1EEF);             //make sure the compressed Directory won't be copied!
            foreach (Interfaces.Files.IPackedFileDescriptor pfd in patient.Index)
            {
                if (!list.Contains(pfd.Type))
                {
                    Interfaces.Files.IPackedFile fl = patient.Read(pfd);

                    Interfaces.Files.IPackedFileDescriptor newpfd = ret.NewDescriptor(pfd.Type, pfd.SubType, pfd.Group, pfd.Instance);
                    newpfd.UserData = fl.UncompressedData;
                    ret.Add(newpfd);
                }
            }

            UpdateFaceStructure(ret);
            return(ret);
        }
예제 #4
0
        /// <summary>
        /// Clone the Makeup of a Sim
        /// </summary>
        /// <returns>the new Package for the patient Sim</returns>
        /// <param name="eyecolor">true, if you want to alter the eyecolor</param>
        /// <param name="makeups">true, if you want to alter the makeup</param>
        public SimPe.Packages.GeneratableFile CloneMakeup(bool eyecolor, bool makeups)
        {
            SimPe.Packages.GeneratableFile ret = SimPe.Packages.GeneratableFile.LoadFromFile((string)null);

            ArrayList list = new ArrayList();

            list.Add((uint)0xE86B1EEF);             //make sure the compressed Directory won't be copied!
            foreach (Interfaces.Files.IPackedFileDescriptor pfd in patient.Index)
            {
                if (!list.Contains(pfd.Type))
                {
                    Interfaces.Files.IPackedFile fl = patient.Read(pfd);

                    Interfaces.Files.IPackedFileDescriptor newpfd = ret.NewDescriptor(pfd.Type, pfd.SubType, pfd.Group, pfd.Instance);
                    newpfd.UserData = fl.UncompressedData;
                    ret.Add(newpfd);
                }
            }

            //Update TXMT Files for the Face
            SimPe.Interfaces.Files.IPackedFileDescriptor[] pfds = ret.FindFiles(Data.MetaData.TXMT);
            foreach (SimPe.Interfaces.Files.IPackedFileDescriptor pfd in pfds)
            {
                SimPe.Plugin.Rcol rcol = new GenericRcol(null, false);
                rcol.ProcessData(pfd, ret);

                MaterialDefinition md = (MaterialDefinition)rcol.Blocks[0];
                this.UpdateMakeup(md, eyecolor, makeups);

                rcol.SynchronizeUserData();
            }

            if (eyecolor)
            {
                //Update DNA File
                Interfaces.Files.IPackedFileDescriptor dna  = ngbh.FindFile(0xEBFEE33F, 0, Data.MetaData.LOCAL_GROUP, spatient.Instance);
                Interfaces.Files.IPackedFileDescriptor adna = ngbh.FindFile(0xEBFEE33F, 0, Data.MetaData.LOCAL_GROUP, sarchetype.Instance);
                if ((dna != null) && (adna != null))
                {
                    SimPe.PackedFiles.Wrapper.Cpf cpf = new Cpf();
                    cpf.ProcessData(dna, ngbh);

                    SimPe.PackedFiles.Wrapper.Cpf acpf = new Cpf();
                    acpf.ProcessData(adna, ngbh);
                    cpf.GetSaveItem("3").StringValue = acpf.GetSaveItem("3").StringValue;

                    cpf.SynchronizeUserData();
                }
            }
            return(ret);
        }
예제 #5
0
        /// <summary>
        /// Creates a Package File from a previously extracted Package
        /// </summary>
        /// <param name="filename">Filename of package.xml File describing the Package</param>
        /// <param name="pb">A Progressbar indicating the progress</param>
        /// <returns>Binary Reader representing the Package File</returns>
        public static System.IO.BinaryReader OpenExtractedPackage(ProgressBar pb, string filename)
        {
            string path = System.IO.Path.GetDirectoryName(filename);

            System.Xml.XmlDocument xmlfile = new XmlDocument();
            xmlfile.Load(filename);

            //Root Node suchen
            XmlNodeList XMLData = xmlfile.GetElementsByTagName("package");

            ArrayList list = new ArrayList();

            //Alle Eintr&auml;ge im Root Node verarbeiten
            Data.MetaData.IndexTypes type = Data.MetaData.IndexTypes.ptShortFileIndex;
            for (int i = 0; i < XMLData.Count; i++)
            {
                XmlNode node = XMLData.Item(i);

                object o = node.Attributes["type"].Value; if (o == null)
                {
                    o = "1";
                }
                type = (Data.MetaData.IndexTypes) uint.Parse(o.ToString());

                if (pb != null)
                {
                    pb.Maximum = node.ChildNodes.Count;
                }
                int count = 0;
                foreach (XmlNode subnode in node)
                {
                    if (pb != null)
                    {
                        pb.Value = count++;
                        System.Windows.Forms.Application.DoEvents();
                    }
                    ///a New FileItem
                    if (subnode.LocalName == "packedfile")
                    {
                        list.Add(CreateDescriptor(path, subnode));
                    }
                }
            }

            SimPe.Packages.GeneratableFile file = SimPe.Packages.GeneratableFile.CreateNew();
            file.BeginUpdate();
            file.Header.IndexType = type;

            foreach (SimPe.Packages.PackedFileDescriptor pfd in list)
            {
                file.Add(pfd);
                if (pfd.Type == Packages.File.FILELIST_TYPE)
                {
                    file.FileList = pfd;
                }
            }

            System.IO.MemoryStream ms = file.Build();
            file.EndUpdate();
            if (pb != null)
            {
                pb.Value = pb.Maximum;
            }
            return(new System.IO.BinaryReader(ms));
        }
예제 #6
0
        /// <summary>
        /// Create a cloned Sim
        /// </summary>
        /// <returns>the new Package for the patient Sim</returns>
        public SimPe.Packages.GeneratableFile CloneSim()
        {
            SimPe.Packages.GeneratableFile ret = SimPe.Packages.GeneratableFile.LoadFromFile((string)null);



            ArrayList list = new ArrayList();

            list.Add((uint)0xAC506764);             //3IDR
            list.Add(Data.MetaData.GZPS);           //GZPS, Property Set
            list.Add((uint)0xAC598EAC);             //AGED
            list.Add((uint)0xCCCEF852);             //LxNR, Face
            list.Add((uint)0x856DDBAC);             //IMG
            list.Add((uint)0x534C4F54);             //SLOT
            list.AddRange(Data.MetaData.RcolList);

            uint hashgroup = this.GetPatientHash();


            foreach (Interfaces.Files.IPackedFileDescriptor pfd in archetype.Index)
            {
                if (list.Contains(pfd.Type))
                {
                    Interfaces.Files.IPackedFile fl = archetype.Read(pfd);

                    Interfaces.Files.IPackedFileDescriptor newpfd = ret.NewDescriptor(pfd.Type, pfd.SubType, pfd.Group, pfd.Instance);
                    newpfd.UserData = fl.UncompressedData;
                    ret.Add(newpfd);

                    ///This is a scenegraph Resource and needs a new Hash
                    if (Data.MetaData.RcolList.Contains(pfd.Type))
                    {
                        SimPe.Plugin.Rcol rcol = new GenericRcol(null, false);
                        rcol.ProcessData(newpfd, ret);

                        rcol.FileName = "#0x" + Helper.HexString(hashgroup) + "!" + Hashes.StripHashFromName(rcol.FileName);

                        switch (pfd.Type)
                        {
                        case Data.MetaData.SHPE:
                        {
                            Shape shp = (Shape)rcol.Blocks[0];
                            foreach (ShapeItem i in shp.Items)
                            {
                                i.FileName = "#0x" + Helper.HexString(hashgroup) + "!" + Hashes.StripHashFromName(i.FileName);
                            }
                            break;
                        }
                        }
                        rcol.SynchronizeUserData();
                    }
                }
            }

            list.Add((uint)0xE86B1EEF);             //make sure the compressed Directory won't be copied!
            foreach (Interfaces.Files.IPackedFileDescriptor pfd in patient.Index)
            {
                if (!list.Contains(pfd.Type))
                {
                    Interfaces.Files.IPackedFile fl = patient.Read(pfd);

                    Interfaces.Files.IPackedFileDescriptor newpfd = ret.NewDescriptor(pfd.Type, pfd.SubType, pfd.Group, pfd.Instance);
                    newpfd.UserData = fl.UncompressedData;
                    ret.Add(newpfd);
                }
            }

            //Copy DNA File
            Interfaces.Files.IPackedFileDescriptor dna = ngbh.FindFile(0xEBFEE33F, 0, Data.MetaData.LOCAL_GROUP, sarchetype.Instance);
            if (dna != null)
            {
                Interfaces.Files.IPackedFileDescriptor tna = ngbh.FindFile(0xEBFEE33F, 0, Data.MetaData.LOCAL_GROUP, spatient.Instance);
                if (tna == null)
                {
                    tna         = ngbh.NewDescriptor(0xEBFEE33F, 0, Data.MetaData.LOCAL_GROUP, spatient.Instance);
                    tna.Changed = true;
                    ngbh.Add(tna);
                }

                Interfaces.Files.IPackedFile fl = ngbh.Read(dna);

                tna.UserData = fl.UncompressedData;
            }

            UpdateFaceStructure(ret);
            return(ret);
        }
예제 #7
0
        /// <summary>
        /// Change the SkinTone of a Sim
        /// </summary>
        /// <param name="skin">the new skintone</param>
        /// param name="skinfiles">a Hashtable listing al Proerty Sets for each available skintone (key=skintone string, value= ArrayList of Cpf Objects)</param>
        /// <returns>the new Package for the patient Sim</returns>
        public SimPe.Packages.GeneratableFile CloneSkinTone(string skin, Hashtable skinfiles)
        {
            SimPe.Packages.GeneratableFile ret = SimPe.Packages.GeneratableFile.LoadFromFile((string)null);
            string pskin = GetSkintone(this.patient);

            ArrayList list = new ArrayList();

            list.Add((uint)0xE86B1EEF);             //make sure the compressed Directory won't be copied!
            foreach (Interfaces.Files.IPackedFileDescriptor pfd in patient.Index)
            {
                if (!list.Contains(pfd.Type))
                {
                    Interfaces.Files.IPackedFile fl = patient.Read(pfd);

                    Interfaces.Files.IPackedFileDescriptor newpfd = ret.NewDescriptor(pfd.Type, pfd.SubType, pfd.Group, pfd.Instance);
                    newpfd.UserData = fl.UncompressedData;
                    ret.Add(newpfd);

                    switch (newpfd.Type)
                    {
                    case (uint)0xAC598EAC:                             //AGED
                    {
                        SimPe.PackedFiles.Wrapper.Cpf cpf = new Cpf();
                        cpf.ProcessData(newpfd, ret);
                        cpf.GetSaveItem("skincolor").StringValue = skin;

                        cpf.SynchronizeUserData();
                        break;
                    }

                    case Data.MetaData.GZPS:
                    {
                        SimPe.PackedFiles.Wrapper.Cpf cpf = new Cpf();
                        cpf.ProcessData(newpfd, ret);
                        cpf.GetSaveItem("skintone").StringValue = skin;

                        cpf.SynchronizeUserData();
                        break;
                    }

                    case Data.MetaData.TXMT:
                    {
                        SimPe.Plugin.Rcol rcol = new GenericRcol(null, false);
                        rcol.ProcessData(newpfd, ret);
                        MaterialDefinition txmt = (MaterialDefinition)rcol.Blocks[0];
                        txmt.FindProperty("cafSkinTone").Value = skin;

                        rcol.SynchronizeUserData();
                        break;
                    }
                    }
                }
            }

            //Update DNA File
            Interfaces.Files.IPackedFileDescriptor dna = ngbh.FindFile(0xEBFEE33F, 0, Data.MetaData.LOCAL_GROUP, spatient.Instance);
            if (dna != null)
            {
                SimPe.PackedFiles.Wrapper.Cpf cpf = new Cpf();
                cpf.ProcessData(dna, ngbh);
                cpf.GetSaveItem("2").StringValue = skin;
                cpf.GetSaveItem("6").StringValue = skin;

                cpf.SynchronizeUserData();
            }

            //Update 3IDR Files
            SimPe.Interfaces.Files.IPackedFileDescriptor[] pfds = ret.FindFiles(0xAC506764);
            foreach (SimPe.Interfaces.Files.IPackedFileDescriptor pfd in pfds)
            {
                SimPe.Plugin.RefFile reffile = new RefFile();
                reffile.ProcessData(pfd, ret);

                UpdateSkintone(reffile, skin, skinfiles);
            }

            //Update TXMT Files for the Face
            pfds = ret.FindFiles(Data.MetaData.TXMT);
            foreach (SimPe.Interfaces.Files.IPackedFileDescriptor pfd in pfds)
            {
                SimPe.Plugin.Rcol rcol = new GenericRcol(null, false);
                rcol.ProcessData(pfd, ret);

                MaterialDefinition md = (MaterialDefinition)rcol.Blocks[0];
                this.UpdateSkintone(md, skin, skinfiles);

                rcol.SynchronizeUserData();
            }


            return(ret);
        }
예제 #8
0
        /// <summary>
        /// Clone an object based on way Files are linked
        /// </summary>
        /// <param name="pfd"></param>
        /// <param name="localgroup"></param>
        /// <param name="onlydefault"></param>
        protected static SimPe.Packages.GeneratableFile RecolorClone(CloneSettings.BaseResourceType br, SimPe.Packages.GeneratableFile ppkg, Interfaces.Files.IPackedFileDescriptor pfd, uint localgroup, ObjectWorkshopSettings settings, bool pkgcontainsonlybase)
        {
            SimPe.Packages.GeneratableFile package = null;
            if (ppkg != null)
            {
                package = (SimPe.Packages.GeneratableFile)ppkg.Clone();
            }
            if (ppkg == null || pkgcontainsonlybase)
            {
                if (!pkgcontainsonlybase)
                {
                    package = SimPe.Packages.GeneratableFile.CreateNew();
                }
                //Get the Base Object Data from the Objects.package File
                string[] modelname = new string[0];
                if (br == CloneSettings.BaseResourceType.Objd)
                {
                    modelname = BaseClone(localgroup, package, pkgcontainsonlybase);
                }
                else
                {
                    SimPe.Interfaces.Scenegraph.IScenegraphFileIndexItem[] fii = FileTable.FileIndex.FindFile(pfd, null);
                    if (fii.Length > 0)
                    {
                        SimPe.Interfaces.Files.IPackedFileDescriptor cpfd = fii[0].FileDescriptor.Clone();
                        cpfd          = cpfd.Clone();
                        cpfd.UserData = fii[0].Package.Read(fii[0].FileDescriptor).UncompressedData;
                        package.Add(cpfd);
                    }
                }
                ObjectCloner objclone = new ObjectCloner(package);
                ArrayList    exclude  = new ArrayList();



                //allways for recolors
                if (settings is OWRecolorSettings)
                {
                    exclude.Add("stdMatEnvCubeTextureName");
                    exclude.Add("TXTR");
                }
                else
                {
                    exclude.Add("tsMaterialsMeshName");
                    exclude.Add("TXTR");
                    exclude.Add("stdMatEnvCubeTextureName");
                }

                //do the recolor
                objclone.Setup = settings;
                objclone.Setup.BaseResource     = br;
                objclone.Setup.OnlyDefaultMmats = (settings.OnlyDefaultMmats && br != CloneSettings.BaseResourceType.Xml);
                objclone.Setup.UpdateMmatGuids  = objclone.Setup.OnlyDefaultMmats;

                /*objclone.Setup.IncludeWallmask = settings.IncludeWallmask;
                 * objclone.Setup.IncludeAnimationResources = settings.IncludeAnimationResources;
                 * objclone.Setup.KeepOriginalMesh = settings.KeepOriginalMesh;
                 * objclone.Setup.PullResourcesByStr = settings.PullResourcesByStr;
                 * objclone.Setup.StrInstances = settings.StrInstances;*/


                objclone.RcolModelClone(modelname, exclude);

                //for clones only when cbparent is checked
                if (settings is OWCloneSettings)
                {
                    if (((OWCloneSettings)settings).StandAloneObject || br == CloneSettings.BaseResourceType.Xml)
                    {
                        string[]            names = Scenegraph.LoadParentModelNames(package, true);
                        SimPe.Packages.File pkg   = SimPe.Packages.File.LoadFromFile(null);

                        ObjectCloner pobj = new ObjectCloner(pkg);
                        pobj.Setup = settings;
                        pobj.Setup.BaseResource     = br;
                        pobj.Setup.OnlyDefaultMmats = (settings.OnlyDefaultMmats && br != CloneSettings.BaseResourceType.Xml);;
                        pobj.Setup.UpdateMmatGuids  = pobj.Setup.OnlyDefaultMmats;

                        /*pobj.Setup.IncludeWallmask = settings.IncludeWallmask;
                         * pobj.Setup.IncludeAnimationResources = settings.IncludeAnimationResources;
                         * pobj.Setup.KeepOriginalMesh = settings.KeepOriginalMesh;
                         * pobj.Setup.PullResourcesByStr = settings.PullResourcesByStr;
                         * pobj.Setup.StrInstances = settings.StrInstances;*/


                        pobj.RcolModelClone(names, exclude);
                        pobj.AddParentFiles(modelname, package);
                    }
                    else
                    {
                        string[] modelnames = modelname;
                        if (!((OWCloneSettings)settings).RemoveUselessResource)
                        {
                            modelnames = null;
                        }
                        objclone.RemoveSubsetReferences(Scenegraph.GetParentSubsets(package), modelnames);
                    }
                }
            }

            return(package);
        }
예제 #9
0
 protected void AddToFileIndex(SimPe.Packages.GeneratableFile file, SimPe.Packages.PackedFileDescriptor pfd)
 {
     file.Add(pfd);
 }
예제 #10
0
        /// <summary>
        /// This will build a SkinTone Replacement for the passed Skintone
        /// </summary>
        /// <param name="skintone">the skintone string</param>
        /// <param name="addtxtr">true, if you want to replace the default TXTR Files</param>
        /// <param name="addtxmt">true if you want to replace the default TXMT Files</param>
        /// <param name="sitem"></param>
        /// <param name="src"></param>
        /// <returns>the replacement package</returns>
        public SimPe.Packages.GeneratableFile BuildOverride(ScannerItem sitem, string skintone, string family, SimPe.Interfaces.Files.IPackageFile src, bool addtxmt, bool addtxtr, bool addref)
        {
            FileTable.FileIndex.Load();
            SimPe.Packages.GeneratableFile pkg = SimPe.Packages.GeneratableFile.LoadFromStream((System.IO.BinaryReader)null);

            WaitingScreen.Wait();
            //Save the old FileTable and the source File
            FileTable.FileIndex.Load();
            FileTable.FileIndex.StoreCurrentState();
            FileTable.FileIndex.AddIndexFromPackage(src);

            bool usefam = (skintone == "00000000-0000-0000-0000-000000000000");

            try
            {
                //find al description Files that belong to the Skintone that should be replaced
                ArrayList basecpf = new ArrayList();

                SimPe.Interfaces.Scenegraph.IScenegraphFileIndexItem[] items = FileTable.FileIndex.FindFile(Data.MetaData.GZPS, true);
                foreach (SimPe.Interfaces.Scenegraph.IScenegraphFileIndexItem item in items)
                {
                    SimPe.PackedFiles.Wrapper.Cpf cpf = new Cpf();
                    cpf.ProcessData(item);

                    if (cpf.GetSaveItem("skintone").StringValue != skintone)
                    {
                        continue;
                    }
                    //if (usefam)
                    if (cpf.GetSaveItem("family").StringValue != family)
                    {
                        continue;
                    }
                    if (cpf.GetSaveItem("type").StringValue != "skin")
                    {
                        continue;
                    }

                    SimPe.Plugin.SkinChain sc = new SkinChain(cpf);
                    basecpf.Add(sc);
                    WaitingScreen.UpdateMessage(cpf.GetSaveItem("name").StringValue);
                }

                ArrayList compare = new ArrayList();
                compare.Add("age");
                //compare.Add("category");
                compare.Add("fitness");
                compare.Add("gender");
                //compare.Add("outfit");
                compare.Add("override0subset");
                //compare.Add("override0resourcekeyidx");
                //compare.Add("shapekeyidx");

                //now select matching Files
                Interfaces.Files.IPackedFileDescriptor[] pfds = src.FindFiles(Data.MetaData.GZPS);

#if DEBUG
                //we could add Debug Code here to see which cpfs were pulled :)

                /*SimPe.Packages.GeneratableFile f = SimPe.Packages.GeneratableFile.CreateNew();
                 *
                 * foreach (SimPe.Plugin.SkinChain sc in basecpf)
                 * {
                 *      sc.Cpf.SynchronizeUserData();
                 *      f.Add(sc.Cpf.FileDescriptor);
                 *
                 *      RefFile r = sc.ReferenceFile;
                 *      if (r!=null)
                 *      {
                 *              r.SynchronizeUserData();
                 *              f.Add(r.FileDescriptor);
                 *      }
                 *
                 *      //foreach (GenericRcol rcol in sc.TXTRs)
                 *      GenericRcol rcol = sc.TXTR;
                 *              if (rcol!=null)
                 *              {
                 *                      rcol.SynchronizeUserData();
                 *                      f.Add(rcol.FileDescriptor);
                 *              }
                 *
                 *      //foreach (GenericRcol rcol in sc.TXMTs)
                 *      rcol = sc.TXMT;
                 *              if (rcol!=null)
                 *              {
                 *                      rcol.SynchronizeUserData();
                 *                      f.Add(rcol.FileDescriptor);
                 *              }
                 * }
                 *
                 * f.Save(@"G:\skinbase.package");
                 * return f;*/
#endif
                foreach (Interfaces.Files.IPackedFileDescriptor pfd in pfds)
                {
                    //load a description File for the new Skintone
                    SimPe.PackedFiles.Wrapper.Cpf cpf = new Cpf();
                    cpf.ProcessData(pfd, src);

                    int index    = -1;
                    int maxpoint = 0;
                    //check if File is a match
                    for (int i = 0; i < basecpf.Count; i++)
                    {
                        SimPe.Plugin.SkinChain sc = (SimPe.Plugin.SkinChain)basecpf[i];
                        int point = compare.Count;
                        //scan for valid CPF Files
                        foreach (string s in compare)
                        {
                            if (s == "age" || s == "category" || s == "outfit")
                            {
                                if ((sc.Cpf.GetSaveItem(s).UIntegerValue & cpf.GetSaveItem(s).UIntegerValue) == 0)
                                {
                                    point--;
                                }
                            }
                            else if (s == "override0subset")
                            {
                                string s1 = sc.Cpf.GetSaveItem(s).StringValue.Trim().ToLower();
                                string s2 = cpf.GetSaveItem(s).StringValue.Trim().ToLower();

                                if (s1 == "bottom")
                                {
                                    s1 = "body";
                                }
                                else if (s1 == "top")
                                {
                                    s1 = "body";
                                }
                                if (s2 == "bottom")
                                {
                                    s2 = "body";
                                }
                                else if (s2 == "top")
                                {
                                    s2 = "body";
                                }

                                if (s1 != s2)
                                {
                                    point--;
                                }
                            }
                            else if (sc.Cpf.GetSaveItem(s).UIntegerValue != cpf.GetSaveItem(s).UIntegerValue)
                            {
                                point--;
                            }
                        }

                        if (point > maxpoint)
                        {
                            index    = i;
                            maxpoint = point;
                        }
                    }



                    //yes, yes :D this is a match
                    if (index >= 0 && maxpoint == compare.Count)
                    {
                        SimPe.Plugin.SkinChain sc = (SimPe.Plugin.SkinChain)basecpf[index];

                        SkinChain newsc = new SkinChain(cpf);

                        if (sc.ReferenceFile != null && newsc.ReferenceFile != null && addref)
                        {
                            RefFile r = newsc.ReferenceFile;
                            r.FileDescriptor = sc.ReferenceFile.FileDescriptor.Clone();

                            r.SynchronizeUserData();
                            if (pkg.FindFile(r.FileDescriptor) == null)
                            {
                                pkg.Add(r.FileDescriptor);
                            }
                        }

                        if (sc.TXTR != null && newsc.TXTR != null && addtxtr)
                        {
                            SimPe.Plugin.GenericRcol txtr = newsc.TXTR;
                            txtr.FileDescriptor = sc.TXTR.FileDescriptor.Clone();
#if DEBUG
#else
                            txtr.FileDescriptor.MarkForReCompress = true;
#endif

                            txtr.FileName = sc.TXTR.FileName;

                            txtr.SynchronizeUserData();
                            if (pkg.FindFile(txtr.FileDescriptor) == null)
                            {
                                pkg.Add(txtr.FileDescriptor);
                            }
                        }

                        if (sc.TXMT != null && newsc.TXMT != null && addtxmt)
                        {
                            SimPe.Plugin.GenericRcol txmt = newsc.TXMT;
                            txmt.FileDescriptor = sc.TXMT.FileDescriptor.Clone();
#if DEBUG
#else
                            txmt.FileDescriptor.MarkForReCompress = true;
#endif

                            MaterialDefinition md    = (MaterialDefinition)txmt.Blocks[0];
                            MaterialDefinition mdorg = (MaterialDefinition)sc.TXMT.Blocks[0];
                            txmt.FileName      = sc.TXMT.FileName;
                            md.FileDescription = mdorg.FileDescription;

                            txmt.SynchronizeUserData();
                            if (pkg.FindFile(txmt.FileDescriptor) == null)
                            {
                                pkg.Add(txmt.FileDescriptor);
                            }
                        }
                    }
                }

                SimPe.PackedFiles.Wrapper.Str str = new Str();
                str.Add(new StrToken(0, 0, "SimPE Skin Override: " + skintone + " (from " + sitem.PackageCacheItem.Name + ")", ""));

                str.FileDescriptor              = new SimPe.Packages.PackedFileDescriptor();
                str.FileDescriptor.Type         = Data.MetaData.STRING_FILE;
                str.FileDescriptor.Group        = Data.MetaData.LOCAL_GROUP;
                str.FileDescriptor.LongInstance = 0;

                str.SynchronizeUserData();
                pkg.Add(str.FileDescriptor);
            }
            finally
            {
                //restore the Previous FileTable
                FileTable.FileIndex.RestoreLastState();
                WaitingScreen.Stop();
            }

            return(pkg);
        }