diff --git a/PckStudio.Core/DLC/DLCManager.cs b/PckStudio.Core/DLC/DLCManager.cs index 83f51e39..31456516 100644 --- a/PckStudio.Core/DLC/DLCManager.cs +++ b/PckStudio.Core/DLC/DLCManager.cs @@ -16,9 +16,13 @@ using OMI.Formats.Pck; using OMI.Workers.GameRule; using OMI.Workers.Language; using OMI.Workers.Pck; +using PckStudio.Core.App; using PckStudio.Core.Deserializer; using PckStudio.Core.Extensions; using PckStudio.Core.Interfaces; +using PckStudio.Core.IO.PckAudio; +using PckStudio.Core.Properties; +using PckStudio.Interfaces; namespace PckStudio.Core.DLC { @@ -53,7 +57,7 @@ namespace PckStudio.Core.DLC { _platform = platform; _byteOrder = GetByteOrderForPlatform(Platform); - PreferredLanguage = GetPreferredLanguage(preferredLanguage); + SetPreferredLanguage(preferredLanguage); } private static ByteOrder GetByteOrderForPlatform(ConsolePlatform platform) @@ -71,14 +75,14 @@ namespace PckStudio.Core.DLC int identifier = _rng.Next(8000, GameConstants.MAX_PACK_ID); IDLCPackage package = packageType switch { - DLCPackageType.SkinPack => DLCSkinPackage.CreateEmpty(name, identifier), + DLCPackageType.SkinPack => DLCSkinPackage.CreateEmpty(name, identifier), DLCPackageType.TexturePack => DLCTexturePackage.CreateDefaultPackage(name, "", identifier), - DLCPackageType.MashUpPack => new DLCMashUpPackage(name, "", identifier), + DLCPackageType.MashUpPack => new DLCMashUpPackage(name, "", identifier), //! TODO: implemnt minigame dlc packages -null - DLCPackageType.MG01 => new DLCBattlePackage(name, identifier), - DLCPackageType.MG02 => new DLCMiniGamePackage(name, identifier, packageType, MiniGameId.Tumble), - DLCPackageType.MG03 => new DLCMiniGamePackage(name, identifier, packageType, MiniGameId.Glide), - DLCPackageType.Invalid => InvalidDLCPackage.Instance, + DLCPackageType.MG01 => new DLCBattlePackage(name, identifier), + DLCPackageType.MG02 => new DLCMiniGamePackage(name, identifier, packageType, MiniGameId.Tumble), + DLCPackageType.MG03 => new DLCMiniGamePackage(name, identifier, packageType, MiniGameId.Glide), + DLCPackageType.Invalid => InvalidDLCPackage.Instance, _ => throw new ArgumentException("Unable to create DLC Package of 'Unknown' type."), }; @@ -165,115 +169,158 @@ namespace PckStudio.Core.DLC bool couldBeTexturePack = fileInfo.Name == DEFAULT_TEXTURE_PACK_FILENAME; bool couldBeMiniGamePack = fileInfo.Name == DEFAULT_MINIGAME_PACK_FILENAME; - bool hasSkins = pckFile.Contains(PckAssetType.SkinFile) || pckFile.Contains(PckAssetType.SkinDataFile); - + bool hasSkins = TryGetDLCSkinPackage(name, identifier, pckFile, fileReader, out IDLCPackage skinPackage); DLCPackageType dlcPackageType = hasSkins ? DLCPackageType.SkinPack : DLCPackageType.Unknown; DirectoryInfo dataDirectoryInfo = fileInfo.Directory.EnumerateDirectories().Where(dirInfo => dirInfo.Name == DATA_DIRECTORY_NAME).FirstOrDefault(); - PckAsset texturePackInfo = pckFile.GetAssetsByType(PckAssetType.TexturePackInfoFile).FirstOrDefault(); - string dataPath = texturePackInfo is not null ? texturePackInfo.GetProperty("DATAPATH") : string.Empty; - if (dataDirectoryInfo is null) - { - return skinPackage; - } + return hasSkins ? skinPackage : InvalidDLCPackage.Instance; - if (!string.IsNullOrWhiteSpace(dataPath)) + bool hasTexturePack = TryGetTexturePack(name, description, identifier, dataDirectoryInfo, pckFile, fileReader, out IDLCPackage texturePackage); + if (hasTexturePack) { - PckFile infoPck = texturePackInfo.GetData(fileReader); - FileInfo texturePackFileInfo = dataDirectoryInfo.EnumerateFiles().Where(fileInfo => fileInfo.Name == dataPath).FirstOrDefault(); - if (IsValidPckFile(texturePackFileInfo)) - { - using Stream texturePackFileStream = texturePackFileInfo.OpenRead(); - PckFile texturePackPck = fileReader.FromStream(texturePackFileStream); - IDLCPackage texturePackage = GetTexturePackageFromPckFile(infoPck, texturePackPck); dlcPackageType = DLCPackageType.TexturePack; } - } - IEnumerable audioFiles = dataDirectoryInfo.EnumerateFiles("*.binka"); - IDictionary audios = new Dictionary(); - foreach (FileInfo audioFile in audioFiles) - { - MemoryStream dataStream = new MemoryStream(); - using (Stream audioStream = audioFile.OpenRead()) - { - audioStream.CopyTo(dataStream); - } - audios.Add(audioFile.Name, dataStream.ToArray()); - } + Dictionary> mapData = GetMapData(pckFile, dataDirectoryInfo); - IDictionary> saves = new Dictionary>(); - foreach (FileInfo worldFile in dataDirectoryInfo.EnumerateFiles("*.mcs")) + if (mapData.Count == 1) { - IDictionary save = MapReader.OpenSave(worldFile.OpenRead()); - saves.Add(worldFile.Name, save); - } - - if (pckFile.Contains("GameRules.grf", PckAssetType.GameRulesFile) && pckFile.TryGetAsset("GameRules.grf", PckAssetType.GameRulesFile, out PckAsset gameRuleAsset)) - { - GameRuleFile gameRuleFile = gameRuleAsset.GetData(new GameRuleFileReader(GetPlatformCompressionType())); dlcPackageType = DLCPackageType.MashUpPack; - } + } Debug.WriteLine(dlcPackageType); return new UnknownDLCPackage(name, pckFile); } - private GameRuleFile.CompressionType GetPlatformCompressionType() - { - switch (Platform) + private Dictionary> GetMapData(PckFile pck, DirectoryInfo dataDirectory) { - case ConsolePlatform.Xbox360: - return GameRuleFile.CompressionType.XMem; + GameRuleFile.CompressionType compressionType = GetPlatformCompressionType(); + var reader = new GameRuleFileReader(compressionType); + IEnumerable values = pck.GetAssetsByType(PckAssetType.GameRulesFile) + .Concat(pck.GetAssetsByType(PckAssetType.GameRulesHeader)) + .Select(asset => asset.GetData(reader)) + .SelectMany(grf => grf.Root.GetRules().Where(rule => rule.Name == "MapOptions" && rule.ContainsParameter("baseSaveName"))) + .Select(rule => rule.GetRule("MapOptions").GetParameterValue("baseSaveName")); - case ConsolePlatform.PS3: - return GameRuleFile.CompressionType.Deflate; - - case ConsolePlatform.XboxOne: - case ConsolePlatform.PS4: - case ConsolePlatform.PSVita: - case ConsolePlatform.WiiU: - case ConsolePlatform.Switch: - return GameRuleFile.CompressionType.Zlib; - - case ConsolePlatform.Unknown: - default: - return GameRuleFile.CompressionType.Unknown; + Dictionary> saves = new Dictionary>(); + foreach (FileInfo worldFile in dataDirectory.EnumerateFiles("*.mcs").Where(file => values.Contains(file.Name))) + { + IDictionary save = MapReader.OpenSave(worldFile.OpenRead()); + saves.Add(worldFile.Name, save); } + + return saves; } - private IDLCPackage GetTexturePackageFromPckFile(PckFile infoPck, PckFile dataPck) + private bool TryGetTexturePack(string name, string description, int identifier, DirectoryInfo dataDirectoryInfo, PckFile pckFile, PckFileReader pckFormatReader, out IDLCPackage texturePackage) + { + if (dataDirectoryInfo is null) + { + texturePackage = default; + return false; + } + PckAsset texturePackInfo = pckFile.GetAssetsByType(PckAssetType.TexturePackInfoFile).FirstOrDefault(); + if (texturePackInfo is null) + { + texturePackage = default; + return false; + } + + DLCTexturePackage.TextureResolution resolution = DLCTexturePackage.GetTextureResolutionFromString(texturePackInfo.Filename); + string dataPath = texturePackInfo.GetProperty("DATAPATH"); + + if (string.IsNullOrWhiteSpace(dataPath)) + { + texturePackage = default; + return false; + } + + PckFile infoPck = texturePackInfo.GetData(pckFormatReader); + FileInfo texturePackFileInfo = dataDirectoryInfo.EnumerateFiles().Where(fileInfo => fileInfo.Name == dataPath).FirstOrDefault(); + + if (!IsValidPckFile(texturePackFileInfo)) { + texturePackage = null; + return false; + } + + using Stream texturePackFileStream = texturePackFileInfo.OpenRead(); + PckFile texturePackPck = pckFormatReader.FromStream(texturePackFileStream); + texturePackage = GetTexturePackageFromPckFile(name, description, identifier, infoPck, texturePackPck, resolution); + + IEnumerable audioFiles = dataDirectoryInfo.EnumerateFiles("*.binka"); + IDictionary audios = new Dictionary(); + foreach (FileInfo audioFile in audioFiles) + { + byte[] data = File.ReadAllBytes(audioFile.FullName); + audios.Add(audioFile.Name, data); + } + + return texturePackage is not null; + } + + private IDLCPackage GetTexturePackageFromPckFile(string name, string description, int identifier, PckFile infoPck, PckFile dataPck, DLCTexturePackage.TextureResolution resolution) + { + if (infoPck is null || dataPck is null) + return null; + if (!infoPck.TryGetAsset("comparison.png", PckAssetType.TextureFile, out PckAsset comparisonAsset)) { Trace.TraceError($"Could not find 'comparison.png'."); - return InvalidDLCPackage.Instance; } if (!infoPck.TryGetAsset("icon.png", PckAssetType.TextureFile, out PckAsset iconnAsset)) { Trace.TraceError($"Could not find 'icon.png'."); - return InvalidDLCPackage.Instance; } - Image comparisonImg = comparisonAsset.GetTexture(); - Image iconImg = iconnAsset.GetTexture(); + Image comparisonImg = comparisonAsset?.GetTexture(); + Image iconImg = iconnAsset?.GetTexture() ?? Resources.unknown_pack; DLCTexturePackage.MetaData metaData = new DLCTexturePackage.MetaData(comparisonImg, iconImg); - bool hasTerrainAtlas = TryGetAtlasFromResourceCategory(dataPck, ResourceCategory.BlockAtlas, out Atlas terrainAtlas); - bool hasItemAtlas = TryGetAtlasFromResourceCategory(dataPck, ResourceCategory.ItemAtlas, out Atlas itemAtlas); + bool hasTerrainAtlas = TryGetAtlasFromResourceCategory(dataPck, ResourceCategory.BlockAtlas, out Atlas terrainAtlas); + bool hasItemAtlas = TryGetAtlasFromResourceCategory(dataPck, ResourceCategory.ItemAtlas, out Atlas itemAtlas); bool hasParticleAtlas = TryGetAtlasFromResourceCategory(dataPck, ResourceCategory.ParticleAtlas, out Atlas particleAtlas); bool hasPaintingAtlas = TryGetAtlasFromResourceCategory(dataPck, ResourceCategory.PaintingAtlas, out Atlas paintingAtlas); - string itemAnimationResourcePath = ResourceLocation.GetPathFromCategory(ResourceCategory.ItemAnimation); - if (dataPck != null && - dataPck.TryGetAsset(itemAnimationResourcePath + "/compass.png", PckAssetType.TextureFile, out PckAsset compassAsset) && - dataPck.TryGetAsset(itemAnimationResourcePath + "/clock.png", PckAssetType.TextureFile, out PckAsset clockAsset)) + string itemAnimationAssetPath = ResourceLocation.GetPathFromCategory(ResourceCategory.ItemAnimation); + + IPckAssetDeserializer deserializer = AnimationDeserializer.DefaultDeserializer; + Animation compassAnimation = dataPck.TryGetAsset(itemAnimationAssetPath + "/compass.png", PckAssetType.TextureFile, out PckAsset compassAsset) ? comparisonAsset.GetDeserializedData(deserializer) : Animation.CreateEmpty(); + Animation clockAnimation = dataPck.TryGetAsset(itemAnimationAssetPath + "/clock.png", PckAssetType.TextureFile, out PckAsset clockAsset) ? clockAsset.GetDeserializedData(deserializer) : Animation.CreateEmpty(); + + if (compassAnimation.FrameCount == 0) + Trace.TraceError("No compass animation found!"); + + if (clockAnimation.FrameCount == 0) + Trace.TraceError("No clock animation found!"); + + ITryGet tryGet = TryGet.FromDelegate((string path, out Image image) => { + bool success = dataPck.TryGetAsset(path, PckAssetType.TextureFile, out PckAsset asset); + image = asset?.GetTexture(); + return success; + }); + Image[] blockEntityBreakingAnimation = new Image[10]; + for (int i = 0; i < blockEntityBreakingAnimation.Length; i++) + { + if (dataPck.TryGetAsset("", PckAssetType.TextureFile, out PckAsset asset)) + blockEntityBreakingAnimation[i] = asset.GetTexture(); } - return null; + + ArmorSet[] armorSets = new ArmorSet[6] + { + ArmorSetDescription.Leather.GetArmorSet(tryGet), + ArmorSetDescription.Chain.GetArmorSet(tryGet), + ArmorSetDescription.Iron.GetArmorSet(tryGet), + ArmorSetDescription.Gold.GetArmorSet(tryGet), + ArmorSetDescription.Diamond.GetArmorSet(tryGet), + ArmorSetDescription.Turtle.GetArmorSet(tryGet) + }; + return new DLCTexturePackage(name, description, identifier, metaData, resolution, terrainAtlas, itemAtlas, particleAtlas, paintingAtlas, + armorSets, null, null, null, null, null, null, null, null); } private bool TryGetAtlasFromResourceCategory(PckFile pck, ResourceCategory resourceCategory, out Atlas atlas) @@ -289,13 +336,23 @@ namespace PckStudio.Core.DLC return true; } - private IDLCPackage GetDLCSkinPackage(string name, int identifier, PckFile pck, PckFileReader fileReader, IDLCPackage parentPackage = null) + private bool TryGetDLCSkinPackage(string name, int identifier, PckFile pck, PckFileReader fileReader, out IDLCPackage skinPackage, IDLCPackage parentPackage = null) { + if (!(pck.Contains(PckAssetType.SkinFile) || pck.Contains(PckAssetType.SkinDataFile))) + { + skinPackage = default; + return false; + } + + IDictionary capes = pck.GetAssetsByType(PckAssetType.CapeFile) + .Where(asset => asset.GetId() != -1) + .ToDictionary(PckAssetExtensions.GetId, PckAssetExtensions.GetTexture); + Skin.Skin GetSkinWithCape(PckAsset skinAsset) { Skin.Skin skin = skinAsset.GetSkin(); if (skinAsset.TryGetProperty("CAPEPATH", out string capeAssetPath) && pck.TryGetAsset(capeAssetPath, PckAssetType.CapeFile, out PckAsset capeAsset)) - skin.CapeTexture = capeAsset.GetTexture(); + skin.CapeId = capeAsset.GetId(); return skin; } @@ -307,7 +364,9 @@ namespace PckStudio.Core.DLC .Select(GetSkinWithCape) ); - return new DLCSkinPackage(name, identifier, skins, null, parentPackage); + skinPackage = new DLCSkinPackage(name, identifier, skins, capes, parentPackage); + return true; + } } private static string GetPreferredLanguage(AppLanguage appLanguage) diff --git a/PckStudio.Core/DLC/DLCMashUpPackage.cs b/PckStudio.Core/DLC/DLCMashUpPackage.cs index fadd82cc..5f8f022a 100644 --- a/PckStudio.Core/DLC/DLCMashUpPackage.cs +++ b/PckStudio.Core/DLC/DLCMashUpPackage.cs @@ -15,6 +15,8 @@ namespace PckStudio.Core.DLC public sealed class DLCMashUpPackage : DLCPackage { public override string Description { get; } + private AbstractGameRule _gameRule { get; } + public bool HasAudioData => _pckAudio is not null && _audioData.Count > 0; private IDLCPackage _skinPackage; private IDLCPackage _texturePackage; @@ -22,16 +24,17 @@ namespace PckStudio.Core.DLC private IDictionary _audioData; private PckAudioFile _pckAudio; - internal DLCMashUpPackage(string name, string description, int identifier, IDLCPackageSerialization packageInfo, AbstractGameRule gameRule, IDLCPackage parentPackage, IDLCPackage skinPackage = null, IDLCPackage texturePackage = null) - : base(name, identifier, packageInfo, parentPackage) + internal DLCMashUpPackage(string name, string description, int identifier, AbstractGameRule gameRule, IDLCPackage parentPackage, IDLCPackage skinPackage = null, IDLCPackage texturePackage = null) + : base(name, identifier, parentPackage) { Description = description; + _gameRule = gameRule; _skinPackage = skinPackage; _texturePackage = texturePackage; } internal DLCMashUpPackage(string name, string description, int identifier) - : this(name, description, identifier, null, new RootGameRule(), null) + : this(name, description, identifier, new RootGameRule(), null) { _skinPackage = DLCSkinPackage.CreateEmpty(this); _texturePackage = DLCTexturePackage.CreateDefaultPackage(this); @@ -41,7 +44,11 @@ namespace PckStudio.Core.DLC public IDLCPackage GetSkinPackage() => _skinPackage; public IDLCPackage GetTexturePackage() => _texturePackage; + public AbstractGameRule GetGameRule() => _gameRule; + public PckAudioFile GetAudioPack() => _pckAudio; public override DLCPackageType GetDLCPackageType() => DLCPackageType.MashUpPack; + + internal NamedData[] GetAudioFiles() => _audioData.Select(kv => new NamedData(kv.Key, kv.Value)).ToArray(); } } diff --git a/PckStudio.Core/DLC/DLCMiniGamePackage.cs b/PckStudio.Core/DLC/DLCMiniGamePackage.cs index 16e432cf..336b8bd0 100644 --- a/PckStudio.Core/DLC/DLCMiniGamePackage.cs +++ b/PckStudio.Core/DLC/DLCMiniGamePackage.cs @@ -14,8 +14,8 @@ namespace PckStudio.Core.DLC private readonly DLCPackageType _packageType; private readonly MiniGameId _miniGameId; - public DLCMiniGamePackage(string name, int identifier, DLCPackageType packageType, MiniGameId miniGameId, IDLCPackageSerialization packageInfo = null, IDLCPackage parentPackage = null) - : base(name, identifier, packageInfo, parentPackage) + public DLCMiniGamePackage(string name, int identifier, DLCPackageType packageType, MiniGameId miniGameId, IDLCPackage parentPackage = null) + : base(name, identifier, parentPackage) { _packageType = packageType; _miniGameId = miniGameId; diff --git a/PckStudio.Core/DLC/DLCPackage.cs b/PckStudio.Core/DLC/DLCPackage.cs index cea12ced..c9d4e8c2 100644 --- a/PckStudio.Core/DLC/DLCPackage.cs +++ b/PckStudio.Core/DLC/DLCPackage.cs @@ -10,18 +10,15 @@ namespace PckStudio.Core.DLC { public abstract class DLCPackage : IDLCPackage { - protected DLCPackage(string name, int identifier, IDLCPackageSerialization packageInfo, IDLCPackage parentPackage) + protected DLCPackage(string name, int identifier, IDLCPackage parentPackage) { Name = name; Identifier = identifier; - PackageInfo = packageInfo; ParentPackage = parentPackage; } public int Identifier { get; } - public IDLCPackageSerialization PackageInfo { get; } - public string Name { get; } = string.Empty; public virtual string Description { get; } = string.Empty; diff --git a/PckStudio.Core/DLC/DLCPackageType.cs b/PckStudio.Core/DLC/DLCPackageType.cs index 8f3fb69e..c7a41062 100644 --- a/PckStudio.Core/DLC/DLCPackageType.cs +++ b/PckStudio.Core/DLC/DLCPackageType.cs @@ -1,13 +1,13 @@ namespace PckStudio.Core.DLC { - public enum DLCPackageType + public enum DLCPackageType : int { Unknown = -1, Invalid, SkinPack, TexturePack, MashUpPack, - //! TODO: Add DLCPackage class for minigames... -null + MG01, MG02, MG03, diff --git a/PckStudio.Core/DLC/DLCSkinPackage.cs b/PckStudio.Core/DLC/DLCSkinPackage.cs index 8c13bd45..9adb9397 100644 --- a/PckStudio.Core/DLC/DLCSkinPackage.cs +++ b/PckStudio.Core/DLC/DLCSkinPackage.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Drawing; using System.IO; using System.Linq; using PckStudio.Core.Interfaces; @@ -18,16 +19,18 @@ namespace PckStudio.Core.DLC { public DLCSkinPackageOrder SkinPackageOrder { get; set; } = DLCSkinPackageOrder.CapesFirst; - private readonly Dictionary _skins; + private readonly IDictionary _capes; + private readonly IDictionary _skins; - internal DLCSkinPackage(string name, int identifier, IEnumerable skins, IDLCPackageSerialization packageInfo, IDLCPackage parentPackage) - : base(name, identifier, packageInfo, parentPackage) + internal DLCSkinPackage(string name, int identifier, IEnumerable skins, IDictionary capes, IDLCPackage parentPackage) + : base(name, identifier, parentPackage) { _skins = skins.ToDictionary(skin => skin.Identifier); + _capes = capes; } internal DLCSkinPackage(string name, int identifier, IDLCPackage parentPackage = null) - : this(name, identifier, Enumerable.Empty(), null, parentPackage) + : this(name, identifier, Enumerable.Empty(), new Dictionary(), parentPackage) { } @@ -38,7 +41,10 @@ namespace PckStudio.Core.DLC public bool ContainsSkin(SkinIdentifier skinIdentifier) => _skins.ContainsKey(skinIdentifier); - public void AddSkin(Skin.Skin skin) => _skins.Add(skin.Identifier, skin); + public void AddSkin(Skin.Skin skin) + { + _skins.Add(skin.Identifier, skin); + } public bool RemoveSkin(SkinIdentifier skinIdentifier) => _skins.Remove(skinIdentifier); @@ -47,5 +53,7 @@ namespace PckStudio.Core.DLC public IReadOnlyCollection GetSkins() => _skins.Values.Cast().ToArray(); public override DLCPackageType GetDLCPackageType() => DLCPackageType.SkinPack; + + internal KeyValuePair[] GetCapes() => _capes.ToArray(); } } \ No newline at end of file diff --git a/PckStudio.Core/DLC/DLCTexturePackage.cs b/PckStudio.Core/DLC/DLCTexturePackage.cs index 9331d743..244d7a1e 100644 --- a/PckStudio.Core/DLC/DLCTexturePackage.cs +++ b/PckStudio.Core/DLC/DLCTexturePackage.cs @@ -11,6 +11,7 @@ using OMI.Formats.Material; using OMI.Formats.Model; using OMI.Formats.Pck; using OMI.Workers.Color; +using PckStudio.Core.Extensions; using PckStudio.Core.Interfaces; using PckStudio.Core.Properties; @@ -36,17 +37,17 @@ namespace PckStudio.Core.DLC private TextureResolution _resolution; - //! Data for x{_resolution}Info.pck - public sealed class MetaData + public sealed class MetaData(Image comparisonImg, Image iconImg) { - public Image ComparisonImg { get; } - public Image IconImg { get; } + public Image ComparisonImg { get; } = comparisonImg; + public Image IconImg { get; } = iconImg; + } - public MetaData(Image comparisonImg, Image iconImg) - { - ComparisonImg = comparisonImg; - IconImg = iconImg; - } + public sealed class EnvironmentData + { + public Image Clouds; + public Image Rain; + public Image Snow; } public MetaData Info { get; } @@ -55,16 +56,18 @@ namespace PckStudio.Core.DLC //! => colours.col private IDictionary _colors; private IDictionary _waterColors; - private ModelContainer _customModels; //! => models.bin - private MaterialContainer _materials; + private ModelContainer _customModels; //! can be null.. => models.bin + private MaterialContainer _materials; //! can be null.. //! terrain mipmaps will be generated automatically. Add mipmap option to settings menu ? -null private Atlas _terrainAtlas; private Atlas _itemsAtlas; private Atlas _particlesAtlas; private Atlas _paintingAtlas; + private ArmorSet[] _armorSets = new ArmorSet[6]; + private EnvironmentData _environmentData; - private Image[] _blockEntityBreakImages; //! max = 10! + private Animation _blockEntityBreakAnimation; private IDictionary _itemAnimations; private IDictionary _blockAnimations; @@ -78,17 +81,17 @@ namespace PckStudio.Core.DLC Atlas itemsAtlas, Atlas particlesAtlas, Atlas paintingAtlas, + ArmorSet[] armorSets, IDictionary colors, IDictionary waterColors, ModelContainer customModels, MaterialContainer materials, - Image[] blockEntityBreakImages, + Animation blockEntityBreakAnimation, IDictionary itemAnimations, IDictionary blockAnimations, - IDLCPackageSerialization packageInfo, IDLCPackage parentPackage ) - : base(name, identifier, packageInfo, parentPackage) + : base(name, identifier, parentPackage) { Description = description; Info = metaData; @@ -97,16 +100,56 @@ namespace PckStudio.Core.DLC _itemsAtlas = itemsAtlas; _particlesAtlas = particlesAtlas; _paintingAtlas = paintingAtlas; + _armorSets = armorSets; _colors = colors; _waterColors = waterColors; _customModels = customModels; _materials = materials; - _blockEntityBreakImages = blockEntityBreakImages; + _blockEntityBreakAnimation = blockEntityBreakAnimation; _itemAnimations = itemAnimations; _blockAnimations = blockAnimations; } public TextureResolution GetResolution() => _resolution; + public Size GetTextureSize() => GetTextureSize(_resolution); + public static Size GetTextureSize(TextureResolution resolution) + { + return resolution switch + { + TextureResolution.x8 => new Size(8, 8), + TextureResolution.x16 => new Size(16, 16), + TextureResolution.x32 => new Size(32, 32), + TextureResolution.x48 => new Size(48, 48), + TextureResolution.x64 => new Size(64, 64), + TextureResolution.x80 => new Size(80, 80), + TextureResolution.x96 => new Size(96, 96), + TextureResolution.x112 => new Size(112, 112), + TextureResolution.x128 => new Size(128, 128), + _ => Size.Empty + }; + } + + public static TextureResolution GetTextureResolutionFromString(string input) + { + _ = input ?? throw new ArgumentNullException(nameof(input)); + input = input.ToLower(); + var a = input.Split('/'); + if (a.Length == 2 && Enum.TryParse(a[0], true, out TextureResolution resolution)) + return resolution; + + if (input[0] == 'x') + { + int i = 1; + char c; + do + { + c = input[i++]; + } while (char.IsDigit(c) && i < input.Length); + if (Enum.TryParse(input.Substring(0, i), true, out resolution)) + return resolution; + } + throw new ArgumentException("Invalid input string: " + input); + } public override DLCPackageType GetDLCPackageType() => DLCPackageType.TexturePack; @@ -116,27 +159,76 @@ namespace PckStudio.Core.DLC internal static IDLCPackage CreateDefaultPackage(string name, string description, int identifier, IDLCPackage parentPackage = null) { TextureResolution resolution = TextureResolution.x16; + MetaData metadata = new MetaData(Resources.Comparison, Resources.TexturePackIcon); - Atlas terrain = Atlas.FromResourceLocation(Resources.terrain_atlas , ResourceLocation.GetFromCategory(ResourceCategory.BlockAtlas)); - Atlas items = Atlas.FromResourceLocation(Resources.items_atlas , ResourceLocation.GetFromCategory(ResourceCategory.ItemAtlas)); + Atlas terrain = Atlas.FromResourceLocation(Resources.terrain_atlas, ResourceLocation.GetFromCategory(ResourceCategory.BlockAtlas)); + Atlas items = Atlas.FromResourceLocation(Resources.items_atlas, ResourceLocation.GetFromCategory(ResourceCategory.ItemAtlas)); Atlas particles = Atlas.FromResourceLocation(Resources.particles_atlas, ResourceLocation.GetFromCategory(ResourceCategory.ParticleAtlas)); - Atlas painting = Atlas.FromResourceLocation(Resources.paintings_atlas, ResourceLocation.GetFromCategory(ResourceCategory.PaintingAtlas)); + Atlas painting = Atlas.FromResourceLocation(Resources.paintings_atlas, ResourceLocation.GetFromCategory(ResourceCategory.PaintingAtlas)); //ColorContainer colors = new COLFileReader().FromStream(new MemoryStream()); IDictionary colors = null; IDictionary waterColors = null; - Image[] blockEntityBreakImages = terrain.GetRange(0, 15, 10, ImageLayoutDirection.Horizontal).Select(t => t.Texture).ToArray(); + + Animation blockEntityBreakAnimation = new Animation(terrain.GetRange(0, 15, 10, ImageLayoutDirection.Horizontal).Select(t => t.Texture).ToArray(), true, 3); + + ArmorSet[] armorSets = GetArmorSets(); + + IDictionary itemAnimations = GetItemAnimations(); + + IDictionary blockAnimations = GetBlockAnimations(); return new DLCTexturePackage( name, description, identifier, metadata, resolution, terrain, items, particles, painting, + armorSets, colors, waterColors, new ModelContainer(), new MaterialContainer(), - blockEntityBreakImages, - null, null, - null, parentPackage + blockEntityBreakAnimation, + itemAnimations, + blockAnimations, + parentPackage ); } + + internal Atlas GetTerrainAtlas() => _terrainAtlas; + + internal Atlas GetItemsAtlas() => _itemsAtlas; + + internal Atlas GetParticleAtlas() => _particlesAtlas; + + internal Atlas GetPaintingAtlas() => _paintingAtlas; + + private static ArmorSet[] GetArmorSets() + { + return new ArmorSet[6] + { + new ArmorSet(ArmorSetDescription.CLOTH, Resources.cloth, Resources.cloth_b), + new ArmorSet(ArmorSetDescription.CHAIN, Resources.chain, default), + new ArmorSet(ArmorSetDescription.IRON, Resources.iron, default), + new ArmorSet(ArmorSetDescription.GOLD, Resources.gold, default), + new ArmorSet(ArmorSetDescription.DIAMOND, Resources.diamond, default), + new ArmorSet(ArmorSetDescription.TURTLE, Resources.turtle, default) + }; + } + + private static IDictionary GetItemAnimations() + { + return new Dictionary() + { + ["clock"] = new Animation(Resources.clock.Split(ImageLayoutDirection.Vertical), true), + ["compass"] = new Animation(Resources.compass.Split(ImageLayoutDirection.Vertical), true), + }; + } + + private static IDictionary GetBlockAnimations() + { + return new Dictionary() + { + ["fire_0"] = new Animation(Resources.fire_layer_0.Split(ImageLayoutDirection.Vertical), true), + ["fire_1"] = new Animation(Resources.fire_layer_1.Split(ImageLayoutDirection.Vertical), true) + }; + } } } \ No newline at end of file diff --git a/PckStudio.Core/DLC/InvalidDLCPackage.cs b/PckStudio.Core/DLC/InvalidDLCPackage.cs index 1eee2c4d..14c7a9dd 100644 --- a/PckStudio.Core/DLC/InvalidDLCPackage.cs +++ b/PckStudio.Core/DLC/InvalidDLCPackage.cs @@ -12,13 +12,13 @@ namespace PckStudio.Core.DLC { internal static IDLCPackage Instance { get; } = new InvalidDLCPackage(); - private InvalidDLCPackage(string name, int identifier, IDLCPackageSerialization packageInfo, IDLCPackage parentPackage) - : base(name, identifier, packageInfo, parentPackage) + private InvalidDLCPackage(string name, int identifier, IDLCPackage parentPackage) + : base(name, identifier, parentPackage) { } private InvalidDLCPackage() - : this(nameof(InvalidDLCPackage), -1, null, null) + : this(nameof(InvalidDLCPackage), -1, null) { } diff --git a/PckStudio.Core/DLC/UnknownDLCPackage.cs b/PckStudio.Core/DLC/UnknownDLCPackage.cs index f86e4fc6..1184e5e3 100644 --- a/PckStudio.Core/DLC/UnknownDLCPackage.cs +++ b/PckStudio.Core/DLC/UnknownDLCPackage.cs @@ -13,7 +13,7 @@ namespace PckStudio.Core.DLC public PckFile PckFile { get; } public UnknownDLCPackage(string name, PckFile pckFile) - : base(name ?? nameof(UnknownDLCPackage), -1, default, default) + : base(name ?? nameof(UnknownDLCPackage), -1, default) { PckFile = pckFile; } diff --git a/PckStudio.Core/Interfaces/IDLCPackage.cs b/PckStudio.Core/Interfaces/IDLCPackage.cs index addd4a1d..d5de6f02 100644 --- a/PckStudio.Core/Interfaces/IDLCPackage.cs +++ b/PckStudio.Core/Interfaces/IDLCPackage.cs @@ -8,8 +8,6 @@ bool IsRootPackage { get; } - IDLCPackageSerialization PackageInfo { get; } - DLC.DLCPackageType GetDLCPackageType(); IDLCPackage ParentPackage { get; }