예제 #1
0
        public static Vcf ParseVcf(string filename)
        {
            var vcf = new Vcf();

            using (var br = new Bwd2Reader(filename))
            {
                br.FindNext("VCFC");

                vcf.VariantName             = br.ReadCString(16);
                vcf.VdfFilename             = br.ReadCString(13);
                vcf.VtfFilename             = br.ReadCString(13);
                vcf.EngineType              = br.ReadUInt32();
                vcf.SuspensionType          = br.ReadUInt32();
                vcf.BrakesType              = br.ReadUInt32();
                vcf.WdfFrontFilename        = br.ReadCString(13);
                vcf.WdfMidFilename          = br.ReadCString(13);
                vcf.WdfBackFilename         = br.ReadCString(13);
                vcf.ArmorFront              = br.ReadUInt32();
                vcf.ArmorLeft               = br.ReadUInt32();
                vcf.ArmorRight              = br.ReadUInt32();
                vcf.ArmorRear               = br.ReadUInt32();
                vcf.ChassisFront            = br.ReadUInt32();
                vcf.ChassisLeft             = br.ReadUInt32();
                vcf.ChassisRight            = br.ReadUInt32();
                vcf.ChassisRear             = br.ReadUInt32();
                vcf.ArmorOrChassisLeftToAdd = br.ReadUInt32();

                br.FindNext("WEPN");
                vcf.Weapons = new List <VcfWeapon>();
                while (br.Current != null && br.Current.Name != "EXIT")
                {
                    var vcfWeapon = new VcfWeapon
                    {
                        MountPoint  = (MountPoint)br.ReadUInt32(),
                        GdfFilename = br.ReadCString(13)
                    };
                    vcf.Weapons.Add(vcfWeapon);
                    br.Next();
                }
            }

            if (vcf.WdfFrontFilename.ToUpper() != "NULL")
            {
                vcf.FrontWheelDef = WdfParser.ParseWdf(vcf.WdfFrontFilename);
            }
            if (vcf.WdfMidFilename.ToUpper() != "NULL")
            {
                vcf.MidWheelDef = WdfParser.ParseWdf(vcf.WdfMidFilename);
            }
            if (vcf.WdfBackFilename.ToUpper() != "NULL")
            {
                vcf.BackWheelDef = WdfParser.ParseWdf(vcf.WdfBackFilename);
            }

            return(vcf);
        }
예제 #2
0
        public static Sdf LoadSdf(string filename)
        {
            filename = filename.ToLower();
            if (SdfCache.ContainsKey(filename))
            {
                return(SdfCache[filename]);
            }

            using (var br = new Bwd2Reader(filename))
            {
                var sdf = new Sdf();

                br.FindNext("SDFC");
                sdf.Name = br.ReadCString(16);
                var one   = br.ReadUInt32();
                var size  = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                var unk1  = br.ReadUInt32();
                var unk2  = br.ReadUInt32();
                var fifty = br.ReadUInt32();
                var xdf   = br.ReadCString(13);
                var wav   = br.ReadCString(13);

                br.FindNext("SGEO");
                var numParts = br.ReadUInt32();
                sdf.Parts = new SdfPart[numParts];
                for (int i = 0; i < numParts; i++)
                {
                    var sdfPart = new SdfPart();
                    sdfPart.Name       = br.ReadCString(8);
                    sdfPart.Right      = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                    sdfPart.Up         = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                    sdfPart.Forward    = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                    sdfPart.Position   = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                    sdfPart.ParentName = br.ReadCString(8);
                    br.BaseStream.Seek(56, SeekOrigin.Current);

                    sdf.Parts[i] = sdfPart;
                }

                SdfCache.Add(filename, sdf);
                return(sdf);
            }
        }
예제 #3
0
        public static Wdf ParseWdf(string filename)
        {
            using (var br = new Bwd2Reader(filename))
            {
                var wdf = new Wdf();

                br.FindNext("WDFC");
                wdf.Name   = br.ReadCString(20);
                wdf.Float1 = br.ReadSingle(); //160
                wdf.Float2 = br.ReadSingle(); //100
                wdf.Float3 = br.ReadSingle(); //70
                wdf.Float4 = br.ReadSingle(); //30
                wdf.Byte1  = br.ReadByte();   // 255
                wdf.Byte2  = br.ReadByte();   // 255
                wdf.Byte3  = br.ReadByte();   // 127
                wdf.Byte4  = br.ReadByte();   // 127
                wdf.Int1   = br.ReadUInt32(); // 100

                wdf.Float5 = br.ReadSingle(); //10
                wdf.Radius = br.ReadSingle();

                br.FindNext("WGEO");
                var numParts = br.ReadUInt32();
                wdf.Parts = new SdfPart[numParts];
                for (int i = 0; i < numParts; i++)
                {
                    var sdfPart = new SdfPart();
                    sdfPart.Name       = br.ReadCString(8);
                    sdfPart.Right      = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                    sdfPart.Up         = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                    sdfPart.Forward    = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                    sdfPart.Position   = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                    sdfPart.ParentName = br.ReadCString(8);
                    br.BaseStream.Seek(36, SeekOrigin.Current);

                    wdf.Parts[i] = sdfPart;
                }

                return(wdf);
            }
        }
예제 #4
0
 public Bwd2Reader(Bwd2Reader parentReader) : this(new PartStream(parentReader.BaseStream, parentReader.Current.DataPosition, parentReader.Current.DataLength))
 {
 }
예제 #5
0
        public static Vdf ParseVdf(string filename)
        {
            using (var br = new Bwd2Reader(filename))
            {
                var vdf = new Vdf();

                br.FindNext("VDFC");


                vdf.Name     = br.ReadCString(16);
                vdf.Unk0     = br.ReadUInt32();
                vdf.Unk1     = br.ReadUInt32();
                vdf.Unk2     = br.ReadUInt32();
                vdf.Unk70f   = br.ReadSingle();
                vdf.Unk35f   = br.ReadSingle();
                vdf.Unk30f   = br.ReadSingle();
                vdf.Unk25f   = br.ReadSingle();
                vdf.Unk255b  = br.ReadByte();
                vdf.Unk255b2 = br.ReadByte();
                vdf.Unk127b  = br.ReadByte();
                vdf.Unk127b2 = br.ReadByte();
                vdf.Unk1320f = br.ReadSingle();
                vdf.Unk1f    = br.ReadSingle();
                vdf.Unk63b   = br.ReadByte();
                vdf.Unk82b   = br.ReadByte();
                vdf.Unk73b   = br.ReadByte();
                vdf.Unk157b  = br.ReadByte();
                vdf.Unk57b   = br.ReadByte();


                vdf.Unk4 = br.ReadUInt32();

                br.FindNext("SOBJ");
                vdf.SOBJGeoName = br.ReadCString(8);

                vdf.VLocs = new List <VLoc>();
                br.FindNext("VLOC");
                while (br.Current != null && br.Current.Name != "EXIT")
                {
                    var vloc = new VLoc
                    {
                        Number   = br.ReadUInt32(),
                        Right    = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()),
                        Up       = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()),
                        Forward  = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()),
                        Position = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle())
                    };
                    vdf.VLocs.Add(vloc);

                    br.Next();
                }


                br.FindNext("VGEO");
                var numParts = br.ReadUInt32();
                vdf.PartsThirdPerson = new List <SdfPart[]>(4);
                for (int damageState = 0; damageState < 4; damageState++)
                {
                    var parts = new SdfPart[numParts];
                    for (int i = 0; i < numParts; i++)
                    {
                        var sdfPart = new SdfPart();
                        sdfPart.Name       = br.ReadCString(8);
                        sdfPart.Right      = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                        sdfPart.Up         = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                        sdfPart.Forward    = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                        sdfPart.Position   = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                        sdfPart.ParentName = br.ReadCString(8);
                        br.BaseStream.Seek(36, SeekOrigin.Current);

                        parts[i] = sdfPart;
                    }
                    vdf.PartsThirdPerson.Add(parts);
                }
                br.BaseStream.Seek(100 * numParts * 12, SeekOrigin.Current);

                vdf.PartsFirstPerson = new SdfPart[numParts];
                for (int i = 0; i < numParts; i++)
                {
                    var sdfPart = new SdfPart();
                    sdfPart.Name       = br.ReadCString(8);
                    sdfPart.Right      = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                    sdfPart.Up         = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                    sdfPart.Forward    = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                    sdfPart.Position   = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                    sdfPart.ParentName = br.ReadCString(8);
                    br.BaseStream.Seek(36, SeekOrigin.Current);

                    vdf.PartsFirstPerson[i] = sdfPart;
                }

                br.FindNext("WLOC");
                vdf.WheelLoc = new WheelLoc[6];
                for (int i = 0; i < 6; i++)
                {
                    var wheelLoc = vdf.WheelLoc[i] = new WheelLoc();
                    var unk1     = br.ReadUInt32();
                    wheelLoc.Right    = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                    wheelLoc.Up       = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                    wheelLoc.Forward  = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                    wheelLoc.Position = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                    var unk2 = br.ReadSingle();
                }

                vdf.HLocs = new List <HLoc>();
                br.FindNext("HLOC");
                while (br.Current != null && br.Current.Name != "EXIT")
                {
                    var hloc = new HLoc
                    {
                        Label    = br.ReadCString(16),
                        Num1     = br.ReadUInt32(),
                        Num2     = br.ReadUInt32(),
                        Num3     = br.ReadUInt32(),
                        Right    = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()),
                        Up       = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()),
                        Forward  = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()),
                        Position = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()),
                        Unk      = br.ReadSingle()
                    };
                    vdf.HLocs.Add(hloc);

                    br.Next();
                }

                return(vdf);
            }
        }
예제 #6
0
        public static MissonDefinition ReadMsnMission(string filename)
        {
            var mdef = new MissonDefinition();

            using (var msn = new Bwd2Reader(filename))
            {
                msn.FindNext("WDEF");
                using (var wdef = new Bwd2Reader(msn))
                {
                    wdef.FindNext("WRLD");
                    wdef.BaseStream.Seek(30, SeekOrigin.Current);
                    mdef.PaletteFilePath         = wdef.ReadCString(13);
                    mdef.LumaTableFilePath       = wdef.ReadCString(13);
                    mdef.XlucencyTableFilePath   = wdef.ReadCString(13);
                    mdef.ObjectiveFilePath       = wdef.ReadCString(13);
                    mdef.SkyTextureFilePath      = wdef.ReadCString(13);
                    mdef.ScroungeTextureFilePath = wdef.ReadCString(13);
                    mdef.SurfaceTextureFilePath  = wdef.ReadCString(13);
                    mdef.LevelMapFilePath        = wdef.ReadCString(13);
                    mdef.HzdFilePath             = wdef.ReadCString(13);
                }
                msn.FindNext("TDEF");
                var    heights = new List <float[, ]>();
                byte[] patchConfig;
                using (var tdef = new Bwd2Reader(msn))
                {
                    tdef.FindNext("ZMAP");
                    var numUniqueTerrainPatches = tdef.ReadByte();
                    patchConfig = tdef.ReadBytes(80 * 80);

                    tdef.FindNext("ZONE");
                    var unk             = tdef.ReadByte();
                    var terrainFilePath = tdef.ReadCString(13);

                    using (var terr = new BinaryReader(VirtualFilesystem.Instance.GetFileStream(terrainFilePath)))
                    {
                        for (var i = 0; i < numUniqueTerrainPatches; i++)
                        {
                            var h = new float[129, 129];
                            for (int z = 0; z < 128; z++)
                            {
                                for (int x = 0; x < 128; x++)
                                {
                                    var tpoint = terr.ReadUInt16();
                                    var height = (tpoint & 0x0FFF) / 4096.0f;
                                    h[z, x] = height;
                                }
                            }

                            heights.Add(h);
                        }
                    }

                    var botLeft  = new Vector2(80, 80);
                    var topRight = new Vector2(0, 0);

                    var defaultHeights = new float[129, 129];
                    for (int z = 0; z < 80; z++)
                    {
                        for (int x = 0; x < 80; x++)
                        {
                            var patchIdx = patchConfig[z * 80 + x];
                            if (patchIdx == 0xFF)
                            {
                                //mdef.TerrainPatches[x, z] = new TerrainPatch(defaultTerrainData);
                            }
                            else
                            {
                                if (x < botLeft.x)
                                {
                                    botLeft.x = x;
                                }
                                if (z < botLeft.y)
                                {
                                    botLeft.y = z;
                                }
                                if (x > topRight.x)
                                {
                                    topRight.x = x;
                                }
                                if (z > topRight.y)
                                {
                                    topRight.y = z;
                                }

                                var h             = heights[patchIdx];
                                var rightPatchIdx = x == 79 ? 0xFF : patchConfig[z * 80 + x + 1];
                                var rightHeights  = rightPatchIdx == 0xFF ? defaultHeights : heights[rightPatchIdx];
                                for (int xx = 0; xx < 129; xx++)
                                {
                                    h[xx, 128] = rightHeights[xx, 0];
                                }

                                var bottomPatchIdx = z == 79 ? 0xFF : patchConfig[(z + 1) * 80 + x];
                                var bottomHeights  = bottomPatchIdx == 0xFF ? defaultHeights : heights[bottomPatchIdx];
                                for (int zz = 0; zz < 129; zz++)
                                {
                                    h[128, zz] = bottomHeights[0, zz];
                                }

                                var bottomRightPatchIdx = z == 79 || x == 79 ? 0xFF : patchConfig[(z + 1) * 80 + x + 1];
                                var bottomRightHeights  = bottomRightPatchIdx == 0xFF
                                    ? defaultHeights
                                    : heights[bottomRightPatchIdx];
                                h[128, 128] = bottomRightHeights[0, 0];

                                var tdata = CreateTerrainData();
                                tdata.SetHeights(0, 0, h);
                                mdef.TerrainPatches[x, z] = new TerrainPatch(tdata);
                            }
                        }
                    }
                    mdef.Middle = (topRight + botLeft) / 2.0f;
                }

                msn.FindNext("RDEF");
                using (var rdef = new Bwd2Reader(msn))
                {
                    rdef.FindNext("RSEG");
                    while (rdef.Current != null && rdef.Current.Name != "EXIT")
                    {
                        var segmentType       = rdef.ReadUInt32();
                        var segmentPieceCount = rdef.ReadUInt32();
                        var road = new Road
                        {
                            SegmentType = (RoadSegmentType)segmentType
                        };

                        for (int i = 0; i < segmentPieceCount; i++)
                        {
                            var roadSegment = new RoadSegment
                            {
                                Left  = new Vector3(rdef.ReadSingle(), rdef.ReadSingle(), rdef.ReadSingle()),
                                Right = new Vector3(rdef.ReadSingle(), rdef.ReadSingle(), rdef.ReadSingle())
                            };

                            var pos            = roadSegment.Left;
                            var patchPosX      = (int)(pos.x / 640.0f);
                            var patchPosZ      = (int)(pos.z / 640.0f);
                            var localPositionX = (pos.x % 640) / 640.0f;
                            var localPositionZ = (pos.z % 640) / 640.0f;
                            var y =
                                mdef.TerrainPatches[patchPosX, patchPosZ].TerrainData.GetInterpolatedHeight(localPositionX,
                                                                                                            localPositionZ) + 0.1f;
                            pos.y            = y;
                            roadSegment.Left = pos;

                            pos            = roadSegment.Right;
                            patchPosX      = (int)(pos.x / 640.0f);
                            patchPosZ      = (int)(pos.z / 640.0f);
                            localPositionX = (pos.x % 640) / 640.0f;
                            localPositionZ = (pos.z % 640) / 640.0f;
                            y =
                                mdef.TerrainPatches[patchPosX, patchPosZ].TerrainData.GetInterpolatedHeight(localPositionX,
                                                                                                            localPositionZ) + 0.1f;
                            pos.y             = y;
                            roadSegment.Right = pos;

                            road.RoadSegments.Add(roadSegment);
                            //TODO: Figure out
                        }
                        mdef.Roads.Add(road);

                        rdef.Next();
                    }
                }

                msn.FindNext("ODEF");
                using (var odef = new Bwd2Reader(msn))
                {
                    odef.FindNext("OBJ");
                    while (odef.Current.Name != "EXIT")
                    {
                        var           rawlabel     = odef.ReadBytes(8);
                        int           labelhigh    = 0;
                        StringBuilder labelBuilder = new StringBuilder();
                        for (int i = 0; i < 8; i++)
                        {
                            var v = rawlabel[i];
                            if (v > 0x7f)
                            {
                                labelhigh = (labelhigh << 1) | 0x01;
                            }
                            else
                            {
                                labelhigh = (labelhigh << 1) & 0xfe;
                            }
                            v = (byte)(v & 0x7f);
                            if (v != 0)
                            {
                                labelBuilder.Append((char)v);
                            }
                        }
                        var label   = labelBuilder.ToString();
                        var right   = new Vector3(odef.ReadSingle(), odef.ReadSingle(), odef.ReadSingle());
                        var upwards = new Vector3(odef.ReadSingle(), odef.ReadSingle(), odef.ReadSingle());
                        var forward = new Vector3(odef.ReadSingle(), odef.ReadSingle(), odef.ReadSingle());
                        var pos     = new Vector3(odef.ReadSingle(), odef.ReadSingle(), odef.ReadSingle());
                        odef.BaseStream.Position += 36;
                        var classId = (ClassId)odef.ReadUInt32();
                        odef.ReadUInt16();
                        var teamId = odef.ReadUInt16();

                        var localPosition = new Vector3(pos.x % 640, pos.y, pos.z % 640);
                        var patchPosX     = (int)(pos.x / 640.0f);
                        var patchPosZ     = (int)(pos.z / 640.0f);
                        mdef.TerrainPatches[patchPosX, patchPosZ].Objects.Add(new Odef
                        {
                            Label         = label,
                            Id            = labelhigh,
                            LocalPosition = localPosition,
                            ClassId       = classId,
                            TeamId        = teamId,
                            LocalRotation = Quaternion.LookRotation(forward, upwards)
                        });

                        odef.Next();
                    }
                }

                msn.FindNext("LDEF");
                using (var ldef = new Bwd2Reader(msn))
                {
                    ldef.FindNext("OBJ");
                    while (ldef.Current != null && ldef.Current.Name != "EXIT")
                    {
                        var label = ldef.ReadCString(8);
                        ldef.BaseStream.Position += 84;
                        var classId = (ClassId)ldef.ReadUInt32();
                        ldef.ReadUInt32();
                        var numStrings = ldef.ReadUInt32();

                        var stringPositions = new List <Vector3>();
                        for (int i = 0; i < numStrings; i++)
                        {
                            var stringPos = new Vector3(ldef.ReadSingle(), ldef.ReadSingle(), ldef.ReadSingle());
                            stringPositions.Add(stringPos);
                        }

                        mdef.StringObjects.Add(new Ldef
                        {
                            Label           = label,
                            StringPositions = stringPositions
                        });

                        ldef.Next();
                    }
                }
            }
            return(mdef);
        }
예제 #7
0
        /*
         *  TMT's are referred in this order:
         *  Front, Back, Right, Left, Top, Under
         *
         *  Given a filename of:
         *  1CP1FTFT
         *
         *  decodes as
         *  1CP = First cop car skin
         *  1 = LOD level
         *  FTFT = Front Front
         *
         *  Sequence of tmt files:
         *  Front
         *  Mid
         *  Back
         *  Top
         *
         *  Full list:
         *
         *  FTFT
         *  FTBK
         *  FTRT
         *  FTLT
         *  FTTP
         *  FTUN
         *
         *  MDFT
         *  MDBK
         *  MDRT
         *  MDLT
         *  MDTP
         *  MDUN
         *
         *  BKFT
         *  BKBK
         *  BKRT
         *  BKLT
         *  BKTP
         *  BKUN
         *
         *  TPFT
         *  TPBK
         *  TPRT
         *  TPLT
         *  TPTP
         *  TPUN
         */


        public static Vtf ParseVtf(string filename)
        {
            var vtf = new Vtf();

            using (var br = new Bwd2Reader(filename))
            {
                br.FindNext("VTFC");

                vtf.VdfFilename     = br.ReadCString(13);
                vtf.PaintSchemeName = br.ReadCString(16);

                vtf.TmtFilenames = new string[78];
                for (int i = 0; i < vtf.TmtFilenames.Length; i++)
                {
                    vtf.TmtFilenames[i] = br.ReadCString(13);
                }

                vtf.Maps = new string[13];
                for (int i = 0; i < vtf.Maps.Length; i++)
                {
                    vtf.Maps[i] = br.ReadCString(13).Replace(".map", "");
                }
            }

            vtf.Tmts = new Dictionary <string, Tmt>();
            for (var tmtIdx = 0; tmtIdx < vtf.TmtFilenames.Length; tmtIdx++)
            {
                var tmtFilename = vtf.TmtFilenames[tmtIdx];
                if (tmtFilename != "NULL")
                {
                    using (var br = new BinaryReader(VirtualFilesystem.Instance.GetFileStream(tmtFilename)))
                    {
                        var one      = br.ReadUInt32();
                        var zero1    = br.ReadUInt32();
                        var zero2    = br.ReadUInt32();
                        var zero3    = br.ReadUInt32();
                        var zero4    = br.ReadUInt32();
                        var two      = br.ReadUInt32();
                        var two2     = br.ReadUInt32();
                        var four     = br.ReadUInt32();
                        var zero5    = br.ReadUInt32();
                        var zero6    = br.ReadUInt32();
                        var tenFloat = br.ReadSingle();
                        var zero7    = br.ReadSingle();
                        var zero8    = br.ReadSingle();
                        var zero9    = br.ReadSingle();
                        var zero10   = br.ReadSingle();
                        var zero11   = br.ReadSingle();

                        var tmt = new Tmt
                        {
                            TextureNames = new List <string>()
                        };
                        while (br.BaseStream.Position < br.BaseStream.Length)
                        {
                            var textureName = br.ReadCString(8);
                            tmt.TextureNames.Add(textureName);
                        }
                        vtf.Tmts.Add(tmtFilename.Substring(3), tmt);
                    }
                }
            }

            return(vtf);
        }