public CarGen(string oplstr) { OPLStr = oplstr; string[] parts = oplstr.Split(','); PosX = float.Parse(parts[0].Trim(), CultureInfo.InvariantCulture); PosY = float.Parse(parts[1].Trim(), CultureInfo.InvariantCulture); PosZ = float.Parse(parts[2].Trim(), CultureInfo.InvariantCulture); RotX = float.Parse(parts[3].Trim(), CultureInfo.InvariantCulture); RotY = float.Parse(parts[4].Trim(), CultureInfo.InvariantCulture); Length = float.Parse(parts[5].Trim(), CultureInfo.InvariantCulture); ModelName = parts[6].Trim().ToLowerInvariant(); CarColor1 = int.Parse(parts[7].Trim(), CultureInfo.InvariantCulture); CarColor2 = int.Parse(parts[8].Trim(), CultureInfo.InvariantCulture); CarColor3 = int.Parse(parts[9].Trim(), CultureInfo.InvariantCulture); SpecularColor = int.Parse(parts[10].Trim(), CultureInfo.InvariantCulture); Flags = uint.Parse(parts[11].Trim(), CultureInfo.InvariantCulture); Alarm = int.Parse(parts[12].Trim(), CultureInfo.InvariantCulture); Unk2 = int.Parse(parts[13].Trim(), CultureInfo.InvariantCulture); //if (model.StartsWith("hash:")) //{ // ModelName = model.Substring(5); // if (ModelName == "0") ModelName = string.Empty; //} //else //{ // ModelName = model; //} if (ModelName.StartsWith("hash:")) { string[] hparts = ModelName.Split(':'); uint hash; if (uint.TryParse(hparts[1].Trim(), out hash)) { string str = JenkIndex.TryGetString(hash); if (!string.IsNullOrEmpty(str)) { ModelName = str.ToLowerInvariant(); } else { ModelName = "hash_" + hash.ToString("X").ToLowerInvariant(); } } } }
public Entity(string oplstr) { OPLStr = oplstr; string[] parts = oplstr.Split(','); PosX = float.Parse(parts[0].Trim(), CultureInfo.InvariantCulture); PosY = float.Parse(parts[1].Trim(), CultureInfo.InvariantCulture); PosZ = float.Parse(parts[2].Trim(), CultureInfo.InvariantCulture); RotX = float.Parse(parts[3].Trim(), CultureInfo.InvariantCulture); RotY = float.Parse(parts[4].Trim(), CultureInfo.InvariantCulture); RotZ = float.Parse(parts[5].Trim(), CultureInfo.InvariantCulture); RotW = float.Parse(parts[6].Trim(), CultureInfo.InvariantCulture); Name = parts[7].Trim().ToLowerInvariant(); Flags = int.Parse(parts[8].Trim(), CultureInfo.InvariantCulture); ParentIndex = int.Parse(parts[9].Trim(), CultureInfo.InvariantCulture); Unk1 = int.Parse(parts[10].Trim(), CultureInfo.InvariantCulture); Unk2 = float.Parse(parts[11].Trim(), CultureInfo.InvariantCulture); if (Name.StartsWith("hash:")) { string[] hparts = Name.Split(':'); uint hash; if (uint.TryParse(hparts[1].Trim(), out hash)) { string str = JenkIndex.TryGetString(hash); if (!string.IsNullOrEmpty(str)) { Name = str.ToLowerInvariant(); } else { Name = "hash_" + hash.ToString("X").ToLowerInvariant(); } } } }
private void ProcessButton_Click(object sender, EventArgs e) { if (!Directory.Exists(InputFolderTextBox.Text)) { MessageBox.Show("Input folder doesn't exist: " + InputFolderTextBox.Text); return; } if (!Directory.Exists(OutputFolderTextBox.Text)) { MessageBox.Show("Output folder doesn't exist: " + OutputFolderTextBox.Text); return; } string inputpath = InputFolderTextBox.Text; string outputpath = OutputFolderTextBox.Text; string[] oplfiles = Directory.GetFiles(inputpath, "*.opl", SearchOption.TopDirectoryOnly); string[] videfiles = Directory.GetFiles(inputpath, "*.vopl.txt", SearchOption.TopDirectoryOnly); float hdloddist = float.Parse(HDLODDistTextBox.Text, CultureInfo.InvariantCulture); float lodloddist = float.Parse(LODLODDistTextBox.Text, CultureInfo.InvariantCulture); float slodloddist = float.Parse(SLODLODDistTextBox.Text, CultureInfo.InvariantCulture); float offsetx = float.Parse(OffsetXTextBox.Text, CultureInfo.InvariantCulture); float offsety = float.Parse(OffsetYTextBox.Text, CultureInfo.InvariantCulture); float offsetz = float.Parse(OffsetZTextBox.Text, CultureInfo.InvariantCulture); bool cargens = CarGeneratorsCheckBox.Checked; uint cargenflags = uint.Parse(CarGenFlagsTextBox.Text, CultureInfo.InvariantCulture); if (!outputpath.EndsWith("\\")) { outputpath = outputpath + "\\"; } StringBuilder errorlog = new StringBuilder(); Dictionary <string, MapFile> mapdict = new Dictionary <string, MapFile>(); Dictionary <string, VideInterior> intdict = new Dictionary <string, VideInterior>(); string stringsfile = inputpath + (inputpath.EndsWith("\\") ? "" : "\\") + "strings.txt"; if (File.Exists(stringsfile)) { string[] strings = File.ReadAllLines(stringsfile); foreach (var str in strings) { JenkIndex.Ensure(str); } } foreach (var videfile in videfiles) //load interior info files output from VIDE { try { VideFile vf = new VideFile(); vf.Load(videfile); foreach (var interior in vf.Interiors) { intdict[interior.Name] = interior; } } catch (Exception ex) { string err = "Error loading " + videfile + ":\n" + ex.ToString(); errorlog.AppendLine(err); } } foreach (var oplfile in oplfiles) //load opl files... { try { MapFile mf = new MapFile(); mf.Load(oplfile); mapdict[mf.Name] = mf; } catch (Exception ex) { string err = "Error loading " + oplfile + ":\n" + ex.ToString(); errorlog.AppendLine(err); } } foreach (var mf in mapdict.Values) //create map file hierarchy { int uscind = mf.Name.LastIndexOf('_'); if (uscind > 0) { string pname = mf.Name.Substring(0, uscind); MapFile parent = null; if (mapdict.TryGetValue(pname, out parent)) { mf.Parent = parent; parent.Children.Add(mf); } else { errorlog.AppendLine("Couldn't find parent " + pname + ".opl for " + mf.Name + "."); } } } foreach (var mf in mapdict.Values) //find parent entities { foreach (var ent in mf.AllEntities) { if (ent.ParentIndex >= 0) { if (mf.Parent != null) { if (ent.ParentIndex < mf.Parent.AllEntities.Count) { ent.Parent = mf.Parent.AllEntities[ent.ParentIndex]; } else { errorlog.AppendLine("Couldn't find parent entity for " + ent.Name + ". ParentIndex " + ent.ParentIndex.ToString() + " was out of range!"); } } else { if (ent.ParentIndex < mf.AllEntities.Count) { ent.Parent = mf.AllEntities[ent.ParentIndex]; } else { errorlog.AppendLine("Couldn't find parent entity for " + ent.Name + ". ParentIndex " + ent.ParentIndex.ToString() + " was out of range!"); } } } if (ent.Parent != null) { ent.Parent.NumChildren++; } } } foreach (var mf in mapdict.Values)//assign ChildDepth values and InteriorInfo to entities for later use { foreach (var ent in mf.AllEntities) { int depth = 0; var pent = ent.Parent; while (pent != null) { depth++; pent.ChildDepth = Math.Max(pent.ChildDepth, depth); pent = pent.Parent; } VideInterior interior; if (intdict.TryGetValue(ent.Name, out interior)) { ent.InteriorInfo = interior; } } } foreach (var mf in mapdict.Values) //process entities in map files, and assign new indices { mf.ProcessEntities(); } foreach (var mf in mapdict.Values) //assign map file parent names { var parent = mf.Parent; if (parent != null) { mf.ParentName = (parent.AllLodEntities.Count > 0) ? parent.Name + "_lod" : parent.Name; } } foreach (var mf in mapdict.Values) { if ((mf.Parent != null) && (mf.AllLodEntities.Count > 0)) { errorlog.AppendLine(mf.Name + " contains LOD entities, but also has a parent OPL. This is not supported and may result in problems!"); } foreach (var ent in mf.AllEntities) { ent.PosX += offsetx; //offset entity positions ent.PosY += offsety; ent.PosZ += offsetz; if (ent.Parent != null) //assign new parent indices { ent.NewParentIndex = ent.Parent.NewIndex; } } foreach (var ent in mf.SlodEntities) //set SLOD entity properties { ent.LODLevel = "LODTYPES_DEPTH_SLOD1"; ent.LODDist = slodloddist; ent.ChildLODDist = lodloddist; ent.Flags = 1572888; } foreach (var ent in mf.LodEntities) //set LOD entity properties { ent.LODLevel = "LODTYPES_DEPTH_LOD"; ent.LODDist = (ent.ParentIndex < 0) ? slodloddist : lodloddist; ent.ChildLODDist = hdloddist; ent.Flags = 1572864; } foreach (var ent in mf.AllHdEntities) { if (ent.ParentIndex >= 0) //set HD entity properties { ent.LODLevel = "LODTYPES_DEPTH_HD"; ent.LODDist = hdloddist; ent.Flags = 1572872; } else //set ORPHANHD properties { ent.LODLevel = "LODTYPES_DEPTH_ORPHANHD"; ent.Flags = 1572872; } } foreach (var ent in mf.AllEntities) { if (ent.InteriorInfo != null) { if (ent.ParentIndex >= 0) { errorlog.AppendLine("Entity " + ent.Name + " in " + mf.Name + " was marked as an interior, but its parentIndex is " + ent.ParentIndex.ToString() + ". This shouldn't happen, LODs may be broken!"); } ent.LODLevel = "LODTYPES_DEPTH_HD"; //milo entities should be HD, but they were processed as orphan. ent.LODDist = ent.InteriorInfo.LodDist; ent.ChildLODDist = 0; ent.Flags = 1572872; } } foreach (var cg in mf.CarGenerators) { cg.PosX += offsetx; //offset cargen positions cg.PosY += offsety; cg.PosZ += offsetz; cg.Flags = cargenflags; } } foreach (var mf in mapdict.Values) { try { MapFile lodmf = null; MapFile hdmf = null; MapFile milomf = null; if (mf.AllLodEntities.Count > 0) { lodmf = new MapFile(); lodmf.Name = mf.Name + "_lod"; lodmf.ParentName = mf.ParentName; lodmf.AllEntities = mf.AllLodEntities; lodmf.CalcExtents(lodloddist); lodmf.Flags = 2; lodmf.ContentFlags = (mf.SlodEntities.Count > 0) ? 18 : 2; lodmf.Save(outputpath); } if (mf.AllHdEntities.Count > 0) { hdmf = new MapFile(); hdmf.Name = mf.Name; hdmf.ParentName = lodmf?.Name ?? mf.ParentName; hdmf.AllEntities = mf.AllHdEntities; hdmf.CalcExtents(hdloddist); hdmf.Flags = 0; hdmf.ContentFlags = (mf.HdEntities.Count > 0) ? 1 : 0; hdmf.CarGenerators = cargens ? mf.CarGenerators : new List <CarGen>(); hdmf.Save(outputpath); } foreach (var intent in mf.InteriorEntities) { milomf = new MapFile(); milomf.Name = mf.Name + "_" + intent.Name + "_milo_"; milomf.ParentName = string.Empty; milomf.AllEntities.Add(intent); milomf.CalcExtents((intent.LODDist) > 0 ? intent.LODDist : 100f); milomf.Flags = 0; milomf.ContentFlags = 73; milomf.Save(outputpath); } } catch (Exception ex) { string err = "Error saving " + mf.Name + ":\n" + ex.ToString(); errorlog.AppendLine(err); } } if (errorlog.Length > 0) { File.WriteAllText(outputpath + "errorlog.txt", errorlog.ToString()); MessageBox.Show("Process complete with errors, see errorlog.txt."); } else { MessageBox.Show("Process complete."); } }