mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/PCK-Studio.git
synced 2026-06-05 14:57:08 +00:00
Core(DLCManager) - Upate type scanning
This commit is contained in:
@@ -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<FileInfo> audioFiles = dataDirectoryInfo.EnumerateFiles("*.binka");
|
||||
IDictionary<string, byte[]> audios = new Dictionary<string, byte[]>();
|
||||
foreach (FileInfo audioFile in audioFiles)
|
||||
{
|
||||
MemoryStream dataStream = new MemoryStream();
|
||||
using (Stream audioStream = audioFile.OpenRead())
|
||||
{
|
||||
audioStream.CopyTo(dataStream);
|
||||
}
|
||||
audios.Add(audioFile.Name, dataStream.ToArray());
|
||||
}
|
||||
Dictionary<string, IDictionary<string, byte[]>> mapData = GetMapData(pckFile, dataDirectoryInfo);
|
||||
|
||||
IDictionary<string, IDictionary<string, byte[]>> saves = new Dictionary<string, IDictionary<string, byte[]>>();
|
||||
foreach (FileInfo worldFile in dataDirectoryInfo.EnumerateFiles("*.mcs"))
|
||||
if (mapData.Count == 1)
|
||||
{
|
||||
IDictionary<string, byte[]> 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<string, IDictionary<string, byte[]>> GetMapData(PckFile pck, DirectoryInfo dataDirectory)
|
||||
{
|
||||
case ConsolePlatform.Xbox360:
|
||||
return GameRuleFile.CompressionType.XMem;
|
||||
GameRuleFile.CompressionType compressionType = GetPlatformCompressionType();
|
||||
var reader = new GameRuleFileReader(compressionType);
|
||||
IEnumerable<string> 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<string, IDictionary<string, byte[]>> saves = new Dictionary<string, IDictionary<string, byte[]>>();
|
||||
foreach (FileInfo worldFile in dataDirectory.EnumerateFiles("*.mcs").Where(file => values.Contains(file.Name)))
|
||||
{
|
||||
IDictionary<string, byte[]> 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<FileInfo> audioFiles = dataDirectoryInfo.EnumerateFiles("*.binka");
|
||||
IDictionary<string, byte[]> audios = new Dictionary<string, byte[]>();
|
||||
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<Animation> 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<string, Image> tryGet = TryGet<string, Image>.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<int, Image> 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)
|
||||
|
||||
@@ -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<string, byte[]> _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<byte[]>[] GetAudioFiles() => _audioData.Select(kv => new NamedData<byte[]>(kv.Key, kv.Value)).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<SkinIdentifier, Skin.Skin> _skins;
|
||||
private readonly IDictionary<int, Image> _capes;
|
||||
private readonly IDictionary<SkinIdentifier, Skin.Skin> _skins;
|
||||
|
||||
internal DLCSkinPackage(string name, int identifier, IEnumerable<Skin.Skin> skins, IDLCPackageSerialization packageInfo, IDLCPackage parentPackage)
|
||||
: base(name, identifier, packageInfo, parentPackage)
|
||||
internal DLCSkinPackage(string name, int identifier, IEnumerable<Skin.Skin> skins, IDictionary<int, Image> 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<Skin.Skin>(), null, parentPackage)
|
||||
: this(name, identifier, Enumerable.Empty<Skin.Skin>(), new Dictionary<int, Image>(), 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<Skin.Skin> GetSkins() => _skins.Values.Cast<Skin.Skin>().ToArray();
|
||||
|
||||
public override DLCPackageType GetDLCPackageType() => DLCPackageType.SkinPack;
|
||||
|
||||
internal KeyValuePair<int, Image>[] GetCapes() => _capes.ToArray();
|
||||
}
|
||||
}
|
||||
@@ -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<string, Color> _colors;
|
||||
private IDictionary<string, (Color surface, Color underwater, Color fog)> _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<string, Animation> _itemAnimations;
|
||||
private IDictionary<string, Animation> _blockAnimations;
|
||||
|
||||
@@ -78,17 +81,17 @@ namespace PckStudio.Core.DLC
|
||||
Atlas itemsAtlas,
|
||||
Atlas particlesAtlas,
|
||||
Atlas paintingAtlas,
|
||||
ArmorSet[] armorSets,
|
||||
IDictionary<string, Color> colors,
|
||||
IDictionary<string, (Color surface, Color underwater, Color fog)> waterColors,
|
||||
ModelContainer customModels,
|
||||
MaterialContainer materials,
|
||||
Image[] blockEntityBreakImages,
|
||||
Animation blockEntityBreakAnimation,
|
||||
IDictionary<string, Animation> itemAnimations,
|
||||
IDictionary<string, Animation> 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<string, Color> colors = null;
|
||||
IDictionary<string, (Color, Color, Color)> 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<string, Animation> itemAnimations = GetItemAnimations();
|
||||
|
||||
IDictionary<string, Animation> 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<string, Animation> GetItemAnimations()
|
||||
{
|
||||
return new Dictionary<string, Animation>()
|
||||
{
|
||||
["clock"] = new Animation(Resources.clock.Split(ImageLayoutDirection.Vertical), true),
|
||||
["compass"] = new Animation(Resources.compass.Split(ImageLayoutDirection.Vertical), true),
|
||||
};
|
||||
}
|
||||
|
||||
private static IDictionary<string, Animation> GetBlockAnimations()
|
||||
{
|
||||
return new Dictionary<string, Animation>()
|
||||
{
|
||||
["fire_0"] = new Animation(Resources.fire_layer_0.Split(ImageLayoutDirection.Vertical), true),
|
||||
["fire_1"] = new Animation(Resources.fire_layer_1.Split(ImageLayoutDirection.Vertical), true)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
|
||||
bool IsRootPackage { get; }
|
||||
|
||||
IDLCPackageSerialization PackageInfo { get; }
|
||||
|
||||
DLC.DLCPackageType GetDLCPackageType();
|
||||
|
||||
IDLCPackage ParentPackage { get; }
|
||||
|
||||
Reference in New Issue
Block a user