/// <summary> /// Gets a GMare background from imported backgrounds /// </summary> /// <returns>A GMare background</returns> private GMareBackground GetBackground() { // Create new background GMareBackground background = null; // If an item was selected if (lstBackgrounds.SelectedItem != null) { // Get GMare vackground from Game Maker background GMBackground back = lstBackgrounds.SelectedItem as GMBackground; // Set properties background = new GMareBackground(); background.GameMakerId = back.Id; background.Name = back.Name; background.OffsetX = back.HorizontalOffset; background.OffsetY = back.VerticalOffset; background.SeparationX = back.HorizontalSeperation; background.SeparationY = back.VerticalSeperation; background.TileWidth = back.TileWidth; background.TileHeight = back.TileHeight; background.Image = new Graphics.PixelMap(GMUtilities.GetBitmap(back.Image)); // If the background is transparent if (back.Transparent == true) { background.Image.UseKey = true; background.Image.ColorKey = Color.FromArgb(background.Image[0, background.Image.Height - 1]); } } // Return converted background return(background); }
private GMProjectWriter _writer = new GMProjectWriter(); // Project writer #endregion #region Constructor /// <summary> /// Constructs a new game maker export form /// </summary> /// <param name="projectPath">Path to a Game Maker project</param> public ExportGMProjectForm(GMProject project, string projectPath) { InitializeComponent(); // Set image keys GMUtilities.ImageKeyGroup = imgProjectTree.Images.Keys[0]; GMUtilities.ImageKeyGroupSelected = imgProjectTree.Images.Keys[1]; GMUtilities.ImageKeyRoom = imgProjectTree.Images.Keys[2]; GMUtilities.ImageKeyRoomSelected = imgProjectTree.Images.Keys[2]; // Set project target Game Maker path _projectPath = projectPath; // Set Game Maker project _project = project; // Populate the backgrounds listbox foreach (GMBackground background in _project.Backgrounds) { // If the background has image data, add it to the list if (background.Image.Data != null) { lstBackgrounds.Items.Add(background); } } // If there is at least one item to select, do so if (lstBackgrounds.Items.Count > 0) { lstBackgrounds.SelectedIndex = 0; } // The object node index int roomIndex = GetResourceIndex(GMResourceType.Rooms); // If no object node was found, return if (roomIndex == -1) { return; } // Add room nodes to treeview //tvRooms.Nodes.Add(GMUtilities.GetTreeNodeFromGMNode(_project, _project.ProjectTree, null)); tvRooms.Nodes.Add(GMUtilities.GetTreeNodeFromGMNode(_project, _project.ProjectTree.Nodes[roomIndex], null)); tvRooms.SelectedNode = tvRooms.Nodes[0]; tvRooms.Nodes[0].Expand(); // Set name of room in text box txtName.Text = App.Room.Name; // Verify requistes Verify(); }
/// <summary> /// On get glyph /// </summary> public override GDI.Bitmap OnGetGlyph(DrawItemEventArgs e) { // Do action based on listbox type switch (_listboxMode) { case ListboxType.Backgrounds: // Get background GMBackground background = Items[e.Index] as GMBackground; // If the background is empty, return null if (background == null) { return(null); } // Image to draw GDI.Bitmap image = null; // Get the background image if (background.Image != null) { image = ScaleBitmap(GMUtilities.GetBitmap(background.Image), _cellSize.Width, _cellSize.Height); } // If the image is still empty, create blank image if (image == null) { image = new GDI.Bitmap(_cellSize.Width, _cellSize.Height); } return(image); case ListboxType.Instances: // Get the instance from the list, also get the parent object of the instance GMareInstance instance = Items[e.Index] as GMareInstance; // If there is no instance or room, return null if (instance == null || App.Room == null) { return(null); } GMareObject gmObject = App.Room.Objects.Find(o => instance.ObjectId == o.Resource.Id); // If the instance or object or object image is empty, return default glyph if (instance == null || gmObject == null || gmObject.Image == null) { return(GMare.Properties.Resources.instance); } // Create a new glyph GDI.Bitmap glyph = new GDI.Bitmap(CellSize.Width * 2 + 2, CellSize.Height); GDI.Bitmap icon = ScaleImage((GDI.Bitmap)gmObject.Image.ToBitmap(), CellSize.Width, CellSize.Height); GDI.Graphics gfx = GDI.Graphics.FromImage(glyph); gfx.DrawImageUnscaled(icon, GDI.Point.Empty); // If there is creation code on the instance, show an icon for it if (instance.CreationCode != string.Empty) { gfx.DrawImageUnscaled(GMare.Properties.Resources.script, new GDI.Point(icon.Width + 2, 0)); } // Return glyph return(glyph); case ListboxType.Objects: // Get the object GMareObject gmObject2 = Items[e.Index] == null ? null : (Items[e.Index] as GMareObject); // If the instance or object or object image is empty, return default glyph if (gmObject2 == null || gmObject2.Image == null) { return(GMare.Properties.Resources.instance); } // Create a new glyph GDI.Bitmap glyph2 = new GDI.Bitmap(CellSize.Width * 2 + 2, CellSize.Height); GDI.Bitmap icon2 = ScaleImage((GDI.Bitmap)gmObject2.Image.ToBitmap(), CellSize.Width, CellSize.Height); GDI.Graphics gfx2 = GDI.Graphics.FromImage(glyph2); gfx2.DrawImageUnscaled(icon2, GDI.Point.Empty); // Return glyph return(glyph2); default: return(Glyph); } }
/// <summary> /// Checks existing instances against newly imported objects /// </summary> /// <param name="project">The Game Maker project to check against</param> private static void CheckInstances(GMProject project) { // If no instances exist, return if (App.Room.Instances.Count == 0) { return; } // Get object node List <Image> images = new List <Image>(); TreeNode root = GMUtilities.GetTreeNodeFromGMNode(project, project.ProjectTree.Nodes[7], images); // A list of checked object resources Dictionary <int, GMResource> ids = new Dictionary <int, GMResource>(); // A list of object nodes List <TreeNode> nodes = new List <TreeNode>(); // Get all the child nodes foreach (TreeNode node in root.Nodes) { nodes.Add(node); } // Iterate through existing instances foreach (GMareInstance instance in App.Room.Instances) { // If the instance's resource id does not match any new objects if (project.Objects.Find(o => o.Id == instance.ObjectId || o.Name == instance.ObjectName) == null) { // If the id check has already processed the instance's object id if (ids.ContainsKey(instance.ObjectId) == true) { // Set new instance data. int key = instance.ObjectId; instance.ObjectId = ids[key].Id; instance.ObjectName = ids[key].Name; continue; } // Get original glyph graphic Bitmap glyph = App.Room.Objects.Find(o => o.Resource.Id == instance.ObjectId).Image.ToBitmap(); // Give the user a choice of either replacing the instance's parent object id, or just delete them using (InstanceConflictForm form = new InstanceConflictForm(nodes.ToArray(), instance.ObjectName, images.ToArray(), glyph)) { // Show the instance options form form.ShowDialog(); // Set resource as one that has been checked ids.Add(instance.ObjectId, form.Object); // Iterate through blocks foreach (GMareInstance block in App.Room.Blocks) { if (block.ObjectId == instance.ObjectId) { block.ObjectId = form.Object.Id; block.ObjectName = form.Object.Name; } } // Set instance with new data instance.ObjectId = form.Object.Id; instance.ObjectName = form.Object.Name; } } } // Dispose foreach (Image img in images) { img.Dispose(); } // Remove all instances that have an empty id App.Room.Instances.RemoveAll(i => i.ObjectId == -1); App.Room.Blocks.RemoveAll(b => b.ObjectId == -1); }
/// <summary> /// Reads sprites from Game Maker project file. /// </summary> public static GMList <GMSprite> ReadSpritesGMX(string directory, ref List <string> assets) { // A list of sprites GMList <GMSprite> sprites = new GMList <GMSprite>(); sprites.AutoIncrementIds = false; // Iterate through .gmx files in the directory foreach (string file in Directory.GetFiles(directory, "*.gmx")) { // Set name of the sprite string name = GetResourceName(file); // If the file is not in the asset list, it has been orphaned, continue if (!assets.Contains(name)) { continue; } // Create a dictionary of sprite properties Dictionary <string, string> properties = new Dictionary <string, string>(); foreach (GMXSpriteProperty property in Enum.GetValues(typeof(GMXSpriteProperty))) { properties.Add(GMXEnumString(property), ""); } // Local variables and texture group strings List <GMImage> subImages = new List <GMImage>(); string textureGroup = GMXEnumString(GMXSpriteProperty.TextureGroup); string textureGroup0 = GMXEnumString(GMXSpriteProperty.TextureGroup0); // Create an xml reader using (XmlReader reader = XmlReader.Create(file)) { // Seek to content reader.MoveToContent(); // Read the GMX file while (reader.Read()) { // If the node is not an element, continue if (reader.NodeType != XmlNodeType.Element) { continue; } // Get the element name string nodeName = reader.Name; // Read element reader.Read(); // If the element value is null or empty, continue if (String.IsNullOrEmpty(reader.Value)) { continue; } // If the element is a frame element create subimage, else normal property if (nodeName.ToLower() == GMXEnumString(GMXSpriteProperty.Frame).ToLower()) { // Create a sub image and set the image path GMImage subImage = new GMImage(); subImage.Compressed = false; subImage.FilePath = reader.Value; subImage.Data = GMUtilities.LoadBytesFromBitmap(directory + "\\" + subImage.FilePath); subImages.Add(subImage); } else { // Set the property value properties[nodeName] = reader.Value; } } } // Create a new sprite, set properties GMSprite sprite = new GMSprite(); sprite.Id = GetIdFromName(name); sprite.Name = name; sprite.OriginX = GMXInt(properties[GMXEnumString(GMXSpriteProperty.XOrigin)], sprite.OriginX); sprite.OriginY = GMXInt(properties[GMXEnumString(GMXSpriteProperty.YOrigin)], sprite.OriginY); sprite.ShapeMode = GMXInt(properties[GMXEnumString(GMXSpriteProperty.ColKind)], sprite.ShapeMode); sprite.AlphaTolerance = GMXInt(properties[GMXEnumString(GMXSpriteProperty.ColTolerance)], sprite.AlphaTolerance); sprite.UseSeperateCollisionMasks = GMXBool(properties[GMXEnumString(GMXSpriteProperty.SepMasks)], sprite.UseSeperateCollisionMasks); sprite.BoundingBoxMode = GMXInt(properties[GMXEnumString(GMXSpriteProperty.BBoxMode)], sprite.BoundingBoxMode); sprite.BoundingBoxLeft = GMXInt(properties[GMXEnumString(GMXSpriteProperty.BBoxLeft)], sprite.BoundingBoxLeft); sprite.BoundingBoxRight = GMXInt(properties[GMXEnumString(GMXSpriteProperty.BBoxRight)], sprite.BoundingBoxRight); sprite.BoundingBoxTop = GMXInt(properties[GMXEnumString(GMXSpriteProperty.BBoxTop)], sprite.BoundingBoxTop); sprite.BoundingBoxBottom = GMXInt(properties[GMXEnumString(GMXSpriteProperty.BBoxBottom)], sprite.BoundingBoxBottom); sprite.TileHorizontally = GMXBool(properties[GMXEnumString(GMXSpriteProperty.HTile)], sprite.TileHorizontally); sprite.TileVertically = GMXBool(properties[GMXEnumString(GMXSpriteProperty.VTile)], sprite.TileVertically); sprite.UsedFor3D = GMXBool(properties[GMXEnumString(GMXSpriteProperty.For3D)], sprite.UsedFor3D); sprite.Width = GMXInt(properties[GMXEnumString(GMXSpriteProperty.Width)], sprite.Width); sprite.Height = GMXInt(properties[GMXEnumString(GMXSpriteProperty.Height)], sprite.Height); properties[textureGroup] = properties[textureGroup] == "" ? "0" : properties[textureGroup]; properties[textureGroup0] = properties[textureGroup0] == "" ? "0" : properties[textureGroup0]; // The texture group does not equal zero set texture group 0 to the texture group value if (properties[textureGroup] != "0") { properties[textureGroup0] = properties[textureGroup]; } // The texture group zero does not equal zero set texture group to the texture group 0 value else if (properties[textureGroup0] != "0") { properties[textureGroup] = properties[textureGroup0]; } // Create a list of texture groups List <int> textureGroups = new List <int>(); for (int i = 0; properties.ContainsKey(textureGroup + i); i++) { textureGroups.Add(Convert.ToInt32(properties[textureGroup + i])); } // Set the subimage size for all subimages foreach (GMImage image in subImages) { image.Width = sprite.Width; image.Height = sprite.Height; } sprite.TextureGroups = textureGroups.ToArray(); sprite.SubImages = subImages.ToArray(); // Add the sprite sprites.Add(sprite); } // Return the list of sprites return(sprites); }
/// <summary> /// Reads all backgrounds from a background XML file /// </summary> /// <param name="directory">The XML (.GMX) file path</param> /// <param name="assets">A list of assets listed in the project GMX</param> /// <returns>A GM background</returns> public static GMList <GMBackground> ReadBackgroundsGMX(string directory, ref List <string> assets) { // A list of backgrounds GMList <GMBackground> backgrounds = new GMList <GMBackground>(); backgrounds.AutoIncrementIds = false; // Iterate through .gmx files in the directory foreach (string file in Directory.GetFiles(directory, "*.gmx")) { // Set name of the background string name = GetResourceName(file); // If the file is not in the asset list, it has been orphaned, continue if (!assets.Contains(name)) { continue; } // Create a dictionary of room properties Dictionary <string, string> properties = new Dictionary <string, string>(); foreach (GMXBackgroundProperty property in Enum.GetValues(typeof(GMXBackgroundProperty))) { properties.Add(GMXEnumString(property), ""); } // Background image and texture group strings GMImage image = null; string textureGroup = GMXEnumString(GMXBackgroundProperty.TextureGroup); string textureGroup0 = GMXEnumString(GMXBackgroundProperty.TextureGroup0); // Create an XMLReader to read in the resource elements using (XmlReader reader = XmlReader.Create(file)) { // Move to a content node reader.MoveToContent(); // Read XML file while (reader.Read()) { // If the node is not an element, continue if (reader.NodeType != XmlNodeType.Element) { continue; } // Get the element name string nodeName = reader.Name; // Read reader.Read(); // If the element value is null or empty, continue if (string.IsNullOrEmpty(reader.Value)) { continue; } // If the element is a frame element create subimage, else normal property if (nodeName.ToLower() == GMXEnumString(GMXBackgroundProperty.Data)) { // Create an image and set the image path image = new GMImage(); image.Compressed = false; image.FilePath = reader.Value; image.Data = GMUtilities.LoadBytesFromBitmap(directory + "\\" + image.FilePath); } else { // Set the property value properties[nodeName] = reader.Value; } } } // Create a new background and set its properties GMBackground background = new GMBackground(); background.Id = GetIdFromName(name); background.Name = name; background.UseAsTileSet = GMXBool(properties[GMXEnumString(GMXBackgroundProperty.IsTileset)], background.UseAsTileSet); background.TileWidth = GMXInt(properties[GMXEnumString(GMXBackgroundProperty.TileWidth)], background.TileWidth); background.TileHeight = GMXInt(properties[GMXEnumString(GMXBackgroundProperty.TileHeight)], background.TileHeight); background.HorizontalOffset = GMXInt(properties[GMXEnumString(GMXBackgroundProperty.TileXOff)], background.HorizontalOffset); background.VerticalOffset = GMXInt(properties[GMXEnumString(GMXBackgroundProperty.TileYOff)], background.VerticalOffset); background.HorizontalSeperation = GMXInt(properties[GMXEnumString(GMXBackgroundProperty.TileHSep)], background.HorizontalSeperation); background.VerticalSeperation = GMXInt(properties[GMXEnumString(GMXBackgroundProperty.TileVSep)], background.VerticalSeperation); background.TileHorizontally = GMXBool(properties[GMXEnumString(GMXBackgroundProperty.HTile)], background.TileHorizontally); background.TileVertically = GMXBool(properties[GMXEnumString(GMXBackgroundProperty.VTile)], background.TileVertically); background.UsedFor3D = GMXBool(properties[GMXEnumString(GMXBackgroundProperty.For3D)], background.UsedFor3D); background.Width = GMXInt(properties[GMXEnumString(GMXBackgroundProperty.Width)], background.Width); background.Height = GMXInt(properties[GMXEnumString(GMXBackgroundProperty.Height)], background.Height); properties[textureGroup] = properties[textureGroup] == "" ? "0" : properties[textureGroup]; properties[textureGroup0] = properties[textureGroup0] == "" ? "0" : properties[textureGroup0]; image.Width = background.Width; image.Height = background.Height; background.Image = image; // The texture group does not equal zero set texture group 0 to the texture group value if (properties[textureGroup] != "0") { properties[textureGroup0] = properties[textureGroup]; } // The texture group zero does not equal zero set texture group to the texture group 0 value else if (properties[textureGroup0] != "0") { properties[textureGroup] = properties[textureGroup0]; } // Create a list of texture groups List <int> textureGroups = new List <int>(); for (int i = 0; properties.ContainsKey(string.Concat(textureGroup, i)); i++) { textureGroups.Add(Convert.ToInt32(properties[string.Concat(textureGroup, i)])); } background.TextureGroups = textureGroups.ToArray(); // Add the background backgrounds.Add(background); } // Return the list of backgrounds return(backgrounds); }
/// <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); }
/// <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); } }