Beispiel #1
0
        public void Save(string path)
        {
            using (DocumentWriter dw = new DocumentWriter(path))
            {
                dw.WriteLine($"VERSION {Version}");
                dw.WriteLine("//	Version 1 :		New crush data");
                if (Version > 1)
                {
                    dw.WriteLine("//		2 :		New windscreen spec");
                }
                dw.WriteLine($"{(FemaleDriver ? "GIRL" : "")}");
                dw.WriteLine($"{Name}", "Name of car");

                dw.WriteLine();

                dw.WriteLine($"{SoftnessFactor}", "softness_factor");

                dw.WriteLine();

                dw.WriteLine("START OF DRIVABLE STUFF");
                dw.WriteLine();
                dw.WriteLine($"{DriversHeadOffset.X},{DriversHeadOffset.Y},{DriversHeadOffset.Z}", "Offset of driver's head in 3D space");
                dw.WriteLine($"{DriversHeadTurnAngles.X},{DriversHeadTurnAngles.Y}", "Angles to turn to make head go left and right");
                dw.WriteLine($"{MirrorCamera.X},{MirrorCamera.Y},{MirrorCamera.Z},{MirrorCamera.W}", "Offset of 'mirror camera' in 3D space, viewing angle of mirror");
                dw.WriteLine($"{string.Join(",", PratcamBorders)}", "Pratcam border names (left, top, right, bottom)");
                dw.WriteLine();
                dw.WriteLine("END OF DRIVABLE STUFF");

                dw.WriteLine();

                dw.WriteLine($"{string.Join(",",EngineNoises)}", "Engine noise (normal, enclosed space, underwater)");

                dw.WriteLine();

                dw.WriteLine($"{(Stealworthy ? "stealworthy" : "")}", "Can be stolen");

                dw.WriteLine();

                foreach (ImpactSpec impactSpec in new List <ImpactSpec> {
                    ImpactTop, ImpactBottom, ImpactLeft, ImpactRight, ImpactFront, ImpactBack
                })
                {
                    dw.WriteLine($"// Damage info for {impactSpec.Description} impacts");
                    dw.WriteLine($"{impactSpec.Clauses.Count}", "Number of clauses");
                    dw.IncreaseIndent();
                    foreach (ImpactSpecClause clause in impactSpec.Clauses)
                    {
                        dw.WriteLine($"{clause.Clause}", "Condition");
                        dw.WriteLine($"{clause.Systems.Count}", "Systems count");

                        dw.IncreaseIndent();
                        foreach (ImpactSpecClauseSystem system in clause.Systems)
                        {
                            dw.WriteLine($"{system.Part},{system.Damage:F1}", "Damage");
                        }
                        dw.DecreaseIndent();
                    }
                    dw.DecreaseIndent();
                }

                dw.WriteLine();

                dw.WriteLine($"{string.Join(",", GridImages)}", "Grid image (opponent, frank, annie)");

                dw.WriteLine();

                dw.WriteLine($"{ExtraLevelsOfDetail.Count}", "Number of extra levels of detail");
                foreach (int extraLevelOfDetail in ExtraLevelsOfDetail)
                {
                    dw.WriteLine($"{extraLevelOfDetail}", "min_dist_squared");
                }

                dw.WriteLine();

                dw.WriteLine($"{WAM}", "crush data file (will be incorporated into this file)");

                dw.WriteLine();

                dw.WriteLine($"{ReflectiveScreenMaterial}", "Name of reflective screen material (or none if non-reflective)");
                dw.WriteLine($"{TransparencyOfWindscreen}", "Percentage transparency of windscreen");

                dw.WriteLine();

                dw.WriteLine($"{SteerableWheels.Count}", "Number of steerable wheels");
                foreach (int steerableWheel in SteerableWheels)
                {
                    dw.WriteLine($"{steerableWheel}", "GroovyFunkRef of nth steerable wheel");
                }

                dw.WriteLine();

                dw.WriteLine($"{string.Join(",", LeftFrontSuspension)}", "Left-front suspension parts GroovyFunkRef");
                dw.WriteLine($"{string.Join(",", RightFrontSuspension)}", "Right-front suspension parts GroovyFunkRef");
                dw.WriteLine($"{string.Join(",", LeftRearSuspension)}", "Left-rear suspension parts GroovyFunkRef");
                dw.WriteLine($"{string.Join(",", RightRearSuspension)}", "Right-rear suspension parts GroovyFunkRef");

                dw.WriteLine();

                dw.WriteLine($"{string.Join(",", DrivenWheels)}", "Driven wheels GroovyFunkRefs (for spinning) - MUST BE 4 ITEMS");
                dw.WriteLine($"{string.Join(",", NonDrivenWheels)}", "Non-driven wheels GroovyFunkRefs (for spinning) - MUST BE 4 ITEMS");

                dw.WriteLine();

                dw.WriteLine($"{DrivenWheelDiameter}", "Driven wheels diameter");
                dw.WriteLine($"{NonDrivenWheelDiameter}", "Non-driven wheels diameter");

                dw.WriteLine();
                dw.WriteLine("START OF FUNK");
                dw.WriteLine();

                for (int i = 0; i < Funks.Count; i++)
                {
                    Funk funk = Funks[i];

                    dw.WriteLine($"{funk.Material}");
                    dw.WriteLine($"{funk.Mode}");
                    dw.WriteLine($"{funk.MatrixModType}");
                    if (funk.MatrixModType != FunkMatrixMode.None)
                    {
                        dw.WriteLine($"{funk.MatrixModMode}");
                    }

                    switch (funk.MatrixModType)
                    {
                    case FunkMatrixMode.roll:
                        dw.WriteLine($"{funk.RollPeriods.X},{funk.RollPeriods.Y}");
                        break;

                    case FunkMatrixMode.slither:
                        dw.WriteLine($"{funk.SlitherSpeed.X},{funk.SlitherSpeed.Y}");
                        dw.WriteLine($"{funk.SlitherAmount.X},{funk.SlitherAmount.Y}");
                        break;

                    case FunkMatrixMode.spin:
                        dw.WriteLine($"{funk.SpinPeriod}");
                        break;
                    }

                    dw.WriteLine($"{funk.LightingMode}");
                    dw.WriteLine($"{funk.AnimationType}");

                    switch (funk.AnimationType)
                    {
                    case FunkAnimationType.frames:
                        dw.WriteLine($"{funk.Framerate}");
                        dw.WriteLine($"{funk.FrameMode}");

                        switch (funk.FrameMode)
                        {
                        case FrameType.texturebits:
                            dw.WriteLine($"{funk.TextureBitMode}");
                            break;

                        case FrameType.continuous:
                            dw.WriteLine($"{funk.FrameSpeed}");
                            break;
                        }

                        dw.WriteLine($"{funk.Frames.Count}");
                        foreach (string frame in funk.Frames)
                        {
                            dw.WriteLine($"{frame}");
                        }
                        break;
                    }

                    if (i + 1 != Funks.Count)
                    {
                        dw.WriteLine();
                        dw.WriteLine("NEXT FUNK");
                        dw.WriteLine();
                    }
                }

                dw.WriteLine();
                dw.WriteLine("END OF FUNK");
                dw.WriteLine();

                dw.WriteLine();
                dw.WriteLine("START OF GROOVE");
                dw.WriteLine();

                for (int i = 0; i < Grooves.Count; i++)
                {
                    Groove groove = Grooves[i];

                    dw.WriteLine($"{groove.Part}");
                    dw.WriteLine($"{groove.LollipopMode}");
                    dw.WriteLine($"{groove.Mode}");
                    dw.WriteLine($"{groove.PathType}");
                    if (groove.PathType != GroovePathNames.None)
                    {
                        dw.WriteLine($"{groove.PathMode}");
                    }

                    switch (groove.PathType)
                    {
                    case GroovePathNames.straight:
                        dw.WriteLine($"{groove.PathCentre.X},{groove.PathCentre.Y},{groove.PathCentre.Z}");
                        dw.WriteLine($"{groove.PathPeriod}");
                        dw.WriteLine($"{groove.PathDelta.X},{groove.PathDelta.Y},{groove.PathDelta.Z}");
                        break;
                    }

                    dw.WriteLine($"{groove.AnimationType}");
                    if (groove.AnimationType != GrooveAnimation.None)
                    {
                        dw.WriteLine($"{groove.AnimationMode}");
                    }

                    switch (groove.AnimationType)
                    {
                    case GrooveAnimation.rock:
                        dw.WriteLine($"{groove.AnimationPeriod}");
                        dw.WriteLine($"{groove.AnimationCentre.X},{groove.AnimationCentre.Y},{groove.AnimationCentre.Z}");
                        dw.WriteLine($"{groove.AnimationAxis}");
                        dw.WriteLine($"{groove.RockMaxAngle}");
                        break;

                    case GrooveAnimation.shear:
                        dw.WriteLine($"{groove.ShearPeriod.X},{groove.ShearPeriod.Y},{groove.ShearPeriod.Z}");
                        dw.WriteLine($"{groove.AnimationCentre.X},{groove.AnimationCentre.Y},{groove.AnimationCentre.Z}");
                        dw.WriteLine($"{groove.ShearMagnitude.X},{groove.ShearMagnitude.Y},{groove.ShearMagnitude.Z}");
                        break;

                    case GrooveAnimation.spin:
                        dw.WriteLine($"{groove.AnimationPeriod}");
                        dw.WriteLine($"{groove.AnimationCentre.X},{groove.AnimationCentre.Y},{groove.AnimationCentre.Z}");
                        dw.WriteLine($"{groove.AnimationAxis}");
                        break;
                    }

                    if (i + 1 != Grooves.Count)
                    {
                        dw.WriteLine();
                        dw.WriteLine("NEXT GROOVE");
                        dw.WriteLine();
                    }
                }

                dw.WriteLine();
                dw.WriteLine("END OF GROOVE");
                dw.WriteLine();

                dw.WriteLine("// END OF CRUSH DATA");

                dw.WriteLine();
                dw.WriteLine("START OF MECHANICS STUFF version 1");
                dw.WriteLine();

                dw.WriteLine($"{MinimumTurningCircle:F6}", "Minimum turning circle.");
                dw.WriteLine($"{BrakeMultiplier:F6}", "Brake multiplier.");
                dw.WriteLine($"{BrakingStrengthMultiplier:F6}", "Braking strength multiplier.");
                dw.WriteLine($"{NumberOfGears}", "Number of gears.");
                dw.WriteLine($"{TopGearRedlineSpeed:F4}", "Speed at red line in highest gear.");
                dw.WriteLine($"{TopGearAcceleration:F6}", "Acceleration in highest gear (m/s^2) i.e. engine strength.");

                dw.WriteLine();

                dw.WriteLine("// Sub member: Root part");
                dw.WriteLine($"{RootPartType}", "Type");
                dw.WriteLine($"{RootPartIdentifier}", "Identifier");
                dw.WriteLine($"{RootPartActor}", "Actor");
                dw.WriteLine("// Sub member: Joint data");
                dw.WriteLine($"{SubPartType}", "Type");
                dw.WriteLine($"{CentreOfMass.X:F6},{CentreOfMass.Y:F6},{CentreOfMass.Z:F6}", "Centre of mass");
                dw.WriteLine($"{Mass}", "Mass");
                dw.WriteLine($"{AngularMomentumProportions.X:F6},{AngularMomentumProportions.Y:F6},{AngularMomentumProportions.Z:F6}", "Angular momentum proportions");
                dw.WriteLine($"{DownforceToWeightBalanceSpeed:F6}", "Downforce-to-weight balance speed");
                dw.WriteLine($"{Wheels.Count}", "Number of 'Wheels' entries.");

                for (int i = 0; i < Wheels.Count; i++)
                {
                    Wheel wheel = Wheels[i];

                    dw.WriteLine($"// Wheels entry #{i + 1}");
                    dw.WriteLine($"{(int)wheel.Type}", "Type");
                    dw.WriteLine($"{wheel.Identifier}", "Identifier");
                    dw.WriteLine($"{wheel.Actor}", "Actor");
                    dw.WriteLine($"{wheel.Position.X},{wheel.Position.Y},{wheel.Position.Z}", "Position");
                    dw.WriteLine($"{wheel.SteerableFlags}", "Steerable flags");
                    dw.WriteLine($"{wheel.DrivenFlags}", "Driven flags");
                    dw.WriteLine($"{wheel.SuspensionGive:F6}", "Suspension give");
                    dw.WriteLine($"{wheel.DampingFactor:F6}", "Damping factor");
                    dw.WriteLine($"{wheel.SlipFrictionReductionFraction:F6}", "Fractional reduction in friction when slipping");
                    dw.WriteLine($"{wheel.FrictionAngles.X:F6},{wheel.FrictionAngles.Y:F6}", "Friction angles");
                    dw.WriteLine($"{wheel.TractionFractionalMultiplier:F6}", "Traction fractional multiplier");
                    dw.WriteLine($"{wheel.RollingResistance:F6}", "Rolling resistance");
                }

                dw.WriteLine();

                dw.WriteLine($"{BoundingShapes.Count}", "Number of 'Bounding shapes' entries.");

                for (int i = 0; i < BoundingShapes.Count; i++)
                {
                    BoundingShape shape = BoundingShapes[i];

                    dw.WriteLine($"// Bounding shapes entry #{i + 1}");
                    dw.WriteLine($"{shape.Type}", "Type");
                    dw.WriteLine($"{shape.Points.Count}");
                    foreach (Vector3 point in shape.Points)
                    {
                        dw.WriteLine($"{point.X:F2},{point.Y:F2},{point.Z:F2}");
                    }
                }

                dw.WriteLine();
                dw.WriteLine($"{SubParts.Count}", "Number of sub-parts.");
                dw.WriteLine();

                dw.WriteLine();
                dw.WriteLine("END OF MECHANICS STUFF");
                dw.WriteLine();

                dw.WriteLine("// Materials for shrapnel");
                dw.WriteLine($"{Shrapnel.Count}", "number of materials");
                foreach (string shrapnel in Shrapnel)
                {
                    dw.WriteLine($"{shrapnel}");
                }

                dw.WriteLine();

                dw.WriteLine("//damage vertices fire points");
                foreach (int point in FirePoints)
                {
                    dw.WriteLine($"{point}");
                }

                dw.WriteLine();

                dw.WriteLine("// start of keyword stuff");
                foreach (Keyword keyword in Keywords)
                {
                    keyword.Write(dw);
                }

                dw.WriteLine("// End of keyword stuff");
                dw.WriteLine("END");
            }
        }
Beispiel #2
0
        public static Car Load(string path)
        {
            DocumentParser file = new DocumentParser(path);
            Car            car  = new Car();

            string version = file.ReadLine();

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

            car.Version = version.Replace("VERSION ", "").ToInt();

            if (file.PeekLine() == "GIRL")
            {
                car.FemaleDriver = true;
                file.ReadLine();
            }

            car.Name           = file.ReadLine();
            car.SoftnessFactor = file.ReadSingle();

            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";

            car.ImpactTop    = ImpactSpec.Load("top", file);
            car.ImpactBottom = ImpactSpec.Load("bottom", file);
            car.ImpactLeft   = ImpactSpec.Load("left", file);
            car.ImpactRight  = ImpactSpec.Load("right", file);
            car.ImpactFront  = ImpactSpec.Load("front", file);
            car.ImpactBack   = ImpactSpec.Load("rear", file);

            car.GridImages = file.ReadStrings();

            int extraLevelsOfDetail = file.ReadInt();

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

            car.WAM = file.ReadLine();

            car.ReflectiveScreenMaterial = file.ReadLine();
            car.TransparencyOfWindscreen = file.ReadSingle();

            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(Funk.Load(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(Groove.Load(file));
                if (file.PeekLine() == "NEXT GROOVE")
                {
                    file.ReadLine();
                }
            }
            file.ReadLine();

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

            car.MinimumTurningCircle      = file.ReadSingle();
            car.BrakeMultiplier           = file.ReadSingle();
            car.BrakingStrengthMultiplier = file.ReadSingle();
            car.NumberOfGears             = file.ReadSingle();
            car.TopGearRedlineSpeed       = file.ReadSingle();
            car.TopGearAcceleration       = file.ReadSingle();

            car.RootPartType       = file.ReadEnum <PartType>();
            car.RootPartIdentifier = file.ReadLine();
            car.RootPartActor      = file.ReadLine();

            car.SubPartType = file.ReadEnum <PartType>();

            car.CentreOfMass = file.ReadVector3();
            car.Mass         = file.ReadSingle();
            car.AngularMomentumProportions    = file.ReadVector3();
            car.DownforceToWeightBalanceSpeed = file.ReadSingle();

            int numberOfWheels = file.ReadInt();

            for (int j = 0; j < numberOfWheels; j++)
            {
                Wheel wheel = new Wheel
                {
                    Type           = file.ReadEnum <Wheel.WheelType>(),
                    Identifier     = file.ReadLine(),
                    Actor          = file.ReadLine(),
                    Position       = file.ReadVector3(),
                    SteerableFlags = file.ReadInt(),
                    DrivenFlags    = file.ReadInt(),
                    SuspensionGive = file.ReadSingle(),
                    DampingFactor  = file.ReadSingle(),
                    SlipFrictionReductionFraction = file.ReadSingle(),
                    FrictionAngles = file.ReadVector2(),
                    TractionFractionalMultiplier = file.ReadSingle(),
                    RollingResistance            = file.ReadSingle()
                };

                car.Wheels.Add(wheel);
            }

            int boundingShapes = file.ReadInt();

            for (int j = 0; j < boundingShapes; j++)
            {
                BoundingShape shape = new BoundingShape
                {
                    Type = file.ReadEnum <BoundingShape.BoundingShapeType>()
                };

                int shapePoints = file.ReadInt();

                for (int k = 0; k < shapePoints; k++)
                {
                    shape.Points.Add(file.ReadVector3());
                }

                car.BoundingShapes.Add(shape);
            }

            int subParts = file.ReadInt();

            for (int j = 0; j < subParts; j++)
            {
                throw new NotImplementedException("subparts?!");
            }

            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());
            }

            for (int i = 0; i < 12; i++)
            {
                car.FirePoints.Add(file.ReadInt());
            }

            while (file.PeekLine() != "END")
            {
                string keyWord = file.ReadLine();

                switch (keyWord)
                {
                case "CAMERA_POSITIONS":
                    car.Keywords.Add(new CameraPosition
                    {
                        BumperPosition  = file.ReadVector3(),
                        CockpitPosition = file.ReadVector3()
                    });
                    break;

                case "CAMERA_TURN_OFF_MATERIALS":
                {
                    CameraTurnOffMaterials ctom = new CameraTurnOffMaterials();

                    int materialCount = file.ReadInt();

                    for (int i = 0; i < materialCount; i++)
                    {
                        CameraTurnOffMaterialEntry ctomEntry = new CameraTurnOffMaterialEntry
                        {
                            MaterialName = file.ReadLine()
                        };

                        int entryCount = file.ReadInt();

                        for (int j = 0; j < entryCount; j++)
                        {
                            ctomEntry.Materials.Add(file.ReadLine());
                        }

                        ctom.Entries.Add(ctomEntry);
                    }

                    car.Keywords.Add(ctom);
                }
                break;

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

            return(car);
        }