Пример #1
0
        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);
        }
Пример #2
0
        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;
        }
Пример #3
0
        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);
        }
Пример #4
0
 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++;
         }
     }
 }
Пример #5
0
        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;
        }