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