Esempio n. 1
0
        public static ImpactSpec Load(string description, DocumentParser file)
        {
            ImpactSpec spec = new ImpactSpec {
                Description = description
            };

            int clauseCount = file.ReadInt();

            for (int i = 0; i < clauseCount; i++)
            {
                spec.Clauses.Add(ImpactSpecClause.Load(file));
            }

            return(spec);
        }
Esempio n. 2
0
        public static ImpactSpecClause Load(DocumentParser file)
        {
            ImpactSpecClause clause = new ImpactSpecClause
            {
                Clause = file.ReadLine()
            };

            int systemCount = file.ReadInt();

            for (int i = 0; i < systemCount; i++)
            {
                clause.Systems.Add(ImpactSpecClauseSystem.Load(file.ReadStrings()));
            }

            return(clause);
        }
Esempio n. 3
0
        public static Funk Load(DocumentParser file)
        {
            Funk funk = new Funk
            {
                Material      = file.ReadLine(),
                Mode          = file.ReadLine().ToEnum <FunkMode>(),
                MatrixModType = file.ReadLine().ToEnumWithDefault <FunkMatrixMode>(FunkMatrixMode.None)
            };

            if (funk.MatrixModType != FunkMatrixMode.None)
            {
                funk.MatrixModMode = file.ReadLine().ToEnum <GroovePathMode>();
            }

            switch (funk.MatrixModType)
            {
            case FunkMatrixMode.None:
                break;

            case FunkMatrixMode.roll:
                funk.RollPeriods = file.ReadVector2();
                break;

            case FunkMatrixMode.slither:
                funk.SlitherSpeed  = file.ReadVector2();
                funk.SlitherAmount = file.ReadVector2();
                break;

            case FunkMatrixMode.spin:
                funk.SpinPeriod = file.ReadSingle();
                break;

            default:
                Console.WriteLine(file.ToString());
                break;
            }

            funk.LightingMode = file.ReadLine().ToEnumWithDefault(GroovePathMode.None);
            if (funk.LightingMode != GroovePathMode.None)
            {
                Console.WriteLine(file.ToString());
            }

            funk.AnimationType = file.ReadLine().ToEnumWithDefault(FunkAnimationType.None);

            switch (funk.AnimationType)
            {
            case FunkAnimationType.None:
                break;

            case FunkAnimationType.frames:
                funk.Framerate = file.ReadEnum <FrameRate>();
                funk.FrameMode = file.ReadEnum <FrameType>();

                switch (funk.FrameMode)
                {
                case FrameType.texturebits:
                    funk.TextureBitMode = file.ReadEnum <TexturebitMode>();
                    break;

                case FrameType.continuous:
                    funk.FrameSpeed = file.ReadSingle();
                    break;
                }

                int frameCount = file.ReadInt();

                for (int i = 0; i < frameCount; i++)
                {
                    funk.Frames.Add(file.ReadLine());
                }
                break;

            default:
                throw new NotImplementedException($"flic not supported!");
            }

            return(funk);
        }
Esempio n. 4
0
        public static Groove Load(DocumentParser file)
        {
            Groove groove = new Groove
            {
                Part         = file.ReadLine(),
                LollipopMode = file.ReadLine().ToEnumWithDefault(LollipopMode.NotALollipop),
                Mode         = file.ReadLine().ToEnum <GrooveMode>(),
                PathType     = file.ReadLine().ToEnumWithDefault(GroovePathNames.None)
            };

            if (groove.PathType != GroovePathNames.None)
            {
                groove.PathMode = file.ReadLine().ToEnum <GroovePathMode>();
            }

            switch (groove.PathType)
            {
            case GroovePathNames.None:
                break;

            case GroovePathNames.straight:
                groove.PathCentre = file.ReadVector3();
                groove.PathPeriod = file.ReadSingle();
                groove.PathDelta  = file.ReadVector3();
                break;

            default:
                Console.WriteLine();
                break;
            }

            groove.AnimationType = file.ReadLine().ToEnumWithDefault(GrooveAnimation.None);
            if (groove.AnimationType != GrooveAnimation.None)
            {
                groove.AnimationMode = file.ReadLine().ToEnum <GroovePathMode>();
            }

            switch (groove.AnimationType)
            {
            case GrooveAnimation.None:
                break;

            case GrooveAnimation.rock:
                groove.AnimationPeriod = file.ReadSingle();
                groove.AnimationCentre = file.ReadVector3();
                groove.AnimationAxis   = file.ReadLine().ToEnum <GrooveAnimationAxis>();
                groove.RockMaxAngle    = file.ReadSingle();
                break;

            case GrooveAnimation.shear:
                groove.ShearPeriod     = file.ReadVector3();
                groove.AnimationCentre = file.ReadVector3();
                groove.ShearMagnitude  = file.ReadVector3();
                break;

            case GrooveAnimation.spin:
                groove.AnimationPeriod = file.ReadSingle();
                groove.AnimationCentre = file.ReadVector3();
                groove.AnimationAxis   = file.ReadLine().ToEnum <GrooveAnimationAxis>();
                break;

            default:
                Console.WriteLine(file.ToString());
                break;
            }

            return(groove);
        }
Esempio n. 5
0
        public ImpactSpecClause(DocumentParser file)
            : this()
        {
            clause = file.ReadLine();

            int systemCount = file.ReadInt();

            for (int i = 0; i < systemCount; i++)
            {
                systems.Add(new ImpactSpecClauseSystem(file.ReadStrings()));
            }
        }
Esempio n. 6
0
        public static Map Load(string path)
        {
            DocumentParser file = new DocumentParser(path);
            Map map = new Map();

            string version = file.ReadLine();

            if (!version.StartsWith("VERSION"))
            {
                Logger.LogToFile(Logger.LogLevel.Error, "Not a valid Carmageddon 2 race .txt file");
                return null;
            }

            map.version = version.Replace("VERSION ", "").ToInt();

            if (map.version == 1)
            {
                // V1 has global lighting data
                map.lightColour = file.ReadVector3();       // RGB for main directional light-source
                map.diffuseLight0 = file.ReadVector2();     // Ambient/Diffuse light to be used when plaything ambient says 0
                map.diffuseLight1 = file.ReadVector2();     // Ambient/Diffuse light to be used when plaything ambient says 1
                map.diffuseLightOther = file.ReadVector2(); // Ambient/Diffuse light to be used when plaything ambient says anything else
            }

            map.gridPosition = file.ReadVector3();          // Position of centre of start of grid
            map.gridRotation = file.ReadInt();              // Direction that grid faces in

            //string t = getNextLine(sr);

            //if (version == 8)
            //{
            //    // alpha and demo v8 files had an extra block here, we'll test if it
            //    if (t.Contains(","))
            //    {
            //        getNextLine(sr); // # laps
            //        getNextLine(sr); // Race completed bonus (all laps raced) for each skill level
            //        getNextLine(sr); // Race completed bonus (all peds killed) for each skill level
            //        getNextLine(sr); // Race completed bonus (all oppos wasted) for each skill level

            //        t = getNextLine(sr);
            //    }
            //}

            int checkpointCount = file.ReadInt();
            for (int i = 0; i < checkpointCount; i++)
            {
                Checkpoint cp = new Checkpoint();

                cp.TimerIncrements = file.ReadVector3();

                int quadCount = file.ReadInt();

                for (int j = 0; j < quadCount; j++)
                {
                    cp.Points.Add(file.ReadVector3());
                    cp.Points.Add(file.ReadVector3());
                    cp.Points.Add(file.ReadVector3());
                    cp.Points.Add(file.ReadVector3());
                }

                map.checkpoints.Add(cp);
            }

            int smashSpecs = file.ReadInt();

            if (smashSpecs > 0)
            {
                throw new NotImplementedException("Can't handle smash specs yet!");
            }

            //for (int k = 0; k < i; k++)
            //{
            //    int flags = Convert.ToInt32(getNextLine(sr));
            //    string trigger = getNextLine(sr);
            //    if (trigger.Length == 3 && trigger.StartsWith("&")) { if (!TestLine("7", getNextLine(sr))) { Console.WriteLine("Noncar smash"); return null; } }
            //    string mode = getNextLine(sr);

            //    switch (mode)
            //    {
            //        case "remove":
            //            Single removalthreshold = getNextLine(sr).ToSingle();
            //            if (!processConnotations(sr)) { return null; }
            //            break;

            //        case "nochange":
            //            Single threshold = getNextLine(sr).ToSingle();
            //            if (!processConnotations(sr)) { return null; }
            //            break;

            //        case "replacemodel":
            //            Single replacethreshold = getNextLine(sr).ToSingle();
            //            if (!processConnotations(sr)) { return null; }
            //            string newmodel = getNextLine(sr);
            //            int chanceoffire = Convert.ToInt32(getNextLine(sr));
            //            if (chanceoffire > 0)
            //            {
            //                int numfires = Convert.ToInt32(getNextLine(sr));
            //                Vector2 smokeindex = Vector2.Parse(getNextLine(sr));
            //            }
            //            break;

            //        case "texturechange":
            //            string intactpixelmap = getNextLine(sr);
            //            int numlevels = Convert.ToInt32(getNextLine(sr));
            //            for (int j = 0; j < numlevels; j++)
            //            {
            //                Single triggerthreshold = getNextLine(sr).ToSingle();
            //                int texchangeflags = Convert.ToInt32(getNextLine(sr));
            //                string collisiontype = getNextLine(sr);

            //                if (!processConnotations(sr)) { return null; }

            //                int numpixelmaps = Convert.ToInt32(getNextLine(sr));
            //                for (int l = 0; l < numpixelmaps; l++)
            //                {
            //                    string pixelmap = getNextLine(sr);
            //                }
            //            }
            //            break;

            //        default:
            //            Console.WriteLine("Unknown mode : " + mode);
            //            return null;
            //    }

            //    if (!TestLine("0", getNextLine(sr))) { Console.WriteLine("Reserved 1"); return null; }
            //    if (!TestLine("0", getNextLine(sr))) { Console.WriteLine("Reserved 2"); return null; }
            //    if (!TestLine("0", getNextLine(sr))) { Console.WriteLine("Reserved 3"); return null; }
            //    if (!TestLine("0", getNextLine(sr))) { Console.WriteLine("Reserved 4"); return null; }
            //}

            int pedSpecs = file.ReadInt();

            for (int i = 0; i < pedSpecs; i++)
            {
                PedSpec ps = new PedSpec();

                ps.MaterialName = file.ReadLine();
                ps.MovementIndex = file.ReadInt();
                ps.GroupIndex = file.ReadInt();
                ps.PedsPer100SquareMetres = file.ReadInt();

                int exclusionCount = file.ReadInt();
                for (int j = 0; j < exclusionCount; j++)
                {
                    ps.ExclusionMaterials.Add(file.ReadLine());
                }

                int exceptionCount = file.ReadInt();
                for (int j = 0; j < exceptionCount; j++)
                {
                    ps.ExceptionMaterials.Add(file.ReadLine());
                }

                map.pedSpecs.Add(ps);
            }

            map.additionalActor = file.ReadLine();

            map.skyPixelmap = file.ReadLine();
            map.horizontalRepetitions = file.ReadInt();
            map.verticalSize = file.ReadInt();
            map.positionOfHorizon = file.ReadInt();
            map.depthCueMode = file.ReadLine();
            map.fogDarkness = file.ReadVector2();
            map.depthCueColour = file.ReadVector3();

            map.defaultEngineNoise = file.ReadInt();

            int specialEffectVolumeCount = file.ReadInt();

            for (int i = 0; i < specialEffectVolumeCount; i++)
            {
                SpecialEffectVolume sev = new SpecialEffectVolume();

                sev.Name = file.ReadLine();

                if (i > 0)
                {
                    sev.Corners.Add(file.ReadVector3());
                    sev.Corners.Add(file.ReadVector3());
                    sev.Corners.Add(file.ReadVector3());
                    sev.Corners.Add(file.ReadVector3());
                }

                sev.GravityMultiplier = file.ReadSingle();
                sev.ViscosityMultiplier = file.ReadSingle();
                sev.CarDamagePerMillisecond = file.ReadSingle();
                sev.PedDamagePerMillisecond = file.ReadSingle();
                sev.CameraEffectIndex = file.ReadInt();
                sev.SkyColour = file.ReadInt();
                sev.WindscreenMaterial = file.ReadLine();
                sev.EntrySoundID = file.ReadInt();
                sev.ExitSoundID = file.ReadInt();
                sev.EngineNoiseIndex = file.ReadInt();
                sev.MaterialIndex = file.ReadInt();

                map.specialVolumes.Add(sev);
            }

            int soundGeneratorCount = file.ReadInt();

            if (soundGeneratorCount > 0)
            {
                throw new NotImplementedException("Can't handle sound generators yet!");
            }

            map.materialDefault = file.ReadLine();
            map.materialDarkness = file.ReadLine();
            map.materialFog = file.ReadLine();

            file.ReadLine();    // (ignore) # areas with different screens

            map.mapPixelmap = file.ReadLine();
            map.worldMapTransform = new Matrix3D(
                file.ReadVector3(),
                file.ReadVector3(),
                file.ReadVector3(),
                file.ReadVector3()
            );

            Console.WriteLine(map.worldMapTransform);

            while (file.ReadLine() != "END OF FUNK") ;
            while (file.ReadLine() != "END OF GROOVE") ;

            if (file.ReadLine() != "START OF OPPONENT PATHS")
            {
                Logger.LogToFile(Logger.LogLevel.Error, "Not a valid Carmageddon 2 race .txt file");
                return null;
            }

            int nodeCount = file.ReadInt();
            for (int i = 0; i < nodeCount; i++)
            {
                map.nodes.Add(file.ReadVector3());
            }

            int pathCount = file.ReadInt();
            for (int i = 0; i < pathCount; i++)
            {
                map.paths.Add(new OpponentPathSection(file.ReadLine()));
            }

            return map;
        }
Esempio n. 7
0
        public Groove(DocumentParser file)
            : this()
        {
            part = file.ReadLine();
            lollipopMode = file.ReadLine().ToEnumWithDefault<LollipopMode>(LollipopMode.NotALollipop);
            mode = file.ReadLine().ToEnum<GrooveMode>();
            pathType = file.ReadLine().ToEnumWithDefault<GroovePathNames>(GroovePathNames.None);
            if (pathType != GroovePathNames.None) { pathMode = file.ReadLine().ToEnum<GroovePathMode>(); }

            switch (pathType)
            {
                case GroovePathNames.None:
                    break;

                case GroovePathNames.straight:
                    pathCentre = file.ReadVector3();
                    pathPeriod = file.ReadSingle();
                    pathDelta = file.ReadVector3();
                    break;

                default:
                    Console.WriteLine();
                    break;
            }

            animationType = file.ReadLine().ToEnumWithDefault<GrooveAnimation>(GrooveAnimation.None);
            if (animationType != GrooveAnimation.None) { animationMode = file.ReadLine().ToEnum<GroovePathMode>(); }

            switch (animationType)
            {
                case GrooveAnimation.rock:
                    animationPeriod = file.ReadSingle();
                    animationCentre = file.ReadVector3();
                    animationAxis = file.ReadLine().ToEnum<GrooveAnimationAxis>();
                    rockMaxAngle = file.ReadSingle();
                    break;

                case GrooveAnimation.shear:
                    shearPeriod = file.ReadVector3();
                    animationCentre = file.ReadVector3();
                    shearMagnitude = file.ReadVector3();
                    break;

                case GrooveAnimation.spin:
                    animationPeriod = file.ReadSingle();
                    animationCentre = file.ReadVector3();
                    animationAxis = file.ReadLine().ToEnum<GrooveAnimationAxis>();
                    break;

                default:
                    Console.WriteLine(file.ToString());
                    break;
            }
        }
Esempio n. 8
0
        public ImpactSpec(DocumentParser file)
            : this()
        {
            int clauseCount = file.ReadInt();

            for (int i = 0; i < clauseCount; i++)
            {
                clauses.Add(new ImpactSpecClause(file));
            }
        }
Esempio n. 9
0
        public Funk(DocumentParser file)
            : this()
        {
            material = file.ReadLine();
            mode = file.ReadLine().ToEnum<FunkMode>();
            matrixModType = file.ReadLine().ToEnum<FunkMatrixMode>();
            if (matrixModType != FunkMatrixMode.None) { matrixModMode = file.ReadLine().ToEnum<GroovePathMode>(); }

            switch (matrixModType)
            {
                case FunkMatrixMode.roll:
                    rollPeriods = file.ReadVector2();
                    break;

                case FunkMatrixMode.spin:
                    spinPeriod = file.ReadSingle();
                    break;

                default:
                    Console.WriteLine(file.ToString());
                    break;
            }

            lightingMode = file.ReadLine().ToEnumWithDefault<GroovePathMode>(GroovePathMode.None);
            if (lightingMode != GroovePathMode.None)
            {
                Console.WriteLine(file.ToString());
            }

            animationType = file.ReadLine().ToEnumWithDefault<FunkAnimationType>(FunkAnimationType.None);
            if (animationType != FunkAnimationType.None)
            {
                Console.WriteLine(file.ToString());
            }
        }
Esempio n. 10
0
 public CrushPointNeighbour(DocumentParser file)
     : this()
 {
     vertexIndex = file.ReadInt();
     factor = file.ReadSingle();
 }
Esempio n. 11
0
        public CrushPoint(DocumentParser file)
            : this()
        {
            vertexIndex = file.ReadInt();
            limitNeg = file.ReadVector3();
            limitPos = file.ReadVector3();
            softnessNeg = file.ReadVector3();
            softnessPos = file.ReadVector3();

            int neighbourCount = file.ReadInt();
            for (int i = 0; i < neighbourCount; i++)
            {
                neighbours.Add(new CrushPointNeighbour(file));
            }
        }
Esempio n. 12
0
        public Crush(DocumentParser file)
            : this()
        {
            softnessFactor = file.ReadSingle();
            foldFactor = file.ReadVector2();
            wibbleFactor = file.ReadSingle();
            limitDeviant = file.ReadSingle();
            splitChance = file.ReadSingle();
            minYFoldDown = file.ReadSingle();

            int pointCount = file.ReadInt();
            for (int i = 0; i < pointCount; i++)
            {
                points.Add(new CrushPoint(file));
            }
        }
Esempio n. 13
0
        public static Car Load(string path)
        {
            var file = new DocumentParser(path);
            var car = new Car();

            car.name = file.ReadLine();

            if (string.Compare(Path.GetFileName(path).ToUpper(), car.name) != 0)
            {
                Logger.LogToFile(Logger.LogLevel.Error, "Not a valid Carmageddon car .txt file, expected {0} but found {1}", Path.GetFileName(path).ToUpper(), car.name);
                return null;
            }

            if (file.ReadLine() != "START OF DRIVABLE STUFF")
            {
                Logger.LogToFile(Logger.LogLevel.Error, "Expected \"{0}\", didn't get it.  Are you sure this is a Car.TXT file?", "START OF DRIVABLE STUFF");
                return null;
            }

            car.driversHeadOffset = file.ReadVector3();
            car.driversHeadTurnAngles = file.ReadVector2();
            car.mirrorCamera = file.ReadVector4();
            car.pratcamBorders = file.ReadStrings();

            if (file.ReadLine() != "END OF DRIVABLE STUFF")
            {
                Logger.LogToFile(Logger.LogLevel.Error, "Expected \"{0}\", didn't get it.  Are you sure this is a Car.TXT file?", "END OF DRIVABLE STUFF");
                return null;
            }

            car.engineNoises = file.ReadInts();
            car.stealWorthy = (file.ReadLine().ToLower() == "stealworthy");

            // This next section is all about impacts, 6 blocks in the order of top, bottom, left, right, front, back
            car.impactTop = new ImpactSpec(file);
            car.impactBottom = new ImpactSpec(file);
            car.impactLeft = new ImpactSpec(file);
            car.impactRight = new ImpactSpec(file);
            car.impactFront = new ImpactSpec(file);
            car.impactBack = new ImpactSpec(file);

            car.gridImages = file.ReadStrings();

            for (int i = 0; i < 3; i++)
            {
                int pixCount = file.ReadInt();

                for (int j = 0; j < pixCount; j++)
                {
                    car.pixelmaps[i].Add(file.ReadLine());
                }
            }

            int shadeCount = file.ReadInt();
            for (int j = 0; j < shadeCount; j++)
            {
                Console.WriteLine();
            }

            for (int i = 0; i < 3; i++)
            {
                int matCount = file.ReadInt();

                for (int j = 0; j < matCount; j++)
                {
                    car.materials[i].Add(file.ReadLine());
                }
            }

            int modelCount = file.ReadInt();
            for (int j = 0; j < modelCount; j++)
            {
                car.models.Add(file.ReadLine());
            }

            int actorCount = file.ReadInt();
            for (int j = 0; j < modelCount; j++)
            {
                var s = file.ReadStrings();
                car.actorLOD.Add(s[0].ToInt());
                car.actors.Add(s[1]);
            }

            car.reflectiveScreenMaterial = file.ReadLine();

            int steerableWheelsCount = file.ReadInt();
            for (int j = 0; j < steerableWheelsCount; j++)
            {
                car.steerableWheels.Add(file.ReadInt());
            }

            car.leftFrontSuspension = file.ReadInts();
            car.rightFrontSuspension = file.ReadInts();
            car.leftRearSuspension = file.ReadInts();
            car.rightRearSuspension = file.ReadInts();
            car.drivenWheels = file.ReadInts();
            car.nonDrivenWheels = file.ReadInts();

            car.drivenWheelDiameter = file.ReadSingle();
            car.nonDrivenWheelDiameter = file.ReadSingle();

            if (file.ReadLine() != "START OF FUNK")
            {
                Logger.LogToFile(Logger.LogLevel.Error, "Expected \"{0}\", didn't get it.  Are you sure this is a Car.TXT file?", "START OF FUNK");
                return null;
            }

            while (file.PeekLine() != "END OF FUNK")
            {
                car.funks.Add(new Funk(file));
                if (file.PeekLine() == "NEXT FUNK") { file.ReadLine(); }
            } file.ReadLine();

            if (file.ReadLine() != "START OF GROOVE")
            {
                Logger.LogToFile(Logger.LogLevel.Error, "Expected \"{0}\", didn't get it.  Are you sure this is a Car.TXT file?", "START OF GROOVE");
                return null;
            }

            while (file.PeekLine() != "END OF GROOVE")
            {
                car.grooves.Add(new Groove(file));
                if (file.PeekLine() == "NEXT GROOVE") { file.ReadLine(); }
            } file.ReadLine();

            for (int i = 0; i < car.models.Count; i++)
            {
                car.crushes.Add(new Crush(file));
                Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}", car.models[i], car.crushes[i].SoftnessFactor, car.crushes[i].FoldFactor, car.crushes[i].WibbleFactor, car.crushes[i].LimitDeviant, car.crushes[i].SplitChance, car.crushes[i].MinYFoldDown);
            }

            int mechanicsVersion = file.ReadLine().Replace("START OF MECHANICS STUFF version ", "", StringComparison.InvariantCultureIgnoreCase).ToInt();

            car.lrWheelPos = file.ReadVector3();
            car.rrWheelPos = file.ReadVector3();
            car.lfWheelPos = file.ReadVector3();
            car.rfWheelPos = file.ReadVector3();
            car.centreOfMass = file.ReadVector3();

            switch (mechanicsVersion)
            {
                case 2:
                    var boundingBoxCount = file.ReadInt();
                    for (int i = 0; i < boundingBoxCount; i++)
                    {
                        car.boundingBoxes.Add(new BoundingBox { Min = file.ReadVector3(), Max = file.ReadVector3() });
                    }
                    break;

                case 3:
                case 4:
                    car.boundingBoxes.Add(new BoundingBox { Min = file.ReadVector3(), Max = file.ReadVector3() });

                    var additionalPointsCount = file.ReadInt();
                    for (int i = 0; i < additionalPointsCount; i++)
                    {
                        car.additionalPoints.Add(file.ReadVector3());
                    }
                    break;
            }

            car.turningCircleRadius = file.ReadSingle();
            car.suspensionGive = file.ReadVector2();
            car.rideHeight = file.ReadSingle();
            car.dampingFactor = file.ReadSingle();
            car.massInTonnes = file.ReadSingle();
            car.fReduction = file.ReadSingle();
            car.frictionAngle = file.ReadVector2();
            car.widthHeightLength = file.ReadVector3();
            car.tractionFractionalMultiplier = file.ReadSingle();
            car.downforceSpeed = file.ReadSingle();
            car.brakeMultiplier = file.ReadSingle();
            car.increaseInBrakesPerSecond = file.ReadSingle();
            car.rollingResistance = file.ReadVector2();
            car.numberOfGears = file.ReadInt();
            car.redLineSpeed = file.ReadInt();
            car.accelerationInHighestGear = file.ReadSingle();

            if (file.ReadLine() != "END OF MECHANICS STUFF")
            {
                Logger.LogToFile(Logger.LogLevel.Error, "Expected \"{0}\", didn't get it.  Are you sure this is a Car.TXT file?", "END OF MECHANICS STUFF");
                return null;
            }

            int shrapnelCount = file.ReadInt();
            for (int i = 0; i < shrapnelCount; i++)
            {
                car.shrapnel.Add(file.ReadLine());
            }

            if (!file.EOF)
            {
                for (int i = 0; i < 12; i++)
                {
                    car.firePoints.Add(file.ReadInt());
                }
            }

            if (!file.EOF)
            {
                Console.WriteLine("Still data to parse in {0}", path);
            }

            return car;
        }