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; }
private void LoadYtypTreeNodes(YtypFile ytyp, TreeNode node)//TODO! { }
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"); } }); }
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; } }
private void ArchetypeSearchButton_Click(object sender, EventArgs e) { var s = ArchetypeSearchTextBox.Text; var loadedOnly = false;// ArchetypeSearchLoadedOnlyCheckBox.Checked; //NOT WORKING... 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; } ArchetypeSearchTextBox.Enabled = false; ArchetypeSearchButton.Enabled = false; ArchetypeSearchAbortButton.Enabled = true; ArchetypeSearchExportResultsButton.Enabled = false; AbortOperation = false; ArchetypeResults.Clear(); ArchetypeResultsListView.VirtualListSize = 0; s = s.ToLowerInvariant(); Task.Run(() => { var rpfman = gfc.RpfMan; var rpflist = loadedOnly ? gfc.ActiveMapRpfFiles.Values.ToList() : rpfman.AllRpfs; var results = new List <Archetype>(); foreach (var rpf in rpflist) { foreach (var entry in rpf.AllEntries) { try { if (AbortOperation) { ArchetypeSearchUpdateStatus("Search aborted!"); ArchetypeSearchComplete(); return; } if (entry.NameLower.EndsWith(".ytyp")) { ArchetypeSearchUpdateStatus(entry.Path); YtypFile ytyp = rpfman.GetFile <YtypFile>(entry); if (ytyp == null) { continue; } if (ytyp.AllArchetypes == null) { continue; } foreach (var arch in ytyp.AllArchetypes) { if (arch.Name.ToLowerInvariant().Contains(s) || arch.AssetName.ToLowerInvariant().Contains(s)) { ArchetypeSearchAddResult(arch); results.Add(arch); } } } } catch (Exception ex) { ArchetypeSearchUpdateStatus(ex.Message); } } } ArchetypeSearchUpdateStatus("Search complete. " + results.Count.ToString() + " archetypes found."); ArchetypeSearchComplete(); }); }
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); * } */ }); }
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); }); }
static void HandleGenPropDefsOptions(string[] args) { CommandLine.Parse <GenPropDefsOptions>(args, (opts, gOpts) => { if (opts.InputFiles != null) { var inputFiles = Utils.Expand(opts.InputFiles); var ytyp = new YtypFile(); if (opts.Ytyp != null) { var inputYtyps = Utils.Expand(opts.Ytyp); for (int i = 0; i < inputYtyps.Length; i++) { var ytyp2 = new YtypFile(); ytyp2.Load(inputYtyps[i].FullName); for (int j = 0; j < ytyp2.CMapTypes.Archetypes.Count; j++) { var archetype = ytyp2.CMapTypes.Archetypes[j]; if (Archetypes.TryGetValue(archetype.Name, out MCBaseArchetypeDef arch)) { Archetypes[archetype.Name] = archetype; } else { Archetypes.Add(archetype.Name, archetype); } } } } 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 nameHash = (MetaName)Jenkins.Hash(name); var ydr = new YdrFile(); ydr.Load(fileInfo.FullName); if (Archetypes.TryGetValue(nameHash, out MCBaseArchetypeDef arch)) { 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; } else { arch = new MCBaseArchetypeDef(); 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.OutputDirectory == null) ? @".\props.ytyp" : opts.OutputDirectory + @"\props.ytyp"; ytyp.Save(path); } }); }