protected override void Write(IProgress <string> progress = null) { progress?.Report("Generating car array"); BeginChunk(0x34600); NextAlignment(0x10); var cars = _carService.GetCars(); for (var index = 0; index < cars.Count; index++) { var aaronCarRecord = cars[index]; var cti = new CarTypeInfo { MaxInstances = new byte[5], WantToKeepLoaded = new byte[5], pad4 = new byte[2], MinTimeBetweenUses = new float[5], AvailableSkinNumbers = new byte[10], CarTypeName = aaronCarRecord.CarTypeName, BaseModelName = aaronCarRecord.BaseModelName, GeometryFilename = @"CARS\" + aaronCarRecord.CarTypeName + @"\GEOMETRY.BIN", CarMemTypeHash = Hashing.BinHash(aaronCarRecord.UsageType.ToString()), CarTypeNameHash = aaronCarRecord.BaseCarID, UsageType = aaronCarRecord.UsageType, ManufacturerName = aaronCarRecord.ManufacturerName, DefaultSkinNumber = aaronCarRecord.DefaultSkinNumber, WhatGame = '\x01', WheelInnerRadiusMax = '\x14', WheelInnerRadiusMin = '\x11', WheelOuterRadius = '\x1a', DefaultBasePaint = aaronCarRecord.DefaultBasePaint, Skinnable = aaronCarRecord.Skinnable, DriverRenderingOffset = new bVector3(), HeadlightPosition = new bVector3(), InCarSteeringWheelRenderingOffset = new bVector3(), Type = index }; BinaryHelpers.WriteStruct(Writer, cti); } EndChunk(); progress?.Report("Generating AnimHookupTable"); BeginChunk(0x34608); for (int i = 0; i < 123; i++) { Writer.Write((byte)0xff); } Writer.Write((byte)0x00); EndChunk(); progress?.Report("Generating AnimHideTables"); BeginChunk(0x34609); for (int i = 0; i < 256; i++) { Writer.Write((byte)0xff); } EndChunk(); progress?.Report("Generating SlotTypes"); BeginChunk(0x34607); Writer.Write(_projectService.GetCurrentProject().SlotOverrideData); foreach (var aaronCarRecord in _carService.GetCars()) { if (aaronCarRecord.Spoiler == null) { continue; } var ss = new SpoilerStructure(); ss.CarTypeNameHash = ss.CarTypeNameHash2 = aaronCarRecord.BaseCarID; ss.Unknown = 0x3C; ss.SpoilerHash = (uint)aaronCarRecord.Spoiler.SpoilerType; BinaryHelpers.WriteStruct(Writer, ss); } EndChunk(); PaddingAlignment(0x10); this.GenerateCarPartData(progress); PaddingAlignment(0x10); DifferenceAlignment(0x8); progress?.Report("Writing collision data"); BeginChunk(0x8003B900); foreach (var aaronCarRecord in cars) { if (aaronCarRecord.BoundsPack == null) { continue; } BeginChunk(0x3b901); NextAlignment(0x10); var boundsPack = aaronCarRecord.BoundsPack; var bh = new BoundsHeader { NameHash = aaronCarRecord.CollisionHash, NumBounds = boundsPack.Entries.Count }; BinaryHelpers.WriteStruct(Writer, bh); foreach (var aaronBoundsEntry in boundsPack.Entries) { var bounds = new Bounds { AttributeName = aaronBoundsEntry.AttributeName, Position = aaronBoundsEntry.Position, ChildIndex = aaronBoundsEntry.ChildIndex, CollectionPtr = 0, HalfDimensions = aaronBoundsEntry.HalfDimensions, Pivot = aaronBoundsEntry.Pivot, NameHash = aaronBoundsEntry.NameHash, PCloudIndex = aaronBoundsEntry.PCloudIndex, NumChildren = aaronBoundsEntry.NumChildren, Orientation = aaronBoundsEntry.Orientation, Surface = aaronBoundsEntry.Surface, Flags = (ushort)aaronBoundsEntry.Flags }; BinaryHelpers.WriteStruct(Writer, bounds); } BinaryHelpers.WriteStruct(Writer, new PCloudHeader { NumPClouds = boundsPack.PointClouds.Count }); foreach (var aaronBoundsPointCloud in boundsPack.PointClouds) { Writer.Write(aaronBoundsPointCloud.Vertices.Count); Writer.Write(0); Writer.Write(0L); foreach (var vertex in aaronBoundsPointCloud.Vertices) { BinaryHelpers.WriteStruct(Writer, vertex); } } EndChunk(); } EndChunk(); PaddingAlignment(0x10); progress?.Report("Writing preset cars"); BeginChunk(0x30220); foreach (var aaronPresetCar in _presetCarService.GetPresetCars()) { BinaryHelpers.WriteStruct(Writer, PresetConverter.ConvertAaronPresetToFEPreset(aaronPresetCar)); } EndChunk(); PaddingAlignment(0x10); progress?.Report("Writing preset skins"); BeginChunk(0x30250); foreach (var aaronPresetSkinRecord in _presetSkinService.GetPresetSkins()) { var ps = new PresetSkin { Null = new byte[0x8], Null3 = new byte[0x38], PresetName = aaronPresetSkinRecord.PresetName, PaintGroup = aaronPresetSkinRecord.PaintGroup, PaintHue = aaronPresetSkinRecord.PaintHue, PaintVariance = aaronPresetSkinRecord.Variance, PaintSaturation = aaronPresetSkinRecord.Saturation, VinylHash = 0xFFFFFFFFu }; BinaryHelpers.WriteStruct(Writer, ps); } EndChunk(); progress?.Report("Writing data tables"); foreach (var aaronDataTable in _dataTableService.GetDataTables()) { PaddingAlignment(0x10); BeginChunk(0x3CE14); NextAlignment(0x10); Writer.Write(aaronDataTable.Hash); foreach (var aaronDataTableEntry in aaronDataTable.Entries) { Writer.Write(aaronDataTableEntry.Hash); Writer.Write(aaronDataTableEntry.Unknown); Writer.Write(aaronDataTableEntry.Unknown2); } EndChunk(); } progress?.Report("Post-processing"); //BeginChunk(0); //var watermarkStr = "File generated by Aaron+ (commit hash: " + VersionReader.AppVersion + ") on "; //watermarkStr += DateTime.Now.ToShortDateString(); //watermarkStr += " @ " + DateTime.Now.ToShortTimeString(); //watermarkStr += " | Created by heyitsleo"; //Writer.Write(watermarkStr); //EndChunk(); }
public string GenerateProject(string directory) { AaronProject aaronProject = new AaronProject(); aaronProject.Version = AaronProjectVersion; aaronProject.CarsDirectory = Path.Combine(directory, "Cars"); aaronProject.CarPartsDirectory = Path.Combine(directory, "CarParts"); aaronProject.PresetCarsDirectory = Path.Combine(directory, "PresetCars"); aaronProject.PresetSkinsDirectory = Path.Combine(directory, "PresetSkins"); aaronProject.DataTablesDirectory = Path.Combine(directory, "DataTables"); aaronProject.OutputFilePath = Path.Combine(directory, "bin", "GlobalC.lzc"); aaronProject.SlotOverrideData = _carPartService.GetSlotOverrideData(); Directory.CreateDirectory(directory); Directory.CreateDirectory(aaronProject.CarsDirectory); Directory.CreateDirectory(aaronProject.CarPartsDirectory); Directory.CreateDirectory(aaronProject.PresetCarsDirectory); Directory.CreateDirectory(aaronProject.PresetSkinsDirectory); Directory.CreateDirectory(aaronProject.DataTablesDirectory); Directory.CreateDirectory(Path.Combine(directory, "bin")); var projectPath = Path.Combine(directory, "project.aproj"); File.WriteAllText(projectPath, Serialization.Serialize(aaronProject)); DebugTiming.BeginTiming("ExportCars"); foreach (var aaronCarRecord in _carService.GetCars()) { File.WriteAllText(Path.Combine(aaronProject.CarsDirectory, aaronCarRecord.CarTypeName + ".json"), Serialization.Serialize(aaronCarRecord)); } DebugTiming.EndTiming("ExportCars"); DebugTiming.BeginTiming("ExportCarParts"); { var carPartCollections = _carPartService.GetCarPartCollections(); foreach (var carPartCollection in carPartCollections) { var fileName = Path.Combine(aaronProject.CarPartsDirectory, $"{carPartCollection.Name}.json"); var serialized = Serialization.Serialize(carPartCollection); File.WriteAllText(fileName, serialized); } } DebugTiming.EndTiming("ExportCarParts"); DebugTiming.BeginTiming("ExportPresets"); foreach (var aaronPresetCar in _presetCarService.GetPresetCars()) { File.WriteAllText( Path.Combine(aaronProject.PresetCarsDirectory, $"{aaronPresetCar.PresetName}.xml"), PresetConverter.ConvertAaronPresetToServerXML(aaronPresetCar).DataContractSerializeObject()); } DebugTiming.EndTiming("ExportPresets"); DebugTiming.BeginTiming("ExportPresetSkins"); foreach (var aaronPresetSkinRecord in _presetSkinService.GetPresetSkins()) { File.WriteAllText( Path.Combine(aaronProject.PresetSkinsDirectory, $"{aaronPresetSkinRecord.PresetName}.json"), Serialization.Serialize(aaronPresetSkinRecord)); } DebugTiming.EndTiming("ExportPresetSkins"); DebugTiming.BeginTiming("ExportDataTables"); foreach (var aaronDataTable in _dataTableService.GetDataTables()) { File.WriteAllText( Path.Combine(aaronProject.DataTablesDirectory, $"{aaronDataTable.Name}.json"), Serialization.Serialize(aaronDataTable)); } DebugTiming.EndTiming("ExportDataTables"); File.WriteAllText(Path.Combine(directory, "strings.json"), Serialization.Serialize(_carPartService.GetStrings())); return(projectPath); }