예제 #1
0
        private bool InternalCreate(Core.Version version, ClientFeatures features)
        {
            if (this.Compiling)
            {
                return(false);
            }

            if (this.Loaded)
            {
                return(true);
            }

            if (features == ClientFeatures.None || features == ClientFeatures.Transparency)
            {
                features |= version.Value >= (ushort)DatFormat.Format_755 ? ClientFeatures.PatternZ : features;
                features |= version.Value >= (ushort)DatFormat.Format_960 ? ClientFeatures.Extended : features;
                features |= version.Value >= (ushort)DatFormat.Format_1050 ? ClientFeatures.FrameDurations : features;
                features |= version.Value >= (ushort)DatFormat.Format_1057 ? ClientFeatures.FrameGroups : features;
            }

            this.Version        = version;
            this.ClientFeatures = features;
            this.transparency   = (features & ClientFeatures.Transparency) == ClientFeatures.Transparency ? true : false;
            this.headSize       = (features & ClientFeatures.Extended) == ClientFeatures.Extended ? HeaderU32 : HeaderU16;
            this.blankSprite    = new Sprite(0, this.transparency);
            this.sprites.Add(1, new Sprite(1, this.transparency));
            this.rawSpriteCount = 0;
            this.Count          = 1;
            this.Changed        = true;
            this.Loaded         = true;
            this.Compiling      = false;
            this.Disposed       = false;
            return(true);
        }
예제 #2
0
        private bool InternalCreate(Core.Version version, ClientFeatures features)
        {
            if (version == null)
            {
                throw new ArgumentNullException(nameof(version));
            }

            if (this.Loaded)
            {
                return(true);
            }

            if (features == ClientFeatures.None || features == ClientFeatures.Transparency)
            {
                features |= version.Value >= (ushort)DatFormat.Format_755 ? ClientFeatures.PatternZ : features;
                features |= version.Value >= (ushort)DatFormat.Format_960 ? ClientFeatures.Extended : features;
                features |= version.Value >= (ushort)DatFormat.Format_1050 ? ClientFeatures.FrameDurations : features;
                features |= version.Value >= (ushort)DatFormat.Format_1057 ? ClientFeatures.FrameGroups : features;
            }

            this.Version        = version;
            this.ClientFeatures = features;
            this.Items.Add(100, ThingType.Create(100, ThingCategory.Item));
            this.ItemCount = 100;
            this.Outfits.Add(1, ThingType.Create(1, ThingCategory.Outfit));
            this.OutfitCount = 1;
            this.Effects.Add(1, ThingType.Create(1, ThingCategory.Effect));
            this.EffectCount = 1;
            this.Missiles.Add(1, ThingType.Create(1, ThingCategory.Missile));
            this.MissileCount = 1;
            this.Changed      = true;
            this.Loaded       = true;
            this.Disposed     = false;
            return(true);
        }
예제 #3
0
        public bool Save(string datPath, string sprPath, Core.Version version, ClientFeatures features)
        {
            if (datPath == null)
            {
                throw new ArgumentNullException(nameof(datPath));
            }

            if (sprPath == null)
            {
                throw new ArgumentNullException(nameof(sprPath));
            }

            if (version == null)
            {
                throw new ArgumentNullException(nameof(version));
            }

            if (!this.Things.Save(datPath, version, features))
            {
                return(false);
            }

            if (!this.Sprites.Save(sprPath, version, features))
            {
                return(false);
            }

            return(true);
        }
예제 #4
0
        public bool CreateEmpty(Core.Version version, ClientFeatures features)
        {
            if (version == null)
            {
                throw new ArgumentNullException(nameof(version));
            }

            this.Things = ThingTypeStorage.Create(version, features);
            if (this.Things == null)
            {
                return(false);
            }

            this.Sprites = SpriteStorage.Create(version, features);
            if (this.Sprites == null)
            {
                return(false);
            }

            this.Things.ProgressChanged  += new ProgressHandler(this.StorageProgressChanged_Handler);
            this.Things.StorageChanged   += new ThingListChangedHandler(this.ThingListChanged_Handler);
            this.Things.StorageCompiled  += new StorageHandler(this.StorageCompiled_Handler);
            this.Things.StorageDisposed  += new StorageHandler(this.StorageDisposed_Handler);
            this.Sprites.StorageChanged  += new SpriteListChangedHandler(this.SpriteListChanged_Handler);
            this.Sprites.ProgressChanged += new ProgressHandler(this.StorageProgressChanged_Handler);
            this.Sprites.StorageCompiled += new StorageHandler(this.StorageCompiled_Handler);
            this.Sprites.StorageDisposed += new StorageHandler(this.StorageDisposed_Handler);

            if (this.Loaded && this.ClientLoaded != null)
            {
                this.ClientLoaded(this, new EventArgs());
            }

            return(this.Loaded);
        }
예제 #5
0
        public bool Save(string path, Core.Version version)
        {
            if (this.Disposed)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }

            return(this.Save(path, version, ClientFeatures.None));
        }
예제 #6
0
        public static SpriteStorage Create(Core.Version version)
        {
            SpriteStorage storage = new SpriteStorage();

            if (storage.InternalCreate(version, ClientFeatures.None))
            {
                return(storage);
            }

            return(null);
        }
예제 #7
0
        public static SpriteStorage Load(string path, Core.Version version)
        {
            SpriteStorage storage = new SpriteStorage();

            if (storage.InternalLoad(path, version, ClientFeatures.None, false))
            {
                return(storage);
            }

            return(null);
        }
예제 #8
0
        public static ThingTypeStorage Create(Core.Version version, ClientFeatures features)
        {
            ThingTypeStorage storage = new ThingTypeStorage();

            if (storage.InternalCreate(version, features))
            {
                return(storage);
            }

            return(null);
        }
예제 #9
0
        public static ThingTypeStorage Load(string path, Core.Version version)
        {
            ThingTypeStorage storage = new ThingTypeStorage();

            if (storage.InternalLoad(path, version, ClientFeatures.None))
            {
                return(storage);
            }

            return(null);
        }
예제 #10
0
        public bool Save(string path, Core.Version version, ClientFeatures features)
        {
            if (path == null)
            {
                throw new ArgumentNullException("path");
            }

            if (version == null)
            {
                throw new ArgumentNullException("version");
            }

            if (this.Disposed)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }

            if (!this.Loaded)
            {
                return false;
            }

            if (features == ClientFeatures.None || features == ClientFeatures.Transparency)
            {
                features |= version.Value >= (ushort)DatFormat.Format_755 ? ClientFeatures.PatternZ : features;
                features |= version.Value >= (ushort)DatFormat.Format_960 ? ClientFeatures.Extended : features;
                features |= version.Value >= (ushort)DatFormat.Format_1050 ? ClientFeatures.FrameDurations : features;
                features |= version.Value >= (ushort)DatFormat.Format_1057 ? ClientFeatures.FrameGroups : features;
            }

            string directory = Path.GetDirectoryName(path);
            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            if (!this.Changed && this.Version.Equals(version) && this.ClientFeatures == features &&
                this.FilePath != null && !this.FilePath.Equals(path))
            {
                // just copy the content if nothing has changed.
                File.Copy(this.FilePath, path, true);

                if (this.ProgressChanged != null)
                {
                    this.ProgressChanged(this, 100);
                }
            }
            else
            {
                string tmpPath = Path.Combine(directory, Path.GetFileNameWithoutExtension(path) + ".tmp");

                using (BinaryWriter writer = new BinaryWriter(new FileStream(tmpPath, FileMode.Create)))
                {
                    // write the signature.
                    writer.Write(version.DatSignature);

                    // write item, outfit, effect and missile count.
                    writer.Write(this.ItemCount);
                    writer.Write(this.OutfitCount);
                    writer.Write(this.EffectCount);
                    writer.Write(this.MissileCount);

                    int total = this.ItemCount + this.OutfitCount + this.EffectCount + this.MissileCount;
                    int compiled = 0;

                    // write item list.
                    for (ushort id = 100; id <= this.ItemCount; id++)
                    {
                        ThingType item = this.Items[id];
                        if (!ThingTypeSerializer.WriteProperties(item, this.Version.Format, writer) ||
                            !ThingTypeSerializer.WriteTexturePatterns(item, features, writer))
                        {
                            throw new Exception("Items list cannot be compiled.");
                        }
                    }

                    // update progress.
                    if (this.ProgressChanged != null)
                    {
                        compiled += this.ItemCount;
                        this.ProgressChanged(this, (compiled * 100) / total);
                    }

                    bool onlyOneGroup = ((this.ClientFeatures & ClientFeatures.FrameGroups) == ClientFeatures.FrameGroups) &&
                                        ((features & ClientFeatures.FrameGroups) != ClientFeatures.FrameGroups);

                    // write outfit list.
                    for (ushort id = 1; id <= this.OutfitCount; id++)
                    {
                        ThingType outfit = onlyOneGroup ? ThingType.ToSingleFrameGroup(this.Outfits[id]) : this.Outfits[id];
                        if (!ThingTypeSerializer.WriteProperties(outfit, this.Version.Format, writer) ||
                            !ThingTypeSerializer.WriteTexturePatterns(outfit, features, writer))
                        {
                            throw new Exception("Outfits list cannot be compiled.");
                        }
                    }

                    // update progress.
                    if (this.ProgressChanged != null)
                    {
                        compiled += this.OutfitCount;
                        this.ProgressChanged(this, (compiled * 100) / total);
                    }

                    // write effect list.
                    for (ushort id = 1; id <= this.EffectCount; id++)
                    {
                        ThingType effect = this.Effects[id];
                        if (!ThingTypeSerializer.WriteProperties(effect, this.Version.Format, writer) ||
                            !ThingTypeSerializer.WriteTexturePatterns(effect, features, writer))
                        {
                            throw new Exception("Effects list cannot be compiled.");
                        }
                    }

                    // update progress.
                    if (this.ProgressChanged != null)
                    {
                        compiled += this.EffectCount;
                        this.ProgressChanged(this, (compiled * 100) / total);
                    }

                    // write missile list.
                    for (ushort id = 1; id <= this.MissileCount; id++)
                    {
                        ThingType missile = this.Missiles[id];
                        if (!ThingTypeSerializer.WriteProperties(missile, this.Version.Format, writer) ||
                            !ThingTypeSerializer.WriteTexturePatterns(missile, features, writer))
                        {
                            throw new Exception("Missiles list cannot be compiled.");
                        }
                    }

                    // update progress.
                    if (this.ProgressChanged != null)
                    {
                        compiled += this.MissileCount;
                        this.ProgressChanged(this, (compiled * 100) / total);
                    }
                }

                if (File.Exists(path))
                {
                    File.Delete(path);
                }

                File.Move(tmpPath, path);
            }

            this.FilePath = path;
            this.Version = version;
            this.ClientFeatures = features;
            this.Changed = false;

            if (this.StorageCompiled != null)
            {
                this.StorageCompiled(this, new EventArgs());
            }

            return true;
        }
예제 #11
0
        public bool Save(string path, Core.Version version, ClientFeatures features)
        {
            if (path == null)
            {
                throw new ArgumentNullException(nameof(path));
            }

            if (version == null)
            {
                throw new ArgumentNullException(nameof(version));
            }

            if (this.Disposed)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }

            if (!this.Loaded || this.Compiling)
            {
                return(false);
            }

            if (features == ClientFeatures.None || features == ClientFeatures.Transparency)
            {
                features |= version.Value >= (ushort)DatFormat.Format_755 ? ClientFeatures.PatternZ : features;
                features |= version.Value >= (ushort)DatFormat.Format_960 ? ClientFeatures.Extended : features;
                features |= version.Value >= (ushort)DatFormat.Format_1050 ? ClientFeatures.FrameDurations : features;
                features |= version.Value >= (ushort)DatFormat.Format_1057 ? ClientFeatures.FrameGroups : features;
            }

            string directory = Path.GetDirectoryName(path);

            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            if (!this.Changed && this.Version.Equals(version) && this.ClientFeatures == features)
            {
                //  just copy the content and reload if nothing has changed.
                if (this.FilePath != null && !this.FilePath.Equals(path))
                {
                    File.Copy(this.FilePath, path, true);

                    if (!this.InternalLoad(path, version, features, true))
                    {
                        return(false);
                    }

                    if (this.ProgressChanged != null)
                    {
                        this.ProgressChanged(this, 100);
                    }

                    if (this.StorageCompiled != null)
                    {
                        this.StorageCompiled(this);
                    }
                }

                return(true);
            }

            this.compilationData          = new CompilationData();
            this.compilationData.Path     = path;
            this.compilationData.TmpPath  = Path.Combine(directory, Path.GetFileNameWithoutExtension(path) + ".tmp");
            this.compilationData.Version  = version;
            this.compilationData.Features = features;
            this.Compiling = true;
            this.worker.RunWorkerAsync();
            return(true);
        }
예제 #12
0
        public bool Save(string path, Core.Version version, ClientFeatures features)
        {
            if (path == null)
            {
                throw new ArgumentNullException("path");
            }

            if (version == null)
            {
                throw new ArgumentNullException("version");
            }

            if (this.Disposed)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }

            if (!this.Loaded || this.Compiling)
            {
                return false;
            }

            if (features == ClientFeatures.None || features == ClientFeatures.Transparency)
            {
                features |= version.Value >= (ushort)DatFormat.Format_755 ? ClientFeatures.PatternZ : features;
                features |= version.Value >= (ushort)DatFormat.Format_960 ? ClientFeatures.Extended : features;
                features |= version.Value >= (ushort)DatFormat.Format_1050 ? ClientFeatures.FrameDurations : features;
                features |= version.Value >= (ushort)DatFormat.Format_1057 ? ClientFeatures.FrameGroups : features;
            }

            string directory = Path.GetDirectoryName(path);
            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            if (!this.Changed && this.Version.Equals(version) && this.ClientFeatures == features)
            {
                //  just copy the content and reload if nothing has changed.
                if (this.FilePath != null && !this.FilePath.Equals(path))
                {
                    File.Copy(this.FilePath, path, true);

                    if (!this.InternalLoad(path, version, features, true))
                    {
                        return false;
                    }

                    if (this.ProgressChanged != null)
                    {
                        this.ProgressChanged(this, 100);
                    }

                    if (this.StorageCompiled != null)
                    {
                        this.StorageCompiled(this, new EventArgs());
                    }
                }

                return true;
            }

            this.compilationData = new CompilationData();
            this.compilationData.Path = path;
            this.compilationData.TmpPath = Path.Combine(directory, Path.GetFileNameWithoutExtension(path) + ".tmp");
            this.compilationData.Version = version;
            this.compilationData.Features = features;
            this.Compiling = true;
            this.worker.RunWorkerAsync();
            return true;
        }
예제 #13
0
        private bool InternalLoad(string path, Core.Version version, ClientFeatures features, bool reloading)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException("path");
            }

            if (version == null)
            {
                throw new ArgumentNullException("version");
            }

            if (!File.Exists(path))
            {
                string message = "File not found: {0}"; // TODO: ResourceManager.GetString("Exception.FileNotFound");
                throw new FileNotFoundException(string.Format(message, path), "path");
            }

            if (this.Compiling)
            {
                return false;
            }

            if (this.Loaded)
            {
                if (reloading)
                {
                    this.stream.Close();
                    this.stream = null;
                }
                else
                {
                    return true;
                }
            }

            if (features == ClientFeatures.None || features == ClientFeatures.Transparency)
            {
                features |= version.Value >= (ushort)DatFormat.Format_755 ? ClientFeatures.PatternZ : features;
                features |= version.Value >= (ushort)DatFormat.Format_960 ? ClientFeatures.Extended : features;
                features |= version.Value >= (ushort)DatFormat.Format_1050 ? ClientFeatures.FrameDurations : features;
                features |= version.Value >= (ushort)DatFormat.Format_1057 ? ClientFeatures.FrameGroups : features;
            }

            this.stream = new FileStream(path, FileMode.Open);
            this.reader = new BinaryReader(this.stream);

            uint signature = this.reader.ReadUInt32();
            if (signature != version.SprSignature)
            {
                string message = "Invalid SPR signature. Expected signature is {0:X} and loaded signature is {1:X}.";
                throw new Exception(string.Format(message, version.SprSignature, signature));
            }

            if ((features & ClientFeatures.Extended) == ClientFeatures.Extended)
            {
                this.headSize = HeaderU32;
                this.rawSpriteCount = this.reader.ReadUInt32();
            }
            else
            {
                this.headSize = HeaderU16;
                this.rawSpriteCount = this.reader.ReadUInt16();
            }

            this.FilePath = path;
            this.Version = version;
            this.ClientFeatures = features;
            this.transparency = (features & ClientFeatures.Transparency) == ClientFeatures.Transparency ? true : false;
            this.Count = this.rawSpriteCount;
            this.blankSprite = new Sprite(0, this.transparency);
            this.Changed = false;
            this.Loaded = true;
            this.Disposed = false;
            return true;
        }
예제 #14
0
        private bool InternalCreate(Core.Version version, ClientFeatures features)
        {
            if (this.Compiling)
            {
                return false;
            }

            if (this.Loaded)
            {
                return true;
            }

            if (features == ClientFeatures.None || features == ClientFeatures.Transparency)
            {
                features |= version.Value >= (ushort)DatFormat.Format_755 ? ClientFeatures.PatternZ : features;
                features |= version.Value >= (ushort)DatFormat.Format_960 ? ClientFeatures.Extended : features;
                features |= version.Value >= (ushort)DatFormat.Format_1050 ? ClientFeatures.FrameDurations : features;
                features |= version.Value >= (ushort)DatFormat.Format_1057 ? ClientFeatures.FrameGroups : features;
            }

            this.Version = version;
            this.ClientFeatures = features;
            this.transparency = (features & ClientFeatures.Transparency) == ClientFeatures.Transparency ? true : false;
            this.headSize = (features & ClientFeatures.Extended) == ClientFeatures.Extended ? HeaderU32 : HeaderU16;
            this.blankSprite = new Sprite(0, this.transparency);
            this.sprites.Add(1, new Sprite(1, this.transparency));
            this.rawSpriteCount = 0;
            this.Count = 1;
            this.Changed = true;
            this.Loaded = true;
            this.Compiling = false;
            this.Disposed = false;
            return true;
        }
예제 #15
0
        private bool InternalLoad(string path, Core.Version version, ClientFeatures features)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException("path");
            }

            if (version == null)
            {
                throw new ArgumentNullException("version");
            }

            if (!File.Exists(path))
            {
                throw new FileNotFoundException(string.Format("File not found: {0}", path), path);
            }

            if (this.Loaded)
            {
                return true;
            }

            if (features == ClientFeatures.None || features == ClientFeatures.Transparency)
            {
                features |= version.Value >= (ushort)DatFormat.Format_755 ? ClientFeatures.PatternZ : features;
                features |= version.Value >= (ushort)DatFormat.Format_960 ? ClientFeatures.Extended : features;
                features |= version.Value >= (ushort)DatFormat.Format_1050 ? ClientFeatures.FrameDurations : features;
                features |= version.Value >= (ushort)DatFormat.Format_1057 ? ClientFeatures.FrameGroups : features;
            }

            using (FileStream stream = new FileStream(path, FileMode.Open))
            {
                BinaryReader reader = new BinaryReader(stream);

                uint signature = reader.ReadUInt32();
                if (signature != version.DatSignature)
                {
                    string message = "Invalid DAT signature. Expected signature is {0:X} and loaded signature is {1:X}.";
                    throw new Exception(string.Format(message, version.DatSignature, signature));
                }

                this.ItemCount = reader.ReadUInt16();
                this.OutfitCount = reader.ReadUInt16();
                this.EffectCount = reader.ReadUInt16();
                this.MissileCount = reader.ReadUInt16();

                int total = this.ItemCount + this.OutfitCount + this.EffectCount + this.MissileCount;
                int loaded = 0;

                // load item list.
                for (ushort id = 100; id <= this.ItemCount; id++)
                {
                    ThingType item = new ThingType(id, ThingCategory.Item);
                    if (!ThingTypeSerializer.ReadProperties(item, version.Format, reader) ||
                        !ThingTypeSerializer.ReadTexturePatterns(item, features, reader))
                    {
                        throw new Exception("Items list cannot be loaded.");
                    }

                    this.Items.Add(id, item);
                }

                // update progress.
                if (this.ProgressChanged != null)
                {
                    loaded += this.ItemCount;
                    this.ProgressChanged(this, (loaded * 100) / total);
                }

                // load outfit list.
                for (ushort id = 1; id <= this.OutfitCount; id++)
                {
                    ThingType outfit = new ThingType(id, ThingCategory.Outfit);
                    if (!ThingTypeSerializer.ReadProperties(outfit, version.Format, reader) ||
                        !ThingTypeSerializer.ReadTexturePatterns(outfit, features, reader))
                    {
                        throw new Exception("Outfits list cannot be loaded.");
                    }

                    this.Outfits.Add(id, outfit);
                }

                // update progress.
                if (this.ProgressChanged != null)
                {
                    loaded += this.OutfitCount;
                    this.ProgressChanged(this, (loaded * 100) / total);
                }

                // load effect list.
                for (ushort id = 1; id <= this.EffectCount; id++)
                {
                    ThingType effect = new ThingType(id, ThingCategory.Effect);
                    if (!ThingTypeSerializer.ReadProperties(effect, version.Format, reader) ||
                        !ThingTypeSerializer.ReadTexturePatterns(effect, features, reader))
                    {
                        throw new Exception("Effects list cannot be loaded.");
                    }

                    this.Effects.Add(id, effect);
                }

                // update progress.
                if (this.ProgressChanged != null)
                {
                    loaded += this.EffectCount;
                    this.ProgressChanged(this, (loaded * 100) / total);
                }

                // load missile list.
                for (ushort id = 1; id <= this.MissileCount; id++)
                {
                    ThingType missile = new ThingType(id, ThingCategory.Missile);
                    if (!ThingTypeSerializer.ReadProperties(missile, version.Format, reader) ||
                        !ThingTypeSerializer.ReadTexturePatterns(missile, features, reader))
                    {
                        throw new Exception("Missiles list cannot be loaded.");
                    }

                    this.Missiles.Add(id, missile);
                }

                // update progress.
                if (this.ProgressChanged != null)
                {
                    loaded += this.MissileCount;
                    this.ProgressChanged(this, (loaded * 100) / total);
                }
            }

            this.FilePath = path;
            this.Version = version;
            this.ClientFeatures = features;
            this.Changed = false;
            this.Loaded = true;
            this.Disposed = false;
            return true;
        }
예제 #16
0
 public bool CreateEmpty(Core.Version version)
 {
     return(this.CreateEmpty(version, ClientFeatures.None));
 }
예제 #17
0
 public bool Save(string datPath, string sprPath, Core.Version version)
 {
     return(this.Save(datPath, sprPath, version, ClientFeatures.None));
 }
예제 #18
0
        public void Dispose()
        {
            this.Disposed = true;

            if (!this.Loaded)
            {
                return;
            }

            this.FilePath = null;
            this.Version = null;
            this.Items.Clear();
            this.Items = null;
            this.ItemCount = 0;
            this.Outfits.Clear();
            this.Outfits = null;
            this.OutfitCount = 0;
            this.Effects.Clear();
            this.Effects = null;
            this.EffectCount = 0;
            this.Missiles.Clear();
            this.Missiles = null;
            this.MissileCount = 0;
            this.Changed = false;
            this.Loaded = false;

            if (this.StorageDisposed != null)
            {
                this.StorageDisposed(this, new EventArgs());
            }
        }
예제 #19
0
        private bool InternalLoad(string path, Core.Version version, ClientFeatures features)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException(nameof(path));
            }

            if (version == null)
            {
                throw new ArgumentNullException(nameof(version));
            }

            if (!File.Exists(path))
            {
                throw new FileNotFoundException($"File not found: {path}", path);
            }

            if (this.Loaded)
            {
                return(true);
            }

            if (features == ClientFeatures.None || features == ClientFeatures.Transparency)
            {
                features |= version.Value >= (ushort)DatFormat.Format_755 ? ClientFeatures.PatternZ : features;
                features |= version.Value >= (ushort)DatFormat.Format_960 ? ClientFeatures.Extended : features;
                features |= version.Value >= (ushort)DatFormat.Format_1050 ? ClientFeatures.FrameDurations : features;
                features |= version.Value >= (ushort)DatFormat.Format_1057 ? ClientFeatures.FrameGroups : features;
            }

            using (FileStream stream = new FileStream(path, FileMode.Open))
            {
                BinaryReader reader = new BinaryReader(stream);

                uint signature = reader.ReadUInt32();
                if (signature != version.DatSignature)
                {
                    string message = "Invalid DAT signature. Expected signature is {0:X} and loaded signature is {1:X}.";
                    throw new Exception(string.Format(message, version.DatSignature, signature));
                }

                this.ItemCount    = reader.ReadUInt16();
                this.OutfitCount  = reader.ReadUInt16();
                this.EffectCount  = reader.ReadUInt16();
                this.MissileCount = reader.ReadUInt16();

                int total  = this.ItemCount + this.OutfitCount + this.EffectCount + this.MissileCount;
                int loaded = 0;

                // load item list.
                for (ushort id = 100; id <= this.ItemCount; id++)
                {
                    ThingType item = new ThingType(id, ThingCategory.Item);
                    if (!ThingTypeSerializer.ReadProperties(item, version.Format, reader) ||
                        !ThingTypeSerializer.ReadTexturePatterns(item, features, reader))
                    {
                        throw new Exception("Items list cannot be loaded.");
                    }

                    this.Items.Add(id, item);
                }

                // update progress.
                if (this.ProgressChanged != null)
                {
                    loaded += this.ItemCount;
                    this.ProgressChanged(this, (loaded * 100) / total);
                }

                // load outfit list.
                for (ushort id = 1; id <= this.OutfitCount; id++)
                {
                    ThingType outfit = new ThingType(id, ThingCategory.Outfit);
                    if (!ThingTypeSerializer.ReadProperties(outfit, version.Format, reader) ||
                        !ThingTypeSerializer.ReadTexturePatterns(outfit, features, reader))
                    {
                        throw new Exception("Outfits list cannot be loaded.");
                    }

                    this.Outfits.Add(id, outfit);
                }

                // update progress.
                if (this.ProgressChanged != null)
                {
                    loaded += this.OutfitCount;
                    this.ProgressChanged(this, (loaded * 100) / total);
                }

                // load effect list.
                for (ushort id = 1; id <= this.EffectCount; id++)
                {
                    ThingType effect = new ThingType(id, ThingCategory.Effect);
                    if (!ThingTypeSerializer.ReadProperties(effect, version.Format, reader) ||
                        !ThingTypeSerializer.ReadTexturePatterns(effect, features, reader))
                    {
                        throw new Exception("Effects list cannot be loaded.");
                    }

                    this.Effects.Add(id, effect);
                }

                // update progress.
                if (this.ProgressChanged != null)
                {
                    loaded += this.EffectCount;
                    this.ProgressChanged(this, (loaded * 100) / total);
                }

                // load missile list.
                for (ushort id = 1; id <= this.MissileCount; id++)
                {
                    ThingType missile = new ThingType(id, ThingCategory.Missile);
                    if (!ThingTypeSerializer.ReadProperties(missile, version.Format, reader) ||
                        !ThingTypeSerializer.ReadTexturePatterns(missile, features, reader))
                    {
                        throw new Exception("Missiles list cannot be loaded.");
                    }

                    this.Missiles.Add(id, missile);
                }

                // update progress.
                if (this.ProgressChanged != null)
                {
                    loaded += this.MissileCount;
                    this.ProgressChanged(this, (loaded * 100) / total);
                }
            }

            this.FilePath       = path;
            this.Version        = version;
            this.ClientFeatures = features;
            this.Changed        = false;
            this.Loaded         = true;
            this.Disposed       = false;
            return(true);
        }
예제 #20
0
        public bool Save(string path, Core.Version version, ClientFeatures features)
        {
            if (path == null)
            {
                throw new ArgumentNullException(nameof(path));
            }

            if (version == null)
            {
                throw new ArgumentNullException(nameof(version));
            }

            if (this.Disposed)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }

            if (!this.Loaded)
            {
                return(false);
            }

            if (features == ClientFeatures.None || features == ClientFeatures.Transparency)
            {
                features |= version.Value >= (ushort)DatFormat.Format_755 ? ClientFeatures.PatternZ : features;
                features |= version.Value >= (ushort)DatFormat.Format_960 ? ClientFeatures.Extended : features;
                features |= version.Value >= (ushort)DatFormat.Format_1050 ? ClientFeatures.FrameDurations : features;
                features |= version.Value >= (ushort)DatFormat.Format_1057 ? ClientFeatures.FrameGroups : features;
            }

            string directory = Path.GetDirectoryName(path);

            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            if (!this.Changed && this.Version.Equals(version) && this.ClientFeatures == features &&
                this.FilePath != null && !this.FilePath.Equals(path))
            {
                // just copy the content if nothing has changed.
                File.Copy(this.FilePath, path, true);

                if (this.ProgressChanged != null)
                {
                    this.ProgressChanged(this, 100);
                }
            }
            else
            {
                string tmpPath = Path.Combine(directory, Path.GetFileNameWithoutExtension(path) + ".tmp");

                using (FlagsBinaryWriter writer = new FlagsBinaryWriter(new FileStream(tmpPath, FileMode.Create)))
                {
                    // write the signature.
                    writer.Write(version.DatSignature);

                    // write item, outfit, effect and missile count.
                    writer.Write(this.ItemCount);
                    writer.Write(this.OutfitCount);
                    writer.Write(this.EffectCount);
                    writer.Write(this.MissileCount);

                    int total    = this.ItemCount + this.OutfitCount + this.EffectCount + this.MissileCount;
                    int compiled = 0;

                    // write item list.
                    for (ushort id = 100; id <= this.ItemCount; id++)
                    {
                        ThingType item = this.Items[id];
                        if (!ThingTypeSerializer.WriteProperties(item, version.Format, writer) ||
                            !ThingTypeSerializer.WriteTexturePatterns(item, features, writer))
                        {
                            throw new Exception("Items list cannot be compiled.");
                        }
                    }

                    // update progress.
                    if (this.ProgressChanged != null)
                    {
                        compiled += this.ItemCount;
                        this.ProgressChanged(this, (compiled * 100) / total);
                    }

                    bool onlyOneGroup = ((this.ClientFeatures & ClientFeatures.FrameGroups) == ClientFeatures.FrameGroups) &&
                                        ((features & ClientFeatures.FrameGroups) != ClientFeatures.FrameGroups);

                    // write outfit list.
                    for (ushort id = 1; id <= this.OutfitCount; id++)
                    {
                        ThingType outfit = onlyOneGroup ? ThingType.ToSingleFrameGroup(this.Outfits[id]) : this.Outfits[id];
                        if (!ThingTypeSerializer.WriteProperties(outfit, version.Format, writer) ||
                            !ThingTypeSerializer.WriteTexturePatterns(outfit, features, writer))
                        {
                            throw new Exception("Outfits list cannot be compiled.");
                        }
                    }

                    // update progress.
                    if (this.ProgressChanged != null)
                    {
                        compiled += this.OutfitCount;
                        this.ProgressChanged(this, (compiled * 100) / total);
                    }

                    // write effect list.
                    for (ushort id = 1; id <= this.EffectCount; id++)
                    {
                        ThingType effect = this.Effects[id];
                        if (!ThingTypeSerializer.WriteProperties(effect, version.Format, writer) ||
                            !ThingTypeSerializer.WriteTexturePatterns(effect, features, writer))
                        {
                            throw new Exception("Effects list cannot be compiled.");
                        }
                    }

                    // update progress.
                    if (this.ProgressChanged != null)
                    {
                        compiled += this.EffectCount;
                        this.ProgressChanged(this, (compiled * 100) / total);
                    }

                    // write missile list.
                    for (ushort id = 1; id <= this.MissileCount; id++)
                    {
                        ThingType missile = this.Missiles[id];
                        if (!ThingTypeSerializer.WriteProperties(missile, version.Format, writer) ||
                            !ThingTypeSerializer.WriteTexturePatterns(missile, features, writer))
                        {
                            throw new Exception("Missiles list cannot be compiled.");
                        }
                    }

                    // update progress.
                    if (this.ProgressChanged != null)
                    {
                        compiled += this.MissileCount;
                        this.ProgressChanged(this, (compiled * 100) / total);
                    }
                }

                if (File.Exists(path))
                {
                    File.Delete(path);
                }

                File.Move(tmpPath, path);
            }

            this.FilePath       = path;
            this.Version        = version;
            this.ClientFeatures = features;
            this.Changed        = false;

            if (this.StorageCompiled != null)
            {
                this.StorageCompiled(this);
            }

            return(true);
        }
예제 #21
0
        private bool InternalLoad(string path, Core.Version version, ClientFeatures features, bool reloading)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException(nameof(path));
            }

            if (version == null)
            {
                throw new ArgumentNullException(nameof(version));
            }

            if (!File.Exists(path))
            {
                string message = $"File not found: {path}"; // TODO: ResourceManager.GetString("Exception.FileNotFound");
                throw new FileNotFoundException(message, path);
            }

            if (this.Compiling)
            {
                return(false);
            }

            if (this.Loaded)
            {
                if (reloading)
                {
                    this.stream.Close();
                    this.stream = null;
                }
                else
                {
                    return(true);
                }
            }

            if (features == ClientFeatures.None || features == ClientFeatures.Transparency)
            {
                features |= version.Value >= (ushort)DatFormat.Format_755 ? ClientFeatures.PatternZ : features;
                features |= version.Value >= (ushort)DatFormat.Format_960 ? ClientFeatures.Extended : features;
                features |= version.Value >= (ushort)DatFormat.Format_1050 ? ClientFeatures.FrameDurations : features;
                features |= version.Value >= (ushort)DatFormat.Format_1057 ? ClientFeatures.FrameGroups : features;
            }

            this.stream = new FileStream(path, FileMode.Open);
            this.reader = new BinaryReader(this.stream);

            uint signature = this.reader.ReadUInt32();

            if (signature != version.SprSignature)
            {
                string message = "Invalid SPR signature. Expected signature is {0:X} and loaded signature is {1:X}.";
                throw new Exception(string.Format(message, version.SprSignature, signature));
            }

            if ((features & ClientFeatures.Extended) == ClientFeatures.Extended)
            {
                this.headSize       = HeaderU32;
                this.rawSpriteCount = this.reader.ReadUInt32();
            }
            else
            {
                this.headSize       = HeaderU16;
                this.rawSpriteCount = this.reader.ReadUInt16();
            }

            this.FilePath       = path;
            this.Version        = version;
            this.ClientFeatures = features;
            this.transparency   = (features & ClientFeatures.Transparency) == ClientFeatures.Transparency ? true : false;
            this.Count          = this.rawSpriteCount;
            this.blankSprite    = new Sprite(0, this.transparency);
            this.Changed        = false;
            this.Loaded         = true;
            this.Disposed       = false;
            return(true);
        }
예제 #22
0
        private bool InternalCreate(Core.Version version, ClientFeatures features)
        {
            if (version == null)
            {
                throw new ArgumentNullException("version");
            }

            if (this.Loaded)
            {
                return true;
            }

            if (features == ClientFeatures.None || features == ClientFeatures.Transparency)
            {
                features |= version.Value >= (ushort)DatFormat.Format_755 ? ClientFeatures.PatternZ : features;
                features |= version.Value >= (ushort)DatFormat.Format_960 ? ClientFeatures.Extended : features;
                features |= version.Value >= (ushort)DatFormat.Format_1050 ? ClientFeatures.FrameDurations : features;
                features |= version.Value >= (ushort)DatFormat.Format_1057 ? ClientFeatures.FrameGroups : features;
            }

            this.Version = version;
            this.ClientFeatures = features;
            this.Items.Add(100, ThingType.Create(100, ThingCategory.Item));
            this.ItemCount = 100;
            this.Outfits.Add(1, ThingType.Create(1, ThingCategory.Outfit));
            this.OutfitCount = 1;
            this.Effects.Add(1, ThingType.Create(1, ThingCategory.Effect));
            this.EffectCount = 1;
            this.Missiles.Add(1, ThingType.Create(1, ThingCategory.Missile));
            this.MissileCount = 1;
            this.Changed = true;
            this.Loaded = true;
            this.Disposed = false;
            return true;
        }