private bool TryDeserializeCarGenData(string json, out ICarGeneratorData data) { bool result; data = null; switch (Options.Game) { case Game.GTA3: { result = TryDeserializeJson(json, out GTA3CarGenBlock carGens); data = carGens; break; } case Game.VC: { result = TryDeserializeJson(json, out VCCarGenBlock carGens); data = carGens; break; } default: { throw new InvalidOperationException("Game not supported!"); } } return(result); }
private void ExportCarGens <TSaveData>() where TSaveData : SaveData, new() { string outFile = !string.IsNullOrEmpty(Options.OutputFile) ? Options.OutputFile : Options.CarGenFile; if (!TryOpenSaveData(Options.SaveDataFile, out TSaveData save)) { return; } ICarGeneratorData carGens = (save as ISaveData).CarGenerators; int numCarGens = carGens.CarGenerators.Count(); string json = SerializeJson(carGens); if (!TryWriteTextFile(outFile, json)) { return; } Log.Info($"Exported {numCarGens} car generator{Pluralize(numCarGens)}."); Result = ExitCode.Success; }
private bool CheckForCollision(ICarGeneratorData targetCarGens, ICarGenerator gen, out int targetIndex, out double distance) { targetIndex = -1; distance = 0; if (Options.Radius <= 0) { return(false); } bool collision = false; int index = 0; foreach (ICarGenerator tgtCg in targetCarGens.CarGenerators) { double dist = Vector3D.Distance(gen.Position, tgtCg.Position); if (tgtCg.Model != 0 && dist <= Options.Radius) { collision = true; targetIndex = index; distance = dist; break; } index++; } return(collision); }
private void UpdateCarGenMetadata(ICarGeneratorData carGens) { carGens.NumberOfCarGenerators = MaxCapacity; carGens.NumberOfEnabledCarGenerators = 0; foreach (ICarGenerator g in carGens.CarGenerators) { if (g.Model != 0 && g.Enabled) { carGens.NumberOfEnabledCarGenerators++; } } }
private void MergeCarGens <TSaveData>() where TSaveData : SaveData, new() { List <TSaveData> sourceSaves = new List <TSaveData>(); List <ICarGenerator> differingCarGens = new List <ICarGenerator>(); CarGenComparer cgComparer = new CarGenComparer(); // Load priority map if (HasUserProvidedPriorityMap) { if (!TryLoadPriorityMap()) { return; } } else { GeneratePriorityMap(); } // Load target file if (!TryOpenSaveData(Options.TargetFile, out TSaveData targetSave)) { return; } // Load source files and find differing car generators foreach (string sourcePath in Options.SourceFiles) { if (!TryOpenSaveData(sourcePath, out TSaveData sourceSave)) { return; } int numDifferingThisSave = 0; for (int i = 0; i < MaxCapacity; i++) { ICarGenerator tgt = (targetSave as ISaveData).CarGenerators[i]; ICarGenerator src = (sourceSave as ISaveData).CarGenerators[i]; if (src.Model != 0 && !cgComparer.Equals(src, tgt)) { Log.InfoF($"Difference found in slot {i}."); differingCarGens.Add(src); numDifferingThisSave++; } } Log.Info($"Found {numDifferingThisSave} differing car generator{Pluralize(numDifferingThisSave)} in {Path.GetFileName(sourcePath)}."); } int numDiffering = differingCarGens.Count; // Reduce the priority map to a list of car generator indices representing the replacement order. // First, sort the map in ascending order by key (priority) and exclude negatives. Next, flatten // all values (list of car generator indices) into a single list of integers, randomizing each // sub-list along the way. List <int> replacementOrder = PriorityMap .OrderBy(pair => pair.Key).Where(pair => pair.Key > -1) .SelectMany(pair => pair.Value.OrderBy(i => RandGen.Next())) .ToList(); // Merge! ISaveData target = (targetSave as ISaveData); ICarGeneratorData targetCarGens = target.CarGenerators; int numReplaced = 0; foreach (int cgIndex in replacementOrder) { if (numReplaced >= numDiffering) { break; } ICarGenerator cg = differingCarGens[numReplaced++]; if (CheckForCollision(targetCarGens, cg, out int idx, out double dist)) { Log.Error($"Collision found: Slot = {idx}; Location = {targetCarGens[idx].Position}; Distance = {dist:0.###}"); Result = ExitCode.Error; return; } targetCarGens[cgIndex] = cg; Log.InfoV($"Wrote slot {cgIndex}: Enabled = {cg.Enabled}; Model = {cg.Model}; Location = {cg.Position}"); } Log.Info($"Merged {numReplaced} car generator{Pluralize(numReplaced)}."); UpdateCarGenMetadata(targetCarGens); if (SetTitle) { targetSave.Name = Options.Title; Log.Info($"Title set to: {targetSave.Name}"); } targetSave.TimeLastSaved = DateTime.Now; if (!TryWriteSaveData(OutputFilePath, targetSave)) { return; } Result = ExitCode.Success; }