Пример #1
0
        private Tag LoadTag(string path)
        {
            int index = LocateTagByID(inverseDictionary[path]);
            Tag tag   = new Tag(tags[index].Type);
            Bsp bsp   = null;

            string[] stringArray = strings.ToArray();

            switch (tags[index].Type)
            {
            case StructureBsp:
                bsp          = GetBsp(tags[index].Identifier);
                map.Position = bsp.BspOffset;
                tag.ReadData(reader, shared, bsp.Magic - bsp.BspHeaderOffset, dictionary, stringArray, coconuts, globals, path);
                break;

            case StructureLightmap:
                bsp          = GetBsp(tags[index].Identifier);
                map.Position = bsp.LightmapOffset;
                tag.ReadData(reader, shared, bsp.Magic - bsp.BspHeaderOffset, dictionary, stringArray, coconuts, globals, path);
                break;

            default:
                map.Position = unchecked (tags[index].Offset - magic);
                tag.ReadData(reader, shared, magic, dictionary, stringArray, coconuts, globals, path);
                break;
            }

            return(tag);
        }
Пример #2
0
        /// <summary>
        ///     Returns true if Order instances are equal
        /// </summary>
        /// <param name="other">Instance of Order to be compared</param>
        /// <returns>Boolean</returns>
        public bool Equals(Order other)
        {
            // credit: http://stackoverflow.com/a/10454552/677735
            if (other == null)
            {
                return(false);
            }

            return((Side == other.Side || Side != null && Side.Equals(other.Side)) &&
                   (Sv == other.Sv || Sv != null && Sv.Equals(other.Sv)) &&
                   (Pt == other.Pt || Pt != null && Pt.Equals(other.Pt)) &&
                   (Ot == other.Ot || Ot != null && Ot.Equals(other.Ot)) &&
                   (P == other.P || P != null && P.Equals(other.P)) &&
                   (Sc == other.Sc || Sc != null && Sc.Equals(other.Sc)) &&
                   (Rc == other.Rc || Rc != null && Rc.Equals(other.Rc)) &&
                   (S == other.S || S != null && S.Equals(other.S)) &&
                   (Pd == other.Pd || Pd != null && Pd.Equals(other.Pd)) &&
                   (Rac == other.Rac || Rac != null && Rac.Equals(other.Rac)) &&
                   (Md == other.Md || Md != null && Md.Equals(other.Md)) &&
                   (Sl == other.Sl || Sl != null && Sl.Equals(other.Sl)) &&
                   (Avp == other.Avp || Avp != null && Avp.Equals(other.Avp)) &&
                   (Sm == other.Sm || Sm != null && Sm.Equals(other.Sm)) &&
                   (Id == other.Id || Id != null && Id.Equals(other.Id)) &&
                   (Bsp == other.Bsp || Bsp != null && Bsp.Equals(other.Bsp)) &&
                   (Status == other.Status || Status != null && Status.Equals(other.Status)) &&
                   (Sr == other.Sr || Sr != null && Sr.Equals(other.Sr)) &&
                   (Cd == other.Cd || Cd != null && Cd.Equals(other.Cd)));
        }
Пример #3
0
        /// <summary>
        /// Factory method to parse a <c>byte</c> array into a <see cref="GameLump"/> object.
        /// </summary>
        /// <param name="data">The data to parse.</param>
        /// <param name="bsp">The <see cref="BSP.Bsp"/> this lump came from.</param>
        /// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
        /// <returns>A <see cref="GameLump"/> object.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="data"/> parameter was <c>null</c>.</exception>
        public static GameLump LumpFactory(byte[] data, Bsp bsp, LumpInfo lumpInfo)
        {
            if (data == null)
            {
                throw new ArgumentNullException();
            }

            return(new GameLump(data, bsp, lumpInfo));
        }
Пример #4
0
        /// <summary>
        /// Parses the passed <c>byte</c> array into a <see cref="StaticProps"/> object.
        /// </summary>
        /// <param name="data">Array of <c>byte</c>s to parse.</param>
        /// <param name="structLength">Number of <c>byte</c>s to copy into the children. Will be recalculated based on BSP format.</param>
        /// <param name="bsp">The <see cref="Bsp"/> this lump came from.</param>
        /// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
        /// <exception cref="ArgumentNullException"><paramref name="data"/> or <paramref name="bsp"/> was <c>null</c>.</exception>
        public StaticProps(byte[] data, int structLength, Bsp bsp, LumpInfo lumpInfo = default) : base(bsp, lumpInfo)
        {
            if (data == null || bsp == null)
            {
                throw new ArgumentNullException();
            }

            if (data.Length > 0)
            {
                int offset = 0;
                ModelDictionary = new string[BitConverter.ToInt32(data, 0)];
                offset         += 4;
                for (int i = 0; i < ModelDictionary.Length; ++i)
                {
                    ModelDictionary[i] = data.ToNullTerminatedString(offset, 128);
                    offset            += 128;
                }
                LeafIndices = new short[BitConverter.ToInt32(data, offset)];
                offset     += 4;
                for (int i = 0; i < LeafIndices.Length; ++i)
                {
                    LeafIndices[i] = BitConverter.ToInt16(data, offset);
                    offset        += 2;
                }
                if (Bsp.Version == MapType.Vindictus && lumpInfo.version == 6)
                {
                    int numPropScales = BitConverter.ToInt32(data, offset);
                    offset += 4 + (numPropScales * 16);
                }
                int numProps = BitConverter.ToInt32(data, offset);
                if (lumpInfo.version == 12)                   // So far only Titanfall
                {
                    offset += 12;
                }
                else
                {
                    offset += 4;
                }
                if (numProps > 0)
                {
                    structLength = (data.Length - offset) / numProps;
                    for (int i = 0; i < numProps; ++i)
                    {
                        byte[] bytes = new byte[structLength];
                        Array.Copy(data, offset, bytes, 0, structLength);
                        Add(new StaticProp(bytes, this));
                        offset += structLength;
                    }
                }
            }
            else
            {
                ModelDictionary = new string[0];
            }
        }
Пример #5
0
 /// <summary>
 /// Creates a new <see cref="NumList"/> object from a <c>byte</c> array.
 /// </summary>
 /// <param name="data"><c>byte</c> array to parse.</param>
 /// <param name="type">The type of number to store.</param>
 /// <exception cref="ArgumentNullException"><paramref name="data"/> was <c>null</c>.</exception>
 public NumList(byte[] data, DataType type, Bsp bsp = null, LumpInfo lumpInfo = default)
 {
     if (data == null)
     {
         throw new ArgumentNullException();
     }
     Bsp       = bsp;
     LumpInfo  = lumpInfo;
     this.data = data;
     Type      = type;
 }
Пример #6
0
        // TODO: Also create a wadmaker.config file, if the wad contained fonts or simple images (mipmap textures are the default behavior, so those don't need a config,
        //       unless the user wants to create a wad file and wants different settings for those images such as different dithering, etc.)
        static void ExtractTextures(string inputFilePath, string outputDirectory, bool extractMipmaps, bool overwriteExistingFiles)
        {
            var stopwatch = Stopwatch.StartNew();

            var imageFilesCreated = 0;

            var textures = new List <Texture>();

            if (inputFilePath.EndsWith(".bsp"))
            {
                textures = Bsp.GetEmbeddedTextures(inputFilePath);
            }
            else
            {
                textures = Wad.Load(inputFilePath).Textures;
            }

            CreateDirectory(outputDirectory);

            var isDecalsWad = Path.GetFileName(inputFilePath).ToLowerInvariant() == "decals.wad";

            foreach (var texture in textures)
            {
                var maxMipmap = extractMipmaps ? 4 : 1;
                for (int mipmap = 0; mipmap < maxMipmap; mipmap++)
                {
                    try
                    {
                        var filePath = Path.Combine(outputDirectory, texture.Name + $"{(mipmap > 0 ? ".mipmap" + mipmap : "")}.png");
                        if (!overwriteExistingFiles && File.Exists(filePath))
                        {
                            Log($"WARNING: {filePath} already exist. Skipping texture.");
                            continue;
                        }

                        using (var image = isDecalsWad ? DecalTextureToImage(texture, mipmap) : TextureToImage(texture, mipmap))
                        {
                            image.SaveAsPng(filePath);
                            imageFilesCreated += 1;
                        }
                    }
                    catch (Exception ex)
                    {
                        Log($"ERROR: failed to extract '{texture.Name}'{(mipmap > 0 ? $" (mipmap {mipmap})" : "")}: {ex.GetType().Name}: '{ex.Message}'.");
                    }
                }
            }

            Log($"Extracted {imageFilesCreated} images from {textures.Count} textures from {inputFilePath} to {outputDirectory}, in {stopwatch.Elapsed.TotalSeconds:0.000} seconds.");
        }
Пример #7
0
        static void RemoveEmbeddedTextures(string bspFilePath, string outputFilePath)
        {
            var stopwatch = Stopwatch.StartNew();

            if (!bspFilePath.EndsWith(".bsp"))
            {
                throw new ArgumentException("Removing embedded textures requires a .bsp file.");
            }

            Log($"Removing embedded textures from '{bspFilePath}' and saving the result to '{outputFilePath}'.");

            var removedTextureCount = Bsp.RemoveEmbeddedTextures(bspFilePath, outputFilePath);

            Log($"Removed {removedTextureCount} embedded textures from {bspFilePath} in {stopwatch.Elapsed.TotalSeconds:0.000} seconds.");
        }
Пример #8
0
        /// <summary>
        ///     Returns true if RunnerDefinition instances are equal
        /// </summary>
        /// <param name="other">Instance of RunnerDefinition to be compared</param>
        /// <returns>Boolean</returns>
        public bool Equals(RunnerDefinition other)
        {
            // credit: http://stackoverflow.com/a/10454552/677735
            if (other == null)
            {
                return(false);
            }

            return((SortPriority == other.SortPriority || SortPriority != null && SortPriority.Equals(other.SortPriority)) &&
                   (RemovalDate == other.RemovalDate || RemovalDate != null && RemovalDate.Equals(other.RemovalDate)) &&
                   (Id == other.Id || Id != null && Id.Equals(other.Id)) &&
                   (Hc == other.Hc || Hc != null && Hc.Equals(other.Hc)) &&
                   (AdjustmentFactor == other.AdjustmentFactor || AdjustmentFactor != null && AdjustmentFactor.Equals(other.AdjustmentFactor)) &&
                   (Bsp == other.Bsp || Bsp != null && Bsp.Equals(other.Bsp)) &&
                   (Status == other.Status || Status != null && Status.Equals(other.Status)));
        }
Пример #9
0
    public override void OnInspectorGUI()
    {
        Bsp myTarget = (Bsp)target;

        if (GUILayout.Button("Generate"))
        {
            myTarget.Generate();
        }

        if (GUILayout.Button("Clear"))
        {
            myTarget.Clear();
        }

        DrawDefaultInspector();
    }
Пример #10
0
        /// <summary>
        ///     Gets the hash code
        /// </summary>
        /// <returns>Hash code</returns>
        public override int GetHashCode()
        {
            // credit: http://stackoverflow.com/a/263416/677735
            unchecked // Overflow is fine, just wrap
            {
                var hash = 41;
                // Suitable nullity checks etc, of course :)

                if (SortPriority != null)
                {
                    hash = hash * 59 + SortPriority.GetHashCode();
                }

                if (RemovalDate != null)
                {
                    hash = hash * 59 + RemovalDate.GetHashCode();
                }

                if (Id != null)
                {
                    hash = hash * 59 + Id.GetHashCode();
                }

                if (Hc != null)
                {
                    hash = hash * 59 + Hc.GetHashCode();
                }

                if (AdjustmentFactor != null)
                {
                    hash = hash * 59 + AdjustmentFactor.GetHashCode();
                }

                if (Bsp != null)
                {
                    hash = hash * 59 + Bsp.GetHashCode();
                }

                if (Status != null)
                {
                    hash = hash * 59 + Status.GetHashCode();
                }

                return(hash);
            }
        }
Пример #11
0
        /// <summary>
        /// Factory method to parse a <c>byte</c> array into a <see cref="Lump{Vertex}"/>.
        /// </summary>
        /// <param name="data">The data to parse.</param>
        /// <param name="bsp">The <see cref="Bsp"/> this lump came from.</param>
        /// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
        /// <returns>A <see cref="Lump{Vertex}"/>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="data"/> was <c>null</c>.</exception>
        /// <remarks>This function goes here since it can't be in Unity's <c>UIVertex</c> class, and so I can't
        /// depend on having a constructor taking a byte array.</remarks>
        public static Lump <Vertex> LumpFactory(byte[] data, Bsp bsp, LumpInfo lumpInfo)
        {
            if (data == null)
            {
                throw new ArgumentNullException();
            }
            int           structLength = GetStructLength(bsp.Version, lumpInfo.version);
            int           numObjects   = data.Length / structLength;
            Lump <Vertex> lump         = new Lump <Vertex>(numObjects, bsp, lumpInfo);

            byte[] bytes = new byte[structLength];
            for (int i = 0; i < numObjects; ++i)
            {
                Array.Copy(data, i * structLength, bytes, 0, structLength);
                lump.Add(CreateVertex(bytes, bsp.Version, lumpInfo.version));
            }
            return(lump);
        }
Пример #12
0
        /// <summary>
        /// Factory method to parse a <c>byte</c> array into a <see cref="Lump{Plane}"/>.
        /// </summary>
        /// <param name="data">The data to parse.</param>
        /// <param name="bsp">The <see cref="Bsp"/> this lump came from.</param>
        /// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
        /// <returns>A <see cref="Lump{Plane}"/>.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="data" /> was null.</exception>
        /// <remarks>This function goes here since it can't go into Unity's Plane class, and so can't depend
        /// on having a constructor taking a byte array.</remarks>
        public static Lump <Plane> LumpFactory(byte[] data, Bsp bsp, LumpInfo lumpInfo)
        {
            if (data == null)
            {
                throw new ArgumentNullException();
            }
            int          structLength = GetStructLength(bsp.Version, lumpInfo.version);
            int          numObjects   = data.Length / structLength;
            Lump <Plane> lump         = new Lump <Plane>(numObjects, bsp, lumpInfo);

            for (int i = 0; i < numObjects; ++i)
            {
                Vector3 normal   = new Vector3(BitConverter.ToSingle(data, structLength * i), BitConverter.ToSingle(data, (structLength * i) + 4), BitConverter.ToSingle(data, (structLength * i) + 8));
                float   distance = BitConverter.ToSingle(data, (structLength * i) + 12);
                lump.Add(new Plane(normal, distance));
            }
            return(lump);
        }
Пример #13
0
        /// <summary>
        /// Parses the passed <c>byte</c> array into a <c>Lump</c> of <typeparamref name="T"/> objects.
        /// </summary>
        /// <param name="data">Array of <c>byte</c>s to parse.</param>
        /// <param name="structLength">Number of <c>byte</c>s to copy into the elements. Negative values indicate a variable length, which is not supported by this constructor.</param>
        /// <param name="bsp">The <see cref="BSP.Bsp"/> which <paramref name="data"/> came from.</param>
        /// <param name="lumpInfo">The <see cref="LumpInfo"/> object for this <c>Lump</c>.</param>
        /// <exception cref="ArgumentNullException"><paramref name="data" /> was <c>null</c>.</exception>
        /// <exception cref="NotSupportedException"><paramref name="structLength"/> is negative.</exception>
        public Lump(byte[] data, int structLength, Bsp bsp = null, LumpInfo lumpInfo = default) : base(data.Length / structLength)
        {
            if (data == null)
            {
                throw new ArgumentNullException();
            }
            if (structLength <= 0)
            {
                throw new NotSupportedException("Cannot use the base Lump constructor for variable length lumps (structLength was negative). Create a derived class with a new constructor instead.");
            }

            Bsp      = bsp;
            LumpInfo = lumpInfo;
            for (int i = 0; i < data.Length / structLength; ++i)
            {
                byte[] bytes = new byte[structLength];
                Array.Copy(data, (i * structLength), bytes, 0, structLength);
                Add((T)Activator.CreateInstance(typeof(T), bytes, this));
            }
        }
Пример #14
0
 public override string ToString()
 {
     return(EventId.ToString()
            + "," + MarketId.ToString()
            + "," + (MeetingDate > DateTime.MinValue ? MeetingDate.ToString("yyyy-MM-dd") : @"\N")
            + "," + DayOfWeek.ToString()
            + "," + CountryCode.ToString()
            + "," + Track.ToString()
            + "," + (RaceTime > DateTime.MinValue ? RaceTime.ToString("yyyy-MM-dd HH:mm:ss") : @"\N")
            + "," + (OffTime > DateTime.MinValue ? OffTime.ToString("yyyy-MM-dd HH:mm:ss") : @"\N")
            + "," + MarketName.ToString()
            + "," + Entries.ToString()
            + "," + Runners.ToString()
            + "," + SelectionId.ToString()
            + "," + SelectionName.ToString()
            + "," + (Bsp > 1 ? Bsp.ToString() : @"\N")
            + "," + (NonRunner ? "1" : "0")
            + "," + (RemovalTime > DateTime.MinValue ? RemovalTime.ToString("yyyy-MM-dd HH:mm:ss") : @"\N")
            + "," + (NonRunner ? ReductionFactor.ToString() : @"\N")
            );
 }
Пример #15
0
        private void LoadTextures(SceneContext sc, Bitmap lightmap)
        {
            var textures = new List <Veldrid.Texture>();

            var inBsp = _texture.NumMips > 0;
            var tex   = _texture.NumMips > 0 ? _texture : Environment.Wads.Get(_texture.Name);

            _currentTextureIndex = 0;
            if (tex != null)
            {
                // Try and load animated textures
                if (tex.Value.Name.Length > 2 && tex.Value.Name[0] == '+')
                {
                    // Animated textures can be 0-9 or A-J
                    var c = tex.Value.Name[1] >= '0' && tex.Value.Name[1] <= '9' ? '0'
                             : tex.Value.Name[1] >= 'A' && tex.Value.Name[1] <= 'J' ? 'A'
                             : '\0';
                    if (c == '\0')
                    {
                        // + texture doesn't follow proper naming standards
                        textures.Add(sc.ResourceCache.GetTexture2D(tex.Value));
                    }
                    else
                    {
                        // Animated texture, load all the variants
                        var name = tex.Value.Name.Substring(2);
                        for (var i = c; i < c + 10; i++)
                        {
                            var frame = "+" + i + name;
                            if (string.Equals(frame, _texture.Name, StringComparison.InvariantCultureIgnoreCase))
                            {
                                _currentTextureIndex = i - c;
                            }
                            tex = inBsp ? Bsp.GetTexture(frame) : Environment.Wads.Get(frame);
                            if (tex.HasValue)
                            {
                                textures.Add(sc.ResourceCache.GetTexture2D(tex.Value));
                            }
                        }
                    }
                }
                else
                {
                    textures.Add(sc.ResourceCache.GetTexture2D(tex.Value));
                }
            }
            else
            {
                textures.Add(sc.ResourceCache.GetPinkTexture());
            }

            var lightmapTexture     = sc.ResourceCache.GetTexture2D(lightmap);
            var lightmapTextureView = sc.ResourceCache.GetTextureView(lightmapTexture);

            if (!textures.Any())
            {
                textures.Add(sc.ResourceCache.GetPinkTexture());
            }

            foreach (var t in textures)
            {
                var tv = sc.ResourceCache.GetTextureView(t);
                _textureResources.Add(sc.ResourceCache.GetTextureResourceSet(tv, lightmapTextureView));
            }
        }
Пример #16
0
 /// <summary>
 /// Creates an empty <c>Lump</c> of <typeparamref name="T"/> objects with the specified initial capactiy.
 /// </summary>
 /// <param name="capacity">The number of elements that can initially be stored.</param>
 /// <param name="bsp">The <see cref="BSP"/> which <paramref name="data"/> came from.</param>
 /// <param name="lumpInfo">The <see cref="LumpInfo"/> object for this <c>Lump</c>.</param>
 public Lump(int capacity, Bsp bsp = null, LumpInfo lumpInfo = default) : base(capacity)
 {
     Bsp      = bsp;
     LumpInfo = lumpInfo;
 }
Пример #17
0
 /// <summary>
 /// Creates a new <c>Lump</c> that contains elements copied from the passed <see cref="IEnumerable{T}"/>.
 /// </summary>
 /// <param name="items">The elements to copy into this <c>Lump</c>.</param>
 /// <param name="bsp">The <see cref="BSP"/> which <paramref name="data"/> came from.</param>
 /// <param name="lumpInfo">The <see cref="LumpInfo"/> object for this <c>Lump</c>.</param>
 public Lump(IEnumerable <T> items, Bsp bsp = null, LumpInfo lumpInfo = default) : base(items)
 {
     Bsp      = bsp;
     LumpInfo = lumpInfo;
 }
Пример #18
0
 /// <summary>
 /// Creates an empty <c>Lump</c> of <typeparamref name="T"/> objects.
 /// </summary>
 /// <param name="bsp">The <see cref="BSP"/> which <paramref name="data"/> came from.</param>
 /// <param name="lumpInfo">The <see cref="LumpInfo"/> object for this <c>Lump</c>.</param>
 public Lump(Bsp bsp = null, LumpInfo lumpInfo = default)
 {
     Bsp      = bsp;
     LumpInfo = lumpInfo;
 }
Пример #19
0
 /// <summary>
 /// Creates an empty <see cref="Textures"/> object with the specified initial capactiy.
 /// </summary>
 /// <param name="capacity">The number of elements that can initially be stored.</param>
 /// <param name="bsp">The <see cref="Bsp"/> this lump came from.</param>
 /// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
 public Textures(int capacity, Bsp bsp = null, LumpInfo lumpInfo = default) : base(capacity, bsp, lumpInfo)
 {
 }
Пример #20
0
        /// <summary>
        ///     Gets the hash code
        /// </summary>
        /// <returns>Hash code</returns>
        public override int GetHashCode()
        {
            // credit: http://stackoverflow.com/a/263416/677735
            unchecked // Overflow is fine, just wrap
            {
                var hash = 41;
                // Suitable nullity checks etc, of course :)

                if (Side != null)
                {
                    hash = hash * 59 + Side.GetHashCode();
                }

                if (Sv != null)
                {
                    hash = hash * 59 + Sv.GetHashCode();
                }

                if (Pt != null)
                {
                    hash = hash * 59 + Pt.GetHashCode();
                }

                if (Ot != null)
                {
                    hash = hash * 59 + Ot.GetHashCode();
                }

                if (P != null)
                {
                    hash = hash * 59 + P.GetHashCode();
                }

                if (Sc != null)
                {
                    hash = hash * 59 + Sc.GetHashCode();
                }

                if (Rc != null)
                {
                    hash = hash * 59 + Rc.GetHashCode();
                }

                if (S != null)
                {
                    hash = hash * 59 + S.GetHashCode();
                }

                if (Pd != null)
                {
                    hash = hash * 59 + Pd.GetHashCode();
                }

                if (Rac != null)
                {
                    hash = hash * 59 + Rac.GetHashCode();
                }

                if (Md != null)
                {
                    hash = hash * 59 + Md.GetHashCode();
                }

                if (Sl != null)
                {
                    hash = hash * 59 + Sl.GetHashCode();
                }

                if (Avp != null)
                {
                    hash = hash * 59 + Avp.GetHashCode();
                }

                if (Sm != null)
                {
                    hash = hash * 59 + Sm.GetHashCode();
                }

                if (Id != null)
                {
                    hash = hash * 59 + Id.GetHashCode();
                }

                if (Bsp != null)
                {
                    hash = hash * 59 + Bsp.GetHashCode();
                }

                if (Status != null)
                {
                    hash = hash * 59 + Status.GetHashCode();
                }

                if (Sr != null)
                {
                    hash = hash * 59 + Sr.GetHashCode();
                }

                if (Cd != null)
                {
                    hash = hash * 59 + Cd.GetHashCode();
                }

                return(hash);
            }
        }
Пример #21
0
 /// <summary>
 /// Initializes a new <see cref="Entities"/> object.
 /// </summary>
 /// <param name="bsp">The <see cref="Bsp"/> this lump came from.</param>
 /// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
 public Entities(Bsp bsp = null, LumpInfo lumpInfo = default) : base(bsp, lumpInfo)
 {
 }
Пример #22
0
 /// <summary>
 /// Initializes a new instance of an <see cref="Entities"/> object with a specified initial capacity.
 /// </summary>
 /// <param name="initialCapacity">Initial capacity of the <c>List</c> of <see cref="Entity"/> objects.</param>
 /// <param name="bsp">The <see cref="Bsp"/> this lump came from.</param>
 /// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
 public Entities(int initialCapacity, Bsp bsp = null, LumpInfo lumpInfo = default) : base(initialCapacity, bsp, lumpInfo)
 {
 }
Пример #23
0
 /// <summary>
 /// Initializes a new instance of an <see cref="Entities"/> object copying a passed <c>IEnumerable</c> of <see cref="Entity"/> objects.
 /// </summary>
 /// <param name="data">Collection of <see cref="Entity"/> objects to copy.</param>
 /// <param name="bsp">The <see cref="BSP"/> this lump came from.</param>
 /// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
 public Entities(IEnumerable <Entity> entities, Bsp bsp = null, LumpInfo lumpInfo = default) : base(entities, bsp, lumpInfo)
 {
 }
Пример #24
0
 /// <summary>
 /// Creates a new <see cref="NumList"/> object from a <c>byte</c> array and returns it.
 /// </summary>
 /// <param name="data"><c>byte</c> array to parse.</param>
 /// <param name="type">The type of number to store.</param>
 /// <returns>The resulting <see cref="NumList"/>.</returns>
 public static NumList LumpFactory(byte[] data, DataType type, Bsp bsp = null, LumpInfo lumpInfo = default)
 {
     return(new NumList(data, type, bsp, lumpInfo));
 }
Пример #25
0
        /// <summary>
        /// Parses the passed <c>byte</c> array into a <see cref="Textures"/> object.
        /// </summary>
        /// <param name="data">Array of <c>byte</c>s to parse.</param>
        /// <param name="structLength">Number of <c>byte</c>s to copy into the children. Will be recalculated based on BSP format.</param>
        /// <param name="bsp">The <see cref="Bsp"/> this lump came from.</param>
        /// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
        /// <exception cref="ArgumentNullException"><paramref name="data"/> or <paramref name="bsp"/> was <c>null</c>.</exception>
        public Textures(byte[] data, int structLength, Bsp bsp, LumpInfo lumpInfo = default) : base(bsp, lumpInfo)
        {
            if (data == null || bsp == null)
            {
                throw new ArgumentNullException();
            }

            switch (bsp.Version)
            {
            case MapType.Nightfire: {
                structLength = 64;
                break;
            }

            case MapType.Quake3:
            case MapType.Raven:
            case MapType.CoD:
            case MapType.CoD2:
            case MapType.CoD4: {
                structLength = 72;
                break;
            }

            case MapType.Quake2:
            case MapType.Daikatana:
            case MapType.SoF:
            case MapType.Stef2:
            case MapType.Stef2Demo:
            case MapType.Fakk: {
                structLength = 76;
                break;
            }

            case MapType.Mohaa: {
                structLength = 140;
                break;
            }

            case MapType.SiN: {
                structLength = 180;
                break;
            }

            case MapType.Source17:
            case MapType.Source18:
            case MapType.Source19:
            case MapType.Source20:
            case MapType.Source21:
            case MapType.Source22:
            case MapType.Source23:
            case MapType.Source27:
            case MapType.L4D2:
            case MapType.TacticalInterventionEncrypted:
            case MapType.Vindictus:
            case MapType.DMoMaM: {
                int offset = 0;
                for (int i = 0; i < data.Length; ++i)
                {
                    if (data[i] == 0x00)
                    {
                        // They are null-terminated strings, of non-constant length (not padded)
                        byte[] myBytes = new byte[i - offset];
                        Array.Copy(data, offset, myBytes, 0, i - offset);
                        Add(new Texture(myBytes, this));
                        offset = i + 1;
                    }
                }
                return;
            }

            case MapType.Quake: {
                int numElements = BitConverter.ToInt32(data, 0);
                structLength = 40;
                for (int i = 0; i < numElements; ++i)
                {
                    byte[] myBytes = new byte[structLength];
                    Array.Copy(data, BitConverter.ToInt32(data, (i + 1) * 4), myBytes, 0, structLength);
                    Add(new Texture(myBytes, this));
                }
                return;
            }

            default: {
                throw new ArgumentException("Lump object Texture does not exist in map type " + bsp.Version + " or has not been implemented.");
            }
            }

            int numObjects = data.Length / structLength;

            for (int i = 0; i < numObjects; ++i)
            {
                byte[] bytes = new byte[structLength];
                Array.Copy(data, (i * structLength), bytes, 0, structLength);
                Add(new Texture(bytes, this));
            }
        }
Пример #26
0
        public void Load(string file)
        {
            filename = file;
            string directory = Path.GetDirectoryName(file) + '\\';

            #region open maps
            shared = new SharedMaps(new FileStream(directory + MainMenu, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), new FileStream(directory + Shared, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), new FileStream(directory + SinglePlayerShared, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));

            map    = new FileStream(file, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
            reader = new BinaryReader(map);
            writer = new BinaryWriter(map);
            #endregion

            #region header and index
            header       = Reinterpret.Memory <MapHeader>(reader.ReadBytes(Marshal.SizeOf(typeof(MapHeader))));
            map.Position = header.IndexOffset;
            index        = Reinterpret.Memory <IndexHeader>(reader.ReadBytes(Marshal.SizeOf(typeof(IndexHeader))));
            magic        = (index.MagicConstant - header.IndexOffset - Marshal.SizeOf(typeof(IndexHeader))) + (header.AllExceptRawLength - header.IndexAndMetaLength - header.IndexLength);

            // each "TagType" is three dwords
            map.Position += 12 * index.TagTypeCount;

            tags = new List <IndexElement>(index.TagCount);
            for (int i = 0; i < index.TagCount; i++)
            {
                tags.Add(Reinterpret.Memory <IndexElement>(reader.ReadBytes(Marshal.SizeOf(typeof(IndexElement)))));
            }
            #endregion

            #region bsps
            int bspCount  = 0;
            int bspOffset = 0;

            if (header.HeadSignature == HeadSignature)
            {
                map.Position = 528 + unchecked (tags[LocateTagByID(index.ScenarioIdentifier)].Offset - magic);
                bspCount     = reader.ReadInt32();
                bspOffset    = unchecked (reader.ReadInt32() - magic);

                bsps = new Bsp[bspCount];
                for (int i = 0; i < bspCount; i++)
                {
                    bsps[i]      = new Bsp();
                    map.Position = bsps[i].LocationInScenario = bspOffset + 68 * i;

                    bsps[i].BspHeaderOffset = reader.ReadInt32();
                    int totalBspSize = reader.ReadInt32();
                    bsps[i].Magic = reader.ReadInt32();

                    map.Position      += 8;
                    bsps[i].BspID      = reader.ReadInt32();
                    map.Position      += 4;
                    bsps[i].LightmapID = reader.ReadInt32();

                    /*
                     * HEADER FORMAT
                     * total size
                     * pointer to bsp location
                     * pointer to lightmap location
                     * 'sbsp'
                     */

                    map.Position = bsps[i].BspHeaderOffset;
                    int inHeaderBspSize   = reader.ReadInt32();
                    int inHeaderBspOffset = reader.ReadInt32();
                    int lightmapOffset    = reader.ReadInt32();
                    bsps[i].BspOffset = (inHeaderBspOffset - bsps[i].Magic) + bsps[i].BspHeaderOffset;

                    if (bsps[i].LightmapID == -1)
                    {
                        bsps[i].BspSize = inHeaderBspSize;
                    }
                    else
                    {
                        bsps[i].LightmapOffset = unchecked (lightmapOffset - bsps[i].Magic) + bsps[i].BspHeaderOffset;
                        bsps[i].BspSize        = bsps[i].LightmapOffset - bsps[i].BspOffset;
                        bsps[i].LightmapSize   = totalBspSize - bsps[i].BspSize;
                    }
                }
            }
            #endregion

            #region strings
            strings      = new List <string>(header.StringIdCount);
            map.Position = header.StringIdTableOffset;
            for (int i = 0; i < header.StringIdCount; i++)
            {
                strings.Add(String.Empty);
                while (true)
                {
                    byte character = reader.ReadByte();
                    if (character == 0)
                    {
                        break;
                    }
                    else
                    {
                        strings[i] += Convert.ToChar(character);
                    }
                }
            }
            string[] stringArray = strings.ToArray();
            #endregion

            #region names
            map.Position      = header.NameTableOffset;
            names             = new List <string>(header.NameTableCount);
            dictionary        = new Dictionary <int, string>(header.NameTableCount);
            inverseDictionary = new Dictionary <string, int>(header.NameTableCount);

            for (int i = 0; i < header.NameTableCount; i++)
            {
                names.Add(String.Empty);
                while (true)
                {
                    byte character = reader.ReadByte();
                    if (character == 0)
                    {
                        break;
                    }
                    else
                    {
                        names[i] += Convert.ToChar(character);
                    }
                }

                string dictionaryName = names[i] + '.' + Singleton <ClassManager> .Instance.GetClassByID(tags[i].Type).Name;

                dictionary.Add(tags[i].Identifier, dictionaryName);
                inverseDictionary.Add(dictionaryName, tags[i].Identifier);
            }
            #endregion

            #region globals and coconuts
            if (header.HeadSignature == HeadSignature)
            {
                map.Position = unchecked (tags[LocateTagByID(index.GlobalsIdentifier)].Offset - magic);
                globals      = new Globals(reader);

                map.Position = unchecked (tags[index.TagCount - 1].Offset - magic);
                coconuts     = new Coconuts(reader, shared, magic, stringArray);
            }
            #endregion

            #region composition
            if (header.HeadSignature == HeadSignature)
            {
                for (int i = 0; i < index.TagCount; i++)
                {
                    int result;

                    switch (tags[i].Type)
                    {
                    case Animation:
                        map.Position = unchecked (tags[i].Offset - magic);
                        result       = Tag.GetFirstInternalResourceOffset(reader, Animation, magic);
                        if (result != -1)
                        {
                            if (result < animationStart || animationStart == -1)
                            {
                                animationStart = result;
                            }
                        }
                        break;

                    case Decorators:
                        map.Position = unchecked (tags[i].Offset - magic);
                        result       = Tag.GetFirstInternalResourceOffset(reader, Decorators, magic);
                        if (result != -1)
                        {
                            if (result < decoratorStart || decoratorStart == -1)
                            {
                                decoratorStart = result;
                            }
                        }
                        break;

                    case ParticleModel:
                        map.Position = unchecked (tags[i].Offset - magic);
                        result       = Tag.GetFirstInternalResourceOffset(reader, ParticleModel, magic);
                        if (result != -1)
                        {
                            if (result < particleModelStart || particleModelStart == -1)
                            {
                                particleModelStart = result;
                            }
                        }
                        break;

                    case WeatherSystem:
                        map.Position = unchecked (tags[i].Offset - magic);
                        result       = Tag.GetFirstInternalResourceOffset(reader, WeatherSystem, magic);
                        if (result != -1)
                        {
                            if (result < weatherStart || weatherStart == -1)
                            {
                                weatherStart = result;
                            }
                        }
                        break;

                    case RenderModel:
                        map.Position = unchecked (tags[i].Offset - magic);
                        result       = Tag.GetFirstInternalResourceOffset(reader, RenderModel, magic);
                        if (result != -1)
                        {
                            if (result < modelStart || modelStart == -1)
                            {
                                modelStart = result;
                            }
                        }
                        break;
                    }
                }

                // this is (should be anyways) constant
                soundStart = Marshal.SizeOf(typeof(MapHeader));

                // this is a calculated value
                bitmapStart = header.CrazyDataOffset + header.CrazyDataSize;

                for (int i = 0; i < bspCount; i++)
                {
                    Bsp bsp = bsps[i];
                    if (bsp.BspOffset < bspMetaStart || bspMetaStart == -1)
                    {
                        bspMetaStart = bsp.BspHeaderOffset;
                    }
                    else if (bsp.LightmapOffset < bspMetaStart || bspMetaStart == -1)
                    {
                        bspMetaStart = bsp.BspHeaderOffset;
                    }

                    int result;

                    if (bsp.BspID != -1)
                    {
                        reader.BaseStream.Position = bsp.BspOffset;
                        result = Tag.GetFirstInternalResourceOffset(reader, StructureBsp, bsp.Magic - bsp.BspHeaderOffset);
                        if (result != -1)
                        {
                            if (result < bspRawStart || bspRawStart == -1 && result != -1)
                            {
                                bspRawStart = result;
                            }
                        }
                    }

                    if (bsp.LightmapID != -1)
                    {
                        reader.BaseStream.Position = bsp.LightmapOffset;
                        result = Tag.GetFirstInternalResourceOffset(reader, StructureLightmap, bsp.Magic - bsp.BspHeaderOffset);
                        if (result != -1)
                        {
                            if (result < bspRawStart || bspRawStart == -1)
                            {
                                bspRawStart = result;
                            }
                        }
                    }
                }

                foreach (Coconuts.ExtraInfo extraInfo in coconuts.ExtraInfos)
                {
                    if (extraInfo.ResourceBlock.RawSize > 0)
                    {
                        uint encoded = Conversion.ToUInt(extraInfo.ResourceBlock.RawOffset);
                        if ((encoded & 0xc0000000) == 0)
                        {
                            if (extraInfo.ResourceBlock.RawOffset < coconutsModelStart || coconutsModelStart == -1)
                            {
                                coconutsModelStart = extraInfo.ResourceBlock.RawOffset;
                            }
                        }
                    }
                }

                if (bspMetaStart < 0)
                {
                    bspMetaStart = header.StringIdPaddedOffset;
                }
                if (animationStart < 0)
                {
                    animationStart = bspMetaStart;
                }
                if (coconutsModelStart < 0)
                {
                    coconutsModelStart = animationStart;
                }
                if (particleModelStart < 0)
                {
                    particleModelStart = coconutsModelStart;
                }
                if (decoratorStart < 0)
                {
                    decoratorStart = particleModelStart;
                }
                if (weatherStart < 0)
                {
                    weatherStart = decoratorStart;
                }
                if (bspRawStart < 0)
                {
                    bspRawStart = weatherStart;
                }
                if (modelStart < 0)
                {
                    modelStart = bspRawStart;
                }

                // these are all duplicates
                stringPaddedStart = header.StringIdPaddedOffset;
                stringIndexStart  = header.StringIdIndexOffset;
                stringTableStart  = header.StringIdTableOffset;
                nameTableStart    = header.NameTableOffset;
                nameIndexStart    = header.NameIndexOffset;
                crazyStart        = header.CrazyDataOffset;

                // this can be calculated a multitude of ways
                unicodeStart = header.NameIndexOffset + header.NameTableCount * sizeof(int);
            }
            #endregion

            valid = true;
        }
Пример #27
0
 void SetupScene() // initialise le niveau
 {
     dijkstra  = FindObjectOfType <Disjskra>();
     bspScript = FindObjectOfType <Bsp>();
 }
Пример #28
0
 /// <summary>
 /// Creates an empty <see cref="Textures"/> object.
 /// </summary>
 /// <param name="bsp">The <see cref="Bsp"/> this lump came from.</param>
 /// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
 public Textures(Bsp bsp = null, LumpInfo lumpInfo = default) : base(bsp, lumpInfo)
 {
 }
Пример #29
0
        /// <summary>
        /// Initializes a new <see cref="Entities"/> object, and parses the passed <c>byte</c> array as a <c>string</c>.
        /// </summary>
        /// <param name="data"><c>Byte</c>s read from a file.</param>
        /// <param name="bsp">The <see cref="Bsp"/> this lump came from.</param>
        /// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
        public Entities(byte[] data, Bsp bsp = null, LumpInfo lumpInfo = default) : base(bsp, lumpInfo)
        {
            // Keep track of whether or not we're currently in a set of quotation marks.
            // I came across a map where the map maker used { and } within a value.
            bool inQuotes   = false;
            int  braceCount = 0;

            // The current character being read in the file. This is necessary because
            // we need to know exactly when the { and } characters occur and capture
            // all text between them.
            char currentChar;
            // This will be the resulting entity, fed into Entity.FromString
            StringBuilder current = new StringBuilder();

            for (int offset = 0; offset < data.Length; ++offset)
            {
                currentChar = (char)data[offset];

                if (currentChar == '\"')
                {
                    if (offset == 0)
                    {
                        inQuotes = !inQuotes;
                    }
                    else if ((char)data[offset - 1] != '\\')
                    {
                        // Allow for escape-sequenced quotes to not affect the state machine, but only if the quote isn't at the end of a line.
                        // Some Source engine entities use escape sequence quotes in values, but MoHAA has a map with an obvious erroneous backslash before a quote at the end of a line.
                        if (inQuotes && (offset + 1 >= data.Length || (char)data[offset + 1] == '\n' || (char)data[offset + 1] == '\r'))
                        {
                            inQuotes = false;
                        }
                    }
                    else
                    {
                        inQuotes = !inQuotes;
                    }
                }

                if (!inQuotes)
                {
                    if (currentChar == '{')
                    {
                        // Occasionally, texture paths have been known to contain { or }. Since these aren't always contained
                        // in quotes, we must be a little more precise about how we want to select our delimiters.
                        // As a general rule, though, making sure we're not in quotes is still very effective at error prevention.
                        if (offset == 0 || (char)data[offset - 1] == '\n' || (char)data[offset - 1] == '\t' || (char)data[offset - 1] == ' ' || (char)data[offset - 1] == '\r')
                        {
                            ++braceCount;
                        }
                    }
                }

                if (braceCount > 0)
                {
                    current.Append(currentChar);
                }

                if (!inQuotes)
                {
                    if (currentChar == '}')
                    {
                        if (offset == 0 || (char)data[offset - 1] == '\n' || (char)data[offset - 1] == '\t' || (char)data[offset - 1] == ' ' || (char)data[offset - 1] == '\r')
                        {
                            --braceCount;
                            if (braceCount == 0)
                            {
                                Entity entity = new Entity(this);
                                entity.ParseString(current.ToString());
                                Add(entity);
                                // Reset StringBuilder
                                current.Length = 0;
                            }
                        }
                    }
                }
            }

            if (braceCount != 0)
            {
                throw new ArgumentException(
                          $"Brace mismatch when parsing entities! Entity: {Count} Brace level: {braceCount}");
            }
        }
Пример #30
0
 /// <summary>
 /// Creates a new <see cref="Textures"/> that contains elements copied from the passed <see cref="IEnumerable{T}"/>.
 /// </summary>
 /// <param name="items">The elements to copy into this <c>Lump</c>.</param>
 /// <param name="bsp">The <see cref="Bsp"/> this lump came from.</param>
 /// <param name="lumpInfo">The <see cref="LumpInfo"/> associated with this lump.</param>
 public Textures(IEnumerable <Texture> items, Bsp bsp = null, LumpInfo lumpInfo = default) : base(items, bsp, lumpInfo)
 {
 }