diff --git a/.gitmodules b/.gitmodules
index 39456fd0..d46d5086 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,6 @@
[submodule "OMI-Lib"]
path = Vendor/OMI-Lib
- url = https://github.com/PhoenixARC/-OMI-Filetype-Library.git
+ url = https://github.com/LCERD/OMI-Filetype-Library.git
[submodule "Vendor/SharpMss32"]
path = Vendor/SharpMss32
url = https://github.com/NessieHax/SharpMss32.git
diff --git a/PCK-Studio/App.config b/PCK-Studio/App.config
index c3b1b2f6..732c8327 100644
--- a/PCK-Studio/App.config
+++ b/PCK-Studio/App.config
@@ -77,6 +77,9 @@
False
+
+ True
+
diff --git a/PCK-Studio/Classes/Models/BackgroundTypes.cs b/PCK-Studio/Classes/Models/BackgroundTypes.cs
deleted file mode 100644
index b460d046..00000000
--- a/PCK-Studio/Classes/Models/BackgroundTypes.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System;
-
-namespace PckStudio.Models
-{
- public enum BackgroundTypes
- {
- Color,
- Gradient,
- Texture
- }
-}
diff --git a/PCK-Studio/Classes/Models/Backgrounds.cs b/PCK-Studio/Classes/Models/Backgrounds.cs
deleted file mode 100644
index 692896bc..00000000
--- a/PCK-Studio/Classes/Models/Backgrounds.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-
-namespace PckStudio.Models
-{
- public enum Backgrounds
- {
- LightStone,
- DarkStone,
- DaySky,
- NightSky,
- Sunset,
- Transparent
- }
-}
diff --git a/PCK-Studio/Classes/Models/Box.cs b/PCK-Studio/Classes/Models/Box.cs
deleted file mode 100644
index 23d64a9d..00000000
--- a/PCK-Studio/Classes/Models/Box.cs
+++ /dev/null
@@ -1,158 +0,0 @@
-using System;
-using System.Drawing;
-
-namespace PckStudio.Models
-{
- public class Box : Object3D
- {
- public override Image Image
- {
- set
- {
- SetImage(value);
- }
- }
-
- internal override MinecraftModelView Viewport
- {
- set
- {
- base.Viewport = value;
- top.Viewport = value;
- bottom.Viewport = value;
- front.Viewport = value;
- back.Viewport = value;
- left.Viewport = value;
- right.Viewport = value;
- Update();
- }
- }
-
- internal override void Update()
- {
- Matrix3D a = globalTransformation * localTransformation;
- top.LocalTransformation = a * topLocalTransformation;
- bottom.LocalTransformation = a * bottomLocalTransformation;
- front.LocalTransformation = a * frontLocalTransformation;
- back.LocalTransformation = a * backLocalTransformation;
- left.LocalTransformation = a * leftLocalTransformation;
- right.LocalTransformation = a * rightLocalTransformation;
- }
-
- public Box(Image image, Rectangle srcTopBottom, Rectangle srcSides, Point3D origin, Effects effects = Effects.None)
- {
- this.effects = effects;
- Origin = origin;
- SetImage(image, srcTopBottom, srcSides);
- }
-
- private void SetImage(Image image, Rectangle srcTopBottom, Rectangle srcSides)
- {
- int num = srcTopBottom.Width / 2;
- int height = srcSides.Height;
- int height2 = srcTopBottom.Height;
- srcTop = new Rectangle(srcTopBottom.Location, new Size(num, height2));
- srcBottom = new Rectangle(srcTopBottom.X + num, srcTopBottom.Y, num, height2);
- srcFront = new Rectangle(srcSides.X + height2, srcSides.Y, num, height);
- srcBack = new Rectangle(srcSides.X + height2 + num + height2, srcSides.Y, num, height);
- srcLeft = new Rectangle(srcSides.Location, new Size(height2, height));
- srcRight = new Rectangle(srcSides.X + height2 + num, srcSides.Y, height2, height);
- SetImage(image);
- }
-
- private void SetImage(Image image)
- {
- bool flag = (byte)(effects & Effects.FlipHorizontally) == 1;
- bool flag2 = (byte)(effects & Effects.FlipVertically) == 2;
- int width = srcFront.Width;
- int height = srcFront.Height;
- int width2 = srcLeft.Width;
- top = new TexturePlane(image, flag2 ? srcBottom : srcTop, new Point3D(width * 0.5f, width2 * 0.5f, (float)(-(float)height) * 0.5f), new Point3D(0f, 1f, 0f), effects & Effects.FlipHorizontally);
- bottom = new TexturePlane(image, flag2 ? srcTop : srcBottom, new Point3D(width / 2f, width2 / 2f, height / 2f), new Point3D(0f, -1f, 0f), effects & Effects.FlipHorizontally);
- front = new TexturePlane(image, srcFront, new Point3D(width * 0.5f, height * 0.5f, (float)(-(float)width2) * 0.5f), new Point3D(0f, 0f, 1f), effects);
- back = new TexturePlane(image, srcBack, new Point3D(width * 0.5f, height * 0.5f, (float)(-(float)width2) * 0.5f), new Point3D(0f, 0f, -1f), effects);
- left = new TexturePlane(image, flag ? srcRight : srcLeft, new Point3D(width2 * 0.5f, height * 0.5f, (float)(-(float)width) * 0.5f), new Point3D(-1f, 0f, 0f), effects);
- right = new TexturePlane(image, flag ? srcLeft : srcRight, new Point3D(width2 * 0.5f, height * 0.5f, (float)(-(float)width) * 0.5f), new Point3D(1f, 0f, 0f), effects);
- top.Viewport = viewport;
- bottom.Viewport = viewport;
- front.Viewport = viewport;
- back.Viewport = viewport;
- left.Viewport = viewport;
- right.Viewport = viewport;
- }
-
- public override float HitTest(PointF location)
- {
- float num = -1000f;
- float num2 = top.HitTest(location);
- if (num2 > num)
- {
- num = num2;
- }
- num2 = bottom.HitTest(location);
- if (num2 > num)
- {
- num = num2;
- }
- num2 = front.HitTest(location);
- if (num2 > num)
- {
- num = num2;
- }
- num2 = back.HitTest(location);
- if (num2 > num)
- {
- num = num2;
- }
- num2 = left.HitTest(location);
- if (num2 > num)
- {
- num = num2;
- }
- num2 = right.HitTest(location);
- if (num2 > num)
- {
- num = num2;
- }
- return num;
- }
-
- private TexturePlane top;
-
- private TexturePlane bottom;
-
- private TexturePlane front;
-
- private TexturePlane back;
-
- private TexturePlane left;
-
- private TexturePlane right;
-
- private Rectangle srcTop;
-
- private Rectangle srcBottom;
-
- private Rectangle srcFront;
-
- private Rectangle srcBack;
-
- private Rectangle srcLeft;
-
- private Rectangle srcRight;
-
- private Matrix3D topLocalTransformation = Matrix3D.CreateRotationX(-1.57079637f);
-
- private Matrix3D bottomLocalTransformation = Matrix3D.CreateRotationX(-1.57079637f);
-
- private Matrix3D frontLocalTransformation = Matrix3D.Identity;
-
- private Matrix3D backLocalTransformation = Matrix3D.CreateRotationY(3.14159274f);
-
- private Matrix3D leftLocalTransformation = Matrix3D.CreateRotationY(-1.57079637f);
-
- private Matrix3D rightLocalTransformation = Matrix3D.CreateRotationY(1.57079637f);
-
- private Effects effects;
- }
-}
diff --git a/PCK-Studio/Classes/Models/DefaultModels/ModelBase.cs b/PCK-Studio/Classes/Models/DefaultModels/ModelBase.cs
deleted file mode 100644
index 66a759c9..00000000
--- a/PCK-Studio/Classes/Models/DefaultModels/ModelBase.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-using System;
-using PckStudio.Models;
-using System.Runtime.CompilerServices;
-using System.Threading;
-using System.Drawing;
-
-namespace PckStudio.Models
-{
- public abstract class ModelBase
- {
- public ModelBase()
- { }
-
- protected Image[] textures;
-
- public EventHandler OnUpdate;
- protected const float OverlayScale = 1.16f;
-
- public Image[] Textures => textures;
-
- public event EventHandler Updatedx
- {
- add
- {
- EventHandler eventHandler = OnUpdate;
- EventHandler eventHandler2;
- do
- {
- eventHandler2 = eventHandler;
- EventHandler value2 = (EventHandler)Delegate.Combine(eventHandler2, value);
- eventHandler = Interlocked.CompareExchange(ref OnUpdate, value2, eventHandler2);
- }
- while (eventHandler != eventHandler2);
- }
- remove
- {
- EventHandler eventHandler = OnUpdate;
- EventHandler eventHandler2;
- do
- {
- eventHandler2 = eventHandler;
- EventHandler value2 = (EventHandler)Delegate.Remove(eventHandler2, value);
- eventHandler = Interlocked.CompareExchange(ref OnUpdate, value2, eventHandler2);
- }
- while (eventHandler != eventHandler2);
- }
- }
-
- protected void OnUpdated()
- {
- if (OnUpdate != null)
- {
- OnUpdate(this, EventArgs.Empty);
- }
- }
-
- public abstract void AddToModelView(MinecraftModelView modelView);
- }
-}
diff --git a/PCK-Studio/Classes/Models/DefaultModels/Steve64x32Model.cs b/PCK-Studio/Classes/Models/DefaultModels/Steve64x32Model.cs
deleted file mode 100644
index 0af00dfc..00000000
--- a/PCK-Studio/Classes/Models/DefaultModels/Steve64x32Model.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-using System;
-using System.IO;
-using System.Drawing;
-using PckStudio.Models;
-using PckStudio.Properties;
-
-namespace PckStudio.Models
-{
- internal class Steve64x32Model : ModelBase
- {
- public Steve64x32Model(Image texture)
- {
- textures = new Image[1] { texture };
- }
-
- public override void AddToModelView(MinecraftModelView modelView)
- {
- _ = Textures[0] ?? throw new NullReferenceException(nameof(Textures));
- Image source = Textures[0];
- Box head = new Box(source, new Rectangle( 8, 0, 16, 8), new Rectangle( 0, 8, 32, 8), new Point3D(0f, 0f, 0f));
- Box headOverlay = new Box(source, new Rectangle(40, 0, 16, 8), new Rectangle(32, 8, 32, 8), new Point3D(0f, 0f, 0f));
- headOverlay.Scale = OverlayScale;
-
- Box body = new Box(source, new Rectangle(20, 16, 16, 4), new Rectangle(16, 20, 24, 12), new Point3D(0f, 0f, 0f));
-
- Box leftArm = new Box(source, new Rectangle(44, 16, 8, 4), new Rectangle(40, 20, 32, 12), new Point3D(0f, 4f, 0f));
- Box rightArm = new Box(source, new Rectangle(44, 16, 8, 4), new Rectangle(40, 20, 32, 12), new Point3D(0f, 4f, 0f));
-
- Box leftLeg = new Box(source, new Rectangle(4, 16, 8, 4), new Rectangle(0, 20, 16, 12), new Point3D(0f, 6f, 0f));
- Box rightLeg = new Box(source, new Rectangle(4, 16, 8, 4), new Rectangle(0, 20, 16, 12), new Point3D(0f, 6f, 0f));
-
- Object3DGroup headGroup = new Object3DGroup();
-
- headGroup.RotationOrder = RotationOrders.XY;
- headGroup.MinDegrees1 = -80f;
- headGroup.MaxDegrees1 = 80f;
-
- headGroup.MinDegrees2 = -57f;
- headGroup.MaxDegrees2 = 57f;
-
- headGroup.Add(head);
- headGroup.Add(headOverlay);
-
- headGroup.Position = new Point3D(0f, 8f, 0f);
- headGroup.Origin = new Point3D(0f, -4f, 0f);
- headGroup.RotationOrder = RotationOrders.XY;
-
- body.Position = new Point3D(0f, 2f, 0f);
-
- leftArm.Position = new Point3D(6f, 6f, 0f);
- leftArm.RotationOrder = RotationOrders.ZX;
- leftArm.MinDegrees1 = 0f;
- leftArm.MaxDegrees1 = 160f;
- leftArm.MinDegrees2 = -170f;
- leftArm.MaxDegrees2 = 60f;
-
- rightArm.Position = new Point3D(-6f, 6f, 0f);
- rightArm.RotationOrder = RotationOrders.ZX;
- rightArm.MinDegrees1 = -160f;
- rightArm.MaxDegrees1 = 0f;
- rightArm.MinDegrees2 = -170f;
- rightArm.MaxDegrees2 = 60f;
-
- leftLeg.Position = new Point3D(2f, -4f, 0f);
- leftLeg.RotationOrder = RotationOrders.ZX;
- leftLeg.MinDegrees1 = 0f;
- leftLeg.MaxDegrees1 = 70f;
- leftLeg.MinDegrees2 = -110f;
- leftLeg.MaxDegrees2 = 60f;
-
- rightLeg.Position = new Point3D(-2f, -4f, 0f);
- rightLeg.RotationOrder = RotationOrders.ZX;
- rightLeg.MinDegrees1 = -70f;
- rightLeg.MaxDegrees1 = 0f;
- rightLeg.MinDegrees2 = -110f;
- rightLeg.MaxDegrees2 = 60f;
-
- modelView.AddDynamic(headGroup);
- modelView.AddStatic(body);
- modelView.AddDynamic(rightArm);
- modelView.AddDynamic(leftArm);
- modelView.AddDynamic(rightLeg);
- modelView.AddDynamic(leftLeg);
- }
-
- public override string ToString() => nameof(Steve64x32Model);
- }
-}
diff --git a/PCK-Studio/Classes/Models/DefaultModels/Steve64x64Model.cs b/PCK-Studio/Classes/Models/DefaultModels/Steve64x64Model.cs
deleted file mode 100644
index e7442333..00000000
--- a/PCK-Studio/Classes/Models/DefaultModels/Steve64x64Model.cs
+++ /dev/null
@@ -1,122 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Linq;
-using System.Security.Policy;
-using System.Text;
-using System.Threading.Tasks;
-using PckStudio.Internal;
-using PckStudio.Models;
-
-namespace PckStudio.Classes.Models.DefaultModels
-{
- internal class Steve64x64Model : ModelBase
- {
- SkinANIM _skinANIM;
- public Steve64x64Model(Image texture, SkinANIM anim)
- {
- textures = new Image[1] { texture };
- _skinANIM = anim;
- }
-
- public override void AddToModelView(MinecraftModelView modelView)
- {
- _ = Textures[0] ?? throw new NullReferenceException(nameof(Textures));
- Image source = Textures[0];
-
- (int top, int side) armWidth = _skinANIM.GetFlag(SkinAnimFlag.SLIM_MODEL) ? (6, 14) : (8, 16);
-
- Box head = new Box(source, new Rectangle(8, 0, 16, 8), new Rectangle(0, 8, 32, 8), new Point3D(0f, 0f, 0f));
- Box headOverlay = new Box(source, new Rectangle(40, 0, 16, 8), new Rectangle(32, 8, 32, 8), new Point3D(0f, 0f, 0f));
- headOverlay.Scale = OverlayScale;
-
- Box body = new Box(source, new Rectangle(20, 16, 16, 4), new Rectangle(16, 20, 24, 12), new Point3D(0f, 0f, 0f));
- Box bodyOverlay = new Box(source, new Rectangle(20, 32, 16, 4), new Rectangle(16, 36, 24, 12), new Point3D(0f, 0f, 0f));
- bodyOverlay.Scale = OverlayScale;
-
- Box rightArm = new Box(source, new Rectangle(44, 16, armWidth.top, 4), new Rectangle(40, 20, armWidth.side, 12), new Point3D(0f, 4f, 0f));
- Box rightArmOverlay = new Box(source, new Rectangle(44, 32, armWidth.top, 4), new Rectangle(40, 36, armWidth.side, 12), new Point3D(0f, 4f, 0f));
- rightArmOverlay.Scale = OverlayScale;
-
- Box leftArm = new Box(source, new Rectangle(36, 48, armWidth.top, 4), new Rectangle(32, 52, armWidth.side, 12), new Point3D(0f, 4f, 0f));
- Box leftArmOverlay = new Box(source, new Rectangle(52, 48, armWidth.top, 4), new Rectangle(48, 52, armWidth.side, 12), new Point3D(0f, 4f, 0f));
- leftArmOverlay.Scale = OverlayScale;
-
- Box rightLeg = new Box(source, new Rectangle(4, 16, 8, 4), new Rectangle(0, 20, 16, 12), new Point3D(0f, 6f, 0f));
- Box rightLegOverlay = new Box(source, new Rectangle(4, 32, 8, 4), new Rectangle(0, 52, 16, 12), new Point3D(0f, 6f, 0f));
- rightLegOverlay.Scale = OverlayScale;
-
- Box leftLeg = new Box(source, new Rectangle(20, 48, 8, 4), new Rectangle(16, 52, 16, 12), new Point3D(0f, 6f, 0f));
- Box leftLegOverlay = new Box(source, new Rectangle( 4, 48, 8, 4), new Rectangle( 0, 52, 16, 12), new Point3D(0f, 6f, 0f));
- leftLegOverlay.Scale = OverlayScale;
-
- Object3DGroup headGroup = new Object3DGroup();
- Object3DGroup bodyGroup = new Object3DGroup();
- Object3DGroup leftArmGroup = new Object3DGroup();
- Object3DGroup rightArmGroup = new Object3DGroup();
- Object3DGroup leftLegGroup = new Object3DGroup();
- Object3DGroup rightLegGroup = new Object3DGroup();
-
- headGroup.RotationOrder = RotationOrders.XY;
- headGroup.MinDegrees1 = -80f;
- headGroup.MaxDegrees1 = 80f;
-
- headGroup.MinDegrees2 = -57f;
- headGroup.MaxDegrees2 = 57f;
-
- headGroup.Origin = new Point3D(0f, -4f, 0f);
- headGroup.RotationOrder = RotationOrders.XY;
-
- headGroup.Position = new Point3D(0f, 8f, 0f);
- headGroup.Add(head);
- headGroup.Add(headOverlay);
-
- bodyGroup.Position = new Point3D(0f, 2f, 0f);
- bodyGroup.Add(body);
- bodyGroup.Add(bodyOverlay);
-
- leftArmGroup.Position = new Point3D(6f, 6f, 0f);
- leftArmGroup.RotationOrder = RotationOrders.ZX;
- leftArmGroup.MinDegrees1 = 0f;
- leftArmGroup.MaxDegrees1 = 160f;
- leftArmGroup.MinDegrees2 = -170f;
- leftArmGroup.MaxDegrees2 = 60f;
- leftArmGroup.Add(leftArm);
- leftArmGroup.Add(leftArmOverlay);
-
- rightArmGroup.Position = new Point3D(-6f, 6f, 0f);
- rightArmGroup.RotationOrder = RotationOrders.ZX;
- rightArmGroup.MinDegrees1 = -160f;
- rightArmGroup.MaxDegrees1 = 0f;
- rightArmGroup.MinDegrees2 = -170f;
- rightArmGroup.MaxDegrees2 = 60f;
- rightArmGroup.Add(rightArm);
- rightArmGroup.Add(rightArmOverlay);
-
- leftLegGroup.Position = new Point3D(2f, -4f, 0f);
- leftLegGroup.RotationOrder = RotationOrders.ZX;
- leftLegGroup.MinDegrees1 = 0f;
- leftLegGroup.MaxDegrees1 = 70f;
- leftLegGroup.MinDegrees2 = -110f;
- leftLegGroup.MaxDegrees2 = 60f;
- leftLegGroup.Add(leftLeg);
- leftLegGroup.Add(leftLegOverlay);
-
- rightLegGroup.Position = new Point3D(-2f, -4f, 0f);
- rightLegGroup.RotationOrder = RotationOrders.ZX;
- rightLegGroup.MinDegrees1 = -70f;
- rightLegGroup.MaxDegrees1 = 0f;
- rightLegGroup.MinDegrees2 = -110f;
- rightLegGroup.MaxDegrees2 = 60f;
- rightLegGroup.Add(rightLeg);
- rightLegGroup.Add(rightLegOverlay);
-
- modelView.AddDynamic(headGroup);
- modelView.AddStatic(bodyGroup);
- modelView.AddDynamic(rightArmGroup);
- modelView.AddDynamic(leftArmGroup);
- modelView.AddDynamic(rightLegGroup);
- modelView.AddDynamic(leftLegGroup);
- }
- }
-}
diff --git a/PCK-Studio/Classes/Models/Effects.cs b/PCK-Studio/Classes/Models/Effects.cs
deleted file mode 100644
index 418101b2..00000000
--- a/PCK-Studio/Classes/Models/Effects.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System;
-
-namespace PckStudio.Models
-{
- [Flags]
- public enum Effects : byte
- {
- None = 0,
- FlipHorizontally = 1,
- FlipVertically = 2
- }
-}
diff --git a/PCK-Studio/Classes/Models/Matrix3D.cs b/PCK-Studio/Classes/Models/Matrix3D.cs
deleted file mode 100644
index 071528dd..00000000
--- a/PCK-Studio/Classes/Models/Matrix3D.cs
+++ /dev/null
@@ -1,177 +0,0 @@
-using System;
-
-namespace PckStudio.Models
-{
- public struct Matrix3D
- {
- public Matrix3D(float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24, float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44)
- {
- M11 = m11;
- M12 = m12;
- M13 = m13;
- M14 = m14;
- M21 = m21;
- M22 = m22;
- M23 = m23;
- M24 = m24;
- M31 = m31;
- M32 = m32;
- M33 = m33;
- M34 = m34;
- M41 = m41;
- M42 = m42;
- M43 = m43;
- M44 = m44;
- }
-
- public static Matrix3D CreateRotationX(float radians)
- {
- float num = (float)Math.Sin((double)radians);
- float num2 = (float)Math.Cos((double)radians);
- return new Matrix3D(1f, 0f, 0f, 0f, 0f, num2, -num, 0f, 0f, num, num2, 0f, 0f, 0f, 0f, 1f);
- }
-
- public static Matrix3D CreateRotationX(float sin, float cos)
- {
- return new Matrix3D(1f, 0f, 0f, 0f, 0f, cos, -sin, 0f, 0f, sin, cos, 0f, 0f, 0f, 0f, 1f);
- }
-
- public static Matrix3D CreateRotationY(float radians)
- {
- float num = (float)Math.Sin((double)radians);
- float num2 = (float)Math.Cos((double)radians);
- return new Matrix3D(num2, 0f, num, 0f, 0f, 1f, 0f, 0f, -num, 0f, num2, 0f, 0f, 0f, 0f, 1f);
- }
-
- public static Matrix3D CreateRotationY(float sin, float cos)
- {
- return new Matrix3D(cos, 0f, sin, 0f, 0f, 1f, 0f, 0f, -sin, 0f, cos, 0f, 0f, 0f, 0f, 1f);
- }
-
- public static Matrix3D CreateRotationZ(float radians)
- {
- float num = (float)Math.Sin((double)radians);
- float num2 = (float)Math.Cos((double)radians);
- return new Matrix3D(num2, -num, 0f, 0f, num, num2, 0f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 0f, 1f);
- }
-
- public static Matrix3D CreateRotationZ(float sin, float cos)
- {
- return new Matrix3D(cos, -sin, 0f, 0f, sin, cos, 0f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 0f, 1f);
- }
-
- public static Matrix3D CreateTranslation(float x, float y, float z)
- {
- return new Matrix3D(1f, 0f, 0f, x, 0f, 1f, 0f, y, 0f, 0f, 1f, z, 0f, 0f, 0f, 1f);
- }
-
- public static Matrix3D CreateTranslation(Point3D point)
- {
- return new Matrix3D(1f, 0f, 0f, point.X, 0f, 1f, 0f, point.Y, 0f, 0f, 1f, point.Z, 0f, 0f, 0f, 1f);
- }
-
- public static Matrix3D CreateScale(float s)
- {
- return new Matrix3D(s, 0f, 0f, 0f, 0f, s, 0f, 0f, 0f, 0f, s, 0f, 0f, 0f, 0f, 1f);
- }
-
- public float Determinant
- {
- get
- {
- return M11 * M22 * M33 * M44 + M21 * M32 * M43 * M14 + M31 * M42 * M13 * M24 + M41 * M12 * M23 * M34 - M14 * M23 * M32 * M41 - M24 * M33 * M42 * M11 - M34 * M43 * M12 * M21 - M44 * M13 * M22 * M31;
- }
- }
-
- public static Matrix3D Identity
- {
- get
- {
- return new Matrix3D(1f, 0f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 0f, 1f);
- }
- }
-
- public static Matrix3D Transpose(Matrix3D m)
- {
- return new Matrix3D(m.M11, m.M21, m.M31, m.M41, m.M12, m.M22, m.M32, m.M42, m.M13, m.M23, m.M33, m.M43, m.M14, m.M24, m.M34, m.M44);
- }
-
- public static Matrix3D Invert(Matrix3D m)
- {
- float determinant = m.Determinant;
- return new Matrix3D((m.M22 * m.M33 * m.M44 + m.M32 * m.M43 * m.M24 + m.M42 * m.M23 * m.M34 - m.M24 * m.M33 * m.M42 - m.M34 * m.M43 * m.M22 - m.M44 * m.M23 * m.M32) / determinant, -(m.M12 * m.M33 * m.M44 + m.M32 * m.M43 * m.M14 + m.M42 * m.M13 * m.M34 - m.M14 * m.M33 * m.M42 - m.M34 * m.M43 * m.M12 - m.M44 * m.M13 * m.M32) / determinant, (m.M12 * m.M23 * m.M44 + m.M22 * m.M43 * m.M14 + m.M42 * m.M13 * m.M24 - m.M14 * m.M23 * m.M42 - m.M24 * m.M43 * m.M12 - m.M44 * m.M13 * m.M22) / determinant, -(m.M12 * m.M23 * m.M34 + m.M22 * m.M33 * m.M14 + m.M32 * m.M13 * m.M24 - m.M14 * m.M23 * m.M32 - m.M24 * m.M33 * m.M12 - m.M34 * m.M13 * m.M22) / determinant, -(m.M21 * m.M33 * m.M44 + m.M31 * m.M43 * m.M24 + m.M41 * m.M23 * m.M34 - m.M24 * m.M33 * m.M41 - m.M34 * m.M43 * m.M21 - m.M44 * m.M23 * m.M31) / determinant, (m.M11 * m.M33 * m.M44 + m.M31 * m.M43 * m.M14 + m.M41 * m.M13 * m.M34 - m.M14 * m.M33 * m.M41 - m.M34 * m.M43 * m.M11 - m.M44 * m.M13 * m.M31) / determinant, -(m.M11 * m.M23 * m.M44 + m.M21 * m.M43 * m.M14 + m.M41 * m.M13 * m.M24 - m.M14 * m.M23 * m.M41 - m.M24 * m.M43 * m.M11 - m.M44 * m.M13 * m.M21) / determinant, (m.M11 * m.M23 * m.M34 + m.M21 * m.M33 * m.M14 + m.M31 * m.M13 * m.M24 - m.M14 * m.M23 * m.M31 - m.M24 * m.M33 * m.M11 - m.M34 * m.M13 * m.M21) / determinant, (m.M21 * m.M32 * m.M44 + m.M31 * m.M42 * m.M24 + m.M41 * m.M22 * m.M34 - m.M24 * m.M32 * m.M41 - m.M34 * m.M42 * m.M21 - m.M44 * m.M22 * m.M31) / determinant, -(m.M11 * m.M32 * m.M44 + m.M31 * m.M42 * m.M14 + m.M41 * m.M12 * m.M34 - m.M14 * m.M32 * m.M41 - m.M34 * m.M42 * m.M11 - m.M44 * m.M12 * m.M31) / determinant, (m.M11 * m.M32 * m.M44 + m.M21 * m.M42 * m.M14 + m.M41 * m.M12 * m.M24 - m.M14 * m.M22 * m.M41 - m.M24 * m.M42 * m.M11 - m.M44 * m.M12 * m.M21) / determinant, -(m.M11 * m.M22 * m.M34 + m.M21 * m.M32 * m.M14 + m.M31 * m.M12 * m.M24 - m.M14 * m.M22 * m.M31 - m.M24 * m.M32 * m.M11 - m.M34 * m.M12 * m.M21) / determinant, -(m.M21 * m.M32 * m.M43 + m.M31 * m.M42 * m.M23 + m.M41 * m.M22 * m.M33 - m.M23 * m.M32 * m.M41 - m.M33 * m.M42 * m.M21 - m.M43 * m.M22 * m.M31) / determinant, (m.M11 * m.M32 * m.M43 + m.M31 * m.M42 * m.M13 + m.M41 * m.M12 * m.M33 - m.M13 * m.M32 * m.M41 - m.M33 * m.M42 * m.M11 - m.M43 * m.M12 * m.M31) / determinant, -(m.M11 * m.M22 * m.M43 + m.M21 * m.M42 * m.M13 + m.M41 * m.M12 * m.M23 - m.M13 * m.M22 * m.M41 - m.M23 * m.M42 * m.M11 - m.M43 * m.M12 * m.M21) / determinant, (m.M11 * m.M22 * m.M33 + m.M21 * m.M32 * m.M13 + m.M31 * m.M12 * m.M23 - m.M13 * m.M22 * m.M31 - m.M23 * m.M32 * m.M11 - m.M33 * m.M12 * m.M21) / determinant);
- }
-
- public static Matrix3D operator +(Matrix3D a, Matrix3D b)
- {
- return new Matrix3D(a.M11 + b.M11, a.M12 + b.M12, a.M13 + b.M13, a.M14 + b.M14, a.M21 + b.M21, a.M22 + b.M22, a.M23 + b.M23, a.M24 + b.M24, a.M31 + b.M31, a.M32 + b.M32, a.M33 + b.M33, a.M34 + b.M34, a.M41 + b.M41, a.M42 + b.M42, a.M43 + b.M43, a.M44 + b.M44);
- }
-
- public static Matrix3D operator -(Matrix3D a, Matrix3D b)
- {
- return new Matrix3D(a.M11 - b.M11, a.M12 - b.M12, a.M13 - b.M13, a.M14 - b.M14, a.M21 - b.M21, a.M22 - b.M22, a.M23 - b.M23, a.M24 - b.M24, a.M31 - b.M31, a.M32 - b.M32, a.M33 - b.M33, a.M34 - b.M34, a.M41 - b.M41, a.M42 - b.M42, a.M43 - b.M43, a.M44 - b.M44);
- }
-
- public static Matrix3D operator *(Matrix3D a, Matrix3D b)
- {
- return new Matrix3D(a.M11 * b.M11 + a.M12 * b.M21 + a.M13 * b.M31 + a.M14 * b.M41, a.M11 * b.M12 + a.M12 * b.M22 + a.M13 * b.M32 + a.M14 * b.M42, a.M11 * b.M13 + a.M12 * b.M23 + a.M13 * b.M33 + a.M14 * b.M43, a.M11 * b.M14 + a.M12 * b.M24 + a.M13 * b.M34 + a.M14 * b.M44, a.M21 * b.M11 + a.M22 * b.M21 + a.M23 * b.M31 + a.M24 * b.M41, a.M21 * b.M12 + a.M22 * b.M22 + a.M23 * b.M32 + a.M24 * b.M42, a.M21 * b.M13 + a.M22 * b.M23 + a.M23 * b.M33 + a.M24 * b.M43, a.M21 * b.M14 + a.M22 * b.M24 + a.M23 * b.M34 + a.M24 * b.M44, a.M31 * b.M11 + a.M32 * b.M21 + a.M33 * b.M31 + a.M34 * b.M41, a.M31 * b.M12 + a.M32 * b.M22 + a.M33 * b.M32 + a.M34 * b.M42, a.M31 * b.M13 + a.M32 * b.M23 + a.M33 * b.M33 + a.M34 * b.M43, a.M31 * b.M14 + a.M32 * b.M24 + a.M33 * b.M34 + a.M34 * b.M44, a.M41 * b.M11 + a.M42 * b.M21 + a.M43 * b.M31 + a.M44 * b.M41, a.M41 * b.M12 + a.M42 * b.M22 + a.M43 * b.M32 + a.M44 * b.M42, a.M41 * b.M13 + a.M42 * b.M23 + a.M43 * b.M33 + a.M44 * b.M43, a.M41 * b.M14 + a.M42 * b.M24 + a.M43 * b.M34 + a.M44 * b.M44);
- }
-
- public static Point3D operator *(Matrix3D m, Point3D p)
- {
- return new Point3D(p.X * m.M11 + p.Y * m.M12 + p.Z * m.M13 + m.M14, p.X * m.M21 + p.Y * m.M22 + p.Z * m.M23 + m.M24, p.X * m.M31 + p.Y * m.M32 + p.Z * m.M33 + m.M34);
- }
-
- public static Matrix3D operator +(Matrix3D m, float n)
- {
- return new Matrix3D(m.M11 + n, m.M12 + n, m.M13 + n, m.M14 + n, m.M21 + n, m.M22 + n, m.M23 + n, m.M24 + n, m.M31 + n, m.M32 + n, m.M33 + n, m.M34 + n, m.M41 + n, m.M42 + n, m.M43 + n, m.M44 + n);
- }
-
- public static Matrix3D operator -(Matrix3D m, float n)
- {
- return new Matrix3D(m.M11 - n, m.M12 - n, m.M13 - n, m.M14 - n, m.M21 - n, m.M22 - n, m.M23 - n, m.M24 - n, m.M31 - n, m.M32 - n, m.M33 - n, m.M34 - n, m.M41 - n, m.M42 - n, m.M43 - n, m.M44 - n);
- }
-
- public static Matrix3D operator *(Matrix3D m, float n)
- {
- return new Matrix3D(m.M11 * n, m.M12 * n, m.M13 * n, m.M14 * n, m.M21 * n, m.M22 * n, m.M23 * n, m.M24 * n, m.M31 * n, m.M32 * n, m.M33 * n, m.M34 * n, m.M41 * n, m.M42 * n, m.M43 * n, m.M44 * n);
- }
-
- public static Matrix3D operator /(Matrix3D m, float n)
- {
- return new Matrix3D(m.M11 / n, m.M12 / n, m.M13 / n, m.M14 / n, m.M21 / n, m.M22 / n, m.M23 / n, m.M24 / n, m.M31 / n, m.M32 / n, m.M33 / n, m.M34 / n, m.M41 / n, m.M42 / n, m.M43 / n, m.M44 / n);
- }
-
- public float M11;
-
- public float M12;
-
- public float M13;
-
- public float M14;
-
- public float M21;
-
- public float M22;
-
- public float M23;
-
- public float M24;
-
- public float M31;
-
- public float M32;
-
- public float M33;
-
- public float M34;
-
- public float M41;
-
- public float M42;
-
- public float M43;
-
- public float M44;
- }
-}
diff --git a/PCK-Studio/Classes/Models/ModelView.Designer.cs b/PCK-Studio/Classes/Models/ModelView.Designer.cs
deleted file mode 100644
index bfedcec8..00000000
--- a/PCK-Studio/Classes/Models/ModelView.Designer.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-
-namespace PckStudio.Models
-{
- partial class MinecraftModelView
- {
- ///
- /// 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 && this.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()
- {
- components = new System.ComponentModel.Container();
- }
-
-
- private PckStudio.Models.BackgroundTypes backgroundType;
-
- private System.Drawing.Brush backgroundBrush = new System.Drawing.SolidBrush(System.Drawing.Color.SkyBlue);
-
- private System.ComponentModel.BackgroundWorker downloader = new System.ComponentModel.BackgroundWorker();
-
- private System.Drawing.Point mouseLastLocation;
-
- private PckStudio.Models.Object3D rotatingObject3D;
-
- private System.Drawing.Color backgroundColor = System.Drawing.Color.Transparent;
-
- private System.Drawing.Color backgroundGradientColor1 = System.Drawing.SystemColors.ControlDarkDark;
-
- private System.Drawing.Color backgroundGradientColor2 = System.Drawing.SystemColors.ControlLightLight;
-
- private static System.Drawing.Color textShadowColor = System.Drawing.Color.FromArgb(0x3F, 0x3F, 0x3F);
-
- private System.Drawing.Image backgroundTexture;
-
- internal PckStudio.Models.Matrix3D GlobalTransformation = PckStudio.Models.Matrix3D.Identity;
-
- private System.Collections.Generic.List texelList = new System.Collections.Generic.List();
-
- private PckStudio.Models.TexelComparer texelComparer = new PckStudio.Models.TexelComparer();
-
- private System.Collections.Generic.List object3DList = new System.Collections.Generic.List();
-
- private System.Collections.Generic.List dynamicObject3DtList = new System.Collections.Generic.List();
- #endregion
- }
-}
diff --git a/PCK-Studio/Classes/Models/ModelView.cs b/PCK-Studio/Classes/Models/ModelView.cs
deleted file mode 100644
index 070e51ec..00000000
--- a/PCK-Studio/Classes/Models/ModelView.cs
+++ /dev/null
@@ -1,431 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Drawing.Drawing2D;
-using System.Drawing.Imaging;
-using System.Drawing.Text;
-using System.IO;
-using System.Net;
-using System.Threading;
-using System.Windows.Forms;
-
-namespace PckStudio.Models
-{
- public partial class MinecraftModelView : Control
- {
- private const int IsometricFOV = 46;
-
- internal float cameraZ = 31.4285717f;
-
- private int Fov = 70;
-
- private float scale = 1f;
-
- internal float RotationX;
-
- internal float RotationY;
-
- private bool perspective = true;
-
- private float PiBy180 = 0.0174532924f;
-
- protected override void OnBackColorChanged(EventArgs e)
- {
- base.OnBackColorChanged(e);
- backgroundColor = BackColor;
- UpdateBackgroundBrush();
- Invalidate();
- }
-
- [Browsable(true)]
- [Category("Appearance")]
- public System.Drawing.Color BackGradientColor1
- {
- get
- {
- return backgroundGradientColor1;
- }
- set
- {
- backgroundGradientColor1 = value;
- UpdateBackgroundBrush();
- Invalidate();
- }
- }
-
- [Browsable(true)]
- [Category("Appearance")]
- public System.Drawing.Color BackGradientColor2
- {
- get
- {
- return backgroundGradientColor2;
- }
- set
- {
- backgroundGradientColor2 = value;
- UpdateBackgroundBrush();
- Invalidate();
- }
- }
-
- [Browsable(true)]
- [Category("Appearance")]
- public new System.Drawing.Image BackgroundImage
- {
- get
- {
- return backgroundTexture;
- }
- set
- {
- backgroundTexture = value;
- UpdateBackgroundBrush();
- Invalidate();
- }
- }
-
- [Browsable(true)]
- [Category("Appearance")]
- public BackgroundTypes BackgroundType
- {
- get
- {
- return backgroundType;
- }
- set
- {
- backgroundType = value;
- UpdateBackgroundBrush();
- Invalidate();
- }
- }
-
- [Browsable(true)]
- [Category("View")]
- public ProjectionTypes Projection
- {
- get
- {
- return perspective ? ProjectionTypes.Perspective : ProjectionTypes.Isometric;
- }
- set
- {
- perspective = value == ProjectionTypes.Perspective;
- SetupProjection();
- foreach (Object3D object3D in object3DList)
- {
- object3D.Update();
- }
- Invalidate();
- }
- }
-
- [Browsable(true)]
- [Category("View")]
- public int FOV
- {
- get
- {
- return Fov;
- }
- set
- {
- Fov = value;
- SetupProjection();
- foreach (Object3D object3D in object3DList)
- {
- object3D.Update();
- }
- Invalidate();
- }
- }
-
- [Browsable(true)]
- [Category("View")]
- public int DegreesX
- {
- get
- {
- return (int)RotationX;
- }
- set
- {
- RotationX = value;
- Matrix3D globalTransformation = Matrix3D.CreateRotationX(RotationX * PiBy180) * Matrix3D.CreateRotationY(RotationY * PiBy180);
- foreach (Object3D object3D in object3DList)
- {
- object3D.GlobalTransformation = globalTransformation;
- }
- Invalidate();
- }
- }
-
- [Browsable(true)]
- [Category("View")]
- public int DegreesY
- {
- get
- {
- return (int)RotationY;
- }
- set
- {
- RotationY = value;
- Matrix3D globalTransformation = Matrix3D.CreateRotationX(RotationX * PiBy180) * Matrix3D.CreateRotationY(RotationY * PiBy180);
- foreach (Object3D object3D in object3DList)
- {
- object3D.GlobalTransformation = globalTransformation;
- }
- Invalidate();
- }
- }
-
- public ModelBase Model
- {
- set
- {
- Clear();
- value.AddToModelView(this);
- Matrix3D globalTransformation = Matrix3D.CreateRotationX(RotationX * 3.14159274f / 180f) * Matrix3D.CreateRotationY(RotationY * 3.14159274f / 180f);
- foreach (Object3D object3D in object3DList)
- {
- object3D.GlobalTransformation = globalTransformation;
- }
- Invalidate();
- }
- }
-
- private void Clear()
- {
- texelList.Clear();
- object3DList.Clear();
- dynamicObject3DtList.Clear();
- rotatingObject3D = null;
- }
-
- protected override void OnPaintBackground(PaintEventArgs pevent)
- {
- base.OnPaintBackground(pevent);
- System.Drawing.Graphics graphics = pevent.Graphics;
- graphics.CompositingQuality = CompositingQuality.HighSpeed;
- graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
- graphics.PixelOffsetMode = PixelOffsetMode.HighSpeed;
- graphics.SmoothingMode = SmoothingMode.HighSpeed;
- graphics.CompositingMode = CompositingMode.SourceCopy;
- graphics.FillRectangle(backgroundBrush, ClientRectangle);
- graphics.CompositingMode = CompositingMode.SourceOver;
- }
-
- protected override void OnPaint(PaintEventArgs pe)
- {
- texelList.Sort(texelComparer);
- System.Drawing.Graphics graphics = pe.Graphics;
- graphics.TranslateTransform(Width / 2, Height / 2);
- graphics.ScaleTransform(scale, -scale);
- graphics.CompositingQuality = CompositingQuality.HighSpeed;
- graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
- graphics.PixelOffsetMode = PixelOffsetMode.HighSpeed;
- graphics.SmoothingMode = SmoothingMode.HighSpeed;
- graphics.CompositingMode = CompositingMode.SourceCopy;
- for (int i = 0; i < texelList.Count; i++)
- {
- texelList[i].Draw(graphics);
- }
- }
-
- public System.Drawing.Image RenderToImage(System.Drawing.Size size, System.Drawing.RectangleF crop)
- {
- if (size.Width / size.Height != crop.Width / crop.Height)
- {
- throw new ArgumentException("Aspect ratio is ambiguous");
- }
- System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(size.Width, size.Height);
- using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(bitmap))
- {
- System.Drawing.Size size2 = new System.Drawing.Size((int)(size.Width / crop.Width), (int)(size.Height / crop.Height));
- texelList.Sort(texelComparer);
- graphics.TranslateTransform(-crop.Left * size2.Width, -crop.Top * size2.Height);
- graphics.TranslateTransform(size2.Width / 2, size2.Height / 2);
- float num = Math.Min(size2.Width, size2.Height) * 0.01f / (float)Math.Tan((perspective ? Fov : IsometricFOV) * 3.1415926535897931 / 360.0);
- graphics.ScaleTransform(num, -num);
- graphics.CompositingQuality = CompositingQuality.HighSpeed;
- graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
- graphics.PixelOffsetMode = PixelOffsetMode.HighSpeed;
- graphics.SmoothingMode = SmoothingMode.HighSpeed;
- graphics.Clear(System.Drawing.Color.Transparent);
- for (int i = 0; i < texelList.Count; i++)
- {
- texelList[i].Draw(graphics);
- }
- }
- return bitmap;
- }
-
- private System.Drawing.Image RenderVersionText()
- {
- System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(0x154, 0x12);
- Version version = new Version(Application.ProductVersion);
- string s = string.Format("{0} {1}.{2}{3}", Application.ProductName, version.Major, version.Minor, (version.Build != 0) ? ("." + version.Build) : "");
- using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(bitmap))
- {
- using (System.Drawing.Brush brush = new System.Drawing.SolidBrush(System.Drawing.Color.FromArgb(0x7F, System.Drawing.Color.Gray)))
- {
- graphics.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;
- graphics.DrawString(s, Font, brush, 1f, 1f);
- graphics.DrawString(s, Font, System.Drawing.Brushes.White, 0f, 0f);
- }
- }
- return bitmap;
- }
-
- private void UpdateBackgroundBrush()
- {
- backgroundBrush = ((backgroundType == BackgroundTypes.Texture) ? new System.Drawing.TextureBrush(backgroundTexture) : ((backgroundType == BackgroundTypes.Gradient) ? new System.Drawing.Drawing2D.LinearGradientBrush(new System.Drawing.Point(0, 0), new System.Drawing.Point(0, System.Math.Max(1, base.Height)), backgroundGradientColor1, backgroundGradientColor2) : new System.Drawing.SolidBrush(backgroundColor)));
- }
-
- public System.Drawing.Brush GetBackgroundBrush(System.Drawing.Size size)
- {
- if (backgroundType == BackgroundTypes.Texture)
- {
- return new System.Drawing.TextureBrush(backgroundTexture);
- }
- if (backgroundType != BackgroundTypes.Gradient)
- {
- return new System.Drawing.SolidBrush(backgroundColor);
- }
- return new LinearGradientBrush(new System.Drawing.Point(0, 0), new System.Drawing.Point(0, Math.Max(1, size.Height)), backgroundGradientColor1, backgroundGradientColor2);
- }
-
- private void SetupProjection()
- {
- cameraZ = 2400f / Fov;
- scale = Math.Min(Width, Height) * 0.01f / (float)Math.Tan((perspective ? Fov : IsometricFOV) * Math.PI / 360.0);
- }
-
- protected override void OnResize(EventArgs e)
- {
- SetupProjection();
- UpdateBackgroundBrush();
- base.OnResize(e);
- }
-
- internal void RemoveTexelsOf(TexturePlane texturePlane)
- {
- for (int i = 0; i < texelList.Count; i++)
- {
- if (texelList[i].TexturePlane == texturePlane)
- {
- texelList.RemoveAt(i);
- i--;
- }
- }
- }
-
- internal void AddTexel(Texel texel)
- {
- texelList.Add(texel);
- }
-
- protected override void OnMouseDown(MouseEventArgs e)
- {
- base.OnMouseDown(e);
- System.Drawing.PointF location = new System.Drawing.PointF((e.X - Width * 0.5f) / scale, -(e.Y - Height * 0.5f) / scale);
- rotatingObject3D = null;
- Object3D item = null;
- float num = -1000f;
- foreach (Object3D object3D in object3DList)
- {
- float num2 = object3D.HitTest(location);
- if (num2 > num)
- {
- num = num2;
- item = object3D;
- }
- }
- if (num > -1000f && dynamicObject3DtList.Contains(item))
- {
- rotatingObject3D = item;
- }
- mouseLastLocation = e.Location;
- Invalidate();
- }
-
- protected override void OnMouseUp(MouseEventArgs e)
- {
- base.OnMouseUp(e);
- rotatingObject3D = null;
- }
-
- protected override void OnMouseMove(MouseEventArgs e)
- {
- base.OnMouseMove(e);
- if (e.Button != MouseButtons.Left)
- {
- return;
- }
- if (rotatingObject3D != null)
- {
- rotatingObject3D.RotateByMouse((e.X - mouseLastLocation.X) * 400f / Height, (e.Y - mouseLastLocation.Y) * 400f / Height);
- mouseLastLocation = e.Location;
- Invalidate();
- return;
- }
- RotationY += (e.X - mouseLastLocation.X) * 400f / Height;
- RotationX += (e.Y - mouseLastLocation.Y) * 400f / Height;
- mouseLastLocation = e.Location;
- Matrix3D globalTransformation = Matrix3D.CreateRotationX(RotationX * 3.14159274f / 180f) * Matrix3D.CreateRotationY(RotationY * 3.14159274f / 180f);
- foreach (Object3D object3D in object3DList)
- {
- object3D.GlobalTransformation = globalTransformation;
- }
- Invalidate();
- }
-
- public void AddStatic(Object3D object3D)
- {
- object3D.Viewport = this;
- object3DList.Add(object3D);
- foreach (Object3D object3D2 in object3DList)
- {
- object3D2.Update();
- }
- }
-
- public void AddDynamic(Object3D object3D)
- {
- AddStatic(object3D);
- dynamicObject3DtList.Add(object3D);
- }
-
- internal System.Drawing.PointF Point3DTo2D(Point3D point3D)
- {
- if (perspective)
- {
- return new System.Drawing.PointF(point3D.X * (-50f / (point3D.Z - cameraZ)), point3D.Y * (-50f / (point3D.Z - cameraZ)));
- }
- return new System.Drawing.PointF(point3D.X, point3D.Y);
- }
-
- internal float GetZOrder(Point3D point3D)
- {
- if (perspective)
- {
- return point3D.X * point3D.X + point3D.Y * point3D.Y + (cameraZ - point3D.Z) * (cameraZ - point3D.Z);
- }
- return -point3D.Z;
- }
-
- public MinecraftModelView()
- {
- SetStyle(ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
- InitializeComponent();
- texelComparer = new TexelComparer();
- }
-
- public MinecraftModelView(IContainer container) : this()
- {
- container.Add(this);
- }
- }
-}
diff --git a/PCK-Studio/Classes/Models/Object3D.cs b/PCK-Studio/Classes/Models/Object3D.cs
deleted file mode 100644
index f9aa9f6a..00000000
--- a/PCK-Studio/Classes/Models/Object3D.cs
+++ /dev/null
@@ -1,461 +0,0 @@
-using System;
-using System.Drawing;
-
-namespace PckStudio.Models
-{
- public abstract class Object3D
- {
- public abstract Image Image { set; }
-
- public float Angle1
- {
- get
- {
- return angle1;
- }
- set
- {
- angle1 = value;
- OnUpdateRotation();
- }
- }
-
- public float Angle2
- {
- get
- {
- return angle2;
- }
- set
- {
- angle2 = value;
- OnUpdateRotation();
- }
- }
-
- public float MinAngle1
- {
- get
- {
- return minAngle1;
- }
- set
- {
- minAngle1 = value;
- }
- }
-
- public float MinAngle2
- {
- get
- {
- return minAngle2;
- }
- set
- {
- minAngle2 = value;
- }
- }
-
- public float MaxAngle1
- {
- get
- {
- return maxAngle1;
- }
- set
- {
- maxAngle1 = value;
- }
- }
-
- public float MaxAngle2
- {
- get
- {
- return maxAngle2;
- }
- set
- {
- maxAngle2 = value;
- }
- }
-
- public float AngleRange1
- {
- get
- {
- return maxAngle1 - minAngle1;
- }
- set
- {
- minAngle1 = angle1 - value / 2f;
- maxAngle1 = angle1 + value / 2f;
- }
- }
-
- public float AngleRange2
- {
- get
- {
- return maxAngle2 - minAngle2;
- }
- set
- {
- minAngle2 = angle2 - value / 2f;
- maxAngle2 = angle2 + value / 2f;
- }
- }
-
- public float MinDegrees1
- {
- get
- {
- return minAngle1 / PIby180;
- }
- set
- {
- minAngle1 = value * PIby180;
- }
- }
-
- public float MinDegrees2
- {
- get
- {
- return minAngle2 / PIby180;
- }
- set
- {
- minAngle2 = value * PIby180;
- }
- }
-
- public float MaxDegrees1
- {
- get
- {
- return maxAngle1 / PIby180;
- }
- set
- {
- maxAngle1 = value * PIby180;
- }
- }
-
- public float MaxDegrees2
- {
- get
- {
- return maxAngle2 / PIby180;
- }
- set
- {
- maxAngle2 = value * PIby180;
- }
- }
-
- public float DegreesRange1
- {
- get
- {
- return AngleRange1 / PIby180;
- }
- set
- {
- AngleRange1 = value * PIby180;
- }
- }
-
- public float DegreesRange2
- {
- get
- {
- return AngleRange2 / PIby180;
- }
- set
- {
- AngleRange2 = value * PIby180;
- }
- }
-
- public float Scale
- {
- get
- {
- return scaleTransformation.M11;
- }
- set
- {
- scaleTransformation = Matrix3D.CreateScale(value);
- UpdateRotation();
- }
- }
-
- public RotationOrders RotationOrder
- {
- get
- {
- return order;
- }
- set
- {
- order = value;
- switch (order)
- {
- case RotationOrders.XY:
- Rotate = new RotateMethod(RotateXY);
- OnUpdateRotation = UpdateRotationXY;
- return;
- case RotationOrders.YX:
- Rotate = new RotateMethod(RotateYX);
- OnUpdateRotation = UpdateRotationYX;
- return;
- case RotationOrders.XZ:
- Rotate = new RotateMethod(RotateXZ);
- OnUpdateRotation = UpdateRotationXZ;
- return;
- case RotationOrders.ZX:
- Rotate = new RotateMethod(RotateZX);
- OnUpdateRotation = UpdateRotationZX;
- return;
- case RotationOrders.YZ:
- Rotate = new RotateMethod(RotateYZ);
- OnUpdateRotation = UpdateRotationYZ;
- return;
- case RotationOrders.ZY:
- Rotate = new RotateMethod(RotateZY);
- OnUpdateRotation = UpdateRotationZY;
- return;
- default:
- return;
- }
- }
- }
-
- internal virtual MinecraftModelView Viewport
- {
- set
- {
- viewport = value;
- }
- }
-
- public Point3D Origin
- {
- get
- {
- return new Point3D(-originTranslation.M14, -originTranslation.M24, -originTranslation.M34);
- }
- set
- {
- originTranslation = Matrix3D.CreateTranslation(-value.X, -value.Y, -value.Z);
- UpdateRotation();
- }
- }
-
- public Point3D Position
- {
- get
- {
- return new Point3D(positionTranslation.M14, positionTranslation.M24, positionTranslation.M34);
- }
- set
- {
- positionTranslation = Matrix3D.CreateTranslation(value);
- UpdateRotation();
- Update();
- }
- }
-
- internal abstract void Update();
-
- public Matrix3D GlobalTransformation
- {
- get
- {
- return globalTransformation;
- }
- set
- {
- globalTransformation = value;
- Update();
- }
- }
-
- public Matrix3D LocalTransformation
- {
- get
- {
- return localTransformation;
- }
- set
- {
- localTransformation = value;
- Update();
- }
- }
-
- public void SetRotation(float angle1, float angle2)
- {
- this.angle1 = angle1;
- this.angle2 = angle2;
- OnUpdateRotation();
- }
-
- public void RotateByMouse(float deltaX, float deltaY)
- {
- if (Rotate != null)
- {
- Rotate(deltaX, deltaY);
- Update();
- }
- }
-
- private void CorrectAngles()
- {
- if (angle1 > maxAngle1)
- {
- angle1 = maxAngle1;
- }
- else if (angle1 < minAngle1)
- {
- angle1 = minAngle1;
- }
- if (angle2 > maxAngle2)
- {
- angle2 = maxAngle2;
- return;
- }
- if (angle2 < minAngle2)
- {
- angle2 = minAngle2;
- }
- }
-
- public abstract float HitTest(PointF location);
-
- private void RotateXY(float delta1, float delta2)
- {
- angle1 += delta1 * PIby180;
- angle2 += delta2 * PIby180 * (float)Math.Cos((double)(viewport.RotationY * PIby180));
- UpdateRotationXY();
- }
-
- private void RotateYX(float delta1, float delta2)
- {
- angle1 += delta1 * PIby180;
- angle2 += delta2 * PIby180 * (float)Math.Cos(viewport.RotationY * 3.1415926535897931 / 180.0);
- UpdateRotationYX();
- }
-
- private void RotateXZ(float delta1, float delta2)
- {
- angle1 += delta1 * PIby180 * (float)Math.Cos((double)(viewport.RotationY * PIby180)) + delta2 * PIby180 * (float)Math.Sin((double)(viewport.RotationY * PIby180));
- angle2 += delta2 * PIby180 * (float)Math.Cos((double)(viewport.RotationY * PIby180)) - delta1 * PIby180 * (float)Math.Sin((double)(viewport.RotationY * PIby180));
- UpdateRotationXZ();
- }
-
- private void RotateZX(float delta1, float delta2)
- {
- angle1 += delta1 * PIby180 * (float)Math.Cos((double)(viewport.RotationY * PIby180)) + delta2 * PIby180 * (float)Math.Sin((double)(viewport.RotationY * PIby180));
- angle2 += delta2 * PIby180 * (float)Math.Cos((double)(viewport.RotationY * PIby180)) - delta1 * PIby180 * (float)Math.Sin((double)(viewport.RotationY * PIby180));
- UpdateRotationZX();
- }
-
- private void RotateZY(float delta1, float delta2)
- {
- angle1 -= delta2 * PIby180;
- angle2 += delta1 * PIby180;
- UpdateRotationZY();
- }
-
- private void RotateYZ(float delta1, float delta2)
- {
- angle1 += delta1 * PIby180;
- angle2 += delta2 * PIby180 * (float)Math.Sin((double)(viewport.RotationY * PIby180));
- UpdateRotationYZ();
- }
-
- private void UpdateRotationXY()
- {
- CorrectAngles();
- localRotation = Matrix3D.CreateRotationY(angle1) * Matrix3D.CreateRotationX(angle2);
- UpdateRotation();
- }
-
- private void UpdateRotationYX()
- {
- CorrectAngles();
- localRotation = Matrix3D.CreateRotationX(angle2) * Matrix3D.CreateRotationY(angle1);
- UpdateRotation();
- }
-
- private void UpdateRotationXZ()
- {
- CorrectAngles();
- localRotation = Matrix3D.CreateRotationZ(angle1) * Matrix3D.CreateRotationX(angle2);
- UpdateRotation();
- }
-
- private void UpdateRotationZX()
- {
- CorrectAngles();
- localRotation = Matrix3D.CreateRotationX(angle2) * Matrix3D.CreateRotationZ(angle1);
- UpdateRotation();
- }
-
- private void UpdateRotationZY()
- {
- CorrectAngles();
- localRotation = Matrix3D.CreateRotationY(angle2) * Matrix3D.CreateRotationZ(angle1);
- UpdateRotation();
- }
-
- private void UpdateRotationYZ()
- {
- CorrectAngles();
- localRotation = Matrix3D.CreateRotationZ(angle2) * Matrix3D.CreateRotationY(angle1);
- UpdateRotation();
- }
-
- private void UpdateRotation()
- {
- localTransformation = positionTranslation * localRotation * originTranslation * scaleTransformation;
- }
-
- public const float PIby180 = 0.0174532924f;
-
- protected Matrix3D originTranslation = Matrix3D.Identity;
-
- protected Matrix3D positionTranslation = Matrix3D.Identity;
-
- protected Matrix3D scaleTransformation = Matrix3D.Identity;
-
- protected Matrix3D localRotation = Matrix3D.Identity;
-
- protected Matrix3D localTransformation = Matrix3D.Identity;
-
- protected Matrix3D globalTransformation = Matrix3D.Identity;
-
- private float angle1;
-
- private float angle2;
-
- private float maxAngle1 = (float)Math.PI;
- private float minAngle1 = (float)-Math.PI;
-
- private float maxAngle2 = (float)Math.PI;
- private float minAngle2 = (float)-Math.PI;
-
- private RotationOrders order;
-
- protected MinecraftModelView viewport;
-
- private RotateMethod Rotate;
-
- private Action OnUpdateRotation;
-
- private delegate void RotateMethod(float deltaX, float deltaY);
- }
-}
diff --git a/PCK-Studio/Classes/Models/Object3DGroup.cs b/PCK-Studio/Classes/Models/Object3DGroup.cs
deleted file mode 100644
index fc3cd524..00000000
--- a/PCK-Studio/Classes/Models/Object3DGroup.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace PckStudio.Models
-{
- public class Object3DGroup : Object3D
- {
- internal override MinecraftModelView Viewport
- {
- set
- {
- base.Viewport = value;
- foreach (Object3D object3D in objects)
- {
- object3D.Viewport = value;
- }
- }
- }
-
- public override System.Drawing.Image Image
- {
- set
- {
- foreach (Object3D object3D in objects)
- {
- object3D.Image = value;
- }
- }
- }
-
- internal override void Update()
- {
- Matrix3D globalTransformation = this.globalTransformation * localTransformation;
- for (int i = 0; i < objects.Count; i++)
- {
- objects[i].GlobalTransformation = globalTransformation;
- }
- }
-
- public override float HitTest(System.Drawing.PointF location)
- {
- float num = -1000f;
- foreach (Object3D object3D in objects)
- {
- float num2 = object3D.HitTest(location);
- if (num2 > num)
- {
- num = num2;
- }
- }
- return num;
- }
-
- public void Add(Object3D object3D)
- {
- if (object3D == this)
- {
- throw new ArgumentException("Cannot add Object3D into itself.");
- }
- objects.Add(object3D);
- }
-
- private List objects = new List();
- }
-}
diff --git a/PCK-Studio/Classes/Models/Point3D.cs b/PCK-Studio/Classes/Models/Point3D.cs
deleted file mode 100644
index e69ebf0b..00000000
--- a/PCK-Studio/Classes/Models/Point3D.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using System;
-
-namespace PckStudio.Models
-{
- public struct Point3D
- {
- public float X;
- public float Y;
- public float Z;
-
- public Point3D(float x, float y, float z)
- {
- (X, Y, Z) = (x, y, z);
- }
-
- public static Point3D Zero => default(Point3D);
-
- public override string ToString()
- {
- return string.Format("({0};{1};{2})", X, Y, Z);
- }
-
- public static Point3D operator +(Point3D a, Point3D b) => new Point3D(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
-
- public static Point3D operator -(Point3D a, Point3D b) => new Point3D(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
-
- public static Point3D operator *(Point3D p, float s) => new Point3D(p.X * s, p.Y * s, p.Z * s);
-
- public static Point3D operator /(Point3D p, float s) => new Point3D(p.X / s, p.Y / s, p.Z / s);
- }
-}
diff --git a/PCK-Studio/Classes/Models/Positions.cs b/PCK-Studio/Classes/Models/Positions.cs
deleted file mode 100644
index 004ba901..00000000
--- a/PCK-Studio/Classes/Models/Positions.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-
-namespace PckStudio.Models
-{
- public enum Positions
- {
- Default,
- Outstretched,
- Walking,
- Running,
- Sitting,
- Zombie
- }
-}
diff --git a/PCK-Studio/Classes/Models/ProjectionTypes.cs b/PCK-Studio/Classes/Models/ProjectionTypes.cs
deleted file mode 100644
index 04d81550..00000000
--- a/PCK-Studio/Classes/Models/ProjectionTypes.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System;
-
-namespace PckStudio.Models
-{
- public enum ProjectionTypes : byte
- {
- Perspective,
- Isometric
- }
-}
diff --git a/PCK-Studio/Classes/Models/RotationOrders.cs b/PCK-Studio/Classes/Models/RotationOrders.cs
deleted file mode 100644
index 0ca2c041..00000000
--- a/PCK-Studio/Classes/Models/RotationOrders.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-
-namespace PckStudio.Models
-{
- public enum RotationOrders : byte
- {
- XY,
- YX,
- XZ,
- ZX,
- YZ,
- ZY
- }
-}
diff --git a/PCK-Studio/Classes/Models/Texel.cs b/PCK-Studio/Classes/Models/Texel.cs
deleted file mode 100644
index 736bcb21..00000000
--- a/PCK-Studio/Classes/Models/Texel.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using System;
-
-namespace PckStudio.Models
-{
- internal struct Texel
- {
- internal Texel(TexturePlane texturePlane, int x, int y, System.Drawing.Color color)
- {
- TexturePlane = texturePlane;
- X = x;
- Y = y;
- this.color = color;
- brush = new System.Drawing.SolidBrush(color);
- pen = new System.Drawing.Pen(System.Drawing.Color.White, 0.01f);
- }
-
- internal double Z
- {
- get
- {
- return TexturePlane.ZOrder[X + 1, Y + 1];
- }
- }
-
- internal void Draw(System.Drawing.Graphics g)
- {
- System.Drawing.PointF[] points = new System.Drawing.PointF[]
- {
- TexturePlane.Points[X, Y],
- TexturePlane.Points[X + 1, Y],
- TexturePlane.Points[X + 1, Y + 1],
- TexturePlane.Points[X, Y + 1]
- };
- g.FillPolygon(brush, points);
- }
-
- internal TexturePlane TexturePlane;
-
- internal int X;
-
- internal int Y;
-
- private System.Drawing.Color color;
-
- private System.Drawing.Brush brush;
-
- private System.Drawing.Pen pen;
- }
-}
diff --git a/PCK-Studio/Classes/Models/TexelComparer.cs b/PCK-Studio/Classes/Models/TexelComparer.cs
deleted file mode 100644
index d7187760..00000000
--- a/PCK-Studio/Classes/Models/TexelComparer.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace PckStudio.Models
-{
- internal class TexelComparer : IComparer
- {
- public int Compare(Texel x, Texel y)
- {
- return -x.Z.CompareTo(y.Z);
- }
-
- public TexelComparer()
- {
- }
- }
-}
diff --git a/PCK-Studio/Classes/Models/TexturePlane.cs b/PCK-Studio/Classes/Models/TexturePlane.cs
deleted file mode 100644
index 0b7b7edf..00000000
--- a/PCK-Studio/Classes/Models/TexturePlane.cs
+++ /dev/null
@@ -1,189 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Drawing.Drawing2D;
-using System.Drawing.Imaging;
-using System.Drawing;
-
-namespace PckStudio.Models
-{
- public class TexturePlane : Object3D
- {
- public override Image Image
- {
- set
- {
- Bitmap = (Bitmap)value;
- }
- }
-
- internal override MinecraftModelView Viewport
- {
- set
- {
- base.Viewport = value;
- if (bitmap != null && value != null)
- {
- UpdateBitmap();
- }
- }
- }
-
- internal override void Update()
- {
- if (Points == null || viewport == null)
- {
- return;
- }
- Matrix3D m = globalTransformation * localTransformation * originTranslation;
- for (int i = 0; i <= width; i++)
- {
- for (int j = 0; j <= height; j++)
- {
- Point3D point3D = m * new Point3D(i, j, 0f);
- Points[i, j] = viewport.Point3DTo2D(point3D);
- double num = (double)viewport.GetZOrder(point3D);
- ZOrder[i, j] += num;
- ZOrder[i + 1, j] += num;
- ZOrder[i, j + 1] += num;
- ZOrder[i + 1, j + 1] = num;
- }
- }
- }
-
- private Bitmap Bitmap
- {
- set
- {
- if (viewport == null)
- {
- bitmap = value;
- return;
- }
- texelList.Clear();
- if (bitmap != null)
- {
- viewport.RemoveTexelsOf(this);
- Points = null;
- }
- bitmap = value;
- if (bitmap != null)
- {
- UpdateBitmap();
- Update();
- }
- }
- }
-
- private void UpdateBitmap()
- {
- width = bitmap.Width;
- height = bitmap.Height;
- visibility = new bool[width, height];
- for (int i = 0; i < width; i++)
- {
- for (int j = 0; j < height; j++)
- {
- Color pixel = bitmap.GetPixel(i, j);
- int num = flipHorizontally ? (width - i - 1) : i;
- int num2 = flipVertically ? j : (height - j - 1);
- if (pixel.A == 0)
- {
- visibility[num, num2] = false;
- }
- else
- {
- visibility[num, num2] = true;
- Texel texel = new Texel(this, num, num2, pixel);
- viewport.AddTexel(texel);
- texelList.Add(texel);
- }
- }
- }
- Points = new PointF[width + 1, height + 1];
- ZOrder = new double[width + 2, height + 2];
- }
-
- public TexturePlane(Image bitmap, Rectangle srcRect, Point3D origin, Point3D normal, Effects effects)
- {
- Origin = origin;
- this.normal = normal;
- if (bitmap == null)
- {
- Bitmap = null;
- return;
- }
- Bitmap bitmap2 = new Bitmap(srcRect.Width, srcRect.Height);
- using (Graphics graphics = Graphics.FromImage(bitmap2))
- {
- graphics.DrawImage(bitmap, new Rectangle(0, 0, bitmap2.Width, bitmap2.Height), srcRect, GraphicsUnit.Pixel);
- }
- flipHorizontally = (byte)(effects & Effects.FlipHorizontally) == 1;
- flipVertically = (byte)(effects & Effects.FlipVertically) == 2;
- Bitmap = bitmap2;
- }
-
- public override float HitTest(PointF location)
- {
- if (Points == null)
- {
- return -1000f;
- }
- GraphicsPath graphicsPath = new GraphicsPath();
- graphicsPath.AddPolygon(new PointF[]
- {
- Points[0, 0],
- Points[Points.GetLength(0) - 1, 0],
- Points[Points.GetLength(0) - 1, Points.GetLength(1) - 1],
- Points[0, Points.GetLength(1) - 1]
- });
- Region region = new Region(graphicsPath);
- if (region.IsVisible(location))
- {
- for (int i = 0; i < Points.GetLength(0) - 1; i++)
- {
- for (int j = 0; j < Points.GetLength(1) - 1; j++)
- {
- if (visibility[i, j])
- {
- graphicsPath.Reset();
- graphicsPath.AddPolygon(new PointF[]
- {
- Points[i, j],
- Points[i + 1, j],
- Points[i + 1, j + 1],
- Points[i, j + 1]
- });
- if (graphicsPath.IsVisible(location))
- {
- return (globalTransformation * localTransformation * originTranslation * new Point3D(i, j, 0f)).Z;
- }
- }
- }
- }
- }
- return -1000f;
- }
-
- private List texelList = new List();
-
- internal PointF[,] Points;
-
- internal double[,] ZOrder;
-
- internal bool IsVisible = true;
-
- private bool[,] visibility;
-
- private Bitmap bitmap;
-
- private bool flipHorizontally;
-
- private bool flipVertically;
-
- private int width;
-
- private int height;
-
- private Point3D normal;
- }
-}
diff --git a/PCK-Studio/Controls/BoxEditorControl.Designer.cs b/PCK-Studio/Controls/BoxEditorControl.Designer.cs
new file mode 100644
index 00000000..eb60c040
--- /dev/null
+++ b/PCK-Studio/Controls/BoxEditorControl.Designer.cs
@@ -0,0 +1,444 @@
+namespace PckStudio.Controls
+{
+ partial class BoxEditorControl
+ {
+ ///
+ /// 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.parentLabel = new MetroFramework.Controls.MetroLabel();
+ this.positionLabel = new MetroFramework.Controls.MetroLabel();
+ this.sizeLabel = new MetroFramework.Controls.MetroLabel();
+ this.uvLabel = new MetroFramework.Controls.MetroLabel();
+ this.inflationLabel = new MetroFramework.Controls.MetroLabel();
+ this.toolTip = new MetroFramework.Components.MetroToolTip();
+ this.parentComboBox = new MetroFramework.Controls.MetroComboBox();
+ this.PosXUpDown = new System.Windows.Forms.NumericUpDown();
+ this.PosYUpDown = new System.Windows.Forms.NumericUpDown();
+ this.PosZUpDown = new System.Windows.Forms.NumericUpDown();
+ this.SizeZUpDown = new System.Windows.Forms.NumericUpDown();
+ this.SizeYUpDown = new System.Windows.Forms.NumericUpDown();
+ this.SizeXUpDown = new System.Windows.Forms.NumericUpDown();
+ this.uvYUpDown = new System.Windows.Forms.NumericUpDown();
+ this.uvXUpDown = new System.Windows.Forms.NumericUpDown();
+ this.helmetCheckBox = new MetroFramework.Controls.MetroCheckBox();
+ this.mirrorCheckBox = new MetroFramework.Controls.MetroCheckBox();
+ this.inflationUpDown = new System.Windows.Forms.NumericUpDown();
+ this.chestplateCheckBox = new MetroFramework.Controls.MetroCheckBox();
+ this.leggingsCheckBox = new MetroFramework.Controls.MetroCheckBox();
+ this.bootsCheckBox = new MetroFramework.Controls.MetroCheckBox();
+ ((System.ComponentModel.ISupportInitialize)(this.PosXUpDown)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.PosYUpDown)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.PosZUpDown)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.SizeZUpDown)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.SizeYUpDown)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.SizeXUpDown)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.uvYUpDown)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.uvXUpDown)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.inflationUpDown)).BeginInit();
+ this.SuspendLayout();
+ //
+ // parentLabel
+ //
+ this.parentLabel.AutoSize = true;
+ this.parentLabel.FontSize = MetroFramework.MetroLabelSize.Tall;
+ this.parentLabel.Location = new System.Drawing.Point(47, 55);
+ this.parentLabel.Name = "parentLabel";
+ this.parentLabel.Size = new System.Drawing.Size(50, 25);
+ this.parentLabel.TabIndex = 2;
+ this.parentLabel.Text = "Type:";
+ this.parentLabel.Theme = MetroFramework.MetroThemeStyle.Dark;
+ //
+ // positionLabel
+ //
+ this.positionLabel.AutoSize = true;
+ this.positionLabel.FontSize = MetroFramework.MetroLabelSize.Tall;
+ this.positionLabel.Location = new System.Drawing.Point(22, 84);
+ this.positionLabel.Name = "positionLabel";
+ this.positionLabel.Size = new System.Drawing.Size(75, 25);
+ this.positionLabel.TabIndex = 4;
+ this.positionLabel.Text = "Position:";
+ this.positionLabel.Theme = MetroFramework.MetroThemeStyle.Dark;
+ //
+ // sizeLabel
+ //
+ this.sizeLabel.AutoSize = true;
+ this.sizeLabel.FontSize = MetroFramework.MetroLabelSize.Tall;
+ this.sizeLabel.Location = new System.Drawing.Point(51, 109);
+ this.sizeLabel.Name = "sizeLabel";
+ this.sizeLabel.Size = new System.Drawing.Size(46, 25);
+ this.sizeLabel.TabIndex = 22;
+ this.sizeLabel.Text = "Size:";
+ this.sizeLabel.Theme = MetroFramework.MetroThemeStyle.Dark;
+ //
+ // uvLabel
+ //
+ this.uvLabel.AutoSize = true;
+ this.uvLabel.FontSize = MetroFramework.MetroLabelSize.Tall;
+ this.uvLabel.Location = new System.Drawing.Point(58, 135);
+ this.uvLabel.Name = "uvLabel";
+ this.uvLabel.Size = new System.Drawing.Size(39, 25);
+ this.uvLabel.TabIndex = 26;
+ this.uvLabel.Text = "UV:";
+ this.uvLabel.Theme = MetroFramework.MetroThemeStyle.Dark;
+ //
+ // inflationLabel
+ //
+ this.inflationLabel.AutoSize = true;
+ this.inflationLabel.FontSize = MetroFramework.MetroLabelSize.Tall;
+ this.inflationLabel.Location = new System.Drawing.Point(42, 165);
+ this.inflationLabel.Name = "inflationLabel";
+ this.inflationLabel.Size = new System.Drawing.Size(55, 25);
+ this.inflationLabel.TabIndex = 31;
+ this.inflationLabel.Text = "Scale:";
+ this.inflationLabel.Theme = MetroFramework.MetroThemeStyle.Dark;
+ //
+ // toolTip
+ //
+ this.toolTip.StripAmpersands = true;
+ this.toolTip.Style = MetroFramework.MetroColorStyle.Blue;
+ this.toolTip.StyleManager = null;
+ this.toolTip.Theme = MetroFramework.MetroThemeStyle.Dark;
+ //
+ // parentComboBox
+ //
+ this.parentComboBox.FormattingEnabled = true;
+ this.parentComboBox.ItemHeight = 23;
+ this.parentComboBox.Items.AddRange(new object[] {
+ "HEAD",
+ "BODY",
+ "ARM0",
+ "ARM1",
+ "LEG0",
+ "LEG1",
+ "HEADWEAR",
+ "JACKET",
+ "SLEEVE0",
+ "SLEEVE1",
+ "PANTS0",
+ "PANTS1",
+ "WAIST",
+ "LEGGING0",
+ "LEGGING1",
+ "SOCK0",
+ "SOCK1",
+ "BOOT0",
+ "BOOT1",
+ "ARMARMOR1",
+ "ARMARMOR0",
+ "BODYARMOR",
+ "BELT"});
+ this.parentComboBox.Location = new System.Drawing.Point(103, 51);
+ this.parentComboBox.Name = "parentComboBox";
+ this.parentComboBox.Size = new System.Drawing.Size(163, 29);
+ this.parentComboBox.TabIndex = 3;
+ this.parentComboBox.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.parentComboBox.UseSelectable = true;
+ //
+ // PosXUpDown
+ //
+ this.PosXUpDown.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(17)))), ((int)(((byte)(17)))), ((int)(((byte)(17)))));
+ this.PosXUpDown.DecimalPlaces = 3;
+ this.PosXUpDown.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204)))));
+ this.PosXUpDown.Location = new System.Drawing.Point(103, 86);
+ this.PosXUpDown.Maximum = new decimal(new int[] {
+ 9999,
+ 0,
+ 0,
+ 0});
+ this.PosXUpDown.Minimum = new decimal(new int[] {
+ 9999,
+ 0,
+ 0,
+ -2147483648});
+ this.PosXUpDown.Name = "PosXUpDown";
+ this.PosXUpDown.Size = new System.Drawing.Size(73, 20);
+ this.PosXUpDown.TabIndex = 19;
+ //
+ // PosYUpDown
+ //
+ this.PosYUpDown.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(17)))), ((int)(((byte)(17)))), ((int)(((byte)(17)))));
+ this.PosYUpDown.DecimalPlaces = 3;
+ this.PosYUpDown.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204)))));
+ this.PosYUpDown.Location = new System.Drawing.Point(182, 86);
+ this.PosYUpDown.Maximum = new decimal(new int[] {
+ 9999,
+ 0,
+ 0,
+ 0});
+ this.PosYUpDown.Minimum = new decimal(new int[] {
+ 9999,
+ 0,
+ 0,
+ -2147483648});
+ this.PosYUpDown.Name = "PosYUpDown";
+ this.PosYUpDown.Size = new System.Drawing.Size(73, 20);
+ this.PosYUpDown.TabIndex = 20;
+ //
+ // PosZUpDown
+ //
+ this.PosZUpDown.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(17)))), ((int)(((byte)(17)))), ((int)(((byte)(17)))));
+ this.PosZUpDown.DecimalPlaces = 3;
+ this.PosZUpDown.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204)))));
+ this.PosZUpDown.Location = new System.Drawing.Point(261, 86);
+ this.PosZUpDown.Maximum = new decimal(new int[] {
+ 9999,
+ 0,
+ 0,
+ 0});
+ this.PosZUpDown.Minimum = new decimal(new int[] {
+ 9999,
+ 0,
+ 0,
+ -2147483648});
+ this.PosZUpDown.Name = "PosZUpDown";
+ this.PosZUpDown.Size = new System.Drawing.Size(73, 20);
+ this.PosZUpDown.TabIndex = 21;
+ //
+ // SizeZUpDown
+ //
+ this.SizeZUpDown.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(17)))), ((int)(((byte)(17)))), ((int)(((byte)(17)))));
+ this.SizeZUpDown.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204)))));
+ this.SizeZUpDown.Location = new System.Drawing.Point(261, 111);
+ this.SizeZUpDown.Maximum = new decimal(new int[] {
+ 9999,
+ 0,
+ 0,
+ 0});
+ this.SizeZUpDown.Name = "SizeZUpDown";
+ this.SizeZUpDown.Size = new System.Drawing.Size(73, 20);
+ this.SizeZUpDown.TabIndex = 25;
+ //
+ // SizeYUpDown
+ //
+ this.SizeYUpDown.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(17)))), ((int)(((byte)(17)))), ((int)(((byte)(17)))));
+ this.SizeYUpDown.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204)))));
+ this.SizeYUpDown.Location = new System.Drawing.Point(182, 111);
+ this.SizeYUpDown.Maximum = new decimal(new int[] {
+ 9999,
+ 0,
+ 0,
+ 0});
+ this.SizeYUpDown.Name = "SizeYUpDown";
+ this.SizeYUpDown.Size = new System.Drawing.Size(73, 20);
+ this.SizeYUpDown.TabIndex = 24;
+ //
+ // SizeXUpDown
+ //
+ this.SizeXUpDown.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(17)))), ((int)(((byte)(17)))), ((int)(((byte)(17)))));
+ this.SizeXUpDown.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204)))));
+ this.SizeXUpDown.Location = new System.Drawing.Point(103, 111);
+ this.SizeXUpDown.Maximum = new decimal(new int[] {
+ 9999,
+ 0,
+ 0,
+ 0});
+ this.SizeXUpDown.Name = "SizeXUpDown";
+ this.SizeXUpDown.Size = new System.Drawing.Size(73, 20);
+ this.SizeXUpDown.TabIndex = 23;
+ //
+ // uvYUpDown
+ //
+ this.uvYUpDown.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(17)))), ((int)(((byte)(17)))), ((int)(((byte)(17)))));
+ this.uvYUpDown.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204)))));
+ this.uvYUpDown.Location = new System.Drawing.Point(182, 137);
+ this.uvYUpDown.Maximum = new decimal(new int[] {
+ 9999,
+ 0,
+ 0,
+ 0});
+ this.uvYUpDown.Minimum = new decimal(new int[] {
+ 9999,
+ 0,
+ 0,
+ -2147483648});
+ this.uvYUpDown.Name = "uvYUpDown";
+ this.uvYUpDown.Size = new System.Drawing.Size(73, 20);
+ this.uvYUpDown.TabIndex = 28;
+ //
+ // uvXUpDown
+ //
+ this.uvXUpDown.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(17)))), ((int)(((byte)(17)))), ((int)(((byte)(17)))));
+ this.uvXUpDown.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204)))));
+ this.uvXUpDown.Location = new System.Drawing.Point(103, 137);
+ this.uvXUpDown.Maximum = new decimal(new int[] {
+ 9999,
+ 0,
+ 0,
+ 0});
+ this.uvXUpDown.Minimum = new decimal(new int[] {
+ 9999,
+ 0,
+ 0,
+ -2147483648});
+ this.uvXUpDown.Name = "uvXUpDown";
+ this.uvXUpDown.Size = new System.Drawing.Size(73, 20);
+ this.uvXUpDown.TabIndex = 27;
+ //
+ // helmetCheckBox
+ //
+ this.helmetCheckBox.AutoSize = true;
+ this.helmetCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Tall;
+ this.helmetCheckBox.FontWeight = MetroFramework.MetroCheckBoxWeight.Light;
+ this.helmetCheckBox.Location = new System.Drawing.Point(340, 84);
+ this.helmetCheckBox.Name = "helmetCheckBox";
+ this.helmetCheckBox.Size = new System.Drawing.Size(160, 25);
+ this.helmetCheckBox.TabIndex = 29;
+ this.helmetCheckBox.Text = "Mask with helmet";
+ this.helmetCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.helmetCheckBox.UseSelectable = true;
+ //
+ // mirrorCheckBox
+ //
+ this.mirrorCheckBox.AutoSize = true;
+ this.mirrorCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Tall;
+ this.mirrorCheckBox.FontWeight = MetroFramework.MetroCheckBoxWeight.Light;
+ this.mirrorCheckBox.Location = new System.Drawing.Point(340, 58);
+ this.mirrorCheckBox.Name = "mirrorCheckBox";
+ this.mirrorCheckBox.Size = new System.Drawing.Size(133, 25);
+ this.mirrorCheckBox.TabIndex = 30;
+ this.mirrorCheckBox.Text = "Mirror Texture";
+ this.mirrorCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.mirrorCheckBox.UseSelectable = true;
+ //
+ // inflationUpDown
+ //
+ this.inflationUpDown.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(17)))), ((int)(((byte)(17)))), ((int)(((byte)(17)))));
+ this.inflationUpDown.DecimalPlaces = 3;
+ this.inflationUpDown.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204)))));
+ this.inflationUpDown.Location = new System.Drawing.Point(103, 167);
+ this.inflationUpDown.Maximum = new decimal(new int[] {
+ 9999,
+ 0,
+ 0,
+ 0});
+ this.inflationUpDown.Name = "inflationUpDown";
+ this.inflationUpDown.Size = new System.Drawing.Size(73, 20);
+ this.inflationUpDown.TabIndex = 32;
+ //
+ // chestplateCheckBox
+ //
+ this.chestplateCheckBox.AutoSize = true;
+ this.chestplateCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Tall;
+ this.chestplateCheckBox.FontWeight = MetroFramework.MetroCheckBoxWeight.Light;
+ this.chestplateCheckBox.Location = new System.Drawing.Point(340, 109);
+ this.chestplateCheckBox.Name = "chestplateCheckBox";
+ this.chestplateCheckBox.Size = new System.Drawing.Size(184, 25);
+ this.chestplateCheckBox.TabIndex = 33;
+ this.chestplateCheckBox.Text = "Mask with chestplate";
+ this.chestplateCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.chestplateCheckBox.UseSelectable = true;
+ //
+ // leggingsCheckBox
+ //
+ this.leggingsCheckBox.AutoSize = true;
+ this.leggingsCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Tall;
+ this.leggingsCheckBox.FontWeight = MetroFramework.MetroCheckBoxWeight.Light;
+ this.leggingsCheckBox.Location = new System.Drawing.Point(340, 135);
+ this.leggingsCheckBox.Name = "leggingsCheckBox";
+ this.leggingsCheckBox.Size = new System.Drawing.Size(172, 25);
+ this.leggingsCheckBox.TabIndex = 34;
+ this.leggingsCheckBox.Text = "Mask with leggings";
+ this.leggingsCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.leggingsCheckBox.UseSelectable = true;
+ //
+ // bootsCheckBox
+ //
+ this.bootsCheckBox.AutoSize = true;
+ this.bootsCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Tall;
+ this.bootsCheckBox.FontWeight = MetroFramework.MetroCheckBoxWeight.Light;
+ this.bootsCheckBox.Location = new System.Drawing.Point(340, 161);
+ this.bootsCheckBox.Name = "bootsCheckBox";
+ this.bootsCheckBox.Size = new System.Drawing.Size(150, 25);
+ this.bootsCheckBox.TabIndex = 35;
+ this.bootsCheckBox.Text = "Mask with boots";
+ this.bootsCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.bootsCheckBox.UseSelectable = true;
+ //
+ // BoxEditorControl
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(18)))), ((int)(((byte)(18)))));
+ this.Controls.Add(this.bootsCheckBox);
+ this.Controls.Add(this.leggingsCheckBox);
+ this.Controls.Add(this.chestplateCheckBox);
+ this.Controls.Add(this.inflationUpDown);
+ this.Controls.Add(this.uvYUpDown);
+ this.Controls.Add(this.uvXUpDown);
+ this.Controls.Add(this.SizeZUpDown);
+ this.Controls.Add(this.SizeYUpDown);
+ this.Controls.Add(this.SizeXUpDown);
+ this.Controls.Add(this.PosZUpDown);
+ this.Controls.Add(this.PosYUpDown);
+ this.Controls.Add(this.PosXUpDown);
+ this.Controls.Add(this.inflationLabel);
+ this.Controls.Add(this.parentComboBox);
+ this.Controls.Add(this.mirrorCheckBox);
+ this.Controls.Add(this.helmetCheckBox);
+ this.Controls.Add(this.uvLabel);
+ this.Controls.Add(this.sizeLabel);
+ this.Controls.Add(this.positionLabel);
+ this.Controls.Add(this.parentLabel);
+ this.Name = "BoxEditorControl";
+ this.Size = new System.Drawing.Size(540, 220);
+ ((System.ComponentModel.ISupportInitialize)(this.PosXUpDown)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.PosYUpDown)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.PosZUpDown)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.SizeZUpDown)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.SizeYUpDown)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.SizeXUpDown)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.uvYUpDown)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.uvXUpDown)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.inflationUpDown)).EndInit();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+ private MetroFramework.Components.MetroToolTip toolTip;
+ private MetroFramework.Controls.MetroComboBox parentComboBox;
+ private System.Windows.Forms.NumericUpDown PosXUpDown;
+ private System.Windows.Forms.NumericUpDown PosYUpDown;
+ private System.Windows.Forms.NumericUpDown PosZUpDown;
+ private System.Windows.Forms.NumericUpDown SizeZUpDown;
+ private System.Windows.Forms.NumericUpDown SizeYUpDown;
+ private System.Windows.Forms.NumericUpDown SizeXUpDown;
+ private System.Windows.Forms.NumericUpDown uvYUpDown;
+ private System.Windows.Forms.NumericUpDown uvXUpDown;
+ private MetroFramework.Controls.MetroCheckBox helmetCheckBox;
+ private MetroFramework.Controls.MetroCheckBox mirrorCheckBox;
+ private System.Windows.Forms.NumericUpDown inflationUpDown;
+ private MetroFramework.Controls.MetroCheckBox chestplateCheckBox;
+ private MetroFramework.Controls.MetroCheckBox leggingsCheckBox;
+ private MetroFramework.Controls.MetroCheckBox bootsCheckBox;
+ private MetroFramework.Controls.MetroLabel parentLabel;
+ private MetroFramework.Controls.MetroLabel positionLabel;
+ private MetroFramework.Controls.MetroLabel sizeLabel;
+ private MetroFramework.Controls.MetroLabel uvLabel;
+ private MetroFramework.Controls.MetroLabel inflationLabel;
+ }
+}
\ No newline at end of file
diff --git a/PCK-Studio/Controls/BoxEditorControl.cs b/PCK-Studio/Controls/BoxEditorControl.cs
new file mode 100644
index 00000000..bc434168
--- /dev/null
+++ b/PCK-Studio/Controls/BoxEditorControl.cs
@@ -0,0 +1,126 @@
+using OpenTK;
+using PckStudio.Core.Skin;
+using PckStudio.Properties;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Diagnostics;
+using System.Drawing;
+using System.Linq;
+using System.Numerics;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;
+
+namespace PckStudio.Controls
+{
+ internal partial class BoxEditorControl : UserControl
+ {
+ public event EventHandler BoxChanged;
+
+ private SkinBOX result;
+ private int boxVersion = 0;
+
+ public BoxEditorControl(SkinBOX box, int xmlVersion)
+ : this(xmlVersion)
+ {
+ SetBOX(box);
+ }
+
+ public BoxEditorControl()
+ :this(0)
+ {
+
+ }
+
+ public BoxEditorControl(int xmlVersion = 0)
+ {
+ InitializeComponent();
+ SetBOXVersion(xmlVersion);
+ parentComboBox.SelectedIndexChanged += this.HandleBoxChanged;
+ PosXUpDown.ValueChanged += this.HandleBoxChanged;
+ PosYUpDown.ValueChanged += this.HandleBoxChanged;
+ PosZUpDown.ValueChanged += this.HandleBoxChanged;
+ SizeXUpDown.ValueChanged += this.HandleBoxChanged;
+ SizeYUpDown.ValueChanged += this.HandleBoxChanged;
+ SizeZUpDown.ValueChanged += this.HandleBoxChanged;
+ uvXUpDown.ValueChanged += this.HandleBoxChanged;
+ uvYUpDown.ValueChanged += this.HandleBoxChanged;
+ helmetCheckBox.CheckedChanged += this.HandleBoxChanged;
+ chestplateCheckBox.CheckedChanged += this.HandleBoxChanged;
+ leggingsCheckBox.CheckedChanged += this.HandleBoxChanged;
+ bootsCheckBox.CheckedChanged += this.HandleBoxChanged;
+ mirrorCheckBox.CheckedChanged += this.HandleBoxChanged;
+ inflationUpDown.ValueChanged += this.HandleBoxChanged;
+ }
+
+ public void SetBOXVersion(int xmlVersion)
+ {
+ boxVersion = xmlVersion;
+ Debug.WriteLine(xmlVersion);
+ inflationUpDown.Enabled = boxVersion == 3;
+ }
+
+ public void SetBOX(SkinBOX box)
+ {
+ if (string.IsNullOrEmpty(box.Type) || !parentComboBox.Items.Contains(box.Type))
+ {
+ throw new Exception("Failed to parse BOX value");
+ }
+
+ parentComboBox.SelectedItem = parentComboBox.Items[parentComboBox.Items.IndexOf(box.Type)];
+ PosXUpDown.Value = (decimal)box.Pos.X;
+ PosYUpDown.Value = (decimal)box.Pos.Y;
+ PosZUpDown.Value = (decimal)box.Pos.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;
+ helmetCheckBox.Checked = (box.ArmorMaskFlags & 1) != 0;
+ chestplateCheckBox.Checked = (box.ArmorMaskFlags & 2) != 0;
+ leggingsCheckBox.Checked = (box.ArmorMaskFlags & 4) != 0;
+ bootsCheckBox.Checked = (box.ArmorMaskFlags & 8) != 0;
+ mirrorCheckBox.Checked = box.Mirror;
+ inflationUpDown.Value = (decimal)box.Scale;
+ }
+
+ public SkinBOX GetBOX()
+ {
+ int mask = 0;
+
+ if (helmetCheckBox.Checked) mask |= 1;
+ if (chestplateCheckBox.Checked) mask |= 2;
+ if (leggingsCheckBox.Checked) mask |= 4;
+ if (bootsCheckBox.Checked) mask |= 8;
+
+ result = SkinBOX.FromString(
+ $"{parentComboBox.SelectedItem} " +
+ $"{PosXUpDown.Value} {PosYUpDown.Value} {PosZUpDown.Value} " +
+ $"{SizeXUpDown.Value} {SizeYUpDown.Value} {SizeZUpDown.Value} " +
+ $"{uvXUpDown.Value} {uvYUpDown.Value} " +
+ $"{mask} " +
+ $"{Convert.ToInt32(mirrorCheckBox.Checked)} " +
+ $"{inflationUpDown.Value}");
+
+ return result;
+ }
+
+ private void HandleBoxChanged(object sender, EventArgs e)
+ {
+ // we'll explain this in a minute
+ this.OnBoxChanged(EventArgs.Empty);
+ }
+
+ protected virtual void OnBoxChanged(EventArgs e)
+ {
+ EventHandler handler = this.BoxChanged;
+ if (handler != null)
+ {
+ handler(this, e);
+ }
+ }
+ }
+}
diff --git a/PCK-Studio/Controls/BoxEditorControl.resx b/PCK-Studio/Controls/BoxEditorControl.resx
new file mode 100644
index 00000000..8766f298
--- /dev/null
+++ b/PCK-Studio/Controls/BoxEditorControl.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/PCK-Studio/Controls/CustomTabControl.cs b/PCK-Studio/Controls/CustomTabControl.cs
new file mode 100644
index 00000000..a9e09f03
--- /dev/null
+++ b/PCK-Studio/Controls/CustomTabControl.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Drawing;
+using System.Windows.Forms;
+
+using MetroFramework.Controls;
+using MetroFramework.Drawing;
+
+
+namespace PckStudio.Controls
+{
+ internal class CustomTabControl : MetroTabControl
+ {
+ private const string CloseChar = "×";
+ private Size CloseButtonSize = new Size(7, 7);
+ private const int StartIndex = 1;
+
+ [Browsable(true)]
+ public event EventHandler PageClosing;
+
+ public CustomTabControl()
+ : base()
+ {
+ }
+
+ private Rectangle GetCloseButtonArea(Rectangle tabArea)
+ {
+ Size closeBtnSz = CloseButtonSize;
+ var closeBtnPt = new Point(
+ tabArea.Right - closeBtnSz.Width,
+ tabArea.Top + 2 + (tabArea.Height - closeBtnSz.Height) / 2);
+ return new Rectangle(closeBtnPt, closeBtnSz);
+ }
+
+ protected override void OnMouseClick(MouseEventArgs e)
+ {
+ base.OnMouseClick(e);
+ if (SelectedIndex < StartIndex)
+ return;
+ Rectangle tabArea = GetTabRect(SelectedIndex);
+ Rectangle buttonArea = GetCloseButtonArea(tabArea);
+ if (buttonArea.Contains(e.Location))
+ {
+ var eventArg = new PageClosingEventArgs(TabPages[SelectedIndex]);
+ PageClosing?.Invoke(this, eventArg);
+ if (!eventArg.Cancel)
+ {
+ SelectedIndex -= 1;
+ TabPages.RemoveAt(SelectedIndex + 1);
+ }
+ }
+ }
+
+ protected override void OnCustomPaintForeground(MetroPaintEventArgs e)
+ {
+ base.OnCustomPaintForeground(e);
+ if (SelectedIndex < StartIndex)
+ return;
+ // Draw Close button
+ Rectangle tabArea = GetTabRect(SelectedIndex);
+
+ Rectangle buttonArea = GetCloseButtonArea(tabArea);
+
+ e.Graphics.FillRectangle(MetroPaint.GetStyleBrush(Style), buttonArea);
+ e.Graphics.DrawString(
+ CloseChar,
+ Font,
+ new SolidBrush(MetroPaint.ForeColor.Title(Theme)),
+ buttonArea.Right - buttonArea.Width - 2, buttonArea.Top - 4);
+ }
+
+ //protected override void OnPaintForeground(PaintEventArgs e)
+ //{
+ // base.OnPaintForeground(e);
+ // for (int i = StartIndex; i < TabPages.Count; i++)
+ // {
+ // // Draw Close button
+ // Rectangle tabArea = GetTabRect(i);
+
+ // Rectangle buttonArea = GetCloseButtonArea(tabArea);
+
+ // e.Graphics.FillRectangle(MetroPaint.GetStyleBrush(Style), buttonArea);
+ // e.Graphics.DrawString(
+ // CloseChar,
+ // Font,
+ // new SolidBrush(MetroPaint.ForeColor.Title(Theme)),
+ // buttonArea.Right - buttonArea.Width - 2, buttonArea.Top - 4);
+ // }
+ //}
+ }
+}
\ No newline at end of file
diff --git a/PCK-Studio/Controls/EditorControl.cs b/PCK-Studio/Controls/EditorControl.cs
new file mode 100644
index 00000000..fffacd64
--- /dev/null
+++ b/PCK-Studio/Controls/EditorControl.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using PckStudio.Interfaces;
+using System.IO;
+
+namespace PckStudio.Controls
+{
+ internal class EditorControl : UserControl, IEditor where T : class
+ {
+ public T EditorValue { get; }
+
+ public ISaveContext SaveContext { get; private set; }
+
+ public string TitleName { get; }
+
+ public EditorControl()
+ {
+ }
+
+ protected EditorControl(string titleName, T value, ISaveContext saveContext)
+ {
+ _ = value ?? throw new ArgumentNullException(nameof(value));
+ TitleName = titleName;
+ EditorValue = value;
+ SaveContext = saveContext;
+ }
+
+ protected override void OnControlRemoved(ControlEventArgs e)
+ {
+ if (SaveContext.AutoSave)
+ Save();
+ base.OnControlRemoved(e);
+ }
+
+ public void SetSaveContext(ISaveContext saveContext) => SaveContext = saveContext;
+
+ protected virtual void PreSave()
+ { }
+
+ protected virtual void PostSave()
+ { }
+
+ public void Save()
+ {
+ PreSave();
+ SaveContext.Save(EditorValue);
+ PostSave();
+ }
+
+ public virtual void Close() => throw new NotImplementedException();
+
+ public virtual void UpdateView() => throw new NotImplementedException();
+ }
+}
diff --git a/PCK-Studio/Controls/EditorForm.cs b/PCK-Studio/Controls/EditorForm.cs
new file mode 100644
index 00000000..e492f697
--- /dev/null
+++ b/PCK-Studio/Controls/EditorForm.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using MetroFramework.Forms;
+using PckStudio.Interfaces;
+
+namespace PckStudio.Controls
+{
+ public class EditorForm : MetroForm where T : class
+ {
+ protected T EditorValue;
+ private readonly ISaveContext SaveContext;
+
+ private EditorForm()
+ {
+ }
+
+ protected EditorForm(T value, ISaveContext saveContext)
+ {
+ _ = value ?? throw new ArgumentNullException(nameof(value));
+ EditorValue = value;
+ SaveContext = saveContext;
+ }
+
+ protected void Save() => SaveContext.Save(EditorValue);
+
+ protected override void OnFormClosing(FormClosingEventArgs e)
+ {
+ if (SaveContext.AutoSave)
+ Save();
+ base.OnFormClosing(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/PCK-Studio/Controls/PageClosingEventArgs.cs b/PCK-Studio/Controls/PageClosingEventArgs.cs
new file mode 100644
index 00000000..ac8de3a4
--- /dev/null
+++ b/PCK-Studio/Controls/PageClosingEventArgs.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace PckStudio.Controls
+{
+ internal class PageClosingEventArgs : CancelEventArgs
+ {
+ private readonly TabPage page;
+ public TabPage Page => page;
+
+ public PageClosingEventArgs(TabPage page)
+ : base()
+ {
+ this.page = page;
+ }
+ }
+}
diff --git a/PCK-Studio/Controls/PckEditor.Designer.cs b/PCK-Studio/Controls/PckEditor.Designer.cs
new file mode 100644
index 00000000..2b27b7fb
--- /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;
+ }
+}
\ No newline at end of file
diff --git a/PCK-Studio/Controls/PckEditor.cs b/PCK-Studio/Controls/PckEditor.cs
new file mode 100644
index 00000000..d6a0ee10
--- /dev/null
+++ b/PCK-Studio/Controls/PckEditor.cs
@@ -0,0 +1,2232 @@
+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 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(string name, PackInfo packInfo, ISaveContext saveContext)
+ : base(name, 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,
+ };
+ }
+
+ protected override void PostSave()
+ {
+ _timesSaved++;
+ _wasModified = false;
+ MessageBox.Show("Pck Saved.", "Saved");
+ Debug.WriteLine($"_timesSaved: {_timesSaved}");
+ }
+
+ 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 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 = TitleName + 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, $"No 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.xmlVersion);
+ 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.Type == PckAssetType.SkinFile)
+ {
+ buttonEdit.Text = "EDIT SKIN";
+ buttonEdit.Visible = true;
+ }
+
+ switch (asset.Type)
+ {
+ case PckAssetType.SkinFile:
+ case PckAssetType.CapeFile:
+ case PckAssetType.TextureFile:
+ {
+
+ try
+ {
+ Image img = asset.GetTexture();
+ previewPictureBox.Image = img;
+ labelImageSize.Text = $"{previewPictureBox.Image.Size.Width}x{previewPictureBox.Image.Size.Height}";
+ }
+ catch(System.ArgumentException ex)
+ {
+ previewPictureBox.Image = Resources.NoImageFound;
+ MessageBox.Show(this, "Not a valid .PNG or .TGA image or invalid image data found");
+ }
+
+ 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;
+ }
+
+ if (resourceLocation.Category == ResourceCategory.MobEntityTextures || resourceLocation.Category == ResourceCategory.ItemEntityTextures)
+ {
+ buttonEdit.Text = "EDIT ENTITY MODEL";
+ 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
+ // - MayNL
+
+ 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(EditorValue.File.xmlVersion))
+ 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;
+ }
+
+ 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, 3),
+ 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, EditorValue.File.xmlVersion);
+ 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, EditorValue.File.xmlVersion);
+ 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..86422c5d
--- /dev/null
+++ b/PCK-Studio/Controls/PckEditor.resx
@@ -0,0 +1,2115 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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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
+ itPtJO1BN8kZM/CL+ReVJtKvTC+jk/HV52E2qlaRdm679HtKPz3Mf+LECXM8Hv9v4B3Tj0fq6urudjqd
+ H3W7XVgXviQcDl8UDocvDvgDl9fX19/gdrvvOHHixG/BFqG/9R4PkTecPw6Tw57JOEiFbVO7Ag3ERzod
+ xEeaLeb7LVbLLVab9Xr7UfsHnE7nRVhn9Xg8l7hcrmsdDsfNdrv9Uxar5XGT2fQVq9X6/ZaWln9wez3k
+ iBJkS+Tr5brPeMPkRGzCR23D52P/q9dxmTLbU++hx58gX6/Hg2NMR4LB4J9ZzOZv2Gy2Aw6HA+t/t9d7
+ 65HpuCIYDF4Ui8XObU4072hpbc2xn/elWG2W7VarZZfVatltsVgut1jMN5jN5ltNJtP9JqPxaYPB8BW9
+ Xv+qTqf7jdra2jdqamoOVldXH6yuPkw+a2qqD+J7/I7rjAbDV3Cf2WS6H+1YLJYbrBbL5VardbfNat1l
+ s9k0jXYrSkdHx7Z4Ir4jFAqd29Dg2+2t917mdruvh3LYbLa7zRbLg0aT8Wm9Qf9CbW3tN6qrq7996NDh
+ 1997770fvPvuu2/88pe//OHPf/GLgz//+c9z6y9+cfCXv/zlwXfffffge++9d/DQoUMY/w9ramq/r9Md
+ +Y7BYPi6yWT6ksViedxmsyOK/jj6huBDodAHwuHwZYFA4Jr6+vqbMJNzOBwP22y2L1gslpdMJtNrBoPh
+ ezqd7o3a2tqD4DEq/sZ3er3+dYPB8E2TyfQ1s9n8rNVq/bzdbr+9rq7uRqfTeYXX493T2Nh4YYOvYbfH
+ 47nU6XReh/5BB+gBXaDviO7Id2pra79fU1PzQypDWnlfR3RH3gAdJqPxNbPZ/KLFYnnOarU+ZLPZ9tvt
+ 9pvq6uqudjgcF7uczvM8HnfOrKJQCQSCVR6P91yn07mnrq7uKpvNjpnPnWaz+UGj0XTAYDC8qNPpvlVT
+ U/t6dXX1G+Av+Ax+g++ov5BlItRf/JzI54fvvvvuDyHPw4cOfa+6uhrjfVWv13/VaDQeMJvNj1it1k/b
+ 7fZbHXWOG51O11Uul2uvx+05v95bv7O+3qepm1arbbvVatsFHbZYrJdDp6mNmO83Gk0FbCSLv6qN4Hro
+ IWwM7ZgtlhuI7Vmtu2k/2jYSTyS2+QOB7Y2Njbu8Xu/5brd7r8vlusrhcCAjcpvNZv2M2Wx+1GgyPqc3
+ 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
+ +mHcbTKZARREP1wu1zler2eXv7FxRzgU2h6PN+XQH/AHtnk93u3IPDjqHAjwzrFarOdZTOYLTEbThbAZ
+ g95w0RHdEWpTvDI7Bt+IjzQw+RsN5xqMhl0Go2GHwWiogg+W+4Segp8er7fK6XLttNvtuyxW67mwS4PB
+ qPpm1V7UsVbnqfl/q62p2aOrrd1zRAf5Goj9W8zmC+w223mOurpzXC7nTmwa8zc2bg+HQjm0/soWvV6/
+ jdXtqEeO6KqOHNHtOKLT7dDRulOnq91Zm1V1pOqO6HbQemSHXq+v4m2gPYNe/yvBBKTDvF7vNpfLtd1m
+ s2HmUGU0muBUCN0YT01tDav4O3+tRSX80GG8pA0jZr1mU5XVatlus1u3OV3OrHHX1/u2uV3ubU6HE7vs
+ qiwWS5XJZN5hNBp36CkNKj9Vvup0O0n7ej0ChB0mg7HKbDQhpbvdarZss2msx9Q5jm6z2W3brFbrdtAD
+ umA8eoOejBNtgn4dqTpadbqdR3RHSOX9sVpl0Ou3oxr1+m2ocn/lFoPesE2vN2w7otNvP6I7glrF9GuH
+ rhaV8ZfXmhpaawtXzivw02w27bBarVV1jroqj9ezvdHfuD0U3rwxctr1esN2WomuU91nNpJtH7TCbsjv
+ zE5gW6KN6A2b5ytKJBrdFgB41NdvdzgdVVai51THDHo9kXVtDXjKK+OtVGvkCh7raqluGA07TCbTDqTN
+ 7EftACnMLDDDKGkMnnrvNqfHtc3hcmy32m1VZivSr6YdBhPsgPAywzuiA6x/VEKfSH92rSlQa2uJfuw0
+ GI07TAjSrFYEgFivxNJFybMPp8O5rc5+dJvdZocNEns0GYw7jHrDDr3uyA7YkGpXgn1xHQcPVR9p0G83
+ GPTbUOV+5OJ0OrfZjx7dZrXZtpvN5iqj0Vhl0BvQH2mX2gqrhF+SHan2JMme209t7U74e/gyIl+LpQrZ
+ GY/LjczXtmAgUJTGSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmU
+ SqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmU
+ SqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmUSqmU
+ SqmUSqmUSqmUSqmUSqmUX73y/wPisoOt4nelbQAAAABJRU5ErkJggg==
+
+
+
+
+ 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
+
+
+ 831, 252
+
+
+ 30, 19
+
+
+ 19
+
+
+
+
+
+ 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, 135
+
+
+ 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, 105
+
+
+ 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, 137
+
+
+ 146, 20
+
+
+ 16
+
+
+ entryDataTextBox
+
+
+ MetroFramework.Controls.MetroTextBox, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a
+
+
+ MetaTab
+
+
+ 4
+
+
+ Bottom, Right
+
+
+ 215, 163
+
+
+ 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, 28
+
+
+ 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+wAAABPSURBVDhP5ZAx
+ DgAgCAMZ/f+HMcbYYOmg0UmHY2ibGzB3txNSgMKsHcD9ksBL5wcBPwyPCwLFJBjjVe4LFHGsgEDBAu6x
+ 4+AxAT9MkYJdKi90axNkwjxWAAAAAElFTkSuQmCC
+
+
+
+ 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
+ vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xOdTWsmQAAABHSURBVDhPY2AY
+ FOD/Aob/GHillCC6Opzg/26p//9PaZCGT+qwIAxAlyQSj0gDRBkgmP4GwDSiYToagG4QlA83gFiAYfOg
+ AAD7x53AAJUk8AAAAABJRU5ErkJggg==
+
+
+
+ 172, 22
+
+
+ Folder
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
+ vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xOdTWsmQAAAImSURBVDhPpc/d
+ T1JxHMdxLosny82tHI9pRSeKWt4oA3mQw+aQ1lq2pdFKBQ5x6OzMaYkmlSWksS6aF8Jqri4UbT1g5jS6
+ 7D9p66Yu6ybOp50vAoN10/ptr52d7fd9f89RKP73AFDYTBoweg1OGjSwGVuIRa8inYf2kWPtSmI1qOie
+ fF+erQSMLbDq1I0BnYocObyfdLRXMAZ5kRYndOp6QB5sdq7zIPEwB+BhWtHLtBF5WCZ/XUNgfIjF7PV+
+ zI0GyWL8MhZvDiIbCeJJNIgF7gKZuuTGnUEnTpu1jYGVVBhbmThKWZF8WUqR0oJYkR0nhYkhrE9cRdfR
+ 1npgdXoMxQdxbM7xWLsbJuuzCWykbmFZGMaycAW7GZHkuQHkuH5SCxRmwtisBqZHIb+/TvEkLw6TnYyA
+ 3YyAPBdAjgvQsxaQB399/wpJksDan4PtXkUxOYYPyQh29jb7etbA2l/JQyhLv2lJLVB8yOPnj28oSxJ8
+ 9hfw9azgfTKKrWQEpXkRnzIi/N0FsPaXdEcql1GYidYD+REWbydDKCZv4ON9kXC9NsRcZ2pK6Tg+p+NA
+ m4KkLnbVA7kRP97cDqE4FcK7ewKJO0+Bd9RtP0pgez7x98DTkBfPrrmxFHLBZVLBbVIjPeDA40BddbAZ
+ BQSfFYKXAd9nqQTManj1SuI3a0nzYEOA9zOI9R1HzGeBw6yC06yG06gkng5tg+rg5PmzlV/411PbvHf+
+ ACl773zoakfrAAAAAElFTkSuQmCC
+
+
+
+ 172, 22
+
+
+ Skin
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
+ vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMkMEa+wAAAJESURBVDhPjdH/
+ TxJhHAfw51+pBQdtbVam8HAHiSZw4Bfkngc4wKkw8+6e0zIDHsilzbut1hdZB+jUslw5qiVKttC+zF/a
+ +qtorO26rV967/3j57W9tw9YOgrkW+HCIS/tsdKehxwEcjt96jv/yjeUb4VJY2DuDSfv+7K7ruhT+8KH
+ IbDUCs6/H37UTt4/HF9tTYiQIfue7Gv31Ms+42xm/cdUsRmZ2e1ZatyQ3noXGn7w8GsKc46dX6r0ynOz
+ cV3wORYPhjNuZvE4uPIdGWe55z+zSY8tbVzKvnCJrBOILCOrcoJjkqz9TpMXOVuCsyU52/Tu5TjHyB8H
+ BR9Tnrgm+Owiy1AEQVUJ5jFXJ6H2GkKsc3MuQLGrhGASXkhw9hQ8r8oSjcOqFIlzzi4oxXpFeK5O+E1p
+ 4C7yFhDb1HNNPdex5Jk8QjHckv2H2iQ4eJBOcI5l3F8Sep6s3qMYVmaH9gvR7iEA3XY62qRPnxqsE35L
+ 9oO2hpXwle3bY9u3oo9LsxTDAoIVMmYFFMN1Mm4oo3XCg0/aNMWwpeWO11IVecS6xARmDGUU1JRQPnY1
+ H4c1Ei7E3H/v/q0Jqiovep3luLsc/08wP0YxPNXTp3raOsC8M/MHhIsYllB/lURqJHyiZSiGy0KvFRQx
+ /Kxn2lqqC/KCG/kcGyREkaumjtQVvqqGisiyrdP5omVqhO8+V0uBguAySKSIPWUME6ydIih6GYqhdQnF
+ cEMJbpBQnYSAofBF7EqwF0/0NEVukXWYxlBGzZrmN8JzbVJ5S6oXAAAAAElFTkSuQmCC
+
+
+
+ 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
+ vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xOdTWsmQAAAAwSURBVDhPY/j/
+ /z8DJRhDAI5FGf6jYHT5UQPQDEBXTCweTgZgw1gUY8MYAqMGkI4B8bClX7FZFPQAAAAASUVORK5CYII=
+
+
+
+ 157, 22
+
+
+ Create
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
+ vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xOdTWsmQAAAImSURBVDhPpc/d
+ T1JxHMdxLosny82tHI9pRSeKWt4oA3mQw+aQ1lq2pdFKBQ5x6OzMaYkmlSWksS6aF8Jqri4UbT1g5jS6
+ 7D9p66Yu6ybOp50vAoN10/ptr52d7fd9f89RKP73AFDYTBoweg1OGjSwGVuIRa8inYf2kWPtSmI1qOie
+ fF+erQSMLbDq1I0BnYocObyfdLRXMAZ5kRYndOp6QB5sdq7zIPEwB+BhWtHLtBF5WCZ/XUNgfIjF7PV+
+ zI0GyWL8MhZvDiIbCeJJNIgF7gKZuuTGnUEnTpu1jYGVVBhbmThKWZF8WUqR0oJYkR0nhYkhrE9cRdfR
+ 1npgdXoMxQdxbM7xWLsbJuuzCWykbmFZGMaycAW7GZHkuQHkuH5SCxRmwtisBqZHIb+/TvEkLw6TnYyA
+ 3YyAPBdAjgvQsxaQB399/wpJksDan4PtXkUxOYYPyQh29jb7etbA2l/JQyhLv2lJLVB8yOPnj28oSxJ8
+ 9hfw9azgfTKKrWQEpXkRnzIi/N0FsPaXdEcql1GYidYD+REWbydDKCZv4ON9kXC9NsRcZ2pK6Tg+p+NA
+ m4KkLnbVA7kRP97cDqE4FcK7ewKJO0+Bd9RtP0pgez7x98DTkBfPrrmxFHLBZVLBbVIjPeDA40BddbAZ
+ BQSfFYKXAd9nqQTManj1SuI3a0nzYEOA9zOI9R1HzGeBw6yC06yG06gkng5tg+rg5PmzlV/411PbvHf+
+ ACl773zoakfrAAAAAElFTkSuQmCC
+
+
+
+ 227, 22
+
+
+ Import Skin
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
+ vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xOdTWsmQAAAEfSURBVDhPY2AY
+ FOD/Aob/GHillCC6Opzg/26p//9PaZCGT+qwIAxAktCW44VjYxVBMHbSEvpvryX6X1uOD4xhanEasK0z
+ 5//evqL/x6Y1gPHe7qL/e/tK/q8qiwbL4zVgc3PO/y0tuf9X1qX9X12f939NQ/7/WQVR/3d3Fv2fk+n7
+ f3amF34DtkANWFWb9n9tQy4YzymK+b+rs+D/nEyf/7MzfQgY0JL7/++/f/9drRb+31Sd8X9bdfr/PZ1F
+ /90tV/3/L8oAwfgM2FAe939zddL/7U1F/zPt9f9nORiA8d6OHOIMmBLv+H9anMN/RwWe/x2+tv+7fGwR
+ GtEwVgMKnLX+57po/HdU5PnvLMsFxuga8RqAF+PyArEAw+ZBAQAYhHHCULgAxQAAAABJRU5ErkJggg==
+
+
+
+ 227, 22
+
+
+ Import Extracted Skins Folder
+
+
+ 227, 22
+
+
+ Add Texture
+
+
+ 227, 22
+
+
+ Add File
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
+ vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xOdTWsmQAAABoSURBVDhPvcxB
+ CsAgDAVRL9GLZ+81cj2L0kA61UQoGPjgwnmlPFdrbavZn/AY+alqjjAikCKMZkCIMFoBS4SRn4h8xj4E
+ Zgj7FCDCfgvwCPstoF1l7DfQ3+xDwELuHECov1/xMcDPuhsgou11NRjL2QAAAABJRU5ErkJggg==
+
+
+
+ 157, 22
+
+
+ Import
+
+
+ 185, 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+wAAACOSURBVDhPpZJd
+ DoAwCIPZzwV2/8NiMGnEwlDjQ+MC9aNDRVXF1HtXEdnK+vB6XYfzGA3ozTlTyGuAPVtrARJMmXxvjHGD
+ pCYW99Zaamk+AfySLQX8KQBGBnmFBLwcM1SQkCATYnM9ADCN5eslYKfqGo8Av+lMAeCXaJMNwC+VgGpa
+ pt8AJL4V+CtUwo90ADqxXn/OjxN+AAAAAElFTkSuQmCC
+
+
+
+ 157, 22
+
+
+ Extract
+
+
+ 154, 6
+
+
+ 157, 22
+
+
+ Clone
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
+ vAAADrwBlbxySQAAACRJREFUOE9jYMAE/wlgkgBZmpDBqAGjBoDAqAFkGgDThAujAADOGivVQUoauAAA
+ AABJRU5ErkJggg==
+
+
+
+ 157, 22
+
+
+ Rename
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
+ vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMkMEa+wAAAC4SURBVDhPlVJR
+ DoUgDFsI/x7A63AvDso/XIBvfNliycCBviXLsLG11BERUYxRmiuEcPyDAbi4vfcyde/I8gyBWuvF1VqT
+ ZiylJHNFBkb8ZU3mMtzY5BscyJYbi9xzgIBFfnPTM1iRGdMO+XwL7kPUgtqhdrMNUQtaDnGVzyFa2BAi
+ 2gisYyDmnHsO5m9ZBasxPusQ4UKmc+6cbYOs52OZZtv6zmwbgqUUvGeuJ8J5CM7YsExWDl+wH0Tk2pdR
+ m6i0AAAAAElFTkSuQmCC
+
+
+
+ 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+wAAABPSURBVDhP5ZAx
+ DgAgCAMZ/f+HMcbYYOmg0UmHY2ibGzB3txNSgMKsHcD9ksBL5wcBPwyPCwLFJBjjVe4LFHGsgEDBAu6x
+ 4+AxAT9MkYJdKi90axNkwjxWAAAAAElFTkSuQmCC
+
+
+
+ 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.Controls.EditorControl`1[[PckStudio.Core.PackInfo, PckStudio.Core, Version=0.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/Extensions/AnimationExtensions.cs b/PCK-Studio/Extensions/AnimationExtensions.cs
deleted file mode 100644
index 81af938a..00000000
--- a/PCK-Studio/Extensions/AnimationExtensions.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using System.Drawing;
-using AnimatedGif;
-using PckStudio.Internal;
-
-namespace PckStudio.Extensions
-{
- internal static class AnimationExtensions
- {
- internal static Image CreateAnimationImage(this Animation animation)
- {
- if (animation.FrameCount == 0)
- {
- return null;
- }
- var ms = new System.IO.MemoryStream();
- var generateor = new AnimatedGifCreator(ms, GameConstants.GameTickInMilliseconds, 0);
- foreach (Animation.Frame frame in animation.GetInterpolatedFrames())
- {
- generateor.AddFrame(frame.Texture, frame.Ticks * GameConstants.GameTickInMilliseconds, GifQuality.Bit8);
- }
- ms.Position = 0;
- return Image.FromStream(ms);
- }
- }
-}
diff --git a/PCK-Studio/Extensions/ImageLayoutDirection.cs b/PCK-Studio/Extensions/ImageLayoutDirection.cs
deleted file mode 100644
index 7cfc23eb..00000000
--- a/PCK-Studio/Extensions/ImageLayoutDirection.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace PckStudio.Extensions
-{
- internal enum ImageLayoutDirection
- {
- Horizontal,
- Vertical
- }
-}
diff --git a/PCK-Studio/Extensions/PckAssetExtensions.cs b/PCK-Studio/Extensions/PckAssetExtensions.cs
deleted file mode 100644
index 08c3f96e..00000000
--- a/PCK-Studio/Extensions/PckAssetExtensions.cs
+++ /dev/null
@@ -1,125 +0,0 @@
-using System;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Drawing;
-using System.Collections.Generic;
-
-using OMI.Formats.Pck;
-using OMI.Workers;
-
-using PckStudio.Interfaces;
-using PckStudio.Internal.Deserializer;
-using PckStudio.Internal.Serializer;
-
-namespace PckStudio.Extensions
-{
- internal static class PckAssetExtensions
- {
- private const string MipMap = "MipMapLevel";
-
- internal static PckAsset CreateNewAssetIf(this PckFile pck, bool condition, string filename, PckAssetType filetype, IDataFormatWriter writer)
- {
- if (condition)
- {
- return pck.CreateNewAsset(filename, filetype, writer);
- }
- return default;
- }
-
- internal static PckAsset CreateNewAsset(this PckFile pck, string filename, PckAssetType filetype, IDataFormatWriter writer)
- {
- PckAsset asset = pck.CreateNewAsset(filename, filetype);
- asset.SetData(writer);
- return asset;
- }
-
- internal static Image GetTexture(this PckAsset asset)
- {
- if (asset.Type != PckAssetType.SkinFile &&
- asset.Type != PckAssetType.CapeFile &&
- asset.Type != PckAssetType.TextureFile)
- {
- throw new Exception("Asset is not suitable to contain image data.");
- }
- return asset.GetDeserializedData(ImageDeserializer.DefaultDeserializer);
- }
-
- internal static T GetDeserializedData(this PckAsset asset, IPckAssetDeserializer deserializer)
- {
- return deserializer.Deserialize(asset);
- }
-
- internal static T GetData(this PckAsset asset, IDataFormatReader formatReader) where T : class
- {
- using var ms = new MemoryStream(asset.Data);
- return formatReader.FromStream(ms);
- }
-
- internal static void SetSerializedData(this PckAsset asset, T obj, IPckAssetSerializer serializer)
- {
- serializer.Serialize(obj, ref asset);
- }
-
- internal static void SetData(this PckAsset asset, IDataFormatWriter formatWriter)
- {
- using (var stream = new MemoryStream())
- {
- formatWriter.WriteToStream(stream);
- asset.SetData(stream.ToArray());
- }
- }
-
- internal static void SetTexture(this PckAsset asset, Image image)
- {
- if (asset.Type != PckAssetType.SkinFile &&
- asset.Type != PckAssetType.CapeFile &&
- asset.Type != PckAssetType.TextureFile)
- {
- throw new Exception("Asset is not suitable to contain image data.");
- }
- asset.SetSerializedData(image, ImageSerializer.DefaultSerializer);
- }
-
- internal static bool IsMipmappedFile(this PckAsset asset)
- {
- // We only want to test the file name itself. ex: "terrainMipMapLevel2"
- string name = Path.GetFileNameWithoutExtension(asset.Filename);
-
- // check if last character is a digit (0-9). If not return false
- if (!char.IsDigit(name[name.Length - 1]))
- return false;
-
- // If string does not end with MipMapLevel, then it's not MipMapped
- if (!name.Remove(name.Length - 1, 1).EndsWith(MipMap))
- return false;
- return true;
- }
-
- internal static string GetNormalPath(this PckAsset asset)
- {
- if (!asset.IsMipmappedFile())
- return asset.Filename;
- string ext = Path.GetExtension(asset.Filename);
- return asset.Filename.Remove(asset.Filename.Length - (MipMap.Length + 1) - ext.Length) + ext;
- }
-
- internal static void DeserializeProperties(this PckAsset asset, IEnumerable serializedData)
- {
- IEnumerable> lines = serializedData
- .Select(line => line.Split([' '], 2))
- .Where (keyValue => keyValue.Length == 2)
- .Select(keyValue => new KeyValuePair(keyValue[0].Replace(":", ""), keyValue[1]));
- foreach (KeyValuePair kv in lines)
- {
- asset.AddProperty(kv);
- }
- }
-
- internal static IEnumerable SerializeProperties(this PckAsset asset, string seperater = ":")
- {
- IReadOnlyList> properties = asset.GetProperties();
- return properties.Select(property => property.Key + seperater + property.Value);
- }
- }
-}
diff --git a/PCK-Studio/External/API/Miles/Binka.cs b/PCK-Studio/External/API/Miles/Binka.cs
index 16e6ee96..47000ef8 100644
--- a/PCK-Studio/External/API/Miles/Binka.cs
+++ b/PCK-Studio/External/API/Miles/Binka.cs
@@ -2,7 +2,7 @@
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
-using PckStudio.Extensions;
+using PckStudio.Core.Extensions;
using PckStudio.Internal;
using PckStudio.Internal.App;
using SharpMSS;
diff --git a/PCK-Studio/FileFormats/CSMBFile.cs b/PCK-Studio/FileFormats/CSMBFile.cs
deleted file mode 100644
index b07d8f80..00000000
--- a/PCK-Studio/FileFormats/CSMBFile.cs
+++ /dev/null
@@ -1,102 +0,0 @@
-using System;
-using System.Drawing;
-using System.IO;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace PckStudio.FileFormats
-{
- #region File Structure
- /*
- Version - 4 bytes[int32]
- NumberOfParts - 4 bytes[int32]
- {
- Part name length - 2 bytes[int16]
- part name - x bytes
- part parent - 4 bytes[int32] (HEAD=1, BODY=2, LEG0=3, LEG1=4, ARM0=5, ARM1=6)
- Position-X - 4 bytes[float]
- Position-Y - 4 bytes[float]
- Position-Z - 4 bytes[float]
- Size-X - 4 bytes[float]
- Size-Y - 4 bytes[float]
- Size-Z - 4 bytes[float]
- UV-Y - 4 bytes[int32]
- UV-X - 4 bytes[int32]
- mirror texture - 1 byte[bool]
- Hide with armour - 1 byte[bool]
- inflation/scale value - 4 bytes[float]
- }
- NumberOfOffsets - 4 bytes[int32]
- {
- offset part - 4 bytes[int32]
- vertical offset - 4 bytes[float]
- }
- */
- #endregion
- class CSMBFile
- {
- public List Parts = new List();
- public List Offsets = new List();
- }
-
- public class CSMBPart
- {
- public string Name = "Partname";
- public CSMBParentPart Parent = 0;
- public float posX, posY, posZ = 0.0f;
- public float sizeX, sizeY, sizeZ = 0.0f;
- public int uvX, uvY = 0;
- public bool HideWArmour, MirrorTexture = false;
- public float Inflation = 0.0f;
- }
- public class CSMBOffset
- {
- public CSMBOffsetPart offsetPart = 0;
- public float VerticalOffset = 0.0f;
- }
-
- public enum CSMBOffsetPart
- {
- HEAD = 0,
- BODY = 1,
- ARM0 = 2,
- ARM1 = 3,
- LEG0 = 4,
- LEG1 = 5,
- HEADWEAR = 6,
- JACKET = 7,
- SLEEVE0 = 8,
- SLEEVE1 = 9,
- PANTS0 = 10,
- PANTS1 = 11,
- WAIST = 12,
- LEGGING0 = 13,
- LEGGING1 = 14,
- SOCK0 = 15,
- SOCK1 = 16,
- BOOT0 = 17,
- BOOT1 = 18,
- ARMARMOR1 = 19,
- ARMARMOR0 = 20,
- BODYARMOR = 21,
- BELT = 22,
- TOOL0 = 23,
- TOOL1 = 24,
- HELMET = 25,
- SHOULDER0 = 26,
- SHOULDER1 = 27,
- CHEST = 28
- }
-
- public enum CSMBParentPart
- {
- HEAD = 0,
- BODY = 1,
- ARM0 = 2,
- ARM1 = 3,
- LEG0 = 4,
- LEG1 = 5,
- }
-}
diff --git a/PCK-Studio/Forms/Additional-Popups/AddSkinPrompt.Designer.cs b/PCK-Studio/Forms/Additional-Popups/AddSkinPrompt.Designer.cs
index bd3df23c..52426b93 100644
--- a/PCK-Studio/Forms/Additional-Popups/AddSkinPrompt.Designer.cs
+++ b/PCK-Studio/Forms/Additional-Popups/AddSkinPrompt.Designer.cs
@@ -33,7 +33,6 @@
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AddSkinPrompt));
System.Windows.Forms.Label label2;
System.Windows.Forms.Label label1;
- this.textTheme = new System.Windows.Forms.TextBox();
this.contextMenuSkin = new System.Windows.Forms.ContextMenuStrip(this.components);
this.replaceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.contextMenuCape = new System.Windows.Forms.ContextMenuStrip(this.components);
@@ -81,11 +80,6 @@
label1.ForeColor = System.Drawing.Color.White;
label1.Name = "label1";
//
- // textTheme
- //
- resources.ApplyResources(this.textTheme, "textTheme");
- this.textTheme.Name = "textTheme";
- //
// contextMenuSkin
//
this.contextMenuSkin.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -289,6 +283,7 @@
// capePictureBox
//
resources.ApplyResources(this.capePictureBox, "capePictureBox");
+ this.capePictureBox.BackgroundInterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Default;
this.capePictureBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.capePictureBox.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
this.capePictureBox.Name = "capePictureBox";
@@ -298,6 +293,7 @@
// skinPictureBox
//
resources.ApplyResources(this.skinPictureBox, "skinPictureBox");
+ this.skinPictureBox.BackgroundInterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Default;
this.skinPictureBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.skinPictureBox.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
this.skinPictureBox.Name = "skinPictureBox";
@@ -343,7 +339,6 @@
}
#endregion
- private System.Windows.Forms.TextBox textTheme;
private System.Windows.Forms.ContextMenuStrip contextMenuSkin;
private System.Windows.Forms.ToolStripMenuItem replaceToolStripMenuItem;
private System.Windows.Forms.ContextMenuStrip contextMenuCape;
diff --git a/PCK-Studio/Forms/Additional-Popups/AddSkinPrompt.cs b/PCK-Studio/Forms/Additional-Popups/AddSkinPrompt.cs
index 0fa628c5..84cb7d7c 100644
--- a/PCK-Studio/Forms/Additional-Popups/AddSkinPrompt.cs
+++ b/PCK-Studio/Forms/Additional-Popups/AddSkinPrompt.cs
@@ -8,127 +8,92 @@ using OMI.Formats.Languages;
using OMI.Formats.Pck;
using PckStudio.Internal;
using PckStudio.Forms.Editor;
-using PckStudio.Internal.IO._3DST;
+using PckStudio.Core.IO._3DST;
using PckStudio.Properties;
using PckStudio.Forms;
-using PckStudio.Extensions;
+using PckStudio.Core.Extensions;
+using System.Linq;
+using System.Diagnostics;
+using PckStudio.Core.Skin;
+using PckStudio.Interfaces;
+using PckStudio.Core;
namespace PckStudio.Forms.Additional_Popups
{
public partial class AddSkinPrompt : MetroFramework.Forms.MetroForm
{
- public PckAsset SkinAsset => _skin;
- public PckAsset CapeAsset => _cape;
- public bool HasCape => _cape is not null;
+ public Skin NewSkin => newSkin;
- private LOCFile currentLoc;
- private PckAsset _skin = new PckAsset("dlcskinXYXYXYXY", PckAssetType.SkinFile);
- private PckAsset _cape;
- private SkinANIM _anim = SkinANIM.Empty;
+ private Skin newSkin;
private Random rng = new Random();
+ private int _xmlVersion = 0;
- private eSkinType skinType;
-
- private enum eSkinType
- {
- Invalid = -1,
- _64x64,
- _64x32,
- _64x64HD,
- _64x32HD,
- Custom,
- }
-
- public AddSkinPrompt(LOCFile loc)
+ public AddSkinPrompt(int xmlVersion = 0)
{
InitializeComponent();
- currentLoc = loc;
+ _xmlVersion = xmlVersion;
+ newSkin = new Skin("", new SkinANIM(SkinAnimMask.MODERN_WIDE_MODEL), Resources.classic_template, Enumerable.Empty(), Enumerable.Empty());
}
- private void CheckImage(Image img)
+ private void SetNewTexture(Image img)
{
- switch (img.Height)
+ Debug.Assert(img is not null, "Image is null.");
+
+ if (img.Width != img.Height && img.Height != img.Width / 2)
{
- case 64:
- _anim = _anim.SetFlag(SkinAnimFlag.RESOLUTION_64x64, true);
- MessageBox.Show(this, "64x64 Skin Detected");
- skinType = eSkinType._64x64;
- break;
- case 32:
- _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 = _anim.SetFlag(SkinAnimFlag.RESOLUTION_64x64, true);
- MessageBox.Show(this, "64x64 HD Skin Detected");
- skinType = eSkinType._64x64HD;
- break;
- }
-
- if (img.Height == img.Width / 2)
- {
- _anim = _anim.SetFlag(SkinAnimFlag.RESOLUTION_64x64 | SkinAnimFlag.SLIM_MODEL, false);
- MessageBox.Show(this, "64x32 HD Skin Detected");
- skinType = eSkinType._64x32HD;
- break;
- }
-
- MessageBox.Show(this, "Not a Valid Skin File");
- skinType = eSkinType.Invalid;
- return;
+ MessageBox.Show("The selected image does not suit a skin texture.", "Invalid image dimensions.", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ return;
}
+ newSkin.Anim.SetFlag(SkinAnimFlag.MODERN_WIDE_MODEL, img.Width == img.Height);
- skinPictureBox.Image = img;
+ skinPictureBox.Image = newSkin.Texture = img;
+ labelSelectTexture.Visible = false;
capePictureBox.Visible = true;
buttonCape.Visible = true;
capeLabel.Visible = true;
buttonDone.Enabled = true;
buttonAnimGen.Enabled = true;
- labelSelectTexture.Visible = false;
}
private void DrawModel()
{
- bool isSlim = _anim.GetFlag(SkinAnimFlag.SLIM_MODEL);
+ bool isSlim = newSkin.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(!newSkin.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 (!newSkin.Anim.GetFlag(SkinAnimFlag.TORSO_DISABLED))
{
//Body
g.DrawRectangle(outlineColor, 70, 55, 40, 60);
g.FillRectangle(fillColor, 71, 56, 39, 59);
}
- if (!_anim.GetFlag(SkinAnimFlag.RIGHT_ARM_DISABLED))
+ if (!newSkin.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 (!newSkin.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 (!newSkin.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 (!newSkin.Anim.GetFlag(SkinAnimFlag.LEFT_LEG_DISABLED))
{
//Leg1
g.DrawRectangle(outlineColor, 90, 115, 20, 60);
@@ -158,7 +123,7 @@ namespace PckStudio.Forms.Additional_Popups
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == DialogResult.OK)
{
- CheckImage(Image.FromFile(ofd.FileName));
+ SetNewTexture(Image.FromFile(ofd.FileName).ReleaseFromFile());
}
}
@@ -188,12 +153,14 @@ namespace PckStudio.Forms.Additional_Popups
using (FileStream fs = File.OpenRead(ofd.FileName))
{
var reader = new _3DSTextureReader();
- CheckImage(reader.FromStream(fs));
+ SetNewTexture(reader.FromStream(fs));
}
textSkinName.Text = Path.GetFileNameWithoutExtension(ofd.FileName);
return;
}
- CheckImage(Image.FromFile(ofd.FileName));
+
+ Image img = Image.FromFile(ofd.FileName).ReleaseFromFile();
+ SetNewTexture(img);
}
}
}
@@ -219,15 +186,13 @@ namespace PckStudio.Forms.Additional_Popups
ofd.Title = "Select a PNG File";
if (ofd.ShowDialog() == DialogResult.OK)
{
- var img = Image.FromFile(ofd.FileName);
+ Image img = Image.FromFile(ofd.FileName).ReleaseFromFile();
if (img.RawFormat != ImageFormat.Png && img.Width != img.Height * 2)
{
MessageBox.Show(this, "Not a Valid Cape File");
return;
}
- capePictureBox.Image = Image.FromFile(ofd.FileName);
- _cape ??= new PckAsset("dlccapeXYXYXYXY", PckAssetType.CapeFile);
- _cape.SetData(File.ReadAllBytes(ofd.FileName));
+ newSkin.CapeTexture = capePictureBox.Image = img;
contextMenuCape.Items[0].Text = "Replace";
capeLabel.Visible = false;
contextMenuCape.Visible = true;
@@ -237,43 +202,17 @@ namespace PckStudio.Forms.Additional_Popups
private void CreateButton_Click(object sender, EventArgs e)
{
- if (!int.TryParse(textSkinID.Text, out int skinId))
+ if (radioButtonManual.Checked)
{
- 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 skinIdStr = skinId.ToString("d08");
- _skin.Filename = $"dlcskin{skinIdStr}.png";
- _skin.AddProperty("DISPLAYNAME", textSkinName.Text);
-
- if (currentLoc is not null)
- {
- string skinDisplayNameLocKey = $"IDS_dlcskin{skinIdStr}_DISPLAYNAME";
- _skin.AddProperty("DISPLAYNAMEID", skinDisplayNameLocKey);
- currentLoc.AddLocKey(skinDisplayNameLocKey, textSkinName.Text);
- }
-
- if (!string.IsNullOrEmpty(textThemeName.Text))
- {
- _skin.AddProperty("THEMENAME", textThemeName.Text);
- if (currentLoc is not null)
+ if (!int.TryParse(textSkinID.Text, out int skinId))
{
- _skin.AddProperty("THEMENAMEID", $"IDS_dlcskin{skinIdStr}_THEMENAME");
- currentLoc.AddLocKey($"IDS_dlcskin{skinIdStr}_THEMENAME", textThemeName.Text);
+ MessageBox.Show("The Skin Id must be a unique 8 digit number that is not already in use", "Invalid Skin Id", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ return;
}
+ newSkin.Identifier = new SkinIdentifier(skinId);
}
- _skin.AddProperty("ANIM", _anim);
- _skin.AddProperty("GAME_FLAGS", "0x18");
- _skin.AddProperty("FREE", "1");
-
- if (HasCape)
- {
- _cape.Filename = $"dlccape{skinIdStr}.png";
- _skin.AddProperty("CAPEPATH", _cape.Filename);
- }
- _skin.SetTexture(skinPictureBox.Image);
+ newSkin.MetaData = new SkinMetaData(textSkinName.Text, textThemeName.Text);
DialogResult = DialogResult.OK;
- Close();
}
private void textSkinID_TextChanged(object sender, EventArgs e)
@@ -284,24 +223,21 @@ namespace PckStudio.Forms.Additional_Popups
private void CreateCustomModel_Click(object sender, EventArgs e)
{
- //Prompt for skin model generator
- if (MessageBox.Show(this, "Create your own custom skin model?", "", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1) != DialogResult.Yes)
+ if (MessageBox.Show("Create your own custom skin model?", "", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1) != DialogResult.Yes)
return;
- _skin.SetTexture(Resources.classic_template);
+ newSkin.MetaData = new SkinMetaData(textSkinName.Text, textThemeName.Text);
- using generateModel generate = new generateModel(_skin);
+ ISaveContext saveContext = new DelegatedSaveContext(Settings.Default.AutoSaveChanges, (customSkin) => newSkin = customSkin);
- if (generate.ShowDialog() == DialogResult.OK)
+ using CustomSkinEditor customSkinEditor = new CustomSkinEditor(newSkin, saveContext, _xmlVersion);
+
+ if (customSkinEditor.ShowDialog() == DialogResult.OK)
{
- displayBox.Image = generate.PreviewImage;
+ skinPictureBox.Image = newSkin.Texture;
buttonDone.Enabled = true;
labelSelectTexture.Visible = false;
- if (skinType != eSkinType._64x64 && skinType != eSkinType._64x64HD)
- {
- buttonSkin.Location = new Point(buttonSkin.Location.X - skinPictureBox.Width, buttonSkin.Location.Y);
- skinType = eSkinType._64x64;
- }
+ DrawModel();
}
}
@@ -309,8 +245,8 @@ namespace PckStudio.Forms.Additional_Popups
{
if (radioButtonAuto.Checked)
{
- int num = rng.Next(100000, 99999999);
- textSkinID.Text = num.ToString();
+ newSkin.Identifier = new(rng.Next(100000, 99999999));
+ textSkinID.Text = newSkin.Identifier.ToString();
textSkinID.Enabled = false;
}
}
@@ -322,10 +258,10 @@ namespace PckStudio.Forms.Additional_Popups
private void buttonAnimGen_Click(object sender, EventArgs e)
{
- using ANIMEditor diag = new ANIMEditor(_anim);
+ using ANIMEditor diag = new ANIMEditor(newSkin.Anim);
if (diag.ShowDialog(this) == DialogResult.OK)
{
- _anim = diag.ResultAnim;
+ newSkin.Anim = diag.ResultAnim;
DrawModel();
}
}
diff --git a/PCK-Studio/Forms/Additional-Popups/AddSkinPrompt.resx b/PCK-Studio/Forms/Additional-Popups/AddSkinPrompt.resx
index 6e87bf23..4255bf1a 100644
--- a/PCK-Studio/Forms/Additional-Popups/AddSkinPrompt.resx
+++ b/PCK-Studio/Forms/Additional-Popups/AddSkinPrompt.resx
@@ -219,21 +219,6 @@
19
-
- 102, 78
-
-
- 239, 20
-
-
- 32
-
-
- textTheme
-
-
- System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
17, 17
@@ -654,9 +639,6 @@
4
-
- False
-
108, 259
diff --git a/PCK-Studio/Forms/Additional-Popups/Animation/ChangeTile.cs b/PCK-Studio/Forms/Additional-Popups/Animation/ChangeTile.cs
index 58fdc3aa..de2fa054 100644
--- a/PCK-Studio/Forms/Additional-Popups/Animation/ChangeTile.cs
+++ b/PCK-Studio/Forms/Additional-Popups/Animation/ChangeTile.cs
@@ -1,14 +1,10 @@
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Windows.Forms;
-using MetroFramework.Controls;
-using System.Xml.Linq;
-using MetroFramework.Forms;
-using PckStudio.Extensions;
-using PckStudio.Internal;
-using PckStudio.Internal.App;
-using PckStudio.Internal.Json;
+using PckStudio.Core;
+using PckStudio.Core.Json;
+using PckStudio.Json;
+using PckStudio.Core.Extensions;
namespace PckStudio.Forms.Additional_Popups.Animation
{
@@ -32,10 +28,8 @@ namespace PckStudio.Forms.Additional_Popups.Animation
private void InitializeTreeviews()
{
- Profiler.Start();
GetTileDataToView(ResourceCategory.BlockAnimation);
GetTileDataToView(ResourceCategory.ItemAnimation);
- Profiler.Stop();
}
public DialogResult ShowDialog(IWin32Window owner)
diff --git a/PCK-Studio/Forms/Additional-Popups/EntityForms/AddEntry.cs b/PCK-Studio/Forms/Additional-Popups/EntityForms/AddEntry.cs
index 1057ab70..9b76ad87 100644
--- a/PCK-Studio/Forms/Additional-Popups/EntityForms/AddEntry.cs
+++ b/PCK-Studio/Forms/Additional-Popups/EntityForms/AddEntry.cs
@@ -2,7 +2,8 @@
using System.Collections.Generic;
using System.Windows.Forms;
using PckStudio.Forms.Additional_Popups.Animation;
-using PckStudio.Internal.Json;
+using PckStudio.Core.Json;
+using PckStudio.Json;
namespace PckStudio.Forms.Additional_Popups.EntityForms
diff --git a/PCK-Studio/Forms/Additional-Popups/FilterPrompt.cs b/PCK-Studio/Forms/Additional-Popups/FilterPrompt.cs
index d86ea855..21ed53e2 100644
--- a/PCK-Studio/Forms/Additional-Popups/FilterPrompt.cs
+++ b/PCK-Studio/Forms/Additional-Popups/FilterPrompt.cs
@@ -77,7 +77,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
+ // Some code in this function is modified code from this StackOverflow answer - MayNL
// 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
diff --git a/PCK-Studio/Forms/Additional-Popups/ItemSelectionPopUp.cs b/PCK-Studio/Forms/Additional-Popups/ItemSelectionPopUp.cs
index f84b95a5..c872cfdd 100644
--- a/PCK-Studio/Forms/Additional-Popups/ItemSelectionPopUp.cs
+++ b/PCK-Studio/Forms/Additional-Popups/ItemSelectionPopUp.cs
@@ -27,8 +27,11 @@ namespace PckStudio.Forms.Additional_Popups
private void okBtn_Click(object sender, EventArgs e)
{
- if(ComboBox.SelectedIndex > -1)
+ if(ComboBox.SelectedIndex <= -1)
+ {
cancelButton_Click(sender, e);
+ return;
+ }
DialogResult = DialogResult.OK;
}
diff --git a/PCK-Studio/Forms/Additional-Popups/NumericPrompt.Designer.cs b/PCK-Studio/Forms/Additional-Popups/NumericPrompt.Designer.cs
index 7bead21f..7c104732 100644
--- a/PCK-Studio/Forms/Additional-Popups/NumericPrompt.Designer.cs
+++ b/PCK-Studio/Forms/Additional-Popups/NumericPrompt.Designer.cs
@@ -31,8 +31,8 @@
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(NumericPrompt));
this.TextLabel = new System.Windows.Forms.Label();
this.OKButton = new System.Windows.Forms.Button();
- this.ContextLabel = new MetroFramework.Controls.MetroLabel();
this.ValueUpDown = new System.Windows.Forms.NumericUpDown();
+ this.toolTipLabel = new MetroFramework.Controls.MetroLabel();
((System.ComponentModel.ISupportInitialize)(this.ValueUpDown)).BeginInit();
this.SuspendLayout();
//
@@ -50,26 +50,28 @@
this.OKButton.UseVisualStyleBackColor = true;
this.OKButton.Click += new System.EventHandler(this.OKBtn_Click);
//
- // ContextLabel
- //
- resources.ApplyResources(this.ContextLabel, "ContextLabel");
- this.ContextLabel.FontSize = MetroFramework.MetroLabelSize.Small;
- this.ContextLabel.Name = "ContextLabel";
- this.ContextLabel.Theme = MetroFramework.MetroThemeStyle.Dark;
- this.ContextLabel.WrapToLine = true;
- //
// ValueUpDown
//
resources.ApplyResources(this.ValueUpDown, "ValueUpDown");
+ this.ValueUpDown.BackColor = System.Drawing.SystemColors.WindowText;
+ this.ValueUpDown.ForeColor = System.Drawing.SystemColors.Window;
this.ValueUpDown.Name = "ValueUpDown";
//
+ // toolTipLabel
+ //
+ resources.ApplyResources(this.toolTipLabel, "toolTipLabel");
+ this.toolTipLabel.FontSize = MetroFramework.MetroLabelSize.Small;
+ this.toolTipLabel.Name = "toolTipLabel";
+ this.toolTipLabel.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.toolTipLabel.WrapToLine = true;
+ //
// NumericPrompt
//
this.AcceptButton = this.OKButton;
resources.ApplyResources(this, "$this");
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.ValueUpDown);
- this.Controls.Add(this.ContextLabel);
+ this.Controls.Add(this.toolTipLabel);
this.Controls.Add(this.OKButton);
this.Controls.Add(this.TextLabel);
this.MaximizeBox = false;
@@ -89,7 +91,7 @@
#endregion
public System.Windows.Forms.Button OKButton;
public System.Windows.Forms.Label TextLabel;
- public MetroFramework.Controls.MetroLabel ContextLabel;
private System.Windows.Forms.NumericUpDown ValueUpDown;
+ private MetroFramework.Controls.MetroLabel toolTipLabel;
}
}
\ No newline at end of file
diff --git a/PCK-Studio/Forms/Additional-Popups/NumericPrompt.cs b/PCK-Studio/Forms/Additional-Popups/NumericPrompt.cs
index 5ebf4bbf..5fad9a9b 100644
--- a/PCK-Studio/Forms/Additional-Popups/NumericPrompt.cs
+++ b/PCK-Studio/Forms/Additional-Popups/NumericPrompt.cs
@@ -6,23 +6,66 @@ namespace PckStudio
{
public partial class NumericPrompt : MetroForm
{
- public int SelectedValue => (int)ValueUpDown.Value;
+ public decimal SelectedValue => ValueUpDown.Value;
+
+ public int SelectedValueAsInt => (int)SelectedValue;
- public int Minimum { set => ValueUpDown.Minimum = value; }
- public int Maximum { set => ValueUpDown.Maximum = value; }
+ public string ToolTipText
+ {
+ get => toolTipLabel.Text;
+ set => toolTipLabel.Text = value;
+ }
+
+ public decimal ValueStep
+ {
+ get => ValueUpDown.Increment;
+ set => ValueUpDown.Increment = value;
+ }
+
+ public int DecimalPlaces
+ {
+ get => ValueUpDown.DecimalPlaces;
+ set => ValueUpDown.DecimalPlaces = value;
+ }
+
+ public decimal Minimum
+ {
+ get => ValueUpDown.Minimum;
+ set => ValueUpDown.Minimum = value;
+ }
+
+ public decimal Maximum
+ {
+ get => ValueUpDown.Maximum;
+ set => ValueUpDown.Maximum = value;
+ }
+
+ private NumericPrompt()
+ {
+ InitializeComponent();
+ }
public NumericPrompt(int initialValue)
: this(initialValue, int.MinValue, int.MaxValue)
{
+ }
+ public NumericPrompt(decimal initialValue, decimal minimum, decimal maximum)
+ : this()
+ {
+ Minimum = minimum;
+ Maximum = maximum;
+ ValueUpDown.Value = initialValue;
}
public NumericPrompt(int initialValue, int minimum, int maximum)
+ : this((decimal)initialValue, minimum, maximum)
+ {
+ }
+
+ public NumericPrompt(float initialValue, float minimum, float maximum)
+ : this((decimal)initialValue, (decimal)minimum, (decimal)maximum)
{
- InitializeComponent();
- ValueUpDown.Value = initialValue;
- Minimum = minimum;
- Maximum = maximum;
}
private void OKBtn_Click(object sender, EventArgs e)
@@ -32,9 +75,9 @@ namespace PckStudio
private void RenamePrompt_Load(object sender, EventArgs e)
{
- if(string.IsNullOrEmpty(ContextLabel.Text))
+ if (string.IsNullOrEmpty(toolTipLabel.Text))
{
- ContextLabel.Visible = false;
+ toolTipLabel.Visible = false;
Size = new System.Drawing.Size(264, 85);
}
}
diff --git a/PCK-Studio/Forms/Additional-Popups/NumericPrompt.resx b/PCK-Studio/Forms/Additional-Popups/NumericPrompt.resx
index 97fc650e..fd242b82 100644
--- a/PCK-Studio/Forms/Additional-Popups/NumericPrompt.resx
+++ b/PCK-Studio/Forms/Additional-Popups/NumericPrompt.resx
@@ -119,15 +119,18 @@
- Bottom
+ Bottom, Left
True
+
+ NoControl
+
- 19, 90
+ 19, 38
34, 13
@@ -163,7 +166,7 @@
NoControl
- 95, 118
+ 83, 66
75, 23
@@ -186,38 +189,14 @@
2
-
- Top
-
-
- 28, 27
-
-
- 208, 58
-
-
- 6
-
-
- TopCenter
-
-
- ContextLabel
-
-
- MetroFramework.Controls.MetroLabel, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a
-
-
- $this
-
-
- 1
+
+ Bottom, Left, Right
- 71, 88
+ 71, 36
- 164, 20
+ 141, 20
7
@@ -234,14 +213,47 @@
0
+
+ False
+
+
+ 3, 11
+
+
+ 235, 22
+
+
+ 235, 22
+
+
+ 6
+
+
+ TopCenter
+
+
+ toolTipLabel
+
+
+ MetroFramework.Controls.MetroLabel, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a
+
+
+ $this
+
+
+ 1
+
True
6, 13
+
+ GrowAndShrink
+
- 264, 150
+ 241, 98
@@ -2749,6 +2761,12 @@
AP//AAA=
+
+ 4, 2, 4, 2
+
+
+ 0, 60, 0, 0
+
CenterParent
diff --git a/PCK-Studio/Forms/AppSettingsForm.Designer.cs b/PCK-Studio/Forms/AppSettingsForm.Designer.cs
index 00ed901a..4fc1d0f8 100644
--- a/PCK-Studio/Forms/AppSettingsForm.Designer.cs
+++ b/PCK-Studio/Forms/AppSettingsForm.Designer.cs
@@ -63,7 +63,6 @@
this.Resizable = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Style = MetroFramework.MetroColorStyle.Black;
- this.Text = "Application Settings";
this.Theme = MetroFramework.MetroThemeStyle.Dark;
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.AppBehaviorSettingsForm_FormClosing);
this.ResumeLayout(false);
diff --git a/PCK-Studio/Forms/AppSettingsForm.cs b/PCK-Studio/Forms/AppSettingsForm.cs
index f9aa41d5..3bbd5509 100644
--- a/PCK-Studio/Forms/AppSettingsForm.cs
+++ b/PCK-Studio/Forms/AppSettingsForm.cs
@@ -5,6 +5,8 @@ using System.Diagnostics;
using System.Windows.Forms;
using MetroFramework.Controls;
using MetroFramework.Forms;
+using PckStudio.Core.App;
+using PckStudio.Internal.App;
using PckStudio.Properties;
namespace PckStudio.Forms
@@ -12,57 +14,84 @@ namespace PckStudio.Forms
public partial class AppSettingsForm : MetroForm
{
private ApplicationSettingsBase _applicationSettings;
+ internal const string keyToStringContextKey = "keyToString";
public AppSettingsForm()
- : this(Settings.Default)
+ : this("Application Settings", Settings.Default, new Dictionary()
+ {
+ ["ShowRichPresence"] = "Show Rich Presence",
+ ["AutoSaveChanges"] = "Auto Save",
+ ["UseLittleEndianAsDefault"] = "Open as Little Endian",
+ ["AutoUpdate"] = "Auto Update",
+ ["LoadSubPcks"] = "Load Sub Pcks",
+ ["UsePrerelease"] = "Use Prerelease",
+ ["ValidateImageDimension"] = "Validate skin dimension",
+ })
{
}
- public AppSettingsForm(ApplicationSettingsBase applicationSettings)
+ public AppSettingsForm(string title, ApplicationSettingsBase applicationSettings, Dictionary keyToStringMap = null)
{
InitializeComponent();
+ Text = title;
_applicationSettings = applicationSettings;
+ if (keyToStringMap is not null && !_applicationSettings.Context.ContainsKey(SettingsManager.KeyToStringContextKeyConst))
+ _applicationSettings.Context.Add(SettingsManager.KeyToStringContextKeyConst, keyToStringMap);
LoadSettings();
}
- private static Dictionary CheckBoxText = new Dictionary()
+ static bool ContextTryGetKeyToString(SettingsContext context, string key, out string value)
{
- ["ShowRichPresence"] = "Show Rich Presence",
- ["AutoSaveChanges"] = "Auto Save",
- ["UseLittleEndianAsDefault"] = "Open as Little Endian",
- ["AutoUpdate"] = "Auto Update",
- ["LoadSubPcks"] = "Load Sub Pcks",
- ["UsePrerelease"] = "Use Prerelease",
- };
-
- private void CheckBox_CheckedChanged(object sender, EventArgs e)
- {
- if (sender is CheckBox checkBox && checkBox.Tag is string settingsKey && _applicationSettings[settingsKey] is bool)
- {
- _applicationSettings[settingsKey] = checkBox.Checked;
- }
+ value = default;
+ return
+ context.ContainsKey(SettingsManager.KeyToStringContextKeyConst) &&
+ context[SettingsManager.KeyToStringContextKeyConst] is Dictionary keyToString &&
+ keyToString.TryGetValue(key, out value);
}
+ static Control CreateCheckBox(SettingsPropertyValue propertyValue, SettingsBase settings)
+ {
+ var control = new MetroCheckBox
+ {
+ Name = propertyValue.Name,
+ Tag = propertyValue.Name,
+ Text = ContextTryGetKeyToString(settings.Context, propertyValue.Name, out string name) ? name : propertyValue.Name,
+ Checked = (bool)propertyValue.PropertyValue,
+
+ AutoSize = true,
+ Theme = MetroFramework.MetroThemeStyle.Dark,
+ Style = MetroFramework.MetroColorStyle.White,
+ };
+
+ void CheckBox_CheckedChanged(object sender, EventArgs e)
+ {
+ if (sender is CheckBox checkBox && checkBox.Tag is string settingsKey && settings[settingsKey] is bool)
+ {
+ settings[settingsKey] = checkBox.Checked;
+ }
+ }
+
+ control.CheckedChanged += CheckBox_CheckedChanged;
+ return control;
+ }
+
+ delegate Control ControlCreateDelegate(SettingsPropertyValue propertyValue, SettingsBase settings);
+
+ Dictionary _typeToControl = new Dictionary()
+ {
+ [typeof(bool)] = CreateCheckBox,
+ };
+
private void LoadSettings()
{
foreach (SettingsPropertyValue item in _applicationSettings.PropertyValues)
{
Debug.WriteLine($"{item.Property.Name}: {item.Property.PropertyType}");
- if (!item.Property.Attributes.ContainsKey(typeof(UserScopedSettingAttribute)) || item.Property.PropertyType != typeof(bool))
+ bool isUserScoped = item.Property.Attributes?.ContainsKey(typeof(UserScopedSettingAttribute)) ?? true;
+ if (!isUserScoped || !_typeToControl.ContainsKey(item.Property.PropertyType) || item.Property.IsReadOnly)
continue;
- var checkBox = new MetroCheckBox
- {
- Name = item.Name,
- Tag = item.Name,
- Text = CheckBoxText.ContainsKey(item.Name) ? CheckBoxText[item.Name] : item.Name,
- Checked = (bool)item.PropertyValue,
-
- AutoSize = true,
- Theme = MetroFramework.MetroThemeStyle.Dark,
- Style = MetroFramework.MetroColorStyle.White,
- };
- checkBox.CheckedChanged += CheckBox_CheckedChanged;
- flowLayoutPanel.Controls.Add(checkBox);
+ Control control = _typeToControl[item.Property.PropertyType](item, _applicationSettings);
+ flowLayoutPanel.Controls.Add(control);
}
}
diff --git a/PCK-Studio/Forms/ContributorsForm.Designer.cs b/PCK-Studio/Forms/ContributorsForm.Designer.cs
index 1fdb6b58..749c7db5 100644
--- a/PCK-Studio/Forms/ContributorsForm.Designer.cs
+++ b/PCK-Studio/Forms/ContributorsForm.Designer.cs
@@ -70,9 +70,9 @@
metroLabel5.Enabled = false;
metroLabel5.Location = new System.Drawing.Point(397, 456);
metroLabel5.Name = "metroLabel5";
- metroLabel5.Size = new System.Drawing.Size(300, 19);
+ metroLabel5.Size = new System.Drawing.Size(298, 19);
metroLabel5.TabIndex = 5;
- metroLabel5.Text = "Additional development by MattNL and Miku-666";
+ metroLabel5.Text = "Additional development by Miku-666 and MayNL";
metroLabel5.Theme = MetroFramework.MetroThemeStyle.Dark;
//
// metroLabel6
diff --git a/PCK-Studio/Forms/Editor/ANIMEditor.Designer.cs b/PCK-Studio/Forms/Editor/ANIMEditor.Designer.cs
index 7941ddce..833ed19b 100644
--- a/PCK-Studio/Forms/Editor/ANIMEditor.Designer.cs
+++ b/PCK-Studio/Forms/Editor/ANIMEditor.Designer.cs
@@ -53,7 +53,7 @@
this.leftArmorCheckBox = new MetroFramework.Controls.MetroCheckBox();
this.chestplateCheckBox = new MetroFramework.Controls.MetroCheckBox();
this.groupBox1 = new System.Windows.Forms.GroupBox();
- this.unknownCheckBox = new MetroFramework.Controls.MetroCheckBox();
+ this.animationOverrideCheckBox = new MetroFramework.Controls.MetroCheckBox();
this.crouchCheckBox = new MetroFramework.Controls.MetroCheckBox();
this.dinnerboneCheckBox = new MetroFramework.Controls.MetroCheckBox();
this.noArmorCheckBox = new MetroFramework.Controls.MetroCheckBox();
@@ -120,9 +120,9 @@
this.rightLegOCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Medium;
this.rightLegOCheckBox.Location = new System.Drawing.Point(180, 208);
this.rightLegOCheckBox.Name = "rightLegOCheckBox";
- this.rightLegOCheckBox.Size = new System.Drawing.Size(199, 19);
+ this.rightLegOCheckBox.Size = new System.Drawing.Size(174, 19);
this.rightLegOCheckBox.TabIndex = 13;
- this.rightLegOCheckBox.Text = "Remove Right Leg Layer Box";
+ this.rightLegOCheckBox.Text = "Remove Right Pants Box";
this.rightLegOCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
this.toolTip.SetToolTip(this.rightLegOCheckBox, " Removes the parent Box for this part. You can still make new boxes f" +
"or this part. Armor will be disabled for this part, but can be rendered again wi" +
@@ -135,9 +135,9 @@
this.headOCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Medium;
this.headOCheckBox.Location = new System.Drawing.Point(180, 50);
this.headOCheckBox.Name = "headOCheckBox";
- this.headOCheckBox.Size = new System.Drawing.Size(173, 19);
+ this.headOCheckBox.Size = new System.Drawing.Size(165, 19);
this.headOCheckBox.TabIndex = 12;
- this.headOCheckBox.Text = "Remove Head Layer Box";
+ this.headOCheckBox.Text = "Remove Headwear Box";
this.headOCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
this.toolTip.SetToolTip(this.headOCheckBox, " Removes the parent Box for this part. You can still make new boxes f" +
"or this part. Armor will be disabled for this part, but can be rendered again wi" +
@@ -150,9 +150,9 @@
this.leftLegOCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Medium;
this.leftLegOCheckBox.Location = new System.Drawing.Point(180, 174);
this.leftLegOCheckBox.Name = "leftLegOCheckBox";
- this.leftLegOCheckBox.Size = new System.Drawing.Size(190, 19);
+ this.leftLegOCheckBox.Size = new System.Drawing.Size(165, 19);
this.leftLegOCheckBox.TabIndex = 11;
- this.leftLegOCheckBox.Text = "Remove Left Leg Layer Box";
+ this.leftLegOCheckBox.Text = "Remove Left Pants Box";
this.leftLegOCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
this.toolTip.SetToolTip(this.leftLegOCheckBox, " Removes the parent Box for this part. You can still make new boxes f" +
"or this part. Armor will be disabled for this part, but can be rendered again wi" +
@@ -165,9 +165,9 @@
this.leftArmOCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Medium;
this.leftArmOCheckBox.Location = new System.Drawing.Point(180, 112);
this.leftArmOCheckBox.Name = "leftArmOCheckBox";
- this.leftArmOCheckBox.Size = new System.Drawing.Size(194, 19);
+ this.leftArmOCheckBox.Size = new System.Drawing.Size(169, 19);
this.leftArmOCheckBox.TabIndex = 9;
- this.leftArmOCheckBox.Text = "Remove Left Arm Layer Box";
+ this.leftArmOCheckBox.Text = "Remove Left Sleeve Box";
this.leftArmOCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
this.toolTip.SetToolTip(this.leftArmOCheckBox, " Removes the parent Box for this part. You can still make new boxes f" +
"or this part. Armor will be disabled for this part, but can be rendered again wi" +
@@ -180,9 +180,9 @@
this.bodyOCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Medium;
this.bodyOCheckBox.Location = new System.Drawing.Point(180, 81);
this.bodyOCheckBox.Name = "bodyOCheckBox";
- this.bodyOCheckBox.Size = new System.Drawing.Size(172, 19);
+ this.bodyOCheckBox.Size = new System.Drawing.Size(141, 19);
this.bodyOCheckBox.TabIndex = 8;
- this.bodyOCheckBox.Text = "Remove Body Layer Box";
+ this.bodyOCheckBox.Text = "Remove Jacket Box";
this.bodyOCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
this.toolTip.SetToolTip(this.bodyOCheckBox, " Removes the parent Box for this part. You can still make new boxes f" +
"or this part. Armor will be disabled for this part, but can be rendered again wi" +
@@ -210,9 +210,9 @@
this.slimCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Medium;
this.slimCheckBox.Location = new System.Drawing.Point(180, 19);
this.slimCheckBox.Name = "slimCheckBox";
- this.slimCheckBox.Size = new System.Drawing.Size(151, 19);
+ this.slimCheckBox.Size = new System.Drawing.Size(164, 19);
this.slimCheckBox.TabIndex = 6;
- this.slimCheckBox.Text = "64x64 Alex/Slim Skin";
+ this.slimCheckBox.Text = "64x64 Slim Skin Model";
this.slimCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
this.toolTip.SetToolTip(this.slimCheckBox, " The 1.8 style skin type with slim arms, overlays for each part, and sep" +
"arate textures for right and left limbs. Resolution is also set to 64x64. " +
@@ -285,9 +285,9 @@
this.bodyCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Medium;
this.bodyCheckBox.Location = new System.Drawing.Point(6, 81);
this.bodyCheckBox.Name = "bodyCheckBox";
- this.bodyCheckBox.Size = new System.Drawing.Size(135, 19);
+ this.bodyCheckBox.Size = new System.Drawing.Size(137, 19);
this.bodyCheckBox.TabIndex = 1;
- this.bodyCheckBox.Text = "Remove Body Box";
+ this.bodyCheckBox.Text = "Remove Torso Box";
this.bodyCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
this.toolTip.SetToolTip(this.bodyCheckBox, " Removes the parent Box for this part. You can still make new boxes f" +
"or this part. Armor will be disabled for this part, but can be rendered again wi" +
@@ -300,9 +300,9 @@
this.classicCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Medium;
this.classicCheckBox.Location = new System.Drawing.Point(6, 19);
this.classicCheckBox.Name = "classicCheckBox";
- this.classicCheckBox.Size = new System.Drawing.Size(136, 19);
+ this.classicCheckBox.Size = new System.Drawing.Size(170, 19);
this.classicCheckBox.TabIndex = 0;
- this.classicCheckBox.Text = "64x64 Classic Skin";
+ this.classicCheckBox.Text = "64x64 Wide Skin Model";
this.classicCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
this.toolTip.SetToolTip(this.classicCheckBox, " The 1.8 style skin type with overlays for each part and separate textur" +
"es for right and left limbs. Resolution is also set to 64x64. ");
@@ -315,9 +315,9 @@
this.rightArmOCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Medium;
this.rightArmOCheckBox.Location = new System.Drawing.Point(180, 143);
this.rightArmOCheckBox.Name = "rightArmOCheckBox";
- this.rightArmOCheckBox.Size = new System.Drawing.Size(203, 19);
+ this.rightArmOCheckBox.Size = new System.Drawing.Size(178, 19);
this.rightArmOCheckBox.TabIndex = 10;
- this.rightArmOCheckBox.Text = "Remove Right Arm Layer Box";
+ this.rightArmOCheckBox.Text = "Remove Right Sleeve Box";
this.rightArmOCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
this.toolTip.SetToolTip(this.rightArmOCheckBox, " Removes the parent Box for this part. You can still make new boxes f" +
"or this part. Armor will be disabled for this part, but can be rendered again wi" +
@@ -347,9 +347,9 @@
this.rightLeggingCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Medium;
this.rightLeggingCheckBox.Location = new System.Drawing.Point(6, 174);
this.rightLeggingCheckBox.Name = "rightLeggingCheckBox";
- this.rightLeggingCheckBox.Size = new System.Drawing.Size(173, 19);
+ this.rightLeggingCheckBox.Size = new System.Drawing.Size(163, 19);
this.rightLeggingCheckBox.TabIndex = 7;
- this.rightLeggingCheckBox.Text = "Render Right Leg Armor";
+ this.rightLeggingCheckBox.Text = "Show Right Leg Armor";
this.rightLeggingCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
this.toolTip.SetToolTip(this.rightLeggingCheckBox, " Forcefully enables the specified armor piece.");
this.rightLeggingCheckBox.UseSelectable = true;
@@ -361,9 +361,9 @@
this.helmetCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Medium;
this.helmetCheckBox.Location = new System.Drawing.Point(6, 19);
this.helmetCheckBox.Name = "helmetCheckBox";
- this.helmetCheckBox.Size = new System.Drawing.Size(147, 19);
+ this.helmetCheckBox.Size = new System.Drawing.Size(137, 19);
this.helmetCheckBox.TabIndex = 5;
- this.helmetCheckBox.Text = "Render Head Armor";
+ this.helmetCheckBox.Text = "Show Head Armor";
this.helmetCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
this.toolTip.SetToolTip(this.helmetCheckBox, " Forcefully enables the specified armor piece.");
this.helmetCheckBox.UseSelectable = true;
@@ -375,9 +375,9 @@
this.leftLeggingCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Medium;
this.leftLeggingCheckBox.Location = new System.Drawing.Point(6, 143);
this.leftLeggingCheckBox.Name = "leftLeggingCheckBox";
- this.leftLeggingCheckBox.Size = new System.Drawing.Size(164, 19);
+ this.leftLeggingCheckBox.Size = new System.Drawing.Size(154, 19);
this.leftLeggingCheckBox.TabIndex = 4;
- this.leftLeggingCheckBox.Text = "Render Left Leg Armor";
+ this.leftLeggingCheckBox.Text = "Show Left Leg Armor";
this.leftLeggingCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
this.toolTip.SetToolTip(this.leftLeggingCheckBox, " Forcefully enables the specified armor piece.");
this.leftLeggingCheckBox.UseSelectable = true;
@@ -389,9 +389,9 @@
this.rightArmorCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Medium;
this.rightArmorCheckBox.Location = new System.Drawing.Point(6, 112);
this.rightArmorCheckBox.Name = "rightArmorCheckBox";
- this.rightArmorCheckBox.Size = new System.Drawing.Size(177, 19);
+ this.rightArmorCheckBox.Size = new System.Drawing.Size(167, 19);
this.rightArmorCheckBox.TabIndex = 3;
- this.rightArmorCheckBox.Text = "Render Right Arm Armor";
+ this.rightArmorCheckBox.Text = "Show Right Arm Armor";
this.rightArmorCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
this.toolTip.SetToolTip(this.rightArmorCheckBox, " Forcefully enables the specified armor piece.");
this.rightArmorCheckBox.UseSelectable = true;
@@ -403,9 +403,9 @@
this.leftArmorCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Medium;
this.leftArmorCheckBox.Location = new System.Drawing.Point(6, 81);
this.leftArmorCheckBox.Name = "leftArmorCheckBox";
- this.leftArmorCheckBox.Size = new System.Drawing.Size(168, 19);
+ this.leftArmorCheckBox.Size = new System.Drawing.Size(158, 19);
this.leftArmorCheckBox.TabIndex = 2;
- this.leftArmorCheckBox.Text = "Render Left Arm Armor";
+ this.leftArmorCheckBox.Text = "Show Left Arm Armor";
this.leftArmorCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
this.toolTip.SetToolTip(this.leftArmorCheckBox, " Forcefully enables the specified armor piece.");
this.leftArmorCheckBox.UseSelectable = true;
@@ -413,20 +413,21 @@
// chestplateCheckBox
//
this.chestplateCheckBox.AutoSize = true;
+ this.chestplateCheckBox.BackColor = System.Drawing.Color.IndianRed;
this.chestplateCheckBox.Enabled = false;
this.chestplateCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Medium;
this.chestplateCheckBox.Location = new System.Drawing.Point(6, 50);
this.chestplateCheckBox.Name = "chestplateCheckBox";
- this.chestplateCheckBox.Size = new System.Drawing.Size(146, 19);
+ this.chestplateCheckBox.Size = new System.Drawing.Size(138, 19);
this.chestplateCheckBox.TabIndex = 1;
- this.chestplateCheckBox.Text = "Render Body Armor";
+ this.chestplateCheckBox.Text = "Show Torso Armor";
this.chestplateCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
this.toolTip.SetToolTip(this.chestplateCheckBox, " Forcefully enables the specified armor piece.");
this.chestplateCheckBox.UseSelectable = true;
//
// groupBox1
//
- this.groupBox1.Controls.Add(this.unknownCheckBox);
+ this.groupBox1.Controls.Add(this.animationOverrideCheckBox);
this.groupBox1.Controls.Add(this.crouchCheckBox);
this.groupBox1.Controls.Add(this.dinnerboneCheckBox);
this.groupBox1.Controls.Add(this.noArmorCheckBox);
@@ -446,19 +447,19 @@
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Special Animations";
//
- // unknownCheckBox
+ // animationOverrideCheckBox
//
- this.unknownCheckBox.AutoSize = true;
- this.unknownCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Medium;
- this.unknownCheckBox.Location = new System.Drawing.Point(126, 81);
- this.unknownCheckBox.Name = "unknownCheckBox";
- this.unknownCheckBox.Size = new System.Drawing.Size(84, 19);
- this.unknownCheckBox.TabIndex = 13;
- this.unknownCheckBox.Text = "Unknown";
- this.unknownCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
- this.toolTip.SetToolTip(this.unknownCheckBox, " If you figure out what this is. Please reach out to MNL#8935 on Discord. (: " +
- "");
- this.unknownCheckBox.UseSelectable = true;
+ this.animationOverrideCheckBox.AutoSize = true;
+ this.animationOverrideCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Medium;
+ this.animationOverrideCheckBox.Location = new System.Drawing.Point(126, 81);
+ this.animationOverrideCheckBox.Name = "animationOverrideCheckBox";
+ this.animationOverrideCheckBox.Size = new System.Drawing.Size(145, 19);
+ this.animationOverrideCheckBox.TabIndex = 13;
+ this.animationOverrideCheckBox.Text = "Animation Override";
+ this.animationOverrideCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.toolTip.SetToolTip(this.animationOverrideCheckBox, "Forcefully display skin effects despite the game\'s \"Custom Skin Animation\" settin" +
+ "g");
+ this.animationOverrideCheckBox.UseSelectable = true;
//
// crouchCheckBox
//
@@ -498,7 +499,7 @@
this.noArmorCheckBox.TabIndex = 10;
this.noArmorCheckBox.Text = "Disable All Armor";
this.noArmorCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
- this.toolTip.SetToolTip(this.noArmorCheckBox, " Disables all armor desptie the armor flags. ");
+ this.toolTip.SetToolTip(this.noArmorCheckBox, " Disables all armor. Overrides the individual armor flags.");
this.noArmorCheckBox.UseSelectable = true;
//
// bobbingCheckBox
@@ -507,11 +508,12 @@
this.bobbingCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Medium;
this.bobbingCheckBox.Location = new System.Drawing.Point(272, 50);
this.bobbingCheckBox.Name = "bobbingCheckBox";
- this.bobbingCheckBox.Size = new System.Drawing.Size(124, 19);
+ this.bobbingCheckBox.Size = new System.Drawing.Size(98, 19);
this.bobbingCheckBox.TabIndex = 9;
- this.bobbingCheckBox.Text = "Disable Bobbing";
+ this.bobbingCheckBox.Text = "No Bobbing";
this.bobbingCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
- this.toolTip.SetToolTip(this.bobbingCheckBox, " Disables the bobbing effect in first person.");
+ this.toolTip.SetToolTip(this.bobbingCheckBox, " Disables the bobbing effect in first person. Overrides the \"View Bobbing\" settin" +
+ "g.");
this.bobbingCheckBox.UseSelectable = true;
//
// santaCheckBox
@@ -520,12 +522,11 @@
this.santaCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Medium;
this.santaCheckBox.Location = new System.Drawing.Point(420, 50);
this.santaCheckBox.Name = "santaCheckBox";
- this.santaCheckBox.Size = new System.Drawing.Size(86, 19);
+ this.santaCheckBox.Size = new System.Drawing.Size(133, 19);
this.santaCheckBox.TabIndex = 8;
- this.santaCheckBox.Text = "Bad Santa";
+ this.santaCheckBox.Text = "Sit Idle Animation";
this.santaCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
- this.toolTip.SetToolTip(this.santaCheckBox, " The skin sits down after about 10 seconds of no controller input. Made for" +
- " Bad Santa in the \"Festive\" skin pack. ");
+ this.toolTip.SetToolTip(this.santaCheckBox, " The skin sits down after about 10 seconds of no controller input.");
this.santaCheckBox.UseSelectable = true;
//
// syncLegsCheckBox
@@ -779,7 +780,7 @@
private MetroFramework.Controls.MetroCheckBox noArmorCheckBox;
private MetroFramework.Controls.MetroCheckBox dinnerboneCheckBox;
private MetroFramework.Controls.MetroCheckBox crouchCheckBox;
- private MetroFramework.Controls.MetroCheckBox unknownCheckBox;
+ private MetroFramework.Controls.MetroCheckBox animationOverrideCheckBox;
private MetroFramework.Controls.MetroButton copyButton;
private MetroFramework.Controls.MetroButton importButton;
private MetroFramework.Controls.MetroButton exportButton;
diff --git a/PCK-Studio/Forms/Editor/ANIMEditor.cs b/PCK-Studio/Forms/Editor/ANIMEditor.cs
index c379d7d2..43bd1a89 100644
--- a/PCK-Studio/Forms/Editor/ANIMEditor.cs
+++ b/PCK-Studio/Forms/Editor/ANIMEditor.cs
@@ -8,6 +8,7 @@ using System.Collections.Generic;
using PckStudio.Internal;
using PckStudio.Forms.Additional_Popups;
using PckStudio.Properties;
+using PckStudio.Core.Skin;
namespace PckStudio.Forms.Editor
{
@@ -74,15 +75,15 @@ namespace PckStudio.Forms.Editor
checkbox.Checked = state;
switch(checkBoxLinkage[checkbox])
{
- case SkinAnimFlag.FORCE_HEAD_ARMOR:
- case SkinAnimFlag.FORCE_BODY_ARMOR:
- case SkinAnimFlag.FORCE_LEFT_ARM_ARMOR:
- case SkinAnimFlag.FORCE_RIGHT_ARM_ARMOR:
- case SkinAnimFlag.FORCE_LEFT_LEG_ARMOR:
- case SkinAnimFlag.FORCE_RIGHT_LEG_ARMOR:
+ case SkinAnimFlag.SHOW_HEAD_ARMOR:
+ case SkinAnimFlag.SHOW_CHESTPLATE_CENTER:
+ case SkinAnimFlag.SHOW_CHESTPLATE_LEFT:
+ case SkinAnimFlag.SHOW_CHESTPLATE_RIGHT:
+ case SkinAnimFlag.SHOW_LEFT_LEG_ARMOR:
+ case SkinAnimFlag.SHOW_RIGHT_LEG_ARMOR:
checkbox.Enabled = state;
break;
- case SkinAnimFlag.RESOLUTION_64x64:
+ case SkinAnimFlag.MODERN_WIDE_MODEL:
checkbox.Enabled = !state;
// Prioritize slim model > classic model, LCE would
if(state)
@@ -104,7 +105,7 @@ namespace PckStudio.Forms.Editor
* not the best way to do this but whatever lol
* fix for both model flags being unset when both are set to true, with slim model prioritized of course
*/
- if (item.Value == SkinAnimFlag.RESOLUTION_64x64 && anim.GetFlag(SkinAnimFlag.SLIM_MODEL))
+ if (item.Value == SkinAnimFlag.MODERN_WIDE_MODEL && anim.GetFlag(SkinAnimFlag.SLIM_MODEL))
continue;
item.Key.Checked = anim.GetFlag(item.Value);
@@ -118,38 +119,38 @@ namespace PckStudio.Forms.Editor
switch (checkBoxLinkage[checkBox])
{
case SkinAnimFlag.HEAD_DISABLED:
- checkBoxLinkage[SkinAnimFlag.FORCE_HEAD_ARMOR].Enabled = checkBox.Checked;
- Uncheck(checkBoxLinkage[SkinAnimFlag.FORCE_HEAD_ARMOR]);
+ checkBoxLinkage[SkinAnimFlag.SHOW_HEAD_ARMOR].Enabled = checkBox.Checked;
+ Uncheck(checkBoxLinkage[SkinAnimFlag.SHOW_HEAD_ARMOR]);
break;
- case SkinAnimFlag.BODY_DISABLED:
- checkBoxLinkage[SkinAnimFlag.FORCE_BODY_ARMOR].Enabled = checkBox.Checked;
- Uncheck(checkBoxLinkage[SkinAnimFlag.FORCE_BODY_ARMOR]);
+ case SkinAnimFlag.TORSO_DISABLED:
+ checkBoxLinkage[SkinAnimFlag.SHOW_CHESTPLATE_CENTER].Enabled = checkBox.Checked;
+ Uncheck(checkBoxLinkage[SkinAnimFlag.SHOW_CHESTPLATE_CENTER]);
break;
case SkinAnimFlag.LEFT_LEG_DISABLED:
- checkBoxLinkage[SkinAnimFlag.FORCE_LEFT_LEG_ARMOR].Enabled = checkBox.Checked;
- Uncheck(checkBoxLinkage[SkinAnimFlag.FORCE_LEFT_LEG_ARMOR]);
+ checkBoxLinkage[SkinAnimFlag.SHOW_LEFT_LEG_ARMOR].Enabled = checkBox.Checked;
+ Uncheck(checkBoxLinkage[SkinAnimFlag.SHOW_LEFT_LEG_ARMOR]);
break;
case SkinAnimFlag.RIGHT_LEG_DISABLED:
- checkBoxLinkage[SkinAnimFlag.FORCE_RIGHT_LEG_ARMOR].Enabled = checkBox.Checked;
- Uncheck(checkBoxLinkage[SkinAnimFlag.FORCE_RIGHT_LEG_ARMOR]);
+ checkBoxLinkage[SkinAnimFlag.SHOW_RIGHT_LEG_ARMOR].Enabled = checkBox.Checked;
+ Uncheck(checkBoxLinkage[SkinAnimFlag.SHOW_RIGHT_LEG_ARMOR]);
break;
case SkinAnimFlag.LEFT_ARM_DISABLED:
- checkBoxLinkage[SkinAnimFlag.FORCE_LEFT_ARM_ARMOR].Enabled = checkBox.Checked;
- Uncheck(checkBoxLinkage[SkinAnimFlag.FORCE_LEFT_ARM_ARMOR]);
+ checkBoxLinkage[SkinAnimFlag.SHOW_CHESTPLATE_LEFT].Enabled = checkBox.Checked;
+ Uncheck(checkBoxLinkage[SkinAnimFlag.SHOW_CHESTPLATE_LEFT]);
break;
case SkinAnimFlag.RIGHT_ARM_DISABLED:
- checkBoxLinkage[SkinAnimFlag.FORCE_RIGHT_ARM_ARMOR].Enabled = checkBox.Checked;
- Uncheck(checkBoxLinkage[SkinAnimFlag.FORCE_RIGHT_ARM_ARMOR]);
+ checkBoxLinkage[SkinAnimFlag.SHOW_CHESTPLATE_LEFT].Enabled = checkBox.Checked;
+ Uncheck(checkBoxLinkage[SkinAnimFlag.SHOW_CHESTPLATE_LEFT]);
break;
- case SkinAnimFlag.RESOLUTION_64x64:
+ case SkinAnimFlag.MODERN_WIDE_MODEL:
Uncheck(checkBoxLinkage[SkinAnimFlag.SLIM_MODEL]);
checkBoxLinkage[SkinAnimFlag.SLIM_MODEL].Enabled = !checkBox.Checked;
break;
case SkinAnimFlag.SLIM_MODEL:
- Uncheck(checkBoxLinkage[SkinAnimFlag.RESOLUTION_64x64]);
- checkBoxLinkage[SkinAnimFlag.RESOLUTION_64x64].Enabled = !checkBox.Checked;
+ Uncheck(checkBoxLinkage[SkinAnimFlag.MODERN_WIDE_MODEL]);
+ checkBoxLinkage[SkinAnimFlag.MODERN_WIDE_MODEL].Enabled = !checkBox.Checked;
break;
default:
break;
@@ -189,37 +190,37 @@ namespace PckStudio.Forms.Editor
private void InitializeRuleSet()
{
ruleset = new ANIMRuleSet(
- (bobbingCheckBox, SkinAnimFlag.HEAD_BOBBING_DISABLED),
- (bodyCheckBox, SkinAnimFlag.BODY_DISABLED),
- (bodyOCheckBox, SkinAnimFlag.BODY_OVERLAY_DISABLED),
- (chestplateCheckBox, SkinAnimFlag.FORCE_BODY_ARMOR),
- (classicCheckBox, SkinAnimFlag.RESOLUTION_64x64),
+ (bobbingCheckBox, SkinAnimFlag.NO_BOBBING_OVERRIDE),
+ (bodyCheckBox, SkinAnimFlag.TORSO_DISABLED),
+ (bodyOCheckBox, SkinAnimFlag.JACKET_DISABLED),
+ (chestplateCheckBox, SkinAnimFlag.SHOW_CHESTPLATE_CENTER),
+ (classicCheckBox, SkinAnimFlag.MODERN_WIDE_MODEL),
(crouchCheckBox, SkinAnimFlag.DO_BACKWARDS_CROUCH),
(dinnerboneCheckBox, SkinAnimFlag.DINNERBONE),
(headCheckBox, SkinAnimFlag.HEAD_DISABLED),
- (headOCheckBox, SkinAnimFlag.HEAD_OVERLAY_DISABLED),
- (helmetCheckBox, SkinAnimFlag.FORCE_HEAD_ARMOR),
+ (headOCheckBox, SkinAnimFlag.HEADWEAR_DISABLED),
+ (helmetCheckBox, SkinAnimFlag.SHOW_HEAD_ARMOR),
(leftArmCheckBox, SkinAnimFlag.LEFT_ARM_DISABLED),
- (leftArmOCheckBox, SkinAnimFlag.LEFT_ARM_OVERLAY_DISABLED),
- (leftArmorCheckBox, SkinAnimFlag.FORCE_LEFT_ARM_ARMOR),
+ (leftArmOCheckBox, SkinAnimFlag.LEFT_SLEEVE_DISABLED),
+ (leftArmorCheckBox, SkinAnimFlag.SHOW_CHESTPLATE_LEFT),
(leftLegCheckBox, SkinAnimFlag.LEFT_LEG_DISABLED),
- (leftLeggingCheckBox, SkinAnimFlag.FORCE_LEFT_LEG_ARMOR),
- (leftLegOCheckBox, SkinAnimFlag.LEFT_LEG_OVERLAY_DISABLED),
+ (leftLeggingCheckBox, SkinAnimFlag.SHOW_LEFT_LEG_ARMOR),
+ (leftLegOCheckBox, SkinAnimFlag.LEFT_PANTS_DISABLED),
(noArmorCheckBox, SkinAnimFlag.ALL_ARMOR_DISABLED),
(rightArmCheckBox, SkinAnimFlag.RIGHT_ARM_DISABLED),
- (rightArmOCheckBox, SkinAnimFlag.RIGHT_ARM_OVERLAY_DISABLED),
- (rightArmorCheckBox, SkinAnimFlag.FORCE_RIGHT_ARM_ARMOR),
+ (rightArmOCheckBox, SkinAnimFlag.RIGHT_SLEEVE_DISABLED),
+ (rightArmorCheckBox, SkinAnimFlag.SHOW_CHESTPLATE_LEFT),
(rightLegCheckBox, SkinAnimFlag.RIGHT_LEG_DISABLED),
- (rightLeggingCheckBox, SkinAnimFlag.FORCE_RIGHT_LEG_ARMOR),
- (rightLegOCheckBox, SkinAnimFlag.RIGHT_LEG_OVERLAY_DISABLED),
- (santaCheckBox, SkinAnimFlag.BAD_SANTA),
+ (rightLeggingCheckBox, SkinAnimFlag.SHOW_RIGHT_LEG_ARMOR),
+ (rightLegOCheckBox, SkinAnimFlag.RIGHT_PANTS_DISABLED),
+ (santaCheckBox, SkinAnimFlag.SIT_IDLE_ANIMATION),
(slimCheckBox, SkinAnimFlag.SLIM_MODEL),
(staticArmsCheckBox, SkinAnimFlag.STATIC_ARMS),
(staticLegsCheckBox, SkinAnimFlag.STATIC_LEGS),
(statueCheckBox, SkinAnimFlag.STATUE_OF_LIBERTY),
(syncArmsCheckBox, SkinAnimFlag.SYNCED_ARMS),
(syncLegsCheckBox, SkinAnimFlag.SYNCED_LEGS),
- (unknownCheckBox, SkinAnimFlag.__BIT_4),
+ (animationOverrideCheckBox, SkinAnimFlag.CUSTOM_ANIMATION_OVERRIDE),
(zombieCheckBox, SkinAnimFlag.ZOMBIE_ARMS)
);
ruleset.OnCheckboxChanged = setDisplayAnim;
@@ -280,7 +281,7 @@ namespace PckStudio.Forms.Editor
if (saveFileDialog.ShowDialog(this) != DialogResult.OK)
return;
bool isSlim = ruleset.Value.GetFlag(SkinAnimFlag.SLIM_MODEL);
- bool is64x64 = ruleset.Value.GetFlag(SkinAnimFlag.RESOLUTION_64x64);
+ bool is64x64 = ruleset.Value.GetFlag(SkinAnimFlag.MODERN_WIDE_MODEL);
bool isClassic32 = !isSlim && !is64x64;
Image skin = isSlim ? Properties.Resources.slim_template : Properties.Resources.classic_template;
@@ -291,11 +292,11 @@ namespace PckStudio.Forms.Editor
using (Graphics graphic = Graphics.FromImage(img))
{
graphic.DrawImage(skin, new Rectangle(Point.Empty, imgSize), new Rectangle(Point.Empty, imgSize), GraphicsUnit.Pixel);
- if (ruleset.Value.GetFlag(SkinAnimFlag.HEAD_OVERLAY_DISABLED))
+ if (ruleset.Value.GetFlag(SkinAnimFlag.HEADWEAR_DISABLED))
graphic.FillRectangle(Brushes.Magenta, new Rectangle(32, 0, 32, 16));
if (ruleset.Value.GetFlag(SkinAnimFlag.HEAD_DISABLED))
graphic.FillRectangle(Brushes.Magenta, new Rectangle(0, 0, 32, 16));
- if (ruleset.Value.GetFlag(SkinAnimFlag.BODY_DISABLED))
+ if (ruleset.Value.GetFlag(SkinAnimFlag.TORSO_DISABLED))
graphic.FillRectangle(Brushes.Magenta, new Rectangle(16, 16, 24, 16));
if (img.Height == 64)
{
@@ -303,19 +304,19 @@ namespace PckStudio.Forms.Editor
graphic.FillRectangle(Brushes.Magenta, new Rectangle(40, 16, 16, 16));
if (ruleset.Value.GetFlag(SkinAnimFlag.RIGHT_LEG_DISABLED))
graphic.FillRectangle(Brushes.Magenta, new Rectangle(0, 16, 16, 16));
- if (ruleset.Value.GetFlag(SkinAnimFlag.BODY_OVERLAY_DISABLED))
+ if (ruleset.Value.GetFlag(SkinAnimFlag.JACKET_DISABLED))
graphic.FillRectangle(Brushes.Magenta, new Rectangle(16, 32, 24, 16));
- if (ruleset.Value.GetFlag(SkinAnimFlag.RIGHT_ARM_OVERLAY_DISABLED))
+ if (ruleset.Value.GetFlag(SkinAnimFlag.RIGHT_SLEEVE_DISABLED))
graphic.FillRectangle(Brushes.Magenta, new Rectangle(40, 32, 16, 16));
- if (ruleset.Value.GetFlag(SkinAnimFlag.RIGHT_LEG_OVERLAY_DISABLED))
+ if (ruleset.Value.GetFlag(SkinAnimFlag.RIGHT_PANTS_DISABLED))
graphic.FillRectangle(Brushes.Magenta, new Rectangle(0, 32, 16, 16));
- if (ruleset.Value.GetFlag(SkinAnimFlag.LEFT_LEG_OVERLAY_DISABLED))
+ if (ruleset.Value.GetFlag(SkinAnimFlag.LEFT_PANTS_DISABLED))
graphic.FillRectangle(Brushes.Magenta, new Rectangle(0, 48, 16, 16));
if (ruleset.Value.GetFlag(SkinAnimFlag.LEFT_LEG_DISABLED))
graphic.FillRectangle(Brushes.Magenta, new Rectangle(16, 48, 16, 16));
if (ruleset.Value.GetFlag(SkinAnimFlag.LEFT_ARM_DISABLED))
graphic.FillRectangle(Brushes.Magenta, new Rectangle(32, 48, 16, 16));
- if (ruleset.Value.GetFlag(SkinAnimFlag.LEFT_ARM_OVERLAY_DISABLED))
+ if (ruleset.Value.GetFlag(SkinAnimFlag.LEFT_SLEEVE_DISABLED))
graphic.FillRectangle(Brushes.Magenta, new Rectangle(48, 48, 16, 16));
}
else
@@ -342,7 +343,7 @@ namespace PckStudio.Forms.Editor
static readonly Dictionary Templates = new Dictionary()
{
{ "Steve (64x32)", SkinAnimMask.NONE },
- { "Steve (64x64)", SkinAnimMask.RESOLUTION_64x64 },
+ { "Steve (64x64)", SkinAnimMask.MODERN_WIDE_MODEL },
{ "Alex (64x64)", SkinAnimMask.SLIM_MODEL },
{ "Zombie Skins", SkinAnimMask.ZOMBIE_ARMS },
{ "Cetacean Skins", SkinAnimMask.SYNCED_ARMS | SkinAnimMask.SYNCED_LEGS },
diff --git a/PCK-Studio/Forms/Editor/AnimationEditor.Designer.cs b/PCK-Studio/Forms/Editor/AnimationEditor.Designer.cs
index 4fed8d2a..7a891d6a 100644
--- a/PCK-Studio/Forms/Editor/AnimationEditor.Designer.cs
+++ b/PCK-Studio/Forms/Editor/AnimationEditor.Designer.cs
@@ -319,7 +319,7 @@
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.animationPictureBox.BlendColor = System.Drawing.Color.White;
- this.animationPictureBox.BlendMode = PckStudio.Extensions.BlendMode.Multiply;
+ this.animationPictureBox.BlendMode = PckStudio.Core.Extensions.BlendMode.Multiply;
this.animationPictureBox.Image = null;
this.animationPictureBox.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
this.animationPictureBox.Location = new System.Drawing.Point(157, 88);
diff --git a/PCK-Studio/Forms/Editor/AnimationEditor.cs b/PCK-Studio/Forms/Editor/AnimationEditor.cs
index e5ba5639..c6c866c4 100644
--- a/PCK-Studio/Forms/Editor/AnimationEditor.cs
+++ b/PCK-Studio/Forms/Editor/AnimationEditor.cs
@@ -1,4 +1,4 @@
-/* Copyright (c) 2023-present miku-666, MattNL
+/* Copyright (c) 2023-present miku-666, MayNL
* 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.
@@ -29,39 +29,32 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PckStudio.Forms.Additional_Popups.Animation;
-using PckStudio.Extensions;
-using PckStudio.Properties;
-using PckStudio.Internal;
-using PckStudio.Internal.Deserializer;
-using PckStudio.Internal.Serializer;
+using PckStudio.Core.Extensions;
+using PckStudio.Core.Deserializer;
+using PckStudio.Core.Serializer;
+using PckStudio.Core;
+using PckStudio.Interfaces;
+using PckStudio.Controls;
namespace PckStudio.Forms.Editor
{
- public partial class AnimationEditor : MetroForm
+ public partial class AnimationEditor : EditorForm
{
- public Animation Result => _animation;
+ private bool _editable;
- private Animation _animation;
- private bool _isSpecialTile;
-
- private AnimationEditor()
+ internal AnimationEditor(Animation animation, ISaveContext saveContext, string displayName, bool editable = true)
+ : base(animation, saveContext)
{
InitializeComponent();
- toolStripSeparator1.Visible = saveToolStripMenuItem1.Visible = !Settings.Default.AutoSaveChanges;
- }
-
- internal AnimationEditor(Animation animation, string displayName, bool isSpecialTile = false)
- : this()
- {
- _ = animation ?? throw new ArgumentNullException(nameof(animation));
- _animation = animation;
+ saveToolStripMenuItem1.Available = !saveContext.AutoSave;
+ toolStripSeparator1.Available = !saveContext.AutoSave;
tileLabel.Text = displayName;
- _isSpecialTile = isSpecialTile;
+ _editable = editable;
animationPictureBox.Image = animation.CreateAnimationImage();
}
- internal AnimationEditor(Animation animation, string displayName, Color blendColor)
- : this(animation, displayName)
+ internal AnimationEditor(Animation animation, ISaveContext saveContext, string displayName, Color blendColor)
+ : this(animation, saveContext, displayName)
{
animationPictureBox.UseBlendColor = true;
animationPictureBox.BlendColor = blendColor;
@@ -69,10 +62,9 @@ namespace PckStudio.Forms.Editor
private void ValidateToolStrip()
{
- bulkAnimationSpeedToolStripMenuItem.Enabled =
- importToolStripMenuItem.Enabled =
- exportAsToolStripMenuItem.Enabled =
- InterpolationCheckbox.Visible = !_isSpecialTile;
+ editToolStripMenuItem.Visible =
+ importToolStripMenuItem.Visible =
+ InterpolationCheckbox.Visible = _editable;
}
private void AnimationEditor_Load(object sender, EventArgs e)
@@ -83,20 +75,20 @@ namespace PckStudio.Forms.Editor
private void LoadAnimationTreeView()
{
- if (_animation is null)
+ if (EditorValue is null)
{
- AnimationStartStopBtn.Enabled = false;
+ AnimationStartStopBtn.Visible = false;
return;
}
- AnimationStartStopBtn.Enabled = true;
- InterpolationCheckbox.Checked = _animation.Interpolate;
+ AnimationStartStopBtn.Visible = true;
+ InterpolationCheckbox.Checked = EditorValue.Interpolate;
TextureIcons.Images.Clear();
- TextureIcons.Images.AddRange(_animation.GetTextures().ToArray());
+ TextureIcons.Images.AddRange(EditorValue.GetTextures().ToArray());
UpdateTreeView();
- animationPictureBox.Image ??= _animation.CreateAnimationImage();
+ animationPictureBox.Image ??= EditorValue.CreateAnimationImage();
- if (_animation.FrameCount > 0)
+ if (EditorValue.FrameCount > 0)
{
animationPictureBox.Image.SelectActiveFrame(FrameDimension.Page, 0);
}
@@ -106,11 +98,11 @@ namespace PckStudio.Forms.Editor
{
frameTreeView.Nodes.Clear();
frameTreeView.Nodes.AddRange(
- _animation.GetFrames()
+ EditorValue.GetFrames()
.Select(frame =>
{
- var imageIndex = _animation.GetTextureIndex(frame.Texture);
- return new TreeNode($"for {frame.Ticks} ticks", imageIndex, imageIndex);
+ var imageIndex = EditorValue.GetTextureIndex(frame.Texture);
+ return new TreeNode($"for {frame.Ticks} tick(s)", imageIndex, imageIndex);
})
.ToArray()
);
@@ -122,7 +114,7 @@ namespace PckStudio.Forms.Editor
{
StopAnimation();
}
- animationPictureBox.Image = _animation.GetFrame(frameTreeView.SelectedNode.Index).Texture;
+ animationPictureBox.Image = EditorValue.GetFrame(frameTreeView.SelectedNode.Index).Texture;
}
private void StopAnimation()
@@ -139,9 +131,9 @@ namespace PckStudio.Forms.Editor
return;
}
- if (_animation.FrameCount > 1)
+ if (EditorValue.FrameCount > 1)
{
- animationPictureBox.Image = _animation.CreateAnimationImage();
+ animationPictureBox.Image = EditorValue.CreateAnimationImage();
animationPictureBox.Start();
AnimationStartStopBtn.Text = "Stop Animation";
}
@@ -166,8 +158,9 @@ namespace PckStudio.Forms.Editor
private void saveToolStripMenuItem1_Click(object sender, EventArgs e)
{
- if (!_isSpecialTile && _animation is not null && _animation.FrameCount > 0)
+ if (_editable && EditorValue is not null && EditorValue.FrameCount > 0)
{
+ Save();
DialogResult = DialogResult.OK;
return;
}
@@ -175,7 +168,7 @@ namespace PckStudio.Forms.Editor
}
// 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
+ // - MayNL
private void frameTreeView_ItemDrag(object sender, ItemDragEventArgs e)
{
@@ -231,7 +224,7 @@ namespace PckStudio.Forms.Editor
{
int draggedIndex = draggedNode.Index;
int targetIndex = targetNode.Index;
- _animation.SwapFrames(draggedIndex, targetIndex);
+ EditorValue.SwapFrames(draggedIndex, targetIndex);
UpdateTreeView();
}
}
@@ -255,18 +248,18 @@ namespace PckStudio.Forms.Editor
private void treeView1_doubleClick(object sender, EventArgs e)
{
- Animation.Frame frame = _animation.GetFrame(frameTreeView.SelectedNode.Index);
- using FrameEditor diag = new FrameEditor(frame.Ticks, _animation.GetTextureIndex(frame.Texture), TextureIcons);
+ Animation.Frame frame = EditorValue.GetFrame(frameTreeView.SelectedNode.Index);
+ using FrameEditor diag = new FrameEditor(frame.Ticks, EditorValue.GetTextureIndex(frame.Texture), TextureIcons);
if (diag.ShowDialog(this) == DialogResult.OK)
{
/* Found a bug here. When passing the frame variable,
* it would replace the first instance of that frame and time
* rather than the actual frame that was clicked.
* I've just switched to passing the index to fix this for now.
- * - Matt
+ * - MayNL
*/
- _animation.SetFrame(frameTreeView.SelectedNode.Index, diag.FrameTextureIndex, diag.FrameTime);
+ EditorValue.SetFrame(frameTreeView.SelectedNode.Index, diag.FrameTextureIndex, diag.FrameTime);
UpdateTreeView();
}
}
@@ -277,14 +270,14 @@ namespace PckStudio.Forms.Editor
diag.SaveBtn.Text = "Add";
if (diag.ShowDialog(this) == DialogResult.OK)
{
- _animation.AddFrame(diag.FrameTextureIndex, _isSpecialTile ? Animation.MinimumFrameTime : diag.FrameTime);
+ EditorValue.AddFrame(diag.FrameTextureIndex, _editable ? diag.FrameTime : Animation.MinimumFrameTime);
UpdateTreeView();
}
}
private void removeFrameToolStripMenuItem_Click(object sender, EventArgs e)
{
- if (frameTreeView.SelectedNode is TreeNode t && _animation.RemoveFrame(t.Index))
+ if (frameTreeView.SelectedNode is TreeNode t && EditorValue.RemoveFrame(t.Index))
{
frameTreeView.SelectedNode.Remove();
}
@@ -297,7 +290,7 @@ namespace PckStudio.Forms.Editor
{
if (animationPictureBox.IsPlaying)
animationPictureBox.Stop();
- _animation.SetFrameTicks(diag.Ticks);
+ EditorValue.SetFrameTicks(diag.Ticks);
UpdateTreeView();
}
diag.Dispose();
@@ -319,7 +312,7 @@ namespace PckStudio.Forms.Editor
Title = "Please select a valid Minecaft: Java Edition animation script",
// It's marked as .png.mcmeta just in case
// some weirdo tries to pass a pack.mcmeta or something
- // -MattNL
+ // -MayNL
Filter = "Animation Scripts (*.mcmeta)|*.png.mcmeta"
};
if (fileDialog.ShowDialog(this) != DialogResult.OK)
@@ -334,10 +327,10 @@ namespace PckStudio.Forms.Editor
}
try
{
- var img = Image.FromFile(textureFile);
+ Image img = Image.FromFile(textureFile).ReleaseFromFile();
JObject mcmeta = JObject.Parse(File.ReadAllText(fileDialog.FileName));
Animation javaAnimation = AnimationDeserializer.DefaultDeserializer.DeserializeJavaAnimation(mcmeta, img);
- _animation = javaAnimation;
+ EditorValue = javaAnimation;
LoadAnimationTreeView();
}
catch (JsonException j_ex)
@@ -354,11 +347,11 @@ namespace PckStudio.Forms.Editor
fileDialog.Filter = "Animation Scripts (*.mcmeta)|*.png.mcmeta";
if (fileDialog.ShowDialog(this) == DialogResult.OK)
{
- JObject mcmeta = AnimationSerializer.SerializeJavaAnimation(_animation);
+ JObject mcmeta = AnimationSerializer.SerializeJavaAnimation(EditorValue);
string jsondata = JsonConvert.SerializeObject(mcmeta, Formatting.Indented);
string filename = fileDialog.FileName;
File.WriteAllText(filename, jsondata);
- Image finalTexture = AnimationSerializer.SerializeTexture(_animation);
+ Image finalTexture = AnimationSerializer.SerializeTexture(EditorValue);
// removes ".mcmeta" from filename
string texturePath = Path.Combine(Path.GetDirectoryName(filename), Path.GetFileNameWithoutExtension(filename));
finalTexture.Save(texturePath);
@@ -390,8 +383,8 @@ namespace PckStudio.Forms.Editor
private void InterpolationCheckbox_CheckedChanged(object sender, EventArgs e)
{
- if (_animation is not null)
- _animation.Interpolate = InterpolationCheckbox.Checked;
+ if (EditorValue is not null)
+ EditorValue.Interpolate = InterpolationCheckbox.Checked;
}
private void AnimationEditor_FormClosing(object sender, FormClosingEventArgs e)
@@ -400,7 +393,7 @@ namespace PckStudio.Forms.Editor
{
animationPictureBox.Stop();
}
- if (Settings.Default.AutoSaveChanges)
+ if (!saveToolStripMenuItem1.Available)
{
saveToolStripMenuItem1_Click(sender, EventArgs.Empty);
}
@@ -415,14 +408,14 @@ namespace PckStudio.Forms.Editor
if (fileDialog.ShowDialog(this) != DialogResult.OK)
return;
- var gif = Image.FromFile(fileDialog.FileName);
+ Image gif = Image.FromFile(fileDialog.FileName).ReleaseFromFile();
if (!gif.RawFormat.Equals(ImageFormat.Gif))
{
MessageBox.Show(this, "Selected file is not a gif", "Invalid file", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
- var oldResolution = _animation.GetFrame(0).Texture.Width;
+ var oldResolution = EditorValue.GetFrame(0).Texture.Width;
FrameDimension dimension = new FrameDimension(gif.FrameDimensionsList[0]);
int frameCount = gif.GetFrameCount(dimension);
@@ -436,8 +429,8 @@ namespace PckStudio.Forms.Editor
textures.Add(new Bitmap(gif, oldResolution, oldResolution));
}
- _animation = new Animation(textures, initFramesFromTextures: true);
- _animation.Interpolate = InterpolationCheckbox.Checked;
+ EditorValue = new Animation(textures, initFramesFromTextures: true);
+ EditorValue.Interpolate = InterpolationCheckbox.Checked;
LoadAnimationTreeView();
}
@@ -452,7 +445,7 @@ namespace PckStudio.Forms.Editor
return;
using Image img = Image.FromFile(ofd.FileName);
IEnumerable textures = img.Split(ImageLayoutDirection.Vertical);
- _animation = new Animation(textures, initFramesFromTextures: true);
+ EditorValue = new Animation(textures, initFramesFromTextures: true);
LoadAnimationTreeView();
}
@@ -465,7 +458,7 @@ namespace PckStudio.Forms.Editor
};
if (fileDialog.ShowDialog(this) != DialogResult.OK)
return;
- _animation.CreateAnimationImage().Save(fileDialog.FileName);
+ EditorValue.CreateAnimationImage().Save(fileDialog.FileName);
}
private void frameTimeandTicksToolStripMenuItem_Click(object sender, EventArgs e)
diff --git a/PCK-Studio/Forms/Editor/AudioEditor.Designer.cs b/PCK-Studio/Forms/Editor/AudioEditor.Designer.cs
index 3bf531e6..9936e814 100644
--- a/PCK-Studio/Forms/Editor/AudioEditor.Designer.cs
+++ b/PCK-Studio/Forms/Editor/AudioEditor.Designer.cs
@@ -40,26 +40,14 @@ namespace PckStudio.Forms.Editor
this.menuStrip = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.saveToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
- this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.deleteUnusedBINKAsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.openDataFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.bulkReplaceExistingTracksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.organizeTracksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.howToAddSongsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.whatAreTheCategoriesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.howToEditCreditsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.optimizeDataFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.bINKACompressionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.treeView2 = new System.Windows.Forms.TreeView();
this.contextMenuStrip2 = new System.Windows.Forms.ContextMenuStrip(this.components);
this.addEntryMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.removeEntryMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.verifyFileLocationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.convertToWAVToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.playOverworldInCreative = new MetroFramework.Controls.MetroCheckBox();
this.compressionUpDown = new System.Windows.Forms.NumericUpDown();
this.metroLabel1 = new MetroFramework.Controls.MetroLabel();
+ this.editEntryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.contextMenuStrip1.SuspendLayout();
this.menuStrip.SuspendLayout();
this.contextMenuStrip2.SuspendLayout();
@@ -124,9 +112,7 @@ namespace PckStudio.Forms.Editor
resources.ApplyResources(this.menuStrip, "menuStrip");
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.helpToolStripMenuItem});
+ this.fileToolStripMenuItem});
this.menuStrip.Name = "menuStrip";
//
// fileToolStripMenuItem
@@ -143,83 +129,6 @@ namespace PckStudio.Forms.Editor
this.saveToolStripMenuItem1.Name = "saveToolStripMenuItem1";
this.saveToolStripMenuItem1.Click += new System.EventHandler(this.saveToolStripMenuItem1_Click);
//
- // toolsToolStripMenuItem
- //
- this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
- this.deleteUnusedBINKAsToolStripMenuItem,
- this.openDataFolderToolStripMenuItem,
- this.bulkReplaceExistingTracksToolStripMenuItem,
- this.organizeTracksToolStripMenuItem});
- this.toolsToolStripMenuItem.ForeColor = System.Drawing.Color.White;
- this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem";
- resources.ApplyResources(this.toolsToolStripMenuItem, "toolsToolStripMenuItem");
- //
- // deleteUnusedBINKAsToolStripMenuItem
- //
- this.deleteUnusedBINKAsToolStripMenuItem.Name = "deleteUnusedBINKAsToolStripMenuItem";
- resources.ApplyResources(this.deleteUnusedBINKAsToolStripMenuItem, "deleteUnusedBINKAsToolStripMenuItem");
- this.deleteUnusedBINKAsToolStripMenuItem.Click += new System.EventHandler(this.deleteUnusedBINKAsToolStripMenuItem_Click);
- //
- // openDataFolderToolStripMenuItem
- //
- this.openDataFolderToolStripMenuItem.Name = "openDataFolderToolStripMenuItem";
- resources.ApplyResources(this.openDataFolderToolStripMenuItem, "openDataFolderToolStripMenuItem");
- this.openDataFolderToolStripMenuItem.Click += new System.EventHandler(this.openDataFolderToolStripMenuItem_Click);
- //
- // bulkReplaceExistingTracksToolStripMenuItem
- //
- this.bulkReplaceExistingTracksToolStripMenuItem.Name = "bulkReplaceExistingTracksToolStripMenuItem";
- resources.ApplyResources(this.bulkReplaceExistingTracksToolStripMenuItem, "bulkReplaceExistingTracksToolStripMenuItem");
- this.bulkReplaceExistingTracksToolStripMenuItem.Click += new System.EventHandler(this.bulkReplaceExistingFilesToolStripMenuItem_Click);
- //
- // organizeTracksToolStripMenuItem
- //
- this.organizeTracksToolStripMenuItem.Name = "organizeTracksToolStripMenuItem";
- resources.ApplyResources(this.organizeTracksToolStripMenuItem, "organizeTracksToolStripMenuItem");
- this.organizeTracksToolStripMenuItem.Click += new System.EventHandler(this.organizeTracksToolStripMenuItem_Click);
- //
- // helpToolStripMenuItem
- //
- this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
- this.howToAddSongsToolStripMenuItem,
- this.whatAreTheCategoriesToolStripMenuItem,
- this.howToEditCreditsToolStripMenuItem,
- this.optimizeDataFolderToolStripMenuItem,
- this.bINKACompressionToolStripMenuItem});
- this.helpToolStripMenuItem.ForeColor = System.Drawing.Color.White;
- this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
- resources.ApplyResources(this.helpToolStripMenuItem, "helpToolStripMenuItem");
- //
- // howToAddSongsToolStripMenuItem
- //
- this.howToAddSongsToolStripMenuItem.Name = "howToAddSongsToolStripMenuItem";
- resources.ApplyResources(this.howToAddSongsToolStripMenuItem, "howToAddSongsToolStripMenuItem");
- this.howToAddSongsToolStripMenuItem.Click += new System.EventHandler(this.howToAddSongsToolStripMenuItem_Click);
- //
- // whatAreTheCategoriesToolStripMenuItem
- //
- this.whatAreTheCategoriesToolStripMenuItem.Name = "whatAreTheCategoriesToolStripMenuItem";
- resources.ApplyResources(this.whatAreTheCategoriesToolStripMenuItem, "whatAreTheCategoriesToolStripMenuItem");
- this.whatAreTheCategoriesToolStripMenuItem.Click += new System.EventHandler(this.whatAreTheCategoriesToolStripMenuItem_Click);
- //
- // howToEditCreditsToolStripMenuItem
- //
- this.howToEditCreditsToolStripMenuItem.Name = "howToEditCreditsToolStripMenuItem";
- resources.ApplyResources(this.howToEditCreditsToolStripMenuItem, "howToEditCreditsToolStripMenuItem");
- this.howToEditCreditsToolStripMenuItem.Click += new System.EventHandler(this.howToEditCreditsToolStripMenuItem_Click);
- //
- // optimizeDataFolderToolStripMenuItem
- //
- this.optimizeDataFolderToolStripMenuItem.Name = "optimizeDataFolderToolStripMenuItem";
- resources.ApplyResources(this.optimizeDataFolderToolStripMenuItem, "optimizeDataFolderToolStripMenuItem");
- this.optimizeDataFolderToolStripMenuItem.Click += new System.EventHandler(this.optimizeDataFolderToolStripMenuItem_Click);
- //
- // bINKACompressionToolStripMenuItem
- //
- this.bINKACompressionToolStripMenuItem.Name = "bINKACompressionToolStripMenuItem";
- resources.ApplyResources(this.bINKACompressionToolStripMenuItem, "bINKACompressionToolStripMenuItem");
- this.bINKACompressionToolStripMenuItem.Click += new System.EventHandler(this.BINKACompressionToolStripMenuItem_Click);
- //
// treeView2
//
this.treeView2.AllowDrop = true;
@@ -236,9 +145,8 @@ namespace PckStudio.Forms.Editor
//
this.contextMenuStrip2.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.addEntryMenuItem,
- this.removeEntryMenuItem,
- this.verifyFileLocationToolStripMenuItem,
- this.convertToWAVToolStripMenuItem});
+ this.editEntryToolStripMenuItem,
+ this.removeEntryMenuItem});
this.contextMenuStrip2.Name = "contextMenuStrip1";
resources.ApplyResources(this.contextMenuStrip2, "contextMenuStrip2");
//
@@ -254,18 +162,6 @@ namespace PckStudio.Forms.Editor
resources.ApplyResources(this.removeEntryMenuItem, "removeEntryMenuItem");
this.removeEntryMenuItem.Click += new System.EventHandler(this.removeEntryMenuItem_Click);
//
- // verifyFileLocationToolStripMenuItem
- //
- this.verifyFileLocationToolStripMenuItem.Name = "verifyFileLocationToolStripMenuItem";
- resources.ApplyResources(this.verifyFileLocationToolStripMenuItem, "verifyFileLocationToolStripMenuItem");
- this.verifyFileLocationToolStripMenuItem.Click += new System.EventHandler(this.verifyFileLocationToolStripMenuItem_Click);
- //
- // convertToWAVToolStripMenuItem
- //
- this.convertToWAVToolStripMenuItem.Name = "convertToWAVToolStripMenuItem";
- resources.ApplyResources(this.convertToWAVToolStripMenuItem, "convertToWAVToolStripMenuItem");
- this.convertToWAVToolStripMenuItem.Click += new System.EventHandler(this.convertToWAVToolStripMenuItem_Click);
- //
// playOverworldInCreative
//
resources.ApplyResources(this.playOverworldInCreative, "playOverworldInCreative");
@@ -305,6 +201,12 @@ namespace PckStudio.Forms.Editor
this.metroLabel1.Name = "metroLabel1";
this.metroLabel1.Theme = MetroFramework.MetroThemeStyle.Dark;
//
+ // editEntryToolStripMenuItem
+ //
+ this.editEntryToolStripMenuItem.Name = "editEntryToolStripMenuItem";
+ resources.ApplyResources(this.editEntryToolStripMenuItem, "editEntryToolStripMenuItem");
+ this.editEntryToolStripMenuItem.Click += new System.EventHandler(this.editEntryToolStripMenuItem_Click);
+ //
// AudioEditor
//
resources.ApplyResources(this, "$this");
@@ -345,23 +247,11 @@ namespace PckStudio.Forms.Editor
private System.Windows.Forms.ContextMenuStrip contextMenuStrip2;
private System.Windows.Forms.ToolStripMenuItem addEntryMenuItem;
private System.Windows.Forms.ToolStripMenuItem removeEntryMenuItem;
- private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
private System.Windows.Forms.ImageList catImages;
- private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem;
- private System.Windows.Forms.ToolStripMenuItem verifyFileLocationToolStripMenuItem;
private MetroFramework.Controls.MetroCheckBox playOverworldInCreative;
- private System.Windows.Forms.ToolStripMenuItem deleteUnusedBINKAsToolStripMenuItem;
- private System.Windows.Forms.ToolStripMenuItem howToAddSongsToolStripMenuItem;
- private System.Windows.Forms.ToolStripMenuItem whatAreTheCategoriesToolStripMenuItem;
- private System.Windows.Forms.ToolStripMenuItem howToEditCreditsToolStripMenuItem;
- private System.Windows.Forms.ToolStripMenuItem optimizeDataFolderToolStripMenuItem;
private System.Windows.Forms.NumericUpDown compressionUpDown;
- private System.Windows.Forms.ToolStripMenuItem bINKACompressionToolStripMenuItem;
private MetroFramework.Controls.MetroLabel metroLabel1;
- private System.Windows.Forms.ToolStripMenuItem openDataFolderToolStripMenuItem;
- private System.Windows.Forms.ToolStripMenuItem bulkReplaceExistingTracksToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem changeCategoryToolStripMenuItem;
- private System.Windows.Forms.ToolStripMenuItem organizeTracksToolStripMenuItem;
- private System.Windows.Forms.ToolStripMenuItem convertToWAVToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem editEntryToolStripMenuItem;
}
}
\ No newline at end of file
diff --git a/PCK-Studio/Forms/Editor/AudioEditor.cs b/PCK-Studio/Forms/Editor/AudioEditor.cs
index cc37747c..91993c66 100644
--- a/PCK-Studio/Forms/Editor/AudioEditor.cs
+++ b/PCK-Studio/Forms/Editor/AudioEditor.cs
@@ -7,30 +7,23 @@ using System.Windows.Forms;
using System.Security.Cryptography;
using System.Text.RegularExpressions;
using System.Diagnostics;
-
-using MetroFramework.Forms;
using NAudio.Wave;
-
-using OMI.Formats.Pck;
-
-using PckStudio.FileFormats;
-using PckStudio.Internal.IO.PckAudio;
using PckStudio.Forms.Additional_Popups;
using PckStudio.Properties;
using PckStudio.External.API.Miles;
-using PckStudio.Extensions;
+using PckStudio.Core.Extensions;
using PckStudio.Internal.App;
+using PckStudio.Controls;
+using PckStudio.Interfaces;
+using PckStudio.Core.FileFormats;
-// Audio Editor by MattNL and Miku-666
+// Audio Editor by MayNL and Miku-666
namespace PckStudio.Forms.Editor
{
- public partial class AudioEditor : MetroForm
+ public partial class AudioEditor : EditorForm
{
public string defaultType = "yes";
- PckAudioFile _audioFile = null;
- PckAsset _audioAsset;
- bool _isLittleEndian = false;
MainForm parent = null;
private static readonly List Categories = new List
@@ -46,13 +39,20 @@ namespace PckStudio.Forms.Editor
"Build Off (Unused)"
/* If the SetMusicID function within the game is ever set to 0x9,
- * it actually attempts to play a "MG04_01.binka" file in the vanilla music folder.
- * Therefore it's safe to assume that the last audio category was indeed
- * supposed to be for the cancelled Build Off mini game (MG04). - May
+ * it actually plays a tracklist for MG04, with all of the Creative
+ * Tracks and the "MG04_01.binka" file in it. The 9th category is MG04 - May
*/
};
- private string GetCategoryFromId(PckAudioFile.AudioCategory.EAudioType categoryId)
+ public AudioEditor(PckAudioFile audioFile, ISaveContext saveContext)
+ : base(audioFile, saveContext)
+ {
+ InitializeComponent();
+ saveToolStripMenuItem1.Visible = !saveContext.AutoSave;
+ SetUpTree();
+ }
+
+ private string GetCategoryFromId(PckAudioFile.AudioCategory.EAudioType categoryId)
=> categoryId >= PckAudioFile.AudioCategory.EAudioType.Overworld &&
categoryId <= PckAudioFile.AudioCategory.EAudioType.BuildOff
? Categories[(int)categoryId]
@@ -63,26 +63,12 @@ namespace PckStudio.Forms.Editor
return (PckAudioFile.AudioCategory.EAudioType)Categories.IndexOf(category);
}
- public AudioEditor(PckAsset asset, bool isLittleEndian)
- {
- InitializeComponent();
-
- saveToolStripMenuItem1.Visible = !Settings.Default.AutoSaveChanges;
-
- _isLittleEndian = isLittleEndian;
-
- _audioAsset = asset;
- _audioFile = _audioAsset.GetData(new PckAudioFileReader(isLittleEndian ? OMI.Endianness.LittleEndian : OMI.Endianness.BigEndian));
-
- SetUpTree();
- }
-
public void SetUpTree()
{
treeView1.BeginUpdate();
treeView1.Nodes.Clear();
- foreach (PckAudioFile.AudioCategory category in _audioFile.Categories)
+ foreach (PckAudioFile.AudioCategory category in EditorValue.Categories)
{
// fix songs with directories using backslash instead of forward slash
// Songs with a backslash instead of a forward slash would not play in RPCS3
@@ -92,7 +78,7 @@ namespace PckStudio.Forms.Editor
if (category.AudioType == PckAudioFile.AudioCategory.EAudioType.Creative)
{
if (category.Name == "include_overworld" &&
- _audioFile.TryGetCategory(PckAudioFile.AudioCategory.EAudioType.Overworld, out PckAudioFile.AudioCategory overworldCategory))
+ EditorValue.TryGetCategory(PckAudioFile.AudioCategory.EAudioType.Overworld, out PckAudioFile.AudioCategory overworldCategory))
{
foreach (var name in category.SongNames.ToList())
{
@@ -108,24 +94,26 @@ namespace PckStudio.Forms.Editor
treeNode.Tag = category;
treeView1.Nodes.Add(treeNode);
}
- playOverworldInCreative.Enabled = _audioFile.HasCategory(PckAudioFile.AudioCategory.EAudioType.Creative);
+ playOverworldInCreative.Enabled = EditorValue.HasCategory(PckAudioFile.AudioCategory.EAudioType.Creative);
treeView1.EndUpdate();
}
private void verifyFileLocationToolStripMenuItem_Click(object sender, EventArgs e)
{
+ /*
if (treeView1.SelectedNode == null || treeView2.SelectedNode == null)
return;
TreeNode entry = treeView2.SelectedNode;
- if (!parent.CreateDataFolder())
- return;
- string FileName = Path.Combine(parent.GetDataPath(), entry.Text + ".binka");
+ string fileName = Path.Combine(parent., entry.Text + ".binka");
- if (File.Exists(FileName))
+ if (File.Exists(fileName))
MessageBox.Show(this, $"\"{entry.Text}.binka\" exists in the \"Data\" folder", "File found");
else
MessageBox.Show(this, $"\"{entry.Text}.binka\" does not exist in the \"Data\" folder. The game will crash when attempting to load this track.", "File missing");
+ */
+
+ // Disabling this for now until location stuff is fixed
}
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
@@ -144,7 +132,7 @@ namespace PckStudio.Forms.Editor
private void addCategoryStripMenuItem_Click(object sender, EventArgs e)
{
- string[] available = Categories.FindAll(str => !_audioFile.HasCategory(GetCategoryId(str))).ToArray();
+ string[] available = Categories.FindAll(str => !EditorValue.HasCategory(GetCategoryId(str))).ToArray();
if (available.Length == 0)
{
MessageBox.Show(this, "There are no more categories that could be added", "All possible categories are used");
@@ -154,8 +142,8 @@ namespace PckStudio.Forms.Editor
if (add.ShowDialog(this) != DialogResult.OK)
return;
- _audioFile.AddCategory(GetCategoryId(add.SelectedItem));
- PckAudioFile.AudioCategory category = _audioFile.GetCategory(GetCategoryId(add.SelectedItem));
+ EditorValue.AddCategory(GetCategoryId(add.SelectedItem));
+ PckAudioFile.AudioCategory category = EditorValue.GetCategory(GetCategoryId(add.SelectedItem));
if (GetCategoryId(add.SelectedItem) == PckAudioFile.AudioCategory.EAudioType.Creative)
{
@@ -170,31 +158,50 @@ namespace PckStudio.Forms.Editor
SetUpTree();
}
+ private void addTrack(PckAudioFile.AudioCategory category, String trackname)
+ {
+ category.SongNames.Add(trackname);
+ treeView2.Nodes.Add(trackname);
+ }
+
private void addEntryMenuItem_Click(object sender, EventArgs e)
{
- if (treeView1.SelectedNode is TreeNode t && t.Tag is PckAudioFile.AudioCategory)
+ if (treeView1.SelectedNode is TreeNode t && t.Tag is PckAudioFile.AudioCategory category)
{
- if (!parent.CreateDataFolder())
- return;
-
- OpenFileDialog ofn = new OpenFileDialog();
- ofn.Multiselect = true;
- ofn.Filter = "Supported audio files (*.binka,*.wav)|*.binka;*.wav";
- ofn.Title = "Please choose WAV or BINKA files to add to your pack";
- ofn.ShowDialog(this);
- ofn.Dispose();
- // Return if name is null or if the user cancels
- if (string.IsNullOrEmpty(ofn.FileName))
- return;
-
- ProcessEntries(ofn.FileNames);
+ TextPrompt audioEntry = new TextPrompt();
+ audioEntry.contextLabel.Text = "Please enter the relative file path without an extension. (i.e; \"music/song\" => \"DLC/{Pack}/Data/music/song.binka\")";
+ audioEntry.LabelText = "Path";
+ audioEntry.OKButtonText = "Add";
+ if (audioEntry.ShowDialog() == DialogResult.OK)
+ {
+ addTrack(category, audioEntry.NewText);
+ }
}
}
- private void removeCategoryStripMenuItem_Click(object sender, EventArgs e)
+ private void editEntryToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ if (treeView1.SelectedNode is TreeNode t && t.Tag is PckAudioFile.AudioCategory category && treeView2.SelectedNode is TreeNode track)
+ {
+ TextPrompt audioEntry = new TextPrompt(track.Text);
+ audioEntry.contextLabel.Text = "Please enter the relative file path without an extension. (i.e; \"music/song\" => \"DLC/{Pack}/Data/music/song.binka\")";
+ audioEntry.LabelText = "Path";
+ audioEntry.OKButtonText = "Save";
+ if (audioEntry.ShowDialog() == DialogResult.OK)
+ {
+ int index = category.SongNames.IndexOf(track.Text);
+ if (index != -1) // Check if the item was found
+ {
+ track.Text = category.SongNames[index] = audioEntry.NewText;
+ }
+ }
+ }
+ }
+
+ private void removeCategoryStripMenuItem_Click(object sender, EventArgs e)
{
if (treeView1.SelectedNode is TreeNode main &&
- _audioFile.RemoveCategory(GetCategoryId(treeView1.SelectedNode.Text)))
+ EditorValue.RemoveCategory(GetCategoryId(treeView1.SelectedNode.Text)))
{
if(GetCategoryId(treeView1.SelectedNode.Text) == PckAudioFile.AudioCategory.EAudioType.Creative)
{
@@ -227,161 +234,31 @@ namespace PckStudio.Forms.Editor
}
}
- async void ProcessEntries(string[] fileList)
- {
- int success = 0;
- int exitCode = 0;
- InProgressPrompt waitDiag = new InProgressPrompt();
- waitDiag.Show(this);
-
- // TODO: rewrite ALL of this
-
- Directory.CreateDirectory(ApplicationScope.DataCacher.CacheDirectory); // create directory in case it doesn't exist
-
- foreach (string file in fileList)
- {
- if (Path.GetExtension(file) == ".binka" || Path.GetExtension(file) == ".wav")
- {
- string songName = string.Join("_", Path.GetFileNameWithoutExtension(file).Split(Path.GetInvalidFileNameChars()));
- songName = Regex.Replace(songName, @"[^\u0000-\u007F]+", "_"); // Replace UTF characters
- string cacheSongFile = Path.Combine(ApplicationScope.DataCacher.CacheDirectory, songName + Path.GetExtension(file));
-
- if (File.Exists(cacheSongFile))
- File.Delete(cacheSongFile);
-
- string new_loc = Path.Combine(parent.GetDataPath(), 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)
- {
- FileStream fs1 = File.OpenRead(file);
- FileStream fs2 = File.OpenRead(new_loc);
-
- string hash1_str = BitConverter.ToString(MD5.Create().ComputeHash(fs1));
- string hash2_str = BitConverter.ToString(MD5.Create().ComputeHash(fs2));
-
- // close the file streams after calculating the hash
- fs1.Close();
- fs2.Close();
-
- is_duplicate_file = hash1_str == hash2_str;
-
- string diag_text = "A file named \"" + Path.GetFileNameWithoutExtension(file) + ".binka\" already exists in the Data folder.";
-
- if (is_duplicate_file)
- diag_text = "\"" + Path.GetFileNameWithoutExtension(file) + ".binka\" has an identical copy present in the Data folder.";
-
- diag_text += " Pressing yes will replace the existing file. By pressing no, the song entry will be added without affecting the file." +
- "You can also cancel this operation and all files in queue.";
-
- DialogResult user_prompt = MessageBox.Show(this, diag_text, "File already exists", MessageBoxButtons.YesNoCancel);
- while (user_prompt == DialogResult.None) // Stops the editor from adding or processing the file until the user has made their choice
- if (user_prompt == DialogResult.Cancel)
- {
- break;
- }
- else if (user_prompt == DialogResult.No)
- {
- if (treeView1.SelectedNode is TreeNode node && node.Tag is PckAudioFile.AudioCategory cat)
- {
- //adds song without affecting the binka file
- cat.SongNames.Add(songName);
- treeView2.Nodes.Add(songName);
- success++;
- }
- continue;
- }
- else if (user_prompt == DialogResult.Yes)
- {
- // deletes the file so that the copy function can happen safely
- // and ignore duplicate files because well... they're duplicates lol
- if (File.Exists(new_loc) && !is_duplicate_file)
- File.Delete(new_loc);
- }
- }
-
- if (Path.GetExtension(file) == ".wav") // Convert Wave to BINKA
- {
- using (var reader = new WaveFileReader(file)) //read from original location
- {
- var newFormat = new WaveFormat(reader.WaveFormat.SampleRate, 16, reader.WaveFormat.Channels);
- using (var conversionStream = new WaveFormatConversionStream(newFormat, reader))
- {
- WaveFileWriter.CreateWaveFile(cacheSongFile, conversionStream); //write to new location
- }
- reader.Close();
- reader.Dispose();
- }
-
- Cursor.Current = Cursors.WaitCursor;
-
- await Task.Run(() =>
- {
- exitCode = Binka.ToBinka(cacheSongFile, new_loc, (int)compressionUpDown.Value);
- });
-
- if (!File.Exists(cacheSongFile))
- MessageBox.Show(this, $"\"{songName}.wav\" failed to convert for some reason. Please report this on the communtiy Discord server, which can be found under \"More\" in the toolbar at the top of the program.", "Conversion failed");
- else
- {
- success++;
- File.Delete(cacheSongFile); //cleanup song
- }
-
- Cursor.Current = Cursors.Default;
-
- if (exitCode != 0)
- continue;
- }
-
- // if the file is NOT a .wav and doesn't exist, copy the file
- else if (!File.Exists(new_loc))
- {
- File.Copy(file, new_loc);
- success++;
- }
-
- // this is repeated again becuase this is meant to prevent any files that fail to convert from being added to the category
- if (treeView1.SelectedNode is TreeNode t && t.Tag is PckAudioFile.AudioCategory category)
- {
- category.SongNames.Add(songName);
- treeView2.Nodes.Add(songName);
- }
- }
- }
- waitDiag.Close();
- waitDiag.Dispose();
-
- MessageBox.Show(this, $"Successfully processed and/or converted {success}/{fileList.Length} file{(fileList.Length != 1 ? "s" : "" )}", "Done!");
- }
-
private void Binka_DragDrop(object sender, DragEventArgs e)
{
- //MessageBox.Show((Owner.Owner as MainForm).saveLocation);
- // Gets the MainForm so we can access the Save Location
- if (treeView1.SelectedNode != null)
+ if (treeView1.SelectedNode is TreeNode t && t.Tag is PckAudioFile.AudioCategory category)
{
- if (!parent.CreateDataFolder())
- return;
-
- ProcessEntries((string[])e.Data.GetData(DataFormats.FileDrop, false));
+ foreach(String s in (string[])e.Data.GetData(DataFormats.FileDrop, false))
+ {
+ addTrack(category, Path.GetFileNameWithoutExtension(s));
+ }
}
}
private void saveToolStripMenuItem1_Click(object sender, EventArgs e)
{
- if (!_audioFile.HasCategory(PckAudioFile.AudioCategory.EAudioType.Overworld) ||
- !_audioFile.HasCategory(PckAudioFile.AudioCategory.EAudioType.Nether) ||
- !_audioFile.HasCategory(PckAudioFile.AudioCategory.EAudioType.End))
+ if (!EditorValue.HasCategory(PckAudioFile.AudioCategory.EAudioType.Overworld) ||
+ !EditorValue.HasCategory(PckAudioFile.AudioCategory.EAudioType.Nether) ||
+ !EditorValue.HasCategory(PckAudioFile.AudioCategory.EAudioType.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 = _audioFile.GetCategory(PckAudioFile.AudioCategory.EAudioType.Overworld);
+ PckAudioFile.AudioCategory overworldCategory = EditorValue.GetCategory(PckAudioFile.AudioCategory.EAudioType.Overworld);
bool songs_missing = false;
- foreach (PckAudioFile.AudioCategory category in _audioFile.Categories)
+ foreach (PckAudioFile.AudioCategory category in EditorValue.Categories)
{
if (category.SongNames.Count < 1)
{
@@ -389,16 +266,6 @@ namespace PckStudio.Forms.Editor
return;
}
- foreach(var song in category.SongNames)
- {
- string FileName = Path.Combine(parent.GetDataPath(), song + ".binka");
- if (!File.Exists(FileName))
- {
- songs_missing = true;
- MessageBox.Show(this, "\"" + song + ".binka\" does not exist in the \"Data\" folder. The game will crash when attempting to load this track.", "File missing");
- }
- }
-
category.Name = "";
if (playOverworldInCreative.Checked && category.AudioType == PckAudioFile.AudioCategory.EAudioType.Creative)
{
@@ -420,7 +287,7 @@ namespace PckStudio.Forms.Editor
return;
}
- _audioAsset.SetData(new PckAudioFileWriter(_audioFile, _isLittleEndian ? OMI.Endianness.LittleEndian : OMI.Endianness.BigEndian));
+ Save();
DialogResult = DialogResult.OK;
}
@@ -429,93 +296,6 @@ namespace PckStudio.Forms.Editor
e.Effect = DragDropEffects.All;
}
- private void helpToolStripMenuItem_Click(object sender, EventArgs e)
- {
- MessageBox.Show(this, "Simply drag and drop BINKA or WAV audio files into the right tree to add them to the category selected on the left tree.\n\n" +
- "The \"Menu\" category will only play once when loading the pack, and never again.\n\n" +
- "The \"Creative\" category will only play songs listed in that category, and unlike other editions of Minecraft, will NOT play songs from the Overworld category. You can fix this by clicking the checkbox found at the top of the form.\n\n" +
- "The mini game categories will only play if you have your pack loaded in those mini games.\n\n" +
- "You can edit the credits for the PCK in the Credits editor! No more managing credit IDs!\n\n", "Help");
- }
-
- private void deleteUnusedBINKAsToolStripMenuItem_Click(object sender, EventArgs e)
- {
- DialogResult dr = MessageBox.Show(this, "This will delete all unused BINKA songs in the Data directory. This cannot be undone. Are you sure you want to continue?", "Warning", MessageBoxButtons.YesNo);
- if (dr != DialogResult.Yes)
- return;
- var totalSongList = new List();
- foreach (string song in _audioFile.Categories.SelectMany(cat => cat.SongNames))
- {
- Console.WriteLine(song);
- totalSongList.Add(song);
- }
-
- if (!parent.CreateDataFolder())
- return;
- int totalDeleted = 0;
- foreach (string song in Directory.GetFiles(parent.GetDataPath(), "*.binka"))
- {
- if (!totalSongList.Contains(Path.GetFileNameWithoutExtension(song)))
- {
- Console.WriteLine("Deleted " + song);
- try
- {
- File.Delete(song);
- }
- catch (IOException ex)
- {
- Console.WriteLine(ex.Message);
- continue;
- }
- totalDeleted++;
- }
- }
- MessageBox.Show(this, "Successfully deleted " + totalDeleted + " files", "Done");
- }
-
- private void howToAddSongsToolStripMenuItem_Click(object sender, EventArgs e)
- {
- MessageBox.Show(this, "Right click the right window and press \"Add Entry\" or drag and drop a valid WAV file into the editor's right window. You can also drop other BINKA files, either from the main game or using a tool like BinkMan. The editor will automatically put the song in the Data folder for you.", "How to add a song");
- }
-
- private void whatAreTheCategoriesToolStripMenuItem_Click(object sender, EventArgs e)
- {
- MessageBox.Show(this, "Categories are pretty self explanatory. The game controls when each category should play.\n" +
- "\nGAMEPLAY - Plays in the specified dimensions and game modes.\n" +
- "-Overworld: Plays in survival mode and in Creative if no songs are set\n" +
- "-Nether: Plays in the Nether.\n" +
- "-End: Plays in the End. Prioritizes the final track when the dragon is alive.\n" +
- "-Creative: Does not play survival tracks unless they're included.\n" +
- "-Menu: Plays on the title screen and only once when the pack is loading. Perfect for intro songs.\n" +
- "\nMINI GAMES - Will only play if you change the map grf files to load your pack and set the ThemeID to 0 for Vanilla maps.\n" +
- "-Battle: Plays in the Battle Mini Game.\n" +
- "-Tumble: Plays in the Tumble Mini Game.\n" +
- "-Glide: Plays in the Glide Mini Game.\n",
- "What are the categories?");
- }
-
- private void howToEditCreditsToolStripMenuItem_Click(object sender, EventArgs e)
- {
- MessageBox.Show(this, "Click Tools -> Credits Editor. This will allow you to edit all the credits easily in the pack easily. Only supports English credits at the moment. ","How to edit credits?");
- }
-
- private void optimizeDataFolderToolStripMenuItem_Click(object sender, EventArgs e)
- {
- MessageBox.Show(this, "Click Tools -> Delete Unused BINKA files. This will clean your folder of any unused songs.", "How to optimize the Data folder");
- }
-
- private void BINKACompressionToolStripMenuItem_Click(object sender, EventArgs e)
- {
- MessageBox.Show(this, "The numerical up/down control is responsible for the level of compression used when converting WAV files. The default is 4, which was commonly used by 4J for the game's files.","BINKA Compression Level");
- }
-
- 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)
@@ -524,70 +304,11 @@ namespace PckStudio.Forms.Editor
Close();
}
- private async void bulkReplaceExistingFilesToolStripMenuItem_Click(object sender, EventArgs e)
- {
- if (!parent.CreateDataFolder())
- return;
-
- int exitCode = 0;
-
-
- OpenFileDialog ofn = new OpenFileDialog();
- ofn.Multiselect = true;
- ofn.Filter = "Supported audio files (*.binka,*.wav)|*.binka;*.wav";
- ofn.Title = "Please choose WAV or BINKA files to replace existing track files";
- ofn.ShowDialog(this);
- ofn.Dispose();
-
- // Return if name is null or if the user cancels
- if (string.IsNullOrEmpty(ofn.FileName))
- return;
-
- var totalSongList = new List();
- foreach (string song in _audioFile.Categories.SelectMany(cat => cat.SongNames))
- {
- totalSongList.Add(song);
- }
-
- foreach (string file in ofn.FileNames)
- {
- string song_name = Path.GetFileNameWithoutExtension(file);
- string file_ext = Path.GetExtension(file).ToLower();
- string new_loc = Path.Combine(parent.GetDataPath(), Path.GetFileNameWithoutExtension(file) + ".binka");
- if (!totalSongList.Contains(song_name) || file == new_loc)
- continue;
-
- Console.WriteLine(file);
- File.Delete(new_loc);
-
- if (file_ext == ".wav") // Convert Wave to BINKA
- {
- Cursor.Current = Cursors.WaitCursor;
- InProgressPrompt waitDiag = new InProgressPrompt();
- waitDiag.Show(this);
-
- await Task.Run(() =>
- {
- exitCode = Binka.ToBinka(file, new_loc, (int)compressionUpDown.Value);
- });
-
- waitDiag.Close();
- waitDiag.Dispose();
- Cursor.Current = Cursors.Default;
-
- if (exitCode != 0)
- continue;
- }
- else if(file_ext == ".binka")
- File.Copy(file, Path.Combine(parent.GetDataPath(), Path.GetFileName(file)));
- }
- }
-
private void convertToWAVToolStripMenuItem_Click(object sender, EventArgs e)
{
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(parent.GetDataPath(), treeView2.SelectedNode.Text + ".binka"), Path.Combine(parent.GetDataPath()));
}
}
@@ -596,7 +317,7 @@ namespace PckStudio.Forms.Editor
if (!(treeView1.SelectedNode is TreeNode t && t.Tag is PckAudioFile.AudioCategory category))
return;
- string[] available = Categories.FindAll(str => !_audioFile.HasCategory(GetCategoryId(str))).ToArray();
+ string[] available = Categories.FindAll(str => !EditorValue.HasCategory(GetCategoryId(str))).ToArray();
if (available.Length > 0)
{
using ItemSelectionPopUp add = new ItemSelectionPopUp(available);
@@ -604,11 +325,11 @@ namespace PckStudio.Forms.Editor
if (add.ShowDialog(this) != DialogResult.OK)
return;
- _audioFile.RemoveCategory(category.AudioType);
+ EditorValue.RemoveCategory(category.AudioType);
- _audioFile.AddCategory(category.parameterType, GetCategoryId(add.SelectedItem), category.AudioType == PckAudioFile.AudioCategory.EAudioType.Overworld && playOverworldInCreative.Checked ? "include_overworld" : "");
+ EditorValue.AddCategory(category.parameterType, GetCategoryId(add.SelectedItem), category.AudioType == PckAudioFile.AudioCategory.EAudioType.Overworld && playOverworldInCreative.Checked ? "include_overworld" : "");
- PckAudioFile.AudioCategory newCategory = _audioFile.GetCategory(GetCategoryId(add.SelectedItem));
+ PckAudioFile.AudioCategory newCategory = EditorValue.GetCategory(GetCategoryId(add.SelectedItem));
category.SongNames.ForEach(c => newCategory.SongNames.Add(c));
@@ -620,35 +341,6 @@ namespace PckStudio.Forms.Editor
}
}
- private void organizeTracksToolStripMenuItem_Click(object sender, EventArgs e)
- {
- 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())
- return;
- string musicdir = Path.Combine(parent.GetDataPath(), "Music");
- Directory.CreateDirectory(musicdir);
- foreach (PckAudioFile.AudioCategory category in _audioFile.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 new_path = Path.Combine(musicdir, Path.GetFileName(song) + ".binka");
- if (File.Exists(songpath) && !File.Exists(new_path))
- {
- File.Move(songpath, new_path);
-
- // Songs with a backslash instead of a forward slash were not playing in RPCS3
- category.SongNames[i] = "Music/" + song.Replace(song, Path.GetFileNameWithoutExtension(songpath));
- }
- }
- }
- treeView2.Nodes.Clear();
- treeView1.SelectedNode = null;
- }
- }
-
private void AudioEditor_FormClosing(object sender, FormClosingEventArgs e)
{
if (Settings.Default.AutoSaveChanges)
diff --git a/PCK-Studio/Forms/Editor/AudioEditor.resx b/PCK-Studio/Forms/Editor/AudioEditor.resx
index f052be01..93f45462 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
- NAAAAk1TRnQBSQFMAgEBCQEAAeABAAHgAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
+ NAAAAk1TRnQBSQFMAgEBCQEAAfABAAHwAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
AwABMAMAAQEBAAEgBgABMBIAATkBXgFzAf8BOQFeAXMB/wE5AV4BcwH/AT4BYgF8Af8BMwFUAWkB/wEz
AVQBaQH/AT4BYgF8Af8BMwFUAWkB/wE5AV4BcwH/ATkBXgFzAf8BOQFeAXMB/wEzAVQBaQH/ASYBPQFM
Af8BMwFUAWkB/wEzAVQBaQH/ATkBXgFzAf/AAAFiAZgBvAH/AWIBmAG8Af8BTQGEAZ8B/wFNAYQBnwH/
@@ -426,100 +400,38 @@
5
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
+ vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMkMEa+wAAABPSURBVDhP5ZAx
+ DgAgCAMZ/f+HMcbYYOmg0UmHY2ibGzB3txNSgMKsHcD9ksBL5wcBPwyPCwLFJBjjVe4LFHGsgEDBAu6x
+ 4+AxAT9MkYJdKi90axNkwjxWAAAAAElFTkSuQmCC
+
+
+
+ 168, 22
+
+
+ Add Category
+
+
+ 168, 22
+
+
+ Remove Category
+
+
+ 168, 22
+
+
+ Set Category
+
19, 8
False
-
-
- 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
-
-
-
- 98, 22
-
-
- Save
-
-
- 37, 20
-
-
- File
-
-
- 220, 22
-
-
- Delete Unused BINKAs
-
-
- 220, 22
-
-
- Open Data Folder
-
-
- 220, 22
-
-
- Bulk Replace Existing Tracks
-
-
- 220, 22
-
-
- Organize Tracks
-
-
- 46, 20
-
-
- Tools
-
-
- 243, 22
-
-
- How to add songs
-
-
- 243, 22
-
-
- What are the categories?
-
-
- 243, 22
-
-
- How to edit credits
-
-
- 243, 22
-
-
- How to optimize the Data folder
-
-
- 243, 22
-
-
- BINKA Compression
-
-
- 44, 20
-
-
- Help
-
20, 60
@@ -544,6 +456,28 @@
7
+
+ 37, 20
+
+
+ File
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
+ vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4yMfEgaZUAAADdSURBVDhPzZJB
+ CoJQEIa9jy0iPFAnCDpAtG3ZooUE4b6oVtIuClpJIAgqZEVlKpqEHUAm5pGPmhTbRA18G//5P5iHgvA3
+ I7ZniiQ7aVM9QZzcOKYbwVDbw8I6A2YAICBvg2VJdtjSs2Cse1Dt6tCYbliGO0UCFlLBxAj590yA0D4X
+ 1Ec7CK8JF9j+lUmWzoVlpYJaz4JKZ5ULZqWCT6F9Jhhowcv9eeBOoQBvPXoBrA0zF8yyR6V9LvCjGLYH
+ NxfMvipIMaQ3Ux6ClPYFsaUq/bmd0rspuIO/Pe3/bu5p+sr3gTvFEQAAAABJRU5ErkJggg==
+
+
+
+ 180, 22
+
+
+ Save
+
Top, Bottom, Left, Right
@@ -553,37 +487,31 @@
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
- vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMkMEa+wAAABSSURBVDhP5c0x
- DsAgDENRxt7/wmkNSpRGf0CCCZAegxNMM7MlGMp3dIU6dxhKf/QMNxRogeQC8ivw5Vn7C0heJlFA+kL5
- jWAohxRkde4wnGftBS90axNmphIGAAAAAElFTkSuQmCC
+ vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMkMEa+wAAABPSURBVDhP5ZAx
+ DgAgCAMZ/f+HMcbYYOmg0UmHY2ibGzB3txNSgMKsHcD9ksBL5wcBPwyPCwLFJBjjVe4LFHGsgEDBAu6x
+ 4+AxAT9MkYJdKi90axNkwjxWAAAAAElFTkSuQmCC
- 173, 22
+ 180, 22
- Add Entry
+ Add Track
+
+
+ 180, 22
+
+
+ Edit Track
- 173, 22
+ 180, 22
- Remove Entry
-
-
- 173, 22
-
-
- Verify File Location
-
-
- 173, 22
-
-
- Convert To WAV
+ Remove Track
- 174, 92
+ 181, 92
contextMenuStrip2
@@ -3256,72 +3184,6 @@
System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- toolsToolStripMenuItem
-
-
- System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- deleteUnusedBINKAsToolStripMenuItem
-
-
- System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- openDataFolderToolStripMenuItem
-
-
- System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- bulkReplaceExistingTracksToolStripMenuItem
-
-
- System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- organizeTracksToolStripMenuItem
-
-
- System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- helpToolStripMenuItem
-
-
- System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- howToAddSongsToolStripMenuItem
-
-
- System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- whatAreTheCategoriesToolStripMenuItem
-
-
- System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- howToEditCreditsToolStripMenuItem
-
-
- System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- optimizeDataFolderToolStripMenuItem
-
-
- System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- bINKACompressionToolStripMenuItem
-
-
- System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
addEntryMenuItem
@@ -3334,22 +3196,16 @@
System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- verifyFileLocationToolStripMenuItem
+
+ editEntryToolStripMenuItem
-
- System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- convertToWAVToolStripMenuItem
-
-
+
System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
AudioEditor
- MetroFramework.Forms.MetroForm, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a
+ PckStudio.Controls.EditorForm`1[[PckStudio.Core.FileFormats.PckAudioFile, PckStudio.Core, Version=0.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/BehaviourEditor.Designer.cs b/PCK-Studio/Forms/Editor/BehaviourEditor.Designer.cs
index ed133825..48a4202d 100644
--- a/PCK-Studio/Forms/Editor/BehaviourEditor.Designer.cs
+++ b/PCK-Studio/Forms/Editor/BehaviourEditor.Designer.cs
@@ -299,7 +299,6 @@
this.Style = MetroFramework.MetroColorStyle.Silver;
this.Text = "Behaviour Editor";
this.Theme = MetroFramework.MetroThemeStyle.Dark;
- this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.BehaviourEditor_FormClosing);
this.metroContextMenu1.ResumeLayout(false);
this.menuStrip.ResumeLayout(false);
this.menuStrip.PerformLayout();
diff --git a/PCK-Studio/Forms/Editor/BehaviourEditor.cs b/PCK-Studio/Forms/Editor/BehaviourEditor.cs
index c47957ee..87e52027 100644
--- a/PCK-Studio/Forms/Editor/BehaviourEditor.cs
+++ b/PCK-Studio/Forms/Editor/BehaviourEditor.cs
@@ -1,75 +1,64 @@
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.Forms.Additional_Popups.EntityForms;
-using Newtonsoft.Json.Linq;
+using System.Collections.Generic;
using OMI.Formats.Behaviour;
-using OMI.Workers.Behaviour;
-using OMI.Formats.Pck;
-using PckStudio.Properties;
-using PckStudio.Internal;
-using PckStudio.Extensions;
-using PckStudio.Internal.Json;
+using PckStudio.Controls;
using PckStudio.Internal.App;
+using PckStudio.Interfaces;
+using PckStudio.Forms.Additional_Popups.EntityForms;
+using PckStudio.Json;
+using PckStudio.Core.Json;
namespace PckStudio.Forms.Editor
{
- public partial class BehaviourEditor : MetroForm
+ // Behaviours File Format research by Miku and MayNL
+ public partial class BehaviourEditor : EditorForm
{
- // Behaviours File Format research by Miku and MattNL
- private readonly PckAsset _asset;
- BehaviourFile _behaviourFile;
+ private const string BehaviourEntryDataType = "behaviours";
+ private readonly List BehaviourData = Entities.BehaviourInfos;
- private readonly List BehaviourData = Entities.BehaviourInfos;
+ public BehaviourEditor(BehaviourFile behaviourFile, ISaveContext saveContext)
+ : base(behaviourFile, saveContext)
+ {
+ InitializeComponent();
- void SetUpTree()
+ saveToolStripMenuItem1.Visible = !saveContext.AutoSave;
+
+ treeView1.ImageList = new ImageList();
+ treeView1.ImageList.Images.AddRange(ApplicationScope.EntityImages);
+ treeView1.ImageList.ColorDepth = ColorDepth.Depth32Bit;
+ SetUpTree();
+ }
+
+ void SetUpTree()
{
treeView1.BeginUpdate();
treeView1.Nodes.Clear();
- foreach (var entry in _behaviourFile.entries)
+ foreach (BehaviourFile.RiderPositionOverride entry in EditorValue.entries)
{
- TreeNode EntryNode = new TreeNode(entry.name);
+ TreeNode entryNode = new TreeNode(entry.name);
- var behaviour = BehaviourData.Find(b => b.InternalName == entry.name);
- EntryNode.Text = behaviour.DisplayName;
- EntryNode.ImageIndex = BehaviourData.IndexOf(behaviour);
- EntryNode.SelectedImageIndex = EntryNode.ImageIndex;
- EntryNode.Tag = entry;
+ EntityInfo behaviour = BehaviourData.Find(b => b.InternalName == entry.name);
+ entryNode.Text = behaviour.DisplayName;
+ entryNode.ImageIndex = BehaviourData.IndexOf(behaviour);
+ entryNode.SelectedImageIndex = entryNode.ImageIndex;
+ entryNode.Tag = entry;
- foreach (var posOverride in entry.overrides)
+ foreach (BehaviourFile.RiderPositionOverride.PositionOverride posOverride in entry.overrides)
{
- TreeNode OverrideNode = new TreeNode("Position Override");
- OverrideNode.Tag = posOverride;
- EntryNode.Nodes.Add(OverrideNode);
- OverrideNode.ImageIndex = 103;
- OverrideNode.SelectedImageIndex = OverrideNode.ImageIndex;
+ TreeNode overrideNode = new TreeNode("Position Override");
+ overrideNode.Tag = posOverride;
+ entryNode.Nodes.Add(overrideNode);
+ overrideNode.ImageIndex = 103;
+ overrideNode.SelectedImageIndex = overrideNode.ImageIndex;
}
- treeView1.Nodes.Add(EntryNode);
+ treeView1.Nodes.Add(entryNode);
}
treeView1.EndUpdate();
}
- public BehaviourEditor(PckAsset asset)
- {
- InitializeComponent();
-
- saveToolStripMenuItem1.Visible = !Settings.Default.AutoSaveChanges;
-
- _asset = asset;
- _behaviourFile = asset.GetData(new BehavioursReader());
-
- treeView1.ImageList = new ImageList();
- treeView1.ImageList.Images.AddRange(ApplicationScope.EntityImages);
- treeView1.ImageList.ColorDepth = ColorDepth.Depth32Bit;
- SetUpTree();
- }
-
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
if (treeView1.SelectedNode is null)
@@ -149,13 +138,13 @@ namespace PckStudio.Forms.Editor
if (!(treeView1.SelectedNode.Tag is BehaviourFile.RiderPositionOverride entry))
return;
- var diag = new AddEntry("behaviours", ApplicationScope.EntityImages);
+ var diag = new AddEntry(BehaviourEntryDataType, ApplicationScope.EntityImages);
if (diag.ShowDialog(this) == DialogResult.OK)
{
if (string.IsNullOrEmpty(diag.SelectedEntity))
return;
- if (_behaviourFile.entries.FindAll(behaviour => behaviour.name == diag.SelectedEntity).Count() > 0)
+ if (EditorValue.entries.FindAll(behaviour => behaviour.name == diag.SelectedEntity).Count() > 0)
{
MessageBox.Show(this, "You cannot have two entries for one entity. Please use the \"Add New Position Override\" tool to add multiple overrides for entities", "Error", MessageBoxButtons.OK);
return;
@@ -186,41 +175,46 @@ namespace PckStudio.Forms.Editor
if (treeView1.SelectedNode.Tag is BehaviourFile.RiderPositionOverride.PositionOverride)
treeView1.SelectedNode = treeView1.SelectedNode.Parent;
- if (treeView1.SelectedNode.Tag is BehaviourFile.RiderPositionOverride)
+ if (treeView1.SelectedNode.Tag is BehaviourFile.RiderPositionOverride positionOverride)
{
- TreeNode OverrideNode = new TreeNode("Position Override");
- OverrideNode.Tag = new BehaviourFile.RiderPositionOverride.PositionOverride();
- OverrideNode.ImageIndex = 103;
- OverrideNode.SelectedImageIndex = 103;
- treeView1.SelectedNode.Nodes.Add(OverrideNode);
- }
+ BehaviourFile.RiderPositionOverride.PositionOverride newPositionOverride = new BehaviourFile.RiderPositionOverride.PositionOverride();
+ TreeNode overrideNode = new TreeNode("Position Override");
+ overrideNode.Tag = newPositionOverride;
+ overrideNode.ImageIndex = 103;
+ overrideNode.SelectedImageIndex = 103;
+ treeView1.SelectedNode.Nodes.Add(overrideNode);
+ positionOverride.overrides.Add(newPositionOverride);
+ }
}
private void addNewEntryToolStripMenuItem_Click(object sender, EventArgs e)
{
- var diag = new AddEntry("behaviours", ApplicationScope.EntityImages);
+ var diag = new AddEntry(BehaviourEntryDataType, ApplicationScope.EntityImages);
if(diag.ShowDialog(this) == DialogResult.OK)
{
if (string.IsNullOrEmpty(diag.SelectedEntity))
return;
- if (_behaviourFile.entries.FindAll(behaviour => behaviour.name == diag.SelectedEntity).Count() > 0)
+ if (EditorValue.entries.FindAll(behaviour => behaviour.name == diag.SelectedEntity).Count() > 0)
{
MessageBox.Show(this, "You cannot have two entries for one entity. Please use the \"Add New Position Override\" tool to add multiple overrides for entities", "Error", MessageBoxButtons.OK);
return;
}
- BehaviourFile.RiderPositionOverride NewOverride = new BehaviourFile.RiderPositionOverride(diag.SelectedEntity);
+ BehaviourFile.RiderPositionOverride newOverride = new BehaviourFile.RiderPositionOverride(diag.SelectedEntity);
+ EditorValue.entries.Add(newOverride);
- TreeNode NewOverrideNode = new TreeNode(NewOverride.name);
- NewOverrideNode.Tag = NewOverride;
+ TreeNode newOverrideNode = new TreeNode(newOverride.name);
+ newOverrideNode.Tag = newOverride;
- EntityInfo behaviour = BehaviourData.Find(b => b.InternalName == NewOverride.name);
- NewOverrideNode.Text = behaviour.DisplayName;
- NewOverrideNode.ImageIndex = BehaviourData.IndexOf(behaviour);
- NewOverrideNode.SelectedImageIndex = NewOverrideNode.ImageIndex;
+ // potentially null de-reference
+ EntityInfo behaviour = BehaviourData.Find(b => b.InternalName == newOverride.name);
- treeView1.Nodes.Add(NewOverrideNode);
- treeView1.SelectedNode = NewOverrideNode;
+ newOverrideNode.Text = behaviour.DisplayName;
+ newOverrideNode.ImageIndex = BehaviourData.IndexOf(behaviour);
+ newOverrideNode.SelectedImageIndex = newOverrideNode.ImageIndex;
+
+ treeView1.Nodes.Add(newOverrideNode);
+ treeView1.SelectedNode = newOverrideNode;
addNewPositionOverrideToolStripMenuItem_Click(sender, e); // adds a Position Override to the new Override
}
@@ -239,36 +233,8 @@ namespace PckStudio.Forms.Editor
private void saveToolStripMenuItem1_Click(object sender, EventArgs e)
{
- _behaviourFile = new BehaviourFile();
- foreach (TreeNode node in treeView1.Nodes)
- {
- if(node.Tag is BehaviourFile.RiderPositionOverride entry)
- {
- entry.overrides.Clear();
- Console.WriteLine();
- foreach (TreeNode overrideNode in node.Nodes)
- {
- if(overrideNode.Tag is BehaviourFile.RiderPositionOverride.PositionOverride overrideEntry)
- {
- entry.overrides.Add(overrideEntry);
- }
- }
-
- _behaviourFile.entries.Add(entry);
- }
- }
-
- _asset.SetData(new BehavioursWriter(_behaviourFile));
-
+ Save();
DialogResult = DialogResult.OK;
}
-
- private void BehaviourEditor_FormClosing(object sender, FormClosingEventArgs e)
- {
- if (Settings.Default.AutoSaveChanges)
- {
- saveToolStripMenuItem1_Click(sender, EventArgs.Empty);
- }
- }
}
}
diff --git a/PCK-Studio/Forms/Editor/BoxEditor.Designer.cs b/PCK-Studio/Forms/Editor/BoxEditor.Designer.cs
index ea00556f..14cfedb8 100644
--- a/PCK-Studio/Forms/Editor/BoxEditor.Designer.cs
+++ b/PCK-Studio/Forms/Editor/BoxEditor.Designer.cs
@@ -28,100 +28,15 @@
///
private void InitializeComponent()
{
- MetroFramework.Controls.MetroLabel parentLabel;
- MetroFramework.Controls.MetroLabel positionLabel;
- MetroFramework.Controls.MetroLabel sizeLabel;
- MetroFramework.Controls.MetroLabel uvLabel;
- MetroFramework.Controls.MetroLabel inflationLabel;
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(BoxEditor));
this.closeButton = new MetroFramework.Controls.MetroButton();
this.toolTip = new MetroFramework.Components.MetroToolTip();
- this.parentComboBox = new MetroFramework.Controls.MetroComboBox();
- this.PosXUpDown = new System.Windows.Forms.NumericUpDown();
- this.PosYUpDown = new System.Windows.Forms.NumericUpDown();
- this.PosZUpDown = new System.Windows.Forms.NumericUpDown();
- this.SizeZUpDown = new System.Windows.Forms.NumericUpDown();
- this.SizeYUpDown = new System.Windows.Forms.NumericUpDown();
- this.SizeXUpDown = new System.Windows.Forms.NumericUpDown();
- this.uvYUpDown = new System.Windows.Forms.NumericUpDown();
- this.uvXUpDown = new System.Windows.Forms.NumericUpDown();
- this.armorCheckBox = new MetroFramework.Controls.MetroCheckBox();
- this.mirrorCheckBox = new MetroFramework.Controls.MetroCheckBox();
- this.inflationUpDown = new System.Windows.Forms.NumericUpDown();
- parentLabel = new MetroFramework.Controls.MetroLabel();
- positionLabel = new MetroFramework.Controls.MetroLabel();
- sizeLabel = new MetroFramework.Controls.MetroLabel();
- uvLabel = new MetroFramework.Controls.MetroLabel();
- inflationLabel = new MetroFramework.Controls.MetroLabel();
- ((System.ComponentModel.ISupportInitialize)(this.PosXUpDown)).BeginInit();
- ((System.ComponentModel.ISupportInitialize)(this.PosYUpDown)).BeginInit();
- ((System.ComponentModel.ISupportInitialize)(this.PosZUpDown)).BeginInit();
- ((System.ComponentModel.ISupportInitialize)(this.SizeZUpDown)).BeginInit();
- ((System.ComponentModel.ISupportInitialize)(this.SizeYUpDown)).BeginInit();
- ((System.ComponentModel.ISupportInitialize)(this.SizeXUpDown)).BeginInit();
- ((System.ComponentModel.ISupportInitialize)(this.uvYUpDown)).BeginInit();
- ((System.ComponentModel.ISupportInitialize)(this.uvXUpDown)).BeginInit();
- ((System.ComponentModel.ISupportInitialize)(this.inflationUpDown)).BeginInit();
+ this.boxEditorControl1 = new PckStudio.Controls.BoxEditorControl();
this.SuspendLayout();
//
- // parentLabel
- //
- parentLabel.AutoSize = true;
- parentLabel.FontSize = MetroFramework.MetroLabelSize.Tall;
- parentLabel.Location = new System.Drawing.Point(357, 72);
- parentLabel.Name = "parentLabel";
- parentLabel.Size = new System.Drawing.Size(64, 25);
- parentLabel.TabIndex = 2;
- parentLabel.Text = "Parent:";
- parentLabel.Theme = MetroFramework.MetroThemeStyle.Dark;
- //
- // positionLabel
- //
- positionLabel.AutoSize = true;
- positionLabel.FontSize = MetroFramework.MetroLabelSize.Tall;
- positionLabel.Location = new System.Drawing.Point(33, 72);
- positionLabel.Name = "positionLabel";
- positionLabel.Size = new System.Drawing.Size(75, 25);
- positionLabel.TabIndex = 4;
- positionLabel.Text = "Position:";
- positionLabel.Theme = MetroFramework.MetroThemeStyle.Dark;
- //
- // sizeLabel
- //
- sizeLabel.AutoSize = true;
- sizeLabel.FontSize = MetroFramework.MetroLabelSize.Tall;
- sizeLabel.Location = new System.Drawing.Point(33, 97);
- sizeLabel.Name = "sizeLabel";
- sizeLabel.Size = new System.Drawing.Size(46, 25);
- sizeLabel.TabIndex = 22;
- sizeLabel.Text = "Size:";
- sizeLabel.Theme = MetroFramework.MetroThemeStyle.Dark;
- //
- // uvLabel
- //
- uvLabel.AutoSize = true;
- uvLabel.FontSize = MetroFramework.MetroLabelSize.Tall;
- uvLabel.Location = new System.Drawing.Point(33, 123);
- uvLabel.Name = "uvLabel";
- uvLabel.Size = new System.Drawing.Size(39, 25);
- uvLabel.TabIndex = 26;
- uvLabel.Text = "UV:";
- uvLabel.Theme = MetroFramework.MetroThemeStyle.Dark;
- //
- // inflationLabel
- //
- inflationLabel.AutoSize = true;
- inflationLabel.FontSize = MetroFramework.MetroLabelSize.Tall;
- inflationLabel.Location = new System.Drawing.Point(33, 149);
- inflationLabel.Name = "inflationLabel";
- inflationLabel.Size = new System.Drawing.Size(55, 25);
- inflationLabel.TabIndex = 31;
- inflationLabel.Text = "Scale:";
- inflationLabel.Theme = MetroFramework.MetroThemeStyle.Dark;
- //
// closeButton
//
- this.closeButton.Location = new System.Drawing.Point(252, 187);
+ this.closeButton.Location = new System.Drawing.Point(207, 187);
this.closeButton.Name = "closeButton";
this.closeButton.Size = new System.Drawing.Size(126, 23);
this.closeButton.TabIndex = 1;
@@ -137,300 +52,26 @@
this.toolTip.StyleManager = null;
this.toolTip.Theme = MetroFramework.MetroThemeStyle.Dark;
//
- // parentComboBox
+ // boxEditorControl1
//
- this.parentComboBox.FormattingEnabled = true;
- this.parentComboBox.ItemHeight = 23;
- this.parentComboBox.Items.AddRange(new object[] {
- "HEAD",
- "BODY",
- "ARM0",
- "ARM1",
- "LEG0",
- "LEG1",
- "HEADWEAR",
- "JACKET",
- "SLEEVE0",
- "SLEEVE1",
- "PANTS0",
- "PANTS1",
- "WAIST",
- "LEGGING0",
- "LEGGING1",
- "SOCK0",
- "SOCK1",
- "BOOT0",
- "BOOT1",
- "ARMARMOR1",
- "ARMARMOR0",
- "BODYARMOR",
- "BELT"});
- this.parentComboBox.Location = new System.Drawing.Point(417, 72);
- this.parentComboBox.Name = "parentComboBox";
- this.parentComboBox.Size = new System.Drawing.Size(163, 29);
- this.parentComboBox.TabIndex = 3;
- this.parentComboBox.Theme = MetroFramework.MetroThemeStyle.Dark;
- this.parentComboBox.UseSelectable = true;
- //
- // PosXUpDown
- //
- this.PosXUpDown.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(17)))), ((int)(((byte)(17)))), ((int)(((byte)(17)))));
- this.PosXUpDown.DecimalPlaces = 3;
- this.PosXUpDown.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204)))));
- this.PosXUpDown.Increment = new decimal(new int[] {
- 1,
- 0,
- 0,
- 65536});
- this.PosXUpDown.Location = new System.Drawing.Point(120, 76);
- this.PosXUpDown.Maximum = new decimal(new int[] {
- 9999,
- 0,
- 0,
- 0});
- this.PosXUpDown.Minimum = new decimal(new int[] {
- 9999,
- 0,
- 0,
- -2147483648});
- this.PosXUpDown.Name = "PosXUpDown";
- this.PosXUpDown.Size = new System.Drawing.Size(73, 20);
- this.PosXUpDown.TabIndex = 19;
- //
- // PosYUpDown
- //
- this.PosYUpDown.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(17)))), ((int)(((byte)(17)))), ((int)(((byte)(17)))));
- this.PosYUpDown.DecimalPlaces = 3;
- this.PosYUpDown.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204)))));
- this.PosYUpDown.Increment = new decimal(new int[] {
- 1,
- 0,
- 0,
- 65536});
- this.PosYUpDown.Location = new System.Drawing.Point(199, 76);
- this.PosYUpDown.Maximum = new decimal(new int[] {
- 9999,
- 0,
- 0,
- 0});
- this.PosYUpDown.Minimum = new decimal(new int[] {
- 9999,
- 0,
- 0,
- -2147483648});
- this.PosYUpDown.Name = "PosYUpDown";
- this.PosYUpDown.Size = new System.Drawing.Size(73, 20);
- this.PosYUpDown.TabIndex = 20;
- //
- // PosZUpDown
- //
- this.PosZUpDown.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(17)))), ((int)(((byte)(17)))), ((int)(((byte)(17)))));
- this.PosZUpDown.DecimalPlaces = 3;
- this.PosZUpDown.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204)))));
- this.PosZUpDown.Increment = new decimal(new int[] {
- 1,
- 0,
- 0,
- 65536});
- this.PosZUpDown.Location = new System.Drawing.Point(278, 76);
- this.PosZUpDown.Maximum = new decimal(new int[] {
- 9999,
- 0,
- 0,
- 0});
- this.PosZUpDown.Minimum = new decimal(new int[] {
- 9999,
- 0,
- 0,
- -2147483648});
- this.PosZUpDown.Name = "PosZUpDown";
- this.PosZUpDown.Size = new System.Drawing.Size(73, 20);
- this.PosZUpDown.TabIndex = 21;
- //
- // SizeZUpDown
- //
- this.SizeZUpDown.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(17)))), ((int)(((byte)(17)))), ((int)(((byte)(17)))));
- this.SizeZUpDown.DecimalPlaces = 3;
- this.SizeZUpDown.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204)))));
- this.SizeZUpDown.Increment = new decimal(new int[] {
- 1,
- 0,
- 0,
- 65536});
- this.SizeZUpDown.Location = new System.Drawing.Point(278, 102);
- this.SizeZUpDown.Maximum = new decimal(new int[] {
- 9999,
- 0,
- 0,
- 0});
- this.SizeZUpDown.Name = "SizeZUpDown";
- this.SizeZUpDown.Size = new System.Drawing.Size(73, 20);
- this.SizeZUpDown.TabIndex = 25;
- //
- // SizeYUpDown
- //
- this.SizeYUpDown.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(17)))), ((int)(((byte)(17)))), ((int)(((byte)(17)))));
- this.SizeYUpDown.DecimalPlaces = 3;
- this.SizeYUpDown.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204)))));
- this.SizeYUpDown.Increment = new decimal(new int[] {
- 1,
- 0,
- 0,
- 65536});
- this.SizeYUpDown.Location = new System.Drawing.Point(199, 102);
- this.SizeYUpDown.Maximum = new decimal(new int[] {
- 9999,
- 0,
- 0,
- 0});
- this.SizeYUpDown.Name = "SizeYUpDown";
- this.SizeYUpDown.Size = new System.Drawing.Size(73, 20);
- this.SizeYUpDown.TabIndex = 24;
- //
- // SizeXUpDown
- //
- this.SizeXUpDown.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(17)))), ((int)(((byte)(17)))), ((int)(((byte)(17)))));
- this.SizeXUpDown.DecimalPlaces = 3;
- this.SizeXUpDown.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204)))));
- this.SizeXUpDown.Increment = new decimal(new int[] {
- 1,
- 0,
- 0,
- 65536});
- this.SizeXUpDown.Location = new System.Drawing.Point(120, 102);
- this.SizeXUpDown.Maximum = new decimal(new int[] {
- 9999,
- 0,
- 0,
- 0});
- this.SizeXUpDown.Name = "SizeXUpDown";
- this.SizeXUpDown.Size = new System.Drawing.Size(73, 20);
- this.SizeXUpDown.TabIndex = 23;
- //
- // uvYUpDown
- //
- this.uvYUpDown.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(17)))), ((int)(((byte)(17)))), ((int)(((byte)(17)))));
- this.uvYUpDown.DecimalPlaces = 3;
- this.uvYUpDown.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204)))));
- this.uvYUpDown.Increment = new decimal(new int[] {
- 1,
- 0,
- 0,
- 65536});
- this.uvYUpDown.Location = new System.Drawing.Point(199, 128);
- this.uvYUpDown.Maximum = new decimal(new int[] {
- 9999,
- 0,
- 0,
- 0});
- this.uvYUpDown.Minimum = new decimal(new int[] {
- 9999,
- 0,
- 0,
- -2147483648});
- this.uvYUpDown.Name = "uvYUpDown";
- this.uvYUpDown.Size = new System.Drawing.Size(73, 20);
- this.uvYUpDown.TabIndex = 28;
- //
- // uvXUpDown
- //
- this.uvXUpDown.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(17)))), ((int)(((byte)(17)))), ((int)(((byte)(17)))));
- this.uvXUpDown.DecimalPlaces = 3;
- this.uvXUpDown.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204)))));
- this.uvXUpDown.Increment = new decimal(new int[] {
- 1,
- 0,
- 0,
- 65536});
- this.uvXUpDown.Location = new System.Drawing.Point(120, 128);
- this.uvXUpDown.Maximum = new decimal(new int[] {
- 9999,
- 0,
- 0,
- 0});
- this.uvXUpDown.Minimum = new decimal(new int[] {
- 9999,
- 0,
- 0,
- -2147483648});
- this.uvXUpDown.Name = "uvXUpDown";
- this.uvXUpDown.Size = new System.Drawing.Size(73, 20);
- this.uvXUpDown.TabIndex = 27;
- //
- // armorCheckBox
- //
- this.armorCheckBox.AutoSize = true;
- this.armorCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Tall;
- this.armorCheckBox.FontWeight = MetroFramework.MetroCheckBoxWeight.Light;
- this.armorCheckBox.Location = new System.Drawing.Point(363, 101);
- this.armorCheckBox.Name = "armorCheckBox";
- this.armorCheckBox.Size = new System.Drawing.Size(245, 25);
- this.armorCheckBox.TabIndex = 29;
- this.armorCheckBox.Text = "Hide when wearing a helmet";
- this.armorCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
- this.armorCheckBox.UseSelectable = true;
- //
- // mirrorCheckBox
- //
- this.mirrorCheckBox.AutoSize = true;
- this.mirrorCheckBox.FontSize = MetroFramework.MetroCheckBoxSize.Tall;
- this.mirrorCheckBox.FontWeight = MetroFramework.MetroCheckBoxWeight.Light;
- this.mirrorCheckBox.Location = new System.Drawing.Point(363, 130);
- this.mirrorCheckBox.Name = "mirrorCheckBox";
- this.mirrorCheckBox.Size = new System.Drawing.Size(133, 25);
- this.mirrorCheckBox.TabIndex = 30;
- this.mirrorCheckBox.Text = "Mirror Texture";
- this.mirrorCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
- this.mirrorCheckBox.UseSelectable = true;
- //
- // inflationUpDown
- //
- this.inflationUpDown.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(17)))), ((int)(((byte)(17)))), ((int)(((byte)(17)))));
- this.inflationUpDown.DecimalPlaces = 3;
- this.inflationUpDown.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204)))));
- this.inflationUpDown.Increment = new decimal(new int[] {
- 1,
- 0,
- 0,
- 65536});
- this.inflationUpDown.Location = new System.Drawing.Point(120, 154);
- this.inflationUpDown.Maximum = new decimal(new int[] {
- 9999,
- 0,
- 0,
- 0});
- this.inflationUpDown.Name = "inflationUpDown";
- this.inflationUpDown.Size = new System.Drawing.Size(73, 20);
- this.inflationUpDown.TabIndex = 32;
+ this.boxEditorControl1.BackColor = System.Drawing.Color.Transparent;
+ this.boxEditorControl1.Location = new System.Drawing.Point(0, 0);
+ this.boxEditorControl1.Name = "boxEditorControl1";
+ this.boxEditorControl1.Size = new System.Drawing.Size(540, 220);
+ this.boxEditorControl1.TabIndex = 2;
//
// BoxEditor
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(630, 220);
- this.Controls.Add(this.inflationUpDown);
- this.Controls.Add(this.uvYUpDown);
- this.Controls.Add(this.uvXUpDown);
- this.Controls.Add(this.SizeZUpDown);
- this.Controls.Add(this.SizeYUpDown);
- this.Controls.Add(this.SizeXUpDown);
- this.Controls.Add(this.PosZUpDown);
- this.Controls.Add(this.PosYUpDown);
- this.Controls.Add(this.PosXUpDown);
- this.Controls.Add(inflationLabel);
- this.Controls.Add(this.parentComboBox);
- this.Controls.Add(this.mirrorCheckBox);
- this.Controls.Add(this.armorCheckBox);
- this.Controls.Add(uvLabel);
- this.Controls.Add(sizeLabel);
- this.Controls.Add(positionLabel);
- this.Controls.Add(parentLabel);
+ this.ClientSize = new System.Drawing.Size(540, 220);
this.Controls.Add(this.closeButton);
+ this.Controls.Add(this.boxEditorControl1);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
- this.MaximumSize = new System.Drawing.Size(630, 554);
+ this.MaximumSize = new System.Drawing.Size(540, 554);
this.MinimizeBox = false;
- this.MinimumSize = new System.Drawing.Size(630, 220);
+ this.MinimumSize = new System.Drawing.Size(540, 220);
this.Name = "BoxEditor";
this.Resizable = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
@@ -438,34 +79,13 @@
this.Text = "BOX Editor";
this.Theme = MetroFramework.MetroThemeStyle.Dark;
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.BoxEditor_FormClosing);
- ((System.ComponentModel.ISupportInitialize)(this.PosXUpDown)).EndInit();
- ((System.ComponentModel.ISupportInitialize)(this.PosYUpDown)).EndInit();
- ((System.ComponentModel.ISupportInitialize)(this.PosZUpDown)).EndInit();
- ((System.ComponentModel.ISupportInitialize)(this.SizeZUpDown)).EndInit();
- ((System.ComponentModel.ISupportInitialize)(this.SizeYUpDown)).EndInit();
- ((System.ComponentModel.ISupportInitialize)(this.SizeXUpDown)).EndInit();
- ((System.ComponentModel.ISupportInitialize)(this.uvYUpDown)).EndInit();
- ((System.ComponentModel.ISupportInitialize)(this.uvXUpDown)).EndInit();
- ((System.ComponentModel.ISupportInitialize)(this.inflationUpDown)).EndInit();
this.ResumeLayout(false);
- this.PerformLayout();
}
#endregion
private MetroFramework.Controls.MetroButton closeButton;
private MetroFramework.Components.MetroToolTip toolTip;
- private MetroFramework.Controls.MetroComboBox parentComboBox;
- private System.Windows.Forms.NumericUpDown PosXUpDown;
- private System.Windows.Forms.NumericUpDown PosYUpDown;
- private System.Windows.Forms.NumericUpDown PosZUpDown;
- private System.Windows.Forms.NumericUpDown SizeZUpDown;
- private System.Windows.Forms.NumericUpDown SizeYUpDown;
- private System.Windows.Forms.NumericUpDown SizeXUpDown;
- private System.Windows.Forms.NumericUpDown uvYUpDown;
- private System.Windows.Forms.NumericUpDown uvXUpDown;
- private MetroFramework.Controls.MetroCheckBox armorCheckBox;
- private MetroFramework.Controls.MetroCheckBox mirrorCheckBox;
- private System.Windows.Forms.NumericUpDown inflationUpDown;
- }
+ private Controls.BoxEditorControl boxEditorControl1;
+ }
}
\ No newline at end of file
diff --git a/PCK-Studio/Forms/Editor/BoxEditor.cs b/PCK-Studio/Forms/Editor/BoxEditor.cs
index 8af249bf..28e0fbe8 100644
--- a/PCK-Studio/Forms/Editor/BoxEditor.cs
+++ b/PCK-Studio/Forms/Editor/BoxEditor.cs
@@ -1,56 +1,31 @@
-using System;
-using System.Windows.Forms;
-using PckStudio.Internal;
+using OpenTK;
+using PckStudio.Core.Skin;
using PckStudio.Properties;
+using System;
+using System.Windows.Forms;
namespace PckStudio.Forms.Editor
{
public partial class BoxEditor : MetroFramework.Forms.MetroForm
{
- public string Result;
+ private SkinBOX result;
+ public SkinBOX Result => result;
- public BoxEditor(string box, bool hasInflation)
- : this(SkinBOX.FromString(box), hasInflation)
+ public BoxEditor(string formattedBoxString, int xmlVersion)
+ : this(SkinBOX.FromString(formattedBoxString), xmlVersion)
{
}
- public BoxEditor(SkinBOX box, bool hasInflation)
+ public BoxEditor(SkinBOX box, int xmlVersion)
{
InitializeComponent();
-
- if (string.IsNullOrEmpty(box.Type) || !parentComboBox.Items.Contains(box.Type))
- {
- throw new Exception("Failed to parse BOX value");
- }
-
- closeButton.Visible = !Settings.Default.AutoSaveChanges;
-
- inflationUpDown.Enabled = hasInflation;
-
- parentComboBox.SelectedItem = parentComboBox.Items[parentComboBox.Items.IndexOf(box.Type)];
- PosXUpDown.Value = (decimal)box.Pos.X;
- PosYUpDown.Value = (decimal)box.Pos.Y;
- PosZUpDown.Value = (decimal)box.Pos.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;
- armorCheckBox.Checked = box.HideWithArmor;
- mirrorCheckBox.Checked = box.Mirror;
- inflationUpDown.Value = (decimal)box.Scale;
- }
+ boxEditorControl1.SetBOXVersion(xmlVersion);
+ boxEditorControl1.SetBOX(box);
+ }
private void saveButton_Click(object sender, EventArgs e)
{
- Result =
- $"{parentComboBox.SelectedItem} " +
- $"{PosXUpDown.Value} {PosYUpDown.Value} {PosZUpDown.Value} " +
- $"{SizeXUpDown.Value} {SizeYUpDown.Value} {SizeZUpDown.Value} " +
- $"{uvXUpDown.Value} {uvYUpDown.Value} " +
- $"{Convert.ToInt32(armorCheckBox.Checked)} " +
- $"{Convert.ToInt32(mirrorCheckBox.Checked)} " +
- $"{inflationUpDown.Value}";
+ result = boxEditorControl1.GetBOX();
DialogResult = DialogResult.OK;
}
diff --git a/PCK-Studio/Forms/Editor/BoxEditor.resx b/PCK-Studio/Forms/Editor/BoxEditor.resx
index 01c3d1a0..332737e0 100644
--- a/PCK-Studio/Forms/Editor/BoxEditor.resx
+++ b/PCK-Studio/Forms/Editor/BoxEditor.resx
@@ -117,21 +117,6 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- False
-
-
- False
-
-
- False
-
-
- False
-
-
- False
-
17, 17
diff --git a/PCK-Studio/Forms/Editor/COLEditor.Designer.cs b/PCK-Studio/Forms/Editor/COLEditor.Designer.cs
index 30338f00..ef808db5 100644
--- a/PCK-Studio/Forms/Editor/COLEditor.Designer.cs
+++ b/PCK-Studio/Forms/Editor/COLEditor.Designer.cs
@@ -547,7 +547,6 @@ namespace PckStudio.Forms.Editor
this.Name = "COLEditor";
this.Style = MetroFramework.MetroColorStyle.Silver;
this.Theme = MetroFramework.MetroThemeStyle.Dark;
- this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.COLEditor_FormClosing);
this.metroPanel1.ResumeLayout(false);
this.metroPanel1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.blueUpDown)).EndInit();
diff --git a/PCK-Studio/Forms/Editor/COLEditor.cs b/PCK-Studio/Forms/Editor/COLEditor.cs
index 73966b8a..4543f3bc 100644
--- a/PCK-Studio/Forms/Editor/COLEditor.cs
+++ b/PCK-Studio/Forms/Editor/COLEditor.cs
@@ -8,32 +8,39 @@ using MetroFramework.Forms;
using OMI.Formats.Color;
using OMI.Formats.Pck;
using OMI.Workers.Color;
-using PckStudio.Extensions;
+using PckStudio.Core.Extensions;
using PckStudio.Properties;
+using PckStudio.Controls;
+using PckStudio.Interfaces;
+using System.Collections.ObjectModel;
namespace PckStudio.Forms.Editor
{
- public partial class COLEditor : MetroForm
+ public partial class COLEditor : EditorForm
{
ColorContainer _defaultColourfile;
- ColorContainer _colourfile;
string _clipboard_color = "#FFFFFF";
- private readonly PckAsset _asset;
-
List colorCache = new List();
List waterCache = new List();
List underwaterCache = new List();
List fogCache = new List();
- public COLEditor(PckAsset asset)
+ private static readonly ICollection PS4Biomes = new List
+ {
+ "bamboo_jungle",
+ "bamboo_jungle_hills",
+ "mesa_mutated",
+ "mega_spruce_taiga_mutated",
+ "mega_taiga_mutated"
+ };
+
+ public COLEditor(ColorContainer colorContainer, ISaveContext saveContext)
+ : base(colorContainer, saveContext)
{
InitializeComponent();
- saveToolStripMenuItem1.Visible = !Settings.Default.AutoSaveChanges;
-
- _asset = asset;
- _colourfile = asset.GetData(new COLFileReader());
+ saveToolStripMenuItem1.Visible = !saveContext.AutoSave;
TU12ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 0);
TU13ToolStripMenuItem.Click += (sender, e) => SetUpDefaultFile(sender, e, 1);
@@ -111,9 +118,9 @@ namespace PckStudio.Forms.Editor
underwaterTreeView.Nodes.Clear();
fogTreeView.Nodes.Clear();
- ColorContainer temp = targetVersion ? _defaultColourfile : _colourfile;
+ ColorContainer temp = targetVersion ? _defaultColourfile : EditorValue;
- List CurrentEntries = new List();
+ List currentEntries = new List();
colorCache.Clear();
fogCache.Clear();
@@ -123,33 +130,33 @@ namespace PckStudio.Forms.Editor
// fixes the duplicate entry bug
if (targetVersion)
{
- foreach(ColorContainer.Color col in _colourfile.Colors)
+ foreach(ColorContainer.Color col in EditorValue.Colors)
{
if (_defaultColourfile.Colors.Find(c => c.Name == col.Name) == null)
continue;
- CurrentEntries.Add(col.Name);
+ currentEntries.Add(col.Name);
AddEntry(colorTreeView, colorCache, col.Name, col);
}
}
foreach (ColorContainer.Color col in temp.Colors)
{
- ColorContainer.Color entry = _colourfile.Colors.Find(color => color.Name == col.Name);
- if (CurrentEntries.Contains(col.Name))
+ 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();
+ currentEntries.Clear();
// fixes the duplicate entry bug
if (targetVersion)
{
- foreach (ColorContainer.WaterColor col in _colourfile.WaterColors)
+ foreach (ColorContainer.WaterColor col in EditorValue.WaterColors)
{
if (_defaultColourfile.WaterColors.Find(c => c.Name == col.Name) == null)
continue;
- ColorContainer.WaterColor entry = _colourfile.WaterColors.Find(color => color.Name == col.Name);
+ 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);
@@ -159,8 +166,8 @@ namespace PckStudio.Forms.Editor
foreach (ColorContainer.WaterColor col in temp.WaterColors)
{
- ColorContainer.WaterColor entry = _colourfile.WaterColors.Find(color => color.Name == col.Name);
- if (CurrentEntries.Contains(col.Name))
+ 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);
@@ -201,14 +208,14 @@ namespace PckStudio.Forms.Editor
fogTreeView.SelectedNode = null;
var colorEntry = (ColorContainer.Color)colorTreeView.SelectedNode.Tag;
- var color = colorEntry.ColorPallette.ToArgb();
+ Color color = colorEntry.ColorPallette;
SetUpValueChanged(false);
alphaUpDown.Visible = false;
alphaLabel.Visible = false;
- redUpDown.Value = color >> 16 & 0xff;
- greenUpDown.Value = color >> 8 & 0xff;
- blueUpDown.Value = color & 0xff;
- pictureBox1.BackColor = Color.FromArgb(0xff << 24 | color);
+ 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);
}
@@ -226,15 +233,17 @@ namespace PckStudio.Forms.Editor
fogTreeView.SelectedNode = null;
var colorEntry = (ColorContainer.WaterColor)waterTreeView.SelectedNode.Tag;
- int color = colorEntry.SurfaceColor.ToArgb();
+ Color color = colorEntry.SurfaceColor;
SetUpValueChanged(false);
+
+ alphaUpDown.Value = color.A;
+ redUpDown.Value = color.R;
+ greenUpDown.Value = color.G;
+ blueUpDown.Value = color.B;
+
alphaUpDown.Enabled = true;
alphaUpDown.Visible = true;
alphaLabel.Visible = true;
- alphaUpDown.Value = color >> 24 & 0xff;
- redUpDown.Value = color >> 16 & 0xff;
- greenUpDown.Value = color >> 8 & 0xff;
- blueUpDown.Value = color & 0xff;
pictureBox1.BackColor = colorEntry.SurfaceColor;
colorTextbox.Text = ColorTranslator.ToHtml(colorEntry.SurfaceColor).TrimStart('#');
SetUpValueChanged(true);
@@ -253,14 +262,14 @@ namespace PckStudio.Forms.Editor
fogTreeView.SelectedNode = null;
var colorEntry = (ColorContainer.WaterColor)underwaterTreeView.SelectedNode.Tag;
- int color = colorEntry.UnderwaterColor.ToArgb();
+ Color color = colorEntry.UnderwaterColor;
SetUpValueChanged(false);
alphaUpDown.Visible = false;
alphaLabel.Visible = false;
- redUpDown.Value = color >> 16 & 0xff;
- greenUpDown.Value = color >> 8 & 0xff;
- blueUpDown.Value = color & 0xff;
- pictureBox1.BackColor = Color.FromArgb(255, Color.FromArgb(0xff << 24 | color));
+ 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);
}
@@ -278,22 +287,21 @@ namespace PckStudio.Forms.Editor
underwaterTreeView.SelectedNode = null;
var colorEntry = (ColorContainer.WaterColor)fogTreeView.SelectedNode.Tag;
- int color = colorEntry.FogColor.ToArgb();
+ Color color = colorEntry.FogColor;
SetUpValueChanged(false);
alphaUpDown.Visible = false;
alphaLabel.Visible = false;
- redUpDown.Value = color >> 16 & 0xff;
- greenUpDown.Value = color >> 8 & 0xff;
- blueUpDown.Value = color & 0xff;
- pictureBox1.BackColor = Color.FromArgb(255, Color.FromArgb(0xff << 24 | color));
+ 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)
{
- _asset.SetData(new COLFileWriter(_colourfile));
-
+ Save();
DialogResult = DialogResult.OK;
}
@@ -485,14 +493,14 @@ namespace PckStudio.Forms.Editor
}
else
{
- ColorContainer.WaterColor WaterEntry = _defaultColourfile.WaterColors.Find(color => color.Name == node.Text);
+ ColorContainer.WaterColor waterEntry = _defaultColourfile.WaterColors.Find(color => color.Name == node.Text);
- if (WaterEntry == null)
+ if (waterEntry == null)
return;
color =
- tab == waterTab ? WaterEntry.SurfaceColor :
- tab == underwaterTab ? WaterEntry.UnderwaterColor : WaterEntry.FogColor;
+ tab == waterTab ? waterEntry.SurfaceColor :
+ tab == underwaterTab ? waterEntry.UnderwaterColor : waterEntry.FogColor;
if (tab == waterTab)
{
@@ -509,7 +517,7 @@ namespace PckStudio.Forms.Editor
private void metroTextBox1_TextChanged(object sender, EventArgs e)
{
- // Some code in this function is modified code from this StackOverflow answer - MattNL
+ // Some code in this function is modified code from this StackOverflow answer - MayNL
//https://stackoverflow.com/questions/8260322/filter-a-treeview-with-a-textbox-in-a-c-sharp-winforms-app
//blocks repainting tree until all objects loaded
@@ -523,52 +531,52 @@ namespace PckStudio.Forms.Editor
fogTreeView.Nodes.Clear();
if (!string.IsNullOrEmpty(metroTextBox1.Text))
{
- foreach (TreeNode _node in colorCache)
+ foreach (TreeNode node in colorCache)
{
- if (_node.Text.ToLower().Contains(metroTextBox1.Text.ToLower()))
+ if (node.Text.ToLower().Contains(metroTextBox1.Text.ToLower()))
{
- colorTreeView.Nodes.Add((TreeNode)_node.Clone());
+ colorTreeView.Nodes.Add((TreeNode)node.Clone());
}
}
- foreach (TreeNode _node in waterCache)
+ foreach (TreeNode node in waterCache)
{
- if (_node.Text.ToLower().Contains(metroTextBox1.Text.ToLower()))
+ if (node.Text.ToLower().Contains(metroTextBox1.Text.ToLower()))
{
- waterTreeView.Nodes.Add((TreeNode)_node.Clone());
+ waterTreeView.Nodes.Add((TreeNode)node.Clone());
}
}
- foreach (TreeNode _node in underwaterCache)
+ foreach (TreeNode node in underwaterCache)
{
- if (_node.Text.ToLower().Contains(metroTextBox1.Text.ToLower()))
+ if (node.Text.ToLower().Contains(metroTextBox1.Text.ToLower()))
{
- underwaterTreeView.Nodes.Add((TreeNode)_node.Clone());
+ underwaterTreeView.Nodes.Add((TreeNode)node.Clone());
}
}
- foreach (TreeNode _node in fogCache)
+ foreach (TreeNode node in fogCache)
{
- if (_node.Text.ToLower().Contains(metroTextBox1.Text.ToLower()))
+ if (node.Text.ToLower().Contains(metroTextBox1.Text.ToLower()))
{
- fogTreeView.Nodes.Add((TreeNode)_node.Clone());
+ fogTreeView.Nodes.Add((TreeNode)node.Clone());
}
}
}
else
{
- foreach (TreeNode _node in colorCache)
+ foreach (TreeNode node in colorCache)
{
- colorTreeView.Nodes.Add((TreeNode)_node.Clone());
+ colorTreeView.Nodes.Add((TreeNode)node.Clone());
}
- foreach (TreeNode _node in waterCache)
+ foreach (TreeNode node in waterCache)
{
- waterTreeView.Nodes.Add((TreeNode)_node.Clone());
+ waterTreeView.Nodes.Add((TreeNode)node.Clone());
}
- foreach (TreeNode _node in underwaterCache)
+ foreach (TreeNode node in underwaterCache)
{
- underwaterTreeView.Nodes.Add((TreeNode)_node.Clone());
+ underwaterTreeView.Nodes.Add((TreeNode)node.Clone());
}
- foreach (TreeNode _node in fogCache)
+ foreach (TreeNode node in fogCache)
{
- fogTreeView.Nodes.Add((TreeNode)_node.Clone());
+ fogTreeView.Nodes.Add((TreeNode)node.Clone());
}
}
//enables redrawing tree after all objects have been added
@@ -588,14 +596,6 @@ namespace PckStudio.Forms.Editor
colorTextbox.Text = _clipboard_color;
}
- private void COLEditor_FormClosing(object sender, FormClosingEventArgs e)
- {
- if (Settings.Default.AutoSaveChanges)
- {
- saveToolStripMenuItem1_Click(sender, EventArgs.Empty);
- }
- }
-
private void colorTextbox_KeyPress(object sender, KeyPressEventArgs e)
{
string hexCheck = "0123456789abcdefABCDEF\b";
@@ -605,21 +605,12 @@ namespace PckStudio.Forms.Editor
private void stripPS4BiomesToolStripMenuItem_Click(object sender, EventArgs e)
{
- if(_colourfile.WaterColors.Count > 0)
+ if(EditorValue.WaterColors.Count > 0)
{
- List PS4Biomes = new List
- {
- "bamboo_jungle",
- "bamboo_jungle_hills",
- "mesa_mutated",
- "mega_spruce_taiga_mutated",
- "mega_taiga_mutated"
- };
-
- foreach (ColorContainer.WaterColor col in _colourfile.WaterColors.ToList())
+ foreach (ColorContainer.WaterColor col in EditorValue.WaterColors.ToList())
{
if (PS4Biomes.Contains(col.Name))
- _colourfile.WaterColors.Remove(col);
+ EditorValue.WaterColors.Remove(col);
}
SetUpTable(false);
@@ -640,12 +631,12 @@ namespace PckStudio.Forms.Editor
entry.Name = prompt.NewText;
entry.ColorPallette = Color.FromArgb(0xFFFFFF);
- if(_colourfile.Colors.Find(c => c.Name == entry.Name) != null)
+ if(EditorValue.Colors.Find(c => c.Name == entry.Name) != null)
{
MessageBox.Show(this, $"\"{entry.Name}\" already exists in this color table", "Color not added");
}
- _colourfile.Colors.Add(entry);
+ EditorValue.Colors.Add(entry);
AddEntry(colorTreeView, colorCache, entry.Name, entry);
}
}
@@ -659,7 +650,7 @@ namespace PckStudio.Forms.Editor
&& entry != null
&& entry.Tag is ColorContainer.Color color)
{
- _colourfile.Colors.Remove(color);
+ EditorValue.Colors.Remove(color);
RemoveEntry(entry, colorCache);
}
}
diff --git a/PCK-Studio/Forms/Editor/CustomSkinEditor.Designer.cs b/PCK-Studio/Forms/Editor/CustomSkinEditor.Designer.cs
new file mode 100644
index 00000000..05b63c69
--- /dev/null
+++ b/PCK-Studio/Forms/Editor/CustomSkinEditor.Designer.cs
@@ -0,0 +1,416 @@
+namespace PckStudio.Forms.Editor
+{
+ partial class CustomSkinEditor
+ {
+ ///
+ /// 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(CustomSkinEditor));
+ this.importTextureButton = new MetroFramework.Controls.MetroButton();
+ this.exportTextureButton = new MetroFramework.Controls.MetroButton();
+ this.skinPartTabContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
+ this.createToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.cloneToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.deleteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.generateUvTextureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.buttonDone = new MetroFramework.Controls.MetroButton();
+ this.importSkinButton = new MetroFramework.Controls.MetroButton();
+ this.exportSkinButton = new MetroFramework.Controls.MetroButton();
+ this.outlineColorButton = new MetroFramework.Controls.MetroButton();
+ this.generateTextureCheckBox = new MetroFramework.Controls.MetroCheckBox();
+ this.showArmorCheckbox = new MetroFramework.Controls.MetroCheckBox();
+ this.skinPartListBox = new System.Windows.Forms.ListBox();
+ this.captureScreenshotButton = new MetroFramework.Controls.MetroButton();
+ this.showToolsCheckBox = new MetroFramework.Controls.MetroCheckBox();
+ this.skinNameLabel = new MetroFramework.Controls.MetroLabel();
+ this.metroTabControl1 = new MetroFramework.Controls.MetroTabControl();
+ this.skinPartsTabPage = new System.Windows.Forms.TabPage();
+ this.skinOffsetsTabPage = new System.Windows.Forms.TabPage();
+ this.offsetListBox = new System.Windows.Forms.ListBox();
+ this.offsetTabContextMenu = new MetroFramework.Controls.MetroContextMenu(this.components);
+ this.addOffsetToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.removeOffsetToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.renderer3D1 = new PckStudio.Rendering.SkinRenderer();
+ this.uvPictureBox = new PckStudio.ToolboxItems.InterpolationPictureBox();
+ this.centerSelectionCheckbox = new MetroFramework.Controls.MetroCheckBox();
+ this.textureSizeLabel = new System.Windows.Forms.Label();
+ this.renderSettingsButton = new MetroFramework.Controls.MetroButton();
+ this.exportTemplateButton = new MetroFramework.Controls.MetroButton();
+ this.animEditorButton = new MetroFramework.Controls.MetroButton();
+ this.boxEditorControl1 = new PckStudio.Controls.BoxEditorControl();
+ this.skinPartTabContextMenu.SuspendLayout();
+ this.metroTabControl1.SuspendLayout();
+ this.skinPartsTabPage.SuspendLayout();
+ this.skinOffsetsTabPage.SuspendLayout();
+ this.offsetTabContextMenu.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.uvPictureBox)).BeginInit();
+ this.SuspendLayout();
+ //
+ // importTextureButton
+ //
+ resources.ApplyResources(this.importTextureButton, "importTextureButton");
+ this.importTextureButton.ForeColor = System.Drawing.Color.White;
+ this.importTextureButton.Name = "importTextureButton";
+ this.importTextureButton.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.importTextureButton.UseSelectable = true;
+ this.importTextureButton.Click += new System.EventHandler(this.importTextureButton_Click);
+ //
+ // exportTextureButton
+ //
+ resources.ApplyResources(this.exportTextureButton, "exportTextureButton");
+ this.exportTextureButton.ForeColor = System.Drawing.Color.White;
+ this.exportTextureButton.Name = "exportTextureButton";
+ this.exportTextureButton.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.exportTextureButton.UseSelectable = true;
+ this.exportTextureButton.Click += new System.EventHandler(this.exportTextureButton_Click);
+ //
+ // skinPartTabContextMenu
+ //
+ this.skinPartTabContextMenu.ImageScalingSize = new System.Drawing.Size(20, 20);
+ this.skinPartTabContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.createToolStripMenuItem,
+ this.cloneToolStripMenuItem,
+ this.deleteToolStripMenuItem,
+ this.generateUvTextureToolStripMenuItem});
+ this.skinPartTabContextMenu.Name = "contextMenuStrip1";
+ resources.ApplyResources(this.skinPartTabContextMenu, "skinPartTabContextMenu");
+ //
+ // createToolStripMenuItem
+ //
+ resources.ApplyResources(this.createToolStripMenuItem, "createToolStripMenuItem");
+ this.createToolStripMenuItem.Name = "createToolStripMenuItem";
+ this.createToolStripMenuItem.Click += new System.EventHandler(this.createToolStripMenuItem_Click);
+ //
+ // cloneToolStripMenuItem
+ //
+ resources.ApplyResources(this.cloneToolStripMenuItem, "cloneToolStripMenuItem");
+ this.cloneToolStripMenuItem.Name = "cloneToolStripMenuItem";
+ this.cloneToolStripMenuItem.Click += new System.EventHandler(this.cloneToolStripMenuItem_Click);
+ //
+ // deleteToolStripMenuItem
+ //
+ resources.ApplyResources(this.deleteToolStripMenuItem, "deleteToolStripMenuItem");
+ this.deleteToolStripMenuItem.Name = "deleteToolStripMenuItem";
+ this.deleteToolStripMenuItem.Click += new System.EventHandler(this.deleteToolStripMenuItem_Click);
+ //
+ // generateUvTextureToolStripMenuItem
+ //
+ resources.ApplyResources(this.generateUvTextureToolStripMenuItem, "generateUvTextureToolStripMenuItem");
+ this.generateUvTextureToolStripMenuItem.Name = "generateUvTextureToolStripMenuItem";
+ this.generateUvTextureToolStripMenuItem.Click += new System.EventHandler(this.generateUvTextureToolStripMenuItem_Click);
+ //
+ // buttonDone
+ //
+ resources.ApplyResources(this.buttonDone, "buttonDone");
+ this.buttonDone.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.buttonDone.ForeColor = System.Drawing.Color.White;
+ this.buttonDone.Name = "buttonDone";
+ this.buttonDone.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.buttonDone.UseSelectable = true;
+ this.buttonDone.Click += new System.EventHandler(this.buttonDone_Click);
+ //
+ // importSkinButton
+ //
+ resources.ApplyResources(this.importSkinButton, "importSkinButton");
+ this.importSkinButton.ForeColor = System.Drawing.Color.White;
+ this.importSkinButton.Name = "importSkinButton";
+ this.importSkinButton.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.importSkinButton.UseSelectable = true;
+ this.importSkinButton.Click += new System.EventHandler(this.importSkinButton_Click);
+ //
+ // exportSkinButton
+ //
+ resources.ApplyResources(this.exportSkinButton, "exportSkinButton");
+ this.exportSkinButton.ForeColor = System.Drawing.Color.White;
+ this.exportSkinButton.Name = "exportSkinButton";
+ this.exportSkinButton.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.exportSkinButton.UseSelectable = true;
+ this.exportSkinButton.Click += new System.EventHandler(this.exportSkinButton_Click);
+ //
+ // outlineColorButton
+ //
+ resources.ApplyResources(this.outlineColorButton, "outlineColorButton");
+ this.outlineColorButton.ForeColor = System.Drawing.Color.White;
+ this.outlineColorButton.Name = "outlineColorButton";
+ this.outlineColorButton.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.outlineColorButton.UseSelectable = true;
+ this.outlineColorButton.Click += new System.EventHandler(this.outlineColorButton_Click);
+ //
+ // generateTextureCheckBox
+ //
+ resources.ApplyResources(this.generateTextureCheckBox, "generateTextureCheckBox");
+ this.generateTextureCheckBox.Name = "generateTextureCheckBox";
+ this.generateTextureCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.generateTextureCheckBox.UseSelectable = true;
+ //
+ // showArmorCheckbox
+ //
+ resources.ApplyResources(this.showArmorCheckbox, "showArmorCheckbox");
+ this.showArmorCheckbox.Name = "showArmorCheckbox";
+ this.showArmorCheckbox.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.showArmorCheckbox.UseSelectable = true;
+ this.showArmorCheckbox.CheckedChanged += new System.EventHandler(this.showArmorCheckbox_CheckedChanged);
+ //
+ // skinPartListBox
+ //
+ this.skinPartListBox.BorderStyle = System.Windows.Forms.BorderStyle.None;
+ this.skinPartListBox.ContextMenuStrip = this.skinPartTabContextMenu;
+ resources.ApplyResources(this.skinPartListBox, "skinPartListBox");
+ this.skinPartListBox.FormattingEnabled = true;
+ this.skinPartListBox.Name = "skinPartListBox";
+ this.skinPartListBox.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended;
+ this.skinPartListBox.Tag = "";
+ this.skinPartListBox.MouseClick += new System.Windows.Forms.MouseEventHandler(this.skinPartListBox_MouseClick);
+ this.skinPartListBox.SelectedIndexChanged += new System.EventHandler(this.skinPartListBox_SelectedIndexChanged);
+ this.skinPartListBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.skinPartListBox_KeyUp);
+ //
+ // captureScreenshotButton
+ //
+ resources.ApplyResources(this.captureScreenshotButton, "captureScreenshotButton");
+ this.captureScreenshotButton.ForeColor = System.Drawing.Color.White;
+ this.captureScreenshotButton.Name = "captureScreenshotButton";
+ this.captureScreenshotButton.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.captureScreenshotButton.UseSelectable = true;
+ this.captureScreenshotButton.Click += new System.EventHandler(this.captureScreenshotButton_Click);
+ //
+ // showToolsCheckBox
+ //
+ resources.ApplyResources(this.showToolsCheckBox, "showToolsCheckBox");
+ this.showToolsCheckBox.Name = "showToolsCheckBox";
+ this.showToolsCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.showToolsCheckBox.UseSelectable = true;
+ //
+ // skinNameLabel
+ //
+ resources.ApplyResources(this.skinNameLabel, "skinNameLabel");
+ this.skinNameLabel.Name = "skinNameLabel";
+ this.skinNameLabel.Theme = MetroFramework.MetroThemeStyle.Dark;
+ //
+ // metroTabControl1
+ //
+ resources.ApplyResources(this.metroTabControl1, "metroTabControl1");
+ this.metroTabControl1.Controls.Add(this.skinPartsTabPage);
+ this.metroTabControl1.Controls.Add(this.skinOffsetsTabPage);
+ this.metroTabControl1.Multiline = true;
+ this.metroTabControl1.Name = "metroTabControl1";
+ this.metroTabControl1.SelectedIndex = 0;
+ this.metroTabControl1.Style = MetroFramework.MetroColorStyle.Pink;
+ this.metroTabControl1.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.metroTabControl1.UseSelectable = true;
+ //
+ // skinPartsTabPage
+ //
+ this.skinPartsTabPage.Controls.Add(this.skinPartListBox);
+ resources.ApplyResources(this.skinPartsTabPage, "skinPartsTabPage");
+ this.skinPartsTabPage.Name = "skinPartsTabPage";
+ //
+ // skinOffsetsTabPage
+ //
+ this.skinOffsetsTabPage.Controls.Add(this.offsetListBox);
+ resources.ApplyResources(this.skinOffsetsTabPage, "skinOffsetsTabPage");
+ this.skinOffsetsTabPage.Name = "skinOffsetsTabPage";
+ //
+ // offsetListBox
+ //
+ this.offsetListBox.ContextMenuStrip = this.offsetTabContextMenu;
+ resources.ApplyResources(this.offsetListBox, "offsetListBox");
+ this.offsetListBox.FormattingEnabled = true;
+ this.offsetListBox.Name = "offsetListBox";
+ this.offsetListBox.DoubleClick += new System.EventHandler(this.offsetListBox_DoubleClick);
+ //
+ // offsetTabContextMenu
+ //
+ this.offsetTabContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.addOffsetToolStripMenuItem,
+ this.removeOffsetToolStripMenuItem});
+ this.offsetTabContextMenu.Name = "offsetTabContextMenu";
+ resources.ApplyResources(this.offsetTabContextMenu, "offsetTabContextMenu");
+ this.offsetTabContextMenu.Theme = MetroFramework.MetroThemeStyle.Dark;
+ //
+ // addOffsetToolStripMenuItem
+ //
+ this.addOffsetToolStripMenuItem.Name = "addOffsetToolStripMenuItem";
+ resources.ApplyResources(this.addOffsetToolStripMenuItem, "addOffsetToolStripMenuItem");
+ this.addOffsetToolStripMenuItem.Click += new System.EventHandler(this.addOffsetToolStripMenuItem_Click);
+ //
+ // removeOffsetToolStripMenuItem
+ //
+ this.removeOffsetToolStripMenuItem.Name = "removeOffsetToolStripMenuItem";
+ resources.ApplyResources(this.removeOffsetToolStripMenuItem, "removeOffsetToolStripMenuItem");
+ this.removeOffsetToolStripMenuItem.Click += new System.EventHandler(this.removeOffsetToolStripMenuItem_Click);
+ //
+ // renderer3D1
+ //
+ resources.ApplyResources(this.renderer3D1, "renderer3D1");
+ this.renderer3D1.Animate = true;
+ this.renderer3D1.BackColor = System.Drawing.Color.DimGray;
+ this.renderer3D1.CapeTexture = null;
+ this.renderer3D1.CenterOnSelect = false;
+ this.renderer3D1.GuideLineColor = System.Drawing.Color.Empty;
+ this.renderer3D1.HighlightlingColor = System.Drawing.Color.Aqua;
+ this.renderer3D1.MouseSensetivity = 0.01F;
+ this.renderer3D1.Name = "renderer3D1";
+ this.renderer3D1.RefreshRate = 60;
+ this.renderer3D1.SelectedIndex = -1;
+ this.renderer3D1.SelectedIndices = new int[] {
+ -1};
+ this.renderer3D1.ShowArmor = false;
+ this.renderer3D1.ShowBoundingBox = false;
+ this.renderer3D1.ShowGuideLines = false;
+ this.renderer3D1.Texture = null;
+ this.renderer3D1.VSync = true;
+ this.renderer3D1.TextureChanging += new System.EventHandler(this.renderer3D1_TextureChanging);
+ //
+ // uvPictureBox
+ //
+ resources.ApplyResources(this.uvPictureBox, "uvPictureBox");
+ this.uvPictureBox.BackgroundInterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
+ this.uvPictureBox.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
+ this.uvPictureBox.Name = "uvPictureBox";
+ this.uvPictureBox.TabStop = false;
+ //
+ // centerSelectionCheckbox
+ //
+ resources.ApplyResources(this.centerSelectionCheckbox, "centerSelectionCheckbox");
+ this.centerSelectionCheckbox.Name = "centerSelectionCheckbox";
+ this.centerSelectionCheckbox.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.centerSelectionCheckbox.UseSelectable = true;
+ this.centerSelectionCheckbox.CheckedChanged += new System.EventHandler(this.centerSelectionCheckbox_CheckedChanged);
+ //
+ // textureSizeLabel
+ //
+ resources.ApplyResources(this.textureSizeLabel, "textureSizeLabel");
+ this.textureSizeLabel.ForeColor = System.Drawing.Color.White;
+ this.textureSizeLabel.Name = "textureSizeLabel";
+ //
+ // renderSettingsButton
+ //
+ resources.ApplyResources(this.renderSettingsButton, "renderSettingsButton");
+ this.renderSettingsButton.Name = "renderSettingsButton";
+ this.renderSettingsButton.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.renderSettingsButton.UseSelectable = true;
+ this.renderSettingsButton.Click += new System.EventHandler(this.renderSettingsButton_Click);
+ //
+ // exportTemplateButton
+ //
+ resources.ApplyResources(this.exportTemplateButton, "exportTemplateButton");
+ this.exportTemplateButton.ForeColor = System.Drawing.Color.White;
+ this.exportTemplateButton.Name = "exportTemplateButton";
+ this.exportTemplateButton.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.exportTemplateButton.UseSelectable = true;
+ this.exportTemplateButton.Click += new System.EventHandler(this.exportTemplateButton_Click);
+ //
+ // animEditorButton
+ //
+ resources.ApplyResources(this.animEditorButton, "animEditorButton");
+ this.animEditorButton.Name = "animEditorButton";
+ this.animEditorButton.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.animEditorButton.UseSelectable = true;
+ this.animEditorButton.Click += new System.EventHandler(this.animEditorButton_Click);
+ //
+ // boxEditorControl1
+ //
+ this.boxEditorControl1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(18)))), ((int)(((byte)(18)))), ((int)(((byte)(18)))));
+ this.boxEditorControl1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ resources.ApplyResources(this.boxEditorControl1, "boxEditorControl1");
+ this.boxEditorControl1.Name = "boxEditorControl1";
+ this.boxEditorControl1.BoxChanged += new System.EventHandler(this.boxEditorControl1_BoxChanged);
+ //
+ // CustomSkinEditor
+ //
+ resources.ApplyResources(this, "$this");
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.metroTabControl1);
+ this.Controls.Add(this.boxEditorControl1);
+ this.Controls.Add(this.exportTextureButton);
+ this.Controls.Add(this.importTextureButton);
+ this.Controls.Add(this.textureSizeLabel);
+ this.Controls.Add(this.showToolsCheckBox);
+ this.Controls.Add(this.centerSelectionCheckbox);
+ this.Controls.Add(this.showArmorCheckbox);
+ this.Controls.Add(this.generateTextureCheckBox);
+ this.Controls.Add(this.outlineColorButton);
+ this.Controls.Add(this.uvPictureBox);
+ this.Controls.Add(this.animEditorButton);
+ this.Controls.Add(this.exportTemplateButton);
+ this.Controls.Add(this.renderSettingsButton);
+ this.Controls.Add(this.skinNameLabel);
+ this.Controls.Add(this.captureScreenshotButton);
+ this.Controls.Add(this.renderer3D1);
+ this.Controls.Add(this.exportSkinButton);
+ this.Controls.Add(this.importSkinButton);
+ this.Controls.Add(this.buttonDone);
+ this.Name = "CustomSkinEditor";
+ this.Style = MetroFramework.MetroColorStyle.Silver;
+ this.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.CustomSkinEditor_FormClosing);
+ this.skinPartTabContextMenu.ResumeLayout(false);
+ this.metroTabControl1.ResumeLayout(false);
+ this.skinPartsTabPage.ResumeLayout(false);
+ this.skinOffsetsTabPage.ResumeLayout(false);
+ this.offsetTabContextMenu.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.uvPictureBox)).EndInit();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+ private System.Windows.Forms.ContextMenuStrip skinPartTabContextMenu;
+ private System.Windows.Forms.ToolStripMenuItem createToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem cloneToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem deleteToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem generateUvTextureToolStripMenuItem;
+ private MetroFramework.Controls.MetroButton buttonDone;
+ private MetroFramework.Controls.MetroButton outlineColorButton;
+ private MetroFramework.Controls.MetroButton exportSkinButton;
+ private MetroFramework.Controls.MetroButton importSkinButton;
+ private PckStudio.ToolboxItems.InterpolationPictureBox uvPictureBox;
+ private MetroFramework.Controls.MetroButton importTextureButton;
+ private MetroFramework.Controls.MetroButton exportTextureButton;
+ private MetroFramework.Controls.MetroCheckBox generateTextureCheckBox;
+ private MetroFramework.Controls.MetroCheckBox showArmorCheckbox;
+ private Rendering.SkinRenderer renderer3D1;
+ private System.Windows.Forms.ListBox skinPartListBox;
+ private MetroFramework.Controls.MetroButton captureScreenshotButton;
+ private MetroFramework.Controls.MetroCheckBox showToolsCheckBox;
+ private MetroFramework.Controls.MetroLabel skinNameLabel;
+ private MetroFramework.Controls.MetroTabControl metroTabControl1;
+ private System.Windows.Forms.TabPage skinPartsTabPage;
+ private System.Windows.Forms.TabPage skinOffsetsTabPage;
+ private System.Windows.Forms.ListBox offsetListBox;
+ private MetroFramework.Controls.MetroContextMenu offsetTabContextMenu;
+ private System.Windows.Forms.ToolStripMenuItem addOffsetToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem removeOffsetToolStripMenuItem;
+ private MetroFramework.Controls.MetroCheckBox centerSelectionCheckbox;
+ private System.Windows.Forms.Label textureSizeLabel;
+ private MetroFramework.Controls.MetroButton renderSettingsButton;
+ private MetroFramework.Controls.MetroButton exportTemplateButton;
+ private MetroFramework.Controls.MetroButton animEditorButton;
+ private Controls.BoxEditorControl boxEditorControl1;
+ }
+}
\ No newline at end of file
diff --git a/PCK-Studio/Forms/Editor/CustomSkinEditor.cs b/PCK-Studio/Forms/Editor/CustomSkinEditor.cs
new file mode 100644
index 00000000..1712aa9d
--- /dev/null
+++ b/PCK-Studio/Forms/Editor/CustomSkinEditor.cs
@@ -0,0 +1,459 @@
+using System;
+using System.Linq;
+using System.Text;
+using System.Drawing;
+using System.Diagnostics;
+using System.Windows.Forms;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Collections.Generic;
+
+using PckStudio.Controls;
+using PckStudio.Properties;
+using PckStudio.Forms.Additional_Popups;
+
+using PckStudio.Core.Skin;
+using PckStudio.Core.Extensions;
+using PckStudio.Interfaces;
+using PckStudio.ModelSupport;
+using PckStudio.ModelSupport.Extension;
+
+namespace PckStudio.Forms.Editor
+{
+ public partial class CustomSkinEditor : EditorForm
+ {
+ private const float cOffsetMaximum = 100_000f;
+ private Random _rng;
+ private bool _inflateOverlayParts;
+ private int _xmlVersion;
+
+ private BindingSource _skinPartListBindingSource;
+ private BindingSource _skinOffsetListBindingSource;
+
+ private Core.App.SettingsManager _settingsManager;
+
+ private static GraphicsConfig _graphicsConfig = new GraphicsConfig()
+ {
+ InterpolationMode = InterpolationMode.NearestNeighbor,
+ PixelOffsetMode = PixelOffsetMode.HighQuality,
+ };
+
+ private CustomSkinEditor() : this(null, null, 0)
+ { }
+
+ public CustomSkinEditor(Skin skin, ISaveContext saveContext, int xmlVersion)
+ : base(skin, saveContext)
+ {
+ InitializeComponent();
+ InitializeRenderSettings();
+ _rng = new Random();
+ _skinPartListBindingSource = new BindingSource(renderer3D1.ModelData, null);
+ skinPartListBox.DataSource = _skinPartListBindingSource;
+ skinPartListBox.DisplayMember = "Type";
+ _xmlVersion = xmlVersion;
+ boxEditorControl1.SetBOXVersion(xmlVersion);
+ _inflateOverlayParts = _xmlVersion > 0;
+ }
+
+ private void InitializeRenderSettings()
+ {
+ _settingsManager = Core.App.SettingsManager.CreateSettings();
+ _settingsManager.AddSetting("shouldAnimate" , true , "Animate skin" , state => renderer3D1.Animate = state);
+ _settingsManager.AddSetting("lockMouse" , true , "Lock mouse when paning/rotating", state => renderer3D1.LockMousePosition = state);
+ _settingsManager.AddSetting("showGuidelines" , false, "Show guidelines" , state => renderer3D1.ShowGuideLines = state);
+ _settingsManager.AddSetting("showBoundingBox", false, "Show Bounding Box" , state => renderer3D1.ShowBoundingBox = state);
+ }
+
+ protected override void OnLoad(EventArgs e)
+ {
+ base.OnLoad(e);
+ renderer3D1.Initialize(_inflateOverlayParts);
+ renderer3D1.GuideLineColor = Color.LightCoral;
+ skinNameLabel.Text = EditorValue.MetaData.Name;
+ if (EditorValue.HasCape)
+ renderer3D1.CapeTexture = EditorValue.CapeTexture;
+ LoadModelData();
+ }
+
+ protected override bool ProcessDialogKey(Keys keyData)
+ {
+ if (keyData == Keys.A)
+ {
+ using var animeditor = new ANIMEditor(EditorValue.Anim);
+ if (animeditor.ShowDialog() == DialogResult.OK)
+ {
+ renderer3D1.ANIM = EditorValue.Anim = animeditor.ResultAnim;
+ skinPartListBox_SelectedIndexChanged(this, EventArgs.Empty);
+ }
+ return true;
+ }
+ return base.ProcessDialogKey(keyData);
+ }
+
+ private void LoadModelData()
+ {
+ SkinModel modelInfo = EditorValue.Model;
+
+ List boxProperties = modelInfo.AdditionalBoxes;
+ List offsetProperties = modelInfo.PartOffsets;
+
+ renderer3D1.ANIM = EditorValue.Anim;
+
+ renderer3D1.ModelData.Clear();
+ foreach (SkinBOX box in boxProperties)
+ {
+ renderer3D1.ModelData.Add(box);
+ }
+ renderer3D1.ResetOffsets();
+ foreach (SkinPartOffset offset in offsetProperties)
+ {
+ renderer3D1.SetPartOffset(offset);
+ }
+
+ if (EditorValue.Texture is not null)
+ {
+ renderer3D1.Texture = EditorValue.Texture;
+ }
+
+ if (EditorValue.Texture is null && renderer3D1.Texture is not null)
+ {
+ EditorValue.Texture = renderer3D1.Texture;
+ }
+
+ _skinOffsetListBindingSource = new BindingSource(renderer3D1.GetOffsets().ToArray(), null);
+ offsetListBox.DataSource = _skinOffsetListBindingSource;
+ offsetListBox.DisplayMember = "Type";
+ offsetListBox.ValueMember = "Value";
+
+ _skinPartListBindingSource.ResetBindings(false);
+ _skinOffsetListBindingSource.ResetBindings(false);
+ }
+
+ private void GenerateUVTextureMap(SkinBOX skinBox)
+ {
+ if (EditorValue?.Texture is null)
+ {
+ Trace.TraceWarning($"[{nameof(CustomSkinEditor)}@{nameof(GenerateUVTextureMap)}] Failed to generate uv for {skinBox}. Reason: Model.Texture was null");
+ return;
+ }
+ using (Graphics graphics = Graphics.FromImage(EditorValue.Texture))
+ {
+ graphics.ApplyConfig(_graphicsConfig);
+ int argb = _rng.Next(unchecked((int)0xFF000000), -1);
+ var color = Color.FromArgb(argb);
+ Brush brush = new SolidBrush(color);
+ graphics.FillPath(brush, skinBox.GetUVGraphicsPath());
+ }
+ renderer3D1.Texture = EditorValue.Texture;
+ }
+
+ private void createToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ SkinBOX newBox = SkinBOX.DefaultHead;
+ renderer3D1.ModelData.Add(newBox);
+ EditorValue.Model.AdditionalBoxes.Add(newBox);
+ _skinPartListBindingSource.ResetBindings(false);
+ if (generateTextureCheckBox.Checked)
+ GenerateUVTextureMap(newBox);
+ }
+
+ private void exportTextureButton_Click(object sender, EventArgs e)
+ {
+ if (EditorValue?.Texture is null)
+ {
+ Trace.TraceWarning($"[{nameof(CustomSkinEditor)}@{nameof(exportTextureButton_Click)}] Failed to export texture. Reason: skin.Model.Texture was null");
+ return;
+ }
+ using SaveFileDialog saveFileDialog = new SaveFileDialog();
+ saveFileDialog.Filter = "PNG Image Files | *.png";
+ if (saveFileDialog.ShowDialog() == DialogResult.OK)
+ {
+ EditorValue.Texture.Save(saveFileDialog.FileName, ImageFormat.Png);
+ }
+ }
+
+ private void importTextureButton_Click(object sender, EventArgs e)
+ {
+ OpenFileDialog openFileDialog = new OpenFileDialog();
+ openFileDialog.Filter = "PNG Image Files | *.png";
+ openFileDialog.Title = "Select Skin Texture";
+
+ if (openFileDialog.ShowDialog() == DialogResult.OK)
+ {
+ generateTextureCheckBox.Checked = false;
+ renderer3D1.Texture = Image.FromFile(openFileDialog.FileName).ReleaseFromFile();
+ }
+ }
+
+ private void buttonDone_Click(object sender, EventArgs e)
+ {
+ EditorValue.Model.AdditionalBoxes.Clear();
+ EditorValue.Model.AdditionalBoxes.AddRange(renderer3D1.ModelData);
+ EditorValue.Model.PartOffsets.Clear();
+ EditorValue.Model.PartOffsets.AddRange(renderer3D1.GetOffsets());
+ // just in case they're not the same instance
+ EditorValue.Anim = renderer3D1.ANIM;
+ DialogResult = DialogResult.OK;
+ Save();
+ }
+
+ private void exportSkinButton_Click(object sender, EventArgs e)
+ {
+ SaveFileDialog saveFileDialog = new SaveFileDialog();
+ saveFileDialog.Title = "Save Model File";
+ saveFileDialog.Filter = SkinModelImporter.Default.SupportedModelFileFormatsFilter;
+ saveFileDialog.FileName = EditorValue.MetaData.Name.TrimEnd(new char[] { '\n', '\r' }).Replace(' ', '_');
+ if (saveFileDialog.ShowDialog() == DialogResult.OK)
+ SkinModelImporter.Default.Export(saveFileDialog.FileName, EditorValue.GetModelInfo());
+ }
+
+ private void importSkinButton_Click(object sender, EventArgs e)
+ {
+ OpenFileDialog openFileDialog = new OpenFileDialog();
+ openFileDialog.Title = "Select Model File";
+ openFileDialog.Filter = SkinModelImporter.Default.SupportedModelFileFormatsFilter;
+ if (MessageBox.Show("Import custom model project file? Your current work will be lost!", "", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1) == DialogResult.Yes && openFileDialog.ShowDialog() == DialogResult.OK)
+ {
+ SkinModelInfo modelInfo = SkinModelImporter.Default.Import(openFileDialog.FileName);
+ if (modelInfo is not null)
+ {
+ EditorValue.SetModelInfo(modelInfo);
+ LoadModelData();
+ }
+ }
+ }
+
+ private void cloneToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ if (skinPartListBox.SelectedItem is SkinBOX box)
+ {
+ SkinBOX clone = box;
+ renderer3D1.ModelData.Add(clone);
+ EditorValue.Model.AdditionalBoxes.Add(clone);
+ _skinPartListBindingSource.ResetBindings(false);
+ }
+ }
+
+ private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ if (skinPartListBox.SelectedItem is SkinBOX box)
+ {
+ renderer3D1.ModelData.Remove(box);
+ EditorValue.Model.AdditionalBoxes.Remove(box);
+ _skinPartListBindingSource.ResetBindings(false);
+ }
+ }
+
+ private void CustomSkinEditor_FormClosing(object sender, FormClosingEventArgs e)
+ {
+ renderer3D1.Dispose();
+ }
+
+ private void outlineColorButton_Click(object sender, EventArgs e)
+ {
+ ColorDialog colorDialog = new ColorDialog();
+ colorDialog.SolidColorOnly = true;
+ if (colorDialog.ShowDialog() == DialogResult.OK)
+ {
+ renderer3D1.GuideLineColor = colorDialog.Color;
+ skinPartListBox_SelectedIndexChanged(sender, e);
+ }
+ }
+
+ private void renderer3D1_TextureChanging(object sender, Rendering.TextureChangingEventArgs e)
+ {
+ Image texture = e.NewTexture;
+ // Skins can only be a 1:1 ratio (base 64x64) or a 2:1 ratio (base 64x32)
+ if (Settings.Default.ValidateImageDimension && texture.Width != texture.Height && texture.Height != texture.Width / 2)
+ {
+ e.Cancel = true;
+ MessageBox.Show("The selected image does not suit a skin texture.", "Invalid image dimensions.", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ return;
+ }
+ uvPictureBox.Image = EditorValue.Texture = texture;
+ textureSizeLabel.Text = $"{texture.Width}x{texture.Height}";
+ }
+
+ // TODO: fixed outline rendering
+ private void skinPartListBox_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ int scale = 1;
+ renderer3D1.SelectedIndices = skinPartListBox.SelectedIndices.Cast().ToArray();
+
+ // TODO: highlight all selected boxes
+ if (skinPartListBox.SelectedItem is SkinBOX box)
+ {
+ boxEditorControl1.SetBOX(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)));
+
+ Bitmap refImg = new Bitmap(1, 1);
+
+ using (var g = Graphics.FromImage(refImg))
+ {
+ g.InterpolationMode = InterpolationMode.HighQualityBicubic;
+ g.DrawImage(uvArea, new Rectangle(0, 0, 1, 1));
+ }
+
+ Color avgColor = refImg.GetPixel(0, 0);
+ renderer3D1.HighlightlingColor = avgColor.Inversed();
+
+ Size scaleSize = new Size(EditorValue.Texture.Width * scale, EditorValue.Texture.Height * scale);
+ uvPictureBox.Image = new Bitmap(scaleSize.Width, scaleSize.Height);
+ using (Graphics g = Graphics.FromImage(uvPictureBox.Image))
+ {
+ GraphicsPath graphicsPath = box.GetUVGraphicsPath(new System.Numerics.Vector2(scaleSize.Width * renderer3D1.TillingFactor.X, scaleSize.Height * renderer3D1.TillingFactor.Y));
+ var brush = new SolidBrush(Color.FromArgb(127, avgColor.GreyScaled()));
+ g.ApplyConfig(_graphicsConfig);
+ g.DrawImage(EditorValue.Texture, new Rectangle(Point.Empty, scaleSize), new Rectangle(Point.Empty, EditorValue.Texture.Size), GraphicsUnit.Pixel);
+ g.FillPath(brush, graphicsPath);
+ }
+ uvPictureBox.Invalidate();
+ }
+ }
+
+ private void captureScreenshotButton_Click(object sender, EventArgs e)
+ {
+ using SaveFileDialog saveFileDialog = new SaveFileDialog()
+ {
+ Filter = "PNG|*.png"
+ };
+ if (saveFileDialog.ShowDialog() == DialogResult.OK)
+ {
+ renderer3D1.GetThumbnail().Save(saveFileDialog.FileName, ImageFormat.Png);
+ }
+ }
+
+ private void showArmorCheckbox_CheckedChanged(object sender, EventArgs e)
+ {
+ renderer3D1.ShowArmor = showArmorCheckbox.Checked;
+ }
+
+ private void skinPartListBox_KeyUp(object sender, KeyEventArgs e)
+ {
+ switch (e.KeyCode)
+ {
+ case Keys.Delete:
+ deleteToolStripMenuItem_Click(sender, e);
+ break;
+ case Keys.Escape:
+ ClearSelection();
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void ReloadOffsetList()
+ {
+ _skinOffsetListBindingSource = new BindingSource(renderer3D1.GetOffsets().ToArray(), null);
+ offsetListBox.DataSource = _skinOffsetListBindingSource;
+ _skinOffsetListBindingSource.ResetBindings(false);
+ }
+
+ private void addOffsetToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ var offsets = renderer3D1.GetOffsets().Select(offset => offset.Type).ToList();
+ string[] available = SkinPartOffset.ValidModelOffsetTypes.Where(s => !offsets.Contains(s)).ToArray();
+ using ItemSelectionPopUp typeSelection = new ItemSelectionPopUp(available);
+ using NumericPrompt valuePrompt = new NumericPrompt(0f, -cOffsetMaximum, cOffsetMaximum);
+ valuePrompt.DecimalPlaces = 1;
+ valuePrompt.ValueStep = (decimal)0.1f;
+ if (typeSelection.ShowDialog() == DialogResult.OK && valuePrompt.ShowDialog() == DialogResult.OK)
+ {
+ renderer3D1.SetPartOffset(typeSelection.SelectedItem, (float)valuePrompt.SelectedValue);
+ ReloadOffsetList();
+ }
+ }
+
+ private void removeOffsetToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ if (offsetListBox.SelectedItem is not SkinPartOffset offset)
+ return;
+ renderer3D1.SetPartOffset(offset.Type, 0f);
+ ReloadOffsetList();
+ }
+
+ private void offsetListBox_DoubleClick(object sender, EventArgs e)
+ {
+ if (offsetListBox.SelectedItem is not SkinPartOffset offset)
+ return;
+
+ using NumericPrompt valuePrompt = new NumericPrompt(offset.Value, -cOffsetMaximum, cOffsetMaximum);
+ valuePrompt.ToolTipText = "Set new Value for " + offset.Type;
+ valuePrompt.DecimalPlaces = 1;
+ valuePrompt.ValueStep = (decimal)0.1f;
+ if (valuePrompt.ShowDialog() == DialogResult.OK)
+ {
+ renderer3D1.SetPartOffset(offset.Type, (float)valuePrompt.SelectedValue);
+ ReloadOffsetList();
+ }
+ }
+
+ private void skinPartListBox_MouseClick(object sender, MouseEventArgs e)
+ {
+ if (skinPartListBox.IndexFromPoint(e.X, e.Y) == -1)
+ ClearSelection();
+ }
+
+ private void ClearSelection()
+ {
+ skinPartListBox.ClearSelected();
+ uvPictureBox.Image = EditorValue.Texture;
+ }
+
+
+ private void centerSelectionCheckbox_CheckedChanged(object sender, EventArgs e)
+ {
+ renderer3D1.CenterOnSelect = centerSelectionCheckbox.Checked;
+ }
+
+ private void generateUvTextureToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ if (skinPartListBox.SelectedItem is SkinBOX skinBox)
+ {
+ GenerateUVTextureMap(skinBox);
+ }
+ }
+
+ private void renderSettingsButton_Click(object sender, EventArgs e)
+ {
+ using AppSettingsForm settingsForm = new AppSettingsForm("Render Settings", _settingsManager.GetSettings());
+ settingsForm.ShowDialog();
+ }
+
+ private string SanitizeModelFilename(in string modelFilename)
+ {
+ return string.IsNullOrWhiteSpace(modelFilename) ? "template" : modelFilename.TrimEnd(new char[] { '\n', '\r' }).Replace(' ', '_');
+ }
+
+ private void exportTemplateButton_Click(object sender, EventArgs e)
+ {
+ Image templateTexture = Resources.classic_template;
+ SkinAnimMask templateAnimMask = SkinAnimMask.MODERN_WIDE_MODEL;
+
+ SaveFileDialog saveFileDialog = new SaveFileDialog();
+ saveFileDialog.Title = "Save Template Model";
+ saveFileDialog.Filter = SkinModelImporter.Default.SupportedModelFileFormatsFilter;
+ saveFileDialog.FileName = SanitizeModelFilename(EditorValue.MetaData.Name);
+ if (saveFileDialog.ShowDialog() == DialogResult.OK)
+ {
+ SkinModelInfo modelInfo = new SkinModelInfo(templateTexture, templateAnimMask, new SkinModel());
+ SkinModelImporter.Default.Export(saveFileDialog.FileName, modelInfo);
+ }
+ }
+
+ private void animEditorButton_Click(object sender, EventArgs e)
+ {
+ ProcessDialogKey(Keys.A);
+ }
+
+ private void boxEditorControl1_BoxChanged(object sender, EventArgs e)
+ {
+ if(skinPartListBox.SelectedIndex > 0)
+ {
+ renderer3D1.ModelData[skinPartListBox.SelectedIndex] = boxEditorControl1.GetBOX();
+ _skinPartListBindingSource.ResetItem(skinPartListBox.SelectedIndex);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/PCK-Studio/Forms/Skins-And-Textures/generateModel.ja.resx b/PCK-Studio/Forms/Editor/CustomSkinEditor.ja.resx
similarity index 100%
rename from PCK-Studio/Forms/Skins-And-Textures/generateModel.ja.resx
rename to PCK-Studio/Forms/Editor/CustomSkinEditor.ja.resx
diff --git a/PCK-Studio/Forms/Skins-And-Textures/generateModel.resx b/PCK-Studio/Forms/Editor/CustomSkinEditor.resx
similarity index 84%
rename from PCK-Studio/Forms/Skins-And-Textures/generateModel.resx
rename to PCK-Studio/Forms/Editor/CustomSkinEditor.resx
index da2157ab..773545d4 100644
--- a/PCK-Studio/Forms/Skins-And-Textures/generateModel.resx
+++ b/PCK-Studio/Forms/Editor/CustomSkinEditor.resx
@@ -117,208 +117,97 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- False
-
-
-
- True
-
-
- NoControl
+
+ Left
-
- 23, 459
+
+ 30, 249
-
- 38, 13
+
+ 61, 21
-
- 137
+
+
+ 128
-
- Parent
+
+ Import
-
- label6
+
+ importTextureButton
-
- System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ MetroFramework.Controls.MetroButton, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a
-
+
$this
-
- 19
+
+ 5
-
- False
-
-
- True
+
+ Left
-
- NoControl
+
+ 97, 249
-
- 691, 357
+
+ 61, 21
-
- 44, 13
+
+ 114
-
- 127
+
+ Export
-
- Position
+
+ exportTextureButton
-
- label5
+
+ MetroFramework.Controls.MetroButton, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a
-
- System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
+
$this
-
- 28
+
+ 4
-
- False
-
-
- True
-
-
- NoControl
-
-
- 691, 259
-
-
- 27, 13
-
-
- 142
-
-
- Size
-
-
- label3
-
-
- System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- $this
-
-
- 27
-
-
- False
-
-
- True
-
-
- NoControl
-
-
- 654, 236
-
-
- 22, 13
-
-
- 131
-
-
- UV
-
-
- label7
-
-
- System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- $this
-
-
- 22
-
-
- False
-
-
- True
-
-
- NoControl
-
-
- 655, 56
-
-
- 128, 13
-
-
- 113
-
-
- Texture Mapping Preview
-
-
- labelTextureMappingPreview
-
-
- System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- $this
-
-
- 16
-
-
+
17, 17
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
- vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMkMEa+wAAABSSURBVDhP5c0x
- DsAgDENRxt7/wmkNSpRGf0CCCZAegxNMM7MlGMp3dIU6dxhKf/QMNxRogeQC8ivw5Vn7C0heJlFA+kL5
- jWAohxRkde4wnGftBS90axNmphIGAAAAAElFTkSuQmCC
+ vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMkMEa+wAAABPSURBVDhP5ZAx
+ DgAgCAMZ/f+HMcbYYOmg0UmHY2ibGzB3txNSgMKsHcD9ksBL5wcBPwyPCwLFJBjjVe4LFHGsgEDBAu6x
+ 4+AxAT9MkYJdKi90axNkwjxWAAAAAElFTkSuQmCC
- 151, 26
+ 201, 26
- Create
+ Add Cube
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
- vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMkMEa+wAAAHbSURBVDhPYyjZ
- 5F622bt8o1fmYpvMxdY5691T5prlrnJq2BsKFM9Z6Zix1DZruX3yAovAPrX8NS4MJZs98la7de2M/I8E
- khdZJsw3m3IwacL+hIoNPkkLDEpWumYus8tf6cTQuSc6zFZj7slckEIGBhD6/z/WUr1oq0fDvtApB1Mm
- H0uOtFaNmaKbPM8iykaTIcpGPSs3K8JWHVlDpK1q4gLDcFv1rHXOIfbq1UGmIfZqQJWVoVYgaQSAaYCD
- aCul3KzMynCrqZk+4baaMA0QdZjo//+KMOtIa62ScMvKEPOycPuNrXEENMBBf5ZvZZjV7CwnFFFMdXCR
- 1jj7tgTn6TleDFtaE4FaN7emIEuXh1pNzPFHFgGqmZATMCXbj2FatmdZsHFZuBWyNAJgiIA0TM31irLT
- hApAAEQdJoJqyPMH2ri7LQaIKsIsCWrwrgizqgo1n5rjMy3He0drFEgDHMDUwQFDWYhlqL3GjBzPylCL
- abm+wHDY1RoLtLA2xAQsD9UANHRbW+zO1miG8hCLKTk+wAiqDrOKsFGrCLWZnu01NdezIhTJbf//72iN
- nZbjNT3Hk2FKtldFmEWEjdautpjKUMsoGw1g/EfZqQMtAWmAASB3RrbHjBxPAFdnoOpP7y1ZAAAAAElF
- TkSuQmCC
+ vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMkMEa+wAAAHaSURBVDhPhZDt
+ a9NQFMbv3yKsaQeCom7JTdJgp65JOzc196ZN29Gt/WCSmw1GSXMdwr4k4D7oxDQtyLQ4VKqizqrsxRf2
+ RfCvinTSLsNhH86n55wf5zkHND7NOv1cc1cxdgRjhycfZuvbU/abzMZ35PRzpHf17kvRfC3Vuuyth4nV
+ d9dAo59deXtjc78YxVR7wVWfTwVHy1s/q+7H/HL3QqN33XiVXu1lwINvJSwmt3/bg0EABhVFFY5Z+5Ld
+ +IGCo/qTX7UiP1EOzteesbqQArrAmLZZEJk4UBQnlroXNZEx38+oErN++4oqJXSBoQgO2icaAiOV4Dnb
+ NKgGW0ZeE1ND4O/cvxVFLuaL/GRD46g67WjSrrc4BhjpkTlHMXxqZsZEGjneouRXZ9pEAZ+9JYph36vH
+ 200EH5P5uEMx3CILgXUThJbs3LnkaPD/G06M0JJbtqKnU3H31CWnrzoGVuYphod++dAvu5gbC+RcDO+h
+ 6RbJhyS35+lnrIobjsohKdkhMkVsaM+1iXLgVSiG99XLccDF8Ktf2fdKoKmyAcm7mF/HsCAkXCS0LaVl
+ yy6KZYuiPa8SEqVNZBBYiovZgjB54Jcp4nQhSRHU0wzFx38bimLYsbIdIv8BV2eg6gZvK4UAAAAASUVO
+ RK5CYII=
- 151, 26
+ 201, 26
Clone
@@ -326,57 +215,52 @@
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
- vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMkMEa+wAAACESURBVDhPlY0B
- DoAgDAP3Dj7r09WTkqGUgJfUxtrOmHFEnL0U76FBqW8PZXmk/9uONEsIb3gsNRzoL/+R5hWC759mGsbQ
- DnzdZbhmiSvhLsM1S1wJdxmuWeJKuMtwzRJXwl2Ga5a4Eu4yXLPElXCX4Zol/WCl6YGdI62n2Zv2cSXV
- byIunLh7mD2ySLcAAAAASUVORK5CYII=
+ vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMkMEa+wAAABUSURBVDhP7Y1B
+ CgAgCAR9h5/t6UaSIGumxw4Jk6DtSJTUIBIP7q+1A+xGXErwYgXmVSAi6ykJArR3CRK8lBHCXoD9NPuC
+ 5wUdUkFHYv8wr2XLCp+ZnLh7mCW3DEkAAAAASUVORK5CYII=
- 151, 26
+ 201, 26
Delete
-
+
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
- vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMkMEa+wAAAFhSURBVFhH7ZY/
- S8RAEMXHW23zDexFkNSSTyDYijZyYq2V4BWBmPZaK7/B1fZiK1iIrRxod4r/Gq38N+7L7B5LyFllVuF8
- 8Mhm55HfZJZAaBq1Zs2yjKx5C+7OiLF223EEYM+CeVaMJlxJXdt1ONZRJuBH/mHo1sPfDY2iwcO39naj
- 35CUkibBo4z+H/6n4EcdetSGzwHQ79BLHf5q6EYbvgTAmaFhHQ67zy2TaPvaAdy+5XUTHMexSHTpsq1r
- APinoftJcFv/ctnWdW7Nb4ZOf4CrnTsezHmenywkCSbwEBMOcVmWlYuiGIVNRIHDvoGwCe2fiwrsHTYA
- p2nqayri7mrKe5vLT7jiPoRnWcaJnYBE2xcPj3ev+OKAvQf99Tvs16wi7m1lY3Bo1CSiq0Y4jJpEdNUI
- h1GTiK4EWGsEx4KaRPQkYO9fgzvw4f7KM/adVVVBxg24e+eOdTSF4GkQ0TdijaTdIsIqEQAAAABJRU5E
- rkJggg==
+ vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMkMEa+wAAAFSSURBVFhH7Za9
+ SsRAFIXPZrSdN9heBEkt8wSCrWgjK9ZaCW4RiGm3tfINtrYXW8FCbGVBu1X8a9zKvys32ZHhqt3cUYgH
+ DgmZufnO3ElIgBZqBQDJi0nUBajXacznclxVDOx3QDTTmEPIOVralHA+T9IB3/JXg2sPfzEYJ4OHqxat
+ X5Pzo+oneJLW/8P/FPwgw702fJYBgwxPEj4xuNKGLzDgxGAk4ezp6+ZkUSxtMXxicCnBbN6OeeBcFsXS
+ kOFvBrcS7OFd4F0WxdIpf0qfDY4lOICr7TvfmIqiOJqzljtwlxLOoqqqapdlOQ5DJIGHAcIQ2j8XNfi7
+ AOw8z/2Yiqi3nNPO+uIDH2UA5xxZa/Xgo8PtCzrbI+/hYPVGdkQWxRL1N9wnOLQmNNQXcEsDiCC8LSkC
+ NGDvX4NPwfu7S4/aT7xXDQlXH4AzOVlTIbgd+gBijaTdhfUeOAAAAABJRU5ErkJggg==
-
- 151, 26
+
+ 201, 26
-
- Change Color
+
+ Re-generate UV Texture
-
- 152, 108
+
+ 202, 108
-
- contextMenuStrip1
+
+ skinPartTabContextMenu
-
+
System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- Flat
-
-
- NoControl
+
+ Bottom, Right
- 654, 676
+ 3, 477
- 130, 22
+ 184, 117
111
@@ -388,661 +272,106 @@
buttonDone
- System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+ MetroFramework.Controls.MetroButton, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a
$this
- 26
-
-
- True
-
-
- NoControl
-
-
- 289, 647
-
-
- 33, 13
-
-
- 102
-
-
- View:
-
-
- labelView
-
-
- System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- $this
-
-
- 25
-
-
- Flat
-
-
- NoControl
-
-
- 554, 642
-
-
- 89, 23
-
-
- 100
-
-
- Rotate Right
-
-
- rotateRightBtn
-
-
- System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- $this
-
-
- 24
-
-
- Flat
-
-
- NoControl
-
-
- 194, 643
-
-
- 89, 23
-
-
- 101
-
-
- Rotate Left
-
-
- rotateLeftBtn
-
-
- System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- $this
-
-
- 23
-
-
- 4, 22
-
-
- 3, 3, 3, 3
-
-
- 116, 132
-
-
- 1
-
-
- Armor
-
-
- tabArmor
-
-
- System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- tabBody
-
-
- 0
-
-
- 2
-
-
- Left
-
-
- 58, 99
-
-
- 43, 20
-
-
- 85
-
-
- 0
-
-
- offsetArms
-
-
- System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- myTablePanel2
-
-
- 0
-
-
- Left
-
-
- True
-
-
- NoControl
-
-
- 3, 103
-
-
- 38, 13
-
-
- 90
-
-
- ARMS
-
-
- label14
-
-
- System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- myTablePanel2
-
-
- 1
-
-
- Left
-
-
- 58, 36
-
-
- 43, 20
-
-
- 83
-
-
- 0
-
-
- offsetBody
-
-
- System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- myTablePanel2
-
-
- 2
-
-
- Left
-
-
- 58, 67
-
-
- 43, 20
-
-
- 84
-
-
- 0
-
-
- offsetLegs
-
-
- System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- myTablePanel2
-
-
- 3
-
-
- Left
-
-
- True
-
-
- NoControl
-
-
- 3, 9
-
-
- 37, 13
-
-
- 87
-
-
- HEAD
-
-
- label10
-
-
- System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- myTablePanel2
-
-
- 4
-
-
- Left
-
-
- True
-
-
- NoControl
-
-
- 3, 71
-
-
- 35, 13
-
-
- 89
-
-
- LEGS
-
-
- label13
-
-
- System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- myTablePanel2
-
-
- 5
-
-
- Left
-
-
- 58, 5
-
-
- 43, 20
-
-
- 86
-
-
- 0
-
-
- offsetHead
-
-
- System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- myTablePanel2
-
-
- 6
-
-
- Left
-
-
- True
-
-
- NoControl
-
-
- 3, 40
-
-
- 37, 13
-
-
- 88
-
-
- BODY
-
-
- label12
-
-
- System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- myTablePanel2
-
-
- 7
-
-
- Fill
-
-
- 3, 3
-
-
- 4
-
-
- 110, 126
-
-
- 146
-
-
- myTablePanel2
-
-
- System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- tabPage1
-
-
- 0
-
-
- <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="offsetArms" Row="3" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="label14" Row="3" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="offsetBody" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="offsetLegs" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="label10" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="label13" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="offsetHead" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="label12" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,50,Percent,50" /><Rows Styles="Percent,25,Percent,25,Percent,25,Percent,25" /></TableLayoutSettings>
-
-
- 4, 22
-
-
- 3, 3, 3, 3
-
-
- 116, 132
-
-
- 0
-
-
- Body
-
-
- tabPage1
-
-
- System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- tabBody
-
-
- 1
-
-
- Fill
-
-
- 3, 16
-
-
- 124, 158
-
-
- 144
-
-
- tabBody
-
-
- System.Windows.Forms.TabControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- groupBox1
-
-
- 0
-
-
- 654, 459
-
-
- 130, 177
-
-
- 139
-
-
- OFFSETS
-
-
- groupBox1
-
-
- System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- $this
-
-
21
-
- HEAD
+
+ Bottom, Left
-
- BODY
+
+ 3, 396
-
- ARM0
+
+ 91, 21
-
- ARM1
+
+ 96
-
- LEG0
+
+ Import Skin
-
- LEG1
+
+ importSkinButton
-
- 23, 484
-
-
- 114, 21
-
-
- 134
-
-
- comboParent
-
-
- System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- $this
-
-
- 18
-
-
- Flat
-
-
- NoControl
-
-
- 722, 206
-
-
- 61, 21
-
-
- 114
-
-
- EXPORT
-
-
- buttonEXPORT
-
-
- System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- $this
-
-
- 15
-
-
- Flat
-
-
- NoControl
-
-
- 655, 206
-
-
- 61, 21
-
-
- 128
-
-
- IMPORT
-
-
- buttonIMPORT
-
-
- System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- $this
-
-
- 20
-
-
- NoControl
-
-
- 655, 72
-
-
- 128, 128
-
-
- Zoom
-
-
- 112
-
-
- uvPictureBox
-
-
- PckStudio.ToolboxItems.InterpolationPictureBox, PCK-Studio, Version=7.0.0.2, Culture=neutral, PublicKeyToken=null
-
-
- $this
-
-
- 17
-
-
- NoControl
-
-
- 194, 56
-
-
- 449, 580
-
-
- StretchImage
-
-
- 98
-
-
- displayBox
-
-
- System.Windows.Forms.PictureBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- $this
-
-
- 13
-
-
- 23, 511
-
-
- 114, 21
-
-
- 146
-
-
- Load Template
-
-
- buttonTemplate
-
-
+
MetroFramework.Controls.MetroButton, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a
-
+
$this
-
- 12
+
+ 20
+
+
+ Bottom, Left
+
+
+ 97, 396
+
+
+ 90, 21
+
+
+ 97
+
+
+ Export skin
+
+
+ exportSkinButton
+
+
+ MetroFramework.Controls.MetroButton, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a
+
+
+ $this
+
+
+ 19
+
+
+ Left
+
+
+ 19, 327
+
+
+ 161, 21
+
+
+ 145
+
+
+ Set Outline Color
+
+
+ False
+
+
+ outlineColorButton
+
+
+ MetroFramework.Controls.MetroButton, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a
+
+
+ $this
+
+
+ 11
+
+
+ Left
True
- 23, 556
+ 23, 276
140, 15
@@ -1063,338 +392,491 @@
$this
- 11
-
-
- True
-
-
- 23, 577
-
-
- 84, 15
-
-
- 148
-
-
- Guide Lines
-
-
- checkGuide
-
-
- MetroFramework.Controls.MetroCheckBox, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a
-
-
- $this
-
-
10
-
+
+ Left
+
+
True
-
- 23, 598
+
+ 49, 375
-
- 129, 15
+
+ 89, 15
-
+
149
-
- Show Armor Offsets
+
+ Show Armor
-
- checkBoxArmor
+
+ showArmorCheckbox
-
+
MetroFramework.Controls.MetroCheckBox, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a
-
+
$this
-
+
9
-
- 658, 275
+
+ Fill
-
- 119, 20
+
+ 0, 0
-
- 150
+
+ 532, 353
-
- Center
+
+ 0
-
- SizeXUpDown
+
+ skinPartListBox
-
- System.Windows.Forms.NumericUpDown, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
+
+ skinPartsTabPage
+
+
+ 0
+
+
+ Bottom, Right
+
+
+ 97, 450
+
+
+ 90, 21
+
+
+ 163
+
+
+ Screenshot
+
+
+ captureScreenshotButton
+
+
+ MetroFramework.Controls.MetroButton, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a
+
+
$this
-
- 8
+
+ 17
-
- 658, 301
+
+ Left
-
- 119, 20
+
+ True
-
- 151
+
+ 49, 354
-
- Center
+
+ 83, 15
-
- SizeYUpDown
+
+ 164
-
- System.Windows.Forms.NumericUpDown, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ Show Tools
-
+
+ showToolsCheckBox
+
+
+ MetroFramework.Controls.MetroCheckBox, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a
+
+
$this
-
+
7
-
- 658, 327
+
+ Top, Left, Right
-
- 119, 20
+
+ True
-
- 152
+
+ 364, 36
-
- Center
+
+ 73, 19
-
- SizeZUpDown
+
+ 165
-
- System.Windows.Forms.NumericUpDown, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ nameLabel
-
+
+ skinNameLabel
+
+
+ MetroFramework.Controls.MetroLabel, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a
+
+
$this
-
- 6
+
+ 16
-
- 682, 233
+
+ Top, Right
-
- 43, 20
+
+ 4, 38
-
- 156
+
+ 532, 353
-
- TextureXUpDown
+
+ 0
-
- System.Windows.Forms.NumericUpDown, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ Parts
-
- $this
+
+ skinPartsTabPage
-
- 5
+
+ System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- 731, 234
+
+ metroTabControl1
-
- 43, 20
+
+ 0
-
- 157
+
+ 204, 17
+
+
+ 152, 22
-
- TextureYUpDown
+
+ Add Offset
-
- System.Windows.Forms.NumericUpDown, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ 152, 22
-
- $this
+
+ Remove Offset
-
- 4
+
+ 153, 48
-
- 657, 425
+
+ offsetTabContextMenu
-
- 120, 20
+
+ MetroFramework.Controls.MetroContextMenu, MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a
-
- 160
+
+