예제 #1
0
        public static Wdf ParseWdf(string filename)
        {
            using (Bwd2Reader br = new Bwd2Reader(filename))
            {
                Wdf 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");
                uint numParts = br.ReadUInt32();
                wdf.Parts = new SdfPart[numParts];
                for (int i = 0; i < numParts; i++)
                {
                    SdfPart 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.Position       += 36;

                    wdf.Parts[i] = sdfPart;
                }

                br.Position -= 16;
                wdf.Radius   = br.ReadSingle();

                return(wdf);
            }
        }
예제 #2
0
        private static SdfPart GetDestroyedPart(Bwd2Reader br)
        {
            string partName = br.ReadCString(8);

            if (string.IsNullOrEmpty(partName) || partName.ToLower() == "null")
            {
                br.Position += 112;
                return(null);
            }

            SdfPart wreckedPart = new SdfPart();

            wreckedPart.Name       = partName;
            wreckedPart.Right      = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
            wreckedPart.Up         = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
            wreckedPart.Forward    = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
            wreckedPart.Position   = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
            wreckedPart.ParentName = br.ReadCString(8);
            br.Position           += 56;

            return(wreckedPart);
        }
예제 #3
0
        public static Vdf ParseVdf(string filename)
        {
            using (Bwd2Reader br = new Bwd2Reader(filename))
            {
                Vdf vdf = new Vdf();
                br.FindNext("VDFC");

                vdf.Name                = br.ReadCString(20);
                vdf.VehicleType         = br.ReadUInt32();
                vdf.VehicleSize         = br.ReadUInt32();
                vdf.LODDistance1        = br.ReadSingle();
                vdf.LODDistance2        = br.ReadSingle();
                vdf.LODDistance3        = br.ReadSingle();
                vdf.LODDistance4        = br.ReadSingle();
                vdf.LODDistance5        = br.ReadSingle();
                vdf.Mass                = br.ReadSingle();
                vdf.CollisionMultiplier = br.ReadSingle();
                vdf.DragCoefficient     = br.ReadSingle();
                vdf.Unknown             = br.ReadUInt32();
                if (br.Current.DataLength == 77)
                {
                    vdf.EltFile = br.ReadCString(13);
                }

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

                vdf.VLocs = new List <VLoc>();
                br.FindNext("VLOC");
                while (br.Current != null && br.Current.Name != "EXIT")
                {
                    VLoc 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");
                uint numParts = br.ReadUInt32();
                vdf.PartsThirdPerson = new List <SdfPart[]>(4);
                for (int damageState = 0; damageState < 4; damageState++)
                {
                    SdfPart[] parts = new SdfPart[numParts];
                    for (int i = 0; i < numParts; i++)
                    {
                        SdfPart 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.Position       += 36;

                        parts[i] = sdfPart;
                    }
                    vdf.PartsThirdPerson.Add(parts);
                }
                br.Position += 100 * numParts * 12;

                vdf.PartsFirstPerson = new SdfPart[numParts];
                for (int i = 0; i < numParts; i++)
                {
                    SdfPart 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.Position       += 36;

                    vdf.PartsFirstPerson[i] = sdfPart;
                }

                br.FindNext("COLP");

                float zMaxOuter = br.ReadSingle();
                float zMaxInner = br.ReadSingle();
                float zMinInner = br.ReadSingle();
                float zMinOuter = br.ReadSingle();

                float xMaxOuter = br.ReadSingle();
                float xMaxInner = br.ReadSingle();
                float xMinInner = br.ReadSingle();
                float xMinOuter = br.ReadSingle();

                float yMaxOuter = br.ReadSingle();
                float yMaxInner = br.ReadSingle();
                float yMinInner = br.ReadSingle();
                float yMinOuter = br.ReadSingle();

                Bounds innerBounds = new Bounds();
                innerBounds.SetMinMax(new Vector3(xMinInner, yMinInner, zMinInner), new Vector3(xMaxInner, yMaxInner, zMaxInner));
                vdf.BoundsInner = innerBounds;

                Bounds outerBounds = new Bounds();
                outerBounds.SetMinMax(new Vector3(xMinOuter, yMinOuter, zMinOuter), new Vector3(xMaxOuter, yMaxOuter, zMaxOuter));
                vdf.BoundsOuter = outerBounds;

                br.FindNext("WLOC");
                vdf.WheelLoc = new WheelLoc[6];
                for (int i = 0; i < 6; i++)
                {
                    WheelLoc wheelLoc = vdf.WheelLoc[i] = new WheelLoc();
                    uint     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());
                    float unk2 = br.ReadSingle();
                }

                vdf.HLocs = new List <HLoc>();
                br.FindNext("HLOC");
                while (br.Current != null && br.Current.Name != "EXIT")
                {
                    HLoc hloc = new HLoc
                    {
                        Label           = br.ReadCString(16),
                        HardpointIndex  = br.ReadUInt32(),
                        FacingDirection = br.ReadUInt32(),
                        MeshType        = (HardpointMeshType)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();
                }

                if (!SpriteManager.Instance.Initialised)
                {
                    if (vdf.EltFile == null)
                    {
                        vdf.Etbls = new List <ETbl>();
                        br.FindNext("ETBL");

                        while (br.Current != null && br.Current.Name != "EXIT")
                        {
                            long tableEnd = br.Current.DataPosition + br.Current.DataLength;
                            while (br.Position < tableEnd)
                            {
                                ETbl etbl = new ETbl
                                {
                                    MapFile          = br.ReadCString(13),
                                    IsReferenceImage = br.ReadUInt32() == 1,
                                    ItemCount        = br.ReadUInt32(),
                                };

                                uint itemCount = etbl.ItemCount;
                                etbl.Items = new Dictionary <string, ETbl.ETblItem>((int)itemCount);
                                for (uint i = 0; i < itemCount; ++i)
                                {
                                    ETbl.ETblItem etblItem = new ETbl.ETblItem
                                    {
                                        Name    = br.ReadCString(16),
                                        XOffset = br.ReadInt32(),
                                        YOffset = br.ReadInt32(),
                                        Width   = br.ReadInt32(),
                                        Height  = br.ReadInt32()
                                    };

                                    etbl.Items.Add(etblItem.Name, etblItem);
                                }

                                vdf.Etbls.Add(etbl);
                            }

                            br.Next();
                        }
                    }
                    else
                    {
                        vdf.Etbls = EltParser.ParseElt(vdf.EltFile);
                    }

                    if (vdf.Etbls != null && vdf.Etbls.Count > 0)
                    {
                        SpriteManager.Instance.Initialise(vdf);
                    }
                }

                return(vdf);
            }
        }
예제 #4
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)
        {
            Vtf vtf = new Vtf();

            using (Bwd2Reader 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 (int tmtIdx = 0; tmtIdx < vtf.TmtFilenames.Length; tmtIdx++)
            {
                string tmtFilename = vtf.TmtFilenames[tmtIdx];
                if (tmtFilename != "NULL")
                {
                    using (Scripts.System.FastBinaryReader br = VirtualFilesystem.Instance.GetFileStream(tmtFilename))
                    {
                        uint  one      = br.ReadUInt32();
                        uint  zero1    = br.ReadUInt32();
                        uint  zero2    = br.ReadUInt32();
                        uint  zero3    = br.ReadUInt32();
                        uint  zero4    = br.ReadUInt32();
                        uint  two      = br.ReadUInt32();
                        uint  two2     = br.ReadUInt32();
                        uint  four     = br.ReadUInt32();
                        uint  zero5    = br.ReadUInt32();
                        uint  zero6    = br.ReadUInt32();
                        float tenFloat = br.ReadSingle();
                        float zero7    = br.ReadSingle();
                        float zero8    = br.ReadSingle();
                        float zero9    = br.ReadSingle();
                        float zero10   = br.ReadSingle();
                        float zero11   = br.ReadSingle();

                        Tmt tmt = new Tmt
                        {
                            TextureNames = new List <string>()
                        };

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

            return(vtf);
        }
예제 #5
0
파일: Bwd2Reader.cs 프로젝트: r1sc/Open76
 public Bwd2Reader(Bwd2Reader parentReader) : this(new FastBinaryReader(parentReader.Data, parentReader.Current.DataPosition, parentReader.Current.DataLength))
 {
     _isChildReader = true;
 }
예제 #6
0
        public static MissonDefinition ReadMsnMission(string filename)
        {
            MissonDefinition mdef = new MissonDefinition();

            using (Bwd2Reader msn = new Bwd2Reader(filename))
            {
                msn.FindNext("WDEF");
                using (Bwd2Reader wdef = new Bwd2Reader(msn))
                {
                    wdef.FindNext("WRLD");
                    wdef.Position               += 30;
                    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");
                List <float[, ]> heights = new List <float[, ]>();
                using (Bwd2Reader tdef = new Bwd2Reader(msn))
                {
                    tdef.FindNext("ZMAP");
                    byte   numUniqueTerrainPatches = tdef.ReadByte();
                    byte[] patchConfig             = tdef.ReadBytes(80 * 80);

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

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

                            heights.Add(h);
                        }
                    }

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

                    float[,] defaultHeights = new float[129, 129];
                    for (int z = 0; z < 80; z++)
                    {
                        for (int x = 0; x < 80; x++)
                        {
                            byte 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;
                                }

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

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

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

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

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

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

                            Vector3 pos            = roadSegment.Left;
                            int     patchPosX      = (int)(pos.x / 640.0f);
                            int     patchPosZ      = (int)(pos.z / 640.0f);
                            float   localPositionX = (pos.x % 640) / 640.0f;
                            float   localPositionZ = (pos.z % 640) / 640.0f;
                            float   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[i] = roadSegment;
                            //TODO: Figure out
                        }
                        mdef.Roads.Add(road);

                        rdef.Next();
                    }
                }

                msn.FindNext("ODEF");
                using (Bwd2Reader odef = new Bwd2Reader(msn))
                {
                    odef.FindNext("OBJ");
                    while (odef.Current.Name != "EXIT")
                    {
                        byte[]        rawlabel     = odef.ReadBytes(8);
                        int           labelhigh    = 0;
                        StringBuilder labelBuilder = new StringBuilder();
                        for (int i = 0; i < 8; i++)
                        {
                            byte 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);
                            }
                        }
                        string  label   = labelBuilder.ToString();
                        Vector3 right   = new Vector3(odef.ReadSingle(), odef.ReadSingle(), odef.ReadSingle());
                        Vector3 upwards = new Vector3(odef.ReadSingle(), odef.ReadSingle(), odef.ReadSingle());
                        Vector3 forward = new Vector3(odef.ReadSingle(), odef.ReadSingle(), odef.ReadSingle());
                        Vector3 pos     = new Vector3(odef.ReadSingle(), odef.ReadSingle(), odef.ReadSingle());

                        odef.Position += 36;
                        ClassId classId = (ClassId)odef.ReadUInt32();
                        ushort  flags   = odef.ReadUInt16();
                        ushort  teamId  = odef.ReadUInt16();

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

                        odef.Next();
                    }
                }

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

                        Vector3[] stringPositions = new Vector3[numStrings];
                        for (int i = 0; i < numStrings; i++)
                        {
                            Vector3 stringPos = new Vector3(ldef.ReadSingle(), ldef.ReadSingle(), ldef.ReadSingle());
                            stringPositions[i] = stringPos;
                        }

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

                        ldef.Next();
                    }
                }

                msn.FindNext("ADEF");
                using (Bwd2Reader adef = new Bwd2Reader(msn))
                {
                    adef.FindNext("FSM");
                    if (adef.Current != null && adef.Current.DataLength > 0)
                    {
                        mdef.FSM = new FSM();

                        mdef.FSM.ActionTable = new string[adef.ReadUInt32()];
                        for (int i = 0; i < mdef.FSM.ActionTable.Length; i++)
                        {
                            mdef.FSM.ActionTable[i] = adef.ReadCString(40);
                        }

                        uint numEntities = adef.ReadUInt32();
                        mdef.FSM.EntityTable = new FSMEntity[numEntities];

                        for (int i = 0; i < numEntities; i++)
                        {
                            string label    = adef.ReadCString(40);
                            byte[] rawlabel = adef.ReadBytes(8);

                            int           labelhigh    = 0;
                            StringBuilder labelBuilder = new StringBuilder();
                            for (int j = 0; j < 8; j++)
                            {
                                byte v = rawlabel[j];
                                if (v > 0x7f)
                                {
                                    labelhigh = (labelhigh << 1) | 0x01;
                                }
                                else
                                {
                                    labelhigh = (labelhigh << 1) & 0xfe;
                                }

                                v = (byte)(v & 0x7f);
                                if (v != 0)
                                {
                                    labelBuilder.Append((char)v);
                                }
                            }

                            mdef.FSM.EntityTable[i] = new FSMEntity
                            {
                                Label = label,
                                Value = labelBuilder.ToString(),
                                Id    = labelhigh
                            };
                        }

                        mdef.FSM.SoundClipTable = new string[adef.ReadUInt32()];
                        for (int i = 0; i < mdef.FSM.SoundClipTable.Length; i++)
                        {
                            mdef.FSM.SoundClipTable[i] = adef.ReadCString(40);
                        }

                        uint numPaths = adef.ReadUInt32();
                        mdef.FSM.Paths = new FSMPath[numPaths];
                        for (int i = 0; i < numPaths; i++)
                        {
                            string       name  = adef.ReadCString(40);
                            I76Vector3[] nodes = new I76Vector3[adef.ReadUInt32()];
                            for (int p = 0; p < nodes.Length; p++)
                            {
                                nodes[p] = new I76Vector3(adef.ReadSingle(), adef.ReadSingle(), adef.ReadSingle());
                            }

                            mdef.FSM.Paths[i] = new FSMPath
                            {
                                Name  = name,
                                Nodes = nodes
                            };
                        }

                        uint numMachines = adef.ReadUInt32();
                        mdef.FSM.StackMachines = new StackMachine[numMachines];
                        for (int i = 0; i < numMachines; i++)
                        {
                            long next = adef.Position + 168;

                            StackMachine machine = new StackMachine();
                            machine.StartAddress     = adef.ReadUInt32();
                            machine.InitialArguments = new int[adef.ReadUInt32()];

                            for (int j = 0; j < machine.InitialArguments.Length; j++)
                            {
                                machine.InitialArguments[j] = adef.ReadInt32();
                            }

                            adef.Position = next;

                            mdef.FSM.StackMachines[i] = machine;
                        }

                        mdef.FSM.Constants = new IntRef[adef.ReadUInt32()];
                        for (int i = 0; i < mdef.FSM.Constants.Length; i++)
                        {
                            mdef.FSM.Constants[i] = new IntRef(adef.ReadInt32());
                        }

                        mdef.FSM.ByteCode = new ByteCode[adef.ReadUInt32()];
                        for (int i = 0; i < mdef.FSM.ByteCode.Length; i++)
                        {
                            ByteCode byteCode = mdef.FSM.ByteCode[i] = new ByteCode();
                            byteCode.OpCode = (OpCode)adef.ReadUInt32();
                            byteCode.Value  = adef.ReadInt32();
                        }
                    }
                }
            }
            return(mdef);
        }
예제 #7
0
        public static Sdf LoadSdf(string filename, bool canWreck)
        {
            filename = filename.ToLower();
            if (SdfCache.ContainsKey(filename))
            {
                return(SdfCache[filename]);
            }

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

                br.FindNext("SDFC");
                sdf.Name = br.ReadCString(16);
                uint    one  = br.ReadUInt32();
                Vector3 size = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                uint    unk1 = br.ReadUInt32();
                uint    unk2 = br.ReadUInt32();
                sdf.Health = br.ReadUInt32();
                string xdfName   = br.ReadCString(13) + ".xdf";
                string soundName = br.ReadCString(13);
                if (!string.IsNullOrEmpty(soundName) && soundName.ToLower() != "null")
                {
                    sdf.DestroySoundName = soundName;
                }

                if (VirtualFilesystem.Instance.FileExists(xdfName))
                {
                    sdf.Xdf = XdfParser.ParseXdf(xdfName);
                }

                br.FindNext("SGEO");
                uint numParts = br.ReadUInt32();
                sdf.Parts = new SdfPart[numParts];
                for (int i = 0; i < numParts; i++)
                {
                    SdfPart 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.Position       += 56;

                    sdf.Parts[i] = sdfPart;
                }

                if (canWreck)
                {
                    SdfPart wreckedPart = GetDestroyedPart(br);
                    if (wreckedPart == null)
                    {
                        wreckedPart = GetDestroyedPart(br);
                    }

                    sdf.WreckedPart = wreckedPart;
                }

                SdfCache.Add(filename, sdf);
                return(sdf);
            }
        }
예제 #8
0
        public static Vcf ParseVcf(string filename)
        {
            Vcf vcf = new Vcf();

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

                vcf.Specials = new List <SpecialType>();
                if (br.TryFindNext("SPEC"))
                {
                    vcf.Specials.Add((SpecialType)br.ReadInt32());
                }
                if (br.TryFindNext("SPEC"))
                {
                    vcf.Specials.Add((SpecialType)br.ReadInt32());
                }
                if (br.TryFindNext("SPEC"))
                {
                    vcf.Specials.Add((SpecialType)br.ReadInt32());
                }

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

                    vcfWeapon.Gdf = GdfParser.ParseGdf(vcfWeapon.GdfFilename);

                    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);
        }
예제 #9
0
        public static Gdf ParseGdf(string filename)
        {
            using (Bwd2Reader br = new Bwd2Reader(filename))
            {
                Gdf gdf = new Gdf();

                br.FindNext("REV");
                int rev = br.ReadInt32();

                br.FindNext("GDFC");
                {
                    gdf.Name = br.ReadCString(16);
                    int   unk1 = br.ReadInt32();
                    int   unk2 = br.ReadInt32();
                    float unk3 = br.ReadSingle();
                    float unk4 = br.ReadSingle();
                    float unk5 = br.ReadSingle();
                    float unk6 = br.ReadSingle();
                    br.ReadBytes(4);
                    gdf.Damage     = br.ReadInt32();
                    gdf.Health     = br.ReadInt32();
                    gdf.WeaponMass = br.ReadSingle();
                    string unk7 = br.ReadCString(12);
                    ushort unk8 = br.ReadUInt16();
                    float  unk9 = br.ReadSingle();
                    gdf.BurstRate      = 1f / br.ReadSingle();
                    gdf.FiringRate     = 1f / br.ReadSingle();
                    gdf.FireAmount     = br.ReadInt32();
                    gdf.BulletVelocity = br.ReadSingle();
                    gdf.WeaponGroup    = br.ReadInt32();
                    gdf.AmmoCount      = br.ReadInt32();
                    float unk10 = br.ReadSingle();

                    gdf.FireSpriteName = br.ReadCString(13);
                    gdf.SoundName      = br.ReadCString(13);
                    if (rev == 8)
                    {
                        int unk11 = br.ReadInt32(); // Always 1?
                        gdf.EnabledSpriteName  = br.ReadCString(16);
                        gdf.DisabledSpriteName = br.ReadCString(16);
                    }
                }

                br.FindNext("GPOF"); // 192 bytes

                SdfPart[] parts = new SdfPart[4];
                for (int i = 0; i < 4; ++i)
                {
                    SdfPart part = new SdfPart();
                    part.Right    = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                    part.Up       = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                    part.Forward  = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                    part.Position = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
                    parts[i]      = part;
                }

                br.FindNext("GGEO"); // 4 bytes
                {
                    int numParts = br.ReadInt32();
                    if (numParts > 0)
                    {
                        int topPartsIndex    = 0;
                        int sidePartsIndex   = 0;
                        int turretPartsIndex = 0;
                        int insidePartsIndex = 0;

                        const int weaponSlots = 4;
                        int       totalSlots  = weaponSlots * numParts;
                        for (int i = 0; i < totalSlots; ++i)
                        {
                            string partName = br.ReadCString(8);
                            if (partName == "NULL")
                            {
                                br.Position += 92;
                            }
                            else
                            {
                                SdfPart sdfPart = new SdfPart
                                {
                                    Name       = partName,
                                    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()),
                                    ParentName = br.ReadCString(8)
                                };

                                char partType = partName[3];
                                switch (partType)
                                {
                                case 'P':
                                    if (gdf.TopParts == null)
                                    {
                                        gdf.TopParts = new SdfPart[numParts];
                                    }

                                    gdf.TopParts[topPartsIndex++] = sdfPart;
                                    break;

                                case 'S':
                                    if (gdf.SideParts == null)
                                    {
                                        gdf.SideParts = new SdfPart[numParts];
                                    }

                                    gdf.SideParts[sidePartsIndex++] = sdfPart;
                                    break;

                                case 'T':
                                    if (gdf.TurretParts == null)
                                    {
                                        gdf.TurretParts = new SdfPart[numParts];
                                    }

                                    gdf.TurretParts[turretPartsIndex++] = sdfPart;
                                    break;

                                case 'I':
                                    if (gdf.InsideParts == null)
                                    {
                                        gdf.InsideParts = new SdfPart[numParts];
                                    }

                                    gdf.InsideParts[insidePartsIndex++] = sdfPart;
                                    break;

                                default:
                                    Debug.LogWarningFormat("Unknown part type '{0}' for part name '{1}'.", partType, partName);
                                    break;
                                }

                                br.Position += 36;
                            }

                            // Skip Lower LOD levels - do we want to use these at all?
                            br.Position += 200;
                        }
                    }
                }

                br.FindNext("ORDF"); // 133 bytes


                br.FindNext("OGEO"); // 104 bytes

                br.ReadInt32();

                gdf.Projectile = new SdfPart
                {
                    Name       = br.ReadCString(8),
                    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()),
                    ParentName = br.ReadCString(8)
                };

                return(gdf);
            }
        }