Beispiel #1
0
        /// <summary>
        /// Loads a .wld File
        /// </summary>
        /// <param name="path">The path to the .wld file</param>
        /// <returns>A new WLD instance</returns>
        /// <exception cref="ArgumentException">Path given is not valid</exception>
        /// <exception cref="EndOfDataException">Unexpected end of Data</exception>
        /// <exception cref="FileNotFoundException">File could not be found</exception>
        /// <exception cref="InsufficientPermissionsException">Insufficient Permissions</exception>
        /// <exception cref="IOException">Read / Write Error</exception>
        public static WLD LoadFromFile(string path)
        {
            FileInfo fileInfo = new FileInfo(path);

            StreamReader reader      = null;
            string       fileContent = "";

            try {
                reader      = new StreamReader(path, Encoding.ASCII, false);
                fileContent = reader.ReadToEnd();
            } catch (ArgumentException ex) {
                Log.Add("Path given is not valid!", LogType.Error);
                throw new ArgumentException("Path given is not valid!", ex);
            } catch (NotSupportedException ex) {
                Log.Add("Path given is not valid!", LogType.Error);
                throw new ArgumentException("Path given is not valid!", ex);
            } catch (PathTooLongException ex) {
                Log.Add("Path given is not valid!", LogType.Error);
                throw new ArgumentException("Path given is not valid!", ex);
            } catch (UnauthorizedAccessException ex) {
                Log.Add("Insufficient Permissions!", LogType.Error);
                throw new InsufficientPermissionsException("Insufficient Permissions!", ex);
            } catch (SecurityException ex) {
                Log.Add("Insufficient Permissions!", LogType.Error);
                throw new InsufficientPermissionsException("Insufficient Permissions!", ex);
            }
            finally {
                if (reader != null)
                {
                    reader.Close();
                }
            }

            WLD wld = new WLD();


            Match m = Regex.Match(fileContent, @"LightName\([""]([A-Za-z0-9_-]+\.[A-Za-z]+)[""]\)");

            if (m.Success && m.Groups.Count >= 2)
            {
                wld.LightFile = m.Groups[1].Value;
            }

            m = Regex.Match(fileContent, @"TerrainName\([""]([A-Za-z0-9_-]+\.[A-Za-z]+)[""]\)");
            if (m.Success && m.Groups.Count >= 2)
            {
                string terrainPath = fileInfo.DirectoryName + "\\" + m.Groups[1].Value;

                if (File.Exists(terrainPath))
                {
                    wld.Terrain = TER.LoadFromFile(terrainPath);
                }
            }

            m = Regex.Match(fileContent, @"SkyName\([""]([A-Za-z0-9_-]+\.[A-Za-z]+)[""]\)");
            if (m.Success && m.Groups.Count >= 2)
            {
                wld.SkyFile = m.Groups[1].Value;
            }

            //Load [Base] Layer
            LYR Base = LYR.LoadFromString(fileContent);

            Base.Name = "[Base]";
            wld.Layers.Add(Base);

            string[] layerFiles = Directory.GetFiles(fileInfo.DirectoryName, "*.lyr", SearchOption.AllDirectories);

            //load all additional layers
            foreach (string file in layerFiles)
            {
                wld.Layers.Add(LYR.LoadFromFile(file));
            }

            return(wld);
        }
Beispiel #2
0
        /// <summary>
        /// Loads Terrain from File
        /// </summary>
        /// <param name="path">The path.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentException">Path given is not valid</exception>
        /// <exception cref="EndOfDataException">Unexpected end of Data</exception>
        /// <exception cref="FileNotFoundException">File could not be found</exception>
        /// <exception cref="InsufficientPermissionsException">Insufficient Permissions</exception>
        /// <exception cref="IOException">Read / Write Error</exception>
        public static TER LoadFromFile(string path)
        {
            ChunkStream stream = null;

            try {
                stream = new ChunkStream(path, FileMode.Open, FileAccess.Read);
            } catch (ArgumentException ex) {
                Log.Add("Path given is not valid!", LogType.Error);
                throw new ArgumentException("Path given is not valid!", ex);
            } catch (NotSupportedException ex) {
                Log.Add("Path given is not valid!", LogType.Error);
                throw new ArgumentException("Path given is not valid!", ex);
            } catch (PathTooLongException ex) {
                Log.Add("Path given is not valid!", LogType.Error);
                throw new ArgumentException("Path given is not valid!", ex);
            } catch (UnauthorizedAccessException ex) {
                Log.Add("Insufficient Permissions!", LogType.Error);
                throw new InsufficientPermissionsException("Insufficient Permissions!", ex);
            } catch (SecurityException ex) {
                Log.Add("Insufficient Permissions!", LogType.Error);
                throw new InsufficientPermissionsException("Insufficient Permissions!", ex);
            }

            TER terrain = new TER();

            if (!stream.ReadString(4).Equals("TERR"))
            {
                throw new InvalidChunkException("Not a valid Terrain File: " + path);
            }

            switch (stream.ReadInt32())
            {
            case 21:
                terrain.Version = TerrainVersion.SWBF1;
                break;

            case 22:
                terrain.Version = TerrainVersion.SWBF2;
                break;

            default:
                Log.Add("Unknown Terrain Version found!", LogType.Warning);
                terrain.Version = TerrainVersion.Unknown;
                break;
            }

            //Terrain Extent (From Position, To Position);
            terrain.Extent.FromX = stream.ReadInt16();
            terrain.Extent.FromY = stream.ReadInt16();
            terrain.Extent.ToX   = stream.ReadInt16();
            terrain.Extent.ToY   = stream.ReadInt16();

            //Int32, unknown purpose
            stream.SkipBytes(4);

            //16 floats follow, describing the Tile Range of each Texture Layer
            for (int i = 0; i < terrain.Layers.Length; i++)
            {
                //tile range is stored as reciprocal (1/X), e.g. 0.03125 for actually 32
                //to get the true tile size, we have ge the reciprocal again
                // (1 / 32) = 0.03125     (1 / 0.03125) = 32
                terrain.Layers[i].TileRange = 1 / stream.ReadFloat();
            }

            //16 bytes follow, describing mapping type for each layer
            for (int i = 0; i < terrain.Layers.Length; i++)
            {
                terrain.Layers[i].MappingType = stream.ReadByte();
            }

            //unknown purpose of bytes
            stream.SkipBytes(64);

            terrain.HeightMultiplier = stream.ReadFloat();
            terrain.GridScale        = stream.ReadFloat();

            //unknown int32
            stream.SkipBytes(4);

            //Full Map Size (e.g. 256 for a 256x256 Map)
            terrain.GridSize = stream.ReadInt32();

            //unknown int32
            stream.SkipBytes(4);

            //SWBF2 Versions have a byte exactly on this point. purpose unknown
            if (terrain.Version == TerrainVersion.SWBF2)
            {
                stream.SkipBytes(1);
            }

            //16 Texture Layers follow (total length of 1024)
            //char[32]	Diffuse texture name.
            //char[32]  Detail texture name.
            for (int i = 0; i < terrain.Layers.Length; i++)
            {
                terrain.Layers[i].DiffuseTexture = stream.ReadString(32).Trim();
                terrain.Layers[i].DetailTexture  = stream.ReadString(32).Trim();
            }

            //skip water layers
            stream.SkipBytes(1088);

            //unknown bytes
            stream.SkipBytes(524);

            //Terrain Height Data
            Log.Add("Size: " + terrain.GridSize, LogType.Info);

            terrain.RawHeights = new short[terrain.GridSize, terrain.GridSize];

            for (int x = 0; x < terrain.GridSize; x++)
            {
                for (int y = 0; y < terrain.GridSize; y++)
                {
                    terrain.RawHeights[x, y] = stream.ReadInt16();
                }
            }

            stream.Close();

            return(terrain);
        }