mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/PCK-Studio.git
synced 2026-05-30 12:17:01 +00:00
Merge main into '3dSkinRenderer'
This commit is contained in:
@@ -77,9 +77,6 @@
|
||||
<setting name="AutoUpdate" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="UseComboBoxForGRFParameter" serializeAs="String">
|
||||
<value>False</value>
|
||||
</setting>
|
||||
<setting name="ValidateImageDimension" serializeAs="String">
|
||||
<value>True</value>
|
||||
</setting>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -28,25 +29,5 @@ namespace PckStudio.Extensions
|
||||
ms.Position = 0;
|
||||
return Image.FromStream(ms);
|
||||
}
|
||||
|
||||
internal static JObject ConvertToJavaAnimation(this Animation animation)
|
||||
{
|
||||
JObject janimation = new JObject();
|
||||
JObject mcmeta = new JObject();
|
||||
mcmeta["comment"] = $"Animation converted with {Application.ProductName}";
|
||||
mcmeta["animation"] = janimation;
|
||||
JArray jframes = new JArray();
|
||||
foreach (Animation.Frame frame in animation.GetFrames())
|
||||
{
|
||||
JObject jframe = new JObject();
|
||||
jframe["index"] = animation.GetTextureIndex(frame.Texture);
|
||||
jframe["time"] = frame.Ticks;
|
||||
jframes.Add(jframe);
|
||||
}
|
||||
janimation["interpolation"] = animation.Interpolate;
|
||||
janimation["frames"] = jframes;
|
||||
return mcmeta;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace PckStudio.Extensions
|
||||
yield break;
|
||||
}
|
||||
|
||||
internal static Image Combine(this IList<Image> sources, ImageLayoutDirection layoutDirection)
|
||||
internal static Image Combine(this IEnumerable<Image> sources, ImageLayoutDirection layoutDirection)
|
||||
{
|
||||
Size imageSize = CalculateImageSize(sources, layoutDirection);
|
||||
var image = new Bitmap(imageSize.Width, imageSize.Height);
|
||||
@@ -110,24 +110,25 @@ namespace PckStudio.Extensions
|
||||
return image;
|
||||
}
|
||||
|
||||
private static Size CalculateImageSize(IList<Image> sources, ImageLayoutDirection layoutDirection)
|
||||
private static Size CalculateImageSize(IEnumerable<Image> sources, ImageLayoutDirection layoutDirection)
|
||||
{
|
||||
if (sources.Count < 2)
|
||||
{
|
||||
return sources.Count < 1 ? Size.Empty : sources[0].Size;
|
||||
}
|
||||
var horizontal = layoutDirection == ImageLayoutDirection.Horizontal;
|
||||
Size size = sources.First().Size;
|
||||
int width = size.Width;
|
||||
int height = size.Height;
|
||||
int count = sources.Count();
|
||||
|
||||
int width = sources[0].Width;
|
||||
int height = sources[0].Height;
|
||||
if (count < 2)
|
||||
return count < 1 ? Size.Empty : size;
|
||||
|
||||
var horizontal = layoutDirection == ImageLayoutDirection.Horizontal;
|
||||
|
||||
if (!sources.All(img => img.Width.Equals(width) && img.Height.Equals(height)))
|
||||
throw new InvalidOperationException("Images must have the same width and height.");
|
||||
|
||||
if (horizontal)
|
||||
width *= sources.Count;
|
||||
width *= count;
|
||||
else
|
||||
height *= sources.Count;
|
||||
height *= count;
|
||||
|
||||
return new Size(width, height);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
this.ValueTextBox = new MetroFramework.Controls.MetroTextBox();
|
||||
this.CancelBtn = new MetroFramework.Controls.MetroButton();
|
||||
this.ConfirmBtn = new MetroFramework.Controls.MetroButton();
|
||||
this.availableComboBox = new MetroFramework.Controls.MetroComboBox();
|
||||
metroLabel1 = new MetroFramework.Controls.MetroLabel();
|
||||
metroLabel2 = new MetroFramework.Controls.MetroLabel();
|
||||
this.SuspendLayout();
|
||||
@@ -46,7 +45,7 @@
|
||||
metroLabel1.Location = new System.Drawing.Point(18, 27);
|
||||
metroLabel1.Name = "metroLabel1";
|
||||
metroLabel1.Size = new System.Drawing.Size(48, 19);
|
||||
metroLabel1.TabIndex = 0;
|
||||
metroLabel1.TabIndex = 4;
|
||||
metroLabel1.Text = "Name:";
|
||||
metroLabel1.Theme = MetroFramework.MetroThemeStyle.Dark;
|
||||
//
|
||||
@@ -56,12 +55,14 @@
|
||||
metroLabel2.Location = new System.Drawing.Point(17, 56);
|
||||
metroLabel2.Name = "metroLabel2";
|
||||
metroLabel2.Size = new System.Drawing.Size(42, 19);
|
||||
metroLabel2.TabIndex = 1;
|
||||
metroLabel2.TabIndex = 5;
|
||||
metroLabel2.Text = "Value:";
|
||||
metroLabel2.Theme = MetroFramework.MetroThemeStyle.Dark;
|
||||
//
|
||||
// NameTextBox
|
||||
//
|
||||
this.NameTextBox.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest;
|
||||
this.NameTextBox.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.CustomSource;
|
||||
//
|
||||
//
|
||||
//
|
||||
@@ -86,7 +87,7 @@
|
||||
this.NameTextBox.ShortcutsEnabled = true;
|
||||
this.NameTextBox.Size = new System.Drawing.Size(165, 23);
|
||||
this.NameTextBox.Style = MetroFramework.MetroColorStyle.White;
|
||||
this.NameTextBox.TabIndex = 2;
|
||||
this.NameTextBox.TabIndex = 0;
|
||||
this.NameTextBox.Theme = MetroFramework.MetroThemeStyle.Dark;
|
||||
this.NameTextBox.UseSelectable = true;
|
||||
this.NameTextBox.WaterMarkColor = System.Drawing.Color.FromArgb(((int)(((byte)(109)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))));
|
||||
@@ -117,8 +118,7 @@
|
||||
this.ValueTextBox.SelectionStart = 0;
|
||||
this.ValueTextBox.ShortcutsEnabled = true;
|
||||
this.ValueTextBox.Size = new System.Drawing.Size(165, 23);
|
||||
this.ValueTextBox.Style = MetroFramework.MetroColorStyle.White;
|
||||
this.ValueTextBox.TabIndex = 3;
|
||||
this.ValueTextBox.TabIndex = 1;
|
||||
this.ValueTextBox.Theme = MetroFramework.MetroThemeStyle.Dark;
|
||||
this.ValueTextBox.UseSelectable = true;
|
||||
this.ValueTextBox.WaterMarkColor = System.Drawing.Color.FromArgb(((int)(((byte)(109)))), ((int)(((byte)(109)))), ((int)(((byte)(109)))));
|
||||
@@ -131,7 +131,7 @@
|
||||
this.CancelBtn.Name = "CancelBtn";
|
||||
this.CancelBtn.Size = new System.Drawing.Size(95, 23);
|
||||
this.CancelBtn.Style = MetroFramework.MetroColorStyle.White;
|
||||
this.CancelBtn.TabIndex = 4;
|
||||
this.CancelBtn.TabIndex = 2;
|
||||
this.CancelBtn.Text = "Cancel";
|
||||
this.CancelBtn.Theme = MetroFramework.MetroThemeStyle.Dark;
|
||||
this.CancelBtn.UseSelectable = true;
|
||||
@@ -142,33 +142,18 @@
|
||||
this.ConfirmBtn.Name = "ConfirmBtn";
|
||||
this.ConfirmBtn.Size = new System.Drawing.Size(96, 23);
|
||||
this.ConfirmBtn.Style = MetroFramework.MetroColorStyle.White;
|
||||
this.ConfirmBtn.TabIndex = 5;
|
||||
this.ConfirmBtn.TabIndex = 3;
|
||||
this.ConfirmBtn.Text = "Confirm";
|
||||
this.ConfirmBtn.Theme = MetroFramework.MetroThemeStyle.Dark;
|
||||
this.ConfirmBtn.UseSelectable = true;
|
||||
this.ConfirmBtn.Click += new System.EventHandler(this.ConfirmButton_Click);
|
||||
//
|
||||
// availableComboBox
|
||||
//
|
||||
this.availableComboBox.FormattingEnabled = true;
|
||||
this.availableComboBox.ItemHeight = 23;
|
||||
this.availableComboBox.Location = new System.Drawing.Point(72, 21);
|
||||
this.availableComboBox.Name = "availableComboBox";
|
||||
this.availableComboBox.Size = new System.Drawing.Size(165, 29);
|
||||
this.availableComboBox.Style = MetroFramework.MetroColorStyle.Silver;
|
||||
this.availableComboBox.TabIndex = 6;
|
||||
this.availableComboBox.Theme = MetroFramework.MetroThemeStyle.Dark;
|
||||
this.availableComboBox.UseSelectable = true;
|
||||
this.availableComboBox.Visible = false;
|
||||
this.availableComboBox.SelectedIndexChanged += new System.EventHandler(this.availableComboBox_SelectedIndexChanged);
|
||||
//
|
||||
// AddParameter
|
||||
//
|
||||
this.AcceptButton = this.ConfirmBtn;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(264, 126);
|
||||
this.Controls.Add(this.availableComboBox);
|
||||
this.Controls.Add(this.ConfirmBtn);
|
||||
this.Controls.Add(this.CancelBtn);
|
||||
this.Controls.Add(this.ValueTextBox);
|
||||
@@ -192,6 +177,5 @@
|
||||
private MetroFramework.Controls.MetroButton CancelBtn;
|
||||
private MetroFramework.Controls.MetroButton ConfirmBtn;
|
||||
private MetroFramework.Controls.MetroTextBox NameTextBox;
|
||||
private MetroFramework.Controls.MetroComboBox availableComboBox;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using OMI.Formats.GameRule;
|
||||
using PckStudio.Properties;
|
||||
|
||||
namespace PckStudio.Forms.Additional_Popups.Grf
|
||||
{
|
||||
@@ -10,25 +9,12 @@ namespace PckStudio.Forms.Additional_Popups.Grf
|
||||
public string ParameterName => NameTextBox.Text;
|
||||
public string ParameterValue => ValueTextBox.Text;
|
||||
|
||||
private bool _useComboBox
|
||||
{
|
||||
get
|
||||
{
|
||||
return availableComboBox.Visible && !NameTextBox.Visible;
|
||||
}
|
||||
set
|
||||
{
|
||||
NameTextBox.Visible = !value;
|
||||
availableComboBox.Visible = value;
|
||||
}
|
||||
}
|
||||
|
||||
public AddParameter()
|
||||
{
|
||||
InitializeComponent();
|
||||
availableComboBox.Items.Clear();
|
||||
availableComboBox.Items.AddRange(GameRuleFile.GameRule.ValidParameters);
|
||||
_useComboBox = Settings.Default.UseComboBoxForGRFParameter;
|
||||
NameTextBox.AutoCompleteCustomSource = new AutoCompleteStringCollection();
|
||||
NameTextBox.AutoCompleteCustomSource.AddRange(GameRuleFile.GameRule.ValidParameters);
|
||||
}
|
||||
|
||||
public AddParameter(string parameterName, string parameterValue, bool isKeyReadonly = true) : this()
|
||||
@@ -36,23 +22,16 @@ namespace PckStudio.Forms.Additional_Popups.Grf
|
||||
NameTextBox.Text = parameterName;
|
||||
ValueTextBox.Text = parameterValue;
|
||||
NameTextBox.Enabled = isKeyReadonly;
|
||||
availableComboBox.Enabled = isKeyReadonly;
|
||||
availableComboBox.SelectedItem = parameterName;
|
||||
}
|
||||
|
||||
private void ConfirmButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(ParameterName) || string.IsNullOrWhiteSpace(ParameterValue))
|
||||
{
|
||||
MessageBox.Show(this, "Name and Value need valid values");
|
||||
MessageBox.Show(this, "Name or value can't be empty.", "Empty value", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
|
||||
return;
|
||||
}
|
||||
DialogResult = DialogResult.OK;
|
||||
}
|
||||
|
||||
private void availableComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
NameTextBox.Text = availableComboBox.SelectedItem.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ namespace PckStudio.Forms
|
||||
["AutoUpdate"] = "Auto Update",
|
||||
["LoadSubPcks"] = "Load Sub Pcks",
|
||||
["UsePrerelease"] = "Use Prerelease",
|
||||
["UseComboBoxForGRFParameter"] = "Easy Grf Param",
|
||||
};
|
||||
|
||||
private void CheckBox_CheckedChanged(object sender, EventArgs e)
|
||||
|
||||
@@ -33,6 +33,7 @@ using PckStudio.Extensions;
|
||||
using PckStudio.Properties;
|
||||
using PckStudio.Internal;
|
||||
using PckStudio.Internal.Deserializer;
|
||||
using PckStudio.Internal.Serializer;
|
||||
|
||||
namespace PckStudio.Forms.Editor
|
||||
{
|
||||
@@ -336,7 +337,6 @@ namespace PckStudio.Forms.Editor
|
||||
var img = Image.FromFile(textureFile).ReleaseFromFile();
|
||||
JObject mcmeta = JObject.Parse(File.ReadAllText(fileDialog.FileName));
|
||||
Animation javaAnimation = AnimationDeserializer.DefaultDeserializer.DeserializeJavaAnimation(mcmeta, img);
|
||||
//javaAnimation.Category = _animation.Category;
|
||||
_animation = javaAnimation;
|
||||
LoadAnimationTreeView();
|
||||
}
|
||||
@@ -354,11 +354,11 @@ namespace PckStudio.Forms.Editor
|
||||
fileDialog.Filter = "Animation Scripts (*.mcmeta)|*.png.mcmeta";
|
||||
if (fileDialog.ShowDialog(this) == DialogResult.OK)
|
||||
{
|
||||
JObject mcmeta = _animation.ConvertToJavaAnimation();
|
||||
JObject mcmeta = AnimationSerializer.SerializeJavaAnimation(_animation);
|
||||
string jsondata = JsonConvert.SerializeObject(mcmeta, Formatting.Indented);
|
||||
string filename = fileDialog.FileName;
|
||||
File.WriteAllText(filename, jsondata);
|
||||
Image finalTexture = _animation.BuildTexture();
|
||||
Image finalTexture = AnimationSerializer.SerializeTexture(_animation);
|
||||
// removes ".mcmeta" from filename
|
||||
string texturePath = Path.Combine(Path.GetDirectoryName(filename), Path.GetFileNameWithoutExtension(filename));
|
||||
finalTexture.Save(texturePath);
|
||||
@@ -422,7 +422,7 @@ namespace PckStudio.Forms.Editor
|
||||
return;
|
||||
}
|
||||
|
||||
var oldResolution = _animation.BuildTexture().Width;
|
||||
var oldResolution = _animation.GetFrame(0).Texture.Width;
|
||||
|
||||
FrameDimension dimension = new FrameDimension(gif.FrameDimensionsList[0]);
|
||||
int frameCount = gif.GetFrameCount(dimension);
|
||||
@@ -436,10 +436,7 @@ namespace PckStudio.Forms.Editor
|
||||
textures.Add(new Bitmap(gif, oldResolution, oldResolution));
|
||||
}
|
||||
|
||||
// TODO: Add function or a other way to initialize the frames by textures.
|
||||
// Currently single frames only get added when an anim has an invalid format or is empty.
|
||||
// -Miku
|
||||
_animation = new Animation(textures, "");
|
||||
_animation = new Animation(textures, initFramesFromTextures: true);
|
||||
_animation.Interpolate = InterpolationCheckbox.Checked;
|
||||
LoadAnimationTreeView();
|
||||
}
|
||||
@@ -453,9 +450,9 @@ namespace PckStudio.Forms.Editor
|
||||
};
|
||||
if (ofd.ShowDialog(this) != DialogResult.OK)
|
||||
return;
|
||||
Image img = Image.FromFile(ofd.FileName).ReleaseFromFile();
|
||||
var textures = img.Split(ImageLayoutDirection.Vertical);
|
||||
_animation = new Animation(textures, string.Empty);
|
||||
using Image img = Image.FromFile(ofd.FileName);
|
||||
IEnumerable<Image> textures = img.Split(ImageLayoutDirection.Vertical);
|
||||
_animation = new Animation(textures, initFramesFromTextures: true);
|
||||
LoadAnimationTreeView();
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ using PckStudio.Extensions;
|
||||
using System.Text;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace PckStudio.Internal
|
||||
{
|
||||
@@ -41,17 +42,13 @@ namespace PckStudio.Internal
|
||||
|
||||
private object _syncLock = new object();
|
||||
|
||||
public Animation(IEnumerable<Image> textures)
|
||||
public Animation(IEnumerable<Image> textures, bool initFramesFromTextures = false)
|
||||
{
|
||||
_textures = new List<Image>(textures);
|
||||
if (initFramesFromTextures)
|
||||
AddTexturesAsFrames(MinimumFrameTime);
|
||||
}
|
||||
|
||||
public Animation(IEnumerable<Image> textures, string animString)
|
||||
: this(textures)
|
||||
{
|
||||
ParseAnim(animString);
|
||||
}
|
||||
|
||||
public class Frame
|
||||
{
|
||||
public readonly Image Texture;
|
||||
@@ -83,47 +80,12 @@ namespace PckStudio.Internal
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseAnim(string anim)
|
||||
{
|
||||
if (string.IsNullOrEmpty(anim))
|
||||
{
|
||||
AddSingleFrames();
|
||||
return;
|
||||
}
|
||||
anim = anim.Trim();
|
||||
anim = (Interpolate = anim.StartsWith("#")) ? anim.Substring(1) : anim;
|
||||
string[] animData = anim.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
int lastFrameTime = MinimumFrameTime;
|
||||
if (animData.Length <= 0)
|
||||
{
|
||||
AddSingleFrames();
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (string frameInfo in animData)
|
||||
{
|
||||
string[] frameData = frameInfo.Split('*');
|
||||
int currentFrameIndex = 0;
|
||||
int.TryParse(frameData[0], out currentFrameIndex);
|
||||
|
||||
// Some textures like the Halloween 2015's Lava texture don't have a
|
||||
// frame time parameter for certain frames.
|
||||
// This will detect that and place the last frame time in its place.
|
||||
// This is accurate to console edition behavior.
|
||||
// - MattNL
|
||||
int currentFrameTime = frameData.Length < 2 || string.IsNullOrEmpty(frameData[1]) ? lastFrameTime : int.Parse(frameData[1]);
|
||||
AddFrame(currentFrameIndex, currentFrameTime);
|
||||
lastFrameTime = currentFrameTime;
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckTextureIndex(int index)
|
||||
{
|
||||
if (!_textures.IndexInRange(index))
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
|
||||
public Frame AddFrame(int textureIndex) => AddFrame(textureIndex, MinimumFrameTime);
|
||||
public Frame AddFrame(int textureIndex, int frameTime)
|
||||
{
|
||||
CheckTextureIndex(textureIndex);
|
||||
@@ -132,11 +94,11 @@ namespace PckStudio.Internal
|
||||
return frame;
|
||||
}
|
||||
|
||||
private void AddSingleFrames()
|
||||
private void AddTexturesAsFrames(int frameTime)
|
||||
{
|
||||
for (int i = 0; i < TextureCount; i++)
|
||||
{
|
||||
AddFrame(i);
|
||||
AddFrame(i, frameTime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,22 +167,6 @@ namespace PckStudio.Internal
|
||||
SetFrame(frameIndex, new Frame(_textures[textureIndex], frameTime));
|
||||
}
|
||||
|
||||
public string BuildAnim()
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder(Interpolate ? "#" : string.Empty);
|
||||
foreach (Frame frame in _frames)
|
||||
stringBuilder.Append($"{GetTextureIndex(frame.Texture)}*{frame.Ticks},");
|
||||
return stringBuilder.ToString(0, stringBuilder.Length - 1);
|
||||
}
|
||||
|
||||
public Image BuildTexture()
|
||||
{
|
||||
if (_textures[0].Width != _textures[0].Height)
|
||||
throw new Exception("Invalid size");
|
||||
|
||||
return _textures.Combine(ImageLayoutDirection.Vertical);
|
||||
}
|
||||
|
||||
internal void SetFrameTicks(int ticks)
|
||||
{
|
||||
lock(_syncLock)
|
||||
|
||||
@@ -23,12 +23,51 @@ namespace PckStudio.Internal.Deserializer
|
||||
{
|
||||
Image texture = asset.GetTexture();
|
||||
IEnumerable<Image> frameTextures = texture.Split(ImageLayoutDirection.Vertical);
|
||||
var _animation = new Animation(frameTextures, asset.GetProperty("ANIM"));
|
||||
return _animation;
|
||||
Animation animation = new Animation(frameTextures);
|
||||
DeserializeAnimationAnim(ref animation, asset.GetProperty("ANIM"));
|
||||
return animation;
|
||||
}
|
||||
return Animation.CreateEmpty();
|
||||
}
|
||||
|
||||
private static bool DeserializeAnimationAnim(ref Animation animation, string animString)
|
||||
{
|
||||
if (string.IsNullOrEmpty(animString))
|
||||
{
|
||||
Trace.TraceError($"[{nameof(AnimationExtensions)}:{nameof(DeserializeAnimationAnim)}] Failed to parse anim. anim was null or empty.");
|
||||
return false;
|
||||
}
|
||||
animString = animString.Trim();
|
||||
|
||||
animation.Interpolate = animString.StartsWith("#");
|
||||
animString = animation.Interpolate ? animString.Substring(1) : animString;
|
||||
|
||||
string[] animData = animString.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (animData.Length <= 0)
|
||||
{
|
||||
Trace.TraceError($"[{nameof(AnimationExtensions)}:{nameof(DeserializeAnimationAnim)}] Failed to parse anim. animData was empty.");
|
||||
return false;
|
||||
}
|
||||
|
||||
int lastFrameTime = Animation.MinimumFrameTime;
|
||||
foreach (string frameInfo in animData)
|
||||
{
|
||||
string[] frameData = frameInfo.Split('*');
|
||||
int currentFrameIndex = 0;
|
||||
int.TryParse(frameData[0], out currentFrameIndex);
|
||||
|
||||
// Some textures like the Halloween 2015's Lava texture don't have a
|
||||
// frame time parameter for certain frames.
|
||||
// This will detect that and place the last frame time in its place.
|
||||
// This is accurate to console edition behavior.
|
||||
// - MattNL
|
||||
int currentFrameTime = frameData.Length < 2 || string.IsNullOrEmpty(frameData[1]) ? lastFrameTime : int.Parse(frameData[1]);
|
||||
animation.AddFrame(currentFrameIndex, currentFrameTime);
|
||||
lastFrameTime = currentFrameTime;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public Animation DeserializeJavaAnimation(JObject jsonObject, Image texture)
|
||||
{
|
||||
IEnumerable<Image> textures = texture.Split(ImageLayoutDirection.Vertical);
|
||||
|
||||
@@ -15,10 +15,16 @@
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
**/
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using OMI.Formats.Pck;
|
||||
using PckStudio.Extensions;
|
||||
using PckStudio.Interfaces;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace PckStudio.Internal.Serializer
|
||||
{
|
||||
@@ -28,10 +34,47 @@ namespace PckStudio.Internal.Serializer
|
||||
|
||||
public void Serialize(Animation animation, ref PckAsset asset)
|
||||
{
|
||||
string anim = animation.BuildAnim();
|
||||
string anim = SerializeAnim(animation);
|
||||
asset.SetProperty("ANIM", anim);
|
||||
Image texture = animation.BuildTexture();
|
||||
Image texture = SerializeTexture(animation);
|
||||
asset.SetTexture(texture);
|
||||
}
|
||||
|
||||
private static string SerializeAnim(Animation animation)
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder(animation.Interpolate ? "#" : string.Empty);
|
||||
foreach (Animation.Frame frame in animation.GetFrames())
|
||||
stringBuilder.Append($"{animation.GetTextureIndex(frame.Texture)}*{frame.Ticks},");
|
||||
return stringBuilder.ToString(0, stringBuilder.Length - 1);
|
||||
}
|
||||
|
||||
internal static Image SerializeTexture(Animation animation)
|
||||
{
|
||||
IReadOnlyCollection<Image> textures = animation.GetTextures();
|
||||
Size size = textures.First().Size;
|
||||
if (size.Width != size.Height)
|
||||
throw new Exception("Invalid size");
|
||||
|
||||
return textures.Combine(ImageLayoutDirection.Vertical);
|
||||
}
|
||||
|
||||
internal static JObject SerializeJavaAnimation(Animation animation)
|
||||
{
|
||||
JObject janimation = new JObject();
|
||||
JObject mcmeta = new JObject();
|
||||
mcmeta["comment"] = $"Animation converted with {Application.ProductName}";
|
||||
mcmeta["animation"] = janimation;
|
||||
JArray jframes = new JArray();
|
||||
foreach (Animation.Frame frame in animation.GetFrames())
|
||||
{
|
||||
JObject jframe = new JObject();
|
||||
jframe["index"] = animation.GetTextureIndex(frame.Texture);
|
||||
jframe["time"] = frame.Ticks;
|
||||
jframes.Add(jframe);
|
||||
}
|
||||
janimation["interpolation"] = animation.Interpolate;
|
||||
janimation["frames"] = jframes;
|
||||
return mcmeta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
14
PCK-Studio/Properties/Settings.Designer.cs
generated
14
PCK-Studio/Properties/Settings.Designer.cs
generated
@@ -12,7 +12,7 @@ namespace PckStudio.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.9.0.0")]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.10.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
@@ -104,18 +104,6 @@ namespace PckStudio.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||
public bool UseComboBoxForGRFParameter {
|
||||
get {
|
||||
return ((bool)(this["UseComboBoxForGRFParameter"]));
|
||||
}
|
||||
set {
|
||||
this["UseComboBoxForGRFParameter"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
public global::System.Collections.Specialized.StringCollection RecentFiles {
|
||||
|
||||
@@ -23,9 +23,6 @@
|
||||
<Setting Name="AutoUpdate" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
<Setting Name="UseComboBoxForGRFParameter" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">False</Value>
|
||||
</Setting>
|
||||
<Setting Name="RecentFiles" Type="System.Collections.Specialized.StringCollection" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
|
||||
Reference in New Issue
Block a user