public async Task <BspFileLoadResult> Load(Stream stream, IEnvironment environment)
        {
            return(await Task.Factory.StartNew(() =>
            {
                var result = new BspFileLoadResult();

                var map = new Map();
                var so = _formatter.Deserialize(stream);
                foreach (var o in so)
                {
                    if (o.Name == nameof(Root))
                    {
                        map.Root.Unclone((Root)_factory.Deserialise(o));
                    }
                    else
                    {
                        map.Data.Add((IMapData)_factory.Deserialise(o));
                    }
                }
                map.Root.DescendantsChanged();

                result.Map = map;
                return result;
            }));
        }
Exemple #2
0
        private Solid ReadSolid(StreamReader rdr, UniqueNumberGenerator generator, BspFileLoadResult result)
        {
            var    faces = new List <Face>();
            string line;

            while ((line = CleanLine(rdr.ReadLine())) != null)
            {
                if (String.IsNullOrWhiteSpace(line))
                {
                    continue;
                }
                if (line == "}")
                {
                    if (!faces.Any())
                    {
                        return(null);
                    }

                    var poly = new Polyhedron(faces.Select(x => x.Plane));
                    var ret  = new Solid(generator.Next("MapObject"));
                    ret.Data.Add(new ObjectColor(Colour.GetRandomBrushColour()));

                    foreach (var face in faces)
                    {
                        var pg = poly.Polygons.FirstOrDefault(x => x.Plane.Normal.EquivalentTo(face.Plane.Normal, 0.0075f)); // Magic number that seems to match VHE
                        if (pg == null)
                        {
                            result.InvalidObjects.Add(poly);
                            return(null);
                        }
                        face.Vertices.AddRange(pg.Vertices);
                    }
                    ret.Data.AddRange(faces);
                    ret.DescendantsChanged();
                    return(ret);
                }
                else if (line == "patchDef2")
                {
                    // Quake 3 has bezier faces
                    // TODO: support bezier faces...
                    while (CleanLine(rdr.ReadLine()) != "}")
                    {
                        // Skip...
                    }
                }
                else if (line == "brushDef")
                {
                    throw new Exception("Maps containing the 'brushDef' structure are not currently supported");
                }
                else
                {
                    faces.Add(ReadFace(line, generator));
                }
            }
            return(null);
        }
Exemple #3
0
        public async Task <BspFileLoadResult> Load(Stream stream, IEnvironment environment)
        {
            var task = await Task.Factory.StartNew(async() =>
            {
                var result = new BspFileLoadResult();

                var map = new Map();
                var so  = _formatter.Deserialize(stream).ToList();

                foreach (var s in so)
                {
                    s.Name = s.Name?.ToLower();
                }

                // If the sledge_native node is found, we should use it to maximise compatibility
                var native = so.FirstOrDefault(x => x.Name == "sledge_native");
                if (native != null)
                {
                    foreach (var o in native.Children)
                    {
                        if (o.Name == nameof(Root))
                        {
                            map.Root.Unclone((Root)_factory.Deserialise(o));
                        }
                        else
                        {
                            map.Data.Add((IMapData)_factory.Deserialise(o));
                        }
                    }
                }
                else
                {
                    // Load a VHE4 VMF format
                    LoadVisgroups(map, so.FirstOrDefault(x => x.Name == "visgroups"));
                    LoadWorld(map, so);
                    LoadCameras(map, so.FirstOrDefault(x => x.Name == "cameras"));
                    LoadCordon(map, so.FirstOrDefault(x => x.Name == "cordon"));
                    await LoadViewSettings(map, so.FirstOrDefault(x => x.Name == "viewsettings"), environment);

                    await Task.FromResult(0);
                }

                map.Root.DescendantsChanged();

                result.Map = map;
                return(result);
            });

            return(await task);
        }
        public Task <BspFileLoadResult> Load(Stream stream, IEnvironment environment)
        {
            return(Task.Run(() =>
            {
                using (var reader = new StreamReader(stream, Encoding.ASCII, true, 1024, false))
                {
                    var result = new BspFileLoadResult();

                    var map = new Map();

                    Read(map, reader);

                    result.Map = map;
                    return result;
                }
            }));
        }
Exemple #5
0
        public async Task <BspFileLoadResult> Load(Stream stream, IEnvironment environment)
        {
            return(await Task.Factory.StartNew(() =>
            {
                using (var br = new BinaryReader(stream, Encoding.ASCII, true))
                {
                    var result = new BspFileLoadResult();

                    // Only RMF version 2.2 is supported for the moment.
                    var version = Math.Round(br.ReadSingle(), 1);
                    if (Math.Abs(version - 2.2) > 0.01)
                    {
                        throw new NotSupportedException("Incorrect RMF version number. Expected 2.2, got " + version + ".");
                    }

                    // RMF header test
                    var header = br.ReadFixedLengthString(Encoding.ASCII, 3);
                    if (header != "RMF")
                    {
                        throw new NotSupportedException("Incorrect RMF header. Expected 'RMF', got '" + header + "'.");
                    }

                    var map = new Map();

                    ReadVisgroups(map, br);
                    ReadWorldspawn(map, br);

                    // Some RMF files might not have the DOCINFO block so we check if we're at the end of the stream
                    if (stream.Position < stream.Length)
                    {
                        // DOCINFO string check
                        var docinfo = br.ReadFixedLengthString(Encoding.ASCII, 8);
                        if (docinfo != "DOCINFO")
                        {
                            throw new NotSupportedException("Incorrect RMF format. Expected 'DOCINFO', got '" + docinfo + "'.");
                        }

                        ReadCameras(map, br);
                    }

                    result.Map = map;
                    return result;
                }
            }));
        }
Exemple #6
0
        public async Task <BspFileLoadResult> Load(Stream stream, IEnvironment environment)
        {
            return(await Task.Factory.StartNew(() =>
            {
                using (var reader = new StreamReader(stream, Encoding.ASCII, true, 1024, false))
                {
                    var result = new BspFileLoadResult();

                    var map = new Map();
                    var entities = ReadAllEntities(reader, map.NumberGenerator, result);

                    var worldspawn = entities.FirstOrDefault(x => x.EntityData?.Name == "worldspawn")
                                     ?? new Entity(0)
                    {
                        Data = { new EntityData {
                                     Name = "worldspawn"
                                 } }
                    };
                    entities.Remove(worldspawn);

                    map.Root.Data.Replace(worldspawn.EntityData);
                    foreach (var ch in worldspawn.Hierarchy.ToList())
                    {
                        ch.Hierarchy.Parent = map.Root;
                    }

                    foreach (var entity in entities)
                    {
                        entity.Hierarchy.Parent = map.Root;
                    }

                    foreach (var obj in worldspawn.Hierarchy.ToList())
                    {
                        obj.Hierarchy.Parent = map.Root;
                    }

                    map.Root.DescendantsChanged();

                    result.Map = map;
                    return result;
                }
            }));
        }
Exemple #7
0
        private Entity ReadEntity(StreamReader rdr, UniqueNumberGenerator generator, BspFileLoadResult result)
        {
            var ent = new Entity(generator.Next("Face"))
            {
                Data =
                {
                    new EntityData(),
                    new ObjectColor(Colour.GetRandomBrushColour())
                }
            };
            string line;

            while ((line = CleanLine(rdr.ReadLine())) != null)
            {
                if (String.IsNullOrWhiteSpace(line))
                {
                    continue;
                }
                if (line[0] == '"')
                {
                    ReadProperty(ent, line);
                }
                else if (line[0] == '{')
                {
                    var s = ReadSolid(rdr, generator, result);
                    if (s != null)
                    {
                        s.Hierarchy.Parent = ent;
                    }
                }
                else if (line[0] == '}')
                {
                    break;
                }
            }
            ent.DescendantsChanged();
            return(ent);
        }
Exemple #8
0
        private List <Entity> ReadAllEntities(StreamReader rdr, UniqueNumberGenerator generator, BspFileLoadResult result)
        {
            var    list = new List <Entity>();
            string line;

            while ((line = CleanLine(rdr.ReadLine())) != null)
            {
                if (String.IsNullOrWhiteSpace(line))
                {
                    continue;
                }
                if (line == "{")
                {
                    list.Add(ReadEntity(rdr, generator, result));
                }
            }
            return(list);
        }