SkinANIM - Made class Immutable

This commit is contained in:
miku-666
2024-08-15 18:27:05 +02:00
parent b1bc4eadad
commit 76c091ed98
4 changed files with 44 additions and 56 deletions

View File

@@ -24,7 +24,7 @@ namespace PckStudio.Forms.Additional_Popups
private LOCFile currentLoc;
private PckAsset _skin = new PckAsset("dlcskinXYXYXYXY", PckAssetType.SkinFile);
private PckAsset _cape;
private SkinANIM anim = new SkinANIM();
private SkinANIM _anim = SkinANIM.Empty;
private Random rng = new Random();
private eSkinType skinType;
@@ -50,19 +50,19 @@ namespace PckStudio.Forms.Additional_Popups
switch (img.Height)
{
case 64:
anim.SetFlag(SkinAnimFlag.RESOLUTION_64x64, true);
_anim = _anim.SetFlag(SkinAnimFlag.RESOLUTION_64x64, true);
MessageBox.Show(this, "64x64 Skin Detected");
skinType = eSkinType._64x64;
break;
case 32:
anim.SetFlag(SkinAnimFlag.RESOLUTION_64x64 | SkinAnimFlag.SLIM_MODEL, false);
_anim = _anim.SetFlag(SkinAnimFlag.RESOLUTION_64x64 | SkinAnimFlag.SLIM_MODEL, false);
MessageBox.Show(this, "64x32 Skin Detected");
skinType = eSkinType._64x32;
break;
default:
if (img.Width == img.Height)
{
anim.SetFlag(SkinAnimFlag.RESOLUTION_64x64, true);
_anim = _anim.SetFlag(SkinAnimFlag.RESOLUTION_64x64, true);
MessageBox.Show(this, "64x64 HD Skin Detected");
skinType = eSkinType._64x64HD;
break;
@@ -70,7 +70,7 @@ namespace PckStudio.Forms.Additional_Popups
if (img.Height == img.Width / 2)
{
anim.SetFlag(SkinAnimFlag.RESOLUTION_64x64 | SkinAnimFlag.SLIM_MODEL, false);
_anim = _anim.SetFlag(SkinAnimFlag.RESOLUTION_64x64 | SkinAnimFlag.SLIM_MODEL, false);
MessageBox.Show(this, "64x32 HD Skin Detected");
skinType = eSkinType._64x32HD;
break;
@@ -92,43 +92,43 @@ namespace PckStudio.Forms.Additional_Popups
private void DrawModel()
{
bool isSlim = anim.GetFlag(SkinAnimFlag.SLIM_MODEL);
bool isSlim = _anim.GetFlag(SkinAnimFlag.SLIM_MODEL);
Pen outlineColor = Pens.LightGray;
Brush fillColor = Brushes.Gray;
Image previewTexture = new Bitmap(displayBox.Width, displayBox.Height);
using (Graphics g = Graphics.FromImage(previewTexture))
{
if(!anim.GetFlag(SkinAnimFlag.HEAD_DISABLED))
if(!_anim.GetFlag(SkinAnimFlag.HEAD_DISABLED))
{
//Head
g.DrawRectangle(outlineColor, 70, 15, 40, 40);
g.FillRectangle(fillColor, 71, 16, 39, 39);
}
if (!anim.GetFlag(SkinAnimFlag.BODY_DISABLED))
if (!_anim.GetFlag(SkinAnimFlag.BODY_DISABLED))
{
//Body
g.DrawRectangle(outlineColor, 70, 55, 40, 60);
g.FillRectangle(fillColor, 71, 56, 39, 59);
}
if (!anim.GetFlag(SkinAnimFlag.RIGHT_ARM_DISABLED))
if (!_anim.GetFlag(SkinAnimFlag.RIGHT_ARM_DISABLED))
{
//Arm0
g.DrawRectangle(outlineColor, isSlim ? 55 : 50, 55, isSlim ? 15 : 20, 60);
g.FillRectangle(fillColor , isSlim ? 56 : 51, 56, isSlim ? 14 : 19, 59);
}
if (!anim.GetFlag(SkinAnimFlag.LEFT_ARM_DISABLED))
if (!_anim.GetFlag(SkinAnimFlag.LEFT_ARM_DISABLED))
{
//Arm1
g.DrawRectangle(outlineColor, 110, 55, isSlim ? 15 : 20, 60);
g.FillRectangle(fillColor, 111, 56, isSlim ? 14 : 19, 59);
}
if (!anim.GetFlag(SkinAnimFlag.RIGHT_LEG_DISABLED))
if (!_anim.GetFlag(SkinAnimFlag.RIGHT_LEG_DISABLED))
{
//Leg0
g.DrawRectangle(outlineColor, 70, 115, 20, 60);
g.FillRectangle(fillColor, 71, 116, 19, 59);
}
if (!anim.GetFlag(SkinAnimFlag.LEFT_LEG_DISABLED))
if (!_anim.GetFlag(SkinAnimFlag.LEFT_LEG_DISABLED))
{
//Leg1
g.DrawRectangle(outlineColor, 90, 115, 20, 60);
@@ -237,18 +237,18 @@ namespace PckStudio.Forms.Additional_Popups
private void CreateButton_Click(object sender, EventArgs e)
{
if (!int.TryParse(textSkinID.Text, out int _skinId))
if (!int.TryParse(textSkinID.Text, out int skinId))
{
MessageBox.Show(this, "The Skin ID Must be a Unique 8 Digit Number Thats Not Already in Use", "Invalid Skin ID", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
string skinId = _skinId.ToString("d08");
_skin.Filename = $"dlcskin{skinId}.png";
string skinIdStr = skinId.ToString("d08");
_skin.Filename = $"dlcskin{skinIdStr}.png";
_skin.AddProperty("DISPLAYNAME", textSkinName.Text);
if (currentLoc is not null)
{
string skinDisplayNameLocKey = $"IDS_dlcskin{skinId}_DISPLAYNAME";
string skinDisplayNameLocKey = $"IDS_dlcskin{skinIdStr}_DISPLAYNAME";
_skin.AddProperty("DISPLAYNAMEID", skinDisplayNameLocKey);
currentLoc.AddLocKey(skinDisplayNameLocKey, textSkinName.Text);
}
@@ -258,17 +258,17 @@ namespace PckStudio.Forms.Additional_Popups
_skin.AddProperty("THEMENAME", textThemeName.Text);
if (currentLoc is not null)
{
_skin.AddProperty("THEMENAMEID", $"IDS_dlcskin{skinId}_THEMENAME");
currentLoc.AddLocKey($"IDS_dlcskin{skinId}_THEMENAME", textThemeName.Text);
_skin.AddProperty("THEMENAMEID", $"IDS_dlcskin{skinIdStr}_THEMENAME");
currentLoc.AddLocKey($"IDS_dlcskin{skinIdStr}_THEMENAME", textThemeName.Text);
}
}
_skin.AddProperty("ANIM", anim);
_skin.AddProperty("ANIM", _anim);
_skin.AddProperty("GAME_FLAGS", "0x18");
_skin.AddProperty("FREE", "1");
if (HasCape)
{
_cape.Filename = $"dlccape{skinId}.png";
_cape.Filename = $"dlccape{skinIdStr}.png";
_skin.AddProperty("CAPEPATH", _cape.Filename);
}
_skin.SetTexture(skinPictureBox.Image);
@@ -322,10 +322,10 @@ namespace PckStudio.Forms.Additional_Popups
private void buttonAnimGen_Click(object sender, EventArgs e)
{
using ANIMEditor diag = new ANIMEditor(anim.ToString());
using ANIMEditor diag = new ANIMEditor(_anim);
if (diag.ShowDialog(this) == DialogResult.OK)
{
anim = diag.ResultAnim;
_anim = diag.ResultAnim;
DrawModel();
}
}

View File

@@ -89,7 +89,7 @@ namespace PckStudio.Forms.Editor
checkbox.Checked = false;
break;
}
_anim.SetFlag(item.Value, checkbox.Checked);
_anim = _anim.SetFlag(item.Value, checkbox.Checked);
});
}
OnCheckboxChanged?.Invoke(_anim);
@@ -154,7 +154,7 @@ namespace PckStudio.Forms.Editor
default:
break;
}
_anim.SetFlag(checkBoxLinkage[checkBox], checkBox.Checked && checkBox.Enabled);
_anim = _anim.SetFlag(checkBoxLinkage[checkBox], checkBox.Checked && checkBox.Enabled);
OnCheckboxChanged?.Invoke(_anim);
}
}
@@ -179,18 +179,6 @@ namespace PckStudio.Forms.Editor
saveButton.Visible = !Settings.Default.AutoSaveChanges;
}
public ANIMEditor(string animString) : this()
{
if (!SkinANIM.IsValidANIM(animString))
{
DialogResult = DialogResult.Abort;
Close();
}
SkinANIM anim = initialANIM = SkinANIM.FromString(animString);
setDisplayAnim(anim);
ruleset.ApplyAnim(anim);
}
public ANIMEditor(SkinANIM skinANIM) : this()
{
initialANIM = skinANIM;
@@ -347,8 +335,8 @@ namespace PckStudio.Forms.Editor
private void resetButton_Click(object sender, EventArgs e)
{
ruleset.ApplyAnim((SkinANIM)initialANIM.Clone());
setDisplayAnim((SkinANIM)initialANIM.Clone());
ruleset.ApplyAnim(initialANIM);
setDisplayAnim(initialANIM);
}
static readonly Dictionary<string, SkinAnimMask> Templates = new Dictionary<string, SkinAnimMask>()
@@ -374,7 +362,7 @@ namespace PckStudio.Forms.Editor
if (diag.ShowDialog(this) != DialogResult.OK)
return;
var templateANIM = new SkinANIM(Templates[diag.SelectedItem]);
SkinANIM templateANIM = SkinANIM.Empty.SetMask(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)
templateANIM |= ruleset.Value;

View File

@@ -26,16 +26,11 @@ namespace PckStudio.Internal
/// </summary>
public class SkinANIM : ICloneable, IEquatable<SkinANIM>, IEquatable<SkinAnimMask>
{
public static readonly SkinANIM Empty = new SkinANIM();
public static readonly SkinANIM Empty = new SkinANIM(0);
private BitVector32 _flags;
private static readonly Regex _validator = new Regex(@"^0x[0-9a-f]{1,8}\b", RegexOptions.IgnoreCase);
public SkinANIM()
: this(SkinAnimMask.NONE)
{
}
public SkinANIM(SkinAnimMask mask)
: this((int)mask)
{
@@ -56,18 +51,18 @@ namespace PckStudio.Internal
public static SkinANIM FromString(string value)
=> IsValidANIM(value)
? new SkinANIM(Convert.ToInt32(value.TrimEnd(' ', '\n', '\r'), 16))
: new SkinANIM();
: Empty;
public static SkinANIM operator |(SkinANIM _this, SkinANIM other) => new SkinANIM(_this._flags.Data | other._flags.Data);
public static SkinANIM operator |(SkinANIM _this, SkinAnimMask mask) => new SkinANIM(_this._flags.Data | (int)mask);
public static SkinANIM operator |(SkinANIM @this, SkinANIM other) => new SkinANIM(@this._flags.Data | other._flags.Data);
public static SkinANIM operator |(SkinANIM @this, SkinAnimMask mask) => new SkinANIM(@this._flags.Data | (int)mask);
public static implicit operator SkinANIM(SkinAnimMask mask) => new SkinANIM(mask);
public static bool operator ==(SkinANIM _this, SkinAnimMask mask) => _this.Equals(mask);
public static bool operator !=(SkinANIM _this, SkinAnimMask mask) => !_this.Equals(mask);
public static bool operator ==(SkinANIM _this, SkinANIM other) => _this.Equals(other);
public static bool operator !=(SkinANIM _this, SkinANIM other) => !_this.Equals(other);
public static bool operator ==(SkinANIM @this, SkinAnimMask mask) => @this.Equals(mask);
public static bool operator !=(SkinANIM @this, SkinAnimMask mask) => !@this.Equals(mask);
public static bool operator ==(SkinANIM @this, SkinANIM other) => @this.Equals(other);
public static bool operator !=(SkinANIM @this, SkinANIM other) => !@this.Equals(other);
public bool Equals(SkinANIM other)
{
@@ -88,11 +83,11 @@ namespace PckStudio.Internal
/// </summary>
/// <param name="flag">ANIM Flag to set</param>
/// <param name="state">State of the flag</param>
public void SetFlag(SkinAnimFlag flag, bool state)
public SkinANIM SetFlag(SkinAnimFlag flag, bool state)
{
if (!Enum.IsDefined(typeof(SkinAnimFlag), flag))
throw new ArgumentOutOfRangeException(nameof(flag));
_flags[1 << (int)flag] = state;
return new SkinANIM(state ? _flags.Data | 1 << (int)flag : _flags.Data & ~(1 << (int)flag));
}
/// <summary>
@@ -111,5 +106,10 @@ namespace PckStudio.Internal
{
return MemberwiseClone();
}
internal SkinANIM SetMask(SkinAnimMask skinAnimMask)
{
return new SkinANIM(skinAnimMask);
}
}
}

View File

@@ -1081,7 +1081,7 @@ namespace PckStudio
case "ANIM" when asset.Type == PckAssetType.SkinFile:
try
{
using ANIMEditor diag = new ANIMEditor(property.Value);
using ANIMEditor diag = new ANIMEditor(SkinANIM.FromString(property.Value));
if (diag.ShowDialog(this) == DialogResult.OK)
{
asset.SetProperty(asset.GetPropertyIndex(property), new KeyValuePair<string, string>("ANIM", diag.ResultAnim.ToString()));