diff --git a/PCK-Studio/Controls/PckEditor.Designer.cs b/PCK-Studio/Controls/PckEditor.Designer.cs new file mode 100644 index 00000000..a5351572 --- /dev/null +++ b/PCK-Studio/Controls/PckEditor.Designer.cs @@ -0,0 +1,824 @@ +using System.Windows.Forms; + +namespace PckStudio.Controls +{ + partial class PckEditor + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.Windows.Forms.PictureBox logoPictureBox; + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PckEditor)); + this.pckFileLabel = new MetroFramework.Controls.MetroLabel(); + this.labelImageSize = new MetroFramework.Controls.MetroLabel(); + this.fileEntryCountLabel = new MetroFramework.Controls.MetroLabel(); + this.PropertiesTabControl = new MetroFramework.Controls.MetroTabControl(); + this.MetaTab = new MetroFramework.Controls.MetroTabPage(); + this.metroLabel2 = new MetroFramework.Controls.MetroLabel(); + this.entryTypeTextBox = new MetroFramework.Controls.MetroTextBox(); + this.entryDataTextBox = new MetroFramework.Controls.MetroTextBox(); + this.buttonEdit = new MetroFramework.Controls.MetroButton(); + this.metroLabel1 = new MetroFramework.Controls.MetroLabel(); + this.treeMeta = new System.Windows.Forms.TreeView(); + this.contextMenuMetaTree = new System.Windows.Forms.ContextMenuStrip(this.components); + this.addEntryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.addEntryToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.addBOXEntryToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.addANIMEntryToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.addMultipleEntriesToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.deleteEntryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.editAllEntriesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.label11 = new MetroFramework.Controls.MetroLabel(); + this.treeViewMain = new System.Windows.Forms.TreeView(); + this.contextMenuPCKEntries = new System.Windows.Forms.ContextMenuStrip(this.components); + this.createToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.folderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.skinToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.createAnimatedTextureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.audiopckToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.colourscolToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.CreateSkinsPCKToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.behavioursbinToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.entityMaterialsbinToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.importSkinsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.importSkinToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.importExtractedSkinsFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.addTextureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.addFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.exportToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.as3DSTextureFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.setFileTypeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.skinToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.capeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.textureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.languagesFileLOCToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.gameRulesFileGRFToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.audioPCKFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.coloursCOLFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.gameRulesHeaderGRHToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.skinsPCKToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.modelsFileBINToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.behavioursFileBINToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.entityMaterialsFileBINToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); + this.miscFunctionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.generateMipMapTextureToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.viewFileInfoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.correctSkinDecimalsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.setSubPCKEndiannessToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.bigEndianXbox360PS3WiiUToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.littleEndianPS4PSVitaSwitchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.setModelContainerFormatToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.version1ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.version2ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.version3114ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.extractToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator(); + this.cloneFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.renameFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.replaceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.deleteFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.imageList = new System.Windows.Forms.ImageList(this.components); + this.addMultipleEntriesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.LittleEndianCheckBox = new MetroFramework.Controls.MetroCheckBox(); + this.previewPictureBox = new PckStudio.ToolboxItems.InterpolationPictureBox(); + logoPictureBox = new System.Windows.Forms.PictureBox(); + ((System.ComponentModel.ISupportInitialize)(logoPictureBox)).BeginInit(); + this.PropertiesTabControl.SuspendLayout(); + this.MetaTab.SuspendLayout(); + this.contextMenuMetaTree.SuspendLayout(); + this.contextMenuPCKEntries.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.previewPictureBox)).BeginInit(); + this.SuspendLayout(); + // + // logoPictureBox + // + resources.ApplyResources(logoPictureBox, "logoPictureBox"); + logoPictureBox.Name = "logoPictureBox"; + logoPictureBox.TabStop = false; + // + // pckFileLabel + // + this.pckFileLabel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20))))); + resources.ApplyResources(this.pckFileLabel, "pckFileLabel"); + this.pckFileLabel.Name = "pckFileLabel"; + this.pckFileLabel.Theme = MetroFramework.MetroThemeStyle.Dark; + // + // labelImageSize + // + resources.ApplyResources(this.labelImageSize, "labelImageSize"); + this.labelImageSize.Name = "labelImageSize"; + this.labelImageSize.Theme = MetroFramework.MetroThemeStyle.Dark; + // + // fileEntryCountLabel + // + resources.ApplyResources(this.fileEntryCountLabel, "fileEntryCountLabel"); + this.fileEntryCountLabel.Name = "fileEntryCountLabel"; + this.fileEntryCountLabel.Theme = MetroFramework.MetroThemeStyle.Dark; + // + // PropertiesTabControl + // + this.PropertiesTabControl.Controls.Add(this.MetaTab); + resources.ApplyResources(this.PropertiesTabControl, "PropertiesTabControl"); + this.PropertiesTabControl.Name = "PropertiesTabControl"; + this.PropertiesTabControl.SelectedIndex = 0; + this.PropertiesTabControl.Style = MetroFramework.MetroColorStyle.Silver; + this.PropertiesTabControl.Theme = MetroFramework.MetroThemeStyle.Dark; + this.PropertiesTabControl.UseSelectable = true; + // + // MetaTab + // + this.MetaTab.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.MetaTab.Controls.Add(this.metroLabel2); + this.MetaTab.Controls.Add(this.entryTypeTextBox); + this.MetaTab.Controls.Add(this.entryDataTextBox); + this.MetaTab.Controls.Add(this.buttonEdit); + this.MetaTab.Controls.Add(this.metroLabel1); + this.MetaTab.Controls.Add(this.treeMeta); + this.MetaTab.HorizontalScrollbarBarColor = true; + this.MetaTab.HorizontalScrollbarHighlightOnWheel = false; + this.MetaTab.HorizontalScrollbarSize = 10; + resources.ApplyResources(this.MetaTab, "MetaTab"); + this.MetaTab.Name = "MetaTab"; + this.MetaTab.Theme = MetroFramework.MetroThemeStyle.Dark; + this.MetaTab.VerticalScrollbarBarColor = true; + this.MetaTab.VerticalScrollbarHighlightOnWheel = false; + this.MetaTab.VerticalScrollbarSize = 10; + // + // metroLabel2 + // + resources.ApplyResources(this.metroLabel2, "metroLabel2"); + this.metroLabel2.Name = "metroLabel2"; + this.metroLabel2.Theme = MetroFramework.MetroThemeStyle.Dark; + // + // entryTypeTextBox + // + resources.ApplyResources(this.entryTypeTextBox, "entryTypeTextBox"); + // + // + // + this.entryTypeTextBox.CustomButton.Image = ((System.Drawing.Image)(resources.GetObject("resource.Image"))); + this.entryTypeTextBox.CustomButton.ImeMode = ((System.Windows.Forms.ImeMode)(resources.GetObject("resource.ImeMode"))); + this.entryTypeTextBox.CustomButton.Location = ((System.Drawing.Point)(resources.GetObject("resource.Location"))); + this.entryTypeTextBox.CustomButton.Name = ""; + this.entryTypeTextBox.CustomButton.Size = ((System.Drawing.Size)(resources.GetObject("resource.Size"))); + this.entryTypeTextBox.CustomButton.Style = MetroFramework.MetroColorStyle.Blue; + this.entryTypeTextBox.CustomButton.TabIndex = ((int)(resources.GetObject("resource.TabIndex"))); + this.entryTypeTextBox.CustomButton.Theme = MetroFramework.MetroThemeStyle.Light; + this.entryTypeTextBox.CustomButton.UseSelectable = true; + this.entryTypeTextBox.CustomButton.Visible = ((bool)(resources.GetObject("resource.Visible"))); + this.entryTypeTextBox.Lines = new string[0]; + this.entryTypeTextBox.MaxLength = 32767; + this.entryTypeTextBox.Name = "entryTypeTextBox"; + this.entryTypeTextBox.PasswordChar = '\0'; + this.entryTypeTextBox.ScrollBars = System.Windows.Forms.ScrollBars.None; + this.entryTypeTextBox.SelectedText = ""; + this.entryTypeTextBox.SelectionLength = 0; + this.entryTypeTextBox.SelectionStart = 0; + this.entryTypeTextBox.ShortcutsEnabled = true; + this.entryTypeTextBox.Theme = MetroFramework.MetroThemeStyle.Dark; + this.entryTypeTextBox.UseSelectable = true; + this.entryTypeTextBox.WaterMarkColor = System.Drawing.Color.FromArgb(((int)(((byte)(109)))), ((int)(((byte)(109)))), ((int)(((byte)(109))))); + this.entryTypeTextBox.WaterMarkFont = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Pixel); + // + // entryDataTextBox + // + resources.ApplyResources(this.entryDataTextBox, "entryDataTextBox"); + // + // + // + this.entryDataTextBox.CustomButton.Image = ((System.Drawing.Image)(resources.GetObject("resource.Image1"))); + this.entryDataTextBox.CustomButton.ImeMode = ((System.Windows.Forms.ImeMode)(resources.GetObject("resource.ImeMode1"))); + this.entryDataTextBox.CustomButton.Location = ((System.Drawing.Point)(resources.GetObject("resource.Location1"))); + this.entryDataTextBox.CustomButton.Name = ""; + this.entryDataTextBox.CustomButton.Size = ((System.Drawing.Size)(resources.GetObject("resource.Size1"))); + this.entryDataTextBox.CustomButton.Style = MetroFramework.MetroColorStyle.Blue; + this.entryDataTextBox.CustomButton.TabIndex = ((int)(resources.GetObject("resource.TabIndex1"))); + this.entryDataTextBox.CustomButton.Theme = MetroFramework.MetroThemeStyle.Light; + this.entryDataTextBox.CustomButton.UseSelectable = true; + this.entryDataTextBox.CustomButton.Visible = ((bool)(resources.GetObject("resource.Visible1"))); + this.entryDataTextBox.Lines = new string[0]; + this.entryDataTextBox.MaxLength = 32767; + this.entryDataTextBox.Name = "entryDataTextBox"; + this.entryDataTextBox.PasswordChar = '\0'; + this.entryDataTextBox.ScrollBars = System.Windows.Forms.ScrollBars.None; + this.entryDataTextBox.SelectedText = ""; + this.entryDataTextBox.SelectionLength = 0; + this.entryDataTextBox.SelectionStart = 0; + this.entryDataTextBox.ShortcutsEnabled = true; + this.entryDataTextBox.Theme = MetroFramework.MetroThemeStyle.Dark; + this.entryDataTextBox.UseSelectable = true; + this.entryDataTextBox.WaterMarkColor = System.Drawing.Color.FromArgb(((int)(((byte)(109)))), ((int)(((byte)(109)))), ((int)(((byte)(109))))); + this.entryDataTextBox.WaterMarkFont = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Pixel); + // + // buttonEdit + // + resources.ApplyResources(this.buttonEdit, "buttonEdit"); + this.buttonEdit.Name = "buttonEdit"; + this.buttonEdit.Theme = MetroFramework.MetroThemeStyle.Dark; + this.buttonEdit.UseSelectable = true; + this.buttonEdit.Click += new System.EventHandler(this.buttonEdit_Click); + // + // metroLabel1 + // + resources.ApplyResources(this.metroLabel1, "metroLabel1"); + this.metroLabel1.Name = "metroLabel1"; + this.metroLabel1.Theme = MetroFramework.MetroThemeStyle.Dark; + // + // treeMeta + // + this.treeMeta.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(13)))), ((int)(((byte)(13)))), ((int)(((byte)(13))))); + this.treeMeta.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.treeMeta.ContextMenuStrip = this.contextMenuMetaTree; + resources.ApplyResources(this.treeMeta, "treeMeta"); + this.treeMeta.ForeColor = System.Drawing.SystemColors.Window; + this.treeMeta.Name = "treeMeta"; + this.treeMeta.PathSeparator = "/"; + this.treeMeta.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeMeta_AfterSelect); + this.treeMeta.DoubleClick += new System.EventHandler(this.treeMeta_DoubleClick); + this.treeMeta.KeyDown += new System.Windows.Forms.KeyEventHandler(this.treeMeta_KeyDown); + // + // contextMenuMetaTree + // + this.contextMenuMetaTree.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.addEntryToolStripMenuItem, + this.addMultipleEntriesToolStripMenuItem1, + this.deleteEntryToolStripMenuItem, + this.editAllEntriesToolStripMenuItem}); + this.contextMenuMetaTree.Name = "contextMenuStrip1"; + resources.ApplyResources(this.contextMenuMetaTree, "contextMenuMetaTree"); + // + // addEntryToolStripMenuItem + // + this.addEntryToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.addEntryToolStripMenuItem1, + this.addBOXEntryToolStripMenuItem1, + this.addANIMEntryToolStripMenuItem1}); + resources.ApplyResources(this.addEntryToolStripMenuItem, "addEntryToolStripMenuItem"); + this.addEntryToolStripMenuItem.Name = "addEntryToolStripMenuItem"; + // + // addEntryToolStripMenuItem1 + // + this.addEntryToolStripMenuItem1.Name = "addEntryToolStripMenuItem1"; + resources.ApplyResources(this.addEntryToolStripMenuItem1, "addEntryToolStripMenuItem1"); + this.addEntryToolStripMenuItem1.Click += new System.EventHandler(this.addEntryToolStripMenuItem_Click); + // + // addBOXEntryToolStripMenuItem1 + // + this.addBOXEntryToolStripMenuItem1.Name = "addBOXEntryToolStripMenuItem1"; + resources.ApplyResources(this.addBOXEntryToolStripMenuItem1, "addBOXEntryToolStripMenuItem1"); + this.addBOXEntryToolStripMenuItem1.Click += new System.EventHandler(this.addBOXEntryToolStripMenuItem1_Click); + // + // addANIMEntryToolStripMenuItem1 + // + this.addANIMEntryToolStripMenuItem1.Name = "addANIMEntryToolStripMenuItem1"; + resources.ApplyResources(this.addANIMEntryToolStripMenuItem1, "addANIMEntryToolStripMenuItem1"); + this.addANIMEntryToolStripMenuItem1.Click += new System.EventHandler(this.addANIMEntryToolStripMenuItem1_Click); + // + // addMultipleEntriesToolStripMenuItem1 + // + this.addMultipleEntriesToolStripMenuItem1.Name = "addMultipleEntriesToolStripMenuItem1"; + resources.ApplyResources(this.addMultipleEntriesToolStripMenuItem1, "addMultipleEntriesToolStripMenuItem1"); + this.addMultipleEntriesToolStripMenuItem1.Click += new System.EventHandler(this.addMultipleEntriesToolStripMenuItem1_Click); + // + // deleteEntryToolStripMenuItem + // + this.deleteEntryToolStripMenuItem.Image = global::PckStudio.Properties.Resources.file_delete; + this.deleteEntryToolStripMenuItem.Name = "deleteEntryToolStripMenuItem"; + resources.ApplyResources(this.deleteEntryToolStripMenuItem, "deleteEntryToolStripMenuItem"); + this.deleteEntryToolStripMenuItem.Click += new System.EventHandler(this.deleteEntryToolStripMenuItem_Click); + // + // editAllEntriesToolStripMenuItem + // + this.editAllEntriesToolStripMenuItem.Name = "editAllEntriesToolStripMenuItem"; + resources.ApplyResources(this.editAllEntriesToolStripMenuItem, "editAllEntriesToolStripMenuItem"); + this.editAllEntriesToolStripMenuItem.Click += new System.EventHandler(this.editAllEntriesToolStripMenuItem_Click); + // + // label11 + // + resources.ApplyResources(this.label11, "label11"); + this.label11.Name = "label11"; + // + // treeViewMain + // + this.treeViewMain.AllowDrop = true; + this.treeViewMain.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(12)))), ((int)(((byte)(12)))), ((int)(((byte)(12))))); + this.treeViewMain.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.treeViewMain.ContextMenuStrip = this.contextMenuPCKEntries; + resources.ApplyResources(this.treeViewMain, "treeViewMain"); + this.treeViewMain.ForeColor = System.Drawing.Color.White; + this.treeViewMain.ImageList = this.imageList; + this.treeViewMain.LabelEdit = true; + this.treeViewMain.Name = "treeViewMain"; + this.treeViewMain.PathSeparator = "/"; + this.treeViewMain.BeforeLabelEdit += new System.Windows.Forms.NodeLabelEditEventHandler(this.treeViewMain_BeforeLabelEdit); + this.treeViewMain.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.treeViewMain_ItemDrag); + this.treeViewMain.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeViewMain_AfterSelect); + this.treeViewMain.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.treeViewMain_NodeMouseClick); + this.treeViewMain.DragDrop += new System.Windows.Forms.DragEventHandler(this.treeViewMain_DragDrop); + this.treeViewMain.DragEnter += new System.Windows.Forms.DragEventHandler(this.treeViewMain_DragEnter); + this.treeViewMain.DragOver += new System.Windows.Forms.DragEventHandler(this.treeViewMain_DragOver); + this.treeViewMain.DoubleClick += new System.EventHandler(this.treeViewMain_DoubleClick); + this.treeViewMain.KeyDown += new System.Windows.Forms.KeyEventHandler(this.treeViewMain_KeyDown); + // + // contextMenuPCKEntries + // + this.contextMenuPCKEntries.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.createToolStripMenuItem, + this.importSkinsToolStripMenuItem, + this.exportToolStripMenuItem, + this.setFileTypeToolStripMenuItem, + this.toolStripSeparator5, + this.miscFunctionsToolStripMenuItem, + this.extractToolStripMenuItem, + this.toolStripSeparator6, + this.cloneFileToolStripMenuItem, + this.renameFileToolStripMenuItem, + this.replaceToolStripMenuItem, + this.deleteFileToolStripMenuItem}); + this.contextMenuPCKEntries.Name = "contextMenuStrip1"; + resources.ApplyResources(this.contextMenuPCKEntries, "contextMenuPCKEntries"); + this.contextMenuPCKEntries.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuPCKEntries_Opening); + // + // createToolStripMenuItem + // + this.createToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.folderToolStripMenuItem, + this.skinToolStripMenuItem, + this.createAnimatedTextureToolStripMenuItem, + this.audiopckToolStripMenuItem, + this.colourscolToolStripMenuItem, + this.CreateSkinsPCKToolStripMenuItem1, + this.behavioursbinToolStripMenuItem, + this.entityMaterialsbinToolStripMenuItem}); + resources.ApplyResources(this.createToolStripMenuItem, "createToolStripMenuItem"); + this.createToolStripMenuItem.Name = "createToolStripMenuItem"; + // + // folderToolStripMenuItem + // + resources.ApplyResources(this.folderToolStripMenuItem, "folderToolStripMenuItem"); + this.folderToolStripMenuItem.Name = "folderToolStripMenuItem"; + this.folderToolStripMenuItem.Click += new System.EventHandler(this.folderToolStripMenuItem_Click); + // + // skinToolStripMenuItem + // + resources.ApplyResources(this.skinToolStripMenuItem, "skinToolStripMenuItem"); + this.skinToolStripMenuItem.Name = "skinToolStripMenuItem"; + this.skinToolStripMenuItem.Click += new System.EventHandler(this.createSkinToolStripMenuItem_Click); + // + // createAnimatedTextureToolStripMenuItem + // + resources.ApplyResources(this.createAnimatedTextureToolStripMenuItem, "createAnimatedTextureToolStripMenuItem"); + this.createAnimatedTextureToolStripMenuItem.Name = "createAnimatedTextureToolStripMenuItem"; + this.createAnimatedTextureToolStripMenuItem.Click += new System.EventHandler(this.createAnimatedTextureToolStripMenuItem_Click); + // + // audiopckToolStripMenuItem + // + this.audiopckToolStripMenuItem.Image = global::PckStudio.Properties.Resources.BINKA_ICON; + this.audiopckToolStripMenuItem.Name = "audiopckToolStripMenuItem"; + resources.ApplyResources(this.audiopckToolStripMenuItem, "audiopckToolStripMenuItem"); + this.audiopckToolStripMenuItem.Click += new System.EventHandler(this.audiopckToolStripMenuItem_Click); + // + // colourscolToolStripMenuItem + // + this.colourscolToolStripMenuItem.Image = global::PckStudio.Properties.Resources.COL_ICON; + this.colourscolToolStripMenuItem.Name = "colourscolToolStripMenuItem"; + resources.ApplyResources(this.colourscolToolStripMenuItem, "colourscolToolStripMenuItem"); + this.colourscolToolStripMenuItem.Click += new System.EventHandler(this.colourscolToolStripMenuItem_Click); + // + // CreateSkinsPCKToolStripMenuItem1 + // + this.CreateSkinsPCKToolStripMenuItem1.Image = global::PckStudio.Properties.Resources.SKINS_ICON; + this.CreateSkinsPCKToolStripMenuItem1.Name = "CreateSkinsPCKToolStripMenuItem1"; + resources.ApplyResources(this.CreateSkinsPCKToolStripMenuItem1, "CreateSkinsPCKToolStripMenuItem1"); + this.CreateSkinsPCKToolStripMenuItem1.Click += new System.EventHandler(this.CreateSkinsPCKToolStripMenuItem1_Click); + // + // behavioursbinToolStripMenuItem + // + this.behavioursbinToolStripMenuItem.Image = global::PckStudio.Properties.Resources.BEHAVIOURS_ICON; + this.behavioursbinToolStripMenuItem.Name = "behavioursbinToolStripMenuItem"; + resources.ApplyResources(this.behavioursbinToolStripMenuItem, "behavioursbinToolStripMenuItem"); + this.behavioursbinToolStripMenuItem.Click += new System.EventHandler(this.behavioursbinToolStripMenuItem_Click); + // + // entityMaterialsbinToolStripMenuItem + // + this.entityMaterialsbinToolStripMenuItem.Image = global::PckStudio.Properties.Resources.ENTITY_MATERIALS_ICON; + this.entityMaterialsbinToolStripMenuItem.Name = "entityMaterialsbinToolStripMenuItem"; + resources.ApplyResources(this.entityMaterialsbinToolStripMenuItem, "entityMaterialsbinToolStripMenuItem"); + this.entityMaterialsbinToolStripMenuItem.Click += new System.EventHandler(this.entityMaterialsbinToolStripMenuItem_Click); + // + // importSkinsToolStripMenuItem + // + this.importSkinsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.importSkinToolStripMenuItem, + this.importExtractedSkinsFolderToolStripMenuItem, + this.addTextureToolStripMenuItem, + this.addFileToolStripMenuItem}); + resources.ApplyResources(this.importSkinsToolStripMenuItem, "importSkinsToolStripMenuItem"); + this.importSkinsToolStripMenuItem.Name = "importSkinsToolStripMenuItem"; + // + // importSkinToolStripMenuItem + // + resources.ApplyResources(this.importSkinToolStripMenuItem, "importSkinToolStripMenuItem"); + this.importSkinToolStripMenuItem.Name = "importSkinToolStripMenuItem"; + this.importSkinToolStripMenuItem.Click += new System.EventHandler(this.importSkinToolStripMenuItem_Click); + // + // importExtractedSkinsFolderToolStripMenuItem + // + resources.ApplyResources(this.importExtractedSkinsFolderToolStripMenuItem, "importExtractedSkinsFolderToolStripMenuItem"); + this.importExtractedSkinsFolderToolStripMenuItem.Name = "importExtractedSkinsFolderToolStripMenuItem"; + this.importExtractedSkinsFolderToolStripMenuItem.Click += new System.EventHandler(this.importExtractedSkinsFolder); + // + // addTextureToolStripMenuItem + // + this.addTextureToolStripMenuItem.Image = global::PckStudio.Properties.Resources.AddTexture; + this.addTextureToolStripMenuItem.Name = "addTextureToolStripMenuItem"; + resources.ApplyResources(this.addTextureToolStripMenuItem, "addTextureToolStripMenuItem"); + this.addTextureToolStripMenuItem.Click += new System.EventHandler(this.addTextureToolStripMenuItem_Click); + // + // addFileToolStripMenuItem + // + this.addFileToolStripMenuItem.Image = global::PckStudio.Properties.Resources.blank; + this.addFileToolStripMenuItem.Name = "addFileToolStripMenuItem"; + resources.ApplyResources(this.addFileToolStripMenuItem, "addFileToolStripMenuItem"); + this.addFileToolStripMenuItem.Click += new System.EventHandler(this.addFileToolStripMenuItem_Click); + // + // exportToolStripMenuItem + // + this.exportToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.as3DSTextureFileToolStripMenuItem}); + this.exportToolStripMenuItem.Name = "exportToolStripMenuItem"; + resources.ApplyResources(this.exportToolStripMenuItem, "exportToolStripMenuItem"); + // + // as3DSTextureFileToolStripMenuItem + // + this.as3DSTextureFileToolStripMenuItem.Name = "as3DSTextureFileToolStripMenuItem"; + resources.ApplyResources(this.as3DSTextureFileToolStripMenuItem, "as3DSTextureFileToolStripMenuItem"); + this.as3DSTextureFileToolStripMenuItem.Click += new System.EventHandler(this.as3DSTextureFileToolStripMenuItem_Click); + // + // setFileTypeToolStripMenuItem + // + this.setFileTypeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.skinToolStripMenuItem1, + this.capeToolStripMenuItem, + this.textureToolStripMenuItem, + this.languagesFileLOCToolStripMenuItem, + this.gameRulesFileGRFToolStripMenuItem, + this.audioPCKFileToolStripMenuItem, + this.coloursCOLFileToolStripMenuItem, + this.gameRulesHeaderGRHToolStripMenuItem, + this.skinsPCKToolStripMenuItem, + this.modelsFileBINToolStripMenuItem, + this.behavioursFileBINToolStripMenuItem, + this.entityMaterialsFileBINToolStripMenuItem}); + this.setFileTypeToolStripMenuItem.Name = "setFileTypeToolStripMenuItem"; + resources.ApplyResources(this.setFileTypeToolStripMenuItem, "setFileTypeToolStripMenuItem"); + // + // skinToolStripMenuItem1 + // + this.skinToolStripMenuItem1.Image = global::PckStudio.Properties.Resources.SKIN_ICON; + this.skinToolStripMenuItem1.Name = "skinToolStripMenuItem1"; + resources.ApplyResources(this.skinToolStripMenuItem1, "skinToolStripMenuItem1"); + // + // capeToolStripMenuItem + // + this.capeToolStripMenuItem.Image = global::PckStudio.Properties.Resources.CAPE_ICON; + this.capeToolStripMenuItem.Name = "capeToolStripMenuItem"; + resources.ApplyResources(this.capeToolStripMenuItem, "capeToolStripMenuItem"); + // + // textureToolStripMenuItem + // + this.textureToolStripMenuItem.Image = global::PckStudio.Properties.Resources.TEXTURE_ICON; + this.textureToolStripMenuItem.Name = "textureToolStripMenuItem"; + resources.ApplyResources(this.textureToolStripMenuItem, "textureToolStripMenuItem"); + // + // languagesFileLOCToolStripMenuItem + // + this.languagesFileLOCToolStripMenuItem.Image = global::PckStudio.Properties.Resources.LOC_ICON; + this.languagesFileLOCToolStripMenuItem.Name = "languagesFileLOCToolStripMenuItem"; + resources.ApplyResources(this.languagesFileLOCToolStripMenuItem, "languagesFileLOCToolStripMenuItem"); + // + // gameRulesFileGRFToolStripMenuItem + // + this.gameRulesFileGRFToolStripMenuItem.Image = global::PckStudio.Properties.Resources.GRF_ICON; + this.gameRulesFileGRFToolStripMenuItem.Name = "gameRulesFileGRFToolStripMenuItem"; + resources.ApplyResources(this.gameRulesFileGRFToolStripMenuItem, "gameRulesFileGRFToolStripMenuItem"); + // + // audioPCKFileToolStripMenuItem + // + this.audioPCKFileToolStripMenuItem.Image = global::PckStudio.Properties.Resources.BINKA_ICON; + this.audioPCKFileToolStripMenuItem.Name = "audioPCKFileToolStripMenuItem"; + resources.ApplyResources(this.audioPCKFileToolStripMenuItem, "audioPCKFileToolStripMenuItem"); + // + // coloursCOLFileToolStripMenuItem + // + this.coloursCOLFileToolStripMenuItem.Image = global::PckStudio.Properties.Resources.COL_ICON; + this.coloursCOLFileToolStripMenuItem.Name = "coloursCOLFileToolStripMenuItem"; + resources.ApplyResources(this.coloursCOLFileToolStripMenuItem, "coloursCOLFileToolStripMenuItem"); + // + // gameRulesHeaderGRHToolStripMenuItem + // + this.gameRulesHeaderGRHToolStripMenuItem.Image = global::PckStudio.Properties.Resources.GRH_ICON; + this.gameRulesHeaderGRHToolStripMenuItem.Name = "gameRulesHeaderGRHToolStripMenuItem"; + resources.ApplyResources(this.gameRulesHeaderGRHToolStripMenuItem, "gameRulesHeaderGRHToolStripMenuItem"); + // + // skinsPCKToolStripMenuItem + // + this.skinsPCKToolStripMenuItem.Image = global::PckStudio.Properties.Resources.SKINS_ICON; + this.skinsPCKToolStripMenuItem.Name = "skinsPCKToolStripMenuItem"; + resources.ApplyResources(this.skinsPCKToolStripMenuItem, "skinsPCKToolStripMenuItem"); + // + // modelsFileBINToolStripMenuItem + // + this.modelsFileBINToolStripMenuItem.Image = global::PckStudio.Properties.Resources.MODELS_ICON; + this.modelsFileBINToolStripMenuItem.Name = "modelsFileBINToolStripMenuItem"; + resources.ApplyResources(this.modelsFileBINToolStripMenuItem, "modelsFileBINToolStripMenuItem"); + // + // behavioursFileBINToolStripMenuItem + // + this.behavioursFileBINToolStripMenuItem.Image = global::PckStudio.Properties.Resources.BEHAVIOURS_ICON; + this.behavioursFileBINToolStripMenuItem.Name = "behavioursFileBINToolStripMenuItem"; + resources.ApplyResources(this.behavioursFileBINToolStripMenuItem, "behavioursFileBINToolStripMenuItem"); + // + // entityMaterialsFileBINToolStripMenuItem + // + this.entityMaterialsFileBINToolStripMenuItem.Image = global::PckStudio.Properties.Resources.ENTITY_MATERIALS_ICON; + this.entityMaterialsFileBINToolStripMenuItem.Name = "entityMaterialsFileBINToolStripMenuItem"; + resources.ApplyResources(this.entityMaterialsFileBINToolStripMenuItem, "entityMaterialsFileBINToolStripMenuItem"); + // + // toolStripSeparator5 + // + this.toolStripSeparator5.Name = "toolStripSeparator5"; + resources.ApplyResources(this.toolStripSeparator5, "toolStripSeparator5"); + // + // miscFunctionsToolStripMenuItem + // + this.miscFunctionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.generateMipMapTextureToolStripMenuItem1, + this.viewFileInfoToolStripMenuItem, + this.correctSkinDecimalsToolStripMenuItem, + this.setSubPCKEndiannessToolStripMenuItem, + this.setModelContainerFormatToolStripMenuItem}); + this.miscFunctionsToolStripMenuItem.Name = "miscFunctionsToolStripMenuItem"; + resources.ApplyResources(this.miscFunctionsToolStripMenuItem, "miscFunctionsToolStripMenuItem"); + // + // generateMipMapTextureToolStripMenuItem1 + // + this.generateMipMapTextureToolStripMenuItem1.Name = "generateMipMapTextureToolStripMenuItem1"; + resources.ApplyResources(this.generateMipMapTextureToolStripMenuItem1, "generateMipMapTextureToolStripMenuItem1"); + this.generateMipMapTextureToolStripMenuItem1.Click += new System.EventHandler(this.generateMipMapTextureToolStripMenuItem_Click); + // + // viewFileInfoToolStripMenuItem + // + this.viewFileInfoToolStripMenuItem.Name = "viewFileInfoToolStripMenuItem"; + resources.ApplyResources(this.viewFileInfoToolStripMenuItem, "viewFileInfoToolStripMenuItem"); + this.viewFileInfoToolStripMenuItem.Click += new System.EventHandler(this.viewFileInfoToolStripMenuItem_Click); + // + // correctSkinDecimalsToolStripMenuItem + // + this.correctSkinDecimalsToolStripMenuItem.Name = "correctSkinDecimalsToolStripMenuItem"; + resources.ApplyResources(this.correctSkinDecimalsToolStripMenuItem, "correctSkinDecimalsToolStripMenuItem"); + this.correctSkinDecimalsToolStripMenuItem.Click += new System.EventHandler(this.correctSkinDecimalsToolStripMenuItem_Click); + // + // setSubPCKEndiannessToolStripMenuItem + // + this.setSubPCKEndiannessToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.bigEndianXbox360PS3WiiUToolStripMenuItem, + this.littleEndianPS4PSVitaSwitchToolStripMenuItem}); + this.setSubPCKEndiannessToolStripMenuItem.Name = "setSubPCKEndiannessToolStripMenuItem"; + resources.ApplyResources(this.setSubPCKEndiannessToolStripMenuItem, "setSubPCKEndiannessToolStripMenuItem"); + // + // bigEndianXbox360PS3WiiUToolStripMenuItem + // + this.bigEndianXbox360PS3WiiUToolStripMenuItem.Name = "bigEndianXbox360PS3WiiUToolStripMenuItem"; + resources.ApplyResources(this.bigEndianXbox360PS3WiiUToolStripMenuItem, "bigEndianXbox360PS3WiiUToolStripMenuItem"); + this.bigEndianXbox360PS3WiiUToolStripMenuItem.Click += new System.EventHandler(this.bigEndianToolStripMenuItem_Click); + // + // littleEndianPS4PSVitaSwitchToolStripMenuItem + // + this.littleEndianPS4PSVitaSwitchToolStripMenuItem.Name = "littleEndianPS4PSVitaSwitchToolStripMenuItem"; + resources.ApplyResources(this.littleEndianPS4PSVitaSwitchToolStripMenuItem, "littleEndianPS4PSVitaSwitchToolStripMenuItem"); + this.littleEndianPS4PSVitaSwitchToolStripMenuItem.Click += new System.EventHandler(this.littleEndianToolStripMenuItem_Click); + // + // setModelContainerFormatToolStripMenuItem + // + this.setModelContainerFormatToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.version1ToolStripMenuItem, + this.version2ToolStripMenuItem, + this.version3114ToolStripMenuItem}); + this.setModelContainerFormatToolStripMenuItem.Name = "setModelContainerFormatToolStripMenuItem"; + resources.ApplyResources(this.setModelContainerFormatToolStripMenuItem, "setModelContainerFormatToolStripMenuItem"); + // + // version1ToolStripMenuItem + // + this.version1ToolStripMenuItem.Name = "version1ToolStripMenuItem"; + resources.ApplyResources(this.version1ToolStripMenuItem, "version1ToolStripMenuItem"); + this.version1ToolStripMenuItem.Click += new System.EventHandler(this.setModelVersion1ToolStripMenuItem_Click); + // + // version2ToolStripMenuItem + // + this.version2ToolStripMenuItem.Name = "version2ToolStripMenuItem"; + resources.ApplyResources(this.version2ToolStripMenuItem, "version2ToolStripMenuItem"); + this.version2ToolStripMenuItem.Click += new System.EventHandler(this.setModelVersion2ToolStripMenuItem_Click); + // + // version3114ToolStripMenuItem + // + this.version3114ToolStripMenuItem.Name = "version3114ToolStripMenuItem"; + resources.ApplyResources(this.version3114ToolStripMenuItem, "version3114ToolStripMenuItem"); + this.version3114ToolStripMenuItem.Click += new System.EventHandler(this.setModelVersion3ToolStripMenuItem_Click); + // + // extractToolStripMenuItem + // + resources.ApplyResources(this.extractToolStripMenuItem, "extractToolStripMenuItem"); + this.extractToolStripMenuItem.Name = "extractToolStripMenuItem"; + this.extractToolStripMenuItem.Click += new System.EventHandler(this.extractToolStripMenuItem_Click); + // + // toolStripSeparator6 + // + this.toolStripSeparator6.Name = "toolStripSeparator6"; + resources.ApplyResources(this.toolStripSeparator6, "toolStripSeparator6"); + // + // cloneFileToolStripMenuItem + // + this.cloneFileToolStripMenuItem.Name = "cloneFileToolStripMenuItem"; + resources.ApplyResources(this.cloneFileToolStripMenuItem, "cloneFileToolStripMenuItem"); + this.cloneFileToolStripMenuItem.Click += new System.EventHandler(this.cloneFileToolStripMenuItem_Click); + // + // renameFileToolStripMenuItem + // + resources.ApplyResources(this.renameFileToolStripMenuItem, "renameFileToolStripMenuItem"); + this.renameFileToolStripMenuItem.Name = "renameFileToolStripMenuItem"; + this.renameFileToolStripMenuItem.Click += new System.EventHandler(this.renameFileToolStripMenuItem_Click); + // + // replaceToolStripMenuItem + // + resources.ApplyResources(this.replaceToolStripMenuItem, "replaceToolStripMenuItem"); + this.replaceToolStripMenuItem.Name = "replaceToolStripMenuItem"; + this.replaceToolStripMenuItem.Click += new System.EventHandler(this.replaceToolStripMenuItem_Click); + // + // deleteFileToolStripMenuItem + // + this.deleteFileToolStripMenuItem.Image = global::PckStudio.Properties.Resources.file_delete; + this.deleteFileToolStripMenuItem.Name = "deleteFileToolStripMenuItem"; + resources.ApplyResources(this.deleteFileToolStripMenuItem, "deleteFileToolStripMenuItem"); + this.deleteFileToolStripMenuItem.Click += new System.EventHandler(this.deleteFileToolStripMenuItem_Click); + // + // imageList + // + this.imageList.ColorDepth = System.Windows.Forms.ColorDepth.Depth32Bit; + resources.ApplyResources(this.imageList, "imageList"); + this.imageList.TransparentColor = System.Drawing.Color.Transparent; + // + // addMultipleEntriesToolStripMenuItem + // + resources.ApplyResources(this.addMultipleEntriesToolStripMenuItem, "addMultipleEntriesToolStripMenuItem"); + this.addMultipleEntriesToolStripMenuItem.Name = "addMultipleEntriesToolStripMenuItem"; + // + // LittleEndianCheckBox + // + resources.ApplyResources(this.LittleEndianCheckBox, "LittleEndianCheckBox"); + this.LittleEndianCheckBox.BackColor = System.Drawing.Color.Transparent; + this.LittleEndianCheckBox.Name = "LittleEndianCheckBox"; + this.LittleEndianCheckBox.Style = MetroFramework.MetroColorStyle.White; + this.LittleEndianCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark; + this.LittleEndianCheckBox.UseSelectable = true; + // + // previewPictureBox + // + resources.ApplyResources(this.previewPictureBox, "previewPictureBox"); + this.previewPictureBox.BackColor = System.Drawing.Color.Transparent; + this.previewPictureBox.BackgroundInterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Default; + this.previewPictureBox.Image = global::PckStudio.Properties.Resources.NoImageFound; + this.previewPictureBox.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; + this.previewPictureBox.Name = "previewPictureBox"; + this.previewPictureBox.TabStop = false; + // + // PckEditor + // + this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(18)))), ((int)(((byte)(18))))); + resources.ApplyResources(this, "$this"); + this.Controls.Add(this.previewPictureBox); + this.Controls.Add(this.LittleEndianCheckBox); + this.Controls.Add(this.pckFileLabel); + this.Controls.Add(this.labelImageSize); + this.Controls.Add(this.fileEntryCountLabel); + this.Controls.Add(this.PropertiesTabControl); + this.Controls.Add(this.label11); + this.Controls.Add(this.treeViewMain); + this.Controls.Add(logoPictureBox); + this.ForeColor = System.Drawing.Color.Transparent; + this.Name = "PckEditor"; + this.Load += new System.EventHandler(this.PckEditor_Load); + ((System.ComponentModel.ISupportInitialize)(logoPictureBox)).EndInit(); + this.PropertiesTabControl.ResumeLayout(false); + this.MetaTab.ResumeLayout(false); + this.MetaTab.PerformLayout(); + this.contextMenuMetaTree.ResumeLayout(false); + this.contextMenuPCKEntries.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.previewPictureBox)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private MetroFramework.Controls.MetroLabel pckFileLabel; + private MetroFramework.Controls.MetroLabel labelImageSize; + private MetroFramework.Controls.MetroLabel fileEntryCountLabel; + private MetroFramework.Controls.MetroTabControl PropertiesTabControl; + private MetroFramework.Controls.MetroTabPage MetaTab; + private System.Windows.Forms.TreeView treeMeta; + private MetroFramework.Controls.MetroLabel label11; + private System.Windows.Forms.TreeView treeViewMain; + private PckStudio.ToolboxItems.InterpolationPictureBox previewPictureBox; + private System.Windows.Forms.ContextMenuStrip contextMenuMetaTree; + private System.Windows.Forms.ToolStripMenuItem addEntryToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem addEntryToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem addBOXEntryToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem addANIMEntryToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem addMultipleEntriesToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem deleteEntryToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem editAllEntriesToolStripMenuItem; + private System.Windows.Forms.ContextMenuStrip contextMenuPCKEntries; + private System.Windows.Forms.ToolStripMenuItem createToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem folderToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem skinToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem createAnimatedTextureToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem audiopckToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem colourscolToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem CreateSkinsPCKToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem behavioursbinToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem entityMaterialsbinToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem importSkinsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem importSkinToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem importExtractedSkinsFolderToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem addTextureToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem addFileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem exportToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem as3DSTextureFileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem setFileTypeToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem skinToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem capeToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem textureToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem languagesFileLOCToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem gameRulesFileGRFToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem audioPCKFileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem coloursCOLFileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem gameRulesHeaderGRHToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem skinsPCKToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem modelsFileBINToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem behavioursFileBINToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem entityMaterialsFileBINToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem miscFunctionsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem generateMipMapTextureToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem viewFileInfoToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem correctSkinDecimalsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem extractToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem cloneFileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem renameFileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem replaceToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem deleteFileToolStripMenuItem; + private System.Windows.Forms.ImageList imageList; + private System.Windows.Forms.ToolStripMenuItem addMultipleEntriesToolStripMenuItem1; + private MetroFramework.Controls.MetroLabel metroLabel2; + private MetroFramework.Controls.MetroTextBox entryTypeTextBox; + private MetroFramework.Controls.MetroTextBox entryDataTextBox; + private MetroFramework.Controls.MetroButton buttonEdit; + private MetroFramework.Controls.MetroLabel metroLabel1; + private MetroFramework.Controls.MetroCheckBox LittleEndianCheckBox; + private System.Windows.Forms.ToolStripMenuItem setSubPCKEndiannessToolStripMenuItem; + private ToolStripMenuItem bigEndianXbox360PS3WiiUToolStripMenuItem; + private ToolStripMenuItem littleEndianPS4PSVitaSwitchToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem setModelContainerFormatToolStripMenuItem; + private ToolStripMenuItem version1ToolStripMenuItem; + private ToolStripMenuItem version2ToolStripMenuItem; + private ToolStripMenuItem version3114ToolStripMenuItem; + private ToolStripSeparator toolStripSeparator5; + private ToolStripSeparator toolStripSeparator6; + } +} diff --git a/PCK-Studio/Controls/PckEditor.cs b/PCK-Studio/Controls/PckEditor.cs new file mode 100644 index 00000000..dc461bac --- /dev/null +++ b/PCK-Studio/Controls/PckEditor.cs @@ -0,0 +1,2251 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Windows.Forms; +using System.Drawing.Drawing2D; + +using MetroFramework.Forms; + +using OMI.Formats.Languages; +using OMI.Formats.Pck; +using OMI.Workers.Language; +using OMI.Workers.Pck; + +using OMI.Workers; +using OMI.Formats.Model; +using OMI.Workers.Model; +using OMI.Formats.GameRule; +using OMI.Workers.GameRule; +using OMI.Formats.Material; +using OMI.Workers.Material; +using OMI.Formats.Behaviour; +using OMI.Workers.Behaviour; +using OMI.Formats.Color; +using OMI.Workers.Color; + +using PckStudio.Core.Extensions; +using PckStudio.Forms.Editor; +using PckStudio.Forms.Additional_Popups; +using PckStudio.Forms.Additional_Popups.Animation; +using PckStudio.Interfaces; +using PckStudio.Internal; +using PckStudio.Popups; +using PckStudio.Properties; + +using PckStudio.Core.Deserializer; +using PckStudio.Core.Serializer; +using PckStudio.Core.Json; +using PckStudio.Core.FileFormats; +using PckStudio.Core.Skin; +using PckStudio.Rendering; +using PckStudio.Core; +using PckStudio.ModelSupport; +using PckStudio.Json; +using PckStudio.Core.IO.PckAudio; +using PckStudio.Core.IO._3DST; +using PckStudio.Core.Misc; + +namespace PckStudio.Controls +{ + internal partial class PckEditor : EditorControl + { + + private string _location = string.Empty; + + private readonly OMI.ByteOrder _originalEndianness; + private OMI.ByteOrder _currentEndianness; + private bool __modified = false; + private bool _wasModified + { + get => __modified; + set + { + if (__modified != value) + { + __modified = value; + _onModifiedChangeDelegate?.Invoke(value); + } + } + } + + private delegate void OnModifiedChangeDelegate(bool state); + private OnModifiedChangeDelegate _onModifiedChangeDelegate; + + private int _timesSaved = 0; + + private readonly Dictionary> _pckAssetTypeHandler; + + public PckEditor(PackInfo packInfo, ISaveContext saveContext) + : base(packInfo, saveContext) + { + InitializeComponent(); + _onModifiedChangeDelegate = OnModify; + _originalEndianness = packInfo.Endianness; + _currentEndianness = packInfo.Endianness; + + LittleEndianCheckBox.Visible = packInfo.AllowEndianSwap; + + treeViewMain.TreeViewNodeSorter = new PckNodeSorter(); + + skinToolStripMenuItem1.Click += (sender, e) => SetFileType(PckAssetType.SkinFile); + capeToolStripMenuItem.Click += (sender, e) => SetFileType(PckAssetType.CapeFile); + textureToolStripMenuItem.Click += (sender, e) => SetFileType(PckAssetType.TextureFile); + languagesFileLOCToolStripMenuItem.Click += (sender, e) => SetFileType(PckAssetType.LocalisationFile); + gameRulesFileGRFToolStripMenuItem.Click += (sender, e) => SetFileType(PckAssetType.GameRulesFile); + audioPCKFileToolStripMenuItem.Click += (sender, e) => SetFileType(PckAssetType.AudioFile); + coloursCOLFileToolStripMenuItem.Click += (sender, e) => SetFileType(PckAssetType.ColourTableFile); + gameRulesHeaderGRHToolStripMenuItem.Click += (sender, e) => SetFileType(PckAssetType.GameRulesHeader); + skinsPCKToolStripMenuItem.Click += (sender, e) => SetFileType(PckAssetType.SkinDataFile); + modelsFileBINToolStripMenuItem.Click += (sender, e) => SetFileType(PckAssetType.ModelsFile); + behavioursFileBINToolStripMenuItem.Click += (sender, e) => SetFileType(PckAssetType.BehavioursFile); + entityMaterialsFileBINToolStripMenuItem.Click += (sender, e) => SetFileType(PckAssetType.MaterialFile); + + imageList.Images.Add(Resources.ZZFolder); // Icon for folders + imageList.Images.Add(Resources.BINKA_ICON); // Icon for music cue file (audio.pck) + imageList.Images.Add(Resources.IMAGE_ICON); // Icon for images (unused for now) + imageList.Images.Add(Resources.LOC_ICON); // Icon for string localization files (languages.loc;localisation.loc) + imageList.Images.Add(Resources.PCK_ICON); // Icon for generic PCK files (*.pck) + imageList.Images.Add(Resources.ZUnknown); // Icon for Unknown formats + imageList.Images.Add(Resources.COL_ICON); // Icon for color palette files (colours.col) + imageList.Images.Add(Resources.SKINS_ICON); // Icon for Skin.pck archives (skins.pck) + imageList.Images.Add(Resources.MODELS_ICON); // Icon for Model files (models.bin) + imageList.Images.Add(Resources.GRF_ICON); // Icon for Game Rule files (*.grf) + imageList.Images.Add(Resources.GRH_ICON); // Icon for Game Rule Header files (*.grh) + imageList.Images.Add(Resources.INFO_ICON); // Icon for Info files (0) + imageList.Images.Add(Resources.SKIN_ICON); // Icon for Skin files (*.png) + imageList.Images.Add(Resources.CAPE_ICON); // Icon for Cape files (*.png) + imageList.Images.Add(Resources.TEXTURE_ICON); // Icon for Texture files (*.png;*.tga) + imageList.Images.Add(Resources.BEHAVIOURS_ICON); // Icon for Behaviour files (behaviours.bin) + imageList.Images.Add(Resources.ENTITY_MATERIALS_ICON); // Icon for Entity Material files (entityMaterials.bin) + + _pckAssetTypeHandler = new Dictionary>(15) + { + [PckAssetType.SkinFile] = HandleSkinFile, + [PckAssetType.CapeFile] = null, + [PckAssetType.TextureFile] = HandleTextureFile, + [PckAssetType.UIDataFile] = _ => throw new NotSupportedException("unused in-game"), + [PckAssetType.InfoFile] = null, + [PckAssetType.TexturePackInfoFile] = HandleInnerPckFile, + [PckAssetType.LocalisationFile] = HandleLocalisationFile, + [PckAssetType.GameRulesFile] = HandleGameRuleFile, + [PckAssetType.AudioFile] = HandleAudioFile, + [PckAssetType.ColourTableFile] = HandleColourFile, + [PckAssetType.GameRulesHeader] = HandleGameRuleFile, + [PckAssetType.SkinDataFile] = HandleInnerPckFile, + [PckAssetType.ModelsFile] = HandleModelsFile, + [PckAssetType.BehavioursFile] = HandleBehavioursFile, + [PckAssetType.MaterialFile] = HandleMaterialFile, + }; + } + + public new void Save() + { + base.Save(); + _timesSaved++; + _wasModified = false; + } + + public override void SaveAs() + { + using SaveFileDialog saveFileDialog = new SaveFileDialog + { + Filter = "PCK (Minecraft Console Package)|*.pck", + DefaultExt = ".pck", + }; + if (saveFileDialog.ShowDialog() == DialogResult.OK) + { + SaveTo(saveFileDialog.FileName); + pckFileLabel.Text = "Current PCK File: " + Path.GetFileName(_location); + } + } + + public override void Close() + { + if (_wasModified && MessageBox.Show("Save PCK?", "Modified PCK", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) + Save(); + } + + private void OnModify(bool state) + { + pckFileLabel.Text = state && !pckFileLabel.Text.StartsWith("*") ? "*" + pckFileLabel.Text : pckFileLabel.Text.Substring(1); + } + + public override void UpdateView() + { + BuildMainTreeView(); + } + + private void SaveTo(string filepath) + { + _location = filepath; + Save(); + } + + private void HandleInnerPckFile(PckAsset asset) + { + if (asset.Type != PckAssetType.SkinDataFile && asset.Type != PckAssetType.TexturePackInfoFile || asset.Size <= 0 || !Settings.Default.LoadSubPcks) + return; + + ISaveContext saveContext = new DelegatedSaveContext(false, (packInfo) => + { + if (packInfo.IsValid) + { + asset.SetData(new PckFileWriter(packInfo.File, _currentEndianness)); + _wasModified = true; + } + }); + + string caption = Path.GetFileName(asset.Filename); + string identifier = _location + Path.GetFileName(asset.Filename); + PckFile pckFile = asset.GetData(new PckFileReader(_originalEndianness)); + PackInfo packInfo = PackInfo.Create(pckFile, _originalEndianness, false); + + // TODO: may change to use a new tab page that will be closed when the main pck is closed + //Program.MainInstance.OpenNewPckTab(caption, identifier, packInfo, saveContext); + } + + private void HandleTextureFile(PckAsset asset) + { + _ = asset.IsMipmappedFile() && EditorValue.File.TryGetAsset(asset.GetNormalPath(), PckAssetType.TextureFile, out asset); + + if (asset.Size <= 0) + { + Trace.TraceInformation($"[{nameof(PckEditor)}:{nameof(HandleTextureFile)}] '{asset.Filename}' size is 0."); + return; + } + + ResourceLocation resourceLocation = ResourceLocation.GetFromPath(asset.Filename); + Debug.WriteLine("Handling Resource file: " + resourceLocation?.ToString()); + + switch (resourceLocation.Category) + { + case ResourceCategory.Unknown: + Debug.WriteLine($"Unknown Resource Category."); + break; + case ResourceCategory.MobEntityTextures: + case ResourceCategory.ItemEntityTextures: + { + string texturePath = asset.Filename.Substring(0, asset.Filename.Length - Path.GetExtension(asset.Filename).Length); + string[] modelNames = GameModelImporter.ModelMetaData.Where(kv => kv.Value.TextureLocations.Contains(texturePath)).Select(kv => kv.Key).ToArray(); + + if (modelNames.Length == 0) + { + MessageBox.Show("No Model info found"); + return; + } + + string modelName = modelNames[0]; + if (modelNames.Length > 1) + { + using ItemSelectionPopUp itemSelectionPopUp = new ItemSelectionPopUp(modelNames.ToArray()); + itemSelectionPopUp.ButtonText = "View"; + itemSelectionPopUp.LabelText = "Models:"; + if (itemSelectionPopUp.ShowDialog() != DialogResult.OK || !modelNames.IndexInRange(itemSelectionPopUp.SelectedIndex)) + { + return; + } + modelName = modelNames[itemSelectionPopUp.SelectedIndex]; + } + + Image texture = asset.GetTexture(); + string textureName = Path.GetFileName(texturePath); + + NamedData modelTexture = new NamedData(textureName, texture); + + bool hasCustomModel = false; + bool hasDefaultModel = TryGetDefaultEntityModel(modelName, out Model model); + if (EditorValue.File.TryGetAsset("models.bin", PckAssetType.ModelsFile, out PckAsset modelsAsset)) + { + ModelContainer models = modelsAsset.GetData(new ModelFileReader()); + hasCustomModel = models.ContainsModel(modelName); + if (hasCustomModel) + { + Debug.WriteLine($"Custom model for '{modelName}' found."); + model = models.GetModelByName(modelName); + } + } + if (!hasDefaultModel && !hasCustomModel) + { + MessageBox.Show(this, $"Not Model found for: {modelName}"); + return; + } + + ShowSimpleModelRender(model, modelTexture); + } + break; + + case ResourceCategory.ItemAnimation: + case ResourceCategory.BlockAnimation: + Animation animation = asset.GetDeserializedData(AnimationDeserializer.DefaultDeserializer); + string internalName = Path.GetFileNameWithoutExtension(asset.Filename); + IList textureInfos = resourceLocation.Category == ResourceCategory.ItemAnimation ? Tiles.ItemTileInfos : Tiles.BlockTileInfos; + string displayname = textureInfos.FirstOrDefault(p => p.InternalName == internalName)?.DisplayName ?? internalName; + + string[] specialTileNames = { "clock", "compass" }; + + ISaveContext saveContext = new DelegatedSaveContext(Settings.Default.AutoSaveChanges, (animation) => + { + asset.SetSerializedData(animation, AnimationSerializer.DefaultSerializer); + }); + + using (AnimationEditor animationEditor = new AnimationEditor(animation, saveContext, displayname, !internalName.ToLower().EqualsAny(specialTileNames))) + { + if (animationEditor.ShowDialog(this) == DialogResult.OK) + { + _wasModified = true; + BuildMainTreeView(); + } + } + break; + case ResourceCategory.ParticleAtlas: + case ResourceCategory.MoonPhaseAtlas: + case ResourceCategory.ItemAtlas: + case ResourceCategory.BlockAtlas: + case ResourceCategory.BannerAtlas: + case ResourceCategory.PaintingAtlas: + case ResourceCategory.ExplosionAtlas: + case ResourceCategory.ExperienceOrbAtlas: + case ResourceCategory.MapIconAtlas: + case ResourceCategory.AdditionalMapIconsAtlas: + Atlas atlas = asset.GetDeserializedData(new AtlasDeserializer(resourceLocation)); + ColorContainer colorContainer = default; + if (EditorValue.File.TryGetAsset("colours.col", PckAssetType.ColourTableFile, out PckAsset colAsset)) + colorContainer = colAsset.GetData(new COLFileReader()); + + ITryGet tryGetAnimation = TryGet.FromDelegate((string key, out Animation animation) => + { + bool found = EditorValue.File.TryGetAsset(key + ".png", PckAssetType.TextureFile, out PckAsset foundAsset) || + EditorValue.File.TryGetAsset(key + ".tga", PckAssetType.TextureFile, out foundAsset); + if (found) + { + animation = foundAsset.GetDeserializedData(AnimationDeserializer.DefaultDeserializer); + return true; + } + animation = default; + return false; + }); + + ITryGet> tryGetAnimationSaveContext = TryGet> + .FromDelegate((string key, out ISaveContext animationSaveContext) => + { + bool found = EditorValue.File.TryGetAsset(key + ".png", PckAssetType.TextureFile, out PckAsset foundAsset) || + EditorValue.File.TryGetAsset(key + ".tga", PckAssetType.TextureFile, out foundAsset); + + if (found) + { + animationSaveContext = new DelegatedSaveContext(Settings.Default.AutoSaveChanges, (animation) => + foundAsset.SetSerializedData(animation, AnimationSerializer.DefaultSerializer)); + return true; + } + + // you could validate the key(animationAssetPath) for validity. -miku + animationSaveContext = new DelegatedSaveContext(Settings.Default.AutoSaveChanges, (animation) => + { + if (animation.FrameCount == 0) + { + Debug.WriteLine("New animation has 0 frames. Aborting saving."); + return; + } + PckAsset newAnimationAsset = EditorValue.File.CreateNewAsset(key + ".png", PckAssetType.TextureFile); + newAnimationAsset.SetSerializedData(animation, AnimationSerializer.DefaultSerializer); + BuildMainTreeView(); + }); + return true; + }); + + ISaveContext textureAtlasSaveContext = new DelegatedSaveContext(Settings.Default.AutoSaveChanges, atlas => asset.SetTexture(atlas)); + + var viewer = new TextureAtlasEditor(atlas, textureAtlasSaveContext, resourceLocation, colorContainer, tryGetAnimation, tryGetAnimationSaveContext); + if (viewer.ShowDialog(this) == DialogResult.OK) + { + _wasModified = true; + BuildMainTreeView(); + } + break; + default: + Debug.WriteLine($"Unhandled Resource Category: {resourceLocation.Category}"); + break; + } + } + + private void HandleGameRuleFile(PckAsset asset) + { + const string cDEFLATE = "PS3"; + const string cXMEM = "Xbox 360"; + const string cZLIB = "Other Platforms"; + + ItemSelectionPopUp dialog = new ItemSelectionPopUp(cZLIB, cDEFLATE, cXMEM); + dialog.LabelText = "Type"; + dialog.ButtonText = "Ok"; + if (dialog.ShowDialog() != DialogResult.OK) + return; + + GameRuleFile.CompressionType compressiontype = dialog.SelectedItem switch + { + cDEFLATE => GameRuleFile.CompressionType.Deflate, + cXMEM => GameRuleFile.CompressionType.XMem, + cZLIB => GameRuleFile.CompressionType.Zlib, + _ => GameRuleFile.CompressionType.Unknown + }; + + GameRuleFile grf = asset.GetData(new GameRuleFileReader(compressiontype)); + + ISaveContext saveContext = new DelegatedSaveContext(Settings.Default.AutoSaveChanges, (gameRuleFile) => + { + asset.SetData(new GameRuleFileWriter(gameRuleFile)); + }); + + using GameRuleFileEditor grfEditor = new GameRuleFileEditor(grf, saveContext); + if (grfEditor.ShowDialog(this) == DialogResult.OK) + { + _wasModified = true; + UpdateRichPresence(); + } + } + + private void HandleAudioFile(PckAsset asset) + { + try + { + ISaveContext saveContext = new DelegatedSaveContext(Settings.Default.AutoSaveChanges, (audioFile) => + { + asset.SetData(new PckAudioFileWriter(audioFile, _currentEndianness)); + }); + PckAudioFile audioFile = asset.GetData(new PckAudioFileReader(_originalEndianness)); + using AudioEditor audioEditor = new AudioEditor(audioFile, saveContext); + _wasModified = audioEditor.ShowDialog(this) == DialogResult.OK; + } + catch (OverflowException) + { + MessageBox.Show(this, $"Failed to open {asset.Filename}\n" + + "Try converting the file by using the \"Misc. Functions/Set PCK Endianness\" tool and try again.", + "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + catch (Exception ex) + { + MessageBox.Show($"Failed to open {asset.Filename}\n" + ex.Message, + "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void HandleLocalisationFile(PckAsset asset) + { + LOCFile locFile = asset.GetData(new LOCFileReader()); + ISaveContext saveContext = new DelegatedSaveContext(Settings.Default.AutoSaveChanges, (locFile) => + { + asset.SetData(new LOCFileWriter(locFile, 2)); + }); + using LOCEditor locedit = new LOCEditor(locFile, saveContext); + _wasModified = locedit.ShowDialog(this) == DialogResult.OK; + UpdateRichPresence(); + } + + private void HandleColourFile(PckAsset asset) + { + ColorContainer colorContainer = asset.GetData(new COLFileReader()); + ISaveContext saveContext = new DelegatedSaveContext(Settings.Default.AutoSaveChanges, (colorContainer) => + { + asset.SetData(new COLFileWriter(colorContainer)); + }); + using COLEditor diag = new COLEditor(colorContainer, saveContext); + _wasModified = diag.ShowDialog(this) == DialogResult.OK; + } + + private void HandleSkinFile(PckAsset asset) + { + Skin skin = asset.GetSkin(); + if (asset.HasProperty("CAPEPATH")) + { + string capeAssetPath = asset.GetProperty("CAPEPATH"); + if (EditorValue.File.TryGetAsset(capeAssetPath, PckAssetType.CapeFile, out PckAsset capeAsset)) + { + skin.CapeTexture = capeAsset.GetTexture(); + } + } + + ISaveContext saveContext = new DelegatedSaveContext(Settings.Default.AutoSaveChanges, (customSkin) => + { + if (!TryGetLocFile(out LOCFile locFile)) + Debug.WriteLine("Failed to aquire loc file."); + asset.SetSkin(customSkin, locFile); + }); + + using CustomSkinEditor skinEditor = new CustomSkinEditor(skin, saveContext, EditorValue.File.HasVerionString); + if (skinEditor.ShowDialog() == DialogResult.OK) + { + entryDataTextBox.Text = entryTypeTextBox.Text = string.Empty; + _wasModified = true; + ReloadMetaTreeView(); + } + } + + private void HandleModelsFile(PckAsset asset) + { + ModelContainer modelContainer = asset.GetData(new ModelFileReader()); + if (modelContainer.ModelCount == 0) + { + MessageBox.Show("No models found.", "Empty Model file", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + } + + TryGetDelegate tryGetTexture = (string path, out Image img) => + { + bool found = EditorValue.File.TryGetAsset(path + ".png", PckAssetType.TextureFile, out PckAsset asset) || + EditorValue.File.TryGetAsset(path + ".tga", PckAssetType.TextureFile, out asset); + img = found ? asset.GetTexture() : default; + return found; + }; + + TrySetDelegate trySetTexture = (string path, Image img) => + { + bool found = EditorValue.File.TryGetAsset(path + ".png", PckAssetType.TextureFile, out PckAsset foundAsset) || + EditorValue.File.TryGetAsset(path + ".tga", PckAssetType.TextureFile, out foundAsset); + PckAsset asset = foundAsset ?? EditorValue.File.CreateNewAsset(path + ".png", PckAssetType.TextureFile); + asset.SetTexture(img); + return true; + }; + + bool hasMaterialAsset = EditorValue.File.TryGetAsset("entityMaterials.bin", PckAssetType.MaterialFile, out PckAsset entityMaterialAsset); + IReadOnlyDictionary entityMaterials = + hasMaterialAsset + ? entityMaterialAsset?.GetData(new MaterialFileReader()).ToDictionary(mat => mat.Name) + : new Dictionary(); + + ISaveContext saveContext = new DelegatedSaveContext(Settings.Default.AutoSaveChanges, (modelContainer) => + { + asset.SetData(new ModelFileWriter(modelContainer, modelContainer.Version)); + }); + + var editor = new ModelEditor(modelContainer, saveContext, TryGetSet.FromDelegates(tryGetTexture, trySetTexture), TryGet.FromDelegate(entityMaterials.TryGetValue)); + if (editor.ShowDialog() == DialogResult.OK) + { + BuildMainTreeView(); + _wasModified = true; + return; + } + } + + private void HandleBehavioursFile(PckAsset asset) + { + BehaviourFile behaviourFile = asset.GetData(new BehavioursReader()); + ISaveContext saveContext = new DelegatedSaveContext(Settings.Default.AutoSaveChanges, (behaviourFile) => + { + asset.SetData(new BehavioursWriter(behaviourFile)); + }); + using BehaviourEditor edit = new BehaviourEditor(behaviourFile, saveContext); + _wasModified = edit.ShowDialog(this) == DialogResult.OK; + } + + private void HandleMaterialFile(PckAsset asset) + { + MaterialContainer materials = asset.GetData(new MaterialFileReader()); + ISaveContext saveContext = new DelegatedSaveContext(Settings.Default.AutoSaveChanges, (materials) => + { + asset.SetData(new MaterialFileWriter(materials)); + }); + using MaterialsEditor edit = new MaterialsEditor(materials, saveContext); + _wasModified = edit.ShowDialog(this) == DialogResult.OK; + } + + private void CheckForPasswordAndRemove() + { + if (EditorValue.File.TryGetAsset("0", PckAssetType.InfoFile, out PckAsset asset)) + { + asset.RemoveProperties("LOCK"); + } + } + + /// + /// wrapper that allows the use of in TreeNode.Nodes.Find(, ...) and TreeNode.Nodes.ContainsKey() + /// + /// + /// + /// new Created TreeNode + private static TreeNode CreateNode(string name, object tag = null) + { + TreeNode node = new TreeNode(name); + node.Name = name; + node.Tag = tag; + return node; + } + + private TreeNode BuildNodeTreeBySeperator(TreeNodeCollection root, string path, char seperator) + { + _ = root ?? throw new ArgumentNullException(nameof(root)); + if (!path.Contains(seperator)) + { + TreeNode finalNode = CreateNode(path); + root.Add(finalNode); + return finalNode; + } + string nodeText = path.Substring(0, path.IndexOf(seperator)); + string subPath = path.Substring(path.IndexOf(seperator) + 1); + + if (string.IsNullOrWhiteSpace(nodeText)) + { + return BuildNodeTreeBySeperator(root, subPath, seperator); + } + + bool alreadyExists = root.ContainsKey(nodeText); + TreeNode subNode = alreadyExists ? root[nodeText] : CreateNode(nodeText); + if (!alreadyExists) + root.Add(subNode); + return BuildNodeTreeBySeperator(subNode.Nodes, subPath, seperator); + } + + private void BuildPckTreeView(TreeNodeCollection root, PckFile pckFile) + { + foreach (PckAsset asset in pckFile.GetAssets()) + { + TreeNode node = BuildNodeTreeBySeperator(root, asset.Filename, '/'); + node.Tag = asset; + int nodeIconId = GetNodeIconId(asset.Type); + node.ImageIndex = nodeIconId; + node.SelectedImageIndex = nodeIconId; + } + } + + private void BuildMainTreeView() + { + // In case the Rename function was just used and the selected node name no longer matches the file name + string selectedNodeText = treeViewMain.SelectedNode is TreeNode node ? node.FullPath : string.Empty; + previewPictureBox.Image = Resources.NoImageFound; + treeMeta.Nodes.Clear(); + treeViewMain.Nodes.Clear(); + BuildPckTreeView(treeViewMain.Nodes, EditorValue.File); + treeViewMain.Sort(); + + TreeNode[] selectedNodes = treeViewMain.FindPath(selectedNodeText); + if (selectedNodes.Length > 0) + { + treeViewMain.SelectedNode = selectedNodes[0]; + } + } + + private int GetNodeIconId(PckAssetType type) + { + return type switch + { + PckAssetType.AudioFile => 1, + PckAssetType.LocalisationFile => 3, + PckAssetType.TexturePackInfoFile => 4, + PckAssetType.ColourTableFile => 6, + PckAssetType.ModelsFile => 8, + PckAssetType.SkinDataFile => 7, + PckAssetType.GameRulesFile => 9, + PckAssetType.GameRulesHeader => 10, + PckAssetType.InfoFile => 11, + PckAssetType.SkinFile => 12, + PckAssetType.CapeFile => 13, + PckAssetType.TextureFile => 14, + PckAssetType.BehavioursFile => 15, + PckAssetType.MaterialFile => 16, + // unknown file format + _ => 5, + }; + } + + private List GetAllChildNodes(TreeNodeCollection root) + { + List childNodes = new List(); + foreach (TreeNode node in root) + { + childNodes.Add(node); + if (node.Nodes.Count > 0) + { + childNodes.AddRange(GetAllChildNodes(node.Nodes)); + } + } + return childNodes; + } + + private bool TryGetLocFile(out LOCFile locFile) + { + if (!EditorValue.File.TryGetAsset("localisation.loc", PckAssetType.LocalisationFile, out PckAsset locAsset) && + !EditorValue.File.TryGetAsset("languages.loc", PckAssetType.LocalisationFile, out locAsset)) + { + locFile = null; + return false; + } + + try + { + locFile = locAsset.GetData(new LOCFileReader()); + return true; + } + catch (Exception ex) + { + Debug.WriteLine(ex.Message); + } + locFile = null; + return false; + } + + private bool TrySetLocFile(in LOCFile locFile) + { + if (!EditorValue.File.TryGetAsset("localisation.loc", PckAssetType.LocalisationFile, out PckAsset locAsset) && + !EditorValue.File.TryGetAsset("languages.loc", PckAssetType.LocalisationFile, out locAsset)) + { + return false; + } + + try + { + locAsset.SetData(new LOCFileWriter(locFile, 2)); + return true; + } + catch (Exception ex) + { + Debug.WriteLine(ex.Message); + } + return false; + } + + private void ReloadMetaTreeView() + { + treeMeta.Nodes.Clear(); + if (treeViewMain.SelectedNode is TreeNode node && + node.Tag is PckAsset asset) + { + foreach (KeyValuePair property in asset.GetProperties()) + { + treeMeta.Nodes.Add(CreateNode(property.Key, property)); + } + } + } + + private void UpdateRichPresence() + { + if (EditorValue is not null && + TryGetLocFile(out LOCFile locfile) && + locfile.HasLocEntry("IDS_DISPLAY_NAME") && + locfile.Languages.Contains("en-EN")) + { + RPC.SetPresence("Editing a Pack:", $" > {locfile.GetLocEntry("IDS_DISPLAY_NAME", "en-EN")}"); + return; + } + // default + RPC.SetPresence("An Open Source .PCK File Editor"); + } + + private static PckAsset CreateNewAudioAsset(bool isLittle, PckAudioFile audioFile) + { + PckAsset newAsset = new PckAsset("audio.pck", PckAssetType.AudioFile); + newAsset.SetData(new PckAudioFileWriter(audioFile, isLittle ? OMI.ByteOrder.LittleEndian : OMI.ByteOrder.BigEndian)); + return newAsset; + } + + private static PckAudioFile CreateNewAudioFile() + { + PckAudioFile audioFile = new PckAudioFile(); + audioFile.AddCategory(PckAudioFile.AudioCategory.EAudioType.Overworld); + audioFile.AddCategory(PckAudioFile.AudioCategory.EAudioType.Nether); + audioFile.AddCategory(PckAudioFile.AudioCategory.EAudioType.End); + return audioFile; + } + + private void addFileToolStripMenuItem_Click(object sender, EventArgs e) + { + using var ofd = new OpenFileDialog(); + // Suddenly, and randomly, this started throwing an exception because it wasn't formatted correctly? + // So now it's formatted correctly and now displays the file type name in the dialog. + ofd.Filter = "All files (*.*)|*.*"; + ofd.Multiselect = false; + + if (ofd.ShowDialog(this) == DialogResult.OK) + { + using AddFilePrompt diag = new AddFilePrompt("res/" + Path.GetFileName(ofd.FileName)); + if (diag.ShowDialog(this) == DialogResult.OK) + { + if (EditorValue.File.Contains(diag.Filepath, diag.Filetype)) + { + MessageBox.Show(this, $"'{diag.Filepath}' of type {diag.Filetype} already exists.", "Import failed", MessageBoxButtons.OK, MessageBoxIcon.Warning); + return; + } + PckAsset asset = EditorValue.File.CreateNewAsset(diag.Filepath, diag.Filetype, () => File.ReadAllBytes(ofd.FileName)); + + BuildMainTreeView(); + _wasModified = true; + } + } + return; + } + + private void addTextureToolStripMenuItem_Click(object sender, EventArgs e) + { + using OpenFileDialog fileDialog = new OpenFileDialog(); + fileDialog.Filter = "Texture File(*.png,*.tga)|*.png;*.tga"; + if (fileDialog.ShowDialog(this) == DialogResult.OK) + { + using TextPrompt renamePrompt = new TextPrompt(Path.GetFileName(fileDialog.FileName)); + renamePrompt.LabelText = "Path"; + if (renamePrompt.ShowDialog(this) == DialogResult.OK && !string.IsNullOrEmpty(renamePrompt.NewText)) + { + if (EditorValue.File.Contains(renamePrompt.NewText, PckAssetType.TextureFile)) + { + MessageBox.Show(this, $"'{renamePrompt.NewText}' already exists.", "Import failed", MessageBoxButtons.OK, MessageBoxIcon.Warning); + return; + } + PckAsset asset = EditorValue.File.CreateNewAsset(renamePrompt.NewText, PckAssetType.TextureFile, () => File.ReadAllBytes(fileDialog.FileName)); + BuildMainTreeView(); + _wasModified = true; + } + } + } + + [Obsolete("Refactor or remove this")] + private void importSkinToolStripMenuItem_Click(object sender, EventArgs e) + { + using (OpenFileDialog contents = new OpenFileDialog()) + { + contents.Title = "Select Extracted Skin File"; + contents.Filter = "Skin File (*.png)|*.png"; + + if (contents.ShowDialog() == DialogResult.OK) + { + string skinNameImport = Path.GetFileName(contents.FileName); + byte[] data = File.ReadAllBytes(contents.FileName); + PckAsset mfNew = EditorValue.File.CreateNewAsset(skinNameImport, PckAssetType.SkinFile); + mfNew.SetData(data); + string propertyFile = Path.GetFileNameWithoutExtension(contents.FileName) + ".txt"; + if (File.Exists(propertyFile)) + { + string[] txtProperties = File.ReadAllLines(propertyFile); + if ((txtProperties.Contains("DISPLAYNAMEID") && txtProperties.Contains("DISPLAYNAME")) || + txtProperties.Contains("THEMENAMEID") && txtProperties.Contains("THEMENAME") && + TryGetLocFile(out LOCFile locFile)) + { + // do stuff + //l.AddLocKey(locThemeId, locTheme); + //using (var stream = new MemoryStream()) + //{ + // LOCFileWriter.Write(stream, locFile); + // locdata.SetData(stream.ToArray()); + //} + } + + try + { + foreach (string prop in txtProperties) + { + string[] arg = prop.Split(':'); + if (arg.Length < 2) + continue; + string key = arg[0]; + string value = arg[1]; + if (key == "DISPLNAMEID" || key == "THEMENAMEID") + { + + } + mfNew.AddProperty(key, value); + } + _wasModified = true; + } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + } + } + } + } + } + + private void folderToolStripMenuItem_Click(object sender, EventArgs e) + { + TextPrompt folderNamePrompt = new TextPrompt(); + if (treeViewMain.SelectedNode is not null) + folderNamePrompt.contextLabel.Text = + $"New folder at the location of \"{( + !treeViewMain.SelectedNode.IsTagOfType() + ? "/" + treeViewMain.SelectedNode.FullPath + : treeViewMain.SelectedNode.Parent == null ? "/" : "/" + treeViewMain.SelectedNode.Parent.FullPath)}\""; + folderNamePrompt.OKButtonText = "Add"; + if (folderNamePrompt.ShowDialog(this) == DialogResult.OK) + { + TreeNode folerNode = CreateNode(folderNamePrompt.NewText); + folerNode.ImageIndex = 0; + folerNode.SelectedImageIndex = 0; + + TreeNodeCollection nodeCollection = treeViewMain.Nodes; + if (treeViewMain.SelectedNode is TreeNode node) + { + if (node.Tag is PckAsset asset && + asset.Type != PckAssetType.TexturePackInfoFile && + asset.Type != PckAssetType.SkinDataFile) + { + if (node.Parent is TreeNode parentNode) + { + nodeCollection = parentNode.Nodes; + } + } + else + nodeCollection = node.Nodes; + } + nodeCollection.Add(folerNode); + } + } + + private void SetFileType(PckAssetType type) + { + if (treeViewMain.SelectedNode.TryGetTagData(out PckAsset asset)) + { + Debug.WriteLine($"Setting {asset.Type} to {type}"); + asset.Type = type; + int nodeIconId = GetNodeIconId(type); + treeViewMain.SelectedNode.ImageIndex = nodeIconId; + treeViewMain.SelectedNode.SelectedImageIndex = nodeIconId; + } + } + + private void treeViewMain_AfterSelect(object sender, TreeViewEventArgs e) + { + ReloadMetaTreeView(); + + entryTypeTextBox.Text = entryDataTextBox.Text = labelImageSize.Text = string.Empty; + buttonEdit.Visible = false; + + previewPictureBox.Image = Resources.NoImageFound; + viewFileInfoToolStripMenuItem.Visible = false; + + if (!e.Node.TryGetTagData(out PckAsset asset)) + { + return; + } + + viewFileInfoToolStripMenuItem.Visible = true; + if (asset.HasProperty("BOX")) + { + buttonEdit.Text = "EDIT BOXES"; + buttonEdit.Visible = true; + } + else if (asset.HasProperty("ANIM") && + asset.GetProperty("ANIM", s => SkinANIM.FromString(s) == (SkinAnimMask.RESOLUTION_64x64 | SkinAnimMask.SLIM_MODEL))) + { + buttonEdit.Text = "View Skin"; + buttonEdit.Visible = true; + } + + switch (asset.Type) + { + case PckAssetType.SkinFile: + case PckAssetType.CapeFile: + case PckAssetType.TextureFile: + { + Image img = asset.GetTexture(); + + previewPictureBox.Image = img; + labelImageSize.Text = $"{previewPictureBox.Image.Size.Width}x{previewPictureBox.Image.Size.Height}"; + + if (asset.Type != PckAssetType.TextureFile) + break; + + ResourceLocation resourceLocation = ResourceLocation.GetFromPath(asset.Filename); + if (resourceLocation is null || resourceLocation.Category == ResourceCategory.Unknown) + break; + + if (resourceLocation.Category == ResourceCategory.ItemAnimation || + resourceLocation.Category == ResourceCategory.BlockAnimation && + !asset.IsMipmappedFile()) + { + buttonEdit.Text = "EDIT TILE ANIMATION"; + buttonEdit.Visible = true; + break; + } + + buttonEdit.Text = "EDIT TEXTURE ATLAS"; + buttonEdit.Visible = true; + } + break; + + case PckAssetType.LocalisationFile: + buttonEdit.Text = "EDIT LOC"; + buttonEdit.Visible = true; + break; + + case PckAssetType.AudioFile: + buttonEdit.Text = "EDIT MUSIC CUES"; + buttonEdit.Visible = true; + break; + + case PckAssetType.ColourTableFile when asset.Filename == "colours.col": + buttonEdit.Text = "EDIT COLORS"; + buttonEdit.Visible = true; + break; + + case PckAssetType.BehavioursFile when asset.Filename == "behaviours.bin": + buttonEdit.Text = "EDIT BEHAVIOURS"; + buttonEdit.Visible = true; + break; + default: + buttonEdit.Visible = false; + break; + } + } + + private void treeViewMain_DoubleClick(object sender, EventArgs e) + { + if (treeViewMain.SelectedNode is TreeNode t && t.Tag is PckAsset asset) + { + if (asset.Size <= 0) + { + Trace.WriteLine($"'{asset.Filename}' has no data attached.", category: nameof(treeViewMain_DoubleClick)); + return; + } + _pckAssetTypeHandler[asset.Type]?.Invoke(asset); + } + } + + // Most of the code below is modified code from this link: + // https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.treeview.itemdrag?view=windowsdesktop-6.0 + // - MattNL + + private void treeViewMain_ItemDrag(object sender, ItemDragEventArgs e) + { + if (e.Button != MouseButtons.Left || e.Item is not TreeNode node) + return; + + if ((node.TryGetTagData(out PckAsset asset) && EditorValue.File.Contains(asset.Filename, asset.Type)) || node.Parent is TreeNode) + { + // TODO: add (mouse) scrolling while dragging item(s) + treeViewMain.DoDragDrop(node, DragDropEffects.Scroll | DragDropEffects.Move); + } + } + + private void treeViewMain_DragOver(object sender, DragEventArgs e) + { + Point dragLocation = new Point(e.X, e.Y); + TreeNode node = treeViewMain.GetNodeAt(treeViewMain.PointToClient(dragLocation)); + treeViewMain.SelectedNode = node.IsTagOfType() ? null : node; + } + + private void treeViewMain_DragEnter(object sender, DragEventArgs e) + { + e.Effect = e.Data.GetDataPresent(DataFormats.FileDrop) ? DragDropEffects.Copy : e.AllowedEffect; + BringToFront(); + Focus(); + treeViewMain.Focus(); + } + + private void treeViewMain_DragDrop(object sender, DragEventArgs e) + { + // Retrieve the client coordinates of the drop location. + Point dragLocation = new Point(e.X, e.Y); + Point targetPoint = treeViewMain.PointToClient(dragLocation); + + if (!treeViewMain.ClientRectangle.Contains(targetPoint)) + return; + + // Retrieve the node at the drop location. + TreeNode targetNode = treeViewMain.GetNodeAt(targetPoint); + + if (e.Data.GetDataPresent(DataFormats.FileDrop) && e.Data.GetData(DataFormats.FileDrop) is string[] filesDropped) + { + IEnumerable files = filesDropped.Where(File.Exists); + IEnumerable directoryFiles = filesDropped + .Where(f => (File.GetAttributes(f) & FileAttributes.Directory) != 0) + .SelectMany(dir => Directory.GetFiles(dir, "*.*", SearchOption.AllDirectories)); + + string baseDirectory = Path.GetDirectoryName(filesDropped.First()); + + IEnumerable importPaths = files.Concat(directoryFiles); + + ImportFiles(baseDirectory, importPaths, string.IsNullOrWhiteSpace(targetNode?.FullPath) ? string.Empty : targetNode?.FullPath); + return; + } + + string dataFormat = typeof(TreeNode).FullName; + + if (targetNode is null) + return; + + if (!e.Data.GetDataPresent(dataFormat)) + return; + + bool isTargetPckFile = targetNode.IsTagOfType(); + TreeNode draggedNode = e.Data.GetData(dataFormat) as TreeNode; + if (draggedNode == null) + { + Debug.WriteLine("Dragged node is null."); + return; + } + + if (targetNode.Equals(draggedNode)) + { + Debug.WriteLine("Dragged node was not moved."); + return; + } + + if (targetNode.Equals(draggedNode.Parent)) + { + Debug.WriteLine("target node is parent of dragged node... nothing done."); + return; + } + + if (draggedNode.Equals(targetNode.Parent)) + { + Debug.WriteLine("dragged node is parent of target node... nothing done."); + return; + } + + if (targetNode.Parent == null && isTargetPckFile && draggedNode.Parent == null) + { + Debug.WriteLine("target node is file and is in the root... nothing done."); + return; + } + + if ((targetNode.Parent?.Equals(draggedNode.Parent) ?? false) && isTargetPckFile) + { + Debug.WriteLine("target node and dragged node have the same parent... nothing done."); + return; + } + + Debug.WriteLine($"Target drop location is {(isTargetPckFile ? "file" : "folder")}."); + + // Retrieve the node that was dragged. + if (draggedNode.TryGetTagData(out PckAsset draggedAsset) && + targetNode.FullPath != draggedAsset.Filename) + { + Debug.WriteLine(draggedAsset.Filename + " was droped onto " + targetNode.FullPath); + string newFilePath = Path.Combine(isTargetPckFile + ? Path.GetDirectoryName(targetNode.FullPath) + : targetNode.FullPath, Path.GetFileName(draggedAsset.Filename)); + Debug.WriteLine("New filepath: " + newFilePath); + draggedAsset.Filename = newFilePath; + _wasModified = true; + BuildMainTreeView(); + return; + } + else + { + IEnumerable pckFiles = GetAllChildNodes(draggedNode.Nodes).Where(t => t.IsTagOfType()).Select(t => t.Tag as PckAsset); + string oldPath = draggedNode.FullPath; + string newPath = Path.Combine(isTargetPckFile ? Path.GetDirectoryName(targetNode.FullPath) : targetNode.FullPath, draggedNode.Text).Replace('\\', '/'); + foreach (PckAsset pckFile in pckFiles) + { + pckFile.Filename = Path.Combine(newPath, pckFile.Filename.Substring(oldPath.Length + 1)).Replace('\\', '/'); + } + _wasModified = true; + BuildMainTreeView(); + } + } + + private void ImportFiles(string baseDirectory, IEnumerable files, string prefix) + { + int fileCount = files.Count(); + int addedCount = 0; + int skippedFiles = 0; + int skipAttempts = 3; + int typeDuplication = 0; + PckAssetType lastSelectedAssetType = PckAssetType.SkinFile; + bool askForAssetType = true; + foreach (var filepath in files) + { + string assetPath = Path.Combine(prefix + filepath.Substring(baseDirectory.Length)).TrimStart('/', '\\'); + PckAssetType assetType = lastSelectedAssetType; + + if (askForAssetType) + { + using AddFilePrompt addFile = new AddFilePrompt(assetPath); + if (addFile.ShowDialog(this) != DialogResult.OK) + { + skippedFiles++; + skipAttempts--; + if (skipAttempts > 0) + continue; + + int remainingFileCount = fileCount - addedCount - skippedFiles; + DialogResult abortFurtherImport = MessageBox.Show($"Do you wan't to abort further file imports?\n{remainingFileCount} file(s) left.", "Abort further import", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); + if (abortFurtherImport == DialogResult.Yes) + { + skippedFiles += remainingFileCount; + break; + } + skipAttempts = 3; + continue; + } + + assetType = addFile.Filetype; + assetPath = addFile.Filepath; + + if (lastSelectedAssetType == assetType) + typeDuplication++; + lastSelectedAssetType = addFile.Filetype; + if (typeDuplication > 1) + { + DialogResult useSameTypeForRest = MessageBox.Show($"Do you want to import all remaining files as {lastSelectedAssetType}?", "Import all as", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); + if (useSameTypeForRest == DialogResult.Yes) + { + askForAssetType = false; + } + } + } + + if (EditorValue.File.Contains(filepath, assetType)) + { + if (askForAssetType) + MessageBox.Show(this, $"'{assetPath}' of type {assetType} already exists.\nSkiping file.", "File already exists", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1); + Debug.WriteLine($"'{assetPath}' of type {assetType} already exists.\nSkiping file."); + continue; + } + PckAsset importedAsset = EditorValue.File.CreateNewAsset(assetPath, assetType, () => File.ReadAllBytes(filepath)); + string propertyFile = filepath + ".txt"; + if (File.Exists(propertyFile)) + { + importedAsset.DeserializeProperties(File.ReadAllLines(propertyFile)); + } + addedCount++; + } + Trace.TraceInformation("[{0}] Imported {1} file(s).", nameof(ImportFiles), addedCount); + Trace.TraceInformation("[{0}] Skipped {1} file(s).", nameof(ImportFiles), skippedFiles); + if (addedCount > 0) + { + _wasModified = true; + BuildMainTreeView(); + } + } + + private IEnumerable GetEndingNodes(TreeNodeCollection collection) + { + List trailingNodes = new List(collection.Count); + foreach (TreeNode node in collection) + { + if (node.Nodes.Count > 0) + { + trailingNodes.AddRange(GetEndingNodes(node.Nodes)); + continue; + } + trailingNodes.Add(node); + } + return trailingNodes; + } + + private void ImportFiles(string[] files) + { + int addedCount = 0; + foreach (var file in files) + { + using AddFilePrompt addFile = new AddFilePrompt(Path.GetFileName(file)); + if (addFile.ShowDialog(this) != DialogResult.OK) + continue; + + if (EditorValue.File.Contains(addFile.Filepath, addFile.Filetype)) + { + MessageBox.Show(this, $"'{addFile.Filepath}' of type {addFile.Filetype} already exists.", "Import failed", MessageBoxButtons.OK, MessageBoxIcon.Warning); + continue; + } + EditorValue.File.CreateNewAsset(addFile.Filepath, addFile.Filetype, () => File.ReadAllBytes(file)); + addedCount++; + + BuildMainTreeView(); + _wasModified = true; + } + Trace.TraceInformation("[{0}] Imported {1} file(s).", nameof(ImportFiles), addedCount); + } + + private void createSkinToolStripMenuItem_Click(object sender, EventArgs e) + { + using (AddSkinPrompt addNewSkinDialog = new AddSkinPrompt()) + if (addNewSkinDialog.ShowDialog() == DialogResult.OK) + { + TryGetLocFile(out LOCFile locFile); + PckAsset skinAsset = addNewSkinDialog.NewSkin.CreateFile(locFile); + EditorValue.File.AddAsset(skinAsset); + + bool hasSkinsFolder = treeViewMain.Nodes.ContainsKey("Skins"); + if (hasSkinsFolder) + skinAsset.Filename = skinAsset.Filename.Insert(0, "Skins/"); // Then Skins folder + EditorValue.File.AddAsset(skinAsset); + + if (addNewSkinDialog.NewSkin.HasCape) + { + PckAsset capeFile = addNewSkinDialog.NewSkin.CreateCapeFile(); + if (hasSkinsFolder) + capeFile.Filename = capeFile.Filename.Insert(0, "Skins/"); // Then Skins folder + EditorValue.File.AddAsset(capeFile); + } + + TrySetLocFile(locFile); + _wasModified = true; + BuildMainTreeView(); + } + } + + private void createAnimatedTextureToolStripMenuItem_Click(object sender, EventArgs e) + { + using ChangeTile diag = new ChangeTile(); + if (diag.ShowDialog(this) != DialogResult.OK) + return; + + string animationFilepath = $"{ResourceLocation.GetPathFromCategory(diag.Category)}/{diag.SelectedTile.InternalName}.png"; + + if (EditorValue.File.Contains(animationFilepath, PckAssetType.TextureFile)) + { + MessageBox.Show(this, $"{diag.SelectedTile.DisplayName} is already present.", "File already present"); + return; + } + + Animation newAnimation = default; + ISaveContext saveContext = new DelegatedSaveContext(Settings.Default.AutoSaveChanges, (animation) => + { + newAnimation = animation; + }); + + using AnimationEditor animationEditor = new AnimationEditor(Animation.CreateEmpty(), saveContext, diag.SelectedTile.DisplayName, !diag.SelectedTile.InternalName.EqualsAny("clock", "compass")); + if (animationEditor.ShowDialog() == DialogResult.OK && newAnimation is not null) + { + _wasModified = true; + PckAsset asset = EditorValue.File.CreateNewAsset(animationFilepath, PckAssetType.TextureFile); + asset.SetSerializedData(newAnimation, AnimationSerializer.DefaultSerializer); + BuildMainTreeView(); + ReloadMetaTreeView(); + } + } + + private void audiopckToolStripMenuItem_Click(object sender, EventArgs e) + { + if (EditorValue.File.Contains(PckAssetType.AudioFile)) + { + // the chance of this happening is really really slim but just in case + MessageBox.Show(this, "There is already an audio file in this PCK!", "Can't create audio.pck"); + return; + } + + if (string.IsNullOrEmpty(_location)) + { + MessageBox.Show(this, "You must save your pck before creating or opening a music cues PCK file", "Can't create audio.pck"); + return; + } + + PckAudioFile newAudioFile = CreateNewAudioFile(); + PckAsset newAudioAsset = CreateNewAudioAsset(LittleEndianCheckBox.Checked, newAudioFile); + + ISaveContext saveContext = new DelegatedSaveContext(Settings.Default.AutoSaveChanges, (audioFile) => + { + newAudioAsset.SetData(new PckAudioFileWriter(audioFile, LittleEndianCheckBox.Checked ? OMI.ByteOrder.LittleEndian : OMI.ByteOrder.BigEndian)); + }); + + AudioEditor diag = new AudioEditor(newAudioFile, saveContext); + if (diag.ShowDialog(this) == DialogResult.OK) + { + EditorValue.File.AddAsset(newAudioAsset); + } + diag.Dispose(); + BuildMainTreeView(); + } + + private void colourscolToolStripMenuItem_Click(object sender, EventArgs e) + { + if (EditorValue.File.TryGetAsset("colours.col", PckAssetType.ColourTableFile, out _)) + { + MessageBox.Show(this, "A color table file already exists in this PCK and a new one cannot be created.", "Operation aborted"); + return; + } + PckAsset newColorAsset = EditorValue.File.CreateNewAsset("colours.col", PckAssetType.ColourTableFile); + newColorAsset.SetData(Resources.tu69colours); + BuildMainTreeView(); + } + + private void CreateSkinsPCKToolStripMenuItem1_Click(object sender, EventArgs e) + { + if (EditorValue.File.TryGetAsset("Skins.pck", PckAssetType.SkinDataFile, out _)) + { + MessageBox.Show(this, "A Skins.pck file already exists in this PCK and a new one cannot be created.", "Operation aborted"); + return; + } + + EditorValue.File.CreateNewAsset("Skins.pck", PckAssetType.SkinDataFile, new PckFileWriter(new PckFile(3, true), + LittleEndianCheckBox.Checked ? OMI.ByteOrder.LittleEndian : OMI.ByteOrder.BigEndian)); + + BuildMainTreeView(); + } + + private void behavioursbinToolStripMenuItem_Click(object sender, EventArgs e) + { + if (EditorValue.File.TryGetAsset("behaviours.bin", PckAssetType.BehavioursFile, out _)) + { + MessageBox.Show(this, "A behaviours file already exists in this PCK and a new one cannot be created.", "Operation aborted"); + return; + } + + EditorValue.File.CreateNewAsset("behaviours.bin", PckAssetType.BehavioursFile, new BehavioursWriter(new BehaviourFile())); + BuildMainTreeView(); + } + + private void entityMaterialsbinToolStripMenuItem_Click(object sender, EventArgs e) + { + if (EditorValue.File.TryGetAsset("entityMaterials.bin", PckAssetType.MaterialFile, out _)) + { + MessageBox.Show(this, "A behaviours file already exists in this PCK and a new one cannot be created.", "Operation aborted"); + return; + } + var materialContainer = new MaterialContainer(); + materialContainer.InitializeDefault(); + EditorValue.File.CreateNewAsset("entityMaterials.bin", PckAssetType.MaterialFile, new MaterialFileWriter(materialContainer)); + BuildMainTreeView(); + } + + [Obsolete("Refactor or remove this")] + private void importExtractedSkinsFolder(object sender, EventArgs e) + { + OpenFolderDialog contents = new OpenFolderDialog(); + if (contents.ShowDialog(Handle) == true) + { + //checks to make sure selected path exist + if (!Directory.Exists(contents.ResultPath)) + { + MessageBox.Show("Directory Lost"); + return; + } + // creates variable to indicate wether current pck skin structure is mashup or regular skin + bool hasSkinsPck = EditorValue.File.HasAsset("Skins.pck", PckAssetType.SkinDataFile); + + foreach (var fullfilename in Directory.GetFiles(contents.ResultPath, "*.png")) + { + string filename = Path.GetFileNameWithoutExtension(fullfilename); + // sets file type based on wether its a cape or skin + PckAssetType pckfiletype = filename.StartsWith("dlccape", StringComparison.OrdinalIgnoreCase) + ? PckAssetType.CapeFile + : PckAssetType.SkinFile; + string pckfilepath = (hasSkinsPck ? "Skins/" : string.Empty) + filename + ".png"; + + + PckAsset newFile = new PckAsset(pckfilepath, pckfiletype); + byte[] filedata = File.ReadAllBytes(fullfilename); + newFile.SetData(filedata); + + if (File.Exists(fullfilename + ".txt")) + { + string[] properties = File.ReadAllText(fullfilename + ".txt").Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); + foreach (string property in properties) + { + string[] param = property.Split(':'); + if (param.Length < 2) + continue; + newFile.AddProperty(param[0], param[1]); + //switch (param[0]) + //{ + // case "DISPLAYNAMEID": + // locNameId = param[1]; + // continue; + + // case "DISPLAYNAME": + // locName = param[1]; + // continue; + + // case "THEMENAMEID": + // locThemeId = param[1]; + // continue; + + // case "THEMENAME": + // locTheme = param[1]; + // continue; + //} + } + } + if (hasSkinsPck) + { + PckAsset skinsFileAsset = EditorValue.File.GetAsset("Skins.pck", PckAssetType.SkinDataFile); + using (var ms = new MemoryStream(skinsFileAsset.Data)) + { + //var reader = new PckFileReader(LittleEndianCheckBox.Checked ? OMI.Endianness.LittleEndian : OMI.Endianness.BigEndian); + //var skinspck = reader.FromStream(ms); + //skinspck.Files.Add(newFile); + //ms.Position = 0; + //var writer = new PckFileWriter(skinspck, LittleEndianCheckBox.Checked ? OMI.Endianness.LittleEndian : OMI.Endianness.BigEndian); + //writer.WriteToStream(ms); + //skinsfile.SetData(ms.ToArray()); + } + continue; + } + EditorValue.File.AddAsset(newFile); + } + BuildMainTreeView(); + _wasModified = true; + } + } + + private void as3DSTextureFileToolStripMenuItem_Click(object sender, EventArgs e) + { + if (treeViewMain.SelectedNode.TryGetTagData(out PckAsset asset) && + asset.Type == PckAssetType.SkinFile) + { + SaveFileDialog saveFileDialog = new SaveFileDialog(); + saveFileDialog.Filter = "3DS Texture|*.3dst"; + saveFileDialog.DefaultExt = ".3dst"; + if (saveFileDialog.ShowDialog(this) == DialogResult.OK) + { + Image img = asset.GetTexture(); + var writer = new _3DSTextureWriter(img); + writer.WriteToFile(saveFileDialog.FileName); + } + } + } + + private void generateMipMapTextureToolStripMenuItem_Click(object sender, EventArgs e) + { + if (treeViewMain.SelectedNode.Tag is PckAsset asset && asset.Type == PckAssetType.TextureFile) + { + string textureDirectory = Path.GetDirectoryName(asset.Filename); + string textureName = Path.GetFileNameWithoutExtension(asset.Filename); + + if (asset.IsMipmappedFile()) + return; + + string textureExtension = Path.GetExtension(asset.Filename); + + using NumericPrompt numericPrompt = new NumericPrompt(0); + numericPrompt.Minimum = 1; + numericPrompt.Maximum = 4; // 5 is the presumed max MipMap level + numericPrompt.ToolTipText = "You can enter the amount of MipMap levels that you would like to generate. " + + "For example: if you enter 2, MipMapLevel1.png and MipMapLevel2.png will be generated"; + numericPrompt.TextLabel.Text = "Levels"; + + if (numericPrompt.ShowDialog(this) == DialogResult.OK) + { + for (int i = 2; i < 2 + numericPrompt.SelectedValueAsInt; i++) + { + string mippedPath = $"{textureDirectory}/{textureName}MipMapLevel{i}{textureExtension}"; + Debug.WriteLine(mippedPath); + if (EditorValue.File.HasAsset(mippedPath, PckAssetType.TextureFile)) + EditorValue.File.RemoveAsset(EditorValue.File.GetAsset(mippedPath, PckAssetType.TextureFile)); + PckAsset mipMappedAsset = new PckAsset(mippedPath, PckAssetType.TextureFile); + + Image originalTexture = asset.GetTexture(); + int newWidth = Math.Max(originalTexture.Width / (int)Math.Pow(2, i - 1), 1); + int newHeight = Math.Max(originalTexture.Height / (int)Math.Pow(2, i - 1), 1); + + Rectangle tileArea = new Rectangle(0, 0, newWidth, newHeight); + Image mippedTexture = new Bitmap(newWidth, newHeight); + using (Graphics gfx = Graphics.FromImage(mippedTexture)) + { + gfx.SmoothingMode = SmoothingMode.None; + gfx.InterpolationMode = InterpolationMode.NearestNeighbor; + gfx.PixelOffsetMode = PixelOffsetMode.HighQuality; + gfx.DrawImage(originalTexture, tileArea); + } + + mipMappedAsset.SetTexture(mippedTexture); + + EditorValue.File.InsertAsset(EditorValue.File.IndexOfAsset(asset) + i - 1, mipMappedAsset); + } + BuildMainTreeView(); + } + } + } + + private void viewFileInfoToolStripMenuItem_Click(object sender, EventArgs e) + { + if (treeViewMain.SelectedNode.Tag is PckAsset asset) + { + MessageBox.Show( + $"Asset path: {asset.Filename}" + + $"\nAsset type: {(int)asset.Type} ({asset.Type})" + + $"\nAsset size: {asset.Size}" + + $"\nProperties count: {asset.PropertyCount}" + , Path.GetFileName(asset.Filename) + " Asset info"); + } + } + + private void correctSkinDecimalsToolStripMenuItem_Click(object sender, EventArgs e) + { + if (treeViewMain.SelectedNode.TryGetTagData(out PckAsset asset) && + asset.Type == PckAssetType.SkinFile) + { + foreach (KeyValuePair p in asset.GetProperties().ToList()) + { + if (p.Key == "BOX" || p.Key == "OFFSET") + asset.SetProperty(asset.GetPropertyIndex(p), new KeyValuePair(p.Key, p.Value.Replace(',', '.'))); + } + ReloadMetaTreeView(); + _wasModified = true; + } + } + + private void extractToolStripMenuItem_Click(object sender, EventArgs e) + { + TreeNode node = treeViewMain.SelectedNode; + + if (node == null) + { + MessageBox.Show(this, "The selected node was null. Please select a node and try again.", "Node not extracted"); + + return; + } + + if (node.Tag == null) + { + OpenFolderDialog dialog = new OpenFolderDialog(); + dialog.Title = @"Select destination folder"; + + if (dialog.ShowDialog(Handle) == true) + extractFolder(dialog.ResultPath); + } + else if (node.TryGetTagData(out PckAsset asset)) + { + using SaveFileDialog exFile = new SaveFileDialog(); + exFile.FileName = Path.GetFileName(asset.Filename); + exFile.Filter = Path.GetExtension(asset.Filename).Replace(".", string.Empty) + " File|*" + Path.GetExtension(asset.Filename); + if (exFile.ShowDialog(this) != DialogResult.OK || + // Makes sure chosen directory isn't null or whitespace AKA makes sure its usable + string.IsNullOrWhiteSpace(Path.GetDirectoryName(exFile.FileName))) + { + MessageBox.Show(this, "The chosen directory is invalid. Please choose a different one and try again.", "Node not extracted"); + + return; + } + + extractFile(exFile.FileName, asset); + } + + // Verification that file extraction path was successful + MessageBox.Show(this, $"\"{node.Text}\" successfully extracted"); + } + + private void extractFolder(string outPath) + { + TreeNode node = treeViewMain.SelectedNode; + + string selectedFolder = node.FullPath; + + foreach (PckAsset asset in EditorValue.File.GetAssets().Where(asset => asset.Filename.StartsWith(selectedFolder))) + { + extractFolderFile(outPath, asset); + } + } + + private void extractFolderFile(string outPath, PckAsset asset) + { + TreeNode node = treeViewMain.SelectedNode; + + // abb = "Abbreviated Path" + string abbPath = Path.GetDirectoryName(asset.Filename); + int startIndex = abbPath.IndexOf(node.Text); + abbPath = abbPath.Substring(startIndex, abbPath.Length - startIndex); + string finalPath = ($"{outPath}/{abbPath}/").Replace('\\', '/'); + + if (!Directory.Exists(finalPath)) + Directory.CreateDirectory(finalPath); + + extractFile(finalPath + "/" + Path.GetFileName(asset.Filename), asset); + } + + private void extractFile(string outFilePath, PckAsset asset) + { + File.WriteAllBytes(outFilePath, asset.Data); + if (asset.PropertyCount > 0) + { + File.WriteAllLines($"{outFilePath}.txt", asset.SerializeProperties()); + } + } + + private void cloneFileToolStripMenuItem_Click(object sender, EventArgs e) + { + TreeNode node = treeViewMain.SelectedNode; + if (node == null || !node.IsTagOfType()) + return; + string path = node.FullPath; + + using TextPrompt diag = new TextPrompt(node.Tag is null ? Path.GetFileName(node.FullPath) : node.FullPath); + diag.contextLabel.Text = $"Creating a clone of \"{path}\". Ensure that the path isn't yet."; + diag.OKButtonText = "Clone"; + + if (diag.ShowDialog(this) == DialogResult.OK) + { + if (node.Tag is PckAsset asset) + { + TreeNode newNode = new TreeNode(); + newNode.Text = Path.GetFileName(diag.NewText); + var newFile = new PckAsset(diag.NewText, asset.Type); + foreach (KeyValuePair property in asset.GetProperties()) + { + newFile.AddProperty(property); + } + newFile.SetData(asset.Data); + newFile.Filename = diag.NewText; + newNode.Tag = newFile; + newNode.ImageIndex = node.ImageIndex; + newNode.SelectedImageIndex = node.SelectedImageIndex; + + if (GetAllChildNodes(treeViewMain.Nodes).FirstOrDefault(n => n.FullPath == diag.NewText) is not null) + { + MessageBox.Show( + this, + $"A file with the path \"{diag.NewText}\" already exists. " + + $"Please try again with a different name.", + "Key already exists"); + return; + } + + TreeNodeCollection nodeCollection = node.Parent?.Nodes ?? treeViewMain.Nodes; + nodeCollection.Insert(node.Index + 1, newNode); + + EditorValue.File.InsertAsset(node.Index + 1, newFile); + BuildMainTreeView(); + _wasModified = true; + } + } + } + + private void renameFileToolStripMenuItem_Click(object sender, EventArgs e) + { + TreeNode node = treeViewMain.SelectedNode; + if (node == null) + return; + string path = node.FullPath; + + bool isFile = node.TryGetTagData(out PckAsset asset); + + using TextPrompt diag = new TextPrompt(isFile ? asset.Filename : Path.GetFileName(node.FullPath)); + + if (diag.ShowDialog(this) == DialogResult.OK) + { + if (isFile) + { + if (EditorValue.File.Contains(diag.NewText, asset.Type)) + { + MessageBox.Show(this, $"{diag.NewText} already exists", "File already exists"); + return; + } + asset.Filename = diag.NewText; + } + else // folders + { + node.Text = diag.NewText; + foreach (TreeNode childNode in GetAllChildNodes(node.Nodes)) + { + if (childNode.Tag is PckAsset folderAsset) + { + if (folderAsset.Filename == diag.NewText) + continue; + folderAsset.Filename = childNode.FullPath; + } + } + } + _wasModified = true; + BuildMainTreeView(); + } + } + + private void replaceToolStripMenuItem_Click(object sender, EventArgs e) + { + if (treeViewMain.SelectedNode.Tag is PckAsset asset) + { + using var ofd = new OpenFileDialog(); + // Suddenly, and randomly, this started throwing an exception because it wasn't formatted correctly? So now it's formatted correctly and now displays the file type name in the dialog. + + string extra_extensions = ""; + + switch (asset.Type) + { + case PckAssetType.TextureFile: + if (Path.GetExtension(asset.Filename) == ".png") + extra_extensions = ";*.tga"; + else if (Path.GetExtension(asset.Filename) == ".tga") + extra_extensions = ";*.png"; + break; + } + + string fileExt = Path.GetExtension(asset.Filename); + + ofd.Filter = $"{asset.Type} (*{fileExt}{extra_extensions})|*{fileExt}{extra_extensions}"; + if (ofd.ShowDialog(this) == DialogResult.OK) + { + string newFileExt = Path.GetExtension(ofd.FileName); + asset.SetData(File.ReadAllBytes(ofd.FileName)); + asset.Filename = asset.Filename.Replace(fileExt, newFileExt); + _wasModified = true; + BuildMainTreeView(); + } + return; + } + MessageBox.Show(this, "Can't replace a folder."); + } + + /// + /// Action to run before an asset will be deleted + /// + /// Asset to remove + /// True if the remove should be canceled, otherwise False + private bool BeforeFileRemove(PckAsset asset) + { + string itemPath = ResourceLocation.GetPathFromCategory(ResourceCategory.ItemAnimation); + + // warn the user about deleting compass.png and clock.png + if (asset.Type == PckAssetType.TextureFile && + (asset.Filename == itemPath + "/compass.png" || asset.Filename == itemPath + "/clock.png")) + { + if (MessageBox.Show(this, "Are you sure want to delete this file? If \"compass.png\" or \"clock.png\" are missing, your game will crash upon loading this pack.", "Warning", + MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No) + return true; + } + + // remove loc key if its a skin/cape + if (asset.Type == PckAssetType.SkinFile || asset.Type == PckAssetType.CapeFile) + { + if (TryGetLocFile(out LOCFile locFile)) + { + if (asset.TryGetProperty("THEMENAMEID", out string value)) + locFile.RemoveLocKey(value); + if (asset.TryGetProperty("DISPLAYNAMEID", out value)) + locFile.RemoveLocKey(value); + TrySetLocFile(locFile); + } + } + return false; + } + + private void deleteFileToolStripMenuItem_Click(object sender, EventArgs e) + { + TreeNode node = treeViewMain.SelectedNode; + if (node == null) + return; + + string path = node.FullPath; + + if (node.TryGetTagData(out PckAsset asset)) + { + if (!BeforeFileRemove(asset) && EditorValue.File.RemoveAsset(asset)) + { + node.Remove(); + _wasModified = true; + } + } + else if (MessageBox.Show(this, "Are you sure want to delete this folder? All contents will be deleted", "Warning", + MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) + { + string pckFolderDir = node.FullPath; + EditorValue.File.RemoveAll(file => file.Filename.StartsWith(pckFolderDir) && !BeforeFileRemove(file)); + node.Remove(); + _wasModified = true; + } + } + + private void treeMeta_AfterSelect(object sender, TreeViewEventArgs e) + { + if (e.Node is TreeNode t && t.Tag is KeyValuePair property) + { + entryTypeTextBox.Text = property.Key; + entryDataTextBox.Text = property.Value; + } + } + + private void treeViewMain_KeyDown(object sender, KeyEventArgs e) + { + switch (e.KeyCode) + { + case Keys.Delete: + deleteFileToolStripMenuItem_Click(sender, e); + break; + case Keys.F2: + renameFileToolStripMenuItem_Click(sender, e); + break; + } + } + + private void treeViewMain_BeforeLabelEdit(object sender, NodeLabelEditEventArgs e) + { + // for now name edits are done through the 'rename' context menu item + // TODO: add folder renaming + //e.CancelEdit = e.Node.Tag is PckAsset; + e.CancelEdit = true; + } + + private void editAllEntriesToolStripMenuItem_Click(object sender, EventArgs e) + { + if (treeViewMain.SelectedNode.TryGetTagData(out PckAsset asset)) + { + IEnumerable props = asset.SerializeProperties(seperater: " "); + using (var input = new MultiTextPrompt(props)) + { + if (input.ShowDialog(this) == DialogResult.OK) + { + asset.ClearProperties(); + asset.DeserializeProperties(input.TextOutput); + ReloadMetaTreeView(); + _wasModified = true; + } + } + } + } + + private void treeMeta_DoubleClick(object sender, EventArgs e) + { + if (treeMeta.SelectedNode is TreeNode subnode && subnode.Tag is KeyValuePair property && + treeViewMain.SelectedNode is TreeNode node && node.Tag is PckAsset asset) + { + if (asset.HasProperty(property.Key)) + { + switch (property.Key) + { + case "ANIM" when asset.Type == PckAssetType.SkinFile: + try + { + using ANIMEditor diag = new ANIMEditor(SkinANIM.FromString(property.Value)); + if (diag.ShowDialog(this) == DialogResult.OK) + { + asset.SetProperty(asset.GetPropertyIndex(property), new KeyValuePair("ANIM", diag.ResultAnim.ToString())); + ReloadMetaTreeView(); + _wasModified = true; + } + return; + } + catch (Exception ex) + { + Debug.WriteLine(ex.Message); + Trace.WriteLine("Invalid ANIM value: " + property.Value); + MessageBox.Show(this, "Failed to parse ANIM value, aborting to normal functionality. Please make sure the value only includes hexadecimal characters (0-9,A-F) and has no more than 8 characters."); + } + break; + + case "BOX" when asset.Type == PckAssetType.SkinFile: + try + { + using BoxEditor diag = new BoxEditor(property.Value, false); + if (diag.ShowDialog(this) == DialogResult.OK) + { + asset.SetProperty(asset.GetPropertyIndex(property), new KeyValuePair("BOX", diag.Result.ToString())); + ReloadMetaTreeView(); + _wasModified = true; + } + return; + } + catch (Exception ex) + { + Debug.WriteLine(ex.Message); + Trace.WriteLine("Invalid BOX value: " + property.Value); + MessageBox.Show(this, "Failed to parse BOX value, aborting to normal functionality."); + } + break; + + default: + break; + + } + + using (AddPropertyPrompt addProperty = new AddPropertyPrompt(property)) + { + if (addProperty.ShowDialog(this) == DialogResult.OK) + { + asset.SetProperty(asset.GetPropertyIndex(property), addProperty.Property); + ReloadMetaTreeView(); + _wasModified = true; + } + } + } + } + } + + private void treeMeta_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyData == Keys.Delete) + deleteEntryToolStripMenuItem_Click(sender, e); + } + + private void addMultipleEntriesToolStripMenuItem1_Click(object sender, EventArgs e) + { + if (treeViewMain.SelectedNode.TryGetTagData(out PckAsset asset)) + { + using var input = new MultiTextPrompt(); + if (input.ShowDialog(this) == DialogResult.OK) + { + asset.DeserializeProperties(input.TextOutput); + ReloadMetaTreeView(); + _wasModified = true; + } + } + } + + private void addBOXEntryToolStripMenuItem1_Click(object sender, EventArgs e) + { + if (treeViewMain.SelectedNode is TreeNode t && t.Tag is PckAsset asset) + { + using BoxEditor diag = new BoxEditor(SkinBOX.DefaultHead, false); + if (diag.ShowDialog(this) == DialogResult.OK) + { + asset.AddProperty("BOX", diag.Result); + ReloadMetaTreeView(); + _wasModified = true; + } + return; + } + } + + private void addANIMEntryToolStripMenuItem1_Click(object sender, EventArgs e) + { + if (treeViewMain.SelectedNode.TryGetTagData(out PckAsset asset)) + { + using ANIMEditor diag = new ANIMEditor(SkinANIM.Empty); + if (diag.ShowDialog(this) == DialogResult.OK) + { + asset.AddProperty("ANIM", diag.ResultAnim); + ReloadMetaTreeView(); + _wasModified = true; + } + return; + } + } + + private void deleteEntryToolStripMenuItem_Click(object sender, EventArgs e) + { + if (treeMeta.SelectedNode is TreeNode t && t.Tag is KeyValuePair property && + treeViewMain.SelectedNode is TreeNode main && main.Tag is PckAsset asset && + asset.RemoveProperty(property)) + { + treeMeta.SelectedNode.Remove(); + _wasModified = true; + } + } + + private void addEntryToolStripMenuItem_Click(object sender, EventArgs e) + { + if (treeViewMain.SelectedNode is TreeNode t && + t.Tag is PckAsset asset) + { + using AddPropertyPrompt addProperty = new AddPropertyPrompt(); + if (addProperty.ShowDialog(this) == DialogResult.OK) + { + asset.AddProperty(addProperty.Property); + ReloadMetaTreeView(); + _wasModified = true; + } + } + } + + private static bool TryGetDefaultEntityModel(string modelName, out Model model) + { + if (!GameModelImporter.DefaultModels.TryGetValue(modelName, out DefaultModel defaultModel) || defaultModel is null) + { + model = default; + return false; + } + model = new Model(modelName, new Size((int)defaultModel.TextureSize.X, (int)defaultModel.TextureSize.Y)); + + foreach (DefaultPart defaultPart in defaultModel.Parts) + { + ModelPart modelPart = new ModelPart(defaultPart.Name, "", defaultPart.Translation, defaultPart.Rotation, System.Numerics.Vector3.Zero); + modelPart.AddBoxes(defaultPart.Boxes.Select(defaultBox => new ModelBox(defaultBox.Position, defaultBox.Size, defaultBox.Uv, defaultBox.Inflate, defaultBox.Mirror))); + model.AddPart(modelPart); + } + + return true; + } + + private void ShowSimpleModelRender(Model model, NamedData modelTexture) + { + MetroForm form = new MetroForm(); + form.Icon = Resources.ProjectLogo; + form.Theme = MetroFramework.MetroThemeStyle.Dark; + form.Style = MetroFramework.MetroColorStyle.Silver; + form.StartPosition = FormStartPosition.CenterParent; + form.Text = $"{model.Name} - {modelTexture.Name}"; + form.Size = new Size(600, 500); + form.MinimumSize = new Size(300, 300); + + void ExportToolStripItem_Click(object sender, EventArgs e) + { + GameModelImporter.Default.ExportSettings.CreateModelOutline = + MessageBox.Show( + $"Do you wish to have all model parts contained in a group called '{model.Name}'?", + "Group model parts", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes; + + using SaveFileDialog openFileDialog = new SaveFileDialog(); + openFileDialog.FileName = model.Name; + openFileDialog.Filter = GameModelImporter.Default.SupportedModelFileFormatsFilter; + + if (openFileDialog.ShowDialog(this) == DialogResult.OK) + { + var modelInfo = new GameModelInfo(model, new NamedData[1] { modelTexture }); + GameModelImporter.Default.Export(openFileDialog.FileName, modelInfo); + } + } + ToolStripItem exportToolStripItem = new ToolStripButton("Export"); + exportToolStripItem.Click += ExportToolStripItem_Click; + + MenuStrip menu = new MenuStrip(); + menu.BackColor = Color.FromArgb(35, 35, 35); + menu.ForeColor = Color.WhiteSmoke; + menu.Anchor = AnchorStyles.Top; + menu.Dock = DockStyle.Top; + menu.Items.Add(exportToolStripItem); + + ModelRenderer renderer = new ModelRenderer(); + form.Controls.Add(menu); + form.Controls.Add(renderer); + + renderer.VSync = true; + renderer.BackColor = Color.FromArgb(30, 30, 30); + renderer.Dock = DockStyle.Fill; + renderer.Texture = modelTexture.Value; + renderer.LoadModel(model); + renderer.ResetCamera(); + + form.ShowDialog(this); + + renderer.Dispose(); + form.Dispose(); + } + + private void PckEditor_Load(object sender, EventArgs e) + { + CheckForPasswordAndRemove(); + BuildMainTreeView(); + UpdateRichPresence(); + } + + private void SetEndianess(OMI.ByteOrder endianness) + { + LittleEndianCheckBox.Checked = endianness == OMI.ByteOrder.LittleEndian; + } + + private OMI.ByteOrder GetEndianess() + { + return LittleEndianCheckBox.Checked ? OMI.ByteOrder.LittleEndian : OMI.ByteOrder.BigEndian; + } + + private void buttonEdit_Click(object sender, EventArgs e) + { + treeViewMain_DoubleClick(sender, e); + } + + private void SetPckEndianness(OMI.ByteOrder endianness) + { + try + { + if (treeViewMain.SelectedNode.Tag is PckAsset asset && (asset.Type is PckAssetType.AudioFile || asset.Type is PckAssetType.SkinDataFile || asset.Type is PckAssetType.TexturePackInfoFile)) + { + IDataFormatReader reader = asset.Type is PckAssetType.AudioFile + ? new PckAudioFileReader(endianness == OMI.ByteOrder.BigEndian ? OMI.ByteOrder.LittleEndian : OMI.ByteOrder.BigEndian) + : new PckFileReader(endianness == OMI.ByteOrder.BigEndian ? OMI.ByteOrder.LittleEndian : OMI.ByteOrder.BigEndian); + object pck = reader.FromStream(new MemoryStream(asset.Data)); + + IDataFormatWriter writer = asset.Type is PckAssetType.AudioFile + ? new PckAudioFileWriter((PckAudioFile)pck, endianness) + : new PckFileWriter((PckFile)pck, endianness); + asset.SetData(writer); + _wasModified = true; + MessageBox.Show($"\"{asset.Filename}\" successfully converted to {(endianness == OMI.ByteOrder.LittleEndian ? "little" : "big")} endian.", "Converted PCK file"); + } + } + catch (OverflowException) + { + MessageBox.Show(this, $"File was not a valid {(endianness != OMI.ByteOrder.LittleEndian ? "little" : "big")} endian PCK File.", "Not a valid PCK file"); + return; + } + catch (Exception ex) + { + MessageBox.Show(this, ex.Message, "Not a valid PCK file"); + return; + } + } + + private void littleEndianToolStripMenuItem_Click(object sender, EventArgs e) => SetPckEndianness(OMI.ByteOrder.LittleEndian); + + private void bigEndianToolStripMenuItem_Click(object sender, EventArgs e) => SetPckEndianness(OMI.ByteOrder.BigEndian); + + private void SetModelVersion(int version) + { + if (treeViewMain.SelectedNode.Tag is PckAsset asset && asset.Type is PckAssetType.ModelsFile) + { + try + { + ModelContainer container = asset.GetData(new ModelFileReader()); + + if (container.Version == version) + { + MessageBox.Show( + this, + $"This model container is already Version {version + 1}.", + "Can't convert", MessageBoxButtons.OK, MessageBoxIcon.Error + ); + return; + } + + if (version == 2 && + MessageBox.Show( + this, + "Conversion to 1.14 models.bin format does not yet support parent declaration and may not be 100% accurate.\n" + + "Would you like to continue?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes + ) + { + return; + } + + if (container.Version > 1 && + MessageBox.Show( + this, + "Conversion from 1.14 models.bin format does not yet support parent parts and may not be 100% accurate.\n" + + "Would you like to continue?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes + ) + { + return; + } + + asset.SetData(new ModelFileWriter(container, version)); + _wasModified = true; + MessageBox.Show( + this, + $"\"{asset.Filename}\" successfully converted to Version {version + 1} format.", + "Converted model container file" + ); + } + catch (Exception ex) + { + MessageBox.Show(this, ex.Message, "Not a valid model container file."); + return; + } + } + } + + private void setModelVersion1ToolStripMenuItem_Click(object sender, EventArgs e) => SetModelVersion(0); + + private void setModelVersion2ToolStripMenuItem_Click(object sender, EventArgs e) => SetModelVersion(1); + + private void setModelVersion3ToolStripMenuItem_Click(object sender, EventArgs e) => SetModelVersion(2); + + private void treeViewMain_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) + { + if (e.Node is not null) + treeViewMain.SelectedNode = e.Node; + } + + private void contextMenuPCKEntries_Opening(object sender, System.ComponentModel.CancelEventArgs e) + { + correctSkinDecimalsToolStripMenuItem.Visible = false; + generateMipMapTextureToolStripMenuItem1.Visible = false; + setModelContainerFormatToolStripMenuItem.Visible = false; + setSubPCKEndiannessToolStripMenuItem.Visible = false; + exportToolStripMenuItem.Visible = false; + toolStripSeparator5.Visible = false; + toolStripSeparator6.Visible = false; + if (treeViewMain?.SelectedNode.TryGetTagData(out PckAsset asset) ?? false) + { + replaceToolStripMenuItem.Visible = true; + cloneFileToolStripMenuItem.Visible = true; + setFileTypeToolStripMenuItem.Visible = true; + toolStripSeparator5.Visible = true; + toolStripSeparator6.Visible = true; + + if (asset.Type == PckAssetType.SkinFile) + { + correctSkinDecimalsToolStripMenuItem.Visible = true; + exportToolStripMenuItem.Visible = true; + } + if (asset.Type == PckAssetType.TextureFile) + generateMipMapTextureToolStripMenuItem1.Visible = true; + if (asset.Type == PckAssetType.ModelsFile) + setModelContainerFormatToolStripMenuItem.Visible = true; + if (asset.Type == PckAssetType.SkinDataFile || asset.Type == PckAssetType.TexturePackInfoFile || asset.Type == PckAssetType.AudioFile) + setSubPCKEndiannessToolStripMenuItem.Visible = true; + } + else + { + replaceToolStripMenuItem.Visible = false; + cloneFileToolStripMenuItem.Visible = false; + setFileTypeToolStripMenuItem.Visible = false; + } + } + } +} \ No newline at end of file diff --git a/PCK-Studio/Controls/PckEditor.resx b/PCK-Studio/Controls/PckEditor.resx new file mode 100644 index 00000000..5e94f7c7 --- /dev/null +++ b/PCK-Studio/Controls/PckEditor.resx @@ -0,0 +1,2097 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + + + 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 + 8+BMiU9xSj9GDDCHwDUcMkHMV8I4YKwwEz0K5TTDbjg/NnbZmEsvwcYuuVQYpxwTXCyU8g2YMaMA9NIJ + QlbKc/bsWePhf9yV868cRwU+9urlV49ddc3mO2PQDmDbQrL1wvZLH2n1jwL0m3S/9BN9i3ENH0E3I+Ij + 165ePWaFyYNijmQzbk6y88LG0GHSNcktA2RXAwTAVlDG8CCv2hKBdbzbZhRPJilXFq4wuuJh8dIlYxYs + Xjhm/sL5Y+fMgz7wYKfjL5ulHyRZNmWXbKCcX4CWVvpbgeTVFkhq0j+BAmI8iTTZBwWAzyt9dNH16gP/ + HXPlvCvGzJs7Tx9M/ohfjp/5M3zskkuJl5c2/SoAuyjtI8ULoND/ZfgWuhdK9G0bxdkYVm1j0OlYdErs + wq+Zk/kS3sJXSkjy8rMGok+SZSlXQL8z3hvLkn6JT+7OLKZwXrZ0KSvWFSNio/3Wb/3Wb/3Wb/3Wb/3W + b/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3W + b/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3W + b/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb/3Wb1uy/Yf/8P8D4rKD + rca4/zIAAAAASUVORK5CYII= + + + + + NoControl + + + 413, 0 + + + 190, 50 + + + Zoom + + + + 14 + + + logoPictureBox + + + System.Windows.Forms.PictureBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 10 + + + 8, 27 + + + 241, 23 + + + 2 + + + pckFileLabel + + + MetroFramework.Controls.MetroLabel, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a + + + $this + + + 4 + + + Top, Right + + + True + + + 1369, 252 + + + 30, 19 + + + 19 + + + aaa + + + labelImageSize + + + MetroFramework.Controls.MetroLabel, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a + + + $this + + + 5 + + + Top, Right + + + True + + + 1347, 53 + + + 0, 0 + + + 17 + + + fileEntryCountLabel + + + MetroFramework.Controls.MetroLabel, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a + + + $this + + + 6 + + + Bottom, Right + + + True + + + 204, 144 + + + 0, 0 + + + 15 + + + metroLabel2 + + + MetroFramework.Controls.MetroLabel, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a + + + MetaTab + + + 2 + + + Bottom, Right + + + + + + NoControl + + + 128, 2 + + + 15, 15 + + + 1 + + + False + + + False + + + 215, 114 + + + 146, 20 + + + 21 + + + entryTypeTextBox + + + MetroFramework.Controls.MetroTextBox, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a + + + MetaTab + + + 3 + + + Bottom, Right + + + + + + NoControl + + + 128, 2 + + + 15, 15 + + + 1 + + + False + + + False + + + 215, 146 + + + 146, 20 + + + 16 + + + entryDataTextBox + + + MetroFramework.Controls.MetroTextBox, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a + + + MetaTab + + + 4 + + + Bottom, Right + + + 215, 172 + + + 146, 33 + + + 20 + + + buttonEdit + + + False + + + buttonEdit + + + MetroFramework.Controls.MetroButton, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a + + + MetaTab + + + 5 + + + Bottom, Right + + + True + + + 266, 37 + + + 0, 0 + + + 13 + + + metroLabel1 + + + MetroFramework.Controls.MetroLabel, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a + + + MetaTab + + + 6 + + + 301, 19 + + + 160, 22 + + + Add Entry + + + 160, 22 + + + Add BOX Entry + + + 160, 22 + + + Add ANIM Entry + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMkMEa+wAAABSSURBVDhP5c0x + DsAgDENRxt7/wmkNSpRGf0CCCZAegxNMM7MlGMp3dIU6dxhKf/QMNxRogeQC8ivw5Vn7C0heJlFA+kL5 + jWAohxRkde4wnGftBS90axNmphIGAAAAAElFTkSuQmCC + + + + 181, 22 + + + Add Entry + + + 181, 22 + + + Add Multiple Entries + + + 181, 22 + + + Delete Entry + + + 181, 22 + + + Edit All Entries + + + 182, 92 + + + contextMenuMetaTree + + + System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Left + + + 5, 5 + + + 204, 229 + + + 0 + + + treeMeta + + + System.Windows.Forms.TreeView, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + MetaTab + + + 7 + + + 4, 38 + + + 5, 5, 5, 5 + + + 724, 239 + + + 0 + + + Properties + + + MetaTab + + + MetroFramework.Controls.MetroTabPage, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a + + + PropertiesTabControl + + + 0 + + + Bottom + + + 279, 270 + + + 732, 281 + + + 11 + + + PropertiesTabControl + + + MetroFramework.Controls.MetroTabControl, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a + + + $this + + + 7 + + + True + + + True + + + 433, 71 + + + 0, 0 + + + 3 + + + label11 + + + MetroFramework.Controls.MetroLabel, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a + + + $this + + + 8 + + + 22, 20 + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xOdTWsmQAAABVSURBVDhPYxgc + 4P8Chv8YeKWUIFSaMPi/W+r//1MapOGTOixQ7UADsCkgAkO1jywDRIGxA8JQPlQ7PQyAaUTDUO30MACG + YZqhfKh24gGGzYMAMDAAAPvHncAZVkkSAAAAAElFTkSuQmCC + + + + 172, 22 + + + Folder + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xOdTWsmQAAAIkSURBVDhPpdLf + T1JxGMfxc1n8qtzcyglCWhFS1PLGHAgisDmktZZtabRSEYhDZ8xpiSWVpaSxLpoXyWquLvzV+oGZq+iy + /6Stm7qsm+DT830YMJw3rbO9Djs7z/P+wob03xcAyWbUwqLXotWgha1pDzPr1axl/y52uEHFrAY1z4l5 + sVsK0IK1UVMbaKQAOXhgN2tuKLHQTKtBh6M0XwmIxe1OtexjXZa9pA6dlnomlgXx7WoCo/1eTF3pwfRQ + gM3HLmD+Wh8yIwE8CgcwFznLJs67cLPPgeMmXW1gKRXCZjqGfCbBvi6kWH6OnoXMKFsd68fa2CW0Haqr + BpYnh5G7F8PGtIyV2yG2NhXHeuo6nioD5CI+pRMsG+nFYqSHVQKrt0LYKAcmhyCeX6Vklk0MsI9phQIK + Bfy07OfPSkAs/v7xDcViEd6OZ/C2LyOXHMb75Agtlk72nF6hdy/FEgrFP3yI2OVA7r6MXz+/04siPB3P + aXgJ75JhbFIgP5PAZwr42lcp8IJnioUCBcLVQHbQizfjQTr1Kj7cTbBIpw1R54mK/GwMXwjqaYWkzrVV + A4uDPry+QYGJIN7eUVjMcQyyvWrrQRxbM/GdA4+Dbjy57MJC0AmnUQ2XUYPZXjse+qvKi9vRHZLisUJx + WyB3m0sBkwZuvYr56A8j7LQs0B2S7LMg2n0EUY8ZdpMaDgo4mlSsq1lXo7w4fuZk6Sf861U5mS9J+gsp + e+98+xbVEAAAAABJRU5ErkJggg== + + + + 172, 22 + + + Skin + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMkMEa+wAAAI/SURBVDhPjZHt + b9JQFMbvv6IRCiYmU+cGpQXH5oACMkZvgQILG2Su7e2mE3l1cTMricaXEQtscVN0UYIaB8MZmW/ZFxP/ + KrzNpCHxi0+eL/ec53fuSQ7IHLqyXW+uwwj7lLBvQweu9N6Y/M65/h3iOmpNLL2hxaYj1bAEnxhXPkyB + TNe9/H76YS96rzOz0Z3lSQI1banX1uTLMfVkYetnMt/2LTRGMq1rwlv7SssJHnyLcbRp77csvLLdaF1l + HabVg+mElVg9cq//gOpJ+tmvVNRmiKsXUi8sPGUGPEWIshihiShlvN1meNoQoQ1R2jDfuBimCfHjJOsg + SrNXWIcRJwuQBFXJneXoOvL0NiGkzDtLrgJnKUIySp6L0MYYeVYWhUKYrAq+MG3WgGJolCfP1BGzI0zc + gfYcpNrlNHZ/SE9Ff4Ejn4vOjjIHDu7HI7RpjRsvsiOPN+7iRmVxqpkLakEANPf7ypyjnJzEQzEDegon + eS/t3grs3gw+Ki5iIAfJCgoMA7i4hWZU6TpmwCdlHr+7SvpoM1YR/VpO1wDQhRlQkzzZ0OVsmKwhby5k + 1cqnuX+tA1WZ4e3mUtiK/X/AcgBv9bUcx9YAXYOcrlPAm+fIIhyvIh/e6lhJYHiNHdX6AwAHPpcTPSWm + AVnWCh2mbeQpQEtN9tclpip78nBot37/i5KoIUY7rhIDOdaiIl+es5U4MkIZ8S15O4E/0YCB8HNbcuOh + mAGqxOQ5S4Q6f1yOF6CVp0w6gxfQ/ZdBnj/Cc21Sm8M0egAAAABJRU5ErkJggg== + + + + 172, 22 + + + Animated Texture + + + 172, 22 + + + Audio.pck + + + 172, 22 + + + Colours.col + + + 172, 22 + + + Skins.pck + + + 172, 22 + + + Behaviours.bin + + + 172, 22 + + + EntityMaterials.bin + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xOdTWsmQAAAA3SURBVDhPY/j/ + /z9FGKsgGIsCKWSMTQ0QYxUE45FmALpiYvFwMgAbxqIYG8YqCMajBhCJ/zMAAPGwpV/Xje8RAAAAAElF + TkSuQmCC + + + + 157, 22 + + + Create + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xOdTWsmQAAAIkSURBVDhPpdLf + T1JxGMfxc1n8qtzcyglCWhFS1PLGHAgisDmktZZtabRSEYhDZ8xpiSWVpaSxLpoXyWquLvzV+oGZq+iy + /6Stm7qsm+DT830YMJw3rbO9Djs7z/P+wob03xcAyWbUwqLXotWgha1pDzPr1axl/y52uEHFrAY1z4l5 + sVsK0IK1UVMbaKQAOXhgN2tuKLHQTKtBh6M0XwmIxe1OtexjXZa9pA6dlnomlgXx7WoCo/1eTF3pwfRQ + gM3HLmD+Wh8yIwE8CgcwFznLJs67cLPPgeMmXW1gKRXCZjqGfCbBvi6kWH6OnoXMKFsd68fa2CW0Haqr + BpYnh5G7F8PGtIyV2yG2NhXHeuo6nioD5CI+pRMsG+nFYqSHVQKrt0LYKAcmhyCeX6Vklk0MsI9phQIK + Bfy07OfPSkAs/v7xDcViEd6OZ/C2LyOXHMb75Agtlk72nF6hdy/FEgrFP3yI2OVA7r6MXz+/04siPB3P + aXgJ75JhbFIgP5PAZwr42lcp8IJnioUCBcLVQHbQizfjQTr1Kj7cTbBIpw1R54mK/GwMXwjqaYWkzrVV + A4uDPry+QYGJIN7eUVjMcQyyvWrrQRxbM/GdA4+Dbjy57MJC0AmnUQ2XUYPZXjse+qvKi9vRHZLisUJx + WyB3m0sBkwZuvYr56A8j7LQs0B2S7LMg2n0EUY8ZdpMaDgo4mlSsq1lXo7w4fuZk6Sf861U5mS9J+gsp + e+98+xbVEAAAAABJRU5ErkJggg== + + + + 228, 22 + + + Import Skin + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xOdTWsmQAAAEnSURBVDhPYxgc + 4P8Chv8YeKWUIFSaMPi/W+r//1MapOGTOixQ7UADkCS05Xjh2FhFEIydtIT+22uJAsX4wBimFqod04Bt + nTn/9/YV/T82rQGM93YXAfkl/1eVRYPl8RqwuTnn/5aW3P8r69L+r67P+7+mIf//rIKo/7s7i/7PyfT9 + PzvTC78BW6AGrKpN+7+2IReM5xTF/N/VWQA0wAdogA8BA4Ca//7799/VauH/TdUZ/7dVp//fA7Td3XLV + //+iwNgBYXwGbCiP+7+5Oun/9qai/5n2+v+zHAzAeG9HDnEGTIl3/D8tzuG/owLP/w5f2/9dPrYIjWgY + qh3VgAJnrf+5Lhr/HRV5/jvLcoExNs0gDNWOagBeDNMM5UO1Ew8wbB4EgIEBABiEccKRdcoAAAAAAElF + TkSuQmCC + + + + 228, 22 + + + Import Extracted Skins Folder + + + 228, 22 + + + Add Texture + + + 228, 22 + + + Add File + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xOdTWsmQAAABzSURBVDhPpYzB + DQAhCARp4hr3Txu254WTjYRb9cEmk/BgRjBVHTv85Twmgt77PcJEYIFrhIkAgWOEiSAGthEmgtbaD9fW + mBgpB4xywCgFxiMf5YDdrq3l5wjEjKtzTARMNlydY2IGot2ureVnRjkQmZbICyCi7XU5cfqKAAAAAElF + TkSuQmCC + + + + 157, 22 + + + Import + + + 186, 22 + + + Export as 3DS Texture + + + 157, 22 + + + Export + + + 222, 22 + + + Skin (.PNG) + + + 222, 22 + + + Cape (.PNG) + + + 222, 22 + + + Texture (.PNG) + + + 222, 22 + + + Languages File (.LOC) + + + 222, 22 + + + Game Rules File (.GRF) + + + 222, 22 + + + Music Cues File (audio.PCK) + + + 222, 22 + + + Colour Table File (.COL) + + + 222, 22 + + + Game Rules Header (.GRH) + + + 222, 22 + + + Skins PCK (.PCK) + + + 222, 22 + + + Models File (.BIN) + + + 222, 22 + + + Behaviours File (.BIN) + + + 222, 22 + + + Entity Materials File (.BIN) + + + 157, 22 + + + Set File Type + + + 154, 6 + + + 223, 22 + + + Generate MipMap Texture + + + 223, 22 + + + View File Info + + + 223, 22 + + + Correct Skin Decimals + + + 100, 22 + + + Big + + + 100, 22 + + + Little + + + 223, 22 + + + Set Endianness + + + 80, 22 + + + 1 + + + 80, 22 + + + 2 + + + 80, 22 + + + 3 + + + 223, 22 + + + Set Model Container version + + + 157, 22 + + + Misc. Functions + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMkMEa+wAAACYSURBVDhPpZBZ + CsQwDEOd5QK5/2E9qCBGXtopzMcDxxKyY3P3izmnm9kt0OlVvsVVVgOAtvduQ4KJdYbaGKOEFFOHamut + ENKaMlk75zi2QX1rUqDpkbEF/cGktb47ygb5ODA8hVArgsK1cx+EAE7LaB8+hb3QzDx942eAXrqjBOgR + MRkBfHeUADbe8ncANw4NhLwF33R3+wA6sV5/E8GOLwAAAABJRU5ErkJggg== + + + + 157, 22 + + + Extract + + + 154, 6 + + + 157, 22 + + + Clone + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAACVJREFUOE9jwAL+E8AkAbI0IYNRA0YNAIFRA8g0AKYJF0YCDAwAzhor1TRE/JoA + AAAASUVORK5CYII= + + + + 157, 22 + + + Rename + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMkMEa+wAAAC/SURBVDhPlVHB + DQMhDEOIfwfoOuzFoPxhAd5c6/SMAgq0tRQFmdgXfA5IKUkBMcbHPxyJCxVCkK7rm+EwaK1dQO9dClzO + WfpOTM7hy1oMGNvY4pucxNY2p6cAWzFw2oZuMmiJweGeHM634UdLg50YwD05vQ2fYoaoDTEMrJyIfw3R + 4qYQWUZgg6OwlDJyMH8LcwF2T8FZ5kYQb4Lde/9Et8S6Dy1z0LUGi7VpWGvl3Lw2V98ZrtwIUYktwwPn + 3AtE5NqX8pp0ZQAAAABJRU5ErkJggg== + + + + 157, 22 + + + Replace + + + 157, 22 + + + Delete + + + 158, 236 + + + contextMenuPCKEntries + + + System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Left + + + 0 + + + 204, 20 + + + 32, 32 + + + 5, 50 + + + 0 + + + 274, 501 + + + 20 + + + treeViewMain + + + System.Windows.Forms.TreeView, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 9 + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMkMEa+wAAABSSURBVDhP5c0x + DsAgDENRxt7/wmkNSpRGf0CCCZAegxNMM7MlGMp3dIU6dxhKf/QMNxRogeQC8ivw5Vn7C0heJlFA+kL5 + jWAohxRkde4wnGftBS90axNmphIGAAAAAElFTkSuQmCC + + + + 181, 22 + + + Add Multiple Entries + + + Top, Right + + + True + + + 831, 0 + + + 173, 15 + + + 22 + + + Save as Switch/Vita/PS4 PCK + + + LittleEndianCheckBox + + + MetroFramework.Controls.MetroCheckBox, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a + + + $this + + + 3 + + + Top, Bottom, Left, Right + + + None + + + NoControl + + + 285, 50 + + + 218, 218 + + + Zoom + + + 18 + + + previewPictureBox + + + PckStudio.ToolboxItems.InterpolationPictureBox, PCK-Studio, Version=7.0.0.2, Culture=neutral, PublicKeyToken=null + + + $this + + + 2 + + + True + + + None + + + 4, 38 + + + 5, 50, 5, 7 + + + 1016, 558 + + + addEntryToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + addEntryToolStripMenuItem1 + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + addBOXEntryToolStripMenuItem1 + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + addANIMEntryToolStripMenuItem1 + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + addMultipleEntriesToolStripMenuItem1 + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + deleteEntryToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + editAllEntriesToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + createToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + folderToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + skinToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + createAnimatedTextureToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + audiopckToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + colourscolToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + CreateSkinsPCKToolStripMenuItem1 + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + behavioursbinToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + entityMaterialsbinToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + importSkinsToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + importSkinToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + importExtractedSkinsFolderToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + addTextureToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + addFileToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + exportToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + as3DSTextureFileToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + setFileTypeToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + skinToolStripMenuItem1 + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + capeToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + textureToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + languagesFileLOCToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + gameRulesFileGRFToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + audioPCKFileToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + coloursCOLFileToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + gameRulesHeaderGRHToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + skinsPCKToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + modelsFileBINToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + behavioursFileBINToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + entityMaterialsFileBINToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + toolStripSeparator5 + + + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + miscFunctionsToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + generateMipMapTextureToolStripMenuItem1 + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + viewFileInfoToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + correctSkinDecimalsToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + setSubPCKEndiannessToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + bigEndianXbox360PS3WiiUToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + littleEndianPS4PSVitaSwitchToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + setModelContainerFormatToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + version1ToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + version2ToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + version3114ToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + extractToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + toolStripSeparator6 + + + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + cloneFileToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + renameFileToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + replaceToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + deleteFileToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + imageList + + + System.Windows.Forms.ImageList, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + addMultipleEntriesToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + PckEditor + + + PckStudio.Internal.EditorControl`1[[PckStudio.Internal.PackInfo, PCK-Studio, Version=7.0.0.2, Culture=neutral, PublicKeyToken=null]], PCK-Studio, Version=7.0.0.2, Culture=neutral, PublicKeyToken=null + + \ No newline at end of file diff --git a/PCK-Studio/Forms/Editor/ModelEditor.resx b/PCK-Studio/Forms/Editor/ModelEditor.resx index a9f732b1..b61b7c65 100644 --- a/PCK-Studio/Forms/Editor/ModelEditor.resx +++ b/PCK-Studio/Forms/Editor/ModelEditor.resx @@ -117,6 +117,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 +<<<<<<<< HEAD:PCK-Studio/Forms/Editor/ModelEditor.resx 17, 17 @@ -126,7 +127,128 @@ 293, 17 +======== + + + True + +>>>>>>>> main:PckStudio.Core/ItemSelectionPopUp.resx + + 15, 41 + + + 35, 13 + + + 3 + + + Items: + + + label2 + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 3 + + + + Flat + + + 54, 76 + + + 75, 23 + + + 4 + + + Add + + + okBtn + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 2 + + + Flat + + + NoControl + + + 135, 76 + + + 75, 23 + + + 6 + + + Cancel + + + cancelButton + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 1 + + + 23 + + + 60, 34 + + + 192, 29 + + + 7 + + + ComboBox + + + MetroFramework.Controls.MetroComboBox, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a + + + $this + + + 0 + + + True + + + 6, 13 + + + 264, 105 + AAABAA0AAAAAAAEAIAD7NAAA1gAAAICAAAABACAAKAgBANE1AACAgAAAAQAIAChMAAD5PQEAQEAAAAEA @@ -2633,4 +2755,13 @@ AP//AAA= + + CenterParent + + + ItemSelectionPopUp + + + MetroFramework.Forms.MetroForm, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a + \ No newline at end of file diff --git a/PckStudio.Core/Resources/additional_mapicons.png b/PckStudio.Core/Resources/additional_mapicons.png new file mode 100644 index 00000000..11b7256a Binary files /dev/null and b/PckStudio.Core/Resources/additional_mapicons.png differ diff --git a/PckStudio.Core/Resources/bannerData.json b/PckStudio.Core/Resources/bannerData.json new file mode 100644 index 00000000..f1de015f --- /dev/null +++ b/PckStudio.Core/Resources/bannerData.json @@ -0,0 +1,1053 @@ +{ + "COMMENT_1": "JSON by MattNL", + "entries": [ + { + "internalName": "base", + "displayName": "Base", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "border", + "displayName": "Bordure", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "bricks", + "displayName": "Field Masoned", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "circle", + "displayName": "Roundel", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "creeper", + "displayName": "Creeper Charge", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "cross", + "displayName": "Saltire", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "curly_border", + "displayName": "Bordure Indented", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "diagonal_left", + "displayName": "Per Bend Sinister", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "diagonal_right", + "displayName": "Per Bend", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "diagonal_up_left", + "displayName": "Per Bend Inverted", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "diagonal_up_right", + "displayName": "Per Bend Sinister Inverted", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "flower", + "displayName": "Flower Charge", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "gradient", + "displayName": "Gradient", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "gradient_up", + "displayName": "Base Gradient", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "half_horizontal", + "displayName": "Per Fess", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "half_horizontal_bottom", + "displayName": "Per Fess Inverted", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "half_vertical", + "displayName": "Per Pale", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "half_vertical_right", + "displayName": "Per Pale Inverted", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "mojang", + "displayName": "Thing", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "rhombus", + "displayName": "Lozenge", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "skull", + "displayName": "Skull Charge", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "small_stripes", + "displayName": "Paly", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "square_bottom_left", + "displayName": "Base Dexter Canton", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "square_bottom_right", + "displayName": "Base Sinister Canton", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "square_top_left", + "displayName": "Chief Dexter Canton", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "square_top_right", + "displayName": "Chief Sinister Canton", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "straight_cross", + "displayName": "Cross", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "stripe_bottom", + "displayName": "Base Fess", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "stripe_center", + "displayName": "Pale", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "strip_downleft", + "displayName": "Bend Sinister", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "stripe_downright", + "displayName": "Bend", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "stripe_left", + "displayName": "Pale Dexter", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "stripe_middle", + "displayName": "Fess", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "stripe_right", + "displayName": "Pale Sinister", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "stripe_top", + "displayName": "Chief Fess", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "triangle_bottom", + "displayName": "Chevron", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "triangle_top", + "displayName": "Inverted Chevron", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "triangles_bottom", + "displayName": "Base Indented", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "triangles_top", + "displayName": "Chief Indented", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + }, + { + "internalName": "mask", + "displayName": "Mask" + }, + { + "internalName": "illager", + "displayName": "Ominous Banner [PS4 ONLY]" + }, + { + "internalName": "globe", + "displayName": "Globe [PS4 ONLY]", + + "colourEntry": { + "defaultName": "Banner_White", + "variants": [ + "Banner_Black", + "Banner_Blue", + "Banner_Brown", + "Banner_Cyan", + "Banner_Gray", + "Banner_Green", + "Banner_Light_Blue", + "Banner_Lime", + "Banner_Magenta", + "Banner_Orange", + "Banner_Pink", + "Banner_Purple", + "Banner_Red", + "Banner_Silver", + "Banner_White", + "Banner_Yellow" + ] + } + } + ] +} diff --git a/PckStudio.Core/Resources/banners.png b/PckStudio.Core/Resources/banners.png new file mode 100644 index 00000000..952a0eff Binary files /dev/null and b/PckStudio.Core/Resources/banners.png differ diff --git a/PckStudio.Core/Resources/blockData.json b/PckStudio.Core/Resources/blockData.json new file mode 100644 index 00000000..d4622c10 --- /dev/null +++ b/PckStudio.Core/Resources/blockData.json @@ -0,0 +1,2922 @@ +{ + "COMMENT_1": "Tile data research by MattNL", + "COMMENT_2": "JSON by PhoenixARC, MattNL, and NessieHax (Miku-666)", + "entries": [ + { + "internalName": "grass_top", + "displayName": "Grass Block (Top)", + + "colourEntry": { + "defaultName": "Grass_Common", + "variants": [ + "Grass_Common", + "Grass_Mesa", + "Grass_Swamp1", + "Grass_Swamp2" + ] + } + }, + { + "internalName": "stone", + "displayName": "Stone" + }, + { + "internalName": "dirt", + "displayName": "Dirt" + }, + { + "internalName": "grass_side", + "displayName": "Grass Block (Side)" + }, + { + "internalName": "planks_oak", + "displayName": "Oak Planks" + }, + { + "internalName": "stoneslab_side", + "displayName": "Stone Slab (Side)" + }, + { + "internalName": "stoneslab_top", + "displayName": "Stone Slab (Top)" + }, + { + "internalName": "brick", + "displayName": "Bricks" + }, + { + "internalName": "tnt_side", + "displayName": "TNT (Side)" + }, + { + "internalName": "tnt_top", + "displayName": "TNT (Top)" + }, + { + "internalName": "tnt_bottom", + "displayName": "TNT (Bottom)" + }, + { + "internalName": "web", + "displayName": "Cobweb" + }, + { + "internalName": "flower_rose", + "displayName": "Poppy" + }, + { + "internalName": "flower_dandelion", + "displayName": "Dandelion" + }, + { + "internalName": "portal", + "displayName": "Nether Portal" + }, + { + "internalName": "sapling", + "displayName": "Oak Sapling" + }, + { + "internalName": "cobblestone", + "displayName": "Cobblestone" + }, + { + "internalName": "bedrock", + "displayName": "Bedrock" + }, + { + "internalName": "sand", + "displayName": "Sand" + }, + { + "internalName": "gravel", + "displayName": "Gravel" + }, + { + "internalName": "log_oak", + "displayName": "Oak Wood (Side)" + }, + { + "internalName": "log_oak_top", + "displayName": "Oak Wood (Top)" + }, + { + "internalName": "iron_block", + "displayName": "Block of Iron" + }, + { + "internalName": "gold_block", + "displayName": "Block of Gold" + }, + { + "internalName": "diamond_block", + "displayName": "Block of Diamond" + }, + { + "internalName": "emerald_block", + "displayName": "Block of Emerald" + }, + { + "internalName": "redstone_block", + "displayName": "Block of Redstone" + }, + { + "internalName": "dropper_front_horizontal", + "displayName": "Dropper (Front)" + }, + { + "internalName": "mushroom_red", + "displayName": "Mushroom (Red)" + }, + { + "internalName": "mushroom_brown", + "displayName": "Mushroom (Brown)" + }, + { + "internalName": "sapling_jungle", + "displayName": "Jungle Tree Sapling" + }, + { + "internalName": "fire_0", + "displayName": "Fire (Layer 1)" + }, + { + "internalName": "gold_ore", + "displayName": "Gold Ore" + }, + { + "internalName": "iron_ore", + "displayName": "Iron Ore" + }, + { + "internalName": "coal_ore", + "displayName": "Coal Ore" + }, + { + "internalName": "bookshelf", + "displayName": "Bookshelf" + }, + { + "internalName": "cobblestone_mossy", + "displayName": "Moss Stone" + }, + { + "internalName": "obsidian", + "displayName": "Obsidian" + }, + { + "internalName": "grass_side_overlay", + "displayName": "Grass Side (Overlay)", + + "colourEntry": { + "defaultName": "Grass_Common", + "variants": [ + "Grass_Common", + "Grass_Mesa", + "Grass_Swamp1", + "Grass_Swamp2" + ] + } + }, + { + "internalName": "tallgrass", + "displayName": "Tall Grass", + + "colourEntry": { + "defaultName": "Grass_Common", + "variants": [ + "Grass_Common", + "Grass_Mesa", + "Grass_Swamp1", + "Grass_Swamp2" + ] + } + }, + { + "internalName": "dispenser_front_vertical", + "displayName": "Dispenser (Vertical) (Front)" + }, + { + "internalName": "beacon", + "displayName": "Beacon" + }, + { + "internalName": "dropper_front_vertical", + "displayName": "Dropper (Vertical) (Front)" + }, + { + "internalName": "workbench_top", + "displayName": "Crafting Table (Top)" + }, + { + "internalName": "furnace_front", + "displayName": "Furnace (Front)" + }, + { + "internalName": "furnace_side", + "displayName": "Furnace/Dispenser/Dropper (Side)" + }, + { + "internalName": "dispenser_front", + "displayName": "Dispenser (Front)" + }, + { + "internalName": "fire_1", + "displayName": "Fire (Layer 2)" + }, + { + "internalName": "sponge", + "displayName": "Sponge" + }, + { + "internalName": "glass", + "displayName": "Glass" + }, + { + "internalName": "diamond_ore", + "displayName": "Diamond Ore" + }, + { + "internalName": "redstone_ore", + "displayName": "Redstone Ore" + }, + { + "internalName": "leaves", + "displayName": "Oak Leaves", + + "colourEntry": { + "defaultName": "Foliage_Default", + "variants": [ + "Foliage_Default", + "Foliage_Evergreen", + "Foliage_Birch", + "Foliage_Mesa", + "Foliage_Swampland" + ] + } + }, + { + "internalName": "leaves_opaque", + "displayName": "Oak Leaves (Opaque)", + + "colourEntry": { + "defaultName": "Foliage_Default", + "variants": [ + "Foliage_Default", + "Foliage_Evergreen", + "Foliage_Birch", + "Foliage_Mesa", + "Foliage_Swampland" + ] + } + }, + { + "internalName": "stonebrick", + "displayName": "Stone Bricks" + }, + { + "internalName": "deadbush", + "displayName": "Dead Bush/Shrub" + }, + { + "internalName": "fern", + "displayName": "Fern", + + "colourEntry": { + "defaultName": "Grass_Common", + "variants": [ + "Grass_Common", + "Grass_Mesa", + "Grass_Swamp1", + "Grass_Swamp2" + ] + } + }, + { + "internalName": "daylight_detector_top", + "displayName": "Daylight Sensor (Top)" + }, + { + "internalName": "daylight_detector_side", + "displayName": "Daylight Sensor (Side)" + }, + { + "internalName": "workbench_side", + "displayName": "Crafting Table (Side)" + }, + { + "internalName": "workbench_front", + "displayName": "Crafting Table (Front)" + }, + { + "internalName": "furnace_front_lit", + "displayName": "Furnace (Lit) (Front)" + }, + { + "internalName": "furnace_top", + "displayName": "Furnace/Dispenser/Dropper (Top)" + }, + { + "internalName": "sapling_spruce", + "displayName": "Spruce Sapling" + }, + { + "internalName": "wool_colored_white", + "displayName": "White Wool" + }, + { + "internalName": "mob_spawner", + "displayName": "Monster Spawner" + }, + { + "internalName": "snow", + "displayName": "Snow" + }, + { + "internalName": "ice", + "displayName": "Ice" + }, + { + "internalName": "snow_side", + "displayName": "Grass Block (Snowy) (Side)" + }, + { + "internalName": "cactus_top", + "displayName": "Cactus (Top)" + }, + { + "internalName": "cactus_side", + "displayName": "Cactus (Side)" + }, + { + "internalName": "cactus_bottom", + "displayName": "Cactus (Bottom)" + }, + { + "internalName": "clay", + "displayName": "Clay" + }, + { + "internalName": "reeds", + "displayName": "Sugar Canes" + }, + { + "internalName": "jukebox_side", + "displayName": "Jukebox (Side)" + }, + { + "internalName": "jukebox_top", + "displayName": "Jukebox (Top)" + }, + { + "internalName": "waterlily", + "displayName": "Lily Pad", + + "colourEntry": { + "defaultName": "Tile_WaterLily", + "variants": [ "Tile_WaterLily" ] + } + }, + { + "internalName": "mycel_side", + "displayName": "Mycelium (Side)" + }, + { + "internalName": "mycel_top", + "displayName": "Mycelium (Top)" + }, + { + "internalName": "sapling_birch", + "displayName": "Birch Sapling" + }, + { + "internalName": "torch_on", + "displayName": "Torch" + }, + { + "internalName": "door_wood_upper", + "displayName": "Oak Door (Top)" + }, + { + "internalName": "door_iron_upper", + "displayName": "Iron Door (Top)" + }, + { + "internalName": "ladder", + "displayName": "Ladder" + }, + { + "internalName": "trapdoor", + "displayName": "Oak Trapdoor" + }, + { + "internalName": "iron_bars", + "displayName": "Iron Bars" + }, + { + "internalName": "farmland_wet", + "displayName": "Farmland (Wet)" + }, + { + "internalName": "farmland_dry", + "displayName": "Farmland" + }, + { + "internalName": "crops_0", + "displayName": "Wheat (Stage 1)" + }, + { + "internalName": "crops_1", + "displayName": "Wheat (Stage 2)" + }, + { + "internalName": "crops_2", + "displayName": "Wheat (Stage 3)" + }, + { + "internalName": "crops_3", + "displayName": "Wheat (Stage 4)" + }, + { + "internalName": "crops_4", + "displayName": "Wheat (Stage 5)" + }, + { + "internalName": "crops_5", + "displayName": "Wheat (Stage 6)" + }, + { + "internalName": "crops_6", + "displayName": "Wheat (Stage 7)" + }, + { + "internalName": "crops_7", + "displayName": "Wheat (Stage 8)" + }, + { + "internalName": "lever", + "displayName": "Lever" + }, + { + "internalName": "door_wood_lower", + "displayName": "Oak Door (Bottom)" + }, + { + "internalName": "door_iron_lower", + "displayName": "Iron Door (Bottom)" + }, + { + "internalName": "redstone_torch_on", + "displayName": "Redstone Torch" + }, + { + "internalName": "stonebrick_mossy", + "displayName": "Mossy Stone Bricks" + }, + { + "internalName": "stonebrick_cracked", + "displayName": "Cracked Stone Bricks" + }, + { + "internalName": "pumpkin_top", + "displayName": "Pumpkin (Top)" + }, + { + "internalName": "netherrack", + "displayName": "Netherrack" + }, + { + "internalName": "soul_sand", + "displayName": "Soul Sand" + }, + { + "internalName": "glowstone", + "displayName": "Glowstone" + }, + { + "internalName": "piston_top_sticky", + "displayName": "Sticky Piston (Top)" + }, + { + "internalName": "piston_top", + "displayName": "Piston (Top)" + }, + { + "internalName": "piston_side", + "displayName": "Piston (Side)" + }, + { + "internalName": "piston_bottom", + "displayName": "Piston (Bottom)" + }, + { + "internalName": "piston_inner_top", + "displayName": "Piston (Inside)" + }, + { + "internalName": "stem_straight", + "displayName": "Stem", + + "colourEntry": { + "defaultName": "Tile_StemMin", + "variants": [ + "Tile_StemMin", + "Tile_StemMax" + ] + } + }, + { + "internalName": "rail_normal_turned", + "displayName": "Rail (Turned)" + }, + { + "internalName": "wool_colored_black", + "displayName": "Black Wool" + }, + { + "internalName": "wool_colored_gray", + "displayName": "Gray Wool" + }, + { + "internalName": "redstone_torch_off", + "displayName": "Redstone Torch (Off)" + }, + { + "internalName": "log_spruce", + "displayName": "Spruce Wood (Side)" + }, + { + "internalName": "log_birch", + "displayName": "Birch Wood (Side)" + }, + { + "internalName": "pumpkin_side", + "displayName": "Pumpkin (Side)" + }, + { + "internalName": "pumpkin_face_off", + "displayName": "Carved Pumpkin" + }, + { + "internalName": "pumpkin_face_on", + "displayName": "Jack-O-Lantern" + }, + { + "internalName": "cake_top", + "displayName": "Cake (Top)" + }, + { + "internalName": "cake_side", + "displayName": "Cake (Side)" + }, + { + "internalName": "cake_inner", + "displayName": "Cake (Inside)" + }, + { + "internalName": "cake_bottom", + "displayName": "Cake (Bottom)" + }, + { + "internalName": "mushroom_block_skin_red", + "displayName": "Mushroom (Red Block)" + }, + { + "internalName": "mushroom_block_skin_brown", + "displayName": "Mushroom (Brown Block)" + }, + { + "internalName": "stem_bent", + "displayName": "Stem (Attached)", + + "colourEntry": { + "defaultName": "Tile_StemMin", + "variants": [ + "Tile_StemMin", + "Tile_StemMax" + ] + } + }, + { + "internalName": "rail_normal", + "displayName": "Rail" + }, + { + "internalName": "wool_colored_red", + "displayName": "Red Wool" + }, + { + "internalName": "wool_colored_pink", + "displayName": "Pink Wool" + }, + { + "internalName": "repeater_off", + "displayName": "Repeater" + }, + { + "internalName": "leaves_spruce", + "displayName": "Spruce Leaves", + + "colourEntry": { + "defaultName": "Foliage_Evergreen", + "variants": [ + "Foliage_Default", + "Foliage_Evergreen", + "Foliage_Birch", + "Foliage_Mesa", + "Foliage_Swampland" + ] + } + }, + { + "internalName": "leaves_spruce_opaque", + "displayName": "Spruce Leaves (Opaque)", + + "colourEntry": { + "defaultName": "Foliage_Evergreen", + "variants": [ + "Foliage_Default", + "Foliage_Evergreen", + "Foliage_Birch", + "Foliage_Mesa", + "Foliage_Swampland" + ] + } + }, + { + "internalName": "conduit_top", + "displayName": "Conduit (Break Particles)" + }, + { + "internalName": "turtle_egg_hatch_0", + "displayName": "Sea Turtle Egg (Stage 1)" + }, + { + "internalName": "melon_side", + "displayName": "Melon (Side)" + }, + { + "internalName": "melon_top", + "displayName": "Melon (Top)" + }, + { + "internalName": "cauldron_top", + "displayName": "Cauldron (Top)" + }, + { + "internalName": "cauldron_inner", + "displayName": "Cauldron (Inside)" + }, + { + "internalName": "sponge_wet", + "displayName": "Wet Sponge" + }, + { + "internalName": "mushroom_block_skin_stem", + "displayName": "Mushroom (Stem Block)" + }, + { + "internalName": "mushroom_block_inside", + "displayName": "Mushroom (Inside Block)" + }, + { + "internalName": "vine", + "displayName": "Vines", + + "colourEntry": { + "defaultName": "Foliage_Default", + "variants": [ + "Foliage_Default", + "Foliage_Evergreen", + "Foliage_Birch", + "Foliage_Mesa", + "Foliage_Swampland" + ] + } + }, + { + "internalName": "lapis_block", + "displayName": "Lapis Lazuli Block" + }, + { + "internalName": "wool_colored_green", + "displayName": "Green Wool" + }, + { + "internalName": "wool_colored_lime", + "displayName": "Lime Wool" + }, + { + "internalName": "repeater_on", + "displayName": "Redstone Repeater (On)" + }, + { + "internalName": "glass_pane_top", + "displayName": "Glass Pane (Top)" + }, + { + "internalName": "chest_top", + "displayName": "Chest (Break Particles)" + }, + { + "internalName": "ender_chest_top", + "displayName": "Ender Chest (Break Particles)" + }, + { + "internalName": "turtle_egg_hatch_1", + "displayName": "Sea Turtle Egg (Stage 2)" + }, + { + "internalName": "turtle_egg_hatch_2", + "displayName": "Sea Turtle Egg (Stage 3)" + }, + { + "internalName": "log_jungle", + "displayName": "Jungle Wood (Side)" + }, + { + "internalName": "cauldron_side", + "displayName": "Cauldron (Side)" + }, + { + "internalName": "cauldron_bottom", + "displayName": "Cauldron (Bottom)" + }, + { + "internalName": "brewing_stand_base", + "displayName": "Brewing Stand (Base)" + }, + { + "internalName": "brewing_stand", + "displayName": "Brewing Stand" + }, + { + "internalName": "endframe_top", + "displayName": "End Portal Frame (Top)" + }, + { + "internalName": "endframe_side", + "displayName": "End Portal Frame (Side)" + }, + { + "internalName": "lapis_ore", + "displayName": "Lapis Lazuli Ore" + }, + { + "internalName": "wool_colored_brown", + "displayName": "Brown Wool" + }, + { + "internalName": "wool_colored_yellow", + "displayName": "Yellow Wool" + }, + { + "internalName": "rail_golden", + "displayName": "Powered Rail" + }, + { + "internalName": "redstone_dust_cross", + "displayName": "Redstone Dust (Cross)", + + "colourEntry": { + "defaultName": "Tile_RedstoneDust", + "variants": [ + "Tile_RedstoneDust", + "Tile_RedstoneDustUnlit", + "Tile_RedstoneDustLitMin", + "Tile_RedstoneDustLitMax" + ] + } + }, + { + "internalName": "redstone_dust_line", + "displayName": "Redstone Dust (Line)", + + "colourEntry": { + "defaultName": "Tile_RedstoneDust", + "variants": [ + "Tile_RedstoneDust", + "Tile_RedstoneDustUnlit", + "Tile_RedstoneDustLitMin", + "Tile_RedstoneDustLitMax" + ] + } + }, + { + "internalName": "enchantment_top", + "displayName": "Enchantment Table (Top)" + }, + { + "internalName": "dragon_egg", + "displayName": "Dragon Egg" + }, + { + "internalName": "cocoa_2", + "displayName": "Cocoa (Stage 3)" + }, + { + "internalName": "cocoa_1", + "displayName": "Cocoa (Stage 2)" + }, + { + "internalName": "cocoa_0", + "displayName": "Cocoa (Stage 1)" + }, + { + "internalName": "emerald_ore", + "displayName": "Emerald Ore" + }, + { + "internalName": "trip_wire_source", + "displayName": "Tripwire Hook" + }, + { + "internalName": "trip_wire", + "displayName": "Tripwire" + }, + { + "internalName": "endframe_eye", + "displayName": "End Portal Frame (Eye)" + }, + { + "internalName": "end_stone", + "displayName": "End Stone" + }, + { + "internalName": "sandstone_top", + "displayName": "Sandstone (Top)" + }, + { + "internalName": "wool_colored_blue", + "displayName": "Blue Wool" + }, + { + "internalName": "wool_colored_light_blue", + "displayName": "Light Blue Wool" + }, + { + "internalName": "rail_golden_powered", + "displayName": "Powered Rail (On)" + }, + { + "internalName": "redstone_dust_cross_overlay", + "displayName": "Redstone Dust (Cross) (Overlay)" + }, + { + "internalName": "redstone_dust_line_overlay", + "displayName": "Redstone Dust (Line) (Overlay)" + }, + { + "internalName": "enchantment_side", + "displayName": "Enchantment Table (Side)" + }, + { + "internalName": "enchantment_bottom", + "displayName": "Enchantment Table (Bottom)" + }, + { + "internalName": "diamondRing", + "displayName": "Diamond Score Ring" + }, + { + "internalName": "itemframe_back", + "displayName": "Item Frame" + }, + { + "internalName": "flower_pot", + "displayName": "Flower Pot" + }, + { + "internalName": "comparator_off", + "displayName": "Redstone Comparator" + }, + { + "internalName": "comparator_on", + "displayName": "Redstone Comparator (On)" + }, + { + "internalName": "rail_activator", + "displayName": "Activator Rail" + }, + { + "internalName": "rail_activator_powered", + "displayName": "Activator Rail (On)" + }, + { + "internalName": "quartz_ore", + "displayName": "Nether Quartz Ore" + }, + { + "internalName": "sandstone_side", + "displayName": "Sandstone (Side)" + }, + { + "internalName": "wool_colored_purple", + "displayName": "Purple Wool" + }, + { + "internalName": "wool_colored_magenta", + "displayName": "Magenta Wool" + }, + { + "internalName": "detectorRail", + "displayName": "Detector Rail" + }, + { + "internalName": "leaves_jungle", + "displayName": "Jungle Leaves", + + "colourEntry": { + "defaultName": "Foliage_Default", + "variants": [ + "Foliage_Default", + "Foliage_Evergreen", + "Foliage_Birch", + "Foliage_Mesa", + "Foliage_Swampland" + ] + } + }, + { + "internalName": "leaves_jungle_opaque", + "displayName": "Jungle Leaves (Opaque)", + + "colourEntry": { + "defaultName": "Foliage_Default", + "variants": [ + "Foliage_Default", + "Foliage_Evergreen", + "Foliage_Birch", + "Foliage_Mesa", + "Foliage_Swampland" + ] + } + }, + { + "internalName": "planks_spruce", + "displayName": "Spruce Planks" + }, + { + "internalName": "planks_jungle", + "displayName": "Jungle Planks" + }, + { + "internalName": "carrots_stage_0", + "displayName": "Carrots (Stage 1)" + }, + { + "internalName": "carrots_stage_1", + "displayName": "Carrots (Stage 2)" + }, + { + "internalName": "carrots_stage_2", + "displayName": "Carrots (Stage 3)" + }, + { + "internalName": "carrots_stage_3", + "displayName": "Carrots (Stage 4)" + }, + { + "internalName": "slime", + "displayName": "Slime Block" + }, + { + "internalName": "water", + "displayName": "Water", + + "colourEntry": { + "isWaterColour": true, + "defaultName": "Water_Plains", + "variants": [ + "Water_Ocean", + "Water_Plains", + "Water_Desert", + "Water_ExtremeHills", + "Water_Forest", + "Water_Taiga", + "Water_Swampland", + "Water_River", + "Water_Hell", + "Water_Sky", + "Water_FrozenOcean", + "Water_FrozenRiver", + "Water_IcePlains", + "Water_IceMountains", + "Water_MushroomIsland", + "Water_MushroomIslandShore", + "Water_Beach", + "Water_DesertHills", + "Water_ForestHills", + "Water_TaigaHills", + "Water_ExtremeHillsEdge", + "Water_Jungle", + "Water_JungleHills", + "Water_JungleEdge", + "Water_DeepOcean", + "Water_StoneBeach", + "Water_ColdBeach", + "Water_BirchForest", + "Water_BirchForestHills", + "Water_RoofedForest", + "Water_ColdTaiga", + "Water_ColdTaigaHills", + "Water_MegaTaiga", + "Water_MegaTaigaHills", + "Water_ExtremeHillsPlus", + "Water_Savanna", + "Water_SavannaPlateau", + "Water_Mesa", + "Water_MesaPlateauF", + "Water_MesaPlateau" + ] + } + }, + { + "internalName": "water_flow", + "displayName": "Flowing Water", + + "width": 2, + "height": 2, + "colourEntry": { + "isWaterColour": true, + "defaultName": "Water_Plains", + "variants": [ + "Water_Ocean", + "Water_Plains", + "Water_Desert", + "Water_ExtremeHills", + "Water_Forest", + "Water_Taiga", + "Water_Swampland", + "Water_River", + "Water_Hell", + "Water_Sky", + "Water_FrozenOcean", + "Water_FrozenRiver", + "Water_IcePlains", + "Water_IceMountains", + "Water_MushroomIsland", + "Water_MushroomIslandShore", + "Water_Beach", + "Water_DesertHills", + "Water_ForestHills", + "Water_TaigaHills", + "Water_ExtremeHillsEdge", + "Water_Jungle", + "Water_JungleHills", + "Water_JungleEdge", + "Water_DeepOcean", + "Water_StoneBeach", + "Water_ColdBeach", + "Water_BirchForest", + "Water_BirchForestHills", + "Water_RoofedForest", + "Water_ColdTaiga", + "Water_ColdTaigaHills", + "Water_MegaTaiga", + "Water_MegaTaigaHills", + "Water_ExtremeHillsPlus", + "Water_Savanna", + "Water_SavannaPlateau", + "Water_Mesa", + "Water_MesaPlateauF", + "Water_MesaPlateau" + ] + } + }, + { + "internalName": "water_flow", + "displayName": "" + }, + { + "internalName": "sandstone_bottom", + "displayName": "Sandstone (Bottom)" + }, + { + "internalName": "wool_colored_cyan", + "displayName": "Cyan Wool" + }, + { + "internalName": "wool_colored_orange", + "displayName": "Orange Wool" + }, + { + "internalName": "redstoneLight", + "displayName": "Redstone Lamp" + }, + { + "internalName": "redstoneLight_lit", + "displayName": "Redstone Lamp (On)" + }, + { + "internalName": "stonebrick_carved", + "displayName": "Chiseled Stone Bricks" + }, + { + "internalName": "planks_birch", + "displayName": "Birch Planks" + }, + { + "internalName": "anvil_base", + "displayName": "Anvil (Base)" + }, + { + "internalName": "anvil_top_damaged_1", + "displayName": "Anvil (Slightly Damaged) (Top)" + }, + { + "internalName": "quartz_block_chiseled_top", + "displayName": "Chiseled Quartz Block (Top)" + }, + { + "internalName": "quartz_block_lines_top", + "displayName": "Pillar Quartz Block (Top)" + }, + { + "internalName": "quartz_block_top", + "displayName": "Block of Quartz (Top)" + }, + { + "internalName": "hopper_outside", + "displayName": "Hopper (Side)" + }, + { + "internalName": "detectorRail_on", + "displayName": "Detector Rail (On)" + }, + { + "internalName": "water_flow", + "displayName": "" + }, + { + "internalName": "water_flow", + "displayName": "" + }, + { + "internalName": "nether_brick", + "displayName": "Nether Brick" + }, + { + "internalName": "wool_colored_silver", + "displayName": "Light Gray Wool" + }, + { + "internalName": "nether_wart_stage_0", + "displayName": "Nether Wart (Stage 1)" + }, + { + "internalName": "nether_wart_stage_1", + "displayName": "Nether Wart (Stage 2)" + }, + { + "internalName": "nether_wart_stage_2", + "displayName": "Nether Wart (Stage 3)" + }, + { + "internalName": "sandstone_carved", + "displayName": "Chiseled Sandstone" + }, + { + "internalName": "sandstone_smooth", + "displayName": "Smooth Sandstone" + }, + { + "internalName": "anvil_top", + "displayName": "Anvil (Top)" + }, + { + "internalName": "anvil_top_damaged_2", + "displayName": "Anvil (Very Damaged) (Top)" + }, + { + "internalName": "quartz_block_chiseled", + "displayName": "Chiseled Quartz Block (Side)" + }, + { + "internalName": "quartz_block_lines", + "displayName": "Pillar Quartz Block (Side)" + }, + { + "internalName": "quartz_block_side", + "displayName": "Block of Quartz (Side)" + }, + { + "internalName": "hopper_inside", + "displayName": "Hopper (Inside)" + }, + { + "internalName": "lava", + "displayName": "Lava" + }, + { + "internalName": "lava_flow", + "displayName": "Flowing Lava", + "width": 2, + "height": 2 + }, + { + "internalName": "lava_flow", + "displayName": "", + }, + { + "internalName": "destroy_0", + "displayName": "Destroy (Stage 1)" + }, + { + "internalName": "destroy_1", + "displayName": "Destroy (Stage 2)" + }, + { + "internalName": "destroy_2", + "displayName": "Destroy (Stage 3)" + }, + { + "internalName": "destroy_3", + "displayName": "Destroy (Stage 4)" + }, + { + "internalName": "destroy_4", + "displayName": "Destroy (Stage 5)" + }, + { + "internalName": "destroy_5", + "displayName": "Destroy (Stage 6)" + }, + { + "internalName": "destroy_6", + "displayName": "Destroy (Stage 7)" + }, + { + "internalName": "destroy_7", + "displayName": "Destroy (Stage 8)" + }, + { + "internalName": "destroy_8", + "displayName": "Destroy (Stage 9)" + }, + { + "internalName": "destroy_9", + "displayName": "Destroy (Stage 10)" + }, + { + "internalName": "hay_block_side", + "displayName": "Hay Bale (Side)" + }, + { + "internalName": "quartz_block_bottom", + "displayName": "Quartz Block (Bottom)" + }, + { + "internalName": "hopper_top", + "displayName": "Hopper (Top)" + }, + { + "internalName": "hay_block_top", + "displayName": "Hay Bale (Top)" + }, + { + "internalName": "lava_flow", + "displayName": "", + }, + { + "internalName": "lava_flow", + "displayName": "", + }, + { + "internalName": "coal_block", + "displayName": "Block of Coal" + }, + { + "internalName": "hardened_clay", + "displayName": "Terracotta" + }, + { + "internalName": "noteblock", + "displayName": "Note Block" + }, + { + "internalName": "stone_andesite", + "displayName": "Andesite" + }, + { + "internalName": "stone_andesite_smooth", + "displayName": "Polished Andesite" + }, + { + "internalName": "stone_diorite", + "displayName": "Diorite" + }, + { + "internalName": "stone_diorite_smooth", + "displayName": "Polished Diorite" + }, + { + "internalName": "stone_granite", + "displayName": "Granite" + }, + { + "internalName": "stone_granite_smooth", + "displayName": "Polished Granite" + }, + { + "internalName": "potatoes_stage_0", + "displayName": "Potatoes (Stage 1)" + }, + { + "internalName": "potatoes_stage_1", + "displayName": "Potatoes (Stage 2)" + }, + { + "internalName": "potatoes_stage_2", + "displayName": "Potatoes (Stage 3)" + }, + { + "internalName": "potatoes_stage_3", + "displayName": "Potatoes (Stage 4)" + }, + { + "internalName": "log_spruce_top", + "displayName": "Spruce Wood (Top)" + }, + { + "internalName": "log_jungle_top", + "displayName": "Jungle Wood (Top)" + }, + { + "internalName": "log_birch_top", + "displayName": "Birch Wood (Top)" + }, + { + "internalName": "hardened_clay_stained_black", + "displayName": "Black Terracotta" + }, + { + "internalName": "hardened_clay_stained_blue", + "displayName": "Blue Terracotta" + }, + { + "internalName": "hardened_clay_stained_brown", + "displayName": "Brown Terracotta" + }, + { + "internalName": "hardened_clay_stained_cyan", + "displayName": "Cyan Terracotta" + }, + { + "internalName": "hardened_clay_stained_gray", + "displayName": "Gray Terracotta" + }, + { + "internalName": "hardened_clay_stained_green", + "displayName": "Green Terracotta" + }, + { + "internalName": "hardened_clay_stained_light_blue", + "displayName": "Light Blue Terracotta" + }, + { + "internalName": "hardened_clay_stained_lime", + "displayName": "Lime Terracotta" + }, + { + "internalName": "hardened_clay_stained_magenta", + "displayName": "Magenta Terracotta" + }, + { + "internalName": "hardened_clay_stained_orange", + "displayName": "Orange Terracotta" + }, + { + "internalName": "hardened_clay_stained_pink", + "displayName": "Pink Terracotta" + }, + { + "internalName": "hardened_clay_stained_purple", + "displayName": "Purple Terracotta" + }, + { + "internalName": "hardened_clay_stained_red", + "displayName": "Red Terracotta" + }, + { + "internalName": "hardened_clay_stained_silver", + "displayName": "Light Gray Terracotta" + }, + { + "internalName": "hardened_clay_stained_white", + "displayName": "White Terracotta" + }, + { + "internalName": "hardened_clay_stained_yellow", + "displayName": "Yellow Terracotta" + }, + { + "internalName": "glass_black", + "displayName": "Black Stained Glass" + }, + { + "internalName": "glass_blue", + "displayName": "Blue Stained Glass" + }, + { + "internalName": "glass_brown", + "displayName": "Brown Stained Glass" + }, + { + "internalName": "glass_cyan", + "displayName": "Cyan Stained Glass" + }, + { + "internalName": "glass_gray", + "displayName": "Gray Stained Glass" + }, + { + "internalName": "glass_green", + "displayName": "Green Stained Glass" + }, + { + "internalName": "glass_light_blue", + "displayName": "Light Blue Stained Glass" + }, + { + "internalName": "glass_lime", + "displayName": "Lime Stained Glass" + }, + { + "internalName": "glass_magenta", + "displayName": "Magenta Stained Glass" + }, + { + "internalName": "glass_orange", + "displayName": "Orange Stained Glass" + }, + { + "internalName": "glass_pink", + "displayName": "Pink Stained Glass" + }, + { + "internalName": "glass_purple", + "displayName": "Purple Stained Glass" + }, + { + "internalName": "glass_red", + "displayName": "Red Stained Glass" + }, + { + "internalName": "glass_silver", + "displayName": "Light Gray Stained Glass" + }, + { + "internalName": "glass_white", + "displayName": "White Stained Glass" + }, + { + "internalName": "glass_yellow", + "displayName": "Yellow Stained Glass" + }, + { + "internalName": "glass_pane_top_black", + "displayName": "Black Stained Glass Pane (Top)" + }, + { + "internalName": "glass_pane_top_blue", + "displayName": "Blue Stained Glass Pane (Top)" + }, + { + "internalName": "glass_pane_top_brown", + "displayName": "Brown Stained Glass Pane (Top)" + }, + { + "internalName": "glass_pane_top_cyan", + "displayName": "Cyan Stained Glass Pane (Top)" + }, + { + "internalName": "glass_pane_top_gray", + "displayName": "Gray Stained Glass Pane (Top)" + }, + { + "internalName": "glass_pane_top_green", + "displayName": "Green Stained Glass Pane (Top)" + }, + { + "internalName": "glass_pane_top_light_blue", + "displayName": "Light Blue Stained Glass Pane (Top)" + }, + { + "internalName": "glass_pane_top_lime", + "displayName": "Lime Stained Glass Pane (Top)" + }, + { + "internalName": "glass_pane_top_magenta", + "displayName": "Magenta Stained Glass Pane (Top)" + }, + { + "internalName": "glass_pane_top_orange", + "displayName": "Orange Stained Glass Pane (Top)" + }, + { + "internalName": "glass_pane_top_pink", + "displayName": "Pink Stained Glass Pane (Top)" + }, + { + "internalName": "glass_pane_top_purple", + "displayName": "Purple Stained Glass Pane (Top)" + }, + { + "internalName": "glass_pane_top_red", + "displayName": "Red Stained Glass Pane (Top)" + }, + { + "internalName": "glass_pane_top_silver", + "displayName": "Light Gray Stained Glass Pane (Top)" + }, + { + "internalName": "glass_pane_top_white", + "displayName": "White Stained Glass Pane (Top)" + }, + { + "internalName": "glass_pane_top_yellow", + "displayName": "Yellow Stained Glass Pane (Top)" + }, + { + "internalName": "double_plant_fern_top", + "displayName": "Large Fern (Top)", + + "colourEntry": { + "defaultName": "Grass_Common", + "variants": [ + "Grass_Common", + "Grass_Mesa", + "Grass_Swamp1", + "Grass_Swamp2" + ] + } + }, + { + "internalName": "double_plant_grass_top", + "displayName": "Double Tall Grass (Top)", + + "colourEntry": { + "defaultName": "Grass_Common", + "variants": [ + "Grass_Common", + "Grass_Mesa", + "Grass_Swamp1", + "Grass_Swamp2" + ] + } + }, + { + "internalName": "double_plant_paeonia_top", + "displayName": "Peony (Top)" + }, + { + "internalName": "double_plant_rose_top", + "displayName": "Rose Bush (Top)" + }, + { + "internalName": "double_plant_syringa_top", + "displayName": "Lilac (Top)" + }, + { + "internalName": "flower_tulip_orange", + "displayName": "Orange Tulip" + }, + { + "internalName": "double_plant_sunflower_top", + "displayName": "Sunflower (Top)" + }, + { + "internalName": "double_plant_sunflower_front", + "displayName": "Sunflower (Front)" + }, + { + "internalName": "log_acacia", + "displayName": "Acacia Wood (Side)" + }, + { + "internalName": "log_acacia_top", + "displayName": "Acacia Wood (Top)" + }, + { + "internalName": "planks_acacia", + "displayName": "Acacia Planks" + }, + { + "internalName": "leaves_acacia", + "displayName": "Acacia Leaves", + + "colourEntry": { + "defaultName": "Foliage_Default", + "variants": [ + "Foliage_Default", + "Foliage_Evergreen", + "Foliage_Birch", + "Foliage_Mesa", + "Foliage_Swampland" + ] + } + }, + { + "internalName": "leaves_acacia_fast", + "displayName": "Acacia Leaves (Opaque)", + + "colourEntry": { + "defaultName": "Foliage_Default", + "variants": [ + "Foliage_Default", + "Foliage_Evergreen", + "Foliage_Birch", + "Foliage_Mesa", + "Foliage_Swampland" + ] + } + }, + { + "internalName": "prismarine_bricks", + "displayName": "Prismarine Bricks" + }, + { + "internalName": "red_sand", + "displayName": "Red Sand" + }, + { + "internalName": "red_sandstone_top", + "displayName": "Red Sandstone (Top)" + }, + { + "internalName": "double_plant_fern_bottom", + "displayName": "Large Fern (Bottom)", + + "colourEntry": { + "defaultName": "Grass_Common", + "variants": [ + "Grass_Common", + "Grass_Mesa", + "Grass_Swamp1", + "Grass_Swamp2" + ] + } + }, + { + "internalName": "double_plant_grass_bottom", + "displayName": "Double Tall Grass (Bottom)", + + "colourEntry": { + "defaultName": "Grass_Common", + "variants": [ + "Grass_Common", + "Grass_Mesa", + "Grass_Swamp1", + "Grass_Swamp2" + ] + } + }, + { + "internalName": "double_plant_paeonia_bottom", + "displayName": "Peony (Bottom)" + }, + { + "internalName": "double_plant_rose_bottom", + "displayName": "Rose Bush (Bottom)" + }, + { + "internalName": "double_plant_syringa_bottom", + "displayName": "Lilac (Bottom)" + }, + { + "internalName": "flower_tulip_pink", + "displayName": "Pink Tulip" + }, + { + "internalName": "double_plant_sunflower_bottom", + "displayName": "Sunflower (Bottom)" + }, + { + "internalName": "double_plant_sunflower_back", + "displayName": "Sunflower (Back)" + }, + { + "internalName": "log_big_oak", + "displayName": "Dark Oak Wood (Side)" + }, + { + "internalName": "log_big_oak_top", + "displayName": "Dark Oak Wood (Top)" + }, + { + "internalName": "planks_big_oak", + "displayName": "Dark Oak Planks" + }, + { + "internalName": "leaves_big_oak", + "displayName": "Dark Oak Leaves", + + "colourEntry": { + "defaultName": "Foliage_Default", + "variants": [ + "Foliage_Default", + "Foliage_Evergreen", + "Foliage_Birch", + "Foliage_Mesa", + "Foliage_Swampland" + ] + } + }, + { + "internalName": "leaves_big_oak_fast", + "displayName": "Dark Oak Leaves (Opaque)", + + "colourEntry": { + "defaultName": "Foliage_Default", + "variants": [ + "Foliage_Default", + "Foliage_Evergreen", + "Foliage_Birch", + "Foliage_Mesa", + "Foliage_Swampland" + ] + } + }, + { + "internalName": "prismarine_dark", + "displayName": "Dark Prismarine" + }, + { + "internalName": "red_sandstone_bottom", + "displayName": "Red Sandstone (Bottom)" + }, + { + "internalName": "red_sandstone_normal", + "displayName": "Red Sandstone (Side)" + }, + { + "internalName": "flower_alium", + "displayName": "Allium" + }, + { + "internalName": "flower_blue_orchid", + "displayName": "Blue Orchid" + }, + { + "internalName": "flower_houstonia", + "displayName": "Azure Bluet" + }, + { + "internalName": "flower_oxeye_daisy", + "displayName": "Oxeye Daisy" + }, + { + "internalName": "flower_tulip_red", + "displayName": "Red Tulip" + }, + { + "internalName": "flower_tulip_white", + "displayName": "White Tulip" + }, + { + "internalName": "sapling_acacia", + "displayName": "Acacia Sapling" + }, + { + "internalName": "sapling_roofed_oak", + "displayName": "Dark Oak Sapling" + }, + { + "internalName": "coarse_dirt", + "displayName": "Coarse Dirt" + }, + { + "internalName": "dirt_podzol_side", + "displayName": "Podzol (Side)" + }, + { + "internalName": "dirt_podzol_top", + "displayName": "Podzol (Top)" + }, + { + "internalName": "leaves_birch", + "displayName": "Birch Leaves", + + "colourEntry": { + "defaultName": "Foliage_Birch", + "variants": [ + "Foliage_Default", + "Foliage_Evergreen", + "Foliage_Birch", + "Foliage_Mesa", + "Foliage_Swampland" + ] + } + }, + { + "internalName": "leaves_birch_fast", + "displayName": "Birch Leaves (Opaque)", + + "colourEntry": { + "defaultName": "Foliage_Birch", + "variants": [ + "Foliage_Default", + "Foliage_Evergreen", + "Foliage_Birch", + "Foliage_Mesa", + "Foliage_Swampland" + ] + } + }, + { + "internalName": "prismarine_rough", + "displayName": "Prismarine" + }, + { + "internalName": "red_sandstone_carved", + "displayName": "Chiseled Red Sandstone" + }, + { + "internalName": "red_sandstone_smooth", + "displayName": "Smooth Red Standstone" + }, + { + "internalName": "door_acacia_upper", + "displayName": "Acacia Door (Top)" + }, + { + "internalName": "door_birch_upper", + "displayName": "Birch Door (Top)" + }, + { + "internalName": "door_dark_oak_upper", + "displayName": "Dark Oak Door (Top)" + }, + { + "internalName": "door_jungle_upper", + "displayName": "Jungle Door (Top)" + }, + { + "internalName": "door_spruce_upper", + "displayName": "Spruce Door (Top)" + }, + { + "internalName": "chorus_flower", + "displayName": "Chorus Flower" + }, + { + "internalName": "chorus_flower_dead", + "displayName": "Chorus Flower (Dead)" + }, + { + "internalName": "chorus_flower_plant", + "displayName": "Chorus Plant" + }, + { + "internalName": "end_bricks", + "displayName": "End Stone Bricks" + }, + { + "internalName": "grass_path_side", + "displayName": "Grass Path (Side)" + }, + { + "internalName": "grass_path_top", + "displayName": "Grass Path (Top)" + }, + { + "internalName": "barrier", + "displayName": "Barrier" + }, + { + "internalName": "ice_packed", + "displayName": "Packed Ice" + }, + { + "internalName": "sea_lantern", + "displayName": "Sea Lantern" + }, + { + "internalName": "daylight_detector_inverted_top", + "displayName": "Daylight Sensor (Inverted) (Top)" + }, + { + "internalName": "iron_trapdoor", + "displayName": "Iron Trapdoor" + }, + { + "internalName": "door_acacia_lower", + "displayName": "Acacia Door (Bottom)" + }, + { + "internalName": "door_birch_lower", + "displayName": "Birch Door (Bottom)" + }, + { + "internalName": "door_dark_oak_lower", + "displayName": "Dark Oak Door (Bottom)" + }, + { + "internalName": "door_jungle_lower", + "displayName": "Jungle Door (Bottom)" + }, + { + "internalName": "door_spruce_lower", + "displayName": "Spruce Door (Bottom)" + }, + { + "internalName": "purpur_block", + "displayName": "Purpur Block" + }, + { + "internalName": "purpur_pillar", + "displayName": "Purpur Pillar (Side)" + }, + { + "internalName": "purpur_pillar_top", + "displayName": "Purpur Pillar (Top)" + }, + { + "internalName": "end_rod", + "displayName": "End Rod" + }, + { + "internalName": "magma", + "displayName": "Magma Block" + }, + { + "internalName": "nether_wart_block", + "displayName": "Nether Wart Block" + }, + { + "internalName": "red_nether_brick", + "displayName": "Red Nether Brick" + }, + { + "internalName": "frosted_ice_0", + "displayName": "Frosted Ice (Stage 1)" + }, + { + "internalName": "frosted_ice_1", + "displayName": "Frosted Ice (Stage 2)" + }, + { + "internalName": "frosted_ice_2", + "displayName": "Frosted Ice (Stage 3)" + }, + { + "internalName": "frosted_ice_3", + "displayName": "Frosted Ice (Stage 4)" + }, + { + "internalName": "beetroots_stage_0", + "displayName": "Beetroots (Stage 1)" + }, + { + "internalName": "beetroots_stage_1", + "displayName": "Beetroots (Stage 2)" + }, + { + "internalName": "beetroots_stage_2", + "displayName": "Beetroots (Stage 3)" + }, + { + "internalName": "beetroots_stage_3", + "displayName": "Beetroots (Stage 4)" + }, + { + "internalName": "chain_command_block_back", + "displayName": "Chain Command Block (Back)" + }, + { + "internalName": "chain_command_block_conditional", + "displayName": "Chain Command Block (Conditional) (Side)" + }, + { + "internalName": "chain_command_block_front", + "displayName": "Chain Command Block (Front)" + }, + { + "internalName": "chain_command_block_side", + "displayName": "Chain Command Block (Side)" + }, + { + "internalName": "command_block_back", + "displayName": "Command Block (Back)" + }, + { + "internalName": "command_block_conditional", + "displayName": "Command Block (Conditional) (Side)" + }, + { + "internalName": "command_block_front", + "displayName": "Command Block (Front)" + }, + { + "internalName": "command_block_side", + "displayName": "Command Block (Side)" + }, + { + "internalName": "repeating_command_block_back", + "displayName": "Repeating Command Block (Back)" + }, + { + "internalName": "repeating_command_block_conditional", + "displayName": "Repeating Command Block (Conditional) (Side)" + }, + { + "internalName": "repeating_command_block_front", + "displayName": "Repeating Command Block (Front)" + }, + { + "internalName": "repeating_command_block_side", + "displayName": "Repeating Command Block (Side)" + }, + { + "internalName": "bone_block_side", + "displayName": "Bone Block (Side)" + }, + { + "internalName": "bone_block_top", + "displayName": "Bone Block (Top)" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "observer_front", + "displayName": "Observer (Front)" + }, + { + "internalName": "observer_side", + "displayName": "Observer (Side)" + }, + { + "internalName": "observer_back", + "displayName": "Observer (Back)" + }, + { + "internalName": "observer_back_lit", + "displayName": "Observer (On) (Back)" + }, + { + "internalName": "observer_top", + "displayName": "Observer (Top and Bottom)" + }, + { + "internalName": "goldRing", + "displayName": "Gold Score Ring" + }, + { + "internalName": "emeraldRing", + "displayName": "Emerald Score Ring" + }, + { + "internalName": "structure_block", + "displayName": "Structure Block" + }, + { + "internalName": "structure_block_corner", + "displayName": "Structure Block (Corner)" + }, + { + "internalName": "structure_block_data", + "displayName": "Structure Block (Data)" + }, + { + "internalName": "structure_block_load", + "displayName": "Structure Block (Load)" + }, + { + "internalName": "structure_block_save", + "displayName": "Structure Block (Save)" + }, + { + "internalName": "concrete_black", + "displayName": "Black Concrete" + }, + { + "internalName": "concrete_blue", + "displayName": "Blue Concrete" + }, + { + "internalName": "concrete_brown", + "displayName": "Brown Concrete" + }, + { + "internalName": "concrete_cyan", + "displayName": "Cyan Concrete" + }, + { + "internalName": "concrete_gray", + "displayName": "Gray Concrete" + }, + { + "internalName": "concrete_green", + "displayName": "Green Concrete" + }, + { + "internalName": "concrete_light_blue", + "displayName": "Light Blue Concrete" + }, + { + "internalName": "concrete_lime", + "displayName": "Lime Concrete" + }, + { + "internalName": "concrete_magenta", + "displayName": "Magenta Concrete" + }, + { + "internalName": "concrete_orange", + "displayName": "Orange Concrete" + }, + { + "internalName": "concrete_pink", + "displayName": "Pink Concrete" + }, + { + "internalName": "concrete_purple", + "displayName": "Purple Concrete" + }, + { + "internalName": "concrete_red", + "displayName": "Red Concrete" + }, + { + "internalName": "concrete_silver", + "displayName": "Light Gray Concrete" + }, + { + "internalName": "concrete_white", + "displayName": "White Concrete" + }, + { + "internalName": "concrete_yellow", + "displayName": "Yellow Concrete" + }, + { + "internalName": "concrete_powder_black", + "displayName": "Black Concrete Powder" + }, + { + "internalName": "concrete_powder_blue", + "displayName": "Blue Concrete Powder" + }, + { + "internalName": "concrete_powder_brown", + "displayName": "Brown Concrete Powder" + }, + { + "internalName": "concrete_powder_cyan", + "displayName": "Cyan Concrete Powder" + }, + { + "internalName": "concrete_powder_gray", + "displayName": "Gray Concrete Powder" + }, + { + "internalName": "concrete_powder_green", + "displayName": "Green Concrete Powder" + }, + { + "internalName": "concrete_powder_light_blue", + "displayName": "Light Blue Concrete Powder" + }, + { + "internalName": "concrete_powder_lime", + "displayName": "Lime Concrete Powder" + }, + { + "internalName": "concrete_powder_magenta", + "displayName": "Magenta Concrete Powder" + }, + { + "internalName": "concrete_powder_orange", + "displayName": "Orange Concrete Powder" + }, + { + "internalName": "concrete_powder_pink", + "displayName": "Pink Concrete Powder" + }, + { + "internalName": "concrete_powder_purple", + "displayName": "Purple Concrete Powder" + }, + { + "internalName": "concrete_powder_red", + "displayName": "Red Concrete Powder" + }, + { + "internalName": "concrete_powder_silver", + "displayName": "Light Gray Concrete Powder" + }, + { + "internalName": "concrete_powder_white", + "displayName": "White Concrete Powder" + }, + { + "internalName": "concrete_powder_yellow", + "displayName": "Yellow Concrete Powder" + }, + { + "internalName": "glazed_terracotta_black", + "displayName": "Black Glazed Terracotta" + }, + { + "internalName": "glazed_terracotta_blue", + "displayName": "Blue Glazed Terracotta" + }, + { + "internalName": "glazed_terracotta_brown", + "displayName": "Brown Glazed Terracotta" + }, + { + "internalName": "glazed_terracotta_cyan", + "displayName": "Cyan Glazed Terracotta" + }, + { + "internalName": "glazed_terracotta_gray", + "displayName": "Gray Glazed Terracotta" + }, + { + "internalName": "glazed_terracotta_green", + "displayName": "Green Glazed Terracotta" + }, + { + "internalName": "glazed_terracotta_light_blue", + "displayName": "Light Blue Glazed Terracotta" + }, + { + "internalName": "glazed_terracotta_lime", + "displayName": "Lime Glazed Terracotta" + }, + { + "internalName": "glazed_terracotta_magenta", + "displayName": "Magenta Glazed Terracotta" + }, + { + "internalName": "glazed_terracotta_orange", + "displayName": "Orange Glazed Terracotta" + }, + { + "internalName": "glazed_terracotta_pink", + "displayName": "Pink Glazed Terracotta" + }, + { + "internalName": "glazed_terracotta_purple", + "displayName": "Purple Glazed Terracotta" + }, + { + "internalName": "glazed_terracotta_red", + "displayName": "Red Glazed Terracotta" + }, + { + "internalName": "glazed_terracotta_silver", + "displayName": "Light Gray Glazed Terracotta" + }, + { + "internalName": "glazed_terracotta_white", + "displayName": "White Glazed Terracotta" + }, + { + "internalName": "glazed_terracotta_yellow", + "displayName": "Yellow Glazed Terracotta" + }, + { + "internalName": "shulker_top", + "displayName": "Shulker Box (Break Particles)", + + "colourEntry": { + "defaultName": "Shulker_Box_Purple", + "variants": [ + "Shulker_Box_Black", + "Shulker_Box_Blue", + "Shulker_Box_Brown", + "Shulker_Box_Cyan", + "Shulker_Box_Grey", + "Shulker_Box_Green", + "Shulker_Box_Light_Blue", + "Shulker_Box_Light_Green", + "Shulker_Box_Magenta", + "Shulker_Box_Orange", + "Shulker_Box_Pink", + "Shulker_Box_Purple", + "Shulker_Box_Red", + "Shulker_Box_Silver", + "Shulker_Box_White", + "Shulker_Box_Yellow" + ] + } + }, + { + "internalName": "shulker_top_overlay", + "displayName": "Shulker Box (Break Particles) (Overlay) (Unused)" + }, + { + "internalName": "cauldron_water", + "displayName": "Cauldron Water", + "allowCustomColour": true, + + "colourEntry": { + "defaultName": "Cauldron_Water", + "variants": [ + "Cauldron_Water", + "Effect_MovementSpeed", + "Effect_MovementSlowDown", + "Effect_DigSpeed", + "Effect_DigSlowdown", + "Effect_DamageBoost", + "Effect_Heal", + "Effect_Harm", + "Effect_Jump", + "Effect_Confusion", + "Effect_Regeneration", + "Effect_DamageResistance", + "Effect_FireResistance", + "Effect_WaterBreathing", + "Effect_Invisibility", + "Effect_Blindness", + "Effect_NightVision", + "Effect_Hunger", + "Effect_Weakness", + "Effect_Poison", + "Effect_Wither", + "Effect_HealthBoost", + "Effect_Absorption", + "Effect_Saturation", + "Effect_Levitation", + "Effect_Luck", + "Effect_BadLuck", + "Effect_TurtleMaster", + "Effect_SlowFall" + ] + } + }, + { + "internalName": "seagrass_doubletall_top", + "displayName": "Double Tall Seagrass (Top)" + }, + { + "internalName": "coral_blue", + "displayName": "Tube Coral Block" + }, + { + "internalName": "coral_purple", + "displayName": "Bubble Coral Block" + }, + { + "internalName": "coral_pink", + "displayName": "Brain Coral Block" + }, + { + "internalName": "coral_red", + "displayName": "Fire Coral Block" + }, + { + "internalName": "coral_yellow", + "displayName": "Horn Coral Block" + }, + { + "internalName": "coral_plant_blue", + "displayName": "Tube Coral" + }, + { + "internalName": "coral_plant_purple", + "displayName": "Bubble Coral" + }, + { + "internalName": "coral_plant_pink", + "displayName": "Brain Coral" + }, + { + "internalName": "coral_plant_red", + "displayName": "Fire Coral" + }, + { + "internalName": "coral_plant_yellow", + "displayName": "Horn Coral" + }, + { + "internalName": "sea_pickle", + "displayName": "Sea Pickle" + }, + { + "internalName": "blue_ice", + "displayName": "Blue Ice" + }, + { + "internalName": "dried_kelp_top", + "displayName": "Dried Kelp Block (Top)" + }, + { + "internalName": "dried_kelp_side", + "displayName": "Dried Kelp Block (Side)" + }, + { + "internalName": "seagrass_carried", + "displayName": "Seagrass (Item)" + }, + { + "internalName": "seagrass_doubletall_bottom", + "displayName": "Double Tall Seagrass (Bottom)" + }, + { + "internalName": "coral_blue_dead", + "displayName": "Dead Tube Coral Block" + }, + { + "internalName": "coral_purple_dead", + "displayName": "Dead Bubble Coral Block" + }, + { + "internalName": "coral_pink_dead", + "displayName": "Dead Brain Coral Block" + }, + { + "internalName": "coral_red_dead", + "displayName": "Dead Fire Coral Block" + }, + { + "internalName": "coral_yellow_dead", + "displayName": "Dead Horn Coral Block" + }, + { + "internalName": "coral_fan_blue", + "displayName": "Tube Coral Fan" + }, + { + "internalName": "coral_fan_purple", + "displayName": "Bubble Coral Fan" + }, + { + "internalName": "coral_fan_pink", + "displayName": "Brain Coral Fan" + }, + { + "internalName": "coral_fan_red", + "displayName": "Fire Coral Fan" + }, + { + "internalName": "coral_fan_yellow", + "displayName": "Horn Coral Fan" + }, + { + "internalName": "bamboo_stem", + "displayName": "Bamboo (Stem) [PS4 ONLY]" + }, + { + "internalName": "bamboo_leaf_small", + "displayName": "Bamboo (Small Leaves) [PS4 ONLY]" + }, + { + "internalName": "kelp_a", + "displayName": "Kelp (Bottom)" + }, + { + "internalName": "kelp_a", + "displayName": "" + }, + { + "internalName": "kelp_a", + "displayName": "" + }, + { + "internalName": "kelp_a", + "displayName": "" + }, + { + "internalName": "kelp_top_a", + "displayName": "Kelp (Top)" + }, + { + "internalName": "kelp_top_a", + "displayName": "" + }, + { + "internalName": "kelp_top_a", + "displayName": "" + }, + { + "internalName": "kelp_top_a", + "displayName": "" + }, + { + "internalName": "seagrass", + "displayName": "Seagrass" + }, + { + "internalName": "coral_fan_blue_dead", + "displayName": "Dead Tube Coral Fan" + }, + { + "internalName": "coral_fan_purple_dead", + "displayName": "Dead Bubble Coral Fan" + }, + { + "internalName": "coral_fan_pink_dead", + "displayName": "Dead Brain Coral Fan" + }, + { + "internalName": "coral_fan_red_dead", + "displayName": "Dead Fire Coral Fan" + }, + { + "internalName": "coral_fan_yellow_dead", + "displayName": "Dead Horn Coral Fan" + }, + { + "internalName": "bamboo_leaf", + "displayName": "Bamboo (Leaves) [PS4 ONLY]" + }, + { + "internalName": "spruce_trapdoor", + "displayName": "Spruce Trapdoor" + }, + { + "internalName": "stripped_log_oak", + "displayName": "Stripped Oak Log (Side)" + }, + { + "internalName": "stripped_log_oak_top", + "displayName": "Stripped Oak Log (Top)" + }, + { + "internalName": "stripped_log_acacia", + "displayName": "Stripped Acacia Log (Side)" + }, + { + "internalName": "stripped_log_acacia_top", + "displayName": "Stripped Acacia Log (Top)" + }, + { + "internalName": "stripped_log_birch", + "displayName": "Stripped Birch Log (Side)" + }, + { + "internalName": "stripped_log_birch_top", + "displayName": "Stripped Birch Log (Top)" + }, + { + "internalName": "stripped_log_dark_oak", + "displayName": "Stripped Dark Oak Log (Side)" + }, + { + "internalName": "stripped_log_dark_oak_top", + "displayName": "Stripped Dark Oak Log (Top)" + }, + { + "internalName": "stripped_log_jungle", + "displayName": "Stripped Jungle Log (Side)" + }, + { + "internalName": "stripped_log_jungle_top", + "displayName": "Stripped Birch Log (Top)" + }, + { + "internalName": "stripped_log_spruce", + "displayName": "Stripped Spruce Log (Side)" + }, + { + "internalName": "stripped_log_spruce_top", + "displayName": "Stripped Spruce Log (Top)" + }, + { + "internalName": "acacia_trapdoor", + "displayName": "Acacia Trapdoor" + }, + { + "internalName": "birch_trapdoor", + "displayName": "Birch Trapdoor" + }, + { + "internalName": "dark_oak_trapdoor", + "displayName": "Dark Oak Trapdoor" + }, + { + "internalName": "jungle_trapdoor", + "displayName": "Jungle Trapdoor" + }, + { + "internalName": "bamboo_sapling", + "displayName": "Bamboo Sapling [PS4 ONLY]" + }, + { + "internalName": "bamboo_singleleaf", + "displayName": "Bamboo (Single Leaf) [PS4 ONLY]" + }, + { + "internalName": "flower_lily_of_the_valley", + "displayName": "Lily of the Valley [PS4 ONLY]" + }, + { + "internalName": "flower_cornflower", + "displayName": "Cornflower [PS4 ONLY]" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "berry_bush_sapling", + "displayName": "Sweet Berry Bush (Stage 1) [PS4 ONLY]" + }, + { + "internalName": "berry_bush_no_berries", + "displayName": "Sweet Berry Bush (Stage 2) [PS4 ONLY]" + }, + { + "internalName": "berry_bush_some_berries", + "displayName": "Sweet Berry Bush (Stage 3) [PS4 ONLY]" + }, + { + "internalName": "berry_bush_full_berries", + "displayName": "Sweet Berry Bush (Stage 4) [PS4 ONLY]" + }, + { + "internalName": "campfire_log", + "displayName": "Campfire (Log) [PS4 ONLY]" + }, + { + "internalName": "campfire_log_lit", + "displayName": "Campfire (Log) (Lit) [PS4 ONLY]" + }, + { + "internalName": "campfire_smoke", + "displayName": "Campfire (Smoke) [PS4 ONLY]" + }, + { + "internalName": "campfire", + "displayName": "Campfire (Flame) [PS4 ONLY]" + }, + { + "internalName": "scaffolding_side", + "displayName": "Scaffolding (Side) [PS4 ONLY]" + }, + { + "internalName": "scaffolding_bottom", + "displayName": "Scaffolding (Bottom) [PS4 ONLY]" + }, + { + "internalName": "scaffolding_top", + "displayName": "Scaffolding (Top) [PS4 ONLY]" + }, + { + "internalName": "barrel_side", + "displayName": "Barrel (Side) [PS4 ONLY]" + }, + { + "internalName": "barrel_top", + "displayName": "Barrel (Top) [PS4 ONLY]" + }, + { + "internalName": "barrel_bottom", + "displayName": "Barrel (Bottom) [PS4 ONLY]" + }, + { + "internalName": "bell_side", + "displayName": "Bell (Side) [PS4 ONLY]" + }, + { + "internalName": "bell_top", + "displayName": "Bell (Top) [PS4 ONLY]" + }, + { + "internalName": "bell_bottom", + "displayName": "Bell (Bottom) [PS4 ONLY]" + }, + { + "internalName": "lantern", + "displayName": "Lantern [PS4 ONLY]" + }, + { + "internalName": "jigsaw_side", + "displayName": "Jigsaw (Side) [PS4 ONLY]" + }, + { + "internalName": "jigsaw_top", + "displayName": "Jigsaw (Top) [PS4 ONLY]" + }, + { + "internalName": "blast_furnace_front", + "displayName": "Blast Furnace (Front) [PS4 ONLY]" + }, + { + "internalName": "blast_furnace_front_on", + "displayName": "Blast Furnace (Front) (Lit) [PS4 ONLY]" + }, + { + "internalName": "blast_furnace_side", + "displayName": "Blast Furnace (Side) [PS4 ONLY]" + }, + { + "internalName": "blast_furnace_top", + "displayName": "Blast Furnace (Top) [PS4 ONLY]" + }, + { + "internalName": "grindstone_side", + "displayName": "Grindstone (Side) [PS4 ONLY]" + }, + { + "internalName": "grindstone_round", + "displayName": "Grindstone (Round) [PS4 ONLY]" + }, + { + "internalName": "grindstone_pivot", + "displayName": "Grindstone (Pivot) [PS4 ONLY]" + }, + { + "internalName": "cartography_table_side1", + "displayName": "Cartography Table (Back) [PS4 ONLY]" + }, + { + "internalName": "cartography_table_side2", + "displayName": "Cartography Table (Right Side) [PS4 ONLY]" + }, + { + "internalName": "cartography_table_side3", + "displayName": "Cartography Table (Front and Left Side) [PS4 ONLY]" + }, + { + "internalName": "cartography_table_top", + "displayName": "Cartography Table (Top) [PS4 ONLY]" + }, + { + "internalName": "lectern_sides", + "displayName": "Lectern (Side) [PS4 ONLY]" + }, + { + "internalName": "lectern_front", + "displayName": "Lectern (Front) [PS4 ONLY]" + }, + { + "internalName": "lectern_base", + "displayName": "Lectern (Base) [PS4 ONLY]" + }, + { + "internalName": "lectern_top", + "displayName": "Lectern (Top) [PS4 ONLY]" + }, + { + "internalName": "loom_side", + "displayName": "Loom (Side) [PS4 ONLY]" + }, + { + "internalName": "loom_front", + "displayName": "Loom (Front) [PS4 ONLY]" + }, + { + "internalName": "loom_top", + "displayName": "Loom (Top) [PS4 ONLY]" + }, + { + "internalName": "loom_bottom", + "displayName": "Loom (Bottom) [PS4 ONLY]" + }, + { + "internalName": "smithing_table_side", + "displayName": "Smithing Table (Side) [PS4 ONLY]" + }, + { + "internalName": "smithing_table_front", + "displayName": "Smithing Table (Front) [PS4 ONLY]" + }, + { + "internalName": "smithing_table_top", + "displayName": "Smithing Table (Top) [PS4 ONLY]" + }, + { + "internalName": "composter_top", + "displayName": "Composter (Top) [PS4 ONLY]" + }, + { + "internalName": "fletcher_table_side2", + "displayName": "Fletching Table (Front and Back) [PS4 ONLY]" + }, + { + "internalName": "fletcher_table_side1", + "displayName": "Fletching Table (Side) [PS4 ONLY]" + }, + { + "internalName": "fletcher_table_top", + "displayName": "Fletching Table (Top) [PS4 ONLY]" + }, + { + "internalName": "stonecutter2_saw", + "displayName": "Stonecutter (Saw) [PS4 ONLY]" + }, + { + "internalName": "stonecutter2_side", + "displayName": "Stonecutter (Side) [PS4 ONLY]" + }, + { + "internalName": "stonecutter2_top", + "displayName": "Stonecutter (Top) [PS4 ONLY]" + }, + { + "internalName": "stonecutter2_bottom", + "displayName": "Stonecutter (Bottom) [PS4 ONLY]" + }, + { + "internalName": "smoker_side", + "displayName": "Smoker (Side) [PS4 ONLY]" + }, + { + "internalName": "smoker_front", + "displayName": "Smoker (Front) [PS4 ONLY]" + }, + { + "internalName": "smoker_front_on", + "displayName": "Smoker (Front) (Lit) [PS4 ONLY]" + }, + { + "internalName": "smoker_top", + "displayName": "Smoker (Top) [PS4 ONLY]" + }, + { + "internalName": "smoker_bottom", + "displayName": "Smoker (Bottom) [PS4 ONLY]" + }, + { + "internalName": "compost", + "displayName": "Compost [PS4 ONLY]" + }, + { + "internalName": "compost_ready", + "displayName": "Compost (Ready) [PS4 ONLY]" + }, + { + "internalName": "composter_bottom", + "displayName": "Composter (Bottom) [PS4 ONLY]" + }, + { + "internalName": "composter_side", + "displayName": "Composter (Side) [PS4 ONLY]" + }, + { + "internalName": "barrel_top_open", + "displayName": "Barrel (Top) (Open) [PS4 ONLY]" + }, + { + "internalName": "smithing_table_bottom", + "displayName": "Smithing Table (Bottom) [PS4 ONLY]" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + } + ] +} diff --git a/PckStudio.Core/Resources/experienceOrbData.json b/PckStudio.Core/Resources/experienceOrbData.json new file mode 100644 index 00000000..f83a7ab3 --- /dev/null +++ b/PckStudio.Core/Resources/experienceOrbData.json @@ -0,0 +1,124 @@ +{ + "COMMENT_1": "JSON by MattNL", + "entries": [ + { + "internalName": "experience_orb_0", + "displayName": "Experience Orb (Size 1)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "experience_orb", + "variants": ["experience_orb"] + } + }, + { + "internalName": "experience_orb_1", + "displayName": "Experience Orb (Size 2)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "experience_orb", + "variants": ["experience_orb"] + } + }, + { + "internalName": "experience_orb_2", + "displayName": "Experience Orb (Size 3)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "experience_orb", + "variants": ["experience_orb"] + } + }, + { + "internalName": "experience_orb_3", + "displayName": "Experience Orb (Size 4)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "experience_orb", + "variants": ["experience_orb"] + } + }, + { + "internalName": "experience_orb_4", + "displayName": "Experience Orb (Size 5)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "experience_orb", + "variants": ["experience_orb"] + } + }, + { + "internalName": "experience_orb_5", + "displayName": "Experience Orb (Size 6)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "experience_orb", + "variants": ["experience_orb"] + } + }, + { + "internalName": "experience_orb_6", + "displayName": "Experience Orb (Size 7)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "experience_orb", + "variants": ["experience_orb"] + } + }, + { + "internalName": "experience_orb_7", + "displayName": "Experience Orb (Size 8)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "experience_orb", + "variants": ["experience_orb"] + } + }, + { + "internalName": "experience_orb_8", + "displayName": "Experience Orb (Size 9)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "experience_orb", + "variants": ["experience_orb"] + } + }, + { + "internalName": "experience_orb_9", + "displayName": "Experience Orb (Size 10)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "experience_orb", + "variants": ["experience_orb"] + } + }, + { + "internalName": "experience_orb_10", + "displayName": "Experience Orb (Size 11)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "experience_orb", + "variants": ["experience_orb"] + } + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + } + ] +} \ No newline at end of file diff --git a/PckStudio.Core/Resources/experience_orbs.png b/PckStudio.Core/Resources/experience_orbs.png new file mode 100644 index 00000000..1a2d58a3 Binary files /dev/null and b/PckStudio.Core/Resources/experience_orbs.png differ diff --git a/PckStudio.Core/Resources/explosion.png b/PckStudio.Core/Resources/explosion.png new file mode 100644 index 00000000..242d9115 Binary files /dev/null and b/PckStudio.Core/Resources/explosion.png differ diff --git a/PckStudio.Core/Resources/explosionData.json b/PckStudio.Core/Resources/explosionData.json new file mode 100644 index 00000000..f9845f7e --- /dev/null +++ b/PckStudio.Core/Resources/explosionData.json @@ -0,0 +1,197 @@ +{ + "COMMENT_1": "JSON by MattNL", + "entries": [ + { + "internalName": "explosion_0", + "displayName": "Explosion (Stage 1)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Particle_Explode", + "variants": [ + "Particle_Explode", + "Particle_HugeExplosion" + ] + } + }, + { + "internalName": "explosion_1", + "displayName": "Explosion (Stage 2)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Particle_Explode", + "variants": [ + "Particle_Explode", + "Particle_HugeExplosion" + ] + } + }, + { + "internalName": "explosion_2", + "displayName": "Explosion (Stage 3)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Particle_Explode", + "variants": [ + "Particle_Explode", + "Particle_HugeExplosion" + ] + } + }, + { + "internalName": "explosion_3", + "displayName": "Explosion (Stage 4)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Particle_Explode", + "variants": [ + "Particle_Explode", + "Particle_HugeExplosion" + ] + } + }, + { + "internalName": "explosion_4", + "displayName": "Explosion (Stage 5)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Particle_Explode", + "variants": [ + "Particle_Explode", + "Particle_HugeExplosion" + ] + } + }, + { + "internalName": "explosion_5", + "displayName": "Explosion (Stage 6)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Particle_Explode", + "variants": [ + "Particle_Explode", + "Particle_HugeExplosion" + ] + } + }, + { + "internalName": "explosion_6", + "displayName": "Explosion (Stage 7)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Particle_Explode", + "variants": [ + "Particle_Explode", + "Particle_HugeExplosion" + ] + } + }, + { + "internalName": "explosion_7", + "displayName": "Explosion (Stage 8)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Particle_Explode", + "variants": [ + "Particle_Explode", + "Particle_HugeExplosion" + ] + } + }, + { + "internalName": "explosion_8", + "displayName": "Explosion (Stage 9)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Particle_Explode", + "variants": [ + "Particle_Explode", + "Particle_HugeExplosion" + ] + } + }, + { + "internalName": "explosion_9", + "displayName": "Explosion (Stage 10)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Particle_Explode", + "variants": [ + "Particle_Explode", + "Particle_HugeExplosion" + ] + } + }, + { + "internalName": "explosion_10", + "displayName": "Explosion (Stage 11)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Particle_Explode", + "variants": [ + "Particle_Explode", + "Particle_HugeExplosion" + ] + } + }, + { + "internalName": "explosion_11", + "displayName": "Explosion (Stage 12)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Particle_Explode", + "variants": [ + "Particle_Explode", + "Particle_HugeExplosion" + ] + } + }, + { + "internalName": "explosion_12", + "displayName": "Explosion (Stage 13)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Particle_Explode", + "variants": [ + "Particle_Explode", + "Particle_HugeExplosion" + ] + } + }, + { + "internalName": "explosion_13", + "displayName": "Explosion (Stage 14)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Particle_Explode", + "variants": [ + "Particle_Explode", + "Particle_HugeExplosion" + ] + } + }, + { + "internalName": "explosion_14", + "displayName": "Explosion (Stage 15)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Particle_Explode", + "variants": [ + "Particle_Explode", + "Particle_HugeExplosion" + ] + } + }, + { + "internalName": "explosion_15", + "displayName": "Explosion (Stage 16)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Particle_Explode", + "variants": [ + "Particle_Explode", + "Particle_HugeExplosion" + ] + } + } + ] +} \ No newline at end of file diff --git a/PckStudio.Core/Resources/itemData.json b/PckStudio.Core/Resources/itemData.json new file mode 100644 index 00000000..51c380b7 --- /dev/null +++ b/PckStudio.Core/Resources/itemData.json @@ -0,0 +1,1361 @@ +{ + "COMMENT_1": "Tile data research by MattNL", + "COMMENT_2": "JSON by PhoenixARC, MattNL, and NessieHax (Miku-666)", + "entries": [ + { + "internalName": "helmetCloth", + "displayName": "Leather Cap", + "allowCustomColour": true, + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Armour_Default_Leather_Colour", + "variants": [ "Armour_Default_Leather_Colour" ] + } + }, + { + "internalName": "helmetChain", + "displayName": "Chain Helmet" + }, + { + "internalName": "helmetIron", + "displayName": "Iron Helmet" + }, + { + "internalName": "helmetDiamond", + "displayName": "Diamond Helmet" + }, + { + "internalName": "helmetGold", + "displayName": "Golden Helmet" + }, + { + "internalName": "flintAndSteel", + "displayName": "Flint and Steel" + }, + { + "internalName": "flint", + "displayName": "Flint" + }, + { + "internalName": "coal", + "displayName": "Coal" + }, + { + "internalName": "string", + "displayName": "String" + }, + { + "internalName": "seeds", + "displayName": "Seeds" + }, + { + "internalName": "apple", + "displayName": "Apple" + }, + { + "internalName": "appleGold", + "displayName": "Golden Apple" + }, + { + "internalName": "egg", + "displayName": "Egg" + }, + { + "internalName": "sugar", + "displayName": "Sugar" + }, + { + "internalName": "snowball", + "displayName": "Snowball" + }, + { + "internalName": "elytra", + "displayName": "Elytra" + }, + { + "internalName": "chestplateCloth", + "displayName": "Leather Tunic", + "allowCustomColour": true, + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Armour_Default_Leather_Colour", + "variants": [ "Armour_Default_Leather_Colour" ] + } + }, + { + "internalName": "chestplateChain", + "displayName": "Chain Chestplate" + }, + { + "internalName": "chestplateIron", + "displayName": "Iron Chestplate" + }, + { + "internalName": "chestplateDiamond", + "displayName": "Diamond Chestplate" + }, + { + "internalName": "chestplateGold", + "displayName": "Golden Chestplate" + }, + { + "internalName": "bow", + "displayName": "Bow" + }, + { + "internalName": "brick", + "displayName": "Brick" + }, + { + "internalName": "ingotIron", + "displayName": "Iron Ingot" + }, + { + "internalName": "feather", + "displayName": "Feather" + }, + { + "internalName": "wheat", + "displayName": "Wheat" + }, + { + "internalName": "painting", + "displayName": "Painting" + }, + { + "internalName": "reeds", + "displayName": "Sugar Canes" + }, + { + "internalName": "bone", + "displayName": "Bone" + }, + { + "internalName": "cake", + "displayName": "Cake" + }, + { + "internalName": "slimeball", + "displayName": "Slimeball" + }, + { + "internalName": "broken_elytra", + "displayName": "Elytra (Broken)" + }, + { + "internalName": "leggingsCloth", + "displayName": "Leather Pants", + "allowCustomColour": true, + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Armour_Default_Leather_Colour", + "variants": [ "Armour_Default_Leather_Colour" ] + } + }, + { + "internalName": "leggingsChain", + "displayName": "Chain Leggings" + }, + { + "internalName": "leggingsIron", + "displayName": "Iron Leggings" + }, + { + "internalName": "leggingsDiamond", + "displayName": "Diamond Leggings" + }, + { + "internalName": "leggingsGold", + "displayName": "Golden Leggings" + }, + { + "internalName": "arrow", + "displayName": "Arrow" + }, + { + "internalName": "end_crystal", + "displayName": "End Crystal" + }, + { + "internalName": "ingotGold", + "displayName": "Gold Ingot" + }, + { + "internalName": "sulphur", + "displayName": "Gunpowder" + }, + { + "internalName": "bread", + "displayName": "Bread" + }, + { + "internalName": "sign", + "displayName": "Oak Sign" + }, + { + "internalName": "doorWood", + "displayName": "Oak Door" + }, + { + "internalName": "doorIron", + "displayName": "Iron Door" + }, + { + "internalName": "bed", + "displayName": "Bed" + }, + { + "internalName": "fireball", + "displayName": "Fire Charge" + }, + { + "internalName": "chorus_fruit", + "displayName": "Chorus Fruit" + }, + { + "internalName": "bootsCloth", + "displayName": "Leather Boots", + "allowCustomColour": true, + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Armour_Default_Leather_Colour", + "variants": [ "Armour_Default_Leather_Colour" ] + } + }, + { + "internalName": "bootsChain", + "displayName": "Chain Boots" + }, + { + "internalName": "bootsIron", + "displayName": "Iron Boots" + }, + { + "internalName": "bootsDiamond", + "displayName": "Diamond Boots" + }, + { + "internalName": "bootsGold", + "displayName": "Golden Boots" + }, + { + "internalName": "stick", + "displayName": "Stick" + }, + { + "internalName": "compass", + "displayName": "Compass" + }, + { + "internalName": "diamond", + "displayName": "Diamond" + }, + { + "internalName": "redstone", + "displayName": "Redstone" + }, + { + "internalName": "clay", + "displayName": "Clay" + }, + { + "internalName": "paper", + "displayName": "Paper" + }, + { + "internalName": "book", + "displayName": "Book" + }, + { + "internalName": "map", + "displayName": "Map" + }, + { + "internalName": "seeds_pumpkin", + "displayName": "Pumpkin Seeds" + }, + { + "internalName": "seeds_melon", + "displayName": "Melon Seeds" + }, + { + "internalName": "chorus_fruit_popped", + "displayName": "Popped Chorus Fruit" + }, + { + "internalName": "swordWood", + "displayName": "Wooden Sword" + }, + { + "internalName": "swordStone", + "displayName": "Stone Sword" + }, + { + "internalName": "swordIron", + "displayName": "Iron Sword" + }, + { + "internalName": "swordDiamond", + "displayName": "Diamond Sword" + }, + { + "internalName": "swordGold", + "displayName": "Golden Sword" + }, + { + "internalName": "fishingRod_uncast", + "displayName": "Fishing Rod" + }, + { + "internalName": "clock", + "displayName": "Clock" + }, + { + "internalName": "bowl", + "displayName": "Bowl" + }, + { + "internalName": "mushroomStew", + "displayName": "Mushroom Stew" + }, + { + "internalName": "yellowDust", + "displayName": "Glowstone Dust" + }, + { + "internalName": "bucket", + "displayName": "Bucket" + }, + { + "internalName": "bucketWater", + "displayName": "Water Bucket" + }, + { + "internalName": "bucketLava", + "displayName": "Lava Bucket" + }, + { + "internalName": "milk", + "displayName": "Milk Bucket" + }, + { + "internalName": "dyePowder_black", + "displayName": "Ink Sac" + }, + { + "internalName": "dyePowder_gray", + "displayName": "Gray Dye" + }, + { + "internalName": "shovelWood", + "displayName": "Wooden Shovel" + }, + { + "internalName": "shovelStone", + "displayName": "Stone Shovel" + }, + { + "internalName": "shovelIron", + "displayName": "Iron Shovel" + }, + { + "internalName": "shovelDiamond", + "displayName": "Diamond Shovel" + }, + { + "internalName": "shovelGold", + "displayName": "Golden Shovel" + }, + { + "internalName": "fishingRod_cast", + "displayName": "Fishing Rod (Cast)" + }, + { + "internalName": "diode", + "displayName": "Redstone Repeater" + }, + { + "internalName": "porkchopRaw", + "displayName": "Raw Porkchop" + }, + { + "internalName": "porkchopCooked", + "displayName": "Cooked Porkchop" + }, + { + "internalName": "fishRaw", + "displayName": "Raw Cod" + }, + { + "internalName": "fishCooked", + "displayName": "Cooked Cod" + }, + { + "internalName": "rottenFlesh", + "displayName": "Rotten Flesh" + }, + { + "internalName": "cookie", + "displayName": "Cookie" + }, + { + "internalName": "shears", + "displayName": "Shears" + }, + { + "internalName": "dyePowder_red", + "displayName": "Rose Red" + }, + { + "internalName": "dyePowder_pink", + "displayName": "Pink Dye" + }, + { + "internalName": "pickaxeWood", + "displayName": "Wooden Pickaxe" + }, + { + "internalName": "pickaxeStone", + "displayName": "Stone Pickaxe" + }, + { + "internalName": "pickaxeIron", + "displayName": "Iron Pickaxe" + }, + { + "internalName": "pickaxeDiamond", + "displayName": "Diamond Pickaxe" + }, + { + "internalName": "pickaxeGold", + "displayName": "Golden Pickaxe" + }, + { + "internalName": "bow_pull_0", + "displayName": "Bow (Pulling Stage 1)" + }, + { + "internalName": "carrotOnAStick", + "displayName": "Carrot on a Stick" + }, + { + "internalName": "leather", + "displayName": "Leather" + }, + { + "internalName": "saddle", + "displayName": "Saddle" + }, + { + "internalName": "beefRaw", + "displayName": "Raw Beef" + }, + { + "internalName": "beefCooked", + "displayName": "Steak" + }, + { + "internalName": "enderPearl", + "displayName": "Ender Pearl" + }, + { + "internalName": "blazeRod", + "displayName": "Blaze Rod" + }, + { + "internalName": "melon", + "displayName": "Melon Slice" + }, + { + "internalName": "dyePowder_green", + "displayName": "Cactus Green" + }, + { + "internalName": "dyePowder_lime", + "displayName": "Lime Dye" + }, + { + "internalName": "hatchetWood", + "displayName": "Wooden Axe" + }, + { + "internalName": "hatchetStone", + "displayName": "Stone Axe" + }, + { + "internalName": "hatchetIron", + "displayName": "Iron Axe" + }, + { + "internalName": "hatchetDiamond", + "displayName": "Diamond Axe" + }, + { + "internalName": "hatchetGold", + "displayName": "Golden Axe" + }, + { + "internalName": "bow_pull_1", + "displayName": "Bow (Pulling Stage 2)" + }, + { + "internalName": "potatoBaked", + "displayName": "Baked Potato" + }, + { + "internalName": "potato", + "displayName": "Potato" + }, + { + "internalName": "carrots", + "displayName": "Carrot" + }, + { + "internalName": "chickenRaw", + "displayName": "Raw Chicken" + }, + { + "internalName": "chickenCooked", + "displayName": "Cooked Chicken" + }, + { + "internalName": "ghastTear", + "displayName": "Ghast Tear" + }, + { + "internalName": "goldNugget", + "displayName": "Gold Nugget" + }, + { + "internalName": "netherStalkSeeds", + "displayName": "Nether Wart" + }, + { + "internalName": "dyePowder_brown", + "displayName": "Cocoa Beans" + }, + { + "internalName": "dyePowder_yellow", + "displayName": "Dandelion Yellow" + }, + { + "internalName": "hoeWood", + "displayName": "Wooden Hoe" + }, + { + "internalName": "hoeStone", + "displayName": "Stone Hoe" + }, + { + "internalName": "hoeIron", + "displayName": "Iron Hoe" + }, + { + "internalName": "hoeDiamond", + "displayName": "Diamond Hoe" + }, + { + "internalName": "hoeGold", + "displayName": "Golden Hoe" + }, + { + "internalName": "bow_pull_2", + "displayName": "Bow (Pulling Stage 3)" + }, + { + "internalName": "potatoPoisonous", + "displayName": "Poisonous Potato" + }, + { + "internalName": "minecart", + "displayName": "Minecart" + }, + { + "internalName": "boat", + "displayName": "Oak Boat" + }, + { + "internalName": "speckledMelon", + "displayName": "Glistering Melon" + }, + { + "internalName": "fermentedSpiderEye", + "displayName": "Fermented Spider Eye" + }, + { + "internalName": "spiderEye", + "displayName": "Spider Eye" + }, + { + "internalName": "glassBottle", + "displayName": "Glass Bottle" + }, + { + "internalName": "potion_contents", + "displayName": "Potion (Overlay)", + "allowCustomColour": true, + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Potion_BaseColour", + "variants": [ + "Potion_BaseColour", + "Effect_MovementSpeed", + "Effect_MovementSlowDown", + "Effect_DigSpeed", + "Effect_DigSlowdown", + "Effect_DamageBoost", + "Effect_Heal", + "Effect_Harm", + "Effect_Jump", + "Effect_Confusion", + "Effect_Regeneration", + "Effect_DamageResistance", + "Effect_FireResistance", + "Effect_WaterBreathing", + "Effect_Invisibility", + "Effect_Blindness", + "Effect_NightVision", + "Effect_Hunger", + "Effect_Weakness", + "Effect_Poison", + "Effect_Wither", + "Effect_HealthBoost", + "Effect_Absorption", + "Effect_Saturation", + "Effect_Levitation", + "Effect_Luck", + "Effect_BadLuck", + "Effect_TurtleMaster", + "Effect_SlowFall" + ] + } + }, + { + "internalName": "dyePowder_blue", + "displayName": "Lapis Lazuli" + }, + { + "internalName": "dyePowder_light_blue", + "displayName": "Light Blue Dye" + }, + { + "internalName": "helmetCloth_overlay", + "displayName": "Leather Cap (Overlay)" + }, + { + "internalName": "spectral_arrow", + "displayName": "Spectral Arrow" + }, + { + "internalName": "iron_horse_armor", + "displayName": "Iron Horse Armor" + }, + { + "internalName": "diamond_horse_armor", + "displayName": "Diamond Horse Armor" + }, + { + "internalName": "gold_horse_armor", + "displayName": "Gold Horse Armor" + }, + { + "internalName": "comparator", + "displayName": "Redstone Comparator" + }, + { + "internalName": "carrotGolden", + "displayName": "Golden Carrot" + }, + { + "internalName": "minecart_chest", + "displayName": "Minecart with Chest" + }, + { + "internalName": "pumpkinPie", + "displayName": "Pumpkin Pie" + }, + { + "internalName": "monsterPlacer", + "displayName": "Spawn Egg", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Mob_Creeper_Colour1", + "variants": [ + "Mob_Creeper_Colour1", + "Mob_Skeleton_Colour1", + "Mob_Spider_Colour1", + "Mob_Zombie_Colour1", + "Mob_Slime_Colour1", + "Mob_Ghast_Colour1", + "Mob_PigZombie_Colour1", + "Mob_Enderman_Colour1", + "Mob_CaveSpider_Colour1", + "Mob_Silverfish_Colour1", + "Mob_Blaze_Colour1", + "Mob_LavaSlime_Colour1", + "Mob_Pig_Colour1", + "Mob_Sheep_Colour1", + "Mob_Cow_Colour1", + "Mob_Chicken_Colour1", + "Mob_Squid_Colour1", + "Mob_Wolf_Colour1", + "Mob_MushroomCow_Colour1", + "Mob_Ocelot_Colour1", + "Mob_Villager_Colour1", + "Mob_Bat_Colour1", + "Mob_Witch_Colour1", + "Mob_Horse_Colour1", + "Mob_Endermite_Color1", + "Mob_Guardian_Color1", + "Mob_Rabbit_Colour1", + "Mob_PolarBear_Colour1", + "Mob_Shulker_Colour1", + "Mob_Elder_Guardian_Colour1", + "Mob_Evocation_Illager_Colour1", + "Mob_Llama_Colour1", + "Mob_Donkey_Colour1", + "Mob_Skeleton_Horse_Colour1", + "Mob_Zombie_Horse_Colour1", + "Mob_Mule_Colour1", + "Mob_Stray_Colour1", + "Mob_Husk_Colour1", + "Mob_Vex_Colour1", + "Mob_Vindication_Illager_Colour1", + "Mob_Zombie_Villager_Colour1", + "Mob_Parrot_Colour1", + "Mob_Wither_Skeleton_Colour1", + "Mob_Turtle_Colour1", + "Mob_Tropical_Colour1", + "Mob_Cod_Colour1", + "Mob_Pufferfish_Colour1", + "Mob_Salmon_Colour1", + "Mob_Drowned_Colour1", + "Mob_Dolphin_Colour1", + "Mob_Phantom_Colour1" + ] + } + }, + { + "internalName": "potion_splash", + "displayName": "Splash Potion" + }, + { + "internalName": "eyeOfEnder", + "displayName": "Eye of Ender" + }, + { + "internalName": "cauldron", + "displayName": "Cauldron" + }, + { + "internalName": "blazePowder", + "displayName": "Blaze Powder" + }, + { + "internalName": "dyePowder_purple", + "displayName": "Purple Dye" + }, + { + "internalName": "dyePowder_magenta", + "displayName": "Magenta Dye" + }, + { + "internalName": "chestplateCloth_overlay", + "displayName": "Leather Tunic (Overlay)" + }, + { + "internalName": "tipped_arrow_base", + "displayName": "Tipped Arrow" + }, + { + "internalName": "dragon_breath", + "displayName": "Dragon's Breath" + }, + { + "internalName": "name_tag", + "displayName": "Name Tag" + }, + { + "internalName": "lead", + "displayName": "Lead" + }, + { + "internalName": "netherbrick", + "displayName": "Nether Brick" + }, + { + "internalName": "fish_clownfish_raw", + "displayName": "Tropical Fish" + }, + { + "internalName": "minecart_furnace", + "displayName": "Minecart with Furnace" + }, + { + "internalName": "charcoal", + "displayName": "Charcoal" + }, + { + "internalName": "monsterPlacer_overlay", + "displayName": "Spawn Egg (Overlay)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Mob_Creeper_Colour2", + "variants": [ + "Mob_Creeper_Colour2", + "Mob_Skeleton_Colour2", + "Mob_Spider_Colour2", + "Mob_Zombie_Colour2", + "Mob_Slime_Colour2", + "Mob_Ghast_Colour2", + "Mob_PigZombie_Colour2", + "Mob_Enderman_Colour2", + "Mob_CaveSpider_Colour2", + "Mob_Silverfish_Colour2", + "Mob_Blaze_Colour2", + "Mob_LavaSlime_Colour2", + "Mob_Pig_Colour2", + "Mob_Sheep_Colour2", + "Mob_Cow_Colour2", + "Mob_Chicken_Colour2", + "Mob_Squid_Colour2", + "Mob_Wolf_Colour2", + "Mob_MushroomCow_Colour2", + "Mob_Ocelot_Colour2", + "Mob_Villager_Colour2", + "Mob_Bat_Colour2", + "Mob_Witch_Colour2", + "Mob_Horse_Colour2", + "Mob_Endermite_Color2", + "Mob_Guardian_Color2", + "Mob_Rabbit_Colour2", + "Mob_PolarBear_Colour2", + "Mob_Shulker_Colour2", + "Mob_Elder_Guardian_Colour2", + "Mob_Evocation_Illager_Colour2", + "Mob_Llama_Colour2", + "Mob_Donkey_Colour2", + "Mob_Skeleton_Horse_Colour2", + "Mob_Zombie_Horse_Colour2", + "Mob_Mule_Colour2", + "Mob_Stray_Colour2", + "Mob_Husk_Colour2", + "Mob_Vex_Colour2", + "Mob_Vindication_Illager_Colour2", + "Mob_Zombie_Villager_Colour2", + "Mob_Parrot_Colour2", + "Mob_Wither_Skeleton_Colour2", + "Mob_Turtle_Colour2", + "Mob_Tropical_Colour2", + "Mob_Cod_Colour2", + "Mob_Pufferfish_Colour2", + "Mob_Salmon_Colour2", + "Mob_Drowned_Colour2", + "Mob_Dolphin_Colour2", + "Mob_Phantom_Colour2" + ] + } + }, + { + "internalName": "bed_overlay", + "displayName": "Bed (Overlay)", + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Bed_White", + "variants": [ + "Bed_Black", + "Bed_Blue", + "Bed_Brown", + "Bed_Cyan", + "Bed_Grey", + "Bed_Green", + "Bed_Light_Blue", + "Bed_Lime", + "Bed_Magenta", + "Bed_Orange", + "Bed_Pink", + "Bed_Purple", + "Bed_Red", + "Bed_Silver", + "Bed_White", + "Bed_Yellow" + ] + } + }, + { + "internalName": "expBottle", + "displayName": "Bottle o'Enchanting" + }, + { + "internalName": "brewingStand", + "displayName": "Brewing Stand" + }, + { + "internalName": "magmaCream", + "displayName": "Magma Cream" + }, + { + "internalName": "dyePowder_cyan", + "displayName": "Cyan Dye" + }, + { + "internalName": "dyePowder_orange", + "displayName": "Orange Dye" + }, + { + "internalName": "leggingsCloth_overlay", + "displayName": "Leather Pants (Overlay)" + }, + { + "internalName": "tipped_arrow_head", + "displayName": "Tipped Arrow (Overlay)" + }, + { + "internalName": "potion_bottle_lingering", + "displayName": "Lingering Potion" + }, + { + "internalName": "barrier", + "displayName": "debug_fourj_item" + }, + { + "internalName": "mutton_raw", + "displayName": "Raw Mutton" + }, + { + "internalName": "rabbit_raw", + "displayName": "Raw Rabbit" + }, + { + "internalName": "fish_pufferfish_raw", + "displayName": "Pufferfish" + }, + { + "internalName": "minecart_hopper", + "displayName": "Minecart with Hopper" + }, + { + "internalName": "hopper", + "displayName": "Hopper" + }, + { + "internalName": "nether_star", + "displayName": "Nether Star" + }, + { + "internalName": "emerald", + "displayName": "Emerald" + }, + { + "internalName": "writingBook", + "displayName": "Book and Quill" + }, + { + "internalName": "writtenBook", + "displayName": "Written Book" + }, + { + "internalName": "flowerPot", + "displayName": "Flower Pot" + }, + { + "internalName": "dyePowder_silver", + "displayName": "Light Gray Dye" + }, + { + "internalName": "dyePowder_white", + "displayName": "Bone Meal" + }, + { + "internalName": "bootsCloth_overlay", + "displayName": "Leather Boots (Overlay)" + }, + { + "internalName": "beetroot", + "displayName": "Beetroot" + }, + { + "internalName": "beetroot_seeds", + "displayName": "Beetroot Seeds" + }, + { + "internalName": "beetroot_soup", + "displayName": "Beetroot Soup" + }, + { + "internalName": "mutton_cooked", + "displayName": "Cooked Mutton" + }, + { + "internalName": "rabbit_cooked", + "displayName": "Cooked Rabbit" + }, + { + "internalName": "fish_salmon_raw", + "displayName": "Raw Salmon" + }, + { + "internalName": "minecart_tnt", + "displayName": "Minecart with TNT" + }, + { + "internalName": "wooden_armorstand", + "displayName": "Armor Stand" + }, + { + "internalName": "fireworks", + "displayName": "Firework Rocket" + }, + { + "internalName": "fireworks_charge", + "displayName": "Firework Star" + }, + { + "internalName": "fireworks_charge_overlay", + "displayName": "Firework Star (Overlay)", + "allowCustomColour": true + }, + { + "internalName": "netherquartz", + "displayName": "Nether Quartz" + }, + { + "internalName": "map_empty", + "displayName": "Empty Map" + }, + { + "internalName": "frame", + "displayName": "Item Frame" + }, + { + "internalName": "enchantedBook", + "displayName": "Enchanted Book" + }, + { + "internalName": "door_acacia", + "displayName": "Acacia Door" + }, + { + "internalName": "door_birch", + "displayName": "Birch Door" + }, + { + "internalName": "door_dark_oak", + "displayName": "Dark Oak Door" + }, + { + "internalName": "door_jungle", + "displayName": "Jungle Door" + }, + { + "internalName": "door_spruce", + "displayName": "Spruce Door" + }, + { + "internalName": "rabbit_stew", + "displayName": "Rabbit Stew" + }, + { + "internalName": "fish_salmon_cooked", + "displayName": "Cooked Salmon" + }, + { + "internalName": "minecart_command_block", + "displayName": "Minecart with Command Block" + }, + { + "internalName": "acacia_boat", + "displayName": "Acacia Boat" + }, + { + "internalName": "birch_boat", + "displayName": "Birch Boat" + }, + { + "internalName": "dark_oak_boat", + "displayName": "Dark Oak Boat" + }, + { + "internalName": "jungle_boat", + "displayName": "Jungle Boat" + }, + { + "internalName": "spruce_boat", + "displayName": "Spruce Boat" + }, + { + "internalName": "prismarine_shard", + "displayName": "Prismarine Shard" + }, + { + "internalName": "prismarine_crystals", + "displayName": "Prismarine Crystals" + }, + { + "internalName": "leather_horse_armor_base", + "displayName": "Leather Horse Armor", + "allowCustomColour": true, + "hasColourEntry": true, + "colourEntry": { + "defaultName": "Armour_Default_Leather_Colour", + "variants": [ "Armour_Default_Leather_Colour" ] + } + }, + { + "internalName": "structure_void", + "displayName": "Structure Void" + }, + { + "internalName": "map_filled_markings", + "displayName": "Filled Map (Overlay)" + }, + { + "internalName": "totem", + "displayName": "Totem of Undying" + }, + { + "internalName": "shulker_shell", + "displayName": "Shulker Shell" + }, + { + "internalName": "iron_nugget", + "displayName": "Iron Nugget" + }, + { + "internalName": "rabbit_foot", + "displayName": "Rabbit's Foot" + }, + { + "internalName": "rabbit_hide", + "displayName": "Rabbit Hide" + }, + { + "internalName": "compass", + "displayName": "" + }, + { + "internalName": "compass", + "displayName": "" + }, + { + "internalName": "compass", + "displayName": "" + }, + { + "internalName": "compass", + "displayName": "" + }, + { + "internalName": "clock", + "displayName": "" + }, + { + "internalName": "clock", + "displayName": "" + }, + { + "internalName": "clock", + "displayName": "" + }, + { + "internalName": "clock", + "displayName": "" + }, + { + "internalName": "dragonFireball", + "displayName": "Dragon Fireball" + }, + { + "internalName": "record_13", + "displayName": "Music Disc (C418 - 13)" + }, + { + "internalName": "record_cat", + "displayName": "Music Disc (C418 - cat)" + }, + { + "internalName": "record_blocks", + "displayName": "Music Disc (C418 - blocks)" + }, + { + "internalName": "record_chirp", + "displayName": "Music Disc (C418 - chirp)" + }, + { + "internalName": "record_far", + "displayName": "Music Disc (C418 - far)" + }, + { + "internalName": "record_mall", + "displayName": "Music Disc (C418 - mall)" + }, + { + "internalName": "record_mellohi", + "displayName": "Music Disc (C418 - mellohi)" + }, + { + "internalName": "record_stal", + "displayName": "Music Disc (C418 - stal)" + }, + { + "internalName": "record_strad", + "displayName": "Music Disc (C418 - strad)" + }, + { + "internalName": "record_ward", + "displayName": "Music Disc (C418 - ward)" + }, + { + "internalName": "record_11", + "displayName": "Music Disc (C418 - 11)" + }, + { + "internalName": "record_where are we now", + "displayName": "Music Disc (C418 - wait)" + }, + { + "internalName": "bucketFish", + "displayName": "Bucket of Cod" + }, + { + "internalName": "bucketSalmon", + "displayName": "Bucket of Salmon" + }, + { + "internalName": "bucketPuffer", + "displayName": "Bucket of Pufferfish" + }, + { + "internalName": "bucketTropical", + "displayName": "Bucket of Tropical Fish" + }, + { + "internalName": "leather_horse_armor_detail", + "displayName": "Leather Horse Armor (Overlay)" + }, + { + "internalName": "dyePowder_black1", + "displayName": "Black Dye [PS4 ONLY]" + }, + { + "internalName": "dyePowder_blue1", + "displayName": "Blue Dye [PS4 ONLY]" + }, + { + "internalName": "dyePowder_brown1", + "displayName": "Brown Dye [PS4 ONLY]" + }, + { + "internalName": "dyePowder_white1", + "displayName": "White Dye [PS4 ONLY]" + }, + { + "internalName": "bamboo", + "displayName": "Bamboo [PS4 ONLY]" + }, + { + "internalName": "lantern_carried", + "displayName": "Lantern [PS4 ONLY]" + }, + { + "internalName": "kelp", + "displayName": "Kelp" + }, + { + "internalName": "dried_kelp", + "displayName": "Dried Kelp" + }, + { + "internalName": "sea_pickle", + "displayName": "Sea Pickle" + }, + { + "internalName": "nautilus", + "displayName": "Nautilus Shell" + }, + { + "internalName": "nautilus_core", + "displayName": "Heart of the Sea" + }, + { + "internalName": "turtle_helmet", + "displayName": "Turtle Shell" + }, + { + "internalName": "turtle_shell_piece", + "displayName": "Scute" + }, + { + "internalName": "trident", + "displayName": "Trident" + }, + { + "internalName": "phantom_membrane", + "displayName": "Phantom Membrane" + }, + { + "internalName": "acacia_sign", + "displayName": "Acacia Sign [PS4 ONLY]" + }, + { + "internalName": "birch_sign", + "displayName": "Birch Sign [PS4 ONLY]" + }, + { + "internalName": "dark_oak_sign", + "displayName": "Dark Oak Sign [PS4 ONLY]" + }, + { + "internalName": "jungle_sign", + "displayName": "Jungle Sign [PS4 ONLY]" + }, + { + "internalName": "spruce_sign", + "displayName": "Spruce Sign [PS4 ONLY]" + }, + { + "internalName": "crossbow", + "displayName": "Crossbow [PS4 ONLY]" + }, + { + "internalName": "crossbow_pull_0", + "displayName": "Crossbow (Pulling Stage 1) [PS4 ONLY]" + }, + { + "internalName": "crossbow_pull_1", + "displayName": "Crossbow (Pulling Stage 2) [PS4 ONLY]" + }, + { + "internalName": "crossbow_pull_2", + "displayName": "Crossbow (Pulling Stage 3) [PS4 ONLY]" + }, + { + "internalName": "crossbow_arrow", + "displayName": "Crossbow (Loaded) [PS4 ONLY]" + }, + { + "internalName": "crossbow_firework", + "displayName": "Crossbow (Loaded) (Firework) [PS4 ONLY]" + }, + { + "internalName": "sweet_berries", + "displayName": "Sweet Berries [PS4 ONLY]" + }, + { + "internalName": "banner_pattern", + "displayName": "Banner Pattern [PS4 ONLY]" + }, + { + "internalName": "bell", + "displayName": "Bell [PS4 ONLY]" + }, + { + "internalName": "campfire_carried", + "displayName": "Campfire [PS4 ONLY]" + }, + { + "internalName": "", + "displayName": "" + } + ] +} diff --git a/PckStudio.Core/Resources/items.png b/PckStudio.Core/Resources/items.png new file mode 100644 index 00000000..6d316ad9 Binary files /dev/null and b/PckStudio.Core/Resources/items.png differ diff --git a/PckStudio.Core/Resources/mapIconData.json b/PckStudio.Core/Resources/mapIconData.json new file mode 100644 index 00000000..8e1273f2 --- /dev/null +++ b/PckStudio.Core/Resources/mapIconData.json @@ -0,0 +1,135 @@ +{ + "COMMENT_1": "JSON by MattNL", + "entries": [ + { + "internalName": "player_1", + "displayName": "Player 1" + }, + { + "internalName": "player_2", + "displayName": "Player 2" + }, + { + "internalName": "player_3", + "displayName": "Player 3" + }, + { + "internalName": "player_4", + "displayName": "Player 4" + }, + { + "internalName": "target_x", + "displayName": "Unused" + }, + { + "internalName": "target_point", + "displayName": "Target Point (Unused)" + }, + { + "internalName": "player_off_map", + "displayName": "Player (Off Map) (Unused)" + }, + { + "internalName": "frame", + "displayName": "Item Frame" + }, + { + "internalName": "player_5", + "displayName": "Player 5" + }, + { + "internalName": "player_6", + "displayName": "Player 6" + }, + { + "internalName": "player_7", + "displayName": "Player 7" + }, + { + "internalName": "player_8", + "displayName": "Player 8" + }, + { + "internalName": "structure", + "displayName": "Structure (Explorer Map)" + }, + { + "internalName": "player_off_limits", + "displayName": "Player (Off Limits) (Unused)" + }, + { + "internalName": "mansion", + "displayName": "Woodland Mansion (Explorer Map)" + }, + { + "internalName": "monument", + "displayName": "Ocean Monument (Explorer Map)" + } + ], + "additional_entries": [ + { + "internalName": "player_1_off_map", + "displayName": "Player 1 (Off Map)" + }, + { + "internalName": "player_2_off_map", + "displayName": "Player 2 (Off Map)" + }, + { + "internalName": "player_3_off_map", + "displayName": "Player 3 (Off Map)" + }, + { + "internalName": "player_4_off_map", + "displayName": "Player 4 (Off Map)" + }, + { + "internalName": "treasure", + "displayName": "Buried Treasure" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "player_5_off_map", + "displayName": "Player 5 (Off Map)" + }, + { + "internalName": "player_6_off_map", + "displayName": "Player 6 (Off Map)" + }, + { + "internalName": "player_7_off_map", + "displayName": "Player 7 (Off Map)" + }, + { + "internalName": "player_8_off_map", + "displayName": "Player 8 (Off Map)" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + } + ] +} diff --git a/PckStudio.Core/Resources/map_icons.png b/PckStudio.Core/Resources/map_icons.png new file mode 100644 index 00000000..7b6ecd13 Binary files /dev/null and b/PckStudio.Core/Resources/map_icons.png differ diff --git a/PckStudio.Core/Resources/moonPhaseData.json b/PckStudio.Core/Resources/moonPhaseData.json new file mode 100644 index 00000000..506e7f6f --- /dev/null +++ b/PckStudio.Core/Resources/moonPhaseData.json @@ -0,0 +1,37 @@ +{ + "COMMENT_1": "JSON by MattNL", + "entries": [ + { + "internalName": "moon_phase_0", + "displayName": "Full Moon" + }, + { + "internalName": "moon_phase_1", + "displayName": "Waning Gibbous" + }, + { + "internalName": "moon_phase_2", + "displayName": "Last Quarter" + }, + { + "internalName": "moon_phase_3", + "displayName": "Waning Crescent" + }, + { + "internalName": "moon_phase_4", + "displayName": "New Moon" + }, + { + "internalName": "moon_phase_5", + "displayName": "Waxing Crescent" + }, + { + "internalName": "moon_phase_6", + "displayName": "First Quarter" + }, + { + "internalName": "moon_phase_7", + "displayName": "Waxing Gibbous" + } + ] +} diff --git a/PckStudio.Core/Resources/moon_phases.png b/PckStudio.Core/Resources/moon_phases.png new file mode 100644 index 00000000..ce239ea7 Binary files /dev/null and b/PckStudio.Core/Resources/moon_phases.png differ diff --git a/PckStudio.Core/Resources/paintingData.json b/PckStudio.Core/Resources/paintingData.json new file mode 100644 index 00000000..5b5b0ef9 --- /dev/null +++ b/PckStudio.Core/Resources/paintingData.json @@ -0,0 +1,1062 @@ +{ + "COMMENT_1": "JSON by MattNL", + "entries": [ + { + "internalName": "Kebab", + "displayName": "\"Kebab med tre pepperoni\" by Kristoffer Zetterstrand" + }, + { + "internalName": "Aztec", + "displayName": "\"de_aztec\" by Kristoffer Zetterstrand" + }, + { + "internalName": "Alban", + "displayName": "\"Albanian\" by Kristoffer Zetterstrand" + }, + { + "internalName": "Aztec2", + "displayName": "\"de_aztec\" by Kristoffer Zetterstrand" + }, + { + "internalName": "Bomb", + "displayName": "\"Target Successfully Bombed\" by Kristoffer Zetterstrand" + }, + { + "internalName": "Plant", + "displayName": "\"Paradisträd\" by Kristoffer Zetterstrand" + }, + { + "internalName": "Wasteland", + "displayName": "\"Wasteland\" by Kristoffer Zetterstrand" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "Back", + "displayName": "Back Texture", + "width": 4, + "height": 4 + }, + { + "internalName": "Back", + "displayName": "", + }, + { + "internalName": "Back", + "displayName": "", + }, + { + "internalName": "Back", + "displayName": "", + }, + { + "internalName": "1x1E1", + "displayName": "Extra Painting 1" + }, + { + "internalName": "1x1E2", + "displayName": "Extra Painting 2" + }, + { + "internalName": "1x1E3", + "displayName": "Extra Painting 3" + }, + { + "internalName": "1x1E4", + "displayName": "Extra Painting 4" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "Back", + "displayName": "" + }, + { + "internalName": "Back", + "displayName": "", + }, + { + "internalName": "Back", + "displayName": "", + }, + { + "internalName": "Back", + "displayName": "", + }, + { + "internalName": "Pool", + "displayName": "\"The Pool\" by Kristoffer Zetterstrand", + "width": 2 + }, + { + "internalName": "Pool", + "displayName": "" + }, + { + "internalName": "Courbet", + "displayName": "\"Bonjour Monsieur Courbet\" by Kristoffer Zetterstrand", + "width": 2 + }, + { + "internalName": "Courbet", + "displayName": "" + }, + { + "internalName": "Sea", + "displayName": "\"Seaside\" by Kristoffer Zetterstrand", + "width": 2 + }, + { + "internalName": "Sea", + "displayName": "" + }, + { + "internalName": "Sunset", + "displayName": "\"sunset_dense\" by Kristoffer Zetterstrand", + "width": 2 + }, + { + "internalName": "Sunset", + "displayName": "" + }, + { + "internalName": "Creebet", + "displayName": "\"Creebet\" by Kristoffer Zetterstrand", + "width": 2 + }, + { + "internalName": "Creebet", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "Back", + "displayName": "" + }, + { + "internalName": "Back", + "displayName": "", + }, + { + "internalName": "Back", + "displayName": "", + }, + { + "internalName": "Back", + "displayName": "", + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "Back", + "displayName": "" + }, + { + "internalName": "Back", + "displayName": "", + }, + { + "internalName": "Back", + "displayName": "", + }, + { + "internalName": "Back", + "displayName": "", + }, + { + "internalName": "Wanderer", + "displayName": "\"Wanderer\" by Kristoffer Zetterstrand", + "height": 2 + }, + { + "internalName": "Graham", + "displayName": "\"Graham\" by Kristoffer Zetterstrand", + "height": 2 + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "Skeleton", + "displayName": "\"Mortal Coil\" by Kristoffer Zetterstrand", + "width": 4, + "height": 3 + }, + { + "internalName": "Skeleton", + "displayName": "", + }, + { + "internalName": "Skeleton", + "displayName": "", + }, + { + "internalName": "Skeleton", + "displayName": "", + }, + { + "internalName": "Wanderer", + "displayName": "" + }, + { + "internalName": "Graham", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "Skeleton", + "displayName": "", + }, + { + "internalName": "Skeleton", + "displayName": "", + }, + { + "internalName": "Skeleton", + "displayName": "", + }, + { + "internalName": "Skeleton", + "displayName": "", + }, + { + "internalName": "Fighters", + "displayName": "\"Fighters\" by Kristoffer Zetterstrand", + "width": 4, + "height": 2 + }, + { + "internalName": "Fighters", + "displayName": "" + }, + { + "internalName": "Fighters", + "displayName": "" + }, + { + "internalName": "Fighters", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "Skeleton", + "displayName": "" + }, + { + "internalName": "Skeleton", + "displayName": "" + }, + { + "internalName": "Skeleton", + "displayName": "" + }, + { + "internalName": "Skeleton", + "displayName": "" + }, + { + "internalName": "Fighters", + "displayName": "" + }, + { + "internalName": "Fighters", + "displayName": "" + }, + { + "internalName": "Fighters", + "displayName": "" + }, + { + "internalName": "Fighters", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "DonkeyKong", + "displayName": "\"Kong\" by Kristoffer Zetterstrand", + "width": 4, + "height": 3 + }, + { + "internalName": "DonkeyKong", + "displayName": "" + }, + { + "internalName": "DonkeyKong", + "displayName": "" + }, + { + "internalName": "DonkeyKong", + "displayName": "" + }, + { + "internalName": "Match", + "displayName": "\"Match\" by Kristoffer Zetterstrand", + "width": 2, + "height": 2 + }, + { + "internalName": "Match", + "displayName": "" + }, + { + "internalName": "Bust", + "displayName": "\"Bust\" by Kristoffer Zetterstrand", + "width": 2, + "height": 2 + }, + { + "internalName": "Bust", + "displayName": "" + }, + { + "internalName": "Stage", + "displayName": "\"The stage is set\" by Kristoffer Zetterstrand", + "width": 2, + "height": 2 + }, + { + "internalName": "Stage", + "displayName": "" + }, + { + "internalName": "Void", + "displayName": "\"The Void\" by Kristoffer Zetterstrand", + "width": 2, + "height": 2 + }, + { + "internalName": "Void", + "displayName": "" + }, + { + "internalName": "SkullAndRoses", + "displayName": "\"Skull and Roses\" by Kristoffer Zetterstrand", + "width": 2, + "height": 2 + }, + { + "internalName": "SkullAndRoses", + "displayName": "" + }, + { + "internalName": "Wither", + "displayName": "\"Wither\" by Jens Bergensten", + "width": 2, + "height": 2 + }, + { + "internalName": "Wither", + "displayName": "" + }, + { + "internalName": "DonkeyKong", + "displayName": "" + }, + { + "internalName": "DonkeyKong", + "displayName": "" + }, + { + "internalName": "DonkeyKong", + "displayName": "" + }, + { + "internalName": "DonkeyKong", + "displayName": "" + }, + { + "internalName": "Match", + "displayName": "" + }, + { + "internalName": "Match", + "displayName": "" + }, + { + "internalName": "Bust", + "displayName": "" + }, + { + "internalName": "Bust", + "displayName": "" + }, + { + "internalName": "Stage", + "displayName": "" + }, + { + "internalName": "Stage", + "displayName": "" + }, + { + "internalName": "Void", + "displayName": "" + }, + { + "internalName": "Void", + "displayName": "" + }, + { + "internalName": "SkullAndRoses", + "displayName": "" + }, + { + "internalName": "SkullAndRoses", + "displayName": "" + }, + { + "internalName": "Wither", + "displayName": "" + }, + { + "internalName": "Wither", + "displayName": "" + }, + { + "internalName": "DonkeyKong", + "displayName": "", + }, + { + "internalName": "DonkeyKong", + "displayName": "", + }, + { + "internalName": "DonkeyKong", + "displayName": "", + }, + { + "internalName": "DonkeyKong", + "displayName": "", + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "Pointer", + "displayName": "\"Pointer\" by Kristoffer Zetterstrand", + "width": 4, + "height": 4 + }, + { + "internalName": "Pointer", + "displayName": "" + }, + { + "internalName": "Pointer", + "displayName": "" + }, + { + "internalName": "Pointer", + "displayName": "" + }, + { + "internalName": "Pigscene", + "displayName": "\"Pigscene\" by Kristoffer Zetterstrand", + "width": 4, + "height": 4 + }, + { + "internalName": "Pigscene", + "displayName": "" + }, + { + "internalName": "Pigscene", + "displayName": "" + }, + { + "internalName": "Pigscene", + "displayName": "" + }, + { + "internalName": "BurningSkull", + "displayName": "\"Skull On Fire\" by Kristoffer Zetterstrand", + "width": 4, + "height": 4 + }, + { + "internalName": "BurningSkull", + "displayName": "" + }, + { + "internalName": "BurningSkull", + "displayName": "" + }, + { + "internalName": "BurningSkull", + "displayName": "" + }, + { + "internalName": "", + "displayName": "", + }, + { + "internalName": "", + "displayName": "", + }, + { + "internalName": "", + "displayName": "", + }, + { + "internalName": "", + "displayName": "", + }, + { + "internalName": "Pointer", + "displayName": "", + }, + { + "internalName": "Pointer", + "displayName": "" + }, + { + "internalName": "Pointer", + "displayName": "" + }, + { + "internalName": "Pointer", + "displayName": "" + }, + { + "internalName": "Pigscene", + "displayName": "" + }, + { + "internalName": "Pigscene", + "displayName": "" + }, + { + "internalName": "Pigscene", + "displayName": "" + }, + { + "internalName": "Pigscene", + "displayName": "" + }, + { + "internalName": "BurningSkull", + "displayName": "" + }, + { + "internalName": "BurningSkull", + "displayName": "" + }, + { + "internalName": "BurningSkull", + "displayName": "" + }, + { + "internalName": "BurningSkull", + "displayName": "" + }, + { + "internalName": "", + "displayName": "", + }, + { + "internalName": "", + "displayName": "", + }, + { + "internalName": "", + "displayName": "", + }, + { + "internalName": "", + "displayName": "", + }, + { + "internalName": "Pointer", + "displayName": "" + }, + { + "internalName": "Pointer", + "displayName": "" + }, + { + "internalName": "Pointer", + "displayName": "" + }, + { + "internalName": "Pointer", + "displayName": "" + }, + { + "internalName": "Pigscene", + "displayName": "", + }, + { + "internalName": "Pigscene", + "displayName": "" + }, + { + "internalName": "Pigscene", + "displayName": "" + }, + { + "internalName": "Pigscene", + "displayName": "" + }, + { + "internalName": "BurningSkull", + "displayName": "", + }, + { + "internalName": "BurningSkull", + "displayName": "" + }, + { + "internalName": "BurningSkull", + "displayName": "" + }, + { + "internalName": "BurningSkull", + "displayName": "" + }, + { + "internalName": "", + "displayName": "", + }, + { + "internalName": "", + "displayName": "", + }, + { + "internalName": "", + "displayName": "", + }, + { + "internalName": "", + "displayName": "", + }, + { + "internalName": "Pointer", + "displayName": "", + }, + { + "internalName": "Pointer", + "displayName": "" + }, + { + "internalName": "Pointer", + "displayName": "" + }, + { + "internalName": "Pointer", + "displayName": "" + }, + { + "internalName": "Pigscene", + "displayName": "", + }, + { + "internalName": "Pigscene", + "displayName": "" + }, + { + "internalName": "Pigscene", + "displayName": "" + }, + { + "internalName": "Pigscene", + "displayName": "" + }, + { + "internalName": "BurningSkull", + "displayName": "", + }, + { + "internalName": "BurningSkull", + "displayName": "" + }, + { + "internalName": "BurningSkull", + "displayName": "" + }, + { + "internalName": "BurningSkull", + "displayName": "" + }, + { + "internalName": "", + "displayName": "", + }, + { + "internalName": "", + "displayName": "", + }, + { + "internalName": "", + "displayName": "", + }, + { + "internalName": "", + "displayName": "", + } + ] +} diff --git a/PckStudio.Core/Resources/paintings.png b/PckStudio.Core/Resources/paintings.png new file mode 100644 index 00000000..b8bc84fe Binary files /dev/null and b/PckStudio.Core/Resources/paintings.png differ diff --git a/PckStudio.Core/Resources/particleData.json b/PckStudio.Core/Resources/particleData.json new file mode 100644 index 00000000..924ab98a --- /dev/null +++ b/PckStudio.Core/Resources/particleData.json @@ -0,0 +1,2097 @@ +{ + "COMMENT_1": "JSON by MattNL", + "entries": [ + { + "internalName": "generic_0", + "displayName": "Generic (Stage 1)", + "colourEntry": { + "defaultName": "None", + "variants": [ + "None", + "Particle_Smoke", + "Particle_NetherPortal", + "Particle_EnderPortal", + "Particle_Ender", + "Particle_DragonBreathMin", + "Particle_DragonBreathMax" + ] + } + }, + { + "internalName": "generic_1", + "displayName": "Generic (Stage 2)", + "colourEntry": { + "defaultName": "None", + "variants": [ + "None", + "Particle_Smoke", + "Particle_NetherPortal", + "Particle_EnderPortal", + "Particle_Ender", + "Particle_DragonBreathMin", + "Particle_DragonBreathMax" + ] + } + }, + { + "internalName": "generic_2", + "displayName": "Generic (Stage 3)", + "colourEntry": { + "defaultName": "None", + "variants": [ + "None", + "Particle_Smoke", + "Particle_NetherPortal", + "Particle_EnderPortal", + "Particle_Ender", + "Particle_DragonBreathMin", + "Particle_DragonBreathMax" + ] + } + }, + { + "internalName": "generic_3", + "displayName": "Generic (Stage 4)", + "colourEntry": { + "defaultName": "None", + "variants": [ + "None", + "Particle_Smoke", + "Particle_NetherPortal", + "Particle_EnderPortal", + "Particle_Ender", + "Particle_DragonBreathMin", + "Particle_DragonBreathMax" + ] + } + }, + { + "internalName": "generic_4", + "displayName": "Generic (Stage 5)", + "colourEntry": { + "defaultName": "None", + "variants": [ + "None", + "Particle_Smoke", + "Particle_NetherPortal", + "Particle_EnderPortal", + "Particle_Ender", + "Particle_DragonBreathMin", + "Particle_DragonBreathMax" + ] + } + }, + { + "internalName": "generic_5", + "displayName": "Generic (Stage 6)", + "colourEntry": { + "defaultName": "None", + "variants": [ + "None", + "Particle_Smoke", + "Particle_NetherPortal", + "Particle_EnderPortal", + "Particle_Ender", + "Particle_DragonBreathMin", + "Particle_DragonBreathMax" + ] + } + }, + { + "internalName": "generic_6", + "displayName": "Generic (Stage 7)", + "colourEntry": { + "defaultName": "None", + "variants": [ + "None", + "Particle_Smoke", + "Particle_NetherPortal", + "Particle_EnderPortal", + "Particle_Ender", + "Particle_DragonBreathMin", + "Particle_DragonBreathMax" + ] + } + }, + { + "internalName": "generic_7", + "displayName": "Generic (Stage 8)", + "colourEntry": { + "defaultName": "None", + "variants": [ + "None", + "Particle_Smoke", + "Particle_NetherPortal", + "Particle_EnderPortal", + "Particle_Ender", + "Particle_DragonBreathMin", + "Particle_DragonBreathMax" + ] + } + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "unused_splash_0", + "displayName": "Splash (Stage 1) (Unused)" + }, + { + "internalName": "unused_splash_1", + "displayName": "Splash (Stage 2) (Unused)" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "splash_0", + "displayName": "Splash (Stage 1)" + }, + { + "internalName": "splash_1", + "displayName": "Splash (Stage 2)" + }, + { + "internalName": "splash_2", + "displayName": "Splash (Stage 3)" + }, + { + "internalName": "splash_3", + "displayName": "Splash (Stage 4)" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "classic_bubble", + "displayName": "Bubble (Unused)" + }, + { + "internalName": "bobber", + "displayName": "Fishing Bobber" + }, + { + "internalName": "bubble", + "displayName": "Bubble", + "colourEntry": { + "isWaterColour": true, + "defaultName": "Water_Plains", + "variants": [ + "Water_Ocean", + "Water_Plains", + "Water_Desert", + "Water_ExtremeHills", + "Water_Forest", + "Water_Taiga", + "Water_Swampland", + "Water_River", + "Water_Hell", + "Water_Sky", + "Water_FrozenOcean", + "Water_FrozenRiver", + "Water_IcePlains", + "Water_IceMountains", + "Water_MushroomIsland", + "Water_MushroomIslandShore", + "Water_Beach", + "Water_DesertHills", + "Water_ForestHills", + "Water_TaigaHills", + "Water_ExtremeHillsEdge", + "Water_Jungle", + "Water_JungleHills", + "Water_JungleEdge", + "Water_DeepOcean", + "Water_StoneBeach", + "Water_ColdBeach", + "Water_BirchForest", + "Water_BirchForestHills", + "Water_RoofedForest", + "Water_ColdTaiga", + "Water_ColdTaigaHills", + "Water_MegaTaiga", + "Water_MegaTaigaHills", + "Water_ExtremeHillsPlus", + "Water_Savanna", + "Water_SavannaPlateau", + "Water_Mesa", + "Water_MesaPlateauF", + "Water_MesaPlateau" + ] + } + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "flash", + "displayName": "Firework Flash", + "width": 4, + "height": 4, + "allowCustomColour": true + }, + { + "internalName": "flash", + "displayName": "" + }, + { + "internalName": "flash", + "displayName": "" + }, + { + "internalName": "flash", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "flame", + "displayName": "Flame" + }, + { + "internalName": "lava", + "displayName": "Lava" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "flash", + "displayName": "" + }, + { + "internalName": "flash", + "displayName": "" + }, + { + "internalName": "flash", + "displayName": "" + }, + { + "internalName": "flash", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "note", + "displayName": "Noteblock Note", + "colourEntry": { + "defaultName": "Particle_Note_00", + "variants": [ + "Particle_Note_00", + "Particle_Note_01", + "Particle_Note_02", + "Particle_Note_03", + "Particle_Note_04", + "Particle_Note_05", + "Particle_Note_06", + "Particle_Note_07", + "Particle_Note_08", + "Particle_Note_09", + "Particle_Note_10", + "Particle_Note_11", + "Particle_Note_12", + "Particle_Note_13", + "Particle_Note_14", + "Particle_Note_15", + "Particle_Note_16", + "Particle_Note_17", + "Particle_Note_18", + "Particle_Note_19", + "Particle_Note_20", + "Particle_Note_21", + "Particle_Note_22", + "Particle_Note_23", + "Particle_Note_24", + ] + } + }, + { + "internalName": "critical_hit", + "displayName": "Critical Hit", + "colourEntry": { + "defaultName": "critical_hit", + "variants": [ + "critical_hit" + ] + } + }, + { + "internalName": "enchanted_hit", + "displayName": "Enchanted Hit", + "colourEntry": { + "defaultName": "critical_hit", + "variants": [ + "critical_hit" + ] + } + }, + { + "internalName": "damage", + "displayName": "Damage Indicator" + }, + { + "internalName": "flash", + "displayName": "" + }, + { + "internalName": "flash", + "displayName": "" + }, + { + "internalName": "flash", + "displayName": "" + }, + { + "internalName": "flash", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "heart", + "displayName": "Heart" + }, + { + "internalName": "angry", + "displayName": "Angry" + }, + { + "internalName": "glint", + "displayName": "Glint" + }, + { + "internalName": "angry_villager", + "displayName": "Angry Villager (Unused)" + }, + { + "internalName": "flash", + "displayName": "" + }, + { + "internalName": "flash", + "displayName": "" + }, + { + "internalName": "flash", + "displayName": "" + }, + { + "internalName": "flash", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "water_0", + "displayName": "Water (Stage 1) (Unused)" + }, + { + "internalName": "water_1", + "displayName": "Water (Stage 2) (Unused)" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "bubble_pop_0", + "displayName": "Bubble Pop (Stage 1) (Unused)", + "width": 2, + "height": 2 + }, + { + "internalName": "bubble_pop_0", + "displayName": "" + }, + { + "internalName": "bubble_pop_1", + "displayName": "Bubble Pop (Stage 2) (Unused)", + "width": 2, + "height": 2 + }, + { + "internalName": "bubble_pop_1", + "displayName": "" + }, + { + "internalName": "bubble_pop_2", + "displayName": "Bubble Pop (Stage 3) (Unused)", + "width": 2, + "height": 2 + }, + { + "internalName": "bubble_pop_2", + "displayName": "" + }, + { + "internalName": "bubble_pop_3", + "displayName": "Bubble Pop (Stage 4) (Unused)", + "width": 2, + "height": 2 + }, + { + "internalName": "bubble_pop_3", + "displayName": "" + }, + { + "internalName": "bubble_pop_4", + "displayName": "Bubble Pop (Stage 5) (Unused)", + "width": 2, + "height": 2 + }, + { + "internalName": "bubble_pop_4", + "displayName": "" + }, + { + "internalName": "drip_hang", + "displayName": "Drip (Hang)", + + "colourEntry": { + "defaultName": "Particle_DripWater", + "variants": [ + "Particle_DripWater", + "Particle_DripLavaStart", + "Particle_DripLavaEnd" + ] + } + }, + { + "internalName": "drip_fall", + "displayName": "Drip (Fall)", + "colourEntry": { + "defaultName": "Particle_DripWater", + "variants": [ + "Particle_DripWater", + "Particle_DripLavaStart", + "Particle_DripLavaEnd" + ] + } + }, + { + "internalName": "drip_land", + "displayName": "Drip (Land)", + "colourEntry": { + "defaultName": "Particle_DripWater", + "variants": [ + "Particle_DripWater", + "Particle_DripLavaStart", + "Particle_DripLavaEnd" + ] + } + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "bubble_pop_0", + "displayName": "" + }, + { + "internalName": "bubble_pop_0", + "displayName": "" + }, + { + "internalName": "bubble_pop_1", + "displayName": "" + }, + { + "internalName": "bubble_pop_1", + "displayName": "" + }, + { + "internalName": "bubble_pop_2", + "displayName": "" + }, + { + "internalName": "bubble_pop_2", + "displayName": "" + }, + { + "internalName": "bubble_pop_3", + "displayName": "" + }, + { + "internalName": "bubble_pop_3", + "displayName": "" + }, + { + "internalName": "bubble_pop_4", + "displayName": "" + }, + { + "internalName": "bubble_pop_4", + "displayName": "" + }, + { + "internalName": "effect_0", + "displayName": "Effect (Stage 1)", + + "allowCustomColour": true, + "colourEntry": { + "defaultName": "Potion_BaseColour", + "variants": [ + "Potion_BaseColour", + "Effect_MovementSpeed", + "Effect_MovementSlowDown", + "Effect_DigSpeed", + "Effect_DigSlowdown", + "Effect_DamageBoost", + "Effect_Heal", + "Effect_Harm", + "Effect_Jump", + "Effect_Confusion", + "Effect_Regeneration", + "Effect_DamageResistance", + "Effect_FireResistance", + "Effect_WaterBreathing", + "Effect_Invisibility", + "Effect_Blindness", + "Effect_NightVision", + "Effect_Hunger", + "Effect_Weakness", + "Effect_Poison", + "Effect_Wither", + "Effect_HealthBoost", + "Effect_Absorption", + "Effect_Saturation", + "Effect_Levitation", + "Effect_Luck", + "Effect_BadLuck", + "Effect_TurtleMaster", + "Effect_SlowFall" + ] + } + }, + { + "internalName": "effect_1", + "displayName": "Effect (Stage 2)", + + "allowCustomColour": true, + "colourEntry": { + "defaultName": "Potion_BaseColour", + "variants": [ + "Potion_BaseColour", + "Effect_MovementSpeed", + "Effect_MovementSlowDown", + "Effect_DigSpeed", + "Effect_DigSlowdown", + "Effect_DamageBoost", + "Effect_Heal", + "Effect_Harm", + "Effect_Jump", + "Effect_Confusion", + "Effect_Regeneration", + "Effect_DamageResistance", + "Effect_FireResistance", + "Effect_WaterBreathing", + "Effect_Invisibility", + "Effect_Blindness", + "Effect_NightVision", + "Effect_Hunger", + "Effect_Weakness", + "Effect_Poison", + "Effect_Wither", + "Effect_HealthBoost", + "Effect_Absorption", + "Effect_Saturation", + "Effect_Levitation", + "Effect_Luck", + "Effect_BadLuck", + "Effect_TurtleMaster", + "Effect_SlowFall" + ] + } + }, + { + "internalName": "effect_2", + "displayName": "Effect (Stage 3)", + "allowCustomColour": true, + + "colourEntry": { + "defaultName": "Potion_BaseColour", + "variants": [ + "Potion_BaseColour", + "Effect_MovementSpeed", + "Effect_MovementSlowDown", + "Effect_DigSpeed", + "Effect_DigSlowdown", + "Effect_DamageBoost", + "Effect_Heal", + "Effect_Harm", + "Effect_Jump", + "Effect_Confusion", + "Effect_Regeneration", + "Effect_DamageResistance", + "Effect_FireResistance", + "Effect_WaterBreathing", + "Effect_Invisibility", + "Effect_Blindness", + "Effect_NightVision", + "Effect_Hunger", + "Effect_Weakness", + "Effect_Poison", + "Effect_Wither", + "Effect_HealthBoost", + "Effect_Absorption", + "Effect_Saturation", + "Effect_Levitation", + "Effect_Luck", + "Effect_BadLuck", + "Effect_TurtleMaster", + "Effect_SlowFall" + ] + } + }, + { + "internalName": "effect_3", + "displayName": "Effect (Stage 4)", + "allowCustomColour": true, + + "colourEntry": { + "defaultName": "Potion_BaseColour", + "variants": [ + "Potion_BaseColour", + "Effect_MovementSpeed", + "Effect_MovementSlowDown", + "Effect_DigSpeed", + "Effect_DigSlowdown", + "Effect_DamageBoost", + "Effect_Heal", + "Effect_Harm", + "Effect_Jump", + "Effect_Confusion", + "Effect_Regeneration", + "Effect_DamageResistance", + "Effect_FireResistance", + "Effect_WaterBreathing", + "Effect_Invisibility", + "Effect_Blindness", + "Effect_NightVision", + "Effect_Hunger", + "Effect_Weakness", + "Effect_Poison", + "Effect_Wither", + "Effect_HealthBoost", + "Effect_Absorption", + "Effect_Saturation", + "Effect_Levitation", + "Effect_Luck", + "Effect_BadLuck", + "Effect_TurtleMaster", + "Effect_SlowFall" + ] + } + }, + { + "internalName": "effect_4", + "displayName": "Effect (Stage 5)", + "allowCustomColour": true, + + "colourEntry": { + "defaultName": "Potion_BaseColour", + "variants": [ + "Potion_BaseColour", + "Effect_MovementSpeed", + "Effect_MovementSlowDown", + "Effect_DigSpeed", + "Effect_DigSlowdown", + "Effect_DamageBoost", + "Effect_Heal", + "Effect_Harm", + "Effect_Jump", + "Effect_Confusion", + "Effect_Regeneration", + "Effect_DamageResistance", + "Effect_FireResistance", + "Effect_WaterBreathing", + "Effect_Invisibility", + "Effect_Blindness", + "Effect_NightVision", + "Effect_Hunger", + "Effect_Weakness", + "Effect_Poison", + "Effect_Wither", + "Effect_HealthBoost", + "Effect_Absorption", + "Effect_Saturation", + "Effect_Levitation", + "Effect_Luck", + "Effect_BadLuck", + "Effect_TurtleMaster", + "Effect_SlowFall" + ] + } + }, + { + "internalName": "effect_5", + "displayName": "Effect (Stage 6)", + "allowCustomColour": true, + + "colourEntry": { + "defaultName": "Potion_BaseColour", + "variants": [ + "Potion_BaseColour", + "Effect_MovementSpeed", + "Effect_MovementSlowDown", + "Effect_DigSpeed", + "Effect_DigSlowdown", + "Effect_DamageBoost", + "Effect_Heal", + "Effect_Harm", + "Effect_Jump", + "Effect_Confusion", + "Effect_Regeneration", + "Effect_DamageResistance", + "Effect_FireResistance", + "Effect_WaterBreathing", + "Effect_Invisibility", + "Effect_Blindness", + "Effect_NightVision", + "Effect_Hunger", + "Effect_Weakness", + "Effect_Poison", + "Effect_Wither", + "Effect_HealthBoost", + "Effect_Absorption", + "Effect_Saturation", + "Effect_Levitation", + "Effect_Luck", + "Effect_BadLuck", + "Effect_TurtleMaster", + "Effect_SlowFall" + ] + } + }, + { + "internalName": "effect_6", + "displayName": "Effect (Stage 7)", + "allowCustomColour": true, + + "colourEntry": { + "defaultName": "Potion_BaseColour", + "variants": [ + "Potion_BaseColour", + "Effect_MovementSpeed", + "Effect_MovementSlowDown", + "Effect_DigSpeed", + "Effect_DigSlowdown", + "Effect_DamageBoost", + "Effect_Heal", + "Effect_Harm", + "Effect_Jump", + "Effect_Confusion", + "Effect_Regeneration", + "Effect_DamageResistance", + "Effect_FireResistance", + "Effect_WaterBreathing", + "Effect_Invisibility", + "Effect_Blindness", + "Effect_NightVision", + "Effect_Hunger", + "Effect_Weakness", + "Effect_Poison", + "Effect_Wither", + "Effect_HealthBoost", + "Effect_Absorption", + "Effect_Saturation", + "Effect_Levitation", + "Effect_Luck", + "Effect_BadLuck", + "Effect_TurtleMaster", + "Effect_SlowFall" + ] + } + }, + { + "internalName": "effect_7", + "displayName": "Effect (Stage 8)", + "allowCustomColour": true, + + "colourEntry": { + "defaultName": "Potion_BaseColour", + "variants": [ + "Potion_BaseColour", + "Effect_MovementSpeed", + "Effect_MovementSlowDown", + "Effect_DigSpeed", + "Effect_DigSlowdown", + "Effect_DamageBoost", + "Effect_Heal", + "Effect_Harm", + "Effect_Jump", + "Effect_Confusion", + "Effect_Regeneration", + "Effect_DamageResistance", + "Effect_FireResistance", + "Effect_WaterBreathing", + "Effect_Invisibility", + "Effect_Blindness", + "Effect_NightVision", + "Effect_Hunger", + "Effect_Weakness", + "Effect_Poison", + "Effect_Wither", + "Effect_HealthBoost", + "Effect_Absorption", + "Effect_Saturation", + "Effect_Levitation", + "Effect_Luck", + "Effect_BadLuck", + "Effect_TurtleMaster", + "Effect_SlowFall" + ] + } + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "spell_0", + "displayName": "Splash Effect (Stage 1)", + "allowCustomColour": true, + + "colourEntry": { + "defaultName": "Potion_BaseColour", + "variants": [ + "Potion_BaseColour", + "Effect_MovementSpeed", + "Effect_MovementSlowDown", + "Effect_DigSpeed", + "Effect_DigSlowdown", + "Effect_DamageBoost", + "Effect_Heal", + "Effect_Harm", + "Effect_Jump", + "Effect_Confusion", + "Effect_Regeneration", + "Effect_DamageResistance", + "Effect_FireResistance", + "Effect_WaterBreathing", + "Effect_Invisibility", + "Effect_Blindness", + "Effect_NightVision", + "Effect_Hunger", + "Effect_Weakness", + "Effect_Poison", + "Effect_Wither", + "Effect_HealthBoost", + "Effect_Absorption", + "Effect_Saturation", + "Effect_Levitation", + "Effect_Luck", + "Effect_BadLuck", + "Effect_TurtleMaster", + "Effect_SlowFall" + ] + } + }, + { + "internalName": "spell_1", + "displayName": "Splash Effect (Stage 2)", + "allowCustomColour": true, + + "colourEntry": { + "defaultName": "Potion_BaseColour", + "variants": [ + "Potion_BaseColour", + "Effect_MovementSpeed", + "Effect_MovementSlowDown", + "Effect_DigSpeed", + "Effect_DigSlowdown", + "Effect_DamageBoost", + "Effect_Heal", + "Effect_Harm", + "Effect_Jump", + "Effect_Confusion", + "Effect_Regeneration", + "Effect_DamageResistance", + "Effect_FireResistance", + "Effect_WaterBreathing", + "Effect_Invisibility", + "Effect_Blindness", + "Effect_NightVision", + "Effect_Hunger", + "Effect_Weakness", + "Effect_Poison", + "Effect_Wither", + "Effect_HealthBoost", + "Effect_Absorption", + "Effect_Saturation", + "Effect_Levitation", + "Effect_Luck", + "Effect_BadLuck", + "Effect_TurtleMaster", + "Effect_SlowFall" + ] + } + }, + { + "internalName": "spell_2", + "displayName": "Splash Effect (Stage 3)", + "allowCustomColour": true, + + "colourEntry": { + "defaultName": "Potion_BaseColour", + "variants": [ + "Potion_BaseColour", + "Effect_MovementSpeed", + "Effect_MovementSlowDown", + "Effect_DigSpeed", + "Effect_DigSlowdown", + "Effect_DamageBoost", + "Effect_Heal", + "Effect_Harm", + "Effect_Jump", + "Effect_Confusion", + "Effect_Regeneration", + "Effect_DamageResistance", + "Effect_FireResistance", + "Effect_WaterBreathing", + "Effect_Invisibility", + "Effect_Blindness", + "Effect_NightVision", + "Effect_Hunger", + "Effect_Weakness", + "Effect_Poison", + "Effect_Wither", + "Effect_HealthBoost", + "Effect_Absorption", + "Effect_Saturation", + "Effect_Levitation", + "Effect_Luck", + "Effect_BadLuck", + "Effect_TurtleMaster", + "Effect_SlowFall" + ] + } + }, + { + "internalName": "spell_3", + "displayName": "Splash Effect (Stage 4)", + "allowCustomColour": true, + + "colourEntry": { + "defaultName": "Potion_BaseColour", + "variants": [ + "Potion_BaseColour", + "Effect_MovementSpeed", + "Effect_MovementSlowDown", + "Effect_DigSpeed", + "Effect_DigSlowdown", + "Effect_DamageBoost", + "Effect_Heal", + "Effect_Harm", + "Effect_Jump", + "Effect_Confusion", + "Effect_Regeneration", + "Effect_DamageResistance", + "Effect_FireResistance", + "Effect_WaterBreathing", + "Effect_Invisibility", + "Effect_Blindness", + "Effect_NightVision", + "Effect_Hunger", + "Effect_Weakness", + "Effect_Poison", + "Effect_Wither", + "Effect_HealthBoost", + "Effect_Absorption", + "Effect_Saturation", + "Effect_Levitation", + "Effect_Luck", + "Effect_BadLuck", + "Effect_TurtleMaster", + "Effect_SlowFall" + ] + } + }, + { + "internalName": "spell_4", + "displayName": "Splash Effect (Stage 5)", + "allowCustomColour": true, + + "colourEntry": { + "defaultName": "Potion_BaseColour", + "variants": [ + "Potion_BaseColour", + "Effect_MovementSpeed", + "Effect_MovementSlowDown", + "Effect_DigSpeed", + "Effect_DigSlowdown", + "Effect_DamageBoost", + "Effect_Heal", + "Effect_Harm", + "Effect_Jump", + "Effect_Confusion", + "Effect_Regeneration", + "Effect_DamageResistance", + "Effect_FireResistance", + "Effect_WaterBreathing", + "Effect_Invisibility", + "Effect_Blindness", + "Effect_NightVision", + "Effect_Hunger", + "Effect_Weakness", + "Effect_Poison", + "Effect_Wither", + "Effect_HealthBoost", + "Effect_Absorption", + "Effect_Saturation", + "Effect_Levitation", + "Effect_Luck", + "Effect_BadLuck", + "Effect_TurtleMaster", + "Effect_SlowFall" + ] + } + }, + { + "internalName": "spell_5", + "displayName": "Splash Effect (Stage 6)", + "allowCustomColour": true, + + "colourEntry": { + "defaultName": "Potion_BaseColour", + "variants": [ + "Potion_BaseColour", + "Effect_MovementSpeed", + "Effect_MovementSlowDown", + "Effect_DigSpeed", + "Effect_DigSlowdown", + "Effect_DamageBoost", + "Effect_Heal", + "Effect_Harm", + "Effect_Jump", + "Effect_Confusion", + "Effect_Regeneration", + "Effect_DamageResistance", + "Effect_FireResistance", + "Effect_WaterBreathing", + "Effect_Invisibility", + "Effect_Blindness", + "Effect_NightVision", + "Effect_Hunger", + "Effect_Weakness", + "Effect_Poison", + "Effect_Wither", + "Effect_HealthBoost", + "Effect_Absorption", + "Effect_Saturation", + "Effect_Levitation", + "Effect_Luck", + "Effect_BadLuck", + "Effect_TurtleMaster", + "Effect_SlowFall" + ] + } + }, + { + "internalName": "spell_6", + "displayName": "Splash Effect (Stage 7)", + "allowCustomColour": true, + + "colourEntry": { + "defaultName": "Potion_BaseColour", + "variants": [ + "Potion_BaseColour", + "Effect_MovementSpeed", + "Effect_MovementSlowDown", + "Effect_DigSpeed", + "Effect_DigSlowdown", + "Effect_DamageBoost", + "Effect_Heal", + "Effect_Harm", + "Effect_Jump", + "Effect_Confusion", + "Effect_Regeneration", + "Effect_DamageResistance", + "Effect_FireResistance", + "Effect_WaterBreathing", + "Effect_Invisibility", + "Effect_Blindness", + "Effect_NightVision", + "Effect_Hunger", + "Effect_Weakness", + "Effect_Poison", + "Effect_Wither", + "Effect_HealthBoost", + "Effect_Absorption", + "Effect_Saturation", + "Effect_Levitation", + "Effect_Luck", + "Effect_BadLuck", + "Effect_TurtleMaster", + "Effect_SlowFall" + ] + } + }, + { + "internalName": "spell_7", + "displayName": "Splash Effect (Stage 8)", + "allowCustomColour": true, + + "colourEntry": { + "defaultName": "Potion_BaseColour", + "variants": [ + "Potion_BaseColour", + "Effect_MovementSpeed", + "Effect_MovementSlowDown", + "Effect_DigSpeed", + "Effect_DigSlowdown", + "Effect_DamageBoost", + "Effect_Heal", + "Effect_Harm", + "Effect_Jump", + "Effect_Confusion", + "Effect_Regeneration", + "Effect_DamageResistance", + "Effect_FireResistance", + "Effect_WaterBreathing", + "Effect_Invisibility", + "Effect_Blindness", + "Effect_NightVision", + "Effect_Hunger", + "Effect_Weakness", + "Effect_Poison", + "Effect_Wither", + "Effect_HealthBoost", + "Effect_Absorption", + "Effect_Saturation", + "Effect_Levitation", + "Effect_Luck", + "Effect_BadLuck", + "Effect_TurtleMaster", + "Effect_SlowFall" + ] + } + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "spark_0", + "displayName": "Firework Spark (Stage 1)", + "allowCustomColour": true, + + "colourEntry": { + "defaultName": "None", + "variants": [ + "None", + "Particle_ScoreRing_Small", + "Particle_ScoreRing_Medium", + "Particle_ScoreRing_Large" + ] + } + }, + { + "internalName": "spark_1", + "displayName": "Firework Spark (Stage 2)", + "allowCustomColour": true, + + "colourEntry": { + "defaultName": "None", + "variants": [ + "None", + "Particle_ScoreRing_Small", + "Particle_ScoreRing_Medium", + "Particle_ScoreRing_Large" + ] + } + }, + { + "internalName": "spark_2", + "displayName": "Firework Spark (Stage 3)", + "allowCustomColour": true, + + "colourEntry": { + "defaultName": "None", + "variants": [ + "None", + "Particle_ScoreRing_Small", + "Particle_ScoreRing_Medium", + "Particle_ScoreRing_Large" + ] + } + }, + { + "internalName": "spark_3", + "displayName": "Firework Spark (Stage 4)", + "allowCustomColour": true, + + "colourEntry": { + "defaultName": "None", + "variants": [ + "None", + "Particle_ScoreRing_Small", + "Particle_ScoreRing_Medium", + "Particle_ScoreRing_Large" + ] + } + }, + { + "internalName": "spark_4", + "displayName": "Firework Spark (Stage 5)", + "allowCustomColour": true, + + "colourEntry": { + "defaultName": "None", + "variants": [ + "None", + "Particle_ScoreRing_Small", + "Particle_ScoreRing_Medium", + "Particle_ScoreRing_Large" + ] + } + }, + { + "internalName": "spark_5", + "displayName": "Firework Spark (Stage 6)", + "allowCustomColour": true, + + "colourEntry": { + "defaultName": "None", + "variants": [ + "None", + "Particle_ScoreRing_Small", + "Particle_ScoreRing_Medium", + "Particle_ScoreRing_Large" + ] + } + }, + { + "internalName": "spark_6", + "displayName": "Firework Spark (Stage 7)", + "allowCustomColour": true, + + "colourEntry": { + "defaultName": "None", + "variants": [ + "None", + "Particle_ScoreRing_Small", + "Particle_ScoreRing_Medium", + "Particle_ScoreRing_Large" + ] + } + }, + { + "internalName": "spark_7", + "displayName": "Firework Spark (Stage 8)", + "allowCustomColour": true, + + "colourEntry": { + "defaultName": "None", + "variants": [ + "None", + "Particle_ScoreRing_Small", + "Particle_ScoreRing_Medium", + "Particle_ScoreRing_Large" + ] + } + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "glitter_0", + "displayName": "Shulker/End Rod Glitter (Stage 1)" + }, + { + "internalName": "glitter_1", + "displayName": "Shulker/End Rod Glitter (Stage 2)" + }, + { + "internalName": "glitter_2", + "displayName": "Shulker/End Rod Glitter (Stage 3)" + }, + { + "internalName": "glitter_3", + "displayName": "Shulker/End Rod Glitter (Stage 4)" + }, + { + "internalName": "glitter_4", + "displayName": "Shulker/End Rod Glitter (Stage 5)" + }, + { + "internalName": "glitter_5", + "displayName": "Shulker/End Rod Glitter (Stage 6)" + }, + { + "internalName": "glitter_6", + "displayName": "Shulker/End Rod Glitter (Stage 7)" + }, + { + "internalName": "glitter_7", + "displayName": "Shulker/End Rod Glitter (Stage 8)" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "camera_shoot_explosion_0", + "displayName": "Bedrock Edition Explosion (Unused) (Stage 1)" + }, + { + "internalName": "camera_shoot_explosion_1", + "displayName": "Bedrock Edition Explosion (Unused) (Stage 2)" + }, + { + "internalName": "camera_shoot_explosion_2", + "displayName": "Bedrock Edition Explosion (Unused) (Stage 3)" + }, + { + "internalName": "camera_shoot_explosion_3", + "displayName": "Bedrock Edition Explosion (Unused) (Stage 4)" + }, + { + "internalName": "camera_shoot_explosion_4", + "displayName": "Bedrock Edition Explosion (Unused) (Stage 5)" + }, + { + "internalName": "camera_shoot_explosion_5", + "displayName": "Bedrock Edition Explosion (Unused) (Stage 6)" + }, + { + "internalName": "camera_shoot_explosion_6", + "displayName": "Bedrock Edition Explosion (Unused) (Stage 7)" + }, + { + "internalName": "camera_shoot_explosion_7", + "displayName": "Bedrock Edition Explosion (Unused) (Stage 8)" + }, + { + "internalName": "camera_shoot_explosion_8", + "displayName": "Bedrock Edition Explosion (Unused) (Stage 9)" + }, + { + "internalName": "camera_shoot_explosion_9", + "displayName": "Bedrock Edition Explosion (Unused) (Stage 10)" + }, + { + "internalName": "camera_shoot_explosion_10", + "displayName": "Bedrock Edition Explosion (Unused) (Stage 11)" + }, + { + "internalName": "camera_shoot_explosion_11", + "displayName": "Bedrock Edition Explosion (Unused) (Stage 12)" + }, + { + "internalName": "camera_shoot_explosion_12", + "displayName": "Bedrock Edition Explosion (Unused) (Stage 13)" + }, + { + "internalName": "camera_shoot_explosion_13", + "displayName": "Bedrock Edition Explosion (Unused) (Stage 14)" + }, + { + "internalName": "camera_shoot_explosion_14", + "displayName": "Bedrock Edition Explosion (Unused) (Stage 15)" + }, + { + "internalName": "camera_shoot_explosion_15", + "displayName": "Bedrock Edition Explosion (Unused) (Stage 16)" + }, + { + "internalName": "conduit_0", + "displayName": "Conduit (Stage 1)" + }, + { + "internalName": "conduit_1", + "displayName": "Conduit (Stage 2)" + }, + { + "internalName": "conduit_2", + "displayName": "Conduit (Stage 3)" + }, + { + "internalName": "conduit_3", + "displayName": "Conduit (Stage 4)" + }, + { + "internalName": "conduit_4", + "displayName": "Conduit (Stage 5)" + }, + { + "internalName": "conduit_5", + "displayName": "Conduit (Stage 6)" + }, + { + "internalName": "conduit_6", + "displayName": "Conduit (Stage 7)" + }, + { + "internalName": "conduit_7", + "displayName": "Conduit (Stage 8)" + }, + { + "internalName": "conduit_8", + "displayName": "Conduit (Stage 9)" + }, + { + "internalName": "conduit_9", + "displayName": "Conduit (Stage 10)" + }, + { + "internalName": "conduit_10", + "displayName": "Conduit (Stage 11)" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "sga_a", + "displayName": "Standard Galactic Language (A)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_b", + "displayName": "Standard Galactic Language (B)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_c", + "displayName": "Standard Galactic Language (C)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_d", + "displayName": "Standard Galactic Language (D)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_e", + "displayName": "Standard Galactic Language (E)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_f", + "displayName": "Standard Galactic Language (F)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_g", + "displayName": "Standard Galactic Language (G)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_h", + "displayName": "Standard Galactic Language (H)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_i", + "displayName": "Standard Galactic Language (I)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_j", + "displayName": "Standard Galactic Language (J)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_k", + "displayName": "Standard Galactic Language (K)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_l", + "displayName": "Standard Galactic Language (L)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_m", + "displayName": "Standard Galactic Language (M)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_n", + "displayName": "Standard Galactic Language (N)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_o", + "displayName": "Standard Galactic Language (O)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_p", + "displayName": "Standard Galactic Language (P)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_q", + "displayName": "Standard Galactic Language (Q)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_r", + "displayName": "Standard Galactic Language (R)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_s", + "displayName": "Standard Galactic Language (S)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_t", + "displayName": "Standard Galactic Language (T)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_u", + "displayName": "Standard Galactic Language (U)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_v", + "displayName": "Standard Galactic Language (V)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_w", + "displayName": "Standard Galactic Language (W)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_x", + "displayName": "Standard Galactic Language (X)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_y", + "displayName": "Standard Galactic Language (Y)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "sga_z", + "displayName": "Standard Galactic Language (Z)", + + "colourEntry": { + "defaultName": "Particle_EnchantmentTable", + "variants": [ + "Particle_EnchantmentTable" + ] + } + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + { + "internalName": "", + "displayName": "" + }, + ] +} \ No newline at end of file diff --git a/PckStudio.Core/Resources/particles.png b/PckStudio.Core/Resources/particles.png new file mode 100644 index 00000000..b4f1e1f6 Binary files /dev/null and b/PckStudio.Core/Resources/particles.png differ diff --git a/PckStudio.Core/Resources/terrain.png b/PckStudio.Core/Resources/terrain.png new file mode 100644 index 00000000..9b6d1791 Binary files /dev/null and b/PckStudio.Core/Resources/terrain.png differ diff --git a/PckStudio.Rendering/TextureChangingEventArgs.cs b/PckStudio.Rendering/TextureChangingEventArgs.cs index 6174e509..af9cbe7f 100644 --- a/PckStudio.Rendering/TextureChangingEventArgs.cs +++ b/PckStudio.Rendering/TextureChangingEventArgs.cs @@ -18,6 +18,7 @@ using System.ComponentModel; using System.Drawing; +<<<<<<<< HEAD:PckStudio.Rendering/TextureChangingEventArgs.cs namespace PckStudio.Rendering { public class TextureChangingEventArgs : CancelEventArgs @@ -28,5 +29,26 @@ namespace PckStudio.Rendering { NewTexture = newTexture; } +======== +namespace PckStudio.Core +{ + public enum ResourceCategory + { + Unknown = -1, + ItemAnimation, + BlockAnimation, + MobEntityTextures, + ItemEntityTextures, + ItemAtlas, + BlockAtlas, + ParticleAtlas, + BannerAtlas, + PaintingAtlas, + ExplosionAtlas, + ExperienceOrbAtlas, + MoonPhaseAtlas, + MapIconAtlas, + AdditionalMapIconsAtlas, +>>>>>>>> main:PckStudio.Core/ResourceCategory.cs } } \ No newline at end of file diff --git a/PckStuido.ModelSupport/Extension/SkinExtension.cs b/PckStuido.ModelSupport/Extension/SkinExtension.cs new file mode 100644 index 00000000..3dcf6492 --- /dev/null +++ b/PckStuido.ModelSupport/Extension/SkinExtension.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OMI.Formats.Model; +using PckStudio.Core.Skin; +using PckStudio.ModelSupport; + +namespace PckStuido.ModelSupport.Extension +{ + public static class SkinExtension + { + public static SkinModelInfo GetModelInfo(this Skin skin) => new SkinModelInfo(skin.Texture, skin.Anim, skin.Model); + + public static void SetModelInfo(this Skin skin, SkinModelInfo modelInfo) + { + skin.Texture = modelInfo.Texture; + skin.Anim = modelInfo.Anim; + skin.Model = modelInfo.Model; + } + } +} diff --git a/PckStuido.ModelSupport/Format/External/BedrockLegacyModel.cs b/PckStuido.ModelSupport/Format/External/BedrockLegacyModel.cs new file mode 100644 index 00000000..1f96f7d4 --- /dev/null +++ b/PckStuido.ModelSupport/Format/External/BedrockLegacyModel.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; + +namespace PckStudio.ModelSupport.Format.External +{ + internal class BedrockLegacyModel : Dictionary + { + } +} diff --git a/PckStuido.ModelSupport/Format/External/BedrockModel.cs b/PckStuido.ModelSupport/Format/External/BedrockModel.cs new file mode 100644 index 00000000..7f8f4766 --- /dev/null +++ b/PckStuido.ModelSupport/Format/External/BedrockModel.cs @@ -0,0 +1,158 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Numerics; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; + +namespace PckStudio.ModelSupport.Format.External +{ + internal class BedrockModel + { + [JsonProperty("format_version")] + public string FormatVersion { get; set; } + + [JsonProperty("minecraft:geometry")] + public List Models { get; } = new List(); + } + + internal class Geometry + { + [JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)] + public GeometryDescription Description { get; set; } + + [JsonProperty("bones")] + public List Bones { get; } = new List(); + } + + internal class GeometryDescription + { + [JsonProperty("identifier")] + public string Identifier { get; set; } + + [JsonProperty("texture_width")] + private int TextureWidth; + + [JsonProperty("texture_height")] + private int TextureHeight; + + [JsonIgnore] + public Size TextureSize + { + get => new Size(TextureWidth, TextureHeight); + set + { + TextureWidth = value.Width; + TextureHeight = value.Height; + } + } + } + + internal class Bone + { + [JsonProperty("name")] + public string Name { get; set; } + + public Bone(string name) + { + Name = name; + Cubes = new List(); + } + + + [JsonProperty("parent", NullValueHandling = NullValueHandling.Ignore)] + public string Parent { get; set; } = ""; + + [JsonIgnore] + public Vector3 Pivot + { + get => pivot.Length < 3 ? Vector3.Zero : new Vector3(pivot[0], pivot[1], pivot[2]); + set + { + if (pivot.Length < 3) + pivot = new float[3]; + pivot[0] = value.X; + pivot[1] = value.Y; + pivot[2] = value.Z; + } + } + + [JsonProperty("cubes")] + public List Cubes; + + [JsonProperty("pivot")] + private float[] pivot { get; set; } = new float[3]; + } + + internal class Cube + { + [JsonProperty("origin")] + private float[] origin { get; set; } = new float[3]; + [JsonIgnore] + public Vector3 Origin + { + get => origin.Length < 3 ? Vector3.Zero : new Vector3(origin[0], origin[1], origin[2]); + set + { + if (origin.Length < 3) + origin = new float[3]; + origin[0] = value.X; + origin[1] = value.Y; + origin[2] = value.Z; + } + } + + [JsonProperty("rotation")] + private float[] rotation { get; set; } = new float[3]; + [JsonIgnore] + public Vector3 Rotation + { + get => rotation.Length < 3 ? Vector3.Zero : new Vector3(rotation[0], rotation[1], rotation[2]); + set + { + rotation[0] = value.X; + rotation[1] = value.Y; + rotation[2] = value.Z; + } + } + + [JsonProperty("size")] + private float[] size { get; set; } = new float[3]; + [JsonIgnore] + public Vector3 Size + { + get => size.Length < 3 ? Vector3.Zero : new Vector3(size[0], size[1], size[2]); + set + { + if (size.Length < 3) + size = new float[3]; + size[0] = value.X; + size[1] = value.Y; + size[2] = value.Z; + } + } + + [JsonProperty("uv")] + private float[] uv { get; set; } = new float[2]; + [JsonIgnore] + public Vector2 Uv + { + get => uv.Length < 2 ? Vector2.Zero : new Vector2(uv[0], uv[1]); + set + { + if (uv.Length < 2) + uv = new float[2]; + uv[0] = value.X; + uv[1] = value.Y; + } + } + + [JsonProperty("inflate")] + public float Inflate { get; set; } = 0f; + + [JsonProperty("mirror", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool Mirror { get; set; } = false; + } +} diff --git a/PckStuido.ModelSupport/Format/External/BlockBenchModel.cs b/PckStuido.ModelSupport/Format/External/BlockBenchModel.cs new file mode 100644 index 00000000..1c3f5e3e --- /dev/null +++ b/PckStuido.ModelSupport/Format/External/BlockBenchModel.cs @@ -0,0 +1,362 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Linq; +using System.Numerics; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using NamedTexture = PckStudio.Core.NamedData; + +namespace PckStudio.ModelSupport.Format.External +{ + internal static class BlockBenchFormatInfos + { + internal static readonly string FormatVersion = "4.5"; + + internal static BlockBenchFormatInfo Free { get; } = new BlockBenchFormatInfo(FormatVersion, "free", true); + internal static BlockBenchFormatInfo BedrockEntity { get; } = new BlockBenchFormatInfo(FormatVersion, "bedrock", true); + } + + internal sealed class BlockBenchFormatInfo + { + [JsonProperty("format_version")] + internal string FormatVersion { get; } + + [JsonProperty("model_format")] + internal string ModelFormat { get; } + + [JsonProperty("box_uv")] + internal bool UseBoxUv { get; set; } + + [JsonConstructor] + private BlockBenchFormatInfo() { } + + internal BlockBenchFormatInfo(string formatVersion, string modelFormat, bool useBoxUv) + { + FormatVersion = formatVersion; + ModelFormat = modelFormat; + UseBoxUv = useBoxUv; + } + } + + internal class Element + { + [JsonProperty("name")] + internal string Name; + + [JsonProperty("box_uv")] + internal bool UseBoxUv; + + [JsonProperty("visibility", DefaultValueHandling = DefaultValueHandling.Ignore)] + internal bool IsVisibile { get; set; } = true; + + [JsonProperty("rescale")] + internal bool Rescale; + + [JsonProperty("mirror_uv")] + internal bool MirrorUv; + + [JsonProperty("locked")] + internal bool Locked; + + [DefaultValue(true)] + [JsonProperty("export", DefaultValueHandling = DefaultValueHandling.Ignore)] + internal bool Export { get; } = true; + + [JsonProperty("inflate")] + internal float Inflate; + + [JsonProperty("origin", NullValueHandling = NullValueHandling.Ignore)] + private float[] origin; + + [JsonProperty("from")] + private float[] from; + + [JsonProperty("to")] + private float[] to; + + [JsonProperty("uv_offset")] + private int[] uv_offset; + + [JsonProperty("rotation", NullValueHandling = NullValueHandling.Ignore)] + private float[] rotation; + + [JsonIgnore()] + internal Vector3 Origin + { + get + { + return new Vector3(origin?[0] ?? 0, origin?[1] ?? 0, origin?[2] ?? 0); + } + set + { + if (origin is null || origin.Length < 3) + origin = new float[3]; + origin[0] = value.X; + origin[1] = value.Y; + origin[2] = value.Z; + } + } + + [JsonIgnore()] + internal Vector3 From + { + get + { + return new Vector3(from?[0] ?? 0, from?[1] ?? 0, from?[2] ?? 0); + } + set + { + if (from is null || from.Length < 3) + from = new float[3]; + from[0] = value.X; + from[1] = value.Y; + from[2] = value.Z; + } + } + + [JsonIgnore()] + internal Vector3 To + { + get + { + return new Vector3(to?[0] ?? 0, to?[1] ?? 0, to?[2] ?? 0); + } + set + { + if (to is null || to.Length < 3) + to = new float[3]; + to[0] = value.X; + to[1] = value.Y; + to[2] = value.Z; + } + } + + [JsonIgnore()] + internal Vector2 UvOffset + { + get + { + return new Vector2(uv_offset?[0] ?? 0, uv_offset?[1] ?? 0); + } + set + { + if (uv_offset is null || uv_offset.Length < 2) + uv_offset = new int[2]; + uv_offset[0] = (int)value.X; + uv_offset[1] = (int)value.Y; + } + } + + [JsonIgnore()] + internal Vector3 Rotation + { + get + { + return new Vector3(rotation?[0] ?? 0, rotation?[1] ?? 0, rotation?[2] ?? 0); + } + set + { + if (rotation is null || rotation.Length < 3) + rotation = new float[3]; + rotation[0] = value.X; + rotation[1] = value.Y; + rotation[2] = value.Z; + } + } + + [JsonProperty("type")] + internal string Type; + + [JsonProperty("uuid")] + internal Guid Uuid; + + internal static Element CreateCube(string name, Vector2 uvOffset, Vector3 pos, Vector3 size, float inflate, bool mirror) + { + return new Element + { + Name = name, + UseBoxUv = true, + Locked = false, + Rescale = false, + Type = "cube", + Uuid = Guid.NewGuid(), + UvOffset = uvOffset, + MirrorUv = mirror, + Inflate = inflate, + From = pos, + To = pos + size + }; + } + + } + + internal class Texture + { + public static implicit operator Image(Texture texture) => texture.GetImage(); + public static implicit operator Texture(Image image) => new Texture(image); + public static implicit operator Texture(NamedTexture namedTexture) => new Texture(namedTexture.Name, namedTexture.Value); + + private const string _TEXTUREDATAHEAD = "data:image/png;base64,"; + + [JsonConstructor] + private Texture() + { + } + + internal Texture(string name, Image image) + : this(image) + { + Name = name; + } + + internal Texture(Image image) + { + if (image is not null) + { + SetImage(image); + return; + } + Debug.WriteLine($"param: {nameof(image)} is null"); + } + + [JsonProperty("name")] + internal string Name { get; set; } + + [JsonProperty("source")] + internal string TextureSource { get; private set; } + + private Image GetImage() + { + string data = TextureSource; + if (data.StartsWith(_TEXTUREDATAHEAD)) + { + byte[] encodedData = Convert.FromBase64String(data.Substring(_TEXTUREDATAHEAD.Length)); + using var ms = new MemoryStream(encodedData); + return Image.FromStream(ms); + } + return null; + } + + private void SetImage(Image image) + { + var ms = new MemoryStream(); + image.Save(ms, ImageFormat.Png); + TextureSource = _TEXTUREDATAHEAD + Convert.ToBase64String(ms.ToArray()); + } + } + + internal class Outline + { + [JsonProperty("name")] + internal string Name; + + [JsonProperty("origin")] + private float[] origin; + + [JsonIgnore] + public Vector3 Origin + { + get => new Vector3(origin?[0] ?? 0, origin?[1] ?? 0, origin?[2] ?? 0); + set + { + if (origin is null || origin.Length < 3) + origin = new float[3]; + origin[0] = value.X; + origin[1] = value.Y; + origin[2] = value.Z; + } + } + + [JsonProperty("rotation")] + private float[] rotation; + + [JsonIgnore] + public Vector3 Rotation + { + get => new Vector3(rotation?[0] ?? 0, rotation?[1] ?? 0, rotation?[2] ?? 0); + set + { + if (rotation is null || rotation.Length < 3) + rotation = new float[3]; + rotation[0] = value.X; + rotation[1] = value.Y; + rotation[2] = value.Z; + } + } + + [JsonProperty("uuid")] + internal Guid Uuid; + + [JsonProperty("children")] + internal JArray Children; + + public Outline(string name) + { + Name = name; + origin = new float[3]; + Uuid = Guid.NewGuid(); + Children = new JArray(); + } + } + + internal class TextureRes + { + [JsonProperty("width")] + internal int Width { get; set; } + + [JsonProperty("height")] + internal int Height { get; set; } + + public TextureRes(int width, int height) + { + Width = width; + Height = height; + } + + public static implicit operator Size(TextureRes res) => new Size(res.Width, res.Height); + public static implicit operator TextureRes(Size size) => new TextureRes(size.Width, size.Height); + } + + internal class BlockBenchModel + { + [JsonProperty("name")] + internal string Name; + + [JsonProperty("meta")] + internal BlockBenchFormatInfo Format; + + [JsonProperty("model_identifier")] + internal string ModelIdentifier { get; set; } = ""; + + [JsonProperty("resolution")] + internal TextureRes TextureResolution; + + [JsonProperty("elements")] + internal Element[] Elements; + + [JsonProperty("outliner")] + internal JArray Outliner; + + [JsonProperty("textures")] + internal Texture[] Textures; + + internal static BlockBenchModel Create(BlockBenchFormatInfo formatInfo, string name, Size textureResolution, IEnumerable textures) + { + return new BlockBenchModel() + { + Name = name, + Textures = textures.ToArray(), + TextureResolution = textureResolution, + ModelIdentifier = "", + Format = formatInfo, + }; + } + } +} diff --git a/PckStuido.ModelSupport/Format/Internal/PSM/PSMFile.cs b/PckStuido.ModelSupport/Format/Internal/PSM/PSMFile.cs new file mode 100644 index 00000000..1aebcecc --- /dev/null +++ b/PckStuido.ModelSupport/Format/Internal/PSM/PSMFile.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using PckStudio.Core.Skin; + +namespace PckStudio.ModelSupport.Internal.Format +{ +/* + Magic - 3 bytes("psm") + Version - 1 byte [u8] + Anim - 4 bytes[int32] + NumberOfParts - 4 bytes[int32] + { + part parent - 1 byte (HEAD=0, BODY=1, LEG0=2, LEG1=3, ARM0=4, ARM1=5) + Position-X - 4 bytes (float32) + Position-Y - 4 bytes (float32) + Position-Z - 4 bytes (float32) + Size-X - 4 bytes (float32) + Size-Y - 4 bytes (float32) + Size-Z - 4 bytes (float32) + MirrorAndUvX - 1 bit flag 7 bits uv.x value(0-64) (s8) + HideWithArmorAndUvY - 1 bit flag 7 bits uv.y value(0-64) (s8) + inflation/scale value - 4 bytes (float32) + } + NumberOfOffsets - 4 bytes[int32] + { + offset part - 1 byte + vertical offset - 4 bytes[float] + } +*/ + public sealed class PSMFile + { + internal static readonly string HEADER_MAGIC = "psm"; + internal const byte CurrentVersion = 1; + + public readonly byte Version; + + internal PSMFile(byte version) + { + Version = version; + } + + internal PSMFile(byte version, SkinANIM skinANIM) + : this(version) + { + SkinANIM = skinANIM; + } + + public SkinANIM SkinANIM { get; private set; } + + public readonly List Parts = new List(); + public readonly List Offsets = new List(); + } + + public enum PSMOffsetType : byte + { + HEAD = 0, + BODY = 1, + ARM0 = 2, + ARM1 = 3, + LEG0 = 4, + LEG1 = 5, + + TOOL0 = 6, + TOOL1 = 7, + + HELMET = 8, + SHOULDER0 = 9, + SHOULDER1 = 10, + CHEST = 11, + WAIST = 12, + PANTS0 = 13, + PANTS1 = 14, + BOOT0 = 15, + BOOT1 = 16, + } + + public enum PSMParentType : byte + { + HEAD = 0, + BODY = 1, + ARM0 = 2, + ARM1 = 3, + LEG0 = 4, + LEG1 = 5, + } +} diff --git a/PckStuido.ModelSupport/Format/Internal/PSM/PSMFileReader.cs b/PckStuido.ModelSupport/Format/Internal/PSM/PSMFileReader.cs new file mode 100644 index 00000000..40579ea3 --- /dev/null +++ b/PckStuido.ModelSupport/Format/Internal/PSM/PSMFileReader.cs @@ -0,0 +1,156 @@ +using System.Diagnostics; +using System.IO; +using System.Text; +using OMI; +using OMI.Workers; +using PckStudio.Core.FileFormats; +using PckStudio.Core; +using PckStudio.Core.Skin; + +namespace PckStudio.ModelSupport.Internal.Format +{ + internal class PSMFileReader : IDataFormatReader, IDataFormatReader + { + public PSMFile FromFile(string filename) + { + if (File.Exists(filename)) + { + using (var fs = File.OpenRead(filename)) + { + return FromStream(fs); + } + } + throw new FileNotFoundException(filename); + } + + public PSMFile FromStream(Stream stream) + { + using var reader = new EndiannessAwareBinaryReader(stream, Encoding.ASCII, leaveOpen: true, ByteOrder.LittleEndian); + + var magic = reader.ReadString(3); + if (magic != PSMFile.HEADER_MAGIC) + { + Trace.TraceError("PSMFileReader.FromStream - Failed to load csmb.\n\tReason: Header magic mismatch."); + return new PSMFile(byte.MaxValue); + } + + byte version = reader.ReadByte(); + if (version < 1 || version > 1) + { + Trace.TraceError("PSMFileReader.FromStream - Failed to load csmb.\n\tReason: Unsupported version."); + return new PSMFile(byte.MaxValue); + } + + var skinANIM = SkinANIM.FromValue(reader.ReadInt32()); + PSMFile csmbFile = new PSMFile(version, skinANIM); + int numOfParts = reader.ReadInt32(); + for (int i = 0; i < numOfParts; i++) + { + SkinBOX part = ReadPart(reader); + csmbFile.Parts.Add(part); + } + int numOfOffsets = reader.ReadInt32(); + for (int i = 0; i < numOfOffsets; i++) + { + SkinPartOffset offset = ReadOffset(reader); + csmbFile.Offsets.Add(offset); + } + + return csmbFile; + } + + private SkinBOX ReadPart(EndiannessAwareBinaryReader reader) + { + string type = GetParentType((PSMParentType)reader.ReadByte()); + float posX = reader.ReadSingle(); + float posY = reader.ReadSingle(); + float posZ = reader.ReadSingle(); + float sizeX = reader.ReadSingle(); + float sizeY = reader.ReadSingle(); + float sizeZ = reader.ReadSingle(); + byte mirrorAndUvX = reader.ReadByte(); + byte hideWithArmorAndUvY = reader.ReadByte(); + int uvX = mirrorAndUvX & 0x7f; + int uvY = hideWithArmorAndUvY & 0x7f; + bool mirror = (mirrorAndUvX & 0x80) != 0; + bool hideWithArmor = (hideWithArmorAndUvY & 0x80) != 0; + float scale = reader.ReadSingle(); + return new SkinBOX(type, new System.Numerics.Vector3(posX, posY, posZ), new System.Numerics.Vector3(sizeX, sizeY, sizeZ), new System.Numerics.Vector2(uvX, uvY), hideWithArmor, mirror, scale); + } + + private SkinPartOffset ReadOffset(EndiannessAwareBinaryReader reader) + { + PSMOffsetType type = (PSMOffsetType)reader.ReadByte(); + float value = reader.ReadSingle(); + return new SkinPartOffset(GetOffsetType(type), value); + } + + private static string GetParentType(PSMParentType type) + { + switch (type) + { + case PSMParentType.HEAD: + return "HEAD"; + case PSMParentType.BODY: + return "BODY"; + case PSMParentType.ARM0: + return "ARM0"; + case PSMParentType.ARM1: + return "ARM1"; + case PSMParentType.LEG0: + return "LEG0"; + case PSMParentType.LEG1: + return "LEG1"; + default: + throw new InvalidDataException(type.ToString()); + } + } + + private static string GetOffsetType(PSMOffsetType type) + { + switch (type) + { + case PSMOffsetType.HEAD: + return "HEAD"; + case PSMOffsetType.BODY: + return "BODY"; + case PSMOffsetType.ARM0: + return "ARM0"; + case PSMOffsetType.ARM1: + return "ARM1"; + case PSMOffsetType.LEG0: + return "LEG0"; + case PSMOffsetType.LEG1: + return "LEG1"; + case PSMOffsetType.TOOL0: + return "TOOL0"; + case PSMOffsetType.TOOL1: + return "TOOL1"; + case PSMOffsetType.HELMET: + return "HELMET"; + case PSMOffsetType.SHOULDER0: + return "SHOULDER0"; + case PSMOffsetType.SHOULDER1: + return "SHOULDER1"; + case PSMOffsetType.CHEST: + return "CHEST"; + case PSMOffsetType.WAIST: + return "WAIST"; + case PSMOffsetType.PANTS0: + return "PANTS0"; + case PSMOffsetType.PANTS1: + return "PANTS1"; + case PSMOffsetType.BOOT0: + return "BOOT0"; + case PSMOffsetType.BOOT1: + return "BOOT1"; + default: + throw new InvalidDataException(type.ToString()); + } + } + + object IDataFormatReader.FromStream(Stream stream) => FromStream(stream); + + object IDataFormatReader.FromFile(string filename) => FromFile(filename); + } +} diff --git a/PckStuido.ModelSupport/Format/Internal/PSM/PSMFileWriter.cs b/PckStuido.ModelSupport/Format/Internal/PSM/PSMFileWriter.cs new file mode 100644 index 00000000..aebb3144 --- /dev/null +++ b/PckStuido.ModelSupport/Format/Internal/PSM/PSMFileWriter.cs @@ -0,0 +1,134 @@ +using System.IO; +using System.Text; +using PckStudio.Core.FileFormats; +using OMI.Workers; +using OMI; +using System; +using OpenTK; +using PckStudio.Core.Skin; + +namespace PckStudio.ModelSupport.Internal.Format +{ + internal class PSMFileWriter : IDataFormatWriter + { + PSMFile _PSM; + + public PSMFileWriter(PSMFile csmb) + { + _PSM = csmb; + } + + public void WriteToFile(string filename) + { + using(var fs = File.OpenWrite(filename)) + { + WriteToStream(fs); + } + } + + public void WriteToStream(Stream stream) + { + using (var writer = new EndiannessAwareBinaryWriter(stream, Encoding.ASCII, leaveOpen: true, ByteOrder.LittleEndian)) + { + writer.WriteString(PSMFile.HEADER_MAGIC); + writer.Write(_PSM.Version); + writer.Write(_PSM.SkinANIM.ToValue()); + writer.Write(_PSM.Parts.Count); + foreach (SkinBOX part in _PSM.Parts) + { + WritePart(writer, part); + } + writer.Write(_PSM.Offsets.Count); + foreach (SkinPartOffset offset in _PSM.Offsets) + { + writer.Write((byte)GetOffsetPart(offset.Type)); + writer.Write(offset.Value); + } + } + } + + private void WritePart(EndiannessAwareBinaryWriter writer, SkinBOX part) + { + writer.Write((byte)GetParentPart(part.Type)); + writer.Write(part.Pos.X); + writer.Write(part.Pos.Y); + writer.Write(part.Pos.Z); + writer.Write(part.Size.X); + writer.Write(part.Size.Y); + writer.Write(part.Size.Z); + + byte uvX = (byte)MathHelper.Clamp((int)part.UV.X, 0, 64); + byte uvY = (byte)MathHelper.Clamp((int)part.UV.Y, 0, 64); + byte mirrorAndUvX = (byte)(Convert.ToByte(part.Mirror) << 7 | uvX); + byte hideWithArmorAndUvY = (byte)(Convert.ToByte(part.HideWithArmor) << 7 | uvY); + + writer.Write(mirrorAndUvX); + writer.Write(hideWithArmorAndUvY); + writer.Write(part.Scale); + } + + private static PSMParentType GetParentPart(string type) + { + switch (type) + { + case "HEAD": + return PSMParentType.HEAD; + case "BODY": + return PSMParentType.BODY; + case "ARM0": + return PSMParentType.ARM0; + case "ARM1": + return PSMParentType.ARM1; + case "LEG0": + return PSMParentType.LEG0; + case "LEG1": + return PSMParentType.LEG1; + default: + throw new InvalidDataException(type); + } + } + + private static PSMOffsetType GetOffsetPart(string type) + { + switch (type) + { + case "HEAD": + return PSMOffsetType.HEAD; + case "BODY": + return PSMOffsetType.BODY; + case "ARM0": + return PSMOffsetType.ARM0; + case "ARM1": + return PSMOffsetType.ARM1; + case "LEG0": + return PSMOffsetType.LEG0; + case "LEG1": + return PSMOffsetType.LEG1; + case "TOOL0": + return PSMOffsetType.TOOL0; + case "TOOL1": + return PSMOffsetType.TOOL1; + case "HELMET": + return PSMOffsetType.HELMET; + case "SHOULDER0": + return PSMOffsetType.SHOULDER0; + case "SHOULDER1": + return PSMOffsetType.SHOULDER1; + case "CHEST": + return PSMOffsetType.CHEST; + case "WAIST": + return PSMOffsetType.WAIST; + case "PANTS0": + return PSMOffsetType.PANTS0; + case "PANTS1": + return PSMOffsetType.PANTS1; + case "BOOT0": + return PSMOffsetType.BOOT0; + case "BOOT1": + return PSMOffsetType.BOOT1; + default: + throw new InvalidDataException(type); + } + } + } +} diff --git a/PckStuido.ModelSupport/GameModelImporter.cs b/PckStuido.ModelSupport/GameModelImporter.cs new file mode 100644 index 00000000..5730d551 --- /dev/null +++ b/PckStuido.ModelSupport/GameModelImporter.cs @@ -0,0 +1,239 @@ +/* Copyright (c) 2024-present miku-666 + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1.The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. +**/ +using System; +using System.IO; +using System.Linq; +using System.Drawing; +using System.Numerics; +using System.Diagnostics; +using System.Collections.Generic; +using System.Collections.ObjectModel; + +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +using OMI.Formats.Model; + +using PckStudio.Core.Json; +using PckStudio.Core.Extensions; +using PckStudio.Core; +using PckStudio.ModelSupport.Format.External; +using PckStuido.ModelSupport.Properties; +using NamedTexture = PckStudio.Core.NamedData; + +namespace PckStudio.ModelSupport +{ + public sealed class GameModelImporter : ModelImporter + { + public static GameModelImporter Default { get; } = new GameModelImporter(); + + public sealed class ModelExportSettings + { + public bool CreateModelOutline { get; set; } = true; + } + + public ModelExportSettings ExportSettings { get; } = new ModelExportSettings(); + + public sealed class ModelImportSettings + { + public int ModelVersion { get; set; } = 1; + } + + public ModelImportSettings ImportSettings { get; } = new ModelImportSettings(); + + public static ReadOnlyDictionary ModelMetaData { get; } = JsonConvert.DeserializeObject>(Resources.modelMetaData); + public static ReadOnlyDictionary DefaultModels { get; } = JsonConvert.DeserializeObject>(Resources.defaultModels); + + private GameModelImporter() + { + // TODO: add import functionality -miku + InternalAddProvider(new FileDialogFilter("Block bench model(*.bbmodel)", "*.bbmodel"), ImportBlockBenchModel, ExportBlockBenchModel); + } + + private readonly Vector3 bbModelTransformAxis = new Vector3(1, 1, 0); + // maybe get this value from the json. -miku + private readonly Vector3 _heightOffset = Vector3.UnitY * 24f; + + private void ExportBlockBenchModel(string filepath, GameModelInfo modelInfo) + { + BlockBenchModel blockBenchModel = BlockBenchModel.Create(BlockBenchFormatInfos.BedrockEntity, modelInfo.Model.Name, modelInfo.Model.TextureSize, modelInfo.Textures.Select(nt => (Texture)nt)); + blockBenchModel.ModelIdentifier = modelInfo.Model.Name; + + List elements = new List(modelInfo.Model.PartCount); + + if (!ModelMetaData.TryGetValue(modelInfo.Model.Name, out JsonModelMetaData modelMetaData)) + { + Trace.TraceError($"[{nameof(GameModelImporter)}:{nameof(ExportBlockBenchModel)}] Failed to get model meta data for '{modelInfo.Model.Name}'."); + return; + } + + IEnumerable outlines = ConvertToOutlines(modelInfo.Model, Vector3.Zero, modelMetaData.RootParts, elements.AddRange); + + blockBenchModel.Elements = elements.ToArray(); + if (ExportSettings.CreateModelOutline) + outlines = new Outline[1] + { + new Outline(modelInfo.Model.Name) { Children = JArray.FromObject(outlines) } + }; + + blockBenchModel.Outliner = JArray.FromObject(outlines); + + string content = JsonConvert.SerializeObject(blockBenchModel, Formatting.Indented); + File.WriteAllText(filepath, content); + } + + private Element ToElement(string partName, ModelBox modelBox, Vector3 partTranslation) + { + Element element = CreateElement(partName, modelBox, partTranslation, bbModelTransformAxis, _heightOffset); + //element.Rotation = rotation * TransformSpace(Vector3.One, Vector3.Zero, bbModelTransformAxis); + //element.Origin = outline.Origin; + return element; + } + + private Outline[] ConvertToOutlines(Model model, Vector3 parentRotation, IReadOnlyCollection keyValues, Action addElements, int depth = 0) + { + Outline CreateOutline(ModelPart modelPart) + { + Outline outline = new Outline(modelPart.Name); + + Vector3 partTranslation = modelPart.Translation; + outline.Origin = TransformSpace(partTranslation, Vector3.Zero, bbModelTransformAxis); + outline.Origin += _heightOffset; + + Vector3 rotation = modelPart.Rotation; + outline.Rotation = rotation * TransformSpace(Vector3.One, Vector3.Zero, bbModelTransformAxis); + outline.Rotation += parentRotation; + + Element[] elements1 = modelPart.GetBoxes().Select(box => ToElement(modelPart.Name, box, partTranslation)).ToArray(); + addElements(elements1); + + outline.Children.Add(elements1.Select(element => element.Uuid).ToArray()); + return outline; + } + + if (depth == 0 && keyValues.Count == 0) + { + return model.GetParts().Select(CreateOutline).ToArray(); + } + + List outlines = new List(); + foreach (ModelMetaDataPart item in keyValues) + { + if (!model.TryGetPart(item.Name, out ModelPart modelPart)) + { + Debug.WriteLine($"{nameof(item.Name)}: '{item.Name}' not in {nameof(model)}."); + continue; + } + Outline partentOutline = CreateOutline(modelPart); + JToken[] s = ConvertToOutlines(model, modelPart.Rotation, item.Children, addElements, depth + 1).Select(JToken.FromObject).ToArray(); + partentOutline.Children.Add(s); + outlines.Add(partentOutline); + } + return outlines.ToArray(); + } + + + private static Element CreateElement(string name, ModelBox box, Vector3 origin, Vector3 translationUnit, Vector3 offset) + { + Vector3 pos = box.Position; + Vector3 size = box.Size; + Vector3 transformPos = TransformSpace(pos + origin, size, translationUnit) + offset; + return Element.CreateCube(name, box.Uv, transformPos, size, box.Inflate, box.Mirror); + } + + private GameModelInfo ImportBlockBenchModel(string filepath) + { + BlockBenchModel blockBenchModel = JsonConvert.DeserializeObject(File.ReadAllText(filepath)); + if (!blockBenchModel.Format.UseBoxUv) + { + Trace.TraceError($"[{nameof(GameModelImporter)}:{nameof(ImportBlockBenchModel)}] Failed to import model '{blockBenchModel.ModelIdentifier}': Model does not use box uv."); + return null; + } + + if (!ModelMetaData.TryGetValue(blockBenchModel.ModelIdentifier, out JsonModelMetaData modelMetaData)) + { + Trace.TraceError($"[{nameof(GameModelImporter)}:{nameof(ImportBlockBenchModel)}] Failed to import model '{blockBenchModel.ModelIdentifier}': No model meta data found."); + return null; + } + + IEnumerable textures = blockBenchModel.Textures + .Where(t => modelMetaData.TextureLocations.Any(texName => !string.IsNullOrEmpty(t.Name) && texName.EndsWith(Path.GetFileNameWithoutExtension(t.Name)))) + .Select(t => new NamedTexture(modelMetaData.TextureLocations.First(texName => texName.EndsWith(Path.GetFileNameWithoutExtension(t.Name))), (Image)t)); + + Model model = new Model(blockBenchModel.ModelIdentifier, blockBenchModel.TextureResolution); + + JArray rootOutline = blockBenchModel.Outliner + .FirstOrDefault(token => token.Type == JTokenType.Object && token.ToObject().Name == blockBenchModel.ModelIdentifier) + ?.ToObject().Children ?? blockBenchModel.Outliner; + + foreach (Outline outline in rootOutline.Where(token => token.Type == JTokenType.Object).Select(token => token.ToObject())) + { + foreach (ModelPart part in ConvertOutlineToModelPart(outline, blockBenchModel.Elements)) + { + model.AddPart(part); + } + } + + return new GameModelInfo(model, textures); + } + + private IEnumerable ConvertOutlineToModelPart(Outline root, IReadOnlyCollection elements) + { + List parts = new List( + root.Children + .Where(token => token.Type == JTokenType.Object) + .SelectMany(token => ConvertOutlineToModelPart(token.ToObject(), elements)) + ); + + IEnumerable modelBoxElements = root.Children + .Where(token => token.Type == JTokenType.String && Guid.TryParse(token.ToString(), out Guid _)) + .Select(token => elements.First(e => e.Uuid == Guid.Parse(token.ToString()))) + .Where(element => element.Type == "cube" && element.UseBoxUv && element.Export); + + Vector3 additionalRotation = new Vector3(); + Element first = modelBoxElements.FirstOrDefault() ?? new Element() { Rotation = Vector3.Zero }; + if (first.Rotation != Vector3.Zero) + { + if (!modelBoxElements.All(e => e.Rotation == first.Rotation)) + { + Trace.TraceError($"[{nameof(GameModelImporter)}:{nameof(ImportBlockBenchModel)}] Rotation can't be applied for single elements."); + return Enumerable.Empty(); + } + additionalRotation = first.Rotation; + } + Vector3 translation = TransformSpace(root.Origin - _heightOffset, Vector3.Zero, bbModelTransformAxis); + Vector3 rotation = TransformSpace(root.Rotation, Vector3.Zero, bbModelTransformAxis); + ModelPart part = new ModelPart(root.Name, string.Empty, translation, rotation, additionalRotation); + part.AddBoxes(modelBoxElements.Select(box => ConvertElementToModelBox(box, part.Translation))); + parts.Add(part); + return parts; + } + + private ModelBox ConvertElementToModelBox(Element element, Vector3 translation) + { + BoundingBox boundingBox = new BoundingBox(element.From, element.To); + + Vector3 pos = boundingBox.Start.ToNumericsVector(); + Vector3 size = boundingBox.Volume.ToNumericsVector(); + + Vector3 transformedPos = TransformSpace(pos, size, bbModelTransformAxis) - translation + _heightOffset; + + return new ModelBox(transformedPos, size, element.UvOffset, element.Inflate, element.MirrorUv); + } + } +} diff --git a/PckStuido.ModelSupport/GameModelInfo.cs b/PckStuido.ModelSupport/GameModelInfo.cs new file mode 100644 index 00000000..dd53eb5a --- /dev/null +++ b/PckStuido.ModelSupport/GameModelInfo.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using OMI.Formats.Model; +using NamedTexture = PckStudio.Core.NamedData; + +namespace PckStudio.ModelSupport +{ + public sealed class GameModelInfo + { + public Model Model { get; } + + public IEnumerable Textures { get; } + + public GameModelInfo(Model model, IEnumerable textures) + { + Model = model; + Textures = textures; + } + + } +} diff --git a/PckStuido.ModelSupport/Json/JsonDefaultModel.cs b/PckStuido.ModelSupport/Json/JsonDefaultModel.cs new file mode 100644 index 00000000..2fb3aadc --- /dev/null +++ b/PckStuido.ModelSupport/Json/JsonDefaultModel.cs @@ -0,0 +1,48 @@ +using System; +using System.Numerics; +using Newtonsoft.Json; + +namespace PckStudio.Core.Json +{ + public class DefaultModel + { + [JsonProperty("textureSize", Required = Required.Always)] + public Vector2 TextureSize { get; set; } + + [JsonProperty("parts", Required = Required.Always)] + public DefaultPart[] Parts { get; set; } = Array.Empty(); + } + + public class DefaultPart + { + [JsonProperty("name", Required = Required.Always)] + public string Name { get; set; } + + [JsonProperty("translation")] + public Vector3 Translation { get; set; } = Vector3.Zero; + + [JsonProperty("rotation")] + public Vector3 Rotation { get; set; } = Vector3.Zero; + + [JsonProperty("boxes")] + public ModelDefaultBox[] Boxes { get; set; } + } + + public class ModelDefaultBox + { + [JsonProperty("pos")] + public Vector3 Position { get; set; } + + [JsonProperty("size")] + public Vector3 Size { get; set; } + + [JsonProperty("uv")] + public Vector2 Uv { get; set; } + + [JsonProperty("mirror")] + public bool Mirror { get; set; } = false; + + [JsonProperty("inflate")] + public float Inflate { get; set; } = 0f; + } +} diff --git a/PckStuido.ModelSupport/Json/JsonModelMetaData.cs b/PckStuido.ModelSupport/Json/JsonModelMetaData.cs new file mode 100644 index 00000000..d274cfb3 --- /dev/null +++ b/PckStuido.ModelSupport/Json/JsonModelMetaData.cs @@ -0,0 +1,46 @@ +using System; +using System.Numerics; +using Newtonsoft.Json; + +namespace PckStudio.Core.Json +{ + public class ModelMetaDataPart + { + [JsonProperty("name", Required = Required.Always)] + public string Name { get; set; } + + [JsonProperty("children", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] + public ModelMetaDataPart[] Children { get; set; } = Array.Empty(); + + [JsonConstructor] + public ModelMetaDataPart() + { + } + + public ModelMetaDataPart(string name) + : this(name, Array.Empty()) + { + } + + public ModelMetaDataPart(string name, params ModelMetaDataPart[] children) + { + Name = name; + Children = children; + } + } + + public class JsonModelMetaData + { + [JsonProperty("textureLocations", Required = Required.Always)] + public string[] TextureLocations { get; set; } + + [JsonProperty("materialName", NullValueHandling = NullValueHandling.Ignore)] + public string MaterialName { get; set; } = string.Empty; + + [JsonProperty("uv_offsets", NullValueHandling = NullValueHandling.Ignore)] + public Vector2[] UvOffsets { get; set; } = Array.Empty(); + + [JsonProperty("parts", NullValueHandling = NullValueHandling.Ignore)] + public ModelMetaDataPart[] RootParts { get; set; } = Array.Empty(); + } +} diff --git a/PckStuido.ModelSupport/ModelImporter.cs b/PckStuido.ModelSupport/ModelImporter.cs new file mode 100644 index 00000000..ee32a94a --- /dev/null +++ b/PckStuido.ModelSupport/ModelImporter.cs @@ -0,0 +1,178 @@ +/* Copyright (c) 2024-present miku-666 + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1.The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. +**/ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Numerics; +using PckStudio.Core; +using PckStudio.Interfaces; + +namespace PckStudio.ModelSupport +{ + public abstract class ModelImporter where T : class + { + private Dictionary> _importProviders = new Dictionary>(); + + private sealed class InternalImportProvider : IModelImportProvider + { + public string Name => nameof(InternalImportProvider); + + public FileDialogFilter DialogFilter => _dialogFilter; + + public bool SupportImport => _import != null; + + public bool SupportExport => _export != null; + + private FileDialogFilter _dialogFilter; + private Func _import; + private Action _export; + + public InternalImportProvider(FileDialogFilter dialogFilter, Func import, Action export) + { + _dialogFilter = dialogFilter; + _import = import; + _export = export; + } + + public void Export(string filename, T model) + { + _ = _export ?? throw new NotImplementedException(); + _export(filename, model); + } + + public T Import(string filename) + { + _ = _import ?? throw new NotImplementedException(); + return _import(filename); + } + + public void Export(ref Stream stream, T model) + { + throw new NotImplementedException(); + } + + public T Import(Stream stream) + { + throw new NotImplementedException(); + } + } + + /// + /// Filter that can be used for or + /// + public string SupportedModelFileFormatsFilter => string.Join("|", _importProviders.Values.Select(p => p.DialogFilter)); + + public T Import(string filename) + { + if (!File.Exists(filename)) + { + Trace.TraceWarning($"[{nameof(ModelImporter)}:Import] Failed to import '{filename}'. File does not exist."); + return default; + } + + if (!HasProvider(filename)) + { + Trace.TraceWarning($"[{nameof(ModelImporter)}:Import] No provider found for '{Path.GetExtension(filename)}'."); + return default; + } + + IModelImportProvider provider = GetProvider(filename); + if (!provider.SupportImport) + { + throw new NotSupportedException($"Provider '{provider.Name}' does not support importing."); + } + + return provider.Import(filename); + } + + public void Export(string filename, T model) + { + if (model is null) + { + Trace.TraceError($"[{nameof(ModelImporter)}:Export] Model is null."); + return; + } + + if (!HasProvider(filename)) + { + Trace.TraceWarning($"[{nameof(ModelImporter)}:Export] No provider found for '{Path.GetExtension(filename)}'."); + return; + } + + IModelImportProvider provider = GetProvider(filename); + if (!provider.SupportExport) + { + throw new NotSupportedException($"Provider '{provider.Name}' does not support exporting."); + } + provider.Export(filename, model); + } + + internal bool AddProvider(IModelImportProvider provider) + { + if (_importProviders.ContainsKey(provider.DialogFilter.Extension)) + return false; + + _importProviders.Add(provider.DialogFilter.Extension, provider); + return true; + } + + protected bool InternalAddProvider(FileDialogFilter dialogFilter, Func import, Action export) + { + return AddProvider(new InternalImportProvider(dialogFilter, import, export)); + } + + /// + /// Translates coordinate unit system into our coordinate system + /// + /// Position/Origin of the Object(Cube). + /// The Size of the Object(Cube). + /// Describes what axises need translation. + /// The translated position + protected static Vector3 TransformSpace(Vector3 origin, Vector3 size, Vector3 translationUnit) + { + // The translation unit describes what axises need to be swapped + // Example: + // translation unit = (1, 0, 0) => This translation unit will ONLY swap the X axis + translationUnit = Vector3.Clamp(translationUnit, Vector3.Zero, Vector3.One); + // To better understand see: + // https://sharplab.io/#v2:C4LgTgrgdgNAJiA1AHwAICYCMBYAUKgBgAJVMA6AOQgFsBTMASwGMBnAbj1QGYT0iBhIgG88RMb3SjxI3OLlEAbgEMwRBlAAOEYEQC8RKLQDuRAGq0mwAPZguACkwwijogQCUHWfLHLVtAB4aFsC0cHoGxmbBNvYAtC7xTpgeUt6+RGC0LOEAKmBKUCwAYjbU/FY2cOpKISx26lrAKV7epACcdpkszd5i7Z1ZevoBQZahPeIAvqlEM9wkmABsUZYxRHkFxaXlldW1duartmqa2m4zMr2KKhmD+ofWtmT8ADZK1Br1p8BODzFkAC16FZftEngB5QwTbxdIgAKn06E8V1hsXuYK4ZEhtGRvVQAHYiLEurixNNcJMgA + Vector3 transformUnit = -((translationUnit * 2) - Vector3.One); + + Vector3 pos = origin; + // The next line essentialy does uses the fomular below just on all axis. + // x = -(pos.x + size.x) + pos *= transformUnit; + pos -= size * translationUnit; + return pos; + } + + private bool HasProvider(string filename) + { + string fileExtension = Path.GetExtension(filename); + return _importProviders.ContainsKey(fileExtension) && _importProviders[fileExtension] is not null; + } + + private IModelImportProvider GetProvider(string filename) + { + string fileExtension = Path.GetExtension(filename); + return _importProviders.ContainsKey(fileExtension) ? _importProviders[fileExtension] : null; + } + } +} diff --git a/PckStuido.ModelSupport/PckStuido.ModelSupport.csproj b/PckStuido.ModelSupport/PckStuido.ModelSupport.csproj new file mode 100644 index 00000000..d7697c87 --- /dev/null +++ b/PckStuido.ModelSupport/PckStuido.ModelSupport.csproj @@ -0,0 +1,96 @@ + + + + + Debug + AnyCPU + {43BCACD7-5405-4499-9B45-E1435AC03C26} + Library + NDEBUG + Properties + PckStuido.ModelSupport + PckStuido.ModelSupport + v4.8 + 12 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + Resources.resx + + + + + + + 13.0.3 + + + + + {345eabed-f0d1-4d04-b409-babdef747352} + PckStudio.Core + + + {693aebc1-293d-4df0-bcae-26a1099fe7bb} + OMI Filetype Library + + + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + + + + + + \ No newline at end of file diff --git a/PckStuido.ModelSupport/Properties/AssemblyInfo.cs b/PckStuido.ModelSupport/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..4e98a15b --- /dev/null +++ b/PckStuido.ModelSupport/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("PckStuido.ModelSupport")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("PckStuido.ModelSupport")] +[assembly: AssemblyCopyright("Copyright © 2025")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("43bcacd7-5405-4499-9b45-e1435ac03c26")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/PckStuido.ModelSupport/Properties/Resources.Designer.cs b/PckStuido.ModelSupport/Properties/Resources.Designer.cs new file mode 100644 index 00000000..b98cf665 --- /dev/null +++ b/PckStuido.ModelSupport/Properties/Resources.Designer.cs @@ -0,0 +1,120 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace PckStuido.ModelSupport.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PckStuido.ModelSupport.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to { + /// "bat": { + /// "textureSize": { "X": 64, "Y": 64 }, + /// "parts": [ + /// { + /// "name": "head", + /// "boxes": [ + /// { "pos": { "X": -3, "Y": -3, "Z": -3 }, "size": { "X": 6, "Y": 6, "Z": 6 }, "uv": { "X": 0, "Y": 0 } } + /// ] + /// }, + /// { + /// "name": "body", + /// "boxes": [ + /// { "pos": { "X": -3, "Y": 4, "Z": -3 }, "size": { "X": 6, "Y": 12, "Z": 6 }, "uv": { "X": 0, "Y": 16 } }, + /// { "pos": { "X": -5, "Y": 16, "Z": 0 }, "size": { "X": 10, "Y": 6, "Z": [rest of string was truncated]";. + /// + internal static string defaultModels { + get { + return ResourceManager.GetString("defaultModels", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to { + /// "bat": { + /// "textureLocations": [ + /// "res/mob/bat" + /// ], + /// "materialName": "bat", + /// "parts": [ + /// { + /// "name": "head", + /// "children": [ + /// { "name": "rightEar" }, + /// { "name": "leftEar" } + /// ] + /// }, + /// { + /// "name": "body", + /// "children": [ + /// { + /// "name": "rightWing", + /// "children": [ + /// { "name": "rightWingTip" } + /// ] + /// }, + /// { + /// "name": "leftWing", + /// [rest of string was truncated]";. + /// + internal static string modelMetaData { + get { + return ResourceManager.GetString("modelMetaData", resourceCulture); + } + } + } +} diff --git a/PckStuido.ModelSupport/Properties/Resources.resx b/PckStuido.ModelSupport/Properties/Resources.resx new file mode 100644 index 00000000..b1909c61 --- /dev/null +++ b/PckStuido.ModelSupport/Properties/Resources.resx @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\defaultModels.json;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + + ..\Resources\modelMetaData.json;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 + + \ No newline at end of file diff --git a/PckStuido.ModelSupport/Resources/defaultModels.json b/PckStuido.ModelSupport/Resources/defaultModels.json new file mode 100644 index 00000000..c77963e9 --- /dev/null +++ b/PckStuido.ModelSupport/Resources/defaultModels.json @@ -0,0 +1,619 @@ +{ + "bat": { + "textureSize": { "X": 64, "Y": 64 }, + "parts": [ + { + "name": "head", + "boxes": [ + { "pos": { "X": -3, "Y": -3, "Z": -3 }, "size": { "X": 6, "Y": 6, "Z": 6 }, "uv": { "X": 0, "Y": 0 } } + ] + }, + { + "name": "body", + "boxes": [ + { "pos": { "X": -3, "Y": 4, "Z": -3 }, "size": { "X": 6, "Y": 12, "Z": 6 }, "uv": { "X": 0, "Y": 16 } }, + { "pos": { "X": -5, "Y": 16, "Z": 0 }, "size": { "X": 10, "Y": 6, "Z": 1 }, "uv": { "X": 0, "Y": 34 } } + ] + }, + { + "name": "rightEar", + "boxes": [ + { "pos": { "X": -4, "Y": -6, "Z": -2 }, "size": { "X": 3, "Y": 4, "Z": 1 }, "uv": { "X": 24, "Y": 0 } } + ] + }, + { + "name": "leftEar", + "boxes": [ + { "pos": { "X": 1, "Y": -6, "Z": -2 }, "size": { "X": 3, "Y": 4, "Z": 1 }, "uv": { "X": 24, "Y": 0 }, "mirror": true } + ] + }, + { + "name": "rightWing", + "boxes": [ + { "pos": { "X": -12, "Y": 1, "Z": 1.5 }, "size": { "X": 10, "Y": 16, "Z": 1 }, "uv": { "X": 42, "Y": 0 } } + ] + }, + { + "name": "rightWingTip", + "translation": { "X": -12, "Y": 1, "Z": 1.5 }, + "boxes": [ + { "pos": { "X": -8, "Y": 1, "Z": 0 }, "size": { "X": 8, "Y": 12, "Z": 1 }, "uv": { "X": 24, "Y": 16 } } + ] + }, + { + "name": "leftWing", + "boxes": [ + { "pos": { "X": 2, "Y": 1, "Z": 1.5 }, "size": { "X": 10, "Y": 16, "Z": 1 }, "uv": { "X": 42, "Y": 0 }, "mirror": true } + ] + }, + { + "name": "leftWingTip", + "translation": { "X": 12, "Y": 1, "Z": 1.5 }, + "boxes": [ + { "pos": { "X": 0, "Y": 1, "Z": 0 }, "size": { "X": 8, "Y": 12, "Z": 1 }, "uv": { "X": 24, "Y": 16 }, "mirror": true } + ] + } + ] + }, + "trident": { + "textureSize": { "X": 32, "Y": 32 }, + "parts": [ + { + "name": "pole", + "boxes": [ + { "pos": { "X": -0.5, "Y": -4, "Z": -0.5 }, "size": { "X": 1, "Y": 31, "Z": 1 }, "uv": { "X": 0, "Y": 0 } }, + { "pos": { "X": -1.5, "Y": 0, "Z": -0.5 }, "size": { "X": 3, "Y": 2, "Z": 1 }, "uv": { "X": 4, "Y": 0 } }, + { "pos": { "X": -2.5, "Y": -3, "Z": -0.5 }, "size": { "X": 1, "Y": 4, "Z": 1 }, "uv": { "X": 4, "Y": 3 } }, + { "pos": { "X": 1.5, "Y": -3, "Z": -0.5 }, "size": { "X": 1, "Y": 4, "Z": 1 }, "uv": { "X": 4, "Y": 3 }, "mirror": true } + ] + } + ] + }, + "irongolem": { + "textureSize": { "X": 128, "Y": 128 }, + "parts": [ + { + "name": "head", + "translation": { "X": 0, "Y": 0, "Z": -2 }, + "boxes": [ + { "pos": { "X": -4, "Y": -12, "Z": -5.5 }, "size": { "X": 8, "Y": 10, "Z": 8 }, "uv": { "X": 0, "Y": 0 } }, + { "pos": { "X": -1, "Y": -5, "Z": -7.5 }, "size": { "X": 2, "Y": 4, "Z": 2 }, "uv": { "X": 24, "Y": 0 } } + ] + }, + { + "name": "body", + "boxes": [ + { "pos": { "X": -9, "Y": -2, "Z": -6 }, "size": { "X": 18, "Y": 12, "Z": 11 }, "uv": { "X": 0, "Y": 40 } }, + { "pos": { "X": -4.5, "Y": 10, "Z": -3 }, "size": { "X": 9, "Y": 5, "Z": 6 }, "uv": { "X": 0, "Y": 70 }, "inflate": 0.5 } + ] + }, + { + "name": "arm0", + "translation": { "X": 0, "Y": 0, "Z": 0 }, + "boxes": [ + { "pos": { "X": -13, "Y": -2.5, "Z": -3 }, "size": { "X": 4, "Y": 30, "Z": 6 }, "uv": { "X": 60, "Y": 58 } } + ] + }, + { + "name": "arm1", + "translation": { "X": 0, "Y": 0, "Z": 0 }, + "boxes": [ + { "pos": { "X": 9, "Y": -2.5, "Z": -3 }, "size": { "X": 4, "Y": 30, "Z": 6 }, "uv": { "X": 60, "Y": 21 } } + ] + }, + { + "name": "leg0", + "translation": { "X": -4, "Y": 18, "Z": 0 }, + "boxes": [ + { "pos": { "X": -3.5, "Y": -3, "Z": -3 }, "size": { "X": 6, "Y": 16, "Z": 5 }, "uv": { "X": 37, "Y": 0 } } + ] + }, + { + "name": "leg1", + "translation": { "X": 5, "Y": 18, "Z": 0 }, + "boxes": [ + { "pos": { "X": -3.5, "Y": -3, "Z": -3 }, "size": { "X": 6, "Y": 16, "Z": 5 }, "uv": { "X": 60, "Y": 0 }, "mirror": true } + ] + } + ] + }, + "dolphin": { + "textureSize": { "X": 64, "Y": 64 }, + "parts": [ + { + "name": "head", + "boxes": [ + { "pos": { "X": -4, "Y": -7, "Z": -6 }, "size": { "X": 8, "Y": 7, "Z": 6 }, "uv": { "X": 0, "Y": 0 } } + ] + }, + { + "name": "nose", + "translation": { "X": 0, "Y": 0, "Z": -10 }, + "boxes": [ + { "pos": { "X": -1, "Y": -2, "Z": 0 }, "size": { "X": 2, "Y": 2, "Z": 4 }, "uv": { "X": 0, "Y": 13 } } + ] + }, + { + "name": "body", + "translation": { "X": 0, "Y": 0, "Z": 0 }, + "rotation": { "X": 0, "Y": 0, "Z": 0 }, + "boxes": [ + { "pos": { "X": -4, "Y": -7, "Z": 0 }, "size": { "X": 8, "Y": 7, "Z": 13 }, "uv": { "X": 0, "Y": 13 } } + ] + }, + { + "name": "back_fin", + "translation": { "X": 0, "Y": -7, "Z": 7 }, + "boxes": [ + { "pos": { "X": -0.5, "Y": -5, "Z": -1 }, "size": { "X": 1, "Y": 5, "Z": 4 }, "uv": { "X": 29, "Y": 0 } } + ] + }, + { + "name": "left_fin", + "translation": { "X": 3, "Y": -1, "Z": 2 }, + "boxes": [ + { "pos": { "X": 0, "Y": -1, "Z": -1 }, "size": { "X": 8, "Y": 1, "Z": 4 }, "uv": { "X": 40, "Y": 0 } } + ] + }, + { + "name": "right_fin", + "translation": { "X": -3, "Y": -1, "Z": 2 }, + "boxes": [ + { "pos": { "X": -8, "Y": -1, "Z": -1 }, "size": { "X": 8, "Y": 1, "Z": 4 }, "uv": { "X": 40, "Y": 6 } } + ] + }, + { + "name": "tail", + "translation": { "X": 0, "Y": -2.5, "Z": 14 }, + "boxes": [ + { "pos": { "X": -2, "Y": -2.5, "Z": -1 }, "size": { "X": 4, "Y": 5, "Z": 11 }, "uv": { "X": 0, "Y": 33 } } + ] + }, + { + "name": "tail_fin", + "translation": { "X": 0, "Y": 0, "Z": 24 }, + "boxes": [ + { "pos": { "X": -5, "Y": -2.5, "Z": -1 }, "size": { "X": 10, "Y": 1, "Z": 6 }, "uv": { "X": 0, "Y": 49 } } + ] + } + ] + }, + "creeper_head": { + "textureSize": { "X": 64, "Y": 32 }, + "parts": [ + { + "name": "head", + "boxes": [ + { "pos": { "X": -4, "Y": -8, "Z": -4 }, "size": { "X": 8, "Y": 8, "Z": 8 }, "uv": { "X": 0, "Y": 0 } } + ] + } + ] + }, + "creeper": { + "textureSize": { "X": 64, "Y": 32 }, + "parts": [ + { + "name": "head", + "translation": { "X": 0, "Y": 6, "Z": 0 }, + "boxes": [ + { "pos": { "X": -4, "Y": -8, "Z": -4 }, "size": { "X": 8, "Y": 8, "Z": 8 }, "uv": { "X": 0, "Y": 0 } } + ] + }, + { + "name": "body", + "translation": { "X": 0, "Y": 6, "Z": 0 }, + "boxes": [ + { "pos": { "X": -4, "Y": 0, "Z": -2 }, "size": { "X": 8, "Y": 12, "Z": 4 }, "uv": { "X": 16, "Y": 16 } } + ] + }, + { + "name": "leg0", + "translation": { "X": -2, "Y": 18, "Z": 4 }, + "boxes": [ + { "pos": { "X": -2, "Y": 0, "Z": -2 }, "size": { "X": 4, "Y": 6, "Z": 4 }, "uv": { "X": 0, "Y": 16 } } + ] + }, + { + "name": "leg1", + "translation": { "X": 2, "Y": 18, "Z": 4 }, + "boxes": [ + { "pos": { "X": -2, "Y": 0, "Z": -2 }, "size": { "X": 4, "Y": 6, "Z": 4 }, "uv": { "X": 0, "Y": 16 } } + ] + }, + { + "name": "leg2", + "translation": { "X": -2, "Y": 18, "Z": -4 }, + "boxes": [ + { "pos": { "X": -2, "Y": 0, "Z": -2 }, "size": { "X": 4, "Y": 6, "Z": 4 }, "uv": { "X": 0, "Y": 16 } } + ] + }, + { + "name": "leg3", + "translation": { "X": 2, "Y": 18, "Z": -4 }, + "boxes": [ + { "pos": { "X": -2, "Y": 0, "Z": -2 }, "size": { "X": 4, "Y": 6, "Z": 4 }, "uv": { "X": 0, "Y": 16 } } + ] + } + ] + }, + "boat": { + "textureSize": { "X": 128, "Y": 64 }, + "parts": [ + { + "name": "bottom", + "translation": { "X": 0, "Y": 3, "Z": 1 }, + "rotation": { "X": 90, "Y": 0, "Z": 0 }, + "boxes": [ + { "pos": { "X": -14, "Y": -9, "Z": -3 }, "size": { "X": 28, "Y": 16, "Z": 3 }, "uv": { "X": 0, "Y": 0 } } + ] + }, + { + "name": "front", + "translation": { "X": 15, "Y": 4, "Z": 0 }, + "rotation": { "X": 0, "Y": 90, "Z": 0 }, + "boxes": [ + { "pos": { "X": -8, "Y": -7, "Z": -1 }, "size": { "X": 16, "Y": 6, "Z": 2 }, "uv": { "X": 0, "Y": 27 } } + ] + }, + { + "name": "back", + "translation": { "X": -15, "Y": 4, "Z": 4 }, + "rotation": { "X": 0, "Y": 270, "Z": 0 }, + "boxes": [ + { "pos": { "X": -13, "Y": -7, "Z": -1 }, "size": { "X": 18, "Y": 6, "Z": 2 }, "uv": { "X": 0, "Y": 19 } } + ] + }, + { + "name": "left", + "translation": { "X": 0, "Y": 4, "Z": 9 }, + "boxes": [ + { "pos": { "X": -14, "Y": -7, "Z": -1 }, "size": { "X": 28, "Y": 6, "Z": 2 }, "uv": { "X": 0, "Y": 43 } } + ] + }, + { + "name": "right", + "translation": { "X": 0, "Y": 4, "Z": -9 }, + "rotation": { "X": 0, "Y": 180, "Z": 0 }, + "boxes": [ + { "pos": { "X": -14, "Y": -7, "Z": -1 }, "size": { "X": 28, "Y": 6, "Z": 2 }, "uv": { "X": 0, "Y": 35 } } + ] + }, + { + "name": "paddle_left", + "translation": { "X": 3, "Y": -5, "Z": 9 }, + "rotation": { "X": 0, "Y": 0, "Z": 11.25 }, + "boxes": [ + { "pos": { "X": -1, "Y": 0, "Z": -5 }, "size": { "X": 2, "Y": 2, "Z": 18 }, "uv": { "X": 62, "Y": 0 } }, + { "pos": { "X": -1.001, "Y": -3, "Z": 8 }, "size": { "X": 1, "Y": 6, "Z": 7 }, "uv": { "X": 62, "Y": 0 } } + ] + }, + { + "name": "paddle_right", + "translation": { "X": 3, "Y": -5, "Z": -9 }, + "rotation": { "X": 0, "Y": 180, "Z": 11.25 }, + "boxes": [ + { "pos": { "X": -1, "Y": 0, "Z": -5 }, "size": { "X": 2, "Y": 2, "Z": 18 }, "uv": { "X": 62, "Y": 20 } }, + { "pos": { "X": 0.001, "Y": -3, "Z": 8 }, "size": { "X": 1, "Y": 6, "Z": 7 }, "uv": { "X": 62, "Y": 20 } } + ] + } + ] + }, + "bed":{ + "textureSize": { "X": 64, "Y": 128 }, + "parts": [ + { + "name": "bed", + "boxes": [ + { "pos": { "X": 0, "Y": 0, "Z": 0 }, "size": { "X": 16, "Y": 32, "Z": 6 }, "uv": { "X": 0, "Y": 0 } }, + { "pos": { "X": 3, "Y": 31, "Z": 6 }, "size": { "X": 10, "Y": 1, "Z": 3 }, "uv": { "X": 38, "Y": 2 } }, + { "pos": { "X": 3, "Y": 0, "Z": 6 }, "size": { "X": 10, "Y": 1, "Z": 3 }, "uv": { "X": 38, "Y": 38 } }, + { "pos": { "X": 15, "Y": 3, "Z": 6 }, "size": { "X": 1, "Y": 26, "Z": 3 }, "uv": { "X": 52, "Y": 6 } }, + { "pos": { "X": 0, "Y": 3, "Z": 6 }, "size": { "X": 1, "Y": 26, "Z": 3 }, "uv": { "X": 44, "Y": 6 } } + ] + }, + { + "name": "leg0", + "boxes": [ + { "pos": { "X": 0, "Y": 29, "Z": 6 }, "size": { "X": 3, "Y": 3, "Z": 3 }, "uv": { "X": 0, "Y": 44 } } + ] + }, + { + "name": "leg1", + "boxes": [ + { "pos": { "X": 13, "Y": 29, "Z": 6 }, "size": { "X": 3, "Y": 3, "Z": 3 }, "uv": { "X": 12, "Y": 44 } } + ] + }, + { + "name": "leg2", + "boxes": [ + { "pos": { "X": 0, "Y": 0, "Z": 6 }, "size": { "X": 3, "Y": 3, "Z": 3 }, "uv": { "X": 0, "Y": 38 } } + ] + }, + { + "name": "leg3", + "boxes": [ + { "pos": { "X": 13, "Y": 0, "Z": 6 }, "size": { "X": 3, "Y": 3, "Z": 3 }, "uv": { "X": 12, "Y": 38 } } + ] + } + ] + }, + "chicken": { + "textureSize": { "X": 64, "Y": 32 }, + "parts": [ + { + "name": "head", + "translation": { "X": 0, "Y": 15, "Z": -4 }, + "boxes": [ + { "pos": { "X": -2, "Y": -6, "Z": -2 }, "size": { "X": 4, "Y": 6, "Z": 3 }, "uv": { "X": 0, "Y": 0 } } + ] + }, + { + "name": "beak", + "translation": { "X": 0, "Y": 15, "Z": -4 }, + "boxes": [ + { "pos": { "X": -2, "Y": -4, "Z": -4 }, "size": { "X": 4, "Y": 2, "Z": 2 }, "uv": { "X": 14, "Y": 0 } } + ] + }, + { + "name": "comb", + "translation": { "X": 0, "Y": 15, "Z": -4 }, + "boxes": [ + { "pos": { "X": -1, "Y": -2, "Z": -3 }, "size": { "X": 2, "Y": 2, "Z": 2 }, "uv": { "X": 14, "Y": 4 } } + ] + }, + { + "name": "body", + "translation": { "X": 0, "Y": 16, "Z": 0 }, + "boxes": [ + { "pos": { "X": -3, "Y": -4, "Z": -3 }, "size": { "X": 6, "Y": 8, "Z": 6 }, "uv": { "X": 0, "Y": 9 } } + ] + }, + { + "name": "leg0", + "translation": { "X": -2, "Y": 19, "Z": 1 }, + "boxes": [ + { "pos": { "X": -1, "Y": 0, "Z": -3 }, "size": { "X": 3, "Y": 5, "Z": 3 }, "uv": { "X": 26, "Y": 0 } } + ] + }, + { + "name": "leg1", + "translation": { "X": 1, "Y": 19, "Z": 1 }, + "boxes": [ + { "pos": { "X": -1, "Y": 0, "Z": -3 }, "size": { "X": 3, "Y": 5, "Z": 3 }, "uv": { "X": 26, "Y": 0 } } + ] + }, + { + "name": "wing0", + "translation": { "X": -4, "Y": 13, "Z": 0 }, + "boxes": [ + { "pos": { "X": 0, "Y": 0, "Z": -3 }, "size": { "X": 1, "Y": 4, "Z": 6 }, "uv": { "X": 24, "Y": 13 } } + ] + }, + { + "name": "wing1", + "translation": { "X": 4, "Y": 13, "Z": 0 }, + "boxes": [ + { "pos": { "X": -1, "Y": 0, "Z": -3 }, "size": { "X": 1, "Y": 4, "Z": 6 }, "uv": { "X": 24, "Y": 13 } } + ] + } + ] + }, + "cow": { + "textureSize": { "X": 64, "Y": 32 }, + "parts": [ + { + "name": "head", + "translation": { "X": 0, "Y": 4, "Z": -8 }, + "boxes": [ + { "pos": { "X": -4, "Y": -4, "Z": -6 }, "size": { "X": 8, "Y": 8, "Z": 6 }, "uv": { "X": 0, "Y": 0 } }, + { "pos": { "X": -5, "Y": -5, "Z": -4 }, "size": { "X": 1, "Y": 3, "Z": 1 }, "uv": { "X": 22, "Y": 0 } }, + { "pos": { "X": 4, "Y": -5, "Z": -4 }, "size": { "X": 1, "Y": 3, "Z": 1 }, "uv": { "X": 22, "Y": 0 } } + ] + }, + { + "name": "body", + "translation": { "X": 0, "Y": 5, "Z": 2 }, + "rotation": { "X": 90, "Y": 0, "Z": 0 }, + "boxes": [ + { "pos": { "X": -6, "Y": -10, "Z": -7 }, "size": { "X": 12, "Y": 18, "Z": 10 }, "uv": { "X": 18, "Y": 4 } }, + { "pos": { "X": -2, "Y": 2, "Z": -8 }, "size": { "X": 4, "Y": 6, "Z": 1 }, "uv": { "X": 52, "Y": 0 } } + ] + }, + { + "name": "leg0", + "translation": { "X": -4, "Y": 12, "Z": 7 }, + "boxes": [ + { "pos": { "X": -2, "Y": 0, "Z": -2 }, "size": { "X": 4, "Y": 12, "Z": 4 }, "uv": { "X": 0, "Y": 16 } } + ] + }, + { + "name": "leg1", + "translation": { "X": 4, "Y": 12, "Z": 7 }, + "boxes": [ + { "pos": { "X": -2, "Y": 0, "Z": -2 }, "size": { "X": 4, "Y": 12, "Z": 4 }, "uv": { "X": 0, "Y": 16 } } + ] + }, + { + "name": "leg2", + "translation": { "X": -4, "Y": 12, "Z": -6 }, + "boxes": [ + { "pos": { "X": -2, "Y": 0, "Z": -2 }, "size": { "X": 4, "Y": 12, "Z": 4 }, "uv": { "X": 0, "Y": 16 } } + ] + }, + { + "name": "leg3", + "translation": { "X": 4, "Y": 12, "Z": -6 }, + "boxes": [ + { "pos": { "X": -2, "Y": 0, "Z": -2 }, "size": { "X": 4, "Y": 12, "Z": 4 }, "uv": { "X": 0, "Y": 16 } } + ] + } + ] + }, + "mooshroom": { + "textureSize": { "X": 64, "Y": 32 }, + "parts": [ + { + "name": "head", + "translation": { "X": 0, "Y": 4, "Z": -8 }, + "boxes": [ + { "pos": { "X": -4, "Y": -4, "Z": -6 }, "size": { "X": 8, "Y": 8, "Z": 6 }, "uv": { "X": 0, "Y": 0 } }, + { "pos": { "X": -5, "Y": -5, "Z": -4 }, "size": { "X": 1, "Y": 3, "Z": 1 }, "uv": { "X": 22, "Y": 0 } }, + { "pos": { "X": 4, "Y": -5, "Z": -4 }, "size": { "X": 1, "Y": 3, "Z": 1 }, "uv": { "X": 22, "Y": 0 } } + ] + }, + { + "name": "body", + "translation": { "X": 0, "Y": 5, "Z": 2 }, + "rotation": { "X": 90, "Y": 0, "Z": 0 }, + "boxes": [ + { "pos": { "X": -6, "Y": -10, "Z": -7 }, "size": { "X": 12, "Y": 18, "Z": 10 }, "uv": { "X": 18, "Y": 4 } }, + { "pos": { "X": -2, "Y": 2, "Z": -8 }, "size": { "X": 4, "Y": 6, "Z": 1 }, "uv": { "X": 52, "Y": 0 } } + ] + }, + { + "name": "leg0", + "translation": { "X": -4, "Y": 12, "Z": 7 }, + "boxes": [ + { "pos": { "X": -2, "Y": 0, "Z": -2 }, "size": { "X": 4, "Y": 12, "Z": 4 }, "uv": { "X": 0, "Y": 16 } } + ] + }, + { + "name": "leg1", + "translation": { "X": 4, "Y": 12, "Z": 7 }, + "boxes": [ + { "pos": { "X": -2, "Y": 0, "Z": -2 }, "size": { "X": 4, "Y": 12, "Z": 4 }, "uv": { "X": 0, "Y": 16 } } + ] + }, + { + "name": "leg2", + "translation": { "X": -4, "Y": 12, "Z": -6 }, + "boxes": [ + { "pos": { "X": -2, "Y": 0, "Z": -2 }, "size": { "X": 4, "Y": 12, "Z": 4 }, "uv": { "X": 0, "Y": 16 } } + ] + }, + { + "name": "leg3", + "translation": { "X": 4, "Y": 12, "Z": -6 }, + "boxes": [ + { "pos": { "X": -2, "Y": 0, "Z": -2 }, "size": { "X": 4, "Y": 12, "Z": 4 }, "uv": { "X": 0, "Y": 16 } } + ] + } + ] + }, + "dragon_head": { + "textureSize": { "X": 256, "Y": 256 }, + "parts": [ + { + "name": "head", + "boxes": [ + // upperlip + { "pos": { "X": -6, "Y": -1, "Z": -24 }, "size": { "X": 12, "Y": 5, "Z": 16 }, "uv": { "X": 176, "Y": 44 } }, + // upperhead + { "pos": { "X": -8, "Y": -8, "Z": -10 }, "size": { "X": 16, "Y": 16, "Z": 16 }, "uv": { "X": 112, "Y": 30 } }, + // scale + { "pos": { "X": 3, "Y": -12, "Z": -4 }, "size": { "X": 2, "Y": 4, "Z": 6 }, "uv": { "X": 0, "Y": 0 } }, + { "pos": { "X": -5, "Y": -12, "Z": -4 }, "size": { "X": 2, "Y": 4, "Z": 6 }, "uv": { "X": 0, "Y": 0 }, "mirror": true }, + // nostril + { "pos": { "X": 3, "Y": -3, "Z": -22 }, "size": { "X": 2, "Y": 2, "Z": 4 }, "uv": { "X": 112, "Y": 0 } }, + { "pos": { "X": -5, "Y": -3, "Z": -22 }, "size": { "X": 2, "Y": 2, "Z": 4 }, "uv": { "X": 112, "Y": 0 }, "mirror": true }, + ] + }, + { + "name": "jaw", + "translation": { "X": 0, "Y": 4, "Z": -8 }, + "boxes": [ + { "pos": { "X": -6, "Y": 0, "Z": -16 }, "size": { "X": 12, "Y": 4, "Z": 16 }, "uv": { "X": 176, "Y": 65 } } + ] + } + ] + }, + "pig": { + "textureSize": { "X": 64, "Y": 32 }, + "parts": [ + { + "name": "head", + "translation": { "X": 0, "Y": 12, "Z": -6 }, + "boxes": [ + { "pos": { "X": -4, "Y": -4, "Z": -8 }, "size": { "X": 8, "Y": 8, "Z": 8 }, "uv": { "X": 0, "Y": 0 } }, + { "pos": { "X": -2, "Y": 0, "Z": -9 }, "size": { "X": 4, "Y": 3, "Z": 1 }, "uv": { "X": 16, "Y": 16 } } + ] + }, + { + "name": "body", + "translation": { "X": 0, "Y": 11, "Z": 2 }, + "rotation": { "X": 90, "Y": 0, "Z": 0 }, + "boxes": [ + { "pos": { "X": -5, "Y": -10, "Z": -7 }, "size": { "X": 10, "Y": 16, "Z": 8 }, "uv": { "X": 28, "Y": 8 } } + ] + }, + { + "name": "leg0", + "translation": { "X": -3, "Y": 18, "Z": 7 }, + "boxes": [ + { "pos": { "X": -2, "Y": 0, "Z": -2 }, "size": { "X": 4, "Y": 6, "Z": 4 }, "uv": { "X": 0, "Y": 16 } } + ] + }, + { + "name": "leg1", + "translation": { "X": 3, "Y": 18, "Z": 7 }, + "boxes": [ + { "pos": { "X": -2, "Y": 0, "Z": -2 }, "size": { "X": 4, "Y": 6, "Z": 4 }, "uv": { "X": 0, "Y": 16 } } + ] + }, + { + "name": "leg2", + "translation": { "X": -3, "Y": 18, "Z": -5 }, + "boxes": [ + { "pos": { "X": -2, "Y": 0, "Z": -2 }, "size": { "X": 4, "Y": 6, "Z": 4 }, "uv": { "X": 0, "Y": 16 } } + ] + }, + { + "name": "leg3", + "translation": { "X": 3, "Y": 18, "Z": -5 }, + "boxes": [ + { "pos": { "X": -2, "Y": 0, "Z": -2 }, "size": { "X": 4, "Y": 6, "Z": 4 }, "uv": { "X": 0, "Y": 16 } } + ] + } + ] + }, + "snowgolem": { + "textureSize": { "X": 64, "Y": 64 }, + "parts": [ + { + "name": "head", + "translation": { "X": 0, "Y": 4, "Z": 0 }, + "boxes": [ + { "pos": { "X": -4, "Y": -8, "Z": -4 }, "size": { "X": 8, "Y": 8, "Z": 8 }, "uv": { "X": 0, "Y": 0 }, "inflate": -0.5 } + ] + }, + { + "name": "arm1", + "translation": { "X": 0, "Y": 6, "Z": 0 }, + "boxes": [ + { "pos": { "X": -1, "Y": 0, "Z": -1 }, "size": { "X": 12, "Y": 2, "Z": 2 }, "uv": { "X": 32, "Y": 0 }, "inflate": -0.5 } + ] + }, + { + "name": "arm2", + "translation": { "X": 0, "Y": 6, "Z": 0 }, + "boxes": [ + { "pos": { "X": -1, "Y": 0, "Z": -1 }, "size": { "X": 12, "Y": 2, "Z": 2 }, "uv": { "X": 32, "Y": 0 }, "inflate": -0.5 } + ] + }, + { + "name": "piece1", + "translation": { "X": 0, "Y": 13, "Z": 0 }, + "boxes": [ + { "pos": { "X": -5, "Y": -10, "Z": -5 }, "size": { "X": 10, "Y": 10, "Z": 10 }, "uv": { "X": 0, "Y": 16 }, "inflate": -0.5 } + ] + }, + { + "name": "piece2", + "translation": { "X": 0, "Y": 24, "Z": 0 }, + "boxes": [ + { "pos": { "X": -6, "Y": -12, "Z": -6 }, "size": { "X": 12, "Y": 12, "Z": 12 }, "uv": { "X": 0, "Y": 36 }, "inflate": -0.5 } + ] + } + ] + } +} \ No newline at end of file diff --git a/PckStuido.ModelSupport/Resources/modelMetaData.json b/PckStuido.ModelSupport/Resources/modelMetaData.json new file mode 100644 index 00000000..9be05f36 --- /dev/null +++ b/PckStuido.ModelSupport/Resources/modelMetaData.json @@ -0,0 +1,739 @@ +{ + "bat": { + "textureLocations": [ + "res/mob/bat" + ], + "materialName": "bat", + "parts": [ + { + "name": "head", + "children": [ + { "name": "rightEar" }, + { "name": "leftEar" } + ] + }, + { + "name": "body", + "children": [ + { + "name": "rightWing", + "children": [ + { "name": "rightWingTip" } + ] + }, + { + "name": "leftWing", + "children": [ + { "name": "leftWingTip" } + ] + } + ] + } + ] + }, + "bed": { + "textureLocations": [ + "res/item/bed" + ], + "uv_offsets": [ {"X": 0, "Y": 64} ] + }, + "blaze": { + "textureLocations": [ + "res/mob/fire" + ], + "materialName": "blaze_head" + }, + "boat": { + "textureLocations": [ + "res/item/boat/boat_acacia", + "res/item/boat/boat_birch", + "res/item/boat/boat_darkoak", + "res/item/boat/boat_jungle", + "res/item/boat/boat_oak", + "res/item/boat/boat_spruce" + ] + }, + "chicken": { + "textureLocations": [ + "res/mob/chicken" + ] + }, + "cow": { + "textureLocations": [ + "res/mob/cow" + ] + }, + "creeper": { + "textureLocations": [ + "res/mob/creeper" + ] + }, + "creeper_head": { + "textureLocations": [ + "res/mob/creeper" + ] + }, + "dolphin": { + "textureLocations": [ + "res/mob/dolphin" + ], + "parts": [ + { + "name": "body", + "children": [ + { + "name": "head", + "children": [ { "name": "nose" } ] + }, + { + "name": "tail", + "children": [ { "name": "tail_fin" } ] + }, + { "name": "right_fin" }, + { "name": "left_fin" }, + { "name": "back_fin" } + ] + } + ] + }, + "dragon": { + "textureLocations": [ + "res/mob/enderdragon/ender" + ], + "materialName": "ender_dragon", + "parts": [ + { "name": "body" }, + // only needs to be inside when neck 1-5 aren't present + { "name": "neck" }, + + // neck 1-5 & tail 1-12 are not required to be inside the model + { "name": "neck1" }, + { "name": "neck2" }, + { "name": "neck3" }, + { "name": "neck4" }, + { "name": "neck5" }, + + { "name": "tail1" }, + { "name": "tail2" }, + { "name": "tail3" }, + { "name": "tail4" }, + { "name": "tail5" }, + { "name": "tail6" }, + { "name": "tail7" }, + { "name": "tail8" }, + { "name": "tail9" }, + { "name": "tail10" }, + { "name": "tail11" }, + { "name": "tail12" }, + + { + "name": "head", + "children": [ { "name": "jaw" } ] + }, + { + "name": "wing", + "children": [ { "name": "wingtip" } ] + }, + { + "name": "wing1", + "children": [ { "name": "wingtip1" } ] + }, + { + "name": "rearleg", + "children": [ + { + "name": "rearlegtip", + "children": [ { "name": "rearfoot" } ] + } + ] + }, + { + "name": "rearleg1", + "children": [ + { + "name": "rearlegtip1", + "children": [ { "name": "rearfoot1" } ] + } + ] + }, + { + "name": "frontleg", + "children": [ + { + "name": "frontlegtip", + "children": [ { "name": "frontfoot" } ] + } + ] + }, + { + "name": "frontleg1", + "children": [ + { + "name": "frontlegtip1", + "children": [ { "name": "frontfoot1" } ] + } + ] + } + ] + }, + "dragon_head": { + "textureLocations": [ + "res/mob/enderdragon/ender" + ], + "parts": [ + { + "name": "head", + "children": [ { "name": "jaw" } ] + } + ] + }, + "enderman": { + "textureLocations": [ + "res/mob/enderman" + ], + "materialName": "enderman" // "enderman_invisible" also valid + }, + "ghast": { + "textureLocations": [ + "res/mob/ghast", + "res/mob/ghast_fire" + ], + "materialName": "ghast" + }, + "guardian": { + "textureLocations": [ + "res/mob/guardian", + "res/mob/guardian_elder" + ], + "materialName": "guardian", + "parts": [ + { + "name": "head", + "children": [ + { "name": "eye" }, + { + "name": "tailpart0", + "children": [ + { + "name": "tailpart1", + "children": [ { "name": "tailpart2" } ] + } + ] + } + ] + } + ] + }, + "irongolem": { + "textureLocations": [ + "res/mob/villager_golem" + ], + "materialName": "iron_golem" + }, + "lavaslime": { + "textureLocations": [ + "res/mob/lava" + ], + "materialName": "magma_cube" + }, + "llama": { + "textureLocations": [ + "res/mob/llama/llama", + "res/mob/llama/llama_brown", + "res/mob/llama/llama_creamy", + "res/mob/llama/llama_gray", + "res/mob/llama/llama_white" + ] + }, + "llamaspit": { + "textureLocations": [ + "res/mob/llama/spit" + ] + }, + "minecart": { + "textureLocations": [ + "res/item/cart" + ] + }, + // the ocelot model is weird.. -miku + "ocelot": { + "textureLocations": [ + "res/mob/ozelot" + ] + }, + "parrot": { + "textureLocations": [ + "res/mob/parrot/parrot_blue", + "res/mob/parrot/parrot_green", + "res/mob/parrot/parrot_grey", + "res/mob/parrot/parrot_red_blue", + "res/mob/parrot/parrot_yellow_blue" + ], + "parts": [ + { + "name": "head", + "children": [ + { "name": "head2" }, + { "name": "beak1" }, + { "name": "beak2" }, + { "name": "feather" } + ] + }, + { "name": "body" }, + { "name": "tail" }, + { "name": "wing0" }, + { "name": "wing1" }, + { "name": "leg0" }, + { "name": "leg1" } + ] + }, + "phantom": { + "textureLocations": [ + "res/mob/phantom" + ], + "materialName": "phantom", // phantom_invisible is also valid + "parts": [ + { + "name": "body", + "children": [ + { "name": "head" }, + { + "name": "wing0", + "children": [ { "name": "wingtip0" } ] + }, + { + "name": "wing1", + "children": [ { "name": "wingtip1" } ] + }, + { + "name": "tail", + "children": [ { "name": "tailtip" } ] + } + ] + } + ] + }, + "pig": { + "textureLocations": [ + "res/mob/pig", + "res/mob/saddle" + ] + }, + "pigzombie": { + "textureLocations": [ + "res/mob/pigzombie" + ], + "materialName": "zombie_pigman" + }, + "polarbear": { + "textureLocations": [ + "res/mob/bear/polarbear" + ] + }, + "rabbit": { + "textureLocations": [ + "res/mob/rabbit/black", + "res/mob/rabbit/brown", + "res/mob/rabbit/caerbannog", + "res/mob/rabbit/gold", + "res/mob/rabbit/salt", + "res/mob/rabbit/toast", + "res/mob/rabbit/white", + "res/mob/rabbit/white_splotched" + ] + }, + "sheep": { + "textureLocations": [ + "res/mob/sheep", + "res/mob/sheep_fur" + ], + "materialName": "sheep" + }, + "sheep.sheared": { + "textureLocations": [ + "res/mob/sheep" + ], + "materialName": "sheep" + }, + "shulker": { + "textureLocations": [ + "res/mob/shulker/endergolem", + "res/mob/shulker/spark" + ], + "materialName": "shulker" + }, + "silverfish": { + "textureLocations": [ + "res/mob/silverfish" + ] + }, + "skeleton": { + "textureLocations": [ + "res/mob/skeleton" + ], + "materialName": "skeleton" + }, + "skeleton.stray": { + "textureLocations": [ + "res/mob/skeleton/stray" + ], + "materialName": "stray" + }, + "skeleton.wither": { + "textureLocations": [ + "res/mob/skeleton_wither" + ], + "materialName": "wither_skeleton" + }, + "slime": { + "textureLocations": [ + "res/mob/slime" + ] + }, + "slime.armor": { + "textureLocations": [ + "res/mob/slime" + ] + }, + "snowgolem": { + "textureLocations": [ + "res/mob/snowman" + ] + }, + "spider": { + "textureLocations": [ + "res/mob/spider", + "res/mob/cavespider" + ], + "materialName": "spider" // "spider_invisible" also valid + }, + "squid": { + "textureLocations": [ + "res/mob/squid" + ] + }, + "trident": { + "textureLocations": [ + "res/item/trident" + ] + }, + "turtle": { + "textureLocations": [ + "res/mob/sea_turtle" + ] + }, + "villager": { + "textureLocations": [ + "res/mob/villager/villager", + "res/mob/villager/butcher", + "res/mob/villager/farmer", + "res/mob/villager/librarian", + "res/mob/villager/priest", + "res/mob/villager/smith" + ] + }, + "villager.witch": { + "textureLocations": [ + "res/mob/witch" + ] + }, + "vex": { + "textureLocations": [ + "res/mob/illager/vex", + "res/mob/illager/vex_charging" + ] + }, + "evoker": { + "textureLocations": [ + "res/mob/illager/evoker" + ] + }, + "vindicator": { + "textureLocations": [ + "res/mob/illager/vindicator" + ] + }, + "witherBoss": { + "textureLocations": [ + "res/mob/wither/wither", + "res/mob/wither/wither_invulnerable" + ], + "materialName": "wither_boss" + }, + "wolf": { + "textureLocations": [ + "res/mob/wolf", + "res/mob/wolf_angry", + "res/mob/wolf_tame" + ], + "materialName": "wolf" + }, + "zombie": { + "textureLocations": [ + "res/mob/zombie" + ] + }, + "zombie.husk": { + "textureLocations": [ + "res/mob/zombie/husk" + ] + }, + "zombie.villager": { + "textureLocations": [ + "res/mob/zombie_villager/zombie_villager", + "res/mob/zombie_villager/zombie_butcher", + "res/mob/zombie_villager/zombie_farmer", + "res/mob/zombie_villager/zombie_librarian", + "res/mob/zombie_villager/zombie_priest", + "res/mob/zombie_villager/zombie_smith" + ] + }, + "horse.v2": { + // markings and armor not included + "textureLocations": [ + "res/mob/horse/donkey", + "res/mob/horse/horse_black", + "res/mob/horse/horse_brown", + "res/mob/horse/horse_chestnut", + "res/mob/horse/horse_creamy", + "res/mob/horse/horse_darkbrown", + "res/mob/horse/horse_gray", + "res/mob/horse/horse_skeleton", + "res/mob/horse/horse_white", + "res/mob/horse/horse_zombie", + "res/mob/horse/mule" + ], + "parts": [ + { + "name": "Neck", + "children": [ + { + "name": "Head", + "children": [ + { "name": "HeadSaddle" }, + { "name": "UMouth" }, + { "name": "Ear1" }, + { "name": "Ear2" }, + { "name": "MuleEarL" }, + { "name": "MuleEarR" }, + { "name": "SaddleMouthL" }, + { "name": "SaddleMouthR" } + ] + } + ] + }, + { + "name": "Body", + "children": [ + { "name": "TailA" }, + { "name": "Saddle" } + ] + }, + { "name": "Mane" }, + { "name": "Leg1A" }, + { "name": "Leg2A" }, + { "name": "Leg3A" }, + { "name": "Leg4A" }, + { "name": "Bag1" }, + { "name": "Bag2" }, + { "name": "SaddleMouthLine" }, + { "name": "SaddleMouthLineR" } + ] + }, + "cat": { + "textureLocations": [ + "res/mob/cat_black", + "res/mob/cat_red", + "res/mob/cat_siamese" + ] + }, + "zombie.drowned": { + "textureLocations": [ + "res/mob/zombie/drowned" + ], + "materialName": "drowned" + }, + "endermite": { + "textureLocations": [ + "res/mob/endermite" + ] + }, + "cod": { + "textureLocations": [ + "res/mob/fish/cod" + ] + }, + "pufferfish.small": { + "textureLocations": [ + "res/mob/fish/pufferfish" + ] + }, + "pufferfish.mid": { + "textureLocations": [ + "res/mob/fish/pufferfish" + ] + }, + "pufferfish.large": { + "textureLocations": [ + "res/mob/fish/pufferfish" + ] + }, + "salmon": { + "textureLocations": [ + "res/mob/fish/salmon" + ] + }, + "skeleton_head": { + "textureLocations": [ + "res/mob/skeleton" + ] + }, + "skeleton_wither_head": { + "textureLocations": [ + "res/mob/skeleton_wither" + ] + }, + "stray.armor": { + "textureLocations": [ + "res/mob/skeleton/stray_overlay" + ] + }, + "stray_armor": { + "textureLocations": [ + "res/mob/skeleton/stray_overlay" + ] + }, + "tropicalfish_a": { + "textureLocations": [ + "res/mob/fish/tropical_a", + "res/mob/fish/tropical_a_pattern_1", + "res/mob/fish/tropical_a_pattern_2", + "res/mob/fish/tropical_a_pattern_3", + "res/mob/fish/tropical_a_pattern_4", + "res/mob/fish/tropical_a_pattern_5", + "res/mob/fish/tropical_a_pattern_6" + ] + }, + "tropicalfish_b": { + "textureLocations": [ + "res/mob/fish/tropical_b", + "res/mob/fish/tropical_b_pattern_1", + "res/mob/fish/tropical_b_pattern_2", + "res/mob/fish/tropical_b_pattern_3", + "res/mob/fish/tropical_b_pattern_4", + "res/mob/fish/tropical_b_pattern_5", + "res/mob/fish/tropical_b_pattern_6" + ] + }, + "zombie_head": { + "textureLocations": [ + "res/mob/zombie" + ] + }, + "mooshroom": { + "textureLocations": [ + "res/mob/redcow" + ] + }, + "witherBoss.armor": { + "textureLocations": [ + "res/mob/wither/wither_armor" + ] + }, + + "villager_v2": { + "textureLocations": [ + "res/mob/villager/villagerBase1", + "res/mob/villager/villagerBase2", + "res/mob/villager/villagerBase3", + "res/mob/villager/villagerBase4", + "res/mob/villager/villagerBase5", + "res/mob/villager/villagerBase6", + + "res/mob/wandering_trader", + + "res/mob/villager/professions/armorer", + "res/mob/villager/professions/butcher", + "res/mob/villager/professions/cartographer", + "res/mob/villager/professions/cleric", + "res/mob/villager/professions/farmer", + "res/mob/villager/professions/fisherman", + "res/mob/villager/professions/fletcher", + "res/mob/villager/professions/leatherworker", + "res/mob/villager/professions/librarian", + "res/mob/villager/professions/nitwit", + "res/mob/villager/professions/shepherd", + "res/mob/villager/professions/stonemason", + "res/mob/villager/professions/toolsmith", + "res/mob/villager/professions/unskilled", + "res/mob/villager/professions/weaponsmith", + + "res/mob/villager/biomes/biome_desert", + "res/mob/villager/biomes/biome_jungle", + "res/mob/villager/biomes/biome_plains", + "res/mob/villager/biomes/biome_savanna", + "res/mob/villager/biomes/biome_snow", + "res/mob/villager/biomes/biome_swamp", + "res/mob/villager/biomes/biome_taiga", + + "res/mob/villager/levels/level_diamond", + "res/mob/villager/levels/level_gold", + "res/mob/villager/levels/level_iron" + ] + }, + "zombie.villager_v2": { + "textureLocations": [ + "res/mob/zombie_villager/zombie_villager", + "res/mob/zombie_villager/zombie_butcher", + "res/mob/zombie_villager/zombie_farmer", + "res/mob/zombie_villager/zombie_librarian", + "res/mob/zombie_villager/zombie_priest", + "res/mob/zombie_villager/zombie_smith", + + "res/mob/zombie_villager/biomes/biome-desert-zombie", + "res/mob/zombie_villager/biomes/biome-jungle-zombie", + "res/mob/zombie_villager/biomes/biome-plains-zombie", + "res/mob/zombie_villager/biomes/biome-savanna-zombie", + "res/mob/zombie_villager/biomes/biome-snow-zombie", + "res/mob/zombie_villager/biomes/biome-swamp-zombie", + "res/mob/zombie_villager/biomes/biome-taiga-zombie", + + "res/mob/zombie_villager/professions/armorer", + "res/mob/zombie_villager/professions/butcher", + "res/mob/zombie_villager/professions/cartographer", + "res/mob/zombie_villager/professions/cleric", + "res/mob/zombie_villager/professions/farmer", + "res/mob/zombie_villager/professions/fisherman", + "res/mob/zombie_villager/professions/fletcher", + "res/mob/zombie_villager/professions/leatherworker", + "res/mob/zombie_villager/professions/librarian", + "res/mob/zombie_villager/professions/nitwit", + "res/mob/zombie_villager/professions/shepherd", + "res/mob/zombie_villager/professions/stonemason", + "res/mob/zombie_villager/professions/toolsmith", + "res/mob/zombie_villager/professions/weaponsmith" + ] + }, + "pillager": { + "textureLocations": [ + "res/mob/pillager" + ] + }, + "ravager": { + "textureLocations": [ + "res/mob/illager/ravager" + ] + }, + + "panda": { + "textureLocations": [ + "res/mob/panda/panda", + "res/mob/panda/panda_aggressive", + "res/mob/panda/panda_brown", + "res/mob/panda/panda_lazy", + "res/mob/panda/panda_playful", + "res/mob/panda/panda_sneezy", + "res/mob/panda/panda_worried" + ] + } +} diff --git a/PckStuido.ModelSupport/SkinModelImporter.cs b/PckStuido.ModelSupport/SkinModelImporter.cs new file mode 100644 index 00000000..2cc7c2a8 --- /dev/null +++ b/PckStuido.ModelSupport/SkinModelImporter.cs @@ -0,0 +1,557 @@ +/* Copyright (c) 2024-present miku-666 + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1.The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. +**/ +using System; +using System.IO; +using System.Linq; +using System.Drawing; +using System.Numerics; +using System.Diagnostics; +using System.Windows.Forms; +using System.Drawing.Imaging; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +using PckStudio.Core; +using PckStudio.Core.Skin; +using PckStudio.Core.Extensions; +using PckStudio.Core.FileFormats; +using PckStudio.ModelSupport.Format.External; +using PckStudio.Core.Additional_Popups; +using PckStudio.ModelSupport.Internal.Format; + +namespace PckStudio.ModelSupport +{ + public sealed class SkinModelImporter : ModelImporter + { + public static SkinModelImporter Default { get; } = new SkinModelImporter(); + + private SkinModelImporter() + { + InternalAddProvider(new("Pck skin model(*.psm)", "*.psm"), ImportPsm, ExportPsm); + InternalAddProvider(new("Block bench model(*.bbmodel)", "*.bbmodel"), ImportBlockBenchModel, ExportBlockBenchModel); + InternalAddProvider(new("Bedrock (Legacy) Model(*.geo.json;*.json)", "*.geo.json;*.json"), ImportBedrockJson, ExportBedrockJson); + } + + internal static SkinModelInfo ImportPsm(string filepath) + { + var reader = new PSMFileReader(); + PSMFile csmbFile = reader.FromFile(filepath); + return new SkinModelInfo(null, csmbFile.SkinANIM, new(csmbFile.Parts, csmbFile.Offsets)); + } + + internal static void ExportPsm(string filepath, SkinModelInfo modelInfo) + { + PSMFile psmFile = new PSMFile(PSMFile.CurrentVersion, modelInfo.Anim); + psmFile.Parts.AddRange(modelInfo.Model.AdditionalBoxes); + psmFile.Offsets.AddRange(modelInfo.Model.PartOffsets); + var writer = new PSMFileWriter(psmFile); + writer.WriteToFile(filepath); + } + + internal static SkinModelInfo ImportBlockBenchModel(string filepath) + { + BlockBenchModel blockBenchModel = JsonConvert.DeserializeObject(File.ReadAllText(filepath)); + if (!blockBenchModel.Format.UseBoxUv) + { + Trace.TraceError($"[{nameof(SkinModelImporter)}:{nameof(ImportBlockBenchModel)}] Failed to import skin '{blockBenchModel.Name}': Skin does not use box uv."); + return null; + } + + IEnumerable partOffsets = blockBenchModel.Outliner + .Where(token => token.Type == JTokenType.Object && SkinBOX.IsValidType(TryConvertToSkinBoxType(token.ToObject().Name))) + .Select(token => token.ToObject()) + .Select(outline => new SkinPartOffset(TryConvertToSkinBoxType(outline.Name), -GetOffsetFromOrigin(TryConvertToSkinBoxType(outline.Name), outline.Origin).Y)) + .Where(offset => offset.Value != 0f); + + IEnumerable boxes = ReadOutliner(null, blockBenchModel.Outliner, blockBenchModel.Elements); + + Image texture = null; + if (blockBenchModel.Textures.IndexInRange(0)) + { + texture = blockBenchModel.Textures[0]; + texture = SwapBoxBottomTexture(texture, boxes); + } + + return CreateSkinModelInfo(texture, boxes, partOffsets); + } + + private static SkinModelInfo CreateSkinModelInfo(Image texture, IEnumerable boxes, IEnumerable partOffsets) + { + SkinANIM skinANIM = ( + SkinAnimMask.HEAD_DISABLED | + SkinAnimMask.HEAD_OVERLAY_DISABLED | + SkinAnimMask.BODY_DISABLED | + SkinAnimMask.BODY_OVERLAY_DISABLED | + SkinAnimMask.RIGHT_ARM_DISABLED | + SkinAnimMask.RIGHT_ARM_OVERLAY_DISABLED | + SkinAnimMask.LEFT_ARM_DISABLED | + SkinAnimMask.LEFT_ARM_OVERLAY_DISABLED | + SkinAnimMask.RIGHT_LEG_DISABLED | + SkinAnimMask.RIGHT_LEG_OVERLAY_DISABLED | + SkinAnimMask.LEFT_LEG_DISABLED | + SkinAnimMask.LEFT_LEG_OVERLAY_DISABLED); + + skinANIM = skinANIM.SetFlag(SkinAnimFlag.RESOLUTION_64x64, texture.Size.Width == texture.Size.Height); + + SkinModel skinModel = new SkinModel(); + + skinModel.PartOffsets.AddRange(partOffsets); + + SkinBOX ApplyOffset(SkinBOX box) + { + SkinPartOffset offset = skinModel.PartOffsets.FirstOrDefault(offset => offset.Type == (box.IsOverlayPart() ? box.GetBaseType() : box.Type)); + return string.IsNullOrEmpty(offset.Type) ? box : new SkinBOX(box.Type, box.Pos - (Vector3.UnitY * offset.Value), box.Size, box.UV, box.HideWithArmor, box.Mirror, box.Scale); + } + + IEnumerable convertedBoxes = boxes.Select(ApplyOffset); + + IEnumerable customBoxes = convertedBoxes.Where(box => !SkinBOX.KnownHashes.ContainsKey(box.GetHashCode())); + + skinModel.AdditionalBoxes.AddRange(customBoxes); + + // check for know boxes and filter them out + SkinAnimMask mask = (SkinAnimMask)convertedBoxes + .Where(box => SkinBOX.KnownHashes.ContainsKey(box.GetHashCode()) && Enum.IsDefined(typeof(SkinAnimMask), (1 >> (int)SkinBOX.KnownHashes[box.GetHashCode()]))) + .Select(box => SkinBOX.KnownHashes[box.GetHashCode()]) + .Select(i => 1 << (int)i) + .DefaultIfEmpty() + .Aggregate((a, b) => a | b); + + if (mask != SkinAnimMask.NONE) + skinANIM &= ~mask; + + return new SkinModelInfo(texture, skinANIM, skinModel); + } + + private static IEnumerable ReadOutliner(string parentName, JArray oulineChildren, IReadOnlyCollection elements) + { + IEnumerable boxes = oulineChildren + .Where(token => token.Type == JTokenType.String && Guid.TryParse(token.ToString(), out Guid elementUuid) && elements.Any(e => e.Uuid == elementUuid)) + .Select(token => elements.First(e => Guid.Parse(token.ToString()) == e.Uuid)) + .Where(element => element.Type == "cube" && element.UseBoxUv && element.Export && SkinBOX.IsValidType(TryConvertToSkinBoxType(parentName ?? element.Name))) + .Select(element => LoadElement(element, TryConvertToSkinBoxType(parentName ?? element.Name))); + + IEnumerable childOutlines = oulineChildren + .Where(token => token.Type == JTokenType.Object) + .Select(token => token.ToObject()); + + foreach (Outline childOutline in childOutlines) + { + boxes = boxes.Concat(ReadOutliner(parentName ?? childOutline.Name, childOutline.Children, elements)); + } + return boxes; + } + + private static SkinBOX LoadElement(Element element, string outlineName) + { + var boundingBox = new BoundingBox(element.From, element.To); + Vector3 pos = boundingBox.Start.ToNumericsVector(); + Vector3 size = boundingBox.Volume.ToNumericsVector(); + Vector2 uv = element.UvOffset; + + pos = TranslateToInternalPosition(outlineName, pos, size, new Vector3(1, 1, 0)); + + var box = new SkinBOX(outlineName, pos, size, uv, mirror: element.MirrorUv); + if (SkinBOX.IsBasePart(outlineName) && ((outlineName == "HEAD" && element.Inflate == 0.5f) || (element.Inflate >= 0.25f && element.Inflate <= 0.5f))) + box = new SkinBOX(SkinBOXExtensions.GetOverlayType(outlineName), pos, size, uv, mirror: element.MirrorUv); + return box; + } + + internal static void ExportBlockBenchModel(string filepath, SkinModelInfo modelInfo) + { + Image exportTexture = SwapBoxBottomTexture(modelInfo); + BlockBenchModel blockBenchModel = BlockBenchModel.Create(BlockBenchFormatInfos.BedrockEntity, Path.GetFileNameWithoutExtension(filepath), new Size(64, exportTexture.Width == exportTexture.Height ? 64 : 32), [exportTexture]); + + Dictionary outliners = new Dictionary(5); + List elements = new List(modelInfo.Model.AdditionalBoxes.Count); + + Dictionary offsetLookUp = new Dictionary(5); + + void AddElement(SkinBOX box) + { + string offsetType = box.IsOverlayPart() ? box.GetBaseType() : box.Type; + + Vector3 offset = GetOffsetForPart(offsetType, ref offsetLookUp, modelInfo.Model.PartOffsets); + if (!outliners.ContainsKey(offsetType)) + { + outliners.Add(offsetType, new Outline(offsetType) + { + Origin = GetSkinPartPivot(offsetType, new Vector3(1, 1, 0)) + offset + }); + } + + Element element = CreateElement(box); + + element.From += offset; + element.To += offset; + + elements.Add(element); + outliners[offsetType].Children.Add(element.Uuid); + } + + ANIM2BOX(modelInfo.Anim, AddElement); + + foreach (SkinBOX box in modelInfo.Model.AdditionalBoxes) + { + AddElement(box); + } + blockBenchModel.Elements = elements.ToArray(); + blockBenchModel.Outliner = JArray.FromObject(outliners.Values); + + string content = JsonConvert.SerializeObject(blockBenchModel); + File.WriteAllText(filepath, content); + } + + private static Element CreateElement(SkinBOX box) + { + Vector3 transformPos = TranslateFromInternalPosistion(box, new Vector3(1, 1, 0)); + Element element = CreateElement(box.UV, transformPos, box.Size, box.Scale, box.Mirror); + if (box.IsOverlayPart()) + element.Inflate = box.Type == "HEADWEAR" ? 0.5f : 0.25f; + return element; + } + + private static Element CreateElement(Vector2 uvOffset, Vector3 pos, Vector3 size, float inflate, bool mirror) + { + return Element.CreateCube("cube", uvOffset, pos, size, inflate, mirror); + } + + private static Geometry GetGeometry(string filepath) + { + // Bedrock Entity (Model) + if (filepath.EndsWith(".geo.json")) + { + BedrockModel bedrockModel = JsonConvert.DeserializeObject(File.ReadAllText(filepath)); + var availableModels = bedrockModel.Models.Select(m => m.Description.Identifier).ToArray(); + if (availableModels.Length < 2) + return availableModels.Length == 1 ? bedrockModel.Models[0] : null; + + using ItemSelectionPopUp itemSelectionPopUp = new ItemSelectionPopUp(availableModels); + if (itemSelectionPopUp.ShowDialog() == DialogResult.OK && bedrockModel.Models.IndexInRange(itemSelectionPopUp.SelectedIndex)) + { + return bedrockModel.Models[itemSelectionPopUp.SelectedIndex]; + } + } + + // Bedrock Legacy Model + else if (filepath.EndsWith(".json")) + { + BedrockLegacyModel bedrockModel = JsonConvert.DeserializeObject(File.ReadAllText(filepath)); + var availableModels = bedrockModel.Select(m => m.Key).ToArray(); + if (availableModels.Length < 2) + return availableModels.Length == 1 ? bedrockModel[availableModels[0]] : null; + using ItemSelectionPopUp itemSelectionPopUp = new ItemSelectionPopUp(availableModels); + if (itemSelectionPopUp.ShowDialog() == DialogResult.OK && bedrockModel.ContainsKey(itemSelectionPopUp.SelectedItem)) + { + return bedrockModel[itemSelectionPopUp.SelectedItem]; + } + } + + return null; + } + + private static SkinModelInfo ImportBedrockJson(string filepath) + { + Geometry geometry = GetGeometry(filepath); + if (geometry is null) + return null; + + (IEnumerable boxes, IEnumerable partOffsets) = LoadGeometry(geometry); + + Image texture = null; + string texturePath = Path.Combine(Path.GetDirectoryName(filepath), Path.GetFileNameWithoutExtension(filepath)) + ".png"; + if (File.Exists(texturePath)) + { + texture = Image.FromFile(texturePath).ReleaseFromFile(); + texture = SwapBoxBottomTexture(texture, boxes); + } + + return CreateSkinModelInfo(texture, boxes, partOffsets); + } + + private static (IEnumerable boxes, IEnumerable partOffsets) LoadGeometry(Geometry geometry) + { + List skinPartOffsets = new List(); + List boxes = new List(); + + foreach (Bone bone in geometry.Bones) + { + string boxType = TryConvertToSkinBoxType(bone.Name); + if (!SkinBOX.IsValidType(boxType)) + continue; + + string offsetType = SkinBOX.IsOverlayPart(boxType) ? SkinBOXExtensions.GetBaseType(boxType) : boxType; + Vector3 offset = GetOffsetFromOrigin(offsetType, bone.Pivot * new Vector3(-1, 1, 1)); + if (offset.Y != 0f) + skinPartOffsets.Add(new SkinPartOffset(offsetType, -offset.Y)); + + foreach (Cube cube in bone.Cubes) + { + Vector3 pos = TranslateToInternalPosition(boxType, cube.Origin, cube.Size, Vector3.UnitY); + var skinBox = new SkinBOX(boxType, pos, cube.Size, cube.Uv, hideWithArmor: bone.Name == "helmet", mirror: cube.Mirror); + if (SkinBOX.IsBasePart(boxType) && ((boxType == "HEAD" && cube.Inflate == 0.5f) || (cube.Inflate >= 0.25f && cube.Inflate <= 0.5f))) + skinBox = new SkinBOX(SkinBOXExtensions.GetOverlayType(boxType), pos, cube.Size, cube.Uv, hideWithArmor: bone.Name == "helmet", mirror: cube.Mirror); + boxes.Add(skinBox); + } + } + return (boxes, skinPartOffsets); + } + + internal static void ExportBedrockJson(string filepath, SkinModelInfo modelInfo) + { + if (string.IsNullOrEmpty(filepath) || !filepath.EndsWith(".json")) + return; + + Dictionary bones = new Dictionary(5); + Dictionary offsetLookUp = new Dictionary(5); + + void AddBone(SkinBOX box) + { + string offsetType = box.IsOverlayPart() ? box.GetBaseType() : box.Type; + + Vector3 offset = GetOffsetForPart(offsetType, ref offsetLookUp, modelInfo.Model.PartOffsets); + + if (!bones.ContainsKey(offsetType)) + { + Bone bone = new Bone(offsetType) + { + Pivot = GetSkinPartPivot(offsetType, new Vector3(0, 1, 0)) + offset + }; + bones.Add(offsetType, bone); + } + Vector3 pivot = bones.ContainsKey(offsetType) ? bones[offsetType].Pivot : Vector3.Zero; + Vector3 pos = TranslateFromInternalPosistion(box, new Vector3(1, 1, 0)); + pos = TransformSpace(pos, box.Size, new Vector3(1, 0, 0)); + + bones[offsetType].Cubes.Add(new Cube() + { + Origin = pos + offset, + Size = box.Size, + Uv = box.UV, + Inflate = box.Scale + (box.IsOverlayPart() ? box.Type == "HEAD" ? 0.5f : 0.25f : 0f), + Mirror = box.Mirror, + }); + } + + ANIM2BOX(modelInfo.Anim, AddBone); + + foreach (SkinBOX box in modelInfo.Model.AdditionalBoxes) + { + AddBone(box); + } + + Geometry selectedGeometry = new Geometry(); + selectedGeometry.Bones.AddRange(bones.Values); + object bedrockModel = null; + // Bedrock Entity (Model) + if (filepath.EndsWith(".geo.json")) + { + selectedGeometry.Description = new GeometryDescription() + { + Identifier = $"geometry.{Application.ProductName}.{Path.GetFileNameWithoutExtension(filepath)}", + TextureSize = modelInfo.Texture.Size, + }; + bedrockModel = new BedrockModel + { + FormatVersion = "1.12.0", + Models = { selectedGeometry } + }; + } + // Bedrock Legacy Model + else if (filepath.EndsWith(".json") && modelInfo.Texture.Height == modelInfo.Texture.Width) + { + bedrockModel = new BedrockLegacyModel + { + { $"geometry.{Application.ProductName}.{Path.GetFileNameWithoutExtension(filepath)}", selectedGeometry } + }; + } + else + { + MessageBox.Show("Can't export to Bedrock Legacy Model.", "Invalid Texture Dimensions", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (bedrockModel is not null) + { + string content = JsonConvert.SerializeObject(bedrockModel); + File.WriteAllText(filepath, content); + string texturePath = Path.Combine(Path.GetDirectoryName(filepath), Path.GetFileNameWithoutExtension(filepath)) + ".png"; + SwapBoxBottomTexture(modelInfo).Save(texturePath, ImageFormat.Png); + } + } + + private static void ANIM2BOX(SkinANIM anim, Action converter) + { + bool isSlim = anim.GetFlag(SkinAnimFlag.SLIM_MODEL); + bool is32x64 = !(anim.GetFlag(SkinAnimFlag.RESOLUTION_64x64) || isSlim); + if (!anim.GetFlag(SkinAnimFlag.HEAD_DISABLED)) + converter(new SkinBOX("HEAD", new Vector3(-4, -8, -4), new Vector3(8), Vector2.Zero)); + + if (!is32x64 && !anim.GetFlag(SkinAnimFlag.HEAD_OVERLAY_DISABLED)) + converter(new SkinBOX("HEADWEAR", new Vector3(-4, -8, -4), new Vector3(8), new Vector2(32, 0))); + + if (!anim.GetFlag(SkinAnimFlag.BODY_DISABLED)) + converter(new SkinBOX("BODY", new(-4, 0, -2), new(8, 12, 4), new(16, 16))); + + if (!is32x64 && !anim.GetFlag(SkinAnimFlag.BODY_OVERLAY_DISABLED)) + converter(new SkinBOX("JACKET", new(-4, 0, -2), new(8, 12, 4), new(16, 32))); + + if (!anim.GetFlag(SkinAnimFlag.RIGHT_ARM_DISABLED)) + converter(new SkinBOX("ARM0", new(isSlim ? -2 : - 3, -2, -2), new(isSlim ? 3 : 4, 12, 4), new(40, 16))); + + if (!is32x64 && !anim.GetFlag(SkinAnimFlag.RIGHT_ARM_OVERLAY_DISABLED)) + converter(new SkinBOX("SLEEVE0", new(isSlim ? -2 : - 3, -2, -2), new(isSlim ? 3 : 4, 12, 4), new(40, 32))); + + if (!anim.GetFlag(SkinAnimFlag.LEFT_ARM_DISABLED)) + converter(new SkinBOX("ARM1", new(-1, -2, -2), new(isSlim ? 3 : 4, 12, 4), is32x64 ? new(40, 16) : new(32, 48), mirror: is32x64)); + + if (!is32x64 && !anim.GetFlag(SkinAnimFlag.LEFT_ARM_OVERLAY_DISABLED)) + converter(new SkinBOX("SLEEVE1", new(-1, -2, -2), new(isSlim ? 3 : 4, 12, 4), new(48, 48))); + + if (!anim.GetFlag(SkinAnimFlag.RIGHT_LEG_DISABLED)) + converter(new SkinBOX("LEG0", new(-2, 0, -2), new(4, 12, 4), new(0, 16))); + + if (!is32x64 && !anim.GetFlag(SkinAnimFlag.RIGHT_LEG_OVERLAY_DISABLED)) + converter(new SkinBOX("PANTS0", new(-2, 0, -2), new(4, 12, 4), new(0, 32))); + + if (!anim.GetFlag(SkinAnimFlag.LEFT_LEG_DISABLED)) + { + converter(new SkinBOX("LEG1", new(-2, 0, -2), new(4, 12, 4), is32x64 ? new(0, 16) : new(16, 48), mirror: is32x64)); + } + + if (!is32x64 && !anim.GetFlag(SkinAnimFlag.LEFT_LEG_OVERLAY_DISABLED)) + { + converter(new SkinBOX("PANTS1", new(-2, 0, -2), new(4, 12, 4), new(0, 48))); + } + } + + private static string TryConvertToSkinBoxType(string name) + { + if (!SkinBOX.IsValidType(name) && SkinBOX.IsValidType(name.ToUpper())) + { + return name.ToUpper(); + } + return name.ToLower() switch + { + "helmet" => "HEAD", + "rightarm" => "ARM0", + "leftarm" => "ARM1", + "rightleg" => "LEG0", + "leftleg" => "LEG1", + "hat" => "HEADWEAR", + "bodyarmor" => "BODY", + "rightsleeve" => "SLEEVE0", + "leftsleeve" => "SLEEVE1", + "rightpants" => "PANTS0", + "leftpants" => "PANTS1", + _ => name, + }; + } + + private static Vector3 GetOffsetFromOrigin(string boxType, Vector3 origin) + { + Vector3 partTranslation = GameConstants.GetSkinPartPivot(boxType); + Vector3 offset = partTranslation - ((Vector3.UnitY * 24f) - origin); + if (offset.X != 0f || offset.Z != 0f) + Trace.TraceWarning($"[{nameof(SkinModelImporter)}:{nameof(GetOffsetFromOrigin)}] Warning: skin part({boxType}) offsets only support horizontal offsets."); + return offset * Vector3.UnitY; + } + + private static Vector3 GetSkinPartPivot(string partName, Vector3 translationUnit) + { + return TransformSpace(GameConstants.GetSkinPartPivot(partName), Vector3.Zero, translationUnit) + (24f * Vector3.UnitY); + } + + private static Vector3 GetOffsetForPart(string offsetType, ref Dictionary offsetLookUp, IEnumerable partOffsets) + { + if (offsetLookUp.ContainsKey(offsetType)) + { + return -offsetLookUp[offsetType].Value * Vector3.UnitY; + } + if (partOffsets.Any(o => o.Type == offsetType)) + { + SkinPartOffset partOffset = partOffsets.First(o => o.Type == offsetType); + offsetLookUp.Add(offsetType, partOffset); + return -partOffset.Value * Vector3.UnitY; + } + return Vector3.Zero; + } + + private static Image SwapBoxBottomTexture(SkinModelInfo modelInfo) + { + return SwapBoxBottomTexture(modelInfo.Texture, modelInfo.Model.AdditionalBoxes); + } + + private static Image SwapBoxBottomTexture(Image texture, IEnumerable boxes) + { + return SwapTextureAreas(texture, boxes.Where(box => !(box.Size == Vector3.One || box.Size == Vector3.Zero)).Select(box => + { + var imgPos = Point.Truncate(new PointF(box.UV.X + box.Size.X + box.Size.Z, box.UV.Y)); + var area = new RectangleF(imgPos, Size.Truncate(new SizeF(box.Size.X, box.Size.Z))); + return Rectangle.Truncate(area); + }), RotateFlipType.RotateNoneFlipY); + } + + private static Image SwapTextureAreas(Image texture, IEnumerable areasToFix, RotateFlipType type) + { + if (texture == null) + { + Trace.TraceError($"[{nameof(SkinModelImporter)}:{nameof(SwapBoxBottomTexture)}] Failed to fix texture: texture is null."); + return null; + } + areasToFix = areasToFix.Where(rect => rect.Size.Width > 0 && rect.Size.Height > 0); + Image result = new Bitmap(texture); + using var g = Graphics.FromImage(result); + g.ApplyConfig(new GraphicsConfig() + { + InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor, + PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality + }); + foreach (Rectangle area in areasToFix) + { + Image targetAreaImage = texture.GetArea(area); + targetAreaImage.RotateFlip(type); + Region clip = g.Clip; + g.SetClip(area); + g.Clear(Color.Transparent); + g.DrawImage(targetAreaImage, area.Location); + g.Clip = clip; + } + return result; + } + + private static Vector3 TranslateToInternalPosition(string boxType, Vector3 origin, Vector3 size, Vector3 translationUnit) + { + Vector3 pos = TransformSpace(origin, size, translationUnit); + // Skin Renderer (and Game) specific offset value. + pos.Y += 24f; + + // This will cancel out the part specific translation. + Vector3 translation = GameConstants.GetSkinPartTranslation(boxType); + pos -= translation; + + return pos; + } + + private static Vector3 TranslateFromInternalPosistion(SkinBOX skinBox, Vector3 translationUnit) + { + return TranslateToInternalPosition(skinBox.Type, skinBox.Pos, skinBox.Size, translationUnit); + } + } +} diff --git a/PckStuido.ModelSupport/SkinModelInfo.cs b/PckStuido.ModelSupport/SkinModelInfo.cs new file mode 100644 index 00000000..a7a1b2f9 --- /dev/null +++ b/PckStuido.ModelSupport/SkinModelInfo.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PckStudio.Core.Skin; + +namespace PckStudio.ModelSupport +{ + public sealed class SkinModelInfo + { + public SkinModel Model { get; } + public SkinANIM Anim { get; } + public Image Texture { get; } + + public SkinModelInfo(Image texture, SkinANIM anim, SkinModel model) + { + Texture = texture; + Anim = anim; + Model = model; + } + } +} diff --git a/Version.json b/Version.json index 88ef4e47..0711d4f6 100644 --- a/Version.json +++ b/Version.json @@ -1,6 +1,6 @@ { - "version": "7.0.0.2", - "url": "https://github.com/PhoenixARC/-PCK-Studio/releases/download/v7.0.0.2/PCK-Studio.zip", + "version": "7.0.1.0", + "url": "https://github.com/PhoenixARC/-PCK-Studio/releases/download/v7.0.1.0/PCK-Studio.zip", "changelog": "https://raw.githubusercontent.com/PhoenixARC/-PCK-Studio/main/CHANGELOG.md", "mandatory": false } \ No newline at end of file