mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +01:00
83 lines
2.5 KiB
C#
83 lines
2.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using OtterGui;
|
|
using OtterGui.Compression;
|
|
using Penumbra.GameData.Files;
|
|
using Penumbra.String.Classes;
|
|
|
|
namespace Penumbra.Mods.Editor;
|
|
|
|
/// <summary> A class that collects information about skin materials in a model file and handle changes on them. </summary>
|
|
public class ModelMaterialInfo
|
|
{
|
|
public readonly FullPath Path;
|
|
public readonly MdlFile File;
|
|
private readonly string[] _currentMaterials;
|
|
private readonly IReadOnlyList<int> _materialIndices;
|
|
public bool Changed { get; private set; }
|
|
|
|
public IReadOnlyList<string> CurrentMaterials
|
|
=> _currentMaterials;
|
|
|
|
private IEnumerable<string> DefaultMaterials
|
|
=> _materialIndices.Select(i => File.Materials[i]);
|
|
|
|
public (string Current, string Default) this[int idx]
|
|
=> (_currentMaterials[idx], File.Materials[_materialIndices[idx]]);
|
|
|
|
public int Count
|
|
=> _materialIndices.Count;
|
|
|
|
// Set the skin material to a new value and flag changes appropriately.
|
|
public void SetMaterial(string value, int materialIdx)
|
|
{
|
|
var mat = File.Materials[_materialIndices[materialIdx]];
|
|
_currentMaterials[materialIdx] = value;
|
|
if (mat != value)
|
|
Changed = true;
|
|
else
|
|
Changed = !_currentMaterials.SequenceEqual(DefaultMaterials);
|
|
}
|
|
|
|
// Save a changed .mdl file.
|
|
public void Save(FileCompactor compactor)
|
|
{
|
|
if (!Changed)
|
|
return;
|
|
|
|
foreach (var (idx, i) in _materialIndices.WithIndex())
|
|
File.Materials[idx] = _currentMaterials[i];
|
|
|
|
try
|
|
{
|
|
compactor.WriteAllBytes(Path.FullName, File.Write());
|
|
Changed = false;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Restore();
|
|
Penumbra.Log.Error($"Could not write manipulated .mdl file {Path.FullName}:\n{e}");
|
|
}
|
|
}
|
|
|
|
// Revert all current changes.
|
|
public void Restore()
|
|
{
|
|
if (!Changed)
|
|
return;
|
|
|
|
foreach (var (idx, i) in _materialIndices.WithIndex())
|
|
_currentMaterials[i] = File.Materials[idx];
|
|
|
|
Changed = false;
|
|
}
|
|
|
|
public ModelMaterialInfo(FullPath path, MdlFile file, IReadOnlyList<int> indices)
|
|
{
|
|
Path = path;
|
|
File = file;
|
|
_materialIndices = indices;
|
|
_currentMaterials = DefaultMaterials.ToArray();
|
|
}
|
|
}
|