예제 #1
0
        /// <summary>
        /// Reads a Game Maker project file
        /// </summary>
        public void ReadProject(string file)
        {
            // If the file does not exist, throw exception
            if (File.Exists(file) == false)
            {
                throw new Exception("The Game Maker project file does not exist.");
            }

            // Get file extension
            string ext = file.Substring(file.LastIndexOf('.')).ToLower();

            // If a GMS project file
            if (ext == ".gmx")
            {
                // Read in the project as a Game Maker Studio project and return
                ReadProjectGMS(file);
                return;
            }

            // Get file size
            FileInfo info   = new FileInfo(file);
            long     length = info.Length;

            // Create a new GM file reader
            using (GMFileReader reader = new GMFileReader(new FileStream(file, FileMode.Open, FileAccess.Read)))
            {
                // Progress event
                ProgressChanged("Starting project read...", reader.BaseStream.Position, length);

                // Read the magic number
                int id = reader.ReadGMInt();

                // If the magic number was incorrect, not a Game Maker project file
                if (id != 1234321)
                {
                    throw new Exception("Not a valid Game Maker project file.");
                }

                // Get Game Maker project file version
                int version = reader.ReadGMInt();

                // Check version
                switch (version)
                {
                case 500: this.GameMakerVersion = GMVersionType.GameMaker50; break;

                case 510: this.GameMakerVersion = GMVersionType.GameMaker51; break;

                case 520: this.GameMakerVersion = GMVersionType.GameMaker52; break;

                case 530: this.GameMakerVersion = GMVersionType.GameMaker53; break;

                case 600: this.GameMakerVersion = GMVersionType.GameMaker60; break;

                case 701: this.GameMakerVersion = GMVersionType.GameMaker70; break;

                case 800: this.GameMakerVersion = GMVersionType.GameMaker80; break;

                case 810: this.GameMakerVersion = GMVersionType.GameMaker81; break;
                }

                // Skip over reserved bytes
                if (version < 600)
                {
                    reader.ReadGMBytes(4);
                }

                // Game Maker 7 project file encryption
                if (version == 701)
                {
                    // Bill and Fred, psssttt they like each other ;)
                    int bill = reader.ReadGMInt();
                    int fred = reader.ReadGMInt();

                    // Skip bytes to treasure.
                    reader.ReadGMBytes(bill * 4);

                    // Get the seed for swap table
                    int seed = reader.ReadGMInt();

                    // Skip bytes to get out of the junk yard
                    reader.ReadGMBytes(fred * 4);

                    // Read first byte of Game id (Not encrypted)
                    byte b = reader.ReadByte();

                    // Set the seed
                    reader.SetSeed(seed);

                    // Read game id
                    id = reader.ReadGMInt(b);
                }
                else  // Read game id normally
                {
                    id = reader.ReadGMInt();
                }

                // Skip unknown bytes
                reader.ReadGMBytes(16);

                // Read settings
                ProgressChanged("Reading Settings...", reader.BaseStream.Position, length);

                // Read main project objects
                this.Settings = GMSettings.ReadSettings(reader);
                this.Settings.GameIdentifier = id;

                // If the version is greater than Game Maker 7.0
                if (version > 701)
                {
                    // Read triggers and constants.
                    this.Triggers           = GMTrigger.ReadTriggers(reader);
                    this.Settings.Constants = GMConstant.ReadConstants(reader);
                }

                // Read sounds
                ProgressChanged("Reading Sounds...", reader.BaseStream.Position, length);
                this.Sounds = GMSound.ReadSounds(reader);

                // Read sprites
                ProgressChanged("Reading Sprites...", reader.BaseStream.Position, length);
                this.Sprites = GMSprite.ReadSprites(reader);

                // Read backgrounds
                ProgressChanged("Reading Backgrounds...", reader.BaseStream.Position, length);
                this.Backgrounds = GMBackground.ReadBackgrounds(reader);

                // Read paths
                ProgressChanged("Reading Paths...", reader.BaseStream.Position, length);
                this.Paths = GMPath.ReadPaths(reader);

                // Read scripts
                ProgressChanged("Reading Scripts...", reader.BaseStream.Position, length);
                this.Scripts = GMScript.ReadScripts(reader);

                // Get version
                int version2 = reader.ReadGMInt();

                // Check version
                if (version2 != 440 && version2 != 540 && version2 != 800)
                {
                    throw new Exception("Unsupported Pre-Font/Pre-Data File object version.");
                }

                // If version is old, read data files else, read fonts.
                if (version2 == 440)
                {
                    // Read data files
                    ProgressChanged("Reading Data Files...", reader.BaseStream.Position, length);
                    this.DataFiles = GMDataFile.ReadDataFiles(reader);
                }
                else
                {
                    // Read fonts
                    ProgressChanged("Reading Fonts...", reader.BaseStream.Position, length);
                    this.Fonts = GMFont.ReadFonts(version2, reader);
                }

                // Read timelines
                ProgressChanged("Reading Timelines...", reader.BaseStream.Position, length);
                this.Timelines = GMTimeline.ReadTimelines(reader);

                // Read objects
                ProgressChanged("Reading Objects...", reader.BaseStream.Position, length);
                this.Objects = GMObject.ReadObjects(reader);

                // Read rooms
                ProgressChanged("Reading Rooms...", reader.BaseStream.Position, length);
                this.Rooms = GMRoom.ReadRooms(this.Objects, reader);

                // Read last ids for instances and tiles
                this.LastInstanceId = reader.ReadGMInt();
                this.LastTileId     = reader.ReadGMInt();

                // If the version is above 6.1, read include files and packages
                if (version >= 700)
                {
                    // Read includes
                    ProgressChanged("Reading Includes...", reader.BaseStream.Position, length);
                    this.Settings.Includes = GMInclude.ReadIncludes(reader);

                    // Read packages
                    ProgressChanged("Reading Packages...", reader.BaseStream.Position, length);
                    this.Packages.AddRange(GMPackage.ReadPackages(reader));
                }

                // Read game information
                ProgressChanged("Reading Game Information...", reader.BaseStream.Position, length);
                this.GameInformation = GMGameInformation.ReadGameInformation(reader);

                // Get version
                version = reader.ReadGMInt();

                // Check version
                if (version != 500)
                {
                    throw new Exception("Unsupported Post-Game Information object version.");
                }

                // Read libraries
                ProgressChanged("Reading Libraries...", reader.BaseStream.Position, length);
                this.Libraries = GMLibrary.ReadLibraries(reader);

                // Read project tree
                ProgressChanged("Reading Project Tree...", reader.BaseStream.Position, length);
                this.ProjectTree = GMNode.ReadTree(file.Substring(file.LastIndexOf(@"\") + 1), reader);

                // Progress event
                ProgressChanged("Finished Reading Project.", reader.BaseStream.Position, length);
            }
        }
예제 #2
0
        public static void Room(ProjectWriter writer, GMRoom self, GMProject proj)
        {
            writer.Write(self.Name);
            writer.Write(self.Version);

            writer.Write(self.Caption);
            writer.Write(self.Width);
            writer.Write(self.Height);
            writer.Write(self.Speed);
            writer.Write(self.Persistent);
            writer.Write(self.BackgroundColor);
            int val = self.DrawBackgroundColor ? 1 : 0;

            if (!self.ClearBGWithWindowColor)
            {
                val |= 0b10;
            }
            writer.Write(val);
            writer.Write(self.CreationCode);

            // -- Backgrounds
            writer.Write(self.Backgrounds.Count);
            foreach (var bg in self.Backgrounds)
            {
                writer.Write(bg.Visible);
                writer.Write(bg.IsForeground);
                if (bg.Background == null)
                {
                    writer.Write(-1);
                }
                else
                {
                    writer.Write(proj.Backgrounds.IndexOf(bg.Background));
                }
                writer.Write(bg.Position);
                writer.Write(bg.TileHorizontal);
                writer.Write(bg.TileVertical);
                writer.Write(bg.SpeedHorizontal);
                writer.Write(bg.SpeedVertical);
                writer.Write(bg.Stretch);
            }

            // -- Views
            writer.Write(self.EnableViews);
            writer.Write(self.Views.Count);
            foreach (var view in self.Views)
            {
                writer.Write(view.Visible);
                writer.Write(view.ViewCoords);
                writer.Write(view.PortCoords);
                writer.Write(view.BorderHor);
                writer.Write(view.BorderVert);
                writer.Write(view.HSpeed);
                writer.Write(view.VSpeed);
                if (view.ViewObject == null)
                {
                    writer.Write(-1);
                }
                else
                {
                    writer.Write(proj.Objects.IndexOf(view.ViewObject));
                }
            }

            // -- Room Instances
            writer.Write(self.Instances.Count);
            foreach (var inst in self.Instances)
            {
                if (inst.ID == -1)
                {
                    Console.WriteLine("Corrupted room instance found!");
                    continue;
                }
                writer.Write(inst.Position);
                writer.Write(proj.Objects.IndexOf(inst.Object));
                writer.Write(inst.ID);
                writer.Write(inst.CreationCode);
            }

            // -- Room Tiles
            writer.Write(self.Tiles.Count);
            foreach (var tile in self.Tiles)
            {
                writer.Write(tile.RoomPosition);
                writer.Write(proj.Backgrounds.IndexOf(tile.Background));
                writer.Write(tile.BGCoords);
                writer.Write(tile.Depth);
                writer.Write(tile.ID);
            }

            // -- in GMK 820 Physics data would go here, but PrikolLib does not support 820 GMK files and never will.
        }
예제 #3
0
        /// <summary>
        /// Reads a Game Maker Studio project file
        /// </summary>
        private void ReadProjectGMS(string file)
        {
            // Set version
            GameMakerVersion = GMVersionType.GameMakerStudio;

            // Path with project file removed
            string folder = file.Remove(file.LastIndexOf("\\"));

            // Set up resource directory strings
            Dictionary <GMResourceType, string> directories = new Dictionary <GMResourceType, string>();

            directories.Add(GMResourceType.Assets, file);
            directories.Add(GMResourceType.DataFiles, file);
            directories.Add(GMResourceType.Configs, file);
            directories.Add(GMResourceType.Constants, file);
            directories.Add(GMResourceType.Hash, file);
            directories.Add(GMResourceType.Backgrounds, folder + "\\" + "background");
            directories.Add(GMResourceType.Objects, folder + "\\" + "objects");
            directories.Add(GMResourceType.Rooms, folder + "\\" + "rooms");
            directories.Add(GMResourceType.Sprites, folder + "\\" + "sprites");
            directories.Add(GMResourceType.Sounds, folder + "\\" + "sound");
            directories.Add(GMResourceType.TimeLines, folder + "\\" + "timelines");
            directories.Add(GMResourceType.Shaders, folder + "\\" + "shaders");
            directories.Add(GMResourceType.Scripts, folder + "\\" + "scripts");
            directories.Add(GMResourceType.Paths, folder + "\\" + "paths");

            // Resource load index
            int index = 0;

            // Iterate through directories
            foreach (KeyValuePair <GMResourceType, string> item in directories)
            {
                // Increment directory index
                index++;

                // If the directory does not exist, continue
                if (Path.GetExtension(item.Value) != ".gmx" && !Directory.Exists(item.Value))
                {
                    continue;
                }

                // Progress changed
                ProgressChanged("Reading " + item.Key.ToString() + "...", index, directories.Count);

                // Load data based on resource type
                switch (item.Key)
                {
                case GMResourceType.Hash: Settings.Hash = ReadHashGMX(item.Value); break;

                case GMResourceType.Assets: ProjectTree = GMNode.ReadTreeGMX(item.Value); Assets = (List <string>)ProjectTree.Tag; break;

                case GMResourceType.DataFiles: DataFiles = GMDataFile.ReadDataFilesGMX(item.Value, out LastDataFileId); break;

                case GMResourceType.Sprites: Sprites = GMSprite.ReadSpritesGMX(item.Value, ref Assets); break;

                //case GMResourceType.Configs: Settings.Configs = GMSettings.GetConfigsGMX(item.Value); break;
                //case GMResourceType.Constants: Settings.Constants = GMSettings.ReadConstantsGMX(item.Value); break;
                case GMResourceType.Backgrounds: Backgrounds = GMBackground.ReadBackgroundsGMX(item.Value, ref Assets); break;

                case GMResourceType.Objects: Objects = GMObject.ReadObjectsGMX(item.Value, ref Assets); break;

                case GMResourceType.Rooms: Rooms = GMRoom.ReadRoomsGMX(item.Value, ref Assets, out LastTileId); break;
                    //case GMResourceType.TimeLines: Timelines = GMTimeline.ReadTimelinesGMX(item.Value, Assets); break;
                    //case GMResourceType.Sounds: Sounds = GMSound.ReadSoundsGMX(item.Value, ref Assets); break;
                    //case GMResourceType.Shaders: Shaders = GMShader.ReadShadersGMX(item.Value, ref Assets); break;
                    //case GMResourceType.Scripts: Scripts = GMScript.ReadScriptsGMX(item.Value, ref Assets); break;
                    //case GMResourceType.Paths: Paths = GMPath.ReadPathsGMX(item.Value, ref Assets); break;
                    //case GMResourceType.TimeLines: Timelines = GMTimeline.ReadTimelinesGMX(item.Value, Assets); break;
                }
            }

            // Retrieve tutorial data
            foreach (GMNode node in ProjectTree.Nodes)
            {
                // If the node is the tutorial state node and it has the nodes we're looking for
                if (node.ResourceType == GMResourceType.TutorialState && node.Nodes != null && node.Nodes.Length == 3)
                {
                    Settings.IsTutorial   = node.Nodes[0].Nodes == null ? Settings.IsTutorial : GMResource.GMXBool(node.Nodes[0].Nodes[0].Name, true);
                    Settings.TutorialName = node.Nodes[1].Nodes == null ? Settings.TutorialName : GMResource.GMXString(node.Nodes[1].Nodes[0].FilePath, "");
                    Settings.TutorialPage = node.Nodes[2].Nodes == null ? Settings.TutorialPage : GMResource.GMXInt(node.Nodes[2].Nodes[0].Name, 0);
                }
            }

            // Progress event
            ProgressChanged("Finished Reading Project.", index, directories.Count);
        }
예제 #4
0
        /// <summary>
        /// Reads rooms from GM file
        /// </summary>
        private GMList<GMRoom> ReadRooms(GMList<GMObject> objects)
        {
            // Get version.
            int version = ReadInt();

            // Check version.
            if (version != 420 && version != 800)
                throw new Exception("Unsupported Pre-Room object version.");

            // Create a new list of rooms.
            GMList<GMRoom> rooms = new GMList<GMRoom>();

            // Amount of room indexes.
            int num = ReadInt();

            // Iterate through rooms.
            for (int i = 0; i < num; i++)
            {
                // If version is 8.0, start inflate.
                if (version == 800)
                    Decompress();

                // If the room at index does not exists, continue.
                if (ReadBool() == false)
                {
                    rooms.LastId++;
                    EndDecompress();
                    continue;
                }

                // Create a room object.
                GMRoom room = new GMRoom();

                // Set room id.
                room.Id = i;

                // Read room data.
                room.Name = ReadString();

                // If version is 8.0, get last changed.
                if (version == 800)
                    room.LastChanged = ReadDouble();

                // Get version.
                int version2 = ReadInt();

                // Check version.
                if (version2 != 500 && version2 != 520 && version2 != 541)
                    throw new Exception("Unsupported Room object version.");

                // Read room data.
                room.Caption = ReadString();
                room.Width = ReadInt();
                room.Height = ReadInt();
                room.SnapY = ReadInt();
                room.SnapX = ReadInt();

                // Versions greater than 5.1 support isometric grid.
                if (version2 > 500)
                    room.IsometricGrid = ReadBool();

                room.Speed = ReadInt();
                room.Persistent = ReadBool();
                room.BackgroundColor = ReadInt();
                room.DrawBackgroundColor = ReadBool();
                room.CreationCode = ReadString();

                // Create new parallax array.
                room.Parallaxes = new GMParallax[ReadInt()];

                // Iterate through parallaxs.
                for (int j = 0; j < room.Parallaxes.Length; j++)
                {
                    // Create a new parallax object.
                    room.Parallaxes[j] = new GMParallax();

                    // Read room parallax data.
                    room.Parallaxes[j].Visible = ReadBool();
                    room.Parallaxes[j].Foreground = ReadBool();
                    room.Parallaxes[j].BackgroundId = ReadInt();
                    room.Parallaxes[j].X = ReadInt();
                    room.Parallaxes[j].Y = ReadInt();
                    room.Parallaxes[j].TileHorizontally = ReadBool();
                    room.Parallaxes[j].TileVertically = ReadBool();
                    room.Parallaxes[j].HorizontalSpeed = ReadInt();
                    room.Parallaxes[j].VerticalSpeed = ReadInt();

                    // Versions greater than 5.1 support parallax stretching.
                    if (version2 > 500)
                        room.Parallaxes[j].Stretch = ReadBool();
                }

                // Read room data.
                room.EnableViews = ReadBool();

                // Create new view array.
                room.Views = new GMView[ReadInt()];

                // Iterate through views
                for (int k = 0; k < room.Views.Length; k++)
                {
                    // Create new view object.
                    room.Views[k] = new GMView();

                    // Read room view data.
                    room.Views[k].Visible = ReadBool();
                    room.Views[k].ViewX = ReadInt();
                    room.Views[k].ViewY = ReadInt();
                    room.Views[k].ViewWidth = ReadInt();
                    room.Views[k].ViewHeight = ReadInt();
                    room.Views[k].PortX = ReadInt();
                    room.Views[k].PortY = ReadInt();

                    // Versions greater than 5.3 support port dimensions.
                    if (version2 > 520)
                    {
                        room.Views[k].PortWidth = ReadInt();
                        room.Views[k].PortHeight = ReadInt();
                    }

                    // Read room view data.
                    room.Views[k].HorizontalBorder = ReadInt();
                    room.Views[k].VerticalBorder = ReadInt();
                    room.Views[k].HorizontalSpeed = ReadInt();
                    room.Views[k].VerticalSpeed = ReadInt();
                    room.Views[k].ObjectToFollow = ReadInt();
                }

                // Create a new array of instances.
                room.Instances = new GMInstance[ReadInt()];

                // Iterate through room instances.
                for (int l = 0; l < room.Instances.Length; l++)
                {
                    // Create new instance.
                    room.Instances[l] = new GMInstance();

                    // Read room instance data.
                    room.Instances[l].X = ReadInt();
                    room.Instances[l].Y = ReadInt();
                    room.Instances[l].ObjectId = ReadInt();
                    room.Instances[l].Id = ReadInt();

                    // Versions greater than 5.1 support creation code and instance locking.
                    if (version2 > 500)
                    {
                        // Read room instance data.
                        room.Instances[l].CreationCode = ReadString();
                        room.Instances[l].Locked = ReadBool();
                    }

                    // Get the object the instance references.
                    GMObject obj = objects.Find(delegate(GMObject o) { return o.Id == room.Instances[l].ObjectId; });

                    // If the object was found, set instance name and depth.
                    if (obj != null)
                    {
                        // Read room instance data.
                        room.Instances[l].Name = obj.Name;
                        room.Instances[l].Depth = obj.Depth;
                    }

                    // Skipped reserved bytes.
                    if (version2 < 520)
                        ReadBytes(8);
                }

                // Create a new array of tiles.
                room.Tiles = new GMTile[ReadInt()];

                // Iterate through room tiles.
                for (int m = 0; m < room.Tiles.Length; m++)
                {
                    // Create new tile object.
                    room.Tiles[m] = new GMTile();

                    // Read room tile data.
                    room.Tiles[m].X = ReadInt();
                    room.Tiles[m].Y = ReadInt();
                    room.Tiles[m].BackgroundId = ReadInt();
                    room.Tiles[m].BackgroundX = ReadInt();
                    room.Tiles[m].BackgroundY = ReadInt();
                    room.Tiles[m].Width = ReadInt();
                    room.Tiles[m].Height = ReadInt();
                    room.Tiles[m].Depth = ReadInt();
                    room.Tiles[m].Id = ReadInt();

                    // Versions greater than 5.1 support tile locking.
                    if (version2 > 500)
                        room.Tiles[m].Locked = ReadBool();
                }

                // Read room data.
                room.RememberWindowSize = ReadBool();
                room.EditorWidth = ReadInt();
                room.EditorHeight = ReadInt();
                room.ShowGrid = ReadBool();
                room.ShowObjects = ReadBool();
                room.ShowTiles = ReadBool();
                room.ShowBackgrounds = ReadBool();
                room.ShowForegrounds = ReadBool();
                room.ShowViews = ReadBool();
                room.DeleteUnderlyingObjects = ReadBool();
                room.DeleteUnderlyingTiles = ReadBool();

                // Versions greater than 5.3 don't support tile settings.
                if (version2 > 520)
                {
                    // Read room tile data.
                    room.CurrentTab = (TabSetting)(ReadInt());
                    room.ScrollBarX = ReadInt();
                    room.ScrollBarY = ReadInt();
                }
                else
                {
                    // Read room tile data.
                    room.TileWidth = ReadInt();
                    room.TileHeight = ReadInt();
                    room.TileHorizontalSeperation = ReadInt();
                    room.TileVerticalSeperation = ReadInt();
                    room.TileHorizontalOffset = ReadInt();
                    room.TileVerticalOffset = ReadInt();
                    room.CurrentTab = (TabSetting)(ReadInt());
                    room.ScrollBarX = ReadInt();
                    room.ScrollBarY = ReadInt();
                }

                // End object inflate.
                EndDecompress();

                // Set room.
                rooms.Add(room);
            }

            // Return rooms
            return rooms;
        }
예제 #5
0
        public override void ConvertData(ProjectFile pf, int index)
        {
            // TODO use asset refs eventually
            var dataCode = pf.DataHandle.GetChunk <GMChunkCODE>()?.List;
            var dataSeqn = pf.DataHandle.GetChunk <GMChunkSEQN>()?.List;

            string getCode(int ind)
            {
                if (ind < 0)
                {
                    return(null);
                }
                if (dataCode == null)
                {
                    return(ind.ToString());
                }
                return(dataCode[ind].Name?.Content);
            }

            GMRoom asset = (GMRoom)pf.Rooms[index].DataAsset;

            AssetRoom projectAsset = new AssetRoom()
            {
                Name                = asset.Name?.Content,
                Caption             = asset.Caption?.Content,
                Width               = asset.Width,
                Height              = asset.Height,
                Speed               = asset.Speed,
                Persistent          = asset.Persistent,
                BackgroundColor     = asset.BackgroundColor,
                DrawBackgroundColor = asset.DrawBackgroundColor,
                CreationCode        = getCode(asset.CreationCodeID),
                EnableViews         = (asset.Flags & GMRoom.RoomFlags.EnableViews) == GMRoom.RoomFlags.EnableViews,
                ShowColor           = (asset.Flags & GMRoom.RoomFlags.ShowColor) == GMRoom.RoomFlags.ShowColor,
                ClearDisplayBuffer  = (asset.Flags & GMRoom.RoomFlags.ClearDisplayBuffer) == GMRoom.RoomFlags.ClearDisplayBuffer,
                Backgrounds         = new(asset.Backgrounds.Count),
                Views               = new(asset.Views.Count),
                GameObjects         = new(asset.GameObjects.Count),
                Tiles               = new(asset.Tiles.Count),
                Physics             = new()
                {
                    Enabled        = asset.Physics,
                    Top            = asset.Top,
                    Left           = asset.Left,
                    Right          = asset.Right,
                    Bottom         = asset.Bottom,
                    GravityX       = asset.GravityX,
                    GravityY       = asset.GravityY,
                    PixelsToMeters = asset.PixelsToMeters
                }
            };

            foreach (var bg in asset.Backgrounds)
            {
                projectAsset.Backgrounds.Add(new AssetRoom.Background()
                {
                    Enabled    = bg.Enabled,
                    Foreground = bg.Foreground,
                    Asset      = bg.BackgroundID >= 0 ? pf.Backgrounds[bg.BackgroundID].Name : null,
                    X          = bg.X,
                    Y          = bg.Y,
                    TileX      = bg.TileX,
                    TileY      = bg.TileY,
                    SpeedX     = bg.SpeedX,
                    SpeedY     = bg.SpeedY,
                    Stretch    = bg.Stretch
                });
            }

            foreach (var view in asset.Views)
            {
                projectAsset.Views.Add(new AssetRoom.View()
                {
                    Enabled      = view.Enabled,
                    ViewX        = view.ViewX,
                    ViewY        = view.ViewY,
                    ViewWidth    = view.ViewWidth,
                    ViewHeight   = view.ViewHeight,
                    PortX        = view.PortX,
                    PortY        = view.PortY,
                    PortWidth    = view.PortWidth,
                    PortHeight   = view.PortHeight,
                    BorderX      = view.BorderX,
                    BorderY      = view.BorderY,
                    SpeedX       = view.SpeedX,
                    SpeedY       = view.SpeedY,
                    FollowObject = view.FollowObjectID >= 0 ? pf.Objects[view.FollowObjectID].Name : null
                });
            }

            foreach (var obj in asset.GameObjects)
            {
                var newObj = new AssetRoom.GameObject()
                {
                    X            = obj.X,
                    Y            = obj.Y,
                    Asset        = obj.ObjectID >= 0 ? pf.Objects[obj.ObjectID].Name : null,
                    InstanceID   = obj.InstanceID,
                    CreationCode = getCode(obj.CreationCodeID),
                    ScaleX       = obj.ScaleX,
                    ScaleY       = obj.ScaleY,
                    Color        = obj.Color,
                    Angle        = obj.Angle,
                    ImageSpeed   = obj.ImageSpeed,
                    ImageIndex   = obj.ImageIndex
                };
                if (pf.DataHandle.VersionInfo.RoomObjectPreCreate)
                {
                    newObj.PreCreateCode = getCode(obj.PreCreateCodeID);
                }
                projectAsset.GameObjects.Add(newObj);
            }

            foreach (var tile in asset.Tiles)
            {
                var newTile = new AssetRoom.Tile()
                {
                    X       = tile.X,
                    Y       = tile.Y,
                    SourceX = tile.SourceX,
                    SourceY = tile.SourceY,
                    Width   = tile.Width,
                    Height  = tile.Height,
                    Depth   = tile.Depth,
                    ID      = tile.Depth,
                    ScaleX  = tile.ScaleX,
                    ScaleY  = tile.ScaleY,
                    Color   = tile.Color
                };
                if (pf.DataHandle.VersionInfo.IsNumberAtLeast(2))
                {
                    newTile.Asset = tile.AssetID >= 0 ? pf.Sprites[tile.AssetID].Name : null;
                }
                else
                {
                    newTile.Asset = tile.AssetID >= 0 ? pf.Backgrounds[tile.AssetID].Name : null;
                }
                projectAsset.Tiles.Add(newTile);
            }

            if (pf.DataHandle.VersionInfo.IsNumberAtLeast(2))
            {
                projectAsset.Layers = new List <AssetRoom.Layer>(asset.Layers.Count);
                foreach (var layer in asset.Layers)
                {
                    var newLayer = new AssetRoom.Layer()
                    {
                        Name    = layer.Name?.Content,
                        ID      = layer.ID,
                        Depth   = layer.Depth,
                        OffsetX = layer.OffsetX,
                        OffsetY = layer.OffsetY,
                        HSpeed  = layer.HSpeed,
                        VSpeed  = layer.VSpeed,
                        Visible = layer.Visible
                    };

                    switch (layer.Kind)
                    {
                    case GMRoom.Layer.LayerKind.Background:
                        newLayer.Background = new AssetRoom.Layer.LayerBackground()
                        {
                            Visible            = layer.Background.Visible,
                            Foreground         = layer.Background.Foreground,
                            Sprite             = layer.Background.SpriteID >= 0 ? pf.Sprites[layer.Background.SpriteID].Name : null,
                            TileHorz           = layer.Background.TileHorz,
                            TileVert           = layer.Background.TileVert,
                            Stretch            = layer.Background.Stretch,
                            Color              = layer.Background.Color,
                            FirstFrame         = layer.Background.FirstFrame,
                            AnimationSpeed     = layer.Background.AnimationSpeed,
                            AnimationSpeedType = layer.Background.AnimationSpeedType
                        };
                        break;

                    case GMRoom.Layer.LayerKind.Instances:
                        newLayer.Instances = layer.Instances;
                        break;

                    case GMRoom.Layer.LayerKind.Assets:
                        newLayer.Assets = new AssetRoom.Layer.LayerAssets()
                        {
                            LegacyTiles = new(layer.Assets.LegacyTiles.Count),
                            Sprites     = new(layer.Assets.Sprites.Count)
                        };

                        foreach (var tile in layer.Assets.LegacyTiles)
                        {
                            var newTile = new AssetRoom.Tile()
                            {
                                X       = tile.X,
                                Y       = tile.Y,
                                SourceX = tile.SourceX,
                                SourceY = tile.SourceY,
                                Width   = tile.Width,
                                Height  = tile.Height,
                                Depth   = tile.Depth,
                                ID      = tile.Depth,
                                ScaleX  = tile.ScaleX,
                                ScaleY  = tile.ScaleY,
                                Color   = tile.Color,
                                Asset   = tile.AssetID >= 0 ? pf.Sprites[tile.AssetID].Name : null
                            };
                            newLayer.Assets.LegacyTiles.Add(newTile);
                        }

                        foreach (var spr in layer.Assets.Sprites)
                        {
                            newLayer.Assets.Sprites.Add(new()
                            {
                                Name               = spr.Name?.Content,
                                Asset              = spr.AssetID >= 0 ? pf.Sprites[spr.AssetID].Name : null,
                                X                  = spr.X,
                                Y                  = spr.Y,
                                ScaleX             = spr.ScaleX,
                                ScaleY             = spr.ScaleY,
                                Color              = spr.Color,
                                AnimationSpeed     = spr.AnimationSpeed,
                                AnimationSpeedType = spr.AnimationSpeedType,
                                FrameIndex         = spr.FrameIndex,
                                Rotation           = spr.Rotation
                            });
                        }

                        if (pf.DataHandle.VersionInfo.IsNumberAtLeast(2, 3))
                        {
                            newLayer.Assets.Sequences = new(layer.Assets.Sequences.Count);
                            foreach (var seq in layer.Assets.Sequences)
                            {
                                newLayer.Assets.Sequences.Add(new()
                                {
                                    Name               = seq.Name?.Content,
                                    Asset              = seq.AssetID >= 0 ? dataSeqn[seq.AssetID].Name?.Content : null,
                                    X                  = seq.X,
                                    Y                  = seq.Y,
                                    ScaleX             = seq.ScaleX,
                                    ScaleY             = seq.ScaleY,
                                    Color              = seq.Color,
                                    AnimationSpeed     = seq.AnimationSpeed,
                                    AnimationSpeedType = seq.AnimationSpeedType,
                                    FrameIndex         = seq.FrameIndex,
                                    Rotation           = seq.Rotation
                                });
                            }

                            if (!pf.DataHandle.VersionInfo.IsNumberAtLeast(2, 3, 2))
                            {
                                newLayer.Assets.NineSlices = new();
                                foreach (var spr in layer.Assets.NineSlices)
                                {
                                    newLayer.Assets.NineSlices.Add(new()
                                    {
                                        Name               = spr.Name?.Content,
                                        Asset              = spr.AssetID >= 0 ? pf.Sprites[spr.AssetID].Name : null,
                                        X                  = spr.X,
                                        Y                  = spr.Y,
                                        ScaleX             = spr.ScaleX,
                                        ScaleY             = spr.ScaleY,
                                        Color              = spr.Color,
                                        AnimationSpeed     = spr.AnimationSpeed,
                                        AnimationSpeedType = spr.AnimationSpeedType,
                                        FrameIndex         = spr.FrameIndex,
                                        Rotation           = spr.Rotation
                                    });
                                }
                            }
                        }
                        break;

                    case GMRoom.Layer.LayerKind.Tiles:
                        newLayer.Tiles = new()
                        {
                            Background = layer.Tiles.BackgroundID >= 0 ? pf.Backgrounds[layer.Tiles.BackgroundID].Name : null,
                            TilesX     = layer.Tiles.TilesX,
                            TilesY     = layer.Tiles.TilesY,
                            TileData   = layer.Tiles.TileData
                        };
                        break;

                    case GMRoom.Layer.LayerKind.Effect:
                        newLayer.Effect = new()
                        {
                            EffectType = layer.Effect.EffectType?.Content,
                            Properties = new(layer.Effect.Properties.Count)
                        };
                        foreach (var prop in layer.Effect.Properties)
                        {
                            newLayer.Effect.Properties.Add(new()
                            {
                                Kind  = prop.Kind,
                                Name  = prop.Name?.Content,
                                Value = prop.Value?.Content
                            });
                        }
                        break;
                    }

                    projectAsset.Layers.Add(newLayer);
                }

                if (pf.DataHandle.VersionInfo.IsNumberAtLeast(2, 3))
                {
                    projectAsset.Sequences = new(asset.SequenceIDs.Count);
                    foreach (int seq in asset.SequenceIDs)
                    {
                        projectAsset.Sequences.Add(seq >= 0 ? dataSeqn[seq].Name?.Content : null);
                    }
                }
            }

            pf.Rooms[index].Asset = projectAsset;
        }
예제 #6
0
        /// <summary>
        /// Sets the given Game Maker room properties to GMare project room properties
        /// </summary>
        /// <param name="room">The room to set properties of</param>
        /// <param name="id">Id of the room</param>
        /// <returns>If the room property set was sucessful</returns>
        private bool SetRoomProperties(GMRoom room, int id)
        {
            // Set room properties
            room.Id              = id == -1 ? room.Id : id;
            room.Name            = txtName.Text;
            room.BackgroundColor = GMUtilities.ColorToGMColor(App.Room.BackColor);
            room.Width           = App.Room.Width;
            room.Height          = App.Room.Height;
            room.TileWidth       = App.Room.Backgrounds[0].TileWidth;
            room.TileHeight      = App.Room.Backgrounds[0].TileHeight;
            room.Caption         = App.Room.Caption;
            room.CreationCode    = App.Room.CreationCode;
            room.Speed           = App.Room.Speed;
            room.Persistent      = App.Room.Persistent;

            // If exporting tiles, set tiles
            if (chkWriteTiles.Checked)
            {
                // Get the game maker background selected
                GMBackground background = (GMBackground)lstBackgrounds.SelectedItem;

                // If the selected background dimensions do not match the GMare project's background
                if (chkWriteTiles.Checked && (App.Room.Backgrounds[0].Image.Width != background.Width || App.Room.Backgrounds[0].Image.Height != background.Height))
                {
                    // Give warning, and cancel export
                    DialogResult result = MessageBox.Show("The selected background's size does not match the background used for this room. Please select a background that is the same size as the used background.",
                                                          "GMare", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);

                    return(false);
                }

                // Copy the room's background, set the game maker background id
                GMareBackground gmareBackground = App.Room.Backgrounds[0].Clone();
                gmareBackground.GameMakerId = background.Id;
                gmareBackground.Name        = background.Name;

                // Get tile array
                GMTile[] tiles = App.Room.GMareTilesToGMTiles(_project.LastTileId, gmareBackground, chkOptimizeTiles.Checked);

                // Set unique names
                foreach (GMTile tile in tiles)
                {
                    tile.Name = GetUniqueName(true);
                }

                // Set the room's tiles
                room.Tiles = tiles;
            }

            // If the room's instances should be written, write instances
            if (chkWriteInstances.Checked)
            {
                room.Instances = SetInstances();

                // If no instances, return  unsuccessful
                if (room.Instances == null)
                {
                    return(false);
                }
            }

            // Successful
            return(true);
        }
예제 #7
0
        /// <summary>
        /// Ok button clicked
        /// </summary>
        private void butExport_Click(object sender, EventArgs e)
        {
            try
            {
                // Get the currently selected node
                GMNode node = tvRooms.SelectedNode.Tag as GMNode;

                // Create a new room
                GMRoom room;

                // If the node is a child node
                if (node.NodeType == GMNodeType.Child)
                {
                    // Give warning about an overwrite
                    DialogResult result = MessageBox.Show("Are you sure you want to overwrite room: " + node.Name + "?", "GMare",
                                                          MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2);

                    // If not ok, return
                    if (result != DialogResult.Yes)
                    {
                        return;
                    }
                }

                // Create a backup of the original project file
                string filePath = MakeBackup();

                // If the backup failed, return, else write the file
                if (filePath == "")
                {
                    return;
                }

                // If the node is being overwritten, overwrite, else add the node
                if (node.NodeType == GMNodeType.Child)
                {
                    // Find the room to overwrite
                    room = _project.Rooms.Find(r => r.Id == node.Id);

                    // Set room properties
                    if (!SetRoomProperties(room, -1))
                    {
                        // Notify the user that the export failed
                        MessageBox.Show("An error occurred while exporting the room, export aborted.", "GMare",
                                        MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                        return;
                    }
                }
                else
                {
                    // Check for any resource doubles
                    foreach (string asset in _project.Assets)
                    {
                        // If the asset already exists, return
                        if (asset == txtName.Text)
                        {
                            MessageBox.Show("The game resource name already exists. Please use a unique name for this room. Export aborted.", "GMare",
                                            MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
                            return;
                        }
                    }

                    // Create a new room
                    room = new GMRoom();

                    // Set room properties
                    if (!SetRoomProperties(room, _project.Rooms.LastId++))
                    {
                        // Give warning about an overwrite
                        MessageBox.Show("An error occurred while exporting the room, export aborted.", "GMare",
                                        MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                        return;
                    }

                    // Add the room to the project
                    _project.Rooms.Add(room);

                    // Increase the amount of children for parent node
                    (tvRooms.SelectedNode.Tag as GMNode).Children++;

                    // Create a new tree node
                    TreeNode treeNode = new TreeNode(room.Name);

                    // Create a new Game Maker node
                    GMNode newNode = new GMNode();
                    newNode.Name            = room.Name;
                    newNode.NodeType        = GMNodeType.Child;
                    newNode.ResourceType    = GMResourceType.Rooms;
                    newNode.ResourceSubType = GMResourceSubType.Room;
                    newNode.Id       = room.Id;
                    newNode.FilePath = "rooms\\" + room.Name;

                    // Set the tree node tag to Game Maker node
                    treeNode.Tag        = newNode;
                    treeNode.ImageIndex = 2;

                    // Add the new node to the tree
                    tvRooms.SelectedNode.Nodes.Add(treeNode);
                }

                // Set room nodes
                _project.ProjectTree.Nodes[GetResourceIndex(GMResourceType.Rooms)] = GMUtilities.GetGMNodeFromTreeNode(tvRooms.Nodes[0]);

                // If refactor tiles, refactor
                if (chkRefactorTiles.Checked == true)
                {
                    _project.RefactorTileIds();
                }

                // If refactor instances, refactor
                if (chkRefactorInstances.Checked == true)
                {
                    _project.RefactorInstanceIds();
                }

                // If a game maker studio project and there is room data, wirte project
                if (_project.GameMakerVersion == GMVersionType.GameMakerStudio)
                {
                    // If the room was never created, notify user
                    if (room == null)
                    {
                        MessageBox.Show("There was an error creating the room to export. Export failed.", "GMare",
                                        MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                    }
                    else
                    {
                        // NOTE: Normally I would not do things this way. It should be the data that drives
                        // the project file creation. However, we're only changing the room portion of the
                        // project and it's just safer, as of now, to write only the project file and the
                        // room vs. writing the entire project out. Luckily GM:S is modular and allows that
                        // to happen
                        GameMaker.Resource.GMNode.WriteTreeGMX(_projectPath, ref _project);
                        GameMaker.Resource.GMRoom.WriteRoomGMX(room, Path.GetDirectoryName(_projectPath) + "\\" + "rooms");
                    }
                }
                // Legacy Game Maker project write
                else
                {
                    _writer.WriteGMProject(_projectPath, _project, _project.GameMakerVersion);
                }

                // Display success message
                if (MessageBox.Show("Export complete. A backup of the original project was made. Do you want to open the directory it was copied to?", "GMare",
                                    MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
                {
                    Process.Start(filePath);
                }

                // Close the form
                Close();
            }
            catch (Exception)
            {
                // Notify the user that the export failed
                MessageBox.Show("An error occurred while exporting the room, export aborted.", "GMare",
                                MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
            }
        }