コード例 #1
0
        public static WAM Load(string path)
        {
            DocumentParser file = new DocumentParser(path);
            WAM            wam  = new WAM();

            string version = file.ReadLine();

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

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

            int xMinCount = file.ReadInt();

            for (int i = 0; i < xMinCount; i++)
            {
                wam.XMins.Add(file.ReadSingle());
            }

            int xMaxCount = file.ReadInt();

            for (int i = 0; i < xMaxCount; i++)
            {
                wam.XMaxs.Add(file.ReadSingle());
            }

            int yMinCount = file.ReadInt();

            for (int i = 0; i < yMinCount; i++)
            {
                wam.YMins.Add(file.ReadSingle());
            }

            int yMaxCount = file.ReadInt();

            for (int i = 0; i < yMaxCount; i++)
            {
                wam.YMaxs.Add(file.ReadSingle());
            }

            int zMinCount = file.ReadInt();

            for (int i = 0; i < zMinCount; i++)
            {
                wam.ZMins.Add(file.ReadSingle());
            }

            int zMaxCount = file.ReadInt();

            for (int i = 0; i < zMaxCount; i++)
            {
                wam.ZMaxs.Add(file.ReadSingle());
            }

            wam.BendabilityFactor  = file.ReadSingle();
            wam.BendPointZMin      = file.ReadSingle();
            wam.BendPointZMax      = file.ReadSingle();
            wam.SnappabilityFactor = file.ReadSingle();
            wam.YSplitPosition     = file.ReadSingle();
            wam.DriverPosition     = file.ReadVector3();

            int crushEntries = file.ReadInt();

            for (int i = 0; i < crushEntries; i++)
            {
                CrushData crush = new CrushData {
                    Actor = file.ReadLine()
                };

                crush.Softness = file.ReadEnum <CrushData.CrushSoftness>();
                crush.Type     = file.ReadEnum <CrushData.CrushType>();

                switch (crush.Type)
                {
                case CrushData.CrushType.detach:
                    crush.EaseOfDetach   = file.ReadEnum <CrushData.Ease>();
                    crush.DetachmentType = file.ReadEnum <CrushData.DetachType>();
                    crush.CrushShape     = file.ReadEnum <CrushData.BoxShape>();
                    break;

                case CrushData.CrushType.flap:
                    crush.HingePoints.Add(file.ReadInt());
                    crush.HingePoints.Add(file.ReadInt());
                    crush.HingePoints.Add(file.ReadInt());
                    crush.KevOFlap   = file.ReadInt() == 1;
                    crush.EaseOfFlap = file.ReadEnum <CrushData.Ease>();
                    crush.CrushShape = file.ReadEnum <CrushData.BoxShape>();
                    break;
                }

                if (crush.CrushShape == CrushData.BoxShape.poly)
                {
                    int polyPoints = file.ReadInt();

                    for (int j = 0; j < polyPoints; j++)
                    {
                        crush.ShapePoints.Add(file.ReadInt());;
                    }
                }

                int smashEntries = file.ReadInt();

                for (int j = 0; j < smashEntries; j++)
                {
                    SmashData smash = new SmashData
                    {
                        Trigger     = file.ReadLine(),
                        TriggerMode = SmashData.SmashTriggerMode.texturechange
                    };

                    smash.IntactMaterial = file.ReadLine();
                    int textureLevels = file.ReadInt();

                    for (int k = 0; k < textureLevels; k++)
                    {
                        SmashDataTextureLevel textureLevel = new SmashDataTextureLevel()
                        {
                            TriggerThreshold = file.ReadSingle(),
                            Flags            = file.ReadInt()
                        };

                        textureLevel.Connotations.Load(file);

                        int pixelmaps = file.ReadInt();
                        for (int l = 0; l < pixelmaps; l++)
                        {
                            textureLevel.Pixelmaps.Add(file.ReadLine());
                        }

                        smash.Levels.Add(textureLevel);
                    }

                    crush.SmashEntries.Add(smash);
                }

                wam.CrushEntries.Add(crush);
            }

            return(wam);
        }
コード例 #2
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()
                {
                    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();

            for (int i = 0; i < smashSpecs; i++)
            {
                SmashData smashable = new SmashData
                {
                    Flags   = file.ReadInt(),
                    Trigger = file.ReadLine()
                };

                if (smashable.Trigger.Length == 3 && smashable.Trigger.StartsWith("&"))
                {
                    smashable.TriggerFlags = file.ReadInt();
                }

                smashable.TriggerMode = file.ReadEnum <SmashData.SmashTriggerMode>();

                switch (smashable.TriggerMode)
                {
                case SmashData.SmashTriggerMode.nochange:
                case SmashData.SmashTriggerMode.remove:
                    smashable.RemovalThreshold = file.ReadSingle();
                    smashable.Connotations.Load(file);
                    break;

                case SmashData.SmashTriggerMode.replacemodel:
                    smashable.RemovalThreshold = file.ReadSingle();
                    smashable.Connotations.Load(file);
                    smashable.NewModel     = file.ReadLine();
                    smashable.ChanceOfFire = file.ReadInt();

                    if (smashable.ChanceOfFire > 0)
                    {
                        smashable.NumFires   = file.ReadInt();
                        smashable.SmokeLevel = file.ReadInts();
                    }
                    break;

                case SmashData.SmashTriggerMode.texturechange:
                    smashable.IntactMaterial = file.ReadLine();
                    int textureLevels = file.ReadInt();

                    for (int j = 0; j < textureLevels; j++)
                    {
                        SmashDataTextureLevel textureLevel = new SmashDataTextureLevel()
                        {
                            TriggerThreshold = file.ReadSingle(),
                            Flags            = file.ReadInt(),
                            CollisionType    = file.ReadEnum <SmashDataTextureLevel.TextureLevelCollisionType>()
                        };

                        textureLevel.Connotations.Load(file);

                        int pixelmaps = file.ReadInt();
                        for (int k = 0; k < pixelmaps; k++)
                        {
                            textureLevel.Pixelmaps.Add(file.ReadLine());
                        }

                        smashable.Levels.Add(textureLevel);
                    }
                    break;

                default:
                    throw new NotImplementedException($"Unknown TriggerMode '{smashable.TriggerMode}'");
                }

                smashable.Reserved1 = file.ReadInt();
                smashable.Reserved2 = file.ReadInt();
                smashable.Reserved3 = file.ReadInt();
                smashable.Reserved4 = file.ReadInt();

                map.Smashables.Add(smashable);
            }

            int pedSpecs = file.ReadInt();

            for (int i = 0; i < pedSpecs; i++)
            {
                PedSpec ps = new PedSpec()
                {
                    MaterialName           = file.ReadLine(),
                    MovementIndex          = file.ReadInt(),
                    GroupIndex             = file.ReadInt(),
                    PedsPer100SquareMetres = file.ReadSingle()
                };

                int exclusionCount = file.ReadInt();
                for (int j = 0; j < exclusionCount; j++)
                {
                    ps.ExclusionMaterials.Add(new PedExclusionMaterial
                    {
                        Flags = file.ReadInt(),
                        Name  = 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 {
                    Type = file.ReadLine()
                };

                if (sev.Type.ToUpper() == "BOX")
                {
                    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();

                if (file.PeekLine().Contains(","))
                {
                    sev.SkyColourRGB = file.ReadVector3();
                }
                else
                {
                    sev.SkyColour = file.ReadInt();
                }

                sev.WindscreenMaterial = file.ReadLine();
                sev.EntrySoundID       = file.ReadInt();
                sev.ExitSoundID        = file.ReadInt();
                sev.EngineNoiseIndex   = file.ReadInt();
                sev.MaterialIndex      = file.ReadInt();

                if (sev.Type.ToUpper() == "BOX")
                {
                    sev.SoundType = file.ReadEnum <SpecialEffectVolume.SpecVolSoundType>();

                    if (sev.SoundType != SpecialEffectVolume.SpecVolSoundType.NONE)
                    {
                        sev.SoundSpec = SoundSpec.Load(file);
                    }
                }

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

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

            while (file.PeekLine() != "END OF FUNK")
            {
                map.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 Map.TXT file?", "START OF GROOVE");
                return(null);
            }

            while (file.PeekLine() != "END OF GROOVE")
            {
                map.Grooves.Add(Groove.Load(file));
                if (file.PeekLine() == "NEXT GROOVE")
                {
                    file.ReadLine();
                }
            }
            file.ReadLine();

            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++)
            {
                string[] parts = file.ReadLine().Split(',');

                map.Paths.Add(new OpponentPathSection
                {
                    StartNode   = parts[0].ToInt(),
                    EndNode     = parts[1].ToInt(),
                    Unknown1    = parts[2].ToInt(),
                    Unknown2    = parts[3].ToInt(),
                    Unknown3    = parts[4].ToInt(),
                    Unknown4    = parts[5].ToInt(),
                    Width       = parts[6].ToSingle(),
                    SectionType = parts[7].ToInt()
                });
            }

            int copStartPoints = file.ReadInt();

            if (copStartPoints > 0)
            {
                throw new NotImplementedException("Cop start points?  Really?");
            }

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

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

            map.DronePathVersion = file.ReadInt();

            int dronepathNodeCount = file.ReadInt();

            for (int i = 0; i < dronepathNodeCount; i++)
            {
                DronePathNode node = new DronePathNode
                {
                    Position  = file.ReadVector3(),
                    DroneName = file.ReadLine()
                };

                if (map.DronePathVersion == 0)
                {
                    node.UnknownVector = file.ReadVector3();
                }
                else
                {
                    node.UnknownInt = file.ReadInt();
                }

                int nextNodeCount = file.ReadInt();
                for (int j = 0; j < nextNodeCount; j++)
                {
                    node.Destinations.Add(file.ReadLine());
                }

                map.DronePaths.Add(node);
            }

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

            int materialModifierCount = file.ReadInt();

            for (int i = 0; i < materialModifierCount; i++)
            {
                map.MaterialModifiers.Add(new MaterialModifier
                {
                    CarWallFriction  = file.ReadSingle(),
                    TyreRoadFriction = file.ReadSingle(),
                    DownForce        = file.ReadSingle(),
                    Bumpiness        = file.ReadSingle(),
                    TyreSoundIndex   = file.ReadInt(),
                    CrashSoundIndex  = file.ReadInt(),
                    ScrapeNoiseIndex = file.ReadInt(),
                    Sparkiness       = file.ReadSingle(),
                    RoomForExpansion = file.ReadInt(),
                    SkidmarkMaterial = file.ReadLine()
                });
            }

            int noncarCount = file.ReadInt();

            for (int i = 0; i < noncarCount; i++)
            {
                map.Noncars.Add(file.ReadLine());
            }

            int shadetableCount = file.ReadInt();

            for (int i = 0; i < shadetableCount; i++)
            {
                map.ShadeTables.Add(new ShadeTable
                {
                    RGB       = file.ReadVector3(),
                    Strengths = file.ReadVector3()
                });
            }

            int networkStartCount = file.ReadInt();

            for (int i = 0; i < networkStartCount; i++)
            {
                map.NetworkStarts.Add(new NetworkStart
                {
                    Position = file.ReadVector3(),
                    Rotation = file.ReadInt()
                });
            }

            int splashfileCount = file.ReadInt();

            for (int i = 0; i < splashfileCount; i++)
            {
                map.SplashFiles.Add(file.ReadLine());
            }

            int txtfileCount = file.ReadInt();

            for (int i = 0; i < txtfileCount; i++)
            {
                map.TxtFiles.Add(file.ReadLine());
            }

            return(map);
        }