diff --git a/PCK-Studio/App.config b/PCK-Studio/App.config index 76598544..3d989fab 100644 --- a/PCK-Studio/App.config +++ b/PCK-Studio/App.config @@ -80,6 +80,12 @@ Unknown + + System_Default + + + Local + diff --git a/PCK-Studio/Controls/DefaultPanel.Designer.cs b/PCK-Studio/Controls/DefaultPanel.Designer.cs index 757d2a11..80b81929 100644 --- a/PCK-Studio/Controls/DefaultPanel.Designer.cs +++ b/PCK-Studio/Controls/DefaultPanel.Designer.cs @@ -36,11 +36,6 @@ this.buttonEdit = new MetroFramework.Controls.MetroButton(); this.metroLabel1 = new MetroFramework.Controls.MetroLabel(); this.treeMeta = new System.Windows.Forms.TreeView(); - this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); - this.displayNameLabel = new System.Windows.Forms.Label(); - this.previewPictureBox = new PckStudio.ToolboxItems.InterpolationPictureBox(); - this.skinRenderer = new PckStudio.Rendering.SkinRenderer(); - this.themeNameLabel = new System.Windows.Forms.Label(); this.contextMenuMetaTree = new System.Windows.Forms.ContextMenuStrip(this.components); this.addEntryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.addEntryToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); @@ -49,11 +44,17 @@ this.addMultipleEntriesToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); this.deleteEntryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.editAllEntriesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.displayNameLabel = new System.Windows.Forms.Label(); + this.previewPictureBox = new PckStudio.ToolboxItems.InterpolationPictureBox(); + this.skinRenderer = new PckStudio.Rendering.SkinRenderer(); + this.themeNameLabel = new System.Windows.Forms.Label(); + this.texSizeLabel = new System.Windows.Forms.Label(); this.PropertiesTabControl.SuspendLayout(); this.MetaTab.SuspendLayout(); + this.contextMenuMetaTree.SuspendLayout(); this.tableLayoutPanel1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.previewPictureBox)).BeginInit(); - this.contextMenuMetaTree.SuspendLayout(); this.SuspendLayout(); // // PropertiesTabControl @@ -61,10 +62,10 @@ this.tableLayoutPanel1.SetColumnSpan(this.PropertiesTabControl, 2); this.PropertiesTabControl.Controls.Add(this.MetaTab); this.PropertiesTabControl.Dock = System.Windows.Forms.DockStyle.Fill; - this.PropertiesTabControl.Location = new System.Drawing.Point(3, 369); + this.PropertiesTabControl.Location = new System.Drawing.Point(3, 368); this.PropertiesTabControl.Name = "PropertiesTabControl"; this.PropertiesTabControl.SelectedIndex = 0; - this.PropertiesTabControl.Size = new System.Drawing.Size(907, 322); + this.PropertiesTabControl.Size = new System.Drawing.Size(907, 323); this.PropertiesTabControl.Style = MetroFramework.MetroColorStyle.Silver; this.PropertiesTabControl.TabIndex = 13; this.PropertiesTabControl.Theme = MetroFramework.MetroThemeStyle.Dark; @@ -83,7 +84,7 @@ this.MetaTab.Location = new System.Drawing.Point(4, 38); this.MetaTab.Name = "MetaTab"; this.MetaTab.Padding = new System.Windows.Forms.Padding(5); - this.MetaTab.Size = new System.Drawing.Size(899, 280); + this.MetaTab.Size = new System.Drawing.Size(899, 281); this.MetaTab.TabIndex = 0; this.MetaTab.Text = "Properties"; this.MetaTab.Theme = MetroFramework.MetroThemeStyle.Dark; @@ -95,7 +96,7 @@ // this.metroLabel2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.metroLabel2.AutoSize = true; - this.metroLabel2.Location = new System.Drawing.Point(379, 146); + this.metroLabel2.Location = new System.Drawing.Point(379, 147); this.metroLabel2.Name = "metroLabel2"; this.metroLabel2.Size = new System.Drawing.Size(0, 0); this.metroLabel2.TabIndex = 15; @@ -104,7 +105,7 @@ // buttonEdit // this.buttonEdit.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.buttonEdit.Location = new System.Drawing.Point(3, 248); + this.buttonEdit.Location = new System.Drawing.Point(3, 249); this.buttonEdit.Name = "buttonEdit"; this.buttonEdit.Size = new System.Drawing.Size(201, 31); this.buttonEdit.TabIndex = 20; @@ -116,7 +117,7 @@ // this.metroLabel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.metroLabel1.AutoSize = true; - this.metroLabel1.Location = new System.Drawing.Point(441, 39); + this.metroLabel1.Location = new System.Drawing.Point(441, 40); this.metroLabel1.Name = "metroLabel1"; this.metroLabel1.Size = new System.Drawing.Size(0, 0); this.metroLabel1.TabIndex = 13; @@ -129,110 +130,15 @@ | System.Windows.Forms.AnchorStyles.Right))); this.treeMeta.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(18)))), ((int)(((byte)(18))))); this.treeMeta.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.treeMeta.ContextMenuStrip = this.contextMenuMetaTree; this.treeMeta.ForeColor = System.Drawing.SystemColors.Window; this.treeMeta.Location = new System.Drawing.Point(3, 4); this.treeMeta.Name = "treeMeta"; this.treeMeta.PathSeparator = "/"; - this.treeMeta.Size = new System.Drawing.Size(888, 238); + this.treeMeta.Size = new System.Drawing.Size(888, 239); this.treeMeta.TabIndex = 0; this.treeMeta.DoubleClick += new System.EventHandler(this.treeMeta_DoubleClick); // - // tableLayoutPanel1 - // - this.tableLayoutPanel1.ColumnCount = 2; - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tableLayoutPanel1.Controls.Add(this.displayNameLabel, 0, 0); - this.tableLayoutPanel1.Controls.Add(this.PropertiesTabControl, 0, 3); - this.tableLayoutPanel1.Controls.Add(this.previewPictureBox, 0, 2); - this.tableLayoutPanel1.Controls.Add(this.skinRenderer, 1, 2); - this.tableLayoutPanel1.Controls.Add(this.themeNameLabel, 0, 1); - this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; - this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); - this.tableLayoutPanel1.Name = "tableLayoutPanel1"; - this.tableLayoutPanel1.RowCount = 4; - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 3F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 3F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 47F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 47F)); - this.tableLayoutPanel1.Size = new System.Drawing.Size(913, 694); - this.tableLayoutPanel1.TabIndex = 14; - // - // displayNameLabel - // - this.displayNameLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.displayNameLabel.AutoSize = true; - this.tableLayoutPanel1.SetColumnSpan(this.displayNameLabel, 2); - this.displayNameLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.displayNameLabel.ForeColor = System.Drawing.Color.White; - this.displayNameLabel.Location = new System.Drawing.Point(3, 0); - this.displayNameLabel.Name = "displayNameLabel"; - this.displayNameLabel.Size = new System.Drawing.Size(907, 20); - this.displayNameLabel.TabIndex = 15; - this.displayNameLabel.Text = "name"; - this.displayNameLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - // - // previewPictureBox - // - this.previewPictureBox.BackgroundInterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Default; - this.previewPictureBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.previewPictureBox.Image = global::PckStudio.Properties.Resources.NoImageFound; - this.previewPictureBox.ImeMode = System.Windows.Forms.ImeMode.NoControl; - this.previewPictureBox.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; - this.previewPictureBox.Location = new System.Drawing.Point(3, 43); - this.previewPictureBox.Name = "previewPictureBox"; - this.previewPictureBox.Size = new System.Drawing.Size(450, 320); - this.previewPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; - this.previewPictureBox.TabIndex = 12; - this.previewPictureBox.TabStop = false; - // - // skinRenderer - // - this.skinRenderer.AllowCameraMovement = false; - this.skinRenderer.Animate = true; - this.skinRenderer.ArmorTexture = null; - this.skinRenderer.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(18)))), ((int)(((byte)(18))))); - this.skinRenderer.CapeTexture = null; - this.skinRenderer.CenterOnSelect = false; - this.skinRenderer.Dock = System.Windows.Forms.DockStyle.Fill; - this.skinRenderer.ForeColor = System.Drawing.Color.CornflowerBlue; - this.skinRenderer.GuideLineColor = System.Drawing.Color.Empty; - this.skinRenderer.HighlightlingColor = System.Drawing.Color.Aqua; - this.skinRenderer.Location = new System.Drawing.Point(459, 43); - this.skinRenderer.MouseSensetivity = 0.01F; - this.skinRenderer.Name = "skinRenderer"; - this.skinRenderer.RefreshRate = 60; - this.skinRenderer.RenderGroundPlane = false; - this.skinRenderer.RenderSkyBox = false; - this.skinRenderer.SelectedIndex = -1; - this.skinRenderer.SelectedIndices = new int[0]; - this.skinRenderer.ShowArmor = false; - this.skinRenderer.ShowBoundingBox = false; - this.skinRenderer.ShowGuideLines = false; - this.skinRenderer.Size = new System.Drawing.Size(451, 320); - this.skinRenderer.TabIndex = 14; - this.skinRenderer.Texture = null; - this.skinRenderer.Visible = false; - this.skinRenderer.VSync = true; - // - // themeNameLabel - // - this.themeNameLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.themeNameLabel.AutoSize = true; - this.tableLayoutPanel1.SetColumnSpan(this.themeNameLabel, 2); - this.themeNameLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.themeNameLabel.ForeColor = System.Drawing.Color.White; - this.themeNameLabel.Location = new System.Drawing.Point(3, 20); - this.themeNameLabel.Name = "themeNameLabel"; - this.themeNameLabel.Size = new System.Drawing.Size(907, 20); - this.themeNameLabel.TabIndex = 16; - this.themeNameLabel.Text = "theme"; - this.themeNameLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - // // contextMenuMetaTree // this.contextMenuMetaTree.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -295,6 +201,116 @@ this.editAllEntriesToolStripMenuItem.Size = new System.Drawing.Size(181, 22); this.editAllEntriesToolStripMenuItem.Click += new System.EventHandler(this.editAllEntriesToolStripMenuItem_Click); // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 2; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel1.Controls.Add(this.displayNameLabel, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.PropertiesTabControl, 0, 4); + this.tableLayoutPanel1.Controls.Add(this.previewPictureBox, 0, 2); + this.tableLayoutPanel1.Controls.Add(this.skinRenderer, 1, 2); + this.tableLayoutPanel1.Controls.Add(this.themeNameLabel, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.texSizeLabel, 0, 3); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 5; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 3F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 3F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 45F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 2F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 47F)); + this.tableLayoutPanel1.Size = new System.Drawing.Size(913, 694); + this.tableLayoutPanel1.TabIndex = 14; + // + // displayNameLabel + // + this.displayNameLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.displayNameLabel.AutoSize = true; + this.tableLayoutPanel1.SetColumnSpan(this.displayNameLabel, 2); + this.displayNameLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.displayNameLabel.ForeColor = System.Drawing.Color.White; + this.displayNameLabel.Location = new System.Drawing.Point(3, 0); + this.displayNameLabel.Name = "displayNameLabel"; + this.displayNameLabel.Size = new System.Drawing.Size(907, 20); + this.displayNameLabel.TabIndex = 15; + this.displayNameLabel.Text = "name"; + this.displayNameLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // previewPictureBox + // + this.previewPictureBox.BackgroundInterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Default; + this.previewPictureBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.previewPictureBox.Image = global::PckStudio.Properties.Resources.NoImageFound; + this.previewPictureBox.ImeMode = System.Windows.Forms.ImeMode.NoControl; + this.previewPictureBox.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; + this.previewPictureBox.Location = new System.Drawing.Point(3, 43); + this.previewPictureBox.Name = "previewPictureBox"; + this.previewPictureBox.Size = new System.Drawing.Size(450, 306); + this.previewPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.previewPictureBox.TabIndex = 12; + this.previewPictureBox.TabStop = false; + // + // skinRenderer + // + this.skinRenderer.AllowCameraMovement = false; + this.skinRenderer.Animate = true; + this.skinRenderer.ArmorTexture = null; + this.skinRenderer.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(18)))), ((int)(((byte)(18))))); + this.skinRenderer.CapeTexture = null; + this.skinRenderer.CenterOnSelect = false; + this.skinRenderer.Dock = System.Windows.Forms.DockStyle.Fill; + this.skinRenderer.ForeColor = System.Drawing.Color.CornflowerBlue; + this.skinRenderer.GuideLineColor = System.Drawing.Color.Empty; + this.skinRenderer.HighlightlingColor = System.Drawing.Color.Aqua; + this.skinRenderer.Location = new System.Drawing.Point(459, 43); + this.skinRenderer.MouseSensetivity = 0.01F; + this.skinRenderer.Name = "skinRenderer"; + this.skinRenderer.RefreshRate = 60; + this.skinRenderer.RenderGroundPlane = false; + this.skinRenderer.RenderSkyBox = false; + this.skinRenderer.SelectedIndex = -1; + this.skinRenderer.SelectedIndices = new int[0]; + this.skinRenderer.ShowArmor = false; + this.skinRenderer.ShowBoundingBox = false; + this.skinRenderer.ShowGuideLines = false; + this.skinRenderer.Size = new System.Drawing.Size(451, 306); + this.skinRenderer.TabIndex = 14; + this.skinRenderer.Texture = null; + this.skinRenderer.Visible = false; + this.skinRenderer.VSync = true; + // + // themeNameLabel + // + this.themeNameLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.themeNameLabel.AutoSize = true; + this.tableLayoutPanel1.SetColumnSpan(this.themeNameLabel, 2); + this.themeNameLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.themeNameLabel.ForeColor = System.Drawing.Color.White; + this.themeNameLabel.Location = new System.Drawing.Point(3, 20); + this.themeNameLabel.Name = "themeNameLabel"; + this.themeNameLabel.Size = new System.Drawing.Size(907, 20); + this.themeNameLabel.TabIndex = 16; + this.themeNameLabel.Text = "theme"; + this.themeNameLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // texSizeLabel + // + this.texSizeLabel.AutoSize = true; + this.texSizeLabel.Dock = System.Windows.Forms.DockStyle.Right; + this.texSizeLabel.ForeColor = System.Drawing.Color.White; + this.texSizeLabel.Location = new System.Drawing.Point(418, 352); + this.texSizeLabel.Name = "texSizeLabel"; + this.texSizeLabel.Size = new System.Drawing.Size(35, 13); + this.texSizeLabel.TabIndex = 17; + this.texSizeLabel.Text = "label1"; + this.texSizeLabel.Visible = false; + // // DefaultPanel // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -306,10 +322,10 @@ this.PropertiesTabControl.ResumeLayout(false); this.MetaTab.ResumeLayout(false); this.MetaTab.PerformLayout(); + this.contextMenuMetaTree.ResumeLayout(false); this.tableLayoutPanel1.ResumeLayout(false); this.tableLayoutPanel1.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.previewPictureBox)).EndInit(); - this.contextMenuMetaTree.ResumeLayout(false); this.ResumeLayout(false); } @@ -335,5 +351,6 @@ private Rendering.SkinRenderer skinRenderer; private System.Windows.Forms.Label displayNameLabel; private System.Windows.Forms.Label themeNameLabel; + private System.Windows.Forms.Label texSizeLabel; } } diff --git a/PCK-Studio/Controls/DefaultPanel.cs b/PCK-Studio/Controls/DefaultPanel.cs index 12c499be..c6af2096 100644 --- a/PCK-Studio/Controls/DefaultPanel.cs +++ b/PCK-Studio/Controls/DefaultPanel.cs @@ -210,6 +210,7 @@ namespace PckStudio.Controls skinRenderer.Visible = false; displayNameLabel.Visible = false; themeNameLabel.Visible = false; + texSizeLabel.Visible = false; ButtonText = null; _currentAsset = null; _onModified = null; @@ -226,8 +227,13 @@ namespace PckStudio.Controls case PckAssetType.CapeFile: case PckAssetType.TextureFile: { - previewPictureBox.Image = asset.GetTexture(); + Image img = asset.GetTexture(); + img = SetBackgroundColor(img, Color.YellowGreen); + + previewPictureBox.Image = img; + texSizeLabel.Text = $"{previewPictureBox.Image.Width}x{previewPictureBox.Image.Height}"; + texSizeLabel.Visible = true; if (skinRenderer.IsInitialized) { @@ -288,5 +294,20 @@ namespace PckStudio.Controls } ReloadMetaTreeView(); } + + private static Image SetBackgroundColor(Image img, Color bgColor) + { +#if DEBUG + Image nImg = new Bitmap(img); + using (Graphics g = Graphics.FromImage(nImg)) + { + g.FillRectangle(new SolidBrush(bgColor), new(Point.Empty, nImg.Size)); + g.DrawImage(img, new Rectangle(Point.Empty, nImg.Size)); + } + return nImg; +#else + return img; +#endif + } } } diff --git a/PCK-Studio/Controls/JavaTextFormatForm.Designer.cs b/PCK-Studio/Controls/JavaImportForm.Designer.cs similarity index 98% rename from PCK-Studio/Controls/JavaTextFormatForm.Designer.cs rename to PCK-Studio/Controls/JavaImportForm.Designer.cs index c394762f..d9720555 100644 --- a/PCK-Studio/Controls/JavaTextFormatForm.Designer.cs +++ b/PCK-Studio/Controls/JavaImportForm.Designer.cs @@ -1,6 +1,6 @@ namespace PckStudio.Controls { - partial class JavaTextFormatForm + partial class JavaImportForm { /// /// Required designer variable. @@ -28,7 +28,7 @@ /// private void InitializeComponent() { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(JavaTextFormatForm)); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(JavaImportForm)); this.richTextBox1 = new System.Windows.Forms.RichTextBox(); this.importWorker = new System.ComponentModel.BackgroundWorker(); this.importButton = new System.Windows.Forms.Button(); diff --git a/PCK-Studio/Controls/JavaTextFormatForm.cs b/PCK-Studio/Controls/JavaImportForm.cs similarity index 79% rename from PCK-Studio/Controls/JavaTextFormatForm.cs rename to PCK-Studio/Controls/JavaImportForm.cs index 742a653d..00a1ce60 100644 --- a/PCK-Studio/Controls/JavaTextFormatForm.cs +++ b/PCK-Studio/Controls/JavaImportForm.cs @@ -10,12 +10,12 @@ using System.Linq; using System.Threading; using System.Windows.Forms; using PckStudio.Core; +using PckStudio.Core.DLC; using PckStudio.Core.IO.Java; -using PckStudio.ToolboxItems; namespace PckStudio.Controls { - public partial class JavaTextFormatForm : ImmersiveForm + public partial class JavaImportForm : ImmersiveForm { static Dictionary _javaColorCodeToColor = new Dictionary() { @@ -47,13 +47,21 @@ namespace PckStudio.Controls ["§t"] = new RichTextBoxColor(Color.FromArgb(0x21, 0x49, 0x7B), Color.FromArgb(0x08, 0x12, 0x1E)), ["§u"] = new RichTextBoxColor(Color.FromArgb(0x9A, 0x5C, 0xC6), Color.FromArgb(0x26, 0x17, 0x31)), }; - - public JavaTextFormatForm(FileInfo fileInfo) + private ResourcePackImporter _importer; + private readonly DLCManager _dlcManager; + private readonly ImportStatusReport _importStatusReport; + + public DLCPackageContent Result { get; private set; } + + public JavaImportForm(FileInfo fileInfo, DLCManager dlcManager) { InitializeComponent(); importWorker.DoWork += Import; importWorker.ProgressChanged += ImportProgressChanged; importWorker.RunWorkerCompleted += ImportCompleted; + _importer = new ResourcePackImporter(default); + _dlcManager = dlcManager; + _importStatusReport = ImportStatusReport.CreateCustom(importWorker.ReportProgressInfo); StartImport(fileInfo); } @@ -63,9 +71,13 @@ namespace PckStudio.Controls importButton.Click += Cancel_Click; importButton.Text = "Cancel"; var zip = new ZipArchive(fileInfo.OpenRead(), ZipArchiveMode.Read); - ResourcePackImporter importer = new ResourcePackImporter(zip, default); - FormatPackDescription(Path.GetFileNameWithoutExtension(fileInfo.Name), importer.ReadPackMeta(zip).Description); - importWorker.RunWorkerAsync(importer); + + string name = Path.GetFileNameWithoutExtension(fileInfo.Name); + if (_importer.StartImport(name, zip, _importStatusReport)) + { + FormatPackDescription(Path.GetFileNameWithoutExtension(fileInfo.Name), _importer.ReadPackMeta(zip).Description); + importWorker.RunWorkerAsync(zip); + } } private void ImportProgressChanged(object sender, ProgressChangedEventArgs eventArgs) @@ -83,26 +95,26 @@ namespace PckStudio.Controls eventArgs.Cancel = true; return; } - if (eventArgs.Argument is not ResourcePackImporter importer) + if (eventArgs.Argument is not ZipArchive zip) { worker.ReportProgressError("Invalid argument passed to background worker."); eventArgs.Cancel = true; return; } worker.ReportProgressInfo($"Start import"); - while(!(eventArgs.Cancel = worker.CancellationPending)) { - AtlasResource.AtlasType atlasType = AtlasResource.AtlasType.ParticleAtlas; - ImportResult<(Atlas atlas, IDictionary animations), ResourcePackImporter.ImportStats> res = importer.ImportAtlas(ResourceLocations.GetFromCategory(AtlasResource.GetId(atlasType)) as AtlasResource, true); + ImportResult res = _importer.ImportAsTexturePack(); + DLCPackageContent pck = _dlcManager.CompilePackage(res.Result); + worker.ReportProgressDebug("Import Stats"); worker.ReportProgressDebug($"Textures: {res.Stats.Textures}/{res.Stats.MaxTextures}({res.Stats.MissingTextures} missing)"); worker.ReportProgressDebug($"Animations: {res.Stats.Animations}"); // on success do: - if (true) + if (!worker.CancellationPending) { worker.ReportProgressInfo($"Import successful"); - eventArgs.Result = res.Result; + eventArgs.Result = pck; break; } } @@ -113,39 +125,23 @@ namespace PckStudio.Controls importButton.Click -= Cancel_Click; importButton.Click += Import_Click; importButton.Text = "Import"; - if (e.Cancelled) + if (e.Cancelled || importWorker.CancellationPending) { MessageBox.Show("Import cancelled", $"Import cancelled."); return; } MessageBox.Show("Import successful", $""); - (Atlas atlas, IDictionary animations) res = ((Atlas atlas, IDictionary animations))e.Result; - var f = new Form(); - f.Size = new Size(600, 600); - var picBox = new InterpolationPictureBox(); - picBox.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; - picBox.SizeMode = PictureBoxSizeMode.Zoom; - picBox.Dock = DockStyle.Fill; - picBox.Image = res.atlas; - f.Controls.Add(picBox); - f.ShowDialog(); + Result = (DLCPackageContent)e.Result; + DialogResult = DialogResult.OK; } - private void FormatPackDescription(string title, string text) + private void FormatPackDescription(string title, string description) { richTextBox1.SelectionAlignment = HorizontalAlignment.Center; richTextBox1.AppendLine("Name: "); - if (!FormatJavaFormatString(title)) - { - richTextBox1.SelectionAlignment = HorizontalAlignment.Left; - return; - } + FormatJavaFormatString(title); richTextBox1.AppendLine("Description: "); - if (!FormatJavaFormatString(text)) - { - richTextBox1.SelectionAlignment = HorizontalAlignment.Left; - return; - } + FormatJavaFormatString(description); richTextBox1.AppendLine(""); richTextBox1.SelectionAlignment = HorizontalAlignment.Left; } @@ -156,10 +152,10 @@ namespace PckStudio.Controls { richTextBox1.AppendLine(text); richTextBox1.AppendLine(""); - return false; + return true; } - foreach (KeyValuePair textSection in text.Split(['§'], StringSplitOptions.RemoveEmptyEntries).Select(s => new KeyValuePair("§" + char.ToLower(s[0]), string.IsNullOrWhiteSpace(s) ? string.Empty : s.Substring(1)))) + foreach (KeyValuePair textSection in text.Split(['§'], StringSplitOptions.RemoveEmptyEntries).Select(s => new KeyValuePair("§" + s[0], string.IsNullOrWhiteSpace(s) ? string.Empty : s.Substring(1)))) { FontStyle fontStyle = FontStyle.Regular; switch (textSection.Key) @@ -196,16 +192,19 @@ namespace PckStudio.Controls richTextBox1.SelectionFont = richTextBox1.Font; break; default: + richTextBox1.SelectionFont = new Font(richTextBox1.Font, fontStyle); + if (_javaColorCodeToColor.TryGetValue(textSection.Key, out RichTextBoxColor textColor)) + { + richTextBox1.AppendText(textSection.Value, textColor); + break; + } + Debug.WriteLine(textSection); + richTextBox1.AppendText(textSection.Key); + richTextBox1.AppendText(textSection.Value); + richTextBox1.AppendText(textSection.Key.Substring(1)); + richTextBox1.AppendText(textSection.Value); break; } - richTextBox1.SelectionFont = new Font(richTextBox1.Font, fontStyle); - if (_javaColorCodeToColor.TryGetValue(textSection.Key, out RichTextBoxColor textColor)) - { - richTextBox1.AppendText(textSection.Value, textColor); - break; - } - richTextBox1.AppendText(textSection.Key); - richTextBox1.AppendText(textSection.Value); } richTextBox1.AppendLine(""); return true; diff --git a/PCK-Studio/Controls/JavaTextFormatForm.resx b/PCK-Studio/Controls/JavaImportForm.resx similarity index 100% rename from PCK-Studio/Controls/JavaTextFormatForm.resx rename to PCK-Studio/Controls/JavaImportForm.resx diff --git a/PCK-Studio/Controls/ModelsPanel.cs b/PCK-Studio/Controls/ModelsPanel.cs index 3b38516b..1b532a06 100644 --- a/PCK-Studio/Controls/ModelsPanel.cs +++ b/PCK-Studio/Controls/ModelsPanel.cs @@ -69,7 +69,7 @@ namespace PckStudio.Controls _imageList.Images.Clear(); textureTreeView.Nodes.Clear(); - foreach ((int i, NamedData item) in textures.enumerate()) + foreach ((int i, NamedData item) in textures.Enumerate()) { _imageList.Images.Add(item.Value); textureTreeView.Nodes.Add(new NamedTextureTreeNode(item) { ImageIndex = i, SelectedImageIndex = i }); diff --git a/PCK-Studio/Controls/RawAssetsEditor.cs b/PCK-Studio/Controls/RawAssetsEditor.cs index c458d654..23cd6307 100644 --- a/PCK-Studio/Controls/RawAssetsEditor.cs +++ b/PCK-Studio/Controls/RawAssetsEditor.cs @@ -234,7 +234,7 @@ namespace PckStudio.Controls RawAssetDLCPackage rawAssetDLCPackage = new RawAssetDLCPackage(asset.Filename, pckFile, _originalEndianness); // TODO: may change to use a new tab page that will be closed when the main pck is closed - //Program.MainInstance.OpenNewPckTab(caption, identifier, RawAssetDLCPackage, saveContext); + Program.MainInstance.OpenNewPckTab(caption, identifier, rawAssetDLCPackage, saveContext); } private void HandleTextureFile(PckAsset asset) diff --git a/PCK-Studio/Controls/RichTextBoxHelper.cs b/PCK-Studio/Controls/RichTextBoxHelper.cs index a0f6c34f..09cfca9b 100644 --- a/PCK-Studio/Controls/RichTextBoxHelper.cs +++ b/PCK-Studio/Controls/RichTextBoxHelper.cs @@ -29,7 +29,14 @@ namespace PckStudio.Controls { if (!text.EndsWith("\n") && !text.EndsWith("\r\n")) text += Environment.NewLine; - box.AppendText(text); + + object Write() + { + box.AppendText(text); + box.Update(); + return box; + } + _ = box.InvokeRequired ? box.Invoke(Write) : Write(); } public static void AppendText(this RichTextBox box, string text, RichTextBoxColor colors) diff --git a/PCK-Studio/Controls/SkinsPanel.cs b/PCK-Studio/Controls/SkinsPanel.cs index 62ccf236..80490824 100644 --- a/PCK-Studio/Controls/SkinsPanel.cs +++ b/PCK-Studio/Controls/SkinsPanel.cs @@ -7,8 +7,10 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; +using DiscordRPC; using OMI.Formats.Pck; using OMI.Workers.Pck; +using PckStudio.Core.DLC; using PckStudio.Core.Extensions; using PckStudio.Core.Skin; @@ -18,9 +20,8 @@ namespace PckStudio.Controls { readonly PckFileReader _reader; readonly ImageList _imageList; - public SkinsPanel(OMI.ByteOrder byteOrder) + public SkinsPanel(OMI.ByteOrder byteOrder) : this() { - InitializeComponent(); _reader = new PckFileReader(byteOrder); _imageList = new ImageList() { @@ -30,13 +31,23 @@ namespace PckStudio.Controls treeView1.ImageList = _imageList; } + public SkinsPanel(DLCSkinPackage skinPackage) : this() + { + Reset(); + LoadTreeview(skinPackage.GetSkins()); + } + public override void LoadAsset(PckAsset asset, Action onChange) { Reset(); + LoadTreeview(asset.GetData(_reader).GetAssetsByType(PckAssetType.SkinFile).Select(PckAssetExtensions.GetSkin)); + } + + private void LoadTreeview(IEnumerable skins) + { treeView1.Nodes.AddRange( - asset.GetData(_reader).GetAssetsByType(PckAssetType.SkinFile) - .Select(PckAssetExtensions.GetSkin) - .enumerate() + skins + .Enumerate() .Select(a => { _imageList.Images.Add(a.value.GetPreviewImage(_imageList.ImageSize)); @@ -46,6 +57,11 @@ namespace PckStudio.Controls ); } + private SkinsPanel() + { + InitializeComponent(); + } + public override void Reset() { _imageList.Images.Clear(); diff --git a/PCK-Studio/Forms/Additional-Popups/Animation/ChangeTile.cs b/PCK-Studio/Forms/Additional-Popups/Animation/ChangeTile.cs index d56646e9..1b1838d6 100644 --- a/PCK-Studio/Forms/Additional-Popups/Animation/ChangeTile.cs +++ b/PCK-Studio/Forms/Additional-Popups/Animation/ChangeTile.cs @@ -63,7 +63,7 @@ namespace PckStudio.Forms.Additional_Popups.Animation }; TreeView view = filterPrompt.AddFilterPage(name, null, filterPredicate); view.ImageList = images.ToImageList(); - foreach ((int i, JsonTileInfo tileData) in textureInfos?.enumerate()) + foreach ((int i, JsonTileInfo tileData) in textureInfos?.Enumerate()) { if (string.IsNullOrEmpty(tileData.InternalName) || view.Nodes.ContainsKey(tileData.InternalName)) continue; diff --git a/PCK-Studio/Forms/Editor/ModelEditor.cs b/PCK-Studio/Forms/Editor/ModelEditor.cs index e8bbde4a..7e5538ab 100644 --- a/PCK-Studio/Forms/Editor/ModelEditor.cs +++ b/PCK-Studio/Forms/Editor/ModelEditor.cs @@ -228,7 +228,7 @@ namespace PckStudio.Forms.Editor textureImageList.Images.Clear(); namedTexturesTreeView.Nodes.Clear(); - foreach ((int i, NamedData item) in textures.enumerate()) + foreach ((int i, NamedData item) in textures.Enumerate()) { textureImageList.Images.Add(item.Value); namedTexturesTreeView.Nodes.Add(new NamedTextureTreeNode(item) { ImageIndex = i, SelectedImageIndex = i }); diff --git a/PCK-Studio/Forms/Editor/TextureAtlasEditor.cs b/PCK-Studio/Forms/Editor/TextureAtlasEditor.cs index ce64ea1c..ddc51185 100644 --- a/PCK-Studio/Forms/Editor/TextureAtlasEditor.cs +++ b/PCK-Studio/Forms/Editor/TextureAtlasEditor.cs @@ -464,7 +464,7 @@ namespace PckStudio.Forms.Editor e.Location, originalPictureBox.SizeMode, _imageLayout); - + Debug.WriteLine(index); if (index != -1) { SelectedIndex = index; diff --git a/PCK-Studio/Forms/Features/CemuPanel.cs b/PCK-Studio/Forms/Features/CemuPanel.cs index de85ef9b..311c1c74 100644 --- a/PCK-Studio/Forms/Features/CemuPanel.cs +++ b/PCK-Studio/Forms/Features/CemuPanel.cs @@ -34,9 +34,11 @@ namespace PckStudio.Forms.Features /// public partial class CemuPanel : UserControl { - private const string TitleId_EUR = "101d7500"; - private const string TitleId_USA = "101d9d00"; - private const string TitleId_JPN = "101dbe00"; + internal const string TITLE_ID_EUR = "101d7500"; + internal const string TITLE_ID_USA = "101d9d00"; + internal const string TITLE_ID_JPN = "101dbe00"; + internal const string BASE_ID = "00050000"; + internal const string UPDATE_ID = "0005000e"; public CemuPanel() { @@ -89,10 +91,11 @@ namespace PckStudio.Forms.Features return false; } - private bool TryApplyPermanentCemuConfig() + public static bool TryGetCemuMLCPath(out DirectoryInfo mlcDir) { string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Cemu"); string filepath = Path.Combine(path, "perm_setting.xml"); + mlcDir = null; if (Directory.Exists(path) && File.Exists(filepath)) { try @@ -105,9 +108,7 @@ namespace PckStudio.Forms.Features } XmlNode configNode = xml.SelectSingleNode("config"); XmlNode mlcpathNode = configNode.SelectSingleNode("MlcPath"); - GameDirectoryTextBox.Text = mlcpathNode.InnerText; - GameDirectoryTextBox.Enabled = false; - BrowseDirectoryBtn.Enabled = false; + mlcDir = new DirectoryInfo(mlcpathNode.InnerText); return true; } catch (Exception ex) @@ -119,19 +120,31 @@ namespace PckStudio.Forms.Features return false; } + private bool TryApplyPermanentCemuConfig() + { + if (TryGetCemuMLCPath(out DirectoryInfo mlcDir)) + { + GameDirectoryTextBox.Text = mlcDir.FullName; + GameDirectoryTextBox.Enabled = false; + BrowseDirectoryBtn.Enabled = false; + return true; + } + return false; + } + private string GetSelectedRegionTitleId() { if (radioButtonEur.Checked) { - return TitleId_EUR; + return TITLE_ID_EUR; } if (radioButtonUs.Checked) { - return TitleId_USA; + return TITLE_ID_USA; } if (radioButtonJap.Checked) { - return TitleId_JPN; + return TITLE_ID_JPN; } throw new Exception("how did you get here ?"); } @@ -329,9 +342,9 @@ namespace PckStudio.Forms.Features { if (IsValidInstallDirectory()) { - radioButtonEur.Enabled = Directory.Exists(GetGameContentPath(TitleId_EUR)); - radioButtonUs.Enabled = Directory.Exists(GetGameContentPath(TitleId_USA)); - radioButtonJap.Enabled = Directory.Exists(GetGameContentPath(TitleId_JPN)); + radioButtonEur.Enabled = Directory.Exists(GetGameContentPath(TITLE_ID_EUR)); + radioButtonUs.Enabled = Directory.Exists(GetGameContentPath(TITLE_ID_USA)); + radioButtonJap.Enabled = Directory.Exists(GetGameContentPath(TITLE_ID_JPN)); } ListDLCs(); } diff --git a/PCK-Studio/MainForm.cs b/PCK-Studio/MainForm.cs index 8f4540b2..eeea0efb 100644 --- a/PCK-Studio/MainForm.cs +++ b/PCK-Studio/MainForm.cs @@ -2,14 +2,16 @@ using System.Collections.Generic; using System.Diagnostics; using System.Drawing; +using System.Drawing.Imaging; using System.IO; +using System.IO.Compression; using System.Linq; using System.Text.RegularExpressions; using System.Windows.Forms; -using MetroFramework.Forms; using OMI.Formats.GameRule; using OMI.Formats.Languages; using OMI.Formats.Pck; +using OMI.Workers; using OMI.Workers.GameRule; using OMI.Workers.Language; using OMI.Workers.Pck; @@ -50,7 +52,7 @@ namespace PckStudio pckOpen.AllowDrop = true; - _dlcManager = new DLCManager(Settings.Default.Platform, Settings.Default.UserLanguage); + _dlcManager = new DLCManager(Settings.Default.Platform, Settings.Default.UserLanguage, Settings.Default.PackageType); Internal.SettingsManager.Default.RegisterPropertyChangedCallback(nameof(Settings.Default.UserLanguage), _dlcManager.SetPreferredLanguage); Internal.SettingsManager.Default.RegisterPropertyChangedCallback(nameof(Settings.Default.Platform), _dlcManager.SetPlatform); } @@ -178,6 +180,7 @@ namespace PckStudio if (TryGetEditor(page, out IEditor editor)) { editor.Close(); + _dlcManager.CloseDLCPackage(editor.EditorValue.Identifier); RemoveOpenFile(page); collection.Remove(page); } @@ -561,7 +564,79 @@ namespace PckStudio }; if (fileDialog.ShowDialog() != DialogResult.OK) return; - new JavaTextFormatForm(new FileInfo(fileDialog.FileName)).ShowDialog(); + var importDialog = new JavaImportForm(new FileInfo(fileDialog.FileName), _dlcManager); + if (importDialog.ShowDialog() == DialogResult.OK) + { + var dlcPackage = new RawAssetDLCPackage(importDialog.Result.Name, importDialog.Result.MainPck, _dlcManager.ByteOrder); + var datadlcPackage = new RawAssetDLCPackage(importDialog.Result.DataFolder?.TexturePck.Name, importDialog.Result.DataFolder?.TexturePck.Value, _dlcManager.ByteOrder); + + if (CemuPanel.TryGetCemuMLCPath(out DirectoryInfo mlcDir) && + MessageBoxEx.AskQuestion("Install pack locally ?", "Install", System.Windows.MessageBoxButton.YesNo) == System.Windows.MessageBoxResult.Yes) + { + string path = _dlcManager.GetInstallPath(); + DirectoryInfo dlcDir = mlcDir.CombineWithDirectoryName(path); + if (!dlcDir.Exists) + { + MessageBoxEx.ShowError("Failed to find dlc folder", "DLC Folder not found"); + return; + } + DirectoryInfo installDir = dlcDir.CreateSubdirectory(importDialog.Result.Name); + FileSystemInfo res = null; + if (_dlcManager.ContentSerilasationType == DLCPackageContentSerilasationType.Local) + res = CreateLocalPackage(installDir, importDialog.Result); + if (_dlcManager.ContentSerilasationType == DLCPackageContentSerilasationType.Share) + res = CreateSharablePackage(fileDialog.FileName, importDialog.Result); + Process.Start("explorer.exe", res.FullName); + } + + + AddEditorPage(dlcPackage); + AddEditorPage(datadlcPackage); + } + } + + private FileInfo CreateSharablePackage(string name, DLCPackageContent packageContent) + { + var fileInfo = new FileInfo(Path.Combine(Path.GetDirectoryName(name), Path.GetFileNameWithoutExtension(name) + "_pck.zip")); + Stream zipStream = fileInfo.OpenWrite(); + + using var zip = new ZipArchive(zipStream, ZipArchiveMode.Create); + { + zip.WriteEntry($"{(packageContent.HasDataFolder ? "TexturePack" : "Pack")}.pck", new PckFileWriter(packageContent.MainPck, _dlcManager.ByteOrder)); + } + + if (packageContent.HasDataFolder) + { + zip.WriteEntry($"Data/{packageContent.DataFolder.TexturePck.Name}", new PckFileWriter(packageContent.DataFolder.TexturePck.Value, _dlcManager.ByteOrder)); + + foreach (NamedData file in packageContent.DataFolder.Files) + { + zip.WriteEntry($"Data/{file.Name}", file.Value); + } + } + return fileInfo; + } + + private DirectoryInfo CreateLocalPackage(DirectoryInfo directory, DLCPackageContent packageContent) + { + directory.CombineWithFileName($"{(packageContent.HasDataFolder ? "TexturePack" : "Pack")}.pck") + .Write(new PckFileWriter(packageContent.MainPck, _dlcManager.ByteOrder)); + + if (packageContent.HasDataFolder) + { + DirectoryInfo dataDir = directory.CombineWithDirectoryName("Data"); + if (!dataDir.Exists) + dataDir.Create(); + + dataDir.CombineWithFileName($"{packageContent.DataFolder.TexturePck.Name}") + .Write(new PckFileWriter(packageContent.DataFolder.TexturePck.Value, _dlcManager.ByteOrder)); + + foreach (NamedData file in packageContent.DataFolder.Files) + { + dataDir.CombineWithFileName(file.Name).Write(file.Value); + } + } + return directory; } } } \ No newline at end of file diff --git a/PCK-Studio/PckStudio.csproj b/PCK-Studio/PckStudio.csproj index 06e8eed9..02325bc6 100644 --- a/PCK-Studio/PckStudio.csproj +++ b/PCK-Studio/PckStudio.csproj @@ -157,11 +157,11 @@ Form - + Form - - JavaTextFormatForm.cs + + JavaImportForm.cs UserControl @@ -433,8 +433,8 @@ DefaultPanel.cs - - JavaTextFormatForm.cs + + JavaImportForm.cs ModelsPanel.cs diff --git a/PCK-Studio/Properties/Settings.Designer.cs b/PCK-Studio/Properties/Settings.Designer.cs index 80cebed4..ea67072a 100644 --- a/PCK-Studio/Properties/Settings.Designer.cs +++ b/PCK-Studio/Properties/Settings.Designer.cs @@ -138,5 +138,17 @@ namespace PckStudio.Properties { this["UserLanguage"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("Local")] + public global::PckStudio.Core.DLC.DLCPackageContentSerilasationType PackageType { + get { + return ((global::PckStudio.Core.DLC.DLCPackageContentSerilasationType)(this["PackageType"])); + } + set { + this["PackageType"] = value; + } + } } } diff --git a/PCK-Studio/Properties/Settings.settings b/PCK-Studio/Properties/Settings.settings index 56c9a612..724dc114 100644 --- a/PCK-Studio/Properties/Settings.settings +++ b/PCK-Studio/Properties/Settings.settings @@ -29,8 +29,11 @@ Unknown - + System_Default + + Local + \ No newline at end of file diff --git a/PCK-Studio/Rendering/ModelRenderer.cs b/PCK-Studio/Rendering/ModelRenderer.cs index dbe64e55..4b16d77e 100644 --- a/PCK-Studio/Rendering/ModelRenderer.cs +++ b/PCK-Studio/Rendering/ModelRenderer.cs @@ -224,11 +224,8 @@ namespace PckStudio.Rendering if (e.Cancel) return; - if (Context.IsCurrent) - { - _modelRenderTexture.SetTexture(e.NewTexture); - GLErrorCheck(); - } + _modelRenderTexture.SetTexture(e.NewTexture); + GLErrorCheck(); } protected override void OnPaint(PaintEventArgs e) diff --git a/PckStudio.Core/Animation.cs b/PckStudio.Core/Animation.cs index 145ea5ef..83c544f3 100644 --- a/PckStudio.Core/Animation.cs +++ b/PckStudio.Core/Animation.cs @@ -140,6 +140,19 @@ namespace PckStudio.Core yield break; } + public void Resize(Size size) + { + GraphicsConfig gc = GraphicsConfig.PixelPerfect(); + (int texId, int ticks)[] textureIndecies = _frames.Select(f => (_textures.IndexOf(f.Texture), f.Ticks)).ToArray(); + IEnumerable resizedTextures = _textures.Select(t => t.Resize(size, gc)).ToArray(); + _textures.Clear(); + _frames.Clear(); + _textures.AddRange(resizedTextures); + foreach ((int texId, int ticks) in textureIndecies) + { + AddFrame(texId, ticks); + } + } public IReadOnlyCollection GetTextures() { diff --git a/PckStudio.Core/App/AppLanguage.cs b/PckStudio.Core/App/AppLanguage.cs index f597faff..96973e13 100644 --- a/PckStudio.Core/App/AppLanguage.cs +++ b/PckStudio.Core/App/AppLanguage.cs @@ -9,6 +9,7 @@ namespace PckStudio.Core.App public enum AppLanguage : int { System_Default, + Czech_Czechia, Czechia, Danish, diff --git a/PckStudio.Core/ArmorSetDescription.cs b/PckStudio.Core/ArmorSetDescription.cs index 5f63c6b7..19969df9 100644 --- a/PckStudio.Core/ArmorSetDescription.cs +++ b/PckStudio.Core/ArmorSetDescription.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Xml.Linq; using PckStudio.Core.Extensions; using PckStudio.Interfaces; @@ -45,6 +46,7 @@ namespace PckStudio.Core LayerCount = Math.Min(Math.Max(layerCount, 0), ('z' - 'b')); TextureCount = Math.Max(textureCount, 1); AssetCount = (LayerCount + 1) * TextureCount; + _pathLookUp.Add(name, this); foreach (var path in GetArmorNames()) { _pathLookUp.Add(path, this); @@ -75,6 +77,28 @@ namespace PckStudio.Core return result; } + public static IEnumerable> GetArmorSetTextures(ArmorSet armorSet) + { + if (!_pathLookUp.TryGetValue(armorSet.Name, out ArmorSetDescription armorSetDescription)) + return Enumerable.Empty>(); + + IEnumerable> textures = armorSet.BaseTexture.Split(new Size(armorSet.BaseTexture.Width, armorSet.BaseTexture.Height / 2), ImageLayoutDirection.Horizontal) + .Enumerate() + .Select(e => new NamedData($"{armorSet.Name}_{e.index + 1}", e.value)); + + if (armorSetDescription.LayerCount > 0 && armorSet.Layer is not null) + { + textures = textures.Concat(armorSet.Layer.Split(new Size(armorSet.Layer.Width, armorSet.Layer.Height / 2), ImageLayoutDirection.Horizontal) + .Enumerate() + .Select(e => new NamedData($"{armorSet.Name}_{e.index + 1}_{Convert.ToChar('b')}", e.value))); + } + + if (armorSet.Name == TURTLE) + return textures.Take(1); + + return textures; + } + public ArmorSet GetArmorSet(ITryGet tryGetTexture) { Image baseTexture = default; diff --git a/PckStudio.Core/Atlas/Atlas.cs b/PckStudio.Core/Atlas/Atlas.cs index c0677808..b6951b1b 100644 --- a/PckStudio.Core/Atlas/Atlas.cs +++ b/PckStudio.Core/Atlas/Atlas.cs @@ -42,7 +42,7 @@ namespace PckStudio.Core private readonly ImageLayoutDirection _layoutDirection; private readonly List _groups; - public static implicit operator Image(Atlas atlas) => atlas.BuildFinalImage(); + public static implicit operator Image(Atlas atlas) => atlas?.BuildFinalImage(); private Atlas(string name, int rows, int columns, IEnumerable tiles, Size tileSize, ImageLayoutDirection layoutDirection) @@ -63,7 +63,8 @@ namespace PckStudio.Core Size tileArea = atlasResource.GetTileArea(source.Size); int rows = source.Width / tileArea.Width; int columns = GameConstants.GetColumnCountForGameVersion(atlasResource.Type, gameVersion); - IEnumerable tiles = source.Split(tileArea, imageLayout).enumerate().Select(((int index, Image img) data) => new AtlasTile(data.img, GetSelectedPoint(data.index, out int col, rows, columns, imageLayout), col, index: data.index, userData: tilesInfo.IndexInRange(data.index) ? tilesInfo[data.index] : default)); + columns = columns == 0 ? source.Height / tileArea.Height : columns; + IEnumerable tiles = source.Split(tileArea, imageLayout).Enumerate().Select(((int index, Image img) data) => new AtlasTile(data.img, GetSelectedPoint(data.index, out int col, rows, columns, imageLayout), col, index: data.index, userData: tilesInfo.IndexInRange(data.index) ? tilesInfo[data.index] : default)); var atlas = new Atlas(atlasResource.Path, rows, columns, tiles, tileArea, imageLayout); atlas.AddGroups(atlasResource.AtlasGroups); return atlas; @@ -73,7 +74,7 @@ namespace PckStudio.Core { ImageLayoutDirection layoutDirection = default; Image none = new Bitmap(res, res); - IEnumerable tiles = Enumerable.Repeat(none, rows * columns).enumerate().Select(iv => new AtlasTile(iv.value, GetSelectedPoint(iv.index, out int col, rows, columns, layoutDirection), col, iv.index, default)); + IEnumerable tiles = Enumerable.Repeat(none, rows * columns).Enumerate().Select(iv => new AtlasTile(iv.value, GetSelectedPoint(iv.index, out int col, rows, columns, layoutDirection), col, iv.index, default)); return new Atlas(atlasResource.Path, rows, columns, tiles, none.Size, layoutDirection); } @@ -304,7 +305,7 @@ namespace PckStudio.Core AtlasResource.AtlasType.AdditionalMapIconsAtlas => Resources.additional_map_icons_atlas, _ => throw new InvalidOperationException() }; - return FromResourceLocation(defaultAtlas, atlasResource); + return FromResourceLocation(defaultAtlas, atlasResource, gameVersion); } } } \ No newline at end of file diff --git a/PckStudio.Core/AtlasResource.cs b/PckStudio.Core/AtlasResource.cs index 414ba5b4..5852b796 100644 --- a/PckStudio.Core/AtlasResource.cs +++ b/PckStudio.Core/AtlasResource.cs @@ -21,7 +21,6 @@ using System.Drawing; using System.IO; using System.Linq; using PckStudio.Core.Json; -using static PckStudio.Core.AtlasResource; namespace PckStudio.Core { @@ -89,5 +88,7 @@ namespace PckStudio.Core } public static ResourceCategory GetId(AtlasType atlasType) => (ResourceCategory)((int)ResourceCategory.Atlas | (int)atlasType); + + internal static AtlasResource Get(AtlasType atlasType) => ResourceLocations.GetFromCategory(GetId(atlasType)) as AtlasResource; } } diff --git a/PckStudio.Core/DLC/DLCManager.cs b/PckStudio.Core/DLC/DLCManager.cs index 924414b6..b4df626f 100644 --- a/PckStudio.Core/DLC/DLCManager.cs +++ b/PckStudio.Core/DLC/DLCManager.cs @@ -44,7 +44,7 @@ namespace PckStudio.Core.DLC public ConsolePlatform Platform => _platform; - public DLCPackageContentSerilasationType ContentSerilasationType { get; set; } = DLCPackageContentSerilasationType.Local; + public DLCPackageContentSerilasationType ContentSerilasationType => _packageContentSerilasationType; /// /// See for details. @@ -55,17 +55,20 @@ namespace PckStudio.Core.DLC private readonly Random _rng = new Random(); private ByteOrder _byteOrder; private ConsolePlatform _platform; + private readonly AppLanguage _preferredAppLanguage; + private readonly DLCPackageContentSerilasationType _packageContentSerilasationType; private PckFileCompiler _pckFileCompiler; /// /// /// See for details. - public DLCManager(ConsolePlatform platform, AppLanguage preferredLanguage) + public DLCManager(ConsolePlatform platform, AppLanguage preferredLanguage, DLCPackageContentSerilasationType packageContentSerilasationType) { _platform = platform; + _preferredAppLanguage = preferredLanguage; + _packageContentSerilasationType = packageContentSerilasationType; _byteOrder = GetByteOrderForPlatform(Platform); - _pckFileCompiler = new PckFileCompiler(_byteOrder, GetPlatformCompressionType(), GameRuleFile.CompressionLevel.None); SetPreferredLanguage(preferredLanguage); } @@ -147,14 +150,14 @@ namespace PckStudio.Core.DLC { _packageRegistry.RegisterPackage(identifier, package, localisation); } - return new RawAssetDLCPackage(fileInfo.Name, pckFile, ByteOrder); + return new RawAssetDLCPackage(fileInfo.Name, identifier, pckFile, ByteOrder); } public bool CloseDLCPackage(int identifier) => _packageRegistry.UnregisterPackage(identifier); internal LOCFile GetLocalisation(int identifier) { - return _packageRegistry.ContainsPackage(identifier) ? _packageRegistry.GetLocalisation(identifier) : default; + return _packageRegistry.ContainsPackage(identifier) ? _packageRegistry.GetLocalisation(identifier) : new LOCFile(); } private bool IsValidPckFile(FileInfo fileInfo) @@ -364,12 +367,14 @@ namespace PckStudio.Core.DLC ArmorSetDescription.Turtle.GetArmorSet(tryGetTexture), environmentData, AbstractColorContainer.FromColorContainer(colorContainer), - customModels, - materials, - blockEntityBreakAnimation, - itemAnimations, - blockAnimations, - sun, moon, + null, + null, + customModels: customModels, + materials: materials, + blockEntityBreakAnimation: blockEntityBreakAnimation, + itemAnimations: itemAnimations, + blockAnimations: blockAnimations, + sun: sun, moon: moon, parentPackage: null); } @@ -441,41 +446,29 @@ namespace PckStudio.Core.DLC } } - private GameRuleFile.CompressionType GetPlatformCompressionType() => GetCompressionTypeForPlatform(Platform); + internal GameRuleFile.CompressionType GetPlatformCompressionType() => GetCompressionTypeForPlatform(Platform); - private static string GetPreferredLanguage(AppLanguage appLanguage) + internal static string GetPreferredLanguage(AppLanguage appLanguage) { return appLanguage switch { AppLanguage.System_Default => LOCFile.ValidLanguages.Contains(CultureInfo.CurrentUICulture.Name) ? CultureInfo.CurrentUICulture.Name : AvailableLanguages.English, AppLanguage.Czech_Czechia => AvailableLanguages.CzechCzechia, AppLanguage.Czechia => AvailableLanguages.Czechia, - AppLanguage.Danish => AvailableLanguages.Danish, AppLanguage.Denmark_Danish => AvailableLanguages.DenmarkDanish, - AppLanguage.German_Austria => AvailableLanguages.GermanAustria, AppLanguage.German => AvailableLanguages.German, - AppLanguage.Greek_Greece => AvailableLanguages.GreekGreece, AppLanguage.Greece => AvailableLanguages.Greece, - AppLanguage.English_Australia => AvailableLanguages.EnglishAustralia, - AppLanguage.English_Canada => AvailableLanguages.EnglishCanada, AppLanguage.English => AvailableLanguages.English, AppLanguage.English_UnitedKingdom => AvailableLanguages.EnglishUnitedKingdom, - AppLanguage.English_Ireland => AvailableLanguages.EnglishIreland, - AppLanguage.English_NewZealand => AvailableLanguages.EnglishNewZealand, - AppLanguage.English_USA=> AvailableLanguages.EnglishUnitedStatesOfAmerica, AppLanguage.Spanish_Spain => AvailableLanguages.SpanishSpain, AppLanguage.Spanish_Mexico => AvailableLanguages.SpanishMexico, AppLanguage.Finnish_Finland => AvailableLanguages.FinnishFinland, AppLanguage.French_France => AvailableLanguages.FrenchFrance, - AppLanguage.French_Canada => AvailableLanguages.FrenchCanada, AppLanguage.Italian_Italy => AvailableLanguages.ItalianItaly, AppLanguage.Japanese_Japan => AvailableLanguages.JapaneseJapan, AppLanguage.Korean_South_Korea => AvailableLanguages.KoreanSouthKorea, - AppLanguage.Latin => AvailableLanguages.Latin, - AppLanguage.Norwegian_Norway => AvailableLanguages.NorwegianNorway, AppLanguage.Norwegian_Bokmål_Norway => AvailableLanguages.NorwegianBokmålNorway, AppLanguage.Dutch_Netherlands => AvailableLanguages.DutchNetherlands, - AppLanguage.Dutch_Belgium => AvailableLanguages.DutchBelgium, AppLanguage.Polish_Poland => AvailableLanguages.PolishPoland, AppLanguage.Portuguese_Brazil => AvailableLanguages.PortugueseBrazil, AppLanguage.Portuguese_Portugal => AvailableLanguages.PortuguesePortugal, @@ -484,9 +477,6 @@ namespace PckStudio.Core.DLC AppLanguage.Swedish_Sweden => AvailableLanguages.SwedishSweden, AppLanguage.Turkish_Turkey => AvailableLanguages.TurkishTurkey, AppLanguage.Chinese_China => AvailableLanguages.ChineseChina, - AppLanguage.Chinese_HongKong => AvailableLanguages.ChineseHongKong, - AppLanguage.Chinese_Singapore => AvailableLanguages.ChineseSingapore, - AppLanguage.Chinese_Taiwan => AvailableLanguages.ChineseTaiwan, _ => AvailableLanguages.English, }; } @@ -501,6 +491,7 @@ namespace PckStudio.Core.DLC public DLCPackageContent CompilePackage(IDLCPackage package) { + _pckFileCompiler = new PckFileCompiler(this); LOCFile localisation = GetLocalisation(package.Identifier); switch (package.GetDLCPackageType()) { @@ -519,5 +510,83 @@ namespace PckStudio.Core.DLC } return DLCPackageContent.Empty; } + + private enum ConsoleRegion + { + US, + EU, + JP + } + + public string GetInstallPath() + { + switch (Platform) + { + case ConsolePlatform.Wii_U: + ConsoleRegion region = GetRegionFromLanguage(); + string titleId = region switch + { + ConsoleRegion.US => "101d9d00", + ConsoleRegion.EU => "101d7500", + ConsoleRegion.JP => "101dbe00", + _ => throw new Exception() + }; + return $"usr/title/0005000e/{titleId}/content/WiiU/DLC"; + default: + return ""; + } + } + + private ConsoleRegion GetRegionFromLanguage() + { + switch (_preferredAppLanguage) + { + case AppLanguage.System_Default: + case AppLanguage.Czech_Czechia: + case AppLanguage.Czechia: + case AppLanguage.Danish: + case AppLanguage.Denmark_Danish: + case AppLanguage.German_Austria: + case AppLanguage.German: + case AppLanguage.Greek_Greece: + case AppLanguage.English_UnitedKingdom: + case AppLanguage.English_Ireland: + case AppLanguage.Spanish_Spain: + case AppLanguage.Finnish_Finland: + case AppLanguage.French_France: + case AppLanguage.Dutch_Netherlands: + case AppLanguage.Dutch_Belgium: + case AppLanguage.Polish_Poland: + case AppLanguage.Norwegian_Norway: + case AppLanguage.Norwegian_Bokmål_Norway: + case AppLanguage.Italian_Italy: + case AppLanguage.Slovak_Slovakia: + case AppLanguage.Swedish_Sweden: + case AppLanguage.Turkish_Turkey: + case AppLanguage.Russian_Russia: + case AppLanguage.Greece: + return ConsoleRegion.EU; + case AppLanguage.English_Australia: + case AppLanguage.English_Canada: + case AppLanguage.English: + case AppLanguage.English_NewZealand: + case AppLanguage.Spanish_Mexico: + case AppLanguage.French_Canada: + case AppLanguage.English_USA: + return ConsoleRegion.US; + case AppLanguage.Korean_South_Korea: + case AppLanguage.Chinese_China: + case AppLanguage.Chinese_HongKong: + case AppLanguage.Chinese_Singapore: + case AppLanguage.Chinese_Taiwan: + case AppLanguage.Japanese_Japan: + return ConsoleRegion.JP; + case AppLanguage.Portuguese_Brazil: + case AppLanguage.Portuguese_Portugal: + case AppLanguage.Latin: + default: + throw new NotImplementedException(); + } + } } } \ No newline at end of file diff --git a/PckStudio.Core/DLC/DLCPackageContent.cs b/PckStudio.Core/DLC/DLCPackageContent.cs index a3b4965c..f31b9d10 100644 --- a/PckStudio.Core/DLC/DLCPackageContent.cs +++ b/PckStudio.Core/DLC/DLCPackageContent.cs @@ -6,13 +6,15 @@ namespace PckStudio.Core.DLC { public class DLCPackageContent { - public static DLCPackageContent Empty => new DLCPackageContent(default); + public static DLCPackageContent Empty => new DLCPackageContent(nameof(Empty), default); - internal bool IsEmpty { get; } + public bool IsEmpty { get; } - internal PckFile MainPck { get; } + public string Name { get; } + public PckFile MainPck { get; } - internal DLCDataFolderContent DataFolder { get; } + public bool HasDataFolder => DataFolder != null; + public DLCDataFolderContent DataFolder { get; } public record DLCDataFolderContent { @@ -30,18 +32,19 @@ namespace PckStudio.Core.DLC public void AddFile(string name, byte[] data) => AddFile(new NamedData(name, data)); } - public DLCPackageContent(PckFile mainPck, NamedData texturePck, NamedData[] dataFiles) - : this(mainPck, new(texturePck, dataFiles ?? Array.Empty>())) + public DLCPackageContent(string name, PckFile mainPck, NamedData texturePck, NamedData[] dataFiles) + : this(name, mainPck, new(texturePck, dataFiles ?? Array.Empty>())) { } - public DLCPackageContent(PckFile mainPck, DLCDataFolderContent dataFolderContent) + public DLCPackageContent(string name, PckFile mainPck, DLCDataFolderContent dataFolderContent) { MainPck = mainPck; DataFolder = dataFolderContent; + Name = name; IsEmpty = mainPck is null; } - public DLCPackageContent(PckFile mainPck) : this(mainPck, default) { } + public DLCPackageContent(string name, PckFile mainPck) : this(name, mainPck, default) { } } } \ No newline at end of file diff --git a/PckStudio.Core/DLC/DLCTexturePackage.cs b/PckStudio.Core/DLC/DLCTexturePackage.cs index 18cda190..409dae98 100644 --- a/PckStudio.Core/DLC/DLCTexturePackage.cs +++ b/PckStudio.Core/DLC/DLCTexturePackage.cs @@ -50,26 +50,27 @@ namespace PckStudio.Core.DLC public MetaData Info { get; } - //! Data for x{16}Data.pck - //! => colours.col private AbstractColorContainer _colorContainter; private AbstractModelContainer _customModels; //! can be null.. => models.bin private IDictionary _materials; //! can be null.. + private IDictionary _itemModelTextures; //! can be null.. + private IDictionary _mobModelTextures; //! can be null.. - //! terrain mipmaps will be generated automatically. Add mipmap option to settings menu ? -null private Atlas _terrainAtlas; private Atlas _itemsAtlas; private Atlas _particlesAtlas; private Atlas _paintingAtlas; private Atlas _moonPhaseAtlas; + private Atlas _mapIconsAtlas; + private Atlas _additionalMapIconsAtlas; + private ArmorSet _leatherArmorSet; private ArmorSet _chainArmorSet; private ArmorSet _ironArmorSet; private ArmorSet _goldArmorSet; private ArmorSet _diamondArmorSet; private ArmorSet _turtleArmorSet; - private Atlas _mapIconsAtlas; - private Atlas _additionalMapIconsAtlas; + private EnvironmentData _environmentData; private Animation _blockEntityBreakAnimation; @@ -101,6 +102,8 @@ namespace PckStudio.Core.DLC ArmorSet turtleArmorSet, EnvironmentData environmentData, AbstractColorContainer colorContainter, + IDictionary itemModelTextures, + IDictionary mobModelTextures, AbstractModelContainer customModels, IDictionary materials, Animation blockEntityBreakAnimation, @@ -108,8 +111,7 @@ namespace PckStudio.Core.DLC IDictionary blockAnimations, Image sun, Image moon, - IDLCPackage parentPackage - ) + IDLCPackage parentPackage) : base(name, identifier, parentPackage) { Description = description; @@ -132,11 +134,51 @@ namespace PckStudio.Core.DLC _colorContainter = colorContainter; _customModels = customModels; _materials = materials; - _blockEntityBreakAnimation = blockEntityBreakAnimation; + _blockEntityBreakAnimation = blockEntityBreakAnimation ?? new Animation(terrainAtlas.GetRange(0, 15, 10, ImageLayoutDirection.Horizontal).Select(t => t.Texture).ToArray(), true); _itemAnimations = itemAnimations ?? new Dictionary(); _blockAnimations = blockAnimations ?? new Dictionary(); _sun = sun; - _moon = moon; + _moon = moon ?? moonPhaseAtlas?[0]?.Texture ?? default; + + foreach (KeyValuePair item in GetDefaultItemAnimations()) + { + if (!_itemAnimations.ContainsKey(item.Key)) + _itemAnimations.Add(item); + } + + foreach (KeyValuePair item in GetDefaultBlockAnimations()) + { + if (!_blockAnimations.ContainsKey(item.Key)) + _blockAnimations.Add(item); + } + + _itemModelTextures = itemModelTextures; + _mobModelTextures = mobModelTextures; + SetTextureSizeForResolution(); + } + + private void SetTextureSizeForResolution() + { + Size size = GetTextureSize(); + + Atlas[] atlases = [_terrainAtlas, _itemsAtlas, _particlesAtlas, _paintingAtlas]; + foreach (Atlas item in atlases) + { + item?.SetTileSize(size); + } + + _blockEntityBreakAnimation.Resize(size); + + foreach (KeyValuePair item in _itemAnimations) + { + item.Value.Resize(size); + } + + foreach (KeyValuePair item in _blockAnimations) + { + item.Value.Resize(size); + } + } public TextureResolution GetResolution() => _resolution; @@ -158,6 +200,23 @@ namespace PckStudio.Core.DLC }; } + public static TextureResolution GetTextureResolution(Size size) + { + return size switch + { + { Width: 8, Height: 8 } => TextureResolution.x8, + { Width: 16, Height: 16 } => TextureResolution.x16, + { Width: 32, Height: 32 } => TextureResolution.x32, + { Width: 48, Height: 48 } => TextureResolution.x48, + { Width: 64, Height: 64 } => TextureResolution.x64, + { Width: 80, Height: 80 } => TextureResolution.x80, + { Width: 96, Height: 96 } => TextureResolution.x96, + { Width: 112, Height: 112 } => TextureResolution.x112, + { Width: 128, Height: 128 } => TextureResolution.x128, + _ => TextureResolution.x16 + }; + } + public static TextureResolution GetTextureResolutionFromString(string input) { _ = input ?? throw new ArgumentNullException(nameof(input)); @@ -191,12 +250,12 @@ namespace PckStudio.Core.DLC MetaData metadata = new MetaData(Resources.Comparison, Resources.TexturePackIcon); - Atlas terrain = Atlas.FromResourceLocation(Resources.terrain_atlas, ResourceLocation.GetFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.BlockAtlas))); - Atlas items = Atlas.FromResourceLocation(Resources.items_atlas, ResourceLocation.GetFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.ItemAtlas))); - Atlas particles = Atlas.FromResourceLocation(Resources.particles_atlas, ResourceLocation.GetFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.ParticleAtlas))); - Atlas painting = Atlas.FromResourceLocation(Resources.paintings_atlas, ResourceLocation.GetFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.PaintingAtlas))); - Atlas moonPhases = Atlas.FromResourceLocation(Resources.moon_phases_atlas, ResourceLocation.GetFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.MoonPhaseAtlas))); - Atlas mapIconsAtlas = Atlas.FromResourceLocation(Resources.map_icons_atlas, ResourceLocation.GetFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.MapIconAtlas))); + Atlas terrain = AtlasResource.Get(AtlasResource.AtlasType.BlockAtlas).GetDefaultAtlas(); + Atlas items = AtlasResource.Get(AtlasResource.AtlasType.ItemAtlas).GetDefaultAtlas(); + Atlas particles = AtlasResource.Get(AtlasResource.AtlasType.ParticleAtlas).GetDefaultAtlas(); + Atlas painting = AtlasResource.Get(AtlasResource.AtlasType.PaintingAtlas).GetDefaultAtlas(); + Atlas moonPhases = AtlasResource.Get(AtlasResource.AtlasType.MoonPhaseAtlas).GetDefaultAtlas(); + Atlas mapIconsAtlas = AtlasResource.Get(AtlasResource.AtlasType.MapIconAtlas).GetDefaultAtlas(); Atlas additionalMapIconsAtlas = Atlas.FromResourceLocation(Resources.additional_map_icons_atlas, ResourceLocation.GetFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.AdditionalMapIconsAtlas))); //ColorContainer colors = new COLFileReader().FromStream(new MemoryStream()); IDictionary colors = null; @@ -204,8 +263,8 @@ namespace PckStudio.Core.DLC Animation blockEntityBreakAnimation = new Animation(terrain.GetRange(0, 15, 10, ImageLayoutDirection.Horizontal).Select(t => t.Texture).ToArray(), true, 3); - IDictionary itemAnimations = GetItemAnimations(); - IDictionary blockAnimations = GetBlockAnimations(); + IDictionary itemAnimations = GetDefaultItemAnimations(); + IDictionary blockAnimations = GetDefaultBlockAnimations(); return new DLCTexturePackage( name, description, identifier, metadata, resolution, @@ -218,26 +277,30 @@ namespace PckStudio.Core.DLC new ArmorSet(ArmorSetDescription.TURTLE, Resources.turtle, default), new EnvironmentData(Resources.clouds, Resources.rain, Resources.snow), new AbstractColorContainer(colors, waterColors), - new AbstractModelContainer(), - new Dictionary(), - blockEntityBreakAnimation, - itemAnimations, - blockAnimations, + itemModelTextures: null, + mobModelTextures: null, + customModels: new AbstractModelContainer(), + materials: new Dictionary(), + blockEntityBreakAnimation: blockEntityBreakAnimation, + itemAnimations: itemAnimations, + blockAnimations: blockAnimations, sun: null, moon: null, - parentPackage + parentPackage: parentPackage ); } - internal Atlas GetTerrainAtlas() => _terrainAtlas; + internal Atlas GetTerrainAtlas() => _terrainAtlas ?? AtlasResource.Get(AtlasResource.AtlasType.BlockAtlas).GetDefaultAtlas(); + internal Atlas GetItemsAtlas() => _itemsAtlas ?? AtlasResource.Get(AtlasResource.AtlasType.ItemAtlas).GetDefaultAtlas(); + internal Atlas GetParticleAtlas() => _particlesAtlas ?? AtlasResource.Get(AtlasResource.AtlasType.ParticleAtlas).GetDefaultAtlas(); + internal Atlas GetPaintingAtlas() => _paintingAtlas ?? AtlasResource.Get(AtlasResource.AtlasType.PaintingAtlas).GetDefaultAtlas(); + internal Atlas GetMoonPhaseAtlas() => _moonPhaseAtlas ?? AtlasResource.Get(AtlasResource.AtlasType.MoonPhaseAtlas).GetDefaultAtlas(); + internal IDictionary GetItemAnimations() => _itemAnimations; + internal IDictionary GetBlockAnimations() => _blockAnimations; + internal IEnumerable GetArmorSets() => new ArmorSet[] { _leatherArmorSet, _chainArmorSet, _ironArmorSet, _goldArmorSet, _diamondArmorSet, _turtleArmorSet }.Where(armorSet => armorSet is not null); + internal Animation GetBlockEntityBreakAnimation() => _blockEntityBreakAnimation; - internal Atlas GetItemsAtlas() => _itemsAtlas; - - internal Atlas GetParticleAtlas() => _particlesAtlas; - - internal Atlas GetPaintingAtlas() => _paintingAtlas; - - private static IDictionary GetItemAnimations() + private static IDictionary GetDefaultItemAnimations() { return new Dictionary() { @@ -246,7 +309,7 @@ namespace PckStudio.Core.DLC }; } - private static IDictionary GetBlockAnimations() + private static IDictionary GetDefaultBlockAnimations() { return new Dictionary() { @@ -254,5 +317,13 @@ namespace PckStudio.Core.DLC ["fire_1"] = new Animation(Resources.fire_layer_1.Split(ImageLayoutDirection.Vertical), true) }; } + + internal Image GetSunTexture() => _sun; + + internal Image GetMoonTexture() => _moon; + + internal IEnumerable> GetItemModelTextures() => _itemModelTextures; + + internal IEnumerable> GetMobModelTextures() => _mobModelTextures; } } \ No newline at end of file diff --git a/PckStudio.Core/DLC/PckFileCompiler.cs b/PckStudio.Core/DLC/PckFileCompiler.cs index 5e3ec54f..4248fefc 100644 --- a/PckStudio.Core/DLC/PckFileCompiler.cs +++ b/PckStudio.Core/DLC/PckFileCompiler.cs @@ -1,42 +1,51 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Drawing; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using DiscordRPC; using OMI; using OMI.Formats.GameRule; using OMI.Formats.Languages; +using OMI.Formats.Model; using OMI.Formats.Pck; +using OMI.Workers.Color; using OMI.Workers.GameRule; using OMI.Workers.Language; +using OMI.Workers.Model; using OMI.Workers.Pck; using PckStudio.Core.Extensions; using PckStudio.Core.Interfaces; using PckStudio.Core.IO.PckAudio; +using PckStudio.Core.Properties; +using PckStudio.Core.Serializer; namespace PckStudio.Core.DLC { internal sealed class PckFileCompiler { + private readonly string _language; private ByteOrder _byteOrder; private GameRuleFile.CompressionType _compressionType; private GameRuleFile.CompressionLevel _compressionLevel; - internal PckFileCompiler(ByteOrder byteOrder, GameRuleFile.CompressionType compressionType, GameRuleFile.CompressionLevel compressionLevel) + internal PckFileCompiler(DLCManager dlcManager) { - _byteOrder = byteOrder; - _compressionType = compressionType; - _compressionLevel = compressionLevel; + _language = dlcManager.PreferredLanguage; + _byteOrder = dlcManager.ByteOrder; + _compressionType = dlcManager.GetPlatformCompressionType(); + _compressionLevel = GameRuleFile.CompressionLevel.None; } - private PckFile CreateRootPckFile(int packId, int packVerison, LOCFile localisation) + private PckFile CreateRootPckFile(int packId, int packVerison) { - PckFile mainPck = new PckFile(); + PckFile mainPck = new PckFile(3, true); PckAsset meta = mainPck.CreateNewAsset("0", PckAssetType.InfoFile); meta.AddProperty("PACKID", packId); meta.AddProperty("PACKVERSION", packVerison); - mainPck.CreateNewAsset("localisation.loc", PckAssetType.LocalisationFile, new LOCFileWriter(localisation, 2)); return mainPck; } @@ -45,18 +54,25 @@ namespace PckStudio.Core.DLC if (package is not DLCSkinPackage skinPackage) return DLCPackageContent.Empty; - PckFile skinsPck = skinPackage.IsRootPackage ? CreateRootPckFile(package.Identifier, 0, localisation) : new PckFile(); + PckFile pckFile = new PckFile(); + if (skinPackage.IsRootPackage) + { + localisation.AddLanguage(_language); + localisation.AddLocKey(DLCManager.PACKAGE_DISPLAYNAME_ID, package.Name); + pckFile = CreateRootPckFile(package.Identifier, 0); + } foreach (KeyValuePair kv in skinPackage.GetCapes()) { - PckAsset capeAsset = skinsPck.CreateNewAsset($"dlccape{kv.Key:08}.png", PckAssetType.CapeFile); + PckAsset capeAsset = pckFile.CreateNewAsset($"dlccape{kv.Key:08}.png", PckAssetType.CapeFile); capeAsset.SetTexture(kv.Value); } foreach (Skin.Skin skin in skinPackage.GetSkins()) { - skinsPck.AddSkin("", skin, localisation); + pckFile.AddSkin("", skin, localisation); } - return new DLCPackageContent(skinsPck); + pckFile.CreateNewAsset("localisation.loc", PckAssetType.LocalisationFile, new LOCFileWriter(localisation, 2)); + return new DLCPackageContent(package.Name, pckFile); } internal DLCPackageContent CompileTexturePackage(IDLCPackage package, LOCFile localisation) @@ -66,29 +82,113 @@ namespace PckStudio.Core.DLC PckFile texturePackInfoPck = new PckFile(); { - texturePackInfoPck.AddTexture("comparison.png", texturePackage.Info.ComparisonImg); - texturePackInfoPck.AddTexture("icon.png", texturePackage.Info.IconImg); + Image comparison = texturePackage.Info?.ComparisonImg ?? Resources.Comparison; + Image icon = texturePackage.Info?.IconImg ?? Resources.TexturePackIcon; + texturePackInfoPck.AddTexture("comparison.png", comparison); + texturePackInfoPck.AddTexture("icon.png", icon); } PckFile texturePck = new PckFile(); { - texturePck.AddTexture(ResourceLocations.GetPathFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.ParticleAtlas)), texturePackage.GetParticleAtlas()); + texturePck.CreateNewAsset("0", PckAssetType.InfoFile); + + texturePck.AddTexture(ResourceLocations.GetPathFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.BlockAtlas)), texturePackage.GetTerrainAtlas(), 2); + texturePck.AddTexture(ResourceLocations.GetPathFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.ItemAtlas)), texturePackage.GetItemsAtlas()); - texturePck.AddTexture(ResourceLocations.GetPathFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.BlockAtlas)), texturePackage.GetTerrainAtlas()); + texturePck.AddTexture(ResourceLocations.GetPathFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.ParticleAtlas)), texturePackage.GetParticleAtlas()); texturePck.AddTexture(ResourceLocations.GetPathFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.PaintingAtlas)), texturePackage.GetPaintingAtlas()); + texturePck.AddTexture(ResourceLocations.GetPathFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.MoonPhaseAtlas)), texturePackage.GetMoonPhaseAtlas()); + + texturePck.AddTexture("res/terrain/sun.png", texturePackage.GetSunTexture()); + texturePck.AddTexture("res/terrain/moon.png", texturePackage.GetMoonTexture()); + + string itemAnimationsPath = ResourceLocations.GetPathFromCategory(ResourceCategory.ItemAnimation); + foreach (KeyValuePair animation in texturePackage.GetItemAnimations()) + { + string path = Path.Combine(itemAnimationsPath, animation.Key).Replace("\\", "/"); + PckAsset asset = texturePck.CreateNewAsset(path + ".png", PckAssetType.TextureFile); + asset.SetSerializedData(animation.Value, AnimationSerializer.DefaultSerializer); + if (animation.Key == "clock" || animation.Key == "compass") + { + asset.SetProperty("ANIM", ""); + } + } + + string blockAnimationsPath = ResourceLocations.GetPathFromCategory(ResourceCategory.BlockAnimation); + foreach (KeyValuePair animation in texturePackage.GetBlockAnimations()) + { + string path = Path.Combine(blockAnimationsPath, animation.Key).Replace("\\", "/"); + PckAsset asset = texturePck.CreateNewAsset(path + ".png", PckAssetType.TextureFile); + asset.SetSerializedData(animation.Value, AnimationSerializer.DefaultSerializer); + } + + string armorTexturePath = ResourceLocations.GetPathFromCategory(ResourceCategory.ArmorTextures); + foreach (NamedData armorTexture in texturePackage.GetArmorSets().SelectMany(ArmorSetDescription.GetArmorSetTextures)) + { + string path = Path.Combine(armorTexturePath, armorTexture.Name).Replace("\\", "/"); + PckAsset asset = texturePck.CreateNewAsset(path + ".png", PckAssetType.TextureFile); + asset.SetSerializedData(armorTexture.Value, ImageSerializer.DefaultSerializer); + } + + { + foreach ((int i, Animation.Frame frame) in texturePackage.GetBlockEntityBreakAnimation().GetFrames().Enumerate()) + { + texturePck.AddTexture($"res/textures/destroy_stage_{i}.png", frame.Texture); + } + } + + { + string mapIconAtlasPath = ResourceLocations.GetPathFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.MapIconAtlas)).Replace("\\", "/"); + string additionalMapIconsAtlasPath = ResourceLocations.GetPathFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.AdditionalMapIconsAtlas)).Replace("\\", "/"); + PckAsset mapIconAtlasAsset = texturePck.CreateNewAsset(mapIconAtlasPath, PckAssetType.TextureFile); + PckAsset additionalMapIconsAtlasAsset = texturePck.CreateNewAsset(additionalMapIconsAtlasPath, PckAssetType.TextureFile); + mapIconAtlasAsset.SetTexture(Resources.map_icons_atlas); + additionalMapIconsAtlasAsset.SetTexture(Resources.additional_map_icons_atlas); + } + + //{ + // PckAsset modelsAsset = texturePck.CreateNewAsset("models.bin", PckAssetType.ModelsFile); + // modelsAsset.SetData(new ModelFileWriter(new ModelContainer(), 0)); + //} + + //{ + // PckAsset colorsAsset = texturePck.CreateNewAsset("colours.col", PckAssetType.ColourTableFile); + // colorsAsset.SetData(Resources.tu69colours); + //} + + { + foreach (KeyValuePair itemTexture in texturePackage.GetItemModelTextures()) + { + texturePck.AddTexture($"res/{itemTexture.Key}.png", itemTexture.Value); + } + foreach (KeyValuePair mobTexture in texturePackage.GetMobModelTextures()) + { + texturePck.AddTexture($"res/{mobTexture.Key}.png", mobTexture.Value); + } + } } if (package.IsRootPackage) { - PckFile mainPck = CreateRootPckFile(package.Identifier, 0, localisation); + foreach (string language in LOCFile.ValidLanguages) + localisation.AddLanguage(language); + PckFile mainPck = CreateRootPckFile(package.Identifier, 0); + localisation.AddLocKey(DLCManager.PACKAGE_DISPLAYNAME_ID, package.Name); + localisation.AddLocKey(DLCTexturePackage.TEXTUREPACK_DESCRIPTION_ID, package.Description); DLCTexturePackage.TextureResolution res = texturePackage.GetResolution(); + localisation.AddLocKey($"IDS_{res.ToString().ToUpper()}_{res.ToString().ToUpper()}INFO_DISPLAYNAME", ""); PckAsset textureInfoAsset = mainPck.CreateNewAsset($"{res}/{res}Info.pck", PckAssetType.TexturePackInfoFile, new PckFileWriter(texturePackInfoPck, _byteOrder)); textureInfoAsset.AddProperty("PACKID", "0"); textureInfoAsset.AddProperty("DATAPATH", $"{res}Data.pck"); - return new DLCPackageContent(mainPck, new NamedData($"{res}Data.pck", texturePck), default); + + PckAsset loc = new PckAsset("languages.loc", PckAssetType.LocalisationFile); + loc.SetData(new LOCFileWriter(localisation, 2)); + //! LOC file needs to be the first asset in the pack -_-.... don't ask why.. -null + mainPck.InsertAsset(0, loc); + return new DLCPackageContent(package.Name, mainPck, new NamedData($"{res}Data.pck", texturePck), default); } - return new DLCPackageContent(texturePackInfoPck); + return new DLCPackageContent(package.Name, texturePackInfoPck); } internal DLCPackageContent CompileMashUpPackage(IDLCPackage package, LOCFile localisation) @@ -104,7 +204,7 @@ namespace PckStudio.Core.DLC PckFile texturePackInfoPck = texturePackContent.MainPck; PckFile texturePck = texturePackContent.DataFolder.TexturePck.Value; - PckFile mainPck = CreateRootPckFile(package.Identifier, 0, localisation); + PckFile mainPck = CreateRootPckFile(package.Identifier, 0); _ = mainPck.CreateNewAssetIf(skinsPck is PckFile && skinsPck.AssetCount > 0, "Skins.pck", PckAssetType.SkinDataFile, new PckFileWriter(skinsPck, _byteOrder)); if (texturePackInfoPck is PckFile && texturePackInfoPck.AssetCount > 0) @@ -128,12 +228,12 @@ namespace PckStudio.Core.DLC texturePackContent.DataFolder.AddFiles(mashUpPackage.GetAudioFiles()); } - return new DLCPackageContent(mainPck, texturePackContent.DataFolder); + return new DLCPackageContent(package.Name, mainPck, texturePackContent.DataFolder); } internal DLCPackageContent CompileRawAssets(IDLCPackage package) { - return package is RawAssetDLCPackage rawAssetDLCPackage ? new DLCPackageContent(rawAssetDLCPackage.PckFile) : DLCPackageContent.Empty; + return package is RawAssetDLCPackage rawAssetDLCPackage ? new DLCPackageContent(package.Name, rawAssetDLCPackage.PckFile) : DLCPackageContent.Empty; } } } diff --git a/PckStudio.Core/DLC/RawAssetDLCPackage.cs b/PckStudio.Core/DLC/RawAssetDLCPackage.cs index cc24da7d..bab14d70 100644 --- a/PckStudio.Core/DLC/RawAssetDLCPackage.cs +++ b/PckStudio.Core/DLC/RawAssetDLCPackage.cs @@ -14,7 +14,10 @@ namespace PckStudio.Core.DLC public ByteOrder ByteOrder { get; } public RawAssetDLCPackage(string name, PckFile pckFile, ByteOrder byteOrder) - : base(name ?? nameof(RawAssetDLCPackage), -1, default) + : this(name, -1, pckFile, byteOrder) + { } + public RawAssetDLCPackage(string name, int id, PckFile pckFile, ByteOrder byteOrder) + : base(name ?? nameof(RawAssetDLCPackage), id, default) { PckFile = pckFile; ByteOrder = byteOrder; diff --git a/PckStudio.Core/Deserializer/AnimationDeserializer.cs b/PckStudio.Core/Deserializer/AnimationDeserializer.cs index f9f7ce5a..784ee4d9 100644 --- a/PckStudio.Core/Deserializer/AnimationDeserializer.cs +++ b/PckStudio.Core/Deserializer/AnimationDeserializer.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Drawing; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; using Newtonsoft.Json.Linq; using OMI.Formats.Pck; @@ -71,8 +72,8 @@ namespace PckStudio.Core.Deserializer { IEnumerable textures = texture.Split(ImageLayoutDirection.Vertical); Animation result = new Animation(textures); - if (jsonObject["animation"] is not JToken animation) - return result; + if (jsonObject["animation"] is not JToken animation || !animation.HasValues) + return new Animation(textures, true); int frameTime = Animation.MINIMUM_FRAME_TIME; @@ -89,15 +90,14 @@ namespace PckStudio.Core.Deserializer if (frame.Type == JTokenType.Object && frame["index"] is JToken frame_index && frame_index.Type == JTokenType.Integer && + frame_index.ToObject().IsWithinRangeOf(0, result.TextureCount - 1) && frame["time"] is JToken frame_time && frame_time.Type == JTokenType.Integer) { - Debug.WriteLine("Index: {0}, Time: {1}", frame_index, frame_time); result.AddFrame((int)frame_index, (int)frame_time); } - else if (frame.Type == JTokenType.Integer) + else if (frame.Type == JTokenType.Integer && frame.ToObject().IsWithinRangeOf(0, result.TextureCount - 1)) { - Debug.WriteLine("Index: {0}, Time: {1}", frame, frameTime); result.AddFrame((int)frame, frameTime); } } diff --git a/PckStudio.Core/Deserializer/ImageDeserializer.cs b/PckStudio.Core/Deserializer/ImageDeserializer.cs index bc365d7c..c2992631 100644 --- a/PckStudio.Core/Deserializer/ImageDeserializer.cs +++ b/PckStudio.Core/Deserializer/ImageDeserializer.cs @@ -5,6 +5,7 @@ using System.IO; using OMI.Formats.Pck; using PckStudio.Interfaces; using PckStudio.Core.IO.TGA; +using PckStudio.Core.Extensions; namespace PckStudio.Core.Deserializer { @@ -24,7 +25,7 @@ namespace PckStudio.Core.Deserializer Image img = Path.GetExtension(asset.Filename) == ".tga" ? TGADeserializer.DeserializeFromStream(stream) - : Image.FromStream(stream); + : Image.FromStream(stream).ReleaseFromFile(); return img.RawFormat != ImageFormat.Jpeg || img.RawFormat != ImageFormat.Png ? new Bitmap(img) : img; } } diff --git a/PckStudio.Core/Extensions/AnimationExtensions.cs b/PckStudio.Core/Extensions/AnimationExtensions.cs index 5d99c839..8b955c7a 100644 --- a/PckStudio.Core/Extensions/AnimationExtensions.cs +++ b/PckStudio.Core/Extensions/AnimationExtensions.cs @@ -40,7 +40,7 @@ namespace PckStudio.Core.Extensions Image[] secondTextures = second.GetTextures().ToArray(); - Animation animation = new Animation(first.GetTextures().enumerate().Select(ift => ift.value.Combine(secondTextures[ift.index], layoutDirection))); + Animation animation = new Animation(first.GetTextures().Enumerate().Select(ift => ift.value.Combine(secondTextures[ift.index], layoutDirection))); foreach ((int texId, int frameTime) item in first.GetFrames().Select(f => (texId: first.GetTextureIndex(f.Texture), frameTime: f.Ticks))) { animation.AddFrame(item.texId, item.frameTime); diff --git a/PckStudio.Core/Extensions/ColorExtensions.cs b/PckStudio.Core/Extensions/ColorExtensions.cs index 0cb29dce..1948ccec 100644 --- a/PckStudio.Core/Extensions/ColorExtensions.cs +++ b/PckStudio.Core/Extensions/ColorExtensions.cs @@ -1,4 +1,6 @@ -using System.Drawing; +using System; +using System.Drawing; +using System.Drawing.Imaging; using System.Numerics; namespace PckStudio.Core.Extensions @@ -60,6 +62,105 @@ namespace PckStudio.Core.Extensions return (byte)(ratio * val1 + (1.0 - ratio) * val2); } + public static Color GetAvgColor(this Image source) + { + Bitmap bm = new Bitmap(source); + BitmapData srcData = bm.LockBits( + new Rectangle(0, 0, bm.Width, bm.Height), + ImageLockMode.ReadOnly, + PixelFormat.Format32bppArgb); + + int stride = srcData.Stride; + + IntPtr scan0 = srcData.Scan0; + + long[] totals = new long[] { 0, 0, 0 }; + + int width = bm.Width; + int height = bm.Height; + int pixelCount = width * height; + + unsafe + { + byte* p = (byte*)(void*)scan0; + + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + int idx = (y * stride) + x * 4; + + totals[idx + 0] += p[idx]; + totals[idx + 1] += p[idx]; + totals[idx + 2] += p[idx]; + } + } + } + bm.UnlockBits(srcData); + + int avgB = (int)(totals[0] / pixelCount); + int avgG = (int)(totals[1] / pixelCount); + int avgR = (int)(totals[2] / pixelCount); + return Color.FromArgb(avgR, avgG, avgB); + } + + public static Image ToGreyScale(this Image source, out Color avgColor) + { + Bitmap bm = new Bitmap(source); + BitmapData srcData = bm.LockBits( + new Rectangle(0, 0, bm.Width, bm.Height), + ImageLockMode.ReadOnly, + PixelFormat.Format32bppArgb); + + int stride = srcData.Stride; + + IntPtr scan0 = srcData.Scan0; + + long[] totals = new long[] { 0, 0, 0 }; + + int width = bm.Width; + int height = bm.Height; + int pixelCount = width * height; + + unsafe + { + byte* p = (byte*)(void*)scan0; + + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + int idx = (y * stride) + x * 4; + + byte r = p[idx + 0]; + byte g = p[idx + 1]; + byte b = p[idx + 2]; + + totals[idx + 0] += r; + totals[idx + 1] += g; + totals[idx + 2] += b; + + byte gs = (byte)((r + g + b) / 3f); + p[idx + 0] = gs; + p[idx + 1] = gs; + p[idx + 2] = gs; + } + } + } + bm.UnlockBits(srcData); + + int avgB = (int)(totals[0] / pixelCount); + int avgG = (int)(totals[1] / pixelCount); + int avgR = (int)(totals[2] / pixelCount); + avgColor = Color.FromArgb(avgR, avgG, avgB); + return bm; + } + + public static string ToHTMLColor(this Color color) + { + return $"#{color.ToArgb().ToString("X").Substring(2)}"; + } + public static Color Mix(this Color c1, Color c2, float ratio) { ratio = MathExtensions.Clamp(ratio, 0.0f, 1.0f); diff --git a/PckStudio.Core/Extensions/DirectoryInfoExtensions.cs b/PckStudio.Core/Extensions/DirectoryInfoExtensions.cs new file mode 100644 index 00000000..b7e282ef --- /dev/null +++ b/PckStudio.Core/Extensions/DirectoryInfoExtensions.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PckStudio.Core.Extensions +{ + public static class DirectoryInfoExtensions + { + public static FileInfo CombineWithFileName(this DirectoryInfo directoryInfo, string fileName) + { + return new FileInfo(Path.Combine(directoryInfo.FullName, fileName)); + } + + public static DirectoryInfo CombineWithDirectoryName(this DirectoryInfo directoryInfo, string directoryName) + { + string path = Path.Combine(directoryInfo.FullName, directoryName); + return new DirectoryInfo(path); + } + } +} diff --git a/PckStudio.Core/Extensions/EnumerableExtensions.cs b/PckStudio.Core/Extensions/EnumerableExtensions.cs index f4571c07..18f341b1 100644 --- a/PckStudio.Core/Extensions/EnumerableExtensions.cs +++ b/PckStudio.Core/Extensions/EnumerableExtensions.cs @@ -7,7 +7,7 @@ namespace PckStudio.Core.Extensions { public static class EnumerableExtensions { - public static IEnumerable<(int index, T value)>enumerate(this IEnumerable array) + public static IEnumerable<(int index, T value)>Enumerate(this IEnumerable array) { int i = 0; foreach (T item in array) @@ -33,15 +33,7 @@ namespace PckStudio.Core.Extensions .Select(t => t.ToString()) .Aggregate((res, next) => string.IsNullOrWhiteSpace(next) ? res : res + seperator + next); - public static bool EqualsAny(this T type, params T[] items) - { - foreach (T item in items) - { - if (item.Equals(type)) - return true; - } - return false; - } + public static bool EqualsAny(this T type, params T[] items) => items.Any(item => item.Equals(type)); public static bool ContainsAny(this IEnumerable source, params T[] items) => source.Any(t => items.Contains(t)); } diff --git a/PckStudio.Core/Extensions/FileInfoExtensions.cs b/PckStudio.Core/Extensions/FileInfoExtensions.cs new file mode 100644 index 00000000..4168f773 --- /dev/null +++ b/PckStudio.Core/Extensions/FileInfoExtensions.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OMI.Workers; + +namespace PckStudio.Core.Extensions +{ + public static class FileInfoExtensions + { + public static void Write(this FileInfo fileInfo, IDataFormatWriter formatWriter) + { + using (Stream stream = !fileInfo.Exists ? fileInfo.Create() : fileInfo.OpenWrite()) + { + formatWriter.WriteToStream(stream); + } + } + + public static void Write(this FileInfo fileInfo, Image image, ImageFormat format) + { + using (Stream stream = !fileInfo.Exists ? fileInfo.Create() : fileInfo.OpenWrite()) + { + image.Save(stream, format); + } + } + + public static void Write(this FileInfo fileInfo, byte[] data) + { + using (Stream stream = !fileInfo.Exists ? fileInfo.Create() : fileInfo.OpenWrite()) + { + stream.Write(data, 0, data.Length); + } + } + + } +} diff --git a/PckStudio.Core/Extensions/GraphicsExtensions.cs b/PckStudio.Core/Extensions/GraphicsExtensions.cs index 48238fc3..b7fa1315 100644 --- a/PckStudio.Core/Extensions/GraphicsExtensions.cs +++ b/PckStudio.Core/Extensions/GraphicsExtensions.cs @@ -22,13 +22,12 @@ namespace PckStudio.Core.Extensions graphics.PixelOffsetMode = config.PixelOffsetMode; } - public static Graphics Fill(this Graphics graphics, Rectangle area, Color color) + public static void Fill(this Graphics graphics, Rectangle area, Color color) { Region clip = graphics.Clip; graphics.SetClip(area, CombineMode.Replace); graphics.Clear(color); graphics.SetClip(clip, CombineMode.Replace); - return graphics; } } } diff --git a/PckStudio.Core/Extensions/ImageExtensions.cs b/PckStudio.Core/Extensions/ImageExtensions.cs index ffe55af9..524331cc 100644 --- a/PckStudio.Core/Extensions/ImageExtensions.cs +++ b/PckStudio.Core/Extensions/ImageExtensions.cs @@ -39,6 +39,13 @@ namespace PckStudio.Core.Extensions return img; } + public static Color GetColor(this Image image, Point location) => image.GetColor(location.X, location.Y); + public static Color GetColor(this Image image, int x, int y) => new Bitmap(image).GetPixel(x, y); + + public static Image GetArea(this Image source, int x, int y, int width, int height) + => source.GetArea(new Point(x, y), new Size(width, height)); + public static Image GetArea(this Image source, Point location, Size size) + => source.GetArea(new Rectangle(location, size)); public static Image GetArea(this Image source, Rectangle area) { Image result = new Bitmap(area.Width, area.Height); @@ -60,7 +67,7 @@ namespace PckStudio.Core.Extensions public static Image CreateMipMap(this Image image, int level) { - int factor = (int)Math.Pow(2, level - 1); + int factor = Math.Max(1, (int)Math.Pow(2, level - 1)); int newWidth = Math.Max(image.Width / factor, 1); int newHeight = Math.Max(image.Height / factor, 1); @@ -143,7 +150,7 @@ namespace PckStudio.Core.Extensions using (var graphic = Graphics.FromImage(image)) { graphic.ApplyConfig(GraphicsConfig.PixelPerfect()); - foreach ((int i, Image texture) in sources.enumerate()) + foreach ((int i, Image texture) in sources.Enumerate()) { int x = Math.DivRem(i, columns, out int y); if (horizontal) @@ -173,15 +180,17 @@ namespace PckStudio.Core.Extensions return size; } - public static Image Resize(this Image image, Size size, GraphicsConfig graphicsConfig) - { - return image.Resize(size.Width, size.Height, graphicsConfig); - } - public static Image Resize(this Image image, int width, int height, GraphicsConfig graphicsConfig) { - var destRect = new Rectangle(0, 0, width, height); - var destImage = new Bitmap(width, height); + return image.Resize(new Size(width, height), graphicsConfig); + } + + public static Image Resize(this Image image, Size size, GraphicsConfig graphicsConfig) + { + if (image.Size == size) + return image; + var destRect = new Rectangle(Point.Empty, size); + var destImage = new Bitmap(size.Width, size.Height); destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution); diff --git a/PckStudio.Core/Extensions/MessageBoxEx.cs b/PckStudio.Core/Extensions/MessageBoxEx.cs new file mode 100644 index 00000000..e33b9716 --- /dev/null +++ b/PckStudio.Core/Extensions/MessageBoxEx.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; + +namespace PckStudio.Core.Extensions +{ + public static class MessageBoxEx + { + public static MessageBoxResult Show(string messageBoxText, string title, MessageBoxButton button, MessageBoxImage icon) => MessageBox.Show(messageBoxText, title, button, icon); + + public static void ShowError(string messageBoxText, string title) => Show(messageBoxText, title, MessageBoxButton.OK, MessageBoxImage.Error); + public static MessageBoxResult ShowWarning(string messageBoxText, string title, MessageBoxButton button) => Show(messageBoxText, title, button, MessageBoxImage.Warning); + public static MessageBoxResult AskQuestion(string question, string title, MessageBoxButton button) => Show(question, title, button, MessageBoxImage.Question); + public static MessageBoxResult ShowInfo(string messageBoxText, string title) => Show(messageBoxText, title, MessageBoxButton.OK, MessageBoxImage.Information); + } +} diff --git a/PckStudio.Core/Extensions/PckAssetExtensions.cs b/PckStudio.Core/Extensions/PckAssetExtensions.cs index 3550ac65..c6562a94 100644 --- a/PckStudio.Core/Extensions/PckAssetExtensions.cs +++ b/PckStudio.Core/Extensions/PckAssetExtensions.cs @@ -19,7 +19,7 @@ namespace PckStudio.Core.Extensions { public static class PckAssetExtensions { - private const string MIPMAP_LEVEL = "MipMapLevel"; + internal const string MIPMAP_LEVEL = "MipMapLevel"; public static Image GetTexture(this PckAsset asset) { diff --git a/PckStudio.Core/Extensions/PckFileExtensions.cs b/PckStudio.Core/Extensions/PckFileExtensions.cs index 1ca6b476..3f81fcd2 100644 --- a/PckStudio.Core/Extensions/PckFileExtensions.cs +++ b/PckStudio.Core/Extensions/PckFileExtensions.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; +using System.Net.NetworkInformation; using System.Text; using System.Threading.Tasks; using System.Windows; @@ -16,10 +18,29 @@ namespace PckStudio.Core.Extensions public static class PckFileExtensions { public static PckAsset AddTexture(this PckFile pck, string assetPath, Image texture) + => pck.AddTexture(assetPath, texture, 0); + public static PckAsset AddTexture(this PckFile pck, string assetPath, Image texture, int mipMapCount) { - PckAsset asset = new PckAsset(assetPath, PckAssetType.TextureFile); + if (string.IsNullOrEmpty(assetPath) || texture is null) + return default; + + PckAsset asset = pck.CreateNewAsset(assetPath, PckAssetType.TextureFile); asset.SetTexture(texture); - pck.AddAsset(asset); + string textureExtension = Path.GetExtension(assetPath); + string dir = Path.GetDirectoryName(assetPath); + string name = Path.GetFileNameWithoutExtension(assetPath); + for (int i = 0; i < mipMapCount; i++) + { + int mipMapLevel = i + 2; + string mippedPath = $"{dir}/{name}{PckAssetExtensions.MIPMAP_LEVEL}{mipMapLevel}{textureExtension}"; + Debug.WriteLine(mippedPath); + if (pck.HasAsset(mippedPath, PckAssetType.TextureFile)) + pck.RemoveAsset(pck.GetAsset(mippedPath, PckAssetType.TextureFile)); + Image mippedTexture = texture.CreateMipMap(mipMapLevel); + + PckAsset mipMappedAsset = pck.CreateNewAsset(mippedPath, PckAssetType.TextureFile); + mipMappedAsset.SetTexture(mippedTexture); + } return asset; } diff --git a/PckStudio.Core/Extensions/StringExtensions.cs b/PckStudio.Core/Extensions/StringExtensions.cs new file mode 100644 index 00000000..bff8d435 --- /dev/null +++ b/PckStudio.Core/Extensions/StringExtensions.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PckStudio.Core.Extensions +{ + internal static class StringExtensions + { + + public static string End(this string str, int count) + { + return str.Substring(str.Length - count); + } + } +} diff --git a/PckStudio.Core/Extensions/TreeNodeCollectionExtensions.cs b/PckStudio.Core/Extensions/TreeNodeCollectionExtensions.cs index f04118b5..0a432fa3 100644 --- a/PckStudio.Core/Extensions/TreeNodeCollectionExtensions.cs +++ b/PckStudio.Core/Extensions/TreeNodeCollectionExtensions.cs @@ -41,7 +41,7 @@ namespace PckStudio.Core.Extensions if (string.IsNullOrWhiteSpace(nodeText)) return BuildNodeTreeBySeperator(root, subPath, seperator, maxDepth - 1); - TreeNode subNode = root.ContainsKey(nodeText) ? root[nodeText] : root.CreateNode(nodeText); + TreeNode subNode = root.ContainsKey(nodeText) ? root.Find(nodeText, searchAllChildren: false).FirstOrDefault(node => node.Tag is null) ?? root.CreateNode(nodeText) : root.CreateNode(nodeText); return BuildNodeTreeBySeperator(subNode.Nodes, subPath, seperator, maxDepth - 1); } diff --git a/PckStudio.Core/Extensions/ZipArchiveEntryExtensions.cs b/PckStudio.Core/Extensions/ZipArchiveEntryExtensions.cs index b58dd1c8..00922ea9 100644 --- a/PckStudio.Core/Extensions/ZipArchiveEntryExtensions.cs +++ b/PckStudio.Core/Extensions/ZipArchiveEntryExtensions.cs @@ -6,10 +6,12 @@ using System.IO.Compression; using System.Linq; using System.Text; using System.Threading.Tasks; +using ICSharpCode.SharpZipLib.GZip; +using OMI.Workers; namespace PckStudio.Core.Extensions { - internal static class ZipArchiveEntryExtensions + public static class ZipArchiveEntryExtensions { public static string ReadAllText(this ZipArchiveEntry entry) { @@ -30,9 +32,31 @@ namespace PckStudio.Core.Extensions return image; } - public static IEnumerable GetDirectoryContent(this ZipArchive zip, string path, string extention = "") + public static IEnumerable GetDirectoryContent(this ZipArchive zip, string path, string extension = "", bool includeSubDirectories = false) { - return zip.Entries.Where(e => e.FullName.StartsWith(path) && e.Name.EndsWith(extention) && !e.Name.EndsWith("/") && !e.Name.EndsWith("\\")); + string sanitisedDirectoryPath = path.Replace('\\', '/'); + return zip.Entries + .Where(e => e.FullName.StartsWith(sanitisedDirectoryPath)) + .Where(e => includeSubDirectories || (e.FullName.Substring(sanitisedDirectoryPath.Length).LastIndexOf('/') == 0 || e.FullName.Substring(sanitisedDirectoryPath.Length).LastIndexOf('/') == -1)) + .Where(e => string.IsNullOrWhiteSpace(extension) || e.FullName.EndsWith(extension)); + } + + public static ZipArchiveEntry WriteEntry(this ZipArchive zip, string name, byte[] data) + { + ZipArchiveEntry zipEntry = zip.CreateEntry(name, CompressionLevel.Fastest); + Stream entryStream = zipEntry.Open(); + entryStream.Write(data, 0, data.Length); + entryStream.Dispose(); + return zipEntry; + } + + public static ZipArchiveEntry WriteEntry(this ZipArchive zip, string name, IDataFormatWriter writer) + { + ZipArchiveEntry zipEntry = zip.CreateEntry(name, CompressionLevel.Fastest); + Stream entryStream = zipEntry.Open(); + writer.WriteToStream(entryStream); + entryStream.Dispose(); + return zipEntry; } } } diff --git a/PckStudio.Core/GameConstants.cs b/PckStudio.Core/GameConstants.cs index 12e95bc4..9845819a 100644 --- a/PckStudio.Core/GameConstants.cs +++ b/PckStudio.Core/GameConstants.cs @@ -115,7 +115,8 @@ namespace PckStudio.Core LCEGameVersion._1_14 when atlasType == AtlasResource.AtlasType.BlockAtlas => 39, _ when atlasType == AtlasResource.AtlasType.PaintingAtlas => 16, _ when atlasType == AtlasResource.AtlasType.ParticleAtlas => 16, - _ => throw new NotImplementedException() + _ when atlasType == AtlasResource.AtlasType.MoonPhaseAtlas => 2, + _ => 0 }; } } diff --git a/PckStudio.Core/IO/Java/ImportStatusReport.cs b/PckStudio.Core/IO/Java/ImportStatusReport.cs new file mode 100644 index 00000000..be5a99db --- /dev/null +++ b/PckStudio.Core/IO/Java/ImportStatusReport.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PckStudio.Core.IO.Java +{ + public class ImportStatusReport + { +#if DEBUG + public static ImportStatusReport Debug = new ImportStatusReport(System.Diagnostics.Debug.Listeners); +#endif +#if TRACE + public static ImportStatusReport Trace = new ImportStatusReport(System.Diagnostics.Trace.Listeners); +#endif + + private readonly TraceListener[] _listeners; + + private ImportStatusReport(TraceListenerCollection listeners) + { + _listeners = new TraceListener[listeners.Count]; + listeners.CopyTo(_listeners, 0); + } + + private ImportStatusReport(params TraceListener[] listeners) + { + _listeners = listeners; + } + + private class ImportStatusReportTextWriter : TextWriter + { + private readonly Action _postMessage; + + public override Encoding Encoding => Encoding.Default; + + public ImportStatusReportTextWriter(Action postMessage) => _postMessage = postMessage; + + public override void Write(string value) => _postMessage(value); + public override void WriteLine(string value) => _postMessage(value + Environment.NewLine); + } + + public static ImportStatusReport CreateCustom(Action postMessage) + { + TextWriterTraceListener listener = new TextWriterTraceListener(new ImportStatusReportTextWriter(postMessage)); + return new ImportStatusReport(listener); + } + + public void Post(string message) + { + foreach (TraceListener listener in _listeners) + { + listener.WriteLine(message); + } + } + } +} diff --git a/PckStudio.Core/IO/Java/JavaConstants.cs b/PckStudio.Core/IO/Java/JavaConstants.cs new file mode 100644 index 00000000..0b7bd4b0 --- /dev/null +++ b/PckStudio.Core/IO/Java/JavaConstants.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PckStudio.Core.IO.Java +{ + internal class JavaConstants + { + + public static Dictionary JavaColorCodeToColor { get; } = new Dictionary() + { + ["§0"] = (Color.FromArgb(0x00, 0x00, 0x00), Color.FromArgb(18, 18, 18)), + ["§1"] = (Color.FromArgb(0x00, 0x00, 0xAA), Color.FromArgb(0x00, 0x00, 0x2A)), + ["§2"] = (Color.FromArgb(0x00, 0xAA, 0x00), Color.FromArgb(0x00, 0x2A, 0x00)), + ["§3"] = (Color.FromArgb(0x00, 0xAA, 0xAA), Color.FromArgb(0x00, 0x2A, 0x2A)), + ["§4"] = (Color.FromArgb(0xAA, 0x00, 0x00), Color.FromArgb(0x2A, 0x00, 0x00)), + ["§5"] = (Color.FromArgb(0xAA, 0x00, 0xAA), Color.FromArgb(0x2A, 0x00, 0x2A)), + ["§6"] = (Color.FromArgb(0xFF, 0xAA, 0x00), Color.FromArgb(0x2A, 0x2A, 0x00)), + ["§7"] = (Color.FromArgb(0xAA, 0xAA, 0xAA), Color.FromArgb(0x2A, 0x2A, 0x2A)), + ["§8"] = (Color.FromArgb(0x55, 0x55, 0x55), Color.FromArgb(0x15, 0x15, 0x15)), + ["§9"] = (Color.FromArgb(0x55, 0x55, 0xFF), Color.FromArgb(0x15, 0x15, 0x3F)), + ["§a"] = (Color.FromArgb(0x55, 0xFF, 0x55), Color.FromArgb(0x15, 0x3F, 0x15)), + ["§b"] = (Color.FromArgb(0x55, 0xFF, 0xFF), Color.FromArgb(0x15, 0x3F, 0x3F)), + ["§c"] = (Color.FromArgb(0xFF, 0x55, 0x55), Color.FromArgb(0x3F, 0x15, 0x15)), + ["§d"] = (Color.FromArgb(0xFF, 0x55, 0xFF), Color.FromArgb(0x3F, 0x15, 0x3F)), + ["§e"] = (Color.FromArgb(0xFF, 0xFF, 0x55), Color.FromArgb(0x3F, 0x3F, 0x15)), + ["§f"] = (Color.FromArgb(0xFF, 0xFF, 0xFF), Color.FromArgb(0x3F, 0x3F, 0x3F)), + ["§g"] = (Color.FromArgb(0xDD, 0xD6, 0x05), Color.FromArgb(0x37, 0x35, 0x01)), + ["§h"] = (Color.FromArgb(0xE3, 0xD4, 0xD1), Color.FromArgb(0x38, 0x35, 0x34)), + ["§i"] = (Color.FromArgb(0xCE, 0xCA, 0xCA), Color.FromArgb(0x33, 0x32, 0x32)), + ["§j"] = (Color.FromArgb(0x44, 0x3A, 0x3B), Color.FromArgb(0x11, 0x0E, 0x0E)), + ["§m"] = (Color.FromArgb(0x97, 0x16, 0x07), Color.FromArgb(0x25, 0x05, 0x01)), + ["§n"] = (Color.FromArgb(0xB4, 0x68, 0x4D), Color.FromArgb(0x2D, 0x1A, 0x13)), + ["§p"] = (Color.FromArgb(0xDE, 0xB1, 0x2D), Color.FromArgb(0x37, 0x2C, 0x0B)), + ["§q"] = (Color.FromArgb(0x47, 0xA0, 0x36), Color.FromArgb(0x04, 0x28, 0x0D)), + ["§s"] = (Color.FromArgb(0x2C, 0xBA, 0xA8), Color.FromArgb(0x0B, 0x2E, 0x2A)), + ["§t"] = (Color.FromArgb(0x21, 0x49, 0x7B), Color.FromArgb(0x08, 0x12, 0x1E)), + ["§u"] = (Color.FromArgb(0x9A, 0x5C, 0xC6), Color.FromArgb(0x26, 0x17, 0x31)), + }; + + public static readonly Color BirchLeaves = Color.FromArgb(unchecked((int)0xFF_80A755)); + public static readonly Color SpruceLeaves = Color.FromArgb(unchecked((int)0xFF_619961)); + public static readonly Color LilyPad = Color.FromArgb(unchecked((int)0xFF_208030)); + public static readonly Color AttachedMelonStem = Color.FromArgb(unchecked((int)0xFF_E0C71C)); + public static readonly Color AttachedPumpkinStem = Color.FromArgb(unchecked((int)0xFF_E0C71C)); + } +} diff --git a/PckStudio.Core/IO/Java/McPackmeta.cs b/PckStudio.Core/IO/Java/McPackmeta.cs index d83e60d2..5690033e 100644 --- a/PckStudio.Core/IO/Java/McPackmeta.cs +++ b/PckStudio.Core/IO/Java/McPackmeta.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json; +using System.Drawing; +using Newtonsoft.Json; namespace PckStudio.Core.IO.Java { @@ -8,10 +9,17 @@ namespace PckStudio.Core.IO.Java public McPack Pack; public struct McPack { - [JsonProperty("pack_format")] - public int Format; + [JsonIgnore] + public Image Icon; + + [JsonIgnore] + public int Format => _format; + [JsonProperty("description")] public string Description; + + [JsonProperty("pack_format")] + private int _format; } } } diff --git a/PckStudio.Core/IO/Java/ResourcePackImporter.cs b/PckStudio.Core/IO/Java/ResourcePackImporter.cs index 4278a375..c848b505 100644 --- a/PckStudio.Core/IO/Java/ResourcePackImporter.cs +++ b/PckStudio.Core/IO/Java/ResourcePackImporter.cs @@ -5,15 +5,12 @@ using System.Drawing; using System.IO; using System.IO.Compression; using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Documents; -using ICSharpCode.SharpZipLib.GZip; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using PckStudio.Core.Deserializer; using PckStudio.Core.DLC; using PckStudio.Core.Extensions; +using PckStudio.Core.Json; using PckStudio.Core.Properties; namespace PckStudio.Core.IO.Java @@ -21,9 +18,10 @@ namespace PckStudio.Core.IO.Java public class ResourcePackImporter { internal const int TARGET_FORMAT_VERSION = 4; - internal const string JAVA_RESOURCE_PACK_PATH = "assets/minecraft/textures"; + private const string JAVA_RESOURCE_PACK_PATH = "assets/minecraft/"; + private const string JAVA_TEXTURES_PATH = "textures"; - static readonly IReadOnlyDictionary _formatToVersion = new Dictionary() + static readonly IReadOnlyDictionary _formatVeriosnToGameVersion = new Dictionary() { [1] = new VersionRange("1.6.1", "1.8.9"), [2] = new VersionRange("1.9", "1.10.2"), @@ -53,7 +51,7 @@ namespace PckStudio.Core.IO.Java [69] = new VersionRange("1.21.9", "1.21.10"), }; - public class ImportStats(int maxTextures) + public class TextureImportStats(int maxTextures) { public int Animations => animations; public int Textures => textures; @@ -63,108 +61,354 @@ namespace PckStudio.Core.IO.Java internal int animations = 0; internal int textures = 0; private int _maxTextures = maxTextures; + + public static TextureImportStats operator +(TextureImportStats lhs, TextureImportStats rhs) + { + return new TextureImportStats(lhs.MaxTextures + rhs.MaxTextures) { animations = lhs.Animations + rhs.Animations, textures = lhs.Textures + rhs.Textures }; + } } - LCEGameVersion _gameVersion; - ZipArchive _zip; - McPackmeta.McPack packMeta; + private readonly LCEGameVersion _gameVersion; + private string _name; + private ImportStatusReport _importStatus; + private McPackmeta.McPack _packMeta; + private Dictionary _resoursePackData; - public ResourcePackImporter(ZipArchive zip, LCEGameVersion gameVersion) + public ResourcePackImporter(LCEGameVersion gameVersion) { - _zip = zip; _gameVersion = gameVersion; - packMeta = ReadPackMeta(zip); } - public static bool IsJavaResourcePack(ZipArchive zip) => zip.GetEntry("pack.mcmeta") is ZipArchiveEntry; + public static bool IsJavaResourcePack(ZipArchive zip) => zip.GetEntry("pack.mcmeta") is not null; + + public bool StartImport(string name, ZipArchive zip, ImportStatusReport importStatus) + { + if (!IsJavaResourcePack(zip)) + { + MessageBoxEx.ShowError("Zip file is not a resource pack", "Import Error"); + return false; + } + _name = name; + _importStatus = importStatus; + _packMeta = ReadPackMeta(zip); + string path = Path.Combine(JAVA_RESOURCE_PACK_PATH, JAVA_TEXTURES_PATH); + _resoursePackData = zip.GetDirectoryContent(path, includeSubDirectories: true).ToDictionary(e => e.FullName.Substring(path.Length + 1)); + return true; + } public McPackmeta.McPack ReadPackMeta(ZipArchive zip) { StreamReader packmeta = new StreamReader(zip.GetEntry("pack.mcmeta").Open()); McPackmeta.McPack pack = JsonConvert.DeserializeObject(packmeta.ReadToEnd()).Pack; - Debug.WriteLineIf(pack.Format == TARGET_FORMAT_VERSION, "Target format version... less work?"); - Debug.WriteLine($"Importing textures from resource pack of version: {GetVersionFromFormat(pack.Format)}(Format:{pack.Format})"); + if (pack.Format == TARGET_FORMAT_VERSION) + _importStatus.Post("Target format version... less work?"); + _importStatus.Post($"Importing textures from resource pack of version: {GetJavaGameVersionFromResourcePackFormat(pack.Format)}(Format:{pack.Format})"); + pack.Icon = zip.GetEntry("pack.png")?.GetImage(); return pack; } - public DLCTexturePackage ImportAsTexturePack(ZipArchive zip) + private IDictionary GetEntries(string path, string extension = "", bool includeSubDirectories = false) { - ImportResult blocks = ImportAtlas(ResourceLocations.GetFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.BlockAtlas)) as AtlasResource); - ImportResult items = ImportAtlas(ResourceLocations.GetFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.ItemAtlas)) as AtlasResource); - - return null; + string sanitisedDirectoryPath = path.Replace("\\", "/"); + return _resoursePackData.Where(kv => kv.Key.StartsWith(sanitisedDirectoryPath)) + .Where(kv => includeSubDirectories || (kv.Key.Substring(sanitisedDirectoryPath.Length).LastIndexOf('/') == 0 || kv.Key.Substring(sanitisedDirectoryPath.Length).LastIndexOf('/') == -1)) + .Where(kv => string.IsNullOrWhiteSpace(extension) || kv.Key.EndsWith(extension)) + .ToDictionary(kv => + { + string res = kv.Key.Substring(path.Length, kv.Key.Length - path.Length - extension.Length); + return res[0] == '/' ? res.Substring(1) : res; + }, kv => kv.Value); } - public ImportResult ImportAtlas(AtlasResource atlasResource) + public ImportResult ImportAsTexturePack() { - Atlas atlas = Atlas.CreateDefault(atlasResource, _gameVersion); - string atlasPath = GetAtlasPathFromFormat(packMeta.Format, atlasResource.Type); - string path = Path.Combine(JAVA_RESOURCE_PACK_PATH, atlasPath).Replace('\\', '/'); + ImportResult<(Atlas Atlas, IDictionary Animations), TextureImportStats> block = ImportAtlas(ResourceLocations.GetFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.BlockAtlas)) as AtlasResource); + ImportResult<(Atlas Atlas, IDictionary Animations), TextureImportStats> item = ImportAtlas(ResourceLocations.GetFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.ItemAtlas)) as AtlasResource); + ImportResult<(Atlas Atlas, IDictionary), TextureImportStats> particles = ImportAtlas(ResourceLocations.GetFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.ParticleAtlas)) as AtlasResource); - IReadOnlyDictionary lookUpTable = GetVersionLookUpTable(atlasResource.Type); - - IReadOnlyDictionary map = - atlasResource.TilesInfo.enumerate() - .ToDictionary(tileInfo => string.IsNullOrEmpty(tileInfo.value.InternalName) ? $"{Guid.NewGuid()}.{tileInfo.index}" : tileInfo.value.InternalName, it => it.index); - - IEnumerable entries = _zip.Entries.Where(e => e.FullName.StartsWith(path) && !e.FullName.EndsWith("/")); - - IReadOnlyDictionary javaAnimations = entries.Where(e => e.FullName.EndsWith(".mcmeta")).ToDictionary(entry => entry.FullName); - - int maxWidth = 0; - ImportStats stats = new ImportStats(atlas.TileCount); - IDictionary animations = new Dictionary(); - foreach (ZipArchiveEntry t in entries) + if (!item.Result.Animations.ContainsKey("clock")) { - if (!t.FullName.EndsWith(".png")) - continue; - string name = Path.GetFileNameWithoutExtension(t.FullName); - if (!map.TryGetValue(name, out int i) && !(lookUpTable.TryGetValue(name, out string lceKey) && map.TryGetValue(lceKey, out i))) - continue; + Animation clock = ImportAnimation("clock_", AtlasResource.AtlasType.ItemAtlas); + item.Result.Animations.Add("clock", clock); + } - if (i >= atlas.TileCount) - continue; + if (!item.Result.Animations.ContainsKey("compass")) + { + Animation compass = ImportAnimation("compass_", AtlasResource.AtlasType.ItemAtlas); + item.Result.Animations.Add("compass", compass); + } - Image img = Image.FromStream(t.Open()); - bool isAnimation = false; - if ((isAnimation = javaAnimations.TryGetValue(t.FullName + ".mcmeta", out ZipArchiveEntry animationEntry))) - { - string jsonData = animationEntry.ReadAllText(); - animations.Add(name, AnimationDeserializer.DefaultDeserializer.DeserializeJavaAnimation(JObject.Parse(jsonData), img)); - stats.animations++; - img = img.GetArea(new Rectangle(Point.Empty, new Size(img.Width, img.Width))); + const int cLAVA_TEXTURE = 238; + const int cWATER_TEXTURE = 206; + int maxWidth = block.Result.Atlas.GetTiles().Where(t => t.Index != cLAVA_TEXTURE && t.Index != cWATER_TEXTURE).Concat(item.Result.Atlas.GetTiles()).Max(t => t.Texture.Width); + + Size tileSize = new Size(maxWidth, maxWidth); + + DLCTexturePackage.TextureResolution resolution = DLCTexturePackage.GetTextureResolution(tileSize); + + ImportResult<(DLCTexturePackage.EnvironmentData environmentData, Atlas moonPhases, Image sun), TextureImportStats> envData = ImportEnvironmentData(); + + ImportResult<(ArmorSet leather, ArmorSet chain, ArmorSet gold, ArmorSet iron, ArmorSet diamond, ArmorSet turtle), TextureImportStats> armorSets = ImportArmorSets(); + + ImportResult<(Dictionary mobs, Dictionary items), TextureImportStats> entityModelTextures = ImportEntityModels(); + + DLCTexturePackage.MetaData metaData = new DLCTexturePackage.MetaData(null, _packMeta.Icon); + + int id = new Random().Next(0, GameConstants.MAX_PACK_ID - 1); + + TextureImportStats stats = block.Stats + item.Stats + particles.Stats + envData.Stats + armorSets.Stats + entityModelTextures.Stats; + + string name = ConvertJavaTextFormatToLCE(_name.Replace("_", " ")); + string description = ConvertJavaTextFormatToLCE(_packMeta.Description); + + DLCTexturePackage dlcTexturePackage = new DLCTexturePackage(name, description, id, + metaData, + resolution, + block.Result.Atlas, + item.Result.Atlas, + particles.Result.Atlas, + paintingAtlas: null, + moonPhaseAtlas: envData.Result.moonPhases, + mapIconsAtlas: null, + additionalMapIconsAtlas: null, + leatherArmorSet: armorSets.Result.leather, + chainArmorSet: armorSets.Result.chain, + ironArmorSet: armorSets.Result.iron, + goldArmorSet: armorSets.Result.gold, + diamondArmorSet: armorSets.Result.diamond, + turtleArmorSet: armorSets.Result.turtle, + environmentData: envData.Result.environmentData, + colorContainter: null, + entityModelTextures.Result.items, + entityModelTextures.Result.mobs, + customModels: null, + materials: null, + blockEntityBreakAnimation: null, + itemAnimations: item.Result.Animations, + blockAnimations: block.Result.Animations, + sun: envData.Result.sun, + moon: null, parentPackage: null); + return new ImportResult(dlcTexturePackage, stats); + } + + private string ConvertJavaTextFormatToLCE(string text) + { + string[] sections = text.Split(['§'], StringSplitOptions.RemoveEmptyEntries); + if (sections.Length == 0 || sections.Length == 1) + return text; + string formatText = string.Join("", sections + .Select(s => { + if (string.IsNullOrWhiteSpace(s) || !(s.Length > 1)) + return s; + string colorFormat = "§" + s[0]; + string colorText = s.Substring(1); + if (JavaConstants.JavaColorCodeToColor.TryGetValue(colorFormat, out (Color foreground, Color background) color)) + { + string htmlColor = color.foreground.ToHTMLColor(); + if (colorText.EndsWith("\n")) + return $"{colorText.Substring(0, colorText.Length - 1)}\n"; + return $"{colorText}"; + } + return s; } + )); + return formatText; + } - if (img.Width > maxWidth) - maxWidth = img.Width; - atlas[i].Texture = img; + private Animation ImportAnimation(string suffix, AtlasResource.AtlasType atlasType) + { + string atlasPath = GetAtlasPathFromFormat(_packMeta.Format, atlasType); + string path = Path.Combine(atlasPath, suffix); + List<(int index, Image texture)> frameTextures = new List<(int, Image)>(64); + foreach (KeyValuePair frameEntry in GetEntries(path, ".png")) + { + string name = Path.GetFileNameWithoutExtension(frameEntry.Key); + if (int.TryParse(name.End(2), out int index)) + frameTextures.Add((index, frameEntry.Value.GetImage())); + } + frameTextures.Sort((a, b) => a.index - b.index); + return new Animation(frameTextures.Select(t => t.texture), true); + } + + public ImportResult<(Atlas Atlas, IDictionary Animations), TextureImportStats> ImportAtlas(AtlasResource atlasResource) + { + _importStatus.Post($"[{nameof(ImportAtlas)}] Importing: '{atlasResource.Path}'"); + Atlas atlas = Atlas.CreateDefault(atlasResource, _gameVersion); + string path = GetAtlasPathFromFormat(_packMeta.Format, atlasResource.Type); + IDictionary entries = GetEntries(path); + + IReadOnlyDictionary lookUpTable = GetVersionLookUpTable(atlasResource.Type); + + IEnumerable<(int index, JsonTileInfo value)> a = atlasResource.TilesInfo.Enumerate().GroupBy(it => it.value.InternalName).Select(grp => grp.FirstOrDefault()); + IReadOnlyDictionary map = a.ToDictionary(tileInfo => string.IsNullOrEmpty(tileInfo.value.InternalName) ? $"{Guid.NewGuid()}.{tileInfo.index}" : tileInfo.value.InternalName.ToLowerInvariant(), it => it.index); + + IReadOnlyDictionary javaAnimations = entries.Values.Where(e => e.FullName.EndsWith(".mcmeta")).ToDictionary(entry => entry.FullName); + + TextureImportStats stats = new TextureImportStats(atlasResource.TilesInfo.Where(t => !string.IsNullOrWhiteSpace(t.InternalName)).Count()); + IDictionary animations = new Dictionary(); + foreach (ZipArchiveEntry entry in entries.Values) + { + _importStatus.Post(entry.FullName); + if (!entry.FullName.EndsWith(".png")) + continue; + string name = Path.GetFileNameWithoutExtension(entry.FullName); + if (!map.TryGetValue(name, out int index) && !(lookUpTable.TryGetValue(name, out JavaResourceConvertJson lceKey) && map.TryGetValue(lceKey.LceName.ToLowerInvariant(), out index)) || !index.IsWithinRangeOf(0, atlas.TileCount - 1)) + continue; + + JsonTileInfo tileInfo = atlas[index]?.GetUserDataOfType(); + + Image img = entry.GetImage(); + bool hasMcMeta = javaAnimations.TryGetValue(entry.FullName + ".mcmeta", out ZipArchiveEntry archiveEntry); + if (hasMcMeta) + { + string jsonData = archiveEntry.ReadAllText(); + Debug.WriteLine(jsonData); + JObject mcMetaJson = JObject.Parse(jsonData); + string animationName = tileInfo?.InternalName ?? name; + if (mcMetaJson["animation"] != null && !animations.ContainsKey(animationName)) + { + Animation animation = AnimationDeserializer.DefaultDeserializer.DeserializeJavaAnimation(mcMetaJson, img); + if (animation.FrameCount > 0) + animations.Add(animationName, animation); + stats.animations++; + img = img.GetArea(new Rectangle(Point.Empty, new Size(img.Width, img.Width))); + stats.textures++; + } + } + atlas[index].Texture = img; stats.textures++; } - atlas.SetTileSize(new Size(maxWidth, maxWidth)); - ImportResult result = new ImportResult(atlas, stats); - Debug.WriteLine("Import Stats"); - Debug.WriteLine($"Textures: {stats.Textures}/{stats.MaxTextures}({stats.MissingTextures} missing)"); - Debug.WriteLine($"Animations: {stats.Animations}"); - foreach (string item in animations.Keys) - { - Debug.WriteLine(item); - } + ImportResult<(Atlas atlas, IDictionary animations), TextureImportStats> result = new ImportResult<(Atlas atlas, IDictionary animations), TextureImportStats>((atlas, animations), stats); + _importStatus.Post($"Import Stats of '{atlasResource.Type}'"); + _importStatus.Post($"Textures: {stats.Textures}/{stats.MaxTextures}({stats.MissingTextures} missing)"); + _importStatus.Post($"Animations: {stats.Animations}"); return result; } - static readonly IReadOnlyDictionary latest2lce_blocks = JsonConvert.DeserializeObject>(Resources.latest2lce_blocks); - static readonly IReadOnlyDictionary latest2lce_items = JsonConvert.DeserializeObject>(Resources.latest2lce_items); - private static IReadOnlyDictionary GetVersionLookUpTable(AtlasResource.AtlasType atlasType) + static readonly IReadOnlyDictionary latest2lce_blocks = JsonConvert.DeserializeObject>(Resources.latest2lce_blocks); + static readonly IReadOnlyDictionary latest2lce_items = JsonConvert.DeserializeObject>(Resources.latest2lce_items); + static readonly IReadOnlyDictionary latest2lce_entities = JsonConvert.DeserializeObject>(Resources.latest2lce_entities); + + class JavaResourceConvertJson + { + [JsonProperty("lce_name")] + public string LceName { get; set; } + [JsonProperty("texture_remap")] + public JavaTextureRemap TextureRemap { get; set; } + } + + class JavaTextureRemap + { + [JsonProperty("source_size")] + [JsonConverter(typeof(SizeJsonConverter))] + public Size SourceSize; + + [JsonProperty("format")] + public int Format = -1; + + [JsonProperty("target_size")] + [JsonConverter(typeof(SizeJsonConverter))] + public Size TargetSize; + + [JsonProperty("areas")] + public JavaTextureRemapArea[] Areas; + } + + class JavaTextureRemapArea + { + [JsonProperty("size")] + [JsonConverter(typeof(SizeJsonConverter))] + public Size Size { get; set; } + + [JsonProperty("from")] + [JsonConverter(typeof(PointJsonConverter))] + public Point From { get; set; } + + [JsonProperty("to")] + [JsonConverter(typeof(PointJsonConverter))] + public Point To { get; set; } + + [JsonProperty("rotation")] + public float Rotation { get; set; } + + public enum FlipDirection + { + None, + x, + y, + xy, + } + + [JsonProperty("flip")] + public FlipDirection Flip { get; set; } = FlipDirection.None; + } + + private Image RemapTexture(Image source, JavaTextureRemap textureRemap) + { + if (textureRemap is null || textureRemap.Format > _packMeta.Format) + return source; + + int xSclar = 1; + int ySclar = 1; + Size s = source.Size; + if (textureRemap.SourceSize != Size.Empty || textureRemap.TargetSize != Size.Empty) + { + xSclar = source.Width / textureRemap.SourceSize.Width; + ySclar = source.Height / textureRemap.SourceSize.Height; + s = textureRemap.TargetSize; + } + Image res = new Bitmap(s.Width * xSclar, s.Height* ySclar); + + using Graphics g = Graphics.FromImage(res); + g.ApplyConfig(GraphicsConfig.PixelPerfect()); + foreach (JavaTextureRemapArea remapArea in textureRemap.Areas) + { + Point from = new Point(remapArea.From.X * xSclar, remapArea.From.Y * ySclar); + Point to = new Point(remapArea.To.X * xSclar, remapArea.To.Y * ySclar); + Size size = new Size(remapArea.Size.Width * xSclar, remapArea.Size.Height * ySclar); + Rectangle area = new Rectangle(from, size); + Image sourceAreaImg = source.GetArea(area); + if (remapArea.Rotation != 0) + { + if (remapArea.Rotation == 90f) + sourceAreaImg.RotateFlip(RotateFlipType.Rotate90FlipNone); + if (remapArea.Rotation == -90f) + sourceAreaImg.RotateFlip(RotateFlipType.Rotate270FlipNone); + if (remapArea.Rotation == 180f) + sourceAreaImg.RotateFlip(RotateFlipType.Rotate180FlipNone); + } + switch (remapArea.Flip) + { + case JavaTextureRemapArea.FlipDirection.x: + sourceAreaImg.RotateFlip(RotateFlipType.RotateNoneFlipX); + break; + case JavaTextureRemapArea.FlipDirection.y: + sourceAreaImg.RotateFlip(RotateFlipType.RotateNoneFlipY); + break; + case JavaTextureRemapArea.FlipDirection.xy: + sourceAreaImg.RotateFlip(RotateFlipType.RotateNoneFlipXY); + break; + case JavaTextureRemapArea.FlipDirection.None: + default: + break; + } + g.DrawImage(sourceAreaImg, to); + } + return res; + } + + + private static IReadOnlyDictionary GetVersionLookUpTable(AtlasResource.AtlasType atlasType) { return atlasType switch { AtlasResource.AtlasType.BlockAtlas => latest2lce_blocks, AtlasResource.AtlasType.ItemAtlas => latest2lce_items, - _ => throw new Exception() + _ => new Dictionary() }; } - private static string GetVersionFromFormat(int format) => _formatToVersion.TryGetValue(format, out IVersion versionRange) ? versionRange.ToString(" - ") : "unknown"; + private static string GetJavaGameVersionFromResourcePackFormat(int format) => _formatVeriosnToGameVersion.TryGetValue(format, out IVersion versionRange) ? versionRange.ToString(" - ") : "unknown"; private static string GetAtlasPathFromFormat(int format, AtlasResource.AtlasType type) { @@ -185,5 +429,254 @@ namespace PckStudio.Core.IO.Java _ => throw new Exception() }; } + + private ImportResult<(ArmorSet Leather, ArmorSet Chain, ArmorSet Gold, ArmorSet Iron, ArmorSet Diamond, ArmorSet Turtle), TextureImportStats> ImportArmorSets() + { + string path = Path.Combine("models", "armor"); + IDictionary entries = GetEntries(path, ".png"); + + TextureImportStats stats = new TextureImportStats(13); + + ArmorSet GetArmorSet(string armorName, string topName, string bottomName, bool hasOverlay = false) + { + Image topImage = entries.TryGetValue(topName, out ZipArchiveEntry entry) ? entry.GetImage() : default; + Image bottomImage = default; + if (!string.IsNullOrWhiteSpace(bottomName)) + bottomImage = entries.TryGetValue(bottomName, out entry) ? entry.GetImage() : default; + + Image baseTexture = topImage?.Combine(bottomImage ?? topImage, ImageLayoutDirection.Vertical); + Image overlayTexture = default; + + if (hasOverlay) + { + topName += "_overlay"; + bottomName += "_overlay"; + Image topOverlayImage = entries.TryGetValue(topName, out entry) ? entry.GetImage() : default; + Image bottomOverlayImage = entries.TryGetValue(bottomName, out entry) ? entry.GetImage() : default; + overlayTexture = topOverlayImage?.Combine(bottomOverlayImage ?? topOverlayImage, ImageLayoutDirection.Vertical); + stats.textures++; + stats.textures += bottomOverlayImage is not null ? 1 : 0; + } + if (baseTexture is null) + return null; + stats.textures++; + stats.textures += bottomImage is not null ? 1 : 0; + return new ArmorSet(armorName, baseTexture, overlayTexture); + } + + ArmorSet leather = GetArmorSet(ArmorSetDescription.CLOTH, "leather_layer_1", "leather_layer_2", hasOverlay: true); + ArmorSet chain = GetArmorSet(ArmorSetDescription.CHAIN, "chainmail_layer_1", "chainmail_layer_2"); + ArmorSet gold = GetArmorSet(ArmorSetDescription.GOLD, "gold_layer_1", "gold_layer_2"); + ArmorSet iron = GetArmorSet(ArmorSetDescription.IRON, "iron_layer_1", "iron_layer_2"); + ArmorSet diamond = GetArmorSet(ArmorSetDescription.DIAMOND, "diamond_layer_1", "diamond_layer_2"); + ArmorSet turtle = GetArmorSet(ArmorSetDescription.TURTLE, "turtle_layer_1", null); + return new ImportResult<(ArmorSet leather, ArmorSet chain, ArmorSet gold, ArmorSet iron, ArmorSet diamond, ArmorSet turtle), TextureImportStats>((leather, chain, gold, iron, diamond, turtle), stats); + } + + private ImportResult<(DLCTexturePackage.EnvironmentData environmentData, Atlas moonPhases, Image sun), TextureImportStats> ImportEnvironmentData() + { + string path = Path.Combine("environment"); + + IDictionary entries = GetEntries(path, ".png"); + + TextureImportStats stats = new TextureImportStats(5); + + stats.textures += entries.TryGetValue("clouds", out ZipArchiveEntry cloudsEntry) ? 1 : 0; + stats.textures += entries.TryGetValue("rain", out ZipArchiveEntry rainEntry) ? 1 : 0; + stats.textures += entries.TryGetValue("snow", out ZipArchiveEntry snowEntry) ? 1 : 0; + stats.textures += entries.TryGetValue("moon_phases", out ZipArchiveEntry moonPhasesEntry) ? 1 : 0; + stats.textures += entries.TryGetValue("sun", out ZipArchiveEntry sunEntry) ? 1 : 0; + + DLCTexturePackage.EnvironmentData environmentData = new DLCTexturePackage.EnvironmentData(cloudsEntry?.GetImage(), rainEntry?.GetImage(), snowEntry?.GetImage()); + Image moonPhasesTexture = moonPhasesEntry?.GetImage(); + Image sun = sunEntry?.GetImage(); + Atlas moonPhases = default; + if (moonPhasesTexture is not null) + { + moonPhases = Atlas.FromResourceLocation(moonPhasesTexture, ResourceLocations.GetFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.MoonPhaseAtlas)) as AtlasResource, _gameVersion); + } + return new ImportResult<(DLCTexturePackage.EnvironmentData environmentData, Atlas moonPhases, Image sun), TextureImportStats>((environmentData, moonPhases, sun), stats); + } + + private ImportResult<(Dictionary mobs, Dictionary items), TextureImportStats> ImportEntityModels() + { + string path = "entity"; + IDictionary entries = GetEntries(path, ".png", includeSubDirectories: true); + + Dictionary mobs = new Dictionary(); + Dictionary items = new Dictionary(); + + TextureImportStats stats = new TextureImportStats(1); + foreach (KeyValuePair kv in entries) + { + if (!latest2lce_entities.TryGetValue(kv.Key, out JavaResourceConvertJson resourceConvertJson)) + continue; + + Image texture = kv.Value.GetImage(); + texture = RemapTexture(texture, resourceConvertJson?.TextureRemap); + Debug.WriteLine(resourceConvertJson.LceName); + if (resourceConvertJson.LceName.StartsWith("item") && !items.ContainsKey(resourceConvertJson.LceName)) + items.Add(resourceConvertJson.LceName, texture); + if (resourceConvertJson.LceName.StartsWith("mob") && !mobs.ContainsKey(resourceConvertJson.LceName)) + mobs.Add(resourceConvertJson.LceName, texture); + } + + bool GetLargeChestTexture(string name, out Image texture) + { + if (entries.TryGetValue($"chest/{name}_right", out ZipArchiveEntry rightEntry) && + entries.TryGetValue($"chest/{name}_left", out ZipArchiveEntry leftEntry)) + { + Image rightTexture = rightEntry.GetImage(); + Image leftTexture = leftEntry.GetImage(); + + if (rightTexture.Size != leftTexture.Size) + { + texture = default; + return false; + } + + Image res = new Bitmap(rightTexture.Width * 2, rightTexture.Height); + Graphics g = Graphics.FromImage(res); + + + Image GetArea(Rectangle area, RotateFlipType rotateFlipType, bool swap = false) + { + Image areaImage = rightTexture.GetArea(area).Combine(leftTexture.GetArea(area), ImageLayoutDirection.Horizontal); + if (swap) + areaImage = leftTexture.GetArea(area).Combine(rightTexture.GetArea(area), ImageLayoutDirection.Horizontal); + if (rotateFlipType != RotateFlipType.RotateNoneFlipNone) + areaImage.RotateFlip(rotateFlipType); + return areaImage; + } + + { + { + Rectangle topArea = new Rectangle(new Point(29, 0), new Size(15, 14)); + Image top = GetArea(topArea, RotateFlipType.RotateNoneFlipY); + g.DrawImage(top, new Point(14, 0)); + } + + { + Rectangle bottomArea = new Rectangle(new Point(14, 0), new Size(15, 14)); + Image bottom = GetArea(bottomArea, RotateFlipType.RotateNoneFlipY); + g.DrawImage(bottom, new Point(44, 0)); + } + } + + { + { + Rectangle frontTopArea = new Rectangle(new Point(43, 14), new Size(15, 5)); + Image frontTop = GetArea(frontTopArea, RotateFlipType.RotateNoneFlipY, true); + g.DrawImage(frontTop, new Point(14, 14)); + } + + { + Rectangle frontBottomArea = new Rectangle(new Point(43, 33), new Size(15, 10)); + Image frontBottom = GetArea(frontBottomArea, RotateFlipType.RotateNoneFlipY, true); + g.DrawImage(frontBottom, new Point(14, 33)); + } + } + + { + { + Rectangle backTopArea = new Rectangle(new Point(14, 14), new Size(15, 5)); + Image backTop = GetArea(backTopArea, RotateFlipType.RotateNoneFlipXY); + g.DrawImage(backTop, new Point(58, 14)); + } + + { + Rectangle backBottomArea = new Rectangle(new Point(14, 33), new Size(15, 10)); + Image backBottom = GetArea(backBottomArea, RotateFlipType.RotateNoneFlipXY); + g.DrawImage(backBottom, new Point(58, 33)); + } + } + + { + Rectangle bottomTopArea = new Rectangle(new Point(29, 19), new Size(15, 14)); + Image bottomTop = GetArea(bottomTopArea, RotateFlipType.RotateNoneFlipY); + g.DrawImage(bottomTop, new Point(14, 19)); + } + + { + Rectangle bottomTopArea = new Rectangle(new Point(14, 19), new Size(15, 14)); + Image bottomTop = GetArea(bottomTopArea, RotateFlipType.RotateNoneFlipY); + g.DrawImage(bottomTop, new Point(44, 19)); + } + + // SIDES TOP + { + { + Image sideRight = rightTexture.GetArea(0, 14, 14, 5); + sideRight.RotateFlip(RotateFlipType.RotateNoneFlipY); + g.DrawImage(sideRight, new Point(0, 14)); + } + + { + Image sideLeft = leftTexture.GetArea(29, 14, 14, 5); + sideLeft.RotateFlip(RotateFlipType.RotateNoneFlipY); + g.DrawImage(sideLeft, new Point(44, 14)); + } + } + + // SIDES BOTTOM + { + { + Image sideRight = rightTexture.GetArea(0, 33, 14, 10); + sideRight.RotateFlip(RotateFlipType.RotateNoneFlipY); + g.DrawImage(sideRight, new Point(0, 33)); + } + + { + Image sideLeft = leftTexture.GetArea(29, 33, 14, 10); + sideLeft.RotateFlip(RotateFlipType.RotateNoneFlipY); + g.DrawImage(sideLeft, new Point(44, 33)); + } + } + + // NOSE + { + { + g.DrawImage(rightTexture.GetArea(0, 1, 1, 4), 0, 1); + g.DrawImage(GetArea(new Rectangle(1, 1, 1, 4), RotateFlipType.RotateNoneFlipNone), new Point(1, 1)); + } + + { + g.DrawImage(leftTexture.GetArea(2, 1, 1, 4), 3, 1); + g.DrawImage(GetArea(new Rectangle(3, 1, 1, 4), RotateFlipType.RotateNoneFlipNone), new Point(4, 1)); + } + + { + g.DrawImage(rightTexture.GetArea(1, 0, 1, 1), 1, 0); + g.DrawImage(leftTexture.GetArea(1, 0, 1, 1), 2, 0); + + g.DrawImage(rightTexture.GetArea(2, 0, 1, 1), 3, 0); + g.DrawImage(leftTexture.GetArea(2, 0, 1, 1), 4, 0); + } + } + + g.Dispose(); + + texture = res; + return true; + } + texture = null; + return false; + } + + if (_packMeta.Format > 5) + { + if (!items.ContainsKey("item/largechest") && GetLargeChestTexture("normal", out Image texture)) + { + items.Add("item/largechest", texture); + } + if (!items.ContainsKey("item/trapped_double") && GetLargeChestTexture("trapped", out texture)) + { + items.Add("item/trapped_double", texture); + } + } + + + return new ImportResult<(Dictionary mobs, Dictionary items), TextureImportStats>((mobs, items), stats); + } } -} +} \ No newline at end of file diff --git a/PckStudio.Core/IO/Java/SizeJsonConverter.cs b/PckStudio.Core/IO/Java/SizeJsonConverter.cs new file mode 100644 index 00000000..0e2e3285 --- /dev/null +++ b/PckStudio.Core/IO/Java/SizeJsonConverter.cs @@ -0,0 +1,41 @@ +using System; +using System.Drawing; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace PckStudio.Core.IO.Java +{ + public class SizeJsonConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, Size value, JsonSerializer serializer) + { + JObject jo = new JObject(); + jo.Add("width", value.Width); + jo.Add("height", value.Height); + jo.WriteTo(writer); + } + + public override Size ReadJson(JsonReader reader, Type objectType, Size existingValue, bool hasExistingValue, JsonSerializer serializer) + { + JObject jo = JObject.Load(reader); + return new Size((int)(jo["width"] ?? 0), (int)(jo["height"] ?? 0)); + } + } + + public class PointJsonConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, Point value, JsonSerializer serializer) + { + JObject jo = new JObject(); + jo.Add("x", value.X); + jo.Add("y", value.Y); + jo.WriteTo(writer); + } + + public override Point ReadJson(JsonReader reader, Type objectType, Point existingValue, bool hasExistingValue, JsonSerializer serializer) + { + JObject jo = JObject.Load(reader); + return new Point((int)(jo["x"] ?? 0), (int)(jo["y"] ?? 0)); + } + } +} \ No newline at end of file diff --git a/PckStudio.Core/PckStudio.Core.csproj b/PckStudio.Core/PckStudio.Core.csproj index 38d9f5d2..03b2fee8 100644 --- a/PckStudio.Core/PckStudio.Core.csproj +++ b/PckStudio.Core/PckStudio.Core.csproj @@ -50,10 +50,17 @@ + + + + + + + @@ -256,6 +263,7 @@ + diff --git a/PckStudio.Core/Properties/Resources.Designer.cs b/PckStudio.Core/Properties/Resources.Designer.cs index 63dc3419..88579522 100644 --- a/PckStudio.Core/Properties/Resources.Designer.cs +++ b/PckStudio.Core/Properties/Resources.Designer.cs @@ -544,19 +544,16 @@ namespace PckStudio.Core.Properties { /// /// Looks up a localized string similar to { - /// "anvil": "anvil_base", - /// "anvil_top": "anvil_top_damaged_0", - /// "chipped_anvil_top": "anvil_top_damaged_1", - /// "damaged_anvil_top": "anvil_top_damaged_2", - /// "beetroots_stage0": "beetroots_stage_0", - /// "beetroots_stage1": "beetroots_stage_1", - /// "beetroots_stage2": "beetroots_stage_2", - /// "beetroots_stage3": "beetroots_stage_3", - /// "bricks": "brick", - /// "carrots_stage0": "carrots_stage_0", - /// "carrots_stage1": "carrots_stage_1", - /// "carrots_stage2": "carrots_stage_2", - /// "carrots_stage3": "carrots_sta [rest of string was truncated]";. + /// "anvil": { "lce_name": "anvil_base" }, + /// "anvil_top": { "lce_name": "anvil_top_damaged_0" }, + /// "chipped_anvil_top": { "lce_name": "anvil_top_damaged_1" }, + /// "damaged_anvil_top": { "lce_name": "anvil_top_damaged_2" }, + /// "beetroots_stage0": { "lce_name": "beetroots_stage_0" }, + /// "beetroots_stage1": { "lce_name": "beetroots_stage_1" }, + /// "beetroots_stage2": { "lce_name": "beetroots_stage_2" }, + /// "beetroots_stage3": { "lce_name": "beetroots_stage_3" }, + /// "bricks": { "lce_name": "brick" }, + /// "carro [rest of string was truncated]";. /// public static string latest2lce_blocks { get { @@ -566,23 +563,44 @@ namespace PckStudio.Core.Properties { /// /// Looks up a localized string similar to { - /// "apple_golden": "appleGold", - /// "golden_apple": "appleGold", - /// "beef_cooked": "beefCooked", - /// "beef_raw": "beefRaw", - /// "beef": "beefRaw", - /// "blaze_powder": "blazePowder", - /// "blaze_rod": "blazeRod", - /// "oak_boat": "boat", - /// "book_normal": "book", - /// "chainmail_boots": "bootsChain", - /// "leather_boots": "bootsCloth", + /// "bed/white": { + /// "lce_name": "item/bed" + /// //"texture_remap": { + /// // "source_size": { "width": 64, "height": 64 }, + /// // "target_size": { "width": 64, "height": 128 }, + /// // "areas": [ + /// // { + /// // "size": { "width": 32, "height": 32 }, + /// // "from": { "x": 0, "y": 0 }, + /// // "to": { "x": 0, "y": 0 } + /// // }, + /// // { + /// // "size": { "width": 32, "weight": 32 }, + /// // "from": { "x": 0, "y": 0 }, + /// // "to": { "x": 0, "y": 0 } + /// [rest of string was truncated]";. + /// + public static string latest2lce_entities { + get { + return ResourceManager.GetString("latest2lce_entities", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to { + /// "apple_golden": { "lce_name": "appleGold" }, + /// "golden_apple": { "lce_name": "appleGold" }, + /// "beef_cooked": { "lce_name": "beefCooked" }, + /// "beef_raw": { "lce_name": "beefRaw" }, + /// "beef": { "lce_name": "beefRaw" }, + /// "blaze_powder": { "lce_name": "blazePowder" }, + /// "blaze_rod": { "lce_name": "blazeRod" }, + /// "oak_boat": { "lce_name": "boat" }, + /// "book_normal": { "lce_name": "book" }, + /// "chainmail_boots": { "lce_name": "bootsChain" }, + /// "leather_boots": { "lce_name": "bootsCloth" }, /// - /// "crossbow_standby": "crossbow", - /// "crossbow_pulling_0": "crossbow_pull_0", - /// "crossbow_pulling_1": "crossbow_pull_1", - /// "crossbow_pulling_2": "crossbow_pull_2", - /// "campfire": " [rest of string was truncated]";. + /// "cro [rest of string was truncated]";. /// public static string latest2lce_items { get { diff --git a/PckStudio.Core/Properties/Resources.resx b/PckStudio.Core/Properties/Resources.resx index 45a2f1bd..35efc155 100644 --- a/PckStudio.Core/Properties/Resources.resx +++ b/PckStudio.Core/Properties/Resources.resx @@ -256,4 +256,7 @@ ..\Resources\java\latest2lce_items.json;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + ..\Resources\java\latest2lce_entities.json;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + \ No newline at end of file diff --git a/PckStudio.Core/Resources/java/latest2lce_blocks.json b/PckStudio.Core/Resources/java/latest2lce_blocks.json index d628bb14..e841741b 100644 --- a/PckStudio.Core/Resources/java/latest2lce_blocks.json +++ b/PckStudio.Core/Resources/java/latest2lce_blocks.json @@ -1,422 +1,422 @@ { - "anvil": "anvil_base", - "anvil_top": "anvil_top_damaged_0", - "chipped_anvil_top": "anvil_top_damaged_1", - "damaged_anvil_top": "anvil_top_damaged_2", - "beetroots_stage0": "beetroots_stage_0", - "beetroots_stage1": "beetroots_stage_1", - "beetroots_stage2": "beetroots_stage_2", - "beetroots_stage3": "beetroots_stage_3", - "bricks": "brick", - "carrots_stage0": "carrots_stage_0", - "carrots_stage1": "carrots_stage_1", - "carrots_stage2": "carrots_stage_2", - "carrots_stage3": "carrots_stage_3", - "mossy_cobblestone": "cobblestone_mossy", - "cocoa_stage0": "cocoa_stage0", - "cocoa_stage1": "cocoa_stage1", - "cocoa_stage2": "cocoa_stage2", - "cocoa_stage_0": "cocoa_stage0", - "cocoa_stage_1": "cocoa_stage1", - "cocoa_stage_2": "cocoa_stage2", - "comparator": "comparator_off", - "black_concrete": "concrete_black", - "blue_concrete": "concrete_blue", - "brown_concrete": "concrete_brown", - "cyan_concrete": "concrete_cyan", - "gray_concrete": "concrete_gray", - "green_concrete": "concrete_green", - "light_blue_concrete": "concrete_light_blue", - "lime_concrete": "concrete_lime", - "magenta_concrete": "concrete_magenta", - "orange_concrete": "concrete_orange", - "pink_concrete": "concrete_pink", - "black_concrete_powder": "concrete_powder_black", - "blue_concrete_powder": "concrete_powder_blue", - "brown_concrete_powder": "concrete_powder_brown", - "cyan_concrete_powder": "concrete_powder_cyan", - "gray_concrete_powder": "concrete_powder_gray", - "green_concrete_powder": "concrete_powder_green", - "light_blue_concrete_powder": "concrete_powder_light_blue", - "lime_concrete_powder": "concrete_powder_lime", - "magenta_concrete_powder": "concrete_powder_magenta", - "orange_concrete_powder": "concrete_powder_orange", - "pink_concrete_powder": "concrete_powder_pink", - "purple_concrete_powder": "concrete_powder_purple", - "red_concrete_powder": "concrete_powder_red", - "light_gray_concrete_powder": "concrete_powder_silver", - "white_concrete_powder": "concrete_powder_white", - "yellow_concrete_powder": "concrete_powder_yellow", - "purple_concrete": "concrete_purple", - "red_concrete": "concrete_red", - "light_gray_concrete": "concrete_silver", - "white_concrete": "concrete_white", - "yellow_concrete": "concrete_yellow", - "dead_bush": "deadbush", - "podzol_side": "dirt_podzol_side", - "podzol_top": "dirt_podzol_top", - "dispenser_front": "dispenser_front_horizontal", - "acacia_door_bottom": "door_acacia_lower", - "acacia_door_top": "door_acacia_upper", - "birch_door_bottom": "door_birch_lower", - "birch_door_top": "door_birch_upper", - "dark_oak_door_bottom": "door_dark_oak_lower", - "dark_oak_door_top": "door_dark_oak_upper", - "iron_door_bottom": "door_iron_lower", - "iron_door_top": "door_iron_upper", - "jungle_door_bottom": "door_jungle_lower", - "jungle_door_top": "door_jungle_upper", - "spruce_door_bottom": "door_spruce_lower", - "spruce_door_top": "door_spruce_upper", - "oak_door_bottom": "door_wood_lower", - "oak_door_top": "door_wood_upper", - "large_fern_bottom": "double_plant_fern_bottom", - "large_fern_top": "double_plant_fern_top", - "tall_grass_bottom": "double_plant_grass_bottom", - "tall_grass_top": "double_plant_grass_top", - "peony_bottom": "double_plant_paeonia_bottom", - "peony_top": "double_plant_paeonia_top", - "rose_bush_bottom": "double_plant_rose_bottom", - "rose_bush_top": "double_plant_rose_top", - "sunflower_back": "double_plant_sunflower_back", - "sunflower_bottom": "double_plant_sunflower_bottom", - "sunflower_front": "double_plant_sunflower_front", - "sunflower_top": "double_plant_sunflower_top", - "lilac_bottom": "double_plant_syringa_bottom", - "lilac_top": "double_plant_syringa_top", - "dropper_front": "dropper_front_horizontal", - "end_stone_bricks": "end_bricks", - "end_portal_frame_eye": "endframe_eye", - "end_portal_frame_side": "endframe_side", - "end_portal_frame_top": "endframe_top", - "farmland": "farmland_dry", - "farmland_moist": "farmland_wet", - "fire_0": "fire_layer_0", - "fire_1": "fire_layer_1", - "allium": "flower_alium", - "flower_allium": "flower_alium", - "blue_orchid": "flower_blue_orchid", - "dandelion": "flower_dandelion", - "azure_bluet": "flower_houstonia", - "oxeye_daisy": "flower_oxeye_daisy", - "poppy": "flower_rose", - "orange_tulip": "flower_tulip_orange", - "pink_tulip": "flower_tulip_pink", - "red_tulip": "flower_tulip_red", - "white_tulip": "flower_tulip_white", - "furnace_front": "furnace_front_off", - "black_stained_glass": "glass_black", - "blue_stained_glass": "glass_blue", - "brown_stained_glass": "glass_brown", - "cyan_stained_glass": "glass_cyan", - "gray_stained_glass": "glass_gray", - "green_stained_glass": "glass_green", - "light_blue_stained_glass": "glass_light_blue", - "lime_stained_glass": "glass_lime", - "magenta_stained_glass": "glass_magenta", - "orange_stained_glass": "glass_orange", - "black_stained_glass_pane_top": "glass_pane_top_black", - "blue_stained_glass_pane_top": "glass_pane_top_blue", - "brown_stained_glass_pane_top": "glass_pane_top_brown", - "cyan_stained_glass_pane_top": "glass_pane_top_cyan", - "gray_stained_glass_pane_top": "glass_pane_top_gray", - "green_stained_glass_pane_top": "glass_pane_top_green", - "light_blue_stained_glass_pane_top": "glass_pane_top_light_blue", - "lime_stained_glass_pane_top": "glass_pane_top_lime", - "magenta_stained_glass_pane_top": "glass_pane_top_magenta", - "orange_stained_glass_pane_top": "glass_pane_top_orange", - "pink_stained_glass_pane_top": "glass_pane_top_pink", - "purple_stained_glass_pane_top": "glass_pane_top_purple", - "red_stained_glass_pane_top": "glass_pane_top_red", - "light_gray_stained_glass_pane_top": "glass_pane_top_silver", - "white_stained_glass_pane_top": "glass_pane_top_white", - "yellow_stained_glass_pane_top": "glass_pane_top_yellow", - "pink_stained_glass": "glass_pink", - "purple_stained_glass": "glass_purple", - "red_stained_glass": "glass_red", - "light_gray_stained_glass": "glass_silver", - "white_stained_glass": "glass_white", - "yellow_stained_glass": "glass_yellow", - "black_glazed_terracotta": "glazed_terracotta_black", - "blue_glazed_terracotta": "glazed_terracotta_blue", - "brown_glazed_terracotta": "glazed_terracotta_brown", - "cyan_glazed_terracotta": "glazed_terracotta_cyan", - "gray_glazed_terracotta": "glazed_terracotta_gray", - "green_glazed_terracotta": "glazed_terracotta_green", - "light_blue_glazed_terracotta": "glazed_terracotta_light_blue", - "lime_glazed_terracotta": "glazed_terracotta_lime", - "magenta_glazed_terracotta": "glazed_terracotta_magenta", - "orange_glazed_terracotta": "glazed_terracotta_orange", - "pink_glazed_terracotta": "glazed_terracotta_pink", - "purple_glazed_terracotta": "glazed_terracotta_purple", - "red_glazed_terracotta": "glazed_terracotta_red", - "light_gray_glazed_terracotta": "glazed_terracotta_silver", - "white_glazed_terracotta": "glazed_terracotta_white", - "yellow_glazed_terracotta": "glazed_terracotta_yellow", - "grass_block_side": "grass_side", - "grass_block_side_overlay": "grass_side_overlay", - "grass_block_snow": "snow_side", - "grass_side_snowed": "snow_side", - "grass_block_top": "grass_top", - "terracotta": "hardened_clay", - "black_terracotta": "hardened_clay_stained_black", - "blue_terracotta": "hardened_clay_stained_blue", - "brown_terracotta": "hardened_clay_stained_brown", - "cyan_terracotta": "hardened_clay_stained_cyan", - "gray_terracotta": "hardened_clay_stained_gray", - "green_terracotta": "hardened_clay_stained_green", - "light_blue_terracotta": "hardened_clay_stained_light_blue", - "lime_terracotta": "hardened_clay_stained_lime", - "magenta_terracotta": "hardened_clay_stained_magenta", - "orange_terracotta": "hardened_clay_stained_orange", - "pink_terracotta": "hardened_clay_stained_pink", - "purple_terracotta": "hardened_clay_stained_purple", - "red_terracotta": "hardened_clay_stained_red", - "light_gray_terracotta": "hardened_clay_stained_silver", - "white_terracotta": "hardened_clay_stained_white", - "yellow_terracotta": "hardened_clay_stained_yellow", - "packed_ice": "ice_packed", - "item_frame": "itemframe_back", - "itemframe_background": "itemframe_back", - "acacia_leaves": "leaves_acacia", - "acacia_leaves_opaque": "leaves_acacia_fast", - "dark_oak_leaves": "leaves_big_oak", - "dark_oak_leaves_opaque": "leaves_big_oak_fast", - "birch_leaves": "leaves_birch", - "birch_leaves_opaque": "leaves_birch_fast", - "jungle_leaves": "leaves_jungle", - "jungle_leaves_opaque": "leaves_jungle_opaque", - "oak_leaves": "leaves", - "red_nether_bricks": "red_nether_brick", - "oak_leaves_opaque": "leaves_opaque", - "spruce_leaves": "leaves_spruce", - "spruce_leaves_opaque": "leaves_spruce_opaque", - "acacia_log": "log_acacia", - "acacia_log_top": "log_acacia_top", - "dark_oak_log": "log_big_oak", - "dark_oak_log_top": "log_big_oak_top", - "birch_log": "log_birch", - "birch_log_top": "log_birch_top", - "jungle_log": "log_jungle", - "jungle_log_top": "log_jungle_top", - "oak_log": "log_oak", - "oak_log_top": "log_oak_top", - "spruce_log": "log_spruce", - "spruce_log_top": "log_spruce_top", - "attached_melon_stem": "melon_stem_connected", - "melon_stem": "melon_stem_disconnected", - "spawner": "mob_spawner", - "brown_mushroom_block": "mushroom_block_skin_brown", - "red_mushroom_block": "mushroom_block_skin_red", - "mushroom_stem": "mushroom_block_skin_stem", - "brown_mushroom": "mushroom_brown", - "red_mushroom": "mushroom_red", - "nether_bricks": "nether_brick", - "nether_wart_stage0": "nether_wart_stage_0", - "nether_wart_stage1": "nether_wart_stage_1", - "nether_wart_stage2": "nether_wart_stage_2", - "note_block": "noteblock", - "observer_back_on": "observer_back_lit", - "piston_top": "piston_top_normal", - "acacia_planks": "planks_acacia", - "dark_oak_planks": "planks_big_oak", - "birch_planks": "planks_birch", - "jungle_planks": "planks_jungle", - "oak_planks": "planks_oak", - "spruce_planks": "planks_spruce", - "nether_portal": "portal", - "potatoes_stage0": "potatoes_stage_0", - "potatoes_stage1": "potatoes_stage_1", - "potatoes_stage2": "potatoes_stage_2", - "potatoes_stage3": "potatoes_stage_3", - "dark_prismarine": "prismarine_dark", - "prismarine": "prismarine_rough", - "carved_pumpkin": "pumpkin_face_off", - "jack_o_lantern": "pumpkin_face_on", - "attached_pumpkin_stem": "pumpkin_stem_connected", - "pumpkin_stem": "pumpkin_stem_disconnected", - "chiseled_quartz_block": "quartz_block_chiseled", - "chiseled_quartz_block_top": "quartz_block_chiseled_top", - "quartz_pillar": "quartz_block_lines", - "quartz_pillar_top": "quartz_block_lines_top", - "nether_quartz_ore": "quartz_ore", - "activator_rail": "rail_activator", - "activator_rail_on": "rail_activator_powered", - "detector_rail": "detectorRail", - "rail_detector": "detectorRail", - "detector_rail_on": "detectorRail_on", - "rail_detector_powered": "detectorRail_on", - "powered_rail": "rail_golden", - "powered_rail_on": "rail_golden_powered", - "rail": "rail_normal", - "rail_corner": "rail_normal_turned", - "chiseled_red_sandstone": "red_sandstone_carved", - "red_sandstone": "red_sandstone_normal", - "cut_red_sandstone": "red_sandstone_smooth", - "redstone_torch": "redstone_torch_on", - "sugar_cane": "reeds", - "repeater": "repeater_off", - "chiseled_sandstone": "sandstone_carved", - "sandstone": "sandstone_side", - "cut_sandstone": "sandstone_smooth", - "acacia_sapling": "sapling_acacia", - "birch_sapling": "sapling_birch", - "jungle_sapling": "sapling_jungle", - "oak_sapling": "sapling", - "dark_oak_sapling": "sapling_roofed_oak", - "spruce_sapling": "sapling_spruce", - "black_shulker_box": "shulker_top_black", - "blue_shulker_box": "shulker_top_blue", - "brown_shulker_box": "shulker_top_brown", - "cyan_shulker_box": "shulker_top_cyan", - "gray_shulker_box": "shulker_top_gray", - "green_shulker_box": "shulker_top_green", - "light_blue_shulker_box": "shulker_top_light_blue", - "lime_shulker_box": "shulker_top_lime", - "magenta_shulker_box": "shulker_top_magenta", - "orange_shulker_box": "shulker_top_orange", - "pink_shulker_box": "shulker_top_pink", - "purple_shulker_box": "shulker_top_purple", - "red_shulker_box": "shulker_top_red", - "light_gray_shulker_box": "shulker_top_silver", - "white_shulker_box": "shulker_top_white", - "yellow_shulker_box": "shulker_top_yellow", - "slime_block": "slime", - "wet_sponge": "sponge_wet", - "andesite": "stone_andesite", - "smooth_andesite": "stone_andesite_smooth", - "diorite": "stone_diorite", - "smooth_diorite": "stone_diorite_smooth", - "granite": "stone_granite", - "smooth_granite": "stone_granite_smooth", - "stone_bricks": "stonebrick", - "chiseled_stone_bricks": "stonebrick_carved", - "cracked_stone_bricks": "stonebrick_cracked", - "mossy_stone_bricks": "stonebrick_mossy", - "grass": "tallgrass", - "torch": "torch_on", - "oak_trapdoor": "trapdoor", - "tripwire": "trip_wire", - "tripwire_hook": "trip_wire_source", - "lily_pad": "waterlily", - "cobweb": "web", - "tube_coral_block": "coral_blue", - "tube_coral": "coral_plant_blue", - "tube_coral_fan": "coral_fan_blue", - "fire_coral_block": "coral_red", - "fire_coral": "coral_plant_red", - "fire_coral_fan": "coral_fan_red", - "horn_coral_block": "coral_yellow", - "horn_coral": "coral_plant_yellow", - "horn_coral_fan": "coral_fan_yellow", - "brain_coral_block": "coral_pink", - "brain_coral": "coral_plant_pink", - "brain_coral_fan": "coral_fan_pink", - "bubble_coral_block": "coral_purple", - "bubble_coral": "coral_plant_purple", - "bubble_coral_fan": "coral_fan_purple", - "dead_brain_coral_block": "coral_pink_dead", - "dead_brain_coral_fan": "coral_fan_pink_dead", - "dead_bubble_coral_block": "coral_purple_dead", - "dead_bubble_coral_fan": "coral_fan_purple_dead", - "dead_fire_coral_block": "coral_red_dead", - "dead_fire_coral_fan": "coral_fan_red_dead", - "dead_horn_coral_block": "coral_yellow_dead", - "dead_horn_coral_fan": "coral_fan_yellow_dead", - "dead_tube_coral_block": "coral_blue_dead", - "dead_tube_coral_fan": "coral_fan_blue_dead", - "wheat_stage0": "crops_0", - "wheat_stage1": "crops_1", - "wheat_stage2": "crops_2", - "wheat_stage3": "crops_3", - "wheat_stage4": "crops_4", - "wheat_stage5": "crops_5", - "wheat_stage6": "crops_6", - "wheat_stage7": "crops_7", + "anvil": { "lce_name": "anvil_base" }, + "anvil_top": { "lce_name": "anvil_top_damaged_0" }, + "chipped_anvil_top": { "lce_name": "anvil_top_damaged_1" }, + "damaged_anvil_top": { "lce_name": "anvil_top_damaged_2" }, + "beetroots_stage0": { "lce_name": "beetroots_stage_0" }, + "beetroots_stage1": { "lce_name": "beetroots_stage_1" }, + "beetroots_stage2": { "lce_name": "beetroots_stage_2" }, + "beetroots_stage3": { "lce_name": "beetroots_stage_3" }, + "bricks": { "lce_name": "brick" }, + "carrots_stage0": { "lce_name": "carrots_stage_0" }, + "carrots_stage1": { "lce_name": "carrots_stage_1" }, + "carrots_stage2": { "lce_name": "carrots_stage_2" }, + "carrots_stage3": { "lce_name": "carrots_stage_3" }, + "mossy_cobblestone": { "lce_name": "cobblestone_mossy" }, + "cocoa_stage0": { "lce_name": "cocoa_stage0" }, + "cocoa_stage1": { "lce_name": "cocoa_stage1" }, + "cocoa_stage2": { "lce_name": "cocoa_stage2" }, + "cocoa_stage_0": { "lce_name": "cocoa_stage0" }, + "cocoa_stage_1": { "lce_name": "cocoa_stage1" }, + "cocoa_stage_2": { "lce_name": "cocoa_stage2" }, + "comparator": { "lce_name": "comparator_off" }, + "black_concrete": { "lce_name": "concrete_black" }, + "blue_concrete": { "lce_name": "concrete_blue" }, + "brown_concrete": { "lce_name": "concrete_brown" }, + "cyan_concrete": { "lce_name": "concrete_cyan" }, + "gray_concrete": { "lce_name": "concrete_gray" }, + "green_concrete": { "lce_name": "concrete_green" }, + "light_blue_concrete": { "lce_name": "concrete_light_blue" }, + "lime_concrete": { "lce_name": "concrete_lime" }, + "magenta_concrete": { "lce_name": "concrete_magenta" }, + "orange_concrete": { "lce_name": "concrete_orange" }, + "pink_concrete": { "lce_name": "concrete_pink" }, + "black_concrete_powder": { "lce_name": "concrete_powder_black" }, + "blue_concrete_powder": { "lce_name": "concrete_powder_blue" }, + "brown_concrete_powder": { "lce_name": "concrete_powder_brown" }, + "cyan_concrete_powder": { "lce_name": "concrete_powder_cyan" }, + "gray_concrete_powder": { "lce_name": "concrete_powder_gray" }, + "green_concrete_powder": { "lce_name": "concrete_powder_green" }, + "light_blue_concrete_powder": { "lce_name": "concrete_powder_light_blue" }, + "lime_concrete_powder": { "lce_name": "concrete_powder_lime" }, + "magenta_concrete_powder": { "lce_name": "concrete_powder_magenta" }, + "orange_concrete_powder": { "lce_name": "concrete_powder_orange" }, + "pink_concrete_powder": { "lce_name": "concrete_powder_pink" }, + "purple_concrete_powder": { "lce_name": "concrete_powder_purple" }, + "red_concrete_powder": { "lce_name": "concrete_powder_red" }, + "light_gray_concrete_powder": { "lce_name": "concrete_powder_silver" }, + "white_concrete_powder": { "lce_name": "concrete_powder_white" }, + "yellow_concrete_powder": { "lce_name": "concrete_powder_yellow" }, + "purple_concrete": { "lce_name": "concrete_purple" }, + "red_concrete": { "lce_name": "concrete_red" }, + "light_gray_concrete": { "lce_name": "concrete_silver" }, + "white_concrete": { "lce_name": "concrete_white" }, + "yellow_concrete": { "lce_name": "concrete_yellow" }, + "dead_bush": { "lce_name": "deadbush" }, + "podzol_side": { "lce_name": "dirt_podzol_side" }, + "podzol_top": { "lce_name": "dirt_podzol_top" }, + "dispenser_front": { "lce_name": "dispenser_front_horizontal" }, + "acacia_door_bottom": { "lce_name": "door_acacia_lower" }, + "acacia_door_top": { "lce_name": "door_acacia_upper" }, + "birch_door_bottom": { "lce_name": "door_birch_lower" }, + "birch_door_top": { "lce_name": "door_birch_upper" }, + "dark_oak_door_bottom": { "lce_name": "door_dark_oak_lower" }, + "dark_oak_door_top": { "lce_name": "door_dark_oak_upper" }, + "iron_door_bottom": { "lce_name": "door_iron_lower" }, + "iron_door_top": { "lce_name": "door_iron_upper" }, + "jungle_door_bottom": { "lce_name": "door_jungle_lower" }, + "jungle_door_top": { "lce_name": "door_jungle_upper" }, + "spruce_door_bottom": { "lce_name": "door_spruce_lower" }, + "spruce_door_top": { "lce_name": "door_spruce_upper" }, + "oak_door_bottom": { "lce_name": "door_wood_lower" }, + "oak_door_top": { "lce_name": "door_wood_upper" }, + "large_fern_bottom": { "lce_name": "double_plant_fern_bottom" }, + "large_fern_top": { "lce_name": "double_plant_fern_top" }, + "tall_grass_bottom": { "lce_name": "double_plant_grass_bottom" }, + "tall_grass_top": { "lce_name": "double_plant_grass_top" }, + "peony_bottom": { "lce_name": "double_plant_paeonia_bottom" }, + "peony_top": { "lce_name": "double_plant_paeonia_top" }, + "rose_bush_bottom": { "lce_name": "double_plant_rose_bottom" }, + "rose_bush_top": { "lce_name": "double_plant_rose_top" }, + "sunflower_back": { "lce_name": "double_plant_sunflower_back" }, + "sunflower_bottom": { "lce_name": "double_plant_sunflower_bottom" }, + "sunflower_front": { "lce_name": "double_plant_sunflower_front" }, + "sunflower_top": { "lce_name": "double_plant_sunflower_top" }, + "lilac_bottom": { "lce_name": "double_plant_syringa_bottom" }, + "lilac_top": { "lce_name": "double_plant_syringa_top" }, + "dropper_front": { "lce_name": "dropper_front_horizontal" }, + "end_stone_bricks": { "lce_name": "end_bricks" }, + "end_portal_frame_eye": { "lce_name": "endframe_eye" }, + "end_portal_frame_side": { "lce_name": "endframe_side" }, + "end_portal_frame_top": { "lce_name": "endframe_top" }, + "farmland": { "lce_name": "farmland_dry" }, + "farmland_moist": { "lce_name": "farmland_wet" }, + "fire_0": { "lce_name": "fire_layer_0" }, + "fire_1": { "lce_name": "fire_layer_1" }, + "allium": { "lce_name": "flower_alium" }, + "flower_allium": { "lce_name": "flower_alium" }, + "blue_orchid": { "lce_name": "flower_blue_orchid" }, + "dandelion": { "lce_name": "flower_dandelion" }, + "azure_bluet": { "lce_name": "flower_houstonia" }, + "oxeye_daisy": { "lce_name": "flower_oxeye_daisy" }, + "poppy": { "lce_name": "flower_rose" }, + "orange_tulip": { "lce_name": "flower_tulip_orange" }, + "pink_tulip": { "lce_name": "flower_tulip_pink" }, + "red_tulip": { "lce_name": "flower_tulip_red" }, + "white_tulip": { "lce_name": "flower_tulip_white" }, + "furnace_front": { "lce_name": "furnace_front_off" }, + "black_stained_glass": { "lce_name": "glass_black" }, + "blue_stained_glass": { "lce_name": "glass_blue" }, + "brown_stained_glass": { "lce_name": "glass_brown" }, + "cyan_stained_glass": { "lce_name": "glass_cyan" }, + "gray_stained_glass": { "lce_name": "glass_gray" }, + "green_stained_glass": { "lce_name": "glass_green" }, + "light_blue_stained_glass": { "lce_name": "glass_light_blue" }, + "lime_stained_glass": { "lce_name": "glass_lime" }, + "magenta_stained_glass": { "lce_name": "glass_magenta" }, + "orange_stained_glass": { "lce_name": "glass_orange" }, + "black_stained_glass_pane_top": { "lce_name": "glass_pane_top_black" }, + "blue_stained_glass_pane_top": { "lce_name": "glass_pane_top_blue" }, + "brown_stained_glass_pane_top": { "lce_name": "glass_pane_top_brown" }, + "cyan_stained_glass_pane_top": { "lce_name": "glass_pane_top_cyan" }, + "gray_stained_glass_pane_top": { "lce_name": "glass_pane_top_gray" }, + "green_stained_glass_pane_top": { "lce_name": "glass_pane_top_green" }, + "light_blue_stained_glass_pane_top": { "lce_name": "glass_pane_top_light_blue" }, + "lime_stained_glass_pane_top": { "lce_name": "glass_pane_top_lime" }, + "magenta_stained_glass_pane_top": { "lce_name": "glass_pane_top_magenta" }, + "orange_stained_glass_pane_top": { "lce_name": "glass_pane_top_orange" }, + "pink_stained_glass_pane_top": { "lce_name": "glass_pane_top_pink" }, + "purple_stained_glass_pane_top": { "lce_name": "glass_pane_top_purple" }, + "red_stained_glass_pane_top": { "lce_name": "glass_pane_top_red" }, + "light_gray_stained_glass_pane_top": { "lce_name": "glass_pane_top_silver" }, + "white_stained_glass_pane_top": { "lce_name": "glass_pane_top_white" }, + "yellow_stained_glass_pane_top": { "lce_name": "glass_pane_top_yellow" }, + "pink_stained_glass": { "lce_name": "glass_pink" }, + "purple_stained_glass": { "lce_name": "glass_purple" }, + "red_stained_glass": { "lce_name": "glass_red" }, + "light_gray_stained_glass": { "lce_name": "glass_silver" }, + "white_stained_glass": { "lce_name": "glass_white" }, + "yellow_stained_glass": { "lce_name": "glass_yellow" }, + "black_glazed_terracotta": { "lce_name": "glazed_terracotta_black" }, + "blue_glazed_terracotta": { "lce_name": "glazed_terracotta_blue" }, + "brown_glazed_terracotta": { "lce_name": "glazed_terracotta_brown" }, + "cyan_glazed_terracotta": { "lce_name": "glazed_terracotta_cyan" }, + "gray_glazed_terracotta": { "lce_name": "glazed_terracotta_gray" }, + "green_glazed_terracotta": { "lce_name": "glazed_terracotta_green" }, + "light_blue_glazed_terracotta": { "lce_name": "glazed_terracotta_light_blue" }, + "lime_glazed_terracotta": { "lce_name": "glazed_terracotta_lime" }, + "magenta_glazed_terracotta": { "lce_name": "glazed_terracotta_magenta" }, + "orange_glazed_terracotta": { "lce_name": "glazed_terracotta_orange" }, + "pink_glazed_terracotta": { "lce_name": "glazed_terracotta_pink" }, + "purple_glazed_terracotta": { "lce_name": "glazed_terracotta_purple" }, + "red_glazed_terracotta": { "lce_name": "glazed_terracotta_red" }, + "light_gray_glazed_terracotta": { "lce_name": "glazed_terracotta_silver" }, + "white_glazed_terracotta": { "lce_name": "glazed_terracotta_white" }, + "yellow_glazed_terracotta": { "lce_name": "glazed_terracotta_yellow" }, + "grass_block_side": { "lce_name": "grass_side" }, + "grass_block_side_overlay": { "lce_name": "grass_side_overlay" }, + "grass_block_snow": { "lce_name": "snow_side" }, + "grass_side_snowed": { "lce_name": "snow_side" }, + "grass_block_top": { "lce_name": "grass_top" }, + "terracotta": { "lce_name": "hardened_clay" }, + "black_terracotta": { "lce_name": "hardened_clay_stained_black" }, + "blue_terracotta": { "lce_name": "hardened_clay_stained_blue" }, + "brown_terracotta": { "lce_name": "hardened_clay_stained_brown" }, + "cyan_terracotta": { "lce_name": "hardened_clay_stained_cyan" }, + "gray_terracotta": { "lce_name": "hardened_clay_stained_gray" }, + "green_terracotta": { "lce_name": "hardened_clay_stained_green" }, + "light_blue_terracotta": { "lce_name": "hardened_clay_stained_light_blue" }, + "lime_terracotta": { "lce_name": "hardened_clay_stained_lime" }, + "magenta_terracotta": { "lce_name": "hardened_clay_stained_magenta" }, + "orange_terracotta": { "lce_name": "hardened_clay_stained_orange" }, + "pink_terracotta": { "lce_name": "hardened_clay_stained_pink" }, + "purple_terracotta": { "lce_name": "hardened_clay_stained_purple" }, + "red_terracotta": { "lce_name": "hardened_clay_stained_red" }, + "light_gray_terracotta": { "lce_name": "hardened_clay_stained_silver" }, + "white_terracotta": { "lce_name": "hardened_clay_stained_white" }, + "yellow_terracotta": { "lce_name": "hardened_clay_stained_yellow" }, + "packed_ice": { "lce_name": "ice_packed" }, + "item_frame": { "lce_name": "itemframe_back" }, + "itemframe_background": { "lce_name": "itemframe_back" }, + "acacia_leaves": { "lce_name": "leaves_acacia" }, + "acacia_leaves_opaque": { "lce_name": "leaves_acacia_fast" }, + "dark_oak_leaves": { "lce_name": "leaves_big_oak" }, + "dark_oak_leaves_opaque": { "lce_name": "leaves_big_oak_fast" }, + "birch_leaves": { "lce_name": "leaves_birch" }, + "birch_leaves_opaque": { "lce_name": "leaves_birch_fast" }, + "jungle_leaves": { "lce_name": "leaves_jungle" }, + "jungle_leaves_opaque": { "lce_name": "leaves_jungle_opaque" }, + "oak_leaves": { "lce_name": "leaves" }, + "red_nether_bricks": { "lce_name": "red_nether_brick" }, + "oak_leaves_opaque": { "lce_name": "leaves_opaque" }, + "spruce_leaves": { "lce_name": "leaves_spruce" }, + "spruce_leaves_opaque": { "lce_name": "leaves_spruce_opaque" }, + "acacia_log": { "lce_name": "log_acacia" }, + "acacia_log_top": { "lce_name": "log_acacia_top" }, + "dark_oak_log": { "lce_name": "log_big_oak" }, + "dark_oak_log_top": { "lce_name": "log_big_oak_top" }, + "birch_log": { "lce_name": "log_birch" }, + "birch_log_top": { "lce_name": "log_birch_top" }, + "jungle_log": { "lce_name": "log_jungle" }, + "jungle_log_top": { "lce_name": "log_jungle_top" }, + "oak_log": { "lce_name": "log_oak" }, + "oak_log_top": { "lce_name": "log_oak_top" }, + "spruce_log": { "lce_name": "log_spruce" }, + "spruce_log_top": { "lce_name": "log_spruce_top" }, + "attached_melon_stem": { "lce_name": "melon_stem_connected" }, + "melon_stem": { "lce_name": "melon_stem_disconnected" }, + "spawner": { "lce_name": "mob_spawner" }, + "brown_mushroom_block": { "lce_name": "mushroom_block_skin_brown" }, + "red_mushroom_block": { "lce_name": "mushroom_block_skin_red" }, + "mushroom_stem": { "lce_name": "mushroom_block_skin_stem" }, + "brown_mushroom": { "lce_name": "mushroom_brown" }, + "red_mushroom": { "lce_name": "mushroom_red" }, + "nether_bricks": { "lce_name": "nether_brick" }, + "nether_wart_stage0": { "lce_name": "nether_wart_stage_0" }, + "nether_wart_stage1": { "lce_name": "nether_wart_stage_1" }, + "nether_wart_stage2": { "lce_name": "nether_wart_stage_2" }, + "note_block": { "lce_name": "noteblock" }, + "observer_back_on": { "lce_name": "observer_back_lit" }, + "piston_top": { "lce_name": "piston_top_normal" }, + "acacia_planks": { "lce_name": "planks_acacia" }, + "dark_oak_planks": { "lce_name": "planks_big_oak" }, + "birch_planks": { "lce_name": "planks_birch" }, + "jungle_planks": { "lce_name": "planks_jungle" }, + "oak_planks": { "lce_name": "planks_oak" }, + "spruce_planks": { "lce_name": "planks_spruce" }, + "nether_portal": { "lce_name": "portal" }, + "potatoes_stage0": { "lce_name": "potatoes_stage_0" }, + "potatoes_stage1": { "lce_name": "potatoes_stage_1" }, + "potatoes_stage2": { "lce_name": "potatoes_stage_2" }, + "potatoes_stage3": { "lce_name": "potatoes_stage_3" }, + "dark_prismarine": { "lce_name": "prismarine_dark" }, + "prismarine": { "lce_name": "prismarine_rough" }, + "carved_pumpkin": { "lce_name": "pumpkin_face_off" }, + "jack_o_lantern": { "lce_name": "pumpkin_face_on" }, + "attached_pumpkin_stem": { "lce_name": "pumpkin_stem_connected" }, + "pumpkin_stem": { "lce_name": "pumpkin_stem_disconnected" }, + "chiseled_quartz_block": { "lce_name": "quartz_block_chiseled" }, + "chiseled_quartz_block_top": { "lce_name": "quartz_block_chiseled_top" }, + "quartz_pillar": { "lce_name": "quartz_block_lines" }, + "quartz_pillar_top": { "lce_name": "quartz_block_lines_top" }, + "nether_quartz_ore": { "lce_name": "quartz_ore" }, + "activator_rail": { "lce_name": "rail_activator" }, + "activator_rail_on": { "lce_name": "rail_activator_powered" }, + "detector_rail": { "lce_name": "detectorRail" }, + "rail_detector": { "lce_name": "detectorRail" }, + "detector_rail_on": { "lce_name": "detectorRail_on" }, + "rail_detector_powered": { "lce_name": "detectorRail_on" }, + "powered_rail": { "lce_name": "rail_golden" }, + "powered_rail_on": { "lce_name": "rail_golden_powered" }, + "rail": { "lce_name": "rail_normal" }, + "rail_corner": { "lce_name": "rail_normal_turned" }, + "chiseled_red_sandstone": { "lce_name": "red_sandstone_carved" }, + "red_sandstone": { "lce_name": "red_sandstone_normal" }, + "cut_red_sandstone": { "lce_name": "red_sandstone_smooth" }, + "redstone_torch": { "lce_name": "redstone_torch_on" }, + "sugar_cane": { "lce_name": "reeds" }, + "repeater": { "lce_name": "repeater_off" }, + "chiseled_sandstone": { "lce_name": "sandstone_carved" }, + "sandstone": { "lce_name": "sandstone_side" }, + "cut_sandstone": { "lce_name": "sandstone_smooth" }, + "acacia_sapling": { "lce_name": "sapling_acacia" }, + "birch_sapling": { "lce_name": "sapling_birch" }, + "jungle_sapling": { "lce_name": "sapling_jungle" }, + "oak_sapling": { "lce_name": "sapling" }, + "dark_oak_sapling": { "lce_name": "sapling_roofed_oak" }, + "spruce_sapling": { "lce_name": "sapling_spruce" }, + "black_shulker_box": { "lce_name": "shulker_top_black" }, + "blue_shulker_box": { "lce_name": "shulker_top_blue" }, + "brown_shulker_box": { "lce_name": "shulker_top_brown" }, + "cyan_shulker_box": { "lce_name": "shulker_top_cyan" }, + "gray_shulker_box": { "lce_name": "shulker_top_gray" }, + "green_shulker_box": { "lce_name": "shulker_top_green" }, + "light_blue_shulker_box": { "lce_name": "shulker_top_light_blue" }, + "lime_shulker_box": { "lce_name": "shulker_top_lime" }, + "magenta_shulker_box": { "lce_name": "shulker_top_magenta" }, + "orange_shulker_box": { "lce_name": "shulker_top_orange" }, + "pink_shulker_box": { "lce_name": "shulker_top_pink" }, + "purple_shulker_box": { "lce_name": "shulker_top_purple" }, + "red_shulker_box": { "lce_name": "shulker_top_red" }, + "light_gray_shulker_box": { "lce_name": "shulker_top_silver" }, + "white_shulker_box": { "lce_name": "shulker_top_white" }, + "yellow_shulker_box": { "lce_name": "shulker_top_yellow" }, + "slime_block": { "lce_name": "slime" }, + "wet_sponge": { "lce_name": "sponge_wet" }, + "andesite": { "lce_name": "stone_andesite" }, + "smooth_andesite": { "lce_name": "stone_andesite_smooth" }, + "diorite": { "lce_name": "stone_diorite" }, + "smooth_diorite": { "lce_name": "stone_diorite_smooth" }, + "granite": { "lce_name": "stone_granite" }, + "smooth_granite": { "lce_name": "stone_granite_smooth" }, + "stone_bricks": { "lce_name": "stonebrick" }, + "chiseled_stone_bricks": { "lce_name": "stonebrick_carved" }, + "cracked_stone_bricks": { "lce_name": "stonebrick_cracked" }, + "mossy_stone_bricks": { "lce_name": "stonebrick_mossy" }, + "grass": { "lce_name": "tallgrass" }, + "torch": { "lce_name": "torch_on" }, + "oak_trapdoor": { "lce_name": "trapdoor" }, + "tripwire": { "lce_name": "trip_wire" }, + "tripwire_hook": { "lce_name": "trip_wire_source" }, + "lily_pad": { "lce_name": "waterlily" }, + "cobweb": { "lce_name": "web" }, + "tube_coral_block": { "lce_name": "coral_blue" }, + "tube_coral": { "lce_name": "coral_plant_blue" }, + "tube_coral_fan": { "lce_name": "coral_fan_blue" }, + "fire_coral_block": { "lce_name": "coral_red" }, + "fire_coral": { "lce_name": "coral_plant_red" }, + "fire_coral_fan": { "lce_name": "coral_fan_red" }, + "horn_coral_block": { "lce_name": "coral_yellow" }, + "horn_coral": { "lce_name": "coral_plant_yellow" }, + "horn_coral_fan": { "lce_name": "coral_fan_yellow" }, + "brain_coral_block": { "lce_name": "coral_pink" }, + "brain_coral": { "lce_name": "coral_plant_pink" }, + "brain_coral_fan": { "lce_name": "coral_fan_pink" }, + "bubble_coral_block": { "lce_name": "coral_purple" }, + "bubble_coral": { "lce_name": "coral_plant_purple" }, + "bubble_coral_fan": { "lce_name": "coral_fan_purple" }, + "dead_brain_coral_block": { "lce_name": "coral_pink_dead" }, + "dead_brain_coral_fan": { "lce_name": "coral_fan_pink_dead" }, + "dead_bubble_coral_block": { "lce_name": "coral_purple_dead" }, + "dead_bubble_coral_fan": { "lce_name": "coral_fan_purple_dead" }, + "dead_fire_coral_block": { "lce_name": "coral_red_dead" }, + "dead_fire_coral_fan": { "lce_name": "coral_fan_red_dead" }, + "dead_horn_coral_block": { "lce_name": "coral_yellow_dead" }, + "dead_horn_coral_fan": { "lce_name": "coral_fan_yellow_dead" }, + "dead_tube_coral_block": { "lce_name": "coral_blue_dead" }, + "dead_tube_coral_fan": { "lce_name": "coral_fan_blue_dead" }, + "wheat_stage0": { "lce_name": "crops_0" }, + "wheat_stage1": { "lce_name": "crops_1" }, + "wheat_stage2": { "lce_name": "crops_2" }, + "wheat_stage3": { "lce_name": "crops_3" }, + "wheat_stage4": { "lce_name": "crops_4" }, + "wheat_stage5": { "lce_name": "crops_5" }, + "wheat_stage6": { "lce_name": "crops_6" }, + "wheat_stage7": { "lce_name": "crops_7" }, - "wheat_stage_0": "crops_0", - "wheat_stage_1": "crops_1", - "wheat_stage_2": "crops_2", - "wheat_stage_3": "crops_3", - "wheat_stage_4": "crops_4", - "wheat_stage_5": "crops_5", - "wheat_stage_6": "crops_6", - "wheat_stage_7": "crops_7", + "wheat_stage_0": { "lce_name": "crops_0" }, + "wheat_stage_1": { "lce_name": "crops_1" }, + "wheat_stage_2": { "lce_name": "crops_2" }, + "wheat_stage_3": { "lce_name": "crops_3" }, + "wheat_stage_4": { "lce_name": "crops_4" }, + "wheat_stage_5": { "lce_name": "crops_5" }, + "wheat_stage_6": { "lce_name": "crops_6" }, + "wheat_stage_7": { "lce_name": "crops_7" }, - "bamboo_stalk": "bamboo_stem", - "bamboo_large_leaves": "bamboo_leaf", - "bamboo_small_leaves": "bamboo_leaf_small", - "bamboo_stage0": "bamboo_sapling", + "bamboo_stalk": { "lce_name": "bamboo_stem" }, + "bamboo_large_leaves": { "lce_name": "bamboo_leaf" }, + "bamboo_small_leaves": { "lce_name": "bamboo_leaf_small" }, + "bamboo_stage0": { "lce_name": "bamboo_sapling" }, - "lily_of_the_valley": "flower_lily_of_the_valley", - "cornflower": "flower_cornflower", + "lily_of_the_valley": { "lce_name": "flower_lily_of_the_valley" }, + "cornflower": { "lce_name": "flower_cornflower" }, - "sweet_berry_bush_stage0": "berry_bush_sapling", - "sweet_berry_bush_stage1": "berry_bush_no_berries", - "sweet_berry_bush_stage2": "berry_bush_some_berries", - "sweet_berry_bush_stage3": "berry_bush_full_berries", - "campfire_fire": "campfire", + "sweet_berry_bush_stage0": { "lce_name": "berry_bush_sapling" }, + "sweet_berry_bush_stage1": { "lce_name": "berry_bush_no_berries" }, + "sweet_berry_bush_stage2": { "lce_name": "berry_bush_some_berries" }, + "sweet_berry_bush_stage3": { "lce_name": "berry_bush_full_berries" }, + "campfire_fire": { "lce_name": "campfire" }, - "black_wool": "wool_colored_black", - "blue_wool": "wool_colored_blue", - "brown_wool": "wool_colored_brown", - "cyan_wool": "wool_colored_cyan", - "gray_wool": "wool_colored_gray", - "green_wool": "wool_colored_green", - "light_blue_wool": "wool_colored_light_blue", - "lime_wool": "wool_colored_lime", - "magenta_wool": "wool_colored_magenta", - "orange_wool": "wool_colored_orange", - "pink_wool": "wool_colored_pink", - "purple_wool": "wool_colored_purple", - "red_wool": "wool_colored_red", - "light_gray_wool": "wool_colored_silver", - "white_wool": "wool_colored_white", - "yellow_wool": "wool_colored_yellow", + "black_wool": { "lce_name": "wool_colored_black" }, + "blue_wool": { "lce_name": "wool_colored_blue" }, + "brown_wool": { "lce_name": "wool_colored_brown" }, + "cyan_wool": { "lce_name": "wool_colored_cyan" }, + "gray_wool": { "lce_name": "wool_colored_gray" }, + "green_wool": { "lce_name": "wool_colored_green" }, + "light_blue_wool": { "lce_name": "wool_colored_light_blue" }, + "lime_wool": { "lce_name": "wool_colored_lime" }, + "magenta_wool": { "lce_name": "wool_colored_magenta" }, + "orange_wool": { "lce_name": "wool_colored_orange" }, + "pink_wool": { "lce_name": "wool_colored_pink" }, + "purple_wool": { "lce_name": "wool_colored_purple" }, + "red_wool": { "lce_name": "wool_colored_red" }, + "light_gray_wool": { "lce_name": "wool_colored_silver" }, + "white_wool": { "lce_name": "wool_colored_white" }, + "yellow_wool": { "lce_name": "wool_colored_yellow" }, - "stripped_oak_log": "stripped_log_oak", - "stripped_oak_log_top": "stripped_log_oak_top", - "stripped_acacia_log": "stripped_log_acacia", - "stripped_acacia_log_top": "stripped_log_acacia_top", - "stripped_birch_log": "stripped_log_birch", - "stripped_birch_log_top": "stripped_log_birch_top", - "stripped_dark_oak_log": "stripped_log_dark_oak", - "stripped_dark_oak_log_top": "stripped_log_dark_oak_top", - "stripped_jungle_log": "stripped_log_jungle", - "stripped_jungle_log_top": "stripped_log_jungle_top", - "stripped_spruce_log": "stripped_log_spruce", - "stripped_spruce_log_top": "stripped_log_spruce_top", + "stripped_oak_log": { "lce_name": "stripped_log_oak" }, + "stripped_oak_log_top": { "lce_name": "stripped_log_oak_top" }, + "stripped_acacia_log": { "lce_name": "stripped_log_acacia" }, + "stripped_acacia_log_top": { "lce_name": "stripped_log_acacia_top" }, + "stripped_birch_log": { "lce_name": "stripped_log_birch" }, + "stripped_birch_log_top": { "lce_name": "stripped_log_birch_top" }, + "stripped_dark_oak_log": { "lce_name": "stripped_log_dark_oak" }, + "stripped_dark_oak_log_top": { "lce_name": "stripped_log_dark_oak_top" }, + "stripped_jungle_log": { "lce_name": "stripped_log_jungle" }, + "stripped_jungle_log_top": { "lce_name": "stripped_log_jungle_top" }, + "stripped_spruce_log": { "lce_name": "stripped_log_spruce" }, + "stripped_spruce_log_top": { "lce_name": "stripped_log_spruce_top" }, - "piston_inner": "piston_inner_top", - "smooth_stone_slab_side": "stoneslab_side", - "smooth_stone": "stoneslab_top", - "crafting_table_top": "workbench_top", - "crafting_table_side": "workbench_side", - "crafting_table_front": "workbench_front", - "furnace_front_on": "furnace_front_lit", + "piston_inner": { "lce_name": "piston_inner_top" }, + "smooth_stone_slab_side": { "lce_name": "stoneslab_side" }, + "smooth_stone": { "lce_name": "stoneslab_top" }, + "crafting_table_top": { "lce_name": "workbench_top" }, + "crafting_table_side": { "lce_name": "workbench_side" }, + "crafting_table_front": { "lce_name": "workbench_front" }, + "furnace_front_on": { "lce_name": "furnace_front_lit" }, - "mycelium_side": "mycel_side", - "mycelium_top": "mycel_top", - "redstone_lamp": "redstoneLight", - "redstone_lamp_on": "redstoneLight_lit", + "mycelium_side": { "lce_name": "mycel_side" }, + "mycelium_top": { "lce_name": "mycel_top" }, + "redstone_lamp": { "lce_name": "redstoneLight" }, + "redstone_lamp_on": { "lce_name": "redstoneLight_lit" }, - "destroy_stage_0": "destroy_0", - "destroy_stage_1": "destroy_1", - "destroy_stage_2": "destroy_2", - "destroy_stage_3": "destroy_3", - "destroy_stage_4": "destroy_4", - "destroy_stage_5": "destroy_5", - "destroy_stage_6": "destroy_6", - "destroy_stage_7": "destroy_7", - "destroy_stage_8": "destroy_8", - "destroy_stage_9": "destroy_9", + "destroy_stage_0": { "lce_name": "destroy_0" }, + "destroy_stage_1": { "lce_name": "destroy_1" }, + "destroy_stage_2": { "lce_name": "destroy_2" }, + "destroy_stage_3": { "lce_name": "destroy_3" }, + "destroy_stage_4": { "lce_name": "destroy_4" }, + "destroy_stage_5": { "lce_name": "destroy_5" }, + "destroy_stage_6": { "lce_name": "destroy_6" }, + "destroy_stage_7": { "lce_name": "destroy_7" }, + "destroy_stage_8": { "lce_name": "destroy_8" }, + "destroy_stage_9": { "lce_name": "destroy_9" }, - "enchanting_table_top": "enchantment_top", - "enchanting_table_side": "enchantment_side", - "enchanting_table_bottom": "enchantment_bottom", - "polished_andesite": "stone_andesite_smooth", - "polished_diorite": "stone_diorite_smooth", - "polished_granite": "stone_granite_smooth", + "enchanting_table_top": { "lce_name": "enchantment_top" }, + "enchanting_table_side": { "lce_name": "enchantment_side" }, + "enchanting_table_bottom": { "lce_name": "enchantment_bottom" }, + "polished_andesite": { "lce_name": "stone_andesite_smooth" }, + "polished_diorite": { "lce_name": "stone_diorite_smooth" }, + "polished_granite": { "lce_name": "stone_granite_smooth" } } \ No newline at end of file diff --git a/PckStudio.Core/Resources/java/latest2lce_entities.json b/PckStudio.Core/Resources/java/latest2lce_entities.json new file mode 100644 index 00000000..23bf2ebb --- /dev/null +++ b/PckStudio.Core/Resources/java/latest2lce_entities.json @@ -0,0 +1,565 @@ +{ + "bed/white": { + "lce_name": "item/bed" + //"texture_remap": { + // "source_size": { "width": 64, "height": 64 }, + // "target_size": { "width": 64, "height": 128 }, + // "areas": [ + // { + // "size": { "width": 32, "height": 32 }, + // "from": { "x": 0, "y": 0 }, + // "to": { "x": 0, "y": 0 } + // }, + // { + // "size": { "width": 32, "weight": 32 }, + // "from": { "x": 0, "y": 0 }, + // "to": { "x": 0, "y": 0 } + // } + // ] + //} + }, + "alex": { "lce_name": "mob/alex" }, + "steve": { "lce_name": "mob/char" }, + + "pig/pig": { "lce_name": "mob/pig" }, + "pig/pig_saddle": { "lce_name": "mob/saddle" }, + + "cow/cow": { "lce_name": "mob/cow" }, + "cow/mooshroom": { "lce_name": "mob/redcow" }, + + "cat/black": { "lce_name": "mob/cat_black" }, + "cat/ocelot": { "lce_name": "mob/ozelot" }, + "cat/red": { "lce_name": "mob/cat_red" }, + "cat/siamese": { "lce_name": "mob/cat_siamese" }, + + "sheep/sheep": { "lce_name": "mob/sheep" }, + "sheep/sheep_fur": { "lce_name": "mob/sheep_fur" }, + + "chicken": { "lce_name": "mob/chicken" }, + + "dolphin": { + "lce_name": "mob/dolphin", + "texture_remap": { + "areas": + [ + { + "size": { "width": 16, "height": 13 }, + "from": { "x": 35, "y": 0 }, + "to": { "x": 13, "y": 13 } + }, + { + "size": { "width": 42, "height": 7 }, + "from": { "x": 22, "y": 13 }, + "to": { "x": 0, "y": 26 } + }, + { + "size": { "width": 20, "height": 6 }, + "from": { "x": 25, "y": 20 }, + "to": { "x": 6, "y": 49 } + }, + { + "size": { "width": 32, "height": 1 }, + "from": { "x": 19, "y": 26 }, + "to": { "x": 0, "y": 55 } + }, + { + "size": { "width": 8, "height": 11 }, + "from": { "x": 11, "y": 9 }, + "to": { "x": 11, "y": 33 } + }, + { + "size": { "width": 30, "height": 5 }, + "from": { "x": 0, "y": 30 }, + "to": { "x": 0, "y": 44 } + }, + { + "size": { "width": 5, "height": 4 }, + "from": { "x": 51, "y": 5 }, + "to": { "x": 29, "y": 4 }, + "rotation": 90 + }, + { + "size": { "width": 5, "height": 4 }, + "from": { "x": 57, "y": 5 }, + "to": { "x": 34, "y": 4 }, + "rotation": -90 + }, + { + "size": { "width": 1, "height": 4 }, + "from": { "x": 56, "y": 5 }, + "to": { "x": 33, "y": 0 }, + "rotation": 180 + }, + { + "size": { "width": 1, "height": 4 }, + "from": { "x": 62, "y": 5 }, + "to": { "x": 34, "y": 0 }, + "rotation": 180 + }, + { + "size": { "width": 1, "height": 5 }, + "from": { "x": 56, "y": 0 }, + "to": { "x": 33, "y": 4 }, + "rotation": 180 + }, + { + "size": { "width": 1, "height": 5 }, + "from": { "x": 57, "y": 0 }, + "to": { "x": 38, "y": 4 }, + "rotation": 180 + } + ] + } + }, + + "bat": { "lce_name": "mob/bat" }, + + "snow_golem": { "lce_name": "mob/snowman" }, + + "iron_golem": { "lce_name": "mob/villager_golem" }, + + "squid": { "lce_name": "mob/squid" }, + "squid/squid": { "lce_name": "mob/squid" }, + + "bear/polarbear": { "lce_name": "mob/bear/polarbear" }, + + "parrot/parrot_blue": { "lce_name": "mob/parrot/parrot_blue" }, + "parrot/parrot_green": { "lce_name": "mob/parrot/parrot_green" }, + "parrot/parrot_grey": { "lce_name": "mob/parrot/parrot_grey" }, + "parrot/parrot_red_blue": { "lce_name": "mob/parrot/parrot_red_blue" }, + "parrot/parrot_yellow_blue": { "lce_name": "mob/parrot/parrot_yellow_blue" }, + + + "llama/brown": { "lce_name": "mob/llama/llama_brown" }, + "llama/creamy": { "lce_name": "mob/llama/llama_creamy" }, + "llama/gray": { "lce_name": "mob/llama/llmma_gray" }, + "llama/white": { "lce_name": "mob/llama/llama_white" }, + "llama/spit": { "lce_name": "mob/llama/spit" }, + + "llama/decor/black": { "lce_name": "mob/llama/decor/decor_black" }, + "llama/decor/blue": { "lce_name": "mob/llama/decor/decor_blue" }, + "llama/decor/brown": { "lce_name": "mob/llama/decor/decor_brown" }, + "llama/decor/cyan": { "lce_name": "mob/llama/decor/decor_cyan" }, + "llama/decor/gray": { "lce_name": "mob/llama/decor/decor_gray" }, + "llama/decor/green": { "lce_name": "mob/llama/decor/decor_green" }, + "llama/decor/light_blue": { "lce_name": "mob/llama/decor/decor_light_blue" }, + "llama/decor/light_gray": { "lce_name": "mob/llama/decor/decor_silver" }, + "llama/decor/lime": { "lce_name": "mob/llama/decor/decor_lime" }, + "llama/decor/magenta": { "lce_name": "mob/llama/decor/decor_magenta" }, + "llama/decor/orange": { "lce_name": "mob/llama/decor/decor_orange" }, + "llama/decor/pink": { "lce_name": "mob/llama/decor/decor_pink" }, + "llama/decor/purple": { "lce_name": "mob/llama/decor/decor_purple" }, + "llama/decor/red": { "lce_name": "mob/llama/decor/decor_red" }, + "llama/decor/white": { "lce_name": "mob/llama/decor/decor_white" }, + "llama/decor/yellow": { "lce_name": "mob/llama/decor/decor_yellow" }, + + "horse/donkey": { "lce_name": "mob/horse/donkey" }, + "horse/horse_black": { "lce_name": "mob/horse/horse_black" }, + "horse/horse_brown": { "lce_name": "mob/horse/horse_brown" }, + "horse/horse_chestnut": { "lce_name": "mob/horse/horse_chestnut" }, + "horse/horse_creamy": { "lce_name": "mob/horse/horse_creamy" }, + "horse/horse_darkbrown": { "lce_name": "mob/horse/horse_darkbrown" }, + "horse/horse_gray": { "lce_name": "mob/horse/horse_gray" }, + "horse/horse_markings_blackdots": { "lce_name": "mob/horse/horse_markings_blackdots" }, + "horse/horse_markings_white": { "lce_name": "mob/horse/horse_markings_white" }, + "horse/horse_markings_whitedots": { "lce_name": "mob/horse/horse_markings_whitedots" }, + "horse/horse_markings_whitefield": { "lce_name": "mob/horse/horse_markings_whitefield" }, + "horse/horse_skeleton": { "lce_name": "mob/horse/horse_skeleton" }, + "horse/horse_white": { "lce_name": "mob/horse/horse_white" }, + "horse/horse_zombie": { "lce_name": "mob/horse/horse_zombie" }, + "horse/mule": { "lce_name": "mob/horse/mule" }, + + // TODO + "horse/armor/horse_armor_leather": { "lce_name": "mob/horse/armor/horse_armor_leather_1" }, + "horse/armor/horse_armor_leather_1": { "lce_name": "mob/horse/armor/horse_armor_leather_1_b" }, + + "horse/armor/horse_armor_iron": { "lce_name": "mob/horse/armor/horse_armor_iron" }, + "horse/armor/horse_armor_gold": { "lce_name": "mob/horse/armor/horse_armor_gold" }, + "horse/armor/horse_armor_diamond": { "lce_name": "mob/horse/armor/horse_armor_diamond" }, + + "fish/cod": { "lce_name": "mob/fish/cod" }, + "fish/pufferfish": { "lce_name": "mob/fish/pufferfish" }, + "fish/salmon": { "lce_name": "mob/fish/salmon" }, + + "fish/tropical_a": { "lce_name": "mob/fish/tropical_a" }, + "fish/tropical_a_pattern_1": { "lce_name": "mob/fish/tropical_a_pattern_1" }, + "fish/tropical_a_pattern_2": { "lce_name": "mob/fish/tropical_a_pattern_2" }, + "fish/tropical_a_pattern_3": { "lce_name": "mob/fish/tropical_a_pattern_3" }, + "fish/tropical_a_pattern_4": { "lce_name": "mob/fish/tropical_a_pattern_4" }, + "fish/tropical_a_pattern_5": { "lce_name": "mob/fish/tropical_a_pattern_5" }, + "fish/tropical_a_pattern_6": { "lce_name": "mob/fish/tropical_a_pattern_6" }, + + "fish/tropical_b": { "lce_name": "mob/fish/tropical_b" }, + "fish/tropical_b_pattern_1": { "lce_name": "mob/fish/tropical_b_pattern_1" }, + "fish/tropical_b_pattern_2": { "lce_name": "mob/fish/tropical_b_pattern_2" }, + "fish/tropical_b_pattern_3": { "lce_name": "mob/fish/tropical_b_pattern_3" }, + "fish/tropical_b_pattern_4": { "lce_name": "mob/fish/tropical_b_pattern_4" }, + "fish/tropical_b_pattern_5": { "lce_name": "mob/fish/tropical_b_pattern_5" }, + "fish/tropical_b_pattern_6": { "lce_name": "mob/fish/tropical_b_pattern_6" }, + + "rabbit/black": { "lce_name": "mob/rabbit/black" }, + "rabbit/brown": { "lce_name": "mob/rabbit/brown" }, + "rabbit/caerbannog": { "lce_name": "mob/rabbit/caerbannog" }, + "rabbit/gold": { "lce_name": "mob/rabbit/gold" }, + "rabbit/salt": { "lce_name": "mob/rabbit/salt" }, + "rabbit/toast": { "lce_name": "mob/rabbit/toast" }, + "rabbit/white": { "lce_name": "mob/rabbit/white" }, + "rabbit/white_splotched": { "lce_name": "mob/rabbit/white_splotched" }, + + "creeper/creeper": { "lce_name": "mob/creeper" }, + "creeper/creeper_armor": { "lce_name": "armor/power" }, + + "illager/evoker": { "lce_name": "mob/illager/evoker" }, + "illager/evoker_fangs": { "lce_name": "mob/illager/fangs" }, + "illager/illusioner": { "lce_name": "mob/illager/illusionist" }, + "illager/vex": { "lce_name": "mob/illager/vex" }, + "illager/vex_charging": { "lce_name": "mob/illager/vex_charging" }, + "illager/vindicator": { "lce_name": "mob/illager/vindicator" }, + + "end_crystal/end_crystal": { "lce_name": "mob/enderdragon/crystal" }, + "end_crystal/end_crystal_beam": { "lce_name": "mob/enderdragon/beam" }, + + "enderdragon/dragon": { "lce_name": "mob/enderdragon/ender" }, + "enderdragon/dragon_eyes": { "lce_name": "mob/enderdragon/ender_eyes" }, + "enderdragon/dragon_fireball": { "lce_name": "mob/enderdragon/dragon_fireball" }, + "enderman/enderman": { "lce_name": "mob/enderman" }, + "enderman/enderman_eyes": { "lce_name": "mob/enderman_eyes" }, + + "ghast/ghast": { "lce_name": "mob/ghast" }, + "ghast/ghast_shooting": { "lce_name": "mob/ghast_fire" }, + "phantom": { "lce_name": "mob/phantom" }, + "guardian": { "lce_name": "mob/guardian" }, + "guardian_beam": { "lce_name": "mob/guardian_beam" }, + "guardian_elder": { "lce_name": "mob/guardian_elder" }, + "endermite": { "lce_name": "mob/endermite" }, + "witch": { "lce_name": "mob/witch" }, + "zombie_pigman": { "lce_name": "mob/pigzombie" }, + "silverfish": { "lce_name": "mob/silverfish" }, + "blaze": { "lce_name": "mob/fire" }, + + "slime/magmacube": { "lce_name": "mob/lava" }, + "slime/slime": { "lce_name": "mob/slime" }, + + "spider/spider": { "lce_name": "mob/spider" }, + "spider_eyes": { "lce_name": "mob/spider_eyes" }, + "spider/cave_spider": { "lce_name": "mob/cavespider" }, + + "skeleton/skeleton": { "lce_name": "mob/skeleton" }, + "skeleton/stray": { "lce_name": "mob/skeleton/stray" }, + "skeleton/stray_overlay": { "lce_name": "mob/skeleton/stray_overlay" }, + + "skeleton/wither_skeleton": { "lce_name": "mob/skeleton_wither" }, + + + "villager/butcher": { "lce_name": "mob/butcher" }, + "villager/farmer": { "lce_name": "mob/farmer" }, + "villager/librarian": { "lce_name": "mob/librarian" }, + "villager/priest": { "lce_name": "mob/priest" }, + "villager/smith": { "lce_name": "mob/smith" }, + "villager/villager": { "lce_name": "mob/villager" }, + + "zombie_villager/zombie_butcher": { "lce_name": "mob/zombie_villager/zombie_butcher" }, + "zombie_villager/zombie_farmer": { "lce_name": "mob/zombie_villager/zombie_farmer" }, + "zombie_villager/zombie_librarian": { "lce_name": "mob/zombie_villager/zombie_librarian" }, + "zombie_villager/zombie_priest": { "lce_name": "mob/zombie_villager/zombie_priest" }, + "zombie_villager/zombie_smith": { "lce_name": "mob/zombie_villager/zombie_smith" }, + "zombie_villager/zombie_villager": { "lce_name": "mob/zombie_villager/zombie_villager" }, + + "turtle/big_sea_turtle": { "lce_name": "mob/sea_turtle" }, + + "wither/wither/wither": { "lce_name": "mob/wither/wither" }, + "wither/wither/wither_armor": { "lce_name": "mob/wither/wither_armor" }, + "wither/wither/wither_invulnerable": { "lce_name": "mob/wither/wither_invulnerable" }, + + "wolf/wolf": { "lce_name": "mob/wolf" }, + "wolf/wolf_angry": { "lce_name": "mob/wolf_angry" }, + "wolf/wolf_collar": { "lce_name": "mob/wolf_collar" }, + "wolf/wolf_tame": { "lce_name": "mob/wolf_tame" }, + + "zombie/zombie": { "lce_name": "mob/zombie" }, + "zombie/zombie_villager": { "lce_name": "mob/zombie_villager" }, + "zombie/husk": { "lce_name": "mob/zombie/husk" }, + "zombie/drowned": { "lce_name": "mob/zombie/drowned" }, + + "shulker/shulker_white": { + "lce_name": "mob/shulker/endergolem", + "texture_remap": { + "source_size": { "width": 64, "height": 64 }, + "target_size": { "width": 64, "height": 128 }, + "areas": [ + { + "size": { "width": 64, "height": 52 }, + "from": { "x": 0, "y": 0 }, + "to": { "x": 0, "y": 0 } + }, + { + "size": { "width": 24, "height": 12 }, + "from": { "x": 0, "y": 52 }, + "to": { "x": 0, "y": 116 } + } + ] + } + }, + + "armorstand/wood": { "lce_name": "item/armorstand/wood" }, + + "banner_base": { "lce_name": "item/banner/banner_base" }, + + "boat/acacia": { "lce_name": "item/boat/boat_acacia" }, + "boat/birch": { "lce_name": "item/boat/boat_birch" }, + "boat/dark_oak": { "lce_name": "item/boat/boat_dark_oak" }, + "boat/jungle": { "lce_name": "item/boat/boat_jungle" }, + "boat/spruce": { "lce_name": "item/boat/boat_spruce" }, + + "sign": { "lce_name": "item/sign" }, + "signs/oak": { "lce_name": "item/sign" }, + "projectiles/arrow": { "lce_name": "item/arrows" }, + "lead_knot": { "lce_name": "item/lead_knot" }, + "trident": { "lce_name": "item/trident" }, + "trident_riptide": { "lce_name": "item/trident_riptide" }, + "enchanting_table_book": { "lce_name": "item/book" }, + "minecart": { "lce_name": "item/cart" }, + + "elytra": { "lce_name": "item/elytra" }, + "equipment/wings/elytra": { "lce_name": "item/elytra" }, + + "chest/normal": { + "lce_name": "item/chest", + + "texture_remap": { + "format": 6, + "areas": [ + { + "size": { "width": 14, "height": 14 }, + "from": { "x": 14, "y": 0 }, + "to": { "x": 28, "y": 0 }, + "flip": "y" + }, + { + "size": { "width": 14, "height": 14 }, + "from": { "x": 28, "y": 0 }, + "to": { "x": 14, "y": 0 }, + "flip": "y" + }, + { + "size": { "width": 14, "height": 14 }, + "from": { "x": 14, "y": 19 }, + "to": { "x": 28, "y": 19 }, + "flip": "y" + }, + { + "size": { "width": 14, "height": 14 }, + "from": { "x": 28, "y": 19 }, + "to": { "x": 14, "y": 19 }, + "flip": "y" + }, + { + "size": { "width": 28, "height": 10 }, + "from": { "x": 0, "y": 33 }, + "to": { "x": 28, "y": 33 }, + "flip": "y" + }, + { + "size": { "width": 28, "height": 10 }, + "from": { "x": 28, "y": 33 }, + "to": { "x": 0, "y": 33 }, + "flip": "y" + }, + { + "size": { "width": 28, "height": 5 }, + "from": { "x": 0, "y": 14 }, + "to": { "x": 28, "y": 14 }, + "flip": "y" + }, + { + "size": { "width": 28, "height": 5 }, + "from": { "x": 28, "y": 14 }, + "to": { "x": 0, "y": 14 }, + "flip": "y" + }, + { + "size": { "width": 6, "height": 5 }, + "from": { "x": 0, "y": 0 }, + "to": { "x": 0, "y": 0 } + } + ] + } + }, + "chest/normal_double": { "lce_name": "item/largechest" }, + "chest/trapped": { + "lce_name": "item/trapped", + + "texture_remap": { + "format": 6, + "areas": [ + { + "size": { "width": 14, "height": 14 }, + "from": { "x": 14, "y": 0 }, + "to": { "x": 28, "y": 0 }, + "flip": "y" + }, + { + "size": { "width": 14, "height": 14 }, + "from": { "x": 28, "y": 0 }, + "to": { "x": 14, "y": 0 }, + "flip": "y" + }, + { + "size": { "width": 14, "height": 14 }, + "from": { "x": 14, "y": 19 }, + "to": { "x": 28, "y": 19 }, + "flip": "y" + }, + { + "size": { "width": 14, "height": 14 }, + "from": { "x": 28, "y": 19 }, + "to": { "x": 14, "y": 19 }, + "flip": "y" + }, + { + "size": { "width": 28, "height": 10 }, + "from": { "x": 0, "y": 33 }, + "to": { "x": 28, "y": 33 }, + "flip": "y" + }, + { + "size": { "width": 28, "height": 10 }, + "from": { "x": 28, "y": 33 }, + "to": { "x": 0, "y": 33 }, + "flip": "y" + }, + { + "size": { "width": 28, "height": 5 }, + "from": { "x": 0, "y": 14 }, + "to": { "x": 28, "y": 14 }, + "flip": "y" + }, + { + "size": { "width": 28, "height": 5 }, + "from": { "x": 28, "y": 14 }, + "to": { "x": 0, "y": 14 }, + "flip": "y" + }, + { + "size": { "width": 6, "height": 5 }, + "from": { "x": 0, "y": 0 }, + "to": { "x": 0, "y": 0 } + } + ] + } + }, + "chest/trapped_double": { "lce_name": "item/trapped_double" }, + + "chest/ender": { + "lce_name": "item/enderchest", + "texture_remap": { + "format": 6, + "areas": [ + { + "size": { "width": 14, "height": 14 }, + "from": { "x": 14, "y": 0 }, + "to": { "x": 28, "y": 0 }, + "flip": "y" + }, + { + "size": { "width": 14, "height": 14 }, + "from": { "x": 28, "y": 0 }, + "to": { "x": 14, "y": 0 }, + "flip": "y" + }, + { + "size": { "width": 14, "height": 14 }, + "from": { "x": 14, "y": 19 }, + "to": { "x": 28, "y": 19 }, + "flip": "y" + }, + { + "size": { "width": 14, "height": 14 }, + "from": { "x": 28, "y": 19 }, + "to": { "x": 14, "y": 19 }, + "flip": "y" + }, + { + "size": { "width": 28, "height": 10 }, + "from": { "x": 0, "y": 33 }, + "to": { "x": 28, "y": 33 }, + "flip": "y" + }, + { + "size": { "width": 28, "height": 10 }, + "from": { "x": 28, "y": 33 }, + "to": { "x": 0, "y": 33 }, + "flip": "y" + }, + { + "size": { "width": 28, "height": 5 }, + "from": { "x": 0, "y": 14 }, + "to": { "x": 28, "y": 14 }, + "flip": "y" + }, + { + "size": { "width": 28, "height": 5 }, + "from": { "x": 28, "y": 14 }, + "to": { "x": 0, "y": 14 }, + "flip": "y" + }, + { + "size": { "width": 6, "height": 5 }, + "from": { "x": 0, "y": 0 }, + "to": { "x": 0, "y": 0 } + } + ] + } + }, + + "conduit/base": { + "lce_name": "item/conduit/conduit_base", + "texture_remap": { + "format": 6, + "source_size": { "width": 32, "height": 16 }, + "target_size": { "width": 24, "height": 12 }, + "areas": [ + { + "size": { "width": 24, "height": 12 }, + "from": { "x": 0, "y": 0 }, + "to": { "x": 0, "y": 0 }, + } + ] + } + }, + "conduit/cage": { "lce_name": "item/conduit/conduit_cage" }, + "conduit/closed_eye": { + "lce_name": "item/conduit/conduit_closed", + "texture_remap": { + "format": 6, + "source_size": { "width": 16, "height": 16 }, + "target_size": { "width": 8, "height": 8 }, + "areas": [ + { + "size": { "width": 8, "height": 8 }, + "from": { "x": 0, "y": 0 }, + "to": { "x": 0, "y": 0 }, + } + ] + } + }, + "conduit/open_eye": { + "lce_name": "item/conduit/conduit_open", + "texture_remap": { + "format": 6, + "source_size": { "width": 16, "height": 16 }, + "target_size": { "width": 8, "height": 8 }, + "areas": [ + { + "size": { "width": 8, "height": 8 }, + "from": { "x": 0, "y": 0 }, + "to": { "x": 0, "y": 0 }, + } + ] + } + }, + "conduit/wind": { "lce_name": "item/conduit/conduit_wind_horizontal" }, + "conduit/wind_vertical": { "lce_name": "item/conduit/conduit_wind_vertical" }, + + +} \ No newline at end of file diff --git a/PckStudio.Core/Resources/java/latest2lce_items.json b/PckStudio.Core/Resources/java/latest2lce_items.json index 7f40eaf5..cf25149a 100644 --- a/PckStudio.Core/Resources/java/latest2lce_items.json +++ b/PckStudio.Core/Resources/java/latest2lce_items.json @@ -1,246 +1,248 @@ { - "apple_golden": "appleGold", - "golden_apple": "appleGold", - "beef_cooked": "beefCooked", - "beef_raw": "beefRaw", - "beef": "beefRaw", - "blaze_powder": "blazePowder", - "blaze_rod": "blazeRod", - "oak_boat": "boat", - "book_normal": "book", - "chainmail_boots": "bootsChain", - "leather_boots": "bootsCloth", + "apple_golden": { "lce_name": "appleGold" }, + "golden_apple": { "lce_name": "appleGold" }, + "beef_cooked": { "lce_name": "beefCooked" }, + "beef_raw": { "lce_name": "beefRaw" }, + "beef": { "lce_name": "beefRaw" }, + "blaze_powder": { "lce_name": "blazePowder" }, + "blaze_rod": { "lce_name": "blazeRod" }, + "oak_boat": { "lce_name": "boat" }, + "book_normal": { "lce_name": "book" }, + "chainmail_boots": { "lce_name": "bootsChain" }, + "leather_boots": { "lce_name": "bootsCloth" }, - "crossbow_standby": "crossbow", - "crossbow_pulling_0": "crossbow_pull_0", - "crossbow_pulling_1": "crossbow_pull_1", - "crossbow_pulling_2": "crossbow_pull_2", - "campfire": "campfire_carried", - - "leather_boots_overlay": "bootsCloth_overlay", - "diamond_boots": "bootsDiamond", - "golden_boots": "bootsGold", - "iron_boots": "bootsIron", - "bow_standby": "bow", - "bow_pulling_0": "bow_pull_0", - "bow_pulling_1": "bow_pull_1", - "bow_pulling_2": "bow_pull_2", - "bucket_empty": "bucket", - "bucket_lava": "bucketLava", - "lava_bucket": "bucketLava", - "bucket_water": "bucketWater", - "water_bucket": "bucketWater", - "carrot_golden": "carrotGolden", - "golden_carrot": "carrotGolden", - "carrot_on_a_stick": "carrotOnAStick", - "carrot": "carrots", - "ink_sac": "dyePowder_black", - "lapis_lazuli": "dyePowder_blue", - "lingering_potion": "potion_bottle_lingering", - "chainmail_chestplate": "chestplateChain", - "leather_chestplate": "chestplateCloth", - "leather_chestplate_overlay": "chestplateCloth_overlay", - "diamond_chestplate": "chestplateDiamond", - "golden_chestplate": "chestplateGold", - "iron_chestplate": "chestplateIron", - "chicken_cooked": "chickenCooked", - "chicken_raw": "chickenRaw", - "clay_ball": "clay", - "repeater": "diode", - "door_iron": "doorIron", - "iron_door": "doorIron", - "door_wood": "doorWood", - "oak_door": "doorWood", - "spruce_door": "door_spruce", - "dark_oak_door": "door_dark_oak", - "jungle_door": "door_jungle", - "acacia_door": "door_acacia", - "birch_door": "door_birch", - "armor_stand": "wooden_armorstand", - "oak_sign": "sign", - "clock_00": "clock", - "clock_0000": "clock", - "compass_00": "compass", - "dye_powder_black": "dyePowder_black", - "dye_powder_blue": "dyePowder_blue", - "dye_powder_brown": "dyePowder_brown", - "dye_powder_cyan": "dyePowder_cyan", - "dye_powder_gray": "dyePowder_gray", - "dye_powder_green": "dyePowder_green", - "dye_powder_light_blue": "dyePowder_lightBlue", - "dye_powder_magenta": "dyePowder_magenta", - "dye_powder_orange": "dyePowder_orange", - "dye_powder_pink": "dyePowder_pink", - "dye_powder_purple": "dyePowder_purple", - "dye_powder_red": "dyePowder_red", - "dye_powder_silver": "dyePowder_silver", - "bone_meal": "dyePowder_white", - "dandelion_yellow": "dyePowder_yellow", - "emptyMap": "map_empty", - "book_enchanted": "enchantedBook", - "enchanted_book": "enchantedBook", - "ender_pearl": "enderPearl", - "experience_bottle": "expBottle", - "ender_eye": "eyeOfEnder", - "spider_eye_fermented": "fermentedSpiderEye", - "firework_star": "fireworks_charge", - "firework_star_overlay": "fireworks_charge_overlay", - "fire_charge": "fireball", - "fish_cooked": "fishCooked", - "fishingRod": "fishingRod_cast", - "fishing_rod_cast": "fishingRod_cast", - "fishingRod_empty": "fishingRod_cast", - "fishing_rod": "fishingRod_uncast", - "fishing_rod_uncast": "fishingRod_uncast", - "fish_raw": "fishRaw", - "flint_and_steel": "flintAndSteel", - "flower_pot": "flowerPot", - "item_frame": "frame", - "ghast_tear": "ghastTear", - "firework_rocket": "fireworks", - "potion_bottle_empty": "glass_bottle", - "gold_nugget": "goldNugget", - "diamond_axe": "hatchetDiamond", - "golden_axe": "hatchetGold", - "iron_axe": "hatchetIron", - "stone_axe": "hatchetStone", - "wooden_axe": "hatchetWood", - "chainmail_helmet": "helmetChain", - "leather_helmet": "helmetCloth", - "leather_helmet_overlay": "helmetCloth_overlay", - "diamond_helmet": "helmetDiamond", - "golden_helmet": "helmetGold", - "iron_helmet": "helmetIron", - "diamond_hoe": "hoeDiamond", - "golden_hoe": "hoeGold", - "iron_hoe": "hoeIron", - "stone_hoe": "hoeStone", - "wooden_hoe": "hoeWood", - "golden_horse_armor": "gold_horse_armor", - "horsearmorgold": "gold_horse_armor", - "gold_ingot": "ingotGold", - "iron_ingot": "ingotIron", - "lead": "leash", - "chainmail_leggings": "leggingsChain", - "leather_leggings": "leggingsCloth", - "leather_leggings_overlay": "leggingsCloth_overlay", - "diamond_leggings": "leggingsDiamond", - "golden_leggings": "leggingsGold", - "iron_leggings": "leggingsIron", - "magma_cream": "magmaCream", - "bucket_milk": "milk", - "milk_bucket": "milk", - "cod_bucket": "bucketFish", - "salmon_bucket": "bucketSalmon", - "pufferfish": "fish_pufferfish_raw", - "pufferfish_bucket": "bucketPuffer", - "tropical_fish": "fish_clownfish_raw", - "tropical_fish_bucket": "bucketTropical", - "fish_cod_raw": "fishRaw", - "cooked_cod": "fishCooked", - "minecart_normal": "minecart", - "minecart_chest": "minecartChest", - "command_block_minecart": "minecart_command_block", - "cooked_beef": "beefCooked", - "mutton": "mutton_raw", - "cooked_mutton": "mutton_cooked", - "cooked_porkchop": "porkchopCooked", - "rabbit": "rabbit_raw", - "cooked_rabbit": "rabbit_cooked", - "salmon": "fish_salmon_raw", - "nether_brick": "netherbrick", - "cooked_salmon": "fish_salmon_cooked", - "fermented_spider_eye": "fermentedSpiderEye", - "melon_slice": "melon", - "nether_wart": "netherStalkSeeds", - "potion_overlay": "potion_contents", - "writable_book": "writingBook", - "written_book": "writtenBook", - "totem_of_undying": "totem", - "turtle_egg": "totem", - "poisonous_potato": "potatoPoisonous", - "popped_chorus_fruit": "chorus_fruit_popped", - "porkchop": "porkchopRaw", - "map": "map_empty", - "filled_map_markings": "map_filled_markings", - "filled_map": "map_filled", - "glass_bottle": "glassBottle", - "dragon_breath": "dragonFireball", - "glistering_melon_slice": "speckledMelon", - "furnace_minecart": "minecart_furnace", - "hopper_minecart": "minecart_hopper", - "tnt_minecart": "minecart_tnt", - "spawn_egg": "monsterPlacer", - "spawn_egg_overlay": "monsterPlacer_overlay", - "mushroom_stew": "mushroomStew", - "name_tag": "nameTag", - "quartz": "netherquartz", - "nether_star": "netherStar", - "diamond_pickaxe": "pickaxeDiamond", - "golden_pickaxe": "pickaxeGold", - "iron_pickaxe": "pickaxeIron", - "stone_pickaxe": "pickaxeStone", - "wooden_pickaxe": "pickaxeWood", - "porkchop_cooked": "porkchopCooked", - "porkchop_raw": "porkchopRaw", - "potato_baked": "potatoBaked", - "baked_potato": "potatoBaked", - "potion_bottle_drinkable": "potion", - "potion_bottle_splash": "potion_splash", - "splash_potion": "potion_splash", - "pumpkin_pie": "pumpkinPie", - "redstone_dust": "redstone", - "rotten_flesh": "rottenFlesh", - "music_disc_cat": "record_cat", - "music_disc_blocks": "record_blocks", - "music_disc_chirp": "record_chirp", - "music_disc_far": "record_far", - "music_disc_mall": "record_mall", - "music_disc_stal": "record_stal", - "music_disc_ward": "record_ward", - "seeds_wheat": "seeds", - "wheat_seeds": "seeds", - "melon_seeds": "seeds_melon", - "pumpkin_seeds": "seeds_pumpkin", - "beetroot_seeds": "seeds_beetroot", - "slime_ball": "slimeball", - "sugar_cane": "reeds", - "white_dye": "dyePowder_white1", - "yellow_dye": "dyePowder_yellow", - "light_blue_dye": "dyePowder_light_blue", - "light_gray_dye": "dyePowder_silver", - "lime_dye": "dyePowder_lime", - "magenta_dye": "dyePowder_magenta", - "orange_dye": "dyePowder_orange", - "pink_dye": "dyePowder_pink", - "purple_dye": "dyePowder_purple", - "red_dye": "dyePowder_red", - "cyan_dye": "dyePowder_cyan", - "gray_dye": "dyePowder_gray", - "cactus_green": "dyePowder_green", - "black_dye": "dyePowder_black", - "blue_dye": "dyePowder_blue", - "brown_dye": "dyePowder_brown1", - "brewing_stand": "brewingStand", - "chest_minecart": "minecart_chest", - "chicken": "chickenRaw", - "cooked_chicken": "chickenCooked", - "cocoa_beans": "dyePowder_brown", - "diamond_shovel": "shovelDiamond", - "golden_shovel": "shovelGold", - "iron_shovel": "shovelIron", - "stone_shovel": "shovelStone", - "wooden_shovel": "shovelWood", - "melon_speckled": "speckledMelon", - "spider_eye": "spiderEye", - "gunpowder": "sulphur", - "diamond_sword": "swordDiamond", - "golden_sword": "swordGold", - "iron_sword": "swordIron", - "stone_sword": "swordStone", - "wooden_sword": "swordWood", - "book_writable": "writingBook", - "book_written": "writtenBook", - "glowstone_dust": "yellowDust", - "lantern": "lantern_carried", + "crossbow_standby": { "lce_name": "crossbow" }, + "crossbow_pulling_0": { "lce_name": "crossbow_pull_0" }, + "crossbow_pulling_1": { "lce_name": "crossbow_pull_1" }, + "crossbow_pulling_2": { "lce_name": "crossbow_pull_2" }, + "campfire": { "lce_name": "campfire_carried" }, + + "leather_boots_overlay": { "lce_name": "bootsCloth_overlay" }, + "heart_of_the_sea": { "lce_name": "nautilus_core" }, + "scute": { "lce_name": "turtle_shell_piece" }, + "diamond_boots": { "lce_name": "bootsDiamond" }, + "golden_boots": { "lce_name": "bootsGold" }, + "iron_boots": { "lce_name": "bootsIron" }, + "bow_standby": { "lce_name": "bow" }, + "bow_pulling_0": { "lce_name": "bow_pull_0" }, + "bow_pulling_1": { "lce_name": "bow_pull_1" }, + "bow_pulling_2": { "lce_name": "bow_pull_2" }, + "bucket_empty": { "lce_name": "bucket" }, + "bucket_lava": { "lce_name": "bucketLava" }, + "lava_bucket": { "lce_name": "bucketLava" }, + "bucket_water": { "lce_name": "bucketWater" }, + "water_bucket": { "lce_name": "bucketWater" }, + "carrot_golden": { "lce_name": "carrotGolden" }, + "golden_carrot": { "lce_name": "carrotGolden" }, + "carrot_on_a_stick": { "lce_name": "carrotOnAStick" }, + "carrot": { "lce_name": "carrots" }, + "ink_sac": { "lce_name": "dyePowder_black" }, + "lapis_lazuli": { "lce_name": "dyePowder_blue" }, + "lingering_potion": { "lce_name": "potion_bottle_lingering" }, + "chainmail_chestplate": { "lce_name": "chestplateChain" }, + "leather_chestplate": { "lce_name": "chestplateCloth" }, + "leather_chestplate_overlay": { "lce_name": "chestplateCloth_overlay" }, + "diamond_chestplate": { "lce_name": "chestplateDiamond" }, + "golden_chestplate": { "lce_name": "chestplateGold" }, + "iron_chestplate": { "lce_name": "chestplateIron" }, + "chicken_cooked": { "lce_name": "chickenCooked" }, + "chicken_raw": { "lce_name": "chickenRaw" }, + "clay_ball": { "lce_name": "clay" }, + "repeater": { "lce_name": "diode" }, + "door_iron": { "lce_name": "doorIron" }, + "iron_door": { "lce_name": "doorIron" }, + "door_wood": { "lce_name": "doorWood" }, + "oak_door": { "lce_name": "doorWood" }, + "spruce_door": { "lce_name": "door_spruce" }, + "dark_oak_door": { "lce_name": "door_dark_oak" }, + "jungle_door": { "lce_name": "door_jungle" }, + "acacia_door": { "lce_name": "door_acacia" }, + "birch_door": { "lce_name": "door_birch" }, + "armor_stand": { "lce_name": "wooden_armorstand" }, + "oak_sign": { "lce_name": "sign" }, + "clock_00": { "lce_name": "clock" }, + "clock_0000": { "lce_name": "clock" }, + "compass_00": { "lce_name": "compass" }, + "dye_powder_black": { "lce_name": "dyePowder_black" }, + "dye_powder_blue": { "lce_name": "dyePowder_blue" }, + "dye_powder_brown": { "lce_name": "dyePowder_brown" }, + "dye_powder_cyan": { "lce_name": "dyePowder_cyan" }, + "dye_powder_gray": { "lce_name": "dyePowder_gray" }, + "dye_powder_green": { "lce_name": "dyePowder_green" }, + "dye_powder_light_blue": { "lce_name": "dyePowder_lightBlue" }, + "dye_powder_magenta": { "lce_name": "dyePowder_magenta" }, + "dye_powder_orange": { "lce_name": "dyePowder_orange" }, + "dye_powder_pink": { "lce_name": "dyePowder_pink" }, + "dye_powder_purple": { "lce_name": "dyePowder_purple" }, + "dye_powder_red": { "lce_name": "dyePowder_red" }, + "dye_powder_silver": { "lce_name": "dyePowder_silver" }, + "bone_meal": { "lce_name": "dyePowder_white" }, + "dandelion_yellow": { "lce_name": "dyePowder_yellow" }, + "emptyMap": { "lce_name": "map_empty" }, + "book_enchanted": { "lce_name": "enchantedBook" }, + "enchanted_book": { "lce_name": "enchantedBook" }, + "ender_pearl": { "lce_name": "enderPearl" }, + "experience_bottle": { "lce_name": "expBottle" }, + "ender_eye": { "lce_name": "eyeOfEnder" }, + "spider_eye_fermented": { "lce_name": "fermentedSpiderEye" }, + "firework_star": { "lce_name": "fireworks_charge" }, + "firework_star_overlay": { "lce_name": "fireworks_charge_overlay" }, + "fire_charge": { "lce_name": "fireball" }, + "fish_cooked": { "lce_name": "fishCooked" }, + "fishingRod": { "lce_name": "fishingRod_cast" }, + "fishing_rod_cast": { "lce_name": "fishingRod_cast" }, + "fishingRod_empty": { "lce_name": "fishingRod_cast" }, + "fishing_rod": { "lce_name": "fishingRod_uncast" }, + "fishing_rod_uncast": { "lce_name": "fishingRod_uncast" }, + "fish_raw": { "lce_name": "fishRaw" }, + "flint_and_steel": { "lce_name": "flintAndSteel" }, + "flower_pot": { "lce_name": "flowerPot" }, + "item_frame": { "lce_name": "frame" }, + "ghast_tear": { "lce_name": "ghastTear" }, + "firework_rocket": { "lce_name": "fireworks" }, + "potion_bottle_empty": { "lce_name": "glass_bottle" }, + "gold_nugget": { "lce_name": "goldNugget" }, + "diamond_axe": { "lce_name": "hatchetDiamond" }, + "golden_axe": { "lce_name": "hatchetGold" }, + "iron_axe": { "lce_name": "hatchetIron" }, + "stone_axe": { "lce_name": "hatchetStone" }, + "wooden_axe": { "lce_name": "hatchetWood" }, + "chainmail_helmet": { "lce_name": "helmetChain" }, + "leather_helmet": { "lce_name": "helmetCloth" }, + "leather_helmet_overlay": { "lce_name": "helmetCloth_overlay" }, + "diamond_helmet": { "lce_name": "helmetDiamond" }, + "golden_helmet": { "lce_name": "helmetGold" }, + "iron_helmet": { "lce_name": "helmetIron" }, + "diamond_hoe": { "lce_name": "hoeDiamond" }, + "golden_hoe": { "lce_name": "hoeGold" }, + "iron_hoe": { "lce_name": "hoeIron" }, + "stone_hoe": { "lce_name": "hoeStone" }, + "wooden_hoe": { "lce_name": "hoeWood" }, + "golden_horse_armor": { "lce_name": "gold_horse_armor" }, + "horsearmorgold": { "lce_name": "gold_horse_armor" }, + "gold_ingot": { "lce_name": "ingotGold" }, + "iron_ingot": { "lce_name": "ingotIron" }, + "lead": { "lce_name": "leash" }, + "chainmail_leggings": { "lce_name": "leggingsChain" }, + "leather_leggings": { "lce_name": "leggingsCloth" }, + "leather_leggings_overlay": { "lce_name": "leggingsCloth_overlay" }, + "diamond_leggings": { "lce_name": "leggingsDiamond" }, + "golden_leggings": { "lce_name": "leggingsGold" }, + "iron_leggings": { "lce_name": "leggingsIron" }, + "magma_cream": { "lce_name": "magmaCream" }, + "bucket_milk": { "lce_name": "milk" }, + "milk_bucket": { "lce_name": "milk" }, + "cod_bucket": { "lce_name": "bucketFish" }, + "salmon_bucket": { "lce_name": "bucketSalmon" }, + "pufferfish": { "lce_name": "fish_pufferfish_raw" }, + "pufferfish_bucket": { "lce_name": "bucketPuffer" }, + "tropical_fish": { "lce_name": "fish_clownfish_raw" }, + "tropical_fish_bucket": { "lce_name": "bucketTropical" }, + "fish_cod_raw": { "lce_name": "fishRaw" }, + "cooked_cod": { "lce_name": "fishCooked" }, + "minecart_normal": { "lce_name": "minecart" }, + "minecart_chest": { "lce_name": "minecartChest" }, + "command_block_minecart": { "lce_name": "minecart_command_block" }, + "cooked_beef": { "lce_name": "beefCooked" }, + "mutton": { "lce_name": "mutton_raw" }, + "cooked_mutton": { "lce_name": "mutton_cooked" }, + "cooked_porkchop": { "lce_name": "porkchopCooked" }, + "rabbit": { "lce_name": "rabbit_raw" }, + "cooked_rabbit": { "lce_name": "rabbit_cooked" }, + "salmon": { "lce_name": "fish_salmon_raw" }, + "nether_brick": { "lce_name": "netherbrick" }, + "cooked_salmon": { "lce_name": "fish_salmon_cooked" }, + "fermented_spider_eye": { "lce_name": "fermentedSpiderEye" }, + "melon_slice": { "lce_name": "melon" }, + "nether_wart": { "lce_name": "netherStalkSeeds" }, + "potion_overlay": { "lce_name": "potion_contents" }, + "writable_book": { "lce_name": "writingBook" }, + "written_book": { "lce_name": "writtenBook" }, + "totem_of_undying": { "lce_name": "totem" }, + "turtle_egg": { "lce_name": "totem" }, + "poisonous_potato": { "lce_name": "potatoPoisonous" }, + "popped_chorus_fruit": { "lce_name": "chorus_fruit_popped" }, + "porkchop": { "lce_name": "porkchopRaw" }, + "map": { "lce_name": "map_empty" }, + "filled_map_markings": { "lce_name": "map_filled_markings" }, + "filled_map": { "lce_name": "map_filled" }, + "glass_bottle": { "lce_name": "glassBottle" }, + "dragon_breath": { "lce_name": "dragonFireball" }, + "glistering_melon_slice": { "lce_name": "speckledMelon" }, + "furnace_minecart": { "lce_name": "minecart_furnace" }, + "hopper_minecart": { "lce_name": "minecart_hopper" }, + "tnt_minecart": { "lce_name": "minecart_tnt" }, + "spawn_egg": { "lce_name": "monsterPlacer" }, + "spawn_egg_overlay": { "lce_name": "monsterPlacer_overlay" }, + "mushroom_stew": { "lce_name": "mushroomStew" }, + "name_tag": { "lce_name": "nameTag" }, + "quartz": { "lce_name": "netherquartz" }, + "nether_star": { "lce_name": "netherStar" }, + "diamond_pickaxe": { "lce_name": "pickaxeDiamond" }, + "golden_pickaxe": { "lce_name": "pickaxeGold" }, + "iron_pickaxe": { "lce_name": "pickaxeIron" }, + "stone_pickaxe": { "lce_name": "pickaxeStone" }, + "wooden_pickaxe": { "lce_name": "pickaxeWood" }, + "porkchop_cooked": { "lce_name": "porkchopCooked" }, + "porkchop_raw": { "lce_name": "porkchopRaw" }, + "potato_baked": { "lce_name": "potatoBaked" }, + "baked_potato": { "lce_name": "potatoBaked" }, + "potion_bottle_drinkable": { "lce_name": "potion" }, + "potion_bottle_splash": { "lce_name": "potion_splash" }, + "splash_potion": { "lce_name": "potion_splash" }, + "pumpkin_pie": { "lce_name": "pumpkinPie" }, + "redstone_dust": { "lce_name": "redstone" }, + "rotten_flesh": { "lce_name": "rottenFlesh" }, + "music_disc_cat": { "lce_name": "record_cat" }, + "music_disc_blocks": { "lce_name": "record_blocks" }, + "music_disc_chirp": { "lce_name": "record_chirp" }, + "music_disc_far": { "lce_name": "record_far" }, + "music_disc_mall": { "lce_name": "record_mall" }, + "music_disc_stal": { "lce_name": "record_stal" }, + "music_disc_ward": { "lce_name": "record_ward" }, + "seeds_wheat": { "lce_name": "seeds" }, + "wheat_seeds": { "lce_name": "seeds" }, + "melon_seeds": { "lce_name": "seeds_melon" }, + "pumpkin_seeds": { "lce_name": "seeds_pumpkin" }, + "beetroot_seeds": { "lce_name": "seeds_beetroot" }, + "slime_ball": { "lce_name": "slimeball" }, + "sugar_cane": { "lce_name": "reeds" }, + "white_dye": { "lce_name": "dyePowder_white1" }, + "yellow_dye": { "lce_name": "dyePowder_yellow" }, + "light_blue_dye": { "lce_name": "dyePowder_light_blue" }, + "light_gray_dye": { "lce_name": "dyePowder_silver" }, + "lime_dye": { "lce_name": "dyePowder_lime" }, + "magenta_dye": { "lce_name": "dyePowder_magenta" }, + "orange_dye": { "lce_name": "dyePowder_orange" }, + "pink_dye": { "lce_name": "dyePowder_pink" }, + "purple_dye": { "lce_name": "dyePowder_purple" }, + "red_dye": { "lce_name": "dyePowder_red" }, + "cyan_dye": { "lce_name": "dyePowder_cyan" }, + "gray_dye": { "lce_name": "dyePowder_gray" }, + "cactus_green": { "lce_name": "dyePowder_green" }, + "black_dye": { "lce_name": "dyePowder_black" }, + "blue_dye": { "lce_name": "dyePowder_blue" }, + "brown_dye": { "lce_name": "dyePowder_brown1" }, + "brewing_stand": { "lce_name": "brewingStand" }, + "chest_minecart": { "lce_name": "minecart_chest" }, + "chicken": { "lce_name": "chickenRaw" }, + "cooked_chicken": { "lce_name": "chickenCooked" }, + "cocoa_beans": { "lce_name": "dyePowder_brown" }, + "diamond_shovel": { "lce_name": "shovelDiamond" }, + "golden_shovel": { "lce_name": "shovelGold" }, + "iron_shovel": { "lce_name": "shovelIron" }, + "stone_shovel": { "lce_name": "shovelStone" }, + "wooden_shovel": { "lce_name": "shovelWood" }, + "melon_speckled": { "lce_name": "speckledMelon" }, + "spider_eye": { "lce_name": "spiderEye" }, + "gunpowder": { "lce_name": "sulphur" }, + "diamond_sword": { "lce_name": "swordDiamond" }, + "golden_sword": { "lce_name": "swordGold" }, + "iron_sword": { "lce_name": "swordIron" }, + "stone_sword": { "lce_name": "swordStone" }, + "wooden_sword": { "lce_name": "swordWood" }, + "book_writable": { "lce_name": "writingBook" }, + "book_written": { "lce_name": "writtenBook" }, + "glowstone_dust": { "lce_name": "yellowDust" }, + "lantern": { "lce_name": "lantern_carried" } } \ No newline at end of file diff --git a/PckStudio.Core/Resources/java/latest2lce_paintings.json b/PckStudio.Core/Resources/java/latest2lce_paintings.json index 15aed6b4..1a4a4d01 100644 --- a/PckStudio.Core/Resources/java/latest2lce_paintings.json +++ b/PckStudio.Core/Resources/java/latest2lce_paintings.json @@ -1,3 +1,6 @@ { - "paintings_kristoffer_zetterstrand": "kz" + "paintings_kristoffer_zetterstrand": { + "lce_name": "kz", + "passThrough": true + } } \ No newline at end of file diff --git a/PckStudio.Core/Serializer/AnimationSerializer.cs b/PckStudio.Core/Serializer/AnimationSerializer.cs index a3e78b68..90d6f552 100644 --- a/PckStudio.Core/Serializer/AnimationSerializer.cs +++ b/PckStudio.Core/Serializer/AnimationSerializer.cs @@ -43,15 +43,15 @@ namespace PckStudio.Core.Serializer private static string SerializeAnim(Animation animation) { - StringBuilder stringBuilder = new StringBuilder(animation.Interpolate ? "#" : string.Empty); - foreach (Animation.Frame frame in animation.GetFrames()) - stringBuilder.Append($"{animation.GetTextureIndex(frame.Texture)}*{frame.Ticks},"); - return stringBuilder.ToString(0, stringBuilder.Length - 1); + string anim = animation.GetFrames().Select(frame => $"{animation.GetTextureIndex(frame.Texture)}*{frame.Ticks}").ToString(","); + return (animation.Interpolate ? "#" : string.Empty) + anim; } public static Image SerializeTexture(Animation animation) { IReadOnlyCollection textures = animation.GetTextures(); + if (!textures.Any()) + return null; Size size = textures.First().Size; if (size.Width != size.Height) throw new Exception("Invalid size"); diff --git a/PckStudio.Core/Serializer/ImageSerializer.cs b/PckStudio.Core/Serializer/ImageSerializer.cs index 07f86568..dfa127e5 100644 --- a/PckStudio.Core/Serializer/ImageSerializer.cs +++ b/PckStudio.Core/Serializer/ImageSerializer.cs @@ -20,25 +20,42 @@ using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.IO; +using System.Reflection; using OMI.Formats.Pck; using PckStudio.Core.IO.TGA; using PckStudio.Interfaces; namespace PckStudio.Core.Serializer { + static class FindEncoderExt + { + public static ImageCodecInfo FindEncoder(this ImageFormat format) + { + MethodInfo findEncoderMethod = typeof(ImageFormat).GetMethod("FindEncoder", BindingFlags.NonPublic | BindingFlags.Instance, + null, new Type[] {}, null); + return (ImageCodecInfo)findEncoderMethod.Invoke(format, null); + } + } + internal sealed class ImageSerializer : IPckAssetSerializer { public static readonly ImageSerializer DefaultSerializer = new ImageSerializer(); public void Serialize(Image obj, ref PckAsset asset) { + if (obj is null) + return; var stream = new MemoryStream(); try { if (Path.GetExtension(asset.Filename) == ".tga") TGASerializer.SerializeToStream(stream, obj); else - obj.Save(stream, ImageFormat.Png); + { + var encoder = ImageFormat.Png.FindEncoder(); + var encParams = new EncoderParameters(1) { Param = [new EncoderParameter(Encoder.ColorDepth, 32)] }; + obj.Save(stream, encoder, encParams); + } asset.SetData(stream.ToArray()); } catch (Exception ex)