diff --git a/PCK-Studio/Forms/Editor/ModelsEditor.Designer.cs b/PCK-Studio/Forms/Editor/ModelsEditor.Designer.cs new file mode 100644 index 00000000..71ac46d7 --- /dev/null +++ b/PCK-Studio/Forms/Editor/ModelsEditor.Designer.cs @@ -0,0 +1,181 @@ +namespace PckStudio.Forms.Editor +{ + partial class ModelsEditor + { + /// + /// 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 Windows Form 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.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ModelsEditor)); + this.treeView1 = new System.Windows.Forms.TreeView(); + this.metroContextMenu1 = new MetroFramework.Controls.MetroContextMenu(this.components); + this.addToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.addNewEntryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.addNewPositionOverrideToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.renameToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.removeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.menuStrip = new System.Windows.Forms.MenuStrip(); + this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.saveToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.metroContextMenu1.SuspendLayout(); + this.menuStrip.SuspendLayout(); + this.SuspendLayout(); + // + // treeView1 + // + this.treeView1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.treeView1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64))))); + this.treeView1.ContextMenuStrip = this.metroContextMenu1; + this.treeView1.ForeColor = System.Drawing.Color.White; + this.treeView1.Location = new System.Drawing.Point(20, 84); + this.treeView1.Margin = new System.Windows.Forms.Padding(0); + this.treeView1.Name = "treeView1"; + this.treeView1.Size = new System.Drawing.Size(186, 176); + this.treeView1.TabIndex = 13; + this.treeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterSelect); + this.treeView1.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.treeView1_NodeMouseClick); + this.treeView1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.treeView1_KeyDown); + this.treeView1.MouseHover += new System.EventHandler(this.treeView1_MouseHover); + // + // metroContextMenu1 + // + this.metroContextMenu1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.addToolStripMenuItem, + this.renameToolStripMenuItem, + this.removeToolStripMenuItem}); + this.metroContextMenu1.Name = "metroContextMenu1"; + this.metroContextMenu1.Size = new System.Drawing.Size(118, 70); + // + // addToolStripMenuItem + // + this.addToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.addNewEntryToolStripMenuItem, + this.addNewPositionOverrideToolStripMenuItem}); + this.addToolStripMenuItem.Name = "addToolStripMenuItem"; + this.addToolStripMenuItem.Size = new System.Drawing.Size(117, 22); + this.addToolStripMenuItem.Text = "Add"; + // + // addNewEntryToolStripMenuItem + // + this.addNewEntryToolStripMenuItem.Name = "addNewEntryToolStripMenuItem"; + this.addNewEntryToolStripMenuItem.Size = new System.Drawing.Size(217, 22); + this.addNewEntryToolStripMenuItem.Text = "Add New Entry"; + this.addNewEntryToolStripMenuItem.Click += new System.EventHandler(this.addNewEntryToolStripMenuItem_Click); + // + // addNewPositionOverrideToolStripMenuItem + // + this.addNewPositionOverrideToolStripMenuItem.Name = "addNewPositionOverrideToolStripMenuItem"; + this.addNewPositionOverrideToolStripMenuItem.Size = new System.Drawing.Size(217, 22); + this.addNewPositionOverrideToolStripMenuItem.Text = "Add New Position Override"; + this.addNewPositionOverrideToolStripMenuItem.Click += new System.EventHandler(this.addNewPositionOverrideToolStripMenuItem_Click); + // + // renameToolStripMenuItem + // + this.renameToolStripMenuItem.Name = "renameToolStripMenuItem"; + this.renameToolStripMenuItem.Size = new System.Drawing.Size(117, 22); + this.renameToolStripMenuItem.Text = "Change"; + this.renameToolStripMenuItem.Click += new System.EventHandler(this.changeToolStripMenuItem_Click); + // + // removeToolStripMenuItem + // + this.removeToolStripMenuItem.Name = "removeToolStripMenuItem"; + this.removeToolStripMenuItem.Size = new System.Drawing.Size(117, 22); + this.removeToolStripMenuItem.Text = "Remove"; + this.removeToolStripMenuItem.Click += new System.EventHandler(this.removeToolStripMenuItem_Click); + // + // menuStrip + // + this.menuStrip.AutoSize = false; + 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.helpToolStripMenuItem}); + this.menuStrip.Location = new System.Drawing.Point(20, 60); + this.menuStrip.Name = "menuStrip"; + this.menuStrip.Size = new System.Drawing.Size(309, 24); + this.menuStrip.TabIndex = 14; + this.menuStrip.Text = "menuStrip1"; + // + // fileToolStripMenuItem + // + this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.saveToolStripMenuItem1}); + this.fileToolStripMenuItem.ForeColor = System.Drawing.Color.White; + this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; + this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); + this.fileToolStripMenuItem.Text = "File"; + // + // saveToolStripMenuItem1 + // + this.saveToolStripMenuItem1.Image = ((System.Drawing.Image)(resources.GetObject("saveToolStripMenuItem1.Image"))); + this.saveToolStripMenuItem1.Name = "saveToolStripMenuItem1"; + this.saveToolStripMenuItem1.Size = new System.Drawing.Size(98, 22); + this.saveToolStripMenuItem1.Text = "Save"; + this.saveToolStripMenuItem1.Click += new System.EventHandler(this.saveToolStripMenuItem1_Click); + // + // helpToolStripMenuItem + // + this.helpToolStripMenuItem.ForeColor = System.Drawing.Color.White; + this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; + this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20); + this.helpToolStripMenuItem.Text = "Help"; + // + // ModelsEditor + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(349, 280); + this.Controls.Add(this.treeView1); + this.Controls.Add(this.menuStrip); + this.Name = "ModelsEditor"; + this.Resizable = false; + this.Style = MetroFramework.MetroColorStyle.Silver; + this.Text = "Entity Model Editor"; + this.Theme = MetroFramework.MetroThemeStyle.Dark; + this.metroContextMenu1.ResumeLayout(false); + this.menuStrip.ResumeLayout(false); + this.menuStrip.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TreeView treeView1; + private System.Windows.Forms.MenuStrip menuStrip; + private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem; + private MetroFramework.Controls.MetroContextMenu metroContextMenu1; + private System.Windows.Forms.ToolStripMenuItem addToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem renameToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem removeToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem addNewPositionOverrideToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem addNewEntryToolStripMenuItem; + } +} \ No newline at end of file diff --git a/PCK-Studio/Forms/Editor/ModelsEditor.cs b/PCK-Studio/Forms/Editor/ModelsEditor.cs new file mode 100644 index 00000000..c744b77b --- /dev/null +++ b/PCK-Studio/Forms/Editor/ModelsEditor.cs @@ -0,0 +1,231 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Windows.Forms; +using MetroFramework.Forms; +using PckStudio.Classes.FileTypes; +using PckStudio.Classes.IO.Model; +using PckStudio.Forms.Additional_Popups.EntityForms; +using Newtonsoft.Json.Linq; + +namespace PckStudio.Forms.Editor +{ + public partial class ModelsEditor : MetroForm + { + // Behaviours File Format research by Miku and MattNL + private readonly PCKFile.FileData _file; + ModelFile modelFile; + + void SetUpTree() + { + treeView1.BeginUpdate(); + treeView1.Nodes.Clear(); + foreach (var entry in modelFile.Models) + { + TreeNode EntryNode = new TreeNode(entry.name); + + foreach (JObject content in Utilities.ModelsUtil.entityData["entities"].Children()) + { + var prop = content.Properties().FirstOrDefault(prop => prop.Name == entry.name); + if (prop is JProperty) + { + EntryNode.Text = (string)prop.Value; + EntryNode.ImageIndex = Utilities.ModelsUtil.entityData["entities"].Children().ToList().IndexOf(content); + EntryNode.SelectedImageIndex = EntryNode.ImageIndex; + break; + } + } + + EntryNode.Tag = entry; + + foreach (var bone in entry.parts) + { + TreeNode BoneNode = new TreeNode(bone.name); + BoneNode.Tag = bone; + EntryNode.Nodes.Add(BoneNode); + BoneNode.ImageIndex = 120; + BoneNode.SelectedImageIndex = BoneNode.ImageIndex; + + foreach (var box in bone.Boxes) + { + TreeNode BoxNode = new TreeNode("Box"); + BoxNode.Tag = box; + BoneNode.Nodes.Add(BoxNode); + BoxNode.ImageIndex = 121; + BoxNode.SelectedImageIndex = BoxNode.ImageIndex; + } + } + + treeView1.Nodes.Add(EntryNode); + } + treeView1.EndUpdate(); + } + + public ModelsEditor(PCKFile.FileData file) + { + InitializeComponent(); + _file = file; + + using (var stream = new MemoryStream(file.Data)) + { + modelFile = ModelFileReader.Read(stream); + } + + treeView1.ImageList = new ImageList(); + treeView1.ImageList.Images.AddRange(Utilities.ModelsUtil.entityImages); + treeView1.ImageList.ColorDepth = ColorDepth.Depth32Bit; + SetUpTree(); + } + + private void treeView1_AfterSelect(object sender, TreeViewEventArgs e) + { + if (e.Node is null) return; + + bool isValidOverride = e.Node.Tag is BehaviourFile.RiderPositionOverride.PositionOverride && + treeView1.SelectedNode != null; + renameToolStripMenuItem.Visible = !isValidOverride; + + + if (isValidOverride) + { + var posOverride = e.Node.Tag as BehaviourFile.RiderPositionOverride.PositionOverride; + } + } + + private void removeToolStripMenuItem_Click(object sender, EventArgs e) + { + if (treeView1.SelectedNode is null) return; + treeView1.SelectedNode.Remove(); + } + + private void changeToolStripMenuItem_Click(object sender, EventArgs e) + { + if (treeView1.SelectedNode == null) return; + if (!(treeView1.SelectedNode.Tag is ModelFile.Model entry)) return; + + var diag = new AddEntry(Utilities.ModelsUtil.entityData, Utilities.ModelsUtil.entityImages); + diag.acceptBtn.Text = "Save"; + + if (diag.ShowDialog() == DialogResult.OK) + { + if (String.IsNullOrEmpty(diag.SelectedEntity)) return; + if (modelFile.Models.FindAll(model => model.name == diag.SelectedEntity).Count() > 0) + { + MessageBox.Show(this, "You cannot have two models for one entity", "Error", MessageBoxButtons.OK); + return; + } + + entry.name = diag.SelectedEntity; + treeView1.SelectedNode.Tag = entry; + + foreach (JObject content in Utilities.ModelsUtil.entityData["entities"].Children()) + { + var prop = content.Properties().FirstOrDefault(prop => prop.Name == entry.name); + if (prop is JProperty) + { + treeView1.SelectedNode.Text = (string)prop.Value; + treeView1.SelectedNode.ImageIndex = Utilities.ModelsUtil.entityData["entities"].Children().ToList().IndexOf(content); + treeView1.SelectedNode.SelectedImageIndex = treeView1.SelectedNode.ImageIndex; + break; + } + } + } + } + + private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) + { + + } + + private void addNewPositionOverrideToolStripMenuItem_Click(object sender, EventArgs e) + { + // change into part + if (treeView1.SelectedNode.Tag is BehaviourFile.RiderPositionOverride.PositionOverride) treeView1.SelectedNode = treeView1.SelectedNode.Parent; + + if (treeView1.SelectedNode.Tag is BehaviourFile.RiderPositionOverride) + { + TreeNode OverrideNode = new TreeNode("Position Override"); + OverrideNode.Tag = new BehaviourFile.RiderPositionOverride.PositionOverride(); + OverrideNode.ImageIndex = 103; + OverrideNode.SelectedImageIndex = 103; + treeView1.SelectedNode.Nodes.Add(OverrideNode); + } + } + + private void addNewEntryToolStripMenuItem_Click(object sender, EventArgs e) + { + var diag = new AddEntry(Utilities.ModelsUtil.entityData, Utilities.ModelsUtil.entityImages); + + if(diag.ShowDialog() == DialogResult.OK) + { + if (string.IsNullOrEmpty(diag.SelectedEntity)) return; + if (modelFile.Models.FindAll(model => model.name == diag.SelectedEntity).Count() > 0) + { + MessageBox.Show(this, "You cannot have two models for one entity.", "Error", MessageBoxButtons.OK); + return; + } + ModelFile.Model NewModel = new ModelFile.Model(diag.SelectedEntity, 64, 64); + + TreeNode NewModelNode = new TreeNode(NewModel.name); + NewModelNode.Tag = NewModel; + foreach (JObject content in Utilities.BehaviourUtil.entityData["entities"].Children()) + { + var prop = content.Properties().FirstOrDefault(prop => prop.Name == NewModel.name); + if (prop is JProperty) + { + NewModelNode.Text = (string)prop.Value; + NewModelNode.ImageIndex = Utilities.ModelsUtil.entityData["entities"].Children().ToList().IndexOf(content); + NewModelNode.SelectedImageIndex = NewModelNode.ImageIndex; + break; + } + } + treeView1.Nodes.Add(NewModelNode); + treeView1.SelectedNode = NewModelNode; + + //addNewPositionOverrideToolStripMenuItem_Click(sender, e); // adds a Position Override to the new Override + } + } + + private void treeView1_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Delete) removeToolStripMenuItem_Click(sender, e); + } + + private void treeView1_MouseHover(object sender, EventArgs e) + { + addNewPositionOverrideToolStripMenuItem.Visible = treeView1.SelectedNode != null; + } + + private void saveToolStripMenuItem1_Click(object sender, EventArgs e) + { + using (var stream = new MemoryStream()) + { + modelFile = new ModelFile(); + + foreach (TreeNode node in treeView1.Nodes) + { + if(node.Tag is ModelFile.Model entry) + { + entry.parts.Clear(); + foreach (TreeNode boneNode in node.Nodes) + { + if(boneNode.Tag is ModelFile.Model.Part boneEntry) + { + entry.parts.Add(boneEntry); + } + } + + modelFile.Models.Add(entry); + } + } + + ModelFileWriter.Write(stream, modelFile); + _file.SetData(stream.ToArray()); + } + DialogResult = DialogResult.OK; + } + } +} diff --git a/PCK-Studio/Forms/Editor/ModelsEditor.resx b/PCK-Studio/Forms/Editor/ModelsEditor.resx new file mode 100644 index 00000000..cbf74e02 --- /dev/null +++ b/PCK-Studio/Forms/Editor/ModelsEditor.resx @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 125, 17 + + + 17, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4yMfEgaZUAAADfSURBVDhPYxg8 + QLt++3yTGbf/Fm599P/Nh49wfPXxq/+rTt37f+Dak/8gOSBgAGEMANIMxGBFyAasPf/0v8GE8//z1t8C + y4HU4DIALIluwLpLL+HiMANAGKoNAWASCavv/n/57gPcgOvP3oENOXj7NViOoAFGU6791+k4ghWD5Aga + QCyGakMAkODcU89R/I8Ng9TgNADk14dPn/8/c+kqVgySgwUqVBsCwAx49urN/zsPHmPFIDmaGvAXJInN + 38gYasBfqDYE0K7dOn/Wvut/sfkdGYPUgJI9VNuAAwYGAGn6yvdevWgPAAAAAElFTkSuQmCC + + + \ No newline at end of file diff --git a/PCK-Studio/MainForm.cs b/PCK-Studio/MainForm.cs index 59146ad2..a7d4d6b4 100644 --- a/PCK-Studio/MainForm.cs +++ b/PCK-Studio/MainForm.cs @@ -464,7 +464,8 @@ namespace PckStudio } public void HandleModelsFile(PCKFile.FileData file) { - MessageBox.Show("Models.bin support has not been implemented. You can use the Spark Editor for the time being to edit these files.", "Not implemented yet."); + using ModelsEditor edit = new ModelsEditor(file); + wasModified = edit.ShowDialog(this) == DialogResult.OK; } public void HandleBehavioursFile(PCKFile.FileData file) { diff --git a/PCK-Studio/PckStudio.csproj b/PCK-Studio/PckStudio.csproj index e4becc84..2eba28af 100644 --- a/PCK-Studio/PckStudio.csproj +++ b/PCK-Studio/PckStudio.csproj @@ -285,6 +285,12 @@ TextPrompt.cs + + Form + + + ModelsEditor.cs + Form @@ -520,6 +526,9 @@ TextPrompt.cs + + ModelsEditor.cs + MaterialsEditor.cs