Compare commits

..

No commits in common. "81e89b84fcea51f52d5d1b9799a7c920a79cf947" and "038a4c1917a1274bbac7f57d4ecf2f3d013d53bb" have entirely different histories.

2 changed files with 49 additions and 110 deletions

View file

@ -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<DecompileContext> DECOMPILE_CONTEXT = new ThreadLocal<DecompileContext>(() => 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 ? "<undefined>" : gameObject.ParentId.Name.Content),
new XElement("maskName", gameObject.TextureMaskId is null ? "<undefined>" : 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);
// TODOPhysics
}
}
}
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)))
)
);
// TODOMakerSettings
// 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 ? "<undefined>" : 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
// TODORoom 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)
);
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<UndertalePath>(gmx.Element("assets"), "paths", "paths", Data.Paths, "path", "paths\\");
WriteIndexes<UndertaleTimeline>(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<T>(XElement rootNode, string elementName, string attributeName, IList<T> dataList, string oneName, string resourcePath, string fileExtension = "")

View file

@ -3,5 +3,3 @@
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