diff --git a/ExportToGMS1Project.csx b/ExportToGMS1Project.csx index aa25435..cd9269c 100644 --- a/ExportToGMS1Project.csx +++ b/ExportToGMS1Project.csx @@ -10,15 +10,12 @@ using System.Reflection; using UndertaleModLib.Models; using UndertaleModLib.Util; using UndertaleModLib.Decompiler; -using Underanalyzer.Decompiler; -string GameName = Data.GeneralInfo.Name.ToString().Replace(@"""",""); //Name == "Project" -> Project int progress = 0; -string projFolder = GetFolder(FilePath) + GameName + ".gmx" + Path.DirectorySeparatorChar; -TextureWorker worker = new(); -GlobalDecompileContext decompileContext = new(Data); +string projFolder = GetFolder(FilePath) + "Export_Project" + Path.DirectorySeparatorChar; +TextureWorker worker = new TextureWorker(); +ThreadLocal DECOMPILE_CONTEXT = new ThreadLocal(() => new DecompileContext(Data, false)); string gmxDeclaration = "This Document is generated by GameMaker, if you edit it by hand then you do so at your own risk!"; -string eol = "\n"; // Linux: "\n", Windows: "\r\n" if (Directory.Exists(projFolder)) { @@ -71,7 +68,7 @@ await ExportTimelines(); GenerateProjectFile(); // --------------- Export completed --------------- -worker.Dispose(); // worker.Cleanup()? +worker.Cleanup(); HideProgressBar(); ScriptMessage("Export Complete.\n\nLocation: " + projFolder); @@ -118,7 +115,8 @@ void ExportSprite(UndertaleSprite sprite) new XElement("For3D", "0"), new XElement("width", sprite.Width.ToString()), new XElement("height", sprite.Height.ToString()), - new XElement("frames") + new XElement("frames"), + new XElement("bbox_right", sprite.MarginRight.ToString()) ) ); @@ -136,14 +134,22 @@ void ExportSprite(UndertaleSprite sprite) } } - File.WriteAllText(projFolder + "/sprites/" + sprite.Name.Content + ".sprite.gmx", gmx.ToString() + eol); + File.WriteAllText(projFolder + "/sprites/" + sprite.Name.Content + ".sprite.gmx", gmx.ToString()); // Save sprite images for (int i = 0; i < sprite.Textures.Count; i++) { if (sprite.Textures[i]?.Texture != null) { - worker.ExportAsPNG(sprite.Textures[i].Texture, projFolder + "/sprites/images/" + sprite.Name.Content + "_" + i + ".png", null, true); + // Fix sprite size + var bitmapNew = new Bitmap((int)sprite.Width, (int)sprite.Height); + var bitmapOrigin = worker.GetTextureFor(sprite.Textures[i].Texture, Path.GetFileNameWithoutExtension(projFolder + "/sprites/images/" + sprite.Name.Content + "_" + i + ".png")); + //worker.ExportAsPNG(sprite.Textures[i].Texture, projFolder + "/sprites/images/" + sprite.Name.Content + "_" + i + ".png"); + var g = Graphics.FromImage(bitmapNew); + g.DrawImage(bitmapOrigin, (int)sprite.Textures[i].Texture.TargetX, (int)sprite.Textures[i].Texture.TargetY); + bitmapNew.Save(projFolder + "/sprites/images/" + sprite.Name.Content + "_" + i + ".png"); + bitmapNew.Dispose(); + bitmapOrigin.Dispose(); } } } @@ -163,8 +169,8 @@ void ExportBackground(UndertaleBackground background) new XComment(gmxDeclaration), new XElement("background", new XElement("istileset", "-1"), - new XElement("tilewidth", background.Texture == null ? "0" : background.Texture.BoundingWidth.ToString()), - new XElement("tileheight", background.Texture == null ? "0" : background.Texture.BoundingHeight.ToString()), + new XElement("tilewidth", background.Texture.BoundingWidth.ToString()), + new XElement("tileheight", background.Texture.BoundingHeight.ToString()), new XElement("tilexoff", "0"), new XElement("tileyoff", "0"), new XElement("tilehsep", "0"), @@ -175,17 +181,16 @@ void ExportBackground(UndertaleBackground background) new XElement("TextureGroup0", "0") ), new XElement("For3D", "0"), - new XElement("width", background.Texture == null ? "0" : background.Texture.BoundingWidth.ToString()), - new XElement("height",background.Texture == null ? "0" : background.Texture.BoundingHeight.ToString()), + new XElement("width", background.Texture.BoundingWidth.ToString()), + new XElement("height", background.Texture.BoundingHeight.ToString()), new XElement("data", "images\\" + background.Name.Content + ".png") ) ); - File.WriteAllText(projFolder + "/background/" + background.Name.Content + ".background.gmx", gmx.ToString() + eol); + File.WriteAllText(projFolder + "/background/" + background.Name.Content + ".background.gmx", gmx.ToString()); // Save background images - if (background.Texture != null) - worker.ExportAsPNG(background.Texture, projFolder + "/background/images/" + background.Name.Content + ".png"); + worker.ExportAsPNG(background.Texture, projFolder + "/background/images/" + background.Name.Content + ".png"); } // --------------- Export Object --------------- async Task ExportGameObjects() @@ -208,36 +213,10 @@ void ExportGameObject(UndertaleGameObject gameObject) new XElement("persistent", BoolToString(gameObject.Persistent)), new XElement("parentName", gameObject.ParentId is null ? "" : gameObject.ParentId.Name.Content), new XElement("maskName", gameObject.TextureMaskId is null ? "" : gameObject.TextureMaskId.Name.Content), - new XElement("events"), - - //Physics - new XElement("PhysicsObject", BoolToString(gameObject.UsesPhysics)), - new XElement("PhysicsObjectSensor", BoolToString(gameObject.IsSensor)), - new XElement("PhysicsObjectShape", (uint)gameObject.CollisionShape), - new XElement("PhysicsObjectDensity", gameObject.Density), - new XElement("PhysicsObjectRestitution", gameObject.Restitution), - new XElement("PhysicsObjectGroup", gameObject.Group), - new XElement("PhysicsObjectLinearDamping", gameObject.LinearDamping), - new XElement("PhysicsObjectAngularDamping", gameObject.AngularDamping), - new XElement("PhysicsObjectFriction", gameObject.Friction), - new XElement("PhysicsObjectAwake", BoolToString(gameObject.Awake)), - new XElement("PhysicsObjectKinematic", BoolToString(gameObject.Kinematic)), - new XElement("PhysicsShapePoints") + new XElement("events") ) ); - - - // Loop through PhysicsShapePoints List - for (int _point = 0; _point < gameObject.PhysicsVertices.Count; _point++) - { - var _x = gameObject.PhysicsVertices[_point].X; - var _y = gameObject.PhysicsVertices[_point].Y; - - var physicsPointsNode = gmx.Element("object").Element("PhysicsShapePoints"); - physicsPointsNode.Add(new XElement("points",_x.ToString() + "," + _y.ToString())); - } - // Traversing the event type list for (int i = 0; i < gameObject.Events.Count; i++) { @@ -270,13 +249,6 @@ void ExportGameObject(UndertaleGameObject gameObject) // Traversing the action list foreach (var k in j.Actions) { - DecompileContext dec_context = new(decompileContext, k.CodeId, Data.ToolInfo.DecompilerSettings); - XElement act_string = null; - try { - act_string = new XElement("string", (k.CodeId != null && dec_context != null) ? dec_context.DecompileToString() : ""); - } catch (DecompilerException) { - act_string = new XElement("string", ""); - } actionNode.Add( new XElement("libid", k.LibID.ToString()), new XElement("id", k.ID.ToString()), @@ -285,7 +257,7 @@ void ExportGameObject(UndertaleGameObject gameObject) new XElement("isquestion", BoolToString(k.IsQuestion)), new XElement("useapplyto", BoolToString(k.UseApplyTo)), new XElement("exetype", k.ExeType.ToString()), - new XElement("functionname", k.ActionName != null ? k.ActionName.Content : ""), + new XElement("functionname", k.ActionName.Content), new XElement("codestring", ""), new XElement("whoName", "self"), new XElement("relative", BoolToString(k.Relative)), @@ -293,7 +265,7 @@ void ExportGameObject(UndertaleGameObject gameObject) new XElement("arguments", new XElement("argument", new XElement("kind", "1"), - act_string + new XElement("string", k.CodeId != null ? Decompiler.Decompile(k.CodeId, DECOMPILE_CONTEXT.Value) : "") ) ) ); @@ -301,11 +273,12 @@ void ExportGameObject(UndertaleGameObject gameObject) eventNode.Add(actionNode); eventsNode.Add(eventNode); + // TODO:Physics } } } - File.WriteAllText(projFolder + "/objects/" + gameObject.Name.Content + ".object.gmx", gmx.ToString() + eol); + File.WriteAllText(projFolder + "/objects/" + gameObject.Name.Content + ".object.gmx", gmx.ToString()); } // --------------- Export Room --------------- @@ -331,29 +304,13 @@ void ExportRoom(UndertaleRoom room) new XElement("speed", room.Speed.ToString()), new XElement("persistent", BoolToString(room.Persistent)), new XElement("colour", room.BackgroundColor.ToString()), - new XElement("showcolour", BoolToString(room.DrawBackgroundColor)), - new XElement("code", room.CreationCodeId != null ? new DecompileContext(decompileContext, room.CreationCodeId).DecompileToString() : ""), + new XElement("code", room.CreationCodeId != null ? Decompiler.Decompile(room.CreationCodeId, DECOMPILE_CONTEXT.Value) : ""), new XElement("enableViews", BoolToString(room.Flags.HasFlag(UndertaleRoom.RoomEntryFlags.EnableViews))), new XElement("clearViewBackground", BoolToString(room.Flags.HasFlag(UndertaleRoom.RoomEntryFlags.ShowColor))), - //new XElement("clearDisplayBuffer", BoolToString(room.Flags.HasFlag(UndertaleRoom.RoomEntryFlags.ClearDisplayBuffer))), - new XElement("makerSettings", - new XElement("isSet", 0), - new XElement("w", 0), - new XElement("h", 0), - new XElement("showGrid", 0), - new XElement("showObjects", 0), - new XElement("showTiles", 0), - new XElement("showBackgrounds", 0), - new XElement("showForegrounds", 0), - new XElement("showViews", 0), - new XElement("deleteUnderlyingObj", 0), - new XElement("deleteUnderlyingTiles", 0), - new XElement("page", 0), - new XElement("xoffset", 0), - new XElement("yoffset", 0) - ) + new XElement("clearDisplayBuffer", BoolToString(room.Flags.HasFlag(UndertaleRoom.RoomEntryFlags.ClearDisplayBuffer))) ) ); + // TODO:MakerSettings // Room backgrounds var backgroundsNode = new XElement("backgrounds"); @@ -365,8 +322,8 @@ void ExportRoom(UndertaleRoom room) new XAttribute("name", i.BackgroundDefinition is null ? "" : i.BackgroundDefinition.Name.Content), new XAttribute("x", i.X.ToString()), new XAttribute("y", i.Y.ToString()), - new XAttribute("htiled", i.X.ToString()), - new XAttribute("vtiled", i.Y.ToString()), + new XAttribute("htiled", i.TileX.ToString()), + new XAttribute("vtiled", i.TileY.ToString()), new XAttribute("hspeed", i.SpeedX.ToString()), new XAttribute("vspeed", i.SpeedY.ToString()), new XAttribute("stretch", "0") @@ -384,8 +341,7 @@ void ExportRoom(UndertaleRoom room) new XAttribute("objName", i.ObjectId is null ? "" : i.ObjectId.Name.Content), new XAttribute("xview", i.ViewX.ToString()), new XAttribute("yview", i.ViewY.ToString()), - new XAttribute("wview", i.ViewWidth.ToString()), - new XAttribute("hview", i.ViewHeight.ToString()), + new XAttribute("wview", i.ViewHeight.ToString()), new XAttribute("xport", i.PortX.ToString()), new XAttribute("yport", i.PortY.ToString()), new XAttribute("wport", i.PortWidth.ToString()), @@ -409,7 +365,7 @@ void ExportRoom(UndertaleRoom room) new XAttribute("y", i.Y.ToString()), new XAttribute("name", "inst_" + i.InstanceID.ToString("X")), new XAttribute("locked", "0"), - new XAttribute("code", i.CreationCode != null ? new DecompileContext(decompileContext, i.CreationCode).DecompileToString() : ""), + new XAttribute("code", i.CreationCode != null ? Decompiler.Decompile(i.CreationCode, DECOMPILE_CONTEXT.Value) : ""), new XAttribute("scaleX", i.ScaleX.ToString()), new XAttribute("scaleY", i.ScaleY.ToString()), new XAttribute("colour", i.Color.ToString()), @@ -443,20 +399,9 @@ void ExportRoom(UndertaleRoom room) } gmx.Element("room").Add(tilesNode); - //Room Physics - - gmx.Element("room").Add( - new XElement("PhysicsWorld", room.World), - new XElement("PhysicsWorldTop", room.Top), - new XElement("PhysicsWorldLeft", room.Left), - new XElement("PhysicsWorldRight", room.Right), - new XElement("PhysicsWorldBottom", room.Bottom), - new XElement("PhysicsWorldGravityX", room.GravityX), - new XElement("PhysicsWorldGravityY", room.GravityY), - new XElement("PhysicsWorldPixToMeters", room.MetersPerPixel) - ); + // TODO:Room physics - File.WriteAllText(projFolder + "/rooms/" + room.Name.Content + ".room.gmx", gmx.ToString() + eol); + File.WriteAllText(projFolder + "/rooms/" + room.Name.Content + ".room.gmx", gmx.ToString()); } // --------------- Export Sound --------------- @@ -477,13 +422,9 @@ void ExportSound(UndertaleSound sound) new XElement("extension", Path.GetExtension(sound.File.Content)), new XElement("origname", "sound\\audio\\" + sound.File.Content), new XElement("effects", sound.Effects.ToString()), - new XElement("volume", - new XElement("volume", sound.Volume.ToString()) - ), + new XElement("volume", sound.Volume.ToString()), new XElement("pan", "0"), - new XElement("bitRates", - new XElement("bitRate", "192") - ), + new XElement("bitRates", "192"), new XElement("sampleRates", new XElement("sampleRate", "44100") ), @@ -502,7 +443,7 @@ void ExportSound(UndertaleSound sound) ) ); - File.WriteAllText(projFolder + "/sound/" + sound.Name.Content + ".sound.gmx", gmx.ToString() + eol); + File.WriteAllText(projFolder + "/sound/" + sound.Name.Content + ".sound.gmx", gmx.ToString()); // Save sound files if (sound.AudioFile != null) @@ -520,7 +461,7 @@ void ExportScript(UndertaleScript script) UpdateProgressBar(null, $"Exporting script: {script.Name.Content}", progress++, resourceNum); // Save GML files - File.WriteAllText(projFolder + "/scripts/" + script.Name.Content + ".gml", script.Code != null ? new DecompileContext(decompileContext, script.Code).DecompileToString() : ""); + File.WriteAllText(projFolder + "/scripts/" + script.Name.Content + ".gml", (script.Code != null ? Decompiler.Decompile(script.Code, DECOMPILE_CONTEXT.Value) : "")); } // --------------- Export Font --------------- @@ -572,7 +513,7 @@ void ExportFont(UndertaleFont font) glyphsNode.Add(glyphNode); } - File.WriteAllText(projFolder + "/fonts/" + font.Name.Content + ".font.gmx", gmx.ToString() + eol); + File.WriteAllText(projFolder + "/fonts/" + font.Name.Content + ".font.gmx", gmx.ToString()); // Save font textures worker.ExportAsPNG(font.Texture, projFolder + "/fonts/" + font.Name.Content + ".png"); @@ -609,7 +550,7 @@ void ExportPath(UndertalePath path) ); } - File.WriteAllText(projFolder + "/paths/" + path.Name.Content + ".path.gmx", gmx.ToString() + eol); + File.WriteAllText(projFolder + "/paths/" + path.Name.Content + ".path.gmx", gmx.ToString()); } // --------------- Export Timelines --------------- @@ -630,9 +571,9 @@ void ExportTimeline(UndertaleTimeline timeline) foreach (var i in timeline.Moments) { var entryNode = new XElement("entry"); - entryNode.Add(new XElement("step", i.Step)); + entryNode.Add(new XElement("step", i.Item1)); entryNode.Add(new XElement("event")); - foreach (var j in i.Event) + foreach (var j in i.Item2) { entryNode.Element("event").Add( new XElement("action", @@ -651,7 +592,7 @@ void ExportTimeline(UndertaleTimeline timeline) new XElement("arguments", new XElement("argument", new XElement("kind", "1"), - new XElement("string", j.CodeId != null ? new DecompileContext(decompileContext, j.CodeId).DecompileToString() : "") + new XElement("string", j.CodeId != null ? Decompiler.Decompile(j.CodeId, DECOMPILE_CONTEXT.Value) : "") ) ) ) @@ -660,7 +601,7 @@ void ExportTimeline(UndertaleTimeline timeline) gmx.Element("timeline").Add(entryNode); } - File.WriteAllText(projFolder + "/timelines/" + timeline.Name.Content + ".timeline.gmx", gmx.ToString() + eol); + File.WriteAllText(projFolder + "/timelines/" + timeline.Name.Content + ".timeline.gmx", gmx.ToString()); } @@ -685,7 +626,7 @@ void GenerateProjectFile() WriteIndexes(gmx.Element("assets"), "paths", "paths", Data.Paths, "path", "paths\\"); WriteIndexes(gmx.Element("assets"), "timelines", "timelines", Data.Timelines, "timeline", "timelines\\"); - File.WriteAllText(projFolder + GameName + ".project.gmx", gmx.ToString() + eol); + File.WriteAllText(projFolder + "Export_Project.project.gmx", gmx.ToString()); } void WriteIndexes(XElement rootNode, string elementName, string attributeName, IList dataList, string oneName, string resourcePath, string fileExtension = "") @@ -699,4 +640,4 @@ void WriteIndexes(XElement rootNode, string elementName, string attributeName resourcesNode.Add(resourceNode); } rootNode.Add(resourcesNode); -} \ No newline at end of file +} diff --git a/README.md b/README.md index f4506b2..14d20dc 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,4 @@ This is a script for UndertaleModTool, which can export game files as project files of GameMaker Studio. -Currently compatible with gms1.4, will support gms2 in the future. - -Original repo: https://github.com/cubeww/UndertaleModTool-ExportToProjectScript \ No newline at end of file +Currently compatible with gms1.4, will support gms2 in the future. \ No newline at end of file