Initial work

This commit is contained in:
miku-666
2025-11-09 09:48:13 +01:00
parent 28413912b4
commit 39b1df7c6d
20 changed files with 765 additions and 70 deletions

View File

@@ -722,9 +722,9 @@ namespace PckStudio.Controls
if (EditorValue is not null &&
TryGetLocFile(out LOCFile locfile) &&
locfile.HasLocEntry("IDS_DISPLAY_NAME") &&
locfile.Languages.Contains("en-EN"))
locfile.Languages.Contains(DLCManager.Default.PreferredLanguage))
{
RPC.SetPresence("Editing a Pack:", $" > {locfile.GetLocEntry("IDS_DISPLAY_NAME", "en-EN")}");
RPC.SetPresence("Editing a Pack:", $" > {locfile.GetLocEntry("IDS_DISPLAY_NAME", DLCManager.Default.PreferredLanguage)}");
return;
}
// default

View File

@@ -86,16 +86,6 @@
//
this.resolutionComboBox.FormattingEnabled = true;
resources.ApplyResources(this.resolutionComboBox, "resolutionComboBox");
this.resolutionComboBox.Items.AddRange(new object[] {
resources.GetString("resolutionComboBox.Items"),
resources.GetString("resolutionComboBox.Items1"),
resources.GetString("resolutionComboBox.Items2"),
resources.GetString("resolutionComboBox.Items3"),
resources.GetString("resolutionComboBox.Items4"),
resources.GetString("resolutionComboBox.Items5"),
resources.GetString("resolutionComboBox.Items6"),
resources.GetString("resolutionComboBox.Items7"),
resources.GetString("resolutionComboBox.Items8")});
this.resolutionComboBox.Name = "resolutionComboBox";
this.resolutionComboBox.Style = MetroFramework.MetroColorStyle.Silver;
this.resolutionComboBox.Theme = MetroFramework.MetroThemeStyle.Dark;

View File

@@ -1,6 +1,7 @@
using System;
using System.Windows.Forms;
using MetroFramework.Forms;
using PckStudio.Core;
namespace PckStudio
{
@@ -16,6 +17,7 @@ namespace PckStudio
public CreateTexturePackPrompt()
{
InitializeComponent();
resolutionComboBox.Items.AddRange(Enum.GetNames(typeof(DLCTexturePackage.TextureResolution)));
}
private void OKBtn_Click(object sender, EventArgs e)

View File

@@ -213,33 +213,6 @@
<data name="resolutionComboBox.ItemHeight" type="System.Int32, mscorlib">
<value>23</value>
</data>
<data name="resolutionComboBox.Items" xml:space="preserve">
<value>x8</value>
</data>
<data name="resolutionComboBox.Items1" xml:space="preserve">
<value>x16</value>
</data>
<data name="resolutionComboBox.Items2" xml:space="preserve">
<value>x32</value>
</data>
<data name="resolutionComboBox.Items3" xml:space="preserve">
<value>x48</value>
</data>
<data name="resolutionComboBox.Items4" xml:space="preserve">
<value>x64</value>
</data>
<data name="resolutionComboBox.Items5" xml:space="preserve">
<value>x80</value>
</data>
<data name="resolutionComboBox.Items6" xml:space="preserve">
<value>x96</value>
</data>
<data name="resolutionComboBox.Items7" xml:space="preserve">
<value>x112</value>
</data>
<data name="resolutionComboBox.Items8" xml:space="preserve">
<value>x128</value>
</data>
<data name="resolutionComboBox.Location" type="System.Drawing.Point, System.Drawing">
<value>76, 40</value>
</data>

View File

@@ -37,8 +37,10 @@ namespace PckStudio
public MainForm()
{
InitializeComponent();
Text = Application.ProductName;
#if DEBUG
DLCManager.Default.Platform = ConsolePlatform.WiiU;
#endif
Text = Application.ProductName;
labelVersion.Text = $"{Application.ProductName}: {ApplicationScope.CurrentVersion}";
@@ -57,6 +59,8 @@ namespace PckStudio
public void LoadPckFromFile(string filepath)
{
Core.Interfaces.IDLCPackage dlcPackage = DLCManager.Default.OpenDLCPackage(filepath);
Debug.WriteLine(dlcPackage?.GetDLCPackageType());
AddEditorPage(filepath);
}

View File

@@ -0,0 +1,14 @@
namespace PckStudio.Core
{
public enum ConsolePlatform
{
Unknown,
Xbox360,
XboxOne,
PS3,
PS4,
PSVita,
WiiU,
Switch
}
}

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PckStudio.Core.Interfaces;
namespace PckStudio.Core
{
internal sealed class DLCBattlePackage : DLCPackage
{
private List<MapData> _maps = new List<MapData>();
public DLCBattlePackage(string name, int identifier, IDLCPackageLocationInfo packageInfo = null, IDLCPackage parentPackage = null)
: base(name, identifier, packageInfo, parentPackage)
{
}
public void AddMap(string name, Image thumbnail, MapSize mapSize, NamedData<byte[]> world)
{
_maps.Add(new MapData(name, thumbnail, MiniGameId.Battle, mapSize, world));
}
public override DLCPackageType GetDLCPackageType() => DLCPackageType.MG01;
}
}

View File

@@ -0,0 +1,268 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using OMI.Formats.GameRule;
using OMI.Formats.Languages;
using OMI.Formats.Pck;
using OMI.Workers.GameRule;
using OMI.Workers.Language;
using OMI.Workers.Pck;
using PckStudio.Core.Deserializer;
using PckStudio.Core.Extensions;
using PckStudio.Core.Interfaces;
namespace PckStudio.Core
{
public sealed class DLCManager
{
public static DLCManager Default { get; } = new DLCManager(default, default, AvailableLanguages.English);
public OMI.ByteOrder ByteOrder { get; set; }
public ConsolePlatform Platform { get; set; }
/// <summary>
/// See <see cref="AvailableLanguages"/> for details.
/// </summary>
public string PreferredLanguage { get; set; }
private const string PackageDisplayNameId = "IDS_DISPLAY_NAME";
private readonly IDictionary<int, IDLCPackage> _openPackages = new Dictionary<int, IDLCPackage>();
private readonly IDictionary<int, LOCFile> _localisationFiles = new Dictionary<int, LOCFile>();
private readonly Random _rng = new Random();
/// <summary>
///
/// </summary>
/// <param name="byteOrder"></param>
/// <param name="platform"></param>
/// <param name="preferredLanguage">See <see cref="AvailableLanguages"/> for details.</param>
public DLCManager(OMI.ByteOrder byteOrder, ConsolePlatform platform, string preferredLanguage)
{
ByteOrder = byteOrder;
Platform = platform;
PreferredLanguage = preferredLanguage;
}
public IDLCPackage CreateNewPackage(string name, DLCPackageType packageType)
{
int identifier = _rng.Next(8000, GameConstants.MAX_PACK_ID);
IDLCPackage package = packageType switch
{
DLCPackageType.SkinPack => DLCSkinPackage.CreateEmpty(name, identifier),
DLCPackageType.TexturePack => DLCTexturePackage.CreateDefaultPackage(name, "", identifier),
DLCPackageType.MashUpPack => new DLCMashUpPackage(name, "", identifier),
//! TODO: implemnt minigame dlc packages -null
DLCPackageType.MG01 => new DLCBattlePackage(name, identifier),
DLCPackageType.MG02 => throw new NotImplementedException(),
DLCPackageType.MG03 => throw new NotImplementedException(),
DLCPackageType.Invalid => InvalidDLCPackage.Instance,
_ => throw new ArgumentException("Unable to create DLC Package of 'Unknown' type."),
};
LOCFile localisation = new LOCFile();
localisation.AddLanguage(PreferredLanguage);
localisation.AddLocKey(PackageDisplayNameId, name);
_localisationFiles.Add(identifier, localisation);
_openPackages.Add(identifier, package);
return package;
}
public IDLCPackage OpenDLCPackage(string filepath) => OpenDLCPackage(new FileInfo(filepath));
public IDLCPackage OpenDLCPackage(FileInfo fileInfo)
{
if (!IsValidPckFile(fileInfo))
return InvalidDLCPackage.Instance;
using Stream stream = fileInfo.OpenRead();
PckFileReader fileReader = new PckFileReader(ByteOrder);
PckFile pckFile = fileReader.FromStream(stream);
Debug.Assert(pckFile.TryGetAsset("0", PckAssetType.InfoFile, out PckAsset zeroAsset), "Could not find asset named:'0'.");
int identifier = (zeroAsset?.HasProperty("PACKID") ?? default) ? zeroAsset.GetProperty("PACKID", int.Parse) : -1;
if (identifier <= 0 || identifier > GameConstants.MAX_PACK_ID)
{
Trace.TraceError($"{nameof(identifier)}({identifier}) was out of range!");
return InvalidDLCPackage.Instance;
}
if (_openPackages.ContainsKey(identifier))
return _openPackages[identifier];
LOCFile localisation = pckFile.GetAssetsByType(PckAssetType.LocalisationFile).FirstOrDefault()?.GetData(new LOCFileReader());
if (localisation is null)
return InvalidDLCPackage.Instance;
_localisationFiles.Add(identifier, localisation);
IDLCPackage package = ScanForPackageType(fileInfo, identifier, pckFile, localisation, fileReader);
_openPackages.Add(identifier, package);
return package;
}
internal LOCFile GetLocalisation(int identifier)
{
return _localisationFiles.ContainsKey(identifier) ? _localisationFiles[identifier] : default;
}
private bool IsValidPckFile(FileInfo fileInfo)
{
if (!fileInfo.Exists)
throw new FileNotFoundException(fileInfo.FullName);
if (fileInfo.Extension != ".pck")
throw new FileFormatException("File does not end with '.pck'.");
return true;
}
private IDLCPackage ScanForPackageType(FileInfo fileInfo, int identifier, PckFile pckFile, LOCFile localisation, PckFileReader fileReader)
{
bool hasLanguage = localisation?.Languages?.Contains(PreferredLanguage) ?? default;
string name = hasLanguage && (localisation?.HasLocEntry(PackageDisplayNameId) ?? default)
? localisation.GetLocEntry(PackageDisplayNameId, PreferredLanguage) : fileInfo.Name;
string description = hasLanguage && (localisation?.HasLocEntry(DLCTexturePackage.TexturePackDescriptionId) ?? default)
? localisation.GetLocEntry(DLCTexturePackage.TexturePackDescriptionId, PreferredLanguage) : string.Empty;
bool couldBeTexturePack = fileInfo.Name == "TexturePack.pck";
bool hasSkins = pckFile.Contains(PckAssetType.SkinFile) || pckFile.Contains(PckAssetType.SkinDataFile);
DLCPackageType dlcPackageType = hasSkins ? DLCPackageType.SkinPack : DLCPackageType.Unknown;
IDLCPackage skinPackage = hasSkins ? GetDLCSkinPackage(name, identifier, pckFile, fileReader) : null;
PckAsset texturePackInfo = pckFile.GetAssetsByType(PckAssetType.TexturePackInfoFile).FirstOrDefault();
string dataPath = texturePackInfo is not null ? texturePackInfo.GetProperty("DATAPATH") : string.Empty;
DirectoryInfo dataDirectoryInfo = fileInfo.Directory.EnumerateDirectories().Where(dirInfo => dirInfo.Name == "Data").FirstOrDefault();
bool hasDataFolder = dataDirectoryInfo is not null;
if (hasDataFolder && !string.IsNullOrWhiteSpace(dataPath))
{
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;
}
bool hasSavefile = dataDirectoryInfo.EnumerateFiles("*.mcs").Any();
PckAsset gameRuleAsset = null;
if (Platform == ConsolePlatform.Unknown)
throw new Exception($"{nameof(Platform)} is Unknown.");
bool hasGameRuleFile = pckFile.Contains("GameRules.grf", PckAssetType.GameRulesFile) && pckFile.TryGetAsset("GameRules.grf", PckAssetType.GameRulesFile, out gameRuleAsset);
if (hasSavefile && hasGameRuleFile)
{
GameRuleFile gameRuleFile = gameRuleAsset.GetData(new GameRuleFileReader(GetPlatformCompressionType()));
dlcPackageType = DLCPackageType.MashUpPack;
}
}
Debug.WriteLine(dlcPackageType);
return InvalidDLCPackage.Instance;
}
private GameRuleFile.CompressionType GetPlatformCompressionType()
{
switch (Platform)
{
case ConsolePlatform.Xbox360:
return GameRuleFile.CompressionType.XMem;
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;
}
}
private IDLCPackage GetTexturePackageFromPckFile(PckFile infoPck, PckFile dataPck)
{
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();
DLCTexturePackage.MetaData metaData = new DLCTexturePackage.MetaData(comparisonImg, iconImg);
bool a = TryGetAtlasFromResourceCategory(dataPck, ResourceCategory.BlockAtlas, out Atlas terrainAtlas);
bool b = TryGetAtlasFromResourceCategory(dataPck, ResourceCategory.ItemAtlas, out Atlas itemAtlas);
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))
{
}
return null;
}
private bool TryGetAtlasFromResourceCategory(PckFile pck, ResourceCategory resourceCategory, out Atlas atlas)
{
ResourceLocation resourceLocation = ResourceLocation.GetFromCategory(resourceCategory);
if (!pck.TryGetAsset(resourceLocation.ToString(), PckAssetType.TextureFile, out PckAsset asset))
{
Trace.TraceWarning($"Could not find '{resourceLocation}'.");
atlas = null;
return false;
}
atlas = asset.GetDeserializedData(new AtlasDeserializer(resourceLocation));
return true;
}
private IDLCPackage GetDLCSkinPackage(string name, int identifier, PckFile pck, PckFileReader fileReader, IDLCPackage parentPackage = null)
{
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();
return skin;
}
IEnumerable<Skin.Skin> skins = pck.GetAssetsByType(PckAssetType.SkinFile).Select(GetSkinWithCape);
skins = skins.Concat(pck.GetAssetsByType(PckAssetType.SkinDataFile)
.Select(asset => asset.GetData(fileReader))
.SelectMany(pck => pck.GetAssetsByType(PckAssetType.SkinFile))
.Select(GetSkinWithCape)
);
return new DLCSkinPackage(name, identifier, skins, null, parentPackage);
}
}
}

View File

@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OMI.Formats.GameRule;
using PckStudio.Core.Interfaces;
namespace PckStudio.Core
{
public sealed class DLCMashUpPackage : DLCPackage
{
public override string Description { get; }
private IDLCPackage _skinPackage;
private IDLCPackage _texturePackage;
private GameRuleFile _gameRule;
private IList<NamedData<byte[]>> _audioData;
private NamedData<byte[]> _savegameData;
internal DLCMashUpPackage(string name, string description, int identifier, IDLCPackageLocationInfo packageInfo, GameRuleFile gameRule, IDLCPackage parentPackage, IDLCPackage skinPackage = null, IDLCPackage texturePackage = null)
: base(name, identifier, packageInfo, parentPackage)
{
Description = description;
_gameRule = gameRule;
_skinPackage = skinPackage;
_texturePackage = texturePackage;
}
internal DLCMashUpPackage(string name, string description, int identifier)
: this(name, description, identifier, null, new GameRuleFile(), null)
{
_skinPackage = DLCSkinPackage.CreateEmpty(this);
_texturePackage = DLCTexturePackage.CreateDefaultPackage(this);
_savegameData = new NamedData<byte[]>("world.mcs", Array.Empty<byte>());
_audioData = new List<NamedData<byte[]>>();
_gameRule.AddRule("MapOptions",
new GameRuleFile.IntParameter("seed", 0),
new GameRuleFile.GameRuleParameter("baseSaveName", _savegameData.Name),
new GameRuleFile.BoolParameter("flatworld", false),
new GameRuleFile.IntParameter("texturePackId", Identifier)
);
_gameRule.AddRule("LevelRules")
.AddRule("UpdatePlayer",
new GameRuleFile.FloatParameter("yRot", 0f),
new GameRuleFile.FloatParameter("xRot", 0f),
new GameRuleFile.IntParameter("spawnX", 0),
new GameRuleFile.IntParameter("spawnY", 0),
new GameRuleFile.IntParameter("spawnZ", 0)
);
}
public IDLCPackage GetSkinPackage() => _skinPackage;
public IDLCPackage GetTexturePackage() => _texturePackage;
public override DLCPackageType GetDLCPackageType() => DLCPackageType.MashUpPack;
}
}

View File

@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PckStudio.Core.Interfaces;
namespace PckStudio.Core
{
public abstract class DLCPackage : IDLCPackage
{
protected DLCPackage(string name, int identifier, IDLCPackageLocationInfo packageInfo, IDLCPackage parentPackage)
{
Name = name;
Identifier = identifier;
PackageInfo = packageInfo;
ParentPackage = parentPackage;
}
public int Identifier { get; }
public IDLCPackageLocationInfo PackageInfo { get; }
public string Name { get; } = string.Empty;
public virtual string Description { get; } = string.Empty;
public abstract DLCPackageType GetDLCPackageType();
public IDLCPackage ParentPackage { get; }
public bool IsRootPackage => ParentPackage is null;
}
}

View File

@@ -0,0 +1,15 @@
namespace PckStudio.Core
{
public enum DLCPackageType
{
Unknown = -1,
Invalid,
SkinPack,
TexturePack,
MashUpPack,
//! TODO: Add DLCPackage class for minigames... -null
MG01,
MG02,
MG03,
}
}

View File

@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using PckStudio.Core.Interfaces;
using PckStudio.Core.Skin;
namespace PckStudio.Core
{
public enum DLCSkinPackageOrder
{
ById,
CapesFirst,
SkinsFirst
}
public sealed class DLCSkinPackage : DLCPackage
{
public DLCSkinPackageOrder SkinPackageOrder { get; set; } = DLCSkinPackageOrder.CapesFirst;
private readonly Dictionary<SkinIdentifier, Skin.Skin> _skins;
internal DLCSkinPackage(string name, int identifier, IEnumerable<Skin.Skin> skins, IDLCPackageLocationInfo packageInfo, IDLCPackage parentPackage)
: base(name, identifier, packageInfo, parentPackage)
{
_skins = skins.ToDictionary(skin => skin.Identifier);
}
internal DLCSkinPackage(string name, int identifier, IDLCPackage parentPackage = null)
: this(name, identifier, Enumerable.Empty<Skin.Skin>(), null, parentPackage)
{
}
internal static IDLCPackage CreateEmpty(string name, int identifier, IDLCPackage parentPackage = null) => new DLCSkinPackage(name, identifier, parentPackage);
internal static IDLCPackage CreateEmpty(IDLCPackage parentPackage) => CreateEmpty(parentPackage.Name, parentPackage.Identifier, parentPackage);
public bool TryGetSkin(SkinIdentifier skinIdentifier, out Skin.Skin skin) => _skins.TryGetValue(skinIdentifier, out skin);
public bool ContainsSkin(SkinIdentifier skinIdentifier) => _skins.ContainsKey(skinIdentifier);
public void AddSkin(Skin.Skin skin) => _skins.Add(skin.Identifier, skin);
public bool RemoveSkin(SkinIdentifier skinIdentifier) => _skins.Remove(skinIdentifier);
public Skin.Skin GetSkin(SkinIdentifier skinIdentifier) => _skins[skinIdentifier];
public IReadOnlyCollection<Skin.Skin> GetSkins() => _skins.Values.Cast<Skin.Skin>().ToArray();
public override DLCPackageType GetDLCPackageType() => DLCPackageType.SkinPack;
}
}

View File

@@ -0,0 +1,142 @@
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.Color;
using OMI.Formats.Material;
using OMI.Formats.Model;
using OMI.Formats.Pck;
using OMI.Workers.Color;
using PckStudio.Core.Interfaces;
using PckStudio.Core.Properties;
namespace PckStudio.Core
{
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 TexturePackDescriptionId = "IDS_TP_DESCRIPTION";
private TextureResolution _resolution;
//! Data for x{_resolution}Info.pck
public sealed class MetaData
{
public Image ComparisonImg { get; }
public Image IconImg { get; }
public MetaData(Image comparisonImg, Image iconImg)
{
ComparisonImg = comparisonImg;
IconImg = iconImg;
}
}
public MetaData Info { get; }
//! Data for x{16}Data.pck
//! => 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;
//! 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 Image[] _blockEntityBreakImages; //! max = 10!
private IDictionary<string, Animation> _itemAnimations;
private IDictionary<string, Animation> _blockAnimations;
internal DLCTexturePackage(
string name,
string description,
int identifier,
MetaData metaData,
TextureResolution resolution,
Atlas terrainAtlas,
Atlas itemsAtlas,
Atlas particlesAtlas,
Atlas paintingAtlas,
IDictionary<string, Color> colors,
IDictionary<string, (Color surface, Color underwater, Color fog)> waterColors,
ModelContainer customModels,
MaterialContainer materials,
Image[] blockEntityBreakImages,
IDictionary<string, Animation> itemAnimations,
IDictionary<string, Animation> blockAnimations,
IDLCPackageLocationInfo packageInfo,
IDLCPackage parentPackage
)
: base(name, identifier, packageInfo, parentPackage)
{
Description = description;
Info = metaData;
_resolution = resolution;
_terrainAtlas = terrainAtlas;
_itemsAtlas = itemsAtlas;
_particlesAtlas = particlesAtlas;
_paintingAtlas = paintingAtlas;
_colors = colors;
_waterColors = waterColors;
_customModels = customModels;
_materials = materials;
_blockEntityBreakImages = blockEntityBreakImages;
_itemAnimations = itemAnimations;
_blockAnimations = blockAnimations;
}
public TextureResolution GetResolution() => _resolution;
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 = 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));
//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();
return new DLCTexturePackage(
name, description, identifier, metadata, resolution,
terrain, items, particles, painting,
colors, waterColors,
new ModelContainer(),
new MaterialContainer(),
blockEntityBreakImages,
null, null,
null, parentPackage
);
}
}
}

View File

@@ -0,0 +1,17 @@
namespace PckStudio.Core.Interfaces
{
public interface IDLCPackage
{
string Name { get; }
string Description { get; }
int Identifier { get; }
bool IsRootPackage { get; }
IDLCPackageLocationInfo PackageInfo { get; }
DLCPackageType GetDLCPackageType();
IDLCPackage ParentPackage { get; }
}
}

View File

@@ -0,0 +1,7 @@
namespace PckStudio.Core.Interfaces
{
public interface IDLCPackageLocationInfo
{
}
}

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PckStudio.Core.Interfaces;
namespace PckStudio.Core
{
// Dummy class
internal sealed class InvalidDLCPackage : DLCPackage
{
internal static IDLCPackage Instance { get; } = new InvalidDLCPackage();
private InvalidDLCPackage(string name, int identifier, IDLCPackageLocationInfo packageInfo, IDLCPackage parentPackage)
: base(name, identifier, packageInfo, parentPackage)
{
}
private InvalidDLCPackage()
: this(nameof(InvalidDLCPackage), -1, null, null)
{
}
public override DLCPackageType GetDLCPackageType() => DLCPackageType.Invalid;
}
}

47
PckStudio.Core/MapData.cs Normal file
View File

@@ -0,0 +1,47 @@
using System.Drawing;
using OMI.Formats.GameRule;
namespace PckStudio.Core
{
public enum MiniGameId : int
{
None,
Battle,
Tumble,
Glide
}
public enum MapSize : int
{
Small,
Large,
Huge
}
public class MapData
{
public string Name { get; }
public Image Thumbnail { get; }
public GameRuleFile Grf { get; }
public NamedData<byte[]> World { get; }
public MapData(string name, Image thumbnail, MiniGameId miniGame, MapSize mapSize, NamedData<byte[]> world)
{
Name = name;
Thumbnail = thumbnail;
Grf = new GameRuleFile();
Grf.AddRule("MapOptions",
new GameRuleFile.IntParameter("seed", 0),
new GameRuleFile.IntParameter("spawnX", 0),
new GameRuleFile.IntParameter("spawnY", 0),
new GameRuleFile.IntParameter("spawnZ", 0),
new GameRuleFile.BoolParameter("flatworld", false),
new GameRuleFile.IntParameter("mapSize", (int)mapSize),
new GameRuleFile.IntParameter("themeId", 0)
);
Grf.AddRule("LevelRules", [new GameRuleFile.IntParameter("ruleType", (int)miniGame)]);
World = world;
}
}
}

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{345EABED-F0D1-4D04-B409-BABDEF747352}</ProjectGuid>
@@ -12,8 +12,8 @@
<AssemblyName>PckStudio.Core</AssemblyName>
<UseWindowsForms>true</UseWindowsForms>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<LangVersion>12</LangVersion>
<FileAlignment>512</FileAlignment>
<LangVersion>12</LangVersion>
<FileAlignment>512</FileAlignment>
<EnableDefaultCompileItems>true</EnableDefaultCompileItems>
<Deterministic>true</Deterministic>
<AutoGenerateBindingRedirects>True</AutoGenerateBindingRedirects>
@@ -59,11 +59,18 @@
<Compile Include="AtlasGroupLargeTileAnimation.cs" />
<Compile Include="AtlasTile.cs" />
<Compile Include="BoundingBox.cs" />
<Compile Include="ConsolePlatform.cs" />
<Compile Include="DelegatedFileSaveContext.cs" />
<Compile Include="DelegatedSaveContext.cs" />
<Compile Include="Deserializer\AnimationDeserializer.cs" />
<Compile Include="Deserializer\AtlasDeserializer.cs" />
<Compile Include="Deserializer\ImageDeserializer.cs" />
<Compile Include="DLCBattlePackage.cs" />
<Compile Include="DLCManager.cs" />
<Compile Include="DLCMashUpPackage.cs" />
<Compile Include="DLCPackage.cs" />
<Compile Include="DLCSkinPackage.cs" />
<Compile Include="DLCTexturePackage.cs" />
<Compile Include="Extensions\AnimationExtensions.cs" />
<Compile Include="Extensions\BlendMode.cs" />
<Compile Include="Extensions\BoundingBoxExtensions.cs" />
@@ -91,12 +98,15 @@
<Compile Include="FileDialogFilter.cs" />
<Compile Include="FileFormats\PckAudioFile.cs" />
<Compile Include="GameConstants.cs" />
<Compile Include="Interfaces\IDLCPackage.cs" />
<Compile Include="Interfaces\IDLCPackageLocationInfo.cs" />
<Compile Include="Interfaces\IEditor.cs" />
<Compile Include="Interfaces\IModelImportProvider.cs" />
<Compile Include="Interfaces\IPckAssetDeserializer.cs" />
<Compile Include="Interfaces\IPckAssetSerializer.cs" />
<Compile Include="Interfaces\ISaveContext.cs" />
<Compile Include="Interfaces\ITryGetSet.cs" />
<Compile Include="InvalidDLCPackage.cs" />
<Compile Include="IO\3DST\3DSTextureReader.cs" />
<Compile Include="IO\3DST\3DSTextureWriter.cs" />
<Compile Include="IO\3DST\TextureCodec.cs" />
@@ -120,10 +130,12 @@
<Compile Include="Json\EntityInfo.cs" />
<Compile Include="Json\TileInfo.cs" />
<Compile Include="Json\UpdateInformation.cs" />
<Compile Include="MapData.cs" />
<Compile Include="Misc\FileCacher.cs" />
<Compile Include="Misc\OpenFolderDialog.cs" />
<Compile Include="NamedData.cs" />
<Compile Include="PackInfo.cs" />
<Compile Include="DLCPackageType.cs" />
<Compile Include="ResourceCategory.cs" />
<Compile Include="ResourceLocation.cs" />
<Compile Include="Serializer\AnimationSerializer.cs" />
@@ -151,10 +163,10 @@
<PackageReference Include="Newtonsoft.Json">
<Version>13.0.3</Version>
</PackageReference>
<PackageReference Include="Autoupdater.NET.Official">
<Version>1.9.2</Version>
</PackageReference>
<PackageReference Include="OpenTK" Version="3.3.3" />
<PackageReference Include="Autoupdater.NET.Official">
<Version>1.9.2</Version>
</PackageReference>
<PackageReference Include="OpenTK" Version="3.3.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Vendor\OMI-Lib\OMI Filetypes Library\OMI Filetype Library.csproj">

View File

@@ -121,27 +121,7 @@ namespace PckStudio.Core
["misc/additionalmapicons.png"] = new ResourceLocation("misc/additionalmapicons.png", ResourceCategory.AdditionalMapIconsAtlas, 4, tilesInfo: Tiles.AdditionalMapIconTileInfos),
};
public static string GetPathFromCategory(ResourceCategory category)
{
return category switch
{
ResourceCategory.ItemAnimation => _categoryLookUp["textures/items"].ToString(),
ResourceCategory.BlockAnimation => _categoryLookUp["textures/blocks"].ToString(),
ResourceCategory.MobEntityTextures => _categoryLookUp["mob"].ToString(),
ResourceCategory.ItemEntityTextures => _categoryLookUp["item"].ToString(),
ResourceCategory.BlockAtlas => _categoryLookUp["terrain.png"].ToString(),
ResourceCategory.ItemAtlas => _categoryLookUp["items.png"].ToString(),
ResourceCategory.ParticleAtlas => _categoryLookUp["particles.png"].ToString(),
ResourceCategory.BannerAtlas => _categoryLookUp["item/banner/Banner_Atlas.png"].ToString(),
ResourceCategory.PaintingAtlas => _categoryLookUp["art/kz.png"].ToString(),
ResourceCategory.ExplosionAtlas => _categoryLookUp["misc/explosion.png"].ToString(),
ResourceCategory.ExperienceOrbAtlas => _categoryLookUp["item/xporb.png"].ToString(),
ResourceCategory.MoonPhaseAtlas => _categoryLookUp["terrain/moon_phases.png"].ToString(),
ResourceCategory.MapIconAtlas => _categoryLookUp["misc/mapicons.png"].ToString(),
ResourceCategory.AdditionalMapIconsAtlas => _categoryLookUp["misc/additionalmapicons.png"].ToString(),
_ => string.Empty
};
}
public static string GetPathFromCategory(ResourceCategory category) => GetFromCategory(category).ToString();
public static ResourceCategory GetCategoryFromPath(string path) => GetFromPath(path).Category;
@@ -204,5 +184,27 @@ namespace PckStudio.Core
{
return "res/" + Path;
}
internal static ResourceLocation GetFromCategory(ResourceCategory category)
{
return category switch
{
ResourceCategory.ItemAnimation => _categoryLookUp["textures/items"],
ResourceCategory.BlockAnimation => _categoryLookUp["textures/blocks"],
ResourceCategory.MobEntityTextures => _categoryLookUp["mob"],
ResourceCategory.ItemEntityTextures => _categoryLookUp["item"],
ResourceCategory.BlockAtlas => _categoryLookUp["terrain.png"],
ResourceCategory.ItemAtlas => _categoryLookUp["items.png"],
ResourceCategory.ParticleAtlas => _categoryLookUp["particles.png"],
ResourceCategory.BannerAtlas => _categoryLookUp["item/banner/Banner_Atlas.png"],
ResourceCategory.PaintingAtlas => _categoryLookUp["art/kz.png"],
ResourceCategory.ExplosionAtlas => _categoryLookUp["misc/explosion.png"],
ResourceCategory.ExperienceOrbAtlas => _categoryLookUp["item/xporb.png"],
ResourceCategory.MoonPhaseAtlas => _categoryLookUp["terrain/moon_phases.png"],
ResourceCategory.MapIconAtlas => _categoryLookUp["misc/mapicons.png"],
ResourceCategory.AdditionalMapIconsAtlas => _categoryLookUp["misc/additionalmapicons.png"],
_ => Unknown
};
}
}
}

2
Vendor/OMI-Lib vendored