public void SetYmapHasChanged(YmapFile ymap, bool changed)
 {
     if (ProjectTreeView.Nodes.Count > 0)
     {
         var pnode  = ProjectTreeView.Nodes[0];
         var ymnode = GetChildTreeNode(pnode, "Ymap");
         if (ymnode == null)
         {
             return;
         }
         string changestr = changed ? "*" : "";
         for (int i = 0; i < ymnode.Nodes.Count; i++)
         {
             var ynode = ymnode.Nodes[i];
             if (ynode.Tag == ymap)
             {
                 string name = ymap.Name;
                 if (ymap.RpfFileEntry != null)
                 {
                     name = ymap.RpfFileEntry.Name;
                 }
                 ynode.Text = changestr + name;
                 break;
             }
         }
     }
 }
Example #2
0
        public void LoadMeta(YmapFile ymap)
        {
            string fn;

            Xml      = MetaXml.GetXml(ymap, out fn);
            FileName = fn;
            RawPropertyGrid.SelectedObject = ymap;
            rpfFileEntry = ymap?.RpfFileEntry;
            modified     = false;
            metaFormat   = MetaFormat.XML;
            if (ymap != null)
            {
                if (ymap.Meta != null)
                {
                    metaFormat = MetaFormat.RSC;
                }
                if (ymap.Pso != null)
                {
                    metaFormat = MetaFormat.PSO;
                }
                if (ymap.Rbf != null)
                {
                    metaFormat = MetaFormat.RBF;
                }
            }
        }
Example #3
0
 public void SetYmap(YmapFile ymap)
 {
     Ymap = ymap;
     Tag  = ymap;
     UpdateFormTitle();
     UpdateYmapUI();
     waschanged = ymap?.HasChanged ?? false;
 }
Example #4
0
        public void LoadMeta(YmapFile ymap)
        {
            string fn;

            Xml      = MetaXml.GetXml(ymap, out fn);
            FileName = fn;
            RawPropertyGrid.SelectedObject = ymap;
            modified = false;
        }
Example #5
0
 public bool ContainsYmap(YmapFile ymap)
 {
     foreach (var f in YmapFiles)
     {
         if (f == ymap)
         {
             return(true);
         }
     }
     return(false);
 }
        private void LoadYmapTreeNodes(YmapFile ymap, TreeNode node)
        {
            if (ymap == null)
            {
                return;
            }

            if (!string.IsNullOrEmpty(node.Name))
            {
                return;                                   //named nodes are eg Entities and CarGens
            }
            node.Nodes.Clear();

            if ((ymap.AllEntities != null) && (ymap.AllEntities.Length > 0))
            {
                var entsnode = node.Nodes.Add("Entities (" + ymap.AllEntities.Length.ToString() + ")");
                entsnode.Name = "Entities";
                entsnode.Tag  = ymap;
                var ents = ymap.AllEntities;
                for (int i = 0; i < ents.Length; i++)
                {
                    var ent   = ents[i];
                    var edef  = ent.CEntityDef;
                    var enode = entsnode.Nodes.Add(edef.archetypeName.ToString());
                    enode.Tag = ent;
                }
            }
            if ((ymap.CarGenerators != null) && (ymap.CarGenerators.Length > 0))
            {
                var cargensnode = node.Nodes.Add("Car Generators (" + ymap.CarGenerators.Length.ToString() + ")");
                cargensnode.Name = "CarGens";
                cargensnode.Tag  = ymap;
                var cargens = ymap.CarGenerators;
                for (int i = 0; i < cargens.Length; i++)
                {
                    var cargen  = cargens[i];
                    var ccgnode = cargensnode.Nodes.Add(cargen.ToString());
                    ccgnode.Tag = cargen;
                }
            }
            if ((ymap.GrassInstanceBatches != null) && (ymap.GrassInstanceBatches.Length > 0))
            {
                var grassbatchesnodes = node.Nodes.Add("Grass Batches (" + ymap.GrassInstanceBatches.Length.ToString() + ")");
                grassbatchesnodes.Name = "GrassBatches";
                grassbatchesnodes.Tag  = ymap;
                var grassbatches = ymap.GrassInstanceBatches;
                for (int i = 0; i < grassbatches.Length; i++)
                {
                    var batch  = grassbatches[i];
                    var gbnode = grassbatchesnodes.Nodes.Add(batch.ToString());
                    gbnode.Tag = batch;
                }
            }
        }
Example #7
0
        public bool AddYmapFile(YmapFile ymap)
        {
            string relpath = GetRelativePath(ymap.FilePath);

            if (string.IsNullOrEmpty(relpath))
            {
                relpath = ymap.Name;
            }
            if (YmapFilenames.Contains(relpath))
            {
                return(false);
            }
            YmapFilenames.Add(relpath);
            YmapFiles.Add(ymap);
            return(true);
        }
Example #8
0
        public void RemoveYmapFile(YmapFile ymap)
        {
            if (ymap == null)
            {
                return;
            }
            var relpath = GetRelativePath(ymap.FilePath);

            if (string.IsNullOrEmpty(relpath))
            {
                relpath = ymap.Name;
            }
            YmapFiles.Remove(ymap);
            YmapFilenames.Remove(relpath);
            HasChanged = true;
        }
Example #9
0
        public YmapFile AddYmapFile(string filename)
        {
            YmapFile ymap = new YmapFile();

            ymap.RpfFileEntry      = new RpfResourceFileEntry();
            ymap.RpfFileEntry.Name = new FileInfo(filename).Name;
            ymap.FilePath          = GetFullFilePath(filename);
            ymap.Name = ymap.RpfFileEntry.Name;
            JenkIndex.Ensure(ymap.Name);
            JenkIndex.Ensure(Path.GetFileNameWithoutExtension(ymap.Name));
            JenkIndex.Ensure(filename);
            if (!AddYmapFile(ymap))
            {
                return(null);
            }
            return(ymap);
        }
Example #10
0
        public void LoadMeta(YmapFile ymap)
        {
            var fn = (ymap?.RpfFileEntry?.Name) ?? "";

            if (ymap.Meta != null)
            {
                LoadMeta(ymap.Meta); fn += ".xml";
            }
            else if (ymap.Pso != null)
            {
                LoadMeta(ymap.Pso); fn += ".pso.xml";
            }
            else if (ymap.Rbf != null)
            {
                LoadMeta(ymap.Rbf); fn += ".rbf.xml";
            }
            FileName = fn;
            RawPropertyGrid.SelectedObject = ymap;
        }
        private void CentreButton_Click(object sender, EventArgs e)
        {
            string filename = mainForm.CurrentListBox;

            if (!string.IsNullOrEmpty(filename))
            {
                YmapFile ymap = new YmapFile();
                ymap.Load(File.ReadAllBytes(filename));

                Vector3 extentMin = ymap.CMapData.entitiesExtentsMin;
                Vector3 extentMax = ymap.CMapData.entitiesExtentsMax;

                Vector3 centrepoint = new Vector3((extentMin.X + extentMax.X) / 2, (extentMin.Y + extentMax.Y) / 2, (extentMin.Z + extentMax.Z) / 2);
                vector1.Text = centrepoint.X + ", " + centrepoint.Y + ", " + centrepoint.Z;
            }
            else
            {
                MessageBox.Show("You don't seem to have a ymap selected on the Main Form.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
Example #12
0
        private void startButton_Click(object sender, EventArgs e)
        {
            if (ymapLocationText.Text != null)
            {
                string   filename = ymapLocationText.Text;
                YmapFile ymap     = new YmapFile();
                ymap.Load(File.ReadAllBytes(filename));

                if (ymap.AllEntities != null)
                {
                    foreach (YmapEntityDef yEnts in ymap.AllEntities)
                    {
                        if (yEnts.IsMlo)
                        {
                            long outputNumber = (long.Parse(yEnts.Name) ^ (long)Math.Floor(yEnts.Position.X * 100) ^ (long)Math.Floor(yEnts.Position.Y * 100) ^ (long)Math.Floor(yEnts.Position.Z * 100)) & 0xffffffff;
                            generatedHashText.Text = outputNumber.ToString();
                        }
                    }
                }
            }
        }
Example #13
0
        public TreeNode FindYmapTreeNode(YmapFile ymap)
        {
            if (ProjectTreeView.Nodes.Count <= 0)
            {
                return(null);
            }
            var projnode  = ProjectTreeView.Nodes[0];
            var ymapsnode = GetChildTreeNode(projnode, "Ymap");

            if (ymapsnode == null)
            {
                return(null);
            }
            for (int i = 0; i < ymapsnode.Nodes.Count; i++)
            {
                var ymapnode = ymapsnode.Nodes[i];
                if (ymapnode.Tag == ymap)
                {
                    return(ymapnode);
                }
            }
            return(null);
        }
Example #14
0
        static void HandleFindPropsOptions(string[] args)
        {
            CommandLine.Parse <FindPropsOptions>(args, (opts, gOpts) =>
            {
                if (opts.Position == null || opts.Position.Count != 3)
                {
                    Console.Error.WriteLine("Please provide position with --position x,y,z");
                    return;
                }

                var position   = new Vector3(opts.Position[0], opts.Position[1], opts.Position[2]);
                var inputFiles = Utils.Expand(opts.InputFiles);

                for (int i = 0; i < inputFiles.Length; i++)
                {
                    var fileInfo = inputFiles[i];

                    if (fileInfo.Name.EndsWith(".ymap"))
                    {
                        var ymap = new YmapFile();

                        ymap.Load(fileInfo.FullName);

                        for (int j = 0; j < ymap.CMapData.Entities.Count; j++)
                        {
                            var entity     = ymap.CMapData.Entities[j];
                            float distance = Vector3.Distance(position, entity.Position);

                            if (distance <= opts.Radius)
                            {
                                Console.WriteLine(fileInfo.Name + " => " + entity.Guid);
                            }
                        }
                    }
                }
            });
        }
Example #15
0
        private void GenerateButton_Click(object sender, EventArgs e)
        {
            //var space = ProjectForm?.WorldForm?.Space;
            //if (space == null) return;
            var gameFileCache = ProjectForm?.WorldForm?.GameFileCache;

            if (gameFileCache == null)
            {
                return;
            }

            var path = ProjectForm.CurrentProjectFile.GetFullFilePath("lodlights") + "\\";

            GenerateButton.Enabled = false;


            List <YmapFile> projectYmaps = ProjectForm.CurrentProjectFile.YmapFiles;

            var pname = NameTextBox.Text;

            Task.Run(() =>
            {
                var lights = new List <Light>();

                foreach (var ymap in projectYmaps)
                {
                    if (ymap?.AllEntities == null)
                    {
                        continue;
                    }
                    foreach (var ent in ymap.AllEntities)
                    {
                        if (ent.Archetype == null)
                        {
                            continue;
                        }

                        bool waiting = false;
                        var dwbl     = gameFileCache.TryGetDrawable(ent.Archetype, out waiting);
                        while (waiting)
                        {
                            dwbl = gameFileCache.TryGetDrawable(ent.Archetype, out waiting);
                            UpdateStatus("Waiting for " + ent.Archetype.AssetName + " to load...");
                            Thread.Sleep(20);
                        }
                        UpdateStatus("Adding lights from " + ent.Archetype.Name + "...");
                        if (dwbl != null)
                        {
                            var fphys = (dwbl as FragDrawable)?.OwnerFragmentPhys;

                            ent.EnsureLights(dwbl);
                            var elights = ent.Lights;
                            if (elights != null)
                            {
                                for (int li = 0; li < elights.Length; li++)
                                {
                                    var elight = elights[li];
                                    var la     = elight.Attributes;

                                    uint r = la.ColorR;
                                    uint g = la.ColorG;
                                    uint b = la.ColorB;
                                    uint i = (byte)Math.Max(Math.Min(Math.Round(la.Intensity * 5.3125f), 255), 0);//5.1=255/48
                                    uint c = (i << 24) + (r << 16) + (g << 8) + b;
                                    uint h = elight.Hash;


                                    //any other way to know if it's a streetlight?
                                    //var name = ent.Archetype.Name;
                                    var flags          = la.Flags;
                                    bool isStreetLight = (((flags >> 10) & 1u) == 1); // (name != null) && (name.Contains("street") || name.Contains("traffic"));
                                    isStreetLight      = false;                       //TODO: fix this!


                                    //@Calcium:
                                    //1 = point
                                    //2 = spot
                                    //4 = capsule
                                    uint type = (uint)la.Type;
                                    uint unk  = isStreetLight ? 1u : 0;//2 bits - isStreetLight low bit, unk high bit
                                    uint t    = la.TimeFlags | (type << 26) | (unk << 24);

                                    var inner = (byte)Math.Round(la.ConeInnerAngle * 1.4117647f);
                                    var outer = (byte)Math.Round(la.ConeOuterAngle * 1.4117647f);
                                    if (type == 4)
                                    {
                                        outer = (byte)Math.Max(Math.Max(la.Extent.X, la.Extent.Y), la.Extent.Z);
                                    }


                                    var light                    = new Light();
                                    light.position               = new MetaVECTOR3(elight.Position);
                                    light.colour                 = c;
                                    light.direction              = new MetaVECTOR3(elight.Direction);
                                    light.falloff                = la.Falloff;
                                    light.falloffExponent        = la.FalloffExponent;
                                    light.timeAndStateFlags      = t;
                                    light.hash                   = h;
                                    light.coneInnerAngle         = inner;
                                    light.coneOuterAngleOrCapExt = outer;
                                    light.coronaIntensity        = (byte)(la.CoronaIntensity * 6);
                                    light.isStreetLight          = isStreetLight;
                                    lights.Add(light);
                                }
                            }
                        }
                    }
                }


                if (lights.Count == 0)
                {
                    MessageBox.Show("No lights found in project!");
                    return;
                }



                //final lights should be sorted by isStreetLight (1 first!) and then hash
                lights.Sort((a, b) =>
                {
                    if (a.isStreetLight != b.isStreetLight)
                    {
                        return(b.isStreetLight.CompareTo(a.isStreetLight));
                    }
                    return(a.hash.CompareTo(b.hash));
                });



                var position          = new List <MetaVECTOR3>();
                var colour            = new List <uint>();
                var direction         = new List <MetaVECTOR3>();
                var falloff           = new List <float>();
                var falloffExponent   = new List <float>();
                var timeAndStateFlags = new List <uint>();
                var hash                   = new List <uint>();
                var coneInnerAngle         = new List <byte>();
                var coneOuterAngleOrCapExt = new List <byte>();
                var coronaIntensity        = new List <byte>();
                ushort numStreetLights     = 0;
                foreach (var light in lights)
                {
                    position.Add(light.position);
                    colour.Add(light.colour);
                    direction.Add(light.direction);
                    falloff.Add(light.falloff);
                    falloffExponent.Add(light.falloffExponent);
                    timeAndStateFlags.Add(light.timeAndStateFlags);
                    hash.Add(light.hash);
                    coneInnerAngle.Add(light.coneInnerAngle);
                    coneOuterAngleOrCapExt.Add(light.coneOuterAngleOrCapExt);
                    coronaIntensity.Add(light.coronaIntensity);
                    if (light.isStreetLight)
                    {
                        numStreetLights++;
                    }
                }



                UpdateStatus("Creating new ymap files...");

                var lodymap  = new YmapFile();
                var distymap = new YmapFile();
                var ll       = new YmapLODLights();
                var dl       = new YmapDistantLODLights();
                var cdl      = new CDistantLODLight();
                distymap.DistantLODLights = dl;
                lodymap.LODLights         = ll;
                lodymap.Parent            = distymap;
                cdl.category        = 1;//0=small, 1=med, 2=large
                cdl.numStreetLights = numStreetLights;
                dl.CDistantLODLight = cdl;
                dl.positions        = position.ToArray();
                dl.colours          = colour.ToArray();
                dl.Ymap             = distymap;
                dl.CalcBB();
                ll.direction         = direction.ToArray();
                ll.falloff           = falloff.ToArray();
                ll.falloffExponent   = falloffExponent.ToArray();
                ll.timeAndStateFlags = timeAndStateFlags.ToArray();
                ll.hash                   = hash.ToArray();
                ll.coneInnerAngle         = coneInnerAngle.ToArray();
                ll.coneOuterAngleOrCapExt = coneOuterAngleOrCapExt.ToArray();
                ll.coronaIntensity        = coronaIntensity.ToArray();
                ll.Ymap                   = lodymap;
                ll.BuildLodLights(dl);
                ll.CalcBB();
                ll.BuildBVH();

                lodymap.CalcFlags();
                lodymap.CalcExtents();
                distymap.CalcFlags();
                distymap.CalcExtents();


                var lodname                     = pname + "_lodlights";
                var distname                    = pname + "_distantlights";
                lodymap.Name                    = lodname;
                lodymap._CMapData.name          = JenkHash.GenHash(lodname);
                lodymap.RpfFileEntry            = new RpfResourceFileEntry();
                lodymap.RpfFileEntry.Name       = lodname + ".ymap";
                lodymap.RpfFileEntry.NameLower  = lodname + ".ymap";
                distymap.Name                   = distname;
                distymap._CMapData.name         = JenkHash.GenHash(distname);
                distymap.RpfFileEntry           = new RpfResourceFileEntry();
                distymap.RpfFileEntry.Name      = distname + ".ymap";
                distymap.RpfFileEntry.NameLower = distname + ".ymap";

                lodymap._CMapData.parent = distymap._CMapData.name;
                lodymap.Loaded           = true;
                distymap.Loaded          = true;

                UpdateStatus("Adding new ymap files to project...");

                ProjectForm.Invoke((MethodInvoker) delegate
                {
                    ProjectForm.AddYmapToProject(lodymap);
                    ProjectForm.AddYmapToProject(distymap);
                });

                var stats = "";
                UpdateStatus("Process complete. " + stats);
                GenerateComplete();
            });
        }
Example #16
0
        private void SelectFile(RpfEntry entry, int offset, int length)
        {
            SelectedEntry  = entry;
            SelectedOffset = offset;
            SelectedLength = length;

            RpfFileEntry rfe = entry as RpfFileEntry;

            if (rfe == null)
            {
                RpfDirectoryEntry rde = entry as RpfDirectoryEntry;
                if (rde != null)
                {
                    FileInfoLabel.Text = rde.Path + " (Directory)";
                    DataTextBox.Text   = "[Please select a data file]";
                }
                else
                {
                    FileInfoLabel.Text = "[Nothing selected]";
                    DataTextBox.Text   = "[Please select a data file]";
                }
                ShowTextures(null);
                return;
            }


            Cursor = Cursors.WaitCursor;

            string typestr = "Resource";

            if (rfe is RpfBinaryFileEntry)
            {
                typestr = "Binary";
            }

            byte[] data = rfe.File.ExtractFile(rfe);

            int datalen = (data != null) ? data.Length : 0;

            FileInfoLabel.Text = rfe.Path + " (" + typestr + " file)  -  " + TextUtil.GetBytesReadable(datalen);


            if (ShowLargeFileContentsCheckBox.Checked || (datalen < 524287)) //512K
            {
                DisplayFileContentsText(rfe, data, length, offset);
            }
            else
            {
                DataTextBox.Text = "[Filesize >512KB. Select the Show large files option to view its contents]";
            }



            bool istexdict = false;


            if (rfe.NameLower.EndsWith(".ymap"))
            {
                YmapFile ymap = new YmapFile(rfe);
                ymap.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = ymap;
            }
            else if (rfe.NameLower.EndsWith(".ytyp"))
            {
                YtypFile ytyp = new YtypFile();
                ytyp.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = ytyp;
            }
            else if (rfe.NameLower.EndsWith(".ymf"))
            {
                YmfFile ymf = new YmfFile();
                ymf.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = ymf;
            }
            else if (rfe.NameLower.EndsWith(".ymt"))
            {
                YmtFile ymt = new YmtFile();
                ymt.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = ymt;
            }
            else if (rfe.NameLower.EndsWith(".ybn"))
            {
                YbnFile ybn = new YbnFile();
                ybn.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = ybn;
            }
            else if (rfe.NameLower.EndsWith(".fxc"))
            {
                FxcFile fxc = new FxcFile();
                fxc.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = fxc;
            }
            else if (rfe.NameLower.EndsWith(".yft"))
            {
                YftFile yft = new YftFile();
                yft.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = yft;

                if ((yft.Fragment != null) && (yft.Fragment.Drawable != null) && (yft.Fragment.Drawable.ShaderGroup != null) && (yft.Fragment.Drawable.ShaderGroup.TextureDictionary != null))
                {
                    ShowTextures(yft.Fragment.Drawable.ShaderGroup.TextureDictionary);
                    istexdict = true;
                }
            }
            else if (rfe.NameLower.EndsWith(".ydr"))
            {
                YdrFile ydr = new YdrFile();
                ydr.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = ydr;

                if ((ydr.Drawable != null) && (ydr.Drawable.ShaderGroup != null) && (ydr.Drawable.ShaderGroup.TextureDictionary != null))
                {
                    ShowTextures(ydr.Drawable.ShaderGroup.TextureDictionary);
                    istexdict = true;
                }
            }
            else if (rfe.NameLower.EndsWith(".ydd"))
            {
                YddFile ydd = new YddFile();
                ydd.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = ydd;
                //todo: show embedded texdicts in ydd's? is this possible?
            }
            else if (rfe.NameLower.EndsWith(".ytd"))
            {
                YtdFile ytd = new YtdFile();
                ytd.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = ytd;
                ShowTextures(ytd.TextureDict);
                istexdict = true;
            }
            else if (rfe.NameLower.EndsWith(".ycd"))
            {
                YcdFile ycd = new YcdFile();
                ycd.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = ycd;
            }
            else if (rfe.NameLower.EndsWith(".ynd"))
            {
                YndFile ynd = new YndFile();
                ynd.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = ynd;
            }
            else if (rfe.NameLower.EndsWith(".ynv"))
            {
                YnvFile ynv = new YnvFile();
                ynv.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = ynv;
            }
            else if (rfe.NameLower.EndsWith("_cache_y.dat"))
            {
                CacheDatFile cdf = new CacheDatFile();
                cdf.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = cdf;
            }
            else if (rfe.NameLower.EndsWith(".rel"))
            {
                RelFile rel = new RelFile(rfe);
                rel.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = rel;
            }
            else if (rfe.NameLower.EndsWith(".gxt2"))
            {
                Gxt2File gxt2 = new Gxt2File();
                gxt2.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = gxt2;
            }
            else if (rfe.NameLower.EndsWith(".pso"))
            {
                JPsoFile pso = new JPsoFile();
                pso.Load(data, rfe);
                DetailsPropertyGrid.SelectedObject = pso;
            }
            else
            {
                DetailsPropertyGrid.SelectedObject = null;
            }


            if (!istexdict)
            {
                ShowTextures(null);
            }


            Cursor = Cursors.Default;
        }
Example #17
0
        // WIP++
        static void HandlYmapToYdrOptions(string[] args)
        {
            CommandLine.Parse <YmapToYdrOptions>(args, (opts, gOpts) =>
            {
                Init(args);

                var files    = new Dictionary <uint, string>();
                var required = new List <uint>();

                var ymap = new YmapFile();

                ymap.Load(opts.InputFile);

                for (int i = 0; i < ymap.CMapData.Entities.Count; i++)
                {
                    var entity = ymap.CMapData.Entities[i];

                    if (required.IndexOf(entity.ArchetypeName) == -1)
                    {
                        required.Add(entity.ArchetypeName);
                    }
                }

                ArchiveUtilities.ForEachResourceFile(Settings.Default.GTAFolder, (fullFileName, file, encryption) =>
                {
                    if (file.Name.EndsWith(".ydr"))
                    {
                        uint hash = Utils.Hash(file.Name.ToLowerInvariant().Replace(".ydr", ""));

                        if (required.IndexOf(hash) != -1 && !files.ContainsKey(hash))
                        {
                            Console.WriteLine(file.Name);

                            string tmp = Path.GetTempFileName();
                            file.Export(tmp);
                            files.Add(hash, tmp);
                        }
                    }
                });

                YdrFile ydr = null;

                var bbMin    = new Vector3(float.MaxValue);
                var bbMax    = new Vector3(float.MinValue);
                var bsCenter = Vector3.Zero;

                foreach (var file in files)
                {
                    var ydr2 = new YdrFile();

                    ydr2.Load(file.Value);

                    bbMin = Vector3.Min(bbMin, (Vector3)(Vector4)ydr2.Drawable.BoundingBoxMin);
                    bbMax = Vector3.Max(bbMin, (Vector3)(Vector4)ydr2.Drawable.BoundingBoxMax);

                    if (ydr == null)
                    {
                        ydr = ydr2;
                        continue;
                    }

                    ydr.Drawable.BoundingSphereRadius = ydr2.Drawable.BoundingSphereRadius;

                    for (int i = 0; i < ydr2.Drawable.DrawableModelsHigh.Entries.Count; i++)
                    {
                        var model = ydr2.Drawable.DrawableModelsHigh.Entries[i];

                        for (int j = 0; j < model.Geometries.Count; j++)
                        {
                            ydr.Drawable.DrawableModelsHigh.Entries[i].Geometries.Add(model.Geometries[j]);
                        }
                    }

                    for (int i = 0; i < ydr2.Drawable.DrawableModelsX.Entries.Count; i++)
                    {
                        var model = ydr2.Drawable.DrawableModelsX.Entries[i];

                        for (int j = 0; j < model.Geometries.Count; j++)
                        {
                            ydr.Drawable.DrawableModelsX.Entries[i].Geometries.Add(model.Geometries[j]);
                        }
                    }
                }

                ydr.Drawable.BoundingBoxMin = (RAGE_Vector4)(Vector4)bbMin;
                ydr.Drawable.BoundingBoxMax = (RAGE_Vector4)(Vector4)bbMax;
                ydr.Drawable.BoundingCenter = (RAGE_Vector3)bsCenter;

                ydr.Save(opts.OutputFile);
            });
        }
Example #18
0
        static void HandleImportMetaOptions(string[] args)
        {
            CommandLine.Parse <ImportMetaOptions>(args, (opts, gOpts) =>
            {
                if (opts.Metadata)
                {
                    Init(args);
                }
                else
                {
                    EnsurePath();
                    EnsureKeys();
                    EnsureCache();
                }

                if (opts.InputFiles == null)
                {
                    Console.WriteLine("Please provide input files with -i --input");
                    return;
                }
                else
                {
                    var inputFiles = Utils.Expand(opts.InputFiles);

                    for (int i = 0; i < inputFiles.Length; i++)
                    {
                        var fileInfo = inputFiles[i];

                        Console.WriteLine(fileInfo.FullName);

                        var strings = MetaUtilities.GetAllStringsFromXml(fileInfo.FullName);

                        foreach (var str in strings)
                        {
                            Utils.Hash(str.ToLowerInvariant());
                        }

                        var doc = new XmlDocument();

                        doc.Load(fileInfo.FullName);

                        var res          = new ResourceFile_GTA5_pc <MetaFile>();
                        res.Version      = 2;
                        res.ResourceData = XmlMeta.GetMeta(doc);

                        if (fileInfo.Name.EndsWith(".ymap.xml") && opts.Metadata)
                        {
                            var toDelete = opts.Delete?.Select(e => Convert.ToUInt32(e)).ToList() ?? new List <uint>();

                            var mappings   = new Dictionary <uint, Dictionary <uint, JObject> >();
                            var basePath   = Path.GetDirectoryName(fileInfo.FullName);
                            var ymaps      = new List <YmapFile>();
                            var ymap       = new YmapFile();
                            var nameHashes = new Dictionary <uint, string>();

                            ymap.ResourceFile = res;

                            ymap.Parse();

                            var topParent     = ImportMeta_GetTopYmapParent((uint)ymap.CMapData.Name);
                            var topParentHash = (uint)topParent["hash"];
                            var topParentName = (string)topParent["name"];
                            var topParentPath = (string)topParent["path"];
                            var topParentYmap = new YmapFile();

                            Console.WriteLine("Top parent is " + topParentName);

                            var entries = new List <JObject>()
                            {
                                topParent
                            };

                            entries.AddRange(ImportMeta_GetYmapChildrens(topParent));

                            for (int j = 0; j < entries.Count; j++)
                            {
                                var entry        = entries[j];
                                var entryHash    = (uint)entry["hash"];
                                var entryName    = (string)entry["name"];
                                var entryPath    = (string)entry["path"];
                                var ymapPath     = basePath + "\\" + entryName + ".ymap";
                                var metadataPath = ymapPath + ".json";

                                nameHashes.Add(entryHash, entryName);

                                if (!File.Exists(ymapPath))
                                {
                                    Console.WriteLine("ERROR => File not found : " + entryName + ".ymap");
                                    return;
                                }

                                if (!File.Exists(metadataPath))
                                {
                                    Console.WriteLine("ERROR => Metadata not found for " + entryName);
                                    return;
                                }

                                var metadataMapping = (JArray)JObject.Parse(File.ReadAllText(metadataPath))["mapping"];
                                var mapping         = new Dictionary <uint, JObject>();

                                for (int k = 0; k < metadataMapping.Count; k++)
                                {
                                    mapping.Add((uint)metadataMapping[k]["guid"], (JObject)metadataMapping[k]);
                                }

                                mappings.Add(entryHash, mapping);

                                if (entryHash == (uint)ymap.CMapData.Name)
                                {
                                    ymaps.Add(ymap);
                                }
                                else
                                {
                                    var ymap2 = new YmapFile();
                                    ymap2.Load(ymapPath);
                                    ymaps.Add(ymap2);
                                }
                            }

                            for (int j = 0; j < ymaps.Count; j++)
                            {
                                var ymap2 = ymaps[j];

                                if (ymap2.CMapData.Parent != 0)
                                {
                                    ymap2.CMapData.ParentMapData = ymaps.Find(e => e.CMapData.Name == ymap2.CMapData.Parent).CMapData;
                                }
                            }

                            bool modified;

                            do
                            {
                                modified = false;

                                for (int j = 0; j < ymaps.Count; j++)
                                {
                                    var ymap2 = ymaps[j];

                                    Console.WriteLine(nameHashes[(uint)ymap2.CMapData.Name]);

                                    var toRemove      = new List <MCEntityDef>();
                                    var toSet         = new List <Tuple <MCEntityDef, MCEntityDef> >();
                                    bool currModified = false;

                                    for (int k = 0; k < ymap2.CMapData.Entities.Count; k++)
                                    {
                                        var entity        = ymap2.CMapData.Entities[k];
                                        var oldHasParent  = (bool)mappings[(uint)ymap2.CMapData.Name][entity.Guid]["hasParent"];
                                        var currHasParent = entity.ParentIndex != -1;

                                        if (oldHasParent)
                                        {
                                            var oldParent         = (uint)mappings[(uint)ymap2.CMapData.Name][entity.Guid]["parent"];
                                            var oldParentYmapName = (string)mappings[(uint)ymap2.CMapData.Name][entity.Guid]["parentYmap"];
                                            var oldParentYmap     = Utils.Hash(oldParentYmapName);

                                            if (currHasParent)
                                            {
                                                if (entity.ParentEntity == null || entity.ParentEntity.Guid != oldParent)
                                                {
                                                    var parentYmap = ymaps.Find(e => (uint)e.CMapData.Name == oldParentYmap);
                                                    var parentIdx  = parentYmap.CMapData.Entities.FindIndex(e => e.Guid == oldParent);

                                                    if (parentIdx == -1)
                                                    {
                                                        Console.WriteLine("DELETE " + entity.Guid + " => Missing parent (" + oldParentYmapName + ")");
                                                        toRemove.Add(entity);
                                                        modified     = true;
                                                        currModified = true;
                                                    }
                                                    else
                                                    {
                                                        Console.WriteLine("ASSIGN parent " + oldParent + " to " + entity.Guid);
                                                        var parent = parentYmap.CMapData.Entities[parentIdx];
                                                        toSet.Add(new Tuple <MCEntityDef, MCEntityDef>(entity, parent));
                                                        modified     = true;
                                                        currModified = true;
                                                    }
                                                }
                                                else
                                                {
                                                    if (toDelete.IndexOf(oldParent) != -1 || (opts.DeleteScope == "full" && toDelete.IndexOf(entity.Guid) != -1))
                                                    {
                                                        Console.WriteLine("DELETE " + entity.Guid + " => Marked for deletion @" + opts.DeleteMode);
                                                        toRemove.Add(entity);
                                                        modified     = true;
                                                        currModified = true;
                                                    }
                                                }
                                            }
                                        }
                                    }

                                    if (opts.DeleteMode == "dummy")
                                    {
                                        for (int k = 0; k < toRemove.Count; k++)
                                        {
                                            toRemove[k].ArchetypeName = Utils.Hash("gtautil_dummy");
                                        }
                                    }
                                    else
                                    {
                                        ymap2.CMapData.RemoveEntities(toRemove);
                                    }

                                    for (int k = 0; k < toSet.Count; k++)
                                    {
                                        toSet[k].Item1.ParentEntity = toSet[k].Item2;
                                    }

                                    if (currModified)
                                    {
                                        Console.WriteLine("MODIFIED");
                                    }
                                }
                            } while (modified && opts.DeleteMode != "dummy");

                            for (int j = 0; j < ymaps.Count; j++)
                            {
                                var ymap2   = ymaps[j];
                                var mapping = new Dictionary <uint, int>();
                                var name    = nameHashes[(uint)ymap2.CMapData.Name];

                                ymap2.Save(basePath + "\\" + name + ".ymap");

                                var data = new JObject
                                {
                                    ["mapping"] = new JArray()
                                };

                                var dataMapping = (JArray)(data["mapping"]);

                                for (int k = 0; k < ymap2.CMapData.Entities.Count; k++)
                                {
                                    var entity = ymap2.CMapData.Entities[k];

                                    if (mapping.ContainsKey(entity.Guid))
                                    {
                                        Console.WriteLine("Duplicate GUID found => " + entity.Guid + " at index " + j + " ABORTING");
                                        return;
                                    }
                                    else
                                    {
                                        mapping.Add(entity.Guid, k);

                                        var entry = new JObject()
                                        {
                                            ["guid"]      = entity.Guid,
                                            ["hasParent"] = entity.ParentIndex != -1,
                                        };

                                        if (entity.ParentIndex != -1)
                                        {
                                            entry["parent"]     = entity.ParentEntity.Guid;
                                            entry["parentName"] = MetaXml.HashString((MetaName)entity.ParentEntity.Guid);
                                            entry["parentYmap"] = nameHashes[(uint)entity.ParentEntity.Parent.Name];
                                        }

                                        dataMapping.Add(entry);
                                    }
                                }

                                var jsonString = JsonConvert.SerializeObject(data, new JsonSerializerSettings()
                                {
                                    Formatting = Newtonsoft.Json.Formatting.Indented
                                });

                                File.WriteAllText(basePath + "\\" + name + ".ymap.json", jsonString);
                            }
                        }
                        else
                        {
                            string fileName = fileInfo.FullName.Replace(".xml", "");
                            res.Save(fileName);
                        }
                    }

                    using (StreamWriter writer = new StreamWriter(AssemblyDirectory + "\\strings.txt"))
                    {
                        foreach (var kvp in Jenkins.Index)
                        {
                            writer.Write(kvp.Value + "\n");
                        }
                    }
                }
            });
        }
Example #19
0
        static void HandleInjectEntitiesOptions(string[] args)
        {
            CommandLine.Parse <InjectEntitiesOptions>(args, (opts, gOpts) =>
            {
                if (opts.Ymap == null)
                {
                    Console.WriteLine("Please provide source ymap file with --ymap");
                    return;
                }

                if (opts.Ytyp == null)
                {
                    Console.WriteLine("Please provide source ytyp file with --ytyp");
                    return;
                }

                if (opts.Position == null || opts.Position.Count() != 3)
                {
                    Console.WriteLine("Please provide a correct position ex: --position 120.5,1370.312,769.2");
                    return;
                }

                if (opts.Rotation == null || opts.Rotation.Count() != 4)
                {
                    Console.WriteLine("Plase provide a correct rotation ex: --rotation 0,0,0,1");
                    return;
                }

                if (opts.Name == null)
                {
                    Console.WriteLine("Plase provide new generated ytyp name with --name");
                    return;
                }

                Init(args);

                var ymapInfos = Utils.Expand(opts.Ymap);
                var ymapNames = ymapInfos.Select(e => Path.GetFileNameWithoutExtension(e.Name)).ToArray();

                var position = new Vector3(opts.Position.ElementAt(0), opts.Position.ElementAt(1), opts.Position.ElementAt(2));
                var rotation = new Quaternion(opts.Rotation.ElementAt(0), opts.Rotation.ElementAt(1), opts.Rotation.ElementAt(2), opts.Rotation.ElementAt(3));

                var ytyp = new YtypFile();

                ytyp.Load(opts.Ytyp);

                MCMloArchetypeDef mlo = null;

                for (int i = 0; i < ytyp.CMapTypes.MloArchetypes.Count; i++)
                {
                    if (opts.MloName == null)
                    {
                        mlo = ytyp.CMapTypes.MloArchetypes[i];
                        break;
                    }
                    else
                    {
                        uint mloNameHash = Jenkins.Hash(opts.MloName.ToLowerInvariant());

                        if (mloNameHash == ytyp.CMapTypes.MloArchetypes[i].Name)
                        {
                            Console.Error.WriteLine("Found MLO => " + opts.MloName);
                            mlo = ytyp.CMapTypes.MloArchetypes[i];
                            break;
                        }
                    }
                }

                if (mlo == null)
                {
                    Console.WriteLine("MLO archetype not found");
                    return;
                }

                var ymaps = new List <YmapFile>();

                for (int i = 0; i < ymapInfos.Length; i++)
                {
                    var ymap = new YmapFile();

                    ymap.Load(ymapInfos[i].FullName);

                    ymaps.Add(ymap);
                }

                var missingYmap  = new YmapFile();
                int missingCount = 0;

                Console.WriteLine("Calculating rooms extents");

                var roomExtents = new Vector3[mlo.Rooms.Count][];

                for (int i = 0; i < mlo.Rooms.Count; i++)
                {
                    var room     = mlo.Rooms[i];
                    var entities = new List <MCEntityDef>();

                    for (int j = 0; j < room.AttachedObjects.Count; j++)
                    {
                        int idx = (int)room.AttachedObjects[j];

                        if (idx >= mlo.Entities.Count)
                        {
                            continue;
                        }

                        entities.Add(mlo.Entities[idx]);
                    }

                    var extents = Utils.CalcExtents(entities);

                    roomExtents[i] = extents[0];
                }

                for (int i = 0; i < ymaps.Count; i++)
                {
                    var ymap = ymaps[i];
                    var name = ymapNames[i];

                    if (name.StartsWith("portal_") || name.StartsWith("entityset_"))
                    {
                        continue;
                    }

                    var roomIdx           = mlo.Rooms.FindIndex(e => e.Name == name);
                    MCMloRoomDef currRoom = null;

                    if (roomIdx != -1)
                    {
                        currRoom = mlo.Rooms[roomIdx];
                    }

                    for (int j = 0; j < ymap.CMapData.Entities.Count; j++)
                    {
                        var entity           = ymap.CMapData.Entities[j];
                        var idx              = mlo.Entities.FindIndex(e => e.Guid == entity.Guid);
                        var room             = currRoom;
                        var originalPosition = entity.Position;
                        var originalRotation = entity.Rotation;

                        Console.WriteLine(name + " => " + j + " (" + idx + "|" + mlo.Entities.Count + ") => " + Utils.HashString((MetaName)entity.ArchetypeName));

                        Utils.World2Mlo(entity, mlo, position, rotation);

                        if (opts.Static && idx == -1)
                        {
                            if ((entity.Flags & 32) == 0)
                            {
                                Console.WriteLine("  Setting static flag (32)");
                                entity.Flags = entity.Flags | 32;
                            }
                        }

                        entity.LodLevel = Unk_1264241711.LODTYPES_DEPTH_ORPHANHD;

                        if (entity.Guid == 0)
                        {
                            var random = new Random();

                            do
                            {
                                entity.Guid = (uint)random.Next(1000000, Int32.MaxValue);
                            }while (mlo.Entities.Count(e => e.Guid == entity.Guid) > 0);

                            Console.WriteLine("  Setting random GUID => " + entity.Guid);
                        }

                        if (idx == -1)
                        {
                            idx = mlo.AddEntity(entity);
                        }
                        else
                        {
                            Console.WriteLine("  Found matching GUID => Overriding " + idx);
                            mlo.Entities[idx] = entity;
                        }


                        Console.WriteLine(j + " " + Utils.HashString((MetaName)entity.ArchetypeName));

                        if (room == null)
                        {
                            room = GetRoomForEntity(mlo, roomExtents, entity);
                        }

                        if (room == null)
                        {
                            entity.Position = originalPosition;
                            entity.Rotation = originalRotation;
                            entity.LodLevel = Unk_1264241711.LODTYPES_DEPTH_HD;

                            missingYmap.CMapData.Entities.Add(entity);

                            missingCount++;

                            continue;
                        }

                        uint id = (uint)idx;

                        if (room.AttachedObjects.IndexOf(id) == -1)
                        {
                            room.AttachedObjects.Add(id);
                        }

                        Console.WriteLine("  Room => " + room.Name);
                    }
                }

                if (opts.DeleteMissing)
                {
                    for (int i = mlo.Entities.Count - 1; i >= 0; i--)
                    {
                        bool found = false;

                        for (int j = 0; j < ymaps.Count; j++)
                        {
                            var ymap = ymaps[j];

                            if (ymap.CMapData.Entities.FindIndex(e => e.Guid == mlo.Entities[i].Guid) != -1)
                            {
                                found = true;
                                break;
                            }
                        }

                        if (!found)
                        {
                            Console.WriteLine("DELETE " + i);

                            for (int j = 0; j < mlo.Rooms.Count; j++)
                            {
                                for (int k = mlo.Rooms[j].AttachedObjects.Count - 1; k >= 0; k--)
                                {
                                    if (mlo.Rooms[j].AttachedObjects[k] == (uint)i)
                                    {
                                        mlo.Rooms[j].AttachedObjects.RemoveAt(k);
                                    }
                                }
                            }
                        }
                    }
                }

                var foundEntities = new Dictionary <uint, List <MCEntityDef> >();

                for (int i = 0; i < ymaps.Count; i++)
                {
                    var ymap = ymaps[i];
                    var name = ymapNames[i];

                    if (!name.StartsWith("entityset_"))
                    {
                        continue;
                    }

                    string[] split  = name.Split('_');
                    uint nameHash   = uint.Parse(split[1]);
                    string roomName = split[2];

                    if (!foundEntities.TryGetValue(nameHash, out List <MCEntityDef> fEntities))
                    {
                        fEntities = new List <MCEntityDef>();
                    }

                    int entitySetIdx = mlo.EntitySets.FindIndex(e => e.Name == nameHash);
                    int roomIdx      = mlo.Rooms.FindIndex(e => e.Name == roomName);

                    MCMloEntitySet currEntitySet = null;

                    if (entitySetIdx != -1)
                    {
                        currEntitySet = mlo.EntitySets[entitySetIdx];
                    }

                    for (int j = 0; j < ymap.CMapData.Entities.Count; j++)
                    {
                        var entity           = ymap.CMapData.Entities[j];
                        var idx              = currEntitySet.Entities.FindIndex(e => e.Guid == entity.Guid);
                        var entitySet        = currEntitySet;
                        var originalPosition = entity.Position;
                        var originalRotation = entity.Rotation;

                        Console.WriteLine(name + " => " + j + " (" + idx + "|" + currEntitySet.Entities.Count + ") => " + Utils.HashString((MetaName)entity.ArchetypeName));

                        Utils.World2Mlo(entity, mlo, position, rotation);

                        if (opts.Static && idx == -1)
                        {
                            if ((entity.Flags & 32) == 0)
                            {
                                Console.WriteLine("  Setting static flag (32)");
                                entity.Flags = entity.Flags | 32;
                            }
                        }

                        entity.LodLevel = Unk_1264241711.LODTYPES_DEPTH_ORPHANHD;

                        if (entity.Guid == 0)
                        {
                            var random = new Random();

                            do
                            {
                                entity.Guid = (uint)random.Next(1000000, Int32.MaxValue);
                            }while (currEntitySet.Entities.Count(e => e.Guid == entity.Guid) > 0);

                            Console.WriteLine("  Setting random GUID => " + entity.Guid);
                        }

                        if (idx == -1)
                        {
                            idx = currEntitySet.AddEntity(entity, roomIdx);
                        }
                        else
                        {
                            Console.WriteLine("  Found matching GUID => Overriding " + idx);
                            currEntitySet.Entities[idx] = entity;
                        }


                        Console.WriteLine(j + " " + Utils.HashString((MetaName)entity.ArchetypeName));

                        fEntities.Add(entity);
                    }

                    foundEntities[nameHash] = fEntities;
                }

                if (opts.DeleteMissing)
                {
                    foreach (var entry in foundEntities)
                    {
                        var entitySet = mlo.EntitySets.Find(e => e.Name == entry.Key);

                        for (int i = entitySet.Entities.Count - 1; i >= 0; i--)
                        {
                            bool found = false;

                            if (entry.Value.FindIndex(e => e.Guid == entitySet.Entities[i].Guid) != -1)
                            {
                                found = true;
                            }

                            if (!found)
                            {
                                Console.WriteLine("DELETE " + i);
                                entitySet.RemoveEntity(entitySet.Entities[i]);
                            }
                        }
                    }
                }

                ytyp.Save(opts.Name + ".ytyp");

                if (missingCount > 0)
                {
                    var extents = Utils.CalcExtents(missingYmap.CMapData.Entities);

                    missingYmap.CMapData.EntitiesExtentsMin  = extents[0][0];
                    missingYmap.CMapData.EntitiesExtentsMax  = extents[0][1];
                    missingYmap.CMapData.StreamingExtentsMin = extents[1][0];
                    missingYmap.CMapData.StreamingExtentsMax = extents[1][1];

                    missingYmap.Save(opts.Name + "_exterior.ymap");
                }
            });
        }
Example #20
0
        static void HandleGenLODLightsOptions(string[] args)
        {
            CommandLine.Parse <GenLODLigthsOptions>(args, (opts, gOpts) =>
            {
                if (opts.CreateMode)
                {
                    if (opts.OutputDirectory == null)
                    {
                        Console.Error.WriteLine("Please provide output directory with --output");
                        return;
                    }

                    Init(args);

                    if (!Directory.Exists(opts.OutputDirectory))
                    {
                        Directory.CreateDirectory(opts.OutputDirectory);
                    }

                    var mapping = new Dictionary <string, int>();

                    ArchiveUtilities.ForEachResourceFile(Settings.Default.GTAFolder, (fullFileName, file, encryption) =>
                    {
                        if (file.Name.EndsWith(".ymap") && file.Name.Contains("lodlights"))
                        {
                            Console.WriteLine(file.Name);

                            int level = GetDLCLevel(fullFileName);
                            int oldLevel;

                            if (!mapping.TryGetValue(file.Name, out oldLevel))
                            {
                                oldLevel = -1;
                                mapping.Add(file.Name, level);
                            }

                            if (level > oldLevel)
                            {
                                file.Export(opts.OutputDirectory + "\\" + file.Name);
                            }
                        }
                    });
                }
                else if (opts.DeleteMode)
                {
                    Init(args);

                    if (opts.InputDirectory == null)
                    {
                        Console.Error.WriteLine("Please provide input directory with --input");
                        return;
                    }

                    if (opts.Position == null || opts.Position.Count != 3)
                    {
                        Console.Error.WriteLine("Please provide position with --position x,y,z");
                        return;
                    }

                    if (!Directory.Exists(opts.InputDirectory + "\\modified"))
                    {
                        Directory.CreateDirectory(opts.InputDirectory + "\\modified");
                    }

                    Vector3 position = new Vector3(opts.Position[0], opts.Position[1], opts.Position[2]);
                    string[] files   = Directory.GetFiles(opts.InputDirectory, "*.ymap");

                    var ymaps = new Dictionary <string, YmapFile>();

                    for (int i = 0; i < files.Length; i++)
                    {
                        string path = files[i];
                        string name = files[i].Replace(".ymap", "");
                        var ymap    = new YmapFile();

                        Console.WriteLine("LOAD " + name);

                        ymap.Load(files[i]);
                        ymaps.Add(name, ymap);
                    }

                    var modified = new Dictionary <string, YmapFile>();

                    foreach (var item in ymaps)
                    {
                        string name   = item.Key;
                        YmapFile ymap = item.Value;

                        for (int j = ymap.CMapData.DistantLODLightsSOA.Entries.Count - 1; j >= 0; j--)
                        {
                            var entry      = ymap.CMapData.DistantLODLightsSOA.Entries[j];
                            var children   = new Dictionary <string, YmapFile>();
                            float distance = Vector3.Distance(position, entry.Position);

                            foreach (var item2 in ymaps)
                            {
                                if (item2.Value.CMapData.Parent == ymap.CMapData.Name)
                                {
                                    children.Add(item2.Key, item2.Value);
                                }
                            }

                            if (distance <= opts.Radius)
                            {
                                Console.WriteLine("Found DistLODLight in " + name + " at index " + j);
                                Console.WriteLine("  Delete : " + name + "@" + j);

                                ymap.CMapData.DistantLODLightsSOA.Entries.RemoveAt(j);

                                if (!modified.ContainsValue(ymap))
                                {
                                    modified.Add(name, ymap);
                                }

                                foreach (var item2 in children)
                                {
                                    string name2   = item2.Key;
                                    YmapFile ymap2 = item2.Value;

                                    Console.WriteLine("  Delete : " + name2 + "@" + j);
                                    item2.Value.CMapData.LODLightsSOA.Entries.RemoveAt(j);

                                    if (!modified.ContainsValue(ymap2))
                                    {
                                        modified.Add(name2, ymap2);
                                    }
                                }
                            }
                        }
                    }

                    foreach (var item in modified)
                    {
                        var descendant = item.Key.Substring(item.Key.LastIndexOf("\\"));
                        item.Value.Save(opts.InputDirectory + "\\" + descendant + ".ymap");
                        item.Value.Save(opts.InputDirectory + "\\modified\\" + descendant + ".ymap");
                    }
                }
            });
        }
Example #21
0
        private void GenerateButton_Click(object sender, EventArgs e)
        {
            //var space = ProjectForm?.WorldForm?.Space;
            //if (space == null) return;
            var gameFileCache = ProjectForm?.WorldForm?.GameFileCache;

            if (gameFileCache == null)
            {
                return;
            }

            var path = ProjectForm.CurrentProjectFile.GetFullFilePath("lodlights") + "\\";

            GenerateButton.Enabled = false;


            List <YmapFile> projectYmaps = ProjectForm.CurrentProjectFile.YmapFiles;

            var pname = NameTextBox.Text;

            Task.Run(() =>
            {
                var lights = new List <Light>();
                var eemin  = new Vector3(float.MaxValue);
                var eemax  = new Vector3(float.MinValue);
                var semin  = new Vector3(float.MaxValue);
                var semax  = new Vector3(float.MinValue);
                //var rnd = new Random();

                foreach (var ymap in projectYmaps)
                {
                    if (ymap?.AllEntities == null)
                    {
                        continue;
                    }
                    foreach (var ent in ymap.AllEntities)
                    {
                        if (ent.Archetype == null)
                        {
                            continue;
                        }

                        bool waiting = false;
                        var dwbl     = gameFileCache.TryGetDrawable(ent.Archetype, out waiting);
                        while (waiting)
                        {
                            dwbl = gameFileCache.TryGetDrawable(ent.Archetype, out waiting);
                            UpdateStatus("Waiting for " + ent.Archetype.AssetName + " to load...");
                            Thread.Sleep(20);
                        }
                        UpdateStatus("Adding lights from " + ent.Archetype.Name + "...");
                        if (dwbl != null)
                        {
                            Drawable ddwbl                 = dwbl as Drawable;
                            FragDrawable fdwbl             = dwbl as FragDrawable;
                            LightAttributes_s[] lightAttrs = null;
                            if (ddwbl != null)
                            {
                                lightAttrs = ddwbl.LightAttributes?.data_items;
                            }
                            else if (fdwbl != null)
                            {
                                lightAttrs = fdwbl.OwnerFragment?.LightAttributes?.data_items;
                            }
                            if (lightAttrs != null)
                            {
                                eemin = Vector3.Min(eemin, ent.BBMin);
                                eemax = Vector3.Max(eemax, ent.BBMax);
                                semin = Vector3.Min(semin, ent.BBMin - ent._CEntityDef.lodDist);
                                semax = Vector3.Max(semax, ent.BBMax + ent._CEntityDef.lodDist);


                                for (int li = 0; li < lightAttrs.Length; li++)
                                {
                                    var la = lightAttrs[li];
                                    //transform this light with the entity position and orientation
                                    //generate lights data from it!


                                    //gotta transform the light position by the given bone! annoying
                                    Bone bone    = null;
                                    Matrix xform = Matrix.Identity;
                                    int boneidx  = 0;
                                    var skeleton = dwbl.Skeleton;
                                    if (skeleton?.Bones?.Data != null)
                                    {
                                        for (int j = 0; j < skeleton.Bones.Data.Count; j++)
                                        {
                                            var tbone = skeleton.Bones.Data[j];
                                            if (tbone.Tag == la.BoneId)
                                            {
                                                boneidx = j;
                                                bone    = tbone;
                                                break;
                                            }
                                        }
                                        if (bone != null)
                                        {
                                            var modeltransforms = skeleton.Transformations;
                                            var fragtransforms  = fdwbl?.OwnerFragmentPhys?.OwnerFragPhysLod?.FragTransforms?.Data;
                                            var fragtransformid = fdwbl?.OwnerFragmentPhys?.OwnerFragPhysIndex ?? 0;
                                            var fragoffset      = fdwbl?.OwnerFragmentPhys?.OwnerFragPhysLod.Unknown_30h ?? Vector4.Zero;
                                            fragoffset.W        = 0.0f;

                                            if ((fragtransforms != null) && (fragtransformid < fragtransforms.Length))
                                            {
                                                xform       = fragtransforms[fragtransformid];
                                                xform.Row4 += fragoffset;
                                            }
                                            else
                                            {
                                                //when using the skeleton's matrices, they need to be transformed by parent
                                                xform         = modeltransforms[boneidx];
                                                xform.Column4 = Vector4.UnitW;
                                                //xform = Matrix.Identity;
                                                short[] pinds   = skeleton.ParentIndices;
                                                short parentind = ((pinds != null) && (boneidx < pinds.Length)) ? pinds[boneidx] : (short)-1;
                                                while ((parentind >= 0) && (parentind < pinds.Length))
                                                {
                                                    Matrix ptrans  = (parentind < modeltransforms.Length) ? modeltransforms[parentind] : Matrix.Identity;
                                                    ptrans.Column4 = Vector4.UnitW;
                                                    xform          = Matrix.Multiply(ptrans, xform);
                                                    parentind      = ((pinds != null) && (parentind < pinds.Length)) ? pinds[parentind] : (short)-1;
                                                }
                                            }
                                        }
                                    }



                                    Vector3 lpos = la.Position;
                                    Vector3 ldir = la.Direction;
                                    Vector3 bpos = xform.Multiply(lpos);
                                    Vector3 bdir = xform.MultiplyRot(ldir);
                                    Vector3 epos = ent.Orientation.Multiply(bpos) + ent.Position;
                                    Vector3 edir = ent.Orientation.Multiply(bdir);

                                    uint r = la.ColorR;
                                    uint g = la.ColorG;
                                    uint b = la.ColorB;
                                    uint i = (byte)Math.Min(la.Intensity * 4, 255);
                                    uint c = (i << 24) + (r << 16) + (g << 8) + b;


                                    uint h = GetLightHash(ent, li);// (uint)rnd.NextLong();

                                    if (ent._CEntityDef.guid == 91259075)
                                    {
                                    }   //h = 2324437992?     should be:19112537
                                    if (ent._CEntityDef.guid == 889043351)
                                    {
                                    }   //h = 422028630 ?     should be:4267224866



                                    //any other way to know if it's a streetlight?
                                    //var name = ent.Archetype.Name;
                                    var flags          = la.Flags;
                                    bool isStreetLight = (((flags >> 10) & 1u) == 1); // (name != null) && (name.Contains("street") || name.Contains("traffic"));
                                    isStreetLight      = false;                       //TODO: fix this!


                                    //@Calcium:
                                    //1 = point
                                    //2 = spot
                                    //4 = capsule
                                    uint type = (uint)la.Type;
                                    uint unk  = isStreetLight ? 1u : 0;//2 bits - isStreetLight low bit, unk high bit
                                    uint t    = la.TimeFlags | (type << 26) | (unk << 24);

                                    var maxext = (byte)Math.Max(Math.Max(la.Extent.X, la.Extent.Y), la.Extent.Z);



                                    var light                    = new Light();
                                    light.position               = new MetaVECTOR3(epos);
                                    light.colour                 = c;
                                    light.direction              = new MetaVECTOR3(edir);
                                    light.falloff                = la.Falloff;
                                    light.falloffExponent        = la.FalloffExponent;
                                    light.timeAndStateFlags      = t;
                                    light.hash                   = h;
                                    light.coneInnerAngle         = (byte)la.ConeInnerAngle;
                                    light.coneOuterAngleOrCapExt = Math.Max((byte)la.ConeOuterAngle, maxext);
                                    light.coronaIntensity        = (byte)(la.CoronaIntensity * 6);
                                    light.isStreetLight          = isStreetLight;
                                    lights.Add(light);
                                }
                            }
                        }
                    }
                }


                if (lights.Count == 0)
                {
                    MessageBox.Show("No lights found in project!");
                    return;
                }



                //final lights should be sorted by isStreetLight (1 first!) and then hash
                lights.Sort((a, b) =>
                {
                    if (a.isStreetLight != b.isStreetLight)
                    {
                        return(b.isStreetLight.CompareTo(a.isStreetLight));
                    }
                    return(a.hash.CompareTo(b.hash));
                });



                var position          = new List <MetaVECTOR3>();
                var colour            = new List <uint>();
                var direction         = new List <MetaVECTOR3>();
                var falloff           = new List <float>();
                var falloffExponent   = new List <float>();
                var timeAndStateFlags = new List <uint>();
                var hash                   = new List <uint>();
                var coneInnerAngle         = new List <byte>();
                var coneOuterAngleOrCapExt = new List <byte>();
                var coronaIntensity        = new List <byte>();
                ushort numStreetLights     = 0;
                foreach (var light in lights)
                {
                    position.Add(light.position);
                    colour.Add(light.colour);
                    direction.Add(light.direction);
                    falloff.Add(light.falloff);
                    falloffExponent.Add(light.falloffExponent);
                    timeAndStateFlags.Add(light.timeAndStateFlags);
                    hash.Add(light.hash);
                    coneInnerAngle.Add(light.coneInnerAngle);
                    coneOuterAngleOrCapExt.Add(light.coneOuterAngleOrCapExt);
                    coronaIntensity.Add(light.coronaIntensity);
                    if (light.isStreetLight)
                    {
                        numStreetLights++;
                    }
                }



                UpdateStatus("Creating new ymap files...");

                var lodymap               = new YmapFile();
                var distymap              = new YmapFile();
                var ll                    = new YmapLODLights();
                var dl                    = new YmapDistantLODLights();
                var cdl                   = new CDistantLODLight();
                cdl.category              = 1;//0=small, 1=med, 2=large
                cdl.numStreetLights       = numStreetLights;
                dl.CDistantLODLight       = cdl;
                dl.positions              = position.ToArray();
                dl.colours                = colour.ToArray();
                ll.direction              = direction.ToArray();
                ll.falloff                = falloff.ToArray();
                ll.falloffExponent        = falloffExponent.ToArray();
                ll.timeAndStateFlags      = timeAndStateFlags.ToArray();
                ll.hash                   = hash.ToArray();
                ll.coneInnerAngle         = coneInnerAngle.ToArray();
                ll.coneOuterAngleOrCapExt = coneOuterAngleOrCapExt.ToArray();
                ll.coronaIntensity        = coronaIntensity.ToArray();


                lodymap._CMapData.flags         = 0;
                distymap._CMapData.flags        = 2;
                lodymap._CMapData.contentFlags  = 128;
                distymap._CMapData.contentFlags = 256;

                lodymap._CMapData.entitiesExtentsMin   = eemin;
                lodymap._CMapData.entitiesExtentsMax   = eemax;
                lodymap._CMapData.streamingExtentsMin  = semin - 1000f;
                lodymap._CMapData.streamingExtentsMax  = semax + 1000f; //vanilla = ~1km
                distymap._CMapData.entitiesExtentsMin  = eemin;
                distymap._CMapData.entitiesExtentsMax  = eemax;
                distymap._CMapData.streamingExtentsMin = semin - 5000f; //make it huge
                distymap._CMapData.streamingExtentsMax = semax + 5000f; //vanilla = ~3km

                lodymap.LODLights         = ll;
                distymap.DistantLODLights = dl;

                var lodname                     = pname + "_lodlights";
                var distname                    = pname + "_distantlights";
                lodymap.Name                    = lodname;
                lodymap._CMapData.name          = JenkHash.GenHash(lodname);
                lodymap.RpfFileEntry            = new RpfResourceFileEntry();
                lodymap.RpfFileEntry.Name       = lodname + ".ymap";
                lodymap.RpfFileEntry.NameLower  = lodname + ".ymap";
                distymap.Name                   = distname;
                distymap._CMapData.name         = JenkHash.GenHash(distname);
                distymap.RpfFileEntry           = new RpfResourceFileEntry();
                distymap.RpfFileEntry.Name      = distname + ".ymap";
                distymap.RpfFileEntry.NameLower = distname + ".ymap";

                lodymap._CMapData.parent = distymap._CMapData.name;


                UpdateStatus("Adding new ymap files to project...");

                ProjectForm.Invoke((MethodInvoker) delegate
                {
                    ProjectForm.AddYmapToProject(lodymap);
                    ProjectForm.AddYmapToProject(distymap);
                });

                var stats = "";
                UpdateStatus("Process complete. " + stats);
                GenerateComplete();
            });
        }
Example #22
0
        static void HandleMergeYmapOptionsOptions(string[] args)
        {
            CommandLine.Parse <MergeYmapOptions>(args, (opts, gOpts) =>
            {
                if (opts.OutputDirectory == null)
                {
                    Console.WriteLine("Plase provide output directory with --output");
                    return;
                }

                if (opts.Name == null)
                {
                    Console.WriteLine("Plase provide name with --name");
                    return;
                }

                if (opts.Ymap == null)
                {
                    Console.WriteLine("Please provide source ymap files with --ymap");
                    return;
                }

                // Init(args);

                var ymapInfos = Utils.Expand(opts.Ymap);
                var bbs       = new List <Tuple <Vector3, Vector3> >();
                var ymap      = new YmapFile();

                for (int i = 0; i < ymapInfos.Length; i++)
                {
                    var _ymap = new YmapFile();

                    _ymap.Load(ymapInfos[i].FullName);

                    ymap.CMapData.AddEntities(_ymap.CMapData.Entities);
                }

                for (int i = 0; i < ymap.CMapData.Entities.Count; i++)
                {
                    var entity = ymap.CMapData.Entities[i];

                    var random = new Random();

                    do
                    {
                        entity.Guid = (uint)random.Next(1000000, Int32.MaxValue);
                    }while (ymap.CMapData.Entities.Count(e => e.Guid == entity.Guid) > 1);

                    Console.WriteLine("[" + i + "] Setting random GUID => " + entity.Guid);
                }

                var extents = Utils.CalcExtents(ymap.CMapData.Entities);

                ymap.CMapData.EntitiesExtentsMin  = extents[0][0];
                ymap.CMapData.EntitiesExtentsMax  = extents[0][1];
                ymap.CMapData.StreamingExtentsMin = extents[1][0];
                ymap.CMapData.StreamingExtentsMax = extents[1][1];

                Directory.CreateDirectory(opts.OutputDirectory);

                ymap.Save(opts.OutputDirectory + "\\" + opts.Name + ".ymap");
            });
        }
Example #23
0
        static void HandleMoveYmapOptionsOptions(string[] args)
        {
            CommandLine.Parse <MoveYmapOptions>(args, (opts, gOpts) =>
            {
                if (opts.OutputDirectory == null)
                {
                    Console.WriteLine("Plase provide output directory with --output");
                    return;
                }

                if (opts.Name == null)
                {
                    Console.WriteLine("Plase provide name with --name");
                    return;
                }

                if (opts.Ymap == null)
                {
                    Console.WriteLine("Please provide source ymap files with --ymap");
                    return;
                }

                if (opts.Position == null)
                {
                    Console.WriteLine("Please provide position with --position");
                    return;
                }

                if (opts.Rotation == null)
                {
                    Console.WriteLine("Please provide rotation with --rotation");
                    return;
                }

                // Init(args);

                var position = new Vector3(opts.Position.ElementAt(0), opts.Position.ElementAt(1), opts.Position.ElementAt(2));
                var rotation = new Quaternion(opts.Rotation.ElementAt(0), opts.Rotation.ElementAt(1), opts.Rotation.ElementAt(2), opts.Rotation.ElementAt(3));

                var ymap = new YmapFile();

                ymap.Load(opts.Ymap);

                if (ymap.CMapData.Entities == null)
                {
                    ymap.CMapData.Entities = new List <MCEntityDef>();
                }
                else
                {
                    for (int i = 0; i < ymap.CMapData.Entities.Count; i++)
                    {
                        var entity         = ymap.CMapData.Entities[i];
                        var placement      = Utils.World2Mlo(entity.Position, entity.Rotation, Vector3.Zero, Quaternion.Identity);
                        var entityRotation = new Quaternion(placement.Item2.X, placement.Item2.Y, placement.Item2.Z, placement.Item2.W);

                        entity.Position = placement.Item1;
                        entity.Rotation = placement.Item2;

                        entity.Position += position;
                        entity.Position  = Utils.RotateTransform(rotation, entity.Position, Vector3.Zero);

                        var newPlacement = Utils.Mlo2World(entity.Position, entity.Rotation, Vector3.Zero, Quaternion.Identity);

                        entity.Position = newPlacement.Item1;
                        entity.Rotation = newPlacement.Item2;
                    }
                }

                if (ymap.CMapData.MloInstances == null)
                {
                    ymap.CMapData.MloInstances = new List <MCMloInstanceDef>();
                }
                else
                {
                    for (int i = 0; i < ymap.CMapData.MloInstances.Count; i++)
                    {
                        var mlo       = ymap.CMapData.MloInstances[i];
                        mlo.Position += position;
                    }
                }

                ymap.CMapData.Block = new MCBlockDesc();

                var extents = Utils.CalcExtents(ymap.CMapData.Entities);;

                ymap.CMapData.EntitiesExtentsMin  = extents[0][0];
                ymap.CMapData.EntitiesExtentsMax  = extents[0][1];
                ymap.CMapData.StreamingExtentsMin = extents[1][0];
                ymap.CMapData.StreamingExtentsMax = extents[1][1];

                ymap.Save(opts.OutputDirectory + "\\" + opts.Name + ".ymap");
            });
        }
Example #24
0
        static void HandleExportMetaOptions(string[] args)
        {
            CommandLine.Parse <ExportMetaOptions>(args, (opts, gOpts) =>
            {
                if (opts.Metadata)
                {
                    Init(args);
                }
                else
                {
                    EnsurePath();
                    EnsureKeys();
                    EnsureCache();
                }

                if (opts.InputFiles == null)
                {
                    Console.WriteLine("Please provide input files with -i --input");
                    return;
                }
                else
                {
                    var inputFiles = Utils.Expand(opts.InputFiles);

                    for (int i = 0; i < inputFiles.Length; i++)
                    {
                        var fileInfo = inputFiles[i];

                        Console.WriteLine(fileInfo.FullName);

                        MetaFile meta = null;

                        if (fileInfo.Name.EndsWith(".ymap") && opts.Metadata)
                        {
                            var ymap = new YmapFile();

                            ymap.Load(fileInfo.FullName);

                            meta = ymap.ResourceFile.ResourceData;

                            var basePath      = Path.GetDirectoryName(fileInfo.FullName);
                            var topParent     = ImportMeta_GetTopYmapParent((uint)ymap.CMapData.Name);
                            var topParentHash = (uint)topParent["hash"];
                            var topParentName = (string)topParent["name"];
                            var topParentPath = (string)topParent["path"];
                            var topParentYmap = new YmapFile();

                            Console.WriteLine("Top parent is " + topParentName);

                            if (File.Exists(basePath + "\\" + topParentName + ".ymap"))
                            {
                                topParentYmap.Load(basePath + "\\" + topParentName + ".ymap");
                            }
                            else
                            {
                                ArchiveUtilities.ForEachResourceFile(Settings.Default.GTAFolder, (fullFileName, file, encryption) =>
                                {
                                    if (fullFileName == topParentPath)
                                    {
                                        var ms = new MemoryStream();
                                        file.Export(ms);
                                        topParentYmap.Load(ms);
                                    }
                                });
                            }

                            var children = ImportMeta_GetYmapChildrens(topParent);
                            var ymaps    = new List <YmapFile>()
                            {
                                topParentYmap
                            };
                            var nameHashes = new Dictionary <uint, string>();

                            nameHashes.Add((uint)topParent["hash"], (string)topParent["name"]);

                            for (int j = 0; j < children.Count; j++)
                            {
                                var cYmap = new YmapFile();
                                var child = children[j];
                                var hash  = (uint)child["hash"];
                                var name  = (string)child["name"];
                                var path  = (string)child["path"];

                                nameHashes.Add(hash, name);

                                if (File.Exists(basePath + "\\" + name + ".ymap"))
                                {
                                    cYmap.Load(basePath + "\\" + name + ".ymap");
                                }
                                else
                                {
                                    Console.WriteLine("Grabbing missing " + name + " from install directory (very slowly, needs optimization)");

                                    ArchiveUtilities.ForEachResourceFile(Settings.Default.GTAFolder, (fullFileName, file, encryption) =>
                                    {
                                        if (fullFileName == path)
                                        {
                                            var ms = new MemoryStream();

                                            file.Export(ms);

                                            cYmap.Load(ms);
                                        }
                                    });
                                }

                                ymaps.Add(cYmap);
                            }

                            ymaps[ymaps.FindIndex(e => e.CMapData.Name == ymap.CMapData.Name)] = ymap;

                            for (int j = 0; j < ymaps.Count; j++)
                            {
                                ymaps[j].CMapData.ParentMapData = ymaps.Find(e => e.CMapData.Name == ymaps[j].CMapData.Parent)?.CMapData;
                            }

                            for (int j = 0; j < ymaps.Count; j++)
                            {
                                var ymap2   = ymaps[j];
                                var mapping = new Dictionary <uint, int>();
                                var name    = nameHashes[(uint)ymap2.CMapData.Name];

                                ymap2.Save(basePath + "\\" + name + ".ymap");

                                var data = new JObject
                                {
                                    ["mapping"] = new JArray()
                                };

                                var dataMapping = (JArray)(data["mapping"]);

                                for (int k = 0; k < ymap2.CMapData.Entities.Count; k++)
                                {
                                    var entity = ymap2.CMapData.Entities[k];

                                    if (mapping.ContainsKey(entity.Guid))
                                    {
                                        Console.WriteLine("Duplicate GUID found => " + entity.Guid + " at index " + j + " ABORTING");
                                        return;
                                    }
                                    else
                                    {
                                        mapping.Add(entity.Guid, k);

                                        var entry = new JObject()
                                        {
                                            ["guid"]      = entity.Guid,
                                            ["hasParent"] = entity.ParentIndex != -1,
                                        };

                                        if (entity.ParentIndex != -1)
                                        {
                                            entry["parent"]     = entity.ParentEntity.Guid;
                                            entry["parentName"] = MetaXml.HashString((MetaName)entity.ParentEntity.Guid);
                                            entry["parentYmap"] = nameHashes[(uint)entity.ParentEntity.Parent.Name];
                                        }

                                        dataMapping.Add(entry);
                                    }
                                }

                                var jsonString = JsonConvert.SerializeObject(data, new JsonSerializerSettings()
                                {
                                    Formatting = Newtonsoft.Json.Formatting.Indented
                                });

                                File.WriteAllText(basePath + "\\" + name + ".ymap.json", jsonString);
                            }
                        }
                        else
                        {
                            var res = new ResourceFile_GTA5_pc <MetaFile>();
                            res.Load(fileInfo.FullName);
                            meta = res.ResourceData;
                        }

                        var xml = MetaXml.GetXml(meta);

                        string fileName = fileInfo.FullName + ".xml";

                        File.WriteAllText(fileName, xml);
                    }
                }
            });
        }
Example #25
0
        static void HandleExtractEntitiesOptions(string[] args)
        {
            CommandLine.Parse <ExtractEntitiesOptions>(args, (opts, gOpts) =>
            {
                if (opts.Ytyp == null)
                {
                    Console.WriteLine("Please provide source ytyp file with --ytyp");
                    return;
                }

                if (opts.Position == null || opts.Position.Count() != 3)
                {
                    Console.WriteLine("Please provide a correct position ex: --position 120.5,1370.312,769.2");
                    return;
                }

                if (opts.Rotation == null || opts.Rotation.Count() != 4)
                {
                    Console.WriteLine("Plase provide a correct rotation ex: --rotation 0,0,0,1");
                    return;
                }

                if (opts.Name == null)
                {
                    Console.WriteLine("Plase output directory name with --name");
                    return;
                }

                Init(args);

                var position = new Vector3(opts.Position.ElementAt(0), opts.Position.ElementAt(1), opts.Position.ElementAt(2));
                var rotation = new Quaternion(opts.Rotation.ElementAt(0), opts.Rotation.ElementAt(1), opts.Rotation.ElementAt(2), opts.Rotation.ElementAt(3));

                var ytyp = new YtypFile();

                ytyp.Load(opts.Ytyp);

                if (!File.Exists(opts.Name + ".original.ytyp"))
                {
                    File.Copy(opts.Ytyp, opts.Name + ".original.ytyp");
                }

                MCMloArchetypeDef mlo = null;

                for (int i = 0; i < ytyp.CMapTypes.MloArchetypes.Count; i++)
                {
                    if (opts.MloName == null)
                    {
                        mlo = ytyp.CMapTypes.MloArchetypes[i];
                        break;
                    }
                    else
                    {
                        uint mloNameHash = Jenkins.Hash(opts.MloName.ToLowerInvariant());

                        if (mloNameHash == ytyp.CMapTypes.MloArchetypes[i].Name)
                        {
                            Console.Error.WriteLine("Found MLO => " + opts.MloName);
                            mlo = ytyp.CMapTypes.MloArchetypes[i];
                            break;
                        }
                    }
                }

                if (mlo == null)
                {
                    Console.WriteLine("MLO archetype not found");
                    return;
                }

                for (int roomId = 0; roomId < mlo.Rooms.Count; roomId++)
                {
                    var room         = mlo.Rooms[roomId];
                    var ymap         = new YmapFile();
                    var ymapEntities = new List <MCEntityDef>();

                    Console.WriteLine("Room => " + room.Name + " (" + room.AttachedObjects.Count + " entities)");

                    for (int i = 0; i < room.AttachedObjects.Count; i++)
                    {
                        int idx = (int)room.AttachedObjects[i];

                        if (idx >= mlo.Entities.Count)
                        {
                            continue;
                        }

                        var entity         = mlo.Entities[idx];
                        var entityRotation = new Quaternion(entity.Rotation.X, entity.Rotation.Y, entity.Rotation.Z, entity.Rotation.W);

                        Utils.Mlo2World(entity, mlo, position, rotation);

                        entity.LodLevel = Unk_1264241711.LODTYPES_DEPTH_HD;

                        if (entity.Guid == 0)
                        {
                            var random = new Random();

                            do
                            {
                                entity.Guid = (uint)random.Next(1000000, Int32.MaxValue);
                            }while (mlo.Entities.Count(e => e.Guid == entity.Guid) == 1);

                            Console.WriteLine("[" + i + "] Setting random GUID => " + entity.Guid);
                        }

                        ymapEntities.Add(entity);
                    }

                    ymap.CMapData.Entities = ymapEntities;

                    var extents = Utils.CalcExtents(ymap.CMapData.Entities);

                    ymap.CMapData.EntitiesExtentsMin  = extents[0][0];
                    ymap.CMapData.EntitiesExtentsMax  = extents[0][1];
                    ymap.CMapData.StreamingExtentsMin = extents[1][0];
                    ymap.CMapData.StreamingExtentsMax = extents[1][1];

                    Console.WriteLine(extents[0][0].X + " " + extents[0][0].Y + " " + extents[0][0].Z);
                    Console.WriteLine(extents[0][1].X + " " + extents[0][1].Y + " " + extents[0][1].Z);

                    Directory.CreateDirectory(opts.Name);

                    ymap.Save(opts.Name + "\\" + room.Name + ".ymap");
                }

                if (mlo.EntitySets != null)
                {
                    for (int i = 0; i < mlo.EntitySets.Count; i++)
                    {
                        var entitySet = mlo.EntitySets[i];

                        Directory.CreateDirectory(opts.Name + "\\entitysets\\" + entitySet.Name);

                        for (int roomId = 0; roomId < mlo.Rooms.Count; roomId++)
                        {
                            var room         = mlo.Rooms[roomId];
                            var ymap         = new YmapFile();
                            var ymapEntities = new List <MCEntityDef>();

                            Console.WriteLine("EntitySet => " + entitySet.Name + " [" + room.Name + "] (" + entitySet.Entities.Count + " entities)");

                            for (int j = 0; j < entitySet.Entities.Count; j++)
                            {
                                int targetRoom = (int)entitySet.Locations[j];

                                if (targetRoom != roomId)
                                {
                                    continue;
                                }

                                var entity         = entitySet.Entities[j];
                                var entityRotation = new Quaternion(entity.Rotation.X, entity.Rotation.Y, entity.Rotation.Z, entity.Rotation.W);

                                Utils.Mlo2World(entity, mlo, position, rotation);

                                entity.LodLevel = Unk_1264241711.LODTYPES_DEPTH_HD;

                                if (entity.Guid == 0)
                                {
                                    var random = new Random();

                                    do
                                    {
                                        entity.Guid = (uint)random.Next(1000000, Int32.MaxValue);
                                    }while (mlo.Entities.Count(e => e.Guid == entity.Guid) == 1);

                                    Console.WriteLine("[" + i + "] Setting random GUID => " + entity.Guid);
                                }

                                ymapEntities.Add(entity);
                            }

                            ymap.CMapData.Entities = ymapEntities;

                            var extents = Utils.CalcExtents(ymap.CMapData.Entities);

                            ymap.CMapData.EntitiesExtentsMin  = extents[0][0];
                            ymap.CMapData.EntitiesExtentsMax  = extents[0][1];
                            ymap.CMapData.StreamingExtentsMin = extents[1][0];
                            ymap.CMapData.StreamingExtentsMax = extents[1][1];

                            Console.WriteLine(extents[0][0].X + " " + extents[0][0].Y + " " + extents[0][0].Z);
                            Console.WriteLine(extents[0][1].X + " " + extents[0][1].Y + " " + extents[0][1].Z);

                            ymap.Save(opts.Name + "\\entitysets\\" + entitySet.Name + "\\entityset_" + entitySet.Name + "_" + room.Name + ".ymap");
                        }
                    }
                }

                /*
                 * for(int portalId=0; portalId < mlo.Portals.Count; portalId++)
                 * {
                 *  var portal = mlo.Portals[portalId];
                 *  var ymap = new YmapFile();
                 *  var ymapEntities = new List<MCEntityDef>();
                 *  var entitiesExtents = new List<Tuple<Vector3, Vector3>>();
                 *  var streamingExtents = new List<Tuple<Vector3, Vector3>>();
                 *
                 *  Console.WriteLine("Portal => " + portalId + " (" + portal.AttachedObjects.Count + " entities)");
                 *
                 *  for (int i = 0; i < portal.AttachedObjects.Count; i++)
                 *  {
                 *      int idx = (int)portal.AttachedObjects[i];
                 *
                 *      if (idx >= mlo.Entities.Count)
                 *          continue;
                 *
                 *      var entity = mlo.Entities[idx];
                 *      var entityRotation = new Quaternion(entity.Rotation.X, entity.Rotation.Y, entity.Rotation.Z, entity.Rotation.W);
                 *
                 *      Utils.Mlo2World(entity, mlo, position, rotation);
                 *
                 *      entity.LodLevel = Unk_1264241711.LODTYPES_DEPTH_HD;
                 *
                 *      if (entity.Guid == 0)
                 *      {
                 *          var random = new Random();
                 *
                 *          do
                 *          {
                 *              entity.Guid = (uint)random.Next(1000000, Int32.MaxValue);
                 *          }
                 *          while (mlo.Entities.Count(e => e.Guid == entity.Guid) == 1);
                 *
                 *          Console.WriteLine("[" + i + "] Setting random GUID => " + entity.Guid);
                 *      }
                 *
                 *      ymapEntities.Add(entity);
                 *  }
                 *
                 *  ymap.CMapData.Entities = ymapEntities;
                 *
                 *  var extents = Utils.CalcExtents(ymap.CMapData.Entities);
                 *
                 *  ymap.CMapData.EntitiesExtentsMin = extents[0][0];
                 *  ymap.CMapData.EntitiesExtentsMax = extents[0][1];
                 *  ymap.CMapData.StreamingExtentsMin = extents[1][0];
                 *  ymap.CMapData.StreamingExtentsMax = extents[1][1];
                 *
                 *  Console.WriteLine(extents[0][0].X + " " + extents[0][0].Y + " " + extents[0][0].Z);
                 *  Console.WriteLine(extents[0][1].X + " " + extents[0][1].Y + " " + extents[0][1].Z);
                 *
                 *  Directory.CreateDirectory(opts.Name);
                 *
                 *  ymap.Save(opts.Name + "\\portal_" + portalId.ToString().PadLeft(3, '0') + ".ymap");
                 *
                 *  var data = new JObject()
                 *  {
                 *      ["corners"] = new JArray()
                 *      {
                 *          new JObject() { ["x"] = portal.Corners[0][0], ["y"] = portal.Corners[0][1], ["z"] = portal.Corners[0][2] },
                 *          new JObject() { ["x"] = portal.Corners[1][0], ["y"] = portal.Corners[1][1], ["z"] = portal.Corners[1][2] },
                 *          new JObject() { ["x"] = portal.Corners[2][0], ["y"] = portal.Corners[2][1], ["z"] = portal.Corners[2][2] },
                 *          new JObject() { ["x"] = portal.Corners[3][0], ["y"] = portal.Corners[3][1], ["z"] = portal.Corners[3][2] },
                 *      },
                 *      ["flags"] = portal.Flags,
                 *      ["mirrorPriority"] = portal.MirrorPriority,
                 *      ["opacity"] = portal.Opacity,
                 *      ["roomFrom"] = portal.RoomFrom,
                 *      ["roomTo"] = portal.RoomTo,
                 *  };
                 *
                 *  var jsonString = JsonConvert.SerializeObject(data, new JsonSerializerSettings() { Formatting = Newtonsoft.Json.Formatting.Indented });
                 *
                 *  File.WriteAllText(opts.Name + "\\portal_" + portalId.ToString().PadLeft(3, '0') + ".json", jsonString);
                 * }
                 */
            });
        }
Example #26
0
 public RenderableLODLights GetRenderableLODLights(YmapFile ymap)
 {
     return(lodlights.Get(ymap));
 }
Example #27
0
        private void startButton_Click(object sender, EventArgs e)
        {
            timerTime            = DateTime.Now;
            watch                = new System.Threading.Timer(Tick, null, 0, 10);
            cancelButton.Enabled = true;
            var errorFiles = new List <string>()
            {
            };

            new Thread(() =>
            {
                Thread.CurrentThread.IsBackground = true;
                //while (cancelLoop)
                //{
                for (var j = 0; j < CurrentList.Items.Count; j++)
                {
                    string filename      = CurrentList.Items[j].ToString();
                    FilesAddedLabel.Text = "Processing " + Path.GetFileName(filename) + " (" + (j + 1) + " of " + CurrentList.Items.Count + ")";

                    Vector3 moveVec = new Vector3(float.Parse(xMove.Text), float.Parse(yMove.Text), float.Parse(zMove.Text));
                    //Quaternion rotVec = Quaternion.RotationYawPitchRoll(float.Parse(xRotate.Text), float.Parse(yRotate.Text), float.Parse(zRotate.Text));

                    if (backupFilesToolStripMenuItem.Checked)
                    {
                        if (!filename.Contains(".rpf"))
                        {
                            File.Copy(filename, $"{filename}.old", true);
                        }
                        else
                        {
                            string fileDirectory = StringFunctions.TopMostRPF(filename);
                            File.Copy(fileDirectory, Path.Combine(fileDirectory, ".old"));
                        }
                    }

                    if (filename.EndsWith(".ybn"))
                    {
                        YbnFile ybn = new YbnFile();
                        RpfDirectoryEntry RPFFilesDirectory;
                        byte[] oldData;
                        if (filename.Contains(".rpf"))
                        {
                            string fileDirectory = StringFunctions.TopMostRPF(filename);
                            if (File.Exists(filename))
                            {
                                RPFFilesDirectory = null;
                                oldData           = File.ReadAllBytes(filename);
                            }
                            else
                            {
                                RpfFile TopRPF = new RpfFile(fileDirectory, fileDirectory);
                                TopRPF.ScanStructure(null, null);
                                (RPFFilesDirectory, oldData) = RPFFunctions.GetFileData(TopRPF, Path.GetFileName(filename));
                            }
                        }
                        else
                        {
                            RPFFilesDirectory = null;
                            oldData           = File.ReadAllBytes(filename);
                        }

                        try
                        {
                            ybn.Load(oldData);

                            if (ybn.Bounds != null)
                            {
                                ybn.Bounds.BoxCenter    += moveVec;
                                ybn.Bounds.BoxMax       += moveVec;
                                ybn.Bounds.BoxMin       += moveVec;
                                ybn.Bounds.SphereCenter += moveVec;

                                BoundComposite boundcomp = ybn.Bounds as BoundComposite;
                                var compchilds           = boundcomp?.Children?.data_items;
                                if (boundcomp.BVH != null)
                                {
                                    Vector3 boundcompBBC            = MathFunctions.ConvertToVec3(boundcomp.BVH.BoundingBoxCenter);
                                    Vector3 boundcompBBMax          = MathFunctions.ConvertToVec3(boundcomp.BVH.BoundingBoxMax);
                                    Vector3 boundcompBBMin          = MathFunctions.ConvertToVec3(boundcomp.BVH.BoundingBoxMin);
                                    boundcomp.BVH.BoundingBoxCenter = new Vector4(boundcompBBC + moveVec, boundcomp.BVH.BoundingBoxCenter.W);
                                    boundcomp.BVH.BoundingBoxMax    = new Vector4(boundcompBBMax + moveVec, boundcomp.BVH.BoundingBoxMax.W);
                                    boundcomp.BVH.BoundingBoxMin    = new Vector4(boundcompBBMin + moveVec, boundcomp.BVH.BoundingBoxMin.W);
                                }
                                if (compchilds != null)
                                {
                                    for (int i = 0; i < compchilds.Length; i++)
                                    {
                                        compchilds[i].BoxCenter    += moveVec;
                                        compchilds[i].BoxMax       += moveVec;
                                        compchilds[i].BoxMin       += moveVec;
                                        compchilds[i].SphereCenter += moveVec;
                                        BoundBVH bgeom              = compchilds[i] as BoundBVH;
                                        if (bgeom != null)
                                        {
                                            if (bgeom.BVH != null)
                                            {
                                                Vector3 bgeomBBC            = MathFunctions.ConvertToVec3(bgeom.BVH.BoundingBoxCenter);
                                                Vector3 bgeomBBMax          = MathFunctions.ConvertToVec3(bgeom.BVH.BoundingBoxMax);
                                                Vector3 bgeomBBMin          = MathFunctions.ConvertToVec3(bgeom.BVH.BoundingBoxMin);
                                                bgeom.BVH.BoundingBoxCenter = new Vector4(bgeomBBC + moveVec, bgeom.BVH.BoundingBoxCenter.W);
                                                bgeom.BVH.BoundingBoxMax    = new Vector4(bgeomBBMax + moveVec, bgeom.BVH.BoundingBoxMax.W);
                                                bgeom.BVH.BoundingBoxMin    = new Vector4(bgeomBBMin + moveVec, bgeom.BVH.BoundingBoxMin.W);
                                            }
                                            bgeom.CenterGeom = bgeom.CenterGeom + moveVec;
                                        }
                                    }
                                }
                            }
                            byte[] newData = ybn.Save();
                            if (filename.Contains(".rpf"))
                            {
                                if (File.Exists(filename))
                                {
                                    RPFFilesDirectory = null;
                                    oldData           = File.ReadAllBytes(filename);
                                }
                                else
                                {
                                    RPFFunctions.AddFileBackToRPF(RPFFilesDirectory, filename, newData);
                                }
                            }
                            else
                            {
                                File.WriteAllBytes(filename, newData);
                            }
                        }
                        catch (Exception)
                        {
                            errorFiles.Add(filename);
                        }
                    }
                    else if (filename.EndsWith(".ymap"))
                    {
                        YmapFile ymap = new YmapFile();
                        RpfDirectoryEntry RPFFilesDirectory;
                        byte[] oldData;
                        if (filename.Contains(".rpf"))
                        {
                            string fileDirectory = StringFunctions.TopMostRPF(filename);
                            if (File.Exists(filename))
                            {
                                RPFFilesDirectory = null;
                                oldData           = File.ReadAllBytes(filename);
                            }
                            else
                            {
                                RpfFile TopRPF = new RpfFile(fileDirectory, fileDirectory);
                                TopRPF.ScanStructure(null, null);
                                (RPFFilesDirectory, oldData) = RPFFunctions.GetFileData(TopRPF, Path.GetFileName(filename));
                            }
                        }
                        else
                        {
                            RPFFilesDirectory = null;
                            oldData           = File.ReadAllBytes(filename);
                        }

                        try
                        {
                            ymap.Load(oldData);
                            if (ymap.CarGenerators != null)
                            {
                                foreach (YmapCarGen yEnts in ymap.CarGenerators)
                                {
                                    yEnts.SetPosition(yEnts.Position + moveVec);
                                    //yEnts.Orientation = Quaternion.Add(yEnts.Orientation, rotVec);
                                }
                            }
                            if (ymap.AllEntities != null)
                            {
                                foreach (YmapEntityDef yEnts in ymap.AllEntities)
                                {
                                    yEnts.SetPosition(yEnts.Position + moveVec);
                                    //yEnts.Orientation = Quaternion.Add(yEnts.Orientation, rotVec);
                                }
                            }
                            if (ymap.DistantLODLights != null)
                            {
                                int lightCount = ymap._CMapData.DistantLODLightsSOA.position.Count1;
                                for (int i = 0; i < lightCount; i++)
                                {
                                    Vector3 vector3     = ymap.DistantLODLights.positions[i].ToVector3() + moveVec;
                                    MetaVECTOR3 metaVec = new MetaVECTOR3 {
                                        x = vector3.X, y = vector3.Y, z = vector3.Z
                                    };
                                    ymap.DistantLODLights.positions[i] = metaVec;
                                }
                            }
                            if (ymap.GrassInstanceBatches != null)
                            {
                                foreach (YmapGrassInstanceBatch yEnts in ymap.GrassInstanceBatches)
                                {
                                    yEnts.Position += moveVec;
                                    yEnts.AABBMin  += moveVec;
                                    yEnts.AABBMax  += moveVec;
                                }
                            }

                            ymap._CMapData.streamingExtentsMax = ymap.CMapData.streamingExtentsMax + moveVec;
                            ymap._CMapData.streamingExtentsMin = ymap.CMapData.streamingExtentsMin + moveVec;
                            ymap._CMapData.entitiesExtentsMax  = ymap.CMapData.entitiesExtentsMax + moveVec;
                            ymap._CMapData.entitiesExtentsMin  = ymap.CMapData.entitiesExtentsMin + moveVec;

                            byte[] newData = ymap.Save();
                            if (filename.Contains(".rpf"))
                            {
                                if (File.Exists(filename))
                                {
                                    RPFFilesDirectory = null;
                                    oldData           = File.ReadAllBytes(filename);
                                }
                                else
                                {
                                    RPFFunctions.AddFileBackToRPF(RPFFilesDirectory, filename, newData);
                                }
                            }
                            else
                            {
                                File.WriteAllBytes(filename, newData);
                            }
                        }
                        catch (Exception)
                        {
                            errorFiles.Add(filename);
                        }
                    }
                }
                if (errorFiles.Count != 0)
                {
                    string message = "The following file(s) were corrupted and were not edited.\n\n";
                    foreach (string item in errorFiles)
                    {
                        message = message + item + "\n";
                    }

                    MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                FilesAddedLabel.Text = "Complete";
                cancelButton.Enabled = false;
                watch.Dispose();
                //}
            }).Start();
        }
Example #28
0
        private void EntitySearchButton_Click(object sender, EventArgs e)
        {
            var s          = EntitySearchTextBox.Text;
            var loadedOnly = EntitySearchLoadedOnlyCheckBox.Checked;

            var gfc = WorldForm.GameFileCache;

            if (!gfc.IsInited)
            {
                MessageBox.Show("Please wait for CodeWalker to initialise.");
                return;
            }
            if (s.Length == 0)
            {
                MessageBox.Show("Please enter a search term.");
                return;
            }
            if (s.Length < 2)
            {
                MessageBox.Show("You don't really want to search for that do you?");
                return;
            }

            EntitySearchTextBox.Enabled             = false;
            EntitySearchButton.Enabled              = false;
            EntitySearchAbortButton.Enabled         = true;
            EntitySearchLoadedOnlyCheckBox.Enabled  = false;
            EntitySearchExportResultsButton.Enabled = false;
            AbortOperation = false;
            EntityResults.Clear();
            EntityResultsListView.VirtualListSize = 0;

            s = s.ToLowerInvariant();
            //var h = JenkHash.GenHash(s, JenkHashInputEncoding.UTF8);

            Task.Run(() =>
            {
                var rpfman  = gfc.RpfMan;
                var rpflist = loadedOnly ? gfc.ActiveMapRpfFiles.Values.ToList() : rpfman.AllRpfs;
                var results = new List <YmapEntityDef>();

                foreach (var rpf in rpflist)
                {
                    foreach (var entry in rpf.AllEntries)
                    {
                        try
                        {
                            if (AbortOperation)
                            {
                                EntitySearchUpdateStatus("Search aborted!");
                                EntitySearchComplete();
                                return;
                            }
                            if (entry.NameLower.EndsWith(".ymap"))
                            {
                                EntitySearchUpdateStatus(entry.Path);

                                YmapFile ymap = rpfman.GetFile <YmapFile>(entry);
                                if (ymap == null)
                                {
                                    continue;
                                }
                                if (ymap.AllEntities == null)
                                {
                                    continue;
                                }

                                foreach (var ent in ymap.AllEntities)
                                {
                                    //if (ent._CEntityDef.archetypeName.Hash == h)
                                    if (ent.Name.ToLowerInvariant().Contains(s))
                                    {
                                        EntitySearchAddResult(ent);
                                        results.Add(ent);
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            EntitySearchUpdateStatus(ex.Message);
                        }
                    }
                }

                EntitySearchUpdateStatus("Search complete. " + results.Count.ToString() + " entities found.");
                EntitySearchComplete();
            });
        }
Example #29
0
        static void HandleBuildCacheOptions(string[] args)
        {
            CommandLine.Parse <BuildCacheOptions>(args, (opts, gOpts) =>
            {
                Init(args);

                dynamic cache = new JObject();

                cache["ymap"] = new JArray();
                cache["ytyp"] = new JArray();

                Console.WriteLine("Building strings");

                var names = FileUtilities.GetAllFileNamesWithoutExtension(Settings.Default.GTAFolder);

                foreach (var name in names)
                {
                    Utils.Hash(name.ToLowerInvariant().Replace("_children", ""));
                }

                using (StreamWriter writer = new StreamWriter(AssemblyDirectory + "\\strings.txt"))
                {
                    foreach (var kvp in Jenkins.Index)
                    {
                        writer.Write(kvp.Value + "\n");
                    }
                }

                Console.WriteLine("Bulding cache");

                ArchiveUtilities.ForEachFile(Settings.Default.GTAFolder, (fullFileName, file, encryption) =>
                {
                    string fileNameWithoutExtension = FileUtilities.RemoveExtension(file.Name);

                    try
                    {
                        if (file.Name.EndsWith(".ymap"))
                        {
                            Console.WriteLine(fullFileName);

                            var ymap = new YmapFile();

                            using (MemoryStream ms = new MemoryStream())
                            {
                                file.Export(ms);
                                ymap.Load(ms, new object[] { true });
                            }

                            dynamic entry = new JObject()
                            {
                                ["name"]               = fileNameWithoutExtension,
                                ["path"]               = fullFileName,
                                ["hash"]               = Jenkins.Hash(fileNameWithoutExtension),
                                ["parent"]             = (uint)ymap.CMapData.Parent,
                                ["entitiesExtentsMin"] = new JObject()
                                {
                                    ["x"] = ymap.CMapData.EntitiesExtentsMin.X,
                                    ["y"] = ymap.CMapData.EntitiesExtentsMin.Y,
                                    ["z"] = ymap.CMapData.EntitiesExtentsMin.Z,
                                },
                                ["entitiesExtentsMax"] = new JObject()
                                {
                                    ["x"] = ymap.CMapData.EntitiesExtentsMax.X,
                                    ["y"] = ymap.CMapData.EntitiesExtentsMax.Y,
                                    ["z"] = ymap.CMapData.EntitiesExtentsMax.Z,
                                },
                                ["mloInstances"] = new JArray(),
                            };

                            if (ymap.CMapData.MloInstances != null)
                            {
                                for (int i = 0; i < ymap.CMapData.MloInstances.Count; i++)
                                {
                                    var mloInstance = ymap.CMapData.MloInstances[i];

                                    var mloInstanceEntry = new JObject()
                                    {
                                        ["name"]     = ymap.CMapData.MloInstances[i].ArchetypeName,
                                        ["position"] = new JObject()
                                        {
                                            ["x"] = mloInstance.Position.X,
                                            ["y"] = mloInstance.Position.Y,
                                            ["z"] = mloInstance.Position.Z,
                                        },
                                        ["rotation"] = new JObject()
                                        {
                                            ["x"] = mloInstance.Rotation.X,
                                            ["y"] = mloInstance.Rotation.Y,
                                            ["z"] = mloInstance.Rotation.Z,
                                            ["w"] = mloInstance.Rotation.W,
                                        }
                                    };

                                    entry["mloInstances"].Add(mloInstanceEntry);
                                }
                            }

                            cache["ymap"].Add(entry);
                        }
                        else if (file.Name.EndsWith(".ytyp"))
                        {
                            Console.WriteLine(fullFileName);

                            var ytyp = new YtypFile();

                            using (MemoryStream ms = new MemoryStream())
                            {
                                file.Export(ms);
                                ytyp.Load(ms);
                            }

                            dynamic entry = new JObject()
                            {
                                ["name"]          = fileNameWithoutExtension,
                                ["path"]          = fullFileName,
                                ["hash"]          = Jenkins.Hash(fileNameWithoutExtension),
                                ["mloArchetypes"] = new JArray(),
                            };

                            if (ytyp.CMapTypes.MloArchetypes != null)
                            {
                                for (int i = 0; i < ytyp.CMapTypes.MloArchetypes.Count; i++)
                                {
                                    var archetype = ytyp.CMapTypes.MloArchetypes[i];
                                    var mloEntry  = new JObject
                                    {
                                        ["name"]  = archetype.Name,
                                        ["rooms"] = new JArray(),
                                    };

                                    if (archetype.Rooms != null)
                                    {
                                        for (int j = 0; j < archetype.Rooms.Count; j++)
                                        {
                                            var room      = archetype.Rooms[j];
                                            var roomEntry = new JObject
                                            {
                                                ["name"]  = room.Name,
                                                ["bbMin"] = new JObject()
                                                {
                                                    ["x"] = room.BbMin.X,
                                                    ["y"] = room.BbMin.Y,
                                                    ["z"] = room.BbMin.Z,
                                                },
                                                ["bbMax"] = new JObject()
                                                {
                                                    ["x"] = room.BbMax.X,
                                                    ["y"] = room.BbMax.Y,
                                                    ["z"] = room.BbMax.Z,
                                                }
                                            };

                                            ((JArray)mloEntry["rooms"]).Add(roomEntry);
                                        }
                                    }

                                    entry["mloArchetypes"].Add(mloEntry);
                                }
                            }

                            cache["ytyp"].Add(entry);
                        }
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                    }
                });

                var jsonString = JsonConvert.SerializeObject(cache, new JsonSerializerSettings()
                {
                    Formatting = Newtonsoft.Json.Formatting.None
                });

                File.WriteAllText(AssemblyDirectory + "\\cache.json", jsonString);
            });
        }
Example #30
0
        static void Main(string[] args)
        {
            EnsurePath();
            EnsureKeys();
            EnsureCache();

            CommandLine.Parse <GenPropDefsOptions>(args, opts =>
            {
                if (opts.InputFiles != null)
                {
                    var inputFiles = Utils.Expand(opts.InputFiles);
                    var ytyp       = new YtypFile();

                    for (int i = 0; i < inputFiles.Length; i++)
                    {
                        var fileInfo = inputFiles[i];

                        string name = "";
                        var split   = fileInfo.Name.Split('.');

                        for (int j = 0; j < split.Length; j++)
                        {
                            if (j < split.Length - 1)
                            {
                                if (j > 0)
                                {
                                    name += ".";
                                }

                                name += split[j];
                            }
                        }

                        Console.WriteLine(name);

                        try
                        {
                            switch (fileInfo.Extension)
                            {
                            case ".ydr":
                                {
                                    var ydr      = new YdrFile();
                                    var arch     = new RageLib.GTA5.ResourceWrappers.PC.Meta.Structures.CBaseArchetypeDef();
                                    var nameHash = (MetaName)Jenkins.Hash(name);

                                    ydr.Load(fileInfo.FullName);

                                    arch.Name              = nameHash;
                                    arch.AssetName         = nameHash;
                                    arch.TextureDictionary = nameHash;
                                    arch.PhysicsDictionary = (MetaName)Jenkins.Hash("prop_" + name);
                                    arch.Flags             = 32;
                                    arch.AssetType         = Unk_1991964615.ASSET_TYPE_DRAWABLE;
                                    arch.BbMin             = (Vector3)(Vector4)ydr.Drawable.BoundingBoxMin;
                                    arch.BbMax             = (Vector3)(Vector4)ydr.Drawable.BoundingBoxMax;
                                    arch.BsCentre          = (Vector3)ydr.Drawable.BoundingCenter;
                                    arch.BsRadius          = ydr.Drawable.BoundingSphereRadius;
                                    arch.LodDist           = 500f;
                                    arch.HdTextureDist     = 5;

                                    ytyp.CMapTypes.Archetypes.Add(arch);

                                    break;
                                }

                            case ".ydd":     // TODO
                                {
                                    break;
                                }

                            default: break;
                            }
                        }
                        catch (Exception e)
                        {
                            Console.Error.WriteLine("ERROR => " + e.Message);
                        }
                    }

                    string path = (opts.Directory == null) ? @".\props.ytyp" : opts.Directory + @"\props.ytyp";

                    ytyp.Save(path);
                }
            });

            CommandLine.Parse <ImportMetaOptions>(args, opts =>
            {
                if (opts.InputFiles != null && opts.Directory != null)
                {
                    var inputFiles = Utils.Expand(opts.InputFiles);

                    for (int i = 0; i < inputFiles.Length; i++)
                    {
                        var fileInfo = inputFiles[i];

                        Console.WriteLine(fileInfo.FullName);

                        var doc = new XmlDocument();

                        doc.Load(fileInfo.FullName);

                        var res          = new ResourceFile_GTA5_pc <MetaFile>();
                        res.Version      = 2;
                        res.ResourceData = XmlMeta.GetMeta(doc);;

                        string fileName = fileInfo.FullName.Replace(".xml", "");

                        res.Save(fileName);
                    }
                }
            });

            CommandLine.Parse <ExportMetaOptions>(args, opts =>
            {
                if (opts.InputFiles != null && opts.Directory != null)
                {
                    var inputFiles = Utils.Expand(opts.InputFiles);

                    for (int i = 0; i < inputFiles.Length; i++)
                    {
                        var fileInfo = inputFiles[i];

                        Console.WriteLine(fileInfo.FullName);

                        var res = new ResourceFile_GTA5_pc <MetaFile>();
                        res.Load(fileInfo.FullName);

                        var xml = MetaXml.GetXml(res.ResourceData);

                        File.WriteAllText(opts.Directory + "\\" + fileInfo.Name + ".xml", xml);
                    }
                }
            });

            CommandLine.Parse <InjectEntitiesOptions>(args, opts =>
            {
                if (opts.Ymap == null)
                {
                    Console.WriteLine("Please provide source ymap file with --ymap");
                    return;
                }

                if (opts.Ytyp == null)
                {
                    Console.WriteLine("Please provide source ytyp file with --ytyp");
                    return;
                }

                if (opts.Room == null)
                {
                    Console.WriteLine("Please provide mlo room name with --room");
                    return;
                }

                if (opts.Position == null || opts.Position.Count() != 3)
                {
                    Console.WriteLine("Please provide a correct position ex: --position 120.5,1370.312,769.2");
                    return;
                }

                if (opts.Rotation == null || opts.Rotation.Count() != 4)
                {
                    Console.WriteLine("Plase provide a correct rotation ex: --rotation 0,0,0,1");
                    return;
                }

                if (opts.Name == null)
                {
                    Console.WriteLine("Plase provide new generated ytyp name with --name");
                    return;
                }

                var position = new Vector3(opts.Position.ElementAt(0), opts.Position.ElementAt(1), opts.Position.ElementAt(2));
                var rotation = new Quaternion(opts.Rotation.ElementAt(0), opts.Rotation.ElementAt(1), opts.Rotation.ElementAt(2), opts.Rotation.ElementAt(3));

                var ymap = new YmapFile();
                var ytyp = new YtypFile();

                ymap.Load(opts.Ymap);
                ytyp.Load(opts.Ytyp);

                RageLib.GTA5.ResourceWrappers.PC.Meta.Structures.CMloArchetypeDef mlo = null;

                for (int i = 0; i < ytyp.CMapTypes.MloArchetypes.Count; i++)
                {
                    mlo = ytyp.CMapTypes.MloArchetypes[i];
                    break;
                }

                if (mlo == null)
                {
                    Console.WriteLine("MLO archetype not found");
                    return;
                }

                RageLib.GTA5.ResourceWrappers.PC.Meta.Structures.CMloRoomDef room = null;

                for (int i = 0; i < mlo.Rooms.Count; i++)
                {
                    if (mlo.Rooms[i].Name == opts.Room)
                    {
                        room = mlo.Rooms[i];
                        break;
                    }
                }

                if (room == null)
                {
                    Console.WriteLine("MLO room not found");
                    return;
                }

                var mloEntities     = new List <RageLib.GTA5.ResourceWrappers.PC.Meta.Structures.CEntityDef>();
                var attachedObjects = new List <uint>();

                mloEntities.AddRange(mlo.Entities);
                attachedObjects.AddRange(room.AttachedObjects);

                for (int i = 0; i < ymap.CMapData.Entities.Count; i++)
                {
                    var entity       = ymap.CMapData.Entities[i];
                    var mloRot       = rotation;
                    var objRot       = new Quaternion(entity.Rotation.X, entity.Rotation.Y, entity.Rotation.Z, entity.Rotation.W);
                    var rotationDiff = objRot * mloRot;                                                                    // Multiply initial entity rotation by mlo rotation

                    entity.Position -= position;                                                                           // Substract mlo world coords from entity world coords
                    entity.Position  = Utils.RotateTransform(Quaternion.Conjugate(mloRot), entity.Position, Vector3.Zero); // Rotate entity around center of mlo instance (mlo entities rotations in space are inverted)
                    entity.Rotation  = new Vector4(rotationDiff.X, rotationDiff.Y, rotationDiff.Z, rotationDiff.W);

                    mloEntities.Add(entity);
                    attachedObjects.Add((uint)mloEntities.IndexOf(entity));
                }

                mlo.Entities         = mloEntities;
                room.AttachedObjects = attachedObjects;

                ytyp.Save(opts.Name.EndsWith(".ytyp") ? opts.Name : opts.Name + ".ytyp");
            });

            CommandLine.Parse <FindOptions>(args, opts =>
            {
                if (opts.Position == null || opts.Position.Count != 3)
                {
                    Console.Error.WriteLine("Please specify position with -p --position");
                    return;
                }

                if (Cache == null)
                {
                    Console.Error.WriteLine("Please build cache first with buildcache");
                    return;
                }

                var c = CultureInfo.InvariantCulture;

                for (int i = 0; i < Cache["ymap"].Count; i++)
                {
                    var cYmap = Cache["ymap"][i];

                    var entitiesExtentsMin = new Vector3((float)cYmap["entitiesExtentsMin"]["x"], (float)cYmap["entitiesExtentsMin"]["y"], (float)cYmap["entitiesExtentsMin"]["z"]);
                    var entitiesExtentsMax = new Vector3((float)cYmap["entitiesExtentsMax"]["x"], (float)cYmap["entitiesExtentsMax"]["y"], (float)cYmap["entitiesExtentsMax"]["z"]);

                    if (
                        opts.Position[0] >= entitiesExtentsMin.X && opts.Position[0] <= entitiesExtentsMax.X &&
                        opts.Position[1] >= entitiesExtentsMin.Y && opts.Position[1] <= entitiesExtentsMax.Y &&
                        opts.Position[2] >= entitiesExtentsMin.Z && opts.Position[2] <= entitiesExtentsMax.Z
                        )
                    {
                        Console.WriteLine("ymap: " + ((string)cYmap["path"]).Split('\\').Last());

                        for (int j = 0; j < cYmap["mloInstances"].Count; j++)
                        {
                            var cMloInstance     = cYmap["mloInstances"][j];
                            var cMloInstanceHash = (uint)cMloInstance["name"];

                            var instancePos = new Vector3((float)cMloInstance["position"]["x"], (float)cMloInstance["position"]["y"], (float)cMloInstance["position"]["z"]);
                            var instanceRot = new Quaternion((float)cMloInstance["rotation"]["x"], (float)cMloInstance["rotation"]["y"], (float)cMloInstance["rotation"]["z"], (float)cMloInstance["rotation"]["w"]);

                            for (int k = 0; k < Cache["ytyp"].Count; k++)
                            {
                                var cYtyp     = Cache["ytyp"][k];
                                var cYtypHash = (uint)cYtyp["hash"];

                                for (int l = 0; l < cYtyp["mloArchetypes"].Count; l++)
                                {
                                    var cMloArch     = cYtyp["mloArchetypes"][l];
                                    var cMloArchHash = (uint)cMloArch["name"];

                                    if (cMloInstanceHash == cMloArchHash)
                                    {
                                        Console.WriteLine("  ytyp => " + ((string)cYtyp["path"]).Split('\\').Last());
                                        Console.WriteLine("    mlo => " + Jenkins.GetString(cMloArchHash));
                                        Console.WriteLine("    position => " + instancePos.X.ToString(c) + "," + instancePos.Y.ToString(c) + "," + instancePos.Z.ToString(c));
                                        Console.WriteLine("    rotation => " + instanceRot.X.ToString(c) + "," + instanceRot.Y.ToString(c) + "," + instanceRot.Z.ToString(c) + "," + instanceRot.W.ToString(c));

                                        for (int m = 0; m < cMloArch["rooms"].Count; m++)
                                        {
                                            var cMloRoom = cMloArch["rooms"][m];

                                            var roomBbMin = new Vector3((float)cMloRoom["bbMin"]["x"], (float)cMloRoom["bbMin"]["y"], (float)cMloRoom["bbMin"]["z"]);
                                            var roomBbMax = new Vector3((float)cMloRoom["bbMax"]["x"], (float)cMloRoom["bbMax"]["y"], (float)cMloRoom["bbMax"]["z"]);

                                            var roomBbMinWorld = instancePos + roomBbMin;
                                            var roomBbMaxWorld = instancePos + roomBbMax;

                                            roomBbMinWorld = Utils.RotateTransform(Quaternion.Conjugate(instanceRot), roomBbMinWorld, Vector3.Zero);
                                            roomBbMaxWorld = Utils.RotateTransform(Quaternion.Conjugate(instanceRot), roomBbMaxWorld, Vector3.Zero);

                                            if (
                                                opts.Position[0] >= roomBbMinWorld.X && opts.Position[0] <= roomBbMaxWorld.X &&
                                                opts.Position[1] >= roomBbMinWorld.Y && opts.Position[1] <= roomBbMaxWorld.Y &&
                                                opts.Position[2] >= roomBbMinWorld.Z && opts.Position[2] <= roomBbMaxWorld.Z
                                                )
                                            {
                                                Console.WriteLine("      room => " + cMloRoom["name"]);
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        Console.WriteLine("");
                    }
                }
            });

            CommandLine.Parse <BuildCacheOptions>(args, opts =>
            {
                dynamic cache = new JObject();

                cache["ymap"] = new JArray();
                cache["ytyp"] = new JArray();

                ArchiveUtilities.ForEachFile(Settings.Default.GTAFolder, (fullFileName, file, encryption) =>
                {
                    Console.WriteLine(fullFileName);

                    string fileNameWithoutExtension = file.Name.Split('.').First();

                    Jenkins.Ensure(fileNameWithoutExtension);

                    if (file.Name.EndsWith(".ymap"))
                    {
                        var ymap = new YmapFile();

                        using (MemoryStream ms = new MemoryStream())
                        {
                            file.Export(ms);
                            ymap.Load(ms);
                        }

                        dynamic entry = new JObject()
                        {
                            ["name"] = fileNameWithoutExtension,
                            ["path"] = fullFileName,
                            ["hash"] = Jenkins.Hash(fileNameWithoutExtension),
                            ["entitiesExtentsMin"] = new JObject()
                            {
                                ["x"] = ymap.CMapData.EntitiesExtentsMin.X,
                                ["y"] = ymap.CMapData.EntitiesExtentsMin.Y,
                                ["z"] = ymap.CMapData.EntitiesExtentsMin.Z,
                            },
                            ["entitiesExtentsMax"] = new JObject()
                            {
                                ["x"] = ymap.CMapData.EntitiesExtentsMax.X,
                                ["y"] = ymap.CMapData.EntitiesExtentsMax.Y,
                                ["z"] = ymap.CMapData.EntitiesExtentsMax.Z,
                            },
                            ["mloInstances"] = new JArray(),
                        };

                        if (ymap.CMapData.MloInstances != null)
                        {
                            for (int i = 0; i < ymap.CMapData.MloInstances.Count; i++)
                            {
                                var mloInstance = ymap.CMapData.MloInstances[i];

                                var mloInstanceEntry = new JObject()
                                {
                                    ["name"]     = ymap.CMapData.MloInstances[i].ArchetypeName,
                                    ["position"] = new JObject()
                                    {
                                        ["x"] = mloInstance.Position.X,
                                        ["y"] = mloInstance.Position.Y,
                                        ["z"] = mloInstance.Position.Z,
                                    },
                                    ["rotation"] = new JObject()
                                    {
                                        ["x"] = mloInstance.Rotation.X,
                                        ["y"] = mloInstance.Rotation.Y,
                                        ["z"] = mloInstance.Rotation.Z,
                                        ["w"] = mloInstance.Rotation.W,
                                    }
                                };

                                entry["mloInstances"].Add(mloInstanceEntry);
                            }
                        }

                        cache["ymap"].Add(entry);
                    }
                    else if (file.Name.EndsWith(".ytyp"))
                    {
                        var ytyp = new YtypFile();

                        using (MemoryStream ms = new MemoryStream())
                        {
                            file.Export(ms);
                            ytyp.Load(ms);
                        }

                        dynamic entry = new JObject()
                        {
                            ["name"]          = fileNameWithoutExtension,
                            ["path"]          = fullFileName,
                            ["hash"]          = Jenkins.Hash(fileNameWithoutExtension),
                            ["mloArchetypes"] = new JArray(),
                        };

                        if (ytyp.CMapTypes.MloArchetypes != null)
                        {
                            for (int i = 0; i < ytyp.CMapTypes.MloArchetypes.Count; i++)
                            {
                                var archetype = ytyp.CMapTypes.MloArchetypes[i];
                                var mloEntry  = new JObject
                                {
                                    ["name"]  = archetype.Name,
                                    ["rooms"] = new JArray(),
                                };

                                if (archetype.Rooms != null)
                                {
                                    for (int j = 0; j < archetype.Rooms.Count; j++)
                                    {
                                        var room      = archetype.Rooms[j];
                                        var roomEntry = new JObject
                                        {
                                            ["name"]  = room.Name,
                                            ["bbMin"] = new JObject()
                                            {
                                                ["x"] = room.BbMin.X,
                                                ["y"] = room.BbMin.Y,
                                                ["z"] = room.BbMin.Z,
                                            },
                                            ["bbMax"] = new JObject()
                                            {
                                                ["x"] = room.BbMax.X,
                                                ["y"] = room.BbMax.Y,
                                                ["z"] = room.BbMax.Z,
                                            }
                                        };

                                        ((JArray)mloEntry["rooms"]).Add(roomEntry);
                                    }
                                }

                                entry["mloArchetypes"].Add(mloEntry);
                            }
                        }

                        cache["ytyp"].Add(entry);
                    }
                });

                var jsonString = JsonConvert.SerializeObject(cache, new JsonSerializerSettings()
                {
                    Formatting = Newtonsoft.Json.Formatting.None
                });

                File.WriteAllText(AssemblyDirectory + "\\cache.json", jsonString);

                using (StreamWriter writer = new StreamWriter(AssemblyDirectory + "\\strings.txt"))
                {
                    foreach (var kvp in Jenkins.Index)
                    {
                        writer.Write(kvp.Value + "\n");
                    }
                }
            });

            if (args.Length == 0 || args[0] == "help")
            {
                Console.Error.Write(CommandLine.GenHelp());
                return;
            }
        }