diff --git a/PCK-Studio/Forms/Editor/ANIMEditor.cs b/PCK-Studio/Forms/Editor/ANIMEditor.cs index 2d912263..eee62455 100644 --- a/PCK-Studio/Forms/Editor/ANIMEditor.cs +++ b/PCK-Studio/Forms/Editor/ANIMEditor.cs @@ -1,9 +1,10 @@ using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Drawing; using System.Linq; +using System.Drawing; +using System.Diagnostics; using System.Windows.Forms; +using System.Collections.Generic; + using PckStudio.Classes.Utils; using PckStudio.Forms.Additional_Popups; @@ -11,13 +12,16 @@ namespace PckStudio.Forms.Editor { public partial class ANIMEditor : MetroFramework.Forms.MetroForm { - readonly SkinANIM initialANIM; - public string outANIM => animValue.Text; - SkinANIM anim = new SkinANIM(); - ANIMRuleSet ruleset; + public SkinANIM ResultAnim => ruleset.Value; + + private readonly SkinANIM initialANIM; + private ANIMRuleSet ruleset; sealed class ANIMRuleSet { + public SkinANIM Value => anim; + public Action OnCheckboxChanged; + private class Bictionary : Dictionary { public Bictionary(int capacity) @@ -43,14 +47,12 @@ namespace PckStudio.Forms.Editor } } private Bictionary checkBoxLinkage; - private SkinANIM ANIM; + private SkinANIM anim; private bool ignoreCheckChanged = false; - public Action OnCheckboxChanged; - - public ANIMRuleSet(ref SkinANIM anim, params (CheckBox, ANIM_EFFECTS)[] linkage) + public ANIMRuleSet(SkinANIM anim, params (CheckBox, ANIM_EFFECTS)[] linkage) { - ANIM = anim; + this.anim = anim; checkBoxLinkage = new Bictionary(32); if (linkage.Length < 32) Debug.WriteLine($"Not all {nameof(ANIM_EFFECTS)} are mapped to a given checkbox."); @@ -65,20 +67,23 @@ namespace PckStudio.Forms.Editor internal void SetAll(bool state) { - ignoreCheckChanged = true; foreach (var item in checkBoxLinkage) { - ANIM.SetFlag(item.Value, state); - item.Key.Checked = state; + IgnoreAndDo(item.Key, checkbox => + { + anim.SetFlag(item.Value, state); + checkbox.Checked = state; + checkbox.Enabled = true; + }); } - ignoreCheckChanged = false; } - internal void ApplyAnim(ref SkinANIM anim) + internal void ApplyAnim(SkinANIM anim) { - ANIM = anim; + this.anim = anim; foreach (var item in checkBoxLinkage) { + IgnoreAndDo(item.Key, checkbox => checkbox.Enabled = true); item.Key.Checked = anim.GetFlag(item.Value); } } @@ -109,18 +114,34 @@ namespace PckStudio.Forms.Editor break; case ANIM_EFFECTS.RESOLUTION_64x64: + + if (checkBoxLinkage[ANIM_EFFECTS.SLIM_MODEL].Checked) + { + checkBoxLinkage[ANIM_EFFECTS.SLIM_MODEL].Checked = false; + } checkBoxLinkage[ANIM_EFFECTS.SLIM_MODEL].Enabled = !checkBox.Checked; break; case ANIM_EFFECTS.SLIM_MODEL: + if (checkBoxLinkage[ANIM_EFFECTS.RESOLUTION_64x64].Checked) + { + checkBoxLinkage[ANIM_EFFECTS.RESOLUTION_64x64].Checked = false; + } checkBoxLinkage[ANIM_EFFECTS.RESOLUTION_64x64].Enabled = !checkBox.Checked; break; default: break; } - ANIM.SetFlag(checkBoxLinkage[checkBox], checkBox.Checked && checkBox.Enabled); - OnCheckboxChanged?.Invoke(); + anim.SetFlag(checkBoxLinkage[checkBox], checkBox.Checked && checkBox.Enabled); + OnCheckboxChanged?.Invoke(anim); } } + + private void IgnoreAndDo(CheckBox checkBox, Action action) + { + ignoreCheckChanged = true; + action.Invoke(checkBox); + ignoreCheckChanged = false; + } } public ANIMEditor(string ANIM) @@ -131,10 +152,10 @@ namespace PckStudio.Forms.Editor DialogResult = DialogResult.Abort; Close(); } - initialANIM = anim = SkinANIM.FromString(ANIM); - setDisplayAnim(); + var anim = initialANIM = SkinANIM.FromString(ANIM); + setDisplayAnim(anim); - ruleset = new ANIMRuleSet(ref anim, + ruleset = new ANIMRuleSet(anim, (bobbingCheckBox, ANIM_EFFECTS.HEAD_BOBBING_DISABLED), (bodyCheckBox, ANIM_EFFECTS.BODY_DISABLED), (bodyOCheckBox, ANIM_EFFECTS.BODY_OVERLAY_DISABLED), @@ -172,7 +193,7 @@ namespace PckStudio.Forms.Editor ruleset.OnCheckboxChanged = setDisplayAnim; } - private void setDisplayAnim() + private void setDisplayAnim(SkinANIM anim) { animValue.Text = anim.ToString(); } @@ -190,24 +211,20 @@ namespace PckStudio.Forms.Editor private void importButton_Click(object sender, EventArgs e) { - string new_value = ""; - - bool first = true; - while (!SkinANIM.IsValidANIM(new_value)) + string value = string.Empty; + while (!SkinANIM.IsValidANIM(value)) { - if (!first) MessageBox.Show($"The following value \"{new_value}\" is not valid. Please try again."); - RenamePrompt diag = new RenamePrompt(new_value); + if (!string.IsNullOrWhiteSpace(value)) MessageBox.Show($"The following value \"{value}\" is not valid. Please try again."); + RenamePrompt diag = new RenamePrompt(value); diag.TextLabel.Text = "ANIM"; diag.OKButton.Text = "Ok"; if (diag.ShowDialog() == DialogResult.OK) { - new_value = diag.NewText; + value = diag.NewText; } else return; - first = false; } - anim = SkinANIM.FromString(new_value); - ruleset.ApplyAnim(ref anim); + ruleset.ApplyAnim(SkinANIM.FromString(value)); } private void uncheckButton_Click(object sender, EventArgs e) @@ -229,8 +246,8 @@ namespace PckStudio.Forms.Editor }; if (saveFileDialog.ShowDialog() != DialogResult.OK) return; - bool isSlim = anim.GetFlag(ANIM_EFFECTS.SLIM_MODEL); - bool is64x64 = anim.GetFlag(ANIM_EFFECTS.RESOLUTION_64x64); + bool isSlim = ruleset.Value.GetFlag(ANIM_EFFECTS.SLIM_MODEL); + bool is64x64 = ruleset.Value.GetFlag(ANIM_EFFECTS.RESOLUTION_64x64); bool isClassic32 = !isSlim && !is64x64; Image skin = isSlim ? Properties.Resources.slim_template : Properties.Resources.classic_template; @@ -239,31 +256,31 @@ namespace PckStudio.Forms.Editor using (Graphics graphic = Graphics.FromImage(img)) { graphic.DrawImage(skin, new Rectangle(0, 0, 64, isClassic32 ? 32 : 64), new Rectangle(0, 0, 64, isClassic32 ? 32 : 64), GraphicsUnit.Pixel); - if (anim.GetFlag(ANIM_EFFECTS.HEAD_OVERLAY_DISABLED)) + if (ruleset.Value.GetFlag(ANIM_EFFECTS.HEAD_OVERLAY_DISABLED)) graphic.FillRectangle(Brushes.Magenta, new Rectangle(32, 0, 32, 16)); - if (anim.GetFlag(ANIM_EFFECTS.HEAD_DISABLED)) + if (ruleset.Value.GetFlag(ANIM_EFFECTS.HEAD_DISABLED)) graphic.FillRectangle(Brushes.Magenta, new Rectangle(0, 0, 32, 16)); - if (anim.GetFlag(ANIM_EFFECTS.BODY_DISABLED)) + if (ruleset.Value.GetFlag(ANIM_EFFECTS.BODY_DISABLED)) graphic.FillRectangle(Brushes.Magenta, new Rectangle(16, 16, 24, 16)); if (img.Height == 64) { - if (anim.GetFlag(ANIM_EFFECTS.RIGHT_ARM_DISABLED)) graphic.FillRectangle(Brushes.Magenta, new Rectangle(40, 16, 16, 16)); - if (anim.GetFlag(ANIM_EFFECTS.RIGHT_LEG_DISABLED)) graphic.FillRectangle(Brushes.Magenta, new Rectangle(0, 16, 16, 16)); - if (anim.GetFlag(ANIM_EFFECTS.BODY_OVERLAY_DISABLED)) graphic.FillRectangle(Brushes.Magenta, new Rectangle(16, 32, 24, 16)); - if (anim.GetFlag(ANIM_EFFECTS.RIGHT_ARM_OVERLAY_DISABLED)) graphic.FillRectangle(Brushes.Magenta, new Rectangle(40, 32, 16, 16)); - if (anim.GetFlag(ANIM_EFFECTS.RIGHT_LEG_OVERLAY_DISABLED)) graphic.FillRectangle(Brushes.Magenta, new Rectangle(0, 32, 16, 16)); - if (anim.GetFlag(ANIM_EFFECTS.LEFT_LEG_OVERLAY_DISABLED)) graphic.FillRectangle(Brushes.Magenta, new Rectangle(0, 48, 16, 16)); - if (anim.GetFlag(ANIM_EFFECTS.LEFT_LEG_DISABLED)) graphic.FillRectangle(Brushes.Magenta, new Rectangle(16, 48, 16, 16)); - if (anim.GetFlag(ANIM_EFFECTS.LEFT_ARM_DISABLED)) graphic.FillRectangle(Brushes.Magenta, new Rectangle(32, 48, 16, 16)); - if (anim.GetFlag(ANIM_EFFECTS.LEFT_ARM_OVERLAY_DISABLED)) graphic.FillRectangle(Brushes.Magenta, new Rectangle(48, 48, 16, 16)); + if (ruleset.Value.GetFlag(ANIM_EFFECTS.RIGHT_ARM_DISABLED)) graphic.FillRectangle(Brushes.Magenta, new Rectangle(40, 16, 16, 16)); + if (ruleset.Value.GetFlag(ANIM_EFFECTS.RIGHT_LEG_DISABLED)) graphic.FillRectangle(Brushes.Magenta, new Rectangle(0, 16, 16, 16)); + if (ruleset.Value.GetFlag(ANIM_EFFECTS.BODY_OVERLAY_DISABLED)) graphic.FillRectangle(Brushes.Magenta, new Rectangle(16, 32, 24, 16)); + if (ruleset.Value.GetFlag(ANIM_EFFECTS.RIGHT_ARM_OVERLAY_DISABLED)) graphic.FillRectangle(Brushes.Magenta, new Rectangle(40, 32, 16, 16)); + if (ruleset.Value.GetFlag(ANIM_EFFECTS.RIGHT_LEG_OVERLAY_DISABLED)) graphic.FillRectangle(Brushes.Magenta, new Rectangle(0, 32, 16, 16)); + if (ruleset.Value.GetFlag(ANIM_EFFECTS.LEFT_LEG_OVERLAY_DISABLED)) graphic.FillRectangle(Brushes.Magenta, new Rectangle(0, 48, 16, 16)); + if (ruleset.Value.GetFlag(ANIM_EFFECTS.LEFT_LEG_DISABLED)) graphic.FillRectangle(Brushes.Magenta, new Rectangle(16, 48, 16, 16)); + if (ruleset.Value.GetFlag(ANIM_EFFECTS.LEFT_ARM_DISABLED)) graphic.FillRectangle(Brushes.Magenta, new Rectangle(32, 48, 16, 16)); + if (ruleset.Value.GetFlag(ANIM_EFFECTS.LEFT_ARM_OVERLAY_DISABLED)) graphic.FillRectangle(Brushes.Magenta, new Rectangle(48, 48, 16, 16)); } else { // Since both classic 32 arms and legs use the same texture, removing the texture would remove both limbs instead of just one. // So both must be disabled by the user before they're removed from the texture; - if (anim.GetFlag(ANIM_EFFECTS.RIGHT_ARM_DISABLED) && anim.GetFlag(ANIM_EFFECTS.LEFT_ARM_DISABLED)) + if (ruleset.Value.GetFlag(ANIM_EFFECTS.RIGHT_ARM_DISABLED) && ruleset.Value.GetFlag(ANIM_EFFECTS.LEFT_ARM_DISABLED)) graphic.FillRectangle(Brushes.Magenta, new Rectangle(40, 16, 16, 16)); - if (anim.GetFlag(ANIM_EFFECTS.RIGHT_LEG_DISABLED) && anim.GetFlag(ANIM_EFFECTS.LEFT_LEG_DISABLED)) + if (ruleset.Value.GetFlag(ANIM_EFFECTS.RIGHT_LEG_DISABLED) && ruleset.Value.GetFlag(ANIM_EFFECTS.LEFT_LEG_DISABLED)) graphic.FillRectangle(Brushes.Magenta, new Rectangle(0, 16, 16, 16)); } img.MakeTransparent(Color.Magenta); @@ -274,13 +291,13 @@ namespace PckStudio.Forms.Editor private void resetButton_Click(object sender, EventArgs e) { - anim = initialANIM; - ruleset.ApplyAnim(ref anim); + ruleset.ApplyAnim((SkinANIM)initialANIM.Clone()); } static readonly Dictionary Templates = new Dictionary() { - { "Steve (64x32)", ANIM_EFFECTS.NONE }, + // TODO + //{ "Steve (64x32)", 0 }, { "Steve (64x64)", ANIM_EFFECTS.RESOLUTION_64x64 }, { "Alex (64x64)", ANIM_EFFECTS.SLIM_MODEL }, { "Zombie Skins", ANIM_EFFECTS.ZOMBIE_ARMS }, @@ -298,13 +315,14 @@ namespace PckStudio.Forms.Editor diag.label2.Text = "Presets"; diag.okBtn.Text = "Load"; - if (diag.ShowDialog() != DialogResult.OK) return; + if (diag.ShowDialog() != DialogResult.OK) + return; - var templateANIM = Templates[diag.SelectedItem]; + var templateANIM = new SkinANIM(Templates[diag.SelectedItem]); DialogResult prompt = MessageBox.Show(this, "Would you like to add this preset's effects to your current ANIM? Otherwise all of your effects will be cleared. Either choice can be undone by pressing \"Restore ANIM\".", "", MessageBoxButtons.YesNo); - if (prompt == DialogResult.Yes) anim |= templateANIM; - else anim = templateANIM; - ruleset.ApplyAnim(ref anim); + if (prompt == DialogResult.Yes) + templateANIM = ruleset.Value | templateANIM; + ruleset.ApplyAnim(templateANIM); } } } diff --git a/PCK-Studio/Forms/Skins-And-Textures/addnewskin.cs b/PCK-Studio/Forms/Skins-And-Textures/addnewskin.cs index 611f1d31..1fda9bed 100644 --- a/PCK-Studio/Forms/Skins-And-Textures/addnewskin.cs +++ b/PCK-Studio/Forms/Skins-And-Textures/addnewskin.cs @@ -369,7 +369,7 @@ namespace PckStudio using ANIMEditor diag = new ANIMEditor(anim.ToString()); if (diag.ShowDialog(this) == DialogResult.OK) { - anim = SkinANIM.FromString(diag.outANIM); + anim = diag.ResultAnim; DrawModel(); } } diff --git a/PCK-Studio/MainForm.cs b/PCK-Studio/MainForm.cs index 0117a036..69ff6639 100644 --- a/PCK-Studio/MainForm.cs +++ b/PCK-Studio/MainForm.cs @@ -1017,7 +1017,7 @@ namespace PckStudio using ANIMEditor diag = new ANIMEditor(property.Item2); if (diag.ShowDialog(this) == DialogResult.OK) { - file.Properties[i] = ("ANIM", diag.outANIM); + file.Properties[i] = ("ANIM", diag.ResultAnim.ToString()); if (IsSubPCKNode(treeViewMain.SelectedNode.FullPath)) RebuildSubPCK(treeViewMain.SelectedNode); ReloadMetaTreeView();