using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using OMI.Formats.Archive; using OMI.Formats.Color; using PckStudio.Core.Colors; using PckStudio.Core.Extensions; using PckStudio.Core.Interfaces; using PckStudio.Core.Model; using PckStudio.Core.Properties; namespace PckStudio.Core.DLC { public sealed class DLCTexturePackage : DLCPackage { public enum TextureResolution { x8, x16, x32, x48, x64, x80, x96, x112, x128 } public override string Description { get; } internal const string TEXTUREPACK_DESCRIPTION_ID = "IDS_TP_DESCRIPTION"; private TextureResolution _resolution; public sealed class MetaData(Image comparisonImg, Image iconImg) { public Image ComparisonImg { get; } = comparisonImg; public Image IconImg { get; } = iconImg; } public sealed class EnvironmentData(Image clouds, Image rain, Image snow) { public Image Clouds = clouds; public Image Rain = rain; public Image Snow = snow; } public MetaData Info { get; } private AbstractColorContainer _colorContainter; private AbstractModelContainer _customModels; //! can be null.. => models.bin private IDictionary _materials; //! can be null.. private IDictionary _itemModelTextures; //! can be null.. private IDictionary _mobModelTextures; //! can be null.. private Atlas _terrainAtlas; private Atlas _itemsAtlas; private Atlas _particlesAtlas; private Atlas _paintingAtlas; private Atlas _moonPhaseAtlas; private Atlas _mapIconsAtlas; private Atlas _additionalMapIconsAtlas; private ArmorSet _leatherArmorSet; private ArmorSet _chainArmorSet; private ArmorSet _ironArmorSet; private ArmorSet _goldArmorSet; private ArmorSet _diamondArmorSet; private ArmorSet _turtleArmorSet; private EnvironmentData _environmentData; private ConsoleArchive _mediaArc; private Animation _blockEntityBreakAnimation; private IDictionary _itemAnimations; private IDictionary _blockAnimations; private Image _sun; private Image _moon; //! TODO: add resources from "res/misc/" private readonly IDictionary _misc; public DLCTexturePackage( string name, string description, int identifier, MetaData metaData, TextureResolution resolution, Atlas terrainAtlas, Atlas itemsAtlas, Atlas particlesAtlas, Atlas paintingAtlas, Atlas moonPhaseAtlas, Atlas mapIconsAtlas, Atlas additionalMapIconsAtlas, ArmorSet leatherArmorSet, ArmorSet chainArmorSet, ArmorSet ironArmorSet, ArmorSet goldArmorSet, ArmorSet diamondArmorSet, ArmorSet turtleArmorSet, EnvironmentData environmentData, AbstractColorContainer colorContainter, IDictionary itemModelTextures, IDictionary mobModelTextures, AbstractModelContainer customModels, IDictionary materials, Animation blockEntityBreakAnimation, IDictionary itemAnimations, IDictionary blockAnimations, Image sun, Image moon, ConsoleArchive mediaArc, IDictionary misc, IDLCPackage parentPackage) : base(name, identifier, parentPackage) { Description = description; Info = metaData; _resolution = resolution; _terrainAtlas = terrainAtlas; _itemsAtlas = itemsAtlas; _particlesAtlas = particlesAtlas; _paintingAtlas = paintingAtlas; _moonPhaseAtlas = moonPhaseAtlas; _mapIconsAtlas = mapIconsAtlas; _additionalMapIconsAtlas = additionalMapIconsAtlas; _leatherArmorSet = leatherArmorSet; _chainArmorSet = chainArmorSet; _ironArmorSet = ironArmorSet; _goldArmorSet = goldArmorSet; _diamondArmorSet = diamondArmorSet; _turtleArmorSet = turtleArmorSet; _environmentData = environmentData; _colorContainter = colorContainter; _customModels = customModels; _materials = materials; _blockEntityBreakAnimation = blockEntityBreakAnimation ?? new Animation(terrainAtlas.GetRange(0, 15, 10, ImageLayoutDirection.Horizontal).Select(t => t.Texture).ToArray(), true); _itemAnimations = itemAnimations ?? new Dictionary(); _blockAnimations = blockAnimations ?? new Dictionary(); _sun = sun; _moon = moon ?? moonPhaseAtlas?[0]?.Texture ?? default; foreach (KeyValuePair item in GetDefaultItemAnimations()) { if (!_itemAnimations.ContainsKey(item.Key)) _itemAnimations.Add(item); } foreach (KeyValuePair item in GetDefaultBlockAnimations()) { if (!_blockAnimations.ContainsKey(item.Key)) _blockAnimations.Add(item); } _itemModelTextures = itemModelTextures; _mobModelTextures = mobModelTextures; _mediaArc = mediaArc; _misc = misc; SetTextureSizeForResolution(); } private void SetTextureSizeForResolution() { Size size = GetTextureSize(); Atlas[] atlases = [_terrainAtlas, _itemsAtlas, _particlesAtlas, _paintingAtlas]; foreach (Atlas item in atlases) { item?.SetTileSize(size); } _blockEntityBreakAnimation.Resize(size); foreach (KeyValuePair item in _itemAnimations) { item.Value.Resize(size); } foreach (KeyValuePair item in _blockAnimations) { item.Value.Resize(size); } } 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 GetTextureResolution(Size size) { return size switch { { Width: 8, Height: 8 } => TextureResolution.x8, { Width: 16, Height: 16 } => TextureResolution.x16, { Width: 32, Height: 32 } => TextureResolution.x32, { Width: 48, Height: 48 } => TextureResolution.x48, { Width: 64, Height: 64 } => TextureResolution.x64, { Width: 80, Height: 80 } => TextureResolution.x80, { Width: 96, Height: 96 } => TextureResolution.x96, { Width: 112, Height: 112 } => TextureResolution.x112, { Width: 128, Height: 128 } => TextureResolution.x128, _ => TextureResolution.x16 }; } 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; internal static IDLCPackage CreateDefaultPackage(IDLCPackage parentPackage) => CreateDefaultPackage(parentPackage.Name, parentPackage.Description, parentPackage.Identifier, parentPackage); 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 = AtlasResource.Get(AtlasResource.AtlasType.BlockAtlas).GetDefaultAtlas(); Atlas items = AtlasResource.Get(AtlasResource.AtlasType.ItemAtlas).GetDefaultAtlas(); Atlas particles = AtlasResource.Get(AtlasResource.AtlasType.ParticleAtlas).GetDefaultAtlas(); Atlas painting = AtlasResource.Get(AtlasResource.AtlasType.PaintingAtlas).GetDefaultAtlas(); Atlas moonPhases = AtlasResource.Get(AtlasResource.AtlasType.MoonPhaseAtlas).GetDefaultAtlas(); Atlas mapIconsAtlas = AtlasResource.Get(AtlasResource.AtlasType.MapIconAtlas).GetDefaultAtlas(); Atlas additionalMapIconsAtlas = Atlas.FromResourceLocation(Resources.additional_map_icons_atlas, ResourceLocation.GetFromCategory(AtlasResource.GetId(AtlasResource.AtlasType.AdditionalMapIconsAtlas))); //ColorContainer colors = new COLFileReader().FromStream(new MemoryStream()); IDictionary colors = null; IDictionary waterColors = null; Animation blockEntityBreakAnimation = new Animation(terrain.GetRange(0, 15, 10, ImageLayoutDirection.Horizontal).Select(t => t.Texture).ToArray(), true, 3); IDictionary itemAnimations = GetDefaultItemAnimations(); IDictionary blockAnimations = GetDefaultBlockAnimations(); return new DLCTexturePackage( name, description, identifier, metadata, resolution, terrain, items, particles, painting, moonPhases, mapIconsAtlas, additionalMapIconsAtlas, 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), new EnvironmentData(Resources.clouds, Resources.rain, Resources.snow), new AbstractColorContainer(colors, waterColors), itemModelTextures: null, mobModelTextures: null, customModels: new AbstractModelContainer(), materials: new Dictionary(), blockEntityBreakAnimation: blockEntityBreakAnimation, itemAnimations: itemAnimations, blockAnimations: blockAnimations, sun: null, moon: null, mediaArc: null, misc: null, parentPackage: parentPackage ); } internal Atlas GetTerrainAtlas() => _terrainAtlas ?? AtlasResource.Get(AtlasResource.AtlasType.BlockAtlas).GetDefaultAtlas(); internal Atlas GetItemsAtlas() => _itemsAtlas ?? AtlasResource.Get(AtlasResource.AtlasType.ItemAtlas).GetDefaultAtlas(); internal Atlas GetParticleAtlas() => _particlesAtlas ?? AtlasResource.Get(AtlasResource.AtlasType.ParticleAtlas).GetDefaultAtlas(); internal Atlas GetPaintingAtlas() => _paintingAtlas ?? AtlasResource.Get(AtlasResource.AtlasType.PaintingAtlas).GetDefaultAtlas(); internal Atlas GetMoonPhaseAtlas() => _moonPhaseAtlas ?? AtlasResource.Get(AtlasResource.AtlasType.MoonPhaseAtlas).GetDefaultAtlas(); internal IDictionary GetItemAnimations() => _itemAnimations; internal IDictionary GetBlockAnimations() => _blockAnimations; internal IEnumerable GetArmorSets() => new ArmorSet[] { _leatherArmorSet, _chainArmorSet, _ironArmorSet, _goldArmorSet, _diamondArmorSet, _turtleArmorSet }.Where(armorSet => armorSet is not null); internal Animation GetBlockEntityBreakAnimation() => _blockEntityBreakAnimation; internal ConsoleArchive GetMediaArc() => _mediaArc; internal EnvironmentData GetEnvironmentData() => _environmentData; private static IDictionary GetDefaultItemAnimations() { return new Dictionary() { ["clock"] = new Animation(Resources.clock.Split(ImageLayoutDirection.Vertical), true), ["compass"] = new Animation(Resources.compass.Split(ImageLayoutDirection.Vertical), true), }; } private static IDictionary GetDefaultBlockAnimations() { 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) }; } internal Image GetSunTexture() => _sun; internal Image GetMoonTexture() => _moon; internal IEnumerable> GetItemModelTextures() => _itemModelTextures; internal IEnumerable> GetMobModelTextures() => _mobModelTextures; internal IDictionary GetMisc() => _misc; } }