diff --git a/PCK-Studio/Controls/NamedTextureTreeNode.cs b/PCK-Studio/Controls/NamedTextureTreeNode.cs index b889bcc4..7f9d5641 100644 --- a/PCK-Studio/Controls/NamedTextureTreeNode.cs +++ b/PCK-Studio/Controls/NamedTextureTreeNode.cs @@ -11,7 +11,6 @@ namespace PckStudio.Controls public NamedTextureTreeNode(NamedData namedTexture) : base(namedTexture.Name) { - Tag = namedTexture; _namedTexture = namedTexture; } 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/Controls/PckAssetBrowserEditor.Designer.cs b/PCK-Studio/Controls/RawAssetsEditor.Designer.cs similarity index 99% rename from PCK-Studio/Controls/PckAssetBrowserEditor.Designer.cs rename to PCK-Studio/Controls/RawAssetsEditor.Designer.cs index 3522a26c..254cc91d 100644 --- a/PCK-Studio/Controls/PckAssetBrowserEditor.Designer.cs +++ b/PCK-Studio/Controls/RawAssetsEditor.Designer.cs @@ -2,7 +2,7 @@ namespace PckStudio.Controls { - partial class PckAssetBrowserEditor + partial class RawAssetsEditor { /// /// Required designer variable. @@ -32,7 +32,7 @@ namespace PckStudio.Controls { this.components = new System.ComponentModel.Container(); System.Windows.Forms.PictureBox logoPictureBox; - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PckAssetBrowserEditor)); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(RawAssetsEditor)); this.pckFileLabel = new MetroFramework.Controls.MetroLabel(); this.fileEntryCountLabel = new MetroFramework.Controls.MetroLabel(); this.metroLabel2 = new MetroFramework.Controls.MetroLabel(); diff --git a/PCK-Studio/Controls/PckAssetBrowserEditor.cs b/PCK-Studio/Controls/RawAssetsEditor.cs similarity index 90% rename from PCK-Studio/Controls/PckAssetBrowserEditor.cs rename to PCK-Studio/Controls/RawAssetsEditor.cs index df5e800d..dbc18309 100644 --- a/PCK-Studio/Controls/PckAssetBrowserEditor.cs +++ b/PCK-Studio/Controls/RawAssetsEditor.cs @@ -48,10 +48,11 @@ using PckStudio.Core.IO.PckAudio; using PckStudio.Core.IO._3DST; using PckStudio.Core.Misc; using PckStudio.Core.DLC; +using PckStudio.Core.Colors; namespace PckStudio.Controls { - internal partial class PckAssetBrowserEditor : EditorControl + internal partial class RawAssetsEditor : EditorControl { private string _location = string.Empty; @@ -85,21 +86,21 @@ namespace PckStudio.Controls private readonly IDictionary> _pckAssetTypeHandler; //private readonly IDictionary _viewPanels; - public PckAssetBrowserEditor(PackInfo packInfo, ISaveContext saveContext) - : base(packInfo, saveContext) + public RawAssetsEditor(RawAssetDLCPackage rawAssetDLCPackage, ISaveContext saveContext) + : base(rawAssetDLCPackage, saveContext) { InitializeComponent(); _onModifiedChangeDelegate = OnModify; - _originalEndianness = packInfo.ByteOrder; - _currentEndianness = packInfo.ByteOrder; + _originalEndianness = rawAssetDLCPackage.ByteOrder; + _currentEndianness = rawAssetDLCPackage.ByteOrder; //! InitializeViewPanels { _default = new DefaultPanel(); _models = new ModelsPanel(TryGet.FromDelegate((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); + bool found = EditorValue.PckFile.TryGetAsset(path + ".png", PckAssetType.TextureFile, out PckAsset asset) || + EditorValue.PckFile.TryGetAsset(path + ".tga", PckAssetType.TextureFile, out asset); img = found ? asset.GetTexture() : default; return found; })); @@ -221,31 +222,28 @@ namespace PckStudio.Controls if (asset.Type != PckAssetType.SkinDataFile && asset.Type != PckAssetType.TexturePackInfoFile || asset.Size <= 0 || !Settings.Default.LoadSubPcks) return; - ISaveContext saveContext = new DelegatedSaveContext(false, (packInfo) => + ISaveContext saveContext = new DelegatedSaveContext(false, (rawAssetDLCPackage) => { - if (packInfo.IsValid) - { - asset.SetData(new PckFileWriter(packInfo.File, _currentEndianness)); - _wasModified = true; - } + asset.SetData(new PckFileWriter(rawAssetDLCPackage.PckFile, _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); + RawAssetDLCPackage rawAssetDLCPackage = new RawAssetDLCPackage(asset.Filename, pckFile, _originalEndianness); // TODO: may change to use a new tab page that will be closed when the main pck is closed - //Program.MainInstance.OpenNewPckTab(caption, identifier, packInfo, saveContext); + //Program.MainInstance.OpenNewPckTab(caption, identifier, RawAssetDLCPackage, saveContext); } private void HandleTextureFile(PckAsset asset) { - _ = asset.IsMipmappedFile() && EditorValue.File.TryGetAsset(asset.GetNormalPath(), PckAssetType.TextureFile, out asset); + _ = asset.IsMipmappedFile() && EditorValue.PckFile.TryGetAsset(asset.GetNormalPath(), PckAssetType.TextureFile, out asset); if (asset.Size <= 0) { - Trace.TraceInformation($"[{nameof(PckAssetBrowserEditor)}:{nameof(HandleTextureFile)}] '{asset.Filename}' size is 0."); + Trace.TraceInformation($"[{nameof(RawAssetsEditor)}:{nameof(HandleTextureFile)}] '{asset.Filename}' size is 0."); return; } _currentViewPanel.LoadAsset(asset, () => _wasModified = true); @@ -260,7 +258,7 @@ namespace PckStudio.Controls break; case ResourceCategory.Textures: { - if ((resourceLocation.Category & ResourceCategory.ArmorTextures) != 0) + if ((resourceLocation.Category & ResourceCategory.ArmorTextures) == 0) { string assetName = Path.GetFileNameWithoutExtension(asset.Filename); ArmorSetDescription armorSetDescription = ArmorSetDescription.GetFromAssetName(assetName); @@ -268,7 +266,7 @@ namespace PckStudio.Controls ITryGet tryGet = TryGet.FromDelegate((string path, out Image img) => { img = null; - if (EditorValue.File.TryGetAsset(path + ".png", PckAssetType.TextureFile, out PckAsset armorAsset)) + if (EditorValue.PckFile.TryGetAsset(path + ".png", PckAssetType.TextureFile, out PckAsset armorAsset)) { img = armorAsset.GetTexture(); Debug.WriteLine($"Got texture for: {path}"); @@ -309,7 +307,7 @@ namespace PckStudio.Controls bool hasCustomModel = false; bool hasDefaultModel = TryGetDefaultEntityModel(modelName, out Model model); - if (EditorValue.File.TryGetAsset("models.bin", PckAssetType.ModelsFile, out PckAsset modelsAsset)) + if (EditorValue.PckFile.TryGetAsset("models.bin", PckAssetType.ModelsFile, out PckAsset modelsAsset)) { ModelContainer models = modelsAsset.GetData(new ModelFileReader()); hasCustomModel = models.ContainsModel(modelName); @@ -354,13 +352,13 @@ namespace PckStudio.Controls case ResourceCategory.Atlas: Atlas atlas = asset.GetDeserializedData(new AtlasDeserializer(resourceLocation)); ColorContainer colorContainer = default; - if (EditorValue.File.TryGetAsset("colours.col", PckAssetType.ColourTableFile, out PckAsset colAsset)) + if (EditorValue.PckFile.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); + bool found = EditorValue.PckFile.TryGetAsset(key + ".png", PckAssetType.TextureFile, out PckAsset foundAsset) || + EditorValue.PckFile.TryGetAsset(key + ".tga", PckAssetType.TextureFile, out foundAsset); if (found) { animation = foundAsset.GetDeserializedData(AnimationDeserializer.DefaultDeserializer); @@ -373,8 +371,8 @@ namespace PckStudio.Controls 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); + bool found = EditorValue.PckFile.TryGetAsset(key + ".png", PckAssetType.TextureFile, out PckAsset foundAsset) || + EditorValue.PckFile.TryGetAsset(key + ".tga", PckAssetType.TextureFile, out foundAsset); if (found) { @@ -391,7 +389,7 @@ namespace PckStudio.Controls Debug.WriteLine("New animation has 0 frames. Aborting saving."); return; } - PckAsset newAnimationAsset = EditorValue.File.CreateNewAsset(key + ".png", PckAssetType.TextureFile); + PckAsset newAnimationAsset = EditorValue.PckFile.CreateNewAsset(key + ".png", PckAssetType.TextureFile); newAnimationAsset.SetSerializedData(animation, AnimationSerializer.DefaultSerializer); BuildMainTreeView(); }); @@ -487,12 +485,15 @@ namespace PckStudio.Controls private void HandleColourFile(PckAsset asset) { - ColorContainer colorContainer = asset.GetData(new COLFileReader()); - ISaveContext saveContext = new DelegatedSaveContext(Settings.Default.AutoSaveChanges, (colorContainer) => + AbstractColorContainer abstractColorContainer = AbstractColorContainer.FromColorContainer(asset.GetData(new COLFileReader())); + ISaveContext saveContext = new DelegatedSaveContext(Settings.Default.AutoSaveChanges, (newColorContainer) => { + ColorContainer colorContainer = new ColorContainer(); + colorContainer.Colors.AddRange(newColorContainer.Colors.Select(kv => new ColorContainer.Color() { Name = kv.Key, ColorPallette = kv.Value })); + colorContainer.WaterColors.AddRange(newColorContainer.WaterColors.Select(kv => new ColorContainer.WaterColor() { Name = kv.Key, SurfaceColor = kv.Value.Surface, FogColor = kv.Value.Fog, UnderwaterColor = kv.Value.Underwater })); asset.SetData(new COLFileWriter(colorContainer)); }); - using COLEditor diag = new COLEditor(colorContainer, saveContext); + using COLEditor diag = new COLEditor(abstractColorContainer, saveContext); _wasModified = diag.ShowDialog(this) == DialogResult.OK; } @@ -503,7 +504,7 @@ namespace PckStudio.Controls if (asset.HasProperty("CAPEPATH")) { string capeAssetPath = asset.GetProperty("CAPEPATH"); - if (EditorValue.File.TryGetAsset(capeAssetPath, PckAssetType.CapeFile, out PckAsset capeAsset)) + if (EditorValue.PckFile.TryGetAsset(capeAssetPath, PckAssetType.CapeFile, out PckAsset capeAsset)) { skin.CapeId = capeAsset.GetId(); cape = capeAsset.GetTexture(); @@ -517,7 +518,7 @@ namespace PckStudio.Controls asset.SetSkin(customSkin, locFile); }); - using CustomSkinEditor skinEditor = new CustomSkinEditor(skin, cape, saveContext, EditorValue.File.HasVerionString); + using CustomSkinEditor skinEditor = new CustomSkinEditor(skin, cape, saveContext, EditorValue.PckFile.HasVerionString); if (skinEditor.ShowDialog() == DialogResult.OK) { _wasModified = true; @@ -536,22 +537,22 @@ namespace PckStudio.Controls 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); + bool found = EditorValue.PckFile.TryGetAsset(path + ".png", PckAssetType.TextureFile, out PckAsset asset) || + EditorValue.PckFile.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); + bool found = EditorValue.PckFile.TryGetAsset(path + ".png", PckAssetType.TextureFile, out PckAsset foundAsset) || + EditorValue.PckFile.TryGetAsset(path + ".tga", PckAssetType.TextureFile, out foundAsset); + PckAsset asset = foundAsset ?? EditorValue.PckFile.CreateNewAsset(path + ".png", PckAssetType.TextureFile); asset.SetTexture(img); return true; }; - bool hasMaterialAsset = EditorValue.File.TryGetAsset("entityMaterials.bin", PckAssetType.MaterialFile, out PckAsset entityMaterialAsset); + bool hasMaterialAsset = EditorValue.PckFile.TryGetAsset("entityMaterials.bin", PckAssetType.MaterialFile, out PckAsset entityMaterialAsset); IReadOnlyDictionary entityMaterials = hasMaterialAsset ? entityMaterialAsset?.GetData(new MaterialFileReader()).ToDictionary(mat => mat.Name) @@ -595,7 +596,7 @@ namespace PckStudio.Controls private void CheckForPasswordAndRemove() { - if (EditorValue.File.TryGetAsset("0", PckAssetType.InfoFile, out PckAsset asset)) + if (EditorValue.PckFile.TryGetAsset("0", PckAssetType.InfoFile, out PckAsset asset)) { asset.RemoveProperties("LOCK"); } @@ -619,7 +620,7 @@ namespace PckStudio.Controls string selectedNodeText = treeViewMain.SelectedNode is TreeNode node ? node.FullPath : string.Empty; _currentViewPanel.Reset(); treeViewMain.Nodes.Clear(); - BuildPckTreeView(treeViewMain.Nodes, EditorValue.File); + BuildPckTreeView(treeViewMain.Nodes, EditorValue.PckFile); treeViewMain.Sort(); TreeNode[] selectedNodes = treeViewMain.FindPath(selectedNodeText); @@ -668,8 +669,8 @@ namespace PckStudio.Controls 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)) + if (!EditorValue.PckFile.TryGetAsset("localisation.loc", PckAssetType.LocalisationFile, out PckAsset locAsset) && + !EditorValue.PckFile.TryGetAsset("languages.loc", PckAssetType.LocalisationFile, out locAsset)) { locFile = null; return false; @@ -690,8 +691,8 @@ namespace PckStudio.Controls 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)) + if (!EditorValue.PckFile.TryGetAsset("localisation.loc", PckAssetType.LocalisationFile, out PckAsset locAsset) && + !EditorValue.PckFile.TryGetAsset("languages.loc", PckAssetType.LocalisationFile, out locAsset)) { return false; } @@ -710,14 +711,14 @@ namespace PckStudio.Controls private void UpdateRichPresence() { - if (EditorValue is not null && - TryGetLocFile(out LOCFile locfile) && - locfile.HasLocEntry("IDS_DISPLAY_NAME") && - locfile.Languages.Contains(DLCManager.Default.PreferredLanguage)) - { - RPC.SetPresence("Editing a Pack:", $" > {locfile.GetLocEntry("IDS_DISPLAY_NAME", DLCManager.Default.PreferredLanguage)}"); - return; - } + //if (EditorValue is not null && + // TryGetLocFile(out LOCFile locfile) && + // locfile.HasLocEntry("IDS_DISPLAY_NAME") && + // locfile.Languages.Contains(DLCManager.Default.PreferredLanguage)) + //{ + // RPC.SetPresence("Editing a Pack:", $" > {locfile.GetLocEntry("IDS_DISPLAY_NAME", DLCManager.Default.PreferredLanguage)}"); + // return; + //} // default RPC.SetPresence("An Open Source .PCK File Editor"); } @@ -732,9 +733,9 @@ namespace PckStudio.Controls 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); + audioFile.AddCategory(PckAudioFile.Category.Overworld); + audioFile.AddCategory(PckAudioFile.Category.Nether); + audioFile.AddCategory(PckAudioFile.Category.End); return audioFile; } @@ -751,12 +752,12 @@ namespace PckStudio.Controls using AddFilePrompt diag = new AddFilePrompt("res/" + Path.GetFileName(ofd.FileName)); if (diag.ShowDialog(this) == DialogResult.OK) { - if (EditorValue.File.Contains(diag.Filepath, diag.Filetype)) + if (EditorValue.PckFile.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)); + PckAsset asset = EditorValue.PckFile.CreateNewAsset(diag.Filepath, diag.Filetype, () => File.ReadAllBytes(ofd.FileName)); BuildMainTreeView(); _wasModified = true; @@ -775,12 +776,12 @@ namespace PckStudio.Controls renamePrompt.LabelText = "Path"; if (renamePrompt.ShowDialog(this) == DialogResult.OK && !string.IsNullOrEmpty(renamePrompt.NewText)) { - if (EditorValue.File.Contains(renamePrompt.NewText, PckAssetType.TextureFile)) + if (EditorValue.PckFile.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)); + PckAsset asset = EditorValue.PckFile.CreateNewAsset(renamePrompt.NewText, PckAssetType.TextureFile, () => File.ReadAllBytes(fileDialog.FileName)); BuildMainTreeView(); _wasModified = true; } @@ -799,7 +800,7 @@ namespace PckStudio.Controls { string skinNameImport = Path.GetFileName(contents.FileName); byte[] data = File.ReadAllBytes(contents.FileName); - PckAsset mfNew = EditorValue.File.CreateNewAsset(skinNameImport, PckAssetType.SkinFile); + PckAsset mfNew = EditorValue.PckFile.CreateNewAsset(skinNameImport, PckAssetType.SkinFile); mfNew.SetData(data); string propertyFile = Path.GetFileNameWithoutExtension(contents.FileName) + ".txt"; if (File.Exists(propertyFile)) @@ -941,7 +942,7 @@ namespace PckStudio.Controls 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) + if ((node.TryGetTagData(out PckAsset asset) && EditorValue.PckFile.Contains(asset.Filename, asset.Type)) || node.Parent is TreeNode) { // TODO: add (mouse) scrolling while dragging item(s) treeViewMain.DoDragDrop(node, DragDropEffects.Scroll | DragDropEffects.Move); @@ -1117,14 +1118,14 @@ namespace PckStudio.Controls } } - if (EditorValue.File.Contains(filepath, assetType)) + if (EditorValue.PckFile.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)); + PckAsset importedAsset = EditorValue.PckFile.CreateNewAsset(assetPath, assetType, () => File.ReadAllBytes(filepath)); string propertyFile = filepath + ".txt"; if (File.Exists(propertyFile)) { @@ -1165,12 +1166,12 @@ namespace PckStudio.Controls if (addFile.ShowDialog(this) != DialogResult.OK) continue; - if (EditorValue.File.Contains(addFile.Filepath, addFile.Filetype)) + if (EditorValue.PckFile.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)); + EditorValue.PckFile.CreateNewAsset(addFile.Filepath, addFile.Filetype, () => File.ReadAllBytes(file)); addedCount++; BuildMainTreeView(); @@ -1186,19 +1187,19 @@ namespace PckStudio.Controls { TryGetLocFile(out LOCFile locFile); PckAsset skinAsset = addNewSkinDialog.NewSkin.CreateFile(locFile); - EditorValue.File.AddAsset(skinAsset); + EditorValue.PckFile.AddAsset(skinAsset); bool hasSkinsFolder = treeViewMain.Nodes.ContainsKey("Skins"); if (hasSkinsFolder) skinAsset.Filename = skinAsset.Filename.Insert(0, "Skins/"); // Then Skins folder - EditorValue.File.AddAsset(skinAsset); + EditorValue.PckFile.AddAsset(skinAsset); if (addNewSkinDialog.HasCape) { PckAsset capeFile = addNewSkinDialog.NewSkin.CreateCapeFile(addNewSkinDialog.CapeTexture); if (hasSkinsFolder) capeFile.Filename = capeFile.Filename.Insert(0, "Skins/"); // Then Skins folder - EditorValue.File.AddAsset(capeFile); + EditorValue.PckFile.AddAsset(capeFile); } TrySetLocFile(locFile); @@ -1215,7 +1216,7 @@ namespace PckStudio.Controls string animationFilepath = $"{ResourceLocations.GetPathFromCategory(diag.Category)}/{diag.SelectedTile.InternalName}.png"; - if (EditorValue.File.Contains(animationFilepath, PckAssetType.TextureFile)) + if (EditorValue.PckFile.Contains(animationFilepath, PckAssetType.TextureFile)) { MessageBox.Show(this, $"{diag.SelectedTile.DisplayName} is already present.", "File already present"); return; @@ -1231,7 +1232,7 @@ namespace PckStudio.Controls if (animationEditor.ShowDialog() == DialogResult.OK && newAnimation is not null) { _wasModified = true; - PckAsset asset = EditorValue.File.CreateNewAsset(animationFilepath, PckAssetType.TextureFile); + PckAsset asset = EditorValue.PckFile.CreateNewAsset(animationFilepath, PckAssetType.TextureFile); asset.SetSerializedData(newAnimation, AnimationSerializer.DefaultSerializer); BuildMainTreeView(); _currentViewPanel.LoadAsset(asset, () => _wasModified = true); @@ -1240,7 +1241,7 @@ namespace PckStudio.Controls private void audiopckToolStripMenuItem_Click(object sender, EventArgs e) { - if (EditorValue.File.Contains(PckAssetType.AudioFile)) + if (EditorValue.PckFile.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"); @@ -1264,7 +1265,7 @@ namespace PckStudio.Controls AudioEditor diag = new AudioEditor(newAudioFile, saveContext); if (diag.ShowDialog(this) == DialogResult.OK) { - EditorValue.File.AddAsset(newAudioAsset); + EditorValue.PckFile.AddAsset(newAudioAsset); } diag.Dispose(); BuildMainTreeView(); @@ -1272,51 +1273,51 @@ namespace PckStudio.Controls private void colourscolToolStripMenuItem_Click(object sender, EventArgs e) { - if (EditorValue.File.TryGetAsset("colours.col", PckAssetType.ColourTableFile, out _)) + if (EditorValue.PckFile.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); + PckAsset newColorAsset = EditorValue.PckFile.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 _)) + if (EditorValue.PckFile.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), _currentEndianness)); + EditorValue.PckFile.CreateNewAsset("Skins.pck", PckAssetType.SkinDataFile, new PckFileWriter(new PckFile(3, true), _currentEndianness)); BuildMainTreeView(); } private void behavioursbinToolStripMenuItem_Click(object sender, EventArgs e) { - if (EditorValue.File.TryGetAsset("behaviours.bin", PckAssetType.BehavioursFile, out _)) + if (EditorValue.PckFile.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())); + EditorValue.PckFile.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 _)) + if (EditorValue.PckFile.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)); + EditorValue.PckFile.CreateNewAsset("entityMaterials.bin", PckAssetType.MaterialFile, new MaterialFileWriter(materialContainer)); BuildMainTreeView(); } @@ -1333,7 +1334,7 @@ namespace PckStudio.Controls return; } // creates variable to indicate wether current pck skin structure is mashup or regular skin - bool hasSkinsPck = EditorValue.File.HasAsset("Skins.pck", PckAssetType.SkinDataFile); + bool hasSkinsPck = EditorValue.PckFile.HasAsset("Skins.pck", PckAssetType.SkinDataFile); foreach (var fullfilename in Directory.GetFiles(contents.ResultPath, "*.png")) { @@ -1380,7 +1381,7 @@ namespace PckStudio.Controls } if (hasSkinsPck) { - PckAsset skinsFileAsset = EditorValue.File.GetAsset("Skins.pck", PckAssetType.SkinDataFile); + PckAsset skinsFileAsset = EditorValue.PckFile.GetAsset("Skins.pck", PckAssetType.SkinDataFile); using (var ms = new MemoryStream(skinsFileAsset.Data)) { //var reader = new PckFileReader(LittleEndianCheckBox.Checked ? OMI.Endianness.LittleEndian : OMI.Endianness.BigEndian); @@ -1393,7 +1394,7 @@ namespace PckStudio.Controls } continue; } - EditorValue.File.AddAsset(newFile); + EditorValue.PckFile.AddAsset(newFile); } BuildMainTreeView(); _wasModified = true; @@ -1442,8 +1443,8 @@ namespace PckStudio.Controls { 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)); + if (EditorValue.PckFile.HasAsset(mippedPath, PckAssetType.TextureFile)) + EditorValue.PckFile.RemoveAsset(EditorValue.PckFile.GetAsset(mippedPath, PckAssetType.TextureFile)); PckAsset mipMappedAsset = new PckAsset(mippedPath, PckAssetType.TextureFile); Image originalTexture = asset.GetTexture(); @@ -1451,7 +1452,7 @@ namespace PckStudio.Controls mipMappedAsset.SetTexture(mippedTexture); - EditorValue.File.InsertAsset(EditorValue.File.IndexOfAsset(asset) + i - 1, mipMappedAsset); + EditorValue.PckFile.InsertAsset(EditorValue.PckFile.IndexOfAsset(asset) + i - 1, mipMappedAsset); } BuildMainTreeView(); } @@ -1532,7 +1533,7 @@ namespace PckStudio.Controls string selectedFolder = node.FullPath; - foreach (PckAsset asset in EditorValue.File.GetAssets().Where(asset => asset.Filename.StartsWith(selectedFolder))) + foreach (PckAsset asset in EditorValue.PckFile.GetAssets().Where(asset => asset.Filename.StartsWith(selectedFolder))) { extractFolderFile(outPath, asset); } @@ -1604,7 +1605,7 @@ namespace PckStudio.Controls TreeNodeCollection nodeCollection = node.Parent?.Nodes ?? treeViewMain.Nodes; nodeCollection.Insert(node.Index + 1, newNode); - EditorValue.File.InsertAsset(node.Index + 1, newFile); + EditorValue.PckFile.InsertAsset(node.Index + 1, newFile); BuildMainTreeView(); _wasModified = true; } @@ -1626,7 +1627,7 @@ namespace PckStudio.Controls { if (isFile) { - if (EditorValue.File.Contains(diag.NewText, asset.Type)) + if (EditorValue.PckFile.Contains(diag.NewText, asset.Type)) { MessageBox.Show(this, $"{diag.NewText} already exists", "File already exists"); return; @@ -1729,7 +1730,7 @@ namespace PckStudio.Controls if (node.TryGetTagData(out PckAsset asset)) { - if (!BeforeFileRemove(asset) && EditorValue.File.RemoveAsset(asset)) + if (!BeforeFileRemove(asset) && EditorValue.PckFile.RemoveAsset(asset)) { _currentViewPanel.Reset(); node.Remove(); @@ -1740,7 +1741,7 @@ namespace PckStudio.Controls MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) { string pckFolderDir = node.FullPath; - EditorValue.File.RemoveAll(file => file.Filename.StartsWith(pckFolderDir) && !BeforeFileRemove(file)); + EditorValue.PckFile.RemoveAll(file => file.Filename.StartsWith(pckFolderDir) && !BeforeFileRemove(file)); node.Remove(); _wasModified = true; } diff --git a/PCK-Studio/Controls/PckAssetBrowserEditor.resx b/PCK-Studio/Controls/RawAssetsEditor.resx similarity index 100% rename from PCK-Studio/Controls/PckAssetBrowserEditor.resx rename to PCK-Studio/Controls/RawAssetsEditor.resx diff --git a/PCK-Studio/Forms/Additional-Popups/Animation/ChangeTile.cs b/PCK-Studio/Forms/Additional-Popups/Animation/ChangeTile.cs index b9edd8c8..d56646e9 100644 --- a/PCK-Studio/Forms/Additional-Popups/Animation/ChangeTile.cs +++ b/PCK-Studio/Forms/Additional-Popups/Animation/ChangeTile.cs @@ -7,6 +7,7 @@ using PckStudio.Json; using PckStudio.Core.Extensions; using System.Drawing; using System.Linq; +using PckStudio.Controls; namespace PckStudio.Forms.Additional_Popups.Animation { @@ -36,7 +37,11 @@ namespace PckStudio.Forms.Additional_Popups.Animation public DialogResult ShowDialog(IWin32Window owner) { - return filterPrompt.ShowDialog(owner); + var f = new ImmersiveForm(); + filterPrompt.Dock = DockStyle.Fill; + filterPrompt.Update(); + f.Controls.Add(filterPrompt); + return f.ShowDialog(owner); } private void filterPrompt_OnSelectedItemChanged(object sender, EventArgs e) @@ -68,7 +73,6 @@ namespace PckStudio.Forms.Additional_Popups.Animation Tag = tileData }; view.Nodes.Add(tileNode); - (view.Tag as List).Add(tileNode); } } diff --git a/PCK-Studio/Forms/Additional-Popups/CreateTexturePackPrompt.Designer.cs b/PCK-Studio/Forms/Additional-Popups/CreateTexturePackPrompt.Designer.cs index 1004219c..e22712bc 100644 --- a/PCK-Studio/Forms/Additional-Popups/CreateTexturePackPrompt.Designer.cs +++ b/PCK-Studio/Forms/Additional-Popups/CreateTexturePackPrompt.Designer.cs @@ -34,7 +34,6 @@ this.InputTextBox = new MetroFramework.Controls.MetroTextBox(); this.resolutionComboBox = new MetroFramework.Controls.MetroComboBox(); this.label1 = new MetroFramework.Controls.MetroLabel(); - this.createSkinsPckCheckBox = new MetroFramework.Controls.MetroCheckBox(); this.SuspendLayout(); // // TextLabel @@ -99,20 +98,11 @@ this.label1.Name = "label1"; this.label1.Theme = MetroFramework.MetroThemeStyle.Dark; // - // createSkinsPckCheckBox - // - resources.ApplyResources(this.createSkinsPckCheckBox, "createSkinsPckCheckBox"); - this.createSkinsPckCheckBox.Name = "createSkinsPckCheckBox"; - this.createSkinsPckCheckBox.Style = MetroFramework.MetroColorStyle.White; - this.createSkinsPckCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark; - this.createSkinsPckCheckBox.UseSelectable = true; - // // CreateTexturePackPrompt // this.AcceptButton = this.OKButton; resources.ApplyResources(this, "$this"); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.Controls.Add(this.createSkinsPckCheckBox); this.Controls.Add(this.label1); this.Controls.Add(this.resolutionComboBox); this.Controls.Add(this.InputTextBox); @@ -132,6 +122,5 @@ private MetroFramework.Controls.MetroTextBox InputTextBox; private MetroFramework.Controls.MetroComboBox resolutionComboBox; public MetroFramework.Controls.MetroLabel label1; - private MetroFramework.Controls.MetroCheckBox createSkinsPckCheckBox; } } \ No newline at end of file diff --git a/PCK-Studio/Forms/Additional-Popups/CreateTexturePackPrompt.cs b/PCK-Studio/Forms/Additional-Popups/CreateTexturePackPrompt.cs index 9bca9700..96b70ecd 100644 --- a/PCK-Studio/Forms/Additional-Popups/CreateTexturePackPrompt.cs +++ b/PCK-Studio/Forms/Additional-Popups/CreateTexturePackPrompt.cs @@ -10,7 +10,6 @@ namespace PckStudio /// /// Text entered only access when DialogResult == DialogResult.OK /// - public bool CreateSkinsPck => createSkinsPckCheckBox.Checked; public string PackName => InputTextBox.Text; public string PackRes => resolutionComboBox.Text; diff --git a/PCK-Studio/Forms/Additional-Popups/CreateTexturePackPrompt.resx b/PCK-Studio/Forms/Additional-Popups/CreateTexturePackPrompt.resx index d6435a89..778a71be 100644 --- a/PCK-Studio/Forms/Additional-Popups/CreateTexturePackPrompt.resx +++ b/PCK-Studio/Forms/Additional-Popups/CreateTexturePackPrompt.resx @@ -147,7 +147,7 @@ $this - 5 + 4 166, 74 @@ -171,7 +171,7 @@ $this - 4 + 3 @@ -208,7 +208,7 @@ $this - 3 + 2 23 @@ -232,7 +232,7 @@ $this - 2 + 1 True @@ -262,33 +262,6 @@ $this - 1 - - - True - - - 19, 77 - - - 109, 15 - - - 8 - - - Create Skins.pck - - - createSkinsPckCheckBox - - - MetroFramework.Controls.MetroCheckBox, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a - - - $this - - 0 @@ -2813,6 +2786,6 @@ CreateTexturePackPrompt - ImmersiveForm, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a + PckStudio.Controls.ImmersiveForm, PCK-Studio, Version=7.0.0.2, Culture=neutral, PublicKeyToken=null \ No newline at end of file diff --git a/PCK-Studio/Forms/Additional-Popups/EntityForms/AddEntry.cs b/PCK-Studio/Forms/Additional-Popups/EntityForms/AddEntry.cs index 9b76ad87..56beb09e 100644 --- a/PCK-Studio/Forms/Additional-Popups/EntityForms/AddEntry.cs +++ b/PCK-Studio/Forms/Additional-Popups/EntityForms/AddEntry.cs @@ -1,8 +1,9 @@ using System; using System.Collections.Generic; using System.Windows.Forms; -using PckStudio.Forms.Additional_Popups.Animation; +using PckStudio.Controls; using PckStudio.Core.Json; +using PckStudio.Forms.Additional_Popups.Animation; using PckStudio.Json; @@ -63,8 +64,12 @@ namespace PckStudio.Forms.Additional_Popups.EntityForms public DialogResult ShowDialog(IWin32Window owner) { - return filterPrompt.ShowDialog(owner); - } + var f = new ImmersiveForm(); + filterPrompt.Dock = DockStyle.Fill; + filterPrompt.Update(); + f.Controls.Add(filterPrompt); + return f.ShowDialog(owner); + } private void treeViews_AfterSelect(object sender, TreeViewEventArgs e) { diff --git a/PCK-Studio/Forms/Additional-Popups/FilterPrompt.Designer.cs b/PCK-Studio/Forms/Additional-Popups/FilterPrompt.Designer.cs index 861ab284..23ce1716 100644 --- a/PCK-Studio/Forms/Additional-Popups/FilterPrompt.Designer.cs +++ b/PCK-Studio/Forms/Additional-Popups/FilterPrompt.Designer.cs @@ -29,9 +29,6 @@ private void InitializeComponent() { MetroFramework.Controls.MetroLabel metroLabel2; - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FilterPrompt)); - this.acceptButton = new System.Windows.Forms.Button(); - this.cancelButton = new System.Windows.Forms.Button(); this.filterTextBox = new MetroFramework.Controls.MetroTextBox(); this.tabController = new MetroFramework.Controls.MetroTabControl(); metroLabel2 = new MetroFramework.Controls.MetroLabel(); @@ -40,41 +37,13 @@ // metroLabel2 // metroLabel2.AutoSize = true; - metroLabel2.Location = new System.Drawing.Point(133, 19); + metroLabel2.Location = new System.Drawing.Point(2, 6); metroLabel2.Name = "metroLabel2"; metroLabel2.Size = new System.Drawing.Size(46, 19); metroLabel2.TabIndex = 16; metroLabel2.Text = "Filter: "; metroLabel2.Theme = MetroFramework.MetroThemeStyle.Dark; // - // acceptButton - // - this.acceptButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.acceptButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.acceptButton.ForeColor = System.Drawing.Color.White; - this.acceptButton.ImeMode = System.Windows.Forms.ImeMode.NoControl; - this.acceptButton.Location = new System.Drawing.Point(92, 196); - this.acceptButton.Name = "acceptButton"; - this.acceptButton.Size = new System.Drawing.Size(75, 23); - this.acceptButton.TabIndex = 7; - this.acceptButton.Text = "Save"; - this.acceptButton.UseVisualStyleBackColor = true; - this.acceptButton.Click += new System.EventHandler(this.AcceptBtn_Click); - // - // cancelButton - // - this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.cancelButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.cancelButton.ForeColor = System.Drawing.Color.White; - this.cancelButton.ImeMode = System.Windows.Forms.ImeMode.NoControl; - this.cancelButton.Location = new System.Drawing.Point(172, 196); - this.cancelButton.Name = "cancelButton"; - this.cancelButton.Size = new System.Drawing.Size(75, 23); - this.cancelButton.TabIndex = 13; - this.cancelButton.Text = "Cancel"; - this.cancelButton.UseVisualStyleBackColor = true; - this.cancelButton.Click += new System.EventHandler(this.CancelBtn_Click); - // // filterTextBox // // @@ -90,7 +59,7 @@ this.filterTextBox.CustomButton.UseSelectable = true; this.filterTextBox.CustomButton.Visible = false; this.filterTextBox.Lines = new string[0]; - this.filterTextBox.Location = new System.Drawing.Point(173, 18); + this.filterTextBox.Location = new System.Drawing.Point(42, 5); this.filterTextBox.MaxLength = 32767; this.filterTextBox.Name = "filterTextBox"; this.filterTextBox.PasswordChar = '\0'; @@ -100,7 +69,7 @@ this.filterTextBox.SelectionStart = 0; this.filterTextBox.ShortcutsEnabled = true; this.filterTextBox.Size = new System.Drawing.Size(156, 23); - this.filterTextBox.TabIndex = 17; + this.filterTextBox.TabIndex = 0; this.filterTextBox.Theme = MetroFramework.MetroThemeStyle.Dark; this.filterTextBox.UseSelectable = true; this.filterTextBox.WaterMarkColor = System.Drawing.Color.FromArgb(((int)(((byte)(109)))), ((int)(((byte)(109)))), ((int)(((byte)(109))))); @@ -109,48 +78,34 @@ // // tabController // - this.tabController.Location = new System.Drawing.Point(6, 8); + this.tabController.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tabController.Location = new System.Drawing.Point(0, 34); this.tabController.Name = "tabController"; - this.tabController.Size = new System.Drawing.Size(326, 184); - this.tabController.Style = MetroFramework.MetroColorStyle.White; + this.tabController.Size = new System.Drawing.Size(360, 408); + this.tabController.Style = MetroFramework.MetroColorStyle.Silver; this.tabController.TabIndex = 18; this.tabController.Theme = MetroFramework.MetroThemeStyle.Dark; this.tabController.UseSelectable = true; // - // FilterPromtp + // FilterPrompt // - this.AcceptButton = this.acceptButton; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.cancelButton; - this.ClientSize = new System.Drawing.Size(338, 228); - this.ControlBox = false; + this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(18)))), ((int)(((byte)(18))))); this.Controls.Add(this.filterTextBox); this.Controls.Add(metroLabel2); this.Controls.Add(this.tabController); - this.Controls.Add(this.cancelButton); - this.Controls.Add(this.acceptButton); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "FilterPromtp"; - this.Resizable = false; - this.Style = MetroFramework.MetroColorStyle.Silver; - this.Theme = MetroFramework.MetroThemeStyle.Dark; + this.Name = "FilterPrompt"; + this.Size = new System.Drawing.Size(360, 442); this.ResumeLayout(false); this.PerformLayout(); } - private void MetroTextBox1_TextChanged(object sender, System.EventArgs e) - { - throw new System.NotImplementedException(); - } +#endregion - #endregion - private System.Windows.Forms.Button acceptButton; - private System.Windows.Forms.Button cancelButton; private MetroFramework.Controls.MetroTextBox filterTextBox; private MetroFramework.Controls.MetroTabControl tabController; } diff --git a/PCK-Studio/Forms/Additional-Popups/FilterPrompt.cs b/PCK-Studio/Forms/Additional-Popups/FilterPrompt.cs index d86ea855..37428cd9 100644 --- a/PCK-Studio/Forms/Additional-Popups/FilterPrompt.cs +++ b/PCK-Studio/Forms/Additional-Popups/FilterPrompt.cs @@ -16,20 +16,15 @@ * 3. This notice may not be removed or altered from any source distribution. **/ using System; -using System.Collections.Generic; using System.Drawing; +using System.Reflection; using System.Windows.Forms; -using MetroFramework.Forms; +using PckStudio.Core.Extensions; namespace PckStudio.Forms.Additional_Popups.Animation { - internal partial class FilterPrompt : MetroForm + internal partial class FilterPrompt : UserControl { - public string AcceptButtonText { get => acceptButton.Text; set => acceptButton.Text = value; } - public string CancelButtonText { get => cancelButton.Text; set => cancelButton.Text = value; } - - public Color PageBackColor { get; set; } = Color.FromArgb(64, 64, 64); - private object _selectedItem; public object SelectedItem => _selectedItem; @@ -48,26 +43,64 @@ namespace PckStudio.Forms.Additional_Popups.Animation InitializeComponent(); } - public TreeView AddFilterPage(string categoryName, string key, FilterPredicate filterPredicate) + public new void Update() + { + base.Update(); + foreach (TabPage tabpage in tabController.TabPages) + { + if (tabpage.Controls[0] is not TreeView pageView || pageView.Tag is not TreeView backingView) + continue; + + pageView.BeginUpdate(); + pageView.ContextMenuStrip = backingView.ContextMenuStrip; + pageView.ImageList = backingView.ImageList; + pageView.Nodes.Clear(); + pageView.Show(); + FilterPredicate filerPredicate = tabpage.Tag as FilterPredicate; + foreach (TreeNode node in backingView.Nodes.GetLeafNodes()) + { + if (string.IsNullOrEmpty(filterTextBox.Text) || + node.FullPath.ToLower().Contains(filterTextBox.Text.ToLower()) || + (filerPredicate?.Invoke(filterTextBox.Text, node.Tag) ?? false)) + { + TreeNode n = pageView.Nodes.BuildNodeTreeBySeperator(node.FullPath, backingView.PathSeparator); + n.Tag = node.Tag; + n.ImageIndex = node.ImageIndex; + n.SelectedImageIndex = node.SelectedImageIndex; + } + } + pageView.EndUpdate(); + } + } + + public TreeView AddFilterPage(string categoryName, string key, FilterPredicate filterPredicate) { _ = categoryName ?? throw new ArgumentNullException(nameof(categoryName)); TabPage page = new TabPage(categoryName); + page.BorderStyle = BorderStyle.None; page.Name = key ?? categoryName; page.Tag = filterPredicate; var pageView = new TreeView() { Dock = DockStyle.Fill, - BackColor = PageBackColor, - }; + BackColor = BackColor, + ForeColor = ForeColor, + }; pageView.AfterSelect += (sender, e) => { _selectedItem = e.Node.Tag; Events[nameof(OnSelectedItemChanged)]?.DynamicInvoke(this, EventArgs.Empty); }; - pageView.Tag = new List(4); + var backingView = new TreeView() + { + Dock = DockStyle.Fill, + BackColor = BackColor, + ForeColor = ForeColor, + }; + pageView.Tag = backingView; page.Controls.Add(pageView); tabController.TabPages.Add(page); - return pageView; + return backingView; } public TreeView GetByKey(string key) @@ -77,43 +110,7 @@ namespace PckStudio.Forms.Additional_Popups.Animation private void filter_TextChanged(object sender, EventArgs e) { - // Some code in this function is modified code from this StackOverflow answer - MattNL - // https://stackoverflow.com/questions/8260322/filter-a-treeview-with-a-textbox-in-a-c-sharp-winforms-app - - // block re-painting control until all objects are loaded - foreach (TabPage tabpage in tabController.TabPages) - { - if (tabpage.Tag is not FilterPredicate filerPredicate || tabpage.Controls[0] is not TreeView pageView || pageView.Tag is not List pageCache) - continue; - - if (string.IsNullOrEmpty(filterTextBox.Text)) - { - pageView.Nodes.Clear(); - pageView.Nodes.AddRange(pageCache.ToArray()); - continue; - } - - pageView.BeginUpdate(); - pageView.Nodes.Clear(); - foreach (TreeNode _node in pageCache) - { - if (_node.Text.ToLower().Contains(filterTextBox.Text.ToLower()) || filerPredicate(filterTextBox.Text, _node.Tag)) - { - pageView.Nodes.Add((TreeNode)_node.Clone()); - } - } - pageView.EndUpdate(); - } - } - - private void CancelBtn_Click(object sender, EventArgs e) - { - DialogResult = DialogResult.Cancel; - } - - private void AcceptBtn_Click(object sender, EventArgs e) - { - DialogResult = _selectedItem is null ? DialogResult.Cancel : DialogResult.OK; + Update(); } } } diff --git a/PCK-Studio/Forms/Additional-Popups/FilterPrompt.resx b/PCK-Studio/Forms/Additional-Popups/FilterPrompt.resx index 608774a9..f00be546 100644 --- a/PCK-Studio/Forms/Additional-Popups/FilterPrompt.resx +++ b/PCK-Studio/Forms/Additional-Popups/FilterPrompt.resx @@ -120,2517 +120,4 @@ False - - True - - - True - - - - - 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 - Tfr6LE9nbYpX/JKYCgGFwgAh6szKQQZn6KfRZOPDjLQMGLihYBm9ZdUWA4hO/4UYIBaICWKDNfzM5xMz - xA6tSh4qxBQV35v7JTYKhcJBCGgRsHoQxUYMWJpJYdI64B0DFC4wduD0X4gBdpsSE8QGDw2e9MQMsUMM - EUvElFf8DjBtDagQMDpLq4BxAroIKDkFywxCCAM6Tv8hXv7EBLFBhedJT8wQO1rxvbnfgRaKAeMEQIEC - TTnHUTQuiBGt8F7pu8woTMdJws3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3N - zc3Nzc3Nzc3Nza2M9r73/T9XFdyT+zuuLAAAAABJRU5ErkJggigAAACAAAAAAAEAAAEAIAAAAAAAAAAC - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAMAAAAGAAAA - CAAAAAoAAAAKAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAA - CwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAA - CwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAA - CwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAA - CwAAAAsAAAALAAAACwAAAAsAAAALAAAACgAAAAoAAAAIAAAABQAAAAMAAAABAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAQAAAAQAAAALAAAAFAAAAB4AAAAlAAAAKwAAACwAAAAtAAAALQAAAC0AAAAtAAAA - LQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAA - LQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAA - LQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAA - LQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAsAAAA - KgAAACUAAAAdAAAAFAAAAAsAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAJAAAAFwAAACoAAABBAAAA - VAAAAGEAAABpAAAAbAAAAG0AAABtAAAAbQAAAG0AAABtAAAAbQAAAG0AAABtAAAAbQAAAG0AAABtAAAA - bQAAAG0AAABtAAAAbQAAAG0AAABtAAAAbQAAAG0AAABtAAAAbQAAAG0AAABtAAAAbQAAAG0AAABtAAAA - bQAAAG0AAABtAAAAbQAAAG0AAABtAAAAbQAAAG0AAABtAAAAbQAAAG0AAABtAAAAbQAAAG0AAABtAAAA - bQAAAG0AAABtAAAAbQAAAG0AAABtAAAAbQAAAG0AAABtAAAAbQAAAG0AAABtAAAAbQAAAG0AAABtAAAA - bQAAAG0AAABtAAAAbQAAAG0AAABtAAAAbQAAAGwAAABpAAAAYQAAAFIAAABBAAAALAAAABkAAAAMAAAA - AwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAEAAAADwAAACMAAABBAAAAYgAAAIGmpqbN/v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+ - //7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+ - //7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+ - //7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+ - //7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+ - ///////+/v7/p6enzAAAAIEAAABlAAAARgAAACoAAAATAAAABwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABEAAAArAAAAUgAAAHz///////// - //7+/v+YmJj/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/5mZmf////////////////8AAACEAAAA - XAAAADcAAAAaAAAACAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAIAAAAPAAAALAAAAFgAAACL//////v7+/8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/5OTk///////Y2NjlAAAAawAAAD0AAAAbAAAACAAAAAEAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAACUAAABTJSUllf////9LS0v/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AgIC - ////////////AAAAbgAAADwAAAAYAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAQAAAAaAAAARQAAAID/////ExMT/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA///////+/v7/AAAAaAAAADQAAAAQAAAA - AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAADQAAAC8AAABo/v7+/2tra/8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA////////////AAAAVgAAACQAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAQAAAAZAAAASc3Nzdj+/v7/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA//////8AAAB7AAAA - PQAAABMAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQAAACgAAABi/////wMDA/8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wMDA/8ZGRn/Gxsb/xwcHP8cHBz/HBwc/xwcHP8cHBz/HBwc - /xwcHP8cHBz/HBwc/xwcHP8cHBz/HBwc/xwcHP8cHBz/HBwc/xwcHP8cHBz/HBwc/xwcHP8cHBz/HBwc - /xwcHP8cHBz/HBwc/xwcHP8cHBz/HBwc/xwcHP8cHBz/HBwc/xwcHP8cHBz/HBwc/xwcHP8cHBz/HBwc - /xwcHP8cHBz/HBwc/xwcHP8cHBz/HBwc/xwcHP8cHBz/HBwc/xwcHP8cHBz/HBwc/xwcHP8cHBz/HBwc - /xwcHP8cHBz/HBwc/xwcHP8cHBz/HBwc/xwcHP8cHBz/Gxsb/woKCv8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/sbGx//////8AAABYAAAAIgAAAAcAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAPAAAANwAAAHj/////AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/xcXF/8fHx//IyMj - /yUlJf8nJyf/Jycn/ygoKP8oKCj/KCgo/ygoKP8oKCj/KCgo/ygoKP8oKCj/KCgo/ygoKP8oKCj/KCgo - /ygoKP8oKCj/KCgo/ygoKP8oKCj/KCgo/ygoKP8oKCj/KCgo/ygoKP8oKCj/KCgo/ygoKP8oKCj/KCgo - /ygoKP8oKCj/KCgo/ygoKP8oKCj/KCgo/ygoKP8oKCj/KCgo/ygoKP8oKCj/KCgo/ygoKP8oKCj/KCgo - /ygoKP8oKCj/KCgo/ygoKP8oKCj/KCgo/ygoKP8oKCj/KCgo/ygoKP8oKCj/KCgo/ygoKP8oKCj/KCgo - /ycnJ/8nJyf/JiYm/yMjI/8gICD/Ghoa/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD///// - /wAAAHEAAAAyAAAADQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAABUAAABE/////4iIiP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8TExP/Hx8f/yUlJf8pKSn/Kysr/y0tLf8tLS3/LS0t/y0tLf8tLS3/LS0t - /y0tLf8tLS3/LS0t/y0tLf8tLS3/LS0t/y0tLf8tLS3/LS0t/y0tLf8tLS3/LS0t/y0tLf8tLS3/LS0t - /y0tLf8tLS3/LS0t/y0tLf8tLS3/LS0t/y0tLf8tLS3/LS0t/y0tLf8tLS3/LS0t/y0tLf8tLS3/LS0t - /y0tLf8tLS3/LS0t/y0tLf8tLS3/LS0t/y0tLf8tLS3/LS0t/y0tLf8tLS3/LS0t/y0tLf8tLS3/LS0t - /y0tLf8tLS3/LS0t/y0tLf8tLS3/LS0t/y0tLf8tLS3/LS0t/y0tLf8sLCz/Kioq/ycnJ/8iIiL/Gxsb - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP/r6+v/ycnJ0gAAAEAAAAATAAAAAQAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAADAAAAGgAAAE/+/v7/Dw8P/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/x0dHf8kJCT/Kioq - /y4uLv8wMDD/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx - /zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx - /zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx - /zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx - /zExMf8xMTH/MTEx/zAwMP8vLy//LCws/ygoKP8hISH/Ghoa/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /xEREf/+/v7/AAAATQAAABkAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAeAAAAVv////8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/ICAg/ycnJ/8tLS3/MTEx/zIyMv8zMzP/MzMz/zMzM/8zMzP/MzMz - /zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz - /zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz - /zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz - /zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjIy/zIyMv8wMDD/LCws - /yUlJf8eHh7/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA//////8AAABVAAAAHQAAAAQAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAABQAAACAAAABa/////wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wgICP8iIiL/KSkp - /y8vL/8yMjL/MzMz/zQ0NP80NDT/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en/6enp/+np6f/paWl - /zQ0NP80NDT/NDQ0/0tLS/+np6f/p6en/6enp/+np6f/NDQ0/zQ0NP80NDT/Q0ND/6enp/+np6f/p6en - /6enp/+np6f/p6en/6enp/+np6f/p6en/zQ0NP+np6f/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en - /0pKSv80NDT/NDQ0/6enp/+np6f/p6en/6enp/80NDT/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en - /6enp/+np6f/p6en/zQ0NP80NDT/MzMz/zExMf8uLi7/KCgo/yEhIf8HBwf/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD//////wAAAFkAAAAgAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAIQAAAFv/////AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/GRkZ/yQkJP8rKyv/MTEx/zMzM/80NDT/NDQ0/zQ0NP+urq7/rq6u - /66urv+urq7/rq6u/66urv+urq7/rq6u/66urv+rq6v/NDQ0/zQ0NP80NDT/TExM/66urv+urq7/rq6u - /66urv80NDT/NDQ0/zQ0NP9ERET/rq6u/66urv+urq7/rq6u/66urv+urq7/rq6u/66urv+urq7/NDQ0 - /66urv+urq7/rq6u/66urv+urq7/rq6u/66urv+urq7/rq6u/66urv80NDT/rq6u/66urv+urq7/rq6u - /zQ0NP+urq7/rq6u/66urv+urq7/rq6u/66urv+urq7/rq6u/66urv+urq7/NDQ0/zQ0NP80NDT/MjIy - /y8vL/8qKir/IyMj/xkZGf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP//////AAAAWwAAACEAAAAFAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAUAAAAhAAAAW/////8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8cHBz/JSUl - /ywsLP8xMTH/MzMz/zU1Nf81NTX/NTU1/6Ghof+hoaH/oaGh/6Ghof+hoaH/oqKi/7Ozs/+zs7P/s7Oz - /7CwsP81NTX/NTU1/zU1Nf9OTk7/s7Oz/7Ozs/+zs7P/s7Oz/zU1Nf81NTX/NTU1/0RERP+zs7P/s7Oz - /7Ozs/+zs7P/oaGh/7Ozs/+zs7P/s7Oz/7Ozs/80NDT/s7Oz/7Ozs/+zs7P/s7Oz/6CgoP+goKD/s7Oz - /7Ozs/+zs7P/s7Oz/zQ0NP+zs7P/s7Oz/7Ozs/+zs7P/NDQ0/7Ozs/+zs7P/s7Oz/7Ozs/+goKD/oKCg - /7Ozs/+zs7P/s7Oz/7Ozs/80NDT/NDQ0/zQ0NP8yMjL/MDAw/ysrK/8kJCT/Gxsb/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA//////8AAABbAAAAIQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAACIAAABc//// - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/xwcHP8lJSX/LCws/zExMf8zMzP/NTU1/zU1Nf81NTX/NTU1 - /zU1Nf81NTX/NTU1/zU1Nf81NTX/urq6/7q6uv+6urr/t7e3/zU1Nf81NTX/NTU1/05OTv+6urr/urq6 - /7q6uv+6urr/NTU1/zU1Nf81NTX/RUVF/7q6uv+6urr/urq6/7S0tP81NTX/urq6/7q6uv+6urr/urq6 - /zU1Nf+6urr/urq6/7q6uv+6urr/NTU1/zU1Nf+6urr/urq6/7q6uv+6urr/NTU1/7q6uv+6urr/urq6 - /7q6uv81NTX/urq6/7q6uv+6urr/urq6/zU1Nf81NTX/urq6/7q6uv+6urr/urq6/zU1Nf81NTX/NTU1 - /zMzM/8xMTH/LCws/yUlJf8cHBz/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD//////wAAAFwAAAAiAAAA - BgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAIgAAAFz/////AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/HBwc - /yUlJf8sLCz/MTEx/zMzM/81NTX/NTU1/zU1Nf81NTX/NTU1/zU1Nf81NTX/NTU1/zU1Nf/BwcH/wcHB - /8HBwf++vr7/NTU1/zU1Nf81NTX/T09P/8HBwf/BwcH/wcHB/8HBwf81NTX/NTU1/zU1Nf9ERET/wcHB - /8HBwf/BwcH/u7u7/zU1Nf/BwcH/wcHB/8HBwf/BwcH/NTU1/8HBwf/BwcH/wcHB/8HBwf81NTX/NTU1 - /8HBwf/BwcH/wcHB/8HBwf81NTX/wcHB/8HBwf/BwcH/wcHB/zU1Nf/BwcH/wcHB/8HBwf/BwcH/NTU1 - /zU1Nf/BwcH/wcHB/8HBwf/BwcH/NTU1/zU1Nf81NTX/MzMz/zExMf8sLCz/JSUl/xwcHP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP//////AAAAXAAAACIAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAiAAAA - XP////8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8dHR3/JiYm/y0tLf8yMjL/NDQ0/zY2Nv82Njb/NjY2 - /8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8TExP82Njb/NjY2/zY2Nv9RUVH/yMjI - /8jIyP/IyMj/yMjI/zY2Nv82Njb/NTU1/0ZGRv/IyMj/yMjI/8jIyP/BwcH/NTU1/8jIyP/IyMj/yMjI - /8jIyP81NTX/yMjI/8jIyP/IyMj/yMjI/zU1Nf81NTX/yMjI/8jIyP/IyMj/yMjI/zU1Nf/IyMj/yMjI - /8jIyP/IyMj/NTU1/8jIyP/IyMj/yMjI/8jIyP81NTX/NTU1/8jIyP/IyMj/yMjI/8jIyP81NTX/NTU1 - /zU1Nf8zMzP/MTEx/ywsLP8lJSX/HBwc/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA//////8AAABcAAAA - IgAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAACIAAABc/////wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /x0dHf8mJib/LS0t/zIyMv80NDT/NjY2/zY2Nv82Njb/z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P - /8/Pz//Pz8//y8vL/zY2Nv82Njb/NjY2/1FRUf/Pz8//z8/P/8/Pz//Pz8//NjY2/zY2Nv82Njb/R0dH - /8/Pz//Pz8//z8/P/8jIyP82Njb/z8/P/8/Pz//Pz8//z8/P/zY2Nv/Pz8//z8/P/8/Pz//Pz8//NjY2 - /zY2Nv/Pz8//z8/P/8/Pz//Pz8//NjY2/8/Pz//Pz8//z8/P/8/Pz/82Njb/z8/P/8/Pz//Pz8//z8/P - /zY2Nv82Njb/z8/P/8/Pz//Pz8//z8/P/zY2Nv82Njb/NTU1/zMzM/8xMTH/LCws/yUlJf8cHBz/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD//////wAAAFwAAAAiAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAA - IgAAAFz/////AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/HR0d/yYmJv8tLS3/MjIy/zQ0NP82Njb/NjY2 - /zY2Nv/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/V1dX/1dXV/9XV1f/R0dH/NjY2/zY2Nv82Njb/UlJS - /9XV1f/V1dX/1dXV/9XV1f82Njb/NjY2/zY2Nv9HR0f/1dXV/9XV1f/V1dX/zc3N/zY2Nv/V1dX/1dXV - /9XV1f/V1dX/NjY2/9XV1f/V1dX/1dXV/9XV1f82Njb/NjY2/9XV1f/V1dX/1dXV/9XV1f82Njb/1dXV - /9XV1f/V1dX/1dXV/zY2Nv/V1dX/1dXV/9XV1f/V1dX/NjY2/zY2Nv/V1dX/1dXV/9XV1f/V1dX/NjY2 - /zY2Nv82Njb/NDQ0/zIyMv8tLS3/JiYm/x0dHf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP//////AAAA - XAAAACIAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAiAAAAXP////8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8dHR3/JiYm/y0tLf8yMjL/NDQ0/zY2Nv82Njb/NjY2/9zc3P/c3Nz/3Nzc/9zc3P82Njb/NjY2 - /zY2Nv82Njb/NjY2/zY2Nv82Njb/NjY2/zY2Nv9TU1P/3Nzc/9zc3P/c3Nz/3Nzc/zY2Nv82Njb/NjY2 - /0hISP/c3Nz/3Nzc/9zc3P/U1NT/NjY2/9zc3P/c3Nz/3Nzc/9zc3P82Njb/3Nzc/9zc3P/c3Nz/3Nzc - /zY2Nv82Njb/3Nzc/9zc3P/c3Nz/3Nzc/zY2Nv/c3Nz/3Nzc/9zc3P/c3Nz/NjY2/9zc3P/c3Nz/3Nzc - /9zc3P82Njb/NjY2/9zc3P/c3Nz/3Nzc/9zc3P82Njb/NjY2/zY2Nv80NDT/MjIy/y0tLf8mJib/HR0d - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA//////8AAABcAAAAIgAAAAYAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - BgAAACIAAABc/////wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/x0dHf8nJyf/Li4u/zMzM/81NTX/Nzc3 - /zc3N/83Nzf/4+Pj/+Pj4//j4+P/4+Pj/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3 - /1VVVf/j4+P/4+Pj/+Pj4//j4+P/Nzc3/zc3N/83Nzf/SUlJ/+Pj4//j4+P/4+Pj/9ra2v83Nzf/4+Pj - /+Pj4//j4+P/4+Pj/zY2Nv/j4+P/4+Pj/+Pj4//j4+P/NjY2/zY2Nv/j4+P/4+Pj/+Pj4//j4+P/NjY2 - /+Pj4//j4+P/4+Pj/+Pj4/82Njb/4+Pj/+Pj4//j4+P/4+Pj/zY2Nv82Njb/4+Pj/+Pj4//j4+P/4+Pj - /zY2Nv82Njb/NjY2/zQ0NP8yMjL/LS0t/yYmJv8dHR3/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD///// - /wAAAFwAAAAiAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAIgAAAFz/////AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/HR0d/ycnJ/8uLi7/MzMz/zU1Nf83Nzf/Nzc3/zc3N//q6ur/6urq/+rq6v/q6ur/Nzc3 - /zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/VVVV/+rq6v/q6ur/6urq/+rq6v83Nzf/Nzc3 - /zc3N/9KSkr/6urq/+rq6v/q6ur/4eHh/zc3N//q6ur/6urq/+rq6v/q6ur/Nzc3/+rq6v/q6ur/6urq - /+rq6v83Nzf/Nzc3/+rq6v/q6ur/6urq/+rq6v83Nzf/6urq/+rq6v/q6ur/6urq/zc3N//q6ur/6urq - /+rq6v/q6ur/Nzc3/zc3N//q6ur/6urq/+rq6v/q6ur/Nzc3/zc3N/83Nzf/NTU1/zMzM/8uLi7/Jycn - /x0dHf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP//////AAAAXAAAACIAAAAGAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAYAAAAiAAAAXP////8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8dHR3/Jycn/y4uLv8zMzP/NTU1 - /zc3N/83Nzf/Nzc3//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx/+zs7P83Nzf/8fHx - //Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/Nzc3/0pKSv/x8fH/8fHx//Hx8f/n5+f/Nzc3 - //Hx8f/x8fH/8fHx//Hx8f83Nzf/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx - /zc3N//x8fH/8fHx//Hx8f/x8fH/Nzc3//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx - //Hx8f83Nzf/Nzc3/zc3N/81NTX/MzMz/y4uLv8nJyf/HR0d/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - //////8AAABcAAAAIgAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAACIAAABc/////wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/x4eHv8oKCj/Ly8v/zQ0NP82Njb/ODg4/zg4OP84ODj/+Pj4//j4+P/4+Pj/+Pj4 - //j4+P/4+Pj/+Pj4//j4+P/4+Pj/8vLy/zg4OP/4+Pj/+Pj4//j4+P/4+Pj/+Pj4//j4+P/4+Pj/+Pj4 - //j4+P83Nzf/SkpK//j4+P/4+Pj/+Pj4/+7u7v83Nzf/+Pj4//j4+P/4+Pj/+Pj4/zc3N//4+Pj/+Pj4 - //j4+P/4+Pj/+Pj4//j4+P/4+Pj/+Pj4/1VVVf83Nzf/Nzc3//j4+P/4+Pj/+Pj4//j4+P83Nzf/+Pj4 - //j4+P/4+Pj/+Pj4//j4+P/4+Pj/+Pj4//j4+P/4+Pj/+Pj4/zc3N/83Nzf/Nzc3/zU1Nf8zMzP/Li4u - /ycnJ/8dHR3/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD//////wAAAFwAAAAiAAAABgAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAGAAAAIgAAAFz/////AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/Hh4e/ygoKP8vLy//NDQ0 - /zY2Nv84ODj/ODg4/zg4OP9xcXH/cXFx/3Fxcf9xcXH/cXFx/3Fxcf9xcXH/cXFx/3Fxcf9vb2//ODg4 - /3Fxcf9xcXH/cXFx/3Fxcf9xcXH/cXFx/3Fxcf9xcXH/cXFx/zg4OP87Ozv/cXFx/3Fxcf9xcXH/bW1t - /zg4OP9xcXH/cXFx/3Fxcf9xcXH/ODg4/3Fxcf9xcXH/cXFx/3Fxcf9xcXH/cXFx/3Fxcf9xcXH/Pj4+ - /zg4OP84ODj/cXFx/3Fxcf9xcXH/cXFx/zg4OP9xcXH/cXFx/3Fxcf9xcXH/cXFx/3Fxcf9xcXH/cXFx - /3Fxcf9xcXH/Nzc3/zc3N/83Nzf/NTU1/zMzM/8uLi7/Jycn/x0dHf8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP//////AAAAXAAAACIAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAiAAAAXP////8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8eHh7/KCgo/y8vL/80NDT/NjY2/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4 - /zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4 - /zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4 - /zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4 - /zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP82Njb/NDQ0 - /y8vL/8oKCj/Hh4e/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA//////8AAABcAAAAIgAAAAYAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAABgAAACIAAABc/////wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/x4eHv8oKCj/Ly8v - /zQ0NP82Njb/ODg4/zg4OP84ODj/pKSk/6SkpP+kpKT/pKSk/6SkpP+kpKT/pKSk/6SkpP84ODj/ODg4 - /zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/pKSk/6SkpP+kpKT/pKSk - /6SkpP+kpKT/pKSk/6SkpP+kpKT/pKSk/6SkpP+kpKT/pKSk/6SkpP+kpKT/pKSk/zg4OP84ODj/pKSk - /6SkpP+kpKT/pKSk/6SkpP+kpKT/pKSk/6SkpP84ODj/ODg4/zg4OP+kpKT/pKSk/6SkpP+kpKT/pKSk - /6SkpP+kpKT/pKSk/zg4OP84ODj/ODg4/zY2Nv80NDT/Ly8v/ygoKP8eHh7/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD//////wAAAFwAAAAiAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAIgAAAFz/////AQEB - /wEBAf8BAQH/AQEB/wEBAf8BAQH/Hh4e/ygoKP8vLy//NTU1/zc3N/85OTn/OTk5/zk5Of+np6f/p6en - /6enp/+np6f/p6en/6enp/+np6f/p6en/zk5Of85OTn/OTk5/zk5Of85OTn/OTk5/zk5Of85OTn/OTk5 - /zk5Of85OTn/OTk5/zk5Of+np6f/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en - /6enp/+np6f/p6en/6enp/+np6f/ODg4/zg4OP+np6f/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en - /zg4OP84ODj/ODg4/6enp/+np6f/p6en/6enp/+np6f/p6en/6enp/+np6f/ODg4/zg4OP84ODj/NjY2 - /zQ0NP8vLy//KCgo/x4eHv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP//////AAAAXAAAACIAAAAGAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAYAAAAiAAAAXP////8CAgL/AgIC/wICAv8CAgL/AgIC/wICAv8eHh7/KCgo - /y8vL/81NTX/Nzc3/zk5Of85OTn/OTk5/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/OTk5 - /zk5Of85OTn/OTk5/zk5Of85OTn/OTk5/zk5Of85OTn/OTk5/zk5Of85OTn/OTk5/6urq/+rq6v/q6ur - /6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/85OTn/OTk5 - /6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/OTk5/zk5Of85OTn/q6ur/6urq/+rq6v/q6ur - /6urq/+rq6v/q6ur/6urq/85OTn/OTk5/zk5Of83Nzf/NTU1/y8vL/8oKCj/Hh4e/wEBAf8BAQH/AQEB - /wEBAf8BAQH/AQEB//////8AAABcAAAAIgAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAACIAAABc//// - /wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/x4eHv8oKCj/Ly8v/zU1Nf83Nzf/OTk5/zk5Of85OTn/rq6u - /66urv+urq7/rq6u/66urv+urq7/rq6u/66urv85OTn/OTk5/zk5Of85OTn/OTk5/zk5Of85OTn/OTk5 - /zk5Of85OTn/OTk5/zk5Of85OTn/rq6u/66urv+urq7/rq6u/66urv+urq7/rq6u/66urv+urq7/rq6u - /66urv+urq7/rq6u/66urv+urq7/rq6u/zk5Of85OTn/rq6u/66urv+urq7/rq6u/66urv+urq7/rq6u - /66urv85OTn/OTk5/zk5Of+urq7/rq6u/66urv+urq7/rq6u/66urv+urq7/rq6u/zk5Of85OTn/OTk5 - /zc3N/81NTX/Ly8v/ygoKP8eHh7/AgIC/wICAv8CAgL/AgIC/wICAv8CAgL//////wAAAFwAAAAiAAAA - BgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAIgAAAFz/////AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/Hx8f - /ykpKf8wMDD/NjY2/zg4OP86Ojr/Ojo6/zo6Ov+ysrL/srKy/7Kysv+ysrL/srKy/7Kysv+ysrL/srKy - /zo6Ov86Ojr/Ojo6/zo6Ov85OTn/OTk5/zk5Of85OTn/OTk5/zk5Of85OTn/OTk5/zk5Of+ysrL/srKy - /7Kysv+ysrL/srKy/7Kysv+ysrL/srKy/7Kysv+ysrL/srKy/7Kysv+ysrL/srKy/7Kysv+ysrL/OTk5 - /zk5Of+ysrL/srKy/7Kysv+ysrL/srKy/7Kysv+ysrL/srKy/zk5Of85OTn/OTk5/7Kysv+ysrL/srKy - /7Kysv+ysrL/srKy/7Kysv+ysrL/OTk5/zk5Of85OTn/Nzc3/zU1Nf8vLy//KCgo/x4eHv8DAwP/AwMD - /wMDA/8DAwP/AwMD/wMDA///////AAAAXAAAACIAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAiAAAA - XP////8EBAT/BAQE/wQEBP8EBAT/BAQE/wQEBP8fHx//KSkp/zAwMP82Njb/ODg4/zo6Ov86Ojr/Ojo6 - /7W1tf+1tbX/tbW1/7W1tf+1tbX/tbW1/7W1tf+1tbX/Ojo6/zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/Ojo6 - /zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/Ojo6/7W1tf+1tbX/tbW1/7W1tf+1tbX/tbW1/7W1tf+1tbX/Ojo6 - /zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/Ojo6/7W1tf+1tbX/tbW1/7W1tf+1tbX/tbW1 - /7W1tf+1tbX/Ojo6/zo6Ov86Ojr/tbW1/7W1tf+1tbX/tbW1/7W1tf+1tbX/tbW1/7W1tf85OTn/OTk5 - /zk5Of83Nzf/NTU1/y8vL/8oKCj/Hh4e/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD//////8AAABcAAAA - IgAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAACIAAABc/////wQEBP8EBAT/BAQE/wQEBP8EBAT/BAQE - /x8fH/8pKSn/MDAw/zY2Nv84ODj/Ojo6/zo6Ov86Ojr/ubm5/7m5uf+5ubn/ubm5/7m5uf+5ubn/ubm5 - /7m5uf86Ojr/Ojo6/zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/ubm5 - /7m5uf+5ubn/ubm5/7m5uf+5ubn/ubm5/7m5uf86Ojr/Ojo6/zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/Ojo6 - /zo6Ov86Ojr/ubm5/7m5uf+5ubn/ubm5/7m5uf+5ubn/ubm5/7m5uf86Ojr/Ojo6/zo6Ov+5ubn/ubm5 - /7m5uf+5ubn/ubm5/7m5uf+5ubn/ubm5/zo6Ov86Ojr/Ojo6/zg4OP82Njb/MDAw/ykpKf8fHx//BAQE - /wQEBP8EBAT/BAQE/wQEBP8EBAT//////wAAAFwAAAAiAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAA - IgAAAFz/////BQUF/wUFBf8FBQX/BQUF/wUFBf8FBQX/Hx8f/ykpKf8wMDD/NjY2/zg4OP86Ojr/Ojo6 - /zo6Ov+8vLz/vLy8/7y8vP+8vLz/vLy8/7y8vP+8vLz/vLy8/zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/Ojo6 - /zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/Ojo6/zo6Ov+8vLz/vLy8/7y8vP+8vLz/vLy8/7y8vP+8vLz/vLy8 - /zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/Ojo6/zo6Ov+8vLz/vLy8/7y8vP+8vLz/vLy8 - /7y8vP+8vLz/vLy8/zo6Ov86Ojr/Ojo6/7y8vP+8vLz/vLy8/7y8vP+8vLz/vLy8/7y8vP+8vLz/Ojo6 - /zo6Ov86Ojr/ODg4/zY2Nv8wMDD/KSkp/x8fH/8FBQX/BAQE/wQEBP8EBAT/BAQE/wQEBP//////AAAA - XAAAACIAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAiAAAAXP////8GBgb/BgYG/wYGBv8GBgb/BgYG - /wYGBv8gICD/Kioq/zExMf83Nzf/OTk5/zs7O/87Ozv/Ozs7/7+/v/+/v7//v7+//7+/v/+/v7//v7+/ - /7+/v/+/v7//Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7 - /7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//Ojo6/zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/Ojo6 - /zo6Ov86Ojr/Ojo6/7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+/ - /7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/86Ojr/Ojo6/zo6Ov84ODj/NjY2/zAwMP8pKSn/Hx8f - /wUFBf8FBQX/BQUF/wUFBf8FBQX/BQUF//////8AAABcAAAAIgAAAAYAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - BgAAACIAAABc/////wcHB/8HBwf/BwcH/wcHB/8HBwf/BwcH/yAgIP8qKir/MTEx/zc3N/85OTn/Ozs7 - /zs7O/87Ozv/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw/87Ozv/Ozs7/zs7O/87Ozv/Ozs7 - /zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD - /8PDw/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/w8PD/8PDw//Dw8P/w8PD - /8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD - /zs7O/87Ozv/Ozs7/zg4OP82Njb/MDAw/ykpKf8fHx//BgYG/wYGBv8GBgb/BgYG/wYGBv8GBgb///// - /wAAAFwAAAAiAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAIgAAAFz/////BwcH/wcHB/8HBwf/BwcH - /wcHB/8HBwf/ICAg/yoqKv8xMTH/Nzc3/zk5Of87Ozv/Ozs7/zs7O//Gxsb/xsbG/8bGxv/Gxsb/xsbG - /8bGxv/Gxsb/xsbG/4KCgv+CgoL/goKC/4KCgv+CgoL/goKC/4KCgv+CgoL/goKC/4KCgv+CgoL/Ozs7 - /zs7O//Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7 - /zs7O/87Ozv/Ozs7/zs7O//Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG - /8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/Ozs7/zs7O/87Ozv/OTk5/zc3N/8xMTH/Kioq - /yAgIP8HBwf/BwcH/wcHB/8HBwf/BwcH/wcHB///////AAAAXAAAACIAAAAGAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAYAAAAiAAAAXP////8ICAj/CAgI/wgICP8ICAj/CAgI/wgICP8gICD/Kioq/zIyMv84ODj/Ojo6 - /zw8PP88PDz/PDw8/8rKyv/Kysr/ysrK/8rKyv/Kysr/ysrK/8rKyv/Kysr/ysrK/8rKyv/Kysr/ysrK - /8rKyv/Kysr/ysrK/8rKyv/Kysr/ysrK/8rKyv87Ozv/Ozs7/8rKyv/Kysr/ysrK/8rKyv/Kysr/ysrK - /8rKyv/Kysr/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/8rKyv/Kysr/ysrK - /8rKyv/Kysr/ysrK/8rKyv/Kysr/ysrK/8rKyv/Kysr/ysrK/8rKyv/Kysr/ysrK/8rKyv/Kysr/ysrK - /8rKyv87Ozv/Ozs7/zs7O/85OTn/Nzc3/zExMf8qKir/ICAg/wcHB/8HBwf/BwcH/wcHB/8HBwf/BwcH - //////8AAABcAAAAIgAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAACIAAABc/////wkJCf8JCQn/CQkJ - /wkJCf8JCQn/CAgI/yAgIP8qKir/MjIy/zg4OP86Ojr/PDw8/zw8PP88PDz/zs7O/87Ozv/Ozs7/zs7O - /87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O - /zw8PP88PDz/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv88PDz/PDw8/zw8PP88PDz/PDw8 - /zw8PP88PDz/PDw8/zw8PP88PDz/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O - /87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/zs7O/87Ozv/Ozs7/zk5Of83Nzf/MTEx - /yoqKv8gICD/CAgI/wgICP8ICAj/CAgI/wgICP8ICAj//////wAAAFwAAAAiAAAABgAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAGAAAAIgAAAFz/////CQkJ/wkJCf8JCQn/CQkJ/wkJCf8JCQn/ICAg/yoqKv8yMjL/ODg4 - /zo6Ov88PDz/PDw8/zw8PP/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR - /9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/PDw8/zw8PP/R0dH/0dHR/9HR0f/R0dH/0dHR - /9HR0f/R0dH/0dHR/zw8PP88PDz/PDw8/zw8PP88PDz/PDw8/zw8PP88PDz/PDw8/zw8PP/R0dH/0dHR - /9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/qamp/zw8PP88PDz/PDw8 - /zw8PP88PDz/PDw8/zw8PP88PDz/Ojo6/zg4OP8yMjL/Kioq/yAgIP8JCQn/CQkJ/wkJCf8JCQn/CQkJ - /wkJCf//////AAAAXAAAACIAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAiAAAAXP////8KCgr/CgoK - /woKCv8KCgr/CgoK/woKCv8hISH/Kysr/zMzM/84ODj/Ojo6/zw8PP88PDz/PDw8/9TU1P/U1NT/1NTU - /9TU1P/U1NT/1NTU/9TU1P/U1NT/1NTU/9TU1P/U1NT/1NTU/9TU1P/U1NT/1NTU/9TU1P/U1NT/1NTU - /9TU1P88PDz/PDw8/9TU1P/U1NT/1NTU/9TU1P/U1NT/1NTU/9TU1P/U1NT/PDw8/zw8PP88PDz/PDw8 - /zw8PP88PDz/PDw8/zw8PP88PDz/PDw8/9TU1P/U1NT/1NTU/9TU1P/U1NT/1NTU/9TU1P/U1NT/1NTU - /9TU1P/U1NT/1NTU/9TU1P+rq6v/PDw8/zw8PP88PDz/PDw8/zw8PP88PDz/PDw8/zw8PP86Ojr/ODg4 - /zIyMv8qKir/ICAg/wkJCf8JCQn/CQkJ/wkJCf8JCQn/CQkJ//////8AAABcAAAAIgAAAAYAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAABgAAACIAAABc/////wsLC/8LCwv/CwsL/wsLC/8LCwv/CwsL/yEhIf8rKyv/MzMz - /zg4OP87Ozv/PT09/z09Pf89PT3/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX - /9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/z09Pf89PT3/19fX/9fX1//X19f/19fX - /9fX1//X19f/19fX/9fX1/89PT3/PT09/z09Pf89PT3/PT09/zw8PP88PDz/PDw8/zw8PP88PDz/19fX - /9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/6ysrP88PDz/PDw8 - /zw8PP88PDz/PDw8/zw8PP88PDz/PDw8/zo6Ov84ODj/MjIy/yoqKv8gICD/CgoK/woKCv8KCgr/CgoK - /woKCv8KCgr//////wAAAFwAAAAiAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAIgAAAFz/////CwsL - /wsLC/8LCwv/CwsL/wsLC/8LCwv/ISEh/ysrK/8zMzP/ODg4/zs7O/89PT3/PT09/z09Pf/b29v/29vb - /9vb2//b29v/29vb/9vb2//b29v/29vb/z09Pf89PT3/PT09/9vb2//b29v/29vb/9vb2//b29v/29vb - /9vb2//b29v/PT09/z09Pf/b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/z09Pf89PT3/PT09 - /z09Pf89PT3/PT09/z09Pf89PT3/PT09/z09Pf/b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb - /9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/PT09/z09Pf89PT3/Ozs7 - /zg4OP8zMzP/Kysr/yEhIf8LCwv/CwsL/wsLC/8LCwv/CwsL/wsLC///////AAAAXAAAACIAAAAGAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAYAAAAiAAAAXP////8MDAz/DAwM/wwMDP8MDAz/DAwM/wwMDP8hISH/Kysr - /zMzM/84ODj/Ozs7/z09Pf89PT3/PT09/97e3v/e3t7/3t7e/97e3v/e3t7/3t7e/97e3v/e3t7/PT09 - /z09Pf89PT3/3t7e/97e3v/e3t7/3t7e/97e3v/e3t7/3t7e/97e3v89PT3/PT09/97e3v/e3t7/3t7e - /97e3v/e3t7/3t7e/97e3v/e3t7/PT09/z09Pf89PT3/PT09/z09Pf89PT3/PT09/z09Pf89PT3/PT09 - /97e3v/e3t7/3t7e/97e3v/e3t7/3t7e/97e3v/e3t7/3t7e/97e3v/e3t7/3t7e/97e3v/e3t7/3t7e - /97e3v/e3t7/3t7e/97e3v89PT3/PT09/z09Pf87Ozv/ODg4/zMzM/8rKyv/ISEh/wsLC/8LCwv/CwsL - /wsLC/8LCwv/CwsL//////8AAABcAAAAIgAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAACIAAABc//// - /w0NDf8NDQ3/DQ0N/w0NDf8NDQ3/DQ0N/yEhIf8sLCz/NDQ0/zk5Of88PDz/Pj4+/z4+Pv8+Pj7/4uLi - /+Li4v/i4uL/4uLi/+Li4v/i4uL/4uLi/+Li4v8+Pj7/PT09/z09Pf/i4uL/4uLi/+Li4v/i4uL/4uLi - /+Li4v/i4uL/4uLi/z09Pf89PT3/4uLi/+Li4v/i4uL/4uLi/+Li4v/i4uL/4uLi/+Li4v89PT3/PT09 - /z09Pf89PT3/PT09/z09Pf89PT3/PT09/z09Pf89PT3/4uLi/+Li4v/i4uL/4uLi/+Li4v/i4uL/4uLi - /+Li4v/FxcX/xcXF/8XFxf/i4uL/4uLi/+Li4v/i4uL/4uLi/+Li4v/i4uL/4uLi/z09Pf89PT3/PT09 - /zs7O/84ODj/MzMz/ysrK/8hISH/DAwM/wwMDP8MDAz/DAwM/wwMDP8MDAz//////wAAAFwAAAAiAAAA - BgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAIgAAAFz/////DQ0N/w0NDf8NDQ3/DQ0N/w0NDf8NDQ3/ISEh - /ywsLP80NDT/OTk5/zw8PP8+Pj7/Pj4+/z4+Pv/l5eX/5eXl/+Xl5f/l5eX/5eXl/+Xl5f/l5eX/5eXl - /z4+Pv8+Pj7/Pj4+/+Xl5f/l5eX/5eXl/+Xl5f/l5eX/5eXl/+Xl5f/l5eX/Pj4+/z4+Pv/l5eX/5eXl - /+Xl5f/l5eX/5eXl/+Xl5f/l5eX/5eXl/z4+Pv8+Pj7/Pj4+/z4+Pv8+Pj7/Pj4+/z4+Pv8+Pj7/Pj4+ - /z4+Pv/l5eX/5eXl/+Xl5f/l5eX/5eXl/+Xl5f/l5eX/5eXl/z09Pf89PT3/PT09/+Xl5f/l5eX/5eXl - /+Xl5f/l5eX/5eXl/+Xl5f/l5eX/PT09/z09Pf89PT3/Ozs7/zg4OP8zMzP/Kysr/yEhIf8NDQ3/DQ0N - /w0NDf8NDQ3/DQ0N/w0NDf//////AAAAXAAAACIAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAiAAAA - XP////8ODg7/Dg4O/w4ODv8ODg7/Dg4O/w4ODv8hISH/LCws/zQ0NP85OTn/PDw8/z4+Pv8+Pj7/Pj4+ - /+np6f/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en/Pj4+/z4+Pv8+Pj7/6enp/+np6f/p6en/6enp - /+np6f/p6en/6enp/+np6f8+Pj7/Pj4+/+np6f/p6en/6enp/+np6f/p6en/6enp/+np6f/p6en/Pj4+ - /z4+Pv8+Pj7/Pj4+/z4+Pv8+Pj7/Pj4+/z4+Pv8+Pj7/Pj4+/+np6f/p6en/6enp/+np6f/p6en/6enp - /+np6f/p6en/Pj4+/z4+Pv8+Pj7/6enp/+np6f/p6en/6enp/+np6f/p6en/6enp/+np6f8+Pj7/Pj4+ - /z4+Pv88PDz/OTk5/zQ0NP8sLCz/ISEh/w0NDf8NDQ3/DQ0N/w0NDf8NDQ3/DQ0N//////8AAABcAAAA - IgAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAACIAAABc/////w4ODv8ODg7/Dg4O/w4ODv8ODg7/Dg4O - /yIiIv8sLCz/NDQ0/zk5Of88PDz/Pj4+/z4+Pv8+Pj7/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs - /+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/z4+Pv8+Pj7/7Ozs - /+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs - /z4+Pv8+Pj7/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/+zs7P8+Pj7/Pj4+/z4+Pv/s7Oz/7Ozs - /+zs7P/s7Oz/7Ozs/+zs7P/s7Oz/7Ozs/z4+Pv8+Pj7/Pj4+/zw8PP85OTn/NDQ0/ywsLP8hISH/Dg4O - /w4ODv8ODg7/Dg4O/w4ODv8ODg7//////wAAAFwAAAAiAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAA - IgAAAFz/////Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//IiIi/y0tLf80NDT/Ojo6/z09Pf8/Pz//Pz8/ - /z8/P//w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw - //Dw8P/w8PD/8PDw//Dw8P/w8PD/Pz8//z8/P//w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw - //Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/Pj4+/z4+Pv/w8PD/8PDw//Dw8P/w8PD/8PDw - //Dw8P/w8PD/8PDw/z4+Pv8+Pj7/Pj4+//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/Pj4+ - /z4+Pv8+Pj7/PDw8/zk5Of80NDT/LCws/yEhIf8ODg7/Dg4O/w4ODv8ODg7/Dg4O/w4ODv//////AAAA - XAAAACIAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAiAAAAXP////8QEBD/EBAQ/xAQEP8QEBD/EBAQ - /xAQEP8iIiL/LS0t/zQ0NP86Ojr/PT09/z8/P/8/Pz//Pz8///Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz - //Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8/8/Pz//Pz8/ - //Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz - //Pz8/8/Pz//Pz8///Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P/Pz8//z8/P/8/Pz//8/Pz - //Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8/8/Pz//Pz8//z8/P/89PT3/Ojo6/zQ0NP8tLS3/IiIi - /w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P//////8AAABcAAAAIgAAAAYAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - BgAAACIAAABc/////xEREf8RERH/ERER/xEREf8RERH/ERER/yIiIv8tLS3/NDQ0/zo6Ov89PT3/Pz8/ - /z8/P/8/Pz//9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2 - //b29v/29vb/9vb2//b29v/29vb/9vb2/z8/P/8/Pz//9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2 - //b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2/z8/P/8/Pz//9vb2//b29v/29vb/9vb2 - //b29v/29vb/9vb2//b29v8/Pz//Pz8//z8/P//29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2 - /z8/P/8/Pz//Pz8//z09Pf86Ojr/NDQ0/y0tLf8iIiL/EBAQ/xAQEP8QEBD/EBAQ/xAQEP8QEBD///// - /wAAAFwAAAAiAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAIgAAAFz/////ERER/xEREf8RERH/ERER - /xEREf8RERH/IiIi/y0tLf81NTX/Ozs7/z4+Pv9AQED/QEBA/0BAQP/6+vr/+vr6//r6+v/6+vr/+vr6 - //r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/5+fn/Pz8/ - /z8/P//6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6 - //r6+v/6+vr/Pz8//z8/P//6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6/z8/P/8/Pz//Pz8/ - //r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/Pz8//z8/P/8/Pz//PT09/zo6Ov80NDT/LS0t - /yIiIv8RERH/ERER/xEREf8RERH/ERER/xEREf//////AAAAXAAAACIAAAAGAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAYAAAAiAAAAXP////8SEhL/EhIS/xISEv8SEhL/EhIS/xISEv8iIiL/LS0t/zU1Nf87Ozv/Pj4+ - /0BAQP9AQED/QEBA/8DAwP/AwMD/v7+//7+/v//AwMD/wMDA/8DAwP/AwMD/v7+//7+/v/+/v7//v7+/ - /8DAwP/AwMD/v7+//7+/v/+/v7//v7+//7+/v/9AQED/QEBA/7+/v/+/v7//v7+//8DAwP/AwMD/wMDA - /8DAwP+/v7//v7+//7+/v//AwMD/wMDA/8DAwP+/v7//v7+//7+/v/9AQED/QEBA/8DAwP/AwMD/v7+/ - /7+/v/+/v7//v7+//7+/v/+/v7//Pz8//z8/P/8/Pz//vr6+/76+vv+/v7//v7+//7+/v/++vr7/vr6+ - /76+vv8/Pz//Pz8//z8/P/89PT3/Ojo6/zQ0NP8tLS3/IiIi/xEREf8RERH/ERER/xEREf8RERH/ERER - //////8AAABcAAAAIgAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAACIAAABc/////xISEv8SEhL/EhIS - /xISEv8SEhL/EhIS/yIiIv8tLS3/NTU1/zs7O/8+Pj7/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA - /0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA - /0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA - /0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA - /0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/z4+Pv87Ozv/NTU1 - /y0tLf8iIiL/EhIS/xISEv8SEhL/EhIS/xISEv8SEhL//////wAAAFwAAAAiAAAABgAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAGAAAAIgAAAFz/////ExMT/xMTE/8TExP/ExMT/xMTE/8TExP/IiIi/y0tLf81NTX/Ozs7 - /z4+Pv9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA - /0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA - /0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA - /0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA - /0BAQP9AQED/QEBA/0BAQP9AQED/Pj4+/zs7O/81NTX/LS0t/yIiIv8TExP/ExMT/xMTE/8TExP/EhIS - /xISEv//////AAAAXAAAACIAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAiAAAAXP////8UFBT/FBQU - /xQUFP8UFBT/FBQU/xQUFP8jIyP/Li4u/zY2Nv88PDz/Pz8//0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB - /0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB - /0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9AQED/QEBA - /0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA - /0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP8+Pj7/Ozs7 - /zU1Nf8tLS3/IiIi/xMTE/8TExP/ExMT/xMTE/8TExP/ExMT//////8AAABcAAAAIgAAAAYAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAABgAAACIAAABc/////xUVFf8VFRX/FRUV/xUVFf8VFRX/FRUV/yMjI/8uLi7/NjY2 - /zw8PP8/Pz//QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB - /0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB - /0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB - /0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB - /0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/z8/P/88PDz/NjY2/y4uLv8iIiL/FBQU/xQUFP8UFBT/FBQU - /xQUFP8UFBT//////wAAAFwAAAAiAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAIgAAAFz/////FRUV - /xUVFf8VFRX/FRUV/xUVFf8VFRX/IyMj/y4uLv82Njb/PDw8/z8/P/9BQUH/QUFB/0FBQf9BQUH/QUFB - /0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB - /0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB - /0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB - /0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/Pz8/ - /zw8PP82Njb/Li4u/yMjI/8VFRX/FRUV/xUVFf8VFRX/FRUV/xUVFf//////AAAAXAAAACIAAAAGAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAYAAAAiAAAAXP////8WFhb/FhYW/xYWFv8WFhb/FhYW/xYWFv8jIyP/Ly8v - /zc3N/89PT3/QEBA/0JCQv9CQkL/QkJC/0JCQv9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB - /0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB - /0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9AQED/QEBA/0BAQP9AQED/Pz8/ - /z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8/ - /z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P/8+Pj7/Ozs7/zU1Nf8tLS3/IiIi/xUVFf8VFRX/FRUV - /xUVFf8VFRX/FRUV//////8AAABcAAAAIgAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAACIAAABc//// - /xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/yMjI/8vLy//Nzc3/z09Pf9AQED/QkJC/0JCQv9CQkL/QkJC - /0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC - /0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC - /0FBQf9BQUH/QEBA/0BAQP8/Pz//Pz8//z4+Pv8+Pj7/Pj4+/z09Pf89PT3/PT09/z09Pf89PT3/PT09 - /z09Pf89PT3/PT09/z09Pf89PT3/PT09/z09Pf89PT3/PT09/z09Pf89PT3/PT09/z09Pf89PT3/PT09 - /zs7O/84ODj/MzMz/ysrK/8hISH/FhYW/xYWFv8WFhb/FhYW/xYWFv8WFhb//////wAAAFwAAAAiAAAA - BgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAIgAAAFz/////FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/IyMj - /y8vL/83Nzf/PT09/0BAQP9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC - /0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC - /0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9BQUH/QEBA/z8/P/8+Pj7/PT09/zs7O/86Ojr/OTk5 - /zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4 - /zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/Nzc3/zQ0NP8uLi7/Jycn/x4eHv8XFxf/FxcX - /xcXF/8XFxf/FxcX/xcXF///////AAAAXAAAACIAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAiAAAA - XP////8YGBj/GBgY/xgYGP8YGBj/GBgY/xgYGP8jIyP/Ly8v/zc3N/89PT3/QEBA/0JCQv9CQkL/QkJC - /0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC - /0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QUFB - /0BAQP8/Pz//PT09/zs7O/84ODj/NTU1/zMzM/8yMjL/MTEx/zAwMP8wMDD/MDAw/zAwMP8wMDD/MDAw - /zAwMP8wMDD/MDAw/zAwMP8wMDD/MDAw/zAwMP8wMDD/MDAw/zAwMP8wMDD/MDAw/zAwMP8wMDD/MDAw - /zAwMP8vLy//LS0t/ygoKP8iIiL/Ghoa/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX//////8AAABbAAAA - IQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAACIAAABc/////xkZGf8ZGRn/GRkZ/xkZGf8ZGRn/GRkZ - /yQkJP8vLy//ODg4/z4+Pv9BQUH/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND - /0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND - /0NDQ/9DQ0P/QkJC/0JCQv9CQkL/QkJC/0FBQf9AQED/Pj4+/zs7O/84ODj/NDQ0/y8vL/8sLCz/KSkp - /ycnJ/8mJib/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl - /yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yQkJP8iIiL/Hh4e/xoaGv8VFRX/GBgY - /xgYGP8YGBj/GBgY/xgYGP8YGBj//////wAAAFoAAAAhAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAA - IgAAAFz/////GRkZ/xkZGf8ZGRn/GRkZ/xkZGf8ZGRn/JCQk/y8vL/84ODj/Pj4+/0FBQf9DQ0P/Q0ND - /0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND - /0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9CQkL/QUFB - /z8/P/87Ozv/Nzc3/zIyMv8sLCz/JiYm/yEhIf8ZGRn/FhYW/xYWFv8WFhb/FhYW/xYWFv8WFhb/FhYW - /xYWFv8WFhb/FhYW/xYWFv8WFhb/FhYW/xYWFv8WFhb/FhYW/xYWFv8WFhb/FhYW/xYWFv8WFhb/FhYW - /xYWFv8WFhb/FhYW/xYWFv8WFhb/FhYW/xkZGf8ZGRn/GRkZ/xkZGf8ZGRn/GRkZ/xkZGf//////AAAA - VwAAAB8AAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAiAAAAXP////8aGhr/Ghoa/xoaGv8aGhr/Ghoa - /xoaGv8kJCT/Ly8v/zg4OP8+Pj7/QUFB/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND - /0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND - /0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0JCQv9AQED/PDw8/zc3N/8wMDD/KSkp/yEhIf8aGhr/Ghoa - /xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa - /xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa - /xoaGv8ZGRn/GRkZ/xkZGf8ZGRn/GRkZ//////8AAABPAAAAGgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - BgAAACIAAABc/////xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/yQkJP8wMDD/OTk5/z8/P/9CQkL/RERE - /0RERP9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND - /0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9CQkL/QUFB - /z09Pf84ODj/MTEx/ygoKP8eHh7/Ghoa/xoaGv8aGhr/Ghoa/xkZGf8ZGRn/GRkZ/xkZGf8ZGRn/GRkZ - /xkZGf8ZGRn/GRkZ/xkZGf8ZGRn/GRkZ/xkZGf8ZGRn/GRkZ/xkZGf8ZGRn/GRkZ/xkZGf8ZGRn/GRkZ - /xkZGf8ZGRn/GRkZ/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr///// - /wAAAD8AAAATAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAIgAAAFz/////Gxsb/xsbG/8bGxv/Gxsb - /xsbG/8bGxv/JCQk/zAwMP85OTn/Pz8//0JCQv9ERET/RERE/0RERP9ERET/RERE/0RERP9ERET/RERE - /0RERP9ERET/RERE/0RERP9ERET/RERE/0RERP9ERET/RERE/0RERP9ERET/RERE/0RERP9ERET/RERE - /0RERP9ERET/RERE/0RERP9ERET/RERE/0NDQ/9AQED/PDw8/zU1Nf8sLCz/ISEh/xsbG/8bGxv/Gxsb - /ysrK/82Njb/NjY2/zY2Nv82Njb/NjY2/zY2Nv82Njb/NjY2/zY2Nv82Njb/NjY2/zY2Nv82Njb/NjY2 - /zY2Nv82Njb/NjY2/zY2Nv82Njb/NjY2/zY2Nv82Njb/NjY2/zY2Nv82Njb/NjY2/xsbG/8bGxv/Gxsb - /xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb////////////AAAAKwAAAAwAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAYAAAAiAAAAXP////8cHBz/HBwc/xwcHP8cHBz/HBwc/xwcHP8kJCT/MDAw/zk5Of8/Pz//QkJC - /0RERP9ERET/RERE/0RERP9ERET/RERE/0RERP9ERET/RERE/0RERP9ERET/RERE/0RERP9ERET/RERE - /0RERP9ERET/RERE/0RERP9ERET/RERE/0RERP9ERET/RERE/0RERP9ERET/RERE/0RERP9DQ0P/QkJC - /z8/P/85OTn/MDAw/yYmJv8cHBz/HBwc/xwcHP82Njb/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3 - /zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3 - /zY2Nv82Njb/NjY2/zY2Nv8sLCz/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG//+/v7///// - /wAAADkAAAAVAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAACIAAABc/////x0dHf8dHR3/HR0d - /x0dHf8dHR3/HR0d/yQkJP8wMDD/OTk5/z8/P/9CQkL/RERE/0RERP9ERET/RERE/0RERP9ERET/RERE - /0RERP9ERET/RERE/0RERP9ERET/RERE/0RERP9ERET/RERE/0RERP9ERET/RERE/0RERP9ERET/RERE - /0RERP9ERET/RERE/0RERP9ERET/RERE/0NDQ/9BQUH/PT09/zU1Nf8sLCz/GBgY/xwcHP8cHBz/NTU1 - /zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4 - /zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP83Nzf/Nzc3/zc3N/83Nzf/LS0t/xwcHP8cHBz/HBwc - /xwcHP8cHBz/HBwc/xwcHP8cHBz//v7+//////8AAAA+AAAAGgAAAAcAAAABAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAGAAAAIgAAAFz/////HR0d/x0dHf8dHR3/HR0d/x0dHf8dHR3/JSUl/zExMf85OTn/QEBA - /0NDQ/9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF - /0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF/0RERP9ERET/Q0ND - /0FBQf88PDz/MzMz/ygoKP8dHR3/HR0d/xYWFv85OTn/OTk5/zk5Of85OTn/OTk5/zk5Of85OTn/OTk5 - /zk5Of85OTn/OTk5/zk5Of85OTn/OTk5/zk5Of85OTn/OTk5/zk5Of84ODj/ODg4/zg4OP84ODj/ODg4 - /zg4OP84ODj/ODg4/y0tLf8dHR3/HR0d/x0dHf8dHR3/HR0d/x0dHf8dHR3/HR0d////////////AAAA - PgAAABsAAAAIAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAiAAAAXP////8eHh7/Hh4e - /x4eHv8eHh7/Hh4e/x4eHv8lJSX/MTEx/zk5Of9AQED/Q0ND/0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF - /0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF - /0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9DQ0P/QUFB/zs7O/8xMTH/JiYm/x4eHv8eHh7/Nzc3 - /zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/Ojo6 - /zo6Ov85OTn/OTk5/zk5Of85OTn/OTk5/zk5Of85OTn/OTk5/zk5Of8vLy//HR0d/x0dHf8dHR3/HR0d - /x0dHf8dHR3/HR0d/x0dHf///////////wAAAD4AAAAbAAAABwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAABgAAACIAAABc/////x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/yUlJf8xMTH/OTk5 - /0BAQP9DQ0P/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF - /0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF - /0NDQ/9AQED/Ojo6/zAwMP8eHh7/Hh4e/x4eHv87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7 - /zs7O/87Ozv/Ozs7/zs7O/86Ojr/Ojo6/zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/Ojo6 - /zo6Ov86Ojr/ICAg/x4eHv8eHh7/Hh4e/x4eHv8eHh7/Hh4e/x4eHv8eHh7///////////8AAAA+AAAA - GwAAAAcAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAIgAAAFz/////Hx8f - /x8fH/8fHx//Hx8f/x8fH/8fHx//JiYm/zIyMv86Ojr/QUFB/0RERP9GRkb/RkZG/0ZGRv9GRkb/RkZG - /0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF - /0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/Q0ND/0BAQP85OTn/Ly8v/x4eHv8fHx//Hx8f - /zw8PP88PDz/PDw8/zw8PP88PDz/PDw8/zw8PP87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7 - /zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/yEhIf8fHx//Hx8f/x8fH/8fHx//Hx8f - /x8fH/8fHx//Hx8f////////////AAAAPgAAABsAAAAIAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAYAAAAiAAAAXP////8gICD/ICAg/yAgIP8gICD/ICAg/yAgIP8mJib/MjIy - /zo6Ov9BQUH/RERE/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG - /0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG - /0ZGRv9ERET/QUFB/zo6Ov8vLy//Hx8f/yAgIP8gICD/PT09/z09Pf89PT3/PT09/z09Pf89PT3/PDw8 - /zw8PP88PDz/PDw8/zw8PP88PDz/PDw8/zw8PP88PDz/PDw8/zw8PP88PDz/PDw8/zw8PP88PDz/PDw8 - /zw8PP8hISH/Hx8f/x8fH/8fHx//Hx8f/x8fH/8fHx//Hx8f/x8fH////////////wAAAD8AAAAbAAAA - BwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAACIAAABc//// - /yEhIf8hISH/ISEh/yEhIf8hISH/ISEh/yYmJv8yMjL/Ojo6/0FBQf9ERET/RkZG/0ZGRv9GRkb/RkZG - /0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG - /0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0RERP9AQED/OTk5/y8vL/8eHh7/ICAg - /x8fH/89PT3/PT09/z09Pf89PT3/PT09/z09Pf89PT3/PT09/z09Pf89PT3/PT09/z09Pf89PT3/PT09 - /z09Pf89PT3/PT09/z09Pf89PT3/PT09/z09Pf89PT3/ISEh/yAgIP8gICD/ICAg/yAgIP8gICD/ICAg - /yAgIP8gICD///////////8AAAA/AAAAGwAAAAgAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAIgAAAFz/////ISEh/yEhIf8hISH/ISEh/yEhIf8hISH/JiYm - /zIyMv86Ojr/QUFB/0RERP9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG - /0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG - /0ZGRv9GRkb/RERE/0BAQP85OTn/Ly8v/x8fH/8hISH/ICAg/z4+Pv8+Pj7/Pj4+/z4+Pv8+Pj7/Pj4+ - /z4+Pv8+Pj7/Pj4+/z4+Pv8+Pj7/Pj4+/z4+Pv8+Pj7/Pj4+/z4+Pv8+Pj7/Pj4+/z4+Pv8+Pj7/Pj4+ - /xoaGv8hISH/ISEh/yEhIf8hISH/ISEh/yEhIf8hISH/ISEh////////////AAAAPgAAABsAAAAIAAAA - AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAiAAAA - XP////8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8mJib/MjIy/zs7O/9CQkL/RUVF/0dHR/9HR0f/R0dH - /0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH - /0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0ZGRv9GRkb/RkZG/0VFRf9ERET/QEBA/zk5Of8vLy//Hx8f - /yIiIv8hISH/Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8/ - /z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P/8YGBj/ISEh/yEhIf8hISH/ISEh/yEhIf8hISH/ISEh - /yEhIf///////////wAAAD4AAAAbAAAABwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAACIAAABc/////yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj - /yYmJv8yMjL/Ozs7/0JCQv9FRUX/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH - /0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH - /0dHR/9HR0f/RkZG/0VFRf9BQUH/Ojo6/y8vL/8gICD/IiIi/yEhIf9AQED/QEBA/0BAQP9AQED/QEBA - /0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/Ghoa - /yIiIv8iIiL/IiIi/yIiIv8iIiL/IiIi/yIiIv8iIiL//v7+//////8AAAA+AAAAGwAAAAgAAAABAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAA - IgAAAFz/////IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/JiYm/zIyMv87Ozv/QkJC/0VFRf9HR0f/R0dH - /0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH - /0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9GRkb/RUVF/0FBQf86Ojr/Ly8v - /yAgIP8jIyP/IiIi/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB - /0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/xwcHP8jIyP/IyMj/yMjI/8jIyP/IyMj/yMjI/8jIyP/IyMj - //7+/v//////AAAAPgAAABsAAAAHAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAiAAAAXP////8kJCT/JCQk/yQkJP8kJCT/JCQk - /yQkJP8nJyf/MzMz/zw8PP9DQ0P/RkZG/0hISP9ISEj/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/R0dH - /0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH - /0dHR/9HR0f/R0dH/0ZGRv9FRUX/QUFB/zo6Ov8vLy//ICAg/yQkJP8jIyP/QkJC/0JCQv9CQkL/QkJC - /0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9BQUH/QUFB/0FBQf8eHh7/JCQk - /yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP/+/v7//////wAAAD4AAAAbAAAABwAAAAEAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - BgAAACIAAABc/////yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/ycnJ/8zMzP/PDw8/0NDQ/9GRkb/SEhI - /0hISP9ISEj/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/SEhI - /0hISP9ISEj/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/R0dH/0ZGRv9CQkL/Ozs7 - /zAwMP8hISH/JSUl/yQkJP9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND - /0NDQ/9DQ0P/QkJC/0JCQv9CQkL/HBwc/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT///// - //////8AAAA+AAAAGwAAAAgAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAIgAAAFz/////JSUl/yUlJf8lJSX/JSUl - /yUlJf8lJSX/Jycn/zMzM/88PDz/Q0ND/0ZGRv9ISEj/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/SEhI - /0hISP9ISEj/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/SEhI - /0hISP9ISEj/SEhI/0hISP9HR0f/RkZG/0JCQv87Ozv/MDAw/yEhIf8lJSX/JCQk/0RERP9ERET/RERE - /0RERP9ERET/RERE/0RERP9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/x8fH/8lJSX/JSUl - /yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl////////////AAAAPwAAABsAAAAHAAAAAQAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAYAAAAiAAAAXP////8mJib/JiYm/yYmJv8mJib/JiYm/yYmJv8nJyf/MzMz/zw8PP9DQ0P/RkZG - /0hISP9ISEj/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/SEhI - /0hISP9ISEj/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/SEhI/0dHR/9GRkb/QkJC - /zs7O/8wMDD/ISEh/yYmJv8lJSX/RUVF/0VFRf9ERET/RERE/0RERP9ERET/RERE/0RERP9ERET/RERE - /0RERP9ERET/RERE/0RERP8jIyP/JSUl/yUlJf8lJSX/JSUl/yUlJf8lJSX/JSUl/yUlJf/+/v7///// - /wAAAD8AAAAcAAAACAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAACIAAABc/////ycnJ/8nJyf/Jycn - /ycnJ/8nJyf/Jycn/ycnJ/80NDT/PT09/0RERP9HR0f/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ - /0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9ISEj/SEhI/0hISP9ISEj/SEhI - /0hISP9ISEj/SEhI/0hISP9ISEj/R0dH/0ZGRv9CQkL/Ozs7/zAwMP8hISH/JiYm/yUlJf9GRkb/RUVF - /0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/IiIi/yYmJv8mJib/JiYm - /yYmJv8mJib/JiYm/yYmJv8mJib//v7+//////8AAAA+AAAAGwAAAAgAAAABAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAGAAAAIgAAAFz/////KCgo/ycnJ/8nJyf/Jycn/ycnJ/8nJyf/Jycn/zQ0NP89PT3/RERE - /0dHR/9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ - /0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9ISEj/R0dH - /0NDQ/88PDz/MTEx/yEhIf8nJyf/JiYm/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG - /0ZGRv9GRkb/RkZG/yMjI/8nJyf/Jycn/ycnJ/8nJyf/Jycn/ycnJ/8nJyf/Jycn////////////AAAA - PgAAABsAAAAHAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAiAAAAXP////8oKCj/KCgo - /ygoKP8oKCj/KCgo/ygoKP8nJyf/NDQ0/z09Pf9ERET/R0dH/0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ - /0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ - /0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0hISP9HR0f/Q0ND/zw8PP8xMTH/IiIi/ygoKP8nJyf/R0dH - /0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/8lJSX/KCgo/ygoKP8oKCj/KCgo - /ygoKP8oKCj/KCgo/ygoKP///////f39/gAAAD4AAAAbAAAACAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAABgAAACIAAABc/////ykpKf8pKSn/KSkp/ykpKf8pKSn/KSkp/ygoKP80NDT/Pj4+ - /0VFRf9ISEj/SkpK/0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK/0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ - /0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9JSUn/SEhI - /0dHR/9DQ0P/PDw8/zExMf8iIiL/KSkp/ygoKP9ISEj/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/SEhI - /0hISP9HR0f/Jycn/ygoKP8oKCj/KCgo/ygoKP8oKCj/KCgo/ygoKP8oKCj///////////8AAAA+AAAA - GwAAAAcAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAIgAAAFz/////KSkp - /ykpKf8pKSn/KSkp/ykpKf8pKSn/KCgo/zQ0NP8+Pj7/RUVF/0hISP9KSkr/SkpK/0pKSv9KSkr/SkpK - /0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK - /0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK/0pKSv9JSUn/R0dH/0RERP88PDz/MTEx/yMjI/8pKSn/KCgo - /0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9JSUn/SEhI/ykpKf8pKSn/KSkp/ykpKf8pKSn/KSkp - /ykpKf8pKSn/KSkp////////////AAAAPgAAABsAAAAHAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAYAAAAiAAAAXP////8qKir/Kioq/yoqKv8qKir/Kioq/yoqKv8oKCj/NDQ0 - /z4+Pv9FRUX/SEhI/0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK - /0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK - /0lJSf9HR0f/RERE/zw8PP8xMTH/IyMj/yoqKv8pKSn/SkpK/0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK - /0pKSv8pKSn/Kioq/yoqKv8qKir/Kioq/yoqKv8qKir/Kioq/yoqKv///////f39/gAAAD4AAAAbAAAA - CAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAACIAAABc//// - /ysrK/8rKyv/Kysr/ysrK/8rKyv/Kysr/ygoKP80NDT/Pj4+/0VFRf9ISEj/SkpK/0pKSv9KSkr/SkpK - /0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK - /0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK/0pKSv9KSkr/SUlJ/0dHR/9ERET/PDw8/zExMf8jIyP/Kioq - /ykpKf9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/KSkp/yoqKv8qKir/Kioq/yoqKv8qKir/Kioq - /yoqKv8qKir///////39/f4AAAA+AAAAGwAAAAcAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAIgAAAFz/////LCws/ywsLP8sLCz/LCws/ywsLP8sLCz/KCgo - /zU1Nf8+Pj7/RkZG/0lJSf9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL - /0tLS/9LS0v/S0tL/0tLS/9LS0v/SkpK/0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK - /0pKSv9JSUn/R0dH/0RERP88PDz/MTEx/yQkJP8rKyv/Kioq/0xMTP9MTEz/TExM/0xMTP9MTEz/S0tL - /yoqKv8rKyv/Kysr/ysrK/8rKyv/Kysr/ysrK/8rKyv/Kysr////////////AAAAPAAAABoAAAAIAAAA - AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAiAAAA - XP////8sLCz/LCws/ywsLP8sLCz/LCws/ywsLP8oKCj/NTU1/z4+Pv9GRkb/SUlJ/0tLS/9LS0v/S0tL - /0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL - /0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0pKSv9ISEj/RUVF/z09Pf8yMjL/JSUl - /ywsLP8rKyv/TU1N/01NTf9NTU3/TExM/0tLS/8sLCz/LCws/ywsLP8sLCz/LCws/ywsLP8sLCz/LCws - /ywsLP///////Pz8/QAAADkAAAAZAAAABwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAACEAAABb/////y0tLf8tLS3/LS0t/y0tLf8tLS3/LS0t - /ycnJ/80NDT/Pj4+/0VFRf9JSUn/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL - /0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL - /0tLS/9LS0v/SkpK/0hISP9FRUX/PT09/zIyMv8lJSX/LCws/ysrK/9OTk7/TU1N/01NTf9LS0v/LCws - /ywsLP8sLCz/LCws/ywsLP8sLCz/LCws/ywsLP8sLCz///////v7+/sAAAA5AAAAFwAAAAYAAAABAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAA - IQAAAFr/////LS0t/y0tLf8tLS3/LS0t/y0tLf8tLS3/JiYm/zMzM/89PT3/RUVF/0lJSf9LS0v/S0tL - /0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL - /0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9KSkr/SEhI/0VFRf89PT3/MjIy - /yUlJf8tLS3/LCws/05OTv9OTk7/TU1N/y0tLf8tLS3/LS0t/y0tLf8tLS3/LS0t/y0tLf8tLS3/LS0t - ////////////AAAAOAAAABcAAAAHAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAfAAAAWP////8uLi7/Li4u/y4uLv8uLi7/Li4u - /y4uLv8kJCT/MDAw/zo6Ov9DQ0P/SEhI/0pKSv9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL - /0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL - /0tLS/9LS0v/S0tL/0pKSv9JSUn/RUVF/z4+Pv8yMjL/JiYm/y4uLv8uLi7/T09P/05OTv8uLi7/Li4u - /y4uLv8uLi7/Li4u/y4uLv8uLi7/Li4u/y4uLv///////////wAAADgAAAAXAAAABgAAAAEAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AwAAABwAAABT/////y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/yQkJP8rKyv/NjY2/z4+Pv9ERET/RkZG - /0hISP9ISEj/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/SEhI - /0hISP9ISEj/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/SEhI/0ZGRv9CQkL/Ozs7 - /zAwMP8lJSX/Li4u/y4uLv81NTX/Li4u/y4uLv8uLi7/Li4u/y4uLv8uLi7/Li4u/y4uLv8uLi7///// - //////8AAAA5AAAAFwAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAFwAAAEn/////MDAw/zAwMP8wMDD/MDAw - /zAwMP8wMDD/LS0t/yUlJf8uLi7/Nzc3/z09Pf9AQED/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC - /0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC - /0JCQv9CQkL/QkJC/0JCQv9CQkL/QEBA/z09Pf82Njb/LCws/yQkJP8vLy//Ly8v/y8vL/8vLy//Ly8v - /y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v////////////AAAAOQAAABcAAAAGAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAEAAAARAAAAPf////9DQ0P/MDAw/zAwMP8wMDD/MDAw/zAwMP8wMDD/HR0d/yYmJv8tLS3/MzMz - /zc3N/85OTn/OTk5/zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/Ojo6 - /zo6Ov86Ojr/Ojo6/zo6Ov85OTn/OTk5/zk5Of85OTn/OTk5/zk5Of85OTn/OTk5/zk5Of83Nzf/NDQ0 - /y4uLv8lJSX/IiIi/zAwMP8wMDD/MDAw/zAwMP8wMDD/MDAw/zAwMP8wMDD/MDAw/zAwMP//////+/v7 - +gAAADkAAAAXAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAAv0dHRyvv7+/8xMTH/MTEx - /zExMf8xMTH/MTEx/zExMf8xMTH/HBwc/yMjI/8oKCj/Kysr/y0tLf8uLi7/Li4u/y4uLv8uLi7/Li4u - /y4uLv8uLi7/Li4u/y4uLv8uLi7/Li4u/y4uLv8uLi7/Li4u/y4uLv8uLi7/Li4u/y4uLv8uLi7/Li4u - /y4uLv8uLi7/Li4u/y4uLv8uLi7/Li4u/y0tLf8qKir/JSUl/x4eHv8lJSX/MDAw/zAwMP8wMDD/MDAw - /zAwMP8wMDD/MDAw/zAwMP8wMDD///////////8AAAA4AAAAGAAAAAcAAAABAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAABgAAAB8AAABT/////zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MDAw - /ykpKf8iIiL/IyMj/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk - /yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8kJCT/IyMj - /yIiIv8eHh7/JSUl/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx/zExMf8xMTH/MTEx////////////AAAA - NwAAABYAAAAGAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAEQAAADj9/f3+6enp - /zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy - /zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy - /zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy - /zIyMv8yMjL/MjIy/zIyMv///////////wAAADYAAAAWAAAABQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAIAAAAFD/////NTU1/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz - /zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz - /zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz - /zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP///////////8AAAA1AAAA - FQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAOAAAA - LmxsbIH/////NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0 - /zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz - /zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz - /zMzM/8zMzP/MzMz///////7+/v7AAAANQAAABUAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAATAAAANP//////////NTU1/zQ0NP80NDT/NDQ0 - /zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0 - /zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0 - /zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP//////29vbzgAAADQAAAAVAAAA - BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAUAAAAVAAAAMvf39/D/////4ODg/zU1Nf81NTX/NTU1/zU1Nf81NTX/NTU1/zU1Nf81NTX/NTU1 - /zU1Nf81NTX/NTU1/zU1Nf81NTX/NTU1/zU1Nf81NTX/NTU1/zU1Nf81NTX/NTU1/zU1Nf81NTX/NTU1 - /zU1Nf81NTX/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0 - /zQ0NP80NDT//////83Nzb4AAAA0AAAAFQAAAAYAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAATAAAAKAAAAEb9/f3+//// - //X19f+rq6v/NTU1/zU1Nf81NTX/NTU1/zU1Nf81NTX/NTU1/zU1Nf81NTX/NTU1/zU1Nf81NTX/NTU1 - /zU1Nf81NTX/NTU1/zU1Nf81NTX/NTU1/zU1Nf81NTX/NTU1/zU1Nf81NTX/NTU1/zU1Nf81NTX/NTU1 - /zU1Nf81NTX/NTU1/zU1Nf81NTX/NTU1/zU1Nf81NTX/ra2t///////IyMi2AAAAMgAAABUAAAAFAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAQAAAALAAAAGgAAAC4AAABD0NDQuv/////9/f3+/f39/v39/f79/f3+/f39 - /v39/f79/f3+/f39/v39/f79/f3+/f39/v39/f79/f3+/f39/v39/f79/f3+/f39/v39/f79/f3+/f39 - /v39/f79/f3+/f39/v39/f79/f3+/f39/v39/f79/f3+/f39/v39/f79/f3+/f39/v39/f79/f3+/f39 - /v39/f79/f3+AAAARAAAACoAAAATAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAFAAAA - DAAAABUAAAAfAAAAJgAAACoAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAA - LAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAA - LAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAArAAAAKAAAACEAAAAXAAAADAAAAAMAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAUAAAAHAAAACQAAAAkAAAAKAAAA - CgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAA - CgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAA - CgAAAAkAAAAIAAAABgAAAAQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - /////////////////////+AAAAAAAAAAAA/////////AAAAAAAAAAAAD////////AAAAAAAAAAAAAf// - /////gAAAAAAAAAAAAD///////wAAAAAAAAAAAAAf//////8AAAAAAAAAAAAAD//////+AAAAAAAAAAA - AAA///////gAAAAAAAAAAAAAH//////4AAAAAAAAAAAAAB//////8AAAAAAAAAAAAAAP//////AAAAAA - AAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////w - AAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA// - ////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAA - AAAP//////AAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAA - AAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////w - AAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA// - ////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAA - AAAP//////AAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAA - AAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////w - AAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA// - ////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAA - AAAP//////AAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAA - AAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////w - AAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA// - ////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAA - AAAP//////AAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAB//////8AAAAAAAAAAAAAA///////AAAAAA - AAAAAAAAf//////wAAAAAAAAAAAAAP//////8AAAAAAAAAAAAAH///////AAAAAAAAAAAAAD///////w - AAAAAAAAAAAAB///////8AAAAAAAAAAAAA////////AAAAAAAAAAAAAf///////wAAAAAAAAAAAAP/// - ////8AAAAAAAAAAAAH////////AAAAAAAAAAAAD////////wAAAAAAAAAAAB////////8AAAAAAAAAAA - A/////////AAAAAAAAAAAAf////////wAAAAAAAAAAAP////////8AAAAAAAAAAAH/////////AAAAAA - AAAAAD/////////wAAAAAAAAAAB/////////8AAAAAAAAAAA//////////AAAAAAAAAAAf/////////w - AAAAAAAAAAP/////////8AAAAAAAAAAH//////////AAAAAAAAAAD//////////wAAAAAAAAAB////// - ////8AAAAAAAAAA///////////AAAAAAAAAAf//////////wAAAAAAAAAP//////////8AAAAAAAAAH/ - //////////AAAAAAAAAD///////////wAAAAAAAAB///////////8AAAAAAAAA////////////gAAAAA - AAAf///////////4AAAAAAAAP////////////AAAAAAAAH////////////wAAAAAAAD////////////+ - AAAAAAAB/////////////wAAAAAAA//////////////AAAAAAAf/////////////8AAAAAAf//////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////8oAAAAgAAAAAABAAABAAgAAAAA - AACAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wEBAf8CAgL/AwMD/wQEBP8FBQX/BgYG/wcHB/8ICAj/CQkJ - /woKCv8LCwv/DAwM/w0NDf8ODg7/Dw8P/xAQEP8RERH/EhIS/xMTE/8UFBT/FRUV/xYWFv8XFxf/GBgY - /xkZGf8aGhr/Gxsb/xwcHP8dHR3/Hh4e/x8fH/8gICD/ISEh/yIiIv8jIyP/JCQk/yUlJf8mJib/Jycn - /ygoKP8pKSn/Kioq/ysrK/8sLCz/LS0t/y4uLv8vLy//MDAw/zExMf8yMjL/MzMz/zQ0NP81NTX/NjY2 - /zc3N/84ODj/OTk5/zo6Ov87Ozv/PDw8/z09Pf8+Pj7/Pz8//0BAQP9BQUH/QkJC/0NDQ/9ERET/RUVF - /0ZGRv9HR0f/SEhI/0lJSf9KSkr/S0tL/0xMTP9NTU3/Tk5O/09PT/9QUFD/UVFR/1JSUv9TU1P/VFRU - /1VVVf9WVlb/V1dX/1hYWP9ZWVn/Wlpa/1tbW/9cXFz/XV1d/15eXv9fX1//YGBg/2FhYf9iYmL/Y2Nj - /2RkZP9lZWX/ZmZm/2dnZ/9oaGj/aWlp/2pqav9ra2v/bGxs/21tbf9ubm7/b29v/3BwcP9ycnL/c3Nz - /3R0dP91dXX/dnZ2/3d3d/94eHj/eXl5/3p6ev97e3v/fHx8/319ff9+fn7/f39//4CAgP+BgYH/goKC - /4SEhP+FhYX/hoaG/4eHh/+IiIj/iYmJ/4qKiv+Li4v/jIyM/42Njf+Ojo7/j4+P/5CQkP+RkZH/kpKS - /5OTk/+UlJT/lZWV/5aWlv+Xl5f/mJiY/5mZmf+ampr/m5ub/5ycnP+dnZ3/np6e/5+fn/+goKD/oaGh - /6Kiov+jo6P/pKSk/6Wlpf+mpqb/p6en/6ioqP+pqan/qqqq/6urq/+srKz/ra2t/66urv+vr6//sLCw - /7Gxsf+ysrL/s7Oz/7S0tP+1tbX/tra2/7e3t/+4uLj/ubm5/7q6uv+7u7v/vLy8/729vf++vr7/v7+/ - /8DAwP/BwcH/wsLC/8PDw//ExMT/xcXF/8bGxv/Hx8f/yMjI/8nJyf/Kysr/y8vL/8zMzP/Nzc3/zs7O - /8/Pz//Q0ND/0dHR/9LS0v/T09P/1NTU/9XV1f/W1tb/19fX/9jY2P/Z2dn/2tra/9vb2//c3Nz/3d3d - /97e3v/f39//4eHh/+Li4v/j4+P/5OTk/+Xl5f/m5ub/5+fn/+jo6P/p6en/6urq/+vr6//s7Oz/7e3t - /+7u7v/v7+//8PDw//Hx8f/y8vL/8/Pz//T09P/39/f/+Pj4//r6+v/7+/v//Pz8//////8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAARqfP1dTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU - 1NTU1NTU1NTU1NTU1NTU1NTU1NTV2cihPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAOsj2xoBkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRk - ZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRniMf2zlgBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAH/xuDcBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATen9bAKAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACX9HYGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABG5NYZAQEAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAefRVAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa - zd0aAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACLwfgAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAQ1sQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAuMoEAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAYp8nYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - ABr0RAAAAAAAAAAGCxEXEhcSFxIXEhcSFxIXEhcSFxIXEhcSFxIXEhcSFxIXEhcSFxIXEhcSFxIXEhcS - FxEUFBcSFxIXEhcSFxIXDwsEAAAAAAAAAACG5QEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAjtoEAAAAAAAAER8kKCcpKCooKigqKConKCkqKCooKigqKCooKigqKCooKigqKCooKigq - KCooKigqKCopKSkoKigqKCooKigpJicmJCAQBgAAAAAAABDsbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAADNhQAAAAAAAAwhJiovKi8qMCowKjAqMCovMC8qMCowKjAqMCowKjAqMCow - KjAqMCowKjAqMCowKjAqMCowKiovKjAqMCowKjApLywqJyUYAAAAAAAAAKW4BgAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOdSAAAAAAAEGigpKjAxMS8vMTExMTEyNCovMTExMTIyLy8w - LzExMTExMTExMTExMDExMTExMTEwLzExMTExNzAxMTExMTEyMjAvMTEsKCEXAAAAAAABWeMAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO9B8AAAAAAAogJyk2MTA3OkdAQUFBQUFBOjcw - MjlBQUE6NzQ3OEFBQUFBQUFBQTc6REFBQUFBQTk3MkFBQUEyOkRBQUFBQUFBOjcxMSosKCAGAAAAAAAf - 8w0BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABb3HwAAAAAADyQpKi83NzaWpaek - paWmpqZ5NzcyZqekp3k0NDRmpaanpKWlpqenOoaopqSlpaWmaDQ3pqakpjqCpqekpaWmp6aINzcwNyop - IQ0AAAAAASH2FgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFvcfAAAAAAAQJCkx - NzExNJeorqiura2qp4U0MjdmqqeugDIxMWmqqqqnra2tqqg/iK6oqK6qra2ceTqqqKitOoavraiuqq2t - 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 - 9hcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABf3KAsLCwwNHCo0Ojw6PEDH1tbW - 1tbW18XDyNbW1tbW1ta6OknV1tbW1tbW0kc6QDpAOjo/PD+41tbW1tbW1tbW1tbYl1hYWFlWPD86ODg0 - LBoKCgoKCij2FwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF/YpDAsLCwsaKjY4 - OkA6Qc7a2dnZ2dnZVTpk2NnZ2dnZ2bo8S9jZ2dnZ2dnVQDo/Oj86Pzw6QMLZ2dnZ2dnZ2dnZ2dnZ2dnZ - 2cM6Pzo6PDQqGg4LCwsLKPcXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX9ikM - DAwMDxoqNjo6QDo6zdvb29vb29tRPGfb3dvb29vbvTpK2t3b29vb3NxBPz8/Pz9AOj88w9vb29vb29vd - 3d3b29vb29zcxkBAOjo4MikcCwsLCwwp9hcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAABf2LA4NDQ0NGik3Nzo6OkbV4eHh4eHh4VU8Z+Te4eHh4eHCPEzc3uHh4eHh3Do6Ojo6Ojo6QTrH - 4eHh4eHh4aaWo+Hh4eHh4eHHPzo6Pzo3KhwMDAwMDCn2FwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAF/YqDQ0NDg8aLDQ6OkY6QNbj4+Pj4+PjWDpn4+Pj4+Pj48Q6SuTj4+Pj4+PcRjpG - OkY6RjpBP8fj4+Pj4+PkYjxc4+Th4+Pj480/Pzo6OjIqHA0NDQ0OLPYXAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAX9iwODg4ODBovNzo6QDpE2ubl5+bn5uZVOmrl5+bn5ufmxz9K5Ofl - 5+bn5uRHOkA6QDpAOkA6x+bn5ufm5+ZnOl/m5+fn5+bnzjw6QDo8NykgDg0NDQ0q9hcAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABf3Kg8PDg4XGiw2OjpAOkDc7Ofs5+zn59XN1ufs5+zn - 7efIQUvl7Ofs5+zn6c3Nzc3Nzc3GQTzU5+zn7Ofs52Y6X+fn7Ofs5+nVRj9AOjg3KRwODg4ODiz2FwAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF/YpEQ8PDw8aKjk6P0A/Qd7t7e3t7e3t - 7e3t7e3t7e3t7cc/S+fv7e3t7e3t7e3t7e3t7eNHOtXu7e3t7e3tZzpg7e3t7e3t7dU/Ojo8OjQsGhAO - Dg4OKvcXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX9ywOEBAREh8pNjo8Pz9B - 4fDw8PDw8PDw8PDw8PDw8PDv1T9M7PDw8PDw8PDw8PDw8PDx50c61PDw8PDw8PBmP1/w8PDw8PDw2EA/ - Rjo5NywcDQ8PDxEp9hcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABf3LBcRERER - Gi83OTpBQEDj8vLy8vLy8vLy8vLy8vLy8vLOOkzy8/Ly8vLy8vLy8vLy8vLsRjrZ8vLy8vLy8mc/X/Ly - 8vLy8vLbQD8/Ojo3LB8XEBAQDiz3FwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - FPcqEREREhQgLDc6Pzo/Ruf09PT09PT09PT09PT09PT09NVATPL09PT09PT09PT09PT09OxGP9r09PT0 - 9PT0Zz9g9PT09PT09N1BQUA8PDkqGhERERIXKfYXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAX9i8SEhISEBoqOjw/R0BBnqenp6enp6enp6enp6enp6enlD9Ipaenp6enp6enp6enp6en - okc/laenp6enp6dWP1Knp6anp6aml0A/Ojo/NikgEREREQ8p9xcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAABf3LxISEhIXICk4OjpAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA - QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEFHOjw4LB8SERARFy/2FwAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF/YxEhIREhEaMDY8P0BAQEBAQEBAQEBAQEBAQEBAQEBAQEBA - QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEA6OjkpIhYUFxISL/YXAAAAAAAA - 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 - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF/c5IRohGhokMTpAQEdGR0ZBRkFGQUZBRkFGR0ZHRkdGR0ZH - RkdGR0FBRjg3KRoaJDo6Ojk5ODg6ODo6OTg3OTk6Ojc6NzY4ODk6KRogGiAaGho01+EkAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX9jofGiAaICQxOEBHREZBR0ZGRkZGRkZGRkZE - R0FGQUZBRkFGQUZBRkZAOjclGiIwOTo8Ojo6Ojo6PDw6Ojo6Ojw6Ojo6Ojo5OSkfGiEaIRohN9bhJQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABf2Oh8fHx8fJDI6Oj9GR0dHR0dH - R0dHR0dHR0RGRkZGRkZGRkZGRkZGQUA6MSQaHzo6Ojw8Ojw/Ojo6PDk6PDo6Ojo6Ojo8OjkqGiAaIBog - GjjX4SYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF/Y5ICAfHx8lMDhG - RkdHRkZGRkZGRkZGRkZGRkdHR0dHR0dHR0dHR0dHPzkwIh8fOTo/Ojo6Pzw6Oj86Ojw8PDo6Ojo6Ojo6 - KSAfHx8fHx841+ElAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX9zog - ICAgICQ3Oj9GRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkRAOjAgISY6QEA6QDpAOkA6OjxBOjxB - OkA6PD86PCofICAgICAgONjhJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAABf3OiIiISEhJTA6QUZERkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGREA5LyUgJzpBOjpBOkE6 - QTpBOkE6OkA6Ojo6QTosICAgICAgIDjZ4SQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAFPc6ISEhISElNzk/RkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZEPzkvISIp - OjxAOkA6QDpAOkA6P0E6P0E6Rzo8KCEhISEhISE52eElAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAX9zoiICIiIiYwOkFGRkdHR0dHR0dHR0dHR0dHR0dHR0dHR0dHRkZG - REY6PDAlIig/Rj8/Pz8/Pz8/Pz8/PzpAPzo/OikiISEhHyEhONfhJgAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABT3PCUlISEhJjc5RkdHR0dHR0dHR0dHR0dHR0dHR0dH - R0dHR0dHR0dHR0E6MCQhKTpAQEBAQEBAQEBAQEBARj9ARjopICAgICElITzY4SUAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF/c6KCUlJSUmMDpBREdHR0dHR0dHR0dH - R0dHR0dHR0dHR0dHR0dHR0ZHQTowJCUqRj9AQUFBQUFBQT9AQUE/OkY6KSQlJSUlJSI62+EkAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU9zokJCQkJCY3PEdGR0hI - SEhISEhISEhISEdHR0dHR0dHR0dHR0dHR0Q/OjAkJSk/RkE/P0BBQEE/RkFAQUZHPyokJCQkJCImOtjh - JAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABf2QCUlJSUl - JzE6REdISEhISEhISEhISEhISEhISEhISEhISEhISEhHREY4MSYlLEZAQEZGRkBGQEZAQEY/QUEpJSQk - JCQkJT/a4SUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - F/c/JSUlJSUmNzpBRkhISEhISEhISEhISEhISEhISEhISEhISEhISEdHQTowJigpR0dGQUFBR0FGQEZG - QEdAKiUlJSUlJSc63eElAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAX9kEnJiYmJic3OkdHSEhISEhISEhISEhISEhISEhISEhISEhISEhIR0ZGOjAmJilJRkdH - R0ZBRkFGQURGPyomJiYmJiYlP9zhJQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAARf2PycnJycnKTc6REdJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSEhISEhIRkE5 - MSYoKkZGRkZHR0dHR0dHREYqJiYmJiYmJkHc4SUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF/ZHKCgoKCgoNDpHSElJSUlJSUlJSUlJSUlJSUlJSUlJSUlJ - SUlJSUhHRzoyJicvRkZGRkZGRkZGRkRBLCgnJycnJyVB4eEkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU9kAoKCgoKCk3OkRHSUlJSUlJSUlJSUlJSUlJ - SUlJSUlJSUlJSUlJSEhEOjEnKDBHR0dHR0dHR0ZERikoKCgoKCgoR+HhJAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABf2RigqKikpKTQ6RklJSkpKSkpK - SUlJSUlJSUlJSUlJSUlJSUlJSUlIR0E6MicpMUhISEhISEhISEYoKSkoKCgoJkTh4SUAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF/ZHKSooKSkqNzpH - SEpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSklHRzowKCgvSUlJSUlJSUlELCkpKCkpKSlH5OEmAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX9kYq - KSksLCo0OkZJSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSUhGOjcnKTdKSUpMS0pKRikpLykpKios - SOHhJQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAARf2RyopLyksKTc6R0hKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpJRkY8MSopNEtLS0tKTEcp - KSksLCwpKUjh5CUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAF/ZHLCovKSopNzpKSktLS0tLS0tLS0tLS0tLS0tKSkpKSkpKSkpKSkpIRjo3KCk4 - S0xMTExGKSosLCopKipR59omAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAEY9kopLC8pLCo3OkRJS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tL - SklHOjQpKTRPTEtLRCkvLykpLyksVufVDQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABb2SCoqMSkwLDc/R0dLS0tLS0tLS0tLS0tLS0tLS0tL - S0tLS0tLS0tKSUc6NiosN0xMTEcpLywqKi8vKVjs1g4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGPZIMSkxKikqNDpHSUtLTExMS0tLS0tL - S0tLS0tLS0tLS0tLS0tLS0pJRzo0Ki80TExGMSkxKTEqKi9Z59UOAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW9kkvKjAqMCkxOkdHSEtJ - SUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlLSklHPDQpLypVRzAvKjAqMCkyWufXDAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARr2SC8vLzAw - KCw5OkdHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0ZJR0Q6MSkxKjoqLy8vMDIyKlXs1A0AAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - BPFYMDAwMDApJzA3P0ZBR0ZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkFBOjkpKTAvLy8vLy8vLypZ8dcN - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAEB24IwMDAwMDAkJyo2OTk8Ojw6PDo8Ojw6PDo8Ojw6PDo8Ojw6PDo8OTg2MSYnMDAwMDAw - MDAxWe7UBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAC4wjIxMTExMS8lJSgpKjAqMCowKjAqMCowKjAqMCowKjAqMCowKjAqLyol - GigwMDAwMDAwL1zx1QoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABlr0RzAyMjIxMTEsKigoKSkpKSkpKSkpKSkpKSkpKSkpKSkp - KSkpKSgoJyUlMDExMTEyMjJZ8ccBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeSnNzQxMTAxMDEwMTAxMDEwMTAxMDEwMTIy - MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjAxWfHPAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABf/ZqMjcwNzI3MjcyNzI3Mjcy - NzI3MjcyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyN1/xxwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAuO1YNjc0NDQ0 - NDQ0NDQ0NDQ0NDQ0NDQ3MjcyNzI3MjcyNzI3MjcyNzI3MjcyNzJh8MoBAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH - 2+dvNDQyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjQ0NDQ0YvDCBgAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAGx/awVzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3NDQ0NGLuxAEAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAiOf0xJeCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKe - 8M4OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITV4+Xl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl - 5eXl5eXl5uSwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - ////////////////4AAAAAAAAAAAD////////8AAAAAAAAAAAAP///////8AAAAAAAAAAAAB///////+ - AAAAAAAAAAAAAP///////AAAAAAAAAAAAAB///////wAAAAAAAAAAAAAP//////4AAAAAAAAAAAAAD// - ////+AAAAAAAAAAAAAAf//////gAAAAAAAAAAAAAH//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAA - AAAP//////AAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAA - AAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////w - AAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA// - ////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAA - AAAP//////AAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAA - AAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////w - AAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA// - ////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAA - AAAP//////AAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAA - AAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////w - AAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA// - ////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAA - AAAP//////AAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAA - AAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////w - AAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA// - ////8AAAAAAAAAAAAAAP//////AAAAAAAAAAAAAAH//////wAAAAAAAAAAAAAD//////8AAAAAAAAAAA - AAB///////AAAAAAAAAAAAAA///////wAAAAAAAAAAAAAf//////8AAAAAAAAAAAAAP///////AAAAAA - AAAAAAAH///////wAAAAAAAAAAAAD///////8AAAAAAAAAAAAB////////AAAAAAAAAAAAA////////w - AAAAAAAAAAAAf///////8AAAAAAAAAAAAP////////AAAAAAAAAAAAH////////wAAAAAAAAAAAD//// - ////8AAAAAAAAAAAB/////////AAAAAAAAAAAA/////////wAAAAAAAAAAAf////////8AAAAAAAAAAA - P/////////AAAAAAAAAAAH/////////wAAAAAAAAAAD/////////8AAAAAAAAAAB//////////AAAAAA - AAAAA//////////wAAAAAAAAAAf/////////8AAAAAAAAAAP//////////AAAAAAAAAAH//////////w - AAAAAAAAAD//////////8AAAAAAAAAB///////////AAAAAAAAAA///////////wAAAAAAAAAf////// - ////8AAAAAAAAAP///////////AAAAAAAAAH///////////wAAAAAAAAD///////////+AAAAAAAAB// - //////////gAAAAAAAA////////////8AAAAAAAAf////////////AAAAAAAAP////////////4AAAAA - AAH/////////////AAAAAAAD/////////////8AAAAAAB//////////////wAAAAAB////////////// - //////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////ygAAABAAAAAgAAAAAEAIAAAAAAAAIAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAIAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAA - AwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAA - AwAAAAMAAAADAAAAAwAAAAMAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAABgAAAB8AAAA8AAAASQAAAEoAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAA - SwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEsAAABLAAAA - SwAAAEsAAABLAAAASwAAAEsAAABLAAAASwAAAEoAAABKAAAAQwAAAC4AAAASAAAAAgAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAEtJSUmm//////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////////AAAA - dQAAADEAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAFj/////AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/zIyMv//////AAAAPgAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAADv/////AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA//////8AAAAsAAAAAQAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAA8AAAB3AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8RERH/AAAA - awAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAj/////wAAAP8AAAD/AAAA/xcXF/8kJCT/KSkp/yoqKv8qKir/Kioq - /yoqKv8qKir/Kioq/yoqKv8qKir/Kioq/yoqKv8qKir/Kioq/yoqKv8qKir/Kioq/yoqKv8qKir/Kioq - /yoqKv8qKir/Kioq/yoqKv8qKir/Kioq/yoqKv8qKir/Kioq/yoqKv8qKir/Kioq/ygoKP8hISH/AAAA - /wAAAP8AAAD/AAAA//7+/v8AAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANP////8AAAD/AAAA/wAAAP8jIyP/Li4u - /zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy - /zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy - /zIyMv8xMTH/LCws/yEhIf8AAAD/AAAA/wAAAP//////AAAAMgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADr/////AAAA - /wAAAP8AAAD/Jycn/zExMf80NDT/NDQ0/6qqqv+qqqr/qqqq/6qqqv80NDT/NDQ0/6qqqv+qqqr/NDQ0 - /zQ0NP+qqqr/qqqq/6qqqv+qqqr/qqqq/zQ0NP+qqqr/qqqq/6qqqv+qqqr/NDQ0/6qqqv+qqqr/NDQ0 - /6qqqv+qqqr/qqqq/6qqqv80NDT/NDQ0/zExMf8nJyf/AAAA/wAAAP8AAAD//////wAAADkAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAEAAAA7/////wAAAP8AAAD/AAAA/ykpKf8yMjL/NTU1/zU1Nf81NTX/NTU1/7e3t/+3t7f/NTU1 - /zU1Nf+3t7f/t7e3/zU1Nf81NTX/t7e3/7e3t/81NTX/t7e3/7e3t/81NTX/t7e3/7e3t/+3t7f/t7e3 - /zU1Nf+3t7f/t7e3/zU1Nf+3t7f/t7e3/7e3t/+3t7f/NDQ0/zQ0NP8xMTH/KCgo/wAAAP8AAAD/AAAA - //////8AAAA7AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAO/////8AAAD/AAAA/wAAAP8qKir/MzMz/zY2Nv82Njb/NTU1 - /zU1Nf/FxcX/xcXF/zU1Nf81NTX/xcXF/8XFxf81NTX/NTU1/8XFxf/FxcX/NTU1/8XFxf/FxcX/NTU1 - /8XFxf/FxcX/xcXF/8XFxf81NTX/xcXF/8XFxf81NTX/xcXF/8XFxf/FxcX/xcXF/zU1Nf81NTX/MjIy - /ykpKf8AAAD/AAAA/wAAAP//////AAAAOwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAADv/////AAAA/wAAAP8AAAD/Kioq - /zMzM/82Njb/NjY2/9PT0//T09P/09PT/9PT0/82Njb/NjY2/9PT0//T09P/NjY2/zY2Nv/T09P/09PT - /zY2Nv/T09P/09PT/zY2Nv/T09P/09PT/9PT0//T09P/NjY2/9PT0//T09P/NjY2/9PT0//T09P/09PT - /9PT0/82Njb/NjY2/zMzM/8qKir/AAAA/wAAAP8AAAD//////wAAADsAAAABAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAA7//// - /wAAAP8AAAD/AAAA/ysrK/80NDT/Nzc3/zc3N//g4OD/4ODg/zc3N/83Nzf/NjY2/zY2Nv/g4OD/4ODg - /zY2Nv82Njb/4ODg/+Dg4P82Njb/4ODg/+Dg4P82Njb/4ODg/+Dg4P/g4OD/4ODg/zY2Nv/g4OD/4ODg - /zY2Nv/g4OD/4ODg/+Dg4P/g4OD/NjY2/zY2Nv8zMzP/Kioq/wAAAP8AAAD/AAAA//////8AAAA7AAAA - AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAABAAAAO/////8AAAD/AAAA/wAAAP8rKyv/NDQ0/zc3N/83Nzf/7e3t/+3t7f/t7e3/7e3t - /zc3N//t7e3/7e3t/+3t7f/t7e3/7e3t/+3t7f/t7e3/Nzc3/+3t7f/t7e3/Nzc3/+3t7f/t7e3/7e3t - /+3t7f83Nzf/7e3t/+3t7f83Nzf/7e3t/+3t7f/t7e3/7e3t/zc3N/83Nzf/NDQ0/ysrK/8AAAD/AAAA - /wAAAP//////AAAAOwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAADv/////AAAA/wAAAP8AAAD/LCws/zU1Nf84ODj/ODg4 - //r6+v/6+vr/+vr6//r6+v84ODj/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+vr6/zg4OP/6+vr/+vr6 - /zg4OP/6+vr/+vr6//r6+v/6+vr/Nzc3//r6+v/6+vr/Nzc3//r6+v/6+vr/+vr6//r6+v83Nzf/Nzc3 - /zQ0NP8rKyv/AAAA/wAAAP8AAAD//////wAAADsAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAA7/////wAAAP8AAAD/AAAA - /ywsLP81NTX/ODg4/01NTf+jo6P/o6Oj/6Ojo/+ZmZn/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/o6Oj - /6Ojo/+jo6P/o6Oj/6Ojo/+jo6P/o6Oj/6Ojo/84ODj/o6Oj/6Ojo/+jo6P/o6Oj/zg4OP+fn5//o6Oj - /6Ojo/+jo6P/RUVF/zg4OP81NTX/LCws/wAAAP8AAAD/AAAA//////8AAAA7AAAAAQAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA - O/////8CAgL/AQEB/wEBAf8sLCz/NjY2/zk5Of9RUVH/qamp/6mpqf+pqan/oKCg/zk5Of85OTn/OTk5 - /zk5Of85OTn/OTk5/6mpqf+pqan/qamp/6mpqf+pqan/qamp/6mpqf+pqan/OTk5/6mpqf+pqan/qamp - /6mpqf84ODj/pqam/6mpqf+pqan/qamp/0ZGRv84ODj/NTU1/ywsLP8BAQH/AQEB/wEBAf//////AAAA - OwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAQAAADv/////AwMD/wMDA/8DAwP/LCws/zY2Nv85OTn/UlJS/7CwsP+wsLD/sLCw - /6Wlpf85OTn/OTk5/zk5Of85OTn/OTk5/zk5Of+wsLD/sLCw/7CwsP+wsLD/sLCw/7CwsP+wsLD/sLCw - /zk5Of+wsLD/sLCw/7CwsP+wsLD/OTk5/6ysrP+wsLD/sLCw/7CwsP9ISEj/OTk5/zY2Nv8sLCz/AgIC - /wICAv8CAgL//////wAAADsAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAA7/////wQEBP8EBAT/BAQE/y0tLf83Nzf/Ojo6 - /1NTU/+3t7f/t7e3/7e3t/+rq6v/Ojo6/zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/t7e3/7e3t/+3t7f/t7e3 - /zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/t7e3/7e3t/+3t7f/t7e3/zo6Ov+ysrL/t7e3/7e3t/+3t7f/SUlJ - /zo6Ov83Nzf/LS0t/wMDA/8DAwP/AwMD//////8AAAA7AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAO/////8GBgb/BgYG - /wYGBv8uLi7/ODg4/zs7O/9VVVX/vr6+/76+vv++vr7/sbGx/zo6Ov86Ojr/Ojo6/zo6Ov86Ojr/Ojo6 - /76+vv++vr7/vr6+/76+vv86Ojr/Ojo6/zo6Ov86Ojr/Ojo6/76+vv++vr7/vr6+/76+vv+/v7//vr6+ - /76+vv++vr7/vr6+/0lJSf86Ojr/Nzc3/y0tLf8FBQX/BQUF/wUFBf//////AAAAOwAAAAEAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AQAAADv/////BwcH/wcHB/8HBwf/Li4u/zg4OP87Ozv/VlZW/8XFxf/FxcX/xcXF/7e3t/87Ozv/Ozs7 - /zs7O/87Ozv/Ozs7/zs7O//FxcX/xcXF/8XFxf/FxcX/Ozs7/zs7O/87Ozv/Ozs7/zs7O//FxcX/xcXF - /8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf9KSkr/Ozs7/zg4OP8uLi7/BgYG/wYGBv8GBgb///// - /wAAADsAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAEAAAA7/////wgICP8ICAj/CAgI/y8vL/85OTn/PDw8/1hYWP/MzMz/zMzM - /8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP88PDz/zMzM/8zMzP/MzMz/zMzM/zw8PP87Ozv/Ozs7 - /zs7O/87Ozv/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/SkpK/zs7O/84ODj/Li4u - /wcHB/8HBwf/BwcH//////8AAAA7AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAO/////8KCgr/CgoK/woKCv8vLy//OTk5 - /zw8PP9YWFj/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/PDw8/9LS0v/S0tL/0tLS - /9LS0v88PDz/PDw8/zw8PP88PDz/PDw8/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v88PDz/PDw8 - /zw8PP88PDz/OTk5/y8vL/8JCQn/CQkJ/wkJCf//////AAAAOwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAADv/////CwsL - /wsLC/8LCwv/MDAw/zo6Ov89PT3/WVlZ/9nZ2f/Z2dn/2dnZ/8vLy/9PT0//2dnZ/9nZ2f/Z2dn/2dnZ - /z09Pf/Z2dn/2dnZ/9nZ2f/Z2dn/PT09/z09Pf89PT3/PT09/z09Pf/Z2dn/2dnZ/9nZ2f/Z2dn/2dnZ - /9nZ2f/Z2dn/09PT/9PT0/9KSkr/PDw8/zk5Of8vLy//CgoK/woKCv8KCgr//////wAAADsAAAABAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAEAAAA7/////wwMDP8MDAz/DAwM/zAwMP86Ojr/PT09/1paWv/g4OD/4ODg/+Dg4P/Nzc3/PT09 - /+Dg4P/g4OD/4ODg/+Dg4P89PT3/4ODg/+Dg4P/g4OD/4ODg/z09Pf89PT3/PT09/z09Pf89PT3/4ODg - /+Dg4P/g4OD/4ODg/+Dg4P/g4OD/4ODg/+Dg4P/g4OD/TU1N/z09Pf86Ojr/MDAw/wwMDP8MDAz/CwsL - //////8AAAA7AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAO/////8ODg7/Dg4O/w4ODv8wMDD/Ozs7/z4+Pv9cXFz/5+fn - /+fn5//n5+f/1NTU/z4+Pv/n5+f/5+fn/+fn5//n5+f/Pj4+/+fn5//n5+f/5+fn/+fn5/8+Pj7/Pj4+ - /z4+Pv8+Pj7/Pj4+/+fn5//n5+f/5+fn/+fn5/8+Pj7/39/f/+fn5//n5+f/5+fn/05OTv8+Pj7/Ozs7 - /zAwMP8NDQ3/DQ0N/w0NDf//////AAAAOwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAADv/////Dw8P/w8PD/8PDw//MTEx - /zw8PP8/Pz//XV1d/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/z4+Pv/u7u7/7u7u - /+7u7v/u7u7/7u7u/+7u7v/u7u7/7u7u/z4+Pv/u7u7/7u7u/+7u7v/u7u7/Pj4+/+bm5v/u7u7/7u7u - /+7u7v9OTk7/Pj4+/zs7O/8wMDD/Dg4O/w4ODv8ODg7//////wAAADsAAAABAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAA7//// - /xAQEP8QEBD/EBAQ/zExMf88PDz/Pz8//11dXf/19fX/9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1 - //X19f8/Pz//9fX1//X19f/19fX/9fX1//X19f/19fX/9fX1//X19f8/Pz//9fX1//X19f/19fX/9fX1 - /z8/P//s7Oz/9fX1//X19f/19fX/UFBQ/z8/P/88PDz/MTEx/xAQEP8QEBD/EBAQ//////8AAAA7AAAA - AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAABAAAAO/////8SEhL/EhIS/xISEv8yMjL/PT09/0BAQP9eXl7//Pz8//z8/P/8/Pz//Pz8 - //z8/P/8/Pz//Pz8//z8/P/8/Pz/QEBA//z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P/8/Pz/Pz8/ - //z8/P/8/Pz//Pz8//z8/P8/Pz//8/Pz//z8/P/8/Pz//Pz8/1BQUP8/Pz//PDw8/zExMf8RERH/ERER - /xEREf//////AAAAOwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAADv/////ExMT/xMTE/8TExP/MjIy/z09Pf9AQED/QEBA - /0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA - /0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA - /z09Pf8yMjL/EhIS/xISEv8SEhL//////wAAADsAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAA7/////xQUFP8UFBT/FBQU - /zMzM/8+Pj7/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB - /0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QEBA/0BAQP9AQED/QEBA - /0BAQP9AQED/QEBA/0BAQP89PT3/MjIy/xQUFP8UFBT/FBQU//////8AAAA7AAAAAQAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA - O/////8WFhb/FhYW/xYWFv8zMzP/Pj4+/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB - /0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QEBA/0BAQP9AQED/QEBA - /0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/Pj4+/zMzM/8VFRX/FRUV/xUVFf//////AAAA - OwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAQAAADv/////FxcX/xcXF/8XFxf/NDQ0/z8/P/9CQkL/QkJC/0JCQv9CQkL/QkJC - /0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0FBQf8/Pz//PT09 - /zw8PP87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zg4OP8uLi7/FhYW - /xYWFv8WFhb//////wAAADsAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAA7/////xgYGP8YGBj/GBgY/zQ0NP9AQED/Q0ND - /0NDQ/9DQ0P/Q0ND/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC - /0BAQP88PDz/NjY2/y8vL/8sLCz/Kysr/ysrK/8rKyv/Kysr/ysrK/8rKyv/Kysr/ysrK/8rKyv/Kysr - /ysrK/8pKSn/ISEh/xgYGP8YGBj/GBgY//////8AAAA6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAO/////8aGhr/Ghoa - /xoaGv80NDT/QEBA/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND - /0NDQ/9DQ0P/Q0ND/0FBQf88PDz/MTEx/yQkJP8ZGRn/GRkZ/xkZGf8ZGRn/GRkZ/xkZGf8ZGRn/GRkZ - /xkZGf8ZGRn/GRkZ/xkZGf8ZGRn/GRkZ/xkZGf8ZGRn/GRkZ/xkZGf//////AAAANAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AQAAADv/////Gxsb/xsbG/8bGxv/NTU1/0FBQf9ERET/RERE/0RERP9ERET/RERE/0RERP9ERET/RERE - /0RERP9ERET/RERE/0NDQ/9DQ0P/Q0ND/0JCQv8+Pj7/MjIy/x8fH/8bGxv/GBgY/zY2Nv82Njb/NjY2 - /zY2Nv82Njb/NjY2/zY2Nv81NTX/NTU1/zU1Nf81NTX/NTU1/xwcHP8aGhr/Ghoa/xoaGv8aGhr///// - /wAAAB4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAEAAAA7/////xwcHP8cHBz/HBwc/zU1Nf9BQUH/RERE/0RERP9ERET/RERE - /0RERP9ERET/RERE/0RERP9ERET/RERE/0RERP9ERET/RERE/0RERP9CQkL/Ozs7/ykpKf8cHBz/Nzc3 - /zg4OP84ODj/ODg4/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N/8cHBz/HBwc - /xwcHP8cHBz//v7+/wAAADwAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAO/////8eHh7/Hh4e/x4eHv82Njb/QkJC - /0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/QkJC - /zc3N/8ZGRn/HR0d/zo6Ov85OTn/OTk5/zk5Of85OTn/OTk5/zk5Of85OTn/OTk5/zk5Of85OTn/OTk5 - /zk5Of8dHR3/HR0d/x0dHf8dHR3//////wAAAD8AAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAADv/////Hx8f - /x8fH/8fHx//NjY2/0JCQv9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF - /0VFRf9FRUX/RUVF/0JCQv81NTX/Hx8f/ykpKf87Ozv/Ozs7/zs7O/87Ozv/Ozs7/zs7O/87Ozv/Ozs7 - /zs7O/87Ozv/Ozs7/zo6Ov8eHh7/Hh4e/x4eHv8eHh7//v7+/wAAAD4AAAAIAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAEAAAA7/////yAgIP8gICD/ICAg/zc3N/9DQ0P/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG - /0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9CQkL/NTU1/yAgIP86Ojr/PT09/z09Pf89PT3/PT09 - /z09Pf89PT3/PT09/z09Pf89PT3/PT09/zw8PP8gICD/ICAg/yAgIP8gICD//v7+/wAAAD4AAAAHAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAO/////8iIiL/IiIi/yIiIv84ODj/RERE/0dHR/9HR0f/RkZG - /0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/QkJC/zU1Nf8hISH/Pz8/ - /z8/P/8/Pz//Pz8//z8/P/8/Pz//Pz8//z8/P/8+Pj7/Pj4+/z4+Pv8hISH/ISEh/yEhIf8hISH///// - /wAAAD4AAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAADv/////IyMj/yMjI/8jIyP/ODg4 - /0RERP9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH - /0NDQ/81NTX/IyMj/0FBQf9BQUH/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP8iIiL/IiIi - /yIiIv8iIiL//////wAAAD8AAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAA7//// - /yUlJf8lJSX/JSUl/zg4OP9FRUX/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/SEhI - /0hISP9ISEj/SEhI/0hISP9DQ0P/NTU1/yQkJP9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC - /0JCQv8kJCT/JCQk/yQkJP8kJCT//////wAAAD4AAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAABAAAAO/////8mJib/JiYm/yYmJv84ODj/RUVF/0hISP9ISEj/SEhI/0hISP9ISEj/SEhI - /0hISP9ISEj/SEhI/0hISP9ISEj/SEhI/0hISP9ISEj/RERE/zY2Nv8lJSX/RERE/0RERP9ERET/RERE - /0RERP9ERET/RERE/0RERP8lJSX/JSUl/yUlJf8lJSX//////wAAAD4AAAAHAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAADv/////Jycn/ycnJ/8nJyf/OTk5/0ZGRv9JSUn/SUlJ - /0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0VFRf83Nzf/Jycn - /0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv8nJyf/Jycn/ycnJ/8nJyf//////wAAAD4AAAAHAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAA7/////ykpKf8pKSn/KSkp - /zk5Of9GRkb/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ - /0lJSf9FRUX/Nzc3/ygoKP9ISEj/SEhI/0hISP9ISEj/SEhI/0dHR/8oKCj/KCgo/ygoKP8oKCj///// - /wAAAD8AAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA - O/////8qKir/Kioq/yoqKv86Ojr/R0dH/0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK - /0pKSv9KSkr/SkpK/0pKSv9KSkr/RkZG/zc3N/8pKSn/SUlJ/0lJSf9JSUn/SUlJ/0lJSf8pKSn/KSkp - /ykpKf8pKSn//////wAAAD4AAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAQAAADv/////Kysr/ysrK/8rKyv/Ojo6/0dHR/9KSkr/SkpK/0pKSv9KSkr/SkpK - /0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK/0ZGRv83Nzf/Kysr/0tLS/9LS0v/S0tL - /0tLS/8rKyv/Kysr/ysrK/8rKyv//////wAAAD0AAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAA6/////ywsLP8sLCz/LCws/zo6Ov9ISEj/S0tL - /0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9HR0f/ODg4 - /ywsLP9NTU3/TU1N/0tLS/8sLCz/LCws/ywsLP8sLCz//////wAAADoAAAAGAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOf////8uLi7/Li4u - /y4uLv84ODj/R0dH/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL - /0pKSv9KSkr/RkZG/zg4OP8tLS3/SUlJ/05OTv8tLS3/LS0t/y0tLf8tLS3//////wAAADkAAAAHAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAADD/////Ly8v/y8vL/8vLy//Li4u/z4+Pv9FRUX/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG - /0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0JCQv80NDT/Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy////// - /wAAADgAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAd/////zAwMP8wMDD/MDAw/x0dHf8rKyv/MjIy/zQ0NP80NDT/NDQ0 - /zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP8xMTH/JiYm/zAwMP8wMDD/MDAw - /zAwMP8wMDD//////wAAADcAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACsXFxbkyMjL/MjIy/zIyMv8yMjL/MjIy - /zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8yMjL/MjIy/zIyMv8xMTH/MTEx - /zExMf8xMTH/MTEx/zExMf8xMTH//////wAAADYAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAn//// - /zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz - /zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP//////wAAADUAAAAFAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAABQAAADT/////NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0 - /zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT/NDQ0/zQ0NP80NDT//////wAAADUAAAAGAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAIrS0tJ3///////////////////////// - //////////////////////////////////////////////////////////////////////////////// - /wAAAC8AAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAA - EgAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAA - FwAAABcAAAAXAAAAFgAAAA4AAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////////////////////////////// - ///4AAAAAD////AAAAAAD///4AAAAAAH///gAAAAAAf//8AAAAAAA///wAAAAAAD///AAAAAAAP//8AA - AAAAA///wAAAAAAD///AAAAAAAP//8AAAAAAA///wAAAAAAD///AAAAAAAP//8AAAAAAA///wAAAAAAD - ///AAAAAAAP//8AAAAAAA///wAAAAAAD///AAAAAAAP//8AAAAAAA///wAAAAAAD///AAAAAAAP//8AA - AAAAA///wAAAAAAD///AAAAAAAP//8AAAAAAA///wAAAAAAD///AAAAAAAP//8AAAAAAA///wAAAAAAD - ///AAAAAAAP//8AAAAAAA///wAAAAAAD///AAAAAAAP//8AAAAAAB///wAAAAAAP///AAAAAAB///8AA - AAAAP///wAAAAAB////AAAAAAP///8AAAAAB////wAAAAAP////AAAAAB////8AAAAAP////wAAAAB// - ///AAAAAP////8AAAAB/////wAAAAP/////AAAAB/////8AAAAP/////wAAAB//////gAAAP//////AA - AB//////+AAAP/////////////////////////////////////////////////////////8oAAAAQAAA - AIAAAAABAAgAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wEBAf8CAgL/AwMD/wQEBP8FBQX/BgYG - /wcHB/8ICAj/CQkJ/woKCv8LCwv/DAwM/w0NDf8ODg7/Dw8P/xAQEP8RERH/EhIS/xMTE/8UFBT/FRUV - /xYWFv8XFxf/GBgY/xkZGf8aGhr/Gxsb/xwcHP8dHR3/Hh4e/x8fH/8gICD/ISEh/yIiIv8jIyP/JCQk - /yUlJf8mJib/Jycn/ygoKP8pKSn/Kioq/ysrK/8sLCz/LS0t/y4uLv8vLy//MDAw/zExMf8yMjL/MzMz - /zQ0NP81NTX/NjY2/zc3N/84ODj/OTk5/zo6Ov87Ozv/PDw8/z09Pf8+Pj7/Pz8//0BAQP9BQUH/QkJC - /0NDQ/9ERET/RUVF/0ZGRv9HR0f/SEhI/0lJSf9KSkr/S0tL/01NTf9PT0//UFBQ/1FRUf9TU1P/VVVV - /1ZWVv9XV1f/WFhY/1lZWf9bW1v/XV1d/15eXv9fX1//YGBg/2NjY/9kZGT/ZWVl/2ZmZv9nZ2f/aGho - /2lpaf9qamr/a2tr/2xsbP9tbW3/bm5u/29vb/9wcHD/cXFx/3Nzc/90dHT/dXV1/3Z2dv93d3f/eHh4 - /3l5ef96enr/e3t7/3x8fP99fX3/fn5+/39/f/+AgID/gYGB/4KCgv+Dg4P/hISE/4WFhf+Ghob/h4eH - /4iIiP+JiYn/ioqK/4yMjP+Ojo7/j4+P/5CQkP+RkZH/kpKS/5OTk/+UlJT/lZWV/5aWlv+Xl5f/mJiY - /5mZmf+ampr/m5ub/5ycnP+dnZ3/np6e/5+fn/+goKD/oaGh/6Kiov+jo6P/pKSk/6Wlpf+mpqb/p6en - /6ioqP+pqan/qqqq/62trf+urq7/r6+v/7CwsP+zs7P/tLS0/7a2tv+3t7f/uLi4/7m5uf+6urr/vb29 - /76+vv+/v7//wMDA/8LCwv/Dw8P/xMTE/8XFxf/Gxsb/x8fH/8rKyv/Ly8v/zMzM/83Nzf/Ozs7/z8/P - /9DQ0P/R0dH/0tLS/9PT0//U1NT/1tbW/9fX1//Y2Nj/2dnZ/9ra2v/c3Nz/3d3d/97e3v/f39//4ODg - /+Hh4f/j4+P/5eXl/+bm5v/n5+f/6Ojo/+np6f/r6+v/7e3t/+7u7v/x8fH/9PT0//X19f8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - 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 - AAAAA///wAAAAAAH///AAAAAAA///8AAAAAAH///wAAAAAA////AAAAAAH///8AAAAAA////wAAAAAH/ - ///AAAAAA////8AAAAAH////wAAAAA/////AAAAAH////8AAAAA/////wAAAAH/////AAAAA/////8AA - AAH/////wAAAA//////AAAAH/////+AAAA//////8AAAH//////4AAA///////////////////////// - /////////////////////////////////ygAAAAwAAAAYAAAAAEAIAAAAAAAAEgAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAA - AQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAQAAAAF4AAABhAAAAYQAAAGEAAABhAAAAYQAAAGEAAABhAAAA - YQAAAGEAAABhAAAAYQAAAGEAAABhAAAAYQAAAGEAAABhAAAAYQAAAGEAAABhAAAAYQAAAGEAAABhAAAA - YQAAAGEAAABXAAAALgAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACJeXl6tOzs7/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD//////wAAAHQAAAATAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAB5AAAACQAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPwAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP9ubm7/AAAA - NgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - bQAAAP8AAAD/AAAA/ykpKf8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v - /y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/y4uLv8mJib/AAAA - /wAAAP8AAAD/AAAAaQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAD3Nzc3AAAAP8AAAD/Hh4e/zAwMP80NDT/p6en/6enp/+np6f/p6en/zQ0NP+np6f/p6en - /zQ0NP+np6f/p6en/6enp/+np6f/p6en/6enp/+np6f/NDQ0/6enp/+np6f/p6en/6enp/+np6f/p6en - /zQ0NP8vLy//HR0d/wAAAP8AAAD/3d3d3QAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc3AAAAP8AAAD/ISEh/zIyMv81NTX/NTU1/zU1Nf+6urr/urq6 - /zU1Nf+6urr/urq6/zU1Nf+6urr/urq6/7q6uv+6urr/urq6/7q6uv+6urr/urq6/7q6uv+6urr/urq6 - /7q6uv+6urr/urq6/zU1Nf8yMjL/ISEh/wAAAP8AAAD/3Nzc3gAAAAQAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc3AAAAP8AAAD/ISEh/zMzM/82Njb/zMzM - /8zMzP/MzMz/zMzM/zY2Nv/MzMz/zMzM/zY2Nv/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM - /8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/zU1Nf8yMjL/ISEh/wAAAP8AAAD/3Nzc3gAAAAQAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc3AAAAP8AAAD/IiIi - /zQ0NP83Nzf/3t7e/97e3v82Njb/NjY2/zY2Nv/e3t7/3t7e/zY2Nv/e3t7/3t7e/97e3v/e3t7/3t7e - /97e3v/e3t7/3t7e/97e3v/e3t7/3t7e/97e3v/e3t7/3t7e/zY2Nv8zMzP/ISEh/wAAAP8AAAD/3Nzc - 3gAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc - 3AAAAP8AAAD/IiIi/zQ0NP83Nzf/7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v - /+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/zc3N/80NDT/IiIi - /wAAAP8AAAD/3Nzc3gAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAE3Nzc3AAAAP8AAAD/IyMj/zU1Nf84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4 - /zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4 - /zg4OP81NTX/IyMj/wAAAP8AAAD/3Nzc3gAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc3AEBAf8BAQH/IyMj/zY2Nv85OTn/qKio/6ioqP+oqKj/OTk5 - /zk5Of85OTn/OTk5/zk5Of+oqKj/qKio/6ioqP+oqKj/qKio/6ioqP84ODj/qKio/6ioqP+oqKj/ODg4 - /6ioqP+oqKj/qKio/zg4OP81NTX/IyMj/wEBAf8AAAD/3Nzc3gAAAAQAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc3AMDA/8DAwP/JCQk/zc3N/86Ojr/sbGx - /7Gxsf+xsbH/OTk5/zk5Of85OTn/OTk5/zk5Of+xsbH/sbGx/7Gxsf+xsbH/sbGx/7Gxsf85OTn/sbGx - /7Gxsf+xsbH/OTk5/7Gxsf+xsbH/sbGx/zk5Of82Njb/IyMj/wICAv8CAgL/3Nzc3gAAAAQAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc3AUFBf8FBQX/JCQk - /zc3N/86Ojr/urq6/7q6uv+6urr/Ojo6/zo6Ov86Ojr/Ojo6/zo6Ov+6urr/urq6/7q6uv86Ojr/Ojo6 - /zo6Ov86Ojr/urq6/7q6uv+6urr/Ojo6/7q6uv+6urr/urq6/zo6Ov83Nzf/JCQk/wQEBP8EBAT/3Nzc - 3gAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc - 3AcHB/8HBwf/JSUl/zg4OP87Ozv/xMTE/8TExP/ExMT/Ozs7/zs7O/87Ozv/Ozs7/zs7O//ExMT/xMTE - /8TExP87Ozv/Ozs7/zs7O/87Ozv/xMTE/8TExP/ExMT/xMTE/8TExP/ExMT/xMTE/zs7O/84ODj/JSUl - /wYGBv8GBgb/3Nzc3gAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAE3Nzc3AgICP8ICAj/JSUl/zg4OP88PDz/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N - /zw8PP/Nzc3/zc3N/83Nzf88PDz/PDw8/zw8PP88PDz/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3/zc3N - /zs7O/84ODj/JSUl/wgICP8ICAj/3Nzc3gAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc3AoKCv8KCgr/JiYm/zk5Of89PT3/1tbW/9bW1v/W1tb/1tbW - /9bW1v/W1tb/1tbW/zw8PP/W1tb/1tbW/9bW1v88PDz/PDw8/zw8PP88PDz/1tbW/9bW1v/W1tb/1tbW - /9bW1v88PDz/PDw8/zw8PP84ODj/JSUl/woKCv8KCgr/3Nzc3gAAAAQAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc3AwMDP8MDAz/JiYm/zk5Of89PT3/39/f - /9/f3//f39//PT09/9/f3//f39//39/f/z09Pf/f39//39/f/9/f3/89PT3/PT09/z09Pf89PT3/39/f - /9/f3//f39//39/f/9/f3//f39//39/f/z09Pf85OTn/JiYm/wsLC/8LCwv/3Nzc3gAAAAQAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc3A4ODv8ODg7/JiYm - /zo6Ov8+Pj7/6Ojo/+jo6P/o6Oj/Pj4+/+jo6P/o6Oj/6Ojo/z4+Pv/o6Oj/6Ojo/+jo6P8+Pj7/Pj4+ - /z4+Pv8+Pj7/6Ojo/+jo6P/o6Oj/Pj4+/+jo6P/o6Oj/6Ojo/z4+Pv86Ojr/JiYm/w0NDf8NDQ3/3Nzc - 3gAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc - 3BAQEP8QEBD/Jycn/zs7O/8/Pz//8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy/z8/P//y8vL/8vLy - //Ly8v/y8vL/8vLy//Ly8v8/Pz//8vLy//Ly8v/y8vL/Pz8///Ly8v/y8vL/8vLy/z4+Pv86Ojr/JiYm - /w8PD/8PDw//3Nzc3gAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAE3Nzc3BISEv8RERH/KCgo/zw8PP9AQED/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7 - /z8/P//7+/v/+/v7//v7+//7+/v/+/v7//v7+/8/Pz//+/v7//v7+//7+/v/Pz8///v7+//7+/v/+/v7 - /z8/P/87Ozv/Jycn/xEREf8RERH/3Nzc3gAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc3BMTE/8TExP/KCgo/zw8PP9AQED/QEBA/0BAQP9AQED/QEBA - /0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA - /0BAQP9AQED/QEBA/0BAQP88PDz/KCgo/xISEv8SEhL/3Nzc3gAAAAQAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc3BUVFf8VFRX/KCgo/z09Pf9BQUH/QUFB - /0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB - /0FBQf9BQUH/QUFB/0FBQf9BQUH/QUFB/0FBQf89PT3/KCgo/xQUFP8UFBT/3Nzc3gAAAAQAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc3BcXF/8XFxf/KSkp - /z4+Pv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QUFB - /z8/P/89PT3/PT09/z09Pf89PT3/PT09/zw8PP88PDz/PDw8/zw8PP85OTn/JSUl/xYWFv8WFhb/3Nzc - 3gAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc - 3BkZGf8ZGRn/Kioq/z8/P/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0JCQv9CQkL/QkJC - /0JCQv8/Pz//Nzc3/y0tLf8oKCj/Jycn/ycnJ/8nJyf/Jycn/ycnJ/8nJyf/Jycn/ycnJ/8kJCT/GBgY - /xgYGP8YGBj/3d3d3QAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAE3Nzc3BoaGv8aGhr/Kioq/z8/P/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND - /0NDQ/9DQ0P/Q0ND/0FBQf81NTX/ICAg/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa/xoaGv8aGhr/Ghoa - /xoaGv8aGhr/Ghoa/xoaGv8aGhr/wcHBuwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc3BwcHP8cHBz/Kioq/0BAQP9ERET/RERE/0RERP9ERET/RERE - /0RERP9ERET/RERE/0RERP9ERET/RERE/z09Pf8nJyf/HBwc/zc3N/83Nzf/Nzc3/zc3N/83Nzf/Nzc3 - /zc3N/83Nzf/Nzc3/zc3N/8cHBz/HBwc/xwcHP//////AAAAIQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc3B4eHv8eHh7/Kysr/0FBQf9FRUX/RUVF - /0VFRf9FRUX/RUVF/0VFRf9FRUX/RUVF/0VFRf9FRUX/RERE/zk5Of8dHR3/Ojo6/zo6Ov86Ojr/Ojo6 - /zk5Of85OTn/OTk5/zk5Of85OTn/OTk5/x0dHf8dHR3/HR0d//7+/v8AAAAlAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc3CAgIP8gICD/LCws - /0JCQv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RUVF/zc3N/8fHx//PDw8 - /zw8PP88PDz/PDw8/zw8PP88PDz/PDw8/zw8PP87Ozv/Hx8f/x8fH/8fHx///v7+/wAAACUAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc - 3CEhIf8hISH/LCws/0JCQv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RkZG/0ZGRv9GRkb/RUVF - /zc3N/8hISH/Pz8//z4+Pv8+Pj7/Pj4+/z4+Pv8+Pj7/Pj4+/z4+Pv8hISH/ISEh/yEhIf/+/v7/AAAA - JQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAE3Nzc3CMjI/8jIyP/LCws/0NDQ/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH - /0dHR/9HR0f/RkZG/zg4OP8jIyP/QUFB/0FBQf9BQUH/QUFB/0FBQf9BQUH/QEBA/yMjI/8jIyP/IyMj - //////8AAAAlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc3CUlJf8lJSX/LS0t/0RERP9ISEj/SEhI/0hISP9ISEj/SEhI - /0hISP9ISEj/SEhI/0hISP9ISEj/R0dH/zk5Of8lJSX/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/JSUl - /yUlJf8lJSX//////wAAACQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc3CcnJ/8nJyf/LS0t/0VFRf9JSUn/SUlJ - /0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9JSUn/R0dH/zk5Of8nJyf/RkZG/0ZGRv9GRkb/RUVF - /0VFRf8mJib/JiYm/yYmJv//////AAAAJQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc3CkpKf8pKSn/Li4u - /0VFRf9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9JSUn/SUlJ/0lJSf9JSUn/SEhI/zo6Ov8oKCj/SEhI - /0hISP9ISEj/SEhI/ygoKP8oKCj/KCgo//////8AAAAlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE3Nzc - 3CoqKv8qKir/Li4u/0ZGRv9KSkr/SkpK/0pKSv9KSkr/SkpK/0pKSv9KSkr/SkpK/0pKSv9KSkr/SUlJ - /zo6Ov8qKir/SkpK/0pKSv9KSkr/Kioq/yoqKv8qKir//////wAAACQAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAE3Nzc3CwsLP8sLCz/Li4u/0dHR/9LS0v/S0tL/0tLS/9LS0v/S0tL/0tLS/9LS0v/S0tL - /0tLS/9LS0v/SkpK/zs7O/8sLCz/TU1N/01NTf8sLCz/LCws/ywsLP//////AAAAIgAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAC3Nzc3C4uLv8uLi7/Kioq/0VFRf9LS0v/S0tL/0tLS/9LS0v/S0tL - /0tLS/9LS0v/S0tL/0tLS/9LS0v/SkpK/zs7O/8uLi7/T09P/y4uLv8uLi7/Li4u//////8AAAAhAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZTAwMP8wMDD/IiIi/zQ0NP89PT3/Pj4+ - /z4+Pv8+Pj7/Pj4+/z4+Pv8+Pj7/Pj4+/z4+Pv8+Pj7/PT09/zExMf8wMDD/MDAw/zAwMP8wMDD///// - /wAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMjIyMv8yMjL/MjIy - /zIyMv8pKSn/KSkp/ygoKP8oKCj/KCgo/ygoKP8oKCj/KCgo/ygoKP8oKCj/KCgo/ygoKP8xMTH/MTEx - /zExMf//////AAAAHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - CP39/f4zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz - /zMzM/8zMzP/MzMz//////8AAAAeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAA7/////TExM/zU1Nf81NTX/NTU1/zU1Nf81NTX/NTU1/zU1Nf81NTX/NTU1 - /zU1Nf81NTX/NTU1/zU1Nf81NTX//////wAAAB0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAFQAAACMAAAAkAAAAJAAAACQAAAAkAAAA - JAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAiAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////8AAP///////wAA//// - ////AAD///////8AAP+AAAAD/wAA/wAAAAH/AAD/AAAAAP8AAP8AAAAA/wAA/gAAAAB/AAD+AAAAAH8A - AP4AAAAAfwAA/gAAAAB/AAD+AAAAAH8AAP4AAAAAfwAA/gAAAAB/AAD+AAAAAH8AAP4AAAAAfwAA/gAA - AAB/AAD+AAAAAH8AAP4AAAAAfwAA/gAAAAB/AAD+AAAAAH8AAP4AAAAAfwAA/gAAAAB/AAD+AAAAAH8A - AP4AAAAAfwAA/gAAAAB/AAD+AAAAAH8AAP4AAAAAfwAA/gAAAAD/AAD+AAAAAf8AAP4AAAAD/wAA/gAA - AAf/AAD+AAAAD/8AAP4AAAAf/wAA/gAAAD//AAD+AAAAf/8AAP4AAAD//wAA/gAAAf//AAD+AAAD//8A - AP8AAAf//wAA/wAAD///AAD/AAAf//8AAP+AAD///wAA////////AAD///////8AAP///////wAA//// - ////AAAoAAAAMAAAAGAAAAABAAgAAAAAAAASAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wEBAf8CAgL/AwMD - /wQEBP8FBQX/BgYG/wcHB/8ICAj/CQkJ/woKCv8LCwv/DAwM/w0NDf8ODg7/Dw8P/xAQEP8RERH/EhIS - /xMTE/8UFBT/FRUV/xYWFv8XFxf/GBgY/xkZGf8aGhr/Gxsb/xwcHP8dHR3/Hh4e/x8fH/8gICD/ISEh - /yIiIv8jIyP/JCQk/yUlJf8mJib/Jycn/ygoKP8pKSn/Kioq/ysrK/8sLCz/LS0t/y4uLv8vLy//MDAw - /zExMf8yMjL/MzMz/zQ0NP81NTX/NjY2/zc3N/84ODj/OTk5/zo6Ov87Ozv/PDw8/z09Pf8+Pj7/Pz8/ - /0BAQP9BQUH/QkJC/0NDQ/9ERET/RUVF/0ZGRv9HR0f/SEhI/0lJSf9KSkr/S0tL/0xMTP9NTU3/Tk5O - /09PT/9RUVH/U1NT/1RUVP9VVVX/VlZW/1dXV/9aWlr/XFxc/11dXf9eXl7/X19f/2FhYf9iYmL/Y2Nj - /2VlZf9nZ2f/aGho/2lpaf9sbGz/bW1t/25ubv9zc3P/dnZ2/3d3d/95eXn/enp6/3t7e/98fHz/fX19 - /35+fv9/f3//gYGB/4iIiP+JiYn/kpKS/5WVlf+Wlpb/l5eX/5iYmP+ZmZn/mpqa/5ubm/+cnJz/nZ2d - /56env+fn5//oKCg/6Ghof+ioqL/pKSk/6Wlpf+mpqb/p6en/6ioqP+pqan/qqqq/6urq/+srKz/ra2t - /6+vr/+xsbH/srKy/7S0tP+1tbX/t7e3/7i4uP+5ubn/urq6/7u7u/+8vLz/v7+//8DAwP/BwcH/wsLC - /8PDw//ExMT/xcXF/8bGxv/Hx8f/yMjI/8nJyf/Kysr/zMzM/83Nzf/Ozs7/z8/P/9LS0v/U1NT/1dXV - /9bW1v/Y2Nj/2tra/9vb2//e3t7/39/f/+Dg4P/h4eH/4uLi/+Pj4//k5OT/5+fn/+jo6P/v7+//8fHx - //Ly8v8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - 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 - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEQAAAP8AAAD/Ly8v/zU1Nf81NTX/vr6+/zU1Nf++vr7/NTU1 - /76+vv9tbW3/sLCw/76+vv++vr7/i4uL/6urq/++vr7/vr6+/zU1Nf8vLy//AAAA/wAAAP8AAAARAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARAAAA/wAAAP8wMDD/NjY2/9nZ2f+NjY3/NjY2 - /9nZ2f82Njb/2dnZ/3R0dP/IyMj/2dnZ/9nZ2f+Xl5f/wMDA/9nZ2f/Z2dn/NjY2/zAwMP8AAAD/AAAA - /wAAABEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEAAAD/AAAA/zExMf83Nzf/9PT0 - //T09P/v7+//9PT0//T09P/09PT/enp6/+Hh4f/09PT/9PT0/6Ojo//W1tb/9PT0//T09P83Nzf/MDAw - /wAAAP8AAAD/AAAAEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEQEBAf8BAQH/MjIy - /zk5Of+mpqb/pqam/zg4OP84ODj/ODg4/6ampv+mpqb/pqam/6ampv85OTn/pqam/6Wlpf+mpqb/pqam - /zg4OP8xMTH/AAAA/wAAAP8AAAARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARAwMD - /wMDA/8zMzP/Ojo6/7Ozs/+zs7P/Ojo6/zo6Ov86Ojr/s7Oz/7Ozs/+ysrL/srKy/zo6Ov+zs7P/s7Oz - /7Ozs/+zs7P/OTk5/zIyMv8DAwP/AwMD/wAAABEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAABEGBgb/BgYG/zQ0NP87Ozv/wcHB/8HBwf87Ozv/Ozs7/zs7O//BwcH/wcHB/zs7O/87Ozv/PDw8 - /8HBwf/BwcH/wcHB/8HBwf86Ojr/MzMz/wYGBv8FBQX/AAAAEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAEQkJCf8JCQn/NTU1/zw8PP/Pz8//z8/P/8/Pz//Pz8//Pz8//8/Pz//Pz8//PDw8 - /zw8PP89PT3/z8/P/8/Pz//Pz8//z8/P/zw8PP81NTX/CAgI/wgICP8AAAARAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAARCwsL/wsLC/82Njb/PT09/93d3f/d3d3/3Nzc/93d3f9AQED/3d3d - /93d3f89PT3/PT09/z4+Pv/d3d3/3d3d/93d3f/d3d3/PT09/zY2Nv8LCwv/CwsL/wAAABEAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEODg7/Dg4O/zc3N/8+Pj7/6urq/+rq6v/p6en/6urq - /0FBQf/q6ur/6urq/0NDQ/9DQ0P/Pz8//+rq6v/o6Oj/6urq/+rq6v8+Pj7/Nzc3/w4ODv8ODg7/AAAA - EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEREREf8RERH/ODg4/z8/P//4+Pj/+Pj4 - //j4+P/4+Pj/QkJC//j4+P/4+Pj/+Pj4//j4+P9AQED/+Pj4//b29v/4+Pj/+Pj4/z8/P/84ODj/EBAQ - /xAQEP8AAAARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARFBQU/xQUFP85OTn/QUFB - /0FBQf9BQUH/QUFB/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP9AQED/QEBA - /zk5Of8TExP/ExMT/wAAABEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEWFhb/FhYW - /zo6Ov9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9BQUH/QUFB/0FBQf8/Pz//Pj4+/z4+Pv8+Pj7/Pj4+ - /z4+Pv8+Pj7/Nzc3/xYWFv8WFhb/AAAAEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - ERkZGf8ZGRn/Ozs7/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/Q0ND/0NDQ/9DQ0P/PDw8/ykpKf8gICD/Hx8f - /x8fH/8fHx//Hx8f/x8fH/8bGxv/GBgY/xgYGP8AAAAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAARHBwc/xwcHP88PDz/RERE/0RERP9ERET/RERE/0RERP9ERET/RERE/0FBQf8kJCT/NDQ0 - /zc3N/82Njb/NjY2/zY2Nv82Njb/NjY2/xsbG/8bGxv//v7+/wAAAAIAAAAAAAAAAAAAAAAAAAAAAAAA - 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 - /yAgIP8iIiL/IyMj/yQkJP8lJSX/JiYm/ycnJ/8oKCj/KSkp/yoqKv8rKyv/LCws/y0tLf8uLi7/Ly8v - /zAwMP8xMTH/MjIy/zMzM/80NDT/NTU1/zY2Nv83Nzf/ODg4/zk5Of86Ojr/Ozs7/zw8PP89PT3/Pj4+ - /z8/P/9AQED/QUFB/0JCQv9DQ0P/RERE/0VFRf9GRkb/R0dH/0hISP9JSUn/SkpK/0tLS/9MTEz/TU1N - /05OTv9PT0//UFBQ/1FRUf9SUlL/U1NT/1RUVP9VVVX/VlZW/1dXV/9YWFj/WVlZ/1paWv9bW1v/XV1d - /15eXv9fX1//YGBg/2FhYf9iYmL/Y2Nj/2VlZf9mZmb/Z2dn/2lpaf9qamr/bGxs/3Jycv95eXn/e3t7 - /3x8fP9+fn7/f39//4CAgP+BgYH/hYWF/4aGhv+IiIj/jIyM/42Njf+Ojo7/j4+P/5CQkP+RkZH/k5OT - /5WVlf+ampr/m5ub/5ycnP+enp7/oaGh/6ampv+np6f/qKio/6mpqf+qqqr/q6ur/7CwsP+zs7P/tLS0 - /7a2tv+7u7v/vLy8/729vf++vr7/v7+//8HBwf/CwsL/w8PD/8fHx//IyMj/ysrK/87Ozv/Pz8//09PT - /9TU1P/V1dX/19fX/9zc3P/d3d3/4eHh/+Pj4//q6ur/6+vr/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - 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 - APAD/wDwB/8A////AP///wAoAAAAGAAAADAAAAABAAgAAAAAAIAEAAAAAAAAAAAAAAAAAAAAAAAAAAAA - /wICAv8FBQX/BgYG/wkJCf8MDAz/DQ0N/w8PD/8QEBD/ERER/xMTE/8UFBT/FxcX/xgYGP8bGxv/HBwc - /x8fH/8gICD/IiIi/yMjI/8kJCT/JSUl/yYmJv8nJyf/KCgo/ykpKf8qKir/Kysr/ywsLP8tLS3/Li4u - /y8vL/8wMDD/MTEx/zMzM/80NDT/NTU1/zY2Nv83Nzf/ODg4/zk5Of86Ojr/Ozs7/z09Pf8+Pj7/Pz8/ - /0BAQP9BQUH/QkJC/0NDQ/9ERET/RUVF/0dHR/9ISEj/SkpK/0tLS/9NTU3/Tk5O/09PT/9QUFD/UlJS - /1VVVf9aWlr/W1tb/19fX/9hYWH/aWlp/2pqav9sbGz/bm5u/3BwcP9xcXH/c3Nz/3R0dP91dXX/eXl5 - /3x8fP+AgID/goKC/4SEhP+FhYX/hoaG/4uLi/+MjIz/kZGR/5SUlP+Wlpb/mJiY/5qamv+cnJz/oaGh - /6Kiov+jo6P/pqam/6urq/+srKz/ra2t/6+vr/+xsbH/s7Oz/7W1tf+/v7//y8vL/9HR0f/j4+P/5OTk - /+bm5v8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAMz4+Pj4+Pj4+PT4+PiUAAAAAAAAAAQFBHxMTExQU - EhQVERMTEyVDAAAAAAAAAFEPCBERERARDxIQERIREAUQTwAAAAABAFkAFThQQFJBVlJWUFJXQRYAWQAA - AAAAAFkBF0ZaPmFJXmJhYmFeShcAWQEAAAABAFgAGEVeTV5WWVthVVhkRBkAWQAAAAAAAFkCGkJgMyhJ - X1pLYUlgQxkBWQABAAABAFkCHEllPDVNZSg0ZV1lSRkEWQAAAAAAAFkFHE1nZmdWZyw1Z2ddPxkGWQAA - AAABAFkHGk9pWGlaaDo9aWNpURoGWQEAAAAAAFkLIVFqampcampbalVqTxkIWQEAAAAAAFkLIS0vLy8v - Ly8sLi4sLSUMWQAAAAAAAFoMIzMwMDAwMCwlISElIRcMWQAAAAAAAFoNIzIyMjIzMBkZHxkcHA4nWgAA - AAAAAFoRJzMzMzMzLBkrKCgoGihUAAAAAAAAAFkSJjQ0NDQ0LCAvLygaLlQAAAAAAAAAAFoXKDU1NTU1 - LiUyMxozVAAAAAAAAAABAFoaKTY2NjY2Lyc1ITVWAAAAAAAAAAAAAFwfKTc3Nzc2LiglOFUAAAAAAAAA - AAAAAFowISMjJSUlJRo5VgAAAAAAAAAAAAAAAABRPjs7Ozo5OUBWAAAAAAAAAAAAAAAAAAAATVZWVlZW - Vk8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A8AAPAPAADwDwAA8A8AAP - APAADwDwAA8A8AAPAPAADwDwAA8A8AAPAPAADwDwAA8A8AAPAPAAHwDwAD8A8AB/APAA/wDwAf8A8AP/ - APAH/wD///8A////ACgAAAAQAAAAIAAAAAEAIAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAOzs7/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD//////wAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAbQAAAP8vLy//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy//Ly8v/wAAAP8AAABpAAAA - AAAAAAAAAAAAAAAAANzc3N0hISH/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP8hISH/3Nzc - 3QAAAAAAAAAAAAAAAAAAAADc3NzdIyMj/zg4OP84ODj/ODg4/zg4OP84ODj/ODg4/zg4OP84ODj/IyMj - /9zc3N0AAAAAAAAAAAAAAAAAAAAA3Nzc3SQkJP+6urr/Ojo6/zo6Ov+6urr/Ojo6/7q6uv86Ojr/urq6 - /yQkJP/c3NzdAAAAAAAAAAAAAAAAAAAAANzc3N0mJib/1tbW/9bW1v/W1tb/1tbW/zw8PP/W1tb/1tbW - /zw8PP8lJSX/3Nzc3QAAAAAAAAAAAAAAAAAAAADc3NzdJycn//Ly8v/y8vL/8vLy//Ly8v/y8vL/8vLy - /z8/P//y8vL/JiYm/9zc3N0AAAAAAAAAAAAAAAAAAAAA3Nzc3SgoKP9BQUH/QUFB/0FBQf9BQUH/QUFB - /0FBQf9BQUH/QUFB/ygoKP/c3NzdAAAAAAAAAAAAAAAAAAAAANzc3N0qKir/Q0ND/0NDQ/9DQ0P/Q0ND - /yAgIP8aGhr/Ghoa/xoaGv8aGhr/wMDAvAAAAAAAAAAAAAAAAAAAAADc3NzdLCws/0ZGRv9GRkb/RkZG - /0VFRf88PDz/PDw8/zw8PP8fHx///v7+/wAAAAAAAAAAAAAAAAAAAAAAAAAA3Nzc3S0tLf9ISEj/SEhI - /0hISP9HR0f/Q0ND/0NDQ/8lJSX//////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANzc3N0uLi7/SkpK - /0pKSv9KSkr/SUlJ/0pKSv8qKir//////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABlIiIi - /z4+Pv8+Pj7/Pj4+/z09Pf8wMDD//////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AExMTP81NTX/NTU1/zU1Nf81NTX//////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8A - AOAHAADgBwAAwAMAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMAHAADADwAAwB8AAOA/AADgfwAA//8A - ACgAAAAQAAAAIAAAAAEACAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAANDQ3/Dw8P/xoaGv8bGxv/HBwc - /x4eHv8hISH/JCQk/yUlJf8nJyf/KCgo/yoqKv8rKyv/LS0t/y8vL/8xMTH/MjIy/zU1Nf82Njb/ODg4 - /zk5Of87Ozv/PDw8/z09Pf8+Pj7/Pz8//0BAQP9BQUH/QkJC/0NDQ/9ERET/RkZG/0hISP9KSkr/W1tb - /3BwcP9xcXH/cnJy/3x8fP9/f3//goKC/4ODg/+IiIj/iYmJ/5aWlv+YmJj/mZmZ/5ubm/+ioqL/o6Oj - /6Wlpf+mpqb/qKio/6mpqf+qqqr/ra2t/7CwsP+4uLj/urq6/8HBwf/Q0ND/1dXV/9jY2P/n5+f/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA - /wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAAAAAAAAAAAAAAAAA - AAAAIxIODQwNCw0MDhkjAAAAACEAFBURHx8WGxMAHwAAAAASAiMkKDM2MzUpAhsAAAAAGwMpJyYzNSws - KAISAAAAABQDKyUbOSItMyoEHgAAAAAgBy87Nz0WNzwmBRYAAAAAGAczPjo/Ojo4MwcgAAAAACEJGRsY - GRkYGRsKHwAAAAAfCR8aHx8NCwwLAiIAAAAAIg4gHx8aDxUYCyIiAAAAACEPICAfHxIfDiIlAAAAAAAi - ESEhIR4VFCIiAAAAAAAAIg4WGBUUESMiAAAAAAAAACwiISIhISMhAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AP//AADgBwAA4AcAAMADAADAAwAAwAMAAMADAADAAwAAwAMAAMADAADABwAAwA8AAMAfAADgPwAA4H8A - AP//AAA= - - \ No newline at end of file diff --git a/PCK-Studio/Forms/Editor/AudioEditor.Designer.cs b/PCK-Studio/Forms/Editor/AudioEditor.Designer.cs index fbc1e30e..2b38f77f 100644 --- a/PCK-Studio/Forms/Editor/AudioEditor.Designer.cs +++ b/PCK-Studio/Forms/Editor/AudioEditor.Designer.cs @@ -269,7 +269,7 @@ namespace PckStudio.Forms.Editor // playOverworldInCreative // resources.ApplyResources(this.playOverworldInCreative, "playOverworldInCreative"); - this.playOverworldInCreative.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.playOverworldInCreative.BackColor = System.Drawing.Color.Transparent; this.playOverworldInCreative.ForeColor = System.Drawing.SystemColors.Window; this.playOverworldInCreative.Name = "playOverworldInCreative"; this.playOverworldInCreative.Theme = MetroFramework.MetroThemeStyle.Dark; @@ -281,6 +281,7 @@ namespace PckStudio.Forms.Editor // resources.ApplyResources(this.compressionUpDown, "compressionUpDown"); this.compressionUpDown.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.compressionUpDown.BorderStyle = System.Windows.Forms.BorderStyle.None; this.compressionUpDown.ForeColor = System.Drawing.SystemColors.Window; this.compressionUpDown.Maximum = new decimal(new int[] { 9, @@ -319,7 +320,6 @@ namespace PckStudio.Forms.Editor this.MinimizeBox = false; this.Name = "AudioEditor"; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.AudioEditor_FormClosing); - this.Shown += new System.EventHandler(this.AudioEditor_Shown); this.contextMenuStrip1.ResumeLayout(false); this.menuStrip.ResumeLayout(false); this.menuStrip.PerformLayout(); diff --git a/PCK-Studio/Forms/Editor/AudioEditor.cs b/PCK-Studio/Forms/Editor/AudioEditor.cs index 7ac98946..0b3c08eb 100644 --- a/PCK-Studio/Forms/Editor/AudioEditor.cs +++ b/PCK-Studio/Forms/Editor/AudioEditor.cs @@ -24,7 +24,6 @@ namespace PckStudio.Forms.Editor public partial class AudioEditor : EditorForm { public string defaultType = "yes"; - MainForm parent = null; private static readonly List Categories = new List { @@ -53,15 +52,14 @@ namespace PckStudio.Forms.Editor SetUpTree(); } - private string GetCategoryFromId(PckAudioFile.AudioCategory.EAudioType categoryId) - => categoryId >= PckAudioFile.AudioCategory.EAudioType.Overworld && - categoryId <= PckAudioFile.AudioCategory.EAudioType.BuildOff + private string GetCategoryFromId(PckAudioFile.Category categoryId) + => Enum.IsDefined(typeof(PckAudioFile.Category), categoryId) ? Categories[(int)categoryId] : "Not valid"; - private PckAudioFile.AudioCategory.EAudioType GetCategoryId(string category) + private PckAudioFile.Category GetCategoryId(string category) { - return (PckAudioFile.AudioCategory.EAudioType)Categories.IndexOf(category); + return (PckAudioFile.Category)Categories.IndexOf(category); } public void SetUpTree() @@ -76,10 +74,10 @@ namespace PckStudio.Forms.Editor foreach (string songname in category.SongNames.FindAll(s => s.Contains('\\'))) category.SongNames[category.SongNames.IndexOf(songname)] = songname.Replace('\\', '/'); - if (category.AudioType == PckAudioFile.AudioCategory.EAudioType.Creative) + if (category.AudioType == PckAudioFile.Category.Creative) { if (category.Name == "include_overworld" && - EditorValue.TryGetCategory(PckAudioFile.AudioCategory.EAudioType.Overworld, out PckAudioFile.AudioCategory overworldCategory)) + EditorValue.TryGetCategory(PckAudioFile.Category.Overworld, out PckAudioFile.AudioCategory overworldCategory)) { foreach (var name in category.SongNames.ToList()) { @@ -95,7 +93,7 @@ namespace PckStudio.Forms.Editor treeNode.Tag = category; treeView1.Nodes.Add(treeNode); } - playOverworldInCreative.Enabled = EditorValue.HasCategory(PckAudioFile.AudioCategory.EAudioType.Creative); + playOverworldInCreative.Enabled = EditorValue.HasCategory(PckAudioFile.Category.Creative); treeView1.EndUpdate(); } @@ -105,9 +103,7 @@ namespace PckStudio.Forms.Editor return; TreeNode entry = treeView2.SelectedNode; - if (!parent.CreateDataFolder()) - return; - string fileName = Path.Combine(parent.GetDataPath(), entry.Text + ".binka"); + string fileName = Path.Combine(entry.Text + ".binka"); if (File.Exists(fileName)) MessageBox.Show(this, $"\"{entry.Text}.binka\" exists in the \"Data\" folder", "File found"); @@ -144,7 +140,7 @@ namespace PckStudio.Forms.Editor EditorValue.AddCategory(GetCategoryId(add.SelectedItem)); PckAudioFile.AudioCategory category = EditorValue.GetCategory(GetCategoryId(add.SelectedItem)); - if (GetCategoryId(add.SelectedItem) == PckAudioFile.AudioCategory.EAudioType.Creative) + if (GetCategoryId(add.SelectedItem) == PckAudioFile.Category.Creative) { playOverworldInCreative.Visible = true; playOverworldInCreative.Checked = false; @@ -161,9 +157,6 @@ namespace PckStudio.Forms.Editor { if (treeView1.SelectedNode is TreeNode t && t.Tag is PckAudioFile.AudioCategory) { - if (!parent.CreateDataFolder()) - return; - OpenFileDialog ofn = new OpenFileDialog(); ofn.Multiselect = true; ofn.Filter = "Supported audio files (*.binka,*.wav)|*.binka;*.wav"; @@ -183,7 +176,7 @@ namespace PckStudio.Forms.Editor if (treeView1.SelectedNode is TreeNode main && EditorValue.RemoveCategory(GetCategoryId(treeView1.SelectedNode.Text))) { - if(GetCategoryId(treeView1.SelectedNode.Text) == PckAudioFile.AudioCategory.EAudioType.Creative) + if(GetCategoryId(treeView1.SelectedNode.Text) == PckAudioFile.Category.Creative) { playOverworldInCreative.Visible = false; playOverworldInCreative.Checked = false; @@ -236,7 +229,7 @@ namespace PckStudio.Forms.Editor if (File.Exists(cacheSongFile)) File.Delete(cacheSongFile); - string new_loc = Path.Combine(parent.GetDataPath(), songName + ".binka"); + string new_loc = Path.Combine(songName + ".binka"); bool is_duplicate_file = false; // To handle if a file already in the pack is dropped back in bool loc_is_occupied = File.Exists(new_loc); if (loc_is_occupied) @@ -348,24 +341,21 @@ namespace PckStudio.Forms.Editor // Gets the MainForm so we can access the Save Location if (treeView1.SelectedNode != null) { - if (!parent.CreateDataFolder()) - return; - ProcessEntries((string[])e.Data.GetData(DataFormats.FileDrop, false)); } } private void saveToolStripMenuItem1_Click(object sender, EventArgs e) { - if (!EditorValue.HasCategory(PckAudioFile.AudioCategory.EAudioType.Overworld) || - !EditorValue.HasCategory(PckAudioFile.AudioCategory.EAudioType.Nether) || - !EditorValue.HasCategory(PckAudioFile.AudioCategory.EAudioType.End)) + if (!EditorValue.HasCategory(PckAudioFile.Category.Overworld) || + !EditorValue.HasCategory(PckAudioFile.Category.Nether) || + !EditorValue.HasCategory(PckAudioFile.Category.End)) { MessageBox.Show(this, "Your changes were not saved. The game will crash when loading your pack if the Overworld, Nether and End categories don't all exist with at least one valid song.", "Mandatory Categories Missing"); return; } - PckAudioFile.AudioCategory overworldCategory = EditorValue.GetCategory(PckAudioFile.AudioCategory.EAudioType.Overworld); + PckAudioFile.AudioCategory overworldCategory = EditorValue.GetCategory(PckAudioFile.Category.Overworld); bool songs_missing = false; foreach (PckAudioFile.AudioCategory category in EditorValue.Categories) @@ -378,7 +368,7 @@ namespace PckStudio.Forms.Editor foreach(var song in category.SongNames) { - string fileName = Path.Combine(parent.GetDataPath(), song + ".binka"); + string fileName = Path.Combine(song + ".binka"); if (!File.Exists(fileName)) { songs_missing = true; @@ -387,7 +377,7 @@ namespace PckStudio.Forms.Editor } category.Name = ""; - if (playOverworldInCreative.Checked && category.AudioType == PckAudioFile.AudioCategory.EAudioType.Creative) + if (playOverworldInCreative.Checked && category.AudioType == PckAudioFile.Category.Creative) { foreach (var name in overworldCategory.SongNames) { @@ -437,10 +427,8 @@ namespace PckStudio.Forms.Editor totalSongList.Add(song); } - if (!parent.CreateDataFolder()) - return; int totalDeleted = 0; - foreach (string song in Directory.GetFiles(parent.GetDataPath(), "*.binka")) + foreach (string song in Directory.GetFiles("*.binka")) { if (!totalSongList.Contains(Path.GetFileNameWithoutExtension(song))) { @@ -498,24 +486,11 @@ namespace PckStudio.Forms.Editor private void openDataFolderToolStripMenuItem_Click(object sender, EventArgs e) { - if (!parent.CreateDataFolder()) - return; - Process.Start("explorer.exe", parent.GetDataPath()); - } - - private void AudioEditor_Shown(object sender, EventArgs e) - { - if (Owner.Owner is MainForm p) - parent = p; - else - Close(); + //Process.Start("explorer.exe", parent.GetDataPath()); } private async void bulkReplaceExistingFilesToolStripMenuItem_Click(object sender, EventArgs e) { - if (!parent.CreateDataFolder()) - return; - int exitCode = 0; @@ -540,7 +515,7 @@ namespace PckStudio.Forms.Editor { string song_name = Path.GetFileNameWithoutExtension(file); string file_ext = Path.GetExtension(file).ToLower(); - string new_loc = Path.Combine(parent.GetDataPath(), Path.GetFileNameWithoutExtension(file) + ".binka"); + string new_loc = Path.Combine(Path.GetFileNameWithoutExtension(file) + ".binka"); if (!totalSongList.Contains(song_name) || file == new_loc) continue; @@ -566,7 +541,7 @@ namespace PckStudio.Forms.Editor continue; } else if(file_ext == ".binka") - File.Copy(file, Path.Combine(parent.GetDataPath(), Path.GetFileName(file))); + File.Copy(file, Path.Combine(Path.GetFileName(file))); } } @@ -574,7 +549,7 @@ namespace PckStudio.Forms.Editor { if (treeView2.SelectedNode != null && treeView1.SelectedNode.Tag is PckAudioFile.AudioCategory) { - Binka.ToWav(Path.Combine(parent.GetDataPath(), treeView2.SelectedNode.Text + ".binka"), Path.Combine(parent.GetDataPath())); + //Binka.ToWav(Path.Combine(treeView2.SelectedNode.Text + ".binka"), Path.Combine(parent.GetDataPath())); } } @@ -593,7 +568,7 @@ namespace PckStudio.Forms.Editor EditorValue.RemoveCategory(category.AudioType); - EditorValue.AddCategory(category.AudioType == PckAudioFile.AudioCategory.EAudioType.Overworld && playOverworldInCreative.Checked ? "include_overworld" : "", GetCategoryId(add.SelectedItem), category.ParameterType); + EditorValue.AddCategory(category.AudioType == PckAudioFile.Category.Overworld && playOverworldInCreative.Checked ? "include_overworld" : "", GetCategoryId(add.SelectedItem), category.ParameterType); PckAudioFile.AudioCategory newCategory = EditorValue.GetCategory(GetCategoryId(add.SelectedItem)); @@ -611,16 +586,16 @@ namespace PckStudio.Forms.Editor { if(MessageBox.Show(this, "This function will move all binka files in the \"Data\" folder into a \"Music\" folder, to keep your data better organized. Would you like to continue?", "Move tracks?", MessageBoxButtons.YesNo) == DialogResult.Yes) { - if (treeView1.Nodes.Count < 1 || !parent.CreateDataFolder()) + if (treeView1.Nodes.Count < 1) return; - string musicdir = Path.Combine(parent.GetDataPath(), "Music"); + string musicdir = Path.Combine("Music"); Directory.CreateDirectory(musicdir); foreach (PckAudioFile.AudioCategory category in EditorValue.Categories) { for (var i = 0; i < category.SongNames.Count; i++) // using standard for loop so the list can be modified { string song = category.SongNames[i]; - string songpath = Path.Combine(parent.GetDataPath(), song + ".binka"); + string songpath = Path.Combine(song + ".binka"); string new_path = Path.Combine(musicdir, Path.GetFileName(song) + ".binka"); if (File.Exists(songpath) && !File.Exists(new_path)) { diff --git a/PCK-Studio/Forms/Editor/AudioEditor.resx b/PCK-Studio/Forms/Editor/AudioEditor.resx index cad5e9bf..1b6a7194 100644 --- a/PCK-Studio/Forms/Editor/AudioEditor.resx +++ b/PCK-Studio/Forms/Editor/AudioEditor.resx @@ -125,32 +125,6 @@ 127, 8 - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMkMEa+wAAABSSURBVDhP5c0x - DsAgDENRxt7/wmkNSpRGf0CCCZAegxNMM7MlGMp3dIU6dxhKf/QMNxRogeQC8ivw5Vn7C0heJlFA+kL5 - jWAohxRkde4wnGftBS90axNmphIGAAAAAElFTkSuQmCC - - - - 168, 22 - - - Add Category - - - 168, 22 - - - Remove Category - - - 168, 22 - - - Set Category - 169, 70 @@ -172,7 +146,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACK - NAAAAk1TRnQBSQFMAgEBCQEAAegBAAHoAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA + NAAAAk1TRnQBSQFMAgEBCQEAAfABAAHwAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA AwABMAMAAQEBAAEgBgABMBIAATkBXgFzAf8BOQFeAXMB/wE5AV4BcwH/AT4BYgF8Af8BMwFUAWkB/wEz AVQBaQH/AT4BYgF8Af8BMwFUAWkB/wE5AV4BcwH/ATkBXgFzAf8BOQFeAXMB/wEzAVQBaQH/ASYBPQFM Af8BMwFUAWkB/wEzAVQBaQH/ATkBXgFzAf/AAAFiAZgBvAH/AWIBmAG8Af8BTQGEAZ8B/wFNAYQBnwH/ @@ -426,12 +400,68 @@ 5 + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMkMEa+wAAABSSURBVDhP5c0x + DsAgDENRxt7/wmkNSpRGf0CCCZAegxNMM7MlGMp3dIU6dxhKf/QMNxRogeQC8ivw5Vn7C0heJlFA+kL5 + jWAohxRkde4wnGftBS90axNmphIGAAAAAElFTkSuQmCC + + + + 168, 22 + + + Add Category + + + 168, 22 + + + Remove Category + + + 168, 22 + + + Set Category + 19, 8 False + + 0, 0 + + + 450, 24 + + + 11 + + + menuStrip1 + + + menuStrip + + + System.Windows.Forms.MenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 7 + + + 37, 20 + + + File + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO @@ -448,11 +478,11 @@ Save - - 37, 20 + + 46, 20 - - File + + Tools 220, 22 @@ -478,11 +508,11 @@ Organize Tracks - - 46, 20 + + 44, 20 - - Tools + + Help 243, 22 @@ -514,42 +544,42 @@ BINKA Compression - - 44, 20 - - - Help - - - 0, 0 - - - 450, 24 - - - 11 - - - menuStrip1 - - - menuStrip - - - System.Windows.Forms.MenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 7 - Top, Bottom, Left, Right 282, 8 + + 174, 92 + + + contextMenuStrip2 + + + System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 151, 84 + + + 279, 208 + + + 13 + + + treeView2 + + + System.Windows.Forms.TreeView, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 6 + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO @@ -582,36 +612,6 @@ Convert To WAV - - 174, 92 - - - contextMenuStrip2 - - - System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 151, 84 - - - 279, 208 - - - 13 - - - treeView2 - - - System.Windows.Forms.TreeView, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 6 - True @@ -649,7 +649,7 @@ 310, 298 - 120, 20 + 120, 16 15 diff --git a/PCK-Studio/Forms/Editor/BoxEditor.cs b/PCK-Studio/Forms/Editor/BoxEditor.cs index c0639487..8eed7352 100644 --- a/PCK-Studio/Forms/Editor/BoxEditor.cs +++ b/PCK-Studio/Forms/Editor/BoxEditor.cs @@ -32,22 +32,22 @@ namespace PckStudio.Forms.Editor inflationUpDown.Enabled = hasInflation; parentComboBox.SelectedIndex = parentComboBox.Items.IndexOf(box.Type); - PosXUpDown.Value = (decimal)box.Pos.X; - PosYUpDown.Value = (decimal)box.Pos.Y; - PosZUpDown.Value = (decimal)box.Pos.Z; + PosXUpDown.Value = (decimal)box.Position.X; + PosYUpDown.Value = (decimal)box.Position.Y; + PosZUpDown.Value = (decimal)box.Position.Z; SizeXUpDown.Value = (decimal)box.Size.X; SizeYUpDown.Value = (decimal)box.Size.Y; SizeZUpDown.Value = (decimal)box.Size.Z; - uvXUpDown.Value = (decimal)box.UV.X; - uvYUpDown.Value = (decimal)box.UV.Y; + uvXUpDown.Value = (decimal)box.Uv.X; + uvYUpDown.Value = (decimal)box.Uv.Y; boxVisibilityComboBox.SelectedItem = Enum.GetName(typeof(SkinBOX.BoxVisibility), box.Visibility); mirrorCheckBox.Checked = box.Mirror; - inflationUpDown.Value = (decimal)box.Scale; + inflationUpDown.Value = (decimal)box.Inflate; } private void saveButton_Click(object sender, EventArgs e) { - SkinBOX.BoxVisibility visibility = Enum.TryParse(boxVisibilityComboBox.SelectedItem.ToString(), out SkinBOX.BoxVisibility v) ? v : default; + SkinBOX.BoxVisibility visibility = Enum.TryParse(boxVisibilityComboBox.SelectedItem?.ToString(), out SkinBOX.BoxVisibility v) ? v : default; Vector3 pos = new Vector3((float)PosXUpDown.Value, (float)PosYUpDown.Value, (float)PosZUpDown.Value); Vector3 size = new Vector3((float)SizeXUpDown.Value, (float)SizeYUpDown.Value, (float)SizeZUpDown.Value); Vector2 uv = new Vector2((int)uvXUpDown.Value, (int)uvYUpDown.Value); diff --git a/PCK-Studio/Forms/Editor/COLEditor.Designer.cs b/PCK-Studio/Forms/Editor/COLEditor.Designer.cs index d492f60e..32a51fea 100644 --- a/PCK-Studio/Forms/Editor/COLEditor.Designer.cs +++ b/PCK-Studio/Forms/Editor/COLEditor.Designer.cs @@ -34,8 +34,7 @@ namespace PckStudio.Forms.Editor this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(COLEditor)); this.metroPanel1 = new MetroFramework.Controls.MetroPanel(); - this.metroTextBox1 = new MetroFramework.Controls.MetroTextBox(); - this.metroLabel2 = new MetroFramework.Controls.MetroLabel(); + this.filterPrompt = new PckStudio.Forms.Additional_Popups.Animation.FilterPrompt(); this.setColorBtn = new MetroFramework.Controls.MetroButton(); this.blueUpDown = new System.Windows.Forms.NumericUpDown(); this.greenUpDown = new System.Windows.Forms.NumericUpDown(); @@ -67,21 +66,14 @@ namespace PckStudio.Forms.Editor this.TU54ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.TU69ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this._1_9_1ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.waterTab = new System.Windows.Forms.TabPage(); - this.waterTreeView = new System.Windows.Forms.TreeView(); + this.viewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.compactViewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ColorContextMenu = new MetroFramework.Controls.MetroContextMenu(this.components); this.copyColorToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.pasteColorToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.restoreOriginalColorToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.addColorToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.removeColorToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.underwaterTreeView = new System.Windows.Forms.TreeView(); - this.fogTreeView = new System.Windows.Forms.TreeView(); - this.colorsTab = new System.Windows.Forms.TabPage(); - this.colorTreeView = new System.Windows.Forms.TreeView(); - this.tabControl = new MetroFramework.Controls.MetroTabControl(); - this.underwaterTab = new System.Windows.Forms.TabPage(); - this.fogTab = new System.Windows.Forms.TabPage(); this.metroPanel1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.blueUpDown)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.greenUpDown)).BeginInit(); @@ -89,18 +81,12 @@ namespace PckStudio.Forms.Editor ((System.ComponentModel.ISupportInitialize)(this.alphaUpDown)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); this.menuStrip.SuspendLayout(); - this.waterTab.SuspendLayout(); this.ColorContextMenu.SuspendLayout(); - this.colorsTab.SuspendLayout(); - this.tabControl.SuspendLayout(); - this.underwaterTab.SuspendLayout(); - this.fogTab.SuspendLayout(); this.SuspendLayout(); // // metroPanel1 // - this.metroPanel1.Controls.Add(this.metroTextBox1); - this.metroPanel1.Controls.Add(this.metroLabel2); + this.metroPanel1.Controls.Add(this.filterPrompt); this.metroPanel1.Controls.Add(this.setColorBtn); this.metroPanel1.Controls.Add(this.blueUpDown); this.metroPanel1.Controls.Add(this.greenUpDown); @@ -124,41 +110,13 @@ namespace PckStudio.Forms.Editor this.metroPanel1.VerticalScrollbarHighlightOnWheel = false; this.metroPanel1.VerticalScrollbarSize = 10; // - // metroTextBox1 + // filterPrompt // - // - // - // - this.metroTextBox1.CustomButton.Image = ((System.Drawing.Image)(resources.GetObject("resource.Image"))); - this.metroTextBox1.CustomButton.Location = ((System.Drawing.Point)(resources.GetObject("resource.Location"))); - this.metroTextBox1.CustomButton.Name = ""; - this.metroTextBox1.CustomButton.Size = ((System.Drawing.Size)(resources.GetObject("resource.Size"))); - this.metroTextBox1.CustomButton.Style = MetroFramework.MetroColorStyle.Blue; - this.metroTextBox1.CustomButton.TabIndex = ((int)(resources.GetObject("resource.TabIndex"))); - this.metroTextBox1.CustomButton.Theme = MetroFramework.MetroThemeStyle.Light; - this.metroTextBox1.CustomButton.UseSelectable = true; - this.metroTextBox1.CustomButton.Visible = ((bool)(resources.GetObject("resource.Visible"))); - this.metroTextBox1.Lines = new string[0]; - resources.ApplyResources(this.metroTextBox1, "metroTextBox1"); - this.metroTextBox1.MaxLength = 32767; - this.metroTextBox1.Name = "metroTextBox1"; - this.metroTextBox1.PasswordChar = '\0'; - this.metroTextBox1.ScrollBars = System.Windows.Forms.ScrollBars.None; - this.metroTextBox1.SelectedText = ""; - this.metroTextBox1.SelectionLength = 0; - this.metroTextBox1.SelectionStart = 0; - this.metroTextBox1.ShortcutsEnabled = true; - this.metroTextBox1.Theme = MetroFramework.MetroThemeStyle.Dark; - this.metroTextBox1.UseSelectable = true; - this.metroTextBox1.WaterMarkColor = System.Drawing.Color.FromArgb(((int)(((byte)(109)))), ((int)(((byte)(109)))), ((int)(((byte)(109))))); - this.metroTextBox1.WaterMarkFont = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Pixel); - this.metroTextBox1.TextChanged += new System.EventHandler(this.metroTextBox1_TextChanged); - // - // metroLabel2 - // - resources.ApplyResources(this.metroLabel2, "metroLabel2"); - this.metroLabel2.Name = "metroLabel2"; - this.metroLabel2.Theme = MetroFramework.MetroThemeStyle.Dark; + this.filterPrompt.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(18)))), ((int)(((byte)(18))))); + this.filterPrompt.ForeColor = System.Drawing.SystemColors.Control; + resources.ApplyResources(this.filterPrompt, "filterPrompt"); + this.filterPrompt.Name = "filterPrompt"; + this.filterPrompt.OnSelectedItemChanged += new System.EventHandler(this.filterPrompt_OnSelectedItemChanged); // // setColorBtn // @@ -247,16 +205,16 @@ namespace PckStudio.Forms.Editor // // // - this.colorTextbox.CustomButton.Image = ((System.Drawing.Image)(resources.GetObject("resource.Image1"))); + this.colorTextbox.CustomButton.Image = ((System.Drawing.Image)(resources.GetObject("resource.Image"))); this.colorTextbox.CustomButton.ImeMode = ((System.Windows.Forms.ImeMode)(resources.GetObject("resource.ImeMode"))); - this.colorTextbox.CustomButton.Location = ((System.Drawing.Point)(resources.GetObject("resource.Location1"))); + this.colorTextbox.CustomButton.Location = ((System.Drawing.Point)(resources.GetObject("resource.Location"))); this.colorTextbox.CustomButton.Name = ""; - this.colorTextbox.CustomButton.Size = ((System.Drawing.Size)(resources.GetObject("resource.Size1"))); + this.colorTextbox.CustomButton.Size = ((System.Drawing.Size)(resources.GetObject("resource.Size"))); this.colorTextbox.CustomButton.Style = MetroFramework.MetroColorStyle.Blue; - this.colorTextbox.CustomButton.TabIndex = ((int)(resources.GetObject("resource.TabIndex1"))); + this.colorTextbox.CustomButton.TabIndex = ((int)(resources.GetObject("resource.TabIndex"))); this.colorTextbox.CustomButton.Theme = MetroFramework.MetroThemeStyle.Light; this.colorTextbox.CustomButton.UseSelectable = true; - this.colorTextbox.CustomButton.Visible = ((bool)(resources.GetObject("resource.Visible1"))); + this.colorTextbox.CustomButton.Visible = ((bool)(resources.GetObject("resource.Visible"))); this.colorTextbox.Lines = new string[0]; resources.ApplyResources(this.colorTextbox, "colorTextbox"); this.colorTextbox.MaxLength = 6; @@ -293,7 +251,8 @@ namespace PckStudio.Forms.Editor this.menuStrip.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.fileToolStripMenuItem, - this.toolsToolStripMenuItem}); + this.toolsToolStripMenuItem, + this.viewToolStripMenuItem}); this.menuStrip.Name = "menuStrip"; // // fileToolStripMenuItem @@ -409,22 +368,21 @@ namespace PckStudio.Forms.Editor this._1_9_1ToolStripMenuItem.Name = "_1_9_1ToolStripMenuItem"; resources.ApplyResources(this._1_9_1ToolStripMenuItem, "_1_9_1ToolStripMenuItem"); // - // waterTab + // viewToolStripMenuItem // - this.waterTab.BackColor = System.Drawing.SystemColors.WindowFrame; - this.waterTab.Controls.Add(this.waterTreeView); - resources.ApplyResources(this.waterTab, "waterTab"); - this.waterTab.Name = "waterTab"; + this.viewToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.compactViewToolStripMenuItem}); + this.viewToolStripMenuItem.ForeColor = System.Drawing.Color.White; + this.viewToolStripMenuItem.Name = "viewToolStripMenuItem"; + resources.ApplyResources(this.viewToolStripMenuItem, "viewToolStripMenuItem"); // - // waterTreeView + // compactViewToolStripMenuItem // - this.waterTreeView.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); - this.waterTreeView.ContextMenuStrip = this.ColorContextMenu; - resources.ApplyResources(this.waterTreeView, "waterTreeView"); - this.waterTreeView.ForeColor = System.Drawing.Color.White; - this.waterTreeView.Name = "waterTreeView"; - this.waterTreeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView2_AfterSelect); - this.waterTreeView.KeyDown += new System.Windows.Forms.KeyEventHandler(this.treeView2_KeyDown); + this.compactViewToolStripMenuItem.BackColor = System.Drawing.SystemColors.Control; + this.compactViewToolStripMenuItem.CheckOnClick = true; + this.compactViewToolStripMenuItem.Name = "compactViewToolStripMenuItem"; + resources.ApplyResources(this.compactViewToolStripMenuItem, "compactViewToolStripMenuItem"); + this.compactViewToolStripMenuItem.CheckStateChanged += new System.EventHandler(this.compactViewToolStripMenuItem_CheckStateChanged); // // ColorContextMenu // @@ -472,76 +430,11 @@ namespace PckStudio.Forms.Editor resources.ApplyResources(this.removeColorToolStripMenuItem, "removeColorToolStripMenuItem"); this.removeColorToolStripMenuItem.Click += new System.EventHandler(this.removeColorToolStripMenuItem_Click); // - // underwaterTreeView - // - this.underwaterTreeView.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); - this.underwaterTreeView.ContextMenuStrip = this.ColorContextMenu; - this.underwaterTreeView.ForeColor = System.Drawing.Color.White; - resources.ApplyResources(this.underwaterTreeView, "underwaterTreeView"); - this.underwaterTreeView.Name = "underwaterTreeView"; - this.underwaterTreeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView3_AfterSelect); - this.underwaterTreeView.KeyDown += new System.Windows.Forms.KeyEventHandler(this.treeView3_KeyDown); - // - // fogTreeView - // - this.fogTreeView.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); - this.fogTreeView.ContextMenuStrip = this.ColorContextMenu; - this.fogTreeView.ForeColor = System.Drawing.Color.White; - resources.ApplyResources(this.fogTreeView, "fogTreeView"); - this.fogTreeView.Name = "fogTreeView"; - this.fogTreeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView4_AfterSelect); - this.fogTreeView.KeyDown += new System.Windows.Forms.KeyEventHandler(this.treeView4_KeyDown); - // - // colorsTab - // - this.colorsTab.BackColor = System.Drawing.SystemColors.WindowFrame; - this.colorsTab.Controls.Add(this.colorTreeView); - resources.ApplyResources(this.colorsTab, "colorsTab"); - this.colorsTab.Name = "colorsTab"; - // - // colorTreeView - // - this.colorTreeView.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); - this.colorTreeView.ContextMenuStrip = this.ColorContextMenu; - resources.ApplyResources(this.colorTreeView, "colorTreeView"); - this.colorTreeView.ForeColor = System.Drawing.Color.White; - this.colorTreeView.Name = "colorTreeView"; - this.colorTreeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterSelect); - this.colorTreeView.KeyDown += new System.Windows.Forms.KeyEventHandler(this.treeView1_KeyDown); - // - // tabControl - // - resources.ApplyResources(this.tabControl, "tabControl"); - this.tabControl.Controls.Add(this.colorsTab); - this.tabControl.Controls.Add(this.waterTab); - this.tabControl.Controls.Add(this.underwaterTab); - this.tabControl.Controls.Add(this.fogTab); - this.tabControl.Name = "tabControl"; - this.tabControl.SelectedIndex = 0; - this.tabControl.Style = MetroFramework.MetroColorStyle.White; - this.tabControl.Theme = MetroFramework.MetroThemeStyle.Dark; - this.tabControl.UseSelectable = true; - // - // underwaterTab - // - this.underwaterTab.BackColor = System.Drawing.SystemColors.WindowFrame; - this.underwaterTab.Controls.Add(this.underwaterTreeView); - resources.ApplyResources(this.underwaterTab, "underwaterTab"); - this.underwaterTab.Name = "underwaterTab"; - // - // fogTab - // - this.fogTab.BackColor = System.Drawing.SystemColors.WindowFrame; - this.fogTab.Controls.Add(this.fogTreeView); - resources.ApplyResources(this.fogTab, "fogTab"); - this.fogTab.Name = "fogTab"; - // // COLEditor // resources.ApplyResources(this, "$this"); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.menuStrip); - this.Controls.Add(this.tabControl); this.Controls.Add(this.metroPanel1); this.ForeColor = System.Drawing.SystemColors.ControlText; this.Name = "COLEditor"; @@ -554,12 +447,7 @@ namespace PckStudio.Forms.Editor ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); this.menuStrip.ResumeLayout(false); this.menuStrip.PerformLayout(); - this.waterTab.ResumeLayout(false); this.ColorContextMenu.ResumeLayout(false); - this.colorsTab.ResumeLayout(false); - this.tabControl.ResumeLayout(false); - this.underwaterTab.ResumeLayout(false); - this.fogTab.ResumeLayout(false); this.ResumeLayout(false); } @@ -567,10 +455,6 @@ namespace PckStudio.Forms.Editor #endregion private MetroFramework.Controls.MetroPanel metroPanel1; - private TreeView colorTreeView; - private TreeView waterTreeView; - private TreeView fogTreeView; - private TreeView underwaterTreeView; private System.Windows.Forms.PictureBox pictureBox1; private System.Windows.Forms.MenuStrip menuStrip; private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; @@ -580,12 +464,7 @@ namespace PckStudio.Forms.Editor private MetroFramework.Controls.MetroLabel redLabel; private MetroFramework.Controls.MetroLabel alphaLabel; private System.Windows.Forms.NumericUpDown alphaUpDown; - private TabPage waterTab; - private TabPage colorsTab; - private MetroFramework.Controls.MetroTabControl tabControl; private MetroFramework.Controls.MetroButton setColorBtn; - private TabPage underwaterTab; - private TabPage fogTab; private NumericUpDown blueUpDown; private NumericUpDown greenUpDown; private NumericUpDown redUpDown; @@ -593,8 +472,6 @@ namespace PckStudio.Forms.Editor private MetroFramework.Controls.MetroLabel metroLabel1; private MetroFramework.Controls.MetroContextMenu ColorContextMenu; private ToolStripMenuItem restoreOriginalColorToolStripMenuItem; - private MetroFramework.Controls.MetroTextBox metroTextBox1; - private MetroFramework.Controls.MetroLabel metroLabel2; private ToolStripMenuItem copyColorToolStripMenuItem; private ToolStripMenuItem pasteColorToolStripMenuItem; private ToolStripMenuItem toolsToolStripMenuItem; @@ -615,5 +492,8 @@ namespace PckStudio.Forms.Editor private ToolStripMenuItem stripPS4BiomesToolStripMenuItem; private ToolStripMenuItem addColorToolStripMenuItem; private ToolStripMenuItem removeColorToolStripMenuItem; + private Additional_Popups.Animation.FilterPrompt filterPrompt; + private ToolStripMenuItem viewToolStripMenuItem; + private ToolStripMenuItem compactViewToolStripMenuItem; } } \ No newline at end of file diff --git a/PCK-Studio/Forms/Editor/COLEditor.cs b/PCK-Studio/Forms/Editor/COLEditor.cs index b36c01a7..2a1e2edc 100644 --- a/PCK-Studio/Forms/Editor/COLEditor.cs +++ b/PCK-Studio/Forms/Editor/COLEditor.cs @@ -4,29 +4,28 @@ using System.Drawing; using System.IO; using System.Linq; using System.Windows.Forms; -using MetroFramework.Forms; using OMI.Formats.Color; -using OMI.Formats.Pck; + using OMI.Workers.Color; using PckStudio.Core.Extensions; +using PckStudio.Core.Colors; using PckStudio.Properties; using PckStudio.Controls; using PckStudio.Interfaces; -using System.Collections.ObjectModel; namespace PckStudio.Forms.Editor { - public partial class COLEditor : EditorForm - { - ColorContainer _defaultColourfile; + public partial class COLEditor : EditorForm + { + AbstractColorContainer _defaultColourfile; string _clipboard_color = "#FFFFFF"; - List colorCache = new List(); - List waterCache = new List(); - List underwaterCache = new List(); - List fogCache = new List(); + TreeView colorTreeView; + TreeView waterTreeView; + TreeView underwaterTreeView; + TreeView fogTreeView; - private static readonly ICollection PS4Biomes = new List + private static readonly ICollection PS4BiomeColors = new List { "bamboo_jungle", "bamboo_jungle_hills", @@ -35,624 +34,372 @@ namespace PckStudio.Forms.Editor "mega_taiga_mutated" }; - public COLEditor(ColorContainer colorContainer, ISaveContext saveContext) - : base(colorContainer, saveContext) - { - InitializeComponent(); - - saveToolStripMenuItem1.Visible = !saveContext.AutoSave; - - TU12ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 0); - TU13ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 1); - TU14ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 2); - TU19ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 3); - TU31ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 4); - TU32ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 5); - TU43ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 6); - TU46ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 7); - TU51ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 8); - TU53ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 9); - TU54ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 10); - TU69ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 11); - _1_9_1ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 12); - - SetUpDefaultFile(null, EventArgs.Empty, 11, false); - - colorTreeView.Select(); - colorTreeView.SelectedNode = colorTreeView.Nodes[0]; - } - - private void SetUpDefaultFile(object sender, EventArgs e, int id, bool showMessageBox = true) - { - if (showMessageBox) - { - DialogResult result = MessageBox.Show(this, "This function will set up your colour table to match that of the chosen version. You may lose some entries in the table. Are you sure you would like to continue?", "Target update version?", MessageBoxButtons.YesNo); - if (result == DialogResult.No) - return; - } - - byte[] colorData = id switch - { - 0 => Resources.tu12colours, - 1 => Resources.tu13colours, - 2 => Resources.tu14colours, - 3 => Resources.tu19colours, - 4 => Resources.tu31colours, - 5 => Resources.tu32colours, - 6 => Resources.tu43colours, - 7 => Resources.tu46colours, - 8 => Resources.tu51colours, - 9 => Resources.tu53colours, - 10 => Resources.tu54colours, - 11 => Resources.tu69colours, - 12 => Resources._1_91_colours, - _ => throw new ArgumentOutOfRangeException(nameof(id)), - }; - var reader = new COLFileReader(); - using (var stream = new MemoryStream(colorData)) - { - _defaultColourfile = reader.FromStream(stream); - } - - SetUpTable(showMessageBox); - } - - void AddEntry(TreeView treeView, List cache, string name, object tag) + public COLEditor(AbstractColorContainer colorContainer, ISaveContext saveContext) + : base(colorContainer, saveContext) { - TreeNode tn = new TreeNode(name); - tn.Tag = tag; - treeView.Nodes.Add(tn); - cache.Add(tn); - } + InitializeComponent(); - void RemoveEntry(TreeNode entry, List cache) - { - cache.Remove(entry); - entry.Remove(); + saveToolStripMenuItem1.Visible = !saveContext.AutoSave; + + TU12ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 0); + TU13ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 1); + TU14ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 2); + TU19ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 3); + TU31ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 4); + TU32ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 5); + TU43ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 6); + TU46ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 7); + TU51ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 8); + TU53ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 9); + TU54ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 10); + TU69ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 11); + _1_9_1ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 12); + + colorTreeView = filterPrompt.AddFilterPage("All", null, null); + waterTreeView = filterPrompt.AddFilterPage("Water", null, null); + underwaterTreeView = filterPrompt.AddFilterPage("Underwater", null, null); + fogTreeView = filterPrompt.AddFilterPage("Fog", null, null); + + colorTreeView.KeyDown += treeView1_KeyDown; + waterTreeView.KeyDown += treeView1_KeyDown; + underwaterTreeView.KeyDown += treeView1_KeyDown; + fogTreeView.KeyDown += treeView1_KeyDown; + + colorTreeView.ContextMenuStrip = ColorContextMenu; + waterTreeView.ContextMenuStrip = ColorContextMenu; + underwaterTreeView.ContextMenuStrip = ColorContextMenu; + fogTreeView.ContextMenuStrip = ColorContextMenu; + + BuildTreeViews(EditorValue); } - void SetUpTable(bool targetVersion) - { - colorTreeView.Nodes.Clear(); - waterTreeView.Nodes.Clear(); - underwaterTreeView.Nodes.Clear(); - fogTreeView.Nodes.Clear(); + private void BuildTreeViews(AbstractColorContainer c) + { + colorTreeView.Nodes.Clear(); + waterTreeView.Nodes.Clear(); + underwaterTreeView.Nodes.Clear(); + fogTreeView.Nodes.Clear(); + int nodeDepth = Convert.ToInt32(compactViewToolStripMenuItem.Checked); - ColorContainer temp = targetVersion ? _defaultColourfile : EditorValue; - - List currentEntries = new List(); - - colorCache.Clear(); - fogCache.Clear(); - underwaterCache.Clear(); - waterCache.Clear(); - - // fixes the duplicate entry bug - if (targetVersion) + foreach (KeyValuePair col in c.Colors) { - foreach(ColorContainer.Color col in EditorValue.Colors) - { - if (_defaultColourfile.Colors.Find(c => c.Name == col.Name) == null) - continue; - currentEntries.Add(col.Name); - AddEntry(colorTreeView, colorCache, col.Name, col); - } + TreeNode n = colorTreeView.Nodes.BuildNodeTreeBySeperator(col.Key, '_', nodeDepth); + n.Tag = col; } - foreach (ColorContainer.Color col in temp.Colors) - { - ColorContainer.Color entry = EditorValue.Colors.Find(color => color.Name == col.Name); - if (currentEntries.Contains(col.Name)) - continue; - ColorContainer.Color color = entry ?? col; - AddEntry(colorTreeView, colorCache, color.Name, color); - } - currentEntries.Clear(); + foreach (KeyValuePair col in c.WaterColors) + { + waterTreeView.Nodes.BuildNodeTreeBySeperator(col.Key, '_', 0).Tag = col; + underwaterTreeView.Nodes.BuildNodeTreeBySeperator(col.Key, '_', 0).Tag = col; + fogTreeView.Nodes.BuildNodeTreeBySeperator(col.Key, '_', 0).Tag = col; + } - // fixes the duplicate entry bug - if (targetVersion) - { - foreach (ColorContainer.WaterColor col in EditorValue.WaterColors) - { - if (_defaultColourfile.WaterColors.Find(c => c.Name == col.Name) == null) - continue; - ColorContainer.WaterColor entry = EditorValue.WaterColors.Find(color => color.Name == col.Name); - ColorContainer.WaterColor color = entry ?? col; - AddEntry(waterTreeView, waterCache, color.Name, color); - AddEntry(underwaterTreeView, underwaterCache, color.Name, color); - AddEntry(fogTreeView, fogCache, color.Name, color); - } - } + filterPrompt.Update(); + } - foreach (ColorContainer.WaterColor col in temp.WaterColors) - { - ColorContainer.WaterColor entry = EditorValue.WaterColors.Find(color => color.Name == col.Name); - if (currentEntries.Contains(col.Name)) - continue; - ColorContainer.WaterColor color = entry ?? col; - AddEntry(waterTreeView, waterCache, color.Name, color); - AddEntry(underwaterTreeView, underwaterCache, color.Name, color); - AddEntry(fogTreeView, fogCache, color.Name, color); - } - - // force the filter function to run to carry filter over and fix treeview size - metroTextBox1_TextChanged(null, null); - } - - void SetUpValueChanged(bool add) - { - if(add) - { - redUpDown.ValueChanged += color_ValueChanged; - greenUpDown.ValueChanged += color_ValueChanged; - blueUpDown.ValueChanged += color_ValueChanged; - } - else - { - redUpDown.ValueChanged -= color_ValueChanged; - greenUpDown.ValueChanged -= color_ValueChanged; - blueUpDown.ValueChanged -= color_ValueChanged; - } - } - - private void treeView1_AfterSelect(object sender, TreeViewEventArgs e) - { - if (colorTreeView.SelectedNode.Tag == null) - return; - - addColorToolStripMenuItem.Visible = true; - removeColorToolStripMenuItem.Visible = true; - - waterTreeView.SelectedNode = null; - underwaterTreeView.SelectedNode = null; - fogTreeView.SelectedNode = null; - - var colorEntry = (ColorContainer.Color)colorTreeView.SelectedNode.Tag; - Color color = colorEntry.ColorPallette; - SetUpValueChanged(false); - alphaUpDown.Visible = false; - alphaLabel.Visible = false; - redUpDown.Value = color.R; - greenUpDown.Value = color.G; - blueUpDown.Value = color.B; - pictureBox1.BackColor = Color.FromArgb(0xff, color); - colorTextbox.Text = ColorTranslator.ToHtml(colorEntry.ColorPallette).TrimStart('#'); - SetUpValueChanged(true); - } - - private void treeView2_AfterSelect(object sender, TreeViewEventArgs e) + private void SetUpDefaultFile(object sender, EventArgs e, int id, bool showMessageBox = true) { - if (waterTreeView.SelectedNode.Tag == null) - return; + if (showMessageBox) + { + DialogResult result = MessageBox.Show(this, "This function will set up your colour table to match that of the chosen version. You may lose some entries in the table. Are you sure you would like to continue?", "Target update version?", MessageBoxButtons.YesNo); + if (result == DialogResult.No) + return; + } - addColorToolStripMenuItem.Visible = false; - removeColorToolStripMenuItem.Visible = false; + byte[] colorData = id switch + { + 0 => Resources.tu12colours, + 1 => Resources.tu13colours, + 2 => Resources.tu14colours, + 3 => Resources.tu19colours, + 4 => Resources.tu31colours, + 5 => Resources.tu32colours, + 6 => Resources.tu43colours, + 7 => Resources.tu46colours, + 8 => Resources.tu51colours, + 9 => Resources.tu53colours, + 10 => Resources.tu54colours, + 11 => Resources.tu69colours, + 12 => Resources._1_91_colours, + _ => throw new ArgumentOutOfRangeException(nameof(id)), + }; + var reader = new COLFileReader(); + using (var stream = new MemoryStream(colorData)) + { + _defaultColourfile = AbstractColorContainer.FromColorContainer(reader.FromStream(stream)); + } - colorTreeView.SelectedNode = null; - underwaterTreeView.SelectedNode = null; - fogTreeView.SelectedNode = null; + BuildTreeViews(_defaultColourfile); + } - var colorEntry = (ColorContainer.WaterColor)waterTreeView.SelectedNode.Tag; - Color color = colorEntry.SurfaceColor; - SetUpValueChanged(false); - - alphaUpDown.Value = color.A; - redUpDown.Value = color.R; - greenUpDown.Value = color.G; - blueUpDown.Value = color.B; + void SetUpValueChanged(bool add) + { + if (add) + { + redUpDown.ValueChanged += color_ValueChanged; + greenUpDown.ValueChanged += color_ValueChanged; + blueUpDown.ValueChanged += color_ValueChanged; + } + else + { + redUpDown.ValueChanged -= color_ValueChanged; + greenUpDown.ValueChanged -= color_ValueChanged; + blueUpDown.ValueChanged -= color_ValueChanged; + } + } - alphaUpDown.Enabled = true; - alphaUpDown.Visible = true; - alphaLabel.Visible = true; - pictureBox1.BackColor = colorEntry.SurfaceColor; - colorTextbox.Text = ColorTranslator.ToHtml(colorEntry.SurfaceColor).TrimStart('#'); - SetUpValueChanged(true); - } - - private void treeView3_AfterSelect(object sender, TreeViewEventArgs e) - { - if (underwaterTreeView.SelectedNode.Tag == null) - return; - - addColorToolStripMenuItem.Visible = false; - removeColorToolStripMenuItem.Visible = false; - - colorTreeView.SelectedNode = null; - waterTreeView.SelectedNode = null; - fogTreeView.SelectedNode = null; - - var colorEntry = (ColorContainer.WaterColor)underwaterTreeView.SelectedNode.Tag; - Color color = colorEntry.UnderwaterColor; - SetUpValueChanged(false); - alphaUpDown.Visible = false; - alphaLabel.Visible = false; - redUpDown.Value = color.R; - greenUpDown.Value = color.G; - blueUpDown.Value = color.B; - pictureBox1.BackColor = Color.FromArgb(0xff, color); - colorTextbox.Text = ColorTranslator.ToHtml(colorEntry.UnderwaterColor).TrimStart('#'); - SetUpValueChanged(true); - } - - private void treeView4_AfterSelect(object sender, TreeViewEventArgs e) - { - if (fogTreeView.SelectedNode.Tag == null) - return; - - addColorToolStripMenuItem.Visible = false; - removeColorToolStripMenuItem.Visible = false; - - colorTreeView.SelectedNode = null; - waterTreeView.SelectedNode = null; - underwaterTreeView.SelectedNode = null; - - var colorEntry = (ColorContainer.WaterColor)fogTreeView.SelectedNode.Tag; - Color color = colorEntry.FogColor; - SetUpValueChanged(false); - alphaUpDown.Visible = false; - alphaLabel.Visible = false; - redUpDown.Value = color.R; - greenUpDown.Value = color.G; - blueUpDown.Value = color.B; - pictureBox1.BackColor = Color.FromArgb(0xff, color); - colorTextbox.Text = ColorTranslator.ToHtml(colorEntry.FogColor).TrimStart('#'); - SetUpValueChanged(true); - } - - private void saveToolStripMenuItem1_Click(object sender, EventArgs e) - { - Save(); + private void saveToolStripMenuItem1_Click(object sender, EventArgs e) + { + Save(); DialogResult = DialogResult.OK; } - public void treeView1_KeyDown(object sender, KeyEventArgs e) - { - TreeNode node = colorTreeView.SelectedNode; - if (e.KeyCode == Keys.Delete && node.Tag is ColorContainer.Color) - { - restoreOriginalColorToolStripMenuItem_Click(sender, e); - } - else if (e.Control && e.KeyCode == Keys.C && node.Tag is ColorContainer.Color) - { - copyColorToolStripMenuItem_Click(sender, e); - } - else if (e.Control && e.KeyCode == Keys.V && node.Tag is ColorContainer.Color) - { - pasteColorToolStripMenuItem_Click(sender, e); - } - } - - private void treeView2_KeyDown(object sender, KeyEventArgs e) + public void treeView1_KeyDown(object sender, KeyEventArgs e) { - TreeNode node = waterTreeView.SelectedNode; - if (e.KeyCode == Keys.Delete && node.Tag is ColorContainer.WaterColor) - { - restoreOriginalColorToolStripMenuItem_Click(sender, e); - } - else if (e.Control && e.KeyCode == Keys.C && node.Tag is ColorContainer.WaterColor) - { - copyColorToolStripMenuItem_Click(sender, e); - } - else if (e.Control && e.KeyCode == Keys.V && node.Tag is ColorContainer.WaterColor) - { - pasteColorToolStripMenuItem_Click(sender, e); - } - } - - private void treeView3_KeyDown(object sender, KeyEventArgs e) - { - TreeNode node = underwaterTreeView.SelectedNode; - if (e.KeyCode == Keys.Delete && node.Tag is ColorContainer.WaterColor) - { - restoreOriginalColorToolStripMenuItem_Click(sender, e); - } - else if (e.Control && e.KeyCode == Keys.C && node.Tag is ColorContainer.WaterColor) - { - copyColorToolStripMenuItem_Click(sender, e); - } - else if (e.Control && e.KeyCode == Keys.V && node.Tag is ColorContainer.WaterColor) - { - pasteColorToolStripMenuItem_Click(sender, e); - } - } - - private void treeView4_KeyDown(object sender, KeyEventArgs e) - { - TreeNode node = fogTreeView.SelectedNode; - if (e.KeyCode == Keys.Delete && node.Tag is ColorContainer.WaterColor) - { - restoreOriginalColorToolStripMenuItem_Click(sender, e); - } - else if (e.Control && e.KeyCode == Keys.C && node.Tag is ColorContainer.WaterColor) - { - copyColorToolStripMenuItem_Click(sender, e); - } - else if (e.Control && e.KeyCode == Keys.V && node.Tag is ColorContainer.WaterColor) - { - pasteColorToolStripMenuItem_Click(sender, e); - } - } - - public bool IsValidHexString(string value) - { - return System.Text.RegularExpressions.Regex.IsMatch(value, @"\A\b[0-9a-fA-F]+\b\Z") && value.Length == 6; - } - - private void colorBox_TextChanged(object sender, EventArgs e) - { - if(IsValidHexString(colorTextbox.Text)) + if (sender is not TreeView treeView) + return; + TreeNode node = treeView.SelectedNode; + switch (e.KeyCode) { - Color color = ColorTranslator.FromHtml("#" + colorTextbox.Text); - - redUpDown.Value = color.R; - greenUpDown.Value = color.G; - blueUpDown.Value = color.B; + case Keys.Delete: + restoreOriginalColorToolStripMenuItem_Click(sender, e); + break; + case Keys.C when e.Control: + copyColorToolStripMenuItem_Click(sender, e); + break; + case Keys.V when e.Control: + pasteColorToolStripMenuItem_Click(sender, e); + break; + default: + break; } - } - - private void color_ValueChanged(object sender, EventArgs e) - { - Color color = Color.FromArgb(tabControl.SelectedTab == waterTab ? (int)alphaUpDown.Value : 255, (int)redUpDown.Value, (int)greenUpDown.Value, (int)blueUpDown.Value); - - if (tabControl.SelectedTab == colorsTab) - { - var colorEntry = (ColorContainer.Color)colorTreeView.SelectedNode.Tag; - colorEntry.ColorPallette = color; - } - else - { - var waterColorEntry = (tabControl.SelectedTab.Controls[0] as TreeView).SelectedNode.Tag as ColorContainer.WaterColor; - - if (tabControl.SelectedTab == waterTab) - waterColorEntry.SurfaceColor = color; - else if (tabControl.SelectedTab == underwaterTab) - waterColorEntry.UnderwaterColor = color; - else - waterColorEntry.FogColor = color; - } - - pictureBox1.BackColor = color; - colorTextbox.Text = ColorTranslator.ToHtml(color).TrimStart('#'); - } - - private void setColorBtn_Click(object sender, EventArgs e) - { - ColorDialog colorPick = new ColorDialog(); - colorPick.AllowFullOpen = true; - colorPick.AnyColor = true; - colorPick.SolidColorOnly = tabControl.SelectedTab == colorsTab; - if (colorPick.ShowDialog(this) != DialogResult.OK) - return; - pictureBox1.BackColor = colorPick.Color; - if (tabControl.SelectedTab == waterTab && waterTreeView.SelectedNode != null && - waterTreeView.SelectedNode.Tag != null && waterTreeView.SelectedNode.Tag is ColorContainer.WaterColor) - { - var colorEntry = (ColorContainer.WaterColor)waterTreeView.SelectedNode.Tag; - // preserves the alpha so the user can handle it since the color picker doesn't support alpha - pictureBox1.BackColor = colorEntry.SurfaceColor = Color.FromArgb(colorEntry.SurfaceColor.A, colorPick.Color); - redUpDown.Value = colorPick.Color.R; - greenUpDown.Value = colorPick.Color.G; - blueUpDown.Value = colorPick.Color.B; - } - else if (tabControl.SelectedTab == underwaterTab && underwaterTreeView.SelectedNode != null && - underwaterTreeView.SelectedNode.Tag != null && underwaterTreeView.SelectedNode.Tag is ColorContainer.WaterColor) - { - var colorEntry = (ColorContainer.WaterColor)underwaterTreeView.SelectedNode.Tag; - // the game doesn't care about the alpha value for underwater colors - colorEntry.UnderwaterColor = Color.FromArgb(0, colorPick.Color); - redUpDown.Value = colorPick.Color.R; - greenUpDown.Value = colorPick.Color.G; - blueUpDown.Value = colorPick.Color.B; - } - else if (tabControl.SelectedTab == fogTab && fogTreeView.SelectedNode != null && - fogTreeView.SelectedNode.Tag != null && fogTreeView.SelectedNode.Tag is ColorContainer.WaterColor) - { - var colorEntry = (ColorContainer.WaterColor)fogTreeView.SelectedNode.Tag; - // the game doesn't care about the alpha value for fog colors - colorEntry.FogColor = Color.FromArgb(0, colorPick.Color); - redUpDown.Value = colorPick.Color.R; - greenUpDown.Value = colorPick.Color.G; - blueUpDown.Value = colorPick.Color.B; - } - else if (tabControl.SelectedTab == colorsTab && colorTreeView.SelectedNode != null && - colorTreeView.SelectedNode.Tag != null && colorTreeView.SelectedNode.Tag is ColorContainer.Color) - { - var colorEntry = (ColorContainer.Color)colorTreeView.SelectedNode.Tag; - colorEntry.ColorPallette = colorPick.Color; - redUpDown.Value = colorPick.Color.R; - greenUpDown.Value = colorPick.Color.G; - blueUpDown.Value = colorPick.Color.B; - } - colorPick.Dispose(); } - private void alpha_ValueChanged(object sender, EventArgs e) - { - var colorEntry = (ColorContainer.WaterColor)waterTreeView.SelectedNode.Tag; - pictureBox1.BackColor = colorEntry.SurfaceColor = Color.FromArgb((int)alphaUpDown.Value, colorEntry.SurfaceColor); - } - - private void restoreOriginalColorToolStripMenuItem_Click(object sender, EventArgs e) - { - if(tabControl.SelectedTab is var tab && tab != null) + private void colorBox_TextChanged(object sender, EventArgs e) + { + if (IsValidHexColor(colorTextbox.Text) && int.TryParse(colorTextbox.Text, System.Globalization.NumberStyles.HexNumber, null, out int argbColor)) { - TreeNode node = (tabControl.SelectedTab.Controls[0] as TreeView).SelectedNode; + SetColor(Color.FromArgb(argbColor)); + } + } - Color color = Color.Empty; + private void color_ValueChanged(object sender, EventArgs e) + { + Color color = Color.FromArgb(filterPrompt.SelectedTabIndex == 1 ? (int)alphaUpDown.Value : 255, (int)redUpDown.Value, (int)greenUpDown.Value, (int)blueUpDown.Value); - if (tab == colorsTab) + if (filterPrompt.SelectedTabIndex == 0 && filterPrompt.SelectedItem is KeyValuePair colorEntry) + { + EditorValue.Colors[colorEntry.Key] = color; + } + else if (filterPrompt.SelectedItem is KeyValuePair waterColorEntry) + { + if (filterPrompt.SelectedTabIndex == 1) + EditorValue.WaterColors[waterColorEntry.Key] = (color, waterColorEntry.Value.Underwater, waterColorEntry.Value.Fog); + else if (filterPrompt.SelectedTabIndex == 2) + EditorValue.WaterColors[waterColorEntry.Key] = (waterColorEntry.Value.Surface, color, waterColorEntry.Value.Fog); + else + EditorValue.WaterColors[waterColorEntry.Key] = (waterColorEntry.Value.Surface, waterColorEntry.Value.Underwater, color); + } + + pictureBox1.BackColor = color; + colorTextbox.Text = color.ToArgb().ToString("X06"); + } + + private void setColorBtn_Click(object sender, EventArgs e) + { + using ColorDialog colorPick = new ColorDialog(); + colorPick.AllowFullOpen = true; + colorPick.AnyColor = true; + colorPick.SolidColorOnly = filterPrompt.SelectedTabIndex == 0; + if (colorPick.ShowDialog(this) != DialogResult.OK) + return; + if (filterPrompt.SelectedTabIndex == 0 && filterPrompt.SelectedItem is ColorContainer.Color color) + { + color.ColorPallette = colorPick.Color; + SetColor(color.ColorPallette); + return; + } + if (filterPrompt.SelectedItem is KeyValuePair waterColorEntry) + { + Color wColor = + filterPrompt.SelectedTabIndex == 1 ? waterColorEntry.Value.Surface : + filterPrompt.SelectedTabIndex == 2 ? waterColorEntry.Value.Underwater : waterColorEntry.Value.Fog; + if (filterPrompt.SelectedTabIndex == 1) + EditorValue.WaterColors[waterColorEntry.Key] = (wColor, waterColorEntry.Value.Underwater, waterColorEntry.Value.Fog); + else if (filterPrompt.SelectedTabIndex == 2) + EditorValue.WaterColors[waterColorEntry.Key] = (waterColorEntry.Value.Surface, wColor, waterColorEntry.Value.Fog); + else + EditorValue.WaterColors[waterColorEntry.Key] = (waterColorEntry.Value.Surface, waterColorEntry.Value.Underwater, wColor); + } + } + + private void alpha_ValueChanged(object sender, EventArgs e) + { + var colorEntry = (KeyValuePair)waterTreeView.SelectedNode.Tag; + EditorValue.WaterColors[colorEntry.Key] = colorEntry.Value; + pictureBox1.BackColor = Color.FromArgb((int)alphaUpDown.Value, colorEntry.Value.Surface); + } + + private void restoreOriginalColorToolStripMenuItem_Click(object sender, EventArgs e) + { + if (filterPrompt.SelectedItem is KeyValuePair color) + { + if (!_defaultColourfile.Colors.TryGetValue(color.Key, out Color col_entry)) { - ColorContainer.Color col_entry = _defaultColourfile.Colors.Find(color => color.Name == node.Text); - - if (col_entry == null) - return; - - color = col_entry.ColorPallette; - - colorTextbox.Text = ColorTranslator.ToHtml(color).TrimStart('#'); - } - else + HideColorEdit(); + return; + } + EditorValue.Colors[color.Key] = col_entry; + SetColor(col_entry); + } + if (filterPrompt.SelectedItem is KeyValuePair waterColor) + { + if (_defaultColourfile.WaterColors.TryGetValue(waterColor.Key, out (Color Surface, Color Underwater, Color Fog) waterColorEntry)) { - ColorContainer.WaterColor waterEntry = _defaultColourfile.WaterColors.Find(color => color.Name == node.Text); + HideColorEdit(); + return; + } - if (waterEntry == null) - return; + Color wColor = + filterPrompt.SelectedTabIndex == 1 ? waterColorEntry.Surface : + filterPrompt.SelectedTabIndex == 2 ? waterColorEntry.Underwater: waterColorEntry.Fog; + if (filterPrompt.SelectedTabIndex == 1) + EditorValue.WaterColors[waterColor.Key] = (wColor, waterColorEntry.Underwater, waterColorEntry.Fog); + else if (filterPrompt.SelectedTabIndex == 2) + EditorValue.WaterColors[waterColor.Key] = (waterColorEntry.Surface, wColor, waterColorEntry.Fog); + else + EditorValue.WaterColors[waterColor.Key] = (waterColorEntry.Surface, waterColorEntry.Underwater, wColor); + SetColor(wColor); + } + } - color = - tab == waterTab ? waterEntry.SurfaceColor : - tab == underwaterTab ? waterEntry.UnderwaterColor : waterEntry.FogColor; + private void copyColorToolStripMenuItem_Click(object sender, EventArgs e) + { + _clipboard_color = colorTextbox.Text; + Clipboard.SetText(_clipboard_color); + } - if (tab == waterTab) - { - alphaUpDown.Value = color.A; - } - - redUpDown.Value = color.R; - greenUpDown.Value = color.G; - blueUpDown.Value = color.B; - } - pictureBox1.BackColor = Color.FromArgb(tab == colorsTab ? 0xFF : color.A, color); - } - } - - private void metroTextBox1_TextChanged(object sender, EventArgs e) - { - // Some code in this function is modified code from this StackOverflow answer - MattNL - //https://stackoverflow.com/questions/8260322/filter-a-treeview-with-a-textbox-in-a-c-sharp-winforms-app - - //blocks repainting tree until all objects loaded - colorTreeView.BeginUpdate(); - colorTreeView.Nodes.Clear(); - waterTreeView.BeginUpdate(); - waterTreeView.Nodes.Clear(); - underwaterTreeView.BeginUpdate(); - underwaterTreeView.Nodes.Clear(); - fogTreeView.BeginUpdate(); - fogTreeView.Nodes.Clear(); - if (!string.IsNullOrEmpty(metroTextBox1.Text)) - { - foreach (TreeNode node in colorCache) - { - if (node.Text.ToLower().Contains(metroTextBox1.Text.ToLower())) - { - colorTreeView.Nodes.Add((TreeNode)node.Clone()); - } - } - foreach (TreeNode node in waterCache) - { - if (node.Text.ToLower().Contains(metroTextBox1.Text.ToLower())) - { - waterTreeView.Nodes.Add((TreeNode)node.Clone()); - } - } - foreach (TreeNode node in underwaterCache) - { - if (node.Text.ToLower().Contains(metroTextBox1.Text.ToLower())) - { - underwaterTreeView.Nodes.Add((TreeNode)node.Clone()); - } - } - foreach (TreeNode node in fogCache) - { - if (node.Text.ToLower().Contains(metroTextBox1.Text.ToLower())) - { - fogTreeView.Nodes.Add((TreeNode)node.Clone()); - } - } - } - else - { - foreach (TreeNode node in colorCache) - { - colorTreeView.Nodes.Add((TreeNode)node.Clone()); - } - foreach (TreeNode node in waterCache) - { - waterTreeView.Nodes.Add((TreeNode)node.Clone()); - } - foreach (TreeNode node in underwaterCache) - { - underwaterTreeView.Nodes.Add((TreeNode)node.Clone()); - } - foreach (TreeNode node in fogCache) - { - fogTreeView.Nodes.Add((TreeNode)node.Clone()); - } - } - //enables redrawing tree after all objects have been added - colorTreeView.EndUpdate(); - waterTreeView.EndUpdate(); - underwaterTreeView.EndUpdate(); - fogTreeView.EndUpdate(); - } - - private void copyColorToolStripMenuItem_Click(object sender, EventArgs e) - { - _clipboard_color = colorTextbox.Text; - } - - private void pasteColorToolStripMenuItem_Click(object sender, EventArgs e) - { - colorTextbox.Text = _clipboard_color; - } + private void pasteColorToolStripMenuItem_Click(object sender, EventArgs e) + { + colorTextbox.Text = _clipboard_color; + } private void colorTextbox_KeyPress(object sender, KeyPressEventArgs e) { - string hexCheck = "0123456789abcdefABCDEF\b"; + e.Handled = !IsHexChar(e.KeyChar); + } - e.Handled = !hexCheck.Contains(e.KeyChar); - } + enum ColorSpace + { + RGB8, + ARGB8, + } + + private static int GetCharCountForColorSpace(ColorSpace colorSpace) + { + return colorSpace switch + { + ColorSpace.RGB8 => 6, + ColorSpace.ARGB8 => 8, + _ => 0, + }; + } + + private static bool IsHexChar(char c) => char.IsDigit(c) || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'; + private static bool IsValidHexColor(string value, ColorSpace colorSpace = ColorSpace.RGB8) => value.All(IsHexChar) && value.Length == GetCharCountForColorSpace(colorSpace); private void stripPS4BiomesToolStripMenuItem_Click(object sender, EventArgs e) { - if(EditorValue.WaterColors.Count > 0) + foreach (string ps4BiomeColor in PS4BiomeColors) { - foreach (ColorContainer.WaterColor col in EditorValue.WaterColors.ToList()) - { - if (PS4Biomes.Contains(col.Name)) - EditorValue.WaterColors.Remove(col); - } - - SetUpTable(false); - } - } + if (EditorValue.WaterColors.ContainsKey(ps4BiomeColor)) + EditorValue.WaterColors.Remove(ps4BiomeColor); + } + BuildTreeViews(EditorValue); + } private void addColorToolStripMenuItem_Click(object sender, EventArgs e) { - if(tabControl.SelectedTab == colorsTab) - { - using (TextPrompt prompt = new TextPrompt()) - { - prompt.OKButtonText = "Add"; - prompt.contextLabel.Text = "Insert the name of the color you would like to add"; - if(prompt.ShowDialog(this) == DialogResult.OK) - { - ColorContainer.Color entry = new ColorContainer.Color(); - entry.Name = prompt.NewText; - entry.ColorPallette = Color.FromArgb(0xFFFFFF); + if (filterPrompt.SelectedTabIndex == 0) + { + using (TextPrompt prompt = new TextPrompt()) + { + prompt.OKButtonText = "Add"; + prompt.contextLabel.Text = "Insert the name of the color you would like to add"; + if (prompt.ShowDialog(this) == DialogResult.OK) + { + if (EditorValue.Colors.ContainsKey(prompt.Name)) + { + MessageBox.Show(this, $"\"{prompt.Name}\" already exists in this color table", "Color not added"); + } - if(EditorValue.Colors.Find(c => c.Name == entry.Name) != null) - { - MessageBox.Show(this, $"\"{entry.Name}\" already exists in this color table", "Color not added"); - } - - EditorValue.Colors.Add(entry); - AddEntry(colorTreeView, colorCache, entry.Name, entry); + EditorValue.Colors.Add(prompt.Name, Color.White); + BuildTreeViews(EditorValue); } - } - } + } + } } private void removeColorToolStripMenuItem_Click(object sender, EventArgs e) { - if (tabControl.SelectedTab == colorsTab - && colorTreeView.SelectedNode is TreeNode entry - && entry != null - && entry.Tag is ColorContainer.Color color) + if (filterPrompt.SelectedItem is ColorContainer.Color color) { - EditorValue.Colors.Remove(color); - RemoveEntry(entry, colorCache); + EditorValue.Colors.Remove(color.Name); } } + + private void SetColor(Color color) + { + redUpDown.Value = color.R; + greenUpDown.Value = color.G; + blueUpDown.Value = color.B; + + pictureBox1.BackColor = Color.FromArgb(color.A == 0 ? 0xff : color.A, color); + colorTextbox.Text = color.ToArgb().ToString("X06"); + ShowColorEdit(); + alphaUpDown.Visible = color.A != 0; + } + + private void filterPrompt_OnSelectedItemChanged(object sender, EventArgs e) + { + if (filterPrompt.SelectedItem is KeyValuePair col) + { + SetColor(col.Value); + return; + } + if (filterPrompt.SelectedItem is KeyValuePair waterColor) + { + SetColor(waterColor.Value.Surface); + return; + } + HideColorEdit(); + } + + private void HideColorEdit() + { + redUpDown.Visible = false; + greenUpDown.Visible = false; + blueUpDown.Visible = false; + alphaUpDown.Visible = false; + + pictureBox1.Visible = false; + colorTextbox.Visible = false; + } + + private void ShowColorEdit() + { + redUpDown.Visible = true; + greenUpDown.Visible = true; + blueUpDown.Visible = true; + alphaUpDown.Visible = true; + + pictureBox1.Visible = true; + colorTextbox.Visible = true; + } + + private void compactViewToolStripMenuItem_CheckStateChanged(object sender, EventArgs e) + { + BuildTreeViews(EditorValue); + } } } diff --git a/PCK-Studio/Forms/Editor/COLEditor.resx b/PCK-Studio/Forms/Editor/COLEditor.resx index 84e19dd5..8801321e 100644 --- a/PCK-Studio/Forms/Editor/COLEditor.resx +++ b/PCK-Studio/Forms/Editor/COLEditor.resx @@ -117,71 +117,28 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - - 113, 1 + + 12, 34 - - 21, 21 + + 323, 557 - - 0 - - - False - - - 101, 27 - - - 135, 23 - - - 24 - - - metroTextBox1 - - - MetroFramework.Controls.MetroTextBox, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a - - - metroPanel1 - - - 2 - - - True - - - 62, 27 - - - 46, 19 - - + 23 - - Filter: + + filterPrompt - - metroLabel2 + + PckStudio.Forms.Additional_Popups.Animation.FilterPrompt, PCK-Studio, Version=7.0.0.2, Culture=neutral, PublicKeyToken=null - - MetroFramework.Controls.MetroLabel, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a - - + metroPanel1 - - 3 + + 2 400, 290 @@ -205,7 +162,7 @@ metroPanel1 - 4 + 3 400, 397 @@ -226,7 +183,7 @@ metroPanel1 - 5 + 4 400, 371 @@ -247,7 +204,7 @@ metroPanel1 - 6 + 5 400, 345 @@ -268,7 +225,7 @@ metroPanel1 - 7 + 6 400, 319 @@ -292,7 +249,7 @@ metroPanel1 - 8 + 7 True @@ -322,7 +279,7 @@ metroPanel1 - 9 + 8 True @@ -349,7 +306,7 @@ metroPanel1 - 10 + 9 True @@ -376,7 +333,7 @@ metroPanel1 - 11 + 10 True @@ -403,24 +360,25 @@ metroPanel1 - 12 + 11 - + + NoControl - + 103, 1 - + 21, 21 - + 0 - + False @@ -442,7 +400,7 @@ metroPanel1 - 13 + 12 True @@ -469,7 +427,7 @@ metroPanel1 - 14 + 13 378, 92 @@ -490,16 +448,16 @@ metroPanel1 - 15 + 14 Fill - 20, 60 + 0, 0 - 612, 523 + 652, 603 0 @@ -514,7 +472,7 @@ $this - 3 + 2 17, 17 @@ -525,11 +483,11 @@ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4yMfEgaZUAAADdSURBVDhPzZJB - CoJQEIa9jy0iPFAnCDpAtG3ZooUE4b6oVtIuClpJIAgqZEVlKpqEHUAm5pGPmhTbRA18G//5P5iHgvA3 - I7ZniiQ7aVM9QZzcOKYbwVDbw8I6A2YAICBvg2VJdtjSs2Cse1Dt6tCYbliGO0UCFlLBxAj590yA0D4X - 1Ec7CK8JF9j+lUmWzoVlpYJaz4JKZ5ULZqWCT6F9Jhhowcv9eeBOoQBvPXoBrA0zF8yyR6V9LvCjGLYH - NxfMvipIMaQ3Ux6ClPYFsaUq/bmd0rspuIO/Pe3/bu5p+sr3gTvFEQAAAABJRU5ErkJggg== + vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4yMfEgaZUAAADfSURBVDhPYxg8 + QLt++3yTGbf/Fm599P/Nh49wfPXxq/+rTt37f+Dak/8gOSBgAGEMANIMxGBFyAasPf/0v8GE8//z1t8C + y4HU4DIALIluwLpLL+HiMANAGKoNAWASCavv/n/57gPcgOvP3oENOXj7NViOoAFGU6791+k4ghWD5Aga + QCyGakMAkODcU89R/I8Ng9TgNADk14dPn/8/c+kqVgySgwUqVBsCwAx49urN/zsPHmPFIDmaGvAXJInN + 38gYasBfqDYE0K7dOn/Wvut/sfkdGYPUgJI9VNuAAwYGAGn6yvdevWgPAAAAAElFTkSuQmCC @@ -551,79 +509,79 @@ Remove PS4 Biome Colors - 416, 22 + 414, 22 TU12 (360) - 416, 22 + 414, 22 TU13/1.00 (360/PS3) - 416, 22 + 414, 22 TU14/1.04 (360/PS3) - 416, 22 + 414, 22 TU19/1.12/CU7 (360/PS3-4-Vita/XONE) - 416, 22 + 414, 22 TU31/1.22/CU19 (360/PS3-4-Vita/XONE) - 416, 22 + 414, 22 TU32/1.24/CU20/P3 (360/PS3-4-Vita/XONE/WIIU) - 416, 22 + 414, 22 TU43/1.35/CU32/P12 (360/PS3-4-Vita/XONE/WIIU) - 416, 22 + 414, 22 TU46/1.38/CU36/P15 (360/PS3-4-Vita/XONE/WIIU) - 416, 22 + 414, 22 TU51/1.44/CU41/P20 (360/PS3-4-Vita/XONE/WIIU) - 416, 22 + 414, 22 TU53/1.49/CU43/P23/1.0.3 (360/PS3-4-Vita/XONE/WIIU/SWITCH) - 416, 22 + 414, 22 TU54/1.52/CU44/P24/1.0.4 (360/PS3-4-Vita/XONE/WIIU/SWITCH) - 416, 22 + 414, 22 TU69/1.76/P38 (360/PS3-4-Vita/WIIU) - 416, 22 + 414, 22 1.91 (PS4) @@ -635,16 +593,28 @@ Target Update - 47, 20 + 46, 20 Tools + + 180, 22 + + + Compact View + + + 44, 20 + + + View + - 20, 60 + 0, 0 - 612, 24 + 652, 24 3 @@ -706,219 +676,6 @@ MetroFramework.Controls.MetroContextMenu, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a - - Fill - - - 0, 0 - - - No - - - 320, 424 - - - 0 - - - waterTreeView - - - System.Windows.Forms.TreeView, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - waterTab - - - 0 - - - 4, 38 - - - 320, 424 - - - 1 - - - Water - - - waterTab - - - System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tabControl - - - 1 - - - 0, 0 - - - 320, 424 - - - 0 - - - underwaterTreeView - - - System.Windows.Forms.TreeView, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - underwaterTab - - - 0 - - - 0, 0 - - - 320, 424 - - - 0 - - - fogTreeView - - - System.Windows.Forms.TreeView, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - fogTab - - - 0 - - - Fill - - - 0, 0 - - - 320, 424 - - - 0 - - - colorTreeView - - - System.Windows.Forms.TreeView, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - colorsTab - - - 0 - - - 4, 38 - - - 320, 424 - - - 0 - - - Everything - - - colorsTab - - - System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tabControl - - - 0 - - - Top, Bottom, Left - - - 4, 38 - - - 320, 424 - - - 2 - - - Underwater - - - underwaterTab - - - System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tabControl - - - 2 - - - 4, 38 - - - 320, 424 - - - 3 - - - Underwater Fog - - - fogTab - - - System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tabControl - - - 3 - - - 23, 114 - - - 328, 466 - - - 22 - - - tabControl - - - MetroFramework.Controls.MetroTabControl, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a - - - $this - - - 2 - True @@ -3551,6 +3308,18 @@ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + viewToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + compactViewToolStripMenuItem + + + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + copyColorToolStripMenuItem @@ -3585,6 +3354,6 @@ COLEditor - ImmersiveForm, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a + PckStudio.Controls.EditorForm`1[[OMI.Formats.Color.ColorContainer, OMI Filetypes, Version=1.0.0.0, 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/CustomSkinEditor.cs b/PCK-Studio/Forms/Editor/CustomSkinEditor.cs index 3e7eabcd..7191ffb4 100644 --- a/PCK-Studio/Forms/Editor/CustomSkinEditor.cs +++ b/PCK-Studio/Forms/Editor/CustomSkinEditor.cs @@ -282,11 +282,11 @@ namespace PckStudio.Forms.Editor StringBuilder pos_sb = new StringBuilder(); foreach (SkinBOX b in skinPartListBox.SelectedItems.Cast()) { - uv_sb.Append(b.UV); + uv_sb.Append(b.Uv); uv_sb.Append(", "); size_sb.Append(b.Size); size_sb.Append(", "); - pos_sb.Append(b.Pos); + pos_sb.Append(b.Position); pos_sb.Append(", "); } @@ -298,7 +298,7 @@ namespace PckStudio.Forms.Editor if (skinPartListBox.SelectedItem is SkinBOX box) { - Image uvArea = EditorValue.Texture.GetArea(Rectangle.Truncate(new RectangleF(box.UV.X, box.UV.Y, box.Size.X * 2 + box.Size.Z * 2, box.Size.Z + box.Size.Y))); + Image uvArea = EditorValue.Texture.GetArea(Rectangle.Truncate(new RectangleF(box.Uv.X, box.Uv.Y, box.Size.X * 2 + box.Size.Z * 2, box.Size.Z + box.Size.Y))); Bitmap refImg = new Bitmap(1, 1); diff --git a/PCK-Studio/Forms/Editor/ModelEditor.resx b/PCK-Studio/Forms/Editor/ModelEditor.resx index a9f732b1..6e1d475c 100644 --- a/PCK-Studio/Forms/Editor/ModelEditor.resx +++ b/PCK-Studio/Forms/Editor/ModelEditor.resx @@ -117,16 +117,122 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - 17, 17 - - - 178, 17 - - - 293, 17 - + + 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 +2739,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/PCK-Studio/Forms/Editor/TextureAtlasEditor.cs b/PCK-Studio/Forms/Editor/TextureAtlasEditor.cs index 6aea5ff0..5fd74d03 100644 --- a/PCK-Studio/Forms/Editor/TextureAtlasEditor.cs +++ b/PCK-Studio/Forms/Editor/TextureAtlasEditor.cs @@ -16,10 +16,8 @@ * 3. This notice may not be removed or altered from any source distribution. **/ using System; -using System.Collections.Generic; using System.Diagnostics; using System.Drawing; -using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; using System.Linq; @@ -34,6 +32,7 @@ using PckStudio.Core.IO; using PckStudio.Core.Json; using PckStudio.Interfaces; using PckStudio.Internal; +using PckStudio.Json; using PckStudio.Properties; namespace PckStudio.Forms.Editor @@ -43,7 +42,7 @@ namespace PckStudio.Forms.Editor private readonly ITryGet _tryGetAnimation; private readonly ITryGet> _tryGetAnimationSaveContext; private readonly AtlasResource _atlasResource; - private readonly ColorContainer _colourTable; + private readonly ColorContainer _colorTable; private readonly ResourceCategory _resourceLocationCategory; private readonly Atlas _atlas; @@ -70,7 +69,7 @@ namespace PckStudio.Forms.Editor Text += _atlas.Name; originalPictureBox.Image = atlas; - _colourTable = colorContainer ?? AppResourceManager.Default.GetData(Resources.tu69colours, new COLFileReader()); + _colorTable = colorContainer ?? AppResourceManager.Default.GetData(Resources.tu69colours, new COLFileReader()); _tryGetAnimation = tryGetAnimation; _tryGetAnimationSaveContext = tryGetAnimationSaveContext; _atlasResource = resourceLocation as AtlasResource; @@ -115,15 +114,22 @@ namespace PckStudio.Forms.Editor private void UpdateAtlasDisplay() { - using (var g = Graphics.FromImage(originalPictureBox.Image)) - { - g.ApplyConfig(_graphicsConfig); - g.Clear(Color.Transparent); - Image image = EditorValue; - g.DrawImage(image, 0, 0, image.Width, image.Height); + using Graphics g = Graphics.FromImage(originalPictureBox.Image); + g.ApplyConfig(_graphicsConfig); + g.Clear(Color.Transparent); + Image image = EditorValue; + g.DrawImage(image, 0, 0, image.Width, image.Height); - SolidBrush brush = new SolidBrush(Color.FromArgb(127, Color.White)); - g.FillRectangle(brush, allowGroupsToolStripMenuItem.Checked ? _atlas.GetTileArea(_selectedTile) : _selectedTile.GetArea(_atlas.TileSize)); + SolidBrush brush = new SolidBrush(Color.FromArgb(127, Color.White)); + if (!allowGroupsToolStripMenuItem.Checked) + { + g.FillRectangle(brush, _selectedTile.GetArea(_atlas.TileSize)); + originalPictureBox.Invalidate(); + return; + } + foreach (Rectangle area in _atlas.GetTileArea(_selectedTile)) + { + g.FillRectangle(brush, area); } originalPictureBox.Invalidate(); } @@ -146,13 +152,13 @@ namespace PckStudio.Forms.Editor tileNameLabel.Text = $"{tileInfo?.DisplayName}"; internalTileNameLabel.Text = $"{tileInfo?.InternalName}"; setColorButton.Enabled = tileInfo.AllowCustomColour; - variantComboBox.Enabled = variantComboBox.Visible = tileInfo.HasColourEntry && tileInfo.ColourEntry?.Variants?.Length > 1; + variantComboBox.Enabled = Tiles.ColorEntries.TryGetValue(tileInfo.ColorKey, out JsonColorEntry colorEntry) && colorEntry?.Variants?.Length > 1 || _colorTable.Colors.Any(c => c.Name == tileInfo.ColorKey); if (variantComboBox.Enabled) { - if (tileInfo.ColourEntry.IsWaterColour) + if (colorEntry?.IsWaterColour ?? default) { - foreach (ColorContainer.WaterColor col in _colourTable.WaterColors) + foreach (ColorContainer.WaterColor col in _colorTable.WaterColors) { if (!variantComboBox.Items.Contains(col.Name)) variantComboBox.Items.Add(col.Name); @@ -160,10 +166,22 @@ namespace PckStudio.Forms.Editor } // TODO: only add variants that are available in the color table - variantComboBox.Items.AddRange(tileInfo.ColourEntry.Variants.Where(colorName => _colourTable.Colors.Any(c => c.Name == colorName) || _colourTable.WaterColors.Any(c => c.Name == colorName)).ToArray()); + if (_colorTable.Colors.Where(c => c.Name == tileInfo.ColorKey).FirstOrDefault() is ColorContainer.Color c) + variantComboBox.Items.Add(c.Name); + if (_colorTable.WaterColors.Where(c => c.Name == tileInfo.ColorKey).FirstOrDefault() is ColorContainer.WaterColor wc) + variantComboBox.Items.Add(wc.Name); + if (tileInfo.HasColourEntry) + { + if (!string.IsNullOrWhiteSpace(colorEntry.DefaultName)) + variantComboBox.Items.Add(colorEntry.DefaultName); + variantComboBox.Items.AddRange(colorEntry.Variants.Where(colorName => _colorTable.Colors.Any(c => c.Name == colorName) || _colorTable.WaterColors.Any(c => c.Name == colorName)).ToArray()); + } if (variantComboBox.Items.Count > 0) + { + variantComboBox.Visible = variantComboBox.Items.Count > 1; variantComboBox.SelectedIndex = 0; + } } CheckForAnimation(); @@ -187,6 +205,7 @@ namespace PckStudio.Forms.Editor if (playAnimationsToolStripMenuItem.Checked && hasAnimation) { + selectTilePictureBox.UseBlendColor = false; selectTilePictureBox.Image = animation.CreateAnimationImage(selectTilePictureBox.BlendColor); selectTilePictureBox.Start(); return; @@ -196,7 +215,8 @@ namespace PckStudio.Forms.Editor if (_selectedTile.IsPartOfGroup && allowGroupsToolStripMenuItem.Checked) { AtlasGroup group = _selectedTile.GetGroup(); - tileNameLabel.Text = $"{group.Name}"; + if (!string.IsNullOrWhiteSpace(group.Name)) + tileNameLabel.Text = group.Name; internalTileNameLabel.Text = string.Empty; if (group.IsAnimation()) { @@ -210,13 +230,32 @@ namespace PckStudio.Forms.Editor return; } } - if (group.IsLargeTile()) - { - selectTilePictureBox.Image = _atlas.GetTileTexture(_selectedTile); - } + selectTilePictureBox.UseBlendColor = false; + setColorButton.Enabled |= group.AllowCustomColor; + selectTilePictureBox.Image = _atlas.GetTileTexture(_selectedTile, selectTilePictureBox.BlendColor); } } + private void ResetView() + { + tileNameLabel.Text = string.Empty; + internalTileNameLabel.Text = string.Empty; + + colorSlider.Visible = false; + colorSliderLabel.Visible = false; + variantComboBox.Visible = false; + + variantComboBox.SelectedItem = null; + variantComboBox.Enabled = false; + variantComboBox.Items.Clear(); + clearColorButton.Enabled = false; + + if (selectTilePictureBox.IsPlaying) + selectTilePictureBox.Stop(); + selectTilePictureBox.UseBlendColor = true; + selectTilePictureBox.Image = null; + } + private void ResetView() { tileNameLabel.Text = string.Empty; @@ -323,11 +362,11 @@ namespace PckStudio.Forms.Editor private void SetTile(Image texture) { - if (_selectedTile.IsPartOfGroup) + if (_selectedTile.IsPartOfGroup && allowGroupsToolStripMenuItem.Checked) { AtlasGroup group = _selectedTile.GetGroup(); _atlas.SetGroup(group, texture); - selectTilePictureBox.Image = _atlas.GetTileTexture(_selectedTile); + selectTilePictureBox.Image = _atlas.GetTileTexture(_selectedTile, selectTilePictureBox.BlendColor); UpdateAtlasDisplay(); return; } @@ -342,36 +381,38 @@ namespace PckStudio.Forms.Editor private Color GetBlendColor() { - if (_selectedTile.TryGetUserDataOfType(out JsonTileInfo tileInfo) && tileInfo.HasColourEntry) + if (_selectedTile.TryGetUserDataOfType(out JsonTileInfo tileInfo)) { - return FindBlendColorByKey(tileInfo.ColourEntry.DefaultName); + string colorKey = tileInfo.InternalName; + + colorSlider.Visible = colorSliderLabel.Visible = true; + // Simply, Experience orbs red value is just sliding between 255 and 0 + if (colorKey.StartsWith("experience_orb")) + return Color.FromArgb(colorSlider.Value, 255, 0); + + // Similar story for critical hits, but for all values + if (colorKey == "critical_hit") + return Color.FromArgb(colorSlider.Value, colorSlider.Value, colorSlider.Value); + + // Enchanted hits are modified critical hit particles + if (colorKey == "enchanted_hit") + { + // This is directly based on Java's source code for handling enchanted hits + // it just multiplies the red by 0.3 and green by .8 of the color assigned to the critical hit particle + var c = Color.FromArgb(colorSlider.Value, colorSlider.Value, colorSlider.Value); + return Color.FromArgb((byte)(c.R * 0.3f), (byte)(c.G * 0.8f), c.B); + } + colorSlider.Visible = colorSliderLabel.Visible = false; + if (tileInfo.HasColourEntry) + return FindBlendColorByKey(tileInfo.ColorEntry.DefaultName); } return Color.White; } - private Color GetSpecificBlendColor(string colorKey) + private Color FindBlendColorByKey(string colorKey, bool isWaterColour = default) { - colorSlider.Visible = colorSliderLabel.Visible = true; - - // Simply, Experience orbs red value is just sliding between 255 and 0 - if (colorKey == "experience_orb") - return Color.FromArgb(colorSlider.Value, 255, 0); - - // Similar story for critical hits, but for all values - return Color.FromArgb(colorSlider.Value, colorSlider.Value, colorSlider.Value); - } - - private Color FindBlendColorByKey(string colorKey) - { - // The following tiles are hardcoded within a range and do not have color table entries - if (colorKey == "experience_orb" || colorKey == "critical_hit") - return GetSpecificBlendColor(colorKey); - - if (!_selectedTile.TryGetUserDataOfType(out JsonTileInfo tileInfo) || !tileInfo.HasColourEntry) - { - Debug.WriteLine("Could not find: " + colorKey); + if (string.IsNullOrWhiteSpace(colorKey)) return Color.White; - } // Enchanted hits are modified critical hit particles if (tileInfo.InternalName == "enchanted_hit") @@ -383,14 +424,11 @@ namespace PckStudio.Forms.Editor } // basic way to check for classic water colors - if (!tileInfo.ColourEntry.IsWaterColour || colorKey.StartsWith("Water_")) + if (!isWaterColour && !colorKey.StartsWith("Water_") && _colorTable.Colors.FirstOrDefault(entry => entry.Name == colorKey) is ColorContainer.Color color) { - if (_colourTable.Colors.FirstOrDefault(entry => entry.Name == colorKey) is ColorContainer.Color color) - { - return color.ColorPallette; - } + return color.ColorPallette; } - else if (_colourTable.WaterColors.FirstOrDefault(entry => entry.Name == colorKey) is ColorContainer.WaterColor waterColor) + if (_colorTable.WaterColors.FirstOrDefault(entry => entry.Name == colorKey) is ColorContainer.WaterColor waterColor) { return waterColor.SurfaceColor; } @@ -406,6 +444,18 @@ namespace PckStudio.Forms.Editor int down = _atlas.Rows; int left = -1; int right = 1; + if (_selectedTile.IsPartOfGroup) + { + AtlasGroup group = _selectedTile.GetGroup(); + if (!group.IsComposedOfMultipleTiles()) + { + Size s = group.GetSize(new Size(1, 1)); + up = -_atlas.Rows * (group.Column - _selectedTile.Column + 1); + down = _atlas.Rows * (group.Column - _selectedTile.Column + s.Height); + left = group.Row - _selectedTile.Row - 1; + right = group.Row - _selectedTile.Row + s.Width; + } + } switch (keyData) { case Keys.R: @@ -512,14 +562,14 @@ namespace PckStudio.Forms.Editor }; if (saveFileDialog.ShowDialog(this) == DialogResult.OK) { - _atlas.GetTileTexture(_selectedTile).Save(saveFileDialog.FileName, ImageFormat.Png); + _atlas.GetTileTexture(_selectedTile, selectTilePictureBox.BlendColor).Save(saveFileDialog.FileName, ImageFormat.Png); Action onChange = new Action((tile, fileInfo) => { Image img = Image.FromFile(fileInfo.FullName).ReleaseFromFile(); bool success = _atlas.SetTile(tile, img); if (!success) { - Size s = _atlas.GetTileArea(tile).Size; + Size s = _atlas.GetTileArea(tile).FirstOrDefault().Size; new ToastContentBuilder() .AddText("Invalid Image Dimensions") .AddText($"Required: {s.Width}x{s.Height} Recived: {img.Width}x{img.Height}") @@ -554,13 +604,8 @@ namespace PckStudio.Forms.Editor { string colorKey = variantComboBox.SelectedItem.ToString(); Color blendColor = FindBlendColorByKey(colorKey); - if (_selectedTile.IsPartOfGroup && _selectedTile.GetGroup().IsAnimation()) - { - selectTilePictureBox.Image = _atlas.GetAnimationFromGroup(_selectedTile.GetGroup()).CreateAnimationImage(blendColor); - selectTilePictureBox.Start(); - return; - } selectTilePictureBox.BlendColor = blendColor; + CheckForAnimation(); } } @@ -589,6 +634,7 @@ namespace PckStudio.Forms.Editor selectTilePictureBox.BlendColor = _colorPick.Color; variantComboBox.Enabled = false; clearColorButton.Enabled = true; + CheckForAnimation(); } private void clearColorButton_Click(object sender, EventArgs e) @@ -598,6 +644,7 @@ namespace PckStudio.Forms.Editor selectTilePictureBox.BlendColor = Color.White; clearColorButton.Enabled = false; + CheckForAnimation(); } private void colorSlider_ValueChanged(object sender, EventArgs e) diff --git a/PCK-Studio/MainForm.cs b/PCK-Studio/MainForm.cs index f70d9e53..8f4540b2 100644 --- a/PCK-Studio/MainForm.cs +++ b/PCK-Studio/MainForm.cs @@ -31,24 +31,29 @@ using PckStudio.Properties; namespace PckStudio { - public partial class MainForm : ImmersiveForm - { - private PckManager PckManager = null; + public partial class MainForm : ImmersiveForm + { + private PckManager PckManager = null; private Dictionary openTabPages = new Dictionary(); + private DLCManager _dlcManager; public MainForm() - { - InitializeComponent(); + { + InitializeComponent(); Text = Application.ProductName; - - labelVersion.Text = $"{Application.ProductName}: {ApplicationScope.CurrentVersion}"; - ChangelogRichTextBox.Text = Resources.CHANGELOG; - - pckOpen.AllowDrop = true; - } + labelVersion.Text = $"{Application.ProductName}: {ApplicationScope.CurrentVersion}"; + + ChangelogRichTextBox.Text = Resources.CHANGELOG; + + pckOpen.AllowDrop = true; + + _dlcManager = new DLCManager(Settings.Default.Platform, Settings.Default.UserLanguage); + Internal.SettingsManager.Default.RegisterPropertyChangedCallback(nameof(Settings.Default.UserLanguage), _dlcManager.SetPreferredLanguage); + Internal.SettingsManager.Default.RegisterPropertyChangedCallback(nameof(Settings.Default.Platform), _dlcManager.SetPlatform); + } public void LoadPckFromFile(IEnumerable filepaths) { @@ -60,44 +65,65 @@ namespace PckStudio public void LoadPckFromFile(string filepath) { - IDLCPackage dlcPackage = DLCManager.Default.OpenDLCPackage(filepath); + IDLCPackage dlcPackage = _dlcManager.OpenDLCPackage(filepath); Debug.WriteLine(dlcPackage?.GetDLCPackageType()); if (dlcPackage is null) + { + MessageBox.Show($"Failed to open '{Path.GetFileName(filepath)}'"); return; + } SaveToRecentFiles(filepath); - if (dlcPackage.GetDLCPackageType() == DLCPackageType.Unknown) - AddEditorPage(dlcPackage); + AddEditorPage(dlcPackage); } - internal void OpenNewPckTab(string caption, string identifier, PackInfo packInfo, ISaveContext saveContext) - { + internal void OpenNewPckTab(string caption, string identifier, RawAssetDLCPackage packInfo, ISaveContext saveContext) + { if (openTabPages.ContainsKey(identifier)) { tabControl.SelectTab(openTabPages[identifier]); return; } - var editor = new PckAssetBrowserEditor(packInfo, saveContext); + var editor = new RawAssetsEditor(packInfo, saveContext); AddPage(caption, identifier, editor); } - private void AddEditorPage(string caption, string identifier, PackInfo packInfo, ISaveContext saveContext = null) + private void AddEditorPage(string caption, string identifier, RawAssetDLCPackage packInfo, ISaveContext saveContext = null) { saveContext ??= GetDefaultSaveContext("./new.pck", "PCK (Minecraft Console Package)"); - var editor = new PckAssetBrowserEditor(packInfo, saveContext); + var editor = new RawAssetsEditor(packInfo, saveContext); AddPage(caption, identifier, editor); } private void AddEditorPage(IDLCPackage dlcPackage) { - PackInfo packInfo = PackInfo.Create((dlcPackage as UnknownDLCPackage).PckFile, default, false); - ISaveContext saveContext = GetDefaultSaveContext("", "PCK (Minecraft Console Package)"); - var editor = new PckAssetBrowserEditor(packInfo, saveContext); - TabPage page = AddPage(dlcPackage.Name, dlcPackage.Name, editor); - } + switch (dlcPackage.GetDLCPackageType()) + { + case DLCPackageType.RawAssets: + ISaveContext saveContext = GetDefaultSaveContext("", "PCK (Minecraft Console Package)"); + var editor = new RawAssetsEditor(dlcPackage as RawAssetDLCPackage, saveContext); + TabPage page = AddPage(dlcPackage.Name, dlcPackage.Name, editor); + break; + case DLCPackageType.SkinPack: + break; + case DLCPackageType.TexturePack: + break; + case DLCPackageType.MashUpPack: + break; + case DLCPackageType.MG01: + case DLCPackageType.MG02: + case DLCPackageType.MG03: + MessageBox.Show("Not Implemented..."); + break; + default: + Trace.TraceError("Invalid Package Type"); + break; - private static ISaveContext GetDefaultSaveContext(string filepath, string description) + } + } + + private static ISaveContext GetDefaultSaveContext(string filepath, string description) { - return new DelegatedFileSaveContext(filepath, false, new FileDialogFilter(description, "*"+Path.GetExtension(filepath)),(packInfo, stream) => new PckFileWriter(packInfo.File, packInfo.ByteOrder).WriteToStream(stream)); + return new DelegatedFileSaveContext(filepath, false, new FileDialogFilter(description, "*" + Path.GetExtension(filepath)), (packInfo, stream) => new PckFileWriter(packInfo.PckFile, packInfo.ByteOrder).WriteToStream(stream)); } private TabPage AddPage(string caption, string identifier, Control control) @@ -114,9 +140,9 @@ namespace PckStudio return page; } - private bool TryGetEditor(TabPage page, out IEditor editor) + private bool TryGetEditor(TabPage page, out IEditor editor) { - if (page.Controls[0] is IEditor outEditor) + if (page.Controls[0] is IEditor outEditor) { editor = outEditor; return true; @@ -125,12 +151,12 @@ namespace PckStudio return false; } - private bool TryGetCurrentEditor(out IEditor editor) => TryGetEditor(tabControl.SelectedTab, out editor); + private bool TryGetCurrentEditor(out IEditor editor) => TryGetEditor(tabControl.SelectedTab, out editor); private void MainForm_Load(object sender, EventArgs e) - { - LoadRecentFileList(); - } + { + LoadRecentFileList(); + } private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { @@ -149,7 +175,7 @@ namespace PckStudio private void CloseTab(TabControl.TabPageCollection collection, TabPage page) { - if (TryGetEditor(page, out IEditor editor)) + if (TryGetEditor(page, out IEditor editor)) { editor.Close(); RemoveOpenFile(page); @@ -174,55 +200,55 @@ namespace PckStudio { Settings.Default.RecentFiles ??= new System.Collections.Specialized.StringCollection(); recentlyOpenToolStripMenuItem.DropDownItems.Clear(); - for (int i = 0; i < Settings.Default.RecentFiles.Count && i < 5; i++) - { - string filepath = Settings.Default.RecentFiles[i]; - if (!string.IsNullOrWhiteSpace(filepath) && File.Exists(filepath)) - { - string displayFilepath = Regex.Replace(filepath, @"([A-Z]{1}\:\\[Uu]sers\\)([^\\]*\\)(.*)", "~\\$3"); + for (int i = 0; i < Settings.Default.RecentFiles.Count && i < 5; i++) + { + string filepath = Settings.Default.RecentFiles[i]; + if (!string.IsNullOrWhiteSpace(filepath) && File.Exists(filepath)) + { + string displayFilepath = Regex.Replace(filepath, @"([A-Z]{1}\:\\[Uu]sers\\)([^\\]*\\)(.*)", "~\\$3"); ToolStripItem item = recentlyOpenToolStripMenuItem.DropDownItems.Add(displayFilepath, null, HandleOpenFile); - item.Tag = filepath; - } - } - if (recentlyOpenToolStripMenuItem.DropDownItems.Count > 0) - { - void clearRecentFileList(object sender, EventArgs e) - { - Settings.Default.RecentFiles.Clear(); - LoadRecentFileList(); + item.Tag = filepath; } - recentlyOpenToolStripMenuItem.DropDownItems.Add(new ToolStripSeparator()); - recentlyOpenToolStripMenuItem.DropDownItems.Add("Clear", null, clearRecentFileList); - } + } + if (recentlyOpenToolStripMenuItem.DropDownItems.Count > 0) + { + void clearRecentFileList(object sender, EventArgs e) + { + Settings.Default.RecentFiles.Clear(); + LoadRecentFileList(); + } + recentlyOpenToolStripMenuItem.DropDownItems.Add(new ToolStripSeparator()); + recentlyOpenToolStripMenuItem.DropDownItems.Add("Clear", null, clearRecentFileList); + } } - private void HandleOpenFile(object sender, EventArgs e) - { - if (sender is ToolStripItem menuItem && menuItem.Tag is string filepath) - { - if (!File.Exists(filepath)) - { - menuItem.Available = false; - return; - } - LoadPckFromFile(filepath); - } + private void HandleOpenFile(object sender, EventArgs e) + { + if (sender is ToolStripItem menuItem && menuItem.Tag is string filepath) + { + if (!File.Exists(filepath)) + { + menuItem.Available = false; + return; + } + LoadPckFromFile(filepath); + } } - private void SaveToRecentFiles(string filepath) - { - if (filepath is null || string.IsNullOrWhiteSpace(filepath)) - return; + private void SaveToRecentFiles(string filepath) + { + if (filepath is null || string.IsNullOrWhiteSpace(filepath)) + return; if (Settings.Default.RecentFiles.Contains(filepath)) Settings.Default.RecentFiles.Remove(filepath); - Settings.Default.RecentFiles.Insert(0, filepath); + Settings.Default.RecentFiles.Insert(0, filepath); - for (int i = Settings.Default.RecentFiles.Count - 1; i >= 5; i--) - { + for (int i = Settings.Default.RecentFiles.Count - 1; i >= 5; i--) + { Settings.Default.RecentFiles.RemoveAt(i); } - Settings.Default.Save(); - LoadRecentFileList(); + Settings.Default.Save(); + LoadRecentFileList(); } private void openPckManagerToolStripMenuItem_Click(object sender, EventArgs e) @@ -239,7 +265,7 @@ namespace PckStudio } private void openToolStripMenuItem_Click(object sender, EventArgs e) - { + { using var ofd = new OpenFileDialog(); ofd.CheckFileExists = true; ofd.Filter = "PCK (Minecraft Console Package)|*.pck"; @@ -251,9 +277,10 @@ namespace PckStudio private void tabControl_PageClosing(object sender, PageClosingEventArgs e) { - if (TryGetEditor(e.Page, out IEditor editor)) + if (TryGetEditor(e.Page, out IEditor editor)) { editor.Close(); + _dlcManager.CloseDLCPackage(editor.EditorValue.Identifier); RemoveOpenFile(); } } @@ -271,70 +298,67 @@ namespace PckStudio } } - private static PckFile InitializePack(int packId, int packVersion, string packName, bool createSkinsPCK) - { - var pack = new PckFile(3); + private static PckFile InitializePack(int packId, int packVersion, string packName) + { + var pack = new PckFile(3); PckAsset zeroAsset = pack.CreateNewAsset("0", PckAssetType.InfoFile); - zeroAsset.AddProperty("PACKID", packId); - zeroAsset.AddProperty("PACKVERSION", packVersion); + zeroAsset.AddProperty("PACKID", packId); + zeroAsset.AddProperty("PACKVERSION", packVersion); - var locFile = new LOCFile(); - locFile.InitializeDefault(packName); - pack.CreateNewAsset("localisation.loc", PckAssetType.LocalisationFile, new LOCFileWriter(locFile, 2)); + var locFile = new LOCFile(); + locFile.InitializeDefault(packName); + pack.CreateNewAsset("localisation.loc", PckAssetType.LocalisationFile, new LOCFileWriter(locFile, 2)); + return pack; + } - pack.CreateNewAssetIf(createSkinsPCK, "Skins.pck", PckAssetType.SkinDataFile, new PckFileWriter(new PckFile(3, true), OMI.ByteOrder.BigEndian)); + private static PckFile InitializeTexturePack(int packId, int packVersion, string packName, string res) + { + PckFile pack = InitializePack(packId, packVersion, packName); - return pack; - } - - private static PckFile InitializeTexturePack(int packId, int packVersion, string packName, string res, bool createSkinsPCK) - { - PckFile pack = InitializePack(packId, packVersion, packName, createSkinsPCK); - - PckFile infoPCK = new PckFile(3); + PckFile infoPCK = new PckFile(3); pack.GetAsset("localisation.loc", PckAssetType.LocalisationFile).Filename = "languages.loc"; PckAsset iconAsset = infoPCK.CreateNewAsset("icon.png", PckAssetType.TextureFile); - iconAsset.SetTexture(Core.Properties.Resources.TexturePackIcon); + iconAsset.SetTexture(Core.Properties.Resources.TexturePackIcon); PckAsset comparisonAsset = infoPCK.CreateNewAsset("comparison.png", PckAssetType.TextureFile); - comparisonAsset.SetTexture(Core.Properties.Resources.Comparison); + comparisonAsset.SetTexture(Core.Properties.Resources.Comparison); PckAsset texturepackInfoAsset = pack.CreateNewAsset($"{res}/{res}Info.pck", PckAssetType.TexturePackInfoFile); - texturepackInfoAsset.AddProperty("PACKID", "0"); - texturepackInfoAsset.AddProperty("DATAPATH", $"{res}Data.pck"); + texturepackInfoAsset.AddProperty("PACKID", "0"); + texturepackInfoAsset.AddProperty("DATAPATH", $"{res}Data.pck"); - texturepackInfoAsset.SetData(new PckFileWriter(infoPCK, OMI.ByteOrder.BigEndian)); + texturepackInfoAsset.SetData(new PckFileWriter(infoPCK, OMI.ByteOrder.BigEndian)); - return pack; - } + return pack; + } - private static PckFile InitializeMashUpPack(int packId, int packVersion, string packName, string res) - { - PckFile pack = InitializeTexturePack(packId, packVersion, packName, res, true); + private static PckFile InitializeMashUpPack(int packId, int packVersion, string packName, string res) + { + PckFile pack = InitializeTexturePack(packId, packVersion, packName, res); PckAsset gameRuleAsset = pack.CreateNewAsset("GameRules.grf", PckAssetType.GameRulesFile); GameRuleFile grfFile = new GameRuleFile(); - grfFile.AddRule("MapOptions", - new KeyValuePair("seed", "0"), - new KeyValuePair("baseSaveName", string.Empty), - new KeyValuePair("flatworld", "false"), - new KeyValuePair("texturePackId", packId.ToString()) - ); - grfFile.AddRule("LevelRules") - .AddRule("UpdatePlayer", - new KeyValuePair("yRot", "0"), - new KeyValuePair("xRot", "0"), - new KeyValuePair("spawnX", "0"), - new KeyValuePair("spawnY", "0"), - new KeyValuePair("spawnZ", "0") - ); + grfFile.AddRule("MapOptions", + new KeyValuePair("seed", "0"), + new KeyValuePair("baseSaveName", string.Empty), + new KeyValuePair("flatworld", "false"), + new KeyValuePair("texturePackId", packId.ToString()) + ); + grfFile.AddRule("LevelRules") + .AddRule("UpdatePlayer", + new KeyValuePair("yRot", "0"), + new KeyValuePair("xRot", "0"), + new KeyValuePair("spawnX", "0"), + new KeyValuePair("spawnY", "0"), + new KeyValuePair("spawnZ", "0") + ); - gameRuleAsset.SetData(new GameRuleFileWriter(grfFile)); + gameRuleAsset.SetData(new GameRuleFileWriter(grfFile)); - return pack; - } + return pack; + } private void skinPackToolStripMenuItem_Click(object sender, EventArgs e) { @@ -342,9 +366,9 @@ namespace PckStudio namePrompt.OKButtonText = "Ok"; if (namePrompt.ShowDialog(this) == DialogResult.OK) { - PckFile skinPck = InitializePack(new Random().Next(8000, GameConstants.MAX_PACK_ID), 0, namePrompt.NewText, true); - PackInfo packInfo = PackInfo.Create(skinPck, OMI.ByteOrder.BigEndian, true); - AddEditorPage("Unsaved skin pack", "Unsaved skin pack", packInfo); + PckFile skinPck = InitializePack(new Random().Next(8000, GameConstants.MAX_PACK_ID), 0, namePrompt.NewText); + RawAssetDLCPackage newRawAssetDLCPackage = new RawAssetDLCPackage("New pack", skinPck, OMI.ByteOrder.BigEndian); + AddEditorPage(newRawAssetDLCPackage.Name, "Unsaved texture pack", newRawAssetDLCPackage); } } @@ -353,9 +377,9 @@ namespace PckStudio var packPrompt = new CreateTexturePackPrompt(); if (packPrompt.ShowDialog() == DialogResult.OK) { - PckFile texturePackPck = InitializeTexturePack(new Random().Next(8000, GameConstants.MAX_PACK_ID), 0, packPrompt.PackName, packPrompt.PackRes, packPrompt.CreateSkinsPck); - PackInfo packInfo = PackInfo.Create(texturePackPck, OMI.ByteOrder.BigEndian, true); - AddEditorPage("Unsaved texture pack", "Unsaved texture pack", packInfo); + PckFile texturePackPck = InitializeTexturePack(new Random().Next(8000, GameConstants.MAX_PACK_ID), 0, packPrompt.PackName, packPrompt.PackRes); + RawAssetDLCPackage newRawAssetDLCPackage = new RawAssetDLCPackage("New pack", texturePackPck, OMI.ByteOrder.BigEndian); + AddEditorPage(newRawAssetDLCPackage.Name, "Unsaved texture pack", newRawAssetDLCPackage); } } @@ -365,16 +389,16 @@ namespace PckStudio if (packPrompt.ShowDialog() == DialogResult.OK) { PckFile mashUpPck = InitializeMashUpPack(new Random().Next(8000, GameConstants.MAX_PACK_ID), 0, packPrompt.PackName, packPrompt.PackRes); - PackInfo packInfo = PackInfo.Create(mashUpPck, OMI.ByteOrder.BigEndian, true); - AddEditorPage("Unsaved mash-up pack", "Unsaved mash-up pack", packInfo); + RawAssetDLCPackage newRawAssetDLCPackage = new RawAssetDLCPackage("New pack", mashUpPck, OMI.ByteOrder.BigEndian); + AddEditorPage(newRawAssetDLCPackage.Name, "Unsaved texture pack", newRawAssetDLCPackage); } } - private void quickChangeToolStripMenuItem_Click(object sender, EventArgs e) - { - if (TryGetCurrentEditor(out IEditor editor)) + private void quickChangeToolStripMenuItem_Click(object sender, EventArgs e) + { + if (TryGetCurrentEditor(out IEditor editor)) { - using AdvancedOptions advanced = new AdvancedOptions(editor.EditorValue.File); + using AdvancedOptions advanced = new AdvancedOptions(editor.EditorValue.PckFile); advanced.IsLittleEndian = editor.EditorValue.ByteOrder == OMI.ByteOrder.LittleEndian; if (advanced.ShowDialog() == DialogResult.OK) { @@ -383,42 +407,16 @@ namespace PckStudio } } - private void closeToolStripMenuItem_Click(object sender, EventArgs e) - { + private void closeToolStripMenuItem_Click(object sender, EventArgs e) + { CloseTab(tabControl.TabPages, tabControl.SelectedTab); } - private void aboutToolStripMenuItem_Click(object sender, EventArgs e) - { - using ContributorsForm info = new ContributorsForm(); - info.ShowDialog(this); - } - - [Obsolete("ReMove this")] - public string GetDataPath() - { - return ""; - } - - [Obsolete("Move this")] - public bool HasDataFolder() - { - return Directory.Exists(GetDataPath()); - } - - [Obsolete("Move this")] - public bool CreateDataFolder() - { - if (!HasDataFolder()) - { - DialogResult result = MessageBox.Show(this, "There is not a \"Data\" folder present in the pack folder. Would you like to create one?", "Folder missing", MessageBoxButtons.YesNo); - if (result == DialogResult.No) - return false; - else - Directory.CreateDirectory(GetDataPath()); - } - return true; - } + private void aboutToolStripMenuItem_Click(object sender, EventArgs e) + { + using ContributorsForm info = new ContributorsForm(); + info.ShowDialog(this); + } private void howToMakeABasicSkinPackToolStripMenuItem_Click(object sender, EventArgs e) => Process.Start("https://www.youtube.com/watch?v=A43aHRHkKxk"); @@ -445,113 +443,113 @@ namespace PckStudio private void trelloBoardToolStripMenuItem_Click(object sender, EventArgs e) => Process.Start("https://trello.com/b/0XLNOEbe/pck-studio"); private void OpenPck_MouseEnter(object sender, EventArgs e) - { - pckOpen.Image = Resources.pckOpen; - } + { + pckOpen.Image = Resources.pckOpen; + } - private void OpenPck_MouseLeave(object sender, EventArgs e) - { - pckOpen.Image = Resources.pckClosed; - } + private void OpenPck_MouseLeave(object sender, EventArgs e) + { + pckOpen.Image = Resources.pckClosed; + } - private void OpenPck_DragEnter(object sender, DragEventArgs e) - { - pckOpen.Image = Resources.pckDrop; + private void OpenPck_DragEnter(object sender, DragEventArgs e) + { + pckOpen.Image = Resources.pckDrop; string[] files = (string[])e.Data.GetData(DataFormats.FileDrop) ?? Array.Empty(); - e.Effect = files.Any(file => Path.GetExtension(file).Equals(".pck", StringComparison.CurrentCultureIgnoreCase)) - ? DragDropEffects.Copy - : DragDropEffects.None; - } + e.Effect = files.Any(file => Path.GetExtension(file).Equals(".pck", StringComparison.CurrentCultureIgnoreCase)) + ? DragDropEffects.Copy + : DragDropEffects.None; + } - private void OpenPck_DragDrop(object sender, DragEventArgs e) - { - if (e.Data.GetData(DataFormats.FileDrop, false) is string[] filepaths) - LoadPckFromFile(filepaths); - } + private void OpenPck_DragDrop(object sender, DragEventArgs e) + { + if (e.Data.GetData(DataFormats.FileDrop, false) is string[] filepaths) + LoadPckFromFile(filepaths); + } - private void OpenPck_DragLeave(object sender, EventArgs e) - { - pckOpen.Image = Resources.pckClosed; - } + private void OpenPck_DragLeave(object sender, EventArgs e) + { + pckOpen.Image = Resources.pckClosed; + } - private void OpenPck_Click(object sender, EventArgs e) - { - openToolStripMenuItem_Click(sender, e); - } + private void OpenPck_Click(object sender, EventArgs e) + { + openToolStripMenuItem_Click(sender, e); + } - private void saveToolStripMenuItem_Click(object sender, EventArgs e) - { - if (TryGetCurrentEditor(out IEditor editor)) + private void saveToolStripMenuItem_Click(object sender, EventArgs e) + { + if (TryGetCurrentEditor(out IEditor editor)) { editor.Save(); } } - private void saveAsToolStripMenuItem_Click(object sender, EventArgs e) - { - if (TryGetCurrentEditor(out IEditor editor)) + private void saveAsToolStripMenuItem_Click(object sender, EventArgs e) + { + if (TryGetCurrentEditor(out IEditor editor)) { editor.SaveAs(); } } - private void wavBinkaToolStripMenuItem_Click(object sender, EventArgs e) - { - using OpenFileDialog fileDialog = new OpenFileDialog - { - Multiselect = true, - Filter = "WAV files (*.wav)|*.wav", - Title = "Please choose WAV files to convert to BINKA" - }; - if (fileDialog.ShowDialog(this) == DialogResult.OK) - { - using ItemSelectionPopUp dialog = new ItemSelectionPopUp( - "Level 1 (Best Quality)", "Level 2", "Level 3", "Level 4", "Level 5", - "Level 6", "Level 7", "Level 8", "Level 9 (Worst Quality)") - { - LabelText = "Compression", - ButtonText = "OK" - }; - - if (dialog.ShowDialog(this) == DialogResult.OK) + private void wavBinkaToolStripMenuItem_Click(object sender, EventArgs e) + { + using OpenFileDialog fileDialog = new OpenFileDialog + { + Multiselect = true, + Filter = "WAV files (*.wav)|*.wav", + Title = "Please choose WAV files to convert to BINKA" + }; + if (fileDialog.ShowDialog(this) == DialogResult.OK) + { + using ItemSelectionPopUp dialog = new ItemSelectionPopUp( + "Level 1 (Best Quality)", "Level 2", "Level 3", "Level 4", "Level 5", + "Level 6", "Level 7", "Level 8", "Level 9 (Worst Quality)") { - BinkaConverter.ToBinka( - fileDialog.FileNames, - new DirectoryInfo(Path.GetDirectoryName(fileDialog.FileName)), - dialog.SelectedIndex + 1 // compression level - ); - } - } - } + LabelText = "Compression", + ButtonText = "OK" + }; - private void binkaWavToolStripMenuItem_Click(object sender, EventArgs e) - { - using OpenFileDialog fileDialog = new OpenFileDialog - { - Multiselect = true, - Filter = "BINKA files (*.binka)|*.binka", - Title = "Please choose BINKA files to convert to WAV" - }; - if (fileDialog.ShowDialog(this) == DialogResult.OK) - { - BinkaConverter.ToWav(fileDialog.FileNames, new DirectoryInfo(Path.GetDirectoryName(fileDialog.FileName))); - } - } + if (dialog.ShowDialog(this) == DialogResult.OK) + { + BinkaConverter.ToBinka( + fileDialog.FileNames, + new DirectoryInfo(Path.GetDirectoryName(fileDialog.FileName)), + dialog.SelectedIndex + 1 // compression level + ); + } + } + } - private void settingsToolStripMenuItem_Click(object sender, EventArgs e) - { - var appSettings = new AppSettingsForm(); - appSettings.ShowDialog(this); - } + private void binkaWavToolStripMenuItem_Click(object sender, EventArgs e) + { + using OpenFileDialog fileDialog = new OpenFileDialog + { + Multiselect = true, + Filter = "BINKA files (*.binka)|*.binka", + Title = "Please choose BINKA files to convert to WAV" + }; + if (fileDialog.ShowDialog(this) == DialogResult.OK) + { + BinkaConverter.ToWav(fileDialog.FileNames, new DirectoryInfo(Path.GetDirectoryName(fileDialog.FileName))); + } + } - private void checkForUpdatesToolStripMenuItem_Click(object sender, EventArgs e) - { - Updater.UpdateToLatest(); - } + private void settingsToolStripMenuItem_Click(object sender, EventArgs e) + { + var appSettings = new AppSettingsForm(); + appSettings.ShowDialog(this); + } + + private void checkForUpdatesToolStripMenuItem_Click(object sender, EventArgs e) + { + Updater.UpdateToLatest(); + } private void exitToolStripMenuItem_Click(object sender, EventArgs e) { - PckManager?.Close(); + PckManager?.Close(); Application.Exit(); } diff --git a/PCK-Studio/PckStudio.csproj b/PCK-Studio/PckStudio.csproj index f0c5686c..06e8eed9 100644 --- a/PCK-Studio/PckStudio.csproj +++ b/PCK-Studio/PckStudio.csproj @@ -181,14 +181,14 @@ UserControl - + UserControl - - PckAssetBrowserEditor.cs + + RawAssetsEditor.cs - Form + UserControl FilterPrompt.cs @@ -439,8 +439,8 @@ ModelsPanel.cs - - PckAssetBrowserEditor.cs + + RawAssetsEditor.cs SkinsPanel.cs @@ -453,6 +453,7 @@ ModelEditor.cs + Designer CemuPanel.cs diff --git a/PCK-Studio/Program.cs b/PCK-Studio/Program.cs index c7d075c6..e6987a8e 100644 --- a/PCK-Studio/Program.cs +++ b/PCK-Studio/Program.cs @@ -38,18 +38,15 @@ namespace PckStudio if (Settings.Default.Platform == Core.ConsolePlatform.Unknown) { MessageBox.Show("Please choose on which console you're playing on.", "Select Platform", MessageBoxButtons.OK, MessageBoxIcon.Question); - var platformChooser = new ItemSelectionPopUp(Enum.GetNames(typeof(Core.ConsolePlatform))); + var platformChooser = new ItemSelectionPopUp(Enum.GetNames(typeof(Core.ConsolePlatform)).Skip(1).ToArray()); if (platformChooser.ShowDialog() == DialogResult.OK && Enum.IsDefined(typeof(ConsolePlatform), platformChooser.SelectedItem)) Settings.Default.Platform = (Core.ConsolePlatform)Enum.Parse(typeof(ConsolePlatform), platformChooser.SelectedItem); } ApplicationScope.Initialize(); - DLCManager.Default.SetPlatform(Settings.Default.Platform); Trace.TraceInformation("Startup"); RPC.Initialize(); MainInstance = new MainForm(); - Internal.SettingsManager.Default.RegisterPropertyChangedCallback(nameof(Settings.Default.UserLanguage), DLCManager.Default.SetPreferredLanguage); - Internal.SettingsManager.Default.RegisterPropertyChangedCallback(nameof(Settings.Default.Platform), DLCManager.Default.SetPlatform); Updater.SetOwner(MainInstance); if (args.Length > 0) { diff --git a/PCK-Studio/Rendering/ModelRenderer.cs b/PCK-Studio/Rendering/ModelRenderer.cs index cc1e05dd..f8dcb3e3 100644 --- a/PCK-Studio/Rendering/ModelRenderer.cs +++ b/PCK-Studio/Rendering/ModelRenderer.cs @@ -132,7 +132,7 @@ namespace PckStudio.Rendering return; } - for (int i = -1; i < modelMetaData.UvOffsets.Length; i++) + foreach (JsonModelMetaLayer layer in modelMetaData.Layers) { bool tryGetPart(string name, out ModelPart modelPart) { @@ -141,13 +141,8 @@ namespace PckStudio.Rendering modelPart = default; return false; } - if (i == -1 || !modelMetaData.UvOffsets.IndexInRange(i)) - { - modelPart = originalModelPart; - return true; - } - System.Numerics.Vector2 uvoffset = modelMetaData.UvOffsets[i]; - modelPart = new ModelPart(originalModelPart.Name, originalModelPart.ParentName, originalModelPart.Translation, originalModelPart.Rotation, originalModelPart.AdditionalRotation); + System.Numerics.Vector2 uvoffset = layer.Uv; + modelPart = new ModelPart(layer.Name ?? originalModelPart.Name, originalModelPart.ParentName, originalModelPart.Translation, originalModelPart.Rotation, originalModelPart.AdditionalRotation); modelPart.AddBoxes(originalModelPart.GetBoxes().Select(box => new ModelBox(box.Position, box.Size, box.Uv + uvoffset, box.Inflate, box.Mirror))); return true; } diff --git a/PCK-Studio/Rendering/SkinRenderer.cs b/PCK-Studio/Rendering/SkinRenderer.cs index cfa4a6ad..30481372 100644 --- a/PCK-Studio/Rendering/SkinRenderer.cs +++ b/PCK-Studio/Rendering/SkinRenderer.cs @@ -267,7 +267,6 @@ namespace PckStudio.Rendering private float animationMaxAngleInDegrees = 5f; private bool showWireFrame = false; - private bool autoInflateOverlayParts; private const float DEFAULT_ARM_ROTATION = 5f; @@ -750,7 +749,7 @@ namespace PckStudio.Rendering } CubeMeshCollection cubeMesh = meshStorage[skinBox.Type]; - cubeMesh.AddSkinBox(skinBox, autoInflateOverlayParts && skinBox.IsOverlayPart() ? skinBox.Type == "HEADWEAR" ? OVERLAY_SCALE * 2 : OVERLAY_SCALE : 0f); + cubeMesh.AddSkinBox(skinBox, skinBox.IsOverlayPart() ? skinBox.Type == "HEADWEAR" ? OVERLAY_SCALE * 2 : OVERLAY_SCALE : 0f); } private void OnANIMUpdate() @@ -1105,7 +1104,7 @@ namespace PckStudio.Rendering if (!meshStorage.ContainsKey(box.Type)) continue; - float inflate = autoInflateOverlayParts && box.IsOverlayPart() ? box.Type == "HEADWEAR" ? OVERLAY_SCALE * 2 : OVERLAY_SCALE : 0f; + float inflate = box.IsOverlayPart() ? box.Type == "HEADWEAR" ? OVERLAY_SCALE * 2 : OVERLAY_SCALE : 0f; Cube cube = box.ToCube(inflate); CubeMeshCollection cubeMesh = meshStorage[box.Type]; yield return cube.GetBoundingBox(cubeMesh.GetTransform()); diff --git a/PckStudio.Core/Animation.cs b/PckStudio.Core/Animation.cs index ec297c8c..145ea5ef 100644 --- a/PckStudio.Core/Animation.cs +++ b/PckStudio.Core/Animation.cs @@ -114,11 +114,11 @@ namespace PckStudio.Core return new ReadOnlyCollection(_frames); } - public IReadOnlyCollection GetInterpolatedFrames() + public IEnumerable GetInterpolatedFrames() { if (Interpolate) { - return new ReadOnlyCollection(InternalGetInterpolatedFrames().ToList()); + return InternalGetInterpolatedFrames(); } return GetFrames(); } @@ -133,7 +133,7 @@ namespace PckStudio.Core nextFrame = _frames[i + 1]; for (int tick = 0; tick < currentFrame.Ticks; tick++) { - double delta = 1.0f - tick / (double)currentFrame.Ticks; + float delta = 1.0f - tick / (float)currentFrame.Ticks; yield return new Frame(currentFrame.Texture.Interpolate(nextFrame.Texture, delta)); } } diff --git a/PckStudio.Core/Atlas.cs b/PckStudio.Core/Atlas/Atlas.cs similarity index 81% rename from PckStudio.Core/Atlas.cs rename to PckStudio.Core/Atlas/Atlas.cs index b3d1a58d..c0677808 100644 --- a/PckStudio.Core/Atlas.cs +++ b/PckStudio.Core/Atlas/Atlas.cs @@ -164,19 +164,19 @@ namespace PckStudio.Core { if (!group.IsAnimation()) return Animation.CreateEmpty(); - if (group is AtlasGroupLargeTileAnimation largeTileAnimation) + if (group is AtlasLargeTileAnimation largeTileAnimation) return GetLargeAnimation(largeTileAnimation); - return GetAnimation(group as AtlasGroupAnimation); + return GetAnimation(group as AtlasAnimation); } - private Animation GetLargeAnimation(AtlasGroupLargeTileAnimation group) + private Animation GetLargeAnimation(AtlasLargeTileAnimation group) { return new Animation(GetLargeAnimationTiles(group).Select(largeTileParts => largeTileParts.Select(t => t.Texture).Combine(group.RowSpan, group.ColumnSpan, _layoutDirection)), true, group.FrameTime); } - private IEnumerable> GetLargeAnimationTiles(AtlasGroupLargeTileAnimation group) => group.GetLargeTiles().Select(GetLargeTile); + private IEnumerable> GetLargeAnimationTiles(AtlasLargeTileAnimation group) => group.GetLargeTiles().Select(GetLargeTile); - private Animation GetAnimation(AtlasGroupAnimation groupAnimation) => new Animation(GetRange(groupAnimation.Row, groupAnimation.Column, groupAnimation.Direction == ImageLayoutDirection.Horizontal ? groupAnimation.Count : 1, groupAnimation.Direction == ImageLayoutDirection.Vertical ? groupAnimation.Count : 1).Select(t => t.Texture), true, groupAnimation.FrameTime); + private Animation GetAnimation(AtlasAnimation groupAnimation) => new Animation(GetRange(groupAnimation.Row, groupAnimation.Column, groupAnimation.Direction == ImageLayoutDirection.Horizontal ? groupAnimation.Count : 1, groupAnimation.Direction == ImageLayoutDirection.Vertical ? groupAnimation.Count : 1).Select(t => t.Texture), true, groupAnimation.FrameTime); private Image BuildFinalImage() { @@ -204,30 +204,50 @@ namespace PckStudio.Core SetRange(group.Row, group.Column, group.Count, group.Direction, animation.GetFrames().Select(f => f.Texture)); } - private IEnumerable GetLargeTile(AtlasGroupLargeTile group) => GetRange(group.Row, group.Column, group.RowSpan, group.ColumnSpan); + private IEnumerable GetLargeTile(AtlasLargeTile group) => GetRange(group.Row, group.Column, group.RowSpan, group.ColumnSpan); - public Image GetTileTexture(AtlasTile tile) + public Image GetTileTexture(AtlasTile tile, Color blendColor) { if (!tile.IsPartOfGroup) return tile; AtlasGroup atlasGroup = tile.GetGroup(); + if (atlasGroup.IsComposedOfMultipleTiles()) + return ComposeTileTexture(atlasGroup, blendColor); + if (!atlasGroup.IsLargeTile()) return tile; - AtlasGroupLargeTile largeTile = atlasGroup is AtlasGroupLargeTileAnimation largeTileAnimation ? largeTileAnimation.GetTile(tile.Row, tile.Column) : atlasGroup as AtlasGroupLargeTile; - return GetLargeTile(largeTile).Select(t => t.Texture).Combine(largeTile.RowSpan, largeTile.ColumnSpan, _layoutDirection); + AtlasLargeTile largeTile = atlasGroup is AtlasLargeTileAnimation largeTileAnimation ? largeTileAnimation.GetTile(tile.Row, tile.Column) : atlasGroup as AtlasLargeTile; + Image tileTexture = GetLargeTile(largeTile).Select(t => t.Texture).Combine(largeTile.RowSpan, largeTile.ColumnSpan, _layoutDirection); + return atlasGroup.AllowCustomColor ? tileTexture.Blend(BlendOption.Multiply(blendColor)) : tileTexture; + } + + private Image ComposeTileTexture(AtlasGroup atlasGroup, Color blendColor) + { + Image result = new Bitmap(TileSize.Width, TileSize.Height); + using Graphics g = Graphics.FromImage(result); + g.ApplyConfig(GraphicsConfig.PixelPerfect()); + + AtlasTile[] textures = atlasGroup.GetTileArea(new Size(1, 1)).Select(r => this[r.X, r.Y]).ToArray(); + if (textures.Length > 1) + { + g.DrawImage(textures[0].Texture.Blend(BlendOption.Multiply(blendColor)), Point.Empty); + g.DrawImage(textures[1], Point.Empty); + } + + return result; } private IEnumerable InternalGetTilesFromGroup(AtlasGroup atlasGroup, out int rowSpan, out int columnSpan) { - if (atlasGroup is AtlasGroupLargeTileAnimation largeTileAnimation) + if (atlasGroup is AtlasLargeTileAnimation largeTileAnimation) { rowSpan = largeTileAnimation.RowSpan; columnSpan = largeTileAnimation.ColumnSpan; return largeTileAnimation.GetLargeTiles().SelectMany(GetLargeTile); } - if (atlasGroup is AtlasGroupLargeTile largeTile) + if (atlasGroup is AtlasLargeTile largeTile) { rowSpan = largeTile.RowSpan; columnSpan = largeTile.ColumnSpan; @@ -235,15 +255,17 @@ namespace PckStudio.Core } rowSpan = 1; columnSpan = 1; + if (atlasGroup is AtlasOverlayGroup multipleTiles) + return multipleTiles.GetTileArea(new Size(1, 1)).Select(r => this[r.X, r.Y]); return GetRange(atlasGroup.Row, atlasGroup.Column, atlasGroup.Count, atlasGroup.Direction); } - public Rectangle GetTileArea(AtlasTile tile) + public Rectangle[] GetTileArea(AtlasTile tile) { if (!tile.IsPartOfGroup) - return tile.GetArea(TileSize); + return [tile.GetArea(TileSize)]; AtlasGroup group = tile.GetGroup(); - return new Rectangle(new Point(group.Row * TileSize.Width, group.Column * TileSize.Height), group.GetSize(TileSize)); + return group.GetTileArea(TileSize); } public bool SetGroup(AtlasGroup group, Image texture) diff --git a/PckStudio.Core/AtlasGroupAnimation.cs b/PckStudio.Core/Atlas/AtlasAnimation.cs similarity index 64% rename from PckStudio.Core/AtlasGroupAnimation.cs rename to PckStudio.Core/Atlas/AtlasAnimation.cs index aa662f2f..6363b410 100644 --- a/PckStudio.Core/AtlasGroupAnimation.cs +++ b/PckStudio.Core/Atlas/AtlasAnimation.cs @@ -16,25 +16,38 @@ * 3. This notice may not be removed or altered from any source distribution. **/ using System.Drawing; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; namespace PckStudio.Core { - internal sealed class AtlasGroupAnimation : AtlasGroup + internal sealed class AtlasAnimation : AtlasGroup { - public int FrameTime { get; } - public override int Count { get; } + [JsonProperty("frameCount", Required = Required.Always)] + private int _frameCount; + + [JsonProperty("frameTime")] + public int FrameTime { get; } = Animation.MINIMUM_FRAME_TIME; + + public override int Count => _frameCount; + + [JsonProperty("direction")] public override ImageLayoutDirection Direction { get; } + [JsonIgnore] protected override bool isAnimation => true; + [JsonIgnore] protected override bool isLargeTile => false; + protected override bool isComposedOfMultipleTiles => false; + public override Size GetSize(Size tileSize) => new Size(tileSize.Width * (Direction == ImageLayoutDirection.Horizontal ? Count : 1), tileSize.Height * (Direction == ImageLayoutDirection.Vertical ? Count : 1)); - public AtlasGroupAnimation(string name, int row, int column, int frameCount, ImageLayoutDirection direction, int frameTime = Animation.MINIMUM_FRAME_TIME) - : base(name, row, column) + public AtlasAnimation(string name, int row, int column, int frameCount, ImageLayoutDirection direction, int frameTime = Animation.MINIMUM_FRAME_TIME, bool allowCustomColor = default) + : base(name, row, column, allowCustomColor) { - Count = frameCount; + _frameCount = frameCount; Direction = direction; FrameTime = frameTime; } diff --git a/PckStudio.Core/AtlasGroup.cs b/PckStudio.Core/Atlas/AtlasGroup.cs similarity index 63% rename from PckStudio.Core/AtlasGroup.cs rename to PckStudio.Core/Atlas/AtlasGroup.cs index 3b2a53f0..46bec537 100644 --- a/PckStudio.Core/AtlasGroup.cs +++ b/PckStudio.Core/Atlas/AtlasGroup.cs @@ -17,32 +17,50 @@ **/ using System; using System.Drawing; +using Newtonsoft.Json; namespace PckStudio.Core { public abstract class AtlasGroup { + [JsonProperty("name", Required = Required.Always, Order = 0)] public string Name { get; set; } + [JsonProperty("row", Required = Required.Always, Order = 1)] public int Row { get; } + [JsonProperty("column", Required = Required.Always, Order = 2)] public int Column { get; } + [JsonProperty("allowCustomColor", DefaultValueHandling = DefaultValueHandling.Populate)] + public bool AllowCustomColor { get; } + [JsonIgnore] public virtual int Count => 1; + [JsonIgnore] protected abstract bool isAnimation { get; } + [JsonIgnore] protected abstract bool isLargeTile { get; } + [JsonIgnore] + protected abstract bool isComposedOfMultipleTiles { get; } + [JsonProperty("direction")] public virtual ImageLayoutDirection Direction => Column > Row ? ImageLayoutDirection.Vertical : ImageLayoutDirection.Horizontal; - public AtlasGroup(string name, int row, int column) + public AtlasGroup(string name, int row, int column, bool allowCustomColor) { Name = name; Row = Math.Max(0, row); Column = Math.Max(0, column); + AllowCustomColor = allowCustomColor; } public bool IsAnimation() => isAnimation; public bool IsLargeTile() => isLargeTile; + public bool IsComposedOfMultipleTiles() => isComposedOfMultipleTiles; public abstract Size GetSize(Size tileSize); + internal virtual Rectangle[] GetTileArea(Size tileSize) + { + return [new Rectangle(new Point(Row * tileSize.Width, Column * tileSize.Height), GetSize(tileSize))]; + } } } \ No newline at end of file diff --git a/PckStudio.Core/Atlas/AtlasGroupJsonConverter.cs b/PckStudio.Core/Atlas/AtlasGroupJsonConverter.cs new file mode 100644 index 00000000..03411dea --- /dev/null +++ b/PckStudio.Core/Atlas/AtlasGroupJsonConverter.cs @@ -0,0 +1,60 @@ +/* Copyright (c) 2025-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 Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using PckStudio.Core.Extensions; +using PckStudio.Core.Json; + +namespace PckStudio.Core +{ + public class AtlasGroupJsonConverter : JsonConverter + { + public override AtlasGroup ReadJson(JsonReader reader, Type objectType, AtlasGroup existingValue, bool hasExistingValue, JsonSerializer serializer) + { + JObject jObject = JObject.Load(reader); + + if (!jObject.TryGetValue("name", out string name) || !jObject.TryGetValue("row", out int row) || !jObject.TryGetValue("column", out int column)) + return default; + + bool allowCustomColor = default; + jObject.TryGetValue("allowCustomColor", out allowCustomColor); + if (jObject.TryGetValue("overlay", out JsonRowAndColumn rowsAndColumns)) + return new AtlasOverlayGroup(name, row, column, rowsAndColumns, allowCustomColor); + + int frameTime = Animation.MINIMUM_FRAME_TIME; + int frameCount = default; + int rowSpan = default; + int columnSpan = default; + ImageLayoutDirection direction = default; + bool isAnimation = jObject.TryGetValue("frameTime", out frameTime) && + jObject.TryGetValue("frameCount", out frameCount) && + jObject.TryGetValue("direction", out direction); + bool isLargeTile = jObject.TryGetValue("rowSpan", out rowSpan) && jObject.TryGetValue("columnSpan", out columnSpan); + if (isAnimation && isLargeTile) + return new AtlasLargeTileAnimation(name, row, column, rowSpan, columnSpan, frameCount, direction, frameTime, allowCustomColor); + if (isAnimation) + return new AtlasAnimation(name, row, column, frameCount, direction, frameTime, allowCustomColor); + if (isLargeTile) + return new AtlasLargeTile(name, row, column, rowSpan, columnSpan, allowCustomColor); + return default; + } + + public override void WriteJson(JsonWriter writer, AtlasGroup value, JsonSerializer serializer) => serializer.Serialize(writer, value); + } +} \ No newline at end of file diff --git a/PckStudio.Core/AtlasGroupLargeTile.cs b/PckStudio.Core/Atlas/AtlasLargeTile.cs similarity index 76% rename from PckStudio.Core/AtlasGroupLargeTile.cs rename to PckStudio.Core/Atlas/AtlasLargeTile.cs index 7475cf4f..988d8e3b 100644 --- a/PckStudio.Core/AtlasGroupLargeTile.cs +++ b/PckStudio.Core/Atlas/AtlasLargeTile.cs @@ -17,24 +17,32 @@ **/ using System; using System.Drawing; +using Newtonsoft.Json; namespace PckStudio.Core { - internal sealed class AtlasGroupLargeTile : AtlasGroup + internal sealed class AtlasLargeTile : AtlasGroup { + [JsonProperty("rowSpan")] public int RowSpan { get; } + [JsonProperty("columnSpan")] public int ColumnSpan { get; } + [JsonIgnore] public override int Count => RowSpan * ColumnSpan; + [JsonIgnore] protected override bool isAnimation => false; + [JsonIgnore] protected override bool isLargeTile => true; + protected override bool isComposedOfMultipleTiles => false; + public override Size GetSize(Size tileSize) => new Size(RowSpan * tileSize.Width, ColumnSpan * tileSize.Height); - public AtlasGroupLargeTile(string name, int row, int column, int rowSpan, int columnSpan) - : base(name, row, column) + public AtlasLargeTile(string name, int row, int column, int rowSpan, int columnSpan, bool allowCustomColor) + : base(name, row, column, allowCustomColor) { RowSpan = Math.Max(1, rowSpan); ColumnSpan = Math.Max(1, columnSpan); diff --git a/PckStudio.Core/AtlasGroupLargeTileAnimation.cs b/PckStudio.Core/Atlas/AtlasLargeTileAnimation.cs similarity index 69% rename from PckStudio.Core/AtlasGroupLargeTileAnimation.cs rename to PckStudio.Core/Atlas/AtlasLargeTileAnimation.cs index e0537197..fba91126 100644 --- a/PckStudio.Core/AtlasGroupLargeTileAnimation.cs +++ b/PckStudio.Core/Atlas/AtlasLargeTileAnimation.cs @@ -19,30 +19,43 @@ using System; using System.Collections.Generic; using System.Drawing; using System.Linq; +using Newtonsoft.Json; namespace PckStudio.Core { - internal sealed class AtlasGroupLargeTileAnimation : AtlasGroup + internal sealed class AtlasLargeTileAnimation : AtlasGroup { - private AtlasGroupLargeTile[] _largeTiles; + [JsonIgnore] + private AtlasLargeTile[] _largeTiles; + + [JsonProperty("frameCount")] private int _frameCount; + [JsonProperty("rowSpan")] public int RowSpan { get; } + [JsonProperty("columnSpan")] public int ColumnSpan { get; } + [JsonProperty("frameTime")] public int FrameTime { get; } + [JsonIgnore] public override int Count => RowSpan * ColumnSpan * _frameCount; + [JsonProperty("direction")] public override ImageLayoutDirection Direction { get; } + [JsonIgnore] protected override bool isAnimation => true; + [JsonIgnore] protected override bool isLargeTile => true; + protected override bool isComposedOfMultipleTiles => false; + public override Size GetSize(Size tileSize) => new Size(RowSpan * tileSize.Width * (Direction == ImageLayoutDirection.Horizontal ? _frameCount : 1), ColumnSpan * tileSize.Height * (Direction == ImageLayoutDirection.Vertical ? _frameCount : 1)); - public AtlasGroupLargeTileAnimation(string name, int row, int column, int rowSpan, int columnSpan, int frameCount, ImageLayoutDirection direction, int frameTime = Animation.MINIMUM_FRAME_TIME) - : base(name, row, column) + public AtlasLargeTileAnimation(string name, int row, int column, int rowSpan, int columnSpan, int frameCount, ImageLayoutDirection direction, int frameTime = Animation.MINIMUM_FRAME_TIME, bool allowCustomColor = default) + : base(name, row, column, allowCustomColor) { _frameCount = Math.Abs(frameCount); RowSpan = Math.Max(1, rowSpan); @@ -52,16 +65,16 @@ namespace PckStudio.Core _largeTiles = InternalGetLargeTiles().ToArray(); } - private IEnumerable InternalGetLargeTiles() + private IEnumerable InternalGetLargeTiles() { for (int i = 0; i < _frameCount; i++) { - yield return new AtlasGroupLargeTile($"{Name}_{i}", Row + (Direction == ImageLayoutDirection.Horizontal ? i * RowSpan : 0), Column + (Direction == ImageLayoutDirection.Vertical ? i * ColumnSpan : 0), RowSpan, ColumnSpan); + yield return new AtlasLargeTile($"{Name}_{i}", Row + (Direction == ImageLayoutDirection.Horizontal ? i * RowSpan : 0), Column + (Direction == ImageLayoutDirection.Vertical ? i * ColumnSpan : 0), RowSpan, ColumnSpan, AllowCustomColor); } yield break; } - internal AtlasGroupLargeTile GetTile(int row, int col) + internal AtlasLargeTile GetTile(int row, int col) { if (!IsInRange(row, col)) return default; @@ -74,6 +87,6 @@ namespace PckStudio.Core return Row <= row && row < (Row + (RowSpan * (Direction == ImageLayoutDirection.Horizontal ? _frameCount : 1))) && Column <= col && col < (Column + (ColumnSpan * (Direction == ImageLayoutDirection.Horizontal ? _frameCount : 1))); } - internal IEnumerable GetLargeTiles() => _largeTiles; + internal IEnumerable GetLargeTiles() => _largeTiles; } } \ No newline at end of file diff --git a/PckStudio.Core/Atlas/AtlasOverlayGroup.cs b/PckStudio.Core/Atlas/AtlasOverlayGroup.cs new file mode 100644 index 00000000..ae0eb208 --- /dev/null +++ b/PckStudio.Core/Atlas/AtlasOverlayGroup.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using PckStudio.Core.Json; + +namespace PckStudio.Core +{ + internal class AtlasOverlayGroup : AtlasGroup + { + private JsonRowAndColumn _overlayAtlasLocation; + + public AtlasOverlayGroup(string name, int row, int column, JsonRowAndColumn overlayAtlasLocation, bool allowCustomColor) + : base(name, row, column, allowCustomColor) + { + _overlayAtlasLocation = overlayAtlasLocation; + } + + protected override bool isAnimation => false; + + protected override bool isLargeTile => false; + + protected override bool isComposedOfMultipleTiles => true; + + public override Size GetSize(Size tileSize) => tileSize; + + internal override Rectangle[] GetTileArea(Size tileSize) => [new Rectangle(new Point(Row * tileSize.Width, Column * tileSize.Height), tileSize), new Rectangle(new Point(_overlayAtlasLocation.Row * tileSize.Width, _overlayAtlasLocation.Column * tileSize.Height), tileSize)]; + } +} \ No newline at end of file diff --git a/PckStudio.Core/AtlasTile.cs b/PckStudio.Core/Atlas/AtlasTile.cs similarity index 95% rename from PckStudio.Core/AtlasTile.cs rename to PckStudio.Core/Atlas/AtlasTile.cs index 093978c8..944c9748 100644 --- a/PckStudio.Core/AtlasTile.cs +++ b/PckStudio.Core/Atlas/AtlasTile.cs @@ -16,6 +16,7 @@ * 3. This notice may not be removed or altered from any source distribution. **/ using System; +using System.Diagnostics; using System.Drawing; namespace PckStudio.Core @@ -44,6 +45,7 @@ namespace PckStudio.Core internal void SetGroup(AtlasGroup group) { + Debug.Assert(_group is null, $"Tile is already part of group:'{_group?.Name}'"); _group = group; } diff --git a/PckStudio.Core/Box.cs b/PckStudio.Core/Box.cs new file mode 100644 index 00000000..93d85b48 --- /dev/null +++ b/PckStudio.Core/Box.cs @@ -0,0 +1,24 @@ +using System.Numerics; +using Newtonsoft.Json; + +namespace PckStudio.Core +{ + public class Box(Vector3 position, Vector3 size, Vector2 uv, float inflate, bool mirror) + { + + [JsonProperty("pos", Required = Required.Always)] + public Vector3 Position { get; } = position; + + [JsonProperty("size", Required = Required.Always)] + public Vector3 Size { get; } = size; + + [JsonProperty("uv", Required = Required.Always)] + public Vector2 Uv { get; } = uv; + + [JsonProperty("mirror", NullValueHandling = NullValueHandling.Ignore)] + public float Inflate { get; } = inflate; + + [JsonProperty("inflate", NullValueHandling = NullValueHandling.Ignore)] + public bool Mirror { get; } = mirror; + } +} diff --git a/PckStudio.Core/Colors/AbstractColorContainer.cs b/PckStudio.Core/Colors/AbstractColorContainer.cs new file mode 100644 index 00000000..0bbec161 --- /dev/null +++ b/PckStudio.Core/Colors/AbstractColorContainer.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OMI.Formats.Color; + +namespace PckStudio.Core.Colors +{ + public class AbstractColorContainer + { + public AbstractColorContainer(IDictionary colors, IDictionary waterColors) + { + Colors = colors; + WaterColors = waterColors; + } + + public bool HasColor(string colorName) => Colors.ContainsKey(colorName) || WaterColors.ContainsKey(colorName); + + public static AbstractColorContainer FromColorContainer(ColorContainer colorContainer) + { + IDictionary colors = colorContainer.Colors + .GroupBy(c => c.Name) + .Select(grp => grp.FirstOrDefault()) + .ToDictionary(c => c.Name, c => c.ColorPallette); + IDictionary waterColors = colorContainer.WaterColors + .GroupBy(c => c.Name) + .Select(grp => grp.FirstOrDefault()) + .ToDictionary(c => c.Name, c => (c.SurfaceColor, c.UnderwaterColor, c.FogColor)); + return new AbstractColorContainer(colors, waterColors); + } + + public IDictionary Colors { get; } + public IDictionary WaterColors { get; } + } +} diff --git a/PckStudio.Core/DLC/DLCManager.cs b/PckStudio.Core/DLC/DLCManager.cs index 31456516..0da5e96d 100644 --- a/PckStudio.Core/DLC/DLCManager.cs +++ b/PckStudio.Core/DLC/DLCManager.cs @@ -5,40 +5,47 @@ using System.Drawing; using System.Globalization; using System.IO; using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using System.Windows.Documents; using OMI; +using OMI.Formats.Color; using OMI.Formats.GameRule; using OMI.Formats.Languages; +using OMI.Formats.Model; using OMI.Formats.Pck; +using OMI.Workers.Color; using OMI.Workers.GameRule; using OMI.Workers.Language; +using OMI.Workers.Material; +using OMI.Workers.Model; using OMI.Workers.Pck; using PckStudio.Core.App; +using PckStudio.Core.Colors; using PckStudio.Core.Deserializer; using PckStudio.Core.Extensions; +using PckStudio.Core.FileFormats; using PckStudio.Core.Interfaces; using PckStudio.Core.IO.PckAudio; -using PckStudio.Core.Properties; +using PckStudio.Core.Model; using PckStudio.Interfaces; namespace PckStudio.Core.DLC { - public sealed class DLCManager + public class DLCManager { - public static DLCManager Default { get; } = new DLCManager(default, AppLanguage.SystemDefault); - internal const string DEFAULT_TEXTURE_PACK_FILENAME = "TexturePack.pck"; internal const string DEFAULT_MINIGAME_PACK_FILENAME = "WorldPack.pck"; internal const string DATA_DIRECTORY_NAME = "Data"; internal const string PACKAGE_DISPLAYNAME_ID = "IDS_DISPLAY_NAME"; + private const string BASE_SAVE_NAME_GRF_PARAMETER_KEY = "baseSaveName"; + private const string GRF_MAP_OPTIONS_NAME = "MapOptions"; + private const string TEXTURE_PACK_DATA_PATH_KEY = "DATAPATH"; + private const string CAPE_PATH_KEY = "CAPEPATH"; public ByteOrder ByteOrder => _byteOrder; public ConsolePlatform Platform => _platform; + public DLCPackageContentSerilasationType ContentSerilasationType { get; set; } = DLCPackageContentSerilasationType.Local; + /// /// See for details. /// @@ -48,6 +55,7 @@ namespace PckStudio.Core.DLC private readonly Random _rng = new Random(); private ByteOrder _byteOrder; private ConsolePlatform _platform; + private PckFileCompiler _pckFileCompiler; /// @@ -57,6 +65,7 @@ namespace PckStudio.Core.DLC { _platform = platform; _byteOrder = GetByteOrderForPlatform(Platform); + _pckFileCompiler = new PckFileCompiler(_byteOrder, GetPlatformCompressionType(), GameRuleFile.CompressionLevel.None); SetPreferredLanguage(preferredLanguage); } @@ -82,7 +91,7 @@ namespace PckStudio.Core.DLC DLCPackageType.MG01 => new DLCBattlePackage(name, identifier), DLCPackageType.MG02 => new DLCMiniGamePackage(name, identifier, packageType, MiniGameId.Tumble), DLCPackageType.MG03 => new DLCMiniGamePackage(name, identifier, packageType, MiniGameId.Glide), - DLCPackageType.Invalid => InvalidDLCPackage.Instance, + DLCPackageType.Invalid => DLCPackage.Invalid, _ => throw new ArgumentException("Unable to create DLC Package of 'Unknown' type."), }; @@ -90,7 +99,7 @@ namespace PckStudio.Core.DLC localisation.AddLanguage(PreferredLanguage); localisation.AddLocKey(PACKAGE_DISPLAYNAME_ID, name); _packageRegistry.RegisterPackage(identifier, package, localisation); - + return package; } @@ -102,7 +111,7 @@ namespace PckStudio.Core.DLC throw new Exception($"{nameof(Platform)} is Unknown."); if (!IsValidPckFile(fileInfo)) - return InvalidDLCPackage.Instance; + return DLCPackage.Invalid; using Stream stream = fileInfo.OpenRead(); @@ -113,14 +122,14 @@ namespace PckStudio.Core.DLC if (!pckFile.TryGetAsset("0", PckAssetType.InfoFile, out PckAsset zeroAsset)) { Trace.TraceError("Could not find asset named:'0'."); - return new UnknownDLCPackage(fileInfo.Name, pckFile); + return new RawAssetDLCPackage(fileInfo.Name, pckFile, ByteOrder); } - int identifier = (zeroAsset?.HasProperty("PACKID") ?? default) ? zeroAsset.GetProperty("PACKID", int.Parse) : -1; - if (identifier <= 0 || identifier > GameConstants.MAX_PACK_ID) + int identifier = zeroAsset.HasProperty("PACKID") ? zeroAsset.GetProperty("PACKID", int.Parse) : -1; + if (!identifier.IsWithinRangeOf(1, GameConstants.MAX_PACK_ID)) { Trace.TraceError($"{nameof(identifier)}({identifier}) was out of range!"); - return new UnknownDLCPackage(fileInfo.Name, pckFile); + return new RawAssetDLCPackage(fileInfo.Name, pckFile, ByteOrder); } if (_packageRegistry.ContainsPackage(identifier)) @@ -128,16 +137,21 @@ namespace PckStudio.Core.DLC LOCFile localisation = pckFile.GetAssetsByType(PckAssetType.LocalisationFile).FirstOrDefault()?.GetData(new LOCFileReader()); if (localisation is null) - return new UnknownDLCPackage(fileInfo.Name, pckFile); + { + Trace.TraceError("No localisation asset found."); + return new RawAssetDLCPackage(fileInfo.Name, pckFile, ByteOrder); + } - IDLCPackage package = ScanForPackageType(fileInfo, identifier, pckFile, localisation, fileReader); + IDLCPackage package = LoadDLCPackage(fileInfo, identifier, pckFile, localisation, fileReader); if (package.GetDLCPackageType() != DLCPackageType.Invalid) { _packageRegistry.RegisterPackage(identifier, package, localisation); } - return package; + return new RawAssetDLCPackage(fileInfo.Name, pckFile, ByteOrder); } + public bool CloseDLCPackage(int identifier) => _packageRegistry.UnregisterPackage(identifier); + internal LOCFile GetLocalisation(int identifier) { return _packageRegistry.ContainsPackage(identifier) ? _packageRegistry.GetLocalisation(identifier) : default; @@ -156,7 +170,7 @@ namespace PckStudio.Core.DLC return true; } - private IDLCPackage ScanForPackageType(FileInfo fileInfo, int identifier, PckFile pckFile, LOCFile localisation, PckFileReader fileReader) + private IDLCPackage LoadDLCPackage(FileInfo fileInfo, int identifier, PckFile pckFile, LOCFile localisation, PckFileReader fileReader) { bool hasLanguage = localisation?.Languages?.Contains(PreferredLanguage) ?? default; @@ -170,52 +184,61 @@ namespace PckStudio.Core.DLC bool couldBeMiniGamePack = fileInfo.Name == DEFAULT_MINIGAME_PACK_FILENAME; bool hasSkins = TryGetDLCSkinPackage(name, identifier, pckFile, fileReader, out IDLCPackage skinPackage); - DLCPackageType dlcPackageType = hasSkins ? DLCPackageType.SkinPack : DLCPackageType.Unknown; DirectoryInfo dataDirectoryInfo = fileInfo.Directory.EnumerateDirectories().Where(dirInfo => dirInfo.Name == DATA_DIRECTORY_NAME).FirstOrDefault(); if (dataDirectoryInfo is null) - return hasSkins ? skinPackage : InvalidDLCPackage.Instance; - - bool hasTexturePack = TryGetTexturePack(name, description, identifier, dataDirectoryInfo, pckFile, fileReader, out IDLCPackage texturePackage); - if (hasTexturePack) { - dlcPackageType = DLCPackageType.TexturePack; - } - - Dictionary> mapData = GetMapData(pckFile, dataDirectoryInfo); - - if (mapData.Count == 1) - { - dlcPackageType = DLCPackageType.MashUpPack; - } - - Debug.WriteLine(dlcPackageType); - return new UnknownDLCPackage(name, pckFile); - } - - private Dictionary> GetMapData(PckFile pck, DirectoryInfo dataDirectory) - { - GameRuleFile.CompressionType compressionType = GetPlatformCompressionType(); - var reader = new GameRuleFileReader(compressionType); - IEnumerable values = pck.GetAssetsByType(PckAssetType.GameRulesFile) - .Concat(pck.GetAssetsByType(PckAssetType.GameRulesHeader)) - .Select(asset => asset.GetData(reader)) - .SelectMany(grf => grf.Root.GetRules().Where(rule => rule.Name == "MapOptions" && rule.ContainsParameter("baseSaveName"))) - .Select(rule => rule.GetRule("MapOptions").GetParameterValue("baseSaveName")); - - Dictionary> saves = new Dictionary>(); - foreach (FileInfo worldFile in dataDirectory.EnumerateFiles("*.mcs").Where(file => values.Contains(file.Name))) - { - IDictionary save = MapReader.OpenSave(worldFile.OpenRead()); - saves.Add(worldFile.Name, save); + Trace.TraceInformation("No data directory found."); + return skinPackage ?? new RawAssetDLCPackage(name, pckFile, ByteOrder); } - return saves; + bool hasTexturePack = TryGetTexturePack(name, description, identifier, dataDirectoryInfo, pckFile, fileReader, out IDLCPackage texturePackage); + if (!hasTexturePack) + { + Trace.TraceWarning("Couldn't parse texturepack."); + return skinPackage ?? new RawAssetDLCPackage(name, pckFile, ByteOrder); + } + + PckAudioFile pckAudioFile = pckFile.GetAssetsByType(PckAssetType.AudioFile).FirstOrDefault()?.GetData(new PckAudioFileReader(ByteOrder)); + IDictionary audios = default; + if (pckAudioFile != null) + { + var songs = pckAudioFile.Categories.SelectMany(audioCategory => audioCategory.SongNames).ToList(); + audios = dataDirectoryInfo.EnumerateFiles("*.binka") + .Where(audioFile => songs.Contains(Path.GetFileNameWithoutExtension(audioFile.Name))) + .ToDictionary(audioFile => audioFile.Name, audioFile => File.ReadAllBytes(audioFile.FullName)); + } + + GameRuleFile.CompressionType compressionType = GetPlatformCompressionType(); + var reader = new GameRuleFileReader(compressionType); + IEnumerable gameRules = pckFile.GetAssetsByType(PckAssetType.GameRulesFile) + .Concat(pckFile.GetAssetsByType(PckAssetType.GameRulesHeader)) + .Select(asset => asset.GetData(reader)); + + Dictionary mapData = GetMapData(gameRules, dataDirectoryInfo); + if (mapData.Count == 0) + return texturePackage ?? skinPackage ?? new RawAssetDLCPackage(name, pckFile, ByteOrder); + + if (mapData.Count == 1) + return new DLCMashUpPackage(name, description, identifier, null, null, pckAudioFile, audios, parentPackage: null, skinPackage: skinPackage, texturePackage: texturePackage); + + return new RawAssetDLCPackage(name, pckFile, ByteOrder); + } + + private Dictionary GetMapData(IEnumerable gameRuleFiles, DirectoryInfo dataDirectory) + { + IEnumerable values = gameRuleFiles + .SelectMany(grf => grf.Root.GetRules().Where(rule => rule.Name == GRF_MAP_OPTIONS_NAME && rule.ContainsParameter(BASE_SAVE_NAME_GRF_PARAMETER_KEY))) + .Select(rule => rule.GetParameterValue(BASE_SAVE_NAME_GRF_PARAMETER_KEY)); + + return dataDirectory.EnumerateFiles("*.mcs") + .Where(file => values.Contains(file.Name)) + .ToDictionary(worldFile => worldFile.Name, worldFile => MapReader.OpenSaveData(worldFile.OpenRead())); } private bool TryGetTexturePack(string name, string description, int identifier, DirectoryInfo dataDirectoryInfo, PckFile pckFile, PckFileReader pckFormatReader, out IDLCPackage texturePackage) - { + { if (dataDirectoryInfo is null) { texturePackage = default; @@ -229,19 +252,19 @@ namespace PckStudio.Core.DLC } DLCTexturePackage.TextureResolution resolution = DLCTexturePackage.GetTextureResolutionFromString(texturePackInfo.Filename); - string dataPath = texturePackInfo.GetProperty("DATAPATH"); + string dataPath = texturePackInfo.GetProperty(TEXTURE_PACK_DATA_PATH_KEY); if (string.IsNullOrWhiteSpace(dataPath)) { texturePackage = default; return false; - } + } PckFile infoPck = texturePackInfo.GetData(pckFormatReader); FileInfo texturePackFileInfo = dataDirectoryInfo.EnumerateFiles().Where(fileInfo => fileInfo.Name == dataPath).FirstOrDefault(); if (!IsValidPckFile(texturePackFileInfo)) - { + { texturePackage = null; return false; } @@ -250,16 +273,8 @@ namespace PckStudio.Core.DLC PckFile texturePackPck = pckFormatReader.FromStream(texturePackFileStream); texturePackage = GetTexturePackageFromPckFile(name, description, identifier, infoPck, texturePackPck, resolution); - IEnumerable audioFiles = dataDirectoryInfo.EnumerateFiles("*.binka"); - IDictionary audios = new Dictionary(); - foreach (FileInfo audioFile in audioFiles) - { - byte[] data = File.ReadAllBytes(audioFile.FullName); - audios.Add(audioFile.Name, data); - } - return texturePackage is not null; - } + } private IDLCPackage GetTexturePackageFromPckFile(string name, string description, int identifier, PckFile infoPck, PckFile dataPck, DLCTexturePackage.TextureResolution resolution) { @@ -267,68 +282,103 @@ namespace PckStudio.Core.DLC return null; if (!infoPck.TryGetAsset("comparison.png", PckAssetType.TextureFile, out PckAsset comparisonAsset)) - { - Trace.TraceError($"Could not find 'comparison.png'."); - } + Trace.TraceWarning($"Could not find 'comparison.png'."); + if (!infoPck.TryGetAsset("icon.png", PckAssetType.TextureFile, out PckAsset iconnAsset)) - { - Trace.TraceError($"Could not find 'icon.png'."); - } + Trace.TraceWarning($"Could not find 'icon.png'."); - Image comparisonImg = comparisonAsset?.GetTexture(); - Image iconImg = iconnAsset?.GetTexture() ?? Resources.unknown_pack; - DLCTexturePackage.MetaData metaData = new DLCTexturePackage.MetaData(comparisonImg, iconImg); + DLCTexturePackage.MetaData metaData = new DLCTexturePackage.MetaData(comparisonAsset?.GetTexture(), iconnAsset?.GetTexture()); - bool hasTerrainAtlas = TryGetAtlasFromResourceCategory(dataPck, ResourceCategory.BlockAtlas, out Atlas terrainAtlas); - bool hasItemAtlas = TryGetAtlasFromResourceCategory(dataPck, ResourceCategory.ItemAtlas, out Atlas itemAtlas); - bool hasParticleAtlas = TryGetAtlasFromResourceCategory(dataPck, ResourceCategory.ParticleAtlas, out Atlas particleAtlas); - bool hasPaintingAtlas = TryGetAtlasFromResourceCategory(dataPck, ResourceCategory.PaintingAtlas, out Atlas paintingAtlas); + TryGetAtlasFromResourceCategory(dataPck, AtlasResource.AtlasType.BlockAtlas, out Atlas terrainAtlas); + TryGetAtlasFromResourceCategory(dataPck, AtlasResource.AtlasType.ItemAtlas, out Atlas itemAtlas); + TryGetAtlasFromResourceCategory(dataPck, AtlasResource.AtlasType.ParticleAtlas, out Atlas particleAtlas); + TryGetAtlasFromResourceCategory(dataPck, AtlasResource.AtlasType.PaintingAtlas, out Atlas paintingAtlas); + TryGetAtlasFromResourceCategory(dataPck, AtlasResource.AtlasType.MoonPhaseAtlas, out Atlas moonPhaseAtlas); + TryGetAtlasFromResourceCategory(dataPck, AtlasResource.AtlasType.MapIconAtlas, out Atlas mapIconsAtlas); + TryGetAtlasFromResourceCategory(dataPck, AtlasResource.AtlasType.AdditionalMapIconsAtlas, out Atlas additionalMapIconsAtlas); string itemAnimationAssetPath = ResourceLocation.GetPathFromCategory(ResourceCategory.ItemAnimation); + string blockAnimationAssetPath = ResourceLocation.GetPathFromCategory(ResourceCategory.BlockAnimation); IPckAssetDeserializer deserializer = AnimationDeserializer.DefaultDeserializer; - Animation compassAnimation = dataPck.TryGetAsset(itemAnimationAssetPath + "/compass.png", PckAssetType.TextureFile, out PckAsset compassAsset) ? comparisonAsset.GetDeserializedData(deserializer) : Animation.CreateEmpty(); - Animation clockAnimation = dataPck.TryGetAsset(itemAnimationAssetPath + "/clock.png", PckAssetType.TextureFile, out PckAsset clockAsset) ? clockAsset.GetDeserializedData(deserializer) : Animation.CreateEmpty(); - if (compassAnimation.FrameCount == 0) + IDictionary itemAnimations = dataPck.GetDirectoryContent(itemAnimationAssetPath, PckAssetType.TextureFile) + .Where(asset => !asset.IsMipmappedFile()) + .ToDictionary(asset => Path.GetFileNameWithoutExtension(asset.Filename), deserializer.Deserialize); + + IDictionary blockAnimations = dataPck.GetDirectoryContent(blockAnimationAssetPath, PckAssetType.TextureFile) + .Where(asset => !asset.IsMipmappedFile()) + .ToDictionary(asset => Path.GetFileNameWithoutExtension(asset.Filename), deserializer.Deserialize); + + if (!itemAnimations.ContainsKey("compass")) Trace.TraceError("No compass animation found!"); - if (clockAnimation.FrameCount == 0) + if (!itemAnimations.ContainsKey("clock")) Trace.TraceError("No clock animation found!"); - ITryGet tryGet = TryGet.FromDelegate((string path, out Image image) => + ITryGet tryGetTexture = TryGet.FromDelegate((string path, out Image image) => { bool success = dataPck.TryGetAsset(path, PckAssetType.TextureFile, out PckAsset asset); image = asset?.GetTexture(); return success; }); - - Image[] blockEntityBreakingAnimation = new Image[10]; - for (int i = 0; i < blockEntityBreakingAnimation.Length; i++) + + ImageDeserializer defaultDeserializer = ImageDeserializer.DefaultDeserializer; + IEnumerable blockEntityBreakingFrames = dataPck.GetDirectoryContent("res/textures/", PckAssetType.TextureFile) + .Select(defaultDeserializer.Deserialize); + Animation blockEntityBreakAnimation = new Animation(blockEntityBreakingFrames); + + ColorContainer colorContainer = dataPck.GetAssetsByType(PckAssetType.ColourTableFile).FirstOrDefault()?.GetData(new COLFileReader()) ?? new ColorContainer(); + + IDictionary environmentTextures = dataPck.GetDirectoryContent("res/environment/", PckAssetType.TextureFile) + .ToDictionary(a => Path.GetFileNameWithoutExtension(a.Filename), defaultDeserializer.Deserialize); + environmentTextures.TryGetValue("clouds", out Image clouds); + environmentTextures.TryGetValue("rain", out Image rain); + environmentTextures.TryGetValue("snow", out Image snow); + + DLCTexturePackage.EnvironmentData environmentData = new DLCTexturePackage.EnvironmentData(clouds, rain, snow); + + IDictionary terrainTextures = dataPck.GetDirectoryContent("res/terrain/", PckAssetType.TextureFile) + .ToDictionary(a => Path.GetFileNameWithoutExtension(a.Filename), defaultDeserializer.Deserialize); + + terrainTextures.TryGetValue("sun", out Image sun); + terrainTextures.TryGetValue("moon", out Image moon); + + AbstractModelContainer customModels = null; + if (dataPck.TryGetAsset("models.bin", PckAssetType.ModelsFile, out PckAsset modelsAsset)) { - if (dataPck.TryGetAsset("", PckAssetType.TextureFile, out PckAsset asset)) - blockEntityBreakingAnimation[i] = asset.GetTexture(); + ModelContainer models = modelsAsset.GetData(new ModelFileReader()); + customModels = AbstractModelContainer.FromModelContainer(models, null); } - ArmorSet[] armorSets = new ArmorSet[6] - { - ArmorSetDescription.Leather.GetArmorSet(tryGet), - ArmorSetDescription.Chain.GetArmorSet(tryGet), - ArmorSetDescription.Iron.GetArmorSet(tryGet), - ArmorSetDescription.Gold.GetArmorSet(tryGet), - ArmorSetDescription.Diamond.GetArmorSet(tryGet), - ArmorSetDescription.Turtle.GetArmorSet(tryGet) - }; - return new DLCTexturePackage(name, description, identifier, metaData, resolution, terrainAtlas, itemAtlas, particleAtlas, paintingAtlas, - armorSets, null, null, null, null, null, null, null, null); + IDictionary materials = dataPck.GetAssetsByType(PckAssetType.MaterialFile).FirstOrDefault()?.GetData(new MaterialFileReader()) + .ToDictionary(mat => mat.Name, mat => mat.Type); + + return new DLCTexturePackage(name, description, identifier, metaData, resolution, + terrainAtlas, itemAtlas, particleAtlas, paintingAtlas, moonPhaseAtlas, mapIconsAtlas, additionalMapIconsAtlas, + ArmorSetDescription.Leather.GetArmorSet(tryGetTexture), + ArmorSetDescription.Chain.GetArmorSet(tryGetTexture), + ArmorSetDescription.Iron.GetArmorSet(tryGetTexture), + ArmorSetDescription.Gold.GetArmorSet(tryGetTexture), + ArmorSetDescription.Diamond.GetArmorSet(tryGetTexture), + ArmorSetDescription.Turtle.GetArmorSet(tryGetTexture), + environmentData, + AbstractColorContainer.FromColorContainer(colorContainer), + customModels, + materials, + blockEntityBreakAnimation, + itemAnimations, + blockAnimations, + sun, moon, + parentPackage: null); } - private bool TryGetAtlasFromResourceCategory(PckFile pck, ResourceCategory resourceCategory, out Atlas atlas) + private bool TryGetAtlasFromResourceCategory(PckFile pck, AtlasResource.AtlasType atlasType, out Atlas atlas) { - ResourceLocation resourceLocation = ResourceLocation.GetFromCategory(resourceCategory); - if (!pck.TryGetAsset(resourceLocation.ToString(), PckAssetType.TextureFile, out PckAsset asset)) + ResourceLocation resourceLocation = ResourceLocation.GetFromCategory(AtlasResource.GetId(atlasType)); + if (!pck.TryGetAsset(resourceLocation.FullPath, PckAssetType.TextureFile, out PckAsset asset)) { - Trace.TraceWarning($"Could not find '{resourceLocation}'."); + Trace.TraceWarning($"Could not find '{resourceLocation.FullPath}'."); atlas = null; return false; } @@ -351,7 +401,7 @@ namespace PckStudio.Core.DLC Skin.Skin GetSkinWithCape(PckAsset skinAsset) { Skin.Skin skin = skinAsset.GetSkin(); - if (skinAsset.TryGetProperty("CAPEPATH", out string capeAssetPath) && pck.TryGetAsset(capeAssetPath, PckAssetType.CapeFile, out PckAsset capeAsset)) + if (skinAsset.TryGetProperty(CAPE_PATH_KEY, out string capeAssetPath) && pck.TryGetAsset(capeAssetPath, PckAssetType.CapeFile, out PckAsset capeAsset)) skin.CapeId = capeAsset.GetId(); return skin; } @@ -367,8 +417,32 @@ namespace PckStudio.Core.DLC skinPackage = new DLCSkinPackage(name, identifier, skins, capes, parentPackage); return true; } + + public static GameRuleFile.CompressionType GetCompressionTypeForPlatform(ConsolePlatform platform) + { + switch (platform) + { + case ConsolePlatform.Xbox360: + return GameRuleFile.CompressionType.XMem; + + case ConsolePlatform.PS3: + return GameRuleFile.CompressionType.Deflate; + + case ConsolePlatform.XboxOne: + case ConsolePlatform.PS4: + case ConsolePlatform.PSVita: + case ConsolePlatform.WiiU: + case ConsolePlatform.Switch: + return GameRuleFile.CompressionType.Zlib; + + case ConsolePlatform.Unknown: + default: + throw new ArgumentException("Platform was not set"); + } } + private GameRuleFile.CompressionType GetPlatformCompressionType() => GetCompressionTypeForPlatform(Platform); + private static string GetPreferredLanguage(AppLanguage appLanguage) { return appLanguage switch @@ -424,5 +498,26 @@ namespace PckStudio.Core.DLC _platform = platform; _byteOrder = GetByteOrderForPlatform(platform); } + + public DLCPackageContent CompilePackage(IDLCPackage package) + { + LOCFile localisation = GetLocalisation(package.Identifier); + switch (package.GetDLCPackageType()) + { + case DLCPackageType.Invalid: + break; + case DLCPackageType.RawAssets: return _pckFileCompiler.CompileRawAssets(package); + case DLCPackageType.SkinPack: return _pckFileCompiler.CompileSkinPackage(package, localisation); + case DLCPackageType.TexturePack: return _pckFileCompiler.CompileTexturePackage(package, localisation); + case DLCPackageType.MashUpPack: return _pckFileCompiler.CompileMashUpPackage(package, localisation); + case DLCPackageType.MG01: + break; + case DLCPackageType.MG02: + break; + case DLCPackageType.MG03: + break; + } + return DLCPackageContent.Empty; + } } } \ No newline at end of file diff --git a/PckStudio.Core/DLC/DLCMashUpPackage.cs b/PckStudio.Core/DLC/DLCMashUpPackage.cs index 5f8f022a..134b1081 100644 --- a/PckStudio.Core/DLC/DLCMashUpPackage.cs +++ b/PckStudio.Core/DLC/DLCMashUpPackage.cs @@ -15,7 +15,7 @@ namespace PckStudio.Core.DLC public sealed class DLCMashUpPackage : DLCPackage { public override string Description { get; } - private AbstractGameRule _gameRule { get; } + private AbstractGameRule _gameRule; public bool HasAudioData => _pckAudio is not null && _audioData.Count > 0; private IDLCPackage _skinPackage; @@ -24,30 +24,45 @@ namespace PckStudio.Core.DLC private IDictionary _audioData; private PckAudioFile _pckAudio; - internal DLCMashUpPackage(string name, string description, int identifier, AbstractGameRule gameRule, IDLCPackage parentPackage, IDLCPackage skinPackage = null, IDLCPackage texturePackage = null) + internal DLCMashUpPackage(string name, string description, int identifier, AbstractGameRule gameRule, MapData mapData, PckAudioFile pckAudio, IDictionary audioData, IDLCPackage parentPackage, IDLCPackage skinPackage = null, IDLCPackage texturePackage = null) : base(name, identifier, parentPackage) { Description = description; _gameRule = gameRule; _skinPackage = skinPackage; _texturePackage = texturePackage; + _mapData = mapData; + _audioData = new Dictionary(); + _pckAudio = pckAudio; + _audioData = audioData; } internal DLCMashUpPackage(string name, string description, int identifier) - : this(name, description, identifier, new RootGameRule(), null) + : this(name, description, identifier, new RootGameRule(), null, new PckAudioFile(), null, null) { _skinPackage = DLCSkinPackage.CreateEmpty(this); _texturePackage = DLCTexturePackage.CreateDefaultPackage(this); - _audioData = new Dictionary(); - _pckAudio = new PckAudioFile(); } + public override DLCPackageType GetDLCPackageType() => DLCPackageType.MashUpPack; + public IDLCPackage GetSkinPackage() => _skinPackage; public IDLCPackage GetTexturePackage() => _texturePackage; - public AbstractGameRule GetGameRule() => _gameRule; - public PckAudioFile GetAudioPack() => _pckAudio; - public override DLCPackageType GetDLCPackageType() => DLCPackageType.MashUpPack; + public bool AddAudio(string name, byte[] audioData, PckAudioFile.Category category) + { + if (_audioData.ContainsKey(name) || !_pckAudio.HasCategory(category)) + return false; + if (_pckAudio.TryGetCategory(category, out PckAudioFile.AudioCategory audioCategory)) + { + audioCategory.SongNames.Add(name); + return true; + } + return false; + } + + public AbstractGameRule GetGameRule() => _gameRule; + internal PckAudioFile GetAudioPack() => _pckAudio; internal NamedData[] GetAudioFiles() => _audioData.Select(kv => new NamedData(kv.Key, kv.Value)).ToArray(); } diff --git a/PckStudio.Core/DLC/DLCPackage.cs b/PckStudio.Core/DLC/DLCPackage.cs index c9d4e8c2..5cb83563 100644 --- a/PckStudio.Core/DLC/DLCPackage.cs +++ b/PckStudio.Core/DLC/DLCPackage.cs @@ -10,6 +10,7 @@ namespace PckStudio.Core.DLC { public abstract class DLCPackage : IDLCPackage { + public static IDLCPackage Invalid = new InvalidDLCPackage(); protected DLCPackage(string name, int identifier, IDLCPackage parentPackage) { Name = name; @@ -17,6 +18,13 @@ namespace PckStudio.Core.DLC ParentPackage = parentPackage; } + private sealed class InvalidDLCPackage : DLCPackage + { + internal InvalidDLCPackage() : base(nameof(InvalidDLCPackage), -1, null) { } + + public override DLCPackageType GetDLCPackageType() => DLCPackageType.Invalid; + } + public int Identifier { get; } public string Name { get; } = string.Empty; diff --git a/PckStudio.Core/DLC/DLCPackageContent.cs b/PckStudio.Core/DLC/DLCPackageContent.cs new file mode 100644 index 00000000..a3b4965c --- /dev/null +++ b/PckStudio.Core/DLC/DLCPackageContent.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using OMI.Formats.Pck; + +namespace PckStudio.Core.DLC +{ + public class DLCPackageContent + { + public static DLCPackageContent Empty => new DLCPackageContent(default); + + internal bool IsEmpty { get; } + + internal PckFile MainPck { get; } + + internal DLCDataFolderContent DataFolder { get; } + + public record DLCDataFolderContent + { + public NamedData TexturePck { get; } + public List> Files { get; } + + public DLCDataFolderContent(NamedData texturePck, NamedData[] files) + { + TexturePck = texturePck; + Files = new List>(files); + } + + public void AddFile(NamedData namedData) => Files.Add(namedData); + public void AddFiles(NamedData[] namedData) => Files.AddRange(namedData); + public void AddFile(string name, byte[] data) => AddFile(new NamedData(name, data)); + } + + public DLCPackageContent(PckFile mainPck, NamedData texturePck, NamedData[] dataFiles) + : this(mainPck, new(texturePck, dataFiles ?? Array.Empty>())) + { + } + + public DLCPackageContent(PckFile mainPck, DLCDataFolderContent dataFolderContent) + { + MainPck = mainPck; + DataFolder = dataFolderContent; + IsEmpty = mainPck is null; + } + + public DLCPackageContent(PckFile mainPck) : this(mainPck, default) { } + } +} \ No newline at end of file diff --git a/PckStudio.Core/DLC/DLCPackageContentSerilasationType.cs b/PckStudio.Core/DLC/DLCPackageContentSerilasationType.cs new file mode 100644 index 00000000..8e227afb --- /dev/null +++ b/PckStudio.Core/DLC/DLCPackageContentSerilasationType.cs @@ -0,0 +1,8 @@ +namespace PckStudio.Core.DLC +{ + public enum DLCPackageContentSerilasationType : int + { + Local, //! create local folder with the value of: ('IDS_DISPLAY_NAME') and write all content into it. + Share //! zip file if texture or mashup pack, else just the pck file. + } +} \ No newline at end of file diff --git a/PckStudio.Core/DLC/DLCPackageRegistry.cs b/PckStudio.Core/DLC/DLCPackageRegistry.cs index c38cc740..b7f33fd5 100644 --- a/PckStudio.Core/DLC/DLCPackageRegistry.cs +++ b/PckStudio.Core/DLC/DLCPackageRegistry.cs @@ -29,5 +29,10 @@ namespace PckStudio.Core.DLC internal bool ContainsPackage(int identifier) => _openPackages.ContainsKey(identifier) && _localisationFiles.ContainsKey(identifier); internal LOCFile GetLocalisation(int identifier) => _localisationFiles[identifier]; + + internal bool UnregisterPackage(int identifier) + { + return _openPackages.Remove(identifier) && _localisationFiles.Remove(identifier); + } } } diff --git a/PckStudio.Core/DLC/DLCPackageType.cs b/PckStudio.Core/DLC/DLCPackageType.cs index c7a41062..1b51a600 100644 --- a/PckStudio.Core/DLC/DLCPackageType.cs +++ b/PckStudio.Core/DLC/DLCPackageType.cs @@ -2,8 +2,8 @@ { public enum DLCPackageType : int { - Unknown = -1, - Invalid, + Invalid = -1, + RawAssets, SkinPack, TexturePack, MashUpPack, diff --git a/PckStudio.Core/DLC/DLCSkinPackage.cs b/PckStudio.Core/DLC/DLCSkinPackage.cs index 9adb9397..7e9a2c0f 100644 --- a/PckStudio.Core/DLC/DLCSkinPackage.cs +++ b/PckStudio.Core/DLC/DLCSkinPackage.cs @@ -11,13 +11,12 @@ namespace PckStudio.Core.DLC public enum DLCSkinPackageOrder { ById, - CapesFirst, - SkinsFirst + ByName, } public sealed class DLCSkinPackage : DLCPackage { - public DLCSkinPackageOrder SkinPackageOrder { get; set; } = DLCSkinPackageOrder.CapesFirst; + public DLCSkinPackageOrder SkinPackageOrder { get; set; } = DLCSkinPackageOrder.ById; private readonly IDictionary _capes; private readonly IDictionary _skins; @@ -38,6 +37,7 @@ namespace PckStudio.Core.DLC internal static IDLCPackage CreateEmpty(IDLCPackage parentPackage) => CreateEmpty(parentPackage.Name, parentPackage.Identifier, parentPackage); public bool TryGetSkin(SkinIdentifier skinIdentifier, out Skin.Skin skin) => _skins.TryGetValue(skinIdentifier, out skin); + public bool TryGetCape(int capeId, out Image cape) => _capes.TryGetValue(capeId, out cape); public bool ContainsSkin(SkinIdentifier skinIdentifier) => _skins.ContainsKey(skinIdentifier); diff --git a/PckStudio.Core/DLC/DLCTexturePackage.cs b/PckStudio.Core/DLC/DLCTexturePackage.cs index 244d7a1e..18cda190 100644 --- a/PckStudio.Core/DLC/DLCTexturePackage.cs +++ b/PckStudio.Core/DLC/DLCTexturePackage.cs @@ -7,12 +7,10 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using OMI.Formats.Color; -using OMI.Formats.Material; -using OMI.Formats.Model; -using OMI.Formats.Pck; -using OMI.Workers.Color; +using PckStudio.Core.Colors; using PckStudio.Core.Extensions; using PckStudio.Core.Interfaces; +using PckStudio.Core.Model; using PckStudio.Core.Properties; namespace PckStudio.Core.DLC @@ -43,33 +41,44 @@ namespace PckStudio.Core.DLC public Image IconImg { get; } = iconImg; } - public sealed class EnvironmentData + public sealed class EnvironmentData(Image clouds, Image rain, Image snow) { - public Image Clouds; - public Image Rain; - public Image Snow; + public Image Clouds = clouds; + public Image Rain = rain; + public Image Snow = snow; } public MetaData Info { get; } //! Data for x{16}Data.pck //! => colours.col - private IDictionary _colors; - private IDictionary _waterColors; - private ModelContainer _customModels; //! can be null.. => models.bin - private MaterialContainer _materials; //! can be null.. + private AbstractColorContainer _colorContainter; + private AbstractModelContainer _customModels; //! can be null.. => models.bin + private IDictionary _materials; //! can be null.. //! terrain mipmaps will be generated automatically. Add mipmap option to settings menu ? -null private Atlas _terrainAtlas; private Atlas _itemsAtlas; private Atlas _particlesAtlas; private Atlas _paintingAtlas; - private ArmorSet[] _armorSets = new ArmorSet[6]; + private Atlas _moonPhaseAtlas; + private ArmorSet _leatherArmorSet; + private ArmorSet _chainArmorSet; + private ArmorSet _ironArmorSet; + private ArmorSet _goldArmorSet; + private ArmorSet _diamondArmorSet; + private ArmorSet _turtleArmorSet; + private Atlas _mapIconsAtlas; + private Atlas _additionalMapIconsAtlas; private EnvironmentData _environmentData; private Animation _blockEntityBreakAnimation; private IDictionary _itemAnimations; private IDictionary _blockAnimations; + private Image _sun; + private Image _moon; + + //! TODO: add resources from "res/misc/" internal DLCTexturePackage( string name, @@ -81,14 +90,24 @@ namespace PckStudio.Core.DLC Atlas itemsAtlas, Atlas particlesAtlas, Atlas paintingAtlas, - ArmorSet[] armorSets, - IDictionary colors, - IDictionary waterColors, - ModelContainer customModels, - MaterialContainer materials, + Atlas moonPhaseAtlas, + Atlas mapIconsAtlas, + Atlas additionalMapIconsAtlas, + ArmorSet leatherArmorSet, + ArmorSet chainArmorSet, + ArmorSet ironArmorSet, + ArmorSet goldArmorSet, + ArmorSet diamondArmorSet, + ArmorSet turtleArmorSet, + EnvironmentData environmentData, + AbstractColorContainer colorContainter, + AbstractModelContainer customModels, + IDictionary materials, Animation blockEntityBreakAnimation, IDictionary itemAnimations, IDictionary blockAnimations, + Image sun, + Image moon, IDLCPackage parentPackage ) : base(name, identifier, parentPackage) @@ -100,14 +119,24 @@ namespace PckStudio.Core.DLC _itemsAtlas = itemsAtlas; _particlesAtlas = particlesAtlas; _paintingAtlas = paintingAtlas; - _armorSets = armorSets; - _colors = colors; - _waterColors = waterColors; + _moonPhaseAtlas = moonPhaseAtlas; + _mapIconsAtlas = mapIconsAtlas; + _additionalMapIconsAtlas = additionalMapIconsAtlas; + _leatherArmorSet = leatherArmorSet; + _chainArmorSet = chainArmorSet; + _ironArmorSet = ironArmorSet; + _goldArmorSet = goldArmorSet; + _diamondArmorSet = diamondArmorSet; + _turtleArmorSet = turtleArmorSet; + _environmentData = environmentData; + _colorContainter = colorContainter; _customModels = customModels; _materials = materials; _blockEntityBreakAnimation = blockEntityBreakAnimation; - _itemAnimations = itemAnimations; - _blockAnimations = blockAnimations; + _itemAnimations = itemAnimations ?? new Dictionary(); + _blockAnimations = blockAnimations ?? new Dictionary(); + _sun = sun; + _moon = moon; } public TextureResolution GetResolution() => _resolution; @@ -162,32 +191,40 @@ namespace PckStudio.Core.DLC MetaData metadata = new MetaData(Resources.Comparison, Resources.TexturePackIcon); - Atlas terrain = Atlas.FromResourceLocation(Resources.terrain_atlas, ResourceLocation.GetFromCategory(ResourceCategory.BlockAtlas)); - Atlas items = Atlas.FromResourceLocation(Resources.items_atlas, ResourceLocation.GetFromCategory(ResourceCategory.ItemAtlas)); - Atlas particles = Atlas.FromResourceLocation(Resources.particles_atlas, ResourceLocation.GetFromCategory(ResourceCategory.ParticleAtlas)); - Atlas painting = Atlas.FromResourceLocation(Resources.paintings_atlas, ResourceLocation.GetFromCategory(ResourceCategory.PaintingAtlas)); + Atlas terrain = Atlas.FromResourceLocation(Resources.terrain_atlas, ResourceLocation.GetFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.BlockAtlas))); + Atlas items = Atlas.FromResourceLocation(Resources.items_atlas, ResourceLocation.GetFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.ItemAtlas))); + Atlas particles = Atlas.FromResourceLocation(Resources.particles_atlas, ResourceLocation.GetFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.ParticleAtlas))); + Atlas painting = Atlas.FromResourceLocation(Resources.paintings_atlas, ResourceLocation.GetFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.PaintingAtlas))); + Atlas moonPhases = Atlas.FromResourceLocation(Resources.moon_phases_atlas, ResourceLocation.GetFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.MoonPhaseAtlas))); + Atlas mapIconsAtlas = Atlas.FromResourceLocation(Resources.map_icons_atlas, ResourceLocation.GetFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.MapIconAtlas))); + Atlas additionalMapIconsAtlas = Atlas.FromResourceLocation(Resources.additional_map_icons_atlas, ResourceLocation.GetFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.AdditionalMapIconsAtlas))); //ColorContainer colors = new COLFileReader().FromStream(new MemoryStream()); IDictionary colors = null; IDictionary waterColors = null; - + Animation blockEntityBreakAnimation = new Animation(terrain.GetRange(0, 15, 10, ImageLayoutDirection.Horizontal).Select(t => t.Texture).ToArray(), true, 3); - - ArmorSet[] armorSets = GetArmorSets(); IDictionary itemAnimations = GetItemAnimations(); - IDictionary blockAnimations = GetBlockAnimations(); return new DLCTexturePackage( name, description, identifier, metadata, resolution, - terrain, items, particles, painting, - armorSets, - colors, waterColors, - new ModelContainer(), - new MaterialContainer(), + terrain, items, particles, painting, moonPhases, mapIconsAtlas, additionalMapIconsAtlas, + new ArmorSet(ArmorSetDescription.CLOTH, Resources.cloth, Resources.cloth_b), + new ArmorSet(ArmorSetDescription.CHAIN, Resources.chain, default), + new ArmorSet(ArmorSetDescription.IRON, Resources.iron, default), + new ArmorSet(ArmorSetDescription.GOLD, Resources.gold, default), + new ArmorSet(ArmorSetDescription.DIAMOND, Resources.diamond, default), + new ArmorSet(ArmorSetDescription.TURTLE, Resources.turtle, default), + new EnvironmentData(Resources.clouds, Resources.rain, Resources.snow), + new AbstractColorContainer(colors, waterColors), + new AbstractModelContainer(), + new Dictionary(), blockEntityBreakAnimation, itemAnimations, blockAnimations, + sun: null, + moon: null, parentPackage ); } @@ -200,19 +237,6 @@ namespace PckStudio.Core.DLC internal Atlas GetPaintingAtlas() => _paintingAtlas; - private static ArmorSet[] GetArmorSets() - { - return new ArmorSet[6] - { - new ArmorSet(ArmorSetDescription.CLOTH, Resources.cloth, Resources.cloth_b), - new ArmorSet(ArmorSetDescription.CHAIN, Resources.chain, default), - new ArmorSet(ArmorSetDescription.IRON, Resources.iron, default), - new ArmorSet(ArmorSetDescription.GOLD, Resources.gold, default), - new ArmorSet(ArmorSetDescription.DIAMOND, Resources.diamond, default), - new ArmorSet(ArmorSetDescription.TURTLE, Resources.turtle, default) - }; - } - private static IDictionary GetItemAnimations() { return new Dictionary() diff --git a/PckStudio.Core/DLC/InvalidDLCPackage.cs b/PckStudio.Core/DLC/InvalidDLCPackage.cs deleted file mode 100644 index 14c7a9dd..00000000 --- a/PckStudio.Core/DLC/InvalidDLCPackage.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using PckStudio.Core.Interfaces; - -namespace PckStudio.Core.DLC -{ - // Dummy class - internal sealed class InvalidDLCPackage : DLCPackage - { - internal static IDLCPackage Instance { get; } = new InvalidDLCPackage(); - - private InvalidDLCPackage(string name, int identifier, IDLCPackage parentPackage) - : base(name, identifier, parentPackage) - { - } - - private InvalidDLCPackage() - : this(nameof(InvalidDLCPackage), -1, null) - { - - } - - public override DLCPackageType GetDLCPackageType() => DLCPackageType.Invalid; - } -} diff --git a/PckStudio.Core/DLC/PckFileCompiler.cs b/PckStudio.Core/DLC/PckFileCompiler.cs new file mode 100644 index 00000000..5e3ec54f --- /dev/null +++ b/PckStudio.Core/DLC/PckFileCompiler.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OMI; +using OMI.Formats.GameRule; +using OMI.Formats.Languages; +using OMI.Formats.Pck; +using OMI.Workers.GameRule; +using OMI.Workers.Language; +using OMI.Workers.Pck; +using PckStudio.Core.Extensions; +using PckStudio.Core.Interfaces; +using PckStudio.Core.IO.PckAudio; + +namespace PckStudio.Core.DLC +{ + internal sealed class PckFileCompiler + { + private ByteOrder _byteOrder; + private GameRuleFile.CompressionType _compressionType; + private GameRuleFile.CompressionLevel _compressionLevel; + + internal PckFileCompiler(ByteOrder byteOrder, GameRuleFile.CompressionType compressionType, GameRuleFile.CompressionLevel compressionLevel) + { + _byteOrder = byteOrder; + _compressionType = compressionType; + _compressionLevel = compressionLevel; + } + + private PckFile CreateRootPckFile(int packId, int packVerison, LOCFile localisation) + { + PckFile mainPck = new PckFile(); + PckAsset meta = mainPck.CreateNewAsset("0", PckAssetType.InfoFile); + meta.AddProperty("PACKID", packId); + meta.AddProperty("PACKVERSION", packVerison); + mainPck.CreateNewAsset("localisation.loc", PckAssetType.LocalisationFile, new LOCFileWriter(localisation, 2)); + return mainPck; + } + + internal DLCPackageContent CompileSkinPackage(IDLCPackage package, LOCFile localisation) + { + if (package is not DLCSkinPackage skinPackage) + return DLCPackageContent.Empty; + + PckFile skinsPck = skinPackage.IsRootPackage ? CreateRootPckFile(package.Identifier, 0, localisation) : new PckFile(); + foreach (KeyValuePair kv in skinPackage.GetCapes()) + { + PckAsset capeAsset = skinsPck.CreateNewAsset($"dlccape{kv.Key:08}.png", PckAssetType.CapeFile); + capeAsset.SetTexture(kv.Value); + } + foreach (Skin.Skin skin in skinPackage.GetSkins()) + { + skinsPck.AddSkin("", skin, localisation); + } + + return new DLCPackageContent(skinsPck); + } + + internal DLCPackageContent CompileTexturePackage(IDLCPackage package, LOCFile localisation) + { + if (package is not DLCTexturePackage texturePackage) + return DLCPackageContent.Empty; + + PckFile texturePackInfoPck = new PckFile(); + { + texturePackInfoPck.AddTexture("comparison.png", texturePackage.Info.ComparisonImg); + texturePackInfoPck.AddTexture("icon.png", texturePackage.Info.IconImg); + } + + PckFile texturePck = new PckFile(); + { + texturePck.AddTexture(ResourceLocations.GetPathFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.ParticleAtlas)), texturePackage.GetParticleAtlas()); + texturePck.AddTexture(ResourceLocations.GetPathFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.ItemAtlas)), texturePackage.GetItemsAtlas()); + texturePck.AddTexture(ResourceLocations.GetPathFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.BlockAtlas)), texturePackage.GetTerrainAtlas()); + texturePck.AddTexture(ResourceLocations.GetPathFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.PaintingAtlas)), texturePackage.GetPaintingAtlas()); + } + + if (package.IsRootPackage) + { + PckFile mainPck = CreateRootPckFile(package.Identifier, 0, localisation); + DLCTexturePackage.TextureResolution res = texturePackage.GetResolution(); + PckAsset textureInfoAsset = mainPck.CreateNewAsset($"{res}/{res}Info.pck", PckAssetType.TexturePackInfoFile, new PckFileWriter(texturePackInfoPck, _byteOrder)); + textureInfoAsset.AddProperty("PACKID", "0"); + textureInfoAsset.AddProperty("DATAPATH", $"{res}Data.pck"); + return new DLCPackageContent(mainPck, new NamedData($"{res}Data.pck", texturePck), default); + } + + return new DLCPackageContent(texturePackInfoPck); + } + + internal DLCPackageContent CompileMashUpPackage(IDLCPackage package, LOCFile localisation) + { + if (package is not DLCMashUpPackage mashUpPackage) + return DLCPackageContent.Empty; + + PckFile skinsPck = CompileSkinPackage(mashUpPackage.GetSkinPackage(), localisation).MainPck; + + DLCTexturePackage texturePackage = mashUpPackage.GetTexturePackage() as DLCTexturePackage; + DLCPackageContent texturePackContent = CompileTexturePackage(texturePackage, localisation); + DLCTexturePackage.TextureResolution res = texturePackage.GetResolution(); + PckFile texturePackInfoPck = texturePackContent.MainPck; + PckFile texturePck = texturePackContent.DataFolder.TexturePck.Value; + + PckFile mainPck = CreateRootPckFile(package.Identifier, 0, localisation); + _ = mainPck.CreateNewAssetIf(skinsPck is PckFile && skinsPck.AssetCount > 0, "Skins.pck", PckAssetType.SkinDataFile, new PckFileWriter(skinsPck, _byteOrder)); + + if (texturePackInfoPck is PckFile && texturePackInfoPck.AssetCount > 0) + { + PckAsset textureInfoAsset = mainPck.CreateNewAsset($"{res}/{res}Info.pck", PckAssetType.TexturePackInfoFile, new PckFileWriter(texturePackInfoPck, _byteOrder)); + textureInfoAsset.AddProperty("PACKID", "0"); + textureInfoAsset.AddProperty("DATAPATH", texturePackContent.DataFolder.TexturePck.Name); + } + + + { + GameRuleFile grf = mashUpPackage.GetGameRule(); + grf.Header.CompressionType = _compressionType; + grf.Header.CompressionLevel = _compressionLevel; + mainPck.CreateNewAsset("GameRule.grf", PckAssetType.GameRulesFile, new GameRuleFileWriter(grf)); + } + + if (mashUpPackage.HasAudioData) + { + mainPck.CreateNewAsset("audio.pck", PckAssetType.AudioFile, new PckAudioFileWriter(mashUpPackage.GetAudioPack(), _byteOrder)); + texturePackContent.DataFolder.AddFiles(mashUpPackage.GetAudioFiles()); + } + + return new DLCPackageContent(mainPck, texturePackContent.DataFolder); + } + + internal DLCPackageContent CompileRawAssets(IDLCPackage package) + { + return package is RawAssetDLCPackage rawAssetDLCPackage ? new DLCPackageContent(rawAssetDLCPackage.PckFile) : DLCPackageContent.Empty; + } + } +} diff --git a/PckStudio.Core/DLC/UnknownDLCPackage.cs b/PckStudio.Core/DLC/RawAssetDLCPackage.cs similarity index 51% rename from PckStudio.Core/DLC/UnknownDLCPackage.cs rename to PckStudio.Core/DLC/RawAssetDLCPackage.cs index 1184e5e3..cc24da7d 100644 --- a/PckStudio.Core/DLC/UnknownDLCPackage.cs +++ b/PckStudio.Core/DLC/RawAssetDLCPackage.cs @@ -3,21 +3,23 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using OMI; using OMI.Formats.Pck; -using PckStudio.Core.Interfaces; namespace PckStudio.Core.DLC { - public sealed class UnknownDLCPackage : DLCPackage + public sealed class RawAssetDLCPackage : DLCPackage { public PckFile PckFile { get; } + public ByteOrder ByteOrder { get; } - public UnknownDLCPackage(string name, PckFile pckFile) - : base(name ?? nameof(UnknownDLCPackage), -1, default) + public RawAssetDLCPackage(string name, PckFile pckFile, ByteOrder byteOrder) + : base(name ?? nameof(RawAssetDLCPackage), -1, default) { PckFile = pckFile; + ByteOrder = byteOrder; } - public override DLCPackageType GetDLCPackageType() => DLCPackageType.Unknown; + public override DLCPackageType GetDLCPackageType() => DLCPackageType.RawAssets; } } diff --git a/PckStudio.Core/Extensions/AnimationExtensions.cs b/PckStudio.Core/Extensions/AnimationExtensions.cs index 4229ba26..5d99c839 100644 --- a/PckStudio.Core/Extensions/AnimationExtensions.cs +++ b/PckStudio.Core/Extensions/AnimationExtensions.cs @@ -1,4 +1,7 @@ -using System.Drawing; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Threading.Tasks; using AnimatedGif; namespace PckStudio.Core.Extensions @@ -23,5 +26,26 @@ namespace PckStudio.Core.Extensions ms.Position = 0; return Image.FromStream(ms); } + + public static Animation Combine(this Animation first, Animation second, ImageLayoutDirection layoutDirection) + { + if (first == null) + return second; + if (second == null) + return first; + if (first.TextureCount != second.TextureCount) + return first; + if (first.FrameCount != second.FrameCount) + return first; + + Image[] secondTextures = second.GetTextures().ToArray(); + + Animation animation = new Animation(first.GetTextures().enumerate().Select(ift => ift.value.Combine(secondTextures[ift.index], layoutDirection))); + foreach ((int texId, int frameTime) item in first.GetFrames().Select(f => (texId: first.GetTextureIndex(f.Texture), frameTime: f.Ticks))) + { + animation.AddFrame(item.texId, item.frameTime); + } + return animation; + } } } diff --git a/PckStudio.Core/Extensions/ColorExtensions.cs b/PckStudio.Core/Extensions/ColorExtensions.cs index 4a64fa9e..0cb29dce 100644 --- a/PckStudio.Core/Extensions/ColorExtensions.cs +++ b/PckStudio.Core/Extensions/ColorExtensions.cs @@ -54,15 +54,15 @@ namespace PckStudio.Core.Extensions return MathExtensions.Clamp(resultValue, 0.0f, 1.0f); } - public static byte Mix(double ratio, byte val1, byte val2) + public static byte Mix(float ratio, byte val1, byte val2) { - ratio = MathExtensions.Clamp(ratio, 0.0, 1.0); + ratio = MathExtensions.Clamp(ratio, 0.0f, 1.0f); return (byte)(ratio * val1 + (1.0 - ratio) * val2); } - public static Color Mix(this Color c1, Color c2, double ratio) + public static Color Mix(this Color c1, Color c2, float ratio) { - ratio = MathExtensions.Clamp(ratio, 0.0, 1.0); + ratio = MathExtensions.Clamp(ratio, 0.0f, 1.0f); return Color.FromArgb(c1.A, Mix(ratio, c1.R, c2.R), Mix(ratio, c1.G, c2.G), diff --git a/PckStudio.Core/Extensions/ImageExtensions.cs b/PckStudio.Core/Extensions/ImageExtensions.cs index e38bee51..ffe55af9 100644 --- a/PckStudio.Core/Extensions/ImageExtensions.cs +++ b/PckStudio.Core/Extensions/ImageExtensions.cs @@ -274,9 +274,9 @@ namespace PckStudio.Core.Extensions return bitmapResult; } - public static Image Interpolate(this Image source, Image target, double delta) + public static Image Interpolate(this Image source, Image target, float delta) { - delta = MathExtensions.Clamp(delta, 0.0, 1.0); + delta = MathExtensions.Clamp(delta, 0.0f, 1.0f); if (source is not Bitmap baseImage || target is not Bitmap overlayImage || source.Width != target.Width || source.Height != target.Height) return source; diff --git a/PckStudio.Core/Extensions/JObjectExtensions.cs b/PckStudio.Core/Extensions/JObjectExtensions.cs new file mode 100644 index 00000000..4d85eb16 --- /dev/null +++ b/PckStudio.Core/Extensions/JObjectExtensions.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json.Linq; + +namespace PckStudio.Core.Extensions +{ + internal static class JObjectExtensions + { + public static bool TryGetValue(this JObject jObject, string propertyName, out T value) + { + if (!jObject.TryGetValue(propertyName, out JToken token)) + { + value = default; + return false; + } + value = token.ToObject() ?? default; + return value is T; + } + } +} diff --git a/PckStudio.Core/Extensions/MathExtensions.cs b/PckStudio.Core/Extensions/MathExtensions.cs index 38fb5b2b..4faf8253 100644 --- a/PckStudio.Core/Extensions/MathExtensions.cs +++ b/PckStudio.Core/Extensions/MathExtensions.cs @@ -2,7 +2,7 @@ namespace PckStudio.Core.Extensions { - public class MathExtensions + public static class MathExtensions { public static T Clamp(T value, T min, T max) where T : IComparable { @@ -12,5 +12,10 @@ namespace PckStudio.Core.Extensions return max; return value; } + + public static bool IsWithinRangeOf(this T value, T min, T max) where T : IComparable + { + return value.CompareTo(min) >= 0 && value.CompareTo(max) <= 0; + } } } diff --git a/PckStudio.Core/Extensions/PckFileExtensions.cs b/PckStudio.Core/Extensions/PckFileExtensions.cs index 750c935a..1ca6b476 100644 --- a/PckStudio.Core/Extensions/PckFileExtensions.cs +++ b/PckStudio.Core/Extensions/PckFileExtensions.cs @@ -55,7 +55,7 @@ namespace PckStudio.Core.Extensions if (skin.HasCape) { - asset.AddProperty("CAPEPATH", $"dlccape{skinId}.png"); + asset.AddProperty("CAPEPATH", $"dlccape{skin.CapeId}.png"); } asset.AddProperty("ANIM", skin.Anim); @@ -91,5 +91,23 @@ namespace PckStudio.Core.Extensions return asset; } + public static bool HasDirectory(this PckFile pck, string directoryPath) + { + string sanitisedDirectoryPath = directoryPath.Replace('\\', '/'); + return pck.GetAssets().Any(asset => asset.Filename.StartsWith(sanitisedDirectoryPath)); + } + + public static IEnumerable GetDirectoryContent(this PckFile pck, string directoryPath, PckAssetType assetType, bool includeSubDirectories = false) + => GetDirectoryContent(pck, directoryPath, includeSubDirectories).Where(asset => asset.Type == assetType); + public static IEnumerable GetDirectoryContent(this PckFile pck, string directoryPath, bool includeSubDirectories = false) + { + string sanitisedDirectoryPath = directoryPath.Replace('\\', '/'); + if (!sanitisedDirectoryPath.EndsWith("/")) + sanitisedDirectoryPath += "/"; + return pck.GetAssets() + .Where(asset => asset.Filename.StartsWith(sanitisedDirectoryPath)) + .Where(asset => includeSubDirectories || !asset.Filename.Substring(sanitisedDirectoryPath.Length).Contains('/')); + } + } } diff --git a/PckStudio.Core/Extensions/SkinBOXExtensions.cs b/PckStudio.Core/Extensions/SkinBOXExtensions.cs index 7ed6229e..264edde1 100644 --- a/PckStudio.Core/Extensions/SkinBOXExtensions.cs +++ b/PckStudio.Core/Extensions/SkinBOXExtensions.cs @@ -19,7 +19,7 @@ namespace PckStudio.Core.Extensions var path = new GraphicsPath(FillMode.Winding); - Vector2 uv = skinBOX.UV; + Vector2 uv = skinBOX.Uv; Vector3 size = skinBOX.Size; path.AddRectangle(new RectangleF(new PointF((uv.X ) * tillingFactor.X, (uv.Y + size.Z) * tillingFactor.Y), new SizeF(size.Z * tillingFactor.X, size.Y * tillingFactor.Y))); @@ -94,12 +94,12 @@ namespace PckStudio.Core.Extensions { return Point.Truncate((face) switch { - SkinBoxFace.Front => new PointF(skinBox.UV.X + skinBox.Size.Z , skinBox.UV.Y + skinBox.Size.Z), - SkinBoxFace.Back => new PointF(skinBox.UV.X + skinBox.Size.Z * 2 + skinBox.Size.X, skinBox.UV.Y + skinBox.Size.Z), - SkinBoxFace.Top => new PointF(skinBox.UV.X + skinBox.Size.X , skinBox.UV.Y), - SkinBoxFace.Bottom => new PointF(skinBox.UV.X + skinBox.Size.X * 2 , skinBox.UV.Y), - SkinBoxFace.Left => new PointF(skinBox.UV.X + skinBox.Size.Z + skinBox.Size.X , skinBox.UV.Y + skinBox.Size.Z), - SkinBoxFace.Right => new PointF(skinBox.UV.X + skinBox.Size.Z , skinBox.UV.Y + skinBox.Size.Z), + SkinBoxFace.Front => new PointF(skinBox.Uv.X + skinBox.Size.Z , skinBox.Uv.Y + skinBox.Size.Z), + SkinBoxFace.Back => new PointF(skinBox.Uv.X + skinBox.Size.Z * 2 + skinBox.Size.X, skinBox.Uv.Y + skinBox.Size.Z), + SkinBoxFace.Top => new PointF(skinBox.Uv.X + skinBox.Size.X , skinBox.Uv.Y), + SkinBoxFace.Bottom => new PointF(skinBox.Uv.X + skinBox.Size.X * 2 , skinBox.Uv.Y), + SkinBoxFace.Left => new PointF(skinBox.Uv.X + skinBox.Size.Z + skinBox.Size.X , skinBox.Uv.Y + skinBox.Size.Z), + SkinBoxFace.Right => new PointF(skinBox.Uv.X + skinBox.Size.Z , skinBox.Uv.Y + skinBox.Size.Z), _ => PointF.Empty, }); } diff --git a/PckStudio.Core/Extensions/SkinExtensions.cs b/PckStudio.Core/Extensions/SkinExtensions.cs index 8ea9fbc4..505ea366 100644 --- a/PckStudio.Core/Extensions/SkinExtensions.cs +++ b/PckStudio.Core/Extensions/SkinExtensions.cs @@ -88,7 +88,7 @@ namespace PckStudio.Core.Extensions } else { - Rectangle area = skin.Model.AdditionalBoxes.Where(sb => sb.Type == "HEAD" || sb.Type == "HEADWEAR").OrderBy(sb=> sb.Pos.Z - sb.Scale).FirstOrDefault()?.GetFaceArea(SkinBOXExtensions.SkinBoxFace.Front) ?? Rectangle.Empty; + Rectangle area = skin.Model.AdditionalBoxes.Where(sb => sb.Type == "HEAD" || sb.Type == "HEADWEAR").OrderBy(sb=> sb.Position.Z - sb.Inflate).FirstOrDefault()?.GetFaceArea(SkinBOXExtensions.SkinBoxFace.Front) ?? Rectangle.Empty; Image img = skin.Texture.GetArea(area); g.DrawImage(img, 0, 0, width, height); } diff --git a/PckStudio.Core/Extensions/TreeNodeCollectionExtensions.cs b/PckStudio.Core/Extensions/TreeNodeCollectionExtensions.cs index 133b88f2..f04118b5 100644 --- a/PckStudio.Core/Extensions/TreeNodeCollectionExtensions.cs +++ b/PckStudio.Core/Extensions/TreeNodeCollectionExtensions.cs @@ -25,23 +25,35 @@ namespace PckStudio.Core.Extensions return node; } - public static TreeNode BuildNodeTreeBySeperator(this TreeNodeCollection root, string path, char seperator) + private static (string, string) Slice(this string s, int i) + => (s.Substring(0, i), s.Substring(i + 1)); + + public static TreeNode BuildNodeTreeBySeperator(this TreeNodeCollection root, string path, char seperator, int maxDepth = -1) + => root.BuildNodeTreeBySeperator(path, seperator.ToString(), maxDepth); + public static TreeNode BuildNodeTreeBySeperator(this TreeNodeCollection root, string path, string seperator, int maxDepth = -1) { _ = root ?? throw new ArgumentNullException(nameof(root)); - if (!path.Contains(seperator)) - { + if (maxDepth == 0 || !path.Contains(seperator)) return root.CreateNode(path); - } - string nodeText = path.Substring(0, path.IndexOf(seperator)); - string subPath = path.Substring(path.IndexOf(seperator) + 1); + + (string nodeText, string subPath) = path.Slice(path.IndexOf(seperator)); if (string.IsNullOrWhiteSpace(nodeText)) - { - return BuildNodeTreeBySeperator(root, subPath, seperator); - } + return BuildNodeTreeBySeperator(root, subPath, seperator, maxDepth - 1); TreeNode subNode = root.ContainsKey(nodeText) ? root[nodeText] : root.CreateNode(nodeText); - return BuildNodeTreeBySeperator(subNode.Nodes, subPath, seperator); + return BuildNodeTreeBySeperator(subNode.Nodes, subPath, seperator, maxDepth - 1); + } + + public static IEnumerable GetLeafNodes(this TreeNodeCollection root) + { + foreach (TreeNode node in root) + { + if (node.Nodes.Count == 0) + yield return node; + foreach (TreeNode ln in node.Nodes.GetLeafNodes()) + yield return ln; + } } } } diff --git a/PckStudio.Core/FileFormats/PckAudioFile.cs b/PckStudio.Core/FileFormats/PckAudioFile.cs index 0cf4b526..8466978f 100644 --- a/PckStudio.Core/FileFormats/PckAudioFile.cs +++ b/PckStudio.Core/FileFormats/PckAudioFile.cs @@ -15,34 +15,33 @@ namespace PckStudio.Core.FileFormats private AudioCategory[] _categories { get; } = new AudioCategory[9]; public Dictionary Credits { get; } = new Dictionary(); + public enum Category : int + { + Overworld, + Nether, + End, + Creative, + Menu, + Battle, + Tumble, + Glide, + BuildOff, + } + + public enum EAudioParameterType : int + { + Unk0, // dimension music + Unk1, // unused music ? + } public sealed class AudioCategory { - public enum EAudioType : int - { - Overworld, - Nether, - End, - Creative, - Menu, - Battle, - Tumble, - Glide, - BuildOff, - } - - public enum EAudioParameterType : int - { - Unk0, // dimension music - Unk1, // unused music ? - } - public string Name { get; set; } = string.Empty; - public EAudioType AudioType { get; } + public Category AudioType { get; } public List SongNames { get; } = new List(); public EAudioParameterType ParameterType { get; } - public AudioCategory(string name, EAudioParameterType parameterType, EAudioType audioType) + public AudioCategory(string name, EAudioParameterType parameterType, Category audioType) { Name = name; ParameterType = parameterType; @@ -98,17 +97,17 @@ namespace PckStudio.Core.FileFormats /// - public bool HasCategory(AudioCategory.EAudioType category) => GetCategory(category) is AudioCategory; + public bool HasCategory(Category category) => GetCategory(category) is AudioCategory; /// - public AudioCategory GetCategory(AudioCategory.EAudioType category) + public AudioCategory GetCategory(Category category) { - if (!Enum.IsDefined(typeof(AudioCategory.EAudioType), category)) + if (!Enum.IsDefined(typeof(Category), category)) throw new InvalidCategoryException(nameof(category)); return _categories[(int)category]; } - public bool TryGetCategory(AudioCategory.EAudioType category, out AudioCategory audioCategory) + public bool TryGetCategory(Category category, out AudioCategory audioCategory) { if (GetCategory(category) is AudioCategory audioCat) { @@ -121,9 +120,9 @@ namespace PckStudio.Core.FileFormats /// True when category was created, otherwise false /// - public bool AddCategory(string name, AudioCategory.EAudioType category, AudioCategory.EAudioParameterType parameterType) + public bool AddCategory(string name, Category category, EAudioParameterType parameterType) { - if (!Enum.IsDefined(typeof(AudioCategory.EAudioType), category)) + if (!Enum.IsDefined(typeof(Category), category)) throw new InvalidCategoryException(nameof(category)); bool exists = HasCategory(category); if (!exists) @@ -133,11 +132,11 @@ namespace PckStudio.Core.FileFormats /// True when category was created, otherwise false /// - public bool AddCategory(AudioCategory.EAudioType category) => AddCategory("", category, AudioCategory.EAudioParameterType.Unk0); + public bool AddCategory(Category category) => AddCategory("", category, EAudioParameterType.Unk0); /// True when category was removed, otherwise false /// - public bool RemoveCategory(AudioCategory.EAudioType category) + public bool RemoveCategory(Category category) { bool exists = HasCategory(category); if (exists) diff --git a/PckStudio.Core/IO/PckAudio/PckAudioFileReader.cs b/PckStudio.Core/IO/PckAudio/PckAudioFileReader.cs index a4489fe5..3b5e4633 100644 --- a/PckStudio.Core/IO/PckAudio/PckAudioFileReader.cs +++ b/PckStudio.Core/IO/PckAudio/PckAudioFileReader.cs @@ -16,7 +16,7 @@ namespace PckStudio.Core.IO.PckAudio private PckAudioFile _file; private ByteOrder _endianness; private List LUT = new List(); - private List _OriginalAudioTypeOrder = new List(); + private List _OriginalAudioTypeOrder = new List(); public PckAudioFileReader(ByteOrder endianness) { @@ -75,8 +75,8 @@ namespace PckStudio.Core.IO.PckAudio int categoryEntryCount = reader.ReadInt32(); for (; 0 < categoryEntryCount; categoryEntryCount--) { - var parameterType = (PckAudioFile.AudioCategory.EAudioParameterType)reader.ReadInt32(); - var audioType = (PckAudioFile.AudioCategory.EAudioType)reader.ReadInt32(); + var parameterType = (PckAudioFile.EAudioParameterType)reader.ReadInt32(); + var audioType = (PckAudioFile.Category)reader.ReadInt32(); string name = ReadString(reader); // AddCategory puts the file's categories out of order and causes some songs to be put in the wrong categories // This is my simple fix for the issue. @@ -89,7 +89,7 @@ namespace PckStudio.Core.IO.PckAudio { List credits = new List(); List creditIds = new List(); - foreach (PckAudioFile.AudioCategory.EAudioType c in _OriginalAudioTypeOrder) + foreach (PckAudioFile.Category c in _OriginalAudioTypeOrder) { int audioCount = reader.ReadInt32(); for (; 0 < audioCount; audioCount--) diff --git a/PckStudio.Core/Json/ColorEntry.cs b/PckStudio.Core/Json/ColorEntry.cs index 283c3761..971d734a 100644 --- a/PckStudio.Core/Json/ColorEntry.cs +++ b/PckStudio.Core/Json/ColorEntry.cs @@ -9,13 +9,13 @@ namespace PckStudio.Core.Json { public class JsonColorEntry { - [JsonProperty("defaultName", Required = Required.Always)] + [JsonProperty("defaultName", DefaultValueHandling = DefaultValueHandling.Populate)] public string DefaultName { get; set; } [JsonProperty("isWaterColour", DefaultValueHandling = DefaultValueHandling.Populate)] public bool IsWaterColour { get; set; } - [JsonProperty("variants", DefaultValueHandling = DefaultValueHandling.Populate)] - public string[] Variants { get; set; } + [JsonProperty("variants", NullValueHandling = NullValueHandling.Ignore)] + public string[] Variants { get; set; } = Array.Empty(); } } diff --git a/PckStudio.Core/Json/JsonDefaultModel.cs b/PckStudio.Core/Json/JsonDefaultModel.cs new file mode 100644 index 00000000..5b337421 --- /dev/null +++ b/PckStudio.Core/Json/JsonDefaultModel.cs @@ -0,0 +1,30 @@ +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 Box[] Boxes { get; set; } + } +} diff --git a/PckStudio.Core/Json/JsonModelMetaData.cs b/PckStudio.Core/Json/JsonModelMetaData.cs new file mode 100644 index 00000000..4d68d7a8 --- /dev/null +++ b/PckStudio.Core/Json/JsonModelMetaData.cs @@ -0,0 +1,61 @@ +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(); + + [JsonProperty("required")] + public bool Reqired { get; set; } = default; + + [JsonConstructor] + public ModelMetaDataPart() + { + } + + public ModelMetaDataPart(string name) + : this(name, Array.Empty()) + { + } + + public ModelMetaDataPart(string name, params ModelMetaDataPart[] children) + { + Name = name; + Children = children; + } + } + + public class JsonModelMetaLayer + { + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("uv")] + public Vector2 Uv { get; set; } + + [JsonProperty("allowedColors", NullValueHandling = NullValueHandling.Ignore)] + public string[] AllowedColors { get; set; } = Array.Empty(); + } + + 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("layers", NullValueHandling = NullValueHandling.Ignore)] + public JsonModelMetaLayer[] Layers { get; set; } = [new JsonModelMetaLayer() { Name = "base", Uv = Vector2.Zero}]; + + [JsonProperty("parts", NullValueHandling = NullValueHandling.Ignore)] + public ModelMetaDataPart[] RootParts { get; set; } = Array.Empty(); + } +} diff --git a/PckStudio.Core/Json/JsonRowAndColumn.cs b/PckStudio.Core/Json/JsonRowAndColumn.cs new file mode 100644 index 00000000..4fcb765b --- /dev/null +++ b/PckStudio.Core/Json/JsonRowAndColumn.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; + +namespace PckStudio.Core.Json +{ + internal class JsonRowAndColumn + { + [JsonProperty("row", Required = Required.Always)] + public int Row { get; set; } + [JsonProperty("column", Required = Required.Always)] + public int Column { get; set; } + } +} diff --git a/PckStudio.Core/Json/TileInfo.cs b/PckStudio.Core/Json/TileInfo.cs index db8628a5..d0d90b14 100644 --- a/PckStudio.Core/Json/TileInfo.cs +++ b/PckStudio.Core/Json/TileInfo.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; +using PckStudio.Json; namespace PckStudio.Core.Json { @@ -15,21 +16,18 @@ namespace PckStudio.Core.Json [JsonProperty("internalName")] public string InternalName { get; set; } - [JsonProperty("width")] - public int TileWidth { get; set; } = 1; - - [JsonProperty("height")] - public int TileHeight { get; set; } = 1; - - [JsonIgnore] - public bool HasColourEntry => ColourEntry != null; - - [JsonProperty("colourEntry", DefaultValueHandling = DefaultValueHandling.Ignore)] - public JsonColorEntry ColourEntry { get; set; } - [JsonProperty("allowCustomColour", DefaultValueHandling = DefaultValueHandling.Populate)] public bool AllowCustomColour { get; set; } + [JsonProperty("colorKey", DefaultValueHandling = DefaultValueHandling.Ignore)] + public string ColorKey { get; set; } = string.Empty; + + [JsonIgnore] + public bool HasColourEntry => Tiles.ColorEntries.ContainsKey(ColorKey); + + [JsonIgnore] + public JsonColorEntry ColorEntry => Tiles.ColorEntries[ColorKey]; + public JsonTileInfo(string displayName, string internalName) { DisplayName = displayName; diff --git a/PckStudio.Core/MapData.cs b/PckStudio.Core/MapData.cs index 655c0a0c..674b4927 100644 --- a/PckStudio.Core/MapData.cs +++ b/PckStudio.Core/MapData.cs @@ -39,8 +39,8 @@ namespace PckStudio.Core Thumbnail = thumbnail; World = world; - var levelData = MapReader.OpenSave(new MemoryStream(world.Value))["level.dat"]; - TagCompound? levelDat = NbtDocument.LoadDocument(new MemoryStream(levelData))!.DocumentRoot?["Data"] as TagCompound; + SaveData saveData = MapReader.OpenSaveData(new MemoryStream(world.Value)); + TagCompound? levelDat = saveData.LevelData.DocumentRoot?["Data"] as TagCompound; _ = levelDat ?? throw new NullReferenceException(nameof(levelDat)); Vector3 spawn = levelDat.GetVector3("Spawn"); diff --git a/PckStudio.Core/MapReader.cs b/PckStudio.Core/MapReader.cs index 6f2d8411..fd5ef342 100644 --- a/PckStudio.Core/MapReader.cs +++ b/PckStudio.Core/MapReader.cs @@ -1,13 +1,42 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.IO; +using System.Linq; +using Cyotek.Data.Nbt; using ICSharpCode.SharpZipLib.Zip.Compression.Streams; using OMI; +using PckStudio.Core.Extensions; namespace PckStudio.Core { + public class SaveData + { + public NbtDocument LevelData { get; } + public IDictionary Players { get; } + + + private IDictionary _worldArchive; + + public SaveData(IDictionary worldArchive) + { + _worldArchive = worldArchive; + if (_worldArchive.TryGetValue("levels.dat", out byte[] levelData)) + { + Stream stream = new MemoryStream(levelData); + LevelData = NbtDocument.LoadDocument(stream); + } + Players = _worldArchive + .Where(kv => kv.Key.StartsWith("players/")) + .ToDictionary( + kv => Guid.Parse(Path.GetFileNameWithoutExtension(kv.Key)), + kv => NbtDocument.LoadDocument(new MemoryStream(kv.Value))); + } + } + + public class MapReader { - public static IDictionary OpenSave(Stream stream) + public static SaveData OpenSaveData(Stream stream) { EndiannessAwareBinaryReader reader = new EndiannessAwareBinaryReader(stream, ByteOrder.BigEndian); _ = reader.ReadInt32(); @@ -35,7 +64,7 @@ namespace PckStudio.Core res.Add(path, data); } - return res; + return new SaveData(res); } } } diff --git a/PckStudio.Core/Model/AbstractModel.cs b/PckStudio.Core/Model/AbstractModel.cs new file mode 100644 index 00000000..73e4e82b --- /dev/null +++ b/PckStudio.Core/Model/AbstractModel.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using DiscordRPC; + +namespace PckStudio.Core.Model +{ + public class AbstractModel + { + public string Name { get; } + + public Size TextureSize { get; } + public NamedData DefaultTexture { get; } + public IReadOnlyDictionary Textures { get; } + + private IDictionary _parts; + + public AbstractModel(string name, Size textureSize, NamedData defaultTexture, IReadOnlyDictionary textures) + { + Name = name; + TextureSize = textureSize; + DefaultTexture = defaultTexture; + Textures = textures; + } + + internal bool AddPart(AbstractModelPart abstractModelPart) + { + if (abstractModelPart is null || _parts.ContainsKey(abstractModelPart.Name)) + return false; + _parts.Add(abstractModelPart.Name, abstractModelPart); + return true; + } + + internal void AddParts(IEnumerable abstractModelParts) + { + foreach (AbstractModelPart abstractModelPart in abstractModelParts) + { + AddPart(abstractModelPart); + } + } + } +} diff --git a/PckStudio.Core/Model/AbstractModelContainer.cs b/PckStudio.Core/Model/AbstractModelContainer.cs new file mode 100644 index 00000000..0daed766 --- /dev/null +++ b/PckStudio.Core/Model/AbstractModelContainer.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; +using OMI.Formats.Model; +using PckStudio.Core.Extensions; +using PckStudio.Core.Json; +using PckStudio.Core.Properties; +using PckStudio.Interfaces; + +namespace PckStudio.Core.Model +{ + public class AbstractModelContainer + { + static Dictionary _metaData = JsonConvert.DeserializeObject>(Resources.modelMetaData); + + private IDictionary _models = new Dictionary(); + + public AbstractModel GetModelByName(string name) => _models[name]; + public bool AddModel(AbstractModel model) + { + if (model == null || _models.ContainsKey(model.Name)) + return false; + _models.Add(model.Name, model); + return true; + } + + public bool RemoveModel(AbstractModel model) => model is not null && _models.Remove(model.Name); + + public static AbstractModelContainer FromModelContainer(OMI.Formats.Model.ModelContainer models, ITryGet texture) + { + var abstractModelContainer = new AbstractModelContainer(); + if (models is null) + return abstractModelContainer; + foreach (OMI.Formats.Model.Model model in models.GetModels().Where(m => _metaData.ContainsKey(m.Name) && m.Name.EqualsAny(_metaData[m.Name].RootParts.Select(mdp => mdp.Name).ToArray()))) + { + if (!_metaData.TryGetValue(model.Name, out JsonModelMetaData modelMetaData)) + { + Trace.TraceWarning($"No model meta data found for: '{model.Name}'."); + continue; + } + + IDictionary parts = model.GetParts().ToDictionary(part => part.Name); + + IReadOnlyDictionary textures = modelMetaData.TextureLocations.Where(s => texture.TryGet(s, out _)).ToDictionary(Path.GetFileNameWithoutExtension, s => + { + texture.TryGet(s, out Image img); + return img; + }); + AbstractModel abstractModel = new AbstractModel(model.Name, model.TextureSize, textures.FirstOrDefault(), textures); + abstractModel.AddParts(GetRootAbstractModelPart(modelMetaData.RootParts, parts, null)); + abstractModelContainer.AddModel(abstractModel); + } + return abstractModelContainer; + } + + private static IEnumerable GetRootAbstractModelPart(ModelMetaDataPart[] dataParts, IDictionary parts, AbstractModelPart parent) + { + foreach (ModelMetaDataPart rootPart in dataParts) + { + if (!parts.TryGetValue(rootPart.Name, out ModelPart part)) + continue; + var abstractModelPart = new AbstractModelPart(part.Name, parent, part.Translation, part.Rotation + part.AdditionalRotation, part.GetBoxes().Select(mb => new Box(mb.Position, mb.Size, mb.Uv, mb.Inflate, mb.Mirror))); + abstractModelPart.AddParts(GetRootAbstractModelPart(rootPart.Children, parts, abstractModelPart)); + yield return abstractModelPart; + } + } + } +} \ No newline at end of file diff --git a/PckStudio.Core/Model/AbstractModelPart.cs b/PckStudio.Core/Model/AbstractModelPart.cs new file mode 100644 index 00000000..b1a9fa60 --- /dev/null +++ b/PckStudio.Core/Model/AbstractModelPart.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Numerics; + +namespace PckStudio.Core.Model +{ + public class AbstractModelPart + { + public string Name { get; } + public AbstractModelPart Parent { get; } + public Vector3 Translation { get; } + public Vector3 Rotation { get; } + + private IList _boxes; + private List _subParts; + + public AbstractModelPart(string name, AbstractModelPart parent, Vector3 translation, Vector3 rotation, IEnumerable boxes) + { + Name = name; + Parent = parent; + Translation = translation; + Rotation = rotation; + _boxes = new List(boxes); + _subParts = new List(); + } + + public void AddBox(Box box) => _boxes.Add(box); + + internal void AddParts(IEnumerable parts) => _subParts.AddRange(parts); + } +} diff --git a/PckStudio.Core/NamedData.cs b/PckStudio.Core/NamedData.cs index 717db6f6..fcaae8db 100644 --- a/PckStudio.Core/NamedData.cs +++ b/PckStudio.Core/NamedData.cs @@ -10,5 +10,7 @@ namespace PckStudio.Core { public readonly string Name = name; public readonly T Value = value; + + public static implicit operator NamedData(KeyValuePair kvp) => new NamedData(kvp.Key, kvp.Value); } } diff --git a/PckStudio.Core/PackInfo.cs b/PckStudio.Core/PackInfo.cs deleted file mode 100644 index e40f4b0f..00000000 --- a/PckStudio.Core/PackInfo.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using OMI.Formats.Pck; - -namespace PckStudio.Core -{ - public sealed class PackInfo - { - public static readonly PackInfo Empty = new PackInfo(default, default, default); - public bool IsValid { get; } - public PckFile File { get; } - public OMI.ByteOrder ByteOrder { get; } - - public bool AllowByteOrderSwap { get; } - - public static PackInfo Create(PckFile file, OMI.ByteOrder byteOrder, bool allowByteOrderSwap) - { - return new PackInfo(file, byteOrder, allowByteOrderSwap); - } - - private PackInfo(PckFile file, OMI.ByteOrder byteOrder, bool allowByteOrderSwap) - { - File = file; - ByteOrder = byteOrder; - AllowByteOrderSwap = allowByteOrderSwap; - IsValid = file is not null && Enum.IsDefined(typeof(OMI.ByteOrder), byteOrder); - } - } -} \ No newline at end of file diff --git a/PckStudio.Core/PckStudio.Core.csproj b/PckStudio.Core/PckStudio.Core.csproj index deae327a..f4a45064 100644 --- a/PckStudio.Core/PckStudio.Core.csproj +++ b/PckStudio.Core/PckStudio.Core.csproj @@ -66,14 +66,17 @@ - - - - - + + + + + + - + + + @@ -85,10 +88,13 @@ + + - + + @@ -100,6 +106,7 @@ + @@ -139,7 +146,6 @@ - @@ -162,14 +168,20 @@ + + + + + + + - True @@ -225,8 +237,13 @@ + + + + + @@ -235,9 +252,11 @@ + + @@ -288,7 +307,11 @@ + + + + \ No newline at end of file diff --git a/PckStudio.Core/Properties/Resources.Designer.cs b/PckStudio.Core/Properties/Resources.Designer.cs index 2c751c97..09e16b44 100644 --- a/PckStudio.Core/Properties/Resources.Designer.cs +++ b/PckStudio.Core/Properties/Resources.Designer.cs @@ -1,700 +1,892 @@ -//------------------------------------------------------------------------------ -// -// 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 PckStudio.Core.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()] - public 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)] - public static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PckStudio.Core.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)] - public static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap additional_map_icons_atlas { - get { - object obj = ResourceManager.GetObject("additional_map_icons_atlas", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized string similar to { - /// "COMMENT_1": "JSON by MattNL", - /// "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" - /// }, - /// { - /// "interna [rest of string was truncated]";. - /// - public static string additionalMapiconsData { - get { - return ResourceManager.GetString("additionalMapiconsData", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to { - /// "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 [rest of string was truncated]";. - /// - public static string bannerData { - get { - return ResourceManager.GetString("bannerData", resourceCulture); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap banners_atlas { - get { - object obj = ResourceManager.GetObject("banners_atlas", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized string similar to { - /// "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" [rest of string was truncated]";. - /// - public static string blockData { - get { - return ResourceManager.GetString("blockData", resourceCulture); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap chain { - get { - object obj = ResourceManager.GetObject("chain", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap clock { - get { - object obj = ResourceManager.GetObject("clock", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap cloth { - get { - object obj = ResourceManager.GetObject("cloth", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap cloth_b { - get { - object obj = ResourceManager.GetObject("cloth_b", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap Comparison { - get { - object obj = ResourceManager.GetObject("Comparison", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap compass { - get { - object obj = ResourceManager.GetObject("compass", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap diamond { - get { - object obj = ResourceManager.GetObject("diamond", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap experience_orbs_atlas { - get { - object obj = ResourceManager.GetObject("experience_orbs_atlas", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized string similar to { - /// "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"] - /// } - /// }, - /// { - /// " [rest of string was truncated]";. - /// - public static string experienceOrbData { - get { - return ResourceManager.GetString("experienceOrbData", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to { - /// "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": [ - /// [rest of string was truncated]";. - /// - public static string explosionData { - get { - return ResourceManager.GetString("explosionData", resourceCulture); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap explosions_atlas { - get { - object obj = ResourceManager.GetObject("explosions_atlas", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap fire_layer_0 { - get { - object obj = ResourceManager.GetObject("fire_layer_0", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap fire_layer_1 { - get { - object obj = ResourceManager.GetObject("fire_layer_1", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap gold { - get { - object obj = ResourceManager.GetObject("gold", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap iron { - get { - object obj = ResourceManager.GetObject("iron", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized string similar to { - /// "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": [rest of string was truncated]";. - /// - public static string itemData { - get { - return ResourceManager.GetString("itemData", resourceCulture); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap items_atlas { - get { - object obj = ResourceManager.GetObject("items_atlas", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized string similar to { - /// "anvil": "anvil_base", - /// "anvil_top": "anvil_top_damaged_0", - /// "chipped_anvil_top": "anvil_top_damaged_1", - /// "damaged_anvil_top": "anvil_top_damaged_2", - /// "beetroots_stage0": "beetroots_stage_0", - /// "beetroots_stage1": "beetroots_stage_1", - /// "beetroots_stage2": "beetroots_stage_2", - /// "beetroots_stage3": "beetroots_stage_3", - /// "bricks": "brick", - /// "carrots_stage0": "carrots_stage_0", - /// "carrots_stage1": "carrots_stage_1", - /// "carrots_stage2": "carrots_stage_2", - /// "carrots_stage3": "carrots_sta [rest of string was truncated]";. - /// - public static string latest2lce_blocks { - get { - return ResourceManager.GetString("latest2lce_blocks", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to { - /// "apple_golden": "appleGold", - /// "beef_cooked": "beefCooked", - /// "beef_raw": "beefRaw", - /// "blaze_powder": "blazePowder", - /// "blaze_rod": "blazeRod", - /// "oak_boat": "boat", - /// "book_normal": "book", - /// "chainmail_boots": "bootsChain", - /// "leather_boots": "bootsCloth", - /// "leather_boots_overlay": "bootsCloth_overlay", - /// "diamond_boots": "bootsDiamond", - /// "gold_boots": "bootsGold", - /// "iron_boots": "bootsIron", - /// "bow_standby": "bow", - /// "bow_pulling_0": "bow_pull_0", - /// "bow_pulling_1": "bow_pull_1", /// [rest of string was truncated]";. - /// - public static string latest2lce_items { - get { - return ResourceManager.GetString("latest2lce_items", resourceCulture); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap map_icons_atlas { - get { - object obj = ResourceManager.GetObject("map_icons_atlas", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized string similar to { - /// "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)" - /// }, - /// { - /// [rest of string was truncated]";. - /// - public static string mapIconData { - get { - return ResourceManager.GetString("mapIconData", resourceCulture); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap moon_phases_atlas { - get { - object obj = ResourceManager.GetObject("moon_phases_atlas", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized string similar to { - /// "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": [rest of string was truncated]";. - /// - public static string moonPhaseData { - get { - return ResourceManager.GetString("moonPhaseData", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to { - /// "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", - /// "disp [rest of string was truncated]";. - /// - public static string paintingData { - get { - return ResourceManager.GetString("paintingData", resourceCulture); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap paintings_atlas { - get { - object obj = ResourceManager.GetObject("paintings_atlas", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized string similar to { - /// "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", [rest of string was truncated]";. - /// - public static string particleData { - get { - return ResourceManager.GetString("particleData", resourceCulture); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap particles_atlas { - get { - object obj = ResourceManager.GetObject("particles_atlas", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized string similar to { - /// "grass_block_top": 0, - /// "grass_block_side": 3, - /// "oak_planks": 4, - /// "smooth_stone_slab_side": 5, - /// "smooth_stone": 6, - /// "bricks": 7, - /// "cobweb": 11, - /// "poppy": 12, - /// "dandelion": 13, - /// "nether_portal": 14, - /// "oak_sapling": 15, - /// "oak_log": 20, - /// "oak_log_top": 21, - /// "dropper_front": 27, - /// "jungle_sapling": 30, - /// "mossy_cobblestone": 36, - /// "grass_block_side_overlay": 38, - /// "grass": 39, - /// "stone_bricks": 54, - /// "crafting_table_top": 43, - /// "dead_bush": 55, - /// "crafting_table_side": 59, /// [rest of string was truncated]";. - /// - public static string resourceFormat_6 { - get { - return ResourceManager.GetString("resourceFormat_6", resourceCulture); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap terrain_atlas { - get { - object obj = ResourceManager.GetObject("terrain_atlas", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap TexturePackIcon { - get { - object obj = ResourceManager.GetObject("TexturePackIcon", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap turtle { - get { - object obj = ResourceManager.GetObject("turtle", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Drawing.Bitmap. - /// - public static System.Drawing.Bitmap unknown_pack { - get { - object obj = ResourceManager.GetObject("unknown_pack", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - } -} +//------------------------------------------------------------------------------ +// +// 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 PckStudio.Core.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()] + public 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)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PckStudio.Core.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)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap additional_map_icons_atlas { + get { + object obj = ResourceManager.GetObject("additional_map_icons_atlas", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to { + /// "COMMENT_1": "JSON by MattNL", + /// "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" + /// }, + /// { + /// "interna [rest of string was truncated]";. + /// + public static string additionalMapiconsData { + get { + return ResourceManager.GetString("additionalMapiconsData", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to { + /// "COMMENT_1": "JSON by MattNL", + /// "entries": [ + /// { + /// "internalName": "base", + /// "displayName": "Base", + /// "colorKey": "Banner_Color" + /// }, + /// { + /// "internalName": "border", + /// "displayName": "Bordure", + /// "colorKey": "Banner_Color" + /// }, + /// { + /// "internalName": "bricks", + /// "displayName": "Field Masoned", + /// "colorKey": "Banner_Color" + /// }, + /// { + /// "internalName": "circle", + /// "displayName": "Roundel", + /// "colorKey": "Banner_Color" + /// }, [rest of string was truncated]";. + /// + public static string bannerData { + get { + return ResourceManager.GetString("bannerData", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap banners_atlas { + get { + object obj = ResourceManager.GetObject("banners_atlas", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to { + /// "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", + /// "colorCategory": ["Grass"] + /// } + /// }, + /// { + /// "internalName": "stone", + /// "displayName": "Stone" + /// }, + /// { + /// "internalName": "dirt", + /// "displayName": "Dirt" + /// }, + /// { + /// "internalName": "grass_side", + /// "displayName": "Grass [rest of string was truncated]";. + /// + public static string blockData { + get { + return ResourceManager.GetString("blockData", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap chain { + get { + object obj = ResourceManager.GetObject("chain", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap clock { + get { + object obj = ResourceManager.GetObject("clock", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap cloth { + get { + object obj = ResourceManager.GetObject("cloth", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap cloth_b { + get { + object obj = ResourceManager.GetObject("cloth_b", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap clouds { + get { + object obj = ResourceManager.GetObject("clouds", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to { + /// "Particle": { + /// "variants": [ + /// "Particle_Smoke", + /// "Particle_NetherPortal", + /// "Particle_EnderPortal", + /// "Particle_Ender", + /// "Particle_DragonBreathMin", + /// "Particle_DragonBreathMax" + /// ] + /// }, + /// "Particle_EnchantmentTable": { + /// "defaultName": "Particle_EnchantmentTable" + /// }, + /// "Particle_ScoreRing": { + /// "variants": [ + /// "Particle_ScoreRing_Small", + /// "Particle_ScoreRing_Medium", + /// "Particle_ScoreRing_Large" + /// ] + /// }, + /// "Potion_Effect": { + /// [rest of string was truncated]";. + /// + public static string colorEntries { + get { + return ResourceManager.GetString("colorEntries", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap Comparison { + get { + object obj = ResourceManager.GetObject("Comparison", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap compass { + get { + object obj = ResourceManager.GetObject("compass", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// 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]";. + /// + public static string defaultModels { + get { + return ResourceManager.GetString("defaultModels", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap diamond { + get { + object obj = ResourceManager.GetObject("diamond", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap experience_orbs_atlas { + get { + object obj = ResourceManager.GetObject("experience_orbs_atlas", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to { + /// "COMMENT_1": "JSON by MattNL", + /// "entries": [ + /// { + /// "internalName": "experience_orb_0", + /// "displayName": "Experience Orb (Size 1)" + /// }, + /// { + /// "internalName": "experience_orb_1", + /// "displayName": "Experience Orb (Size 2)" + /// }, + /// { + /// "internalName": "experience_orb_2", + /// "displayName": "Experience Orb (Size 3)" + /// }, + /// { + /// "internalName": "experience_orb_3", + /// "displayName": "Experience Orb (Size 4)" + /// }, + /// { + /// "internalName": "experience_orb_4", + /// "displayName": "Experience Or [rest of string was truncated]";. + /// + public static string experienceOrbData { + get { + return ResourceManager.GetString("experienceOrbData", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to { + /// "COMMENT_1": "JSON by MattNL", + /// "entries": [ + /// { + /// "internalName": "explosion_0", + /// "displayName": "Explosion (Stage 1)", + /// "colorKey": "Particle_Explode" + /// }, + /// { + /// "internalName": "explosion_1", + /// "displayName": "Explosion (Stage 2)", + /// "colorKey": "Particle_Explode" + /// }, + /// { + /// "internalName": "explosion_2", + /// "displayName": "Explosion (Stage 3)", + /// "colorKey": "Particle_Explode" + /// }, + /// { + /// "internalName": "explosion_3", + /// [rest of string was truncated]";. + /// + public static string explosionData { + get { + return ResourceManager.GetString("explosionData", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap explosions_atlas { + get { + object obj = ResourceManager.GetObject("explosions_atlas", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap fire_layer_0 { + get { + object obj = ResourceManager.GetObject("fire_layer_0", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap fire_layer_1 { + get { + object obj = ResourceManager.GetObject("fire_layer_1", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap gold { + get { + object obj = ResourceManager.GetObject("gold", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap iron { + get { + object obj = ResourceManager.GetObject("iron", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to { + /// "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, + /// "colorKey": "Armour_Default_Leather_Colour" + /// }, + /// { + /// "internalName": "helmetChain", + /// "displayName": "Chain Helmet" + /// }, + /// { + /// "internalName": "helmetIron", + /// "displayName": "Iron Helmet" + /// }, + /// { + /// "internalName": "helmetDiamond", + /// "displayName": [rest of string was truncated]";. + /// + public static string itemData { + get { + return ResourceManager.GetString("itemData", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap items_atlas { + get { + object obj = ResourceManager.GetObject("items_atlas", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to [ + /// { + /// "name": "Bow Pulling", + /// "row": 5, + /// "column": 6, + /// "frameCount": 3, + /// "frameTime": 6, + /// "direction": 1 + /// }, + /// { + /// "name": "Leather Cap", + /// "row": 0, + /// "column": 0, + /// "overlay": { "row": 0, "column": 9 } + /// }, + /// { + /// "name": "Leather Tunic", + /// "row": 0, + /// "column": 1, + /// "overlay": { "row": 0, "column": 10 } + /// }, + /// { + /// "name": "Leather Pants", + /// "row": 0, + /// "column": 2, + /// "overlay": { "row": 0, "column": 11 } + /// }, + /// { + /// "name": "Leather [rest of string was truncated]";. + /// + public static string items_groups { + get { + return ResourceManager.GetString("items_groups", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap map_icons_atlas { + get { + object obj = ResourceManager.GetObject("map_icons_atlas", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to { + /// "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)" + /// }, + /// { + /// [rest of string was truncated]";. + /// + public static string mapIconData { + get { + return ResourceManager.GetString("mapIconData", 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]";. + /// + public static string modelMetaData { + get { + return ResourceManager.GetString("modelMetaData", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap moon_phases_atlas { + get { + object obj = ResourceManager.GetObject("moon_phases_atlas", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to { + /// "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": [rest of string was truncated]";. + /// + public static string moonPhaseData { + get { + return ResourceManager.GetString("moonPhaseData", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to [ + /// { + /// "name": "The Pool", + /// "row": 0, + /// "column": 2, + /// "rowSpan": 2, + /// "columnSpan": 1, + /// "direction": 1 + /// }, + /// { + /// "name": "Bonjour Monsiuer Courbet", + /// "row": 2, + /// "column": 2, + /// "rowSpan": 2, + /// "columnSpan": 1, + /// "direction": 0 + /// }, + /// { + /// "name": "Seaside", + /// "row": 4, + /// "column": 2, + /// "rowSpan": 2, + /// "columnSpan": 1, + /// "direction": 0 + /// }, + /// { + /// "name": "sunset_dense", + /// "row": 6, + /// "column": 2, + /// "rowSpan": 2, + /// "columnSpan": [rest of string was truncated]";. + /// + public static string painting_groups { + get { + return ResourceManager.GetString("painting_groups", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to { + /// "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", + /// "disp [rest of string was truncated]";. + /// + public static string paintingData { + get { + return ResourceManager.GetString("paintingData", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap paintings_atlas { + get { + object obj = ResourceManager.GetObject("paintings_atlas", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to { + /// "COMMENT_1": "JSON by MattNL", + /// "entries": [ + /// { + /// "internalName": "generic_0", + /// "displayName": "Generic (Stage 1)", + /// "colorKey": "Particle" + /// }, + /// { + /// "internalName": "generic_1", + /// "displayName": "Generic (Stage 2)", + /// "colorKey": "Particle" + /// }, + /// { + /// "internalName": "generic_2", + /// "displayName": "Generic (Stage 3)", + /// "colorKey": "Particle" + /// }, + /// { + /// "internalName": "generic_3", + /// "displayName": "Generic (Stage 4)", + /// [rest of string was truncated]";. + /// + public static string particleData { + get { + return ResourceManager.GetString("particleData", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap particles_atlas { + get { + object obj = ResourceManager.GetObject("particles_atlas", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to [ + /// { + /// "name": "Generic", + /// "row": 0, + /// "column": 0, + /// "frameCount": 8, + /// "frameTime": 2, + /// "direction": 0 + /// }, + /// { + /// "name": "Splash", + /// "row": 3, + /// "column": 1, + /// "frameCount": 4, + /// "frameTime": 2, + /// "direction": 0 + /// }, + /// { + /// "name": "Drip", + /// "row": 0, + /// "column": 7, + /// "frameCount": 3, + /// "frameTime": 4, + /// "direction": 0 + /// }, + /// { + /// "name": "Effect", + /// "row": 0, + /// "column": 8, + /// "frameCount": 8, + /// "frameTime": 2, + /// "direction": [rest of string was truncated]";. + /// + public static string particles_groups { + get { + return ResourceManager.GetString("particles_groups", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap rain { + get { + object obj = ResourceManager.GetObject("rain", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap snow { + get { + object obj = ResourceManager.GetObject("snow", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap terrain_atlas { + get { + object obj = ResourceManager.GetObject("terrain_atlas", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to [ + /// { + /// "name": "Oak Door", + /// "row": 1, + /// "column": 5, + /// "rowSpan": 1, + /// "columnSpan": 2, + /// "direction": 1 + /// }, + /// { + /// "name": "Iron Door", + /// "row": 2, + /// "column": 5, + /// "rowSpan": 1, + /// "columnSpan": 2, + /// "direction": 1 + /// }, + /// { + /// "name": "Acacia Door", + /// "row": 0, + /// "column": 23, + /// "rowSpan": 1, + /// "columnSpan": 2, + /// "direction": 1 + /// }, + /// { + /// "name": "Birch Door", + /// "row": 1, + /// "column": 23, + /// "rowSpan": 1, + /// "columnSpan": 2, + /// "di [rest of string was truncated]";. + /// + public static string terrain_groups { + get { + return ResourceManager.GetString("terrain_groups", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap TexturePackIcon { + get { + object obj = ResourceManager.GetObject("TexturePackIcon", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap turtle { + get { + object obj = ResourceManager.GetObject("turtle", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap unknown_pack { + get { + object obj = ResourceManager.GetObject("unknown_pack", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/PckStudio.Core/Properties/Resources.resx b/PckStudio.Core/Properties/Resources.resx index e0ed160e..93c7f7bf 100644 --- a/PckStudio.Core/Properties/Resources.resx +++ b/PckStudio.Core/Properties/Resources.resx @@ -145,12 +145,18 @@ ..\Resources\armor\cloth_b.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\clouds.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\Comparison.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a ..\Resources\compass.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\defaultModels.json;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + ..\Resources\armor\diamond.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -181,14 +187,14 @@ ..\Resources\atlas\itemData.json;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 + + ..\Resources\atlas\groups\item_groups.json;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + ..\Resources\atlas\items.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\java\latest2lce_blocks.json;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 - - - ..\Resources\java\latest2lce_items.json;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + ..\Resources\atlas\groups\painting_groups.json;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 ..\Resources\atlas\mapIconData.json;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 @@ -196,6 +202,9 @@ ..\Resources\atlas\map_icons.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\modelMetaData.json;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + ..\Resources\atlas\moonPhaseData.json;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 @@ -211,11 +220,20 @@ ..\Resources\atlas\particleData.json;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;iso-8859-1 + + ..\Resources\atlas\groups\particles_groups.json;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + ..\Resources\atlas\particles.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\java\resourceFormat_6.json;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + ..\Resources\rain.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\snow.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\atlas\groups\terrain_groups.json;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 ..\Resources\atlas\terrain.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -229,4 +247,7 @@ ..\Resources\unknown_pack.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\atlas\colorEntries.json;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + \ No newline at end of file diff --git a/PckStudio.Core/ResourceLocations.cs b/PckStudio.Core/ResourceLocations.cs index c4788603..69ecdd43 100644 --- a/PckStudio.Core/ResourceLocations.cs +++ b/PckStudio.Core/ResourceLocations.cs @@ -15,7 +15,11 @@ * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. **/ +using System.Diagnostics; using System.Drawing; +using System.IO; +using System.Linq; +using Newtonsoft.Json; using PckStudio.Core.Properties; using PckStudio.Json; @@ -23,6 +27,10 @@ namespace PckStudio.Core { public static class ResourceLocations { + static JsonSerializerSettings _serializerSettings = new JsonSerializerSettings() + { + Converters = [new AtlasGroupJsonConverter()] + }; static ResourceLocations() { _all = new ResourceLocation[] { @@ -50,77 +58,14 @@ namespace PckStudio.Core public static string GetPathFromCategory(ResourceCategory category) => ResourceLocation.GetPathFromCategory(category); - private static readonly AtlasGroup[] _particaleAtlasGroups = - { - new AtlasGroupAnimation("generic" , row: 0, column: 0, frameCount: 8, ImageLayoutDirection.Horizontal, 2), - new AtlasGroupAnimation("splash" , row: 3, column: 1, frameCount: 4, ImageLayoutDirection.Horizontal, 2), - new AtlasGroupAnimation("drip" , row: 0, column: 7, frameCount: 3, ImageLayoutDirection.Horizontal, 4), - new AtlasGroupAnimation("effect" , row: 0, column: 8, frameCount: 8, ImageLayoutDirection.Horizontal, 2), - new AtlasGroupAnimation("splash_effect" , row: 0, column: 9, frameCount: 8, ImageLayoutDirection.Horizontal, 2), - new AtlasGroupAnimation("firework_spark" , row: 0, column: 10, frameCount: 8, ImageLayoutDirection.Horizontal, 2), - new AtlasGroupAnimation("glitter" , row: 0, column: 11, frameCount: 8, ImageLayoutDirection.Horizontal, 2), - new AtlasGroupAnimation("BE_explosion" , row: 0, column: 12, frameCount: 16, ImageLayoutDirection.Horizontal), - new AtlasGroupLargeTile("flash" , row: 4, column: 2, rowSpan: 4, columnSpan: 4), - new AtlasGroupLargeTileAnimation("bubble_pop", row: 6, column: 6, rowSpan: 2, columnSpan: 2, frameCount: 5, ImageLayoutDirection.Horizontal, 2), - }; + private static readonly AtlasGroup[] _particaleAtlasGroups = JsonConvert.DeserializeObject(Resources.particles_groups, _serializerSettings); - private static readonly AtlasGroup[] _terrainAtlasGroups = - { - new AtlasGroupLargeTile("Oak Door" , row: 1, column: 5, rowSpan: 1, columnSpan: 2), - new AtlasGroupLargeTile("Iron Door" , row: 2, column: 5, rowSpan: 1, columnSpan: 2), - new AtlasGroupLargeTile("Acacia Door" , row: 0, column: 23, rowSpan: 1, columnSpan: 2), - new AtlasGroupLargeTile("Birch Door" , row: 1, column: 23, rowSpan: 1, columnSpan: 2), - new AtlasGroupLargeTile("Dark Oak Door", row: 2, column: 23, rowSpan: 1, columnSpan: 2), - new AtlasGroupLargeTile("Jungle Door" , row: 3, column: 23, rowSpan: 1, columnSpan: 2), - new AtlasGroupLargeTile("Spruce Door" , row: 4, column: 23, rowSpan: 1, columnSpan: 2), + private static readonly AtlasGroup[] _terrainAtlasGroups = JsonConvert.DeserializeObject(Resources.terrain_groups, _serializerSettings); - new AtlasGroupLargeTile("Large Fern" , row: 0, column: 20, rowSpan: 1, columnSpan: 2), - new AtlasGroupLargeTile("Double Tall Grass", row: 1, column: 20, rowSpan: 1, columnSpan: 2), - new AtlasGroupLargeTile("Poeny" , row: 2, column: 20, rowSpan: 1, columnSpan: 2), - new AtlasGroupLargeTile("Rose Bush" , row: 3, column: 20, rowSpan: 1, columnSpan: 2), - new AtlasGroupLargeTile("Lilac" , row: 4, column: 20, rowSpan: 1, columnSpan: 2), + private static readonly AtlasGroup[] _itemsAtlasGroups = JsonConvert.DeserializeObject(Resources.items_groups, _serializerSettings); - new AtlasGroupAnimation("Wheat" , row: 8, column: 5, frameCount: 8, ImageLayoutDirection.Horizontal, 5), - new AtlasGroupAnimation("Potatoes" , row: 9, column: 16, frameCount: 4, ImageLayoutDirection.Horizontal, 5), - new AtlasGroupAnimation("Carrots" , row: 8, column: 12, frameCount: 4, ImageLayoutDirection.Horizontal, 5), - new AtlasGroupAnimation("Beetroots" , row: 0, column: 25, frameCount: 4, ImageLayoutDirection.Horizontal, 5), - new AtlasGroupAnimation("Nether Wart", row: 2, column: 14, frameCount: 3, ImageLayoutDirection.Horizontal, 5), - new AtlasGroupAnimation("Destroy" , row: 0, column: 15, frameCount: 10, ImageLayoutDirection.Horizontal, 3), - }; - - private static readonly AtlasGroup[] _itemsAtlasGroups = - { - new AtlasGroupAnimation("Bow Pulling", row: 5, column: 6, frameCount: 3, ImageLayoutDirection.Vertical, 6), - }; - - private static readonly AtlasGroup[] _paintingAtlasGroups = - { - new AtlasGroupLargeTile("The Pool" , row: 0, column: 2, rowSpan: 2, columnSpan: 1), - new AtlasGroupLargeTile("Bonjour Monsiuer Courbet", row: 2, column: 2, rowSpan: 2, columnSpan: 1), - new AtlasGroupLargeTile("Seaside" , row: 4, column: 2, rowSpan: 2, columnSpan: 1), - new AtlasGroupLargeTile("sunset_dense" , row: 6, column: 2, rowSpan: 2, columnSpan: 1), - new AtlasGroupLargeTile("Creebet" , row: 8, column: 2, rowSpan: 2, columnSpan: 1), - - new AtlasGroupLargeTile("Wanderer" , row: 0, column: 4, rowSpan: 1, columnSpan: 2), - new AtlasGroupLargeTile("Graham" , row: 1, column: 4, rowSpan: 1, columnSpan: 2), - - new AtlasGroupLargeTile("Fighters" , row: 0, column: 6, rowSpan: 4, columnSpan: 2), - - new AtlasGroupLargeTile("Match" , row: 0, column: 8, rowSpan: 2, columnSpan: 2), - new AtlasGroupLargeTile("Bust" , row: 2, column: 8, rowSpan: 2, columnSpan: 2), - new AtlasGroupLargeTile("The stage is set" , row: 4, column: 8, rowSpan: 2, columnSpan: 2), - new AtlasGroupLargeTile("The Void" , row: 6, column: 8, rowSpan: 2, columnSpan: 2), - new AtlasGroupLargeTile("Skull and Roses" , row: 8, column: 8, rowSpan: 2, columnSpan: 2), - new AtlasGroupLargeTile("Wither" , row: 10, column: 8, rowSpan: 2, columnSpan: 2), - - new AtlasGroupLargeTile("Mortal Coil" , row: 12, column: 4, rowSpan: 4, columnSpan: 3), - new AtlasGroupLargeTile("Kong" , row: 12, column: 7, rowSpan: 4, columnSpan: 3), - - new AtlasGroupLargeTile("Back Texture" , row: 12, column: 0, rowSpan: 4, columnSpan: 4), - new AtlasGroupLargeTile("Pointer" , row: 0, column: 12, rowSpan: 4, columnSpan: 4), - new AtlasGroupLargeTile("Pigscene" , row: 4, column: 12, rowSpan: 4, columnSpan: 4), - new AtlasGroupLargeTile("Skull On Fire" , row: 8, column: 12, rowSpan: 4, columnSpan: 4), - }; + private static readonly AtlasGroup[] _paintingAtlasGroups = JsonConvert.DeserializeObject(Resources.painting_groups, _serializerSettings); + private static readonly ResourceLocation[] _all; } 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/atlas/bannerData.json b/PckStudio.Core/Resources/atlas/bannerData.json index f1de015f..4907e048 100644 --- a/PckStudio.Core/Resources/atlas/bannerData.json +++ b/PckStudio.Core/Resources/atlas/bannerData.json @@ -1,1053 +1,213 @@ { - "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" - ] - } - } - ] + "COMMENT_1": "JSON by MattNL", + "entries": [ + { + "internalName": "base", + "displayName": "Base", + "colorKey": "Banner_Color" + }, + { + "internalName": "border", + "displayName": "Bordure", + "colorKey": "Banner_Color" + }, + { + "internalName": "bricks", + "displayName": "Field Masoned", + "colorKey": "Banner_Color" + }, + { + "internalName": "circle", + "displayName": "Roundel", + "colorKey": "Banner_Color" + }, + { + "internalName": "creeper", + "displayName": "Creeper Charge", + "colorKey": "Banner_Color" + }, + { + "internalName": "cross", + "displayName": "Saltire", + "colorKey": "Banner_Color" + }, + { + "internalName": "curly_border", + "displayName": "Bordure Indented", + "colorKey": "Banner_Color" + }, + { + "internalName": "diagonal_left", + "displayName": "Per Bend Sinister", + "colorKey": "Banner_Color" + }, + { + "internalName": "diagonal_right", + "displayName": "Per Bend", + "colorKey": "Banner_Color" + }, + { + "internalName": "diagonal_up_left", + "displayName": "Per Bend Inverted", + "colorKey": "Banner_Color" + }, + { + "internalName": "diagonal_up_right", + "displayName": "Per Bend Sinister Inverted", + "colorKey": "Banner_Color" + }, + { + "internalName": "flower", + "displayName": "Flower Charge", + "colorKey": "Banner_Color" + }, + { + "internalName": "gradient", + "displayName": "Gradient", + "colorKey": "Banner_Color" + }, + { + "internalName": "gradient_up", + "displayName": "Base Gradient", + "colorKey": "Banner_Color" + }, + { + "internalName": "half_horizontal", + "displayName": "Per Fess", + "colorKey": "Banner_Color" + }, + { + "internalName": "half_horizontal_bottom", + "displayName": "Per Fess Inverted", + "colorKey": "Banner_Color" + }, + { + "internalName": "half_vertical", + "displayName": "Per Pale", + "colorKey": "Banner_Color" + }, + { + "internalName": "half_vertical_right", + "displayName": "Per Pale Inverted", + "colorKey": "Banner_Color" + }, + { + "internalName": "mojang", + "displayName": "Thing", + "colorKey": "Banner_Color" + }, + { + "internalName": "rhombus", + "displayName": "Lozenge", + "colorKey": "Banner_Color" + }, + { + "internalName": "skull", + "displayName": "Skull Charge", + "colorKey": "Banner_Color" + }, + { + "internalName": "small_stripes", + "displayName": "Paly", + "colorKey": "Banner_Color" + }, + { + "internalName": "square_bottom_left", + "displayName": "Base Dexter Canton", + "colorKey": "Banner_Color" + }, + { + "internalName": "square_bottom_right", + "displayName": "Base Sinister Canton", + "colorKey": "Banner_Color" + }, + { + "internalName": "square_top_left", + "displayName": "Chief Dexter Canton", + "colorKey": "Banner_Color" + }, + { + "internalName": "square_top_right", + "displayName": "Chief Sinister Canton", + "colorKey": "Banner_Color" + }, + { + "internalName": "straight_cross", + "displayName": "Cross", + "colorKey": "Banner_Color" + }, + { + "internalName": "stripe_bottom", + "displayName": "Base Fess", + "colorKey": "Banner_Color" + }, + { + "internalName": "stripe_center", + "displayName": "Pale", + "colorKey": "Banner_Color" + }, + { + "internalName": "strip_downleft", + "displayName": "Bend Sinister", + "colorKey": "Banner_Color" + }, + { + "internalName": "stripe_downright", + "displayName": "Bend", + "colorKey": "Banner_Color" + }, + { + "internalName": "stripe_left", + "displayName": "Pale Dexter", + "colorKey": "Banner_Color" + }, + { + "internalName": "stripe_middle", + "displayName": "Fess", + "colorKey": "Banner_Color" + }, + { + "internalName": "stripe_right", + "displayName": "Pale Sinister", + "colorKey": "Banner_Color" + }, + { + "internalName": "stripe_top", + "displayName": "Chief Fess", + "colorKey": "Banner_Color" + }, + { + "internalName": "triangle_bottom", + "displayName": "Chevron", + "colorKey": "Banner_Color" + }, + { + "internalName": "triangle_top", + "displayName": "Inverted Chevron", + "colorKey": "Banner_Color" + }, + { + "internalName": "triangles_bottom", + "displayName": "Base Indented", + "colorKey": "Banner_Color" + }, + { + "internalName": "triangles_top", + "displayName": "Chief Indented", + "colorKey": "Banner_Color" + }, + { + "internalName": "mask", + "displayName": "Mask" + }, + { + "internalName": "illager", + "displayName": "Ominous Banner [PS4 ONLY]" + }, + { + "internalName": "globe", + "displayName": "Globe [PS4 ONLY]", + "colorKey": "Banner_Color" + } + ] } diff --git a/PckStudio.Core/Resources/atlas/blockData.json b/PckStudio.Core/Resources/atlas/blockData.json index b994b67a..d51b6403 100644 --- a/PckStudio.Core/Resources/atlas/blockData.json +++ b/PckStudio.Core/Resources/atlas/blockData.json @@ -1,2922 +1,2535 @@ { - "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_flow0 - "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_flow1 - "displayName": "" - }, - { - "internalName": "", // water_flow2 - "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_flow0 - "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_flow1 - "displayName": "", - }, - { - "internalName": "", // lava_flow2 - "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_a0", - "displayName": "" - }, - { - "internalName": "kelp_a1", - "displayName": "" - }, - { - "internalName": "kelp_a2", - "displayName": "" - }, - { - "internalName": "kelp_top_a", - "displayName": "Kelp (Top)" - }, - { - "internalName": "kelp_top_a0", - "displayName": "" - }, - { - "internalName": "kelp_top_a1", - "displayName": "" - }, - { - "internalName": "kelp_top_a2", - "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": "" - } - ] + "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)", + "colorKey": "Grass" + }, + { + "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)", + "colorKey": "Grass" + }, + { + "internalName": "tallgrass", + "displayName": "Tall Grass", + "colorKey": "Grass" + }, + { + "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", + "colorKey": "Foliage" + }, + { + "internalName": "leaves_opaque", + "displayName": "Oak Leaves (Opaque)", + "colorKey": "Foliage" + }, + { + "internalName": "stonebrick", + "displayName": "Stone Bricks" + }, + { + "internalName": "deadbush", + "displayName": "Dead Bush/Shrub" + }, + { + "internalName": "fern", + "displayName": "Fern", + "colorKey": "Grass" + }, + { + "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", + "colorKey": "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", + "colorKey": "Stem_Color" + }, + { + "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)", + "colorKey": "Stem_Color" + }, + { + "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", + "colorKey": "Foliage" + }, + { + "internalName": "leaves_spruce_opaque", + "displayName": "Spruce Leaves (Opaque)", + "colorKey": "Foliage" + }, + { + "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", + "colorKey": "Foliage" + }, + { + "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)", + "colorKey": "RedstoneDust" + }, + { + "internalName": "redstone_dust_line", + "displayName": "Redstone Dust (Line)", + "colorKey": "RedstoneDust" + }, + { + "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", + "colorKey": "Foliage" + }, + { + "internalName": "leaves_jungle_opaque", + "displayName": "Jungle Leaves (Opaque)", + "colorKey": "Foliage" + }, + { + "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", + "colorKey": "Water" + }, + { + "internalName": "water_flow", + "displayName": "Flowing Water", + "colorKey": "Water" + }, + { + "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" + }, + { + "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)", + "colorKey": "Grass" + }, + { + "internalName": "double_plant_grass_top", + "displayName": "Double Tall Grass (Top)", + "colorKey": "Grass" + }, + { + "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", + "colorKey": "Foliage" + }, + { + "internalName": "leaves_acacia_fast", + "displayName": "Acacia Leaves (Opaque)", + "colorKey": "Foliage" + }, + { + "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)", + "colorKey": "Grass" + }, + { + "internalName": "double_plant_grass_bottom", + "displayName": "Double Tall Grass (Bottom)", + "colorKey": "Grass" + }, + { + "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", + "colorKey": "Foliage" + }, + { + "internalName": "leaves_big_oak_fast", + "displayName": "Dark Oak Leaves (Opaque)", + "colorKey": "Foliage" + }, + { + "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", + "colorKey": "Foliage", + "defaultColorKey": "Foliage_Birch" + }, + { + "internalName": "leaves_birch_fast", + "displayName": "Birch Leaves (Opaque)", + "colorKey": "Foliage", + "defaultColorKey": "Foliage_Birch" + }, + { + "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)", + "colorKey": "Shulker_Box_Color" + }, + { + "internalName": "shulker_top_overlay", + "displayName": "Shulker Box (Break Particles) (Overlay) (Unused)" + }, + { + "internalName": "cauldron_water", + "displayName": "Cauldron Water", + "allowCustomColour": true, + "colorKey": "Cauldron_Water_Effect" + }, + { + "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/atlas/colorEntries.json b/PckStudio.Core/Resources/atlas/colorEntries.json new file mode 100644 index 00000000..cf545cf2 --- /dev/null +++ b/PckStudio.Core/Resources/atlas/colorEntries.json @@ -0,0 +1,376 @@ +{ + "Grass": { + "variants": [ + "Grass_Common", + "Grass_Mesa", + "Grass_Swamp1", + "Grass_Swamp2" + ] + }, + "Foliage": { + "variants": [ + "Foliage_Default", + "Foliage_Evergreen", + "Foliage_Birch", + "Foliage_Mesa", + "Foliage_Swampland" + ] + }, + "RedstoneDust": { + "variants": [ + "Tile_RedstoneDust", + "Tile_RedstoneDustUnlit", + "Tile_RedstoneDustLitMin", + "Tile_RedstoneDustLitMax" + ] + }, + "Particle": { + "variants": [ + "Particle_Smoke", + "Particle_NetherPortal", + "Particle_EnderPortal", + "Particle_Ender", + "Particle_DragonBreathMin", + "Particle_DragonBreathMax" + ] + }, + "Particle_ScoreRing": { + "variants": [ + "Particle_ScoreRing_Small", + "Particle_ScoreRing_Medium", + "Particle_ScoreRing_Large" + ] + }, + "Potion_Effect": { + "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" + ] + }, + "Particle_Drip": { + "variants": [ + "Particle_DripWater", + "Particle_DripLavaStart", + "Particle_DripLavaEnd" + ] + }, + "Particle_Note": { + "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" + ] + }, + "Water": { + "isWaterColour": true, + "variants": [ + "Water_Plains", + "Water_Ocean", + "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" + ] + }, + "SpawnEggBaseColor": { + "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" + ] + }, + "SpawnEggOverlayColor": { + "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" + ] + }, + "Bed_Color": { + "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" + ] + }, + "Particle_Explode": { + "variants": [ + "Particle_Explode", + "Particle_HugeExplosion" + ] + }, + "Banner_Color": { + "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" + ] + }, + "Cauldron_Water_Effect": { + "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" + ] + }, + "Shulker_Box_Color": { + "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" + ] + }, + "Stem_Color": { + "variants": [ + "Tile_StemMin", + "Tile_StemMax" + ] + } +} diff --git a/PckStudio.Core/Resources/atlas/experienceOrbData.json b/PckStudio.Core/Resources/atlas/experienceOrbData.json index f83a7ab3..c8134837 100644 --- a/PckStudio.Core/Resources/atlas/experienceOrbData.json +++ b/PckStudio.Core/Resources/atlas/experienceOrbData.json @@ -3,102 +3,47 @@ "entries": [ { "internalName": "experience_orb_0", - "displayName": "Experience Orb (Size 1)", - "hasColourEntry": true, - "colourEntry": { - "defaultName": "experience_orb", - "variants": ["experience_orb"] - } + "displayName": "Experience Orb (Size 1)" }, { "internalName": "experience_orb_1", - "displayName": "Experience Orb (Size 2)", - "hasColourEntry": true, - "colourEntry": { - "defaultName": "experience_orb", - "variants": ["experience_orb"] - } + "displayName": "Experience Orb (Size 2)" }, { "internalName": "experience_orb_2", - "displayName": "Experience Orb (Size 3)", - "hasColourEntry": true, - "colourEntry": { - "defaultName": "experience_orb", - "variants": ["experience_orb"] - } + "displayName": "Experience Orb (Size 3)" }, { "internalName": "experience_orb_3", - "displayName": "Experience Orb (Size 4)", - "hasColourEntry": true, - "colourEntry": { - "defaultName": "experience_orb", - "variants": ["experience_orb"] - } + "displayName": "Experience Orb (Size 4)" }, { "internalName": "experience_orb_4", - "displayName": "Experience Orb (Size 5)", - "hasColourEntry": true, - "colourEntry": { - "defaultName": "experience_orb", - "variants": ["experience_orb"] - } + "displayName": "Experience Orb (Size 5)" }, { "internalName": "experience_orb_5", - "displayName": "Experience Orb (Size 6)", - "hasColourEntry": true, - "colourEntry": { - "defaultName": "experience_orb", - "variants": ["experience_orb"] - } + "displayName": "Experience Orb (Size 6)" }, { "internalName": "experience_orb_6", - "displayName": "Experience Orb (Size 7)", - "hasColourEntry": true, - "colourEntry": { - "defaultName": "experience_orb", - "variants": ["experience_orb"] - } + "displayName": "Experience Orb (Size 7)" }, { "internalName": "experience_orb_7", - "displayName": "Experience Orb (Size 8)", - "hasColourEntry": true, - "colourEntry": { - "defaultName": "experience_orb", - "variants": ["experience_orb"] - } + "displayName": "Experience Orb (Size 8)" }, { "internalName": "experience_orb_8", - "displayName": "Experience Orb (Size 9)", - "hasColourEntry": true, - "colourEntry": { - "defaultName": "experience_orb", - "variants": ["experience_orb"] - } + "displayName": "Experience Orb (Size 9)" }, { "internalName": "experience_orb_9", - "displayName": "Experience Orb (Size 10)", - "hasColourEntry": true, - "colourEntry": { - "defaultName": "experience_orb", - "variants": ["experience_orb"] - } + "displayName": "Experience Orb (Size 10)" }, { "internalName": "experience_orb_10", - "displayName": "Experience Orb (Size 11)", - "hasColourEntry": true, - "colourEntry": { - "defaultName": "experience_orb", - "variants": ["experience_orb"] - } + "displayName": "Experience Orb (Size 11)" }, { "internalName": "", diff --git a/PckStudio.Core/Resources/atlas/explosionData.json b/PckStudio.Core/Resources/atlas/explosionData.json index f9845f7e..2ed608eb 100644 --- a/PckStudio.Core/Resources/atlas/explosionData.json +++ b/PckStudio.Core/Resources/atlas/explosionData.json @@ -1,197 +1,85 @@ { - "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" - ] - } - } - ] + "COMMENT_1": "JSON by MattNL", + "entries": [ + { + "internalName": "explosion_0", + "displayName": "Explosion (Stage 1)", + "colorKey": "Particle_Explode" + }, + { + "internalName": "explosion_1", + "displayName": "Explosion (Stage 2)", + "colorKey": "Particle_Explode" + }, + { + "internalName": "explosion_2", + "displayName": "Explosion (Stage 3)", + "colorKey": "Particle_Explode" + }, + { + "internalName": "explosion_3", + "displayName": "Explosion (Stage 4)", + "colorKey": "Particle_Explode" + }, + { + "internalName": "explosion_4", + "displayName": "Explosion (Stage 5)", + "colorKey": "Particle_Explode" + }, + { + "internalName": "explosion_5", + "displayName": "Explosion (Stage 6)", + "colorKey": "Particle_Explode" + }, + { + "internalName": "explosion_6", + "displayName": "Explosion (Stage 7)", + "colorKey": "Particle_Explode" + }, + { + "internalName": "explosion_7", + "displayName": "Explosion (Stage 8)", + "colorKey": "Particle_Explode" + }, + { + "internalName": "explosion_8", + "displayName": "Explosion (Stage 9)", + "colorKey": "Particle_Explode" + }, + { + "internalName": "explosion_9", + "displayName": "Explosion (Stage 10)", + "colorKey": "Particle_Explode" + }, + { + "internalName": "explosion_10", + "displayName": "Explosion (Stage 11)", + "colorKey": "Particle_Explode" + }, + { + "internalName": "explosion_11", + "displayName": "Explosion (Stage 12)", + "colorKey": "Particle_Explode" + }, + { + "internalName": "explosion_12", + "displayName": "Explosion (Stage 13)", + "colorKey": "Particle_Explode" + }, + { + "internalName": "explosion_13", + "displayName": "Explosion (Stage 14)", + "colorKey": "Particle_Explode" + }, + { + "internalName": "explosion_14", + "displayName": "Explosion (Stage 15)", + "colorKey": "Particle_Explode" + }, + { + "internalName": "explosion_15", + "displayName": "Explosion (Stage 16)", + "colorKey": "Particle_Explode" + } + ] } \ No newline at end of file diff --git a/PckStudio.Core/Resources/atlas/groups/item_groups.json b/PckStudio.Core/Resources/atlas/groups/item_groups.json new file mode 100644 index 00000000..2701ffab --- /dev/null +++ b/PckStudio.Core/Resources/atlas/groups/item_groups.json @@ -0,0 +1,40 @@ +[ + { + "name": "Bow Pulling", + "row": 5, + "column": 6, + "frameCount": 3, + "frameTime": 6, + "direction": 1 + }, + { + "name": "Leather Cap", + "row": 0, + "column": 0, + "overlay": { "row": 0, "column": 9 } + }, + { + "name": "Leather Tunic", + "row": 0, + "column": 1, + "overlay": { "row": 0, "column": 10 } + }, + { + "name": "Leather Pants", + "row": 0, + "column": 2, + "overlay": { "row": 0, "column": 11 } + }, + { + "name": "Leather Boots", + "row": 0, + "column": 3, + "overlay": { "row": 0, "column": 12 } + }, + { + "name": "Leather Horse Armor", + "row": 15, + "column": 13, + "overlay": { "row": 0, "column": 16 } + } +] \ No newline at end of file diff --git a/PckStudio.Core/Resources/atlas/groups/painting_groups.json b/PckStudio.Core/Resources/atlas/groups/painting_groups.json new file mode 100644 index 00000000..5d80577f --- /dev/null +++ b/PckStudio.Core/Resources/atlas/groups/painting_groups.json @@ -0,0 +1,162 @@ +[ + { + "name": "The Pool", + "row": 0, + "column": 2, + "rowSpan": 2, + "columnSpan": 1, + "direction": 1 + }, + { + "name": "Bonjour Monsiuer Courbet", + "row": 2, + "column": 2, + "rowSpan": 2, + "columnSpan": 1, + "direction": 0 + }, + { + "name": "Seaside", + "row": 4, + "column": 2, + "rowSpan": 2, + "columnSpan": 1, + "direction": 0 + }, + { + "name": "sunset_dense", + "row": 6, + "column": 2, + "rowSpan": 2, + "columnSpan": 1, + "direction": 0 + }, + { + "name": "Creebet", + "row": 8, + "column": 2, + "rowSpan": 2, + "columnSpan": 1, + "direction": 0 + }, + { + "name": "Wanderer", + "row": 0, + "column": 4, + "rowSpan": 1, + "columnSpan": 2, + "direction": 1 + }, + { + "name": "Graham", + "row": 1, + "column": 4, + "rowSpan": 1, + "columnSpan": 2, + "direction": 1 + }, + { + "name": "Fighters", + "row": 0, + "column": 6, + "rowSpan": 4, + "columnSpan": 2, + "direction": 1 + }, + { + "name": "Match", + "row": 0, + "column": 8, + "rowSpan": 2, + "columnSpan": 2, + "direction": 1 + }, + { + "name": "Bust", + "row": 2, + "column": 8, + "rowSpan": 2, + "columnSpan": 2, + "direction": 1 + }, + { + "name": "The stage is set", + "row": 4, + "column": 8, + "rowSpan": 2, + "columnSpan": 2, + "direction": 1 + }, + { + "name": "The Void", + "row": 6, + "column": 8, + "rowSpan": 2, + "columnSpan": 2, + "direction": 1 + }, + { + "name": "Skull and Roses", + "row": 8, + "column": 8, + "rowSpan": 2, + "columnSpan": 2, + "direction": 0 + }, + { + "name": "Wither", + "row": 10, + "column": 8, + "rowSpan": 2, + "columnSpan": 2, + "direction": 0 + }, + { + "name": "Mortal Coil", + "row": 12, + "column": 4, + "rowSpan": 4, + "columnSpan": 3, + "direction": 0 + }, + { + "name": "Kong", + "row": 12, + "column": 7, + "rowSpan": 4, + "columnSpan": 3, + "direction": 0 + }, + { + "name": "Back Texture", + "row": 12, + "column": 0, + "rowSpan": 4, + "columnSpan": 4, + "direction": 0 + }, + { + "name": "Pointer", + "row": 0, + "column": 12, + "rowSpan": 4, + "columnSpan": 4, + "direction": 1 + }, + { + "name": "Pigscene", + "row": 4, + "column": 12, + "rowSpan": 4, + "columnSpan": 4, + "direction": 1 + }, + { + "name": "Skull On Fire", + "row": 8, + "column": 12, + "rowSpan": 4, + "columnSpan": 4, + "direction": 1 + } +] \ No newline at end of file diff --git a/PckStudio.Core/Resources/atlas/groups/particles_groups.json b/PckStudio.Core/Resources/atlas/groups/particles_groups.json new file mode 100644 index 00000000..123c2ea8 --- /dev/null +++ b/PckStudio.Core/Resources/atlas/groups/particles_groups.json @@ -0,0 +1,85 @@ +[ + { + "name": "Generic", + "row": 0, + "column": 0, + "frameCount": 8, + "frameTime": 2, + "direction": 0 + }, + { + "name": "Splash", + "row": 3, + "column": 1, + "frameCount": 4, + "frameTime": 2, + "direction": 0 + }, + { + "name": "Drip", + "row": 0, + "column": 7, + "frameCount": 3, + "frameTime": 4, + "direction": 0 + }, + { + "name": "Effect", + "row": 0, + "column": 8, + "frameCount": 8, + "frameTime": 2, + "direction": 0 + }, + { + "name": "Splash Effect", + "row": 0, + "column": 9, + "frameCount": 8, + "frameTime": 2, + "direction": 0 + }, + { + "name": "Firework Spark", + "row": 0, + "column": 10, + "frameCount": 8, + "frameTime": 2, + "direction": 0 + }, + { + "name": "Shulker/End Rod Glitter", + "row": 0, + "column": 11, + "frameCount": 8, + "frameTime": 2, + "direction": 0 + }, + { + "name": "Bedrock Edition Explosion (Unused)", + "row": 0, + "column": 12, + "frameCount": 16, + "frameTime": 1, + "direction": 0 + }, + { + "name": "Firework Flash", + "row": 4, + "column": 2, + "rowSpan": 4, + "columnSpan": 4, + "direction": 0, + "allowCustomColor": true + }, + { + "name": "Bubble Pop (Unused)", + "row": 6, + "column": 6, + "frameCount": 5, + "rowSpan": 2, + "columnSpan": 2, + "frameTime": 2, + "direction": 0 + } +] \ No newline at end of file diff --git a/PckStudio.Core/Resources/atlas/groups/terrain_groups.json b/PckStudio.Core/Resources/atlas/groups/terrain_groups.json new file mode 100644 index 00000000..c724c356 --- /dev/null +++ b/PckStudio.Core/Resources/atlas/groups/terrain_groups.json @@ -0,0 +1,146 @@ +[ + { + "name": "Oak Door", + "row": 1, + "column": 5, + "rowSpan": 1, + "columnSpan": 2, + "direction": 1 + }, + { + "name": "Iron Door", + "row": 2, + "column": 5, + "rowSpan": 1, + "columnSpan": 2, + "direction": 1 + }, + { + "name": "Acacia Door", + "row": 0, + "column": 23, + "rowSpan": 1, + "columnSpan": 2, + "direction": 1 + }, + { + "name": "Birch Door", + "row": 1, + "column": 23, + "rowSpan": 1, + "columnSpan": 2, + "direction": 1 + }, + { + "name": "Dark Oak Door", + "row": 2, + "column": 23, + "rowSpan": 1, + "columnSpan": 2, + "direction": 1 + }, + { + "name": "Jungle Door", + "row": 3, + "column": 23, + "rowSpan": 1, + "columnSpan": 2, + "direction": 1 + }, + { + "name": "Spruce Door", + "row": 4, + "column": 23, + "rowSpan": 1, + "columnSpan": 2, + "direction": 1 + }, + { + "name": "Large Fern", + "row": 0, + "column": 20, + "rowSpan": 1, + "columnSpan": 2, + "direction": 1 + }, + { + "name": "Double Tall Grass", + "row": 1, + "column": 20, + "rowSpan": 1, + "columnSpan": 2, + "direction": 1 + }, + { + "name": "Poeny", + "row": 2, + "column": 20, + "rowSpan": 1, + "columnSpan": 2, + "direction": 1 + }, + { + "name": "Rose Bush", + "row": 3, + "column": 20, + "rowSpan": 1, + "columnSpan": 2, + "direction": 1 + }, + { + "name": "Lilac", + "row": 4, + "column": 20, + "rowSpan": 1, + "columnSpan": 2, + "direction": 1 + }, + { + "name": "Wheat", + "row": 8, + "column": 5, + "frameCount": 8, + "frameTime": 5, + "direction": 0 + }, + { + "name": "Potatoes", + "row": 9, + "column": 16, + "frameCount": 4, + "frameTime": 9, + "direction": 0 + }, + { + "name": "Carrots", + "row": 8, + "column": 12, + "frameCount": 4, + "frameTime": 9, + "direction": 0 + }, + { + "name": "Beetroots", + "row": 0, + "column": 25, + "frameCount": 4, + "frameTime": 9, + "direction": 0 + }, + { + "name": "Nether Wart", + "row": 2, + "column": 14, + "frameCount": 3, + "frameTime": 10, + "direction": 0 + }, + { + "name": "Destroy", + "row": 0, + "column": 15, + "frameCount": 10, + "frameTime": 3, + "direction": 0 + } +] \ No newline at end of file diff --git a/PckStudio.Core/Resources/atlas/itemData.json b/PckStudio.Core/Resources/atlas/itemData.json index d288fdf1..66035812 100644 --- a/PckStudio.Core/Resources/atlas/itemData.json +++ b/PckStudio.Core/Resources/atlas/itemData.json @@ -6,11 +6,7 @@ "internalName": "helmetCloth", "displayName": "Leather Cap", "allowCustomColour": true, - "hasColourEntry": true, - "colourEntry": { - "defaultName": "Armour_Default_Leather_Colour", - "variants": [ "Armour_Default_Leather_Colour" ] - } + "colorKey": "Armour_Default_Leather_Colour" }, { "internalName": "helmetChain", @@ -76,11 +72,7 @@ "internalName": "chestplateCloth", "displayName": "Leather Tunic", "allowCustomColour": true, - "hasColourEntry": true, - "colourEntry": { - "defaultName": "Armour_Default_Leather_Colour", - "variants": [ "Armour_Default_Leather_Colour" ] - } + "colorKey": "Armour_Default_Leather_Colour" }, { "internalName": "chestplateChain", @@ -146,11 +138,7 @@ "internalName": "leggingsCloth", "displayName": "Leather Pants", "allowCustomColour": true, - "hasColourEntry": true, - "colourEntry": { - "defaultName": "Armour_Default_Leather_Colour", - "variants": [ "Armour_Default_Leather_Colour" ] - } + "colorKey": "Armour_Default_Leather_Colour" }, { "internalName": "leggingsChain", @@ -216,11 +204,7 @@ "internalName": "bootsCloth", "displayName": "Leather Boots", "allowCustomColour": true, - "hasColourEntry": true, - "colourEntry": { - "defaultName": "Armour_Default_Leather_Colour", - "variants": [ "Armour_Default_Leather_Colour" ] - } + "colorKey": "Armour_Default_Leather_Colour" }, { "internalName": "bootsChain", @@ -594,41 +578,7 @@ "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" - ] - } + "colorKey": "Potion_Effect" }, { "internalName": "dyePowder_blue", @@ -677,63 +627,7 @@ { "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" - ] - } + "colorKey": "SpawnEggBaseColor" }, { "internalName": "potion_splash", @@ -798,89 +692,12 @@ { "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" - ] - } + "colorKey": "SpawnEggOverlayColor" }, { "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" - ] - } + "colorKey": "Bed_Color" }, { "internalName": "expBottle", @@ -1095,11 +912,7 @@ "internalName": "leather_horse_armor_base", "displayName": "Leather Horse Armor", "allowCustomColour": true, - "hasColourEntry": true, - "colourEntry": { - "defaultName": "Armour_Default_Leather_Colour", - "variants": [ "Armour_Default_Leather_Colour" ] - } + "colorKey": "Armour_Default_Leather_Colour" }, { "internalName": "structure_void", diff --git a/PckStudio.Core/Resources/atlas/paintingData.json b/PckStudio.Core/Resources/atlas/paintingData.json index 5b5b0ef9..741c8302 100644 --- a/PckStudio.Core/Resources/atlas/paintingData.json +++ b/PckStudio.Core/Resources/atlas/paintingData.json @@ -51,21 +51,19 @@ }, { "internalName": "Back", - "displayName": "Back Texture", - "width": 4, - "height": 4 + "displayName": "Back Texture" }, { "internalName": "Back", - "displayName": "", + "displayName": "" }, { "internalName": "Back", - "displayName": "", + "displayName": "" }, { "internalName": "Back", - "displayName": "", + "displayName": "" }, { "internalName": "1x1E1", @@ -121,20 +119,19 @@ }, { "internalName": "Back", - "displayName": "", + "displayName": "" }, { "internalName": "Back", - "displayName": "", + "displayName": "" }, { "internalName": "Back", - "displayName": "", + "displayName": "" }, { "internalName": "Pool", - "displayName": "\"The Pool\" by Kristoffer Zetterstrand", - "width": 2 + "displayName": "\"The Pool\" by Kristoffer Zetterstrand" }, { "internalName": "Pool", @@ -142,8 +139,7 @@ }, { "internalName": "Courbet", - "displayName": "\"Bonjour Monsieur Courbet\" by Kristoffer Zetterstrand", - "width": 2 + "displayName": "\"Bonjour Monsieur Courbet\" by Kristoffer Zetterstrand" }, { "internalName": "Courbet", @@ -151,8 +147,7 @@ }, { "internalName": "Sea", - "displayName": "\"Seaside\" by Kristoffer Zetterstrand", - "width": 2 + "displayName": "\"Seaside\" by Kristoffer Zetterstrand" }, { "internalName": "Sea", @@ -160,8 +155,7 @@ }, { "internalName": "Sunset", - "displayName": "\"sunset_dense\" by Kristoffer Zetterstrand", - "width": 2 + "displayName": "\"sunset_dense\" by Kristoffer Zetterstrand" }, { "internalName": "Sunset", @@ -169,8 +163,7 @@ }, { "internalName": "Creebet", - "displayName": "\"Creebet\" by Kristoffer Zetterstrand", - "width": 2 + "displayName": "\"Creebet\" by Kristoffer Zetterstrand" }, { "internalName": "Creebet", @@ -190,15 +183,15 @@ }, { "internalName": "Back", - "displayName": "", + "displayName": "" }, { "internalName": "Back", - "displayName": "", + "displayName": "" }, { "internalName": "Back", - "displayName": "", + "displayName": "" }, { "internalName": "", @@ -254,25 +247,23 @@ }, { "internalName": "Back", - "displayName": "", + "displayName": "" }, { "internalName": "Back", - "displayName": "", + "displayName": "" }, { "internalName": "Back", - "displayName": "", + "displayName": "" }, { "internalName": "Wanderer", - "displayName": "\"Wanderer\" by Kristoffer Zetterstrand", - "height": 2 + "displayName": "\"Wanderer\" by Kristoffer Zetterstrand" }, { "internalName": "Graham", - "displayName": "\"Graham\" by Kristoffer Zetterstrand", - "height": 2 + "displayName": "\"Graham\" by Kristoffer Zetterstrand" }, { "internalName": "", @@ -316,21 +307,19 @@ }, { "internalName": "Skeleton", - "displayName": "\"Mortal Coil\" by Kristoffer Zetterstrand", - "width": 4, - "height": 3 + "displayName": "\"Mortal Coil\" by Kristoffer Zetterstrand" }, { "internalName": "Skeleton", - "displayName": "", + "displayName": "" }, { "internalName": "Skeleton", - "displayName": "", + "displayName": "" }, { "internalName": "Skeleton", - "displayName": "", + "displayName": "" }, { "internalName": "Wanderer", @@ -382,25 +371,23 @@ }, { "internalName": "Skeleton", - "displayName": "", + "displayName": "" }, { "internalName": "Skeleton", - "displayName": "", + "displayName": "" }, { "internalName": "Skeleton", - "displayName": "", + "displayName": "" }, { "internalName": "Skeleton", - "displayName": "", + "displayName": "" }, { "internalName": "Fighters", - "displayName": "\"Fighters\" by Kristoffer Zetterstrand", - "width": 4, - "height": 2 + "displayName": "\"Fighters\" by Kristoffer Zetterstrand" }, { "internalName": "Fighters", @@ -512,9 +499,7 @@ }, { "internalName": "DonkeyKong", - "displayName": "\"Kong\" by Kristoffer Zetterstrand", - "width": 4, - "height": 3 + "displayName": "\"Kong\" by Kristoffer Zetterstrand" }, { "internalName": "DonkeyKong", @@ -530,9 +515,7 @@ }, { "internalName": "Match", - "displayName": "\"Match\" by Kristoffer Zetterstrand", - "width": 2, - "height": 2 + "displayName": "\"Match\" by Kristoffer Zetterstrand" }, { "internalName": "Match", @@ -540,9 +523,7 @@ }, { "internalName": "Bust", - "displayName": "\"Bust\" by Kristoffer Zetterstrand", - "width": 2, - "height": 2 + "displayName": "\"Bust\" by Kristoffer Zetterstrand" }, { "internalName": "Bust", @@ -550,9 +531,7 @@ }, { "internalName": "Stage", - "displayName": "\"The stage is set\" by Kristoffer Zetterstrand", - "width": 2, - "height": 2 + "displayName": "\"The stage is set\" by Kristoffer Zetterstrand" }, { "internalName": "Stage", @@ -560,9 +539,7 @@ }, { "internalName": "Void", - "displayName": "\"The Void\" by Kristoffer Zetterstrand", - "width": 2, - "height": 2 + "displayName": "\"The Void\" by Kristoffer Zetterstrand" }, { "internalName": "Void", @@ -570,9 +547,7 @@ }, { "internalName": "SkullAndRoses", - "displayName": "\"Skull and Roses\" by Kristoffer Zetterstrand", - "width": 2, - "height": 2 + "displayName": "\"Skull and Roses\" by Kristoffer Zetterstrand" }, { "internalName": "SkullAndRoses", @@ -580,9 +555,7 @@ }, { "internalName": "Wither", - "displayName": "\"Wither\" by Jens Bergensten", - "width": 2, - "height": 2 + "displayName": "\"Wither\" by Jens Bergensten" }, { "internalName": "Wither", @@ -654,19 +627,19 @@ }, { "internalName": "DonkeyKong", - "displayName": "", + "displayName": "" }, { "internalName": "DonkeyKong", - "displayName": "", + "displayName": "" }, { "internalName": "DonkeyKong", - "displayName": "", + "displayName": "" }, { "internalName": "DonkeyKong", - "displayName": "", + "displayName": "" }, { "internalName": "", @@ -798,9 +771,7 @@ }, { "internalName": "Pointer", - "displayName": "\"Pointer\" by Kristoffer Zetterstrand", - "width": 4, - "height": 4 + "displayName": "\"Pointer\" by Kristoffer Zetterstrand" }, { "internalName": "Pointer", @@ -816,9 +787,7 @@ }, { "internalName": "Pigscene", - "displayName": "\"Pigscene\" by Kristoffer Zetterstrand", - "width": 4, - "height": 4 + "displayName": "\"Pigscene\" by Kristoffer Zetterstrand" }, { "internalName": "Pigscene", @@ -834,9 +803,7 @@ }, { "internalName": "BurningSkull", - "displayName": "\"Skull On Fire\" by Kristoffer Zetterstrand", - "width": 4, - "height": 4 + "displayName": "\"Skull On Fire\" by Kristoffer Zetterstrand" }, { "internalName": "BurningSkull", @@ -852,83 +819,19 @@ }, { "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": "", + "displayName": "" }, { "internalName": "", - "displayName": "", + "displayName": "" }, { "internalName": "", - "displayName": "", - }, - { - "internalName": "", - "displayName": "", + "displayName": "" }, { "internalName": "Pointer", @@ -948,7 +851,7 @@ }, { "internalName": "Pigscene", - "displayName": "", + "displayName": "" }, { "internalName": "Pigscene", @@ -964,7 +867,7 @@ }, { "internalName": "BurningSkull", - "displayName": "", + "displayName": "" }, { "internalName": "BurningSkull", @@ -980,23 +883,23 @@ }, { "internalName": "", - "displayName": "", + "displayName": "" }, { "internalName": "", - "displayName": "", + "displayName": "" }, { "internalName": "", - "displayName": "", + "displayName": "" }, { "internalName": "", - "displayName": "", + "displayName": "" }, { "internalName": "Pointer", - "displayName": "", + "displayName": "" }, { "internalName": "Pointer", @@ -1012,7 +915,7 @@ }, { "internalName": "Pigscene", - "displayName": "", + "displayName": "" }, { "internalName": "Pigscene", @@ -1028,7 +931,7 @@ }, { "internalName": "BurningSkull", - "displayName": "", + "displayName": "" }, { "internalName": "BurningSkull", @@ -1044,19 +947,83 @@ }, { "internalName": "", - "displayName": "", + "displayName": "" }, { "internalName": "", - "displayName": "", + "displayName": "" }, { "internalName": "", - "displayName": "", + "displayName": "" }, { "internalName": "", - "displayName": "", + "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/atlas/particleData.json b/PckStudio.Core/Resources/atlas/particleData.json index 924ab98a..c5549007 100644 --- a/PckStudio.Core/Resources/atlas/particleData.json +++ b/PckStudio.Core/Resources/atlas/particleData.json @@ -4,130 +4,42 @@ { "internalName": "generic_0", "displayName": "Generic (Stage 1)", - "colourEntry": { - "defaultName": "None", - "variants": [ - "None", - "Particle_Smoke", - "Particle_NetherPortal", - "Particle_EnderPortal", - "Particle_Ender", - "Particle_DragonBreathMin", - "Particle_DragonBreathMax" - ] - } + "colorKey": "Particle" }, { "internalName": "generic_1", "displayName": "Generic (Stage 2)", - "colourEntry": { - "defaultName": "None", - "variants": [ - "None", - "Particle_Smoke", - "Particle_NetherPortal", - "Particle_EnderPortal", - "Particle_Ender", - "Particle_DragonBreathMin", - "Particle_DragonBreathMax" - ] - } + "colorKey": "Particle" }, { "internalName": "generic_2", "displayName": "Generic (Stage 3)", - "colourEntry": { - "defaultName": "None", - "variants": [ - "None", - "Particle_Smoke", - "Particle_NetherPortal", - "Particle_EnderPortal", - "Particle_Ender", - "Particle_DragonBreathMin", - "Particle_DragonBreathMax" - ] - } + "colorKey": "Particle" }, { "internalName": "generic_3", "displayName": "Generic (Stage 4)", - "colourEntry": { - "defaultName": "None", - "variants": [ - "None", - "Particle_Smoke", - "Particle_NetherPortal", - "Particle_EnderPortal", - "Particle_Ender", - "Particle_DragonBreathMin", - "Particle_DragonBreathMax" - ] - } + "colorKey": "Particle" }, { "internalName": "generic_4", "displayName": "Generic (Stage 5)", - "colourEntry": { - "defaultName": "None", - "variants": [ - "None", - "Particle_Smoke", - "Particle_NetherPortal", - "Particle_EnderPortal", - "Particle_Ender", - "Particle_DragonBreathMin", - "Particle_DragonBreathMax" - ] - } + "colorKey": "Particle" }, { "internalName": "generic_5", "displayName": "Generic (Stage 6)", - "colourEntry": { - "defaultName": "None", - "variants": [ - "None", - "Particle_Smoke", - "Particle_NetherPortal", - "Particle_EnderPortal", - "Particle_Ender", - "Particle_DragonBreathMin", - "Particle_DragonBreathMax" - ] - } + "colorKey": "Particle" }, { "internalName": "generic_6", "displayName": "Generic (Stage 7)", - "colourEntry": { - "defaultName": "None", - "variants": [ - "None", - "Particle_Smoke", - "Particle_NetherPortal", - "Particle_EnderPortal", - "Particle_Ender", - "Particle_DragonBreathMin", - "Particle_DragonBreathMax" - ] - } + "colorKey": "Particle" }, { "internalName": "generic_7", "displayName": "Generic (Stage 8)", - "colourEntry": { - "defaultName": "None", - "variants": [ - "None", - "Particle_Smoke", - "Particle_NetherPortal", - "Particle_EnderPortal", - "Particle_Ender", - "Particle_DragonBreathMin", - "Particle_DragonBreathMax" - ] - } + "colorKey": "Particle" }, { "internalName": "", @@ -236,52 +148,7 @@ { "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" - ] - } + "colorKey": "Water" }, { "internalName": "", @@ -289,10 +156,7 @@ }, { "internalName": "flash", - "displayName": "Firework Flash", - "width": 4, - "height": 4, - "allowCustomColour": true + "displayName": "Firework Flash" }, { "internalName": "flash", @@ -405,56 +269,15 @@ { "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", - ] - } + "colorKey": "Particle_Note" }, { "internalName": "critical_hit", - "displayName": "Critical Hit", - "colourEntry": { - "defaultName": "critical_hit", - "variants": [ - "critical_hit" - ] - } + "displayName": "Critical Hit" }, { "internalName": "enchanted_hit", - "displayName": "Enchanted Hit", - "colourEntry": { - "defaultName": "critical_hit", - "variants": [ - "critical_hit" - ] - } + "displayName": "Enchanted Hit" }, { "internalName": "damage", @@ -598,9 +421,7 @@ }, { "internalName": "bubble_pop_0", - "displayName": "Bubble Pop (Stage 1) (Unused)", - "width": 2, - "height": 2 + "displayName": "Bubble Pop (Stage 1) (Unused)" }, { "internalName": "bubble_pop_0", @@ -608,9 +429,7 @@ }, { "internalName": "bubble_pop_1", - "displayName": "Bubble Pop (Stage 2) (Unused)", - "width": 2, - "height": 2 + "displayName": "Bubble Pop (Stage 2) (Unused)" }, { "internalName": "bubble_pop_1", @@ -618,9 +437,7 @@ }, { "internalName": "bubble_pop_2", - "displayName": "Bubble Pop (Stage 3) (Unused)", - "width": 2, - "height": 2 + "displayName": "Bubble Pop (Stage 3) (Unused)" }, { "internalName": "bubble_pop_2", @@ -628,9 +445,7 @@ }, { "internalName": "bubble_pop_3", - "displayName": "Bubble Pop (Stage 4) (Unused)", - "width": 2, - "height": 2 + "displayName": "Bubble Pop (Stage 4) (Unused)" }, { "internalName": "bubble_pop_3", @@ -638,9 +453,7 @@ }, { "internalName": "bubble_pop_4", - "displayName": "Bubble Pop (Stage 5) (Unused)", - "width": 2, - "height": 2 + "displayName": "Bubble Pop (Stage 5) (Unused)" }, { "internalName": "bubble_pop_4", @@ -649,39 +462,17 @@ { "internalName": "drip_hang", "displayName": "Drip (Hang)", - - "colourEntry": { - "defaultName": "Particle_DripWater", - "variants": [ - "Particle_DripWater", - "Particle_DripLavaStart", - "Particle_DripLavaEnd" - ] - } + "colorKey": "Particle_Drip" }, { "internalName": "drip_fall", "displayName": "Drip (Fall)", - "colourEntry": { - "defaultName": "Particle_DripWater", - "variants": [ - "Particle_DripWater", - "Particle_DripLavaStart", - "Particle_DripLavaEnd" - ] - } + "colorKey": "Particle_Drip" }, { "internalName": "drip_land", "displayName": "Drip (Land)", - "colourEntry": { - "defaultName": "Particle_DripWater", - "variants": [ - "Particle_DripWater", - "Particle_DripLavaStart", - "Particle_DripLavaEnd" - ] - } + "colorKey": "Particle_Drip" }, { "internalName": "", @@ -738,322 +529,50 @@ { "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" - ] - } + "colorKey": "Potion_Effect" }, { "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" - ] - } + "colorKey": "Potion_Effect" }, { "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" - ] - } + "colorKey": "Potion_Effect" }, { "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" - ] - } + "colorKey": "Potion_Effect" }, { "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" - ] - } + "colorKey": "Potion_Effect" }, { "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" - ] - } + "colorKey": "Potion_Effect" }, { "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" - ] - } + "colorKey": "Potion_Effect" }, { "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" - ] - } + "colorKey": "Potion_Effect" }, { "internalName": "", @@ -1091,321 +610,49 @@ "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" - ] - } + "colorKey": "Potion_Effect" }, { "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" - ] - } + "colorKey": "Potion_Effect" }, { "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" - ] - } + "colorKey": "Potion_Effect" }, { "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" - ] - } + "colorKey": "Potion_Effect" }, { "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" - ] - } + "colorKey": "Potion_Effect" }, { "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" - ] - } + "colorKey": "Potion_Effect" }, { "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" - ] - } + "colorKey": "Potion_Effect" }, { "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" - ] - } + "colorKey": "Potion_Effect" }, { "internalName": "", @@ -1443,121 +690,49 @@ "internalName": "spark_0", "displayName": "Firework Spark (Stage 1)", "allowCustomColour": true, - - "colourEntry": { - "defaultName": "None", - "variants": [ - "None", - "Particle_ScoreRing_Small", - "Particle_ScoreRing_Medium", - "Particle_ScoreRing_Large" - ] - } + "colorKey": "Particle_ScoreRing" }, { "internalName": "spark_1", "displayName": "Firework Spark (Stage 2)", "allowCustomColour": true, - - "colourEntry": { - "defaultName": "None", - "variants": [ - "None", - "Particle_ScoreRing_Small", - "Particle_ScoreRing_Medium", - "Particle_ScoreRing_Large" - ] - } + "colorKey": "Particle_ScoreRing" }, { "internalName": "spark_2", "displayName": "Firework Spark (Stage 3)", "allowCustomColour": true, - - "colourEntry": { - "defaultName": "None", - "variants": [ - "None", - "Particle_ScoreRing_Small", - "Particle_ScoreRing_Medium", - "Particle_ScoreRing_Large" - ] - } + "colorKey": "Particle_ScoreRing" }, { "internalName": "spark_3", "displayName": "Firework Spark (Stage 4)", "allowCustomColour": true, - - "colourEntry": { - "defaultName": "None", - "variants": [ - "None", - "Particle_ScoreRing_Small", - "Particle_ScoreRing_Medium", - "Particle_ScoreRing_Large" - ] - } + "colorKey": "Particle_ScoreRing" }, { "internalName": "spark_4", "displayName": "Firework Spark (Stage 5)", "allowCustomColour": true, - - "colourEntry": { - "defaultName": "None", - "variants": [ - "None", - "Particle_ScoreRing_Small", - "Particle_ScoreRing_Medium", - "Particle_ScoreRing_Large" - ] - } + "colorKey": "Particle_ScoreRing" }, { "internalName": "spark_5", "displayName": "Firework Spark (Stage 6)", "allowCustomColour": true, - - "colourEntry": { - "defaultName": "None", - "variants": [ - "None", - "Particle_ScoreRing_Small", - "Particle_ScoreRing_Medium", - "Particle_ScoreRing_Large" - ] - } + "colorKey": "Particle_ScoreRing" }, { "internalName": "spark_6", "displayName": "Firework Spark (Stage 7)", "allowCustomColour": true, - - "colourEntry": { - "defaultName": "None", - "variants": [ - "None", - "Particle_ScoreRing_Small", - "Particle_ScoreRing_Medium", - "Particle_ScoreRing_Large" - ] - } + "colorKey": "Particle_ScoreRing" }, { "internalName": "spark_7", "displayName": "Firework Spark (Stage 8)", "allowCustomColour": true, - - "colourEntry": { - "defaultName": "None", - "variants": [ - "None", - "Particle_ScoreRing_Small", - "Particle_ScoreRing_Medium", - "Particle_ScoreRing_Large" - ] - } + "colorKey": "Particle_ScoreRing" }, { "internalName": "", @@ -1790,288 +965,132 @@ { "internalName": "sga_a", "displayName": "Standard Galactic Language (A)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_b", "displayName": "Standard Galactic Language (B)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_c", "displayName": "Standard Galactic Language (C)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_d", "displayName": "Standard Galactic Language (D)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_e", "displayName": "Standard Galactic Language (E)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_f", "displayName": "Standard Galactic Language (F)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_g", "displayName": "Standard Galactic Language (G)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_h", "displayName": "Standard Galactic Language (H)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_i", "displayName": "Standard Galactic Language (I)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_j", "displayName": "Standard Galactic Language (J)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_k", "displayName": "Standard Galactic Language (K)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_l", "displayName": "Standard Galactic Language (L)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_m", "displayName": "Standard Galactic Language (M)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_n", "displayName": "Standard Galactic Language (N)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_o", "displayName": "Standard Galactic Language (O)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_p", "displayName": "Standard Galactic Language (P)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_q", "displayName": "Standard Galactic Language (Q)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_r", "displayName": "Standard Galactic Language (R)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_s", "displayName": "Standard Galactic Language (S)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_t", "displayName": "Standard Galactic Language (T)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_u", "displayName": "Standard Galactic Language (U)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_v", "displayName": "Standard Galactic Language (V)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_w", "displayName": "Standard Galactic Language (W)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_x", "displayName": "Standard Galactic Language (X)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_y", "displayName": "Standard Galactic Language (Y)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "sga_z", "displayName": "Standard Galactic Language (Z)", - - "colourEntry": { - "defaultName": "Particle_EnchantmentTable", - "variants": [ - "Particle_EnchantmentTable" - ] - } + "colorKey": "Particle_EnchantmentTable" }, { "internalName": "", @@ -2092,6 +1111,6 @@ { "internalName": "", "displayName": "" - }, + } ] } \ No newline at end of file diff --git a/PckStudio.Core/Resources/atlas/terrain.png b/PckStudio.Core/Resources/atlas/terrain.png index 9b6d1791..bfdc63b5 100644 Binary files a/PckStudio.Core/Resources/atlas/terrain.png and b/PckStudio.Core/Resources/atlas/terrain.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/clouds.png b/PckStudio.Core/Resources/clouds.png new file mode 100644 index 00000000..b4a78c2f Binary files /dev/null and b/PckStudio.Core/Resources/clouds.png differ diff --git a/PckStudio.ModelSupport/Resources/defaultModels.json b/PckStudio.Core/Resources/defaultModels.json similarity index 100% rename from PckStudio.ModelSupport/Resources/defaultModels.json rename to PckStudio.Core/Resources/defaultModels.json 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/modelMetaData.json b/PckStudio.Core/Resources/modelMetaData.json new file mode 100644 index 00000000..578e9d37 --- /dev/null +++ b/PckStudio.Core/Resources/modelMetaData.json @@ -0,0 +1,787 @@ +{ + "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" + ], + "textureAspectRatio": 0.5, + "layers": [ + { + "name": "overlay", + "uv": {"X": 0, "Y": 0}, + "allowedColors": + [ + "Bed_White", + "Bed_Silver", + "Bed_Grey", + "Bed_Black", + "Bed_Blue", + "Bed_Brown", + "Bed_Cyan", + "Bed_Green", + "Bed_Light_Blue", + "Bed_Lime", + "Bed_Magenta", + "Bed_Orange", + "Bed_Pink", + "Bed_Purple", + "Bed_Red", + "Bed_Yellow" + ] + }, + { + "name": "base", + "uv": {"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", "required": false }, + { "name": "neck2", "required": false }, + { "name": "neck3", "required": false }, + { "name": "neck4", "required": false }, + { "name": "neck5", "required": false }, + + { "name": "tail1", "required": false }, + { "name": "tail2", "required": false }, + { "name": "tail3", "required": false }, + { "name": "tail4", "required": false }, + { "name": "tail5", "required": false }, + { "name": "tail6", "required": false }, + { "name": "tail7", "required": false }, + { "name": "tail8", "required": false }, + { "name": "tail9", "required": false }, + { "name": "tail10", "required": false }, + { "name": "tail11", "required": false }, + { "name": "tail12", "required": false }, + + { + "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" + ] + }, + + "wood": { + "textureLocations": [ "res/item/armorstand/wood" ], + "parts": [ + { "name": "head" }, + { "name": "body" }, + { + "name": "rightArm", + "children": [{ "name": "rightItem" }] + }, + { + "name": "leftArm", + "children": [{ "name": "leftItem" }] + }, + { "name": "rightLeg" }, + { "name": "leftLeg" }, + { "name": "base_plate" } + ] + } +} 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/rain.png b/PckStudio.Core/Resources/rain.png new file mode 100644 index 00000000..75d775b1 Binary files /dev/null and b/PckStudio.Core/Resources/rain.png differ diff --git a/PckStudio.Core/Resources/snow.png b/PckStudio.Core/Resources/snow.png new file mode 100644 index 00000000..84417c5c Binary files /dev/null and b/PckStudio.Core/Resources/snow.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.Core/Skin/SkinBOX.cs b/PckStudio.Core/Skin/SkinBOX.cs index ce1417ae..ea1f32c6 100644 --- a/PckStudio.Core/Skin/SkinBOX.cs +++ b/PckStudio.Core/Skin/SkinBOX.cs @@ -25,7 +25,7 @@ using PckStudio.Core.Extensions; namespace PckStudio.Core.Skin { - public record SkinBOX : IEquatable + public class SkinBOX : Box { public static readonly SkinBOX DefaultHead = new SkinBOX("HEAD", new Vector3(-4, -8, -4), new Vector3(8), Vector2.Zero); public static readonly SkinBOX Empty = new SkinBOX("", Vector3.Zero, Vector3.Zero, Vector2.Zero); @@ -89,12 +89,7 @@ namespace PckStudio.Core.Skin public static readonly string[] ValidBoxTypes = BaseTypes.Concat(OverlayTypes).ToArray(); public string Type { get; } - public Vector3 Pos { get; } - public Vector3 Size { get; } - public Vector2 UV { get; } public BoxVisibility Visibility { get; } - public bool Mirror { get; } - public float Scale { get; } [Flags] public enum BoxVisibility : byte @@ -108,14 +103,10 @@ namespace PckStudio.Core.Skin public SkinBOX(string type, Vector3 pos, Vector3 size, Vector2 uv, BoxVisibility visibility = BoxVisibility.Always, bool mirror = false, float scale = 0.0f) + : base(pos, size, uv, scale, mirror) { Type = type; - Pos = pos; - Size = size; - UV = uv; Visibility = visibility; - Mirror = mirror; - Scale = scale; } public static SkinBOX FromString(string value) => FromString(value, false); @@ -175,7 +166,7 @@ namespace PckStudio.Core.Skin public override string ToString() { - return InvariantFormat(Type, Pos.X, Pos.Y, Pos.Z, Size.X, Size.Y, Size.Z, UV.X, UV.Y, Visibility.ToString("d"), Convert.ToInt32(Mirror), Scale); + return InvariantFormat(Type, Position.X, Position.Y, Position.Z, Size.X, Size.Y, Size.Z, Uv.X, Uv.Y, Visibility.ToString("d"), Convert.ToInt32(Mirror), Inflate); } private static Vector2 TryGetVector2(string[] arguments, int startIndex) @@ -196,12 +187,12 @@ namespace PckStudio.Core.Skin { int hashCode = -1311939065; hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(Type); - hashCode = hashCode * -1521134295 + Pos.GetHashCode(); + hashCode = hashCode * -1521134295 + Position.GetHashCode(); hashCode = hashCode * -1521134295 + Size.GetHashCode(); - hashCode = hashCode * -1521134295 + UV.GetHashCode(); + hashCode = hashCode * -1521134295 + Uv.GetHashCode(); hashCode = hashCode * -1521134295 + Visibility.GetHashCode(); hashCode = hashCode * -1521134295 + Mirror.GetHashCode(); - hashCode = hashCode * -1521134295 + Scale.GetHashCode(); + hashCode = hashCode * -1521134295 + Inflate.GetHashCode(); return hashCode; } } diff --git a/PckStudio.Core/Skin/SkinIdentifier.cs b/PckStudio.Core/Skin/SkinIdentifier.cs index cec8e9aa..b7fba1ee 100644 --- a/PckStudio.Core/Skin/SkinIdentifier.cs +++ b/PckStudio.Core/Skin/SkinIdentifier.cs @@ -5,19 +5,19 @@ namespace PckStudio.Core.Skin { public sealed class SkinIdentifier : IFormattable { - public int Id { get; } + private readonly int _id; public SkinIdentifier(int id) { - Id = id; + _id = id; } - public static implicit operator int(SkinIdentifier _this) => _this.Id; + public static implicit operator int(SkinIdentifier @this) => @this._id; - public string ToString(string format, IFormatProvider formatProvider) => Id.ToString(format, formatProvider); + public string ToString(string format, IFormatProvider formatProvider) => _id.ToString(format, formatProvider); - public string ToString(string format) => Id.ToString(format, NumberFormatInfo.CurrentInfo); + public string ToString(string format) => _id.ToString(format, NumberFormatInfo.CurrentInfo); - public override string ToString() => Id.ToString(NumberFormatInfo.CurrentInfo); + public override string ToString() => _id.ToString(NumberFormatInfo.CurrentInfo); } } diff --git a/PckStudio.Core/Skin/SkinPartOffset.cs b/PckStudio.Core/Skin/SkinPartOffset.cs index ccdc3eab..8482ab8d 100644 --- a/PckStudio.Core/Skin/SkinPartOffset.cs +++ b/PckStudio.Core/Skin/SkinPartOffset.cs @@ -53,7 +53,10 @@ namespace PckStudio.Core.Skin { string[] offset = ReplaceWhitespace(offsetFormatString.TrimEnd('\n', '\r', ' '), ",").Split(','); if (offset.Length < 3) - throw new InvalidDataException("Format string does not contain enough data."); + { + Trace.TraceError("Format string does not contain enough data."); + return new SkinPartOffset(); + } string type = offset[0]; diff --git a/PckStudio.Core/Tiles.cs b/PckStudio.Core/Tiles.cs index c9e22301..71505b2f 100644 --- a/PckStudio.Core/Tiles.cs +++ b/PckStudio.Core/Tiles.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Drawing; using System.Linq; using System.Windows.Forms; @@ -29,6 +30,7 @@ namespace PckStudio.Json public static JsonTiles JsonPaintingData { get; } = JsonConvert.DeserializeObject(Resources.paintingData); public static JsonTiles JsonBannerData { get; } = JsonConvert.DeserializeObject(Resources.bannerData); + public static ReadOnlyDictionary ColorEntries { get; } = JsonConvert.DeserializeObject>(Resources.colorEntries); public static List ItemTileInfos => JsonItemData.Entries; public static List BlockTileInfos => JsonBlockData.Entries; public static List ParticleTileInfos => JsonParticleData.Entries; diff --git a/PckStudio.ModelSupport/Format/Internal/PSM/PSMFileWriter.cs b/PckStudio.ModelSupport/Format/Internal/PSM/PSMFileWriter.cs index cb4908c6..b617f721 100644 --- a/PckStudio.ModelSupport/Format/Internal/PSM/PSMFileWriter.cs +++ b/PckStudio.ModelSupport/Format/Internal/PSM/PSMFileWriter.cs @@ -20,7 +20,7 @@ namespace PckStudio.ModelSupport.Internal.Format public void WriteToFile(string filename) { - using(var fs = File.OpenWrite(filename)) + using (Stream fs = File.OpenWrite(filename)) { WriteToStream(fs); } @@ -53,21 +53,21 @@ namespace PckStudio.ModelSupport.Internal.Format if (_PSM.Version == 2) data |= (byte)((byte)part.Visibility << 4); writer.Write(data); - writer.Write(part.Pos.X); - writer.Write(part.Pos.Y); - writer.Write(part.Pos.Z); + writer.Write(part.Position.X); + writer.Write(part.Position.Y); + writer.Write(part.Position.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 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.Visibility & SkinBOX.BoxVisibility.HideWhenWearingHelmet) != 0) << 7 | uvY); writer.Write(mirrorAndUvX); writer.Write(_PSM.Version == 1 ? hideWithArmorAndUvY : uvY); - writer.Write(part.Scale); + writer.Write(part.Inflate); } private static PSMParentType GetParentPart(string type) diff --git a/PckStudio.ModelSupport/GameModelImporter.cs b/PckStudio.ModelSupport/GameModelImporter.cs index 5730d551..53954944 100644 --- a/PckStudio.ModelSupport/GameModelImporter.cs +++ b/PckStudio.ModelSupport/GameModelImporter.cs @@ -29,12 +29,12 @@ using Newtonsoft.Json.Linq; using OMI.Formats.Model; -using PckStudio.Core.Json; +using PckStudio.Core.Properties; using PckStudio.Core.Extensions; using PckStudio.Core; using PckStudio.ModelSupport.Format.External; -using PckStuido.ModelSupport.Properties; using NamedTexture = PckStudio.Core.NamedData; +using PckStudio.Core.Json; namespace PckStudio.ModelSupport { diff --git a/PckStudio.ModelSupport/PckStudio.ModelSupport.csproj b/PckStudio.ModelSupport/PckStudio.ModelSupport.csproj index d7697c87..9f8636d2 100644 --- a/PckStudio.ModelSupport/PckStudio.ModelSupport.csproj +++ b/PckStudio.ModelSupport/PckStudio.ModelSupport.csproj @@ -54,8 +54,6 @@ - - @@ -88,9 +86,5 @@ Designer - - - - \ No newline at end of file diff --git a/PckStudio.ModelSupport/Properties/Resources.Designer.cs b/PckStudio.ModelSupport/Properties/Resources.Designer.cs index b98cf665..cde2fbe8 100644 --- a/PckStudio.ModelSupport/Properties/Resources.Designer.cs +++ b/PckStudio.ModelSupport/Properties/Resources.Designer.cs @@ -59,62 +59,5 @@ namespace PckStuido.ModelSupport.Properties { 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/PckStudio.ModelSupport/Properties/Resources.resx b/PckStudio.ModelSupport/Properties/Resources.resx index b1909c61..1af7de15 100644 --- a/PckStudio.ModelSupport/Properties/Resources.resx +++ b/PckStudio.ModelSupport/Properties/Resources.resx @@ -117,11 +117,4 @@ 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/PckStudio.ModelSupport/SkinModelImporter.cs b/PckStudio.ModelSupport/SkinModelImporter.cs index 8104478e..40107ff9 100644 --- a/PckStudio.ModelSupport/SkinModelImporter.cs +++ b/PckStudio.ModelSupport/SkinModelImporter.cs @@ -116,7 +116,7 @@ namespace PckStudio.ModelSupport 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.Visibility, box.Mirror, box.Scale); + return string.IsNullOrEmpty(offset.Type) ? box : new SkinBOX(box.Type, box.Position - (Vector3.UnitY * offset.Value), box.Size, box.Uv, box.Visibility, box.Mirror, box.Inflate); } IEnumerable convertedBoxes = boxes.Select(ApplyOffset); @@ -221,7 +221,7 @@ namespace PckStudio.ModelSupport 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); + Element element = CreateElement(box.Uv, transformPos, box.Size, box.Inflate, box.Mirror); if (box.IsOverlayPart()) element.Inflate = box.Type == "HEADWEAR" ? 0.5f : 0.25f; return element; @@ -343,8 +343,8 @@ namespace PckStudio.ModelSupport { Origin = pos + offset, Size = box.Size, - Uv = box.UV, - Inflate = box.Scale + (box.IsOverlayPart() ? box.Type == "HEAD" ? 0.5f : 0.25f : 0f), + Uv = box.Uv, + Inflate = box.Inflate + (box.IsOverlayPart() ? box.Type == "HEAD" ? 0.5f : 0.25f : 0f), Mirror = box.Mirror, }); } @@ -502,7 +502,7 @@ namespace PckStudio.ModelSupport { 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 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); @@ -547,7 +547,7 @@ namespace PckStudio.ModelSupport private static Vector3 TranslateFromInternalPosistion(SkinBOX skinBox, Vector3 translationUnit) { - return TranslateToInternalPosition(skinBox.Type, skinBox.Pos, skinBox.Size, translationUnit); + return TranslateToInternalPosition(skinBox.Type, skinBox.Position, skinBox.Size, translationUnit); } } } diff --git a/PckStudio.Rendering/Extension/SkinBoxExtension.cs b/PckStudio.Rendering/Extension/SkinBoxExtension.cs index 6a8675bf..92a415ec 100644 --- a/PckStudio.Rendering/Extension/SkinBoxExtension.cs +++ b/PckStudio.Rendering/Extension/SkinBoxExtension.cs @@ -13,6 +13,6 @@ namespace PckStudio.Rendering.Extension public static Cube ToCube(this SkinBOX skinBOX) => skinBOX.ToCube(0f); public static Cube ToCube(this SkinBOX skinBOX, float inflate, bool flipZMapping = false) - => new Cube(skinBOX.Pos.ToOpenTKVector(), skinBOX.Size.ToOpenTKVector(), skinBOX.UV.ToOpenTKVector(), skinBOX.Scale + inflate, skinBOX.Mirror, flipZMapping); + => new Cube(skinBOX.Position.ToOpenTKVector(), skinBOX.Size.ToOpenTKVector(), skinBOX.Uv.ToOpenTKVector(), skinBOX.Inflate + inflate, skinBOX.Mirror, flipZMapping); } } 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/PckStudio.ModelSupport/Json/JsonDefaultModel.cs b/PckStuido.ModelSupport/Json/JsonDefaultModel.cs similarity index 97% rename from PckStudio.ModelSupport/Json/JsonDefaultModel.cs rename to PckStuido.ModelSupport/Json/JsonDefaultModel.cs index 59c4a329..2fb3aadc 100644 --- a/PckStudio.ModelSupport/Json/JsonDefaultModel.cs +++ b/PckStuido.ModelSupport/Json/JsonDefaultModel.cs @@ -2,7 +2,7 @@ using System.Numerics; using Newtonsoft.Json; -namespace PckStudio.ModelSupport +namespace PckStudio.Core.Json { public class DefaultModel { diff --git a/PckStudio.ModelSupport/Json/JsonModelMetaData.cs b/PckStuido.ModelSupport/Json/JsonModelMetaData.cs similarity index 97% rename from PckStudio.ModelSupport/Json/JsonModelMetaData.cs rename to PckStuido.ModelSupport/Json/JsonModelMetaData.cs index 9d503462..d274cfb3 100644 --- a/PckStudio.ModelSupport/Json/JsonModelMetaData.cs +++ b/PckStuido.ModelSupport/Json/JsonModelMetaData.cs @@ -2,7 +2,7 @@ using System.Numerics; using Newtonsoft.Json; -namespace PckStudio.ModelSupport +namespace PckStudio.Core.Json { public class ModelMetaDataPart { 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/PckStudio.ModelSupport/Resources/modelMetaData.json b/PckStuido.ModelSupport/Resources/modelMetaData.json similarity index 97% rename from PckStudio.ModelSupport/Resources/modelMetaData.json rename to PckStuido.ModelSupport/Resources/modelMetaData.json index e2d75dda..9be05f36 100644 --- a/PckStudio.ModelSupport/Resources/modelMetaData.json +++ b/PckStuido.ModelSupport/Resources/modelMetaData.json @@ -735,30 +735,5 @@ "res/mob/panda/panda_sneezy", "res/mob/panda/panda_worried" ] - }, - - "wood": { - "textureLocations": [ "res/item/armorstand/wood" ], - "parts": [ - { "name": "head" }, - { "name": "body" }, - { - "name": "rightArm", - "children": [{ "name": "rightItem" }] - }, - { - "name": "leftArm", - "children": [{ "name": "leftItem" }] - }, - { - "name": "rightLeg" - }, - { - "name": "leftLeg" - }, - { - "name": "base_plate" - } - ] } } 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